From fad245bbe903dbfd4438a32f1ca4587946b09db4 Mon Sep 17 00:00:00 2001 From: "jian.yang" Date: Wed, 11 Jan 2023 11:28:29 +0800 Subject: [PATCH 001/456] BACKPORT: FROMLIST: PCI: mediatek-gen3: Add power and reset control feature for downstream component Make MediaTek's controller driver capable of controlling power supplies and reset pin of a downstream component in power-on and power-off flow. Some downstream components (e.g., a WIFI chip) may need an extra reset other than of PERST# and their power supplies, depending on the requirements of platform, may need to controlled by their parent's driver. To meet the requirements described above, I add this feature to MediaTek's PCIe controller driver as a optional feature. Signed-off-by: jian.yang (am from https://patchwork.kernel.org/patch/13095926/) (also found at https://lore.kernel.org/r/20230111032830.20447-2-jian.yang@mediatek.com) Conflict: Drop gpio flags related part because of compile error BUG=b:381207734 TEST=Check wifi works on ciri UPSTREAM-TASK=b:313371758 Change-Id: Ieedd26a0a497dc34750bcdba834ba092fff03f4a Signed-off-by: Johnson Wang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4263136 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao (cherry picked from commit db6586120fda817db668637582786da022d6f166) Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051645 Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 96 ++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 975b3024fb08c..2fc450b4e9d1e 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include @@ -15,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "../pci.h" @@ -100,6 +104,13 @@ #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) +/* Downstream Component power supplies used by MediaTek PCIe */ +static const char *const dsc_power_supplies[] = { + "pcie1v8", + "pcie3v3", + "pcie12v", +}; + /** * struct mtk_msi_set - MSI information for each set * @base: IO mapped register base @@ -122,6 +133,10 @@ struct mtk_msi_set { * @phy: PHY controller block * @clks: PCIe clocks * @num_clks: PCIe clocks count for this port + * @supplies: Downstream Component power supplies + * @num_supplies: Downstream Component power supplies count + * @dsc_reset: The GPIO pin to reset Downstream component + * @dsc_reset_delay_ms: Delay in ms before the deassertion of reset GPIO * @irq: PCIe controller interrupt number * @saved_irq_state: IRQ enable state saved at suspend time * @irq_lock: lock protecting IRQ register access @@ -141,6 +156,10 @@ struct mtk_gen3_pcie { struct phy *phy; struct clk_bulk_data *clks; int num_clks; + struct regulator_bulk_data *supplies; + int num_supplies; + struct gpio_desc *dsc_reset; + u32 dsc_reset_delay_ms; int irq; u32 saved_irq_state; @@ -778,7 +797,7 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); struct resource *regs; - int ret; + int ret, i; regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcie-mac"); if (!regs) @@ -824,14 +843,87 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) return pcie->num_clks; } + pcie->num_supplies = ARRAY_SIZE(dsc_power_supplies); + pcie->supplies = devm_kcalloc(dev, pcie->num_supplies, + sizeof(*pcie->supplies), + GFP_KERNEL); + if (!pcie->supplies) + return -ENOMEM; + + for (i = 0; i < pcie->num_supplies; i++) + pcie->supplies[i].supply = dsc_power_supplies[i]; + + ret = devm_regulator_bulk_get(dev, pcie->num_supplies, pcie->supplies); + if (ret) + return ret; + + pcie->dsc_reset = devm_gpiod_get_optional(dev, "dsc-reset", + GPIOD_OUT_LOW); + if (IS_ERR(pcie->dsc_reset)) { + ret = PTR_ERR(pcie->dsc_reset); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to request DSC reset gpio\n"); + + return ret; + } + + ret = of_property_read_u32(dev->of_node, "dsc-reset-msleep", + &pcie->dsc_reset_delay_ms); + if (ret) { + dev_info(dev, "Failed to get delay time of DSC, set it to default 5ms\n"); + pcie->dsc_reset_delay_ms = 5; + } + return 0; } +static int mtk_pcie_dsc_power_up(struct mtk_gen3_pcie *pcie) +{ + struct device *dev = pcie->dev; + int ret; + + /* Assert Downstream Component reset */ + if (pcie->dsc_reset) + gpiod_set_value_cansleep(pcie->dsc_reset, 1); + + ret = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); + if (ret) + dev_err(dev, "failed to enable DSC power supplies: %d\n", ret); + + /* De-assert Downstream Component reset */ + if (pcie->dsc_reset) { + /* + * Wait for a short time before we de-assert the reset GPIO. + * Depends on the requirement of a specific Downstream + * Component. + */ + usleep_range(1000 * pcie->dsc_reset_delay_ms, + 1000 * pcie->dsc_reset_delay_ms + 100); + gpiod_set_value_cansleep(pcie->dsc_reset, 0); + } + + return ret; +} + +static void mtk_pcie_dsc_power_down(struct mtk_gen3_pcie *pcie) +{ + /* Assert Downstream Component reset */ + if (pcie->dsc_reset) + gpiod_set_value_cansleep(pcie->dsc_reset, 1); + + regulator_bulk_disable(pcie->num_supplies, pcie->supplies); +} + static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie) { struct device *dev = pcie->dev; int err; + /* Downstream Component power up before RC */ + err = mtk_pcie_dsc_power_up(pcie); + if (err) + return err; + /* PHY power on and enable pipe clock */ reset_control_deassert(pcie->phy_reset); @@ -870,6 +962,7 @@ err_phy_on: phy_exit(pcie->phy); err_phy_init: reset_control_assert(pcie->phy_reset); + mtk_pcie_dsc_power_down(pcie); return err; } @@ -885,6 +978,7 @@ static void mtk_pcie_power_down(struct mtk_gen3_pcie *pcie) phy_power_off(pcie->phy); phy_exit(pcie->phy); reset_control_assert(pcie->phy_reset); + mtk_pcie_dsc_power_down(pcie); } static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) -- GitLab From c6cbdcb9cf9ab11c8ace8ea03870662d4dcf1e45 Mon Sep 17 00:00:00 2001 From: "michael.lo" Date: Thu, 27 Apr 2023 18:35:33 +0800 Subject: [PATCH 002/456] CHROMIUM: PCI: mediatek-gen3: Avoid power up/down wakeup source If a child device on the PCIe bus is a wakeup source, then the PCIe controller shouldn't turn on or off its power. BUG=b:275643860,b:236339750,b:381207734 UPSTREAM-TASK=b:313371758 TEST=Check wifi works on ciri Change-Id: I1cf7fcdb47a3e625e5e473e2803891288fde5e52 Signed-off-by: michael.lo Signed-off-by: Jason Chen Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4486582 Reviewed-by: Chen-Yu Tsai (cherry picked from commit 95d18c6c0e2a98751201d9a36a8dafa393795747) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6048310 Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Tested-by: Hsin-Te Yuan Auto-Submit: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 2fc450b4e9d1e..65d32ac5a091e 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -920,9 +920,11 @@ static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie) int err; /* Downstream Component power up before RC */ - err = mtk_pcie_dsc_power_up(pcie); - if (err) - return err; + if (!device_wakeup_path(pcie->dev)) { + err = mtk_pcie_dsc_power_up(pcie); + if (err) + return err; + } /* PHY power on and enable pipe clock */ reset_control_deassert(pcie->phy_reset); @@ -978,7 +980,9 @@ static void mtk_pcie_power_down(struct mtk_gen3_pcie *pcie) phy_power_off(pcie->phy); phy_exit(pcie->phy); reset_control_assert(pcie->phy_reset); - mtk_pcie_dsc_power_down(pcie); + + if (!pcie->dev->power.is_suspended || !device_wakeup_path(pcie->dev)) + mtk_pcie_dsc_power_down(pcie); } static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) -- GitLab From cd7567e1959a41538dc1d426a7389693f4e6c7e6 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Wed, 21 Feb 2024 15:11:26 +0800 Subject: [PATCH 003/456] CHROMIUM: arm64: dts: mediatek: mt8188-geralt: Add wifi node The MT7921 WiFi device is on the PCIe bus. Describe the node and mark it as a wakeup-source. BUG=b:313371758,b:311139883,b:381207734 UPSTREAM-TASK=b:244281402 TEST=Check wifi works on ciri Change-Id: Ib89f3d60d0088ca1c8d3bf5a5aad5be6eaa05b2d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5313161 Reviewed-by: Chen-Yu Tsai Tested-by: Fei Shao Commit-Queue: Fei Shao (cherry picked from commit bccf7ad507b453470e0215eff879cb9be3bfa1c7) Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051646 Reviewed-by: Pin-yen Lin Commit-Queue: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi index 3a79d8cca839d..64071cb068f26 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi @@ -678,6 +678,16 @@ pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; status = "okay"; + + pcie@0,0 { + #address-cells = <3>; + #size-cells = <2>; + reg = <0x0000 0 0 0 0>; + wifi: pcie@1,0 { + reg = <0x0000 0 0 0 0>; + wakeup-source; + }; + }; }; &pciephy { -- GitLab From 452ba6bf159b026bd45bb84a181fc7fc4dc2f13d Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Wed, 27 Nov 2024 10:15:25 +0000 Subject: [PATCH 004/456] CHROMIUM: arm64: dts: mediatek: mt8188-geralt: Add PCIe power supplies and reset Add power supplies and reset in PCIe node. BUG=b:381207734 TEST=Check wifi works on ciri UPSTREAM-TASK=b:313371758 Change-Id: I238a517a9a4768606bc55ca37d9da32413309a86 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6048312 Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi index 64071cb068f26..6bfbd3a58bc24 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi @@ -677,6 +677,9 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; + pcie1v8-supply = <&mt6359_vcn18_ldo_reg>; + pcie3v3-supply = <&pp3300_wlan>; + dsc-reset-gpios = <&pio 145 1>; status = "okay"; pcie@0,0 { -- GitLab From 682fb51e2a239df0424546f1c4ca7649796c49a8 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Thu, 28 Nov 2024 01:57:15 +0000 Subject: [PATCH 005/456] UPSTREAM: ASoC: qcom: sc7280: Fix missing Soundwire runtime stream alloc Commit 15c7fab0e047 ("ASoC: qcom: Move Soundwire runtime stream alloc to soundcards") moved the allocation of Soundwire stream runtime from the Qualcomm Soundwire driver to each individual machine sound card driver, except that it forgot to update SC7280 card. Just like for other Qualcomm sound cards using Soundwire, the card driver should allocate and release the runtime. Otherwise sound playback will result in a NULL pointer dereference or other effect of uninitialized memory accesses (which was confirmed on SDM845 having similar issue). Cc: stable@vger.kernel.org Cc: Alexey Klimov Cc: Steev Klimaszewski Fixes: 15c7fab0e047 ("ASoC: qcom: Move Soundwire runtime stream alloc to soundcards") Link: https://lore.kernel.org/r/20241010054109.16938-1-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241012101108.129476-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown (cherry picked from commit db7e59e6a39a4d3d54ca8197c796557e6d480b0d) BUG=b:326869955 TEST=Test Audio use cases. Signed-off-by: Linux Patches Robot Change-Id: I723a48142dfed5a42a9a88d5f370c283a2be87ca Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055715 Reviewed-by: Sean Paul Reviewed-by: Terry Cheong Reviewed-by: Yu-Hsuan Hsu Commit-Queue: Terry Cheong Signed-off-by: Hubert Mazur --- sound/soc/qcom/Kconfig | 1 + sound/soc/qcom/sc7280.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 0fa79e71fc496..9121ec10462dc 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -209,6 +209,7 @@ config SND_SOC_SC7280 tristate "SoC Machine driver for SC7280 boards" depends on I2C && SOUNDWIRE select SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_SDW select SND_SOC_LPASS_SC7280 select SND_SOC_MAX98357A select SND_SOC_WCD938X_SDW diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c index f636c0d2ca363..7653145151505 100644 --- a/sound/soc/qcom/sc7280.c +++ b/sound/soc/qcom/sc7280.c @@ -21,6 +21,7 @@ #include "common.h" #include "lpass.h" #include "qdsp6/q6afe.h" +#include "sdw.h" #define DEFAULT_MCLK_RATE 19200000 #define RT5682_PLL_FREQ (48000 * 512) @@ -314,6 +315,7 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) struct snd_soc_card *card = rtd->card; struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; switch (cpu_dai->id) { case MI2S_PRIMARY: @@ -331,6 +333,9 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) default: break; } + + data->sruntime[cpu_dai->id] = NULL; + sdw_release_stream(sruntime); } static int sc7280_snd_startup(struct snd_pcm_substream *substream) @@ -345,6 +350,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream) switch (cpu_dai->id) { case MI2S_PRIMARY: ret = sc7280_rt5682_init(rtd); + if (ret) + return ret; break; case SECONDARY_MI2S_RX: codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; @@ -358,7 +365,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream) default: break; } - return ret; + + return qcom_snd_sdw_startup(substream); } static const struct snd_soc_ops sc7280_ops = { -- GitLab From 238461083520a12f2eee75b68bcf46ce1a6827a7 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Thu, 28 Nov 2024 05:52:56 +0000 Subject: [PATCH 006/456] Revert "CHROMIUM: ASoC: mediatek: mt8188-mt6359: Check existence of dai_name before dereferencing" This reverts commit 35a0b894b6248896b88a1511cfe8d7956e559f2b. BUG=b:380813926 TEST=test audio on ciri UPSTREAM-TASK=b:380814787 Change-Id: I09fdf824a7af447c59bb7ced322407e3989b7b1c Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057108 Reviewed-by: Pin-yen Lin Commit-Queue: Pin-yen Lin Signed-off-by: Hubert Mazur --- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 79e6ee057856d..1550e56ab57d5 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -1277,12 +1277,10 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (dai_link->num_codecs && dai_link->codecs->dai_name && - strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (dai_link->num_codecs && dai_link->codecs->dai_name && - strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC_BE") == 0) { @@ -1329,8 +1327,7 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, init_es8326 = true; } } else { - if (dai_link->num_codecs && dai_link->codecs->dai_name && - strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { + if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { if (!init_dumb) { dai_link->init = mt8188_dumb_amp_init; init_dumb = true; -- GitLab From 86de5556b08a651272f003d68db3b89d1920a0bf Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Tue, 16 Apr 2024 09:13:57 +0200 Subject: [PATCH 007/456] UPSTREAM: ASoC: mediatek: mt8192: Migrate to mtk_soundcard_common_probe Add mtk_soundcard_pdata platform data for the MediaTek common sound card probe mechanism, including a driver/soc-specific probe extension (used for bits that cannot be commonized hence specific to this driver), and change the probe function to mtk_soundcard_common_probe. This is also adding the possibility of specifying the links and routing with the audio-routing property and (x)-dai-link nodes in device trees to stop hardcoding machine specific links in the card driver assupported by the common probe function, but support for legacy device trees is retained with a legacy_probe function, which is used only in case the new properties are not found. Reviewed-by: Alexandre Mergnat Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20240416071410.75620-6-angelogioacchino.delregno@collabora.com Signed-off-by: Mark Brown (cherry picked from commit 2d72cbb56327205ae04a9376c5b78a35b6347294) BUG=b:380813926 TEST=Boot and test audio on ciri Change-Id: Ie939fac6f2d1ca618b93ab7bc0e8bcf369fd41ae Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057109 Reviewed-by: Sean Paul Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- .../mt8192/mt8192-mt6359-rt1015-rt5682.c | 164 ++++++++++-------- 1 file changed, 91 insertions(+), 73 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index bfcb2c486c39d..645bc1aa67c7f 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -20,6 +20,8 @@ #include "../../codecs/rt1015.h" #include "../../codecs/rt5682.h" #include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-soc-card.h" +#include "../common/mtk-soundcard-driver.h" #include "mt8192-afe-common.h" #include "mt8192-afe-clk.h" #include "mt8192-afe-gpio.h" @@ -38,9 +40,10 @@ #define RT1015P_RT5682_OF_NAME "mediatek,mt8192_mt6359_rt1015p_rt5682" #define RT1015P_RT5682S_OF_NAME "mediatek,mt8192_mt6359_rt1015p_rt5682s" -struct mt8192_mt6359_priv { - struct snd_soc_jack headset_jack; - struct snd_soc_jack hdmi_jack; +enum mt8192_jacks { + MT8192_JACK_HEADSET, + MT8192_JACK_HDMI, + MT8192_JACK_MAX, }; /* Headset jack detection DAPM pins */ @@ -323,13 +326,13 @@ static int mt8192_mt6359_init(struct snd_soc_pcm_runtime *rtd) static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) { + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8192_JACK_HEADSET]; struct snd_soc_component *cmpnt_afe = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); struct snd_soc_component *cmpnt_codec = snd_soc_rtd_to_codec(rtd, 0)->component; - struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_jack *jack = &priv->headset_jack; int ret; ret = mt8192_dai_i2s_set_share(afe, "I2S8", "I2S9"); @@ -359,19 +362,19 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) static int mt8192_mt6359_hdmi_init(struct snd_soc_pcm_runtime *rtd) { + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8192_JACK_HDMI]; struct snd_soc_component *cmpnt_codec = snd_soc_rtd_to_codec(rtd, 0)->component; - struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); int ret; - ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, - &priv->hdmi_jack); + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack); if (ret) { dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret); return ret; } - return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); + return snd_soc_component_set_jack(cmpnt_codec, jack, NULL); } static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, @@ -1136,71 +1139,53 @@ static int mt8192_mt6359_card_set_be_link(struct snd_soc_card *card, return 0; } -static int mt8192_mt6359_dev_probe(struct platform_device *pdev) +static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data) { - struct snd_soc_card *card; - struct device_node *platform_node, *hdmi_codec, *headset_codec, *speaker_codec; - int ret, i; + struct mtk_platform_card_data *card_data = soc_card_data->card_data; + struct snd_soc_card *card = card_data->card; + struct device *dev = card->dev; + struct device_node *hdmi_codec, *headset_codec, *speaker_codec; struct snd_soc_dai_link *dai_link; - struct mt8192_mt6359_priv *priv; - - card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); - if (!card) - return -EINVAL; - card->dev = &pdev->dev; - - if (of_device_is_compatible(pdev->dev.of_node, RT1015P_RT5682_OF_NAME)) - card->name = RT1015P_RT5682_CARD_NAME; - else if (of_device_is_compatible(pdev->dev.of_node, RT1015P_RT5682S_OF_NAME)) - card->name = RT1015P_RT5682S_CARD_NAME; - else - dev_dbg(&pdev->dev, "No need to set card name\n"); + int ret, i; - hdmi_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,hdmi-codec", 0); + hdmi_codec = of_parse_phandle(dev->of_node, "mediatek,hdmi-codec", 0); if (!hdmi_codec) - dev_dbg(&pdev->dev, "The machine has no hdmi-codec\n"); + dev_dbg(dev, "The machine has no hdmi-codec\n"); - platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); - if (!platform_node) { - ret = -EINVAL; - dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); - goto err_platform_node; - } - - speaker_codec = of_get_child_by_name(pdev->dev.of_node, "speaker-codecs"); + speaker_codec = of_get_child_by_name(dev->of_node, "speaker-codecs"); if (!speaker_codec) { ret = -EINVAL; - dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n"); + dev_err_probe(dev, ret, "Property 'speaker-codecs' missing or invalid\n"); goto err_speaker_codec; } - headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec"); + headset_codec = of_get_child_by_name(dev->of_node, "headset-codec"); if (!headset_codec) { ret = -EINVAL; - dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n"); + dev_err_probe(dev, ret, "Property 'headset-codec' missing or invalid\n"); goto err_headset_codec; } for_each_card_prelinks(card, i, dai_link) { ret = mt8192_mt6359_card_set_be_link(card, dai_link, speaker_codec, "I2S3"); if (ret) { - dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n", + dev_err_probe(dev, ret, "%s set speaker_codec fail\n", dai_link->name); - goto err_probe; + break; } ret = mt8192_mt6359_card_set_be_link(card, dai_link, headset_codec, "I2S8"); if (ret) { - dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n", + dev_err_probe(dev, ret, "%s set headset_codec fail\n", dai_link->name); - goto err_probe; + break; } ret = mt8192_mt6359_card_set_be_link(card, dai_link, headset_codec, "I2S9"); if (ret) { - dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n", + dev_err_probe(dev, ret, "%s set headset_codec fail\n", dai_link->name); - goto err_probe; + break; } if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { @@ -1211,52 +1196,85 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) if (dai_link->num_codecs && dai_link->codecs[0].dai_name && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; - - if (!dai_link->platforms->name) - dai_link->platforms->of_node = platform_node; - } - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_probe; - } - snd_soc_card_set_drvdata(card, priv); - - ret = mt8192_afe_gpio_init(&pdev->dev); - if (ret) { - dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__); - goto err_probe; } - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__); - -err_probe: of_node_put(headset_codec); err_headset_codec: of_node_put(speaker_codec); err_speaker_codec: - of_node_put(platform_node); -err_platform_node: - of_node_put(hdmi_codec); + if (hdmi_codec) + of_node_put(hdmi_codec); + return ret; } +static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy) +{ + struct mtk_platform_card_data *card_data = soc_card_data->card_data; + struct snd_soc_card *card = card_data->card; + int ret; + + if (legacy) { + ret = mt8192_mt6359_legacy_probe(soc_card_data); + if (ret) + return ret; + } else { + struct snd_soc_dai_link *dai_link; + int i; + + for_each_card_prelinks(card, i, dai_link) + if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) + dai_link->ops = &mt8192_rt1015_i2s_ops; + } + + ret = mt8192_afe_gpio_init(card->dev); + if (ret) + return dev_err_probe(card->dev, ret, "%s init gpio error\n", __func__); + + return 0; +} + +static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015_rt5682_pdata = { + .card_name = RT1015_RT5682_CARD_NAME, + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8192_mt6359_rt1015_rt5682_card, + .num_jacks = MT8192_JACK_MAX, + }, + .soc_probe = mt8192_mt6359_soc_card_probe +}; + +static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015p_rt5682_pdata = { + .card_name = RT1015P_RT5682_CARD_NAME, + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8192_mt6359_rt1015p_rt5682x_card, + .num_jacks = MT8192_JACK_MAX, + }, + .soc_probe = mt8192_mt6359_soc_card_probe +}; + +static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015p_rt5682s_pdata = { + .card_name = RT1015P_RT5682S_CARD_NAME, + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8192_mt6359_rt1015p_rt5682x_card, + .num_jacks = MT8192_JACK_MAX, + }, + .soc_probe = mt8192_mt6359_soc_card_probe +}; + #ifdef CONFIG_OF static const struct of_device_id mt8192_mt6359_dt_match[] = { { .compatible = RT1015_RT5682_OF_NAME, - .data = &mt8192_mt6359_rt1015_rt5682_card, + .data = &mt8192_mt6359_rt1015_rt5682_pdata, }, { .compatible = RT1015P_RT5682_OF_NAME, - .data = &mt8192_mt6359_rt1015p_rt5682x_card, + .data = &mt8192_mt6359_rt1015p_rt5682_pdata, }, { .compatible = RT1015P_RT5682S_OF_NAME, - .data = &mt8192_mt6359_rt1015p_rt5682x_card, + .data = &mt8192_mt6359_rt1015p_rt5682s_pdata, }, {} }; @@ -1276,7 +1294,7 @@ static struct platform_driver mt8192_mt6359_driver = { #endif .pm = &mt8192_mt6359_pm_ops, }, - .probe = mt8192_mt6359_dev_probe, + .probe = mtk_soundcard_common_probe, }; module_platform_driver(mt8192_mt6359_driver); -- GitLab From a5d120a5f0cb57fca0872b4f7cde0d6abdc41b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 26 Nov 2024 15:09:43 -0500 Subject: [PATCH 008/456] FROMGIT: ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following commit 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()"), COMP_DUMMY() became an array with zero length, and only gets populated with the dummy struct after the card is registered. Since the sound card driver's probe happens before the card registration, accessing any of the members of a dummy component during probe will result in undefined behavior. This can be observed in the mt8188 and mt8195 machine sound drivers. By omitting a dai link subnode in the sound card's node in the Devicetree, the default uninitialized dummy codec is used, and when its dai_name pointer gets passed to strcmp() it results in a null pointer dereference and a kernel panic. In addition to that, set_card_codec_info() in the generic helpers file, mtk-soundcard-driver.c, will populate a dai link with a dummy codec when a dai link node is present in DT but with no codec property. The result is that at probe time, a dummy codec can either be uninitialized with num_codecs = 0, or be an initialized dummy codec, with num_codecs = 1 and dai_name = "snd-soc-dummy-dai". In order to accommodate for both situations, check that num_codecs is not zero before accessing the codecs' fields but still check for the codec's dai name against "snd-soc-dummy-dai" as needed. While at it, also drop the check that dai_name is not null in the mt8192 driver, introduced in commit 4d4e1b6319e5 ("ASoC: mediatek: mt8192: Check existence of dai_name before dereferencing"), as it is actually redundant given the preceding num_codecs != 0 check. Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Acked-by: Kuninori Morimoto Reviewed-by: Fei Shao Acked-by: Trevor Wu Link: https://patch.msgid.link/20241126-asoc-mtk-dummy-panic-v1-1-42d53e168d2e@collabora.com Signed-off-by: Mark Brown (cherry picked from commit 2f2020327cc8561d7c520d2f2d9acea84fa7b3a3 git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next) BUG=b:380813926 TEST=Boot and test audio on ciri Change-Id: Ib2b2b0587f45133f854af3d5e09f7f5781cfa1bd Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057110 Commit-Queue: Pin-yen Lin Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 9 +++++++-- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 4 ++-- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 9 +++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 1550e56ab57d5..62429e8e57b55 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -1277,10 +1277,12 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC_BE") == 0) { @@ -1292,6 +1294,9 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { /* * The TDM protocol settings with fixed 4 slots are defined in diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 645bc1aa67c7f..4fcaab1efded1 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -1193,7 +1193,7 @@ static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data) dai_link->ignore = 0; } - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } @@ -1223,7 +1223,7 @@ static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, int i; for_each_card_prelinks(card, i, dai_link) - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 6e53bc4a77242..7165b8c8b6d71 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -1509,10 +1509,12 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC1_BE") == 0 || @@ -1525,6 +1527,9 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { if (!(codec_init & MAX98390_CODEC_INIT)) { dai_link->init = mt8195_max98390_init; -- GitLab From 064511be1691a0105bb7880904757140644e4f47 Mon Sep 17 00:00:00 2001 From: Jameson Thies Date: Wed, 27 Nov 2024 21:32:33 +0000 Subject: [PATCH 009/456] CHROMIUM: config: Enable CONFIG_USB_LINK_LAYER_TEST Enable CONFIG_USB_LINK_LAYER_TEST as a module to add the lvstest driver. BUG=b:373699419 TEST=emerge-brya chromeos-kernel-6_6, modprobe lvstest Change-Id: I15083cb72112672d540d214282d23fce9b1a4045 Signed-off-by: Jameson Thies Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055589 Reviewed-by: Benson Leung Signed-off-by: Hubert Mazur --- .../chromeos/x86_64/chromeos-intel-pineview.flavour.config | 1 + 1 file changed, 1 insertion(+) diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config index 5c5ab78203cf0..6836b7f3bdbf0 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config @@ -179,6 +179,7 @@ CONFIG_USB4=y CONFIG_USB4_DEBUGFS_WRITE=y CONFIG_USB4_DMA_TEST=m CONFIG_USB4_NET=m +CONFIG_USB_LINK_LAYER_TEST=m CONFIG_VFIO=m CONFIG_VFIO_PCI=m CONFIG_VIDEO_AK7375=m -- GitLab From cdfaf612b19736dd3d5bb0ec289113fa9dc4e49c Mon Sep 17 00:00:00 2001 From: Pin-yen Lin Date: Thu, 28 Nov 2024 18:37:59 +0800 Subject: [PATCH 010/456] CHROMIUM: arm64: dts: mt8186: Change LVTS compatible string Use a different compatible string for the downstream forward-ported LVTS thermal driver for Corsola. This is to prevent conflict with the upstream LVTS driver, which will be added by to chromeos-6.6 for Geralt. BUG=b:337997758, b:381377918 TEST=`grep . /sys/class/thermal/thermal_zone*/type` on Rusty UPSTREAM-TASK=b:339741475 Cq-Depend: chromium:6057115 Change-Id: Iccac1fa5649ac42b9d20c29dda7d80ddf6bc79b3 Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055959 Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8186.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi index 835dfd2f2e40c..5253f9748a22f 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi @@ -1357,7 +1357,7 @@ }; lvts: thermal-sensor@1100b000 { - compatible = "mediatek,mt8186-lvts"; + compatible = "mediatek,mt8186-lvts-legacy"; reg = <0 0x1100b000 0 0x1000>; interrupts = ; clocks = <&infracfg_ao CLK_INFRA_AO_THERM>; -- GitLab From 3730317eacede557baa0ee46e8396d7843cef0a7 Mon Sep 17 00:00:00 2001 From: Stuti Saxena Date: Tue, 14 May 2024 12:29:42 +0530 Subject: [PATCH 011/456] CHROMIUM: msm: camera: common: Fixing nested irq locking call This change fixes nested irq call from vfe core to vfe bus flow. Ensures hw lock is taken while handling bus top half. BUG=b:332260372 UPSTREAM-TASK=b:274966069 TEST=senozhatsky: CCA preview and CTS on strongbad under lockdep Change-Id: I4e8472d2a2ca025823831f97e3f7ed1076b80808 Signed-off-by: Stuti Saxena Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6048309 Commit-Queue: Ricardo Ribalda Reviewed-by: Sergey Senozhatsky Tested-by: Sergey Senozhatsky Reviewed-by: Ricardo Ribalda Signed-off-by: Hubert Mazur --- .../irq_controller/cam_irq_controller.c | 137 ++++++++++++++++-- .../irq_controller/cam_irq_controller.h | 20 ++- .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 21 ++- .../vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c | 8 +- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c | 27 ++-- 5 files changed, 176 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c index b2f4370d29830..708c6c78e58ab 100644 --- a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c +++ b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c @@ -108,6 +108,7 @@ struct cam_irq_controller { struct list_head th_list_head[CAM_IRQ_PRIORITY_MAX]; uint32_t hdl_idx; spinlock_t lock; + spinlock_t th_lock; struct cam_irq_th_payload th_payload; }; @@ -217,6 +218,7 @@ int cam_irq_controller_init(const char *name, void __iomem *mem_base, INIT_LIST_HEAD(&controller->th_list_head[i]); spin_lock_init(&controller->lock); + spin_lock_init(&controller->th_lock); controller->hdl_idx = 1; *irq_controller = controller; @@ -272,7 +274,8 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, CAM_IRQ_HANDLER_TOP_HALF top_half_handler, CAM_IRQ_HANDLER_BOTTOM_HALF bottom_half_handler, void *bottom_half, - struct cam_irq_bh_api *irq_bh_api) + struct cam_irq_bh_api *irq_bh_api, + enum cam_irq_controller_type controller_type) { struct cam_irq_controller *controller = irq_controller; struct cam_irq_evt_handler *evt_handler = NULL; @@ -355,12 +358,30 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, controller->hdl_idx = 1; if (!in_irq()) { - spin_lock_irqsave(&controller->lock, flags); - rc = _cam_irq_controller_subscribe_irq(controller, - priority, - evt_bit_mask_arr, - evt_handler); - spin_unlock_irqrestore(&controller->lock, flags); + switch (controller_type) { + case CAM_IRQ_CONTROLLER_VFE: + spin_lock_irqsave(&controller->lock, flags); + CAM_DBG(CAM_IRQ_CTRL, "~IRQ: controller: %s", controller->name); + rc = _cam_irq_controller_subscribe_irq(controller, + priority, + evt_bit_mask_arr, + evt_handler); + spin_unlock_irqrestore(&controller->lock, flags); + break; + + case CAM_IRQ_CONTROLLER_VFE_BUS: + spin_lock_irqsave(&controller->th_lock, flags); + CAM_DBG(CAM_IRQ_CTRL, "~IRQ: controller: %s", controller->name); + rc = _cam_irq_controller_subscribe_irq(controller, + priority, + evt_bit_mask_arr, + evt_handler); + spin_unlock_irqrestore(&controller->th_lock, flags); + break; + default: + CAM_DBG(CAM_IRQ_CTRL, "~IRQ: Invalid Controller %s", controller->name); + break; + } } else { rc = _cam_irq_controller_subscribe_irq(controller, priority, @@ -515,7 +536,8 @@ _cam_irq_controller_unsubscribe_irq(struct cam_irq_controller *controller, } int cam_irq_controller_unsubscribe_irq(void *irq_controller, - uint32_t handle) + uint32_t handle, + enum cam_irq_controller_type controller_type) { struct cam_irq_controller *controller; unsigned long flags; @@ -527,10 +549,24 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller, controller = irq_controller; if (!in_irq()) { - spin_lock_irqsave(&controller->lock, flags); - rc = _cam_irq_controller_unsubscribe_irq(irq_controller, - handle); - spin_unlock_irqrestore(&controller->lock, flags); + switch (controller_type) { + case CAM_IRQ_CONTROLLER_VFE: + spin_lock_irqsave(&controller->lock, flags); + rc = _cam_irq_controller_unsubscribe_irq(irq_controller, + handle); + spin_unlock_irqrestore(&controller->lock, flags); + break; + case CAM_IRQ_CONTROLLER_VFE_BUS: + spin_lock_irqsave(&controller->th_lock, flags); + rc = _cam_irq_controller_unsubscribe_irq(irq_controller, + handle); + spin_unlock_irqrestore(&controller->th_lock, flags); + break; + default: + CAM_DBG(CAM_IRQ_CTRL, "~IRQ: Invalid Controller %s", controller->name); + rc = -EINVAL; + break; + } } else { rc = _cam_irq_controller_unsubscribe_irq(irq_controller, handle); @@ -561,8 +597,11 @@ static bool cam_irq_controller_match_bit_mask( for (i = 0; i < controller->num_registers; i++) { if (evt_handler->evt_bit_mask_arr[i] & - controller->irq_status_arr[i]) + controller->irq_status_arr[i]) { + CAM_DBG(CAM_IRQ_CTRL, "controller name: %s; num_registers: %u", + controller->name, controller->num_registers); return true; + } } return false; @@ -601,6 +640,13 @@ static void cam_irq_controller_th_processing( th_payload->evt_status_arr[i] = controller->irq_status_arr[i] & evt_handler->evt_bit_mask_arr[i]; + + CAM_DBG(CAM_IRQ_CTRL, "%s: evt_handler: evt_bit_mask_arr[%d]: 0x%X", + controller->name, i, evt_handler->evt_bit_mask_arr[i]); + CAM_DBG(CAM_IRQ_CTRL, "%s: controller : irq_status_arr[%d]: 0x%X", + controller->name, i, controller->irq_status_arr[i]); + CAM_DBG(CAM_IRQ_CTRL, "%s: th_payload : evt_status_arr[%d]: 0x%X", + controller->name, i, th_payload->evt_status_arr[i]); } irq_bh_api = &evt_handler->irq_bh_api; @@ -620,10 +666,13 @@ static void cam_irq_controller_th_processing( * irq_status_arr[0] is dummy argument passed. the entire * status array is passed in th_payload. */ - if (evt_handler->top_half_handler) + if (evt_handler->top_half_handler) { + CAM_DBG(CAM_IRQ_CTRL, "Top Half Handler, dummy argument for controller %s evnt-ID : 0x%X", + controller->name, controller->irq_status_arr[0]); rc = evt_handler->top_half_handler( controller->irq_status_arr[0], (void *)th_payload); + } if (rc && bh_cmd) { irq_bh_api->put_bh_payload_func( @@ -729,3 +778,63 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv) return IRQ_HANDLED; } + +irqreturn_t cam_vfe_bus_controller_handle_irq(int irq_num, void *priv) +{ + struct cam_irq_controller *controller = priv; + struct cam_irq_register_obj *irq_register; + bool need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false}; + int i; + int j; + + if (!controller) + return IRQ_NONE; + + CAM_DBG(CAM_IRQ_CTRL, + "Locking: %s IRQ Controller: [%pK], lock handle: %pK irq_num: %d", + controller->name, controller, &controller->th_lock, irq_num); + + spin_lock(&controller->th_lock); + for (i = 0; i < controller->num_registers; i++) { + + irq_register = &controller->irq_register_arr[i]; + + controller->irq_status_arr[i] = + cam_io_r_mb(controller->mem_base + controller->irq_register_arr[i].status_reg_offset); + + cam_io_w_mb(controller->irq_status_arr[i], + controller->mem_base + controller->irq_register_arr[i].clear_reg_offset); + + CAM_DBG(CAM_IRQ_CTRL, "Read irq status%d (0x%x) = 0x%x", i, + controller->irq_register_arr[i].status_reg_offset, + controller->irq_status_arr[i]); + + for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) { + if (irq_register->top_half_enable_mask[j] & + controller->irq_status_arr[i]) + need_th_processing[j] = true; + } + } + + CAM_DBG(CAM_IRQ_CTRL, "Status Registers read Successful"); + + if (controller->global_clear_offset) + cam_io_w_mb(controller->global_clear_bitmask, + controller->mem_base + controller->global_clear_offset); + + CAM_DBG(CAM_IRQ_CTRL, "Status Clear done"); + + for (i = 0; i < CAM_IRQ_PRIORITY_MAX; i++) { + if (need_th_processing[i]) { + CAM_DBG(CAM_IRQ_CTRL, "Invoke TH processing"); + cam_irq_controller_th_processing(controller, + &controller->th_list_head[i]); + } + } + spin_unlock(&controller->th_lock); + + CAM_DBG(CAM_IRQ_CTRL, "Unlocked: %s IRQ Controller: %pK, lock handle: %pK", + controller->name, controller, &controller->th_lock); + + return IRQ_HANDLED; +} diff --git a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h index 4962a35b4812a..95c77626578ea 100644 --- a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h +++ b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h @@ -18,6 +18,19 @@ #define CAM_IRQ_BITS_PER_REGISTER 32 +/* + * enum cam_irq_controller_type: + * @Brief: Controller type for IRQ events. + * CONTROLLER_VFE + * CONTROLLER_VFE_BUS + * + */ +enum cam_irq_controller_type { + CAM_IRQ_CONTROLLER_VFE, + CAM_IRQ_CONTROLLER_VFE_BUS, + CAM_IRQ_CONTROLLER_MAX, +}; + /* * enum cam_irq_priority_level: * @Brief: Priority levels for IRQ events. @@ -177,7 +190,8 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, CAM_IRQ_HANDLER_TOP_HALF top_half_handler, CAM_IRQ_HANDLER_BOTTOM_HALF bottom_half_handler, void *bottom_half, - struct cam_irq_bh_api *irq_bh_api); + struct cam_irq_bh_api *irq_bh_api, + enum cam_irq_controller_type controller_type); /* * cam_irq_controller_unsubscribe_irq() @@ -192,7 +206,7 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, * Negative: Failure */ int cam_irq_controller_unsubscribe_irq(void *irq_controller, - uint32_t handle); + uint32_t handle, enum cam_irq_controller_type controller_type); /* * cam_irq_controller_deinit() @@ -226,6 +240,8 @@ int cam_irq_controller_deinit(void **irq_controller); */ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv); +irqreturn_t cam_vfe_bus_controller_handle_irq(int irq_num, void *priv); + /* * cam_irq_controller_disable_irq() * diff --git a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 85d9021f96e98..ed502900f9b10 100644 --- a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -405,7 +405,7 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size) core_info->irq_handle = cam_irq_controller_subscribe_irq( core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_0, top_reset_irq_reg_mask, &core_info->irq_payload, - cam_vfe_reset_irq_top_half, NULL, NULL, NULL); + cam_vfe_reset_irq_top_half, NULL, NULL, NULL, CAM_IRQ_CONTROLLER_VFE); if (core_info->irq_handle < 0) { CAM_ERR(CAM_ISP, "subscribe irq controller failed"); return -EFAULT; @@ -425,7 +425,7 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size) CAM_DBG(CAM_ISP, "reset complete done (%d)", rc); rc = cam_irq_controller_unsubscribe_irq( - core_info->vfe_irq_controller, core_info->irq_handle); + core_info->vfe_irq_controller, core_info->irq_handle, CAM_IRQ_CONTROLLER_VFE); if (rc) CAM_ERR(CAM_ISP, "Error! Unsubscribe failed"); @@ -599,7 +599,8 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, isp_res->tasklet_info, - &tasklet_bh_api); + &tasklet_bh_api, + CAM_IRQ_CONTROLLER_VFE); if (isp_res->irq_handle < 1) rc = -ENOMEM; } else if (isp_res->res_id == CAM_ISP_HW_VFE_IN_RD) { @@ -612,7 +613,8 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, isp_res->tasklet_info, - &tasklet_bh_api); + &tasklet_bh_api, + CAM_IRQ_CONTROLLER_VFE); if (isp_res->irq_handle < 1) rc = -ENOMEM; } else if (isp_res->rdi_only_ctx) { @@ -636,7 +638,8 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, isp_res->tasklet_info, - &tasklet_bh_api); + &tasklet_bh_api, + CAM_IRQ_CONTROLLER_VFE); if (isp_res->irq_handle < 1) rc = -ENOMEM; } @@ -673,7 +676,8 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_vfe_irq_err_top_half, cam_ife_mgr_do_tasklet, core_info->tasklet_info, - &tasklet_bh_api); + &tasklet_bh_api, + CAM_IRQ_CONTROLLER_VFE); if (core_info->irq_err_handle < 1) { CAM_ERR(CAM_ISP, "Error handle subscribe failure"); rc = -ENOMEM; @@ -705,7 +709,7 @@ int cam_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size) mutex_lock(&vfe_hw->hw_mutex); if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN) { cam_irq_controller_unsubscribe_irq( - core_info->vfe_irq_controller, isp_res->irq_handle); + core_info->vfe_irq_controller, isp_res->irq_handle, CAM_IRQ_CONTROLLER_VFE); isp_res->irq_handle = 0; rc = core_info->vfe_top->hw_ops.stop( @@ -724,7 +728,8 @@ int cam_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size) if (core_info->irq_err_handle) { cam_irq_controller_unsubscribe_irq( core_info->vfe_irq_controller, - core_info->irq_err_handle); + core_info->irq_err_handle, + CAM_IRQ_CONTROLLER_VFE); core_info->irq_err_handle = 0; } diff --git a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c index 0aecef6355b31..c692d65b7567f 100644 --- a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c +++ b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c @@ -955,7 +955,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv, cam_vfe_bus_rd_ver1_handle_irq, NULL, NULL, - NULL); + NULL, + CAM_IRQ_CONTROLLER_VFE_BUS); if (bus_priv->irq_handle <= 0) { CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ"); @@ -995,7 +996,7 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv, if (bus_priv->error_irq_handle) { rc = cam_irq_controller_unsubscribe_irq( bus_priv->common_data.bus_irq_controller, - bus_priv->error_irq_handle); + bus_priv->error_irq_handle, CAM_IRQ_CONTROLLER_VFE_BUS); if (rc) CAM_ERR(CAM_ISP, "Failed to unsubscribe error irq rc=%d", rc); @@ -1006,7 +1007,8 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv, if (bus_priv->irq_handle) { rc = cam_irq_controller_unsubscribe_irq( bus_priv->common_data.vfe_irq_controller, - bus_priv->irq_handle); + bus_priv->irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); if (rc) CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc); diff --git a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index 1ed165dfda1b6..a2b583bf70c97 100644 --- a/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/drivers/media/platform/camx/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -1177,7 +1177,7 @@ static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res) bus_irq_reg_mask, wm_res, wm_res->top_half_handler, cam_ife_mgr_do_tasklet_buf_done, - wm_res->tasklet_info, &tasklet_bh_api); + wm_res->tasklet_info, &tasklet_bh_api, CAM_IRQ_CONTROLLER_VFE_BUS); if (wm_res->irq_handle < 0) { CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d", rsrc_data->index); @@ -1262,7 +1262,8 @@ static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res) if (rsrc_data->irq_enabled) rc = cam_irq_controller_unsubscribe_irq( common_data->bus_irq_controller, - wm_res->irq_handle); + wm_res->irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; @@ -1988,7 +1989,7 @@ static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp) bus_irq_reg_mask, comp_grp, comp_grp->top_half_handler, cam_ife_mgr_do_tasklet_buf_done, - comp_grp->tasklet_info, &tasklet_bh_api); + comp_grp->tasklet_info, &tasklet_bh_api, CAM_IRQ_CONTROLLER_VFE_BUS); if (comp_grp->irq_handle < 0) { CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d", rsrc_data->comp_grp_type); @@ -2016,7 +2017,8 @@ static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp) rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)) { rc = cam_irq_controller_unsubscribe_irq( common_data->bus_irq_controller, - comp_grp->irq_handle); + comp_grp->irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); } comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; @@ -2678,7 +2680,7 @@ static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id, bus_priv = th_payload->handler_priv; CAM_DBG(CAM_ISP, "Enter"); - rc = cam_irq_controller_handle_irq(evt_id, + rc = cam_vfe_bus_controller_handle_irq(evt_id, bus_priv->common_data.bus_irq_controller); return (rc == IRQ_HANDLED) ? 0 : -EINVAL; } @@ -3419,7 +3421,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv, cam_vfe_bus_ver2_handle_irq, NULL, NULL, - NULL); + NULL, + CAM_IRQ_CONTROLLER_VFE_BUS); if ((int)bus_priv->irq_handle <= 0) { CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ"); @@ -3435,7 +3438,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv, cam_vfe_bus_error_irq_top_half, cam_vfe_bus_err_bottom_half, bus_priv->tasklet_info, - &tasklet_bh_api); + &tasklet_bh_api, + CAM_IRQ_CONTROLLER_VFE_BUS); if ((int)bus_priv->error_irq_handle <= 0) { CAM_ERR(CAM_ISP, "Failed to subscribe BUS error IRQ %d", @@ -3480,7 +3484,8 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv, if (bus_priv->error_irq_handle) { rc = cam_irq_controller_unsubscribe_irq( bus_priv->common_data.bus_irq_controller, - bus_priv->error_irq_handle); + bus_priv->error_irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); if (rc) CAM_ERR(CAM_ISP, "Failed to unsubscribe error irq rc=%d", rc); @@ -3491,7 +3496,8 @@ static int cam_vfe_bus_deinit_hw(void *hw_priv, if (bus_priv->irq_handle) { rc = cam_irq_controller_unsubscribe_irq( bus_priv->common_data.vfe_irq_controller, - bus_priv->irq_handle); + bus_priv->irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); if (rc) CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc); @@ -3547,7 +3553,8 @@ static int cam_vfe_bus_process_cmd( CAM_DBG(CAM_ISP, "Mask off bus error irq handler"); rc = cam_irq_controller_unsubscribe_irq( bus_priv->common_data.bus_irq_controller, - bus_priv->error_irq_handle); + bus_priv->error_irq_handle, + CAM_IRQ_CONTROLLER_VFE_BUS); if (rc) CAM_ERR(CAM_ISP, "Failed to unsubscribe error irq rc=%d", -- GitLab From 0519e0ff3daa44484cfbe991aef01132f056a58e Mon Sep 17 00:00:00 2001 From: Pin-yen Lin Date: Thu, 28 Nov 2024 17:41:11 +0800 Subject: [PATCH 012/456] FIXUP: CHROMIUM: mt8195: backport legacy SOC_LVTS_TEMP as the out-of-tree driver CL:5528009 removed lvts_thermal.o from Makefile when it pulled back the downstream thermal driver for MT8195 and MT8186. Add lvts_thermal.c back for MT8188 and change the compatible strings for MT8186 to keep Corsola on the downstream LVTS driver. BUG=b:381377918 TEST=`grep . /sys/class/thermal/thermal_zone*/type` on Ciri and Tomato UPSTREAM-TASK=b:339741475 Signed-off-by: Pin-yen Lin Change-Id: I940620dc93bd67ff9586be730fa5fc562f64f1ca Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057115 Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/thermal/mediatek/Makefile | 1 + drivers/thermal/mediatek/soc_temp_lvts_mt8192.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile index 5ce1cfb9f6ffd..409964f83ac7c 100644 --- a/drivers/thermal/mediatek/Makefile +++ b/drivers/thermal/mediatek/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o +obj-$(CONFIG_MTK_LVTS_THERMAL) += lvts_thermal.o obj-$(CONFIG_MTK_LVTS_THERMAL) += soc_temp_lvts.o obj-$(CONFIG_MTK_LVTS_THERMAL) += soc_temp_lvts_mt8192.o diff --git a/drivers/thermal/mediatek/soc_temp_lvts_mt8192.c b/drivers/thermal/mediatek/soc_temp_lvts_mt8192.c index 84daf06aeb754..cc8830e32d25e 100644 --- a/drivers/thermal/mediatek/soc_temp_lvts_mt8192.c +++ b/drivers/thermal/mediatek/soc_temp_lvts_mt8192.c @@ -1635,7 +1635,7 @@ static const struct of_device_id lvts_of_match[] = { .data = (void *)&mt8195_lvts_data, }, { - .compatible = "mediatek,mt8186-lvts", + .compatible = "mediatek,mt8186-lvts-legacy", .data = (void *)&mt8186_lvts_data, }, { -- GitLab From 6685a52ca7215074e6d04b520c7f3eed305397ca Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Sat, 30 Nov 2024 02:15:25 +0000 Subject: [PATCH 013/456] UPSTREAM: mseal: update mseal.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pedro Falcato's optimization [1] for checking sealed VMAs, which replaces the can_modify_mm() function with an in-loop check, necessitates an update to the mseal.rst documentation to reflect this change. Furthermore, the document has received offline comments regarding the code sample and suggestions for sentence clarification to enhance reader comprehension. [1] https://lore.kernel.org/linux-mm/20240817-mseal-depessimize-v3-0-d8d2e037df30@gmail.com/ Update doc after in-loop change: mprotect/madvise can have partially updated and munmap is atomic. Fix indentation and clarify some sections to improve readability. Link: https://lkml.kernel.org/r/20241008040942.1478931-2-jeffxu@chromium.org Fixes: df2a7df9a9aa ("mm/munmap: replace can_modify_mm with can_modify_vma") Fixes: 4a2dd02b0916 ("mm/mprotect: replace can_modify_mm with can_modify_vma") Fixes: 38075679b5f1 ("mm/mremap: replace can_modify_mm with can_modify_vma") Fixes: 23c57d1fa2b9 ("mseal: replace can_modify_mm_madv with a vma variant") Signed-off-by: Jeff Xu Reviewed-by: Randy Dunlap Cc: Elliott Hughes Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Jann Horn Cc: Jonathan Corbet Cc: Jorge Lucangeli Obes Cc: Kees Cook Cc: "Liam R. Howlett" Cc: Linus Torvalds Cc: Lorenzo Stoakes Cc: Matthew Wilcox Cc: Muhammad Usama Anjum Cc: Pedro Falcato Cc: Stephen Röttger Cc: Suren Baghdasaryan Cc: "Theo de Raadt" Signed-off-by: Andrew Morton (cherry picked from commit 183430079869fcb4b2967800d7659bbeb6052d07) BUG=b:376740772 TEST=CQ Test Signed-off-by: Linux Patches Robot Change-Id: I6525a9a5cd8b60b099db9058d3aff331a2169738 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6043117 Reviewed-by: Jeff Xu Tested-by: Jeff Xu Reviewed-by: Jorge Lucangeli Obes Commit-Queue: Jeff Xu Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- Documentation/userspace-api/mseal.rst | 307 +++++++++++++------------- 1 file changed, 148 insertions(+), 159 deletions(-) diff --git a/Documentation/userspace-api/mseal.rst b/Documentation/userspace-api/mseal.rst index 4132eec995a39..41102f74c5e20 100644 --- a/Documentation/userspace-api/mseal.rst +++ b/Documentation/userspace-api/mseal.rst @@ -23,177 +23,166 @@ applications can additionally seal security critical data at runtime. A similar feature already exists in the XNU kernel with the VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2]. -User API -======== -mseal() ------------ -The mseal() syscall has the following signature: - -``int mseal(void addr, size_t len, unsigned long flags)`` - -**addr/len**: virtual memory address range. - -The address range set by ``addr``/``len`` must meet: - - The start address must be in an allocated VMA. - - The start address must be page aligned. - - The end address (``addr`` + ``len``) must be in an allocated VMA. - - no gap (unallocated memory) between start and end address. - -The ``len`` will be paged aligned implicitly by the kernel. - -**flags**: reserved for future use. - -**return values**: - -- ``0``: Success. - -- ``-EINVAL``: - - Invalid input ``flags``. - - The start address (``addr``) is not page aligned. - - Address range (``addr`` + ``len``) overflow. - -- ``-ENOMEM``: - - The start address (``addr``) is not allocated. - - The end address (``addr`` + ``len``) is not allocated. - - A gap (unallocated memory) between start and end address. - -- ``-EPERM``: - - sealing is supported only on 64-bit CPUs, 32-bit is not supported. - -- For above error cases, users can expect the given memory range is - unmodified, i.e. no partial update. - -- There might be other internal errors/cases not listed here, e.g. - error during merging/splitting VMAs, or the process reaching the max - number of supported VMAs. In those cases, partial updates to the given - memory range could happen. However, those cases should be rare. - -**Blocked operations after sealing**: - Unmapping, moving to another location, and shrinking the size, - via munmap() and mremap(), can leave an empty space, therefore - can be replaced with a VMA with a new set of attributes. - - Moving or expanding a different VMA into the current location, - via mremap(). - - Modifying a VMA via mmap(MAP_FIXED). - - Size expansion, via mremap(), does not appear to pose any - specific risks to sealed VMAs. It is included anyway because - the use case is unclear. In any case, users can rely on - merging to expand a sealed VMA. - - mprotect() and pkey_mprotect(). - - Some destructive madvice() behaviors (e.g. MADV_DONTNEED) - for anonymous memory, when users don't have write permission to the - memory. Those behaviors can alter region contents by discarding pages, - effectively a memset(0) for anonymous memory. - - Kernel will return -EPERM for blocked operations. - - For blocked operations, one can expect the given address is unmodified, - i.e. no partial update. Note, this is different from existing mm - system call behaviors, where partial updates are made till an error is - found and returned to userspace. To give an example: - - Assume following code sequence: - - - ptr = mmap(null, 8192, PROT_NONE); - - munmap(ptr + 4096, 4096); - - ret1 = mprotect(ptr, 8192, PROT_READ); - - mseal(ptr, 4096); - - ret2 = mprotect(ptr, 8192, PROT_NONE); - - ret1 will be -ENOMEM, the page from ptr is updated to PROT_READ. - - ret2 will be -EPERM, the page remains to be PROT_READ. - -**Note**: - -- mseal() only works on 64-bit CPUs, not 32-bit CPU. - -- users can call mseal() multiple times, mseal() on an already sealed memory - is a no-action (not error). - -- munseal() is not supported. - -Use cases: -========== +SYSCALL +======= +mseal syscall signature +----------------------- + ``int mseal(void \* addr, size_t len, unsigned long flags)`` + + **addr**/**len**: virtual memory address range. + The address range set by **addr**/**len** must meet: + - The start address must be in an allocated VMA. + - The start address must be page aligned. + - The end address (**addr** + **len**) must be in an allocated VMA. + - no gap (unallocated memory) between start and end address. + + The ``len`` will be paged aligned implicitly by the kernel. + + **flags**: reserved for future use. + + **Return values**: + - **0**: Success. + - **-EINVAL**: + * Invalid input ``flags``. + * The start address (``addr``) is not page aligned. + * Address range (``addr`` + ``len``) overflow. + - **-ENOMEM**: + * The start address (``addr``) is not allocated. + * The end address (``addr`` + ``len``) is not allocated. + * A gap (unallocated memory) between start and end address. + - **-EPERM**: + * sealing is supported only on 64-bit CPUs, 32-bit is not supported. + + **Note about error return**: + - For above error cases, users can expect the given memory range is + unmodified, i.e. no partial update. + - There might be other internal errors/cases not listed here, e.g. + error during merging/splitting VMAs, or the process reaching the maximum + number of supported VMAs. In those cases, partial updates to the given + memory range could happen. However, those cases should be rare. + + **Architecture support**: + mseal only works on 64-bit CPUs, not 32-bit CPUs. + + **Idempotent**: + users can call mseal multiple times. mseal on an already sealed memory + is a no-action (not error). + + **no munseal** + Once mapping is sealed, it can't be unsealed. The kernel should never + have munseal, this is consistent with other sealing feature, e.g. + F_SEAL_SEAL for file. + +Blocked mm syscall for sealed mapping +------------------------------------- + It might be important to note: **once the mapping is sealed, it will + stay in the process's memory until the process terminates**. + + Example:: + + *ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + rc = mseal(ptr, 4096, 0); + /* munmap will fail */ + rc = munmap(ptr, 4096); + assert(rc < 0); + + Blocked mm syscall: + - munmap + - mmap + - mremap + - mprotect and pkey_mprotect + - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, + MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK + + The first set of syscalls to block is munmap, mremap, mmap. They can + either leave an empty space in the address space, therefore allowing + replacement with a new mapping with new set of attributes, or can + overwrite the existing mapping with another mapping. + + mprotect and pkey_mprotect are blocked because they changes the + protection bits (RWX) of the mapping. + + Certain destructive madvise behaviors, specifically MADV_DONTNEED, + MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce + risks when applied to anonymous memory by threads lacking write + permissions. Consequently, these operations are prohibited under such + conditions. The aforementioned behaviors have the potential to modify + region contents by discarding pages, effectively performing a memset(0) + operation on the anonymous memory. + + Kernel will return -EPERM for blocked syscalls. + + When blocked syscall return -EPERM due to sealing, the memory regions may + or may not be changed, depends on the syscall being blocked: + + - munmap: munmap is atomic. If one of VMAs in the given range is + sealed, none of VMAs are updated. + - mprotect, pkey_mprotect, madvise: partial update might happen, e.g. + when mprotect over multiple VMAs, mprotect might update the beginning + VMAs before reaching the sealed VMA and return -EPERM. + - mmap and mremap: undefined behavior. + +Use cases +========= - glibc: The dynamic linker, during loading ELF executables, can apply sealing to - non-writable memory segments. - -- Chrome browser: protect some security sensitive data-structures. + mapping segments. -Notes on which memory to seal: -============================== +- Chrome browser: protect some security sensitive data structures. -It might be important to note that sealing changes the lifetime of a mapping, -i.e. the sealed mapping won’t be unmapped till the process terminates or the -exec system call is invoked. Applications can apply sealing to any virtual -memory region from userspace, but it is crucial to thoroughly analyze the -mapping's lifetime prior to apply the sealing. +When not to use mseal +===================== +Applications can apply sealing to any virtual memory region from userspace, +but it is *crucial to thoroughly analyze the mapping's lifetime* prior to +apply the sealing. This is because the sealed mapping *won’t be unmapped* +until the process terminates or the exec system call is invoked. For example: + - aio/shm + aio/shm can call mmap and munmap on behalf of userspace, e.g. + ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to + the lifetime of the process. If those memories are sealed from userspace, + then munmap will fail, causing leaks in VMA address space during the + lifetime of the process. + + - ptr allocated by malloc (heap) + Don't use mseal on the memory ptr return from malloc(). + malloc() is implemented by allocator, e.g. by glibc. Heap manager might + allocate a ptr from brk or mapping created by mmap. + If an app calls mseal on a ptr returned from malloc(), this can affect + the heap manager's ability to manage the mappings; the outcome is + non-deterministic. + + Example:: + + ptr = malloc(size); + /* don't call mseal on ptr return from malloc. */ + mseal(ptr, size); + /* free will success, allocator can't shrink heap lower than ptr */ + free(ptr); + +mseal doesn't block +=================== +In a nutshell, mseal blocks certain mm syscall from modifying some of VMA's +attributes, such as protection bits (RWX). Sealed mappings doesn't mean the +memory is immutable. -- aio/shm - - aio/shm can call mmap()/munmap() on behalf of userspace, e.g. ksys_shmdt() in - shm.c. The lifetime of those mapping are not tied to the lifetime of the - process. If those memories are sealed from userspace, then munmap() will fail, - causing leaks in VMA address space during the lifetime of the process. - -- Brk (heap) - - Currently, userspace applications can seal parts of the heap by calling - malloc() and mseal(). - let's assume following calls from user space: - - - ptr = malloc(size); - - mprotect(ptr, size, RO); - - mseal(ptr, size); - - free(ptr); - - Technically, before mseal() is added, the user can change the protection of - the heap by calling mprotect(RO). As long as the user changes the protection - back to RW before free(), the memory range can be reused. - - Adding mseal() into the picture, however, the heap is then sealed partially, - the user can still free it, but the memory remains to be RO. If the address - is re-used by the heap manager for another malloc, the process might crash - soon after. Therefore, it is important not to apply sealing to any memory - that might get recycled. - - Furthermore, even if the application never calls the free() for the ptr, - the heap manager may invoke the brk system call to shrink the size of the - heap. In the kernel, the brk-shrink will call munmap(). Consequently, - depending on the location of the ptr, the outcome of brk-shrink is - nondeterministic. - - -Additional notes: -================= As Jann Horn pointed out in [3], there are still a few ways to write -to RO memory, which is, in a way, by design. Those cases are not covered -by mseal(). If applications want to block such cases, sandbox tools (such as -seccomp, LSM, etc) might be considered. +to RO memory, which is, in a way, by design. And those could be blocked +by different security measures. Those cases are: -- Write to read-only memory through /proc/self/mem interface. -- Write to read-only memory through ptrace (such as PTRACE_POKETEXT). -- userfaultfd. + - Write to read-only memory through /proc/self/mem interface (FOLL_FORCE). + - Write to read-only memory through ptrace (such as PTRACE_POKETEXT). + - userfaultfd. The idea that inspired this patch comes from Stephen Röttger’s work in V8 CFI [4]. Chrome browser in ChromeOS will be the first user of this API. -Reference: -========== -[1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 - -[2] https://man.openbsd.org/mimmutable.2 - -[3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com - -[4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc +Reference +========= +- [1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 +- [2] https://man.openbsd.org/mimmutable.2 +- [3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com +- [4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc -- GitLab From 795ea909fdd7ab089823f5b40cec0360c2265b44 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Wed, 1 Nov 2023 15:27:00 +0800 Subject: [PATCH 014/456] BACKPORT: ASoC: codecs: ES8326: Add chip version flag The new chip version requires the addition of a new clock table. We determine which clock table to choose based on the version. Newer versions of the chip have fewer processes to go through in the headset detection, so the version flag is used to skip them. Signed-off-by: Zhu Ning Link: https://lore.kernel.org/r/20231101072702.91316-2-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit ee09084fbf9fdda6bf0179bcdca52196d0cde8a1) Resolved conflict: Undo unexpected marked executable BUG=b:309733238, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I2eb59792295bbf9d840fb1242263abadc355e122 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5221191 Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061880 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 176 +++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 68 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 32a9b26ee2c89..96dc4ef8862d1 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -198,77 +198,108 @@ struct _coeff_div { /* codec hifi mclk clock divider coefficients */ /* {ratio, LRCK, MCLK, REG04, REG05, REG06, REG07, REG08, REG09, REG10, REG11} */ -static const struct _coeff_div coeff_div[] = { - {32, 8000, 256000, 0x60, 0x00, 0x0F, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {32, 16000, 512000, 0x20, 0x00, 0x0D, 0x75, 0x0A, 0x1B, 0x1F, 0x3F}, - {32, 44100, 1411200, 0x00, 0x00, 0x13, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {32, 48000, 1536000, 0x00, 0x00, 0x13, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {36, 8000, 288000, 0x20, 0x00, 0x0D, 0x75, 0x0A, 0x1B, 0x23, 0x47}, - {36, 16000, 576000, 0x20, 0x00, 0x0D, 0x75, 0x0A, 0x1B, 0x23, 0x47}, - {48, 8000, 384000, 0x60, 0x02, 0x1F, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {48, 16000, 768000, 0x20, 0x02, 0x0F, 0x75, 0x0A, 0x1B, 0x1F, 0x3F}, - {48, 48000, 2304000, 0x00, 0x02, 0x0D, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {64, 8000, 512000, 0x60, 0x00, 0x0D, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {64, 16000, 1024000, 0x20, 0x00, 0x05, 0x75, 0x0A, 0x1B, 0x1F, 0x3F}, - - {64, 44100, 2822400, 0x00, 0x00, 0x11, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {64, 48000, 3072000, 0x00, 0x00, 0x11, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {72, 8000, 576000, 0x20, 0x00, 0x13, 0x35, 0x0A, 0x1B, 0x23, 0x47}, - {72, 16000, 1152000, 0x20, 0x00, 0x05, 0x75, 0x0A, 0x1B, 0x23, 0x47}, - {96, 8000, 768000, 0x60, 0x02, 0x1D, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {96, 16000, 1536000, 0x20, 0x02, 0x0D, 0x75, 0x0A, 0x1B, 0x1F, 0x3F}, - {100, 48000, 4800000, 0x04, 0x04, 0x3F, 0x6D, 0x38, 0x08, 0x4f, 0x1f}, - {125, 48000, 6000000, 0x04, 0x04, 0x1F, 0x2D, 0x0A, 0x0A, 0x27, 0x27}, - {128, 8000, 1024000, 0x60, 0x00, 0x13, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {128, 16000, 2048000, 0x20, 0x00, 0x11, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - - {128, 44100, 5644800, 0x00, 0x00, 0x01, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {128, 48000, 6144000, 0x00, 0x00, 0x01, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {144, 8000, 1152000, 0x20, 0x00, 0x03, 0x35, 0x0A, 0x1B, 0x23, 0x47}, - {144, 16000, 2304000, 0x20, 0x00, 0x11, 0x35, 0x0A, 0x1B, 0x23, 0x47}, - {192, 8000, 1536000, 0x60, 0x02, 0x0D, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {192, 16000, 3072000, 0x20, 0x02, 0x05, 0x75, 0x0A, 0x1B, 0x1F, 0x3F}, - {200, 48000, 9600000, 0x04, 0x04, 0x0F, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {250, 48000, 12000000, 0x04, 0x04, 0x0F, 0x2D, 0x0A, 0x0A, 0x27, 0x27}, - {256, 8000, 2048000, 0x60, 0x00, 0x11, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {256, 16000, 4096000, 0x20, 0x00, 0x01, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - - {256, 44100, 11289600, 0x00, 0x00, 0x10, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {256, 48000, 12288000, 0x00, 0x00, 0x30, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {288, 8000, 2304000, 0x20, 0x00, 0x01, 0x35, 0x0A, 0x1B, 0x23, 0x47}, - {384, 8000, 3072000, 0x60, 0x02, 0x05, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, - {384, 16000, 6144000, 0x20, 0x02, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - {384, 48000, 18432000, 0x00, 0x02, 0x01, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {400, 48000, 19200000, 0x09, 0x04, 0x0f, 0x6d, 0x3a, 0x0A, 0x4F, 0x1F}, - {500, 48000, 24000000, 0x18, 0x04, 0x1F, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {512, 8000, 4096000, 0x60, 0x00, 0x01, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {512, 16000, 8192000, 0x20, 0x00, 0x10, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - - {512, 44100, 22579200, 0x00, 0x00, 0x00, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {512, 48000, 24576000, 0x00, 0x00, 0x00, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {768, 8000, 6144000, 0x60, 0x02, 0x11, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {768, 16000, 12288000, 0x20, 0x02, 0x01, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - {800, 48000, 38400000, 0x00, 0x18, 0x13, 0x2D, 0x0A, 0x0A, 0x1F, 0x1F}, - {1024, 8000, 8192000, 0x60, 0x00, 0x10, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, +static const struct _coeff_div coeff_div_v0[] = { + {64, 8000, 512000, 0x60, 0x01, 0x0F, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, + {64, 16000, 1024000, 0x20, 0x00, 0x33, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, + {64, 44100, 2822400, 0xE0, 0x00, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {64, 48000, 3072000, 0xE0, 0x00, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {128, 8000, 1024000, 0x60, 0x00, 0x33, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, + {128, 16000, 2048000, 0x20, 0x00, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, + {128, 44100, 5644800, 0xE0, 0x01, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {128, 48000, 6144000, 0xE0, 0x01, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + + {192, 32000, 6144000, 0xE0, 0x02, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {256, 8000, 2048000, 0x60, 0x00, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, + {256, 16000, 4096000, 0x20, 0x01, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, + {256, 44100, 11289600, 0xE0, 0x00, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {256, 48000, 12288000, 0xE0, 0x00, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {384, 32000, 12288000, 0xE0, 0x05, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {400, 48000, 19200000, 0xE9, 0x04, 0x0F, 0x6d, 0x4A, 0x0A, 0x1F, 0x1F}, + + {500, 48000, 24000000, 0xF8, 0x04, 0x3F, 0x6D, 0x4A, 0x0A, 0x1F, 0x1F}, + {512, 8000, 4096000, 0x60, 0x01, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, + {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, + {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {768, 32000, 24576000, 0xE0, 0x02, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, + {1024, 8000, 8192000, 0x60, 0x00, 0x30, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, {1024, 16000, 16384000, 0x20, 0x00, 0x00, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - {1152, 16000, 18432000, 0x20, 0x08, 0x11, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - {1536, 8000, 12288000, 0x60, 0x02, 0x01, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - - {1536, 16000, 24576000, 0x20, 0x02, 0x10, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, - {1625, 8000, 13000000, 0x0C, 0x18, 0x1F, 0x2D, 0x0A, 0x0A, 0x27, 0x27}, - {1625, 16000, 26000000, 0x0C, 0x18, 0x1F, 0x2D, 0x0A, 0x0A, 0x27, 0x27}, - {2048, 8000, 16384000, 0x60, 0x00, 0x00, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {2304, 8000, 18432000, 0x40, 0x02, 0x10, 0x35, 0x0A, 0x1B, 0x1F, 0x5F}, - {3072, 8000, 24576000, 0x60, 0x02, 0x10, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, - {3250, 8000, 26000000, 0x0C, 0x18, 0x0F, 0x2D, 0x0A, 0x0A, 0x27, 0x27}, +}; +static const struct _coeff_div coeff_div_v3[] = { + {32, 8000, 256000, 0x60, 0x00, 0x0F, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {32, 16000, 512000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, + {32, 44100, 1411200, 0x00, 0x00, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, + {32, 48000, 1536000, 0x00, 0x00, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, + {36, 8000, 288000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x23, 0x47}, + {36, 16000, 576000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x23, 0x47}, + {48, 8000, 384000, 0x60, 0x02, 0x1F, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {48, 16000, 768000, 0x20, 0x02, 0x0F, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, + {48, 48000, 2304000, 0x00, 0x02, 0x0D, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, + + {64, 8000, 512000, 0x60, 0x00, 0x35, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {64, 16000, 1024000, 0x20, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, + {64, 44100, 2822400, 0xE0, 0x00, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {64, 48000, 3072000, 0xE0, 0x00, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {72, 8000, 576000, 0x20, 0x00, 0x13, 0x35, 0x8A, 0x1B, 0x23, 0x47}, + {72, 16000, 1152000, 0x20, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x23, 0x47}, + {96, 8000, 768000, 0x60, 0x02, 0x1D, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {96, 16000, 1536000, 0x20, 0x02, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, + {100, 48000, 4800000, 0x04, 0x04, 0x3F, 0x6D, 0xB8, 0x08, 0x4f, 0x1f}, + {125, 48000, 6000000, 0x04, 0x04, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, + + {128, 8000, 1024000, 0x60, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {128, 16000, 2048000, 0x20, 0x00, 0x31, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {128, 44100, 5644800, 0xE0, 0x00, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {128, 48000, 6144000, 0xE0, 0x00, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {144, 8000, 1152000, 0x20, 0x00, 0x03, 0x35, 0x8A, 0x1B, 0x23, 0x47}, + {144, 16000, 2304000, 0x20, 0x00, 0x11, 0x35, 0x8A, 0x1B, 0x23, 0x47}, + {192, 8000, 1536000, 0x60, 0x02, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {192, 32000, 6144000, 0xE0, 0x02, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {192, 16000, 3072000, 0x20, 0x02, 0x05, 0x75, 0xCA, 0x1B, 0x1F, 0x3F}, + + {200, 48000, 9600000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {250, 48000, 12000000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x27, 0x27}, + {256, 8000, 2048000, 0x60, 0x00, 0x31, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {256, 16000, 4096000, 0x20, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {256, 44100, 11289600, 0xE0, 0x00, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {256, 48000, 12288000, 0xE0, 0x00, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {288, 8000, 2304000, 0x20, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x23, 0x47}, + {384, 8000, 3072000, 0x60, 0x02, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, + {384, 16000, 6144000, 0x20, 0x02, 0x03, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {384, 32000, 12288000, 0xE0, 0x02, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {384, 48000, 18432000, 0x00, 0x02, 0x01, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, + + {400, 48000, 19200000, 0xE4, 0x04, 0x35, 0x6d, 0xCA, 0x0A, 0x1F, 0x1F}, + {500, 48000, 24000000, 0xF8, 0x04, 0x3F, 0x6D, 0xCA, 0x0A, 0x1F, 0x1F}, + {512, 8000, 4096000, 0x60, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {768, 8000, 6144000, 0x60, 0x02, 0x11, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {768, 16000, 12288000, 0x20, 0x02, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {768, 32000, 24576000, 0xE0, 0x02, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {800, 48000, 38400000, 0x00, 0x18, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, + + {1024, 8000, 8192000, 0x60, 0x00, 0x30, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {1024, 16000, 16384000, 0x20, 0x00, 0x00, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {1152, 16000, 18432000, 0x20, 0x08, 0x11, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {1536, 8000, 12288000, 0x60, 0x02, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {1536, 16000, 24576000, 0x20, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, + {1625, 8000, 13000000, 0x0C, 0x18, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, + {1625, 16000, 26000000, 0x0C, 0x18, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, + {2048, 8000, 16384000, 0x60, 0x00, 0x00, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {2304, 8000, 18432000, 0x40, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x5F}, + {3072, 8000, 24576000, 0x60, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, + {3250, 8000, 26000000, 0x0C, 0x18, 0x0F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, }; -static inline int get_coeff(int mclk, int rate) +static inline int get_coeff(int mclk, int rate, int array, + const struct _coeff_div *coeff_div) { int i; - for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + for (i = 0; i < array; i++) { if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) return i; } @@ -276,6 +307,7 @@ static inline int get_coeff(int mclk, int rate) return -EINVAL; } + static int es8326_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -333,11 +365,19 @@ static int es8326_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; + const struct _coeff_div *coeff_div; struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); u8 srate = 0; - int coeff; + int coeff, array; - coeff = get_coeff(es8326->sysclk, params_rate(params)); + if (es8326->version == 0) { + coeff_div = coeff_div_v0; + array = ARRAY_SIZE(coeff_div_v0); + } else { + coeff_div = coeff_div_v3; + array = ARRAY_SIZE(coeff_div_v3); + } + coeff = get_coeff(es8326->sysclk, params_rate(params), array, coeff_div); /* bit size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -594,7 +634,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) iface = snd_soc_component_read(comp, ES8326_HPDET_STA); dev_dbg(comp->dev, "gpio flag %#04x", iface); - if (es8326->jack_remove_retry == 1) { + if ((es8326->jack_remove_retry == 1) && (es8326->version != ES8326_VERSION_B)) { if (iface & ES8326_HPINSERT_FLAG) es8326->jack_remove_retry = 2; else @@ -630,7 +670,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) /* * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event */ - if (es8326->jack_remove_retry == 0) { + if ((es8326->jack_remove_retry == 0) && (es8326->version != ES8326_VERSION_B)) { es8326->jack_remove_retry = 1; dev_dbg(comp->dev, "remove event check, invert HPJACK_POL, cnt = %d\n", es8326->jack_remove_retry); -- GitLab From abc1e519de59fe6aab1348d65fdf7f4caf5b2886 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Wed, 1 Nov 2023 15:27:01 +0800 Subject: [PATCH 015/456] UPSTREAM: ASoC: codecs: ES8326: Changing initialisation and broadcasting New chip versions require new initialisation and playback processes. Changing the initialisation and playback process for better results. The old chip versions are going to work well with the new sequences. We've tested this with version_v0 and version_v3 chips under the new sequence and they both pass. Signed-off-by: Zhu Ning Link: https://lore.kernel.org/r/20231101072702.91316-3-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit fc702b2c04d778d7e3a4091ebe54a86c5d0a0d96) BUG=b:309733238, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I827ed6ceb62cf93aee5d23d5e899bf01258c05bd Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5221165 Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-by: cong yang Reviewed-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061881 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 51 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 96dc4ef8862d1..a2d15f288e4df 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -132,6 +132,11 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { SND_SOC_DAPM_PGA("LHPMIX", ES8326_DAC2HPMIX, 7, 0, NULL, 0), SND_SOC_DAPM_PGA("RHPMIX", ES8326_DAC2HPMIX, 3, 0, NULL, 0), + SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOR Supply", ES8326_HP_CAL, + 4, 7, 0, 0), + SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOL Supply", ES8326_HP_CAL, + 0, 7, 0, 0), + SND_SOC_DAPM_OUTPUT("HPOL"), SND_SOC_DAPM_OUTPUT("HPOR"), }; @@ -156,6 +161,9 @@ static const struct snd_soc_dapm_route es8326_dapm_routes[] = { {"LHPMIX", NULL, "Left DAC"}, {"RHPMIX", NULL, "Right DAC"}, + {"HPOR", NULL, "HPOR Supply"}, + {"HPOL", NULL, "HPOL Supply"}, + {"HPOL", NULL, "LHPMIX"}, {"HPOR", NULL, "RHPMIX"}, }; @@ -307,7 +315,6 @@ static inline int get_coeff(int mclk, int rate, int array, return -EINVAL; } - static int es8326_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -449,8 +456,8 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r); es8326->calibrated = true; } - regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa0); - regmap_write(es8326->regmap, ES8326_HP_VOL, 0x80); + regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); + regmap_write(es8326->regmap, ES8326_HP_VOL, 0x91); regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON); regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, ~(ES8326_MUTE)); @@ -470,8 +477,6 @@ static int es8326_set_bias_level(struct snd_soc_component *codec, if (ret) return ret; - regmap_write(es8326->regmap, ES8326_RESET, 0x9f); - msleep(20); regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, @@ -480,19 +485,21 @@ static int es8326_set_bias_level(struct snd_soc_component *codec, regmap_write(es8326->regmap, ES8326_PGA_PDN, 0x40); regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00); regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x20); - regmap_write(es8326->regmap, ES8326_RESET, ES8326_CSM_ON); + + regmap_update_bits(es8326->regmap, ES8326_RESET, + ES8326_CSM_ON, ES8326_CSM_ON); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - break; - case SND_SOC_BIAS_OFF: - clk_disable_unprepare(es8326->mclk); regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b); regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x00); regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x00); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT); break; + case SND_SOC_BIAS_OFF: + clk_disable_unprepare(es8326->mclk); + break; } return 0; @@ -764,13 +771,15 @@ static int es8326_calibrate(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_CLK_DIV1, 0x01); regmap_write(es8326->regmap, ES8326_CLK_DLL, 0x30); regmap_write(es8326->regmap, ES8326_CLK_MUX, 0xed); + regmap_write(es8326->regmap, ES8326_CLK_DAC_SEL, 0x08); regmap_write(es8326->regmap, ES8326_CLK_TRI, 0xc1); regmap_write(es8326->regmap, ES8326_DAC_MUTE, 0x03); regmap_write(es8326->regmap, ES8326_ANA_VSEL, 0x7f); - regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x33); + regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x03); regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x88); - regmap_write(es8326->regmap, ES8326_HP_VOL, 0x80); + usleep_range(15000, 20000); regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, 0x8c); + usleep_range(15000, 20000); regmap_write(es8326->regmap, ES8326_RESET, 0xc0); usleep_range(15000, 20000); @@ -808,27 +817,27 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_RESET, 0x1f); regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); usleep_range(10000, 15000); - regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0x88); + regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0xe9); + regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0x4b); /* set headphone default type and detect pin */ - regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x81); + regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x83); regmap_write(es8326->regmap, ES8326_CLK_RESAMPLE, 0x05); + regmap_write(es8326->regmap, ES8326_HP_MISC, 0x30); /* set internal oscillator as clock source of headpone cp */ - regmap_write(es8326->regmap, ES8326_CLK_DIV_CPC, 0x84); + regmap_write(es8326->regmap, ES8326_CLK_DIV_CPC, 0x89); regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_ON); /* clock manager reset release */ regmap_write(es8326->regmap, ES8326_RESET, 0x17); /* set headphone detection as half scan mode */ - regmap_write(es8326->regmap, ES8326_HP_MISC, 0x08); + regmap_write(es8326->regmap, ES8326_HP_MISC, 0x30); regmap_write(es8326->regmap, ES8326_PULLUP_CTL, 0x00); /* enable headphone driver */ regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa7); usleep_range(2000, 5000); - regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xab); - usleep_range(2000, 5000); - regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xbb); - usleep_range(2000, 5000); + regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xa3); + regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xb3); regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); regmap_write(es8326->regmap, ES8326_CLK_INV, 0x00); @@ -842,9 +851,6 @@ static int es8326_resume(struct snd_soc_component *component) /* set ADC and DAC in low power mode */ regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); - /* force micbias on */ - regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0x4f); - regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x08); regmap_write(es8326->regmap, ES8326_ANA_VSEL, 0x7F); /* select vdda as micbias source */ regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x23); @@ -872,6 +878,7 @@ static int es8326_resume(struct snd_soc_component *component) ((es8326->version == ES8326_VERSION_B) ? (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); + regmap_write(es8326->regmap, ES8326_HP_VOL, 0x11); es8326->jack_remove_retry = 0; es8326->hp = 0; -- GitLab From c9b0de26650948c377213a46c1b0706b3e7cab03 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Wed, 1 Nov 2023 15:27:02 +0800 Subject: [PATCH 016/456] UPSTREAM: ASoC: codecs: ES8326: Changing the headset detection time The old headset detection time is not enough for the new chip version. An error occurs with the old detection time.According to tests, 400ms is the best detection time that does not trigger an error. The delay time after the trigger is reduced by 300ms to keep the whole detection time unchanged. Signed-off-by: Zhu Ning Link: https://lore.kernel.org/r/20231101072702.91316-4-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 8a81491adbd9b25a648704c9825adaefb0c31868) BUG=b:309733238, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Icafcacd0ee7356357a1f1e020503718b56ee9c50 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5221192 Reviewed-by: Sean Paul Reviewed-by: cong yang Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061882 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index a2d15f288e4df..393aac44c1fe4 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -693,14 +693,14 @@ static void es8326_jack_detect_handler(struct work_struct *work) if (es8326->hp == 0) { dev_dbg(comp->dev, "First insert, start OMTP/CTIA type check\n"); /* - * set auto-check mode, then restart jack_detect_work after 100ms. + * set auto-check mode, then restart jack_detect_work after 400ms. * Don't report jack status. */ regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); queue_delayed_work(system_wq, &es8326->jack_detect_work, - msecs_to_jiffies(100)); + msecs_to_jiffies(400)); es8326->hp = 1; goto exit; } @@ -750,7 +750,7 @@ static irqreturn_t es8326_irq(int irq, void *dev_id) msecs_to_jiffies(10)); else queue_delayed_work(system_wq, &es8326->jack_detect_work, - msecs_to_jiffies(600)); + msecs_to_jiffies(300)); out: return IRQ_HANDLED; -- GitLab From deb13d1eb83ebbf08b13080a992ae8457132b496 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Sat, 20 Jan 2024 18:12:36 +0800 Subject: [PATCH 017/456] UPSTREAM: ASoC: codecs: ES8326: improving crosstalk performance We change the crosstalk parameter in es8326_resume function to improve crosstalk performance. Adding crosstalk kcontrol to enhance the flexibility of crosstalk debugging in machine. Adding ES8326_DAC_CROSSTALK macro to declare the crosstalk register. Signed-off-by: Zhu Ning Link: https://msgid.link/r/20240120101240.12496-2-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 523d242d4309797e6b27c708fbd1463f301c199a) BUG=b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Icb3e19299d32346aa32669ac464f2d002a32cdec Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061883 Reviewed-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 82 +++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/es8326.h | 1 + 2 files changed, 83 insertions(+) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 393aac44c1fe4..27eee67f5c566 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -45,6 +45,82 @@ struct es8326_priv { int jack_remove_retry; }; +static int es8326_crosstalk1_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int crosstalk_h, crosstalk_l; + unsigned int crosstalk; + + regmap_read(es8326->regmap, ES8326_DAC_RAMPRATE, &crosstalk_h); + regmap_read(es8326->regmap, ES8326_DAC_CROSSTALK, &crosstalk_l); + crosstalk_h &= 0x20; + crosstalk_l &= 0xf0; + crosstalk = crosstalk_h >> 1 | crosstalk_l >> 4; + ucontrol->value.integer.value[0] = crosstalk; + + return 0; +} + +static int es8326_crosstalk1_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int crosstalk_h, crosstalk_l; + unsigned int crosstalk; + + crosstalk = ucontrol->value.integer.value[0]; + regmap_read(es8326->regmap, ES8326_DAC_CROSSTALK, &crosstalk_l); + crosstalk_h = (crosstalk & 0x10) << 1; + crosstalk_l &= 0x0f; + crosstalk_l |= (crosstalk & 0x0f) << 4; + regmap_update_bits(es8326->regmap, ES8326_DAC_RAMPRATE, + 0x20, crosstalk_h); + regmap_write(es8326->regmap, ES8326_DAC_CROSSTALK, crosstalk_l); + + return 0; +} + +static int es8326_crosstalk2_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int crosstalk_h, crosstalk_l; + unsigned int crosstalk; + + regmap_read(es8326->regmap, ES8326_DAC_RAMPRATE, &crosstalk_h); + regmap_read(es8326->regmap, ES8326_DAC_CROSSTALK, &crosstalk_l); + crosstalk_h &= 0x10; + crosstalk_l &= 0x0f; + crosstalk = crosstalk_h | crosstalk_l; + ucontrol->value.integer.value[0] = crosstalk; + + return 0; +} + +static int es8326_crosstalk2_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int crosstalk_h, crosstalk_l; + unsigned int crosstalk; + + crosstalk = ucontrol->value.integer.value[0]; + regmap_read(es8326->regmap, ES8326_DAC_CROSSTALK, &crosstalk_l); + crosstalk_h = crosstalk & 0x10; + crosstalk_l &= 0xf0; + crosstalk_l |= crosstalk & 0x0f; + regmap_update_bits(es8326->regmap, ES8326_DAC_RAMPRATE, + 0x10, crosstalk_h); + regmap_write(es8326->regmap, ES8326_DAC_CROSSTALK, crosstalk_l); + + return 0; +} + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9550, 50, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9550, 50, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_analog_pga_tlv, 0, 300, 0); @@ -102,6 +178,10 @@ static const struct snd_kcontrol_new es8326_snd_controls[] = { SOC_SINGLE_TLV("ALC Capture Target Level", ES8326_ALC_LEVEL, 0, 0x0f, 0, drc_target_tlv), + SOC_SINGLE_EXT("CROSSTALK1", SND_SOC_NOPM, 0, 31, 0, + es8326_crosstalk1_get, es8326_crosstalk1_set), + SOC_SINGLE_EXT("CROSSTALK2", SND_SOC_NOPM, 0, 31, 0, + es8326_crosstalk2_get, es8326_crosstalk2_set), }; static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { @@ -846,6 +926,8 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_CLK_CAL_TIME, 0x00); /* calibrate for B version */ es8326_calibrate(component); + regmap_write(es8326->regmap, ES8326_DAC_CROSSTALK, 0xaa); + regmap_write(es8326->regmap, ES8326_DAC_RAMPRATE, 0x00); /* turn off headphone out */ regmap_write(es8326->regmap, ES8326_HP_CAL, 0x00); /* set ADC and DAC in low power mode */ diff --git a/sound/soc/codecs/es8326.h b/sound/soc/codecs/es8326.h index 90a08351d6acd..dfef808673f4a 100644 --- a/sound/soc/codecs/es8326.h +++ b/sound/soc/codecs/es8326.h @@ -72,6 +72,7 @@ #define ES8326_DAC_VOL 0x50 #define ES8326_DRC_RECOVERY 0x53 #define ES8326_DRC_WINSIZE 0x54 +#define ES8326_DAC_CROSSTALK 0x55 #define ES8326_HPJACK_TIMER 0x56 #define ES8326_HPDET_TYPE 0x57 #define ES8326_INT_SOURCE 0x58 -- GitLab From 8954104e432e5fea28cf7504c9ff65a74504327c Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Sat, 20 Jan 2024 18:12:37 +0800 Subject: [PATCH 018/456] UPSTREAM: ASoC: codecs: ES8326: Improving the THD+N performance We update the values of some registers in the initialization sequence in es8326_resume function to improve THD+N performance. THD+N performance decreases if the output level on headphone is close to full scale. So we change the register setting in es8326_jack_detect_handler function to improve THD+N performance if headphone pulgged. Also, the register setting should be restored when the headset is unplugged Signed-off-by: Zhu Ning Link: https://msgid.link/r/20240120101240.12496-3-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 14a0a1ec3335ac3945a96437c35465e4a9616b88) BUG=b:309733238,b:321580616, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ifbc20a373ee6091da6c98402c66ca2e01c7d98d6 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5237975 Tested-by: Fei Shao Reviewed-by: cong yang Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061884 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 21 +++++++++++++-------- sound/soc/codecs/es8326.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 27eee67f5c566..b7bb4ac73a8a3 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -754,6 +754,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) es8326->hp = 0; } regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); + regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x0a); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x0f, 0x03); /* * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event */ @@ -779,6 +781,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); + regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x1f); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x0f, 0x08); queue_delayed_work(system_wq, &es8326->jack_detect_work, msecs_to_jiffies(400)); es8326->hp = 1; @@ -848,14 +852,14 @@ static int es8326_calibrate(struct snd_soc_component *component) if ((es8326->version == ES8326_VERSION_B) && (es8326->calibrated == false)) { dev_dbg(component->dev, "ES8326_VERSION_B, calibrating\n"); regmap_write(es8326->regmap, ES8326_CLK_INV, 0xc0); - regmap_write(es8326->regmap, ES8326_CLK_DIV1, 0x01); + regmap_write(es8326->regmap, ES8326_CLK_DIV1, 0x03); regmap_write(es8326->regmap, ES8326_CLK_DLL, 0x30); regmap_write(es8326->regmap, ES8326_CLK_MUX, 0xed); regmap_write(es8326->regmap, ES8326_CLK_DAC_SEL, 0x08); regmap_write(es8326->regmap, ES8326_CLK_TRI, 0xc1); regmap_write(es8326->regmap, ES8326_DAC_MUTE, 0x03); regmap_write(es8326->regmap, ES8326_ANA_VSEL, 0x7f); - regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x03); + regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x23); regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x88); usleep_range(15000, 20000); regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, 0x8c); @@ -896,13 +900,13 @@ static int es8326_resume(struct snd_soc_component *component) /* reset internal clock state */ regmap_write(es8326->regmap, ES8326_RESET, 0x1f); regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); + regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); usleep_range(10000, 15000); regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0xe9); - regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0x4b); + regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0xcb); /* set headphone default type and detect pin */ regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x83); regmap_write(es8326->regmap, ES8326_CLK_RESAMPLE, 0x05); - regmap_write(es8326->regmap, ES8326_HP_MISC, 0x30); /* set internal oscillator as clock source of headpone cp */ regmap_write(es8326->regmap, ES8326_CLK_DIV_CPC, 0x89); @@ -910,14 +914,15 @@ static int es8326_resume(struct snd_soc_component *component) /* clock manager reset release */ regmap_write(es8326->regmap, ES8326_RESET, 0x17); /* set headphone detection as half scan mode */ - regmap_write(es8326->regmap, ES8326_HP_MISC, 0x30); + regmap_write(es8326->regmap, ES8326_HP_MISC, 0x3d); regmap_write(es8326->regmap, ES8326_PULLUP_CTL, 0x00); /* enable headphone driver */ + regmap_write(es8326->regmap, ES8326_HP_VOL, 0xc4); regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa7); usleep_range(2000, 5000); - regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xa3); - regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0xb3); + regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0x23); + regmap_write(es8326->regmap, ES8326_HP_DRIVER_REF, 0x33); regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); regmap_write(es8326->regmap, ES8326_CLK_INV, 0x00); @@ -948,7 +953,7 @@ static int es8326_resume(struct snd_soc_component *component) (ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT)); regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT); - regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b); + regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00); regmap_write(es8326->regmap, ES8326_RESET, ES8326_CSM_ON); regmap_update_bits(es8326->regmap, ES8326_PGAGAIN, ES8326_MIC_SEL_MASK, ES8326_MIC1_SEL); diff --git a/sound/soc/codecs/es8326.h b/sound/soc/codecs/es8326.h index dfef808673f4a..4234bbb900c45 100644 --- a/sound/soc/codecs/es8326.h +++ b/sound/soc/codecs/es8326.h @@ -101,7 +101,7 @@ #define ES8326_MUTE (3 << 0) /* ES8326_CLK_CTL */ -#define ES8326_CLK_ON (0x7f << 0) +#define ES8326_CLK_ON (0x7e << 0) #define ES8326_CLK_OFF (0 << 0) /* ES8326_CLK_INV */ -- GitLab From fb3ee78b76692ec148da487d03789a599ecb1a0f Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Sat, 20 Jan 2024 18:12:39 +0800 Subject: [PATCH 019/456] UPSTREAM: ASoC: codecs: ES8326: Minimize the pop noise on headphone We modify the register settings to minimize headphone pop noise during ES8326 power-up and music start/stop. Signed-off-by: Zhu Ning Link: https://msgid.link/r/20240120101240.12496-5-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit a3aa9255d6ccb1bff13c7c98e5d3bf10ba67f92e) BUG=b:309733238,b:321580616, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I1ffb09c05ed3e2f87c9786bad72b2cad4c1f78eb Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5243974 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-by: cong yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061885 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index b7bb4ac73a8a3..4390431e7520a 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -523,7 +523,8 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, ES8326_MUTE); - regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xf0); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, + 0x30, 0x00); } else { if (!es8326->calibrated) { regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_FORCE_CAL); @@ -536,8 +537,13 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r); es8326->calibrated = true; } + regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x01); + usleep_range(1000, 5000); + regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00); + usleep_range(1000, 5000); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x20); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x30); regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); - regmap_write(es8326->regmap, ES8326_HP_VOL, 0x91); regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON); regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, ~(ES8326_MUTE)); @@ -557,23 +563,20 @@ static int es8326_set_bias_level(struct snd_soc_component *codec, if (ret) return ret; - regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00); + regmap_update_bits(es8326->regmap, ES8326_RESET, 0x02, 0x02); + usleep_range(5000, 10000); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, (ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT)); - regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); regmap_write(es8326->regmap, ES8326_PGA_PDN, 0x40); regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00); regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x20); - - regmap_update_bits(es8326->regmap, ES8326_RESET, - ES8326_CSM_ON, ES8326_CSM_ON); + regmap_update_bits(es8326->regmap, ES8326_RESET, 0x02, 0x00); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b); - regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x00); regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x00); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT); break; @@ -779,6 +782,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) * Don't report jack status. */ regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); + es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x1f); @@ -822,13 +826,10 @@ exit: static irqreturn_t es8326_irq(int irq, void *dev_id) { struct es8326_priv *es8326 = dev_id; - struct snd_soc_component *comp = es8326->component; if (!es8326->jack) goto out; - es8326_enable_micbias(comp); - if (es8326->jack->status & SND_JACK_HEADSET) queue_delayed_work(system_wq, &es8326->jack_detect_work, msecs_to_jiffies(10)); @@ -945,6 +946,14 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_DAC_DSM, 0x08); regmap_write(es8326->regmap, ES8326_DAC_VPPSCALE, 0x15); + regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x80 | + ((es8326->version == ES8326_VERSION_B) ? + (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : + (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); + usleep_range(5000, 10000); + es8326_enable_micbias(es8326->component); + usleep_range(50000, 70000); + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_write(es8326->regmap, ES8326_INT_SOURCE, (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); regmap_write(es8326->regmap, ES8326_INTOUT_IO, @@ -961,11 +970,6 @@ static int es8326_resume(struct snd_soc_component *component) regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, ES8326_MUTE); - regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x80 | - ((es8326->version == ES8326_VERSION_B) ? - (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : - (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); - regmap_write(es8326->regmap, ES8326_HP_VOL, 0x11); es8326->jack_remove_retry = 0; es8326->hp = 0; -- GitLab From e4e54ed9db4621e06880231f1d18bd2439f35038 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Sat, 20 Jan 2024 18:12:40 +0800 Subject: [PATCH 020/456] UPSTREAM: ASoC: codecs: ES8326: fix the capture noise issue We get a noise issue during the startup of recording. We update the register setting and dapm widgets to fix this issue. we change callback type of es8326_mute function to mute_stream. ES8326_ADC_MUTE is moved to es8326_mute function so it can be turned on at last and turned off at first. Signed-off-by: Zhu Ning Link: https://msgid.link/r/20240120101240.12496-6-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 8c99a0a607b5e0cf6b79b283d7bb2c2b84e01da5) BUG=b:309733238,b:321580616, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Idcfd6715c1d797c5481f42098c07c2b737a0c62e Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5243975 Reviewed-by: cong yang Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061886 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 63 ++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 4390431e7520a..29bb9f09a5bd5 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -197,12 +197,6 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0, SND_SOC_NOPM, 0, 0), - /* ADC Digital Mute */ - SND_SOC_DAPM_PGA("ADC L1", ES8326_ADC_MUTE, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("ADC R1", ES8326_ADC_MUTE, 1, 1, NULL, 0), - SND_SOC_DAPM_PGA("ADC L2", ES8326_ADC_MUTE, 2, 1, NULL, 0), - SND_SOC_DAPM_PGA("ADC R2", ES8326_ADC_MUTE, 3, 1, NULL, 0), - /* Analog Power Supply*/ SND_SOC_DAPM_DAC("Right DAC", NULL, ES8326_ANA_PDN, 0, 1), SND_SOC_DAPM_DAC("Left DAC", NULL, ES8326_ANA_PDN, 1, 1), @@ -222,15 +216,10 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { }; static const struct snd_soc_dapm_route es8326_dapm_routes[] = { - {"ADC L1", NULL, "MIC1"}, - {"ADC R1", NULL, "MIC2"}, - {"ADC L2", NULL, "MIC3"}, - {"ADC R2", NULL, "MIC4"}, - - {"ADC L", NULL, "ADC L1"}, - {"ADC R", NULL, "ADC R1"}, - {"ADC L", NULL, "ADC L2"}, - {"ADC R", NULL, "ADC R2"}, + {"ADC L", NULL, "MIC1"}, + {"ADC R", NULL, "MIC2"}, + {"ADC L", NULL, "MIC3"}, + {"ADC R", NULL, "MIC4"}, {"I2S OUT", NULL, "ADC L"}, {"I2S OUT", NULL, "ADC R"}, @@ -520,11 +509,16 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) unsigned int offset_l, offset_r; if (mute) { - regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); - regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, - ES8326_MUTE_MASK, ES8326_MUTE); - regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, - 0x30, 0x00); + if (direction == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); + regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, + ES8326_MUTE_MASK, ES8326_MUTE); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, + 0x30, 0x00); + } else { + regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE, + 0x0F, 0x0F); + } } else { if (!es8326->calibrated) { regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_FORCE_CAL); @@ -537,16 +531,22 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r); es8326->calibrated = true; } - regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x01); - usleep_range(1000, 5000); - regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00); - usleep_range(1000, 5000); - regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x20); - regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x30); - regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); - regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON); - regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, - ES8326_MUTE_MASK, ~(ES8326_MUTE)); + if (direction == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x01); + usleep_range(1000, 5000); + regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00); + usleep_range(1000, 5000); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x20); + regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x30, 0x30); + regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa1); + regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON); + regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, + ES8326_MUTE_MASK, ~(ES8326_MUTE)); + } else { + msleep(300); + regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE, + 0x0F, 0x00); + } } return 0; } @@ -596,7 +596,7 @@ static const struct snd_soc_dai_ops es8326_ops = { .set_fmt = es8326_set_dai_fmt, .set_sysclk = es8326_set_dai_sysclk, .mute_stream = es8326_mute, - .no_capture_mute = 1, + .no_capture_mute = 0, }; static struct snd_soc_dai_driver es8326_dai = { @@ -970,6 +970,7 @@ static int es8326_resume(struct snd_soc_component *component) regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, ES8326_MUTE); + regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); es8326->jack_remove_retry = 0; es8326->hp = 0; -- GitLab From b5316695700416c7ca10f183afa7c3f5d02e2ffa Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Wed, 24 Jan 2024 14:48:06 +0800 Subject: [PATCH 021/456] UPSTREAM: ASoC: codecs: ES8326: Adding new volume kcontrols ES8326 features a headphone volume control register and four DAC volume control registers. We add new volume Kcontrols for these registers to enhance the configurability of the volume settings, providing users with greater flexibility. Signed-off-by: Zhu Ning Link: https://msgid.link/r/20240124064806.30511-2-zhuning0077@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 966323dd9a65dde599f59176280468a0cb04c875) BUG=b:309733238,b:321580616, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I79a49348c4ae5f7cb058e869ae9a3d2b90ecd286 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5237911 Reviewed-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: cong yang Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061887 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 92 ++++++++++++++++++++++++++++++++++++++- sound/soc/codecs/es8326.h | 5 ++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 29bb9f09a5bd5..12f1d9a805b70 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -36,6 +36,8 @@ struct es8326_priv { u8 jack_pol; u8 interrupt_src; u8 interrupt_clk; + u8 hpl_vol; + u8 hpr_vol; bool jd_inverted; unsigned int sysclk; @@ -121,6 +123,72 @@ static int es8326_crosstalk2_set(struct snd_kcontrol *kcontrol, return 0; } +static int es8326_hplvol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = es8326->hpl_vol; + + return 0; +} + +static int es8326_hplvol_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int hp_vol; + + hp_vol = ucontrol->value.integer.value[0]; + if (hp_vol > 5) + return -EINVAL; + if (es8326->hpl_vol != hp_vol) { + es8326->hpl_vol = hp_vol; + if (hp_vol >= 3) + hp_vol++; + regmap_update_bits(es8326->regmap, ES8326_HP_VOL, + 0x70, (hp_vol << 4)); + return 1; + } + + return 0; +} + +static int es8326_hprvol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = es8326->hpr_vol; + + return 0; +} + +static int es8326_hprvol_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int hp_vol; + + hp_vol = ucontrol->value.integer.value[0]; + if (hp_vol > 5) + return -EINVAL; + if (es8326->hpr_vol != hp_vol) { + es8326->hpr_vol = hp_vol; + if (hp_vol >= 3) + hp_vol++; + regmap_update_bits(es8326->regmap, ES8326_HP_VOL, + 0x07, hp_vol); + return 1; + } + + return 0; +} + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9550, 50, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9550, 50, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_analog_pga_tlv, 0, 300, 0); @@ -151,15 +219,24 @@ static const char *const winsize[] = { static const char *const dacpol_txt[] = { "Normal", "R Invert", "L Invert", "L + R Invert" }; +static const char *const hp_spkvol_switch[] = { + "HPVOL: HPL+HPL, SPKVOL: HPL+HPL", + "HPVOL: HPL+HPR, SPKVOL: HPL+HPR", + "HPVOL: HPL+HPL, SPKVOL: SPKL+SPKR", + "HPVOL: HPL+HPR, SPKVOL: SPKL+SPKR", +}; + static const struct soc_enum dacpol = SOC_ENUM_SINGLE(ES8326_DAC_DSM, 4, 4, dacpol_txt); static const struct soc_enum alc_winsize = SOC_ENUM_SINGLE(ES8326_ADC_RAMPRATE, 4, 16, winsize); static const struct soc_enum drc_winsize = SOC_ENUM_SINGLE(ES8326_DRC_WINSIZE, 4, 16, winsize); +static const struct soc_enum hpvol_spkvol_switch = + SOC_ENUM_SINGLE(ES8326_HP_MISC, 6, 4, hp_spkvol_switch); static const struct snd_kcontrol_new es8326_snd_controls[] = { - SOC_SINGLE_TLV("DAC Playback Volume", ES8326_DAC_VOL, 0, 0xbf, 0, dac_vol_tlv), + SOC_SINGLE_TLV("DAC Playback Volume", ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv), SOC_ENUM("Playback Polarity", dacpol), SOC_SINGLE_TLV("DAC Ramp Rate", ES8326_DAC_RAMPRATE, 0, 0x0f, 0, softramp_rate), SOC_SINGLE_TLV("DRC Recovery Level", ES8326_DRC_RECOVERY, 0, 4, 0, drc_recovery_tlv), @@ -182,6 +259,17 @@ static const struct snd_kcontrol_new es8326_snd_controls[] = { es8326_crosstalk1_get, es8326_crosstalk1_set), SOC_SINGLE_EXT("CROSSTALK2", SND_SOC_NOPM, 0, 31, 0, es8326_crosstalk2_get, es8326_crosstalk2_set), + SOC_SINGLE_EXT("HPL Volume", SND_SOC_NOPM, 0, 5, 0, + es8326_hplvol_get, es8326_hplvol_set), + SOC_SINGLE_EXT("HPR Volume", SND_SOC_NOPM, 0, 5, 0, + es8326_hprvol_get, es8326_hprvol_set), + + SOC_SINGLE_TLV("HPL Playback Volume", ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv), + SOC_SINGLE_TLV("HPR Playback Volume", ES8326_DACR_VOL, 0, 0xbf, 0, dac_vol_tlv), + SOC_SINGLE_TLV("SPKL Playback Volume", ES8326_SPKL_VOL, 0, 0xbf, 0, dac_vol_tlv), + SOC_SINGLE_TLV("SPKR Playback Volume", ES8326_SPKR_VOL, 0, 0xbf, 0, dac_vol_tlv), + + SOC_ENUM("HPVol SPKVol Switch", hpvol_spkvol_switch), }; static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { @@ -974,6 +1062,8 @@ static int es8326_resume(struct snd_soc_component *component) es8326->jack_remove_retry = 0; es8326->hp = 0; + es8326->hpl_vol = 0x03; + es8326->hpr_vol = 0x03; return 0; } diff --git a/sound/soc/codecs/es8326.h b/sound/soc/codecs/es8326.h index 4234bbb900c45..ee12caef81053 100644 --- a/sound/soc/codecs/es8326.h +++ b/sound/soc/codecs/es8326.h @@ -69,7 +69,7 @@ #define ES8326_DAC_DSM 0x4D #define ES8326_DAC_RAMPRATE 0x4E #define ES8326_DAC_VPPSCALE 0x4F -#define ES8326_DAC_VOL 0x50 +#define ES8326_DACL_VOL 0x50 #define ES8326_DRC_RECOVERY 0x53 #define ES8326_DRC_WINSIZE 0x54 #define ES8326_DAC_CROSSTALK 0x55 @@ -81,6 +81,9 @@ #define ES8326_SDINOUT23_IO 0x5B #define ES8326_JACK_PULSE 0x5C +#define ES8326_DACR_VOL 0xF4 +#define ES8326_SPKL_VOL 0xF5 +#define ES8326_SPKR_VOL 0xF6 #define ES8326_HP_MISC 0xF7 #define ES8326_CTIA_OMTP_STA 0xF8 #define ES8326_PULLUP_CTL 0xF9 -- GitLab From 10c70fd92052433ec440a58bf091246054fba86d Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Thu, 7 Mar 2024 13:12:21 +0800 Subject: [PATCH 022/456] UPSTREAM: ASoC: codecs: ES8326: Changing members of private structure We don't use mic1_src and mic2_src.so we delete these two members. We changed the default value of interrupt-clk for headphone detection Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240307051222.24010-2-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit bb6983847fb4535bb0386a91dd523088ece36450) BUG=b:309733238, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I49e27eaa48634d1adc6149c7fec902ad0a41bab9 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5379981 Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: cong yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061888 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 12f1d9a805b70..5942bd4c76f79 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -31,8 +31,6 @@ struct es8326_priv { * while enabling or disabling or during an irq. */ struct mutex lock; - u8 mic1_src; - u8 mic2_src; u8 jack_pol; u8 interrupt_src; u8 interrupt_clk; @@ -1094,20 +1092,6 @@ static int es8326_probe(struct snd_soc_component *component) es8326->jd_inverted = device_property_read_bool(component->dev, "everest,jack-detect-inverted"); - ret = device_property_read_u8(component->dev, "everest,mic1-src", &es8326->mic1_src); - if (ret != 0) { - dev_dbg(component->dev, "mic1-src return %d", ret); - es8326->mic1_src = ES8326_ADC_AMIC; - } - dev_dbg(component->dev, "mic1-src %x", es8326->mic1_src); - - ret = device_property_read_u8(component->dev, "everest,mic2-src", &es8326->mic2_src); - if (ret != 0) { - dev_dbg(component->dev, "mic2-src return %d", ret); - es8326->mic2_src = ES8326_ADC_DMIC; - } - dev_dbg(component->dev, "mic2-src %x", es8326->mic2_src); - ret = device_property_read_u8(component->dev, "everest,jack-pol", &es8326->jack_pol); if (ret != 0) { dev_dbg(component->dev, "jack-pol return %d", ret); @@ -1127,7 +1111,7 @@ static int es8326_probe(struct snd_soc_component *component) &es8326->interrupt_clk); if (ret != 0) { dev_dbg(component->dev, "interrupt-clk return %d", ret); - es8326->interrupt_clk = 0x45; + es8326->interrupt_clk = 0x00; } dev_dbg(component->dev, "interrupt-clk %x", es8326->interrupt_clk); -- GitLab From 22db306961d924a37c8c69b70b5d1be203b9a4bc Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Thu, 7 Mar 2024 13:12:22 +0800 Subject: [PATCH 023/456] UPSTREAM: ASoC: codecs: ES8326: change support for ES8326 Removed mic1-src and mic2-src. and changed default value of interrupt-clk Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240307051222.24010-3-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit e87eecdf53228dd2b8bfeab84d409652f96a16d0) BUG=b:309733238, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I48d546306f28f02ca78d4978271d12a91984322d Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5379867 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: cong yang Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061889 Signed-off-by: Hubert Mazur --- .../devicetree/bindings/sound/everest,es8326.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/everest,es8326.yaml b/Documentation/devicetree/bindings/sound/everest,es8326.yaml index 07781408e7882..8c82d47375ec7 100644 --- a/Documentation/devicetree/bindings/sound/everest,es8326.yaml +++ b/Documentation/devicetree/bindings/sound/everest,es8326.yaml @@ -38,6 +38,7 @@ properties: default: 0x0f everest,mic1-src: + deprecated: true $ref: /schemas/types.yaml#/definitions/uint8 description: the value of reg 2A when headset plugged. @@ -46,6 +47,7 @@ properties: default: 0x22 everest,mic2-src: + deprecated: true $ref: /schemas/types.yaml#/definitions/uint8 description: the value of reg 2A when headset unplugged. @@ -87,7 +89,7 @@ properties: 0 means the chip detect jack type again after button released. minimum: 0 maximum: 0x7f - default: 0x45 + default: 0x00 required: - compatible @@ -107,10 +109,8 @@ examples: clocks = <&clks 10>; clock-names = "mclk"; #sound-dai-cells = <0>; - everest,mic1-src = [22]; - everest,mic2-src = [44]; everest,jack-pol = [0e]; everest,interrupt-src = [08]; - everest,interrupt-clk = [45]; + everest,interrupt-clk = [00]; }; }; -- GitLab From 1f154d6c1c62919814367ccf8811a853b60e9735 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Wed, 20 Mar 2024 16:30:11 +0800 Subject: [PATCH 024/456] UPSTREAM: ASoC: codecs: ES8326: Reducing power consumption For lower power consumption during hibernation, the configuration of es8326_suspend and es8326_remove will be adjusted. Adding es8326_i2c_shutdown and es8326_i2c_remove to cover different situations Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240320083012.4282-2-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 39938bb1bb23fd70f1c75ce9f52d92185403b89a) BUG=b:329220267, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I1fdd5cb98abf937bee34288e45d0bcf0b455c695 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5400156 Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061890 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 5942bd4c76f79..16ff2ec088b1d 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -1074,12 +1074,13 @@ static int es8326_suspend(struct snd_soc_component *component) es8326->calibrated = false; regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_OFF); regcache_cache_only(es8326->regmap, true); - regcache_mark_dirty(es8326->regmap); /* reset register value to default */ regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x01); usleep_range(1000, 3000); regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x00); + + regcache_mark_dirty(es8326->regmap); return 0; } @@ -1165,8 +1166,13 @@ static int es8326_set_jack(struct snd_soc_component *component, static void es8326_remove(struct snd_soc_component *component) { + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + es8326_disable_jack_detect(component); es8326_set_bias_level(component, SND_SOC_BIAS_OFF); + regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x01); + usleep_range(1000, 3000); + regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x00); } static const struct snd_soc_component_driver soc_component_dev_es8326 = { @@ -1238,6 +1244,29 @@ static int es8326_i2c_probe(struct i2c_client *i2c) &es8326_dai, 1); } + +static void es8326_i2c_shutdown(struct i2c_client *i2c) +{ + struct snd_soc_component *component; + struct es8326_priv *es8326; + + es8326 = i2c_get_clientdata(i2c); + component = es8326->component; + dev_dbg(component->dev, "Enter into %s\n", __func__); + cancel_delayed_work_sync(&es8326->jack_detect_work); + cancel_delayed_work_sync(&es8326->button_press_work); + + regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x01); + usleep_range(1000, 3000); + regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x00); + +} + +static void es8326_i2c_remove(struct i2c_client *i2c) +{ + es8326_i2c_shutdown(i2c); +} + static const struct i2c_device_id es8326_i2c_id[] = { {"es8326", 0 }, {} @@ -1267,6 +1296,8 @@ static struct i2c_driver es8326_i2c_driver = { .of_match_table = of_match_ptr(es8326_of_match), }, .probe = es8326_i2c_probe, + .shutdown = es8326_i2c_shutdown, + .remove = es8326_i2c_remove, .id_table = es8326_i2c_id, }; module_i2c_driver(es8326_i2c_driver); -- GitLab From 541cd67f9a0b641d410ecaec6c105123d0f76e1c Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Wed, 20 Mar 2024 16:30:12 +0800 Subject: [PATCH 025/456] UPSTREAM: ASoC: codecs: ES8326: Delete unused REG_SUPPLY REG_SUPPLY mutes the DAC when switching between HDMI and speaker, so remove it to fix the mute issues Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240320083012.4282-3-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit e6913c6ef83c80aa7569c9e08204542222fbf542) BUG=b:329220267, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I457fcb2f427d9083db1a06a1246295f070635e5d Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5400176 Reviewed-by: cong yang Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061891 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 16ff2ec088b1d..db8c6a91b6c3e 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -292,11 +292,6 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { SND_SOC_DAPM_PGA("LHPMIX", ES8326_DAC2HPMIX, 7, 0, NULL, 0), SND_SOC_DAPM_PGA("RHPMIX", ES8326_DAC2HPMIX, 3, 0, NULL, 0), - SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOR Supply", ES8326_HP_CAL, - 4, 7, 0, 0), - SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOL Supply", ES8326_HP_CAL, - 0, 7, 0, 0), - SND_SOC_DAPM_OUTPUT("HPOL"), SND_SOC_DAPM_OUTPUT("HPOR"), }; @@ -316,9 +311,6 @@ static const struct snd_soc_dapm_route es8326_dapm_routes[] = { {"LHPMIX", NULL, "Left DAC"}, {"RHPMIX", NULL, "Right DAC"}, - {"HPOR", NULL, "HPOR Supply"}, - {"HPOL", NULL, "HPOL Supply"}, - {"HPOL", NULL, "LHPMIX"}, {"HPOR", NULL, "RHPMIX"}, }; -- GitLab From 37c79f80f807c726d221d3e2ed69b79276f91d90 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 2 Apr 2024 14:20:40 +0800 Subject: [PATCH 026/456] UPSTREAM: ASoC: codecs: ES8326: Solve error interruption issue We got an error report about headphone type detection and button detection. We fixed the headphone type detection error by adjusting the debounce timer configuration. And we fixed the button detection error by disabling the button detection feature when the headphone are unplugged and enabling it when headphone are plugged in. Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240402062043.20608-2-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 8a655cee6c9d4588570ad0cb099c5660f9a44a12) BUG=b:330129193, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I75d3f9a0048c9246999821d7d53ce97a5d04730a Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5417834 Reviewed-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061892 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index db8c6a91b6c3e..34c0ab78bdc93 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -837,6 +837,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x0a); regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x0f, 0x03); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); /* * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event */ @@ -859,6 +860,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) * set auto-check mode, then restart jack_detect_work after 400ms. * Don't report jack status. */ + regmap_write(es8326->regmap, ES8326_INT_SOURCE, + (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); @@ -981,7 +984,7 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); usleep_range(10000, 15000); - regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0xe9); + regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0xd9); regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0xcb); /* set headphone default type and detect pin */ regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x83); @@ -1032,8 +1035,7 @@ static int es8326_resume(struct snd_soc_component *component) es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); - regmap_write(es8326->regmap, ES8326_INT_SOURCE, - (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, -- GitLab From 39f254d78ddbef3e4b804e2a401f569e9b12b917 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 2 Apr 2024 14:20:41 +0800 Subject: [PATCH 027/456] UPSTREAM: ASoC: codecs: ES8326: modify clock table We got a digital microphone feature issue. And we fixed it by modifying the clock table. Also, we changed the marco ES8326_CLK_ON declaration Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240402062043.20608-3-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 4581468d071b64a2e3c2ae333fff82dc0391a306) BUG=b:330129193, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ic4fa458b2c0b245b0445338e834460b45674c1c4 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5418594 Reviewed-by: Sean Paul Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061893 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 22 +++++++++++----------- sound/soc/codecs/es8326.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 34c0ab78bdc93..eeadaacf9dae8 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -404,9 +404,9 @@ static const struct _coeff_div coeff_div_v3[] = { {125, 48000, 6000000, 0x04, 0x04, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, {128, 8000, 1024000, 0x60, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, - {128, 16000, 2048000, 0x20, 0x00, 0x31, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, - {128, 44100, 5644800, 0xE0, 0x00, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, - {128, 48000, 6144000, 0xE0, 0x00, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {128, 16000, 2048000, 0x20, 0x00, 0x31, 0x35, 0x08, 0x19, 0x1F, 0x3F}, + {128, 44100, 5644800, 0xE0, 0x00, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, + {128, 48000, 6144000, 0xE0, 0x00, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, {144, 8000, 1152000, 0x20, 0x00, 0x03, 0x35, 0x8A, 0x1B, 0x23, 0x47}, {144, 16000, 2304000, 0x20, 0x00, 0x11, 0x35, 0x8A, 0x1B, 0x23, 0x47}, {192, 8000, 1536000, 0x60, 0x02, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, @@ -415,10 +415,10 @@ static const struct _coeff_div coeff_div_v3[] = { {200, 48000, 9600000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, {250, 48000, 12000000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x27, 0x27}, - {256, 8000, 2048000, 0x60, 0x00, 0x31, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, - {256, 16000, 4096000, 0x20, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, - {256, 44100, 11289600, 0xE0, 0x00, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, - {256, 48000, 12288000, 0xE0, 0x00, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {256, 8000, 2048000, 0x60, 0x00, 0x31, 0x35, 0x08, 0x19, 0x1F, 0x7F}, + {256, 16000, 4096000, 0x20, 0x00, 0x01, 0x35, 0x08, 0x19, 0x1F, 0x3F}, + {256, 44100, 11289600, 0xE0, 0x01, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, + {256, 48000, 12288000, 0xE0, 0x01, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, {288, 8000, 2304000, 0x20, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x23, 0x47}, {384, 8000, 3072000, 0x60, 0x02, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, {384, 16000, 6144000, 0x20, 0x02, 0x03, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, @@ -427,10 +427,10 @@ static const struct _coeff_div coeff_div_v3[] = { {400, 48000, 19200000, 0xE4, 0x04, 0x35, 0x6d, 0xCA, 0x0A, 0x1F, 0x1F}, {500, 48000, 24000000, 0xF8, 0x04, 0x3F, 0x6D, 0xCA, 0x0A, 0x1F, 0x1F}, - {512, 8000, 4096000, 0x60, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, - {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, - {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, - {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, + {512, 8000, 4096000, 0x60, 0x00, 0x01, 0x08, 0x19, 0x1B, 0x1F, 0x7F}, + {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x08, 0x19, 0x1F, 0x3F}, + {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, + {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, {768, 8000, 6144000, 0x60, 0x02, 0x11, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, {768, 16000, 12288000, 0x20, 0x02, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, {768, 32000, 24576000, 0xE0, 0x02, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, diff --git a/sound/soc/codecs/es8326.h b/sound/soc/codecs/es8326.h index ee12caef81053..c3e52e7bdef57 100644 --- a/sound/soc/codecs/es8326.h +++ b/sound/soc/codecs/es8326.h @@ -104,7 +104,7 @@ #define ES8326_MUTE (3 << 0) /* ES8326_CLK_CTL */ -#define ES8326_CLK_ON (0x7e << 0) +#define ES8326_CLK_ON (0x7f << 0) #define ES8326_CLK_OFF (0 << 0) /* ES8326_CLK_INV */ -- GitLab From a60c82c48b07925e7c96a4a3a295ef0eac26638c Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 2 Apr 2024 14:20:42 +0800 Subject: [PATCH 028/456] UPSTREAM: ASoC: codecs: ES8326: Solve a headphone detection issue after suspend and resume We got a headphone detection issue after suspend and resume. And we fixed it by modifying the configuration at es8326_suspend and invoke es8326_irq at es8326_resume. Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240402062043.20608-4-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 6e5f5bf894eb9260f07ad0da4e2dd2efd616ed59) BUG=b:330129193, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ib37d2644febbee83f06f4e3d6cc8cc49b14d5d67 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5417835 Reviewed-by: Fei Shao Reviewed-by: cong yang Reviewed-by: Sean Paul Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061894 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index eeadaacf9dae8..f9b386f1b842a 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -1056,6 +1056,8 @@ static int es8326_resume(struct snd_soc_component *component) es8326->hp = 0; es8326->hpl_vol = 0x03; es8326->hpr_vol = 0x03; + + es8326_irq(es8326->irq, es8326); return 0; } @@ -1066,6 +1068,9 @@ static int es8326_suspend(struct snd_soc_component *component) cancel_delayed_work_sync(&es8326->jack_detect_work); es8326_disable_micbias(component); es8326->calibrated = false; + regmap_write(es8326->regmap, ES8326_CLK_MUX, 0x2d); + regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x00); + regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b); regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_OFF); regcache_cache_only(es8326->regmap, true); -- GitLab From a777ebae481dfc7b25bd5ed5bd4b075468551b34 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 2 Apr 2024 14:20:43 +0800 Subject: [PATCH 029/456] UPSTREAM: ASoC: codecs: ES8326: Removing the control of ADC_SCALE We removed the configuration of ES8326_ADC_SCALE in es8326_jack_detect_handler because user changed the configuration by snd_controls Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240402062043.20608-5-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit fec9c7f668ac5dd107f4da5a3b18379e07ec1a41) BUG=b:330129193, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ide8d4780e48009a3b4bc697df80f49cd915855f2 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5418474 Reviewed-by: cong yang Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061895 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index f9b386f1b842a..5eaab1e1c8e7c 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -829,7 +829,6 @@ static void es8326_jack_detect_handler(struct work_struct *work) SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); snd_soc_jack_report(es8326->jack, 0, SND_JACK_HEADSET); /* mute adc when mic path switch */ - regmap_write(es8326->regmap, ES8326_ADC_SCALE, 0x33); regmap_write(es8326->regmap, ES8326_ADC1_SRC, 0x44); regmap_write(es8326->regmap, ES8326_ADC2_SRC, 0x66); es8326->hp = 0; @@ -888,7 +887,6 @@ static void es8326_jack_detect_handler(struct work_struct *work) snd_soc_jack_report(es8326->jack, SND_JACK_HEADSET, SND_JACK_HEADSET); - regmap_write(es8326->regmap, ES8326_ADC_SCALE, 0x33); regmap_update_bits(es8326->regmap, ES8326_PGA_PDN, 0x08, 0x08); regmap_update_bits(es8326->regmap, ES8326_PGAGAIN, -- GitLab From 4c22efa3bad4c2517c1d258284cc45ef52e0a6e7 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Wed, 15 May 2024 14:25:17 +0800 Subject: [PATCH 030/456] UPSTREAM: ASoC: codecs: ES8326: solve hp and button detect issue We got an error report about headphone type detection and button detection. We fixed the headphone type detection error by adjusting the condition of setting es8326->hp to 0.And we fixed the button detection error by adjusting micbias and vref. Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240515062517.23661-1-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 714f5df027b085c19c32af6f08a959bf35b9fb7c) BUG=b:340128964, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I295b6a162c04e1a3a1c799c9419e5eccfef81acc Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5543744 Reviewed-by: cong yang Reviewed-by: Fei Shao Reviewed-by: Sean Paul Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061896 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 5eaab1e1c8e7c..b7b3eec56d5a7 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -831,8 +831,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) /* mute adc when mic path switch */ regmap_write(es8326->regmap, ES8326_ADC1_SRC, 0x44); regmap_write(es8326->regmap, ES8326_ADC2_SRC, 0x66); - es8326->hp = 0; } + es8326->hp = 0; regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x0a); regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x0f, 0x03); @@ -983,7 +983,7 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); usleep_range(10000, 15000); regmap_write(es8326->regmap, ES8326_HPJACK_TIMER, 0xd9); - regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0xcb); + regmap_write(es8326->regmap, ES8326_ANA_MICBIAS, 0xd8); /* set headphone default type and detect pin */ regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x83); regmap_write(es8326->regmap, ES8326_CLK_RESAMPLE, 0x05); @@ -1020,7 +1020,7 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_ANA_VSEL, 0x7F); /* select vdda as micbias source */ - regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x23); + regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x03); /* set dac dsmclip = 1 */ regmap_write(es8326->regmap, ES8326_DAC_DSM, 0x08); regmap_write(es8326->regmap, ES8326_DAC_VPPSCALE, 0x15); -- GitLab From 15faa6bc6da4bc89db35adc6b0850ac93f97edbf Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 4 Jun 2024 10:19:46 +0800 Subject: [PATCH 031/456] UPSTREAM: ASoC: codecs: ES8326: Solve headphone detection issue When switching between OMTP and CTIA headset, we can hear pop noise. To solve this issue, We modified the configuration for headphone detection Signed-off-by: Zhang Yi Link: https://msgid.link/r/20240604021946.2911-1-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit b7c40988808f8d7426dee1e4d96a4e204de4a8bc) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Id79d3d3b3efb226b92b20110dd3c8bea8bea0d8e Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5960420 Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061997 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index b7b3eec56d5a7..98049a21f35b4 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -859,12 +859,16 @@ static void es8326_jack_detect_handler(struct work_struct *work) * set auto-check mode, then restart jack_detect_work after 400ms. * Don't report jack status. */ - regmap_write(es8326->regmap, ES8326_INT_SOURCE, - (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x00); es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x10); + usleep_range(50000, 70000); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, + (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x1f); regmap_update_bits(es8326->regmap, ES8326_HP_DRIVER_REF, 0x0f, 0x08); queue_delayed_work(system_wq, &es8326->jack_detect_work, -- GitLab From 9f4f524d36eaeefef26305a1678ebb818a6481e5 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Mon, 24 Jun 2024 11:06:04 +0800 Subject: [PATCH 032/456] UPSTREAM: ASoC: codecs: ES8326: Slove headphone detection issue We modified the headphone detection setting to avoid an error button state after codec resume from suspend state Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20240624030607.4307-2-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 4eed78198b30c4c5975e454e7b1e6e25a7ac7353) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I2ecc532326952a68aa219acf640c809352716a2e Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5960421 Reviewed-by: cong yang Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061998 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 98049a21f35b4..212dfda173576 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -879,6 +879,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) if (es8326->jack->status & SND_JACK_HEADSET) { /* detect button */ dev_dbg(comp->dev, "button pressed\n"); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, + (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); queue_delayed_work(system_wq, &es8326->button_press_work, 10); goto exit; } @@ -1054,11 +1056,6 @@ static int es8326_resume(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); - es8326->jack_remove_retry = 0; - es8326->hp = 0; - es8326->hpl_vol = 0x03; - es8326->hpr_vol = 0x03; - es8326_irq(es8326->irq, es8326); return 0; } @@ -1213,6 +1210,10 @@ static int es8326_i2c_probe(struct i2c_client *i2c) } es8326->irq = i2c->irq; + es8326->jack_remove_retry = 0; + es8326->hp = 0; + es8326->hpl_vol = 0x03; + es8326->hpr_vol = 0x03; INIT_DELAYED_WORK(&es8326->jack_detect_work, es8326_jack_detect_handler); INIT_DELAYED_WORK(&es8326->button_press_work, -- GitLab From 3e329885fdf3b484345cb9c0986c66f0ed17dc79 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Mon, 24 Jun 2024 11:06:06 +0800 Subject: [PATCH 033/456] UPSTREAM: ASoC: codecs: ES8326: Minimize the pop noise Executing regcache_sync at initialization, we can hear a gentle pop noise. So we created es8326_init for initialization instead of executing es8326_resume Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20240624030607.4307-4-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 7e7dbdee96cbc660e7e8d3d9d7a512acaa6ca69d) BUG=b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ieb9c332f25b1c71fac8e6bbaccb56def4d5cb8b2 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5960422 Reviewed-by: Sean Paul Reviewed-by: cong yang Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061999 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 212dfda173576..a9c1156c93e5b 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -976,14 +976,10 @@ static int es8326_calibrate(struct snd_soc_component *component) return 0; } -static int es8326_resume(struct snd_soc_component *component) +static void es8326_init(struct snd_soc_component *component) { struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); - regcache_cache_only(es8326->regmap, false); - regcache_sync(es8326->regmap); - - /* reset internal clock state */ regmap_write(es8326->regmap, ES8326_RESET, 0x1f); regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); @@ -1039,7 +1035,6 @@ static int es8326_resume(struct snd_soc_component *component) es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); - regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, @@ -1055,6 +1050,28 @@ static int es8326_resume(struct snd_soc_component *component) ES8326_MUTE); regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); + regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff); + + msleep(200); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); +} + +static int es8326_resume(struct snd_soc_component *component) +{ + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int reg; + + regcache_cache_only(es8326->regmap, false); + regcache_cache_bypass(es8326->regmap, true); + regmap_read(es8326->regmap, ES8326_CLK_RESAMPLE, ®); + regcache_cache_bypass(es8326->regmap, false); + /* reset internal clock state */ + if (reg == 0x05) + regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_ON); + else + es8326_init(component); + + regcache_sync(es8326->regmap); es8326_irq(es8326->irq, es8326); return 0; @@ -1114,7 +1131,7 @@ static int es8326_probe(struct snd_soc_component *component) } dev_dbg(component->dev, "interrupt-clk %x", es8326->interrupt_clk); - es8326_resume(component); + es8326_init(component); return 0; } -- GitLab From 1397e232764ffe8acb5ae85ad6e653ece2968e0d Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Mon, 24 Jun 2024 11:06:07 +0800 Subject: [PATCH 034/456] UPSTREAM: ASoC: codecs: ES8326: regcache_sync error issue We modified the regmap_config members to fix cach sync error. There are several registers that should be read-only registers. If these registers are written while synchronizing the register values, the codec will enter an error state.So we create es8326_writeable_register, and set these registers to false Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20240624030607.4307-5-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 34fa846f52f9fbef8aa262d3b39e71188e8dd884) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: I3e367a5c4c20f2f129159b9a6ade3a47104704ba Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5960423 Reviewed-by: cong yang Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6062000 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index a9c1156c93e5b..602a73771ec91 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -329,11 +329,29 @@ static bool es8326_volatile_register(struct device *dev, unsigned int reg) } } +static bool es8326_writeable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ES8326_BIAS_SW1: + case ES8326_BIAS_SW2: + case ES8326_BIAS_SW3: + case ES8326_BIAS_SW4: + case ES8326_ADC_HPFS1: + case ES8326_ADC_HPFS2: + return false; + default: + return true; + } +} + static const struct regmap_config es8326_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = 0xff, + .use_single_read = true, + .use_single_write = true, .volatile_reg = es8326_volatile_register, + .writeable_reg = es8326_writeable_register, .cache_type = REGCACHE_RBTREE, }; -- GitLab From 54d5c9e0abed229befaf8b8f26787821cc415eb8 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Fri, 26 Jul 2024 11:10:02 +0800 Subject: [PATCH 035/456] UPSTREAM: ASoC: codecs: ES8326: suspend issue We find that we need to disable micbias for the codec to enter suspend So We modify the trigger conditions for enable_micbias and disable_micbias Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20240726031002.35055-1-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 6024f3429fd1ac4948bac9610ecd4d0139088f0b) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ic07d1f9ed7c3ad0ef9f154246a96b73ea80af609 Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5960424 Reviewed-by: cong yang Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6062001 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 602a73771ec91..cac1502de5e98 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -805,6 +805,7 @@ static void es8326_jack_button_handler(struct work_struct *work) SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); button_to_report = 0; } + es8326_disable_micbias(es8326->component); } mutex_unlock(&es8326->lock); } @@ -880,7 +881,6 @@ static void es8326_jack_detect_handler(struct work_struct *work) regmap_write(es8326->regmap, ES8326_INT_SOURCE, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x00); - es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x10); @@ -899,6 +899,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) dev_dbg(comp->dev, "button pressed\n"); regmap_write(es8326->regmap, ES8326_INT_SOURCE, (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); + es8326_enable_micbias(es8326->component); queue_delayed_work(system_wq, &es8326->button_press_work, 10); goto exit; } @@ -1069,6 +1070,7 @@ static void es8326_init(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff); + es8326_disable_micbias(es8326->component); msleep(200); regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); -- GitLab From 19ed5b746744d1e41e2906c6833125072990fc49 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Mon, 28 Oct 2024 14:05:29 +0800 Subject: [PATCH 036/456] UPSTREAM: ASoC: codecs: ES8326: Modify the configuration of and micbias Because we designed a new version of ES8326, the configuration of micbias needed to be modified.We tested the new driver, on both the new version and the old one. It works well. Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20241028060529.3359-1-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit bc48c55557edea46939ffef8ab9fa807b5951948) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Ie8d00acd6f2cb69c2399400cd2826c869ac14d9c Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5974575 Reviewed-by: Sean Paul Reviewed-by: cong yang Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6062002 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index cac1502de5e98..0d97fc77ab0a8 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -614,6 +614,10 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) } else { regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE, 0x0F, 0x0F); + if (es8326->version > ES8326_VERSION_B) { + regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x00); + } } } else { if (!es8326->calibrated) { @@ -640,6 +644,10 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) ES8326_MUTE_MASK, ~(ES8326_MUTE)); } else { msleep(300); + if (es8326->version > ES8326_VERSION_B) { + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x50); + regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x00); + } regmap_update_bits(es8326->regmap, ES8326_ADC_MUTE, 0x0F, 0x00); } @@ -821,7 +829,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) iface = snd_soc_component_read(comp, ES8326_HPDET_STA); dev_dbg(comp->dev, "gpio flag %#04x", iface); - if ((es8326->jack_remove_retry == 1) && (es8326->version != ES8326_VERSION_B)) { + if ((es8326->jack_remove_retry == 1) && (es8326->version < ES8326_VERSION_B)) { if (iface & ES8326_HPINSERT_FLAG) es8326->jack_remove_retry = 2; else @@ -859,7 +867,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) /* * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event */ - if ((es8326->jack_remove_retry == 0) && (es8326->version != ES8326_VERSION_B)) { + if ((es8326->jack_remove_retry == 0) && (es8326->version < ES8326_VERSION_B)) { es8326->jack_remove_retry = 1; dev_dbg(comp->dev, "remove event check, invert HPJACK_POL, cnt = %d\n", es8326->jack_remove_retry); @@ -954,7 +962,7 @@ static int es8326_calibrate(struct snd_soc_component *component) regmap_read(es8326->regmap, ES8326_CHIP_VERSION, ®); es8326->version = reg; - if ((es8326->version == ES8326_VERSION_B) && (es8326->calibrated == false)) { + if ((es8326->version >= ES8326_VERSION_B) && (es8326->calibrated == false)) { dev_dbg(component->dev, "ES8326_VERSION_B, calibrating\n"); regmap_write(es8326->regmap, ES8326_CLK_INV, 0xc0); regmap_write(es8326->regmap, ES8326_CLK_DIV1, 0x03); @@ -1047,7 +1055,7 @@ static void es8326_init(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_DAC_VPPSCALE, 0x15); regmap_write(es8326->regmap, ES8326_HPDET_TYPE, 0x80 | - ((es8326->version == ES8326_VERSION_B) ? + ((es8326->version >= ES8326_VERSION_B) ? (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); usleep_range(5000, 10000); @@ -1071,6 +1079,10 @@ static void es8326_init(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff); es8326_disable_micbias(es8326->component); + if (es8326->version > ES8326_VERSION_B) { + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x73, 0x03); + regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40); + } msleep(200); regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); -- GitLab From 5a43a4936d75312c7f2ac1df1a29b046a6c9d02f Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Thu, 31 Oct 2024 14:02:53 +0800 Subject: [PATCH 037/456] UPSTREAM: ASoC: codecs: ES8326: Reduce pop noise We modify the value of ES8326_ANA_MICBIAS to reduce the pop noise Signed-off-by: Zhang Yi Link: https://patch.msgid.link/20241031060253.21001-1-zhangyi@everest-semi.com Signed-off-by: Mark Brown (cherry picked from commit 8f5fab5329b7e966344d59fd1c17adbf9f025c52) BUG=b:376164982, b:380813926 TEST=Play audio on Ciri sku2 Change-Id: Id7b85aab0996fc99a0c06d0720c352048152ac7e Signed-off-by: Rui Zhou Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5997811 Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-by: Lei Cao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6062003 Signed-off-by: Hubert Mazur --- sound/soc/codecs/es8326.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 0d97fc77ab0a8..a722632fefb4e 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -616,7 +616,7 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) 0x0F, 0x0F); if (es8326->version > ES8326_VERSION_B) { regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40); - regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x00); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x10); } } } else { @@ -1080,7 +1080,7 @@ static void es8326_init(struct snd_soc_component *component) regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff); es8326_disable_micbias(es8326->component); if (es8326->version > ES8326_VERSION_B) { - regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x73, 0x03); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x73, 0x13); regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40); } -- GitLab From bc6df4964a1f6627845d23d5429a176e4523507a Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 27 Nov 2024 03:34:36 +0000 Subject: [PATCH 038/456] Revert "BACKPORT: FROMLIST: xhci: fix unmatched num_trbs_free" This reverts commit 22fc096fac606b2013801ed45ae711e732ea95ef. Reason: per b/356734817#comment14, commit 2710f8186f88 ("xhci: Stop unnecessary tracking of free trbs in a ring") can replace it. BUG=b:356734817 BUG=b:285134532 TEST=none Change-Id: Id7028b6b67a6be8b6df02db194fa5262f37c80e4 Signed-off-by: Tzung-Bi Shih Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6048306 Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- drivers/usb/host/xhci-ring.c | 92 ++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 65fb74eb873eb..0e97f98c1bd4e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -158,54 +158,6 @@ static void next_trb(struct xhci_hcd *xhci, } } -/* Forward dequeue pointer to the specific position, - * walk through the ring and reclaim free trb slots to num_trbs_free - */ -static int move_deq(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, - struct xhci_segment *new_seg, union xhci_trb *new_deq) -{ - unsigned int steps; - union xhci_trb *deq; - struct xhci_segment *seg = ep_ring->deq_seg; - - /* direct paths */ - if (ep_ring->dequeue == new_deq) { - return 0; - } else if ((ep_ring->deq_seg == new_seg) && - (ep_ring->dequeue <= new_deq)) { - steps = new_deq - ep_ring->dequeue; - deq = new_deq; - goto found; - } - - /* fast walk to the next segment */ - seg = seg->next; - steps = (TRBS_PER_SEGMENT - 1) - - (ep_ring->dequeue - ep_ring->deq_seg->trbs); - deq = &seg->trbs[0]; - - while (deq != new_deq) { - if (trb_is_link(deq)) { - seg = seg->next; - deq = seg->trbs; - } else { - steps++; - deq++; - } - if (deq == ep_ring->dequeue) { - xhci_warn(xhci, "Unable to find new dequeue pointer\n"); - return -ENOENT; - } - } - -found: - ep_ring->deq_seg = seg; - ep_ring->dequeue = deq; - ep_ring->num_trbs_free += steps; - - return 0; -} - /* * See Cycle bit rules. SW is the consumer for the event ring only. */ @@ -1376,6 +1328,43 @@ void xhci_hc_died(struct xhci_hcd *xhci) usb_hc_died(xhci_to_hcd(xhci)); } +static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci, + struct xhci_virt_device *dev, + struct xhci_ring *ep_ring, + unsigned int ep_index) +{ + union xhci_trb *dequeue_temp; + + dequeue_temp = ep_ring->dequeue; + + /* If we get two back-to-back stalls, and the first stalled transfer + * ends just before a link TRB, the dequeue pointer will be left on + * the link TRB by the code in the while loop. So we have to update + * the dequeue pointer one segment further, or we'll jump off + * the segment into la-la-land. + */ + if (trb_is_link(ep_ring->dequeue)) { + ep_ring->deq_seg = ep_ring->deq_seg->next; + ep_ring->dequeue = ep_ring->deq_seg->trbs; + } + + while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) { + /* We have more usable TRBs */ + ep_ring->dequeue++; + if (trb_is_link(ep_ring->dequeue)) { + if (ep_ring->dequeue == + dev->eps[ep_index].queued_deq_ptr) + break; + ep_ring->deq_seg = ep_ring->deq_seg->next; + ep_ring->dequeue = ep_ring->deq_seg->trbs; + } + if (ep_ring->dequeue == dequeue_temp) { + xhci_dbg(xhci, "Unable to find new dequeue pointer\n"); + break; + } + } +} + /* * When we get a completion for a Set Transfer Ring Dequeue Pointer command, * we need to clear the set deq pending flag in the endpoint ring state, so that @@ -1476,8 +1465,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, /* Update the ring's dequeue segment and dequeue pointer * to reflect the new position. */ - move_deq(xhci, ep_ring, ep->queued_deq_seg, - ep->queued_deq_ptr); + update_ring_for_set_deq_completion(xhci, ep->vdev, + ep_ring, ep_index); } else { xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n"); xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", @@ -2352,7 +2341,8 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, } /* Update ring dequeue pointer */ - move_deq(xhci, ep_ring, td->last_trb_seg, td->last_trb); + ep_ring->dequeue = td->last_trb; + ep_ring->deq_seg = td->last_trb_seg; inc_deq(xhci, ep_ring); return xhci_td_cleanup(xhci, td, ep_ring, td->status); -- GitLab From b91c0d7e50f34af1937be36fe7e565d8f28f8e2f Mon Sep 17 00:00:00 2001 From: Vineeth Pillai Date: Mon, 25 Nov 2024 09:50:45 -0500 Subject: [PATCH 039/456] CHROMIUM: sched: Fix the dl_server reset logic dl_server field in task_struct should only be set when the task is selected by dlserver. There were couple of code path where the reset was not happening and this caused incorrect usage of dlserver. There are cases where dl_server was not reset and task migrates to another cpu. One such example caused triggering of the following WARNING: WARNING: CPU: 0 PID: 2682 at kernel/sched/sched.h:1377 update_curr_dl_se+0x4b8/0x6f1 update_curr+0x12f/0x327 kernel/sched/fair.c:980 put_prev_entity+0x3c/0x139 kernel/sched/fair.c:5123 put_prev_task_fair+0x39/0x5f kernel/sched/fair.c:8132 put_prev_task kernel/sched/sched.h:2269 [inline] put_prev_task_balance+0x12d/0x190 kernel/sched/core.c:6006 __pick_next_task kernel/sched/core.c:6063 [inline] pick_next_task kernel/sched/core.c:6124 [inline] __schedule+0x970/0x43a0 kernel/sched/core.c:6703 preempt_schedule_common+0x74/0xc0 kernel/sched/core.c:6920 preempt_schedule+0xd6/0xdd kernel/sched/core.c:6944 preempt_schedule_thunk+0x16/0x18 arch/x86/entry/thunk_64.S:34 __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:160 [inline] _raw_spin_unlock_irq+0x3c/0x3e kernel/locking/spinlock.c:202 spin_unlock_irq include/linux/spinlock.h:401 [inline] call_usermodehelper_exec_async+0x7a/0x336 kernel/umh.c:75 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 Fix those paths where dl_server field was not reset correctly. Upstream has taken care of this by a small rework in dlserver: commit bd9bbc96e835 ("sched: Rework dl_server") Backporting is not trivial as this commit is based on a set of patches for sched_ext preparation. BUG=b:379053607 TEST=syzkaller repro program doesn't crash Change-Id: I2a5015fe8d26d8f684e4c8cf7fa11c1eebb0f643 Signed-off-by: Vineeth Pillai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6049514 Reviewed-by: Suleiman Souhlal Signed-off-by: Hubert Mazur --- kernel/sched/core.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 9708589ebf04c..c0ee11c747410 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4056,8 +4056,6 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags, rq->idle_stamp = 0; } #endif - - p->dl_server = NULL; } /* @@ -5051,6 +5049,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) init_entity_runnable_average(&p->se); trace_android_rvh_finish_prio_fork(p); + p->dl_server = NULL; #ifdef CONFIG_SCHED_INFO if (likely(sched_info_on())) @@ -6331,18 +6330,12 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) /* * This is a normal CFS pick, but the previous could be a DL pick. - * Clear it as previous is no longer picked. + * Clear it as previous is no longer picked. We also clear this if + * @p == @prev, as this is not a dlserver pick. */ if (prev->dl_server) prev->dl_server = NULL; - /* - * This is the fast path; it cannot be a DL server pick; - * therefore even if @p == @prev, ->dl_server must be NULL. - */ - if (p->dl_server) - p->dl_server = NULL; - return p; } @@ -6419,7 +6412,10 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) * coming online. core_pick would already be migrated to * another cpu during offline. */ - rq->core_pick = NULL; + if (rq->core_pick) { + rq->core_pick->dl_server = NULL; + rq->core_pick = NULL; + } return __pick_next_task(rq, prev, rf); } @@ -6440,6 +6436,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) next = rq->core_pick; if (next != prev) { put_prev_task(rq, prev); + prev->dl_server = NULL; set_next_task(rq, next); } @@ -6487,7 +6484,10 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) if (!need_sync) { next = pick_task(rq); if (!next->core_cookie) { - rq->core_pick = NULL; + if (rq->core_pick) { + rq->core_pick->dl_server = NULL; + rq->core_pick = NULL; + } /* * For robustness, update the min_vruntime_fi for * unconstrained picks as well. -- GitLab From 93c3acb0f1bdb662edc58ff918d39b97e0131b32 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 2 Dec 2024 08:14:13 -0800 Subject: [PATCH 040/456] Revert "FROMLIST: remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region" This reverts commit 59e92ca1c5a7bc64cf7dcebf061c1de6da4be7c0. We'll replace with the upstream-tagged commit. BUG=b:360864198 TEST=git diff Cq-Depend: chromium:6064359 Change-Id: Ic8dd5d7483f6c5c7db5c3c0d20b2ecb1e37c5370 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6064358 Reviewed-by: Stephen Boyd Commit-Queue: Stephen Boyd Signed-off-by: Hubert Mazur --- drivers/remoteproc/qcom_q6v5_mss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 2d717f2ed396c..22fe7b5f5236d 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -1161,9 +1161,6 @@ static int q6v5_mba_load(struct q6v5 *qproc) goto disable_active_clks; } - if (qproc->has_mba_logs) - qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE); - writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); if (qproc->dp_size) { writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG); @@ -1174,6 +1171,9 @@ static int q6v5_mba_load(struct q6v5 *qproc) if (ret) goto reclaim_mba; + if (qproc->has_mba_logs) + qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE); + ret = q6v5_rmb_mba_wait(qproc, 0, 5000); if (ret == -ETIMEDOUT) { dev_err(qproc->dev, "MBA boot timed out\n"); -- GitLab From 55920d8b624db6d12ebcd7a68ed79b4264801897 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Tue, 3 Dec 2024 02:09:00 +0000 Subject: [PATCH 041/456] UPSTREAM: net: ethernet: mtk_wed: fix path of MT7988 WO firmware linux-firmware commit 808cba84 ("mtk_wed: add firmware for mt7988 Wireless Ethernet Dispatcher") added mt7988_wo_{0,1}.bin in the 'mediatek/mt7988' directory while driver current expects the files in the 'mediatek' directory. Change path in the driver header now that the firmware has been added. Fixes: e2f64db13aa1 ("net: ethernet: mtk_wed: introduce WED support for MT7988") Signed-off-by: Daniel Golle Reviewed-by: Andrew Lunn Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/Zxz0GWTR5X5LdWPe@pidgin.makrotopia.org Signed-off-by: Jakub Kicinski (cherry picked from commit 637f41476384c76d3cd7dcf5947caf2c8b8d7a9b) BUG=b:178754244, b:337131500 TEST=Build against all mt76 drivers successfully Signed-off-by: Linux Patches Robot Change-Id: I92201471ce7d538b5da738171e3e1b48758d9d8a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6065747 Commit-Queue: David Ruth Reviewed-by: Sean Paul Reviewed-by: David Ruth Reviewed-by: Jintao Lin Tested-by: Jintao Lin Signed-off-by: Hubert Mazur --- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h index 87a67fa3868d3..c01b1e8428f6d 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h @@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx { #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" -#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin" -#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin" +#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin" +#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin" #define MTK_WO_MCU_CFG_LS_BASE 0 #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) -- GitLab From da9c0768c993ae104a7afe320e049e0a879ae70d Mon Sep 17 00:00:00 2001 From: Marek Maslanka Date: Thu, 28 Nov 2024 20:52:09 +0000 Subject: [PATCH 042/456] FROMGIT: ASoC: Intel: avs: da7219: Remove suspend_pre() and resume_post() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The presence of a plugged jack is not detected after resuming the device if the jack was plugged before the device was suspended. This problem is caused by calling the sound/soc/codecs/da7219-aad.c:da7219_aad_jack_det() function on resume, which forces the jack insertion state to be unplugged. Signed-off-by: Marek Maslanka Link: https://patch.msgid.link/20241128205215.2435485-1-mmaslanka@google.com Reviewed-by: Cezary Rojewski Signed-off-by: Mark Brown (cherry picked from commit 04c319e05d0b08cc789db7abccce0fcb13dbab16 https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next) BUG=b:351137990 TEST=Build & deploy. Insert headphone jack, suspend-resume, check if inserted jack is detected Change-Id: If71c4f4b3d9f6e1847bbc9a7949f4367c65efd14 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6070067 Reviewed-by: Sean Paul Tested-by: Marek Maślanka Auto-Submit: Marek Maślanka Commit-Queue: Marek Maślanka Reviewed-by: Łukasz Majczak Signed-off-by: Hubert Mazur --- sound/soc/intel/avs/boards/da7219.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 80c0a1a956542..daf53ca490a14 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -211,21 +211,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_card_suspend_pre(struct snd_soc_card *card) -{ - struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); - - return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); -} - -static int avs_card_resume_post(struct snd_soc_card *card) -{ - struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); - struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - - return snd_soc_component_set_jack(codec_dai->component, jack, NULL); -} - static int avs_da7219_probe(struct platform_device *pdev) { struct snd_soc_dai_link *dai_link; @@ -257,8 +242,6 @@ static int avs_da7219_probe(struct platform_device *pdev) card->name = "avs_da7219"; card->dev = dev; card->owner = THIS_MODULE; - card->suspend_pre = avs_card_suspend_pre; - card->resume_post = avs_card_resume_post; card->dai_link = dai_link; card->num_links = 1; card->controls = card_controls; -- GitLab From c51c71f3b298ef37a396e0046c3e6b017f74377d Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Thu, 15 Aug 2024 18:12:10 +0800 Subject: [PATCH 043/456] CHROMIUM: thermal: mediatek: Add virtual temp driver (v2) Add virtual temp driver to create a virtual sensor for the thermal aggregation zone (soc_max) for device thermal controls. This driver is a refactored version based on previous MTK driver. MTK attempted to upstream this but got rejected, and they are working on the alternative solution. This is the tentative solution before that becomes available. BUG=b:382001244 UPSTREAM-TASK=b:236331727 TEST=grep -r . /sys/class/thermal/thermal_zone*/type Change-Id: I363a74a4bbc00dea6218e3e0955edc179b28a0f4 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6063465 Reviewed-by: Pin-yen Lin Commit-Queue: Hsin-Te Yuan Tested-by: Hsin-Te Yuan Kcr-patch: 2709799f1affdde144f48a76580afa9f5c6d5542d647e412ea562b6d.patch Signed-off-by: Hubert Mazur --- drivers/thermal/mediatek/Makefile | 2 +- drivers/thermal/mediatek/virtual_temp.c | 108 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 drivers/thermal/mediatek/virtual_temp.c diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile index 409964f83ac7c..cd67ee5aea0d1 100644 --- a/drivers/thermal/mediatek/Makefile +++ b/drivers/thermal/mediatek/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o -obj-$(CONFIG_MTK_LVTS_THERMAL) += lvts_thermal.o +obj-$(CONFIG_MTK_LVTS_THERMAL) += lvts_thermal.o virtual_temp.o obj-$(CONFIG_MTK_LVTS_THERMAL) += soc_temp_lvts.o obj-$(CONFIG_MTK_LVTS_THERMAL) += soc_temp_lvts_mt8192.o diff --git a/drivers/thermal/mediatek/virtual_temp.c b/drivers/thermal/mediatek/virtual_temp.c new file mode 100644 index 0000000000000..bc843bfe445cd --- /dev/null +++ b/drivers/thermal/mediatek/virtual_temp.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Copyright (c) 2024 Google Inc. + */ +#include +#include +#include +#include +#include + +#define TZ_DEV_SZ_MAX 20 + +static struct thermal_zone_device *tz_devs[TZ_DEV_SZ_MAX]; +static const char **tz_dev_names; +static u32 tz_dev_sz; + +static int vtemp_get_temp(struct thermal_zone_device *tz, int *temp) +{ + int i, ret; + int tz_temp, tz_temp_max = 0; + + for (i = 0; i < tz_dev_sz; i++) { + if (!tz_devs[i]) { + dev_warn(&tz->device, "Thermal zone %s is NULL\n", tz_dev_names[i]); + continue; + } + + ret = thermal_zone_get_temp(tz_devs[i], &tz_temp); + if (ret < 0) { + if (ret != -EAGAIN) + dev_warn(&tz->device, + "Failed to get temp from %s: %d\n", + tz_dev_names[i], ret); + continue; + } + tz_temp_max = max(tz_temp_max, tz_temp); + } + + *temp = tz_temp_max; + + return 0; +} + +static const struct thermal_zone_device_ops vtemp_ops = { + .get_temp = vtemp_get_temp, +}; + +static int vtemp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev_of_node(dev); + struct thermal_zone_device *tz_vtemp; + int i, ret; + + tz_dev_names = devm_kcalloc(dev, TZ_DEV_SZ_MAX, sizeof(*tz_dev_names), GFP_KERNEL); + if (!tz_dev_names) + return -ENOMEM; + + ret = of_property_read_string_array(np, "mediatek,tz-names", tz_dev_names, TZ_DEV_SZ_MAX); + if (ret < 0) + return ret; + + tz_dev_sz = (u32)ret; + for (i = 0; i < tz_dev_sz; i++) { + tz_devs[i] = thermal_zone_get_zone_by_name(tz_dev_names[i]); + if (IS_ERR(tz_devs[i])) { + ret = PTR_ERR(tz_devs[i]); + + /* The thermal zone may not be ready yet, defer probing to retry. */ + if (ret == -ENODEV) { + dev_dbg(dev, "thermal zone %s is not ready, defer probing.\n", + tz_dev_names[i]); + return -EPROBE_DEFER; + } + + dev_err(dev, "Failed to get thermal zone %s: %d\n", tz_dev_names[i], ret); + return ret; + } + } + + tz_vtemp = devm_thermal_of_zone_register(dev, 0, NULL, &vtemp_ops); + if (IS_ERR(tz_vtemp)) + return dev_err_probe(dev, PTR_ERR(tz_vtemp), + "Failed to register vtemp thermal zone\n"); + + return 0; +} + +static const struct of_device_id vtemp_of_match[] = { + { .compatible = "mediatek,virtual-temp", }, + {}, +}; +MODULE_DEVICE_TABLE(of, vtemp_of_match); + +static struct platform_driver vtemp_driver = { + .probe = vtemp_probe, + .driver = { + .name = "mtk-virtual-temp", + .of_match_table = vtemp_of_match, + }, +}; + +module_platform_driver(vtemp_driver); + +MODULE_AUTHOR("Michael Kao "); +MODULE_DESCRIPTION("MediaTek Virtual Temp driver v2"); +MODULE_LICENSE("GPL v2"); -- GitLab From 88d81b7b13d574cea23d754bfccc654ab66e33e4 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Fri, 30 Aug 2024 13:03:31 +0800 Subject: [PATCH 044/456] CHROMIUM: arm64: dts: mediatek: mt8188: Drop CPU/GPU thermal zone cooling maps The upstream thermal solution is still WIP, and the current cooling maps and trip points configurations for individual CPU/GPU cluster thermal zone significantly degrade CPU frequency temperature limit as there's no tuned sustainable-power and "switch on" trip point information for power allocator governor. Remove the cooling maps for performance concerns, and fall back to the original downstream aggregated soc_max thermal zone for thermal control. BUG=b:382001244 UPSTREAM-TASK=b:236331727 TEST=grep -r . /sys/class/thermal/thermal_zone*/type Change-Id: I3fb0c0e0951efcc265bc42ce7c3b78846d6f8f10 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6063466 Reviewed-by: Pin-yen Lin Tested-by: Hsin-Te Yuan Commit-Queue: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188.dtsi | 78 ------------------------ 1 file changed, 78 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi index 23ec3ff6cad9b..f61ba01deee35 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi @@ -490,18 +490,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_little0_alert0>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; cpu-little1-thermal { @@ -528,18 +516,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_little1_alert0>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; cpu-little2-thermal { @@ -566,18 +542,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_little2_alert0>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; cpu-little3-thermal { @@ -604,18 +568,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_little3_alert0>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; cpu-big0-thermal { @@ -642,14 +594,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_big0_alert0>; - cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; cpu-big1-thermal { @@ -676,14 +620,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&cpu_big1_alert0>; - cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; apu-thermal { @@ -736,13 +672,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&gpu_alert0>; - cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; gpu1-thermal { @@ -769,13 +698,6 @@ type = "critical"; }; }; - - cooling-maps { - map0 { - trip = <&gpu1_alert0>; - cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; }; adsp-thermal { -- GitLab From 59f9b340e93a860d5c400c3dd6c681ad0a474b4b Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Tue, 3 Dec 2024 09:06:02 +0000 Subject: [PATCH 045/456] CHROMIUM: arm64: dts: mediatek: mt8188: Add vtemp node Add virtual temp sensor for thermal aggregation. mediatek,tz-names property lists all the thermal zones on MT8188. BUG=b:382001244 TEST=grep -r . /sys/class/thermal/thermal_zone*/type UPSTREAM-TASK=b:236331727 Change-Id: I9ee64b85262f9ba71d12dda9b38178bbc0cf2409 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6063467 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi index f61ba01deee35..078d39522db8b 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi @@ -465,6 +465,25 @@ status = "disabled"; }; + vtemp: vtemp { + compatible = "mediatek,virtual-temp"; + #thermal-sensor-cells = <1>; + mediatek,tz-names = "cpu-little0-thermal", + "cpu-little1-thermal", + "cpu-little2-thermal", + "cpu-little3-thermal", + "cpu-big0-thermal", + "cpu-big1-thermal", + "apu-thermal", + "gpu-thermal", + "gpu1-thermal", + "adsp-thermal", + "vdo-thermal", + "infra-thermal", + "cam1-thermal", + "cam2-thermal"; + }; + thermal_zones: thermal-zones { cpu-little0-thermal { polling-delay = <1000>; -- GitLab From 5af06eb0b5938ffd6b2ef4e426d0533cc1dfd8e7 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Fri, 30 Aug 2024 11:48:42 +0800 Subject: [PATCH 046/456] CHROMIUM: arm64: dts: mediatek: mt8188: Add soc_max thermal zone Add soc_max thermal zone as the downstream solution of virtual aggregated thermal zone. BUG=b:382001244 UPSTREAM-TASK=b:236331727 TEST=grep -r . /sys/class/thermal/thermal_zone*/type Change-Id: I7d1320f85c5e04efe281784029ca357ea6c85472 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6063468 Commit-Queue: Hsin-Te Yuan Reviewed-by: Pin-yen Lin Tested-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188.dtsi | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi index 078d39522db8b..15f83087dd581 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi @@ -485,6 +485,61 @@ }; thermal_zones: thermal-zones { + soc_max { + polling-delay = <1000>; /* milliseconds */ + polling-delay-passive = <100>; /* milliseconds */ + thermal-sensors = <&vtemp 0>; + sustainable-power = <1500>; + + trips { + soc_max_switch_on: trip-switch-on { + temperature = <68000>; + hysteresis = <2000>; + type = "passive"; + }; + + soc_max_alert0: trip-alert0 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + soc_max_alert1: trip-alert1 { + temperature = <95000>; + hysteresis = <2000>; + type = "hot"; + }; + + soc_max_crit: trip-crit { + temperature = <115000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&soc_max_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <2345>; + }; + + map1 { + trip = <&soc_max_alert0>; + cooling-device = + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + }; + }; + cpu-little0-thermal { polling-delay = <1000>; polling-delay-passive = <150>; -- GitLab From 185eff42abb8d87192040510a0b9dfefdc0d5f49 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Wed, 4 Dec 2024 09:28:48 +0000 Subject: [PATCH 047/456] CHROMIUM: dt-bindings: thermal: mediatek: Add vitrual temp definition Add virtual temp definition for Mediatek platform BUG=b:382001244 TEST=check soc_max get probed UPSTREAM-TASK=b:236331727 Change-Id: I8060e533e1e65395d6b54b7ae2d34ddc73874071 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6068609 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- .../thermal/mediatek,virtual-temp.yaml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,virtual-temp.yaml diff --git a/Documentation/devicetree/bindings/thermal/mediatek,virtual-temp.yaml b/Documentation/devicetree/bindings/thermal/mediatek,virtual-temp.yaml new file mode 100644 index 0000000000000..167015a55b188 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/mediatek,virtual-temp.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/mediatek.virtual-temp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Virtual Temperature sensor (vtemp) + +maintainers: + - Hsin-Te Yuan + +properties: + compatible: + const: mediatek,virtual-temp + + mediatek,tz-names: + description: The thermal zones to be aggregated + + "#thermal-sensor-cells": + const: 1 + +required: + - compatible + - mediatek,tz-names + - "#thermal-sensor-cells" + +additionalProperties: false + +examples: + - | + vtemp: vtemp { + compatible = "mediatek,virtual-temp"; + #thermal-sensor-cells = <1>; + mediatek,tz-names = "cpu-little0-thermal", + "cpu-little1-thermal", + "cpu-little2-thermal", + "cpu-little3-thermal", + "cpu-big0-thermal", + "cpu-big1-thermal", + "apu-thermal", + "gpu-thermal", + "gpu1-thermal", + "adsp-thermal", + "vdo-thermal", + "infra-thermal", + "cam1-thermal", + "cam2-thermal"; + }; -- GitLab From 20b02919485ddd89a69c69d96932a2ae565c2a88 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Wed, 4 Dec 2024 02:12:00 +0000 Subject: [PATCH 048/456] UPSTREAM: wifi: rtw89: coex: check NULL return of kmalloc in btc_fw_set_monreg() kmalloc may fail, return value might be NULL and will cause NULL pointer dereference. Add check NULL return of kmalloc in btc_fw_set_monreg(). Signed-off-by: Pei Xiao Fixes: b952cb0a6e2d ("wifi: rtw89: coex: Add register monitor report v7 format") Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/516a91f3997534f708af43c7592cbafdd53dd599.1730253508.git.xiaopei01@kylinos.cn (cherry picked from commit 81df5ed446b448bdc327b7c7f0b50121fc1f4aa2) BUG=b:356434907 TEST=verify suite:wifi_matfunc and suite:wifi_perf on nissa with 8852B. Signed-off-by: Linux Patches Robot Change-Id: I29be1aa371f1f1cc2248da7dbb0690eb18c1cdf4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6068396 Reviewed-by: Sean Paul Commit-Queue: Andrzej Ostruszka Reviewed-by: David Ruth Reviewed-by: Andrzej Ostruszka Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/coex.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 4280e3b6ae928..d636cdb60cff8 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -2499,6 +2499,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) if (ver->fcxmreg == 7) { sz = struct_size(v7, regs, n); v7 = kmalloc(sz, GFP_KERNEL); + if (!v7) + return; v7->type = RPT_EN_MREG; v7->fver = ver->fcxmreg; v7->len = n; @@ -2513,6 +2515,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) } else { sz = struct_size(v1, regs, n); v1 = kmalloc(sz, GFP_KERNEL); + if (!v1) + return; v1->fver = ver->fcxmreg; v1->reg_num = n; memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n)); -- GitLab From 59f63d162517d250911f27e01ca558b5b982e456 Mon Sep 17 00:00:00 2001 From: Nathan Hebert Date: Tue, 3 Dec 2024 23:57:43 +0000 Subject: [PATCH 049/456] Revert "FROMGIT: media: venus: factor out inst destruction routine" This reverts commit 965ec133e8b5bf3e71e50385f4eb709ced03f512. Reason for revert: Parent CL causes a V4L2 buffer leak during vdec_close(). https://crbug.com/379757114 Original change's description: > FROMGIT: media: venus: factor out inst destruction routine > > Factor out common instance destruction code into > a common function. > > Suggested-by: Bryan O'Donoghue > Signed-off-by: Sergey Senozhatsky > Reviewed-by: Bryan O'Donoghue > Signed-off-by: Stanimir Varbanov > Signed-off-by: Hans Verkuil > (cherry picked from commit 1b3bb4d69f20be5931abc18a6dbc24ff687fa780 > git://linuxtv.org/media.git next) > > BUG=b:340147762 > TEST=CTS on strongbad > > Change-Id: Idc509f8ad6bf0d0d779b291fbe665725cf7a8258 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6011189 > Reviewed-by: Ricardo Ribalda > Reviewed-by: Sean Paul > Tested-by: Sergey Senozhatsky > Commit-Queue: Sergey Senozhatsky BUG=b:340147762 BUG=b:379757114 TEST=tast video.ChromeStackDecoderPerf.vp8 stops leaking DMABuf's Change-Id: I2237db38a7bc1148df211787514a0abe9e1bb1ed Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6068666 Tested-by: Nathan Hebert Reviewed-by: Sergey Senozhatsky Commit-Queue: Nathan Hebert Reviewed-by: Fritz Koenig Signed-off-by: Hubert Mazur --- drivers/media/platform/qcom/venus/core.c | 25 ------------------- drivers/media/platform/qcom/venus/core.h | 2 -- drivers/media/platform/qcom/venus/vdec.c | 24 ++++++++++++++++-- drivers/media/platform/qcom/venus/vdec.h | 1 + .../media/platform/qcom/venus/vdec_ctrls.c | 5 ++++ drivers/media/platform/qcom/venus/venc.c | 24 ++++++++++++++++-- drivers/media/platform/qcom/venus/venc.h | 1 + .../media/platform/qcom/venus/venc_ctrls.c | 5 ++++ 8 files changed, 56 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index e7f9bf84606f3..41f722dee0421 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -501,30 +500,6 @@ err_cpucfg_path: return ret; } -void venus_close_common(struct venus_inst *inst) -{ - /* - * First, remove the inst from the ->instances list, so that - * to_instance() will return NULL. - */ - hfi_session_destroy(inst); - /* - * Second, make sure we don't have IRQ/IRQ-thread currently running - * or pending execution, which would race with the inst destruction. - */ - synchronize_irq(inst->core->irq); - - v4l2_m2m_ctx_release(inst->m2m_ctx); - v4l2_m2m_release(inst->m2m_dev); - v4l2_fh_del(&inst->fh); - v4l2_fh_exit(&inst->fh); - v4l2_ctrl_handler_free(&inst->ctrl_handler); - - mutex_destroy(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); -} -EXPORT_SYMBOL_GPL(venus_close_common); - static __maybe_unused int venus_runtime_resume(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 7a203cdd08058..3748a9a74dce6 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -569,6 +569,4 @@ is_fw_rev_or_older(struct venus_core *core, u32 vmajor, u32 vminor, u32 vrev) (core)->venus_ver.minor == vminor && (core)->venus_ver.rev <= vrev); } - -void venus_close_common(struct venus_inst *inst); #endif diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 9951218653fe0..d802ece8948fa 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1735,7 +1735,7 @@ err_m2m_release: err_session_destroy: hfi_session_destroy(inst); err_ctrl_deinit: - v4l2_ctrl_handler_free(&inst->ctrl_handler); + vdec_ctrl_deinit(inst); err_free: kfree(inst); return ret; @@ -1746,9 +1746,29 @@ static int vdec_close(struct file *file) struct venus_inst *inst = to_inst(file); vdec_pm_get(inst); + cancel_work_sync(&inst->delayed_process_work); - venus_close_common(inst); + /* + * First, remove the inst from the ->instances list, so that + * to_instance() will return NULL. + */ + hfi_session_destroy(inst); + /* + * Second, make sure we don't have IRQ/IRQ-thread currently running + * or pending execution, which would race with the inst destruction. + */ + synchronize_irq(inst->core->irq); + + v4l2_m2m_ctx_release(inst->m2m_ctx); + v4l2_m2m_release(inst->m2m_dev); ida_destroy(&inst->dpb_ids); + v4l2_fh_del(&inst->fh); + v4l2_fh_exit(&inst->fh); + vdec_ctrl_deinit(inst); + + mutex_destroy(&inst->lock); + mutex_destroy(&inst->ctx_q_lock); + vdec_pm_put(inst, false); kfree(inst); diff --git a/drivers/media/platform/qcom/venus/vdec.h b/drivers/media/platform/qcom/venus/vdec.h index 0cf981108ff08..6b262d0bf561b 100644 --- a/drivers/media/platform/qcom/venus/vdec.h +++ b/drivers/media/platform/qcom/venus/vdec.h @@ -9,5 +9,6 @@ struct venus_inst; int vdec_ctrl_init(struct venus_inst *inst); +void vdec_ctrl_deinit(struct venus_inst *inst); #endif diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c index 36ed955b04194..7e0f29bf7fae0 100644 --- a/drivers/media/platform/qcom/venus/vdec_ctrls.c +++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c @@ -187,3 +187,8 @@ int vdec_ctrl_init(struct venus_inst *inst) return 0; } + +void vdec_ctrl_deinit(struct venus_inst *inst) +{ + v4l2_ctrl_handler_free(&inst->ctrl_handler); +} diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 9424ddca86799..a72681de11790 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1526,7 +1526,7 @@ err_m2m_release: err_session_destroy: hfi_session_destroy(inst); err_ctrl_deinit: - v4l2_ctrl_handler_free(&inst->ctrl_handler); + venc_ctrl_deinit(inst); err_free: kfree(inst); return ret; @@ -1537,8 +1537,28 @@ static int venc_close(struct file *file) struct venus_inst *inst = to_inst(file); venc_pm_get(inst); - venus_close_common(inst); + + /* + * First, remove the inst from the ->instances list, so that + * to_instance() will return NULL. + */ + hfi_session_destroy(inst); + /* + * Second, make sure we don't have IRQ/IRQ-thread currently running + * or pending execution, which would race with the inst destruction. + */ + synchronize_irq(inst->core->irq); + + v4l2_m2m_ctx_release(inst->m2m_ctx); + v4l2_m2m_release(inst->m2m_dev); + v4l2_fh_del(&inst->fh); + v4l2_fh_exit(&inst->fh); + venc_ctrl_deinit(inst); + inst->enc_state = VENUS_ENC_STATE_DEINIT; + mutex_destroy(&inst->lock); + mutex_destroy(&inst->ctx_q_lock); + venc_pm_put(inst, false); kfree(inst); diff --git a/drivers/media/platform/qcom/venus/venc.h b/drivers/media/platform/qcom/venus/venc.h index 719d0f73b14b8..4ea37fdcd9b8f 100644 --- a/drivers/media/platform/qcom/venus/venc.h +++ b/drivers/media/platform/qcom/venus/venc.h @@ -9,5 +9,6 @@ struct venus_inst; int venc_ctrl_init(struct venus_inst *inst); +void venc_ctrl_deinit(struct venus_inst *inst); #endif diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c index 406aeedef81f3..4cad8058339a4 100644 --- a/drivers/media/platform/qcom/venus/venc_ctrls.c +++ b/drivers/media/platform/qcom/venus/venc_ctrls.c @@ -724,3 +724,8 @@ err: v4l2_ctrl_handler_free(&inst->ctrl_handler); return ret; } + +void venc_ctrl_deinit(struct venus_inst *inst) +{ + v4l2_ctrl_handler_free(&inst->ctrl_handler); +} -- GitLab From 56eb4c747fb6d87b78b210ff042400f3e4462ff4 Mon Sep 17 00:00:00 2001 From: Nathan Hebert Date: Tue, 3 Dec 2024 23:59:21 +0000 Subject: [PATCH 050/456] Revert "FROMGIT: media: venus: sync with threaded IRQ during inst destruction" This reverts commit bf1212549c2a9e38c361e4b5eadc1577c31d4a1b. Reason for revert: Causes a V4L2 buffer leak during vdec_close(). https://crbug.com/379757114 Original change's description: > FROMGIT: media: venus: sync with threaded IRQ during inst destruction > > When destroying an inst we should make sure that we don't race > against threaded IRQ (or pending IRQ), otherwise we can concurrently > kfree() inst context and inst itself. > > BUG: KASAN: slab-use-after-free in vb2_queue_error+0x80/0x90 > Call trace: > dump_backtrace+0x1c4/0x1f8 > show_stack+0x38/0x60 > dump_stack_lvl+0x168/0x1f0 > print_report+0x170/0x4c8 > kasan_report+0x94/0xd0 > __asan_report_load2_noabort+0x20/0x30 > vb2_queue_error+0x80/0x90 > venus_helper_vb2_queue_error+0x54/0x78 > venc_event_notify+0xec/0x158 > hfi_event_notify+0x878/0xd20 > hfi_process_msg_packet+0x27c/0x4e0 > venus_isr_thread+0x258/0x6e8 > hfi_isr_thread+0x70/0x90 > venus_isr_thread+0x34/0x50 > irq_thread_fn+0x88/0x130 > irq_thread+0x160/0x2c0 > kthread+0x294/0x328 > ret_from_fork+0x10/0x20 > > Allocated by task 20291: > kasan_set_track+0x4c/0x80 > kasan_save_alloc_info+0x28/0x38 > __kasan_kmalloc+0x84/0xa0 > kmalloc_trace+0x7c/0x98 > v4l2_m2m_ctx_init+0x74/0x280 > venc_open+0x444/0x6d0 > v4l2_open+0x19c/0x2a0 > chrdev_open+0x374/0x3f0 > do_dentry_open+0x710/0x10a8 > vfs_open+0x88/0xa8 > path_openat+0x1e6c/0x2700 > do_filp_open+0x1a4/0x2e0 > do_sys_openat2+0xe8/0x508 > do_sys_open+0x15c/0x1a0 > __arm64_sys_openat+0xa8/0xc8 > invoke_syscall+0xdc/0x270 > el0_svc_common+0x1ec/0x250 > do_el0_svc+0x54/0x70 > el0_svc+0x50/0xe8 > el0t_64_sync_handler+0x48/0x120 > el0t_64_sync+0x1a8/0x1b0 > > Freed by task 20291: > kasan_set_track+0x4c/0x80 > kasan_save_free_info+0x3c/0x60 > ____kasan_slab_free+0x124/0x1a0 > __kasan_slab_free+0x18/0x28 > __kmem_cache_free+0x134/0x300 > kfree+0xc8/0x1a8 > v4l2_m2m_ctx_release+0x44/0x60 > venc_close+0x78/0x130 [venus_enc] > v4l2_release+0x20c/0x2f8 > __fput+0x328/0x7f0 > ____fput+0x2c/0x48 > task_work_run+0x1e0/0x280 > get_signal+0xfb8/0x1190 > do_notify_resume+0x34c/0x16a8 > el0_svc+0x9c/0xe8 > el0t_64_sync_handler+0x48/0x120 > el0t_64_sync+0x1a8/0x1b0 > > Rearrange inst destruction. First remove the inst from the > core->instances list, second synchronize IRQ/IRQ-thread to > make sure that nothing else would see the inst while we take > it down. > > Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files") > Signed-off-by: Sergey Senozhatsky > Reviewed-by: Bryan O'Donoghue > Signed-off-by: Stanimir Varbanov > Signed-off-by: Hans Verkuil > (cherry picked from commit 45b1a1b348ec178a599323f1ce7d7932aea8c6d4 > git://linuxtv.org/media.git next) > > BUG=b:340147762 > TEST=CTS on strongbad > > Change-Id: If939f6ff95525b95c2246f810cd90a71d608b87d > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6011188 > Reviewed-by: Ricardo Ribalda > Commit-Queue: Sergey Senozhatsky > Reviewed-by: Sean Paul > Tested-by: Sergey Senozhatsky Bug: KASAN: slab-use-after-free in vb2_queue_error+0x80/0x90 BUG=b:340147762 BUG=b:379757114 TEST=tast video.ChromeStackDecoderPerf.vp8 stops leaking DMABuf's Change-Id: I5affcd109bcf42c974e28f89d5f4eb79a368b623 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6068667 Reviewed-by: Fritz Koenig Commit-Queue: Nathan Hebert Tested-by: Nathan Hebert Reviewed-by: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/media/platform/qcom/venus/vdec.c | 12 +----------- drivers/media/platform/qcom/venus/venc.c | 12 +----------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index d802ece8948fa..00aadf5907da4 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1748,20 +1748,10 @@ static int vdec_close(struct file *file) vdec_pm_get(inst); cancel_work_sync(&inst->delayed_process_work); - /* - * First, remove the inst from the ->instances list, so that - * to_instance() will return NULL. - */ - hfi_session_destroy(inst); - /* - * Second, make sure we don't have IRQ/IRQ-thread currently running - * or pending execution, which would race with the inst destruction. - */ - synchronize_irq(inst->core->irq); - v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); ida_destroy(&inst->dpb_ids); + hfi_session_destroy(inst); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); vdec_ctrl_deinit(inst); diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index a72681de11790..d8f4700879a3e 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1538,19 +1538,9 @@ static int venc_close(struct file *file) venc_pm_get(inst); - /* - * First, remove the inst from the ->instances list, so that - * to_instance() will return NULL. - */ - hfi_session_destroy(inst); - /* - * Second, make sure we don't have IRQ/IRQ-thread currently running - * or pending execution, which would race with the inst destruction. - */ - synchronize_irq(inst->core->irq); - v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); + hfi_session_destroy(inst); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); venc_ctrl_deinit(inst); -- GitLab From 5dbce83547de75a112c01d8e3a3d5c318bb16254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 27 Nov 2024 08:11:14 +0200 Subject: [PATCH 051/456] FROMGIT: drm/i915: Don't reuse commit_work for the cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we reuse the commit_work for a later cleanup step. Let's not do that so that atomic ioctl handler won't accidentally wait for the cleanup work when it really wants to just wait on the commit_tail() part. We'll just add another work struct for the cleanup. BUG=b:341810357 TEST=S0ix with DPT enabled Cc: Brian Geffon Cc: Vidya Srinivas Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241127061117.25622-2-ville.syrjala@linux.intel.com (cherry picked from commit 0768530b7c5bedd9b967c87e2f85ab982ae29b9b https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) Reviewed-by: Vidya Srinivas Tested-by: Vidya Srinivas Change-Id: I8160c96b7e1cfe7db374e76e477c8be3f55020ec Signed-off-by: Vidya Srinivas Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051628 Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_display.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3b135f60a6432..03a61d0e966bb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7159,7 +7159,7 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat static void intel_atomic_cleanup_work(struct work_struct *work) { struct intel_atomic_state *state = - container_of(work, struct intel_atomic_state, base.commit_work); + container_of(work, struct intel_atomic_state, cleanup_work); struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc; @@ -7433,8 +7433,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * schedule point (cond_resched()) here anyway to keep latencies * down. */ - INIT_WORK(&state->base.commit_work, intel_atomic_cleanup_work); - queue_work(system_highpri_wq, &state->base.commit_work); + INIT_WORK(&state->cleanup_work, intel_atomic_cleanup_work); + queue_work(system_highpri_wq, &state->cleanup_work); } static void intel_atomic_commit_work(struct work_struct *work) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 5b45e7cbfdc46..ca6ba73d995de 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -703,6 +703,8 @@ struct intel_atomic_state { struct i915_sw_fence commit_ready; struct llist_node freed; + + struct work_struct cleanup_work; }; struct intel_plane_state { -- GitLab From b63ecf27b86912951df0f1f3b0c60c3ca02e9378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 27 Nov 2024 08:11:15 +0200 Subject: [PATCH 052/456] FROMGIT: drm/i915: Intruduce display.wq.cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a dedicated workqueue for the commit cleanup work. In the future we'll need this to guarantee all the cleanup works have finished at a specific point during suspend. BUG=b:341810357 TEST=S0ix with DPT enabled Cc: Brian Geffon Cc: Vidya Srinivas Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241127061117.25622-3-ville.syrjala@linux.intel.com (cherry picked from commit 37ab41e11f359fa66934f7e25bba2e4360f6ccec https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) Reviewed-by: Vidya Srinivas Tested-by: Vidya Srinivas Change-Id: Ib2021ebe9667ad6bb02077b7750909b1f3854074 Signed-off-by: Vidya Srinivas Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051629 Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_display_core.h | 3 +++ drivers/gpu/drm/i915/display/intel_display_driver.c | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 03a61d0e966bb..5b4e464527708 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7434,7 +7434,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * down. */ INIT_WORK(&state->cleanup_work, intel_atomic_cleanup_work); - queue_work(system_highpri_wq, &state->cleanup_work); + queue_work(dev_priv->display.wq.cleanup, &state->cleanup_work); } static void intel_atomic_commit_work(struct work_struct *work) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 3da971859d513..41273053570f5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -523,6 +523,9 @@ struct intel_display { /* unbound hipri wq for page flips/plane updates */ struct workqueue_struct *flip; + + /* hipri wq for commit cleanups */ + struct workqueue_struct *cleanup; } wq; /* Grouping using named structs. Keep sorted. */ diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index d6bff9e1ca4ae..548393d52c5e6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -228,6 +228,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); + i915->display.wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0); intel_mode_config_init(i915); @@ -558,6 +559,7 @@ void intel_display_driver_remove(struct drm_i915_private *i915) flush_workqueue(i915->display.wq.flip); flush_workqueue(i915->display.wq.modeset); + flush_workqueue(i915->display.wq.cleanup); flush_work(&i915->display.atomic_helper.free_work); drm_WARN_ON(&i915->drm, !llist_empty(&i915->display.atomic_helper.free_list)); @@ -601,6 +603,7 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915) destroy_workqueue(i915->display.wq.flip); destroy_workqueue(i915->display.wq.modeset); + destroy_workqueue(i915->display.wq.cleanup); intel_fbc_cleanup(i915); } -- GitLab From 715de573fedb90f8c201292f3ead4e406e787122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 27 Nov 2024 08:11:16 +0200 Subject: [PATCH 053/456] FROMGIT: drm/i915/dpt: Evict all DPT VMAs on suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently intel_dpt_resume() tries to blindly rewrite all the PTEs for currently bound DPT VMAs. That is problematic because the CPU mapping for the DPT is only really guaranteed to exist while the DPT object has been pinned. In the past we worked around this issue by making DPT objects unshrinkable, but that is undesirable as it'll waste physical RAM. Let's instead forcefully evict all the DPT VMAs on suspend, thus guaranteeing that intel_dpt_resume() has nothing to do. To guarantee that all the DPT VMAs are evictable by intel_dpt_suspend() we need to flush the cleanup workqueue after the display output has been shut down. And for good measure throw in a few extra WARNs to catch any mistakes. BUG=b:341810357 TEST=S0ix with DPT enabled Cc: Brian Geffon Cc: Vidya Srinivas Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241127061117.25622-4-ville.syrjala@linux.intel.com (cherry picked from commit 106216c220a2c7f275110e72e97527961ee33704 https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) Reviewed-by: Vidya Srinivas Tested-by: Vidya Srinivas Change-Id: I46fb025e196369d0da84c074e0f6b2d3054449d1 Signed-off-by: Vidya Srinivas Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051630 Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- .../drm/i915/display/intel_display_driver.c | 3 +++ drivers/gpu/drm/i915/display/intel_dpt.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_ggtt.c | 19 ++++++++++++++----- drivers/gpu/drm/i915/gt/intel_gtt.h | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 548393d52c5e6..f166a78d99b71 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -663,6 +663,9 @@ int intel_display_driver_suspend(struct drm_i915_private *i915) ret); else i915->display.restore.modeset_state = state; + /* ensure all DPT VMAs have been unpinned for intel_dpt_suspend() */ + flush_workqueue(i915->display.wq.cleanup); + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index a4d20d8df360b..51e4e1e691b67 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -207,7 +207,7 @@ void intel_dpt_resume(struct drm_i915_private *i915) struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); if (fb->dpt_vm) - i915_ggtt_resume_vm(fb->dpt_vm); + i915_ggtt_resume_vm(fb->dpt_vm, true); } mutex_unlock(&i915->drm.mode_config.fb_lock); } @@ -235,7 +235,7 @@ void intel_dpt_suspend(struct drm_i915_private *i915) struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); if (fb->dpt_vm) - i915_ggtt_suspend_vm(fb->dpt_vm); + i915_ggtt_suspend_vm(fb->dpt_vm, true); } mutex_unlock(&i915->drm.mode_config.fb_lock); diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index d281828e33bac..9aafce22f14eb 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -108,11 +108,12 @@ int i915_ggtt_init_hw(struct drm_i915_private *i915) /** * i915_ggtt_suspend_vm - Suspend the memory mappings for a GGTT or DPT VM * @vm: The VM to suspend the mappings for + * @evict_all: Evict all VMAs * * Suspend the memory mappings for all objects mapped to HW via the GGTT or a * DPT page table. */ -void i915_ggtt_suspend_vm(struct i915_address_space *vm) +void i915_ggtt_suspend_vm(struct i915_address_space *vm, bool evict_all) { struct i915_vma *vma, *vn; int save_skip_rewrite; @@ -158,7 +159,7 @@ retry: goto retry; } - if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) { + if (evict_all || !i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) { i915_vma_wait_for_bind(vma); __i915_vma_evict(vma, false); @@ -173,13 +174,15 @@ retry: vm->skip_pte_rewrite = save_skip_rewrite; mutex_unlock(&vm->mutex); + + drm_WARN_ON(&vm->i915->drm, evict_all && !list_empty(&vm->bound_list)); } void i915_ggtt_suspend(struct i915_ggtt *ggtt) { struct intel_gt *gt; - i915_ggtt_suspend_vm(&ggtt->vm); + i915_ggtt_suspend_vm(&ggtt->vm, false); ggtt->invalidate(ggtt); list_for_each_entry(gt, &ggtt->gt_list, ggtt_link) @@ -1548,6 +1551,7 @@ int i915_ggtt_enable_hw(struct drm_i915_private *i915) /** * i915_ggtt_resume_vm - Restore the memory mappings for a GGTT or DPT VM * @vm: The VM to restore the mappings for + * @all_evicted: Were all VMAs expected to be evicted on suspend? * * Restore the memory mappings for all objects mapped to HW via the GGTT or a * DPT page table. @@ -1555,13 +1559,18 @@ int i915_ggtt_enable_hw(struct drm_i915_private *i915) * Returns %true if restoring the mapping for any object that was in a write * domain before suspend. */ -bool i915_ggtt_resume_vm(struct i915_address_space *vm) +bool i915_ggtt_resume_vm(struct i915_address_space *vm, bool all_evicted) { struct i915_vma *vma; bool write_domain_objs = false; drm_WARN_ON(&vm->i915->drm, !vm->is_ggtt && !vm->is_dpt); + if (all_evicted) { + drm_WARN_ON(&vm->i915->drm, !list_empty(&vm->bound_list)); + return false; + } + /* First fill our portion of the GTT with scratch pages */ vm->clear_range(vm, 0, vm->total); @@ -1601,7 +1610,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt) list_for_each_entry(gt, &ggtt->gt_list, ggtt_link) intel_gt_check_and_clear_faults(gt); - flush = i915_ggtt_resume_vm(&ggtt->vm); + flush = i915_ggtt_resume_vm(&ggtt->vm, false); if (drm_mm_node_allocated(&ggtt->error_capture)) ggtt->vm.scratch_range(&ggtt->vm, ggtt->error_capture.start, diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h index 4734ef4b0be58..0222d789b4d18 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.h +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h @@ -607,8 +607,8 @@ int i915_ppgtt_init_hw(struct intel_gt *gt); struct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt, unsigned long lmem_pt_obj_flags); -void i915_ggtt_suspend_vm(struct i915_address_space *vm); -bool i915_ggtt_resume_vm(struct i915_address_space *vm); +void i915_ggtt_suspend_vm(struct i915_address_space *vm, bool evict_all); +bool i915_ggtt_resume_vm(struct i915_address_space *vm, bool all_evicted); void i915_ggtt_suspend(struct i915_ggtt *gtt); void i915_ggtt_resume(struct i915_ggtt *ggtt); -- GitLab From 76d30bb0f7835794f92745abaffe8a98b38d8062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 27 Nov 2024 08:11:17 +0200 Subject: [PATCH 054/456] FROMGIT: Revert "drm/i915/dpt: Make DPT object unshrinkable" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 51064d471c53dcc8eddd2333c3f1c1d9131ba36c. Now that we forcefully evict all DPT VMAs during suspend there should be no problem allowing the shrinker to eat the DPT objects. BUG=b:341810357 TEST=S0ix with DPT enabled Cc: Brian Geffon Cc: Vidya Srinivas Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12965 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241127061117.25622-5-ville.syrjala@linux.intel.com (cherry picked from commit 24387a21dc8d3d7be9ce7a99dba4d4477456caab https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) Acked-by: Brian Geffon Reviewed-by: Vidya Srinivas Tested-by: Vidya Srinivas Change-Id: I78269b918d9b0e391d9a8fb22b0f9c72bbf63c88 Signed-off-by: Vidya Srinivas Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6051631 Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 5d7446a48ae79..3560a062d2872 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -284,9 +284,7 @@ bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj); static inline bool i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj) { - /* TODO: make DPT shrinkable when it has no bound vmas */ - return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE) && - !obj->is_dpt; + return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE); } static inline bool -- GitLab From 719d0515924b255e846376cedc480a33c1e05514 Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Fri, 26 Jan 2024 09:57:19 +0000 Subject: [PATCH 055/456] UPSTREAM: platform/chrome: Update binary interface for EC-based watchdog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update structures and defines related to EC_CMD_HANG_DETECT to allow usage of new EC-based watchdog. Signed-off-by: Lukasz Majczak Reviewed-by: Guenter Roeck Acked-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20240126095721.782782-2-lma@chromium.org Signed-off-by: Lee Jones (cherry picked from commit 4d2ff655fb85a0bf1ecec6022ffdacb2a5f83fd2) BUG=b:381226345 TEST=Build and boot Akali360 Change-Id: I2afeb7216612a9a4748871da1e4ab8742b1200af Signed-off-by: Jędrzej Ciupis Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6058341 Reviewed-by: Sean Paul Reviewed-by: Kornel Dulęba Reviewed-by: Marek Maślanka Signed-off-by: Hubert Mazur --- .../linux/platform_data/cros_ec_commands.h | 78 +++++++++---------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 35c5de6568716..fff191a8d413e 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4059,60 +4059,52 @@ struct ec_response_i2c_passthru { } __ec_align1; /*****************************************************************************/ -/* Power button hang detect */ - +/* AP hang detect */ #define EC_CMD_HANG_DETECT 0x009F -/* Reasons to start hang detection timer */ -/* Power button pressed */ -#define EC_HANG_START_ON_POWER_PRESS BIT(0) - -/* Lid closed */ -#define EC_HANG_START_ON_LID_CLOSE BIT(1) - - /* Lid opened */ -#define EC_HANG_START_ON_LID_OPEN BIT(2) - -/* Start of AP S3->S0 transition (booting or resuming from suspend) */ -#define EC_HANG_START_ON_RESUME BIT(3) - -/* Reasons to cancel hang detection */ +#define EC_HANG_DETECT_MIN_TIMEOUT 5 +#define EC_HANG_DETECT_MAX_TIMEOUT 65535 -/* Power button released */ -#define EC_HANG_STOP_ON_POWER_RELEASE BIT(8) +/* EC hang detect commands */ +enum ec_hang_detect_cmds { + /* Reload AP hang detect timer. */ + EC_HANG_DETECT_CMD_RELOAD = 0x0, -/* Any host command from AP received */ -#define EC_HANG_STOP_ON_HOST_COMMAND BIT(9) + /* Stop AP hang detect timer. */ + EC_HANG_DETECT_CMD_CANCEL = 0x1, -/* Stop on end of AP S0->S3 transition (suspending or shutting down) */ -#define EC_HANG_STOP_ON_SUSPEND BIT(10) + /* Configure watchdog with given reboot timeout and + * cancel currently running AP hang detect timer. + */ + EC_HANG_DETECT_CMD_SET_TIMEOUT = 0x2, -/* - * If this flag is set, all the other fields are ignored, and the hang detect - * timer is started. This provides the AP a way to start the hang timer - * without reconfiguring any of the other hang detect settings. Note that - * you must previously have configured the timeouts. - */ -#define EC_HANG_START_NOW BIT(30) + /* Get last hang status - whether the AP boot was clear or not */ + EC_HANG_DETECT_CMD_GET_STATUS = 0x3, -/* - * If this flag is set, all the other fields are ignored (including - * EC_HANG_START_NOW). This provides the AP a way to stop the hang timer - * without reconfiguring any of the other hang detect settings. - */ -#define EC_HANG_STOP_NOW BIT(31) + /* Clear last hang status. Called when AP is rebooting/shutting down + * gracefully. + */ + EC_HANG_DETECT_CMD_CLEAR_STATUS = 0x4 +}; struct ec_params_hang_detect { - /* Flags; see EC_HANG_* */ - uint32_t flags; - - /* Timeout in msec before generating host event, if enabled */ - uint16_t host_event_timeout_msec; + uint16_t command; /* enum ec_hang_detect_cmds */ + /* Timeout in seconds before generating reboot */ + uint16_t reboot_timeout_sec; +} __ec_align2; - /* Timeout in msec before generating warm reboot, if enabled */ - uint16_t warm_reboot_timeout_msec; -} __ec_align4; +/* Status codes that describe whether AP has boot normally or the hang has been + * detected and EC has reset AP + */ +enum ec_hang_detect_status { + EC_HANG_DETECT_AP_BOOT_NORMAL = 0x0, + EC_HANG_DETECT_AP_BOOT_EC_WDT = 0x1, + EC_HANG_DETECT_AP_BOOT_COUNT, +}; +struct ec_response_hang_detect { + uint8_t status; /* enum ec_hang_detect_status */ +} __ec_align1; /*****************************************************************************/ /* Commands for battery charging */ -- GitLab From c7cfbf229ce01cb9b809aeb2730ebd50f2633654 Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Fri, 26 Jan 2024 09:57:20 +0000 Subject: [PATCH 056/456] UPSTREAM: watchdog: Add ChromeOS EC-based watchdog driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embedded Controller (EC) present on Chromebook devices can be used as a watchdog. Implement a driver to support it. Signed-off-by: Lukasz Majczak Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240126095721.782782-3-lma@chromium.org Signed-off-by: Lee Jones (cherry picked from commit 843dac4d3687f7628ba4f76e1481ee3838b27a35) BUG=b:381226345 TEST=Build and boot Akali360 Change-Id: I248bf44f58985ee572f50389cdf72441d02c598f Signed-off-by: Jędrzej Ciupis Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6058342 Reviewed-by: Kornel Dulęba Reviewed-by: Sean Paul Reviewed-by: Marek Maślanka Signed-off-by: Hubert Mazur --- MAINTAINERS | 6 + drivers/watchdog/Kconfig | 11 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/cros_ec_wdt.c | 204 +++++++++++++++++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 drivers/watchdog/cros_ec_wdt.c diff --git a/MAINTAINERS b/MAINTAINERS index da3a8b6b15179..1995d1607dc1f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4932,6 +4932,12 @@ R: Sami Kyöstilä S: Maintained F: drivers/platform/chrome/cros_hps_i2c.c +CHROMEOS EC WATCHDOG +M: Lukasz Majczak +L: chrome-platform@lists.linux.dev +S: Maintained +F: drivers/watchdog/cros_ec_wdt.c + CHRONTEL CH7322 CEC DRIVER M: Joe Tessler L: linux-media@vger.kernel.org diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 751458959411c..38a243410002a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -181,6 +181,17 @@ config BD957XMUF_WATCHDOG watchdog. Alternatively say M to compile the driver as a module, which will be called bd9576_wdt. +config CROS_EC_WATCHDOG + tristate "ChromeOS EC-based watchdog" + select WATCHDOG_CORE + depends on CROS_EC + help + Watchdog driver for Chromebook devices equipped with embedded controller. + Trigger event is recorded in EC and checked on the subsequent boot. + + To compile this driver as a module, choose M here: the + module will be called cros_ec_wdt. + config DA9052_WATCHDOG tristate "Dialog DA9052 Watchdog" depends on PMIC_DA9052 || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 7eab9de311cb9..6fb2d57505523 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -218,6 +218,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o # Architecture Independent obj-$(CONFIG_BD957XMUF_WATCHDOG) += bd9576_wdt.o +obj-$(CONFIG_CROS_EC_WATCHDOG) += cros_ec_wdt.o obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o diff --git a/drivers/watchdog/cros_ec_wdt.c b/drivers/watchdog/cros_ec_wdt.c new file mode 100644 index 0000000000000..ba045e29f9a5e --- /dev/null +++ b/drivers/watchdog/cros_ec_wdt.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Google LLC. + * Author: Lukasz Majczak + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CROS_EC_WATCHDOG_DEFAULT_TIME 30 /* seconds */ +#define DRV_NAME "cros-ec-wdt" + +union cros_ec_wdt_data { + struct ec_params_hang_detect req; + struct ec_response_hang_detect resp; +} __packed; + +static int cros_ec_wdt_send_cmd(struct cros_ec_device *cros_ec, + union cros_ec_wdt_data *arg) +{ + int ret; + struct { + struct cros_ec_command msg; + union cros_ec_wdt_data data; + } __packed buf = { + .msg = { + .version = 0, + .command = EC_CMD_HANG_DETECT, + .insize = (arg->req.command == EC_HANG_DETECT_CMD_GET_STATUS) ? + sizeof(struct ec_response_hang_detect) : + 0, + .outsize = sizeof(struct ec_params_hang_detect), + }, + .data.req = arg->req + }; + + ret = cros_ec_cmd_xfer_status(cros_ec, &buf.msg); + if (ret < 0) + return ret; + + arg->resp = buf.data.resp; + + return 0; +} + +static int cros_ec_wdt_ping(struct watchdog_device *wdd) +{ + struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd); + union cros_ec_wdt_data arg; + int ret; + + arg.req.command = EC_HANG_DETECT_CMD_RELOAD; + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); + if (ret < 0) + dev_dbg(wdd->parent, "Failed to ping watchdog (%d)", ret); + + return ret; +} + +static int cros_ec_wdt_start(struct watchdog_device *wdd) +{ + struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd); + union cros_ec_wdt_data arg; + int ret; + + /* Prepare watchdog on EC side */ + arg.req.command = EC_HANG_DETECT_CMD_SET_TIMEOUT; + arg.req.reboot_timeout_sec = wdd->timeout; + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); + if (ret < 0) + dev_dbg(wdd->parent, "Failed to start watchdog (%d)", ret); + + return ret; +} + +static int cros_ec_wdt_stop(struct watchdog_device *wdd) +{ + struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd); + union cros_ec_wdt_data arg; + int ret; + + arg.req.command = EC_HANG_DETECT_CMD_CANCEL; + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); + if (ret < 0) + dev_dbg(wdd->parent, "Failed to stop watchdog (%d)", ret); + + return ret; +} + +static int cros_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) +{ + unsigned int old_timeout = wdd->timeout; + int ret; + + wdd->timeout = t; + ret = cros_ec_wdt_start(wdd); + if (ret < 0) + wdd->timeout = old_timeout; + + return ret; +} + +static const struct watchdog_info cros_ec_wdt_ident = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = DRV_NAME, +}; + +static const struct watchdog_ops cros_ec_wdt_ops = { + .owner = THIS_MODULE, + .ping = cros_ec_wdt_ping, + .start = cros_ec_wdt_start, + .stop = cros_ec_wdt_stop, + .set_timeout = cros_ec_wdt_set_timeout, +}; + +static int cros_ec_wdt_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); + struct cros_ec_device *cros_ec = ec_dev->ec_dev; + struct watchdog_device *wdd; + union cros_ec_wdt_data arg; + int ret = 0; + + wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL); + if (!wdd) + return -ENOMEM; + + arg.req.command = EC_HANG_DETECT_CMD_GET_STATUS; + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get watchdog bootstatus"); + + wdd->parent = &pdev->dev; + wdd->info = &cros_ec_wdt_ident; + wdd->ops = &cros_ec_wdt_ops; + wdd->timeout = CROS_EC_WATCHDOG_DEFAULT_TIME; + wdd->min_timeout = EC_HANG_DETECT_MIN_TIMEOUT; + wdd->max_timeout = EC_HANG_DETECT_MAX_TIMEOUT; + if (arg.resp.status == EC_HANG_DETECT_AP_BOOT_EC_WDT) + wdd->bootstatus = WDIOF_CARDRESET; + + arg.req.command = EC_HANG_DETECT_CMD_CLEAR_STATUS; + ret = cros_ec_wdt_send_cmd(cros_ec, &arg); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to clear watchdog bootstatus"); + + watchdog_stop_on_reboot(wdd); + watchdog_stop_on_unregister(wdd); + watchdog_set_drvdata(wdd, cros_ec); + platform_set_drvdata(pdev, wdd); + + return devm_watchdog_register_device(dev, wdd); +} + +static int __maybe_unused cros_ec_wdt_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + int ret = 0; + + if (watchdog_active(wdd)) + ret = cros_ec_wdt_stop(wdd); + + return ret; +} + +static int __maybe_unused cros_ec_wdt_resume(struct platform_device *pdev) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + int ret = 0; + + if (watchdog_active(wdd)) + ret = cros_ec_wdt_start(wdd); + + return ret; +} + +static const struct platform_device_id cros_ec_wdt_id[] = { + { DRV_NAME, 0 }, + {} +}; + +static struct platform_driver cros_ec_wdt_driver = { + .probe = cros_ec_wdt_probe, + .suspend = pm_ptr(cros_ec_wdt_suspend), + .resume = pm_ptr(cros_ec_wdt_resume), + .driver = { + .name = DRV_NAME, + }, + .id_table = cros_ec_wdt_id, +}; + +module_platform_driver(cros_ec_wdt_driver); + +MODULE_DEVICE_TABLE(platform, cros_ec_wdt_id); +MODULE_DESCRIPTION("Cros EC Watchdog Device Driver"); +MODULE_LICENSE("GPL"); -- GitLab From 7be0cc44e32e7db4bcbc30648862a6ac97de222e Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Fri, 19 Jan 2024 08:43:27 +0000 Subject: [PATCH 057/456] BACKPORT: mfd: cros_ec: Register EC-based watchdog subdevice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ChromeOS EC-based watchdog as EC subdevice. Signed-off-by: Lukasz Majczak Link: https://lore.kernel.org/r/20240119084328.3135503-4-lma@chromium.org Signed-off-by: Lee Jones (cherry picked from commit 6cea614ba78d6b78e64e39f5ccdfad4aac1d0110) BUG=b:381226345 TEST=Build and boot Akali360 Change-Id: I1ea17552e352a87e28fd48c9d03dd2ccec86b1e6 Signed-off-by: Jędrzej Ciupis Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6058343 Reviewed-by: Marek Maślanka Reviewed-by: Kornel Dulęba Signed-off-by: Hubert Mazur --- drivers/mfd/cros_ec_dev.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index e7f0aa4052b6e..91d84f7279b04 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -99,6 +99,10 @@ static const struct mfd_cell cros_ec_ucsi_cells[] = { { .name = "cros_ec_ucsi", }, }; +static const struct mfd_cell cros_ec_wdt_cells[] = { + { .name = "cros-ec-wdt", } +}; + static const struct cros_feature_to_cells cros_subdevices[] = { { .id = EC_FEATURE_CEC, @@ -120,6 +124,11 @@ static const struct cros_feature_to_cells cros_subdevices[] = { .mfd_cells = cros_ec_ucsi_cells, .num_cells = ARRAY_SIZE(cros_ec_ucsi_cells), }, + { + .id = EC_FEATURE_HANG_DETECT, + .mfd_cells = cros_ec_wdt_cells, + .num_cells = ARRAY_SIZE(cros_ec_wdt_cells), + }, }; static const struct mfd_cell cros_ec_platform_cells[] = { -- GitLab From 4cc9c43be490919745e04db210c760949a1e8aa0 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 5 Dec 2024 11:07:16 -0800 Subject: [PATCH 058/456] CHROMIUM: Increase DPM watchdog timeout to 15 seconds In we changfed the DPM watchdog from 60 seconds to 10. This is causing problems. Change it to 15 seconds. Some background here: * On most recent systems the EC has a sleep hang detector. When the AP starts going to suspend it tells the EC about it's plan. The EC then monitors a GPIO that is supposed to assert when the AP successfully gets into a low power mode. If the EC doesn't see this GPIO assert after 10 seconds then it's a "sleep hang". When the EC sees this sleep hang it asserts a wakeup signal to the AP. The userspace power manager in ChromeOS knows about this case and will try to suspend again. If userspace sees too many failed suspends in a row it will try to shut the system down. * On newer ECs the sleep hang detector has apparently been improved to have a "hard sleep hang dector". After the EC wakes the AP for a soft sleep hang then it expects the AP to tell it that it's awake. If the EC never sees it then it's a hard sleep hang and the EC will try to reboot. See https://crrev.com/c/4749162 * On even newer ECs, there's even more complex logic. See https://crrev.com/c/5369987 In general, panicking the AP is pretty disruptive and should be a last resort. Better than doing a panic() is to try first to abort the suspend / wake the system back up so that it can try to suspend again. There's a reasonable chance that retrying the suspend will work. If it doesn't there is already logic in userspace to eventually give up and shut the system down. Eventually, it seems like it would be a good idea to make the DPM watchdog try to abort the suspend / wake the system up instead of jumping straight to a panic(). While considering that, let's at least set the timeout to 15 seconds. It has been found that there are several timeouts in the kernel tuned at around 10 seconds. In at least one case after the timeout expired then the system would have gone to suspend. In another case it's believed that the system would have woken up and then a future suspend might have worked. Because of the short DPM timeout both were now causing kernel panic(). While both cases were bugs that should be addressed, doing a panic was worse for the end user. BUG=b:382269699 TEST=suspend/resume Change-Id: If1f778730dd167830c0698d2d2fdbefc61a7c633 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6075338 Reviewed-by: Boris Mittelberg Reviewed-by: Lalith Rajendran Signed-off-by: Hubert Mazur --- chromeos/config/chromeos/arm64/common.config | 2 +- chromeos/config/chromeos/armel/common.config | 2 +- .../chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config | 2 +- .../chromeos/x86_64/chromeos-intel-denverton.flavour.config | 2 +- .../chromeos/x86_64/chromeos-intel-pineview.flavour.config | 2 +- .../chromeos/x86_64/chromiumos-x86_64-generic.flavour.config | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/chromeos/config/chromeos/arm64/common.config b/chromeos/config/chromeos/arm64/common.config index 6076cdb0177b7..23d54554a62cd 100644 --- a/chromeos/config/chromeos/arm64/common.config +++ b/chromeos/config/chromeos/arm64/common.config @@ -46,7 +46,7 @@ CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_PANEL_EDP=y CONFIG_ENERGY_MODEL=y diff --git a/chromeos/config/chromeos/armel/common.config b/chromeos/config/chromeos/armel/common.config index 74c6f7328bab5..163b786868673 100644 --- a/chromeos/config/chromeos/armel/common.config +++ b/chromeos/config/chromeos/armel/common.config @@ -49,7 +49,7 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DEVFREQ_THERMAL=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 CONFIG_DRM_DW_HDMI_AHB_AUDIO=y CONFIG_DRM_DW_HDMI_I2S_AUDIO=y # CONFIG_DRM_FBDEV_EMULATION is not set diff --git a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config index 60257497a9313..db1fa2ac1ce77 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config @@ -37,7 +37,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_DEBUG_GPIO=y CONFIG_DMA_CMA=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 CONFIG_DRM_AMDGPU=y CONFIG_DRM_AMDGPU_SI=y CONFIG_DRM_AMD_ACP=y diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config index e7b3202f81aa4..65943db87e3c9 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config @@ -15,7 +15,7 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y # CONFIG_CPU_SUP_AMD is not set CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_I915=y CONFIG_DW_DMAC=m diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config index 6836b7f3bdbf0..6743af243b660 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config @@ -21,7 +21,7 @@ CONFIG_CROS_EC_ISHTP=m CONFIG_DEBUG_GPIO=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 CONFIG_DPTF_PCH_FIVR=y # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_I915=y diff --git a/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config b/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config index 7eae69bdf9f1c..27f273473f2b5 100644 --- a/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config @@ -18,7 +18,7 @@ CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_DEBUG_GPIO=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=10 +CONFIG_DPM_WATCHDOG_TIMEOUT=15 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_GMA500=y # CONFIG_DRM_I2C_CH7006 is not set -- GitLab From 8477a7b42d8dc34482e4856657b4fb69fc85e2f4 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Mon, 25 Nov 2024 06:33:27 +0000 Subject: [PATCH 059/456] Revert "FROMLIST: zram: clear IDLE flag after recompression" This reverts commit e45247052ff183bf24d4f69b56e25bec73a102d5. Reason for revert: will land UPSTREAM commit. BUG=b:376045274, b:375972987 TEST=none Change-Id: I395df6f4cf50a019f101dd80315cceaaec0fe472 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047502 Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 20460e21a3a75..9c8f274a28dfb 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1725,13 +1725,6 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page, if (ret) return ret; - /* - * We touched this entry so mark it as non-IDLE. This makes sure that - * we don't preserve IDLE flag and don't incorrectly pick this entry - * for different post-processing type (e.g. writeback). - */ - zram_clear_flag(zram, index, ZRAM_IDLE); - class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old); /* * Iterate the secondary comp algorithms list (in order of priority) -- GitLab From a5ec54a5fbeabb6dfcf579fc1b3ac74b2f40c7c7 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 6 Sep 2024 16:14:43 +0200 Subject: [PATCH 060/456] UPSTREAM: zram: Replace bit spinlocks with a spinlock_t. The bit spinlock disables preemption. The spinlock_t lock becomes a sleeping lock on PREEMPT_RT and it can not be acquired in this context. In this locked section, zs_free() acquires a zs_pool::lock, and there is access to zram::wb_limit_lock. Add a spinlock_t for locking. Keep the set/ clear ZRAM_LOCK bit after the lock has been acquired/ dropped. The size of struct zram_table_entry increases by 4 bytes due to lock and additional 4 bytes padding with CONFIG_ZRAM_TRACK_ENTRY_ACTIME enabled. [senozhatsky: this is needed to avoid conflicts with the post-processing series] Signed-off-by: Mike Galbraith Reviewed-by: Sergey Senozhatsky Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Jens Axboe Link: https://lore.kernel.org/r/20240906141520.730009-2-bigeasy@linutronix.de Signed-off-by: Jens Axboe (cherry picked from commit 9518e5bfaae19447d657983d0628062ab6712610) BUG=b:372160868 TEST=compile tested Change-Id: I36e26eea30c5b76de8e2ebbe3c22c293b1c9defc Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047504 Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 18 ++++++++++++++---- drivers/block/zram/zram_drv.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 9c8f274a28dfb..5231e5ece7c8b 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -60,17 +60,24 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index, static int zram_slot_trylock(struct zram *zram, u32 index) { - return bit_spin_trylock(ZRAM_LOCK, &zram->table[index].flags); + int ret; + + ret = spin_trylock(&zram->table[index].lock); + if (ret) + __set_bit(ZRAM_LOCK, &zram->table[index].flags); + return ret; } static void zram_slot_lock(struct zram *zram, u32 index) { - bit_spin_lock(ZRAM_LOCK, &zram->table[index].flags); + spin_lock(&zram->table[index].lock); + __set_bit(ZRAM_LOCK, &zram->table[index].flags); } static void zram_slot_unlock(struct zram *zram, u32 index) { - bit_spin_unlock(ZRAM_LOCK, &zram->table[index].flags); + __clear_bit(ZRAM_LOCK, &zram->table[index].flags); + spin_unlock(&zram->table[index].lock); } static inline bool init_done(struct zram *zram) @@ -1350,7 +1357,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize) static bool zram_meta_alloc(struct zram *zram, u64 disksize) { - size_t num_pages; + size_t num_pages, index; num_pages = disksize >> PAGE_SHIFT; zram->table = vzalloc(array_size(num_pages, sizeof(*zram->table))); @@ -1366,6 +1373,9 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) if (!huge_class_size) huge_class_size = zs_huge_class_size(zram->mem_pool); + + for (index = 0; index < num_pages; index++) + spin_lock_init(&zram->table[index].lock); return true; } diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index b976824ead676..7aeff672b96f1 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -69,6 +69,7 @@ struct zram_table_entry { unsigned long element; }; unsigned long flags; + spinlock_t lock; #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME ktime_t ac_time; #endif -- GitLab From 95d2645bcb9778c5dcad21faf972998fa53c5a71 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 6 Sep 2024 16:14:44 +0200 Subject: [PATCH 061/456] UPSTREAM: zram: Remove ZRAM_LOCK The ZRAM_LOCK was used for locking and after the addition of spinlock_t the bit set and cleared but there no reader of it. Remove the ZRAM_LOCK bit. [senozhatsky: this is needed to avoid conflicts with the post-processing sereis] Reviewed-by: Sergey Senozhatsky Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Jens Axboe Link: https://lore.kernel.org/r/20240906141520.730009-3-bigeasy@linutronix.de Signed-off-by: Jens Axboe (cherry picked from commit 6086aeb49e3d9e25165769b2a0a13ff67f98a1a2) BUG=b:372160868 TEST=compile tested Change-Id: I86ddac29905355bccd69d08a162ae7c82e3bf5e3 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047505 Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 11 ++--------- drivers/block/zram/zram_drv.h | 4 +--- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 5231e5ece7c8b..39877944cc0e2 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -60,23 +60,16 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index, static int zram_slot_trylock(struct zram *zram, u32 index) { - int ret; - - ret = spin_trylock(&zram->table[index].lock); - if (ret) - __set_bit(ZRAM_LOCK, &zram->table[index].flags); - return ret; + return spin_trylock(&zram->table[index].lock); } static void zram_slot_lock(struct zram *zram, u32 index) { spin_lock(&zram->table[index].lock); - __set_bit(ZRAM_LOCK, &zram->table[index].flags); } static void zram_slot_unlock(struct zram *zram, u32 index) { - __clear_bit(ZRAM_LOCK, &zram->table[index].flags); spin_unlock(&zram->table[index].lock); } @@ -1433,7 +1426,7 @@ out: zram_set_handle(zram, index, 0); zram_set_obj_size(zram, index, 0); WARN_ON_ONCE(zram->table[index].flags & - ~(1UL << ZRAM_LOCK | 1UL << ZRAM_UNDER_WB)); + ~(1UL << ZRAM_UNDER_WB)); } /* diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 7aeff672b96f1..d5eef65870380 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -45,9 +45,7 @@ /* Flags for zram pages (table[page_no].flags) */ enum zram_pageflags { - /* zram slot is locked */ - ZRAM_LOCK = ZRAM_FLAG_SHIFT, - ZRAM_SAME, /* Page consists the same element */ + ZRAM_SAME = ZRAM_FLAG_SHIFT, /* Page consists the same element */ ZRAM_WB, /* page is stored on backing_device */ ZRAM_UNDER_WB, /* page is under writeback */ ZRAM_HUGE, /* Incompressible page */ -- GitLab From 86b5d0af74b42194ac2c3a73068f169038f0bcdf Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 6 Sep 2024 16:14:45 +0200 Subject: [PATCH 062/456] UPSTREAM: zram: Shrink zram_table_entry::flags. The zram_table_entry::flags member is of type long and uses 8 bytes on a 64bit architecture. With a PAGE_SIZE of 256KiB we have PAGE_SHIFT of 18 which in turn leads to __NR_ZRAM_PAGEFLAGS = 27. This still fits in an ordinary integer. By reducing the size of `flags' to four bytes, the size of the struct goes back to 16 bytes. The padding between the lock and ac_time (if enabled) is also gone. Make zram_table_entry::flags an unsigned int and update the build test to reflect the change. [senozhatsky: this is needed to avoid conflicts with the post-processing series] Reviewed-by: Sergey Senozhatsky Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Jens Axboe Link: https://lore.kernel.org/r/20240906141520.730009-4-bigeasy@linutronix.de Signed-off-by: Jens Axboe (cherry picked from commit 68d20eb60efbdc80662efedeb088353e9c4aa17f) BUG=b:372160868 TEST=compile tested Change-Id: I235a93fd67573dd01e2ed32a0f68086523d3afc9 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047506 Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 3 ++- drivers/block/zram/zram_drv.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 39877944cc0e2..d8eea0a8d5c7f 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -2591,9 +2591,10 @@ static void destroy_devices(void) static int __init zram_init(void) { + struct zram_table_entry zram_te; int ret; - BUILD_BUG_ON(__NR_ZRAM_PAGEFLAGS > BITS_PER_LONG); + BUILD_BUG_ON(__NR_ZRAM_PAGEFLAGS > sizeof(zram_te.flags) * 8); ret = cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare", zcomp_cpu_up_prepare, zcomp_cpu_dead); diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index d5eef65870380..cfc8c059db636 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -66,7 +66,7 @@ struct zram_table_entry { unsigned long handle; unsigned long element; }; - unsigned long flags; + unsigned int flags; spinlock_t lock; #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME ktime_t ac_time; -- GitLab From b8093b3f5f19f2c6d0cf5d42d136641ebb7958ec Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:06 +0900 Subject: [PATCH 063/456] UPSTREAM: zram: introduce ZRAM_PP_SLOT flag Patch series "zram: optimal post-processing target selection", v5. Problem: -------- Both recompression and writeback perform a very simple linear scan of all zram slots in search for post-processing (writeback or recompress) candidate slots. This often means that we pick the worst candidate for pp (post-processing), e.g. a 48 bytes object for writeback, which is nearly useless, because it only releases 48 bytes from zsmalloc pool, but consumes an entire 4K slot in the backing device. Similarly, recompression of an 48 bytes objects is unlikely to save more memory that recompression of a 3000 bytes object. Both recompression and writeback consume constrained resources (CPU time, batter, backing device storage space) and quite often have a (daily) limit on the number of items they post-process, so we should utilize those constrained resources in the most optimal way. Solution: --------- This patch reworks the way we select pp targets. We, quite clearly, want to sort all the candidates and always pick the largest, be it recompression or writeback. Especially for writeback, because the larger object we writeback the more memory we release. This series introduces concept of pp buckets and pp scan/selection. The scan step is a simple iteration over all zram->table entries, just like what we currently do, but we don't post-process a candidate slot immediately. Instead we assign it to a PP (post-processing) bucket. PP bucket is, basically, a list which holds pp candidate slots that belong to the same size class. PP buckets are 64 bytes apart, slots are not strictly sorted within a bucket there is a 64 bytes variance. The select step simply iterates over pp buckets from highest to lowest and picks all candidate slots a particular buckets contains. So this gives us sorted candidates (in linear time) and allows us to select most optimal (largest) candidates for post-processing first. This patch (of 7): This flag indicates that the slot was selected as a candidate slot for post-processing (pp) and was assigned to a pp bucket. It does not necessarily mean that the slot is currently under post-processing, but may mean so. The slot can loose its PP_SLOT flag, while still being in the pp-bucket, if it's accessed or slot_free-ed. Link: https://lkml.kernel.org/r/20240917021020.883356-1-senozhatsky@chromium.org Link: https://lkml.kernel.org/r/20240917021020.883356-2-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit bf779fb9afb5c5cc3c45d19a7a1ea7cd77c742f0) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: I4b78581abe90a9d835ae88ed33a6cfb618880448 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047507 Tested-by: Sergey Senozhatsky Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Commit-Queue: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 2 ++ drivers/block/zram/zram_drv.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index d8eea0a8d5c7f..2c98d9aeb6ce3 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -178,6 +178,7 @@ static inline u32 zram_get_priority(struct zram *zram, u32 index) static void zram_accessed(struct zram *zram, u32 index) { zram_clear_flag(zram, index, ZRAM_IDLE); + zram_clear_flag(zram, index, ZRAM_PP_SLOT); #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME zram->table[index].ac_time = ktime_get_boottime(); #endif @@ -1396,6 +1397,7 @@ static void zram_free_page(struct zram *zram, size_t index) zram_clear_flag(zram, index, ZRAM_INCOMPRESSIBLE); zram_set_priority(zram, index, 0); + zram_clear_flag(zram, index, ZRAM_PP_SLOT); if (zram_test_flag(zram, index, ZRAM_WB)) { zram_clear_flag(zram, index, ZRAM_WB); diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index cfc8c059db636..914cb66299694 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -48,6 +48,7 @@ enum zram_pageflags { ZRAM_SAME = ZRAM_FLAG_SHIFT, /* Page consists the same element */ ZRAM_WB, /* page is stored on backing_device */ ZRAM_UNDER_WB, /* page is under writeback */ + ZRAM_PP_SLOT, /* Selected for post-processing */ ZRAM_HUGE, /* Incompressible page */ ZRAM_IDLE, /* not accessed page since last idle marking */ ZRAM_INCOMPRESSIBLE, /* none of the algorithms could compress it */ -- GitLab From fac57fc5b2da49130a98a5eb1b59a92ef1200f3e Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:07 +0900 Subject: [PATCH 064/456] UPSTREAM: zram: permit only one post-processing operation at a time Both recompress and writeback soon will unlock slots during processing, which makes things too complex wrt possible race-conditions. We still want to clear PP_SLOT in slot_free, because this is how we figure out that slot that was selected for post-processing has been released under us and when we start post-processing we check if slot still has PP_SLOT set. At the same time, theoretically, we can have something like this: CPU0 CPU1 recompress scan slots set PP_SLOT unlock slot slot_free clear PP_SLOT allocate PP_SLOT writeback scan slots set PP_SLOT unlock slot select PP-slot test PP_SLOT So recompress will not detect that slot has been re-used and re-selected for concurrent writeback post-processing. Make sure that we only permit on post-processing operation at a time. So now recompress and writeback post-processing don't race against each other, we only need to handle slot re-use (slot_free and write), which is handled individually by each pp operation. Having recompress and writeback competing for the same slots is not exactly good anyway (can't imagine anyone doing that). Link: https://lkml.kernel.org/r/20240917021020.883356-3-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 58652f2b6d21f2874c9f060165ec7e03e8b1fc71) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: I2f58b59171314563266548050135aa603deadf93 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047508 Tested-by: Sergey Senozhatsky Commit-Queue: Sergey Senozhatsky Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Signed-off-by: Hubert Mazur --- Documentation/admin-guide/blockdev/zram.rst | 2 ++ drivers/block/zram/zram_drv.c | 16 ++++++++++++++++ drivers/block/zram/zram_drv.h | 1 + 3 files changed, 19 insertions(+) diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst index 678d70d6e1c3a..714a5171bfc0b 100644 --- a/Documentation/admin-guide/blockdev/zram.rst +++ b/Documentation/admin-guide/blockdev/zram.rst @@ -47,6 +47,8 @@ The list of possible return codes: -ENOMEM zram was not able to allocate enough memory to fulfil your needs. -EINVAL invalid input has been provided. +-EAGAIN re-try operation later (e.g. when attempting to run recompress + and writeback simultaneously). ======== ============================================================= If you use 'echo', the returned value is set by the 'echo' utility, diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 2c98d9aeb6ce3..3cf21448f5557 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -664,6 +664,12 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } + /* Do not permit concurrent post-processing actions. */ + if (atomic_xchg(&zram->pp_in_progress, 1)) { + up_read(&zram->init_lock); + return -EAGAIN; + } + if (!zram->backing_dev) { ret = -ENODEV; goto release_init_lock; @@ -790,6 +796,7 @@ next: free_block_bdev(zram, blk_idx); __free_page(page); release_init_lock: + atomic_set(&zram->pp_in_progress, 0); up_read(&zram->init_lock); return ret; @@ -1926,6 +1933,12 @@ static ssize_t recompress_store(struct device *dev, goto release_init_lock; } + /* Do not permit concurrent post-processing actions. */ + if (atomic_xchg(&zram->pp_in_progress, 1)) { + up_read(&zram->init_lock); + return -EAGAIN; + } + if (algo) { bool found = false; @@ -1993,6 +2006,7 @@ next: __free_page(page); release_init_lock: + atomic_set(&zram->pp_in_progress, 0); up_read(&zram->init_lock); return ret; } @@ -2184,6 +2198,7 @@ static void zram_reset_device(struct zram *zram) zram->disksize = 0; zram_destroy_comps(zram); memset(&zram->stats, 0, sizeof(zram->stats)); + atomic_set(&zram->pp_in_progress, 0); reset_bdev(zram); comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor); @@ -2407,6 +2422,7 @@ static int zram_add(void) zram->disk->fops = &zram_devops; zram->disk->private_data = zram; snprintf(zram->disk->disk_name, 16, "zram%d", device_id); + atomic_set(&zram->pp_in_progress, 0); /* Actual capacity set using sysfs (/sys/block/zram/disksize */ set_capacity(zram->disk, 0); diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 914cb66299694..73a9d47d76bae 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -140,5 +140,6 @@ struct zram { #ifdef CONFIG_ZRAM_MEMORY_TRACKING struct dentry *debugfs_dir; #endif + atomic_t pp_in_progress; }; #endif -- GitLab From 4b0b199a67b68e0a425b96d2ca44a4f47952ba1a Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:08 +0900 Subject: [PATCH 065/456] UPSTREAM: zram: rework recompress target selection strategy Target slot selection for recompression is just a simple iteration over zram->table entries (stored pages) from slot 0 to max slot. Given that zram->table slots are written in random order and are not sorted by size, a simple iteration over slots selects suboptimal targets for recompression. This is not a problem if we recompress every single zram->table slot, but we never do that in reality. In reality we limit the number of slots we can recompress (via max_pages parameter) and hence proper slot selection becomes very important. The strategy is quite simple, suppose we have two candidate slots for recompression, one of size 48 bytes and one of size 2800 bytes, and we can recompress only one, then it certainly makes more sense to pick 2800 entry for recompression. Because even if we manage to compress 48 bytes objects even further the savings are going to be very small. Potential savings after good re-compression of 2800 bytes objects are much higher. This patch reworks slot selection and introduces the strategy described above: among candidate slots always select the biggest ones first. For that the patch introduces zram_pp_ctl (post-processing) structure which holds NUM_PP_BUCKETS pp buckets of slots. Slots are assigned to a particular group based on their sizes - the larger the size of the slot the higher the group index. This, basically, sorts slots by size in liner time (we still perform just one iteration over zram->table slots). When we select slot for recompression we always first lookup in higher pp buckets (those that hold the largest slots). Which achieves the desired behavior. TEST ==== A very simple demonstration: zram is configured with zstd, and zstd with dict as a recompression stream. A limited (max 4096 pages) recompression is performed then, with a log of sizes of slots that were recompressed. You can see that patched zram selects slots for recompression in significantly different manner, which leads to higher memory savings (see column #2 of mm_stat output). BASE ---- *** initial state of zram device /sys/block/zram0/mm_stat 1750994944 504491413 514203648 0 514203648 1 0 34204 34204 *** recompress idle max_pages=4096 /sys/block/zram0/mm_stat 1750994944 504262229 514953216 0 514203648 1 0 34204 34204 Sizes of selected objects for recompression: ... 45 58 24 226 91 40 24 24 24 424 2104 93 2078 2078 2078 959 154 ... PATCHED ------- *** initial state of zram device /sys/block/zram0/mm_stat 1750982656 504492801 514170880 0 514170880 1 0 34204 34204 *** recompress idle max_pages=4096 /sys/block/zram0/mm_stat 1750982656 503716710 517586944 0 514170880 1 0 34204 34204 Sizes of selected objects for recompression: ... 3680 3694 3667 3590 3614 3553 3537 3548 3550 3542 3543 3537 ... Note, pp-slots are not strictly sorted, there is a PP_BUCKET_SIZE_RANGE variation of sizes within particular bucket. [senozhatsky@chromium.org: do not skip the first bucket] Link: https://lkml.kernel.org/r/20241001085634.1948384-1-senozhatsky@chromium.org Link: https://lkml.kernel.org/r/20240917021020.883356-4-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Dan Carpenter Signed-off-by: Andrew Morton (cherry picked from commit 3f909a60cec19509f6bfa01f90ad878e410cec51) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: If527e502af143a15db2ab91c9efa1759d26e16b5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047509 Commit-Queue: Sergey Senozhatsky Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Tested-by: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 187 +++++++++++++++++++++++++++++----- 1 file changed, 160 insertions(+), 27 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 3cf21448f5557..0882bde8a8cc0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -184,6 +184,99 @@ static void zram_accessed(struct zram *zram, u32 index) #endif } +#ifdef CONFIG_ZRAM_MULTI_COMP +struct zram_pp_slot { + unsigned long index; + struct list_head entry; +}; + +/* + * A post-processing bucket is, essentially, a size class, this defines + * the range (in bytes) of pp-slots sizes in particular bucket. + */ +#define PP_BUCKET_SIZE_RANGE 64 +#define NUM_PP_BUCKETS ((PAGE_SIZE / PP_BUCKET_SIZE_RANGE) + 1) + +struct zram_pp_ctl { + struct list_head pp_buckets[NUM_PP_BUCKETS]; +}; + +static struct zram_pp_ctl *init_pp_ctl(void) +{ + struct zram_pp_ctl *ctl; + u32 idx; + + ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return NULL; + + for (idx = 0; idx < NUM_PP_BUCKETS; idx++) + INIT_LIST_HEAD(&ctl->pp_buckets[idx]); + return ctl; +} + +static void release_pp_slot(struct zram *zram, struct zram_pp_slot *pps) +{ + list_del_init(&pps->entry); + + zram_slot_lock(zram, pps->index); + zram_clear_flag(zram, pps->index, ZRAM_PP_SLOT); + zram_slot_unlock(zram, pps->index); + + kfree(pps); +} + +static void release_pp_ctl(struct zram *zram, struct zram_pp_ctl *ctl) +{ + u32 idx; + + if (!ctl) + return; + + for (idx = 0; idx < NUM_PP_BUCKETS; idx++) { + while (!list_empty(&ctl->pp_buckets[idx])) { + struct zram_pp_slot *pps; + + pps = list_first_entry(&ctl->pp_buckets[idx], + struct zram_pp_slot, + entry); + release_pp_slot(zram, pps); + } + } + + kfree(ctl); +} + +static void place_pp_slot(struct zram *zram, struct zram_pp_ctl *ctl, + struct zram_pp_slot *pps) +{ + u32 idx; + + idx = zram_get_obj_size(zram, pps->index) / PP_BUCKET_SIZE_RANGE; + list_add(&pps->entry, &ctl->pp_buckets[idx]); + + zram_set_flag(zram, pps->index, ZRAM_PP_SLOT); +} + +static struct zram_pp_slot *select_pp_slot(struct zram_pp_ctl *ctl) +{ + struct zram_pp_slot *pps = NULL; + s32 idx = NUM_PP_BUCKETS - 1; + + /* The higher the bucket id the more optimal slot post-processing is */ + while (idx >= 0) { + pps = list_first_entry_or_null(&ctl->pp_buckets[idx], + struct zram_pp_slot, + entry); + if (pps) + break; + + idx--; + } + return pps; +} +#endif + static inline void update_used_max(struct zram *zram, const unsigned long pages) { @@ -1700,6 +1793,52 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, } #ifdef CONFIG_ZRAM_MULTI_COMP +#define RECOMPRESS_IDLE (1 << 0) +#define RECOMPRESS_HUGE (1 << 1) + +static int scan_slots_for_recompress(struct zram *zram, u32 mode, + struct zram_pp_ctl *ctl) +{ + unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; + struct zram_pp_slot *pps = NULL; + unsigned long index; + + for (index = 0; index < nr_pages; index++) { + if (!pps) + pps = kmalloc(sizeof(*pps), GFP_KERNEL); + if (!pps) + return -ENOMEM; + + INIT_LIST_HEAD(&pps->entry); + + zram_slot_lock(zram, index); + if (!zram_allocated(zram, index)) + goto next; + + if (mode & RECOMPRESS_IDLE && + !zram_test_flag(zram, index, ZRAM_IDLE)) + goto next; + + if (mode & RECOMPRESS_HUGE && + !zram_test_flag(zram, index, ZRAM_HUGE)) + goto next; + + if (zram_test_flag(zram, index, ZRAM_WB) || + zram_test_flag(zram, index, ZRAM_SAME) || + zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) + goto next; + + pps->index = index; + place_pp_slot(zram, ctl, pps); + pps = NULL; +next: + zram_slot_unlock(zram, index); + } + + kfree(pps); + return 0; +} + /* * This function will decompress (unless it's ZRAM_HUGE) the page and then * attempt to compress it using provided compression algorithm priority @@ -1707,7 +1846,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, * * Corresponding ZRAM slot should be locked. */ -static int zram_recompress(struct zram *zram, u32 index, struct page *page, +static int recompress_slot(struct zram *zram, u32 index, struct page *page, u64 *num_recomp_pages, u32 threshold, u32 prio, u32 prio_max) { @@ -1850,20 +1989,17 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page, return 0; } -#define RECOMPRESS_IDLE (1 << 0) -#define RECOMPRESS_HUGE (1 << 1) - static ssize_t recompress_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { u32 prio = ZRAM_SECONDARY_COMP, prio_max = ZRAM_MAX_COMPS; struct zram *zram = dev_to_zram(dev); - unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; char *args, *param, *val, *algo = NULL; u64 num_recomp_pages = ULLONG_MAX; + struct zram_pp_ctl *ctl = NULL; + struct zram_pp_slot *pps; u32 mode = 0, threshold = 0; - unsigned long index; struct page *page; ssize_t ret; @@ -1965,36 +2101,32 @@ static ssize_t recompress_store(struct device *dev, goto release_init_lock; } + ctl = init_pp_ctl(); + if (!ctl) { + ret = -ENOMEM; + goto release_init_lock; + } + + scan_slots_for_recompress(zram, mode, ctl); + ret = len; - for (index = 0; index < nr_pages; index++) { + while ((pps = select_pp_slot(ctl))) { int err = 0; if (!num_recomp_pages) break; - zram_slot_lock(zram, index); - - if (!zram_allocated(zram, index)) - goto next; - - if (mode & RECOMPRESS_IDLE && - !zram_test_flag(zram, index, ZRAM_IDLE)) - goto next; - - if (mode & RECOMPRESS_HUGE && - !zram_test_flag(zram, index, ZRAM_HUGE)) + zram_slot_lock(zram, pps->index); + if (!zram_test_flag(zram, pps->index, ZRAM_PP_SLOT)) goto next; - if (zram_test_flag(zram, index, ZRAM_WB) || - zram_test_flag(zram, index, ZRAM_UNDER_WB) || - zram_test_flag(zram, index, ZRAM_SAME) || - zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) - goto next; - - err = zram_recompress(zram, index, page, &num_recomp_pages, - threshold, prio, prio_max); + err = recompress_slot(zram, pps->index, page, + &num_recomp_pages, threshold, + prio, prio_max); next: - zram_slot_unlock(zram, index); + zram_slot_unlock(zram, pps->index); + release_pp_slot(zram, pps); + if (err) { ret = err; break; @@ -2006,6 +2138,7 @@ next: __free_page(page); release_init_lock: + release_pp_ctl(zram, ctl); atomic_set(&zram->pp_in_progress, 0); up_read(&zram->init_lock); return ret; -- GitLab From 30533410fb81d20efcc60a96e16375c5ad6e6b25 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:09 +0900 Subject: [PATCH 066/456] UPSTREAM: zram: rework writeback target selection strategy Writeback suffers from the same problem as recompression did before - target slot selection for writeback is just a simple iteration over zram->table entries (stored pages) which selects suboptimal targets for writeback. This is especially problematic for writeback, because we uncompress objects before writeback so each of them takes 4K out of limited writeback storage. For example, when we take a 48 bytes slot and store it as a 4K object to writeback device we only save 48 bytes of memory (release from zsmalloc pool). We naturally want to pick the largest objects for writeback, because then each writeback will release the largest amount of memory. This patch applies the same solution and strategy as for recompression target selection: pp control (post-process) with 16 buckets of candidate pp slots. Slots are assigned to pp buckets based on sizes - the larger the slot the higher the group index. This gives us sorted by size lists of candidate slots (in linear time), so that among post-processing candidate slots we always select the largest ones first and maximize the memory saving. TEST ==== A very simple demonstration: zram is configured with a writeback device. A limited writeback (wb_limit 2500 pages) is performed then, with a log of sizes of slots that were written back. You can see that patched zram selects slots for recompression in significantly different manner, which leads to higher memory savings (see column #2 of mm_stat output). BASE ---- *** initial state of zram device /sys/block/zram0/mm_stat 1750327296 619765836 631902208 0 631902208 1 0 34278 34278 *** writeback idle wb_limit 2500 /sys/block/zram0/mm_stat 1750327296 617622333 631578624 0 631902208 1 0 34278 34278 Sizes of selected objects for writeback: ... 193 349 46 46 46 46 852 1002 543 162 107 49 34 34 34 ... PATCHED ------- *** initial state of zram device /sys/block/zram0/mm_stat 1750319104 619760957 631992320 0 631992320 1 0 34278 34278 *** writeback idle wb_limit 2500 /sys/block/zram0/mm_stat 1750319104 612672056 626135040 0 631992320 1 0 34278 34278 Sizes of selected objects for writeback: ... 3667 3580 3581 3580 3581 3581 3581 3231 3211 3203 3231 3246 ... Note, pp-slots are not strictly sorted, there is a PP_BUCKET_SIZE_RANGE variation of sizes within particular bucket. Link: https://lkml.kernel.org/r/20240917021020.883356-5-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 330edc2bc059a48b1f61a704521818d4f831767c) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: Ifceca0aa6eee0c9f66db700276ee170e8635f950 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047510 Reviewed-by: Brian Geffon Tested-by: Sergey Senozhatsky Reviewed-by: Sean Paul Commit-Queue: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 83 +++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 0882bde8a8cc0..4234742182c8a 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -184,7 +184,7 @@ static void zram_accessed(struct zram *zram, u32 index) #endif } -#ifdef CONFIG_ZRAM_MULTI_COMP +#if defined CONFIG_ZRAM_WRITEBACK || defined CONFIG_ZRAM_MULTI_COMP struct zram_pp_slot { unsigned long index; struct list_head entry; @@ -718,11 +718,57 @@ static void read_from_bdev_async(struct zram *zram, struct page *page, #define IDLE_WRITEBACK (1<<1) #define INCOMPRESSIBLE_WRITEBACK (1<<2) +static int scan_slots_for_writeback(struct zram *zram, u32 mode, + unsigned long nr_pages, + unsigned long index, + struct zram_pp_ctl *ctl) +{ + struct zram_pp_slot *pps = NULL; + + for (; nr_pages != 0; index++, nr_pages--) { + if (!pps) + pps = kmalloc(sizeof(*pps), GFP_KERNEL); + if (!pps) + return -ENOMEM; + + INIT_LIST_HEAD(&pps->entry); + + zram_slot_lock(zram, index); + if (!zram_allocated(zram, index)) + goto next; + + if (zram_test_flag(zram, index, ZRAM_WB) || + zram_test_flag(zram, index, ZRAM_SAME)) + goto next; + + if (mode & IDLE_WRITEBACK && + !zram_test_flag(zram, index, ZRAM_IDLE)) + goto next; + if (mode & HUGE_WRITEBACK && + !zram_test_flag(zram, index, ZRAM_HUGE)) + goto next; + if (mode & INCOMPRESSIBLE_WRITEBACK && + !zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) + goto next; + + pps->index = index; + place_pp_slot(zram, ctl, pps); + pps = NULL; +next: + zram_slot_unlock(zram, index); + } + + kfree(pps); + return 0; +} + static ssize_t writeback_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; + struct zram_pp_ctl *ctl = NULL; + struct zram_pp_slot *pps; unsigned long index = 0; struct bio bio; struct bio_vec bio_vec; @@ -774,7 +820,15 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - for (; nr_pages != 0; index++, nr_pages--) { + ctl = init_pp_ctl(); + if (!ctl) { + ret = -ENOMEM; + goto release_init_lock; + } + + scan_slots_for_writeback(zram, mode, nr_pages, index, ctl); + + while ((pps = select_pp_slot(ctl))) { spin_lock(&zram->wb_limit_lock); if (zram->wb_limit_enable && !zram->bd_wb_limit) { spin_unlock(&zram->wb_limit_lock); @@ -791,25 +845,10 @@ static ssize_t writeback_store(struct device *dev, } } + index = pps->index; zram_slot_lock(zram, index); - if (!zram_allocated(zram, index)) - goto next; - - if (zram_test_flag(zram, index, ZRAM_WB) || - zram_test_flag(zram, index, ZRAM_SAME) || - zram_test_flag(zram, index, ZRAM_UNDER_WB)) - goto next; - - if (mode & IDLE_WRITEBACK && - !zram_test_flag(zram, index, ZRAM_IDLE)) - goto next; - if (mode & HUGE_WRITEBACK && - !zram_test_flag(zram, index, ZRAM_HUGE)) - goto next; - if (mode & INCOMPRESSIBLE_WRITEBACK && - !zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) + if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) goto next; - /* * Clearing ZRAM_UNDER_WB is duty of caller. * IOW, zram_free_page never clear it. @@ -823,6 +862,8 @@ static ssize_t writeback_store(struct device *dev, zram_clear_flag(zram, index, ZRAM_UNDER_WB); zram_clear_flag(zram, index, ZRAM_IDLE); zram_slot_unlock(zram, index); + + release_pp_slot(zram, pps); continue; } @@ -841,6 +882,8 @@ static ssize_t writeback_store(struct device *dev, zram_clear_flag(zram, index, ZRAM_UNDER_WB); zram_clear_flag(zram, index, ZRAM_IDLE); zram_slot_unlock(zram, index); + + release_pp_slot(zram, pps); /* * BIO errors are not fatal, we continue and simply * attempt to writeback the remaining objects (pages). @@ -883,12 +926,14 @@ static ssize_t writeback_store(struct device *dev, spin_unlock(&zram->wb_limit_lock); next: zram_slot_unlock(zram, index); + release_pp_slot(zram, pps); } if (blk_idx) free_block_bdev(zram, blk_idx); __free_page(page); release_init_lock: + release_pp_ctl(zram, ctl); atomic_set(&zram->pp_in_progress, 0); up_read(&zram->init_lock); -- GitLab From 034943a66f7477c502842b0f39fe493ab77aee97 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:11 +0900 Subject: [PATCH 067/456] UPSTREAM: zram: reshuffle zram_free_page() flags operations Drop some redundant zram_test_flag() calls and re-order zram_clear_flag() calls. Plus two small trivial coding style fixes. No functional changes. Link: https://lkml.kernel.org/r/20240917021020.883356-7-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 1a1d0f8992d5c6c8059d28cd9cb263180dd98a28) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: Icbaa239bce4ea0b2bc5e96fce7d79c0762bb3b89 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047512 Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Tested-by: Sergey Senozhatsky Commit-Queue: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 4234742182c8a..3e78c8963df1a 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1530,20 +1530,17 @@ static void zram_free_page(struct zram *zram, size_t index) #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME zram->table[index].ac_time = 0; #endif - if (zram_test_flag(zram, index, ZRAM_IDLE)) - zram_clear_flag(zram, index, ZRAM_IDLE); + + zram_clear_flag(zram, index, ZRAM_IDLE); + zram_clear_flag(zram, index, ZRAM_INCOMPRESSIBLE); + zram_clear_flag(zram, index, ZRAM_PP_SLOT); + zram_set_priority(zram, index, 0); if (zram_test_flag(zram, index, ZRAM_HUGE)) { zram_clear_flag(zram, index, ZRAM_HUGE); atomic64_dec(&zram->stats.huge_pages); } - if (zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) - zram_clear_flag(zram, index, ZRAM_INCOMPRESSIBLE); - - zram_set_priority(zram, index, 0); - zram_clear_flag(zram, index, ZRAM_PP_SLOT); - if (zram_test_flag(zram, index, ZRAM_WB)) { zram_clear_flag(zram, index, ZRAM_WB); free_block_bdev(zram, zram_get_element(zram, index)); @@ -1567,13 +1564,12 @@ static void zram_free_page(struct zram *zram, size_t index) zs_free(zram->mem_pool, handle); atomic64_sub(zram_get_obj_size(zram, index), - &zram->stats.compr_data_size); + &zram->stats.compr_data_size); out: atomic64_dec(&zram->stats.pages_stored); zram_set_handle(zram, index, 0); zram_set_obj_size(zram, index, 0); - WARN_ON_ONCE(zram->table[index].flags & - ~(1UL << ZRAM_UNDER_WB)); + WARN_ON_ONCE(zram->table[index].flags & ~(1UL << ZRAM_UNDER_WB)); } /* -- GitLab From 66d39d88ef733432b869946100c156c7e086dac5 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 17 Sep 2024 11:09:12 +0900 Subject: [PATCH 068/456] UPSTREAM: zram: remove UNDER_WB and simplify writeback We now have only one active post-processing at any time, so we don't have same race conditions that we had before. If slot selected for post-processing gets freed or freed and reallocated it loses its PP_SLOT flag and there is no way for such a slot to gain PP_SLOT flag again until current post-processing terminates. Link: https://lkml.kernel.org/r/20240917021020.883356-8-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 5e99893444a0e0582feb49d618195114b6e35760) BUG=b:372160868 TEST=compile tested, MemoryPressure tast on brya Change-Id: I211cffe78b114b4e57264ac73892f264b986ae55 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047513 Reviewed-by: Brian Geffon Commit-Queue: Sergey Senozhatsky Tested-by: Sergey Senozhatsky Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 53 +++++++++++------------------------ drivers/block/zram/zram_drv.h | 1 - 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 3e78c8963df1a..4d7311174a8e2 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -390,10 +390,7 @@ static void mark_idle(struct zram *zram, ktime_t cutoff) for (index = 0; index < nr_pages; index++) { /* - * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race. - * See the comment in writeback_store. - * - * Also do not mark ZRAM_SAME slots as ZRAM_IDLE, because no + * Do not mark ZRAM_SAME slots as ZRAM_IDLE, because no * post-processing (recompress, writeback) happens to the * ZRAM_SAME slot. * @@ -402,7 +399,6 @@ static void mark_idle(struct zram *zram, ktime_t cutoff) zram_slot_lock(zram, index); if (!zram_allocated(zram, index) || zram_test_flag(zram, index, ZRAM_WB) || - zram_test_flag(zram, index, ZRAM_UNDER_WB) || zram_test_flag(zram, index, ZRAM_SAME)) { zram_slot_unlock(zram, index); continue; @@ -847,22 +843,17 @@ static ssize_t writeback_store(struct device *dev, index = pps->index; zram_slot_lock(zram, index); - if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) - goto next; /* - * Clearing ZRAM_UNDER_WB is duty of caller. - * IOW, zram_free_page never clear it. + * scan_slots() sets ZRAM_PP_SLOT and relases slot lock, so + * slots can change in the meantime. If slots are accessed or + * freed they lose ZRAM_PP_SLOT flag and hence we don't + * post-process them. */ - zram_set_flag(zram, index, ZRAM_UNDER_WB); - /* Need for hugepage writeback racing */ - zram_set_flag(zram, index, ZRAM_IDLE); + if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) + goto next; zram_slot_unlock(zram, index); - if (zram_read_page(zram, page, index, NULL)) { - zram_slot_lock(zram, index); - zram_clear_flag(zram, index, ZRAM_UNDER_WB); - zram_clear_flag(zram, index, ZRAM_IDLE); - zram_slot_unlock(zram, index); + if (zram_read_page(zram, page, index, NULL)) { release_pp_slot(zram, pps); continue; } @@ -878,11 +869,6 @@ static ssize_t writeback_store(struct device *dev, */ err = submit_bio_wait(&bio); if (err) { - zram_slot_lock(zram, index); - zram_clear_flag(zram, index, ZRAM_UNDER_WB); - zram_clear_flag(zram, index, ZRAM_IDLE); - zram_slot_unlock(zram, index); - release_pp_slot(zram, pps); /* * BIO errors are not fatal, we continue and simply @@ -897,25 +883,19 @@ static ssize_t writeback_store(struct device *dev, } atomic64_inc(&zram->stats.bd_writes); + zram_slot_lock(zram, index); /* - * We released zram_slot_lock so need to check if the slot was - * changed. If there is freeing for the slot, we can catch it - * easily by zram_allocated. - * A subtle case is the slot is freed/reallocated/marked as - * ZRAM_IDLE again. To close the race, idle_store doesn't - * mark ZRAM_IDLE once it found the slot was ZRAM_UNDER_WB. - * Thus, we could close the race by checking ZRAM_IDLE bit. + * Same as above, we release slot lock during writeback so + * slot can change under us: slot_free() or slot_free() and + * reallocation (zram_write_page()). In both cases slot loses + * ZRAM_PP_SLOT flag. No concurrent post-processing can set + * ZRAM_PP_SLOT on such slots until current post-processing + * finishes. */ - zram_slot_lock(zram, index); - if (!zram_allocated(zram, index) || - !zram_test_flag(zram, index, ZRAM_IDLE)) { - zram_clear_flag(zram, index, ZRAM_UNDER_WB); - zram_clear_flag(zram, index, ZRAM_IDLE); + if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) goto next; - } zram_free_page(zram, index); - zram_clear_flag(zram, index, ZRAM_UNDER_WB); zram_set_flag(zram, index, ZRAM_WB); zram_set_element(zram, index, blk_idx); blk_idx = 0; @@ -1569,7 +1549,6 @@ out: atomic64_dec(&zram->stats.pages_stored); zram_set_handle(zram, index, 0); zram_set_obj_size(zram, index, 0); - WARN_ON_ONCE(zram->table[index].flags & ~(1UL << ZRAM_UNDER_WB)); } /* diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 73a9d47d76bae..134be414e2106 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -47,7 +47,6 @@ enum zram_pageflags { ZRAM_SAME = ZRAM_FLAG_SHIFT, /* Page consists the same element */ ZRAM_WB, /* page is stored on backing_device */ - ZRAM_UNDER_WB, /* page is under writeback */ ZRAM_PP_SLOT, /* Selected for post-processing */ ZRAM_HUGE, /* Incompressible page */ ZRAM_IDLE, /* not accessed page since last idle marking */ -- GitLab From 5cd5efb05ea1b1e7fce7fa019129147b6c9fc53a Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Wed, 9 Oct 2024 13:28:00 +0900 Subject: [PATCH 069/456] UPSTREAM: zram: do not open-code comp priority 0 A cosmetic change: do not open-code compression priority 0, use ZRAM_PRIMARY_COMP instead. Link: https://lkml.kernel.org/r/20241009042908.750260-1-senozhatsky@chromium.org Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 01a9097aa3ce4c6aef296779c163169ac403260e) BUG=none TEST=none Change-Id: Id6a19edfd0c70efbc032ad5d867ec63eeaa39800 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047514 Commit-Queue: Sergey Senozhatsky Reviewed-by: Sean Paul Reviewed-by: Brian Geffon Tested-by: Sergey Senozhatsky Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 4d7311174a8e2..a5c9e626e4ef0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -2317,7 +2317,7 @@ static void zram_destroy_comps(struct zram *zram) { u32 prio; - for (prio = 0; prio < ZRAM_MAX_COMPS; prio++) { + for (prio = ZRAM_PRIMARY_COMP; prio < ZRAM_MAX_COMPS; prio++) { struct zcomp *comp = zram->comps[prio]; zram->comps[prio] = NULL; @@ -2384,7 +2384,7 @@ static ssize_t disksize_store(struct device *dev, goto out_unlock; } - for (prio = 0; prio < ZRAM_MAX_COMPS; prio++) { + for (prio = ZRAM_PRIMARY_COMP; prio < ZRAM_MAX_COMPS; prio++) { if (!zram->comp_algs[prio]) continue; -- GitLab From 4553ddc6f0e8390211661686894e7c2ed44365d9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 Nov 2024 12:50:35 +0100 Subject: [PATCH 070/456] UPSTREAM: zram: ZRAM_DEF_COMP should depend on ZRAM When Compressed RAM block device support is disabled, the CONFIG_ZRAM_DEF_COMP symbol still ends up in the generated config file: CONFIG_ZRAM_DEF_COMP="unset-value" While this causes no real harm, avoid polluting the config file by adding a dependency on ZRAM. Link: https://lkml.kernel.org/r/64e05bad68a9bd5cc322efd114a04d25de525940.1730807319.git.geert@linux-m68k.org Fixes: 917a59e81c34 ("zram: introduce custom comp backends API") Signed-off-by: Geert Uytterhoeven Reviewed-by: Sergey Senozhatsky Cc: Jens Axboe Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit 9f3310ccc71efff041fed3f8be5ad19b0feab30b) BUG=none TEST=none Change-Id: I5604195e3def3f69ed2821b9b2a6e122e024c784 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047517 Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/block/zram/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 6aea609b795c2..402b7b1758632 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig @@ -94,6 +94,7 @@ endchoice config ZRAM_DEF_COMP string + depends on ZRAM default "lzo-rle" if ZRAM_DEF_COMP_LZORLE default "lzo" if ZRAM_DEF_COMP_LZO default "lz4" if ZRAM_DEF_COMP_LZ4 -- GitLab From 32aa601bbf5b5a0fc39fafa7fbb370a8850ef18b Mon Sep 17 00:00:00 2001 From: Liu Shixin Date: Fri, 8 Nov 2024 18:01:47 +0800 Subject: [PATCH 071/456] UPSTREAM: zram: fix NULL pointer in comp_algorithm_show() LTP reported a NULL pointer dereference as followed: CPU: 7 UID: 0 PID: 5995 Comm: cat Kdump: loaded Not tainted 6.12.0-rc6+ #3 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __pi_strcmp+0x24/0x140 lr : zcomp_available_show+0x60/0x100 [zram] sp : ffff800088b93b90 x29: ffff800088b93b90 x28: 0000000000000001 x27: 0000000000400cc0 x26: 0000000000000ffe x25: ffff80007b3e2388 x24: 0000000000000000 x23: ffff80007b3e2390 x22: ffff0004041a9000 x21: ffff80007b3e2900 x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: ffff80007b3e2900 x9 : ffff80007b3cb280 x8 : 0101010101010101 x7 : 0000000000000000 x6 : 0000000000000000 x5 : 0000000000000040 x4 : 0000000000000000 x3 : 00656c722d6f7a6c x2 : 0000000000000000 x1 : ffff80007b3e2900 x0 : 0000000000000000 Call trace: __pi_strcmp+0x24/0x140 comp_algorithm_show+0x40/0x70 [zram] dev_attr_show+0x28/0x80 sysfs_kf_seq_show+0x90/0x140 kernfs_seq_show+0x34/0x48 seq_read_iter+0x1d4/0x4e8 kernfs_fop_read_iter+0x40/0x58 new_sync_read+0x9c/0x168 vfs_read+0x1a8/0x1f8 ksys_read+0x74/0x108 __arm64_sys_read+0x24/0x38 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0xc8/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x38/0x138 el0t_64_sync_handler+0xc0/0xc8 el0t_64_sync+0x188/0x190 The zram->comp_algs[ZRAM_PRIMARY_COMP] can be NULL in zram_add() if comp_algorithm_set() has not been called. User can access the zram device by sysfs after device_add_disk(), so there is a time window to trigger the NULL pointer dereference. Move it ahead device_add_disk() to make sure when user can access the zram device, it is ready. comp_algorithm_set() is protected by zram->init_lock in other places and no such problem. Link: https://lkml.kernel.org/r/20241108100147.3776123-1-liushixin2@huawei.com Fixes: 7ac07a26dea7 ("zram: preparation for multi-zcomp support") Signed-off-by: Liu Shixin Reviewed-by: Sergey Senozhatsky Cc: Jens Axboe Cc: Minchan Kim Signed-off-by: Andrew Morton (cherry picked from commit f364cdeb38938f9d03061682b8ff3779dd1730e5) BUG=none TEST=none Change-Id: I59f0d165f7aaaf447d9f735ed99f575255ba4a7d Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6047518 Reviewed-by: Brian Geffon Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/block/zram/zram_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index a5c9e626e4ef0..7c1feec6d6d71 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -2576,6 +2576,8 @@ static int zram_add(void) zram->disk->private_data = zram; snprintf(zram->disk->disk_name, 16, "zram%d", device_id); atomic_set(&zram->pp_in_progress, 0); + zram_comp_params_reset(zram); + comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor); /* Actual capacity set using sysfs (/sys/block/zram/disksize */ set_capacity(zram->disk, 0); @@ -2611,9 +2613,6 @@ static int zram_add(void) if (ret) goto out_cleanup_disk; - zram_comp_params_reset(zram); - comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor); - zram_debugfs_register(zram); pr_info("Added device: %s\n", zram->disk->disk_name); return device_id; -- GitLab From 0195ece7eaaa5fa79332fe31c52ebec5cede114f Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Fri, 17 May 2024 10:23:55 +0000 Subject: [PATCH 072/456] CHROMIUM: config: disable iTCO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iTCO is broken since skylake CPU generation. Disable it till it's fixed. BUG=b:330764064 TEST=(chroot) $ ./chromeos/scripts/kernelconfig olddefconfig Change-Id: I2045680ca4be21221f61945f4ef35fc428526e8f Signed-off-by: Lukasz Majczak Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5625957 Commit-Queue: Jędrzej Ciupis Tested-by: Jędrzej Ciupis Reviewed-by: Tim Van Patten Signed-off-by: Hubert Mazur --- .../chromeos/x86_64/chromeos-intel-denverton.flavour.config | 2 -- .../chromeos/x86_64/chromeos-intel-pineview.flavour.config | 2 -- 2 files changed, 4 deletions(-) diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config index 65943db87e3c9..fd6ec6272ed9a 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config @@ -38,8 +38,6 @@ CONFIG_INTEL_PMT_TELEMETRY=y CONFIG_INTEL_SOC_DTS_THERMAL=y CONFIG_INTEL_VSEC=y CONFIG_IRQ_REMAP=y -CONFIG_ITCO_VENDOR_SUPPORT=y -CONFIG_ITCO_WDT=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI=m diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config index 6743af243b660..d9ea65c9adf8d 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config @@ -68,8 +68,6 @@ CONFIG_INTEL_TELEMETRY=y CONFIG_INTEL_TURBO_MAX_3=y CONFIG_INTEL_VSEC=y CONFIG_IRQ_REMAP=y -CONFIG_ITCO_VENDOR_SUPPORT=y -CONFIG_ITCO_WDT=y CONFIG_IWL7000=m CONFIG_KERNEL_LZMA=y CONFIG_KEYBOARD_GPIO=y -- GitLab From d63511d8408909fda7ae2916dafdffcfd2f6018a Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Fri, 17 May 2024 10:46:42 +0000 Subject: [PATCH 073/456] CHROMIUM: config: Enable EC-based watchdog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable EC-based watchdog module for all platforms. BUG=b:287218810 TEST=(chroot) $ ./chromeos/scripts/kernelconfig olddefconfig Change-Id: Ia7aa2db2e5592b86c2cee3e24856a2c6b830e7d1 Signed-off-by: Lukasz Majczak Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5625958 Tested-by: Jędrzej Ciupis Commit-Queue: Jędrzej Ciupis Reviewed-by: Marek Maślanka Signed-off-by: Hubert Mazur --- chromeos/config/chromeos/base.config | 2 ++ .../chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/chromeos/config/chromeos/base.config b/chromeos/config/chromeos/base.config index cd9a1a0d0cc55..4be6e9710b679 100644 --- a/chromeos/config/chromeos/base.config +++ b/chromeos/config/chromeos/base.config @@ -59,6 +59,7 @@ CONFIG_CRC7=m CONFIG_CROS_EC=y CONFIG_CROS_EC_SENSORHUB=m CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_WATCHDOG=y CONFIG_CROS_HPS_I2C=m CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLAKE2B=y @@ -479,6 +480,7 @@ CONFIG_VFAT_FS=m CONFIG_VHOST_VSOCK=y CONFIG_VSOCKETS=y CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_SYSFS=y CONFIG_WERROR=y CONFIG_WIREGUARD=m CONFIG_XFRM_INTERFACE=m diff --git a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config index db1fa2ac1ce77..55b42a952469e 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config @@ -115,7 +115,6 @@ CONFIG_TMPFS=y CONFIG_TOUCHSCREEN_RM_TS=y CONFIG_USB4=y CONFIG_USB_ROLE_SWITCH=m -CONFIG_WATCHDOG_SYSFS=y CONFIG_X86_AMD_FREQ_SENSITIVITY=y CONFIG_X86_AMD_PSTATE=y CONFIG_X86_AMD_PSTATE_DEFAULT_MODE=2 -- GitLab From 195b3c9d0308c61c53bb9b344c3afbfec4e8a7e6 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Wed, 4 Dec 2024 13:43:49 +0000 Subject: [PATCH 074/456] CHROMIUM: fuse: add hung_request watchdog Add a hung_task watchdog to detect stalled request so that we can terminate the connection and avoid locking up the user-space. The core part is taken from [1], stripped down to bare minimum that we need, and converted to a task-based watchdog. [1] https://lore.kernel.org/all/20241114191332.669127-3-joannelkoong@gmail.com/ UPSTREAM-TASK=b:381968048 BUG=b:373731719 TEST=accessed gdrive via Files app on dedede kill -STOP $(pidof drivefs) .. long wait .. kill -CONT $(pidof drivefs) both before and during fuse req processing under lockdep, kasan Change-Id: I3b0c39af61af89a5e91ce2e21b39899dfb7364a4 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076182 Reviewed-by: Tomasz Figa Commit-Queue: Tomasz Figa Kcr-patch: ad21b060e9b5f2bdfcad3ad55133356d86cffe866fca4e5da9dae079.patch Signed-off-by: Hubert Mazur --- fs/fuse/dev.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 7 +++ fs/fuse/inode.c | 3 +- kernel/hung_task.c | 1 + 4 files changed, 143 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d0bf4bc63095c..e3bd9b60e6398 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -22,12 +22,17 @@ #include #include #include +#include +#include +#include #include MODULE_ALIAS_MISCDEV(FUSE_MINOR); MODULE_ALIAS("devname:fuse"); +#define FUSE_WATCHDOG_TIMEOUT (60 * HZ) + /* Ordinary requests have even IDs, while interrupts IDs are odd */ #define FUSE_INT_REQ_BIT (1ULL << 0) #define FUSE_REQ_ID_STEP (1ULL << 1) @@ -43,6 +48,131 @@ static struct fuse_dev *fuse_get_dev(struct file *file) return READ_ONCE(file->private_data); } +static unsigned long fuse_watchdog_timeout(void) +{ + unsigned long hang_check = sysctl_hung_task_timeout_secs; + + if (hang_check) + return hang_check * (HZ / 2); + return FUSE_WATCHDOG_TIMEOUT; +} + +static bool request_expired(struct fuse_conn *fc, struct list_head *list) +{ + struct fuse_req *req; + + req = list_first_entry_or_null(list, struct fuse_req, list); + if (!req) + return false; + return time_after(jiffies, req->create_time + fuse_watchdog_timeout()); +} + +static struct task_struct *fuse_watchdog_detach(struct fuse_conn *fc) +{ + struct task_struct *watchdog = NULL; + + spin_lock(&fc->lock); + if (!IS_ERR_OR_NULL(fc->watchdog)) + watchdog = get_task_struct(fc->watchdog); + fc->watchdog = NULL; + spin_unlock(&fc->lock); + + return watchdog; +} + +static int fuse_watchdog_fn(void *conn) +{ + struct task_struct *watchdog; + struct fuse_conn *fc = (struct fuse_conn *)conn; + struct fuse_iqueue *fiq = &fc->iq; + struct fuse_dev *fud; + struct fuse_pqueue *fpq; + int i; + + set_freezable(); + while (!kthread_should_stop()) { + bool connected; + bool expired; + + spin_lock(&fc->bg_lock); + connected = fc->connected; + spin_unlock(&fc->bg_lock); + if (!connected) + goto sleep; + + spin_lock(&fiq->lock); + expired = request_expired(fc, &fiq->pending); + spin_unlock(&fiq->lock); + if (expired) + goto abort_conn; + + spin_lock(&fc->bg_lock); + expired = request_expired(fc, &fc->bg_queue); + spin_unlock(&fc->bg_lock); + if (expired) + goto abort_conn; + + spin_lock(&fc->lock); + list_for_each_entry(fud, &fc->devices, entry) { + fpq = &fud->pq; + spin_lock(&fpq->lock); + if (request_expired(fc, &fpq->io)) + goto fpq_abort; + + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) { + if (request_expired(fc, &fpq->processing[i])) + goto fpq_abort; + } + spin_unlock(&fpq->lock); + } + spin_unlock(&fc->lock); + +sleep: + schedule_timeout_interruptible(fuse_watchdog_timeout()); + try_to_freeze(); + } + + watchdog = fuse_watchdog_detach(fc); + if (watchdog) + put_task_struct(watchdog); + return 0; + +fpq_abort: + spin_unlock(&fpq->lock); + spin_unlock(&fc->lock); +abort_conn: + watchdog = fuse_watchdog_detach(fc); + if (watchdog) + put_task_struct(watchdog); + + pr_err("%s: connection timeout\n", current->comm); + fuse_abort_conn(fc); + return 0; +} + +void init_fuse_watchdog(struct fuse_conn *fc) +{ + /* PIDs can have multiple connections, distinguish them */ + static atomic_t num; + + fc->watchdog = kthread_create(fuse_watchdog_fn, fc, + "fusedog%d/%d", + atomic_inc_return(&num), + task_pid_nr(current)); + if (!IS_ERR_OR_NULL(fc->watchdog)) + wake_up_process(fc->watchdog); +} + +void terminate_fuse_watchdog(struct fuse_conn *fc) +{ + struct task_struct *watchdog = fuse_watchdog_detach(fc); + + if (watchdog) { + kthread_stop(watchdog); + put_task_struct(watchdog); + } +} + static void fuse_request_init(struct fuse_mount *fm, struct fuse_req *req) { INIT_LIST_HEAD(&req->list); @@ -51,6 +181,7 @@ static void fuse_request_init(struct fuse_mount *fm, struct fuse_req *req) refcount_set(&req->count, 1); __set_bit(FR_PENDING, &req->flags); req->fm = fm; + req->create_time = jiffies; } static struct fuse_req *fuse_request_alloc(struct fuse_mount *fm, gfp_t flags) @@ -2163,6 +2294,8 @@ void fuse_abort_conn(struct fuse_conn *fc) { struct fuse_iqueue *fiq = &fc->iq; + terminate_fuse_watchdog(fc); + spin_lock(&fc->lock); if (fc->connected) { struct fuse_dev *fud; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e9be849628f63..1671a4cf74988 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -479,6 +479,9 @@ struct fuse_req { /** fuse_mount this request belongs to */ struct fuse_mount *fm; + + /** When (in jiffies) the request was created */ + unsigned long create_time; }; struct fuse_iqueue; @@ -965,6 +968,8 @@ struct fuse_conn { /** Protects passthrough_req */ spinlock_t passthrough_req_lock; + + struct task_struct *watchdog; }; /* @@ -1222,6 +1227,8 @@ void fuse_request_end(struct fuse_req *req); /* Abort all requests */ void fuse_abort_conn(struct fuse_conn *fc); void fuse_wait_aborted(struct fuse_conn *fc); +void init_fuse_watchdog(struct fuse_conn *fc); +void terminate_fuse_watchdog(struct fuse_conn *fc); /** * Invalidate inode attributes diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 0ef81978dddb8..fb865a4095a91 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1120,6 +1120,7 @@ void fuse_conn_put(struct fuse_conn *fc) struct fuse_iqueue *fiq = &fc->iq; struct fuse_sync_bucket *bucket; + terminate_fuse_watchdog(fc); if (IS_ENABLED(CONFIG_FUSE_DAX)) fuse_dax_conn_free(fc); if (fiq->ops->release) @@ -1875,7 +1876,7 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) fc->destroy = ctx->destroy; fc->no_control = ctx->no_control; fc->no_force_umount = ctx->no_force_umount; - fc->no_daemon = ctx->no_daemon; + init_fuse_watchdog(fc); err = -ENOMEM; root = fuse_get_root_inode(sb, ctx->rootmode, ctx->root_bpf, diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 98a7e7477c3d3..38e8176e2d43d 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -44,6 +44,7 @@ static int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; * Zero means infinite timeout - no checking done: */ unsigned long __read_mostly sysctl_hung_task_timeout_secs = CONFIG_DEFAULT_HUNG_TASK_TIMEOUT; +EXPORT_SYMBOL_GPL(sysctl_hung_task_timeout_secs); /* * Zero (default value) means use sysctl_hung_task_timeout_secs: -- GitLab From 5923881496ef5f7a5105d96ad191f777516b8e7c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 28 Sep 2023 16:55:35 +0800 Subject: [PATCH 075/456] UPSTREAM: arm64: dts: mediatek: mt8183-kukui: Add PMIC regulator supplies The PMIC regulator node is missing regulator supplies. Now that the binding supports them, add all the power rail supplies. Most of them are fed from a system-wide semi-regulated power rail. A couple LDOs are fed from the PMIC's own buck regulator outputs. Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230928085537.3246669-13-wenst@chromium.org Signed-off-by: Matthias Brugger (cherry picked from commit 2a99858c172e5a391572492fdfac02180ab3b772) BUG=b:286326583, b:362203280 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I1096cc559b3a4ee4a669d0a32fb22c345e6bd658 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072609 Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 8607f4881b90c..9af3d0e96a14a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -103,6 +103,14 @@ regulator-max-microvolt = <3300000>; }; + /* system wide semi-regulated power rail from charger */ + reg_vsys: regulator-vsys { + compatible = "regulator-fixed"; + regulator-name = "vsys"; + regulator-always-on; + regulator-boot-on; + }; + reserved_memory: reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -440,6 +448,26 @@ Avdd-supply = <&mt6358_vaud28_reg>; }; +&mt6358regulator { + vsys-ldo1-supply = <®_vsys>; + vsys-ldo2-supply = <®_vsys>; + vsys-ldo3-supply = <®_vsys>; + vsys-vcore-supply = <®_vsys>; + vsys-vdram1-supply = <®_vsys>; + vsys-vgpu-supply = <®_vsys>; + vsys-vmodem-supply = <®_vsys>; + vsys-vpa-supply = <®_vsys>; + vsys-vproc11-supply = <®_vsys>; + vsys-vproc12-supply = <®_vsys>; + vsys-vs1-supply = <®_vsys>; + vsys-vs2-supply = <®_vsys>; + vs1-ldo1-supply = <&mt6358_vs1_reg>; + vs2-ldo1-supply = <&mt6358_vdram1_reg>; + vs2-ldo2-supply = <&mt6358_vs2_reg>; + vs2-ldo3-supply = <&mt6358_vs2_reg>; + vs2-ldo4-supply = <&mt6358_vs2_reg>; +}; + &mt6358_vgpu_reg { regulator-max-microvolt = <900000>; -- GitLab From 927202318dcf40e4ec52a65d19beea4a89efaf89 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 13 Sep 2023 16:44:56 +0800 Subject: [PATCH 076/456] UPSTREAM: arm64: dts: mediatek: mt6358: Merge ldo_vcn33_* regulators The ldo_vcn33_bt and ldo_vcn33_wifi regulators are actually the same regulator, having the same voltage setting and output pin. There are simply two enable bits that are ORed together to enable the regulator. Having two regulators representing the same output pin is misleading from a design matching standpoint, and also error-prone in driver implementations. Now that the bindings have these two merged, merge them in the device tree as well. Neither vcn33 regulators are referenced in upstream device trees. As far as hardware designs go, none of the Chromebooks using MT8183 w/ MT6358 use this output. Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 9a8014b1d4d2b1ffc53a844e07dfdd814b70dad0) BUG=b:286326583, b:362203280 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ib9c9f67a3d134140c724ce374abb052201851a47 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072610 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt6358.dtsi | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi index 9a549069a483e..48a2062c1485b 100644 --- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi @@ -309,15 +309,8 @@ regulator-enable-ramp-delay = <120>; }; - mt6358_vcn33_bt_reg: ldo_vcn33_bt { - regulator-name = "vcn33_bt"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3500000>; - regulator-enable-ramp-delay = <270>; - }; - - mt6358_vcn33_wifi_reg: ldo_vcn33_wifi { - regulator-name = "vcn33_wifi"; + mt6358_vcn33_reg: ldo_vcn33 { + regulator-name = "vcn33"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <270>; -- GitLab From def6241c8de735457844160d190c9b43bc1eec19 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 30 Nov 2023 15:40:30 +0800 Subject: [PATCH 077/456] UPSTREAM: arm64: dts: mt6358: Drop bogus "regulator-fixed" compatible properties Whether a regulator under the MT6358 PMIC is a fixed regulator or not is derived from the node name. Compatible string properties are not used. This causes validation errors after the regulator binding is converted to DT schema. Drop the bogus "regulator-fixed" compatible properties from the PMIC's regulator sub-nodes. Fixes: 9f8872221674 ("arm64: dts: mt6358: add PMIC MT6358 related nodes") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20231130074032.913511-3-wenst@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 26af327371a992f3eef4d1de1df888d3ebc05d00) BUG=b:286326583, b:362203280 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: If50a96f29e01fa88bd77790507ce904e93c5111f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072611 Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt6358.dtsi | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi index 48a2062c1485b..bdf4a3ef819b0 100644 --- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi @@ -133,7 +133,6 @@ }; mt6358_vrf12_reg: ldo_vrf12 { - compatible = "regulator-fixed"; regulator-name = "vrf12"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -141,7 +140,6 @@ }; mt6358_vio18_reg: ldo_vio18 { - compatible = "regulator-fixed"; regulator-name = "vio18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -158,7 +156,6 @@ }; mt6358_vcamio_reg: ldo_vcamio { - compatible = "regulator-fixed"; regulator-name = "vcamio"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -173,7 +170,6 @@ }; mt6358_vcn18_reg: ldo_vcn18 { - compatible = "regulator-fixed"; regulator-name = "vcn18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -181,7 +177,6 @@ }; mt6358_vfe28_reg: ldo_vfe28 { - compatible = "regulator-fixed"; regulator-name = "vfe28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -198,7 +193,6 @@ }; mt6358_vcn28_reg: ldo_vcn28 { - compatible = "regulator-fixed"; regulator-name = "vcn28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -223,7 +217,6 @@ }; mt6358_vxo22_reg: ldo_vxo22 { - compatible = "regulator-fixed"; regulator-name = "vxo22"; regulator-min-microvolt = <2200000>; regulator-max-microvolt = <2200000>; @@ -239,7 +232,6 @@ }; mt6358_vaux18_reg: ldo_vaux18 { - compatible = "regulator-fixed"; regulator-name = "vaux18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -254,7 +246,6 @@ }; mt6358_vbif28_reg: ldo_vbif28 { - compatible = "regulator-fixed"; regulator-name = "vbif28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -285,7 +276,6 @@ }; mt6358_vio28_reg: ldo_vio28 { - compatible = "regulator-fixed"; regulator-name = "vio28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -293,7 +283,6 @@ }; mt6358_va12_reg: ldo_va12 { - compatible = "regulator-fixed"; regulator-name = "va12"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -302,7 +291,6 @@ }; mt6358_vrf18_reg: ldo_vrf18 { - compatible = "regulator-fixed"; regulator-name = "vrf18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -338,7 +326,6 @@ }; mt6358_vaud28_reg: ldo_vaud28 { - compatible = "regulator-fixed"; regulator-name = "vaud28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; -- GitLab From ab58ee5109979365317a6563f9085fdd747dfbbc Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 25 Jun 2024 17:54:38 +0800 Subject: [PATCH 078/456] UPSTREAM: arm64: dts: mt8183-kukui: clean up regulator tree Some regulators in the kukui device tree are modeled incorrectly. Some are missing supplies and some switches are incorrectly modeled as voltage regulators. A pass-through was incorrectly modeled as a regulator. Add supplies where missing, remove voltage constraints for "switches", and drop the "bl_pp5000" pass-through. This depends on commit 2a99858c172e ("arm64: dts: mediatek: mt8183-kukui: Add PMIC regulator supplies") for reg_vsys. Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board") Fixes: f15722c0fef0 ("arm64: dts: mt8183: Add pwm and backlight node") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20240625095441.3474194-1-wenst@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit f5843dc83583d58e13e6851c70ad8371f036dc35) BUG=b:286326583, b:362203280 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ieae51863620cbbadc22ae8def2f67224744129de Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072612 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 9af3d0e96a14a..cb52584ae610e 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -24,7 +24,7 @@ backlight_lcd0: backlight_lcd0 { compatible = "pwm-backlight"; pwms = <&pwm0 0 500000>; - power-supply = <&bl_pp5000>; + power-supply = <®_vsys>; enable-gpios = <&pio 176 0>; brightness-levels = <0 1023>; num-interpolated-steps = <1023>; @@ -47,10 +47,9 @@ it6505_pp18_reg: regulator0 { compatible = "regulator-fixed"; regulator-name = "it6505_pp18"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; gpio = <&pio 178 0>; enable-active-high; + vin-supply = <&pp1800_alw>; }; lcd_pp3300: regulator1 { @@ -62,27 +61,16 @@ regulator-boot-on; }; - bl_pp5000: regulator2 { - compatible = "regulator-fixed"; - regulator-name = "bl_pp5000"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - regulator-boot-on; - }; - mmc1_fixed_power: regulator3 { compatible = "regulator-fixed"; regulator-name = "mmc1_power"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + vin-supply = <&pp3300_alw>; }; mmc1_fixed_io: regulator4 { compatible = "regulator-fixed"; regulator-name = "mmc1_io"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + vin-supply = <&pp1800_alw>; }; pp1800_alw: regulator5 { @@ -92,6 +80,7 @@ regulator-boot-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + vin-supply = <®_vsys>; }; pp3300_alw: regulator6 { @@ -101,6 +90,7 @@ regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + vin-supply = <®_vsys>; }; /* system wide semi-regulated power rail from charger */ -- GitLab From 6d3c85efcc1ad71e8797253fe131b2182b7b38a7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 12 Apr 2024 15:30:42 +0800 Subject: [PATCH 079/456] UPSTREAM: dt-bindings: net: bluetooth: Add MediaTek MT7921S SDIO Bluetooth The MediaTek MT7921S is a WiFi/Bluetooth combo chip that works over SDIO. WiFi and Bluetooth are separate SDIO functions within the chip. While the Bluetooth SDIO function is fully discoverable, the chip has a pin that can reset just the Bluetooth core, as opposed to the full chip. This should be described in the device tree. Add a device tree binding for the Bluetooth SDIO function of the MT7921S specifically to document the reset line. This binding is based on the MMC controller binding, which specifies one device node per SDIO function. Cc: Sean Wang Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rob Herring Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit defa9cca02fd5904ff26f6b8ce65c72002570f69) BUG=none TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Id6ff8d0638063749c5ee31524e6dc267e0a8f0f8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072613 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../bluetooth/mediatek,mt7921s-bluetooth.yaml | 55 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml diff --git a/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml new file mode 100644 index 0000000000000..67ff7caad599f --- /dev/null +++ b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/bluetooth/mediatek,mt7921s-bluetooth.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT7921S Bluetooth + +maintainers: + - Sean Wang + +description: + MT7921S is an SDIO-attached dual-radio WiFi+Bluetooth Combo chip; each + function is its own SDIO function on a shared SDIO interface. The chip + has two dedicated reset lines, one for each function core. + This binding only covers the Bluetooth SDIO function, with one device + node describing only this SDIO function. + +allOf: + - $ref: bluetooth-controller.yaml# + +properties: + compatible: + enum: + - mediatek,mt7921s-bluetooth + + reg: + const: 2 + + reset-gpios: + maxItems: 1 + description: + An active-low reset line for the Bluetooth core; on typical M.2 + key E modules this is the W_DISABLE2# pin. + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + mmc { + #address-cells = <1>; + #size-cells = <0>; + + bluetooth@2 { + compatible = "mediatek,mt7921s-bluetooth"; + reg = <2>; + reset-gpios = <&pio 8 GPIO_ACTIVE_LOW>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 1995d1607dc1f..e8b8ce6e64f82 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13391,6 +13391,7 @@ M: Sean Wang L: linux-bluetooth@vger.kernel.org L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml F: Documentation/devicetree/bindings/net/mediatek-bluetooth.txt F: drivers/bluetooth/btmtkuart.c -- GitLab From ee4f12ca4a204fba420b1b45f6b25830ed0aee10 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 8 Oct 2024 16:27:20 +0800 Subject: [PATCH 080/456] UPSTREAM: Bluetooth: btmtksdio: Lookup device node only as fallback If the device tree is properly written, the SDIO function device node should be correctly defined, and the mmc core in Linux should correctly tie it to the device being probed. Only fall back to searching for the device node by compatible if the original device node tied to the device is incorrect, as seen in older device trees. Signed-off-by: Chen-Yu Tsai Tested-by: AngeloGioacchino Del Regno # Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit 6d83d955f6a1538aeeb810c2fa9c1aa91322839b) BUG=none TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I309586ba08fc02b61c7e8eaf80d41bc82403a4e4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072614 Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/bluetooth/btmtksdio.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 2d70f4ef974f0..9462b8e0e832a 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -1328,6 +1328,8 @@ static int btmtksdio_probe(struct sdio_func *func, { struct btmtksdio_dev *bdev; struct hci_dev *hdev; + struct device_node *old_node; + bool restore_node; int err; bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL); @@ -1411,13 +1413,24 @@ static int btmtksdio_probe(struct sdio_func *func, if (err) bt_dev_err(hdev, "failed to initialize device wakeup"); - bdev->dev->of_node = of_find_compatible_node(NULL, NULL, - "mediatek,mt7921s-bluetooth"); + restore_node = false; + if (!of_device_is_compatible(bdev->dev->of_node, "mediatek,mt7921s-bluetooth")) { + restore_node = true; + old_node = bdev->dev->of_node; + bdev->dev->of_node = of_find_compatible_node(NULL, NULL, + "mediatek,mt7921s-bluetooth"); + } + bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(bdev->reset)) err = PTR_ERR(bdev->reset); + if (restore_node) { + of_node_put(bdev->dev->of_node); + bdev->dev->of_node = old_node; + } + return err; } -- GitLab From aae6cd1d3abcfc283af7975e4a0d8c09662dc83b Mon Sep 17 00:00:00 2001 From: Pin-yen Lin Date: Wed, 27 Nov 2024 18:55:43 +0800 Subject: [PATCH 081/456] FROMGIT: wifi: mwifiex: decrease timeout waiting for host sleep from 10s to 5s In commit 52250cbee7f6 ("mwifiex: use timeout variant for wait_event_interruptible") it was noted that sometimes we seemed to miss the signal that our host sleep settings took effect. A 10 second timeout was added to the code to make sure we didn't hang forever waiting. It appears that this problem still exists and we hit the timeout sometimes for Chromebooks in the field. Recently on ChromeOS we've started setting the DPM watchdog to trip if full system suspend takes over 10 seconds. Given the timeout in the original patch, obviously we're hitting the DPM watchdog before mwifiex gets a chance to timeout. While we could increase the DPM watchdog in ChromeOS to avoid this problem, it's probably better to simply decrease the timeout. Any time we're waiting several seconds for the firmware to respond it's likely that the firmware won't ever respond. With that in mind, decrease the timeout in mwifiex from 10 seconds to 5 seconds. Suggested-by: Doug Anderson Signed-off-by: Pin-yen Lin Reviewed-by: Douglas Anderson Acked-by: Brian Norris Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241127105709.4014302-1-treapking@chromium.org (cherry picked from commit f143cece43dd05fa651fa14d97726b67b92e9d03 git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main) BUG=b:349043911 TEST=CQ Change-Id: I6a6533010d401c1b126888a0c0d37d607fc11c73 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6081072 Reviewed-by: Brian Norris Commit-Queue: Brian Norris Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index a2ad2b53f0168..a46581a5a8e1d 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -548,7 +548,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q, adapter->hs_activate_wait_q_woken, - (10 * HZ)) <= 0) { + (5 * HZ)) <= 0) { mwifiex_dbg(adapter, ERROR, "hs_activate_wait_q terminated\n"); return false; -- GitLab From 3666214b2866f4b2d25dbd73769cab0515017d98 Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Mon, 9 Dec 2024 08:49:05 -0800 Subject: [PATCH 082/456] CHROMIUM: usb: typec: cros_ec_ucsi: Cancel work on suspend To avoid spurious wakes, cancel write recovery when we suspend or destroy the UCSI object. BUG=b:381146486 UPSTREAM-TASK=b:335338337 TEST=Build + quick suspend on Brox Change-Id: I15a77ab6c64052bd041f72135134255a5d146592 Signed-off-by: Abhishek Pandit-Subedi Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6080582 Auto-Submit: Abhishek Pandit-Subedi Reviewed-by: Shyam Sundar Radjacoumar Tested-by: Abhishek Pandit-Subedi Reviewed-by: Abhishek Pandit-Subedi Commit-Queue: Abhishek Pandit-Subedi Signed-off-by: Hubert Mazur --- drivers/usb/typec/ucsi/cros_ec_ucsi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c index 476a2b73fe7a1..afecdcb1d3938 100644 --- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c +++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c @@ -240,6 +240,7 @@ static int cros_ucsi_event(struct notifier_block *nb, static void cros_ucsi_destroy(struct cros_ucsi_data *udata) { cros_usbpd_unregister_notify(&udata->nb); + cancel_delayed_work_sync(&udata->write_tmo); cancel_work_sync(&udata->work); ucsi_destroy(udata->ucsi); } @@ -308,6 +309,7 @@ static int __maybe_unused cros_ucsi_suspend(struct device *dev) { struct cros_ucsi_data *udata = dev_get_drvdata(dev); + cancel_delayed_work_sync(&udata->write_tmo); cancel_work_sync(&udata->work); return 0; -- GitLab From d112d1194d2edda6c0d357fb1fe97f5ddc9512a3 Mon Sep 17 00:00:00 2001 From: Gavin Liu Date: Tue, 7 May 2024 10:00:37 +0800 Subject: [PATCH 083/456] UPSTREAM: optee: add timeout value to optee_notif_wait() to support timeout Add timeout value to support self waking when timeout to avoid waiting indefinitely. Signed-off-by: Gavin Liu Reviewed-by: Sumit Garg Signed-off-by: Jens Wiklander (cherry picked from commit 14ca6401d8703725c7297dcc4bf8de73323411ac) BUG=b:375554683 TEST=emerge-rauru chromeos-kernel-6_6 Signed-off-by: Gavin Liu Change-Id: If9cac87ba0dfff87e7cfe679c8a4f27bf840efba Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073297 Reviewed-by: Yu-Che Cheng Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-by: Chen-Yu Tsai Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/tee/optee/notif.c | 9 +++++++-- drivers/tee/optee/optee_private.h | 5 ++++- drivers/tee/optee/optee_rpc_cmd.h | 1 + drivers/tee/optee/rpc.c | 10 ++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c index 05212842b0a50..d5e5c06456093 100644 --- a/drivers/tee/optee/notif.c +++ b/drivers/tee/optee/notif.c @@ -29,7 +29,7 @@ static bool have_key(struct optee *optee, u_int key) return false; } -int optee_notif_wait(struct optee *optee, u_int key) +int optee_notif_wait(struct optee *optee, u_int key, u32 timeout) { unsigned long flags; struct notif_entry *entry; @@ -70,7 +70,12 @@ int optee_notif_wait(struct optee *optee, u_int key) * Unlock temporarily and wait for completion. */ spin_unlock_irqrestore(&optee->notif.lock, flags); - wait_for_completion(&entry->c); + if (timeout != 0) { + if (!wait_for_completion_timeout(&entry->c, timeout)) + rc = -ETIMEDOUT; + } else { + wait_for_completion(&entry->c); + } spin_lock_irqsave(&optee->notif.lock, flags); list_del(&entry->link); diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index 6bb5cae096886..1ffe372db585d 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -26,6 +26,9 @@ #define TEEC_ERROR_BUSY 0xFFFF000D #define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 +/* API Return Codes are from the GP TEE Internal Core API Specification */ +#define TEE_ERROR_TIMEOUT 0xFFFF3001 + #define TEEC_ORIGIN_COMMS 0x00000002 /* @@ -232,7 +235,7 @@ struct optee_call_ctx { int optee_notif_init(struct optee *optee, u_int max_key); void optee_notif_uninit(struct optee *optee); -int optee_notif_wait(struct optee *optee, u_int key); +int optee_notif_wait(struct optee *optee, u_int key, u32 timeout); int optee_notif_send(struct optee *optee, u_int key); u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, diff --git a/drivers/tee/optee/optee_rpc_cmd.h b/drivers/tee/optee/optee_rpc_cmd.h index f3f06e0994a75..4576751b490c3 100644 --- a/drivers/tee/optee/optee_rpc_cmd.h +++ b/drivers/tee/optee/optee_rpc_cmd.h @@ -41,6 +41,7 @@ * Waiting on notification * [in] value[0].a OPTEE_RPC_NOTIFICATION_WAIT * [in] value[0].b notification value + * [in] value[0].c timeout in milliseconds or 0 if no timeout * * Sending a synchronous notification * [in] value[0].a OPTEE_RPC_NOTIFICATION_SEND diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index e69bc6380683a..13f63c0a7f049 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -130,6 +130,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, static void handle_rpc_func_cmd_wq(struct optee *optee, struct optee_msg_arg *arg) { + int rc = 0; + if (arg->num_params != 1) goto bad; @@ -139,7 +141,8 @@ static void handle_rpc_func_cmd_wq(struct optee *optee, switch (arg->params[0].u.value.a) { case OPTEE_RPC_NOTIFICATION_WAIT: - if (optee_notif_wait(optee, arg->params[0].u.value.b)) + rc = optee_notif_wait(optee, arg->params[0].u.value.b, arg->params[0].u.value.c); + if (rc) goto bad; break; case OPTEE_RPC_NOTIFICATION_SEND: @@ -153,7 +156,10 @@ static void handle_rpc_func_cmd_wq(struct optee *optee, arg->ret = TEEC_SUCCESS; return; bad: - arg->ret = TEEC_ERROR_BAD_PARAMETERS; + if (rc == -ETIMEDOUT) + arg->ret = TEE_ERROR_TIMEOUT; + else + arg->ret = TEEC_ERROR_BAD_PARAMETERS; } static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg) -- GitLab From 1168de932cc33602fb4e33ea766d6091089e6fb7 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 25 Oct 2023 10:46:12 +0200 Subject: [PATCH 084/456] UPSTREAM: regulator: fixed: add support for under-voltage IRQ Add interrupt support for under-voltage notification. This functionality can be used on systems capable to detect under-voltage state and having enough capacity to let the SoC do some emergency preparation. This change enforce default policy to shutdown system as soon as interrupt is triggered. Signed-off-by: Oleksij Rempel Link: https://lore.kernel.org/r/20231025084614.3092295-6-o.rempel@pengutronix.de Signed-off-by: Mark Brown (cherry picked from commit ecb6f1f456144e9ade5a492192287decbeef4cfe) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I2b1222d88e6b825fd57528d1e4778da5052852d9 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072618 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/regulator/fixed.c | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 55130efae9b8b..cb93e5cdcfa94 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,8 @@ #include #include +/* Default time in millisecond to wait for emergency shutdown */ +#define FV_DEF_EMERG_SHUTDWN_TMO 10 struct fixed_voltage_data { struct regulator_desc desc; @@ -105,6 +108,49 @@ static int reg_is_enabled(struct regulator_dev *rdev) return priv->enable_counter > 0; } +static irqreturn_t reg_fixed_under_voltage_irq_handler(int irq, void *data) +{ + struct fixed_voltage_data *priv = data; + struct regulator_dev *rdev = priv->dev; + + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, + NULL); + + return IRQ_HANDLED; +} + +/** + * reg_fixed_get_irqs - Get and register the optional IRQ for fixed voltage + * regulator. + * @dev: Pointer to the device structure. + * @priv: Pointer to fixed_voltage_data structure containing private data. + * + * This function tries to get the IRQ from the device firmware node. + * If it's an optional IRQ and not found, it returns 0. + * Otherwise, it attempts to request the threaded IRQ. + * + * Return: 0 on success, or error code on failure. + */ +static int reg_fixed_get_irqs(struct device *dev, + struct fixed_voltage_data *priv) +{ + int ret; + + ret = fwnode_irq_get(dev_fwnode(dev), 0); + /* This is optional IRQ. If not found we will get -EINVAL */ + if (ret == -EINVAL) + return 0; + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get IRQ\n"); + + ret = devm_request_threaded_irq(dev, ret, NULL, + reg_fixed_under_voltage_irq_handler, + IRQF_ONESHOT, "under-voltage", priv); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ\n"); + + return 0; +} /** * of_get_fixed_voltage_config - extract fixed_voltage_config structure info @@ -294,6 +340,10 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name, drvdata->desc.fixed_uV); + ret = reg_fixed_get_irqs(dev, drvdata); + if (ret) + return ret; + return 0; } -- GitLab From 8108ef746cd7fe854cdfbcbdfda9e911586cb0d8 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 29 Apr 2024 18:40:09 -0500 Subject: [PATCH 085/456] UPSTREAM: regulator: devres: add API for reference voltage supplies A common use case for regulators is to supply a reference voltage to an analog input or output device. This adds a new devres API to get, enable, and get the voltage in a single call. This allows eliminating boilerplate code in drivers that use reference supplies in this way. Signed-off-by: David Lechner Link: https://lore.kernel.org/r/20240429-regulator-get-enable-get-votlage-v2-1-b1f11ab766c1@baylibre.com Signed-off-by: Mark Brown (cherry picked from commit b250c20b64290808aa4b5cc6d68819a7ee28237f) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I9a18d111631827cfc9834f161477fceb523e4792 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072619 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- .../driver-api/driver-model/devres.rst | 1 + drivers/regulator/devres.c | 59 +++++++++++++++++++ include/linux/regulator/consumer.h | 7 +++ 3 files changed, 67 insertions(+) diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 8be086b3f8297..3fe1711dd587c 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -426,6 +426,7 @@ REGULATOR devm_regulator_bulk_put() devm_regulator_get() devm_regulator_get_enable() + devm_regulator_get_enable_read_voltage() devm_regulator_get_enable_optional() devm_regulator_get_exclusive() devm_regulator_get_optional() diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 90bb0d178885a..4f290b9b559b9 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -145,6 +145,65 @@ struct regulator *devm_regulator_get_optional(struct device *dev, } EXPORT_SYMBOL_GPL(devm_regulator_get_optional); +/** + * devm_regulator_get_enable_read_voltage - Resource managed regulator get and + * enable that returns the voltage + * @dev: device to supply + * @id: supply name or regulator ID. + * + * Get and enable regulator for duration of the device life-time. + * regulator_disable() and regulator_put() are automatically called on driver + * detach. See regulator_get_optional(), regulator_enable(), and + * regulator_get_voltage() for more information. + * + * This is a convenience function for supplies that provide a reference voltage + * where the consumer driver just needs to know the voltage and keep the + * regulator enabled. + * + * In cases where the supply is not strictly required, callers can check for + * -ENODEV error and handle it accordingly. + * + * Returns: voltage in microvolts on success, or an error code on failure. + */ +int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id) +{ + struct regulator *r; + int ret; + + /* + * Since we need a real voltage, we use devm_regulator_get_optional() + * rather than getting a dummy regulator with devm_regulator_get() and + * then letting regulator_get_voltage() fail with -EINVAL. This way, the + * caller can handle the -ENODEV error code if needed instead of the + * ambiguous -EINVAL. + */ + r = devm_regulator_get_optional(dev, id); + if (IS_ERR(r)) + return PTR_ERR(r); + + ret = regulator_enable(r); + if (ret) + goto err_regulator_put; + + ret = devm_add_action_or_reset(dev, regulator_action_disable, r); + if (ret) + goto err_regulator_put; + + ret = regulator_get_voltage(r); + if (ret < 0) + goto err_release_action; + + return 0; + +err_release_action: + devm_release_action(dev, regulator_action_disable, r); +err_regulator_put: + devm_regulator_put(r); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_regulator_get_enable_read_voltage); + static int devm_regulator_match(struct device *dev, void *res, void *data) { struct regulator **r = res; diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 25d0684d37b3e..9a2f1e9a94a85 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -209,6 +209,7 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev, const char *id); int devm_regulator_get_enable(struct device *dev, const char *id); int devm_regulator_get_enable_optional(struct device *dev, const char *id); +int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); void devm_regulator_put(struct regulator *regulator); @@ -374,6 +375,12 @@ static inline int devm_regulator_get_enable_optional(struct device *dev, return 0; } +static inline int devm_regulator_get_enable_read_voltage(struct device *dev, + const char *id) +{ + return -ENODEV; +} + static inline struct regulator *__must_check regulator_get_optional(struct device *dev, const char *id) { -- GitLab From 351cb7d6639f97e11c2f4313db21159787f38721 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 6 May 2024 10:59:15 -0500 Subject: [PATCH 086/456] UPSTREAM: regulator: devres: fix devm_regulator_get_enable_read_voltage() return The devm_regulator_get_enable_read_voltage() function is supposed to return the voltage that the regulator is currently set to. However, it currently returns 0. Fixes: b250c20b6429 ("regulator: devres: add API for reference voltage supplies") Signed-off-by: David Lechner Link: https://lore.kernel.org/r/20240506-regulator-devm_regulator_get_enable_read_voltage-fixes-v1-1-356cdd152067@baylibre.com Signed-off-by: Mark Brown (cherry picked from commit 257b2335eebf51e318db1f3b2d023512da46fa66) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Iad988081bbea537fd0bb3d3f8c770850caeb6ccc Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072620 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/devres.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 4f290b9b559b9..7111c46e9de13 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -193,7 +193,7 @@ int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id) if (ret < 0) goto err_release_action; - return 0; + return ret; err_release_action: devm_release_action(dev, regulator_action_disable, r); -- GitLab From 9d52b52c774388bb94ae5d3ff180b9ec487b6513 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 16 Jun 2024 11:53:55 +0100 Subject: [PATCH 087/456] UPSTREAM: regulator: core: Add helper for allow HW access to enable/disable regulator Add a helper function that allow regulator consumers to allow low-level HW access, in order to enable/disable regulator in atomic context. The use-case for RZ/G2L SoC is to enable VBUS selection register based on vbus detection that happens in interrupt context. Signed-off-by: Biju Das Link: https://patch.msgid.link/20240616105402.45211-4-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown (cherry picked from commit 1cb7d29157603561af4c38535e936850ceb99f0f) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I610e40372680ed47d1e5f558eb359ec90496673a Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072621 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- Documentation/power/regulator/consumer.rst | 6 +++++ drivers/regulator/core.c | 28 ++++++++++++++++++++++ include/linux/regulator/consumer.h | 7 ++++++ 3 files changed, 41 insertions(+) diff --git a/Documentation/power/regulator/consumer.rst b/Documentation/power/regulator/consumer.rst index 85c2bf5ac07ed..9d2416f63f6e3 100644 --- a/Documentation/power/regulator/consumer.rst +++ b/Documentation/power/regulator/consumer.rst @@ -227,3 +227,9 @@ directly written to the voltage selector register, use:: int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector); + +To access the hardware for enabling/disabling the regulator, consumers must +use regulator_get_exclusive(), as it can't work if there's more than one +consumer. To enable/disable regulator use:: + + int regulator_hardware_enable(struct regulator *regulator, bool enable); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 352131d2df4ca..35bd701ded1cc 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3395,6 +3395,34 @@ int regulator_list_hardware_vsel(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); +/** + * regulator_hardware_enable - access the HW for enable/disable regulator + * @regulator: regulator source + * @enable: true for enable, false for disable + * + * Request that the regulator be enabled/disabled with the regulator output at + * the predefined voltage or current value. + * + * On success 0 is returned, otherwise a negative errno is returned. + */ +int regulator_hardware_enable(struct regulator *regulator, bool enable) +{ + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + int ret = -EOPNOTSUPP; + + if (!rdev->exclusive || !ops || !ops->enable || !ops->disable) + return ret; + + if (enable) + ret = ops->enable(rdev); + else + ret = ops->disable(rdev); + + return ret; +} +EXPORT_SYMBOL_GPL(regulator_hardware_enable); + /** * regulator_get_linear_step - return the voltage step size between VSEL values * @regulator: regulator source diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 9a2f1e9a94a85..a6cdd3ac12ad9 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -295,6 +295,7 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, unsigned *vsel_mask); int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector); +int regulator_hardware_enable(struct regulator *regulator, bool enable); /* regulator notifier block */ int regulator_register_notifier(struct regulator *regulator, @@ -624,6 +625,12 @@ static inline int regulator_list_hardware_vsel(struct regulator *regulator, return -EOPNOTSUPP; } +static inline int regulator_hardware_enable(struct regulator *regulator, + bool enable) +{ + return -EOPNOTSUPP; +} + static inline int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb) { -- GitLab From a8cc255b6aa19af0c6560801db6754cc118647c6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 22 Aug 2024 15:20:44 +0800 Subject: [PATCH 088/456] UPSTREAM: regulator: Clarify error message for "id == NULL" in _regulator_get() The original error message simply said "get() with no identifier" without any context as to what was requested or what device the request was related to. The only thing the user or developer could do was grep for the message in the full source tree. Amend the error message to be more specific, and also use dev_* to associate the error message with a device. Signed-off-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240822072047.3097740-2-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit ad9d7a82901d9cea756b8666035b30ca41728e15) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ia5e3b56f74057a456b78ef9f30583620cf27bca3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076441 Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 35bd701ded1cc..7c3f09efd5aed 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2181,7 +2181,7 @@ struct regulator *_regulator_get(struct device *dev, const char *id, } if (id == NULL) { - pr_err("get() with no identifier\n"); + dev_err(dev, "regulator request with no identifier\n"); return ERR_PTR(-EINVAL); } -- GitLab From ffbf17799f8acfcce77ac03a405962b104e54669 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 22 Aug 2024 15:20:46 +0800 Subject: [PATCH 089/456] UPSTREAM: regulator: Fully clean up on error in of_regulator_bulk_get_all() Currently in of_regulator_bulk_get_all(), if any regulator request fails, the error path releases all regulators already requested, but leaves the |struct regulator_bulk_data| memory to the caller to free, and also leaves the regulator consumer pointers dangling. The latter behavior is not documented, and may not be what the caller is expecting. Instead, explicitly clean up everything on error, and make it clear that the result pointer is only update if the whole request succeeds. Signed-off-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240822072047.3097740-4-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit bfefa214d179f13d01cf1b64a7efbabf586b0c49) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I213a1745dd9246ed69111a91d2f1e47e8726ab2e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076442 Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/regulator/of_regulator.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index f23c12f4ffbfa..fafea1feda211 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -750,19 +750,19 @@ static int is_supply_name(const char *name) * This helper function allows drivers to get several regulator * consumers in one operation. If any of the regulators cannot be * acquired then any regulators that were allocated will be freed - * before returning to the caller. + * before returning to the caller, and @consumers will not be + * changed. */ int of_regulator_bulk_get_all(struct device *dev, struct device_node *np, struct regulator_bulk_data **consumers) { int num_consumers = 0; struct regulator *tmp; + struct regulator_bulk_data *_consumers = NULL; struct property *prop; int i, n = 0, ret; char name[64]; - *consumers = NULL; - /* * first pass: get numbers of xxx-supply * second pass: fill consumers @@ -772,7 +772,7 @@ restart: i = is_supply_name(prop->name); if (i == 0) continue; - if (!*consumers) { + if (!_consumers) { num_consumers++; continue; } else { @@ -783,25 +783,28 @@ restart: ret = PTR_ERR(tmp); goto error; } - (*consumers)[n].consumer = tmp; + _consumers[n].consumer = tmp; n++; continue; } } - if (*consumers) + if (_consumers) { + *consumers = _consumers; return num_consumers; + } if (num_consumers == 0) return 0; - *consumers = kmalloc_array(num_consumers, + _consumers = kmalloc_array(num_consumers, sizeof(struct regulator_bulk_data), GFP_KERNEL); - if (!*consumers) + if (!_consumers) return -ENOMEM; goto restart; error: while (--n >= 0) - regulator_put(consumers[n]->consumer); + regulator_put(_consumers[n].consumer); + kfree(_consumers); return ret; } EXPORT_SYMBOL_GPL(of_regulator_bulk_get_all); -- GitLab From 504d3cd4648505ec5896392bcd9ef10b954c9284 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:21 +0800 Subject: [PATCH 090/456] UPSTREAM: regulator: core: Fix short description for _regulator_check_status_enabled() kernel-doc complains that _regulator_check_status_enabled() is missing a short description. Since the current description is already quite short, just trim it a bit more and use it as the short description. Fixes: f7d7ad42a9dc ("regulator: Allow regulators to verify enabled during enable()") Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-2-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit caa08dd8cdb8e58bf810e986cd6f9081ad056018) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I51b4ecfb693287d76c9dc24aed8e9bd5cf175d6f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076443 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7c3f09efd5aed..23cdbbd1c01f9 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2694,10 +2694,8 @@ static void _regulator_delay_helper(unsigned int delay) } /** - * _regulator_check_status_enabled - * - * A helper function to check if the regulator status can be interpreted - * as 'regulator is enabled'. + * _regulator_check_status_enabled - check if regulator status can be + * interpreted as "regulator is enabled" * @rdev: the regulator device to check * * Return: -- GitLab From 66712e5a907dcf4cf8b9122f521a0f7082be3f60 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:22 +0800 Subject: [PATCH 091/456] UPSTREAM: regulator: core: Fix regulator_is_supported_voltage() kerneldoc return value The kerneldoc for regulator_is_supported_voltage() states that the return value is a boolean. That is not correct, as it could return an error number if the check failed. Fix the description by expanding it to cover the valid return values and error conditions. The description is also converted to a proper "Return" section. Fixes: c5f3939b8fe0 ("regulator: core: Support fixed voltages in regulator_is_supported_voltage()") Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-3-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 753b9d86adb9d2c5882ac8ee0c3816aa48697eaa) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I1013250cecce6176a6ad7b0e37c42fd069cf6b0c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076444 Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 23cdbbd1c01f9..db88b9ec8e93b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3443,7 +3443,9 @@ EXPORT_SYMBOL_GPL(regulator_get_linear_step); * @min_uV: Minimum required voltage in uV. * @max_uV: Maximum required voltage in uV. * - * Returns a boolean. + * Return: 1 if the voltage range is supported, 0 if not, or a negative error + * number if @regulator's voltage can't be changed and voltage readback + * failed. */ int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV) -- GitLab From 8c294d23a403e922e61814afe32a02ef3a722fef Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:23 +0800 Subject: [PATCH 092/456] UPSTREAM: regulator: core: Fix incorrectly formatted kerneldoc "Return" sections kernel-doc complains about missing "Return" section for many documented functions in the regulator core. Many of them actually have descriptions about the return values, just not in the format kernel-doc wants. Convert these to use the proper "Return:" section header. The existing descriptions have been reworded and moved around to fit the grammar and formatting. In a few cases where the functions don't call even more functions and the error numbers are known, those are documented in detail. Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-4-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit f746af13dd115ae3e0ec9d762baa170184401d41) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I1a027d5e13269bfd86940cacdc310cd1bc4d26b8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076445 Commit-Queue: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 101 ++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index db88b9ec8e93b..836955ed3f283 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -425,8 +425,9 @@ static void regulator_lock_dependent(struct regulator_dev *rdev, * * Traverse all child nodes. * Extract the child regulator device node corresponding to the supply name. - * returns the device node corresponding to the regulator if found, else - * returns NULL. + * + * Return: Pointer to the &struct device_node corresponding to the regulator + * if found, or %NULL if not found. */ static struct device_node *of_get_child_regulator(struct device_node *parent, const char *prop_name) @@ -458,8 +459,9 @@ err_node_put: * @supply: regulator supply name * * Extract the regulator device node corresponding to the supply name. - * returns the device node corresponding to the regulator if found, else - * returns NULL. + * + * Return: Pointer to the &struct device_node corresponding to the regulator + * if found, or %NULL if not found. */ static struct device_node *of_get_regulator(struct device *dev, const char *supply) { @@ -2295,13 +2297,13 @@ struct regulator *_regulator_get(struct device *dev, const char *id, * @dev: device for regulator "consumer" * @id: Supply name or regulator ID. * - * Returns a struct regulator corresponding to the regulator producer, - * or IS_ERR() condition containing errno. - * * Use of supply names configured via set_consumer_device_supply() is * strongly encouraged. It is recommended that the supply name used * should match the name used for the supply and/or the relevant * device pins in the datasheet. + * + * Return: Pointer to a &struct regulator corresponding to the regulator + * producer, or an ERR_PTR() encoded negative error number. */ struct regulator *regulator_get(struct device *dev, const char *id) { @@ -2314,11 +2316,9 @@ EXPORT_SYMBOL_GPL(regulator_get); * @dev: device for regulator "consumer" * @id: Supply name or regulator ID. * - * Returns a struct regulator corresponding to the regulator producer, - * or IS_ERR() condition containing errno. Other consumers will be - * unable to obtain this regulator while this reference is held and the - * use count for the regulator will be initialised to reflect the current - * state of the regulator. + * Other consumers will be unable to obtain this regulator while this + * reference is held and the use count for the regulator will be + * initialised to reflect the current state of the regulator. * * This is intended for use by consumers which cannot tolerate shared * use of the regulator such as those which need to force the @@ -2329,6 +2329,9 @@ EXPORT_SYMBOL_GPL(regulator_get); * strongly encouraged. It is recommended that the supply name used * should match the name used for the supply and/or the relevant * device pins in the datasheet. + * + * Return: Pointer to a &struct regulator corresponding to the regulator + * producer, or an ERR_PTR() encoded negative error number. */ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) { @@ -2341,9 +2344,6 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive); * @dev: device for regulator "consumer" * @id: Supply name or regulator ID. * - * Returns a struct regulator corresponding to the regulator producer, - * or IS_ERR() condition containing errno. - * * This is intended for use by consumers for devices which can have * some supplies unconnected in normal use, such as some MMC devices. * It can allow the regulator core to provide stub supplies for other @@ -2355,6 +2355,9 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive); * strongly encouraged. It is recommended that the supply name used * should match the name used for the supply and/or the relevant * device pins in the datasheet. + * + * Return: Pointer to a &struct regulator corresponding to the regulator + * producer, or an ERR_PTR() encoded negative error number. */ struct regulator *regulator_get_optional(struct device *dev, const char *id) { @@ -2494,12 +2497,12 @@ EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); * lookup the supply * @num_id: Number of aliases to register * - * @return 0 on success, an errno on failure. - * * This helper function allows drivers to register several supply * aliases in one operation. If any of the aliases cannot be * registered any aliases that were registered will be removed * before returning to the caller. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_bulk_register_supply_alias(struct device *dev, const char *const *id, @@ -2824,7 +2827,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * responsible for keeping track of the refcount for a given regulator consumer * and applying / unapplying these things. * - * Returns 0 upon no error; -error upon error. + * Return: 0 on success or negative error number on failure. */ static int _regulator_handle_consumer_enable(struct regulator *regulator) { @@ -2850,7 +2853,7 @@ static int _regulator_handle_consumer_enable(struct regulator *regulator) * * The opposite of _regulator_handle_consumer_enable(). * - * Returns 0 upon no error; -error upon error. + * Return: 0 on success or a negative error number on failure. */ static int _regulator_handle_consumer_disable(struct regulator *regulator) { @@ -3258,13 +3261,13 @@ static int _regulator_list_voltage(struct regulator_dev *rdev, * regulator_is_enabled - is the regulator output enabled * @regulator: regulator source * - * Returns positive if the regulator driver backing the source/client - * has requested that the device be enabled, zero if it hasn't, else a - * negative errno code. - * * Note that the device backing this regulator handle can have multiple * users, so it might be enabled even if regulator_enable() was never * called for this particular source. + * + * Return: Positive if the regulator driver backing the source/client + * has requested that the device be enabled, zero if it hasn't, + * else a negative error number. */ int regulator_is_enabled(struct regulator *regulator) { @@ -3285,9 +3288,10 @@ EXPORT_SYMBOL_GPL(regulator_is_enabled); * regulator_count_voltages - count regulator_list_voltage() selectors * @regulator: regulator source * - * Returns number of selectors, or negative errno. Selectors are - * numbered starting at zero, and typically correspond to bitfields - * in hardware registers. + * Return: Number of selectors for @regulator, or negative error number. + * + * Selectors are numbered starting at zero, and typically correspond to + * bitfields in hardware registers. */ int regulator_count_voltages(struct regulator *regulator) { @@ -3309,9 +3313,9 @@ EXPORT_SYMBOL_GPL(regulator_count_voltages); * @selector: identify voltage to list * Context: can sleep * - * Returns a voltage that can be passed to @regulator_set_voltage(), - * zero if this selector code can't be used on this system, or a - * negative errno. + * Return: Voltage for @selector that can be passed to regulator_set_voltage(), + * 0 if @selector can't be used on this system, or a negative error + * number on failure. */ int regulator_list_voltage(struct regulator *regulator, unsigned selector) { @@ -3323,8 +3327,8 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage); * regulator_get_regmap - get the regulator's register map * @regulator: regulator source * - * Returns the register map for the given regulator, or an ERR_PTR value - * if the regulator doesn't use regmap. + * Return: Pointer to the &struct regmap for @regulator, or ERR_PTR() + * encoded -%EOPNOTSUPP if @regulator doesn't use regmap. */ struct regmap *regulator_get_regmap(struct regulator *regulator) { @@ -3374,7 +3378,9 @@ EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); * directly written to the regulator registers. The address of the voltage * register can be determined by calling @regulator_get_hardware_vsel_register. * - * On error a negative errno is returned. + * Return: 0 on success, -%EINVAL if the selector is outside the supported + * range, or -%EOPNOTSUPP if the regulator does not support voltage + * selectors. */ int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector) @@ -3401,7 +3407,7 @@ EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); * Request that the regulator be enabled/disabled with the regulator output at * the predefined voltage or current value. * - * On success 0 is returned, otherwise a negative errno is returned. + * Return: 0 on success or a negative error number on failure. */ int regulator_hardware_enable(struct regulator *regulator, bool enable) { @@ -3425,8 +3431,8 @@ EXPORT_SYMBOL_GPL(regulator_hardware_enable); * regulator_get_linear_step - return the voltage step size between VSEL values * @regulator: regulator source * - * Returns the voltage step size between VSEL values for linear - * regulators, or return 0 if the regulator isn't a linear regulator. + * Return: The voltage step size between VSEL values for linear regulators, + * or 0 if the regulator isn't a linear regulator. */ unsigned int regulator_get_linear_step(struct regulator *regulator) { @@ -4515,7 +4521,7 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage_rdev); * regulator_get_voltage - get regulator output voltage * @regulator: regulator source * - * This returns the current regulator voltage in uV. + * Return: Current regulator voltage in uV, or a negative error number on failure. * * NOTE: If the regulator is disabled it will return the voltage value. This * function should not be used to determine regulator state. @@ -4599,7 +4605,8 @@ static int _regulator_get_current_limit(struct regulator_dev *rdev) * regulator_get_current_limit - get regulator output current * @regulator: regulator source * - * This returns the current supplied by the specified current sink in uA. + * Return: Current supplied by the specified current sink in uA, + * or a negative error number on failure. * * NOTE: If the regulator is disabled it will return the current value. This * function should not be used to determine regulator state. @@ -4767,7 +4774,7 @@ EXPORT_SYMBOL_GPL(regulator_get_error_flags); * If a regulator is an always-on regulator then an individual consumer's * load will still be removed if that consumer is fully disabled. * - * On error a negative errno is returned. + * Return: 0 on success or a negative error number on failure. */ int regulator_set_load(struct regulator *regulator, int uA_load) { @@ -4936,12 +4943,12 @@ err: * @num_consumers: Number of consumers to register * @consumers: Configuration of consumers; clients are stored here. * - * @return 0 on success, an errno on failure. - * * This helper function allows drivers to get several regulator * consumers in one operation. If any of the regulators cannot be * acquired then any regulators that were allocated will be freed * before returning to the caller. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers) @@ -4962,12 +4969,13 @@ static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) * * @num_consumers: Number of consumers * @consumers: Consumer data; clients are stored here. - * @return 0 on success, an errno on failure * * This convenience API allows consumers to enable multiple regulator * clients in a single API call. If any consumers cannot be enabled * then any others that were enabled will be disabled again prior to * return. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers) @@ -5011,12 +5019,13 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable); * * @num_consumers: Number of consumers * @consumers: Consumer data; clients are stored here. - * @return 0 on success, an errno on failure * * This convenience API allows consumers to disable multiple regulator * clients in a single API call. If any consumers cannot be disabled * then any others that were disabled will be enabled again prior to * return. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers) @@ -5050,7 +5059,6 @@ EXPORT_SYMBOL_GPL(regulator_bulk_disable); * * @num_consumers: Number of consumers * @consumers: Consumer data; clients are stored here. - * @return 0 on success, an errno on failure * * This convenience API allows consumers to forcibly disable multiple regulator * clients in a single API call. @@ -5058,6 +5066,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_disable); * likely occur if the regulators are not disabled (e.g. over temp). * Although regulator_force_disable function call for some consumers can * return error numbers, the function is called for all consumers. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_bulk_force_disable(int num_consumers, struct regulator_bulk_data *consumers) @@ -5517,8 +5527,9 @@ static struct regulator_coupler generic_regulator_coupler = { * @cfg: runtime configuration for regulator * * Called by regulator drivers to register a regulator. - * Returns a valid pointer to struct regulator_dev on success - * or an ERR_PTR() on error. + * + * Return: Pointer to a valid &struct regulator_dev on success or + * an ERR_PTR() encoded negative error number on failure. */ struct regulator_dev * regulator_register(struct device *dev, -- GitLab From f919b56bd3b5935bd740853780bc29faf14a56bf Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:24 +0800 Subject: [PATCH 093/456] UPSTREAM: regulator: core: Add missing kerneldoc "Return" sections kernel-doc complains about missing "Return" section for many documented functions in the regulator core. Some with free-form return value descriptions have been fixed in the previous patch. The remaining are completely missing any mention of return values. Add "Return" sections to these kerneldoc blocks with basic descriptions. In a few cases where the functions don't call even more functions and the error numbers are known, those are documented in detail. Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-5-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 4ac204ff2d4ec360d9d2e39840ad286ddb78439f) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Iff45f05d98d1967c30439409901ebc08e320f7d2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076446 Reviewed-by: Pin-yen Lin Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 65 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 836955ed3f283..ff66c2357142e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -137,6 +137,8 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops) * once. If a task, which is calling this function is other * than the one, which initially locked the mutex, it will * wait on mutex. + * + * Return: 0 on success or a negative error number on failure. */ static inline int regulator_lock_nested(struct regulator_dev *rdev, struct ww_acquire_ctx *ww_ctx) @@ -1462,6 +1464,8 @@ static int handle_notify_limits(struct regulator_dev *rdev, * Constraints *must* be set by platform code in order for some * regulator operations to proceed i.e. set_voltage, set_current_limit, * set_mode. + * + * Return: 0 on success or a negative error number on failure. */ static int set_machine_constraints(struct regulator_dev *rdev) { @@ -1700,6 +1704,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) * Called by platform initialisation code to set the supply regulator for this * regulator. This ensures that a regulators supply will also be enabled by the * core if it's child is enabled. + * + * Return: 0 on success or a negative error number on failure. */ static int set_supply(struct regulator_dev *rdev, struct regulator_dev *supply_rdev) @@ -1732,6 +1738,8 @@ static int set_supply(struct regulator_dev *rdev, * sources to symbolic names for supplies for use by devices. Devices * should use these symbolic names to request regulators, avoiding the * need to provide board-specific regulator names as platform data. + * + * Return: 0 on success or a negative error number on failure. */ static int set_consumer_device_supply(struct regulator_dev *rdev, const char *consumer_dev_name, @@ -1998,11 +2006,13 @@ static struct regulator_dev *regulator_lookup_by_name(const char *name) * @dev: device for regulator "consumer". * @supply: Supply name or regulator ID. * + * Return: pointer to &struct regulator_dev or ERR_PTR() encoded negative error number. + * * If successful, returns a struct regulator_dev that corresponds to the name * @supply and with the embedded struct device refcount incremented by one. * The refcount must be dropped by calling put_device(). - * On failure one of the following ERR-PTR-encoded values is returned: - * -ENODEV if lookup fails permanently, -EPROBE_DEFER if lookup could succeed + * On failure one of the following ERR_PTR() encoded values is returned: + * -%ENODEV if lookup fails permanently, -%EPROBE_DEFER if lookup could succeed * in the future. */ static struct regulator_dev *regulator_dev_lookup(struct device *dev, @@ -2438,6 +2448,8 @@ EXPORT_SYMBOL_GPL(regulator_put); * * All lookups for id on dev will instead be conducted for alias_id on * alias_dev. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_register_supply_alias(struct device *dev, const char *id, struct device *alias_dev, @@ -2627,6 +2639,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) * * GPIO is enabled in case of initial use. (enable_count is 0) * GPIO is disabled when it is not shared any more. (enable_count <= 1) + * + * Return: 0 on success or a negative error number on failure. */ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) { @@ -2949,6 +2963,8 @@ err_disable_supply: * * NOTE: the output value can be set by other drivers, boot loader or may be * hardwired in the regulator. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_enable(struct regulator *regulator) { @@ -3059,6 +3075,8 @@ static int _regulator_disable(struct regulator *regulator) * NOTE: this will only disable the regulator output if no other consumer * devices have it enabled, the regulator device supports disabling and * machine constraints permit this operation. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_disable(struct regulator *regulator) { @@ -3108,6 +3126,8 @@ static int _regulator_force_disable(struct regulator_dev *rdev) * NOTE: this *will* disable the regulator output even if other consumer * devices have it enabled. This should be used for situations when device * damage will likely occur if the regulator is not disabled (e.g. over temp). + * + * Return: 0 on success or a negative error number on failure. */ int regulator_force_disable(struct regulator *regulator) { @@ -3190,6 +3210,8 @@ static void regulator_disable_work(struct work_struct *work) * NOTE: this will only disable the regulator output if no other consumer * devices have it enabled, the regulator device supports disabling and * machine constraints permit this operation. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_disable_deferred(struct regulator *regulator, int ms) { @@ -3349,6 +3371,9 @@ EXPORT_SYMBOL_GPL(regulator_get_regmap); * hardware or firmware that can make I2C requests behind the kernel's back, * for example. * + * Return: 0 on success, or -%EOPNOTSUPP if the regulator does not support + * voltage selectors. + * * On success, the output parameters @vsel_reg and @vsel_mask are filled in * and 0 is returned, otherwise a negative errno is returned. */ @@ -4204,6 +4229,8 @@ static int regulator_balance_voltage(struct regulator_dev *rdev, * request voltage that meets the system constraints will be used. * Regulator system constraints must be set for this regulator before * calling this function otherwise this call will fail. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) { @@ -4314,6 +4341,8 @@ EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage); * Provided with the starting and ending voltage, this function attempts to * calculate the time in microseconds required to rise or fall to this new * voltage. + * + * Return: ramp time in microseconds, or a negative error number if calculation failed. */ int regulator_set_voltage_time(struct regulator *regulator, int old_uV, int new_uV) @@ -4371,6 +4400,8 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time); * * Drivers providing ramp_delay in regulation_constraints can use this as their * set_voltage_time_sel() operation. + * + * Return: ramp time in microseconds, or a negative error number if calculation failed. */ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, @@ -4423,6 +4454,8 @@ out: * Re-apply the last configured voltage. This is intended to be used * where some external control source the consumer is cooperating with * has caused the configured voltage to change. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_sync_voltage(struct regulator *regulator) { @@ -4554,6 +4587,8 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage); * * NOTE: Regulator system constraints must be set for this regulator before * calling this function otherwise this call will fail. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_set_current_limit(struct regulator *regulator, int min_uA, int max_uA) @@ -4627,6 +4662,8 @@ EXPORT_SYMBOL_GPL(regulator_get_current_limit); * * NOTE: Regulator system constraints must be set for this regulator before * calling this function otherwise this call will fail. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_set_mode(struct regulator *regulator, unsigned int mode) { @@ -4688,6 +4725,9 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev) * @regulator: regulator source * * Get the current regulator operating mode. + * + * Return: Current operating mode as %REGULATOR_MODE_* values, + * or a negative error number on failure. */ unsigned int regulator_get_mode(struct regulator *regulator) { @@ -4734,6 +4774,8 @@ static int _regulator_get_error_flags(struct regulator_dev *rdev, * @flags: pointer to store error flags * * Get the current regulator error information. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_get_error_flags(struct regulator *regulator, unsigned int *flags) @@ -4806,6 +4848,9 @@ EXPORT_SYMBOL_GPL(regulator_set_load); * for the regulator also enable bypass mode and the machine * constraints allow this. Bypass mode means that the regulator is * simply passing the input directly to the output with no regulation. + * + * Return: 0 on success or if changing bypass is not possible, or + * a negative error number on failure. */ int regulator_allow_bypass(struct regulator *regulator, bool enable) { @@ -4863,6 +4908,8 @@ EXPORT_SYMBOL_GPL(regulator_allow_bypass); * @nb: notifier block * * Register notifier block to receive regulator events. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb) @@ -4878,6 +4925,8 @@ EXPORT_SYMBOL_GPL(regulator_register_notifier); * @nb: notifier block * * Unregister regulator event notifier block. + * + * Return: 0 on success or a negative error number on failure. */ int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb) @@ -5117,6 +5166,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); * * Called by regulator drivers to notify clients a regulator event has * occurred. + * + * Return: %NOTIFY_DONE. */ int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) @@ -5133,6 +5184,8 @@ EXPORT_SYMBOL_GPL(regulator_notifier_call_chain); * @mode: Mode to convert * * Convert a regulator mode into a status. + * + * Return: %REGULATOR_STATUS_* value corresponding to given mode. */ int regulator_mode_to_status(unsigned int mode) { @@ -5823,6 +5876,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister); * @dev: ``&struct device`` pointer that is passed to _regulator_suspend() * * Configure each regulator with it's suspend operating parameters for state. + * + * Return: 0 on success or a negative error number on failure. */ static int regulator_suspend(struct device *dev) { @@ -5912,6 +5967,8 @@ EXPORT_SYMBOL_GPL(regulator_has_full_constraints); * * Get rdev regulator driver private data. This call can be used in the * regulator driver context. + * + * Return: Pointer to regulator driver private data. */ void *rdev_get_drvdata(struct regulator_dev *rdev) { @@ -5925,6 +5982,8 @@ EXPORT_SYMBOL_GPL(rdev_get_drvdata); * * Get regulator driver private data. This call can be used in the consumer * driver context when non API regulator specific functions need to be called. + * + * Return: Pointer to regulator driver private data. */ void *regulator_get_drvdata(struct regulator *regulator) { @@ -5946,6 +6005,8 @@ EXPORT_SYMBOL_GPL(regulator_set_drvdata); /** * rdev_get_id - get regulator ID * @rdev: regulator + * + * Return: Regulator ID for @rdev. */ int rdev_get_id(struct regulator_dev *rdev) { -- GitLab From fc56ca8bbae80732b97eac0ae6ea02052ed992f6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:25 +0800 Subject: [PATCH 094/456] UPSTREAM: regulator: of: Fix incorrectly formatted kerneldoc "Return" sections kernel-doc complains about missing "Return" section for many documented functions in the regulator OF-specific code. These all have descriptions about the return values, just not in the format kernel-doc wants. Convert these to use the proper "Return:" section header. The existing descriptions have been reworded and moved around to fit the grammar and formatting. Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-6-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit dac41d59f2de25b8d3f5350c8cbfe39187d214da) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I0eb16c3e6386b24137ad07898070bfa71fd8f062 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076447 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/of_regulator.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index fafea1feda211..966f0fa271f2e 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -329,8 +329,10 @@ static int of_get_regulation_constraints(struct device *dev, * @desc: regulator description * * Populates regulator_init_data structure by extracting data from device - * tree node, returns a pointer to the populated structure or NULL if memory - * alloc fails. + * tree node. + * + * Return: Pointer to a populated &struct regulator_init_data or NULL if + * memory allocation fails. */ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, struct device_node *node, @@ -382,7 +384,7 @@ static void devm_of_regulator_put_matches(struct device *dev, void *res) * in place and an additional of_node reference is taken for each matched * regulator. * - * Returns the number of matches found or a negative error code on failure. + * Return: The number of matches found or a negative error number on failure. */ int of_regulator_match(struct device *dev, struct device_node *node, struct of_regulator_match *matches, @@ -622,7 +624,7 @@ static bool of_coupling_find_node(struct device_node *src, * - all coupled regulators have the same number of regulator_dev phandles * - all regulators are linked to each other * - * Returns true if all conditions are met. + * Return: True if all conditions are met; false otherwise. */ bool of_check_coupling_data(struct regulator_dev *rdev) { @@ -693,8 +695,8 @@ clean: * "regulator-coupled-with" property * @index: Index in phandles array * - * Returns the regulator_dev pointer parsed from DTS. If it has not been yet - * registered, returns NULL + * Return: Pointer to the &struct regulator_dev parsed from DTS, or %NULL if + * it has not yet been registered. */ struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev, int index) -- GitLab From 694e43f6beb3fdabdfd05905964fb829665d28cc Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:29 +0800 Subject: [PATCH 095/456] UPSTREAM: regulator: of: Fix kerneldoc format for of_regulator_bulk_get_all() of_regulator_bulk_get_all() has a comment section that pretty much resembles a kerneldoc block, except that the block begins with "/*" instead of "/**". Fix that and also rework the "Return" section and the error code terminology so that it is the same as the other kerneldoc blocks in the same file. Fixes: 27b9ecc7a9ba ("regulator: Add of_regulator_bulk_get_all") Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-10-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 6eace77a6048c9b0b50950e88ef987d4519a53c1) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I4c8932ed05e6bb0daab36a96d9bb7b8ddbb5fddf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076448 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/of_regulator.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 966f0fa271f2e..0d027901f1c3d 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -740,20 +740,21 @@ static int is_supply_name(const char *name) return 0; } -/* +/** * of_regulator_bulk_get_all - get multiple regulator consumers * * @dev: Device to supply * @np: device node to search for consumers * @consumers: Configuration of consumers; clients are stored here. * - * @return number of regulators on success, an errno on failure. - * * This helper function allows drivers to get several regulator * consumers in one operation. If any of the regulators cannot be * acquired then any regulators that were allocated will be freed * before returning to the caller, and @consumers will not be * changed. + * + * Return: Number of regulators on success, or a negative error number + * on failure. */ int of_regulator_bulk_get_all(struct device *dev, struct device_node *np, struct regulator_bulk_data **consumers) -- GitLab From 38731edf21383d677ae58ae3a9871b7487b47c56 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Aug 2024 16:51:30 +0800 Subject: [PATCH 096/456] UPSTREAM: regulator: Unify "negative error number" terminology in comments Previous commits cleaning up kerneldoc used the term "negative error number" to refer to error condition return values. Update remaining instances of other terminology such as "error code" or "errno" as well so the whole regulator subsystem is unified. Signed-off-by: Chen-Yu Tsai Reported-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240829085131.1361701-11-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 98ce82a52886edd5197e903cb2b56f21bf3b0781) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ica7cd893f9e995673a622647226bd031647c9959 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076449 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 2 +- drivers/regulator/devres.c | 18 +++++++++--------- drivers/regulator/fixed.c | 2 +- drivers/regulator/irq_helpers.c | 2 +- drivers/regulator/max77802-regulator.c | 4 ++-- drivers/regulator/qcom-rpmh-regulator.c | 6 +++--- drivers/regulator/qcom_smd-regulator.c | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ff66c2357142e..8b0f99c62b94c 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3375,7 +3375,7 @@ EXPORT_SYMBOL_GPL(regulator_get_regmap); * voltage selectors. * * On success, the output parameters @vsel_reg and @vsel_mask are filled in - * and 0 is returned, otherwise a negative errno is returned. + * and 0 is returned, otherwise a negative error number is returned. */ int regulator_get_hardware_vsel_register(struct regulator *regulator, unsigned *vsel_reg, diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 7111c46e9de13..1b893cdd1aad6 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -163,7 +163,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_get_optional); * In cases where the supply is not strictly required, callers can check for * -ENODEV error and handle it accordingly. * - * Returns: voltage in microvolts on success, or an error code on failure. + * Returns: voltage in microvolts on success, or an negative error number on failure. */ int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id) { @@ -174,8 +174,8 @@ int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id) * Since we need a real voltage, we use devm_regulator_get_optional() * rather than getting a dummy regulator with devm_regulator_get() and * then letting regulator_get_voltage() fail with -EINVAL. This way, the - * caller can handle the -ENODEV error code if needed instead of the - * ambiguous -EINVAL. + * caller can handle the -ENODEV negative error number if needed instead + * of the ambiguous -EINVAL. */ r = devm_regulator_get_optional(dev, id); if (IS_ERR(r)) @@ -276,7 +276,7 @@ static int _devm_regulator_bulk_get(struct device *dev, int num_consumers, * @num_consumers: number of consumers to register * @consumers: configuration of consumers; clients are stored here. * - * @return 0 on success, an errno on failure. + * @return 0 on success, a negative error number on failure. * * This helper function allows drivers to get several regulator * consumers in one operation with management, the regulators will @@ -299,7 +299,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); * @num_consumers: number of consumers to register * @consumers: configuration of consumers; clients are stored here. * - * @return 0 on success, an errno on failure. + * @return 0 on success, a negative error number on failure. * * This helper function allows drivers to exclusively get several * regulator consumers in one operation with management, the regulators @@ -326,7 +326,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_exclusive); * This is a convenience function to allow bulk regulator configuration * to be stored "static const" in files. * - * Return: 0 on success, an errno on failure. + * Return: 0 on success, a negative error number on failure. */ int devm_regulator_bulk_get_const(struct device *dev, int num_consumers, const struct regulator_bulk_data *in_consumers, @@ -393,7 +393,7 @@ static void devm_regulator_bulk_disable(void *res) * @num_consumers: number of consumers to register * @id: list of supply names or regulator IDs * - * @return 0 on success, an errno on failure. + * @return 0 on success, a negative error number on failure. * * This helper function allows drivers to get several regulator * consumers in one operation with management, the regulators will @@ -574,7 +574,7 @@ static void devm_regulator_unregister_supply_alias(struct device *dev, * lookup the supply * @num_id: number of aliases to register * - * @return 0 on success, an errno on failure. + * @return 0 on success, a negative error number on failure. * * This helper function allows drivers to register several supply * aliases in one operation, the aliases will be automatically @@ -726,7 +726,7 @@ static void regulator_irq_helper_drop(void *res) * IRQ. * @rdev_amount: Amount of regulators associated with this IRQ. * - * Return: handle to irq_helper or an ERR_PTR() encoded error code. + * Return: handle to irq_helper or an ERR_PTR() encoded negative error number. */ void *devm_regulator_irq_helper(struct device *dev, const struct regulator_irq_desc *d, int irq, diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index cb93e5cdcfa94..35a2bf580ad9a 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -129,7 +129,7 @@ static irqreturn_t reg_fixed_under_voltage_irq_handler(int irq, void *data) * If it's an optional IRQ and not found, it returns 0. * Otherwise, it attempts to request the threaded IRQ. * - * Return: 0 on success, or error code on failure. + * Return: 0 on success, or a negative error number on failure. */ static int reg_fixed_get_irqs(struct device *dev, struct fixed_voltage_data *priv) diff --git a/drivers/regulator/irq_helpers.c b/drivers/regulator/irq_helpers.c index 5ab1a0befe12f..ba07a7016a272 100644 --- a/drivers/regulator/irq_helpers.c +++ b/drivers/regulator/irq_helpers.c @@ -333,7 +333,7 @@ static void init_rdev_errors(struct regulator_irq *h) * IRQ. * @rdev_amount: Amount of regulators associated with this IRQ. * - * Return: handle to irq_helper or an ERR_PTR() encoded error code. + * Return: handle to irq_helper or an ERR_PTR() encoded negative error number. */ void *regulator_irq_helper(struct device *dev, const struct regulator_irq_desc *d, int irq, diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c index 69eb6abd25514..b2e87642bec41 100644 --- a/drivers/regulator/max77802-regulator.c +++ b/drivers/regulator/max77802-regulator.c @@ -160,8 +160,8 @@ static unsigned max77802_get_mode(struct regulator_dev *rdev) * Enable Control Logic3 by PWRREQ (LDO 3) * * If setting the regulator mode fails, the function only warns but does - * not return an error code to avoid the regulator core to stop setting - * the operating mode for the remaining regulators. + * not return a negative error number to avoid the regulator core to stop + * setting the operating mode for the remaining regulators. */ static int max77802_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index b2e359ac31693..dbf46c58de1c2 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -155,7 +155,7 @@ struct rpmh_vreg_init_data { * @wait_for_ack: Boolean indicating if execution must wait until the * request has been acknowledged as complete * - * Return: 0 on success, errno on failure + * Return: 0 on success, or a negative error number on failure */ static int rpmh_regulator_send_request(struct rpmh_vreg *vreg, struct tcs_cmd *cmd, bool wait_for_ack) @@ -314,7 +314,7 @@ static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev) * This function is used in the regulator_ops for VRM type RPMh regulator * devices. * - * Return: 0 on success, errno on failure + * Return: 0 on success, or a negative error number on failure */ static unsigned int rpmh_regulator_vrm_get_optimum_mode( struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) @@ -406,7 +406,7 @@ static const struct regulator_ops rpmh_regulator_xob_ops = { * @pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator * resources defined for the top level PMIC device * - * Return: 0 on success, errno on failure + * Return: 0 on success, or a negative error number on failure */ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev, struct device_node *node, const char *pmic_id, diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index f53ada076252d..8cfaf7b6f170e 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -1353,7 +1353,7 @@ MODULE_DEVICE_TABLE(of, rpm_of_match); * @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator * resources defined for the top level PMIC device * - * Return: 0 on success, errno on failure + * Return: 0 on success, or a negative error number on failure */ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev, struct device_node *node, struct qcom_smd_rpm *rpm, -- GitLab From cbc42af7c84000093f21e49aaf695a9889b4980a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 4 Sep 2024 17:00:05 +0800 Subject: [PATCH 097/456] UPSTREAM: regulator: Move OF-specific regulator lookup code to of_regulator.c There's still a bit of OF-specific code in the regulator device lookup function. Move those bits of code over to of_regulator.c, and create a new function of_regulator_dev_lookup() to encapsulate the code moved out of regulator_dev_lookup(). Also mark of_find_regulator_by_node() as static, since there are no other users in other compile units. There are no functional changes. A line alignment was also fixed. Signed-off-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240904090016.2841572-4-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit b8c3255457147162cd713a319a8e2274335449b9) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Id9c2db3e29e5eab96332f570b6958039d713a840 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076450 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 87 ++---------------------- drivers/regulator/internal.h | 9 +-- drivers/regulator/of_regulator.c | 110 ++++++++++++++++++++++++++++++- 3 files changed, 119 insertions(+), 87 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8b0f99c62b94c..0d304b832885a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -419,74 +419,6 @@ static void regulator_lock_dependent(struct regulator_dev *rdev, mutex_unlock(®ulator_list_mutex); } -/** - * of_get_child_regulator - get a child regulator device node - * based on supply name - * @parent: Parent device node - * @prop_name: Combination regulator supply name and "-supply" - * - * Traverse all child nodes. - * Extract the child regulator device node corresponding to the supply name. - * - * Return: Pointer to the &struct device_node corresponding to the regulator - * if found, or %NULL if not found. - */ -static struct device_node *of_get_child_regulator(struct device_node *parent, - const char *prop_name) -{ - struct device_node *regnode = NULL; - struct device_node *child = NULL; - - for_each_child_of_node(parent, child) { - regnode = of_parse_phandle(child, prop_name, 0); - - if (!regnode) { - regnode = of_get_child_regulator(child, prop_name); - if (regnode) - goto err_node_put; - } else { - goto err_node_put; - } - } - return NULL; - -err_node_put: - of_node_put(child); - return regnode; -} - -/** - * of_get_regulator - get a regulator device node based on supply name - * @dev: Device pointer for the consumer (of regulator) device - * @supply: regulator supply name - * - * Extract the regulator device node corresponding to the supply name. - * - * Return: Pointer to the &struct device_node corresponding to the regulator - * if found, or %NULL if not found. - */ -static struct device_node *of_get_regulator(struct device *dev, const char *supply) -{ - struct device_node *regnode = NULL; - char prop_name[64]; /* 64 is max size of property name */ - - dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); - - snprintf(prop_name, 64, "%s-supply", supply); - regnode = of_parse_phandle(dev->of_node, prop_name, 0); - - if (!regnode) { - regnode = of_get_child_regulator(dev->of_node, prop_name); - if (regnode) - return regnode; - - dev_dbg(dev, "Looking up %s property in node %pOF failed\n", - prop_name, dev->of_node); - return NULL; - } - return regnode; -} - /* Platform voltage constraint check */ int regulator_check_voltage(struct regulator_dev *rdev, int *min_uV, int *max_uV) @@ -2019,7 +1951,6 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, const char *supply) { struct regulator_dev *r = NULL; - struct device_node *node; struct regulator_map *map; const char *devname = NULL; @@ -2027,19 +1958,11 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, /* first do a dt based lookup */ if (dev && dev->of_node) { - node = of_get_regulator(dev, supply); - if (node) { - r = of_find_regulator_by_node(node); - of_node_put(node); - if (r) - return r; - - /* - * We have a node, but there is no device. - * assume it has not registered yet. - */ - return ERR_PTR(-EPROBE_DEFER); - } + r = of_regulator_dev_lookup(dev, supply); + if (!IS_ERR(r)) + return r; + if (PTR_ERR(r) == -EPROBE_DEFER) + return r; } /* if not found, try doing it non-dt way */ diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index fb4433068d298..f230aaf6b9c62 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -66,7 +66,8 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev) } #ifdef CONFIG_OF -struct regulator_dev *of_find_regulator_by_node(struct device_node *np); +struct regulator_dev *of_regulator_dev_lookup(struct device *dev, + const char *supply); struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, struct regulator_config *config, @@ -80,10 +81,10 @@ int of_get_n_coupled(struct regulator_dev *rdev); bool of_check_coupling_data(struct regulator_dev *rdev); #else -static inline struct regulator_dev * -of_find_regulator_by_node(struct device_node *np) +static inline struct regulator_dev *of_regulator_dev_lookup(struct device *dev, + const char *supply) { - return NULL; + return ERR_PTR(-ENODEV); } static inline struct regulator_init_data * diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 0d027901f1c3d..3933cb22f96c3 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -555,7 +555,75 @@ error: return NULL; } -struct regulator_dev *of_find_regulator_by_node(struct device_node *np) +/** + * of_get_child_regulator - get a child regulator device node + * based on supply name + * @parent: Parent device node + * @prop_name: Combination regulator supply name and "-supply" + * + * Traverse all child nodes. + * Extract the child regulator device node corresponding to the supply name. + * + * Return: Pointer to the &struct device_node corresponding to the regulator + * if found, or %NULL if not found. + */ +static struct device_node *of_get_child_regulator(struct device_node *parent, + const char *prop_name) +{ + struct device_node *regnode = NULL; + struct device_node *child = NULL; + + for_each_child_of_node(parent, child) { + regnode = of_parse_phandle(child, prop_name, 0); + + if (!regnode) { + regnode = of_get_child_regulator(child, prop_name); + if (regnode) + goto err_node_put; + } else { + goto err_node_put; + } + } + return NULL; + +err_node_put: + of_node_put(child); + return regnode; +} + +/** + * of_get_regulator - get a regulator device node based on supply name + * @dev: Device pointer for the consumer (of regulator) device + * @supply: regulator supply name + * + * Extract the regulator device node corresponding to the supply name. + * + * Return: Pointer to the &struct device_node corresponding to the regulator + * if found, or %NULL if not found. + */ +static struct device_node *of_get_regulator(struct device *dev, const char *supply) +{ + struct device_node *regnode = NULL; + char prop_name[64]; /* 64 is max size of property name */ + + dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); + + snprintf(prop_name, 64, "%s-supply", supply); + regnode = of_parse_phandle(dev->of_node, prop_name, 0); + + if (!regnode) { + regnode = of_get_child_regulator(dev->of_node, prop_name); + if (regnode) + return regnode; + + dev_dbg(dev, "Looking up %s property in node %pOF failed\n", + prop_name, dev->of_node); + return NULL; + } + return regnode; +} + +static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) { struct device *dev; @@ -564,6 +632,46 @@ struct regulator_dev *of_find_regulator_by_node(struct device_node *np) return dev ? dev_to_rdev(dev) : NULL; } +/** + * of_regulator_dev_lookup - lookup a regulator device with device tree only + * @dev: Device pointer for regulator supply lookup. + * @supply: Supply name or regulator ID. + * + * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR() + * encoded value on error. + * + * If successful, returns a pointer to the &struct regulator_dev that + * corresponds to the name @supply and with the embedded &struct device + * refcount incremented by one. The refcount must be dropped by calling + * put_device(). + * + * On failure one of the following ERR_PTR() encoded values is returned: + * * -%ENODEV if lookup fails permanently. + * * -%EPROBE_DEFER if lookup could succeed in the future. + */ +struct regulator_dev *of_regulator_dev_lookup(struct device *dev, + const char *supply) +{ + struct regulator_dev *r; + struct device_node *node; + + node = of_get_regulator(dev, supply); + if (node) { + r = of_find_regulator_by_node(node); + of_node_put(node); + if (r) + return r; + + /* + * We have a node, but there is no device. + * assume it has not registered yet. + */ + return ERR_PTR(-EPROBE_DEFER); + } + + return ERR_PTR(-ENODEV); +} + /* * Returns number of regulators coupled with rdev. */ -- GitLab From bea321f628efe08eff517ee18d4042961d070cf1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 4 Sep 2024 22:08:56 +0300 Subject: [PATCH 098/456] UPSTREAM: regulator: of: Refactor of_get_*regulator() to decrease indentation Refactor of_get_*regulator() to decrease indentation and increase readability. No functional changes intended. Signed-off-by: Andy Shevchenko Reviewed-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240904190856.1221459-1-andy.shevchenko@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 401d078eaf2edd605c9121741e166d9326c63677) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I79be1916f1ac389db9bf30e6f58a0789370a118b Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076451 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/regulator/of_regulator.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 3933cb22f96c3..0847708b63613 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -575,14 +575,12 @@ static struct device_node *of_get_child_regulator(struct device_node *parent, for_each_child_of_node(parent, child) { regnode = of_parse_phandle(child, prop_name, 0); + if (regnode) + goto err_node_put; - if (!regnode) { - regnode = of_get_child_regulator(child, prop_name); - if (regnode) - goto err_node_put; - } else { + regnode = of_get_child_regulator(child, prop_name); + if (regnode) goto err_node_put; - } } return NULL; @@ -610,17 +608,15 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp snprintf(prop_name, 64, "%s-supply", supply); regnode = of_parse_phandle(dev->of_node, prop_name, 0); + if (regnode) + return regnode; - if (!regnode) { - regnode = of_get_child_regulator(dev->of_node, prop_name); - if (regnode) - return regnode; + regnode = of_get_child_regulator(dev->of_node, prop_name); + if (regnode) + return regnode; - dev_dbg(dev, "Looking up %s property in node %pOF failed\n", - prop_name, dev->of_node); - return NULL; - } - return regnode; + dev_dbg(dev, "Looking up %s property in node %pOF failed\n", prop_name, dev->of_node); + return NULL; } static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) -- GitLab From ec4c90a0a07ce037d68afd3bb62aed591d3013d7 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Wed, 11 Sep 2024 20:03:38 +0800 Subject: [PATCH 099/456] UPSTREAM: regulator: core: fix the broken behavior of regulator_dev_lookup() The behavior of regulator_dev_lookup() for non-DT way has been broken since the commit b8c325545714 ("regulator: Move OF-specific regulator lookup code to of_regulator.c"). Before the commit, of_get_regulator() was used to get the regulator, which returns NULL if the regulator is not found. So the regulator will be looked up through regulator_lookup_by_name() if no matching regulator is found in regulator_map_list. However, currently, of_regulator_dev_lookup() is used to instead of of_get_regulator(), but the variable 'r' is set to ERR_PTR(-ENODEV) instead of NULL if the regulator is not found. In this case, if no regulator is found in regulator_map_list, the variable 'r' is still ERR_PTR(-ENODEV), So regulator_dev_lookup() returns the value of 'r' directly instead of continuing to look up the regulator through regulator_lookup_by_name(). Fixes: b8c325545714 ("regulator: Move OF-specific regulator lookup code to of_regulator.c") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20240911120338.526384-1-wei.fang@nxp.com Signed-off-by: Mark Brown (cherry picked from commit a1d12410d9b1ecff87d39f80b0d1cec895012ffa) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I90682ab7ffbf1db7d7245b6d2c2b16a12e0359a1 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076452 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0d304b832885a..a08298c12b826 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1963,6 +1963,9 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, return r; if (PTR_ERR(r) == -EPROBE_DEFER) return r; + + if (PTR_ERR(r) == -ENODEV) + r = NULL; } /* if not found, try doing it non-dt way */ -- GitLab From be413d3ee0970194d2e02e69f9b0b6ad53ba1fb8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Sep 2024 15:27:41 +0800 Subject: [PATCH 100/456] UPSTREAM: regulator: Split up _regulator_get() _regulator_get() contains a lot of common code doing checks prior to the regulator lookup and housekeeping work after the lookup. Almost all the code could be shared with a OF-specific variant of _regulator_get(). Split out the common parts so that they can be reused. The OF-specific version of _regulator_get() will be added in a subsequent patch. No functional changes were made. Signed-off-by: Chen-Yu Tsai Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240911072751.365361-4-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 2a1de5678944147c2a41b6006127d2d0b618e83b) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ife328565f9fb31b09dd17d4f53c929f394f45a73 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076453 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 54 ++++++++++++++++++++++++++++-------- drivers/regulator/internal.h | 4 +++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a08298c12b826..0d6147cc085e4 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2104,26 +2104,43 @@ out: return ret; } -/* Internal regulator request function */ -struct regulator *_regulator_get(struct device *dev, const char *id, - enum regulator_get_type get_type) +/* common pre-checks for regulator requests */ +int _regulator_get_common_check(struct device *dev, const char *id, + enum regulator_get_type get_type) { - struct regulator_dev *rdev; - struct regulator *regulator; - struct device_link *link; - int ret; - if (get_type >= MAX_GET_TYPE) { dev_err(dev, "invalid type %d in %s\n", get_type, __func__); - return ERR_PTR(-EINVAL); + return -EINVAL; } if (id == NULL) { dev_err(dev, "regulator request with no identifier\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - rdev = regulator_dev_lookup(dev, id); + return 0; +} + +/** + * _regulator_get_common - Common code for regulator requests + * @rdev: regulator device pointer as returned by *regulator_dev_lookup() + * Its reference count is expected to have been incremented. + * @dev: device used for dev_printk messages + * @id: Supply name or regulator ID + * @get_type: enum regulator_get_type value corresponding to type of request + * + * Returns: pointer to struct regulator corresponding to @rdev, or ERR_PTR() + * encoded error. + * + * This function should be chained with *regulator_dev_lookup() functions. + */ +struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct device *dev, + const char *id, enum regulator_get_type get_type) +{ + struct regulator *regulator; + struct device_link *link; + int ret; + if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); @@ -2228,6 +2245,21 @@ struct regulator *_regulator_get(struct device *dev, const char *id, return regulator; } +/* Internal regulator request function */ +struct regulator *_regulator_get(struct device *dev, const char *id, + enum regulator_get_type get_type) +{ + struct regulator_dev *rdev; + int ret; + + ret = _regulator_get_common_check(dev, id, get_type); + if (ret) + return ERR_PTR(ret); + + rdev = regulator_dev_lookup(dev, id); + return _regulator_get_common(rdev, dev, id, get_type); +} + /** * regulator_get - lookup and obtain a reference to a regulator. * @dev: device for regulator "consumer" diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index f230aaf6b9c62..1cfff6e5c5e5a 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -121,6 +121,10 @@ enum regulator_get_type { MAX_GET_TYPE }; +int _regulator_get_common_check(struct device *dev, const char *id, + enum regulator_get_type get_type); +struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct device *dev, + const char *id, enum regulator_get_type get_type); struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type); int _regulator_bulk_get(struct device *dev, int num_consumers, -- GitLab From 43b611b46ec5af79dc77ee80200aca2f7127442c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 25 Sep 2024 17:38:04 +0800 Subject: [PATCH 101/456] UPSTREAM: regulator: Add of_regulator_get_optional() for pure DT regulator lookup The to-be-introduced I2C component prober needs to enable regulator supplies (and toggle GPIO pins) for the various components it intends to probe. To support this, a new "pure DT lookup" method for getting regulator supplies is needed, since the device normally requesting the supply won't get created until after the component is probed to be available. Add a new of_regulator_get_optional() function for this. This mirrors the existing regulator_get_optional() function, but is OF-specific. The underlying code that supports the existing regulator_get*() functions has been reworked in previous patches to support this specific case. Also convert an existing usage of "dev && dev->of_node" to "dev_of_node(dev)". Link: https://lore.kernel.org/all/20231220203537.83479-2-jernej.skrabec@gmail.com/ [1] Signed-off-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240925093807.1026949-2-wenst@chromium.org Reviewed-by: Andy Shevchenko Signed-off-by: Mark Brown (cherry picked from commit 5441b6975adc26aeaca316b9075e04a98238b1b3) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ie9602480373ac706710ce498ee794f7c42fde504 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076454 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/regulator/core.c | 4 +-- drivers/regulator/internal.h | 2 ++ drivers/regulator/of_regulator.c | 51 ++++++++++++++++++++++++++---- include/linux/regulator/consumer.h | 20 ++++++++++++ 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0d6147cc085e4..0b34d2fa56875 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1957,8 +1957,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, regulator_supply_alias(&dev, &supply); /* first do a dt based lookup */ - if (dev && dev->of_node) { - r = of_regulator_dev_lookup(dev, supply); + if (dev_of_node(dev)) { + r = of_regulator_dev_lookup(dev, dev_of_node(dev), supply); if (!IS_ERR(r)) return r; if (PTR_ERR(r) == -EPROBE_DEFER) diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 1cfff6e5c5e5a..a711d63585c9a 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -67,6 +67,7 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev) #ifdef CONFIG_OF struct regulator_dev *of_regulator_dev_lookup(struct device *dev, + struct device_node *np, const char *supply); struct regulator_init_data *regulator_of_get_init_data(struct device *dev, const struct regulator_desc *desc, @@ -82,6 +83,7 @@ bool of_check_coupling_data(struct regulator_dev *rdev); #else static inline struct regulator_dev *of_regulator_dev_lookup(struct device *dev, + struct device_node *np, const char *supply) { return ERR_PTR(-ENODEV); diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 0847708b63613..fc8c0bf7ddd9c 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -591,7 +591,8 @@ err_node_put: /** * of_get_regulator - get a regulator device node based on supply name - * @dev: Device pointer for the consumer (of regulator) device + * @dev: Device pointer for dev_printk() messages + * @node: Device node pointer for supply property lookup * @supply: regulator supply name * * Extract the regulator device node corresponding to the supply name. @@ -599,15 +600,16 @@ err_node_put: * Return: Pointer to the &struct device_node corresponding to the regulator * if found, or %NULL if not found. */ -static struct device_node *of_get_regulator(struct device *dev, const char *supply) +static struct device_node *of_get_regulator(struct device *dev, struct device_node *node, + const char *supply) { struct device_node *regnode = NULL; char prop_name[64]; /* 64 is max size of property name */ - dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); + dev_dbg(dev, "Looking up %s-supply from device node %pOF\n", supply, node); snprintf(prop_name, 64, "%s-supply", supply); - regnode = of_parse_phandle(dev->of_node, prop_name, 0); + regnode = of_parse_phandle(node, prop_name, 0); if (regnode) return regnode; @@ -631,6 +633,7 @@ static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) /** * of_regulator_dev_lookup - lookup a regulator device with device tree only * @dev: Device pointer for regulator supply lookup. + * @np: Device node pointer for regulator supply lookup. * @supply: Supply name or regulator ID. * * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR() @@ -645,13 +648,13 @@ static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) * * -%ENODEV if lookup fails permanently. * * -%EPROBE_DEFER if lookup could succeed in the future. */ -struct regulator_dev *of_regulator_dev_lookup(struct device *dev, +struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_node *np, const char *supply) { struct regulator_dev *r; struct device_node *node; - node = of_get_regulator(dev, supply); + node = of_get_regulator(dev, np, supply); if (node) { r = of_find_regulator_by_node(node); of_node_put(node); @@ -668,6 +671,42 @@ struct regulator_dev *of_regulator_dev_lookup(struct device *dev, return ERR_PTR(-ENODEV); } +static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, + const char *id, enum regulator_get_type get_type) +{ + struct regulator_dev *r; + int ret; + + ret = _regulator_get_common_check(dev, id, get_type); + if (ret) + return ERR_PTR(ret); + + r = of_regulator_dev_lookup(dev, node, id); + return _regulator_get_common(r, dev, id, get_type); +} + +/** + * of_regulator_get_optional - get optional regulator via device tree lookup + * @dev: device used for dev_printk() messages + * @node: device node for regulator "consumer" + * @id: Supply name + * + * Return: pointer to struct regulator corresponding to the regulator producer, + * or PTR_ERR() encoded error number. + * + * This is intended for use by consumers that want to get a regulator + * supply directly from a device node, and can and want to deal with + * absence of such supplies. This will _not_ consider supply aliases. + * See regulator_dev_lookup(). + */ +struct regulator *of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id) +{ + return _of_regulator_get(dev, node, id, OPTIONAL_GET); +} +EXPORT_SYMBOL_GPL(of_regulator_get_optional); + /* * Returns number of regulators coupled with rdev. */ diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index a6cdd3ac12ad9..63fbcce097448 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -213,6 +213,19 @@ int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); void devm_regulator_put(struct regulator *regulator); +#if IS_ENABLED(CONFIG_OF) +struct regulator *__must_check of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id); +#else +static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id) +{ + return ERR_PTR(-ENODEV); +} +#endif + int regulator_register_supply_alias(struct device *dev, const char *id, struct device *alias_dev, const char *alias_id); @@ -395,6 +408,13 @@ devm_regulator_get_optional(struct device *dev, const char *id) return ERR_PTR(-ENODEV); } +static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id) +{ + return ERR_PTR(-ENODEV); +} + static inline void regulator_put(struct regulator *regulator) { } -- GitLab From e5c64f547823e950e94151156363ea64021707dc Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 25 Sep 2024 17:38:05 +0800 Subject: [PATCH 102/456] UPSTREAM: regulator: Add devres version of of_regulator_get_optional() There are existing uses for a devres version of of_regulator_get_optional() in power domain drivers. On MediaTek platforms, power domains may have regulator supplies tied to them. The driver currently tries to use devm_regulator_get() to not have to manage the lifecycle, but ends up doing it in a very hacky way by replacing the device node of the power domain controller device to the device node of the power domain that is currently being registered, getting the supply, and reverting the device node. Provide a better API so that the hack can be replaced. Signed-off-by: Chen-Yu Tsai Link: https://patch.msgid.link/20240925093807.1026949-3-wenst@chromium.org Signed-off-by: Mark Brown (cherry picked from commit 36ec3f437227470568e5f460997f367f5446a34d) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I04f53ca37fdce9153157b3adae9d806275242ef3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076455 Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/regulator/devres.c | 39 ++++++++++++++++++++++++++++++ drivers/regulator/internal.h | 16 +++++++----- drivers/regulator/of_regulator.c | 4 +-- include/linux/regulator/consumer.h | 17 +++++++++++++ 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 1b893cdd1aad6..36164aec30e83 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -749,3 +749,42 @@ void *devm_regulator_irq_helper(struct device *dev, return ptr; } EXPORT_SYMBOL_GPL(devm_regulator_irq_helper); + +#if IS_ENABLED(CONFIG_OF) +static struct regulator *_devm_of_regulator_get(struct device *dev, struct device_node *node, + const char *id, int get_type) +{ + struct regulator **ptr, *regulator; + + ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regulator = _of_regulator_get(dev, node, id, get_type); + if (!IS_ERR(regulator)) { + *ptr = regulator; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regulator; +} + +/** + * devm_of_regulator_get_optional - Resource managed of_regulator_get_optional() + * @dev: device used for dev_printk() messages and resource lifetime management + * @node: device node for regulator "consumer" + * @id: supply name or regulator ID. + * + * Managed regulator_get_optional(). Regulators returned from this + * function are automatically regulator_put() on driver detach. See + * of_regulator_get_optional() for more information. + */ +struct regulator *devm_of_regulator_get_optional(struct device *dev, struct device_node *node, + const char *id) +{ + return _devm_of_regulator_get(dev, node, id, OPTIONAL_GET); +} +EXPORT_SYMBOL_GPL(devm_of_regulator_get_optional); +#endif diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index a711d63585c9a..c069507c1d653 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -65,6 +65,13 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev) return container_of(dev, struct regulator_dev, dev); } +enum regulator_get_type { + NORMAL_GET, + EXCLUSIVE_GET, + OPTIONAL_GET, + MAX_GET_TYPE +}; + #ifdef CONFIG_OF struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_node *np, @@ -74,6 +81,9 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, struct regulator_config *config, struct device_node **node); +struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, + const char *id, enum regulator_get_type get_type); + struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev, int index); @@ -116,12 +126,6 @@ static inline bool of_check_coupling_data(struct regulator_dev *rdev) } #endif -enum regulator_get_type { - NORMAL_GET, - EXCLUSIVE_GET, - OPTIONAL_GET, - MAX_GET_TYPE -}; int _regulator_get_common_check(struct device *dev, const char *id, enum regulator_get_type get_type); diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index fc8c0bf7ddd9c..637f4d02be9a5 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -671,8 +671,8 @@ struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_ return ERR_PTR(-ENODEV); } -static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, - const char *id, enum regulator_get_type get_type) +struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, + const char *id, enum regulator_get_type get_type) { struct regulator_dev *r; int ret; diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 63fbcce097448..34ff926c42875 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -217,6 +217,9 @@ void devm_regulator_put(struct regulator *regulator); struct regulator *__must_check of_regulator_get_optional(struct device *dev, struct device_node *node, const char *id); +struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id); #else static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, struct device_node *node, @@ -224,6 +227,13 @@ static inline struct regulator *__must_check of_regulator_get_optional(struct de { return ERR_PTR(-ENODEV); } + +static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id) +{ + return ERR_PTR(-ENODEV); +} #endif int regulator_register_supply_alias(struct device *dev, const char *id, @@ -415,6 +425,13 @@ static inline struct regulator *__must_check of_regulator_get_optional(struct de return ERR_PTR(-ENODEV); } +static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, + struct device_node *node, + const char *id) +{ + return ERR_PTR(-ENODEV); +} + static inline void regulator_put(struct regulator *regulator) { } -- GitLab From a03c611bed300597e2bf392eee201c336527e783 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Thu, 6 Jun 2024 09:22:37 +0200 Subject: [PATCH 103/456] UPSTREAM: dev_printk: add new dev_err_probe() helpers This is similar to dev_err_probe() but for cases where an ERR_PTR() or ERR_CAST() is to be returned simplifying patterns like: dev_err_probe(dev, ret, ...); return ERR_PTR(ret) or dev_err_probe(dev, PTR_ERR(ptr), ...); return ERR_CAST(ptr) Signed-off-by: Nuno Sa Link: https://patch.msgid.link/20240606-dev-add_dev_errp_probe-v3-1-51bb229edd79@analog.com Signed-off-by: Jonathan Cameron (cherry picked from commit dbbe7eaf0e4795bf003ac06872aaf52b6b6b1310) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ia4b497247078dd586e2ab35f544c812921ebc0c4 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076456 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- include/linux/dev_printk.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h index ae80a303c216b..ca32b5bb28eb5 100644 --- a/include/linux/dev_printk.h +++ b/include/linux/dev_printk.h @@ -277,4 +277,12 @@ do { \ __printf(3, 4) int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); +/* Simple helper for dev_err_probe() when ERR_PTR() is to be returned. */ +#define dev_err_ptr_probe(dev, ___err, fmt, ...) \ + ERR_PTR(dev_err_probe(dev, ___err, fmt, ##__VA_ARGS__)) + +/* Simple helper for dev_err_probe() when ERR_CAST() is to be returned. */ +#define dev_err_cast_probe(dev, ___err_ptr, fmt, ...) \ + ERR_PTR(dev_err_probe(dev, PTR_ERR(___err_ptr), fmt, ##__VA_ARGS__)) + #endif /* _DEVICE_PRINTK_H_ */ -- GitLab From 9ab31b1eaa005a2b301d7e29d2492db2f1f9b12a Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 28 Aug 2024 20:12:30 +0800 Subject: [PATCH 104/456] UPSTREAM: pmdomain: mediatek: make use of dev_err_cast_probe() Using dev_err_cast_probe() to simplify the code. Signed-off-by: Hongbo Li Reviewed-by: Matthias Brugger Link: https://lore.kernel.org/r/20240828121230.3696315-1-lihongbo22@huawei.com Signed-off-by: Ulf Hansson (cherry picked from commit 391a2e64d757a0d22a99676930b5aee29f4a4f35) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I0a65681c21b918c2b8c0562070382f4ffb6841e5 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076457 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/pmdomain/mediatek/mtk-pm-domains.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c index edded392950ce..058ad98e39527 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -353,12 +353,10 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no scpsys->dev->of_node = node; pd->supply = devm_regulator_get(scpsys->dev, "domain"); scpsys->dev->of_node = root_node; - if (IS_ERR(pd->supply)) { - dev_err_probe(scpsys->dev, PTR_ERR(pd->supply), + if (IS_ERR(pd->supply)) + return dev_err_cast_probe(scpsys->dev, pd->supply, "%pOF: failed to get power supply.\n", node); - return ERR_CAST(pd->supply); - } } pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg"); -- GitLab From bc413794cb8616c06214bf1ac11ffd95b61ec767 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 30 Sep 2024 12:45:23 +0800 Subject: [PATCH 105/456] UPSTREAM: pmdomain: mediatek: Use OF-specific regulator API to get power domain supply The MediaTek power domain driver contains a hack that assigns the device node of the power domain to the struct device of the power domain controller in order to use the devres regulator API. Now that there is a proper OF-specific regulator API, and even a devres version, replace the hack with proper code. This change is incompatible with incomplete device trees. Instead of assigning the dummy regulator in cases where the power domain requires a supply but the device tree does not provide one, the driver will just error out. This will be seen on the MT8390 EVK, which is missing supplies for the IMG_VCORE and CAM_VCORE domains. And likely all the MediaTek EVBs, which have no power domain supplies specified. This is however the correct behavior. If the power domain's supply is missing, then it should not work. Relying on other parts of the system to keep the unattached regulator enabled is likely to break in ways less easier to understand. Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20240930044525.2043884-4-wenst@chromium.org Signed-off-by: Ulf Hansson (cherry picked from commit ca824b2d69c52b3a9cc51b4b7f9ed8c8e554487a) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I6f37c8b73ad036a7f389d3c544a0ead4b5d12295 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076458 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/pmdomain/mediatek/mtk-pm-domains.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c index 058ad98e39527..6702aaa1a24f3 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -308,7 +308,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no { const struct scpsys_domain_data *domain_data; struct scpsys_domain *pd; - struct device_node *root_node = scpsys->dev->of_node; struct device_node *smi_node; struct property *prop; const char *clk_name; @@ -343,16 +342,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no pd->scpsys = scpsys; if (MTK_SCPD_CAPS(pd, MTK_SCPD_DOMAIN_SUPPLY)) { - /* - * Find regulator in current power domain node. - * devm_regulator_get() finds regulator in a node and its child - * node, so set of_node to current power domain node then change - * back to original node after regulator is found for current - * power domain node. - */ - scpsys->dev->of_node = node; - pd->supply = devm_regulator_get(scpsys->dev, "domain"); - scpsys->dev->of_node = root_node; + pd->supply = devm_of_regulator_get_optional(scpsys->dev, node, "domain"); if (IS_ERR(pd->supply)) return dev_err_cast_probe(scpsys->dev, pd->supply, "%pOF: failed to get power supply.\n", -- GitLab From 1ccc63e8e2e4b160a8d5fe1dfc3c2a0746e7e589 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 8 Oct 2024 15:34:22 +0800 Subject: [PATCH 106/456] UPSTREAM: i2c: core: Remove extra space in Makefile Some lines in the Makefile have a space before tabs. Remove those. Reported-by: Andy Shevchenko Closes: https://lore.kernel.org/all/ZsdE0PxKnGRjzChl@smile.fi.intel.com/ Signed-off-by: Chen-Yu Tsai Reviewed-by: Andy Shevchenko Reviewed-by: Andi Shyti Signed-off-by: Wolfram Sang (cherry picked from commit 3b2af08fadc4c931d3014e03804bf21afbcaa666) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I2467b7e114fa6c3e72550253ce1f13b2bd359caf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076459 Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/i2c/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 3f71ce4711e35..f12d6b10a85e9 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -5,10 +5,10 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o obj-$(CONFIG_I2C) += i2c-core.o -i2c-core-objs := i2c-core-base.o i2c-core-smbus.o +i2c-core-objs := i2c-core-base.o i2c-core-smbus.o i2c-core-$(CONFIG_ACPI) += i2c-core-acpi.o -i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o -i2c-core-$(CONFIG_OF) += i2c-core-of.o +i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o +i2c-core-$(CONFIG_OF) += i2c-core-of.o obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o -- GitLab From 657a5e4593e8da7c4054d258a9d2db6db50da02a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 9 Apr 2024 13:59:39 -0500 Subject: [PATCH 107/456] UPSTREAM: of: Add a helper to free property struct Freeing a property struct is 3 kfree()'s which is duplicated in multiple spots. Add a helper, __of_prop_free(), and replace all the open coded cases in the DT code. Reviewed-by: Saravana Kannan Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/20240409-dt-cleanup-free-v2-1-5b419a4af38d@kernel.org Signed-off-by: Rob Herring (cherry picked from commit 1c5e3d9bf33b811e1c6dd9081b322004acc4a1fd) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I9d402ab9dd6d62e9969e473c382858f3b2d11990 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076460 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/of/dynamic.c | 26 ++++++++++++-------------- drivers/of/of_private.h | 1 + drivers/of/overlay.c | 11 +++-------- drivers/of/unittest.c | 12 +++--------- 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 4d57a4e341054..8d38b40938d5f 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -306,15 +306,20 @@ int of_detach_node(struct device_node *np) } EXPORT_SYMBOL_GPL(of_detach_node); +void __of_prop_free(struct property *prop) +{ + kfree(prop->name); + kfree(prop->value); + kfree(prop); +} + static void property_list_free(struct property *prop_list) { struct property *prop, *next; for (prop = prop_list; prop != NULL; prop = next) { next = prop->next; - kfree(prop->name); - kfree(prop->value); - kfree(prop); + __of_prop_free(prop); } } @@ -427,9 +432,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) return new; err_free: - kfree(new->name); - kfree(new->value); - kfree(new); + __of_prop_free(new); return NULL; } @@ -471,9 +474,7 @@ struct device_node *__of_node_dup(const struct device_node *np, if (!new_pp) goto err_prop; if (__of_add_property(node, new_pp)) { - kfree(new_pp->name); - kfree(new_pp->value); - kfree(new_pp); + __of_prop_free(new_pp); goto err_prop; } } @@ -933,11 +934,8 @@ static int of_changeset_add_prop_helper(struct of_changeset *ocs, return -ENOMEM; ret = of_changeset_add_property(ocs, np, new_pp); - if (ret) { - kfree(new_pp->name); - kfree(new_pp->value); - kfree(new_pp); - } + if (ret) + __of_prop_free(new_pp); return ret; } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 21f8f5e80917d..73b55f4f84a3c 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -123,6 +123,7 @@ extern void *__unflatten_device_tree(const void *blob, * own the devtree lock or work on detached trees only. */ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); +void __of_prop_free(struct property *prop); struct device_node *__of_node_dup(const struct device_node *np, const char *full_name); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index a9a292d6d59b2..dc13299586414 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -262,9 +262,7 @@ static struct property *dup_and_fixup_symbol_prop( return new_prop; err_free_new_prop: - kfree(new_prop->name); - kfree(new_prop->value); - kfree(new_prop); + __of_prop_free(new_prop); err_free_target_path: kfree(target_path); @@ -361,11 +359,8 @@ static int add_changeset_property(struct overlay_changeset *ovcs, pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n", target->np, new_prop->name); - if (ret) { - kfree(new_prop->name); - kfree(new_prop->value); - kfree(new_prop); - } + if (ret) + __of_prop_free(new_prop); return ret; } diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 3b22c36bfb0b7..5bfec440b4fd7 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -800,15 +800,11 @@ static void __init of_unittest_property_copy(void) new = __of_prop_dup(&p1, GFP_KERNEL); unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\n"); - kfree(new->value); - kfree(new->name); - kfree(new); + __of_prop_free(new); new = __of_prop_dup(&p2, GFP_KERNEL); unittest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n"); - kfree(new->value); - kfree(new->name); - kfree(new); + __of_prop_free(new); #endif } @@ -3665,9 +3661,7 @@ static __init void of_unittest_overlay_high_level(void) goto err_unlock; } if (__of_add_property(of_symbols, new_prop)) { - kfree(new_prop->name); - kfree(new_prop->value); - kfree(new_prop); + __of_prop_free(new_prop); /* "name" auto-generated by unflatten */ if (!strcmp(prop->name, "name")) continue; -- GitLab From 4ef2cd620d2d1cde9a62de3405afb98b314c0ebc Mon Sep 17 00:00:00 2001 From: Herve Codina Date: Mon, 27 May 2024 18:14:42 +0200 Subject: [PATCH 108/456] UPSTREAM: of: dynamic: Introduce of_changeset_add_prop_bool() APIs to add some properties in a changeset exist but nothing to add a DT boolean property (i.e. a property without any values). Fill this lack with of_changeset_add_prop_bool(). Signed-off-by: Herve Codina Link: https://lore.kernel.org/r/20240527161450.326615-16-herve.codina@bootlin.com Signed-off-by: Rob Herring (Arm) (cherry picked from commit f2b388d63e6c7c6151bb295e5cbf48a2ac91e51a) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I1f5b5ff0f4dd06371ef035846c941cbf73d87180 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076461 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/of/dynamic.c | 25 +++++++++++++++++++++++++ include/linux/of.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 8d38b40938d5f..e342eb37e6a80 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -1050,3 +1050,28 @@ int of_changeset_add_prop_u32_array(struct of_changeset *ocs, return ret; } EXPORT_SYMBOL_GPL(of_changeset_add_prop_u32_array); + +/** + * of_changeset_add_prop_bool - Add a boolean property (i.e. a property without + * any values) to a changeset. + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be added + * + * Create a boolean property and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, + const char *prop_name) +{ + struct property prop; + + prop.name = (char *)prop_name; + prop.length = 0; + prop.value = NULL; + + return of_changeset_add_prop_helper(ocs, np, &prop); +} +EXPORT_SYMBOL_GPL(of_changeset_add_prop_bool); diff --git a/include/linux/of.h b/include/linux/of.h index dfc687c33d55a..7dc098bb584ff 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1625,6 +1625,9 @@ static inline int of_changeset_add_prop_u32(struct of_changeset *ocs, return of_changeset_add_prop_u32_array(ocs, np, prop_name, &val, 1); } +int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, + const char *prop_name); + #else /* CONFIG_OF_DYNAMIC */ static inline int of_reconfig_notifier_register(struct notifier_block *nb) { -- GitLab From ad7cb739a3c572766e1b699f82dae5b1fcacc662 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:28 +0800 Subject: [PATCH 109/456] UPSTREAM: of: dynamic: Add of_changeset_update_prop_string Add a helper function to add string property updates to an OF changeset. This is similar to of_changeset_add_prop_string(), but instead of adding the property (and failing if it exists), it will update the property. This shall be used later in the DT hardware prober. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring (Arm) Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 81de291d86b704de1809cfb06672902d003cf3a3) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Id72c1d3163925cbfb8ca16d24a9bb20bd4dcd66e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076462 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/of/dynamic.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index e342eb37e6a80..41c24abc43e0b 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -1075,3 +1075,47 @@ int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, return of_changeset_add_prop_helper(ocs, np, &prop); } EXPORT_SYMBOL_GPL(of_changeset_add_prop_bool); + +static int of_changeset_update_prop_helper(struct of_changeset *ocs, + struct device_node *np, + const struct property *pp) +{ + struct property *new_pp; + int ret; + + new_pp = __of_prop_dup(pp, GFP_KERNEL); + if (!new_pp) + return -ENOMEM; + + ret = of_changeset_update_property(ocs, np, new_pp); + if (ret) + __of_prop_free(new_pp); + + return ret; +} + +/** + * of_changeset_update_prop_string - Add a string property update to a changeset + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be updated + * @str: pointer to null terminated string + * + * Create a string property to be updated and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_update_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str) +{ + struct property prop = { + .name = (char *)prop_name, + .length = strlen(str) + 1, + .value = (void *)str, + }; + + return of_changeset_update_prop_helper(ocs, np, &prop); +} +EXPORT_SYMBOL_GPL(of_changeset_update_prop_string); diff --git a/include/linux/of.h b/include/linux/of.h index 7dc098bb584ff..d05b4f1f16745 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1625,6 +1625,10 @@ static inline int of_changeset_add_prop_u32(struct of_changeset *ocs, return of_changeset_add_prop_u32_array(ocs, np, prop_name, &val, 1); } +int of_changeset_update_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str); + int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, const char *prop_name); -- GitLab From db65ab0c0447eff50346dfb7a84ccd155c53d874 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 10 Jan 2024 01:14:34 +0000 Subject: [PATCH 110/456] UPSTREAM: of: Add __of_device_is_status() and makes more generic status check Linux Kernel has __of_device_is_available() / __of_device_is_fail(), these are checking if the status was "okay" / "ok" / "fail" / "fail-". Add more generic __of_device_is_status() function for these. Signed-off-by: Kuninori Morimoto Tested-by: Yusuke Goda Reviewed-by: Rob Herring Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/87cyuagfba.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Geert Uytterhoeven (cherry picked from commit b5056ecf7cf92b7b38a54f0dbf705c31ca346e23) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ib5b9e2fed3387e2e801bc8086419b141810629ac Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076463 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/of/base.c | 57 ++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 38da5b1a18b41..9069abef4dff5 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -416,15 +416,8 @@ bool of_machine_compatible_match(const char *const *compats) } EXPORT_SYMBOL(of_machine_compatible_match); -/** - * __of_device_is_available - check if a device is available for use - * - * @device: Node to check for availability, with locks already held - * - * Return: True if the status property is absent or set to "okay" or "ok", - * false otherwise - */ -static bool __of_device_is_available(const struct device_node *device) +static bool __of_device_is_status(const struct device_node *device, + const char * const*strings) { const char *status; int statlen; @@ -434,16 +427,45 @@ static bool __of_device_is_available(const struct device_node *device) status = __of_get_property(device, "status", &statlen); if (status == NULL) - return true; + return false; if (statlen > 0) { - if (!strcmp(status, "okay") || !strcmp(status, "ok")) - return true; + while (*strings) { + unsigned int len = strlen(*strings); + + if ((*strings)[len - 1] == '-') { + if (!strncmp(status, *strings, len)) + return true; + } else { + if (!strcmp(status, *strings)) + return true; + } + strings++; + } } return false; } +/** + * __of_device_is_available - check if a device is available for use + * + * @device: Node to check for availability, with locks already held + * + * Return: True if the status property is absent or set to "okay" or "ok", + * false otherwise + */ +static bool __of_device_is_available(const struct device_node *device) +{ + static const char * const ok[] = {"okay", "ok", NULL}; + + if (!device) + return false; + + return !__of_get_property(device, "status", NULL) || + __of_device_is_status(device, ok); +} + /** * of_device_is_available - check if a device is available for use * @@ -475,16 +497,9 @@ EXPORT_SYMBOL(of_device_is_available); */ static bool __of_device_is_fail(const struct device_node *device) { - const char *status; - - if (!device) - return false; - - status = __of_get_property(device, "status", NULL); - if (status == NULL) - return false; + static const char * const fail[] = {"fail", "fail-", NULL}; - return !strcmp(status, "fail") || !strncmp(status, "fail-", 5); + return __of_device_is_status(device, fail); } /** -- GitLab From 7f9c16397d2df508d82d3b7fb3a6da6630cfabde Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 10 Jan 2024 01:14:43 +0000 Subject: [PATCH 111/456] UPSTREAM: of: Add of_get_next_status_child() and makes more generic of_get_next Linux Kernel has of_get_next_available_child(). Add more generic of_get_next_status_child() to enable to use same logic for other status. Signed-off-by: Kuninori Morimoto Tested-by: Yusuke Goda Reviewed-by: Rob Herring Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/87bk9ugfb0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Geert Uytterhoeven (cherry picked from commit 8918283af1bd68f46f75164289492988dbc67a41) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I2a83767d24846e1003447efd9613f9cc7f92263b Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076464 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/of/base.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 9069abef4dff5..c4b07593c9c7d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -613,16 +613,9 @@ struct device_node *of_get_next_child(const struct device_node *node, } EXPORT_SYMBOL(of_get_next_child); -/** - * of_get_next_available_child - Find the next available child node - * @node: parent node - * @prev: previous child of the parent node, or NULL to get first - * - * This function is like of_get_next_child(), except that it - * automatically skips any disabled nodes (i.e. status = "disabled"). - */ -struct device_node *of_get_next_available_child(const struct device_node *node, - struct device_node *prev) +static struct device_node *of_get_next_status_child(const struct device_node *node, + struct device_node *prev, + bool (*checker)(const struct device_node *)) { struct device_node *next; unsigned long flags; @@ -633,7 +626,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node, raw_spin_lock_irqsave(&devtree_lock, flags); next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) { - if (!__of_device_is_available(next)) + if (!checker(next)) continue; if (of_node_get(next)) break; @@ -642,6 +635,20 @@ struct device_node *of_get_next_available_child(const struct device_node *node, raw_spin_unlock_irqrestore(&devtree_lock, flags); return next; } + +/** + * of_get_next_available_child - Find the next available child node + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * This function is like of_get_next_child(), except that it + * automatically skips any disabled nodes (i.e. status = "disabled"). + */ +struct device_node *of_get_next_available_child(const struct device_node *node, + struct device_node *prev) +{ + return of_get_next_status_child(node, prev, __of_device_is_available); +} EXPORT_SYMBOL(of_get_next_available_child); /** -- GitLab From dddf0277e1ddf79bf5d0650841e9495c69473792 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:29 +0800 Subject: [PATCH 112/456] UPSTREAM: of: base: Add for_each_child_of_node_with_prefix() There are cases where drivers would go through child device nodes and operate on only the ones whose node name starts with a given prefix. Provide a helper for these users. This will mainly be used in a subsequent patch that implements a hardware component prober for I2C busses. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring (Arm) Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 1fcc67e3a354865775355eafec1fb061a755c971) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I05e297316835eafbe29eb88842de4e06516b072f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076465 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/of/base.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/of.h | 9 +++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index c4b07593c9c7d..6ebdd46329402 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -613,6 +613,41 @@ struct device_node *of_get_next_child(const struct device_node *node, } EXPORT_SYMBOL(of_get_next_child); +/** + * of_get_next_child_with_prefix - Find the next child node with prefix + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * This function is like of_get_next_child(), except that it automatically + * skips any nodes whose name doesn't have the given prefix. + * + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix) +{ + struct device_node *next; + unsigned long flags; + + if (!node) + return NULL; + + raw_spin_lock_irqsave(&devtree_lock, flags); + next = prev ? prev->sibling : node->child; + for (; next; next = next->sibling) { + if (!of_node_name_prefix(next, prefix)) + continue; + if (of_node_get(next)) + break; + } + of_node_put(prev); + raw_spin_unlock_irqrestore(&devtree_lock, flags); + return next; +} +EXPORT_SYMBOL(of_get_next_child_with_prefix); + static struct device_node *of_get_next_status_child(const struct device_node *node, struct device_node *prev, bool (*checker)(const struct device_node *)) diff --git a/include/linux/of.h b/include/linux/of.h index d05b4f1f16745..c74df54164c5d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -289,6 +289,9 @@ extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_next_parent(struct device_node *node); extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); +extern struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix); extern struct device_node *of_get_next_available_child( const struct device_node *node, struct device_node *prev); @@ -1445,6 +1448,12 @@ static inline int of_property_read_s32(const struct device_node *np, child != NULL; \ child = of_get_next_child(parent, child)) +#define for_each_child_of_node_with_prefix(parent, child, prefix) \ + for (struct device_node *child __free(device_node) = \ + of_get_next_child_with_prefix(parent, NULL, prefix); \ + child != NULL; \ + child = of_get_next_child_with_prefix(parent, child, prefix)) + #define for_each_available_child_of_node(parent, child) \ for (child = of_get_next_available_child(parent, NULL); child != NULL; \ child = of_get_next_available_child(parent, child)) -- GitLab From d70b9de7e65b3f1ae09f5a663ba74e10b234e39d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 28 Nov 2024 12:26:30 +0800 Subject: [PATCH 113/456] UPSTREAM: of: base: Document prefix argument for of_get_next_child_with_prefix() When of_get_next_child_with_prefix() was added, the prefix argument was left undocumented. This caused a new warning to be generated during the kerneldoc build process: drivers/of/base.c:661: warning: Function parameter or struct member 'prefix' not described in 'of_get_next_child_with_prefix' Properly document the argument to fix this. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202411280010.KGSDBOUE-lkp@intel.com/ Fixes: 1fcc67e3a354 ("of: base: Add for_each_child_of_node_with_prefix()") Signed-off-by: Chen-Yu Tsai Signed-off-by: Wolfram Sang (cherry picked from commit 0d40daa1c1369c2fef6a40f44640b2e5f3453daa) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I2c06922f32d2039ecdb264040bf0ffcc978d8230 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076466 Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/of/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 6ebdd46329402..0ba27e4760de0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -617,6 +617,7 @@ EXPORT_SYMBOL(of_get_next_child); * of_get_next_child_with_prefix - Find the next child node with prefix * @node: parent node * @prev: previous child of the parent node, or NULL to get first + * @prefix: prefix that the node name should have * * This function is like of_get_next_child(), except that it automatically * skips any nodes whose name doesn't have the given prefix. -- GitLab From 95711dea5830c3336f798aef3ccdf129d173cc50 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:30 +0800 Subject: [PATCH 114/456] UPSTREAM: i2c: Introduce OF component probe function Some devices are designed and manufactured with some components having multiple drop-in replacement options. These components are often connected to the mainboard via ribbon cables, having the same signals and pin assignments across all options. These may include the display panel and touchscreen on laptops and tablets, and the trackpad on laptops. Sometimes which component option is used in a particular device can be detected by some firmware provided identifier, other times that information is not available, and the kernel has to try to probe each device. This change attempts to make the "probe each device" case cleaner. The current approach is to have all options added and enabled in the device tree. The kernel would then bind each device and run each driver's probe function. This works, but has been broken before due to the introduction of asynchronous probing, causing multiple instances requesting "shared" resources, such as pinmuxes, GPIO pins, interrupt lines, at the same time, with only one instance succeeding. Work arounds for these include moving the pinmux to the parent I2C controller, using GPIO hogs or pinmux settings to keep the GPIO pins in some fixed configuration, and requesting the interrupt line very late. Such configurations can be seen on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based Lenovo Thinkpad 13S. Instead of this delicate dance between drivers and device tree quirks, this change introduces a simple I2C component probe function. For a given class of devices on the same I2C bus, it will go through all of them, doing a simple I2C read transfer and see which one of them responds. It will then enable the device that responds. This requires some minor modifications in the existing device tree. The status for all the device nodes for the component options must be set to "fail-needs-probe". This makes it clear that some mechanism is needed to enable one of them, and also prevents the prober and device drivers running at the same time. Signed-off-by: Chen-Yu Tsai Reviewed-by: Andy Shevchenko Reviewed-by: Douglas Anderson Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 157ce8f381efe264933e9366db828d845bade3a1) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ib227baf54c40cca9011537e9f9ca91fc085b1da0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076467 Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- MAINTAINERS | 8 ++ drivers/i2c/Makefile | 1 + drivers/i2c/i2c-core-of-prober.c | 183 +++++++++++++++++++++++++++++++ include/linux/i2c-of-prober.h | 75 +++++++++++++ 4 files changed, 267 insertions(+) create mode 100644 drivers/i2c/i2c-core-of-prober.c create mode 100644 include/linux/i2c-of-prober.h diff --git a/MAINTAINERS b/MAINTAINERS index e8b8ce6e64f82..3c39aa493cb87 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9886,6 +9886,14 @@ S: Maintained F: Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml F: drivers/i2c/busses/i2c-mv64xxx.c +I2C OF COMPONENT PROBER +M: Chen-Yu Tsai +L: linux-i2c@vger.kernel.org +L: devicetree@vger.kernel.org +S: Maintained +F: drivers/i2c/i2c-core-of-prober.c +F: include/linux-i2c-of-prober.h + I2C OVER PARALLEL PORT M: Jean Delvare L: linux-i2c@vger.kernel.org diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index f12d6b10a85e9..c539cdc1e3051 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -9,6 +9,7 @@ i2c-core-objs := i2c-core-base.o i2c-core-smbus.o i2c-core-$(CONFIG_ACPI) += i2c-core-acpi.o i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o i2c-core-$(CONFIG_OF) += i2c-core-of.o +i2c-core-$(CONFIG_OF_DYNAMIC) += i2c-core-of-prober.o obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c new file mode 100644 index 0000000000000..21f7a47692936 --- /dev/null +++ b/drivers/i2c/i2c-core-of-prober.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Linux I2C core OF component prober code + * + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Some devices, such as Google Hana Chromebooks, are produced by multiple + * vendors each using their preferred components. Such components are all + * in the device tree. Instead of having all of them enabled and having each + * driver separately try and probe its device while fighting over shared + * resources, they can be marked as "fail-needs-probe" and have a prober + * figure out which one is actually used beforehand. + * + * This prober assumes such drop-in parts are on the same I2C bus, have + * non-conflicting addresses, and can be directly probed by seeing which + * address responds. + * + * TODO: + * - Support handling common regulators. + * - Support handling common GPIOs. + * - Support I2C muxes + */ + +static struct device_node *i2c_of_probe_get_i2c_node(struct device *dev, const char *type) +{ + struct device_node *node __free(device_node) = of_find_node_by_name(NULL, type); + if (!node) { + dev_err(dev, "Could not find %s device node\n", type); + return NULL; + } + + struct device_node *i2c_node __free(device_node) = of_get_parent(node); + if (!of_node_name_eq(i2c_node, "i2c")) { + dev_err(dev, "%s device isn't on I2C bus\n", type); + return NULL; + } + + if (!of_device_is_available(i2c_node)) { + dev_err(dev, "I2C controller not available\n"); + return NULL; + } + + return no_free_ptr(i2c_node); +} + +static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node) +{ + int ret; + + dev_dbg(dev, "Enabling %pOF\n", node); + + struct of_changeset *ocs __free(kfree) = kzalloc(sizeof(*ocs), GFP_KERNEL); + if (!ocs) + return -ENOMEM; + + of_changeset_init(ocs); + ret = of_changeset_update_prop_string(ocs, node, "status", "okay"); + if (ret) + return ret; + + ret = of_changeset_apply(ocs); + if (ret) { + /* ocs needs to be explicitly cleaned up before being freed. */ + of_changeset_destroy(ocs); + } else { + /* + * ocs is intentionally kept around as it needs to + * exist as long as the change is applied. + */ + void *ptr __always_unused = no_free_ptr(ocs); + } + + return ret; +} + +static const struct i2c_of_probe_ops i2c_of_probe_dummy_ops; + +/** + * i2c_of_probe_component() - probe for devices of "type" on the same i2c bus + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages. + * @cfg: Pointer to the &struct i2c_of_probe_cfg containing callbacks and other options + * for the prober. + * @ctx: Context data for callbacks. + * + * Probe for possible I2C components of the same "type" (&i2c_of_probe_cfg->type) + * on the same I2C bus that have their status marked as "fail-needs-probe". + * + * Assumes that across the entire device tree the only instances of nodes + * with "type" prefixed node names (not including the address portion) are + * the ones that need handling for second source components. In other words, + * if "type" is "touchscreen", then all device nodes named "touchscreen*" + * are the ones that need probing. There cannot be another "touchscreen*" + * node that is already enabled. + * + * Assumes that for each "type" of component, only one actually exists. In + * other words, only one matching and existing device will be enabled. + * + * Context: Process context only. Does non-atomic I2C transfers. + * Should only be used from a driver probe function, as the function + * can return -EPROBE_DEFER if the I2C adapter or other resources + * are unavailable. + * Return: 0 on success or no-op, error code otherwise. + * A no-op can happen when it seems like the device tree already + * has components of the type to be probed already enabled. This + * can happen when the device tree had not been updated to mark + * the status of the to-be-probed components as "fail-needs-probe". + * Or this function was already run with the same parameters and + * succeeded in enabling a component. The latter could happen if + * the user had multiple types of components to probe, and one of + * them down the list caused a deferred probe. This is expected + * behavior. + */ +int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx) +{ + const struct i2c_of_probe_ops *ops; + const char *type; + struct i2c_adapter *i2c; + int ret; + + ops = cfg->ops ?: &i2c_of_probe_dummy_ops; + type = cfg->type; + + struct device_node *i2c_node __free(device_node) = i2c_of_probe_get_i2c_node(dev, type); + if (!i2c_node) + return -ENODEV; + + /* + * If any devices of the given "type" are already enabled then this function is a no-op. + * Either the device tree hasn't been modified to work with this probe function, or the + * function had already run before and enabled some component. + */ + for_each_child_of_node_with_prefix(i2c_node, node, type) + if (of_device_is_available(node)) + return 0; + + i2c = of_get_i2c_adapter_by_node(i2c_node); + if (!i2c) + return dev_err_probe(dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n"); + + /* Grab and enable resources */ + ret = 0; + if (ops->enable) + ret = ops->enable(dev, i2c_node, ctx); + if (ret) + goto out_put_i2c_adapter; + + for_each_child_of_node_with_prefix(i2c_node, node, type) { + union i2c_smbus_data data; + u32 addr; + + if (of_property_read_u32(node, "reg", &addr)) + continue; + if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0) + continue; + + /* Found a device that is responding */ + if (ops->cleanup_early) + ops->cleanup_early(dev, ctx); + ret = i2c_of_probe_enable_node(dev, node); + break; + } + + if (ops->cleanup) + ops->cleanup(dev, ctx); +out_put_i2c_adapter: + i2c_put_adapter(i2c); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_component, I2C_OF_PROBER); diff --git a/include/linux/i2c-of-prober.h b/include/linux/i2c-of-prober.h new file mode 100644 index 0000000000000..e7e052ac9e482 --- /dev/null +++ b/include/linux/i2c-of-prober.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Definitions for the Linux I2C OF component prober + * + * Copyright (C) 2024 Google LLC + */ + +#ifndef _LINUX_I2C_OF_PROBER_H +#define _LINUX_I2C_OF_PROBER_H + +#include + +struct device; +struct device_node; + +/** + * struct i2c_of_probe_ops - I2C OF component prober callbacks + * + * A set of callbacks to be used by i2c_of_probe_component(). + * + * All callbacks are optional. Callbacks are called only once per run, and are + * used in the order they are defined in this structure. + * + * All callbacks that have return values shall return %0 on success, + * or a negative error number on failure. + * + * The @dev parameter passed to the callbacks is the same as @dev passed to + * i2c_of_probe_component(). It should only be used for dev_printk() calls + * and nothing else, especially not managed device resource (devres) APIs. + */ +struct i2c_of_probe_ops { + /** + * @enable: Retrieve and enable resources so that the components respond to probes. + * + * It is OK for this callback to return -EPROBE_DEFER since the intended use includes + * retrieving resources and enables them. Resources should be reverted to their initial + * state and released before returning if this fails. + */ + int (*enable)(struct device *dev, struct device_node *bus_node, void *data); + + /** + * @cleanup_early: Release exclusive resources prior to calling probe() on a + * detected component. + * + * Only called if a matching component is actually found. If none are found, + * resources that would have been released in this callback should be released in + * @free_resourcs_late instead. + */ + void (*cleanup_early)(struct device *dev, void *data); + + /** + * @cleanup: Opposite of @enable to balance refcounts and free resources after probing. + * + * Should check if resources were already freed by @cleanup_early. + */ + void (*cleanup)(struct device *dev, void *data); +}; + +/** + * struct i2c_of_probe_cfg - I2C OF component prober configuration + * @ops: Callbacks for the prober to use. + * @type: A string to match the device node name prefix to probe for. + */ +struct i2c_of_probe_cfg { + const struct i2c_of_probe_ops *ops; + const char *type; +}; + +#if IS_ENABLED(CONFIG_OF_DYNAMIC) + +int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx); + +#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ + +#endif /* _LINUX_I2C_OF_PROBER_H */ -- GitLab From a7291a45fef3fc5a98851b7cfffd179702a508cb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:31 +0800 Subject: [PATCH 115/456] UPSTREAM: i2c: of-prober: Add simple helpers for regulator support Add helpers to do regulator management for the I2C OF component prober. Components that the prober intends to probe likely require their regulator supplies be enabled, and GPIOs be toggled to enable them or bring them out of reset before they will respond to probe attempts. GPIOs will be handled in the next patch. The assumption is that the same class of components to be probed are always connected in the same fashion with the same regulator supply and GPIO. The names may vary due to binding differences, but the physical layout does not change. This set of helpers supports at most one regulator supply. The user must specify the node from which the supply is retrieved. The supply name and the amount of time to wait after the supply is enabled are also given by the user. Signed-off-by: Chen-Yu Tsai Reviewed-by: Douglas Anderson Reviewed-by: Andy Shevchenko Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 897261149d255d03fc90bec6782e3835cacbfdde) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I608eeb8c07e8d361a15beab87d19e94eb7e5a467 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076468 Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/i2c/i2c-core-of-prober.c | 138 ++++++++++++++++++++++++++++++- include/linux/i2c-of-prober.h | 44 ++++++++++ 2 files changed, 181 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c index 21f7a47692936..76df75c51caee 100644 --- a/drivers/i2c/i2c-core-of-prober.c +++ b/drivers/i2c/i2c-core-of-prober.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include @@ -29,7 +31,6 @@ * address responds. * * TODO: - * - Support handling common regulators. * - Support handling common GPIOs. * - Support I2C muxes */ @@ -181,3 +182,138 @@ out_put_i2c_adapter: return ret; } EXPORT_SYMBOL_NS_GPL(i2c_of_probe_component, I2C_OF_PROBER); + +static int i2c_of_probe_simple_get_supply(struct device *dev, struct device_node *node, + struct i2c_of_probe_simple_ctx *ctx) +{ + const char *supply_name; + struct regulator *supply; + + /* + * It's entirely possible for the component's device node to not have the + * regulator supplies. While it does not make sense from a hardware perspective, + * the supplies could be always on or otherwise not modeled in the device tree, + * but the device would still work. + */ + supply_name = ctx->opts->supply_name; + if (!supply_name) + return 0; + + supply = of_regulator_get_optional(dev, node, supply_name); + if (IS_ERR(supply)) { + return dev_err_probe(dev, PTR_ERR(supply), + "Failed to get regulator supply \"%s\" from %pOF\n", + supply_name, node); + } + + ctx->supply = supply; + + return 0; +} + +static void i2c_of_probe_simple_put_supply(struct i2c_of_probe_simple_ctx *ctx) +{ + regulator_put(ctx->supply); + ctx->supply = NULL; +} + +static int i2c_of_probe_simple_enable_regulator(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + int ret; + + if (!ctx->supply) + return 0; + + dev_dbg(dev, "Enabling regulator supply \"%s\"\n", ctx->opts->supply_name); + + ret = regulator_enable(ctx->supply); + if (ret) + return ret; + + if (ctx->opts->post_power_on_delay_ms) + msleep(ctx->opts->post_power_on_delay_ms); + + return 0; +} + +static void i2c_of_probe_simple_disable_regulator(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + if (!ctx->supply) + return; + + dev_dbg(dev, "Disabling regulator supply \"%s\"\n", ctx->opts->supply_name); + + regulator_disable(ctx->supply); +} + +/** + * i2c_of_probe_simple_enable - Simple helper for I2C OF prober to get and enable resources + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages + * @bus_node: Pointer to the &struct device_node of the I2C adapter. + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * If &i2c_of_probe_simple_opts->supply_name is given, request the named regulator supply. + * If a regulator supply was found, enable that regulator. + * + * Return: %0 on success or no-op, or a negative error number on failure. + */ +int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + struct device_node *node; + const char *compat; + int ret; + + dev_dbg(dev, "Requesting resources for components under I2C bus %pOF\n", bus_node); + + if (!ctx || !ctx->opts) + return -EINVAL; + + compat = ctx->opts->res_node_compatible; + if (!compat) + return -EINVAL; + + node = of_get_compatible_child(bus_node, compat); + if (!node) + return dev_err_probe(dev, -ENODEV, "No device compatible with \"%s\" found\n", + compat); + + ret = i2c_of_probe_simple_get_supply(dev, node, ctx); + if (ret) + goto out_put_node; + + ret = i2c_of_probe_simple_enable_regulator(dev, ctx); + if (ret) + goto out_put_supply; + + return 0; + +out_put_supply: + i2c_of_probe_simple_put_supply(ctx); +out_put_node: + of_node_put(node); + return ret; +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_enable, I2C_OF_PROBER); + +/** + * i2c_of_probe_simple_cleanup - Clean up and release resources for I2C OF prober simple helpers + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * * If a regulator supply was found, disable that regulator and release it. + */ +void i2c_of_probe_simple_cleanup(struct device *dev, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + + i2c_of_probe_simple_disable_regulator(dev, ctx); + i2c_of_probe_simple_put_supply(ctx); +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_cleanup, I2C_OF_PROBER); + +struct i2c_of_probe_ops i2c_of_probe_simple_ops = { + .enable = i2c_of_probe_simple_enable, + .cleanup = i2c_of_probe_simple_cleanup, +}; +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_ops, I2C_OF_PROBER); diff --git a/include/linux/i2c-of-prober.h b/include/linux/i2c-of-prober.h index e7e052ac9e482..df95aa6ad90ef 100644 --- a/include/linux/i2c-of-prober.h +++ b/include/linux/i2c-of-prober.h @@ -70,6 +70,50 @@ struct i2c_of_probe_cfg { int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx); +/** + * DOC: I2C OF component prober simple helpers + * + * Components such as trackpads are commonly connected to a devices baseboard + * with a 6-pin ribbon cable. That gives at most one voltage supply and one + * GPIO (commonly a "enable" or "reset" line) besides the I2C bus, interrupt + * pin, and common ground. Touchscreens, while integrated into the display + * panel's connection, typically have the same set of connections. + * + * A simple set of helpers are provided here for use with the I2C OF component + * prober. This implementation targets such components, allowing for at most + * one regulator supply. + * + * The following helpers are provided: + * * i2c_of_probe_simple_enable() + * * i2c_of_probe_simple_cleanup() + */ + +/** + * struct i2c_of_probe_simple_opts - Options for simple I2C component prober callbacks + * @res_node_compatible: Compatible string of device node to retrieve resources from. + * @supply_name: Name of regulator supply. + * @post_power_on_delay_ms: Delay after regulators are powered on. Passed to msleep(). + */ +struct i2c_of_probe_simple_opts { + const char *res_node_compatible; + const char *supply_name; + unsigned int post_power_on_delay_ms; +}; + +struct regulator; + +struct i2c_of_probe_simple_ctx { + /* public: provided by user before helpers are used. */ + const struct i2c_of_probe_simple_opts *opts; + /* private: internal fields for helpers. */ + struct regulator *supply; +}; + +int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, void *data); +void i2c_of_probe_simple_cleanup(struct device *dev, void *data); + +extern struct i2c_of_probe_ops i2c_of_probe_simple_ops; + #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ #endif /* _LINUX_I2C_OF_PROBER_H */ -- GitLab From 8a22c3b7692960eb5b92212e3ae6eed5e49c784b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:32 +0800 Subject: [PATCH 116/456] UPSTREAM: i2c: of-prober: Add GPIO support to simple helpers Add GPIO support to the simple helpers for the I2C OF component prober. Components that the prober intends to probe likely require their regulator supplies be enabled, and GPIOs be toggled to enable them or bring them out of reset before they will respond to probe attempts. Regulator supplies were handled in the previous patch. The assumption is that the same class of components to be probed are always connected in the same fashion with the same regulator supply and GPIO. The names may vary due to binding differences, but the physical layout does not change. This supports at most one GPIO pin. The user must specify the GPIO name, the polarity, and the amount of time to wait after the GPIO is toggled. Devices with more than one GPIO pin likely require specific power sequencing beyond what generic code can easily support. Signed-off-by: Chen-Yu Tsai Reviewed-by: Douglas Anderson Reviewed-by: Andy Shevchenko Tested-by: Andrey Skvortsov Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 39b415f84654892003cebb7c026b7daa3380610b) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Iab5a631ab85322edfe090180d0f391c0bc30b2ee Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076469 Commit-Queue: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Tested-by: Chen-Yu Tsai Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/i2c/i2c-core-of-prober.c | 100 ++++++++++++++++++++++++++++++- include/linux/i2c-of-prober.h | 21 +++++++ 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c index 76df75c51caee..b9ca785f8b178 100644 --- a/drivers/i2c/i2c-core-of-prober.c +++ b/drivers/i2c/i2c-core-of-prober.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,6 @@ * address responds. * * TODO: - * - Support handling common GPIOs. * - Support I2C muxes */ @@ -246,6 +246,62 @@ static void i2c_of_probe_simple_disable_regulator(struct device *dev, struct i2c regulator_disable(ctx->supply); } +static int i2c_of_probe_simple_get_gpiod(struct device *dev, struct device_node *node, + struct i2c_of_probe_simple_ctx *ctx) +{ + struct fwnode_handle *fwnode = of_fwnode_handle(node); + struct gpio_desc *gpiod; + const char *con_id; + + /* NULL signals no GPIO needed */ + if (!ctx->opts->gpio_name) + return 0; + + /* An empty string signals an unnamed GPIO */ + if (!ctx->opts->gpio_name[0]) + con_id = NULL; + else + con_id = ctx->opts->gpio_name; + + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0, GPIOD_ASIS, "i2c-of-prober"); + if (IS_ERR(gpiod)) + return PTR_ERR(gpiod); + + ctx->gpiod = gpiod; + + return 0; +} + +static void i2c_of_probe_simple_put_gpiod(struct i2c_of_probe_simple_ctx *ctx) +{ + gpiod_put(ctx->gpiod); + ctx->gpiod = NULL; +} + +static int i2c_of_probe_simple_set_gpio(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + int ret; + + if (!ctx->gpiod) + return 0; + + dev_dbg(dev, "Configuring GPIO\n"); + + ret = gpiod_direction_output(ctx->gpiod, ctx->opts->gpio_assert_to_enable); + if (ret) + return ret; + + if (ctx->opts->post_gpio_config_delay_ms) + msleep(ctx->opts->post_gpio_config_delay_ms); + + return 0; +} + +static void i2c_of_probe_simple_disable_gpio(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + gpiod_set_value(ctx->gpiod, !ctx->opts->gpio_assert_to_enable); +} + /** * i2c_of_probe_simple_enable - Simple helper for I2C OF prober to get and enable resources * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages @@ -253,7 +309,11 @@ static void i2c_of_probe_simple_disable_regulator(struct device *dev, struct i2c * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. * * If &i2c_of_probe_simple_opts->supply_name is given, request the named regulator supply. + * If &i2c_of_probe_simple_opts->gpio_name is given, request the named GPIO. Or if it is + * the empty string, request the unnamed GPIO. * If a regulator supply was found, enable that regulator. + * If a GPIO line was found, configure the GPIO line to output and set value + * according to given options. * * Return: %0 on success or no-op, or a negative error number on failure. */ @@ -282,12 +342,24 @@ int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, if (ret) goto out_put_node; - ret = i2c_of_probe_simple_enable_regulator(dev, ctx); + ret = i2c_of_probe_simple_get_gpiod(dev, node, ctx); if (ret) goto out_put_supply; + ret = i2c_of_probe_simple_enable_regulator(dev, ctx); + if (ret) + goto out_put_gpiod; + + ret = i2c_of_probe_simple_set_gpio(dev, ctx); + if (ret) + goto out_disable_regulator; + return 0; +out_disable_regulator: + i2c_of_probe_simple_disable_regulator(dev, ctx); +out_put_gpiod: + i2c_of_probe_simple_put_gpiod(ctx); out_put_supply: i2c_of_probe_simple_put_supply(ctx); out_put_node: @@ -296,17 +368,40 @@ out_put_node: } EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_enable, I2C_OF_PROBER); +/** + * i2c_of_probe_simple_cleanup_early - \ + * Simple helper for I2C OF prober to release GPIOs before component is enabled + * @dev: Pointer to the &struct device of the caller; unused. + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * GPIO descriptors are exclusive and have to be released before the + * actual driver probes so that the latter can acquire them. + */ +void i2c_of_probe_simple_cleanup_early(struct device *dev, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + + i2c_of_probe_simple_put_gpiod(ctx); +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_cleanup_early, I2C_OF_PROBER); + /** * i2c_of_probe_simple_cleanup - Clean up and release resources for I2C OF prober simple helpers * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. * + * * If a GPIO line was found and not yet released, set its value to the opposite of that + * set in i2c_of_probe_simple_enable() and release it. * * If a regulator supply was found, disable that regulator and release it. */ void i2c_of_probe_simple_cleanup(struct device *dev, void *data) { struct i2c_of_probe_simple_ctx *ctx = data; + /* GPIO operations here are no-ops if i2c_of_probe_simple_cleanup_early was called. */ + i2c_of_probe_simple_disable_gpio(dev, ctx); + i2c_of_probe_simple_put_gpiod(ctx); + i2c_of_probe_simple_disable_regulator(dev, ctx); i2c_of_probe_simple_put_supply(ctx); } @@ -314,6 +409,7 @@ EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_cleanup, I2C_OF_PROBER); struct i2c_of_probe_ops i2c_of_probe_simple_ops = { .enable = i2c_of_probe_simple_enable, + .cleanup_early = i2c_of_probe_simple_cleanup_early, .cleanup = i2c_of_probe_simple_cleanup, }; EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_ops, I2C_OF_PROBER); diff --git a/include/linux/i2c-of-prober.h b/include/linux/i2c-of-prober.h index df95aa6ad90ef..bb6d47f50ee59 100644 --- a/include/linux/i2c-of-prober.h +++ b/include/linux/i2c-of-prober.h @@ -9,6 +9,7 @@ #define _LINUX_I2C_OF_PROBER_H #include +#include struct device; struct device_node; @@ -85,6 +86,7 @@ int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cf * * The following helpers are provided: * * i2c_of_probe_simple_enable() + * * i2c_of_probe_simple_cleanup_early() * * i2c_of_probe_simple_cleanup() */ @@ -92,14 +94,31 @@ int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cf * struct i2c_of_probe_simple_opts - Options for simple I2C component prober callbacks * @res_node_compatible: Compatible string of device node to retrieve resources from. * @supply_name: Name of regulator supply. + * @gpio_name: Name of GPIO. NULL if no GPIO line is used. Empty string ("") if GPIO + * line is unnamed. * @post_power_on_delay_ms: Delay after regulators are powered on. Passed to msleep(). + * @post_gpio_config_delay_ms: Delay after GPIO is configured. Passed to msleep(). + * @gpio_assert_to_enable: %true if GPIO should be asserted, i.e. set to logical high, + * to enable the component. + * + * This describes power sequences common for the class of components supported by the + * simple component prober: + * * @gpio_name is configured to the non-active setting according to @gpio_assert_to_enable. + * * @supply_name regulator supply is enabled. + * * Wait for @post_power_on_delay_ms to pass. + * * @gpio_name is configured to the active setting according to @gpio_assert_to_enable. + * * Wait for @post_gpio_config_delay_ms to pass. */ struct i2c_of_probe_simple_opts { const char *res_node_compatible; const char *supply_name; + const char *gpio_name; unsigned int post_power_on_delay_ms; + unsigned int post_gpio_config_delay_ms; + bool gpio_assert_to_enable; }; +struct gpio_desc; struct regulator; struct i2c_of_probe_simple_ctx { @@ -107,9 +126,11 @@ struct i2c_of_probe_simple_ctx { const struct i2c_of_probe_simple_opts *opts; /* private: internal fields for helpers. */ struct regulator *supply; + struct gpio_desc *gpiod; }; int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, void *data); +void i2c_of_probe_simple_cleanup_early(struct device *dev, void *data); void i2c_of_probe_simple_cleanup(struct device *dev, void *data); extern struct i2c_of_probe_ops i2c_of_probe_simple_ops; -- GitLab From fe02e0ef2b560d336afcd12ff33207c2a0d75f6b Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 3 Oct 2023 14:59:53 +0300 Subject: [PATCH 117/456] UPSTREAM: kernel.h: Move ARRAY_SIZE() to a separate header Touching files so used for the kernel, forces 'make' to recompile most of the kernel. Having those definitions in more granular files helps avoid recompiling so much of the kernel. Signed-off-by: Alejandro Colomar Reviewed-by: Giovanni Cabiddu Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230817143352.132583-2-lucas.segarra.fernandez@intel.com [andy: reduced to cover only string.h for now] Signed-off-by: Andy Shevchenko (cherry picked from commit 3cd39bc3b11b8d34b7d7c961a35fdfd18b0ebf75) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ia0c7fc31497db03e9b40a859d0bb78f3431c9048 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076470 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- include/linux/array_size.h | 13 +++++++++++++ include/linux/kernel.h | 7 +------ include/linux/string.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 include/linux/array_size.h diff --git a/include/linux/array_size.h b/include/linux/array_size.h new file mode 100644 index 0000000000000..06d7d83196ca3 --- /dev/null +++ b/include/linux/array_size.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_ARRAY_SIZE_H +#define _LINUX_ARRAY_SIZE_H + +#include + +/** + * ARRAY_SIZE - get the number of elements in array @arr + * @arr: array to be sized + */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + +#endif /* _LINUX_ARRAY_SIZE_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5447c1d8c81ec..e0531145e63ea 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -50,12 +51,6 @@ #define READ 0 #define WRITE 1 -/** - * ARRAY_SIZE - get the number of elements in array @arr - * @arr: array to be sized - */ -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) - #define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL) #define u64_to_user_ptr(x) ( \ diff --git a/include/linux/string.h b/include/linux/string.h index 5077776e995e0..ce137830a0b99 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -2,6 +2,7 @@ #ifndef _LINUX_STRING_H_ #define _LINUX_STRING_H_ +#include #include /* for inline */ #include /* for size_t */ #include /* for NULL */ -- GitLab From 51b7708bde20bb25ca0db5e8509e723d25419e3f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:33 +0800 Subject: [PATCH 118/456] BACKPORT: platform/chrome: Introduce device tree hardware prober Some devices are designed and manufactured with some components having multiple drop-in replacement options. These components are often connected to the mainboard via ribbon cables, having the same signals and pin assignments across all options. These may include the display panel and touchscreen on laptops and tablets, and the trackpad on laptops. Sometimes which component option is used in a particular device can be detected by some firmware provided identifier, other times that information is not available, and the kernel has to try to probe each device. This change attempts to make the "probe each device" case cleaner. The current approach is to have all options added and enabled in the device tree. The kernel would then bind each device and run each driver's probe function. This works, but has been broken before due to the introduction of asynchronous probing, causing multiple instances requesting "shared" resources, such as pinmuxes, GPIO pins, interrupt lines, at the same time, with only one instance succeeding. Work arounds for these include moving the pinmux to the parent I2C controller, using GPIO hogs or pinmux settings to keep the GPIO pins in some fixed configuration, and requesting the interrupt line very late. Such configurations can be seen on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based Lenovo Thinkpad 13S. Instead of this delicate dance between drivers and device tree quirks, this change introduces a simple I2C component prober. For any given class of devices on the same I2C bus, it will go through all of them, doing a simple I2C read transfer and see which one of them responds. It will then enable the device that responds. This requires some minor modifications in the existing device tree. The status for all the device nodes for the component options must be set to "fail-needs-probe". This makes it clear that some mechanism is needed to enable one of them, and also prevents the prober and device drivers running at the same time. Originally the driver was enabled when CONFIG_OF was set but this behavior breaks the abi. Change the defaults to 'n' to disable building it by default. Signed-off-by: Chen-Yu Tsai Acked-by: Tzung-Bi Shih Reviewed-by: Douglas Anderson Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit 3fc361af8ab0a96619ba0146a5f694f59ae3f4c2) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I90578af34b3faa50eb6348eb1fd97f86442b662b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076471 Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/platform/chrome/Kconfig | 11 ++ drivers/platform/chrome/Makefile | 1 + .../platform/chrome/chromeos_of_hw_prober.c | 154 ++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 drivers/platform/chrome/chromeos_of_hw_prober.c diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index b8f1e9bec8349..67e4f00a5d59d 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -61,6 +61,17 @@ config CHROMEOS_TBMC To compile this driver as a module, choose M here: the module will be called chromeos_tbmc. +config CHROMEOS_OF_HW_PROBER + tristate "ChromeOS Device Tree Hardware Prober" + depends on OF + depends on I2C + select OF_DYNAMIC + default n + help + This option enables the device tree hardware prober for ChromeOS + devices. The driver will probe the correct component variant in + devices that have multiple drop-in options for one component. + config CROS_EC tristate "ChromeOS Embedded Controller" select CROS_EC_PROTO diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index d0dd28d60e320..c50da279d771f 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -6,6 +6,7 @@ CFLAGS_cros_ec_sensorhub_ring.o:= -I$(src) obj-$(CONFIG_CHROMEOS_ACPI) += chromeos_acpi.o obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o +obj-$(CONFIG_CHROMEOS_OF_HW_PROBER) += chromeos_of_hw_prober.o obj-$(CONFIG_CHROMEOS_PRIVACY_SCREEN) += chromeos_privacy_screen.o obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o diff --git a/drivers/platform/chrome/chromeos_of_hw_prober.c b/drivers/platform/chrome/chromeos_of_hw_prober.c new file mode 100644 index 0000000000000..297d4704b75fd --- /dev/null +++ b/drivers/platform/chrome/chromeos_of_hw_prober.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ChromeOS Device Tree Hardware Prober + * + * Copyright (c) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "chromeos_of_hw_prober" + +/** + * struct hw_prober_entry - Holds an entry for the hardware prober + * + * @compatible: compatible string to match against the machine + * @prober: prober function to call when machine matches + * @data: extra data for the prober function + */ +struct hw_prober_entry { + const char *compatible; + int (*prober)(struct device *dev, const void *data); + const void *data; +}; + +struct chromeos_i2c_probe_data { + const struct i2c_of_probe_cfg *cfg; + const struct i2c_of_probe_simple_opts *opts; +}; + +static int chromeos_i2c_component_prober(struct device *dev, const void *_data) +{ + const struct chromeos_i2c_probe_data *data = _data; + struct i2c_of_probe_simple_ctx ctx = { + .opts = data->opts, + }; + + return i2c_of_probe_component(dev, data->cfg, &ctx); +} + +#define DEFINE_CHROMEOS_I2C_PROBE_CFG_SIMPLE_BY_TYPE(_type) \ + static const struct i2c_of_probe_cfg chromeos_i2c_probe_simple_ ## _type ## _cfg = { \ + .type = #_type, \ + .ops = &i2c_of_probe_simple_ops, \ + } + +#define DEFINE_CHROMEOS_I2C_PROBE_DATA_DUMB_BY_TYPE(_type) \ + static const struct chromeos_i2c_probe_data chromeos_i2c_probe_dumb_ ## _type = { \ + .cfg = &(const struct i2c_of_probe_cfg) { \ + .type = #_type, \ + }, \ + } + +DEFINE_CHROMEOS_I2C_PROBE_DATA_DUMB_BY_TYPE(touchscreen); + +DEFINE_CHROMEOS_I2C_PROBE_CFG_SIMPLE_BY_TYPE(trackpad); + +static const struct chromeos_i2c_probe_data chromeos_i2c_probe_hana_trackpad = { + .cfg = &chromeos_i2c_probe_simple_trackpad_cfg, + .opts = &(const struct i2c_of_probe_simple_opts) { + .res_node_compatible = "elan,ekth3000", + .supply_name = "vcc", + /* + * ELAN trackpad needs 2 ms for H/W init and 100 ms for F/W init. + * Synaptics trackpad needs 100 ms. + * However, the regulator is set to "always-on", presumably to + * avoid this delay. The ELAN driver is also missing delays. + */ + .post_power_on_delay_ms = 0, + }, +}; + +static const struct hw_prober_entry hw_prober_platforms[] = { + { + .compatible = "google,hana", + .prober = chromeos_i2c_component_prober, + .data = &chromeos_i2c_probe_dumb_touchscreen, + }, { + .compatible = "google,hana", + .prober = chromeos_i2c_component_prober, + .data = &chromeos_i2c_probe_hana_trackpad, + }, +}; + +static int chromeos_of_hw_prober_probe(struct platform_device *pdev) +{ + for (size_t i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++) { + int ret; + + if (!of_machine_is_compatible(hw_prober_platforms[i].compatible)) + continue; + + ret = hw_prober_platforms[i].prober(&pdev->dev, hw_prober_platforms[i].data); + /* Ignore unrecoverable errors and keep going through other probers */ + if (ret == -EPROBE_DEFER) + return ret; + } + + return 0; +} + +static struct platform_driver chromeos_of_hw_prober_driver = { + .probe = chromeos_of_hw_prober_probe, + .driver = { + .name = DRV_NAME, + }, +}; + +static struct platform_device *chromeos_of_hw_prober_pdev; + +static int chromeos_of_hw_prober_driver_init(void) +{ + size_t i; + int ret; + + for (i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++) + if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) + break; + if (i == ARRAY_SIZE(hw_prober_platforms)) + return -ENODEV; + + ret = platform_driver_register(&chromeos_of_hw_prober_driver); + if (ret) + return ret; + + chromeos_of_hw_prober_pdev = + platform_device_register_simple(DRV_NAME, PLATFORM_DEVID_NONE, NULL, 0); + if (IS_ERR(chromeos_of_hw_prober_pdev)) + goto err; + + return 0; + +err: + platform_driver_unregister(&chromeos_of_hw_prober_driver); + + return PTR_ERR(chromeos_of_hw_prober_pdev); +} +module_init(chromeos_of_hw_prober_driver_init); + +static void chromeos_of_hw_prober_driver_exit(void) +{ + platform_device_unregister(chromeos_of_hw_prober_pdev); + platform_driver_unregister(&chromeos_of_hw_prober_driver); +} +module_exit(chromeos_of_hw_prober_driver_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ChromeOS device tree hardware prober"); +MODULE_IMPORT_NS(I2C_OF_PROBER); -- GitLab From 0dca856cecc758e9a8ad677edeb6d90ed513fff5 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 25 Oct 2023 11:38:10 +0200 Subject: [PATCH 119/456] UPSTREAM: arm64: dts: mediatek: mt8173: Use interrupts-extended where possible Change all instances of interrupt-parent + interrupts to one line as interrupts-extended where possible across all MT8173 DTs to both simplify and reduce code size. Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 355f0a4c6965847834fed6cff49026cb6506a0b3) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I8fdd4542c3e70a1d0756cf0210cb63bf0902eb5d Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076472 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- .../boot/dts/mediatek/mt8173-elm-hana.dtsi | 9 +++---- arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 24 +++++++------------ arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 3 +-- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi index fd6230352f4fd..c7d977ff4e62f 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi @@ -13,8 +13,7 @@ touchscreen2: touchscreen@34 { compatible = "melfas,mip4_ts"; reg = <0x34>; - interrupt-parent = <&pio>; - interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; }; /* @@ -26,8 +25,7 @@ compatible = "hid-over-i2c"; reg = <0x20>; hid-descr-addr = <0x0020>; - interrupt-parent = <&pio>; - interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; }; }; @@ -39,8 +37,7 @@ */ trackpad2: trackpad@2c { compatible = "hid-over-i2c"; - interrupt-parent = <&pio>; - interrupts = <117 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; reg = <0x2c>; hid-descr-addr = <0x0020>; /* diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index 5ef12697791f5..3c6b6701ceb99 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -250,8 +250,7 @@ reg = <0x1a>; avdd-supply = <&mt6397_vgp1_reg>; cpvdd-supply = <&mt6397_vcama_reg>; - interrupt-parent = <&pio>; - interrupts = <3 IRQ_TYPE_EDGE_BOTH>; + interrupts-extended = <&pio 3 IRQ_TYPE_EDGE_BOTH>; pinctrl-names = "default"; pinctrl-0 = <&rt5650_irq>; #sound-dai-cells = <1>; @@ -313,8 +312,7 @@ da9211: da9211@68 { compatible = "dlg,da9211"; reg = <0x68>; - interrupt-parent = <&pio>; - interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 15 IRQ_TYPE_LEVEL_LOW>; regulators { da9211_vcpu_reg: BUCKA { @@ -358,8 +356,7 @@ touchscreen: touchscreen@10 { compatible = "elan,ekth3500"; reg = <0x10>; - interrupt-parent = <&pio>; - interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; }; }; @@ -371,8 +368,7 @@ trackpad: trackpad@15 { compatible = "elan,ekth3000"; - interrupt-parent = <&pio>; - interrupts = <117 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; reg = <0x15>; vcc-supply = <&mt6397_vgp6_reg>; wakeup-source; @@ -444,8 +440,7 @@ btmrvl: btmrvl@2 { compatible = "marvell,sd8897-bt"; reg = <2>; - interrupt-parent = <&pio>; - interrupts = <119 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 119 IRQ_TYPE_LEVEL_LOW>; marvell,wakeup-pin = /bits/ 16 <0x0d>; marvell,wakeup-gap-ms = /bits/ 16 <0x64>; }; @@ -453,8 +448,7 @@ mwifiex: mwifiex@1 { compatible = "marvell,sd8897"; reg = <1>; - interrupt-parent = <&pio>; - interrupts = <38 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 38 IRQ_TYPE_LEVEL_LOW>; marvell,wakeup-pin = <3>; }; }; @@ -938,8 +932,7 @@ compatible = "mediatek,mt6397"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&pio>; - interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <2>; @@ -1142,8 +1135,7 @@ compatible = "google,cros-ec-spi"; reg = <0x0>; spi-max-frequency = <12000000>; - interrupt-parent = <&pio>; - interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&pio 0 IRQ_TYPE_LEVEL_LOW>; google,cros-ec-spi-msg-delay = <500>; i2c_tunnel: i2c-tunnel0 { diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts index f6a70f22bd0c4..3941ae52b5b5c 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts @@ -303,8 +303,7 @@ pmic: pmic { compatible = "mediatek,mt6397"; - interrupt-parent = <&pio>; - interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <2>; -- GitLab From 5e22c878eb2d0d8aa78f99aa8be4a7107ba71fdc Mon Sep 17 00:00:00 2001 From: Pin-yen Lin Date: Wed, 15 Nov 2023 12:35:01 +0800 Subject: [PATCH 120/456] UPSTREAM: arm64: dts: mt8173: Add G2Touch touchscreen node Lenovo Ideapad C330 Chromebook (MTK) uses G2Touch touchscreen as a second source component. Signed-off-by: Pin-yen Lin Reviewed-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20231115043511.2670477-1-treapking@chromium.org [Angelo: Rebased and added comment] Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 0b2f9d0e397b6c2d510d118bac036f7f6bb3c3db) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: Ia6720358b5742a7dcb4d0b5891deb36eae1650e6 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076473 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi index c7d977ff4e62f..ae0379fd42a91 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi @@ -27,6 +27,15 @@ hid-descr-addr = <0x0020>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; }; + + /* Lenovo Ideapad C330 uses G2Touch touchscreen as a 2nd source touchscreen */ + touchscreen@40 { + compatible = "hid-over-i2c"; + reg = <0x40>; + hid-descr-addr = <0x0001>; + interrupt-parent = <&pio>; + interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + }; }; &i2c4 { -- GitLab From 911a5a3b85505bf4744abf51d85b07502cac0f92 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Nov 2024 17:33:34 +0800 Subject: [PATCH 121/456] UPSTREAM: arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Instead of having them all available, mark them all as "fail-needs-probe" and have the implementation try to probe which one is present. Also remove the shared resource workaround by moving the pinctrl entry for the trackpad interrupt line back into the individual trackpad nodes. Cc: # Needs accompanying new driver to work Signed-off-by: Chen-Yu Tsai Reviewed-by: Douglas Anderson Reviewed-by: AngeloGioacchino Del Regno Acked-by: AngeloGioacchino Del Regno Signed-off-by: Wolfram Sang (cherry picked from commit aac9e2afa807e862073e9536099a3184b0e936d2) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I40ff9f00e405072b6fd26215d4d32f61426f5d6a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076475 Reviewed-by: Pin-yen Lin Commit-Queue: Chen-Yu Tsai Reviewed-by: Sean Paul Tested-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 14 ++++++++++++++ arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi index ae0379fd42a91..dfc5c2f0ddefd 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi @@ -14,6 +14,7 @@ compatible = "melfas,mip4_ts"; reg = <0x34>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* @@ -26,6 +27,7 @@ reg = <0x20>; hid-descr-addr = <0x0020>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* Lenovo Ideapad C330 uses G2Touch touchscreen as a 2nd source touchscreen */ @@ -35,6 +37,7 @@ hid-descr-addr = <0x0001>; interrupt-parent = <&pio>; interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; }; @@ -47,6 +50,8 @@ trackpad2: trackpad@2c { compatible = "hid-over-i2c"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x2c>; hid-descr-addr = <0x0020>; /* @@ -58,6 +63,7 @@ */ vdd-supply = <&mt6397_vgp6_reg>; wakeup-source; + status = "fail-needs-probe"; }; }; @@ -82,3 +88,11 @@ }; }; }; + +&touchscreen { + status = "fail-needs-probe"; +}; + +&trackpad { + status = "fail-needs-probe"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index 3c6b6701ceb99..0609763bd20ae 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -363,12 +363,12 @@ &i2c4 { clock-frequency = <400000>; status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&trackpad_irq>; trackpad: trackpad@15 { compatible = "elan,ekth3000"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x15>; vcc-supply = <&mt6397_vgp6_reg>; wakeup-source; -- GitLab From 4b1e7eff0580602763d07c8fc324c97dcd6699c6 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Fri, 29 Nov 2024 10:52:38 +0100 Subject: [PATCH 122/456] UPSTREAM: MAINTAINERS: fix typo in I2C OF COMPONENT PROBER Commit 157ce8f381ef ("i2c: Introduce OF component probe function") adds the header file include/linux/i2c-of-prober.h and a corresponding file entry in the newly added MAINTAINERS section I2C OF COMPONENT PROBER. This file entry unfortunately has a typo. Fortunately, ./scripts/get_maintainer.pl --self-test=patterns detects this broken reference. Fix the typo in this file entry in the I2C OF COMPONENT PROBER section. Fixes: 157ce8f381ef ("i2c: Introduce OF component probe function") Signed-off-by: Lukas Bulwahn Signed-off-by: Wolfram Sang (cherry picked from commit caf4bdb558cbc9893524b0a15e6423ee6305cb0c) BUG=b:313564065 TEST=cros build-packages -b kukui chromeos-kernel-6_6 Change-Id: I1a8dac5f6032f627e46f8e2417036baabe27851e Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6076363 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3c39aa493cb87..28eadb4026867 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9892,7 +9892,7 @@ L: linux-i2c@vger.kernel.org L: devicetree@vger.kernel.org S: Maintained F: drivers/i2c/i2c-core-of-prober.c -F: include/linux-i2c-of-prober.h +F: include/linux/i2c-of-prober.h I2C OVER PARALLEL PORT M: Jean Delvare -- GitLab From fed1c5e3284dcddc0c8f12de2d59db1a99027053 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Tue, 10 Dec 2024 02:20:19 +0000 Subject: [PATCH 123/456] UPSTREAM: sched/deadline: Fix replenish_dl_new_period dl_server condition The condition in replenish_dl_new_period() that checks if a reservation (dl_server) is deferred and is not handling a starvation case is obviously wrong. Fix it. Fixes: a110a81c52a9 ("sched/deadline: Deferrable dl server") Signed-off-by: Juri Lelli Signed-off-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20241127063740.8278-1-juri.lelli@redhat.com (cherry picked from commit 22368fe1f9bbf39db2b5b52859589883273e80ce) BUG=b:307273029 TEST=CQ Signed-off-by: Linux Patches Robot Change-Id: I88bd3cadb77b42ef22fe28367404e6d9ce7d7aa5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6082997 Reviewed-by: Sean Paul Reviewed-by: Suleiman Souhlal Reviewed-by: Aashish Sharma Commit-Queue: Aashish Sharma Signed-off-by: Hubert Mazur --- kernel/sched/deadline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index fb9eebb5f59aa..fff9f068f5e33 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -782,7 +782,7 @@ static inline void replenish_dl_new_period(struct sched_dl_entity *dl_se, * If it is a deferred reservation, and the server * is not handling an starvation case, defer it. */ - if (dl_se->dl_defer & !dl_se->dl_defer_running) { + if (dl_se->dl_defer && !dl_se->dl_defer_running) { dl_se->dl_throttled = 1; dl_se->dl_defer_armed = 1; } -- GitLab From 41af11dbe5bab99d35787cc704f82a1fb0143220 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 1 Dec 2024 14:57:54 +0200 Subject: [PATCH 124/456] CHROMIUM: iwl7000: re-enumerate if we can't access the device When we can't access the device, we get 0xFFFFFFFF as a response to all our requests. Check what the CSR_FUNC_SCRATCH returns immediately after we wrote it. If we can't access that register, attempt to re-enumerate the bus. There will be a bigger feature later, but for now, do something quick that can be backported to release branches as well. BUG=b:374205496 TEST=wifi_matfunc,reset stress,suspend-resume stress,idle associated stress Cq-Depend: 6072225 Change-Id: Ia477838623cc0b5466c4eb2e424bbd83ee1526df Signed-off-by: Emmanuel Grumbach iwl7000-tree: 20123a9fc1010fcff6c9f48cec7b0085595586b9 Signed-off-by: Miri Korenblit Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6063049 Tested-by: Arowa Suliman Commit-Queue: Nicolas Norvez Reviewed-by: Nicolas Norvez Reviewed-by: David Ruth Signed-off-by: Hubert Mazur --- drivers/net/wireless/iwl7000/iwlwifi/pcie/trans-gen2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/iwl7000/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/iwl7000/iwlwifi/pcie/trans-gen2.c index aec03a1628951..dfaa9365f99e7 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/iwl7000/iwlwifi/pcie/trans-gen2.c @@ -528,6 +528,16 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE); + /* + * If we can't read the value we just wrote and get 0xFFFFFFFF + * just re-enumerate + */ + if (iwl_read32(trans, CSR_FUNC_SCRATCH) == ~0U) { + IWL_WARN(trans, + "Readback verification failed (0xFFFFFFFF) after write. Re-enumerating device\n"); + iwl_trans_pcie_remove(trans, true); + goto out; + } iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_ROM_START); } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { -- GitLab From bb962bc3fbd8f046ebbe44a46d5cf7f6c6f9d7ef Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Mon, 2 Dec 2024 18:08:37 +0800 Subject: [PATCH 125/456] CHROMIUM: soc: mediatek: mtk-socinfo: update soc_id and machine fields The current /sys/devices/soc0/machine combines SoC ID and marketing name, which is illogical. SoC ID should have its own dedicated soc_id field. Decouple SoC ID and marketing name under /sys/devices/soc0/machine to allow independent updates to both field. We don't have much time due to project schedule, so we'll land CHROMIUM for now. I plan to send an upstream patch to better address this when I have cycle. See bug and go/cros-mtk-socinfo for details. BUG=b:373555245 TEST=grep -r '' /sys/devices/soc0/* # on MTK devices UPSTREAM-TASK=b:382614972 Cq-Depend: chromium:6064381 Change-Id: I627db65d62f8c4a6a0bdb03c8c58f04e56bece47 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6065906 Tested-by: Hsin-Te Yuan Commit-Queue: Hsin-Te Yuan Reviewed-by: Hsin-Te Yuan Kcr-patch: 9732940c8ce9e2c4e93efa344415de2385ba722f5d13ff916a76eca6.patch Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-socinfo.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index 42572e8c1520d..d717a2855bff4 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -61,23 +61,22 @@ static struct socinfo_data socinfo_data_table[] = { static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop) { struct soc_device_attribute *attrs; - static char machine[30] = {0}; static const char *soc_manufacturer = "MediaTek"; attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL); if (!attrs) return -ENOMEM; - snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name, - mtk_socinfop->socinfo_data->soc_name); attrs->family = soc_manufacturer; - attrs->machine = machine; + attrs->machine = mtk_socinfop->socinfo_data->marketing_name; + attrs->soc_id = mtk_socinfop->socinfo_data->soc_name; mtk_socinfop->soc_dev = soc_device_register(attrs); if (IS_ERR(mtk_socinfop->soc_dev)) return PTR_ERR(mtk_socinfop->soc_dev); - dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n", soc_manufacturer, attrs->machine); + dev_info(mtk_socinfop->dev, "SoC detected, family: %s, soc_id: %s, machine: %s\n", + attrs->family, attrs->soc_id, attrs->machine); return 0; } -- GitLab From 909114a78764e1deae017d5ac1e6e7ec26893582 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 9 Dec 2024 10:27:47 +0100 Subject: [PATCH 126/456] CHROMIUM: iwl7000: enable 320 MHz on slow PCIe links Despite not being able to sustain the full 320 MHz throughput even at MCS 9, enable 320 MHz on slow PCIe links. This may in some cases result in frames being dropped (on the air) by the firmware if they cannot be delivered to the host, but it can still be better to use 320 MHz. BUG=b:374205496 TEST=mat_func Change-Id: I1224023721aaeff8ebcaa47dff88613c7fd0533a Signed-off-by: Johannes Berg (cherry picked from commit eb7d6db965836a900acfbfe096f56d181a86596e) iwl7000-tree: 88930902ec680787510843818479159c911b42f8 Signed-off-by: Miri Korenblit Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6082171 Reviewed-by: Nicolas Norvez Tested-by: Miriam Rachel Korenblit Reviewed-by: Arowa Suliman Reviewed-by: Guy Damary Tested-by: Arowa Suliman Commit-Queue: Arowa Suliman Kcr-patch: 8bd3ea833c8b4ae9d733b3e46d3821b99ce9929bd7ba4b19f545e370.patch Signed-off-by: Hubert Mazur --- .../wireless/iwl7000/iwlwifi/iwl-nvm-parse.c | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwl7000/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwl7000/iwlwifi/iwl-nvm-parse.c index f1cfb115a537f..8955ab536059d 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwl7000/iwlwifi/iwl-nvm-parse.c @@ -928,12 +928,10 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, u8 tx_chains, u8 rx_chains, const struct iwl_fw *fw) { - bool is_ap = iftype_data->types_mask & BIT(NL80211_IFTYPE_AP); - bool no_320; - - no_320 = (!trans->trans_cfg->integrated && - trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB) || - trans->reduced_cap_sku; + bool is_ap = iftype_data->types_mask & (BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO)); + bool slow_pcie = (!trans->trans_cfg->integrated && + trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB); if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be) cfg_eht_cap_set_has_eht(iftype_data, false); @@ -962,14 +960,12 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, #endif break; case NL80211_BAND_6GHZ: -#if CFG80211_VERSION >= KERNEL_VERSION(5,18,0) - if (!no_320) { - cfg_eht_cap(iftype_data)->eht_cap_elem.phy_cap_info[0] |= - IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; - cfg_eht_cap(iftype_data)->eht_cap_elem.phy_cap_info[1] |= - IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK; + if (!trans->reduced_cap_sku) { + iftype_data->eht_cap.eht_cap_elem.phy_cap_info[0] |= + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; + iftype_data->eht_cap.eht_cap_elem.phy_cap_info[1] |= + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK; } -#endif fallthrough; case NL80211_BAND_5GHZ: iftype_data->he_cap.he_cap_elem.phy_cap_info[0] |= @@ -1006,6 +1002,14 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, cfg_eht_cap(iftype_data)->eht_cap_elem.phy_cap_info[4] |= 0x10; } } + + if (slow_pcie) { + struct ieee80211_eht_mcs_nss_supp *mcs_nss = + &iftype_data->eht_cap.eht_mcs_nss_supp; + + mcs_nss->bw._320.rx_tx_mcs11_max_nss = 0; + mcs_nss->bw._320.rx_tx_mcs13_max_nss = 0; + } } else { struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp = &iftype_data->he_cap.he_mcs_nss_supp; -- GitLab From 416a01b377a09e7965df201886eceb593e8a3046 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 10 Dec 2024 04:20:25 +0000 Subject: [PATCH 127/456] Revert "CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Voltorb" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 24da0611c5ccf9612839c2db48ae598295396fd0. Reason for revert: Upstream changes to mt8186-corsola.dtsi and mt8186-corsola-voltorb.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. Original change's description: > CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Voltorb > > BUG=b:366134684 > TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 > UPSTREAM-TASK=b:362203280 > > Change-Id: I1ad24a7ee242c584397523a363f3d96551db3af6 > Signed-off-by: Albert Jakieła > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6034937 > Reviewed-by: Wojciech Macek BUG=b:366134684 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:362203280 Change-Id: I2fe6a920f5318ad882a4dfb7832c38703b7c4b73 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083571 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 2 - .../mt8186-corsola-voltorb-rev0-sku589824.dts | 51 ------------------- .../mt8186-corsola-voltorb-rev0-sku589825.dts | 46 ----------------- .../mt8186-corsola-voltorb-sku589825.dts | 5 +- 4 files changed, 2 insertions(+), 102 deletions(-) delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 0757b45e64e88..3aafd0a185f20 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -90,8 +90,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131077.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131080.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131082.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku65536.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-rev0-sku589824.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-rev0-sku589825.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts deleted file mode 100644 index c946c764f12b6..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2022 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-voltorb.dtsi" - -/ { - model = "Google Voltorb rev0 sku589824(non-T) board"; - compatible = "google,voltorb-rev0-sku589824", "google,voltorb", - "mediatek,mt8186"; -}; - -&max98360a { - status = "disabled"; -}; - -&rt1019p{ - status = "okay"; -}; - -&sound { - compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound"; - playback-codecs { - sound-dai = <&it6505dptx>,<&rt1019p>; - }; -}; - -&spmi { - status = "disabled"; -}; - -&cpu6 { - proc-supply = <&mt6366_vproc11_reg>; - /delete-property/ sram-supply; -}; - -&cpu7 { - proc-supply = <&mt6366_vproc11_reg>; - /delete-property/ sram-supply; -}; - -&cluster1_opp_14 { - opp-hz = /bits/ 64 <1986000000>; - opp-microvolt = <1093750>; -}; - -&cluster1_opp_15 { - opp-hz = /bits/ 64 <2050000000>; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts deleted file mode 100644 index 47fb3a02d8ced..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2022 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-voltorb.dtsi" - -/ { - model = "Google Voltorb rev0 sku589825 board"; - compatible = "google,voltorb-rev0-sku589825", "google,voltorb", - "mediatek,mt8186"; -}; - -&max98360a { - status = "disabled"; -}; - -&rt1019p{ - status = "okay"; -}; - -&sound { - compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound"; - playback-codecs { - sound-dai = <&it6505dptx>,<&rt1019p>; - }; -}; - -&i2c1 { - touchscreen_auo: touchscreen@10 { - status = "okay"; - - compatible = "hid-over-i2c"; - reg = <0x10>; - interrupt-parent = <&pio>; - interrupts = <12 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&touchscreen_pins>; - reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; - vdd-supply = <&pp3300_s3>; - - post-power-on-delay-ms = <450>; - hid-descr-addr = <0x0001>; - }; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts index 89caa6f9eadb7..45e57f7706cc1 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts @@ -8,9 +8,8 @@ / { model = "Google Voltorb sku589825 board"; - compatible = "google,voltorb-sku589825", - "google,voltorb-sku2147483647", "google,voltorb-sku2147483391", - "google,voltorb", "mediatek,mt8186"; + compatible = "google,voltorb-sku589825", "google,voltorb", + "mediatek,mt8186"; }; &i2c1 { -- GitLab From 38ab05f3a132a93f838b0634f96f758bf7ab8bec Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Dec 2024 15:22:00 +0800 Subject: [PATCH 128/456] Revert "CHROMIUM: arm64: dts: mt8186: Add corsola-squirtle board" This reverts the following commits: bd9dc6c0d7d2 CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Squirtle 1e05dc8b4efe CHROMIUM: arm64: dts: mt8186: Disable trackpad node c63dce2127f6 CHROMIUM: arm64: dts: mt8186: Change touchscreens compatible cd76211072e8 CHROMIUM: arm64: dts: mt8186: Update Squirtle sound card configuration ce404a5722ea CHROMIUM: arm64: dts: mt8186: Add corsola-squirtle board Reason for revert: Upstream changes to mt8186-corsola.dtsi and mt8186-corsola-voltorb.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. BUG=b:370726331 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:370725325, b:383242710 Change-Id: Ic73f4ac64c80696b41b88a23357936656a071718 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087656 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 1 - .../mediatek/mt8186-corsola-squirtle-sku0.dts | 14 --- .../dts/mediatek/mt8186-corsola-squirtle.dtsi | 119 ------------------ 3 files changed, 134 deletions(-) delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle-sku0.dts delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dtsi diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 3aafd0a185f20..36234bfb84dc7 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -68,7 +68,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku2.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku3.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku4.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-squirtle-sku0.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-rev0-sku131072.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-rev0-sku131073.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle-sku0.dts deleted file mode 100644 index ed3fef48c9d71..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle-sku0.dts +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2024 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-squirtle.dtsi" - -/ { - model = "Google squirtle sku0/unprovisioned board"; - compatible = "google,squirtle-sku0","google,squirtle-sku2147483647", - "google,squirtle-sku2147483391", - "google,squirtle","mediatek,mt8186"; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dtsi deleted file mode 100644 index 4dd62367ceaf7..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dtsi +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2024 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-voltorb.dtsi" - -&max98360a { - status = "disabled"; -}; - -&rt5682s { - status = "disabled"; -}; - -&i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins &touchscreen_pins>; - - touchscreen@16 { - status = "okay"; - compatible = "elan,ekth6a12nay"; - reg = <0x16>; - interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; - /* - * Squirtle has a second source touchscreen using the same - * GPIO pin. This causes both devices to fail probe, so - * `reset-gpios` are commented. Not using `reset-gpios` - * does not change the operation of the touchscreen, - * because this pin is pulled high in pinctrl. This property - * will be commented out until the correct solution - * is merged into upstream. - * reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; - */ - vcc33-supply = <&pp3300_s3>; - }; - - touchscreen@10 { - status = "okay"; - compatible = "elan,ekth6a12nay"; - reg = <0x10>; - interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; - /* - * Squirtle has a second source touchscreen using the same - * GPIO pin. This causes both devices to fail probe, so - * `reset-gpios` are commented. Not using `reset-gpios` - * does not change the operation of the touchscreen, - * because this pin is pulled high in pinctrl. This property - * will be commented out until the correct solution - * is merged into upstream. - * reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; - */ - vcc33-supply = <&pp3300_s3>; - }; -}; - -&i2c2 { - touchpad@2c { - status = "disabled"; - }; - - touchpad@68 { - compatible = "hid-over-i2c"; - reg = <0x68>; - hid-descr-addr = <0x20>; - interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>; - vcc-supply = <&pp3300_s3>; - wakeup-source; - }; -}; - -&i2c5 { - clock-frequency = <400000>; - - rt5650: rt5650@1a { - compatible = "realtek,rt5650"; - reg = <0x1a>; - avdd-supply = <&mt6366_vio18_reg>; - pinctrl-names = "default"; - pinctrl-0 = <&rt1019p_pins_default>; - cbj-sleeve-gpio = <&pio 150 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pio>; - interrupts = <17 IRQ_TYPE_EDGE_BOTH>; - #sound-dai-cells = <0>; - realtek,dmic1-data-pin = <2>; - realtek,jd-mode = <2>; - }; -}; - -&sound { - status = "okay"; - - compatible = "mediatek,mt8186-mt6366-rt5650-sound"; - model = "mt8186_rt5650"; - - audio-routing = - "Headphone", "HPOL", - "Headphone", "HPOR", - "HDMI1", "TX"; - - hs-playback-dai-link { - codec { - sound-dai = <&rt5650>; - }; - }; - - hs-capture-dai-link { - codec { - sound-dai = <&rt5650>; - }; - }; - - spk-hdmi-playback-dai-link { - codec { - sound-dai = <&it6505dptx>; - }; - }; -}; -- GitLab From 40145f907c15cc96fdfb9cc5fda9239c9e6f5ff3 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 10 Dec 2024 04:38:00 +0000 Subject: [PATCH 129/456] Revert "CHROMIUM: arm64: dts: mediate: Introduce MT8186 Chinchou/Chinchou360 Chromebook" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a143545a12deebcd2f54d7ed97fe852cde245ab7. Reason for revert: Upstream changes to mt8186-corsola.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. Original change's description: > CHROMIUM: arm64: dts: mediate: Introduce MT8186 Chinchou/Chinchou360 Chromebook > > The MT8186 Chinchou/Chinchou360, also known as the Asus Chromebook > CZ12/CZ11 Flip, is a clamshell or convertible device with touchscreen > andi stylus. > > BUG=b:366134687 > UPSTREAM-TASK=b:365065372 > TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 > > Change-Id: Id92671b6f84bdaba817692fcb8035171d34ac5af > Signed-off-by: Albert Jakieła > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5868877 > Tested-by: Wojciech Macek > Commit-Queue: ChromeOS Auto Retry > Reviewed-by: Wojciech Macek Conflicts: arch/arm64/boot/dts/mediatek/Makefile BUG=b:366134687 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:365065372 Change-Id: Ibd164995e5595ebb6015c6fe9c0f77845a110695 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083572 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 3 - .../mediatek/mt8186-corsola-chinchou-sku0.dts | 18 - .../mediatek/mt8186-corsola-chinchou-sku1.dts | 34 -- .../mt8186-corsola-chinchou-sku16.dts | 28 -- .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 445 ------------------ 5 files changed, 528 deletions(-) delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts delete mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 36234bfb84dc7..73e93dda81b53 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -52,9 +52,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-kyogre.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts deleted file mode 100644 index 29dd92318da13..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2023 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-chinchou.dtsi" - -/ { - model = "Google chinchou sku0 board"; - compatible = "google,chinchou-sku0", "google,chinchou-sku2", - "google,chinchou-sku4", "google,chinchou-sku5", - "google,chinchou", "mediatek,mt8186"; -}; - -&gpio_keys { - status = "disabled"; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts deleted file mode 100644 index 8ba31f81d9ada..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2023 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-chinchou.dtsi" - -/ { - model = "Google chinchou sku1/sku17 board"; - compatible = "google,chinchou-sku1", "google,chinchou-sku17", - "google,chinchou-sku3", "google,chinchou-sku6", - "google,chinchou-sku7", "google,chinchou-sku20", - "google,chinchou-sku22", "google,chinchou-sku23", - "mediatek,mt8186"; -}; - -&i2c1 { - i2c-scl-internal-delay-ns = <10000>; - - touchscreen: touchscreen@41 { - compatible = "ilitek,ili2901"; - reg = <0x41>; - interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&touchscreen_pins>; - reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; - vccio-supply = <&pp1800_tchscr_report_disable>; - }; -}; - -&gpio_keys { - status = "disabled"; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts deleted file mode 100644 index d3378d7ad096a..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2023 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola-chinchou.dtsi" - -/ { - model = "Google chinchou sku16/sku2147483647 board"; - compatible = "google,chinchou-sku16", "google,chinchou-sku18", - "google,chinchou-sku19", "google,chinchou-sku21", - "google,chinchou-sku2147483647", "mediatek,mt8186"; -}; - -&i2c1 { - i2c-scl-internal-delay-ns = <10000>; - - touchscreen: touchscreen@41 { - compatible = "ilitek,ili2901"; - reg = <0x41>; - interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&touchscreen_pins>; - reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; - vccio-supply = <&pp1800_tchscr_report_disable>; - }; -}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi deleted file mode 100644 index c77cc43f84429..0000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi +++ /dev/null @@ -1,445 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2023 Google LLC - */ - -/dts-v1/; -#include "mt8186-corsola.dtsi" - -/ { - tboard_thermistor1: thermal-sensor1 { - compatible = "generic-adc-thermal"; - #thermal-sensor-cells = <0>; - io-channels = <&auxadc 0>; - io-channel-names = "sensor-channel"; - temperature-lookup-table = < (-5000) 1491 - 0 1413 - 5000 1324 - 10000 1225 - 15000 1120 - 20000 1012 - 25000 900 - 30000 797 - 35000 698 - 40000 607 - 45000 525 - 50000 451 - 55000 386 - 60000 330 - 65000 282 - 70000 241 - 75000 206 - 80000 176 - 85000 151 - 90000 129 - 95000 111 - 100000 96 - 105000 83 - 110000 72 - 115000 62 - 120000 54 - 125000 47>; - }; - - tboard_thermistor2: thermal-sensor2 { - compatible = "generic-adc-thermal"; - #thermal-sensor-cells = <0>; - io-channels = <&auxadc 1>; - io-channel-names = "sensor-channel"; - temperature-lookup-table = < (-5000) 1491 - 0 1413 - 5000 1324 - 10000 1225 - 15000 1120 - 20000 1012 - 25000 900 - 30000 797 - 35000 698 - 40000 607 - 45000 525 - 50000 451 - 55000 386 - 60000 330 - 65000 282 - 70000 241 - 75000 206 - 80000 176 - 85000 151 - 90000 129 - 95000 111 - 100000 96 - 105000 83 - 110000 72 - 115000 62 - 120000 54 - 125000 47>; - }; - - pp1800_tchscr_report_disable: regulator-pp1800-tchscr-report-disable { - compatible = "regulator-fixed"; - regulator-name = "pp1800_tchscr_report_disable"; - pinctrl-names = "default"; - enable-active-low; - regulator-boot-on; - pinctrl-0 = <&touch_pin_report>; - gpio = <&pio 37 GPIO_ACTIVE_LOW>; - }; - - pp1000_edpbrdg: regulator-pp1000-edpbrdg { - compatible = "regulator-fixed"; - regulator-name = "pp1000_edpbrdg"; - pinctrl-names = "default"; - pinctrl-0 = <&en_pp1000_edpbrdg>; - enable-active-high; - regulator-boot-on; - gpio = <&pio 29 GPIO_ACTIVE_HIGH>; - vin-supply = <&pp3300_z2>; - }; - - pp1800_edpbrdg_dx: regulator-pp1800-edpbrdg-dx { - compatible = "regulator-fixed"; - regulator-name = "pp1800_edpbrdg_dx"; - pinctrl-names = "default"; - pinctrl-0 = <&en_pp1800_edpbrdg>; - enable-active-high; - regulator-boot-on; - gpio = <&pio 30 GPIO_ACTIVE_HIGH>; - vin-supply = <&mt6366_vio18_reg>; - }; - - pp3300_edp_dx: regulator-pp3300-edp-dx { - compatible = "regulator-fixed"; - regulator-name = "pp3300_edp_dx"; - pinctrl-names = "default"; - pinctrl-0 = <&en_pp3300_edpbrdg>; - enable-active-high; - regulator-boot-on; - gpio = <&pio 31 GPIO_ACTIVE_HIGH>; - vin-supply = <&pp3300_z2>; - }; -}; - -&rt5682s { - status = "disabled"; -}; - -&rt1019p { - status = "disabled"; -}; - -&dsi_out { - remote-endpoint = <&anx7625_in>; -}; - -&i2c0 { - clock-frequency = <400000>; - - anx_bridge: anx7625@58 { - compatible = "analogix,anx7625"; - reg = <0x58>; - pinctrl-names = "default"; - pinctrl-0 = <&anx7625_pins>; - panel_flags = <1>; - enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>; - reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>; - vdd10-supply = <&pp1000_edpbrdg>; - vdd18-supply = <&pp1800_edpbrdg_dx>; - vdd33-supply = <&pp3300_edp_dx>; - #address-cells = <1>; - #size-cells = <0>; - analogix,lane0-swing = /bits/ 8 <0x70 0x30>; - analogix,lane1-swing = /bits/ 8 <0x70 0x30>; - - port@0 { - reg = <0>; - - anx7625_in: endpoint { - remote-endpoint = <&dsi_out>; - data-lanes = <0 1 2 3>; - }; - }; - - port@1 { - reg = <1>; - - anx7625_out: endpoint { - remote-endpoint = <&panel_in>; - }; - }; - - aux-bus { - panel: panel { - compatible = "edp-panel"; - power-supply = <&pp3300_disp_x>; - backlight = <&backlight_lcd0>; - - port { - panel_in: endpoint { - remote-endpoint = <&anx7625_out>; - }; - }; - }; - }; - }; -}; - -&i2c2 { - trackpad@15 { - compatible = "hid-over-i2c"; - post-power-on-delay-ms = <10>; - hid-descr-addr = <0x0001>; - vdd-supply = <&pp3300_s3>; - }; -}; - -&i2c5 { - clock-frequency = <400000>; - - rt5650: rt5650@1a { - compatible = "realtek,rt5650"; - reg = <0x1a>; - avdd-supply = <&mt6366_vio18_reg>; - pinctrl-names = "default"; - pinctrl-0 = <&rt1019p_pins_default>; - cbj-sleeve-gpio = <&pio 150 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pio>; - interrupts = <17 IRQ_TYPE_EDGE_BOTH>; - #sound-dai-cells = <0>; - realtek,dmic1-data-pin = <2>; - realtek,jd-mode = <2>; - }; -}; - -&mmc1_pins_default { - pins-clk { - drive-strength = ; - }; - - pins-cmd-dat { - drive-strength = ; - }; -}; - -&mmc1_pins_uhs { - pins-clk { - drive-strength = ; - }; - - pins-cmd-dat { - drive-strength = ; - }; -}; - -&sound { - status = "okay"; - - compatible = "mediatek,mt8186-mt6366-rt5650-sound"; - mediatek,adsp = <&adsp>; - - audio-routing = - "Headphone", "HPOL", - "Headphone", "HPOR", - "HDMI1", "TX"; - - hs-playback-dai-link { - codec { - sound-dai = <&rt5650>; - }; - }; - - hs-capture-dai-link { - codec { - sound-dai = <&rt5650>; - }; - }; - - spk-share-dai-link { - }; - - spk-hdmi-playback-dai-link { - codec { - sound-dai = <&it6505dptx>; - }; - }; -}; - -&wifi_enable_pin { - pins-wifi-enable { - pinmux = ; - }; -}; - -&wifi_pwrseq { - reset-gpios = <&pio 51 GPIO_ACTIVE_LOW>; -}; - -&keyboard_controller { - keypad,num-columns = <15>; - - function-row-physmap = < - MATRIX_KEY(0x00, 0x02, 0) /* T1 */ - MATRIX_KEY(0x03, 0x02, 0) /* T2 */ - MATRIX_KEY(0x02, 0x02, 0) /* T3 */ - MATRIX_KEY(0x01, 0x02, 0) /* T4 */ - MATRIX_KEY(0x03, 0x04, 0) /* T5 */ - MATRIX_KEY(0x02, 0x04, 0) /* T6 */ - MATRIX_KEY(0x01, 0x04, 0) /* T7 */ - MATRIX_KEY(0x02, 0x09, 0) /* T8 */ - MATRIX_KEY(0x01, 0x09, 0) /* T9 */ - MATRIX_KEY(0x00, 0x04, 0) /* T10 */ - MATRIX_KEY(0x00, 0x01, 0) /* T11 */ - MATRIX_KEY(0x01, 0x05, 0) /* T12 */ - >; - - linux,keymap = < - CROS_STD_MAIN_KEYMAP - MATRIX_KEY(0x00, 0x02, KEY_BACK) /* T1 */ - MATRIX_KEY(0x03, 0x02, KEY_REFRESH) /* T2 */ - MATRIX_KEY(0x02, 0x02, KEY_ZOOM) /* T3 */ - MATRIX_KEY(0x01, 0x02, KEY_SCALE) /* T4 */ - MATRIX_KEY(0x03, 0x04, KEY_SYSRQ) /* T5 */ - MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN) /* T6 */ - MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP) /* T7 */ - MATRIX_KEY(0x02, 0x09, KEY_MUTE) /* T8 */ - MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN) /* T9 */ - MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP) /* T10 */ - MATRIX_KEY(0x00, 0x01, KEY_MICMUTE) /* T11 */ - MATRIX_KEY(0x01, 0x05, KEY_CONTROLPANEL) /* T12 */ - MATRIX_KEY(0x03, 0x05, KEY_PREVIOUSSONG) /* T13 */ - MATRIX_KEY(0x00, 0x09, KEY_PLAYPAUSE) /* T14 */ - MATRIX_KEY(0x00, 0x0b, KEY_NEXTSONG) /* T15 */ - MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA) /* Search*/ - MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL) /* Left Control*/ - MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT) /* Left ALT*/ - MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL) /* Right Control*/ - MATRIX_KEY(0x06, 0x0a, KEY_BACKSLASH) /* BACKSLASH*/ - >; -}; - -&thermal_zones { - cpu-ntc { - polling-delay = <1000>; /* milliseconds */ - polling-delay-passive = <0>; /* milliseconds */ - thermal-sensors = <&tboard_thermistor1>; - }; - - pmic-ntc { - polling-delay = <1000>; /* milliseconds */ - polling-delay-passive = <50>; /* milliseconds */ - thermal-sensors = <&tboard_thermistor2>; - sustainable-power = <1500>; - - trips { - pmic_temp_alert0: trip-point@0 { - temperature = <50000>; - hysteresis = <2000>; - type = "passive"; - }; - - pmic_temp_alert1: target@1 { - temperature = <60000>; - hysteresis = <2000>; - type = "passive"; - }; - - pmic_ntc_crit: pmic-ntc-crit@0 { - temperature = <80000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&pmic_temp_alert1>; - cooling-device = <&cpu0 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu1 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu2 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu3 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu4 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu5 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>; - contribution = <4096>; - }; - - map1 { - trip = <&pmic_temp_alert1>; - cooling-device = <&cpu6 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu7 - THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>; - contribution = <1024>; - }; - }; - }; -}; - -&pio { - touch_pin_report: pin-report { - pinmux = ; - output-low; - }; - - anx7625_pins: anx7625-pins { - pins1 { - pinmux = , - ; - output-low; - }; - - pins2 { - pinmux = ; - input-enable; - bias-pull-up; - }; - }; - - en_pp1000_edpbrdg: pp1000-edpbrdg-en-pins { - pins-vreg-en { - pinmux = ; - output-low; - }; - }; - - en_pp1800_edpbrdg: pp1800-edpbrdg-en-pins { - pins-vreg-en { - pinmux = ; - output-low; - }; - }; - - en_pp3300_edpbrdg: pp3300-edpbrdg-en-pins { - pins-vreg-en { - pinmux = ; - output-low; - }; - }; -}; - -&i2c_tunnel { - /delete-node/ sbs-battery@b; - - battery: sbs-battery@f { - compatible = "sbs,sbs-battery"; - reg = <0xf>; - sbs,i2c-retry-count = <2>; - sbs,poll-retry-count = <1>; - }; -}; - -&pen_insert { - wakeup-event-action = ; -}; -- GitLab From 4a1891982592bf4edba7f7c6a587e2d256c007bf Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 20 Jun 2024 17:47:37 +0800 Subject: [PATCH 130/456] UPSTREAM: dt-bindings: arm: mediatek: Add MT8186 Voltorb Chromebooks Add an entry for the MT8186 based Voltorb Chromebooks, also known as the Acer Chromebook 311 (C723/C723T). The device is a clamshell style laptop with an optional touchscreen. Signed-off-by: Chen-Yu Tsai Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240620094746.2404753-3-wenst@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 9b4e41428498651da04e0ceca879958a6703b4dd) BUG=b:213000788 TEST=cros build-packages -b corsola chromeos-kernel-6_6 Change-Id: I7ce5e598d695382ea07f8bdbb59b5a270dcab6bc Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087657 Reviewed-by: Sean Paul Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- Documentation/devicetree/bindings/arm/mediatek.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml index 425f79950da6e..08ad93d2d2597 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml @@ -326,6 +326,13 @@ properties: - const: google,tentacruel-sku327683 - const: google,tentacruel - const: mediatek,mt8186 + - description: Google Voltorb (Acer Chromebook 311 C723/C732T) + items: + - enum: + - google,voltorb-sku589824 + - google,voltorb-sku589825 + - const: google,voltorb + - const: mediatek,mt8186 - items: - enum: - mediatek,mt8186-evb -- GitLab From 7af0764ff91c70bbdcc93c457fc1335a55fceb53 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 18 Oct 2024 16:21:11 +0800 Subject: [PATCH 131/456] UPSTREAM: arm64: dts: mediatek: mt8186-corsola-voltorb: Merge speaker codec nodes The Voltorb device uses a speaker codec different from the original Corsola device. When the Voltorb device tree was first added, the new codec was added as a separate node when it should have just replaced the existing one. Merge the two nodes. The only differences are the compatible string and the GPIO line property name. This keeps the device node path for the speaker codec the same across the MT8186 Chromebook line. Also rename the related labels and node names from having rt1019p to speaker codec. Cc: stable@vger.kernel.org # v6.11+ Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20241018082113.1297268-1-wenst@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 26ea2459d1724406bf0b342df6b4b1f002d7f8e3) BUG=b:362203280 TEST=cros build-packages -b corsola chromeos-kernel-6_6 Change-Id: Idd8c5ff98d12e60f149adc386fe7dae2afc1475b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087658 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- .../dts/mediatek/mt8186-corsola-voltorb.dtsi | 21 +++++-------------- .../boot/dts/mediatek/mt8186-corsola.dtsi | 8 +++---- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi index 52ec58128d561..b495a241b4432 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb.dtsi @@ -10,12 +10,6 @@ / { chassis-type = "laptop"; - - max98360a: max98360a { - compatible = "maxim,max98360a"; - sdmode-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; - #sound-dai-cells = <0>; - }; }; &cpu6 { @@ -59,19 +53,14 @@ opp-hz = /bits/ 64 <2200000000>; }; -&rt1019p{ - status = "disabled"; -}; - &sound { compatible = "mediatek,mt8186-mt6366-rt5682s-max98360-sound"; - status = "okay"; +}; - spk-hdmi-playback-dai-link { - codec { - sound-dai = <&it6505dptx>, <&max98360a>; - }; - }; +&speaker_codec { + compatible = "maxim,max98360a"; + sdmode-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; + /delete-property/ sdb-gpios; }; &spmi { diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi index 384f44edb3694..6e25b011af5f1 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi @@ -259,15 +259,15 @@ mediatek,clk-provider = "cpu"; /* RT1019P and IT6505 connected to the same I2S line */ codec { - sound-dai = <&it6505dptx>, <&rt1019p>; + sound-dai = <&it6505dptx>, <&speaker_codec>; }; }; }; - rt1019p: speaker-codec { + speaker_codec: speaker-codec { compatible = "realtek,rt1019p"; pinctrl-names = "default"; - pinctrl-0 = <&rt1019p_pins_default>; + pinctrl-0 = <&speaker_codec_pins_default>; #sound-dai-cells = <0>; sdb-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; }; @@ -1228,7 +1228,7 @@ }; }; - rt1019p_pins_default: rt1019p-default-pins { + speaker_codec_pins_default: speaker-codec-default-pins { pins-sdb { pinmux = ; output-low; -- GitLab From f881bea34702fd29f34b8bba4c03e201041bcef5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Dec 2024 13:40:34 +0800 Subject: [PATCH 132/456] CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Voltorb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This partially reverts commit 8b773a52b717fb59a505ac3b493412745bb05e83. This only reinstates the unprovisioned SKU IDs, not the rev0 proto DTS files. Reason for revert: Upstream changes to mt8186-corsola.dtsi and mt8186-corsola-voltorb.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. Original change's description: > CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Voltorb > > BUG=b:366134684 > TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 > UPSTREAM-TASK=b:362203280 > > Change-Id: I1ad24a7ee242c584397523a363f3d96551db3af6 > Signed-off-by: Albert Jakieła > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6034937 > Reviewed-by: Wojciech Macek BUG=b:366134684 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:362203280 Change-Id: I4ef8bb5ea9945edc44dca573e5991b323e330bdf Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087659 Reviewed-by: Pin-yen Lin Reviewed-by: Albert Jakieła Signed-off-by: Hubert Mazur --- .../boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts index 45e57f7706cc1..89caa6f9eadb7 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-sku589825.dts @@ -8,8 +8,9 @@ / { model = "Google Voltorb sku589825 board"; - compatible = "google,voltorb-sku589825", "google,voltorb", - "mediatek,mt8186"; + compatible = "google,voltorb-sku589825", + "google,voltorb-sku2147483647", "google,voltorb-sku2147483391", + "google,voltorb", "mediatek,mt8186"; }; &i2c1 { -- GitLab From 9da3627c526af1d805ae2f6c73e5f43f36da8499 Mon Sep 17 00:00:00 2001 From: Zhengqiao Xia Date: Mon, 2 Dec 2024 11:20:33 +0800 Subject: [PATCH 133/456] BACKPORT: FROMLIST: arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MT8186 chinchou, known as ASUS Chromebook CZ12 Flip (CZ1204F) and CZ12(CZ1204C), is a MT8186 based laptop. It is based on the "corsola" design.It includes chinchou and chinchou360, including LTE, stylus, touchscreen combinations. Signed-off-by: Zhengqiao Xia (am from https://patchwork.kernel.org/patch/13889962/) (also found at https://lore.kernel.org/r/20241202032035.29045-3-xiazhengqiao@huaqin.corp-partner.google.com) Conflicts: arch/arm64/boot/dts/mediatek/Makefile Conflicts with rule for Kyogre. UPSTREAM-TASK=b:383222356 BUG=b:366136896, b:366134687 TEST=cros build-packages -b corsola chromeos-kernel-6_6 Change-Id: Idd60ce345dfd9aef30ec8d4babaa27e1f2da17c9 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087660 Reviewed-by: Albert Jakieła Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 3 + .../mediatek/mt8186-corsola-chinchou-sku0.dts | 18 + .../mediatek/mt8186-corsola-chinchou-sku1.dts | 35 ++ .../mt8186-corsola-chinchou-sku16.dts | 29 ++ .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++ 5 files changed, 406 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 73e93dda81b53..36234bfb84dc7 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -52,6 +52,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-kyogre.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts new file mode 100644 index 0000000000000..5d012bc4ff0da --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2024 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-chinchou.dtsi" + +/ { + model = "Google chinchou CZ1104CM2A/CZ1204CM2A"; + compatible = "google,chinchou-sku0", "google,chinchou-sku2", + "google,chinchou-sku4", "google,chinchou-sku5", + "google,chinchou", "mediatek,mt8186"; +}; + +&gpio_keys { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts new file mode 100644 index 0000000000000..c18f473f6a0fc --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2024 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-chinchou.dtsi" + +/ { + model = "Google chinchou CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A"; + compatible = "google,chinchou-sku1", "google,chinchou-sku17", + "google,chinchou-sku3", "google,chinchou-sku6", + "google,chinchou-sku7", "google,chinchou-sku20", + "google,chinchou-sku22", "google,chinchou-sku23", + "google,chinchou", "mediatek,mt8186"; +}; + +&gpio_keys { + status = "disabled"; +}; + +&i2c1 { + i2c-scl-internal-delay-ns = <10000>; + + touchscreen: touchscreen@41 { + compatible = "ilitek,ili2901"; + reg = <0x41>; + interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&touchscreen_pins>; + reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; + vccio-supply = <&pp1800_tchscr_report_disable>; + vcc33-supply = <&pp3300_z2>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts new file mode 100644 index 0000000000000..eb377de1fcde6 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2024 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-chinchou.dtsi" + +/ { + model = "Google chinchou CZ1104FM2A/CZ1204FM2A"; + compatible = "google,chinchou-sku16", "google,chinchou-sku18", + "google,chinchou-sku19", "google,chinchou-sku21", + "google,chinchou", "mediatek,mt8186"; +}; + +&i2c1 { + i2c-scl-internal-delay-ns = <10000>; + + touchscreen: touchscreen@41 { + compatible = "ilitek,ili2901"; + reg = <0x41>; + interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&touchscreen_pins>; + reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; + vccio-supply = <&pp1800_tchscr_report_disable>; + vcc33-supply = <&pp3300_z2>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi new file mode 100644 index 0000000000000..c3835c7c44445 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2024 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola.dtsi" + +/ { + /delete-node/ speaker-codec; + + pp1000_edpbrdg: regulator-pp1000-edpbrdg { + compatible = "regulator-fixed"; + regulator-name = "pp1000_edpbrdg"; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp1000_edpbrdg>; + enable-active-high; + regulator-boot-on; + gpio = <&pio 29 GPIO_ACTIVE_HIGH>; + vin-supply = <&pp3300_z2>; + }; + + pp1800_edpbrdg_dx: regulator-pp1800-edpbrdg-dx { + compatible = "regulator-fixed"; + regulator-name = "pp1800_edpbrdg_dx"; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp1800_edpbrdg>; + enable-active-high; + regulator-boot-on; + gpio = <&pio 30 GPIO_ACTIVE_HIGH>; + vin-supply = <&mt6366_vio18_reg>; + }; + + pp3300_edp_dx: regulator-pp3300-edp-dx { + compatible = "regulator-fixed"; + regulator-name = "pp3300_edp_dx"; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp3300_edpbrdg>; + enable-active-high; + regulator-boot-on; + gpio = <&pio 31 GPIO_ACTIVE_HIGH>; + vin-supply = <&pp3300_z2>; + }; + + pp1800_tchscr_report_disable: regulator-pp1800-tchscr-report-disable { + compatible = "regulator-fixed"; + regulator-name = "pp1800_tchscr_report_disable"; + pinctrl-names = "default"; + regulator-boot-on; + pinctrl-0 = <&touch_pin_report>; + gpio = <&pio 37 GPIO_ACTIVE_LOW>; + }; +}; + +&dsi_out { + remote-endpoint = <&anx7625_in>; +}; + +&i2c0 { + clock-frequency = <400000>; + + anx_bridge: anx7625@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + pinctrl-names = "default"; + pinctrl-0 = <&anx7625_pins>; + enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&pp1000_edpbrdg>; + vdd18-supply = <&pp1800_edpbrdg_dx>; + vdd33-supply = <&pp3300_edp_dx>; + analogix,lane0-swing = /bits/ 8 <0x70 0x30>; + analogix,lane1-swing = /bits/ 8 <0x70 0x30>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + anx7625_in: endpoint { + remote-endpoint = <&dsi_out>; + data-lanes = <0 1 2 3>; + }; + }; + + port@1 { + reg = <1>; + + anx7625_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + + aux-bus { + panel: panel { + compatible = "edp-panel"; + power-supply = <&pp3300_disp_x>; + backlight = <&backlight_lcd0>; + + port { + panel_in: endpoint { + remote-endpoint = <&anx7625_out>; + }; + }; + }; + }; + }; +}; + +&i2c2 { + /delete-node/ trackpad@15; + + touchpad@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>; + post-power-on-delay-ms = <10>; + hid-descr-addr = <0x0001>; + vdd-supply = <&pp3300_s3>; + wakeup-source; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + /delete-node/ codec@1a; + + rt5650: rt5650@1a { + compatible = "realtek,rt5650"; + reg = <0x1a>; + avdd-supply = <&mt6366_vio18_reg>; + cpvdd-supply = <&mt6366_vio18_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&speaker_codec_pins_default>; + cbj-sleeve-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&pio>; + interrupts = <17 IRQ_TYPE_EDGE_BOTH>; + #sound-dai-cells = <0>; + realtek,dmic1-data-pin = <2>; + realtek,jd-mode = <2>; + }; +}; + +&i2c_tunnel { + /delete-node/ sbs-battery@b; + + battery: sbs-battery@f { + compatible = "sbs,sbs-battery"; + reg = <0xf>; + sbs,i2c-retry-count = <2>; + sbs,poll-retry-count = <1>; + }; +}; + +&keyboard_controller { + keypad,num-columns = <15>; + + function-row-physmap = < + MATRIX_KEY(0x00, 0x02, 0) /* T1 */ + MATRIX_KEY(0x03, 0x02, 0) /* T2 */ + MATRIX_KEY(0x02, 0x02, 0) /* T3 */ + MATRIX_KEY(0x01, 0x02, 0) /* T4 */ + MATRIX_KEY(0x03, 0x04, 0) /* T5 */ + MATRIX_KEY(0x02, 0x04, 0) /* T6 */ + MATRIX_KEY(0x01, 0x04, 0) /* T7 */ + MATRIX_KEY(0x02, 0x09, 0) /* T8 */ + MATRIX_KEY(0x01, 0x09, 0) /* T9 */ + MATRIX_KEY(0x00, 0x04, 0) /* T10 */ + MATRIX_KEY(0x00, 0x01, 0) /* T11 */ + MATRIX_KEY(0x01, 0x05, 0) /* T12 */ + >; + + linux,keymap = < + CROS_STD_MAIN_KEYMAP + MATRIX_KEY(0x00, 0x02, KEY_BACK) /* T1 */ + MATRIX_KEY(0x03, 0x02, KEY_REFRESH) /* T2 */ + MATRIX_KEY(0x02, 0x02, KEY_ZOOM) /* T3 */ + MATRIX_KEY(0x01, 0x02, KEY_SCALE) /* T4 */ + MATRIX_KEY(0x03, 0x04, KEY_SYSRQ) /* T5 */ + MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN) /* T6 */ + MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP) /* T7 */ + MATRIX_KEY(0x02, 0x09, KEY_MUTE) /* T8 */ + MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN) /* T9 */ + MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP) /* T10 */ + MATRIX_KEY(0x00, 0x01, KEY_MICMUTE) /* T11 */ + MATRIX_KEY(0x01, 0x05, KEY_CONTROLPANEL) /* T12 */ + MATRIX_KEY(0x03, 0x05, KEY_PREVIOUSSONG) /* T13 */ + MATRIX_KEY(0x00, 0x09, KEY_PLAYPAUSE) /* T14 */ + MATRIX_KEY(0x00, 0x0b, KEY_NEXTSONG) /* T15 */ + MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA) /* Search*/ + MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL) /* Left Control*/ + MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT) /* Left ALT*/ + MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL) /* Right Control*/ + MATRIX_KEY(0x06, 0x0a, KEY_BACKSLASH) /* BACKSLASH*/ + >; +}; + +&mmc1_pins_default { + pins-clk { + drive-strength = ; + }; + + pins-cmd-dat { + drive-strength = ; + }; +}; + +&mmc1_pins_uhs { + pins-clk { + drive-strength = ; + }; + + pins-cmd-dat { + drive-strength = ; + }; +}; + +&pen_insert { + wakeup-event-action = ; +}; + +&pio { + anx7625_pins: anx7625-pins { + pins-int { + pinmux = ; + input-enable; + bias-disable; + }; + + pins-reset { + pinmux = ; + output-low; + }; + + pins-power-en { + pinmux = ; + output-low; + }; + }; + + en_pp1000_edpbrdg: pp1000-edpbrdg-en-pins { + pins-vreg-en { + pinmux = ; + output-low; + }; + }; + + en_pp1800_edpbrdg: pp1800-edpbrdg-en-pins { + pins-vreg-en { + pinmux = ; + output-low; + }; + }; + + en_pp3300_edpbrdg: pp3300-edpbrdg-en-pins { + pins-vreg-en { + pinmux = ; + output-low; + }; + }; + + touch_pin_report: pin-report-pins { + pins-touch-en { + pinmux = ; + output-low; + }; + }; +}; + +&sound { + compatible = "mediatek,mt8186-mt6366-rt5650-sound"; + model = "mt8186_rt5650"; + mediatek,adsp = <&adsp>; + + audio-routing = + "Headphone", "HPOL", + "Headphone", "HPOR", + "IN1P", "Headset Mic", + "IN1N", "Headset Mic", + "Speakers", "SPOL", + "Speakers", "SPOR", + "HDMI1", "TX"; + + hs-playback-dai-link { + codec { + sound-dai = <&rt5650>; + }; + }; + + hs-capture-dai-link { + codec { + sound-dai = <&rt5650>; + }; + }; + + spk-share-dai-link { + }; + + spk-hdmi-playback-dai-link { + codec { + sound-dai = <&it6505dptx>; + }; + }; +}; + +&touchscreen_pins { + /delete-node/ pins-report-sw; +}; + +&wifi_enable_pin { + pins-wifi-enable { + pinmux = ; + }; +}; + +&wifi_pwrseq { + reset-gpios = <&pio 51 GPIO_ACTIVE_LOW>; +}; -- GitLab From b629db16633c0126f71143f79011d609c3e25da9 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 10 Dec 2024 17:49:57 +0800 Subject: [PATCH 134/456] CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Chinchou This adds back the unprovisioned SKU ID for Chinchou. UPSTREAM-TASK=b:383222356 BUG=b:366136896, b:366134687 TEST=cros build-packages -b corsola chromeos-kernel-6_6 Change-Id: I03f7d6bece99c7a5385f1a9d4e169eceadff729f Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087661 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts index eb377de1fcde6..8fa5979d7be25 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts @@ -10,6 +10,7 @@ model = "Google chinchou CZ1104FM2A/CZ1204FM2A"; compatible = "google,chinchou-sku16", "google,chinchou-sku18", "google,chinchou-sku19", "google,chinchou-sku21", + "google,chinchou-sku2147483647", "google,chinchou", "mediatek,mt8186"; }; -- GitLab From d81359f47776200e0ca1a323ccc933388a570d66 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Dec 2024 15:26:13 +0800 Subject: [PATCH 135/456] Reapply "CHROMIUM: arm64: dts: mt8186: Add corsola-squirtle board" This reverts commit 4f862436c8436660cbd66c2028b60f2ca81422df. This includes the following commits: bd9dc6c0d7d2 CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Squirtle 1e05dc8b4efe CHROMIUM: arm64: dts: mt8186: Disable trackpad node c63dce2127f6 CHROMIUM: arm64: dts: mt8186: Change touchscreens compatible cd76211072e8 CHROMIUM: arm64: dts: mt8186: Update Squirtle sound card configuration ce404a5722ea CHROMIUM: arm64: dts: mt8186: Add corsola-squirtle board Reason for revert: Upstream changes to mt8186-corsola.dtsi and mt8186-corsola-voltorb.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. Additional changes include: - Drop SKU-specific compatible string and dts file, since there is only one SKU - Rename "touchpad" device node name to "trackpad" - Reorder touchscreen nodes - Adapt to merged and renamed speaker device node - Rename "rt5645" device node name to generic "audio-codec" - Delete existing audio-codec BUG=b:370726331 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:370725325, b:383242710 Change-Id: I870fe89403290406a11558cfe645ced1edf68944 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087662 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 1 + .../dts/mediatek/mt8186-corsola-squirtle.dts | 120 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dts diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 36234bfb84dc7..4f21959f36c27 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -68,6 +68,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku2.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku3.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku4.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-squirtle.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-rev0-sku131072.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-rev0-sku131073.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-starmie-sku0.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dts new file mode 100644 index 0000000000000..1fbebec1a8bb6 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-squirtle.dts @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2024 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-voltorb.dtsi" + +/ { + model = "Google squirtle board"; + compatible = "google,squirtle","mediatek,mt8186"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins &touchscreen_pins>; + + touchscreen@10 { + status = "okay"; + compatible = "elan,ekth6a12nay"; + reg = <0x10>; + interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; + /* + * Squirtle has a second source touchscreen using the same + * GPIO pin. This causes both devices to fail probe, so + * `reset-gpios` are commented. Not using `reset-gpios` + * does not change the operation of the touchscreen, + * because this pin is pulled high in pinctrl. This property + * will be commented out until the correct solution + * is merged into upstream. + * reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; + */ + vcc33-supply = <&pp3300_s3>; + }; + + touchscreen@16 { + status = "okay"; + compatible = "elan,ekth6a12nay"; + reg = <0x16>; + interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; + /* + * Squirtle has a second source touchscreen using the same + * GPIO pin. This causes both devices to fail probe, so + * `reset-gpios` are commented. Not using `reset-gpios` + * does not change the operation of the touchscreen, + * because this pin is pulled high in pinctrl. This property + * will be commented out until the correct solution + * is merged into upstream. + * reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; + */ + vcc33-supply = <&pp3300_s3>; + }; +}; + +&i2c2 { + trackpad@2c { + status = "disabled"; + }; + + trackpad@68 { + compatible = "hid-over-i2c"; + reg = <0x68>; + hid-descr-addr = <0x20>; + interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>; + vcc-supply = <&pp3300_s3>; + wakeup-source; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + + /delete-node/ codec@1a; + + rt5650: codec@1a { + compatible = "realtek,rt5650"; + reg = <0x1a>; + interrupts-extended = <&pio 17 IRQ_TYPE_EDGE_BOTH>; + avdd-supply = <&mt6366_vio18_reg>; + cpvdd-supply = <&mt6366_vio18_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&speaker_codec_pins_default>; + cbj-sleeve-gpio = <&pio 150 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + realtek,dmic1-data-pin = <2>; + realtek,jd-mode = <2>; + }; +}; + +&speaker_codec { + status = "disabled"; +}; + +&sound { + compatible = "mediatek,mt8186-mt6366-rt5650-sound"; + model = "mt8186_rt5650"; + + audio-routing = + "Headphone", "HPOL", + "Headphone", "HPOR", + "HDMI1", "TX"; + + hs-playback-dai-link { + codec { + sound-dai = <&rt5650>; + }; + }; + + hs-capture-dai-link { + codec { + sound-dai = <&rt5650>; + }; + }; + + spk-hdmi-playback-dai-link { + codec { + sound-dai = <&it6505dptx>; + }; + }; +}; -- GitLab From e655fed49b068eeb0de2285571cd7889ee6d9e29 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Dec 2024 15:07:21 +0800 Subject: [PATCH 136/456] CHROMIUM: arm64: dts: mt8186: Add Voltorb Proto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This partially reverts commit 8b773a52b717fb59a505ac3b493412745bb05e83. This only reinstates the rev0 proto DTS files, not the unprovisioned SKU IDs. This may not actually be needed if the proto devices aren't used anywhere. Reason for revert: Upstream changes to mt8186-corsola.dtsi and mt8186-corsola-voltorb.dtsi cause conflicts and build errors. Revert and reapply to make it bisectable. Original change's description: > CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Voltorb > > BUG=b:366134684 > TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 > UPSTREAM-TASK=b:362203280 > > Change-Id: I1ad24a7ee242c584397523a363f3d96551db3af6 > Signed-off-by: Albert Jakieła > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6034937 > Reviewed-by: Wojciech Macek BUG=b:366134684 TEST=cros build-packages -b corsola chromeos-kernel-6_6 UPSTREAM-TASK=b:362203280 Change-Id: I3da286fed844fb757d79ab4fa71d4f280f3d6b9b Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6087663 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 2 + .../mt8186-corsola-voltorb-rev0-sku589824.dts | 46 +++++++++++++++++++ .../mt8186-corsola-voltorb-rev0-sku589825.dts | 37 +++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 4f21959f36c27..9d7137de16228 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -90,6 +90,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131077.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131080.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku131082.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-veluza-sku65536.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-rev0-sku589824.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-rev0-sku589825.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589824.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-voltorb-sku589825.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts new file mode 100644 index 0000000000000..7e9667dd4be72 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589824.dts @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2022 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-voltorb.dtsi" + +/ { + model = "Google Voltorb rev0 sku589824(non-T) board"; + compatible = "google,voltorb-rev0-sku589824", "google,voltorb", + "mediatek,mt8186"; +}; + +&cluster1_opp_14 { + opp-hz = /bits/ 64 <1986000000>; + opp-microvolt = <1093750>; +}; + +&cluster1_opp_15 { + opp-hz = /bits/ 64 <2050000000>; +}; + +&cpu6 { + proc-supply = <&mt6366_vproc11_reg>; + /delete-property/ sram-supply; +}; + +&cpu7 { + proc-supply = <&mt6366_vproc11_reg>; + /delete-property/ sram-supply; +}; + +&sound { + compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound"; +}; + +&speaker_codec { + compatible = "realtek,rt1019p"; + sdb-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; + /delete-property/ sdmode-gpios; +}; + +&spmi { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts new file mode 100644 index 0000000000000..de6a42d0ff9da --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-voltorb-rev0-sku589825.dts @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2022 Google LLC + */ + +/dts-v1/; +#include "mt8186-corsola-voltorb.dtsi" + +/ { + model = "Google Voltorb rev0 sku589825 board"; + compatible = "google,voltorb-rev0-sku589825", "google,voltorb", + "mediatek,mt8186"; +}; + +&i2c1 { + touchscreen_auo: touchscreen@10 { + compatible = "hid-over-i2c"; + reg = <0x10>; + interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&touchscreen_pins>; + reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>; + vdd-supply = <&pp3300_s3>; + post-power-on-delay-ms = <450>; + hid-descr-addr = <0x0001>; + }; +}; + +&sound { + compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound"; +}; + +&speaker_codec { + compatible = "realtek,rt1019p"; + sdb-gpios = <&pio 150 GPIO_ACTIVE_HIGH>; + /delete-property/ sdmode-gpios; +}; -- GitLab From 3bab9acc3b16a0a7265653c954f91b78900f3713 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Thu, 12 Dec 2024 08:04:50 +0000 Subject: [PATCH 137/456] CHROMIUM: HID: hid-himax: Add spi_device_id Add spi_device_id for this driver. This is essential for auto-probe when build as module. BUG=b:382031220 TEST=driver get probed when build as module UPSTREAM-TASK=b:321173762 Change-Id: Ia23f64dfd2f1343d05216af9d149fe1a7e4bea53 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088656 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/hid/hid-himax.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/hid/hid-himax.c b/drivers/hid/hid-himax.c index e3a17119fa145..2f24a306d261f 100644 --- a/drivers/hid/hid-himax.c +++ b/drivers/hid/hid-himax.c @@ -5342,6 +5342,12 @@ static const struct of_device_id himax_table[] = { MODULE_DEVICE_TABLE(of, himax_table); #endif +static const struct spi_device_id himax_spi_id[] = { + { "hx83102j" }, + { }, +}; +MODULE_DEVICE_TABLE(spi, himax_spi_id); + static struct spi_driver himax_hid_over_spi_driver = { .driver = { .name = "hx83102j", -- GitLab From 127e2b5dfe7ef746fc53850a2e566603ca4866e5 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 10 Dec 2024 13:48:07 -0800 Subject: [PATCH 138/456] Revert "FROMLIST: scsi: ufs: core: sysfs: Prevent div by zero" This reverts commit faf8c96c0071ace4f5bc156f2eb364b2fed3adf5. Using upstream version. BUG=b:374857405 UPSTREAM-TASK=b:379985341 TEST=none Change-Id: I0bdea5bb781bea008f755799c825ff7ececa5464 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6086139 Reviewed-by: Daniil Lunev Reviewed-by: Alexis Savery Signed-off-by: Hubert Mazur --- drivers/ufs/core/ufs-sysfs.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 06917153df7ba..8397a5226b1b3 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -485,9 +485,6 @@ static ssize_t read_req_latency_avg_show(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_hba_monitor *m = &hba->monitor; - if (!m->nr_req[READ]) - return sysfs_emit(buf, "0\n"); - return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[READ]), m->nr_req[READ])); } @@ -555,9 +552,6 @@ static ssize_t write_req_latency_avg_show(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_hba_monitor *m = &hba->monitor; - if (!m->nr_req[WRITE]) - return sysfs_emit(buf, "0\n"); - return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[WRITE]), m->nr_req[WRITE])); } -- GitLab From f0a51e651703eeaca8de0259449fbb8f0b1e00de Mon Sep 17 00:00:00 2001 From: Charles Wang Date: Mon, 11 Nov 2024 15:49:59 +0800 Subject: [PATCH 139/456] UPSTREAM: dt-bindings: input: Goodix GT7986U SPI HID Touchscreen The Goodix GT7986U touch controller report touch data according to the HID protocol through the SPI bus. However, it is incompatible with Microsoft's HID-over-SPI protocol. NOTE: these bindings are distinct from the bindings used with the GT7986U when the chip is running I2C firmware. For some background, see discussion on the mailing lists in the thread: https://lore.kernel.org/r/20241018020815.3098263-2-charles.goodix@gmail.com Signed-off-by: Charles Wang Reviewed-by: Douglas Anderson Reviewed-by: Rob Herring (Arm) Signed-off-by: Jiri Kosina (cherry picked from commit 20bcb2734bafa2adfbf8fc62542c742df9c46cfd) BUG=b:374150242 TEST=None Change-Id: I237ebba10b09c620e4c1279270f95ae7de97f7b7 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088572 Reviewed-by: Sean Paul Tested-by: Jingyuan Liang Reviewed-by: Jingyuan Liang Reviewed-by: Henry Barnor Signed-off-by: Hubert Mazur --- .../bindings/input/goodix,gt7986u-spifw.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/goodix,gt7986u-spifw.yaml diff --git a/Documentation/devicetree/bindings/input/goodix,gt7986u-spifw.yaml b/Documentation/devicetree/bindings/input/goodix,gt7986u-spifw.yaml new file mode 100644 index 0000000000000..92bd0041febaf --- /dev/null +++ b/Documentation/devicetree/bindings/input/goodix,gt7986u-spifw.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/goodix,gt7986u-spifw.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Goodix GT7986U SPI HID Touchscreen + +maintainers: + - Charles Wang + +description: | + Supports the Goodix GT7986U touchscreen. + This touch controller reports data packaged according to the HID protocol + over the SPI bus, but it is incompatible with Microsoft's HID-over-SPI protocol. + + NOTE: these bindings are distinct from the bindings used with the + GT7986U when the chip is running I2C firmware. This is because there's + not a single device that talks over both I2C and SPI but rather + distinct touchscreens that happen to be built with the same ASIC but + that are distinct products running distinct firmware. + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - goodix,gt7986u-spifw + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + spi-max-frequency: true + +required: + - compatible + - reg + - interrupts + - reset-gpios + +unevaluatedProperties: false + +examples: + - | + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@0 { + compatible = "goodix,gt7986u-spifw"; + reg = <0>; + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + spi-max-frequency = <10000000>; + }; + }; + +... -- GitLab From bf6ec142c2b5e7d4782ac7ee26271d39c58e59b7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 25 Sep 2024 21:49:20 +0200 Subject: [PATCH 140/456] UPSTREAM: HID: hid-goodix: drop unsupported and undocumented DT part Drop support for Devicetree from, because the binding is being reverted (on basis of duplicating existing binding) and property was not added to the original binding. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Jiri Kosina (cherry picked from commit c6bae35fd67087e2dd2d874d0553e59b2f132424) BUG=b:374150242 TEST=Existing touchscreens still work Change-Id: I14014495080b461c37d567b952e68bb75b7a40f2 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088573 Reviewed-by: Sean Paul Tested-by: Jingyuan Liang Reviewed-by: Jingyuan Liang Reviewed-by: Henry Barnor Signed-off-by: Hubert Mazur --- drivers/hid/hid-goodix-spi.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/hid/hid-goodix-spi.c b/drivers/hid/hid-goodix-spi.c index 1f77d6c973d03..37ffb753ecc8d 100644 --- a/drivers/hid/hid-goodix-spi.c +++ b/drivers/hid/hid-goodix-spi.c @@ -790,14 +790,6 @@ static const struct acpi_device_id goodix_spi_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, goodix_spi_acpi_match); #endif -#ifdef CONFIG_OF -static const struct of_device_id goodix_spi_of_match[] = { - { .compatible = "goodix,gt7986u", }, - { } -}; -MODULE_DEVICE_TABLE(of, goodix_spi_of_match); -#endif - static const struct spi_device_id goodix_spi_ids[] = { { "gt7986u" }, { }, @@ -808,7 +800,6 @@ static struct spi_driver goodix_spi_driver = { .driver = { .name = "goodix-spi-hid", .acpi_match_table = ACPI_PTR(goodix_spi_acpi_match), - .of_match_table = of_match_ptr(goodix_spi_of_match), .pm = pm_sleep_ptr(&goodix_spi_pm_ops), }, .probe = goodix_spi_probe, -- GitLab From c4684649b4f73e32747f4f2e16f3f5657cc93023 Mon Sep 17 00:00:00 2001 From: Charles Wang Date: Mon, 11 Nov 2024 15:50:00 +0800 Subject: [PATCH 141/456] UPSTREAM: HID: hid-goodix-spi: Add OF supports This patch introduces the following changes: - Adds OF match table. - Hardcodes hid-report-addr in the driver rather than fetching it from the device property. Signed-off-by: Charles Wang Reviewed-by: Douglas Anderson Signed-off-by: Jiri Kosina (cherry picked from commit c8eb2faef11866be7802ff2ce9852890bcfcde16) BUG=b:374150242 TEST=Existing touchscreens still work Change-Id: I574d3b57c6c931df2553c0b552f02f52c51a935b Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088574 Reviewed-by: Jingyuan Liang Reviewed-by: Henry Barnor Reviewed-by: Sean Paul Tested-by: Jingyuan Liang Signed-off-by: Hubert Mazur --- drivers/hid/hid-goodix-spi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-goodix-spi.c b/drivers/hid/hid-goodix-spi.c index 37ffb753ecc8d..cb3aaef56c957 100644 --- a/drivers/hid/hid-goodix-spi.c +++ b/drivers/hid/hid-goodix-spi.c @@ -20,6 +20,7 @@ #define GOODIX_HID_REPORT_DESC_ADDR 0x105AA #define GOODIX_HID_SIGN_ADDR 0x10D32 #define GOODIX_HID_CMD_ADDR 0x10364 +#define GOODIX_HID_REPORT_ADDR 0x22C8C #define GOODIX_HID_GET_REPORT_CMD 0x02 #define GOODIX_HID_SET_REPORT_CMD 0x03 @@ -701,12 +702,7 @@ static int goodix_spi_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(ts->reset_gpio), "failed to request reset gpio\n"); - error = device_property_read_u32(dev, "goodix,hid-report-addr", - &ts->hid_report_addr); - if (error) - return dev_err_probe(dev, error, - "failed get hid report addr\n"); - + ts->hid_report_addr = GOODIX_HID_REPORT_ADDR; error = goodix_dev_confirm(ts); if (error) return error; @@ -790,6 +786,14 @@ static const struct acpi_device_id goodix_spi_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, goodix_spi_acpi_match); #endif +#ifdef CONFIG_OF +static const struct of_device_id goodix_spi_of_match[] = { + { .compatible = "goodix,gt7986u-spifw", }, + { } +}; +MODULE_DEVICE_TABLE(of, goodix_spi_of_match); +#endif + static const struct spi_device_id goodix_spi_ids[] = { { "gt7986u" }, { }, @@ -800,6 +804,7 @@ static struct spi_driver goodix_spi_driver = { .driver = { .name = "goodix-spi-hid", .acpi_match_table = ACPI_PTR(goodix_spi_acpi_match), + .of_match_table = of_match_ptr(goodix_spi_of_match), .pm = pm_sleep_ptr(&goodix_spi_pm_ops), }, .probe = goodix_spi_probe, -- GitLab From 4039b44d32ed757593560480bdf4cf9f8c1d2810 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:39 +0800 Subject: [PATCH 142/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/i915_gem_object.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults and preemption disables. There're 2 reasons why i915_gem_object_read_from_page_kmap() doesn't need to disable pagefaults and preemption for mapping: 1. The flush operation is safe. In drm/i915/gem/i915_gem_object.c, i915_gem_object_read_from_page_kmap() calls drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, i915_gem_object_read_from_page_kmap() is a function where the use of kmap_local_page() in place of kmap_atomic() is correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). And remove the redundant variable that stores the address of the mapped page since kunmap_local() can accept any pointer within the page. [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-2-zhao1.liu@linux.intel.com (cherry picked from commit e6174e8e19e8fd26016c941c7271868326cd861a) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: Ibfc90660601b31e7be75acf1ab80b3b37dc83174 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951498 Reviewed-by: Sean Paul Reviewed-by: Shyam Sundar Radjacoumar Reviewed-by: Drew Davenport Tested-by: Wentao Qin Commit-Queue: Shawn C Lee Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 25eeeb863209e..58e6c680fe0df 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -500,17 +500,15 @@ static void i915_gem_object_read_from_page_kmap(struct drm_i915_gem_object *obj, u64 offset, void *dst, int size) { pgoff_t idx = offset >> PAGE_SHIFT; - void *src_map; void *src_ptr; - src_map = kmap_atomic(i915_gem_object_get_page(obj, idx)); - - src_ptr = src_map + offset_in_page(offset); + src_ptr = kmap_local_page(i915_gem_object_get_page(obj, idx)) + + offset_in_page(offset); if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) drm_clflush_virt_range(src_ptr, size); memcpy(dst, src_ptr, size); - kunmap_atomic(src_map); + kunmap_local(src_ptr); } static void -- GitLab From 4acef8d9d429366daa4af74596c4472e5a1b64cd Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:40 +0800 Subject: [PATCH 143/456] UPSTREAM: drm/i915: Use memcpy_[from/to]_page() in gem/i915_gem_pyhs.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() + memcpy() to memcpy_[from/to]_page(), which use kmap_local_page() to build local mapping and then do memcpy(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults and preemption disables. In drm/i915/gem/i915_gem_phys.c, the functions i915_gem_object_get_pages_phys() and i915_gem_object_put_pages_phys() don't need to disable pagefaults and preemption for mapping because of 2 reasons: 1. The flush operation is safe. In drm/i915/gem/i915_gem_object.c, i915_gem_object_get_pages_phys() and i915_gem_object_put_pages_phys() calls drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, i915_gem_object_get_pages_phys() and i915_gem_object_put_pages_phys() are two functions where the uses of local mappings in place of atomic mappings are correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() + memcpy() to memcpy_from_page() and memcpy_to_page(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-3-zhao1.liu@linux.intel.com (cherry picked from commit f4d88908cd9a430a7473eea6ff2300a3b728e11c) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I83c4e400593b5877c09621b56fca89275d1ea9ec Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951499 Commit-Queue: Shawn C Lee Reviewed-by: Sean Paul Tested-by: Wentao Qin Reviewed-by: Shyam Sundar Radjacoumar Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c index 5df128e2f4dc2..ef85c6dc9fd59 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -65,16 +65,13 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) dst = vaddr; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { struct page *page; - void *src; page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) goto err_st; - src = kmap_atomic(page); - memcpy(dst, src, PAGE_SIZE); + memcpy_from_page(dst, page, 0, PAGE_SIZE); drm_clflush_virt_range(dst, PAGE_SIZE); - kunmap_atomic(src); put_page(page); dst += PAGE_SIZE; @@ -113,16 +110,13 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { struct page *page; - char *dst; page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) continue; - dst = kmap_atomic(page); drm_clflush_virt_range(src, PAGE_SIZE); - memcpy(dst, src, PAGE_SIZE); - kunmap_atomic(dst); + memcpy_to_page(page, 0, src, PAGE_SIZE); set_page_dirty(page); if (obj->mm.madv == I915_MADV_WILLNEED) -- GitLab From 90fea30674bac60dc9b4f535106df3fc07f9e69f Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:41 +0800 Subject: [PATCH 144/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/i915_gem_shmem.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1]. The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults or preemption disables. In drm/i915/gem/i915_gem_shmem.c, the function shmem_pwrite() need to disable pagefault to eliminate the potential recursion fault[2]. But here __copy_from_user_inatomic() doesn't need to disable preemption and local mapping is valid for sched in/out. So it can use kmap_local_page() / kunmap_local() with pagefault_disable() / pagefault_enable() to replace atomic mapping. [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com [2]: https://patchwork.freedesktop.org/patch/295840/ Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-4-zhao1.liu@linux.intel.com (cherry picked from commit 756eed0f2602f73df8d6c5bc8418ecd11cce9803) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: Iae8585d5978f6ed872a7aa774e864ebf101c5c00 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951500 Reviewed-by: Drew Davenport Tested-by: Wentao Qin Reviewed-by: Shyam Sundar Radjacoumar Reviewed-by: Sean Paul Commit-Queue: Shawn C Lee Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 73a4a4eb29e08..38b72d86560f0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -485,11 +485,13 @@ shmem_pwrite(struct drm_i915_gem_object *obj, if (err < 0) return err; - vaddr = kmap_atomic(page); + vaddr = kmap_local_page(page); + pagefault_disable(); unwritten = __copy_from_user_inatomic(vaddr + pg, user_data, len); - kunmap_atomic(vaddr); + pagefault_enable(); + kunmap_local(vaddr); err = aops->write_end(obj->base.filp, mapping, offset, len, len - unwritten, page, data); -- GitLab From fe217ce86be17b2f3df42d01b2a30ccd3517a20d Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:42 +0800 Subject: [PATCH 145/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/selftests/huge_pages.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults or preemption disables. In drm/i915/gem/selftests/huge_pages.c, function __cpu_check_shmem() mainly uses mapping to flush cache and check the value. There're 2 reasons why __cpu_check_shmem() doesn't need to disable pagefaults and preemption for mapping: 1. The flush operation is safe. Function __cpu_check_shmem() calls drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, __cpu_check_shmem() is a function where the use of kmap_local_page() in place of kmap_atomic() is correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-5-zhao1.liu@linux.intel.com (cherry picked from commit 1fcb967595a5156da2f081a5ade319c60fc5af72) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I0d1c4fb9942d4d691071cceadbd4d9b05c857edf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951501 Reviewed-by: Shyam Sundar Radjacoumar Reviewed-by: Drew Davenport Commit-Queue: Shawn C Lee Reviewed-by: Sean Paul Tested-by: Wentao Qin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 6b9f6cf50bf6b..c9e6d77abab07 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1082,7 +1082,7 @@ __cpu_check_shmem(struct drm_i915_gem_object *obj, u32 dword, u32 val) goto err_unlock; for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) { - u32 *ptr = kmap_atomic(i915_gem_object_get_page(obj, n)); + u32 *ptr = kmap_local_page(i915_gem_object_get_page(obj, n)); if (needs_flush & CLFLUSH_BEFORE) drm_clflush_virt_range(ptr, PAGE_SIZE); @@ -1090,12 +1090,12 @@ __cpu_check_shmem(struct drm_i915_gem_object *obj, u32 dword, u32 val) if (ptr[dword] != val) { pr_err("n=%lu ptr[%u]=%u, val=%u\n", n, dword, ptr[dword], val); - kunmap_atomic(ptr); + kunmap_local(ptr); err = -EINVAL; break; } - kunmap_atomic(ptr); + kunmap_local(ptr); } i915_gem_object_finish_access(obj); -- GitLab From 17f46774a13cd5f5180cc6594c25fc5207913d76 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:43 +0800 Subject: [PATCH 146/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/selftests/i915_gem_coherency.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration).. With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults or preemption disables. In drm/i915/gem/selftests/i915_gem_coherency.c, functions cpu_set() and cpu_get() mainly uses mapping to flush cache and assign the value. There're 2 reasons why cpu_set() and cpu_get() don't need to disable pagefaults and preemption for mapping: 1. The flush operation is safe. cpu_set() and cpu_get() call drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, cpu_set() and cpu_get() are functions where the use of kmap_local_page() in place of kmap_atomic() is correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-6-zhao1.liu@linux.intel.com (cherry picked from commit 40b399000665ee154927a8e0d7b0c7e7505bbaef) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: Iccc32b9a2850758c64fe060528cfbdc2326fa2e1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951502 Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Tested-by: Wentao Qin Commit-Queue: Shawn C Lee Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- .../gpu/drm/i915/gem/selftests/i915_gem_coherency.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c index 3bef1beec7cbb..beeb3e12ecccc 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c @@ -24,7 +24,6 @@ static int cpu_set(struct context *ctx, unsigned long offset, u32 v) { unsigned int needs_clflush; struct page *page; - void *map; u32 *cpu; int err; @@ -34,8 +33,7 @@ static int cpu_set(struct context *ctx, unsigned long offset, u32 v) goto out; page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT); - map = kmap_atomic(page); - cpu = map + offset_in_page(offset); + cpu = kmap_local_page(page) + offset_in_page(offset); if (needs_clflush & CLFLUSH_BEFORE) drm_clflush_virt_range(cpu, sizeof(*cpu)); @@ -45,7 +43,7 @@ static int cpu_set(struct context *ctx, unsigned long offset, u32 v) if (needs_clflush & CLFLUSH_AFTER) drm_clflush_virt_range(cpu, sizeof(*cpu)); - kunmap_atomic(map); + kunmap_local(cpu); i915_gem_object_finish_access(ctx->obj); out: @@ -57,7 +55,6 @@ static int cpu_get(struct context *ctx, unsigned long offset, u32 *v) { unsigned int needs_clflush; struct page *page; - void *map; u32 *cpu; int err; @@ -67,15 +64,14 @@ static int cpu_get(struct context *ctx, unsigned long offset, u32 *v) goto out; page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT); - map = kmap_atomic(page); - cpu = map + offset_in_page(offset); + cpu = kmap_local_page(page) + offset_in_page(offset); if (needs_clflush & CLFLUSH_BEFORE) drm_clflush_virt_range(cpu, sizeof(*cpu)); *v = *cpu; - kunmap_atomic(map); + kunmap_local(cpu); i915_gem_object_finish_access(ctx->obj); out: -- GitLab From ebe587bf0a3b119e46dba6bae668dbeb99861143 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:44 +0800 Subject: [PATCH 147/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/selftests/i915_gem_context.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption. With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults or preemption disables. In drm/i915/gem/selftests/i915_gem_context.c, functions cpu_fill() and cpu_check() mainly uses mapping to flush cache and check/assign the value. There're 2 reasons why cpu_fill() and cpu_check() don't need to disable pagefaults and preemption for mapping: 1. The flush operation is safe. cpu_fill() and cpu_check() call drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, cpu_fill() and cpu_check() are functions where the use of kmap_local_page() in place of kmap_atomic() is correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-7-zhao1.liu@linux.intel.com (cherry picked from commit b1c51b0e2e7cb98f643a801c50f8ad76ebc36450) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: If1fa45e831877d5bb2c08137e2ff5bb740dc6d23 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951943 Reviewed-by: Sean Paul Reviewed-by: Shyam Sundar Radjacoumar Tested-by: Wentao Qin Reviewed-by: Drew Davenport Commit-Queue: Shawn C Lee Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index 7021b6e9b219e..89d4dc8b60c6a 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -489,12 +489,12 @@ static int cpu_fill(struct drm_i915_gem_object *obj, u32 value) for (n = 0; n < real_page_count(obj); n++) { u32 *map; - map = kmap_atomic(i915_gem_object_get_page(obj, n)); + map = kmap_local_page(i915_gem_object_get_page(obj, n)); for (m = 0; m < DW_PER_PAGE; m++) map[m] = value; if (!has_llc) drm_clflush_virt_range(map, PAGE_SIZE); - kunmap_atomic(map); + kunmap_local(map); } i915_gem_object_finish_access(obj); @@ -520,7 +520,7 @@ static noinline int cpu_check(struct drm_i915_gem_object *obj, for (n = 0; n < real_page_count(obj); n++) { u32 *map, m; - map = kmap_atomic(i915_gem_object_get_page(obj, n)); + map = kmap_local_page(i915_gem_object_get_page(obj, n)); if (needs_flush & CLFLUSH_BEFORE) drm_clflush_virt_range(map, PAGE_SIZE); @@ -546,7 +546,7 @@ static noinline int cpu_check(struct drm_i915_gem_object *obj, } out_unmap: - kunmap_atomic(map); + kunmap_local(map); if (err) break; } -- GitLab From fc1edd32e97e7c2d08013d5a6aeabaa0b19edefb Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:45 +0800 Subject: [PATCH 148/456] UPSTREAM: drm/i915: Use memcpy_from_page() in gt/uc/intel_uc_fw.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults or preemption disables. In drm/i915/gt/uc/intel_us_fw.c, the function intel_uc_fw_copy_rsa() just use the mapping to do memory copy so it doesn't need to disable pagefaults and preemption for mapping. Thus the local mapping without atomic context (not disable pagefaults / preemption) is enough. Therefore, intel_uc_fw_copy_rsa() is a function where the use of memcpy_from_page() with kmap_local_page() in place of memcpy() with kmap_atomic() is correctly suited. Convert the calls of memcpy() with kmap_atomic() / kunmap_atomic() to memcpy_from_page() which uses local mapping to copy. [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com/T/#u Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-8-zhao1.liu@linux.intel.com (cherry picked from commit 55a6e46180cb8b36fb1076501b569bfd42df1644) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I99102a5424d303c57fdee99344c84b9988cd18e0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951944 Commit-Queue: Shawn C Lee Tested-by: Wentao Qin Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Reviewed-by: Shyam Sundar Radjacoumar Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index 32e27e9a2490f..6c203c4bd84db 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -1343,16 +1343,13 @@ size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len) for_each_sgt_page(page, iter, uc_fw->obj->mm.pages) { u32 len = min_t(u32, size, PAGE_SIZE - offset); - void *vaddr; if (idx > 0) { idx--; continue; } - vaddr = kmap_atomic(page); - memcpy(dst, vaddr + offset, len); - kunmap_atomic(vaddr); + memcpy_from_page(dst, page, offset, len); offset = 0; dst += len; -- GitLab From c23de2110df22f7bfe237a2eba810d7b4e9d99ae Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:46 +0800 Subject: [PATCH 149/456] UPSTREAM: drm/i915: Use kmap_local_page() in i915_cmd_parser.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the call from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults and preemption disables. There're 2 reasons why function copy_batch() doesn't need to disable pagefaults and preemption for mapping: 1. The flush operation is safe. In i915_cmd_parser.c, copy_batch() calls drm_clflush_virt_range() to use CLFLUSHOPT or WBINVD to flush. Since CLFLUSHOPT is global on x86 and WBINVD is called on each cpu in drm_clflush_virt_range(), the flush operation is global. 2. Any context switch caused by preemption or page faults (page fault may cause sleep) doesn't affect the validity of local mapping. Therefore, copy_batch() is a function where the use of kmap_local_page() in place of kmap_atomic() is correctly suited. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Dave Hansen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-9-zhao1.liu@linux.intel.com (cherry picked from commit e4865c60dd6e312e58c85247e48899af7e19041a) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: Id8fb39e3a5ea37c364e5e77bf2a1cd9b3590951a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951945 Reviewed-by: Shyam Sundar Radjacoumar Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Commit-Queue: Shawn C Lee Tested-by: Wentao Qin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/i915_cmd_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index ddf49c2dbb917..2905df83e180e 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1211,11 +1211,11 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, for (n = offset >> PAGE_SHIFT; remain; n++) { int len = min(remain, PAGE_SIZE - x); - src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); + src = kmap_local_page(i915_gem_object_get_page(src_obj, n)); if (src_needs_clflush) drm_clflush_virt_range(src + x, len); memcpy(ptr, src + x, len); - kunmap_atomic(src); + kunmap_local(src); ptr += len; remain -= len; -- GitLab From 87b608a652142fb6eaf110f930b9392aca2c63f0 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Sun, 3 Dec 2023 21:29:47 +0800 Subject: [PATCH 150/456] UPSTREAM: drm/i915: Use kmap_local_page() in gem/i915_gem_execbuffer.c The use of kmap_atomic() is being deprecated in favor of kmap_local_page()[1], and this patch converts the calls from kmap_atomic() to kmap_local_page(). The main difference between atomic and local mappings is that local mappings doesn't disable page faults or preemption (the preemption is disabled for !PREEMPT_RT case, otherwise it only disables migration). With kmap_local_page(), we can avoid the often unwanted side effect of unnecessary page faults and preemption disables. In i915_gem_execbuffer.c, eb->reloc_cache.vaddr is mapped by kmap_atomic() in eb_relocate_entry(), and is unmapped by kunmap_atomic() in reloc_cache_reset(). And this mapping/unmapping occurs in two places: one is in eb_relocate_vma(), and another is in eb_relocate_vma_slow(). The function eb_relocate_vma() or eb_relocate_vma_slow() doesn't need to disable pagefaults and preemption during the above mapping/ unmapping. So it can simply use kmap_local_page() / kunmap_local() that can instead do the mapping / unmapping regardless of the context. Convert the calls of kmap_atomic() / kunmap_atomic() to kmap_local_page() / kunmap_local(). [1]: https://lore.kernel.org/all/20220813220034.806698-1-ira.weiny@intel.com Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Zhao Liu Reviewed-by: Ira Weiny Reviewed-by: Fabio M. De Francesco Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20231203132947.2328805-10-zhao1.liu@linux.intel.com (cherry picked from commit 31accc37eaee98a90b25809ed58c6ee4956ab642) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I226b819b13ac48fbfc7aee2c841cb17c1180bfa4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951946 Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Commit-Queue: Shawn C Lee Reviewed-by: Sean Paul Tested-by: Wentao Qin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5a687a3686bd5..69a938ff3441a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -1156,7 +1156,7 @@ static void reloc_cache_unmap(struct reloc_cache *cache) vaddr = unmask_page(cache->vaddr); if (cache->vaddr & KMAP) - kunmap_atomic(vaddr); + kunmap_local(vaddr); else io_mapping_unmap_atomic((void __iomem *)vaddr); } @@ -1172,7 +1172,7 @@ static void reloc_cache_remap(struct reloc_cache *cache, if (cache->vaddr & KMAP) { struct page *page = i915_gem_object_get_page(obj, cache->page); - vaddr = kmap_atomic(page); + vaddr = kmap_local_page(page); cache->vaddr = unmask_flags(cache->vaddr) | (unsigned long)vaddr; } else { @@ -1202,7 +1202,7 @@ static void reloc_cache_reset(struct reloc_cache *cache, struct i915_execbuffer if (cache->vaddr & CLFLUSH_AFTER) mb(); - kunmap_atomic(vaddr); + kunmap_local(vaddr); i915_gem_object_finish_access(obj); } else { struct i915_ggtt *ggtt = cache_to_ggtt(cache); @@ -1234,7 +1234,7 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj, struct page *page; if (cache->vaddr) { - kunmap_atomic(unmask_page(cache->vaddr)); + kunmap_local(unmask_page(cache->vaddr)); } else { unsigned int flushes; int err; @@ -1256,7 +1256,7 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj, if (!obj->mm.dirty) set_page_dirty(page); - vaddr = kmap_atomic(page); + vaddr = kmap_local_page(page); cache->vaddr = unmask_flags(cache->vaddr) | (unsigned long)vaddr; cache->page = pageno; -- GitLab From d5b69a1a8d22d5661e0e441d9ffe2edf04fadd3a Mon Sep 17 00:00:00 2001 From: Jonathan Cavitt Date: Tue, 28 Nov 2023 08:25:05 -0800 Subject: [PATCH 151/456] UPSTREAM: drm/i915/gem: Atomically invalidate userptr on mmu-notifier Never block for outstanding work on userptr object upon receipt of a mmu-notifier. The reason we originally did so was to immediately unbind the userptr and unpin its pages, but since that has been dropped in commit b4b9731b02c3c ("drm/i915: Simplify userptr locking"), we never return the pages to the system i.e. never drop our page->mapcount and so do not allow the page and CPU PTE to be revoked. Based on this history, we know we are safe to drop the wait entirely. Upon return from mmu-notifier, we will still have the userptr pages pinned preventing the following PTE operation (such as try_to_unmap) adjusting the vm_area_struct, so it is safe to keep the pages around for as long as we still have i/o pending. We do not have any means currently to asynchronously revalidate the userptr pages, that is always prior to next use. Signed-off-by: Chris Wilson Signed-off-by: Jonathan Cavitt Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20231128162505.3493942-1-jonathan.cavitt@intel.com (cherry picked from commit 86ceaaaec59707b06216a15b3852867fa2f1574e) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I0bcc6275dec16b0b5722cad7e2c0190d3724f06f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951947 Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Commit-Queue: Shawn C Lee Tested-by: Wentao Qin Signed-off-by: Hubert Mazur --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 8 ---- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 42 ------------------- drivers/gpu/drm/i915/gem/i915_gem_userptr.h | 14 ------- drivers/gpu/drm/i915/i915_drv.h | 8 ---- drivers/gpu/drm/i915/i915_gem.c | 5 --- 5 files changed, 77 deletions(-) delete mode 100644 drivers/gpu/drm/i915/gem/i915_gem_userptr.h diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 69a938ff3441a..f94357d0a4fa2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2157,12 +2157,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) #ifdef CONFIG_MMU_NOTIFIER if (!err && (eb->args->flags & __EXEC_USERPTR_USED)) { - read_lock(&eb->i915->mm.notifier_lock); - - /* - * count is always at least 1, otherwise __EXEC_USERPTR_USED - * could not have been set - */ for (i = 0; i < count; i++) { struct eb_vma *ev = &eb->vma[i]; struct drm_i915_gem_object *obj = ev->vma->obj; @@ -2174,8 +2168,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) if (err) break; } - - read_unlock(&eb->i915->mm.notifier_lock); } #endif diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index c08b67593565c..61abfb505766d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -42,7 +42,6 @@ #include "i915_drv.h" #include "i915_gem_ioctls.h" #include "i915_gem_object.h" -#include "i915_gem_userptr.h" #include "i915_scatterlist.h" #ifdef CONFIG_MMU_NOTIFIER @@ -61,36 +60,7 @@ static bool i915_gem_userptr_invalidate(struct mmu_interval_notifier *mni, const struct mmu_notifier_range *range, unsigned long cur_seq) { - struct drm_i915_gem_object *obj = container_of(mni, struct drm_i915_gem_object, userptr.notifier); - struct drm_i915_private *i915 = to_i915(obj->base.dev); - long r; - - if (!mmu_notifier_range_blockable(range)) - return false; - - write_lock(&i915->mm.notifier_lock); - mmu_interval_set_seq(mni, cur_seq); - - write_unlock(&i915->mm.notifier_lock); - - /* - * We don't wait when the process is exiting. This is valid - * because the object will be cleaned up anyway. - * - * This is also temporarily required as a hack, because we - * cannot currently force non-consistent batch buffers to preempt - * and reschedule by waiting on it, hanging processes on exit. - */ - if (current->flags & PF_EXITING) - return true; - - /* we will unbind on next submission, still have userptr pins */ - r = dma_resv_wait_timeout(obj->base.resv, DMA_RESV_USAGE_BOOKKEEP, false, - MAX_SCHEDULE_TIMEOUT); - if (r <= 0) - drm_err(&i915->drm, "(%ld) failed to wait for idle\n", r); - return true; } @@ -583,15 +553,3 @@ i915_gem_userptr_ioctl(struct drm_device *dev, #endif } -int i915_gem_init_userptr(struct drm_i915_private *dev_priv) -{ -#ifdef CONFIG_MMU_NOTIFIER - rwlock_init(&dev_priv->mm.notifier_lock); -#endif - - return 0; -} - -void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv) -{ -} diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.h b/drivers/gpu/drm/i915/gem/i915_gem_userptr.h deleted file mode 100644 index 8dadb2f8436d4..0000000000000 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2021 Intel Corporation - */ - -#ifndef __I915_GEM_USERPTR_H__ -#define __I915_GEM_USERPTR_H__ - -struct drm_i915_private; - -int i915_gem_init_userptr(struct drm_i915_private *dev_priv); -void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv); - -#endif /* __I915_GEM_USERPTR_H__ */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cb2574d7d6db5..8d7af8337317b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -165,14 +165,6 @@ struct i915_gem_mm { struct notifier_block vmap_notifier; struct shrinker shrinker; -#ifdef CONFIG_MMU_NOTIFIER - /** - * notifier_lock for mmu notifiers, memory may not be allocated - * while holding this lock. - */ - rwlock_t notifier_lock; -#endif - /* shrinker accounting, also useful for userland debugging */ u64 shrink_memory; u32 shrink_count; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c166ad5e187a3..02e10451867a5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -48,7 +48,6 @@ #include "gem/i915_gem_object_frontbuffer.h" #include "gem/i915_gem_pm.h" #include "gem/i915_gem_region.h" -#include "gem/i915_gem_userptr.h" #include "gt/intel_engine_user.h" #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" @@ -1165,10 +1164,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv) if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv)) RUNTIME_INFO(dev_priv)->page_sizes = I915_GTT_PAGE_SIZE_4K; - ret = i915_gem_init_userptr(dev_priv); - if (ret) - return ret; - for_each_gt(gt, dev_priv, i) { intel_uc_fetch_firmwares(>->uc); intel_wopcm_init(>->wopcm); -- GitLab From c3c28af1a07742e929d15dca03305ca08983d19a Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 5 Mar 2024 15:35:08 +0100 Subject: [PATCH 152/456] UPSTREAM: Revert "drm/i915: Wait for active retire before i915_active_fini()" This reverts commit 7a2280e8dcd2f1f436db9631287c0b21cf6a92b0, obsoleted by "drm/i915/vma: Fix UAF on destroy against retire race". Signed-off-by: Janusz Krzysztofik Cc: Nirmoy Das Reviewed-by: Nirmoy Das Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240305143747.335367-8-janusz.krzysztofik@linux.intel.com (cherry picked from commit d666a4944e381b64b244e321f5570e5291a579d5) Signed-off-by: Lee Shawn C BUG=b:369985652 TEST=No kernel panic while running system stress test. Change-Id: I4fb76c5a2a32c822308378b1d14e87be0b9a2156 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5951948 Commit-Queue: Shawn C Lee Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Tested-by: Wentao Qin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/i915_vma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 6347ed57f8725..3290d399b730d 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -1768,8 +1768,6 @@ static void release_references(struct i915_vma *vma, struct intel_gt *gt, if (vm_ddestroy) i915_vm_resv_put(vma->vm); - /* Wait for async active retire */ - i915_active_wait(&vma->active); i915_active_fini(&vma->active); GEM_WARN_ON(vma->resource); i915_vma_free(vma); -- GitLab From e34671bc7518f8d0e882d10c57fc4b9b451956f7 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 30 Oct 2023 18:40:12 +0100 Subject: [PATCH 153/456] BACKPORT: drm/i915: Replace custom intel runtime_pm tracker with ref_tracker library Beside reusing existing code, the main advantage of ref_tracker is tracking per instance of wakeref. It allows also to catch double put. On the other side we lose information about the first acquire and the last release, but the advantages outweigh it. BUG=b:361021804 TEST=No kernel panic, no auto reboot issue while running webfish test Change-Id: I645e213fdcea4276fbb5195914850225f5aa9aa8 Signed-off-by: Andrzej Hajda Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20231030-ref_tracker_i915-v1-1-006fe6b96421@intel.com (cherry picked from commit b49e894c3fd83f67aae2a4778b98ea3838e41020) Signed-off-by: Shinni Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6002403 Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/Kconfig.debug | 4 + .../drm/i915/display/intel_display_power.c | 2 +- drivers/gpu/drm/i915/i915_driver.c | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 221 ++---------------- drivers/gpu/drm/i915/intel_runtime_pm.h | 11 +- drivers/gpu/drm/i915/intel_wakeref.c | 28 +++ drivers/gpu/drm/i915/intel_wakeref.h | 35 ++- 7 files changed, 86 insertions(+), 217 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index ecbad4ecd16bd..4dc85e5371785 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -41,7 +41,9 @@ config DRM_I915_DEBUG select DEBUG_FS select PREEMPT_COUNT select I2C_CHARDEV + select REF_TRACKER select STACKDEPOT + select STACKTRACE select DRM_DP_AUX_CHARDEV select DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE if DRM_I915_DP_TUNNEL select X86_MSR # used by igt/pm_rpm @@ -249,7 +251,9 @@ config DRM_I915_DEBUG_RUNTIME_PM bool "Enable extra state checking for runtime PM" depends on DRM_I915 default n + select REF_TRACKER select STACKDEPOT + select STACKTRACE help Choose this option to turn on extra state checking for the runtime PM functionality. This may introduce overhead during diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index c28955171531f..1379ad65d3c30 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -409,7 +409,7 @@ print_async_put_domains_state(struct i915_power_domains *power_domains) struct drm_i915_private, display.power.domains); - drm_dbg(&i915->drm, "async_put_wakeref %u\n", + drm_dbg(&i915->drm, "async_put_wakeref %lu\n", power_domains->async_put_wakeref); print_power_domains(power_domains, "async_put_domains[0]", diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 56cc3469bb7db..c5fc6428830d1 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1023,7 +1023,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_power_domains_driver_remove(i915); enable_rpm_wakeref_asserts(&i915->runtime_pm); - intel_runtime_pm_driver_release(&i915->runtime_pm); + intel_runtime_pm_driver_last_release(&i915->runtime_pm); } static bool suspend_to_idle(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 6d8e5e5c0cba2..0f6905a67788d 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -52,182 +52,37 @@ #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) -#include - -#define STACKDEPTH 8 - -static noinline depot_stack_handle_t __save_depot_stack(void) -{ - unsigned long entries[STACKDEPTH]; - unsigned int n; - - n = stack_trace_save(entries, ARRAY_SIZE(entries), 1); - return stack_depot_save(entries, n, GFP_NOWAIT | __GFP_NOWARN); -} - static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { - spin_lock_init(&rpm->debug.lock); - stack_depot_init(); + ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT, dev_name(rpm->kdev)); } -static noinline depot_stack_handle_t +static intel_wakeref_t track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { - depot_stack_handle_t stack, *stacks; - unsigned long flags; - - if (rpm->no_wakeref_tracking) - return -1; - - stack = __save_depot_stack(); - if (!stack) + if (!rpm->available || rpm->no_wakeref_tracking) return -1; - spin_lock_irqsave(&rpm->debug.lock, flags); - - if (!rpm->debug.count) - rpm->debug.last_acquire = stack; - - stacks = krealloc(rpm->debug.owners, - (rpm->debug.count + 1) * sizeof(*stacks), - GFP_NOWAIT | __GFP_NOWARN); - if (stacks) { - stacks[rpm->debug.count++] = stack; - rpm->debug.owners = stacks; - } else { - stack = -1; - } - - spin_unlock_irqrestore(&rpm->debug.lock, flags); - - return stack; + return intel_ref_tracker_alloc(&rpm->debug); } static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, - depot_stack_handle_t stack) + intel_wakeref_t wakeref) { - struct drm_i915_private *i915 = container_of(rpm, - struct drm_i915_private, - runtime_pm); - unsigned long flags, n; - bool found = false; - - if (unlikely(stack == -1)) + if (!rpm->available || rpm->no_wakeref_tracking) return; - spin_lock_irqsave(&rpm->debug.lock, flags); - for (n = rpm->debug.count; n--; ) { - if (rpm->debug.owners[n] == stack) { - memmove(rpm->debug.owners + n, - rpm->debug.owners + n + 1, - (--rpm->debug.count - n) * sizeof(stack)); - found = true; - break; - } - } - spin_unlock_irqrestore(&rpm->debug.lock, flags); - - if (drm_WARN(&i915->drm, !found, - "Unmatched wakeref (tracking %lu), count %u\n", - rpm->debug.count, atomic_read(&rpm->wakeref_count))) { - char *buf; - - buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN); - if (!buf) - return; - - stack_depot_snprint(stack, buf, PAGE_SIZE, 2); - DRM_DEBUG_DRIVER("wakeref %x from\n%s", stack, buf); - - stack = READ_ONCE(rpm->debug.last_release); - if (stack) { - stack_depot_snprint(stack, buf, PAGE_SIZE, 2); - DRM_DEBUG_DRIVER("wakeref last released at\n%s", buf); - } - - kfree(buf); - } + intel_ref_tracker_free(&rpm->debug, wakeref); } -static int cmphandle(const void *_a, const void *_b) +static void untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm) { - const depot_stack_handle_t * const a = _a, * const b = _b; - - if (*a < *b) - return -1; - else if (*a > *b) - return 1; - else - return 0; -} - -static void -__print_intel_runtime_pm_wakeref(struct drm_printer *p, - const struct intel_runtime_pm_debug *dbg) -{ - unsigned long i; - char *buf; - - buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN); - if (!buf) - return; - - if (dbg->last_acquire) { - stack_depot_snprint(dbg->last_acquire, buf, PAGE_SIZE, 2); - drm_printf(p, "Wakeref last acquired:\n%s", buf); - } - - if (dbg->last_release) { - stack_depot_snprint(dbg->last_release, buf, PAGE_SIZE, 2); - drm_printf(p, "Wakeref last released:\n%s", buf); - } - - drm_printf(p, "Wakeref count: %lu\n", dbg->count); - - sort(dbg->owners, dbg->count, sizeof(*dbg->owners), cmphandle, NULL); - - for (i = 0; i < dbg->count; i++) { - depot_stack_handle_t stack = dbg->owners[i]; - unsigned long rep; - - rep = 1; - while (i + 1 < dbg->count && dbg->owners[i + 1] == stack) - rep++, i++; - stack_depot_snprint(stack, buf, PAGE_SIZE, 2); - drm_printf(p, "Wakeref x%lu taken at:\n%s", rep, buf); - } - - kfree(buf); -} - -static noinline void -__untrack_all_wakerefs(struct intel_runtime_pm_debug *debug, - struct intel_runtime_pm_debug *saved) -{ - *saved = *debug; - - debug->owners = NULL; - debug->count = 0; - debug->last_release = __save_depot_stack(); -} - -static void -dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug) -{ - if (debug->count) { - struct drm_printer p = drm_debug_printer("i915"); - - __print_intel_runtime_pm_wakeref(&p, debug); - } - - kfree(debug->owners); + ref_tracker_dir_exit(&rpm->debug); } static noinline void __intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm) { - struct intel_runtime_pm_debug dbg = {}; unsigned long flags; if (!atomic_dec_and_lock_irqsave(&rpm->wakeref_count, @@ -235,60 +90,14 @@ __intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm) flags)) return; - __untrack_all_wakerefs(&rpm->debug, &dbg); + ref_tracker_dir_print_locked(&rpm->debug, INTEL_REFTRACK_PRINT_LIMIT); spin_unlock_irqrestore(&rpm->debug.lock, flags); - - dump_and_free_wakeref_tracking(&dbg); -} - -static noinline void -untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm) -{ - struct intel_runtime_pm_debug dbg = {}; - unsigned long flags; - - spin_lock_irqsave(&rpm->debug.lock, flags); - __untrack_all_wakerefs(&rpm->debug, &dbg); - spin_unlock_irqrestore(&rpm->debug.lock, flags); - - dump_and_free_wakeref_tracking(&dbg); } void print_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, struct drm_printer *p) { - struct intel_runtime_pm_debug dbg = {}; - - do { - unsigned long alloc = dbg.count; - depot_stack_handle_t *s; - - spin_lock_irq(&rpm->debug.lock); - dbg.count = rpm->debug.count; - if (dbg.count <= alloc) { - memcpy(dbg.owners, - rpm->debug.owners, - dbg.count * sizeof(*s)); - } - dbg.last_acquire = rpm->debug.last_acquire; - dbg.last_release = rpm->debug.last_release; - spin_unlock_irq(&rpm->debug.lock); - if (dbg.count <= alloc) - break; - - s = krealloc(dbg.owners, - dbg.count * sizeof(*s), - GFP_NOWAIT | __GFP_NOWARN); - if (!s) - goto out; - - dbg.owners = s; - } while (1); - - __print_intel_runtime_pm_wakeref(p, &dbg); - -out: - kfree(dbg.owners); + intel_ref_tracker_show(&rpm->debug, p); } #else @@ -297,14 +106,14 @@ static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { } -static depot_stack_handle_t +static intel_wakeref_t track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { return -1; } static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, - intel_wakeref_t wref) + intel_wakeref_t wakeref) { } @@ -639,7 +448,11 @@ void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm) "i915 raw-wakerefs=%d wakelocks=%d on cleanup\n", intel_rpm_raw_wakeref_count(count), intel_rpm_wakelock_count(count)); +} +void intel_runtime_pm_driver_last_release(struct intel_runtime_pm *rpm) +{ + intel_runtime_pm_driver_release(rpm); untrack_all_intel_runtime_pm_wakerefs(rpm); } diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index 764b183ae4529..8c2251b2174ae 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -77,15 +77,7 @@ struct intel_runtime_pm { * paired rpm_put) we can remove corresponding pairs of and keep * the array trimmed to active wakerefs. */ - struct intel_runtime_pm_debug { - spinlock_t lock; - - depot_stack_handle_t last_acquire; - depot_stack_handle_t last_release; - - depot_stack_handle_t *owners; - unsigned long count; - } debug; + struct ref_tracker_dir debug; #endif }; @@ -189,6 +181,7 @@ void intel_runtime_pm_init_early(struct intel_runtime_pm *rpm); void intel_runtime_pm_enable(struct intel_runtime_pm *rpm); void intel_runtime_pm_disable(struct intel_runtime_pm *rpm); void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm); +void intel_runtime_pm_driver_last_release(struct intel_runtime_pm *rpm); intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm); intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm); diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c index 623a690893868..2401b88b55a40 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.c +++ b/drivers/gpu/drm/i915/intel_wakeref.c @@ -191,3 +191,31 @@ void intel_wakeref_auto_fini(struct intel_wakeref_auto *wf) intel_wakeref_auto(wf, 0); INTEL_WAKEREF_BUG_ON(wf->wakeref); } + +void intel_ref_tracker_show(struct ref_tracker_dir *dir, + struct drm_printer *p) +{ + const size_t buf_size = PAGE_SIZE; + char *buf, *sb, *se; + size_t count; + + buf = kmalloc(buf_size, GFP_NOWAIT); + if (!buf) + return; + + count = ref_tracker_dir_snprint(dir, buf, buf_size); + if (!count) + goto free; + /* printk does not like big buffers, so we split it */ + for (sb = buf; *sb; sb = se + 1) { + se = strchrnul(sb, '\n'); + drm_printf(p, "%.*s", (int)(se - sb + 1), sb); + if (!*se) + break; + } + if (count >= buf_size) + drm_printf(p, "\n...dropped %zd extra bytes of leak report.\n", + count + 1 - buf_size); +free: + kfree(buf); +} diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index ec881b0973689..909cad13ac1f7 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -7,16 +7,25 @@ #ifndef INTEL_WAKEREF_H #define INTEL_WAKEREF_H +#include + #include #include #include #include #include #include +#include +#include #include #include #include +typedef unsigned long intel_wakeref_t; + +#define INTEL_REFTRACK_DEAD_COUNT 16 +#define INTEL_REFTRACK_PRINT_LIMIT 16 + #if IS_ENABLED(CONFIG_DRM_I915_DEBUG) #define INTEL_WAKEREF_BUG_ON(expr) BUG_ON(expr) #else @@ -26,8 +35,6 @@ struct intel_runtime_pm; struct intel_wakeref; -typedef depot_stack_handle_t intel_wakeref_t; - struct intel_wakeref_ops { int (*get)(struct intel_wakeref *wf); int (*put)(struct intel_wakeref *wf); @@ -261,6 +268,30 @@ __intel_wakeref_defer_park(struct intel_wakeref *wf) */ int intel_wakeref_wait_for_idle(struct intel_wakeref *wf); +#define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1)) + +static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *dir) +{ + struct ref_tracker *user = NULL; + + ref_tracker_alloc(dir, &user, GFP_NOWAIT); + + return (intel_wakeref_t)user ?: INTEL_WAKEREF_DEF; +} + +static inline void intel_ref_tracker_free(struct ref_tracker_dir *dir, + intel_wakeref_t handle) +{ + struct ref_tracker *user; + + user = (handle == INTEL_WAKEREF_DEF) ? NULL : (void *)handle; + + ref_tracker_free(dir, &user); +} + +void intel_ref_tracker_show(struct ref_tracker_dir *dir, + struct drm_printer *p); + struct intel_wakeref_auto { struct drm_i915_private *i915; struct timer_list timer; -- GitLab From 494df4997d2db37ee07d5ef362f47b92be893372 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 30 Oct 2023 18:40:13 +0100 Subject: [PATCH 154/456] BACKPORT: drm/i915: Track gt pm wakerefs Track every intel_gt_pm_get() until its corresponding release in intel_gt_pm_put() by returning a cookie to the caller for acquire that must be passed by on released. When there is an imbalance, we can see who either tried to free a stale wakeref, or who forgot to free theirs. v2: track recently added calls in gen8_ggtt_bind_get_ce and destroyed_worker_func BUG=b:361021804 TEST=No kernel panic issue, no auto reboot issue while running webfish test Change-Id: Icab9ba2ac0dbb050d61403a1c1da2867702b3db5 Signed-off-by: Andrzej Hajda Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20231030-ref_tracker_i915-v1-2-006fe6b96421@intel.com (cherry picked from commit 5e4e06e4087eb91b0e5405ed42e792415d055e45) Signed-off-by: Shinni Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6002404 Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/Kconfig.debug | 14 +++++++ .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 14 ++++--- .../i915/gem/selftests/i915_gem_coherency.c | 10 +++-- .../drm/i915/gem/selftests/i915_gem_mman.c | 14 ++++--- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 13 +++++-- .../gpu/drm/i915/gt/intel_breadcrumbs_types.h | 3 +- drivers/gpu/drm/i915/gt/intel_context.h | 4 +- drivers/gpu/drm/i915/gt/intel_context_types.h | 2 + drivers/gpu/drm/i915/gt/intel_engine_pm.c | 7 ++-- drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 + .../drm/i915/gt/intel_execlists_submission.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 16 ++++---- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 12 +++--- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 38 ++++++++++++++----- drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c | 4 +- drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 20 ++++++---- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 5 ++- drivers/gpu/drm/i915/gt/selftest_reset.c | 10 +++-- drivers/gpu/drm/i915/gt/selftest_rps.c | 17 +++++---- drivers/gpu/drm/i915/gt/selftest_slpc.c | 5 ++- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 ++++--- drivers/gpu/drm/i915/i915_pmu.c | 16 ++++---- drivers/gpu/drm/i915/intel_wakeref.c | 7 +++- drivers/gpu/drm/i915/intel_wakeref.h | 38 +++++++++++++++++-- 24 files changed, 197 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 4dc85e5371785..9d36c2a4535ea 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -58,6 +58,7 @@ config DRM_I915_DEBUG select DRM_I915_DEBUG_GEM_ONCE select DRM_I915_DEBUG_MMIO select DRM_I915_DEBUG_RUNTIME_PM + select DRM_I915_DEBUG_WAKEREF select DRM_I915_SW_FENCE_DEBUG_OBJECTS select DRM_I915_SELFTEST default n @@ -262,3 +263,16 @@ config DRM_I915_DEBUG_RUNTIME_PM Recommended for driver developers only. If in doubt, say "N" + +config DRM_I915_DEBUG_WAKEREF + bool "Enable extra tracking for wakerefs" + depends on DRM_I915 + select REF_TRACKER + select STACKDEPOT + select STACKTRACE + help + Choose this option to turn on extra state checking and usage + tracking for the wakerefPM functionality. This may introduce + overhead during driver runtime. + + If in doubt, say "N" diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index f94357d0a4fa2..e611480abfe77 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -253,6 +253,8 @@ struct i915_execbuffer { struct intel_gt *gt; /* gt for the execbuf */ struct intel_context *context; /* logical state for the request */ struct i915_gem_context *gem_context; /** caller's context */ + intel_wakeref_t wakeref; + intel_wakeref_t wakeref_gt0; /** our requests to build */ struct i915_request *requests[MAX_ENGINE_INSTANCE + 1]; @@ -2711,13 +2713,13 @@ eb_select_engine(struct i915_execbuffer *eb) for_each_child(ce, child) intel_context_get(child); - intel_gt_pm_get(gt); + eb->wakeref = intel_gt_pm_get(ce->engine->gt); /* * Keep GT0 active on MTL so that i915_vma_parked() doesn't * free VMAs while execbuf ioctl is validating VMAs. */ if (gt->info.id) - intel_gt_pm_get(to_gt(gt->i915)); + eb->wakeref_gt0 = intel_gt_pm_get(to_gt(gt->i915)); if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { err = intel_context_alloc_state(ce); @@ -2757,9 +2759,9 @@ eb_select_engine(struct i915_execbuffer *eb) err: if (gt->info.id) - intel_gt_pm_put(to_gt(gt->i915)); + intel_gt_pm_put(to_gt(gt->i915), eb->wakeref_gt0); - intel_gt_pm_put(gt); + intel_gt_pm_put(ce->engine->gt, eb->wakeref); for_each_child(ce, child) intel_context_put(child); intel_context_put(ce); @@ -2777,8 +2779,8 @@ eb_put_engine(struct i915_execbuffer *eb) * i915_vma_parked() from interfering while execbuf validates vmas. */ if (eb->gt->info.id) - intel_gt_pm_put(to_gt(eb->gt->i915)); - intel_gt_pm_put(eb->gt); + intel_gt_pm_put(to_gt(eb->gt->i915), eb->wakeref_gt0); + intel_gt_pm_put(eb->context->engine->gt, eb->wakeref); for_each_child(eb->context, child) intel_context_put(child); intel_context_put(eb->context); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c index beeb3e12ecccc..2a0c0634d446e 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c @@ -81,6 +81,7 @@ out: static int gtt_set(struct context *ctx, unsigned long offset, u32 v) { + intel_wakeref_t wakeref; struct i915_vma *vma; u32 __iomem *map; int err = 0; @@ -95,7 +96,7 @@ static int gtt_set(struct context *ctx, unsigned long offset, u32 v) if (IS_ERR(vma)) return PTR_ERR(vma); - intel_gt_pm_get(vma->vm->gt); + wakeref = intel_gt_pm_get(vma->vm->gt); map = i915_vma_pin_iomap(vma); i915_vma_unpin(vma); @@ -108,12 +109,13 @@ static int gtt_set(struct context *ctx, unsigned long offset, u32 v) i915_vma_unpin_iomap(vma); out_rpm: - intel_gt_pm_put(vma->vm->gt); + intel_gt_pm_put(vma->vm->gt, wakeref); return err; } static int gtt_get(struct context *ctx, unsigned long offset, u32 *v) { + intel_wakeref_t wakeref; struct i915_vma *vma; u32 __iomem *map; int err = 0; @@ -128,7 +130,7 @@ static int gtt_get(struct context *ctx, unsigned long offset, u32 *v) if (IS_ERR(vma)) return PTR_ERR(vma); - intel_gt_pm_get(vma->vm->gt); + wakeref = intel_gt_pm_get(vma->vm->gt); map = i915_vma_pin_iomap(vma); i915_vma_unpin(vma); @@ -141,7 +143,7 @@ static int gtt_get(struct context *ctx, unsigned long offset, u32 *v) i915_vma_unpin_iomap(vma); out_rpm: - intel_gt_pm_put(vma->vm->gt); + intel_gt_pm_put(vma->vm->gt, wakeref); return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 306defba17b52..99a9ade739562 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -630,14 +630,14 @@ static bool assert_mmap_offset(struct drm_i915_private *i915, static void disable_retire_worker(struct drm_i915_private *i915) { i915_gem_driver_unregister__shrinker(i915); - intel_gt_pm_get(to_gt(i915)); + intel_gt_pm_get_untracked(to_gt(i915)); cancel_delayed_work_sync(&to_gt(i915)->requests.retire_work); } static void restore_retire_worker(struct drm_i915_private *i915) { igt_flush_test(i915); - intel_gt_pm_put(to_gt(i915)); + intel_gt_pm_put_untracked(to_gt(i915)); i915_gem_driver_register__shrinker(i915); } @@ -778,6 +778,7 @@ err_obj: static int gtt_set(struct drm_i915_gem_object *obj) { + intel_wakeref_t wakeref; struct i915_vma *vma; void __iomem *map; int err = 0; @@ -786,7 +787,7 @@ static int gtt_set(struct drm_i915_gem_object *obj) if (IS_ERR(vma)) return PTR_ERR(vma); - intel_gt_pm_get(vma->vm->gt); + wakeref = intel_gt_pm_get(vma->vm->gt); map = i915_vma_pin_iomap(vma); i915_vma_unpin(vma); if (IS_ERR(map)) { @@ -798,12 +799,13 @@ static int gtt_set(struct drm_i915_gem_object *obj) i915_vma_unpin_iomap(vma); out: - intel_gt_pm_put(vma->vm->gt); + intel_gt_pm_put(vma->vm->gt, wakeref); return err; } static int gtt_check(struct drm_i915_gem_object *obj) { + intel_wakeref_t wakeref; struct i915_vma *vma; void __iomem *map; int err = 0; @@ -812,7 +814,7 @@ static int gtt_check(struct drm_i915_gem_object *obj) if (IS_ERR(vma)) return PTR_ERR(vma); - intel_gt_pm_get(vma->vm->gt); + wakeref = intel_gt_pm_get(vma->vm->gt); map = i915_vma_pin_iomap(vma); i915_vma_unpin(vma); if (IS_ERR(map)) { @@ -828,7 +830,7 @@ static int gtt_check(struct drm_i915_gem_object *obj) i915_vma_unpin_iomap(vma); out: - intel_gt_pm_put(vma->vm->gt); + intel_gt_pm_put(vma->vm->gt, wakeref); return err; } diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index f2973cd1a8aae..20b9b04ec1e0b 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -28,11 +28,14 @@ static void irq_disable(struct intel_breadcrumbs *b) static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) { + intel_wakeref_t wakeref; + /* * Since we are waiting on a request, the GPU should be busy * and should have its own rpm reference. */ - if (GEM_WARN_ON(!intel_gt_pm_get_if_awake(b->irq_engine->gt))) + wakeref = intel_gt_pm_get_if_awake(b->irq_engine->gt); + if (GEM_WARN_ON(!wakeref)) return; /* @@ -41,7 +44,7 @@ static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) * which we can add a new waiter and avoid the cost of re-enabling * the irq. */ - WRITE_ONCE(b->irq_armed, true); + WRITE_ONCE(b->irq_armed, wakeref); /* Requests may have completed before we could enable the interrupt. */ if (!b->irq_enabled++ && b->irq_enable(b)) @@ -61,12 +64,14 @@ static void intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) { + intel_wakeref_t wakeref = b->irq_armed; + GEM_BUG_ON(!b->irq_enabled); if (!--b->irq_enabled) b->irq_disable(b); - WRITE_ONCE(b->irq_armed, false); - intel_gt_pm_put_async(b->irq_engine->gt); + WRITE_ONCE(b->irq_armed, 0); + intel_gt_pm_put_async(b->irq_engine->gt, wakeref); } static void intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h index 72dfd3748c4c3..bdf09fd67b6e7 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h @@ -13,6 +13,7 @@ #include #include "intel_engine_types.h" +#include "intel_wakeref.h" /* * Rather than have every client wait upon all user interrupts, @@ -43,7 +44,7 @@ struct intel_breadcrumbs { spinlock_t irq_lock; /* protects the interrupt from hardirq context */ struct irq_work irq_work; /* for use from inside irq_lock */ unsigned int irq_enabled; - bool irq_armed; + intel_wakeref_t irq_armed; /* Not all breadcrumbs are attached to physical HW */ intel_engine_mask_t engine_mask; diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index 57caf9eacf223..9f523999acd1b 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -212,7 +212,7 @@ static inline void intel_context_enter(struct intel_context *ce) return; ce->ops->enter(ce); - intel_gt_pm_get(ce->vm->gt); + ce->wakeref = intel_gt_pm_get(ce->vm->gt); } static inline void intel_context_mark_active(struct intel_context *ce) @@ -229,7 +229,7 @@ static inline void intel_context_exit(struct intel_context *ce) if (--ce->active_count) return; - intel_gt_pm_put_async(ce->vm->gt); + intel_gt_pm_put_async(ce->vm->gt, ce->wakeref); ce->ops->exit(ce); } diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 97b9ac8aca105..98c7f6052069c 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -17,6 +17,7 @@ #include "i915_utils.h" #include "intel_engine_types.h" #include "intel_sseu.h" +#include "intel_wakeref.h" #include "uc/intel_guc_fwif.h" @@ -114,6 +115,7 @@ struct intel_context { u32 ring_size; struct intel_ring *ring; struct intel_timeline *timeline; + intel_wakeref_t wakeref; unsigned long flags; #define CONTEXT_BARRIER_BIT 0 diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c index 5a3a5b29d1507..fb7bff27b45a3 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c @@ -63,7 +63,7 @@ static int __engine_unpark(struct intel_wakeref *wf) ENGINE_TRACE(engine, "\n"); - intel_gt_pm_get(engine->gt); + engine->wakeref_track = intel_gt_pm_get(engine->gt); /* Discard stale context state from across idling */ ce = engine->kernel_context; @@ -122,6 +122,7 @@ __queue_and_release_pm(struct i915_request *rq, */ GEM_BUG_ON(rq->context->active_count != 1); __intel_gt_pm_get(engine->gt); + rq->context->wakeref = intel_wakeref_track(&engine->gt->wakeref); /* * We have to serialise all potential retirement paths with our @@ -282,7 +283,7 @@ static int __engine_park(struct intel_wakeref *wf) engine->park(engine); /* While gt calls i915_vma_parked(), we have to break the lock cycle */ - intel_gt_pm_put_async(engine->gt); + intel_gt_pm_put_async(engine->gt, engine->wakeref_track); return 0; } @@ -293,7 +294,7 @@ static const struct intel_wakeref_ops wf_ops = { void intel_engine_init__pm(struct intel_engine_cs *engine) { - intel_wakeref_init(&engine->wakeref, engine->i915, &wf_ops); + intel_wakeref_init(&engine->wakeref, engine->i915, &wf_ops, engine->name); intel_engine_init_heartbeat(engine); intel_gsc_idle_msg_enable(engine); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index c6320a06db442..a49fc1babd948 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -443,7 +443,9 @@ struct intel_engine_cs { unsigned long serial; unsigned long wakeref_serial; + intel_wakeref_t wakeref_track; struct intel_wakeref wakeref; + struct file *default_state; struct { diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 2065be5a196bf..439d48a65711e 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -630,7 +630,7 @@ static void __execlists_schedule_out(struct i915_request * const rq, execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); if (engine->fw_domain && !--engine->fw_active) intel_uncore_forcewake_put(engine->uncore, engine->fw_domain); - intel_gt_pm_put_async(engine->gt); + intel_gt_pm_put_async_untracked(engine->gt); /* * If this is part of a virtual engine, its next request may diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 9aafce22f14eb..da8d0fa22b4f0 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -301,7 +301,7 @@ static bool should_update_ggtt_with_bind(struct i915_ggtt *ggtt) return intel_gt_is_bind_context_ready(gt); } -static struct intel_context *gen8_ggtt_bind_get_ce(struct i915_ggtt *ggtt) +static struct intel_context *gen8_ggtt_bind_get_ce(struct i915_ggtt *ggtt, intel_wakeref_t *wakeref) { struct intel_context *ce; struct intel_gt *gt = ggtt->vm.gt; @@ -318,7 +318,8 @@ static struct intel_context *gen8_ggtt_bind_get_ce(struct i915_ggtt *ggtt) * would conflict with fs_reclaim trying to allocate memory while * doing rpm_resume(). */ - if (!intel_gt_pm_get_if_awake(gt)) + *wakeref = intel_gt_pm_get_if_awake(gt); + if (!*wakeref) return NULL; intel_engine_pm_get(ce->engine); @@ -326,10 +327,10 @@ static struct intel_context *gen8_ggtt_bind_get_ce(struct i915_ggtt *ggtt) return ce; } -static void gen8_ggtt_bind_put_ce(struct intel_context *ce) +static void gen8_ggtt_bind_put_ce(struct intel_context *ce, intel_wakeref_t wakeref) { intel_engine_pm_put(ce->engine); - intel_gt_pm_put(ce->engine->gt); + intel_gt_pm_put(ce->engine->gt, wakeref); } static bool gen8_ggtt_bind_ptes(struct i915_ggtt *ggtt, u32 offset, @@ -342,12 +343,13 @@ static bool gen8_ggtt_bind_ptes(struct i915_ggtt *ggtt, u32 offset, struct sgt_iter iter; struct i915_request *rq; struct intel_context *ce; + intel_wakeref_t wakeref; u32 *cs; if (!num_entries) return true; - ce = gen8_ggtt_bind_get_ce(ggtt); + ce = gen8_ggtt_bind_get_ce(ggtt, &wakeref); if (!ce) return false; @@ -423,13 +425,13 @@ queue_err_rq: offset += n_ptes; } - gen8_ggtt_bind_put_ce(ce); + gen8_ggtt_bind_put_ce(ce, wakeref); return true; err_rq: i915_request_put(rq); put_ce: - gen8_ggtt_bind_put_ce(ce); + gen8_ggtt_bind_put_ce(ce, wakeref); return false; } diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index f5899d503e234..4e38d666fe703 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -28,19 +28,20 @@ static void user_forcewake(struct intel_gt *gt, bool suspend) { int count = atomic_read(>->user_wakeref); + intel_wakeref_t wakeref; /* Inside suspend/resume so single threaded, no races to worry about. */ if (likely(!count)) return; - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); if (suspend) { GEM_BUG_ON(count > atomic_read(>->wakeref.count)); atomic_sub(count, >->wakeref.count); } else { atomic_add(count, >->wakeref.count); } - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); } static void runtime_begin(struct intel_gt *gt) @@ -138,7 +139,7 @@ void intel_gt_pm_init_early(struct intel_gt *gt) * runtime_pm is per-device rather than per-tile, so this is still the * correct structure. */ - intel_wakeref_init(>->wakeref, gt->i915, &wf_ops); + intel_wakeref_init(>->wakeref, gt->i915, &wf_ops, "GT"); seqcount_mutex_init(>->stats.lock, >->wakeref.mutex); } @@ -236,6 +237,7 @@ int intel_gt_resume(struct intel_gt *gt) { struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; int err; err = intel_gt_has_unrecoverable_error(gt); @@ -252,7 +254,7 @@ int intel_gt_resume(struct intel_gt *gt) */ gt_sanitize(gt, true); - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL); intel_rc6_sanitize(>->rc6); @@ -295,7 +297,7 @@ int intel_gt_resume(struct intel_gt *gt) out_fw: intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); intel_gt_bind_context_set_ready(gt); return err; diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index b1eeb5b33918c..911fd0160221b 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -16,19 +16,28 @@ static inline bool intel_gt_pm_is_awake(const struct intel_gt *gt) return intel_wakeref_is_active(>->wakeref); } -static inline void intel_gt_pm_get(struct intel_gt *gt) +static inline void intel_gt_pm_get_untracked(struct intel_gt *gt) { intel_wakeref_get(>->wakeref); } +static inline intel_wakeref_t intel_gt_pm_get(struct intel_gt *gt) +{ + intel_gt_pm_get_untracked(gt); + return intel_wakeref_track(>->wakeref); +} + static inline void __intel_gt_pm_get(struct intel_gt *gt) { __intel_wakeref_get(>->wakeref); } -static inline bool intel_gt_pm_get_if_awake(struct intel_gt *gt) +static inline intel_wakeref_t intel_gt_pm_get_if_awake(struct intel_gt *gt) { - return intel_wakeref_get_if_active(>->wakeref); + if (!intel_wakeref_get_if_active(>->wakeref)) + return 0; + + return intel_wakeref_track(>->wakeref); } static inline void intel_gt_pm_might_get(struct intel_gt *gt) @@ -36,12 +45,18 @@ static inline void intel_gt_pm_might_get(struct intel_gt *gt) intel_wakeref_might_get(>->wakeref); } -static inline void intel_gt_pm_put(struct intel_gt *gt) +static inline void intel_gt_pm_put_untracked(struct intel_gt *gt) { intel_wakeref_put(>->wakeref); } -static inline void intel_gt_pm_put_async(struct intel_gt *gt) +static inline void intel_gt_pm_put(struct intel_gt *gt, intel_wakeref_t handle) +{ + intel_wakeref_untrack(>->wakeref, handle); + intel_gt_pm_put_untracked(gt); +} + +static inline void intel_gt_pm_put_async_untracked(struct intel_gt *gt) { intel_wakeref_put_async(>->wakeref); } @@ -51,9 +66,14 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt) intel_wakeref_might_put(>->wakeref); } -#define with_intel_gt_pm(gt, tmp) \ - for (tmp = 1, intel_gt_pm_get(gt); tmp; \ - intel_gt_pm_put(gt), tmp = 0) +static inline void intel_gt_pm_put_async(struct intel_gt *gt, intel_wakeref_t handle) +{ + intel_wakeref_untrack(>->wakeref, handle); + intel_gt_pm_put_async_untracked(gt); +} + +#define with_intel_gt_pm(gt, wf) \ + for (wf = intel_gt_pm_get(gt); wf; intel_gt_pm_put(gt, wf), wf = 0) /** * with_intel_gt_pm_if_awake - if GT is PM awake, get a reference to prevent @@ -64,7 +84,7 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt) * @wf: pointer to a temporary wakeref. */ #define with_intel_gt_pm_if_awake(gt, wf) \ - for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt), wf = 0) + for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt, wf), wf = 0) static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt) { diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c index f900cc68d6d98..7114c116e9284 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c @@ -27,7 +27,7 @@ void intel_gt_pm_debugfs_forcewake_user_open(struct intel_gt *gt) { atomic_inc(>->user_wakeref); - intel_gt_pm_get(gt); + intel_gt_pm_get_untracked(gt); if (GRAPHICS_VER(gt->i915) >= 6) intel_uncore_forcewake_user_get(gt->uncore); } @@ -36,7 +36,7 @@ void intel_gt_pm_debugfs_forcewake_user_release(struct intel_gt *gt) { if (GRAPHICS_VER(gt->i915) >= 6) intel_uncore_forcewake_user_put(gt->uncore); - intel_gt_pm_put(gt); + intel_gt_pm_put_untracked(gt); atomic_dec(>->user_wakeref); } diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c index 86cecf7a11054..5ffa5e30f4192 100644 --- a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c @@ -21,20 +21,22 @@ static int cmp_u32(const void *A, const void *B) return *a - *b; } -static void perf_begin(struct intel_gt *gt) +static intel_wakeref_t perf_begin(struct intel_gt *gt) { - intel_gt_pm_get(gt); + intel_wakeref_t wakeref = intel_gt_pm_get(gt); /* Boost gpufreq to max [waitboost] and keep it fixed */ atomic_inc(>->rps.num_waiters); queue_work(gt->i915->unordered_wq, >->rps.work); flush_work(>->rps.work); + + return wakeref; } -static int perf_end(struct intel_gt *gt) +static int perf_end(struct intel_gt *gt, intel_wakeref_t wakeref) { atomic_dec(>->rps.num_waiters); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); return igt_flush_test(gt->i915); } @@ -133,12 +135,13 @@ static int perf_mi_bb_start(void *arg) struct intel_gt *gt = arg; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; int err = 0; if (GRAPHICS_VER(gt->i915) < 4) /* Any CS_TIMESTAMP? */ return 0; - perf_begin(gt); + wakeref = perf_begin(gt); for_each_engine(engine, gt, id) { struct intel_context *ce = engine->kernel_context; struct i915_vma *batch; @@ -207,7 +210,7 @@ out: pr_info("%s: MI_BB_START cycles: %u\n", engine->name, trifilter(cycles)); } - if (perf_end(gt)) + if (perf_end(gt, wakeref)) err = -EIO; return err; @@ -260,12 +263,13 @@ static int perf_mi_noop(void *arg) struct intel_gt *gt = arg; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; int err = 0; if (GRAPHICS_VER(gt->i915) < 4) /* Any CS_TIMESTAMP? */ return 0; - perf_begin(gt); + wakeref = perf_begin(gt); for_each_engine(engine, gt, id) { struct intel_context *ce = engine->kernel_context; struct i915_vma *base, *nop; @@ -364,7 +368,7 @@ out: pr_info("%s: 16K MI_NOOP cycles: %u\n", engine->name, trifilter(cycles)); } - if (perf_end(gt)) + if (perf_end(gt, wakeref)) err = -EIO; return err; diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c index 0971241707ce8..33351deeea4f0 100644 --- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c @@ -81,6 +81,7 @@ static int live_gt_clocks(void *arg) struct intel_gt *gt = arg; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; int err = 0; if (!gt->clock_frequency) { /* unknown */ @@ -91,7 +92,7 @@ static int live_gt_clocks(void *arg) if (GRAPHICS_VER(gt->i915) < 4) /* Any CS_TIMESTAMP? */ return 0; - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL); for_each_engine(engine, gt, id) { @@ -128,7 +129,7 @@ static int live_gt_clocks(void *arg) } intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_reset.c b/drivers/gpu/drm/i915/gt/selftest_reset.c index 79aa6ac66ad2f..f40de408cd3a9 100644 --- a/drivers/gpu/drm/i915/gt/selftest_reset.c +++ b/drivers/gpu/drm/i915/gt/selftest_reset.c @@ -261,11 +261,12 @@ static int igt_atomic_reset(void *arg) { struct intel_gt *gt = arg; const typeof(*igt_atomic_phases) *p; + intel_wakeref_t wakeref; int err = 0; /* Check that the resets are usable from atomic context */ - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); igt_global_reset_lock(gt); /* Flush any requests before we get started and check basics */ @@ -296,7 +297,7 @@ static int igt_atomic_reset(void *arg) unlock: igt_global_reset_unlock(gt); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); return err; } @@ -307,6 +308,7 @@ static int igt_atomic_engine_reset(void *arg) const typeof(*igt_atomic_phases) *p; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; int err = 0; /* Check that the resets are usable from atomic context */ @@ -317,7 +319,7 @@ static int igt_atomic_engine_reset(void *arg) if (intel_uc_uses_guc_submission(>->uc)) return 0; - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); igt_global_reset_lock(gt); /* Flush any requests before we get started and check basics */ @@ -365,7 +367,7 @@ static int igt_atomic_engine_reset(void *arg) out_unlock: igt_global_reset_unlock(gt); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); return err; } diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c index fb30f733b0366..dcef8d4989197 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rps.c +++ b/drivers/gpu/drm/i915/gt/selftest_rps.c @@ -224,6 +224,7 @@ int live_rps_clock_interval(void *arg) struct intel_engine_cs *engine; enum intel_engine_id id; struct igt_spinner spin; + intel_wakeref_t wakeref; int err = 0; if (!intel_rps_is_enabled(rps) || GRAPHICS_VER(gt->i915) < 6) @@ -236,7 +237,7 @@ int live_rps_clock_interval(void *arg) saved_work = rps->work.func; rps->work.func = dummy_rps_work; - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); intel_rps_disable(>->rps); intel_gt_check_clock_frequency(gt); @@ -355,7 +356,7 @@ int live_rps_clock_interval(void *arg) } intel_rps_enable(>->rps); - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); igt_spinner_fini(&spin); @@ -376,6 +377,7 @@ int live_rps_control(void *arg) struct intel_engine_cs *engine; enum intel_engine_id id; struct igt_spinner spin; + intel_wakeref_t wakeref; int err = 0; /* @@ -398,7 +400,7 @@ int live_rps_control(void *arg) saved_work = rps->work.func; rps->work.func = dummy_rps_work; - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); for_each_engine(engine, gt, id) { struct i915_request *rq; ktime_t min_dt, max_dt; @@ -488,7 +490,7 @@ int live_rps_control(void *arg) break; } } - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); igt_spinner_fini(&spin); @@ -1023,6 +1025,7 @@ int live_rps_interrupt(void *arg) struct intel_engine_cs *engine; enum intel_engine_id id; struct igt_spinner spin; + intel_wakeref_t wakeref; u32 pm_events; int err = 0; @@ -1033,9 +1036,9 @@ int live_rps_interrupt(void *arg) if (!intel_rps_has_interrupts(rps) || GRAPHICS_VER(gt->i915) < 6) return 0; - intel_gt_pm_get(gt); - pm_events = rps->pm_events; - intel_gt_pm_put(gt); + pm_events = 0; + with_intel_gt_pm(gt, wakeref) + pm_events = rps->pm_events; if (!pm_events) { pr_err("No RPS PM events registered, but RPS is enabled?\n"); return -ENODEV; diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c b/drivers/gpu/drm/i915/gt/selftest_slpc.c index 952c8d52d68a2..302d0540295d7 100644 --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c @@ -266,6 +266,7 @@ static int run_test(struct intel_gt *gt, int test_type) struct intel_rps *rps = >->rps; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; struct igt_spinner spin; u32 slpc_min_freq, slpc_max_freq; int err = 0; @@ -311,7 +312,7 @@ static int run_test(struct intel_gt *gt, int test_type) } intel_gt_pm_wait_for_idle(gt); - intel_gt_pm_get(gt); + wakeref = intel_gt_pm_get(gt); for_each_engine(engine, gt, id) { struct i915_request *rq; u32 max_act_freq; @@ -397,7 +398,7 @@ static int run_test(struct intel_gt *gt, int test_type) if (igt_flush_test(gt->i915)) err = -EIO; - intel_gt_pm_put(gt); + intel_gt_pm_put(gt, wakeref); igt_spinner_fini(&spin); intel_gt_pm_wait_for_idle(gt); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index e7ed118da63b4..8864334e31ac4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1120,7 +1120,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct intel_guc *guc) if (deregister) guc_signal_context_fence(ce); if (destroyed) { - intel_gt_pm_put_async(guc_to_gt(guc)); + intel_gt_pm_put_async_untracked(guc_to_gt(guc)); release_guc_id(guc, ce); __guc_context_destroy(ce); } @@ -1331,6 +1331,7 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now) unsigned long flags; u32 reset_count; bool in_reset; + intel_wakeref_t wakeref; spin_lock_irqsave(&guc->timestamp.lock, flags); @@ -1353,7 +1354,8 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now) * start_gt_clk is derived from GuC state. To get a consistent * view of activity, we query the GuC state only if gt is awake. */ - if (!in_reset && intel_gt_pm_get_if_awake(gt)) { + wakeref = in_reset ? 0 : intel_gt_pm_get_if_awake(gt); + if (wakeref) { stats_saved = *stats; gt_stamp_saved = guc->timestamp.gt_stamp; /* @@ -1362,7 +1364,7 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now) */ guc_update_engine_gt_clks(engine); guc_update_pm_timestamp(guc, now); - intel_gt_pm_put_async(gt); + intel_gt_pm_put_async(gt, wakeref); if (i915_reset_count(gpu_error) != reset_count) { *stats = stats_saved; guc->timestamp.gt_stamp = gt_stamp_saved; @@ -3485,7 +3487,7 @@ static void destroyed_worker_func(struct work_struct *w) struct intel_guc *guc = container_of(w, struct intel_guc, submission_state.destroyed_worker); struct intel_gt *gt = guc_to_gt(guc); - int tmp; + intel_wakeref_t wakeref; /* * In rare cases we can get here via async context-free fence-signals that @@ -3498,7 +3500,7 @@ static void destroyed_worker_func(struct work_struct *w) if (!intel_guc_is_ready(guc)) return; - with_intel_gt_pm(gt, tmp) + with_intel_gt_pm(gt, wakeref) deregister_destroyed_contexts(guc); } @@ -5005,7 +5007,7 @@ int intel_guc_deregister_done_process_msg(struct intel_guc *guc, intel_context_put(ce); } else if (context_destroyed(ce)) { /* Context has been destroyed */ - intel_gt_pm_put_async(guc_to_gt(guc)); + intel_gt_pm_put_async_untracked(guc_to_gt(guc)); release_guc_id(guc, ce); __guc_context_destroy(ce); } diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 7b1076b5e748c..334451f66a145 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -213,19 +213,19 @@ static u64 get_rc6(struct intel_gt *gt) struct drm_i915_private *i915 = gt->i915; const unsigned int gt_id = gt->info.id; struct i915_pmu *pmu = &i915->pmu; + intel_wakeref_t wakeref; unsigned long flags; - bool awake = false; u64 val; - if (intel_gt_pm_get_if_awake(gt)) { + wakeref = intel_gt_pm_get_if_awake(gt); + if (wakeref) { val = __get_rc6(gt); - intel_gt_pm_put_async(gt); - awake = true; + intel_gt_pm_put_async(gt, wakeref); } spin_lock_irqsave(&pmu->lock, flags); - if (awake) { + if (wakeref) { store_sample(pmu, gt_id, __I915_SAMPLE_RC6, val); } else { /* @@ -429,12 +429,14 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns) const unsigned int gt_id = gt->info.id; struct i915_pmu *pmu = &i915->pmu; struct intel_rps *rps = >->rps; + intel_wakeref_t wakeref; if (!frequency_sampling_enabled(pmu, gt_id)) return; /* Report 0/0 (actual/requested) frequency while parked. */ - if (!intel_gt_pm_get_if_awake(gt)) + wakeref = intel_gt_pm_get_if_awake(gt); + if (!wakeref) return; if (pmu->enable & config_mask(__I915_PMU_ACTUAL_FREQUENCY(gt_id))) { @@ -463,7 +465,7 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns) period_ns / 1000); } - intel_gt_pm_put_async(gt); + intel_gt_pm_put_async(gt, wakeref); } static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer) diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c index 2401b88b55a40..dea2f63184f89 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.c +++ b/drivers/gpu/drm/i915/intel_wakeref.c @@ -99,7 +99,8 @@ static void __intel_wakeref_put_work(struct work_struct *wrk) void __intel_wakeref_init(struct intel_wakeref *wf, struct drm_i915_private *i915, const struct intel_wakeref_ops *ops, - struct intel_wakeref_lockclass *key) + struct intel_wakeref_lockclass *key, + const char *name) { wf->i915 = i915; wf->ops = ops; @@ -111,6 +112,10 @@ void __intel_wakeref_init(struct intel_wakeref *wf, INIT_DELAYED_WORK(&wf->work, __intel_wakeref_put_work); lockdep_init_map(&wf->work.work.lockdep_map, "wakeref.work", &key->work, 0); + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF) + ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, name); +#endif } int intel_wakeref_wait_for_idle(struct intel_wakeref *wf) diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index 909cad13ac1f7..68aa3be482515 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -50,6 +50,10 @@ struct intel_wakeref { const struct intel_wakeref_ops *ops; struct delayed_work work; + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF) + struct ref_tracker_dir debug; +#endif }; struct intel_wakeref_lockclass { @@ -60,11 +64,12 @@ struct intel_wakeref_lockclass { void __intel_wakeref_init(struct intel_wakeref *wf, struct drm_i915_private *i915, const struct intel_wakeref_ops *ops, - struct intel_wakeref_lockclass *key); -#define intel_wakeref_init(wf, i915, ops) do { \ + struct intel_wakeref_lockclass *key, + const char *name); +#define intel_wakeref_init(wf, i915, ops, name) do { \ static struct intel_wakeref_lockclass __key; \ \ - __intel_wakeref_init((wf), (i915), (ops), &__key); \ + __intel_wakeref_init((wf), (i915), (ops), &__key, name); \ } while (0) int __intel_wakeref_get_first(struct intel_wakeref *wf); @@ -292,6 +297,33 @@ static inline void intel_ref_tracker_free(struct ref_tracker_dir *dir, void intel_ref_tracker_show(struct ref_tracker_dir *dir, struct drm_printer *p); +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF) + +static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf) +{ + return intel_ref_tracker_alloc(&wf->debug); +} + +static inline void intel_wakeref_untrack(struct intel_wakeref *wf, + intel_wakeref_t handle) +{ + intel_ref_tracker_free(&wf->debug, handle); +} + +#else + +static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf) +{ + return -1; +} + +static inline void intel_wakeref_untrack(struct intel_wakeref *wf, + intel_wakeref_t handle) +{ +} + +#endif + struct intel_wakeref_auto { struct drm_i915_private *i915; struct timer_list timer; -- GitLab From 5a1c19ad7755c61dbd5132e1ac7db68148afe893 Mon Sep 17 00:00:00 2001 From: Shinni Tsai Date: Wed, 11 Dec 2024 20:52:52 +0800 Subject: [PATCH 155/456] FIXUP: drm/i915/vma: Fix UAF on destroy against retire race BUG=b:361021804 TEST=No kernel panic issue, no auto reboot issue while running webfish test Fix the difference between the stable merge commit 5e3eb862df9f9 drm/i915/vma: Fix UAF on destroy against retire race and original commit 0e45882ca829b drm/i915/vma: Fix UAF on destroy against retire race. Change-Id: Ic531d6a999206e19256a5ca68850889ac072abd2 Signed-off-by: Shinni Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088243 Reviewed-by: Drew Davenport Reviewed-by: Shyam Sundar Radjacoumar Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/i915_vma.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 3290d399b730d..bca9954026bdd 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -113,9 +113,16 @@ static int __i915_vma_active(struct i915_active *ref) * Exclude global GTT VMA from holding a GT wakeref * while active, otherwise GPU never goes idle. */ - if (!i915_vma_is_ggtt(vma)) - intel_gt_pm_get(vma->vm->gt); - + if (!i915_vma_is_ggtt(vma)) { + /* + * Since we and our _retire() counterpart can be + * called asynchronously, storing a wakeref tracking + * handle inside struct i915_vma is not safe, and + * there is no other good place for that. Hence, + * use untracked variants of intel_gt_pm_get/put(). + */ + intel_gt_pm_get_untracked(vma->vm->gt); + } return 0; } @@ -128,7 +135,7 @@ static void __i915_vma_retire(struct i915_active *ref) * Since we can be called from atomic contexts, * use an async variant of intel_gt_pm_put(). */ - intel_gt_pm_put_async(vma->vm->gt); + intel_gt_pm_put_async_untracked(vma->vm->gt); } i915_vma_put(vma); -- GitLab From 59ee6aeb31bd999e6d32a1d197967c451f9a55ec Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 11 Dec 2024 19:01:39 +0800 Subject: [PATCH 156/456] UPSTREAM: Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925 Add HW IDs for wireless module specific to Acer/ASUS notebook models to ensure proper recognition and functionality. These HW IDs are extracted from Windows driver inf file. Note some HW IDs without official drivers, still in testing phase. Thus, we update module HW ID and test ensure consistent boot success. Signed-off-by: Jiande Lu Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit 129d329286f624b0ccd66e904a2c27eb4d5196e5 https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master) BUG=b:383474120 TEST=Build pass, MT7925 power on pass on Rauru Change-Id: Ic85d899f596e0a5e3856873f72a9cd5b6dd176fb Signed-off-by: Chris Lu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088711 Reviewed-by: Fei Shao Reviewed-by: Hsin-chen Chuang Commit-Queue: Fei Shao Reviewed-by: Sean Paul Kcr-patch: 30360133c24e600505744682d7d66332665b5f7989476cc8f90c9aa7.patch Signed-off-by: Hubert Mazur --- drivers/bluetooth/btusb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ad974bc54efd0..c0ad8b910066d 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -646,9 +646,6 @@ static const struct usb_device_id quirks_table[] = { { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, { USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, -- GitLab From 02a899adc4225224063bed8b073b7aeb78e7623b Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 11 Dec 2024 19:08:49 +0800 Subject: [PATCH 157/456] BACKPORT: Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925 Add VID 0489 & PID e111 for MediaTek MT7925 USB Bluetooth chip. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=02 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e111 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Signed-off-by: Hao Qin Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit faa5fd605d2081b6c9fa2355b59582d4ccd24b16 https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master) BUG=b:383474120 TEST=Build pass, MT7925 power on pass on Rauru Backport Notes: BTUSB_VALID_LE_STATES was removed in the latest Kernel driver. Change-Id: I9843e388729ac666e00be51f9e7f70fa385b1df4 Signed-off-by: Chris Lu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6088712 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Hsin-chen Chuang Kcr-patch: 63485b2c62fc4828a24be8759409049a02c319d9c05a4726090fde29.patch Signed-off-by: Hubert Mazur --- drivers/bluetooth/btusb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c0ad8b910066d..8b3e43a763210 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -664,7 +664,8 @@ static const struct usb_device_id quirks_table[] = { /* Additional MediaTek MT7925 Bluetooth devices */ { USB_DEVICE(0x0489, 0xe111), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH }, + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, -- GitLab From 4578c0e72a91c663c47d565cda5b21971a459f65 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Fri, 13 Dec 2024 06:24:59 +0000 Subject: [PATCH 158/456] CHROMIUM: arm64: dts: mediatek: mt8188-geralt: Add Mali power models The downstream Mali driver requires that power models be defined for it to do DVFS. These models are not part of the upstream binding. Add them to satisfy the driver. BUG=b:383949399 UPSTREAM-TASK=b:260376782 TEST=Boot up to login screen Change-Id: I15ba5a9ad3e6c7ff3226dba0a58943f7091a4139 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6090739 Reviewed-by: Pin-yen Lin Kcr-patch: ed02c39b6bb88ced3958de7681bdfecda37e6d3ca15b26b2ead9a331.patch Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi index 6bfbd3a58bc24..ee21ff7e924ea 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi @@ -391,6 +391,23 @@ supply-names = "mali"; mali-supply = <&mt6359_vproc2_buck_reg>; status = "okay"; + + /* + * The power models below are not part of the upstream binding + * but are required by the proprietary Mali driver. + */ + power_model@0 { + compatible = "arm,mali-simple-power-model"; + dynamic-coefficient = <4687>; + static-coefficient = <2427750>; + thermal-zone = "soc_max"; + ts = <20000 2000 (-20) 2>; + }; + + power_model@1 { + compatible = "arm,mali-tnax-power-model"; + scale = <5>; + }; }; &i2c0 { -- GitLab From 6d4ebf8ac719b28b352cf1e8aeb133768b4ab0ed Mon Sep 17 00:00:00 2001 From: Manish Mandlik Date: Fri, 13 Dec 2024 09:10:06 -0800 Subject: [PATCH 159/456] Revert "CHROMIUM: Bluetooth: btusb: Read device coredump_disabled flag" This reverts commit e44b7cfad92ad299b70aff4cdae1ba7b814ecfb2. Reason for revert: Feature flag dependency cleanup. BUG=b:359303889, b:384024562 TEST=Verify coredump feature works by writing to sysfs Change-Id: Ic63a28aa14a673c53b7b8a5770a48a0a136f43a8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6093200 Commit-Queue: Manish Mandlik Reviewed-by: Michael Sun Tested-by: Manish Mandlik Signed-off-by: Hubert Mazur --- drivers/bluetooth/btusb.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8b3e43a763210..af45f4a6e3c1e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1893,15 +1893,6 @@ done: kfree_skb(skb); } -#ifdef CONFIG_DEV_COREDUMP -static bool btusb_coredump_enabled(struct hci_dev *hdev) -{ - struct btusb_data *data = hci_get_drvdata(hdev); - - return !data->intf->dev.coredump_disabled; -} -#endif - static int btusb_open(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -3954,9 +3945,6 @@ static int btusb_probe(struct usb_interface *intf, hdev->notify = btusb_notify; hdev->wakeup = btusb_wakeup; hdev->do_wakeup = btusb_do_wakeup; -#ifdef CONFIG_DEV_COREDUMP - hdev->dump.enabled = btusb_coredump_enabled; -#endif #ifdef CONFIG_PM err = btusb_config_oob_wake(hdev); @@ -4426,7 +4414,7 @@ static void btusb_coredump(struct device *dev) struct btusb_data *data = dev_get_drvdata(dev); struct hci_dev *hdev = data->hdev; - if (!dev->coredump_disabled && hdev->dump.coredump) + if (hdev->dump.coredump) hdev->dump.coredump(hdev); } #endif -- GitLab From 5164c6751c637b9fe4b2dfbd2cbc3363943fc24b Mon Sep 17 00:00:00 2001 From: Manish Mandlik Date: Fri, 13 Dec 2024 09:10:18 -0800 Subject: [PATCH 160/456] Revert "CHROMIUM: Bluetooth: Enable coredump with device coredump_disabled flag" This reverts commit 970fd059759b9cd95e37164bcfec0721ebac916a. Reason for revert: Feature flag dependency cleanup. BUG=b:359303889, b:384024562 TEST=Verify coredump feature works by writing to sysfs Change-Id: Ic678a544c7c12e4384cbfa88a9b219f87d13667a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6093201 Tested-by: Manish Mandlik Reviewed-by: Michael Sun Commit-Queue: Manish Mandlik Signed-off-by: Hubert Mazur --- include/net/bluetooth/coredump.h | 5 ----- net/bluetooth/coredump.c | 11 +---------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h index d24b00602ca48..72f51b587a046 100644 --- a/include/net/bluetooth/coredump.h +++ b/include/net/bluetooth/coredump.h @@ -8,7 +8,6 @@ #define DEVCOREDUMP_TIMEOUT msecs_to_jiffies(10000) /* 10 sec */ -typedef bool (*coredump_enabled_t)(struct hci_dev *hdev); typedef void (*coredump_t)(struct hci_dev *hdev); typedef void (*dmp_hdr_t)(struct hci_dev *hdev, struct sk_buff *skb); typedef void (*notify_change_t)(struct hci_dev *hdev, int state); @@ -28,8 +27,6 @@ typedef void (*notify_change_t)(struct hci_dev *hdev, int state); * @dump_rx: Devcoredump state machine work * @dump_timeout: Devcoredump timeout work * - * @enabled: Checks if the devcoredump is enabled for the device - * * @coredump: Called from the driver's .coredump() function. * @dmp_hdr: Create a dump header to identify controller/fw/driver info * @notify_change: Notify driver when devcoredump state has changed @@ -56,8 +53,6 @@ struct hci_devcoredump { struct work_struct dump_rx; struct delayed_work dump_timeout; - coredump_enabled_t enabled; - coredump_t coredump; dmp_hdr_t dmp_hdr; notify_change_t notify_change; diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c index d05135ce635e6..ec97a4bab1c9f 100644 --- a/net/bluetooth/coredump.c +++ b/net/bluetooth/coredump.c @@ -426,16 +426,7 @@ EXPORT_SYMBOL(hci_devcd_register); static inline bool hci_devcd_enabled(struct hci_dev *hdev) { - /* The 'supported' flag is true when the driver registers with the HCI - * devcoredump API, whereas, the 'enabled' is controlled via a sysfs - * entry. For drivers like btusb which supports multiple vendor drivers, - * it is possible that the vendor driver does not support but the - * interface is provided by the base btusb driver. So, check both. - */ - if (hdev->dump.supported && hdev->dump.enabled) - return hdev->dump.enabled(hdev); - - return false; + return hdev->dump.supported; } int hci_devcd_init(struct hci_dev *hdev, u32 dump_size) -- GitLab From f9a61ece293b809106fdf8a2b2fde0929f93c8c5 Mon Sep 17 00:00:00 2001 From: Manish Mandlik Date: Fri, 13 Dec 2024 09:07:28 -0800 Subject: [PATCH 161/456] Revert "FROMLIST: sysfs: Add attribute info for /sys/devices/.../coredump_disabled" This reverts commit 3f8659167b6c4efda78a29bbaee3a49781e4b81d. Reason for revert: Feature flag dependency cleanup. BUG=b:359303889, b:384024562 TEST=Verify coredump feature works by writing to sysfs Change-Id: I39cb2f072417503abc441b217bd440f9deaf7694 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6093202 Reviewed-by: Michael Sun Tested-by: Manish Mandlik Commit-Queue: Manish Mandlik Signed-off-by: Hubert Mazur --- Documentation/ABI/testing/sysfs-devices-coredump | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-coredump b/Documentation/ABI/testing/sysfs-devices-coredump index 4bcfc7dbad673..e459368533a4e 100644 --- a/Documentation/ABI/testing/sysfs-devices-coredump +++ b/Documentation/ABI/testing/sysfs-devices-coredump @@ -8,17 +8,3 @@ Description: file will trigger the .coredump() callback. Available when CONFIG_DEV_COREDUMP is enabled. - -What: /sys/devices/.../coredump_disabled -Date: July 2022 -Contact: Manish Mandlik -Description: - The /sys/devices/.../coredump_disabled attribute can be used by - drivers to selectively enable/disable devcoredump functionality - for a device. The userspace can write 0/1 to it to control - enabling/disabling of devcoredump for that particular device. - This attribute is present only when the device is bound to a - driver which implements the .coredump() callback. The attribute - is readable and writeable. - - Available when CONFIG_DEV_COREDUMP is enabled. -- GitLab From af0c09ac1e3648a15b0be8e6e365c31b8b7766fb Mon Sep 17 00:00:00 2001 From: Manish Mandlik Date: Fri, 13 Dec 2024 09:09:25 -0800 Subject: [PATCH 162/456] Revert "FROMLIST: devcoredump: Add per device sysfs entry to enable/disable coredump" This reverts commit f2968dcf8e7392a4598984fb272118086bdac9a2. Reason for revert: Feature flag dependency cleanup. BUG=b:359303889, b:384024562 TEST=Verify coredump feature works by writing to sysfs Change-Id: I46637a27f9ad094825fef91fe905ecedb02a86f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6093203 Tested-by: Manish Mandlik Reviewed-by: Michael Sun Commit-Queue: Manish Mandlik Signed-off-by: Hubert Mazur --- drivers/base/dd.c | 33 ++------------------------------- drivers/base/devcoredump.c | 2 +- include/linux/device.h | 3 --- 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e06eef7cdfed3..e170d7d809446 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -432,35 +432,6 @@ static ssize_t coredump_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_WO(coredump); -static ssize_t coredump_disabled_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%d\n", dev->coredump_disabled); -} - -static ssize_t coredump_disabled_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - bool disabled; - - if (kstrtobool(buf, &disabled) < 0) - return -EINVAL; - - dev->coredump_disabled = disabled; - - return count; -} -static DEVICE_ATTR_RW(coredump_disabled); - -static struct attribute *dev_coredump_attrs[] = { - &dev_attr_coredump.attr, - &dev_attr_coredump_disabled.attr, - NULL, -}; -ATTRIBUTE_GROUPS(dev_coredump); - static int driver_sysfs_add(struct device *dev) { int ret; @@ -480,7 +451,7 @@ static int driver_sysfs_add(struct device *dev) if (!IS_ENABLED(CONFIG_DEV_COREDUMP) || !dev->driver->coredump) return 0; - ret = device_add_groups(dev, dev_coredump_groups); + ret = device_create_file(dev, &dev_attr_coredump); if (!ret) return 0; @@ -500,7 +471,7 @@ static void driver_sysfs_remove(struct device *dev) if (drv) { if (drv->coredump) - device_remove_groups(dev, dev_coredump_groups); + device_remove_file(dev, &dev_attr_coredump); sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj)); sysfs_remove_link(&dev->kobj, "driver"); } diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 8849c80224069..7e2d1f0d903a6 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -329,7 +329,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, struct devcd_entry *devcd; struct device *existing; - if (devcd_disabled || dev->coredump_disabled) + if (devcd_disabled) goto free; existing = class_find_device(&devcd_class, NULL, dev, diff --git a/include/linux/device.h b/include/linux/device.h index 8a41dade13d75..cad394750ec8d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -677,8 +677,6 @@ struct device_physical_location { * should be set by the subsystem / bus driver that discovered * the device. * - * @coredump_disabled: Can be used to selectively enable/disable the coredump - * functionality for a particular device via sysfs entry. * @offline_disabled: If set, the device is permanently online. * @offline: Set after successful invocation of bus type's .offline(). * @of_node_reused: Set if the device-tree node is shared with an ancestor @@ -795,7 +793,6 @@ struct device { enum device_removable removable; - bool coredump_disabled:1; bool offline_disabled:1; bool offline:1; bool of_node_reused:1; -- GitLab From c11f384239078bf733358c2812007018874fed48 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 16 Dec 2024 08:37:03 -0800 Subject: [PATCH 163/456] CHROMIUM: HID: hid-himax: Fix spi_device_id When the spi_device_id was added for hid-himax, we forgot to add it to the `struct spi_driver`. This led to warnings (seen when building with USE flags "nowerror kernel_warning_level_1"): .../drivers/hid/hid-himax.c:5345:35: warning: unused variable 'himax_spi_id' [-Wunused-const-variable] 5345 | static const struct spi_device_id himax_spi_id[] = { | ^~~~~~~~~~~~ Looking at other drivers, we're supposed to have a reference to this table in the `struct spi_driver`. Add it. BUG=b:382031220 TEST=build and see this warning is gone UPSTREAM-TASK=b:321173762 Change-Id: I971f2ad835c68ffe24e6634e5789f820a4f378aa Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6098450 Reviewed-by: Stephen Boyd Commit-Queue: Stephen Boyd Signed-off-by: Hubert Mazur --- drivers/hid/hid-himax.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-himax.c b/drivers/hid/hid-himax.c index 2f24a306d261f..e4edfd45b2613 100644 --- a/drivers/hid/hid-himax.c +++ b/drivers/hid/hid-himax.c @@ -5356,6 +5356,7 @@ static struct spi_driver himax_hid_over_spi_driver = { .of_match_table = of_match_ptr(himax_table), #endif }, + .id_table = himax_spi_id, .probe = himax_spi_drv_probe, .remove = himax_spi_drv_remove, .shutdown = himax_shutdown, -- GitLab From 424b4b3bd1b115001f84b23d760a72d5a19b8f77 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 16 Dec 2024 08:39:34 -0800 Subject: [PATCH 164/456] CHROMIUM: HID: hid-himax: resned => resend in function comment When building with USE flags "nowerror kernel_warning_level_1", you can see: .../drivers/hid/hid-himax.c:2180: warning: expecting prototype for himax_mcu_resned_cmd_func(). Prototype was for himax_mcu_resend_cmd_func() instead It can be seen that the kernel-doc comment had a typo. Fix. BUG=None TEST=Warning is gone UPSTREAM-TASK=b:321173762 Change-Id: Ia376d6176e71dbddf567d53026f01bf7ec276187 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6098451 Commit-Queue: Stephen Boyd Reviewed-by: Stephen Boyd Signed-off-by: Hubert Mazur --- drivers/hid/hid-himax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-himax.c b/drivers/hid/hid-himax.c index e4edfd45b2613..ca3f28e18ae1b 100644 --- a/drivers/hid/hid-himax.c +++ b/drivers/hid/hid-himax.c @@ -2166,7 +2166,7 @@ static int himax_mcu_tp_info_check(struct himax_ts_data *ts) } /** - * himax_mcu_resned_cmd_func() - Resend command collection + * himax_mcu_resend_cmd_func() - Resend command collection * @ts: Himax touch screen data * * This function is used to collect commands that need to be resent to TPIC after -- GitLab From 8c98a8c68a310dd077ea70c3429184d06d713d0e Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 10 Dec 2024 10:48:14 +0000 Subject: [PATCH 165/456] BACKPORT: FROMLIST: media: uvcvideo: Add quirk for Actions UVC05 Actions UVC05 is a HDMI to USB dongle that implements the UVC protocol. When the device suspends, its firmware seems to enter a weird mode when it does not produce more frames. Add the device to the quirk list to disable autosuspend. Bus 001 Device 007: ID 1de1:f105 Actions Microelectronics Co. Display capture-UVC05 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 [unknown] bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 idVendor 0x1de1 Actions Microelectronics Co. idProduct 0xf105 Display capture-UVC05 bcdDevice 4.09 iManufacturer 1 Actions Micro iProduct 2 Display capture-UVC05 iSerial 3 -1005308387 bNumConfigurations 1 Signed-off-by: Ricardo Ribalda (am from https://patchwork.kernel.org/patch/13901255/) (also found at https://lore.kernel.org/r/20241210-uvc-hdmi-suspend-v1-1-01f5dec023ea@chromium.org) Conflicts: drivers/media/usb/uvc/uvc_driver.c UPSTREAM-TASK=b:255969015 BUG=b:323302656 TEST=Open the camera app Change-Id: I5191e079c8e3df60c589aeafb1565df89f18ae6d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6082115 Tested-by: Ricardo Ribalda Reviewed-by: Hidenori Kobayashi Tested-by: Yunke Cao Auto-Submit: Ricardo Ribalda Commit-Queue: Yunke Cao Reviewed-by: Yunke Cao Kcr-patch: 840a037fc9e68a32bfaf4f5d251be13f0414ab4ae3695a828cab8d0e.patch Signed-off-by: Hubert Mazur --- drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 8e417208be662..a7c769870efa0 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -3051,6 +3051,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceProtocol = 0, .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT) }, + /* Actions Microelectronics Co. Display capture-UVC05 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1de1, + .idProduct = 0xf105, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) }, /* NXP Semiconductors IR VIDEO */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- GitLab From 2c52838f181fd76898625e6c252b279ab2d6b8b6 Mon Sep 17 00:00:00 2001 From: Andrew Kreimer Date: Mon, 9 Sep 2024 16:56:38 +0300 Subject: [PATCH 166/456] UPSTREAM: accel/ivpu: Fix a typo Fix a typo in comments. Reported-by: Matthew Wilcox Signed-off-by: Andrew Kreimer Signed-off-by: Simona Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20240909135655.45938-1-algonell@gmail.com (cherry picked from commit 284a8908f5ec25355a831e3e2d87975d748e98dc) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I9be032dad49aa2bf025b8c3de6df2f813d9347ff Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057330 Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/vpu_boot_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index 82954b91b7481..d474bc7b15c01 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -8,7 +8,7 @@ /* * =========== FW API version information beginning ================ - * The bellow values will be used to construct the version info this way: + * The below values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes -- GitLab From 681d8a2c16ee30c288e933be3c5df61dda4b0bd2 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Mon, 30 Sep 2024 21:52:52 +0200 Subject: [PATCH 167/456] UPSTREAM: accel/ivpu: Update VPU FW API headers This commit bumps: - Boot API from 3.24.0 to 3.26.3 - JSM API from 3.16.0 to 3.25.0 Signed-off-by: Andrzej Kacprowski Co-developed-by: Tomasz Rusinowicz Signed-off-by: Tomasz Rusinowicz Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-2-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit a4293cc75348409f998c991c48cbe5532c438114) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I2b8f3fe569a3a545bcbb6d50593158d669d44ca8 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057331 Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_job.c | 2 +- drivers/accel/ivpu/ivpu_jsm_msg.c | 3 +- drivers/accel/ivpu/vpu_boot_api.h | 43 +++-- drivers/accel/ivpu/vpu_jsm_api.h | 303 +++++++++++++++++++++++++----- 4 files changed, 292 insertions(+), 59 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index be2e2bf0f43f0..b00634af8bc34 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -354,7 +354,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) return -EBUSY; } - entry = &cmdq->jobq->job[tail]; + entry = &cmdq->jobq->slot[tail].job; entry->batch_buf_addr = job->cmd_buf_vpu_addr; entry->job_id = job->job_id; entry->flags = 0; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 46ef16c3c0691..b06da8f50fd39 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -48,9 +48,10 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP); - IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT); + IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED); IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL); IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE); diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index d474bc7b15c01..908e68ea1c39c 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -1,13 +1,12 @@ /* SPDX-License-Identifier: MIT */ /* - * Copyright (c) 2020-2023, Intel Corporation. + * Copyright (c) 2020-2024, Intel Corporation. */ #ifndef VPU_BOOT_API_H #define VPU_BOOT_API_H /* - * =========== FW API version information beginning ================ * The below values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; @@ -27,19 +26,18 @@ * Minor version changes when API backward compatibility is preserved. * Resets to 0 if Major version is incremented. */ -#define VPU_BOOT_API_VER_MINOR 24 +#define VPU_BOOT_API_VER_MINOR 26 /* * API header changed (field names, documentation, formatting) but API itself has not been changed */ -#define VPU_BOOT_API_VER_PATCH 0 +#define VPU_BOOT_API_VER_PATCH 3 /* * Index in the API version table * Must be unique for each API */ #define VPU_BOOT_API_VER_INDEX 0 -/* ------------ FW API version information end ---------------------*/ #pragma pack(push, 4) @@ -164,8 +162,6 @@ enum vpu_trace_destination { /* VPU 30xx HW component IDs are sequential, so define first and last IDs. */ #define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT #define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15 -#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST -#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST struct vpu_boot_l2_cache_config { u8 use; @@ -199,6 +195,17 @@ struct vpu_warm_boot_section { */ #define POWER_PROFILE_SURVIVABILITY 0x1 +/** + * Enum for dvfs_mode boot param. + */ +enum vpu_governor { + VPU_GOV_DEFAULT = 0, /* Default Governor for the system */ + VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */ + VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */ + VPU_GOV_POWER_SAVE = 3, /* Power save governor */ + VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */ +}; + struct vpu_boot_params { u32 magic; u32 vpu_id; @@ -301,7 +308,14 @@ struct vpu_boot_params { u32 temp_sensor_period_ms; /** PLL ratio for efficient clock frequency */ u32 pn_freq_pll_ratio; - /** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */ + /** + * DVFS Mode: + * 0 - Default, DVFS mode selected by the firmware + * 1 - Max Performance + * 2 - On Demand + * 3 - Power Save + * 4 - On Demand Priority Aware + */ u32 dvfs_mode; /** * Depending on DVFS Mode: @@ -332,8 +346,8 @@ struct vpu_boot_params { u64 d0i3_entry_vpu_ts; /* * The system time of the host operating system in microseconds. - * E.g the number of microseconds since 1st of January 1970, or whatever date the - * host operating system uses to maintain system time. + * E.g the number of microseconds since 1st of January 1970, or whatever + * date the host operating system uses to maintain system time. * This value will be used to track system time on the VPU. * The KMD is required to update this value on every VPU reset. */ @@ -382,10 +396,7 @@ struct vpu_boot_params { u32 pad6[734]; }; -/* - * Magic numbers set between host and vpu to detect corruptio of tracing init - */ - +/* Magic numbers set between host and vpu to detect corruption of tracing init */ #define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE) /* Tracing buffer message format definitions */ @@ -405,7 +416,9 @@ struct vpu_tracing_buffer_header { u32 host_canary_start; /* offset from start of buffer for trace entries */ u32 read_index; - u32 pad_to_cache_line_size_0[14]; + /* keeps track of wrapping on the reader side */ + u32 read_wrap_count; + u32 pad_to_cache_line_size_0[13]; /* End of first cache line */ /** diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 33f462b1a25d8..7215c144158cb 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -22,7 +22,7 @@ /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 16 +#define VPU_JSM_API_VER_MINOR 25 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -36,7 +36,7 @@ /* * Number of Priority Bands for Hardware Scheduling - * Bands: RealTime, Focus, Normal, Idle + * Bands: Idle(0), Normal(1), Focus(2), RealTime(3) */ #define VPU_HWS_NUM_PRIORITY_BANDS 4 @@ -74,6 +74,7 @@ #define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU /* Job status returned when the job was preempted mid-inference */ #define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU +#define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU /* * Host <-> VPU IPC channels. @@ -86,18 +87,58 @@ /* * Job flags bit masks. */ -#define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001 -#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000 +enum { + /* + * Null submission mask. + * When set, batch buffer's commands are not processed but returned as + * successful immediately, except fences and timestamps. + * When cleared, batch buffer's commands are processed normally. + * Used for testing and profiling purposes. + */ + VPU_JOB_FLAGS_NULL_SUBMISSION_MASK = (1 << 0U), + /* + * Inline command mask. + * When set, the object in job queue is an inline command (see struct vpu_inline_cmd below). + * When cleared, the object in job queue is a job (see struct vpu_job_queue_entry below). + */ + VPU_JOB_FLAGS_INLINE_CMD_MASK = (1 << 1U), + /* + * VPU private data mask. + * Reserved for the VPU to store private data about the job (or inline command) + * while being processed. + */ + VPU_JOB_FLAGS_PRIVATE_DATA_MASK = 0xFFFF0000U +}; /* - * Sizes of the reserved areas in jobs, in bytes. + * Job queue flags bit masks. */ -#define VPU_JOB_RESERVED_BYTES 8 +enum { + /* + * No job done notification mask. + * When set, indicates that no job done notification should be sent for any + * job from this queue. When cleared, indicates that job done notification + * should be sent for every job completed from this queue. + */ + VPU_JOB_QUEUE_FLAGS_NO_JOB_DONE_MASK = (1 << 0U), + /* + * Native fence usage mask. + * When set, indicates that job queue uses native fences (as inline commands + * in job queue). Such queues may also use legacy fences (as commands in batch buffers). + * When cleared, indicates the job queue only uses legacy fences. + * NOTE: For queues using native fences, VPU expects that all jobs in the queue + * are immediately followed by an inline command object. This object is expected + * to be a fence signal command in most cases, but can also be a NOP in case the host + * does not need per-job fence signalling. Other inline commands objects can be + * inserted between "job and inline command" pairs. + */ + VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), -/* - * Sizes of the reserved areas in job queues, in bytes. - */ -#define VPU_JOB_QUEUE_RESERVED_BYTES 52 + /* + * Enable turbo mode for testing NPU performance; not recommended for regular usage. + */ + VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U) +}; /* * Max length (including trailing NULL char) of trace entity name (e.g., the @@ -140,24 +181,113 @@ */ #define VPU_HWS_INVALID_CMDQ_HANDLE 0ULL +/* + * Inline commands types. + */ +/* + * NOP. + * VPU does nothing other than consuming the inline command object. + */ +#define VPU_INLINE_CMD_TYPE_NOP 0x0 +/* + * Fence wait. + * VPU waits for the fence current value to reach monitored value. + * Fence wait operations are executed upon job dispatching. While waiting for + * the fence to be satisfied, VPU blocks fetching of the next objects in the queue. + * Jobs present in the queue prior to the fence wait object may be processed + * concurrently. + */ +#define VPU_INLINE_CMD_TYPE_FENCE_WAIT 0x1 +/* + * Fence signal. + * VPU sets the fence current value to the provided value. If new current value + * is equal to or higher than monitored value, VPU sends fence signalled notification + * to the host. Fence signal operations are executed upon completion of all the jobs + * present in the queue prior to them, and in-order relative to each other in the queue. + * But jobs in-between them may be processed concurrently and may complete out-of-order. + */ +#define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2 + +/* + * Job scheduling priority bands for both hardware scheduling and OS scheduling. + */ +enum vpu_job_scheduling_priority_band { + VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE = 0, + VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL = 1, + VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS = 2, + VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME = 3, + VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4, +}; + /* * Job format. + * Jobs defines the actual workloads to be executed by a given engine. */ struct vpu_job_queue_entry { - u64 batch_buf_addr; /**< Address of VPU commands batch buffer */ - u32 job_id; /**< Job ID */ - u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */ - u64 root_page_table_addr; /**< Address of root page table to use for this job */ - u64 root_page_table_update_counter; /**< Page tables update events counter */ - u64 primary_preempt_buf_addr; + /**< Address of VPU commands batch buffer */ + u64 batch_buf_addr; + /**< Job ID */ + u32 job_id; + /**< Flags bit field, see VPU_JOB_FLAGS_* above */ + u32 flags; + /** + * Doorbell ring timestamp taken by KMD from SoC's global system clock, in + * microseconds. NPU can convert this value to its own fixed clock's timebase, + * to match other profiling timestamps. + */ + u64 doorbell_timestamp; + /**< Extra id for job tracking, used only in the firmware perf traces */ + u64 host_tracking_id; /**< Address of the primary preemption buffer to use for this job */ - u32 primary_preempt_buf_size; + u64 primary_preempt_buf_addr; /**< Size of the primary preemption buffer to use for this job */ - u32 secondary_preempt_buf_size; + u32 primary_preempt_buf_size; /**< Size of secondary preemption buffer to use for this job */ - u64 secondary_preempt_buf_addr; + u32 secondary_preempt_buf_size; /**< Address of secondary preemption buffer to use for this job */ - u8 reserved_0[VPU_JOB_RESERVED_BYTES]; + u64 secondary_preempt_buf_addr; + u64 reserved_0; +}; + +/* + * Inline command format. + * Inline commands are the commands executed at scheduler level (typically, + * synchronization directives). Inline command and job objects must be of + * the same size and have flags field at same offset. + */ +struct vpu_inline_cmd { + u64 reserved_0; + /* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ + u32 type; + /* Flags bit field, see VPU_JOB_FLAGS_* above. */ + u32 flags; + /* Inline command payload. Depends on inline command type. */ + union { + /* Fence (wait and signal) commands' payload. */ + struct { + /* Fence object handle. */ + u64 fence_handle; + /* User VA of the current fence value. */ + u64 current_value_va; + /* User VA of the monitored fence value (read-only). */ + u64 monitored_value_va; + /* Value to wait for or write in fence location. */ + u64 value; + /* User VA of the log buffer in which to add log entry on completion. */ + u64 log_buffer_va; + } fence; + /* Other commands do not have a payload. */ + /* Payload definition for future inline commands can be inserted here. */ + u64 reserved_1[6]; + } payload; +}; + +/* + * Job queue slots can be populated either with job objects or inline command objects. + */ +union vpu_jobq_slot { + struct vpu_job_queue_entry job; + struct vpu_inline_cmd inline_cmd; }; /* @@ -167,7 +297,21 @@ struct vpu_job_queue_header { u32 engine_idx; u32 head; u32 tail; - u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES]; + u32 flags; + /* Set to 1 to indicate priority_band field is valid */ + u32 priority_band_valid; + /* + * Priority for the work of this job queue, valid only if the HWS is NOT used + * and the `priority_band_valid` is set to 1. It is applied only during + * the VPU_JSM_MSG_REGISTER_DB message processing. + * The device firmware might use the `priority_band` to optimize the power + * management logic, but it will not affect the order of jobs. + * Available priority bands: @see enum vpu_job_scheduling_priority_band + */ + u32 priority_band; + /* Inside realtime band assigns a further priority, limited to 0..31 range */ + u32 realtime_priority_level; + u32 reserved_0[9]; }; /* @@ -175,7 +319,7 @@ struct vpu_job_queue_header { */ struct vpu_job_queue { struct vpu_job_queue_header header; - struct vpu_job_queue_entry job[]; + union vpu_jobq_slot slot[]; }; /** @@ -197,9 +341,7 @@ enum vpu_trace_entity_type { struct vpu_hws_log_buffer_header { /* Written by VPU after adding a log entry. Initialised by host to 0. */ u32 first_free_entry_index; - /* Incremented by VPU every time the VPU overwrites the 0th entry; - * initialised by host to 0. - */ + /* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ u32 wraparound_count; /* * This is the number of buffers that can be stored in the log buffer provided by the host. @@ -230,14 +372,80 @@ struct vpu_hws_log_buffer_entry { u64 operation_data[2]; }; +/* Native fence log buffer types. */ +enum vpu_hws_native_fence_log_type { + VPU_HWS_NATIVE_FENCE_LOG_TYPE_WAITS = 1, + VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2 +}; + +/* HWS native fence log buffer header. */ +struct vpu_hws_native_fence_log_header { + union { + struct { + /* Index of the first free entry in buffer. */ + u32 first_free_entry_idx; + /* Incremented each time NPU wraps around the buffer to write next entry. */ + u32 wraparound_count; + }; + /* Field allowing atomic update of both fields above. */ + u64 atomic_wraparound_and_entry_idx; + }; + /* Log buffer type, see enum vpu_hws_native_fence_log_type. */ + u64 type; + /* Allocated number of entries in the log buffer. */ + u64 entry_nb; + u64 reserved[2]; +}; + +/* Native fence log operation types. */ +enum vpu_hws_native_fence_log_op { + VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0, + VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1 +}; + +/* HWS native fence log entry. */ +struct vpu_hws_native_fence_log_entry { + /* Newly signaled/unblocked fence value. */ + u64 fence_value; + /* Native fence object handle to which this operation belongs. */ + u64 fence_handle; + /* Operation type, see enum vpu_hws_native_fence_log_op. */ + u64 op_type; + u64 reserved_0; + /* + * VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence + * wait was started (in NPU SysTime). + */ + u64 fence_wait_start_ts; + u64 reserved_1; + /* Timestamp at which fence operation was completed (in NPU SysTime). */ + u64 fence_end_ts; +}; + +/* Native fence log buffer. */ +struct vpu_hws_native_fence_log_buffer { + struct vpu_hws_native_fence_log_header header; + struct vpu_hws_native_fence_log_entry entry[]; +}; + /* * Host <-> VPU IPC messages types. */ enum vpu_ipc_msg_type { VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF, + /* IPC Host -> Device, Async commands */ VPU_JSM_MSG_ASYNC_CMD = 0x1100, VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD, + /** + * Preempt engine. The NPU stops (preempts) all the jobs currently + * executing on the target engine making the engine become idle and ready to + * execute new jobs. + * NOTE: The NPU does not remove unstarted jobs (if any) from job queues of + * the target engine, but it stops processing them (until the queue doorbell + * is rung again); the host is responsible to reset the job queue, either + * after preemption or when resubmitting jobs to the queue. + */ VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101, VPU_JSM_MSG_REGISTER_DB = 0x1102, VPU_JSM_MSG_UNREGISTER_DB = 0x1103, @@ -323,9 +531,10 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC commands before this one. * */ VPU_JSM_MSG_STATE_DUMP = 0x11FF, + /* IPC Host -> Device, General commands */ VPU_JSM_MSG_GENERAL_CMD = 0x1200, - VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD, + VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD, /** * Control dyndbg behavior by executing a dyndbg command; equivalent to * Linux command: `echo '' > /dynamic_debug/control`. @@ -335,8 +544,12 @@ enum vpu_ipc_msg_type { * Perform the save procedure for the D0i3 entry */ VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202, + /* IPC Device -> Host, Job completion */ VPU_JSM_MSG_JOB_DONE = 0x2100, + /* IPC Device -> Host, Fence signalled */ + VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101, + /* IPC Device -> Host, Async command completion */ VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200, VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE, @@ -422,6 +635,7 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC responses before this one. * */ VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF, + /* IPC Device -> Host, General command completion */ VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300, VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE, @@ -600,11 +814,6 @@ struct vpu_jsm_metric_streamer_update { u64 next_buffer_size; }; -struct vpu_ipc_msg_payload_blob_deinit { - /* 64-bit unique ID for the blob to be de-initialized. */ - u64 blob_id; -}; - struct vpu_ipc_msg_payload_job_done { /* Engine to which the job was submitted. */ u32 engine_idx; @@ -622,6 +831,21 @@ struct vpu_ipc_msg_payload_job_done { u64 cmdq_id; }; +/* + * Notification message upon native fence signalling. + * @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED + */ +struct vpu_ipc_msg_payload_native_fence_signalled { + /* Engine ID. */ + u32 engine_idx; + /* Host SSID. */ + u32 host_ssid; + /* CMDQ ID */ + u64 cmdq_id; + /* Fence object handle. */ + u64 fence_handle; +}; + struct vpu_jsm_engine_reset_context { /* Host SSID */ u32 host_ssid; @@ -700,11 +924,6 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { u8 power_limit[16]; }; -struct vpu_ipc_msg_payload_blob_deinit_done { - /* 64-bit unique ID for the blob de-initialized. */ - u64 blob_id; -}; - /* HWS priority band setup request / response */ struct vpu_ipc_msg_payload_hws_priority_band_setup { /* @@ -794,7 +1013,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { u32 reserved_0; /* Command queue id */ u64 cmdq_id; - /* Priority band to assign to work of this context */ + /* + * Priority band to assign to work of this context. + * Available priority bands: @see enum vpu_job_scheduling_priority_band + */ u32 priority_band; /* Inside realtime band assigns a further priority */ u32 realtime_priority_level; @@ -869,9 +1091,7 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log { */ u64 notify_index; /* - * Enable extra events to be output to log for debug of scheduling algorithm. - * Interpreted by VPU as a boolean to enable or disable, expected values are - * 0 and 1. + * Field is now deprecated, will be removed when KMD is updated to support removal */ u32 enable_extra_events; /* Zero Padding */ @@ -1243,10 +1463,10 @@ union vpu_ipc_msg_payload { struct vpu_jsm_metric_streamer_start metric_streamer_start; struct vpu_jsm_metric_streamer_stop metric_streamer_stop; struct vpu_jsm_metric_streamer_update metric_streamer_update; - struct vpu_ipc_msg_payload_blob_deinit blob_deinit; struct vpu_ipc_msg_payload_ssid_release ssid_release; struct vpu_jsm_hws_register_db hws_register_db; struct vpu_ipc_msg_payload_job_done job_done; + struct vpu_ipc_msg_payload_native_fence_signalled native_fence_signalled; struct vpu_ipc_msg_payload_engine_reset_done engine_reset_done; struct vpu_ipc_msg_payload_engine_preempt_done engine_preempt_done; struct vpu_ipc_msg_payload_register_db_done register_db_done; @@ -1254,7 +1474,6 @@ union vpu_ipc_msg_payload { struct vpu_ipc_msg_payload_query_engine_hb_done query_engine_hb_done; struct vpu_ipc_msg_payload_get_power_level_count_done get_power_level_count_done; struct vpu_jsm_metric_streamer_done metric_streamer_done; - struct vpu_ipc_msg_payload_blob_deinit_done blob_deinit_done; struct vpu_ipc_msg_payload_trace_config trace_config; struct vpu_ipc_msg_payload_trace_capability_rsp trace_capability; struct vpu_ipc_msg_payload_trace_get_name trace_get_name; -- GitLab From 7a82539cd9b47c88edf4e7c244781aafee29b494 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:52:53 +0200 Subject: [PATCH 168/456] UPSTREAM: accel/ivpu: Rename ivpu_log_level to fw_log_level Rename module param ivpu_log_level to fw_log_level, so it is clear what log level is actually changed. Reviewed-by: Maciej Falkowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-3-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 3a3fb8110c65d361cd9d750c9e16520f740c93f2) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id14204fa80f666442d2a590a290f4ef8f6eae504 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057332 Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_fw.c | 4 ++-- drivers/accel/ivpu/ivpu_fw_log.c | 12 ++++++------ drivers/accel/ivpu/ivpu_fw_log.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index ede6165e09d90..00e27e2c14779 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -208,7 +208,7 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->cold_boot_entry_point = fw_hdr->entry_point; fw->entry_point = fw->cold_boot_entry_point; - fw->trace_level = min_t(u32, ivpu_log_level, IVPU_FW_LOG_FATAL); + fw->trace_level = min_t(u32, ivpu_fw_log_level, IVPU_FW_LOG_FATAL); fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING; fw->trace_hw_component_mask = -1; @@ -311,7 +311,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) goto err_free_fw_mem; } - if (ivpu_log_level <= IVPU_FW_LOG_INFO) + if (ivpu_fw_log_level <= IVPU_FW_LOG_INFO) log_verb_size = IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE; else log_verb_size = IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE; diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index ef0adb5e0fbeb..2f2d3242f21be 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include @@ -15,12 +15,12 @@ #include "ivpu_fw_log.h" #include "ivpu_gem.h" -#define IVPU_FW_LOG_LINE_LENGTH 256 +#define IVPU_FW_LOG_LINE_LENGTH 256 -unsigned int ivpu_log_level = IVPU_FW_LOG_ERROR; -module_param(ivpu_log_level, uint, 0444); -MODULE_PARM_DESC(ivpu_log_level, - "NPU firmware default trace level: debug=" __stringify(IVPU_FW_LOG_DEBUG) +unsigned int ivpu_fw_log_level = IVPU_FW_LOG_ERROR; +module_param_named(fw_log_level, ivpu_fw_log_level, uint, 0444); +MODULE_PARM_DESC(fw_log_level, + "NPU firmware default log level: debug=" __stringify(IVPU_FW_LOG_DEBUG) " info=" __stringify(IVPU_FW_LOG_INFO) " warn=" __stringify(IVPU_FW_LOG_WARN) " error=" __stringify(IVPU_FW_LOG_ERROR) diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 0b2573f6f3151..ccef4298e45b5 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __IVPU_FW_LOG_H__ @@ -19,12 +19,12 @@ #define IVPU_FW_LOG_ERROR 4 #define IVPU_FW_LOG_FATAL 5 -extern unsigned int ivpu_log_level; - #define IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE SZ_1M #define IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE SZ_8M #define IVPU_FW_CRITICAL_BUFFER_SIZE SZ_512K +extern unsigned int ivpu_fw_log_level; + void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); -- GitLab From 18418221226a2c110379c87c7f27d2482e0bccf5 Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz Date: Mon, 30 Sep 2024 21:52:54 +0200 Subject: [PATCH 169/456] UPSTREAM: accel/ivpu: Reset fw log on cold boot Add ivpu_fw_log_reset() that resets the read_index of all FW logs on cold boot so logs are properly read. Signed-off-by: Tomasz Rusinowicz Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-4-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 4b4d9e394b6f45ac26ac6144b31604c76b7e3705) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I8e1aaf855da5bbe1c81cbb7118665363aa25c771 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057333 Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_fw_log.c | 14 ++++++++++++++ drivers/accel/ivpu/ivpu_fw_log.h | 1 + drivers/accel/ivpu/ivpu_pm.c | 1 + 3 files changed, 16 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 2f2d3242f21be..817210e35f70e 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -140,3 +140,17 @@ void ivpu_fw_log_clear(struct ivpu_device *vdev) while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) log_header->read_index = log_header->write_index; } + +void ivpu_fw_log_reset(struct ivpu_device *vdev) +{ + struct vpu_tracing_buffer_header *log_header; + u32 next; + + next = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) + log_header->read_index = 0; + + next = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) + log_header->read_index = 0; +} diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index ccef4298e45b5..a033ce2d642f6 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -27,6 +27,7 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); +void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) { diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 59d3170f5e354..3c36b55c01d51 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -37,6 +37,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) ivpu_cmdq_reset_all_contexts(vdev); ivpu_ipc_reset(vdev); + ivpu_fw_log_reset(vdev); ivpu_fw_load(vdev); fw->entry_point = fw->cold_boot_entry_point; } -- GitLab From a69ead58899786ac98f274a126e346dddc9cd9ea Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:52:55 +0200 Subject: [PATCH 170/456] UPSTREAM: accel/ivpu: Refactor functions in ivpu_fw_log.c Make function names more consistent and (arguably) readable in fw log code. Add fw_log_print_all_in_bo() that remove duplicated code in ivpu_fw_log_print(). Reviewed-by: Tomasz Rusinowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-5-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 1fc1251149a76d3b75d7f4c94d9c4e081b7df6b4) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I92a05d3e1b4736935510db30db6c5f891d136420 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057334 Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_debugfs.c | 2 +- drivers/accel/ivpu/ivpu_fw_log.c | 62 ++++++++++++++++--------------- drivers/accel/ivpu/ivpu_fw_log.h | 2 +- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 99c58fda36099..cfc71f99433f3 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -190,7 +190,7 @@ fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, l if (!size) return -EINVAL; - ivpu_fw_log_clear(vdev); + ivpu_fw_log_mark_read(vdev); return size; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 817210e35f70e..343ebfd30d280 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -26,8 +26,8 @@ MODULE_PARM_DESC(fw_log_level, " error=" __stringify(IVPU_FW_LOG_ERROR) " fatal=" __stringify(IVPU_FW_LOG_FATAL)); -static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, - struct vpu_tracing_buffer_header **log_header) +static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, + struct vpu_tracing_buffer_header **out_log) { struct vpu_tracing_buffer_header *log; @@ -48,7 +48,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, return -EINVAL; } - *log_header = log; + *out_log = log; *offset += log->size; ivpu_dbg(vdev, FW_BOOT, @@ -59,7 +59,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, return 0; } -static void buffer_print(char *buffer, u32 size, struct drm_printer *p) +static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) { char line[IVPU_FW_LOG_LINE_LENGTH]; u32 index = 0; @@ -90,11 +90,11 @@ static void buffer_print(char *buffer, u32 size, struct drm_printer *p) drm_printf(p, "%s\n", line); } -static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buffer_header *log, - const char *prefix, bool only_new_msgs, struct drm_printer *p) +static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, + bool only_new_msgs, struct drm_printer *p) { - char *log_buffer = (void *)log + log->header_size; - u32 log_size = log->size - log->header_size; + char *log_data = (void *)log + log->header_size; + u32 data_size = log->size - log->header_size; u32 log_start = log->read_index; u32 log_end = log->write_index; @@ -106,51 +106,55 @@ static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buf drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); if (log->write_index > log->read_index) { - buffer_print(log_buffer + log_start, log_end - log_start, p); + fw_log_print_lines(log_data + log_start, log_end - log_start, p); } else { - buffer_print(log_buffer + log_end, log_size - log_end, p); - buffer_print(log_buffer, log_end, p); + fw_log_print_lines(log_data + log_end, data_size - log_end, p); + fw_log_print_lines(log_data, log_end, p); } drm_printf(p, "\x1b[0m"); drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } -void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) +static void +fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name, + struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - fw_log_print_buffer(vdev, log_header, "NPU critical", only_new_msgs, p); + while (fw_log_from_bo(vdev, bo, &next, &log) == 0) + fw_log_print_buffer(log, name, only_new_msgs, p); +} - next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - fw_log_print_buffer(vdev, log_header, "NPU verbose", only_new_msgs, p); +void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) +{ + fw_log_print_all_in_bo(vdev, "NPU critical", vdev->fw->mem_log_crit, only_new_msgs, p); + fw_log_print_all_in_bo(vdev, "NPU verbose", vdev->fw->mem_log_verb, only_new_msgs, p); } -void ivpu_fw_log_clear(struct ivpu_device *vdev) +void ivpu_fw_log_mark_read(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - log_header->read_index = log_header->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + log->read_index = log->write_index; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - log_header->read_index = log_header->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + log->read_index = log->write_index; } void ivpu_fw_log_reset(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - log_header->read_index = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + log->read_index = 0; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - log_header->read_index = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + log->read_index = 0; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index a033ce2d642f6..41c85b74cc7fd 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -26,7 +26,7 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); -void ivpu_fw_log_clear(struct ivpu_device *vdev); +void ivpu_fw_log_mark_read(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) -- GitLab From b9261fcf8eb231e31a7be9342b6efb2bc605647d Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:52:56 +0200 Subject: [PATCH 171/456] UPSTREAM: accel/ivpu: Fix fw log printing - Fix empty log detection that couldn't work without read_wrap_count - Start printing wrapped log from correct position (log_start) - Properly handle logs that are wrapped multiple times in reference to reader position - Don't add a newline when log buffer is wrapped - Always add a newline after printing a log buffer in case log does not end with one Reviewed-by: Tomasz Rusinowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-6-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 4bc988b47019536b3b1f7d9c5b83893c712d94d6) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I7f89a30d406d1062f76856ad82f3edde2f469acb Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057335 Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_fw_log.c | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 343ebfd30d280..337c906b02107 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -87,7 +87,7 @@ static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) } line[index] = 0; if (index != 0) - drm_printf(p, "%s\n", line); + drm_printf(p, "%s", line); } static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, @@ -95,23 +95,29 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha { char *log_data = (void *)log + log->header_size; u32 data_size = log->size - log->header_size; - u32 log_start = log->read_index; - u32 log_end = log->write_index; + u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0; + u32 log_end = READ_ONCE(log->write_index); - if (!(log->write_index || log->wrap_count) || - (log->write_index == log->read_index && only_new_msgs)) { - drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); - return; + if (log->wrap_count == log->read_wrap_count) { + if (log_end <= log_start) { + drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); + return; + } + } else if (log->wrap_count == log->read_wrap_count + 1) { + if (log_end > log_start) + log_start = log_end; + } else { + log_start = log_end; } drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); - if (log->write_index > log->read_index) { + if (log_end > log_start) { fw_log_print_lines(log_data + log_start, log_end - log_start, p); } else { - fw_log_print_lines(log_data + log_end, data_size - log_end, p); + fw_log_print_lines(log_data + log_start, data_size - log_start, p); fw_log_print_lines(log_data, log_end, p); } - drm_printf(p, "\x1b[0m"); + drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */ drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } @@ -135,14 +141,19 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev) { struct vpu_tracing_buffer_header *log; - u32 next = 0; + u32 next; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) - log->read_index = log->write_index; + next = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { + log->read_index = READ_ONCE(log->write_index); + log->read_wrap_count = READ_ONCE(log->wrap_count); + } next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) - log->read_index = log->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { + log->read_index = READ_ONCE(log->write_index); + log->read_wrap_count = READ_ONCE(log->wrap_count); + } } void ivpu_fw_log_reset(struct ivpu_device *vdev) @@ -151,10 +162,14 @@ void ivpu_fw_log_reset(struct ivpu_device *vdev) u32 next; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { log->read_index = 0; + log->read_wrap_count = 0; + } next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { log->read_index = 0; + log->read_wrap_count = 0; + } } -- GitLab From b7039dd4ce3662b0e9f21e38ec1669dad36f7cc0 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:52:57 +0200 Subject: [PATCH 172/456] UPSTREAM: accel/ivpu: Limit FW version string length Limit FW version string, when parsing FW binary, to 256 bytes and always add NULL-terminate it. Reviewed-by: Karol Wachowski Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-7-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 990b1e3d150104249115a0ad81ea77c53b28f0f8) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I2ab812206ceb7fe3168e4ff648c881547ab8594b Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057336 Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_fw.c | 7 ++++--- drivers/accel/ivpu/ivpu_fw.h | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 00e27e2c14779..7e8593c831ec2 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -25,7 +25,6 @@ #define FW_SHAVE_NN_MAX_SIZE SZ_2M #define FW_RUNTIME_MIN_ADDR (FW_GLOBAL_MEM_START) #define FW_RUNTIME_MAX_ADDR (FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE) -#define FW_VERSION_HEADER_SIZE SZ_4K #define FW_FILE_IMAGE_OFFSET (VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE) #define WATCHDOG_MSS_REDIRECT 32 @@ -191,8 +190,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", fw_hdr->header_version, fw_hdr->image_format); - ivpu_info(vdev, "Firmware: %s, version: %s", fw->name, - (const char *)fw_hdr + VPU_FW_HEADER_SIZE); + if (!scnprintf(fw->version, sizeof(fw->version), "%s", fw->file->data + VPU_FW_HEADER_SIZE)) + ivpu_warn(vdev, "Missing firmware version\n"); + + ivpu_info(vdev, "Firmware: %s, version: %s\n", fw->name, fw->version); if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, BOOT, 3)) return -EINVAL; diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 40d9d17be3f52..5e8eb608b70f1 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ +#define FW_VERSION_HEADER_SIZE SZ_4K +#define FW_VERSION_STR_SIZE SZ_256 + struct ivpu_device; struct ivpu_bo; struct vpu_boot_params; @@ -13,6 +16,7 @@ struct vpu_boot_params; struct ivpu_fw_info { const struct firmware *file; const char *name; + char version[FW_VERSION_STR_SIZE]; struct ivpu_bo *mem; struct ivpu_bo *mem_shave_nn; struct ivpu_bo *mem_log_crit; -- GitLab From 97af3ccb471e3b351fcb6a1945db0a42bdd471eb Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:52:58 +0200 Subject: [PATCH 173/456] UPSTREAM: accel/ivpu: Add coredump support Use coredump (if available) to collect FW logs in case of a FW crash. This makes dmesg more readable and allows to collect more log data. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-8-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit bade0340526827d03d9c293450c0422beba77f04) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I8d1f04cc9aadf4cf58b438b60b4a36ccdfc55304 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057337 Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/Kconfig | 1 + drivers/accel/ivpu/Makefile | 1 + drivers/accel/ivpu/ivpu_coredump.c | 39 ++++++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_coredump.h | 25 +++++++++++++++++++ drivers/accel/ivpu/ivpu_drv.c | 5 ++-- drivers/accel/ivpu/ivpu_fw_log.h | 8 ------ drivers/accel/ivpu/ivpu_pm.c | 9 ++++--- 7 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 drivers/accel/ivpu/ivpu_coredump.c create mode 100644 drivers/accel/ivpu/ivpu_coredump.h diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index 682c532452863..e4d418b44626e 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -8,6 +8,7 @@ config DRM_ACCEL_IVPU select FW_LOADER select DRM_GEM_SHMEM_HELPER select GENERIC_ALLOCATOR + select WANT_DEV_COREDUMP help Choose this option if you have a system with an 14th generation Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU) diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index ebd682a42eb12..232ea6d28c6e2 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -19,5 +19,6 @@ intel_vpu-y := \ ivpu_sysfs.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o +intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o diff --git a/drivers/accel/ivpu/ivpu_coredump.c b/drivers/accel/ivpu/ivpu_coredump.c new file mode 100644 index 0000000000000..16ad0c30818cc --- /dev/null +++ b/drivers/accel/ivpu/ivpu_coredump.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#include +#include + +#include "ivpu_coredump.h" +#include "ivpu_fw.h" +#include "ivpu_gem.h" +#include "vpu_boot_api.h" + +#define CRASH_DUMP_HEADER "Intel NPU crash dump" +#define CRASH_DUMP_HEADERS_SIZE SZ_4K + +void ivpu_dev_coredump(struct ivpu_device *vdev) +{ + struct drm_print_iterator pi = {}; + struct drm_printer p; + size_t coredump_size; + char *coredump; + + coredump_size = CRASH_DUMP_HEADERS_SIZE + FW_VERSION_HEADER_SIZE + + ivpu_bo_size(vdev->fw->mem_log_crit) + ivpu_bo_size(vdev->fw->mem_log_verb); + coredump = vmalloc(coredump_size); + if (!coredump) + return; + + pi.data = coredump; + pi.remain = coredump_size; + p = drm_coredump_printer(&pi); + + drm_printf(&p, "%s\n", CRASH_DUMP_HEADER); + drm_printf(&p, "FW version: %s\n", vdev->fw->version); + ivpu_fw_log_print(vdev, false, &p); + + dev_coredumpv(vdev->drm.dev, coredump, pi.offset, GFP_KERNEL); +} diff --git a/drivers/accel/ivpu/ivpu_coredump.h b/drivers/accel/ivpu/ivpu_coredump.h new file mode 100644 index 0000000000000..8efb09d024411 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_coredump.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#ifndef __IVPU_COREDUMP_H__ +#define __IVPU_COREDUMP_H__ + +#include + +#include "ivpu_drv.h" +#include "ivpu_fw_log.h" + +#ifdef CONFIG_DEV_COREDUMP +void ivpu_dev_coredump(struct ivpu_device *vdev); +#else +static inline void ivpu_dev_coredump(struct ivpu_device *vdev) +{ + struct drm_printer p = drm_info_printer(vdev->drm.dev); + + ivpu_fw_log_print(vdev, false, &p); +} +#endif + +#endif /* __IVPU_COREDUMP_H__ */ diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index c91400ecf9265..38b4158f52784 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -14,7 +14,7 @@ #include #include -#include "vpu_boot_api.h" +#include "ivpu_coredump.h" #include "ivpu_debugfs.h" #include "ivpu_drv.h" #include "ivpu_fw.h" @@ -29,6 +29,7 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" #include "ivpu_sysfs.h" +#include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR #define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ @@ -382,7 +383,7 @@ int ivpu_boot(struct ivpu_device *vdev) ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); ivpu_hw_diagnose_failure(vdev); ivpu_mmu_evtq_dump(vdev); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 41c85b74cc7fd..8bb528a73cb7e 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -8,8 +8,6 @@ #include -#include - #include "ivpu_drv.h" #define IVPU_FW_LOG_DEFAULT 0 @@ -29,11 +27,5 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); -static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) -{ - struct drm_printer p = drm_info_printer(vdev->drm.dev); - - ivpu_fw_log_print(vdev, false, &p); -} #endif /* __IVPU_FW_LOG_H__ */ diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 3c36b55c01d51..bf77395ffcb7c 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -9,17 +9,18 @@ #include #include -#include "vpu_boot_api.h" +#include "ivpu_coredump.h" #include "ivpu_drv.h" -#include "ivpu_hw.h" #include "ivpu_fw.h" #include "ivpu_fw_log.h" +#include "ivpu_hw.h" #include "ivpu_ipc.h" #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" +#include "vpu_boot_api.h" static bool ivpu_disable_recovery; module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); @@ -124,7 +125,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); atomic_inc(&vdev->pm->reset_counter); atomic_set(&vdev->pm->reset_pending, 1); @@ -263,7 +264,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) if (!is_idle || ret_d0i3) { ivpu_err(vdev, "Forcing cold boot due to previous errors\n"); atomic_inc(&vdev->pm->reset_counter); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); ivpu_pm_prepare_cold_boot(vdev); } else { ivpu_pm_prepare_warm_boot(vdev); -- GitLab From c5bf9a928eb9fa422dd37305f5b465f8d11a530e Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz Date: Mon, 30 Sep 2024 21:52:59 +0200 Subject: [PATCH 174/456] UPSTREAM: accel/ivpu: Add FW state dump on TDR Send JSM state dump message at the beginning of TDR handler. This allows FW to collect debug info in the FW log before the state of the NPU is lost allowing to analyze the cause of a TDR. Wait a predefined timeout (10 ms) so the FW has a chance to write debug logs. We cannot wait for JSM response at this point because IRQs are already disabled before TDR handler is invoked. Signed-off-by: Tomasz Rusinowicz Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-9-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 5e162f872d7af8f041b143536617ab2563ea7de5) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I10628da790b9c74048a340ad273eef3e1c5c546f Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057338 Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.h | 1 + drivers/accel/ivpu/ivpu_hw.c | 3 +++ drivers/accel/ivpu/ivpu_ipc.c | 26 ++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_ipc.h | 2 ++ drivers/accel/ivpu/ivpu_jsm_msg.c | 8 ++++++++ drivers/accel/ivpu/ivpu_jsm_msg.h | 2 ++ drivers/accel/ivpu/ivpu_pm.c | 1 + 7 files changed, 43 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 63f13b697eed7..2b30cc2e9272e 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -152,6 +152,7 @@ struct ivpu_device { int tdr; int autosuspend; int d0i3_entry_msg; + int state_dump_msg; } timeout; }; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 27f0fe4d54e00..85219e9596215 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -89,12 +89,14 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.tdr = 2000000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 500; + vdev->timeout.state_dump_msg = 10; } else if (ivpu_is_simics(vdev)) { vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 100; + vdev->timeout.state_dump_msg = 10; } else { vdev->timeout.boot = 1000; vdev->timeout.jsm = 500; @@ -104,6 +106,7 @@ static void timeouts_init(struct ivpu_device *vdev) else vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 5; + vdev->timeout.state_dump_msg = 10; } } diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 42f3fca6d8652..008fda068d18e 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -364,6 +364,32 @@ int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, return ret; } +int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + u32 channel, unsigned long timeout_ms) +{ + struct ivpu_ipc_consumer cons; + int ret; + + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + + ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); + + ret = ivpu_ipc_send(vdev, &cons, req); + if (ret) { + ivpu_warn_ratelimited(vdev, "IPC send failed: %d\n", ret); + goto consumer_del; + } + + msleep(timeout_ms); + +consumer_del: + ivpu_ipc_consumer_del(vdev, &cons); + ivpu_rpm_put(vdev); + return ret; +} + static bool ivpu_ipc_match_consumer(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg) diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 4fe38141045ea..6bbe6e32c8749 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -108,5 +108,7 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); +int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + u32 channel, unsigned long timeout_ms); #endif /* __IVPU_IPC_H__ */ diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index b06da8f50fd39..cd33964d292bc 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -559,3 +559,11 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } + +int ivpu_jsm_state_dump(struct ivpu_device *vdev) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_STATE_DUMP }; + + return ivpu_ipc_send_and_wait(vdev, &req, VPU_IPC_CHAN_ASYNC_CMD, + vdev->timeout.state_dump_msg); +} diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index e4e42c0ff6e65..9e84d3526a146 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -43,4 +43,6 @@ int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mas u64 buffer_size, u32 *sample_size, u64 *info_size); int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us); int ivpu_jsm_dct_disable(struct ivpu_device *vdev); +int ivpu_jsm_state_dump(struct ivpu_device *vdev); + #endif diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index bf77395ffcb7c..b5a69941e6e0a 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -125,6 +125,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); + ivpu_jsm_state_dump(vdev); ivpu_dev_coredump(vdev); atomic_inc(&vdev->pm->reset_counter); -- GitLab From 41a301d2cad61c222d8e80804b845d536f9e49c4 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:00 +0200 Subject: [PATCH 175/456] UPSTREAM: accel/ivpu: Set 500 ns delay between power island TRICKLE and ENABLE Follow HW documentation recommendation of 500 ns delay between setting AON_PWR_ISLAND_TRICKLE_EN and AON_PWR_ISLAND_EN registers during power island enabling. Previously this was only done correctly for VPU 4+. VPU 3.7 had the delay added after power island disable where it is not needed. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-10-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 525a3858aad73a42683783eee1b462cf8d4076d0) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id1cb63ab07e05014bd4bbfce276cc2fa8f52de19 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057339 Reviewed-by: Sean Paul Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw_ip.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index dfd2f4a5b5268..cfcbb99168e65 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -311,9 +311,6 @@ static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val); - - if (enable) - ndelay(500); } static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) @@ -326,9 +323,6 @@ static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val); - - if (!enable) - ndelay(500); } static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable) @@ -347,9 +341,11 @@ static void pwr_island_enable(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { pwr_island_trickle_drive_37xx(vdev, true); + ndelay(500); pwr_island_drive_37xx(vdev, true); } else { pwr_island_trickle_drive_40xx(vdev, true); + ndelay(500); pwr_island_drive_40xx(vdev, true); } } -- GitLab From 26d07937190f36298d63877fb9c6b372c4b1cf18 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:01 +0200 Subject: [PATCH 176/456] UPSTREAM: accel/ivpu: Turn on autosuspend on Simics With recent Simics update DVFS flows using cdyn were fixed and it is possible to enable D0i3/D3 entry flows on autosuspend. Set autosuspend timeout to 100 ms by default on Simics. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-11-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 03b3b6657db541e41620050816c55f1750f07bd4) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I9c24c0e32259dc36ac75dbe9ddc6e6c9a528aecc Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057340 Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 85219e9596215..1c259d7178151 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -94,7 +94,7 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; - vdev->timeout.autosuspend = -1; + vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 100; vdev->timeout.state_dump_msg = 10; } else { -- GitLab From 01a945a4df0d4297cf1a4f9fb736039d89df9262 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:02 +0200 Subject: [PATCH 177/456] UPSTREAM: accel/ivpu: Add FW version debugfs entry Add debugfs that prints current firmware version string on read. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-12-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 2baf2143dd406ce7ffb847a03ad40e3cc99322fa) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Idbbc60f16786bb6c3d6e0575df2ecbdf592a99d6 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057341 Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index cfc71f99433f3..3d4a6287727c3 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -43,6 +43,14 @@ static int fw_name_show(struct seq_file *s, void *v) return 0; } +static int fw_version_show(struct seq_file *s, void *v) +{ + struct ivpu_device *vdev = seq_to_ivpu(s); + + seq_printf(s, "%s\n", vdev->fw->version); + return 0; +} + static int fw_trace_capability_show(struct seq_file *s, void *v) { struct ivpu_device *vdev = seq_to_ivpu(s); @@ -109,6 +117,7 @@ static int reset_pending_show(struct seq_file *s, void *v) static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, + {"fw_version", fw_version_show, 0}, {"fw_trace_capability", fw_trace_capability_show, 0}, {"fw_trace_config", fw_trace_config_show, 0}, {"last_bootmode", last_bootmode_show, 0}, -- GitLab From 78b0021e2fbf01b4f0433bd7ce08e122dce95f27 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:03 +0200 Subject: [PATCH 178/456] UPSTREAM: accel/ivpu: Stop using hardcoded DRIVER_DATE Hardcoded driver date is useless, so use kernel version as a driver date to make identifying .ko file easier. Also allow to pass DRIVER_DATE on build time to allow versioning the driver in case it is built out of the tree. Reviewed-by: Karol Wachowski Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-13-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit e38501cee5364aeb3bd265b484a8e47baa6634aa) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: If5d084fbec07593cc9e9522179cd99b6a62448de Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057342 Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 15 +++++++++++---- drivers/accel/ivpu/ivpu_drv.h | 1 - include/uapi/drm/ivpu_accel.h | 3 --- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 38b4158f52784..9fd371af5814c 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -32,8 +33,7 @@ #include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR -#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ - __stringify(DRM_IVPU_DRIVER_MINOR) "." +#define DRIVER_VERSION_STR "1.0.0 " UTS_RELEASE #endif static struct lock_class_key submitted_jobs_xa_lock_class_key; @@ -447,9 +447,16 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, + +#ifdef DRIVER_DATE .date = DRIVER_DATE, - .major = DRM_IVPU_DRIVER_MAJOR, - .minor = DRM_IVPU_DRIVER_MINOR, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +#else + .date = UTS_RELEASE, + .major = 1, +#endif }; static void ivpu_context_abort_invalid(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 2b30cc2e9272e..471478281021d 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -21,7 +21,6 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" -#define DRIVER_DATE "20230117" #define PCI_DEVICE_ID_MTL 0x7d1d #define PCI_DEVICE_ID_ARL 0xad1d diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 084fb529e1e96..234664d352507 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -12,9 +12,6 @@ extern "C" { #endif -#define DRM_IVPU_DRIVER_MAJOR 1 -#define DRM_IVPU_DRIVER_MINOR 0 - #define DRM_IVPU_GET_PARAM 0x00 #define DRM_IVPU_SET_PARAM 0x01 #define DRM_IVPU_BO_CREATE 0x02 -- GitLab From 867c286db800601cc54dc539efb842f0c1665893 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:04 +0200 Subject: [PATCH 179/456] UPSTREAM: accel/ivpu: Remove 1-tile power up Simics workaround Previously Simics was not providing workpoint for configurations with 0 tiles enabled, that had to be worked around in the KMD. This got fixed in Simics and workaround is no longer needed. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-14-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 378ed3b64d5409fa602e05f7ff49dfb4b08ff747) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I6157463080bb1f98acd6ed59c5bc17376ca18e71 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057343 Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw_btrs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 745e5248803da..cad2ce7f2e244 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -315,10 +315,6 @@ static void prepare_wp_request(struct ivpu_device *vdev, struct wp_request *wp, wp->cdyn = enable ? PLL_CDYN_DEFAULT : 0; wp->epp = enable ? PLL_EPP_DEFAULT : 0; } - - /* Simics cannot start without at least one tile */ - if (enable && ivpu_is_simics(vdev)) - wp->cfg = 1; } static int wait_for_pll_lock(struct ivpu_device *vdev, bool enable) -- GitLab From d6a9ac949d7eeebb52c71e91000fa630612c1a04 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Mon, 30 Sep 2024 21:53:05 +0200 Subject: [PATCH 180/456] UPSTREAM: accel/ivpu: Allow reading dvfs_mode debugfs file Make the dvfs_mode read-write to allow checking current mode. Simplify the dvfs_mode implementation with the DEFINE_DEBUGFS_ATTRIBUTE. Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-15-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 9f3814e822133b9001d8deb7d3903e2adb656819) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: If6633188f08ab07bf8caf85809331dbef1f1f982 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057344 Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_debugfs.c | 33 +++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 3d4a6287727c3..caae16282fdaa 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -125,32 +125,23 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"reset_pending", reset_pending_show, 0}, }; -static ssize_t -dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int dvfs_mode_get(void *data, u64 *dvfs_mode) { - struct ivpu_device *vdev = file->private_data; - struct ivpu_fw_info *fw = vdev->fw; - u32 dvfs_mode; - int ret; + struct ivpu_device *vdev = (struct ivpu_device *)data; - ret = kstrtou32_from_user(user_buf, size, 0, &dvfs_mode); - if (ret < 0) - return ret; - - fw->dvfs_mode = dvfs_mode; + *dvfs_mode = vdev->fw->dvfs_mode; + return 0; +} - ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); - if (ret) - return ret; +static int dvfs_mode_set(void *data, u64 dvfs_mode) +{ + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + vdev->fw->dvfs_mode = (u32)dvfs_mode; + return pci_try_reset_function(to_pci_dev(vdev->drm.dev)); } -static const struct file_operations dvfs_mode_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = dvfs_mode_fops_write, -}; +DEFINE_DEBUGFS_ATTRIBUTE(dvfs_mode_fops, dvfs_mode_get, dvfs_mode_set, "%llu\n"); static ssize_t fw_dyndbg_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) @@ -430,7 +421,7 @@ void ivpu_debugfs_init(struct ivpu_device *vdev) debugfs_create_file("force_recovery", 0200, debugfs_root, vdev, &ivpu_force_recovery_fops); - debugfs_create_file("dvfs_mode", 0200, debugfs_root, vdev, + debugfs_create_file("dvfs_mode", 0644, debugfs_root, vdev, &dvfs_mode_fops); debugfs_create_file("fw_dyndbg", 0200, debugfs_root, vdev, -- GitLab From c016dd807e24c6c39bff0fffdd5cce613bf762cc Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:06 +0200 Subject: [PATCH 181/456] UPSTREAM: accel/ivpu: Add one jiffy to bo_wait_ioctl timeout value Add one jiffy to ensure wait function never times out before intended timeout value, which could happen if absolute timeout value is less than (1s / CONFIG_HZ) in the future. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-16-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 707542dd1a56d23387dbf978bf107793840310cc) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ia16a9365c3117de9fda08bfc52432023056c70c3 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6057345 Reviewed-by: Sean Paul Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index 1b409dbd332d8..d8e97a760fbc0 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -384,6 +384,9 @@ int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file timeout = drm_timeout_abs_to_jiffies(args->timeout_ns); + /* Add 1 jiffy to ensure the wait function never times out before intended timeout_ns */ + timeout += 1; + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -EINVAL; -- GitLab From 4b6084abdcd832b6f8b52b823458c572c5a7906b Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:07 +0200 Subject: [PATCH 182/456] UPSTREAM: accel/ivpu: Add auto selection logic for job scheduler Add ivpu_fw_sched_mode_select() function that can select scheduling mode based on HW and FW versions. This prepares for a switch to HWS on selected platforms. Reviewed-by: Karol Wachowski Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-17-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 436b67d6936b5658426e40d0df8f147239bc532b) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I0d381b2c69ec655665a0336f8a6d848fe777defa Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059148 Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 6 +++--- drivers/accel/ivpu/ivpu_drv.h | 2 ++ drivers/accel/ivpu/ivpu_fw.c | 15 +++++++++++++-- drivers/accel/ivpu/ivpu_fw.h | 3 +++ drivers/accel/ivpu/ivpu_hw.h | 1 - drivers/accel/ivpu/ivpu_hw_btrs.c | 2 -- drivers/accel/ivpu/ivpu_job.c | 14 +++++++------- drivers/accel/ivpu/ivpu_sysfs.c | 24 ++++++++++++++++++++++++ 8 files changed, 52 insertions(+), 15 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 9fd371af5814c..fcf26e6d4e9c2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -54,9 +54,9 @@ u8 ivpu_pll_max_ratio = U8_MAX; module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644); MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency"); -int ivpu_sched_mode; +int ivpu_sched_mode = IVPU_SCHED_MODE_AUTO; module_param_named(sched_mode, ivpu_sched_mode, int, 0444); -MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler"); +MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler, 1 - Use HW scheduler"); bool ivpu_disable_mmu_cont_pages; module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444); @@ -347,7 +347,7 @@ static int ivpu_hw_sched_init(struct ivpu_device *vdev) { int ret = 0; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_setup_priority_bands(vdev); if (ret) { ivpu_err(vdev, "Failed to enable hw scheduler: %d", ret); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 471478281021d..c4bd8757f8ded 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -56,6 +56,8 @@ #define IVPU_PLATFORM_FPGA 3 #define IVPU_PLATFORM_INVALID 8 +#define IVPU_SCHED_MODE_AUTO -1 + #define IVPU_DBG_REG BIT(0) #define IVPU_DBG_IRQ BIT(1) #define IVPU_DBG_MMU BIT(2) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 7e8593c831ec2..4d59dd19f6847 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -134,6 +134,15 @@ static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range return true; } +static u32 +ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr) +{ + if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO) + return ivpu_sched_mode; + + return VPU_SCHEDULING_MODE_OS; +} + static int ivpu_fw_parse(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; @@ -215,8 +224,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->dvfs_mode = 0; + fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; + ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, fw_hdr->ro_section_size, @@ -605,8 +616,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->punit_telemetry_sram_base = ivpu_hw_telemetry_offset_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_telemetry_size_get(vdev); boot_params->vpu_telemetry_enable = ivpu_hw_telemetry_enable_get(vdev); - boot_params->vpu_scheduling_mode = vdev->hw->sched_mode; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) + boot_params->vpu_scheduling_mode = vdev->fw->sched_mode; + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) boot_params->vpu_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS; boot_params->dvfs_mode = vdev->fw->dvfs_mode; if (!IVPU_WA(disable_d0i3_msg)) diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 5e8eb608b70f1..1d0b2bd9d65cf 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -6,6 +6,8 @@ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ +#include "vpu_jsm_api.h" + #define FW_VERSION_HEADER_SIZE SZ_4K #define FW_VERSION_STR_SIZE SZ_256 @@ -36,6 +38,7 @@ struct ivpu_fw_info { u32 secondary_preempt_buf_size; u64 read_only_addr; u32 read_only_size; + u32 sched_mode; }; int ivpu_fw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index 1c0c98e3afb88..dc5518248c405 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -46,7 +46,6 @@ struct ivpu_hw_info { u32 profiling_freq; } pll; u32 tile_fuse; - u32 sched_mode; u32 sku; u16 config; int dma_bits; diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index cad2ce7f2e244..7dc8e333dcec2 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -163,7 +163,6 @@ static int info_init_mtl(struct ivpu_device *vdev) hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; hw->sku = BTRS_MTL_TILE_SKU_BOTH; hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO; - hw->sched_mode = ivpu_sched_mode; return 0; } @@ -178,7 +177,6 @@ static int info_init_lnl(struct ivpu_device *vdev) if (ret) return ret; - hw->sched_mode = ivpu_sched_mode; hw->tile_fuse = tile_fuse_config; hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b00634af8bc34..b1abdca5891cd 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -37,7 +37,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); struct ivpu_addr_range range; - if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); @@ -68,7 +68,7 @@ err_free_primary: static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { - if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return; drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); @@ -149,7 +149,7 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * struct ivpu_device *vdev = file_priv->vdev; int ret; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else @@ -184,7 +184,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->tail = 0; wmb(); /* Flush WC buffer for jobq->header */ - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); if (ret) return ret; @@ -211,7 +211,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); if (!ret) ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); @@ -335,7 +335,7 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) ivpu_cmdq_fini_all(file_priv); - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS) + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS) ivpu_jsm_context_release(vdev, file_priv->ctx.id); } @@ -361,7 +361,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW && + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c index 913669f1786e8..616477fc17fa0 100644 --- a/drivers/accel/ivpu/ivpu_sysfs.c +++ b/drivers/accel/ivpu/ivpu_sysfs.c @@ -6,6 +6,8 @@ #include #include +#include "ivpu_drv.h" +#include "ivpu_fw.h" #include "ivpu_hw.h" #include "ivpu_sysfs.h" @@ -39,8 +41,30 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b static DEVICE_ATTR_RO(npu_busy_time_us); +/** + * DOC: sched_mode + * + * The sched_mode is used to report current NPU scheduling mode. + * + * It returns following strings: + * - "HW" - Hardware Scheduler mode + * - "OS" - Operating System Scheduler mode + * + */ +static ssize_t +sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct drm_device *drm = dev_get_drvdata(dev); + struct ivpu_device *vdev = to_ivpu_device(drm); + + return sysfs_emit(buf, "%s\n", vdev->fw->sched_mode ? "HW" : "OS"); +} + +static DEVICE_ATTR_RO(sched_mode); + static struct attribute *ivpu_dev_attrs[] = { &dev_attr_npu_busy_time_us.attr, + &dev_attr_sched_mode.attr, NULL, }; -- GitLab From 0ae6dbbdcaf00b28ef064d023f887ad7c90c5212 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:08 +0200 Subject: [PATCH 183/456] UPSTREAM: accel/ivpu: Print JSM message result in case of error Change debug message to error level in case of receiving non-successful result of JSM message. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-18-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 3886f9440aa3a5b55f2f2030f8a6fdab5b41fbd1) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I19bb052532d47341fedec1a7d814248c5720a34d Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059149 Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 008fda068d18e..e4e64bbf4ef61 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -278,7 +278,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) { - ivpu_dbg(vdev, IPC, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); + ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); ret = -EBADMSG; } -- GitLab From 8a4109b538d472d4be974e1f7dedf225b4e31245 Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz Date: Mon, 30 Sep 2024 21:53:09 +0200 Subject: [PATCH 184/456] UPSTREAM: accel/ivpu: Make DB_ID and JOB_ID allocations incremental Save last used ID and use it to limit the possible values for the ID. This should decrease the rate at which the IDs are reused, which will make debugging easier. Signed-off-by: Tomasz Rusinowicz Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-19-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit c3b0ec0fe0c7ebc4eb42ba60f7340ecdb7aae1a2) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id2a4a746737aaf5ac4ebab43b52fbc9e9dacd16e Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059150 Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 9 +++++++++ drivers/accel/ivpu/ivpu_drv.h | 7 +++++++ drivers/accel/ivpu/ivpu_job.c | 37 +++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index fcf26e6d4e9c2..ffb8309a4f657 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -260,6 +260,11 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) if (ret) goto err_xa_erase; + file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, + (file_priv->ctx.id - 1)); + file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; + file_priv->job_limit = file_priv->default_job_limit; + mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -614,6 +619,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); + vdev->default_db_limit.min = IVPU_MIN_DB; + vdev->default_db_limit.max = IVPU_MAX_DB; + vdev->db_limit = vdev->default_db_limit; + ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) goto err_xa_destroy; diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index c4bd8757f8ded..9acef14deab57 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -45,6 +45,9 @@ #define IVPU_MIN_DB 1 #define IVPU_MAX_DB 255 +#define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) +#define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) + #define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) @@ -135,6 +138,8 @@ struct ivpu_device { struct xa_limit context_xa_limit; struct xarray db_xa; + struct xa_limit db_limit; + struct xa_limit default_db_limit; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -170,6 +175,8 @@ struct ivpu_file_priv { struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; + struct xa_limit job_limit; + struct xa_limit default_job_limit; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b1abdca5891cd..8798fb2046abc 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -21,8 +21,6 @@ #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 -#define JOB_ID_JOB_MASK GENMASK(7, 0) -#define JOB_ID_CONTEXT_MASK GENMASK(31, 8) #define JOB_MAX_BUFFER_COUNT 65535 static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq) @@ -77,9 +75,28 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } +static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, + const struct xa_limit default_limit) +{ + int ret; + + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) { + limit->min = default_limit.min; + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) + return ret; + } + + limit->min = *id + 1; + if (limit->min > limit->max) + limit->min = default_limit.min; + + return ret; +} + static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { - struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB}; struct ivpu_device *vdev = file_priv->vdev; struct ivpu_cmdq *cmdq; int ret; @@ -88,7 +105,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - ret = xa_alloc(&vdev->db_xa, &cmdq->db_id, NULL, db_xa_limit, GFP_KERNEL); + xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ + ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, + vdev->default_db_limit); + xa_unlock(&vdev->db_xa); if (ret) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; @@ -519,7 +539,6 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) { struct ivpu_file_priv *file_priv = job->file_priv; struct ivpu_device *vdev = job->vdev; - struct xa_limit job_id_range; struct ivpu_cmdq *cmdq; bool is_first_job; int ret; @@ -530,7 +549,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority); + cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); @@ -538,12 +557,10 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) goto err_unlock_file_priv; } - job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); - job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; - xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); + ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, + file_priv->default_job_limit); if (ret) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); -- GitLab From cecc8907def4d1cb313d01a72bed55585ec29a88 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Mon, 30 Sep 2024 21:53:10 +0200 Subject: [PATCH 185/456] UPSTREAM: accel/ivpu: Add test_mode bit to force turbo Add new test_mode BIT(9) that forces firmware to enable turbo burst mode. Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-20-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 7459211aa6352c219169c6bc9d1b0caf24e1ffd2) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I7f513dbf927dee92289bf4ac0c9b3d9ee235cd06 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059151 Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.h | 1 + drivers/accel/ivpu/ivpu_job.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 9acef14deab57..151ab9f2ddc9b 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,6 +197,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) #define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) +#define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 8798fb2046abc..dc5cf7ded9439 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -202,6 +202,11 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->engine_idx = engine; jobq_header->head = 0; jobq_header->tail = 0; + if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { + ivpu_dbg(vdev, JOB, "Turbo mode enabled"); + jobq_header->flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE; + } + wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { -- GitLab From c4266f26621988a2898e85df1fb0fae007495f17 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:11 +0200 Subject: [PATCH 186/456] UPSTREAM: accel/ivpu: Remove skip of clock own resource ack on Simics With recent Simics model update CLOCK_RESOURCE_OWN_ACK signal was implemented as part of VPU STATUS register and workaround is no longer needed. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-21-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 8c3c5f84370cc076b1af2da09a89ce74292d186e) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Idb7a5cb73c6a6867a0883aed7c48870f029b65b0 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059152 Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw_btrs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 7dc8e333dcec2..6d5f1cc711435 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -459,9 +459,6 @@ int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev) if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) return 0; - if (ivpu_is_simics(vdev)) - return 0; - return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US); } -- GitLab From 28458004793ed2561fa3fd2a245155440e4f1686 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Mon, 30 Sep 2024 21:53:12 +0200 Subject: [PATCH 187/456] UPSTREAM: accel/ivpu: Fix reset_engine debugfs file logic The current reset_engine implementation unconditionally resets all engines. Improve implementation to reset only the engine requested by the user space to allow more granular testing. Also use DEFINE_DEBUGFS_ATTRIBUTE() to simplify implementation. Same changes applied to resume_engine debugfs file for consistency. Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-22-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 541a137254c71822e7a3ebdf8309c5a37b7de465) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I8b7db83f7606e33d8ac59620cc488f51334ee8ab Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059153 Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_debugfs.c | 42 ++++++------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index caae16282fdaa..98e1363194902 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -335,49 +335,23 @@ static const struct file_operations ivpu_force_recovery_fops = { .write = ivpu_force_recovery_fn, }; -static ssize_t -ivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int ivpu_reset_engine_fn(void *data, u64 val) { - struct ivpu_device *vdev = file->private_data; - - if (!size) - return -EINVAL; - - if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) - return -ENODEV; - if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY)) - return -ENODEV; + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + return ivpu_jsm_reset_engine(vdev, (u32)val); } -static const struct file_operations ivpu_reset_engine_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = ivpu_reset_engine_fn, -}; +DEFINE_DEBUGFS_ATTRIBUTE(ivpu_reset_engine_fops, NULL, ivpu_reset_engine_fn, "0x%02llx\n"); -static ssize_t -ivpu_resume_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int ivpu_resume_engine_fn(void *data, u64 val) { - struct ivpu_device *vdev = file->private_data; - - if (!size) - return -EINVAL; - - if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) - return -ENODEV; - if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COPY)) - return -ENODEV; + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + return ivpu_jsm_hws_resume_engine(vdev, (u32)val); } -static const struct file_operations ivpu_resume_engine_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = ivpu_resume_engine_fn, -}; +DEFINE_DEBUGFS_ATTRIBUTE(ivpu_resume_engine_fops, NULL, ivpu_resume_engine_fn, "0x%02llx\n"); static int dct_active_get(void *data, u64 *active_percent) { -- GitLab From 1b48529038b09afc0b9ad53692a5c892bfbff5a8 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:13 +0200 Subject: [PATCH 188/456] UPSTREAM: accel/ivpu: Prevent recovery invocation during probe and resume Refactor IPC send and receive functions to allow correct handling of operations that should not trigger a recovery process. Expose ivpu_send_receive_internal(), which is now utilized by the D0i3 entry, DCT initialization, and HWS initialization functions. These functions have been modified to return error codes gracefully, rather than initiating recovery. The updated functions are invoked within ivpu_probe() and ivpu_resume(), ensuring that any errors encountered during these stages result in a proper teardown or shutdown sequence. The previous approach of triggering recovery within these functions could lead to a race condition, potentially causing undefined behavior and kernel crashes due to null pointer dereferences. Fixes: 45e45362e095 ("accel/ivpu: Introduce ivpu_ipc_send_receive_active()") Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-23-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 5eaa497411197c41b0813d61ba3fbd6267049082) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I53885e7f8de61d95bd32c55569a18767b7af3d53 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059154 Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_ipc.c | 35 +++++++++++-------------------- drivers/accel/ivpu/ivpu_ipc.h | 7 +++---- drivers/accel/ivpu/ivpu_jsm_msg.c | 19 +++++++---------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index e4e64bbf4ef61..d3fa787f562ae 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -291,15 +291,16 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, return ret; } -static int +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp_type, - struct vpu_jsm_msg *resp, u32 channel, - unsigned long timeout_ms) + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms) { struct ivpu_ipc_consumer cons; int ret; + drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); ret = ivpu_ipc_send(vdev, &cons, req); @@ -325,19 +326,21 @@ consumer_del: return ret; } -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) +int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms) { struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB }; struct vpu_jsm_msg hb_resp; int ret, hb_ret; - drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms); if (ret != -ETIMEDOUT) - return ret; + goto rpm_put; hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, @@ -345,21 +348,7 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r if (hb_ret == -ETIMEDOUT) ivpu_pm_trigger_recovery(vdev, "IPC timeout"); - return ret; -} - -int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) -{ - int ret; - - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return ret; - - ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms); - +rpm_put: ivpu_rpm_put(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 6bbe6e32c8749..b4dfb504679ba 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -101,10 +101,9 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg, unsigned long timeout_ms); - -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms); +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp_type, + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index cd33964d292bc..ae91ad24d10d8 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -271,9 +271,8 @@ int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev) req.payload.pwr_d0i3_enter.send_response = 1; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, - &resp, VPU_IPC_CHAN_GEN_CMD, - vdev->timeout.d0i3_entry_msg); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, &resp, + VPU_IPC_CHAN_GEN_CMD, vdev->timeout.d0i3_entry_msg); if (ret) return ret; @@ -431,8 +430,8 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev) req.payload.hws_priority_band_setup.normal_band_percentage = 10; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, - &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, + &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to set priority bands: %d\n", ret); @@ -545,9 +544,8 @@ int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us req.payload.pwr_dct_control.dct_active_us = active_us; req.payload.pwr_dct_control.dct_inactive_us = inactive_us; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } int ivpu_jsm_dct_disable(struct ivpu_device *vdev) @@ -555,9 +553,8 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE }; struct vpu_jsm_msg resp; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } int ivpu_jsm_state_dump(struct ivpu_device *vdev) -- GitLab From 5aea179a998163ae92be053986acd76e6f184872 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:14 +0200 Subject: [PATCH 189/456] UPSTREAM: accel/ivpu: Refactor failure diagnostics during boot Move diagnostic functions to common error handling within ivpu_boot() function to ensure diagnostics are gathered even in cases where NPU fails after successful boot (DCT and HWS init failures). Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-24-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit cc3c72c7e6101de86cdd7bee8d9765480d8a1720) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ica66e80f1f25d51bbe4af617ec09e912babfb372 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059155 Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ffb8309a4f657..14c2412c6f8e6 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -386,10 +386,7 @@ int ivpu_boot(struct ivpu_device *vdev) ret = ivpu_wait_for_ready(vdev); if (ret) { ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); - ivpu_hw_diagnose_failure(vdev); - ivpu_mmu_evtq_dump(vdev); - ivpu_dev_coredump(vdev); - return ret; + goto err_diagnose_failure; } ivpu_hw_irq_clear(vdev); @@ -400,12 +397,20 @@ int ivpu_boot(struct ivpu_device *vdev) if (ivpu_fw_is_cold_boot(vdev)) { ret = ivpu_pm_dct_init(vdev); if (ret) - return ret; + goto err_diagnose_failure; - return ivpu_hw_sched_init(vdev); + ret = ivpu_hw_sched_init(vdev); + if (ret) + goto err_diagnose_failure; } return 0; + +err_diagnose_failure: + ivpu_hw_diagnose_failure(vdev); + ivpu_mmu_evtq_dump(vdev); + ivpu_dev_coredump(vdev); + return ret; } void ivpu_prepare_for_reset(struct ivpu_device *vdev) -- GitLab From e3955ad993261fa7224b874e052310c8f540adee Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:15 +0200 Subject: [PATCH 190/456] UPSTREAM: accel/ivpu: Remove invalid warnings Warn in ivpu_file_priv_put() checks a pointer that is previously accessed. Warn in ivpu_ipc_fini() can be triggered even in valid cases where IPC is disabled upon closing the device. Reviewed-by: Karol Wachowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-25-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 1bc92a517bb4ba3f1372793b782ea18e96432170) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I90fe4678d922c0f46b72a576f7ab2c8847069c9b Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059156 Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 2 -- drivers/accel/ivpu/ivpu_ipc.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 14c2412c6f8e6..dc983140128b4 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -117,8 +117,6 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link) struct ivpu_file_priv *file_priv = *link; struct ivpu_device *vdev = file_priv->vdev; - drm_WARN_ON(&vdev->drm, !file_priv); - ivpu_dbg(vdev, KREF, "file_priv put: ctx %u refcount %u\n", file_priv->ctx.id, kref_read(&file_priv->ref)); diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index d3fa787f562ae..8d8a037b57ecf 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -533,7 +533,6 @@ void ivpu_ipc_fini(struct ivpu_device *vdev) { struct ivpu_ipc_info *ipc = vdev->ipc; - drm_WARN_ON(&vdev->drm, ipc->on); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cons_list)); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cb_msg_list)); drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0); -- GitLab From b475447b82107000dcfa8c5507e7ec28497c1053 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:16 +0200 Subject: [PATCH 191/456] UPSTREAM: accel/ivpu: Do not fail on cmdq if failed to allocate preemption buffers Allow to proceed with job command queue creation even if preemption buffers failed to be allocated, print warning that preemption on such command queue will be disabled. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-26-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 08eb99ce911d3ea202f79b42b96cd6e8498f7f69) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ibcba330cbcf40b7cdb744430a7fd7009b9b50094 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059157 Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_job.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index dc5cf7ded9439..48272bc853e0c 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -60,6 +60,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, err_free_primary: ivpu_bo_free(cmdq->primary_preempt_buf); + cmdq->primary_preempt_buf = NULL; return -ENOMEM; } @@ -69,10 +70,10 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return; - drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); - drm_WARN_ON(&vdev->drm, !cmdq->secondary_preempt_buf); - ivpu_bo_free(cmdq->primary_preempt_buf); - ivpu_bo_free(cmdq->secondary_preempt_buf); + if (cmdq->primary_preempt_buf) + ivpu_bo_free(cmdq->primary_preempt_buf); + if (cmdq->secondary_preempt_buf) + ivpu_bo_free(cmdq->secondary_preempt_buf); } static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, @@ -120,12 +121,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) - goto err_free_cmdq_mem; + ivpu_warn(vdev, "Failed to allocate preemption buffers, preemption limited\n"); return cmdq; -err_free_cmdq_mem: - ivpu_bo_free(cmdq->mem); err_erase_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: @@ -388,10 +387,16 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { - entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; - entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); - entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; - entry->secondary_preempt_buf_size = ivpu_bo_size(cmdq->secondary_preempt_buf); + if (cmdq->primary_preempt_buf) { + entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; + entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); + } + + if (cmdq->secondary_preempt_buf) { + entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; + entry->secondary_preempt_buf_size = + ivpu_bo_size(cmdq->secondary_preempt_buf); + } } wmb(); /* Ensure that tail is updated after filling entry */ -- GitLab From 2134003a69aa3fbfeba00c7da4cbf687813ca343 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Mon, 30 Sep 2024 21:53:17 +0200 Subject: [PATCH 192/456] UPSTREAM: accel/ivpu: Use whole user and shave ranges for preemption buffers Do not restrict range for preemption buffers allocation just to the end of user and shave ranges, use them whole instead to avoid situation where end of range might be already allocated causing preemption buffers allocation to fail. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-27-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 755fb86789165dca776e69631a4ed332f0341e29) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I717d440ccf6db817bd1c47e3a7c101099359f4ff Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059158 Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_job.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 48272bc853e0c..cd41b87715056 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -33,24 +33,19 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, { u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - struct ivpu_addr_range range; if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; - range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); - range.end = vdev->hw->ranges.user.end; - cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, primary_size, - DRM_IVPU_BO_WC); + cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, + primary_size, DRM_IVPU_BO_WC); if (!cmdq->primary_preempt_buf) { ivpu_err(vdev, "Failed to create primary preemption buffer\n"); return -ENOMEM; } - range.start = vdev->hw->ranges.shave.end - (secondary_size * IVPU_NUM_CMDQS_PER_CTX); - range.end = vdev->hw->ranges.shave.end; - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, secondary_size, - DRM_IVPU_BO_WC); + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, + secondary_size, DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); goto err_free_primary; -- GitLab From 8fd5908f7157cc18f8658e42b9948608e524980d Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:18 +0200 Subject: [PATCH 193/456] UPSTREAM: accel/ivpu: Increase MS info buffer size Increase MS info BO to 64KB to allow collecting more metrics. Reviewed-by: Karol Wachowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-28-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 98110eb5924bd9a718a1e3a4e16527ed4f84910d) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ic3d6e9ee62641041ef557e9c1681bd35513f1d09 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059159 Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index 2f9d37f5c208a..ffe7b10f8a767 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -11,7 +11,7 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" -#define MS_INFO_BUFFER_SIZE SZ_16K +#define MS_INFO_BUFFER_SIZE SZ_64K #define MS_NUM_BUFFERS 2 #define MS_READ_PERIOD_MULTIPLIER 2 #define MS_MIN_SAMPLE_PERIOD_NS 1000000 -- GitLab From 86f534caade16372e82be4795b42619caada9db9 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:19 +0200 Subject: [PATCH 194/456] UPSTREAM: accel/ivpu: Fix ivpu_jsm_dyndbg_control() Use correct channel for dyndbg JSM message. Reviewed-by: Karol Wachowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-29-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit ed3fb318fd681bc226be3b309a1c658d231a282b) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I3420704c7a817c6385246da756e05b4c53c37747 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059160 Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_jsm_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index ae91ad24d10d8..494ebc2475b19 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -197,7 +197,7 @@ int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size strscpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN); ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp, - VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + VPU_IPC_CHAN_GEN_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to send command \"%s\": ret %d\n", command, ret); -- GitLab From 67f8a510d0743e36b1fab6f1d3616c167d40c8fa Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:20 +0200 Subject: [PATCH 195/456] UPSTREAM: accel/ivpu: Remove HWS_EXTRA_EVENTS from test modes IVPU_TEST_MODE_HWS_EXTRA_EVENTS was never used and can be safely removed Reviewed-by: Karol Wachowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-30-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 3e521803e552e5cfee1a3011d14a5f75b938a0c2) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I7c11fad33f1d709b7fd263b34065c23568476d35 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059161 Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.h | 1 - drivers/accel/ivpu/ivpu_jsm_msg.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 151ab9f2ddc9b..5b43f91f20155 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -195,7 +195,6 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) -#define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 494ebc2475b19..8f5d904ca1ed4 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -394,8 +394,6 @@ int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u3 req.payload.hws_set_scheduling_log.host_ssid = host_ssid; req.payload.hws_set_scheduling_log.vpu_log_buffer_va = vpu_log_buffer_va; req.payload.hws_set_scheduling_log.notify_index = 0; - req.payload.hws_set_scheduling_log.enable_extra_events = - ivpu_test_mode & IVPU_TEST_MODE_HWS_EXTRA_EVENTS; ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); -- GitLab From 247e0f02d0075cef7f5a27fd0861d7464b4b89b9 Mon Sep 17 00:00:00 2001 From: Jakub Pawlak Date: Mon, 30 Sep 2024 21:53:21 +0200 Subject: [PATCH 196/456] UPSTREAM: accel/ivpu: Add tracing for IPC/PM/JOB Add multiple trace points in couple of key places to enable tracing with ftrace. Signed-off-by: Jakub Pawlak Reviewed-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-31-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 7cb8d38a068291c9fdc182c177e42a1aa3eea97b) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id1a44e3a7d3fd1c7e6128b2e2c272edb609412b9 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059162 Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/Makefile | 5 +- drivers/accel/ivpu/ivpu_ipc.c | 3 ++ drivers/accel/ivpu/ivpu_job.c | 4 ++ drivers/accel/ivpu/ivpu_pm.c | 9 ++++ drivers/accel/ivpu/ivpu_trace.h | 73 ++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_trace_points.c | 9 ++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 drivers/accel/ivpu/ivpu_trace.h create mode 100644 drivers/accel/ivpu/ivpu_trace_points.c diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 232ea6d28c6e2..e73937c86d9ad 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -16,9 +16,12 @@ intel_vpu-y := \ ivpu_mmu_context.o \ ivpu_ms.o \ ivpu_pm.o \ - ivpu_sysfs.o + ivpu_sysfs.o \ + ivpu_trace_points.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o + +CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 8d8a037b57ecf..66e485414ba87 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -15,6 +15,7 @@ #include "ivpu_ipc.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #define IPC_MAX_RX_MSG 128 @@ -227,6 +228,7 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, stru goto unlock; ivpu_ipc_tx(vdev, cons->tx_vpu_addr); + trace_jsm("[tx]", req); unlock: mutex_unlock(&ipc->lock); @@ -284,6 +286,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, if (jsm_msg) memcpy(jsm_msg, rx_msg->jsm_msg, size); + trace_jsm("[rx]", rx_msg->jsm_msg); } ivpu_ipc_rx_msg_del(vdev, rx_msg); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index cd41b87715056..98e0b7b614071 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -18,6 +18,7 @@ #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 @@ -482,6 +483,7 @@ ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) job->file_priv = ivpu_file_priv_get(file_priv); + trace_job("create", job); ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); return job; @@ -521,6 +523,7 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job->bos[CMD_BUF_IDX]->job_status = job_status; dma_fence_signal(job->done_fence); + trace_job("done", job); ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); @@ -588,6 +591,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) vdev->busy_start_ts = ktime_get(); } + trace_job("submit", job); ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n", job->job_id, file_priv->ctx.id, job->engine_idx, priority, job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index b5a69941e6e0a..6d180c81e6df9 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -20,6 +20,7 @@ #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #include "vpu_boot_api.h" static bool ivpu_disable_recovery; @@ -198,6 +199,7 @@ int ivpu_pm_suspend_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); unsigned long timeout; + trace_pm("suspend"); ivpu_dbg(vdev, PM, "Suspend..\n"); timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr); @@ -215,6 +217,7 @@ int ivpu_pm_suspend_cb(struct device *dev) ivpu_pm_prepare_warm_boot(vdev); ivpu_dbg(vdev, PM, "Suspend done.\n"); + trace_pm("suspend done"); return 0; } @@ -225,6 +228,7 @@ int ivpu_pm_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; + trace_pm("resume"); ivpu_dbg(vdev, PM, "Resume..\n"); ret = ivpu_resume(vdev); @@ -232,6 +236,7 @@ int ivpu_pm_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to resume: %d\n", ret); ivpu_dbg(vdev, PM, "Resume done.\n"); + trace_pm("resume done"); return ret; } @@ -246,6 +251,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work)); + trace_pm("runtime suspend"); ivpu_dbg(vdev, PM, "Runtime suspend..\n"); ivpu_mmu_disable(vdev); @@ -272,6 +278,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) } ivpu_dbg(vdev, PM, "Runtime suspend done.\n"); + trace_pm("runtime suspend done"); return 0; } @@ -282,6 +289,7 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; + trace_pm("runtime resume"); ivpu_dbg(vdev, PM, "Runtime resume..\n"); ret = ivpu_resume(vdev); @@ -289,6 +297,7 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); ivpu_dbg(vdev, PM, "Runtime resume done.\n"); + trace_pm("runtime resume done"); return ret; } diff --git a/drivers/accel/ivpu/ivpu_trace.h b/drivers/accel/ivpu/ivpu_trace.h new file mode 100644 index 0000000000000..eb792038e7010 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_trace.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#if !defined(__IVPU_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) +#define __IVPU_TRACE_H__ + +#include +#include "ivpu_drv.h" +#include "ivpu_job.h" +#include "vpu_jsm_api.h" +#include "ivpu_jsm_msg.h" +#include "ivpu_ipc.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vpu +#define TRACE_INCLUDE_FILE ivpu_trace + +TRACE_EVENT(pm, + TP_PROTO(const char *event), + TP_ARGS(event), + TP_STRUCT__entry(__field(const char *, event)), + TP_fast_assign(__entry->event = event;), + TP_printk("%s", __entry->event) +); + +TRACE_EVENT(job, + TP_PROTO(const char *event, struct ivpu_job *job), + TP_ARGS(event, job), + TP_STRUCT__entry(__field(const char *, event) + __field(u32, ctx_id) + __field(u32, engine_id) + __field(u32, job_id) + ), + TP_fast_assign(__entry->event = event; + __entry->ctx_id = job->file_priv->ctx.id; + __entry->engine_id = job->engine_idx; + __entry->job_id = job->job_id;), + TP_printk("%s context:%d engine:%d job:%d", + __entry->event, + __entry->ctx_id, + __entry->engine_id, + __entry->job_id) +); + +TRACE_EVENT(jsm, + TP_PROTO(const char *event, struct vpu_jsm_msg *msg), + TP_ARGS(event, msg), + TP_STRUCT__entry(__field(const char *, event) + __field(const char *, type) + __field(enum vpu_ipc_msg_status, status) + __field(u32, request_id) + __field(u32, result) + ), + TP_fast_assign(__entry->event = event; + __entry->type = ivpu_jsm_msg_type_to_str(msg->type); + __entry->status = msg->status; + __entry->request_id = msg->request_id; + __entry->result = msg->result;), + TP_printk("%s type:%s, status:%#x, id:%#x, result:%#x", + __entry->event, + __entry->type, + __entry->status, + __entry->request_id, + __entry->result) +); + +#endif /* __IVPU_TRACE_H__ */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#include diff --git a/drivers/accel/ivpu/ivpu_trace_points.c b/drivers/accel/ivpu/ivpu_trace_points.c new file mode 100644 index 0000000000000..f8fb99de0de32 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_trace_points.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "ivpu_trace.h" +#endif -- GitLab From d46dea2ee71ac863c65f3e1f385f9b277b1dbf79 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Mon, 30 Sep 2024 21:53:22 +0200 Subject: [PATCH 197/456] UPSTREAM: accel/ivpu: Fix typos in ivpu_pm.c Replace "Filed" with an actual word. Reviewed-by: Karol Wachowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-32-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit c4fd5979ce3149b1be37b162be25b9a031d8e7e1) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I088a358912f1b86fb56262661385ac05896588a0 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059163 Reviewed-by: Sean Paul Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 6d180c81e6df9..e567df79a6129 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -423,7 +423,7 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); if (ret) { - ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); return ret; } @@ -440,7 +440,7 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) ret = ivpu_jsm_dct_disable(vdev); if (ret) { - ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); return ret; } -- GitLab From d560cc35f4e698b5f216a1cb4fbab53f5d46be17 Mon Sep 17 00:00:00 2001 From: Maciej Falkowski Date: Fri, 4 Oct 2024 18:25:04 +0200 Subject: [PATCH 198/456] UPSTREAM: accel/ivpu: Add initial Panther Lake support Add support for the 5th generation of Intel NPU that is going to be present in PTL_P (Panther Lake) CPUs. NPU5 code reuses almost all of previous driver code. Signed-off-by: Maciej Falkowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20241004162505.1695605-2-maciej.falkowski@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit c140244f0cfb9601dbc35e7ab90914954a76b3d1) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I353f7009a3bc756af2fa9b8d100b3b0b9b3c9645 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059164 Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 1 + drivers/accel/ivpu/ivpu_drv.h | 10 +++++++--- drivers/accel/ivpu/ivpu_fw.c | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index dc983140128b4..e7d8967c02f29 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -742,6 +742,7 @@ static struct pci_device_id ivpu_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, { } }; MODULE_DEVICE_TABLE(pci, ivpu_pci_ids); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b43f91f20155..f905021ac1748 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -22,9 +22,10 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" -#define PCI_DEVICE_ID_MTL 0x7d1d -#define PCI_DEVICE_ID_ARL 0xad1d -#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_MTL 0x7d1d +#define PCI_DEVICE_ID_ARL 0xad1d +#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_PTL_P 0xb03e #define IVPU_HW_IP_37XX 37 #define IVPU_HW_IP_40XX 40 @@ -224,6 +225,8 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev) return IVPU_HW_IP_37XX; case PCI_DEVICE_ID_LNL: return IVPU_HW_IP_40XX; + case PCI_DEVICE_ID_PTL_P: + return IVPU_HW_IP_50XX; default: dump_stack(); ivpu_err(vdev, "Unknown NPU IP generation\n"); @@ -238,6 +241,7 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_ARL: return IVPU_HW_BTRS_MTL; case PCI_DEVICE_ID_LNL: + case PCI_DEVICE_ID_PTL_P: return IVPU_HW_BTRS_LNL; default: dump_stack(); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 4d59dd19f6847..be367465e7df4 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -57,11 +57,14 @@ static struct { { IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" }, { IVPU_HW_IP_40XX, "vpu_40xx.bin" }, { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" }, + { IVPU_HW_IP_50XX, "vpu_50xx.bin" }, + { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v0.0.bin" }, }; /* Production fw_names from the table above */ MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin"); MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin"); +MODULE_FIRMWARE("intel/vpu/vpu_50xx_v0.0.bin"); static int ivpu_fw_request(struct ivpu_device *vdev) { -- GitLab From e9fbc3b6ea5b06b345a2d73b5e6e1f4b4a2cbb72 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Fri, 4 Oct 2024 18:25:05 +0200 Subject: [PATCH 199/456] UPSTREAM: accel/ivpu: Update power island delays Apply Hardware Architecture Specification compatible delays for main island power delivery for 50xx and above. Signed-off-by: Karol Wachowski Signed-off-by: Maciej Falkowski Reviewed-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/20241004162505.1695605-3-maciej.falkowski@linux.intel.com Signed-off-by: Jacek Lawrynowicz (cherry picked from commit 88bdd1644ca28d48591b2a1e6e8b8c2b13f4bd3f) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Iaf119034c87e13ac19288e89b38e05c9aaae700c Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059165 Reviewed-by: Sean Paul Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw_40xx_reg.h | 2 ++ drivers/accel/ivpu/ivpu_hw_ip.c | 49 +++++++++++++++++---------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h index d0b795b344c7f..fc0ee8d637f96 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h @@ -115,6 +115,8 @@ #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY 0x00030068u #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST_DLY_MASK GENMASK(7, 0) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST1_DLY_MASK GENMASK(15, 8) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST2_DLY_MASK GENMASK(23, 16) #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index cfcbb99168e65..b9b16f4041434 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -8,15 +8,12 @@ #include "ivpu_hw.h" #include "ivpu_hw_37xx_reg.h" #include "ivpu_hw_40xx_reg.h" +#include "ivpu_hw_btrs.h" #include "ivpu_hw_ip.h" #include "ivpu_hw_reg_io.h" #include "ivpu_mmu.h" #include "ivpu_pm.h" -#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 0 -#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH 18 -#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT 3 -#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH 46 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC) #define TIM_SAFE_ENABLE 0xf1d0dead @@ -268,20 +265,15 @@ void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev) idle_gen_drive_40xx(vdev, false); } -static void pwr_island_delay_set_50xx(struct ivpu_device *vdev) +static void +pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status) { - u32 val, post, status; - - if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) { - post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT; - status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT; - } else { - post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH; - status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH; - } + u32 val; val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY); val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val); REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val); val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY); @@ -682,13 +674,36 @@ static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable) REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val); } +static void pwr_island_delay_set(struct ivpu_device *vdev) +{ + bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH; + u32 post, post1, post2, status; + + if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) + return; + + switch (ivpu_device_id(vdev)) { + case PCI_DEVICE_ID_PTL_P: + post = high ? 18 : 0; + post1 = 0; + post2 = 0; + status = high ? 46 : 3; + break; + + default: + dump_stack(); + ivpu_err(vdev, "Unknown device ID\n"); + return; + } + + pwr_island_delay_set_50xx(vdev, post, post1, post2, status); +} + int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev) { int ret; - if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX) - pwr_island_delay_set_50xx(vdev); - + pwr_island_delay_set(vdev); pwr_island_enable(vdev); ret = wait_for_pwr_island_status(vdev, 0x1); -- GitLab From 3685feb472ae10d375d0b79ac884b77694deb95e Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Thu, 17 Oct 2024 16:49:58 +0200 Subject: [PATCH 200/456] UPSTREAM: accel/ivpu: Fix NOC firewall interrupt handling The NOC firewall interrupt means that the HW prevented unauthorized access to a protected resource, so there is no need to trigger device reset in such case. To facilitate security testing add firewall_irq_counter debugfs file that tracks firewall interrupts. Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code") Cc: stable@vger.kernel.org # v6.11+ Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017144958.79327-1-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 72f7e16eccddde99386a10eb2d08833e805917c6) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I6c955890f45ca7b14aec52428d9b219a3dd05cd4 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059166 Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++ drivers/accel/ivpu/ivpu_hw.c | 1 + drivers/accel/ivpu/ivpu_hw.h | 1 + drivers/accel/ivpu/ivpu_hw_ip.c | 5 ++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 98e1363194902..c4b6660d7332b 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -114,6 +114,14 @@ static int reset_pending_show(struct seq_file *s, void *v) return 0; } +static int firewall_irq_counter_show(struct seq_file *s, void *v) +{ + struct ivpu_device *vdev = seq_to_ivpu(s); + + seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter)); + return 0; +} + static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, @@ -123,6 +131,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"last_bootmode", last_bootmode_show, 0}, {"reset_counter", reset_counter_show, 0}, {"reset_pending", reset_pending_show, 0}, + {"firewall_irq_counter", firewall_irq_counter_show, 0}, }; static int dvfs_mode_get(void *data, u64 *dvfs_mode) diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 1c259d7178151..f1f5e0c4961b2 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -252,6 +252,7 @@ int ivpu_hw_init(struct ivpu_device *vdev) platform_init(vdev); wa_init(vdev); timeouts_init(vdev); + atomic_set(&vdev->hw->firewall_irq_counter, 0); return 0; } diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index dc5518248c405..fc4dbfc980c81 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -51,6 +51,7 @@ struct ivpu_hw_info { int dma_bits; ktime_t d0i3_entry_host_ts; u64 d0i3_entry_vpu_ts; + atomic_t firewall_irq_counter; }; int ivpu_hw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index b9b16f4041434..029dd065614b2 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -1073,7 +1073,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev) static void irq_noc_firewall_handler(struct ivpu_device *vdev) { - ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); + atomic_inc(&vdev->hw->firewall_irq_counter); + + ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n", + atomic_read(&vdev->hw->firewall_irq_counter)); } /* Handler for IRQs from NPU core */ -- GitLab From 96235361ed933fafd7de7442d466e338b1394985 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:07 +0200 Subject: [PATCH 201/456] UPSTREAM: accel/ivpu: Do not fail when more than 1 tile is fused Allow TILE_FUSE register to disable more than 1 tile. The driver should not prevent such configurations from being functional. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-2-jacek.lawrynowicz@linux.intel.com (cherry picked from commit ce68f86c445133117a3474987a1fe29be3d6e8e4) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Iea82c53a34e8ed900a0fc29bcc835214b2728610 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059167 Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_hw_btrs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 6d5f1cc711435..3212c99f36823 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -141,16 +141,10 @@ static int read_tile_config_fuse(struct ivpu_device *vdev, u32 *tile_fuse_config } config = REG_GET_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, CONFIG, fuse); - if (!tile_disable_check(config)) { - ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", config); - return -EIO; - } + if (!tile_disable_check(config)) + ivpu_warn(vdev, "More than 1 tile disabled, tile fuse config mask: 0x%x\n", config); - if (config) - ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n", - BTRS_LNL_TILE_MAX_NUM - 1, ffs(config) - 1); - else - ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", BTRS_LNL_TILE_MAX_NUM); + ivpu_dbg(vdev, MISC, "Tile disable config mask: 0x%x\n", config); *tile_fuse_config = config; return 0; -- GitLab From d7decc22a225c102d69a06b113ab782855a7f7e3 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:08 +0200 Subject: [PATCH 202/456] UPSTREAM: accel/ivpu: Defer MMU root page table allocation Defer root page table allocation and unify context init/fini functions. Move allocation of the root page table from the file_priv_open function to perform a lazy allocation approach during ivpu_bo_pin(). By doing so, we avoid the overhead of allocating page tables for simple operations like GET_PARAM that do not require them. Additionally, the MMU context descriptor table initialization has been moved to the ivpu_mmu_context_map_page function. This change streamlines the process and ensures that the descriptor table is only initialized when it is actually needed. Refactor init/fini functions to remove redundant code and make the context management more straightforward. Overall, these changes lead to a reduction in the time taken by the file descriptor open operation, as the costly root page table allocation is now avoided for operations that do not require it. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-3-jacek.lawrynowicz@linux.intel.com (cherry picked from commit a74f4d991352c95b20f445b8b0c99ffa2ef79f8e) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I2f55abde185ce7de3aa39af48623a54c1f5c6a0e Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059168 Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 12 +-- drivers/accel/ivpu/ivpu_mmu.c | 94 ++++++----------- drivers/accel/ivpu/ivpu_mmu.h | 4 +- drivers/accel/ivpu/ivpu_mmu_context.c | 145 +++++++++++++------------- drivers/accel/ivpu/ivpu_mmu_context.h | 9 +- 5 files changed, 115 insertions(+), 149 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index e7d8967c02f29..34e3e9b1c3f23 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -86,7 +86,7 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi ivpu_cmdq_release_all_locked(file_priv); ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); - ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); + ivpu_mmu_context_fini(vdev, &file_priv->ctx); file_priv->bound = false; drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); } @@ -254,9 +254,7 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) goto err_unlock; } - ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); - if (ret) - goto err_xa_erase; + ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); @@ -273,8 +271,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) return 0; -err_xa_erase: - xa_erase_irq(&vdev->context_xa, ctx_id); err_unlock: mutex_unlock(&vdev->context_list_lock); mutex_destroy(&file_priv->ms_lock); @@ -652,9 +648,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev) if (ret) goto err_shutdown; - ret = ivpu_mmu_global_context_init(vdev); - if (ret) - goto err_shutdown; + ivpu_mmu_global_context_init(vdev); ret = ivpu_mmu_init(vdev); if (ret) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index c078e214b2212..4ff0d7a519859 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -696,7 +696,7 @@ unlock: return ret; } -static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) +static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_dma, bool valid) { struct ivpu_mmu_info *mmu = vdev->mmu; struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab; @@ -708,30 +708,29 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) return -EINVAL; entry = cdtab->base + (ssid * IVPU_MMU_CDTAB_ENT_SIZE); - - if (cd_dma != 0) { - cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | - IVPU_MMU_CD_0_TCR_EPD1 | - IVPU_MMU_CD_0_AA64 | - IVPU_MMU_CD_0_R | - IVPU_MMU_CD_0_ASET | - IVPU_MMU_CD_0_V; - cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; - cd[2] = 0; - cd[3] = 0x0000000000007444; - - /* For global context generate memory fault on VPU */ - if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) - cd[0] |= IVPU_MMU_CD_0_A; - } else { - memset(cd, 0, sizeof(cd)); - } + drm_WARN_ON(&vdev->drm, (entry[0] & IVPU_MMU_CD_0_V) == valid); + + cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | + IVPU_MMU_CD_0_TCR_EPD1 | + IVPU_MMU_CD_0_AA64 | + IVPU_MMU_CD_0_R | + IVPU_MMU_CD_0_ASET; + cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; + cd[2] = 0; + cd[3] = 0x0000000000007444; + + /* For global context generate memory fault on VPU */ + if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) + cd[0] |= IVPU_MMU_CD_0_A; + + if (valid) + cd[0] |= IVPU_MMU_CD_0_V; WRITE_ONCE(entry[1], cd[1]); WRITE_ONCE(entry[2], cd[2]); @@ -741,8 +740,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) if (!ivpu_is_force_snoop_enabled(vdev)) clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE); - ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", - cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); + ivpu_dbg(vdev, MMU, "CDTAB set %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", + valid ? "valid" : "invalid", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); mutex_lock(&mmu->lock); if (!mmu->on) @@ -758,33 +757,6 @@ unlock: return ret; } -static int ivpu_mmu_cd_add_gbl(struct ivpu_device *vdev) -{ - int ret; - - ret = ivpu_mmu_cd_add(vdev, 0, vdev->gctx.pgtable.pgd_dma); - if (ret) - ivpu_err(vdev, "Failed to add global CD entry: %d\n", ret); - - return ret; -} - -static int ivpu_mmu_cd_add_user(struct ivpu_device *vdev, u32 ssid, dma_addr_t cd_dma) -{ - int ret; - - if (ssid == 0) { - ivpu_err(vdev, "Invalid SSID: %u\n", ssid); - return -EINVAL; - } - - ret = ivpu_mmu_cd_add(vdev, ssid, cd_dma); - if (ret) - ivpu_err(vdev, "Failed to add CD entry SSID=%u: %d\n", ssid, ret); - - return ret; -} - int ivpu_mmu_init(struct ivpu_device *vdev) { struct ivpu_mmu_info *mmu = vdev->mmu; @@ -808,12 +780,6 @@ int ivpu_mmu_init(struct ivpu_device *vdev) return ret; } - ret = ivpu_mmu_cd_add_gbl(vdev); - if (ret) { - ivpu_err(vdev, "Failed to initialize strtab: %d\n", ret); - return ret; - } - ret = ivpu_mmu_enable(vdev); if (ret) { ivpu_err(vdev, "Failed to resume MMU: %d\n", ret); @@ -966,12 +932,12 @@ void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_GERRORN, gerror_val); } -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) { - return ivpu_mmu_cd_add_user(vdev, ssid, pgtable->pgd_dma); + return ivpu_mmu_cdtab_entry_set(vdev, ssid, pgtable->pgd_dma, true); } -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid) +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid) { - ivpu_mmu_cd_add_user(vdev, ssid, 0); /* 0 will clear CD entry */ + ivpu_mmu_cdtab_entry_set(vdev, ssid, 0, false); } diff --git a/drivers/accel/ivpu/ivpu_mmu.h b/drivers/accel/ivpu/ivpu_mmu.h index 6fa35c2407106..7afea9cd8731d 100644 --- a/drivers/accel/ivpu/ivpu_mmu.h +++ b/drivers/accel/ivpu/ivpu_mmu.h @@ -40,8 +40,8 @@ struct ivpu_mmu_info { int ivpu_mmu_init(struct ivpu_device *vdev); void ivpu_mmu_disable(struct ivpu_device *vdev); int ivpu_mmu_enable(struct ivpu_device *vdev); -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid); +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid); int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid); void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 46d497062041b..43b58016a18f9 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -89,19 +89,6 @@ static void ivpu_pgtable_free_page(struct ivpu_device *vdev, u64 *cpu_addr, dma_ } } -static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) -{ - dma_addr_t pgd_dma; - - pgtable->pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); - if (!pgtable->pgd_dma_ptr) - return -ENOMEM; - - pgtable->pgd_dma = pgd_dma; - - return 0; -} - static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) { int pgd_idx, pud_idx, pmd_idx; @@ -139,6 +126,27 @@ static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgt } ivpu_pgtable_free_page(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma); + pgtable->pgd_dma_ptr = NULL; + pgtable->pgd_dma = 0; +} + +static u64* +ivpu_mmu_ensure_pgd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) +{ + u64 *pgd_dma_ptr = pgtable->pgd_dma_ptr; + dma_addr_t pgd_dma; + + if (pgd_dma_ptr) + return pgd_dma_ptr; + + pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); + if (!pgd_dma_ptr) + return NULL; + + pgtable->pgd_dma_ptr = pgd_dma_ptr; + pgtable->pgd_dma = pgd_dma; + + return pgd_dma_ptr; } static u64* @@ -236,6 +244,12 @@ ivpu_mmu_context_map_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr); int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr); + drm_WARN_ON(&vdev->drm, ctx->id == IVPU_RESERVED_CONTEXT_MMU_SSID); + + /* Allocate PGD - first level page table if needed */ + if (!ivpu_mmu_ensure_pgd(vdev, &ctx->pgtable)) + return -ENOMEM; + /* Allocate PUD - second level page table if needed */ if (!ivpu_mmu_ensure_pud(vdev, &ctx->pgtable, pgd_idx)) return -ENOMEM; @@ -447,12 +461,21 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - mutex_unlock(&ctx->lock); - return ret; + goto err_unlock; } vpu_addr += size; } + if (!ctx->is_cd_valid) { + ret = ivpu_mmu_cd_set(vdev, ctx->id, &ctx->pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", + ctx->id, ret); + goto err_unlock; + } + ctx->is_cd_valid = true; + } + /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); @@ -462,6 +485,11 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); return ret; + +err_unlock: + mutex_unlock(&ctx->lock); + return ret; + } void @@ -529,20 +557,12 @@ ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *n mutex_unlock(&ctx->lock); } -static int -ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) { u64 start, end; - int ret; mutex_init(&ctx->lock); - ret = ivpu_mmu_pgtable_init(vdev, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to initialize pgtable for ctx %u: %d\n", context_id, ret); - return ret; - } - if (!context_id) { start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; @@ -553,41 +573,59 @@ ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u3 drm_mm_init(&ctx->mm, start, end - start); ctx->id = context_id; - - return 0; } -static void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) { - if (drm_WARN_ON(&vdev->drm, !ctx->pgtable.pgd_dma_ptr)) - return; + if (ctx->is_cd_valid) { + ivpu_mmu_cd_clear(vdev, ctx->id); + ctx->is_cd_valid = false; + } mutex_destroy(&ctx->lock); ivpu_mmu_pgtables_free(vdev, &ctx->pgtable); drm_mm_takedown(&ctx->mm); - - ctx->pgtable.pgd_dma_ptr = NULL; - ctx->pgtable.pgd_dma = 0; } -int ivpu_mmu_global_context_init(struct ivpu_device *vdev) +void ivpu_mmu_global_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); + ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); } void ivpu_mmu_global_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_context_fini(vdev, &vdev->gctx); + ivpu_mmu_context_fini(vdev, &vdev->gctx); } int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + int ret; + + ivpu_mmu_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + + mutex_lock(&vdev->rctx.lock); + + if (!ivpu_mmu_ensure_pgd(vdev, &vdev->rctx.pgtable)) { + ivpu_err(vdev, "Failed to allocate root page table for reserved context\n"); + ret = -ENOMEM; + goto unlock; + } + + ret = ivpu_mmu_cd_set(vdev, vdev->rctx.id, &vdev->rctx.pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for reserved context\n"); + goto unlock; + } + +unlock: + mutex_unlock(&vdev->rctx.lock); + return ret; } void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_fini(vdev, &vdev->rctx); + ivpu_mmu_cd_clear(vdev, vdev->rctx.id); + ivpu_mmu_context_fini(vdev, &vdev->rctx); } void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) @@ -602,36 +640,3 @@ void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) xa_unlock(&vdev->context_xa); } - -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id) -{ - int ret; - - drm_WARN_ON(&vdev->drm, !ctx_id); - - ret = ivpu_mmu_context_init(vdev, ctx, ctx_id); - if (ret) { - ivpu_err(vdev, "Failed to initialize context %u: %d\n", ctx_id, ret); - return ret; - } - - ret = ivpu_mmu_set_pgtable(vdev, ctx_id, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to set page table for context %u: %d\n", ctx_id, ret); - goto err_context_fini; - } - - return 0; - -err_context_fini: - ivpu_mmu_context_fini(vdev, ctx); - return ret; -} - -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) -{ - drm_WARN_ON(&vdev->drm, !ctx->id); - - ivpu_mmu_clear_pgtable(vdev, ctx->id); - ivpu_mmu_context_fini(vdev, ctx); -} diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h index 7f9aaf3d10c2f..8042fc0670622 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.h +++ b/drivers/accel/ivpu/ivpu_mmu_context.h @@ -23,19 +23,20 @@ struct ivpu_mmu_pgtable { }; struct ivpu_mmu_context { - struct mutex lock; /* Protects: mm, pgtable */ + struct mutex lock; /* Protects: mm, pgtable, is_cd_valid */ struct drm_mm mm; struct ivpu_mmu_pgtable pgtable; + bool is_cd_valid; u32 id; }; -int ivpu_mmu_global_context_init(struct ivpu_device *vdev); +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id); +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); +void ivpu_mmu_global_context_init(struct ivpu_device *vdev); void ivpu_mmu_global_context_fini(struct ivpu_device *vdev); int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev); void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev); -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id); -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid); int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range, -- GitLab From 1678d468c96734792d80393dd7bd3928ffd6fe1b Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Thu, 17 Oct 2024 16:58:09 +0200 Subject: [PATCH 203/456] UPSTREAM: accel/ivpu: Remove copy engine support Copy engine was deprecated by the FW and is no longer supported. Compute engine includes all copy engine functionality and should be used instead. This change does not affect user space as the copy engine was never used outside of a couple of tests. Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-4-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 94b2a2c0e7cba3f163609dbd94120ee533ad2a07) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I009c1a28d3277bb6413e77594844567574bdced2 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059169 Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.h | 5 +--- drivers/accel/ivpu/ivpu_job.c | 43 +++++++++++-------------------- drivers/accel/ivpu/ivpu_jsm_msg.c | 8 +++--- include/uapi/drm/ivpu_accel.h | 6 +---- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index f905021ac1748..5b4f5104b4708 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -49,11 +49,8 @@ #define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) #define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) -#define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 -#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) - -#define IVPU_CMDQ_INDEX(engine, priority) ((engine) * IVPU_NUM_PRIORITIES + (priority)) +#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 98e0b7b614071..f580959e87787 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -247,8 +247,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; int ret; lockdep_assert_held(&file_priv->lock); @@ -257,7 +256,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - file_priv->cmdq[cmdq_idx] = cmdq; + file_priv->cmdq[priority] = cmdq; } ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); @@ -267,15 +266,14 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 return cmdq; } -static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) +static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; lockdep_assert_held(&file_priv->lock); if (cmdq) { - file_priv->cmdq[cmdq_idx] = NULL; + file_priv->cmdq[priority] = NULL; ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } @@ -283,14 +281,12 @@ static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engin void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; lockdep_assert_held(&file_priv->lock); - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) - ivpu_cmdq_release_locked(file_priv, engine, priority); + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) + ivpu_cmdq_release_locked(file_priv, priority); } /* @@ -301,19 +297,15 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; mutex_lock(&file_priv->lock); - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; - if (cmdq) - cmdq->db_registered = false; - } + if (cmdq) + cmdq->db_registered = false; } mutex_unlock(&file_priv->lock); @@ -334,16 +326,11 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - - if (file_priv->cmdq[cmdq_idx]) - ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]); - } + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + if (file_priv->cmdq[priority]) + ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); } } @@ -699,7 +686,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) int idx, ret; u8 priority; - if (params->engine > DRM_IVPU_ENGINE_COPY) + if (params->engine != DRM_IVPU_ENGINE_COMPUTE) return -EINVAL; if (params->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 8f5d904ca1ed4..30a40be769301 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -132,7 +132,7 @@ int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat) struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.query_engine_hb.engine_idx = engine; @@ -155,7 +155,7 @@ int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.engine_reset.engine_idx = engine; @@ -174,7 +174,7 @@ int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.engine_preempt.engine_idx = engine; @@ -346,7 +346,7 @@ int ivpu_jsm_hws_resume_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine >= VPU_ENGINE_NB) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.hws_resume_engine.engine_idx = engine; diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 234664d352507..a35b97b097bf6 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -258,7 +258,7 @@ struct drm_ivpu_bo_info { /* drm_ivpu_submit engines */ #define DRM_IVPU_ENGINE_COMPUTE 0 -#define DRM_IVPU_ENGINE_COPY 1 +#define DRM_IVPU_ENGINE_COPY 1 /* Deprecated */ /** * struct drm_ivpu_submit - Submit commands to the VPU @@ -289,10 +289,6 @@ struct drm_ivpu_submit { * %DRM_IVPU_ENGINE_COMPUTE: * * Performs Deep Learning Neural Compute Inference Operations - * - * %DRM_IVPU_ENGINE_COPY: - * - * Performs memory copy operations to/from system memory allocated for VPU */ __u32 engine; -- GitLab From 9b4a57c87e5e69b566ad02905116e6f3ddcb5514 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:10 +0200 Subject: [PATCH 204/456] UPSTREAM: accel/ivpu: Clear CDTAB entry in case of failure Don't leave a context descriptor in case CFGI_ALL flush fails. Mark it as invalid (by clearing valid bit) so nothing is left in partially-initialized state. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-5-jacek.lawrynowicz@linux.intel.com (cherry picked from commit add38f8211b5dcf447a50bea4da54c391e39336c) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I24d2244cd29084169dd9197043605013c212abc9 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059170 Reviewed-by: Sean Paul Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 4ff0d7a519859..26ef52fbb93e5 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -749,10 +749,17 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d ret = ivpu_mmu_cmdq_write_cfgi_all(vdev); if (ret) - goto unlock; + goto err_invalidate; ret = ivpu_mmu_cmdq_sync(vdev); + if (ret) + goto err_invalidate; unlock: + mutex_unlock(&mmu->lock); + return 0; + +err_invalidate: + WRITE_ONCE(entry[0], 0); mutex_unlock(&mmu->lock); return ret; } -- GitLab From ef98063441bddd6544b0099a5b1fe51639341c5e Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:11 +0200 Subject: [PATCH 205/456] UPSTREAM: accel/ivpu: Unmap partially mapped BOs in case of errors Ensure that all buffers that were created only partially through allocated scatter-gather table are unmapped from MMU600 in case of errors. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-6-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 1fc65fa96ff4703e8d26dda351d942e8940f322f) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ibdf90ccdb3dead105356c807ff45b1d8f15194a0 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059171 Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_mmu_context.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 43b58016a18f9..c404e87b4c88c 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -431,6 +431,7 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr, struct sg_table *sgt, bool llc_coherent) { + size_t start_vpu_addr = vpu_addr; struct scatterlist *sg; int ret; u64 prot; @@ -461,7 +462,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - goto err_unlock; + goto err_unmap_pages; } vpu_addr += size; } @@ -471,7 +472,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) { ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", ctx->id, ret); - goto err_unlock; + goto err_unmap_pages; } ctx->is_cd_valid = true; } @@ -479,17 +480,19 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); - mutex_unlock(&ctx->lock); - ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); - if (ret) + if (ret) { ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); - return ret; + goto err_unmap_pages; + } -err_unlock: mutex_unlock(&ctx->lock); - return ret; + return 0; +err_unmap_pages: + ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, vpu_addr - start_vpu_addr); + mutex_unlock(&ctx->lock); + return ret; } void -- GitLab From 8e6b81a0fb127ee3c4d5f92dc312b226803ad333 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:12 +0200 Subject: [PATCH 206/456] UPSTREAM: accel/ivpu: Use xa_alloc_cyclic() instead of custom function Remove custom ivpu_id_alloc() wrapper used for ID allocations and replace it with standard xa_alloc_cyclic() API. The idea behind ivpu_id_alloc() was to have monotonic IDs, so the driver is easier to debug because same IDs are not reused all over. The same can be achieved just by using appropriate Linux API. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-7-jacek.lawrynowicz@linux.intel.com (cherry picked from commit ae7af7d8dc2a13a427aa90d003fe4fb2c168342a) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id1cf3d70a1d549e341efd5fe57d7cf5fe93cc522 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059172 Tested-by: Basavaprasad Kanshetty Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 11 ++++------- drivers/accel/ivpu/ivpu_drv.h | 4 ++-- drivers/accel/ivpu/ivpu_job.c | 34 ++++++---------------------------- 3 files changed, 12 insertions(+), 37 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 34e3e9b1c3f23..383e3eb988983 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -256,10 +256,8 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); - file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, - (file_priv->ctx.id - 1)); - file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; - file_priv->job_limit = file_priv->default_job_limit; + file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); + file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -618,9 +616,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); - vdev->default_db_limit.min = IVPU_MIN_DB; - vdev->default_db_limit.max = IVPU_MAX_DB; - vdev->db_limit = vdev->default_db_limit; + vdev->db_limit.min = IVPU_MIN_DB; + vdev->db_limit.max = IVPU_MAX_DB; ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b4f5104b4708..6774402821706 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -137,7 +137,7 @@ struct ivpu_device { struct xarray db_xa; struct xa_limit db_limit; - struct xa_limit default_db_limit; + u32 db_next; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -174,7 +174,7 @@ struct ivpu_file_priv { struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; - struct xa_limit default_job_limit; + u32 job_id_next; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index f580959e87787..9154c2e14245f 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -72,26 +72,6 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } -static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, - const struct xa_limit default_limit) -{ - int ret; - - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) { - limit->min = default_limit.min; - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) - return ret; - } - - limit->min = *id + 1; - if (limit->min > limit->max) - limit->min = default_limit.min; - - return ret; -} - static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { struct ivpu_device *vdev = file_priv->vdev; @@ -102,11 +82,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ - ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, - vdev->default_db_limit); - xa_unlock(&vdev->db_xa); - if (ret) { + ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next, + GFP_KERNEL); + if (ret < 0) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; } @@ -554,9 +532,9 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, - file_priv->default_job_limit); - if (ret) { + ret = __xa_alloc_cyclic(&vdev->submitted_jobs_xa, &job->job_id, job, file_priv->job_limit, + &file_priv->job_id_next, GFP_KERNEL); + if (ret < 0) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); ret = -EBUSY; -- GitLab From 7ecb07872a16940b3f2f54cb0d0311166e2566eb Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:13 +0200 Subject: [PATCH 207/456] UPSTREAM: accel/ivpu: Make command queue ID allocated on XArray Use XArray for dynamic command queue ID allocations instead of fixed ones. This is required by upcoming changes to UAPI that will allow to manage command queues by user space instead of having predefined number of queues in a context. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-8-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 76ad741ec7349bb1112f3a0ff27adf1ca75cf025) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I73843bc9c5e4db7c995ef24a5fea8d66191d8afa Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059173 Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.c | 6 +++ drivers/accel/ivpu/ivpu_drv.h | 7 ++- drivers/accel/ivpu/ivpu_job.c | 91 ++++++++++++++++++----------------- drivers/accel/ivpu/ivpu_job.h | 2 + 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 383e3eb988983..f5a8d93fe2a57 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -104,6 +104,8 @@ static void file_priv_release(struct kref *ref) pm_runtime_get_sync(vdev->drm.dev); mutex_lock(&vdev->context_list_lock); file_priv_unbind(vdev, file_priv); + drm_WARN_ON(&vdev->drm, !xa_empty(&file_priv->cmdq_xa)); + xa_destroy(&file_priv->cmdq_xa); mutex_unlock(&vdev->context_list_lock); pm_runtime_put_autosuspend(vdev->drm.dev); @@ -259,6 +261,10 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; + xa_init_flags(&file_priv->cmdq_xa, XA_FLAGS_ALLOC1); + file_priv->cmdq_limit.min = IVPU_CMDQ_MIN_ID; + file_priv->cmdq_limit.max = IVPU_CMDQ_MAX_ID; + mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 6774402821706..8e79d78906bfe 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -52,6 +52,9 @@ #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) +#define IVPU_CMDQ_MIN_ID 1 +#define IVPU_CMDQ_MAX_ID 255 + #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 #define IVPU_PLATFORM_FPGA 3 @@ -168,13 +171,15 @@ struct ivpu_file_priv { struct kref ref; struct ivpu_device *vdev; struct mutex lock; /* Protects cmdq */ - struct ivpu_cmdq *cmdq[IVPU_NUM_CMDQS_PER_CTX]; + struct xarray cmdq_xa; struct ivpu_mmu_context ctx; struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; u32 job_id_next; + struct xa_limit cmdq_limit; + u32 cmdq_id_next; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 9154c2e14245f..82a57a30244d3 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -89,9 +89,16 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) goto err_free_cmdq; } + ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit, + &file_priv->cmdq_id_next, GFP_KERNEL); + if (ret < 0) { + ivpu_err(vdev, "Failed to allocate command queue id: %d\n", ret); + goto err_erase_db_xa; + } + cmdq->mem = ivpu_bo_create_global(vdev, SZ_4K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); if (!cmdq->mem) - goto err_erase_xa; + goto err_erase_cmdq_xa; ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) @@ -99,7 +106,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) return cmdq; -err_erase_xa: +err_erase_cmdq_xa: + xa_erase(&file_priv->cmdq_xa, cmdq->id); +err_erase_db_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: kfree(cmdq); @@ -123,13 +132,13 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq struct ivpu_device *vdev = file_priv->vdev; int ret; - ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->db_id, + ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->id, task_pid_nr(current), engine, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (ret) return ret; - ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->db_id, + ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id, priority); if (ret) return ret; @@ -143,20 +152,21 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * int ret; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) - ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, + ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (!ret) - ivpu_dbg(vdev, JOB, "DB %d registered to ctx %d\n", cmdq->db_id, file_priv->ctx.id); + ivpu_dbg(vdev, JOB, "DB %d registered to cmdq %d ctx %d\n", + cmdq->db_id, cmdq->id, file_priv->ctx.id); return ret; } static int -ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 engine, u8 priority) +ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u8 priority) { struct ivpu_device *vdev = file_priv->vdev; struct vpu_job_queue_header *jobq_header; @@ -172,7 +182,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); jobq_header = &cmdq->jobq->header; - jobq_header->engine_idx = engine; + jobq_header->engine_idx = VPU_ENGINE_COMPUTE; jobq_header->head = 0; jobq_header->tail = 0; if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { @@ -183,7 +193,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); + ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, priority); if (ret) return ret; } @@ -210,9 +220,9 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); + ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id); if (!ret) - ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); + ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->id); } ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id); @@ -222,51 +232,46 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm return 0; } -static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, - u8 priority) +static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u8 priority) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; int ret; lockdep_assert_held(&file_priv->lock); + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + if (cmdq->priority == priority) + break; + if (!cmdq) { cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - file_priv->cmdq[priority] = cmdq; + cmdq->priority = priority; } - ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); + ret = ivpu_cmdq_init(file_priv, cmdq, priority); if (ret) return NULL; return cmdq; } -static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) +void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; lockdep_assert_held(&file_priv->lock); - if (cmdq) { - file_priv->cmdq[priority] = NULL; + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) { + xa_erase(&file_priv->cmdq_xa, cmdq_id); ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } } -void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) -{ - u8 priority; - - lockdep_assert_held(&file_priv->lock); - - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) - ivpu_cmdq_release_locked(file_priv, priority); -} - /* * Mark the doorbell as unregistered * This function needs to be called when the VPU hardware is restarted @@ -275,16 +280,13 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { - u8 priority; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; mutex_lock(&file_priv->lock); - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; - - if (cmdq) - cmdq->db_registered = false; - } + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + cmdq->db_registered = false; mutex_unlock(&file_priv->lock); } @@ -304,12 +306,11 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { - u8 priority; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - if (file_priv->cmdq[priority]) - ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); - } + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + ivpu_cmdq_fini(file_priv, cmdq); } void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) @@ -334,8 +335,8 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) /* Check if there is space left in job queue */ if (next_entry == header->head) { - ivpu_dbg(vdev, JOB, "Job queue full: ctx %d engine %d db %d head %d tail %d\n", - job->file_priv->ctx.id, job->engine_idx, cmdq->db_id, header->head, tail); + ivpu_dbg(vdev, JOB, "Job queue full: ctx %d cmdq %d db %d head %d tail %d\n", + job->file_priv->ctx.id, cmdq->id, cmdq->db_id, header->head, tail); return -EBUSY; } @@ -522,7 +523,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); + cmdq = ivpu_cmdq_acquire(file_priv, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h index 6accb94028c7a..8b19e3f8b4cfb 100644 --- a/drivers/accel/ivpu/ivpu_job.h +++ b/drivers/accel/ivpu/ivpu_job.h @@ -28,8 +28,10 @@ struct ivpu_cmdq { struct ivpu_bo *secondary_preempt_buf; struct ivpu_bo *mem; u32 entry_count; + u32 id; u32 db_id; bool db_registered; + u8 priority; }; /** -- GitLab From a87a0f9604fac61a89e2c63f2cd5cfb72a0cdfcd Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:14 +0200 Subject: [PATCH 208/456] UPSTREAM: accel/ivpu: Don't allocate preemption buffers when MIP is disabled Do not allocate preemption buffers when Mid Inference Preemption (MIP) is disabled through test mode. Rename IVPU_TEST_MODE_PREEMPTION_DISABLE to IVPU_TEST_MODE_MIP_DISABLE to better describe that this test mode only disables MIP - job level preemption will still occur. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-9-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 7df06efe1c28b25ad02e49987cd0bc1661615129) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I23c2a21575d1e78075db41792dbf11c1d71534ea Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059174 Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_drv.h | 2 +- drivers/accel/ivpu/ivpu_job.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 8e79d78906bfe..3fdff3f6cffd8 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,7 +197,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2) #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) -#define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) +#define IVPU_TEST_MODE_MIP_DISABLE BIT(6) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 82a57a30244d3..39ba6d3d8b0de 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -35,7 +35,8 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW || + ivpu_test_mode & IVPU_TEST_MODE_MIP_DISABLE) return 0; cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, @@ -347,8 +348,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && - (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { if (cmdq->primary_preempt_buf) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); -- GitLab From d20945462a51ff457b7dd7e49aefdaebb1e875ab Mon Sep 17 00:00:00 2001 From: Maciej Falkowski Date: Thu, 17 Oct 2024 16:58:15 +0200 Subject: [PATCH 209/456] UPSTREAM: accel/ivpu: Add debug Kconfig option Add CONFIG_DRM_ACCEL_IVPU_DEBUG option that: - Adds -DDEBUG that enables printk regardless of the kernel config - Enables unsafe module params (that are now disabled by default) Signed-off-by: Maciej Falkowski Reviewed-by: Jacek Lawrynowicz Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-10-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 5f8600b9d5a20b01b720b4deeade7a88316aa4e3) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Id787bdd37a4295d3cbbe97653ee3dcbac0576442 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059175 Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Shik Chen Tested-by: Basavaprasad Kanshetty Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/Kconfig | 9 +++++++++ drivers/accel/ivpu/Makefile | 2 ++ drivers/accel/ivpu/ivpu_drv.c | 2 ++ drivers/accel/ivpu/ivpu_fw.c | 2 ++ drivers/accel/ivpu/ivpu_pm.c | 2 ++ 5 files changed, 17 insertions(+) diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index e4d418b44626e..9e055b5ce03d2 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -16,3 +16,12 @@ config DRM_ACCEL_IVPU and Deep Learning applications. If "M" is selected, the module will be called intel_vpu. + +config DRM_ACCEL_IVPU_DEBUG + bool "Intel NPU debug mode" + depends on DRM_ACCEL_IVPU + help + Choose this option to enable additional + debug features for the Intel NPU driver: + - Always print debug messages regardless of dyndbg config, + - Enable unsafe module params. diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index e73937c86d9ad..1029e0bab0615 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -24,4 +24,6 @@ intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o +subdir-ccflags-$(CONFIG_DRM_ACCEL_IVPU_DEBUG) += -DDEBUG + CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index f5a8d93fe2a57..ca2bf47ce2484 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -43,8 +43,10 @@ module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644); MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros."); int ivpu_test_mode; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(test_mode, ivpu_test_mode, int, 0644); MODULE_PARM_DESC(test_mode, "Test mode mask. See IVPU_TEST_MODE_* macros."); +#endif u8 ivpu_pll_min_ratio; module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index be367465e7df4..d358cf0b0f972 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -46,8 +46,10 @@ #define IVPU_FOCUS_PRESENT_TIMER_MS 1000 static char *ivpu_firmware; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644); MODULE_PARM_DESC(firmware, "NPU firmware binary in /lib/firmware/.."); +#endif static struct { int gen; diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index e567df79a6129..dbc0711e28d13 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -24,8 +24,10 @@ #include "vpu_boot_api.h" static bool ivpu_disable_recovery; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); MODULE_PARM_DESC(disable_recovery, "Disables recovery when NPU hang is detected"); +#endif static unsigned long ivpu_tdr_timeout_ms; module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644); -- GitLab From bb7268d5291e887c1ae7e771fd4fe43728432aa2 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:16 +0200 Subject: [PATCH 210/456] UPSTREAM: accel/ivpu: Increase DMA address range Increase DMA address range to: * 128 GB on 37xx (due to MMU limitations) * 256 GB on other generations Merge User and DMA ranges on 40xx and above as it is possible to access whole 256 GBs from both FW and DMA. Increase User range on 37xx from 255MB to 511MB to allow loading very large models. Do not set global_alias_pio_base/size on other generations than 37xx as it's only used on 37xx anyway. Signed-off-by: Karol Wachowski Signed-off-by: Andrzej Kacprowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-11-jacek.lawrynowicz@linux.intel.com (cherry picked from commit 83b6fa5844b53fe25417229e44c460e4f84da432) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I070559634baf65ff08a0c7c4bb5485654912a1fe Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059176 Tested-by: Yang Jie Reviewed-by: Shik Chen Reviewed-by: Samuel Jacob Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_fw.c | 6 ++++-- drivers/accel/ivpu/ivpu_hw.c | 10 +++++----- drivers/accel/ivpu/ivpu_mmu_context.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index d358cf0b0f972..6037ec0b30968 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -584,8 +584,10 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; - boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { + boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; + boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + } /* Allow configuration for L2C_PAGE_TABLE with boot param value */ boot_params->autoconfig = 1; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index f1f5e0c4961b2..4e1054f3466e8 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -114,14 +114,14 @@ static void memory_ranges_init(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x88000000, 511 * SZ_1M); ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_128G); } else { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000, SZ_2G); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x100000000, SZ_256G); + vdev->hw->ranges.dma = vdev->hw->ranges.user; } } diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index c404e87b4c88c..72847cc3ee647 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -570,8 +570,8 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; } else { - start = vdev->hw->ranges.user.start; - end = vdev->hw->ranges.dma.end; + start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start); + end = max_t(u64, vdev->hw->ranges.user.end, vdev->hw->ranges.dma.end); } drm_mm_init(&ctx->mm, start, end - start); -- GitLab From 08aa2aab0dcb380d63ca17770c529f18a234f0d1 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Thu, 17 Oct 2024 16:58:17 +0200 Subject: [PATCH 211/456] UPSTREAM: accel/ivpu: Move secondary preemption buffer allocation to DMA range Secondary preemption buffer is accessible by NPU's DMA and can be allocated with addresses above 4 GB. Move secondary preemption buffer allocation from SHAVE range which is much smaller (2GB) to DMA range. This allows to allocate more command queues with corresponding preemption buffers without running out of address range. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-12-jacek.lawrynowicz@linux.intel.com (cherry picked from commit e91191efe75a94ae10fac4b384962068a8151886) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: I0d4ff010f674d036f9baf83833fdada6928d9b63 Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059177 Reviewed-by: Samuel Jacob Tested-by: Basavaprasad Kanshetty Reviewed-by: Shik Chen Reviewed-by: Sean Paul Commit-Queue: Samuel Jacob Signed-off-by: Hubert Mazur --- drivers/accel/ivpu/ivpu_job.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 39ba6d3d8b0de..7149312f16e19 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -46,7 +46,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, return -ENOMEM; } - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.dma, secondary_size, DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); -- GitLab From a5fc5564d4182c234a6a68df1837054fd5809176 Mon Sep 17 00:00:00 2001 From: Matt Coster Date: Wed, 22 Nov 2023 16:34:22 +0000 Subject: [PATCH 212/456] UPSTREAM: sizes.h: Add entries between SZ_32G and SZ_64T sizes.h has a gap in defines between SZ_32G and SZ_64T. Add the missing defines so they can be used in drivers. Signed-off-by: Matt Coster Signed-off-by: Sarah Walker Signed-off-by: Donald Robson Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/58b227d96f27859b453caf0ceaaac81a6616304b.1700668843.git.donald.robson@imgtec.com Signed-off-by: Maxime Ripard (cherry picked from commit 66b73e9a402d822723b3af5263eb12d735628eac) BUG=b:381329506 TEST=NPU driver loaded successfully Change-Id: Ib149fb20d2b296f8b13809cec384f265cfd6ad1b Signed-off-by: Vivek Trambadiya Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6059178 Reviewed-by: Shik Chen Commit-Queue: Samuel Jacob Tested-by: Basavaprasad Kanshetty Tested-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Samuel Jacob Signed-off-by: Hubert Mazur --- include/linux/sizes.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/sizes.h b/include/linux/sizes.h index 84aa448d8bb32..c3a00b967d18a 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -47,8 +47,17 @@ #define SZ_8G _AC(0x200000000, ULL) #define SZ_16G _AC(0x400000000, ULL) #define SZ_32G _AC(0x800000000, ULL) +#define SZ_64G _AC(0x1000000000, ULL) +#define SZ_128G _AC(0x2000000000, ULL) +#define SZ_256G _AC(0x4000000000, ULL) +#define SZ_512G _AC(0x8000000000, ULL) #define SZ_1T _AC(0x10000000000, ULL) +#define SZ_2T _AC(0x20000000000, ULL) +#define SZ_4T _AC(0x40000000000, ULL) +#define SZ_8T _AC(0x80000000000, ULL) +#define SZ_16T _AC(0x100000000000, ULL) +#define SZ_32T _AC(0x200000000000, ULL) #define SZ_64T _AC(0x400000000000, ULL) #endif /* __LINUX_SIZES_H__ */ -- GitLab From aa701943b7ea8d90d5e97b6e9360c4a9b0fc8852 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Mon, 2 Dec 2024 02:08:42 +0000 Subject: [PATCH 213/456] UPSTREAM: drm/amd: Add some missing straps from NBIO 7.11.0 Earlier ASICs have strap information exported, and this is missing for NBIO 7.11.0. Cc: stable@vger.kernel.org Reviewed-by: Alex Deucher Fixes: ca8c68142ad8 ("drm/amdgpu: add nbio 7.11 registers") Link: https://lore.kernel.org/r/20241118174611.10700-1-mario.limonciello@amd.com Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher (cherry picked from commit 902fbbf429b8213232b18de0ddfd5c0f3851cb8f) BUG=b:325713868 TEST=tast run graphics.IgtKms.kms_vrr Signed-off-by: Linux Patches Robot Change-Id: I3b45fa8634f9a9e34806af89569785cc6d0c3f82 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6061858 Commit-Queue: Tim Van Patten Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul Reviewed-by: Tim Van Patten Signed-off-by: Hubert Mazur --- .../amd/include/asic_reg/nbio/nbio_7_11_0_offset.h | 2 ++ .../amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h index f446b1760f7ca..82f95e95b6a67 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h @@ -7563,6 +7563,8 @@ // base address: 0x10100000 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0 0xd000 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_BASE_IDX 5 +#define regRCC_DEV0_EPF5_STRAP4 0xd284 +#define regRCC_DEV0_EPF5_STRAP4_BASE_IDX 5 // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h index 84242240f611c..4b99683ca2544 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h @@ -50625,6 +50625,19 @@ #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D1_SUPPORT_DEV0_F0_MASK 0x40000000L #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D2_SUPPORT_DEV0_F0_MASK 0x80000000L +//RCC_DEV0_EPF5_STRAP4 +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5__SHIFT 0x14 +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5__SHIFT 0x15 +#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5__SHIFT 0x16 +#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5__SHIFT 0x17 +#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5__SHIFT 0x1c +#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5__SHIFT 0x1f +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5_MASK 0x00100000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5_MASK 0x00200000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5_MASK 0x00400000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5_MASK 0x0F800000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5_MASK 0x70000000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5_MASK 0x80000000L // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk //HARD_RST_CTRL -- GitLab From f51cae53bd44dde296aadf7222e4187ed5aa621b Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 29 Apr 2024 15:04:42 +0000 Subject: [PATCH 214/456] UPSTREAM: media: uvcvideo: Refactor iterators Avoid using the iterators after the list_for_each() constructs. This patch should be a NOP, but makes cocci, happier: drivers/media/usb/uvc/uvc_ctrl.c:1861:44-50: ERROR: invalid reference to the index variable of the iterator on line 1850 drivers/media/usb/uvc/uvc_ctrl.c:2195:17-23: ERROR: invalid reference to the index variable of the iterator on line 2179 Reviewed-by: Sergey Senozhatsky Reviewed-by: Laurent Pinchart Signed-off-by: Ricardo Ribalda Signed-off-by: Hans Verkuil (cherry picked from commit 64627daf0c5f7838111f52bbbd1a597cb5d6871a) BUG=b:381229714 TEST=Compile test Change-Id: I4f37d5b068bffbc93adb7d751224939851eb84f9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108502 Reviewed-by: Hidenori Kobayashi Tested-by: Ricardo Ribalda Commit-Queue: Hidenori Kobayashi Reviewed-by: Sean Paul Auto-Submit: Ricardo Ribalda Signed-off-by: Hubert Mazur --- drivers/media/usb/uvc/uvc_ctrl.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 23679f73f3033..dae3c8636082f 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2176,16 +2176,18 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, list_for_each_entry(entity, &chain->entities, chain) { ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, &err_ctrl); - if (ret < 0) + if (ret < 0) { + if (ctrls) + ctrls->error_idx = + uvc_ctrl_find_ctrl_idx(entity, ctrls, + err_ctrl); goto done; + } } if (!rollback) uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); done: - if (ret < 0 && ctrls) - ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls, - err_ctrl); mutex_unlock(&chain->ctrl_mutex); return ret; } @@ -2638,7 +2640,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev, int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry) { - struct uvc_entity *entity; + struct uvc_entity *entity, *iter; struct uvc_control *ctrl; unsigned int i; bool found; @@ -2648,16 +2650,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, int ret; /* Find the extension unit. */ - found = false; - list_for_each_entry(entity, &chain->entities, chain) { - if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && - entity->id == xqry->unit) { - found = true; + entity = NULL; + list_for_each_entry(iter, &chain->entities, chain) { + if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT && + iter->id == xqry->unit) { + entity = iter; break; } } - if (!found) { + if (!entity) { uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n", xqry->unit); return -ENOENT; -- GitLab From f237fa206e5a9b42dc6f44d22995742493c27b30 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 3 Dec 2024 21:20:08 +0000 Subject: [PATCH 215/456] FROMGIT: media: uvcvideo: Only save async fh if success Now we keep a reference to the active fh for any call to uvc_ctrl_set, regardless if it is an actual set or if it is a just a try or if the device refused the operation. We should only keep the file handle if the device actually accepted applying the operation. Cc: stable@vger.kernel.org Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives") Suggested-by: Hans de Goede Reviewed-by: Hans de Goede Reviewed-by: Laurent Pinchart Signed-off-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-1-26c867231118@chromium.org Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab (cherry picked from commit d9fecd096f67a4469536e040a8a10bbfb665918b https://gitlab.freedesktop.org/linux-media/media-committers.git next) BUG=b:381229714 TEST=Compile test Change-Id: I8c1e686a0e014c0320388bcf2c8ab30e7e2ee62d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108503 Reviewed-by: Hidenori Kobayashi Tested-by: Ricardo Ribalda Commit-Queue: Hidenori Kobayashi Auto-Submit: Ricardo Ribalda Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/media/usb/uvc/uvc_ctrl.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index dae3c8636082f..2b058608adee9 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2090,7 +2090,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) } static int uvc_ctrl_commit_entity(struct uvc_device *dev, - struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl) + struct uvc_fh *handle, + struct uvc_entity *entity, + int rollback, + struct uvc_control **err_ctrl) { struct uvc_control *ctrl; unsigned int i; @@ -2138,6 +2141,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, *err_ctrl = ctrl; return ret; } + + if (!rollback && handle && + ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + ctrl->handle = handle; } return 0; @@ -2174,8 +2181,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, /* Find the control. */ list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, - &err_ctrl); + ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, + rollback, &err_ctrl); if (ret < 0) { if (ctrls) ctrls->error_idx = @@ -2465,9 +2472,6 @@ int uvc_ctrl_set(struct uvc_fh *handle, return ret; } - if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) - ctrl->handle = handle; - ctrl->dirty = 1; ctrl->modified = 1; return 0; @@ -2796,7 +2800,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev) ctrl->dirty = 1; } - ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL); + ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL); if (ret < 0) return ret; } -- GitLab From 67f253cf0d82417dfba83bbed3cb942bbd728e2f Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 3 Dec 2024 21:20:09 +0000 Subject: [PATCH 216/456] FROMGIT: media: uvcvideo: Remove redundant NULL assignment ctrl->handle will only be different than NULL for controls that have mappings. This is because that assignment is only done inside uvc_ctrl_set() for mapped controls. Cc: stable@vger.kernel.org Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives") Reviewed-by: Laurent Pinchart Reviewed-by: Hans de Goede Signed-off-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-2-26c867231118@chromium.org Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab (cherry picked from commit 04d3398f66d2d31c4b8caea88f051a4257b7a161 https://gitlab.freedesktop.org/linux-media/media-committers.git next) BUG=b:381229714 TEST=Compile test Change-Id: Iaea9e34151776313dca68a47f367f79cf0996a09 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108504 Reviewed-by: Sean Paul Tested-by: Ricardo Ribalda Commit-Queue: Hidenori Kobayashi Auto-Submit: Ricardo Ribalda Reviewed-by: Hidenori Kobayashi Signed-off-by: Hubert Mazur --- drivers/media/usb/uvc/uvc_ctrl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 2b058608adee9..4c4411e095363 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1918,10 +1918,8 @@ bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, struct uvc_device *dev = chain->dev; struct uvc_ctrl_work *w = &dev->async_ctrl; - if (list_empty(&ctrl->info.mappings)) { - ctrl->handle = NULL; + if (list_empty(&ctrl->info.mappings)) return false; - } w->data = data; w->urb = urb; -- GitLab From 198d0aea24f92aaeb16402da4451d574a39b0f0f Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 3 Dec 2024 21:20:10 +0000 Subject: [PATCH 217/456] FROMGIT: media: uvcvideo: Remove dangling pointers When an async control is written, we copy a pointer to the file handle that started the operation. That pointer will be used when the device is done. Which could be anytime in the future. If the user closes that file descriptor, its structure will be freed, and there will be one dangling pointer per pending async control, that the driver will try to use. Clean all the dangling pointers during release(). To avoid adding a performance penalty in the most common case (no async operation), a counter has been introduced with some logic to make sure that it is properly handled. Cc: stable@vger.kernel.org Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives") Reviewed-by: Hans de Goede Signed-off-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20241203-uvc-fix-async-v6-3-26c867231118@chromium.org Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab (cherry picked from commit 221cd51efe4565501a3dbf04cc011b537dcce7fb https://gitlab.freedesktop.org/linux-media/media-committers.git next) BUG=b:381229714 TEST=Compile test Change-Id: I2d17dc6591e220ea3e460b90d16d7e187138c015 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108505 Tested-by: Ricardo Ribalda Reviewed-by: Sean Paul Auto-Submit: Ricardo Ribalda Commit-Queue: Hidenori Kobayashi Reviewed-by: Hidenori Kobayashi Signed-off-by: Hubert Mazur --- drivers/media/usb/uvc/uvc_ctrl.c | 59 ++++++++++++++++++++++++++++++-- drivers/media/usb/uvc/uvc_v4l2.c | 2 ++ drivers/media/usb/uvc/uvcvideo.h | 9 ++++- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 4c4411e095363..1fc33897ca8f6 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1857,6 +1857,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); } +static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, + struct uvc_fh *new_handle) +{ + lockdep_assert_held(&handle->chain->ctrl_mutex); + + if (new_handle) { + if (ctrl->handle) + dev_warn_ratelimited(&handle->stream->dev->udev->dev, + "UVC non compliance: Setting an async control with a pending operation."); + + if (new_handle == ctrl->handle) + return; + + if (ctrl->handle) { + WARN_ON(!ctrl->handle->pending_async_ctrls); + if (ctrl->handle->pending_async_ctrls) + ctrl->handle->pending_async_ctrls--; + } + + ctrl->handle = new_handle; + handle->pending_async_ctrls++; + return; + } + + /* Cannot clear the handle for a control not owned by us.*/ + if (WARN_ON(ctrl->handle != handle)) + return; + + ctrl->handle = NULL; + if (WARN_ON(!handle->pending_async_ctrls)) + return; + handle->pending_async_ctrls--; +} + void uvc_ctrl_status_event(struct uvc_video_chain *chain, struct uvc_control *ctrl, const u8 *data) { @@ -1867,7 +1901,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, mutex_lock(&chain->ctrl_mutex); handle = ctrl->handle; - ctrl->handle = NULL; + if (handle) + uvc_ctrl_set_handle(handle, ctrl, NULL); list_for_each_entry(mapping, &ctrl->info.mappings, list) { s32 value = __uvc_ctrl_get_value(mapping, data); @@ -2142,7 +2177,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, if (!rollback && handle && ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) - ctrl->handle = handle; + uvc_ctrl_set_handle(handle, ctrl, handle); } return 0; @@ -3299,6 +3334,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev) return 0; } +void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) +{ + struct uvc_entity *entity; + + guard(mutex)(&handle->chain->ctrl_mutex); + + if (!handle->pending_async_ctrls) + return; + + list_for_each_entry(entity, &handle->chain->dev->entities, list) { + for (unsigned int i = 0; i < entity->ncontrols; ++i) { + if (entity->controls[i].handle != handle) + continue; + uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); + } + } + + WARN_ON(handle->pending_async_ctrls); +} + /* * Cleanup device controls. */ diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index c0a7c0091099c..8346b7730cb7b 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -659,6 +659,8 @@ static int uvc_v4l2_release(struct file *file) uvc_dbg(stream->dev, CALLS, "%s\n", __func__); + uvc_ctrl_cleanup_fh(handle); + /* Only free resources if this is a privileged handle. */ if (uvc_has_privileges(handle)) uvc_queue_release(&stream->queue); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 14c4902fa246b..aa7648897d328 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -369,7 +369,11 @@ struct uvc_video_chain { struct uvc_entity *processing; /* Processing unit */ struct uvc_entity *selector; /* Selector unit */ - struct mutex ctrl_mutex; /* Protects ctrl.info */ + struct mutex ctrl_mutex; /* + * Protects ctrl.info, + * ctrl.handle and + * uvc_fh.pending_async_ctrls + */ struct v4l2_prio_state prio; /* V4L2 priority state */ u32 caps; /* V4L2 chain-wide caps */ @@ -643,6 +647,7 @@ struct uvc_fh { struct uvc_video_chain *chain; struct uvc_streaming *stream; enum uvc_handle_state state; + unsigned int pending_async_ctrls; }; struct uvc_driver { @@ -832,6 +837,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); +void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); + /* Utility functions */ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, u8 epaddr); -- GitLab From f58d47bda5341ae4e285246f1bad2cfa396ad406 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Fri, 13 Dec 2024 09:29:22 +0000 Subject: [PATCH 218/456] FROMGIT: arm64: dts: mediatek: mt8188: Add GPU speed bin NVMEM cells On the MT8188, the chip is binned for different GPU voltages at the highest OPPs. The binning value is stored in the efuse. Add the NVMEM cell, and tie it to the GPU. Signed-off-by: Hsin-Te Yuan Link: https://lore.kernel.org/r/20241213-speedbin-v1-1-a0053ead9477@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 50e7592cb696b3767d2186b0d51bb37a2fddbb67 git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git for-next) BUG=b:383949399 TEST=ls /sys/class/devfreq/13000000.gpu/ on ciri Change-Id: Ibda637508f27751656c86a7a0c8e9713c23486e8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109723 Auto-Submit: Hsin-Te Yuan Tested-by: Hsin-Te Yuan Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8188.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi index 15f83087dd581..a835ed619f7c4 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi @@ -2121,6 +2121,11 @@ reg = <0x1ac 0x40>; }; + gpu_speedbin: gpu-speedbin@581 { + reg = <0x581 0x1>; + bits = <0 3>; + }; + socinfo-data1@7a0 { reg = <0x7a0 0x4>; }; @@ -2139,6 +2144,8 @@ , ; interrupt-names = "job", "mmu", "gpu"; + nvmem-cells = <&gpu_speedbin>; + nvmem-cell-names = "speed-bin"; operating-points-v2 = <&gpu_opp_table>; power-domains = <&spm MT8188_POWER_DOMAIN_MFG2>, <&spm MT8188_POWER_DOMAIN_MFG3>, -- GitLab From ab97daae87f2fc9b012eb001b2b92fb520748468 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Mon, 23 Dec 2024 10:24:03 +0800 Subject: [PATCH 219/456] CHROMIUM: media: platform: mediatek: mdp3: add definition for IMGI reg Add a header to define IMGI's register for connecting to ISP to avoid using magic numbers. BUG=b:379039600 TEST=build pass UPSTREAM-TASK=b:354021564 Change-Id: I3fd61fee1fc8c74dda62213a469941485977a516 Signed-off-by: Moudy Ho Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109619 Tested-by: Jason-jh Lin Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Reviewed-by: Jason-jh Lin Signed-off-by: Hubert Mazur --- .../platform/mediatek/mdp3/mdp_reg_imgi.h | 35 +++++++++++++++++++ .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 35 ++++++++++++------- 2 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_imgi.h diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_imgi.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_imgi.h new file mode 100644 index 0000000000000..e4876fcf82e60 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_imgi.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_IMGI_H__ +#define __MDP_REG_IMGI_H__ + +#define MDP_IMGI_DBG_SEL 0x30 +#define MDP_IMGI_CG_CON 0x2000 +#define MDP_IMGI_BASE_OFFSET 0x2304 +#define MDP_IMGI_SMX1O_ADDR 0x27d0 +#define MDP_IMGI_SMX2O_ADDR 0x2800 +#define MDP_IMGI_SMX3O_ADDR 0x2830 +#define MDP_IMGI_SMX4O_ADDR 0x2860 +#define MDP_IMGI_SMX1I_ADDR 0x2890 +#define MDP_IMGI_SMX2I_ADDR 0x28c0 +#define MDP_IMGI_SMX3I_ADDR 0x28f0 +#define MDP_IMGI_SMX4I_ADDR 0x2920 + +/* MASK */ +#define MDP_IMGI_DBG_SEL_MASK 0x1fff +#define MDP_IMGI_CG_CON_MASK 0xffffffff +#define MDP_IMGI_BASE_OFFSET_MASK 0xffffffff +#define MDP_IMGI_SMX1O_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX2O_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX3O_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX4O_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX1I_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX2I_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX3I_ADDR_MASK 0xffffffff +#define MDP_IMGI_SMX4I_ADDR_MASK 0xffffffff + +#endif // __MDP_REG_IMGI_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index a59122638e509..f32c92f055c20 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -15,6 +15,7 @@ #include "mdp_reg_rdma.h" #include "mdp_reg_ccorr.h" +#include "mdp_reg_imgi.h" #include "mdp_reg_rsz.h" #include "mdp_reg_wrot.h" #include "mdp_reg_wdma.h" @@ -781,23 +782,31 @@ static int config_isp_frame(struct mdp_comp_ctx *ctx, /* DIP_X_SMX1I_BASE_ADDR, DIP_X_SMX1O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[0]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2890, reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x27D0, reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX1I_ADDR, + reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX1O_ADDR, + reg, 0xFFFFFFFF); /* DIP_X_SMX2I_BASE_ADDR, DIP_X_SMX2O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[1]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x28C0, reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2800, reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX2I_ADDR, + reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX2O_ADDR, + reg, 0xFFFFFFFF); /* DIP_X_SMX3I_BASE_ADDR, DIP_X_SMX3O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[2]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x28F0, reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2830, reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX3I_ADDR, reg, + 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX3O_ADDR, reg, + 0xFFFFFFFF); /* DIP_X_SMX4I_BASE_ADDR, DIP_X_SMX4O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[3]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2920, reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2860, reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX4I_ADDR, + reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX4O_ADDR, + reg, 0xFFFFFFFF); idx = CFG_COMP(MT8183, ctx->param, isp.cq_idx); if (idx >= m_dev->mdp_data->dip_cq_len) { @@ -824,7 +833,8 @@ static int config_isp_subfrm(struct mdp_comp_ctx *ctx, else return 0; - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2304, reg, 0xFFFFFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_BASE_OFFSET, + reg, 0xFFFFFFFF); return 0; } @@ -849,10 +859,10 @@ static int wait_isp_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* MDP_DL_SEL: select MDP_CROP */ if (c_id & BIT(c1)) - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0, + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_DBG_SEL, 0x0, BIT(9)); if (c_id & BIT(c2)) - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0, + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_DBG_SEL, 0x0, BIT(10) | BIT(11)); idx = CFG_COMP(MT8183, ctx->param, isp.cq_idx); @@ -862,7 +872,8 @@ static int wait_isp_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) } evt = dip_cq[idx].event_id; - MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(idx), BIT(idx)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_CG_CON, + BIT(idx), BIT(idx)); MM_REG_WAIT(cmd, evt); return 0; -- GitLab From b069733478575a209f274bbdf7c832aa8276bc16 Mon Sep 17 00:00:00 2001 From: Jason-jh Lin Date: Fri, 23 Aug 2024 17:31:21 -0400 Subject: [PATCH 220/456] FROMGIT: media: platform: mtk-mdp3: Use cmdq_pkt_write when no mask is needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmdq_pkt_write_mask() boils down to a cmdq_pkt_write() when the mask is 0xFFFFFFFF. Call cmdq_pkt_write() directly in those cases to simplify the code. Suggested-by: AngeloGioacchino Del Regno Signed-off-by: Nícolas F. R. A. Prado (cherry-picked from commit 1ab010907fb154210f945d7a7248f59e860a9cdb https://gitlab.freedesktop.org/linux-media/media-committers.git next) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Idcaa47e4e63feb25dbb5cca1f05b0be9bb8fbcce Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109254 Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 6adac857a4779..275ad4609147c 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -191,8 +191,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, /* Enable mux settings */ for (index = 0; index < ctrl->num_sets; index++) { set = &ctrl->sets[index]; - cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg, - set->value, 0xFFFFFFFF); + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value); } /* Config sub-frame information */ for (index = (num_comp - 1); index >= 0; index--) { @@ -226,8 +225,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, /* Disable mux settings */ for (index = 0; index < ctrl->num_sets; index++) { set = &ctrl->sets[index]; - cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg, - 0, 0xFFFFFFFF); + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0); } return 0; -- GitLab From 534fd4ffaadb698d5da1565ee4a0d40b3d1d4a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Fri, 23 Aug 2024 17:31:22 -0400 Subject: [PATCH 221/456] FROMGIT: media: platform: mtk-mdp3: Remove useless variadic arguments from macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A few macros declare variadic arguments even though the underlying functions don't support them. Remove them. Signed-off-by: Nícolas F. R. A. Prado (cherry-picked from commit 6d9038dc87003623aaf9a4dd86d7096ab5748397 https://gitlab.freedesktop.org/linux-media/media-committers.git next) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: I813b01dcd1ef2f66d5d4a3d0a0fd445f1a0f61f9 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109255 Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../media/platform/mediatek/mdp3/mtk-mdp3-comp.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index 20d2bcb77ef93..051c534b86f35 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -9,16 +9,16 @@ #include "mtk-mdp3-cmdq.h" -#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask, ...) \ +#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \ cmdq_pkt_write_mask(&((cmd)->pkt), id, \ - (base) + (ofst), (val), (mask), ##__VA_ARGS__) + (base) + (ofst), (val), (mask)) -#define MM_REG_WRITE(cmd, id, base, ofst, val, mask, ...) \ +#define MM_REG_WRITE(cmd, id, base, ofst, val, mask) \ do { \ typeof(mask) (m) = (mask); \ MM_REG_WRITE_MASK(cmd, id, base, ofst, val, \ (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ - (0xffffffff) : (m), ##__VA_ARGS__); \ + (0xffffffff) : (m)); \ } while (0) #define MM_REG_WAIT(cmd, evt) \ @@ -49,19 +49,19 @@ do { \ cmdq_pkt_set_event(&((c)->pkt), (e)); \ } while (0) -#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask, ...) \ +#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask) \ do { \ typeof(_mask) (_m) = (_mask); \ cmdq_pkt_poll_mask(&((cmd)->pkt), id, \ - (base) + (ofst), (val), (_m), ##__VA_ARGS__); \ + (base) + (ofst), (val), (_m)); \ } while (0) -#define MM_REG_POLL(cmd, id, base, ofst, val, mask, ...) \ +#define MM_REG_POLL(cmd, id, base, ofst, val, mask) \ do { \ typeof(mask) (m) = (mask); \ MM_REG_POLL_MASK((cmd), id, base, ofst, val, \ (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ - (0xffffffff) : (m), ##__VA_ARGS__); \ + (0xffffffff) : (m)); \ } while (0) enum mtk_mdp_comp_id { -- GitLab From c922cc6b683dd4cb581ce63b570de393443c9b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Fri, 23 Aug 2024 17:31:23 -0400 Subject: [PATCH 222/456] BACKPORT: FROMGIT: media: platform: mtk-mdp3: Remove mask parameter from MM_REG_WRITE macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two macros to issue a cmdq write: MM_REG_WRITE_MASK and MM_REG_WRITE, but confusingly, both of them take a mask parameter. The difference is that MM_REG_WRITE additionally checks whether the mask passed in contains the register mask, in which case, the 0xffffffff mask is passed to cmdq_pkt_write_mask(), effectively disregarding the mask and calling cmdq_pkt_write() as an optimization. Move that optimization to the MM_REG_WRITE_MASK macro and make MM_REG_WRITE the variant that doesn't take a mask, directly calling to cmdq_pkt_write(). Change the call sites to MM_REG_WRITE whenever a mask wasn't necessary (ie 0xffffffff or a _MASK was passed as mask) and in other cases to MM_REG_WRITE_MASK. Signed-off-by: Nícolas F. R. A. Prado (cherry-picked from commit 7b00fcfdb5ddfbcab34295dee3b8c4989ae92c2a https://gitlab.freedesktop.org/linux-media/media-committers.git next) Conflicts: drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: I11a745f6a1bec06558337248931243a734694d85 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6118436 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 323 +++++++++--------- .../platform/mediatek/mdp3/mtk-mdp3-comp.h | 10 +- 2 files changed, 160 insertions(+), 173 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index f32c92f055c20..2cc4a44814853 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -65,14 +65,14 @@ static int init_rdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* Disable RSZ1 */ if (ctx->comp->inner_id == rdma0 && prz1) - MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE, - 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, prz1->reg_base, + PRZ_ENABLE, 0x0, BIT(0)); } /* Reset RDMA */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0)); MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8)); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0)); return 0; } @@ -90,92 +90,93 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx, if (mdp_cfg && mdp_cfg->rdma_support_10bit) { if (block10bit) - MM_REG_WRITE(cmd, subsys_id, base, - MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7); + MM_REG_WRITE_MASK(cmd, subsys_id, base, + MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7); else - MM_REG_WRITE(cmd, subsys_id, base, - MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7); + MM_REG_WRITE_MASK(cmd, subsys_id, base, + MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7); } /* Setup smi control */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON, - (7 << 4) + //burst type to 8 - (1 << 16), //enable pre-ultra - 0x00030071); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON, + (7 << 4) + //burst type to 8 + (1 << 16), //enable pre-ultra + 0x00030071); /* Setup source frame info */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg, - 0x03C8FE0F); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg, 0x03C8FE0F); if (mdp_cfg) if (mdp_cfg->rdma_support_10bit && en_ufo) { /* Setup source buffer base */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y); - MM_REG_WRITE(cmd, subsys_id, - base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, + MDP_RDMA_UFO_DEC_LENGTH_BASE_Y, reg); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c); - MM_REG_WRITE(cmd, subsys_id, - base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, + MDP_RDMA_UFO_DEC_LENGTH_BASE_C, reg); + /* Set 10bit source frame pitch */ if (block10bit) { if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl); - MM_REG_WRITE(cmd, subsys_id, - base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL, - reg, 0x001FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, + MDP_RDMA_MF_BKGD_SIZE_IN_PXL, + reg, 0x001FFFFF); } } if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.control); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg, - 0x1110); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_CON, reg, 0x1110); + /* Setup source buffer base */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg); + /* Setup source buffer end */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0, reg); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1, reg); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2, reg); + /* Setup source frame pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, - reg, 0x001FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, + reg, 0x001FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE, - reg, 0x001FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE, + reg, 0x001FFFFF); + /* Setup color transform */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.transform); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0, - reg, 0x0F110000); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0, + reg, 0x0F110000); return 0; } @@ -193,13 +194,12 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, u32 reg = 0; /* Enable RDMA */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0)); /* Set Y pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0, reg); /* Set 10bit UFO mode */ if (mdp_cfg) { @@ -207,36 +207,37 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p); MM_REG_WRITE(cmd, subsys_id, base, - MDP_RDMA_SRC_OFFSET_0_P, - reg, 0xFFFFFFFF); + MDP_RDMA_SRC_OFFSET_0_P, reg); } } /* Set U pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1, reg); + /* Set V pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2, reg); + /* Set source size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg, - 0x1FFF1FFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg, + 0x1FFF1FFF); + /* Set target size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE, - reg, 0x1FFF1FFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE, + reg, 0x1FFF1FFF); + /* Set crop offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst); - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1, - reg, 0x003F001F); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1, + reg, 0x003F001F); if (CFG_CHECK(MT8183, p_id)) { csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); @@ -244,8 +245,8 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, } if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only) if ((csf_r - csf_l + 1) > 320) - MM_REG_WRITE(cmd, subsys_id, base, - MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, + MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2)); return 0; } @@ -262,7 +263,7 @@ static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) dev_err(dev, "Do not support RDMA1_DONE event\n"); /* Disable RDMA */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0)); return 0; } @@ -280,10 +281,10 @@ static int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) u8 subsys_id = ctx->comp->subsys_id; /* Reset RSZ */ - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16)); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16)); /* Enable RSZ */ - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0)); return 0; } @@ -301,26 +302,28 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx, if (bypass) { /* Disable RSZ */ - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0)); return 0; } if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.control1); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg, - 0x03FFFDF3); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, reg, 0x03FFFDF3); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.control2); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, - 0x0FFFC290); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x0FFFC290); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP, - reg, 0x007FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP, reg, + 0x007FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP, - reg, 0x007FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP, reg, + 0x007FFFFF); + return 0; } @@ -335,12 +338,11 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, - 0x00003800); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x00003800); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg); if (CFG_CHECK(MT8183, p_id)) { csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); @@ -348,41 +350,42 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx, } if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) if ((csf_r - csf_l + 1) <= 16) - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, - BIT(27), BIT(27)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, + BIT(27), BIT(27)); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET, - reg, 0xFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET, + reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix); - MM_REG_WRITE(cmd, subsys_id, - base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET, - reg, 0x1FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET, + reg, 0x1FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET, - reg, 0xFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET, + reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET, - reg, 0x1FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET, + reg, 0x1FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left); - MM_REG_WRITE(cmd, subsys_id, - base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET, - reg, 0xFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET, + reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix); - MM_REG_WRITE(cmd, subsys_id, - base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET, - reg, 0x1FFFFF); + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET, + reg, 0x1FFFFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip); - MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg); return 0; } @@ -403,7 +406,7 @@ static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx, } if ((csf_r - csf_l + 1) <= 16) - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0, + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0, BIT(27)); } @@ -424,9 +427,9 @@ static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) u8 subsys_id = ctx->comp->subsys_id; /* Reset WROT */ - MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); return 0; } @@ -443,56 +446,53 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx, /* Write frame base address */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg); /* Write frame related registers */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.control); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_CTRL, reg, 0xF131510F); /* Write frame Y pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE, reg, 0x0000FFFF); /* Write frame UV pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE_C, reg, 0xFFFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE_V, reg, 0xFFFF); /* Write matrix control */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3); /* Set the fixed ALPHA as 0xFF */ - MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000, 0xFF000000); /* Set VIDO_EOL_SEL */ - MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31)); /* Set VIDO_FIFO_TEST */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test); if (reg != 0) - MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_FIFO_TEST, reg, 0xFFF); /* Filter enable */ if (mdp_cfg && mdp_cfg->wrot_filter_constraint) { if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.filter); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 0x77); } @@ -509,40 +509,40 @@ static int config_wrot_subfrm(struct mdp_comp_ctx *ctx, /* Write Y pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR, reg, 0x0FFFFFFF); /* Write U pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR_C, reg, 0x0FFFFFFF); /* Write V pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR_V, reg, 0x0FFFFFFF); /* Write source size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_IN_SIZE, reg, 0x1FFF1FFF); /* Write target size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_TAR_SIZE, reg, 0x1FFF1FFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_CROP_OFST, reg, 0x1FFF1FFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf); - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 0x1FFF7F00); /* Enable WROT */ - MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0)); return 0; } @@ -560,11 +560,11 @@ static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) dev_err(dev, "Do not support WROT1_DONE event\n"); if (mdp_cfg && mdp_cfg->wrot_filter_constraint) - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0, + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0, 0x77); /* Disable WROT */ - MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0)); return 0; } @@ -583,9 +583,9 @@ static int init_wdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) u8 subsys_id = ctx->comp->subsys_id; /* Reset WDMA */ - MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0)); MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0)); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0)); return 0; } @@ -597,39 +597,35 @@ static int config_wdma_frame(struct mdp_comp_ctx *ctx, u8 subsys_id = ctx->comp->subsys_id; u32 reg = 0; - MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050); /* Setup frame information */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.wdma_cfg); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CFG, reg, 0x0F01B8F0); /* Setup frame base address */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.iova[0]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.iova[1]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.iova[2]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg); /* Setup Y pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.w_in_byte); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE, reg, 0x0000FFFF); /* Setup UV pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.uv_stride); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_UV_PITCH, reg, 0x0000FFFF); /* Set the fixed ALPHA as 0xFF */ - MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF, 0x800000FF); return 0; @@ -645,36 +641,36 @@ static int config_wdma_subfrm(struct mdp_comp_ctx *ctx, /* Write Y pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[0]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET, reg, 0x0FFFFFFF); /* Write U pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[1]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET, reg, 0x0FFFFFFF); /* Write V pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[2]); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET, reg, 0x0FFFFFFF); /* Write source size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].src); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_SRC_SIZE, reg, 0x3FFF3FFF); /* Write target size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg, 0x3FFF3FFF); /* Write clip offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip_ofst); - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, reg, + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CLIP_COORD, reg, 0x3FFF3FFF); /* Enable WDMA */ - MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0)); return 0; } @@ -686,7 +682,7 @@ static int wait_wdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); /* Disable WDMA */ - MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0)); return 0; } @@ -704,9 +700,9 @@ static int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) u8 subsys_id = ctx->comp->subsys_id; /* CCORR enable */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0)); /* Relay mode */ - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0)); + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0)); return 0; } @@ -728,7 +724,7 @@ static int config_ccorr_subfrm(struct mdp_comp_ctx *ctx, hsize = csf_r - csf_l + 1; vsize = csf_b - csf_t + 1; - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE, + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_SIZE, (hsize << 16) + (vsize << 0), 0x1FFF1FFF); return 0; } @@ -782,31 +778,23 @@ static int config_isp_frame(struct mdp_comp_ctx *ctx, /* DIP_X_SMX1I_BASE_ADDR, DIP_X_SMX1O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[0]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX1I_ADDR, - reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX1O_ADDR, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX1I_ADDR, reg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX1O_ADDR, reg); /* DIP_X_SMX2I_BASE_ADDR, DIP_X_SMX2O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[1]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX2I_ADDR, - reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX2O_ADDR, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX2I_ADDR, reg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX2O_ADDR, reg); /* DIP_X_SMX3I_BASE_ADDR, DIP_X_SMX3O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[2]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX3I_ADDR, reg, - 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX3O_ADDR, reg, - 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX3I_ADDR, reg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX3O_ADDR, reg); /* DIP_X_SMX4I_BASE_ADDR, DIP_X_SMX4O_BASE_ADDR */ reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[3]); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX4I_ADDR, - reg, 0xFFFFFFFF); - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_SMX4O_ADDR, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX4I_ADDR, reg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_SMX4O_ADDR, reg); idx = CFG_COMP(MT8183, ctx->param, isp.cq_idx); if (idx >= m_dev->mdp_data->dip_cq_len) { @@ -816,7 +804,7 @@ static int config_isp_frame(struct mdp_comp_ctx *ctx, reg = CFG_COMP(MT8183, ctx->param, isp.cq_iova); ofst = dip_cq[idx].frm_ofst; - MM_REG_WRITE_MASK(cmd, subsys_id, base, ofst, reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, ofst, reg); return 0; } @@ -833,8 +821,7 @@ static int config_isp_subfrm(struct mdp_comp_ctx *ctx, else return 0; - MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_IMGI_BASE_OFFSET, - reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, MDP_IMGI_BASE_OFFSET, reg); return 0; } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index 051c534b86f35..dbedb87dfeb35 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -10,17 +10,17 @@ #include "mtk-mdp3-cmdq.h" #define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \ - cmdq_pkt_write_mask(&((cmd)->pkt), id, \ - (base) + (ofst), (val), (mask)) - -#define MM_REG_WRITE(cmd, id, base, ofst, val, mask) \ do { \ typeof(mask) (m) = (mask); \ - MM_REG_WRITE_MASK(cmd, id, base, ofst, val, \ + cmdq_pkt_write_mask(&((cmd)->pkt), id, (base) + (ofst), \ + (val), \ (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ (0xffffffff) : (m)); \ } while (0) +#define MM_REG_WRITE(cmd, id, base, ofst, val) \ + cmdq_pkt_write(&((cmd)->pkt), id, (base) + (ofst), (val)) + #define MM_REG_WAIT(cmd, evt) \ do { \ typeof(cmd) (c) = (cmd); \ -- GitLab From c53062d2f147e9e99b436242fc70195dafe90fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Fri, 23 Aug 2024 17:31:24 -0400 Subject: [PATCH 223/456] BACKPORT: FROMGIT: media: platform: mtk-mdp3: Remove mask parameter from MM_REG_POLL macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just like was done with MM_REG_WRITE, remove the mask from the MM_REG_POLL macro, leaving MM_REG_POLL_MASK to be used when a mask is required, and update the call sites accordingly. In this case, all calls require a mask, so MM_REG_POLL remains unused, but at least this makes the MM_REG_POLL macros consistent with the MM_REG_WRITE ones. Signed-off-by: Nícolas F. R. A. Prado (cherry-picked from commit 6633de339047364b25daecc3055b006fc253efe9 https://gitlab.freedesktop.org/linux-media/media-committers.git next) Conflicts: drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: If99009b7a572f30c5979d7790d87ec7d3eea3018 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6118437 Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- .../media/platform/mediatek/mdp3/mtk-mdp3-comp.c | 8 ++++---- .../media/platform/mediatek/mdp3/mtk-mdp3-comp.h | 13 +++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index 2cc4a44814853..3c4af56504876 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -71,7 +71,7 @@ static int init_rdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* Reset RDMA */ MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0)); - MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8)); + MM_REG_POLL_MASK(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8)); MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0)); return 0; } @@ -428,9 +428,9 @@ static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* Reset WROT */ MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); - MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); + MM_REG_POLL_MASK(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); - MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); + MM_REG_POLL_MASK(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); return 0; } @@ -584,7 +584,7 @@ static int init_wdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* Reset WDMA */ MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0)); - MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0)); + MM_REG_POLL_MASK(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0)); MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0)); return 0; } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index dbedb87dfeb35..f618ec6769f6d 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -53,16 +53,13 @@ do { \ do { \ typeof(_mask) (_m) = (_mask); \ cmdq_pkt_poll_mask(&((cmd)->pkt), id, \ - (base) + (ofst), (val), (_m)); \ + (base) + (ofst), (val), \ + (((_m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ + (0xffffffff) : (_m)); \ } while (0) -#define MM_REG_POLL(cmd, id, base, ofst, val, mask) \ -do { \ - typeof(mask) (m) = (mask); \ - MM_REG_POLL_MASK((cmd), id, base, ofst, val, \ - (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ - (0xffffffff) : (m)); \ -} while (0) +#define MM_REG_POLL(cmd, id, base, ofst, val) \ + cmdq_pkt_poll(&((cmd)->pkt), id, (base) + (ofst), (val)) enum mtk_mdp_comp_id { MDP_COMP_NONE = -1, /* Invalid engine */ -- GitLab From db0ec267ac36e981645457467916983471be6b6c Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Fri, 29 Nov 2024 12:02:15 +0000 Subject: [PATCH 224/456] Revert "CHROMIUM: arm64: dts: mt8183: Disable SVS" This reverts commit 689790683e846ef5326e30a5ec0e0d2b099d374e. BUG=b:360282314 TEST=Check SVS is probed successfully Change-Id: I920c5167813b1f16090dc21777452e250388ed37 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055961 Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 8f5ce25e4cea1..317a6c9e8a2c9 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -1194,7 +1194,6 @@ <&thermal_calibration>; nvmem-cell-names = "svs-calibration-data", "t-calibration-data"; - status = "disabled"; }; thermal: thermal@1100b000 { -- GitLab From 2fbef77a2b74fa841583423282300f18bbf7cefd Mon Sep 17 00:00:00 2001 From: Xin Ji Date: Thu, 19 Dec 2024 15:03:29 +0800 Subject: [PATCH 225/456] FROMGIT: drm/bridge:anx7625: Update HDCP content status When user enabled HDCP feature, userspace will set HDCP content to DRM_MODE_CONTENT_PROTECTION_DESIRED. Next, anx7625 will update HDCP content to DRM_MODE_CONTENT_PROTECTION_ENABLED if down stream support HDCP feature. As anx7625 bridge IC will be power down after call .atomic_disable(), then all HDCP status will be lost on chip. So we should reestablish HDCP again in .atomic_enable(), and update hdcp content to DESIRE if current HDCP content is ENABLE in .atomic_disable(). v4: - Change HDCP content value to DESIRED if HDCP status is ENABLE in bridge interface .atomic_enable(). v3: - Move hdcp content value checking from bridge interface .atomic_check() to .atomic_enable() v2: - Add more details in commit message Signed-off-by: Xin Ji Tested-by: Pin-yen Lin Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241219070330.224996-1-xji@analogixsemi.com Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20241219070330.224996-1-xji@analogixsemi.com (cherry picked from commit a253b0b1292b4db0fec5733acceffc87bad4ffaf https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-next) BUG=b:374039873 TEST=Play Widevine Playback on external and change resolution Change-Id: I2d35bf123301bede3dd65c9e79542c7a8c64e66e Signed-off-by: Pin-yen Lin Signed-off-by: Alvin1 Chen Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108544 Reviewed-by: Sean Paul Reviewed-by: Hsin-Te Yuan (cherry picked from commit 57c910bcce3bbffa2d017ac73364c18e3fa6d3c0) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108702 Commit-Queue: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/analogix/anx7625.c | 73 +++++++++-------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 8a7f1574bdad1..e758ff46ea372 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2151,49 +2151,6 @@ static void hdcp_check_work_func(struct work_struct *work) drm_modeset_unlock(&drm_dev->mode_config.connection_mutex); } -static int anx7625_connector_atomic_check(struct anx7625_data *ctx, - struct drm_connector_state *state) -{ - struct device *dev = ctx->dev; - int cp; - - dev_dbg(dev, "hdcp state check\n"); - cp = state->content_protection; - - if (cp == ctx->hdcp_cp) - return 0; - - if (cp == DRM_MODE_CONTENT_PROTECTION_DESIRED) { - if (ctx->dp_en) { - dev_dbg(dev, "enable HDCP\n"); - anx7625_hdcp_enable(ctx); - - queue_delayed_work(ctx->hdcp_workqueue, - &ctx->hdcp_work, - msecs_to_jiffies(2000)); - } - } - - if (cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { - if (ctx->hdcp_cp != DRM_MODE_CONTENT_PROTECTION_ENABLED) { - dev_err(dev, "current CP is not ENABLED\n"); - return -EINVAL; - } - anx7625_hdcp_disable(ctx); - ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_UNDESIRED; - drm_hdcp_update_content_protection(ctx->connector, - ctx->hdcp_cp); - dev_dbg(dev, "update CP to UNDESIRE\n"); - } - - if (cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - dev_err(dev, "Userspace illegal set to PROTECTION ENABLE\n"); - return -EINVAL; - } - - return 0; -} - static int anx7625_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -2435,7 +2392,7 @@ static int anx7625_bridge_atomic_check(struct drm_bridge *bridge, anx7625_bridge_mode_fixup(bridge, &crtc_state->mode, &crtc_state->adjusted_mode); - return anx7625_connector_atomic_check(ctx, conn_state); + return 0; } static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, @@ -2444,6 +2401,7 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, struct anx7625_data *ctx = bridge_to_anx7625(bridge); struct device *dev = ctx->dev; struct drm_connector *connector; + struct drm_connector_state *conn_state; dev_dbg(dev, "drm atomic enable\n"); @@ -2463,6 +2421,22 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, _anx7625_hpd_polling(ctx, 5000 * 100); anx7625_dp_start(ctx); + + conn_state = drm_atomic_get_new_connector_state(state->base.state, connector); + + if (WARN_ON(!conn_state)) + return; + + if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { + if (ctx->dp_en) { + dev_dbg(dev, "enable HDCP\n"); + anx7625_hdcp_enable(ctx); + + queue_delayed_work(ctx->hdcp_workqueue, + &ctx->hdcp_work, + msecs_to_jiffies(2000)); + } + } } static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge, @@ -2473,6 +2447,17 @@ static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge, dev_dbg(dev, "drm atomic disable\n"); + flush_workqueue(ctx->hdcp_workqueue); + + if (ctx->connector && + ctx->hdcp_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + anx7625_hdcp_disable(ctx); + ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_DESIRED; + drm_hdcp_update_content_protection(ctx->connector, + ctx->hdcp_cp); + dev_dbg(dev, "update CP to DESIRE\n"); + } + ctx->connector = NULL; anx7625_dp_stop(ctx); -- GitLab From ed5da8e248c347bee7809cd57477c31da20f7cf4 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 11 Dec 2024 11:47:16 +0800 Subject: [PATCH 226/456] FROMGIT: drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb() mtk_crtc_finish_page_flip() is used to notify userspace that a page flip has been completed, allowing userspace to free the frame buffer of the last frame and commit the next frame. In MediaTek's hardware design for configuring display hardware by using GCE, `DRM_EVENT_FLIP_COMPLETE` should be notified to userspace after GCE has finished configuring all display hardware settings for each atomic_commit(). Currently, mtk_crtc_finish_page_flip() cannot guarantee that GCE has configured all the display hardware settings of the last frame. Therefore, to increase the accuracy of the timing for notifying `DRM_EVENT_FLIP_COMPLETE` to userspace, mtk_crtc_finish_page_flip() should be moved to ddp_cmdq_cb(). Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done") Signed-off-by: Jason-JH.Lin Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20241211034716.29241-1-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit da03801ad08f2488c01e684509cd89e1aa5d17ec https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git mediatek-drm-fixes) BUG=b:370548086 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039600 Signed-off-by: Jason-jh Lin Change-Id: I81ee5d23f8567021185ab0709c59565f093d5f55 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073781 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_crtc.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c index a541c67e02a55..98894ab200f09 100644 --- a/drivers/gpu/drm/mediatek/mtk_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c @@ -112,6 +112,11 @@ static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc) drm_crtc_handle_vblank(&mtk_crtc->base); +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + if (mtk_crtc->cmdq_client.chan) + return; +#endif + spin_lock_irqsave(&mtk_crtc->config_lock, flags); if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) { mtk_crtc_finish_page_flip(mtk_crtc); @@ -323,10 +328,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) state = to_mtk_crtc_state(mtk_crtc->base.state); spin_lock_irqsave(&mtk_crtc->config_lock, flags); - if (mtk_crtc->config_updating) { - spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); + if (mtk_crtc->config_updating) goto ddp_cmdq_cb_out; - } state->pending_config = false; @@ -354,10 +357,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) mtk_crtc->pending_async_planes = false; } - spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); - ddp_cmdq_cb_out: + if (mtk_crtc->pending_needs_vblank) { + mtk_crtc_finish_page_flip(mtk_crtc); + mtk_crtc->pending_needs_vblank = false; + } + + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); + mtk_crtc->cmdq_vblank_cnt = 0; wake_up(&mtk_crtc->cb_blocking_queue); } @@ -645,13 +653,18 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank) */ mtk_crtc->cmdq_vblank_cnt = 3; + spin_lock_irqsave(&mtk_crtc->config_lock, flags); + mtk_crtc->config_updating = false; + spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); + mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle); mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0); } -#endif +#else spin_lock_irqsave(&mtk_crtc->config_lock, flags); mtk_crtc->config_updating = false; spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); +#endif mutex_unlock(&mtk_crtc->hw_lock); } -- GitLab From 0b3bf463ea2b2674f4a312b4a7ea35d610fd3a43 Mon Sep 17 00:00:00 2001 From: Hsiao Chien Sung Date: Wed, 17 Jul 2024 13:24:42 +0800 Subject: [PATCH 227/456] UPSTREAM: drm/mediatek: Support "None" blending in Mixer Support "None" alpha blending mode on MediaTek's chips. Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hsiao Chien Sung Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20240717-alpha-blending-v4-2-4b1c806c0749@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit eb17c5909481d5950282ca8460e7b7420a4c36a4) BUG=b:258560987 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: I21b081e2ab43112e4f011e88879872bf097d3a0c Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6123495 Reviewed-by: Pin-yen Lin Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_ethdr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index 25394cf911bb4..e28df541ab7b2 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -3,6 +3,7 @@ * Copyright (c) 2021 MediaTek Inc. */ +#include #include #include #include @@ -175,7 +176,8 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, alpha_con |= state->base.alpha & MIXER_ALPHA; } - if (state->base.fb && !state->base.fb->format->has_alpha) { + if ((state->base.fb && !state->base.fb->format->has_alpha) || + state->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE) { /* * Mixer doesn't support CONST_BLD mode, * use a trick to make the output equivalent -- GitLab From 0037d0c0fb128d60000a96281fb9b79a3735eee1 Mon Sep 17 00:00:00 2001 From: Hsiao Chien Sung Date: Wed, 17 Jul 2024 13:24:44 +0800 Subject: [PATCH 228/456] UPSTREAM: drm/mediatek: Support "Pre-multiplied" blending in Mixer Support "Pre-multiplied" alpha blending mode in Mixer. Before this patch, only the coverage mode is supported. To replace the default setting that is set in mtk_ethdr_config(), we change mtk_ddp_write_mask() to mtk_ddp_write(), and this change will also reset the NON_PREMULTI_SOURCE bit that was assigned in mtk_ethdr_config(). Therefore, we must still set NON_PREMULTI_SOURCE bit if the blend mode is not DRM_MODE_BLEND_PREMULTI. Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hsiao Chien Sung Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20240717-alpha-blending-v4-4-4b1c806c0749@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit 59e9d9de25f046b48ae7c2756e1a3f32166d6635) BUG=b:258560987 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: I7802c2d6bd915dc014363fd28503820ea1662731 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6123497 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_ethdr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index e28df541ab7b2..00617d435a52f 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -36,6 +36,7 @@ #define MIX_SRC_L0_EN BIT(0) #define MIX_L_SRC_CON(n) (0x28 + 0x18 * (n)) #define NON_PREMULTI_SOURCE (2 << 12) +#define PREMULTI_SOURCE (3 << 12) #define MIX_L_SRC_SIZE(n) (0x30 + 0x18 * (n)) #define MIX_L_SRC_OFFSET(n) (0x34 + 0x18 * (n)) #define MIX_FUNC_DCM0 0x120 @@ -176,6 +177,11 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, alpha_con |= state->base.alpha & MIXER_ALPHA; } + if (state->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) + alpha_con |= PREMULTI_SOURCE; + else + alpha_con |= NON_PREMULTI_SOURCE; + if ((state->base.fb && !state->base.fb->format->has_alpha) || state->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE) { /* @@ -193,8 +199,7 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, mtk_ddp_write(cmdq_pkt, pending->height << 16 | align_width, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx)); mtk_ddp_write(cmdq_pkt, offset, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_OFFSET(idx)); - mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx), - 0x1ff); + mtk_ddp_write(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx)); mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON, BIT(idx)); } -- GitLab From febd0ba928a7dd4f5ea6f8d3dcc9b84024a78fa1 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 9 Oct 2024 11:46:42 +0800 Subject: [PATCH 229/456] UPSTREAM: drm/mediatek: ovl: Fix XRGB format breakage for blend_modes unsupported SoCs OVL_CON_AEN is for alpha blending enable. For the SoC that is supported the blend_modes, OVL_CON_AEN will always enabled to use constant alpha and then use the ignore_pixel_alpha bit to do the alpha blending for XRGB8888 format. Note that ignore pixel alpha bit is not supported if the SoC is not supported the blend_modes. So it will break the original setting of XRGB8888 format for the blend_modes unsupported SoCs, such as MT8173. To fix the downgrade issue, enable alpha blending only when a valid blend_mode or has_alpha is set. Fixes: bc46eb5d5d77 ("drm/mediatek: Support DRM plane alpha in OVL") Signed-off-by: Jason-JH.Lin Reviewed-by: CK Hu Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20241009034646.13143-2-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit 995d4d558eea79f8d2e8e46d0914c3940b7463ac) BUG=b:258560987 TEST=TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: I5688a8c461876fc5ed5d23e21f3a38fcaadcc218 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109988 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 7db536d322b21..2bc13dd7fb82d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -485,8 +485,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, con = ovl_fmt_convert(ovl, fmt, blend_mode); if (state->base.fb) { - con |= OVL_CON_AEN; con |= state->base.alpha & OVL_CON_ALPHA; + + /* + * For blend_modes supported SoCs, always enable alpha blending. + * For blend_modes unsupported SoCs, enable alpha blending when has_alpha is set. + */ + if (blend_mode || state->base.fb->format->has_alpha) + con |= OVL_CON_AEN; } /* CONST_BLD must be enabled for XRGB formats although the alpha channel -- GitLab From f3f96af8b90651aa0a484fc6a3603604a7040235 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 9 Oct 2024 11:46:43 +0800 Subject: [PATCH 230/456] UPSTREAM: drm/mediatek: ovl: Refine ignore_pixel_alpha comment and placement Refine the comment for ignore_pixel_alpha flag and move it to if(state->fb) statement to make it less conditional. Signed-off-by: Jason-JH.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20241009034646.13143-3-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit 28fbc3293f034f3d148bb0bc433114db493657b8) BUG=b:258560987 TEST=TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: If3abdc584efde0ccdbb2c608faac5061bb50add9 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109989 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 2bc13dd7fb82d..d2a2ab529738e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -493,16 +493,16 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, */ if (blend_mode || state->base.fb->format->has_alpha) con |= OVL_CON_AEN; - } - /* CONST_BLD must be enabled for XRGB formats although the alpha channel - * can be ignored, or OVL will still read the value from memory. - * For RGB888 related formats, whether CONST_BLD is enabled or not won't - * affect the result. Therefore we use !has_alpha as the condition. - */ - if ((state->base.fb && !state->base.fb->format->has_alpha) || - blend_mode == DRM_MODE_BLEND_PIXEL_NONE) - ignore_pixel_alpha = OVL_CONST_BLEND; + /* + * Although the alpha channel can be ignored, CONST_BLD must be enabled + * for XRGB format, otherwise OVL will still read the value from memory. + * For RGB888 related formats, whether CONST_BLD is enabled or not won't + * affect the result. Therefore we use !has_alpha as the condition. + */ + if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || !state->base.fb->format->has_alpha) + ignore_pixel_alpha = OVL_CONST_BLEND; + } /* * Treat rotate 180 as flip x + flip y, and XOR the original rotation value -- GitLab From a6b3f5a5bd2eb164bf8bd2094f3ecc5147548729 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 9 Oct 2024 11:46:44 +0800 Subject: [PATCH 231/456] UPSTREAM: drm/mediatek: ovl: Remove the color format comment for ovl_fmt_convert() Since we changed MACROs to be consistent with DRM input color format naming, the comment for ovl_fmt_conver() is no longer needed. Fixes: 9f428b95ac89 ("drm/mediatek: Add new color format MACROs in OVL") Signed-off-by: Jason-JH.Lin Reviewed-by: CK Hu Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20241009034646.13143-4-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit 41607c3ceb0e527e0985387bc41bbf291dc9a3d8) BUG=b:258560987 TEST=TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: I6bd478bb65bd53f5dbc4c434a154022d7db04b1c Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109990 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index d2a2ab529738e..772abf2fbd751 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -389,11 +389,6 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx, static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt, unsigned int blend_mode) { - /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" - * is defined in mediatek HW data sheet. - * The alphabet order in XXX is no relation to data - * arrangement in memory. - */ switch (fmt) { default: case DRM_FORMAT_RGB565: -- GitLab From 0d30e0ded7cb2cda29491ba986a2de1313d6d7fb Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 9 Oct 2024 11:46:45 +0800 Subject: [PATCH 232/456] UPSTREAM: drm/mediatek: ovl: Add blend_modes to driver data OVL_CON_CLRFMT_MAN is a configuration for extending color format settings of DISP_REG_OVL_CON(n). It will change some of the original color format settings. Take the settings of (3 << 12) for example. - If OVL_CON_CLRFMT_MAN = 0 means OVL_CON_CLRFMT_RGBA8888. - If OVL_CON_CLRFMT_MAN = 1 means OVL_CON_CLRFMT_PARGB8888. Since previous SoCs did not support OVL_CON_CLRFMT_MAN, this means that the SoC does not support the premultiplied color format. It will break the original color format setting of MT8173. Therefore, the blend_modes is added to the driver data and then mtk_ovl_fmt_convert() will check the blend_modes to see if pre-multiplied is supported in the current platform. If it is not supported, use coverage mode to set it to the supported color formats to solve the degradation problem. Fixes: a3f7f7ef4bfe ("drm/mediatek: Support "Pre-multiplied" blending in OVL") Signed-off-by: Jason-JH.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20241009034646.13143-5-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit 333ab43616ff46694b46b4137acd0e19dc291a7f) BUG=b:258560987 TEST=TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: Ia350f6a6e1090fb4e153e0b529363e063038f563 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6124753 Reviewed-by: Fei Shao Reviewed-by: Pin-yen Lin Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 34 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 772abf2fbd751..158c6d6705b33 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -146,6 +146,7 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + const u32 blend_modes; const u32 *formats; size_t num_formats; bool supports_clrfmt_ext; @@ -386,9 +387,27 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx, DISP_REG_OVL_RDMA_CTRL(idx)); } -static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt, - unsigned int blend_mode) +static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl, + struct mtk_plane_state *state) { + unsigned int fmt = state->pending.format; + unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE; + + /* + * For the platforms where OVL_CON_CLRFMT_MAN is defined in the hardware data sheet + * and supports premultiplied color formats, such as OVL_CON_CLRFMT_PARGB8888. + * + * Check blend_modes in the driver data to see if premultiplied mode is supported. + * If not, use coverage mode instead to set it to the supported color formats. + * + * Current DRM assumption is that alpha is default premultiplied, so the bitmask of + * blend_modes must include BIT(DRM_MODE_BLEND_PREMULTI). Otherwise, mtk_plane_init() + * will get an error return from drm_plane_create_blend_mode_property() and + * state->base.pixel_blend_mode should not be used. + */ + if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI)) + blend_mode = state->base.pixel_blend_mode; + switch (fmt) { default: case DRM_FORMAT_RGB565: @@ -478,7 +497,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, return; } - con = ovl_fmt_convert(ovl, fmt, blend_mode); + con = mtk_ovl_fmt_convert(ovl, state); if (state->base.fb) { con |= state->base.alpha & OVL_CON_ALPHA; @@ -677,6 +696,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { .layer_nr = 4, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE), .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), }; @@ -687,6 +709,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = { .layer_nr = 2, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE), .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), }; @@ -698,6 +723,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .fmt_rgb565_is_0 = true, .smi_id_en = true, .supports_afbc = true, + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE), .formats = mt8195_formats, .num_formats = ARRAY_SIZE(mt8195_formats), .supports_clrfmt_ext = true, -- GitLab From 89ea0ab85097f029ff6e142c2d9d0fbfd35e9c2c Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 9 Oct 2024 11:46:46 +0800 Subject: [PATCH 233/456] UPSTREAM: drm/mediatek: Add blend_modes to mtk_plane_init() for different SoCs Since some SoCs support premultiplied pixel formats but some do not, the blend_modes parameter is added to mtk_plane_init(), which is obtained from the mtk_ddp_comp_get_blend_modes function implemented in different blending supported components. The blending supported components can use driver data to set the blend mode capabilities for different SoCs. Change-Id: I8eaf25eceef12ae490adab50bd6a5383360b0bd6 Signed-off-by: Jason-JH.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20241009034646.13143-6-jason-jh.lin@mediatek.com/ Signed-off-by: Chun-Kuang Hu (cherry-picked from commit e6411bf2aea87aa3fdf74c7bce37db3d975ab026) BUG=b:258560987 TEST=TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:287363873 Change-Id: Iab2bb7b90971d4e89cca96427ee3e890052e8c4e Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6124754 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_crtc.c | 1 + drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 2 ++ drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 10 ++++++++++ drivers/gpu/drm/mediatek/mtk_disp_drv.h | 2 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 7 +++++++ drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 7 +++++++ drivers/gpu/drm/mediatek/mtk_ethdr.c | 7 +++++++ drivers/gpu/drm/mediatek/mtk_ethdr.h | 1 + drivers/gpu/drm/mediatek/mtk_plane.c | 15 +++++++-------- drivers/gpu/drm/mediatek/mtk_plane.h | 4 ++-- 10 files changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c index 98894ab200f09..d72dc0c2aff30 100644 --- a/drivers/gpu/drm/mediatek/mtk_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c @@ -964,6 +964,7 @@ static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev, BIT(pipe), mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes), mtk_ddp_comp_supported_rotations(comp), + mtk_ddp_comp_get_blend_modes(comp), mtk_ddp_comp_get_formats(comp), mtk_ddp_comp_get_num_formats(comp), i); if (ret) diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c index be66d94be3613..edc6417639e64 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c @@ -363,6 +363,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = { .layer_config = mtk_ovl_layer_config, .bgclr_in_on = mtk_ovl_bgclr_in_on, .bgclr_in_off = mtk_ovl_bgclr_in_off, + .get_blend_modes = mtk_ovl_get_blend_modes, .get_formats = mtk_ovl_get_formats, .get_num_formats = mtk_ovl_get_num_formats, }; @@ -416,6 +417,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = { .disconnect = mtk_ovl_adaptor_disconnect, .add = mtk_ovl_adaptor_add_comp, .remove = mtk_ovl_adaptor_remove_comp, + .get_blend_modes = mtk_ovl_adaptor_get_blend_modes, .get_formats = mtk_ovl_adaptor_get_formats, .get_num_formats = mtk_ovl_adaptor_get_num_formats, .mode_valid = mtk_ovl_adaptor_mode_valid, diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h index ecf6dc283cd7c..39720b27f4e9e 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h @@ -80,6 +80,7 @@ struct mtk_ddp_comp_funcs { void (*ctm_set)(struct device *dev, struct drm_crtc_state *state); struct device * (*dma_dev_get)(struct device *dev); + u32 (*get_blend_modes)(struct device *dev); const u32 *(*get_formats)(struct device *dev); size_t (*get_num_formats)(struct device *dev); void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next); @@ -266,6 +267,15 @@ static inline struct device *mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp *comp) return comp->dev; } +static inline +u32 mtk_ddp_comp_get_blend_modes(struct mtk_ddp_comp *comp) +{ + if (comp->funcs && comp->funcs->get_blend_modes) + return comp->funcs->get_blend_modes(comp->dev); + + return 0; +} + static inline const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp) { diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 082ac18fe04aa..04154db9085c0 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -103,6 +103,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +u32 mtk_ovl_get_blend_modes(struct device *dev); const u32 *mtk_ovl_get_formats(struct device *dev); size_t mtk_ovl_get_num_formats(struct device *dev); @@ -131,6 +132,7 @@ void mtk_ovl_adaptor_start(struct device *dev); void mtk_ovl_adaptor_stop(struct device *dev); unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev); struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev); +u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev); const u32 *mtk_ovl_adaptor_get_formats(struct device *dev); size_t mtk_ovl_adaptor_get_num_formats(struct device *dev); enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 158c6d6705b33..d15d9a3033710 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -215,6 +215,13 @@ void mtk_ovl_disable_vblank(struct device *dev) writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } +u32 mtk_ovl_get_blend_modes(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->blend_modes; +} + const u32 *mtk_ovl_get_formats(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index 9bb176278b66e..c348713d65fd7 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -401,6 +401,13 @@ void mtk_ovl_adaptor_disable_vblank(struct device *dev) mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]); } +u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev) +{ + struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); + + return mtk_ethdr_get_blend_modes(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]); +} + const u32 *mtk_ovl_adaptor_get_formats(struct device *dev) { struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index 00617d435a52f..4474a1a563c2b 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -145,6 +145,13 @@ static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +u32 mtk_ethdr_get_blend_modes(struct device *dev) +{ + return BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE); +} + void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, struct mtk_plane_state *state, struct cmdq_pkt *cmdq_pkt) diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h index 81af9edea3f74..a72aeee46829a 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.h +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h @@ -13,6 +13,7 @@ void mtk_ethdr_clk_disable(struct device *dev); void mtk_ethdr_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt); +u32 mtk_ethdr_get_blend_modes(struct device *dev); void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, struct mtk_plane_state *state, struct cmdq_pkt *cmdq_pkt); diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c index 7d2cb4e0fafad..8a48b3b0a9567 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_plane.c @@ -320,8 +320,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = { int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, unsigned long possible_crtcs, enum drm_plane_type type, - unsigned int supported_rotations, const u32 *formats, - size_t num_formats, unsigned int plane_idx) + unsigned int supported_rotations, const u32 blend_modes, + const u32 *formats, size_t num_formats, unsigned int plane_idx) { int err; @@ -366,12 +366,11 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, if (err) DRM_ERROR("failed to create property: alpha\n"); - err = drm_plane_create_blend_mode_property(plane, - BIT(DRM_MODE_BLEND_PREMULTI) | - BIT(DRM_MODE_BLEND_COVERAGE) | - BIT(DRM_MODE_BLEND_PIXEL_NONE)); - if (err) - DRM_ERROR("failed to create property: blend_mode\n"); + if (blend_modes) { + err = drm_plane_create_blend_mode_property(plane, blend_modes); + if (err) + DRM_ERROR("failed to create property: blend_mode\n"); + } drm_plane_helper_add(plane, &mtk_plane_helper_funcs); diff --git a/drivers/gpu/drm/mediatek/mtk_plane.h b/drivers/gpu/drm/mediatek/mtk_plane.h index 5b177eac67b7a..3b13b89989c7e 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.h +++ b/drivers/gpu/drm/mediatek/mtk_plane.h @@ -48,6 +48,6 @@ to_mtk_plane_state(struct drm_plane_state *state) int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, unsigned long possible_crtcs, enum drm_plane_type type, - unsigned int supported_rotations, const u32 *formats, - size_t num_formats, unsigned int plane_idx); + unsigned int supported_rotations, const u32 blend_modes, + const u32 *formats, size_t num_formats, unsigned int plane_idx); #endif -- GitLab From 84cd2152b115ca951e9232feedaec73b58a1c2af Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Wed, 4 Dec 2024 02:10:48 +0000 Subject: [PATCH 234/456] UPSTREAM: arm64: dts: mediatek: mt8195-cherry: Use correct audio codec DAI The RT5682i and RT5682s drivers describe two DAIs: AIF1 supports both playback and capture, while AIF2 supports capture only. Cherry doesn't specify which DAI to use. Although this doesn't cause real issues because AIF1 happens to be the first DAI, it should be corrected: codec@1a: #sound-dai-cells: 1 was expected Update #sound-dai-cells to 1 and adjust DAI link usages accordingly. Fixes: 87728e3ccf35 ("arm64: dts: mediatek: mt8195-cherry: Specify sound DAI links and routing") Signed-off-by: Fei Shao Link: https://lore.kernel.org/r/20241021114318.1358681-1-fshao@chromium.org Signed-off-by: AngeloGioacchino Del Regno (cherry picked from commit 7d5794e6d964940e46286fadbe69a3245fa51e44) BUG=b:371156518 TEST=Boot kernel and test audio on Dojo and Tomato Signed-off-by: Linux Patches Robot Change-Id: Ie1983e43a4e3021f70828ea7da8d0cad042ba51c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6068395 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Tested-by: Wojciech Macek Reviewed-by: Sean Paul Reviewed-by: Wojciech Macek Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi index 2e8b128835c72..ef159bb2d88e1 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi @@ -445,7 +445,7 @@ /* Realtek RT5682i or RT5682s, sharing the same configuration */ reg = <0x1a>; interrupts-extended = <&pio 89 IRQ_TYPE_EDGE_BOTH>; - #sound-dai-cells = <0>; + #sound-dai-cells = <1>; realtek,jd-src = <1>; AVDD-supply = <&mt6359_vio18_ldo_reg>; @@ -1195,7 +1195,7 @@ link-name = "ETDM1_OUT_BE"; mediatek,clk-provider = "cpu"; codec { - sound-dai = <&audio_codec>; + sound-dai = <&audio_codec 0>; }; }; @@ -1203,7 +1203,7 @@ link-name = "ETDM2_IN_BE"; mediatek,clk-provider = "cpu"; codec { - sound-dai = <&audio_codec>; + sound-dai = <&audio_codec 0>; }; }; -- GitLab From cae64c191beed9d91cf5fae6ef2482dda1afb961 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:54 +0800 Subject: [PATCH 235/456] FROMLIST: dt-bindings: mailbox: mediatek: Add MT8196 support for gce-mailbox 1. Add compatible name and iommus property to mediatek,gce-mailbox.yaml for MT8196. - The compatible name "mediatek,mt8196-gce-mailbox" is added to ensure that the device tree can correctly identify and configure the GCE mailbox for the MT8196 SoC. - The iommus property is added to specify the IOMMU configuration for the GCE mailbox, ensuring proper memory management and access control. 2. Add the Global Command Engine (GCE) binding header to define the abstrct symbol binding to the GCE hardware settings of GCE Thread Priority, GCE Subsys ID and GCE Event for MT8196. - GCE Thread Priority: Defined to configure the priority level for each GCE hardware thread. This is necessary for proper scheduling and execution of commands in the GCE. - GCE Subsys ID: Defined to specify the subsystem ID for GCE clients. This is used to correctly address and access different subsystems within the GCE. - GCE Event: Defined to specify the events that the GCE can handle. These events are used by the driver to synchronize and manage hardware operations. Examples of the binding usage in the driver code: 1) GCE Thread Priority: - Defined in the header file: `#define CMDQ_THR_PRIO_4 4` - Used in the Device Tree: `mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;` - Parsed and used in the driver to set thread priority: ```c static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,i const struct of_phandle_args *sp) { thread->priority = sp->args[1]; } // set GCE thread priority to the priority level 4 for GCE thread 0 writel(thread->priority, thread->base + CMDQ_THR_PRIORITY); ``` 2) GCE Subsys ID: - Defined in the header file: `#define SUBSYS_1c00XXXX 3` - Used in the Device Tree: `mediatek,gce-client-reg = <&gce SUBSYS_1c00XXXX 0x0000 0x1000>;` - Parsed and used in the driver to configure subsys ID: ```c int cmdq_dev_get_client_reg(struct device *dev, struct cmdq_client_reg *client_reg, int idx) { client_reg->subsys = (u8)spec.args[0]; client_reg->offset = (u16)spec.args[1]; } // GCE write the value to the register 0x1c000000 + 0x0000 + offset cmdq_pkt_write(cmdq_handle, client_reg->subsys, client_reg->offset + offset, value); ``` 3) GCE Event: - Defined in the header file: `#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0 574` - Used in the Device Tree: `mediatek,gce-events = ;` - Parsed and used in the driver to handle events: ```c int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path, unsigned int path_len, int priv_data_index, const struct mtk_drm_route *conn_routes, unsigned int num_conn_routes) { of_property_read_u32_index(priv->mutex_node, "mediatek,gce-events", i, &mtk_crtc->cmdq_event); } // GCE clear the STREAM_DONE event sent from DISP_MUTEX hardware cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event); ``` Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-2-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Id64bb29ec583b2c9b0d218485e873413618bb41f Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108926 Reviewed-by: Sean Paul Reviewed-by: Pin-yen Lin Commit-Queue: ChromeOS Auto Retry Tested-by: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- .../mailbox/mediatek,gce-mailbox.yaml | 4 + .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1415 +++++++++++++++++ 2 files changed, 1419 insertions(+) create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml index cef9d76013985..73d6db34d64a5 100644 --- a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml @@ -25,6 +25,7 @@ properties: - mediatek,mt8188-gce - mediatek,mt8192-gce - mediatek,mt8195-gce + - mediatek,mt8196-gce - items: - const: mediatek,mt6795-gce - const: mediatek,mt8173-gce @@ -49,6 +50,9 @@ properties: items: - const: gce + iommus: + maxItems: 1 + required: - compatible - "#mbox-cells" diff --git a/include/dt-bindings/mailbox/mediatek,mt8196-gce.h b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h new file mode 100644 index 0000000000000..9e07002360334 --- /dev/null +++ b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h @@ -0,0 +1,1415 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2024 MediaTek Inc. + * + */ + +#ifndef _DT_BINDINGS_GCE_MT8196_H +#define _DT_BINDINGS_GCE_MT8196_H + +/* GCE thread priority */ +#define CMDQ_THR_PRIO_LOWEST 0 +#define CMDQ_THR_PRIO_1 1 +#define CMDQ_THR_PRIO_2 2 +#define CMDQ_THR_PRIO_3 3 +#define CMDQ_THR_PRIO_4 4 +#define CMDQ_THR_PRIO_5 5 +#define CMDQ_THR_PRIO_6 6 +#define CMDQ_THR_PRIO_HIGHEST 7 + +/* GCE subsys table */ +#define SUBSYS_1300XXXX 0 +#define SUBSYS_1400XXXX 1 +#define SUBSYS_1401XXXX 2 +#define SUBSYS_1402XXXX 3 +#define SUBSYS_1502XXXX 4 +#define SUBSYS_1880XXXX 5 +#define SUBSYS_1881XXXX 6 +#define SUBSYS_1882XXXX 7 +#define SUBSYS_1883XXXX 8 +#define SUBSYS_1884XXXX 9 +#define SUBSYS_1000XXXX 10 +#define SUBSYS_1001XXXX 11 +#define SUBSYS_1002XXXX 12 +#define SUBSYS_1003XXXX 13 +#define SUBSYS_1004XXXX 14 +#define SUBSYS_1005XXXX 15 +#define SUBSYS_1020XXXX 16 +#define SUBSYS_1028XXXX 17 +#define SUBSYS_1700XXXX 18 +#define SUBSYS_1701XXXX 19 +#define SUBSYS_1702XXXX 20 +#define SUBSYS_1703XXXX 21 +#define SUBSYS_1800XXXX 22 +#define SUBSYS_1801XXXX 23 +#define SUBSYS_1802XXXX 24 +#define SUBSYS_1804XXXX 25 +#define SUBSYS_1805XXXX 26 +#define SUBSYS_1808XXXX 27 +#define SUBSYS_180aXXXX 28 +#define SUBSYS_180bXXXX 29 +#define SUBSYS_NO_SUPPORT 99 + +/* GCE-D hardware events */ +#define CMDQ_EVENT_DISP0_STREAM_SOF0 0 +#define CMDQ_EVENT_DISP0_STREAM_SOF1 1 +#define CMDQ_EVENT_DISP0_STREAM_SOF2 2 +#define CMDQ_EVENT_DISP0_STREAM_SOF3 3 +#define CMDQ_EVENT_DISP0_STREAM_SOF4 4 +#define CMDQ_EVENT_DISP0_STREAM_SOF5 5 +#define CMDQ_EVENT_DISP0_STREAM_SOF6 6 +#define CMDQ_EVENT_DISP0_STREAM_SOF7 7 +#define CMDQ_EVENT_DISP0_STREAM_SOF8 8 +#define CMDQ_EVENT_DISP0_STREAM_SOF9 9 +#define CMDQ_EVENT_DISP0_STREAM_SOF10 10 +#define CMDQ_EVENT_DISP0_STREAM_SOF11 11 +#define CMDQ_EVENT_DISP0_STREAM_SOF12 12 +#define CMDQ_EVENT_DISP0_STREAM_SOF13 13 +#define CMDQ_EVENT_DISP0_STREAM_SOF14 14 +#define CMDQ_EVENT_DISP0_STREAM_SOF15 15 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL0 16 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL1 17 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL2 18 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL3 19 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL4 20 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL5 21 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL6 22 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL7 23 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL8 24 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL9 25 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL10 26 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL11 27 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL12 28 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL13 29 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL14 30 +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL15 31 +#define CMDQ_EVENT_DISP0_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 32 +#define CMDQ_EVENT_DISP0_DISP_WDMA0_SW_RST_DONE_ENG_EVENT 33 +#define CMDQ_EVENT_DISP0_DISP_POSTMASK1_RST_DONE_ENG_EVENT 34 +#define CMDQ_EVENT_DISP0_DISP_POSTMASK0_RST_DONE_ENG_EVENT 35 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_TIMEOUT_ENG_EVENT 36 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT0 37 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT1 38 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT2 39 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT3 40 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT4 41 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT5 42 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT6 43 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT7 44 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT8 45 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT9 46 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT10 47 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT11 48 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT12 49 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT13 50 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT14 51 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT15 52 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_GET_RELEASE_ENG_EVENT 53 +#define CMDQ_EVENT_DISP0_DISP_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 54 + +#define CMDQ_EVENT_DISP1_STREAM_SOF0 55 +#define CMDQ_EVENT_DISP1_STREAM_SOF1 56 +#define CMDQ_EVENT_DISP1_STREAM_SOF2 57 +#define CMDQ_EVENT_DISP1_STREAM_SOF3 58 +#define CMDQ_EVENT_DISP1_STREAM_SOF4 59 +#define CMDQ_EVENT_DISP1_STREAM_SOF5 60 +#define CMDQ_EVENT_DISP1_STREAM_SOF6 61 +#define CMDQ_EVENT_DISP1_STREAM_SOF7 62 +#define CMDQ_EVENT_DISP1_STREAM_SOF8 63 +#define CMDQ_EVENT_DISP1_STREAM_SOF9 64 +#define CMDQ_EVENT_DISP1_STREAM_SOF10 65 +#define CMDQ_EVENT_DISP1_STREAM_SOF11 66 +#define CMDQ_EVENT_DISP1_STREAM_SOF12 67 +#define CMDQ_EVENT_DISP1_STREAM_SOF13 68 +#define CMDQ_EVENT_DISP1_STREAM_SOF14 69 +#define CMDQ_EVENT_DISP1_STREAM_SOF15 70 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL0 71 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL1 72 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL2 73 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL3 74 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL4 75 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL5 76 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL6 77 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL7 78 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL8 79 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL9 80 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL10 81 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL11 82 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL12 83 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL13 84 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL14 85 +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL15 86 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT0 87 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT1 88 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT2 89 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT3 90 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT4 91 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT5 92 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT6 93 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT7 94 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT8 95 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT9 96 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT10 97 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT11 98 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT12 99 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT13 100 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT14 101 +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT15 102 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT0 103 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT1 104 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT2 105 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT3 106 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT4 107 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT5 108 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT6 109 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT7 110 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT8 111 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT9 112 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT10 113 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT11 114 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT12 115 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT13 116 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT14 117 +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT15 118 +#define CMDQ_EVENT_DISP1_OCIP_SUBSYS_SRAM_ISOINT_ENG_EVENT 119 +#define CMDQ_EVENT_DISP1_DISP_WDMA4_TARGET_LINE_END_ENG_EVENT 120 +#define CMDQ_EVENT_DISP1_DISP_WDMA4_SW_RST_DONE_ENG_EVENT 121 +#define CMDQ_EVENT_DISP1_DISP_WDMA3_TARGET_LINE_END_ENG_EVENT 122 +#define CMDQ_EVENT_DISP1_DISP_WDMA3_SW_RST_DONE_ENG_EVENT 123 +#define CMDQ_EVENT_DISP1_DISP_WDMA2_TARGET_LINE_END_ENG_EVENT 124 +#define CMDQ_EVENT_DISP1_DISP_WDMA2_SW_RST_DONE_ENG_EVENT 125 +#define CMDQ_EVENT_DISP1_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 126 +#define CMDQ_EVENT_DISP1_DISP_WDMA1_SW_RST_DONE_ENG_EVENT 127 +#define CMDQ_EVENT_DISP1_DISP_MUTEX0_TIMEOUT_ENG_EVENT 128 +#define CMDQ_EVENT_DISP1_DISP_MUTEX0_GET_RLZ_ENG_EVENT 129 +#define CMDQ_EVENT_DISP1_DISP_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 130 +#define CMDQ_EVENT_DISP1_DISP_GDMA0_SW_RST_DONE_ENG_EVENT 131 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_START_ENG_EVENT 132 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_END_ENG_EVENT 133 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VRR_VFP_LAST_SAFE_BLANK_ENG_EVENT 134 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_START_ENG_EVENT 135 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_LAST_LINE_ENG_EVENT 136 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VDE_END_ENG_EVENT 137 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TRIGGER_LOOP_CLR_ENG_EVENT 138 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE1_ENG_EVENT 139 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE0_ENG_EVENT 140 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_START_ENG_EVENT 141 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_END_ENG_EVENT 142 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_START_ENG_EVENT 143 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_END_ENG_EVENT 144 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT0 145 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT1 146 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT2 147 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT3 148 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT4 149 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT5 150 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT6 151 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT7 152 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT8 153 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT9 154 +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT10 155 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT0 156 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT1 157 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT2 158 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT3 159 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT4 160 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT5 161 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT6 162 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT7 163 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT8 164 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT9 165 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT10 166 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT11 167 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT12 168 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT13 169 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT14 170 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT15 171 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT16 172 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT17 173 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT18 174 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT19 175 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT20 176 +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT21 177 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT0 178 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT1 179 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT2 180 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT3 181 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT4 182 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT5 183 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT6 184 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT7 185 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT8 186 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT9 187 +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT10 188 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_START_ENG_EVENT 189 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_END_ENG_EVENT 190 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_START_ENG_EVENT 191 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_END_ENG_EVENT 192 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_TARGET_LINE_ENG_EVENT 193 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_START_ENG_EVENT 194 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_END_ENG_EVENT 195 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_START_ENG_EVENT 196 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_END_ENG_EVENT 197 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_TARGET_LINE_ENG_EVENT 198 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT0 199 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT1 200 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT2 201 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT3 202 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT4 203 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT5 204 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT6 205 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT7 206 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT8 207 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT9 208 +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT10 209 + +#define CMDQ_EVENT_MML0_STREAM_SOF0 210 +#define CMDQ_EVENT_MML0_STREAM_SOF1 211 +#define CMDQ_EVENT_MML0_STREAM_SOF2 212 +#define CMDQ_EVENT_MML0_STREAM_SOF3 213 +#define CMDQ_EVENT_MML0_STREAM_SOF4 214 +#define CMDQ_EVENT_MML0_STREAM_SOF5 215 +#define CMDQ_EVENT_MML0_STREAM_SOF6 216 +#define CMDQ_EVENT_MML0_STREAM_SOF7 217 +#define CMDQ_EVENT_MML0_STREAM_SOF8 218 +#define CMDQ_EVENT_MML0_STREAM_SOF9 219 +#define CMDQ_EVENT_MML0_STREAM_SOF10 220 +#define CMDQ_EVENT_MML0_STREAM_SOF11 221 +#define CMDQ_EVENT_MML0_STREAM_SOF12 222 +#define CMDQ_EVENT_MML0_STREAM_SOF13 223 +#define CMDQ_EVENT_MML0_STREAM_SOF14 224 +#define CMDQ_EVENT_MML0_STREAM_SOF15 225 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL0 226 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL1 227 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL2 228 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL3 229 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL4 230 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL5 231 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL6 232 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL7 233 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL8 234 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL9 235 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL10 236 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL11 237 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL12 238 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL13 239 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL14 240 +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL15 241 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT0 242 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT1 243 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT2 244 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT3 245 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT4 246 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT5 247 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT6 248 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT7 249 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT8 250 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT9 251 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT10 252 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT11 253 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT12 254 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT13 255 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT14 256 +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT15 257 +#define CMDQ_EVENT_MML0_MDP_WROT2_SW_RST_DONE_ENG_EVENT 258 +#define CMDQ_EVENT_MML0_MDP_WROT1_SW_RST_DONE_ENG_EVENT 259 +#define CMDQ_EVENT_MML0_MDP_WROT0_SW_RST_DONE_ENG_EVENT 260 +#define CMDQ_EVENT_MML0_MDP_RROT0_SW_RST_DONE_ENG_EVENT 261 +#define CMDQ_EVENT_MML0_MDP_RDMA2_SW_RST_DONE_ENG_EVENT 262 +#define CMDQ_EVENT_MML0_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 263 +#define CMDQ_EVENT_MML0_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 264 +#define CMDQ_EVENT_MML0_MDP_MERGE0_SW_RST_DONE_ENG_EVENT 265 +#define CMDQ_EVENT_MML0_DISP_MUTEX0_TIMEOUT_ENG_EVENT 266 +#define CMDQ_EVENT_MML0_DISP_MUTEX0_GET_RLZ_ENG_EVENT 267 + +#define CMDQ_EVENT_MML1_STREAM_SOF0 268 +#define CMDQ_EVENT_MML1_STREAM_SOF1 269 +#define CMDQ_EVENT_MML1_STREAM_SOF2 270 +#define CMDQ_EVENT_MML1_STREAM_SOF3 271 +#define CMDQ_EVENT_MML1_STREAM_SOF4 272 +#define CMDQ_EVENT_MML1_STREAM_SOF5 273 +#define CMDQ_EVENT_MML1_STREAM_SOF6 274 +#define CMDQ_EVENT_MML1_STREAM_SOF7 275 +#define CMDQ_EVENT_MML1_STREAM_SOF8 276 +#define CMDQ_EVENT_MML1_STREAM_SOF9 277 +#define CMDQ_EVENT_MML1_STREAM_SOF10 278 +#define CMDQ_EVENT_MML1_STREAM_SOF11 279 +#define CMDQ_EVENT_MML1_STREAM_SOF12 280 +#define CMDQ_EVENT_MML1_STREAM_SOF13 281 +#define CMDQ_EVENT_MML1_STREAM_SOF14 282 +#define CMDQ_EVENT_MML1_STREAM_SOF15 283 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL0 284 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL1 285 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL2 286 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL3 287 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL4 288 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL5 289 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL6 290 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL7 291 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL8 292 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL9 293 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL10 294 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL11 295 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL12 296 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL13 297 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL14 298 +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL15 299 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT0 300 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT1 301 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT2 302 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT3 303 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT4 304 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT5 305 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT6 306 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT7 307 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT8 308 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT9 309 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT10 310 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT11 311 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT12 312 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT13 313 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT14 314 +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT15 315 +#define CMDQ_EVENT_MML1_MDP_WROT2_SW_RST_DONE_ENG_EVENT 316 +#define CMDQ_EVENT_MML1_MDP_WROT1_SW_RST_DONE_ENG_EVENT 317 +#define CMDQ_EVENT_MML1_MDP_WROT0_SW_RST_DONE_ENG_EVENT 318 +#define CMDQ_EVENT_MML1_MDP_RROT0_SW_RST_DONE_ENG_EVENT 319 +#define CMDQ_EVENT_MML1_MDP_RDMA2_SW_RST_DONE_ENG_EVENT 320 +#define CMDQ_EVENT_MML1_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 321 +#define CMDQ_EVENT_MML1_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 322 +#define CMDQ_EVENT_MML1_MDP_MERGE0_SW_RST_DONE_ENG_EVENT 323 +#define CMDQ_EVENT_MML1_DISP_MUTEX0_TIMEOUT_ENG_EVENT 324 +#define CMDQ_EVENT_MML1_DISP_MUTEX0_GET_RLZ_ENG_EVENT 325 + +#define CMDQ_EVENT_OVL0_STREAM_SOF0 326 +#define CMDQ_EVENT_OVL0_STREAM_SOF1 327 +#define CMDQ_EVENT_OVL0_STREAM_SOF2 328 +#define CMDQ_EVENT_OVL0_STREAM_SOF3 329 +#define CMDQ_EVENT_OVL0_STREAM_SOF4 330 +#define CMDQ_EVENT_OVL0_STREAM_SOF5 331 +#define CMDQ_EVENT_OVL0_STREAM_SOF6 332 +#define CMDQ_EVENT_OVL0_STREAM_SOF7 333 +#define CMDQ_EVENT_OVL0_STREAM_SOF8 334 +#define CMDQ_EVENT_OVL0_STREAM_SOF9 335 +#define CMDQ_EVENT_OVL0_STREAM_SOF10 336 +#define CMDQ_EVENT_OVL0_STREAM_SOF11 337 +#define CMDQ_EVENT_OVL0_STREAM_SOF12 338 +#define CMDQ_EVENT_OVL0_STREAM_SOF13 339 +#define CMDQ_EVENT_OVL0_STREAM_SOF14 340 +#define CMDQ_EVENT_OVL0_STREAM_SOF15 341 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL0 342 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL1 343 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL2 344 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL3 345 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL4 346 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL5 347 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL6 348 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL7 349 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL8 350 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL9 351 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL10 352 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL11 353 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL12 354 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL13 355 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL14 356 +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL15 357 +#define CMDQ_EVENT_OVL0_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT 358 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_TIMEOUT_ENG_EVENT 359 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0 360 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1 361 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2 362 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3 363 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4 364 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5 365 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6 366 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7 367 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8 368 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9 369 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10 370 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11 371 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12 372 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13 373 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14 374 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15 375 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_GET_RELEASE_ENG_EVENT 376 +#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 377 +#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 378 +#define CMDQ_EVENT_OVL0_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT 379 +#define CMDQ_EVENT_OVL0_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT 380 +#define CMDQ_EVENT_OVL0_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT 381 +#define CMDQ_EVENT_OVL0_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT 382 +#define CMDQ_EVENT_OVL0_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT 383 +#define CMDQ_EVENT_OVL0_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT 384 +#define CMDQ_EVENT_OVL0_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT 385 +#define CMDQ_EVENT_OVL0_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT 386 +#define CMDQ_EVENT_OVL0_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT 387 +#define CMDQ_EVENT_OVL0_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT 388 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 389 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT 390 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 391 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT 392 +#define CMDQ_EVENT_OVL0_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT 393 +#define CMDQ_EVENT_OVL1_STREAM_SOF0 394 +#define CMDQ_EVENT_OVL1_STREAM_SOF1 395 +#define CMDQ_EVENT_OVL1_STREAM_SOF2 396 +#define CMDQ_EVENT_OVL1_STREAM_SOF3 397 +#define CMDQ_EVENT_OVL1_STREAM_SOF4 398 +#define CMDQ_EVENT_OVL1_STREAM_SOF5 399 +#define CMDQ_EVENT_OVL1_STREAM_SOF6 400 +#define CMDQ_EVENT_OVL1_STREAM_SOF7 401 +#define CMDQ_EVENT_OVL1_STREAM_SOF8 402 +#define CMDQ_EVENT_OVL1_STREAM_SOF9 403 +#define CMDQ_EVENT_OVL1_STREAM_SOF10 404 +#define CMDQ_EVENT_OVL1_STREAM_SOF11 405 +#define CMDQ_EVENT_OVL1_STREAM_SOF12 406 +#define CMDQ_EVENT_OVL1_STREAM_SOF13 407 +#define CMDQ_EVENT_OVL1_STREAM_SOF14 408 +#define CMDQ_EVENT_OVL1_STREAM_SOF15 409 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL0 410 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL1 411 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL2 412 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL3 413 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL4 414 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL5 415 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL6 416 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL7 417 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL8 418 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL9 419 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL10 420 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL11 421 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL12 422 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL13 423 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL14 424 +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL15 425 +#define CMDQ_EVENT_OVL1_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT 426 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_TIMEOUT_ENG_EVENT 427 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0 428 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1 429 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2 430 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3 431 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4 432 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5 433 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6 434 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7 435 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8 436 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9 437 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10 438 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11 439 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12 440 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13 441 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14 442 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15 443 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_GET_RELEASE_ENG_EVENT 444 +#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 445 +#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 446 +#define CMDQ_EVENT_OVL1_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT 447 +#define CMDQ_EVENT_OVL1_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT 448 +#define CMDQ_EVENT_OVL1_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT 449 +#define CMDQ_EVENT_OVL1_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT 450 +#define CMDQ_EVENT_OVL1_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT 451 +#define CMDQ_EVENT_OVL1_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT 452 +#define CMDQ_EVENT_OVL1_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT 453 +#define CMDQ_EVENT_OVL1_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT 454 +#define CMDQ_EVENT_OVL1_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT 455 +#define CMDQ_EVENT_OVL1_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT 456 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 457 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT 458 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 459 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT 460 +#define CMDQ_EVENT_OVL1_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT 461 + +#define CMDQ_EVENT_DPC_DT_DONE0 462 +#define CMDQ_EVENT_DPC_DT_DONE1 463 +#define CMDQ_EVENT_DPC_DT_DONE2_0_MERGE 464 +#define CMDQ_EVENT_DPC_DT_DONE2_1_MERGE 465 +#define CMDQ_EVENT_DPC_DT_DONE2_2_MERGE 466 +#define CMDQ_EVENT_DPC_DT_DONE2_3_MERGE 467 +#define CMDQ_EVENT_DPC_DT_DONE3 468 +#define CMDQ_EVENT_DPC_DT_DONE4_MERGE 469 +#define CMDQ_EVENT_DPC_DT_DONE5 470 +#define CMDQ_EVENT_DPC_DT_DONE6_0_MERGE 471 +#define CMDQ_EVENT_DPC_DT_DONE6_1_MERGE 472 +#define CMDQ_EVENT_DPC_DT_DONE6_2_MERGE 473 +#define CMDQ_EVENT_DPC_DT_DONE6_3_MERGE 474 +#define CMDQ_EVENT_DPC_DT_DONE7 475 +#define CMDQ_EVENT_DPC_DT_DONE32_MERGE 476 +#define CMDQ_EVENT_DPC_DT_DONE33 477 +#define CMDQ_EVENT_DPC_DT_DONE34_0 478 +#define CMDQ_EVENT_DPC_DT_DONE35 479 +#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_ON_BEFORE_OFF 480 +#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_PRETE_BEFORE_ON 481 +#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_ON_BEFORE_OFF 482 +#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_PRETE_BEFORE_ON 483 +#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_ON_BEFORE_OFF 484 +#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_PRETE_BEFORE_ON 485 +#define CMDQ_EVENT_DPC_DISP_SW_CONFIG_WHEN_MTCMOS_OFF 486 +#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_ON_BEFORE_OFF 487 +#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_PRETE_BEFORE_ON 488 +#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_ON_BEFORE_OFF 489 +#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_PRETE_BEFORE_ON 490 +#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_ON_BEFORE_OFF 491 +#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_PRETE_BEFORE_ON 492 +#define CMDQ_EVENT_DPC_MML_SW_CONFIG_WHEN_MTCMOS_OFF 493 +#define CMDQ_EVENT_DPTX_DPTX_EVENT0 494 +#define CMDQ_EVENT_DPTX_DPTX_EVENT1 495 +#define CMDQ_EVENT_DPTX_DPTX_EVENT2 496 +#define CMDQ_EVENT_DPTX_DPTX_EVENT3 497 +#define CMDQ_EVENT_EDPTX_EDPTX_EVENT0 498 +#define CMDQ_EVENT_EDPTX_EDPTX_EVENT1 499 + +#define CMDQ_EVENT_DSI0_TE_I_DSI0_TE_I 898 +#define CMDQ_EVENT_DSI1_TE_I_DSI1_TE_I 899 +#define CMDQ_EVENT_DSI2_TE_I_DSI2_TE_I 900 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_0 901 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_1 902 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_2 903 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_3 904 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_4 905 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_5 906 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_6 907 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_7 908 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_8 909 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_9 910 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_10 911 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_11 912 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_12 913 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_13 914 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_14 915 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_15 916 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_16 917 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_17 918 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_18 919 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_19 920 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_20 921 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_21 922 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_22 923 +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_23 924 +#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_0 925 +#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_1 926 +#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_0 927 +#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_1 928 +#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_0 929 +#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_1 930 +#define CMDQ_EVENT_DSI3_TE_I_DSI3_TE_I 931 +#define CMDQ_EVENT_SPI0_FINISH_EVENT_DSI4_TE_I 932 +#define CMDQ_EVENT_SPI0_EVENT_EVENT_DSI5_TE_I 933 + +/* GCE-M hardware events */ +#define CMDQ_EVENT_VENC3_VENC_RESERVED 0 +#define CMDQ_EVENT_VENC3_VENC_FRAME_DONE 1 +#define CMDQ_EVENT_VENC3_VENC_PAUSE_DONE 2 +#define CMDQ_EVENT_VENC3_JPGENC_DONE 3 +#define CMDQ_EVENT_VENC3_VENC_MB_DONE 4 +#define CMDQ_EVENT_VENC3_VENC_128BYTE_DONE 5 +#define CMDQ_EVENT_VENC3_JPGDEC_DONE 6 +#define CMDQ_EVENT_VENC3_JPGDEC_C1_DONE 7 +#define CMDQ_EVENT_VENC3_JPGDEC_INSUFF_DONE 8 +#define CMDQ_EVENT_VENC3_JPGDEC_C1_INSUFF_DONE 9 +#define CMDQ_EVENT_VENC3_WP_2ND_STAGE_DONE 10 +#define CMDQ_EVENT_VENC3_WP_3RD_STAGE_DONE 11 +#define CMDQ_EVENT_VENC3_PPS_HEADER_DONE 12 +#define CMDQ_EVENT_VENC3_SPS_HEADER_DONE 13 +#define CMDQ_EVENT_VENC3_VPS_HEADER_DONE 14 +#define CMDQ_EVENT_VENC3_VENC_SLICE_DONE 15 +#define CMDQ_EVENT_VENC3_VENC_SOC_SLICE_DONE 16 +#define CMDQ_EVENT_VENC3_VENC_SOC_FRAME_DONE 17 + +#define CMDQ_EVENT_VENC2_VENC_FRAME_DONE 33 +#define CMDQ_EVENT_VENC2_VENC_PAUSE_DONE 34 +#define CMDQ_EVENT_VENC2_JPGENC_DONE 35 +#define CMDQ_EVENT_VENC2_VENC_MB_DONE 36 +#define CMDQ_EVENT_VENC2_VENC_128BYTE_DONE 37 +#define CMDQ_EVENT_VENC2_JPGDEC_DONE 38 +#define CMDQ_EVENT_VENC2_JPGDEC_C1_DONE 39 +#define CMDQ_EVENT_VENC2_JPGDEC_INSUFF_DONE 40 +#define CMDQ_EVENT_VENC2_JPGDEC_C1_INSUFF_DONE 41 +#define CMDQ_EVENT_VENC2_WP_2ND_STAGE_DONE 42 +#define CMDQ_EVENT_VENC2_WP_3RD_STAGE_DONE 43 +#define CMDQ_EVENT_VENC2_PPS_HEADER_DONE 44 +#define CMDQ_EVENT_VENC2_SPS_HEADER_DONE 45 +#define CMDQ_EVENT_VENC2_VPS_HEADER_DONE 46 +#define CMDQ_EVENT_VENC2_VENC_SLICE_DONE 47 +#define CMDQ_EVENT_VENC2_VENC_SOC_SLICE_DONE 48 +#define CMDQ_EVENT_VENC2_VENC_SOC_FRAME_DONE 49 + +#define CMDQ_EVENT_VENC1_VENC_FRAME_DONE 65 +#define CMDQ_EVENT_VENC1_VENC_PAUSE_DONE 66 +#define CMDQ_EVENT_VENC1_JPGENC_DONE 67 +#define CMDQ_EVENT_VENC1_VENC_MB_DONE 68 +#define CMDQ_EVENT_VENC1_VENC_128BYTE_DONE 69 +#define CMDQ_EVENT_VENC1_JPGDEC_DONE 70 +#define CMDQ_EVENT_VENC1_JPGDEC_C1_DONE 71 +#define CMDQ_EVENT_VENC1_JPGDEC_INSUFF_DONE 72 +#define CMDQ_EVENT_VENC1_JPGDEC_C1_INSUFF_DONE 73 +#define CMDQ_EVENT_VENC1_WP_2ND_STAGE_DONE 74 +#define CMDQ_EVENT_VENC1_WP_3RD_STAGE_DONE 75 +#define CMDQ_EVENT_VENC1_PPS_HEADER_DONE 76 +#define CMDQ_EVENT_VENC1_SPS_HEADER_DONE 77 +#define CMDQ_EVENT_VENC1_VPS_HEADER_DONE 78 +#define CMDQ_EVENT_VENC1_VENC_SLICE_DONE 79 +#define CMDQ_EVENT_VENC1_VENC_SOC_SLICE_DONE 80 +#define CMDQ_EVENT_VENC1_VENC_SOC_FRAME_DONE 81 + +#define CMDQ_EVENT_VDEC1_VDEC_LINE_CNT_INT 192 +#define CMDQ_EVENT_VDEC1_VDEC_INT 193 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_2 194 +#define CMDQ_EVENT_VDEC1_VDEC_DEC_ERR 195 +#define CMDQ_EVENT_VDEC1_VDEC_BUSY_OVERFLOW 196 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_5 197 +#define CMDQ_EVENT_VDEC1_VDEC_INI_FETCH_RDY 198 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_7 199 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_8 200 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_9 201 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_10 202 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_11 203 + +#define CMDQ_EVENT_VDEC1_VDEC_GCE_CNT_OP_THR 207 + +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_32 224 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_INT 225 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_34 226 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_DEC_ERR 227 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_BUSY_OVERFLOW 228 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_37 229 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_INI_FETCH_RDY 230 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_39 231 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_40 232 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_41 233 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_42 234 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_43 235 + +#define CMDQ_EVENT_VDEC1_VDEC_LAT_GCE_CNT_OP_THR 239 + +#define CMDQ_EVENT_IMG_IMG_EVENT_0 256 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_0 257 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_1 258 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_2 259 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_3 260 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_4 261 +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_5 262 +#define CMDQ_EVENT_IMG_TRAW0_DMA_ERR_EVENT 263 +#define CMDQ_EVENT_IMG_TRAW0_DUMMY_0 264 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_0 265 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_1 266 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_2 267 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_3 268 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_4 269 +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_5 270 +#define CMDQ_EVENT_IMG_TRAW1_DMA_ERR_EVENT 271 +#define CMDQ_EVENT_IMG_ADL_TILE_DONE_EVENT 272 +#define CMDQ_EVENT_IMG_ADLWR0_TILE_DONE_EVENT 273 +#define CMDQ_EVENT_IMG_ADLWR1_TILE_DONE_EVENT 274 +#define CMDQ_EVENT_IMG_IMGSYS_IPE_ME_DONE 275 +#define CMDQ_EVENT_IMG_IMGSYS_IPE_MMG_DONE 276 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_0 277 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_1 278 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_2 279 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_3 280 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_4 281 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_5 282 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_6 283 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_7 284 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_8 285 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_9 286 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_10 287 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_11 288 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_12 289 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_13 290 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_14 291 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_15 292 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_16 293 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_17 294 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_18 295 +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_19 296 +#define CMDQ_EVENT_IMG_QOF_ON_EVENT_0 297 +#define CMDQ_EVENT_IMG_QOF_ON_EVENT_1 298 +#define CMDQ_EVENT_IMG_QOF_ON_EVENT_2 299 +#define CMDQ_EVENT_IMG_QOF_ON_EVENT_3 300 +#define CMDQ_EVENT_IMG_QOF_ON_EVENT_4 301 +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_0 302 +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_1 303 +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_2 304 +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_3 305 +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_4 306 +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_0 307 +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_1 308 +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_2 309 +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_3 310 +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_4 311 +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_0 312 +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_1 313 +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_2 314 +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_3 315 +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_4 316 + +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_0 317 +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_1 318 +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_2 319 +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_3 320 +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_4 321 +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_5 322 +#define CMDQ_EVENT_IMG_DIP_DMA_ERR_EVENT 323 +#define CMDQ_EVENT_IMG_DIP_NR_DMA_ERR_EVENT 324 +#define CMDQ_EVENT_IMG_DIP_DUMMY_0 325 + +#define CMDQ_EVENT_IMG_WPE_EIS_GCE_FRAME_DONE 326 +#define CMDQ_EVENT_IMG_WPE_EIS_DONE_SYNC_OUT 327 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_0 328 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_1 329 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_2 330 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_3 331 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_4 332 +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_5 333 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_0 334 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_1 335 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_2 336 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_3 337 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_4 338 +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_5 339 +#define CMDQ_EVENT_IMG_PQA_DMA_ERR_EVENT 340 +#define CMDQ_EVENT_IMG_WPE0_DUMMY_0 341 +#define CMDQ_EVENT_IMG_WPE0_DUMMY_1 342 +#define CMDQ_EVENT_IMG_WPE0_DUMMY_2 343 +#define CMDQ_EVENT_IMG_OMC_TNR_GCE_FRAME_DONE 344 +#define CMDQ_EVENT_IMG_OMC_TNR_DONE_SYNC_OUT 345 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_0 346 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_1 347 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_2 348 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_3 349 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_4 350 +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_5 351 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_0 352 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_1 353 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_2 354 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_3 355 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_4 356 +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_5 357 +#define CMDQ_EVENT_IMG_PQB_DMA_ERR_EVENT 358 +#define CMDQ_EVENT_IMG_WPE1_DUMMY_0 359 +#define CMDQ_EVENT_IMG_WPE1_DUMMY_1 360 +#define CMDQ_EVENT_IMG_WPE1_DUMMY_2 361 +#define CMDQ_EVENT_IMG_WPE_LITE_GCE_FRAME_DONE 362 +#define CMDQ_EVENT_IMG_WPE_LITE_DONE_SYNC_OUT 363 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_0 364 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_1 365 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_2 366 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_3 367 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_4 368 +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_5 369 +#define CMDQ_EVENT_IMG_OMC_LITE_GCE_FRAME_DONE 370 +#define CMDQ_EVENT_IMG_OMC_LITE_DONE_SYNC_OUT 371 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_0 372 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_1 373 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_2 374 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_3 375 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_4 376 +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_5 377 +#define CMDQ_EVENT_IMG_WPE2_DUMMY_0 378 +#define CMDQ_EVENT_IMG_WPE2_DUMMY_1 379 +#define CMDQ_EVENT_IMG_WPE2_DUMMY_2 380 +#define CMDQ_EVENT_IMG_IMGSYS_IPE_FDVT0_DONE 381 +#define CMDQ_EVENT_IMG_IMG_EVENT_126 382 +#define CMDQ_EVENT_IMG_IMG_EVENT_127 383 + +#define CMDQ_EVENT_CAM_CAM_EVENT_0 384 +#define CMDQ_EVENT_CAM_CAM_SUBA_SW_PASS1_DONE 385 +#define CMDQ_EVENT_CAM_CAM_SUBB_SW_PASS1_DONE 386 +#define CMDQ_EVENT_CAM_CAM_SUBC_SW_PASS1_DONE 387 +#define CMDQ_EVENT_CAM_CAM_SUBA_TFMR_PASS1_DONE 388 +#define CMDQ_EVENT_CAM_CAM_SUBB_TFMR_PASS1_DONE 389 +#define CMDQ_EVENT_CAM_CAM_SUBC_TFMR_PASS1_DONE 390 +#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_0 391 +#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_1 392 +#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_2 393 +#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_3 394 +#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_0 395 +#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_1 396 +#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_2 397 +#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_3 398 +#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_0 399 +#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_1 400 +#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_2 401 +#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_3 402 +#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_0 403 +#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_1 404 +#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_2 405 +#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_3 406 +#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_0 407 +#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_1 408 +#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_2 409 +#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_3 410 +#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_0 411 +#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_1 412 +#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_2 413 +#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_3 414 +#define CMDQ_EVENT_CAM_MRAW0_SW_PASS1_DONE 415 +#define CMDQ_EVENT_CAM_MRAW1_SW_PASS1_DONE 416 +#define CMDQ_EVENT_CAM_MRAW2_SW_PASS1_DONE 417 +#define CMDQ_EVENT_CAM_MRAW3_SW_PASS1_DONE 418 +#define CMDQ_EVENT_CAM_UISP_SW_PASS1_DONE 419 +#define CMDQ_EVENT_CAM_TG_MRAW0_OUT_SOF 420 +#define CMDQ_EVENT_CAM_TG_MRAW1_OUT_SOF 421 +#define CMDQ_EVENT_CAM_TG_MRAW2_OUT_SOF 422 +#define CMDQ_EVENT_CAM_TG_MRAW3_OUT_SOF 423 +#define CMDQ_EVENT_CAM_PDA0_IRQO_EVENT_DONE_D1 424 +#define CMDQ_EVENT_CAM_PDA1_IRQO_EVENT_DONE_D1 425 + +#define CMDQ_EVENT_CAM_DPE_DVP_CMQ_EVENT 426 +#define CMDQ_EVENT_CAM_DPE_DVS_CMQ_EVENT 427 +#define CMDQ_EVENT_CAM_DPE_DVFG_CMQ_EVENT 428 +#define CMDQ_EVENT_CAM_CAM_EVENT_45 429 +#define CMDQ_EVENT_CAM_CAM_EVENT_46 430 +#define CMDQ_EVENT_CAM_CAM_EVENT_47 431 +#define CMDQ_EVENT_CAM_CAM_EVENT_48 432 +#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT1 433 +#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT2 434 +#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT3 435 +#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT4 436 +#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT1 437 +#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT2 438 +#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT3 439 +#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT4 440 +#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT1 441 +#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT2 442 +#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT3 443 +#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT4 444 +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBA 445 +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBB 446 +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBC 447 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBA 448 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBB 449 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBC 450 +#define CMDQ_EVENT_CAM_RAW_SEL_SOF_UISP 451 +#define CMDQ_EVENT_CAM_CAM_SUBA_RING_BUFFER_OVERFLOW_INT_IN 452 +#define CMDQ_EVENT_CAM_CAM_SUBB_RING_BUFFER_OVERFLOW_INT_IN 453 +#define CMDQ_EVENT_CAM_CAM_SUBC_RING_BUFFER_OVERFLOW_INT_IN 454 +#define CMDQ_EVENT_CAM_CAM_EVENT_71 455 +#define CMDQ_EVENT_CAM_ADL_WR_FRAME_DONE 456 +#define CMDQ_EVENT_CAM_ADL_RD_FRAME_DONE 457 +#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_ON_EVENT 458 +#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_ON_EVENT 459 +#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_ON_EVENT 460 +#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_OFF_EVENT 461 +#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_OFF_EVENT 462 +#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_OFF_EVENT 463 +#define CMDQ_EVENT_CAM_QOF_RAWA_SAVE_EVENT 464 +#define CMDQ_EVENT_CAM_QOF_RAWB_SAVE_EVENT 465 +#define CMDQ_EVENT_CAM_QOF_RAWC_SAVE_EVENT 466 +#define CMDQ_EVENT_CAM_QOF_RAWA_RESTORE_EVENT 467 +#define CMDQ_EVENT_CAM_QOF_RAWB_RESTORE_EVENT 468 +#define CMDQ_EVENT_CAM_QOF_RAWC_RESTORE_EVENT 469 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_0 470 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_1 471 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_2 472 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_3 473 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_4 474 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_5 475 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_6 476 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_7 477 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_8 478 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_9 479 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_10 480 +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_11 481 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_0 482 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_1 483 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_2 484 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_3 485 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_4 486 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_5 487 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_6 488 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_7 489 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_8 490 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_9 491 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_10 492 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_11 493 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_12 494 +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_13 495 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_NON_SEC_IRQ 496 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_SEC_IRQ 497 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_VM_IRQ 498 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_EXCH_VM_IRQ 499 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_NON_SEC_IRQ 500 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_SEC_IRQ 501 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_VM_IRQ 502 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_EXCH_VM_IRQ 503 +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_0 504 +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_1 505 +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_2 506 +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_3 507 +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_4 508 +#define CMDQ_EVENT_CAM_CAM_EVENT_125 509 +#define CMDQ_EVENT_CAM_CAM_EVENT_126 510 +#define CMDQ_EVENT_CAM_CAM_EVENT_127 511 + +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MMSRAM_COMM_SMIASSER 898 +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MDP_COMM_SMIASSER 899 +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_DISP_COMM_SMIASSER 900 + +#define CMDQ_MAX_HW_EVENT 512 +/* End of hardware event and begin of software token */ + +/* + * CMDQ software tokens: + * The following are GCE software tokens, which can be used by clients + * event to operate API. + */ + +/* Begin of GCE-D software token */ +/* MML software tokens */ +#define CMDQ_SYNC_TOKEN_MML_BUFA 630 +#define CMDQ_SYNC_TOKEN_MML_BUFB 631 +#define CMDQ_SYNC_TOKEN_MML_BUF_NEXT 632 +#define CMDQ_SYNC_TOKEN_MML_IR_MML_READY 633 +#define CMDQ_SYNC_TOKEN_MML_IR_DISP_READY 634 +#define CMDQ_SYNC_TOKEN_MML_MML_STOP 635 +#define CMDQ_SYNC_TOKEN_MML_PIPE0 636 +#define CMDQ_SYNC_TOKEN_MML_PIPE1 637 +#define CMDQ_SYNC_TOKEN_MML_PIPE1_NEXT 638 +#define CMDQ_SYNC_TOKEN_MML_APU_START 639 + +/* Config thread notify trigger thread */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY 640 +/* Trigger thread notify config thread */ +#define CMDQ_SYNC_TOKEN_STREAM_EOF 641 +/* Block Trigger thread until the ESD check finishes */ +#define CMDQ_SYNC_TOKEN_ESD_EOF 642 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK 643 +/* Check CABC setup finish */ +#define CMDQ_SYNC_TOKEN_CABC_EOF 644 + +/* VFP period token for Msync */ +#define CMDQ_SYNC_TOKEN_VFP_PERIOD 645 +/* Software sync token for dual display */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_1 694 +#define CMDQ_SYNC_TOKEN_STREAM_EOF_1 695 +#define CMDQ_SYNC_TOKEN_ESD_EOF_1 696 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_1 697 +#define CMDQ_SYNC_TOKEN_CABC_EOF_1 698 + +/* + * GPR access tokens (for HW register backup) + * There are 15 32-bit GPR, form 3 GPR as a set + * (64-bit for address, 32-bit for value) + */ +#define CMDQ_SYNC_TOKEN_GPR_SET_0 700 +#define CMDQ_SYNC_TOKEN_GPR_SET_1 701 +#define CMDQ_SYNC_TOKEN_GPR_SET_2 702 +#define CMDQ_SYNC_TOKEN_GPR_SET_3 703 +#define CMDQ_SYNC_TOKEN_GPR_SET_4 704 + +#define CMDQ_SYNC_TOKEN_TE_0 705 +#define CMDQ_SYNC_TOKEN_PREFETCH_TE_0 706 +#define CMDQ_SYNC_TOKEN_VIDLE_POWER_ON 707 +#define CMDQ_SYNC_TOKEN_CHECK_TRIGGER_MERGE 708 + +/* Resource lock event to control resource in GCE thread */ +#define CMDQ_SYNC_RESOURCE_WROT0 710 +#define CMDQ_SYNC_RESOURCE_WROT1 711 + +/* Hardware TRACE software token */ +#define CMDQ_SYNC_TOKEN_HW_TRACE_WAIT 712 +#define CMDQ_SYNC_TOKEN_HW_TRACE_LOCK 713 + +/* Software sync token for dual display */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_3 714 +#define CMDQ_SYNC_TOKEN_STREAM_EOF_3 715 +#define CMDQ_SYNC_TOKEN_ESD_EOF_3 716 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_3 717 +#define CMDQ_SYNC_TOKEN_CABC_EOF_3 718 +/* End of GCE-D software token */ + +/* Begin of GCE-M software token */ +/* IMGSYS_POOL */ +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_1 514 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_2 515 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_3 516 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_4 517 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_5 518 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_6 519 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_7 520 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_8 521 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_9 522 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_10 523 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_11 524 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_12 525 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_13 526 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_14 527 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_15 528 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_16 529 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_17 530 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_18 531 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_19 532 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_20 533 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_21 534 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_22 535 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_23 536 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_24 537 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_25 538 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_26 539 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_27 540 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_28 541 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_29 542 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_30 543 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_31 544 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_32 545 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_33 546 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_34 547 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_35 548 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_36 549 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_37 550 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_38 551 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_39 552 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_40 553 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_41 554 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_42 555 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_43 556 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_44 557 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_45 558 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_46 559 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_47 560 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_48 561 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_49 562 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_50 563 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_51 564 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_52 565 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_53 566 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_54 567 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_55 568 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_56 569 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_57 570 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_58 571 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_59 572 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_60 573 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_61 574 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_62 575 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_63 576 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_64 577 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_65 578 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_66 579 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_67 580 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_68 581 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_69 582 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_70 583 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_71 584 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_72 585 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_73 586 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_74 587 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_75 588 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_76 589 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_77 590 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_78 591 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_79 592 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_80 593 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_81 594 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_82 595 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_83 596 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_84 597 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_85 598 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_86 599 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_87 600 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_88 601 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_89 602 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_90 603 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_91 604 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_92 605 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_93 606 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_94 607 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_95 608 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_96 609 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_97 610 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_98 611 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_99 612 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_100 613 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_101 614 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_102 615 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_103 616 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_104 617 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_105 618 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_106 619 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_107 620 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_108 621 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_109 622 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_110 623 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_111 624 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_112 625 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_113 626 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_114 627 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_115 628 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_116 629 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_117 630 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_118 631 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_119 632 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_120 633 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_121 634 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_122 635 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_123 636 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_124 637 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_125 638 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_126 639 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_127 640 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_128 641 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_129 642 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_130 643 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_131 644 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_132 645 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_133 646 + +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_134 694 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_135 695 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_136 696 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_137 697 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_138 698 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_139 699 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_140 700 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_141 701 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_142 702 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_143 703 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_144 704 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_145 705 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_146 706 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_147 707 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_148 708 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_149 709 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_150 710 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_151 711 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_152 714 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_153 715 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_154 716 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_155 717 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_156 718 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_157 719 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_158 720 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_159 721 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_160 722 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_161 723 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_162 724 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_163 725 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_164 726 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_165 727 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_166 728 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_167 729 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_168 730 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_169 731 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_170 732 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_171 733 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_172 734 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_173 735 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_174 736 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_175 737 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_176 738 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_177 739 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_178 740 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_179 741 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_180 742 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_181 743 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_182 744 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_183 745 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_184 746 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_185 747 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_186 748 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_187 749 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_188 750 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_189 751 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_190 752 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_191 753 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_192 754 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_193 755 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_194 756 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_195 757 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_196 758 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_197 759 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_198 760 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_199 761 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_200 762 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_201 763 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_202 764 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_203 765 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_204 766 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_205 767 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_206 784 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_207 785 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_208 786 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_209 787 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_210 788 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_211 789 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_212 790 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_213 791 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_214 792 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_215 793 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_216 794 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_217 795 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_218 796 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_219 797 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_220 798 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_221 799 + +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_222 833 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_223 834 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_224 835 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_225 836 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_226 837 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_227 838 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_228 839 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_229 840 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_230 841 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_231 842 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_232 843 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_233 844 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_234 845 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_235 846 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_236 847 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_237 848 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_238 849 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_239 850 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_240 851 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_241 852 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_242 853 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_243 854 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_244 855 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_245 856 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_246 857 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_247 858 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_248 859 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_249 860 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_250 861 + +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_251 901 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_252 902 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_253 903 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_254 904 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_255 905 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_256 906 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_257 907 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_258 908 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_259 909 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_260 910 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_261 911 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_262 912 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_263 913 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_264 914 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_265 915 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_266 916 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_267 917 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_268 918 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_269 919 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_270 920 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_271 921 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_272 922 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_273 923 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_274 924 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_275 925 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_276 926 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_277 927 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_278 928 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_279 929 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_280 930 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_281 931 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_282 932 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_283 933 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_284 934 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_285 935 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_286 936 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_287 937 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_288 938 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_289 939 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_290 940 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_291 941 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_292 942 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_293 943 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_294 944 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_295 945 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_296 946 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_297 947 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_298 948 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_299 949 +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_300 950 + +/* ISP software token */ +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS 665 +#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_TNR 666 +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_LITE 667 +#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW 668 +#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW 669 +#define CMDQ_SYNC_TOKEN_IMGSYS_XTRAW 670 +#define CMDQ_SYNC_TOKEN_IMGSYS_DIP 671 +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A 672 +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B 673 +#define CMDQ_SYNC_TOKEN_IPESYS_ME 674 +#define CMDQ_SYNC_TOKEN_APUSYS_APU 675 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_TRAW 676 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_LTRAW 677 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_XTRAW 678 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_DIP 679 +#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_LITE 680 + +/* IMG software token for QoS */ +#define CMDQ_SYNC_TOKEN_IMGSYS_QOS_LOCK 800 +/* IMG software token for Qof */ +#define CMDQ_SYNC_TOKEN_DIP_POWER_CTRL 862 +#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_ON 863 +#define CMDQ_SYNC_TOKEN_DIP_PWR_ON 864 +#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_OFF 865 +#define CMDQ_SYNC_TOKEN_DIP_PWR_OFF 866 +#define CMDQ_SYNC_TOKEN_DIP_PWR_HAND_SHAKE 867 + +#define CMDQ_SYNC_TOKEN_TRAW_POWER_CTRL 868 +#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_ON 869 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_ON 870 +#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_OFF 871 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_OFF 872 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_HAND_SHAKE 873 +/* End of GCE-M software token */ + +/* Begin of common software token */ + +/* + * Notify normal CMDQ there are some secure task done + * MUST NOT CHANGE, this token sync with secure world + */ +#define CMDQ_SYNC_SECURE_THR_EOF 647 + +/* CMDQ use software token */ +#define CMDQ_SYNC_TOKEN_USER_0 649 +#define CMDQ_SYNC_TOKEN_USER_1 650 +#define CMDQ_SYNC_TOKEN_POLL_MONITOR 651 +#define CMDQ_SYNC_TOKEN_TPR_LOCK 652 + +/* TZMP software token */ +#define CMDQ_SYNC_TOKEN_TZMP_DISP_WAIT 653 +#define CMDQ_SYNC_TOKEN_TZMP_DISP_SET 654 +#define CMDQ_SYNC_TOKEN_TZMP_ISP_WAIT 655 +#define CMDQ_SYNC_TOKEN_TZMP_ISP_SET 656 +#define CMDQ_SYNC_TOKEN_TZMP_AIE_WAIT 657 +#define CMDQ_SYNC_TOKEN_TZMP_AIE_SET 658 +#define CMDQ_SYNC_TOKEN_TZMP_ADL_WAIT 659 +#define CMDQ_SYNC_TOKEN_TZMP_ADL_SET 660 + +/* PREBUILT software token */ +#define CMDQ_SYNC_TOKEN_PREBUILT_MDP_LOCK 682 +#define CMDQ_SYNC_TOKEN_PREBUILT_MML_LOCK 685 +#define CMDQ_SYNC_TOKEN_PREBUILT_VFMT_LOCK 688 +#define CMDQ_SYNC_TOKEN_PREBUILT_DISP_LOCK 691 +#define CMDQ_SYNC_TOKEN_DISP_VA_START 692 +#define CMDQ_SYNC_TOKEN_DISP_VA_END 693 + +/* Event for GPR timer, used in sleep and poll with timeout */ +#define CMDQ_TOKEN_GPR_TIMER_R0 994 +#define CMDQ_TOKEN_GPR_TIMER_R1 995 +#define CMDQ_TOKEN_GPR_TIMER_R2 996 +#define CMDQ_TOKEN_GPR_TIMER_R3 997 +#define CMDQ_TOKEN_GPR_TIMER_R4 998 +#define CMDQ_TOKEN_GPR_TIMER_R5 999 +#define CMDQ_TOKEN_GPR_TIMER_R6 1000 +#define CMDQ_TOKEN_GPR_TIMER_R7 1001 +#define CMDQ_TOKEN_GPR_TIMER_R8 1002 +#define CMDQ_TOKEN_GPR_TIMER_R9 1003 +#define CMDQ_TOKEN_GPR_TIMER_R10 1004 +#define CMDQ_TOKEN_GPR_TIMER_R11 1005 +#define CMDQ_TOKEN_GPR_TIMER_R12 1006 +#define CMDQ_TOKEN_GPR_TIMER_R13 1007 +#define CMDQ_TOKEN_GPR_TIMER_R14 1008 +#define CMDQ_TOKEN_GPR_TIMER_R15 1009 +/* End of common software token */ +/* CMDQ software tokens END */ + +#endif -- GitLab From db1828b07c861df38dfb60a2e1f0ba9fd65b8054 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:55 +0800 Subject: [PATCH 236/456] FROMLIST: mailbox: mtk-cmdq: Add driver data to support for MT8196 MT8196 has 3 new hardware configuration compared with the previous SoC, which correspond to the 3 new driver data: 1. mminfra_offset: For GCE data plane control Since GCE has been moved into mminfra, GCE needs to append the mminfra offset to the DRAM address when accessing the DRAM. 2. gce_vm: For GCE hardware virtualization Currently, the first version of the mt8196 mailbox controller only requires setting the VM-related registers to enable the permissions of a host VM. 3. dma_mask_bit: For dma address bit control In order to avoid the hardware limitations of MT8196 accessing DRAM, GCE needs to configure the DMA address to be less than 35 bits. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-3-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: I7179a057ee4fdfbc7cfdb78a0bffe765c5886e27 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108927 Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Pin-yen Lin Commit-Queue: ChromeOS Auto Retry Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/mailbox/mtk-cmdq-mailbox.c | 90 +++++++++++++++++++++--- include/linux/mailbox/mtk-cmdq-mailbox.h | 2 + 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 6e927cab8a3d7..14dbff17d3707 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -44,6 +44,17 @@ #define GCE_CTRL_BY_SW GENMASK(2, 0) #define GCE_DDR_EN GENMASK(18, 16) +#define GCE_VM_ID_MAP0 0x5018 +#define GCE_VM_MAP0_ALL_HOST GENMASK(29, 0) +#define GCE_VM_ID_MAP1 0x501c +#define GCE_VM_MAP1_ALL_HOST GENMASK(29, 0) +#define GCE_VM_ID_MAP2 0x5020 +#define GCE_VM_MAP2_ALL_HOST GENMASK(29, 0) +#define GCE_VM_ID_MAP3 0x5024 +#define GCE_VM_MAP3_ALL_HOST GENMASK(5, 0) +#define GCE_VM_CPR_GSIZE 0x50c4 +#define GCE_VM_CPR_GSIZE_HSOT GENMASK(3, 0) + #define CMDQ_THR_ACTIVE_SLOT_CYCLES 0x3200 #define CMDQ_THR_ENABLED 0x1 #define CMDQ_THR_DISABLED 0x0 @@ -88,11 +99,24 @@ struct cmdq { struct gce_plat { u32 thread_nr; u8 shift; + dma_addr_t mminfra_offset; bool control_by_sw; bool sw_ddr_en; + bool gce_vm; + u32 dma_mask_bit; u32 gce_num; }; +static inline u32 cmdq_reg_shift_addr(u32 addr, const struct gce_plat *pdata) +{ + return ((addr + pdata->mminfra_offset) >> pdata->shift); +} + +static inline u32 cmdq_reg_revert_addr(u32 addr, const struct gce_plat *pdata) +{ + return ((addr << pdata->shift) - pdata->mminfra_offset); +} + static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable) { WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks)); @@ -113,6 +137,30 @@ u8 cmdq_get_shift_pa(struct mbox_chan *chan) } EXPORT_SYMBOL(cmdq_get_shift_pa); +dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan) +{ + struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox); + + return cmdq->pdata->mminfra_offset; +} +EXPORT_SYMBOL(cmdq_get_offset_pa); + +bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr) +{ + struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox); + + if (cmdq->pdata->mminfra_offset == 0) + return false; + + /* + * mminfra will recognize the addr that greater than the mminfra_offset + * as a transaction to DRAM. + * So the caller needs to append mminfra_offset for the true case. + */ + return (addr >= cmdq->pdata->mminfra_offset); +} +EXPORT_SYMBOL(cmdq_addr_need_offset); + static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread) { u32 status; @@ -144,6 +192,17 @@ static void cmdq_init(struct cmdq *cmdq) u32 gctl_regval = 0; WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks)); + + if (cmdq->pdata->gce_vm) { + /* config cpr size for host vm */ + writel(GCE_VM_CPR_GSIZE_HSOT, cmdq->base + GCE_VM_CPR_GSIZE); + /* config CPR_GSIZE before setting VM_ID_MAP to avoid data leakage */ + writel(GCE_VM_MAP0_ALL_HOST, cmdq->base + GCE_VM_ID_MAP0); + writel(GCE_VM_MAP1_ALL_HOST, cmdq->base + GCE_VM_ID_MAP1); + writel(GCE_VM_MAP2_ALL_HOST, cmdq->base + GCE_VM_ID_MAP2); + writel(GCE_VM_MAP3_ALL_HOST, cmdq->base + GCE_VM_ID_MAP3); + } + if (cmdq->pdata->control_by_sw) gctl_regval = GCE_CTRL_BY_SW; if (cmdq->pdata->sw_ddr_en) @@ -200,7 +259,7 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task) prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE); prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] = (u64)CMDQ_JUMP_BY_PA << 32 | - (task->pa_base >> task->cmdq->pdata->shift); + cmdq_reg_shift_addr(task->pa_base, task->cmdq->pdata); dma_sync_single_for_device(dev, prev_task->pa_base, prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE); @@ -265,7 +324,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq, else return; - curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift; + curr_pa = cmdq_reg_shift_addr(readl(thread->base + CMDQ_THR_CURR_ADDR), cmdq->pdata); list_for_each_entry_safe(task, tmp, &thread->task_busy_list, list_entry) { @@ -418,9 +477,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) */ WARN_ON(cmdq_thread_reset(cmdq, thread) < 0); - writel(task->pa_base >> cmdq->pdata->shift, + writel(cmdq_reg_shift_addr(task->pa_base, cmdq->pdata), thread->base + CMDQ_THR_CURR_ADDR); - writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift, + writel(cmdq_reg_shift_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata), thread->base + CMDQ_THR_END_ADDR); writel(thread->priority, thread->base + CMDQ_THR_PRIORITY); @@ -428,10 +487,10 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK); } else { WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0); - curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << - cmdq->pdata->shift; - end_pa = readl(thread->base + CMDQ_THR_END_ADDR) << - cmdq->pdata->shift; + curr_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_CURR_ADDR), + cmdq->pdata); + end_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_END_ADDR), + cmdq->pdata); /* check boundary */ if (curr_pa == end_pa - CMDQ_INST_SIZE || curr_pa == end_pa) { @@ -637,6 +696,9 @@ static int cmdq_probe(struct platform_device *pdev) } } + if (cmdq->pdata->dma_mask_bit) + dma_set_coherent_mask(dev, DMA_BIT_MASK(cmdq->pdata->dma_mask_bit)); + cmdq->mbox.dev = dev; cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr, sizeof(*cmdq->mbox.chans), GFP_KERNEL); @@ -756,6 +818,17 @@ static const struct gce_plat gce_plat_mt8195 = { .gce_num = 2 }; +static const struct gce_plat gce_plat_mt8196 = { + .thread_nr = 32, + .shift = 3, + .mminfra_offset = 0x80000000, /* 2GB */ + .control_by_sw = true, + .sw_ddr_en = true, + .gce_vm = true, + .dma_mask_bit = 35, + .gce_num = 2 +}; + static const struct of_device_id cmdq_of_ids[] = { {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_mt6779}, {.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_mt8173}, @@ -764,6 +837,7 @@ static const struct of_device_id cmdq_of_ids[] = { {.compatible = "mediatek,mt8188-gce", .data = (void *)&gce_plat_mt8188}, {.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_mt8192}, {.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_mt8195}, + {.compatible = "mediatek,mt8196-gce", .data = (void *)&gce_plat_mt8196}, {} }; diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h index a8f0070c7aa98..79398bf95f8da 100644 --- a/include/linux/mailbox/mtk-cmdq-mailbox.h +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h @@ -79,5 +79,7 @@ struct cmdq_pkt { }; u8 cmdq_get_shift_pa(struct mbox_chan *chan); +dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan); +bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr); #endif /* __MTK_CMDQ_MAILBOX_H__ */ -- GitLab From 0b95b915bf46e0ec032f30c0c1769f8520e5fff7 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Fri, 29 Nov 2024 01:59:37 +0000 Subject: [PATCH 237/456] UPSTREAM: platform/x86/intel/pmc: Fix pmc_core_iounmap to call iounmap for valid addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 50c6dbdfd16e ("x86/ioremap: Improve iounmap() address range checks") introduces a WARN when adrress ranges of iounmap are invalid. On Thinkpad P1 Gen 7 (Meteor Lake-P) this caused the following warning to appear: WARNING: CPU: 7 PID: 713 at arch/x86/mm/ioremap.c:461 iounmap+0x58/0x1f0 Modules linked in: rfkill(+) snd_timer(+) fjes(+) snd soundcore intel_pmc_core(+) int3403_thermal(+) int340x_thermal_zone intel_vsec pmt_telemetry acpi_pad pmt_class acpi_tad int3400_thermal acpi_thermal_rel joydev loop nfnetlink zram xe drm_suballoc_helper nouveau i915 mxm_wmi drm_ttm_helper gpu_sched drm_gpuvm drm_exec drm_buddy i2c_algo_bit crct10dif_pclmul crc32_pclmul ttm crc32c_intel polyval_clmulni rtsx_pci_sdmmc ucsi_acpi polyval_generic mmc_core hid_multitouch drm_display_helper ghash_clmulni_intel typec_ucsi nvme sha512_ssse3 video sha256_ssse3 nvme_core intel_vpu sha1_ssse3 rtsx_pci cec typec nvme_auth i2c_hid_acpi i2c_hid wmi pinctrl_meteorlake serio_raw ip6_tables ip_tables fuse CPU: 7 UID: 0 PID: 713 Comm: (udev-worker) Not tainted 6.12.0-rc2iounmap+ #42 Hardware name: LENOVO 21KWCTO1WW/21KWCTO1WW, BIOS N48ET19W (1.06 ) 07/18/2024 RIP: 0010:iounmap+0x58/0x1f0 Code: 85 6a 01 00 00 48 8b 05 e6 e2 28 04 48 39 c5 72 19 eb 26 cc cc cc 48 ba 00 00 00 00 00 00 32 00 48 8d 44 02 ff 48 39 c5 72 23 <0f> 0b 48 83 c4 08 5b 5d 41 5c c3 cc cc cc cc 48 ba 00 00 00 00 00 RSP: 0018:ffff888131eff038 EFLAGS: 00010207 RAX: ffffc90000000000 RBX: 0000000000000000 RCX: ffff888e33b80000 RDX: dffffc0000000000 RSI: ffff888e33bc29c0 RDI: 0000000000000000 RBP: 0000000000000000 R08: ffff8881598a8000 R09: ffff888e2ccedc10 R10: 0000000000000003 R11: ffffffffb3367634 R12: 00000000fe000000 R13: ffff888101d0da28 R14: ffffffffc2e437e0 R15: ffff888110b03b28 FS: 00007f3c1d4b3980(0000) GS:ffff888e33b80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005651cfc93578 CR3: 0000000124e4c002 CR4: 0000000000f70ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: ? __warn.cold+0xb6/0x176 ? iounmap+0x58/0x1f0 ? report_bug+0x1f4/0x2b0 ? handle_bug+0x58/0x90 ? exc_invalid_op+0x17/0x40 ? asm_exc_invalid_op+0x1a/0x20 ? iounmap+0x58/0x1f0 pmc_core_ssram_get_pmc+0x477/0x6c0 [intel_pmc_core] ? __pfx_pmc_core_ssram_get_pmc+0x10/0x10 [intel_pmc_core] ? __pfx_do_pci_enable_device+0x10/0x10 ? pci_wait_for_pending+0x60/0x110 ? pci_enable_device_flags+0x1e3/0x2e0 ? __pfx_mtl_core_init+0x10/0x10 [intel_pmc_core] pmc_core_ssram_init+0x7f/0x110 [intel_pmc_core] mtl_core_init+0xda/0x130 [intel_pmc_core] ? __mutex_init+0xb9/0x130 pmc_core_probe+0x27e/0x10b0 [intel_pmc_core] ? _raw_spin_lock_irqsave+0x96/0xf0 ? __pfx_pmc_core_probe+0x10/0x10 [intel_pmc_core] ? __pfx_mutex_unlock+0x10/0x10 ? __pfx_mutex_lock+0x10/0x10 ? device_pm_check_callbacks+0x82/0x370 ? acpi_dev_pm_attach+0x234/0x2b0 platform_probe+0x9f/0x150 really_probe+0x1e0/0x8a0 __driver_probe_device+0x18c/0x370 ? __pfx___driver_attach+0x10/0x10 driver_probe_device+0x4a/0x120 __driver_attach+0x190/0x4a0 ? __pfx___driver_attach+0x10/0x10 bus_for_each_dev+0x103/0x180 ? __pfx_bus_for_each_dev+0x10/0x10 ? klist_add_tail+0x136/0x270 bus_add_driver+0x2fc/0x540 driver_register+0x1a5/0x360 ? __pfx_pmc_core_driver_init+0x10/0x10 [intel_pmc_core] do_one_initcall+0xa4/0x380 ? __pfx_do_one_initcall+0x10/0x10 ? kasan_unpoison+0x44/0x70 do_init_module+0x296/0x800 load_module+0x5090/0x6ce0 ? __pfx_load_module+0x10/0x10 ? ima_post_read_file+0x193/0x200 ? __pfx_ima_post_read_file+0x10/0x10 ? rw_verify_area+0x152/0x4c0 ? kernel_read_file+0x257/0x750 ? __pfx_kernel_read_file+0x10/0x10 ? __pfx_filemap_get_read_batch+0x10/0x10 ? init_module_from_file+0xd1/0x130 init_module_from_file+0xd1/0x130 ? __pfx_init_module_from_file+0x10/0x10 ? __pfx__raw_spin_lock+0x10/0x10 ? __pfx_cred_has_capability.isra.0+0x10/0x10 idempotent_init_module+0x236/0x770 ? __pfx_idempotent_init_module+0x10/0x10 ? fdget+0x58/0x3f0 ? security_capable+0x7d/0x110 __x64_sys_finit_module+0xbe/0x130 do_syscall_64+0x82/0x160 ? __pfx_filemap_read+0x10/0x10 ? __pfx___fsnotify_parent+0x10/0x10 ? vfs_read+0x3a6/0xa30 ? vfs_read+0x3a6/0xa30 ? __seccomp_filter+0x175/0xc60 ? __pfx___seccomp_filter+0x10/0x10 ? fdget_pos+0x1ce/0x500 ? syscall_exit_to_user_mode_prepare+0x149/0x170 ? syscall_exit_to_user_mode+0x10/0x210 ? do_syscall_64+0x8e/0x160 ? switch_fpu_return+0xe3/0x1f0 ? syscall_exit_to_user_mode+0x1d5/0x210 ? do_syscall_64+0x8e/0x160 ? exc_page_fault+0x76/0xf0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f3c1d6d155d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 83 58 0f 00 f7 d8 64 89 01 48 RSP: 002b:00007ffe6309db38 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 RAX: ffffffffffffffda RBX: 0000557c212550a0 RCX: 00007f3c1d6d155d RDX: 0000000000000000 RSI: 00007f3c1cd943bd RDI: 0000000000000025 RBP: 00007ffe6309dbf0 R08: 00007f3c1d7c7b20 R09: 00007ffe6309db80 R10: 0000557c21255270 R11: 0000000000000246 R12: 00007f3c1cd943bd R13: 0000000000020000 R14: 0000557c21255c80 R15: 0000557c21255240 no_free_ptr(tmp_ssram) sets tmp_ssram NULL while assigning ssram. pmc_core_iounmap calls iounmap unconditionally causing the above warning to appear during boot. Fix it by checking for a valid address before calling iounmap. Also in the function pmc_core_ssram_get_pmc return -ENOMEM when ioremap fails similar to other instances in the file. Fixes: a01486dc4bb1 ("platform/x86/intel/pmc: Cleanup SSRAM discovery") Reviewed-by: Ilpo Järvinen Reviewed-by: David E. Box Signed-off-by: Vamsi Krishna Brahmajosyula Link: https://lore.kernel.org/r/20241018104958.14195-1-vamsikrishna.brahmajosyula@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede (cherry picked from commit 48771da48072823956b271dddd568492c13d8170) BUG=b:334238249 TEST='ls /sys/kernel/debug/pmc_core/' Signed-off-by: Linux Patches Robot Change-Id: I632f980c8020e646e86009348fd880b1058992b2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6058703 Commit-Queue: Tzung-Bi Shih Reviewed-by: Samuel Jacob Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/x86/intel/pmc/core_ssram.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform/x86/intel/pmc/core_ssram.c index 1bde86c54eb97..239211486fb91 100644 --- a/drivers/platform/x86/intel/pmc/core_ssram.c +++ b/drivers/platform/x86/intel/pmc/core_ssram.c @@ -29,7 +29,7 @@ #define LPM_REG_COUNT 28 #define LPM_MODE_OFFSET 1 -DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T)); +DEFINE_FREE(pmc_core_iounmap, void __iomem *, if (_T) iounmap(_T)) static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map) { @@ -262,6 +262,8 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset) ssram_base = ssram_pcidev->resource[0].start; tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); + if (!tmp_ssram) + return -ENOMEM; if (pmc_idx != PMC_IDX_MAIN) { /* -- GitLab From e1e0cfc33580d5feecae219b05e5a34ba2ee0ec9 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 14 Jun 2024 12:01:32 +0800 Subject: [PATCH 238/456] FROMLIST: mailbox: Add power_get/power_put API to mbox_chan_ops To avoid pm_runtime APIs calling sleep in all the atomic context APIs in mbox_chan_ops, we add power_get/power_put API to let the controllers implement them with pm_runtime APIs outside the other atomic context APIs in mbox_chan_ops. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240614040133.24967-2-jason-jh.lin@mediatek.com/) BUG=b:380121989,b:337193377 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:386306093 Change-Id: I08946f47d771a02b8ccc9b72c59cb4d85a0b2df5 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109427 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/mailbox/mailbox.c | 55 ++++++++++++++++++++++++++++++ include/linux/mailbox_controller.h | 11 ++++++ 2 files changed, 66 insertions(+) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index ebff3baf30451..7546fcd750312 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -58,6 +58,12 @@ static void msg_submit(struct mbox_chan *chan) void *data; int err = -EBUSY; + if (chan->mbox->ops->power_get) { + err = chan->mbox->ops->power_get(chan); + if (err < 0) + return; + } + spin_lock_irqsave(&chan->lock, flags); if (!chan->msg_count || chan->active_req) @@ -89,12 +95,16 @@ exit: hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags); } + + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); } static void tx_tick(struct mbox_chan *chan, int r) { unsigned long flags; void *mssg; + int ret; spin_lock_irqsave(&chan->lock, flags); mssg = chan->active_req; @@ -107,10 +117,19 @@ static void tx_tick(struct mbox_chan *chan, int r) if (!mssg) return; + if (chan->mbox->ops->power_get) { + ret = chan->mbox->ops->power_get(chan); + if (ret < 0) + return; + } + /* Notify the client */ if (chan->cl->tx_done) chan->cl->tx_done(chan->cl, mssg, r); + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); + if (r != -ETIME && chan->cl->tx_block) complete(&chan->tx_complete); } @@ -223,9 +242,16 @@ EXPORT_SYMBOL_GPL(mbox_client_txdone); */ bool mbox_client_peek_data(struct mbox_chan *chan) { + if (chan->mbox->ops->power_get) + if (chan->mbox->ops->power_get(chan) < 0) + return false; + if (chan->mbox->ops->peek_data) return chan->mbox->ops->peek_data(chan); + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); + return false; } EXPORT_SYMBOL_GPL(mbox_client_peek_data); @@ -310,10 +336,19 @@ int mbox_flush(struct mbox_chan *chan, unsigned long timeout) if (!chan->mbox->ops->flush) return -ENOTSUPP; + if (chan->mbox->ops->power_get) { + ret = chan->mbox->ops->power_get(chan); + if (ret < 0) + return ret; + } + ret = chan->mbox->ops->flush(chan, timeout); if (ret < 0) tx_tick(chan, ret); + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); + return ret; } EXPORT_SYMBOL_GPL(mbox_flush); @@ -341,6 +376,12 @@ static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl) spin_unlock_irqrestore(&chan->lock, flags); + if (chan->mbox->ops->power_get) { + ret = chan->mbox->ops->power_get(chan); + if (ret < 0) + return ret; + } + if (chan->mbox->ops->startup) { ret = chan->mbox->ops->startup(chan); @@ -441,7 +482,11 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) if (ret) chan = ERR_PTR(ret); + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); + mutex_unlock(&con_mutex); + return chan; } EXPORT_SYMBOL_GPL(mbox_request_channel); @@ -485,13 +530,23 @@ EXPORT_SYMBOL_GPL(mbox_request_channel_byname); void mbox_free_channel(struct mbox_chan *chan) { unsigned long flags; + int ret; if (!chan || !chan->cl) return; + if (chan->mbox->ops->power_get) { + ret = chan->mbox->ops->power_get(chan); + if (ret < 0) + return; + } + if (chan->mbox->ops->shutdown) chan->mbox->ops->shutdown(chan); + if (chan->mbox->ops->power_put) + chan->mbox->ops->power_put(chan); + /* The queued TX requests are simply aborted, no callbacks are made */ spin_lock_irqsave(&chan->lock, flags); chan->cl = NULL; diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h index 6fee33cb52f58..e8f26e7dabfde 100644 --- a/include/linux/mailbox_controller.h +++ b/include/linux/mailbox_controller.h @@ -42,6 +42,15 @@ struct mbox_chan; * Used only if txdone_poll:=true && txdone_irq:=false * @peek_data: Atomic check for any received data. Return true if controller * has some data to push to the client. False otherwise. + * @power_get: Called when the controller need to get the reference to keep + * the power on for the device of mailbox controller. It is + * optional to implement this function with pm_runtime APIs or + * more complicated operation. + * Return 0 is success, otherwise are fail. + * @power_put: Called when the controller need to put the reference to release + * the power for the device of mailbox controller. It is optional + * to implement this function with pm_runtime APIs or more + * complicated operation. */ struct mbox_chan_ops { int (*send_data)(struct mbox_chan *chan, void *data); @@ -50,6 +59,8 @@ struct mbox_chan_ops { void (*shutdown)(struct mbox_chan *chan); bool (*last_tx_done)(struct mbox_chan *chan); bool (*peek_data)(struct mbox_chan *chan); + int (*power_get)(struct mbox_chan *chan); + void (*power_put)(struct mbox_chan *chan); }; /** -- GitLab From f17d6c1917e356f409d3f1a4d170ee95095a5983 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 14 Jun 2024 12:01:33 +0800 Subject: [PATCH 239/456] BACKPORT: FROMLIST: mailbox: mtk-cmdq: Move pm_runimte_get and put to mbox_chan_ops API When we run kernel with lockdebug option, we will get the BUG below: BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:1164 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 3616, name: kworker/u17:3 preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 INFO: lockdep is turned off. irq event stamp: 0 CPU: 1 PID: 3616 Comm: kworker/u17:3 Not tainted 6.1.87-lockdep-14133-g26e933aca785 #1 Hardware name: Google Ciri sku0/unprovisioned board (DT) Workqueue: imgsys_runner imgsys_runner_func Call trace: dump_backtrace+0x100/0x120 show_stack+0x20/0x2c dump_stack_lvl+0x84/0xb4 dump_stack+0x18/0x48 __might_resched+0x354/0x4c0 __might_sleep+0x98/0xe4 __pm_runtime_resume+0x70/0x124 cmdq_mbox_send_data+0xe4/0xb1c msg_submit+0x194/0x2dc mbox_send_message+0x190/0x330 imgsys_cmdq_sendtask+0x1618/0x2224 imgsys_runner_func+0xac/0x11c process_one_work+0x638/0xf84 worker_thread+0x808/0xcd0 kthread+0x24c/0x324 ret_from_fork+0x10/0x20 We found that there is a spin_lock_irqsave protection in msg_submit() of mailbox.c and it is in the atomic context. So when cmdq driver calls pm_runtime_get_sync() in cmdq_mbox_send_data(), it will get this BUG report. To avoid using sleep in atomic context, move pm_runtime_get_sync to mbox_chan_ops->power_get and also move pm_runtime_put_autosuspend to mbox_chan_ops->power_put. Fixes: 8afe816b0c99 ("mailbox: mtk-cmdq-mailbox: Implement Runtime PM with autosuspend") Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240614040133.24967-3-jason-jh.lin@mediatek.com/) Conflicts: drivers/mailbox/mtk-cmdq-mailbox.c BUG=b:380121989,b:337193377 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:386306093 Change-Id: Idfef54743836cdda9bddfd290309e2762bf0d853 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109428 Reviewed-by: Pin-yen Lin Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/mailbox/mtk-cmdq-mailbox.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 14dbff17d3707..c0b39ad07030b 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -457,10 +457,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) return ret; task = kzalloc(sizeof(*task), GFP_ATOMIC); - if (!task) { - pm_runtime_put_autosuspend(cmdq->mbox.dev); + if (!task) return -ENOMEM; - } task->cmdq = cmdq; INIT_LIST_HEAD(&task->list_entry); @@ -508,7 +506,6 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) list_move_tail(&task->list_entry, &thread->task_busy_list); pm_runtime_mark_last_busy(cmdq->mbox.dev); - pm_runtime_put_autosuspend(cmdq->mbox.dev); return 0; } @@ -556,7 +553,6 @@ done: spin_unlock_irqrestore(&thread->chan->lock, flags); pm_runtime_mark_last_busy(cmdq->mbox.dev); - pm_runtime_put_autosuspend(cmdq->mbox.dev); } static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) @@ -596,7 +592,6 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) out: spin_unlock_irqrestore(&thread->chan->lock, flags); pm_runtime_mark_last_busy(cmdq->mbox.dev); - pm_runtime_put_autosuspend(cmdq->mbox.dev); return 0; @@ -611,15 +606,31 @@ wait: return -EFAULT; } pm_runtime_mark_last_busy(cmdq->mbox.dev); - pm_runtime_put_autosuspend(cmdq->mbox.dev); + return 0; } +static int cmdq_mbox_pm_resume(struct mbox_chan *chan) +{ + struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); + + return pm_runtime_get_sync(cmdq->mbox.dev); +} + +static void cmdq_mbox_pm_susepnd(struct mbox_chan *chan) +{ + struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); + + pm_runtime_put_autosuspend(cmdq->mbox.dev); +} + static const struct mbox_chan_ops cmdq_mbox_chan_ops = { .send_data = cmdq_mbox_send_data, .startup = cmdq_mbox_startup, .shutdown = cmdq_mbox_shutdown, .flush = cmdq_mbox_flush, + .power_get = cmdq_mbox_pm_resume, + .power_put = cmdq_mbox_pm_susepnd, }; static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox, -- GitLab From b32c24aa6309f5505a49abaa9ceb69c2ecf2b1a5 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Thu, 28 Nov 2024 01:58:01 +0000 Subject: [PATCH 240/456] UPSTREAM: usb: acpi: fix boot hang due to early incorrect 'tunneled' USB3 device links Fix a boot hang issue triggered when a USB3 device is incorrectly assumed to be tunneled over USB4, thus attempting to create a device link between the USB3 "consumer" device and the USB4 "supplier" Host Interface before the USB4 side is properly bound to a driver. This could happen if xhci isn't capable of detecting tunneled devices, but ACPI tables contain all info needed to assume device is tunneled. i.e. udev->tunnel_mode == USB_LINK_UNKNOWN. It turns out that even for actual tunneled USB3 devices it can't be assumed that the thunderbolt driver providing the tunnel is loaded before the tunneled USB3 device is created. The tunnel can be created by BIOS and remain in use by thunderbolt/USB4 host driver once it loads. Solve this by making the device link "stateless", which doesn't create a driver presence order dependency between the supplier and consumer drivers. It still guarantees correct suspend/resume and shutdown ordering. cc: Mario Limonciello Fixes: f1bfb4a6fed6 ("usb: acpi: add device link between tunneled USB3 device and USB4 Host Interface") Tested-by: Harry Wentland Signed-off-by: Mathias Nyman Reviewed-by: Mika Westerberg Tested-by: Mario Limonciello Link: https://lore.kernel.org/r/20241024131355.3836538-1-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 623dae3e7084a9504e6dc4cf0cb83f305f413b4d) BUG=b:350634469 TEST=USB 3.2 and TBT/USB4 sanity check Signed-off-by: Linux Patches Robot Change-Id: Ie21aa77a691b32a08b35dc1f613ff83a5c57a874 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055716 Commit-Queue: Divya Chauhan Reviewed-by: Divya Chauhan Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/usb/core/usb-acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index 21585ed89ef84..03c22114214b5 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -170,11 +170,11 @@ static int usb_acpi_add_usb4_devlink(struct usb_device *udev) struct fwnode_handle *nhi_fwnode __free(fwnode_handle) = fwnode_find_reference(dev_fwnode(&port_dev->dev), "usb4-host-interface", 0); - if (IS_ERR(nhi_fwnode)) + if (IS_ERR(nhi_fwnode) || !nhi_fwnode->dev) return 0; link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev, - DL_FLAG_AUTOREMOVE_CONSUMER | + DL_FLAG_STATELESS | DL_FLAG_RPM_ACTIVE | DL_FLAG_PM_RUNTIME); if (!link) { -- GitLab From 79ce891cdc8dcd45d4c4ef4ca0751442843c6c7e Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Sat, 30 Nov 2024 02:07:16 +0000 Subject: [PATCH 241/456] UPSTREAM: Revert "net: do not leave a dangling sk pointer, when socket creation fails" This reverts commit 6cd4a78d962bebbaf8beb7d2ead3f34120e3f7b2. inet/inet6->create() implementations have been fixed to explicitly NULL the allocated sk object on error. A warning was put in place to make sure any future changes will not leave a dangling pointer in pf->create() implementations. So this code is now redundant. Suggested-by: Kuniyuki Iwashima Signed-off-by: Ignat Korchagin Reviewed-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20241014153808.51894-10-ignat@cloudflare.com Signed-off-by: Jakub Kicinski (cherry picked from commit 18429e6e0c2ad26250862a786964d8c73400d9a0) BUG=None TEST=None Signed-off-by: Linux Patches Robot Change-Id: I09cda199db968ce18180100c41a8f5db9f7ddc56 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6060154 Reviewed-by: Divya Chauhan Reviewed-by: Tzung-Bi Shih Commit-Queue: Divya Chauhan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- net/core/sock.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index f530e2efa0fb2..f73baae46f406 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3735,9 +3735,6 @@ void sk_common_release(struct sock *sk) sk->sk_prot->unhash(sk); - if (sk->sk_socket) - sk->sk_socket->sk = NULL; - /* * In this point socket cannot receive new packets, but it is possible * that some packets are in flight because some CPU runs receiver and -- GitLab From b580e230e941fb6c3b26ad6ad1a86549db03bb82 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Fri, 22 Nov 2024 01:53:43 +0000 Subject: [PATCH 242/456] UPSTREAM: irqchip/gic-v4: Correctly deal with set_affinity on lazily-mapped VPEs Zenghui points out that a recent change to the way set_affinity is handled for VPEs has the potential to return an error if the VPE hasn't been mapped yet (because the guest hasn't emited a MAPTI command yet), affecting GICv4.0 implementations that rely on the ITSList feature. Fix this by making the set_affinity succeed in this case, and return early, without trying to touch the HW. Fixes: 1442ee0011983 ("irqchip/gic-v4: Don't allow a VMOVP on a dying VPE") Reported-by: Zenghui Yu Signed-off-by: Marc Zyngier Signed-off-by: Thomas Gleixner Reviewed-by: Zenghui Yu Link: https://lore.kernel.org/all/20241027102220.1858558-1-maz@kernel.org Link: https://lore.kernel.org/r/aab45cd3-e5ca-58cf-e081-e32a17f5b4e7@huawei.com (cherry picked from commit e6c24e2d05bb05de96ffb9bdb0ee62d20ad526f8) BUG=None TEST=None Signed-off-by: Linux Patches Robot Change-Id: I7136d1bdf67b2bdb21343ab9cc335545c6835ed3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6042843 Commit-Queue: Divya Chauhan Reviewed-by: Tzung-Bi Shih Reviewed-by: Divya Chauhan Reviewed-by: Sean Paul Kcr-patch: 12584e70f2224f4429b3367a4f3bbbb79c1925159b6db1b6002dd476.patch Signed-off-by: Hubert Mazur --- drivers/irqchip/irq-gic-v3-its.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 2818164d649a6..3a74175796c3e 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -3816,6 +3816,23 @@ static int its_vpe_set_affinity(struct irq_data *d, unsigned long flags; int from, cpu; + /* + * Check if we're racing against a VPE being destroyed, for + * which we don't want to allow a VMOVP. + */ + if (!atomic_read(&vpe->vmapp_count)) { + if (gic_requires_eager_mapping()) + return -EINVAL; + + /* + * If we lazily map the VPEs, this isn't an error and + * we can exit cleanly. + */ + cpu = cpumask_first(mask_val); + irq_data_update_effective_affinity(d, cpumask_of(cpu)); + return IRQ_SET_MASK_OK_DONE; + } + /* * Changing affinity is mega expensive, so let's be as lazy as * we can and only do it if we really have to. Also, if mapped -- GitLab From 7c16ed471c83a80f6143c0dac2c2503ebe36e1a0 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Mon, 9 Dec 2024 02:14:25 +0000 Subject: [PATCH 243/456] UPSTREAM: x86/cpu/topology: Remove limit of CPUs due to disabled IO/APIC The rework of possible CPUs management erroneously disabled SMP when the IO/APIC is disabled either by the 'noapic' command line parameter or during IO/APIC setup. SMP is possible without IO/APIC. Remove the ioapic_is_disabled conditions from the relevant possible CPU management code paths to restore the orgininal behaviour. Fixes: 7c0edad3643f ("x86/cpu/topology: Rework possible CPU management") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241202145905.1482-1-ffmancera@riseup.net (cherry picked from commit 73da582a476ea6e3512f89f8ed57dfed945829a2) BUG=b:349369441 TEST=Build and test on various affected systems Signed-off-by: Linux Patches Robot Change-Id: I823a21a572824a8469d6c999668f84768f9de0e9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6079913 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Commit-Queue: Divya Chauhan Reviewed-by: Divya Chauhan Signed-off-by: Hubert Mazur --- arch/x86/kernel/cpu/topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index b5c15602f1518..a8d1cc6d223df 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -428,8 +428,8 @@ void __init topology_apply_cmdline_limits_early(void) { unsigned int possible = nr_cpu_ids; - /* 'maxcpus=0' 'nosmp' 'nolapic' 'disableapic' 'noapic' */ - if (!setup_max_cpus || ioapic_is_disabled || apic_is_disabled) + /* 'maxcpus=0' 'nosmp' 'nolapic' 'disableapic' */ + if (!setup_max_cpus || apic_is_disabled) possible = 1; /* 'possible_cpus=N' */ @@ -443,7 +443,7 @@ void __init topology_apply_cmdline_limits_early(void) static __init bool restrict_to_up(void) { - if (!smp_found_config || ioapic_is_disabled) + if (!smp_found_config) return true; /* * XEN PV is special as it does not advertise the local APIC -- GitLab From 6f967b4426546819a19bcb0d044ef17fabc7ab1e Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 29 Oct 2024 14:01:55 +0200 Subject: [PATCH 244/456] CHROMIUM: iwl7000: Revert "wifi: iwlwifi: remove retry loops in start" Revert commit dfdfe4be183b ("wifi: iwlwifi: remove retry loops in start"), it turns out that there's an issue with the PNVM load notification from firmware not getting processed, that this patch has been somewhat successfully papering over. Since this is being reported, revert the loop removal for now. We will later at least clean this up to only attempt to retry if there was a timeout, but currently we don't even bubble up the failure reason to the correct layer, only returning NULL. Signed-off-by: Miri Korenblit BUG=b:385666021 Change-Id: I4d4b52a0f5972693cbb872eaefb123dbed2f85d4 iwl7000-tree: b6ea5d8de1a82f8774c1e3c534410329fc58c85e Signed-off-by: Miri Korenblit Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6120272 Reviewed-by: Nicolas Norvez Tested-by: Arowa Suliman Commit-Queue: Arowa Suliman Tested-by: Miriam Rachel Korenblit Reviewed-by: Arowa Suliman Kcr-patch: 5aa92061607da484de10c5b6603f87373ecff352158239e0bcfa81de.patch Signed-off-by: Hubert Mazur --- .../net/wireless/iwl7000/iwlwifi/iwl-drv.c | 28 +++++++++++++------ .../net/wireless/iwl7000/iwlwifi/iwl-drv.h | 5 +++- .../wireless/iwl7000/iwlwifi/mvm/mac80211.c | 19 +++++++------ 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.c index b4aec25f81f02..7cdeb43690ee7 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.c @@ -1701,25 +1701,35 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) const struct iwl_op_mode_ops *ops = op->ops; struct dentry *dbgfs_dir = NULL; struct iwl_op_mode *op_mode = NULL; + int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; /* also protects start/stop from racing against each other */ lockdep_assert_held(&iwlwifi_opmode_table_mtx); + for (retry = 0; retry <= max_retry; retry++) { + #ifdef CPTCFG_IWLWIFI_DEBUGFS - drv->dbgfs_op_mode = debugfs_create_dir(op->name, - drv->dbgfs_drv); - dbgfs_dir = drv->dbgfs_op_mode; + drv->dbgfs_op_mode = debugfs_create_dir(op->name, + drv->dbgfs_drv); + dbgfs_dir = drv->dbgfs_op_mode; #endif - op_mode = ops->start(drv->trans, drv->trans->cfg, - &drv->fw, dbgfs_dir); - if (op_mode) - return op_mode; + op_mode = ops->start(drv->trans, drv->trans->cfg, + &drv->fw, dbgfs_dir); + + if (op_mode) + return op_mode; + + if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status)) + break; + + IWL_ERR(drv, "retry init count %d\n", retry); #ifdef CPTCFG_IWLWIFI_DEBUGFS - debugfs_remove_recursive(drv->dbgfs_op_mode); - drv->dbgfs_op_mode = NULL; + debugfs_remove_recursive(drv->dbgfs_op_mode); + drv->dbgfs_op_mode = NULL; #endif + } return NULL; } diff --git a/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.h index 6e5dd9c8cf234..ef2764d949014 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwl7000/iwlwifi/iwl-drv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2020-2021, 2023 Intel Corporation + * Copyright (C) 2005-2014, 2020-2021, 2023-2024 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH */ #ifndef __iwl_drv_h__ @@ -108,6 +108,9 @@ int iwl_drv_switch_op_mode(struct iwl_drv *drv, const char *new_op_name); #define EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(sym) #define VISIBLE_IF_IWLWIFI_KUNIT static +/* max retry for init flow */ +#define IWL_MAX_INIT_RETRY 2 + #define FW_NAME_PRE_BUFSIZE 64 struct iwl_trans; const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf); diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c index c5204605f889e..89e2ef15ba29b 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c @@ -1392,21 +1392,22 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; + int retry, max_retry = 0; mutex_lock(&mvm->mutex); /* we are starting the mac not in error flow, and restart is enabled */ if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && - iwlwifi_mod_params.fw_restart) { - /* - * This will prevent mac80211 recovery flows to trigger during - * init failures - */ - set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); - } + iwlwifi_mod_params.fw_restart) + max_retry = IWL_MAX_INIT_RETRY; - ret = __iwl_mvm_mac_start(mvm); - clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); + for (retry = 0; retry <= max_retry; retry++) { + ret = __iwl_mvm_mac_start(mvm); + if (!ret) + break; + + IWL_ERR(mvm, "mac start retry %d\n", retry); + } mutex_unlock(&mvm->mutex); -- GitLab From f0451770a3baaf6a940535d5ae441238f00be514 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:56 +0800 Subject: [PATCH 245/456] FROMLIST: soc: mediatek: mtk-cmdq: Add pa_base parsing for unsupported subsys ID hardware When GCE executes instructions, the corresponding hardware register can be found through the subsys ID. For hardware that does not support subsys ID, its subsys ID will be set to invalid value and its physical address needs to be used to generate GCE instructions. This commit adds a pa_base parsing flow to the cmdq_client_reg structure for these unsupported subsys ID hardware. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-4-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Ie60289808c12e45ba6048cbac21f772421370be5 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108928 Reviewed-by: Fei Shao Reviewed-by: Chen-Yu Tsai Tested-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-cmdq-helper.c | 18 ++++++++++++++++-- include/linux/soc/mediatek/mtk-cmdq.h | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 94c8aea17f7a7..875cd77954f0a 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #define CMDQ_WRITE_ENABLE_MASK BIT(0) @@ -60,20 +61,30 @@ int cmdq_dev_get_client_reg(struct device *dev, struct cmdq_client_reg *client_reg, int idx) { struct of_phandle_args spec; + struct resource res; int err; if (!client_reg) return -ENOENT; + if (of_address_to_resource(dev->of_node, 0, &res) != 0) { + dev_err(dev, "Missing reg in %s node\n", dev->of_node->full_name); + return -EINVAL; + } + client_reg->pa_base = res.start; + err = of_parse_phandle_with_fixed_args(dev->of_node, "mediatek,gce-client-reg", 3, idx, &spec); if (err < 0) { - dev_warn(dev, + dev_dbg(dev, "error %d can't parse gce-client-reg property (%d)", err, idx); - return err; + /* make subsys invalid */ + client_reg->subsys = CMDQ_SUBSYS_INVALID; + + return 0; } client_reg->subsys = (u8)spec.args[0]; @@ -130,6 +141,9 @@ int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t siz pkt->buf_size = size; + /* need to use pkt->cl->chan later to call mbox APIs when generating instruction */ + pkt->cl = (void *)client; + dev = client->chan->mbox->dev; dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size, DMA_TO_DEVICE); diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h index 5bee6f7fc400e..3a246d538d4fd 100644 --- a/include/linux/soc/mediatek/mtk-cmdq.h +++ b/include/linux/soc/mediatek/mtk-cmdq.h @@ -23,6 +23,8 @@ #define CMDQ_THR_SPR_IDX2 (2) #define CMDQ_THR_SPR_IDX3 (3) +#define CMDQ_SUBSYS_INVALID (U8_MAX) + struct cmdq_pkt; enum cmdq_logic_op { @@ -52,6 +54,7 @@ struct cmdq_operand { struct cmdq_client_reg { u8 subsys; + phys_addr_t pa_base; u16 offset; u16 size; }; -- GitLab From f902fb0e57128d6c6fd521441724bcc6a83f5124 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:57 +0800 Subject: [PATCH 246/456] FROMLIST: soc: mediatek: mtk-cmdq: Add mminfra_offset compatibility for DRAM address Since GCE has been moved to mminfra in MT8196, all transactions from mminfra to DRAM will have their addresses adjusted by subtracting a mminfra offset. This information should be handled inside the CMDQ driver, allowing CMDQ users to call CMDQ APIs as usual. Therefore, CMDQ driver needs to use the mbox API to get the mminfra_offset value of the SoC, and then add it to the DRAM address when generating instructions to ensure GCE accesses the correct DRAM address. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-5-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: I17acf81a339885ccf23d2285051a24f0248e3ed9 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108929 Reviewed-by: Chen-Yu Tsai Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-cmdq-helper.c | 35 ++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 875cd77954f0a..4cab5158409f5 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -314,10 +314,22 @@ EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value); int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr) { + struct cmdq_client *cl = (struct cmdq_client *)pkt->cl; const u16 high_addr_reg_idx = CMDQ_THR_SPR_IDX0; const u16 value_reg_idx = CMDQ_THR_SPR_IDX1; int ret; + if (!cl) { + pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__); + return -EINVAL; + } + + if (cmdq_addr_need_offset(cl->chan, src_addr)) + src_addr += cmdq_get_offset_pa(cl->chan); + + if (cmdq_addr_need_offset(cl->chan, dst_addr)) + dst_addr += cmdq_get_offset_pa(cl->chan); + /* read the value of src_addr into high_addr_reg_idx */ ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(src_addr)); if (ret < 0) @@ -428,10 +440,19 @@ EXPORT_SYMBOL(cmdq_pkt_poll_mask); int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask) { + struct cmdq_client *cl = (struct cmdq_client *)pkt->cl; struct cmdq_instruction inst = { {0} }; u8 use_mask = 0; int ret; + if (!cl) { + pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__); + return -EINVAL; + } + + if (cmdq_addr_need_offset(cl->chan, addr)) + addr += cmdq_get_offset_pa(cl->chan); + /* * Append an MASK instruction to set the mask for following POLL instruction * which enables use_mask bit. @@ -509,11 +530,21 @@ EXPORT_SYMBOL(cmdq_pkt_assign); int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa) { + struct cmdq_client *cl = (struct cmdq_client *)pkt->cl; struct cmdq_instruction inst = { .op = CMDQ_CODE_JUMP, - .offset = CMDQ_JUMP_ABSOLUTE, - .value = addr >> shift_pa + .offset = CMDQ_JUMP_ABSOLUTE }; + + if (!cl) { + pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__); + return -EINVAL; + } + + if (cmdq_addr_need_offset(cl->chan, addr)) + addr += cmdq_get_offset_pa(cl->chan); + + inst.value = addr >> shift_pa; return cmdq_pkt_append_command(pkt, inst); } EXPORT_SYMBOL(cmdq_pkt_jump_abs); -- GitLab From d2e262972a1b934e597101c70198dc3d1e70da55 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:58 +0800 Subject: [PATCH 247/456] FROMLIST: soc: mediatek: Add programming flow for unsupported subsys ID hardware To support hardware without subsys IDs on new SoCs, add a programming flow that checks whether the subsys ID is valid. If the subsys ID is invalid, the flow will call 2 alternative CMDQ APIs: cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same functionality. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-6-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Id3d3ad7f147ac0ef01acbfd35b44ad5175e7e33c Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108930 Reviewed-by: Fei Shao Reviewed-by: Chen-Yu Tsai Commit-Queue: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-mmsys.c | 14 +++++++++++--- drivers/soc/mediatek/mtk-mutex.c | 11 +++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 521057c06811a..aa5a4ee17078b 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -169,9 +169,17 @@ static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 tmp; if (mmsys->cmdq_base.size && cmdq_pkt) { - ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys, - mmsys->cmdq_base.offset + offset, val, - mask); + offset += mmsys->cmdq_base.offset; + if (mmsys->cmdq_base.subsys != CMDQ_SUBSYS_INVALID) { + ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys, + offset, val, mask); + } else { + /* only MMIO access, no need to check mminfro_offset */ + ret = cmdq_pkt_assign(cmdq_pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_HIGH(mmsys->cmdq_base.pa_base)); + ret |= cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_LOW(offset), val, mask); + } if (ret) pr_debug("CMDQ unavailable: using CPU write\n"); else diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index 73c256d3950b0..5e2ce726abbba 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -922,6 +922,7 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt) struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, mutex[mutex->id]); struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt; + dma_addr_t en_addr = mtx->addr + DISP_REG_MUTEX_EN(mutex->id); WARN_ON(&mtx->mutex[mutex->id] != mutex); @@ -930,8 +931,14 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt) return -ENODEV; } - cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys, - mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1); + if (mtx->cmdq_reg.subsys != CMDQ_SUBSYS_INVALID) { + cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys, en_addr, 1); + } else { + /* only MMIO access, no need to check mminfro_offset */ + cmdq_pkt_assign(cmdq_pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(en_addr)); + cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(en_addr), 1); + } + return 0; } EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq); -- GitLab From 80dc52902a8a386bf31f0d0ca5d45ee52b738f77 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:07:59 +0800 Subject: [PATCH 248/456] FROMLIST: drm/mediatek: Add programming flow for unsupported subsys ID hardware To support hardware without subsys IDs on new SoCs, add a programming flow that checks whether the subsys ID is valid. If the subsys ID is invalid, the flow will call 2 alternative CMDQ APIs: cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same functionality. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-7-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Ib850e88f3e74c871c98534fca2e79b688e9d88ef Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108931 Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Chen-Yu Tsai Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 33 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c index edc6417639e64..219d67735a54e 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c @@ -66,14 +66,37 @@ struct mtk_ddp_comp_dev { struct cmdq_client_reg cmdq_reg; }; +#if IS_REACHABLE(CONFIG_MTK_CMDQ) +static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt, struct cmdq_client_reg *cmdq_reg, + unsigned int offset, unsigned int value, unsigned int mask) +{ + offset += cmdq_reg->offset; + + if (cmdq_reg->subsys != CMDQ_SUBSYS_INVALID) { + if (mask == GENMASK(31, 0)) + cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, offset, value); + else + cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, offset, value, mask); + } else { + /* only MMIO access, no need to check mminfro_offset */ + cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base)); + if (mask == GENMASK(31, 0)) + cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_LOW(offset), value); + else + cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_LOW(offset), value, mask); + } +} +#endif + void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value, struct cmdq_client_reg *cmdq_reg, void __iomem *regs, unsigned int offset) { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) - cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, - cmdq_reg->offset + offset, value); + mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0)); else #endif writel(value, regs + offset); @@ -85,8 +108,7 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value, { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) - cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, - cmdq_reg->offset + offset, value); + mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0)); else #endif writel_relaxed(value, regs + offset); @@ -98,8 +120,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value, { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) { - cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, - cmdq_reg->offset + offset, value, mask); + mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, mask); } else { #endif u32 tmp = readl(regs + offset); -- GitLab From 34ea792cce871cdf7e0e817872d79205dc7b72cc Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Fri, 20 Dec 2024 01:08:00 +0800 Subject: [PATCH 249/456] FROMLIST: media: mediatek: mdp3: Add programming flow for unsupported subsys ID hardware To support hardware without subsys IDs on new SoCs, add a programming flow that checks whether the subsys ID is valid. If the subsys ID is invalid, the flow will call 2 alternative CMDQ APIs: cmdq_pkt_assign() and cmdq_pkt_write_s_mask_value() to achieve the same functionality. Signed-off-by: Jason-JH.Lin (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20241219170800.2957-8-jason-jh.lin@mediatek.com/) BUG=b:379039600 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354021564 Change-Id: Ife4abc3070e0aab547ad2b68aa835c45ece316cf Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6108932 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 18 ++++- .../platform/mediatek/mdp3/mtk-mdp3-comp.h | 79 ++++++++++++++----- 2 files changed, 77 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 275ad4609147c..4f440b3d42ed7 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -191,7 +191,14 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, /* Enable mux settings */ for (index = 0; index < ctrl->num_sets; index++) { set = &ctrl->sets[index]; - cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value); + if (set->subsys_id != CMDQ_SUBSYS_INVALID) { + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value); + } else { + /* only MMIO access, no need to check mminfro_offset */ + cmdq_pkt_assign(&cmd->pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(set->reg)); + cmdq_pkt_write_s_value(&cmd->pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_LOW(set->reg), set->value); + } } /* Config sub-frame information */ for (index = (num_comp - 1); index >= 0; index--) { @@ -225,7 +232,14 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, /* Disable mux settings */ for (index = 0; index < ctrl->num_sets; index++) { set = &ctrl->sets[index]; - cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0); + if (set->subsys_id != CMDQ_SUBSYS_INVALID) { + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0); + } else { + /* only MMIO access, no need to check mminfro_offset */ + cmdq_pkt_assign(&cmd->pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(set->reg)); + cmdq_pkt_write_s_value(&cmd->pkt, CMDQ_THR_SPR_IDX0, + CMDQ_ADDR_LOW(set->reg), 0); + } } return 0; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index f618ec6769f6d..06342a25e0859 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -9,17 +9,44 @@ #include "mtk-mdp3-cmdq.h" -#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \ -do { \ - typeof(mask) (m) = (mask); \ - cmdq_pkt_write_mask(&((cmd)->pkt), id, (base) + (ofst), \ - (val), \ - (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ - (0xffffffff) : (m)); \ +#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \ +do { \ + typeof(cmd) (_c) = (cmd); \ + typeof(id) (_i) = (id); \ + typeof(base) (_b) = (base); \ + typeof(ofst) (_o) = (ofst); \ + typeof(val) (_v) = (val); \ + typeof(mask) (_m) = (mask); \ + _m = ((_m & (ofst##_MASK)) == (ofst##_MASK)) ? 0xffffffff : _m; \ + if (_i != CMDQ_SUBSYS_INVALID) { \ + cmdq_pkt_write_mask(&_c->pkt, _i, _b + _o, _v, _m); \ + } else { \ + /* only MMIO access, no need to check mminfro_offset */ \ + cmdq_pkt_assign(&_c->pkt, CMDQ_THR_SPR_IDX0, \ + CMDQ_ADDR_HIGH(_b)); \ + cmdq_pkt_write_s_mask_value(&_c->pkt, CMDQ_THR_SPR_IDX0,\ + CMDQ_ADDR_LOW(_b + _o), \ + _v, _m); \ + } \ } while (0) -#define MM_REG_WRITE(cmd, id, base, ofst, val) \ - cmdq_pkt_write(&((cmd)->pkt), id, (base) + (ofst), (val)) +#define MM_REG_WRITE(cmd, id, base, ofst, val) \ +do { \ + typeof(cmd) (_c) = (cmd); \ + typeof(id) (_i) = (id); \ + typeof(base) (_b) = (base); \ + typeof(ofst) (_o) = (ofst); \ + typeof(val) (_v) = (val); \ + if (_i != CMDQ_SUBSYS_INVALID) { \ + cmdq_pkt_write(&_c->pkt, _i, _b + _o, _v); \ + } else { \ + /* only MMIO access, no need to check mminfro_offset */ \ + cmdq_pkt_assign(&_c->pkt, CMDQ_THR_SPR_IDX0, \ + CMDQ_ADDR_HIGH(_b)); \ + cmdq_pkt_write_s_value(&_c->pkt, CMDQ_THR_SPR_IDX0, \ + CMDQ_ADDR_LOW(_b + _o), _v); \ + } \ +} while (0) #define MM_REG_WAIT(cmd, evt) \ do { \ @@ -49,17 +76,33 @@ do { \ cmdq_pkt_set_event(&((c)->pkt), (e)); \ } while (0) -#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask) \ -do { \ - typeof(_mask) (_m) = (_mask); \ - cmdq_pkt_poll_mask(&((cmd)->pkt), id, \ - (base) + (ofst), (val), \ - (((_m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ - (0xffffffff) : (_m)); \ +#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, mask) \ +do { \ + typeof(cmd) (_c) = (cmd); \ + typeof(id) (_i) = (id); \ + typeof(base) (_b) = (base); \ + typeof(ofst) (_o) = (ofst); \ + typeof(val) (_v) = (val); \ + typeof(mask) (_m) = (mask); \ + _m = ((_m & (ofst##_MASK)) == (ofst##_MASK)) ? 0xffffffff : _m; \ + if (_i != CMDQ_SUBSYS_INVALID) \ + cmdq_pkt_poll_mask(&_c->pkt, _i, _b + _o, _v, _m); \ + else /* POLL not support SPR, so use cmdq_pkt_poll_addr() */ \ + cmdq_pkt_poll_addr(&_c->pkt, _b + _o, _v, _m); \ } while (0) -#define MM_REG_POLL(cmd, id, base, ofst, val) \ - cmdq_pkt_poll(&((cmd)->pkt), id, (base) + (ofst), (val)) +#define MM_REG_POLL(cmd, id, base, ofst, val) \ +do { \ + typeof(cmd) (_c) = (cmd); \ + typeof(id) (_i) = (id); \ + typeof(base) (_b) = (base); \ + typeof(ofst) (_o) = (ofst); \ + typeof(val) (_v) = (val); \ + if (_i != CMDQ_SUBSYS_INVALID) \ + cmdq_pkt_poll(&_c->pkt, _i, _b + _o, _v); \ + else /* POLL not support SPR, so use cmdq_pkt_poll_addr() */ \ + cmdq_pkt_poll_addr(&_c->pkt, _b + _o, _v, 0xffffffff); \ +} while (0) enum mtk_mdp_comp_id { MDP_COMP_NONE = -1, /* Invalid engine */ -- GitLab From c61596e3c05f320e07354a70aabd550a8d246f81 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Thu, 5 Dec 2024 02:02:46 +0000 Subject: [PATCH 250/456] UPSTREAM: ASoC: dapm: fix bounds checker error in dapm_widget_list_create The widgets array in the snd_soc_dapm_widget_list has a __counted_by attribute attached to it, which points to the num_widgets variable. This attribute is used in bounds checking, and if it is not set before the array is filled, then the bounds sanitizer will issue a warning or a kernel panic if CONFIG_UBSAN_TRAP is set. This patch sets the size of the widgets list calculated with list_for_each as the initial value for num_widgets as it is used for allocating memory for the array. It is updated with the actual number of added elements after the array is filled. Signed-off-by: Aleksei Vetrov Fixes: 80e698e2df5b ("ASoC: soc-dapm: Annotate struct snd_soc_dapm_widget_list with __counted_by") Link: https://patch.msgid.link/20241028-soc-dapm-bounds-checker-fix-v1-1-262b0394e89e@google.com Signed-off-by: Mark Brown (cherry picked from commit 2ef9439f7a19fd3d43b288d38b1c6e55b668a4fe) BUG=b:326869955 TEST=Test Audio use cases. Signed-off-by: Linux Patches Robot Change-Id: I4cfc168ee129e81944e7538a103356062c91758d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6072530 Commit-Queue: Terry Cheong Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Reviewed-by: Terry Cheong Signed-off-by: Hubert Mazur --- sound/soc/soc-dapm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index fa0d24e8f9f44..b32cb7520ba3d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1148,6 +1148,8 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list, if (*list == NULL) return -ENOMEM; + (*list)->num_widgets = size; + list_for_each_entry(w, widgets, work_list) (*list)->widgets[i++] = w; -- GitLab From d6f6b5453db1b14181822e43f4c772ded7b3c622 Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Fri, 3 Jan 2025 21:35:59 +0800 Subject: [PATCH 251/456] FROMLIST: wifi: mt76: mt7925: fix the unfinished command of regd_notifier before suspend Before entering suspend, we need to ensure that all MCU command are completed. In some cases, such as with regd_notifier, there is a chance that CLC commands, will be executed before suspend. Signed-off-by: Quan Zhou (am from https://patchwork.kernel.org/patch/13925567/) (also found at https://lore.kernel.org/r/3af7b4e5bf7437832b016e32743657d1d55b1f9d.1735910288.git.quan.zhou@mediatek.com) BUG=b:378382242 UPSTREAM-TASK=b:387617840 TEST=fix the unfinished command of regd_notifier before suspend Change-Id: If243b72bc26052f0d3e35a2d07ff68f5be3427a1 Signed-off-by: Quan Zhou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6144485 Reviewed-by: Fei Shao Tested-by: Jintao Lin Reviewed-by: Jintao Lin Commit-Queue: Jintao Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/net/wireless/mediatek/mt76/mt7925/init.c | 4 ++++ drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index 039949b344b98..d69a1dbc4c1b4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -79,11 +79,14 @@ mt7925_regd_notifier(struct wiphy *wiphy, mdev->region = req->dfs_region; dev->country_ie_env = req->country_ie_env; + dev->regd_in_progress = true; mt792x_mutex_acquire(dev); mt7925_mcu_set_clc(dev, req->alpha2, req->country_ie_env); mt7925_mcu_set_channel_domain(hw->priv); mt7925_set_tx_sar_pwr(hw, NULL); mt792x_mutex_release(dev); + dev->regd_in_progress = false; + wake_up(&dev->wait); } static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev) @@ -225,6 +228,7 @@ int mt7925_register_device(struct mt792x_dev *dev) spin_lock_init(&dev->pm.wake.lock); mutex_init(&dev->pm.mutex); init_waitqueue_head(&dev->pm.wait); + init_waitqueue_head(&dev->wait); spin_lock_init(&dev->pm.txq_lock); INIT_DELAYED_WORK(&dev->mphy.mac_work, mt792x_mac_work); INIT_DELAYED_WORK(&dev->phy.scan_work, mt7925_scan_work); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index e36a8f4541941..d1b0389a5cc25 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -455,6 +455,9 @@ static int mt7925_pci_suspend(struct device *device) if (err < 0) goto restore_suspend; + wait_event_timeout(dev->wait, + !dev->regd_in_progress, 5 * HZ); + /* always enable deep sleep during suspend to reduce * power consumption */ -- GitLab From c9445470326c65fe11a654976a380974943c6d4f Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Fri, 3 Jan 2025 21:39:43 +0800 Subject: [PATCH 252/456] FROMLIST: wifi: mt76: mt7925: fix CLC command timeout when suspend/resume When enter suspend/resume while in a connected state, the upper layer will trigger disconnection before entering suspend, and at the same time, it will trigger regd_notifier() and update CLC, causing the CLC event to not be received due to suspend, resulting in a command timeout. Therefore, the update of CLC is postponed until resume, to ensure data consistency and avoid the occurrence of command timeout. Signed-off-by: Quan Zhou (am from https://patchwork.kernel.org/patch/13925569/) (also found at https://lore.kernel.org/r/bab00a2805d0533fd8beaa059222659858a9dcb5.1735910455.git.quan.zhou@mediatek.com) BUG=b:378382242, b:385629825 UPSTREAM-TASK=b:387617842 TEST=fix CLC command timeout when suspend/resume Change-Id: I0313a9780370dbbb0d43a4d4bec899ab5be8fb18 Signed-off-by: Quan Zhou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6144346 Reviewed-by: Sean Paul Reviewed-by: Fei Shao Tested-by: Jintao Lin Reviewed-by: Jintao Lin Commit-Queue: Jintao Lin Signed-off-by: Hubert Mazur --- .../net/wireless/mediatek/mt76/mt7925/init.c | 20 ++++++++++++++++--- .../wireless/mediatek/mt76/mt7925/mt7925.h | 1 + .../net/wireless/mediatek/mt76/mt7925/pci.c | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index d69a1dbc4c1b4..e601c4232e007 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -57,6 +57,18 @@ static int mt7925_thermal_init(struct mt792x_phy *phy) mt7925_hwmon_groups); return PTR_ERR_OR_ZERO(hwmon); } + +void mt7925_regd_update(struct mt792x_dev *dev) +{ + struct mt76_dev *mdev = &dev->mt76; + struct ieee80211_hw *hw = mdev->hw; + + mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); + mt7925_mcu_set_channel_domain(hw->priv); + mt7925_set_tx_sar_pwr(hw, NULL); +} +EXPORT_SYMBOL_GPL(mt7925_regd_update); + static void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) @@ -64,6 +76,7 @@ mt7925_regd_notifier(struct wiphy *wiphy, struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt76_dev *mdev = &dev->mt76; + struct mt76_connac_pm *pm = &dev->pm; /* allow world regdom at the first boot only */ if (!memcmp(req->alpha2, "00", 2) && @@ -79,11 +92,12 @@ mt7925_regd_notifier(struct wiphy *wiphy, mdev->region = req->dfs_region; dev->country_ie_env = req->country_ie_env; + if (pm->suspended) + return; + dev->regd_in_progress = true; mt792x_mutex_acquire(dev); - mt7925_mcu_set_clc(dev, req->alpha2, req->country_ie_env); - mt7925_mcu_set_channel_domain(hw->priv); - mt7925_set_tx_sar_pwr(hw, NULL); + mt7925_regd_update(dev); mt792x_mutex_release(dev); dev->regd_in_progress = false; wake_up(&dev->wait); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h index c5ea431998e06..60536d98cd6be 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h @@ -215,6 +215,7 @@ int mt7925_mcu_chip_config(struct mt792x_dev *dev, const char *cmd); int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, u8 bit_op, u32 bit_map); +void mt7925_regd_update(struct mt792x_dev *dev); int mt7925_mac_init(struct mt792x_dev *dev); int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index d1b0389a5cc25..93d0fccc15869 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -557,11 +557,14 @@ static int mt7925_pci_resume(struct device *device) local_bh_enable(); err = mt76_connac_mcu_set_hif_suspend(mdev, false); + if (err < 0) + goto failed; /* restore previous ds setting */ if (!pm->ds_enable) mt7925_mcu_set_deep_sleep(dev, false); + mt7925_regd_update(dev); failed: pm->suspended = false; -- GitLab From 3e8a06ae12c25760678278aa01cb74611c66c1a0 Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Fri, 3 Jan 2025 21:44:54 +0800 Subject: [PATCH 253/456] FROMLIST: wifi: mt76: mt7925: add handler to hif suspend/resume event When the system suspend or resume, the WiFi driver sends an hif_ctrl command to the firmware and waits for an event. Due to changes in the event format reported by the chip, the current mt7925's driver does not account for these changes, resulting in command timeout. Add flow to handle hif_ctrl event to avoid command timeout. We also exented API mt76_connac_mcu_set_hif_suspend for connac3 this time. Signed-off-by: Quan Zhou (am from https://patchwork.kernel.org/patch/13925572/) (also found at https://lore.kernel.org/r/3a0844ff5162142c4a9f3cf7104f75076ddd3b87.1735910562.git.quan.zhou@mediatek.com) BUG=b:378382242 UPSTREAM-TASK=b:387617843 TEST=add handler to hif suspend/resume event Change-Id: I976a6617e839f33f6a40d413bffe2f913dd8f509 Signed-off-by: Quan Zhou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6144486 Tested-by: Jintao Lin Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Jintao Lin Reviewed-by: Jintao Lin Signed-off-by: Hubert Mazur --- .../net/wireless/mediatek/mt76/mt7615/main.c | 4 +- .../net/wireless/mediatek/mt76/mt7615/pci.c | 6 +-- .../net/wireless/mediatek/mt76/mt7615/sdio.c | 4 +- .../net/wireless/mediatek/mt76/mt7615/usb.c | 4 +- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 4 +- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 3 +- .../net/wireless/mediatek/mt76/mt7921/pci.c | 6 +-- .../net/wireless/mediatek/mt76/mt7921/sdio.c | 6 +-- .../net/wireless/mediatek/mt76/mt7921/usb.c | 4 +- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 49 ++++++++++++++++++- .../wireless/mediatek/mt76/mt7925/mt7925.h | 20 ++++++++ .../net/wireless/mediatek/mt76/mt7925/pci.c | 29 ++++++++--- .../net/wireless/mediatek/mt76/mt7925/usb.c | 20 ++++++-- drivers/net/wireless/mediatek/mt76/mt792x.h | 2 + 14 files changed, 127 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index c27acaf0eb1cf..ca1ca2b2fa5cb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -1262,7 +1262,7 @@ static int mt7615_suspend(struct ieee80211_hw *hw, phy->mt76); if (!mt7615_dev_running(dev)) - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true); mt7615_mutex_release(dev); @@ -1284,7 +1284,7 @@ static int mt7615_resume(struct ieee80211_hw *hw) if (!running) { int err; - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true); if (err < 0) { mt7615_mutex_release(dev); return err; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c index 9f43e673518b8..9a278589df4ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c @@ -83,7 +83,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state) hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && mt7615_firmware_offload(dev); if (hif_suspend) { - err = mt76_connac_mcu_set_hif_suspend(mdev, true); + err = mt76_connac_mcu_set_hif_suspend(mdev, true, true); if (err) return err; } @@ -131,7 +131,7 @@ restore: } napi_enable(&mdev->tx_napi); if (hif_suspend) - mt76_connac_mcu_set_hif_suspend(mdev, false); + mt76_connac_mcu_set_hif_suspend(mdev, false, true); return err; } @@ -175,7 +175,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev) if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && mt7615_firmware_offload(dev)) - err = mt76_connac_mcu_set_hif_suspend(mdev, false); + err = mt76_connac_mcu_set_hif_suspend(mdev, false, true); return err; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c index 9692890ba51b7..8f75a98f68a7f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c @@ -190,7 +190,7 @@ static int mt7663s_suspend(struct device *dev) mt7615_firmware_offload(mdev)) { int err; - err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, true); + err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, true, true); if (err < 0) return err; } @@ -229,7 +229,7 @@ static int mt7663s_resume(struct device *dev) if (!test_bit(MT76_STATE_SUSPEND, &mdev->mphy.state) && mt7615_firmware_offload(mdev)) - err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, false); + err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, false, true); return err; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c index df737e1ff27b7..461128463728c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c @@ -224,7 +224,7 @@ static int mt7663u_suspend(struct usb_interface *intf, pm_message_t state) mt7615_firmware_offload(dev)) { int err; - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true); if (err < 0) return err; } @@ -252,7 +252,7 @@ static int mt7663u_resume(struct usb_interface *intf) if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && mt7615_firmware_offload(dev)) - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true); return err; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 47586444e68ab..769ddee49386b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -2521,7 +2521,7 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_wow_ctrl); -int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend) +int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp) { struct { struct { @@ -2553,7 +2553,7 @@ int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend) req.hdr.hif_type = 0; return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req, - sizeof(req), true); + sizeof(req), wait_resp); } EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend); diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 3991a686ab1e0..0e8c9edacc172 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -1037,6 +1037,7 @@ enum { /* unified event table */ enum { MCU_UNI_EVENT_RESULT = 0x01, + MCU_UNI_EVENT_HIF_CTRL = 0x03, MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04, MCU_UNI_EVENT_ACCESS_REG = 0x6, MCU_UNI_EVENT_IE_COUNTDOWN = 0x09, @@ -1975,7 +1976,7 @@ int mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev, struct ieee80211_vif *vif, bool enable, u8 mdtim, bool wow_suspend); -int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend); +int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp); void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif); int mt76_connac_sta_state_dp(struct mt76_dev *dev, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 95a14e21bf1ce..d42360eeaa165 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -429,7 +429,7 @@ static int mt7921_pci_suspend(struct device *device) if (err < 0) goto restore_suspend; - err = mt76_connac_mcu_set_hif_suspend(mdev, true); + err = mt76_connac_mcu_set_hif_suspend(mdev, true, true); if (err) goto restore_suspend; @@ -475,7 +475,7 @@ restore_napi: if (!pm->ds_enable) mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); - mt76_connac_mcu_set_hif_suspend(mdev, false); + mt76_connac_mcu_set_hif_suspend(mdev, false, true); restore_suspend: pm->suspended = false; @@ -526,7 +526,7 @@ static int mt7921_pci_resume(struct device *device) if (!pm->ds_enable) mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); - err = mt76_connac_mcu_set_hif_suspend(mdev, false); + err = mt76_connac_mcu_set_hif_suspend(mdev, false, true); if (err < 0) goto failed; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c index 004d942ee11a8..fa45324338761 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -239,7 +239,7 @@ static int mt7921s_suspend(struct device *__dev) mt76s_txqs_empty(&dev->mt76), 5 * HZ); /* It is supposed that SDIO bus is idle at the point */ - err = mt76_connac_mcu_set_hif_suspend(mdev, true); + err = mt76_connac_mcu_set_hif_suspend(mdev, true, true); if (err) goto restore_worker; @@ -257,7 +257,7 @@ static int mt7921s_suspend(struct device *__dev) restore_txrx_worker: mt76_worker_enable(&mdev->sdio.net_worker); mt76_worker_enable(&mdev->sdio.txrx_worker); - mt76_connac_mcu_set_hif_suspend(mdev, false); + mt76_connac_mcu_set_hif_suspend(mdev, false, true); restore_worker: mt76_worker_enable(&mdev->tx_worker); @@ -301,7 +301,7 @@ static int mt7921s_resume(struct device *__dev) if (!pm->ds_enable) mt76_connac_mcu_set_deep_sleep(mdev, false); - err = mt76_connac_mcu_set_hif_suspend(mdev, false); + err = mt76_connac_mcu_set_hif_suspend(mdev, false, true); failed: pm->suspended = false; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index 8b7c03c47598d..57620eda853f4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -256,7 +256,7 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state) pm->suspended = true; flush_work(&dev->reset_work); - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true); if (err) goto failed; @@ -306,7 +306,7 @@ static int mt7921u_resume(struct usb_interface *intf) if (err < 0) goto failed; - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true); failed: pm->suspended = false; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index be36d6408536e..670cf9fc0f1aa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -39,7 +39,6 @@ int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd, } else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) || cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) || cmd == MCU_UNI_CMD(STA_REC_UPDATE) || - cmd == MCU_UNI_CMD(HIF_CTRL) || cmd == MCU_UNI_CMD(OFFLOAD) || cmd == MCU_UNI_CMD(SUSPEND)) { struct mt7925_mcu_uni_event *event; @@ -343,6 +342,51 @@ static void mt7925_mcu_roc_handle_grant(struct mt792x_dev *dev, jiffies + msecs_to_jiffies(duration)); } +static void +mt7925_mcu_handle_hif_ctrl_basic(struct mt792x_dev *dev, struct tlv *tlv) +{ + struct mt7925_mcu_hif_ctrl_basic_tlv *basic; + + basic = (struct mt7925_mcu_hif_ctrl_basic_tlv *)tlv; + + if (basic->hifsuspend) { + if (basic->hif_tx_traffic_status == HIF_TRAFFIC_IDLE && + basic->hif_rx_traffic_status == HIF_TRAFFIC_IDLE) + /* success */ + dev->hif_idle = true; + else + /* busy */ + /* invalid */ + dev->hif_idle = false; + } else { + dev->hif_resumed = true; + } + wake_up(&dev->wait); +} + +static void +mt7925_mcu_uni_hif_ctrl_event(struct mt792x_dev *dev, struct sk_buff *skb) +{ + struct tlv *tlv; + u32 tlv_len; + + skb_pull(skb, sizeof(struct mt7925_mcu_rxd) + 4); + tlv = (struct tlv *)skb->data; + tlv_len = skb->len; + + while (tlv_len > 0 && le16_to_cpu(tlv->len) <= tlv_len) { + switch (le16_to_cpu(tlv->tag)) { + case UNI_EVENT_HIF_CTRL_BASIC: + mt7925_mcu_handle_hif_ctrl_basic(dev, tlv); + break; + default: + break; + } + tlv_len -= le16_to_cpu(tlv->len); + tlv = (struct tlv *)((char *)(tlv) + le16_to_cpu(tlv->len)); + } +} + static void mt7925_mcu_uni_roc_event(struct mt792x_dev *dev, struct sk_buff *skb) { @@ -489,6 +533,9 @@ mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev, rxd = (struct mt7925_mcu_rxd *)skb->data; switch (rxd->eid) { + case MCU_UNI_EVENT_HIF_CTRL: + mt7925_mcu_uni_hif_ctrl_event(dev, skb); + break; case MCU_UNI_EVENT_FW_LOG_2_HOST: mt7925_mcu_uni_debug_msg_event(dev, skb); break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h index 60536d98cd6be..0eff0db50c62d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h @@ -27,6 +27,26 @@ #define MCU_UNI_EVENT_ROC 0x27 +#define HIF_TRAFFIC_IDLE 0x2 + +enum { + UNI_EVENT_HIF_CTRL_BASIC = 0, + UNI_EVENT_HIF_CTRL_TAG_NUM +}; + +struct mt7925_mcu_hif_ctrl_basic_tlv { + __le16 tag; + __le16 len; + u8 cid; + u8 pad[3]; + u32 status; + u8 hif_type; + u8 hif_tx_traffic_status; + u8 hif_rx_traffic_status; + u8 hifsuspend; + u8 rsv[4]; +} __packed; + enum { UNI_ROC_ACQUIRE, UNI_ROC_ABORT, diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index 93d0fccc15869..36e0e98f6e936 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -442,9 +442,10 @@ static int mt7925_pci_suspend(struct device *device) struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; - int i, err; + int i, err, ret; pm->suspended = true; + dev->hif_resumed = false; flush_work(&dev->reset_work); cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); @@ -463,9 +464,13 @@ static int mt7925_pci_suspend(struct device *device) */ mt7925_mcu_set_deep_sleep(dev, true); - err = mt76_connac_mcu_set_hif_suspend(mdev, true); - if (err) + mt76_connac_mcu_set_hif_suspend(mdev, true, false); + ret = wait_event_timeout(dev->wait, + dev->hif_idle, 3 * HZ); + if (!ret) { + err = -ETIMEDOUT; goto restore_suspend; + } napi_disable(&mdev->tx_napi); mt76_worker_disable(&mdev->tx_worker); @@ -509,8 +514,11 @@ restore_napi: if (!pm->ds_enable) mt7925_mcu_set_deep_sleep(dev, false); - mt76_connac_mcu_set_hif_suspend(mdev, false); - + mt76_connac_mcu_set_hif_suspend(mdev, false, false); + ret = wait_event_timeout(dev->wait, + dev->hif_resumed, 3 * HZ); + if (!ret) + err = -ETIMEDOUT; restore_suspend: pm->suspended = false; @@ -526,8 +534,9 @@ static int mt7925_pci_resume(struct device *device) struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; - int i, err; + int i, err, ret; + dev->hif_idle = false; err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto failed; @@ -556,9 +565,13 @@ static int mt7925_pci_resume(struct device *device) napi_schedule(&mdev->tx_napi); local_bh_enable(); - err = mt76_connac_mcu_set_hif_suspend(mdev, false); - if (err < 0) + mt76_connac_mcu_set_hif_suspend(mdev, false, false); + ret = wait_event_timeout(dev->wait, + dev->hif_resumed, 3 * HZ); + if (!ret) { + err = -ETIMEDOUT; goto failed; + } /* restore previous ds setting */ if (!pm->ds_enable) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c index 1e0f094fc9059..b1fa5d50cac88 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c @@ -243,14 +243,19 @@ static int mt7925u_suspend(struct usb_interface *intf, pm_message_t state) { struct mt792x_dev *dev = usb_get_intfdata(intf); struct mt76_connac_pm *pm = &dev->pm; - int err; + int err, ret; pm->suspended = true; + dev->hif_resumed = false; flush_work(&dev->reset_work); - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); - if (err) + mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, false); + ret = wait_event_timeout(dev->wait, + dev->hif_idle, 3 * HZ); + if (!ret) { + err = -ETIMEDOUT; goto failed; + } mt76u_stop_rx(&dev->mt76); mt76u_stop_tx(&dev->mt76); @@ -271,8 +276,9 @@ static int mt7925u_resume(struct usb_interface *intf) struct mt792x_dev *dev = usb_get_intfdata(intf); struct mt76_connac_pm *pm = &dev->pm; bool reinit = true; - int err, i; + int err, i, ret; + dev->hif_idle = false; for (i = 0; i < 10; i++) { u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT); @@ -298,7 +304,11 @@ static int mt7925u_resume(struct usb_interface *intf) if (err < 0) goto failed; - err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, false); + ret = wait_event_timeout(dev->wait, + dev->hif_resumed, 3 * HZ); + if (!ret) + err = -ETIMEDOUT; failed: pm->suspended = false; diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index c54ea31496526..48c9e5e62a6c5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -214,6 +214,8 @@ struct mt792x_dev { bool has_eht:1; bool regd_in_progress:1; bool aspm_supported:1; + bool hif_idle:1; + bool hif_resumed:1; wait_queue_head_t wait; struct work_struct init_work; -- GitLab From d4ea56e59971b7d0fdfec2d1faada6574e4c50be Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Fri, 3 Jan 2025 21:53:50 +0800 Subject: [PATCH 254/456] FROMLIST: wifi: mt76: mt7925e: fix too long of wifi resume time The mt7925e takes a long time to resume in platform resume scenarios. This is due to the mt7925 reconfiguring the tx power for each wifi channel during resume. By streamlining the process and removing redundant power configurations, the resume time for the mt7925 can be shortened. Signed-off-by: Quan Zhou (am from https://patchwork.kernel.org/patch/13925579/) (also found at https://lore.kernel.org/r/f075d43d87a5eefa5869baf755e9986edf735860.1735910836.git.quan.zhou@mediatek.com) BUG=b:381808308 UPSTREAM-TASK=b:387599382 TEST=fix too long of wifi resume time Change-Id: Ic110e42fc679d8525ec955d1a3d20b944a3ab117 Signed-off-by: Quan Zhou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6144226 Reviewed-by: Jintao Lin Tested-by: Jintao Lin Commit-Queue: Jintao Lin Reviewed-by: Sean Paul Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/net/wireless/mediatek/mt76/mt7925/init.c | 5 +++++ drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 1 + drivers/net/wireless/mediatek/mt76/mt7925/main.c | 10 +++++++--- drivers/net/wireless/mediatek/mt76/mt792x.h | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index e601c4232e007..77d07dc85ea66 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -63,9 +63,13 @@ void mt7925_regd_update(struct mt792x_dev *dev) struct mt76_dev *mdev = &dev->mt76; struct ieee80211_hw *hw = mdev->hw; + if (!dev->regd_change) + return; + mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); mt7925_mcu_set_channel_domain(hw->priv); mt7925_set_tx_sar_pwr(hw, NULL); + dev->regd_change = false; } EXPORT_SYMBOL_GPL(mt7925_regd_update); @@ -91,6 +95,7 @@ mt7925_regd_notifier(struct wiphy *wiphy, memcpy(mdev->alpha2, req->alpha2, 2); mdev->region = req->dfs_region; dev->country_ie_env = req->country_ie_env; + dev->regd_change = true; if (pm->suspended) return; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c index cf36750cf7092..473c4184a026f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -1310,6 +1310,7 @@ void mt7925_mac_reset_work(struct work_struct *work) cancel_delayed_work_sync(&dev->mphy.mac_work); cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); + dev->sar_inited = false; for (i = 0; i < 10; i++) { mutex_lock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 3532612524d2a..1f8c63a28ed60 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -311,6 +311,7 @@ void mt7925_set_stream_he_eht_caps(struct mt792x_phy *phy) int __mt7925_start(struct mt792x_phy *phy) { struct mt76_phy *mphy = phy->mt76; + struct mt792x_dev *dev = phy->dev; int err; err = mt7925_mcu_set_channel_domain(mphy); @@ -321,9 +322,12 @@ int __mt7925_start(struct mt792x_phy *phy) if (err) return err; - err = mt7925_set_tx_sar_pwr(mphy->hw, NULL); - if (err) - return err; + if (!dev->sar_inited) { + err = mt7925_set_tx_sar_pwr(mphy->hw, NULL); + if (err) + return err; + dev->sar_inited = true; + } mt792x_mac_reset_counters(phy); set_bit(MT76_STATE_RUNNING, &mphy->state); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index 48c9e5e62a6c5..d91d67c597112 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -216,6 +216,8 @@ struct mt792x_dev { bool aspm_supported:1; bool hif_idle:1; bool hif_resumed:1; + bool sar_inited:1; + bool regd_change:1; wait_queue_head_t wait; struct work_struct init_work; -- GitLab From 74f39fb6cbcfcad063fbdaf6bcd07931657a57d3 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Wed, 4 Dec 2024 22:25:38 +0800 Subject: [PATCH 255/456] FROMGIT: drm/mediatek: dp: Support flexible length of DP calibration data The DP calibration data is stored in nvmem cells, and the data layout is described in the `mtk_dp_efuse_fmt` arrays for each platform. There is no guarantee that the data is always a 4-length u32 cell array. For example, MT8188 has a data length of 3, preventing it from passing the preliminary check and undergoing calibration. Update the logic to support flexible data lengths. Specifically, we validate the length returned from `nvmem_cell_read()` against the platform-specific efuse format. If out-of-bound access is detected, fall back to the default calibration values. This likely indicates an error in either the efuse data length described in DT or the efuse format within the driver. Signed-off-by: Fei Shao Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20241204142626.158395-1-fshao@chromium.org/ Signed-off-by: Chun-Kuang Hu (cherry picked from commit ba5811562988652d88de7503b3bd12da063ae729 https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git mediatek-drm-next) BUG=None TEST=DP calibration works with `reg = <0x1a0 0xc>` in efuse_dp_calib on Geralt UPSTREAM-TASK=b:326878753 Change-Id: Ib0b52a816d13daa5e465bdca5044cead89c39dca Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6144670 Reviewed-by: Pin-yen Lin Commit-Queue: Pin-yen Lin Auto-Submit: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_dp.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index d43d0b352c0bd..2407bc9f0ddba 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -1168,17 +1168,25 @@ static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp) buf = (u32 *)nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) { + if (IS_ERR(buf)) { dev_warn(dev, "Failed to read nvmem_cell_read\n"); - - if (!IS_ERR(buf)) - kfree(buf); - goto use_default_val; } + /* The cell length is in bytes. Convert it to be compatible with u32 buffer. */ + len /= sizeof(u32); + for (i = 0; i < MTK_DP_CAL_MAX; i++) { fmt = &mtk_dp->data->efuse_fmt[i]; + + if (fmt->idx >= len) { + dev_warn(mtk_dp->dev, + "Out-of-bound efuse data access, fmt idx = %d, buf len = %zu\n", + fmt->idx, len); + kfree(buf); + goto use_default_val; + } + cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask; if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) { -- GitLab From 7f7d06ce866c15b6cb1152c08afb1950c37f4f3d Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 3 Apr 2024 18:25:57 +0800 Subject: [PATCH 256/456] CHROMIUM: mailbox: mtk-cmdq: Support GCE loop packets in interrupt handler 1. Add a loop flag for CMDQ packet struct. CMDQ helper will use a loop flag to mark CMDQ packet as looping command and make current command buffer jumps to the beginning when GCE executes to the end of command buffer. 2. Add a looping task handle flow in irq handler. GCE irq occurs when GCE executes to the end of command(EOC) instruction. If the CMDQ packet is a looping command, GCE irq handler can not delete the CMDQ task and disable the GCE thread. Signed-off-by: Jason-JH.Lin Signed-off-by: Hsiao Chien Sung (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240526144443.14345-5-jason-jh.lin@mediatek.com/) BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Change-Id: Ib2eb1653f0187a8cad83899899fa10d2fae03db1 Signed-off-by: Hsiao Chien Sung Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5172075 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073697 Reviewed-by: Hsin-Te Yuan Reviewed-by: Chen-Yu Tsai Reviewed-by: Pin-yen Lin Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/mailbox/mtk-cmdq-mailbox.c | 11 +++++++++++ include/linux/mailbox/mtk-cmdq-mailbox.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index c0b39ad07030b..8995ab46d0551 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -326,6 +326,17 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq, curr_pa = cmdq_reg_shift_addr(readl(thread->base + CMDQ_THR_CURR_ADDR), cmdq->pdata); + task = list_first_entry_or_null(&thread->task_busy_list, + struct cmdq_task, list_entry); + if (task && task->pkt->loop) { + struct cmdq_cb_data data; + + data.sta = err; + data.pkt = task->pkt; + mbox_chan_received_data(task->thread->chan, &data); + return; + } + list_for_each_entry_safe(task, tmp, &thread->task_busy_list, list_entry) { task_end_pa = task->pa_base + task->pkt->cmd_buf_size; diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h index 79398bf95f8da..3f720250fd781 100644 --- a/include/linux/mailbox/mtk-cmdq-mailbox.h +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h @@ -76,6 +76,7 @@ struct cmdq_pkt { size_t cmd_buf_size; /* command occupied size */ size_t buf_size; /* real buffer size */ void *cl; + bool loop; }; u8 cmdq_get_shift_pa(struct mbox_chan *chan); -- GitLab From 45499261092bfdce1f2eb7d43a1e092318dde157 Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Thu, 7 Mar 2024 23:22:16 +0800 Subject: [PATCH 257/456] CHROMIUM: mailbox: mediatek: Move reuseable definition to header for secure driver To support CMDQ secure driver, move some reuseable definition to header. - define: e.g. CMDQ_GCE_NUM_MAX, CMDQ_THR_BASE, CMDQ_THR_SIZE. - struct: e.g. cmdq_thread, cmdq, cmdq_task. - include: e.g. . Add "#include " for the function that takes "struct mbox_chan * chan" as a parameter. That may occur a build error if secure driver header includes the mtk-cmdq-mailbox.h. - function: e.g. cmdq_get_shift_pa(struct mbox_chan *chan). Signed-off-by: Jason-JH.Lin Signed-off-by: Hsiao Chien Sung (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240526144443.14345-6-jason-jh.lin@mediatek.com/) BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Change-Id: Ic47e1d5f12907f408f02ca9eaaa50ecf3f21c08b Signed-off-by: Hsiao Chien Sung Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5172077 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Sean Paul Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073698 Reviewed-by: Yidi Lin Reviewed-by: Hsin-Te Yuan Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- drivers/mailbox/mtk-cmdq-mailbox.c | 30 --------------------- include/linux/mailbox/mtk-cmdq-mailbox.h | 33 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 8995ab46d0551..6ed0a0d420443 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -3,7 +3,6 @@ // Copyright (c) 2018 MediaTek Inc. #include -#include #include #include #include @@ -22,13 +21,10 @@ #define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT) #define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE) -#define CMDQ_GCE_NUM_MAX (2) #define CMDQ_CURR_IRQ_STATUS 0x10 #define CMDQ_SYNC_TOKEN_UPDATE 0x68 #define CMDQ_THR_SLOT_CYCLES 0x30 -#define CMDQ_THR_BASE 0x100 -#define CMDQ_THR_SIZE 0x80 #define CMDQ_THR_WARM_RESET 0x00 #define CMDQ_THR_ENABLE_TASK 0x04 #define CMDQ_THR_SUSPEND_TASK 0x08 @@ -70,32 +66,6 @@ #define CMDQ_JUMP_BY_OFFSET 0x10000000 #define CMDQ_JUMP_BY_PA 0x10000001 -struct cmdq_thread { - struct mbox_chan *chan; - void __iomem *base; - struct list_head task_busy_list; - u32 priority; -}; - -struct cmdq_task { - struct cmdq *cmdq; - struct list_head list_entry; - dma_addr_t pa_base; - struct cmdq_thread *thread; - struct cmdq_pkt *pkt; /* the packet sent from mailbox client */ -}; - -struct cmdq { - struct mbox_controller mbox; - void __iomem *base; - int irq; - u32 irq_mask; - const struct gce_plat *pdata; - struct cmdq_thread *thread; - struct clk_bulk_data clocks[CMDQ_GCE_NUM_MAX]; - bool suspended; -}; - struct gce_plat { u32 thread_nr; u8 shift; diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h index 3f720250fd781..a4532b26714a6 100644 --- a/include/linux/mailbox/mtk-cmdq-mailbox.h +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h @@ -7,10 +7,17 @@ #ifndef __MTK_CMDQ_MAILBOX_H__ #define __MTK_CMDQ_MAILBOX_H__ +#include +#include #include #include #include +#define CMDQ_GCE_NUM_MAX 2 + +#define CMDQ_THR_BASE 0x100 +#define CMDQ_THR_SIZE 0x80 + #define CMDQ_INST_SIZE 8 /* instruction is 64-bit */ #define CMDQ_SUBSYS_SHIFT 16 #define CMDQ_OP_CODE_SHIFT 24 @@ -79,6 +86,32 @@ struct cmdq_pkt { bool loop; }; +struct cmdq_thread { + struct mbox_chan *chan; + void __iomem *base; + struct list_head task_busy_list; + u32 priority; +}; + +struct cmdq { + struct mbox_controller mbox; + void __iomem *base; + int irq; + u32 irq_mask; + const struct gce_plat *pdata; + struct cmdq_thread *thread; + struct clk_bulk_data clocks[CMDQ_GCE_NUM_MAX]; + bool suspended; +}; + +struct cmdq_task { + struct cmdq *cmdq; + struct list_head list_entry; + dma_addr_t pa_base; + struct cmdq_thread *thread; + struct cmdq_pkt *pkt; /* the packet sent from mailbox client */ +}; + u8 cmdq_get_shift_pa(struct mbox_chan *chan); dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan); bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr); -- GitLab From 97c5d505a1182134708bdeae67d240a2160a3ac5 Mon Sep 17 00:00:00 2001 From: Jason-jh Lin Date: Mon, 27 May 2024 22:43:25 +0800 Subject: [PATCH 258/456] CHROMIUM: mailbox: mediatek: Add CMDQ secure mailbox driver To support secure video path feature, GCE have to read/write registgers in the secure world. GCE will enable the secure access permission to the HW who wants to access the secure content buffer. Add CMDQ secure mailbox driver to make CMDQ client user is able to sending their HW settings to the secure world. So that GCE can execute all instructions to configure HW in the secure world. TODO: Remove timeout detection in cmdq_sec_session_send(). Signed-off-by: Jason-JH.Lin Signed-off-by: Hsiao Chien Sung (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240526144443.14345-7-jason-jh.lin@mediatek.com/) Conflicts: drivers/mailbox/mtk-cmdq-mailbox.c conflict with CL:5607585 Fix addr_metadata list missing error conflict with CL:6073702 change share memory to secure memory BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Change-Id: I88b479dbe7b6bd9e6b62d46988e0e5d37d337296 Signed-off-by: Hsiao Chien Sung Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5172078 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073699 Reviewed-by: Yidi Lin Reviewed-by: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/mailbox/Makefile | 2 +- drivers/mailbox/mtk-cmdq-sec-mailbox.c | 947 ++++++++++++++++++ drivers/mailbox/mtk-cmdq-sec-tee.c | 170 ++++ include/linux/mailbox/mtk-cmdq-mailbox.h | 1 + .../linux/mailbox/mtk-cmdq-sec-iwc-common.h | 256 +++++ include/linux/mailbox/mtk-cmdq-sec-mailbox.h | 66 ++ include/linux/mailbox/mtk-cmdq-sec-tee.h | 149 +++ 7 files changed, 1590 insertions(+), 1 deletion(-) create mode 100644 drivers/mailbox/mtk-cmdq-sec-mailbox.c create mode 100644 drivers/mailbox/mtk-cmdq-sec-tee.c create mode 100644 include/linux/mailbox/mtk-cmdq-sec-iwc-common.h create mode 100644 include/linux/mailbox/mtk-cmdq-sec-mailbox.h create mode 100644 include/linux/mailbox/mtk-cmdq-sec-tee.h diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index fc93761171113..82da2f4ee81a1 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -51,7 +51,7 @@ obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o obj-$(CONFIG_MTK_ADSP_MBOX) += mtk-adsp-mailbox.o -obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o +obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o mtk-cmdq-sec-mailbox.o mtk-cmdq-sec-tee.o obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o diff --git a/drivers/mailbox/mtk-cmdq-sec-mailbox.c b/drivers/mailbox/mtk-cmdq-sec-mailbox.c new file mode 100644 index 0000000000000..abe54f4c4f3a1 --- /dev/null +++ b/drivers/mailbox/mtk-cmdq-sec-mailbox.c @@ -0,0 +1,947 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define CMDQ_THR_EXEC_CNT_PA (0x28) + +#define CMDQ_TIMEOUT_DEFAULT (1000) + +#define CMDQ_WFE_CMD(event) (0x2000000080008001ULL | ((u64)(event) << 32)) +#define CMDQ_EOC_CMD (0x4000000000000001ULL) +#define CMDQ_JUMP_CMD(addr, shift) (0x1000000100000000ULL | ((addr) >> (shift))) + +struct cmdq_sec_task { + struct cmdq_task task; + + /* secure CMDQ */ + bool reset_exec; + u32 wait_cookie; + u64 trigger; + u64 exec_time; + struct work_struct exec_work; +}; + +struct cmdq_sec_thread { + struct cmdq_thread thread; + + /* secure CMDQ */ + struct device *dev; + u32 idx; + struct timer_list timeout; + u32 timeout_ms; + struct work_struct timeout_work; + u32 wait_cookie; + u32 next_cookie; + u32 task_cnt; + struct workqueue_struct *task_exec_wq; +}; + +/** + * struct cmdq_sec_context - CMDQ secure context structure. + * @tgid: tgid of process context. + * @state: state of inter-world communicatiom. + * @iwc_msg: buffer for inter-world communicatiom message. + * @tee_ctx: context structure for tee vendor. + * + * Note it is not global data, each process has its own cmdq_sec_context. + */ +struct cmdq_sec_context { + u32 tgid; + void *iwc_msg; + struct cmdq_sec_tee_context tee_ctx; +}; + +struct cmdq_sec { + struct device dev; + const struct gce_sec_plat *pdata; + void __iomem *base; + phys_addr_t base_pa; + struct cmdq_sec_thread *sec_thread; + struct cmdq_pkt clt_pkt; + + atomic_t path_res; + u64 cookie_buf_base; + struct cmdq_sec_context *context; + + struct workqueue_struct *timeout_wq; + u64 sec_invoke; + u64 sec_done; + + struct mbox_client notify_clt; + struct mbox_chan *notify_chan; + struct work_struct irq_notify_work; + struct workqueue_struct *notify_wq; + /* mutex for cmdq_sec_thread excuting cmdq_sec_task */ + struct mutex exec_lock; +}; + +u16 cmdq_sec_get_eof_event_id(struct mbox_chan *chan) +{ + struct cmdq_thread *thread = chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, struct cmdq_sec_thread, thread); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + + return (u16)cmdq->pdata->cmdq_event; +} +EXPORT_SYMBOL_GPL(cmdq_sec_get_eof_event_id); + +dma_addr_t cmdq_sec_get_exec_cnt_addr(struct mbox_chan *chan) +{ + struct cmdq_thread *thread = chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, struct cmdq_sec_thread, thread); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + + dev_dbg(&cmdq->dev, "%s %d: thread:%u gce:%#lx", + __func__, __LINE__, sec_thread->idx, + (unsigned long)cmdq->base_pa); + + return cmdq->base_pa + CMDQ_THR_BASE + + CMDQ_THR_SIZE * sec_thread->idx + CMDQ_THR_EXEC_CNT_PA; +} +EXPORT_SYMBOL_GPL(cmdq_sec_get_exec_cnt_addr); + +dma_addr_t cmdq_sec_get_cookie_addr(struct mbox_chan *chan) +{ + struct cmdq_thread *thread = chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, struct cmdq_sec_thread, thread); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + + if (cmdq->cookie_buf_base == 0) { + dev_err(&cmdq->dev, "%s cookie buffer not ready!", __func__); + return 0; + } + + return cmdq->cookie_buf_base + sec_thread->idx * sizeof(u32); +} +EXPORT_SYMBOL_GPL(cmdq_sec_get_cookie_addr); + +static int cmdq_sec_fill_iwc_msg(struct cmdq_sec_context *context, + struct cmdq_sec_task *sec_task, u32 thrd_idx) +{ + struct iwc_cmdq_message_t *iwc_msg = NULL; + struct cmdq_sec_data *data = (struct cmdq_sec_data *)sec_task->task.pkt->sec_data; + u32 *instr; + + iwc_msg = (struct iwc_cmdq_message_t *)context->iwc_msg; + + if (sec_task->task.pkt->cmd_buf_size + 4 * CMDQ_INST_SIZE > CMDQ_TZ_CMD_BLOCK_SIZE) { + dev_err(context->tee_ctx.dev, "sec_task:%p size:%zu > %u", + sec_task, sec_task->task.pkt->cmd_buf_size, CMDQ_TZ_CMD_BLOCK_SIZE); + return -EFAULT; + } + + if (thrd_idx == CMDQ_INVALID_THREAD) { + iwc_msg->command.cmd_size = 0; + iwc_msg->command.metadata.addr_list_length = 0; + return -EINVAL; + } + + iwc_msg->command.thread = thrd_idx; + iwc_msg->command.cmd_size = sec_task->task.pkt->cmd_buf_size; + memcpy(iwc_msg->command.va_base, sec_task->task.pkt->va_base, iwc_msg->command.cmd_size); + instr = &iwc_msg->command.va_base[iwc_msg->command.cmd_size / 4 - 4]; + /* Remove IRQ_EN in EOC */ + if (*(u64 *)instr == CMDQ_EOC_CMD) + instr[0] = 0; + else + dev_err(context->tee_ctx.dev, "%s %d: find EOC failed: %#x %#x", + __func__, __LINE__, instr[1], instr[0]); + + iwc_msg->command.wait_cookie = sec_task->wait_cookie; + iwc_msg->command.reset_exec = sec_task->reset_exec; + + if (data->meta_cnt > 0) { + iwc_msg->command.metadata.addr_list_length = data->meta_cnt; + memcpy(iwc_msg->command.metadata.addr_list, data->meta_list, + data->meta_cnt * sizeof(struct iwc_cmdq_addr_metadata_t)); + } + + iwc_msg->command.normal_task_handle = (unsigned long)sec_task->task.pkt; + + return 0; +} + +static int cmdq_sec_session_send(struct cmdq_sec *cmdq, + struct cmdq_sec_thread *sec_thread, + struct cmdq_sec_task *sec_task, const u32 iwc_cmd) +{ + int err; + u64 cost; + s32 thrd_idx = (sec_thread) ? sec_thread->idx : CMDQ_INVALID_THREAD; + bool reset_cookie = (sec_thread) ? !sec_thread->task_cnt : false; + struct iwc_cmdq_message_t *iwc_msg = (struct iwc_cmdq_message_t *)cmdq->context->iwc_msg; + struct cmdq_sec_data *sec_data; + + memset(iwc_msg, 0, sizeof(*iwc_msg)); + iwc_msg->cmd = iwc_cmd; + iwc_msg->cmdq_id = cmdq->pdata->hwid; + + switch (iwc_cmd) { + case CMD_CMDQ_IWC_SUBMIT_TASK: + iwc_msg->command.thread = thrd_idx; + err = cmdq_sec_fill_iwc_msg(cmdq->context, sec_task, thrd_idx); + if (err) + return err; + break; + case CMD_CMDQ_IWC_TASK_COOKIE: + iwc_msg->path_resource.reset_cookie = reset_cookie; + iwc_msg->path_resource.thread_id = thrd_idx; + break; + case CMD_CMDQ_IWC_FLUSH_THREAD: + case CMD_CMDQ_IWC_CANCEL_TASK: + iwc_msg->cancel_task.wait_cookie = sec_task->wait_cookie; + iwc_msg->cancel_task.thread = thrd_idx; + sec_data = (struct cmdq_sec_data *)sec_task->task.pkt->sec_data; + iwc_msg->cancel_task.needs_vblank = sec_data->needs_vblank; + break; + case CMD_CMDQ_IWC_PATH_RES_ALLOCATE: + case CMD_CMDQ_IWC_PATH_RES_RELEASE: + default: + break; + } + + dev_dbg(&cmdq->dev, "%s execute cmdq:%p sec_task:%p command:%u thread:%u cookie:%d", + __func__, cmdq, sec_task, iwc_cmd, thrd_idx, + sec_task ? sec_task->wait_cookie : -1); + + /* send message */ + cmdq->sec_invoke = sched_clock(); + err = cmdq_sec_execute_session(&cmdq->context->tee_ctx, iwc_msg->cmd, CMDQ_TIMEOUT_DEFAULT); + cmdq->sec_done = sched_clock(); + + cost = div_u64(cmdq->sec_done - cmdq->sec_invoke, 1000000); + if (cost >= CMDQ_TIMEOUT_DEFAULT) + dev_err(&cmdq->dev, "%s execute timeout cmdq:%p sec_task:%p cost:%lluus", + __func__, cmdq, sec_task, cost); + else + dev_dbg(&cmdq->dev, "%s execute done cmdq:%p sec_task:%p cost:%lluus", + __func__, cmdq, sec_task, cost); + + return err; +} + +static int cmdq_sec_session_reply(const u32 iwc_cmd, struct iwc_cmdq_message_t *iwc_msg, + struct cmdq_sec_task *sec_task) +{ + if (iwc_msg->rsp == 0) + return iwc_msg->rsp; + + if (iwc_cmd == CMD_CMDQ_IWC_SUBMIT_TASK) { + struct iwc_cmdq_sec_status_t *sec_status = &iwc_msg->sec_status; + int i; + + /* print submit fail case status */ + pr_err("last sec status: step:%u status:%d args:%#x %#x %#x %#x dispatch:%s\n", + sec_status->step, sec_status->status, sec_status->args[0], + sec_status->args[1], sec_status->args[2], sec_status->args[3], + sec_status->dispatch); + + for (i = 0; i < sec_status->inst_index; i += 2) + pr_err("instr %d: %08x %08x\n", i / 2, + sec_status->sec_inst[i], sec_status->sec_inst[i + 1]); + } else if (iwc_cmd == CMD_CMDQ_IWC_CANCEL_TASK) { + struct iwc_cmdq_cancel_task_t *cancel = &iwc_msg->cancel_task; + + /* print cancel task fail case status */ + if ((cancel->err_instr[1] >> 24) == CMDQ_CODE_WFE) + pr_err("secure error inst event:%u value:%d\n", + cancel->err_instr[1], cancel->reg_value); + + pr_err("cancel_task inst:%08x %08x aee:%d reset:%d pc:0x%08x\n", + cancel->err_instr[1], cancel->err_instr[0], + cancel->throw_aee, cancel->has_reset, cancel->pc); + } + + return iwc_msg->rsp; +} + +static int cmdq_sec_task_submit(struct cmdq_sec *cmdq, struct cmdq_sec_thread *sec_thread, + struct cmdq_sec_task *sec_task, const u32 iwc_cmd) +{ + int err; + + err = cmdq_sec_session_send(cmdq, sec_thread, sec_task, iwc_cmd); + if (err) { + dev_err(&cmdq->dev, "%s %d: iwc_cmd:%d err:%d sec_task:%p thread:%u gce:%#lx", + __func__, __LINE__, iwc_cmd, err, sec_task, + (sec_thread) ? sec_thread->idx : CMDQ_INVALID_THREAD, + (unsigned long)cmdq->base_pa); + return err; + } + + err = cmdq_sec_session_reply(iwc_cmd, cmdq->context->iwc_msg, sec_task); + if (err) { + dev_err(&cmdq->dev, "%s %d: cmdq_sec_session_reply() err: %d", + __func__, __LINE__, err); + return err; + } + + return 0; +} + +static u32 cmdq_sec_get_cookie(struct cmdq_sec *cmdq, struct cmdq_sec_thread *sec_thread) +{ + int err; + struct iwc_cmdq_message_t *iwc_msg; + + if (cmdq->cookie_buf_base == 0) { + dev_err(&cmdq->dev, "%s cookie buffer not ready!", __func__); + return 0; + } + + err = cmdq_sec_task_submit(cmdq, sec_thread, NULL, CMD_CMDQ_IWC_TASK_COOKIE); + if (err) { + dev_err(&cmdq->dev, "cmdq_sec_task_submit err:%d thread:%u", err, sec_thread->idx); + return 0; + } + + iwc_msg = (struct iwc_cmdq_message_t *)cmdq->context->iwc_msg; + + return iwc_msg->path_resource.cookie; +} + +static void cmdq_sec_task_done(struct cmdq_sec_task *sec_task, int sta) +{ + struct cmdq_cb_data data; + + data.sta = sta; + data.pkt = sec_task->task.pkt; + + pr_debug("%s sec_task:%p pkt:%p err:%d", + __func__, sec_task, sec_task->task.pkt, sta); + + mbox_chan_received_data(sec_task->task.thread->chan, &data); + + list_del_init(&sec_task->task.list_entry); + kfree(sec_task); +} + +static bool cmdq_sec_irq_handler(struct cmdq_sec_thread *sec_thread, + const u32 cookie, const int err) +{ + struct cmdq_sec_task *sec_task; + struct cmdq_task *task, *temp, *cur_task = NULL; + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + unsigned long flags; + int done; + + spin_lock_irqsave(&sec_thread->thread.chan->lock, flags); + if (sec_thread->wait_cookie <= cookie) + done = cookie - sec_thread->wait_cookie + 1; + else if (sec_thread->wait_cookie == (cookie + 1) % CMDQ_MAX_COOKIE_VALUE) + done = 0; + else + done = CMDQ_MAX_COOKIE_VALUE - sec_thread->wait_cookie + 1 + cookie + 1; + + list_for_each_entry_safe(task, temp, &sec_thread->thread.task_busy_list, list_entry) { + if (!done) + break; + + sec_task = container_of(task, struct cmdq_sec_task, task); + cmdq_sec_task_done(sec_task, err); + + if (sec_thread->task_cnt) + sec_thread->task_cnt -= 1; + + done--; + } + + cur_task = list_first_entry_or_null(&sec_thread->thread.task_busy_list, + struct cmdq_task, list_entry); + if (err && cur_task) { + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + + sec_task = container_of(cur_task, struct cmdq_sec_task, task); + + /* for error task, cancel, callback and done */ + cmdq_sec_task_submit(cmdq, sec_thread, sec_task, CMD_CMDQ_IWC_CANCEL_TASK); + + cmdq_sec_task_done(sec_task, err); + + spin_lock_irqsave(&sec_thread->thread.chan->lock, flags); + + task = list_first_entry_or_null(&sec_thread->thread.task_busy_list, + struct cmdq_task, list_entry); + if (cur_task == task) + cmdq_sec_task_done(sec_task, err); + else + dev_err(&cmdq->dev, "task list changed"); + + /* + * error case stop all task for secure, + * since secure tdrv always remove all when cancel + */ + while (!list_empty(&sec_thread->thread.task_busy_list)) { + cur_task = list_first_entry(&sec_thread->thread.task_busy_list, + struct cmdq_task, list_entry); + + sec_task = container_of(cur_task, struct cmdq_sec_task, task); + cmdq_sec_task_done(sec_task, -ECONNABORTED); + } + } else if (err) { + dev_dbg(&cmdq->dev, "error but all task done, check notify callback"); + } + + if (list_empty(&sec_thread->thread.task_busy_list)) { + sec_thread->wait_cookie = 0; + sec_thread->next_cookie = 0; + sec_thread->task_cnt = 0; + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + + if (cmdq_sec_task_submit(cmdq, sec_thread, NULL, CMD_CMDQ_IWC_TASK_COOKIE) < 0) + dev_err(&cmdq->dev, "cmdq_sec_task_submit err, thread:%u",sec_thread->idx); + + del_timer(&sec_thread->timeout); + return true; + } + + sec_thread->wait_cookie = cookie % CMDQ_MAX_COOKIE_VALUE + 1; + + mod_timer(&sec_thread->timeout, jiffies + msecs_to_jiffies(sec_thread->timeout_ms)); + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + + return false; +} + +static void cmdq_sec_irq_notify_work(struct work_struct *work_item) +{ + struct cmdq_sec *cmdq = container_of(work_item, struct cmdq_sec, irq_notify_work); + int i; + + mutex_lock(&cmdq->exec_lock); + + for (i = 0; i < cmdq->pdata->secure_thread_nr; i++) { + struct cmdq_sec_thread *sec_thread = &cmdq->sec_thread[i]; + u32 cookie = cmdq_sec_get_cookie(cmdq, sec_thread); + + if (cookie < sec_thread->wait_cookie || !sec_thread->task_cnt) + continue; + + cmdq_sec_irq_handler(sec_thread, cookie, 0); + } + + mutex_unlock(&cmdq->exec_lock); +} + +static void cmdq_sec_irq_notify_callback(struct mbox_client *cl, void *mssg) +{ + struct cmdq_cb_data *data = (struct cmdq_cb_data *)mssg; + struct cmdq_sec *cmdq = container_of(data->pkt, struct cmdq_sec, clt_pkt); + + if (work_pending(&cmdq->irq_notify_work)) { + dev_dbg(&cmdq->dev, "%s last notify callback working", __func__); + return; + } + + queue_work(cmdq->notify_wq, &cmdq->irq_notify_work); +} + +static void cmdq_sec_irq_notify_stop(struct cmdq_sec *cmdq) +{ + dma_unmap_single(cmdq->pdata->mbox->dev, cmdq->clt_pkt.pa_base, + cmdq->clt_pkt.buf_size, DMA_TO_DEVICE); + kfree(cmdq->clt_pkt.va_base); + memset(&cmdq->clt_pkt, 0, sizeof (cmdq->clt_pkt)); + mbox_free_channel(cmdq->notify_chan); + cmdq->notify_chan = NULL; + memset(&cmdq->notify_clt, 0, sizeof (cmdq->notify_clt)); +} + +static int cmdq_sec_irq_notify_start(struct cmdq_sec *cmdq) +{ + int err; + dma_addr_t dma_addr; + u64 *inst = NULL; + + if (cmdq->notify_chan) { + dev_warn(&cmdq->dev, "%s: already started\n", __func__); + return 0; + } + + cmdq->notify_clt.dev = cmdq->pdata->mbox->dev; + cmdq->notify_clt.rx_callback = cmdq_sec_irq_notify_callback; + cmdq->notify_clt.tx_block = false; + cmdq->notify_clt.knows_txdone = true; + cmdq->notify_chan = mbox_request_channel(&cmdq->notify_clt, 0); + if (IS_ERR(cmdq->notify_chan)) { + dev_err(&cmdq->dev, "failed to request channel\n"); + return -ENODEV; + } + + cmdq->clt_pkt.va_base = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!cmdq->clt_pkt.va_base) + return -ENOMEM; + + cmdq->clt_pkt.buf_size = PAGE_SIZE; + dma_addr = dma_map_single(cmdq->pdata->mbox->dev, cmdq->clt_pkt.va_base, + cmdq->clt_pkt.buf_size, DMA_TO_DEVICE); + if (dma_mapping_error(cmdq->pdata->mbox->dev, dma_addr)) { + dev_err(cmdq->pdata->mbox->dev, "dma map failed, size=%lu\n", PAGE_SIZE); + kfree(cmdq->clt_pkt.va_base); + return -ENOMEM; + } + cmdq->clt_pkt.pa_base = dma_addr; + + INIT_WORK(&cmdq->irq_notify_work, cmdq_sec_irq_notify_work); + + /* generate irq notify loop command */ + inst = (u64 *)cmdq->clt_pkt.va_base; + *inst = CMDQ_WFE_CMD(cmdq->pdata->cmdq_event); + inst++; + *inst = CMDQ_EOC_CMD; + inst++; + *inst = CMDQ_JUMP_CMD(cmdq->clt_pkt.pa_base + cmdq->pdata->mminfra_offset, + cmdq->pdata->shift); + inst++; + cmdq->clt_pkt.cmd_buf_size += CMDQ_INST_SIZE * 3; + cmdq->clt_pkt.loop = true; + + dma_sync_single_for_device(cmdq->pdata->mbox->dev, + cmdq->clt_pkt.pa_base, + cmdq->clt_pkt.cmd_buf_size, + DMA_TO_DEVICE); + err = mbox_send_message(cmdq->notify_chan, &cmdq->clt_pkt); + mbox_client_txdone(cmdq->notify_chan, 0); + if (err < 0) { + dev_err(&cmdq->dev, "%s failed:%d", __func__, err); + cmdq_sec_irq_notify_stop(cmdq); + return err; + } + + dev_dbg(&cmdq->dev, "%s success!", __func__); + + return 0; +} + +static int cmdq_sec_mbox_flush(struct mbox_chan *chan, unsigned long timeout) +{ + struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, + struct cmdq_sec_thread, thread); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + u32 cookie = 0; + int err = 0; + struct iwc_cmdq_message_t *iwc_msg; + struct cmdq_sec_task *sec_task; + struct cmdq_task *cur_task = NULL; + + mutex_lock(&cmdq->exec_lock); + + if (list_empty(&thread->task_busy_list) || sec_thread->task_cnt == 0) + goto flush_done; + + cur_task = list_first_entry_or_null(&sec_thread->thread.task_busy_list, + struct cmdq_task, list_entry); + if (!cur_task) + goto flush_done; + + sec_task = container_of(cur_task, struct cmdq_sec_task, task); + err = cmdq_sec_task_submit(cmdq, sec_thread, sec_task, CMD_CMDQ_IWC_FLUSH_THREAD); + if (err) { + dev_err(&cmdq->dev, "cmdq_sec_task_submit err:%d thread:%u", err, sec_thread->idx); + goto flush_done; + } + + iwc_msg = (struct iwc_cmdq_message_t *)cmdq->context->iwc_msg; + cookie = cmdq_sec_get_cookie(cmdq, sec_thread); + if (cookie >= sec_thread->wait_cookie && iwc_msg->cancel_task.irq_status) + cmdq_sec_irq_handler(sec_thread, sec_task->wait_cookie, err); + else if (iwc_msg->cancel_task.irq_status == 0) + cmdq_sec_irq_handler(sec_thread, sec_task->wait_cookie, -ECONNABORTED); + +flush_done: + mutex_unlock(&cmdq->exec_lock); + + return err; +} + +static void cmdq_sec_task_exec_work(struct work_struct *work_item) +{ + struct cmdq_sec_task *sec_task = container_of(work_item, + struct cmdq_sec_task, exec_work); + struct cmdq_sec_thread *sec_thread = container_of(sec_task->task.thread, + struct cmdq_sec_thread, thread); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + unsigned long flags; + int err; + + dev_dbg(&cmdq->dev, "%s gce:%#lx sec_task:%p pkt:%p thread:%u", + __func__, (unsigned long)cmdq->base_pa, + sec_task, sec_task->task.pkt, sec_thread->idx); + + if (!sec_task->task.pkt->sec_data) { + dev_err(&cmdq->dev, "pkt:%p without sec_data", sec_task->task.pkt); + return; + } + + if (sec_thread->task_cnt >= CMDQ_MAX_TASK_IN_SECURE_THREAD) { + struct cmdq_cb_data cb_data; + + dev_dbg(&cmdq->dev, "task_cnt:%u cannot more than %u sec_task:%p thread:%u", + sec_thread->task_cnt, CMDQ_MAX_TASK_IN_SECURE_THREAD, + sec_task, sec_thread->idx); + cb_data.sta = -EMSGSIZE; + cb_data.pkt = sec_task->task.pkt; + mbox_chan_received_data(sec_thread->thread.chan, &cb_data); + kfree(sec_task); + return; + } + + cmdq_sec_mbox_flush(sec_thread->thread.chan, 0); + + mutex_lock(&cmdq->exec_lock); + + if (!sec_thread->task_cnt) { + err = cmdq_sec_task_submit(cmdq, sec_thread, NULL, CMD_CMDQ_IWC_TASK_COOKIE); + if (err) + dev_err(&cmdq->dev, "cmdq_sec_task_submit err:%d thread:%u", + err, sec_thread->idx); + } + + spin_lock_irqsave(&sec_thread->thread.chan->lock, flags); + if (!sec_thread->task_cnt) { + mod_timer(&sec_thread->timeout, jiffies + + msecs_to_jiffies(sec_thread->timeout_ms)); + sec_thread->wait_cookie = 1; + sec_thread->next_cookie = 1; + } + sec_task->reset_exec = sec_thread->task_cnt ? false : true; + sec_task->wait_cookie = sec_thread->next_cookie; + sec_thread->next_cookie = (sec_thread->next_cookie + 1) % CMDQ_MAX_COOKIE_VALUE; + list_add_tail(&sec_task->task.list_entry, &sec_thread->thread.task_busy_list); + sec_thread->task_cnt += 1; + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + sec_task->trigger = sched_clock(); + + err = cmdq_sec_task_submit(cmdq, sec_thread, sec_task, CMD_CMDQ_IWC_SUBMIT_TASK); + if (err) { + struct cmdq_cb_data cb_data; + + cb_data.sta = err; + cb_data.pkt = sec_task->task.pkt; + mbox_chan_received_data(sec_thread->thread.chan, &cb_data); + + spin_lock_irqsave(&sec_thread->thread.chan->lock, flags); + if (!sec_thread->task_cnt) + dev_err(&cmdq->dev, "thread:%u task_cnt:%u cannot below zero", + sec_thread->idx, sec_thread->task_cnt); + else + sec_thread->task_cnt -= 1; + + sec_thread->next_cookie = (sec_thread->next_cookie - 1 + + CMDQ_MAX_COOKIE_VALUE) % CMDQ_MAX_COOKIE_VALUE; + list_del(&sec_task->task.list_entry); + dev_dbg(&cmdq->dev, "gce:%#lx err:%d sec_task:%p pkt:%p", + (unsigned long)cmdq->base_pa, err, sec_task, sec_task->task.pkt); + dev_dbg(&cmdq->dev, "thread:%u task_cnt:%u wait_cookie:%u next_cookie:%u", + sec_thread->idx, sec_thread->task_cnt, + sec_thread->wait_cookie, sec_thread->next_cookie); + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + + kfree(sec_task); + } + + mutex_unlock(&cmdq->exec_lock); +} + +static int cmdq_sec_mbox_send_data(struct mbox_chan *chan, void *data) +{ + struct cmdq_pkt *pkt = (struct cmdq_pkt *)data; + struct cmdq_sec_data *sec_data = (struct cmdq_sec_data *)pkt->sec_data; + struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, struct cmdq_sec_thread, thread); + struct cmdq_sec_task *sec_task; + + if (!sec_data) + return -EINVAL; + + sec_task = kzalloc(sizeof(*sec_task), GFP_ATOMIC); + if (!sec_task) + return -ENOMEM; + + sec_task->task.pkt = pkt; + sec_task->task.thread = thread; + + INIT_WORK(&sec_task->exec_work, cmdq_sec_task_exec_work); + queue_work(sec_thread->task_exec_wq, &sec_task->exec_work); + + return 0; +} + +static void cmdq_sec_thread_timeout(struct timer_list *t) +{ + struct cmdq_sec_thread *sec_thread = from_timer(sec_thread, t, timeout); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + + if (!work_pending(&sec_thread->timeout_work)) + queue_work(cmdq->timeout_wq, &sec_thread->timeout_work); +} + +static void cmdq_sec_task_timeout_work(struct work_struct *work_item) +{ + struct cmdq_sec_thread *sec_thread = container_of(work_item, + struct cmdq_sec_thread, timeout_work); + struct cmdq_sec *cmdq = container_of(sec_thread->dev, struct cmdq_sec, dev); + struct cmdq_task *task; + struct cmdq_sec_task *sec_task; + unsigned long flags; + u64 duration; + u32 cookie; + + mutex_lock(&cmdq->exec_lock); + cookie = cmdq_sec_get_cookie(cmdq, sec_thread); + + spin_lock_irqsave(&sec_thread->thread.chan->lock, flags); + if (list_empty(&sec_thread->thread.task_busy_list)) { + dev_err(&cmdq->dev, "thread:%u task_list is empty", sec_thread->idx); + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + goto done; + } + + task = list_first_entry(&sec_thread->thread.task_busy_list, + struct cmdq_task, list_entry); + sec_task = container_of(task, struct cmdq_sec_task, task); + duration = div_u64(sched_clock() - sec_task->trigger, 1000000); + if (duration < sec_thread->timeout_ms) { + mod_timer(&sec_thread->timeout, jiffies + + msecs_to_jiffies(sec_thread->timeout_ms - duration)); + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + goto done; + } + + spin_unlock_irqrestore(&sec_thread->thread.chan->lock, flags); + + dev_err(&cmdq->dev, "%s duration:%llu cookie:%u thread:%u", + __func__, duration, cookie, sec_thread->idx); + cmdq_sec_irq_handler(sec_thread, cookie, -ETIMEDOUT); + +done: + mutex_unlock(&cmdq->exec_lock); +} + +static int cmdq_sec_mbox_startup(struct mbox_chan *chan) +{ + struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv; + struct cmdq_sec_thread *sec_thread = container_of(thread, + struct cmdq_sec_thread, thread); + char name[20]; + + snprintf(name, sizeof(name), "task_exec_wq_%u", sec_thread->idx); + sec_thread->task_exec_wq = create_singlethread_workqueue(name); + + return 0; +} + +static void cmdq_sec_mbox_shutdown(struct mbox_chan *chan) +{ + cmdq_sec_mbox_flush(chan, 0); +} + +static const struct mbox_chan_ops cmdq_sec_mbox_chan_ops = { + .send_data = cmdq_sec_mbox_send_data, + .startup = cmdq_sec_mbox_startup, + .shutdown = cmdq_sec_mbox_shutdown, +}; + +struct cmdq_sec_mailbox cmdq_sec_mbox = { + .ops = &cmdq_sec_mbox_chan_ops, +}; +EXPORT_SYMBOL_GPL(cmdq_sec_mbox); + +static int cmdq_sec_probe(struct platform_device *pdev) +{ + int i, ret; + struct cmdq_sec *cmdq = NULL; + struct device *dev = &pdev->dev; + struct resource *res; + struct cmdq_sec_context *context; + struct iwc_cmdq_message_t *iwc_msg; + + /* + * Check TEE context is ready at the begining, + * to avoid cmdq_sec structure leaking if probe defer. + */ + context = devm_kzalloc(dev, sizeof(*context), GFP_ATOMIC); + if (!context) + return -ENOMEM; + + context->tgid = current->tgid; + cmdq_sec_setup_tee_context(&context->tee_ctx); + ret = cmdq_sec_init_context(&context->tee_ctx); + if (ret) { + dev_warn(dev, "%s %d: cmdq_sec_init_context() fail: %d", + __func__, __LINE__, ret); + return -EPROBE_DEFER; + } + + ret = cmdq_sec_allocate_wsm(&context->tee_ctx, &context->iwc_msg, + sizeof(struct iwc_cmdq_message_t)); + if (ret) + goto probe_err; + + ret = cmdq_sec_open_session(&context->tee_ctx, context->iwc_msg); + if (ret) + goto probe_err; + + cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL); + if (!cmdq) { + ret = -ENOMEM; + goto probe_err; + } + + cmdq->context = context; + cmdq->dev = pdev->dev; + context->tee_ctx.dev = &cmdq->dev; + cmdq->pdata = (struct gce_sec_plat *)pdev->dev.platform_data; + if (!cmdq->pdata) { + dev_err(dev, "no valid gce platform data!\n"); + ret = -EINVAL; + goto probe_err; + } + + res = platform_get_resource(to_platform_device(cmdq->pdata->mbox->dev), + IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "platform_get_resource() failed!\n"); + ret = -EINVAL; + goto probe_err; + } + + cmdq->base = cmdq->pdata->base; + cmdq->base_pa = res->start; + if (!cmdq->base || cmdq->base_pa == 0) { + ret = -EINVAL; + goto probe_err; + } + + ret = cmdq_sec_irq_notify_start(cmdq); + if (ret) { + dev_err(dev, "%s %d: cmdq_sec_irq_notify_start() failed: %d\n", + __func__, __LINE__, ret); + cmdq_sec_irq_notify_stop(cmdq); + goto probe_err; + } + + ret = cmdq_sec_task_submit(cmdq, NULL, NULL, CMD_CMDQ_IWC_PATH_RES_ALLOCATE); + if (ret) { + dev_err(dev, "%s %d: CMD_CMDQ_IWC_PATH_RES_ALLOCATE failed: %d\n", + __func__, __LINE__, ret); + goto probe_err; + } + + iwc_msg = (struct iwc_cmdq_message_t *)cmdq->context->iwc_msg; + cmdq->cookie_buf_base = iwc_msg->path_resource.cookie_buf_base; + + cmdq->sec_thread = devm_kcalloc(dev, cmdq->pdata->secure_thread_nr, + sizeof(*cmdq->sec_thread), GFP_KERNEL); + if (!cmdq->sec_thread) { + ret = -ENOMEM; + goto probe_err; + } + + mutex_init(&cmdq->exec_lock); + for (i = 0; i < cmdq->pdata->secure_thread_nr; i++) { + char name[20]; + u32 idx = i + cmdq->pdata->secure_thread_min; + + cmdq->sec_thread[i].dev = &cmdq->dev; + cmdq->sec_thread[i].idx = idx; + cmdq->sec_thread[i].thread.base = cmdq->base + CMDQ_THR_BASE + CMDQ_THR_SIZE * idx; + cmdq->sec_thread[i].timeout_ms = CMDQ_TIMEOUT_DEFAULT; + INIT_LIST_HEAD(&cmdq->sec_thread[i].thread.task_busy_list); + cmdq->pdata->mbox->chans[idx].con_priv = (void *)&cmdq->sec_thread[i].thread; + cmdq->sec_thread[i].thread.chan = &cmdq->pdata->mbox->chans[idx]; + + snprintf(name, sizeof(name), "task_exec_wq_%u", idx); + cmdq->sec_thread[i].task_exec_wq = create_singlethread_workqueue(name); + timer_setup(&cmdq->sec_thread[i].timeout, cmdq_sec_thread_timeout, 0); + INIT_WORK(&cmdq->sec_thread[i].timeout_work, cmdq_sec_task_timeout_work); + dev_dbg(dev, "re-assign chans[%d] as secure thread\n", idx); + } + cmdq->notify_wq = create_singlethread_workqueue("mtk_cmdq_sec_notify_wq"); + cmdq->timeout_wq = create_singlethread_workqueue("mtk_cmdq_sec_timeout_wq"); + + platform_set_drvdata(pdev, cmdq); + + return 0; + +probe_err: + + if (cmdq) { + if (cmdq->notify_chan) + cmdq_sec_irq_notify_stop(cmdq); + + if (cmdq_sec_task_submit(cmdq, NULL, NULL, CMD_CMDQ_IWC_PATH_RES_RELEASE)) + dev_err(dev, "%s %d: CMD_CMDQ_IWC_PATH_RES_RELEASE failed\n", + __func__, __LINE__); + } + + if (context) { + if (context->tee_ctx.session) + cmdq_sec_close_session(&context->tee_ctx); + + cmdq_sec_free_wsm(&context->tee_ctx, &context->iwc_msg); + cmdq_sec_deinit_context(&context->tee_ctx); + } + + return ret; +} + +static int cmdq_sec_remove(struct platform_device *pdev) +{ + struct cmdq_sec *cmdq = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + + if (cmdq->notify_chan) + cmdq_sec_irq_notify_stop(cmdq); + + if (cmdq_sec_task_submit(cmdq, NULL, NULL, CMD_CMDQ_IWC_PATH_RES_RELEASE)) + dev_err(dev, "%s %d: CMD_CMDQ_IWC_PATH_RES_RELEASE failed\n", + __func__, __LINE__); + + if (cmdq->context) { + if (cmdq->context->tee_ctx.session) + cmdq_sec_close_session(&cmdq->context->tee_ctx); + + cmdq_sec_free_wsm(&cmdq->context->tee_ctx, &cmdq->context->iwc_msg); + cmdq_sec_deinit_context(&cmdq->context->tee_ctx); + } + + return 0; +} + +static struct platform_driver cmdq_sec_drv = { + .probe = cmdq_sec_probe, + .remove = cmdq_sec_remove, + .driver = { + .name = "mtk-cmdq-sec", + }, +}; + +static int __init cmdq_sec_init(void) +{ + return platform_driver_register(&cmdq_sec_drv); +} + +static void __exit cmdq_sec_exit(void) +{ + platform_driver_unregister(&cmdq_sec_drv); +} + +module_init(cmdq_sec_init); +module_exit(cmdq_sec_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/mailbox/mtk-cmdq-sec-tee.c b/drivers/mailbox/mtk-cmdq-sec-tee.c new file mode 100644 index 0000000000000..a0368babf1c9d --- /dev/null +++ b/drivers/mailbox/mtk-cmdq-sec-tee.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include + +#include +#include + +/* lock to protect atomic secure task execution */ +static DEFINE_MUTEX(cmdq_sec_exec_lock); + +void cmdq_sec_setup_tee_context(struct cmdq_sec_tee_context *tee) +{ + /* 09010000 0000 0000 0000000000000000 */ + memset(tee->uuid, 0, sizeof(tee->uuid)); + tee->uuid[0] = 0x9; + tee->uuid[1] = 0x1; +} +EXPORT_SYMBOL_GPL(cmdq_sec_setup_tee_context); + +#if IS_ENABLED(CONFIG_TEE) +static int tee_dev_match(struct tee_ioctl_version_data *t, const void *v) +{ + if (t->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + + return 0; +} + +int cmdq_sec_init_context(struct cmdq_sec_tee_context *tee) +{ + tee->tee_context = tee_client_open_context(NULL, tee_dev_match, NULL, NULL); + if (IS_ERR(tee->tee_context)) { + dev_err(tee->dev, "[%s][%d] tee_client_open_context failed!", __func__, __LINE__); + return -EFAULT; + } + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_init_context); + +int cmdq_sec_deinit_context(struct cmdq_sec_tee_context *tee) +{ + if (tee && tee->tee_context) + tee_client_close_context(tee->tee_context); + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_deinit_context); + +int cmdq_sec_allocate_wsm(struct cmdq_sec_tee_context *tee, void **wsm_buffer, u32 size) +{ + void *buffer; + + if (!wsm_buffer) + return -EINVAL; + + if (size == 0) + return -EINVAL; + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + tee->shared_mem = tee_shm_register_kernel_buf(tee->tee_context, buffer, size); + if (!tee->shared_mem) { + kfree(buffer); + return -ENOMEM; + } + + *wsm_buffer = buffer; + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_allocate_wsm); + +int cmdq_sec_free_wsm(struct cmdq_sec_tee_context *tee, void **wsm_buffer) +{ + if (!wsm_buffer) + return -EINVAL; + + tee_shm_free(tee->shared_mem); + tee->shared_mem = NULL; + kfree(*wsm_buffer); + *wsm_buffer = NULL; + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_free_wsm); + +int cmdq_sec_open_session(struct cmdq_sec_tee_context *tee, void *wsm_buffer) +{ + struct tee_ioctl_open_session_arg osarg = {0}; + struct tee_param params = {0}; + int ret = 0; + + if (!wsm_buffer) + return -EINVAL; + + osarg.num_params = 1; + memcpy(osarg.uuid, tee->uuid, sizeof(osarg.uuid)); + osarg.clnt_login = 0; + + ret = tee_client_open_session(tee->tee_context, &osarg, ¶ms); + if (ret) + return -EFAULT; + + if (!osarg.ret) + tee->session = osarg.session; + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_open_session); + +int cmdq_sec_close_session(struct cmdq_sec_tee_context *tee) +{ + tee_client_close_session(tee->tee_context, tee->session); + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_close_session); + +int cmdq_sec_execute_session(struct cmdq_sec_tee_context *tee, u32 cmd, s32 timeout_ms) +{ + struct tee_ioctl_invoke_arg invoke_arg = {0}; + struct tee_param params = {0}; + u64 ts = sched_clock(); + int ret = 0; + + mutex_lock(&cmdq_sec_exec_lock); + + params.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + params.u.memref.shm = tee->shared_mem; + params.u.memref.shm_offs = 0; + params.u.memref.size = tee->shared_mem->size; + + invoke_arg.num_params = 1; + invoke_arg.session = tee->session; + invoke_arg.func = cmd; + + ret = tee_client_invoke_func(tee->tee_context, &invoke_arg, ¶ms); + if (ret) { + dev_err(tee->dev, "tee_client_invoke_func failed, ret=%d\n", ret); + return -EFAULT; + } + + ret = invoke_arg.ret; + + mutex_unlock(&cmdq_sec_exec_lock); + + ts = div_u64(sched_clock() - ts, 1000000); + + if (ret != 0) + dev_err(tee->dev, + "[SEC]execute: TEEC_InvokeCommand:%u ret:%d cost:%lluus", cmd, ret, ts); + else if (ts > timeout_ms) + dev_err(tee->dev, + "[SEC]execute: TEEC_InvokeCommand:%u ret:%d cost:%lluus", cmd, ret, ts); + else + dev_dbg(tee->dev, + "[SEC]execute: TEEC_InvokeCommand:%u ret:%d cost:%lluus", cmd, ret, ts); + + return ret; +} +EXPORT_SYMBOL_GPL(cmdq_sec_execute_session); +#endif + +MODULE_LICENSE("GPL"); diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h index a4532b26714a6..692259280e05d 100644 --- a/include/linux/mailbox/mtk-cmdq-mailbox.h +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h @@ -84,6 +84,7 @@ struct cmdq_pkt { size_t buf_size; /* real buffer size */ void *cl; bool loop; + void *sec_data; }; struct cmdq_thread { diff --git a/include/linux/mailbox/mtk-cmdq-sec-iwc-common.h b/include/linux/mailbox/mtk-cmdq-sec-iwc-common.h new file mode 100644 index 0000000000000..40413c5e852e0 --- /dev/null +++ b/include/linux/mailbox/mtk-cmdq-sec-iwc-common.h @@ -0,0 +1,256 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __CMDQ_SEC_IWC_COMMON_H__ +#define __CMDQ_SEC_IWC_COMMON_H__ + +/** + * CMDQ_TZ_CMD_BLOCK_SIZE - total command buffer size copy from normal world to secure world. + * Maximum 1 pages will be requested for each command buffer. + * This size could be adjusted when command buffer size is not enough. + */ +#define CMDQ_TZ_CMD_BLOCK_SIZE (4096) + +/** + * CMDQ_IWC_MAX_CMD_LENGTH - max length of u32 array to store commanad buffer. + */ +#define CMDQ_IWC_MAX_CMD_LENGTH (CMDQ_TZ_CMD_BLOCK_SIZE / sizeof(u32)) + +/** + * CMDQ_IWC_MAX_ADDR_LIST_LENGTH - max length of addr metadata list. + */ +#define CMDQ_IWC_MAX_ADDR_LIST_LENGTH (30) + +/** + * CMDQ_IWC_CLIENT_NAME - length for caller_name in iwc_cmdq_command_t. + */ +#define CMDQ_IWC_CLIENT_NAME (16) + +/** + * CMDQ_MAX_READBACK_ENG - length for readback_engs in iwc_cmdq_command_t. + */ +#define CMDQ_MAX_READBACK_ENG (8) + +/** + * CMDQ_SEC_MESSAGE_INST_LEN - length for sec_inst in iwc_cmdq_sec_status_t. + */ +#define CMDQ_SEC_MESSAGE_INST_LEN (8) + +/** + * CMDQ_SEC_DISPATCH_LEN - length for dispatch in iwc_cmdq_sec_status_t. + */ +#define CMDQ_SEC_DISPATCH_LEN (8) + +/* + * IWC Command IDs - ID for normal world(TLC or linux kernel) to secure world. + */ +#define CMD_CMDQ_IWC_SUBMIT_TASK (1) /* submit current task */ +#define CMD_CMDQ_IWC_TASK_COOKIE (2) /* get or reset task cookie info */ +#define CMD_CMDQ_IWC_CANCEL_TASK (3) /* cancel current task */ +#define CMD_CMDQ_IWC_PATH_RES_ALLOCATE (4) /* create global resource for secure path */ +#define CMD_CMDQ_IWC_PATH_RES_RELEASE (5) /* release global resource for secure path */ +#define CMD_CMDQ_IWC_FLUSH_THREAD (6) /* flush the task on current thread */ + +/** + * enum cmdq_iwc_addr_metadata_type - address medadata type to be converted in secure world. + * @CMDQ_IWC_H_2_PA: secure handle to sec PA. + * @CMDQ_IWC_H_2_MVA: secure handle to sec MVA. + * @CMDQ_IWC_NMVA_2_MVA: map normal MVA to secure world. + * @CMDQ_IWC_PH_2_MVA: session protected handle to sec MVA. + * + * To tell secure world waht operation to use for converting address in metadata list. + */ +enum cmdq_iwc_addr_metadata_type { + CMDQ_IWC_H_2_PA = 0, + CMDQ_IWC_H_2_MVA = 1, + CMDQ_IWC_NMVA_2_MVA = 2, + CMDQ_IWC_PH_2_MVA = 3, +}; + +/** + * struct iwc_cmdq_addr_metadata_t - metadata structure for converting address of secure buffer. + * @type: addr metadata type. + * @base_handle: secure address handle. + * @block_offset: block offset from handle(PA) to current block(plane). + * @offset: buffser offset to secure handle. + */ +struct iwc_cmdq_addr_metadata_t { + /** + * @type: address medadata type to be converted in secure world. + */ + u32 type; + + /** + * @base_handle: + * @block_offset: + * @offset: + * these members are used to store the buffer and offset relationship. + * + * ------------- + * | | | + * ------------- + * ^ ^ ^ ^ + * A B C D + * + * A: base_handle + * B: base_handle + block_offset + * C: base_handle + block_offset + offset + */ + u64 base_handle; + u32 block_offset; + u32 offset; +}; + +/** + * struct iwc_cmdq_metadata_t - metadata structure for converting a list of secure buffer address. + * @addr_list_length: length of metadata address list. + * @addr_list: array of metadata address list. + */ +struct iwc_cmdq_metadata_t { + u32 addr_list_length; + struct iwc_cmdq_addr_metadata_t addr_list[CMDQ_IWC_MAX_ADDR_LIST_LENGTH]; +}; + +/** + * struct iwc_cmdq_command_t - structure for excuting cmdq task in secure world. + * @thread: GCE secure thread index to execute command. + * @scenario: scenario to execute command. + * @priority: priority of GCE secure thread. + * @cmd_size: command size used in command buffer. + * @va_base: command buffer + * @wait_cookie: index in thread's task list, it should be (nextCookie - 1). + * @reset_exec: reset HW thread. + * @metadata: metadata structure for converting a list of secure buffer address. + * @normal_task_handle: handle to reference task in normal world. + */ +struct iwc_cmdq_command_t { + /* basic execution data */ + u32 thread; + u32 scenario; + u32 priority; + u32 cmd_size; + u32 va_base[CMDQ_IWC_MAX_CMD_LENGTH]; + + /* exec order data */ + u32 wait_cookie; + bool reset_exec; + + /* metadata */ + struct iwc_cmdq_metadata_t metadata; + + /* debug */ + u64 normal_task_handle; +}; + +/** + * struct iwc_cmdq_cancel_task_t - structure for canceling cmdq task in the secure world. + * @thread: [IN] GCE secure thread index. + * @wait_cookie: [IN] execute count cookie to wait. + * @throw_aee: [OUT] AEE has thrown. + * @has_reset: [OUT] current secure thread has been reset + * @irq_status: [OUT] global secure IRQ flag. + * @irq_flag: [OUT] thread IRQ flag. + * @err_instr: [OUT] err_instr[0] = instruction low bits, err_instr[1] = instruction high bits. + * @reg_value: [OUT] value of error register. + * @pc: [OUT] current pc. + * + * used to store cancel task status from secure world. + */ +struct iwc_cmdq_cancel_task_t { + s32 thread; + u32 wait_cookie; + bool needs_vblank; + bool throw_aee; + bool has_reset; + s32 irq_status; + s32 irq_flag; + u32 err_instr[2]; + u32 reg_value; + u32 pc; +}; + +/** + * struct iwc_cmdq_path_resource_t - Inter-World Communication resource allocation structure. + * @cookie_buf_base: use u64 for 64 bit compatible support cookie buffer address. + * @thread_id: thread id for secure world to use. + * @cookie: cookie from secure world to use. + * @reset_cookie: reset cookie flag to secure world. + * + * used to allocate secure memory from secure world. + */ +struct iwc_cmdq_path_resource_t { + u64 cookie_buf_base; + u32 thread_id; + u32 cookie; + bool reset_cookie; +}; + +/** + * struct iwc_cmdq_debug_config_t - debug config structure for secure debug log. + * + * @log_level: log level in secure world. + * @enable_profile: enable profile in secure world. + */ +struct iwc_cmdq_debug_config_t { + s32 log_level; + s32 enable_profile; +}; + +/** + * struct iwc_cmdq_sec_status_t - secure status from secure world. + * + * @step: the step in secure cmdq TA. + * @status: the status in secure cmdq TA. + * @args: the status arguments in secure cmdq TA. + * @sec_inst: current instruction in secure cmdq TA. + * @inst_index: current instruction index in secure cmdq TA. + * @dispatch: current HW engine configuring in secure cmdq TA. + */ +struct iwc_cmdq_sec_status_t { + u32 step; + s32 status; + u32 args[4]; + u32 sec_inst[CMDQ_SEC_MESSAGE_INST_LEN]; + u32 inst_index; + char dispatch[CMDQ_SEC_DISPATCH_LEN]; +}; + +/** + * struct iwc_cmdq_message_t - Inter-World Communication message structure. + * @cmd: [IN] iwc command id. + * @rsp: [OUT] respond from secureworld, 0 for success, < 0 for error. + * @command: [IN] structure for excuting cmdq task in secure world. + * @cancel_task: [IN] structure for canceling cmdq task in the secure world. + * @path_resource: [IN] + * @debug: [IN] debug config structure for secure debug log. + * @sec_status: [OUT] secure status from secure world. + * @cmdq_id: [IN] GCE core id. + * + * Both Linex kernel and mobicore have their own MMU tables for mapping + * world shared memory and physical addresses, so mobicore does not understand + * linux virtual address mapping. + * If we want to transact a large buffer in TCI/DCI, there are 2 ways (both require 1 copy): + * 1. Ue mc_map to map the normal world buffer to WSM and pass secure_virt_addr in TCI/DCI buffer. + * Note that mc_map implies a memcopy to copy the content from normal world to WSM. + * 2. Declare a fixed-length array in TCI/DCI struct and its size must be < 1M. + */ +struct iwc_cmdq_message_t { + union { + u32 cmd; + s32 rsp; + }; + + union { + struct iwc_cmdq_command_t command; + struct iwc_cmdq_cancel_task_t cancel_task; + struct iwc_cmdq_path_resource_t path_resource; + }; + + struct iwc_cmdq_debug_config_t debug; + struct iwc_cmdq_sec_status_t sec_status; + + u8 cmdq_id; +}; +#endif /* __CMDQ_SEC_IWC_COMMON_H__ */ diff --git a/include/linux/mailbox/mtk-cmdq-sec-mailbox.h b/include/linux/mailbox/mtk-cmdq-sec-mailbox.h new file mode 100644 index 0000000000000..af935e90eed28 --- /dev/null +++ b/include/linux/mailbox/mtk-cmdq-sec-mailbox.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MTK_CMDQ_SEC_MAILBOX_H__ +#define __MTK_CMDQ_SEC_MAILBOX_H__ + +#include +#include + +#include +#include + +#define CMDQ_INVALID_THREAD (-1) +#define CMDQ_MAX_TASK_IN_SECURE_THREAD (16) + +/** + * CMDQ_MAX_COOKIE_VALUE - max value of CMDQ_THR_EXEC_CNT_PA (value starts from 0) + */ +#define CMDQ_MAX_COOKIE_VALUE (0xffff) + +/** + * struct gce_sec_plat - used to pass platform data from cmdq driver. + * @mbox: pointer to mbox controller. + * @base: GCE register base va. + * @hwid: GCE core id. + * @secure_thread_nr: number of secure thread. + * @secure_thread_min: min index of secure thread. + * @cmdq_event: secure EOF event id. + * @shift: address shift bit for GCE + */ +struct gce_sec_plat { + struct mbox_controller *mbox; + void __iomem *base; + u32 hwid; + u8 secure_thread_nr; + u8 secure_thread_min; + u32 cmdq_event; + u8 shift; + u64 mminfra_offset; +}; + +struct cmdq_sec_mailbox { + const struct mbox_chan_ops *ops; +}; + +extern struct cmdq_sec_mailbox cmdq_sec_mbox; + +/** + * struct cmdq_sec_data - used to translate secure buffer PA related instruction + * @meta_cnt: count of element in addr_list. + * @meta_list: array of iwc_cmdq_addr_metadata_t. + * @scenario: scenario config for secure world. + */ +struct cmdq_sec_data { + bool needs_vblank; + u32 meta_cnt; + struct iwc_cmdq_addr_metadata_t meta_list[CMDQ_IWC_MAX_ADDR_LIST_LENGTH]; +}; + +u16 cmdq_sec_get_eof_event_id(struct mbox_chan *chan); +dma_addr_t cmdq_sec_get_cookie_addr(struct mbox_chan *chan); +dma_addr_t cmdq_sec_get_exec_cnt_addr(struct mbox_chan *chan); + +#endif /* __MTK_CMDQ_SEC_MAILBOX_H__ */ diff --git a/include/linux/mailbox/mtk-cmdq-sec-tee.h b/include/linux/mailbox/mtk-cmdq-sec-tee.h new file mode 100644 index 0000000000000..51cfc2ade9387 --- /dev/null +++ b/include/linux/mailbox/mtk-cmdq-sec-tee.h @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MTK_CMDQ_SEC_TEE_H__ +#define __MTK_CMDQ_SEC_TEE_H__ + +#include +#include +#include + +/** + * struct cmdq_sec_tee_context - context for tee vendor + * @uuid: Universally Unique Identifier of secure world. + * @tee_context: basic tee context. + * @session: session handle. + * @shared_mem: shared memory. + */ +struct cmdq_sec_tee_context { + u8 uuid[TEE_IOCTL_UUID_LEN]; + struct device *dev; + struct tee_context *tee_context; + u32 session; + struct tee_shm *shared_mem; +}; + +/** + * cmdq_sec_setup_tee_context() - setup the uuid for the tee context to communicate with + * @tee: context for tee vendor + * + * Return: 0 for success; else the error code is returned + * + */ +void cmdq_sec_setup_tee_context(struct cmdq_sec_tee_context *tee); + +#if IS_ENABLED(CONFIG_TEE) + +/** + * cmdq_sec_init_context() - initialize the tee context + * @tee: context for tee vendor + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_init_context(struct cmdq_sec_tee_context *tee); + +/** + * cmdq_sec_deinit_context() - de-initialize the tee context + * @tee: context for tee vendor + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_deinit_context(struct cmdq_sec_tee_context *tee); + +/** + * cmdq_sec_allocate_wsm() - allocate the world share memory to pass message to tee + * @tee: context for tee vendor + * @wsm_buffer: world share memory buffer with parameters pass to tee + * @size: size to allocate + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_allocate_wsm(struct cmdq_sec_tee_context *tee, void **wsm_buffer, u32 size); + +/** + * cmdq_sec_free_wsm() - free the world share memory + * @tee: context for tee vendor + * @wsm_buffer: world share memory buffer with parameters pass to tee + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_free_wsm(struct cmdq_sec_tee_context *tee, void **wsm_buffer); + +/** + * cmdq_sec_open_session() - open session to the tee context + * @tee: context for tee vendor + * @wsm_buffer: world share memory buffer with parameters pass to tee + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_open_session(struct cmdq_sec_tee_context *tee, void *wsm_buffer); + +/** + * cmdq_sec_close_session() - close session to the tee context + * @tee: context for tee vendor + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_close_session(struct cmdq_sec_tee_context *tee); + +/** + * cmdq_sec_execute_session() - execute session to the tee context + * @tee: context for tee vendor + * @cmd: tee invoke cmd id + * @timeout_ms: timeout ms to current tee invoke cmd + * + * Return: 0 for success; else the error code is returned + * + */ +int cmdq_sec_execute_session(struct cmdq_sec_tee_context *tee, u32 cmd, s32 timeout_ms); + +#else /* IS_ENABLED(CONFIG_TEE) */ + +static inline int cmdq_sec_init_context(struct cmdq_sec_tee_context *tee) +{ + return -EFAULT; +} + +static inline int cmdq_sec_deinit_context(struct cmdq_sec_tee_context *tee) +{ + return -EFAULT; +} + +static inline int cmdq_sec_allocate_wsm(struct cmdq_sec_tee_context *tee, + void **wsm_buffer, u32 size) +{ + return -EFAULT; +} + +static inline int cmdq_sec_free_wsm(struct cmdq_sec_tee_context *tee, void **wsm_buffer) +{ + return -EFAULT; +} + +static inline int cmdq_sec_open_session(struct cmdq_sec_tee_context *tee, void *wsm_buffer) +{ + return -EFAULT; +} + +static inline int cmdq_sec_close_session(struct cmdq_sec_tee_context *tee) +{ + return -EFAULT; +} + +static inline int cmdq_sec_execute_session(struct cmdq_sec_tee_context *tee, + u32 cmd, s32 timeout_ms) +{ + return -EFAULT; +} + +#endif /* IS_ENABLED(CONFIG_TEE) */ + +#endif /* __MTK_CMDQ_SEC_TEE_H__ */ -- GitLab From c2a488f8c67e8fc5bc3b0951da78e164a2d8548c Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 3 Apr 2024 18:26:01 +0800 Subject: [PATCH 259/456] CHROMIUM: mailbox: mediatek: Add secure CMDQ driver support for CMDQ driver CMDQ driver will probe a secure CMDQ driver when has_sec flag in platform data is true and its device node in dts has defined a event id of CMDQ_SYNC_TOKEN_SEC_EOF. Secure CMDQ driver support on mt8188 and mt8195 currently. So add a has_secure flag to their driver data to probe it. Signed-off-by: Jason-JH.Lin Signed-off-by: Hsiao Chien Sung (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240526144443.14345-8-jason-jh.lin@mediatek.com/) Conflicts: drivers/mailbox/mtk-cmdq-mailbox.c conflict with CL:6108927 Add driver data to support for MT8196 BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Change-Id: I5562d8a23c7ce323ca0f96ce53727c109bb156a2 Signed-off-by: Hsiao Chien Sung Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5172079 Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073700 Reviewed-by: Pin-yen Lin Reviewed-by: Hsin-Te Yuan Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/mailbox/mtk-cmdq-mailbox.c | 76 +++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 6ed0a0d420443..61b24219ab81c 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -15,7 +15,8 @@ #include #include #include -#include +#include +#include #define CMDQ_MBOX_AUTOSUSPEND_DELAY_MS 100 @@ -66,6 +67,13 @@ #define CMDQ_JUMP_BY_OFFSET 0x10000000 #define CMDQ_JUMP_BY_PA 0x10000001 +#define CMDQ_THR_IDX(thread, cmdq) (((thread)->base - (cmdq)->base - CMDQ_THR_BASE) \ + / CMDQ_THR_SIZE) + +#define CMDQ_IS_SECURE_THREAD(idx, cmdq) ((idx) >= (cmdq)->pdata->secure_thread_min && \ + (idx) < (cmdq)->pdata->secure_thread_min + \ + (cmdq)->pdata->secure_thread_nr) + struct gce_plat { u32 thread_nr; u8 shift; @@ -74,6 +82,8 @@ struct gce_plat { bool sw_ddr_en; bool gce_vm; u32 dma_mask_bit; + u32 secure_thread_nr; + u32 secure_thread_min; u32 gce_num; }; @@ -428,6 +438,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); struct cmdq_task *task; unsigned long curr_pa, end_pa; + u32 idx = CMDQ_THR_IDX(thread, cmdq); int ret; /* Client should not flush new tasks if suspended. */ @@ -437,6 +448,13 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) if (ret < 0) return ret; + if (CMDQ_IS_SECURE_THREAD(idx, cmdq)) { + ret = cmdq_sec_mbox.ops->send_data(chan, data); + pm_runtime_mark_last_busy(cmdq->mbox.dev); + pm_runtime_put_autosuspend(cmdq->mbox.dev); + return ret; + } + task = kzalloc(sizeof(*task), GFP_ATOMIC); if (!task) return -ENOMEM; @@ -493,6 +511,13 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) static int cmdq_mbox_startup(struct mbox_chan *chan) { + struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); + struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv; + u32 idx = CMDQ_THR_IDX(thread, cmdq); + + if (CMDQ_IS_SECURE_THREAD(idx, cmdq)) + cmdq_sec_mbox.ops->startup(chan); + return 0; } @@ -502,9 +527,17 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan) struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); struct cmdq_task *task, *tmp; unsigned long flags; + u32 idx = CMDQ_THR_IDX(thread, cmdq); WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev) < 0); + if (CMDQ_IS_SECURE_THREAD(idx, cmdq)) { + cmdq_sec_mbox.ops->shutdown(chan); + pm_runtime_mark_last_busy(cmdq->mbox.dev); + pm_runtime_put_autosuspend(cmdq->mbox.dev); + return; + } + spin_lock_irqsave(&thread->chan->lock, flags); if (list_empty(&thread->task_busy_list)) goto done; @@ -544,8 +577,17 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) struct cmdq_task *task, *tmp; unsigned long flags; u32 enable; + u32 idx = CMDQ_THR_IDX(thread, cmdq); int ret; + if (CMDQ_IS_SECURE_THREAD(idx, cmdq)) { + /* + * secure mbox_flush will be called inside the + * cmdq_sec_mbox.ops->send_data(chan); + */ + return 0; + } + ret = pm_runtime_get_sync(cmdq->mbox.dev); if (ret < 0) return ret; @@ -640,6 +682,8 @@ static int cmdq_probe(struct platform_device *pdev) int alias_id = 0; static const char * const clk_name = "gce"; static const char * const clk_names[] = { "gce0", "gce1" }; + static struct gce_sec_plat sec_plat = {0}; + u32 hwid = 0; cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL); if (!cmdq) @@ -665,6 +709,8 @@ static int cmdq_probe(struct platform_device *pdev) dev, cmdq->base, cmdq->irq); if (cmdq->pdata->gce_num > 1) { + hwid = of_alias_get_id(dev->of_node, clk_name); + for_each_child_of_node(phandle->parent, node) { alias_id = of_alias_get_id(node, clk_name); if (alias_id >= 0 && alias_id < cmdq->pdata->gce_num) { @@ -750,6 +796,28 @@ static int cmdq_probe(struct platform_device *pdev) return err; } + if (of_property_read_u32_index(dev->of_node, "mediatek,gce-events", 0, + &sec_plat.cmdq_event) == 0) { + struct platform_device *cmdq_sec; + + sec_plat.mbox = &cmdq->mbox; + sec_plat.base = cmdq->base; + sec_plat.hwid = hwid; + sec_plat.secure_thread_nr = cmdq->pdata->secure_thread_nr; + sec_plat.secure_thread_min = cmdq->pdata->secure_thread_min; + sec_plat.shift = cmdq->pdata->shift; + sec_plat.mminfra_offset = cmdq->pdata->mminfra_offset; + + cmdq_sec = platform_device_register_data(dev, "mtk-cmdq-sec", + PLATFORM_DEVID_AUTO, + &sec_plat, + sizeof(sec_plat)); + if (IS_ERR(cmdq_sec)) { + dev_err(dev, "failed to register platform_device mtk-cmdq-sec\n"); + return PTR_ERR(cmdq_sec); + } + } + return 0; } @@ -793,6 +861,8 @@ static const struct gce_plat gce_plat_mt8188 = { .thread_nr = 32, .shift = 3, .control_by_sw = true, + .secure_thread_nr = 2, + .secure_thread_min = 8, .gce_num = 2 }; @@ -807,6 +877,8 @@ static const struct gce_plat gce_plat_mt8195 = { .thread_nr = 24, .shift = 3, .control_by_sw = true, + .secure_thread_nr = 2, + .secure_thread_min = 8, .gce_num = 2 }; @@ -818,6 +890,8 @@ static const struct gce_plat gce_plat_mt8196 = { .sw_ddr_en = true, .gce_vm = true, .dma_mask_bit = 35, + .secure_thread_nr = 3, + .secure_thread_min = 8, .gce_num = 2 }; -- GitLab From ed5dbced978293d513c1e361af775513a42bd19e Mon Sep 17 00:00:00 2001 From: "Jason-JH.Lin" Date: Wed, 22 May 2024 02:15:58 +0800 Subject: [PATCH 260/456] CHROMIUM: soc: mediatek: mtk-cmdq: Add secure cmdq_pkt APIs Open secure cmdq_pkt APIs to support executing commands in secure world 1. Add cmdq_sec_pkt_alloc_sec_data(), cmdq_sec_pkt_free_sec_data() and cmdq_sec_pkt_set_data() to prepare the sec_data in cmdq_pkt that will be referenced in the secure world. 2. Add cmdq_sec_insert_backup_cookie() and cmdq_sec_pkt_write() to generate commands that need to be executed in the secure world. In cmdq_sec_pkt_write(), we need to prepare the metadata to store buffer offset of the secure buffer handle because secure world can only translate the start address of secure buffer by secure handle. Signed-off-by: Jason-JH.Lin Signed-off-by: Hsiao Chien Sung (am from https://patchwork.kernel.org/project/linux-mediatek/patch/20240526144443.14345-9-jason-jh.lin@mediatek.com/) Conflicts: drivers/soc/mediatek/mtk-cmdq-helper.c conflict with CL:5607585 Fix addr_metadata list missing error BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Change-Id: I444d646c1f4cb698bbb9a199df2dc15ccc4185d5 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5452815 Reviewed-by: Sean Paul Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073701 Reviewed-by: Hsin-Te Yuan Reviewed-by: Chen-Yu Tsai Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-cmdq-helper.c | 116 +++++++++++++++++++++++++ include/linux/soc/mediatek/mtk-cmdq.h | 58 +++++++++++++ 2 files changed, 174 insertions(+) diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 4cab5158409f5..f9d53fa860f42 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -587,4 +587,120 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt) } EXPORT_SYMBOL(cmdq_pkt_finalize); +int cmdq_sec_insert_backup_cookie(struct cmdq_pkt *pkt) +{ + struct cmdq_client *cl = (struct cmdq_client *)pkt->cl; + struct cmdq_operand left, right; + struct device *dev; + dma_addr_t addr; + + if (!cl) { + pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__); + return -EINVAL; + } + dev = cl->chan->mbox->dev; + + addr = cmdq_sec_get_exec_cnt_addr(cl->chan); + if (addr == 0) { + dev_err(dev, "%s %d: failed to get exec cnt addr!\n", + __func__, __LINE__); + return -EINVAL; + } + + cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX1, CMDQ_ADDR_HIGH(addr)); + cmdq_pkt_read_s(pkt, CMDQ_THR_SPR_IDX1, CMDQ_ADDR_LOW(addr), CMDQ_THR_SPR_IDX1); + + left.reg = true; + left.idx = CMDQ_THR_SPR_IDX1; + right.reg = false; + right.value = 1; + cmdq_pkt_logic_command(pkt, CMDQ_THR_SPR_IDX1, &left, CMDQ_LOGIC_ADD, &right); + + addr = cmdq_sec_get_cookie_addr(cl->chan) + cmdq_get_offset_pa(cl->chan); + if (addr == 0) { + dev_err(dev, "%s %d: failed to get cookie addr!\n", + __func__, __LINE__); + return -EINVAL; + } + + cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX2, CMDQ_ADDR_HIGH(addr)); + cmdq_pkt_write_s(pkt, CMDQ_THR_SPR_IDX2, CMDQ_ADDR_LOW(addr), CMDQ_THR_SPR_IDX1); + cmdq_pkt_set_event(pkt, cmdq_sec_get_eof_event_id(cl->chan)); + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_insert_backup_cookie); + +void cmdq_sec_pkt_free_sec_data(struct cmdq_pkt *pkt) +{ + kfree(pkt->sec_data); +} +EXPORT_SYMBOL_GPL(cmdq_sec_pkt_free_sec_data); + +int cmdq_sec_pkt_alloc_sec_data(struct cmdq_pkt *pkt) +{ + struct cmdq_sec_data *sec_data; + + if (pkt->sec_data) { + memset(pkt->sec_data, 0, sizeof(struct cmdq_sec_data)); + return 0; + } + + sec_data = kzalloc(sizeof(*sec_data), GFP_KERNEL); + if (!sec_data) + return -ENOMEM; + + pkt->sec_data = (void *)sec_data; + + return 0; +} +EXPORT_SYMBOL_GPL(cmdq_sec_pkt_alloc_sec_data); + +static int cmdq_sec_append_metadata(struct cmdq_pkt *pkt, + const enum cmdq_iwc_addr_metadata_type type, + const u32 base, const u32 offset) +{ + struct cmdq_client *cl = (struct cmdq_client *)pkt->cl; + struct device *dev = cl->chan->mbox->dev; + struct cmdq_sec_data *sec_data; + int idx; + + dev_dbg(dev, "[%s %d] pkt:%p type:%u base:%#x offset:%#x", + __func__, __LINE__, pkt, type, base, offset); + + if (!pkt->sec_data) { + dev_err(dev, "[%s %d] no sec_data\n", __func__, __LINE__); + return -ENOMEM; + } + + sec_data = (struct cmdq_sec_data *)pkt->sec_data; + idx = sec_data->meta_cnt; + if (idx >= CMDQ_IWC_MAX_ADDR_LIST_LENGTH) { + dev_err(dev, "idx:%u reach over:%u", idx, CMDQ_IWC_MAX_ADDR_LIST_LENGTH); + return -EFAULT; + } + + sec_data->meta_list[idx].type = type; + sec_data->meta_list[idx].base_handle = base; + sec_data->meta_list[idx].offset = offset; + sec_data->meta_cnt += 1; + + return 0; +} + +int cmdq_sec_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base, u16 offset, + enum cmdq_iwc_addr_metadata_type type, + u32 base, u32 base_offset) +{ + if (subsys != CMDQ_SUBSYS_INVALID) + cmdq_pkt_write(pkt, subsys, offset, base); + else { + cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base)); + cmdq_pkt_write_s_value(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(offset), base); + } + + return cmdq_sec_append_metadata(pkt, type, base, base_offset); +} +EXPORT_SYMBOL_GPL(cmdq_sec_pkt_write); + MODULE_LICENSE("GPL v2"); diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h index 3a246d538d4fd..8002e05e8140c 100644 --- a/include/linux/soc/mediatek/mtk-cmdq.h +++ b/include/linux/soc/mediatek/mtk-cmdq.h @@ -9,6 +9,7 @@ #include #include +#include #include #define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0))) @@ -402,6 +403,44 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt); */ int cmdq_pkt_finalize(struct cmdq_pkt *pkt); +/** + * cmdq_sec_pkt_free_sec_data() - free sec_data for CMDQ packet. + * @pkt: the CMDQ packet. + */ +void cmdq_sec_pkt_free_sec_data(struct cmdq_pkt *pkt); + +/** + * cmdq_sec_pkt_alloc_sec_data() - allocate sec_data for CMDQ packet. + * @pkt: the CMDQ packet. + * + * Return: 0 for success; else the error code is returned + */ +int cmdq_sec_pkt_alloc_sec_data(struct cmdq_pkt *pkt); + +/** + * cmdq_sec_insert_backup_cookie() - append backup cookie related instructions. + * @pkt: the CMDQ packet. + * + * Return: 0 for success; else the error code is returned + */ +int cmdq_sec_insert_backup_cookie(struct cmdq_pkt *pkt); + +/** + * cmdq_sec_pkt_write() - append write secure buffer related instructions. + * @pkt: the CMDQ packet. + * @subsys: the CMDQ sub system code. + * @pa_base: the physical address base of secure buffer. + * @offset: register offset from CMDQ sub system. + * @type: the address metadata conversion type. + * @base: the secure handle of secure buffer. + * @base_offset:the address offset of secure buffer. + * + * Return: 0 for success; else the error code is returned + */ +int cmdq_sec_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base, u16 offset, + enum cmdq_iwc_addr_metadata_type type, + u32 base, u32 base_offset); + #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */ static inline int cmdq_dev_get_client_reg(struct device *dev, @@ -527,6 +566,25 @@ static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt) return -EINVAL; } +static inline void cmdq_sec_pkt_free_sec_data(struct cmdq_pkt *pkt) {} + +static inline int cmdq_sec_pkt_alloc_sec_data(struct cmdq_pkt *pkt) +{ + return -EINVAL; +} + +static inline int cmdq_sec_insert_backup_cookie(struct cmdq_pkt *pkt) +{ + return -EINVAL; +} + +static inline int cmdq_sec_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base, u16 offset, + enum cmdq_iwc_addr_metadata_type type, + u32 base, u32 base_offset) +{ + return -EINVAL; +} + #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */ #endif /* __MTK_CMDQ_H__ */ -- GitLab From 0f0a43f25a48ad860cb4131fa6259588c557285c Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 26 Nov 2024 10:55:07 +0800 Subject: [PATCH 261/456] FROMLIST: usb: mtk-xhci: add support remote wakeup of mt8196 There are 2 USB controllers on mt8196, each controller's wakeup control is different, add some specific versions for them. Signed-off-by: Chunfeng Yun (am from https://patchwork.kernel.org/patch/13885450/) (also found at https://lore.kernel.org/r/20241126025507.29605-2-chunfeng.yun@mediatek.com) BUG=b:357046538 TEST=emerge-rauru sys-kernel/chromeo-kernel-6_6 UPSTREAM-TASK=b:387403117 Change-Id: I9bd43f501e111f6a676316d17bec2488cc9449d4 Signed-off-by: Liu Liu Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073710 Reviewed-by: Hsin-Te Yuan Reviewed-by: Chen-Yu Tsai Reviewed-by: Sean Paul Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/usb/host/xhci-mtk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 3252e3d2d79cd..31223912b0b47 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -113,6 +113,12 @@ #define WC1_IS_P_95 BIT(12) #define WC1_IS_EN_P0_95 BIT(6) +/* mt8196 */ +#define PERI_WK_CTRL0_8196 0x08 +#define UWK_V1_7_CTRL2_MASK 0x5 + +#define WCP1_IS_EN BIT(7) /* port1 en bit */ + /* mt2712 etc */ #define PERI_SSUSB_SPM_CTRL 0x0 #define SSC_IP_SLEEP_EN BIT(4) @@ -129,6 +135,8 @@ enum ssusb_uwk_vers { SSUSB_UWK_V1_4, /* mt8195 IP1 */ SSUSB_UWK_V1_5, /* mt8195 IP2 */ SSUSB_UWK_V1_6, /* mt8195 IP3 */ + SSUSB_UWK_V1_7, /* mt8196 IP0 */ + SSUSB_UWK_V1_8, /* mt8196 IP1 */ }; /* @@ -381,6 +389,16 @@ static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable) msk = WC0_IS_EN_P3_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95; val = enable ? (WC0_IS_EN_P3_95 | WC0_IS_C_95(0x1)) : 0; break; + case SSUSB_UWK_V1_7: + reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8196; + msk = UWK_V1_7_CTRL2_MASK; + val = enable ? msk : 0; + break; + case SSUSB_UWK_V1_8: + reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8196; + msk = WCP1_IS_EN; + val = enable ? msk : 0; + break; case SSUSB_UWK_V2: reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL; msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN; -- GitLab From 3369a89659a69de608823002b59a094e13fcb051 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 26 Nov 2024 10:58:59 +0800 Subject: [PATCH 262/456] FROMLIST: phy: mediatek: xsphy: add support to set disconnect threshold Add a property to tune usb2 phy's disconnect threshold. Signed-off-by: Chunfeng Yun (am from https://patchwork.kernel.org/patch/13885460/) (also found at https://lore.kernel.org/r/20241126025859.29923-2-chunfeng.yun@mediatek.com) BUG=b:364480848 TEST=emerge-rauru sys-kernel/chromeo-kernel-6_6 UPSTREAM-TASK=b:387403117 Change-Id: I431ce673977d1f3491527532baff0aa7d7d6ce15 Signed-off-by: Liu Liu Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073711 Reviewed-by: Sean Paul Reviewed-by: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/phy/mediatek/phy-mtk-xsphy.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c index b222fbbd71d18..8b46223b510c3 100644 --- a/drivers/phy/mediatek/phy-mtk-xsphy.c +++ b/drivers/phy/mediatek/phy-mtk-xsphy.c @@ -59,6 +59,7 @@ #define XSP_USBPHYACR6 ((SSUSB_SIFSLV_U2PHY_COM) + 0x018) #define P2A6_RG_BC11_SW_EN BIT(23) #define P2A6_RG_OTG_VBUSCMP_EN BIT(20) +#define PA6_RG_U2_DISCTH GENMASK(7, 4) #define XSP_U2PHYDTM1 ((SSUSB_SIFSLV_U2PHY_COM) + 0x06C) #define P2D_FORCE_IDDIG BIT(9) @@ -95,6 +96,7 @@ struct xsphy_instance { int eye_src; int eye_vrt; int eye_term; + int discth; }; struct mtk_xsphy { @@ -244,9 +246,12 @@ static void phy_parse_property(struct mtk_xsphy *xsphy, &inst->eye_vrt); device_property_read_u32(dev, "mediatek,eye-term", &inst->eye_term); - dev_dbg(dev, "intr:%d, src:%d, vrt:%d, term:%d\n", + device_property_read_u32(dev, "mediatek,discth", + &inst->discth); + dev_dbg(dev, "intr:%d, src:%d, vrt:%d, term:%d, discth:%d\n", inst->efuse_intr, inst->eye_src, - inst->eye_vrt, inst->eye_term); + inst->eye_vrt, inst->eye_term, + inst->discth); break; case PHY_TYPE_USB3: device_property_read_u32(dev, "mediatek,efuse-intr", @@ -285,6 +290,9 @@ static void u2_phy_props_set(struct mtk_xsphy *xsphy, if (inst->eye_term) mtk_phy_update_field(pbase + XSP_USBPHYACR1, P2A1_RG_TERM_SEL, inst->eye_term); + if (inst->discth) + mtk_phy_update_field(pbase + XSP_USBPHYACR6, PA6_RG_U2_DISCTH, + inst->discth); } static void u3_phy_props_set(struct mtk_xsphy *xsphy, -- GitLab From 59195e148651dce528d6798905fff39a6613e7cd Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Fri, 29 Nov 2024 12:15:14 +0000 Subject: [PATCH 263/456] CHROMIUM: Build SVS as module On MT8183, SVS relies on mali gpu being powered on. However, mali doesn't support runtime PM on MT8183. Hence, it's impossible to guarantee that SVS can be probed successfully. Currently, build as module luckily makes SVS get probed successfully, so we decided to do so as workaround. BUG=b:360282314 TEST=SVS get probed successfully on MT8183, MT8186 and MT8195 Change-Id: Ic3cb7e4955184a533463936dbbead394b833bb2f Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6055963 Commit-Queue: Pin-yen Lin Reviewed-by: Pin-yen Lin Signed-off-by: Hubert Mazur --- .../config/chromeos/arm64/chromiumos-mediatek.flavour.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config index 066dc84a34695..b1284ecb4193a 100644 --- a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config +++ b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config @@ -75,7 +75,7 @@ CONFIG_MTK_PMIC_WRAP=y CONFIG_MTK_SCP=m CONFIG_MTK_SENINF=m CONFIG_MTK_SOC_THERMAL=y -CONFIG_MTK_SVS=y +CONFIG_MTK_SVS=m CONFIG_MTK_THERMAL=y CONFIG_MWIFIEX_SDIO=m CONFIG_NVMEM_MTK_EFUSE=y -- GitLab From f781bf3503260cc278b5bbfd40c5cd021e1dafae Mon Sep 17 00:00:00 2001 From: "T.J. Mercier" Date: Sat, 20 Jul 2024 15:15:42 +0800 Subject: [PATCH 264/456] UPSTREAM: dma-buf: heaps: Deduplicate docs and adopt common format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docs for dma_heap_get_name were incorrect, and since they were duplicated in the header they were wrong there too. The docs formatting was inconsistent so I tried to make it more consistent across functions since I'm already in here doing cleanup. Remove multiple unused includes and alphabetize. Signed-off-by: T.J. Mercier Signed-off-by: Yong Wu [Yong: Just add a comment for "priv" to mute build warning] Signed-off-by: Yunfei Dong Link: https://patchwork.freedesktop.org/patch/msgid/20240720071606.27930-5-yunfei.dong@mediatek.com Signed-off-by: Christian König (cherry picked from commit d5e79eeba3086a52593b295ac4bf6eddd64d4aad) BUG=336924470 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Signed-off-by: Yunfei Dong Change-Id: I9d255f6fbef7a9f4fcc4a0eff4ab75dcc3bd67cf Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073909 Reviewed-by: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Reviewed-by: Yidi Lin Kcr-patch: 1cceb8c194605d7a2f430c53a41af07113f268608c977e0c74c19ce0.patch Signed-off-by: Hubert Mazur --- drivers/dma-buf/dma-heap.c | 30 ++++++++++++++++-------------- include/linux/dma-heap.h | 22 +--------------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index be74ed4020ae1..082a2a1b4b2a3 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -7,18 +7,16 @@ */ #include -#include #include #include +#include #include -#include #include -#include #include -#include -#include -#include #include +#include +#include +#include #include #include @@ -30,10 +28,10 @@ * struct dma_heap - represents a dmabuf heap in the system * @name: used for debugging/device-node name * @ops: ops struct for this heap - * @heap_devt heap device node - * @list list head connecting to list of heaps - * @heap_cdev heap char device - * @heap_dev heap device struct + * @priv: private data for this heap + * @heap_devt: heap device node + * @list: list head connecting to list of heaps + * @heap_cdev: heap char device * * Represents a heap of memory from which buffers can be made. */ @@ -239,11 +237,11 @@ static const struct file_operations dma_heap_fops = { }; /** - * dma_heap_get_drvdata() - get per-subdriver data for the heap + * dma_heap_get_drvdata - get per-heap driver data * @heap: DMA-Heap to retrieve private data for * * Returns: - * The per-subdriver data for the heap. + * The per-heap data for the heap. */ void *dma_heap_get_drvdata(struct dma_heap *heap) { @@ -292,8 +290,8 @@ struct device *dma_heap_get_dev(struct dma_heap *heap) EXPORT_SYMBOL_GPL(dma_heap_get_dev); /** - * dma_heap_get_name() - get heap name - * @heap: DMA-Heap to retrieve private data for + * dma_heap_get_name - get heap name + * @heap: DMA-Heap to retrieve the name of * * Returns: * The char* for the heap name. @@ -304,6 +302,10 @@ const char *dma_heap_get_name(struct dma_heap *heap) } EXPORT_SYMBOL_GPL(dma_heap_get_name); +/** + * dma_heap_add - adds a heap to dmabuf heaps + * @exp_info: information needed to register this heap + */ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) { struct dma_heap *heap, *h, *err_ret; diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h index e5cab27d239da..0001365514be0 100644 --- a/include/linux/dma-heap.h +++ b/include/linux/dma-heap.h @@ -9,15 +9,13 @@ #ifndef _DMA_HEAPS_H #define _DMA_HEAPS_H -#include #include struct dma_heap; /** * struct dma_heap_ops - ops to operate on a given heap - * @allocate: allocate dmabuf and return struct dma_buf ptr - * @get_pool_size: if heap maintains memory pools, get pool size in bytes + * @allocate: allocate dmabuf and return struct dma_buf ptr * * allocate returns dmabuf on success, ERR_PTR(-errno) on error. */ @@ -43,13 +41,6 @@ struct dma_heap_export_info { void *priv; }; -/** - * dma_heap_get_drvdata() - get per-heap driver data - * @heap: DMA-Heap to retrieve private data for - * - * Returns: - * The per-heap data for the heap. - */ void *dma_heap_get_drvdata(struct dma_heap *heap); /** @@ -61,19 +52,8 @@ void *dma_heap_get_drvdata(struct dma_heap *heap); */ struct device *dma_heap_get_dev(struct dma_heap *heap); -/** - * dma_heap_get_name() - get heap name - * @heap: DMA-Heap to retrieve private data for - * - * Returns: - * The char* for the heap name. - */ const char *dma_heap_get_name(struct dma_heap *heap); -/** - * dma_heap_add - adds a heap to dmabuf heaps - * @exp_info: information needed to register this heap - */ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info); /** -- GitLab From 9e912381132b6f31cfff1cc606ceb34923f320b3 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:20 +0800 Subject: [PATCH 265/456] FROMGIT: drm/bridge: it6505: improve AUX operation for edid read The original AUX operation using data registers is limited to 4 bytes. The AUX operation command CMD_AUX_I2C_EDID_READ uses AUX FIFO and is capable of reading 16 bytes. This improves the speed of EDID read. Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-2-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit d0c97a51cdef2badc8d17f6edfbc0bdc0ba92065 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I650121211d197ea7a7cb9c85c63a78a15201e591 Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151216 Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 62656d2980b72..5eba9c3137ba0 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -1085,10 +1085,13 @@ static ssize_t it6505_aux_do_transfer(struct it6505 *it6505, size_t size, enum aux_cmd_reply *reply) { int i, ret_size, ret = 0, request_size; + int fifo_max_size = (cmd == CMD_AUX_I2C_EDID_READ) ? AUX_FIFO_MAX_SIZE : 4; mutex_lock(&it6505->aux_lock); - for (i = 0; i < size; i += 4) { - request_size = min((int)size - i, 4); + i = 0; + do { + request_size = min_t(int, (int)size - i, fifo_max_size); + ret_size = it6505_aux_operation(it6505, cmd, address + i, buffer + i, request_size, reply); @@ -1097,8 +1100,9 @@ static ssize_t it6505_aux_do_transfer(struct it6505 *it6505, goto aux_op_err; } + i += request_size; ret += ret_size; - } + } while (i < size); aux_op_err: mutex_unlock(&it6505->aux_lock); -- GitLab From f95cd7fb7cefa25cb063a1ccd02bb7a7c0647c63 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:21 +0800 Subject: [PATCH 266/456] FROMGIT: drm/bridge: it6505: add AUX operation for HDCP KSV list read HDCP KSV list readback can choose to use AUX FIFO or general data register. For some DisplayPort devices, the KSV list must be read in 5 byte boundaries. The original AUX read command does not support these devices. The AUX command operation control register "REG_AUX_CMD_REQ" uses b[3:0] as AUX operacion control, and b[7:4] are status bits and read only. To change KSV read operation uses "CMD_AUX_NATIVE_READ" from using the data registers to using AUX FIFO. The extended command "CMD_AUX_GET_KSV_LIST" is added as "CMD_AUX_NATIVE_READ" with the 0x10 flag which selects AUX FIFO mode. Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-3-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 235d9bf8a1e1c0a0cf1340c40567e6b4f2b742c6 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I58080ab81fbe8f79a06c4bc42c0acf129603df30 Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151217 Reviewed-by: Sean Paul Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 5eba9c3137ba0..98c7a9fb9e2fa 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -127,6 +128,7 @@ #define REG_AUX_OUT_DATA0 0x27 #define REG_AUX_CMD_REQ 0x2B +#define M_AUX_REQ_CMD 0x0F #define AUX_BUSY BIT(5) #define REG_AUX_DATA_0_7 0x2C @@ -325,6 +327,9 @@ enum aux_cmd_type { CMD_AUX_NATIVE_READ = 0x0, CMD_AUX_NATIVE_WRITE = 0x5, CMD_AUX_I2C_EDID_READ = 0xB, + + /* KSV read with AUX FIFO extend from CMD_AUX_NATIVE_READ*/ + CMD_AUX_GET_KSV_LIST = 0x10, }; enum aux_cmd_reply { @@ -974,7 +979,8 @@ static ssize_t it6505_aux_operation(struct it6505 *it6505, it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, AUX_USER_MODE); aux_op_start: - if (cmd == CMD_AUX_I2C_EDID_READ) { + /* HW AUX FIFO supports only EDID and DCPD KSV FIFO area */ + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { /* AUX EDID FIFO has max length of AUX_FIFO_MAX_SIZE bytes. */ size = min_t(size_t, size, AUX_FIFO_MAX_SIZE); /* Enable AUX FIFO read back and clear FIFO */ @@ -1005,7 +1011,7 @@ aux_op_start: size); /* Aux Fire */ - it6505_write(it6505, REG_AUX_CMD_REQ, cmd); + it6505_write(it6505, REG_AUX_CMD_REQ, FIELD_GET(M_AUX_REQ_CMD, cmd)); ret = it6505_aux_wait(it6505); if (ret < 0) @@ -1039,7 +1045,7 @@ aux_op_start: goto aux_op_start; } - if (cmd == CMD_AUX_I2C_EDID_READ) { + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { for (i = 0; i < size; i++) { ret = it6505_read(it6505, REG_AUX_DATA_FIFO); if (ret < 0) @@ -1064,7 +1070,7 @@ aux_op_start: ret = i; aux_op_err: - if (cmd == CMD_AUX_I2C_EDID_READ) { + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { /* clear AUX FIFO */ it6505_set_bits(it6505, REG_AUX_CTRL, AUX_EN_FIFO_READ | CLR_EDID_FIFO, @@ -1085,7 +1091,8 @@ static ssize_t it6505_aux_do_transfer(struct it6505 *it6505, size_t size, enum aux_cmd_reply *reply) { int i, ret_size, ret = 0, request_size; - int fifo_max_size = (cmd == CMD_AUX_I2C_EDID_READ) ? AUX_FIFO_MAX_SIZE : 4; + int fifo_max_size = (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) ? + AUX_FIFO_MAX_SIZE : 4; mutex_lock(&it6505->aux_lock); i = 0; -- GitLab From e8b2529db1265aef6091f14ffcc72485068d4a60 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:22 +0800 Subject: [PATCH 267/456] FROMGIT: drm/bridge: it6505: Change definition MAX_HDCP_DOWN_STREAM_COUNT A HDCP source device shall support max downstream to 127 devices. Change definition MAX_HDCP_DOWN_STREAM_COUNT to 127 KSVs shall save for DRM blocked devices check. This results in struct it6505 growth by ~0.5 KiB. Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-4-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 85597bc0d70c287ba41f17d14d3d857a38a3d727 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I9b6e3bbb106218a861048fae093df24e1b418253 Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151218 Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 98c7a9fb9e2fa..a861853b1171b 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -299,7 +299,7 @@ #define MAX_LANE_COUNT 4 #define MAX_LINK_RATE HBR #define AUTO_TRAIN_RETRY 3 -#define MAX_HDCP_DOWN_STREAM_COUNT 10 +#define MAX_HDCP_DOWN_STREAM_COUNT 127 #define MAX_CR_LEVEL 0x03 #define MAX_EQ_LEVEL 0x03 #define AUX_WAIT_TIMEOUT_MS 15 -- GitLab From 50ca45cc959033b186e65e71c47f6c174a8f48b4 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:23 +0800 Subject: [PATCH 268/456] FROMGIT: drm/bridge: it6505: fix HDCP Bstatus check When HDCP is activated, a DisplayPort source receiving CP_IRQ from the sink shall check Bstatus from DPCD and process the corresponding value Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-5-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 0fd2ff47d8c207fa3173661de04bb9e8201c0ad2 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I2f1b820e1599ec15b094eaaf8eace8bd229f0df7 Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151219 Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index a861853b1171b..cfbbc9ccf2c23 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -2332,14 +2332,20 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector); if (dp_irq_vector & DP_CP_IRQ) { - it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, - HDCP_TRIGGER_CPIRQ); - bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS); if (bstatus < 0) return bstatus; DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus); + + /*Check BSTATUS when recive CP_IRQ */ + if (bstatus & DP_BSTATUS_R0_PRIME_READY && + it6505->hdcp_status == HDCP_AUTH_GOING) + it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, + HDCP_TRIGGER_CPIRQ); + else if (bstatus & (DP_BSTATUS_REAUTH_REQ | DP_BSTATUS_LINK_FAILURE) && + it6505->hdcp_status == HDCP_AUTH_DONE) + it6505_start_hdcp(it6505); } ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status); -- GitLab From 98392fce1c611a823f200a5f324121a92bdee042 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:24 +0800 Subject: [PATCH 269/456] FROMGIT: drm/bridge: it6505: fix HDCP encryption when R0 ready When starting HDCP authentication, HDCP encryption should be enabled when R0'is checked. Change encryption enables time at R0' ready. The hardware HDCP engine trigger is changed and the repeater KSV fails will restart HDCP. Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-6-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 8c01b0bae2f9e58f2fee0e811cb90d8331986554 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I8a9614257d369bceb83f86ddd870ac476be5ee0b Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151220 Reviewed-by: Sean Paul Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index cfbbc9ccf2c23..522937994bcd8 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -2101,15 +2101,12 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505); DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s", ksv_list_check ? "pass" : "fail"); - if (ksv_list_check) { - it6505_set_bits(it6505, REG_HDCP_TRIGGER, - HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); + + if (ksv_list_check) return; - } + timeout: - it6505_set_bits(it6505, REG_HDCP_TRIGGER, - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL, - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL); + it6505_start_hdcp(it6505); } static void it6505_hdcp_work(struct work_struct *work) @@ -2482,7 +2479,11 @@ static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505) { struct device *dev = it6505->dev; - DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt"); + DRM_DEV_DEBUG_DRIVER(dev, "HDCP repeater R0 event Interrupt"); + /* 1B01 HDCP encription should start when R0 is ready*/ + it6505_set_bits(it6505, REG_HDCP_TRIGGER, + HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); + schedule_work(&it6505->hdcp_wait_ksv_list); } -- GitLab From 78c322514891404833c5cb4ff618db7f93d6d92b Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:25 +0800 Subject: [PATCH 270/456] FROMGIT: drm/bridge: it6505: fix HDCP CTS KSV list read with UNIGRAF DPR-100. When running the HDCP CTS test with UNIGRAF DPR-100. KSV list must be read from DP_AUX_HDCP_KSV_FIFO in an AUX request, and can not separate with multiple read requests. The AUX operation command "CMD_AUX_GET_KSV_LIST" reads the KSV list with AUX FIFO and is able to read DP_AUX_HDCP_KSV_FIFO in an AUX request. Add it6505_get_ksvlist() which uses CMD_AUX_GET_KSV_LIST operation to read the KSV list. Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-7-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit aa97239300e3f2a9ecbccf7ebfa240860bdddafb https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-next) BUG=b:369468872 TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 Change-Id: I48616ad3739787dcb3a7f121c44214b83b9d7c76 Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151221 Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 48 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 522937994bcd8..6ea33b857a95b 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -1198,6 +1198,37 @@ static int it6505_get_edid_block(void *data, u8 *buf, unsigned int block, return 0; } +static int it6505_get_ksvlist(struct it6505 *it6505, u8 *buf, size_t len) +{ + struct device *dev = it6505->dev; + enum aux_cmd_reply reply; + int request_size, ret; + int i = 0; + + do { + request_size = min_t(int, (int)len - i, 15); + + ret = it6505_aux_do_transfer(it6505, CMD_AUX_GET_KSV_LIST, + DP_AUX_HDCP_KSV_FIFO, + buf + i, request_size, &reply); + + DRM_DEV_DEBUG_DRIVER(dev, "request_size = %d, ret =%d", request_size, ret); + if (ret < 0) + return ret; + + i += request_size; + } while (i < len); + + DRM_DEV_DEBUG_DRIVER(dev, "ksv read cnt = %d down_stream_cnt=%d ", i, i / 5); + + for (i = 0 ; i < len; i += 5) { + DRM_DEV_DEBUG_DRIVER(dev, "ksv[%d] = %02X%02X%02X%02X%02X", + i / 5, buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4]); + } + + return len; +} + static void it6505_variable_config(struct it6505 *it6505) { it6505->link_rate_bw_code = HBR; @@ -1979,7 +2010,7 @@ static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input) { struct device *dev = it6505->dev; u8 binfo[2]; - int down_stream_count, i, err, msg_count = 0; + int down_stream_count, err, msg_count = 0; err = it6505_get_dpcd(it6505, DP_AUX_HDCP_BINFO, binfo, ARRAY_SIZE(binfo)); @@ -2004,18 +2035,11 @@ static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input) down_stream_count); return 0; } + err = it6505_get_ksvlist(it6505, sha1_input, down_stream_count * 5); + if (err < 0) + return err; - for (i = 0; i < down_stream_count; i++) { - err = it6505_get_dpcd(it6505, DP_AUX_HDCP_KSV_FIFO + - (i % 3) * DRM_HDCP_KSV_LEN, - sha1_input + msg_count, - DRM_HDCP_KSV_LEN); - - if (err < 0) - return err; - - msg_count += 5; - } + msg_count += down_stream_count * 5; it6505->hdcp_down_stream_count = down_stream_count; sha1_input[msg_count++] = binfo[0]; -- GitLab From 1cc11e939455d74f8c34b0696417e0beaa769406 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:26 +0800 Subject: [PATCH 271/456] FROMGIT: drm/bridge: it6505: fix HDCP CTS compare V matching When HDCP negotiation with a repeater device. Checking SHA V' matching must retry 3 times before restarting HDCP. Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-8-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 0989c02c7a5c887c70afeae80c64d0291624e1a7 https://gitlab.freedesktop.org/drm/misc/kernel drm-misc-next) BUG=b:369468872 TEST=Update kernel and check display is ok Change-Id: I78f61ee45e00c5c3741e61a5313387af2955ebd2 Signed-off-by: Hermes Wu Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151222 Reviewed-by: Hsin-Te Yuan Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 32 +++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 6ea33b857a95b..744a561de0ec7 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -2067,7 +2067,7 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) { struct device *dev = it6505->dev; u8 av[5][4], bv[5][4]; - int i, err; + int i, err, retry; i = it6505_setup_sha1_input(it6505, it6505->sha1_input); if (i <= 0) { @@ -2076,22 +2076,28 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) } it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av); + /*1B-05 V' must retry 3 times */ + for (retry = 0; retry < 3; retry++) { + err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, + sizeof(bv)); - err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, - sizeof(bv)); + if (err < 0) { + dev_err(dev, "Read V' value Fail %d", retry); + continue; + } - if (err < 0) { - dev_err(dev, "Read V' value Fail"); - return false; - } + for (i = 0; i < 5; i++) { + if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || + av[i][1] != av[i][2] || bv[i][0] != av[i][3]) + break; - for (i = 0; i < 5; i++) - if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || - bv[i][1] != av[i][2] || bv[i][0] != av[i][3]) - return false; + DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d, %d", retry, i); + return true; + } + } - DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!"); - return true; + DRM_DEV_DEBUG_DRIVER(dev, "V' NOT match!! %d", retry); + return false; } static void it6505_hdcp_wait_ksv_list(struct work_struct *work) -- GitLab From fc57ad2d4791b1b81e03fd985ae938805350d115 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:27 +0800 Subject: [PATCH 272/456] FROMGIT: drm/bridge: it6505: fix HDCP CTS KSV list wait timer HDCP must disabled encryption and restart authentication after waiting KSV for 5s. The original method uses a counter in a waitting loop that may wait much longer than it is supposed to. Use time_after() for KSV wait timeout. Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-9-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 9f9eef9ec1a2b57d95a86fe81df758e8253a7766 https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-next) BUG=b:369468872 TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 Change-Id: Id94b40db59a38d43ac54015d3ce885db55c5215f Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151223 Reviewed-by: Sean Paul Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 744a561de0ec7..5fec3d5f2d7cc 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -2105,12 +2105,13 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) struct it6505 *it6505 = container_of(work, struct it6505, hdcp_wait_ksv_list); struct device *dev = it6505->dev; - unsigned int timeout = 5000; - u8 bstatus = 0; + u8 bstatus; bool ksv_list_check; + /* 1B-04 wait ksv list for 5s */ + unsigned long timeout = jiffies + + msecs_to_jiffies(5000) + 1; - timeout /= 20; - while (timeout > 0) { + for (;;) { if (!it6505_get_sink_hpd_status(it6505)) return; @@ -2119,13 +2120,12 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) if (bstatus & DP_BSTATUS_READY) break; - msleep(20); - timeout--; - } + if (time_after(jiffies, timeout)) { + DRM_DEV_DEBUG_DRIVER(dev, "KSV list wait timeout"); + goto timeout; + } - if (timeout == 0) { - DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed"); - goto timeout; + msleep(20); } ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505); -- GitLab From 147352be13c146c308c4e9eebfbb56ce54c6a999 Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Mon, 30 Dec 2024 18:51:28 +0800 Subject: [PATCH 273/456] FROMGIT: drm/bridge: it6505: add I2C functionality on AUX DisplayPort AUX protocol supports I2C transport which is capable of reading EDID or supports MCCS. In drm_dp_helper, drm_dp_i2c_xfer() packs I2C requests into a sequence of AUX requests. it6505_aux_i2c_operation() is implemented to match drm_dp_i2c_xfer() operactions. it6505_aux_i2c_transfer() adds I2C functionality for it6505_aux_transfer(). Reviewed-by: Dmitry Baryshkov Signed-off-by: Hermes Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20241230-v7-upstream-v7-10-e0fdd4844703@ite.corp-partner.google.com (cherry picked from commit 041d61ad66ea0d88890264e96e8f81437a33a9cf https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-next) BUG=b:369468872 TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 Change-Id: Id7480662df28ccff19d75f1f625d35dfa1ff6ecf Signed-off-by: Pin-yen Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151224 Reviewed-by: Sean Paul Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/gpu/drm/bridge/ite-it6505.c | 177 +++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 5fec3d5f2d7cc..5a19cb1daafbc 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -269,6 +269,18 @@ #define REG_SSC_CTRL1 0x189 #define REG_SSC_CTRL2 0x18A +#define REG_AUX_USER_CTRL 0x190 +#define EN_USER_AUX BIT(0) +#define USER_AUX_DONE BIT(1) +#define AUX_EVENT BIT(4) + +#define REG_AUX_USER_DATA_REC 0x191 +#define M_AUX_IN_REC 0xF0 +#define M_AUX_OUT_REC 0x0F + +#define REG_AUX_USER_REPLY 0x19A +#define REG_AUX_USER_RXB(n) (n + 0x19B) + #define RBR DP_LINK_BW_1_62 #define HBR DP_LINK_BW_2_7 #define HBR2 DP_LINK_BW_5_4 @@ -304,6 +316,8 @@ #define MAX_EQ_LEVEL 0x03 #define AUX_WAIT_TIMEOUT_MS 15 #define AUX_FIFO_MAX_SIZE 16 +#define AUX_I2C_MAX_SIZE 4 +#define AUX_I2C_DEFER_RETRY 4 #define PIXEL_CLK_DELAY 1 #define PIXEL_CLK_INVERSE 0 #define ADJUST_PHASE_THRESHOLD 80000 @@ -326,7 +340,12 @@ enum aux_cmd_type { CMD_AUX_NATIVE_READ = 0x0, CMD_AUX_NATIVE_WRITE = 0x5, + CMD_AUX_GI2C_ADR = 0x08, + CMD_AUX_GI2C_READ = 0x09, + CMD_AUX_GI2C_WRITE = 0x0A, CMD_AUX_I2C_EDID_READ = 0xB, + CMD_AUX_I2C_READ = 0x0D, + CMD_AUX_I2C_WRITE = 0x0C, /* KSV read with AUX FIFO extend from CMD_AUX_NATIVE_READ*/ CMD_AUX_GET_KSV_LIST = 0x10, @@ -1116,6 +1135,161 @@ aux_op_err: return ret; } +static bool it6505_aux_i2c_reply_defer(u8 reply) +{ + if (reply == DP_AUX_NATIVE_REPLY_DEFER || reply == DP_AUX_I2C_REPLY_DEFER) + return true; + return false; +} + +static bool it6505_aux_i2c_reply_nack(u8 reply) +{ + if (reply == DP_AUX_NATIVE_REPLY_NACK || reply == DP_AUX_I2C_REPLY_NACK) + return true; + return false; +} + +static int it6505_aux_i2c_wait(struct it6505 *it6505, u8 *reply) +{ + int err = 0; + unsigned long timeout; + struct device *dev = it6505->dev; + + timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1; + + do { + if (it6505_read(it6505, REG_AUX_USER_CTRL) & AUX_EVENT) + break; + if (time_after(jiffies, timeout)) { + dev_err(dev, "Timed out waiting AUX I2C, BUSY = %X\n", + it6505_aux_op_finished(it6505)); + err = -ETIMEDOUT; + goto end_aux_i2c_wait; + } + usleep_range(300, 800); + } while (!it6505_aux_op_finished(it6505)); + + *reply = it6505_read(it6505, REG_AUX_USER_REPLY) >> 4; + + if (*reply == 0) + goto end_aux_i2c_wait; + + if (it6505_aux_i2c_reply_defer(*reply)) + err = -EBUSY; + else if (it6505_aux_i2c_reply_nack(*reply)) + err = -ENXIO; + +end_aux_i2c_wait: + it6505_set_bits(it6505, REG_AUX_USER_CTRL, USER_AUX_DONE, USER_AUX_DONE); + return err; +} + +static int it6505_aux_i2c_readb(struct it6505 *it6505, u8 *buf, size_t size, u8 *reply) +{ + int ret, i; + int retry; + + for (retry = 0; retry < AUX_I2C_DEFER_RETRY; retry++) { + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_READ); + + ret = it6505_aux_i2c_wait(it6505, reply); + if (it6505_aux_i2c_reply_defer(*reply)) + continue; + if (ret >= 0) + break; + } + + for (i = 0; i < size; i++) + buf[i] = it6505_read(it6505, REG_AUX_USER_RXB(0 + i)); + + return size; +} + +static int it6505_aux_i2c_writeb(struct it6505 *it6505, u8 *buf, size_t size, u8 *reply) +{ + int i, ret; + int retry; + + for (i = 0; i < size; i++) + it6505_write(it6505, REG_AUX_OUT_DATA0 + i, buf[i]); + + for (retry = 0; retry < AUX_I2C_DEFER_RETRY; retry++) { + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_WRITE); + + ret = it6505_aux_i2c_wait(it6505, reply); + if (it6505_aux_i2c_reply_defer(*reply)) + continue; + if (ret >= 0) + break; + } + return size; +} + +static ssize_t it6505_aux_i2c_operation(struct it6505 *it6505, + struct drm_dp_aux_msg *msg) +{ + int ret; + ssize_t request_size, data_cnt = 0; + u8 *buffer = msg->buffer; + + /* set AUX user mode */ + it6505_set_bits(it6505, REG_AUX_CTRL, + AUX_USER_MODE | AUX_NO_SEGMENT_WR, AUX_USER_MODE); + it6505_set_bits(it6505, REG_AUX_USER_CTRL, EN_USER_AUX, EN_USER_AUX); + /* clear AUX FIFO */ + it6505_set_bits(it6505, REG_AUX_CTRL, + AUX_EN_FIFO_READ | CLR_EDID_FIFO, + AUX_EN_FIFO_READ | CLR_EDID_FIFO); + + it6505_set_bits(it6505, REG_AUX_CTRL, + AUX_EN_FIFO_READ | CLR_EDID_FIFO, 0x00); + + it6505_write(it6505, REG_AUX_ADR_0_7, 0x00); + it6505_write(it6505, REG_AUX_ADR_8_15, msg->address << 1); + + if (msg->size == 0) { + /* IIC Start/STOP dummy write */ + it6505_write(it6505, REG_AUX_ADR_16_19, msg->request); + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_ADR); + ret = it6505_aux_i2c_wait(it6505, &msg->reply); + goto end_aux_i2c_transfer; + } + + /* IIC data transfer */ + data_cnt = 0; + do { + request_size = min_t(ssize_t, msg->size - data_cnt, AUX_I2C_MAX_SIZE); + it6505_write(it6505, REG_AUX_ADR_16_19, + msg->request | ((request_size - 1) << 4)); + if ((msg->request & DP_AUX_I2C_READ) == DP_AUX_I2C_READ) + ret = it6505_aux_i2c_readb(it6505, &buffer[data_cnt], + request_size, &msg->reply); + else + ret = it6505_aux_i2c_writeb(it6505, &buffer[data_cnt], + request_size, &msg->reply); + + if (ret < 0) + goto end_aux_i2c_transfer; + + data_cnt += request_size; + } while (data_cnt < msg->size); + ret = data_cnt; +end_aux_i2c_transfer: + + it6505_set_bits(it6505, REG_AUX_USER_CTRL, EN_USER_AUX, 0); + it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, 0); + return ret; +} + +static ssize_t it6505_aux_i2c_transfer(struct drm_dp_aux *aux, + struct drm_dp_aux_msg *msg) +{ + struct it6505 *it6505 = container_of(aux, struct it6505, aux); + + guard(mutex)(&it6505->aux_lock); + return it6505_aux_i2c_operation(it6505, msg); +} + static ssize_t it6505_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { @@ -1125,9 +1299,8 @@ static ssize_t it6505_aux_transfer(struct drm_dp_aux *aux, int ret; enum aux_cmd_reply reply; - /* IT6505 doesn't support arbitrary I2C read / write. */ if (is_i2c) - return -EINVAL; + return it6505_aux_i2c_transfer(aux, msg); switch (msg->request) { case DP_AUX_NATIVE_READ: -- GitLab From 6fd570d1cf9c9aa9128a16c586666448cd035a78 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Thu, 2 Jan 2025 17:34:28 +0800 Subject: [PATCH 274/456] CHROMIUM: media: platform: mediatek: mdp3: fix resource race conditions and enhance ISP integration With the addition of direct ISP calls, MDP3 occurs several resource race conditions involving CMDQ and MUTEX. To address these issues, independent resources are allocated for different scenarios. Notably, the WDMA path allocated for ISP now has the capability to control 'pm_runtime_*' functions. Additionally, during camera HAL testing, a scenario was discovered where, in a short period of time, the ISP controls the MDP3 to output stream, along with the MDP3 M2M process frames. To handle this situation, one appropriate mutex is configured to protect critical sections. BUG=b:378802673 TEST=build pass UPSTREAM-TASK=b:368493852 Change-Id: I72a71d96560ed94085261711881c804df762af1a Signed-off-by: Moudy Ho Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6138204 Tested-by: Yudhistira Erlandinata Reviewed-by: Pin-yen Lin Commit-Queue: Hsin-Te Yuan Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 1 + .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 81 +++++++++++++++---- .../platform/mediatek/mdp3/mtk-mdp3-core.c | 14 ++++ .../platform/mediatek/mdp3/mtk-mdp3-core.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-vpu.c | 2 - 5 files changed, 80 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index d9ba2df38e9be..4276817c617fd 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -477,6 +477,7 @@ static const struct mdp_dip_cq_data mt8183_dip_cb[] = { const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .mdp_plat_id = MT8183, + .mdp_con_res = 0x14001000, .mdp_probe_infra = mt8183_mdp_probe_infra, .mdp_cfg = &mt8183_plat_cfg, .mdp_mutex_table_idx = mt8183_mutex_idx, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 4f440b3d42ed7..d49d10e95ed43 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -44,6 +44,34 @@ static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 return (count < num) ? (dis_output || dis_tile) : true; } +static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev, + enum mtk_mdp_comp_id id) +{ + enum mdp_pipe_id pipe_id; + + switch (id) { + case MDP_COMP_RDMA0: + pipe_id = MDP_PIPE_RDMA0; + break; + case MDP_COMP_ISP_IMGI: + pipe_id = MDP_PIPE_IMGI; + break; + case MDP_COMP_WPEI: + pipe_id = MDP_PIPE_WPEI; + break; + case MDP_COMP_WPEI2: + pipe_id = MDP_PIPE_WPEI2; + break; + default: + /* Avoid exceptions when operating MUTEX */ + pipe_id = MDP_PIPE_RDMA0; + dev_err(&mdp_dev->pdev->dev, "Unknown pipeline id %d", id); + break; + } + + return pipe_id; +} + static int mdp_path_subfrm_require(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, s32 *mutex_id, u32 count) @@ -340,18 +368,24 @@ static void mdp_auto_release_work(struct work_struct *work) { struct mdp_cmdq_cmd *cmd; struct mdp_dev *mdp; + enum mdp_pipe_id pipe_id; int id; cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work); mdp = cmd->mdp; - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + id = mdp->mdp_data->pipe_info[pipe_id].mutex_id; mtk_mutex_unprepare(mdp->mdp_mutex[id]); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); + if (CFG_CHECK(MT8183, mdp->mdp_data->mdp_plat_id)) + mutex_unlock(&mdp->m2m_lock); - atomic_dec(&mdp->job_count); - wake_up(&mdp->callback_wq); + if (cmd->mdp_ctx) { + atomic_dec(&mdp->job_count); + wake_up(&mdp->callback_wq); + } mdp_cmdq_pkt_destroy(&cmd->pkt); kfree(cmd->comps); @@ -366,6 +400,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) struct cmdq_cb_data *data; struct mdp_dev *mdp; struct device *dev; + enum mdp_pipe_id pipe_id; int id; if (!mssg) { @@ -392,10 +427,13 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work); if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) { dev_err(dev, "%s:queue_work fail!\n", __func__); - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + id = mdp->mdp_data->pipe_info[pipe_id].mutex_id; mtk_mutex_unprepare(mdp->mdp_mutex[id]); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); + if (CFG_CHECK(MT8183, mdp->mdp_data->mdp_plat_id)) + mutex_unlock(&mdp->m2m_lock); atomic_dec(&mdp->job_count); wake_up(&mdp->callback_wq); @@ -414,14 +452,17 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) struct mdp_cmdq_cmd *cmd = NULL; struct mdp_comp *comps = NULL; struct device *dev = &mdp->pdev->dev; + enum mdp_pipe_id pipe_id = MDP_PIPE_RDMA0; const int p_id = mdp->mdp_data->mdp_plat_id; int i, ret; u32 num_comp = 0; - atomic_inc(&mdp->job_count); - if (atomic_read(&mdp->suspended)) { - atomic_dec(&mdp->job_count); - return -ECANCELED; + if (param->mdp_ctx) { + atomic_inc(&mdp->job_count); + if (atomic_read(&mdp->suspended)) { + atomic_dec(&mdp->job_count); + return -ECANCELED; + } } cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); @@ -452,13 +493,6 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_comps; } - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - ret = mtk_mutex_prepare(mdp->mdp_mutex[i]); - if (ret) { - dev_err(dev, "Fail to enable mutex clk\n"); - goto err_free_path; - } - path->mdp_dev = mdp; path->config = param->config; path->param = param->param; @@ -478,6 +512,14 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_path; } + pipe_id = __get_pipe(mdp, path->comps[0].comp->public_id); + i = mdp->mdp_data->pipe_info[pipe_id].mutex_id; + ret = mtk_mutex_prepare(mdp->mdp_mutex[i]); + if (ret) { + dev_err(dev, "Fail to enable mutex clk\n"); + goto err_free_path; + } + ret = mdp_path_config(mdp, cmd, path); if (ret) { dev_err(dev, "mdp_path_config error\n"); @@ -497,6 +539,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) cmd->num_comps = num_comp; cmd->mdp_ctx = param->mdp_ctx; + if (CFG_CHECK(MT8183, p_id)) + mutex_lock(&mdp->m2m_lock); ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps); if (ret) goto err_free_path; @@ -518,7 +562,9 @@ err_clock_off: mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); err_free_path: - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; + if (CFG_CHECK(MT8183, p_id)) + mutex_unlock(&mdp->m2m_lock); + i = mdp->mdp_data->pipe_info[pipe_id].mutex_id; mtk_mutex_unprepare(mdp->mdp_mutex[i]); kfree(path); err_free_comps: @@ -528,7 +574,8 @@ err_destroy_pkt: err_free_cmd: kfree(cmd); err_cancel_job: - atomic_dec(&mdp->job_count); + if (param->mdp_ctx) + atomic_dec(&mdp->job_count); return ret; } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index cc44be10fdb77..9e0158e9796e8 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -21,6 +21,9 @@ static const struct of_device_id mdp_of_ids[] = { { .compatible = "mediatek,mt8183-mdp3-rdma", .data = &mt8183_mdp_driver_data, }, + { .compatible = "mediatek,mt8183-mdp3-wdma", + .data = &mt8183_mdp_driver_data, + }, {}, }; MODULE_DEVICE_TABLE(of, mdp_of_ids); @@ -87,6 +90,7 @@ int mdp_vpu_get_locked(struct mdp_dev *mdp) { int ret = 0; + mutex_lock(&mdp->vpu_lock); if (mdp->vpu_count++ == 0) { ret = rproc_boot(mdp->rproc_handle); if (ret) { @@ -107,12 +111,14 @@ int mdp_vpu_get_locked(struct mdp_dev *mdp) goto err_init_vpu; } } + mutex_unlock(&mdp->vpu_lock); return 0; err_init_vpu: mdp_vpu_unregister(mdp); err_reg_vpu: err_load_vpu: + mutex_unlock(&mdp->vpu_lock); mdp->vpu_count--; return ret; } @@ -153,6 +159,7 @@ static int mdp_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct mdp_dev *mdp; struct platform_device *mm_pdev; + struct resource *res; int ret, i, mutex_id; mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); @@ -164,6 +171,12 @@ static int mdp_probe(struct platform_device *pdev) mdp->pdev = pdev; mdp->mdp_data = of_device_get_match_data(&pdev->dev); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res->start != mdp->mdp_data->mdp_con_res) { + platform_set_drvdata(pdev, mdp); + goto success_return; + } + mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MMSYS); if (!mm_pdev) { ret = -ENODEV; @@ -246,6 +259,7 @@ static int mdp_probe(struct platform_device *pdev) goto err_unregister_device; } +success_return: dev_dbg(dev, "mdp-%d registered successfully\n", pdev->id); return 0; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index bc697d1a0c6ee..62733a2fa1855 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -52,6 +52,7 @@ enum mdp_pipe_id { struct mtk_mdp_driver_data { const int mdp_plat_id; + const resource_size_t mdp_con_res; const struct of_device_id *mdp_probe_infra; const struct mdp_platform_config *mdp_cfg; const u32 *mdp_mutex_table_idx; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c index 49fc2e9d45dd5..116efe1a4e331 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c @@ -208,12 +208,10 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp, goto err_work_size; /* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */ - mutex_lock(vpu->lock); vpu->work_size = ALIGN(vpu->work_size, 64); vpu->param_size = ALIGN(sizeof(struct img_ipi_frameparam), 64); vpu->config_size = ALIGN(sizeof(struct img_config), 64); err = mdp_vpu_shared_mem_alloc(vpu); - mutex_unlock(vpu->lock); if (err) { dev_err(&mdp->pdev->dev, "VPU memory alloc fail!"); goto err_mem_alloc; -- GitLab From 87c8fa616e9ba507102ef83c3e13e72a4408f7d5 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:43:28 +0800 Subject: [PATCH 275/456] CHROMIUM: dt-bindings: power: Add MT8196 power domain header Add MT8196 power domain header. BUG=b:385017273 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:379034565 Change-Id: If7398c2747def4279208323c6f27fb39c783528a Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6147633 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/power/mt8196-power.h | 78 ++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 include/dt-bindings/power/mt8196-power.h diff --git a/include/dt-bindings/power/mt8196-power.h b/include/dt-bindings/power/mt8196-power.h new file mode 100644 index 0000000000000..ee7d76d2a76ff --- /dev/null +++ b/include/dt-bindings/power/mt8196-power.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Chong-ming Wei + */ + +#ifndef _DT_BINDINGS_POWER_MT8196_POWER_H +#define _DT_BINDINGS_POWER_MT8196_POWER_H + +/* SPM */ +#define MT8196_POWER_DOMAIN_MD 0 +#define MT8196_POWER_DOMAIN_CONN 1 +#define MT8196_POWER_DOMAIN_SSUSB_P0 2 +#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0 3 +#define MT8196_POWER_DOMAIN_SSUSB_P1 4 +#define MT8196_POWER_DOMAIN_SSUSB_P23 5 +#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2 6 +#define MT8196_POWER_DOMAIN_PEXTP_MAC0 7 +#define MT8196_POWER_DOMAIN_PEXTP_MAC1 8 +#define MT8196_POWER_DOMAIN_PEXTP_MAC2 9 +#define MT8196_POWER_DOMAIN_PEXTP_PHY0 10 +#define MT8196_POWER_DOMAIN_PEXTP_PHY1 11 +#define MT8196_POWER_DOMAIN_PEXTP_PHY2 12 +#define MT8196_POWER_DOMAIN_ADSP_AO 13 +#define MT8196_POWER_DOMAIN_ADSP_INFRA 14 +#define MT8196_POWER_DOMAIN_AUDIO 15 +#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT 16 +#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 17 +#define MT8196_POWER_DOMAIN_SSR 18 +#define MT8196_POWER_DOMAIN_SPU_ISE 19 +#define MT8196_POWER_DOMAIN_SPU_HWROT 20 +#define MT8196_SPM_POWER_DOMAIN_NR 21 + +/* MMPC */ +#define MT8196_POWER_DOMAIN_MM_INFRA_AO 0 +#define MT8196_POWER_DOMAIN_MM_INFRA0 1 +#define MT8196_POWER_DOMAIN_MM_INFRA1 2 +#define MT8196_POWER_DOMAIN_ISP_VCORE 3 +#define MT8196_POWER_DOMAIN_ISP_MAIN 4 +#define MT8196_POWER_DOMAIN_ISP_TRAW 5 +#define MT8196_POWER_DOMAIN_ISP_DIP 6 +#define MT8196_POWER_DOMAIN_ISP_WPE_EIS 7 +#define MT8196_POWER_DOMAIN_ISP_WPE_TNR 8 +#define MT8196_POWER_DOMAIN_ISP_WPE_LITE 9 +#define MT8196_POWER_DOMAIN_VDE_VCORE0 10 +#define MT8196_POWER_DOMAIN_VDE0 11 +#define MT8196_POWER_DOMAIN_VDE1 12 +#define MT8196_POWER_DOMAIN_VEN0 13 +#define MT8196_POWER_DOMAIN_VEN1 14 +#define MT8196_POWER_DOMAIN_VEN2 15 +#define MT8196_POWER_DOMAIN_CAM_VCORE 16 +#define MT8196_POWER_DOMAIN_CAM_MAIN 17 +#define MT8196_POWER_DOMAIN_CAM_MRAW 18 +#define MT8196_POWER_DOMAIN_CAM_RAWA 19 +#define MT8196_POWER_DOMAIN_CAM_RAWB 20 +#define MT8196_POWER_DOMAIN_CAM_RAWC 21 +#define MT8196_POWER_DOMAIN_CAM_RMSA 22 +#define MT8196_POWER_DOMAIN_CAM_RMSB 23 +#define MT8196_POWER_DOMAIN_CAM_RMSC 24 +#define MT8196_POWER_DOMAIN_CAM_CCU 25 +#define MT8196_POWER_DOMAIN_DISP_VCORE 26 +#define MT8196_POWER_DOMAIN_DIS0_DORMANT 27 +#define MT8196_POWER_DOMAIN_DIS1_DORMANT 28 +#define MT8196_POWER_DOMAIN_OVL0_DORMANT 29 +#define MT8196_POWER_DOMAIN_OVL1_DORMANT 30 +#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT 31 +#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT 32 +#define MT8196_POWER_DOMAIN_MML0_DORMANT 33 +#define MT8196_POWER_DOMAIN_MML1_DORMANT 34 +#define MT8196_POWER_DOMAIN_CSI_BS_RX 35 +#define MT8196_POWER_DOMAIN_CSI_LS_RX 36 +#define MT8196_POWER_DOMAIN_DSI_PHY0 37 +#define MT8196_POWER_DOMAIN_DSI_PHY1 38 +#define MT8196_POWER_DOMAIN_DSI_PHY2 39 +#define MT8196_MMPC_POWER_DOMAIN_NR 40 + + +#endif /* _DT_BINDINGS_POWER_MT8196_POWER_H */ -- GitLab From c4a282b0bf3a2354b90b18c588026fd5fd4659d1 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:44:31 +0800 Subject: [PATCH 276/456] CHROMIUM: dt-bindings: clock: Add MT8196 clock header Add MT8196 clock header. BUG=b:385017273 BUG=b:383207708 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:354021544 Change-Id: I663c99cc2b053cb2d18572a946b6dfb2d0336698 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6147634 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/clock/mt8196-clk.h | 1515 ++++++++++++++++++++++++ 1 file changed, 1515 insertions(+) create mode 100644 include/dt-bindings/clock/mt8196-clk.h diff --git a/include/dt-bindings/clock/mt8196-clk.h b/include/dt-bindings/clock/mt8196-clk.h new file mode 100644 index 0000000000000..aa6f9544ffcc5 --- /dev/null +++ b/include/dt-bindings/clock/mt8196-clk.h @@ -0,0 +1,1515 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Chong-ming Wei + */ + +#ifndef _DT_BINDINGS_CLK_MT8196_H +#define _DT_BINDINGS_CLK_MT8196_H + +/* CKSYS */ +#define CLK_CK_AXI_SEL 0 +#define CLK_CK_MEM_SUB_SEL 1 +#define CLK_CK_IO_NOC_SEL 2 +#define CLK_CK_P_AXI_SEL 3 +#define CLK_CK_PEXTP0_AXI_SEL 4 +#define CLK_CK_PEXTP1_USB_AXI_SEL 5 +#define CLK_CK_P_FMEM_SUB_SEL 6 +#define CLK_CK_PEXPT0_MEM_SUB_SEL 7 +#define CLK_CK_PEXTP1_USB_MEM_SUB_SEL 8 +#define CLK_CK_P_NOC_SEL 9 +#define CLK_CK_EMI_N_SEL 10 +#define CLK_CK_EMI_S_SEL 11 +#define CLK_CK_AP2CONN_HOST_SEL 12 +#define CLK_CK_ATB_SEL 13 +#define CLK_CK_CIRQ_SEL 14 +#define CLK_CK_PBUS_156M_SEL 15 +#define CLK_CK_EFUSE_SEL 16 +#define CLK_CK_MCL3GIC_SEL 17 +#define CLK_CK_MCINFRA_SEL 18 +#define CLK_CK_DSP_SEL 19 +#define CLK_CK_MFG_REF_SEL 20 +#define CLK_CK_MFG_EB_SEL 21 +#define CLK_CK_UART_SEL 22 +#define CLK_CK_SPI0_BCLK_SEL 23 +#define CLK_CK_SPI1_BCLK_SEL 24 +#define CLK_CK_SPI2_BCLK_SEL 25 +#define CLK_CK_SPI3_BCLK_SEL 26 +#define CLK_CK_SPI4_BCLK_SEL 27 +#define CLK_CK_SPI5_BCLK_SEL 28 +#define CLK_CK_SPI6_BCLK_SEL 29 +#define CLK_CK_SPI7_BCLK_SEL 30 +#define CLK_CK_MSDC30_1_SEL 31 +#define CLK_CK_MSDC30_2_SEL 32 +#define CLK_CK_DISP_PWM_SEL 33 +#define CLK_CK_USB_TOP_1P_SEL 34 +#define CLK_CK_USB_XHCI_1P_SEL 35 +#define CLK_CK_USB_FMCNT_P1_SEL 36 +#define CLK_CK_I2C_P_SEL 37 +#define CLK_CK_I2C_EAST_SEL 38 +#define CLK_CK_I2C_WEST_SEL 39 +#define CLK_CK_I2C_NORTH_SEL 40 +#define CLK_CK_AES_UFSFDE_SEL 41 +#define CLK_CK_SEL 42 +#define CLK_CK_AUD_1_SEL 43 +#define CLK_CK_AUD_2_SEL 44 +#define CLK_CK_ADSP_SEL 45 +#define CLK_CK_ADSP_UARTHUB_BCLK_SEL 46 +#define CLK_CK_DPMAIF_MAIN_SEL 47 +#define CLK_CK_PWM_SEL 48 +#define CLK_CK_MCUPM_SEL 49 +#define CLK_CK_IPSEAST_SEL 50 +#define CLK_CK_TL_SEL 51 +#define CLK_CK_TL_P1_SEL 52 +#define CLK_CK_TL_P2_SEL 53 +#define CLK_CK_EMI_INTERFACE_546_SEL 54 +#define CLK_CK_SDF_SEL 55 +#define CLK_CK_UARTHUB_BCLK_SEL 56 +#define CLK_CK_DPSW_CMP_26M_SEL 57 +#define CLK_CK_SMAPCK_SEL 58 +#define CLK_CK_SSR_PKA_SEL 59 +#define CLK_CK_SSR_DMA_SEL 60 +#define CLK_CK_SSR_KDF_SEL 61 +#define CLK_CK_SSR_RNG_SEL 62 +#define CLK_CK_SPU0_SEL 63 +#define CLK_CK_SPU1_SEL 64 +#define CLK_CK_DXCC_SEL 65 +#define CLK_CK_APLL_I2SIN0_MCK_SEL 66 +#define CLK_CK_APLL_I2SIN1_MCK_SEL 67 +#define CLK_CK_APLL_I2SIN2_MCK_SEL 68 +#define CLK_CK_APLL_I2SIN3_MCK_SEL 69 +#define CLK_CK_APLL_I2SIN4_MCK_SEL 70 +#define CLK_CK_APLL_I2SIN6_MCK_SEL 71 +#define CLK_CK_APLL_I2SOUT0_MCK_SEL 72 +#define CLK_CK_APLL_I2SOUT1_MCK_SEL 73 +#define CLK_CK_APLL_I2SOUT2_MCK_SEL 74 +#define CLK_CK_APLL_I2SOUT3_MCK_SEL 75 +#define CLK_CK_APLL_I2SOUT4_MCK_SEL 76 +#define CLK_CK_APLL_I2SOUT6_MCK_SEL 77 +#define CLK_CK_APLL_FMI2S_MCK_SEL 78 +#define CLK_CK_APLL_TDMOUT_MCK_SEL 79 +#define CLK_CK_APLL12_CK_DIV_I2SIN0 80 +#define CLK_CK_APLL12_CK_DIV_I2SIN1 81 +#define CLK_CK_APLL12_CK_DIV_I2SIN2 82 +#define CLK_CK_APLL12_CK_DIV_I2SIN3 83 +#define CLK_CK_APLL12_CK_DIV_I2SIN4 84 +#define CLK_CK_APLL12_CK_DIV_I2SIN6 85 +#define CLK_CK_APLL12_CK_DIV_I2SOUT0 86 +#define CLK_CK_APLL12_CK_DIV_I2SOUT1 87 +#define CLK_CK_APLL12_CK_DIV_I2SOUT2 88 +#define CLK_CK_APLL12_CK_DIV_I2SOUT3 89 +#define CLK_CK_APLL12_CK_DIV_I2SOUT4 90 +#define CLK_CK_APLL12_CK_DIV_I2SOUT6 91 +#define CLK_CK_APLL12_CK_DIV_FMI2S 92 +#define CLK_CK_APLL12_CK_DIV_TDMOUT_M 93 +#define CLK_CK_APLL12_CK_DIV_TDMOUT_B 94 +#define CLK_CK_MAINPLL_D3 95 +#define CLK_CK_MAINPLL_D4 96 +#define CLK_CK_MAINPLL_D4_D2 97 +#define CLK_CK_MAINPLL_D4_D4 98 +#define CLK_CK_MAINPLL_D4_D8 99 +#define CLK_CK_MAINPLL_D5 100 +#define CLK_CK_MAINPLL_D5_D2 101 +#define CLK_CK_MAINPLL_D5_D4 102 +#define CLK_CK_MAINPLL_D5_D8 103 +#define CLK_CK_MAINPLL_D6 104 +#define CLK_CK_MAINPLL_D6_D2 105 +#define CLK_CK_MAINPLL_D7 106 +#define CLK_CK_MAINPLL_D7_D2 107 +#define CLK_CK_MAINPLL_D7_D4 108 +#define CLK_CK_MAINPLL_D7_D8 109 +#define CLK_CK_MAINPLL_D9 110 +#define CLK_CK_UNIVPLL_D4 111 +#define CLK_CK_UNIVPLL_D4_D2 112 +#define CLK_CK_UNIVPLL_D4_D4 113 +#define CLK_CK_UNIVPLL_D4_D8 114 +#define CLK_CK_UNIVPLL_D5 115 +#define CLK_CK_UNIVPLL_D5_D2 116 +#define CLK_CK_UNIVPLL_D5_D4 117 +#define CLK_CK_UNIVPLL_D6 118 +#define CLK_CK_UNIVPLL_D6_D2 119 +#define CLK_CK_UNIVPLL_D6_D4 120 +#define CLK_CK_UNIVPLL_D6_D8 121 +#define CLK_CK_UNIVPLL_D6_D16 122 +#define CLK_CK_UNIVPLL_192M 123 +#define CLK_CK_UNIVPLL_192M_D4 124 +#define CLK_CK_UNIVPLL_192M_D8 125 +#define CLK_CK_UNIVPLL_192M_D16 126 +#define CLK_CK_UNIVPLL_192M_D32 127 +#define CLK_CK_UNIVPLL_192M_D10 128 +#define CLK_CK_APLL1 129 +#define CLK_CK_APLL1_D4 130 +#define CLK_CK_APLL1_D8 131 +#define CLK_CK_APLL2 132 +#define CLK_CK_APLL2_D4 133 +#define CLK_CK_APLL2_D8 134 +#define CLK_CK_ADSPPLL 135 +#define CLK_CK_EMIPLL1 136 +#define CLK_CK_TVDPLL1_D2 137 +#define CLK_CK_MSDCPLL_D2 138 +#define CLK_CK_CLKRTC 139 +#define CLK_CK_TCK_26M_MX9 140 +#define CLK_CK_F26M 141 +#define CLK_CK_F26M_CK_D2 142 +#define CLK_CK_OSC 143 +#define CLK_CK_OSC_D2 144 +#define CLK_CK_OSC_D3 145 +#define CLK_CK_OSC_D4 146 +#define CLK_CK_OSC_D5 147 +#define CLK_CK_OSC_D7 148 +#define CLK_CK_OSC_D8 149 +#define CLK_CK_OSC_D10 150 +#define CLK_CK_OSC_D14 151 +#define CLK_CK_OSC_D20 152 +#define CLK_CK_OSC_D32 153 +#define CLK_CK_OSC_D40 154 +#define CLK_CK_OSC3 155 +#define CLK_CK_P_AXI 156 +#define CLK_CK_PEXTP0_AXI 157 +#define CLK_CK_PEXTP1_USB_AXI 158 +#define CLK_CK_PEXPT0_MEM_SUB 159 +#define CLK_CK_PEXTP1_USB_MEM_SUB 160 +#define CLK_CK_UART 161 +#define CLK_CK_SPI0_BCLK 162 +#define CLK_CK_SPI1_BCLK 163 +#define CLK_CK_SPI2_BCLK 164 +#define CLK_CK_SPI3_BCLK 165 +#define CLK_CK_SPI4_BCLK 166 +#define CLK_CK_SPI5_BCLK 167 +#define CLK_CK_SPI6_BCLK 168 +#define CLK_CK_SPI7_BCLK 169 +#define CLK_CK_MSDC30_1 170 +#define CLK_CK_MSDC30_2 171 +#define CLK_CK_I2C_PERI 172 +#define CLK_CK_I2C_EAST 173 +#define CLK_CK_I2C_WEST 174 +#define CLK_CK_I2C_NORTH 175 +#define CLK_CK_AES_UFSFDE 176 +#define CLK_CK_UFS 177 +#define CLK_CK_AUD_1 178 +#define CLK_CK_AUD_2 179 +#define CLK_CK_DPMAIF_MAIN 180 +#define CLK_CK_PWM 181 +#define CLK_CK_TL 182 +#define CLK_CK_TL_P1 183 +#define CLK_CK_TL_P2 184 +#define CLK_CK_SSR_RNG 185 +#define CLK_CK_SPU0 186 +#define CLK_CK_DXCC 187 +#define CLK_CK_SFLASH_SEL 188 +#define CLK_CK_SFLASH 189 +#define CLK_CK_NR_CLK 190 + +/* APMIXEDSYS */ +#define CLK_APMIXED_MAINPLL 0 +#define CLK_APMIXED_UNIVPLL 1 +#define CLK_APMIXED_MSDCPLL 2 +#define CLK_APMIXED_ADSPPLL 3 +#define CLK_APMIXED_EMIPLL 4 +#define CLK_APMIXED_EMIPLL2 5 +#define CLK_APMIXED_NR_CLK 6 + +/* CKSYS_GP2 */ +#define CLK_CK2_SENINF0_SEL 0 +#define CLK_CK2_SENINF1_SEL 1 +#define CLK_CK2_SENINF2_SEL 2 +#define CLK_CK2_SENINF3_SEL 3 +#define CLK_CK2_SENINF4_SEL 4 +#define CLK_CK2_SENINF5_SEL 5 +#define CLK_CK2_IMG1_SEL 6 +#define CLK_CK2_IPE_SEL 7 +#define CLK_CK2_CAM_SEL 8 +#define CLK_CK2_CAMTM_SEL 9 +#define CLK_CK2_DPE_SEL 10 +#define CLK_CK2_VDEC_SEL 11 +#define CLK_CK2_CCUSYS_SEL 12 +#define CLK_CK2_CCUTM_SEL 13 +#define CLK_CK2_VENC_SEL 14 +#define CLK_CK2_DP1_SEL 15 +#define CLK_CK2_DP0_SEL 16 +#define CLK_CK2_DISP_SEL 17 +#define CLK_CK2_MDP_SEL 18 +#define CLK_CK2_MMINFRA_SEL 19 +#define CLK_CK2_MMINFRA_SNOC_SEL 20 +#define CLK_CK2_MMUP_SEL 21 +#define CLK_CK2_MMINFRA_AO_SEL 22 +#define CLK_CK2_MAINPLL2_D2 23 +#define CLK_CK2_MAINPLL2_D3 24 +#define CLK_CK2_MAINPLL2_D4 25 +#define CLK_CK2_MAINPLL2_D4_D2 26 +#define CLK_CK2_MAINPLL2_D4_D4 27 +#define CLK_CK2_MAINPLL2_D5 28 +#define CLK_CK2_MAINPLL2_D5_D2 29 +#define CLK_CK2_MAINPLL2_D6 30 +#define CLK_CK2_MAINPLL2_D6_D2 31 +#define CLK_CK2_MAINPLL2_D7 32 +#define CLK_CK2_MAINPLL2_D7_D2 33 +#define CLK_CK2_MAINPLL2_D9 34 +#define CLK_CK2_UNIVPLL2_D3 35 +#define CLK_CK2_UNIVPLL2_D4 36 +#define CLK_CK2_UNIVPLL2_D4_D2 37 +#define CLK_CK2_UNIVPLL2_D5 38 +#define CLK_CK2_UNIVPLL2_D5_D2 39 +#define CLK_CK2_UNIVPLL2_D6 40 +#define CLK_CK2_UNIVPLL2_D6_D2 41 +#define CLK_CK2_UNIVPLL2_D6_D4 42 +#define CLK_CK2_UNIVPLL2_D7 43 +#define CLK_CK2_IMGPLL_D2 44 +#define CLK_CK2_IMGPLL_D4 45 +#define CLK_CK2_IMGPLL_D5 46 +#define CLK_CK2_IMGPLL_D5_D2 47 +#define CLK_CK2_MMPLL2_D3 48 +#define CLK_CK2_MMPLL2_D4 49 +#define CLK_CK2_MMPLL2_D4_D2 50 +#define CLK_CK2_MMPLL2_D5 51 +#define CLK_CK2_MMPLL2_D5_D2 52 +#define CLK_CK2_MMPLL2_D6 53 +#define CLK_CK2_MMPLL2_D6_D2 54 +#define CLK_CK2_MMPLL2_D7 55 +#define CLK_CK2_MMPLL2_D9 56 +#define CLK_CK2_TVDPLL1_D4 57 +#define CLK_CK2_TVDPLL1_D8 58 +#define CLK_CK2_TVDPLL1_D16 59 +#define CLK_CK2_TVDPLL2_D2 60 +#define CLK_CK2_TVDPLL2_D4 61 +#define CLK_CK2_TVDPLL2_D8 62 +#define CLK_CK2_TVDPLL2_D16 63 +#define CLK_CK2_CCUSYS 64 +#define CLK_CK2_VENC 65 +#define CLK_CK2_MMINFRA 66 +#define CLK_CK2_IMG1 67 +#define CLK_CK2_IPE 68 +#define CLK_CK2_CAM 69 +#define CLK_CK2_CAMTM 70 +#define CLK_CK2_DPE 71 +#define CLK_CK2_VDEC 72 +#define CLK_CK2_DP1 73 +#define CLK_CK2_DP0 74 +#define CLK_CK2_MDP 75 +#define CLK_CK2_DISP 76 +#define CLK_CK2_AVS_IMG 77 +#define CLK_CK2_AVS_VDEC 78 +#define CLK_CK2_DVO_SEL 79 +#define CLK_CK2_DVO_FAVT_SEL 80 +#define CLK_CK2_TVDPLL3_D2 81 +#define CLK_CK2_TVDPLL3_D4 82 +#define CLK_CK2_TVDPLL3_D8 83 +#define CLK_CK2_TVDPLL3_D16 84 +#define CLK_CK2_NR_CLK 85 + +/* APMIXEDSYS_GP2 */ +#define CLK_APMIXED2_MAINPLL2 0 +#define CLK_APMIXED2_UNIVPLL2 1 +#define CLK_APMIXED2_MMPLL2 2 +#define CLK_APMIXED2_IMGPLL 3 +#define CLK_APMIXED2_TVDPLL1 4 +#define CLK_APMIXED2_TVDPLL2 5 +#define CLK_APMIXED2_TVDPLL3 6 +#define CLK_APMIXED2_NR_CLK 7 + +/* IMP_IIC_WRAP_E */ +#define CLK_IMPE_I2C5 0 +#define CLK_IMPE_I2C5_I2C 1 +#define CLK_IMPE_NR_CLK 2 + +/* IMP_IIC_WRAP_W */ +#define CLK_IMPW_I2C0 0 +#define CLK_IMPW_I2C0_I2C 1 +#define CLK_IMPW_I2C3 2 +#define CLK_IMPW_I2C3_I2C 3 +#define CLK_IMPW_I2C6 4 +#define CLK_IMPW_I2C6_I2C 5 +#define CLK_IMPW_I2C10 6 +#define CLK_IMPW_I2C10_I2C 7 +#define CLK_IMPW_NR_CLK 8 + +/* IMP_IIC_WRAP_N */ +#define CLK_IMPN_I2C1 0 +#define CLK_IMPN_I2C1_I2C 1 +#define CLK_IMPN_I2C2 2 +#define CLK_IMPN_I2C2_I2C 3 +#define CLK_IMPN_I2C4 4 +#define CLK_IMPN_I2C4_I2C 5 +#define CLK_IMPN_I2C7 6 +#define CLK_IMPN_I2C7_I2C 7 +#define CLK_IMPN_I2C8 8 +#define CLK_IMPN_I2C8_I2C 9 +#define CLK_IMPN_I2C9 10 +#define CLK_IMPN_I2C9_I2C 11 +#define CLK_IMPN_NR_CLK 12 + +/* APIFRBUS_AO_MEM_REG */ +#define CLK_IFR_MEM_DPMAIF_MAIN 0 +#define CLK_IFR_MEM_DPMAIF_MAIN_CCCI 1 +#define CLK_IFR_MEM_DPMAIF_26M 2 +#define CLK_IFR_MEM_DPMAIF_26M_CCCI 3 +#define CLK_IFR_MEM_NR_CLK 4 + +/* IMP_IIC_WRAP_C */ +#define CLK_IMPC_I2C11 0 +#define CLK_IMPC_I2C11_I2C 1 +#define CLK_IMPC_I2C12 2 +#define CLK_IMPC_I2C12_I2C 3 +#define CLK_IMPC_I2C13 4 +#define CLK_IMPC_I2C13_I2C 5 +#define CLK_IMPC_I2C14 6 +#define CLK_IMPC_I2C14_I2C 7 +#define CLK_IMPC_NR_CLK 8 + +/* PERICFG_AO */ +#define CLK_PERAO_UART0_BCLK 0 +#define CLK_PERAO_UART0_BCLK_UART 1 +#define CLK_PERAO_UART1_BCLK 2 +#define CLK_PERAO_UART1_BCLK_UART 3 +#define CLK_PERAO_UART2_BCLK 4 +#define CLK_PERAO_UART2_BCLK_UART 5 +#define CLK_PERAO_UART3_BCLK 6 +#define CLK_PERAO_UART3_BCLK_UART 7 +#define CLK_PERAO_UART4_BCLK 8 +#define CLK_PERAO_UART4_BCLK_UART 9 +#define CLK_PERAO_UART5_BCLK 10 +#define CLK_PERAO_UART5_BCLK_UART 11 +#define CLK_PERAO_PWM_X16W_HCLK 12 +#define CLK_PERAO_PWM_X16W_HCLK_PWM 13 +#define CLK_PERAO_PWM_X16W_BCLK 14 +#define CLK_PERAO_PWM_X16W_BCLK_PWM 15 +#define CLK_PERAO_PWM_PWM_BCLK0 16 +#define CLK_PERAO_PWM_PWM_BCLK0_PWM 17 +#define CLK_PERAO_PWM_PWM_BCLK1 18 +#define CLK_PERAO_PWM_PWM_BCLK1_PWM 19 +#define CLK_PERAO_PWM_PWM_BCLK2 20 +#define CLK_PERAO_PWM_PWM_BCLK2_PWM 21 +#define CLK_PERAO_PWM_PWM_BCLK3 22 +#define CLK_PERAO_PWM_PWM_BCLK3_PWM 23 +#define CLK_PERAO_SPI0_BCLK 24 +#define CLK_PERAO_SPI0_BCLK_SPI 25 +#define CLK_PERAO_SPI1_BCLK 26 +#define CLK_PERAO_SPI1_BCLK_SPI 27 +#define CLK_PERAO_SPI2_BCLK 28 +#define CLK_PERAO_SPI2_BCLK_SPI 29 +#define CLK_PERAO_SPI3_BCLK 30 +#define CLK_PERAO_SPI3_BCLK_SPI 31 +#define CLK_PERAO_SPI4_BCLK 32 +#define CLK_PERAO_SPI4_BCLK_SPI 33 +#define CLK_PERAO_SPI5_BCLK 34 +#define CLK_PERAO_SPI5_BCLK_SPI 35 +#define CLK_PERAO_SPI6_BCLK 36 +#define CLK_PERAO_SPI6_BCLK_SPI 37 +#define CLK_PERAO_SPI7_BCLK 38 +#define CLK_PERAO_SPI7_BCLK_SPI 39 +#define CLK_PERAO_AP_DMA_X32W_BCLK 40 +#define CLK_PERAO_AP_DMA_X32W_BCLK_UART 41 +#define CLK_PERAO_AP_DMA_X32W_BCLK_I2C 42 +#define CLK_PERAO_MSDC1_MSDC_SRC 43 +#define CLK_PERAO_MSDC1_MSDC_SRC_MSDC1 44 +#define CLK_PERAO_MSDC1_HCLK 45 +#define CLK_PERAO_MSDC1_HCLK_MSDC1 46 +#define CLK_PERAO_MSDC1_AXI 47 +#define CLK_PERAO_MSDC1_AXI_MSDC1 48 +#define CLK_PERAO_MSDC1_HCLK_WRAP 49 +#define CLK_PERAO_MSDC1_HCLK_WRAP_MSDC1 50 +#define CLK_PERAO_MSDC2_MSDC_SRC 51 +#define CLK_PERAO_MSDC2_MSDC_SRC_MSDC2 52 +#define CLK_PERAO_MSDC2_HCLK 53 +#define CLK_PERAO_MSDC2_HCLK_MSDC2 54 +#define CLK_PERAO_MSDC2_AXI 55 +#define CLK_PERAO_MSDC2_AXI_MSDC2 56 +#define CLK_PERAO_MSDC2_HCLK_WRAP 57 +#define CLK_PERAO_MSDC2_HCLK_WRAP_MSDC2 58 +#define CLK_PERAO_FLASHIF_FLASH 59 +#define CLK_PERAO_FLASHIF_FLASH_FLASHIF 60 +#define CLK_PERAO_FLASHIF_27M 61 +#define CLK_PERAO_FLASHIF_27M_FLASHIF 62 +#define CLK_PERAO_FLASHIF_DRAM 63 +#define CLK_PERAO_FLASHIF_DRAM_FLASHIF 64 +#define CLK_PERAO_FLASHIF_AXI 65 +#define CLK_PERAO_FLASHIF_AXI_FLASHIF 66 +#define CLK_PERAO_FLASHIF_BCLK 67 +#define CLK_PERAO_FLASHIF_BCLK_FLASHIF 68 +#define CLK_PERAO_NR_CLK 69 + +/* UFSCFG_AO */ +#define CLK_UFSAO_UNIPRO_TX_SYM 0 +#define CLK_UFSAO_UNIPRO_TX_SYM_UFS 1 +#define CLK_UFSAO_UNIPRO_RX_SYM0 2 +#define CLK_UFSAO_UNIPRO_RX_SYM0_UFS 3 +#define CLK_UFSAO_UNIPRO_RX_SYM1 4 +#define CLK_UFSAO_UNIPRO_RX_SYM1_UFS 5 +#define CLK_UFSAO_UNIPRO_SYS 6 +#define CLK_UFSAO_UNIPRO_SYS_UFS 7 +#define CLK_UFSAO_UNIPRO_SAP 8 +#define CLK_UFSAO_UNIPRO_SAP_UFS 9 +#define CLK_UFSAO_PHY_SAP 10 +#define CLK_UFSAO_PHY_SAP_UFS 11 +#define CLK_UFSAO_UFSHCI_UFS 12 +#define CLK_UFSAO_UFSHCI_UFS_UFS 13 +#define CLK_UFSAO_UFSHCI_AES 14 +#define CLK_UFSAO_UFSHCI_AES_UFS 15 +#define CLK_UFSAO_NR_CLK 16 + +/* PEXTP0CFG_AO */ +#define CLK_PEXT_PEXTP_MAC_P0_TL 0 +#define CLK_PEXT_PEXTP_MAC_P0_TL_PCIE 1 +#define CLK_PEXT_PEXTP_MAC_P0_REF 2 +#define CLK_PEXT_PEXTP_MAC_P0_REF_PCIE 3 +#define CLK_PEXT_PEXTP_PHY_P0_MCU_BUS 4 +#define CLK_PEXT_PEXTP_PHY_P0_MCU_BUS_PCIE 5 +#define CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF 6 +#define CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF_PCIE 7 +#define CLK_PEXT_PEXTP_MAC_P0_AXI_250 8 +#define CLK_PEXT_PEXTP_MAC_P0_AXI_250_PCIE 9 +#define CLK_PEXT_PEXTP_MAC_P0_AHB_APB 10 +#define CLK_PEXT_PEXTP_MAC_P0_AHB_APB_PCIE 11 +#define CLK_PEXT_PEXTP_MAC_P0_PL_P 12 +#define CLK_PEXT_PEXTP_MAC_P0_PL_P_PCIE 13 +#define CLK_PEXT_PEXTP_VLP_AO_P0_LP 14 +#define CLK_PEXT_PEXTP_VLP_AO_P0_LP_PCIE 15 +#define CLK_PEXT_NR_CLK 16 + +/* PEXTP1CFG_AO */ +#define CLK_PEXT1_PEXTP_MAC_P1_TL 0 +#define CLK_PEXT1_PEXTP_MAC_P1_TL_PCIE 1 +#define CLK_PEXT1_PEXTP_MAC_P1_REF 2 +#define CLK_PEXT1_PEXTP_MAC_P1_REF_PCIE 3 +#define CLK_PEXT1_PEXTP_MAC_P2_TL 4 +#define CLK_PEXT1_PEXTP_MAC_P2_TL_PCIE 5 +#define CLK_PEXT1_PEXTP_MAC_P2_REF 6 +#define CLK_PEXT1_PEXTP_MAC_P2_REF_PCIE 7 +#define CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS 8 +#define CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS_PCIE 9 +#define CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF 10 +#define CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF_PCIE 11 +#define CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS 12 +#define CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS_PCIE 13 +#define CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF 14 +#define CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF_PCIE 15 +#define CLK_PEXT1_PEXTP_MAC_P1_AXI_250 16 +#define CLK_PEXT1_PEXTP_MAC_P1_AXI_250_PCIE 17 +#define CLK_PEXT1_PEXTP_MAC_P1_AHB_APB 18 +#define CLK_PEXT1_PEXTP_MAC_P1_AHB_APB_PCIE 19 +#define CLK_PEXT1_PEXTP_MAC_P1_PL_P 20 +#define CLK_PEXT1_PEXTP_MAC_P1_PL_P_PCIE 21 +#define CLK_PEXT1_PEXTP_MAC_P2_AXI_250 22 +#define CLK_PEXT1_PEXTP_MAC_P2_AXI_250_PCIE 23 +#define CLK_PEXT1_PEXTP_MAC_P2_AHB_APB 24 +#define CLK_PEXT1_PEXTP_MAC_P2_AHB_APB_PCIE 25 +#define CLK_PEXT1_PEXTP_MAC_P2_PL_P 26 +#define CLK_PEXT1_PEXTP_MAC_P2_PL_P_PCIE 27 +#define CLK_PEXT1_PEXTP_VLP_AO_P1_LP 28 +#define CLK_PEXT1_PEXTP_VLP_AO_P1_LP_PCIE 29 +#define CLK_PEXT1_PEXTP_VLP_AO_P2_LP 30 +#define CLK_PEXT1_PEXTP_VLP_AO_P2_LP_PCIE 31 +#define CLK_PEXT1_NR_CLK 32 + +/* VLP_CKSYS */ +#define CLK_VLP_CK_VLP_APLL1 0 +#define CLK_VLP_CK_VLP_APLL2 1 +#define CLK_VLP_CK_SCP_SEL 2 +#define CLK_VLP_CK_SCP_SPI_SEL 3 +#define CLK_VLP_CK_SCP_IIC_SEL 4 +#define CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL 5 +#define CLK_VLP_CK_PWRAP_ULPOSC_SEL 6 +#define CLK_VLP_CK_SPMI_M_TIA_32K_SEL 7 +#define CLK_VLP_CK_APXGPT_26M_BCLK_SEL 8 +#define CLK_VLP_CK_DPSW_SEL 9 +#define CLK_VLP_CK_DPSW_CENTRAL_SEL 10 +#define CLK_VLP_CK_SPMI_M_MST_SEL 11 +#define CLK_VLP_CK_DVFSRC_SEL 12 +#define CLK_VLP_CK_PWM_VLP_SEL 13 +#define CLK_VLP_CK_AXI_VLP_SEL 14 +#define CLK_VLP_CK_SYSTIMER_26M_SEL 15 +#define CLK_VLP_CK_SSPM_SEL 16 +#define CLK_VLP_CK_SRCK_SEL 17 +#define CLK_VLP_CK_CAMTG0_SEL 18 +#define CLK_VLP_CK_CAMTG1_SEL 19 +#define CLK_VLP_CK_CAMTG2_SEL 20 +#define CLK_VLP_CK_CAMTG3_SEL 21 +#define CLK_VLP_CK_CAMTG4_SEL 22 +#define CLK_VLP_CK_CAMTG5_SEL 23 +#define CLK_VLP_CK_CAMTG6_SEL 24 +#define CLK_VLP_CK_CAMTG7_SEL 25 +#define CLK_VLP_CK_SSPM_26M_SEL 26 +#define CLK_VLP_CK_ULPOSC_SSPM_SEL 27 +#define CLK_VLP_CK_VLP_PBUS_26M_SEL 28 +#define CLK_VLP_CK_DEBUG_ERR_FLAG_SEL 29 +#define CLK_VLP_CK_DPMSRDMA_SEL 30 +#define CLK_VLP_CK_VLP_PBUS_156M_SEL 31 +#define CLK_VLP_CK_SPM_SEL 32 +#define CLK_VLP_CK_MMINFRA_VLP_SEL 33 +#define CLK_VLP_CK_USB_TOP_SEL 34 +#define CLK_VLP_CK_USB_XHCI_SEL 35 +#define CLK_VLP_CK_NOC_VLP_SEL 36 +#define CLK_VLP_CK_AUDIO_H_SEL 37 +#define CLK_VLP_CK_AUD_ENGEN1_SEL 38 +#define CLK_VLP_CK_AUD_ENGEN2_SEL 39 +#define CLK_VLP_CK_AUD_INTBUS_SEL 40 +#define CLK_VLP_CK_SPVLP_26M_SEL 41 +#define CLK_VLP_CK_SPU0_VLP_SEL 42 +#define CLK_VLP_CK_SPU1_VLP_SEL 43 +#define CLK_VLP_CK_OSC3 44 +#define CLK_VLP_CK_CLKSQ 45 +#define CLK_VLP_CK_AUDIO_H 46 +#define CLK_VLP_CK_AUD_ENGEN1 47 +#define CLK_VLP_CK_AUD_ENGEN2 48 +#define CLK_VLP_CK_INFRA_26M 49 +#define CLK_VLP_CK_AUD_CLKSQ 50 +#define CLK_VLP_CK_NR_CLK 51 + +/* SCP_I3C */ +#define CLK_SCP_I3C_I2C1 0 +#define CLK_SCP_I3C_I2C1_SCP_I2C 1 +#define CLK_SCP_I3C_NR_CLK 2 + +/* AFE */ +#define CLK_AFE_PCM1 0 +#define CLK_AFE_PCM1_AFE 1 +#define CLK_AFE_PCM0 2 +#define CLK_AFE_PCM0_AFE 3 +#define CLK_AFE_CM2 4 +#define CLK_AFE_CM2_AFE 5 +#define CLK_AFE_CM1 6 +#define CLK_AFE_CM1_AFE 7 +#define CLK_AFE_CM0 8 +#define CLK_AFE_CM0_AFE 9 +#define CLK_AFE_STF 10 +#define CLK_AFE_STF_AFE 11 +#define CLK_AFE_HW_GAIN23 12 +#define CLK_AFE_HW_GAIN23_AFE 13 +#define CLK_AFE_HW_GAIN01 14 +#define CLK_AFE_HW_GAIN01_AFE 15 +#define CLK_AFE_FM_I2S 16 +#define CLK_AFE_FM_I2S_AFE 17 +#define CLK_AFE_MTKAIFV4 18 +#define CLK_AFE_MTKAIFV4_AFE 19 +#define CLK_AFE_UL2_ADC_HIRES_TML 20 +#define CLK_AFE_UL2_ADC_HIRES_TML_AFE 21 +#define CLK_AFE_UL2_ADC_HIRES 22 +#define CLK_AFE_UL2_ADC_HIRES_AFE 23 +#define CLK_AFE_UL2_TML 24 +#define CLK_AFE_UL2_TML_AFE 25 +#define CLK_AFE_UL2_ADC 26 +#define CLK_AFE_UL2_ADC_AFE 27 +#define CLK_AFE_UL1_ADC_HIRES_TML 28 +#define CLK_AFE_UL1_ADC_HIRES_TML_AFE 29 +#define CLK_AFE_UL1_ADC_HIRES 30 +#define CLK_AFE_UL1_ADC_HIRES_AFE 31 +#define CLK_AFE_UL1_TML 32 +#define CLK_AFE_UL1_TML_AFE 33 +#define CLK_AFE_UL1_ADC 34 +#define CLK_AFE_UL1_ADC_AFE 35 +#define CLK_AFE_UL0_ADC_HIRES_TML 36 +#define CLK_AFE_UL0_ADC_HIRES_TML_AFE 37 +#define CLK_AFE_UL0_ADC_HIRES 38 +#define CLK_AFE_UL0_ADC_HIRES_AFE 39 +#define CLK_AFE_UL0_TML 40 +#define CLK_AFE_UL0_TML_AFE 41 +#define CLK_AFE_UL0_ADC 42 +#define CLK_AFE_UL0_ADC_AFE 43 +#define CLK_AFE_ETDM_IN6 44 +#define CLK_AFE_ETDM_IN6_AFE 45 +#define CLK_AFE_ETDM_IN5 46 +#define CLK_AFE_ETDM_IN5_AFE 47 +#define CLK_AFE_ETDM_IN4 48 +#define CLK_AFE_ETDM_IN4_AFE 49 +#define CLK_AFE_ETDM_IN3 50 +#define CLK_AFE_ETDM_IN3_AFE 51 +#define CLK_AFE_ETDM_IN2 52 +#define CLK_AFE_ETDM_IN2_AFE 53 +#define CLK_AFE_ETDM_IN1 54 +#define CLK_AFE_ETDM_IN1_AFE 55 +#define CLK_AFE_ETDM_IN0 56 +#define CLK_AFE_ETDM_IN0_AFE 57 +#define CLK_AFE_ETDM_OUT6 58 +#define CLK_AFE_ETDM_OUT6_AFE 59 +#define CLK_AFE_ETDM_OUT5 60 +#define CLK_AFE_ETDM_OUT5_AFE 61 +#define CLK_AFE_ETDM_OUT4 62 +#define CLK_AFE_ETDM_OUT4_AFE 63 +#define CLK_AFE_ETDM_OUT3 64 +#define CLK_AFE_ETDM_OUT3_AFE 65 +#define CLK_AFE_ETDM_OUT2 66 +#define CLK_AFE_ETDM_OUT2_AFE 67 +#define CLK_AFE_ETDM_OUT1 68 +#define CLK_AFE_ETDM_OUT1_AFE 69 +#define CLK_AFE_ETDM_OUT0 70 +#define CLK_AFE_ETDM_OUT0_AFE 71 +#define CLK_AFE_TDM_OUT 72 +#define CLK_AFE_TDM_OUT_AFE 73 +#define CLK_AFE_GENERAL15_ASRC 74 +#define CLK_AFE_GENERAL15_ASRC_AFE 75 +#define CLK_AFE_GENERAL14_ASRC 76 +#define CLK_AFE_GENERAL14_ASRC_AFE 77 +#define CLK_AFE_GENERAL13_ASRC 78 +#define CLK_AFE_GENERAL13_ASRC_AFE 79 +#define CLK_AFE_GENERAL12_ASRC 80 +#define CLK_AFE_GENERAL12_ASRC_AFE 81 +#define CLK_AFE_GENERAL11_ASRC 82 +#define CLK_AFE_GENERAL11_ASRC_AFE 83 +#define CLK_AFE_GENERAL10_ASRC 84 +#define CLK_AFE_GENERAL10_ASRC_AFE 85 +#define CLK_AFE_GENERAL9_ASRC 86 +#define CLK_AFE_GENERAL9_ASRC_AFE 87 +#define CLK_AFE_GENERAL8_ASRC 88 +#define CLK_AFE_GENERAL8_ASRC_AFE 89 +#define CLK_AFE_GENERAL7_ASRC 90 +#define CLK_AFE_GENERAL7_ASRC_AFE 91 +#define CLK_AFE_GENERAL6_ASRC 92 +#define CLK_AFE_GENERAL6_ASRC_AFE 93 +#define CLK_AFE_GENERAL5_ASRC 94 +#define CLK_AFE_GENERAL5_ASRC_AFE 95 +#define CLK_AFE_GENERAL4_ASRC 96 +#define CLK_AFE_GENERAL4_ASRC_AFE 97 +#define CLK_AFE_GENERAL3_ASRC 98 +#define CLK_AFE_GENERAL3_ASRC_AFE 99 +#define CLK_AFE_GENERAL2_ASRC 100 +#define CLK_AFE_GENERAL2_ASRC_AFE 101 +#define CLK_AFE_GENERAL1_ASRC 102 +#define CLK_AFE_GENERAL1_ASRC_AFE 103 +#define CLK_AFE_GENERAL0_ASRC 104 +#define CLK_AFE_GENERAL0_ASRC_AFE 105 +#define CLK_AFE_CONNSYS_I2S_ASRC 106 +#define CLK_AFE_CONNSYS_I2S_ASRC_AFE 107 +#define CLK_AFE_AUDIO_HOPPING 108 +#define CLK_AFE_AUDIO_HOPPING_AFE 109 +#define CLK_AFE_AUDIO_F26M 110 +#define CLK_AFE_AUDIO_F26M_AFE 111 +#define CLK_AFE_APLL1 112 +#define CLK_AFE_APLL1_AFE 113 +#define CLK_AFE_APLL2 114 +#define CLK_AFE_APLL2_AFE 115 +#define CLK_AFE_H208M 116 +#define CLK_AFE_H208M_AFE 117 +#define CLK_AFE_APLL_TUNER2 118 +#define CLK_AFE_APLL_TUNER2_AFE 119 +#define CLK_AFE_APLL_TUNER1 120 +#define CLK_AFE_APLL_TUNER1_AFE 121 +#define CLK_AFE_NR_CLK 122 + +/* DISPSYS_CONFIG */ +#define CLK_MM_CONFIG 0 +#define CLK_MM_CONFIG_DISP 1 +#define CLK_MM_DISP_MUTEX0 2 +#define CLK_MM_DISP_MUTEX0_DISP 3 +#define CLK_MM_DISP_AAL0 4 +#define CLK_MM_DISP_AAL0_PQ 5 +#define CLK_MM_DISP_AAL1 6 +#define CLK_MM_DISP_AAL1_PQ 7 +#define CLK_MM_DISP_C3D0 8 +#define CLK_MM_DISP_C3D0_PQ 9 +#define CLK_MM_DISP_C3D1 10 +#define CLK_MM_DISP_C3D1_PQ 11 +#define CLK_MM_DISP_C3D2 12 +#define CLK_MM_DISP_C3D2_PQ 13 +#define CLK_MM_DISP_C3D3 14 +#define CLK_MM_DISP_C3D3_PQ 15 +#define CLK_MM_DISP_CCORR0 16 +#define CLK_MM_DISP_CCORR0_PQ 17 +#define CLK_MM_DISP_CCORR1 18 +#define CLK_MM_DISP_CCORR1_PQ 19 +#define CLK_MM_DISP_CCORR2 20 +#define CLK_MM_DISP_CCORR2_PQ 21 +#define CLK_MM_DISP_CCORR3 22 +#define CLK_MM_DISP_CCORR3_PQ 23 +#define CLK_MM_DISP_CHIST0 24 +#define CLK_MM_DISP_CHIST0_PQ 25 +#define CLK_MM_DISP_CHIST1 26 +#define CLK_MM_DISP_CHIST1_PQ 27 +#define CLK_MM_DISP_COLOR0 28 +#define CLK_MM_DISP_COLOR0_PQ 29 +#define CLK_MM_DISP_COLOR1 30 +#define CLK_MM_DISP_COLOR1_PQ 31 +#define CLK_MM_DISP_DITHER0 32 +#define CLK_MM_DISP_DITHER0_PQ 33 +#define CLK_MM_DISP_DITHER1 34 +#define CLK_MM_DISP_DITHER1_PQ 35 +#define CLK_MM_DISP_DLI_ASYNC0 36 +#define CLK_MM_DISP_DLI_ASYNC0_DISP 37 +#define CLK_MM_DISP_DLI_ASYNC1 38 +#define CLK_MM_DISP_DLI_ASYNC1_DISP 39 +#define CLK_MM_DISP_DLI_ASYNC2 40 +#define CLK_MM_DISP_DLI_ASYNC2_DISP 41 +#define CLK_MM_DISP_DLI_ASYNC3 42 +#define CLK_MM_DISP_DLI_ASYNC3_DISP 43 +#define CLK_MM_DISP_DLI_ASYNC4 44 +#define CLK_MM_DISP_DLI_ASYNC4_DISP 45 +#define CLK_MM_DISP_DLI_ASYNC5 46 +#define CLK_MM_DISP_DLI_ASYNC5_DISP 47 +#define CLK_MM_DISP_DLI_ASYNC6 48 +#define CLK_MM_DISP_DLI_ASYNC6_DISP 49 +#define CLK_MM_DISP_DLI_ASYNC7 50 +#define CLK_MM_DISP_DLI_ASYNC7_DISP 51 +#define CLK_MM_DISP_DLI_ASYNC8 52 +#define CLK_MM_DISP_DLI_ASYNC8_DISP 53 +#define CLK_MM_DISP_DLI_ASYNC9 54 +#define CLK_MM_DISP_DLI_ASYNC9_DISP 55 +#define CLK_MM_DISP_DLI_ASYNC10 56 +#define CLK_MM_DISP_DLI_ASYNC10_DISP 57 +#define CLK_MM_DISP_DLI_ASYNC11 58 +#define CLK_MM_DISP_DLI_ASYNC11_DISP 59 +#define CLK_MM_DISP_DLI_ASYNC12 60 +#define CLK_MM_DISP_DLI_ASYNC12_DISP 61 +#define CLK_MM_DISP_DLI_ASYNC13 62 +#define CLK_MM_DISP_DLI_ASYNC13_DISP 63 +#define CLK_MM_DISP_DLI_ASYNC14 64 +#define CLK_MM_DISP_DLI_ASYNC14_DISP 65 +#define CLK_MM_DISP_DLI_ASYNC15 66 +#define CLK_MM_DISP_DLI_ASYNC15_DISP 67 +#define CLK_MM_DISP_DLO_ASYNC0 68 +#define CLK_MM_DISP_DLO_ASYNC0_DISP 69 +#define CLK_MM_DISP_DLO_ASYNC1 70 +#define CLK_MM_DISP_DLO_ASYNC1_DISP 71 +#define CLK_MM_DISP_DLO_ASYNC2 72 +#define CLK_MM_DISP_DLO_ASYNC2_DISP 73 +#define CLK_MM_DISP_DLO_ASYNC3 74 +#define CLK_MM_DISP_DLO_ASYNC3_DISP 75 +#define CLK_MM_DISP_DLO_ASYNC4 76 +#define CLK_MM_DISP_DLO_ASYNC4_DISP 77 +#define CLK_MM_DISP_DLO_ASYNC5 78 +#define CLK_MM_DISP_DLO_ASYNC5_DISP 79 +#define CLK_MM_DISP_DLO_ASYNC6 80 +#define CLK_MM_DISP_DLO_ASYNC6_DISP 81 +#define CLK_MM_DISP_DLO_ASYNC7 82 +#define CLK_MM_DISP_DLO_ASYNC7_DISP 83 +#define CLK_MM_DISP_DLO_ASYNC8 84 +#define CLK_MM_DISP_DLO_ASYNC8_DISP 85 +#define CLK_MM_DISP_GAMMA0 86 +#define CLK_MM_DISP_GAMMA0_PQ 87 +#define CLK_MM_DISP_GAMMA1 88 +#define CLK_MM_DISP_GAMMA1_PQ 89 +#define CLK_MM_MDP_AAL0 90 +#define CLK_MM_MDP_AAL0_PQ 91 +#define CLK_MM_MDP_AAL1 92 +#define CLK_MM_MDP_AAL1_PQ 93 +#define CLK_MM_MDP_RDMA0 94 +#define CLK_MM_MDP_RDMA0_DISP 95 +#define CLK_MM_DISP_POSTMASK0 96 +#define CLK_MM_DISP_POSTMASK0_DISP 97 +#define CLK_MM_DISP_POSTMASK1 98 +#define CLK_MM_DISP_POSTMASK1_DISP 99 +#define CLK_MM_MDP_RSZ0 100 +#define CLK_MM_MDP_RSZ0_DISP 101 +#define CLK_MM_MDP_RSZ1 102 +#define CLK_MM_MDP_RSZ1_DISP 103 +#define CLK_MM_DISP_SPR0 104 +#define CLK_MM_DISP_SPR0_DISP 105 +#define CLK_MM_DISP_TDSHP0 106 +#define CLK_MM_DISP_TDSHP0_PQ 107 +#define CLK_MM_DISP_TDSHP1 108 +#define CLK_MM_DISP_TDSHP1_PQ 109 +#define CLK_MM_DISP_WDMA0 110 +#define CLK_MM_DISP_WDMA0_DISP 111 +#define CLK_MM_DISP_Y2R0 112 +#define CLK_MM_DISP_Y2R0_DISP 113 +#define CLK_MM_SMI_SUB_COMM0 114 +#define CLK_MM_SMI_SUB_COMM0_SMI 115 +#define CLK_MM_DISP_FAKE_ENG0 116 +#define CLK_MM_DISP_FAKE_ENG0_DISP 117 +#define CLK_MM_NR_CLK 118 + +/* DISPSYS1_CONFIG */ +#define CLK_MM1_DISPSYS1_CONFIG 0 +#define CLK_MM1_DISPSYS1_CONFIG_DISP 1 +#define CLK_MM1_DISPSYS1_S_CONFIG 2 +#define CLK_MM1_DISPSYS1_S_CONFIG_DISP 3 +#define CLK_MM1_DISP_MUTEX0 4 +#define CLK_MM1_DISP_MUTEX0_DISP 5 +#define CLK_MM1_DISP_DLI_ASYNC20 6 +#define CLK_MM1_DISP_DLI_ASYNC20_DISP 7 +#define CLK_MM1_DISP_DLI_ASYNC21 8 +#define CLK_MM1_DISP_DLI_ASYNC21_DISP 9 +#define CLK_MM1_DISP_DLI_ASYNC22 10 +#define CLK_MM1_DISP_DLI_ASYNC22_DISP 11 +#define CLK_MM1_DISP_DLI_ASYNC23 12 +#define CLK_MM1_DISP_DLI_ASYNC23_DISP 13 +#define CLK_MM1_DISP_DLI_ASYNC24 14 +#define CLK_MM1_DISP_DLI_ASYNC24_DISP 15 +#define CLK_MM1_DISP_DLI_ASYNC25 16 +#define CLK_MM1_DISP_DLI_ASYNC25_DISP 17 +#define CLK_MM1_DISP_DLI_ASYNC26 18 +#define CLK_MM1_DISP_DLI_ASYNC26_DISP 19 +#define CLK_MM1_DISP_DLI_ASYNC27 20 +#define CLK_MM1_DISP_DLI_ASYNC27_DISP 21 +#define CLK_MM1_DISP_DLI_ASYNC28 22 +#define CLK_MM1_DISP_DLI_ASYNC28_DISP 23 +#define CLK_MM1_DISP_RELAY0 24 +#define CLK_MM1_DISP_RELAY0_DISP 25 +#define CLK_MM1_DISP_RELAY1 26 +#define CLK_MM1_DISP_RELAY1_DISP 27 +#define CLK_MM1_DISP_RELAY2 28 +#define CLK_MM1_DISP_RELAY2_DISP 29 +#define CLK_MM1_DISP_RELAY3 30 +#define CLK_MM1_DISP_RELAY3_DISP 31 +#define CLK_MM1_DISP_DP_INTF0 32 +#define CLK_MM1_DISP_DP_INTF0_DISP 33 +#define CLK_MM1_DISP_DP_INTF1 34 +#define CLK_MM1_DISP_DP_INTF1_DISP 35 +#define CLK_MM1_DISP_DSC_WRAP0 36 +#define CLK_MM1_DISP_DSC_WRAP0_DISP 37 +#define CLK_MM1_DISP_DSC_WRAP1 38 +#define CLK_MM1_DISP_DSC_WRAP1_DISP 39 +#define CLK_MM1_DISP_DSC_WRAP2 40 +#define CLK_MM1_DISP_DSC_WRAP2_DISP 41 +#define CLK_MM1_DISP_DSC_WRAP3 42 +#define CLK_MM1_DISP_DSC_WRAP3_DISP 43 +#define CLK_MM1_DISP_DSI0 44 +#define CLK_MM1_DISP_DSI0_DISP 45 +#define CLK_MM1_DISP_DSI1 46 +#define CLK_MM1_DISP_DSI1_DISP 47 +#define CLK_MM1_DISP_DSI2 48 +#define CLK_MM1_DISP_DSI2_DISP 49 +#define CLK_MM1_DISP_DVO0 50 +#define CLK_MM1_DISP_DVO0_DISP 51 +#define CLK_MM1_DISP_GDMA0 52 +#define CLK_MM1_DISP_GDMA0_DISP 53 +#define CLK_MM1_DISP_MERGE0 54 +#define CLK_MM1_DISP_MERGE0_DISP 55 +#define CLK_MM1_DISP_MERGE1 56 +#define CLK_MM1_DISP_MERGE1_DISP 57 +#define CLK_MM1_DISP_MERGE2 58 +#define CLK_MM1_DISP_MERGE2_DISP 59 +#define CLK_MM1_DISP_ODDMR0 60 +#define CLK_MM1_DISP_ODDMR0_PQ 61 +#define CLK_MM1_DISP_POSTALIGN0 62 +#define CLK_MM1_DISP_POSTALIGN0_PQ 63 +#define CLK_MM1_DISP_DITHER2 64 +#define CLK_MM1_DISP_DITHER2_PQ 65 +#define CLK_MM1_DISP_R2Y0 66 +#define CLK_MM1_DISP_R2Y0_DISP 67 +#define CLK_MM1_DISP_SPLITTER0 68 +#define CLK_MM1_DISP_SPLITTER0_DISP 69 +#define CLK_MM1_DISP_SPLITTER1 70 +#define CLK_MM1_DISP_SPLITTER1_DISP 71 +#define CLK_MM1_DISP_SPLITTER2 72 +#define CLK_MM1_DISP_SPLITTER2_DISP 73 +#define CLK_MM1_DISP_SPLITTER3 74 +#define CLK_MM1_DISP_SPLITTER3_DISP 75 +#define CLK_MM1_DISP_VDCM0 76 +#define CLK_MM1_DISP_VDCM0_DISP 77 +#define CLK_MM1_DISP_WDMA1 78 +#define CLK_MM1_DISP_WDMA1_DISP 79 +#define CLK_MM1_DISP_WDMA2 80 +#define CLK_MM1_DISP_WDMA2_DISP 81 +#define CLK_MM1_DISP_WDMA3 82 +#define CLK_MM1_DISP_WDMA3_DISP 83 +#define CLK_MM1_DISP_WDMA4 84 +#define CLK_MM1_DISP_WDMA4_DISP 85 +#define CLK_MM1_MDP_RDMA1 86 +#define CLK_MM1_MDP_RDMA1_DISP 87 +#define CLK_MM1_SMI_LARB0 88 +#define CLK_MM1_SMI_LARB0_SMI 89 +#define CLK_MM1_MOD1 90 +#define CLK_MM1_MOD1_DISP 91 +#define CLK_MM1_MOD2 92 +#define CLK_MM1_MOD2_DISP 93 +#define CLK_MM1_MOD3 94 +#define CLK_MM1_MOD3_DISP 95 +#define CLK_MM1_MOD4 96 +#define CLK_MM1_MOD4_DISP 97 +#define CLK_MM1_MOD5 98 +#define CLK_MM1_MOD5_DISP 99 +#define CLK_MM1_MOD6 100 +#define CLK_MM1_MOD6_DISP 101 +#define CLK_MM1_CK_CG0 102 +#define CLK_MM1_CK_CG0_DISP 103 +#define CLK_MM1_CK_CG1 104 +#define CLK_MM1_CK_CG1_DISP 105 +#define CLK_MM1_CK_CG2 106 +#define CLK_MM1_CK_CG2_DISP 107 +#define CLK_MM1_CK_CG3 108 +#define CLK_MM1_CK_CG3_DISP 109 +#define CLK_MM1_CK_CG4 110 +#define CLK_MM1_CK_CG4_DISP 111 +#define CLK_MM1_CK_CG5 112 +#define CLK_MM1_CK_CG5_DISP 113 +#define CLK_MM1_CK_CG6 114 +#define CLK_MM1_CK_CG6_DISP 115 +#define CLK_MM1_CK_CG7 116 +#define CLK_MM1_CK_CG7_DISP 117 +#define CLK_MM1_F26M 118 +#define CLK_MM1_F26M_DISP 119 +#define CLK_MM1_NR_CLK 120 + +/* OVLSYS_CONFIG */ +#define CLK_OVLSYS_CONFIG 0 +#define CLK_OVLSYS_CONFIG_DISP 1 +#define CLK_OVL_FAKE_ENG0 2 +#define CLK_OVL_FAKE_ENG0_DISP 3 +#define CLK_OVL_FAKE_ENG1 4 +#define CLK_OVL_FAKE_ENG1_DISP 5 +#define CLK_OVL_MUTEX0 6 +#define CLK_OVL_MUTEX0_DISP 7 +#define CLK_OVL_EXDMA0 8 +#define CLK_OVL_EXDMA0_DISP 9 +#define CLK_OVL_EXDMA1 10 +#define CLK_OVL_EXDMA1_DISP 11 +#define CLK_OVL_EXDMA2 12 +#define CLK_OVL_EXDMA2_DISP 13 +#define CLK_OVL_EXDMA3 14 +#define CLK_OVL_EXDMA3_DISP 15 +#define CLK_OVL_EXDMA4 16 +#define CLK_OVL_EXDMA4_DISP 17 +#define CLK_OVL_EXDMA5 18 +#define CLK_OVL_EXDMA5_DISP 19 +#define CLK_OVL_EXDMA6 20 +#define CLK_OVL_EXDMA6_DISP 21 +#define CLK_OVL_EXDMA7 22 +#define CLK_OVL_EXDMA7_DISP 23 +#define CLK_OVL_EXDMA8 24 +#define CLK_OVL_EXDMA8_DISP 25 +#define CLK_OVL_EXDMA9 26 +#define CLK_OVL_EXDMA9_DISP 27 +#define CLK_OVL_BLENDER0 28 +#define CLK_OVL_BLENDER0_DISP 29 +#define CLK_OVL_BLENDER1 30 +#define CLK_OVL_BLENDER1_DISP 31 +#define CLK_OVL_BLENDER2 32 +#define CLK_OVL_BLENDER2_DISP 33 +#define CLK_OVL_BLENDER3 34 +#define CLK_OVL_BLENDER3_DISP 35 +#define CLK_OVL_BLENDER4 36 +#define CLK_OVL_BLENDER4_DISP 37 +#define CLK_OVL_BLENDER5 38 +#define CLK_OVL_BLENDER5_DISP 39 +#define CLK_OVL_BLENDER6 40 +#define CLK_OVL_BLENDER6_DISP 41 +#define CLK_OVL_BLENDER7 42 +#define CLK_OVL_BLENDER7_DISP 43 +#define CLK_OVL_BLENDER8 44 +#define CLK_OVL_BLENDER8_DISP 45 +#define CLK_OVL_BLENDER9 46 +#define CLK_OVL_BLENDER9_DISP 47 +#define CLK_OVL_OUTPROC0 48 +#define CLK_OVL_OUTPROC0_DISP 49 +#define CLK_OVL_OUTPROC1 50 +#define CLK_OVL_OUTPROC1_DISP 51 +#define CLK_OVL_OUTPROC2 52 +#define CLK_OVL_OUTPROC2_DISP 53 +#define CLK_OVL_OUTPROC3 54 +#define CLK_OVL_OUTPROC3_DISP 55 +#define CLK_OVL_OUTPROC4 56 +#define CLK_OVL_OUTPROC4_DISP 57 +#define CLK_OVL_OUTPROC5 58 +#define CLK_OVL_OUTPROC5_DISP 59 +#define CLK_OVL_MDP_RSZ0 60 +#define CLK_OVL_MDP_RSZ0_DISP 61 +#define CLK_OVL_MDP_RSZ1 62 +#define CLK_OVL_MDP_RSZ1_DISP 63 +#define CLK_OVL_DISP_WDMA0 64 +#define CLK_OVL_DISP_WDMA0_DISP 65 +#define CLK_OVL_DISP_WDMA1 66 +#define CLK_OVL_DISP_WDMA1_DISP 67 +#define CLK_OVL_UFBC_WDMA0 68 +#define CLK_OVL_UFBC_WDMA0_DISP 69 +#define CLK_OVL_MDP_RDMA0 70 +#define CLK_OVL_MDP_RDMA0_DISP 71 +#define CLK_OVL_MDP_RDMA1 72 +#define CLK_OVL_MDP_RDMA1_DISP 73 +#define CLK_OVL_BWM0 74 +#define CLK_OVL_BWM0_DISP 75 +#define CLK_OVL_DLI0 76 +#define CLK_OVL_DLI0_DISP 77 +#define CLK_OVL_DLI1 78 +#define CLK_OVL_DLI1_DISP 79 +#define CLK_OVL_DLI2 80 +#define CLK_OVL_DLI2_DISP 81 +#define CLK_OVL_DLI3 82 +#define CLK_OVL_DLI3_DISP 83 +#define CLK_OVL_DLI4 84 +#define CLK_OVL_DLI4_DISP 85 +#define CLK_OVL_DLI5 86 +#define CLK_OVL_DLI5_DISP 87 +#define CLK_OVL_DLI6 88 +#define CLK_OVL_DLI6_DISP 89 +#define CLK_OVL_DLI7 90 +#define CLK_OVL_DLI7_DISP 91 +#define CLK_OVL_DLI8 92 +#define CLK_OVL_DLI8_DISP 93 +#define CLK_OVL_DLO0 94 +#define CLK_OVL_DLO0_DISP 95 +#define CLK_OVL_DLO1 96 +#define CLK_OVL_DLO1_DISP 97 +#define CLK_OVL_DLO2 98 +#define CLK_OVL_DLO2_DISP 99 +#define CLK_OVL_DLO3 100 +#define CLK_OVL_DLO3_DISP 101 +#define CLK_OVL_DLO4 102 +#define CLK_OVL_DLO4_DISP 103 +#define CLK_OVL_DLO5 104 +#define CLK_OVL_DLO5_DISP 105 +#define CLK_OVL_DLO6 106 +#define CLK_OVL_DLO6_DISP 107 +#define CLK_OVL_DLO7 108 +#define CLK_OVL_DLO7_DISP 109 +#define CLK_OVL_DLO8 110 +#define CLK_OVL_DLO8_DISP 111 +#define CLK_OVL_DLO9 112 +#define CLK_OVL_DLO9_DISP 113 +#define CLK_OVL_DLO10 114 +#define CLK_OVL_DLO10_DISP 115 +#define CLK_OVL_DLO11 116 +#define CLK_OVL_DLO11_DISP 117 +#define CLK_OVL_DLO12 118 +#define CLK_OVL_DLO12_DISP 119 +#define CLK_OVLSYS_RELAY0 120 +#define CLK_OVLSYS_RELAY0_DISP 121 +#define CLK_OVL_INLINEROT0 122 +#define CLK_OVL_INLINEROT0_DISP 123 +#define CLK_OVL_SMI 124 +#define CLK_OVL_SMI_SMI 125 +#define CLK_OVL_NR_CLK 126 + +/* OVLSYS1_CONFIG */ +#define CLK_OVL1_OVLSYS_CONFIG 0 +#define CLK_OVL1_OVLSYS_CONFIG_DISP 1 +#define CLK_OVL1_OVL_FAKE_ENG0 2 +#define CLK_OVL1_OVL_FAKE_ENG0_DISP 3 +#define CLK_OVL1_OVL_FAKE_ENG1 4 +#define CLK_OVL1_OVL_FAKE_ENG1_DISP 5 +#define CLK_OVL1_OVL_MUTEX0 6 +#define CLK_OVL1_OVL_MUTEX0_DISP 7 +#define CLK_OVL1_OVL_EXDMA0 8 +#define CLK_OVL1_OVL_EXDMA0_DISP 9 +#define CLK_OVL1_OVL_EXDMA1 10 +#define CLK_OVL1_OVL_EXDMA1_DISP 11 +#define CLK_OVL1_OVL_EXDMA2 12 +#define CLK_OVL1_OVL_EXDMA2_DISP 13 +#define CLK_OVL1_OVL_EXDMA3 14 +#define CLK_OVL1_OVL_EXDMA3_DISP 15 +#define CLK_OVL1_OVL_EXDMA4 16 +#define CLK_OVL1_OVL_EXDMA4_DISP 17 +#define CLK_OVL1_OVL_EXDMA5 18 +#define CLK_OVL1_OVL_EXDMA5_DISP 19 +#define CLK_OVL1_OVL_EXDMA6 20 +#define CLK_OVL1_OVL_EXDMA6_DISP 21 +#define CLK_OVL1_OVL_EXDMA7 22 +#define CLK_OVL1_OVL_EXDMA7_DISP 23 +#define CLK_OVL1_OVL_EXDMA8 24 +#define CLK_OVL1_OVL_EXDMA8_DISP 25 +#define CLK_OVL1_OVL_EXDMA9 26 +#define CLK_OVL1_OVL_EXDMA9_DISP 27 +#define CLK_OVL1_OVL_BLENDER0 28 +#define CLK_OVL1_OVL_BLENDER0_DISP 29 +#define CLK_OVL1_OVL_BLENDER1 30 +#define CLK_OVL1_OVL_BLENDER1_DISP 31 +#define CLK_OVL1_OVL_BLENDER2 32 +#define CLK_OVL1_OVL_BLENDER2_DISP 33 +#define CLK_OVL1_OVL_BLENDER3 34 +#define CLK_OVL1_OVL_BLENDER3_DISP 35 +#define CLK_OVL1_OVL_BLENDER4 36 +#define CLK_OVL1_OVL_BLENDER4_DISP 37 +#define CLK_OVL1_OVL_BLENDER5 38 +#define CLK_OVL1_OVL_BLENDER5_DISP 39 +#define CLK_OVL1_OVL_BLENDER6 40 +#define CLK_OVL1_OVL_BLENDER6_DISP 41 +#define CLK_OVL1_OVL_BLENDER7 42 +#define CLK_OVL1_OVL_BLENDER7_DISP 43 +#define CLK_OVL1_OVL_BLENDER8 44 +#define CLK_OVL1_OVL_BLENDER8_DISP 45 +#define CLK_OVL1_OVL_BLENDER9 46 +#define CLK_OVL1_OVL_BLENDER9_DISP 47 +#define CLK_OVL1_OVL_OUTPROC0 48 +#define CLK_OVL1_OVL_OUTPROC0_DISP 49 +#define CLK_OVL1_OVL_OUTPROC1 50 +#define CLK_OVL1_OVL_OUTPROC1_DISP 51 +#define CLK_OVL1_OVL_OUTPROC2 52 +#define CLK_OVL1_OVL_OUTPROC2_DISP 53 +#define CLK_OVL1_OVL_OUTPROC3 54 +#define CLK_OVL1_OVL_OUTPROC3_DISP 55 +#define CLK_OVL1_OVL_OUTPROC4 56 +#define CLK_OVL1_OVL_OUTPROC4_DISP 57 +#define CLK_OVL1_OVL_OUTPROC5 58 +#define CLK_OVL1_OVL_OUTPROC5_DISP 59 +#define CLK_OVL1_OVL_MDP_RSZ0 60 +#define CLK_OVL1_OVL_MDP_RSZ0_DISP 61 +#define CLK_OVL1_OVL_MDP_RSZ1 62 +#define CLK_OVL1_OVL_MDP_RSZ1_DISP 63 +#define CLK_OVL1_OVL_DISP_WDMA0 64 +#define CLK_OVL1_OVL_DISP_WDMA0_DISP 65 +#define CLK_OVL1_OVL_DISP_WDMA1 66 +#define CLK_OVL1_OVL_DISP_WDMA1_DISP 67 +#define CLK_OVL1_OVL_UFBC_WDMA0 68 +#define CLK_OVL1_OVL_UFBC_WDMA0_DISP 69 +#define CLK_OVL1_OVL_MDP_RDMA0 70 +#define CLK_OVL1_OVL_MDP_RDMA0_DISP 71 +#define CLK_OVL1_OVL_MDP_RDMA1 72 +#define CLK_OVL1_OVL_MDP_RDMA1_DISP 73 +#define CLK_OVL1_OVL_BWM0 74 +#define CLK_OVL1_OVL_BWM0_DISP 75 +#define CLK_OVL1_DLI0 76 +#define CLK_OVL1_DLI0_DISP 77 +#define CLK_OVL1_DLI1 78 +#define CLK_OVL1_DLI1_DISP 79 +#define CLK_OVL1_DLI2 80 +#define CLK_OVL1_DLI2_DISP 81 +#define CLK_OVL1_DLI3 82 +#define CLK_OVL1_DLI3_DISP 83 +#define CLK_OVL1_DLI4 84 +#define CLK_OVL1_DLI4_DISP 85 +#define CLK_OVL1_DLI5 86 +#define CLK_OVL1_DLI5_DISP 87 +#define CLK_OVL1_DLI6 88 +#define CLK_OVL1_DLI6_DISP 89 +#define CLK_OVL1_DLI7 90 +#define CLK_OVL1_DLI7_DISP 91 +#define CLK_OVL1_DLI8 92 +#define CLK_OVL1_DLI8_DISP 93 +#define CLK_OVL1_DLO0 94 +#define CLK_OVL1_DLO0_DISP 95 +#define CLK_OVL1_DLO1 96 +#define CLK_OVL1_DLO1_DISP 97 +#define CLK_OVL1_DLO2 98 +#define CLK_OVL1_DLO2_DISP 99 +#define CLK_OVL1_DLO3 100 +#define CLK_OVL1_DLO3_DISP 101 +#define CLK_OVL1_DLO4 102 +#define CLK_OVL1_DLO4_DISP 103 +#define CLK_OVL1_DLO5 104 +#define CLK_OVL1_DLO5_DISP 105 +#define CLK_OVL1_DLO6 106 +#define CLK_OVL1_DLO6_DISP 107 +#define CLK_OVL1_DLO7 108 +#define CLK_OVL1_DLO7_DISP 109 +#define CLK_OVL1_DLO8 110 +#define CLK_OVL1_DLO8_DISP 111 +#define CLK_OVL1_DLO9 112 +#define CLK_OVL1_DLO9_DISP 113 +#define CLK_OVL1_DLO10 114 +#define CLK_OVL1_DLO10_DISP 115 +#define CLK_OVL1_DLO11 116 +#define CLK_OVL1_DLO11_DISP 117 +#define CLK_OVL1_DLO12 118 +#define CLK_OVL1_DLO12_DISP 119 +#define CLK_OVL1_OVLSYS_RELAY0 120 +#define CLK_OVL1_OVLSYS_RELAY0_DISP 121 +#define CLK_OVL1_OVL_INLINEROT0 122 +#define CLK_OVL1_OVL_INLINEROT0_DISP 123 +#define CLK_OVL1_SMI 124 +#define CLK_OVL1_SMI_SMI 125 +#define CLK_OVL1_NR_CLK 126 + +/* VDEC_SOC_GCON_BASE */ +#define CLK_VDE1_LARB1_CKEN 0 +#define CLK_VDE1_LARB1_CKEN_VDEC 1 +#define CLK_VDE1_LARB1_CKEN_SMI 2 +#define CLK_VDE1_LAT_CKEN 3 +#define CLK_VDE1_LAT_CKEN_VDEC 4 +#define CLK_VDE1_LAT_ACTIVE 5 +#define CLK_VDE1_LAT_ACTIVE_VDEC 6 +#define CLK_VDE1_LAT_CKEN_ENG 7 +#define CLK_VDE1_LAT_CKEN_ENG_VDEC 8 +#define CLK_VDE1_VDEC_CKEN 9 +#define CLK_VDE1_VDEC_CKEN_VDEC 10 +#define CLK_VDE1_VDEC_ACTIVE 11 +#define CLK_VDE1_VDEC_ACTIVE_VDEC 12 +#define CLK_VDE1_VDEC_CKEN_ENG 13 +#define CLK_VDE1_VDEC_CKEN_ENG_VDEC 14 +#define CLK_VDE1_VDEC_SOC_APTV_EN 15 +#define CLK_VDE1_VDEC_SOC_APTV_EN_VDEC 16 +#define CLK_VDE1_VDEC_SOC_APTV_TOP_EN 17 +#define CLK_VDE1_VDEC_SOC_APTV_TOP_EN_VDEC 18 +#define CLK_VDE1_VDEC_SOC_IPS_EN 19 +#define CLK_VDE1_VDEC_SOC_IPS_EN_VDEC 20 +#define CLK_VDE1_NR_CLK 21 + +/* VDEC_GCON_BASE */ +#define CLK_VDE2_LARB1_CKEN 0 +#define CLK_VDE2_LARB1_CKEN_VDEC 1 +#define CLK_VDE2_LARB1_CKEN_SMI 2 +#define CLK_VDE2_LAT_CKEN 3 +#define CLK_VDE2_LAT_CKEN_VDEC 4 +#define CLK_VDE2_LAT_ACTIVE 5 +#define CLK_VDE2_LAT_ACTIVE_VDEC 6 +#define CLK_VDE2_LAT_CKEN_ENG 7 +#define CLK_VDE2_LAT_CKEN_ENG_VDEC 8 +#define CLK_VDE2_VDEC_CKEN 9 +#define CLK_VDE2_VDEC_CKEN_VDEC 10 +#define CLK_VDE2_VDEC_ACTIVE 11 +#define CLK_VDE2_VDEC_ACTIVE_VDEC 12 +#define CLK_VDE2_VDEC_CKEN_ENG 13 +#define CLK_VDE2_VDEC_CKEN_ENG_VDEC 14 +#define CLK_VDE2_NR_CLK 15 + +/* VENC_GCON */ +#define CLK_VEN1_CKE0_LARB 0 +#define CLK_VEN1_CKE0_LARB_VENC 1 +#define CLK_VEN1_CKE0_LARB_JPGENC 2 +#define CLK_VEN1_CKE0_LARB_JPGDEC 3 +#define CLK_VEN1_CKE0_LARB_SMI 4 +#define CLK_VEN1_CKE1_VENC 5 +#define CLK_VEN1_CKE1_VENC_VENC 6 +#define CLK_VEN1_CKE1_VENC_SMI 7 +#define CLK_VEN1_CKE2_JPGENC 8 +#define CLK_VEN1_CKE2_JPGENC_JPGENC 9 +#define CLK_VEN1_CKE3_JPGDEC 10 +#define CLK_VEN1_CKE3_JPGDEC_JPGDEC 11 +#define CLK_VEN1_CKE4_JPGDEC_C1 12 +#define CLK_VEN1_CKE4_JPGDEC_C1_JPGDEC 13 +#define CLK_VEN1_CKE5_GALS 14 +#define CLK_VEN1_CKE5_GALS_VENC 15 +#define CLK_VEN1_CKE5_GALS_JPGENC 16 +#define CLK_VEN1_CKE5_GALS_JPGDEC 17 +#define CLK_VEN1_CKE29_VENC_ADAB_CTRL 18 +#define CLK_VEN1_CKE29_VENC_ADAB_CTRL_VENC 19 +#define CLK_VEN1_CKE29_VENC_XPC_CTRL 20 +#define CLK_VEN1_CKE29_VENC_XPC_CTRL_VENC 21 +#define CLK_VEN1_CKE29_VENC_XPC_CTRL_JPGENC 22 +#define CLK_VEN1_CKE29_VENC_XPC_CTRL_JPGDEC 23 +#define CLK_VEN1_CKE6_GALS_SRAM 24 +#define CLK_VEN1_CKE6_GALS_SRAM_VENC 25 +#define CLK_VEN1_RES_FLAT 26 +#define CLK_VEN1_RES_FLAT_VENC 27 +#define CLK_VEN1_RES_FLAT_JPGENC 28 +#define CLK_VEN1_RES_FLAT_JPGDEC 29 +#define CLK_VEN1_NR_CLK 30 + +/* VENC_GCON_CORE1 */ +#define CLK_VEN2_CKE0_LARB 0 +#define CLK_VEN2_CKE0_LARB_VENC 1 +#define CLK_VEN2_CKE0_LARB_JPGENC 2 +#define CLK_VEN2_CKE0_LARB_JPGDEC 3 +#define CLK_VEN2_CKE0_LARB_SMI 4 +#define CLK_VEN2_CKE1_VENC 5 +#define CLK_VEN2_CKE1_VENC_VENC 6 +#define CLK_VEN2_CKE1_VENC_SMI 7 +#define CLK_VEN2_CKE2_JPGENC 8 +#define CLK_VEN2_CKE2_JPGENC_JPGENC 9 +#define CLK_VEN2_CKE3_JPGDEC 10 +#define CLK_VEN2_CKE3_JPGDEC_JPGDEC 11 +#define CLK_VEN2_CKE5_GALS 12 +#define CLK_VEN2_CKE5_GALS_VENC 13 +#define CLK_VEN2_CKE5_GALS_JPGENC 14 +#define CLK_VEN2_CKE5_GALS_JPGDEC 15 +#define CLK_VEN2_CKE29_VENC_XPC_CTRL 16 +#define CLK_VEN2_CKE29_VENC_XPC_CTRL_VENC 17 +#define CLK_VEN2_CKE29_VENC_XPC_CTRL_JPGENC 18 +#define CLK_VEN2_CKE29_VENC_XPC_CTRL_JPGDEC 19 +#define CLK_VEN2_CKE6_GALS_SRAM 20 +#define CLK_VEN2_CKE6_GALS_SRAM_VENC 21 +#define CLK_VEN2_RES_FLAT 22 +#define CLK_VEN2_RES_FLAT_VENC 23 +#define CLK_VEN2_RES_FLAT_JPGENC 24 +#define CLK_VEN2_RES_FLAT_JPGDEC 25 +#define CLK_VEN2_NR_CLK 26 + +/* VENC_GCON_CORE2 */ +#define CLK_VEN_C2_CKE0_LARB 0 +#define CLK_VEN_C2_CKE0_LARB_VENC 1 +#define CLK_VEN_C2_CKE0_LARB_SMI 2 +#define CLK_VEN_C2_CKE1_VENC 3 +#define CLK_VEN_C2_CKE1_VENC_VENC 4 +#define CLK_VEN_C2_CKE1_VENC_SMI 5 +#define CLK_VEN_C2_CKE5_GALS 6 +#define CLK_VEN_C2_CKE5_GALS_VENC 7 +#define CLK_VEN_C2_CKE29_VENC_XPC_CTRL 8 +#define CLK_VEN_C2_CKE29_VENC_XPC_CTRL_VENC 9 +#define CLK_VEN_C2_CKE6_GALS_SRAM 10 +#define CLK_VEN_C2_CKE6_GALS_SRAM_VENC 11 +#define CLK_VEN_C2_RES_FLAT 12 +#define CLK_VEN_C2_RES_FLAT_VENC 13 +#define CLK_VEN_C2_NR_CLK 14 + +/* MDPSYS_CONFIG */ +#define CLK_MDP_MDP_MUTEX0 0 +#define CLK_MDP_MDP_MUTEX0_MML 1 +#define CLK_MDP_SMI0 2 +#define CLK_MDP_SMI0_MML 3 +#define CLK_MDP_SMI0_SMI 4 +#define CLK_MDP_APB_BUS 5 +#define CLK_MDP_APB_BUS_MML 6 +#define CLK_MDP_MDP_RDMA0 7 +#define CLK_MDP_MDP_RDMA0_MML 8 +#define CLK_MDP_MDP_RDMA1 9 +#define CLK_MDP_MDP_RDMA1_MML 10 +#define CLK_MDP_MDP_RDMA2 11 +#define CLK_MDP_MDP_RDMA2_MML 12 +#define CLK_MDP_MDP_BIRSZ0 13 +#define CLK_MDP_MDP_BIRSZ0_MML 14 +#define CLK_MDP_MDP_HDR0 15 +#define CLK_MDP_MDP_HDR0_MML 16 +#define CLK_MDP_MDP_AAL0 17 +#define CLK_MDP_MDP_AAL0_MML 18 +#define CLK_MDP_MDP_RSZ0 19 +#define CLK_MDP_MDP_RSZ0_MML 20 +#define CLK_MDP_MDP_RSZ2 21 +#define CLK_MDP_MDP_RSZ2_MML 22 +#define CLK_MDP_MDP_TDSHP0 23 +#define CLK_MDP_MDP_TDSHP0_MML 24 +#define CLK_MDP_MDP_COLOR0 25 +#define CLK_MDP_MDP_COLOR0_MML 26 +#define CLK_MDP_MDP_WROT0 27 +#define CLK_MDP_MDP_WROT0_MML 28 +#define CLK_MDP_MDP_WROT1 29 +#define CLK_MDP_MDP_WROT1_MML 30 +#define CLK_MDP_MDP_WROT2 31 +#define CLK_MDP_MDP_WROT2_MML 32 +#define CLK_MDP_MDP_FAKE_ENG0 33 +#define CLK_MDP_MDP_FAKE_ENG0_MML 34 +#define CLK_MDP_APB_DB 35 +#define CLK_MDP_APB_DB_MML 36 +#define CLK_MDP_MDP_DLI_ASYNC0 37 +#define CLK_MDP_MDP_DLI_ASYNC0_MML 38 +#define CLK_MDP_MDP_DLI_ASYNC1 39 +#define CLK_MDP_MDP_DLI_ASYNC1_MML 40 +#define CLK_MDP_MDP_DLO_ASYNC0 41 +#define CLK_MDP_MDP_DLO_ASYNC0_MML 42 +#define CLK_MDP_MDP_DLO_ASYNC1 43 +#define CLK_MDP_MDP_DLO_ASYNC1_MML 44 +#define CLK_MDP_MDP_DLI_ASYNC2 45 +#define CLK_MDP_MDP_DLI_ASYNC2_MML 46 +#define CLK_MDP_MDP_DLO_ASYNC2 47 +#define CLK_MDP_MDP_DLO_ASYNC2_MML 48 +#define CLK_MDP_MDP_DLO_ASYNC3 49 +#define CLK_MDP_MDP_DLO_ASYNC3_MML 50 +#define CLK_MDP_IMG_DL_ASYNC0 51 +#define CLK_MDP_IMG_DL_ASYNC0_MML 52 +#define CLK_MDP_MDP_RROT0 53 +#define CLK_MDP_MDP_RROT0_MML 54 +#define CLK_MDP_MDP_MERGE0 55 +#define CLK_MDP_MDP_MERGE0_MML 56 +#define CLK_MDP_MDP_C3D0 57 +#define CLK_MDP_MDP_C3D0_MML 58 +#define CLK_MDP_MDP_FG0 59 +#define CLK_MDP_MDP_FG0_MML 60 +#define CLK_MDP_MDP_CLA2 61 +#define CLK_MDP_MDP_CLA2_MML 62 +#define CLK_MDP_MDP_DLO_ASYNC4 63 +#define CLK_MDP_MDP_DLO_ASYNC4_MML 64 +#define CLK_MDP_VPP_RSZ0 65 +#define CLK_MDP_VPP_RSZ0_MML 66 +#define CLK_MDP_VPP_RSZ1 67 +#define CLK_MDP_VPP_RSZ1_MML 68 +#define CLK_MDP_MDP_DLO_ASYNC5 69 +#define CLK_MDP_MDP_DLO_ASYNC5_MML 70 +#define CLK_MDP_IMG0 71 +#define CLK_MDP_IMG0_MML 72 +#define CLK_MDP_F26M 73 +#define CLK_MDP_F26M_MML 74 +#define CLK_MDP_IMG_DL_RELAY0 75 +#define CLK_MDP_IMG_DL_RELAY0_MML 76 +#define CLK_MDP_IMG_DL_RELAY1 77 +#define CLK_MDP_IMG_DL_RELAY1_MML 78 +#define CLK_MDP_NR_CLK 79 + +/* MDPSYS1_CONFIG */ +#define CLK_MDP1_MDP_MUTEX0 0 +#define CLK_MDP1_MDP_MUTEX0_MML 1 +#define CLK_MDP1_SMI0 2 +#define CLK_MDP1_SMI0_SMI 3 +#define CLK_MDP1_APB_BUS 4 +#define CLK_MDP1_APB_BUS_MML 5 +#define CLK_MDP1_MDP_RDMA0 6 +#define CLK_MDP1_MDP_RDMA0_MML 7 +#define CLK_MDP1_MDP_RDMA1 8 +#define CLK_MDP1_MDP_RDMA1_MML 9 +#define CLK_MDP1_MDP_RDMA2 10 +#define CLK_MDP1_MDP_RDMA2_MML 11 +#define CLK_MDP1_MDP_BIRSZ0 12 +#define CLK_MDP1_MDP_BIRSZ0_MML 13 +#define CLK_MDP1_MDP_HDR0 14 +#define CLK_MDP1_MDP_HDR0_MML 15 +#define CLK_MDP1_MDP_AAL0 16 +#define CLK_MDP1_MDP_AAL0_MML 17 +#define CLK_MDP1_MDP_RSZ0 18 +#define CLK_MDP1_MDP_RSZ0_MML 19 +#define CLK_MDP1_MDP_RSZ2 20 +#define CLK_MDP1_MDP_RSZ2_MML 21 +#define CLK_MDP1_MDP_TDSHP0 22 +#define CLK_MDP1_MDP_TDSHP0_MML 23 +#define CLK_MDP1_MDP_COLOR0 24 +#define CLK_MDP1_MDP_COLOR0_MML 25 +#define CLK_MDP1_MDP_WROT0 26 +#define CLK_MDP1_MDP_WROT0_MML 27 +#define CLK_MDP1_MDP_WROT1 28 +#define CLK_MDP1_MDP_WROT1_MML 29 +#define CLK_MDP1_MDP_WROT2 30 +#define CLK_MDP1_MDP_WROT2_MML 31 +#define CLK_MDP1_MDP_FAKE_ENG0 32 +#define CLK_MDP1_MDP_FAKE_ENG0_MML 33 +#define CLK_MDP1_APB_DB 34 +#define CLK_MDP1_APB_DB_MML 35 +#define CLK_MDP1_MDP_DLI_ASYNC0 36 +#define CLK_MDP1_MDP_DLI_ASYNC0_MML 37 +#define CLK_MDP1_MDP_DLI_ASYNC1 38 +#define CLK_MDP1_MDP_DLI_ASYNC1_MML 39 +#define CLK_MDP1_MDP_DLO_ASYNC0 40 +#define CLK_MDP1_MDP_DLO_ASYNC0_MML 41 +#define CLK_MDP1_MDP_DLO_ASYNC1 42 +#define CLK_MDP1_MDP_DLO_ASYNC1_MML 43 +#define CLK_MDP1_MDP_DLI_ASYNC2 44 +#define CLK_MDP1_MDP_DLI_ASYNC2_MML 45 +#define CLK_MDP1_MDP_DLO_ASYNC2 46 +#define CLK_MDP1_MDP_DLO_ASYNC2_MML 47 +#define CLK_MDP1_MDP_DLO_ASYNC3 48 +#define CLK_MDP1_MDP_DLO_ASYNC3_MML 49 +#define CLK_MDP1_IMG_DL_ASYNC0 50 +#define CLK_MDP1_IMG_DL_ASYNC0_MML 51 +#define CLK_MDP1_MDP_RROT0 52 +#define CLK_MDP1_MDP_RROT0_MML 53 +#define CLK_MDP1_MDP_MERGE0 54 +#define CLK_MDP1_MDP_MERGE0_MML 55 +#define CLK_MDP1_MDP_C3D0 56 +#define CLK_MDP1_MDP_C3D0_MML 57 +#define CLK_MDP1_MDP_FG0 58 +#define CLK_MDP1_MDP_FG0_MML 59 +#define CLK_MDP1_MDP_CLA2 60 +#define CLK_MDP1_MDP_CLA2_MML 61 +#define CLK_MDP1_MDP_DLO_ASYNC4 62 +#define CLK_MDP1_MDP_DLO_ASYNC4_MML 63 +#define CLK_MDP1_VPP_RSZ0 64 +#define CLK_MDP1_VPP_RSZ0_MML 65 +#define CLK_MDP1_VPP_RSZ1 66 +#define CLK_MDP1_VPP_RSZ1_MML 67 +#define CLK_MDP1_MDP_DLO_ASYNC5 68 +#define CLK_MDP1_MDP_DLO_ASYNC5_MML 69 +#define CLK_MDP1_IMG0 70 +#define CLK_MDP1_IMG0_MML 71 +#define CLK_MDP1_F26M 72 +#define CLK_MDP1_F26M_MML 73 +#define CLK_MDP1_IMG_DL_RELAY0 74 +#define CLK_MDP1_IMG_DL_RELAY0_MML 75 +#define CLK_MDP1_IMG_DL_RELAY1 76 +#define CLK_MDP1_IMG_DL_RELAY1_MML 77 +#define CLK_MDP1_NR_CLK 78 + +/* DISP_VDISP_AO_CONFIG */ +#define CLK_MM_V_DISP_VDISP_AO_CONFIG 0 +#define CLK_MM_V_DISP_VDISP_AO_CONFIG_DISP 1 +#define CLK_MM_V_DISP_DPC 2 +#define CLK_MM_V_DISP_DPC_DISP 3 +#define CLK_MM_V_SMI_SUB_SOMM0 4 +#define CLK_MM_V_SMI_SUB_SOMM0_SMI 5 +#define CLK_MM_V_NR_CLK 6 + +/* MFGPLL_PLL_CTRL */ +#define CLK_MFG_AO_MFGPLL 0 +#define CLK_MFG_AO_NR_CLK 1 + +/* MFGPLL_SC0_PLL_CTRL */ +#define CLK_MFGSC0_AO_MFGPLL_SC0 0 +#define CLK_MFGSC0_AO_NR_CLK 1 + +/* MFGPLL_SC1_PLL_CTRL */ +#define CLK_MFGSC1_AO_MFGPLL_SC1 0 +#define CLK_MFGSC1_AO_NR_CLK 1 + +/* CCIPLL_PLL_CTRL */ +#define CLK_CCIPLL 0 +#define CLK_CCI_NR_CLK 1 + +/* ARMPLL_LL_PLL_CTRL */ +#define CLK_CPLL_ARMPLL_LL 0 +#define CLK_CPU_LL_NR_CLK 1 + +/* ARMPLL_BL_PLL_CTRL */ +#define CLK_CPBL_ARMPLL_BL 0 +#define CLK_CPU_BL_NR_CLK 1 + +/* ARMPLL_B_PLL_CTRL */ +#define CLK_CPB_ARMPLL_B 0 +#define CLK_CPU_B_NR_CLK 1 + +/* PTPPLL_PLL_CTRL */ +#define CLK_PTPPLL 0 +#define CLK_PTP_NR_CLK 1 + +#endif /* _DT_BINDINGS_CLK_MT8196_H */ -- GitLab From c7ad2d3b21473dd9600b683613c4d52d798269dc Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:43:28 +0800 Subject: [PATCH 277/456] CHROMIUM: dt-bindings: iio: Add MT635X AUXADC header Add MT635X AUXADC header for MT8196 PMIC. BUG=b:385017273 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:356073834 Change-Id: I93ef73ce9f302604672e52f7c4095073924cfbfa Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6147635 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/iio/mt635x-auxadc.h | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 include/dt-bindings/iio/mt635x-auxadc.h diff --git a/include/dt-bindings/iio/mt635x-auxadc.h b/include/dt-bindings/iio/mt635x-auxadc.h new file mode 100644 index 0000000000000..1aeef3b3c2840 --- /dev/null +++ b/include/dt-bindings/iio/mt635x-auxadc.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef _DT_BINDINGS_MT635X_AUXADC_H +#define _DT_BINDINGS_MT635X_AUXADC_H + +/* PMIC MT635x AUXADC channels */ +#define AUXADC_BATADC 0x00 +#define AUXADC_ISENSE 0x01 +#define AUXADC_VCDT 0x02 +#define AUXADC_BAT_TEMP 0x03 +#define AUXADC_BATID 0x04 +#define AUXADC_CHIP_TEMP 0x05 +#define AUXADC_VCORE_TEMP 0x06 +#define AUXADC_VPROC_TEMP 0x07 +#define AUXADC_VGPU_TEMP 0x08 +#define AUXADC_ACCDET 0x09 +#define AUXADC_VDCXO 0x0a +#define AUXADC_TSX_TEMP 0x0b +#define AUXADC_HPOFS_CAL 0x0c +#define AUXADC_DCXO_TEMP 0x0d +#define AUXADC_VBIF 0x0e +#define AUXADC_IMP 0x0f +#define AUXADC_IMIX_R 0x10 +#define AUXADC_VTREF 0x11 +#define AUXADC_VSYSSNS 0x12 +#define AUXADC_VIN1 0x13 +#define AUXADC_VIN2 0x14 +#define AUXADC_VIN3 0x15 +#define AUXADC_VIN4 0x16 +#define AUXADC_VIN5 0x17 +#define AUXADC_VIN6 0x18 +#define AUXADC_VIN7 0x19 + +#define AUXADC_CHAN_MIN AUXADC_BATADC +#define AUXADC_CHAN_MAX AUXADC_VIN7 + +#define ADC_PURES_100K (0) +#define ADC_PURES_30K (1) +#define ADC_PURES_400K (2) +#define ADC_PURES_OPEN (3) + +#define ADC_PURES_100K_MASK (ADC_PURES_100K << 8) +#define ADC_PURES_30K_MASK (ADC_PURES_30K << 8) +#define ADC_PURES_400K_MASK (ADC_PURES_400K << 8) +#define ADC_PURES_OPEN_MASK (ADC_PURES_OPEN << 8) + +#endif /* _DT_BINDINGS_MT635X_AUXADC_H */ -- GitLab From d7e0302beda92e4f51b1b5b66cb5eea7fb43415a Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:44:31 +0800 Subject: [PATCH 278/456] CHROMIUM: dt-bindings: memory: Add MT8196 LARB port header Add MT8196 LARB port header. BUG=b:385017273, b:383247849 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:354020406 Change-Id: I40f82edebd0cc6bc8fd73c8d185bae66a04e2936 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6147636 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/memory/mt8196-larb-port.h | 850 ++++++++++++++++++ 1 file changed, 850 insertions(+) create mode 100644 include/dt-bindings/memory/mt8196-larb-port.h diff --git a/include/dt-bindings/memory/mt8196-larb-port.h b/include/dt-bindings/memory/mt8196-larb-port.h new file mode 100644 index 0000000000000..9be265291e5d3 --- /dev/null +++ b/include/dt-bindings/memory/mt8196-larb-port.h @@ -0,0 +1,850 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Mingyuan Ma + */ + +#ifndef _DTS_IOMMU_PORT_MT8196_H_ +#define _DTS_IOMMU_PORT_MT8196_H_ + +#define MTK_M4U_PORT_ID(tab, dom, larb, port) (((tab & 0x3) << 20) | ((dom & 0xf) << 16) |\ + ((larb & 0x3f) << 5) | (port & 0x1f)) +#define MTK_SMMU_PORT_ID(larb, port) (MTK_M4U_PORT_ID(0, 0, larb, port)) + +/* Larb0 -- 13 */ +#define SMMU_L0_P0_OVL_RDMA2_HDR MTK_SMMU_PORT_ID(0, 0) +#define SMMU_L0_P1_OVL_RDMA7_HDR MTK_SMMU_PORT_ID(0, 1) +#define SMMU_L0_P2_OVL_RDMA2 MTK_SMMU_PORT_ID(0, 2) +#define SMMU_L0_P3_OVL_RDMA7 MTK_SMMU_PORT_ID(0, 3) +#define SMMU_L0_P4_RESERVED MTK_SMMU_PORT_ID(0, 4) +#define SMMU_L0_P5_RESERVED MTK_SMMU_PORT_ID(0, 5) +#define SMMU_L0_P6_OVL_RDMA2_HDR_STASH MTK_SMMU_PORT_ID(0, 6) +#define SMMU_L0_P7_OVL_RDMA7_HDR_STASH MTK_SMMU_PORT_ID(0, 7) +#define SMMU_L0_P8_OVL_RDMA2_STASH MTK_SMMU_PORT_ID(0, 8) +#define SMMU_L0_P9_OVL_RDMA7_STASH MTK_SMMU_PORT_ID(0, 9) +#define SMMU_L0_P10_RESERVED MTK_SMMU_PORT_ID(0, 10) +#define SMMU_L0_P11_RESERVED MTK_SMMU_PORT_ID(0, 11) +#define SMMU_L0_P12_DISP_FAKE0 MTK_SMMU_PORT_ID(0, 12) + +/* Larb1 -- 16 */ +#define SMMU_L1_P0_OVL_RDMA3_HDR MTK_SMMU_PORT_ID(1, 0) +#define SMMU_L1_P1_OVL_RDMA6_HDR MTK_SMMU_PORT_ID(1, 1) +#define SMMU_L1_P2_OVL_RDMA3 MTK_SMMU_PORT_ID(1, 2) +#define SMMU_L1_P3_OVL_RDMA6 MTK_SMMU_PORT_ID(1, 3) +#define SMMU_L1_P4_MDP_RDMA1 MTK_SMMU_PORT_ID(1, 4) +#define SMMU_L1_P5_RESERVED MTK_SMMU_PORT_ID(1, 5) +#define SMMU_L1_P6_DISP_WDMA1 MTK_SMMU_PORT_ID(1, 6) +#define SMMU_L1_P7_OVL_RDMA3_HDR_STASH MTK_SMMU_PORT_ID(1, 7) +#define SMMU_L1_P8_OVL_RDMA6_HDR_STASH MTK_SMMU_PORT_ID(1, 8) +#define SMMU_L1_P9_OVL_RDMA3_STASH MTK_SMMU_PORT_ID(1, 9) +#define SMMU_L1_P10_OVL_RDMA6_STASH MTK_SMMU_PORT_ID(1, 10) +#define SMMU_L1_P11_MDP_RDMA1_STASH MTK_SMMU_PORT_ID(1, 11) +#define SMMU_L1_P12_DISP_BWM0 MTK_SMMU_PORT_ID(1, 12) +#define SMMU_L1_P13_DISP_BWM0_STASH MTK_SMMU_PORT_ID(1, 13) +#define SMMU_L1_P14_RESERVED MTK_SMMU_PORT_ID(1, 14) +#define SMMU_L1_P15_DISP_FAKE1 MTK_SMMU_PORT_ID(1, 15) + +/* Larb2 -- 18 */ +#define SMMU_L2_P0_MDP_RDMA2 MTK_SMMU_PORT_ID(2, 0) +#define SMMU_L2_P1_MDP_WROT2 MTK_SMMU_PORT_ID(2, 1) +#define SMMU_L2_P2_MDP_RDMA1 MTK_SMMU_PORT_ID(2, 2) +#define SMMU_L2_P3_MDP_WROT1 MTK_SMMU_PORT_ID(2, 3) +#define SMMU_L2_P4_MDP_RDMA0 MTK_SMMU_PORT_ID(2, 4) +#define SMMU_L2_P5_MDP_WROT0 MTK_SMMU_PORT_ID(2, 5) +#define SMMU_L2_P6_MDP_RROT0 MTK_SMMU_PORT_ID(2, 6) +#define SMMU_L2_P7_MDP_FG0 MTK_SMMU_PORT_ID(2, 7) +#define SMMU_L2_P8_RESERVED MTK_SMMU_PORT_ID(2, 8) +#define SMMU_L2_P9_MDP_RDMA0_STASH MTK_SMMU_PORT_ID(2, 9) +#define SMMU_L2_P10_MDP_WROT0_STASH MTK_SMMU_PORT_ID(2, 10) +#define SMMU_L2_P11_MDP_RROT0_STASH MTK_SMMU_PORT_ID(2, 11) +#define SMMU_L2_P12_MDP_RDMA2_STASH MTK_SMMU_PORT_ID(2, 12) +#define SMMU_L2_P13_MDP_WROT2_STASH MTK_SMMU_PORT_ID(2, 13) +#define SMMU_L2_P14_MDP_RDMA1_STASH MTK_SMMU_PORT_ID(2, 14) +#define SMMU_L2_P15_MDP_WROT1_STASH MTK_SMMU_PORT_ID(2, 15) +#define SMMU_L2_P16_RESERVED MTK_SMMU_PORT_ID(2, 16) +#define SMMU_L2_P17_MDP_FAKE_ENG0 MTK_SMMU_PORT_ID(2, 17) + +/* Larb3 -- 18 */ +#define SMMU_L3_P0_MDP_RDMA2 MTK_SMMU_PORT_ID(3, 0) +#define SMMU_L3_P1_MDP_WROT2 MTK_SMMU_PORT_ID(3, 1) +#define SMMU_L3_P2_MDP_RDMA1 MTK_SMMU_PORT_ID(3, 2) +#define SMMU_L3_P3_MDP_WROT1 MTK_SMMU_PORT_ID(3, 3) +#define SMMU_L3_P4_MDP_RDMA0 MTK_SMMU_PORT_ID(3, 4) +#define SMMU_L3_P5_MDP_WROT0 MTK_SMMU_PORT_ID(3, 5) +#define SMMU_L3_P6_MDP_RROT0 MTK_SMMU_PORT_ID(3, 6) +#define SMMU_L3_P7_MDP_FG0 MTK_SMMU_PORT_ID(3, 7) +#define SMMU_L3_P8_RESERVED MTK_SMMU_PORT_ID(3, 8) +#define SMMU_L3_P9_MDP_RDMA0_STASH MTK_SMMU_PORT_ID(3, 9) +#define SMMU_L3_P10_MDP_WROT0_STASH MTK_SMMU_PORT_ID(3, 10) +#define SMMU_L3_P11_MDP_RROT0_STASH MTK_SMMU_PORT_ID(3, 11) +#define SMMU_L3_P12_MDP_RDMA2_STASH MTK_SMMU_PORT_ID(3, 12) +#define SMMU_L3_P13_MDP_WROT2_STASH MTK_SMMU_PORT_ID(3, 13) +#define SMMU_L3_P14_MDP_RDMA1_STASH MTK_SMMU_PORT_ID(3, 14) +#define SMMU_L3_P15_MDP_WROT1_STASH MTK_SMMU_PORT_ID(3, 15) +#define SMMU_L3_P16_RESERVED MTK_SMMU_PORT_ID(3, 16) +#define SMMU_L3_P17_MDP_FAKE_ENG0 MTK_SMMU_PORT_ID(3, 17) + +/* Larb4 -- 8 */ +#define SMMU_L4_P0_VDEC_MC_C MTK_SMMU_PORT_ID(4, 0) +#define SMMU_L4_P1_VDEC_UFO MTK_SMMU_PORT_ID(4, 1) +#define SMMU_L4_P2_VDEC_PP MTK_SMMU_PORT_ID(4, 2) +#define SMMU_L4_P3_VDEC_UFO_C MTK_SMMU_PORT_ID(4, 3) +#define SMMU_L4_P4_VDEC_TILE MTK_SMMU_PORT_ID(4, 4) +#define SMMU_L4_P5_VDEC_VLD MTK_SMMU_PORT_ID(4, 5) +#define SMMU_L4_P6_VDEC_VLD2 MTK_SMMU_PORT_ID(4, 6) +#define SMMU_L4_P7_VDEC_AVC_MV MTK_SMMU_PORT_ID(4, 7) + +/* Larb5 -- 8 */ +#define SMMU_L5_P0_VDEC_LAT0_VLD MTK_SMMU_PORT_ID(5, 0) +#define SMMU_L5_P1_VDEC_LAT0_VLD2 MTK_SMMU_PORT_ID(5, 1) +#define SMMU_L5_P2_VDEC_MC MTK_SMMU_PORT_ID(5, 2) +#define SMMU_L5_P3_VDEC_UFO_ENC MTK_SMMU_PORT_ID(5, 3) +#define SMMU_L5_P4_VDEC_LAT0_WDMA MTK_SMMU_PORT_ID(5, 4) +#define SMMU_L5_P5_VDEC_LAT0_AVC_MV MTK_SMMU_PORT_ID(5, 5) +#define SMMU_L5_P6_VDEC_LAT0_TILE MTK_SMMU_PORT_ID(5, 6) +#define SMMU_L5_P7_VDEC_LAT0_UNIWRAP MTK_SMMU_PORT_ID(5, 7) + +/* Larb6 -- 3 */ +#define SMMU_L6_P0_VDEC_MC_PORT2 MTK_SMMU_PORT_ID(6, 0) +#define SMMU_L6_P1_VDEC_UFO_ENC_C MTK_SMMU_PORT_ID(6, 1) +#define SMMU_L6_P2_VDEC_UNIWRAP MTK_SMMU_PORT_ID(6, 2) + +/* Larb7 -- 32 */ +#define SMMU_L7_P0_RCPU MTK_SMMU_PORT_ID(7, 0) +#define SMMU_L7_P1_REC_FRM MTK_SMMU_PORT_ID(7, 1) +#define SMMU_L7_P2_BS MTK_SMMU_PORT_ID(7, 2) +#define SMMU_L7_P3_SVCOMV MTK_SMMU_PORT_ID(7, 3) +#define SMMU_L7_P4_RDCOMV MTK_SMMU_PORT_ID(7, 4) +#define SMMU_L7_P5_NBM_R MTK_SMMU_PORT_ID(7, 5) +#define SMMU_L7_P6_NBM_R_LITE MTK_SMMU_PORT_ID(7, 6) +#define SMMU_L7_P7_JPGENC_YRD MTK_SMMU_PORT_ID(7, 7) +#define SMMU_L7_P8_JPGENC_CRD MTK_SMMU_PORT_ID(7, 8) +#define SMMU_L7_P9_JPGENC_QT MTK_SMMU_PORT_ID(7, 9) +#define SMMU_L7_P10_FCS_SUB_W MTK_SMMU_PORT_ID(7, 10) +#define SMMU_L7_P11_FCS_NBM_R MTK_SMMU_PORT_ID(7, 11) +#define SMMU_L7_P12_WPP_BS MTK_SMMU_PORT_ID(7, 12) +#define SMMU_L7_P13_WPP_RDMA MTK_SMMU_PORT_ID(7, 13) +#define SMMU_L7_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(7, 14) +#define SMMU_L7_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(7, 15) +#define SMMU_L7_P16_JPGENC_BS MTK_SMMU_PORT_ID(7, 16) +#define SMMU_L7_P17_JPGDEC_W MTK_SMMU_PORT_ID(7, 17) +#define SMMU_L7_P18_JPGDEC_BS MTK_SMMU_PORT_ID(7, 18) +#define SMMU_L7_P19_NBM_W MTK_SMMU_PORT_ID(7, 19) +#define SMMU_L7_P20_NBM_W_LITE MTK_SMMU_PORT_ID(7, 20) +#define SMMU_L7_P21_CUR_LUMA MTK_SMMU_PORT_ID(7, 21) +#define SMMU_L7_P22_CUR_CHROMA MTK_SMMU_PORT_ID(7, 22) +#define SMMU_L7_P23_REF_LUMA MTK_SMMU_PORT_ID(7, 23) +#define SMMU_L7_P24_REF_CHROMA MTK_SMMU_PORT_ID(7, 24) +#define SMMU_L7_P25_FCS_SUB_R MTK_SMMU_PORT_ID(7, 25) +#define SMMU_L7_P26_FCS_NBM_W MTK_SMMU_PORT_ID(7, 26) +#define SMMU_L7_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(7, 27) +#define SMMU_L7_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(7, 28) +#define SMMU_L7_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(7, 29) +#define SMMU_L7_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(7, 30) +#define SMMU_L7_P31_EC_SYSRAM MTK_SMMU_PORT_ID(7, 31) + +/* Larb8 -- 32 */ +#define SMMU_L8_P0_RCPU MTK_SMMU_PORT_ID(8, 0) +#define SMMU_L8_P1_REC_FRM MTK_SMMU_PORT_ID(8, 1) +#define SMMU_L8_P2_BS MTK_SMMU_PORT_ID(8, 2) +#define SMMU_L8_P3_SVCOMV MTK_SMMU_PORT_ID(8, 3) +#define SMMU_L8_P4_RDCOMV MTK_SMMU_PORT_ID(8, 4) +#define SMMU_L8_P5_NBM_R MTK_SMMU_PORT_ID(8, 5) +#define SMMU_L8_P6_NBM_R_LITE MTK_SMMU_PORT_ID(8, 6) +#define SMMU_L8_P7_JPGENC_YRD MTK_SMMU_PORT_ID(8, 7) +#define SMMU_L8_P8_JPGENC_CRD MTK_SMMU_PORT_ID(8, 8) +#define SMMU_L8_P9_JPGENC_QT MTK_SMMU_PORT_ID(8, 9) +#define SMMU_L8_P10_FCS_SUB_W MTK_SMMU_PORT_ID(8, 10) +#define SMMU_L8_P11_FCS_NBM_R MTK_SMMU_PORT_ID(8, 11) +#define SMMU_L8_P12_WPP_BS MTK_SMMU_PORT_ID(8, 12) +#define SMMU_L8_P13_WPP_RDMA MTK_SMMU_PORT_ID(8, 13) +#define SMMU_L8_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(8, 14) +#define SMMU_L8_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(8, 15) +#define SMMU_L8_P16_JPGENC_BS MTK_SMMU_PORT_ID(8, 16) +#define SMMU_L8_P17_JPGDEC_W MTK_SMMU_PORT_ID(8, 17) +#define SMMU_L8_P18_JPGDEC_BS MTK_SMMU_PORT_ID(8, 18) +#define SMMU_L8_P19_NBM_W MTK_SMMU_PORT_ID(8, 19) +#define SMMU_L8_P20_NBM_W_LITE MTK_SMMU_PORT_ID(8, 20) +#define SMMU_L8_P21_CUR_LUMA MTK_SMMU_PORT_ID(8, 21) +#define SMMU_L8_P22_CUR_CHROMA MTK_SMMU_PORT_ID(8, 22) +#define SMMU_L8_P23_REF_LUMA MTK_SMMU_PORT_ID(8, 23) +#define SMMU_L8_P24_REF_CHROMA MTK_SMMU_PORT_ID(8, 24) +#define SMMU_L8_P25_FCS_SUB_R MTK_SMMU_PORT_ID(8, 25) +#define SMMU_L8_P26_FCS_NBM_W MTK_SMMU_PORT_ID(8, 26) +#define SMMU_L8_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(8, 27) +#define SMMU_L8_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(8, 28) +#define SMMU_L8_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(8, 29) +#define SMMU_L8_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(8, 30) +#define SMMU_L8_P31_EC_SYSRAM MTK_SMMU_PORT_ID(8, 31) + +/* Larb9 -- 27 */ +#define SMMU_L9_P0_IMGI_T1_B MTK_SMMU_PORT_ID(9, 0) +#define SMMU_L9_P1_IMGCI_T1_B MTK_SMMU_PORT_ID(9, 1) +#define SMMU_L9_P2_SMTI_T1_B MTK_SMMU_PORT_ID(9, 2) +#define SMMU_L9_P3_YUVO_T1_B MTK_SMMU_PORT_ID(9, 3) +#define SMMU_L9_P4_YUVCO_T1_B MTK_SMMU_PORT_ID(9, 4) +#define SMMU_L9_P5_YUVO_T2_B MTK_SMMU_PORT_ID(9, 5) +#define SMMU_L9_P6_YUVBO_T2_B MTK_SMMU_PORT_ID(9, 6) +#define SMMU_L9_P7_TNCSTO_T1_B MTK_SMMU_PORT_ID(9, 7) +#define SMMU_L9_P8_TNCSTI_T2_B MTK_SMMU_PORT_ID(9, 8) +#define SMMU_L9_P9_YUFETI_T1_B MTK_SMMU_PORT_ID(9, 9) +#define SMMU_L9_P10_STG_T1_B MTK_SMMU_PORT_ID(9, 10) +#define SMMU_L9_P11_STG_T2_B MTK_SMMU_PORT_ID(9, 11) +#define SMMU_L9_P12_ME_RDMA_0 MTK_SMMU_PORT_ID(9, 12) +#define SMMU_L9_P13_ME_WDMA_0 MTK_SMMU_PORT_ID(9, 13) +#define SMMU_L9_P14_MEMMG_RDMA_0 MTK_SMMU_PORT_ID(9, 14) +#define SMMU_L9_P15_MEMMG_WDMA_0 MTK_SMMU_PORT_ID(9, 15) +#define SMMU_L9_P16_ME_2ND_RDMA_0 MTK_SMMU_PORT_ID(9, 16) +#define SMMU_L9_P17_ME_2ND_WDMA_0 MTK_SMMU_PORT_ID(9, 17) +#define SMMU_L9_P18_MEMMG_2ND_RDMA_0 MTK_SMMU_PORT_ID(9, 18) +#define SMMU_L9_P19_MEMMG_2ND_WDMA_0 MTK_SMMU_PORT_ID(9, 19) +#define SMMU_L9_P20_STSCMD_ME0 MTK_SMMU_PORT_ID(9, 20) +#define SMMU_L9_P21_STSCMD_ME1 MTK_SMMU_PORT_ID(9, 21) +#define SMMU_L9_P22_IMGI_T1_N_B MTK_SMMU_PORT_ID(9, 22) +#define SMMU_L9_P23_SMTO_T1_B MTK_SMMU_PORT_ID(9, 23) +#define SMMU_L9_P24_TNCSO_T1_B MTK_SMMU_PORT_ID(9, 24) +#define SMMU_L9_P25_YUFETO_T1_B MTK_SMMU_PORT_ID(9, 25) +#define SMMU_L9_P26_DUMMY MTK_SMMU_PORT_ID(9, 26) + +/* Larb10 -- 9 */ +#define SMMU_L10_P0_IMGI_D1 MTK_SMMU_PORT_ID(10, 0) +#define SMMU_L10_P1_IMGCI_D1 MTK_SMMU_PORT_ID(10, 1) +#define SMMU_L10_P2_RECI_D1 MTK_SMMU_PORT_ID(10, 2) +#define SMMU_L10_P3_RECI_D1_N MTK_SMMU_PORT_ID(10, 3) +#define SMMU_L10_P4_TNRCI_D1 MTK_SMMU_PORT_ID(10, 4) +#define SMMU_L10_P5_TNRCI_D1_N MTK_SMMU_PORT_ID(10, 5) +#define SMMU_L10_P6_STG_D1 MTK_SMMU_PORT_ID(10, 6) +#define SMMU_L10_P7_IMGDI_D1 MTK_SMMU_PORT_ID(10, 7) +#define SMMU_L10_P8_DUMMY MTK_SMMU_PORT_ID(10, 8) + +/* Larb11 -- 16 */ +#define SMMU_L11_P0_WPE_RDMA_0 MTK_SMMU_PORT_ID(11, 0) +#define SMMU_L11_P1_WPE_RDMA_1 MTK_SMMU_PORT_ID(11, 1) +#define SMMU_L11_P2_WPE_RDMA_2 MTK_SMMU_PORT_ID(11, 2) +#define SMMU_L11_P3_PIMGI_P1 MTK_SMMU_PORT_ID(11, 3) +#define SMMU_L11_P4_STG_P1 MTK_SMMU_PORT_ID(11, 4) +#define SMMU_L11_P5_STS_P2 MTK_SMMU_PORT_ID(11, 5) +#define SMMU_L11_P6_STS_P3 MTK_SMMU_PORT_ID(11, 6) +#define SMMU_L11_P7_OMC_RDMA_0 MTK_SMMU_PORT_ID(11, 7) +#define SMMU_L11_P8_OMC_RDMA_1 MTK_SMMU_PORT_ID(11, 8) +#define SMMU_L11_P9_STS_P4 MTK_SMMU_PORT_ID(11, 9) +#define SMMU_L11_P10_PIMGCI_P1 MTK_SMMU_PORT_ID(11, 10) +#define SMMU_L11_P11_WPE_WDMA_0 MTK_SMMU_PORT_ID(11, 11) +#define SMMU_L11_P12_WROT_P1 MTK_SMMU_PORT_ID(11, 12) +#define SMMU_L11_P13_IOSO_P1 MTK_SMMU_PORT_ID(11, 13) +#define SMMU_L11_P14_OMC_WDMA_0 MTK_SMMU_PORT_ID(11, 14) +#define SMMU_L11_P15_DUMMY MTK_SMMU_PORT_ID(11, 15) + +/* Larb12 -- 6 */ +#define SMMU_L12_P0_FDVT_RDA_0 MTK_SMMU_PORT_ID(12, 0) +#define SMMU_L12_P1_FDVT_WRA_0 MTK_SMMU_PORT_ID(12, 1) +#define SMMU_L12_P2_STSCMD_FDVT MTK_SMMU_PORT_ID(12, 2) +#define SMMU_L12_P3_DUMMY MTK_SMMU_PORT_ID(12, 3) +#define SMMU_L12_P4_DUMMY MTK_SMMU_PORT_ID(12, 4) +#define SMMU_L12_P5_DUMMY MTK_SMMU_PORT_ID(12, 5) + +/* Larb13 -- 7 */ +#define SMMU_L13_P0_CAMSV_B_CQI_E1 MTK_SMMU_PORT_ID(13, 0) +#define SMMU_L13_P1_CAMSV_B0_WDMA MTK_SMMU_PORT_ID(13, 1) +#define SMMU_L13_P2_CAMSV_B1_WDMA MTK_SMMU_PORT_ID(13, 2) +#define SMMU_L13_P3_FAKE_ENG MTK_SMMU_PORT_ID(13, 3) +#define SMMU_L13_P4_RESERVED_1 MTK_SMMU_PORT_ID(13, 4) +#define SMMU_L13_P5_CAMSV_B0_STG MTK_SMMU_PORT_ID(13, 5) +#define SMMU_L13_P6_CAMSV_B1_STG MTK_SMMU_PORT_ID(13, 6) + +/* Larb14 -- 6 */ +#define SMMU_L14_P0_CAMSV_A_CQI_E1 MTK_SMMU_PORT_ID(14, 0) +#define SMMU_L14_P1_CAMSV_A0_WDMA MTK_SMMU_PORT_ID(14, 1) +#define SMMU_L14_P2_CAMSV_A1_WDMA MTK_SMMU_PORT_ID(14, 2) +#define SMMU_L14_P3_RESERVED_0 MTK_SMMU_PORT_ID(14, 3) +#define SMMU_L14_P4_CAMSV_A0_STG MTK_SMMU_PORT_ID(14, 4) +#define SMMU_L14_P5_CAMSV_A1_STG MTK_SMMU_PORT_ID(14, 5) + +/* Larb15 -- 12 */ +#define SMMU_L15_P0_VIPI_D1 MTK_SMMU_PORT_ID(15, 0) +#define SMMU_L15_P1_VIPCI_D1 MTK_SMMU_PORT_ID(15, 1) +#define SMMU_L15_P2_IMG3O_D1 MTK_SMMU_PORT_ID(15, 2) +#define SMMU_L15_P3_IMG3CO_D1 MTK_SMMU_PORT_ID(15, 3) +#define SMMU_L15_P4_IMG7O_D1 MTK_SMMU_PORT_ID(15, 4) +#define SMMU_L15_P5_IMG7CO_D1 MTK_SMMU_PORT_ID(15, 5) +#define SMMU_L15_P6_IMG2O_D1 MTK_SMMU_PORT_ID(15, 6) +#define SMMU_L15_P7_IMG5O_D1 MTK_SMMU_PORT_ID(15, 7) +#define SMMU_L15_P8_DHZAI_D1 MTK_SMMU_PORT_ID(15, 8) +#define SMMU_L15_P9_STG_D4 MTK_SMMU_PORT_ID(15, 9) +#define SMMU_L15_P10_DUMMY MTK_SMMU_PORT_ID(15, 10) +#define SMMU_L15_P11_DUMMY MTK_SMMU_PORT_ID(15, 11) + +/* Larb16 -- 19 */ +#define SMMU_L16_P0_CQI_R1 MTK_SMMU_PORT_ID(16, 0) +#define SMMU_L16_P1_CQI_R5 MTK_SMMU_PORT_ID(16, 1) +#define SMMU_L16_P2_RAWI_R2 MTK_SMMU_PORT_ID(16, 2) +#define SMMU_L16_P3_RAWI_R3 MTK_SMMU_PORT_ID(16, 3) +#define SMMU_L16_P4_RAWI_R4 MTK_SMMU_PORT_ID(16, 4) +#define SMMU_L16_P5_RAWI_R5 MTK_SMMU_PORT_ID(16, 5) +#define SMMU_L16_P6_BPCI_R1 MTK_SMMU_PORT_ID(16, 6) +#define SMMU_L16_P7_BPCI_R3 MTK_SMMU_PORT_ID(16, 7) +#define SMMU_L16_P8_GRMGI_R1 MTK_SMMU_PORT_ID(16, 8) +#define SMMU_L16_P9_LSCI_R1 MTK_SMMU_PORT_ID(16, 9) +#define SMMU_L16_P10_IMGO_R1 MTK_SMMU_PORT_ID(16, 10) +#define SMMU_L16_P11_IMGO_R2 MTK_SMMU_PORT_ID(16, 11) +#define SMMU_L16_P12_DRZB2NO_R1 MTK_SMMU_PORT_ID(16, 12) +#define SMMU_L16_P13_DRZB2NBO_R1 MTK_SMMU_PORT_ID(16, 13) +#define SMMU_L16_P14_GMPO_R1 MTK_SMMU_PORT_ID(16, 14) +#define SMMU_L16_P15_DRZB2NCO_R1 MTK_SMMU_PORT_ID(16, 15) +#define SMMU_L16_P16_AWBO_R1 MTK_SMMU_PORT_ID(16, 16) +#define SMMU_L16_P17_STG_R1 MTK_SMMU_PORT_ID(16, 17) +#define SMMU_L16_P18_STG_R2 MTK_SMMU_PORT_ID(16, 18) + +/* Larb17 -- 7 */ +#define SMMU_L17_P0_YUVO_R1 MTK_SMMU_PORT_ID(17, 0) +#define SMMU_L17_P1_YUVO_R3 MTK_SMMU_PORT_ID(17, 1) +#define SMMU_L17_P2_YUVO_R2 MTK_SMMU_PORT_ID(17, 2) +#define SMMU_L17_P3_DRZH2NO_R1 MTK_SMMU_PORT_ID(17, 3) +#define SMMU_L17_P4_YUVO_R4 MTK_SMMU_PORT_ID(17, 4) +#define SMMU_L17_P5_DRZH1NO_R1 MTK_SMMU_PORT_ID(17, 5) +#define SMMU_L17_P6_STG_R3 MTK_SMMU_PORT_ID(17, 6) + +/* Larb18 -- 6 */ +#define SMMU_L18_P0_IMGADL_0_IPUI_E1 MTK_SMMU_PORT_ID(18, 0) +#define SMMU_L18_P1_IMGADL_0_IPUI_E2 MTK_SMMU_PORT_ID(18, 1) +#define SMMU_L18_P2_IMGADL_1_IPUO MTK_SMMU_PORT_ID(18, 2) +#define SMMU_L18_P3_IMGADL_1_IPUBO MTK_SMMU_PORT_ID(18, 3) +#define SMMU_L18_P4_DUMMY MTK_SMMU_PORT_ID(18, 4) +#define SMMU_L18_P5_DUMMY MTK_SMMU_PORT_ID(18, 5) + +/* Larb19 -- 15 */ +#define SMMU_L19_P0_YUV_LA_READ MTK_SMMU_PORT_ID(19, 0) +#define SMMU_L19_P1_YUV_LA_WTIRE MTK_SMMU_PORT_ID(19, 1) +#define SMMU_L19_P2_YUV_FUS_READ MTK_SMMU_PORT_ID(19, 2) +#define SMMU_L19_P3_YUV_FUS_WTIRE MTK_SMMU_PORT_ID(19, 3) +#define SMMU_L19_P4_DVS_RD MTK_SMMU_PORT_ID(19, 4) +#define SMMU_L19_P5_DVS_WT MTK_SMMU_PORT_ID(19, 5) +#define SMMU_L19_P6_DVP_RD MTK_SMMU_PORT_ID(19, 6) +#define SMMU_L19_P7_DVP_WT MTK_SMMU_PORT_ID(19, 7) +#define SMMU_L19_P8_DHZE_R MTK_SMMU_PORT_ID(19, 8) +#define SMMU_L19_P9_DHZE_W MTK_SMMU_PORT_ID(19, 9) +#define SMMU_L19_P10_DVGF_RD MTK_SMMU_PORT_ID(19, 10) +#define SMMU_L19_P11_DVGF_WT MTK_SMMU_PORT_ID(19, 11) +#define SMMU_L19_P12_STG_WR MTK_SMMU_PORT_ID(19, 12) +#define SMMU_L19_P13_YUV_FUS_STG MTK_SMMU_PORT_ID(19, 13) +#define SMMU_L19_P14_YUV_LA_STG MTK_SMMU_PORT_ID(19, 14) + +/* Larb20 -- 15 */ +#define SMMU_L20_P0_OVL_RDMA4_HDR MTK_SMMU_PORT_ID(20, 0) +#define SMMU_L20_P1_OVL_RDMA9_HDR MTK_SMMU_PORT_ID(20, 1) +#define SMMU_L20_P2_OVL_RDMA0_HDR MTK_SMMU_PORT_ID(20, 2) +#define SMMU_L20_P3_OVL_RDMA4 MTK_SMMU_PORT_ID(20, 3) +#define SMMU_L20_P4_OVL_RDMA9 MTK_SMMU_PORT_ID(20, 4) +#define SMMU_L20_P5_OVL_RDMA0 MTK_SMMU_PORT_ID(20, 5) +#define SMMU_L20_P6_RESERVED MTK_SMMU_PORT_ID(20, 6) +#define SMMU_L20_P7_OVL_RDMA4_HDR_STASH MTK_SMMU_PORT_ID(20, 7) +#define SMMU_L20_P8_OVL_RDMA9_HDR_STASH MTK_SMMU_PORT_ID(20, 8) +#define SMMU_L20_P9_OVL_RDMA0_HDR_STASH MTK_SMMU_PORT_ID(20, 9) +#define SMMU_L20_P10_OVL_RDMA4_STASH MTK_SMMU_PORT_ID(20, 10) +#define SMMU_L20_P11_OVL_RDMA9_STASH MTK_SMMU_PORT_ID(20, 11) +#define SMMU_L20_P12_OVL_RDMA0_STASH MTK_SMMU_PORT_ID(20, 12) +#define SMMU_L20_P13_RESERVED MTK_SMMU_PORT_ID(20, 13) +#define SMMU_L20_P14_RESERVED MTK_SMMU_PORT_ID(20, 14) + +/* Larb21 -- 18 */ +#define SMMU_L21_P0_OVL_RDMA5_HDR MTK_SMMU_PORT_ID(21, 0) +#define SMMU_L21_P1_OVL_RDMA8_HDR MTK_SMMU_PORT_ID(21, 1) +#define SMMU_L21_P2_OVL_RDMA1_HDR MTK_SMMU_PORT_ID(21, 2) +#define SMMU_L21_P3_OVL_RDMA5 MTK_SMMU_PORT_ID(21, 3) +#define SMMU_L21_P4_OVL_RDMA8 MTK_SMMU_PORT_ID(21, 4) +#define SMMU_L21_P5_OVL_RDMA1 MTK_SMMU_PORT_ID(21, 5) +#define SMMU_L21_P6_RESERVED MTK_SMMU_PORT_ID(21, 6) +#define SMMU_L21_P7_MDP_RDMA0 MTK_SMMU_PORT_ID(21, 7) +#define SMMU_L21_P8_DISP_WDMA0 MTK_SMMU_PORT_ID(21, 8) +#define SMMU_L21_P9_DISP_UFBC_WDMA0 MTK_SMMU_PORT_ID(21, 9) +#define SMMU_L21_P10_OVL_RDMA5_HDR_STASH MTK_SMMU_PORT_ID(21, 10) +#define SMMU_L21_P11_OVL_RDMA8_HDR_STASH MTK_SMMU_PORT_ID(21, 11) +#define SMMU_L21_P12_OVL_RDMA1_HDR_STASH MTK_SMMU_PORT_ID(21, 12) +#define SMMU_L21_P13_OVL_RDMA5_STASH MTK_SMMU_PORT_ID(21, 13) +#define SMMU_L21_P14_OVL_RDMA8_STASH MTK_SMMU_PORT_ID(21, 14) +#define SMMU_L21_P15_OVL_RDMA1_STASH MTK_SMMU_PORT_ID(21, 15) +#define SMMU_L21_P16_MDP_RDMA0_STASH MTK_SMMU_PORT_ID(21, 16) +#define SMMU_L21_P17_RESERVED MTK_SMMU_PORT_ID(21, 17) + +/* Larb22 -- 16 */ +#define SMMU_L22_P0_WPE_RDMA_0 MTK_SMMU_PORT_ID(22, 0) +#define SMMU_L22_P1_WPE_RDMA_1 MTK_SMMU_PORT_ID(22, 1) +#define SMMU_L22_P2_WPE_RDMA_2 MTK_SMMU_PORT_ID(22, 2) +#define SMMU_L22_P3_PIMGI_P1 MTK_SMMU_PORT_ID(22, 3) +#define SMMU_L22_P4_STG_P1 MTK_SMMU_PORT_ID(22, 4) +#define SMMU_L22_P5_STS_P2 MTK_SMMU_PORT_ID(22, 5) +#define SMMU_L22_P6_STS_P3 MTK_SMMU_PORT_ID(22, 6) +#define SMMU_L22_P7_OMC_RDMA_0 MTK_SMMU_PORT_ID(22, 7) +#define SMMU_L22_P8_OMC_RDMA_1 MTK_SMMU_PORT_ID(22, 8) +#define SMMU_L22_P9_STS_P4 MTK_SMMU_PORT_ID(22, 9) +#define SMMU_L22_P10_PIMGCI_P1 MTK_SMMU_PORT_ID(22, 10) +#define SMMU_L22_P11_WPE_WDMA_0 MTK_SMMU_PORT_ID(22, 11) +#define SMMU_L22_P12_WROT_P1 MTK_SMMU_PORT_ID(22, 12) +#define SMMU_L22_P13_IOSO_P1 MTK_SMMU_PORT_ID(22, 13) +#define SMMU_L22_P14_OMC_WDMA_0 MTK_SMMU_PORT_ID(22, 14) +#define SMMU_L22_P15_DUMMY MTK_SMMU_PORT_ID(22, 15) + +/* Larb23 -- 16 */ +#define SMMU_L23_P0_WPE_RDMA_0 MTK_SMMU_PORT_ID(23, 0) +#define SMMU_L23_P1_WPE_RDMA_1 MTK_SMMU_PORT_ID(23, 1) +#define SMMU_L23_P2_WPE_RDMA_2 MTK_SMMU_PORT_ID(23, 2) +#define SMMU_L23_P3_PIMGI_P1 MTK_SMMU_PORT_ID(23, 3) +#define SMMU_L23_P4_STG_P1 MTK_SMMU_PORT_ID(23, 4) +#define SMMU_L23_P5_STS_P2 MTK_SMMU_PORT_ID(23, 5) +#define SMMU_L23_P6_STS_P3 MTK_SMMU_PORT_ID(23, 6) +#define SMMU_L23_P7_OMC_RDMA_0 MTK_SMMU_PORT_ID(23, 7) +#define SMMU_L23_P8_OMC_RDMA_1 MTK_SMMU_PORT_ID(23, 8) +#define SMMU_L23_P9_STS_P4 MTK_SMMU_PORT_ID(23, 9) +#define SMMU_L23_P10_PIMGCI_P1 MTK_SMMU_PORT_ID(23, 10) +#define SMMU_L23_P11_WPE_WDMA_0 MTK_SMMU_PORT_ID(23, 11) +#define SMMU_L23_P12_WROT_P1 MTK_SMMU_PORT_ID(23, 12) +#define SMMU_L23_P13_IOSO_P1 MTK_SMMU_PORT_ID(23, 13) +#define SMMU_L23_P14_OMC_WDMA_0 MTK_SMMU_PORT_ID(23, 14) +#define SMMU_L23_P15_DUMMY MTK_SMMU_PORT_ID(23, 15) + +/* Larb24 -- 32 */ +#define SMMU_L24_P0_RCPU MTK_SMMU_PORT_ID(24, 0) +#define SMMU_L24_P1_REC_FRM MTK_SMMU_PORT_ID(24, 1) +#define SMMU_L24_P2_BS MTK_SMMU_PORT_ID(24, 2) +#define SMMU_L24_P3_SVCOMV MTK_SMMU_PORT_ID(24, 3) +#define SMMU_L24_P4_RDCOMV MTK_SMMU_PORT_ID(24, 4) +#define SMMU_L24_P5_NBM_R MTK_SMMU_PORT_ID(24, 5) +#define SMMU_L24_P6_NBM_R_LITE MTK_SMMU_PORT_ID(24, 6) +#define SMMU_L24_P7_JPGENC_YRD MTK_SMMU_PORT_ID(24, 7) +#define SMMU_L24_P8_JPGENC_CRD MTK_SMMU_PORT_ID(24, 8) +#define SMMU_L24_P9_JPGENC_QT MTK_SMMU_PORT_ID(24, 9) +#define SMMU_L24_P10_FCS_SUB_W MTK_SMMU_PORT_ID(24, 10) +#define SMMU_L24_P11_FCS_NBM_R MTK_SMMU_PORT_ID(24, 11) +#define SMMU_L24_P12_WPP_BS MTK_SMMU_PORT_ID(24, 12) +#define SMMU_L24_P13_WPP_RDMA MTK_SMMU_PORT_ID(24, 13) +#define SMMU_L24_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(24, 14) +#define SMMU_L24_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(24, 15) +#define SMMU_L24_P16_JPGENC_BS MTK_SMMU_PORT_ID(24, 16) +#define SMMU_L24_P17_JPGDEC_W MTK_SMMU_PORT_ID(24, 17) +#define SMMU_L24_P18_JPGDEC_BS MTK_SMMU_PORT_ID(24, 18) +#define SMMU_L24_P19_NBM_W MTK_SMMU_PORT_ID(24, 19) +#define SMMU_L24_P20_NBM_W_LITE MTK_SMMU_PORT_ID(24, 20) +#define SMMU_L24_P21_CUR_LUMA MTK_SMMU_PORT_ID(24, 21) +#define SMMU_L24_P22_CUR_CHROMA MTK_SMMU_PORT_ID(24, 22) +#define SMMU_L24_P23_REF_LUMA MTK_SMMU_PORT_ID(24, 23) +#define SMMU_L24_P24_REF_CHROMA MTK_SMMU_PORT_ID(24, 24) +#define SMMU_L24_P25_FCS_SUB_R MTK_SMMU_PORT_ID(24, 25) +#define SMMU_L24_P26_FCS_NBM_W MTK_SMMU_PORT_ID(24, 26) +#define SMMU_L24_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(24, 27) +#define SMMU_L24_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(24, 28) +#define SMMU_L24_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(24, 29) +#define SMMU_L24_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(24, 30) +#define SMMU_L24_P31_EC_SYSRAM MTK_SMMU_PORT_ID(24, 31) + +/* Larb25 -- 16 */ +#define SMMU_L25_P0_CQI_M1 MTK_SMMU_PORT_ID(25, 0) +#define SMMU_L25_P1_IMGO_M1 MTK_SMMU_PORT_ID(25, 1) +#define SMMU_L25_P2_CQI_M1 MTK_SMMU_PORT_ID(25, 2) +#define SMMU_L25_P3_IMGO_M1 MTK_SMMU_PORT_ID(25, 3) +#define SMMU_L25_P4_SMIR0 MTK_SMMU_PORT_ID(25, 4) +#define SMMU_L25_P5_SMIR1 MTK_SMMU_PORT_ID(25, 5) +#define SMMU_L25_P6_SMIR2 MTK_SMMU_PORT_ID(25, 6) +#define SMMU_L25_P7_SMIR3 MTK_SMMU_PORT_ID(25, 7) +#define SMMU_L25_P8_SMIR4 MTK_SMMU_PORT_ID(25, 8) +#define SMMU_L25_P9_SMIW MTK_SMMU_PORT_ID(25, 9) +#define SMMU_L25_P10_STG_WR MTK_SMMU_PORT_ID(25, 10) +#define SMMU_L25_P11_STG_M1 MTK_SMMU_PORT_ID(25, 11) +#define SMMU_L25_P12_STG_M1 MTK_SMMU_PORT_ID(25, 12) +#define SMMU_L25_P13_RESERVED_0 MTK_SMMU_PORT_ID(25, 13) +#define SMMU_L25_P14_RESERVED_1 MTK_SMMU_PORT_ID(25, 14) +#define SMMU_L25_P15_RESERVED_2 MTK_SMMU_PORT_ID(25, 15) + +/* Larb26 -- 16 */ +#define SMMU_L26_P0_CQI_M1 MTK_SMMU_PORT_ID(26, 0) +#define SMMU_L26_P1_IMGO_M1 MTK_SMMU_PORT_ID(26, 1) +#define SMMU_L26_P2_CQI_M1 MTK_SMMU_PORT_ID(26, 2) +#define SMMU_L26_P3_IMGO_M1 MTK_SMMU_PORT_ID(26, 3) +#define SMMU_L26_P4_SMIR0 MTK_SMMU_PORT_ID(26, 4) +#define SMMU_L26_P5_SMIR1 MTK_SMMU_PORT_ID(26, 5) +#define SMMU_L26_P6_SMIR2 MTK_SMMU_PORT_ID(26, 6) +#define SMMU_L26_P7_SMIR3 MTK_SMMU_PORT_ID(26, 7) +#define SMMU_L26_P8_SMIR4 MTK_SMMU_PORT_ID(26, 8) +#define SMMU_L26_P9_SMIW MTK_SMMU_PORT_ID(26, 9) +#define SMMU_L26_P10_STG_WR MTK_SMMU_PORT_ID(26, 10) +#define SMMU_L26_P11_STG_M1 MTK_SMMU_PORT_ID(26, 11) +#define SMMU_L26_P12_STG_M1 MTK_SMMU_PORT_ID(26, 12) +#define SMMU_L26_P13_RESERVED_0 MTK_SMMU_PORT_ID(26, 13) +#define SMMU_L26_P14_RESERVED_1 MTK_SMMU_PORT_ID(26, 14) +#define SMMU_L26_P15_RESERVED_2 MTK_SMMU_PORT_ID(26, 15) + +/* Larb27 -- 9 */ +#define SMMU_L27_P0_IPUI_I1 MTK_SMMU_PORT_ID(27, 0) +#define SMMU_L27_P1_ROOTCQ_CQI_E1 MTK_SMMU_PORT_ID(27, 1) +#define SMMU_L27_P2_IPUO_O1 MTK_SMMU_PORT_ID(27, 2) +#define SMMU_L27_P3_CQI_U1 MTK_SMMU_PORT_ID(27, 3) +#define SMMU_L27_P4_STG_U1 MTK_SMMU_PORT_ID(27, 4) +#define SMMU_L27_P5_CAMSV_A1_WDMA MTK_SMMU_PORT_ID(27, 5) +#define SMMU_L27_P6_CAMSV_B1_WDMA MTK_SMMU_PORT_ID(27, 6) +#define SMMU_L27_P7_IMGO_U1 MTK_SMMU_PORT_ID(27, 7) +#define SMMU_L27_P8_YUVO_U1 MTK_SMMU_PORT_ID(27, 8) + +/* Larb28 -- 9 */ +#define SMMU_L28_P0_IMGI_T1_A MTK_SMMU_PORT_ID(28, 0) +#define SMMU_L28_P1_IMGCI_T1_A MTK_SMMU_PORT_ID(28, 1) +#define SMMU_L28_P2_YUVO_T1_A MTK_SMMU_PORT_ID(28, 2) +#define SMMU_L28_P3_YUVCO_T1_A MTK_SMMU_PORT_ID(28, 3) +#define SMMU_L28_P4_YUVO_T2_A MTK_SMMU_PORT_ID(28, 4) +#define SMMU_L28_P5_YUVBO_T2_A MTK_SMMU_PORT_ID(28, 5) +#define SMMU_L28_P6_STG_T1_A MTK_SMMU_PORT_ID(28, 6) +#define SMMU_L28_P7_IMGI_T1_N_A MTK_SMMU_PORT_ID(28, 7) +#define SMMU_L28_P8_DUMMY MTK_SMMU_PORT_ID(28, 8) + +/* Larb29 -- 14 */ +#define SMMU_L29_P0_CAMSV_C_CQI_E1 MTK_SMMU_PORT_ID(29, 0) +#define SMMU_L29_P1_CAMSV_D_CQI_E1 MTK_SMMU_PORT_ID(29, 1) +#define SMMU_L29_P2_CAMSV_E_CQI_E1 MTK_SMMU_PORT_ID(29, 2) +#define SMMU_L29_P3_CAMSV_F_CQI_E1 MTK_SMMU_PORT_ID(29, 3) +#define SMMU_L29_P4_CAMSV_C_WDMA MTK_SMMU_PORT_ID(29, 4) +#define SMMU_L29_P5_CAMSV_D_WDMA MTK_SMMU_PORT_ID(29, 5) +#define SMMU_L29_P6_CAMSV_E_WDMA MTK_SMMU_PORT_ID(29, 6) +#define SMMU_L29_P7_CAMSV_F_WDMA MTK_SMMU_PORT_ID(29, 7) +#define SMMU_L29_P8_RESERVED_0 MTK_SMMU_PORT_ID(29, 8) +#define SMMU_L29_P9_RESERVED_1 MTK_SMMU_PORT_ID(29, 9) +#define SMMU_L29_P10_CAMSV_C_STG MTK_SMMU_PORT_ID(29, 10) +#define SMMU_L29_P11_CAMSV_D_STG MTK_SMMU_PORT_ID(29, 11) +#define SMMU_L29_P12_CAMSV_E_STG MTK_SMMU_PORT_ID(29, 12) +#define SMMU_L29_P13_CAMSV_F_STG MTK_SMMU_PORT_ID(29, 13) + +/* Larb30 -- 4 */ +#define SMMU_L30_P0_CCUI MTK_SMMU_PORT_ID(30, 0) +#define SMMU_L30_P1_CCUO MTK_SMMU_PORT_ID(30, 1) +#define SMMU_L30_P2_CCUI2 MTK_SMMU_PORT_ID(30, 2) +#define SMMU_L30_P3_CCUO2 MTK_SMMU_PORT_ID(30, 3) + +/* Larb31 -- dummy */ + +/* Larb32 -- 10 */ +#define SMMU_L32_P0_DISP_RESERVED_0 MTK_SMMU_PORT_ID(32, 0) +#define SMMU_L32_P1_DISP_RESERVED_1 MTK_SMMU_PORT_ID(32, 1) +#define SMMU_L32_P2_DISP_RESERVED_2 MTK_SMMU_PORT_ID(32, 2) +#define SMMU_L32_P3_DISP_RESERVED_3 MTK_SMMU_PORT_ID(32, 3) +#define SMMU_L32_P4_DISP_POSTMASK0 MTK_SMMU_PORT_ID(32, 4) +#define SMMU_L32_P5_DISP_POSTMASK1 MTK_SMMU_PORT_ID(32, 5) +#define SMMU_L32_P6_DISP_MDP_RDMA0 MTK_SMMU_PORT_ID(32, 6) +#define SMMU_L32_P7_DISP_WDMA0 MTK_SMMU_PORT_ID(32, 7) +#define SMMU_L32_P8_DISP_FAKE_ENG0 MTK_SMMU_PORT_ID(32, 8) +#define SMMU_L32_P9_DISP_MDP_RDMA0_STASH MTK_SMMU_PORT_ID(32, 9) + +/* Larb33 -- 16 */ +#define SMMU_L33_P0_DISP1_ODDMR0_DMRR0 MTK_SMMU_PORT_ID(33, 0) +#define SMMU_L33_P1_RESERVED MTK_SMMU_PORT_ID(33, 1) +#define SMMU_L33_P2_RESERVED MTK_SMMU_PORT_ID(33, 2) +#define SMMU_L33_P3_RESERVED MTK_SMMU_PORT_ID(33, 3) +#define SMMU_L33_P4_DISP1_ODDMR0_DBIR MTK_SMMU_PORT_ID(33, 4) +#define SMMU_L33_P5_DISP1_ODDMR0_ODR MTK_SMMU_PORT_ID(33, 5) +#define SMMU_L33_P6_DISP1_ODDMR0_ODW MTK_SMMU_PORT_ID(33, 6) +#define SMMU_L33_P7_RESERVED MTK_SMMU_PORT_ID(33, 7) +#define SMMU_L33_P8_DISP1_GDMA0 MTK_SMMU_PORT_ID(33, 8) +#define SMMU_L33_P9_DISP1_MDP_RDMA1 MTK_SMMU_PORT_ID(33, 9) +#define SMMU_L33_P10_DISP1_WDMA1 MTK_SMMU_PORT_ID(33, 10) +#define SMMU_L33_P11_DISP1_WDMA2 MTK_SMMU_PORT_ID(33, 11) +#define SMMU_L33_P12_DISP1_WDMA3 MTK_SMMU_PORT_ID(33, 12) +#define SMMU_L33_P13_DISP1_WDMA4 MTK_SMMU_PORT_ID(33, 13) +#define SMMU_L33_P14_DISP1_MDP_RDMA1_STASH MTK_SMMU_PORT_ID(33, 14) +#define SMMU_L33_P15_RESERVED MTK_SMMU_PORT_ID(33, 15) + +/* Larb34 -- 13 */ +#define SMMU_L34_P0_OVL_RDMA2_HDR MTK_SMMU_PORT_ID(34, 0) +#define SMMU_L34_P1_OVL_RDMA7_HDR MTK_SMMU_PORT_ID(34, 1) +#define SMMU_L34_P2_OVL_RDMA2 MTK_SMMU_PORT_ID(34, 2) +#define SMMU_L34_P3_OVL_RDMA7 MTK_SMMU_PORT_ID(34, 3) +#define SMMU_L34_P4_RESERVED MTK_SMMU_PORT_ID(34, 4) +#define SMMU_L34_P5_RESERVED MTK_SMMU_PORT_ID(34, 5) +#define SMMU_L34_P6_OVL_RDMA2_HDR_STASH MTK_SMMU_PORT_ID(34, 6) +#define SMMU_L34_P7_OVL_RDMA7_HDR_STASH MTK_SMMU_PORT_ID(34, 7) +#define SMMU_L34_P8_OVL_RDMA2_STASH MTK_SMMU_PORT_ID(34, 8) +#define SMMU_L34_P9_OVL_RDMA7_STASH MTK_SMMU_PORT_ID(34, 9) +#define SMMU_L34_P10_RESERVED MTK_SMMU_PORT_ID(34, 10) +#define SMMU_L34_P11_RESERVED MTK_SMMU_PORT_ID(34, 11) +#define SMMU_L34_P12_DISP_FAKE0 MTK_SMMU_PORT_ID(34, 12) + +/* Larb35 -- 16 */ +#define SMMU_L35_P0_OVL_RDMA3_HDR MTK_SMMU_PORT_ID(35, 0) +#define SMMU_L35_P1_OVL_RDMA6_HDR MTK_SMMU_PORT_ID(35, 1) +#define SMMU_L35_P2_OVL_RDMA3 MTK_SMMU_PORT_ID(35, 2) +#define SMMU_L35_P3_OVL_RDMA6 MTK_SMMU_PORT_ID(35, 3) +#define SMMU_L35_P4_MDP_RDMA1 MTK_SMMU_PORT_ID(35, 4) +#define SMMU_L35_P5_RESERVED MTK_SMMU_PORT_ID(35, 5) +#define SMMU_L35_P6_DISP_WDMA1 MTK_SMMU_PORT_ID(35, 6) +#define SMMU_L35_P7_OVL_RDMA3_HDR_STASH MTK_SMMU_PORT_ID(35, 7) +#define SMMU_L35_P8_OVL_RDMA6_HDR_STASH MTK_SMMU_PORT_ID(35, 8) +#define SMMU_L35_P9_OVL_RDMA3_STASH MTK_SMMU_PORT_ID(35, 9) +#define SMMU_L35_P10_OVL_RDMA6_STASH MTK_SMMU_PORT_ID(35, 10) +#define SMMU_L35_P11_MDP_RDMA1_STASH MTK_SMMU_PORT_ID(35, 11) +#define SMMU_L35_P12_DISP_BWM0 MTK_SMMU_PORT_ID(35, 12) +#define SMMU_L35_P13_DISP_BWM0_STASH MTK_SMMU_PORT_ID(35, 13) +#define SMMU_L35_P14_RESERVED MTK_SMMU_PORT_ID(35, 14) +#define SMMU_L35_P15_DISP_FAKE1 MTK_SMMU_PORT_ID(35, 15) + +/* Larb36 -- 15 */ +#define SMMU_L36_P0_OVL_RDMA4_HDR MTK_SMMU_PORT_ID(36, 0) +#define SMMU_L36_P1_OVL_RDMA9_HDR MTK_SMMU_PORT_ID(36, 1) +#define SMMU_L36_P2_OVL_RDMA0_HDR MTK_SMMU_PORT_ID(36, 2) +#define SMMU_L36_P3_OVL_RDMA4 MTK_SMMU_PORT_ID(36, 3) +#define SMMU_L36_P4_OVL_RDMA9 MTK_SMMU_PORT_ID(36, 4) +#define SMMU_L36_P5_OVL_RDMA0 MTK_SMMU_PORT_ID(36, 5) +#define SMMU_L36_P6_RESERVED MTK_SMMU_PORT_ID(36, 6) +#define SMMU_L36_P7_OVL_RDMA4_HDR_STASH MTK_SMMU_PORT_ID(36, 7) +#define SMMU_L36_P8_OVL_RDMA9_HDR_STASH MTK_SMMU_PORT_ID(36, 8) +#define SMMU_L36_P9_OVL_RDMA0_HDR_STASH MTK_SMMU_PORT_ID(36, 9) +#define SMMU_L36_P10_OVL_RDMA4_STASH MTK_SMMU_PORT_ID(36, 10) +#define SMMU_L36_P11_OVL_RDMA9_STASH MTK_SMMU_PORT_ID(36, 11) +#define SMMU_L36_P12_OVL_RDMA0_STASH MTK_SMMU_PORT_ID(36, 12) +#define SMMU_L36_P13_RESERVED MTK_SMMU_PORT_ID(36, 13) +#define SMMU_L36_P14_RESERVED MTK_SMMU_PORT_ID(36, 14) + +/* Larb37 -- 18 */ +#define SMMU_L37_P0_OVL_RDMA5_HDR MTK_SMMU_PORT_ID(37, 0) +#define SMMU_L37_P1_OVL_RDMA8_HDR MTK_SMMU_PORT_ID(37, 1) +#define SMMU_L37_P2_OVL_RDMA1_HDR MTK_SMMU_PORT_ID(37, 2) +#define SMMU_L37_P3_OVL_RDMA5 MTK_SMMU_PORT_ID(37, 3) +#define SMMU_L37_P4_OVL_RDMA8 MTK_SMMU_PORT_ID(37, 4) +#define SMMU_L37_P5_OVL_RDMA1 MTK_SMMU_PORT_ID(37, 5) +#define SMMU_L37_P6_RESERVED MTK_SMMU_PORT_ID(37, 6) +#define SMMU_L37_P7_MDP_RDMA0 MTK_SMMU_PORT_ID(37, 7) +#define SMMU_L37_P8_DISP_WDMA0 MTK_SMMU_PORT_ID(37, 8) +#define SMMU_L37_P9_DISP_UFBC_WDMA0 MTK_SMMU_PORT_ID(37, 9) +#define SMMU_L37_P10_OVL_RDMA5_HDR_STASH MTK_SMMU_PORT_ID(37, 10) +#define SMMU_L37_P11_OVL_RDMA8_HDR_STASH MTK_SMMU_PORT_ID(37, 11) +#define SMMU_L37_P12_OVL_RDMA1_HDR_STASH MTK_SMMU_PORT_ID(37, 12) +#define SMMU_L37_P13_OVL_RDMA5_STASH MTK_SMMU_PORT_ID(37, 13) +#define SMMU_L37_P14_OVL_RDMA8_STASH MTK_SMMU_PORT_ID(37, 14) +#define SMMU_L37_P15_OVL_RDMA1_STASH MTK_SMMU_PORT_ID(37, 15) +#define SMMU_L37_P16_MDP_RDMA0_STASH MTK_SMMU_PORT_ID(37, 16) +#define SMMU_L37_P17_RESERVED MTK_SMMU_PORT_ID(37, 17) + +/* Larb38 -- 15 */ +#define SMMU_L38_P0_TNRWI_D1 MTK_SMMU_PORT_ID(38, 0) +#define SMMU_L38_P1_RECBI_D1 MTK_SMMU_PORT_ID(38, 1) +#define SMMU_L38_P2_RECI_D3 MTK_SMMU_PORT_ID(38, 2) +#define SMMU_L38_P3_SMTI_D1 MTK_SMMU_PORT_ID(38, 3) +#define SMMU_L38_P4_SMTCI_D1 MTK_SMMU_PORT_ID(38, 4) +#define SMMU_L38_P5_IMG4O_D1 MTK_SMMU_PORT_ID(38, 5) +#define SMMU_L38_P6_IMG4CO_D1 MTK_SMMU_PORT_ID(38, 6) +#define SMMU_L38_P7_TNRMO_D1 MTK_SMMU_PORT_ID(38, 7) +#define SMMU_L38_P8_STG_D2 MTK_SMMU_PORT_ID(38, 8) +#define SMMU_L38_P9_STG_D3 MTK_SMMU_PORT_ID(38, 9) +#define SMMU_L38_P10_DUMMY MTK_SMMU_PORT_ID(38, 10) +#define SMMU_L38_P11_SMTO_D1 MTK_SMMU_PORT_ID(38, 11) +#define SMMU_L38_P12_SMTCO_D1 MTK_SMMU_PORT_ID(38, 12) +#define SMMU_L38_P13_YUFETO_D1 MTK_SMMU_PORT_ID(38, 13) +#define SMMU_L38_P14_DUMMY MTK_SMMU_PORT_ID(38, 14) + +/* Larb39 -- 20 */ +#define SMMU_L39_P0_EECSI_D1 MTK_SMMU_PORT_ID(39, 0) +#define SMMU_L39_P1_SNRCSI_D1 MTK_SMMU_PORT_ID(39, 1) +#define SMMU_L39_P2_SNRCSI_D1_N MTK_SMMU_PORT_ID(39, 2) +#define SMMU_L39_P3_SMTI_D4 MTK_SMMU_PORT_ID(39, 3) +#define SMMU_L39_P4_SMTI_D10 MTK_SMMU_PORT_ID(39, 4) +#define SMMU_L39_P5_SMTCI_D4 MTK_SMMU_PORT_ID(39, 5) +#define SMMU_L39_P6_YUFETI_D2 MTK_SMMU_PORT_ID(39, 6) +#define SMMU_L39_P7_BOKMI_D1 MTK_SMMU_PORT_ID(39, 7) +#define SMMU_L39_P8_BOKMI_D1_N MTK_SMMU_PORT_ID(39, 8) +#define SMMU_L39_P9_CNRO_D1 MTK_SMMU_PORT_ID(39, 9) +#define SMMU_L39_P10_BOKMO_D1 MTK_SMMU_PORT_ID(39, 10) +#define SMMU_L39_P11_STG_D5 MTK_SMMU_PORT_ID(39, 11) +#define SMMU_L39_P12_STG_D6 MTK_SMMU_PORT_ID(39, 12) +#define SMMU_L39_P13_DUMMY MTK_SMMU_PORT_ID(39, 13) +#define SMMU_L39_P14_TNCO_D1 MTK_SMMU_PORT_ID(39, 14) +#define SMMU_L39_P15_SMTO_D4 MTK_SMMU_PORT_ID(39, 15) +#define SMMU_L39_P16_SMTO_D10 MTK_SMMU_PORT_ID(39, 16) +#define SMMU_L39_P17_SMTCO_D4 MTK_SMMU_PORT_ID(39, 17) +#define SMMU_L39_P18_YUFETO_D2 MTK_SMMU_PORT_ID(39, 18) +#define SMMU_L39_P19_DUMMY MTK_SMMU_PORT_ID(39, 19) + +/* Larb40 -- 17 */ +#define SMMU_L40_P0_SMTI_T1_A MTK_SMMU_PORT_ID(40, 0) +#define SMMU_L40_P1_SMTI_T4_A MTK_SMMU_PORT_ID(40, 1) +#define SMMU_L40_P2_TNCSTI_T2_A MTK_SMMU_PORT_ID(40, 2) +#define SMMU_L40_P3_LTMSTI_T1_A MTK_SMMU_PORT_ID(40, 3) +#define SMMU_L40_P4_FBWO_T1_A MTK_SMMU_PORT_ID(40, 4) +#define SMMU_L40_P5_TIMGO_T1_A MTK_SMMU_PORT_ID(40, 5) +#define SMMU_L40_P6_TNCSTO_T1_A MTK_SMMU_PORT_ID(40, 6) +#define SMMU_L40_P7_YUFETI_T1_A MTK_SMMU_PORT_ID(40, 7) +#define SMMU_L40_P8_STG_T2_A MTK_SMMU_PORT_ID(40, 8) +#define SMMU_L40_P9_STG_T3_A MTK_SMMU_PORT_ID(40, 9) +#define SMMU_L40_P10_DUMMY MTK_SMMU_PORT_ID(40, 10) +#define SMMU_L40_P11_TNCSO_T1_A MTK_SMMU_PORT_ID(40, 11) +#define SMMU_L40_P12_SMTO_T1_A MTK_SMMU_PORT_ID(40, 12) +#define SMMU_L40_P13_SMTO_T4_A MTK_SMMU_PORT_ID(40, 13) +#define SMMU_L40_P14_LTMSBO_T1_A MTK_SMMU_PORT_ID(40, 14) +#define SMMU_L40_P15_YUFETO_T1_A MTK_SMMU_PORT_ID(40, 15) +#define SMMU_L40_P16_DUMMY MTK_SMMU_PORT_ID(40, 16) + +/* Larb41 -- 32 */ +#define SMMU_L41_P0_ADAB_FORMATTER_R MTK_SMMU_PORT_ID(41, 0) +#define SMMU_L41_P1_REC_FRM MTK_SMMU_PORT_ID(41, 1) +#define SMMU_L41_P2_ADAB_FORMATTER_W MTK_SMMU_PORT_ID(41, 2) +#define SMMU_L41_P3_ADAB_CUR_LUMA_R MTK_SMMU_PORT_ID(41, 3) +#define SMMU_L41_P4_ADAB_REF_LUMA_R MTK_SMMU_PORT_ID(41, 4) +#define SMMU_L41_P5_NBM_R MTK_SMMU_PORT_ID(41, 5) +#define SMMU_L41_P6_NBM_R_LITE MTK_SMMU_PORT_ID(41, 6) +#define SMMU_L41_P7_JPGENC_YRD MTK_SMMU_PORT_ID(41, 7) +#define SMMU_L41_P8_JPGENC_CRD MTK_SMMU_PORT_ID(41, 8) +#define SMMU_L41_P9_JPGENC_QT MTK_SMMU_PORT_ID(41, 9) +#define SMMU_L41_P10_FCS_SUB_W MTK_SMMU_PORT_ID(41, 10) +#define SMMU_L41_P11_FCS_NBM_R MTK_SMMU_PORT_ID(41, 11) +#define SMMU_L41_P12_WPP_BS MTK_SMMU_PORT_ID(41, 12) +#define SMMU_L41_P13_WPP_RDMA MTK_SMMU_PORT_ID(41, 13) +#define SMMU_L41_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(41, 14) +#define SMMU_L41_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(41, 15) +#define SMMU_L41_P16_JPGENC_BS MTK_SMMU_PORT_ID(41, 16) +#define SMMU_L41_P17_JPGDEC_W MTK_SMMU_PORT_ID(41, 17) +#define SMMU_L41_P18_JPGDEC_BS MTK_SMMU_PORT_ID(41, 18) +#define SMMU_L41_P19_NBM_W MTK_SMMU_PORT_ID(41, 19) +#define SMMU_L41_P20_NBM_W_LITE MTK_SMMU_PORT_ID(41, 20) +#define SMMU_L41_P21_CUR_LUMA MTK_SMMU_PORT_ID(41, 21) +#define SMMU_L41_P22_CUR_CHROMA MTK_SMMU_PORT_ID(41, 22) +#define SMMU_L41_P23_REF_LUMA MTK_SMMU_PORT_ID(41, 23) +#define SMMU_L41_P24_REF_CHROMA MTK_SMMU_PORT_ID(41, 24) +#define SMMU_L41_P25_FCS_SUB_R MTK_SMMU_PORT_ID(41, 25) +#define SMMU_L41_P26_FCS_NBM_W MTK_SMMU_PORT_ID(41, 26) +#define SMMU_L41_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(41, 27) +#define SMMU_L41_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(41, 28) +#define SMMU_L41_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(41, 29) +#define SMMU_L41_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(41, 30) +#define SMMU_L41_P31_EC_SYSRAM MTK_SMMU_PORT_ID(41, 31) + +/* Larb42 -- 32 */ +#define SMMU_L42_P0_RCPU MTK_SMMU_PORT_ID(42, 0) +#define SMMU_L42_P1_REC_FRM MTK_SMMU_PORT_ID(42, 1) +#define SMMU_L42_P2_BS MTK_SMMU_PORT_ID(42, 2) +#define SMMU_L42_P3_SVCOMV MTK_SMMU_PORT_ID(42, 3) +#define SMMU_L42_P4_RDCOMV MTK_SMMU_PORT_ID(42, 4) +#define SMMU_L42_P5_NBM_R MTK_SMMU_PORT_ID(42, 5) +#define SMMU_L42_P6_NBM_R_LITE MTK_SMMU_PORT_ID(42, 6) +#define SMMU_L42_P7_JPGENC_YRD MTK_SMMU_PORT_ID(42, 7) +#define SMMU_L42_P8_JPGENC_CRD MTK_SMMU_PORT_ID(42, 8) +#define SMMU_L42_P9_JPGENC_QT MTK_SMMU_PORT_ID(42, 9) +#define SMMU_L42_P10_FCS_SUB_W MTK_SMMU_PORT_ID(42, 10) +#define SMMU_L42_P11_FCS_NBM_R MTK_SMMU_PORT_ID(42, 11) +#define SMMU_L42_P12_WPP_BS MTK_SMMU_PORT_ID(42, 12) +#define SMMU_L42_P13_WPP_RDMA MTK_SMMU_PORT_ID(42, 13) +#define SMMU_L42_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(42, 14) +#define SMMU_L42_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(42, 15) +#define SMMU_L42_P16_JPGENC_BS MTK_SMMU_PORT_ID(42, 16) +#define SMMU_L42_P17_JPGDEC_W MTK_SMMU_PORT_ID(42, 17) +#define SMMU_L42_P18_JPGDEC_BS MTK_SMMU_PORT_ID(42, 18) +#define SMMU_L42_P19_NBM_W MTK_SMMU_PORT_ID(42, 19) +#define SMMU_L42_P20_NBM_W_LITE MTK_SMMU_PORT_ID(42, 20) +#define SMMU_L42_P21_CUR_LUMA MTK_SMMU_PORT_ID(42, 21) +#define SMMU_L42_P22_CUR_CHROMA MTK_SMMU_PORT_ID(42, 22) +#define SMMU_L42_P23_REF_LUMA MTK_SMMU_PORT_ID(42, 23) +#define SMMU_L42_P24_REF_CHROMA MTK_SMMU_PORT_ID(42, 24) +#define SMMU_L42_P25_FCS_SUB_R MTK_SMMU_PORT_ID(42, 25) +#define SMMU_L42_P26_FCS_NBM_W MTK_SMMU_PORT_ID(42, 26) +#define SMMU_L42_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(42, 27) +#define SMMU_L42_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(42, 28) +#define SMMU_L42_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(42, 29) +#define SMMU_L42_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(42, 30) +#define SMMU_L42_P31_EC_SYSRAM MTK_SMMU_PORT_ID(42, 31) + +/* Larb43 -- 19 */ +#define SMMU_L43_P0_CQI_R1 MTK_SMMU_PORT_ID(43, 0) +#define SMMU_L43_P1_CQI_R5 MTK_SMMU_PORT_ID(43, 1) +#define SMMU_L43_P2_RAWI_R2 MTK_SMMU_PORT_ID(43, 2) +#define SMMU_L43_P3_RAWI_R3 MTK_SMMU_PORT_ID(43, 3) +#define SMMU_L43_P4_RAWI_R4 MTK_SMMU_PORT_ID(43, 4) +#define SMMU_L43_P5_RAWI_R5 MTK_SMMU_PORT_ID(43, 5) +#define SMMU_L43_P6_BPCI_R1 MTK_SMMU_PORT_ID(43, 6) +#define SMMU_L43_P7_BPCI_R3 MTK_SMMU_PORT_ID(43, 7) +#define SMMU_L43_P8_GRMGI_R1 MTK_SMMU_PORT_ID(43, 8) +#define SMMU_L43_P9_LSCI_R1 MTK_SMMU_PORT_ID(43, 9) +#define SMMU_L43_P10_IMGO_R1 MTK_SMMU_PORT_ID(43, 10) +#define SMMU_L43_P11_IMGO_R2 MTK_SMMU_PORT_ID(43, 11) +#define SMMU_L43_P12_DRZB2NO_R1 MTK_SMMU_PORT_ID(43, 12) +#define SMMU_L43_P13_DRZB2NBO_R1 MTK_SMMU_PORT_ID(43, 13) +#define SMMU_L43_P14_GMPO_R1 MTK_SMMU_PORT_ID(43, 14) +#define SMMU_L43_P15_DRZB2NCO_R1 MTK_SMMU_PORT_ID(43, 15) +#define SMMU_L43_P16_AWBO_R1 MTK_SMMU_PORT_ID(43, 16) +#define SMMU_L43_P17_STG_R1 MTK_SMMU_PORT_ID(43, 17) +#define SMMU_L43_P18_STG_R2 MTK_SMMU_PORT_ID(43, 18) + +/* Larb44 -- 19 */ +#define SMMU_L44_P0_CQI_R1 MTK_SMMU_PORT_ID(44, 0) +#define SMMU_L44_P1_CQI_R5 MTK_SMMU_PORT_ID(44, 1) +#define SMMU_L44_P2_RAWI_R2 MTK_SMMU_PORT_ID(44, 2) +#define SMMU_L44_P3_RAWI_R3 MTK_SMMU_PORT_ID(44, 3) +#define SMMU_L44_P4_RAWI_R4 MTK_SMMU_PORT_ID(44, 4) +#define SMMU_L44_P5_RAWI_R5 MTK_SMMU_PORT_ID(44, 5) +#define SMMU_L44_P6_BPCI_R1 MTK_SMMU_PORT_ID(44, 6) +#define SMMU_L44_P7_BPCI_R3 MTK_SMMU_PORT_ID(44, 7) +#define SMMU_L44_P8_GRMGI_R1 MTK_SMMU_PORT_ID(44, 8) +#define SMMU_L44_P9_LSCI_R1 MTK_SMMU_PORT_ID(44, 9) +#define SMMU_L44_P10_IMGO_R1 MTK_SMMU_PORT_ID(44, 10) +#define SMMU_L44_P11_IMGO_R2 MTK_SMMU_PORT_ID(44, 11) +#define SMMU_L44_P12_DRZB2NO_R1 MTK_SMMU_PORT_ID(44, 12) +#define SMMU_L44_P13_DRZB2NBO_R1 MTK_SMMU_PORT_ID(44, 13) +#define SMMU_L44_P14_GMPO_R1 MTK_SMMU_PORT_ID(44, 14) +#define SMMU_L44_P15_DRZB2NCO_R1 MTK_SMMU_PORT_ID(44, 15) +#define SMMU_L44_P16_AWBO_R1 MTK_SMMU_PORT_ID(44, 16) +#define SMMU_L44_P17_STG_R1 MTK_SMMU_PORT_ID(44, 17) +#define SMMU_L44_P18_STG_R2 MTK_SMMU_PORT_ID(44, 18) + +/* Larb45 -- 7 */ +#define SMMU_L45_P0_YUVO_R1 MTK_SMMU_PORT_ID(45, 0) +#define SMMU_L45_P1_YUVO_R3 MTK_SMMU_PORT_ID(45, 1) +#define SMMU_L45_P2_YUVO_R2 MTK_SMMU_PORT_ID(45, 2) +#define SMMU_L45_P3_DRZH2NO_R1 MTK_SMMU_PORT_ID(45, 3) +#define SMMU_L45_P4_YUVO_R4 MTK_SMMU_PORT_ID(45, 4) +#define SMMU_L45_P5_DRZH1NO_R1 MTK_SMMU_PORT_ID(45, 5) +#define SMMU_L45_P6_STG_R3 MTK_SMMU_PORT_ID(45, 6) + +/* Larb46 -- 7 */ +#define SMMU_L46_P0_YUVO_R1 MTK_SMMU_PORT_ID(46, 0) +#define SMMU_L46_P1_YUVO_R3 MTK_SMMU_PORT_ID(46, 1) +#define SMMU_L46_P2_YUVO_R2 MTK_SMMU_PORT_ID(46, 2) +#define SMMU_L46_P3_DRZH2NO_R1 MTK_SMMU_PORT_ID(46, 3) +#define SMMU_L46_P4_YUVO_R4 MTK_SMMU_PORT_ID(46, 4) +#define SMMU_L46_P5_DRZH1NO_R1 MTK_SMMU_PORT_ID(46, 5) +#define SMMU_L46_P6_STG_R3 MTK_SMMU_PORT_ID(46, 6) + +/* Larb47 -- 32 */ +#define SMMU_L47_P0_RCPU MTK_SMMU_PORT_ID(47, 0) +#define SMMU_L47_P1_REC_FRM MTK_SMMU_PORT_ID(47, 1) +#define SMMU_L47_P2_BS MTK_SMMU_PORT_ID(47, 2) +#define SMMU_L47_P3_SVCOMV MTK_SMMU_PORT_ID(47, 3) +#define SMMU_L47_P4_RDCOMV MTK_SMMU_PORT_ID(47, 4) +#define SMMU_L47_P5_NBM_R MTK_SMMU_PORT_ID(47, 5) +#define SMMU_L47_P6_NBM_R_LITE MTK_SMMU_PORT_ID(47, 6) +#define SMMU_L47_P7_JPGENC_YRD MTK_SMMU_PORT_ID(47, 7) +#define SMMU_L47_P8_JPGENC_CRD MTK_SMMU_PORT_ID(47, 8) +#define SMMU_L47_P9_JPGENC_QT MTK_SMMU_PORT_ID(47, 9) +#define SMMU_L47_P10_FCS_SUB_W MTK_SMMU_PORT_ID(47, 10) +#define SMMU_L47_P11_FCS_NBM_R MTK_SMMU_PORT_ID(47, 11) +#define SMMU_L47_P12_WPP_BS MTK_SMMU_PORT_ID(47, 12) +#define SMMU_L47_P13_WPP_RDMA MTK_SMMU_PORT_ID(47, 13) +#define SMMU_L47_P14_DB_SYSRAM_W MTK_SMMU_PORT_ID(47, 14) +#define SMMU_L47_P15_DB_SYSRAM_R MTK_SMMU_PORT_ID(47, 15) +#define SMMU_L47_P16_JPGENC_BS MTK_SMMU_PORT_ID(47, 16) +#define SMMU_L47_P17_JPGDEC_W MTK_SMMU_PORT_ID(47, 17) +#define SMMU_L47_P18_JPGDEC_BS MTK_SMMU_PORT_ID(47, 18) +#define SMMU_L47_P19_NBM_W MTK_SMMU_PORT_ID(47, 19) +#define SMMU_L47_P20_NBM_W_LITE MTK_SMMU_PORT_ID(47, 20) +#define SMMU_L47_P21_CUR_LUMA MTK_SMMU_PORT_ID(47, 21) +#define SMMU_L47_P22_CUR_CHROMA MTK_SMMU_PORT_ID(47, 22) +#define SMMU_L47_P23_REF_LUMA MTK_SMMU_PORT_ID(47, 23) +#define SMMU_L47_P24_REF_CHROMA MTK_SMMU_PORT_ID(47, 24) +#define SMMU_L47_P25_FCS_SUB_R MTK_SMMU_PORT_ID(47, 25) +#define SMMU_L47_P26_FCS_NBM_W MTK_SMMU_PORT_ID(47, 26) +#define SMMU_L47_P27_JPGDEC_W_1 MTK_SMMU_PORT_ID(47, 27) +#define SMMU_L47_P28_JPGDEC_BS_1 MTK_SMMU_PORT_ID(47, 28) +#define SMMU_L47_P29_JPGDEC_HUF_1 MTK_SMMU_PORT_ID(47, 29) +#define SMMU_L47_P30_JPGDEC_HUF MTK_SMMU_PORT_ID(47, 30) +#define SMMU_L47_P31_EC_SYSRAM MTK_SMMU_PORT_ID(47, 31) + +/* Fake larb48 */ +#define SMMU_L48_CCU0 MTK_SMMU_PORT_ID(48, 0) +#define SMMU_L48_CCU1 MTK_SMMU_PORT_ID(48, 1) + +/* Fake larb49 */ +#define SMMU_L49_MMUP MTK_SMMU_PORT_ID(49, 0) +#define SMMU_L49_GCE_D MTK_SMMU_PORT_ID(49, 1) +#define SMMU_L49_GCE_M MTK_SMMU_PORT_ID(49, 2) + +#endif /* _DTS_IOMMU_PORT_MT8196_H_ */ -- GitLab From 30358ece8e25e16ac90f1b6d3a74ce53da26dfab Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:44:31 +0800 Subject: [PATCH 279/456] CHROMIUM: dt-bindings: memory: Add MediaTek SMI header Add MT8196 SMI header. BUG=b:385017273, b:383247849 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:354020406 Change-Id: Icc7edc9e8e06db22ec13cba830befe6a16013e9f Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6147637 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/memory/mtk-smi-user.h | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 include/dt-bindings/memory/mtk-smi-user.h diff --git a/include/dt-bindings/memory/mtk-smi-user.h b/include/dt-bindings/memory/mtk-smi-user.h new file mode 100644 index 0000000000000..d79b77efcd328 --- /dev/null +++ b/include/dt-bindings/memory/mtk-smi-user.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Yc Li + */ +#ifndef MTK_SMI_USER_H +#define MTK_SMI_USER_H + + +#define MTK_SMI_DRIVER (0) +/* disp */ +#define MTK_SMI_DISP (1) +/* MML */ +#define MTK_SMI_MML0 (2) +#define MTK_SMI_MML1 (3) +/* VDEC */ +#define MTK_SMI_VDEC_CORE (4) +#define MTK_SMI_VDEC_LAT (5) +/* VECN */ +#define MTK_SMI_VENC0 (6) +#define MTK_SMI_VENC1 (7) +#define MTK_SMI_VENC2 (8) +#define MTK_SMI_JPEGDEC0 (9) +#define MTK_SMI_JPEGDEC1 (10) +#define MTK_SMI_JPEGENC0 (11) +#define MTK_SMI_JEPGENC1 (12) +/* CAM */ +#define MTK_SMI_CCU (13) +#define MTK_SMI_CAMSV1 (14) +#define MTK_SMI_CAMSV2 (15) +#define MTK_SMI_CAMSV3 (16) +#define MTK_SMI_PDA1 (17) +#define MTK_SMI_PDA2 (18) +#define MTK_SMI_MRAW1 (19) +#define MTK_SMI_MRAW2 (20) +#define MTK_SMI_CAM_RAW (21) +#define MTK_SMI_CAM_RAWA (22) +#define MTK_SMI_CAM_RAWB (23) +#define MTK_SMI_CAM_RAWC (24) +#define MTK_SMI_CAM_YUVA (25) +#define MTK_SMI_CAM_YUVB (26) +#define MTK_SMI_CAM_YUVC (27) +#define MTK_SMI_CAM_AOV (28) +/* IMG */ +#define MTK_SMI_IMG_DPE (29) +#define MTK_SMI_IMG_FW (30) +#define MTK_SMI_IMG_DIP (31) +#define MTK_SMI_IMG_TRAW (32) +#define MTK_SMI_IMG_WPE_EIS (33) +#define MTK_SMI_IMG_WPE_TNR (34) +#define MTK_SMI_IMG_WPE_LITE (35) +#define MTK_SMI_IMG_AOV (36) + +/* MMINFRA */ +#define MTK_SMI_MMINFRA (37) + +#define MTK_SMI_USER_ID_NR (38) + +#endif -- GitLab From 6dbeb412d140a2499a257cf81c87db5ae7c23cd3 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 7 Jan 2025 12:44:31 +0800 Subject: [PATCH 280/456] CHROMIUM: dt-bindings: pinctrl: Add MT8196 pinfunc header Add MT8196 pinfunc header. BUG=b:385017273 TEST=emerge-rauru chromeos-kernel-6_6; Boot to login screen UPSTREAM-TASK=b:379035069 Change-Id: I06d396ef153a610caf1a075fa8ec417b07bb0ac2 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071724 Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- include/dt-bindings/pinctrl/mt8196-pinfunc.h | 1572 ++++++++++++++++++ 1 file changed, 1572 insertions(+) create mode 100644 include/dt-bindings/pinctrl/mt8196-pinfunc.h diff --git a/include/dt-bindings/pinctrl/mt8196-pinfunc.h b/include/dt-bindings/pinctrl/mt8196-pinfunc.h new file mode 100644 index 0000000000000..717351b12255c --- /dev/null +++ b/include/dt-bindings/pinctrl/mt8196-pinfunc.h @@ -0,0 +1,1572 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (C) 2024 Mediatek Inc. + * Author: Guodong Liu + */ + +#ifndef __MT8196_PINFUNC_H +#define __MT8196_PINFUNC_H + +#include + +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_DMIC1_CLK (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_SPI3_A_MO (MTK_PIN_NO(0) | 3) +#define PINMUX_GPIO0__FUNC_FMI2S_B_LRCK (MTK_PIN_NO(0) | 4) +#define PINMUX_GPIO0__FUNC_SCP_DMIC1_CLK (MTK_PIN_NO(0) | 5) +#define PINMUX_GPIO0__FUNC_TP_GPIO14_AO (MTK_PIN_NO(0) | 6) + +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_DMIC1_DAT (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_SRCLKENAI1 (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_SPI3_A_MI (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_FMI2S_B_DI (MTK_PIN_NO(1) | 4) +#define PINMUX_GPIO1__FUNC_SCP_DMIC1_DAT (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_TP_GPIO15_AO (MTK_PIN_NO(1) | 6) + +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_PWM_VLP (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_DSI_HSYNC (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_RG_TSFDC_LDO_EN (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_TP_GPIO8_AO (MTK_PIN_NO(2) | 6) + +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_MD_INT0 (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_DSI1_HSYNC (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_DA_TSFDC_LDO_MODE (MTK_PIN_NO(3) | 5) +#define PINMUX_GPIO3__FUNC_TP_GPIO9_AO (MTK_PIN_NO(3) | 6) + +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_DISP_PWM1 (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_MD32_0_GPIO0 (MTK_PIN_NO(4) | 2) + +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_LCM1_RST (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_SPI7_A_CLK (MTK_PIN_NO(5) | 2) + +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_DSI1_TE (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_SPI7_A_CSB (MTK_PIN_NO(6) | 2) + +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_SPI7_A_MO (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_GPS_PPS0 (MTK_PIN_NO(7) | 3) + +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_SPI7_A_MI (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_EDP_TX_HPD (MTK_PIN_NO(8) | 3) + +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_I2SIN1_LRCK (MTK_PIN_NO(9) | 3) +#define PINMUX_GPIO9__FUNC_RG_TSFDC_LDO_REFSEL0 (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_I2SOUT1_DO (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_RG_TSFDC_LDO_REFSEL1 (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_FMI2S_B_BCK (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_DBG_MON_A30 (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_I2SIN1_DI_B (MTK_PIN_NO(12) | 3) + +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_EDP_TX_HPD (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_GPS_PPS1 (MTK_PIN_NO(13) | 2) + +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_SRCLKENA2 (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_DSI2_TE (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_SPMI_P_TRIG_FLAG (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_MD_INT3 (MTK_PIN_NO(14) | 5) +#define PINMUX_GPIO14__FUNC_TP_GPIO8_AO (MTK_PIN_NO(14) | 6) + +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_SRCLKENAI0 (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_SPMI_M_TRIG_FLAG (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_UCTS0 (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_MD_INT4 (MTK_PIN_NO(15) | 4) +#define PINMUX_GPIO15__FUNC_I2SOUT2_DO (MTK_PIN_NO(15) | 5) +#define PINMUX_GPIO15__FUNC_TP_GPIO9_AO (MTK_PIN_NO(15) | 6) + +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_SRCLKENAI1 (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_DP_TX_HPD (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_URTS0 (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(16) | 4) +#define PINMUX_GPIO16__FUNC_KPROW2 (MTK_PIN_NO(16) | 5) +#define PINMUX_GPIO16__FUNC_TP_GPIO10_AO (MTK_PIN_NO(16) | 6) + +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_MD_INT0 (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_DP_OC_EN (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_UCTS1 (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_MD_NTN_URXD1 (MTK_PIN_NO(17) | 4) +#define PINMUX_GPIO17__FUNC_KPCOL2 (MTK_PIN_NO(17) | 5) +#define PINMUX_GPIO17__FUNC_TP_GPIO11_AO (MTK_PIN_NO(17) | 6) + +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_DMIC1_CLK (MTK_PIN_NO(18) | 1) +#define PINMUX_GPIO18__FUNC_DP_RAUX_SBU1 (MTK_PIN_NO(18) | 2) +#define PINMUX_GPIO18__FUNC_URTS1 (MTK_PIN_NO(18) | 3) +#define PINMUX_GPIO18__FUNC_MD_NTN_UTXD1 (MTK_PIN_NO(18) | 4) +#define PINMUX_GPIO18__FUNC_I2SIN2_DI (MTK_PIN_NO(18) | 5) +#define PINMUX_GPIO18__FUNC_TP_UTXD_GNSS_VLP (MTK_PIN_NO(18) | 6) + +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_DMIC1_DAT (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_DP_RAUX_SBU2 (MTK_PIN_NO(19) | 2) +#define PINMUX_GPIO19__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_CLKM3_A (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_I2SIN2_BCK (MTK_PIN_NO(19) | 5) +#define PINMUX_GPIO19__FUNC_TP_URXD_GNSS_VLP (MTK_PIN_NO(19) | 6) + +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_IDDIG (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_LCM2_RST (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_GPS_PPS1 (MTK_PIN_NO(20) | 3) +#define PINMUX_GPIO20__FUNC_CLKM2_A (MTK_PIN_NO(20) | 4) + +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_BPI_BUS11 (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_PCIE_PERSTN_1P (MTK_PIN_NO(21) | 2) +#define PINMUX_GPIO21__FUNC_DSI1_TE (MTK_PIN_NO(21) | 3) +#define PINMUX_GPIO21__FUNC_DMIC_CLK (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_SCP_DMIC_CLK (MTK_PIN_NO(21) | 5) + +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_BPI_BUS12 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_PCIE_CLKREQN_1P (MTK_PIN_NO(22) | 2) +#define PINMUX_GPIO22__FUNC_DSI2_TE (MTK_PIN_NO(22) | 3) +#define PINMUX_GPIO22__FUNC_DMIC_DAT (MTK_PIN_NO(22) | 4) +#define PINMUX_GPIO22__FUNC_SCP_DMIC_DAT (MTK_PIN_NO(22) | 5) + +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_BPI_BUS13 (MTK_PIN_NO(23) | 1) +#define PINMUX_GPIO23__FUNC_PCIE_WAKEN_1P (MTK_PIN_NO(23) | 2) +#define PINMUX_GPIO23__FUNC_DSI3_TE (MTK_PIN_NO(23) | 3) +#define PINMUX_GPIO23__FUNC_DMIC1_CLK (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_SCP_DMIC1_CLK (MTK_PIN_NO(23) | 5) + +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_BPI_BUS14 (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_LCM1_RST (MTK_PIN_NO(24) | 2) +#define PINMUX_GPIO24__FUNC_AGPS_SYNC (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_DMIC1_DAT (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_SCP_DMIC1_DAT (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_DISP_PWM1 (MTK_PIN_NO(24) | 6) + +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_BPI_BUS15 (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_LCM2_RST (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_SRCLKENAI1 (MTK_PIN_NO(25) | 3) +#define PINMUX_GPIO25__FUNC_DMIC2_CLK (MTK_PIN_NO(25) | 4) +#define PINMUX_GPIO25__FUNC_DISP_PWM2 (MTK_PIN_NO(25) | 6) + +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_BPI_BUS16 (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_LCM3_RST (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_DMIC2_DAT (MTK_PIN_NO(26) | 4) +#define PINMUX_GPIO26__FUNC_DISP_PWM3 (MTK_PIN_NO(26) | 6) + +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_BPI_BUS17 (MTK_PIN_NO(27) | 1) +#define PINMUX_GPIO27__FUNC_UTXD4 (MTK_PIN_NO(27) | 2) +#define PINMUX_GPIO27__FUNC_DISP_PWM4 (MTK_PIN_NO(27) | 6) +#define PINMUX_GPIO27__FUNC_DBG_MON_A20 (MTK_PIN_NO(27) | 7) + +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_BPI_BUS18 (MTK_PIN_NO(28) | 1) +#define PINMUX_GPIO28__FUNC_URXD4 (MTK_PIN_NO(28) | 2) +#define PINMUX_GPIO28__FUNC_SPI2_A_MI (MTK_PIN_NO(28) | 3) +#define PINMUX_GPIO28__FUNC_CLKM0_A (MTK_PIN_NO(28) | 4) +#define PINMUX_GPIO28__FUNC_DBG_MON_A21 (MTK_PIN_NO(28) | 7) + +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_BPI_BUS19 (MTK_PIN_NO(29) | 1) +#define PINMUX_GPIO29__FUNC_MD_NTN_UTXD1 (MTK_PIN_NO(29) | 2) +#define PINMUX_GPIO29__FUNC_SPI2_A_MO (MTK_PIN_NO(29) | 3) +#define PINMUX_GPIO29__FUNC_CLKM1_A (MTK_PIN_NO(29) | 4) +#define PINMUX_GPIO29__FUNC_UCTS4 (MTK_PIN_NO(29) | 6) +#define PINMUX_GPIO29__FUNC_DBG_MON_A17 (MTK_PIN_NO(29) | 7) + +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_BPI_BUS20 (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_MD_NTN_URXD1 (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_SPI2_A_CLK (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_CLKM2_A (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_DSI3_HSYNC (MTK_PIN_NO(30) | 5) +#define PINMUX_GPIO30__FUNC_URTS4 (MTK_PIN_NO(30) | 6) +#define PINMUX_GPIO30__FUNC_DBG_MON_A18 (MTK_PIN_NO(30) | 7) + +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_BPI_BUS21 (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_SPI2_A_CSB (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_CLKM3_A (MTK_PIN_NO(31) | 4) +#define PINMUX_GPIO31__FUNC_EDP_TX_HPD (MTK_PIN_NO(31) | 6) +#define PINMUX_GPIO31__FUNC_DBG_MON_A19 (MTK_PIN_NO(31) | 7) + +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_LCM4_RST (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_DP_TX_HPD (MTK_PIN_NO(32) | 2) +#define PINMUX_GPIO32__FUNC_SSPM_JTAG_TCK_VLP (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_ADSP_JTAG0_TCK (MTK_PIN_NO(32) | 4) +#define PINMUX_GPIO32__FUNC_SCP_JTAG0_TCK_VLP (MTK_PIN_NO(32) | 5) +#define PINMUX_GPIO32__FUNC_SPU0_TCK (MTK_PIN_NO(32) | 6) +#define PINMUX_GPIO32__FUNC_IO_JTAG_TCK (MTK_PIN_NO(32) | 7) + +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_DSI4_TE (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_DP_OC_EN (MTK_PIN_NO(33) | 2) +#define PINMUX_GPIO33__FUNC_SSPM_JTAG_TRSTN_VLP (MTK_PIN_NO(33) | 3) +#define PINMUX_GPIO33__FUNC_ADSP_JTAG0_TRSTN (MTK_PIN_NO(33) | 4) +#define PINMUX_GPIO33__FUNC_SCP_JTAG0_TRSTN_VLP (MTK_PIN_NO(33) | 5) +#define PINMUX_GPIO33__FUNC_SPU0_NTRST (MTK_PIN_NO(33) | 6) +#define PINMUX_GPIO33__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(33) | 7) + +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_UCTS5 (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_DP_RAUX_SBU1 (MTK_PIN_NO(34) | 2) +#define PINMUX_GPIO34__FUNC_SSPM_JTAG_TDI_VLP (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_ADSP_JTAG0_TDI (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_SCP_JTAG0_TDI_VLP (MTK_PIN_NO(34) | 5) +#define PINMUX_GPIO34__FUNC_SPU0_TDI (MTK_PIN_NO(34) | 6) +#define PINMUX_GPIO34__FUNC_IO_JTAG_TDI (MTK_PIN_NO(34) | 7) + +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_URTS5 (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_DP_RAUX_SBU2 (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_SSPM_JTAG_TDO_VLP (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_ADSP_JTAG0_TDO (MTK_PIN_NO(35) | 4) +#define PINMUX_GPIO35__FUNC_SCP_JTAG0_TDO_VLP (MTK_PIN_NO(35) | 5) +#define PINMUX_GPIO35__FUNC_SPU0_TDO (MTK_PIN_NO(35) | 6) +#define PINMUX_GPIO35__FUNC_IO_JTAG_TDO (MTK_PIN_NO(35) | 7) + +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_UTXD5 (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_SSPM_JTAG_TMS_VLP (MTK_PIN_NO(36) | 3) +#define PINMUX_GPIO36__FUNC_ADSP_JTAG0_TMS (MTK_PIN_NO(36) | 4) +#define PINMUX_GPIO36__FUNC_SCP_JTAG0_TMS_VLP (MTK_PIN_NO(36) | 5) +#define PINMUX_GPIO36__FUNC_SPU0_TMS (MTK_PIN_NO(36) | 6) +#define PINMUX_GPIO36__FUNC_IO_JTAG_TMS (MTK_PIN_NO(36) | 7) + +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_URXD5 (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_MD_INT3 (MTK_PIN_NO(37) | 3) +#define PINMUX_GPIO37__FUNC_CLKM0_B (MTK_PIN_NO(37) | 4) +#define PINMUX_GPIO37__FUNC_TP_GPIO5_AO (MTK_PIN_NO(37) | 5) +#define PINMUX_GPIO37__FUNC_SPU0_UTX (MTK_PIN_NO(37) | 6) +#define PINMUX_GPIO37__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(37) | 7) + +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_SPMI_P_TRIG_FLAG (MTK_PIN_NO(38) | 2) +#define PINMUX_GPIO38__FUNC_MD_INT4 (MTK_PIN_NO(38) | 3) +#define PINMUX_GPIO38__FUNC_CLKM1_B (MTK_PIN_NO(38) | 4) +#define PINMUX_GPIO38__FUNC_TP_GPIO6_AO (MTK_PIN_NO(38) | 5) +#define PINMUX_GPIO38__FUNC_SPU0_URX (MTK_PIN_NO(38) | 6) +#define PINMUX_GPIO38__FUNC_DAP_MD32_SWD (MTK_PIN_NO(38) | 7) + +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_I2S_MCK0 (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_GPS_PPS0 (MTK_PIN_NO(39) | 3) +#define PINMUX_GPIO39__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(39) | 4) +#define PINMUX_GPIO39__FUNC_DBG_MON_B12 (MTK_PIN_NO(39) | 7) + +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_I2SIN6_0_BCK (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_SPI4_B_CLK (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_UCTS2 (MTK_PIN_NO(40) | 4) +#define PINMUX_GPIO40__FUNC_CCU1_UTXD (MTK_PIN_NO(40) | 5) +#define PINMUX_GPIO40__FUNC_DBG_MON_B13 (MTK_PIN_NO(40) | 7) + +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_I2SIN6_0_LRCK (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_SPI4_B_CSB (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_URTS2 (MTK_PIN_NO(41) | 4) +#define PINMUX_GPIO41__FUNC_CCU1_URXD (MTK_PIN_NO(41) | 5) +#define PINMUX_GPIO41__FUNC_DBG_MON_B14 (MTK_PIN_NO(41) | 7) + +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_I2SIN6_0_DI (MTK_PIN_NO(42) | 1) +#define PINMUX_GPIO42__FUNC_SPI4_B_MI (MTK_PIN_NO(42) | 3) +#define PINMUX_GPIO42__FUNC_URXD2 (MTK_PIN_NO(42) | 4) +#define PINMUX_GPIO42__FUNC_CCU1_URTS (MTK_PIN_NO(42) | 5) +#define PINMUX_GPIO42__FUNC_MD32_0_RXD (MTK_PIN_NO(42) | 6) +#define PINMUX_GPIO42__FUNC_DBG_MON_B15 (MTK_PIN_NO(42) | 7) + +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_I2SOUT6_0_DO (MTK_PIN_NO(43) | 1) +#define PINMUX_GPIO43__FUNC_SPI4_B_MO (MTK_PIN_NO(43) | 3) +#define PINMUX_GPIO43__FUNC_UTXD2 (MTK_PIN_NO(43) | 4) +#define PINMUX_GPIO43__FUNC_CCU1_UCTS (MTK_PIN_NO(43) | 5) +#define PINMUX_GPIO43__FUNC_MD32_0_TXD (MTK_PIN_NO(43) | 6) +#define PINMUX_GPIO43__FUNC_DBG_MON_B16 (MTK_PIN_NO(43) | 7) + +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(44) | 1) +#define PINMUX_GPIO44__FUNC_SPI3_A_CLK (MTK_PIN_NO(44) | 3) +#define PINMUX_GPIO44__FUNC_TP_GPIO10_AO (MTK_PIN_NO(44) | 6) + +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(45) | 1) +#define PINMUX_GPIO45__FUNC_DSI2_HSYNC (MTK_PIN_NO(45) | 2) +#define PINMUX_GPIO45__FUNC_SPI3_A_CSB (MTK_PIN_NO(45) | 3) +#define PINMUX_GPIO45__FUNC_PWM_VLP (MTK_PIN_NO(45) | 4) +#define PINMUX_GPIO45__FUNC_TP_GPIO11_AO (MTK_PIN_NO(45) | 6) + +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_SCP_SCL4 (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_PWM_VLP (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_SCP_ILDO_DTEST1_VLP (MTK_PIN_NO(46) | 4) +#define PINMUX_GPIO46__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(46) | 5) +#define PINMUX_GPIO46__FUNC_TP_GPIO0_AO (MTK_PIN_NO(46) | 6) + +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_SCP_SDA4 (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_SCP_ILDO_DTEST2_VLP (MTK_PIN_NO(47) | 4) +#define PINMUX_GPIO47__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(47) | 5) +#define PINMUX_GPIO47__FUNC_TP_GPIO1_AO (MTK_PIN_NO(47) | 6) + +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_SCP_SCL5 (MTK_PIN_NO(48) | 1) +#define PINMUX_GPIO48__FUNC_PWM_VLP (MTK_PIN_NO(48) | 2) +#define PINMUX_GPIO48__FUNC_CCU0_UTXD (MTK_PIN_NO(48) | 3) +#define PINMUX_GPIO48__FUNC_SCP_ILDO_DTEST3_VLP (MTK_PIN_NO(48) | 4) +#define PINMUX_GPIO48__FUNC_TP_GPIO2_AO (MTK_PIN_NO(48) | 6) + +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_SCP_SDA5 (MTK_PIN_NO(49) | 1) +#define PINMUX_GPIO49__FUNC_CCU0_URXD (MTK_PIN_NO(49) | 3) +#define PINMUX_GPIO49__FUNC_SCP_ILDO_DTEST4_VLP (MTK_PIN_NO(49) | 4) +#define PINMUX_GPIO49__FUNC_TP_GPIO3_AO (MTK_PIN_NO(49) | 6) + +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_SCP_SCL6 (MTK_PIN_NO(50) | 1) +#define PINMUX_GPIO50__FUNC_PWM_VLP (MTK_PIN_NO(50) | 2) +#define PINMUX_GPIO50__FUNC_CCU0_URTS (MTK_PIN_NO(50) | 3) +#define PINMUX_GPIO50__FUNC_DSI_HSYNC (MTK_PIN_NO(50) | 4) +#define PINMUX_GPIO50__FUNC_TP_GPIO4_AO (MTK_PIN_NO(50) | 6) + +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_SCP_SDA6 (MTK_PIN_NO(51) | 1) +#define PINMUX_GPIO51__FUNC_CCU0_UCTS (MTK_PIN_NO(51) | 3) +#define PINMUX_GPIO51__FUNC_DSI1_HSYNC (MTK_PIN_NO(51) | 4) +#define PINMUX_GPIO51__FUNC_TP_GPIO5_AO (MTK_PIN_NO(51) | 6) + +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_SCP_SCL1 (MTK_PIN_NO(52) | 1) +#define PINMUX_GPIO52__FUNC_TDM_DATA2 (MTK_PIN_NO(52) | 3) + +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_SCP_SDA1 (MTK_PIN_NO(53) | 1) +#define PINMUX_GPIO53__FUNC_TDM_DATA3 (MTK_PIN_NO(53) | 3) + +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(54) | 1) +#define PINMUX_GPIO54__FUNC_TDM_MCK (MTK_PIN_NO(54) | 3) + +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_AUD_CLK_MISO (MTK_PIN_NO(55) | 1) +#define PINMUX_GPIO55__FUNC_I2SOUT2_BCK (MTK_PIN_NO(55) | 2) +#define PINMUX_GPIO55__FUNC_TDM_BCK (MTK_PIN_NO(55) | 3) + +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_I2SOUT2_LRCK (MTK_PIN_NO(56) | 2) +#define PINMUX_GPIO56__FUNC_TDM_LRCK (MTK_PIN_NO(56) | 3) + +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(57) | 1) +#define PINMUX_GPIO57__FUNC_I2SOUT2_DO (MTK_PIN_NO(57) | 2) +#define PINMUX_GPIO57__FUNC_TDM_DATA0 (MTK_PIN_NO(57) | 3) + +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(58) | 1) +#define PINMUX_GPIO58__FUNC_TDM_DATA1 (MTK_PIN_NO(58) | 3) + +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_I2SIN1_BCK (MTK_PIN_NO(59) | 3) + +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_KPCOL0 (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_TP_GPIO13_AO (MTK_PIN_NO(60) | 6) + +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_MCU_M_PMIC_POC_I (MTK_PIN_NO(61) | 1) + +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_MCU_B_PMIC_POC_I (MTK_PIN_NO(62) | 1) + +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_MFG_PMIC_POC_I (MTK_PIN_NO(63) | 1) + +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_PRE_UVLO (MTK_PIN_NO(64) | 1) + +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_DPM2PMIC (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_SRCLKENA1 (MTK_PIN_NO(65) | 2) + +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_WATCHDOG (MTK_PIN_NO(66) | 1) + +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_SRCLKENA0 (MTK_PIN_NO(67) | 1) + +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(68) | 1) + +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_RTC32K_CK (MTK_PIN_NO(69) | 1) + +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_CMFLASH0 (MTK_PIN_NO(70) | 1) + +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) + +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) + +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) + +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_DCXO_FPM_LPM (MTK_PIN_NO(74) | 1) + +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_SPMI_M_SCL (MTK_PIN_NO(75) | 1) + +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_SPMI_M_SDA (MTK_PIN_NO(76) | 1) + +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_SPMI_P_SCL (MTK_PIN_NO(77) | 1) + +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_SPMI_P_SDA (MTK_PIN_NO(78) | 1) + +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_CMMCLK0 (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_MD_INT4 (MTK_PIN_NO(79) | 2) + +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_CMMCLK1 (MTK_PIN_NO(80) | 1) + +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_SCP_SPI0_CK (MTK_PIN_NO(81) | 1) +#define PINMUX_GPIO81__FUNC_SPI6_B_CLK (MTK_PIN_NO(81) | 2) +#define PINMUX_GPIO81__FUNC_PWM_VLP (MTK_PIN_NO(81) | 3) +#define PINMUX_GPIO81__FUNC_I2SOUT5_BCK (MTK_PIN_NO(81) | 4) +#define PINMUX_GPIO81__FUNC_TP_GPIO0_AO (MTK_PIN_NO(81) | 6) + +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_SCP_SPI0_CS (MTK_PIN_NO(82) | 1) +#define PINMUX_GPIO82__FUNC_SPI6_B_CSB (MTK_PIN_NO(82) | 2) +#define PINMUX_GPIO82__FUNC_I2SOUT5_LRCK (MTK_PIN_NO(82) | 4) +#define PINMUX_GPIO82__FUNC_TP_GPIO1_AO (MTK_PIN_NO(82) | 6) + +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_SCP_SPI0_MO (MTK_PIN_NO(83) | 1) +#define PINMUX_GPIO83__FUNC_SPI6_B_MO (MTK_PIN_NO(83) | 2) +#define PINMUX_GPIO83__FUNC_I2SOUT5_DATA0 (MTK_PIN_NO(83) | 4) +#define PINMUX_GPIO83__FUNC_TP_GPIO2_AO (MTK_PIN_NO(83) | 6) + +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_SCP_SPI0_MI (MTK_PIN_NO(84) | 1) +#define PINMUX_GPIO84__FUNC_SPI6_B_MI (MTK_PIN_NO(84) | 2) +#define PINMUX_GPIO84__FUNC_I2SOUT5_DATA1 (MTK_PIN_NO(84) | 4) +#define PINMUX_GPIO84__FUNC_TP_GPIO3_AO (MTK_PIN_NO(84) | 6) + +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_SCP_SPI1_CK (MTK_PIN_NO(85) | 1) +#define PINMUX_GPIO85__FUNC_SPI7_B_CLK (MTK_PIN_NO(85) | 2) +#define PINMUX_GPIO85__FUNC_I2SIN5_DATA0 (MTK_PIN_NO(85) | 4) +#define PINMUX_GPIO85__FUNC_PWM_VLP (MTK_PIN_NO(85) | 5) +#define PINMUX_GPIO85__FUNC_TP_GPIO4_AO (MTK_PIN_NO(85) | 6) + +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_SCP_SPI1_CS (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_SPI7_B_CSB (MTK_PIN_NO(86) | 2) +#define PINMUX_GPIO86__FUNC_I2SIN5_DATA1 (MTK_PIN_NO(86) | 4) +#define PINMUX_GPIO86__FUNC_TP_GPIO5_AO (MTK_PIN_NO(86) | 6) + +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_SCP_SPI1_MO (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_SPI7_B_MO (MTK_PIN_NO(87) | 2) +#define PINMUX_GPIO87__FUNC_I2SIN5_BCK (MTK_PIN_NO(87) | 4) +#define PINMUX_GPIO87__FUNC_TP_GPIO6_AO (MTK_PIN_NO(87) | 6) + +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_SCP_SPI1_MI (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_SPI7_B_MI (MTK_PIN_NO(88) | 2) +#define PINMUX_GPIO88__FUNC_I2SIN5_LRCK (MTK_PIN_NO(88) | 4) +#define PINMUX_GPIO88__FUNC_TP_GPIO7_AO (MTK_PIN_NO(88) | 6) + +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_DSI_TE (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_DSI1_TE (MTK_PIN_NO(89) | 2) +#define PINMUX_GPIO89__FUNC_DBG_MON_B30 (MTK_PIN_NO(89) | 7) + +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_LCM_RST (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_LCM1_RST (MTK_PIN_NO(90) | 2) +#define PINMUX_GPIO90__FUNC_DBG_MON_B31 (MTK_PIN_NO(90) | 7) + +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_CMFLASH2 (MTK_PIN_NO(91) | 1) +#define PINMUX_GPIO91__FUNC_SF_D0 (MTK_PIN_NO(91) | 2) +#define PINMUX_GPIO91__FUNC_SRCLKENAI1 (MTK_PIN_NO(91) | 3) +#define PINMUX_GPIO91__FUNC_KPCOL2 (MTK_PIN_NO(91) | 5) +#define PINMUX_GPIO91__FUNC_TP_GPIO11_AO (MTK_PIN_NO(91) | 6) + +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_CMFLASH3 (MTK_PIN_NO(92) | 1) +#define PINMUX_GPIO92__FUNC_SF_D1 (MTK_PIN_NO(92) | 2) +#define PINMUX_GPIO92__FUNC_DISP_PWM1 (MTK_PIN_NO(92) | 4) +#define PINMUX_GPIO92__FUNC_TP_GPIO12_AO (MTK_PIN_NO(92) | 6) + +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_CMFLASH1 (MTK_PIN_NO(93) | 1) +#define PINMUX_GPIO93__FUNC_SF_D2 (MTK_PIN_NO(93) | 2) +#define PINMUX_GPIO93__FUNC_SRCLKENAI0 (MTK_PIN_NO(93) | 3) +#define PINMUX_GPIO93__FUNC_KPROW2 (MTK_PIN_NO(93) | 5) +#define PINMUX_GPIO93__FUNC_TP_GPIO13_AO (MTK_PIN_NO(93) | 6) + +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_I2S_MCK1 (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_SF_D3 (MTK_PIN_NO(94) | 2) +#define PINMUX_GPIO94__FUNC_MD32_0_GPIO0 (MTK_PIN_NO(94) | 4) +#define PINMUX_GPIO94__FUNC_CLKM0_A (MTK_PIN_NO(94) | 5) +#define PINMUX_GPIO94__FUNC_TP_GPIO14_AO (MTK_PIN_NO(94) | 6) +#define PINMUX_GPIO94__FUNC_DBG_MON_B18 (MTK_PIN_NO(94) | 7) + +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_I2SIN1_BCK (MTK_PIN_NO(95) | 1) +#define PINMUX_GPIO95__FUNC_I2SIN4_BCK (MTK_PIN_NO(95) | 2) +#define PINMUX_GPIO95__FUNC_SPI6_A_CLK (MTK_PIN_NO(95) | 3) +#define PINMUX_GPIO95__FUNC_MD32_1_GPIO0 (MTK_PIN_NO(95) | 4) +#define PINMUX_GPIO95__FUNC_CLKM1_A (MTK_PIN_NO(95) | 5) +#define PINMUX_GPIO95__FUNC_TP_GPIO15_AO (MTK_PIN_NO(95) | 6) +#define PINMUX_GPIO95__FUNC_DBG_MON_B19 (MTK_PIN_NO(95) | 7) + +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_I2SIN1_LRCK (MTK_PIN_NO(96) | 1) +#define PINMUX_GPIO96__FUNC_I2SIN4_LRCK (MTK_PIN_NO(96) | 2) +#define PINMUX_GPIO96__FUNC_SPI6_A_CSB (MTK_PIN_NO(96) | 3) +#define PINMUX_GPIO96__FUNC_MD32_2_GPIO0 (MTK_PIN_NO(96) | 4) +#define PINMUX_GPIO96__FUNC_CLKM2_A (MTK_PIN_NO(96) | 5) +#define PINMUX_GPIO96__FUNC_DBG_MON_B20 (MTK_PIN_NO(96) | 7) + +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_I2SIN1_DI_A (MTK_PIN_NO(97) | 1) +#define PINMUX_GPIO97__FUNC_I2SIN4_DATA0 (MTK_PIN_NO(97) | 2) +#define PINMUX_GPIO97__FUNC_SPI6_A_MO (MTK_PIN_NO(97) | 3) +#define PINMUX_GPIO97__FUNC_MD32_3_GPIO0 (MTK_PIN_NO(97) | 4) +#define PINMUX_GPIO97__FUNC_CLKM3_A (MTK_PIN_NO(97) | 5) +#define PINMUX_GPIO97__FUNC_DBG_MON_B21 (MTK_PIN_NO(97) | 7) + +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_I2SOUT1_DO (MTK_PIN_NO(98) | 1) +#define PINMUX_GPIO98__FUNC_I2SOUT4_DATA0 (MTK_PIN_NO(98) | 2) +#define PINMUX_GPIO98__FUNC_SPI6_A_MI (MTK_PIN_NO(98) | 3) +#define PINMUX_GPIO98__FUNC_DBG_MON_B22 (MTK_PIN_NO(98) | 7) + +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_SCL0 (MTK_PIN_NO(99) | 1) +#define PINMUX_GPIO99__FUNC_LCM2_RST (MTK_PIN_NO(99) | 2) +#define PINMUX_GPIO99__FUNC_AUD_DAC_26M_CLK (MTK_PIN_NO(99) | 3) +#define PINMUX_GPIO99__FUNC_SPU0_SCL (MTK_PIN_NO(99) | 4) +#define PINMUX_GPIO99__FUNC_DBG_MON_B24 (MTK_PIN_NO(99) | 7) + +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_SDA0 (MTK_PIN_NO(100) | 1) +#define PINMUX_GPIO100__FUNC_DSI2_TE (MTK_PIN_NO(100) | 2) +#define PINMUX_GPIO100__FUNC_SPU0_SDA (MTK_PIN_NO(100) | 4) +#define PINMUX_GPIO100__FUNC_DBG_MON_B25 (MTK_PIN_NO(100) | 7) + +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_SCL10 (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_SF_CS (MTK_PIN_NO(101) | 2) +#define PINMUX_GPIO101__FUNC_SCP_DMIC1_CLK (MTK_PIN_NO(101) | 3) +#define PINMUX_GPIO101__FUNC_I2SIN5_DATA2 (MTK_PIN_NO(101) | 4) +#define PINMUX_GPIO101__FUNC_SCP_SCL_OIS (MTK_PIN_NO(101) | 5) +#define PINMUX_GPIO101__FUNC_TP_GPIO10_AO (MTK_PIN_NO(101) | 6) +#define PINMUX_GPIO101__FUNC_DBG_MON_B28 (MTK_PIN_NO(101) | 7) + +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_SDA10 (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_SF_CK (MTK_PIN_NO(102) | 2) +#define PINMUX_GPIO102__FUNC_SCP_DMIC1_DAT (MTK_PIN_NO(102) | 3) +#define PINMUX_GPIO102__FUNC_I2SIN5_DATA3 (MTK_PIN_NO(102) | 4) +#define PINMUX_GPIO102__FUNC_SCP_SDA_OIS (MTK_PIN_NO(102) | 5) +#define PINMUX_GPIO102__FUNC_TP_GPIO11_AO (MTK_PIN_NO(102) | 6) +#define PINMUX_GPIO102__FUNC_DBG_MON_B29 (MTK_PIN_NO(102) | 7) + +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_DISP_PWM (MTK_PIN_NO(103) | 1) +#define PINMUX_GPIO103__FUNC_DSI1_TE (MTK_PIN_NO(103) | 2) +#define PINMUX_GPIO103__FUNC_I2S_MCK0 (MTK_PIN_NO(103) | 5) +#define PINMUX_GPIO103__FUNC_DBG_MON_B23 (MTK_PIN_NO(103) | 7) + +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_SCL6 (MTK_PIN_NO(104) | 1) +#define PINMUX_GPIO104__FUNC_SPU1_SCL (MTK_PIN_NO(104) | 2) +#define PINMUX_GPIO104__FUNC_AUD_DAC_26M_CLK (MTK_PIN_NO(104) | 3) +#define PINMUX_GPIO104__FUNC_USB_DRVVBUS_2P (MTK_PIN_NO(104) | 4) +#define PINMUX_GPIO104__FUNC_I2S_MCK1 (MTK_PIN_NO(104) | 5) +#define PINMUX_GPIO104__FUNC_IDDIG_2P (MTK_PIN_NO(104) | 6) +#define PINMUX_GPIO104__FUNC_DBG_MON_B26 (MTK_PIN_NO(104) | 7) + +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_SDA6 (MTK_PIN_NO(105) | 1) +#define PINMUX_GPIO105__FUNC_SPU1_SDA (MTK_PIN_NO(105) | 2) +#define PINMUX_GPIO105__FUNC_DISP_PWM2 (MTK_PIN_NO(105) | 3) +#define PINMUX_GPIO105__FUNC_VBUSVALID_2P (MTK_PIN_NO(105) | 4) +#define PINMUX_GPIO105__FUNC_I2S_MCK2 (MTK_PIN_NO(105) | 5) +#define PINMUX_GPIO105__FUNC_VBUSVALID_3P (MTK_PIN_NO(105) | 6) +#define PINMUX_GPIO105__FUNC_DBG_MON_B27 (MTK_PIN_NO(105) | 7) + +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_SCP_SPI3_CK (MTK_PIN_NO(106) | 1) +#define PINMUX_GPIO106__FUNC_SPI3_B_CLK (MTK_PIN_NO(106) | 2) +#define PINMUX_GPIO106__FUNC_MD_UTXD0 (MTK_PIN_NO(106) | 3) +#define PINMUX_GPIO106__FUNC_TP_UTXD1_VLP (MTK_PIN_NO(106) | 4) +#define PINMUX_GPIO106__FUNC_CONN_BG_GPS_MCU_UART0_TXD (MTK_PIN_NO(106) | 5) +#define PINMUX_GPIO106__FUNC_TP_GPIO6_AO (MTK_PIN_NO(106) | 6) +#define PINMUX_GPIO106__FUNC_DBG_MON_B0 (MTK_PIN_NO(106) | 7) + +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_SCP_SPI3_CS (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_SPI3_B_CSB (MTK_PIN_NO(107) | 2) +#define PINMUX_GPIO107__FUNC_MD_URXD0 (MTK_PIN_NO(107) | 3) +#define PINMUX_GPIO107__FUNC_TP_URXD1_VLP (MTK_PIN_NO(107) | 4) +#define PINMUX_GPIO107__FUNC_CONN_BG_GPS_MCU_UART0_RXD (MTK_PIN_NO(107) | 5) +#define PINMUX_GPIO107__FUNC_TP_GPIO7_AO (MTK_PIN_NO(107) | 6) +#define PINMUX_GPIO107__FUNC_DBG_MON_B1 (MTK_PIN_NO(107) | 7) + +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_SCP_SPI3_MO (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_SPI3_B_MO (MTK_PIN_NO(108) | 2) +#define PINMUX_GPIO108__FUNC_MD_UTXD1 (MTK_PIN_NO(108) | 3) +#define PINMUX_GPIO108__FUNC_MD32PCM_UTXD_AO_VLP (MTK_PIN_NO(108) | 4) +#define PINMUX_GPIO108__FUNC_CONN_BG_GPS_MCU_UART1_TXD (MTK_PIN_NO(108) | 5) +#define PINMUX_GPIO108__FUNC_TP_GPIO8_AO (MTK_PIN_NO(108) | 6) +#define PINMUX_GPIO108__FUNC_DBG_MON_B2 (MTK_PIN_NO(108) | 7) + +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_SCP_SPI3_MI (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_SPI3_B_MI (MTK_PIN_NO(109) | 2) +#define PINMUX_GPIO109__FUNC_MD_URXD1 (MTK_PIN_NO(109) | 3) +#define PINMUX_GPIO109__FUNC_MD32PCM_URXD_AO_VLP (MTK_PIN_NO(109) | 4) +#define PINMUX_GPIO109__FUNC_CONN_BG_GPS_MCU_UART1_RXD (MTK_PIN_NO(109) | 5) +#define PINMUX_GPIO109__FUNC_TP_GPIO9_AO (MTK_PIN_NO(109) | 6) +#define PINMUX_GPIO109__FUNC_DBG_MON_B3 (MTK_PIN_NO(109) | 7) + +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_SPI1_CLK (MTK_PIN_NO(110) | 1) +#define PINMUX_GPIO110__FUNC_PWM_0 (MTK_PIN_NO(110) | 2) +#define PINMUX_GPIO110__FUNC_MD_UCTS0 (MTK_PIN_NO(110) | 3) +#define PINMUX_GPIO110__FUNC_TP_UCTS1_VLP (MTK_PIN_NO(110) | 4) +#define PINMUX_GPIO110__FUNC_SPU0_GPIO_O (MTK_PIN_NO(110) | 6) +#define PINMUX_GPIO110__FUNC_DBG_MON_B4 (MTK_PIN_NO(110) | 7) + +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_SPI1_CSB (MTK_PIN_NO(111) | 1) +#define PINMUX_GPIO111__FUNC_PWM_1 (MTK_PIN_NO(111) | 2) +#define PINMUX_GPIO111__FUNC_MD_URTS0 (MTK_PIN_NO(111) | 3) +#define PINMUX_GPIO111__FUNC_TP_URTS1_VLP (MTK_PIN_NO(111) | 4) +#define PINMUX_GPIO111__FUNC_SPU0_GPIO_I (MTK_PIN_NO(111) | 6) +#define PINMUX_GPIO111__FUNC_DBG_MON_B5 (MTK_PIN_NO(111) | 7) + +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_SPI1_MO (MTK_PIN_NO(112) | 1) +#define PINMUX_GPIO112__FUNC_PWM_2 (MTK_PIN_NO(112) | 2) +#define PINMUX_GPIO112__FUNC_MD_UCTS1 (MTK_PIN_NO(112) | 3) +#define PINMUX_GPIO112__FUNC_SPU1_GPIO_O (MTK_PIN_NO(112) | 6) +#define PINMUX_GPIO112__FUNC_DBG_MON_B6 (MTK_PIN_NO(112) | 7) + +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_SPI1_MI (MTK_PIN_NO(113) | 1) +#define PINMUX_GPIO113__FUNC_PWM_3 (MTK_PIN_NO(113) | 2) +#define PINMUX_GPIO113__FUNC_MD_URTS1 (MTK_PIN_NO(113) | 3) +#define PINMUX_GPIO113__FUNC_SPU1_GPIO_I (MTK_PIN_NO(113) | 6) +#define PINMUX_GPIO113__FUNC_DBG_MON_B7 (MTK_PIN_NO(113) | 7) + +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_SPI0_SPU_CLK (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_SPI4_A_CLK (MTK_PIN_NO(114) | 2) +#define PINMUX_GPIO114__FUNC_CONN_BG_GPS_MCU_DBG_UART_TXD (MTK_PIN_NO(114) | 5) +#define PINMUX_GPIO114__FUNC_DBG_MON_B8 (MTK_PIN_NO(114) | 7) + +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_SPI0_SPU_CSB (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_SPI4_A_CSB (MTK_PIN_NO(115) | 2) +#define PINMUX_GPIO115__FUNC_DBG_MON_B9 (MTK_PIN_NO(115) | 7) + +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_SPI0_SPU_MO (MTK_PIN_NO(116) | 1) +#define PINMUX_GPIO116__FUNC_SPI4_A_MO (MTK_PIN_NO(116) | 2) +#define PINMUX_GPIO116__FUNC_LCM1_RST (MTK_PIN_NO(116) | 3) +#define PINMUX_GPIO116__FUNC_DBG_MON_B10 (MTK_PIN_NO(116) | 7) + +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_SPI0_SPU_MI (MTK_PIN_NO(117) | 1) +#define PINMUX_GPIO117__FUNC_SPI4_A_MI (MTK_PIN_NO(117) | 2) +#define PINMUX_GPIO117__FUNC_DSI1_TE (MTK_PIN_NO(117) | 3) +#define PINMUX_GPIO117__FUNC_DBG_MON_B11 (MTK_PIN_NO(117) | 7) + +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_SPI5_CLK (MTK_PIN_NO(118) | 1) +#define PINMUX_GPIO118__FUNC_USB_DRVVBUS (MTK_PIN_NO(118) | 2) +#define PINMUX_GPIO118__FUNC_DP_TX_HPD (MTK_PIN_NO(118) | 3) +#define PINMUX_GPIO118__FUNC_AD_ILDO_DTEST0 (MTK_PIN_NO(118) | 4) + +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_SPI5_CSB (MTK_PIN_NO(119) | 1) +#define PINMUX_GPIO119__FUNC_VBUSVALID (MTK_PIN_NO(119) | 2) +#define PINMUX_GPIO119__FUNC_DP_OC_EN (MTK_PIN_NO(119) | 3) +#define PINMUX_GPIO119__FUNC_AD_ILDO_DTEST1 (MTK_PIN_NO(119) | 4) + +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_SPI5_MO (MTK_PIN_NO(120) | 1) +#define PINMUX_GPIO120__FUNC_LCM2_RST (MTK_PIN_NO(120) | 2) +#define PINMUX_GPIO120__FUNC_DP_RAUX_SBU1 (MTK_PIN_NO(120) | 3) +#define PINMUX_GPIO120__FUNC_AD_ILDO_DTEST2 (MTK_PIN_NO(120) | 4) +#define PINMUX_GPIO120__FUNC_IDDIG_3P (MTK_PIN_NO(120) | 6) + +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_SPI5_MI (MTK_PIN_NO(121) | 1) +#define PINMUX_GPIO121__FUNC_DSI2_TE (MTK_PIN_NO(121) | 2) +#define PINMUX_GPIO121__FUNC_DP_RAUX_SBU2 (MTK_PIN_NO(121) | 3) +#define PINMUX_GPIO121__FUNC_AD_ILDO_DTEST3 (MTK_PIN_NO(121) | 4) +#define PINMUX_GPIO121__FUNC_USB_DRVVBUS_3P (MTK_PIN_NO(121) | 6) +#define PINMUX_GPIO121__FUNC_DBG_MON_B17 (MTK_PIN_NO(121) | 7) + +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_AP_GOOD (MTK_PIN_NO(122) | 1) +#define PINMUX_GPIO122__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(122) | 2) + +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_SCL3 (MTK_PIN_NO(123) | 1) +#define PINMUX_GPIO123__FUNC_I2SIN2_LRCK (MTK_PIN_NO(123) | 5) +#define PINMUX_GPIO123__FUNC_TP_UTXD_MD_VCORE (MTK_PIN_NO(123) | 6) + +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_SDA3 (MTK_PIN_NO(124) | 1) +#define PINMUX_GPIO124__FUNC_TP_URXD_MD_VCORE (MTK_PIN_NO(124) | 6) + +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_MSDC1_CLK (MTK_PIN_NO(125) | 1) +#define PINMUX_GPIO125__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(125) | 2) +#define PINMUX_GPIO125__FUNC_HFRP_JTAG0_TCK (MTK_PIN_NO(125) | 3) +#define PINMUX_GPIO125__FUNC_UDI_TCK (MTK_PIN_NO(125) | 4) +#define PINMUX_GPIO125__FUNC_CONN_BGF_DSP_L1_JCK (MTK_PIN_NO(125) | 5) +#define PINMUX_GPIO125__FUNC_SCP_JTAG_LITTLE_TCK_VLP (MTK_PIN_NO(125) | 6) +#define PINMUX_GPIO125__FUNC_JTCK2_SEL1 (MTK_PIN_NO(125) | 7) + +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_MSDC1_CMD (MTK_PIN_NO(126) | 1) +#define PINMUX_GPIO126__FUNC_HFRP_JTAG0_TMS (MTK_PIN_NO(126) | 3) +#define PINMUX_GPIO126__FUNC_UDI_TMS (MTK_PIN_NO(126) | 4) +#define PINMUX_GPIO126__FUNC_CONN_BGF_DSP_L1_JMS (MTK_PIN_NO(126) | 5) +#define PINMUX_GPIO126__FUNC_SCP_JTAG_LITTLE_TMS_VLP (MTK_PIN_NO(126) | 6) +#define PINMUX_GPIO126__FUNC_JTMS2_SEL1 (MTK_PIN_NO(126) | 7) + +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_MSDC1_DAT0 (MTK_PIN_NO(127) | 1) +#define PINMUX_GPIO127__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(127) | 2) +#define PINMUX_GPIO127__FUNC_HFRP_JTAG0_TDI (MTK_PIN_NO(127) | 3) +#define PINMUX_GPIO127__FUNC_UDI_TDI_0 (MTK_PIN_NO(127) | 4) +#define PINMUX_GPIO127__FUNC_CONN_BGF_DSP_L1_JDI (MTK_PIN_NO(127) | 5) +#define PINMUX_GPIO127__FUNC_SCP_JTAG_LITTLE_TDI_VLP (MTK_PIN_NO(127) | 6) +#define PINMUX_GPIO127__FUNC_JTDI2_SEL1 (MTK_PIN_NO(127) | 7) + +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_MSDC1_DAT1 (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(128) | 2) +#define PINMUX_GPIO128__FUNC_HFRP_JTAG0_TDO (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_UDI_TDO_0 (MTK_PIN_NO(128) | 4) +#define PINMUX_GPIO128__FUNC_CONN_BGF_DSP_L1_JDO (MTK_PIN_NO(128) | 5) +#define PINMUX_GPIO128__FUNC_SCP_JTAG_LITTLE_TDO_VLP (MTK_PIN_NO(128) | 6) +#define PINMUX_GPIO128__FUNC_JTDO2_SEL1 (MTK_PIN_NO(128) | 7) + +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_MSDC1_DAT2 (MTK_PIN_NO(129) | 1) +#define PINMUX_GPIO129__FUNC_DSI2_HSYNC (MTK_PIN_NO(129) | 2) +#define PINMUX_GPIO129__FUNC_HFRP_JTAG0_TRSTN (MTK_PIN_NO(129) | 3) +#define PINMUX_GPIO129__FUNC_UDI_NTRST (MTK_PIN_NO(129) | 4) +#define PINMUX_GPIO129__FUNC_SCP_JTAG_LITTLE_TRSTN_VLP (MTK_PIN_NO(129) | 6) +#define PINMUX_GPIO129__FUNC_JTRSTN2_SEL1 (MTK_PIN_NO(129) | 7) + +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_MSDC1_DAT3 (MTK_PIN_NO(130) | 1) +#define PINMUX_GPIO130__FUNC_DSI3_HSYNC (MTK_PIN_NO(130) | 2) +#define PINMUX_GPIO130__FUNC_CONN_BGF_DSP_L1_JINTP (MTK_PIN_NO(130) | 5) + +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(131) | 2) +#define PINMUX_GPIO131__FUNC_MCUPM_JTAG_TDI (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_CLKM0_A (MTK_PIN_NO(131) | 4) +#define PINMUX_GPIO131__FUNC_CONN_BGF_DSP_L5_JDI (MTK_PIN_NO(131) | 5) +#define PINMUX_GPIO131__FUNC_TSFDC_SCK (MTK_PIN_NO(131) | 6) +#define PINMUX_GPIO131__FUNC_SCP_JTAG0_TDI_VCORE (MTK_PIN_NO(131) | 7) + +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(132) | 2) +#define PINMUX_GPIO132__FUNC_MCUPM_JTAG_TMS (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_CLKM1_B (MTK_PIN_NO(132) | 4) +#define PINMUX_GPIO132__FUNC_CONN_BGF_DSP_L5_JMS (MTK_PIN_NO(132) | 5) +#define PINMUX_GPIO132__FUNC_TSFDC_SDI (MTK_PIN_NO(132) | 6) +#define PINMUX_GPIO132__FUNC_SCP_JTAG0_TMS_VCORE (MTK_PIN_NO(132) | 7) + +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(133) | 1) +#define PINMUX_GPIO133__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(133) | 2) +#define PINMUX_GPIO133__FUNC_MCUPM_JTAG_TDO (MTK_PIN_NO(133) | 3) +#define PINMUX_GPIO133__FUNC_CONN_BGF_DSP_L5_JDO (MTK_PIN_NO(133) | 5) +#define PINMUX_GPIO133__FUNC_TSFDC_SCF (MTK_PIN_NO(133) | 6) +#define PINMUX_GPIO133__FUNC_SCP_JTAG0_TDO_VCORE (MTK_PIN_NO(133) | 7) + +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(134) | 1) +#define PINMUX_GPIO134__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(134) | 2) +#define PINMUX_GPIO134__FUNC_TSFDC_26M (MTK_PIN_NO(134) | 6) + +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(135) | 1) +#define PINMUX_GPIO135__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(135) | 2) +#define PINMUX_GPIO135__FUNC_MCUPM_JTAG_TCK (MTK_PIN_NO(135) | 3) +#define PINMUX_GPIO135__FUNC_CONN_BGF_DSP_L5_JCK (MTK_PIN_NO(135) | 5) +#define PINMUX_GPIO135__FUNC_TSFDC_SDO (MTK_PIN_NO(135) | 6) +#define PINMUX_GPIO135__FUNC_SCP_JTAG0_TCK_VCORE (MTK_PIN_NO(135) | 7) + +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(136) | 1) +#define PINMUX_GPIO136__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(136) | 2) +#define PINMUX_GPIO136__FUNC_MCUPM_JTAG_TRSTN (MTK_PIN_NO(136) | 3) +#define PINMUX_GPIO136__FUNC_CONN_BGF_DSP_L5_JINTP (MTK_PIN_NO(136) | 5) +#define PINMUX_GPIO136__FUNC_TSFDC_FOUT (MTK_PIN_NO(136) | 6) +#define PINMUX_GPIO136__FUNC_SCP_JTAG0_TRSTN_VCORE (MTK_PIN_NO(136) | 7) + +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_MIPI0_D_SCLK (MTK_PIN_NO(137) | 1) +#define PINMUX_GPIO137__FUNC_BPI_BUS16 (MTK_PIN_NO(137) | 2) +#define PINMUX_GPIO137__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(137) | 4) +#define PINMUX_GPIO137__FUNC_SPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(137) | 6) +#define PINMUX_GPIO137__FUNC_DBG_MON_A0 (MTK_PIN_NO(137) | 7) + +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_MIPI0_D_SDATA (MTK_PIN_NO(138) | 1) +#define PINMUX_GPIO138__FUNC_BPI_BUS17 (MTK_PIN_NO(138) | 2) +#define PINMUX_GPIO138__FUNC_PCM0_LRCK (MTK_PIN_NO(138) | 4) +#define PINMUX_GPIO138__FUNC_SPM_JTAG_TCK_VCORE (MTK_PIN_NO(138) | 6) +#define PINMUX_GPIO138__FUNC_DBG_MON_A1 (MTK_PIN_NO(138) | 7) + +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_MIPI1_D_SCLK (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_BPI_BUS18 (MTK_PIN_NO(139) | 2) +#define PINMUX_GPIO139__FUNC_MD_GPS_BLANK (MTK_PIN_NO(139) | 4) +#define PINMUX_GPIO139__FUNC_SPM_JTAG_TMS_VCORE (MTK_PIN_NO(139) | 6) +#define PINMUX_GPIO139__FUNC_DBG_MON_A2 (MTK_PIN_NO(139) | 7) + +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_MIPI1_D_SDATA (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_BPI_BUS19 (MTK_PIN_NO(140) | 2) +#define PINMUX_GPIO140__FUNC_MD_URXD1_CONN (MTK_PIN_NO(140) | 4) +#define PINMUX_GPIO140__FUNC_SPM_JTAG_TDO_VCORE (MTK_PIN_NO(140) | 6) +#define PINMUX_GPIO140__FUNC_DBG_MON_A3 (MTK_PIN_NO(140) | 7) + +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_MIPI2_D_SCLK (MTK_PIN_NO(141) | 1) +#define PINMUX_GPIO141__FUNC_BPI_BUS20 (MTK_PIN_NO(141) | 2) +#define PINMUX_GPIO141__FUNC_MD_UTXD1_CONN (MTK_PIN_NO(141) | 4) +#define PINMUX_GPIO141__FUNC_SPM_JTAG_TDI_VCORE (MTK_PIN_NO(141) | 6) +#define PINMUX_GPIO141__FUNC_DBG_MON_A4 (MTK_PIN_NO(141) | 7) + +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_MIPI2_D_SDATA (MTK_PIN_NO(142) | 1) +#define PINMUX_GPIO142__FUNC_BPI_BUS21 (MTK_PIN_NO(142) | 2) +#define PINMUX_GPIO142__FUNC_SSPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(142) | 6) +#define PINMUX_GPIO142__FUNC_DBG_MON_A5 (MTK_PIN_NO(142) | 7) + +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_MIPI3_D_SCLK (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_BPI_BUS22 (MTK_PIN_NO(143) | 2) +#define PINMUX_GPIO143__FUNC_TP_UTXD_GNSS_VLP (MTK_PIN_NO(143) | 4) +#define PINMUX_GPIO143__FUNC_MD_UTXD1_CONN (MTK_PIN_NO(143) | 5) +#define PINMUX_GPIO143__FUNC_SSPM_JTAG_TCK_VCORE (MTK_PIN_NO(143) | 6) + +#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define PINMUX_GPIO144__FUNC_MIPI3_D_SDATA (MTK_PIN_NO(144) | 1) +#define PINMUX_GPIO144__FUNC_BPI_BUS23 (MTK_PIN_NO(144) | 2) +#define PINMUX_GPIO144__FUNC_TP_URXD_GNSS_VLP (MTK_PIN_NO(144) | 4) +#define PINMUX_GPIO144__FUNC_MD_URXD1_CONN (MTK_PIN_NO(144) | 5) +#define PINMUX_GPIO144__FUNC_SSPM_JTAG_TMS_VCORE (MTK_PIN_NO(144) | 6) + +#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define PINMUX_GPIO145__FUNC_BPI_BUS0 (MTK_PIN_NO(145) | 1) +#define PINMUX_GPIO145__FUNC_PCIE_WAKEN_1P (MTK_PIN_NO(145) | 4) +#define PINMUX_GPIO145__FUNC_SSPM_JTAG_TDO_VCORE (MTK_PIN_NO(145) | 6) +#define PINMUX_GPIO145__FUNC_DBG_MON_A10 (MTK_PIN_NO(145) | 7) + +#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define PINMUX_GPIO146__FUNC_BPI_BUS1 (MTK_PIN_NO(146) | 1) +#define PINMUX_GPIO146__FUNC_PCIE_PERSTN_1P (MTK_PIN_NO(146) | 4) +#define PINMUX_GPIO146__FUNC_SSPM_JTAG_TDI_VCORE (MTK_PIN_NO(146) | 6) +#define PINMUX_GPIO146__FUNC_DBG_MON_A11 (MTK_PIN_NO(146) | 7) + +#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define PINMUX_GPIO147__FUNC_BPI_BUS2 (MTK_PIN_NO(147) | 1) +#define PINMUX_GPIO147__FUNC_AUD_DAC_26M_CLK (MTK_PIN_NO(147) | 2) +#define PINMUX_GPIO147__FUNC_PCIE_CLKREQN_1P (MTK_PIN_NO(147) | 4) +#define PINMUX_GPIO147__FUNC_SCP_JTAG_LITTLE_TRSTN_VCORE (MTK_PIN_NO(147) | 6) +#define PINMUX_GPIO147__FUNC_DBG_MON_A12 (MTK_PIN_NO(147) | 7) + +#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define PINMUX_GPIO148__FUNC_BPI_BUS3 (MTK_PIN_NO(148) | 1) +#define PINMUX_GPIO148__FUNC_AUD_DAC_26M_CLK (MTK_PIN_NO(148) | 2) +#define PINMUX_GPIO148__FUNC_TP_UTXD_MD_VLP (MTK_PIN_NO(148) | 4) +#define PINMUX_GPIO148__FUNC_TP_GPIO0_AO (MTK_PIN_NO(148) | 5) +#define PINMUX_GPIO148__FUNC_SCP_JTAG_LITTLE_TCK_VCORE (MTK_PIN_NO(148) | 6) +#define PINMUX_GPIO148__FUNC_DBG_MON_A13 (MTK_PIN_NO(148) | 7) + +#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define PINMUX_GPIO149__FUNC_BPI_BUS4 (MTK_PIN_NO(149) | 1) +#define PINMUX_GPIO149__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(149) | 2) +#define PINMUX_GPIO149__FUNC_TP_URXD_MD_VLP (MTK_PIN_NO(149) | 4) +#define PINMUX_GPIO149__FUNC_TP_GPIO1_AO (MTK_PIN_NO(149) | 5) +#define PINMUX_GPIO149__FUNC_SCP_JTAG_LITTLE_TMS_VCORE (MTK_PIN_NO(149) | 6) +#define PINMUX_GPIO149__FUNC_DBG_MON_A14 (MTK_PIN_NO(149) | 7) + +#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define PINMUX_GPIO150__FUNC_BPI_BUS5 (MTK_PIN_NO(150) | 1) +#define PINMUX_GPIO150__FUNC_GPS_PPS0 (MTK_PIN_NO(150) | 2) +#define PINMUX_GPIO150__FUNC_TP_GPIO2_AO (MTK_PIN_NO(150) | 5) +#define PINMUX_GPIO150__FUNC_SCP_JTAG_LITTLE_TDO_VCORE (MTK_PIN_NO(150) | 6) +#define PINMUX_GPIO150__FUNC_DBG_MON_A15 (MTK_PIN_NO(150) | 7) + +#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define PINMUX_GPIO151__FUNC_BPI_BUS6 (MTK_PIN_NO(151) | 1) +#define PINMUX_GPIO151__FUNC_GPS_PPS1 (MTK_PIN_NO(151) | 2) +#define PINMUX_GPIO151__FUNC_TP_GPIO3_AO (MTK_PIN_NO(151) | 5) +#define PINMUX_GPIO151__FUNC_SCP_JTAG_LITTLE_TDI_VCORE (MTK_PIN_NO(151) | 6) + +#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define PINMUX_GPIO152__FUNC_BPI_BUS7 (MTK_PIN_NO(152) | 1) +#define PINMUX_GPIO152__FUNC_EDP_TX_HPD (MTK_PIN_NO(152) | 2) +#define PINMUX_GPIO152__FUNC_AGPS_SYNC (MTK_PIN_NO(152) | 5) +#define PINMUX_GPIO152__FUNC_SSPM_UTXD_AO_VCORE (MTK_PIN_NO(152) | 6) + +#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define PINMUX_GPIO153__FUNC_MD_UCNT_A_TGL (MTK_PIN_NO(153) | 1) +#define PINMUX_GPIO153__FUNC_TP_URTS1_VCORE (MTK_PIN_NO(153) | 6) +#define PINMUX_GPIO153__FUNC_DBG_MON_A8 (MTK_PIN_NO(153) | 7) + +#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define PINMUX_GPIO154__FUNC_DIGRF_IRQ (MTK_PIN_NO(154) | 1) +#define PINMUX_GPIO154__FUNC_TP_UCTS1_VCORE (MTK_PIN_NO(154) | 6) +#define PINMUX_GPIO154__FUNC_DBG_MON_A9 (MTK_PIN_NO(154) | 7) + +#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define PINMUX_GPIO155__FUNC_MIPI_M_SCLK (MTK_PIN_NO(155) | 1) +#define PINMUX_GPIO155__FUNC_UCTS2 (MTK_PIN_NO(155) | 4) +#define PINMUX_GPIO155__FUNC_TP_UTXD_CONSYS_VCORE (MTK_PIN_NO(155) | 6) +#define PINMUX_GPIO155__FUNC_DBG_MON_A6 (MTK_PIN_NO(155) | 7) + +#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define PINMUX_GPIO156__FUNC_MIPI_M_SDATA (MTK_PIN_NO(156) | 1) +#define PINMUX_GPIO156__FUNC_URTS2 (MTK_PIN_NO(156) | 4) +#define PINMUX_GPIO156__FUNC_TP_URXD_CONSYS_VCORE (MTK_PIN_NO(156) | 6) +#define PINMUX_GPIO156__FUNC_DBG_MON_A7 (MTK_PIN_NO(156) | 7) + +#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define PINMUX_GPIO157__FUNC_BPI_BUS8 (MTK_PIN_NO(157) | 1) +#define PINMUX_GPIO157__FUNC_UTXD2 (MTK_PIN_NO(157) | 4) +#define PINMUX_GPIO157__FUNC_CLKM0_A (MTK_PIN_NO(157) | 5) +#define PINMUX_GPIO157__FUNC_SSPM_URXD_AO_VCORE (MTK_PIN_NO(157) | 6) +#define PINMUX_GPIO157__FUNC_DBG_MON_A16 (MTK_PIN_NO(157) | 7) + +#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define PINMUX_GPIO158__FUNC_BPI_BUS9 (MTK_PIN_NO(158) | 1) +#define PINMUX_GPIO158__FUNC_URXD2 (MTK_PIN_NO(158) | 4) +#define PINMUX_GPIO158__FUNC_CLKM1_A (MTK_PIN_NO(158) | 5) +#define PINMUX_GPIO158__FUNC_TP_UTXD1_VCORE (MTK_PIN_NO(158) | 6) + +#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define PINMUX_GPIO159__FUNC_BPI_BUS10 (MTK_PIN_NO(159) | 1) +#define PINMUX_GPIO159__FUNC_MD_INT0 (MTK_PIN_NO(159) | 2) +#define PINMUX_GPIO159__FUNC_SRCLKENAI1 (MTK_PIN_NO(159) | 3) +#define PINMUX_GPIO159__FUNC_CLKM2_A (MTK_PIN_NO(159) | 5) +#define PINMUX_GPIO159__FUNC_TP_URXD1_VCORE (MTK_PIN_NO(159) | 6) + +#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define PINMUX_GPIO160__FUNC_UTXD0 (MTK_PIN_NO(160) | 1) +#define PINMUX_GPIO160__FUNC_MD_UTXD1 (MTK_PIN_NO(160) | 2) +#define PINMUX_GPIO160__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(160) | 5) +#define PINMUX_GPIO160__FUNC_CONN_BG_GPS_MCU_DBG_UART_TXD (MTK_PIN_NO(160) | 6) + +#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define PINMUX_GPIO161__FUNC_URXD0 (MTK_PIN_NO(161) | 1) +#define PINMUX_GPIO161__FUNC_MD_URXD1 (MTK_PIN_NO(161) | 2) +#define PINMUX_GPIO161__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(161) | 5) + +#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define PINMUX_GPIO162__FUNC_UTXD1 (MTK_PIN_NO(162) | 1) +#define PINMUX_GPIO162__FUNC_MD_UTXD0 (MTK_PIN_NO(162) | 2) +#define PINMUX_GPIO162__FUNC_TP_UTXD1_VLP (MTK_PIN_NO(162) | 3) +#define PINMUX_GPIO162__FUNC_ADSP_UTXD0 (MTK_PIN_NO(162) | 4) +#define PINMUX_GPIO162__FUNC_SSPM_UTXD_AO_VLP (MTK_PIN_NO(162) | 5) +#define PINMUX_GPIO162__FUNC_HFRP_UTXD1 (MTK_PIN_NO(162) | 6) + +#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define PINMUX_GPIO163__FUNC_URXD1 (MTK_PIN_NO(163) | 1) +#define PINMUX_GPIO163__FUNC_MD_URXD0 (MTK_PIN_NO(163) | 2) +#define PINMUX_GPIO163__FUNC_TP_URXD1_VLP (MTK_PIN_NO(163) | 3) +#define PINMUX_GPIO163__FUNC_ADSP_URXD0 (MTK_PIN_NO(163) | 4) +#define PINMUX_GPIO163__FUNC_SSPM_URXD_AO_VLP (MTK_PIN_NO(163) | 5) +#define PINMUX_GPIO163__FUNC_HFRP_URXD1 (MTK_PIN_NO(163) | 6) + +#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define PINMUX_GPIO164__FUNC_SCP_SCL0 (MTK_PIN_NO(164) | 1) +#define PINMUX_GPIO164__FUNC_TP_GPIO0_AO (MTK_PIN_NO(164) | 6) +#define PINMUX_GPIO164__FUNC_DBG_MON_A22 (MTK_PIN_NO(164) | 7) + +#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) +#define PINMUX_GPIO165__FUNC_SCP_SDA0 (MTK_PIN_NO(165) | 1) +#define PINMUX_GPIO165__FUNC_TP_GPIO1_AO (MTK_PIN_NO(165) | 6) +#define PINMUX_GPIO165__FUNC_DBG_MON_A23 (MTK_PIN_NO(165) | 7) + +#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) +#define PINMUX_GPIO166__FUNC_SCP_SCL2 (MTK_PIN_NO(166) | 1) +#define PINMUX_GPIO166__FUNC_TP_GPIO2_AO (MTK_PIN_NO(166) | 6) +#define PINMUX_GPIO166__FUNC_DBG_MON_A24 (MTK_PIN_NO(166) | 7) + +#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) +#define PINMUX_GPIO167__FUNC_SCP_SDA2 (MTK_PIN_NO(167) | 1) +#define PINMUX_GPIO167__FUNC_TP_GPIO3_AO (MTK_PIN_NO(167) | 6) +#define PINMUX_GPIO167__FUNC_DBG_MON_A25 (MTK_PIN_NO(167) | 7) + +#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) +#define PINMUX_GPIO168__FUNC_SCP_SPI2_CK (MTK_PIN_NO(168) | 1) +#define PINMUX_GPIO168__FUNC_SPI2_B_CLK (MTK_PIN_NO(168) | 2) +#define PINMUX_GPIO168__FUNC_PWM_VLP (MTK_PIN_NO(168) | 3) +#define PINMUX_GPIO168__FUNC_SCP_SCL2 (MTK_PIN_NO(168) | 4) +#define PINMUX_GPIO168__FUNC_DBG_MON_A26 (MTK_PIN_NO(168) | 7) + +#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define PINMUX_GPIO169__FUNC_SCP_SPI2_CS (MTK_PIN_NO(169) | 1) +#define PINMUX_GPIO169__FUNC_SPI2_B_CSB (MTK_PIN_NO(169) | 2) +#define PINMUX_GPIO169__FUNC_DBG_MON_A27 (MTK_PIN_NO(169) | 7) + +#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define PINMUX_GPIO170__FUNC_SCP_SPI2_MO (MTK_PIN_NO(170) | 1) +#define PINMUX_GPIO170__FUNC_SPI2_B_MO (MTK_PIN_NO(170) | 2) +#define PINMUX_GPIO170__FUNC_SCP_SDA2 (MTK_PIN_NO(170) | 4) +#define PINMUX_GPIO170__FUNC_DBG_MON_A28 (MTK_PIN_NO(170) | 7) + +#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define PINMUX_GPIO171__FUNC_SCP_SPI2_MI (MTK_PIN_NO(171) | 1) +#define PINMUX_GPIO171__FUNC_SPI2_B_MI (MTK_PIN_NO(171) | 2) +#define PINMUX_GPIO171__FUNC_DBG_MON_A29 (MTK_PIN_NO(171) | 7) + +#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define PINMUX_GPIO172__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(172) | 1) + +#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define PINMUX_GPIO173__FUNC_CMFLASH3 (MTK_PIN_NO(173) | 1) +#define PINMUX_GPIO173__FUNC_PWM_3 (MTK_PIN_NO(173) | 2) +#define PINMUX_GPIO173__FUNC_MD_GPS_L5_BLANK (MTK_PIN_NO(173) | 3) +#define PINMUX_GPIO173__FUNC_CLKM1_A (MTK_PIN_NO(173) | 4) +#define PINMUX_GPIO173__FUNC_DBG_MON_A31 (MTK_PIN_NO(173) | 7) + +#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define PINMUX_GPIO174__FUNC_CMFLASH0 (MTK_PIN_NO(174) | 1) +#define PINMUX_GPIO174__FUNC_PWM_0 (MTK_PIN_NO(174) | 2) +#define PINMUX_GPIO174__FUNC_VBUSVALID_1P (MTK_PIN_NO(174) | 3) +#define PINMUX_GPIO174__FUNC_MD32_2_RXD (MTK_PIN_NO(174) | 4) +#define PINMUX_GPIO174__FUNC_DISP_PWM3 (MTK_PIN_NO(174) | 5) + +#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define PINMUX_GPIO175__FUNC_CMFLASH1 (MTK_PIN_NO(175) | 1) +#define PINMUX_GPIO175__FUNC_PWM_1 (MTK_PIN_NO(175) | 2) +#define PINMUX_GPIO175__FUNC_EDP_TX_HPD (MTK_PIN_NO(175) | 3) +#define PINMUX_GPIO175__FUNC_MD32_2_TXD (MTK_PIN_NO(175) | 4) +#define PINMUX_GPIO175__FUNC_DISP_PWM4 (MTK_PIN_NO(175) | 5) + +#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) +#define PINMUX_GPIO176__FUNC_SCL5 (MTK_PIN_NO(176) | 1) +#define PINMUX_GPIO176__FUNC_LCM3_RST (MTK_PIN_NO(176) | 2) +#define PINMUX_GPIO176__FUNC_MD_URXD1_CONN (MTK_PIN_NO(176) | 4) +#define PINMUX_GPIO176__FUNC_TP_UTXD_GNSS_VCORE (MTK_PIN_NO(176) | 6) + +#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) +#define PINMUX_GPIO177__FUNC_SDA5 (MTK_PIN_NO(177) | 1) +#define PINMUX_GPIO177__FUNC_DSI3_TE (MTK_PIN_NO(177) | 2) +#define PINMUX_GPIO177__FUNC_MD_UTXD1_CONN (MTK_PIN_NO(177) | 4) +#define PINMUX_GPIO177__FUNC_TP_URXD_GNSS_VCORE (MTK_PIN_NO(177) | 6) + +#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) +#define PINMUX_GPIO178__FUNC_DMIC_CLK (MTK_PIN_NO(178) | 1) +#define PINMUX_GPIO178__FUNC_SCP_DMIC_CLK (MTK_PIN_NO(178) | 2) +#define PINMUX_GPIO178__FUNC_SRCLKENAI0 (MTK_PIN_NO(178) | 3) +#define PINMUX_GPIO178__FUNC_CLKM2_B (MTK_PIN_NO(178) | 4) +#define PINMUX_GPIO178__FUNC_TP_GPIO7_AO (MTK_PIN_NO(178) | 5) +#define PINMUX_GPIO178__FUNC_SPU1_UTX (MTK_PIN_NO(178) | 6) +#define PINMUX_GPIO178__FUNC_DAP_SONIC_SWCK (MTK_PIN_NO(178) | 7) + +#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) +#define PINMUX_GPIO179__FUNC_DMIC_DAT (MTK_PIN_NO(179) | 1) +#define PINMUX_GPIO179__FUNC_SCP_DMIC_DAT (MTK_PIN_NO(179) | 2) +#define PINMUX_GPIO179__FUNC_SRCLKENAI1 (MTK_PIN_NO(179) | 3) +#define PINMUX_GPIO179__FUNC_CLKM3_B (MTK_PIN_NO(179) | 4) +#define PINMUX_GPIO179__FUNC_TP_GPIO8_AO (MTK_PIN_NO(179) | 5) +#define PINMUX_GPIO179__FUNC_SPU1_URX (MTK_PIN_NO(179) | 6) +#define PINMUX_GPIO179__FUNC_DAP_SONIC_SWD (MTK_PIN_NO(179) | 7) + +#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) +#define PINMUX_GPIO180__FUNC_IDDIG_1P (MTK_PIN_NO(180) | 1) +#define PINMUX_GPIO180__FUNC_CMVREF0 (MTK_PIN_NO(180) | 2) +#define PINMUX_GPIO180__FUNC_GPS_PPS1 (MTK_PIN_NO(180) | 3) +#define PINMUX_GPIO180__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(180) | 4) +#define PINMUX_GPIO180__FUNC_DISP_PWM1 (MTK_PIN_NO(180) | 5) + +#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) +#define PINMUX_GPIO181__FUNC_USB_DRVVBUS_1P (MTK_PIN_NO(181) | 1) +#define PINMUX_GPIO181__FUNC_CMVREF1 (MTK_PIN_NO(181) | 2) +#define PINMUX_GPIO181__FUNC_MFG_EB_JTAG_TRSTN (MTK_PIN_NO(181) | 3) +#define PINMUX_GPIO181__FUNC_ADSP_JTAG1_TRSTN (MTK_PIN_NO(181) | 4) +#define PINMUX_GPIO181__FUNC_HFRP_JTAG1_TRSTN (MTK_PIN_NO(181) | 5) +#define PINMUX_GPIO181__FUNC_SPU1_NTRST (MTK_PIN_NO(181) | 6) +#define PINMUX_GPIO181__FUNC_CONN_BG_GPS_MCU_TRST_B (MTK_PIN_NO(181) | 7) + +#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) +#define PINMUX_GPIO182__FUNC_SCL11 (MTK_PIN_NO(182) | 1) +#define PINMUX_GPIO182__FUNC_CMVREF2 (MTK_PIN_NO(182) | 2) +#define PINMUX_GPIO182__FUNC_MFG_EB_JTAG_TCK (MTK_PIN_NO(182) | 3) +#define PINMUX_GPIO182__FUNC_ADSP_JTAG1_TCK (MTK_PIN_NO(182) | 4) +#define PINMUX_GPIO182__FUNC_HFRP_JTAG1_TCK (MTK_PIN_NO(182) | 5) +#define PINMUX_GPIO182__FUNC_SPU1_TCK (MTK_PIN_NO(182) | 6) +#define PINMUX_GPIO182__FUNC_CONN_BG_GPS_MCU_TCK (MTK_PIN_NO(182) | 7) + +#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) +#define PINMUX_GPIO183__FUNC_SDA11 (MTK_PIN_NO(183) | 1) +#define PINMUX_GPIO183__FUNC_CMVREF3 (MTK_PIN_NO(183) | 2) +#define PINMUX_GPIO183__FUNC_MFG_EB_JTAG_TMS (MTK_PIN_NO(183) | 3) +#define PINMUX_GPIO183__FUNC_ADSP_JTAG1_TMS (MTK_PIN_NO(183) | 4) +#define PINMUX_GPIO183__FUNC_HFRP_JTAG1_TMS (MTK_PIN_NO(183) | 5) +#define PINMUX_GPIO183__FUNC_SPU1_TMS (MTK_PIN_NO(183) | 6) +#define PINMUX_GPIO183__FUNC_CONN_BG_GPS_MCU_TMS (MTK_PIN_NO(183) | 7) + +#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) +#define PINMUX_GPIO184__FUNC_SCL12 (MTK_PIN_NO(184) | 1) +#define PINMUX_GPIO184__FUNC_CMVREF4 (MTK_PIN_NO(184) | 2) +#define PINMUX_GPIO184__FUNC_MFG_EB_JTAG_TDO (MTK_PIN_NO(184) | 3) +#define PINMUX_GPIO184__FUNC_ADSP_JTAG1_TDO (MTK_PIN_NO(184) | 4) +#define PINMUX_GPIO184__FUNC_HFRP_JTAG1_TDO (MTK_PIN_NO(184) | 5) +#define PINMUX_GPIO184__FUNC_SPU1_TDO (MTK_PIN_NO(184) | 6) +#define PINMUX_GPIO184__FUNC_CONN_BG_GPS_MCU_TDO (MTK_PIN_NO(184) | 7) + +#define PINMUX_GPIO185__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) +#define PINMUX_GPIO185__FUNC_SDA12 (MTK_PIN_NO(185) | 1) +#define PINMUX_GPIO185__FUNC_CMVREF5 (MTK_PIN_NO(185) | 2) +#define PINMUX_GPIO185__FUNC_MFG_EB_JTAG_TDI (MTK_PIN_NO(185) | 3) +#define PINMUX_GPIO185__FUNC_ADSP_JTAG1_TDI (MTK_PIN_NO(185) | 4) +#define PINMUX_GPIO185__FUNC_HFRP_JTAG1_TDI (MTK_PIN_NO(185) | 5) +#define PINMUX_GPIO185__FUNC_SPU1_TDI (MTK_PIN_NO(185) | 6) +#define PINMUX_GPIO185__FUNC_CONN_BG_GPS_MCU_TDI (MTK_PIN_NO(185) | 7) + +#define PINMUX_GPIO186__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) +#define PINMUX_GPIO186__FUNC_MD_GPS_L1_BLANK (MTK_PIN_NO(186) | 1) +#define PINMUX_GPIO186__FUNC_PMSR_SMAP (MTK_PIN_NO(186) | 2) +#define PINMUX_GPIO186__FUNC_TP_GPIO2_AO (MTK_PIN_NO(186) | 3) + +#define PINMUX_GPIO187__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) +#define PINMUX_GPIO187__FUNC_MD_GPS_L5_BLANK (MTK_PIN_NO(187) | 1) +#define PINMUX_GPIO187__FUNC_TP_GPIO4_AO (MTK_PIN_NO(187) | 3) + +#define PINMUX_GPIO188__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) +#define PINMUX_GPIO188__FUNC_SCL2 (MTK_PIN_NO(188) | 1) +#define PINMUX_GPIO188__FUNC_SCP_SCL8 (MTK_PIN_NO(188) | 2) + +#define PINMUX_GPIO189__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) +#define PINMUX_GPIO189__FUNC_SDA2 (MTK_PIN_NO(189) | 1) +#define PINMUX_GPIO189__FUNC_SCP_SDA8 (MTK_PIN_NO(189) | 2) + +#define PINMUX_GPIO190__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) +#define PINMUX_GPIO190__FUNC_SCL4 (MTK_PIN_NO(190) | 1) +#define PINMUX_GPIO190__FUNC_SCP_SCL9 (MTK_PIN_NO(190) | 2) +#define PINMUX_GPIO190__FUNC_UDI_TDI_6 (MTK_PIN_NO(190) | 6) + +#define PINMUX_GPIO191__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) +#define PINMUX_GPIO191__FUNC_SDA4 (MTK_PIN_NO(191) | 1) +#define PINMUX_GPIO191__FUNC_SCP_SDA9 (MTK_PIN_NO(191) | 2) +#define PINMUX_GPIO191__FUNC_UDI_TDI_7 (MTK_PIN_NO(191) | 6) + +#define PINMUX_GPIO192__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) +#define PINMUX_GPIO192__FUNC_CMMCLK2 (MTK_PIN_NO(192) | 1) +#define PINMUX_GPIO192__FUNC_MD32_3_RXD (MTK_PIN_NO(192) | 4) + +#define PINMUX_GPIO193__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) +#define PINMUX_GPIO193__FUNC_CLKM0_B (MTK_PIN_NO(193) | 3) +#define PINMUX_GPIO193__FUNC_MD32_3_TXD (MTK_PIN_NO(193) | 4) +#define PINMUX_GPIO193__FUNC_UDI_TDO_7 (MTK_PIN_NO(193) | 6) + +#define PINMUX_GPIO194__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) +#define PINMUX_GPIO194__FUNC_SCL7 (MTK_PIN_NO(194) | 1) +#define PINMUX_GPIO194__FUNC_MD32_3_GPIO0 (MTK_PIN_NO(194) | 2) +#define PINMUX_GPIO194__FUNC_CLKM2_B (MTK_PIN_NO(194) | 3) +#define PINMUX_GPIO194__FUNC_UDI_TDI_2 (MTK_PIN_NO(194) | 6) + +#define PINMUX_GPIO195__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) +#define PINMUX_GPIO195__FUNC_SDA7 (MTK_PIN_NO(195) | 1) +#define PINMUX_GPIO195__FUNC_CLKM3_B (MTK_PIN_NO(195) | 3) +#define PINMUX_GPIO195__FUNC_UDI_TDI_3 (MTK_PIN_NO(195) | 6) + +#define PINMUX_GPIO196__FUNC_GPIO196 (MTK_PIN_NO(196) | 0) +#define PINMUX_GPIO196__FUNC_CMMCLK3 (MTK_PIN_NO(196) | 1) + +#define PINMUX_GPIO197__FUNC_GPIO197 (MTK_PIN_NO(197) | 0) +#define PINMUX_GPIO197__FUNC_CLKM1_B (MTK_PIN_NO(197) | 3) +#define PINMUX_GPIO197__FUNC_UDI_TDI_1 (MTK_PIN_NO(197) | 6) + +#define PINMUX_GPIO198__FUNC_GPIO198 (MTK_PIN_NO(198) | 0) +#define PINMUX_GPIO198__FUNC_SCL8 (MTK_PIN_NO(198) | 1) +#define PINMUX_GPIO198__FUNC_UDI_TDI_4 (MTK_PIN_NO(198) | 6) + +#define PINMUX_GPIO199__FUNC_GPIO199 (MTK_PIN_NO(199) | 0) +#define PINMUX_GPIO199__FUNC_SDA8 (MTK_PIN_NO(199) | 1) +#define PINMUX_GPIO199__FUNC_UDI_TDI_5 (MTK_PIN_NO(199) | 6) + +#define PINMUX_GPIO200__FUNC_GPIO200 (MTK_PIN_NO(200) | 0) +#define PINMUX_GPIO200__FUNC_SCL1 (MTK_PIN_NO(200) | 1) + +#define PINMUX_GPIO201__FUNC_GPIO201 (MTK_PIN_NO(201) | 0) +#define PINMUX_GPIO201__FUNC_SDA1 (MTK_PIN_NO(201) | 1) +#define PINMUX_GPIO201__FUNC_TSFDC_BG_COMP (MTK_PIN_NO(201) | 7) + +#define PINMUX_GPIO202__FUNC_GPIO202 (MTK_PIN_NO(202) | 0) +#define PINMUX_GPIO202__FUNC_SCL9 (MTK_PIN_NO(202) | 1) +#define PINMUX_GPIO202__FUNC_SCP_SCL7 (MTK_PIN_NO(202) | 2) +#define PINMUX_GPIO202__FUNC_TP_GPIO15_AO (MTK_PIN_NO(202) | 6) + +#define PINMUX_GPIO203__FUNC_GPIO203 (MTK_PIN_NO(203) | 0) +#define PINMUX_GPIO203__FUNC_SDA9 (MTK_PIN_NO(203) | 1) +#define PINMUX_GPIO203__FUNC_SCP_SDA7 (MTK_PIN_NO(203) | 2) +#define PINMUX_GPIO203__FUNC_TP_GPIO9_AO (MTK_PIN_NO(203) | 6) + +#define PINMUX_GPIO204__FUNC_GPIO204 (MTK_PIN_NO(204) | 0) +#define PINMUX_GPIO204__FUNC_SCL13 (MTK_PIN_NO(204) | 1) +#define PINMUX_GPIO204__FUNC_CMVREF6 (MTK_PIN_NO(204) | 2) +#define PINMUX_GPIO204__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(204) | 3) +#define PINMUX_GPIO204__FUNC_CLKM2_B (MTK_PIN_NO(204) | 5) +#define PINMUX_GPIO204__FUNC_TP_GPIO12_AO (MTK_PIN_NO(204) | 6) + +#define PINMUX_GPIO205__FUNC_GPIO205 (MTK_PIN_NO(205) | 0) +#define PINMUX_GPIO205__FUNC_SDA13 (MTK_PIN_NO(205) | 1) +#define PINMUX_GPIO205__FUNC_CMVREF7 (MTK_PIN_NO(205) | 2) +#define PINMUX_GPIO205__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(205) | 3) +#define PINMUX_GPIO205__FUNC_CLKM3_B (MTK_PIN_NO(205) | 5) +#define PINMUX_GPIO205__FUNC_TP_GPIO13_AO (MTK_PIN_NO(205) | 6) + +#define PINMUX_GPIO206__FUNC_GPIO206 (MTK_PIN_NO(206) | 0) +#define PINMUX_GPIO206__FUNC_MD32_2_GPIO0 (MTK_PIN_NO(206) | 2) +#define PINMUX_GPIO206__FUNC_VBUSVALID (MTK_PIN_NO(206) | 5) +#define PINMUX_GPIO206__FUNC_UDI_TDO_3 (MTK_PIN_NO(206) | 6) + +#define PINMUX_GPIO207__FUNC_GPIO207 (MTK_PIN_NO(207) | 0) +#define PINMUX_GPIO207__FUNC_PCIE_WAKEN_2P (MTK_PIN_NO(207) | 1) +#define PINMUX_GPIO207__FUNC_PMSR_SMAP_MAX (MTK_PIN_NO(207) | 2) +#define PINMUX_GPIO207__FUNC_FMI2S_A_BCK (MTK_PIN_NO(207) | 4) +#define PINMUX_GPIO207__FUNC_UDI_TDO_4 (MTK_PIN_NO(207) | 6) + +#define PINMUX_GPIO208__FUNC_GPIO208 (MTK_PIN_NO(208) | 0) +#define PINMUX_GPIO208__FUNC_PCIE_CLKREQN_2P (MTK_PIN_NO(208) | 1) +#define PINMUX_GPIO208__FUNC_PMSR_SMAP_MAX_W (MTK_PIN_NO(208) | 2) +#define PINMUX_GPIO208__FUNC_FMI2S_A_LRCK (MTK_PIN_NO(208) | 4) +#define PINMUX_GPIO208__FUNC_CLKM0_B (MTK_PIN_NO(208) | 5) +#define PINMUX_GPIO208__FUNC_UDI_TDO_5 (MTK_PIN_NO(208) | 6) + +#define PINMUX_GPIO209__FUNC_GPIO209 (MTK_PIN_NO(209) | 0) +#define PINMUX_GPIO209__FUNC_PCIE_PERSTN_2P (MTK_PIN_NO(209) | 1) +#define PINMUX_GPIO209__FUNC_PMSR_SMAP (MTK_PIN_NO(209) | 2) +#define PINMUX_GPIO209__FUNC_FMI2S_A_DI (MTK_PIN_NO(209) | 4) +#define PINMUX_GPIO209__FUNC_CLKM1_B (MTK_PIN_NO(209) | 5) +#define PINMUX_GPIO209__FUNC_UDI_TDO_6 (MTK_PIN_NO(209) | 6) + +#define PINMUX_GPIO210__FUNC_GPIO210 (MTK_PIN_NO(210) | 0) +#define PINMUX_GPIO210__FUNC_CMMCLK4 (MTK_PIN_NO(210) | 1) + +#define PINMUX_GPIO211__FUNC_GPIO211 (MTK_PIN_NO(211) | 0) +#define PINMUX_GPIO211__FUNC_CMMCLK5 (MTK_PIN_NO(211) | 1) +#define PINMUX_GPIO211__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(211) | 2) + +#define PINMUX_GPIO212__FUNC_GPIO212 (MTK_PIN_NO(212) | 0) +#define PINMUX_GPIO212__FUNC_CMMCLK6 (MTK_PIN_NO(212) | 1) +#define PINMUX_GPIO212__FUNC_TP_GPIO10_AO (MTK_PIN_NO(212) | 2) +#define PINMUX_GPIO212__FUNC_IDDIG (MTK_PIN_NO(212) | 5) +#define PINMUX_GPIO212__FUNC_UDI_TDO_1 (MTK_PIN_NO(212) | 6) + +#define PINMUX_GPIO213__FUNC_GPIO213 (MTK_PIN_NO(213) | 0) +#define PINMUX_GPIO213__FUNC_CMMCLK7 (MTK_PIN_NO(213) | 1) +#define PINMUX_GPIO213__FUNC_TP_GPIO11_AO (MTK_PIN_NO(213) | 2) +#define PINMUX_GPIO213__FUNC_USB_DRVVBUS (MTK_PIN_NO(213) | 5) +#define PINMUX_GPIO213__FUNC_UDI_TDO_2 (MTK_PIN_NO(213) | 6) + +#define PINMUX_GPIO214__FUNC_GPIO214 (MTK_PIN_NO(214) | 0) +#define PINMUX_GPIO214__FUNC_SCP_SCL3 (MTK_PIN_NO(214) | 1) +#define PINMUX_GPIO214__FUNC_SDA14_E1 (MTK_PIN_NO(214) | 2) +#define PINMUX_GPIO214__FUNC_SCL14_E2 (MTK_PIN_NO(214) | 2) +#define PINMUX_GPIO214__FUNC_GBE1_MDC (MTK_PIN_NO(214) | 6) +#define PINMUX_GPIO214__FUNC_GBE0_MDC (MTK_PIN_NO(214) | 7) + +#define PINMUX_GPIO215__FUNC_GPIO215 (MTK_PIN_NO(215) | 0) +#define PINMUX_GPIO215__FUNC_SCP_SDA3 (MTK_PIN_NO(215) | 1) +#define PINMUX_GPIO215__FUNC_SCL14_E1 (MTK_PIN_NO(215) | 2) +#define PINMUX_GPIO215__FUNC_SDA14_E2 (MTK_PIN_NO(215) | 2) +#define PINMUX_GPIO215__FUNC_GBE1_MDIO (MTK_PIN_NO(215) | 6) +#define PINMUX_GPIO215__FUNC_GBE0_MDIO (MTK_PIN_NO(215) | 7) + +#define PINMUX_GPIO216__FUNC_GPIO216 (MTK_PIN_NO(216) | 0) +#define PINMUX_GPIO216__FUNC_GPS_PPS0 (MTK_PIN_NO(216) | 1) + +#define PINMUX_GPIO217__FUNC_GPIO217 (MTK_PIN_NO(217) | 0) +#define PINMUX_GPIO217__FUNC_KPROW0 (MTK_PIN_NO(217) | 1) +#define PINMUX_GPIO217__FUNC_TP_GPIO12_AO (MTK_PIN_NO(217) | 6) + +#define PINMUX_GPIO218__FUNC_GPIO218 (MTK_PIN_NO(218) | 0) +#define PINMUX_GPIO218__FUNC_KPROW1 (MTK_PIN_NO(218) | 1) +#define PINMUX_GPIO218__FUNC_SPI0_WP (MTK_PIN_NO(218) | 2) +#define PINMUX_GPIO218__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(218) | 3) +#define PINMUX_GPIO218__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(218) | 5) +#define PINMUX_GPIO218__FUNC_TP_GPIO14_AO (MTK_PIN_NO(218) | 6) + +#define PINMUX_GPIO219__FUNC_GPIO219 (MTK_PIN_NO(219) | 0) +#define PINMUX_GPIO219__FUNC_KPCOL1 (MTK_PIN_NO(219) | 1) +#define PINMUX_GPIO219__FUNC_SPI0_HOLD (MTK_PIN_NO(219) | 2) +#define PINMUX_GPIO219__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(219) | 3) +#define PINMUX_GPIO219__FUNC_SPMI_M_TRIG_FLAG (MTK_PIN_NO(219) | 4) +#define PINMUX_GPIO219__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(219) | 5) +#define PINMUX_GPIO219__FUNC_SPM_JTAG_TRSTN_VLP (MTK_PIN_NO(219) | 6) +#define PINMUX_GPIO219__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(219) | 7) + +#define PINMUX_GPIO220__FUNC_GPIO220 (MTK_PIN_NO(220) | 0) +#define PINMUX_GPIO220__FUNC_SPI0_CLK (MTK_PIN_NO(220) | 1) +#define PINMUX_GPIO220__FUNC_SPM_JTAG_TCK_VLP (MTK_PIN_NO(220) | 6) +#define PINMUX_GPIO220__FUNC_JTCK_SEL1 (MTK_PIN_NO(220) | 7) + +#define PINMUX_GPIO221__FUNC_GPIO221 (MTK_PIN_NO(221) | 0) +#define PINMUX_GPIO221__FUNC_SPI0_CSB (MTK_PIN_NO(221) | 1) +#define PINMUX_GPIO221__FUNC_SPM_JTAG_TMS_VLP (MTK_PIN_NO(221) | 6) +#define PINMUX_GPIO221__FUNC_JTMS_SEL1 (MTK_PIN_NO(221) | 7) + +#define PINMUX_GPIO222__FUNC_GPIO222 (MTK_PIN_NO(222) | 0) +#define PINMUX_GPIO222__FUNC_SPI0_MO (MTK_PIN_NO(222) | 1) +#define PINMUX_GPIO222__FUNC_SCP_SCL7 (MTK_PIN_NO(222) | 2) +#define PINMUX_GPIO222__FUNC_SPM_JTAG_TDO_VLP (MTK_PIN_NO(222) | 6) +#define PINMUX_GPIO222__FUNC_JTDO_SEL1 (MTK_PIN_NO(222) | 7) + +#define PINMUX_GPIO223__FUNC_GPIO223 (MTK_PIN_NO(223) | 0) +#define PINMUX_GPIO223__FUNC_SPI0_MI (MTK_PIN_NO(223) | 1) +#define PINMUX_GPIO223__FUNC_SCP_SDA7 (MTK_PIN_NO(223) | 2) +#define PINMUX_GPIO223__FUNC_SPM_JTAG_TDI_VLP (MTK_PIN_NO(223) | 6) +#define PINMUX_GPIO223__FUNC_JTDI_SEL1 (MTK_PIN_NO(223) | 7) + +#define PINMUX_GPIO224__FUNC_GPIO224 (MTK_PIN_NO(224) | 0) +#define PINMUX_GPIO224__FUNC_MSDC2_CLK (MTK_PIN_NO(224) | 1) +#define PINMUX_GPIO224__FUNC_DMIC2_CLK (MTK_PIN_NO(224) | 2) +#define PINMUX_GPIO224__FUNC_GBE0_AUX_PPS0 (MTK_PIN_NO(224) | 3) +#define PINMUX_GPIO224__FUNC_GBE0_TXER (MTK_PIN_NO(224) | 4) +#define PINMUX_GPIO224__FUNC_GBE1_TXER (MTK_PIN_NO(224) | 5) +#define PINMUX_GPIO224__FUNC_GBE1_AUX_PPS0 (MTK_PIN_NO(224) | 6) +#define PINMUX_GPIO224__FUNC_MD32_1_TXD (MTK_PIN_NO(224) | 7) + +#define PINMUX_GPIO225__FUNC_GPIO225 (MTK_PIN_NO(225) | 0) +#define PINMUX_GPIO225__FUNC_MSDC2_CMD (MTK_PIN_NO(225) | 1) +#define PINMUX_GPIO225__FUNC_DMIC2_DAT (MTK_PIN_NO(225) | 2) +#define PINMUX_GPIO225__FUNC_GBE0_AUX_PPS1 (MTK_PIN_NO(225) | 3) +#define PINMUX_GPIO225__FUNC_GBE0_RXER (MTK_PIN_NO(225) | 4) +#define PINMUX_GPIO225__FUNC_GBE1_RXER (MTK_PIN_NO(225) | 5) +#define PINMUX_GPIO225__FUNC_GBE1_AUX_PPS1 (MTK_PIN_NO(225) | 6) +#define PINMUX_GPIO225__FUNC_MD32_1_RXD (MTK_PIN_NO(225) | 7) + +#define PINMUX_GPIO226__FUNC_GPIO226 (MTK_PIN_NO(226) | 0) +#define PINMUX_GPIO226__FUNC_MSDC2_DAT0 (MTK_PIN_NO(226) | 1) +#define PINMUX_GPIO226__FUNC_I2SIN3_BCK (MTK_PIN_NO(226) | 2) +#define PINMUX_GPIO226__FUNC_GBE0_AUX_PPS2 (MTK_PIN_NO(226) | 3) +#define PINMUX_GPIO226__FUNC_GBE0_COL (MTK_PIN_NO(226) | 4) +#define PINMUX_GPIO226__FUNC_GBE1_COL (MTK_PIN_NO(226) | 5) +#define PINMUX_GPIO226__FUNC_GBE1_AUX_PPS2 (MTK_PIN_NO(226) | 6) +#define PINMUX_GPIO226__FUNC_GBE1_MDC (MTK_PIN_NO(226) | 7) + +#define PINMUX_GPIO227__FUNC_GPIO227 (MTK_PIN_NO(227) | 0) +#define PINMUX_GPIO227__FUNC_MSDC2_DAT1 (MTK_PIN_NO(227) | 1) +#define PINMUX_GPIO227__FUNC_I2SIN3_LRCK (MTK_PIN_NO(227) | 2) +#define PINMUX_GPIO227__FUNC_GBE0_AUX_PPS3 (MTK_PIN_NO(227) | 3) +#define PINMUX_GPIO227__FUNC_GBE0_INTR (MTK_PIN_NO(227) | 4) +#define PINMUX_GPIO227__FUNC_GBE1_INTR (MTK_PIN_NO(227) | 5) +#define PINMUX_GPIO227__FUNC_GBE1_AUX_PPS3 (MTK_PIN_NO(227) | 6) +#define PINMUX_GPIO227__FUNC_GBE1_MDIO (MTK_PIN_NO(227) | 7) + +#define PINMUX_GPIO228__FUNC_GPIO228 (MTK_PIN_NO(228) | 0) +#define PINMUX_GPIO228__FUNC_MSDC2_DAT2 (MTK_PIN_NO(228) | 1) +#define PINMUX_GPIO228__FUNC_I2SIN3_DI (MTK_PIN_NO(228) | 2) +#define PINMUX_GPIO228__FUNC_GBE0_MDC (MTK_PIN_NO(228) | 3) +#define PINMUX_GPIO228__FUNC_GBE1_MDC (MTK_PIN_NO(228) | 4) +#define PINMUX_GPIO228__FUNC_CONN_BG_GPS_MCU_AICE_TCKC (MTK_PIN_NO(228) | 5) + +#define PINMUX_GPIO229__FUNC_GPIO229 (MTK_PIN_NO(229) | 0) +#define PINMUX_GPIO229__FUNC_MSDC2_DAT3 (MTK_PIN_NO(229) | 1) +#define PINMUX_GPIO229__FUNC_I2SOUT3_DO (MTK_PIN_NO(229) | 2) +#define PINMUX_GPIO229__FUNC_GBE0_MDIO (MTK_PIN_NO(229) | 3) +#define PINMUX_GPIO229__FUNC_GBE1_MDIO (MTK_PIN_NO(229) | 4) +#define PINMUX_GPIO229__FUNC_CONN_BG_GPS_MCU_AICE_TMSC (MTK_PIN_NO(229) | 5) +#define PINMUX_GPIO229__FUNC_AVB_CLK2 (MTK_PIN_NO(229) | 7) + +#define PINMUX_GPIO230__FUNC_GPIO230 (MTK_PIN_NO(230) | 0) +#define PINMUX_GPIO230__FUNC_CONN_TOP_CLK (MTK_PIN_NO(230) | 1) + +#define PINMUX_GPIO231__FUNC_GPIO231 (MTK_PIN_NO(231) | 0) +#define PINMUX_GPIO231__FUNC_CONN_TOP_DATA (MTK_PIN_NO(231) | 1) + +#define PINMUX_GPIO232__FUNC_GPIO232 (MTK_PIN_NO(232) | 0) +#define PINMUX_GPIO232__FUNC_CONN_HRST_B (MTK_PIN_NO(232) | 1) + +#define PINMUX_GPIO233__FUNC_GPIO233 (MTK_PIN_NO(233) | 0) +#define PINMUX_GPIO233__FUNC_I2SIN0_BCK (MTK_PIN_NO(233) | 1) + +#define PINMUX_GPIO234__FUNC_GPIO234 (MTK_PIN_NO(234) | 0) +#define PINMUX_GPIO234__FUNC_I2SIN0_LRCK (MTK_PIN_NO(234) | 1) + +#define PINMUX_GPIO235__FUNC_GPIO235 (MTK_PIN_NO(235) | 0) +#define PINMUX_GPIO235__FUNC_I2SIN0_DI (MTK_PIN_NO(235) | 1) + +#define PINMUX_GPIO236__FUNC_GPIO236 (MTK_PIN_NO(236) | 0) +#define PINMUX_GPIO236__FUNC_I2SOUT0_DO (MTK_PIN_NO(236) | 1) + +#define PINMUX_GPIO237__FUNC_GPIO237 (MTK_PIN_NO(237) | 0) +#define PINMUX_GPIO237__FUNC_CONN_UARTHUB_UART_TX (MTK_PIN_NO(237) | 1) +#define PINMUX_GPIO237__FUNC_UTXD3 (MTK_PIN_NO(237) | 3) + +#define PINMUX_GPIO238__FUNC_GPIO238 (MTK_PIN_NO(238) | 0) +#define PINMUX_GPIO238__FUNC_CONN_UARTHUB_UART_RX (MTK_PIN_NO(238) | 1) +#define PINMUX_GPIO238__FUNC_URXD3 (MTK_PIN_NO(238) | 3) + +#define PINMUX_GPIO239__FUNC_GPIO239 (MTK_PIN_NO(239) | 0) +#define PINMUX_GPIO239__FUNC_TP_UTXD_CONSYS_VLP (MTK_PIN_NO(239) | 1) +#define PINMUX_GPIO239__FUNC_TP_URXD_CONSYS_VLP (MTK_PIN_NO(239) | 2) + +#define PINMUX_GPIO240__FUNC_GPIO240 (MTK_PIN_NO(240) | 0) +#define PINMUX_GPIO240__FUNC_TP_URXD_CONSYS_VLP (MTK_PIN_NO(240) | 1) +#define PINMUX_GPIO240__FUNC_TP_UTXD_CONSYS_VLP (MTK_PIN_NO(240) | 2) + +#define PINMUX_GPIO241__FUNC_GPIO241 (MTK_PIN_NO(241) | 0) +#define PINMUX_GPIO241__FUNC_PCIE_PERSTN (MTK_PIN_NO(241) | 1) + +#define PINMUX_GPIO242__FUNC_GPIO242 (MTK_PIN_NO(242) | 0) +#define PINMUX_GPIO242__FUNC_PCIE_WAKEN (MTK_PIN_NO(242) | 1) + +#define PINMUX_GPIO243__FUNC_GPIO243 (MTK_PIN_NO(243) | 0) +#define PINMUX_GPIO243__FUNC_PCIE_CLKREQN (MTK_PIN_NO(243) | 1) + +#define PINMUX_GPIO244__FUNC_GPIO244 (MTK_PIN_NO(244) | 0) +#define PINMUX_GPIO244__FUNC_CONN_RST (MTK_PIN_NO(244) | 1) + +#define PINMUX_GPIO245__FUNC_GPIO245 (MTK_PIN_NO(245) | 0) + +#define PINMUX_GPIO246__FUNC_GPIO246 (MTK_PIN_NO(246) | 0) +#define PINMUX_GPIO246__FUNC_CONN_PTA_TXD0 (MTK_PIN_NO(246) | 1) + +#define PINMUX_GPIO247__FUNC_GPIO247 (MTK_PIN_NO(247) | 0) +#define PINMUX_GPIO247__FUNC_CONN_PTA_RXD0 (MTK_PIN_NO(247) | 1) + +#define PINMUX_GPIO248__FUNC_GPIO248 (MTK_PIN_NO(248) | 0) +#define PINMUX_GPIO248__FUNC_UCTS3 (MTK_PIN_NO(248) | 3) + +#define PINMUX_GPIO249__FUNC_GPIO249 (MTK_PIN_NO(249) | 0) +#define PINMUX_GPIO249__FUNC_URTS3 (MTK_PIN_NO(249) | 3) + +#define PINMUX_GPIO250__FUNC_GPIO250 (MTK_PIN_NO(250) | 0) + +#define PINMUX_GPIO251__FUNC_GPIO251 (MTK_PIN_NO(251) | 0) +#define PINMUX_GPIO251__FUNC_IDDIG_1P (MTK_PIN_NO(251) | 1) + +#define PINMUX_GPIO252__FUNC_GPIO252 (MTK_PIN_NO(252) | 0) +#define PINMUX_GPIO252__FUNC_USB_DRVVBUS_1P (MTK_PIN_NO(252) | 1) + +#define PINMUX_GPIO253__FUNC_GPIO253 (MTK_PIN_NO(253) | 0) +#define PINMUX_GPIO253__FUNC_VBUSVALID_1P (MTK_PIN_NO(253) | 1) + +#define PINMUX_GPIO254__FUNC_GPIO254 (MTK_PIN_NO(254) | 0) +#define PINMUX_GPIO254__FUNC_IDDIG_2P (MTK_PIN_NO(254) | 1) + +#define PINMUX_GPIO255__FUNC_GPIO255 (MTK_PIN_NO(255) | 0) +#define PINMUX_GPIO255__FUNC_USB_DRVVBUS_2P (MTK_PIN_NO(255) | 1) + +#define PINMUX_GPIO256__FUNC_GPIO256 (MTK_PIN_NO(256) | 0) +#define PINMUX_GPIO256__FUNC_VBUSVALID_2P (MTK_PIN_NO(256) | 1) + +#define PINMUX_GPIO257__FUNC_GPIO257 (MTK_PIN_NO(257) | 0) +#define PINMUX_GPIO257__FUNC_VBUSVALID_3P (MTK_PIN_NO(257) | 1) + +#define PINMUX_GPIO258__FUNC_GPIO258 (MTK_PIN_NO(258) | 0) +#define PINMUX_GPIO258__FUNC_AVB_CLK1 (MTK_PIN_NO(258) | 7) + +#define PINMUX_GPIO259__FUNC_GPIO259 (MTK_PIN_NO(259) | 0) +#define PINMUX_GPIO259__FUNC_GBE0_TXD0 (MTK_PIN_NO(259) | 1) +#define PINMUX_GPIO259__FUNC_GBE1_TXD0 (MTK_PIN_NO(259) | 2) + +#define PINMUX_GPIO260__FUNC_GPIO260 (MTK_PIN_NO(260) | 0) +#define PINMUX_GPIO260__FUNC_GBE0_TXD1 (MTK_PIN_NO(260) | 1) +#define PINMUX_GPIO260__FUNC_GBE1_TXD1 (MTK_PIN_NO(260) | 2) + +#define PINMUX_GPIO261__FUNC_GPIO261 (MTK_PIN_NO(261) | 0) +#define PINMUX_GPIO261__FUNC_GBE0_TXC (MTK_PIN_NO(261) | 1) +#define PINMUX_GPIO261__FUNC_GBE1_TXC (MTK_PIN_NO(261) | 2) + +#define PINMUX_GPIO262__FUNC_GPIO262 (MTK_PIN_NO(262) | 0) +#define PINMUX_GPIO262__FUNC_GBE0_TXEN (MTK_PIN_NO(262) | 1) +#define PINMUX_GPIO262__FUNC_GBE1_TXEN (MTK_PIN_NO(262) | 2) + +#define PINMUX_GPIO263__FUNC_GPIO263 (MTK_PIN_NO(263) | 0) +#define PINMUX_GPIO263__FUNC_GBE0_RXD0 (MTK_PIN_NO(263) | 1) +#define PINMUX_GPIO263__FUNC_GBE1_RXD0 (MTK_PIN_NO(263) | 2) +#define PINMUX_GPIO263__FUNC_GBE0_AUX_PPS0 (MTK_PIN_NO(263) | 3) + +#define PINMUX_GPIO264__FUNC_GPIO264 (MTK_PIN_NO(264) | 0) +#define PINMUX_GPIO264__FUNC_GBE0_RXD1 (MTK_PIN_NO(264) | 1) +#define PINMUX_GPIO264__FUNC_GBE1_RXD1 (MTK_PIN_NO(264) | 2) +#define PINMUX_GPIO264__FUNC_GBE0_AUX_PPS1 (MTK_PIN_NO(264) | 3) + +#define PINMUX_GPIO265__FUNC_GPIO265 (MTK_PIN_NO(265) | 0) +#define PINMUX_GPIO265__FUNC_GBE0_RXC (MTK_PIN_NO(265) | 1) +#define PINMUX_GPIO265__FUNC_GBE1_RXC (MTK_PIN_NO(265) | 2) +#define PINMUX_GPIO265__FUNC_GBE0_AUX_PPS2 (MTK_PIN_NO(265) | 3) + +#define PINMUX_GPIO266__FUNC_GPIO266 (MTK_PIN_NO(266) | 0) +#define PINMUX_GPIO266__FUNC_GBE0_RXDV (MTK_PIN_NO(266) | 1) +#define PINMUX_GPIO266__FUNC_GBE1_RXDV (MTK_PIN_NO(266) | 2) +#define PINMUX_GPIO266__FUNC_GBE0_AUX_PPS3 (MTK_PIN_NO(266) | 3) + +#define PINMUX_GPIO267__FUNC_GPIO267 (MTK_PIN_NO(267) | 0) +#define PINMUX_GPIO267__FUNC_GBE0_TXD2 (MTK_PIN_NO(267) | 1) +#define PINMUX_GPIO267__FUNC_GBE1_TXD2 (MTK_PIN_NO(267) | 2) +#define PINMUX_GPIO267__FUNC_GBE0_RXER (MTK_PIN_NO(267) | 3) +#define PINMUX_GPIO267__FUNC_GBE1_RXER (MTK_PIN_NO(267) | 4) + +#define PINMUX_GPIO268__FUNC_GPIO268 (MTK_PIN_NO(268) | 0) +#define PINMUX_GPIO268__FUNC_GBE0_TXD3 (MTK_PIN_NO(268) | 1) +#define PINMUX_GPIO268__FUNC_GBE1_TXD3 (MTK_PIN_NO(268) | 2) + +#define PINMUX_GPIO269__FUNC_GPIO269 (MTK_PIN_NO(269) | 0) +#define PINMUX_GPIO269__FUNC_GBE0_RXD2 (MTK_PIN_NO(269) | 1) +#define PINMUX_GPIO269__FUNC_GBE1_RXD2 (MTK_PIN_NO(269) | 2) +#define PINMUX_GPIO269__FUNC_GBE0_MDC (MTK_PIN_NO(269) | 3) + +#define PINMUX_GPIO270__FUNC_GPIO270 (MTK_PIN_NO(270) | 0) +#define PINMUX_GPIO270__FUNC_GBE0_RXD3 (MTK_PIN_NO(270) | 1) +#define PINMUX_GPIO270__FUNC_GBE1_RXD3 (MTK_PIN_NO(270) | 2) +#define PINMUX_GPIO270__FUNC_GBE0_MDIO (MTK_PIN_NO(270) | 3) + +#endif /* __MT8196_PINFUNC_H */ -- GitLab From 63fc2ba26501d0eaad7990fefec80fdb8aff8372 Mon Sep 17 00:00:00 2001 From: liuqf Date: Thu, 5 Dec 2024 10:26:05 +0000 Subject: [PATCH 281/456] Revert "CHROMIUM: net: wwan: t7xx Fix use-after-free in rescan logic" This reverts commit 0806c68cfea4815d26a2d52ee88aa3e5f8ad393e. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check modemfwd firmware flash. Change-Id: I54ff6d3f46acde8586b4d70946a3cecca777e520 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6074312 Tested-by: Daniel Winkler Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c index 96acca72e840d..99fefda6b1378 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c @@ -56,23 +56,20 @@ static void t7xx_remove_rescan(struct work_struct *work) if (pdev) { pr_debug("start remove and rescan flow\n"); -#ifdef CONFIG_ACPI - handle = ACPI_HANDLE(&pdev->dev); -#endif pci_stop_and_remove_bus_device_locked(pdev); #ifdef CONFIG_ACPI + handle = ACPI_HANDLE(&pdev->dev); if (cold_reboot) { pr_info("Performing cold modem reboot\n"); status = acpi_execute_simple_method(handle, "FHRF", 1); if (ACPI_FAILURE(status)) { - pr_err("t7xx: Failed to call _FHRF: 0x%x\n", - status); + dev_err(&pdev->dev, "Failed to call _FHRF: %d\n", + status); } - status = acpi_evaluate_object(handle, "SHRF", NULL, - NULL); + status = acpi_evaluate_object(handle, "SHRF", NULL, NULL); if (ACPI_FAILURE(status)) { - pr_err("t7xX: Failed to call _SHRF: 0x%x\n", - status); + dev_err(&pdev->dev, "Failed to call _SHRF: %d\n", + status); } } #endif -- GitLab From 183dc55b96551817d7d5d2a58683e9478bf9d54b Mon Sep 17 00:00:00 2001 From: liuqf Date: Thu, 5 Dec 2024 10:27:51 +0000 Subject: [PATCH 282/456] Revert "BACKPORT: FROMLIST: net: wwan: t7xx: Fix remove rescan block" This reverts commit 0f31c6bc52d78376ee07ef05b556f96719ecb4f9. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check reset modem. Change-Id: Ib9cc8b296358e4f69506fdc4dd9f3de32e0bf8e5 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6074313 Tested-by: Daniel Winkler Reviewed-by: Ujjwal Pande Reviewed-by: Daniel Winkler Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 0eace12538310..6113d9225a4fe 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -293,9 +293,7 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma struct cldma_ctrl *md_ctrl; int err; - if (ctl->curr_state == FSM_STATE_STOPPED || - ctl->curr_state == FSM_STATE_STOPPING || - ctl->md->rgu_irq_asserted) { + if (ctl->curr_state == FSM_STATE_STOPPED || ctl->curr_state == FSM_STATE_STOPPING) { fsm_finish_command(ctl, cmd, -EINVAL); return; } @@ -307,22 +305,24 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_TO_STOP); t7xx_cldma_stop(md_ctrl); - if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) - t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY); - - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); - /* Wait for the DRM disable to take effect */ - msleep(FSM_DRM_DISABLE_DELAY_MS); - - if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) { - /* Do not try fldr because device will always wait for - * MHCCIF bit 13 in fastboot download flow. - */ - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); - } else { - err = t7xx_acpi_fldr_func(t7xx_dev); - if (err) + if (!ctl->md->rgu_irq_asserted) { + if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) + t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY); + + t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); + /* Wait for the DRM disable to take effect */ + msleep(FSM_DRM_DISABLE_DELAY_MS); + + if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) { + /* Do not try fldr because device will always wait for + * MHCCIF bit 13 in fastboot download flow. + */ t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); + } else { + err = t7xx_acpi_fldr_func(t7xx_dev); + if (err) + t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); + } } fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl)); -- GitLab From bbdcc163e34e587d9ae54c9d03d7b249c0ee26cb Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:07:24 +0000 Subject: [PATCH 283/456] Revert "CHROMIUM: net: wwan: t7xx: Modify the LINUX/LK trigger source" This reverts commit fccf284589f42893ca123ae876df9d0129c5cea5. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I2f2bd1d2cbb9345d290be8ac7c21b1622c9d74ee Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928748 Tested-by: Daniel Winkler Commit-Queue: Daniel Winkler Reviewed-by: Ujjwal Pande Reviewed-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 6113d9225a4fe..97244cc3ecdf5 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -420,7 +420,7 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command goto finish_command; } - if (status != ctl->prev_status || cmd->flag != 0) { + if (status != ctl->prev_status) { stage = FIELD_GET(MISC_STAGE_MASK, status); switch (stage) { case T7XX_DEV_STAGE_INIT: @@ -437,12 +437,10 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command case T7XX_DEV_STAGE_LINUX: dev_info(dev, "LINUX_STAGE Entered\n"); - t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM | - D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK); - if (cmd->flag == 0) - break; t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]); t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]); + t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM | + D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK); t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL); ret = fsm_routine_starting(ctl); break; -- GitLab From a58d79274c0ed8f9ce7ae89d8feaf7c419731a40 Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:07:38 +0000 Subject: [PATCH 284/456] Revert "CHROMIUM: net: wwan: t7xx: Delete flash FW end reboot rescan" This reverts commit 40a319ebd082e3a42fd777b53f57c261f1b95811. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I6dc0a6ad724ea8cd330970e486f5c2322df59e48 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928749 Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_port_devlink.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c index 4e266d4d864bd..fa0c7d7e35302 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c +++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c @@ -441,10 +441,8 @@ static int t7xx_devlink_reload_up(struct devlink *devlink, *actions_performed = BIT(action); switch (action) { case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: - t7xx_rescan_queue_work(dl->t7xx_dev->pdev, false); - return 0; case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: - /* the modem sends rgu interrupt after the reboot */ + t7xx_rescan_queue_work(dl->t7xx_dev->pdev, false); return 0; default: /* Unsupported action should not get to this function */ -- GitLab From fd5c0468313520020ee4617070cdcdf5f81f8ee8 Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:07:51 +0000 Subject: [PATCH 285/456] Revert "CHROMIUM: net: wwan: t7xx: Add support for cold reboot" This reverts commit c940646a64e5d36361fa65e86022c9d1f91d826e. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Ib0a9c5fd6193860473bbf56e9153d5c8bf99e4fa Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928750 Reviewed-by: Ujjwal Pande Reviewed-by: Daniel Winkler Tested-by: Daniel Winkler Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_modem_ops.c | 2 +- drivers/net/wwan/t7xx/t7xx_pci.c | 32 ----------------------- drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 30 ++------------------- drivers/net/wwan/t7xx/t7xx_pci_rescan.h | 3 +-- drivers/net/wwan/t7xx/t7xx_port_devlink.c | 2 +- 5 files changed, 5 insertions(+), 64 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 04320f252f780..2fcaea4694ba6 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -195,7 +195,7 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data) msleep(RGU_RESET_DELAY_MS); t7xx_reset_device_via_pmic(t7xx_dev); - t7xx_rescan_queue_work(t7xx_dev->pdev, false); + t7xx_rescan_queue_work(t7xx_dev->pdev); return IRQ_HANDLED; } diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 4ff5b28d3c5c3..80743e0644028 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -61,26 +61,6 @@ enum t7xx_pm_state { MTK_PM_RESUMED, }; -static ssize_t cold_reboot_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - t7xx_rescan_queue_work(pdev, true); - return count; -} - -static DEVICE_ATTR_WO(cold_reboot); - -static struct attribute *cold_reboot_attr[] = { - &dev_attr_cold_reboot.attr, - NULL -}; - -static const struct attribute_group cold_reboot_attribute_group = { - .attrs = cold_reboot_attr, -}; - static void t7xx_dev_set_sleep_capability(struct t7xx_pci_dev *t7xx_dev, bool enable) { void __iomem *ctrl_reg = IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_CTRL; @@ -755,17 +735,8 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pcie_mac_interrupts_dis(t7xx_dev); - ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj, - &cold_reboot_attribute_group); - if (ret) { - t7xx_md_exit(t7xx_dev); - goto err_devlink_unregister; - } - ret = t7xx_interrupt_init(t7xx_dev); if (ret) { - sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &cold_reboot_attribute_group); t7xx_md_exit(t7xx_dev); goto err_devlink_unregister; } @@ -790,9 +761,6 @@ static void t7xx_pci_remove(struct pci_dev *pdev) t7xx_md_exit(t7xx_dev); t7xx_devlink_unregister(t7xx_dev); - sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &cold_reboot_attribute_group); - for (i = 0; i < EXT_INT_NUM; i++) { if (!t7xx_dev->intr_handler[i]) continue; diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c index 99fefda6b1378..c502fb62b2835 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c @@ -7,7 +7,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":t7xx:%s: " fmt, __func__ #define dev_fmt(fmt) "t7xx: " fmt -#include #include #include #include @@ -42,37 +41,13 @@ static void t7xx_remove_rescan(struct work_struct *work) { int num_retries = RESCAN_RETRIES; struct pci_dev *pdev; -#ifdef CONFIG_ACPI - acpi_status status; - acpi_handle handle; - bool cold_reboot; -#endif atomic_set(&t7xx_rescan_ctx.rescan_done, 0); pdev = t7xx_rescan_ctx.dev; -#ifdef CONFIG_ACPI - cold_reboot = t7xx_rescan_ctx.cold_reboot; -#endif if (pdev) { - pr_debug("start remove and rescan flow\n"); pci_stop_and_remove_bus_device_locked(pdev); -#ifdef CONFIG_ACPI - handle = ACPI_HANDLE(&pdev->dev); - if (cold_reboot) { - pr_info("Performing cold modem reboot\n"); - status = acpi_execute_simple_method(handle, "FHRF", 1); - if (ACPI_FAILURE(status)) { - dev_err(&pdev->dev, "Failed to call _FHRF: %d\n", - status); - } - status = acpi_evaluate_object(handle, "SHRF", NULL, NULL); - if (ACPI_FAILURE(status)) { - dev_err(&pdev->dev, "Failed to call _SHRF: %d\n", - status); - } - } -#endif + pr_debug("start remove and rescan flow\n"); } do { @@ -85,7 +60,7 @@ static void t7xx_remove_rescan(struct work_struct *work) } while (num_retries--); } -void t7xx_rescan_queue_work(struct pci_dev *pdev, bool cold_reboot) +void t7xx_rescan_queue_work(struct pci_dev *pdev) { if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) { dev_err(&pdev->dev, "Rescan failed\n"); @@ -93,7 +68,6 @@ void t7xx_rescan_queue_work(struct pci_dev *pdev, bool cold_reboot) } t7xx_rescan_ctx.dev = pdev; - t7xx_rescan_ctx.cold_reboot = cold_reboot; queue_work(t7xx_rescan_ctx.pcie_rescan_wq, &t7xx_rescan_ctx.service_task); } diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h index e1d13e73571e4..80b25c44151c9 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h @@ -17,11 +17,10 @@ struct remove_rescan_context { struct workqueue_struct *pcie_rescan_wq; struct pci_dev *dev; atomic_t rescan_done; - bool cold_reboot; }; void t7xx_pci_dev_rescan(void); -void t7xx_rescan_queue_work(struct pci_dev *pdev, bool cold_reboot); +void t7xx_rescan_queue_work(struct pci_dev *pdev); int t7xx_rescan_init(void); void t7xx_rescan_deinit(void); void t7xx_rescan_done(void); diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c index fa0c7d7e35302..8de2ee65fe0cb 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c +++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c @@ -442,7 +442,7 @@ static int t7xx_devlink_reload_up(struct devlink *devlink, switch (action) { case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: - t7xx_rescan_queue_work(dl->t7xx_dev->pdev, false); + t7xx_rescan_queue_work(dl->t7xx_dev->pdev); return 0; default: /* Unsupported action should not get to this function */ -- GitLab From 9b3b92a724681dd84d8250a413acf3ab3d97b9d4 Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:08:03 +0000 Subject: [PATCH 286/456] Revert "CHROMIUM: net: wwan: t7xx: Add delay between remove and rescan" This reverts commit 4c11c48db0a662b8a516764bd90d1b202c400036. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I656c4e82900498309e5605a94d2d5278ede9d0e0 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928751 Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c index c502fb62b2835..67f13c0358461 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c +++ b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c @@ -51,12 +51,12 @@ static void t7xx_remove_rescan(struct work_struct *work) } do { - msleep(DELAY_RESCAN_MTIME); t7xx_pci_dev_rescan(); if (atomic_read(&t7xx_rescan_ctx.rescan_done)) break; + msleep(DELAY_RESCAN_MTIME); } while (num_retries--); } -- GitLab From 621a7cdd4df9df4bbd8ca23c830007036d17ba9b Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:08:14 +0000 Subject: [PATCH 287/456] Revert "CHROMIUM: net: wwan: t7xx: Compat for MR2 software" This reverts commit ca4893020e6388319012d4b5fd2aaf4ba9a7335a. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Idd383ace32382d7b93f734dd93f9b63493417e03 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928752 Reviewed-by: Ujjwal Pande Reviewed-by: Daniel Winkler Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_port_devlink.c | 30 +---------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c index 8de2ee65fe0cb..71256c6f68819 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c +++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c @@ -502,41 +502,13 @@ err_clear_bit: return ret; } -struct devlink_info_req { - struct sk_buff *msg; - void (*version_cb)(const char *version_name, - enum devlink_info_version_type version_type, - void *version_cb_priv); - void *version_cb_priv; -}; - -struct devlink_flash_component_lookup_ctx { - const char *lookup_name; - bool lookup_name_found; -}; - -static int t7xx_devlink_info_get_loopback(struct devlink *devlink, struct devlink_info_req *req, - struct netlink_ext_ack *extack) -{ - struct devlink_flash_component_lookup_ctx *lookup_ctx = req->version_cb_priv; - int ret; - - if (!req) - return t7xx_devlink_info_get(devlink, req, extack); - - ret = devlink_info_version_running_put_ext(req, lookup_ctx->lookup_name, - "1.0", DEVLINK_INFO_VERSION_TYPE_COMPONENT); - - return ret; -} - /* Call back function for devlink ops */ static const struct devlink_ops devlink_flash_ops = { .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, .flash_update = t7xx_devlink_flash_update, .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), - .info_get = t7xx_devlink_info_get_loopback, + .info_get = t7xx_devlink_info_get, .reload_down = t7xx_devlink_reload_down, .reload_up = t7xx_devlink_reload_up, }; -- GitLab From b6369b35f8c543b24ac0c943595d1874c8f24231 Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:08:27 +0000 Subject: [PATCH 288/456] Revert "CHROMIUM: net: wwan: t7xx: Restore udev events" This reverts commit fc836abd58211cb14bfeeb5923e357f4f3f0a111. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Ie31c592ca1afc529166a6a6b1d5591237407ac58 Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928753 Reviewed-by: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/Makefile | 3 +- drivers/net/wwan/t7xx/t7xx_port_devlink.c | 17 --------- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 6 ---- drivers/net/wwan/t7xx/t7xx_uevent.c | 41 ---------------------- drivers/net/wwan/t7xx/t7xx_uevent.h | 39 -------------------- 5 files changed, 1 insertion(+), 105 deletions(-) delete mode 100644 drivers/net/wwan/t7xx/t7xx_uevent.c delete mode 100644 drivers/net/wwan/t7xx/t7xx_uevent.h diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile index 6905c087c77d2..b5acffcb10475 100644 --- a/drivers/net/wwan/t7xx/Makefile +++ b/drivers/net/wwan/t7xx/Makefile @@ -18,8 +18,7 @@ mtk_t7xx-y:= t7xx_pci.o \ t7xx_netdev.o \ t7xx_pci_rescan.o \ t7xx_port_devlink.o \ - t7xx_port_ap_msg.o \ - t7xx_uevent.o + t7xx_port_ap_msg.o mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \ t7xx_port_trace.o \ diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c index 71256c6f68819..fa918b33fc9f0 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c +++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c @@ -12,7 +12,6 @@ #include "t7xx_port_devlink.h" #include "t7xx_port_proxy.h" #include "t7xx_state_monitor.h" -#include "t7xx_uevent.h" static struct t7xx_devlink_region_info t7xx_devlink_region_infos[] = { [T7XX_MRDUMP_INDEX] = {"mr_dump", T7XX_MRDUMP_SIZE}, @@ -205,7 +204,6 @@ static int t7xx_devlink_fb_flash_partition(struct t7xx_port *port, const char *p static int t7xx_devlink_fb_get_core(struct t7xx_port *port) { - char mrdump_complete_event[T7XX_FB_EVENT_SIZE]; u32 mrd_mb = T7XX_MRDUMP_SIZE / (1024 * 1024); struct t7xx_devlink *dl = port->t7xx_dev->dl; char mcmd[T7XX_FB_MCMD_SIZE + 1]; @@ -255,15 +253,11 @@ static int t7xx_devlink_fb_get_core(struct t7xx_port *port) } else if ((clen == strlen(T7XX_FB_RESP_MRDUMP_DONE)) && (!strcmp(mcmd, T7XX_FB_RESP_MRDUMP_DONE))) { dev_dbg(port->dev, "%s! size:%zd\n", T7XX_FB_RESP_MRDUMP_DONE, offset_dlen); - snprintf(mrdump_complete_event, sizeof(mrdump_complete_event), - "%s size=%zu", T7XX_UEVENT_MRDUMP_READY, offset_dlen); - t7xx_uevent_send(dl->port->dev, mrdump_complete_event); clear_bit(T7XX_MRDUMP_STATUS, &dl->status); return 0; } dev_err(port->dev, "getcore protocol error (read len %05d, response %s)\n", clen, mcmd); - t7xx_uevent_send(dl->port->dev, T7XX_UEVENT_MRD_DISCD); ret = -EPROTO; goto free_mem; } @@ -278,7 +272,6 @@ free_mem: static int t7xx_devlink_fb_dump_log(struct t7xx_port *port) { - char lkdump_complete_event[T7XX_FB_EVENT_SIZE]; struct t7xx_devlink *dl = port->t7xx_dev->dl; struct t7xx_devlink_region *lkdump_region; char rsp[T7XX_FB_RESPONSE_SIZE]; @@ -309,7 +302,6 @@ static int t7xx_devlink_fb_dump_log(struct t7xx_port *port) if (datasize > lkdump_region->info->size) { dev_err(port->dev, "lkdump size is more than %dKB. Discarded!\n", T7XX_LKDUMP_SIZE / 1024); - t7xx_uevent_send(dl->port->dev, T7XX_UEVENT_LKD_DISCD); clear_bit(T7XX_LKDUMP_STATUS, &dl->status); return -EPROTO; } @@ -333,9 +325,6 @@ static int t7xx_devlink_fb_dump_log(struct t7xx_port *port) } dev_dbg(port->dev, "LKDUMP DONE! size:%zd\n", offset); - snprintf(lkdump_complete_event, sizeof(lkdump_complete_event), "%s size=%zu", - T7XX_UEVENT_LKDUMP_READY, offset); - t7xx_uevent_send(dl->port->dev, lkdump_complete_event); clear_bit(T7XX_LKDUMP_STATUS, &dl->status); return t7xx_devlink_fb_handle_response(port, NULL); } @@ -347,7 +336,6 @@ static int t7xx_devlink_flash_update(struct devlink *devlink, struct t7xx_devlink *dl = devlink_priv(devlink); const char *component = params->component; const struct firmware *fw = params->fw; - char flash_event[T7XX_FB_EVENT_SIZE]; struct t7xx_port *port; int ret; @@ -375,15 +363,10 @@ static int t7xx_devlink_flash_update(struct devlink *devlink, if (ret) { devlink_flash_update_status_notify(devlink, "flashing failure!", params->component, 0, 0); - snprintf(flash_event, sizeof(flash_event), "%s for [%s]", - T7XX_UEVENT_FLASHING_FAILURE, params->component); } else { devlink_flash_update_status_notify(devlink, "flashing success!", params->component, 0, 0); - snprintf(flash_event, sizeof(flash_event), "%s for [%s]", - T7XX_UEVENT_FLASHING_SUCCESS, params->component); } - t7xx_uevent_send(dl->port->dev, flash_event); clear_bit(T7XX_FLASH_STATUS, &dl->status); err_out: diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 97244cc3ecdf5..aaf2ac1321545 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -41,7 +41,6 @@ #include "t7xx_port_proxy.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" -#include "t7xx_uevent.h" #define FSM_DRM_DISABLE_DELAY_MS 200 #define FSM_EVENT_POLL_INTERVAL_MS 20 @@ -257,10 +256,6 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int port->port_conf->ops->enable_chl(port); t7xx_cldma_start(md_ctrl); - if (lk_event == LK_EVENT_CREATE_PD_PORT) - t7xx_uevent_send(dev, T7XX_UEVENT_MODEM_FASTBOOT_DUMP_MODE); - else - t7xx_uevent_send(dev, T7XX_UEVENT_MODEM_FASTBOOT_DL_MODE); break; default: @@ -345,7 +340,6 @@ static void fsm_routine_ready(struct t7xx_fsm_ctl *ctl) ctl->curr_state = FSM_STATE_READY; t7xx_fsm_broadcast_ready_state(ctl); - t7xx_uevent_send(&md->t7xx_dev->pdev->dev, T7XX_UEVENT_MODEM_READY); t7xx_md_event_notify(md, FSM_READY); } diff --git a/drivers/net/wwan/t7xx/t7xx_uevent.c b/drivers/net/wwan/t7xx/t7xx_uevent.c deleted file mode 100644 index 5a320cf3f94b3..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_uevent.c +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2022, Intel Corporation. - */ - -#include - -#include "t7xx_uevent.h" - -/* Update the uevent in work queue context */ -static void t7xx_uevent_work(struct work_struct *data) -{ - struct t7xx_uevent_info *info; - char *envp[2] = { NULL, NULL }; - - info = container_of(data, struct t7xx_uevent_info, work); - envp[0] = info->uevent; - - if (kobject_uevent_env(&info->dev->kobj, KOBJ_CHANGE, envp)) - pr_err("uevent %s failed to sent", info->uevent); - - kfree(info); -} - -/** - * t7xx_uevent_send - Send modem event to user space. - * @dev: Generic device pointer - * @uevent: Uevent information - */ -void t7xx_uevent_send(struct device *dev, char *uevent) -{ - struct t7xx_uevent_info *info = kzalloc(sizeof(*info), GFP_ATOMIC); - - if (!info) - return; - - INIT_WORK(&info->work, t7xx_uevent_work); - info->dev = dev; - snprintf(info->uevent, T7XX_MAX_UEVENT_LEN, "T7XX_EVENT=%s", uevent); - schedule_work(&info->work); -} diff --git a/drivers/net/wwan/t7xx/t7xx_uevent.h b/drivers/net/wwan/t7xx/t7xx_uevent.h deleted file mode 100644 index e871dc0e9444d..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_uevent.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (c) 2022, Intel Corporation. - */ - -#ifndef __T7XX_UEVENT_H__ -#define __T7XX_UEVENT_H__ - -#include -#include - -/* Maximum length of user events */ -#define T7XX_MAX_UEVENT_LEN 64 - -/* T7XX Host driver uevents */ -#define T7XX_UEVENT_MODEM_READY "T7XX_MODEM_READY" -#define T7XX_UEVENT_MODEM_FASTBOOT_DL_MODE "T7XX_MODEM_FASTBOOT_DL_MODE" -#define T7XX_UEVENT_MODEM_FASTBOOT_DUMP_MODE "T7XX_MODEM_FASTBOOT_DUMP_MODE" -#define T7XX_UEVENT_MRDUMP_READY "T7XX_MRDUMP_READY" -#define T7XX_UEVENT_LKDUMP_READY "T7XX_LKDUMP_READY" -#define T7XX_UEVENT_MRD_DISCD "T7XX_MRDUMP_DISCARDED" -#define T7XX_UEVENT_LKD_DISCD "T7XX_LKDUMP_DISCARDED" -#define T7XX_UEVENT_FLASHING_SUCCESS "T7XX_FLASHING_SUCCESS" -#define T7XX_UEVENT_FLASHING_FAILURE "T7XX_FLASHING_FAILURE" - -/** - * struct t7xx_uevent_info - Uevent information structure. - * @dev: Pointer to device structure - * @uevent: Uevent information - * @work: Uevent work struct - */ -struct t7xx_uevent_info { - struct device *dev; - char uevent[T7XX_MAX_UEVENT_LEN]; - struct work_struct work; -}; - -void t7xx_uevent_send(struct device *dev, char *uevent); -#endif -- GitLab From 8210d387aad4f3b9c57bc19894def1d4120b6475 Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:08:38 +0000 Subject: [PATCH 289/456] Revert "FROMLIST: net: wwan: t7xx: Enable fw flashing and coredump collection" This reverts commit 839fccb8f6e49d39a69e2c7b03609d9e33999fff. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I7a79f7bdc42755254ac4684c73a4718a3dee057a Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928754 Reviewed-by: Daniel Winkler Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Ujjwal Pande Signed-off-by: Hubert Mazur --- drivers/net/wwan/Kconfig | 1 - drivers/net/wwan/t7xx/Makefile | 4 +- drivers/net/wwan/t7xx/t7xx_pci.c | 16 +- drivers/net/wwan/t7xx/t7xx_pci.h | 2 - drivers/net/wwan/t7xx/t7xx_port.h | 2 - drivers/net/wwan/t7xx/t7xx_port_ap_msg.c | 78 --- drivers/net/wwan/t7xx/t7xx_port_ap_msg.h | 11 - drivers/net/wwan/t7xx/t7xx_port_devlink.c | 664 --------------------- drivers/net/wwan/t7xx/t7xx_port_devlink.h | 86 --- drivers/net/wwan/t7xx/t7xx_port_proxy.c | 32 - drivers/net/wwan/t7xx/t7xx_port_proxy.h | 4 - drivers/net/wwan/t7xx/t7xx_port_wwan.c | 22 +- drivers/net/wwan/t7xx/t7xx_reg.h | 6 - drivers/net/wwan/t7xx/t7xx_state_monitor.c | 37 +- 14 files changed, 26 insertions(+), 939 deletions(-) delete mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.c delete mode 100644 drivers/net/wwan/t7xx/t7xx_port_ap_msg.h delete mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.c delete mode 100644 drivers/net/wwan/t7xx/t7xx_port_devlink.h diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig index dd7a9883c1ff5..410b0245114e8 100644 --- a/drivers/net/wwan/Kconfig +++ b/drivers/net/wwan/Kconfig @@ -108,7 +108,6 @@ config IOSM config MTK_T7XX tristate "MediaTek PCIe 5G WWAN modem T7xx device" depends on PCI - select NET_DEVLINK select RELAY if WWAN_DEBUGFS help Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device. diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile index b5acffcb10475..b5e1946ac8af0 100644 --- a/drivers/net/wwan/t7xx/Makefile +++ b/drivers/net/wwan/t7xx/Makefile @@ -16,9 +16,7 @@ mtk_t7xx-y:= t7xx_pci.o \ t7xx_hif_dpmaif_rx.o \ t7xx_dpmaif.o \ t7xx_netdev.o \ - t7xx_pci_rescan.o \ - t7xx_port_devlink.o \ - t7xx_port_ap_msg.o + t7xx_pci_rescan.o mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \ t7xx_port_trace.o \ diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 80743e0644028..4c8ccf90170b4 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -40,7 +40,6 @@ #include "t7xx_pci.h" #include "t7xx_pci_rescan.h" #include "t7xx_pcie_mac.h" -#include "t7xx_port_devlink.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" @@ -110,7 +109,7 @@ static int t7xx_pci_pm_init(struct t7xx_pci_dev *t7xx_dev) pm_runtime_set_autosuspend_delay(&pdev->dev, PM_AUTOSUSPEND_MS); pm_runtime_use_autosuspend(&pdev->dev); - return 0; + return t7xx_wait_pm_config(t7xx_dev); } void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev) @@ -725,20 +724,16 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pci_infracfg_ao_calc(t7xx_dev); t7xx_mhccif_init(t7xx_dev); - ret = t7xx_devlink_register(t7xx_dev); - if (ret) - return ret; - ret = t7xx_md_init(t7xx_dev); if (ret) - goto err_devlink_unregister; + return ret; t7xx_pcie_mac_interrupts_dis(t7xx_dev); ret = t7xx_interrupt_init(t7xx_dev); if (ret) { t7xx_md_exit(t7xx_dev); - goto err_devlink_unregister; + return ret; } t7xx_rescan_done(); @@ -746,10 +741,6 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pcie_mac_interrupts_en(t7xx_dev); return 0; - -err_devlink_unregister: - t7xx_devlink_unregister(t7xx_dev); - return ret; } static void t7xx_pci_remove(struct pci_dev *pdev) @@ -759,7 +750,6 @@ static void t7xx_pci_remove(struct pci_dev *pdev) t7xx_dev = pci_get_drvdata(pdev); t7xx_md_exit(t7xx_dev); - t7xx_devlink_unregister(t7xx_dev); for (i = 0; i < EXT_INT_NUM; i++) { if (!t7xx_dev->intr_handler[i]) diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index 067bc8fc0b9e8..f08f1ab744691 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.h +++ b/drivers/net/wwan/t7xx/t7xx_pci.h @@ -59,7 +59,6 @@ typedef irqreturn_t (*t7xx_intr_callback)(int irq, void *param); * @md_pm_lock: protects PCIe sleep lock * @sleep_disable_count: PCIe L1.2 lock counter * @sleep_lock_acquire: indicates that sleep has been disabled - * @dl: devlink struct */ struct t7xx_pci_dev { t7xx_intr_callback intr_handler[EXT_INT_NUM]; @@ -83,7 +82,6 @@ struct t7xx_pci_dev { #ifdef CONFIG_WWAN_DEBUGFS struct dentry *debugfs_dir; #endif - struct t7xx_devlink *dl; }; enum t7xx_pm_id { diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index dfa7ad2a97966..09acb1ef144db 100644 --- a/drivers/net/wwan/t7xx/t7xx_port.h +++ b/drivers/net/wwan/t7xx/t7xx_port.h @@ -42,8 +42,6 @@ enum port_ch { /* to AP */ PORT_CH_AP_CONTROL_RX = 0x1000, PORT_CH_AP_CONTROL_TX = 0x1001, - PORT_CH_AP_MSG_RX = 0x101E, - PORT_CH_AP_MSG_TX = 0x101F, /* to MD */ PORT_CH_CONTROL_RX = 0x2000, diff --git a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c deleted file mode 100644 index 241a179f2e3f3..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2022-2023, Intel Corporation. - */ - -#include "t7xx_port.h" -#include "t7xx_port_ap_msg.h" -#include "t7xx_port_devlink.h" -#include "t7xx_port_proxy.h" -#include "t7xx_state_monitor.h" - -int t7xx_port_ap_msg_tx(struct t7xx_port *port, char *buff, size_t len) -{ - const struct t7xx_port_conf *port_conf; - size_t offset, chunk_len = 0, txq_mtu; - struct t7xx_fsm_ctl *ctl; - struct sk_buff *skb_ccci; - enum md_state md_state; - int ret; - - if (!len || !port->chan_enable) - return -EINVAL; - - port_conf = port->port_conf; - ctl = port->t7xx_dev->md->fsm_ctl; - md_state = t7xx_fsm_get_md_state(ctl); - if (md_state == MD_STATE_WAITING_FOR_HS1 || md_state == MD_STATE_WAITING_FOR_HS2) { - dev_warn(port->dev, "Cannot write to %s port when md_state=%d\n", - port_conf->name, md_state); - return -ENODEV; - } - - txq_mtu = t7xx_get_port_mtu(port); - for (offset = 0; offset < len; offset += chunk_len) { - chunk_len = min(len - offset, txq_mtu - sizeof(struct ccci_header)); - skb_ccci = t7xx_port_alloc_skb(chunk_len); - if (!skb_ccci) - return -ENOMEM; - - skb_put_data(skb_ccci, buff + offset, chunk_len); - ret = t7xx_port_send_skb(port, skb_ccci, 0, 0); - if (ret) { - dev_kfree_skb_any(skb_ccci); - dev_err(port->dev, "Write error on %s port, %d\n", - port_conf->name, ret); - return ret; - } - } - - return len; -} - -static int t7xx_port_ap_msg_init(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - - port->rx_length_th = T7XX_MAX_QUEUE_LENGTH; - dl->status = T7XX_DEVLINK_IDLE; - dl->port = port; - - return 0; -} - -static void t7xx_port_ap_msg_uninit(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - - dl->mode = T7XX_NORMAL_MODE; - skb_queue_purge(&port->rx_skb_list); -} - -struct port_ops ap_msg_port_ops = { - .init = &t7xx_port_ap_msg_init, - .recv_skb = &t7xx_port_enqueue_skb, - .uninit = &t7xx_port_ap_msg_uninit, - .enable_chl = &t7xx_port_enable_chl, - .disable_chl = &t7xx_port_disable_chl, -}; diff --git a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h b/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h deleted file mode 100644 index 4838d87d86cff..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_port_ap_msg.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (c) 2022-2023, Intel Corporation. - */ - -#ifndef __T7XX_PORT_AP_MSG_H__ -#define __T7XX_PORT_AP_MSG_H__ - -int t7xx_port_ap_msg_tx(struct t7xx_port *port, char *buff, size_t len); - -#endif /* __T7XX_PORT_AP_MSG_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c deleted file mode 100644 index fa918b33fc9f0..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c +++ /dev/null @@ -1,664 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2022-2023, Intel Corporation. - */ - -#include - -#include "t7xx_hif_cldma.h" -#include "t7xx_pci_rescan.h" -#include "t7xx_port.h" -#include "t7xx_port_ap_msg.h" -#include "t7xx_port_devlink.h" -#include "t7xx_port_proxy.h" -#include "t7xx_state_monitor.h" - -static struct t7xx_devlink_region_info t7xx_devlink_region_infos[] = { - [T7XX_MRDUMP_INDEX] = {"mr_dump", T7XX_MRDUMP_SIZE}, - [T7XX_LKDUMP_INDEX] = {"lk_dump", T7XX_LKDUMP_SIZE}, -}; - -static int t7xx_devlink_port_read(struct t7xx_port *port, char *buf, size_t count) -{ - struct sk_buff *skb; - int ret, read_len; - - spin_lock_irq(&port->rx_wq.lock); - if (skb_queue_empty(&port->rx_skb_list)) { - ret = wait_event_interruptible_locked_irq(port->rx_wq, - !skb_queue_empty(&port->rx_skb_list)); - if (ret == -ERESTARTSYS) { - spin_unlock_irq(&port->rx_wq.lock); - return -EINTR; - } - } - skb = skb_dequeue(&port->rx_skb_list); - spin_unlock_irq(&port->rx_wq.lock); - - read_len = min_t(size_t, count, skb->len); - memcpy(buf, skb->data, read_len); - - if (read_len < skb->len) { - skb_pull(skb, read_len); - skb_queue_head(&port->rx_skb_list, skb); - } else { - consume_skb(skb); - } - - return read_len; -} - -static int t7xx_devlink_port_write(struct t7xx_port *port, const char *buf, size_t count) -{ - const struct t7xx_port_conf *port_conf = port->port_conf; - size_t actual = count, len, offset = 0; - struct sk_buff *skb; - int ret, txq_mtu; - - txq_mtu = t7xx_get_port_mtu(port); - if (txq_mtu < 0) - return -EINVAL; - - while (actual) { - len = min_t(size_t, actual, txq_mtu); - skb = __dev_alloc_skb(len, GFP_KERNEL); - if (!skb) - return -ENOMEM; - - skb_put_data(skb, buf + offset, len); - ret = t7xx_port_send_raw_skb(port, skb); - if (ret) { - dev_err(port->dev, "write error on %s, size: %zu, ret: %d\n", - port_conf->name, len, ret); - dev_kfree_skb(skb); - return ret; - } - - offset += len; - actual -= len; - } - - return count; -} - -static int t7xx_devlink_fb_handle_response(struct t7xx_port *port, char *data) -{ - char status[T7XX_FB_RESPONSE_SIZE + 1]; - int ret = 0, index, read_bytes; - - for (index = 0; index < T7XX_FB_RESP_COUNT; index++) { - read_bytes = t7xx_devlink_port_read(port, status, T7XX_FB_RESPONSE_SIZE); - if (read_bytes < 0) { - dev_err(port->dev, "status read interrupted\n"); - ret = -EIO; - break; - } - - status[read_bytes] = '\0'; - dev_dbg(port->dev, "raw response from device: %s\n", status); - if (!strncmp(status, T7XX_FB_RESP_INFO, strlen(T7XX_FB_RESP_INFO))) { - break; - } else if (!strncmp(status, T7XX_FB_RESP_OKAY, strlen(T7XX_FB_RESP_OKAY))) { - break; - } else if (!strncmp(status, T7XX_FB_RESP_FAIL, strlen(T7XX_FB_RESP_FAIL))) { - ret = -EPROTO; - break; - } else if (!strncmp(status, T7XX_FB_RESP_DATA, strlen(T7XX_FB_RESP_DATA))) { - if (data) - snprintf(data, T7XX_FB_RESPONSE_SIZE, "%s", - status + strlen(T7XX_FB_RESP_DATA)); - break; - } - } - - return ret; -} - -static int t7xx_devlink_fb_raw_command(char *cmd, struct t7xx_port *port, char *data) -{ - int ret, cmd_size = strlen(cmd); - - if (cmd_size > T7XX_FB_COMMAND_SIZE) { - dev_err(port->dev, "command length %d is long\n", cmd_size); - return -EINVAL; - } - - if (cmd_size != t7xx_devlink_port_write(port, cmd, cmd_size)) { - dev_err(port->dev, "raw command = %s write failed\n", cmd); - return -EIO; - } - - dev_dbg(port->dev, "raw command = %s written to the device\n", cmd); - ret = t7xx_devlink_fb_handle_response(port, data); - if (ret) - dev_err(port->dev, "raw command = %s response FAILURE:%d\n", cmd, ret); - - return ret; -} - -static int t7xx_devlink_fb_download_command(struct t7xx_port *port, size_t size) -{ - char download_command[T7XX_FB_COMMAND_SIZE]; - - snprintf(download_command, sizeof(download_command), "%s:%08zx", - T7XX_FB_CMD_DOWNLOAD, size); - return t7xx_devlink_fb_raw_command(download_command, port, NULL); -} - -static int t7xx_devlink_fb_download(struct t7xx_port *port, const u8 *buf, size_t size) -{ - int ret; - - if (!size) - return -EINVAL; - - ret = t7xx_devlink_fb_download_command(port, size); - if (ret) - return ret; - - ret = t7xx_devlink_port_write(port, buf, size); - if (ret < 0) - return ret; - - return t7xx_devlink_fb_handle_response(port, NULL); -} - -static int t7xx_devlink_fb_flash(struct t7xx_port *port, const char *cmd) -{ - char flash_command[T7XX_FB_COMMAND_SIZE]; - - snprintf(flash_command, sizeof(flash_command), "%s:%s", T7XX_FB_CMD_FLASH, cmd); - return t7xx_devlink_fb_raw_command(flash_command, port, NULL); -} - -static int t7xx_devlink_get_part_ver_fb_mode(struct t7xx_port *port, const char *cmd, char *data) -{ - char req_command[T7XX_FB_COMMAND_SIZE]; - - snprintf(req_command, sizeof(req_command), "%s:%s", T7XX_FB_CMD_GET_VER, cmd); - return t7xx_devlink_fb_raw_command(req_command, port, data); -} - -static int t7xx_devlink_get_part_ver_norm_mode(struct t7xx_port *port, const char *cmd, char *data) -{ - char req_command[T7XX_FB_COMMAND_SIZE]; - int len; - - len = snprintf(req_command, sizeof(req_command), "%s:%s", T7XX_FB_CMD_GET_VER, cmd); - t7xx_port_ap_msg_tx(port, req_command, len); - - return t7xx_devlink_fb_handle_response(port, data); -} - -static int t7xx_devlink_fb_flash_partition(struct t7xx_port *port, const char *partition, - const u8 *buf, size_t size) -{ - int ret; - - ret = t7xx_devlink_fb_download(port, buf, size); - if (ret < 0) - return ret; - - return t7xx_devlink_fb_flash(port, partition); -} - -static int t7xx_devlink_fb_get_core(struct t7xx_port *port) -{ - u32 mrd_mb = T7XX_MRDUMP_SIZE / (1024 * 1024); - struct t7xx_devlink *dl = port->t7xx_dev->dl; - char mcmd[T7XX_FB_MCMD_SIZE + 1]; - size_t offset_dlen = 0; - int clen, dlen, ret; - - dl->regions[T7XX_MRDUMP_INDEX].buf = vmalloc(dl->regions[T7XX_MRDUMP_INDEX].info->size); - if (!dl->regions[T7XX_MRDUMP_INDEX].buf) - return -ENOMEM; - - set_bit(T7XX_MRDUMP_STATUS, &dl->status); - ret = t7xx_devlink_fb_raw_command(T7XX_FB_CMD_OEM_MRDUMP, port, NULL); - if (ret) { - dev_err(port->dev, "%s command failed\n", T7XX_FB_CMD_OEM_MRDUMP); - goto free_mem; - } - - while (dl->regions[T7XX_MRDUMP_INDEX].info->size > offset_dlen) { - clen = t7xx_devlink_port_read(port, mcmd, sizeof(mcmd) - 1); - mcmd[clen] = '\0'; - if (clen == strlen(T7XX_FB_CMD_RTS) && (!strcmp(mcmd, T7XX_FB_CMD_RTS))) { - memset(mcmd, 0, sizeof(mcmd)); - if (t7xx_devlink_port_write(port, T7XX_FB_CMD_CTS, strlen(T7XX_FB_CMD_CTS)) - != strlen(T7XX_FB_CMD_CTS)) { - dev_err(port->dev, "write for _CTS failed:%zu\n", - strlen(T7XX_FB_CMD_CTS)); - goto free_mem; - } - - dlen = t7xx_devlink_port_read(port, dl->regions[T7XX_MRDUMP_INDEX].buf + - offset_dlen, T7XX_FB_MDATA_SIZE); - if (dlen <= 0) { - dev_err(port->dev, "read data error(%d)\n", dlen); - ret = -EPROTO; - goto free_mem; - } - offset_dlen += dlen; - - if (t7xx_devlink_port_write(port, T7XX_FB_CMD_FIN, strlen(T7XX_FB_CMD_FIN)) - != strlen(T7XX_FB_CMD_FIN)) { - dev_err(port->dev, "_FIN failed, (Read %05zu:%05zu)\n", - strlen(T7XX_FB_CMD_FIN), offset_dlen); - ret = -EPROTO; - goto free_mem; - } - continue; - } else if ((clen == strlen(T7XX_FB_RESP_MRDUMP_DONE)) && - (!strcmp(mcmd, T7XX_FB_RESP_MRDUMP_DONE))) { - dev_dbg(port->dev, "%s! size:%zd\n", T7XX_FB_RESP_MRDUMP_DONE, offset_dlen); - clear_bit(T7XX_MRDUMP_STATUS, &dl->status); - return 0; - } - dev_err(port->dev, "getcore protocol error (read len %05d, response %s)\n", - clen, mcmd); - ret = -EPROTO; - goto free_mem; - } - - dev_err(port->dev, "mrdump exceeds %uMB size. Discarded!\n", mrd_mb); - -free_mem: - vfree(dl->regions[T7XX_MRDUMP_INDEX].buf); - clear_bit(T7XX_MRDUMP_STATUS, &dl->status); - return ret; -} - -static int t7xx_devlink_fb_dump_log(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - struct t7xx_devlink_region *lkdump_region; - char rsp[T7XX_FB_RESPONSE_SIZE]; - int dlen, datasize = 0, ret; - size_t offset = 0; - - if (dl->status != T7XX_DEVLINK_IDLE) { - dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n"); - return -EBUSY; - } - - set_bit(T7XX_LKDUMP_STATUS, &dl->status); - ret = t7xx_devlink_fb_raw_command(T7XX_FB_CMD_OEM_LKDUMP, port, rsp); - if (ret) { - dev_err(port->dev, "%s command returns failure\n", T7XX_FB_CMD_OEM_LKDUMP); - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return ret; - } - - ret = kstrtoint(rsp, 16, &datasize); - if (ret) { - dev_err(port->dev, "kstrtoint error!\n"); - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return ret; - } - - lkdump_region = &dl->regions[T7XX_LKDUMP_INDEX]; - if (datasize > lkdump_region->info->size) { - dev_err(port->dev, "lkdump size is more than %dKB. Discarded!\n", - T7XX_LKDUMP_SIZE / 1024); - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return -EPROTO; - } - - lkdump_region->buf = vmalloc(lkdump_region->info->size); - if (!lkdump_region->buf) { - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return -ENOMEM; - } - - while (datasize > 0) { - dlen = t7xx_devlink_port_read(port, lkdump_region->buf + offset, datasize); - if (dlen <= 0) { - dev_err(port->dev, "lkdump read error ret = %d\n", dlen); - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return -EPROTO; - } - - datasize -= dlen; - offset += dlen; - } - - dev_dbg(port->dev, "LKDUMP DONE! size:%zd\n", offset); - clear_bit(T7XX_LKDUMP_STATUS, &dl->status); - return t7xx_devlink_fb_handle_response(port, NULL); -} - -static int t7xx_devlink_flash_update(struct devlink *devlink, - struct devlink_flash_update_params *params, - struct netlink_ext_ack *extack) -{ - struct t7xx_devlink *dl = devlink_priv(devlink); - const char *component = params->component; - const struct firmware *fw = params->fw; - struct t7xx_port *port; - int ret; - - if (dl->mode != T7XX_FB_DL_MODE) { - dev_err(&dl->t7xx_dev->pdev->dev, "Modem is not in fastboot download mode!\n"); - ret = -EPERM; - goto err_out; - } - - if (dl->status != T7XX_DEVLINK_IDLE) { - dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n"); - ret = -EBUSY; - goto err_out; - } - - if (!component || !fw->data) { - ret = -EINVAL; - goto err_out; - } - - set_bit(T7XX_FLASH_STATUS, &dl->status); - port = dl->port; - dev_dbg(port->dev, "flash partition name:%s binary size:%zu\n", component, fw->size); - ret = t7xx_devlink_fb_flash_partition(port, component, fw->data, fw->size); - if (ret) { - devlink_flash_update_status_notify(devlink, "flashing failure!", - params->component, 0, 0); - } else { - devlink_flash_update_status_notify(devlink, "flashing success!", - params->component, 0, 0); - } - clear_bit(T7XX_FLASH_STATUS, &dl->status); - -err_out: - return ret; -} - -enum t7xx_devlink_param_id { - T7XX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, - T7XX_DEVLINK_PARAM_ID_FASTBOOT, -}; - -static const struct devlink_param t7xx_devlink_params[] = { - DEVLINK_PARAM_DRIVER(T7XX_DEVLINK_PARAM_ID_FASTBOOT, - "fastboot", DEVLINK_PARAM_TYPE_BOOL, - BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), - NULL, NULL, NULL), -}; - -bool t7xx_devlink_param_get_fastboot(struct devlink *devlink) -{ - union devlink_param_value saved_value; - - devl_param_driverinit_value_get(devlink, T7XX_DEVLINK_PARAM_ID_FASTBOOT, - &saved_value); - return saved_value.vbool; -} - -static int t7xx_devlink_reload_down(struct devlink *devlink, bool netns_change, - enum devlink_reload_action action, - enum devlink_reload_limit limit, - struct netlink_ext_ack *extack) -{ - struct t7xx_devlink *dl = devlink_priv(devlink); - - switch (action) { - case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: - return 0; - case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: - if (!dl->mode) - return -EPERM; - return t7xx_devlink_fb_raw_command(T7XX_FB_CMD_REBOOT, dl->port, NULL); - default: - /* Unsupported action should not get to this function */ - return -EOPNOTSUPP; - } -} - -static int t7xx_devlink_reload_up(struct devlink *devlink, - enum devlink_reload_action action, - enum devlink_reload_limit limit, - u32 *actions_performed, - struct netlink_ext_ack *extack) -{ - struct t7xx_devlink *dl = devlink_priv(devlink); - *actions_performed = BIT(action); - switch (action) { - case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: - case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: - t7xx_rescan_queue_work(dl->t7xx_dev->pdev); - return 0; - default: - /* Unsupported action should not get to this function */ - return -EOPNOTSUPP; - } -} - -static int t7xx_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, - struct netlink_ext_ack *extack) -{ - struct t7xx_devlink *dl = devlink_priv(devlink); - char *part_name, *ver, *part_no, *data; - int ret, total_part, i, ver_len; - struct t7xx_port *port; - - port = dl->port; - port->port_conf->ops->enable_chl(port); - - if (dl->status != T7XX_DEVLINK_IDLE) { - dev_err(&dl->t7xx_dev->pdev->dev, "Modem is busy!\n"); - return -EBUSY; - } - - data = kzalloc(T7XX_FB_RESPONSE_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - - set_bit(T7XX_GET_INFO, &dl->status); - if (dl->mode == T7XX_FB_DL_MODE) - ret = t7xx_devlink_get_part_ver_fb_mode(port, "", data); - else - ret = t7xx_devlink_get_part_ver_norm_mode(port, "", data); - - if (ret < 0) - goto err_clear_bit; - - part_no = strsep(&data, ","); - if (kstrtoint(part_no, 16, &total_part)) { - dev_err(&dl->t7xx_dev->pdev->dev, "kstrtoint error!\n"); - ret = -EINVAL; - goto err_clear_bit; - } - - for (i = 0; i < total_part; i++) { - part_name = strsep(&data, ","); - ver = strsep(&data, ","); - ver_len = strlen(ver); - if (ver[ver_len - 2] == 0x5C && ver[ver_len - 1] == 0x6E) - ver[ver_len - 4] = '\0'; - ret = devlink_info_version_running_put_ext(req, part_name, ver, - DEVLINK_INFO_VERSION_TYPE_COMPONENT); - } - -err_clear_bit: - clear_bit(T7XX_GET_INFO, &dl->status); - kfree(data); - return ret; -} - -/* Call back function for devlink ops */ -static const struct devlink_ops devlink_flash_ops = { - .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, - .flash_update = t7xx_devlink_flash_update, - .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | - BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), - .info_get = t7xx_devlink_info_get, - .reload_down = t7xx_devlink_reload_down, - .reload_up = t7xx_devlink_reload_up, -}; - -static int t7xx_devlink_region_snapshot(struct devlink *dl, const struct devlink_region_ops *ops, - struct netlink_ext_ack *extack, u8 **data) -{ - struct t7xx_devlink *t7xx_dl = devlink_priv(dl); - struct t7xx_devlink_region *region = ops->priv; - struct t7xx_port *port = t7xx_dl->port; - u8 *snapshot_mem; - - if (t7xx_dl->status != T7XX_DEVLINK_IDLE) - return -EBUSY; - - if (!strncmp(ops->name, "mr_dump", strlen("mr_dump"))) { - snapshot_mem = vmalloc(region->info->size); - memcpy(snapshot_mem, region->buf, region->info->size); - *data = snapshot_mem; - } else if (!strncmp(ops->name, "lk_dump", strlen("lk_dump"))) { - int ret; - - ret = t7xx_devlink_fb_dump_log(port); - if (ret) - return ret; - - *data = region->buf; - } - - return 0; -} - -/* To create regions for dump files */ -static int t7xx_devlink_create_regions(struct t7xx_devlink *dl) -{ - int ret, i; - - BUILD_BUG_ON(ARRAY_SIZE(t7xx_devlink_region_infos) > ARRAY_SIZE(dl->regions)); - for (i = 0; i < ARRAY_SIZE(t7xx_devlink_region_infos); i++) { - dl->regions[i].info = &t7xx_devlink_region_infos[i]; - dl->regions[i].ops.name = dl->regions[i].info->name; - dl->regions[i].ops.snapshot = t7xx_devlink_region_snapshot; - dl->regions[i].ops.destructor = vfree; - dl->regions[i].dlreg = devlink_region_create(dl->ctx, &dl->regions[i].ops, - T7XX_MAX_SNAPSHOTS, - t7xx_devlink_region_infos[i].size); - if (IS_ERR(dl->regions[i].dlreg)) { - ret = PTR_ERR(dl->regions[i].dlreg); - dev_err(dl->port->dev, "devlink region fail,err %d\n", ret); - for ( ; i >= 0; i--) - devlink_region_destroy(dl->regions[i].dlreg); - - return ret; - } - - dl->regions[i].ops.priv = &dl->regions[i]; - } - - return 0; -} - -int t7xx_devlink_register(struct t7xx_pci_dev *t7xx_dev) -{ - union devlink_param_value value; - struct devlink *dl_ctx; - - dl_ctx = devlink_alloc(&devlink_flash_ops, sizeof(struct t7xx_devlink), - &t7xx_dev->pdev->dev); - if (!dl_ctx) - return -ENOMEM; - - t7xx_dev->dl = devlink_priv(dl_ctx); - t7xx_dev->dl->ctx = dl_ctx; - t7xx_dev->dl->t7xx_dev = t7xx_dev; - devlink_params_register(dl_ctx, t7xx_devlink_params, ARRAY_SIZE(t7xx_devlink_params)); - value.vbool = false; - devl_param_driverinit_value_set(dl_ctx, T7XX_DEVLINK_PARAM_ID_FASTBOOT, value); - devlink_register(dl_ctx); - - return 0; -} - -void t7xx_devlink_unregister(struct t7xx_pci_dev *t7xx_dev) -{ - struct devlink *dl_ctx = t7xx_dev->dl->ctx; - - devlink_unregister(dl_ctx); - devlink_params_unregister(dl_ctx, t7xx_devlink_params, ARRAY_SIZE(t7xx_devlink_params)); - devlink_free(dl_ctx); -} - -static void t7xx_devlink_work(struct work_struct *work) -{ - struct t7xx_devlink *dl; - - dl = container_of(work, struct t7xx_devlink, ws); - t7xx_devlink_fb_get_core(dl->port); -} - -/** - * t7xx_devlink_init - Initialize devlink to t7xx driver - * @port: Pointer to port structure - * - * Returns: 0 on success and error values on failure - */ -static int t7xx_devlink_init(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - struct workqueue_struct *dl_wq; - int rc; - - dl_wq = create_workqueue("t7xx_devlink"); - if (!dl_wq) { - dev_err(port->dev, "create_workqueue failed\n"); - return -ENODATA; - } - - INIT_WORK(&dl->ws, t7xx_devlink_work); - port->rx_length_th = T7XX_MAX_QUEUE_LENGTH; - - dl->mode = T7XX_NORMAL_MODE; - dl->status = T7XX_DEVLINK_IDLE; - dl->wq = dl_wq; - dl->port = port; - - rc = t7xx_devlink_create_regions(dl); - if (rc) { - destroy_workqueue(dl->wq); - dev_err(port->dev, "devlink region creation failed, rc %d\n", rc); - return -ENOMEM; - } - - return 0; -} - -static void t7xx_devlink_uninit(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - int i; - - vfree(dl->regions[T7XX_MRDUMP_INDEX].buf); - - dl->mode = T7XX_NORMAL_MODE; - destroy_workqueue(dl->wq); - - BUILD_BUG_ON(ARRAY_SIZE(t7xx_devlink_region_infos) > ARRAY_SIZE(dl->regions)); - for (i = 0; i < ARRAY_SIZE(t7xx_devlink_region_infos); ++i) - devlink_region_destroy(dl->regions[i].dlreg); - - skb_queue_purge(&port->rx_skb_list); -} - -static int t7xx_devlink_enable_chl(struct t7xx_port *port) -{ - struct t7xx_devlink *dl = port->t7xx_dev->dl; - - t7xx_port_enable_chl(port); - if (dl->mode == T7XX_FB_DUMP_MODE) - queue_work(dl->wq, &dl->ws); - - return 0; -} - -struct port_ops devlink_port_ops = { - .init = &t7xx_devlink_init, - .recv_skb = &t7xx_port_enqueue_skb, - .uninit = &t7xx_devlink_uninit, - .enable_chl = &t7xx_devlink_enable_chl, - .disable_chl = &t7xx_port_disable_chl, -}; diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.h b/drivers/net/wwan/t7xx/t7xx_port_devlink.h deleted file mode 100644 index 4074004110b8e..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_port_devlink.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (c) 2022-2023, Intel Corporation. - */ - -#ifndef __T7XX_PORT_DEVLINK_H__ -#define __T7XX_PORT_DEVLINK_H__ - -#include -#include - -#include "t7xx_pci.h" - -#define T7XX_MAX_QUEUE_LENGTH 32 -#define T7XX_FB_COMMAND_SIZE 64 -#define T7XX_FB_RESPONSE_SIZE 512 -#define T7XX_FB_MCMD_SIZE 64 -#define T7XX_FB_MDATA_SIZE 1024 -#define T7XX_FB_RESP_COUNT 30 - -#define T7XX_FB_CMD_RTS "_RTS" -#define T7XX_FB_CMD_CTS "_CTS" -#define T7XX_FB_CMD_FIN "_FIN" -#define T7XX_FB_CMD_OEM_MRDUMP "oem mrdump" -#define T7XX_FB_CMD_OEM_LKDUMP "oem dump_pllk_log" -#define T7XX_FB_CMD_DOWNLOAD "download" -#define T7XX_FB_CMD_FLASH "flash" -#define T7XX_FB_CMD_REBOOT "reboot" -#define T7XX_FB_RESP_MRDUMP_DONE "MRDUMP08_DONE" -#define T7XX_FB_RESP_OKAY "OKAY" -#define T7XX_FB_RESP_FAIL "FAIL" -#define T7XX_FB_RESP_DATA "DATA" -#define T7XX_FB_RESP_INFO "INFO" -#define T7XX_FB_CMD_GET_VER "get_version" - -#define T7XX_FB_EVENT_SIZE 50 - -#define T7XX_MAX_SNAPSHOTS 1 -#define T7XX_MRDUMP_SIZE (160 * 1024 * 1024) -#define T7XX_LKDUMP_SIZE (256 * 1024) -#define T7XX_TOTAL_REGIONS 2 - -#define T7XX_FLASH_STATUS 0 -#define T7XX_MRDUMP_STATUS 1 -#define T7XX_LKDUMP_STATUS 2 -#define T7XX_GET_INFO 3 -#define T7XX_DEVLINK_IDLE 0 - -#define T7XX_NORMAL_MODE 0 -#define T7XX_FB_DL_MODE 1 -#define T7XX_FB_DUMP_MODE 2 - -/* Internal region indexes */ -enum t7xx_regions { - T7XX_MRDUMP_INDEX, - T7XX_LKDUMP_INDEX, -}; - -struct t7xx_devlink_region_info { - const char *name; - size_t size; -}; - -struct t7xx_devlink_region { - struct t7xx_devlink_region_info *info; - struct devlink_region_ops ops; - struct devlink_region *dlreg; - void *buf; -}; - -struct t7xx_devlink { - struct t7xx_devlink_region regions[T7XX_TOTAL_REGIONS]; - struct t7xx_pci_dev *t7xx_dev; - struct workqueue_struct *wq; - struct t7xx_port *port; - struct work_struct ws; - struct devlink *ctx; - unsigned long status; - u8 mode; -}; - -bool t7xx_devlink_param_get_fastboot(struct devlink *devlink); -int t7xx_devlink_register(struct t7xx_pci_dev *t7xx_dev); -void t7xx_devlink_unregister(struct t7xx_pci_dev *t7xx_dev); - -#endif /*__T7XX_PORT_DEVLINK_H__*/ diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 5cc03a5a9bccc..b457e8da098e4 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -40,7 +40,6 @@ #define Q_IDX_CTRL 0 #define Q_IDX_MBIM 2 #define Q_IDX_AT_CMD 5 -#define Q_IDX_AP_MSG 2 #define INVALID_SEQ_NUM GENMASK(15, 0) @@ -98,18 +97,7 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { .path_id = CLDMA_ID_AP, .ops = &ctl_port_ops, .name = "t7xx_ap_ctrl", - }, { - .tx_ch = PORT_CH_AP_MSG_TX, - .rx_ch = PORT_CH_AP_MSG_RX, - .txq_index = Q_IDX_AP_MSG, - .rxq_index = Q_IDX_AP_MSG, - .txq_exp_index = Q_IDX_AP_MSG, - .rxq_exp_index = Q_IDX_AP_MSG, - .path_id = CLDMA_ID_AP, - .ops = &ap_msg_port_ops, - .name = "ap_msg", }, - }; static struct t7xx_port_conf t7xx_early_port_conf[] = { @@ -121,8 +109,6 @@ static struct t7xx_port_conf t7xx_early_port_conf[] = { .txq_exp_index = CLDMA_Q_IDX_DUMP, .rxq_exp_index = CLDMA_Q_IDX_DUMP, .path_id = CLDMA_ID_AP, - .ops = &devlink_port_ops, - .name = "devlink", }, }; @@ -339,24 +325,6 @@ int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg); } -int t7xx_port_enable_chl(struct t7xx_port *port) -{ - spin_lock(&port->port_update_lock); - port->chan_enable = true; - spin_unlock(&port->port_update_lock); - - return 0; -} - -int t7xx_port_disable_chl(struct t7xx_port *port) -{ - spin_lock(&port->port_update_lock); - port->chan_enable = false; - spin_unlock(&port->port_update_lock); - - return 0; -} - static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox) { struct t7xx_port *port; diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h index b86594ed04584..0f3fb53259b7a 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h @@ -93,8 +93,6 @@ struct ctrl_msg_header { /* Port operations mapping */ extern struct port_ops wwan_sub_port_ops; extern struct port_ops ctl_port_ops; -extern struct port_ops devlink_port_ops; -extern struct port_ops ap_msg_port_ops; #ifdef CONFIG_WWAN_DEBUGFS extern struct port_ops t7xx_trace_port_ops; @@ -110,7 +108,5 @@ int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned in void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id); int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb); int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb); -int t7xx_port_enable_chl(struct t7xx_port *port); -int t7xx_port_disable_chl(struct t7xx_port *port); #endif /* __T7XX_PORT_PROXY_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c index 0637a51a08fef..17389c8f6600a 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c +++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c @@ -131,6 +131,24 @@ static int t7xx_port_wwan_recv_skb(struct t7xx_port *port, struct sk_buff *skb) return 0; } +static int t7xx_port_wwan_enable_chl(struct t7xx_port *port) +{ + spin_lock(&port->port_update_lock); + port->chan_enable = true; + spin_unlock(&port->port_update_lock); + + return 0; +} + +static int t7xx_port_wwan_disable_chl(struct t7xx_port *port) +{ + spin_lock(&port->port_update_lock); + port->chan_enable = false; + spin_unlock(&port->port_update_lock); + + return 0; +} + static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int state) { const struct t7xx_port_conf *port_conf = port->port_conf; @@ -154,7 +172,7 @@ struct port_ops wwan_sub_port_ops = { .init = t7xx_port_wwan_init, .recv_skb = t7xx_port_wwan_recv_skb, .uninit = t7xx_port_wwan_uninit, - .enable_chl = t7xx_port_enable_chl, - .disable_chl = t7xx_port_disable_chl, + .enable_chl = t7xx_port_wwan_enable_chl, + .disable_chl = t7xx_port_wwan_disable_chl, .md_state_notify = t7xx_port_wwan_md_state_notify, }; diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h index d19f2b810f8e5..44352cd024603 100644 --- a/drivers/net/wwan/t7xx/t7xx_reg.h +++ b/drivers/net/wwan/t7xx/t7xx_reg.h @@ -101,18 +101,12 @@ enum t7xx_pm_resume_state { PM_RESUME_REG_STATE_L2_EXP, }; -enum host_event_e { - HOST_EVENT_INIT = 0, - FASTBOOT_DL_NOTIFY = 0x3, -}; - #define T7XX_PCIE_MISC_DEV_STATUS 0x0d1c #define MISC_RESET_TYPE_FLDR BIT(27) #define MISC_RESET_TYPE_PLDR BIT(26) #define MISC_DEV_STATUS_MASK GENMASK(15, 0) #define MISC_DEV_STATUS_INVALID GENMASK(15, 0) #define MISC_LK_EVENT_MASK GENMASK(11, 8) -#define HOST_EVENT_MASK GENMASK(31, 28) enum lk_event_id { LK_EVENT_NORMAL = 0, diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index aaf2ac1321545..65f487f4fffd3 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -37,7 +37,6 @@ #include "t7xx_modem_ops.h" #include "t7xx_pci.h" #include "t7xx_pcie_mac.h" -#include "t7xx_port_devlink.h" #include "t7xx_port_proxy.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" @@ -214,22 +213,11 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm fsm_finish_command(ctl, cmd, 0); } -static void t7xx_host_event_notify(struct t7xx_modem *md, unsigned int event_id) -{ - u32 value; - - value = ioread32(IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); - value &= ~HOST_EVENT_MASK; - value |= FIELD_PREP(HOST_EVENT_MASK, event_id); - iowrite32(value, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); -} - static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status) { struct t7xx_modem *md = ctl->md; struct cldma_ctrl *md_ctrl; enum lk_event_id lk_event; - struct t7xx_port *port; struct device *dev; dev = &md->t7xx_dev->pdev->dev; @@ -240,21 +228,10 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int break; case LK_EVENT_CREATE_PD_PORT: - case LK_EVENT_CREATE_POST_DL_PORT: md_ctrl = md->md_ctrl[CLDMA_ID_AP]; t7xx_cldma_hif_hw_init(md_ctrl); t7xx_cldma_stop(md_ctrl); t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG); - port = ctl->md->t7xx_dev->dl->port; - if (WARN_ON(!port)) - return; - - if (lk_event == LK_EVENT_CREATE_PD_PORT) - md->t7xx_dev->dl->mode = T7XX_FB_DUMP_MODE; - else - md->t7xx_dev->dl->mode = T7XX_FB_DL_MODE; - - port->port_conf->ops->enable_chl(port); t7xx_cldma_start(md_ctrl); break; @@ -301,23 +278,13 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma t7xx_cldma_stop(md_ctrl); if (!ctl->md->rgu_irq_asserted) { - if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) - t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY); - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); /* Wait for the DRM disable to take effect */ msleep(FSM_DRM_DISABLE_DELAY_MS); - if (t7xx_devlink_param_get_fastboot(t7xx_dev->dl->ctx)) { - /* Do not try fldr because device will always wait for - * MHCCIF bit 13 in fastboot download flow. - */ + err = t7xx_acpi_fldr_func(t7xx_dev); + if (err) t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); - } else { - err = t7xx_acpi_fldr_func(t7xx_dev); - if (err) - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); - } } fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl)); -- GitLab From fd66cbc4d86d6e08f2285ec77b422146c31d716f Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:08:48 +0000 Subject: [PATCH 290/456] Revert "FROMLIST: net: wwan: t7xx: PCIe reset rescan" This reverts commit e38ee2af3e5f112fe98c044f57767489a6ac1322. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I15d4417b53f6ecd2699f379a8f89ba2d9d393eed Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928755 Reviewed-by: Ujjwal Pande Tested-by: Daniel Winkler Reviewed-by: Daniel Winkler Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/Makefile | 3 +- drivers/net/wwan/t7xx/t7xx_modem_ops.c | 3 - drivers/net/wwan/t7xx/t7xx_pci.c | 56 +-------------- drivers/net/wwan/t7xx/t7xx_pci_rescan.c | 96 ------------------------- drivers/net/wwan/t7xx/t7xx_pci_rescan.h | 28 -------- 5 files changed, 2 insertions(+), 184 deletions(-) delete mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.c delete mode 100644 drivers/net/wwan/t7xx/t7xx_pci_rescan.h diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile index b5e1946ac8af0..2652cd00504e6 100644 --- a/drivers/net/wwan/t7xx/Makefile +++ b/drivers/net/wwan/t7xx/Makefile @@ -15,8 +15,7 @@ mtk_t7xx-y:= t7xx_pci.o \ t7xx_hif_dpmaif_tx.o \ t7xx_hif_dpmaif_rx.o \ t7xx_dpmaif.o \ - t7xx_netdev.o \ - t7xx_pci_rescan.o + t7xx_netdev.o mtk_t7xx-$(CONFIG_WWAN_DEBUGFS) += \ t7xx_port_trace.o \ diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 2fcaea4694ba6..cbd65aa48721a 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -37,7 +37,6 @@ #include "t7xx_modem_ops.h" #include "t7xx_netdev.h" #include "t7xx_pci.h" -#include "t7xx_pci_rescan.h" #include "t7xx_pcie_mac.h" #include "t7xx_port.h" #include "t7xx_port_proxy.h" @@ -195,8 +194,6 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data) msleep(RGU_RESET_DELAY_MS); t7xx_reset_device_via_pmic(t7xx_dev); - t7xx_rescan_queue_work(t7xx_dev->pdev); - return IRQ_HANDLED; } diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 4c8ccf90170b4..91256e005b846 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -38,7 +38,6 @@ #include "t7xx_mhccif.h" #include "t7xx_modem_ops.h" #include "t7xx_pci.h" -#include "t7xx_pci_rescan.h" #include "t7xx_pcie_mac.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" @@ -736,7 +735,6 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } - t7xx_rescan_done(); t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT); t7xx_pcie_mac_interrupts_en(t7xx_dev); @@ -776,59 +774,7 @@ static struct pci_driver t7xx_pci_driver = { .shutdown = t7xx_pci_shutdown, }; -static int __init t7xx_pci_init(void) -{ - int ret; - - t7xx_pci_dev_rescan(); - ret = t7xx_rescan_init(); - if (ret) { - pr_err("Failed to init t7xx rescan work\n"); - return ret; - } - - return pci_register_driver(&t7xx_pci_driver); -} -module_init(t7xx_pci_init); - -static int t7xx_always_match(struct device *dev, const void *data) -{ - struct pci_dev *pdev = to_pci_dev(dev); - const struct pci_device_id *id = data; - - if (pci_match_id(id, pdev)) - return 1; - - return 0; -} - -static void __exit t7xx_pci_cleanup(void) -{ - int remove_flag = 0; - struct device *dev; - - dev = driver_find_device(&t7xx_pci_driver.driver, NULL, &t7xx_pci_table[0], - t7xx_always_match); - if (dev) { - pr_debug("unregister t7xx PCIe driver while device is still exist.\n"); - put_device(dev); - remove_flag = 1; - } else { - pr_debug("no t7xx PCIe driver found.\n"); - } - - pci_lock_rescan_remove(); - pci_unregister_driver(&t7xx_pci_driver); - pci_unlock_rescan_remove(); - - t7xx_rescan_deinit(); - if (remove_flag) { - pr_debug("remove t7xx PCI device\n"); - pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); - } -} - -module_exit(t7xx_pci_cleanup); +module_pci_driver(t7xx_pci_driver); MODULE_AUTHOR("MediaTek Inc"); MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver"); diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c b/drivers/net/wwan/t7xx/t7xx_pci_rescan.c deleted file mode 100644 index 67f13c0358461..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2021, MediaTek Inc. - * Copyright (c) 2021-2023, Intel Corporation. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ":t7xx:%s: " fmt, __func__ -#define dev_fmt(fmt) "t7xx: " fmt - -#include -#include -#include -#include - -#include "t7xx_pci.h" -#include "t7xx_pci_rescan.h" - -static struct remove_rescan_context t7xx_rescan_ctx; - -void t7xx_pci_dev_rescan(void) -{ - struct pci_bus *b = NULL; - - pci_lock_rescan_remove(); - while ((b = pci_find_next_bus(b))) - pci_rescan_bus(b); - pci_unlock_rescan_remove(); -} - -void t7xx_rescan_done(void) -{ - if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) { - atomic_set(&t7xx_rescan_ctx.rescan_done, 1); - pr_debug("Rescan probe\n"); - } else { - pr_debug("Init probe\n"); - } -} - -static void t7xx_remove_rescan(struct work_struct *work) -{ - int num_retries = RESCAN_RETRIES; - struct pci_dev *pdev; - - atomic_set(&t7xx_rescan_ctx.rescan_done, 0); - pdev = t7xx_rescan_ctx.dev; - - if (pdev) { - pci_stop_and_remove_bus_device_locked(pdev); - pr_debug("start remove and rescan flow\n"); - } - - do { - t7xx_pci_dev_rescan(); - - if (atomic_read(&t7xx_rescan_ctx.rescan_done)) - break; - - msleep(DELAY_RESCAN_MTIME); - } while (num_retries--); -} - -void t7xx_rescan_queue_work(struct pci_dev *pdev) -{ - if (!atomic_read(&t7xx_rescan_ctx.rescan_done)) { - dev_err(&pdev->dev, "Rescan failed\n"); - return; - } - - t7xx_rescan_ctx.dev = pdev; - queue_work(t7xx_rescan_ctx.pcie_rescan_wq, &t7xx_rescan_ctx.service_task); -} - -int t7xx_rescan_init(void) -{ - atomic_set(&t7xx_rescan_ctx.rescan_done, 1); - t7xx_rescan_ctx.dev = NULL; - - t7xx_rescan_ctx.pcie_rescan_wq = create_singlethread_workqueue(MTK_RESCAN_WQ); - if (!t7xx_rescan_ctx.pcie_rescan_wq) { - pr_err("Failed to create workqueue: %s\n", MTK_RESCAN_WQ); - return -ENOMEM; - } - - INIT_WORK(&t7xx_rescan_ctx.service_task, t7xx_remove_rescan); - - return 0; -} - -void t7xx_rescan_deinit(void) -{ - t7xx_rescan_ctx.dev = NULL; - atomic_set(&t7xx_rescan_ctx.rescan_done, 0); - cancel_work_sync(&t7xx_rescan_ctx.service_task); - destroy_workqueue(t7xx_rescan_ctx.pcie_rescan_wq); -} diff --git a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h b/drivers/net/wwan/t7xx/t7xx_pci_rescan.h deleted file mode 100644 index 80b25c44151c9..0000000000000 --- a/drivers/net/wwan/t7xx/t7xx_pci_rescan.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (c) 2021, MediaTek Inc. - * Copyright (c) 2021-2023, Intel Corporation. - */ - -#ifndef __T7XX_PCI_RESCAN_H__ -#define __T7XX_PCI_RESCAN_H__ - -#define MTK_RESCAN_WQ "mtk_rescan_wq" - -#define DELAY_RESCAN_MTIME 1000 -#define RESCAN_RETRIES 35 - -struct remove_rescan_context { - struct work_struct service_task; - struct workqueue_struct *pcie_rescan_wq; - struct pci_dev *dev; - atomic_t rescan_done; -}; - -void t7xx_pci_dev_rescan(void); -void t7xx_rescan_queue_work(struct pci_dev *pdev); -int t7xx_rescan_init(void); -void t7xx_rescan_deinit(void); -void t7xx_rescan_done(void); - -#endif /* __T7XX_PCI_RESCAN_H__ */ -- GitLab From c693d0c2f5e84b8609a7e625d111603b76cce54f Mon Sep 17 00:00:00 2001 From: liuqf Date: Mon, 14 Oct 2024 09:09:01 +0000 Subject: [PATCH 291/456] Revert "FROMLIST: net: wwan: t7xx: Infrastructure for early port configuration" This reverts commit 7003fbb7bb8a2ec7530cc6fc66dd4297ad8aabe1. This patch don't upstream and will be replaced by upstream solution. BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Ie868ed82494cd583b486873868791d1b28f2dedf Signed-off-by: jack song Signed-off-by: liuqf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928756 Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_hif_cldma.c | 47 ++++-------- drivers/net/wwan/t7xx/t7xx_hif_cldma.h | 18 +---- drivers/net/wwan/t7xx/t7xx_modem_ops.c | 4 +- drivers/net/wwan/t7xx/t7xx_port.h | 4 - drivers/net/wwan/t7xx/t7xx_port_proxy.c | 89 +++------------------- drivers/net/wwan/t7xx/t7xx_port_proxy.h | 12 +-- drivers/net/wwan/t7xx/t7xx_reg.h | 24 +----- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 86 +++------------------ drivers/net/wwan/t7xx/t7xx_state_monitor.h | 1 - 9 files changed, 49 insertions(+), 236 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c index 97163e1e5783e..554ba4669cc8d 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c @@ -57,6 +57,8 @@ #define CHECK_Q_STOP_TIMEOUT_US 1000000 #define CHECK_Q_STOP_STEP_US 10000 +#define CLDMA_JUMBO_BUFF_SZ (63 * 1024 + sizeof(struct ccci_header)) + static void md_cd_queue_struct_reset(struct cldma_queue *queue, struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx, unsigned int index) { @@ -160,7 +162,7 @@ static int t7xx_cldma_gpd_rx_from_q(struct cldma_queue *queue, int budget, bool skb_reset_tail_pointer(skb); skb_put(skb, le16_to_cpu(gpd->data_buff_len)); - ret = queue->recv_skb(queue, skb); + ret = md_ctrl->recv_skb(queue, skb); /* Break processing, will try again later */ if (ret < 0) return ret; @@ -896,13 +898,13 @@ static void t7xx_cldma_hw_start_send(struct cldma_ctrl *md_ctrl, int qno, /** * t7xx_cldma_set_recv_skb() - Set the callback to handle RX packets. - * @queue: CLDMA queue. + * @md_ctrl: CLDMA context structure. * @recv_skb: Receiving skb callback. */ -void t7xx_cldma_set_recv_skb(struct cldma_queue *queue, +void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl, int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb)) { - queue->recv_skb = recv_skb; + md_ctrl->recv_skb = recv_skb; } /** @@ -992,28 +994,6 @@ allow_sleep: return ret; } -static void t7xx_cldma_adjust_config(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id) -{ - int qno; - - for (qno = 0; qno < CLDMA_RXQ_NUM; qno++) { - md_ctrl->rx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ; - t7xx_cldma_set_recv_skb(&md_ctrl->rxq[qno], t7xx_port_proxy_recv_skb); - } - - md_ctrl->rx_ring[CLDMA_RXQ_NUM - 1].pkt_size = CLDMA_JUMBO_BUFF_SZ; - - for (qno = 0; qno < CLDMA_TXQ_NUM; qno++) - md_ctrl->tx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ; - - if (cfg_id == CLDMA_DEDICATED_Q_CFG) { - md_ctrl->tx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ; - md_ctrl->rx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ; - t7xx_cldma_set_recv_skb(&md_ctrl->rxq[CLDMA_Q_IDX_DUMP], - t7xx_port_proxy_recv_skb_from_dedicated_queue); - } -} - static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl) { char dma_pool_name[32]; @@ -1039,9 +1019,16 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl) dev_err(md_ctrl->dev, "control TX ring init fail\n"); goto err_free_tx_ring; } + + md_ctrl->tx_ring[i].pkt_size = CLDMA_MTU; } for (j = 0; j < CLDMA_RXQ_NUM; j++) { + md_ctrl->rx_ring[j].pkt_size = CLDMA_MTU; + + if (j == CLDMA_RXQ_NUM - 1) + md_ctrl->rx_ring[j].pkt_size = CLDMA_JUMBO_BUFF_SZ; + ret = t7xx_cldma_rx_ring_init(md_ctrl, &md_ctrl->rx_ring[j]); if (ret) { dev_err(md_ctrl->dev, "Control RX ring init fail\n"); @@ -1108,7 +1095,6 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev) { struct device *dev = &t7xx_dev->pdev->dev; struct cldma_ctrl *md_ctrl; - int qno; md_ctrl = devm_kzalloc(dev, sizeof(*md_ctrl), GFP_KERNEL); if (!md_ctrl) @@ -1117,9 +1103,7 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev) md_ctrl->t7xx_dev = t7xx_dev; md_ctrl->dev = dev; md_ctrl->hif_id = hif_id; - for (qno = 0; qno < CLDMA_RXQ_NUM; qno++) - md_ctrl->rxq[qno].recv_skb = t7xx_cldma_default_recv_skb; - + md_ctrl->recv_skb = t7xx_cldma_default_recv_skb; t7xx_hw_info_init(md_ctrl); t7xx_dev->md->md_ctrl[hif_id] = md_ctrl; return 0; @@ -1349,10 +1333,9 @@ err_workqueue: return -ENOMEM; } -void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id) +void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl) { t7xx_cldma_late_release(md_ctrl); - t7xx_cldma_adjust_config(md_ctrl, cfg_id); t7xx_cldma_late_init(md_ctrl); } diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h index 8d2e3f00ca87e..4410bac6993ae 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h @@ -31,10 +31,6 @@ #include "t7xx_cldma.h" #include "t7xx_pci.h" -#define CLDMA_JUMBO_BUFF_SZ (63 * 1024 + sizeof(struct ccci_header)) -#define CLDMA_SHARED_Q_BUFF_SZ 3584 -#define CLDMA_DEDICATED_Q_BUFF_SZ 2048 - /** * enum cldma_id - Identifiers for CLDMA HW units. * @CLDMA_ID_MD: Modem control channel. @@ -59,11 +55,6 @@ struct cldma_gpd { __le16 not_used2; }; -enum cldma_cfg { - CLDMA_SHARED_Q_CFG, - CLDMA_DEDICATED_Q_CFG, -}; - struct cldma_request { struct cldma_gpd *gpd; /* Virtual address for CPU */ dma_addr_t gpd_addr; /* Physical address for DMA */ @@ -91,7 +82,6 @@ struct cldma_queue { wait_queue_head_t req_wq; /* Only for TX */ struct workqueue_struct *worker; struct work_struct cldma_work; - int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb); }; struct cldma_ctrl { @@ -111,24 +101,24 @@ struct cldma_ctrl { struct md_pm_entity *pm_entity; struct t7xx_cldma_hw hw_info; bool is_late_init; + int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb); }; -#define CLDMA_Q_IDX_DUMP 1 #define GPD_FLAGS_HWO BIT(0) #define GPD_FLAGS_IOC BIT(7) #define GPD_DMAPOOL_ALIGN 16 -#define CLDMA_MTU 3584 /* 3.5kB */ +#define CLDMA_MTU 3584 /* 3.5kB */ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev); void t7xx_cldma_hif_hw_init(struct cldma_ctrl *md_ctrl); int t7xx_cldma_init(struct cldma_ctrl *md_ctrl); void t7xx_cldma_exit(struct cldma_ctrl *md_ctrl); -void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id); +void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl); void t7xx_cldma_start(struct cldma_ctrl *md_ctrl); int t7xx_cldma_stop(struct cldma_ctrl *md_ctrl); void t7xx_cldma_reset(struct cldma_ctrl *md_ctrl); -void t7xx_cldma_set_recv_skb(struct cldma_queue *queue, +void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl, int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb)); int t7xx_cldma_send_skb(struct cldma_ctrl *md_ctrl, int qno, struct sk_buff *skb); void t7xx_cldma_stop_all_qs(struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx); diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index cbd65aa48721a..24e7d491468e0 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -529,7 +529,7 @@ static void t7xx_md_hk_wq(struct work_struct *work) /* Clear the HS2 EXIT event appended in core_reset() */ t7xx_fsm_clr_event(ctl, FSM_EVENT_MD_HS2_EXIT); - t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD], CLDMA_SHARED_Q_CFG); + t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD]); t7xx_cldma_start(md->md_ctrl[CLDMA_ID_MD]); t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_FOR_HS2); md->core_md.handshake_ongoing = true; @@ -544,7 +544,7 @@ static void t7xx_ap_hk_wq(struct work_struct *work) /* Clear the HS2 EXIT event appended in t7xx_core_reset(). */ t7xx_fsm_clr_event(ctl, FSM_EVENT_AP_HS2_EXIT); t7xx_cldma_stop(md->md_ctrl[CLDMA_ID_AP]); - t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP], CLDMA_SHARED_Q_CFG); + t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP]); t7xx_cldma_start(md->md_ctrl[CLDMA_ID_AP]); md->core_ap.handshake_ongoing = true; t7xx_core_hk_handler(md, &md->core_ap, ctl, FSM_EVENT_AP_HS2, FSM_EVENT_AP_HS2_EXIT); diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index 09acb1ef144db..4ae8a00a85322 100644 --- a/drivers/net/wwan/t7xx/t7xx_port.h +++ b/drivers/net/wwan/t7xx/t7xx_port.h @@ -75,8 +75,6 @@ enum port_ch { PORT_CH_DSS6_TX = 0x20df, PORT_CH_DSS7_RX = 0x20e0, PORT_CH_DSS7_TX = 0x20e1, - - PORT_CH_ID_UNIMPORTANT = 0xffff, }; struct t7xx_port; @@ -137,11 +135,9 @@ struct t7xx_port { }; }; -int t7xx_get_port_mtu(struct t7xx_port *port); struct sk_buff *t7xx_port_alloc_skb(int payload); struct sk_buff *t7xx_ctrl_alloc_skb(int payload); int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb); -int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb); int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header, unsigned int ex_msg); int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg, diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index b457e8da098e4..274846d39fbf3 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -100,18 +100,6 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { }, }; -static struct t7xx_port_conf t7xx_early_port_conf[] = { - { - .tx_ch = PORT_CH_ID_UNIMPORTANT, - .rx_ch = PORT_CH_ID_UNIMPORTANT, - .txq_index = CLDMA_Q_IDX_DUMP, - .rxq_index = CLDMA_Q_IDX_DUMP, - .txq_exp_index = CLDMA_Q_IDX_DUMP, - .rxq_exp_index = CLDMA_Q_IDX_DUMP, - .path_id = CLDMA_ID_AP, - }, -}; - static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch) { const struct t7xx_port_conf *port_conf; @@ -226,17 +214,7 @@ int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb) return 0; } -int t7xx_get_port_mtu(struct t7xx_port *port) -{ - enum cldma_id path_id = port->port_conf->path_id; - int tx_qno = t7xx_port_get_queue_no(port); - struct cldma_ctrl *md_ctrl; - - md_ctrl = port->t7xx_dev->md->md_ctrl[path_id]; - return md_ctrl->tx_ring[tx_qno].pkt_size; -} - -int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb) +static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb) { enum cldma_id path_id = port->port_conf->path_id; struct cldma_ctrl *md_ctrl; @@ -351,30 +329,6 @@ static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox) } } -int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb) -{ - struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev; - struct port_proxy *port_prox = t7xx_dev->md->port_prox; - const struct t7xx_port_conf *port_conf; - struct t7xx_port *port; - int ret; - - port = &port_prox->ports[0]; - if (WARN_ON(port->port_conf->rxq_index != queue->index)) { - dev_kfree_skb_any(skb); - return -EINVAL; - } - - port_conf = port->port_conf; - ret = port_conf->ops->recv_skb(port, skb); - if (ret < 0 && ret != -ENOBUFS) { - dev_err(port->dev, "drop on RX ch %d, %d\n", port_conf->rx_ch, ret); - dev_kfree_skb_any(skb); - } - - return ret; -} - static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev, struct cldma_queue *queue, u16 channel) { @@ -405,7 +359,7 @@ static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev ** 0 - Packet consumed. ** -ERROR - Failed to process skb. */ -int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb) +static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb) { struct ccci_header *ccci_h = (struct ccci_header *)skb->data; struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev; @@ -497,47 +451,26 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md) t7xx_proxy_setup_ch_mapping(port_prox); } -void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id) -{ - struct port_proxy *port_prox = md->port_prox; - const struct t7xx_port_conf *port_conf; - u32 port_count; - int i; - - t7xx_port_proxy_uninit(port_prox); - - if (cfg_id == PORT_CFG_ID_EARLY) { - port_conf = t7xx_early_port_conf; - port_count = ARRAY_SIZE(t7xx_early_port_conf); - } else { - port_conf = t7xx_port_conf; - port_count = ARRAY_SIZE(t7xx_port_conf); - } - - for (i = 0; i < port_count; i++) - port_prox->ports[i].port_conf = &port_conf[i]; - - port_prox->cfg_id = cfg_id; - port_prox->port_count = port_count; - t7xx_proxy_init_all_ports(md); -} - static int t7xx_proxy_alloc(struct t7xx_modem *md) { - u32 early_port_count = ARRAY_SIZE(t7xx_early_port_conf); unsigned int port_count = ARRAY_SIZE(t7xx_port_conf); struct device *dev = &md->t7xx_dev->pdev->dev; struct port_proxy *port_prox; + int i; - port_count = max_t(u32, port_count, early_port_count); - port_prox = devm_kzalloc(dev, struct_size(port_prox, ports, port_count), GFP_KERNEL); + port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * port_count, + GFP_KERNEL); if (!port_prox) return -ENOMEM; md->port_prox = port_prox; port_prox->dev = dev; - t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_EARLY); + for (i = 0; i < port_count; i++) + port_prox->ports[i].port_conf = &t7xx_port_conf[i]; + + port_prox->port_count = port_count; + t7xx_proxy_init_all_ports(md); return 0; } @@ -559,6 +492,8 @@ int t7xx_port_proxy_init(struct t7xx_modem *md) if (ret) return ret; + t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_AP], t7xx_port_proxy_recv_skb); + t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb); return 0; } diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h index 0f3fb53259b7a..81d059fbc0fb4 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h @@ -31,19 +31,12 @@ #define RX_QUEUE_MAXLEN 32 #define CTRL_QUEUE_MAXLEN 16 -enum port_cfg_id { - PORT_CFG_ID_INVALID, - PORT_CFG_ID_NORMAL, - PORT_CFG_ID_EARLY, -}; - struct port_proxy { int port_count; struct list_head rx_ch_ports[PORT_CH_ID_MASK + 1]; struct list_head queue_ports[CLDMA_NUM][MTK_QUEUES]; struct device *dev; - enum port_cfg_id cfg_id; - struct t7xx_port ports[]; + struct t7xx_port ports[]; }; struct ccci_header { @@ -105,8 +98,5 @@ void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg); int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id, bool en_flag); -void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id); -int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb); -int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb); #endif /* __T7XX_PORT_PROXY_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h index 44352cd024603..c41d7d094c085 100644 --- a/drivers/net/wwan/t7xx/t7xx_reg.h +++ b/drivers/net/wwan/t7xx/t7xx_reg.h @@ -102,28 +102,10 @@ enum t7xx_pm_resume_state { }; #define T7XX_PCIE_MISC_DEV_STATUS 0x0d1c -#define MISC_RESET_TYPE_FLDR BIT(27) -#define MISC_RESET_TYPE_PLDR BIT(26) -#define MISC_DEV_STATUS_MASK GENMASK(15, 0) -#define MISC_DEV_STATUS_INVALID GENMASK(15, 0) -#define MISC_LK_EVENT_MASK GENMASK(11, 8) - -enum lk_event_id { - LK_EVENT_NORMAL = 0, - LK_EVENT_CREATE_PD_PORT = 1, - LK_EVENT_CREATE_POST_DL_PORT = 2, - LK_EVENT_RESET = 7, -}; - #define MISC_STAGE_MASK GENMASK(2, 0) - -enum t7xx_device_stage { - T7XX_DEV_STAGE_INIT = 0, - T7XX_DEV_STAGE_BROM_PRE = 1, - T7XX_DEV_STAGE_BROM_POST = 2, - T7XX_DEV_STAGE_LK = 3, - T7XX_DEV_STAGE_LINUX = 4, -}; +#define MISC_RESET_TYPE_PLDR BIT(26) +#define MISC_RESET_TYPE_FLDR BIT(27) +#define LINUX_STAGE 4 #define T7XX_PCIE_RESOURCE_STATUS 0x0d28 #define T7XX_PCIE_RESOURCE_STS_MSK GENMASK(4, 0) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 65f487f4fffd3..64868df3640d1 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -213,34 +213,6 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm fsm_finish_command(ctl, cmd, 0); } -static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status) -{ - struct t7xx_modem *md = ctl->md; - struct cldma_ctrl *md_ctrl; - enum lk_event_id lk_event; - struct device *dev; - - dev = &md->t7xx_dev->pdev->dev; - lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status); - switch (lk_event) { - case LK_EVENT_NORMAL: - case LK_EVENT_RESET: - break; - - case LK_EVENT_CREATE_PD_PORT: - md_ctrl = md->md_ctrl[CLDMA_ID_AP]; - t7xx_cldma_hif_hw_init(md_ctrl); - t7xx_cldma_stop(md_ctrl); - t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG); - t7xx_cldma_start(md_ctrl); - break; - - default: - dev_err(dev, "Invalid LK event %d\n", lk_event); - break; - } -} - static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl) { ctl->curr_state = FSM_STATE_STOPPED; @@ -352,9 +324,8 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl) static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd) { struct t7xx_modem *md = ctl->md; - struct device *dev; - u32 status, stage; - int ret = 0; + u32 dev_status; + int ret; if (!md) return; @@ -365,55 +336,23 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command return; } - dev = &md->t7xx_dev->pdev->dev; ctl->curr_state = FSM_STATE_PRE_START; t7xx_md_event_notify(md, FSM_PRE_START); - ret = read_poll_timeout(ioread32, status, - ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LINUX) || - ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LK), 100000, - 20000000, false, IREG_BASE(md->t7xx_dev) + - T7XX_PCIE_MISC_DEV_STATUS); - + ret = read_poll_timeout(ioread32, dev_status, + (dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 2000000, + false, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); if (ret) { - ret = -ETIMEDOUT; - dev_err(dev, "read poll %d\n", ret); - goto finish_command; - } - - if (status != ctl->prev_status) { - stage = FIELD_GET(MISC_STAGE_MASK, status); - switch (stage) { - case T7XX_DEV_STAGE_INIT: - case T7XX_DEV_STAGE_BROM_PRE: - case T7XX_DEV_STAGE_BROM_POST: - dev_info(dev, "BROM_STAGE Entered\n"); - ret = t7xx_fsm_append_cmd(ctl, FSM_CMD_START, 0); - break; + struct device *dev = &md->t7xx_dev->pdev->dev; - case T7XX_DEV_STAGE_LK: - dev_info(dev, "LK_STAGE Entered\n"); - t7xx_lk_stage_event_handling(ctl, status); - break; - - case T7XX_DEV_STAGE_LINUX: - dev_info(dev, "LINUX_STAGE Entered\n"); - t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]); - t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]); - t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM | - D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK); - t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL); - ret = fsm_routine_starting(ctl); - break; - - default: - break; - } - ctl->prev_status = status; + fsm_finish_command(ctl, cmd, -ETIMEDOUT); + dev_err(dev, "Invalid device status 0x%lx\n", dev_status & MISC_STAGE_MASK); + return; } -finish_command: - fsm_finish_command(ctl, cmd, ret); + t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]); + t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]); + fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl)); } static int fsm_main_thread(void *data) @@ -585,7 +524,6 @@ void t7xx_fsm_reset(struct t7xx_modem *md) fsm_flush_event_cmd_qs(ctl); ctl->curr_state = FSM_STATE_STOPPED; ctl->exp_flg = false; - ctl->prev_status = 0; } int t7xx_fsm_init(struct t7xx_modem *md) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h index 295108b109e32..74f96fd2605e8 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h @@ -96,7 +96,6 @@ struct t7xx_fsm_ctl { bool exp_flg; spinlock_t notifier_lock; /* Protects notifier list */ struct list_head notifier_list; - u32 prev_status; }; struct t7xx_fsm_event { -- GitLab From e43772b0d0389432ddee2847f93f095ee629e150 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 9 Oct 2023 15:46:18 -0600 Subject: [PATCH 292/456] UPSTREAM: net: wwan: t7xx: Add __counted_by for struct t7xx_fsm_event and use struct_size() Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). While there, use struct_size() helper, instead of the open-coded version, to calculate the size for the allocation of the whole flexible structure, including of course, the flexible-array member. This code was found with the help of Coccinelle, and audited and fixed manually. Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kees Cook Signed-off-by: David S. Miller (cherry picked from commit 2dd3071892202ccaec3c59afc65c5b88357e73c9) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I101514400e4e5f95cfcfe5ef15fee4c2af03b81d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928757 Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Reviewed-by: Sean Paul Tested-by: Daniel Winkler Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 3 ++- drivers/net/wwan/t7xx/t7xx_state_monitor.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 64868df3640d1..f0d8f1b386095 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -453,7 +453,8 @@ int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state ev return -EINVAL; } - event = kmalloc(sizeof(*event) + length, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + event = kmalloc(struct_size(event, data, length), + in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!event) return -ENOMEM; diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h index 74f96fd2605e8..c2cfaca07b207 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h @@ -102,7 +102,7 @@ struct t7xx_fsm_event { struct list_head entry; enum t7xx_fsm_event_state event_id; unsigned int length; - unsigned char data[]; + unsigned char data[] __counted_by(length); }; struct t7xx_fsm_command { -- GitLab From 430cbd1ac83b9fc4baab2fc570a34ce48cee6426 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 5 Feb 2024 18:22:27 +0800 Subject: [PATCH 293/456] UPSTREAM: wwan: core: Add WWAN fastboot port type Add a new WWAN port that connects to the device fastboot protocol interface. Signed-off-by: Jinjian Song Signed-off-by: David S. Miller (cherry picked from commit e3caf184107a4e2e196528b98b218ddc41e4cb8c) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I565cb56217ab0df54680e303c0706f7ceca8995e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928758 Tested-by: Daniel Winkler Reviewed-by: Sean Paul Reviewed-by: Ujjwal Pande Reviewed-by: Daniel Winkler Commit-Queue: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/wwan_core.c | 4 ++++ include/linux/wwan.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index 45ed3afc443df..4e6709bb6a867 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -327,6 +327,10 @@ static const struct { .name = "XMMRPC", .devsuf = "xmmrpc", }, + [WWAN_PORT_FASTBOOT] = { + .name = "FASTBOOT", + .devsuf = "fastboot", + }, }; static ssize_t type_show(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/wwan.h b/include/linux/wwan.h index cc66bd98c8a1e..2b1280308259e 100644 --- a/include/linux/wwan.h +++ b/include/linux/wwan.h @@ -17,6 +17,7 @@ * @WWAN_PORT_QCDM: Qcom Modem diagnostic interface * @WWAN_PORT_FIREHOSE: XML based command protocol * @WWAN_PORT_XMMRPC: Control protocol for Intel XMM modems + * @WWAN_PORT_FASTBOOT: Fastboot protocol control * * @WWAN_PORT_MAX: Highest supported port types * @WWAN_PORT_UNKNOWN: Special value to indicate an unknown port type @@ -29,6 +30,7 @@ enum wwan_port_type { WWAN_PORT_QCDM, WWAN_PORT_FIREHOSE, WWAN_PORT_XMMRPC, + WWAN_PORT_FASTBOOT, /* Add new port types above this line */ -- GitLab From e5192a2b1a8154ef1c3e4fc6573fd6e63fab9f09 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 5 Feb 2024 18:22:28 +0800 Subject: [PATCH 294/456] UPSTREAM: net: wwan: t7xx: Add sysfs attribute for device state machine Add support for userspace to get/set the device mode, device's state machine changes between (unknown/ready/reset/fastboot). Get the device state mode: - 'cat /sys/bus/pci/devices/${bdf}/t7xx_mode' Set the device state mode: - reset(cold reset): 'echo reset > /sys/bus/pci/devices/${bdf}/t7xx_mode' - fastboot: 'echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode' Reload driver to get the new device state after setting operation. Signed-off-by: Jinjian Song Signed-off-by: David S. Miller (cherry picked from commit 409c38d4f156740bf3165fd6ceae4fa6425eebf4) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Ic9fcf1c9fb313461ad9a38112771d3551fbdb260 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928759 Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Reviewed-by: Sean Paul Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- .../networking/device_drivers/wwan/t7xx.rst | 28 +++++ drivers/net/wwan/t7xx/t7xx_modem_ops.c | 6 ++ drivers/net/wwan/t7xx/t7xx_modem_ops.h | 1 + drivers/net/wwan/t7xx/t7xx_pci.c | 101 +++++++++++++++++- drivers/net/wwan/t7xx/t7xx_pci.h | 14 ++- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 1 + 6 files changed, 145 insertions(+), 6 deletions(-) diff --git a/Documentation/networking/device_drivers/wwan/t7xx.rst b/Documentation/networking/device_drivers/wwan/t7xx.rst index dd5b731957ca4..8429b99273417 100644 --- a/Documentation/networking/device_drivers/wwan/t7xx.rst +++ b/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -39,6 +39,34 @@ command and receive response: - open the AT control channel using a UART tool or a special user tool +Sysfs +===== +The driver provides sysfs interfaces to userspace. + +t7xx_mode +--------- +The sysfs interface provides userspace with access to the device mode, this interface +supports read and write operations. + +Device mode: + +- ``unknown`` represents that device in unknown status +- ``ready`` represents that device in ready status +- ``reset`` represents that device in reset status +- ``fastboot_switching`` represents that device in fastboot switching status +- ``fastboot_download`` represents that device in fastboot download status +- ``fastboot_dump`` represents that device in fastboot dump status + +Read from userspace to get the current device mode. + +:: + $ cat /sys/bus/pci/devices/${bdf}/t7xx_mode + +Write from userspace to set the device mode. + +:: + $ echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode + Management application development ================================== The driver and userspace interfaces are described below. The MBIM protocol is diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 24e7d491468e0..ca262d2961ed7 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -177,6 +177,11 @@ int t7xx_acpi_fldr_func(struct t7xx_pci_dev *t7xx_dev) return t7xx_acpi_reset(t7xx_dev, "_RST"); } +int t7xx_acpi_pldr_func(struct t7xx_pci_dev *t7xx_dev) +{ + return t7xx_acpi_reset(t7xx_dev, "MRST._RST"); +} + static void t7xx_reset_device_via_pmic(struct t7xx_pci_dev *t7xx_dev) { u32 val; @@ -192,6 +197,7 @@ static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data) { struct t7xx_pci_dev *t7xx_dev = data; + t7xx_mode_update(t7xx_dev, T7XX_RESET); msleep(RGU_RESET_DELAY_MS); t7xx_reset_device_via_pmic(t7xx_dev); return IRQ_HANDLED; diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.h b/drivers/net/wwan/t7xx/t7xx_modem_ops.h index abe633cf7adc0..b39e945a92e01 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.h +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.h @@ -85,6 +85,7 @@ int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev); void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev); void t7xx_clear_rgu_irq(struct t7xx_pci_dev *t7xx_dev); int t7xx_acpi_fldr_func(struct t7xx_pci_dev *t7xx_dev); +int t7xx_acpi_pldr_func(struct t7xx_pci_dev *t7xx_dev); int t7xx_pci_mhccif_isr(struct t7xx_pci_dev *t7xx_dev); #endif /* __T7XX_MODEM_OPS_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 91256e005b846..f99eb21cb8ccb 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -52,6 +52,81 @@ #define PM_RESOURCE_POLL_TIMEOUT_US 10000 #define PM_RESOURCE_POLL_STEP_US 100 +static const char * const t7xx_mode_names[] = { + [T7XX_UNKNOWN] = "unknown", + [T7XX_READY] = "ready", + [T7XX_RESET] = "reset", + [T7XX_FASTBOOT_SWITCHING] = "fastboot_switching", + [T7XX_FASTBOOT_DOWNLOAD] = "fastboot_download", + [T7XX_FASTBOOT_DUMP] = "fastboot_dump", +}; + +static_assert(ARRAY_SIZE(t7xx_mode_names) == T7XX_MODE_LAST); + +static ssize_t t7xx_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + int index = 0; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + index = sysfs_match_string(t7xx_mode_names, buf); + if (index == T7XX_FASTBOOT_SWITCHING) { + WRITE_ONCE(t7xx_dev->mode, T7XX_FASTBOOT_SWITCHING); + } else if (index == T7XX_RESET) { + WRITE_ONCE(t7xx_dev->mode, T7XX_RESET); + t7xx_acpi_pldr_func(t7xx_dev); + } + + return count; +}; + +static ssize_t t7xx_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + enum t7xx_mode mode = T7XX_UNKNOWN; + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + mode = READ_ONCE(t7xx_dev->mode); + if (mode < T7XX_MODE_LAST) + return sysfs_emit(buf, "%s\n", t7xx_mode_names[mode]); + + return sysfs_emit(buf, "%s\n", t7xx_mode_names[T7XX_UNKNOWN]); +} + +static DEVICE_ATTR_RW(t7xx_mode); + +static struct attribute *t7xx_mode_attr[] = { + &dev_attr_t7xx_mode.attr, + NULL +}; + +static const struct attribute_group t7xx_mode_attribute_group = { + .attrs = t7xx_mode_attr, +}; + +void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode) +{ + if (!t7xx_dev) + return; + + WRITE_ONCE(t7xx_dev->mode, mode); + sysfs_notify(&t7xx_dev->pdev->dev.kobj, NULL, "t7xx_mode"); +} + enum t7xx_pm_state { MTK_PM_EXCEPTION, MTK_PM_INIT, /* Device initialized, but handshake not completed */ @@ -279,7 +354,8 @@ static int __t7xx_pci_pm_suspend(struct pci_dev *pdev) int ret; t7xx_dev = pci_get_drvdata(pdev); - if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT) { + if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT || + READ_ONCE(t7xx_dev->mode) != T7XX_READY) { dev_err(&pdev->dev, "[PM] Exiting suspend, modem in invalid state\n"); return -EFAULT; } @@ -729,16 +805,28 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pcie_mac_interrupts_dis(t7xx_dev); + ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj, + &t7xx_mode_attribute_group); + if (ret) + goto err_md_exit; + ret = t7xx_interrupt_init(t7xx_dev); - if (ret) { - t7xx_md_exit(t7xx_dev); - return ret; - } + if (ret) + goto err_remove_group; + t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT); t7xx_pcie_mac_interrupts_en(t7xx_dev); return 0; + +err_remove_group: + sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, + &t7xx_mode_attribute_group); + +err_md_exit: + t7xx_md_exit(t7xx_dev); + return ret; } static void t7xx_pci_remove(struct pci_dev *pdev) @@ -747,6 +835,9 @@ static void t7xx_pci_remove(struct pci_dev *pdev) int i; t7xx_dev = pci_get_drvdata(pdev); + + sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, + &t7xx_mode_attribute_group); t7xx_md_exit(t7xx_dev); for (i = 0; i < EXT_INT_NUM; i++) { diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index f08f1ab744691..49a11586d8d84 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.h +++ b/drivers/net/wwan/t7xx/t7xx_pci.h @@ -43,6 +43,16 @@ struct t7xx_addr_base { typedef irqreturn_t (*t7xx_intr_callback)(int irq, void *param); +enum t7xx_mode { + T7XX_UNKNOWN, + T7XX_READY, + T7XX_RESET, + T7XX_FASTBOOT_SWITCHING, + T7XX_FASTBOOT_DOWNLOAD, + T7XX_FASTBOOT_DUMP, + T7XX_MODE_LAST, /* must always be last */ +}; + /* struct t7xx_pci_dev - MTK device context structure * @intr_handler: array of handler function for request_threaded_irq * @intr_thread: array of thread_fn for request_threaded_irq @@ -59,6 +69,7 @@ typedef irqreturn_t (*t7xx_intr_callback)(int irq, void *param); * @md_pm_lock: protects PCIe sleep lock * @sleep_disable_count: PCIe L1.2 lock counter * @sleep_lock_acquire: indicates that sleep has been disabled + * @mode: indicates the device mode */ struct t7xx_pci_dev { t7xx_intr_callback intr_handler[EXT_INT_NUM]; @@ -82,6 +93,7 @@ struct t7xx_pci_dev { #ifdef CONFIG_WWAN_DEBUGFS struct dentry *debugfs_dir; #endif + u32 mode; }; enum t7xx_pm_id { @@ -120,5 +132,5 @@ int t7xx_pci_pm_entity_register(struct t7xx_pci_dev *t7xx_dev, struct md_pm_enti int t7xx_pci_pm_entity_unregister(struct t7xx_pci_dev *t7xx_dev, struct md_pm_entity *pm_entity); void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev); void t7xx_pci_pm_exp_detected(struct t7xx_pci_dev *t7xx_dev); - +void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode); #endif /* __T7XX_PCI_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index f0d8f1b386095..3691ca8450814 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -279,6 +279,7 @@ static void fsm_routine_ready(struct t7xx_fsm_ctl *ctl) ctl->curr_state = FSM_STATE_READY; t7xx_fsm_broadcast_ready_state(ctl); + t7xx_mode_update(md->t7xx_dev, T7XX_READY); t7xx_md_event_notify(md, FSM_READY); } -- GitLab From 98b764efd4b4cc7e1f549726523c2881a27de434 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 5 Feb 2024 18:22:29 +0800 Subject: [PATCH 295/456] UPSTREAM: net: wwan: t7xx: Infrastructure for early port configuration To support cases such as FW update or Core dump, the t7xx device is capable of signaling the host that a special port needs to be created before the handshake phase. Adds the infrastructure required to create the early ports which also requires a different configuration of CLDMA queues. Base on the v5 patch version of follow series: 'net: wwan: t7xx: fw flashing & coredump support' (https://patchwork.kernel.org/project/netdevbpf/patch/3777bb382f4b0395cb594a602c5c79dbab86c9e0.1674307425.git.m.chetan.kumar@linux.intel.com/) Signed-off-by: Jinjian Song Signed-off-by: David S. Miller (cherry picked from commit d27553c14f06f4db61cb9ddaf88e8d4df91d740c) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I13b255f29cb585c402fd8ff6f2071854ce1f5f2e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928760 Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Sean Paul Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_hif_cldma.c | 47 +++++--- drivers/net/wwan/t7xx/t7xx_hif_cldma.h | 18 ++- drivers/net/wwan/t7xx/t7xx_modem_ops.c | 8 +- drivers/net/wwan/t7xx/t7xx_pci.c | 2 +- drivers/net/wwan/t7xx/t7xx_port.h | 4 + drivers/net/wwan/t7xx/t7xx_port_proxy.c | 105 ++++++++++++++--- drivers/net/wwan/t7xx/t7xx_port_proxy.h | 10 ++ drivers/net/wwan/t7xx/t7xx_port_wwan.c | 5 +- drivers/net/wwan/t7xx/t7xx_reg.h | 24 +++- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 127 +++++++++++++++++---- drivers/net/wwan/t7xx/t7xx_state_monitor.h | 1 + 11 files changed, 290 insertions(+), 61 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c index 554ba4669cc8d..97163e1e5783e 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c @@ -57,8 +57,6 @@ #define CHECK_Q_STOP_TIMEOUT_US 1000000 #define CHECK_Q_STOP_STEP_US 10000 -#define CLDMA_JUMBO_BUFF_SZ (63 * 1024 + sizeof(struct ccci_header)) - static void md_cd_queue_struct_reset(struct cldma_queue *queue, struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx, unsigned int index) { @@ -162,7 +160,7 @@ static int t7xx_cldma_gpd_rx_from_q(struct cldma_queue *queue, int budget, bool skb_reset_tail_pointer(skb); skb_put(skb, le16_to_cpu(gpd->data_buff_len)); - ret = md_ctrl->recv_skb(queue, skb); + ret = queue->recv_skb(queue, skb); /* Break processing, will try again later */ if (ret < 0) return ret; @@ -898,13 +896,13 @@ static void t7xx_cldma_hw_start_send(struct cldma_ctrl *md_ctrl, int qno, /** * t7xx_cldma_set_recv_skb() - Set the callback to handle RX packets. - * @md_ctrl: CLDMA context structure. + * @queue: CLDMA queue. * @recv_skb: Receiving skb callback. */ -void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl, +void t7xx_cldma_set_recv_skb(struct cldma_queue *queue, int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb)) { - md_ctrl->recv_skb = recv_skb; + queue->recv_skb = recv_skb; } /** @@ -994,6 +992,28 @@ allow_sleep: return ret; } +static void t7xx_cldma_adjust_config(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id) +{ + int qno; + + for (qno = 0; qno < CLDMA_RXQ_NUM; qno++) { + md_ctrl->rx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ; + t7xx_cldma_set_recv_skb(&md_ctrl->rxq[qno], t7xx_port_proxy_recv_skb); + } + + md_ctrl->rx_ring[CLDMA_RXQ_NUM - 1].pkt_size = CLDMA_JUMBO_BUFF_SZ; + + for (qno = 0; qno < CLDMA_TXQ_NUM; qno++) + md_ctrl->tx_ring[qno].pkt_size = CLDMA_SHARED_Q_BUFF_SZ; + + if (cfg_id == CLDMA_DEDICATED_Q_CFG) { + md_ctrl->tx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ; + md_ctrl->rx_ring[CLDMA_Q_IDX_DUMP].pkt_size = CLDMA_DEDICATED_Q_BUFF_SZ; + t7xx_cldma_set_recv_skb(&md_ctrl->rxq[CLDMA_Q_IDX_DUMP], + t7xx_port_proxy_recv_skb_from_dedicated_queue); + } +} + static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl) { char dma_pool_name[32]; @@ -1019,16 +1039,9 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl) dev_err(md_ctrl->dev, "control TX ring init fail\n"); goto err_free_tx_ring; } - - md_ctrl->tx_ring[i].pkt_size = CLDMA_MTU; } for (j = 0; j < CLDMA_RXQ_NUM; j++) { - md_ctrl->rx_ring[j].pkt_size = CLDMA_MTU; - - if (j == CLDMA_RXQ_NUM - 1) - md_ctrl->rx_ring[j].pkt_size = CLDMA_JUMBO_BUFF_SZ; - ret = t7xx_cldma_rx_ring_init(md_ctrl, &md_ctrl->rx_ring[j]); if (ret) { dev_err(md_ctrl->dev, "Control RX ring init fail\n"); @@ -1095,6 +1108,7 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev) { struct device *dev = &t7xx_dev->pdev->dev; struct cldma_ctrl *md_ctrl; + int qno; md_ctrl = devm_kzalloc(dev, sizeof(*md_ctrl), GFP_KERNEL); if (!md_ctrl) @@ -1103,7 +1117,9 @@ int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev) md_ctrl->t7xx_dev = t7xx_dev; md_ctrl->dev = dev; md_ctrl->hif_id = hif_id; - md_ctrl->recv_skb = t7xx_cldma_default_recv_skb; + for (qno = 0; qno < CLDMA_RXQ_NUM; qno++) + md_ctrl->rxq[qno].recv_skb = t7xx_cldma_default_recv_skb; + t7xx_hw_info_init(md_ctrl); t7xx_dev->md->md_ctrl[hif_id] = md_ctrl; return 0; @@ -1333,9 +1349,10 @@ err_workqueue: return -ENOMEM; } -void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl) +void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id) { t7xx_cldma_late_release(md_ctrl); + t7xx_cldma_adjust_config(md_ctrl, cfg_id); t7xx_cldma_late_init(md_ctrl); } diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h index 4410bac6993ae..f2d9941be9c83 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.h +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.h @@ -31,6 +31,10 @@ #include "t7xx_cldma.h" #include "t7xx_pci.h" +#define CLDMA_JUMBO_BUFF_SZ (63 * 1024 + sizeof(struct ccci_header)) +#define CLDMA_SHARED_Q_BUFF_SZ 3584 +#define CLDMA_DEDICATED_Q_BUFF_SZ 2048 + /** * enum cldma_id - Identifiers for CLDMA HW units. * @CLDMA_ID_MD: Modem control channel. @@ -55,6 +59,11 @@ struct cldma_gpd { __le16 not_used2; }; +enum cldma_cfg { + CLDMA_SHARED_Q_CFG, + CLDMA_DEDICATED_Q_CFG, +}; + struct cldma_request { struct cldma_gpd *gpd; /* Virtual address for CPU */ dma_addr_t gpd_addr; /* Physical address for DMA */ @@ -82,6 +91,7 @@ struct cldma_queue { wait_queue_head_t req_wq; /* Only for TX */ struct workqueue_struct *worker; struct work_struct cldma_work; + int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb); }; struct cldma_ctrl { @@ -101,24 +111,22 @@ struct cldma_ctrl { struct md_pm_entity *pm_entity; struct t7xx_cldma_hw hw_info; bool is_late_init; - int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb); }; +#define CLDMA_Q_IDX_DUMP 1 #define GPD_FLAGS_HWO BIT(0) #define GPD_FLAGS_IOC BIT(7) #define GPD_DMAPOOL_ALIGN 16 -#define CLDMA_MTU 3584 /* 3.5kB */ - int t7xx_cldma_alloc(enum cldma_id hif_id, struct t7xx_pci_dev *t7xx_dev); void t7xx_cldma_hif_hw_init(struct cldma_ctrl *md_ctrl); int t7xx_cldma_init(struct cldma_ctrl *md_ctrl); void t7xx_cldma_exit(struct cldma_ctrl *md_ctrl); -void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl); +void t7xx_cldma_switch_cfg(struct cldma_ctrl *md_ctrl, enum cldma_cfg cfg_id); void t7xx_cldma_start(struct cldma_ctrl *md_ctrl); int t7xx_cldma_stop(struct cldma_ctrl *md_ctrl); void t7xx_cldma_reset(struct cldma_ctrl *md_ctrl); -void t7xx_cldma_set_recv_skb(struct cldma_ctrl *md_ctrl, +void t7xx_cldma_set_recv_skb(struct cldma_queue *queue, int (*recv_skb)(struct cldma_queue *queue, struct sk_buff *skb)); int t7xx_cldma_send_skb(struct cldma_ctrl *md_ctrl, int qno, struct sk_buff *skb); void t7xx_cldma_stop_all_qs(struct cldma_ctrl *md_ctrl, enum mtk_txrx tx_rx); diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index ca262d2961ed7..8d864d4ed77f5 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -535,7 +535,7 @@ static void t7xx_md_hk_wq(struct work_struct *work) /* Clear the HS2 EXIT event appended in core_reset() */ t7xx_fsm_clr_event(ctl, FSM_EVENT_MD_HS2_EXIT); - t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD]); + t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_MD], CLDMA_SHARED_Q_CFG); t7xx_cldma_start(md->md_ctrl[CLDMA_ID_MD]); t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_FOR_HS2); md->core_md.handshake_ongoing = true; @@ -550,7 +550,7 @@ static void t7xx_ap_hk_wq(struct work_struct *work) /* Clear the HS2 EXIT event appended in t7xx_core_reset(). */ t7xx_fsm_clr_event(ctl, FSM_EVENT_AP_HS2_EXIT); t7xx_cldma_stop(md->md_ctrl[CLDMA_ID_AP]); - t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP]); + t7xx_cldma_switch_cfg(md->md_ctrl[CLDMA_ID_AP], CLDMA_SHARED_Q_CFG); t7xx_cldma_start(md->md_ctrl[CLDMA_ID_AP]); md->core_ap.handshake_ongoing = true; t7xx_core_hk_handler(md, &md->core_ap, ctl, FSM_EVENT_AP_HS2, FSM_EVENT_AP_HS2_EXIT); @@ -764,6 +764,7 @@ err_destroy_hswq: void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev) { + enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode); struct t7xx_modem *md = t7xx_dev->md; t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT); @@ -771,7 +772,8 @@ void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev) if (!md->md_init_finish) return; - t7xx_fsm_append_cmd(md->fsm_ctl, FSM_CMD_PRE_STOP, FSM_CMD_FLAG_WAIT_FOR_COMPLETION); + if (mode != T7XX_RESET && mode != T7XX_UNKNOWN) + t7xx_fsm_append_cmd(md->fsm_ctl, FSM_CMD_PRE_STOP, FSM_CMD_FLAG_WAIT_FOR_COMPLETION); t7xx_port_proxy_uninit(md->port_prox); t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_AP]); t7xx_cldma_exit(md->md_ctrl[CLDMA_ID_MD]); diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index f99eb21cb8ccb..e0b1e7a616cae 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -183,7 +183,7 @@ static int t7xx_pci_pm_init(struct t7xx_pci_dev *t7xx_dev) pm_runtime_set_autosuspend_delay(&pdev->dev, PM_AUTOSUSPEND_MS); pm_runtime_use_autosuspend(&pdev->dev); - return t7xx_wait_pm_config(t7xx_dev); + return 0; } void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev) diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index 4ae8a00a85322..f74d3bab810d8 100644 --- a/drivers/net/wwan/t7xx/t7xx_port.h +++ b/drivers/net/wwan/t7xx/t7xx_port.h @@ -75,6 +75,8 @@ enum port_ch { PORT_CH_DSS6_TX = 0x20df, PORT_CH_DSS7_RX = 0x20e0, PORT_CH_DSS7_TX = 0x20e1, + + PORT_CH_UNIMPORTANT = 0xffff, }; struct t7xx_port; @@ -135,11 +137,13 @@ struct t7xx_port { }; }; +int t7xx_get_port_mtu(struct t7xx_port *port); struct sk_buff *t7xx_port_alloc_skb(int payload); struct sk_buff *t7xx_ctrl_alloc_skb(int payload); int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb); int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header, unsigned int ex_msg); +int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb); int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg, unsigned int ex_msg); diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 274846d39fbf3..e53a152faee40 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -48,6 +48,9 @@ i < (proxy)->port_count; \ i++, (p) = &(proxy)->ports[i]) +#define T7XX_MAX_POSSIBLE_PORTS_NUM \ + (max(ARRAY_SIZE(t7xx_port_conf), ARRAY_SIZE(t7xx_early_port_conf))) + static const struct t7xx_port_conf t7xx_port_conf[] = { { .tx_ch = PORT_CH_UART2_TX, @@ -100,6 +103,18 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { }, }; +static const struct t7xx_port_conf t7xx_early_port_conf[] = { + { + .tx_ch = PORT_CH_UNIMPORTANT, + .rx_ch = PORT_CH_UNIMPORTANT, + .txq_index = CLDMA_Q_IDX_DUMP, + .rxq_index = CLDMA_Q_IDX_DUMP, + .txq_exp_index = CLDMA_Q_IDX_DUMP, + .rxq_exp_index = CLDMA_Q_IDX_DUMP, + .path_id = CLDMA_ID_AP, + }, +}; + static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch) { const struct t7xx_port_conf *port_conf; @@ -214,7 +229,17 @@ int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb) return 0; } -static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb) +int t7xx_get_port_mtu(struct t7xx_port *port) +{ + enum cldma_id path_id = port->port_conf->path_id; + int tx_qno = t7xx_port_get_queue_no(port); + struct cldma_ctrl *md_ctrl; + + md_ctrl = port->t7xx_dev->md->md_ctrl[path_id]; + return md_ctrl->tx_ring[tx_qno].pkt_size; +} + +int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb) { enum cldma_id path_id = port->port_conf->path_id; struct cldma_ctrl *md_ctrl; @@ -329,6 +354,39 @@ static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox) } } +/** + * t7xx_port_proxy_recv_skb_from_dedicated_queue() - Dispatch early port received skb. + * @queue: CLDMA queue. + * @skb: Socket buffer. + * + * Return: + ** 0 - Packet consumed. + ** -ERROR - Failed to process skb. + */ +int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb) +{ + struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev; + struct port_proxy *port_prox = t7xx_dev->md->port_prox; + const struct t7xx_port_conf *port_conf; + struct t7xx_port *port; + int ret; + + port = &port_prox->ports[0]; + if (WARN_ON_ONCE(port->port_conf->rxq_index != queue->index)) { + dev_kfree_skb_any(skb); + return -EINVAL; + } + + port_conf = port->port_conf; + ret = port_conf->ops->recv_skb(port, skb); + if (ret < 0 && ret != -ENOBUFS) { + dev_err(port->dev, "drop on RX ch %d, %d\n", port_conf->rx_ch, ret); + dev_kfree_skb_any(skb); + } + + return ret; +} + static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev, struct cldma_queue *queue, u16 channel) { @@ -359,7 +417,7 @@ static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev ** 0 - Packet consumed. ** -ERROR - Failed to process skb. */ -static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb) +int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb) { struct ccci_header *ccci_h = (struct ccci_header *)skb->data; struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev; @@ -444,33 +502,54 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md) spin_lock_init(&port->port_update_lock); port->chan_enable = false; - if (port_conf->ops->init) + if (port_conf->ops && port_conf->ops->init) port_conf->ops->init(port); } t7xx_proxy_setup_ch_mapping(port_prox); } +void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id) +{ + struct port_proxy *port_prox = md->port_prox; + const struct t7xx_port_conf *port_conf; + u32 port_count; + int i; + + t7xx_port_proxy_uninit(port_prox); + + if (cfg_id == PORT_CFG_ID_EARLY) { + port_conf = t7xx_early_port_conf; + port_count = ARRAY_SIZE(t7xx_early_port_conf); + } else { + port_conf = t7xx_port_conf; + port_count = ARRAY_SIZE(t7xx_port_conf); + } + + for (i = 0; i < port_count; i++) + port_prox->ports[i].port_conf = &port_conf[i]; + + port_prox->cfg_id = cfg_id; + port_prox->port_count = port_count; + + t7xx_proxy_init_all_ports(md); +} + static int t7xx_proxy_alloc(struct t7xx_modem *md) { - unsigned int port_count = ARRAY_SIZE(t7xx_port_conf); struct device *dev = &md->t7xx_dev->pdev->dev; struct port_proxy *port_prox; - int i; - port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * port_count, + port_prox = devm_kzalloc(dev, sizeof(*port_prox) + + sizeof(struct t7xx_port) * T7XX_MAX_POSSIBLE_PORTS_NUM, GFP_KERNEL); if (!port_prox) return -ENOMEM; md->port_prox = port_prox; port_prox->dev = dev; + t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_EARLY); - for (i = 0; i < port_count; i++) - port_prox->ports[i].port_conf = &t7xx_port_conf[i]; - - port_prox->port_count = port_count; - t7xx_proxy_init_all_ports(md); return 0; } @@ -492,8 +571,6 @@ int t7xx_port_proxy_init(struct t7xx_modem *md) if (ret) return ret; - t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_AP], t7xx_port_proxy_recv_skb); - t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb); return 0; } @@ -505,7 +582,7 @@ void t7xx_port_proxy_uninit(struct port_proxy *port_prox) for_each_proxy_port(i, port, port_prox) { const struct t7xx_port_conf *port_conf = port->port_conf; - if (port_conf->ops->uninit) + if (port_conf->ops && port_conf->ops->uninit) port_conf->ops->uninit(port); } } diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h index 81d059fbc0fb4..7f5706811445b 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h @@ -31,11 +31,18 @@ #define RX_QUEUE_MAXLEN 32 #define CTRL_QUEUE_MAXLEN 16 +enum port_cfg_id { + PORT_CFG_ID_INVALID, + PORT_CFG_ID_NORMAL, + PORT_CFG_ID_EARLY, +}; + struct port_proxy { int port_count; struct list_head rx_ch_ports[PORT_CH_ID_MASK + 1]; struct list_head queue_ports[CLDMA_NUM][MTK_QUEUES]; struct device *dev; + enum port_cfg_id cfg_id; struct t7xx_port ports[]; }; @@ -98,5 +105,8 @@ void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg); int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id, bool en_flag); +void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id); +int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb); +int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb); #endif /* __T7XX_PORT_PROXY_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c index 17389c8f6600a..ddc20ddfa7347 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c +++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c @@ -152,14 +152,15 @@ static int t7xx_port_wwan_disable_chl(struct t7xx_port *port) static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int state) { const struct t7xx_port_conf *port_conf = port->port_conf; - unsigned int header_len = sizeof(struct ccci_header); + unsigned int header_len = sizeof(struct ccci_header), mtu; struct wwan_port_caps caps; if (state != MD_STATE_READY) return; if (!port->wwan.wwan_port) { - caps.frag_len = CLDMA_MTU - header_len; + mtu = t7xx_get_port_mtu(port); + caps.frag_len = mtu - header_len; caps.headroom_len = header_len; port->wwan.wwan_port = wwan_create_port(port->dev, port_conf->port_type, &wwan_ops, &caps, port); diff --git a/drivers/net/wwan/t7xx/t7xx_reg.h b/drivers/net/wwan/t7xx/t7xx_reg.h index c41d7d094c085..9c7dc72ac6f62 100644 --- a/drivers/net/wwan/t7xx/t7xx_reg.h +++ b/drivers/net/wwan/t7xx/t7xx_reg.h @@ -101,11 +101,33 @@ enum t7xx_pm_resume_state { PM_RESUME_REG_STATE_L2_EXP, }; +enum host_event_e { + HOST_EVENT_INIT = 0, + FASTBOOT_DL_NOTIFY = 0x3, +}; + #define T7XX_PCIE_MISC_DEV_STATUS 0x0d1c #define MISC_STAGE_MASK GENMASK(2, 0) #define MISC_RESET_TYPE_PLDR BIT(26) #define MISC_RESET_TYPE_FLDR BIT(27) -#define LINUX_STAGE 4 +#define MISC_RESET_TYPE_PLDR BIT(26) +#define MISC_LK_EVENT_MASK GENMASK(11, 8) +#define HOST_EVENT_MASK GENMASK(31, 28) + +enum lk_event_id { + LK_EVENT_NORMAL = 0, + LK_EVENT_CREATE_PD_PORT = 1, + LK_EVENT_CREATE_POST_DL_PORT = 2, + LK_EVENT_RESET = 7, +}; + +enum t7xx_device_stage { + T7XX_DEV_STAGE_INIT = 0, + T7XX_DEV_STAGE_BROM_PRE = 1, + T7XX_DEV_STAGE_BROM_POST = 2, + T7XX_DEV_STAGE_LK = 3, + T7XX_DEV_STAGE_LINUX = 4, +}; #define T7XX_PCIE_RESOURCE_STATUS 0x0d28 #define T7XX_PCIE_RESOURCE_STS_MSK GENMASK(4, 0) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 3691ca8450814..5ca08cc1f1644 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -47,6 +47,13 @@ #define FSM_MD_EX_PASS_TIMEOUT_MS 45000 #define FSM_CMD_TIMEOUT_MS 2000 +#define wait_for_expected_dev_stage(status) \ + read_poll_timeout(ioread32, status, \ + ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LINUX) || \ + ((status & MISC_STAGE_MASK) == T7XX_DEV_STAGE_LK), 100000, \ + 20000000, false, IREG_BASE(md->t7xx_dev) + \ + T7XX_PCIE_MISC_DEV_STATUS) + void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier) { struct t7xx_fsm_ctl *ctl = md->fsm_ctl; @@ -213,6 +220,51 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm fsm_finish_command(ctl, cmd, 0); } +static void t7xx_host_event_notify(struct t7xx_modem *md, unsigned int event_id) +{ + u32 value; + + value = ioread32(IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); + value &= ~HOST_EVENT_MASK; + value |= FIELD_PREP(HOST_EVENT_MASK, event_id); + iowrite32(value, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); +} + +static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status) +{ + struct t7xx_modem *md = ctl->md; + struct cldma_ctrl *md_ctrl; + enum lk_event_id lk_event; + struct device *dev; + + dev = &md->t7xx_dev->pdev->dev; + lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status); + switch (lk_event) { + case LK_EVENT_NORMAL: + case LK_EVENT_RESET: + break; + + case LK_EVENT_CREATE_PD_PORT: + case LK_EVENT_CREATE_POST_DL_PORT: + md_ctrl = md->md_ctrl[CLDMA_ID_AP]; + t7xx_cldma_hif_hw_init(md_ctrl); + t7xx_cldma_stop(md_ctrl); + t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG); + + t7xx_cldma_start(md_ctrl); + + if (lk_event == LK_EVENT_CREATE_POST_DL_PORT) + t7xx_mode_update(md->t7xx_dev, T7XX_FASTBOOT_DOWNLOAD); + else + t7xx_mode_update(md->t7xx_dev, T7XX_FASTBOOT_DUMP); + break; + + default: + dev_err(dev, "Invalid LK event %d\n", lk_event); + break; + } +} + static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl) { ctl->curr_state = FSM_STATE_STOPPED; @@ -233,8 +285,9 @@ static void fsm_routine_stopped(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comman static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd) { - struct t7xx_pci_dev *t7xx_dev; - struct cldma_ctrl *md_ctrl; + struct cldma_ctrl *md_ctrl = ctl->md->md_ctrl[CLDMA_ID_MD]; + struct t7xx_pci_dev *t7xx_dev = ctl->md->t7xx_dev; + enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode); int err; if (ctl->curr_state == FSM_STATE_STOPPED || ctl->curr_state == FSM_STATE_STOPPING) { @@ -242,18 +295,20 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma return; } - md_ctrl = ctl->md->md_ctrl[CLDMA_ID_MD]; - t7xx_dev = ctl->md->t7xx_dev; - ctl->curr_state = FSM_STATE_STOPPING; t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_TO_STOP); t7xx_cldma_stop(md_ctrl); - if (!ctl->md->rgu_irq_asserted) { - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); - /* Wait for the DRM disable to take effect */ - msleep(FSM_DRM_DISABLE_DELAY_MS); + if (mode == T7XX_FASTBOOT_SWITCHING) + t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY); + + t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); + /* Wait for the DRM disable to take effect */ + msleep(FSM_DRM_DISABLE_DELAY_MS); + if (mode == T7XX_FASTBOOT_SWITCHING) { + t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); + } else { err = t7xx_acpi_fldr_func(t7xx_dev); if (err) t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); @@ -325,7 +380,8 @@ static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl) static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd) { struct t7xx_modem *md = ctl->md; - u32 dev_status; + struct device *dev; + u32 status; int ret; if (!md) @@ -337,23 +393,53 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command return; } + dev = &md->t7xx_dev->pdev->dev; ctl->curr_state = FSM_STATE_PRE_START; t7xx_md_event_notify(md, FSM_PRE_START); - ret = read_poll_timeout(ioread32, dev_status, - (dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 2000000, - false, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); + ret = wait_for_expected_dev_stage(status); + if (ret) { - struct device *dev = &md->t7xx_dev->pdev->dev; + dev_err(dev, "read poll timeout %d\n", ret); + goto finish_command; + } - fsm_finish_command(ctl, cmd, -ETIMEDOUT); - dev_err(dev, "Invalid device status 0x%lx\n", dev_status & MISC_STAGE_MASK); - return; + if (status != ctl->status || cmd->flag != 0) { + u32 stage = FIELD_GET(MISC_STAGE_MASK, status); + + switch (stage) { + case T7XX_DEV_STAGE_INIT: + case T7XX_DEV_STAGE_BROM_PRE: + case T7XX_DEV_STAGE_BROM_POST: + dev_dbg(dev, "BROM_STAGE Entered\n"); + ret = t7xx_fsm_append_cmd(ctl, FSM_CMD_START, 0); + break; + + case T7XX_DEV_STAGE_LK: + dev_dbg(dev, "LK_STAGE Entered\n"); + t7xx_lk_stage_event_handling(ctl, status); + break; + + case T7XX_DEV_STAGE_LINUX: + dev_dbg(dev, "LINUX_STAGE Entered\n"); + t7xx_mhccif_mask_clr(md->t7xx_dev, D2H_INT_PORT_ENUM | + D2H_INT_ASYNC_MD_HK | D2H_INT_ASYNC_AP_HK); + if (cmd->flag == 0) + break; + t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]); + t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]); + t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_NORMAL); + ret = fsm_routine_starting(ctl); + break; + + default: + break; + } + ctl->status = status; } - t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]); - t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]); - fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl)); +finish_command: + fsm_finish_command(ctl, cmd, ret); } static int fsm_main_thread(void *data) @@ -526,6 +612,7 @@ void t7xx_fsm_reset(struct t7xx_modem *md) fsm_flush_event_cmd_qs(ctl); ctl->curr_state = FSM_STATE_STOPPED; ctl->exp_flg = false; + ctl->status = T7XX_DEV_STAGE_INIT; } int t7xx_fsm_init(struct t7xx_modem *md) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h index c2cfaca07b207..6e0601bb752e5 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h @@ -96,6 +96,7 @@ struct t7xx_fsm_ctl { bool exp_flg; spinlock_t notifier_lock; /* Protects notifier list */ struct list_head notifier_list; + u32 status; /* Device boot stage */ }; struct t7xx_fsm_event { -- GitLab From 226a12745f47eb25dc438c0901d2b19004cef0b8 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 5 Feb 2024 18:22:30 +0800 Subject: [PATCH 296/456] UPSTREAM: net: wwan: t7xx: Add fastboot WWAN port On early detection of wwan device in fastboot mode, driver sets up CLDMA0 HW tx/rx queues for raw data transfer and then create fastboot port to userspace. Application can use this port to flash firmware and collect core dump by fastboot protocol commands. E.g., flash firmware through fastboot port: - "download:%08x": write data to memory with the download size. - "flash:%s": write the previously downloaded image to the named partition. - "reboot": reboot the device. Link: https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md Signed-off-by: Jinjian Song Signed-off-by: David S. Miller (cherry picked from commit 2dac6381c3da50d4b2525fd0514e41e8041ad974) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: Iaceeddb60325ea725ed900e33c16b1b31204d50c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928761 Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Reviewed-by: Sean Paul Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- .../networking/device_drivers/wwan/t7xx.rst | 18 +++ drivers/net/wwan/t7xx/t7xx_port_proxy.c | 3 + drivers/net/wwan/t7xx/t7xx_port_wwan.c | 116 ++++++++++++++---- drivers/net/wwan/t7xx/t7xx_state_monitor.c | 4 + 4 files changed, 115 insertions(+), 26 deletions(-) diff --git a/Documentation/networking/device_drivers/wwan/t7xx.rst b/Documentation/networking/device_drivers/wwan/t7xx.rst index 8429b99273417..f346f5f85f154 100644 --- a/Documentation/networking/device_drivers/wwan/t7xx.rst +++ b/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -125,6 +125,20 @@ The driver exposes an AT port by implementing AT WWAN Port. The userspace end of the control port is a /dev/wwan0at0 character device. Application shall use this interface to issue AT commands. +fastboot port userspace ABI +--------------------------- + +/dev/wwan0fastboot0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a fastboot protocol interface by implementing +fastboot WWAN Port. The userspace end of the fastboot channel pipe is a +/dev/wwan0fastboot0 character device. Application shall use this interface for +fastboot protocol communication. + +Please note that driver needs to be reloaded to export /dev/wwan0fastboot0 +port, because device needs a cold reset after enter ``fastboot_switching`` +mode. + The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification. References @@ -146,3 +160,7 @@ speak the Mobile Interface Broadband Model (MBIM) protocol"* [4] *Specification # 27.007 - 3GPP* - https://www.3gpp.org/DynaReport/27007.htm + +[5] *fastboot "a mechanism for communicating with bootloaders"* + +- https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index e53a152faee40..8f5e01705af29 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -112,6 +112,9 @@ static const struct t7xx_port_conf t7xx_early_port_conf[] = { .txq_exp_index = CLDMA_Q_IDX_DUMP, .rxq_exp_index = CLDMA_Q_IDX_DUMP, .path_id = CLDMA_ID_AP, + .ops = &wwan_sub_port_ops, + .name = "fastboot", + .port_type = WWAN_PORT_FASTBOOT, }, }; diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c index ddc20ddfa7347..4b23ba693f3f1 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c +++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2021, MediaTek Inc. * Copyright (c) 2021-2022, Intel Corporation. + * Copyright (c) 2024, Fibocom Wireless Inc. * * Authors: * Amir Hanania @@ -15,6 +16,7 @@ * Chiranjeevi Rapolu * Eliot Lee * Sreehari Kancharla + * Jinjian Song */ #include @@ -33,7 +35,7 @@ #include "t7xx_port_proxy.h" #include "t7xx_state_monitor.h" -static int t7xx_port_ctrl_start(struct wwan_port *port) +static int t7xx_port_wwan_start(struct wwan_port *port) { struct t7xx_port *port_mtk = wwan_port_get_drvdata(port); @@ -44,30 +46,60 @@ static int t7xx_port_ctrl_start(struct wwan_port *port) return 0; } -static void t7xx_port_ctrl_stop(struct wwan_port *port) +static void t7xx_port_wwan_stop(struct wwan_port *port) { struct t7xx_port *port_mtk = wwan_port_get_drvdata(port); atomic_dec(&port_mtk->usage_cnt); } -static int t7xx_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb) +static int t7xx_port_fastboot_tx(struct t7xx_port *port, struct sk_buff *skb) +{ + struct sk_buff *cur = skb, *tx_skb; + size_t actual, len, offset = 0; + int txq_mtu; + int ret; + + txq_mtu = t7xx_get_port_mtu(port); + if (txq_mtu < 0) + return -EINVAL; + + actual = cur->len; + while (actual) { + len = min_t(size_t, actual, txq_mtu); + tx_skb = __dev_alloc_skb(len, GFP_KERNEL); + if (!tx_skb) + return -ENOMEM; + + skb_put_data(tx_skb, cur->data + offset, len); + + ret = t7xx_port_send_raw_skb(port, tx_skb); + if (ret) { + dev_kfree_skb(tx_skb); + dev_err(port->dev, "Write error on fastboot port, %d\n", ret); + break; + } + offset += len; + actual -= len; + } + + dev_kfree_skb(skb); + return 0; +} + +static int t7xx_port_ctrl_tx(struct t7xx_port *port, struct sk_buff *skb) { - struct t7xx_port *port_private = wwan_port_get_drvdata(port); const struct t7xx_port_conf *port_conf; struct sk_buff *cur = skb, *cloned; struct t7xx_fsm_ctl *ctl; enum md_state md_state; int cnt = 0, ret; - if (!port_private->chan_enable) - return -EINVAL; - - port_conf = port_private->port_conf; - ctl = port_private->t7xx_dev->md->fsm_ctl; + port_conf = port->port_conf; + ctl = port->t7xx_dev->md->fsm_ctl; md_state = t7xx_fsm_get_md_state(ctl); if (md_state == MD_STATE_WAITING_FOR_HS1 || md_state == MD_STATE_WAITING_FOR_HS2) { - dev_warn(port_private->dev, "Cannot write to %s port when md_state=%d\n", + dev_warn(port->dev, "Cannot write to %s port when md_state=%d\n", port_conf->name, md_state); return -ENODEV; } @@ -75,10 +107,10 @@ static int t7xx_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb) while (cur) { cloned = skb_clone(cur, GFP_KERNEL); cloned->len = skb_headlen(cur); - ret = t7xx_port_send_skb(port_private, cloned, 0, 0); + ret = t7xx_port_send_skb(port, cloned, 0, 0); if (ret) { dev_kfree_skb(cloned); - dev_err(port_private->dev, "Write error on %s port, %d\n", + dev_err(port->dev, "Write error on %s port, %d\n", port_conf->name, ret); return cnt ? cnt + ret : ret; } @@ -93,14 +125,53 @@ static int t7xx_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb) return 0; } +static int t7xx_port_wwan_tx(struct wwan_port *port, struct sk_buff *skb) +{ + struct t7xx_port *port_private = wwan_port_get_drvdata(port); + const struct t7xx_port_conf *port_conf = port_private->port_conf; + int ret; + + if (!port_private->chan_enable) + return -EINVAL; + + if (port_conf->port_type != WWAN_PORT_FASTBOOT) + ret = t7xx_port_ctrl_tx(port_private, skb); + else + ret = t7xx_port_fastboot_tx(port_private, skb); + + return ret; +} + static const struct wwan_port_ops wwan_ops = { - .start = t7xx_port_ctrl_start, - .stop = t7xx_port_ctrl_stop, - .tx = t7xx_port_ctrl_tx, + .start = t7xx_port_wwan_start, + .stop = t7xx_port_wwan_stop, + .tx = t7xx_port_wwan_tx, }; +static void t7xx_port_wwan_create(struct t7xx_port *port) +{ + const struct t7xx_port_conf *port_conf = port->port_conf; + unsigned int header_len = sizeof(struct ccci_header), mtu; + struct wwan_port_caps caps; + + if (!port->wwan.wwan_port) { + mtu = t7xx_get_port_mtu(port); + caps.frag_len = mtu - header_len; + caps.headroom_len = header_len; + port->wwan.wwan_port = wwan_create_port(port->dev, port_conf->port_type, + &wwan_ops, &caps, port); + if (IS_ERR(port->wwan.wwan_port)) + dev_err(port->dev, "Unable to create WWAN port %s", port_conf->name); + } +} + static int t7xx_port_wwan_init(struct t7xx_port *port) { + const struct t7xx_port_conf *port_conf = port->port_conf; + + if (port_conf->port_type == WWAN_PORT_FASTBOOT) + t7xx_port_wwan_create(port); + port->rx_length_th = RX_QUEUE_MAXLEN; return 0; } @@ -152,21 +223,14 @@ static int t7xx_port_wwan_disable_chl(struct t7xx_port *port) static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int state) { const struct t7xx_port_conf *port_conf = port->port_conf; - unsigned int header_len = sizeof(struct ccci_header), mtu; - struct wwan_port_caps caps; + + if (port_conf->port_type == WWAN_PORT_FASTBOOT) + return; if (state != MD_STATE_READY) return; - if (!port->wwan.wwan_port) { - mtu = t7xx_get_port_mtu(port); - caps.frag_len = mtu - header_len; - caps.headroom_len = header_len; - port->wwan.wwan_port = wwan_create_port(port->dev, port_conf->port_type, - &wwan_ops, &caps, port); - if (IS_ERR(port->wwan.wwan_port)) - dev_err(port->dev, "Unable to create WWWAN port %s", port_conf->name); - } + t7xx_port_wwan_create(port); } struct port_ops wwan_sub_port_ops = { diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index 5ca08cc1f1644..f2e15dc8f6a51 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -236,6 +236,7 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int struct cldma_ctrl *md_ctrl; enum lk_event_id lk_event; struct device *dev; + struct t7xx_port *port; dev = &md->t7xx_dev->pdev->dev; lk_event = FIELD_GET(MISC_LK_EVENT_MASK, status); @@ -251,6 +252,9 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int t7xx_cldma_stop(md_ctrl); t7xx_cldma_switch_cfg(md_ctrl, CLDMA_DEDICATED_Q_CFG); + port = &ctl->md->port_prox->ports[0]; + port->port_conf->ops->enable_chl(port); + t7xx_cldma_start(md_ctrl); if (lk_event == LK_EVENT_CREATE_POST_DL_PORT) -- GitLab From b35d5c62f04c0009e2d4f1082fef795ea68e7b54 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sat, 24 Feb 2024 19:19:32 +0100 Subject: [PATCH 297/456] UPSTREAM: net: wwan: t7xx: Prefer struct_size over open coded arithmetic This is an effort to get rid of all multiplications from allocation functions in order to prevent integer overflows [1][2]. As the "port_prox" variable is a pointer to "struct port_proxy" and this structure ends in a flexible array: struct port_proxy { [...] struct t7xx_port ports[]; }; the preferred way in the kernel is to use the struct_size() helper to do the arithmetic instead of the argument "size + size * count" in the devm_kzalloc() function. This way, the code is more readable and safer. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1] Link: https://github.com/KSPP/linux/issues/160 [2] Signed-off-by: Erick Archer Reviewed-by: Sergey Ryazanov Link: https://lore.kernel.org/r/20240224181932.2720-1-erick.archer@gmx.com Signed-off-by: Jakub Kicinski (cherry picked from commit 848e34ca203046c9b967034596828472f08e4ac7) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I79328be78b58dadd7561d594310c7ccbd97733ed Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5928762 Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Reviewed-by: Sean Paul Tested-by: Daniel Winkler Reviewed-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_port_proxy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 8f5e01705af29..7d6388bf1d7c3 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -543,8 +543,10 @@ static int t7xx_proxy_alloc(struct t7xx_modem *md) struct device *dev = &md->t7xx_dev->pdev->dev; struct port_proxy *port_prox; - port_prox = devm_kzalloc(dev, sizeof(*port_prox) + - sizeof(struct t7xx_port) * T7XX_MAX_POSSIBLE_PORTS_NUM, + port_prox = devm_kzalloc(dev, + struct_size(port_prox, + ports, + T7XX_MAX_POSSIBLE_PORTS_NUM), GFP_KERNEL); if (!port_prox) return -ENOMEM; -- GitLab From 9d06c4fba6b7c7a5ad7029051c1c62d086347d49 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Sat, 17 Aug 2024 16:33:55 +0800 Subject: [PATCH 298/456] UPSTREAM: net: wwan: t7xx: PCIe reset rescan WWAN device is programmed to boot in normal mode or fastboot mode, when triggering a device reset through ACPI call or fastboot switch command. Maintain state machine synchronization and reprobe logic after a device reset. The PCIe device reset triggered by several ways. E.g.: - fastboot: echo "fastboot_switching" > /sys/bus/pci/devices/${bdf}/t7xx_mode. - reset: echo "reset" > /sys/bus/pci/devices/${bdf}/t7xx_mode. - IRQ: PCIe device request driver to reset itself by an interrupt request. Use pci_reset_function() as a generic way to reset device, save and restore the PCIe configuration before and after reset device to ensure the reprobe process. Suggestion from Bjorn: Link: https://lore.kernel.org/all/20230127133034.GA1364550@bhelgaas/ Signed-off-by: Jinjian Song Signed-off-by: David S. Miller (cherry picked from commit d785ed945de6955361aafc2d540d9bb7c6a69a65) Signed-off-by: Liu Qf BUG=b:302351783 TEST=check fastboot flash support on brya. Change-Id: I66d3527f770efaaff78b193de50c633bbbdd843f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5929943 Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Reviewed-by: Sean Paul Reviewed-by: Daniel Winkler Tested-by: Daniel Winkler Signed-off-by: Hubert Mazur --- drivers/net/wwan/t7xx/t7xx_modem_ops.c | 47 ++++++++++++++++--- drivers/net/wwan/t7xx/t7xx_modem_ops.h | 9 +++- drivers/net/wwan/t7xx/t7xx_pci.c | 53 ++++++++++++++++++---- drivers/net/wwan/t7xx/t7xx_pci.h | 3 ++ drivers/net/wwan/t7xx/t7xx_port_proxy.c | 1 - drivers/net/wwan/t7xx/t7xx_port_trace.c | 1 + drivers/net/wwan/t7xx/t7xx_state_monitor.c | 34 +++++--------- 7 files changed, 105 insertions(+), 43 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 8d864d4ed77f5..79f17100f70b1 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -53,6 +53,7 @@ #define RGU_RESET_DELAY_MS 10 #define PORT_RESET_DELAY_MS 2000 +#define FASTBOOT_RESET_DELAY_MS 2000 #define EX_HS_TIMEOUT_MS 5000 #define EX_HS_POLL_DELAY_MS 10 @@ -167,19 +168,52 @@ static int t7xx_acpi_reset(struct t7xx_pci_dev *t7xx_dev, char *fn_name) } kfree(buffer.pointer); +#else + struct device *dev = &t7xx_dev->pdev->dev; + int ret; + ret = pci_reset_function(t7xx_dev->pdev); + if (ret) { + dev_err(dev, "Failed to reset device, error:%d\n", ret); + return ret; + } #endif return 0; } -int t7xx_acpi_fldr_func(struct t7xx_pci_dev *t7xx_dev) +static void t7xx_host_event_notify(struct t7xx_pci_dev *t7xx_dev, unsigned int event_id) { - return t7xx_acpi_reset(t7xx_dev, "_RST"); + u32 value; + + value = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); + value &= ~HOST_EVENT_MASK; + value |= FIELD_PREP(HOST_EVENT_MASK, event_id); + iowrite32(value, IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); } -int t7xx_acpi_pldr_func(struct t7xx_pci_dev *t7xx_dev) +int t7xx_reset_device(struct t7xx_pci_dev *t7xx_dev, enum reset_type type) { - return t7xx_acpi_reset(t7xx_dev, "MRST._RST"); + int ret = 0; + + pci_save_state(t7xx_dev->pdev); + t7xx_pci_reprobe_early(t7xx_dev); + t7xx_mode_update(t7xx_dev, T7XX_RESET); + + if (type == FLDR) { + ret = t7xx_acpi_reset(t7xx_dev, "_RST"); + } else if (type == PLDR) { + ret = t7xx_acpi_reset(t7xx_dev, "MRST._RST"); + } else if (type == FASTBOOT) { + t7xx_host_event_notify(t7xx_dev, FASTBOOT_DL_NOTIFY); + t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); + msleep(FASTBOOT_RESET_DELAY_MS); + } + + pci_restore_state(t7xx_dev->pdev); + if (ret) + return ret; + + return t7xx_pci_reprobe(t7xx_dev, true); } static void t7xx_reset_device_via_pmic(struct t7xx_pci_dev *t7xx_dev) @@ -188,16 +222,15 @@ static void t7xx_reset_device_via_pmic(struct t7xx_pci_dev *t7xx_dev) val = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); if (val & MISC_RESET_TYPE_PLDR) - t7xx_acpi_reset(t7xx_dev, "MRST._RST"); + t7xx_reset_device(t7xx_dev, PLDR); else if (val & MISC_RESET_TYPE_FLDR) - t7xx_acpi_fldr_func(t7xx_dev); + t7xx_reset_device(t7xx_dev, FLDR); } static irqreturn_t t7xx_rgu_isr_thread(int irq, void *data) { struct t7xx_pci_dev *t7xx_dev = data; - t7xx_mode_update(t7xx_dev, T7XX_RESET); msleep(RGU_RESET_DELAY_MS); t7xx_reset_device_via_pmic(t7xx_dev); return IRQ_HANDLED; diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.h b/drivers/net/wwan/t7xx/t7xx_modem_ops.h index b39e945a92e01..39ed0000fbba2 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.h +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.h @@ -78,14 +78,19 @@ struct t7xx_modem { spinlock_t exp_lock; /* Protects exception events */ }; +enum reset_type { + FLDR, + PLDR, + FASTBOOT, +}; + void t7xx_md_exception_handshake(struct t7xx_modem *md); void t7xx_md_event_notify(struct t7xx_modem *md, enum md_event_id evt_id); int t7xx_md_reset(struct t7xx_pci_dev *t7xx_dev); int t7xx_md_init(struct t7xx_pci_dev *t7xx_dev); void t7xx_md_exit(struct t7xx_pci_dev *t7xx_dev); void t7xx_clear_rgu_irq(struct t7xx_pci_dev *t7xx_dev); -int t7xx_acpi_fldr_func(struct t7xx_pci_dev *t7xx_dev); -int t7xx_acpi_pldr_func(struct t7xx_pci_dev *t7xx_dev); +int t7xx_reset_device(struct t7xx_pci_dev *t7xx_dev, enum reset_type type); int t7xx_pci_mhccif_isr(struct t7xx_pci_dev *t7xx_dev); #endif /* __T7XX_MODEM_OPS_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index e0b1e7a616cae..6da0d431d26d6 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -69,6 +69,7 @@ static ssize_t t7xx_mode_store(struct device *dev, { struct t7xx_pci_dev *t7xx_dev; struct pci_dev *pdev; + enum t7xx_mode mode; int index = 0; pdev = to_pci_dev(dev); @@ -76,12 +77,22 @@ static ssize_t t7xx_mode_store(struct device *dev, if (!t7xx_dev) return -ENODEV; + mode = READ_ONCE(t7xx_dev->mode); + index = sysfs_match_string(t7xx_mode_names, buf); + if (index == mode) + return -EBUSY; + if (index == T7XX_FASTBOOT_SWITCHING) { + if (mode == T7XX_FASTBOOT_DOWNLOAD) + return count; + WRITE_ONCE(t7xx_dev->mode, T7XX_FASTBOOT_SWITCHING); + pm_runtime_resume(dev); + t7xx_reset_device(t7xx_dev, FASTBOOT); } else if (index == T7XX_RESET) { - WRITE_ONCE(t7xx_dev->mode, T7XX_RESET); - t7xx_acpi_pldr_func(t7xx_dev); + pm_runtime_resume(dev); + t7xx_reset_device(t7xx_dev, PLDR); } return count; @@ -446,7 +457,7 @@ static int t7xx_pcie_reinit(struct t7xx_pci_dev *t7xx_dev, bool is_d3) if (is_d3) { t7xx_mhccif_init(t7xx_dev); - return t7xx_pci_pm_reinit(t7xx_dev); + t7xx_pci_pm_reinit(t7xx_dev); } return 0; @@ -481,6 +492,33 @@ static int t7xx_send_fsm_command(struct t7xx_pci_dev *t7xx_dev, u32 event) return ret; } +int t7xx_pci_reprobe_early(struct t7xx_pci_dev *t7xx_dev) +{ + enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode); + int ret; + + if (mode == T7XX_FASTBOOT_DOWNLOAD) + pm_runtime_put_noidle(&t7xx_dev->pdev->dev); + + ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP); + if (ret) + return ret; + + return 0; +} + +int t7xx_pci_reprobe(struct t7xx_pci_dev *t7xx_dev, bool boot) +{ + int ret; + + ret = t7xx_pcie_reinit(t7xx_dev, boot); + if (ret) + return ret; + + t7xx_clear_rgu_irq(t7xx_dev); + return t7xx_send_fsm_command(t7xx_dev, FSM_CMD_START); +} + static int __t7xx_pci_pm_resume(struct pci_dev *pdev, bool state_check) { struct t7xx_pci_dev *t7xx_dev; @@ -507,16 +545,11 @@ static int __t7xx_pci_pm_resume(struct pci_dev *pdev, bool state_check) if (prev_state == PM_RESUME_REG_STATE_L3 || (prev_state == PM_RESUME_REG_STATE_INIT && atr_reg_val == ATR_SRC_ADDR_INVALID)) { - ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP); - if (ret) - return ret; - - ret = t7xx_pcie_reinit(t7xx_dev, true); + ret = t7xx_pci_reprobe_early(t7xx_dev); if (ret) return ret; - t7xx_clear_rgu_irq(t7xx_dev); - return t7xx_send_fsm_command(t7xx_dev, FSM_CMD_START); + return t7xx_pci_reprobe(t7xx_dev, true); } if (prev_state == PM_RESUME_REG_STATE_EXP || diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index 49a11586d8d84..cd8ea17c26441 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.h +++ b/drivers/net/wwan/t7xx/t7xx_pci.h @@ -133,4 +133,7 @@ int t7xx_pci_pm_entity_unregister(struct t7xx_pci_dev *t7xx_dev, struct md_pm_en void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev); void t7xx_pci_pm_exp_detected(struct t7xx_pci_dev *t7xx_dev); void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode); +int t7xx_pci_reprobe(struct t7xx_pci_dev *t7xx_dev, bool boot); +int t7xx_pci_reprobe_early(struct t7xx_pci_dev *t7xx_dev); + #endif /* __T7XX_PCI_H__ */ diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 7d6388bf1d7c3..35743e7de0c30 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -553,7 +553,6 @@ static int t7xx_proxy_alloc(struct t7xx_modem *md) md->port_prox = port_prox; port_prox->dev = dev; - t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_EARLY); return 0; } diff --git a/drivers/net/wwan/t7xx/t7xx_port_trace.c b/drivers/net/wwan/t7xx/t7xx_port_trace.c index 6a3f363858655..4ed8b4e29bf1d 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_trace.c +++ b/drivers/net/wwan/t7xx/t7xx_port_trace.c @@ -59,6 +59,7 @@ static void t7xx_trace_port_uninit(struct t7xx_port *port) relay_close(relaych); debugfs_remove_recursive(debugfs_dir); + port->log.relaych = NULL; } static int t7xx_trace_port_recv_skb(struct t7xx_port *port, struct sk_buff *skb) diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index f2e15dc8f6a51..cbdbb91e8381f 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -220,16 +220,6 @@ static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comm fsm_finish_command(ctl, cmd, 0); } -static void t7xx_host_event_notify(struct t7xx_modem *md, unsigned int event_id) -{ - u32 value; - - value = ioread32(IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); - value &= ~HOST_EVENT_MASK; - value |= FIELD_PREP(HOST_EVENT_MASK, event_id); - iowrite32(value, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS); -} - static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int status) { struct t7xx_modem *md = ctl->md; @@ -271,8 +261,14 @@ static void t7xx_lk_stage_event_handling(struct t7xx_fsm_ctl *ctl, unsigned int static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl) { + enum t7xx_mode mode; + ctl->curr_state = FSM_STATE_STOPPED; + mode = READ_ONCE(ctl->md->t7xx_dev->mode); + if (mode == T7XX_FASTBOOT_DOWNLOAD || mode == T7XX_FASTBOOT_DUMP) + return 0; + t7xx_fsm_broadcast_state(ctl, MD_STATE_STOPPED); return t7xx_md_reset(ctl->md->t7xx_dev); } @@ -291,8 +287,6 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma { struct cldma_ctrl *md_ctrl = ctl->md->md_ctrl[CLDMA_ID_MD]; struct t7xx_pci_dev *t7xx_dev = ctl->md->t7xx_dev; - enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode); - int err; if (ctl->curr_state == FSM_STATE_STOPPED || ctl->curr_state == FSM_STATE_STOPPING) { fsm_finish_command(ctl, cmd, -EINVAL); @@ -303,21 +297,10 @@ static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_comma t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_TO_STOP); t7xx_cldma_stop(md_ctrl); - if (mode == T7XX_FASTBOOT_SWITCHING) - t7xx_host_event_notify(ctl->md, FASTBOOT_DL_NOTIFY); - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP); /* Wait for the DRM disable to take effect */ msleep(FSM_DRM_DISABLE_DELAY_MS); - if (mode == T7XX_FASTBOOT_SWITCHING) { - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); - } else { - err = t7xx_acpi_fldr_func(t7xx_dev); - if (err) - t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET); - } - fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl)); } @@ -421,7 +404,9 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command case T7XX_DEV_STAGE_LK: dev_dbg(dev, "LK_STAGE Entered\n"); + t7xx_port_proxy_set_cfg(md, PORT_CFG_ID_EARLY); t7xx_lk_stage_event_handling(ctl, status); + break; case T7XX_DEV_STAGE_LINUX: @@ -443,6 +428,9 @@ static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command } finish_command: + if (ret) + t7xx_mode_update(md->t7xx_dev, T7XX_UNKNOWN); + fsm_finish_command(ctl, cmd, ret); } -- GitLab From a2d7c174356b6a923ce407d2c65c605c8f184717 Mon Sep 17 00:00:00 2001 From: Xavier Chang Date: Mon, 8 Jan 2024 09:52:13 +0800 Subject: [PATCH 299/456] CHROMIUM: arm64: dts: mt8196: Add MT8196 EVB dts Add MT8196 EVB dts and the dtsi files. BUG=b:334735558 TEST=Kernel Build Pass and boot to shell pass UPSTREAM-TASK=b:387626746 Signed-off-by: Haodong Shi Signed-off-by: Kai Liang Signed-off-by: Xavier Chang Signed-off-by: Fei Shao Change-Id: I30590208c1196e8f08261e2b7566eba39dc42a72 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071723 Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/Makefile | 3 +- arch/arm64/boot/dts/mediatek/mt8196-evb.dts | 21 + arch/arm64/boot/dts/mediatek/mt8196.dtsi | 1349 +++++++++++++++++++ 3 files changed, 1372 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/mediatek/mt8196-evb.dts create mode 100644 arch/arm64/boot/dts/mediatek/mt8196.dtsi diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 9d7137de16228..c872bc5464776 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -113,5 +113,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r2.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-cherry-tomato-r3.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8196-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb -dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb \ No newline at end of file diff --git a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts new file mode 100644 index 0000000000000..c9747f3e4a7f8 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2021 MediaTek Inc. + * Author: Seiya Wang + */ +/dts-v1/; +#include "mt8196.dtsi" + +/ { + model = "MediaTek MT8196 evaluation board"; + compatible = "mediatek,mt8196-evb", "mediatek,mt8196"; + + /* chosen */ + chosen: chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi new file mode 100644 index 0000000000000..9f55c3e4b3496 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -0,0 +1,1349 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt8196"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + mmc1 = &mmc1; + mmc2 = &mmc2; + serial0 = &uart0; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; + spi3 = &spi3; + spi4 = &spi4; + spi5 = &spi5; + spi6 = &spi6; + spi7 = &spi7; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a720"; + reg = <0x000>; + performance-domains = <&performance 0>; + enable-method = "psci"; + clock-frequency = <2100000000>; + capacity-dmips-mhz = <714>; + cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff_l + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu1: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a720"; + reg = <0x100>; + performance-domains = <&performance 0>; + enable-method = "psci"; + clock-frequency = <2100000000>; + capacity-dmips-mhz = <714>; + cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff_l + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a720"; + reg = <0x200>; + performance-domains = <&performance 0>; + enable-method = "psci"; + clock-frequency = <2100000000>; + capacity-dmips-mhz = <714>; + cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff_l + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a720"; + reg = <0x300>; + performance-domains = <&performance 0>; + enable-method = "psci"; + clock-frequency = <2100000000>; + capacity-dmips-mhz = <714>; + cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff_l + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "arm,cortex-x4"; + reg = <0x400>; + performance-domains = <&performance 1>; + enable-method = "psci"; + clock-frequency = <2800000000>; + capacity-dmips-mhz = <1024>; + cpu-idle-states = <&cpuoff_m &clusteroff_m &mcusysoff_m + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_1>; + #cooling-cells = <2>; + }; + + cpu5: cpu@500 { + device_type = "cpu"; + compatible = "arm,cortex-x4"; + reg = <0x500>; + performance-domains = <&performance 1>; + enable-method = "psci"; + clock-frequency = <2800000000>; + capacity-dmips-mhz = <1024>; + cpu-idle-states = <&cpuoff_m &clusteroff_m &mcusysoff_m + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_1>; + #cooling-cells = <2>; + }; + + cpu6: cpu@600 { + device_type = "cpu"; + compatible = "arm,cortex-x4"; + reg = <0x600>; + performance-domains = <&performance 1>; + enable-method = "psci"; + clock-frequency = <2800000000>; + capacity-dmips-mhz = <1024>; + cpu-idle-states = <&cpuoff_m &clusteroff_m &mcusysoff_m + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_1>; + #cooling-cells = <2>; + }; + + cpu7: cpu@700 { + device_type = "cpu"; + compatible = "arm,cortex-x925"; + reg = <0x700>; + performance-domains = <&performance 2>; + enable-method = "psci"; + clock-frequency = <3600000000>; + capacity-dmips-mhz = <937>; + cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff_b + &system_vcore &s2idle>; + i-cache-size = <65536>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <65536>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&l2_2>; + #cooling-cells = <2>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu4>; + }; + core1 { + cpu = <&cpu5>; + }; + core2 { + cpu = <&cpu6>; + }; + }; + + cluster2 { + core0 { + cpu = <&cpu7>; + }; + }; + }; + + idle-states { + entry-method = "arm,psci"; + cpuoff_l: cpuoff-l { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x00010000>; + local-timer-stop; + entry-latency-us = <97>; + exit-latency-us = <252>; + min-residency-us = <6710>; + }; + + cpuoff_m: cpuoff-m { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x00010000>; + local-timer-stop; + entry-latency-us = <53>; + exit-latency-us = <143>; + min-residency-us = <2120>; + }; + + cpuoff_b: cpuoff-b { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x00010000>; + local-timer-stop; + entry-latency-us = <40>; + exit-latency-us = <107>; + min-residency-us = <2580>; + }; + + clusteroff_l: clusteroff-l { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x01010001>; + local-timer-stop; + entry-latency-us = <109>; + exit-latency-us = <325>; + min-residency-us = <6710>; + }; + + clusteroff_m: clusteroff-m { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x01010001>; + local-timer-stop; + entry-latency-us = <59>; + exit-latency-us = <188>; + min-residency-us = <2120>; + }; + + clusteroff_b: clusteroff-b { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x01010001>; + local-timer-stop; + entry-latency-us = <43>; + exit-latency-us = <138>; + min-residency-us = <2580>; + }; + + mcusysoff_l: mcusysoff-l { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x02010007>; + local-timer-stop; + entry-latency-us = <1357>; + exit-latency-us = <835>; + min-residency-us = <6710>; + }; + + mcusysoff_m: mcusysoff-m { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x02010007>; + local-timer-stop; + entry-latency-us = <1202>; + exit-latency-us = <679>; + min-residency-us = <2120>; + }; + + mcusysoff_b: mcusysoff-b { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x02010007>; + local-timer-stop; + entry-latency-us = <1143>; + exit-latency-us = <611>; + min-residency-us = <2580>; + }; + + system_vcore: system-vcore { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x020100ff>; + local-timer-stop; + entry-latency-us = <940>; + exit-latency-us = <3500>; + min-residency-us = <35200>; + }; + + s2idle: s2idle { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x020180ff>; + local-timer-stop; + entry-latency-us = <10000>; + exit-latency-us = <10000>; + min-residency-us = <4294967295>; + }; + }; + + l2_0: l2-cache0 { + compatible = "cache"; + cache-level = <2>; + cache-size = <524288>; + cache-line-size = <64>; + cache-sets = <2048>; + next-level-cache = <&l3_0>; + cache-unified; + }; + + l2_1: l2-cache1 { + compatible = "cache"; + cache-level = <2>; + cache-size = <1048576>; + cache-line-size = <64>; + cache-sets = <4096>; + next-level-cache = <&l3_0>; + cache-unified; + }; + + l2_2: l2-cache2 { + compatible = "cache"; + cache-level = <2>; + cache-size = <2097152>; + cache-line-size = <64>; + cache-sets = <8192>; + next-level-cache = <&l3_0>; + cache-unified; + }; + + l3_0: l3-cache { + compatible = "cache"; + cache-level = <3>; + cache-size = <12582912>; + cache-line-size = <64>; + cache-sets = <49152>; + cache-unified; + }; + }; + + clk_ao: clk-ao { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + }; + + clkitg: clkitg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + }; + + clocks { + clk_null: clk-null { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + clk32k: clk32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32000>; + }; + + clk13m: clk13m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <13000000>; + }; + + clk26m: clk26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + /* + * ulposc: Ultra Low Power Oscillator + * It is used by soc when the 26Mhz clock is turned + * off. It also is used by other modules. + */ + ulposc: ulposc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <520000000>; + }; + + /* + * ulposc3: Ultra Low Power Oscillator 3 + * It is used by soc when the 26Mhz clock is turned + * off. It also is used by other modules. + */ + ulposc3: ulposc3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk104m: clk104m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <104000000>; + }; + }; + + memory: memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0x40000000>; + }; + + pmu_hunter: pmu-hunter { + compatible = "arm,cortex-a720-pmu"; + interrupt-parent = <&gic>; + interrupts = ; + }; + + pmu_hunter_elp: pmu-hunter-elp { + compatible = "arm,cortex-x4-pmu"; + interrupt-parent = <&gic>; + interrupts = ; + }; + + pmu_blackhawk: pmu-blackhawk{ + compatible = "arm,cortex-x925-pmu"; + interrupt-parent = <&gic>; + interrupts = ; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + }; + + timer: timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + clock-frequency = <13000000>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + + csram_sys: csram-sysram@11bc00 { + reg = <0 0x11bc00 0 0x1400>; /* 5KB */ + }; + + cpu_mcucfg: mcusys-ao-cfg@c000000 { + reg = <0 0xc000000 0 0x10000>; /* 64KB */ + }; + + cpu_pll: mcusys-pll1u-top@c030000 { + reg = <0 0xc030000 0 0x1000>; /* 4KB */ + }; + + ccipll_pll_ctrl_clk: syscon@c1e0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ccipll-pll-ctrl", "mediatek,mt8196-ccipll_pll_ctrl", "syscon"; + reg = <0 0xc1e0000 0 0x400>; + #clock-cells = <1>; + }; + + armpll_ll_pll_ctrl_clk: syscon@c1e0400 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-armpll-ll-pll-ctrl", "mediatek,mt8196-armpll_ll_pll_ctrl", "syscon"; + reg = <0 0xc1e0400 0 0x400>; + #clock-cells = <1>; + }; + + armpll_bl_pll_ctrl_clk: syscon@c1e0800 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-armpll-bl-pll-ctrl", "mediatek,mt8196-armpll_bl_pll_ctrl", "syscon"; + reg = <0 0xc1e0800 0 0x400>; + #clock-cells = <1>; + }; + + armpll_b_pll_ctrl_clk: syscon@c1e0c00 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-armpll-b-pll-ctrl", "mediatek,mt8196-armpll_b_pll_ctrl", "syscon"; + reg = <0 0xc1e0c00 0 0x1000>; + #clock-cells = <1>; + }; + + ptppll_pll_ctrl_clk: syscon@c1e4000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ptppll-pll-ctrl", "mediatek,mt8196-ptppll_pll_ctrl", "syscon"; + reg = <0 0xc1e4000 0 0x1000>; + #clock-cells = <1>; + }; + + performance: performance-controller@c2c0f20 { + compatible = "mediatek,cpufreq-hw"; + reg = <0 0xc2c0f20 0 0x120>, + <0 0xc2c1040 0 0x120>, + <0 0xc2c1160 0 0x120>; + reg-names = "performance-domain0", + "performance-domain1", + "performance-domain2"; + #performance-domain-cells = <1>; + }; + + gic: interrupt-controller@c400000 { + compatible = "arm,gic-v3"; + reg = <0 0xc400000 0 0x40000>, /* distributor */ + <0 0xc440000 0 0x200000>; /* redistributor */ + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <2>; + #redistributor-regions = <1>; + interrupt-parent = <&gic>; + interrupt-controller; + interrupts = ; + + ppi-partitions { + ppi_cluster0: interrupt-partition-0 { + affinity = <&cpu0 &cpu1 &cpu2 &cpu3>; + }; + + ppi_cluster1: interrupt-partition-1 { + affinity = <&cpu4 &cpu5 &cpu6>; + }; + + ppi_cluster2: interrupt-partition-2 { + affinity = <&cpu7>; + }; + }; + }; + + cksys_clk: syscon@10000000 { + compatible = "mediatek,mt8196-cksys", "syscon"; + reg = <0 0x10000000 0 0x800>; + hw-voter-regmap = <&hwv>; + #clock-cells = <1>; + }; + + apmixedsys_clk: syscon@10000800 { + compatible = "mediatek,mt8196-apmixedsys", "syscon"; + reg = <0 0x10000800 0 0x1000>; + #clock-cells = <1>; + }; + + cksys_gp2_clk: syscon@1000c000 { + compatible = "mediatek,mt8196-cksys-gp2", "syscon"; + reg = <0 0x1000c000 0 0x800>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + apmixedsys_gp2_clk: syscon@1000c800 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-apmixedsys-gp2", "mediatek,mt8196-apmixedsys_gp2", "syscon"; + reg = <0 0x1000c800 0 0x1000>; + #clock-cells = <1>; + }; + + infracfg_ao_clk: syscon@10001000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-infracfg-ao", "mediatek,mt8196-infracfg_ao", "syscon"; + reg = <0 0x10001000 0 0x1000>; + #clock-cells = <1>; + }; + + ifr_bus: syscon@1002c000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ifr-bus", "mediatek,mt8196-ifr_bus", "syscon"; + reg = <0 0x1002c000 0 0x1000>; + }; + + i2c5: i2c@120a0000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x120a0000 0 0x20000>, + <0 0x16400000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_e_clk CLK_IMPE_I2C5_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + imp_iic_wrap_e_clk: syscon@120c0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-imp-iic-wrap-e", "mediatek,mt8196-imp_iic_wrap_e", "syscon"; + reg = <0 0x120c0000 0 0x1000>; + #clock-cells = <1>; + }; + + i2c0: i2c@13130000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13130000 0 0x20000>, + <0 0x16370000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_w_clk CLK_IMPW_I2C0_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c3: i2c@13150000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13150000 0 0x20000>, + <0 0x163c0000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_w_clk CLK_IMPW_I2C3_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c6: i2c@13170000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13170000 0 0x20000>, + <0 0x16410000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_w_clk CLK_IMPW_I2C6_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c10: i2c@13190000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13190000 0 0x20000>, + <0 0x164b0000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_w_clk CLK_IMPW_I2C10_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + imp_iic_wrap_w_clk: syscon@131b0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-imp-iic-wrap-w", "mediatek,mt8196-imp_iic_wrap_w", "syscon"; + reg = <0 0x131b0000 0 0x1000>; + #clock-cells = <1>; + }; + + i2c1: i2c@13930000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13930000 0 0x80000>, + <0 0x16380000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C1_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c2: i2c@139b0000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x139b0000 0 0x80000>, + <0 0x16390000 0 0x30000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C2_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c4: i2c@13a30000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13a30000 0 0x80000>, + <0 0x163d0000 0 0x30000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C4_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c7: i2c@13ab0000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13ab0000 0 0x80000>, + <0 0x16420000 0 0x30000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C7_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c8: i2c@13b30000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13b30000 0 0x80000>, + <0 0x16450000 0 0x30000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C8_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c9: i2c@13bb0000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x13bb0000 0 0x80000>, + <0 0x16480000 0 0x30000>; + interrupts = ; + clocks = <&imp_iic_wrap_n_clk CLK_IMPN_I2C9_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + imp_iic_wrap_n_clk: syscon@13c30000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-imp-iic-wrap-n", "mediatek,mt8196-imp_iic_wrap_n", "syscon"; + reg = <0 0x13c30000 0 0x1000>; + hw-voter-regmap = <&hwv>; + #clock-cells = <1>; + }; + + apifrbus_ao_mem_reg_clk: syscon@14126000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-apifrbus-ao-mem-reg", "mediatek,mt8196-apifrbus_ao_mem_reg", "syscon"; + reg = <0 0x14126000 0 0x1000>; + #clock-cells = <1>; + }; + + hwv: syscon@14500000 { + compatible = "mediatek,mt8196-hwv", "syscon"; + reg = <0 0x14500000 0 0x3000>; + }; + + uart0: serial@16000000 { + compatible = "mediatek,mt6577-uart"; + reg = <0 0x16000000 0 0x1000>; + interrupts = ; + clocks = <&clk26m>, <&pericfg_ao_clk CLK_PERAO_UART0_BCLK_UART>; + clock-names = "baud", "bus"; + + status = "disabled"; + }; + + uart1: serial@16010000 { + compatible = "mediatek,mt6577-uart"; + reg = <0 0x16010000 0 0x1000>; + interrupts = ; + clocks = <&clk26m>, <&pericfg_ao_clk CLK_PERAO_UART1_BCLK_UART>; + clock-names = "baud", "bus"; + + status = "disabled"; + }; + + uart2: serial@16020000 { + compatible = "mediatek,mt6577-uart"; + reg = <0 0x16020000 0 0x1000>; + interrupts = ; + clocks = <&clk26m>, <&pericfg_ao_clk CLK_PERAO_UART2_BCLK_UART>; + clock-names = "baud", "bus"; + + status = "disabled"; + }; + + uart3: serial@16030000 { + compatible = "mediatek,mt6985-uart"; + reg = <0 0x16030000 0 0x1000>; + interrupts = , + ; /* uart3 wakeup irq */ + clocks = <&clk104m>, <&pericfg_ao_clk CLK_PERAO_UART3_BCLK_UART>; + clock-names = "baud", "bus"; + + status = "disabled"; + }; + + spi0: spi@16110000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x16110000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI0_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI0_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi1: spi@16130000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x16130000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI1_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI1_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi2: spi@16150000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x16150000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI2_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI2_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi3: spi@16170000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x16170000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI3_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI3_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi4: spi@16190000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x16190000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI4_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI4_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi5: spi@161b0000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x161b0000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI5_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI5_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + spi6: spi@161d0000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x161d0000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI6_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI6_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <1>; + + status = "disabled"; + }; + + spi7: spi@161f0000 { + compatible = "mediatek,mt8196-spi"; + reg = <0 0x161f0000 0 0x100>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_UNIVPLL_D6_D2>, + <&cksys_clk CLK_CK_SPI7_BCLK_SEL>, + <&pericfg_ao_clk CLK_PERAO_SPI7_BCLK_SPI>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + mediatek,pad-select = <0>; + + status = "disabled"; + }; + + i2c11: i2c@16200000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x16200000 0 0x40000>, + <0 0x164c0000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_c_clk CLK_IMPC_I2C11_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c12: i2c@16240000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x16240000 0 0x40000>, + <0 0x164d0000 0 0x20000>; + interrupts = ; + clocks = <&imp_iic_wrap_c_clk CLK_IMPC_I2C12_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c13: i2c@16280000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x16280000 0 0x40000>, + <0 0x164f0000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_c_clk CLK_IMPC_I2C13_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c14: i2c@162c0000 { + compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; + reg = <0 0x162c0000 0 0x40000>, + <0 0x16500000 0 0x10000>; + interrupts = ; + clocks = <&imp_iic_wrap_c_clk CLK_IMPC_I2C14_I2C>, + <&pericfg_ao_clk CLK_PERAO_AP_DMA_X32W_BCLK_I2C>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + imp_iic_wrap_c_clk: syscon@16300000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-imp-iic-wrap-c", "mediatek,mt8196-imp_iic_wrap_c", "syscon"; + reg = <0 0x16300000 0 0x1000>; + #clock-cells = <1>; + }; + + mmc1: mmc@16310000 { + compatible = "mediatek,mt8196-mmc"; + reg = <0 0x16310000 0 0x1000>, + <0 0x12a10000 0 0x1000>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_MSDC30_1_SEL>, + <&pericfg_ao_clk CLK_PERAO_MSDC1_AXI_MSDC1>, + <&pericfg_ao_clk CLK_PERAO_MSDC1_HCLK_MSDC1>, + <&pericfg_ao_clk CLK_PERAO_MSDC1_MSDC_SRC_MSDC1>, + <&pericfg_ao_clk CLK_PERAO_MSDC1_HCLK_WRAP_MSDC1>; + clock-names = "source", "axi_cg", "hclk", "source_cg", "ahb_cg"; + + status = "disabled"; + }; + + mmc2: mmc@16320000 { + compatible = "mediatek,mt8196-mmc"; + reg = <0 0x16320000 0 0x1000>, + <0 0x138a0000 0 0x1000>; + interrupts = ; + clocks = <&cksys_clk CLK_CK_MSDC30_2_SEL>, + <&pericfg_ao_clk CLK_PERAO_MSDC2_AXI_MSDC2>, + <&pericfg_ao_clk CLK_PERAO_MSDC2_HCLK_MSDC2>, + <&pericfg_ao_clk CLK_PERAO_MSDC2_MSDC_SRC_MSDC2>, + <&pericfg_ao_clk CLK_PERAO_MSDC2_HCLK_WRAP_MSDC2>; + clock-names = "source", "axi_cg", "hclk", "source_cg", "ahb_cg"; + + status = "disabled"; + }; + + pericfg_ao_clk: syscon@16640000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-pericfg-ao", "mediatek,mt8196-pericfg_ao", "syscon"; + reg = <0 0x16640000 0 0x1000>; + hw-voter-regmap = <&hwv>; + #clock-cells = <1>; + }; + + ufscfg_ao_sec_clk: syscon@16890000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ufscfg-ao-sec", "mediatek,mt8196-ufscfg_ao_sec", "syscon"; + reg = <0 0x16890000 0 0x1000>; + #clock-cells = <1>; + }; + + ufscfg_ao_clk: syscon@168a0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ufscfg-ao", "mediatek,mt8196-ufscfg_ao", "syscon"; + reg = <0 0x168a0000 0 0x1000>; + #clock-cells = <1>; + }; + + pextp0cfg_ao_clk: syscon@169b0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-pextp0cfg-ao", "mediatek,mt8196-pextp0cfg_ao", "syscon", "simple-mfd"; + reg = <0 0x169b0000 0 0x1000>; + #clock-cells = <1>; + + pextp0ao_rst: reset-controller { + compatible = "ti,syscon-reset"; + #reset-cells = <1>; + + ti,reset-bits = < + /* 0: PCIe0 MAC reset */ + 0x8 0 0xc 0 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + /* 1: PCIe0 PHY reset */ + 0x8 1 0xc 1 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + >; + }; + }; + + pextp1cfg_ao_clk: syscon@169e0000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-pextp1cfg-ao", "mediatek,mt8196-pextp1cfg_ao", "syscon", "simple-mfd"; + reg = <0 0x169e0000 0 0x1000>; + #clock-cells = <1>; + + pextp1ao_rst: reset-controller { + compatible = "ti,syscon-reset"; + #reset-cells = <1>; + + ti,reset-bits = < + /* 0: PCIe1 MAC reset */ + 0x8 0 0xc 0 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + /* 1: PCIe1 PHY reset */ + 0x8 1 0xc 1 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + /* 2: PCIe2 MAC reset */ + 0x8 8 0xc 8 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + /* 3: PCIe2 PHY reset */ + 0x8 9 0xc 9 0 0 + (ASSERT_SET | DEASSERT_SET | STATUS_NONE) + >; + }; + }; + + ssr_top_clk: syscon@18000000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ssr-top", "mediatek,mt8196-ssr_top", "syscon"; + reg = <0 0x18000000 0 0x1000>; + hw-voter-regmap = <&hwv>; + #clock-cells = <1>; + }; + + afe_clk: syscon@1a110000 { + compatible = "mediatek,mt8196-audiosys", "syscon"; + reg = <0 0x1a110000 0 0x1000>; + #clock-cells = <1>; + }; + + scpsys: power-controller@1c004000 { + compatible = "mediatek,mt8196-scpsys-hwv", "syscon"; + reg = <0 0x1c004000 0 0x1000>; + #power-domain-cells = <1>; + apifrbus-ao-io-reg-bus = <&ifr_bus>; + spm = <&scpsys_bus>; + hw-voter-regmap = <&hwv>; + }; + + scpsys_bus: syscon@1c00d000 { + compatible = "mediatek,mt8196-scpsys-bus", "syscon"; + reg = <0 0x1c00d000 0 0x1000>; + }; + + watchdog: watchdog@1c010000 { + compatible = "mediatek,mt8196-wdt", + "mediatek,mt6589-wdt", + "syscon", "simple-mfd"; + reg = <0 0x1c010000 0 0x1000>; + }; + + vlp_cksys_clk: syscon@1c016000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-vlp-cksys", "mediatek,mt8196-vlp_cksys", "syscon"; + reg = <0 0x1c016000 0 0x1000>; + hw-voter-regmap = <&hwv>; + #clock-cells = <1>; + }; + + systimer: systimer@1c400000 { + compatible = "mediatek,mt8196-timer", + "mediatek,mt6765-timer"; + reg = <0 0x1c400000 0 0x1000>; + interrupts = ; + clocks = <&clk13m>; + }; + + mminfra_hwv: syscon@31a80000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-mminfra-hwv", "mediatek,mt8196-mminfra_hwv", "syscon"; + reg = <0 0x31a80000 0 0x1000>; + }; + + mm_hwv: syscon@31b00000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-mm-hwv", "mediatek,mt8196-mm_hwv", "syscon"; + reg = <0 0x31b00000 0 0x3000>; + }; + + hfrpsys: power-controller@31b50000 { + compatible = "mediatek,mt8196-hfrpsys-hwv", "syscon"; + reg = <0 0x31b50000 0 0x1000>; + #power-domain-cells = <1>; + mmpc = <&hfrpsys>; + mm-hw-ccf-regmap = <&mm_hwv>; + mminfra-hwv-regmap = <&mminfra_hwv>; + }; + + dispsys_config_clk: syscon@32000000 { + compatible = "mediatek,mt8196-mmsys0", "syscon"; + reg = <0 0x32000000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + dispsys1_config_clk: syscon@32400000 { + compatible = "mediatek,mt8196-mmsys1", "syscon"; + reg = <0 0x32400000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + ovlsys_config_clk: syscon@32800000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ovlsys-config", "mediatek,mt8196-ovlsys_config", "syscon"; + reg = <0 0x32800000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + ovlsys1_config_clk: syscon@32c00000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-ovlsys1-config", "mediatek,mt8196-ovlsys1_config", "syscon"; + reg = <0 0x32c00000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + vdec_soc_gcon_base_clk: syscon@3600f000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-vdecsys-soc", "mediatek,mt8196-vdecsys_soc", "syscon"; + reg = <0 0x3600f000 0 0x1000>; + #clock-cells = <1>; + }; + + vdec_gcon_base_clk: syscon@3602f000 { + compatible = "mediatek,mt8196-vdecsys", "syscon"; + reg = <0 0x3602f000 0 0x1000>; + #clock-cells = <1>; + }; + + venc_gcon_clk: syscon@38000000 { + compatible = "mediatek,mt8196-vencsys", "syscon"; + reg = <0 0x38000000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + venc_gcon_core1_clk: syscon@38800000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-vencsys-c1", "mediatek,mt8196-vencsys_c1", "syscon"; + reg = <0 0x38800000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + venc_gcon_core2_clk: syscon@38c00000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-vencsys-c2", "mediatek,mt8196-vencsys_c2", "syscon"; + reg = <0 0x38c00000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + cam_main_r1a_clk: syscon@3a000000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-cam_main-r1a", "mediatek,mt8196-cam_main_r1a", "syscon"; + reg = <0 0x3a000000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + mdpsys_config_clk: syscon@3e000000 { + compatible = "mediatek,mt8196-mdpsys", "syscon"; + reg = <0 0x3e000000 0 0x1000>; + #clock-cells = <1>; + }; + + mdpsys1_config_clk: syscon@3e400000 { + compatible = "mediatek,mt8196-mdpsys1", "syscon"; + reg = <0 0x3e400000 0 0x1000>; + #clock-cells = <1>; + }; + + disp_vdisp_ao_config_clk: syscon@3e800000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-disp-vdisp-ao-config", "mediatek,mt8196-disp_vdisp_ao_config", "syscon"; + reg = <0 0x3e800000 0 0x1000>; + mm-hw-ccf-regmap = <&mm_hwv>; + #clock-cells = <1>; + }; + + mfgpll_pll_ctrl_clk: syscon@4b810000 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-mfgpll-pll-ctrl", "mediatek,mt8196-mfgpll_pll_ctrl", "syscon"; + reg = <0 0x4b810000 0 0x400>; + #clock-cells = <1>; + }; + + mfgpll_sc0_pll_ctrl_clk: syscon@4b810400 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-mfgpll-sc0-pll-ctrl", "mediatek,mt8196-mfgpll_sc0_pll_ctrl", "syscon"; + reg = <0 0x4b810400 0 0x400>; + #clock-cells = <1>; + }; + + mfgpll_sc1_pll_ctrl_clk: syscon@4b810800 { + /* TODO: Fix compatible in driver */ + compatible = "mediatek,mt8196-mfgpll-sc1-pll-ctrl", "mediatek,mt8196-mfgpll_sc1_pll_ctrl", "syscon"; + reg = <0 0x4b810800 0 0x1000>; + #clock-cells = <1>; + }; + }; +}; -- GitLab From c99504ec5c8913ee55970c4ff2fe896676c9f6bb Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Tue, 3 Dec 2024 15:21:53 +0800 Subject: [PATCH 300/456] BACKPORT: FROMLIST: iommu/iova: Add support for IOVA max alignment tuning IOVAs are aligned to the smallest PAGE_SIZE order, where the requested IOVA can fit. But this might not work for all use-cases. It can cause IOVA fragmentation in some multimedia and 8K video use-cases that may require larger buffers to be allocated and mapped. When the above allocation pattern is used with the current alignment scheme, the IOVA space could be quickly exhausted for 32bit devices. In order to get better IOVA space utilization and reduce fragmentation, a new kernel command line parameter is introduced to make the alignment limit configurable by the user during boot. Signed-off-by: Georgi Djakov (am from https://lore.kernel.org/all/1634148667-409263-1-git-send-email-quic_c_gdjako@quicinc.com/) Conflicts: drivers/iommu/iova.c [include linux/init.h for early_param()] [guard early_param() with `#ifndef MODULE`, for arm-generic buildtest] BUG=b:379500209 TEST=Boot ok UPSTREAM-TASK=b:387224505 Change-Id: Ia8ac7b4b57921e8e0c72ab162c11234730a596d0 Signed-off-by: Yong Wu Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071736 Reviewed-by: Chen-Yu Tsai Commit-Queue: ChromeOS Auto Retry Reviewed-by: Pin-yen Lin Kcr-patch: b51edd13e63c4f95764df64f5062318914f6729e7f02074eb1c25013.patch Signed-off-by: Hubert Mazur --- .../admin-guide/kernel-parameters.txt | 8 ++++ drivers/iommu/iova.c | 45 +++++++++++++------ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index f3e01d390fa08..116cf5d91682a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2263,6 +2263,14 @@ forcing Dual Address Cycle for PCI cards supporting greater than 32-bit addressing. + iommu.max_align_shift= + [ARM64, X86] Limit the alignment of IOVAs to a maximum + PAGE_SIZE order. Larger IOVAs will be aligned to this + specified order. The order is expressed as a power of + two multiplied by the PAGE_SIZE. + Format: { "4" | "5" | "6" | "7" | "8" | "9" } + Default: 9 + iommu.strict= [ARM64, X86] Configure TLB invalidation behaviour Format: { "0" | "1" } 0 - Lazy mode. diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index ef5bbb99ae18c..8f651698d6690 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -11,13 +11,16 @@ #include #include #include -#include +#include /* The anchor node sits above the top of the usable address space */ #define IOVA_ANCHOR ~0UL #define IOVA_RANGE_CACHE_MAX_SIZE 6 /* log of max cached IOVA range size (in pages) */ +#define IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT 9 +static unsigned long iommu_max_align_shift __read_mostly = IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT; + static bool iova_rcache_insert(struct iova_domain *iovad, unsigned long pfn, unsigned long size); @@ -32,6 +35,29 @@ unsigned long iova_rcache_range(void) return PAGE_SIZE << (IOVA_RANGE_CACHE_MAX_SIZE - 1); } +static unsigned long limit_align_shift(struct iova_domain *iovad, unsigned long shift) +{ + unsigned long max_align_shift; + + max_align_shift = iommu_max_align_shift + PAGE_SHIFT - iova_shift(iovad); + return min_t(unsigned long, max_align_shift, shift); +} + +#ifndef MODULE +static int __init iommu_set_def_max_align_shift(char *str) +{ + unsigned long max_align_shift; + + int ret = kstrtoul(str, 10, &max_align_shift); + + if (!ret) + iommu_max_align_shift = max_align_shift; + + return 0; +} +early_param("iommu.max_align_shift", iommu_set_def_max_align_shift); +#endif + static int iova_cpuhp_dead(unsigned int cpu, struct hlist_node *node) { struct iova_domain *iovad; @@ -188,11 +214,8 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, unsigned long align_mask = ~0UL; unsigned long high_pfn = limit_pfn, low_pfn = iovad->start_pfn; - if (size_aligned) { - unsigned long shift = fls_long(size - 1); - trace_android_rvh_iommu_limit_align_shift(iovad, size, &shift); - align_mask <<= shift; - } + if (size_aligned) + align_mask <<= limit_align_shift(iovad, fls_long(size - 1)); /* Walk the tree backwards */ spin_lock_irqsave(&iovad->iova_rbtree_lock, flags); @@ -321,18 +344,14 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, bool size_aligned) { struct iova *new_iova; - int ret = -1; + int ret; new_iova = alloc_iova_mem(); if (!new_iova) return NULL; - trace_android_rvh_iommu_alloc_insert_iova(iovad, size, limit_pfn + 1, - new_iova, size_aligned, &ret); - if (ret) { - ret = __alloc_and_insert_iova_range(iovad, size, - limit_pfn + 1, new_iova, size_aligned); - } + ret = __alloc_and_insert_iova_range(iovad, size, limit_pfn + 1, + new_iova, size_aligned); if (ret) { free_iova_mem(new_iova); -- GitLab From da85b917253e874a96b57a3590cc5584adacec7c Mon Sep 17 00:00:00 2001 From: Guodong Liu Date: Mon, 11 Nov 2024 16:53:46 +0800 Subject: [PATCH 301/456] FROMLIST: pinctrl: mediatek: Add support for MT8196 Add register address for each pin config. Add the function for each pin. Signed-off-by: Guodong Liu Cathy Xu (am from https://patchwork.kernel.org/patch/13870420/) (also found at https://lore.kernel.org/r/20241111085354.26576-1-ot_cathy.xu@mediatek.com) UPSTREAM-TASK=b:379035069 BUG=None TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I197d3ab27bf2a10321ae60c97f1a9f33eff8ded5 Signed-off-by: Xavier Chang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073683 Reviewed-by: Sean Paul Commit-Queue: ChromeOS Auto Retry Reviewed-by: Pin-yen Lin Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pinctrl/mediatek/Kconfig | 12 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt8196.c | 1757 +++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h | 2791 +++++++++++++++++ 4 files changed, 4561 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8196.c create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index 7af287252834a..e6eae3f3c4504 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -241,6 +241,18 @@ config PINCTRL_MT8195 default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS +config PINCTRL_MT8196 + bool "MediaTek MT8196 pin control" + depends on OF + depends on ARM64 || COMPILE_TEST + default ARM64 && ARCH_MEDIATEK + select PINCTRL_MTK_PARIS + help + Say yes here to support pin controller and gpio driver + on MediaTek MT8196 SoC. + In MTK platform, we support virtual gpio and use it to + map specific eint which doesn't have real gpio pin. + config PINCTRL_MT8365 bool "MediaTek MT8365 pin control" depends on OF diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index 680f7e8526e00..6d29673dd1995 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_PINCTRL_MT8186) += pinctrl-mt8186.o obj-$(CONFIG_PINCTRL_MT8188) += pinctrl-mt8188.o obj-$(CONFIG_PINCTRL_MT8192) += pinctrl-mt8192.o obj-$(CONFIG_PINCTRL_MT8195) += pinctrl-mt8195.o +obj-$(CONFIG_PINCTRL_MT8196) += pinctrl-mt8196.o obj-$(CONFIG_PINCTRL_MT8365) += pinctrl-mt8365.o obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8196.c b/drivers/pinctrl/mediatek/pinctrl-mt8196.c new file mode 100644 index 0000000000000..6d2bee7067187 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt8196.c @@ -0,0 +1,1757 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Mediatek Inc. + * Author: Guodong Liu + * + */ + +#include +#include "pinctrl-mtk-mt8196.h" +#include "pinctrl-paris.h" + +#define PIN_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 0) + +#define PINS_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 1) + +static const struct mtk_pin_field_calc mt8196_pin_mode_range[] = { + PIN_FIELD(0, 270, 0x0300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt8196_pin_dir_range[] = { + PIN_FIELD(0, 270, 0x0000, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_di_range[] = { + PIN_FIELD(0, 270, 0x0200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_do_range[] = { + PIN_FIELD(0, 270, 0x0100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, 8, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 8, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 11, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(3, 3, 11, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(4, 4, 11, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 11, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(6, 6, 11, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(7, 7, 11, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(8, 8, 11, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(9, 9, 9, 0x0120, 0x10, 13, 1), + PIN_FIELD_BASE(10, 10, 9, 0x0120, 0x10, 12, 1), + PIN_FIELD_BASE(11, 11, 8, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(12, 12, 9, 0x0120, 0x10, 15, 1), + PIN_FIELD_BASE(13, 13, 6, 0x0120, 0x10, 3, 1), + PIN_FIELD_BASE(14, 14, 3, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(15, 15, 6, 0x0120, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 6, 0x0120, 0x10, 3, 1), + PIN_FIELD_BASE(17, 17, 6, 0x0120, 0x10, 3, 1), + PIN_FIELD_BASE(18, 18, 6, 0x0120, 0x10, 1, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0120, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 3, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(21, 21, 2, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(22, 22, 2, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(23, 23, 2, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(24, 24, 2, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(25, 25, 2, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(26, 26, 2, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(27, 27, 2, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(28, 28, 2, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(29, 29, 2, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(30, 30, 2, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(31, 31, 2, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(32, 32, 1, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(33, 33, 1, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(34, 34, 1, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, 1, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(36, 36, 1, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(37, 37, 1, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(38, 38, 1, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(39, 39, 8, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(40, 40, 8, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(41, 41, 8, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(42, 42, 8, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(43, 43, 8, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(44, 44, 8, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(45, 45, 8, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(46, 46, 8, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(47, 47, 8, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(48, 48, 8, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(49, 49, 8, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(50, 50, 8, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(51, 51, 8, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(52, 52, 9, 0x0120, 0x10, 7, 1), + PIN_FIELD_BASE(53, 53, 9, 0x0120, 0x10, 8, 1), + PIN_FIELD_BASE(54, 54, 9, 0x0120, 0x10, 2, 1), + PIN_FIELD_BASE(55, 55, 9, 0x0120, 0x10, 1, 1), + PIN_FIELD_BASE(56, 56, 9, 0x0120, 0x10, 5, 1), + PIN_FIELD_BASE(57, 57, 9, 0x0120, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 9, 0x0120, 0x10, 3, 1), + PIN_FIELD_BASE(59, 59, 9, 0x0120, 0x10, 4, 1), + PIN_FIELD_BASE(60, 60, 9, 0x0120, 0x10, 19, 1), + PIN_FIELD_BASE(61, 61, 9, 0x0120, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, 9, 0x0120, 0x10, 9, 1), + PIN_FIELD_BASE(63, 63, 9, 0x0120, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, 9, 0x0120, 0x10, 0, 1), + PIN_FIELD_BASE(65, 65, 9, 0x0120, 0x10, 11, 1), + PIN_FIELD_BASE(66, 66, 9, 0x0120, 0x10, 16, 1), + PIN_FIELD_BASE(67, 67, 9, 0x0120, 0x10, 18, 1), + PIN_FIELD_BASE(68, 68, 9, 0x0120, 0x10, 18, 1), + PIN_FIELD_BASE(69, 69, 9, 0x0120, 0x10, 18, 1), + PIN_FIELD_BASE(70, 70, 9, 0x0120, 0x10, 17, 1), + PIN_FIELD_BASE(71, 71, 9, 0x0120, 0x10, 17, 1), + PIN_FIELD_BASE(72, 72, 9, 0x0120, 0x10, 18, 1), + PIN_FIELD_BASE(73, 73, 9, 0x0120, 0x10, 17, 1), + PIN_FIELD_BASE(74, 74, 9, 0x0120, 0x10, 17, 1), + PIN_FIELD_BASE(75, 75, 10, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(76, 76, 10, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(77, 77, 10, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(78, 78, 10, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(79, 79, 10, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(80, 80, 10, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(81, 81, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(82, 82, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(83, 83, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(84, 84, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(85, 85, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(86, 86, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(87, 87, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, 11, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(89, 89, 11, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(90, 90, 11, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(91, 91, 12, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(92, 92, 12, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(93, 93, 12, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(94, 94, 12, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(95, 95, 12, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(96, 96, 12, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(97, 97, 12, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(98, 98, 12, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(99, 99, 12, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(100, 100, 12, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(101, 101, 12, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(102, 102, 12, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(103, 103, 12, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(104, 104, 12, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(105, 105, 12, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(106, 106, 5, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(107, 107, 5, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(108, 108, 5, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(109, 109, 5, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(110, 110, 5, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(112, 112, 5, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(113, 113, 5, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(114, 114, 5, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(115, 115, 5, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(116, 116, 5, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(117, 117, 5, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0120, 0x10, 6, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0120, 0x10, 7, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0120, 0x10, 9, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0120, 0x10, 8, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0120, 0x10, 3, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0120, 0x10, 4, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0120, 0x10, 5, 1), + PIN_FIELD_BASE(125, 125, 7, 0x00f0, 0x10, 0, 1), + PIN_FIELD_BASE(126, 126, 7, 0x00f0, 0x10, 1, 1), + PIN_FIELD_BASE(127, 127, 7, 0x00f0, 0x10, 2, 1), + PIN_FIELD_BASE(128, 128, 7, 0x00f0, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 7, 0x00f0, 0x10, 4, 1), + PIN_FIELD_BASE(130, 130, 7, 0x00f0, 0x10, 5, 1), + PIN_FIELD_BASE(131, 131, 7, 0x00f0, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 7, 0x00f0, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 7, 0x00f0, 0x10, 10, 1), + PIN_FIELD_BASE(134, 134, 7, 0x00f0, 0x10, 6, 1), + PIN_FIELD_BASE(135, 135, 7, 0x00f0, 0x10, 8, 1), + PIN_FIELD_BASE(136, 136, 7, 0x00f0, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 4, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(138, 138, 4, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(139, 139, 4, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(140, 140, 4, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(141, 141, 4, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(142, 142, 4, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(143, 143, 4, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(144, 144, 4, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(145, 145, 4, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(146, 146, 4, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(147, 147, 4, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(148, 148, 4, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(149, 149, 4, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(150, 150, 4, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(151, 151, 4, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(152, 152, 4, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(153, 153, 4, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(154, 154, 4, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(155, 155, 4, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(156, 156, 4, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(157, 157, 2, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(158, 158, 2, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(159, 159, 2, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(160, 160, 3, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(161, 161, 3, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(162, 162, 3, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(163, 163, 3, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(164, 164, 3, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(165, 165, 3, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(166, 166, 3, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(167, 167, 3, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(168, 168, 3, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(169, 169, 3, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(170, 170, 3, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(171, 171, 3, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(172, 172, 3, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 3, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(174, 174, 1, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(175, 175, 1, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(176, 176, 1, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(177, 177, 1, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(178, 178, 1, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(179, 179, 1, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(180, 180, 1, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(181, 181, 1, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(182, 182, 1, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(183, 183, 1, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(184, 184, 1, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(185, 185, 1, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 13, 0x0110, 0x10, 14, 1), + PIN_FIELD_BASE(187, 187, 13, 0x0110, 0x10, 14, 1), + PIN_FIELD_BASE(188, 188, 13, 0x0110, 0x10, 4, 1), + PIN_FIELD_BASE(189, 189, 13, 0x0110, 0x10, 9, 1), + PIN_FIELD_BASE(190, 190, 13, 0x0110, 0x10, 5, 1), + PIN_FIELD_BASE(191, 191, 13, 0x0110, 0x10, 10, 1), + PIN_FIELD_BASE(192, 192, 13, 0x0110, 0x10, 0, 1), + PIN_FIELD_BASE(193, 193, 13, 0x0110, 0x10, 15, 1), + PIN_FIELD_BASE(194, 194, 13, 0x0110, 0x10, 6, 1), + PIN_FIELD_BASE(195, 195, 13, 0x0110, 0x10, 11, 1), + PIN_FIELD_BASE(196, 196, 13, 0x0110, 0x10, 1, 1), + PIN_FIELD_BASE(197, 197, 13, 0x0110, 0x10, 16, 1), + PIN_FIELD_BASE(198, 198, 13, 0x0110, 0x10, 7, 1), + PIN_FIELD_BASE(199, 199, 13, 0x0110, 0x10, 12, 1), + PIN_FIELD_BASE(200, 200, 13, 0x0110, 0x10, 19, 1), + PIN_FIELD_BASE(201, 201, 13, 0x0110, 0x10, 22, 1), + PIN_FIELD_BASE(202, 202, 13, 0x0110, 0x10, 8, 1), + PIN_FIELD_BASE(203, 203, 13, 0x0110, 0x10, 13, 1), + PIN_FIELD_BASE(204, 204, 13, 0x0110, 0x10, 2, 1), + PIN_FIELD_BASE(205, 205, 13, 0x0110, 0x10, 3, 1), + PIN_FIELD_BASE(206, 206, 13, 0x0110, 0x10, 18, 1), + PIN_FIELD_BASE(207, 207, 13, 0x0110, 0x10, 17, 1), + PIN_FIELD_BASE(208, 208, 13, 0x0110, 0x10, 17, 1), + PIN_FIELD_BASE(209, 209, 13, 0x0110, 0x10, 17, 1), + PIN_FIELD_BASE(210, 210, 14, 0x0130, 0x10, 0, 1), + PIN_FIELD_BASE(211, 211, 14, 0x0130, 0x10, 1, 1), + PIN_FIELD_BASE(212, 212, 14, 0x0130, 0x10, 2, 1), + PIN_FIELD_BASE(213, 213, 14, 0x0130, 0x10, 3, 1), + PIN_FIELD_BASE(214, 214, 13, 0x0110, 0x10, 20, 1), + PIN_FIELD_BASE(215, 215, 13, 0x0110, 0x10, 21, 1), + PIN_FIELD_BASE(216, 216, 14, 0x0130, 0x10, 11, 1), + PIN_FIELD_BASE(217, 217, 14, 0x0130, 0x10, 11, 1), + PIN_FIELD_BASE(218, 218, 14, 0x0130, 0x10, 11, 1), + PIN_FIELD_BASE(219, 219, 14, 0x0130, 0x10, 4, 1), + PIN_FIELD_BASE(220, 220, 14, 0x0130, 0x10, 11, 1), + PIN_FIELD_BASE(221, 221, 14, 0x0130, 0x10, 12, 1), + PIN_FIELD_BASE(222, 222, 14, 0x0130, 0x10, 22, 1), + PIN_FIELD_BASE(223, 223, 14, 0x0130, 0x10, 21, 1), + PIN_FIELD_BASE(224, 224, 14, 0x0130, 0x10, 5, 1), + PIN_FIELD_BASE(225, 225, 14, 0x0130, 0x10, 6, 1), + PIN_FIELD_BASE(226, 226, 14, 0x0130, 0x10, 7, 1), + PIN_FIELD_BASE(227, 227, 14, 0x0130, 0x10, 8, 1), + PIN_FIELD_BASE(228, 228, 14, 0x0130, 0x10, 9, 1), + PIN_FIELD_BASE(229, 229, 14, 0x0130, 0x10, 10, 1), + PIN_FIELD_BASE(230, 230, 15, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(231, 231, 15, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(232, 232, 15, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(233, 233, 15, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(234, 234, 15, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(235, 235, 15, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(236, 236, 15, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(237, 237, 15, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(238, 238, 15, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(239, 239, 15, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(240, 240, 15, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(241, 241, 15, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(242, 242, 15, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(243, 243, 15, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(244, 244, 15, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(245, 245, 15, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(246, 246, 15, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(247, 247, 15, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(248, 248, 15, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(249, 249, 15, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(250, 250, 15, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(251, 251, 3, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(252, 252, 3, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(253, 253, 3, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(254, 254, 3, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(255, 255, 3, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(256, 256, 3, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(257, 257, 3, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(258, 258, 3, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(259, 259, 14, 0x0130, 0x10, 13, 1), + PIN_FIELD_BASE(260, 260, 14, 0x0130, 0x10, 14, 1), + PIN_FIELD_BASE(261, 261, 14, 0x0130, 0x10, 15, 1), + PIN_FIELD_BASE(262, 262, 14, 0x0130, 0x10, 16, 1), + PIN_FIELD_BASE(263, 263, 14, 0x0130, 0x10, 17, 1), + PIN_FIELD_BASE(264, 264, 14, 0x0130, 0x10, 18, 1), + PIN_FIELD_BASE(265, 265, 14, 0x0130, 0x10, 19, 1), + PIN_FIELD_BASE(266, 266, 14, 0x0130, 0x10, 20, 1), + PIN_FIELD_BASE(267, 267, 15, 0x00e0, 0x10, 8, 1), + PIN_FIELD_BASE(268, 268, 15, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(269, 269, 15, 0x00e0, 0x10, 6, 1), + PIN_FIELD_BASE(270, 270, 15, 0x00e0, 0x10, 7, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, 8, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 8, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 11, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(3, 3, 11, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(4, 4, 11, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(5, 5, 11, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(6, 6, 11, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(7, 7, 11, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(8, 8, 11, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(9, 9, 9, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(10, 10, 9, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(11, 11, 8, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(12, 12, 9, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(13, 13, 6, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(14, 14, 3, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(15, 15, 6, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(16, 16, 6, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(17, 17, 6, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(18, 18, 6, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(20, 20, 3, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(21, 21, 2, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(22, 22, 2, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(23, 23, 2, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(24, 24, 2, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(25, 25, 2, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(26, 26, 2, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(27, 27, 2, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(28, 28, 2, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(29, 29, 2, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(30, 30, 2, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(31, 31, 2, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(33, 33, 1, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(39, 39, 8, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(40, 40, 8, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(41, 41, 8, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(42, 42, 8, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(43, 43, 8, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 8, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 8, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(46, 46, 8, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(47, 47, 8, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(48, 48, 8, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(49, 49, 8, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(50, 50, 8, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(51, 51, 8, 0x0060, 0x10, 15, 1), + PIN_FIELD_BASE(52, 52, 9, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(53, 53, 9, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(54, 54, 9, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(55, 55, 9, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(56, 56, 9, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(57, 57, 9, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 9, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(59, 59, 9, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(60, 60, 9, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(61, 61, 9, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, 9, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(63, 63, 9, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(64, 64, 9, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(65, 65, 9, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(66, 66, 9, 0x0070, 0x10, 24, 1), + PIN_FIELD_BASE(67, 67, 9, 0x0070, 0x10, 22, 1), + PIN_FIELD_BASE(68, 68, 9, 0x0070, 0x10, 21, 1), + PIN_FIELD_BASE(69, 69, 9, 0x0070, 0x10, 25, 1), + PIN_FIELD_BASE(70, 70, 9, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(71, 71, 9, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(72, 72, 9, 0x0070, 0x10, 23, 1), + PIN_FIELD_BASE(73, 73, 9, 0x0070, 0x10, 20, 1), + PIN_FIELD_BASE(74, 74, 9, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(75, 75, 10, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(76, 76, 10, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(77, 77, 10, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(78, 78, 10, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(79, 79, 10, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(80, 80, 10, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(81, 81, 11, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(82, 82, 11, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(83, 83, 11, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(84, 84, 11, 0x0040, 0x10, 11, 1), + PIN_FIELD_BASE(85, 85, 11, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(86, 86, 11, 0x0040, 0x10, 14, 1), + PIN_FIELD_BASE(87, 87, 11, 0x0040, 0x10, 16, 1), + PIN_FIELD_BASE(88, 88, 11, 0x0040, 0x10, 15, 1), + PIN_FIELD_BASE(89, 89, 11, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(90, 90, 11, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(91, 91, 12, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(92, 92, 12, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(93, 93, 12, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(94, 94, 12, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(95, 95, 12, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(96, 96, 12, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(97, 97, 12, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(98, 98, 12, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(99, 99, 12, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 12, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 12, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 12, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 12, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 12, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(105, 105, 12, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(106, 106, 5, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(107, 107, 5, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(108, 108, 5, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(109, 109, 5, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(116, 116, 5, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(117, 117, 5, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(125, 125, 7, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(126, 126, 7, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(127, 127, 7, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(128, 128, 7, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 7, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(130, 130, 7, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(131, 131, 7, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 7, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 7, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(134, 134, 7, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(135, 135, 7, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(136, 136, 7, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 4, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(138, 138, 4, 0x0040, 0x10, 11, 1), + PIN_FIELD_BASE(139, 139, 4, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(140, 140, 4, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(141, 141, 4, 0x0040, 0x10, 14, 1), + PIN_FIELD_BASE(142, 142, 4, 0x0040, 0x10, 15, 1), + PIN_FIELD_BASE(143, 143, 4, 0x0040, 0x10, 16, 1), + PIN_FIELD_BASE(144, 144, 4, 0x0040, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 4, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(146, 146, 4, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(147, 147, 4, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(148, 148, 4, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(149, 149, 4, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(150, 150, 4, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(151, 151, 4, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(152, 152, 4, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(153, 153, 4, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(154, 154, 4, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(155, 155, 4, 0x0040, 0x10, 18, 1), + PIN_FIELD_BASE(156, 156, 4, 0x0040, 0x10, 19, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(160, 160, 3, 0x0050, 0x10, 22, 1), + PIN_FIELD_BASE(161, 161, 3, 0x0050, 0x10, 20, 1), + PIN_FIELD_BASE(162, 162, 3, 0x0050, 0x10, 23, 1), + PIN_FIELD_BASE(163, 163, 3, 0x0050, 0x10, 21, 1), + PIN_FIELD_BASE(164, 164, 3, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(165, 165, 3, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(166, 166, 3, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(167, 167, 3, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(168, 168, 3, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0050, 0x10, 19, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(174, 174, 1, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(175, 175, 1, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(176, 176, 1, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(177, 177, 1, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(178, 178, 1, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(179, 179, 1, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(180, 180, 1, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(181, 181, 1, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(182, 182, 1, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(183, 183, 1, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 13, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(187, 187, 13, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(188, 188, 13, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(189, 189, 13, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(190, 190, 13, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(191, 191, 13, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(192, 192, 13, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(193, 193, 13, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(194, 194, 13, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(195, 195, 13, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(196, 196, 13, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(197, 197, 13, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(198, 198, 13, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(199, 199, 13, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(200, 200, 13, 0x0090, 0x10, 22, 1), + PIN_FIELD_BASE(201, 201, 13, 0x0090, 0x10, 25, 1), + PIN_FIELD_BASE(202, 202, 13, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(203, 203, 13, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(204, 204, 13, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(205, 205, 13, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(206, 206, 13, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(207, 207, 13, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(208, 208, 13, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(209, 209, 13, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(210, 210, 14, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(211, 211, 14, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(212, 212, 14, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(213, 213, 14, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(214, 214, 13, 0x0090, 0x10, 23, 1), + PIN_FIELD_BASE(215, 215, 13, 0x0090, 0x10, 24, 1), + PIN_FIELD_BASE(216, 216, 14, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(217, 217, 14, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(218, 218, 14, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(219, 219, 14, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(220, 220, 14, 0x0060, 0x10, 22, 1), + PIN_FIELD_BASE(221, 221, 14, 0x0060, 0x10, 23, 1), + PIN_FIELD_BASE(222, 222, 14, 0x0060, 0x10, 25, 1), + PIN_FIELD_BASE(223, 223, 14, 0x0060, 0x10, 24, 1), + PIN_FIELD_BASE(224, 224, 14, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(225, 225, 14, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(226, 226, 14, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(227, 227, 14, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(228, 228, 14, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(229, 229, 14, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(230, 230, 15, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(231, 231, 15, 0x0040, 0x10, 14, 1), + PIN_FIELD_BASE(232, 232, 15, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(233, 233, 15, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(234, 234, 15, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(235, 235, 15, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(236, 236, 15, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(237, 237, 15, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(238, 238, 15, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(239, 239, 15, 0x0040, 0x10, 23, 1), + PIN_FIELD_BASE(240, 240, 15, 0x0040, 0x10, 22, 1), + PIN_FIELD_BASE(241, 241, 15, 0x0040, 0x10, 16, 1), + PIN_FIELD_BASE(242, 242, 15, 0x0040, 0x10, 17, 1), + PIN_FIELD_BASE(243, 243, 15, 0x0040, 0x10, 15, 1), + PIN_FIELD_BASE(244, 244, 15, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(245, 245, 15, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(246, 246, 15, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(247, 247, 15, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(248, 248, 15, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(249, 249, 15, 0x0040, 0x10, 24, 1), + PIN_FIELD_BASE(250, 250, 15, 0x0040, 0x10, 11, 1), + PIN_FIELD_BASE(251, 251, 3, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(252, 252, 3, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(253, 253, 3, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(254, 254, 3, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(255, 255, 3, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(256, 256, 3, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(257, 257, 3, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(258, 258, 3, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(259, 259, 14, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(260, 260, 14, 0x0060, 0x10, 15, 1), + PIN_FIELD_BASE(261, 261, 14, 0x0060, 0x10, 16, 1), + PIN_FIELD_BASE(262, 262, 14, 0x0060, 0x10, 17, 1), + PIN_FIELD_BASE(263, 263, 14, 0x0060, 0x10, 18, 1), + PIN_FIELD_BASE(264, 264, 14, 0x0060, 0x10, 19, 1), + PIN_FIELD_BASE(265, 265, 14, 0x0060, 0x10, 20, 1), + PIN_FIELD_BASE(266, 266, 14, 0x0060, 0x10, 21, 1), + PIN_FIELD_BASE(267, 267, 15, 0x0040, 0x10, 20, 1), + PIN_FIELD_BASE(268, 268, 15, 0x0040, 0x10, 21, 1), + PIN_FIELD_BASE(269, 269, 15, 0x0040, 0x10, 18, 1), + PIN_FIELD_BASE(270, 270, 15, 0x0040, 0x10, 19, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_pupd_range[] = { + PIN_FIELD_BASE(60, 60, 9, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(125, 125, 7, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(126, 126, 7, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(127, 127, 7, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(128, 128, 7, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 7, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(130, 130, 7, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(131, 131, 7, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 7, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 7, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(134, 134, 7, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(135, 135, 7, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(136, 136, 7, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 4, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(138, 138, 4, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(139, 139, 4, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(140, 140, 4, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(141, 141, 4, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(142, 142, 4, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(143, 143, 4, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(144, 144, 4, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 4, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(146, 146, 4, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(147, 147, 4, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(148, 148, 4, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(149, 149, 4, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(150, 150, 4, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(151, 151, 4, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(152, 152, 4, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(153, 153, 4, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(154, 154, 4, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(155, 155, 4, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(156, 156, 4, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(217, 217, 14, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(218, 218, 14, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(219, 219, 14, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(224, 224, 14, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(225, 225, 14, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(226, 226, 14, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(227, 227, 14, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(228, 228, 14, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(229, 229, 14, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(259, 259, 14, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(260, 260, 14, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(261, 261, 14, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(262, 262, 14, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(263, 263, 14, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(264, 264, 14, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(265, 265, 14, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(266, 266, 14, 0x00a0, 0x10, 16, 1), + PIN_FIELD_BASE(267, 267, 15, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(268, 268, 15, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(269, 269, 15, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(270, 270, 15, 0x0080, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_r0_range[] = { + PIN_FIELD_BASE(60, 60, 9, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(125, 125, 7, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(126, 126, 7, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(127, 127, 7, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(128, 128, 7, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 7, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(130, 130, 7, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(131, 131, 7, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 7, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 7, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(134, 134, 7, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(135, 135, 7, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(136, 136, 7, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 4, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(138, 138, 4, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(139, 139, 4, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(140, 140, 4, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(141, 141, 4, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(142, 142, 4, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(143, 143, 4, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(144, 144, 4, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 4, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(146, 146, 4, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(147, 147, 4, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(148, 148, 4, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(149, 149, 4, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(150, 150, 4, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(151, 151, 4, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(152, 152, 4, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(153, 153, 4, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(154, 154, 4, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(155, 155, 4, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(156, 156, 4, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(217, 217, 14, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(218, 218, 14, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(219, 219, 14, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(224, 224, 14, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(225, 225, 14, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(226, 226, 14, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(227, 227, 14, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(228, 228, 14, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(229, 229, 14, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(259, 259, 14, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(260, 260, 14, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(261, 261, 14, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(262, 262, 14, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(263, 263, 14, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(264, 264, 14, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(265, 265, 14, 0x00c0, 0x10, 15, 1), + PIN_FIELD_BASE(266, 266, 14, 0x00c0, 0x10, 16, 1), + PIN_FIELD_BASE(267, 267, 15, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(268, 268, 15, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(269, 269, 15, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(270, 270, 15, 0x00a0, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_r1_range[] = { + PIN_FIELD_BASE(60, 60, 9, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(125, 125, 7, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(126, 126, 7, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(127, 127, 7, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(128, 128, 7, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 7, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(130, 130, 7, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(131, 131, 7, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 7, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 7, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(134, 134, 7, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(135, 135, 7, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(136, 136, 7, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 4, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(138, 138, 4, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(139, 139, 4, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(140, 140, 4, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(141, 141, 4, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(142, 142, 4, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(143, 143, 4, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(144, 144, 4, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 4, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(146, 146, 4, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(147, 147, 4, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(148, 148, 4, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(149, 149, 4, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(150, 150, 4, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(151, 151, 4, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(152, 152, 4, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(153, 153, 4, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(154, 154, 4, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(155, 155, 4, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(156, 156, 4, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(217, 217, 14, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(218, 218, 14, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(219, 219, 14, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(224, 224, 14, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(225, 225, 14, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(226, 226, 14, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(227, 227, 14, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(228, 228, 14, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(229, 229, 14, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(259, 259, 14, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(260, 260, 14, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(261, 261, 14, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(262, 262, 14, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(263, 263, 14, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(264, 264, 14, 0x00d0, 0x10, 14, 1), + PIN_FIELD_BASE(265, 265, 14, 0x00d0, 0x10, 15, 1), + PIN_FIELD_BASE(266, 266, 14, 0x00d0, 0x10, 16, 1), + PIN_FIELD_BASE(267, 267, 15, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(268, 268, 15, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(269, 269, 15, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(270, 270, 15, 0x00b0, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_pu_range[] = { + PIN_FIELD_BASE(0, 0, 8, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 8, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 11, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(3, 3, 11, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(4, 4, 11, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(5, 5, 11, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(6, 6, 11, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(7, 7, 11, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(8, 8, 11, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(9, 9, 9, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(10, 10, 9, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(11, 11, 8, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(12, 12, 9, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(13, 13, 6, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(14, 14, 3, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(15, 15, 6, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(16, 16, 6, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(17, 17, 6, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(18, 18, 6, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 6, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(20, 20, 3, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(21, 21, 2, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(22, 22, 2, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(23, 23, 2, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(24, 24, 2, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(25, 25, 2, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(26, 26, 2, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(27, 27, 2, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(28, 28, 2, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(29, 29, 2, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(30, 30, 2, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(31, 31, 2, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(33, 33, 1, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(39, 39, 8, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(40, 40, 8, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(41, 41, 8, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(42, 42, 8, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(43, 43, 8, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 8, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 8, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(46, 46, 8, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(47, 47, 8, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(48, 48, 8, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(49, 49, 8, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(50, 50, 8, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(51, 51, 8, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(52, 52, 9, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(53, 53, 9, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(54, 54, 9, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(55, 55, 9, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(56, 56, 9, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(57, 57, 9, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 9, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(59, 59, 9, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(61, 61, 9, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, 9, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(63, 63, 9, 0x00c0, 0x10, 18, 1), + PIN_FIELD_BASE(64, 64, 9, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(65, 65, 9, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(66, 66, 9, 0x00c0, 0x10, 24, 1), + PIN_FIELD_BASE(67, 67, 9, 0x00c0, 0x10, 21, 1), + PIN_FIELD_BASE(68, 68, 9, 0x00c0, 0x10, 20, 1), + PIN_FIELD_BASE(69, 69, 9, 0x00c0, 0x10, 25, 1), + PIN_FIELD_BASE(70, 70, 9, 0x00c0, 0x10, 16, 1), + PIN_FIELD_BASE(71, 71, 9, 0x00c0, 0x10, 15, 1), + PIN_FIELD_BASE(72, 72, 9, 0x00c0, 0x10, 23, 1), + PIN_FIELD_BASE(73, 73, 9, 0x00c0, 0x10, 19, 1), + PIN_FIELD_BASE(74, 74, 9, 0x00c0, 0x10, 17, 1), + PIN_FIELD_BASE(75, 75, 10, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(76, 76, 10, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(77, 77, 10, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(78, 78, 10, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(79, 79, 10, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(80, 80, 10, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(81, 81, 11, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(82, 82, 11, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(83, 83, 11, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(84, 84, 11, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(85, 85, 11, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(86, 86, 11, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(87, 87, 11, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(88, 88, 11, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(89, 89, 11, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(90, 90, 11, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(91, 91, 12, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(92, 92, 12, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(93, 93, 12, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(94, 94, 12, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(95, 95, 12, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(96, 96, 12, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(97, 97, 12, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(98, 98, 12, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(99, 99, 12, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 12, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 12, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 12, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 12, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 12, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(105, 105, 12, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(106, 106, 5, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(107, 107, 5, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(108, 108, 5, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(109, 109, 5, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(116, 116, 5, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(117, 117, 5, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(118, 118, 6, 0x00b0, 0x10, 9, 1), + PIN_FIELD_BASE(119, 119, 6, 0x00b0, 0x10, 10, 1), + PIN_FIELD_BASE(120, 120, 6, 0x00b0, 0x10, 12, 1), + PIN_FIELD_BASE(121, 121, 6, 0x00b0, 0x10, 11, 1), + PIN_FIELD_BASE(122, 122, 6, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(124, 124, 6, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(160, 160, 3, 0x0090, 0x10, 22, 1), + PIN_FIELD_BASE(161, 161, 3, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(162, 162, 3, 0x0090, 0x10, 23, 1), + PIN_FIELD_BASE(163, 163, 3, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(164, 164, 3, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(165, 165, 3, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(166, 166, 3, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(167, 167, 3, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(168, 168, 3, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(174, 174, 1, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(175, 175, 1, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(176, 176, 1, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(177, 177, 1, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(178, 178, 1, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(179, 179, 1, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(180, 180, 1, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(181, 181, 1, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(182, 182, 1, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(183, 183, 1, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 13, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(187, 187, 13, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(188, 188, 13, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(189, 189, 13, 0x00d0, 0x10, 17, 1), + PIN_FIELD_BASE(190, 190, 13, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(191, 191, 13, 0x00d0, 0x10, 18, 1), + PIN_FIELD_BASE(192, 192, 13, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(193, 193, 13, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(194, 194, 13, 0x00d0, 0x10, 14, 1), + PIN_FIELD_BASE(195, 195, 13, 0x00d0, 0x10, 19, 1), + PIN_FIELD_BASE(196, 196, 13, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(197, 197, 13, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(198, 198, 13, 0x00d0, 0x10, 15, 1), + PIN_FIELD_BASE(199, 199, 13, 0x00d0, 0x10, 20, 1), + PIN_FIELD_BASE(200, 200, 13, 0x00d0, 0x10, 22, 1), + PIN_FIELD_BASE(201, 201, 13, 0x00d0, 0x10, 25, 1), + PIN_FIELD_BASE(202, 202, 13, 0x00d0, 0x10, 16, 1), + PIN_FIELD_BASE(203, 203, 13, 0x00d0, 0x10, 21, 1), + PIN_FIELD_BASE(204, 204, 13, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(205, 205, 13, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(206, 206, 13, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(207, 207, 13, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(208, 208, 13, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(209, 209, 13, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(210, 210, 14, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(211, 211, 14, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(212, 212, 14, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(213, 213, 14, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(214, 214, 13, 0x00d0, 0x10, 23, 1), + PIN_FIELD_BASE(215, 215, 13, 0x00d0, 0x10, 24, 1), + PIN_FIELD_BASE(216, 216, 14, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(220, 220, 14, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(221, 221, 14, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(222, 222, 14, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(223, 223, 14, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(230, 230, 15, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(231, 231, 15, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(232, 232, 15, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(233, 233, 15, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(234, 234, 15, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(235, 235, 15, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(236, 236, 15, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(237, 237, 15, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(238, 238, 15, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(239, 239, 15, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(240, 240, 15, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(241, 241, 15, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(242, 242, 15, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(243, 243, 15, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(244, 244, 15, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(245, 245, 15, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(246, 246, 15, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(247, 247, 15, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(248, 248, 15, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(249, 249, 15, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(250, 250, 15, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(251, 251, 3, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(252, 252, 3, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(253, 253, 3, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(254, 254, 3, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(255, 255, 3, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(256, 256, 3, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(257, 257, 3, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(258, 258, 3, 0x0090, 0x10, 9, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_pd_range[] = { + PIN_FIELD_BASE(0, 0, 8, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 8, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 11, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(3, 3, 11, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(4, 4, 11, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(5, 5, 11, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(6, 6, 11, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(7, 7, 11, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(8, 8, 11, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(9, 9, 9, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(10, 10, 9, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(11, 11, 8, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(12, 12, 9, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(13, 13, 6, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(14, 14, 3, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(15, 15, 6, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(16, 16, 6, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(17, 17, 6, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(18, 18, 6, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(20, 20, 3, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(21, 21, 2, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(22, 22, 2, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(23, 23, 2, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(24, 24, 2, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(25, 25, 2, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(26, 26, 2, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(27, 27, 2, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(28, 28, 2, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(29, 29, 2, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(30, 30, 2, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(31, 31, 2, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(33, 33, 1, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(39, 39, 8, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(40, 40, 8, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(41, 41, 8, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(42, 42, 8, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(43, 43, 8, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 8, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 8, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(46, 46, 8, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(47, 47, 8, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(48, 48, 8, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(49, 49, 8, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(50, 50, 8, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(51, 51, 8, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(52, 52, 9, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(53, 53, 9, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(54, 54, 9, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(55, 55, 9, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(56, 56, 9, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(57, 57, 9, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 9, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(59, 59, 9, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(61, 61, 9, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, 9, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(63, 63, 9, 0x00a0, 0x10, 18, 1), + PIN_FIELD_BASE(64, 64, 9, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(65, 65, 9, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(66, 66, 9, 0x00a0, 0x10, 24, 1), + PIN_FIELD_BASE(67, 67, 9, 0x00a0, 0x10, 21, 1), + PIN_FIELD_BASE(68, 68, 9, 0x00a0, 0x10, 20, 1), + PIN_FIELD_BASE(69, 69, 9, 0x00a0, 0x10, 25, 1), + PIN_FIELD_BASE(70, 70, 9, 0x00a0, 0x10, 16, 1), + PIN_FIELD_BASE(71, 71, 9, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(72, 72, 9, 0x00a0, 0x10, 23, 1), + PIN_FIELD_BASE(73, 73, 9, 0x00a0, 0x10, 19, 1), + PIN_FIELD_BASE(74, 74, 9, 0x00a0, 0x10, 17, 1), + PIN_FIELD_BASE(75, 75, 10, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(76, 76, 10, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(77, 77, 10, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(78, 78, 10, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(79, 79, 10, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(80, 80, 10, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(81, 81, 11, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(82, 82, 11, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(83, 83, 11, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(84, 84, 11, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(85, 85, 11, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(86, 86, 11, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(87, 87, 11, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(88, 88, 11, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(89, 89, 11, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(90, 90, 11, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(91, 91, 12, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(92, 92, 12, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(93, 93, 12, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(94, 94, 12, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(95, 95, 12, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(96, 96, 12, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(97, 97, 12, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(98, 98, 12, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(99, 99, 12, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 12, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 12, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 12, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 12, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 12, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(105, 105, 12, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(106, 106, 5, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(107, 107, 5, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(108, 108, 5, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(109, 109, 5, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(116, 116, 5, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(117, 117, 5, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(160, 160, 3, 0x0080, 0x10, 22, 1), + PIN_FIELD_BASE(161, 161, 3, 0x0080, 0x10, 20, 1), + PIN_FIELD_BASE(162, 162, 3, 0x0080, 0x10, 23, 1), + PIN_FIELD_BASE(163, 163, 3, 0x0080, 0x10, 21, 1), + PIN_FIELD_BASE(164, 164, 3, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(165, 165, 3, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(166, 166, 3, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(167, 167, 3, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(168, 168, 3, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(174, 174, 1, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(175, 175, 1, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(176, 176, 1, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(177, 177, 1, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(178, 178, 1, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(179, 179, 1, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(180, 180, 1, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(181, 181, 1, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(182, 182, 1, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(183, 183, 1, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 13, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(187, 187, 13, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(188, 188, 13, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(189, 189, 13, 0x00c0, 0x10, 17, 1), + PIN_FIELD_BASE(190, 190, 13, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(191, 191, 13, 0x00c0, 0x10, 18, 1), + PIN_FIELD_BASE(192, 192, 13, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(193, 193, 13, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(194, 194, 13, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(195, 195, 13, 0x00c0, 0x10, 19, 1), + PIN_FIELD_BASE(196, 196, 13, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(197, 197, 13, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(198, 198, 13, 0x00c0, 0x10, 15, 1), + PIN_FIELD_BASE(199, 199, 13, 0x00c0, 0x10, 20, 1), + PIN_FIELD_BASE(200, 200, 13, 0x00c0, 0x10, 22, 1), + PIN_FIELD_BASE(201, 201, 13, 0x00c0, 0x10, 25, 1), + PIN_FIELD_BASE(202, 202, 13, 0x00c0, 0x10, 16, 1), + PIN_FIELD_BASE(203, 203, 13, 0x00c0, 0x10, 21, 1), + PIN_FIELD_BASE(204, 204, 13, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(205, 205, 13, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(206, 206, 13, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(207, 207, 13, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(208, 208, 13, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(209, 209, 13, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(210, 210, 14, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(211, 211, 14, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(212, 212, 14, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(213, 213, 14, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(214, 214, 13, 0x00c0, 0x10, 23, 1), + PIN_FIELD_BASE(215, 215, 13, 0x00c0, 0x10, 24, 1), + PIN_FIELD_BASE(216, 216, 14, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(220, 220, 14, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(221, 221, 14, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(222, 222, 14, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(223, 223, 14, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(230, 230, 15, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(231, 231, 15, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(232, 232, 15, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(233, 233, 15, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(234, 234, 15, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(235, 235, 15, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(236, 236, 15, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(237, 237, 15, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(238, 238, 15, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(239, 239, 15, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(240, 240, 15, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(241, 241, 15, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(242, 242, 15, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(243, 243, 15, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(244, 244, 15, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(245, 245, 15, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(246, 246, 15, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(247, 247, 15, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(248, 248, 15, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(249, 249, 15, 0x0070, 0x10, 20, 1), + PIN_FIELD_BASE(250, 250, 15, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(251, 251, 3, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(252, 252, 3, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(253, 253, 3, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(254, 254, 3, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(255, 255, 3, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(256, 256, 3, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(257, 257, 3, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(258, 258, 3, 0x0080, 0x10, 9, 1), +}; + +static const struct mtk_pin_field_calc mt8196_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, 8, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(1, 1, 8, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(2, 2, 11, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(3, 3, 11, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(4, 4, 11, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(5, 5, 11, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(6, 6, 11, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(7, 7, 11, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(8, 8, 11, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(9, 9, 9, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(10, 10, 9, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(11, 11, 8, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(12, 12, 9, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(13, 13, 6, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(14, 14, 3, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(15, 15, 6, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(16, 16, 6, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(17, 17, 6, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(18, 18, 6, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(19, 19, 6, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(20, 20, 3, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(21, 21, 2, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(22, 22, 2, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(23, 23, 2, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(24, 24, 2, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(25, 25, 2, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(26, 26, 2, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(27, 27, 2, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(28, 28, 2, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(29, 29, 2, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(30, 30, 2, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(31, 31, 2, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(32, 32, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(33, 33, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(34, 34, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(35, 35, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(36, 36, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(37, 37, 1, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(38, 38, 1, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(39, 39, 8, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(40, 40, 8, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(41, 41, 8, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(42, 42, 8, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(43, 43, 8, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(44, 44, 8, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(45, 45, 8, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(46, 46, 8, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(47, 47, 8, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(48, 48, 8, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(49, 49, 8, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(50, 50, 8, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(51, 51, 8, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(52, 52, 9, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(53, 53, 9, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(54, 54, 9, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(55, 55, 9, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(56, 56, 9, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(57, 57, 9, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(58, 58, 9, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(59, 59, 9, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(60, 60, 9, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(61, 61, 9, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(62, 62, 9, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(63, 63, 9, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(64, 64, 9, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(65, 65, 9, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(66, 66, 9, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(67, 67, 9, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(68, 68, 9, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(69, 69, 9, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(70, 70, 9, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(71, 71, 9, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(72, 72, 9, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(73, 73, 9, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(74, 74, 9, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(75, 75, 10, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(76, 76, 10, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(77, 77, 10, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(78, 78, 10, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(79, 79, 10, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(80, 80, 10, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(81, 81, 11, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(82, 82, 11, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(83, 83, 11, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(84, 84, 11, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(85, 85, 11, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(86, 86, 11, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(87, 87, 11, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(88, 88, 11, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(89, 89, 11, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(90, 90, 11, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(91, 91, 12, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(92, 92, 12, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(93, 93, 12, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(94, 94, 12, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(95, 95, 12, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(96, 96, 12, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(97, 97, 12, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(98, 98, 12, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(99, 99, 12, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(100, 100, 12, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(101, 101, 12, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(102, 102, 12, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(103, 103, 12, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(104, 104, 12, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(105, 105, 12, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(106, 106, 5, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(107, 107, 5, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(108, 108, 5, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(109, 109, 5, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(110, 110, 5, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(111, 111, 5, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(112, 112, 5, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(113, 113, 5, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(114, 114, 5, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(115, 115, 5, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(116, 116, 5, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(117, 117, 5, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(118, 118, 6, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(119, 119, 6, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(120, 120, 6, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(121, 121, 6, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(122, 122, 6, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(123, 123, 6, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(124, 124, 6, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(125, 125, 7, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(126, 126, 7, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(127, 127, 7, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(128, 128, 7, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(129, 129, 7, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(130, 130, 7, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(131, 131, 7, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(132, 132, 7, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(133, 133, 7, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(134, 134, 7, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(135, 135, 7, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(136, 136, 7, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(137, 137, 4, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(138, 138, 4, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(139, 139, 4, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(140, 140, 4, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(141, 141, 4, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(142, 142, 4, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(143, 143, 4, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(144, 144, 4, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(145, 145, 4, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(146, 146, 4, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(147, 147, 4, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(148, 148, 4, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(149, 149, 4, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(150, 150, 4, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(151, 151, 4, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(152, 152, 4, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(153, 153, 4, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(154, 154, 4, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(155, 155, 4, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(156, 156, 4, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(157, 157, 2, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(158, 158, 2, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(159, 159, 2, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(160, 160, 3, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(161, 161, 3, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(162, 162, 3, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(163, 163, 3, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(164, 164, 3, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(165, 165, 3, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(166, 166, 3, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(167, 167, 3, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(168, 168, 3, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(169, 169, 3, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(170, 170, 3, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(171, 171, 3, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(172, 172, 3, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(173, 173, 3, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(174, 174, 1, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(175, 175, 1, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(176, 176, 1, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(177, 177, 1, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(178, 178, 1, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(179, 179, 1, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(180, 180, 1, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(181, 181, 1, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(182, 182, 1, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(183, 183, 1, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(184, 184, 1, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(185, 185, 1, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(186, 186, 13, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(187, 187, 13, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(188, 188, 13, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(189, 189, 13, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(190, 190, 13, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(191, 191, 13, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(192, 192, 13, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(193, 193, 13, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(194, 194, 13, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(195, 195, 13, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(196, 196, 13, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(197, 197, 13, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(198, 198, 13, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(199, 199, 13, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(200, 200, 13, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(201, 201, 13, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(202, 202, 13, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(203, 203, 13, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(204, 204, 13, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(205, 205, 13, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(206, 206, 13, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(207, 207, 13, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(208, 208, 13, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(209, 209, 13, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(210, 210, 14, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(211, 211, 14, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(212, 212, 14, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(213, 213, 14, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(214, 214, 13, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(215, 215, 13, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(216, 216, 14, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(217, 217, 14, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(218, 218, 14, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(219, 219, 14, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(220, 220, 14, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(221, 221, 14, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(222, 222, 14, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(223, 223, 14, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(224, 224, 14, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(225, 225, 14, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(226, 226, 14, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(227, 227, 14, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(228, 228, 14, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(229, 229, 14, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(230, 230, 15, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(231, 231, 15, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(232, 232, 15, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(233, 233, 15, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(234, 234, 15, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(235, 235, 15, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(236, 236, 15, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(237, 237, 15, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(238, 238, 15, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(239, 239, 15, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(240, 240, 15, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(241, 241, 15, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(242, 242, 15, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(243, 243, 15, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(244, 244, 15, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(245, 245, 15, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(246, 246, 15, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(247, 247, 15, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(248, 248, 15, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(249, 249, 15, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(250, 250, 15, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(251, 251, 3, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(252, 252, 3, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(253, 253, 3, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(254, 254, 3, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(255, 255, 3, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(256, 256, 3, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(257, 257, 3, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(258, 258, 3, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(259, 259, 14, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(260, 260, 14, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(261, 261, 14, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(262, 262, 14, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(263, 263, 14, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(264, 264, 14, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(265, 265, 14, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(266, 266, 14, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(267, 267, 15, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(268, 268, 15, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(269, 269, 15, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(270, 270, 15, 0x0000, 0x10, 21, 3), +}; + +static const struct mtk_pin_field_calc mt8196_pin_drv_adv_range[] = { + PIN_FIELD_BASE(46, 46, 8, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(47, 47, 8, 0x0030, 0x10, 9, 3), + PIN_FIELD_BASE(48, 48, 8, 0x0030, 0x10, 3, 3), + PIN_FIELD_BASE(49, 49, 8, 0x0030, 0x10, 12, 3), + PIN_FIELD_BASE(50, 50, 8, 0x0030, 0x10, 6, 3), + PIN_FIELD_BASE(51, 51, 8, 0x0030, 0x10, 15, 3), + PIN_FIELD_BASE(52, 52, 9, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(53, 53, 9, 0x0030, 0x10, 3, 3), + PIN_FIELD_BASE(75, 75, 10, 0x0020, 0x10, 0, 5), + PIN_FIELD_BASE(76, 76, 10, 0x0020, 0x10, 5, 5), + PIN_FIELD_BASE(77, 77, 10, 0x0020, 0x10, 10, 5), + PIN_FIELD_BASE(78, 78, 10, 0x0020, 0x10, 15, 5), + PIN_FIELD_BASE(99, 99, 12, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(100, 100, 12, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(101, 101, 12, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(102, 102, 12, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(104, 104, 12, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(105, 105, 12, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(123, 123, 6, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(124, 124, 6, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(164, 164, 3, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(165, 165, 3, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(166, 166, 3, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(167, 167, 3, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(168, 168, 3, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(170, 170, 3, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(176, 176, 1, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(177, 177, 1, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(188, 188, 13, 0x0040, 0x10, 0, 3), + PIN_FIELD_BASE(189, 189, 13, 0x0040, 0x10, 15, 3), + PIN_FIELD_BASE(190, 190, 13, 0x0040, 0x10, 3, 3), + PIN_FIELD_BASE(191, 191, 13, 0x0040, 0x10, 18, 3), + PIN_FIELD_BASE(194, 194, 13, 0x0040, 0x10, 6, 3), + PIN_FIELD_BASE(195, 195, 13, 0x0040, 0x10, 21, 3), + PIN_FIELD_BASE(198, 198, 13, 0x0040, 0x10, 9, 3), + PIN_FIELD_BASE(199, 199, 13, 0x0040, 0x10, 24, 3), + PIN_FIELD_BASE(200, 200, 13, 0x0050, 0x10, 0, 3), + PIN_FIELD_BASE(201, 201, 13, 0x0050, 0x10, 9, 3), + PIN_FIELD_BASE(202, 202, 13, 0x0040, 0x10, 12, 3), + PIN_FIELD_BASE(203, 203, 13, 0x0040, 0x10, 27, 3), + PIN_FIELD_BASE(214, 214, 13, 0x0050, 0x10, 3, 3), + PIN_FIELD_BASE(215, 215, 13, 0x0050, 0x10, 6, 3), +}; + +static const struct mtk_pin_field_calc mt8196_pin_rsel_range[] = { + PIN_FIELD_BASE(46, 46, 8, 0x00c0, 0x10, 0, 3), + PIN_FIELD_BASE(47, 47, 8, 0x00c0, 0x10, 9, 3), + PIN_FIELD_BASE(48, 48, 8, 0x00c0, 0x10, 3, 3), + PIN_FIELD_BASE(49, 49, 8, 0x00c0, 0x10, 12, 3), + PIN_FIELD_BASE(50, 50, 8, 0x00c0, 0x10, 6, 3), + PIN_FIELD_BASE(51, 51, 8, 0x00c0, 0x10, 15, 3), + PIN_FIELD_BASE(52, 52, 9, 0x0110, 0x10, 0, 3), + PIN_FIELD_BASE(53, 53, 9, 0x0110, 0x10, 3, 3), + PIN_FIELD_BASE(99, 99, 12, 0x00b0, 0x10, 0, 3), + PIN_FIELD_BASE(100, 100, 12, 0x00b0, 0x10, 9, 3), + PIN_FIELD_BASE(101, 101, 12, 0x00b0, 0x10, 3, 3), + PIN_FIELD_BASE(102, 102, 12, 0x00b0, 0x10, 12, 3), + PIN_FIELD_BASE(104, 104, 12, 0x00b0, 0x10, 6, 3), + PIN_FIELD_BASE(105, 105, 12, 0x00b0, 0x10, 15, 3), + PIN_FIELD_BASE(123, 123, 6, 0x0100, 0x10, 0, 3), + PIN_FIELD_BASE(124, 124, 6, 0x0100, 0x10, 3, 3), + PIN_FIELD_BASE(164, 164, 3, 0x00b0, 0x10, 0, 3), + PIN_FIELD_BASE(165, 165, 3, 0x00b0, 0x10, 6, 3), + PIN_FIELD_BASE(166, 166, 3, 0x00b0, 0x10, 3, 3), + PIN_FIELD_BASE(167, 167, 3, 0x00b0, 0x10, 9, 3), + PIN_FIELD_BASE(168, 168, 3, 0x00b0, 0x10, 12, 3), + PIN_FIELD_BASE(170, 170, 3, 0x00b0, 0x10, 15, 3), + PIN_FIELD_BASE(176, 176, 1, 0x00b0, 0x10, 0, 3), + PIN_FIELD_BASE(177, 177, 1, 0x00b0, 0x10, 3, 3), + PIN_FIELD_BASE(188, 188, 13, 0x00f0, 0x10, 0, 3), + PIN_FIELD_BASE(189, 189, 13, 0x00f0, 0x10, 15, 3), + PIN_FIELD_BASE(190, 190, 13, 0x00f0, 0x10, 3, 3), + PIN_FIELD_BASE(191, 191, 13, 0x00f0, 0x10, 18, 3), + PIN_FIELD_BASE(194, 194, 13, 0x00f0, 0x10, 6, 3), + PIN_FIELD_BASE(195, 195, 13, 0x00f0, 0x10, 21, 3), + PIN_FIELD_BASE(198, 198, 13, 0x00f0, 0x10, 9, 3), + PIN_FIELD_BASE(199, 199, 13, 0x00f0, 0x10, 24, 3), + PIN_FIELD_BASE(200, 200, 13, 0x0100, 0x10, 0, 3), + PIN_FIELD_BASE(201, 201, 13, 0x0100, 0x10, 9, 3), + PIN_FIELD_BASE(202, 202, 13, 0x00f0, 0x10, 12, 3), + PIN_FIELD_BASE(203, 203, 13, 0x00f0, 0x10, 27, 3), + PIN_FIELD_BASE(214, 214, 13, 0x0100, 0x10, 3, 3), + PIN_FIELD_BASE(215, 215, 13, 0x0100, 0x10, 6, 3), +}; + +static const unsigned int mt8196_pull_type[] = { + MTK_PULL_PU_PD_TYPE,/*0*/ MTK_PULL_PU_PD_TYPE,/*1*/ + MTK_PULL_PU_PD_TYPE,/*2*/ MTK_PULL_PU_PD_TYPE,/*3*/ + MTK_PULL_PU_PD_TYPE,/*4*/ MTK_PULL_PU_PD_TYPE,/*5*/ + MTK_PULL_PU_PD_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE,/*7*/ + MTK_PULL_PU_PD_TYPE,/*8*/ MTK_PULL_PU_PD_TYPE,/*9*/ + MTK_PULL_PU_PD_TYPE,/*10*/ MTK_PULL_PU_PD_TYPE,/*11*/ + MTK_PULL_PU_PD_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE,/*13*/ + MTK_PULL_PU_PD_TYPE,/*14*/ MTK_PULL_PU_PD_TYPE,/*15*/ + MTK_PULL_PU_PD_TYPE,/*16*/ MTK_PULL_PU_PD_TYPE,/*17*/ + MTK_PULL_PU_PD_TYPE,/*18*/ MTK_PULL_PU_PD_TYPE,/*19*/ + MTK_PULL_PU_PD_TYPE,/*20*/ MTK_PULL_PU_PD_TYPE,/*21*/ + MTK_PULL_PU_PD_TYPE,/*22*/ MTK_PULL_PU_PD_TYPE,/*23*/ + MTK_PULL_PU_PD_TYPE,/*24*/ MTK_PULL_PU_PD_TYPE,/*25*/ + MTK_PULL_PU_PD_TYPE,/*26*/ MTK_PULL_PU_PD_TYPE,/*27*/ + MTK_PULL_PU_PD_TYPE,/*28*/ MTK_PULL_PU_PD_TYPE,/*29*/ + MTK_PULL_PU_PD_TYPE,/*30*/ MTK_PULL_PU_PD_TYPE,/*31*/ + MTK_PULL_PU_PD_TYPE,/*32*/ MTK_PULL_PU_PD_TYPE,/*33*/ + MTK_PULL_PU_PD_TYPE,/*34*/ MTK_PULL_PU_PD_TYPE,/*35*/ + MTK_PULL_PU_PD_TYPE,/*36*/ MTK_PULL_PU_PD_TYPE,/*37*/ + MTK_PULL_PU_PD_TYPE,/*38*/ MTK_PULL_PU_PD_TYPE,/*39*/ + MTK_PULL_PU_PD_TYPE,/*40*/ MTK_PULL_PU_PD_TYPE,/*41*/ + MTK_PULL_PU_PD_TYPE,/*42*/ MTK_PULL_PU_PD_TYPE,/*43*/ + MTK_PULL_PU_PD_TYPE,/*44*/ MTK_PULL_PU_PD_TYPE,/*45*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*46*/ MTK_PULL_PU_PD_RSEL_TYPE,/*47*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*48*/ MTK_PULL_PU_PD_RSEL_TYPE,/*49*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*50*/ MTK_PULL_PU_PD_RSEL_TYPE,/*51*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*52*/ MTK_PULL_PU_PD_RSEL_TYPE,/*53*/ + MTK_PULL_PU_PD_TYPE,/*54*/ MTK_PULL_PU_PD_TYPE,/*55*/ + MTK_PULL_PU_PD_TYPE,/*56*/ MTK_PULL_PU_PD_TYPE,/*57*/ + MTK_PULL_PU_PD_TYPE,/*58*/ MTK_PULL_PU_PD_TYPE,/*59*/ + MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PU_PD_TYPE,/*61*/ + MTK_PULL_PU_PD_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE,/*63*/ + MTK_PULL_PU_PD_TYPE,/*64*/ MTK_PULL_PU_PD_TYPE,/*65*/ + MTK_PULL_PU_PD_TYPE,/*66*/ MTK_PULL_PU_PD_TYPE,/*67*/ + MTK_PULL_PU_PD_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/ + MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/ + MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/ + MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/ + MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/ + MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/ + MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/ + MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/ + MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/ + MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/ + MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/ + MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/ + MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/ + MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/ + MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/ + MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_RSEL_TYPE,/*99*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*100*/ MTK_PULL_PU_PD_RSEL_TYPE,/*101*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*102*/ MTK_PULL_PU_PD_TYPE,/*103*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*104*/ MTK_PULL_PU_PD_RSEL_TYPE,/*105*/ + MTK_PULL_PU_PD_TYPE,/*106*/ MTK_PULL_PU_PD_TYPE,/*107*/ + MTK_PULL_PU_PD_TYPE,/*108*/ MTK_PULL_PU_PD_TYPE,/*109*/ + MTK_PULL_PU_PD_TYPE,/*110*/ MTK_PULL_PU_PD_TYPE,/*111*/ + MTK_PULL_PU_PD_TYPE,/*112*/ MTK_PULL_PU_PD_TYPE,/*113*/ + MTK_PULL_PU_PD_TYPE,/*114*/ MTK_PULL_PU_PD_TYPE,/*115*/ + MTK_PULL_PU_PD_TYPE,/*116*/ MTK_PULL_PU_PD_TYPE,/*117*/ + MTK_PULL_PU_PD_TYPE,/*118*/ MTK_PULL_PU_PD_TYPE,/*119*/ + MTK_PULL_PU_PD_TYPE,/*120*/ MTK_PULL_PU_PD_TYPE,/*121*/ + MTK_PULL_PU_PD_TYPE,/*122*/ MTK_PULL_PU_PD_RSEL_TYPE,/*123*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*124*/ MTK_PULL_PUPD_R1R0_TYPE,/*125*/ + MTK_PULL_PUPD_R1R0_TYPE,/*126*/ MTK_PULL_PUPD_R1R0_TYPE,/*127*/ + MTK_PULL_PUPD_R1R0_TYPE,/*128*/ MTK_PULL_PUPD_R1R0_TYPE,/*129*/ + MTK_PULL_PUPD_R1R0_TYPE,/*130*/ MTK_PULL_PUPD_R1R0_TYPE,/*131*/ + MTK_PULL_PUPD_R1R0_TYPE,/*132*/ MTK_PULL_PUPD_R1R0_TYPE,/*133*/ + MTK_PULL_PUPD_R1R0_TYPE,/*134*/ MTK_PULL_PUPD_R1R0_TYPE,/*135*/ + MTK_PULL_PUPD_R1R0_TYPE,/*136*/ MTK_PULL_PUPD_R1R0_TYPE,/*137*/ + MTK_PULL_PUPD_R1R0_TYPE,/*138*/ MTK_PULL_PUPD_R1R0_TYPE,/*139*/ + MTK_PULL_PUPD_R1R0_TYPE,/*140*/ MTK_PULL_PUPD_R1R0_TYPE,/*141*/ + MTK_PULL_PUPD_R1R0_TYPE,/*142*/ MTK_PULL_PUPD_R1R0_TYPE,/*143*/ + MTK_PULL_PUPD_R1R0_TYPE,/*144*/ MTK_PULL_PUPD_R1R0_TYPE,/*145*/ + MTK_PULL_PUPD_R1R0_TYPE,/*146*/ MTK_PULL_PUPD_R1R0_TYPE,/*147*/ + MTK_PULL_PUPD_R1R0_TYPE,/*148*/ MTK_PULL_PUPD_R1R0_TYPE,/*149*/ + MTK_PULL_PUPD_R1R0_TYPE,/*150*/ MTK_PULL_PUPD_R1R0_TYPE,/*151*/ + MTK_PULL_PUPD_R1R0_TYPE,/*152*/ MTK_PULL_PUPD_R1R0_TYPE,/*153*/ + MTK_PULL_PUPD_R1R0_TYPE,/*154*/ MTK_PULL_PUPD_R1R0_TYPE,/*155*/ + MTK_PULL_PUPD_R1R0_TYPE,/*156*/ MTK_PULL_PU_PD_TYPE,/*157*/ + MTK_PULL_PU_PD_TYPE,/*158*/ MTK_PULL_PU_PD_TYPE,/*159*/ + MTK_PULL_PU_PD_TYPE,/*160*/ MTK_PULL_PU_PD_TYPE,/*161*/ + MTK_PULL_PU_PD_TYPE,/*162*/ MTK_PULL_PU_PD_TYPE,/*163*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*164*/ MTK_PULL_PU_PD_RSEL_TYPE,/*165*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*166*/ MTK_PULL_PU_PD_RSEL_TYPE,/*167*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*168*/ MTK_PULL_PU_PD_TYPE,/*169*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*170*/ MTK_PULL_PU_PD_TYPE,/*171*/ + MTK_PULL_PU_PD_TYPE,/*172*/ MTK_PULL_PU_PD_TYPE,/*173*/ + MTK_PULL_PU_PD_TYPE,/*174*/ MTK_PULL_PU_PD_TYPE,/*175*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*176*/ MTK_PULL_PU_PD_RSEL_TYPE,/*177*/ + MTK_PULL_PU_PD_TYPE,/*178*/ MTK_PULL_PU_PD_TYPE,/*179*/ + MTK_PULL_PU_PD_TYPE,/*180*/ MTK_PULL_PU_PD_TYPE,/*181*/ + MTK_PULL_PU_PD_TYPE,/*182*/ MTK_PULL_PU_PD_TYPE,/*183*/ + MTK_PULL_PU_PD_TYPE,/*184*/ MTK_PULL_PU_PD_TYPE,/*185*/ + MTK_PULL_PU_PD_TYPE,/*186*/ MTK_PULL_PU_PD_TYPE,/*187*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*188*/ MTK_PULL_PU_PD_RSEL_TYPE,/*189*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*190*/ MTK_PULL_PU_PD_RSEL_TYPE,/*191*/ + MTK_PULL_PU_PD_TYPE,/*192*/ MTK_PULL_PU_PD_TYPE,/*193*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*194*/ MTK_PULL_PU_PD_RSEL_TYPE,/*195*/ + MTK_PULL_PU_PD_TYPE,/*196*/ MTK_PULL_PU_PD_TYPE,/*197*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*198*/ MTK_PULL_PU_PD_RSEL_TYPE,/*199*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*200*/ MTK_PULL_PU_PD_RSEL_TYPE,/*201*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*202*/ MTK_PULL_PU_PD_RSEL_TYPE,/*203*/ + MTK_PULL_PU_PD_TYPE,/*204*/ MTK_PULL_PU_PD_TYPE,/*205*/ + MTK_PULL_PU_PD_TYPE,/*206*/ MTK_PULL_PU_PD_TYPE,/*207*/ + MTK_PULL_PU_PD_TYPE,/*208*/ MTK_PULL_PU_PD_TYPE,/*209*/ + MTK_PULL_PU_PD_TYPE,/*210*/ MTK_PULL_PU_PD_TYPE,/*211*/ + MTK_PULL_PU_PD_TYPE,/*212*/ MTK_PULL_PU_PD_TYPE,/*213*/ + MTK_PULL_PU_PD_RSEL_TYPE,/*214*/ MTK_PULL_PU_PD_RSEL_TYPE,/*215*/ + MTK_PULL_PU_PD_TYPE,/*216*/ MTK_PULL_PUPD_R1R0_TYPE,/*217*/ + MTK_PULL_PUPD_R1R0_TYPE,/*218*/ MTK_PULL_PUPD_R1R0_TYPE,/*219*/ + MTK_PULL_PU_PD_TYPE,/*220*/ MTK_PULL_PU_PD_TYPE,/*221*/ + MTK_PULL_PU_PD_TYPE,/*222*/ MTK_PULL_PU_PD_TYPE,/*223*/ + MTK_PULL_PUPD_R1R0_TYPE,/*224*/ MTK_PULL_PUPD_R1R0_TYPE,/*225*/ + MTK_PULL_PUPD_R1R0_TYPE,/*226*/ MTK_PULL_PUPD_R1R0_TYPE,/*227*/ + MTK_PULL_PUPD_R1R0_TYPE,/*228*/ MTK_PULL_PUPD_R1R0_TYPE,/*229*/ + MTK_PULL_PU_PD_TYPE,/*230*/ MTK_PULL_PU_PD_TYPE,/*231*/ + MTK_PULL_PU_PD_TYPE,/*232*/ MTK_PULL_PU_PD_TYPE,/*233*/ + MTK_PULL_PU_PD_TYPE,/*234*/ MTK_PULL_PU_PD_TYPE,/*235*/ + MTK_PULL_PU_PD_TYPE,/*236*/ MTK_PULL_PU_PD_TYPE,/*237*/ + MTK_PULL_PU_PD_TYPE,/*238*/ MTK_PULL_PU_PD_TYPE,/*239*/ + MTK_PULL_PU_PD_TYPE,/*240*/ MTK_PULL_PU_PD_TYPE,/*241*/ + MTK_PULL_PU_PD_TYPE,/*242*/ MTK_PULL_PU_PD_TYPE,/*243*/ + MTK_PULL_PU_PD_TYPE,/*244*/ MTK_PULL_PU_PD_TYPE,/*245*/ + MTK_PULL_PU_PD_TYPE,/*246*/ MTK_PULL_PU_PD_TYPE,/*247*/ + MTK_PULL_PU_PD_TYPE,/*248*/ MTK_PULL_PU_PD_TYPE,/*249*/ + MTK_PULL_PU_PD_TYPE,/*250*/ MTK_PULL_PU_PD_TYPE,/*251*/ + MTK_PULL_PU_PD_TYPE,/*252*/ MTK_PULL_PU_PD_TYPE,/*253*/ + MTK_PULL_PU_PD_TYPE,/*254*/ MTK_PULL_PU_PD_TYPE,/*255*/ + MTK_PULL_PU_PD_TYPE,/*256*/ MTK_PULL_PU_PD_TYPE,/*257*/ + MTK_PULL_PU_PD_TYPE,/*258*/ MTK_PULL_PUPD_R1R0_TYPE,/*259*/ + MTK_PULL_PUPD_R1R0_TYPE,/*260*/ MTK_PULL_PUPD_R1R0_TYPE,/*261*/ + MTK_PULL_PUPD_R1R0_TYPE,/*262*/ MTK_PULL_PUPD_R1R0_TYPE,/*263*/ + MTK_PULL_PUPD_R1R0_TYPE,/*264*/ MTK_PULL_PUPD_R1R0_TYPE,/*265*/ + MTK_PULL_PUPD_R1R0_TYPE,/*266*/ MTK_PULL_PUPD_R1R0_TYPE,/*267*/ + MTK_PULL_PUPD_R1R0_TYPE,/*268*/ MTK_PULL_PUPD_R1R0_TYPE,/*269*/ + MTK_PULL_PUPD_R1R0_TYPE,/*270*/ +}; + +static const struct mtk_pin_reg_calc mt8196_reg_cals[PINCTRL_PIN_REG_MAX] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8196_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8196_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8196_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8196_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8196_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8196_pin_ies_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8196_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8196_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8196_pin_r1_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8196_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt8196_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt8196_pin_drv_range), + [PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8196_pin_drv_adv_range), + [PINCTRL_PIN_REG_RSEL] = MTK_RANGE(mt8196_pin_rsel_range), +}; + +static const char * const mt8196_pinctrl_register_base_names[] = { + "iocfg0", "iocfg_rt", "iocfg_rm1", "iocfg_rm2", + "iocfg_rb", "iocfg_bm1", "iocfg_bm2", "iocfg_bm3", + "iocfg_lt", "iocfg_lm1", "iocfg_lm2", "iocfg_lb1", + "iocfg_lb2", "iocfg_tm1", "iocfg_tm2", "iocfg_tm3", +}; + +static const struct mtk_pin_soc mt8196_data = { + .reg_cal = mt8196_reg_cals, + .pins = mtk_pins_mt8196, + .npins = ARRAY_SIZE(mtk_pins_mt8196), + .ngrps = ARRAY_SIZE(mtk_pins_mt8196), + .nfuncs = 8, + .gpio_m = 0, + .base_names = mt8196_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt8196_pinctrl_register_base_names), + .pull_type = mt8196_pull_type, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_rev1, + .drive_get = mtk_pinconf_drive_get_rev1, + .adv_drive_get = mtk_pinconf_adv_drive_get_raw, + .adv_drive_set = mtk_pinconf_adv_drive_set_raw, +}; + +static const struct of_device_id mt8196_pinctrl_of_match[] = { + { .compatible = "mediatek,mt8196-pinctrl", .data = &mt8196_data }, + { } +}; + +static struct platform_driver mt8196_pinctrl_driver = { + .driver = { + .name = "mt8196-pinctrl", + .of_match_table = mt8196_pinctrl_of_match, + .pm = &mtk_paris_pinctrl_pm_ops, + }, + .probe = mtk_paris_pinctrl_probe, +}; + +static int __init mt8196_pinctrl_init(void) +{ + return platform_driver_register(&mt8196_pinctrl_driver); +} +arch_initcall(mt8196_pinctrl_init); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek MT8196 Pinctrl Driver"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h new file mode 100644 index 0000000000000..9732ede74d9b9 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h @@ -0,0 +1,2791 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2024 Mediatek Inc. + * Author: Guodong Liu + * + */ + +#ifndef __PINCTRL_MTK_MT8196_H +#define __PINCTRL_MTK_MT8196_H + +#include "pinctrl-paris.h" + +static const struct mtk_pin_desc mtk_pins_mt8196[] = { + + MTK_PIN( + 0, "GPIO0", + MTK_EINT_FUNCTION(0, 0), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO0"), + MTK_FUNCTION(1, "DMIC1_CLK"), + MTK_FUNCTION(3, "SPI3_A_MO"), + MTK_FUNCTION(4, "FMI2S_B_LRCK"), + MTK_FUNCTION(5, "SCP_DMIC1_CLK"), + MTK_FUNCTION(6, "TP_GPIO14_AO") + ), + MTK_PIN( + 1, "GPIO1", + MTK_EINT_FUNCTION(0, 1), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO1"), + MTK_FUNCTION(1, "DMIC1_DAT"), + MTK_FUNCTION(2, "SRCLKENAI1"), + MTK_FUNCTION(3, "SPI3_A_MI"), + MTK_FUNCTION(4, "FMI2S_B_DI"), + MTK_FUNCTION(5, "SCP_DMIC1_DAT"), + MTK_FUNCTION(6, "TP_GPIO15_AO") + ), + MTK_PIN( + 2, "GPIO2", + MTK_EINT_FUNCTION(0, 2), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO2"), + MTK_FUNCTION(1, "PWM_VLP"), + MTK_FUNCTION(2, "DSI_HSYNC"), + MTK_FUNCTION(5, "RG_TSFDC_LDO_EN"), + MTK_FUNCTION(6, "TP_GPIO8_AO") + ), + MTK_PIN( + 3, "GPIO3", + MTK_EINT_FUNCTION(0, 3), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO3"), + MTK_FUNCTION(1, "MD_INT0"), + MTK_FUNCTION(2, "DSI1_HSYNC"), + MTK_FUNCTION(5, "DA_TSFDC_LDO_MODE"), + MTK_FUNCTION(6, "TP_GPIO9_AO") + ), + MTK_PIN( + 4, "GPIO4", + MTK_EINT_FUNCTION(0, 4), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO4"), + MTK_FUNCTION(1, "DISP_PWM1"), + MTK_FUNCTION(2, "MD32_0_GPIO0") + ), + MTK_PIN( + 5, "GPIO5", + MTK_EINT_FUNCTION(0, 5), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO5"), + MTK_FUNCTION(1, "LCM1_RST"), + MTK_FUNCTION(2, "SPI7_A_CLK") + ), + MTK_PIN( + 6, "GPIO6", + MTK_EINT_FUNCTION(0, 6), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO6"), + MTK_FUNCTION(1, "DSI1_TE"), + MTK_FUNCTION(2, "SPI7_A_CSB") + ), + MTK_PIN( + 7, "GPIO7", + MTK_EINT_FUNCTION(0, 7), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO7"), + MTK_FUNCTION(2, "SPI7_A_MO"), + MTK_FUNCTION(3, "GPS_PPS0") + ), + MTK_PIN( + 8, "GPIO8", + MTK_EINT_FUNCTION(0, 8), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO8"), + MTK_FUNCTION(2, "SPI7_A_MI"), + MTK_FUNCTION(3, "EDP_TX_HPD") + ), + MTK_PIN( + 9, "GPIO9", + MTK_EINT_FUNCTION(0, 9), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO9"), + MTK_FUNCTION(3, "I2SIN1_LRCK"), + MTK_FUNCTION(7, "RG_TSFDC_LDO_REFSEL0") + ), + MTK_PIN( + 10, "GPIO10", + MTK_EINT_FUNCTION(0, 10), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO10"), + MTK_FUNCTION(3, "I2SOUT1_DO"), + MTK_FUNCTION(7, "RG_TSFDC_LDO_REFSEL1") + ), + MTK_PIN( + 11, "GPIO11", + MTK_EINT_FUNCTION(0, 11), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO11"), + MTK_FUNCTION(4, "FMI2S_B_BCK"), + MTK_FUNCTION(7, "DBG_MON_A30") + ), + MTK_PIN( + 12, "GPIO12", + MTK_EINT_FUNCTION(0, 12), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO12"), + MTK_FUNCTION(3, "I2SIN1_DI_B") + ), + MTK_PIN( + 13, "GPIO13", + MTK_EINT_FUNCTION(0, 13), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO13"), + MTK_FUNCTION(1, "EDP_TX_HPD"), + MTK_FUNCTION(2, "GPS_PPS1") + ), + MTK_PIN( + 14, "GPIO14", + MTK_EINT_FUNCTION(0, 14), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO14"), + MTK_FUNCTION(1, "SRCLKENA2"), + MTK_FUNCTION(2, "DSI2_TE"), + MTK_FUNCTION(3, "SPMI_P_TRIG_FLAG"), + MTK_FUNCTION(5, "MD_INT3"), + MTK_FUNCTION(6, "TP_GPIO8_AO") + ), + MTK_PIN( + 15, "GPIO15", + MTK_EINT_FUNCTION(0, 15), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO15"), + MTK_FUNCTION(1, "SRCLKENAI0"), + MTK_FUNCTION(2, "SPMI_M_TRIG_FLAG"), + MTK_FUNCTION(3, "UCTS0"), + MTK_FUNCTION(4, "MD_INT4"), + MTK_FUNCTION(5, "I2SOUT2_DO"), + MTK_FUNCTION(6, "TP_GPIO9_AO") + ), + MTK_PIN( + 16, "GPIO16", + MTK_EINT_FUNCTION(0, 16), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO16"), + MTK_FUNCTION(1, "SRCLKENAI1"), + MTK_FUNCTION(2, "DP_TX_HPD"), + MTK_FUNCTION(3, "URTS0"), + MTK_FUNCTION(4, "GPS_L5_ELNA_EN"), + MTK_FUNCTION(5, "KPROW2"), + MTK_FUNCTION(6, "TP_GPIO10_AO") + ), + MTK_PIN( + 17, "GPIO17", + MTK_EINT_FUNCTION(0, 17), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO17"), + MTK_FUNCTION(1, "MD_INT0"), + MTK_FUNCTION(2, "DP_OC_EN"), + MTK_FUNCTION(3, "UCTS1"), + MTK_FUNCTION(4, "MD_NTN_URXD1"), + MTK_FUNCTION(5, "KPCOL2"), + MTK_FUNCTION(6, "TP_GPIO11_AO") + ), + MTK_PIN( + 18, "GPIO18", + MTK_EINT_FUNCTION(0, 18), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO18"), + MTK_FUNCTION(1, "DMIC1_CLK"), + MTK_FUNCTION(2, "DP_RAUX_SBU1"), + MTK_FUNCTION(3, "URTS1"), + MTK_FUNCTION(4, "MD_NTN_UTXD1"), + MTK_FUNCTION(5, "I2SIN2_DI"), + MTK_FUNCTION(6, "TP_UTXD_GNSS_VLP") + ), + MTK_PIN( + 19, "GPIO19", + MTK_EINT_FUNCTION(0, 19), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO19"), + MTK_FUNCTION(1, "DMIC1_DAT"), + MTK_FUNCTION(2, "DP_RAUX_SBU2"), + MTK_FUNCTION(3, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(4, "CLKM3_A"), + MTK_FUNCTION(5, "I2SIN2_BCK"), + MTK_FUNCTION(6, "TP_URXD_GNSS_VLP") + ), + MTK_PIN( + 20, "GPIO20", + MTK_EINT_FUNCTION(0, 20), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO20"), + MTK_FUNCTION(1, "IDDIG"), + MTK_FUNCTION(2, "LCM2_RST"), + MTK_FUNCTION(3, "GPS_PPS1"), + MTK_FUNCTION(4, "CLKM2_A") + ), + MTK_PIN( + 21, "GPIO21", + MTK_EINT_FUNCTION(0, 21), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO21"), + MTK_FUNCTION(1, "BPI_BUS11"), + MTK_FUNCTION(2, "PCIE_PERSTN_1P"), + MTK_FUNCTION(3, "DSI1_TE"), + MTK_FUNCTION(4, "DMIC_CLK"), + MTK_FUNCTION(5, "SCP_DMIC_CLK") + ), + MTK_PIN( + 22, "GPIO22", + MTK_EINT_FUNCTION(0, 22), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO22"), + MTK_FUNCTION(1, "BPI_BUS12"), + MTK_FUNCTION(2, "PCIE_CLKREQN_1P"), + MTK_FUNCTION(3, "DSI2_TE"), + MTK_FUNCTION(4, "DMIC_DAT"), + MTK_FUNCTION(5, "SCP_DMIC_DAT") + ), + MTK_PIN( + 23, "GPIO23", + MTK_EINT_FUNCTION(0, 23), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO23"), + MTK_FUNCTION(1, "BPI_BUS13"), + MTK_FUNCTION(2, "PCIE_WAKEN_1P"), + MTK_FUNCTION(3, "DSI3_TE"), + MTK_FUNCTION(4, "DMIC1_CLK"), + MTK_FUNCTION(5, "SCP_DMIC1_CLK") + ), + MTK_PIN( + 24, "GPIO24", + MTK_EINT_FUNCTION(0, 24), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO24"), + MTK_FUNCTION(1, "BPI_BUS14"), + MTK_FUNCTION(2, "LCM1_RST"), + MTK_FUNCTION(3, "AGPS_SYNC"), + MTK_FUNCTION(4, "DMIC1_DAT"), + MTK_FUNCTION(5, "SCP_DMIC1_DAT"), + MTK_FUNCTION(6, "DISP_PWM1") + ), + MTK_PIN( + 25, "GPIO25", + MTK_EINT_FUNCTION(0, 25), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO25"), + MTK_FUNCTION(1, "BPI_BUS15"), + MTK_FUNCTION(2, "LCM2_RST"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(4, "DMIC2_CLK"), + MTK_FUNCTION(6, "DISP_PWM2") + ), + MTK_PIN( + 26, "GPIO26", + MTK_EINT_FUNCTION(0, 26), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO26"), + MTK_FUNCTION(1, "BPI_BUS16"), + MTK_FUNCTION(2, "LCM3_RST"), + MTK_FUNCTION(4, "DMIC2_DAT"), + MTK_FUNCTION(6, "DISP_PWM3") + ), + MTK_PIN( + 27, "GPIO27", + MTK_EINT_FUNCTION(0, 27), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO27"), + MTK_FUNCTION(1, "BPI_BUS17"), + MTK_FUNCTION(2, "UTXD4"), + MTK_FUNCTION(6, "DISP_PWM4"), + MTK_FUNCTION(7, "DBG_MON_A20") + ), + MTK_PIN( + 28, "GPIO28", + MTK_EINT_FUNCTION(0, 28), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO28"), + MTK_FUNCTION(1, "BPI_BUS18"), + MTK_FUNCTION(2, "URXD4"), + MTK_FUNCTION(3, "SPI2_A_MI"), + MTK_FUNCTION(4, "CLKM0_A"), + MTK_FUNCTION(7, "DBG_MON_A21") + ), + MTK_PIN( + 29, "GPIO29", + MTK_EINT_FUNCTION(0, 29), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO29"), + MTK_FUNCTION(1, "BPI_BUS19"), + MTK_FUNCTION(2, "MD_NTN_UTXD1"), + MTK_FUNCTION(3, "SPI2_A_MO"), + MTK_FUNCTION(4, "CLKM1_A"), + MTK_FUNCTION(6, "UCTS4"), + MTK_FUNCTION(7, "DBG_MON_A17") + ), + MTK_PIN( + 30, "GPIO30", + MTK_EINT_FUNCTION(0, 30), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO30"), + MTK_FUNCTION(1, "BPI_BUS20"), + MTK_FUNCTION(2, "MD_NTN_URXD1"), + MTK_FUNCTION(3, "SPI2_A_CLK"), + MTK_FUNCTION(4, "CLKM2_A"), + MTK_FUNCTION(5, "DSI3_HSYNC"), + MTK_FUNCTION(6, "URTS4"), + MTK_FUNCTION(7, "DBG_MON_A18") + ), + MTK_PIN( + 31, "GPIO31", + MTK_EINT_FUNCTION(0, 31), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO31"), + MTK_FUNCTION(1, "BPI_BUS21"), + MTK_FUNCTION(3, "SPI2_A_CSB"), + MTK_FUNCTION(4, "CLKM3_A"), + MTK_FUNCTION(6, "EDP_TX_HPD"), + MTK_FUNCTION(7, "DBG_MON_A19") + ), + MTK_PIN( + 32, "GPIO32", + MTK_EINT_FUNCTION(0, 32), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO32"), + MTK_FUNCTION(1, "LCM4_RST"), + MTK_FUNCTION(2, "DP_TX_HPD"), + MTK_FUNCTION(3, "SSPM_JTAG_TCK_VLP"), + MTK_FUNCTION(4, "ADSP_JTAG0_TCK"), + MTK_FUNCTION(5, "SCP_JTAG0_TCK_VLP"), + MTK_FUNCTION(6, "SPU0_TCK"), + MTK_FUNCTION(7, "IO_JTAG_TCK") + ), + MTK_PIN( + 33, "GPIO33", + MTK_EINT_FUNCTION(0, 33), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO33"), + MTK_FUNCTION(1, "DSI4_TE"), + MTK_FUNCTION(2, "DP_OC_EN"), + MTK_FUNCTION(3, "SSPM_JTAG_TRSTN_VLP"), + MTK_FUNCTION(4, "ADSP_JTAG0_TRSTN"), + MTK_FUNCTION(5, "SCP_JTAG0_TRSTN_VLP"), + MTK_FUNCTION(6, "SPU0_NTRST"), + MTK_FUNCTION(7, "IO_JTAG_TRSTN") + ), + MTK_PIN( + 34, "GPIO34", + MTK_EINT_FUNCTION(0, 34), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO34"), + MTK_FUNCTION(1, "UCTS5"), + MTK_FUNCTION(2, "DP_RAUX_SBU1"), + MTK_FUNCTION(3, "SSPM_JTAG_TDI_VLP"), + MTK_FUNCTION(4, "ADSP_JTAG0_TDI"), + MTK_FUNCTION(5, "SCP_JTAG0_TDI_VLP"), + MTK_FUNCTION(6, "SPU0_TDI"), + MTK_FUNCTION(7, "IO_JTAG_TDI") + ), + MTK_PIN( + 35, "GPIO35", + MTK_EINT_FUNCTION(0, 35), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO35"), + MTK_FUNCTION(1, "URTS5"), + MTK_FUNCTION(2, "DP_RAUX_SBU2"), + MTK_FUNCTION(3, "SSPM_JTAG_TDO_VLP"), + MTK_FUNCTION(4, "ADSP_JTAG0_TDO"), + MTK_FUNCTION(5, "SCP_JTAG0_TDO_VLP"), + MTK_FUNCTION(6, "SPU0_TDO"), + MTK_FUNCTION(7, "IO_JTAG_TDO") + ), + MTK_PIN( + 36, "GPIO36", + MTK_EINT_FUNCTION(0, 36), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO36"), + MTK_FUNCTION(1, "UTXD5"), + MTK_FUNCTION(3, "SSPM_JTAG_TMS_VLP"), + MTK_FUNCTION(4, "ADSP_JTAG0_TMS"), + MTK_FUNCTION(5, "SCP_JTAG0_TMS_VLP"), + MTK_FUNCTION(6, "SPU0_TMS"), + MTK_FUNCTION(7, "IO_JTAG_TMS") + ), + MTK_PIN( + 37, "GPIO37", + MTK_EINT_FUNCTION(0, 37), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO37"), + MTK_FUNCTION(1, "URXD5"), + MTK_FUNCTION(3, "MD_INT3"), + MTK_FUNCTION(4, "CLKM0_B"), + MTK_FUNCTION(5, "TP_GPIO5_AO"), + MTK_FUNCTION(6, "SPU0_UTX"), + MTK_FUNCTION(7, "DAP_MD32_SWCK") + ), + MTK_PIN( + 38, "GPIO38", + MTK_EINT_FUNCTION(0, 38), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO38"), + MTK_FUNCTION(2, "SPMI_P_TRIG_FLAG"), + MTK_FUNCTION(3, "MD_INT4"), + MTK_FUNCTION(4, "CLKM1_B"), + MTK_FUNCTION(5, "TP_GPIO6_AO"), + MTK_FUNCTION(6, "SPU0_URX"), + MTK_FUNCTION(7, "DAP_MD32_SWD") + ), + MTK_PIN( + 39, "GPIO39", + MTK_EINT_FUNCTION(0, 39), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO39"), + MTK_FUNCTION(1, "I2S_MCK0"), + MTK_FUNCTION(3, "GPS_PPS0"), + MTK_FUNCTION(4, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(7, "DBG_MON_B12") + ), + MTK_PIN( + 40, "GPIO40", + MTK_EINT_FUNCTION(0, 40), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO40"), + MTK_FUNCTION(1, "I2SIN6_0_BCK"), + MTK_FUNCTION(3, "SPI4_B_CLK"), + MTK_FUNCTION(4, "UCTS2"), + MTK_FUNCTION(5, "CCU1_UTXD"), + MTK_FUNCTION(7, "DBG_MON_B13") + ), + MTK_PIN( + 41, "GPIO41", + MTK_EINT_FUNCTION(0, 41), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO41"), + MTK_FUNCTION(1, "I2SIN6_0_LRCK"), + MTK_FUNCTION(3, "SPI4_B_CSB"), + MTK_FUNCTION(4, "URTS2"), + MTK_FUNCTION(5, "CCU1_URXD"), + MTK_FUNCTION(7, "DBG_MON_B14") + ), + MTK_PIN( + 42, "GPIO42", + MTK_EINT_FUNCTION(0, 42), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO42"), + MTK_FUNCTION(1, "I2SIN6_0_DI"), + MTK_FUNCTION(3, "SPI4_B_MI"), + MTK_FUNCTION(4, "URXD2"), + MTK_FUNCTION(5, "CCU1_URTS"), + MTK_FUNCTION(6, "MD32_0_RXD"), + MTK_FUNCTION(7, "DBG_MON_B15") + ), + MTK_PIN( + 43, "GPIO43", + MTK_EINT_FUNCTION(0, 43), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO43"), + MTK_FUNCTION(1, "I2SOUT6_0_DO"), + MTK_FUNCTION(3, "SPI4_B_MO"), + MTK_FUNCTION(4, "UTXD2"), + MTK_FUNCTION(5, "CCU1_UCTS"), + MTK_FUNCTION(6, "MD32_0_TXD"), + MTK_FUNCTION(7, "DBG_MON_B16") + ), + MTK_PIN( + 44, "GPIO44", + MTK_EINT_FUNCTION(0, 44), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO44"), + MTK_FUNCTION(1, "MD_INT1_C2K_UIM0_HOT_PLUG"), + MTK_FUNCTION(3, "SPI3_A_CLK"), + MTK_FUNCTION(6, "TP_GPIO10_AO") + ), + MTK_PIN( + 45, "GPIO45", + MTK_EINT_FUNCTION(0, 45), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO45"), + MTK_FUNCTION(1, "MD_INT2_C2K_UIM1_HOT_PLUG"), + MTK_FUNCTION(2, "DSI2_HSYNC"), + MTK_FUNCTION(3, "SPI3_A_CSB"), + MTK_FUNCTION(4, "PWM_VLP"), + MTK_FUNCTION(6, "TP_GPIO11_AO") + ), + MTK_PIN( + 46, "GPIO46", + MTK_EINT_FUNCTION(0, 46), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO46"), + MTK_FUNCTION(1, "SCP_SCL4"), + MTK_FUNCTION(2, "PWM_VLP"), + MTK_FUNCTION(4, "SCP_ILDO_DTEST1_VLP"), + MTK_FUNCTION(5, "UFS_MPHY_SCL"), + MTK_FUNCTION(6, "TP_GPIO0_AO") + ), + MTK_PIN( + 47, "GPIO47", + MTK_EINT_FUNCTION(0, 47), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO47"), + MTK_FUNCTION(1, "SCP_SDA4"), + MTK_FUNCTION(4, "SCP_ILDO_DTEST2_VLP"), + MTK_FUNCTION(5, "UFS_MPHY_SDA"), + MTK_FUNCTION(6, "TP_GPIO1_AO") + ), + MTK_PIN( + 48, "GPIO48", + MTK_EINT_FUNCTION(0, 48), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO48"), + MTK_FUNCTION(1, "SCP_SCL5"), + MTK_FUNCTION(2, "PWM_VLP"), + MTK_FUNCTION(3, "CCU0_UTXD"), + MTK_FUNCTION(4, "SCP_ILDO_DTEST3_VLP"), + MTK_FUNCTION(6, "TP_GPIO2_AO") + ), + MTK_PIN( + 49, "GPIO49", + MTK_EINT_FUNCTION(0, 49), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO49"), + MTK_FUNCTION(1, "SCP_SDA5"), + MTK_FUNCTION(3, "CCU0_URXD"), + MTK_FUNCTION(4, "SCP_ILDO_DTEST4_VLP"), + MTK_FUNCTION(6, "TP_GPIO3_AO") + ), + MTK_PIN( + 50, "GPIO50", + MTK_EINT_FUNCTION(0, 50), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO50"), + MTK_FUNCTION(1, "SCP_SCL6"), + MTK_FUNCTION(2, "PWM_VLP"), + MTK_FUNCTION(3, "CCU0_URTS"), + MTK_FUNCTION(4, "DSI_HSYNC"), + MTK_FUNCTION(6, "TP_GPIO4_AO") + ), + MTK_PIN( + 51, "GPIO51", + MTK_EINT_FUNCTION(0, 51), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO51"), + MTK_FUNCTION(1, "SCP_SDA6"), + MTK_FUNCTION(3, "CCU0_UCTS"), + MTK_FUNCTION(4, "DSI1_HSYNC"), + MTK_FUNCTION(6, "TP_GPIO5_AO") + ), + MTK_PIN( + 52, "GPIO52", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO52"), + MTK_FUNCTION(1, "SCP_SCL1"), + MTK_FUNCTION(3, "TDM_DATA2") + ), + MTK_PIN( + 53, "GPIO53", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO53"), + MTK_FUNCTION(1, "SCP_SDA1"), + MTK_FUNCTION(3, "TDM_DATA3") + ), + MTK_PIN( + 54, "GPIO54", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO54"), + MTK_FUNCTION(1, "AUD_CLK_MOSI"), + MTK_FUNCTION(3, "TDM_MCK") + ), + MTK_PIN( + 55, "GPIO55", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO55"), + MTK_FUNCTION(1, "AUD_CLK_MISO"), + MTK_FUNCTION(2, "I2SOUT2_BCK"), + MTK_FUNCTION(3, "TDM_BCK") + ), + MTK_PIN( + 56, "GPIO56", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO56"), + MTK_FUNCTION(1, "AUD_DAT_MOSI0"), + MTK_FUNCTION(2, "I2SOUT2_LRCK"), + MTK_FUNCTION(3, "TDM_LRCK") + ), + MTK_PIN( + 57, "GPIO57", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO57"), + MTK_FUNCTION(1, "AUD_DAT_MOSI1"), + MTK_FUNCTION(2, "I2SOUT2_DO"), + MTK_FUNCTION(3, "TDM_DATA0") + ), + MTK_PIN( + 58, "GPIO58", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO58"), + MTK_FUNCTION(1, "AUD_DAT_MISO0"), + MTK_FUNCTION(3, "TDM_DATA1") + ), + MTK_PIN( + 59, "GPIO59", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO59"), + MTK_FUNCTION(1, "AUD_DAT_MISO1"), + MTK_FUNCTION(3, "I2SIN1_BCK") + ), + MTK_PIN( + 60, "GPIO60", + MTK_EINT_FUNCTION(0, 60), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO60"), + MTK_FUNCTION(1, "KPCOL0"), + MTK_FUNCTION(6, "TP_GPIO13_AO") + ), + MTK_PIN( + 61, "GPIO61", + MTK_EINT_FUNCTION(0, 61), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO61"), + MTK_FUNCTION(1, "MCU_M_PMIC_POC_I") + ), + MTK_PIN( + 62, "GPIO62", + MTK_EINT_FUNCTION(0, 62), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO62"), + MTK_FUNCTION(1, "MCU_B_PMIC_POC_I") + ), + MTK_PIN( + 63, "GPIO63", + MTK_EINT_FUNCTION(0, 63), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO63"), + MTK_FUNCTION(1, "MFG_PMIC_POC_I") + ), + MTK_PIN( + 64, "GPIO64", + MTK_EINT_FUNCTION(0, 64), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO64"), + MTK_FUNCTION(1, "PRE_UVLO") + ), + MTK_PIN( + 65, "GPIO65", + MTK_EINT_FUNCTION(0, 65), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO65"), + MTK_FUNCTION(1, "DPM2PMIC"), + MTK_FUNCTION(2, "SRCLKENA1") + ), + MTK_PIN( + 66, "GPIO66", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO66"), + MTK_FUNCTION(1, "WATCHDOG") + ), + MTK_PIN( + 67, "GPIO67", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO67"), + MTK_FUNCTION(1, "SRCLKENA0") + ), + MTK_PIN( + 68, "GPIO68", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO68"), + MTK_FUNCTION(1, "SCP_VREQ_VAO") + ), + MTK_PIN( + 69, "GPIO69", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO69"), + MTK_FUNCTION(1, "RTC32K_CK") + ), + MTK_PIN( + 70, "GPIO70", + MTK_EINT_FUNCTION(0, 70), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO70"), + MTK_FUNCTION(1, "CMFLASH0") + ), + MTK_PIN( + 71, "GPIO71", + MTK_EINT_FUNCTION(0, 71), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO71") + ), + MTK_PIN( + 72, "GPIO72", + MTK_EINT_FUNCTION(0, 72), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO72") + ), + MTK_PIN( + 73, "GPIO73", + MTK_EINT_FUNCTION(0, 73), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO73") + ), + MTK_PIN( + 74, "GPIO74", + MTK_EINT_FUNCTION(0, 74), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO74"), + MTK_FUNCTION(1, "DCXO_FPM_LPM") + ), + MTK_PIN( + 75, "GPIO75", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO75"), + MTK_FUNCTION(1, "SPMI_M_SCL") + ), + MTK_PIN( + 76, "GPIO76", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO76"), + MTK_FUNCTION(1, "SPMI_M_SDA") + ), + MTK_PIN( + 77, "GPIO77", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO77"), + MTK_FUNCTION(1, "SPMI_P_SCL") + ), + MTK_PIN( + 78, "GPIO78", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO78"), + MTK_FUNCTION(1, "SPMI_P_SDA") + ), + MTK_PIN( + 79, "GPIO79", + MTK_EINT_FUNCTION(0, 79), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO79"), + MTK_FUNCTION(1, "CMMCLK0"), + MTK_FUNCTION(2, "MD_INT4") + ), + MTK_PIN( + 80, "GPIO80", + MTK_EINT_FUNCTION(0, 80), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO80"), + MTK_FUNCTION(1, "CMMCLK1") + ), + MTK_PIN( + 81, "GPIO81", + MTK_EINT_FUNCTION(0, 81), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO81"), + MTK_FUNCTION(1, "SCP_SPI0_CK"), + MTK_FUNCTION(2, "SPI6_B_CLK"), + MTK_FUNCTION(3, "PWM_VLP"), + MTK_FUNCTION(4, "I2SOUT5_BCK"), + MTK_FUNCTION(6, "TP_GPIO0_AO") + ), + MTK_PIN( + 82, "GPIO82", + MTK_EINT_FUNCTION(0, 82), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO82"), + MTK_FUNCTION(1, "SCP_SPI0_CS"), + MTK_FUNCTION(2, "SPI6_B_CSB"), + MTK_FUNCTION(4, "I2SOUT5_LRCK"), + MTK_FUNCTION(6, "TP_GPIO1_AO") + ), + MTK_PIN( + 83, "GPIO83", + MTK_EINT_FUNCTION(0, 83), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO83"), + MTK_FUNCTION(1, "SCP_SPI0_MO"), + MTK_FUNCTION(2, "SPI6_B_MO"), + MTK_FUNCTION(4, "I2SOUT5_DATA0"), + MTK_FUNCTION(6, "TP_GPIO2_AO") + ), + MTK_PIN( + 84, "GPIO84", + MTK_EINT_FUNCTION(0, 84), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO84"), + MTK_FUNCTION(1, "SCP_SPI0_MI"), + MTK_FUNCTION(2, "SPI6_B_MI"), + MTK_FUNCTION(4, "I2SOUT5_DATA1"), + MTK_FUNCTION(6, "TP_GPIO3_AO") + ), + MTK_PIN( + 85, "GPIO85", + MTK_EINT_FUNCTION(0, 85), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO85"), + MTK_FUNCTION(1, "SCP_SPI1_CK"), + MTK_FUNCTION(2, "SPI7_B_CLK"), + MTK_FUNCTION(4, "I2SIN5_DATA0"), + MTK_FUNCTION(5, "PWM_VLP"), + MTK_FUNCTION(6, "TP_GPIO4_AO") + ), + MTK_PIN( + 86, "GPIO86", + MTK_EINT_FUNCTION(0, 86), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO86"), + MTK_FUNCTION(1, "SCP_SPI1_CS"), + MTK_FUNCTION(2, "SPI7_B_CSB"), + MTK_FUNCTION(4, "I2SIN5_DATA1"), + MTK_FUNCTION(6, "TP_GPIO5_AO") + ), + MTK_PIN( + 87, "GPIO87", + MTK_EINT_FUNCTION(0, 87), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO87"), + MTK_FUNCTION(1, "SCP_SPI1_MO"), + MTK_FUNCTION(2, "SPI7_B_MO"), + MTK_FUNCTION(4, "I2SIN5_BCK"), + MTK_FUNCTION(6, "TP_GPIO6_AO") + ), + MTK_PIN( + 88, "GPIO88", + MTK_EINT_FUNCTION(0, 88), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO88"), + MTK_FUNCTION(1, "SCP_SPI1_MI"), + MTK_FUNCTION(2, "SPI7_B_MI"), + MTK_FUNCTION(4, "I2SIN5_LRCK"), + MTK_FUNCTION(6, "TP_GPIO7_AO") + ), + MTK_PIN( + 89, "GPIO89", + MTK_EINT_FUNCTION(0, 89), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO89"), + MTK_FUNCTION(1, "DSI_TE"), + MTK_FUNCTION(2, "DSI1_TE"), + MTK_FUNCTION(7, "DBG_MON_B30") + ), + MTK_PIN( + 90, "GPIO90", + MTK_EINT_FUNCTION(0, 90), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO90"), + MTK_FUNCTION(1, "LCM_RST"), + MTK_FUNCTION(2, "LCM1_RST"), + MTK_FUNCTION(7, "DBG_MON_B31") + ), + MTK_PIN( + 91, "GPIO91", + MTK_EINT_FUNCTION(0, 91), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO91"), + MTK_FUNCTION(1, "CMFLASH2"), + MTK_FUNCTION(2, "SF_D0"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(5, "KPCOL2"), + MTK_FUNCTION(6, "TP_GPIO11_AO") + ), + MTK_PIN( + 92, "GPIO92", + MTK_EINT_FUNCTION(0, 92), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO92"), + MTK_FUNCTION(1, "CMFLASH3"), + MTK_FUNCTION(2, "SF_D1"), + MTK_FUNCTION(4, "DISP_PWM1"), + MTK_FUNCTION(6, "TP_GPIO12_AO") + ), + MTK_PIN( + 93, "GPIO93", + MTK_EINT_FUNCTION(0, 93), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO93"), + MTK_FUNCTION(1, "CMFLASH1"), + MTK_FUNCTION(2, "SF_D2"), + MTK_FUNCTION(3, "SRCLKENAI0"), + MTK_FUNCTION(5, "KPROW2"), + MTK_FUNCTION(6, "TP_GPIO13_AO") + ), + MTK_PIN( + 94, "GPIO94", + MTK_EINT_FUNCTION(0, 94), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO94"), + MTK_FUNCTION(1, "I2S_MCK1"), + MTK_FUNCTION(2, "SF_D3"), + MTK_FUNCTION(4, "MD32_0_GPIO0"), + MTK_FUNCTION(5, "CLKM0_A"), + MTK_FUNCTION(6, "TP_GPIO14_AO"), + MTK_FUNCTION(7, "DBG_MON_B18") + ), + MTK_PIN( + 95, "GPIO95", + MTK_EINT_FUNCTION(0, 95), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO95"), + MTK_FUNCTION(1, "I2SIN1_BCK"), + MTK_FUNCTION(2, "I2SIN4_BCK"), + MTK_FUNCTION(3, "SPI6_A_CLK"), + MTK_FUNCTION(4, "MD32_1_GPIO0"), + MTK_FUNCTION(5, "CLKM1_A"), + MTK_FUNCTION(6, "TP_GPIO15_AO"), + MTK_FUNCTION(7, "DBG_MON_B19") + ), + MTK_PIN( + 96, "GPIO96", + MTK_EINT_FUNCTION(0, 96), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO96"), + MTK_FUNCTION(1, "I2SIN1_LRCK"), + MTK_FUNCTION(2, "I2SIN4_LRCK"), + MTK_FUNCTION(3, "SPI6_A_CSB"), + MTK_FUNCTION(4, "MD32_2_GPIO0"), + MTK_FUNCTION(5, "CLKM2_A"), + MTK_FUNCTION(7, "DBG_MON_B20") + ), + MTK_PIN( + 97, "GPIO97", + MTK_EINT_FUNCTION(0, 97), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO97"), + MTK_FUNCTION(1, "I2SIN1_DI_A"), + MTK_FUNCTION(2, "I2SIN4_DATA0"), + MTK_FUNCTION(3, "SPI6_A_MO"), + MTK_FUNCTION(4, "MD32_3_GPIO0"), + MTK_FUNCTION(5, "CLKM3_A"), + MTK_FUNCTION(7, "DBG_MON_B21") + ), + MTK_PIN( + 98, "GPIO98", + MTK_EINT_FUNCTION(0, 98), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO98"), + MTK_FUNCTION(1, "I2SOUT1_DO"), + MTK_FUNCTION(2, "I2SOUT4_DATA0"), + MTK_FUNCTION(3, "SPI6_A_MI"), + MTK_FUNCTION(7, "DBG_MON_B22") + ), + MTK_PIN( + 99, "GPIO99", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO99"), + MTK_FUNCTION(1, "SCL0"), + MTK_FUNCTION(2, "LCM2_RST"), + MTK_FUNCTION(3, "AUD_DAC_26M_CLK"), + MTK_FUNCTION(4, "SPU0_SCL"), + MTK_FUNCTION(7, "DBG_MON_B24") + ), + MTK_PIN( + 100, "GPIO100", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO100"), + MTK_FUNCTION(1, "SDA0"), + MTK_FUNCTION(2, "DSI2_TE"), + MTK_FUNCTION(4, "SPU0_SDA"), + MTK_FUNCTION(7, "DBG_MON_B25") + ), + MTK_PIN( + 101, "GPIO101", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO101"), + MTK_FUNCTION(1, "SCL10"), + MTK_FUNCTION(2, "SF_CS"), + MTK_FUNCTION(3, "SCP_DMIC1_CLK"), + MTK_FUNCTION(4, "I2SIN5_DATA2"), + MTK_FUNCTION(5, "SCP_SCL_OIS"), + MTK_FUNCTION(6, "TP_GPIO10_AO"), + MTK_FUNCTION(7, "DBG_MON_B28") + ), + MTK_PIN( + 102, "GPIO102", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO102"), + MTK_FUNCTION(1, "SDA10"), + MTK_FUNCTION(2, "SF_CK"), + MTK_FUNCTION(3, "SCP_DMIC1_DAT"), + MTK_FUNCTION(4, "I2SIN5_DATA3"), + MTK_FUNCTION(5, "SCP_SDA_OIS"), + MTK_FUNCTION(6, "TP_GPIO11_AO"), + MTK_FUNCTION(7, "DBG_MON_B29") + ), + MTK_PIN( + 103, "GPIO103", + MTK_EINT_FUNCTION(0, 103), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO103"), + MTK_FUNCTION(1, "DISP_PWM"), + MTK_FUNCTION(2, "DSI1_TE"), + MTK_FUNCTION(5, "I2S_MCK0"), + MTK_FUNCTION(7, "DBG_MON_B23") + ), + MTK_PIN( + 104, "GPIO104", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO104"), + MTK_FUNCTION(1, "SCL6"), + MTK_FUNCTION(2, "SPU1_SCL"), + MTK_FUNCTION(3, "AUD_DAC_26M_CLK"), + MTK_FUNCTION(4, "USB_DRVVBUS_2P"), + MTK_FUNCTION(5, "I2S_MCK1"), + MTK_FUNCTION(6, "IDDIG_2P"), + MTK_FUNCTION(7, "DBG_MON_B26") + ), + MTK_PIN( + 105, "GPIO105", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO105"), + MTK_FUNCTION(1, "SDA6"), + MTK_FUNCTION(2, "SPU1_SDA"), + MTK_FUNCTION(3, "DISP_PWM2"), + MTK_FUNCTION(4, "VBUSVALID_2P"), + MTK_FUNCTION(5, "I2S_MCK2"), + MTK_FUNCTION(6, "VBUSVALID_3P"), + MTK_FUNCTION(7, "DBG_MON_B27") + ), + MTK_PIN( + 106, "GPIO106", + MTK_EINT_FUNCTION(0, 106), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO106"), + MTK_FUNCTION(1, "SCP_SPI3_CK"), + MTK_FUNCTION(2, "SPI3_B_CLK"), + MTK_FUNCTION(3, "MD_UTXD0"), + MTK_FUNCTION(4, "TP_UTXD1_VLP"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_UART0_TXD"), + MTK_FUNCTION(6, "TP_GPIO6_AO"), + MTK_FUNCTION(7, "DBG_MON_B0") + ), + MTK_PIN( + 107, "GPIO107", + MTK_EINT_FUNCTION(0, 107), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO107"), + MTK_FUNCTION(1, "SCP_SPI3_CS"), + MTK_FUNCTION(2, "SPI3_B_CSB"), + MTK_FUNCTION(3, "MD_URXD0"), + MTK_FUNCTION(4, "TP_URXD1_VLP"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_UART0_RXD"), + MTK_FUNCTION(6, "TP_GPIO7_AO"), + MTK_FUNCTION(7, "DBG_MON_B1") + ), + MTK_PIN( + 108, "GPIO108", + MTK_EINT_FUNCTION(0, 108), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO108"), + MTK_FUNCTION(1, "SCP_SPI3_MO"), + MTK_FUNCTION(2, "SPI3_B_MO"), + MTK_FUNCTION(3, "MD_UTXD1"), + MTK_FUNCTION(4, "MD32PCM_UTXD_AO_VLP"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_UART1_TXD"), + MTK_FUNCTION(6, "TP_GPIO8_AO"), + MTK_FUNCTION(7, "DBG_MON_B2") + ), + MTK_PIN( + 109, "GPIO109", + MTK_EINT_FUNCTION(0, 109), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO109"), + MTK_FUNCTION(1, "SCP_SPI3_MI"), + MTK_FUNCTION(2, "SPI3_B_MI"), + MTK_FUNCTION(3, "MD_URXD1"), + MTK_FUNCTION(4, "MD32PCM_URXD_AO_VLP"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_UART1_RXD"), + MTK_FUNCTION(6, "TP_GPIO9_AO"), + MTK_FUNCTION(7, "DBG_MON_B3") + ), + MTK_PIN( + 110, "GPIO110", + MTK_EINT_FUNCTION(0, 110), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO110"), + MTK_FUNCTION(1, "SPI1_CLK"), + MTK_FUNCTION(2, "PWM_0"), + MTK_FUNCTION(3, "MD_UCTS0"), + MTK_FUNCTION(4, "TP_UCTS1_VLP"), + MTK_FUNCTION(6, "SPU0_GPIO_O"), + MTK_FUNCTION(7, "DBG_MON_B4") + ), + MTK_PIN( + 111, "GPIO111", + MTK_EINT_FUNCTION(0, 111), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO111"), + MTK_FUNCTION(1, "SPI1_CSB"), + MTK_FUNCTION(2, "PWM_1"), + MTK_FUNCTION(3, "MD_URTS0"), + MTK_FUNCTION(4, "TP_URTS1_VLP"), + MTK_FUNCTION(6, "SPU0_GPIO_I"), + MTK_FUNCTION(7, "DBG_MON_B5") + ), + MTK_PIN( + 112, "GPIO112", + MTK_EINT_FUNCTION(0, 112), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO112"), + MTK_FUNCTION(1, "SPI1_MO"), + MTK_FUNCTION(2, "PWM_2"), + MTK_FUNCTION(3, "MD_UCTS1"), + MTK_FUNCTION(6, "SPU1_GPIO_O"), + MTK_FUNCTION(7, "DBG_MON_B6") + ), + MTK_PIN( + 113, "GPIO113", + MTK_EINT_FUNCTION(0, 113), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO113"), + MTK_FUNCTION(1, "SPI1_MI"), + MTK_FUNCTION(2, "PWM_3"), + MTK_FUNCTION(3, "MD_URTS1"), + MTK_FUNCTION(6, "SPU1_GPIO_I"), + MTK_FUNCTION(7, "DBG_MON_B7") + ), + MTK_PIN( + 114, "GPIO114", + MTK_EINT_FUNCTION(0, 114), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO114"), + MTK_FUNCTION(1, "SPI0_SPU_CLK"), + MTK_FUNCTION(2, "SPI4_A_CLK"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_DBG_UART_TX"), + MTK_FUNCTION(7, "DBG_MON_B8") + ), + MTK_PIN( + 115, "GPIO115", + MTK_EINT_FUNCTION(0, 115), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO115"), + MTK_FUNCTION(1, "SPI0_SPU_CSB"), + MTK_FUNCTION(2, "SPI4_A_CSB"), + MTK_FUNCTION(7, "DBG_MON_B9") + ), + MTK_PIN( + 116, "GPIO116", + MTK_EINT_FUNCTION(0, 116), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO116"), + MTK_FUNCTION(1, "SPI0_SPU_MO"), + MTK_FUNCTION(2, "SPI4_A_MO"), + MTK_FUNCTION(3, "LCM1_RST"), + MTK_FUNCTION(7, "DBG_MON_B10") + ), + MTK_PIN( + 117, "GPIO117", + MTK_EINT_FUNCTION(0, 117), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO117"), + MTK_FUNCTION(1, "SPI0_SPU_MI"), + MTK_FUNCTION(2, "SPI4_A_MI"), + MTK_FUNCTION(3, "DSI1_TE"), + MTK_FUNCTION(7, "DBG_MON_B11") + ), + MTK_PIN( + 118, "GPIO118", + MTK_EINT_FUNCTION(0, 118), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO118"), + MTK_FUNCTION(1, "SPI5_CLK"), + MTK_FUNCTION(2, "USB_DRVVBUS"), + MTK_FUNCTION(3, "DP_TX_HPD"), + MTK_FUNCTION(4, "AD_ILDO_DTEST0") + ), + MTK_PIN( + 119, "GPIO119", + MTK_EINT_FUNCTION(0, 119), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO119"), + MTK_FUNCTION(1, "SPI5_CSB"), + MTK_FUNCTION(2, "VBUSVALID"), + MTK_FUNCTION(3, "DP_OC_EN"), + MTK_FUNCTION(4, "AD_ILDO_DTEST1") + ), + MTK_PIN( + 120, "GPIO120", + MTK_EINT_FUNCTION(0, 120), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO120"), + MTK_FUNCTION(1, "SPI5_MO"), + MTK_FUNCTION(2, "LCM2_RST"), + MTK_FUNCTION(3, "DP_RAUX_SBU1"), + MTK_FUNCTION(4, "AD_ILDO_DTEST2"), + MTK_FUNCTION(6, "IDDIG_3P") + ), + MTK_PIN( + 121, "GPIO121", + MTK_EINT_FUNCTION(0, 121), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO121"), + MTK_FUNCTION(1, "SPI5_MI"), + MTK_FUNCTION(2, "DSI2_TE"), + MTK_FUNCTION(3, "DP_RAUX_SBU2"), + MTK_FUNCTION(4, "AD_ILDO_DTEST3"), + MTK_FUNCTION(6, "USB_DRVVBUS_3P"), + MTK_FUNCTION(7, "DBG_MON_B17") + ), + MTK_PIN( + 122, "GPIO122", + MTK_EINT_FUNCTION(0, 122), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO122"), + MTK_FUNCTION(1, "AP_GOOD"), + MTK_FUNCTION(2, "CONN_TCXOENA_REQ") + ), + MTK_PIN( + 123, "GPIO123", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO123"), + MTK_FUNCTION(1, "SCL3"), + MTK_FUNCTION(5, "I2SIN2_LRCK"), + MTK_FUNCTION(6, "TP_UTXD_MD_VCORE") + ), + MTK_PIN( + 124, "GPIO124", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO124"), + MTK_FUNCTION(1, "SDA3"), + MTK_FUNCTION(6, "TP_URXD_MD_VCORE") + ), + MTK_PIN( + 125, "GPIO125", + MTK_EINT_FUNCTION(0, 125), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO125"), + MTK_FUNCTION(1, "MSDC1_CLK"), + MTK_FUNCTION(2, "MD1_SIM2_SCLK"), + MTK_FUNCTION(3, "HFRP_JTAG0_TCK"), + MTK_FUNCTION(4, "UDI_TCK"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L1_JCK"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TCK_VLP"), + MTK_FUNCTION(7, "JTCK2_SEL1") + ), + MTK_PIN( + 126, "GPIO126", + MTK_EINT_FUNCTION(0, 126), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO126"), + MTK_FUNCTION(1, "MSDC1_CMD"), + MTK_FUNCTION(3, "HFRP_JTAG0_TMS"), + MTK_FUNCTION(4, "UDI_TMS"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L1_JMS"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TMS_VLP"), + MTK_FUNCTION(7, "JTMS2_SEL1") + ), + MTK_PIN( + 127, "GPIO127", + MTK_EINT_FUNCTION(0, 127), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO127"), + MTK_FUNCTION(1, "MSDC1_DAT0"), + MTK_FUNCTION(2, "MD1_SIM2_SRST"), + MTK_FUNCTION(3, "HFRP_JTAG0_TDI"), + MTK_FUNCTION(4, "UDI_TDI_0"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L1_JDI"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TDI_VLP"), + MTK_FUNCTION(7, "JTDI2_SEL1") + ), + MTK_PIN( + 128, "GPIO128", + MTK_EINT_FUNCTION(0, 128), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO128"), + MTK_FUNCTION(1, "MSDC1_DAT1"), + MTK_FUNCTION(2, "MD1_SIM2_SIO"), + MTK_FUNCTION(3, "HFRP_JTAG0_TDO"), + MTK_FUNCTION(4, "UDI_TDO_0"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L1_JDO"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TDO_VLP"), + MTK_FUNCTION(7, "JTDO2_SEL1") + ), + MTK_PIN( + 129, "GPIO129", + MTK_EINT_FUNCTION(0, 129), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO129"), + MTK_FUNCTION(1, "MSDC1_DAT2"), + MTK_FUNCTION(2, "DSI2_HSYNC"), + MTK_FUNCTION(3, "HFRP_JTAG0_TRSTN"), + MTK_FUNCTION(4, "UDI_NTRST"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TRSTN_VLP"), + MTK_FUNCTION(7, "JTRSTN2_SEL1") + ), + MTK_PIN( + 130, "GPIO130", + MTK_EINT_FUNCTION(0, 130), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO130"), + MTK_FUNCTION(1, "MSDC1_DAT3"), + MTK_FUNCTION(2, "DSI3_HSYNC"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L1_JINTP") + ), + MTK_PIN( + 131, "GPIO131", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO131"), + MTK_FUNCTION(1, "MD1_SIM2_SCLK"), + MTK_FUNCTION(2, "MD1_SIM1_SCLK"), + MTK_FUNCTION(3, "MCUPM_JTAG_TDI"), + MTK_FUNCTION(4, "CLKM0_A"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L5_JDI"), + MTK_FUNCTION(6, "TSFDC_SCK"), + MTK_FUNCTION(7, "SCP_JTAG0_TDI_VCORE") + ), + MTK_PIN( + 132, "GPIO132", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO132"), + MTK_FUNCTION(1, "MD1_SIM2_SRST"), + MTK_FUNCTION(2, "MD1_SIM1_SRST"), + MTK_FUNCTION(3, "MCUPM_JTAG_TMS"), + MTK_FUNCTION(4, "CLKM1_B"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L5_JMS"), + MTK_FUNCTION(6, "TSFDC_SDI"), + MTK_FUNCTION(7, "SCP_JTAG0_TMS_VCORE") + ), + MTK_PIN( + 133, "GPIO133", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO133"), + MTK_FUNCTION(1, "MD1_SIM2_SIO"), + MTK_FUNCTION(2, "MD1_SIM1_SIO"), + MTK_FUNCTION(3, "MCUPM_JTAG_TDO"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L5_JDO"), + MTK_FUNCTION(6, "TSFDC_SCF"), + MTK_FUNCTION(7, "SCP_JTAG0_TDO_VCORE") + ), + MTK_PIN( + 134, "GPIO134", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO134"), + MTK_FUNCTION(1, "MD1_SIM1_SCLK"), + MTK_FUNCTION(2, "MD1_SIM2_SCLK"), + MTK_FUNCTION(6, "TSFDC_26M") + ), + MTK_PIN( + 135, "GPIO135", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO135"), + MTK_FUNCTION(1, "MD1_SIM1_SRST"), + MTK_FUNCTION(2, "MD1_SIM2_SRST"), + MTK_FUNCTION(3, "MCUPM_JTAG_TCK"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L5_JCK"), + MTK_FUNCTION(6, "TSFDC_SDO"), + MTK_FUNCTION(7, "SCP_JTAG0_TCK_VCORE") + ), + MTK_PIN( + 136, "GPIO136", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO136"), + MTK_FUNCTION(1, "MD1_SIM1_SIO"), + MTK_FUNCTION(2, "MD1_SIM2_SIO"), + MTK_FUNCTION(3, "MCUPM_JTAG_TRSTN"), + MTK_FUNCTION(5, "CONN_BGF_DSP_L5_JINTP"), + MTK_FUNCTION(6, "TSFDC_FOUT"), + MTK_FUNCTION(7, "SCP_JTAG0_TRSTN_VCORE") + ), + MTK_PIN( + 137, "GPIO137", + MTK_EINT_FUNCTION(0, 137), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO137"), + MTK_FUNCTION(1, "MIPI0_D_SCLK"), + MTK_FUNCTION(2, "BPI_BUS16"), + MTK_FUNCTION(4, "EXT_FRAME_SYNC"), + MTK_FUNCTION(6, "SPM_JTAG_TRSTN_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A0") + ), + MTK_PIN( + 138, "GPIO138", + MTK_EINT_FUNCTION(0, 138), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO138"), + MTK_FUNCTION(1, "MIPI0_D_SDATA"), + MTK_FUNCTION(2, "BPI_BUS17"), + MTK_FUNCTION(4, "PCM0_LRCK"), + MTK_FUNCTION(6, "SPM_JTAG_TCK_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A1") + ), + MTK_PIN( + 139, "GPIO139", + MTK_EINT_FUNCTION(0, 139), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO139"), + MTK_FUNCTION(1, "MIPI1_D_SCLK"), + MTK_FUNCTION(2, "BPI_BUS18"), + MTK_FUNCTION(4, "MD_GPS_BLANK"), + MTK_FUNCTION(6, "SPM_JTAG_TMS_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A2") + ), + MTK_PIN( + 140, "GPIO140", + MTK_EINT_FUNCTION(0, 140), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO140"), + MTK_FUNCTION(1, "MIPI1_D_SDATA"), + MTK_FUNCTION(2, "BPI_BUS19"), + MTK_FUNCTION(4, "MD_URXD1_CONN"), + MTK_FUNCTION(6, "SPM_JTAG_TDO_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A3") + ), + MTK_PIN( + 141, "GPIO141", + MTK_EINT_FUNCTION(0, 141), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO141"), + MTK_FUNCTION(1, "MIPI2_D_SCLK"), + MTK_FUNCTION(2, "BPI_BUS20"), + MTK_FUNCTION(4, "MD_UTXD1_CONN"), + MTK_FUNCTION(6, "SPM_JTAG_TDI_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A4") + ), + MTK_PIN( + 142, "GPIO142", + MTK_EINT_FUNCTION(0, 142), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO142"), + MTK_FUNCTION(1, "MIPI2_D_SDATA"), + MTK_FUNCTION(2, "BPI_BUS21"), + MTK_FUNCTION(6, "SSPM_JTAG_TRSTN_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A5") + ), + MTK_PIN( + 143, "GPIO143", + MTK_EINT_FUNCTION(0, 143), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO143"), + MTK_FUNCTION(1, "MIPI3_D_SCLK"), + MTK_FUNCTION(2, "BPI_BUS22"), + MTK_FUNCTION(4, "TP_UTXD_GNSS_VLP"), + MTK_FUNCTION(5, "MD_UTXD1_CONN"), + MTK_FUNCTION(6, "SSPM_JTAG_TCK_VCORE") + ), + MTK_PIN( + 144, "GPIO144", + MTK_EINT_FUNCTION(0, 144), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO144"), + MTK_FUNCTION(1, "MIPI3_D_SDATA"), + MTK_FUNCTION(2, "BPI_BUS23"), + MTK_FUNCTION(4, "TP_URXD_GNSS_VLP"), + MTK_FUNCTION(5, "MD_URXD1_CONN"), + MTK_FUNCTION(6, "SSPM_JTAG_TMS_VCORE") + ), + MTK_PIN( + 145, "GPIO145", + MTK_EINT_FUNCTION(0, 145), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO145"), + MTK_FUNCTION(1, "BPI_BUS0"), + MTK_FUNCTION(4, "PCIE_WAKEN_1P"), + MTK_FUNCTION(6, "SSPM_JTAG_TDO_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A10") + ), + MTK_PIN( + 146, "GPIO146", + MTK_EINT_FUNCTION(0, 146), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO146"), + MTK_FUNCTION(1, "BPI_BUS1"), + MTK_FUNCTION(4, "PCIE_PERSTN_1P"), + MTK_FUNCTION(6, "SSPM_JTAG_TDI_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A11") + ), + MTK_PIN( + 147, "GPIO147", + MTK_EINT_FUNCTION(0, 147), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO147"), + MTK_FUNCTION(1, "BPI_BUS2"), + MTK_FUNCTION(2, "AUD_DAC_26M_CLK"), + MTK_FUNCTION(4, "PCIE_CLKREQN_1P"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TRSTN_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A12") + ), + MTK_PIN( + 148, "GPIO148", + MTK_EINT_FUNCTION(0, 148), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO148"), + MTK_FUNCTION(1, "BPI_BUS3"), + MTK_FUNCTION(2, "AUD_DAC_26M_CLK"), + MTK_FUNCTION(4, "TP_UTXD_MD_VLP"), + MTK_FUNCTION(5, "TP_GPIO0_AO"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TCK_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A13") + ), + MTK_PIN( + 149, "GPIO149", + MTK_EINT_FUNCTION(0, 149), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO149"), + MTK_FUNCTION(1, "BPI_BUS4"), + MTK_FUNCTION(2, "EXT_FRAME_SYNC"), + MTK_FUNCTION(4, "TP_URXD_MD_VLP"), + MTK_FUNCTION(5, "TP_GPIO1_AO"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TMS_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A14") + ), + MTK_PIN( + 150, "GPIO150", + MTK_EINT_FUNCTION(0, 150), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO150"), + MTK_FUNCTION(1, "BPI_BUS5"), + MTK_FUNCTION(2, "GPS_PPS0"), + MTK_FUNCTION(5, "TP_GPIO2_AO"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TDO_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A15") + ), + MTK_PIN( + 151, "GPIO151", + MTK_EINT_FUNCTION(0, 151), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO151"), + MTK_FUNCTION(1, "BPI_BUS6"), + MTK_FUNCTION(2, "GPS_PPS1"), + MTK_FUNCTION(5, "TP_GPIO3_AO"), + MTK_FUNCTION(6, "SCP_JTAG_LITTLE_TDI_VCORE") + ), + MTK_PIN( + 152, "GPIO152", + MTK_EINT_FUNCTION(0, 152), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO152"), + MTK_FUNCTION(1, "BPI_BUS7"), + MTK_FUNCTION(2, "EDP_TX_HPD"), + MTK_FUNCTION(5, "AGPS_SYNC"), + MTK_FUNCTION(6, "SSPM_UTXD_AO_VCORE") + ), + MTK_PIN( + 153, "GPIO153", + MTK_EINT_FUNCTION(0, 153), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO153"), + MTK_FUNCTION(1, "MD_UCNT_A_TGL"), + MTK_FUNCTION(6, "TP_URTS1_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A8") + ), + MTK_PIN( + 154, "GPIO154", + MTK_EINT_FUNCTION(0, 154), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO154"), + MTK_FUNCTION(1, "DIGRF_IRQ"), + MTK_FUNCTION(6, "TP_UCTS1_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A9") + ), + MTK_PIN( + 155, "GPIO155", + MTK_EINT_FUNCTION(0, 155), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO155"), + MTK_FUNCTION(1, "MIPI_M_SCLK"), + MTK_FUNCTION(4, "UCTS2"), + MTK_FUNCTION(6, "TP_UTXD_CONSYS_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A6") + ), + MTK_PIN( + 156, "GPIO156", + MTK_EINT_FUNCTION(0, 156), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO156"), + MTK_FUNCTION(1, "MIPI_M_SDATA"), + MTK_FUNCTION(4, "URTS2"), + MTK_FUNCTION(6, "TP_URXD_CONSYS_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A7") + ), + MTK_PIN( + 157, "GPIO157", + MTK_EINT_FUNCTION(0, 157), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO157"), + MTK_FUNCTION(1, "BPI_BUS8"), + MTK_FUNCTION(4, "UTXD2"), + MTK_FUNCTION(5, "CLKM0_A"), + MTK_FUNCTION(6, "SSPM_URXD_AO_VCORE"), + MTK_FUNCTION(7, "DBG_MON_A16") + ), + MTK_PIN( + 158, "GPIO158", + MTK_EINT_FUNCTION(0, 158), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO158"), + MTK_FUNCTION(1, "BPI_BUS9"), + MTK_FUNCTION(4, "URXD2"), + MTK_FUNCTION(5, "CLKM1_A"), + MTK_FUNCTION(6, "TP_UTXD1_VCORE") + ), + MTK_PIN( + 159, "GPIO159", + MTK_EINT_FUNCTION(0, 159), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO159"), + MTK_FUNCTION(1, "BPI_BUS10"), + MTK_FUNCTION(2, "MD_INT0"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(5, "CLKM2_A"), + MTK_FUNCTION(6, "TP_URXD1_VCORE") + ), + MTK_PIN( + 160, "GPIO160", + MTK_EINT_FUNCTION(0, 160), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO160"), + MTK_FUNCTION(1, "UTXD0"), + MTK_FUNCTION(2, "MD_UTXD1"), + MTK_FUNCTION(5, "MBISTREADEN_TRIGGER"), + MTK_FUNCTION(6, "CONN_BG_GPS_MCU_DBG_UART_TX") + ), + MTK_PIN( + 161, "GPIO161", + MTK_EINT_FUNCTION(0, 161), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO161"), + MTK_FUNCTION(1, "URXD0"), + MTK_FUNCTION(2, "MD_URXD1"), + MTK_FUNCTION(5, "MBISTWRITEEN_TRIGGER") + ), + MTK_PIN( + 162, "GPIO162", + MTK_EINT_FUNCTION(0, 162), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO162"), + MTK_FUNCTION(1, "UTXD1"), + MTK_FUNCTION(2, "MD_UTXD0"), + MTK_FUNCTION(3, "TP_UTXD1_VLP"), + MTK_FUNCTION(4, "ADSP_UTXD0"), + MTK_FUNCTION(5, "SSPM_UTXD_AO_VLP"), + MTK_FUNCTION(6, "HFRP_UTXD1") + ), + MTK_PIN( + 163, "GPIO163", + MTK_EINT_FUNCTION(0, 163), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO163"), + MTK_FUNCTION(1, "URXD1"), + MTK_FUNCTION(2, "MD_URXD0"), + MTK_FUNCTION(3, "TP_URXD1_VLP"), + MTK_FUNCTION(4, "ADSP_URXD0"), + MTK_FUNCTION(5, "SSPM_URXD_AO_VLP"), + MTK_FUNCTION(6, "HFRP_URXD1") + ), + MTK_PIN( + 164, "GPIO164", + MTK_EINT_FUNCTION(0, 164), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO164"), + MTK_FUNCTION(1, "SCP_SCL0"), + MTK_FUNCTION(6, "TP_GPIO0_AO"), + MTK_FUNCTION(7, "DBG_MON_A22") + ), + MTK_PIN( + 165, "GPIO165", + MTK_EINT_FUNCTION(0, 165), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO165"), + MTK_FUNCTION(1, "SCP_SDA0"), + MTK_FUNCTION(6, "TP_GPIO1_AO"), + MTK_FUNCTION(7, "DBG_MON_A23") + ), + MTK_PIN( + 166, "GPIO166", + MTK_EINT_FUNCTION(0, 166), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO166"), + MTK_FUNCTION(1, "SCP_SCL2"), + MTK_FUNCTION(6, "TP_GPIO2_AO"), + MTK_FUNCTION(7, "DBG_MON_A24") + ), + MTK_PIN( + 167, "GPIO167", + MTK_EINT_FUNCTION(0, 167), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO167"), + MTK_FUNCTION(1, "SCP_SDA2"), + MTK_FUNCTION(6, "TP_GPIO3_AO"), + MTK_FUNCTION(7, "DBG_MON_A25") + ), + MTK_PIN( + 168, "GPIO168", + MTK_EINT_FUNCTION(0, 168), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO168"), + MTK_FUNCTION(1, "SCP_SPI2_CK"), + MTK_FUNCTION(2, "SPI2_B_CLK"), + MTK_FUNCTION(3, "PWM_VLP"), + MTK_FUNCTION(4, "SCP_SCL2"), + MTK_FUNCTION(7, "DBG_MON_A26") + ), + MTK_PIN( + 169, "GPIO169", + MTK_EINT_FUNCTION(0, 169), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO169"), + MTK_FUNCTION(1, "SCP_SPI2_CS"), + MTK_FUNCTION(2, "SPI2_B_CSB"), + MTK_FUNCTION(7, "DBG_MON_A27") + ), + MTK_PIN( + 170, "GPIO170", + MTK_EINT_FUNCTION(0, 170), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO170"), + MTK_FUNCTION(1, "SCP_SPI2_MO"), + MTK_FUNCTION(2, "SPI2_B_MO"), + MTK_FUNCTION(4, "SCP_SDA2"), + MTK_FUNCTION(7, "DBG_MON_A28") + ), + MTK_PIN( + 171, "GPIO171", + MTK_EINT_FUNCTION(0, 171), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO171"), + MTK_FUNCTION(1, "SCP_SPI2_MI"), + MTK_FUNCTION(2, "SPI2_B_MI"), + MTK_FUNCTION(7, "DBG_MON_A29") + ), + MTK_PIN( + 172, "GPIO172", + MTK_EINT_FUNCTION(0, 172), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO172"), + MTK_FUNCTION(1, "CONN_TCXOENA_REQ") + ), + MTK_PIN( + 173, "GPIO173", + MTK_EINT_FUNCTION(0, 173), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO173"), + MTK_FUNCTION(1, "CMFLASH3"), + MTK_FUNCTION(2, "PWM_3"), + MTK_FUNCTION(3, "MD_GPS_L5_BLANK"), + MTK_FUNCTION(4, "CLKM1_A"), + MTK_FUNCTION(7, "DBG_MON_A31") + ), + MTK_PIN( + 174, "GPIO174", + MTK_EINT_FUNCTION(0, 174), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO174"), + MTK_FUNCTION(1, "CMFLASH0"), + MTK_FUNCTION(2, "PWM_0"), + MTK_FUNCTION(3, "VBUSVALID_1P"), + MTK_FUNCTION(4, "MD32_2_RXD"), + MTK_FUNCTION(5, "DISP_PWM3") + ), + MTK_PIN( + 175, "GPIO175", + MTK_EINT_FUNCTION(0, 175), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO175"), + MTK_FUNCTION(1, "CMFLASH1"), + MTK_FUNCTION(2, "PWM_1"), + MTK_FUNCTION(3, "EDP_TX_HPD"), + MTK_FUNCTION(4, "MD32_2_TXD"), + MTK_FUNCTION(5, "DISP_PWM4") + ), + MTK_PIN( + 176, "GPIO176", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO176"), + MTK_FUNCTION(1, "SCL5"), + MTK_FUNCTION(2, "LCM3_RST"), + MTK_FUNCTION(4, "MD_URXD1_CONN"), + MTK_FUNCTION(6, "TP_UTXD_GNSS_VCORE") + ), + MTK_PIN( + 177, "GPIO177", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO177"), + MTK_FUNCTION(1, "SDA5"), + MTK_FUNCTION(2, "DSI3_TE"), + MTK_FUNCTION(4, "MD_UTXD1_CONN"), + MTK_FUNCTION(6, "TP_URXD_GNSS_VCORE") + ), + MTK_PIN( + 178, "GPIO178", + MTK_EINT_FUNCTION(0, 178), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO178"), + MTK_FUNCTION(1, "DMIC_CLK"), + MTK_FUNCTION(2, "SCP_DMIC_CLK"), + MTK_FUNCTION(3, "SRCLKENAI0"), + MTK_FUNCTION(4, "CLKM2_B"), + MTK_FUNCTION(5, "TP_GPIO7_AO"), + MTK_FUNCTION(6, "SPU1_UTX"), + MTK_FUNCTION(7, "DAP_SONIC_SWCK") + ), + MTK_PIN( + 179, "GPIO179", + MTK_EINT_FUNCTION(0, 179), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO179"), + MTK_FUNCTION(1, "DMIC_DAT"), + MTK_FUNCTION(2, "SCP_DMIC_DAT"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(4, "CLKM3_B"), + MTK_FUNCTION(5, "TP_GPIO8_AO"), + MTK_FUNCTION(6, "SPU1_URX"), + MTK_FUNCTION(7, "DAP_SONIC_SWD") + ), + MTK_PIN( + 180, "GPIO180", + MTK_EINT_FUNCTION(0, 180), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO180"), + MTK_FUNCTION(1, "IDDIG_1P"), + MTK_FUNCTION(2, "CMVREF0"), + MTK_FUNCTION(3, "GPS_PPS1"), + MTK_FUNCTION(4, "GPS_L5_ELNA_EN"), + MTK_FUNCTION(5, "DISP_PWM1") + ), + MTK_PIN( + 181, "GPIO181", + MTK_EINT_FUNCTION(0, 181), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO181"), + MTK_FUNCTION(1, "USB_DRVVBUS_1P"), + MTK_FUNCTION(2, "CMVREF1"), + MTK_FUNCTION(3, "MFG_EB_JTAG_TRSTN"), + MTK_FUNCTION(4, "ADSP_JTAG1_TRSTN"), + MTK_FUNCTION(5, "HFRP_JTAG1_TRSTN"), + MTK_FUNCTION(6, "SPU1_NTRST"), + MTK_FUNCTION(7, "CONN_BG_GPS_MCU_TRST_B") + ), + MTK_PIN( + 182, "GPIO182", + MTK_EINT_FUNCTION(0, 182), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO182"), + MTK_FUNCTION(1, "SCL11"), + MTK_FUNCTION(2, "CMVREF2"), + MTK_FUNCTION(3, "MFG_EB_JTAG_TCK"), + MTK_FUNCTION(4, "ADSP_JTAG1_TCK"), + MTK_FUNCTION(5, "HFRP_JTAG1_TCK"), + MTK_FUNCTION(6, "SPU1_TCK"), + MTK_FUNCTION(7, "CONN_BG_GPS_MCU_TCK") + ), + MTK_PIN( + 183, "GPIO183", + MTK_EINT_FUNCTION(0, 183), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO183"), + MTK_FUNCTION(1, "SDA11"), + MTK_FUNCTION(2, "CMVREF3"), + MTK_FUNCTION(3, "MFG_EB_JTAG_TMS"), + MTK_FUNCTION(4, "ADSP_JTAG1_TMS"), + MTK_FUNCTION(5, "HFRP_JTAG1_TMS"), + MTK_FUNCTION(6, "SPU1_TMS"), + MTK_FUNCTION(7, "CONN_BG_GPS_MCU_TMS") + ), + MTK_PIN( + 184, "GPIO184", + MTK_EINT_FUNCTION(0, 184), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO184"), + MTK_FUNCTION(1, "SCL12"), + MTK_FUNCTION(2, "CMVREF4"), + MTK_FUNCTION(3, "MFG_EB_JTAG_TDO"), + MTK_FUNCTION(4, "ADSP_JTAG1_TDO"), + MTK_FUNCTION(5, "HFRP_JTAG1_TDO"), + MTK_FUNCTION(6, "SPU1_TDO"), + MTK_FUNCTION(7, "CONN_BG_GPS_MCU_TDO") + ), + MTK_PIN( + 185, "GPIO185", + MTK_EINT_FUNCTION(0, 185), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO185"), + MTK_FUNCTION(1, "SDA12"), + MTK_FUNCTION(2, "CMVREF5"), + MTK_FUNCTION(3, "MFG_EB_JTAG_TDI"), + MTK_FUNCTION(4, "ADSP_JTAG1_TDI"), + MTK_FUNCTION(5, "HFRP_JTAG1_TDI"), + MTK_FUNCTION(6, "SPU1_TDI"), + MTK_FUNCTION(7, "CONN_BG_GPS_MCU_TDI") + ), + MTK_PIN( + 186, "GPIO186", + MTK_EINT_FUNCTION(0, 186), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO186"), + MTK_FUNCTION(1, "MD_GPS_L1_BLANK"), + MTK_FUNCTION(2, "PMSR_SMAP"), + MTK_FUNCTION(3, "TP_GPIO2_AO") + ), + MTK_PIN( + 187, "GPIO187", + MTK_EINT_FUNCTION(0, 187), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO187"), + MTK_FUNCTION(1, "MD_GPS_L5_BLANK"), + MTK_FUNCTION(3, "TP_GPIO4_AO") + ), + MTK_PIN( + 188, "GPIO188", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO188"), + MTK_FUNCTION(1, "SCL2"), + MTK_FUNCTION(2, "SCP_SCL8") + ), + MTK_PIN( + 189, "GPIO189", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO189"), + MTK_FUNCTION(1, "SDA2"), + MTK_FUNCTION(2, "SCP_SDA8") + ), + MTK_PIN( + 190, "GPIO190", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO190"), + MTK_FUNCTION(1, "SCL4"), + MTK_FUNCTION(2, "SCP_SCL9"), + MTK_FUNCTION(6, "UDI_TDI_6") + ), + MTK_PIN( + 191, "GPIO191", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO191"), + MTK_FUNCTION(1, "SDA4"), + MTK_FUNCTION(2, "SCP_SDA9"), + MTK_FUNCTION(6, "UDI_TDI_7") + ), + MTK_PIN( + 192, "GPIO192", + MTK_EINT_FUNCTION(0, 192), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO192"), + MTK_FUNCTION(1, "CMMCLK2"), + MTK_FUNCTION(4, "MD32_3_RXD") + ), + MTK_PIN( + 193, "GPIO193", + MTK_EINT_FUNCTION(0, 193), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO193"), + MTK_FUNCTION(3, "CLKM0_B"), + MTK_FUNCTION(4, "MD32_3_TXD"), + MTK_FUNCTION(6, "UDI_TDO_7") + ), + MTK_PIN( + 194, "GPIO194", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO194"), + MTK_FUNCTION(1, "SCL7"), + MTK_FUNCTION(2, "MD32_3_GPIO0"), + MTK_FUNCTION(3, "CLKM2_B"), + MTK_FUNCTION(6, "UDI_TDI_2") + ), + MTK_PIN( + 195, "GPIO195", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO195"), + MTK_FUNCTION(1, "SDA7"), + MTK_FUNCTION(3, "CLKM3_B"), + MTK_FUNCTION(6, "UDI_TDI_3") + ), + MTK_PIN( + 196, "GPIO196", + MTK_EINT_FUNCTION(0, 196), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO196"), + MTK_FUNCTION(1, "CMMCLK3") + ), + MTK_PIN( + 197, "GPIO197", + MTK_EINT_FUNCTION(0, 197), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO197"), + MTK_FUNCTION(3, "CLKM1_B"), + MTK_FUNCTION(6, "UDI_TDI_1") + ), + MTK_PIN( + 198, "GPIO198", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO198"), + MTK_FUNCTION(1, "SCL8"), + MTK_FUNCTION(6, "UDI_TDI_4") + ), + MTK_PIN( + 199, "GPIO199", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO199"), + MTK_FUNCTION(1, "SDA8"), + MTK_FUNCTION(6, "UDI_TDI_5") + ), + MTK_PIN( + 200, "GPIO200", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO200"), + MTK_FUNCTION(1, "SCL1") + ), + MTK_PIN( + 201, "GPIO201", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO201"), + MTK_FUNCTION(1, "SDA1"), + MTK_FUNCTION(7, "TSFDC_BG_COMP") + ), + MTK_PIN( + 202, "GPIO202", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO202"), + MTK_FUNCTION(1, "SCL9"), + MTK_FUNCTION(2, "SCP_SCL7"), + MTK_FUNCTION(6, "TP_GPIO15_AO") + ), + MTK_PIN( + 203, "GPIO203", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO203"), + MTK_FUNCTION(1, "SDA9"), + MTK_FUNCTION(2, "SCP_SDA7"), + MTK_FUNCTION(6, "TP_GPIO9_AO") + ), + MTK_PIN( + 204, "GPIO204", + MTK_EINT_FUNCTION(0, 204), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO204"), + MTK_FUNCTION(1, "SCL13"), + MTK_FUNCTION(2, "CMVREF6"), + MTK_FUNCTION(3, "GPS_L1_ELNA_EN"), + MTK_FUNCTION(5, "CLKM2_B"), + MTK_FUNCTION(6, "TP_GPIO12_AO") + ), + MTK_PIN( + 205, "GPIO205", + MTK_EINT_FUNCTION(0, 205), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO205"), + MTK_FUNCTION(1, "SDA13"), + MTK_FUNCTION(2, "CMVREF7"), + MTK_FUNCTION(3, "GPS_L5_ELNA_EN"), + MTK_FUNCTION(5, "CLKM3_B"), + MTK_FUNCTION(6, "TP_GPIO13_AO") + ), + MTK_PIN( + 206, "GPIO206", + MTK_EINT_FUNCTION(0, 206), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO206"), + MTK_FUNCTION(2, "MD32_2_GPIO0"), + MTK_FUNCTION(5, "VBUSVALID"), + MTK_FUNCTION(6, "UDI_TDO_3") + ), + MTK_PIN( + 207, "GPIO207", + MTK_EINT_FUNCTION(0, 207), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO207"), + MTK_FUNCTION(1, "PCIE_WAKEN_2P"), + MTK_FUNCTION(2, "PMSR_SMAP_MAX"), + MTK_FUNCTION(4, "FMI2S_A_BCK"), + MTK_FUNCTION(6, "UDI_TDO_4") + ), + MTK_PIN( + 208, "GPIO208", + MTK_EINT_FUNCTION(0, 208), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO208"), + MTK_FUNCTION(1, "PCIE_CLKREQN_2P"), + MTK_FUNCTION(2, "PMSR_SMAP_MAX_W"), + MTK_FUNCTION(4, "FMI2S_A_LRCK"), + MTK_FUNCTION(5, "CLKM0_B"), + MTK_FUNCTION(6, "UDI_TDO_5") + ), + MTK_PIN( + 209, "GPIO209", + MTK_EINT_FUNCTION(0, 209), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO209"), + MTK_FUNCTION(1, "PCIE_PERSTN_2P"), + MTK_FUNCTION(2, "PMSR_SMAP"), + MTK_FUNCTION(4, "FMI2S_A_DI"), + MTK_FUNCTION(5, "CLKM1_B"), + MTK_FUNCTION(6, "UDI_TDO_6") + ), + MTK_PIN( + 210, "GPIO210", + MTK_EINT_FUNCTION(0, 210), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO210"), + MTK_FUNCTION(1, "CMMCLK4") + ), + MTK_PIN( + 211, "GPIO211", + MTK_EINT_FUNCTION(0, 211), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO211"), + MTK_FUNCTION(1, "CMMCLK5"), + MTK_FUNCTION(2, "CONN_TCXOENA_REQ") + ), + MTK_PIN( + 212, "GPIO212", + MTK_EINT_FUNCTION(0, 212), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO212"), + MTK_FUNCTION(1, "CMMCLK6"), + MTK_FUNCTION(2, "TP_GPIO10_AO"), + MTK_FUNCTION(5, "IDDIG"), + MTK_FUNCTION(6, "UDI_TDO_1") + ), + MTK_PIN( + 213, "GPIO213", + MTK_EINT_FUNCTION(0, 213), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO213"), + MTK_FUNCTION(1, "CMMCLK7"), + MTK_FUNCTION(2, "TP_GPIO11_AO"), + MTK_FUNCTION(5, "USB_DRVVBUS"), + MTK_FUNCTION(6, "UDI_TDO_2") + ), + MTK_PIN( + 214, "GPIO214", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO214"), + MTK_FUNCTION(1, "SCP_SCL3"), + MTK_FUNCTION(2, "SDA14_E1_SCL14_E2"), + MTK_FUNCTION(6, "GBE1_MDC"), + MTK_FUNCTION(7, "GBE0_MDC") + ), + MTK_PIN( + 215, "GPIO215", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO215"), + MTK_FUNCTION(1, "SCP_SDA3"), + MTK_FUNCTION(2, "SCL14_E1_SDA14_E2"), + MTK_FUNCTION(6, "GBE1_MDIO"), + MTK_FUNCTION(7, "GBE0_MDIO") + ), + MTK_PIN( + 216, "GPIO216", + MTK_EINT_FUNCTION(0, 216), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO216"), + MTK_FUNCTION(1, "GPS_PPS0") + ), + MTK_PIN( + 217, "GPIO217", + MTK_EINT_FUNCTION(0, 217), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO217"), + MTK_FUNCTION(1, "KPROW0"), + MTK_FUNCTION(6, "TP_GPIO12_AO") + ), + MTK_PIN( + 218, "GPIO218", + MTK_EINT_FUNCTION(0, 218), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO218"), + MTK_FUNCTION(1, "KPROW1"), + MTK_FUNCTION(2, "SPI0_WP"), + MTK_FUNCTION(3, "MBISTREADEN_TRIGGER"), + MTK_FUNCTION(5, "GPS_L5_ELNA_EN"), + MTK_FUNCTION(6, "TP_GPIO14_AO") + ), + MTK_PIN( + 219, "GPIO219", + MTK_EINT_FUNCTION(0, 219), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO219"), + MTK_FUNCTION(1, "KPCOL1"), + MTK_FUNCTION(2, "SPI0_HOLD"), + MTK_FUNCTION(3, "MBISTWRITEEN_TRIGGER"), + MTK_FUNCTION(4, "SPMI_M_TRIG_FLAG"), + MTK_FUNCTION(5, "GPS_L1_ELNA_EN"), + MTK_FUNCTION(6, "SPM_JTAG_TRSTN_VLP"), + MTK_FUNCTION(7, "JTRSTN_SEL1") + ), + MTK_PIN( + 220, "GPIO220", + MTK_EINT_FUNCTION(0, 220), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO220"), + MTK_FUNCTION(1, "SPI0_CLK"), + MTK_FUNCTION(6, "SPM_JTAG_TCK_VLP"), + MTK_FUNCTION(7, "JTCK_SEL1") + ), + MTK_PIN( + 221, "GPIO221", + MTK_EINT_FUNCTION(0, 221), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO221"), + MTK_FUNCTION(1, "SPI0_CSB"), + MTK_FUNCTION(6, "SPM_JTAG_TMS_VLP"), + MTK_FUNCTION(7, "JTMS_SEL1") + ), + MTK_PIN( + 222, "GPIO222", + MTK_EINT_FUNCTION(0, 222), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO222"), + MTK_FUNCTION(1, "SPI0_MO"), + MTK_FUNCTION(2, "SCP_SCL7"), + MTK_FUNCTION(6, "SPM_JTAG_TDO_VLP"), + MTK_FUNCTION(7, "JTDO_SEL1") + ), + MTK_PIN( + 223, "GPIO223", + MTK_EINT_FUNCTION(0, 223), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO223"), + MTK_FUNCTION(1, "SPI0_MI"), + MTK_FUNCTION(2, "SCP_SDA7"), + MTK_FUNCTION(6, "SPM_JTAG_TDI_VLP"), + MTK_FUNCTION(7, "JTDI_SEL1") + ), + MTK_PIN( + 224, "GPIO224", + MTK_EINT_FUNCTION(0, 224), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO224"), + MTK_FUNCTION(1, "MSDC2_CLK"), + MTK_FUNCTION(2, "DMIC2_CLK"), + MTK_FUNCTION(3, "GBE0_AUX_PPS0"), + MTK_FUNCTION(4, "GBE0_TXER"), + MTK_FUNCTION(5, "GBE1_TXER"), + MTK_FUNCTION(6, "GBE1_AUX_PPS0"), + MTK_FUNCTION(7, "MD32_1_TXD") + ), + MTK_PIN( + 225, "GPIO225", + MTK_EINT_FUNCTION(0, 225), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO225"), + MTK_FUNCTION(1, "MSDC2_CMD"), + MTK_FUNCTION(2, "DMIC2_DAT"), + MTK_FUNCTION(3, "GBE0_AUX_PPS1"), + MTK_FUNCTION(4, "GBE0_RXER"), + MTK_FUNCTION(5, "GBE1_RXER"), + MTK_FUNCTION(6, "GBE1_AUX_PPS1"), + MTK_FUNCTION(7, "MD32_1_RXD") + ), + MTK_PIN( + 226, "GPIO226", + MTK_EINT_FUNCTION(0, 226), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO226"), + MTK_FUNCTION(1, "MSDC2_DAT0"), + MTK_FUNCTION(2, "I2SIN3_BCK"), + MTK_FUNCTION(3, "GBE0_AUX_PPS2"), + MTK_FUNCTION(4, "GBE0_COL"), + MTK_FUNCTION(5, "GBE1_COL"), + MTK_FUNCTION(6, "GBE1_AUX_PPS2"), + MTK_FUNCTION(7, "GBE1_MDC") + ), + MTK_PIN( + 227, "GPIO227", + MTK_EINT_FUNCTION(0, 227), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO227"), + MTK_FUNCTION(1, "MSDC2_DAT1"), + MTK_FUNCTION(2, "I2SIN3_LRCK"), + MTK_FUNCTION(3, "GBE0_AUX_PPS3"), + MTK_FUNCTION(4, "GBE0_INTR"), + MTK_FUNCTION(5, "GBE1_INTR"), + MTK_FUNCTION(6, "GBE1_AUX_PPS3"), + MTK_FUNCTION(7, "GBE1_MDIO") + ), + MTK_PIN( + 228, "GPIO228", + MTK_EINT_FUNCTION(0, 228), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO228"), + MTK_FUNCTION(1, "MSDC2_DAT2"), + MTK_FUNCTION(2, "I2SIN3_DI"), + MTK_FUNCTION(3, "GBE0_MDC"), + MTK_FUNCTION(4, "GBE1_MDC"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_AICE_TCKC") + ), + MTK_PIN( + 229, "GPIO229", + MTK_EINT_FUNCTION(0, 229), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO229"), + MTK_FUNCTION(1, "MSDC2_DAT3"), + MTK_FUNCTION(2, "I2SOUT3_DO"), + MTK_FUNCTION(3, "GBE0_MDIO"), + MTK_FUNCTION(4, "GBE1_MDIO"), + MTK_FUNCTION(5, "CONN_BG_GPS_MCU_AICE_TMSC"), + MTK_FUNCTION(7, "AVB_CLK2") + ), + MTK_PIN( + 230, "GPIO230", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO230"), + MTK_FUNCTION(1, "CONN_TOP_CLK") + ), + MTK_PIN( + 231, "GPIO231", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO231"), + MTK_FUNCTION(1, "CONN_TOP_DATA") + ), + MTK_PIN( + 232, "GPIO232", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO232"), + MTK_FUNCTION(1, "CONN_HRST_B") + ), + MTK_PIN( + 233, "GPIO233", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO233"), + MTK_FUNCTION(1, "I2SIN0_BCK") + ), + MTK_PIN( + 234, "GPIO234", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO234"), + MTK_FUNCTION(1, "I2SIN0_LRCK") + ), + MTK_PIN( + 235, "GPIO235", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO235"), + MTK_FUNCTION(1, "I2SIN0_DI") + ), + MTK_PIN( + 236, "GPIO236", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO236"), + MTK_FUNCTION(1, "I2SOUT0_DO") + ), + MTK_PIN( + 237, "GPIO237", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO237"), + MTK_FUNCTION(1, "CONN_UARTHUB_UART_TX"), + MTK_FUNCTION(3, "UTXD3") + ), + MTK_PIN( + 238, "GPIO238", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO238"), + MTK_FUNCTION(1, "CONN_UARTHUB_UART_RX"), + MTK_FUNCTION(3, "URXD3") + ), + MTK_PIN( + 239, "GPIO239", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO239"), + MTK_FUNCTION(1, "TP_UTXD_CONSYS_VLP"), + MTK_FUNCTION(2, "TP_URXD_CONSYS_VLP") + ), + MTK_PIN( + 240, "GPIO240", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO240"), + MTK_FUNCTION(1, "TP_URXD_CONSYS_VLP"), + MTK_FUNCTION(2, "TP_UTXD_CONSYS_VLP") + ), + MTK_PIN( + 241, "GPIO241", + MTK_EINT_FUNCTION(0, 241), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO241"), + MTK_FUNCTION(1, "PCIE_PERSTN") + ), + MTK_PIN( + 242, "GPIO242", + MTK_EINT_FUNCTION(0, 242), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO242"), + MTK_FUNCTION(1, "PCIE_WAKEN") + ), + MTK_PIN( + 243, "GPIO243", + MTK_EINT_FUNCTION(0, 243), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO243"), + MTK_FUNCTION(1, "PCIE_CLKREQN") + ), + MTK_PIN( + 244, "GPIO244", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO244"), + MTK_FUNCTION(1, "CONN_RST") + ), + MTK_PIN( + 245, "GPIO245", + MTK_EINT_FUNCTION(0, 245), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO245") + ), + MTK_PIN( + 246, "GPIO246", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO246"), + MTK_FUNCTION(1, "CONN_PTA_TXD0") + ), + MTK_PIN( + 247, "GPIO247", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO247"), + MTK_FUNCTION(1, "CONN_PTA_RXD0") + ), + MTK_PIN( + 248, "GPIO248", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO248"), + MTK_FUNCTION(3, "UCTS3") + ), + MTK_PIN( + 249, "GPIO249", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO249"), + MTK_FUNCTION(3, "URTS3") + ), + MTK_PIN( + 250, "GPIO250", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO250") + ), + MTK_PIN( + 251, "GPIO251", + MTK_EINT_FUNCTION(0, 251), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO251"), + MTK_FUNCTION(1, "IDDIG_1P") + ), + MTK_PIN( + 252, "GPIO252", + MTK_EINT_FUNCTION(0, 252), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO252"), + MTK_FUNCTION(1, "USB_DRVVBUS_1P") + ), + MTK_PIN( + 253, "GPIO253", + MTK_EINT_FUNCTION(0, 253), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO253"), + MTK_FUNCTION(1, "VBUSVALID_1P") + ), + MTK_PIN( + 254, "GPIO254", + MTK_EINT_FUNCTION(0, 254), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO254"), + MTK_FUNCTION(1, "IDDIG_2P") + ), + MTK_PIN( + 255, "GPIO255", + MTK_EINT_FUNCTION(0, 255), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO255"), + MTK_FUNCTION(1, "USB_DRVVBUS_2P") + ), + MTK_PIN( + 256, "GPIO256", + MTK_EINT_FUNCTION(0, 256), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO256"), + MTK_FUNCTION(1, "VBUSVALID_2P") + ), + MTK_PIN( + 257, "GPIO257", + MTK_EINT_FUNCTION(0, 257), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO257"), + MTK_FUNCTION(1, "VBUSVALID_3P") + ), + MTK_PIN( + 258, "GPIO258", + MTK_EINT_FUNCTION(0, 258), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO258"), + MTK_FUNCTION(7, "AVB_CLK1") + ), + MTK_PIN( + 259, "GPIO259", + MTK_EINT_FUNCTION(0, 259), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO259"), + MTK_FUNCTION(1, "GBE0_TXD0"), + MTK_FUNCTION(2, "GBE1_TXD0") + ), + MTK_PIN( + 260, "GPIO260", + MTK_EINT_FUNCTION(0, 260), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO260"), + MTK_FUNCTION(1, "GBE0_TXD1"), + MTK_FUNCTION(2, "GBE1_TXD1") + ), + MTK_PIN( + 261, "GPIO261", + MTK_EINT_FUNCTION(0, 261), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO261"), + MTK_FUNCTION(1, "GBE0_TXC"), + MTK_FUNCTION(2, "GBE1_TXC") + ), + MTK_PIN( + 262, "GPIO262", + MTK_EINT_FUNCTION(0, 262), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO262"), + MTK_FUNCTION(1, "GBE0_TXEN"), + MTK_FUNCTION(2, "GBE1_TXEN") + ), + MTK_PIN( + 263, "GPIO263", + MTK_EINT_FUNCTION(0, 263), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO263"), + MTK_FUNCTION(1, "GBE0_RXD0"), + MTK_FUNCTION(2, "GBE1_RXD0"), + MTK_FUNCTION(3, "GBE0_AUX_PPS0") + ), + MTK_PIN( + 264, "GPIO264", + MTK_EINT_FUNCTION(0, 264), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO264"), + MTK_FUNCTION(1, "GBE0_RXD1"), + MTK_FUNCTION(2, "GBE1_RXD1"), + MTK_FUNCTION(3, "GBE0_AUX_PPS1") + ), + MTK_PIN( + 265, "GPIO265", + MTK_EINT_FUNCTION(0, 265), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO265"), + MTK_FUNCTION(1, "GBE0_RXC"), + MTK_FUNCTION(2, "GBE1_RXC"), + MTK_FUNCTION(3, "GBE0_AUX_PPS2") + ), + MTK_PIN( + 266, "GPIO266", + MTK_EINT_FUNCTION(0, 266), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO266"), + MTK_FUNCTION(1, "GBE0_RXDV"), + MTK_FUNCTION(2, "GBE1_RXDV"), + MTK_FUNCTION(3, "GBE0_AUX_PPS3") + ), + MTK_PIN( + 267, "GPIO267", + MTK_EINT_FUNCTION(0, 267), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO267"), + MTK_FUNCTION(1, "GBE0_TXD2"), + MTK_FUNCTION(2, "GBE1_TXD2"), + MTK_FUNCTION(3, "GBE0_RXER"), + MTK_FUNCTION(4, "GBE1_RXER") + ), + MTK_PIN( + 268, "GPIO268", + MTK_EINT_FUNCTION(0, 268), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO268"), + MTK_FUNCTION(1, "GBE0_TXD3"), + MTK_FUNCTION(2, "GBE1_TXD3") + ), + MTK_PIN( + 269, "GPIO269", + MTK_EINT_FUNCTION(0, 269), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO269"), + MTK_FUNCTION(1, "GBE0_RXD2"), + MTK_FUNCTION(2, "GBE1_RXD2"), + MTK_FUNCTION(3, "GBE0_MDC") + ), + MTK_PIN( + 270, "GPIO270", + MTK_EINT_FUNCTION(0, 270), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO270"), + MTK_FUNCTION(1, "GBE0_RXD3"), + MTK_FUNCTION(2, "GBE1_RXD3"), + MTK_FUNCTION(3, "GBE0_MDIO") + ), + MTK_PIN( + 271, "veint271", + MTK_EINT_FUNCTION(0, 271), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 272, "veint272", + MTK_EINT_FUNCTION(0, 272), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 273, "veint273", + MTK_EINT_FUNCTION(0, 273), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 274, "veint274", + MTK_EINT_FUNCTION(0, 274), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 275, "veint275", + MTK_EINT_FUNCTION(0, 275), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 276, "veint276", + MTK_EINT_FUNCTION(0, 276), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 277, "veint277", + MTK_EINT_FUNCTION(0, 277), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 278, "veint278", + MTK_EINT_FUNCTION(0, 278), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 279, "veint279", + MTK_EINT_FUNCTION(0, 279), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 280, "veint280", + MTK_EINT_FUNCTION(0, 280), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 281, "veint281", + MTK_EINT_FUNCTION(0, 281), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 282, "veint282", + MTK_EINT_FUNCTION(0, 282), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 283, "veint283", + MTK_EINT_FUNCTION(0, 283), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 284, "veint284", + MTK_EINT_FUNCTION(0, 284), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 285, "veint285", + MTK_EINT_FUNCTION(0, 285), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 286, "veint286", + MTK_EINT_FUNCTION(0, 286), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 287, "veint287", + MTK_EINT_FUNCTION(0, 287), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 288, "veint288", + MTK_EINT_FUNCTION(0, 288), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 289, "veint289", + MTK_EINT_FUNCTION(0, 289), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 290, "veint290", + MTK_EINT_FUNCTION(0, 290), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 291, "veint291", + MTK_EINT_FUNCTION(0, 291), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 292, "veint292", + MTK_EINT_FUNCTION(0, 292), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ) +}; + +#endif /* __PINCTRL__MTK_MT8196_H */ -- GitLab From eb6be1bb0741d17365d4b22d72dad99da99a742a Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 7 Jan 2025 12:05:58 -0800 Subject: [PATCH 302/456] FROMLIST: arm64: errata: Add QCOM_KRYO_4XX_GOLD to the spectre_bhb_k24_list Qualcomm Kryo 400-series Gold cores have a derivative of an ARM Cortex A76 in them. Since A76 needs Spectre mitigation via looping then the Kyro 400-series Gold cores also need Spectre mitigation via looping. Qualcomm has confirmed that the proper "k" value for Kryo 400-series Gold cores is 24. Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels") Cc: stable@vger.kernel.org Cc: Scott Bauer Signed-off-by: Douglas Anderson (am from https://patchwork.kernel.org/patch/13929573/) (also found at https://lore.kernel.org/r/20250107120555.v4.1.Ie4ef54abe02e7eb0eee50f830575719bf23bda48@changeid) UPSTREAM-TASK=b:388304073 BUG=b:382116385 TEST=lscpu shows mitigation in place Change-Id: Ie4ef54abe02e7eb0eee50f830575719bf23bda48 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6150152 Commit-Queue: Stephen Boyd Reviewed-by: Sean Paul Auto-Submit: Douglas Anderson Reviewed-by: Stephen Boyd Tested-by: Douglas Anderson Signed-off-by: Hubert Mazur --- arch/arm64/kernel/proton-pack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 57503dc4b22fa..23848ba417d92 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -866,6 +866,7 @@ u8 spectre_bhb_loop_affected(int scope) MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD), {}, }; static const struct midr_range spectre_bhb_k11_list[] = { -- GitLab From 2d57acd8db3e2c33537e656c65be6186cab1de8f Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 8 Jan 2025 13:56:23 -0800 Subject: [PATCH 303/456] CHROMIUM: drm/img-rogue: Don't do anything on non-8173 hardware The img-rogue driver seems to do quite a bit of work at boot time even on hardware that doesn't have an Imagination GPU. Add a big band-aid into the driver to not do this. On at least one device without an Imagination GPU, the unnecessary init code was causing a KASAN splat at bootup. The KASAN error will now be avoided on devices without an Imagination GPU, but further research should be done to see if the KASAN error is present on devices with the Imagination GPU. UPSTREAM-TASK=b:249947433 BUG=b:388565491 TEST=Boot rauru and no more splat TEST=Boot rauru w/ initcall_debug and `... returned -19 after 172 usecs` TEST=Boot hana and GPU still inits Change-Id: Ia80adf9e7be9ad77466f0725d82b2b15bacab44c Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6160113 Commit-Queue: Stephen Boyd Reviewed-by: Stephen Boyd Signed-off-by: Hubert Mazur --- .../gpu/drm/img-rogue/1.17/pvr_platform_drv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c b/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c index b1586c9bf4340..9cb2d76cf53ab 100644 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c +++ b/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c @@ -291,6 +291,24 @@ static struct platform_driver pvr_platform_driver = { static int __init pvr_init(void) { int err; + struct device_node *np; + + /* + * CHROMIUM: + * + * This driver seems to do a bunch of stuff before it even detects + * if hardware is available. That's bad. In general drivers are + * supposed to be registering themselves and then actually doing + * something when they see the relevant hardware show up. + * + * Since this driver is downstream and doing an intrusive refactor + * would be disruptive, we'll just apply a large band-aid and early- + * return if we don't find the needed dt-compatible. + */ + np = of_find_compatible_node(NULL, NULL, SYS_RGX_OF_COMPATIBLE); + if (!np) + return -ENODEV; + of_node_put(np); DRM_DEBUG_DRIVER("\n"); -- GitLab From 293893312ab99afa4e6a8e19d5b5b4cf2e6c0166 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Thu, 2 Jan 2025 13:04:56 -0800 Subject: [PATCH 304/456] FROMGIT: platform/chrome: Update ChromeOS EC command tracing Mechanically update tracing with new command: sed -n 's/^#define \(EC_CMD_[[:alnum:]_]*\)\s.*/\tTRACE_SYMBOL(\1), \\/p' include/linux/platform_data/cros_ec_commands.h Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20250102210456.2399245-1-gwendal@chromium.org Signed-off-by: Tzung-Bi Shih (cherry picked from commit df78050d1a1338dd3e07db959b42c2d03969ed30 https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git for-next) BUG=None TEST=All upstream commands are decodeded Change-Id: I007a8f8ce92bb21e5c4fe9b4f6521c7f6534d3e0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6065385 Commit-Queue: ChromeOS Auto Retry Tested-by: Gwendal Grignou Reviewed-by: Tzung-Bi Shih Reviewed-by: Benson Leung Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_trace.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index 425e9441b7ca5..9827b3117597c 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -122,8 +122,10 @@ TRACE_SYMBOL(EC_CMD_ENTERING_MODE), \ TRACE_SYMBOL(EC_CMD_I2C_PASSTHRU_PROTECT), \ TRACE_SYMBOL(EC_CMD_CEC_WRITE_MSG), \ + TRACE_SYMBOL(EC_CMD_CEC_READ_MSG), \ TRACE_SYMBOL(EC_CMD_CEC_SET), \ TRACE_SYMBOL(EC_CMD_CEC_GET), \ + TRACE_SYMBOL(EC_CMD_CEC_PORT_COUNT), \ TRACE_SYMBOL(EC_CMD_EC_CODEC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_DMIC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \ @@ -161,11 +163,18 @@ TRACE_SYMBOL(EC_CMD_ADC_READ), \ TRACE_SYMBOL(EC_CMD_ROLLBACK_INFO), \ TRACE_SYMBOL(EC_CMD_AP_RESET), \ + TRACE_SYMBOL(EC_CMD_PCHG_COUNT), \ + TRACE_SYMBOL(EC_CMD_PCHG), \ + TRACE_SYMBOL(EC_CMD_PCHG_UPDATE), \ TRACE_SYMBOL(EC_CMD_REGULATOR_GET_INFO), \ TRACE_SYMBOL(EC_CMD_REGULATOR_ENABLE), \ TRACE_SYMBOL(EC_CMD_REGULATOR_IS_ENABLED), \ TRACE_SYMBOL(EC_CMD_REGULATOR_SET_VOLTAGE), \ TRACE_SYMBOL(EC_CMD_REGULATOR_GET_VOLTAGE), \ + TRACE_SYMBOL(EC_CMD_TYPEC_DISCOVERY), \ + TRACE_SYMBOL(EC_CMD_TYPEC_CONTROL), \ + TRACE_SYMBOL(EC_CMD_TYPEC_STATUS), \ + TRACE_SYMBOL(EC_CMD_TYPEC_VDM_RESPONSE), \ TRACE_SYMBOL(EC_CMD_CR51_BASE), \ TRACE_SYMBOL(EC_CMD_CR51_LAST), \ TRACE_SYMBOL(EC_CMD_FP_PASSTHRU), \ @@ -184,6 +193,7 @@ TRACE_SYMBOL(EC_CMD_BATTERY_GET_STATIC), \ TRACE_SYMBOL(EC_CMD_BATTERY_GET_DYNAMIC), \ TRACE_SYMBOL(EC_CMD_CHARGER_CONTROL), \ + TRACE_SYMBOL(EC_CMD_USB_PD_MUX_ACK), \ TRACE_SYMBOL(EC_CMD_BOARD_SPECIFIC_BASE), \ TRACE_SYMBOL(EC_CMD_BOARD_SPECIFIC_LAST) -- GitLab From 99022872d54547653e4f98402aa38a28f2a8954f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:40 +0200 Subject: [PATCH 305/456] FROMGIT: drm/i915/ddi: change intel_ddi_init_{dp, hdmi}_connector() return type The caller doesn't actually need the returned struct intel_connector; it's stored in the ->attached_connector of intel_dp and intel_hdmi. Switch to returning an int with 0 for success and negative errors codes to be able to indicate success even when we don't have a connector. Reviewed-by: Suraj Kandpal Tested-by: Sergey Senozhatsky Link: https://patchwork.freedesktop.org/patch/msgid/8ef7fe838231919e85eaead640c51ad3e4550d27.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit e1980a977686d46dbf45687f7750f1c50d1d6cf8 https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: I1da794b0803aa343e1e239fb9d3bc7ebf506bae5 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151737 Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_ddi.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 1f0e2486e56da..dcc1daf9060b2 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4363,8 +4363,7 @@ static const struct drm_encoder_funcs intel_ddi_funcs = { .late_register = intel_ddi_encoder_late_register, }; -static struct intel_connector * -intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) +static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_connector *connector; @@ -4372,7 +4371,7 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) connector = intel_connector_alloc(); if (!connector) - return NULL; + return -ENOMEM; dig_port->dp.output_reg = DDI_BUF_CTL(port); if (DISPLAY_VER(i915) >= 14) @@ -4387,7 +4386,7 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) if (!intel_dp_init_connector(dig_port, connector)) { kfree(connector); - return NULL; + return -EINVAL; } if (dig_port->base.type == INTEL_OUTPUT_EDP) { @@ -4403,7 +4402,7 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) } } - return connector; + return 0; } static int intel_hdmi_reset_link(struct intel_encoder *encoder, @@ -4575,20 +4574,19 @@ static bool bdw_digital_port_connected(struct intel_encoder *encoder) return intel_de_read(dev_priv, GEN8_DE_PORT_ISR) & bit; } -static struct intel_connector * -intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) +static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) { struct intel_connector *connector; enum port port = dig_port->base.port; connector = intel_connector_alloc(); if (!connector) - return NULL; + return -ENOMEM; dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); intel_hdmi_init_connector(dig_port, connector); - return connector; + return 0; } static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) @@ -5137,7 +5135,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, intel_infoframe_init(dig_port); if (init_dp) { - if (!intel_ddi_init_dp_connector(dig_port)) + if (intel_ddi_init_dp_connector(dig_port)) goto err; dig_port->hpd_pulse = intel_dp_hpd_pulse; @@ -5151,7 +5149,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, * but leave it just in case we have some really bad VBTs... */ if (encoder->type != INTEL_OUTPUT_EDP && init_hdmi) { - if (!intel_ddi_init_hdmi_connector(dig_port)) + if (intel_ddi_init_hdmi_connector(dig_port)) goto err; } -- GitLab From 52101875ad11610bb36993d91e916d65d3471272 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:41 +0200 Subject: [PATCH 306/456] BACKPORT: FROMGIT: drm/i915/hdmi: propagate errors from intel_hdmi_init_connector() Propagate errors from intel_hdmi_init_connector() to be able to handle them at callers. This is similar to intel_dp_init_connector(). Cc: Sergey Senozhatsky Cc: Ville Syrjala Reported-and-tested-by: Sergey Senozhatsky Closes: https://lore.kernel.org/r/20241031105145.2140590-1-senozhatsky@chromium.org Reviewed-by: Sergey Senozhatsky Link: https://patchwork.freedesktop.org/patch/msgid/cdaf9e32cc4880c46e120933438c37b4d87be12e.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit 7fb56536fa37e23bc291d31c10e575d500f4fda7 https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) Conflicts: drivers/gpu/drm/i915/display/intel_hdmi.c BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: Ib738e1ecc6d20f267c1fa6010a774c6310bcd85e Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151738 Reviewed-by: Drew Davenport Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_hdmi.c | 10 ++++++---- drivers/gpu/drm/i915/display/intel_hdmi.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 116834466af6d..4704a90881a71 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3010,7 +3010,7 @@ void intel_infoframe_init(struct intel_digital_port *dig_port) } } -void intel_hdmi_init_connector(struct intel_digital_port *dig_port, +bool intel_hdmi_init_connector(struct intel_digital_port *dig_port, struct intel_connector *intel_connector) { struct drm_connector *connector = &intel_connector->base; @@ -3027,17 +3027,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, intel_encoder->base.base.id, intel_encoder->base.name); if (DISPLAY_VER(dev_priv) < 12 && drm_WARN_ON(dev, port == PORT_A)) - return; + return false; if (drm_WARN(dev, dig_port->max_lanes < 4, "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n", dig_port->max_lanes, intel_encoder->base.base.id, intel_encoder->base.name)) - return; + return false; ddc_pin = intel_hdmi_ddc_pin(intel_encoder); if (!ddc_pin) - return; + return false; drm_connector_init_with_ddc(dev, connector, &intel_hdmi_connector_funcs, @@ -3092,6 +3092,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, &conn_info); if (!intel_hdmi->cec_notifier) drm_dbg_kms(&dev_priv->drm, "CEC notifier get failed\n"); + + return true; } /* diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h index 51a7474d5cf1c..cfecfb010e4b8 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.h +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h @@ -22,7 +22,7 @@ struct intel_encoder; struct intel_hdmi; union hdmi_infoframe; -void intel_hdmi_init_connector(struct intel_digital_port *dig_port, +bool intel_hdmi_init_connector(struct intel_digital_port *dig_port, struct intel_connector *intel_connector); bool intel_hdmi_compute_has_hdmi_sink(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, -- GitLab From f8e7e93a1ee264db7821b3f29a1915a977e68f91 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:42 +0200 Subject: [PATCH 307/456] FROMGIT: drm/i915/hdmi: add error handling in g4x_hdmi_init() Handle encoder and connector init failures in g4x_hdmi_init(). This is similar to g4x_dp_init(). Cc: Sergey Senozhatsky Cc: Ville Syrjala Reported-and-tested-by: Sergey Senozhatsky Closes: https://lore.kernel.org/r/20241031105145.2140590-1-senozhatsky@chromium.org Reviewed-by: Sergey Senozhatsky Link: https://patchwork.freedesktop.org/patch/msgid/cafae7bf1f9ffb8f6a1d7a508cd2ce7dcf06fef7.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit 7603ba81225c815d2ceb4ad52f13e8df4b9d03cc https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: I1e6751aae5e1d9c341aad1ae71e0f4f836d48077 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151739 Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/g4x_hdmi.c | 35 ++++++++++++++++--------- drivers/gpu/drm/i915/display/g4x_hdmi.h | 5 ++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 45e044b4a88db..75a2af831dd96 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -677,7 +677,7 @@ static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port "Platform does not support HDMI %c\n", port_name(port)); } -void g4x_hdmi_init(struct drm_i915_private *dev_priv, +bool g4x_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, enum port port) { const struct intel_bios_encoder_data *devdata; @@ -686,10 +686,10 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv, struct intel_connector *intel_connector; if (!assert_port_valid(dev_priv, port)) - return; + return false; if (!assert_hdmi_port_valid(dev_priv, port)) - return; + return false; devdata = intel_bios_encoder_data_lookup(dev_priv, port); @@ -700,15 +700,13 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv, dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); if (!dig_port) - return; + return false; dig_port->aux_ch = AUX_CH_NONE; intel_connector = intel_connector_alloc(); - if (!intel_connector) { - kfree(dig_port); - return; - } + if (!intel_connector) + goto err_connector_alloc; intel_encoder = &dig_port->base; @@ -716,9 +714,10 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv, mutex_init(&dig_port->hdcp_mutex); - drm_encoder_init(&dev_priv->drm, &intel_encoder->base, - &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS, - "HDMI %c", port_name(port)); + if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base, + &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS, + "HDMI %c", port_name(port))) + goto err_encoder_init; intel_encoder->hotplug = intel_hdmi_hotplug; intel_encoder->compute_config = g4x_hdmi_compute_config; @@ -779,5 +778,17 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv, intel_infoframe_init(dig_port); - intel_hdmi_init_connector(dig_port, intel_connector); + if (!intel_hdmi_init_connector(dig_port, intel_connector)) + goto err_init_connector; + + return true; + +err_init_connector: + drm_encoder_cleanup(&intel_encoder->base); +err_encoder_init: + kfree(intel_connector); +err_connector_alloc: + kfree(dig_port); + + return false; } diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.h b/drivers/gpu/drm/i915/display/g4x_hdmi.h index 817f55c7a3a1e..a52e8986ec7ab 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.h +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.h @@ -16,14 +16,15 @@ struct drm_connector; struct drm_i915_private; #ifdef I915 -void g4x_hdmi_init(struct drm_i915_private *dev_priv, +bool g4x_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, enum port port); int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, struct drm_atomic_state *state); #else -static inline void g4x_hdmi_init(struct drm_i915_private *dev_priv, +static inline bool g4x_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, int port) { + return false; } static inline int g4x_hdmi_connector_atomic_check(struct drm_connector *connector, struct drm_atomic_state *state) -- GitLab From 37fe345d036b8b1974834cb624aaf53108570d68 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:43 +0200 Subject: [PATCH 308/456] FROMGIT: drm/i915/ddi: gracefully handle errors from intel_ddi_init_hdmi_connector() Errors from intel_ddi_init_hdmi_connector() can just mean "there's no HDMI" while we'll still want to continue with DP only. Handle the errors gracefully, but don't propagate. Clear the hdmi_reg which is used as a proxy to indicate the HDMI is initialized. v2: Gracefully handle but do not propagate Cc: Sergey Senozhatsky Cc: Ville Syrjala Reported-and-tested-by: Sergey Senozhatsky Closes: https://lore.kernel.org/r/20241031105145.2140590-1-senozhatsky@chromium.org Reviewed-by: Sergey Senozhatsky # v1 Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/d72cb54ac7cc5ca29b3b9d70e4d368ea41643b08.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit 8ea07e294ea2d046e16fa98e37007edcd4b9525d https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: Id7a5aa8e0fb38090d4aa7678fd453360c2da5040 Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151740 Reviewed-by: Tomasz Figa Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_ddi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dcc1daf9060b2..1e58d41f8b75a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4584,7 +4584,16 @@ static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) return -ENOMEM; dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); - intel_hdmi_init_connector(dig_port, connector); + + if (!intel_hdmi_init_connector(dig_port, connector)) { + /* + * HDMI connector init failures may just mean conflicting DDC + * pins or not having enough lanes. Handle them gracefully, but + * don't fail the entire DDI init. + */ + dig_port->hdmi.hdmi_reg = INVALID_MMIO_REG; + kfree(connector); + } return 0; } -- GitLab From 6ab93cc37713c9bb7585351da7f4be409376aea5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:44 +0200 Subject: [PATCH 309/456] FROMGIT: drm/i915/display: add intel_encoder_is_hdmi() Similar to intel_encoder_is_dp() and friends. Cc: Sergey Senozhatsky Cc: Ville Syrjala Reviewed-by: Suraj Kandpal Tested-by: Sergey Senozhatsky Link: https://patchwork.freedesktop.org/patch/msgid/e6bf9e01deb5d0d8b566af128a762d1313638847.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit efa43b751637c0e16a92e1787f1d8baaf56dafba https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: I0a76c9176357ca216e5b27f2998c0ed4eb027bed Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151741 Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_display_types.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ca6ba73d995de..4a390bf091f9d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -2052,6 +2052,19 @@ static inline bool intel_encoder_is_dp(struct intel_encoder *encoder) } } +static inline bool intel_encoder_is_hdmi(struct intel_encoder *encoder) +{ + switch (encoder->type) { + case INTEL_OUTPUT_HDMI: + return true; + case INTEL_OUTPUT_DDI: + /* See if the HDMI encoder is valid. */ + return i915_mmio_reg_valid(enc_to_intel_hdmi(encoder)->hdmi_reg); + default: + return false; + } +} + static inline struct intel_lspcon * enc_to_intel_lspcon(struct intel_encoder *encoder) { -- GitLab From 31810dd09cc59da747d0c4e3b53825e006ce68f1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Dec 2024 16:14:45 +0200 Subject: [PATCH 310/456] FROMGIT: drm/i915/ddi: only call shutdown hooks for valid encoders DDI might be HDMI or DP only, leaving the other encoder uninitialized. Calling the shutdown hook on an uninitialized encoder may lead to a NULL pointer dereference. Check the encoder types (and thus validity via the DP output_reg or HDMI hdmi_reg checks) before calling the hooks. Reported-and-tested-by: Sergey Senozhatsky Closes: https://lore.kernel.org/r/20241031105145.2140590-1-senozhatsky@chromium.org Cc: Sergey Senozhatsky Cc: Ville Syrjala Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/8b197c50e7f3be2bbc07e3935b21e919815015d5.1735568047.git.jani.nikula@intel.com Signed-off-by: Jani Nikula (cherry picked from commit 60a43ecbd59decb77b31c09a73f09e1d4f4d1c4c https://gitlab.freedesktop.org/drm/i915/kernel.git drm-intel-next) BUG=b:384399086 TEST=tested shutdown on dedede Change-Id: I5dc172860fbd591d17496a3359682aa4c390bbfd Signed-off-by: Sergey Senozhatsky Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6151742 Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 1e58d41f8b75a..5aca8a7fd93c7 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4750,8 +4750,10 @@ static void intel_ddi_tc_encoder_suspend_complete(struct intel_encoder *encoder) static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) { - intel_dp_encoder_shutdown(encoder); - intel_hdmi_encoder_shutdown(encoder); + if (intel_encoder_is_dp(encoder)) + intel_dp_encoder_shutdown(encoder); + if (intel_encoder_is_hdmi(encoder)) + intel_hdmi_encoder_shutdown(encoder); } static void intel_ddi_tc_encoder_shutdown_complete(struct intel_encoder *encoder) -- GitLab From 51377a1be891daa0def46e3c682d97d0da6f14ce Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 2 Apr 2024 19:47:10 -0500 Subject: [PATCH 311/456] UPSTREAM: platform/chrome: cros_ec_lpc: introduce a priv struct for the lpc device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lpc_driver_data stores the MMIO port base for EC mapped memory. cros_ec_lpc_readmem uses this port base instead of hardcoding EC_LPC_ADDR_MEMMAP. Signed-off-by: Dustin L. Howett Reviewed-by: Thomas Weißschuh Tested-by: Thomas Weißschuh Tested-by: Mario Limonciello Link: https://lore.kernel.org/r/20240403004713.130365-2-dustin@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit 8d4a9c69de19b10964e61398a60c3b7373d005a6) BUG=b:354066052 TEST=Compile Change-Id: I7cb5558bdf327d803f6ff5e4d0044cc3696c2760 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142442 Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 42e1770887fb0..e0fb636a185c3 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -34,6 +34,14 @@ /* True if ACPI device is present */ static bool cros_ec_lpc_acpi_device_found; +/** + * struct cros_ec_lpc - LPC device-specific data + * @mmio_memory_base: The first I/O port addressing EC mapped memory. + */ +struct cros_ec_lpc { + u16 mmio_memory_base; +}; + /** * struct lpc_driver_ops - LPC driver operations * @read: Copy length bytes from EC address offset into buffer dest. Returns @@ -290,6 +298,7 @@ done: static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset, unsigned int bytes, void *dest) { + struct cros_ec_lpc *ec_lpc = ec->priv; int i = offset; char *s = dest; int cnt = 0; @@ -299,13 +308,13 @@ static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset, /* fixed length */ if (bytes) { - cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + offset, bytes, s); + cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + offset, bytes, s); return bytes; } /* string */ for (; i < EC_MEMMAP_SIZE; i++, s++) { - cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + i, 1, s); + cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + i, 1, s); cnt++; if (!*s) break; @@ -353,9 +362,16 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) struct acpi_device *adev; acpi_status status; struct cros_ec_device *ec_dev; + struct cros_ec_lpc *ec_lpc; u8 buf[2] = {}; int irq, ret; + ec_lpc = devm_kzalloc(dev, sizeof(*ec_lpc), GFP_KERNEL); + if (!ec_lpc) + return -ENOMEM; + + ec_lpc->mmio_memory_base = EC_LPC_ADDR_MEMMAP; + /* * The Framework Laptop (and possibly other non-ChromeOS devices) * only exposes the eight I/O ports that are required for the Microchip EC. @@ -380,7 +396,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) cros_ec_lpc_ops.write = cros_ec_lpc_mec_write_bytes; cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); if (buf[0] != 'E' || buf[1] != 'C') { - if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE, + if (!devm_request_region(dev, ec_lpc->mmio_memory_base, EC_MEMMAP_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve memmap region\n"); return -EBUSY; @@ -389,7 +405,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) /* Re-assign read/write operations for the non MEC variant */ cros_ec_lpc_ops.read = cros_ec_lpc_read_bytes; cros_ec_lpc_ops.write = cros_ec_lpc_write_bytes; - cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, + cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2, buf); if (buf[0] != 'E' || buf[1] != 'C') { dev_err(dev, "EC ID not detected\n"); @@ -423,6 +439,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) ec_dev->din_size = sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); ec_dev->dout_size = sizeof(struct ec_host_request); + ec_dev->priv = ec_lpc; /* * Some boards do not have an IRQ allotted for cros_ec_lpc, -- GitLab From 0fb50042ccae7889f32f00442c2441cd7dea4076 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 2 Apr 2024 19:47:11 -0500 Subject: [PATCH 312/456] UPSTREAM: platform/chrome: cros_ec_lpc: pass driver_data from DMI to the device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lpc_driver_data will be stored in drvdata until probe is complete. Signed-off-by: Dustin L. Howett Reviewed-by: Thomas Weißschuh Tested-by: Thomas Weißschuh Tested-by: Mario Limonciello Link: https://lore.kernel.org/r/20240403004713.130365-3-dustin@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit c0e6ba2d0b117176e1329c2bfe3fa4c79301c6cd) BUG=b:354066052 TEST=Compile Change-Id: I8c8be692b1d62f8e74aa3d6ae27b80fa6ca8f4f8 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142443 Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index e0fb636a185c3..6650f373a32cd 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -629,14 +629,16 @@ static int __init cros_ec_lpc_init(void) { int ret; acpi_status status; + const struct dmi_system_id *dmi_match; status = acpi_get_devices(ACPI_DRV_NAME, cros_ec_lpc_parse_device, &cros_ec_lpc_acpi_device_found, NULL); if (ACPI_FAILURE(status)) pr_warn(DRV_NAME ": Looking for %s failed\n", ACPI_DRV_NAME); - if (!cros_ec_lpc_acpi_device_found && - !dmi_check_system(cros_ec_lpc_dmi_table)) { + dmi_match = dmi_first_match(cros_ec_lpc_dmi_table); + + if (!cros_ec_lpc_acpi_device_found && !dmi_match) { pr_err(DRV_NAME ": unsupported system.\n"); return -ENODEV; } @@ -649,6 +651,9 @@ static int __init cros_ec_lpc_init(void) } if (!cros_ec_lpc_acpi_device_found) { + /* Pass the DMI match's driver data down to the platform device */ + platform_set_drvdata(&cros_ec_lpc_device, dmi_match->driver_data); + /* Register the device, and it'll get hooked up automatically */ ret = platform_device_register(&cros_ec_lpc_device); if (ret) { -- GitLab From ffb4f0c47037bd20497bbe509558c8563ab09aa0 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 2 Apr 2024 19:47:12 -0500 Subject: [PATCH 313/456] UPSTREAM: platform/chrome: cros_ec_lpc: add a "quirks" system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some devices ship a ChromeOS EC in a non-standard configuration. Quirks allow cros_ec_lpc to account for these non-standard configurations. It only supports one quirk right now: - CROS_EC_LPC_QUIRK_REMAP_MEMORY: use a different port I/O base for MMIO to the EC's memory region Signed-off-by: Dustin L. Howett Reviewed-by: Thomas Weißschuh Tested-by: Thomas Weißschuh Tested-by: Mario Limonciello Link: https://lore.kernel.org/r/20240403004713.130365-4-dustin@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit e4dbf9d65e421860af09e5cb44177416bb3afe80) BUG=b:354066052 TEST=Compile Change-Id: I8e1072c4c663cb16a7b9da139603f46915a41d28 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142444 Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 6650f373a32cd..b6a711526eeeb 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -34,6 +34,24 @@ /* True if ACPI device is present */ static bool cros_ec_lpc_acpi_device_found; +/* + * Indicates that lpc_driver_data.quirk_mmio_memory_base should + * be used as the base port for EC mapped memory. + */ +#define CROS_EC_LPC_QUIRK_REMAP_MEMORY BIT(0) + +/** + * struct lpc_driver_data - driver data attached to a DMI device ID to indicate + * hardware quirks. + * @quirks: a bitfield composed of quirks from CROS_EC_LPC_QUIRK_* + * @quirk_mmio_memory_base: The first I/O port addressing EC mapped memory (used + * when quirk ...REMAP_MEMORY is set.) + */ +struct lpc_driver_data { + u32 quirks; + u16 quirk_mmio_memory_base; +}; + /** * struct cros_ec_lpc - LPC device-specific data * @mmio_memory_base: The first I/O port addressing EC mapped memory. @@ -363,8 +381,10 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) acpi_status status; struct cros_ec_device *ec_dev; struct cros_ec_lpc *ec_lpc; + struct lpc_driver_data *driver_data; u8 buf[2] = {}; int irq, ret; + u32 quirks; ec_lpc = devm_kzalloc(dev, sizeof(*ec_lpc), GFP_KERNEL); if (!ec_lpc) @@ -372,6 +392,17 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) ec_lpc->mmio_memory_base = EC_LPC_ADDR_MEMMAP; + driver_data = platform_get_drvdata(pdev); + if (driver_data) { + quirks = driver_data->quirks; + + if (quirks) + dev_info(dev, "loaded with quirks %8.08x\n", quirks); + + if (quirks & CROS_EC_LPC_QUIRK_REMAP_MEMORY) + ec_lpc->mmio_memory_base = driver_data->quirk_mmio_memory_base; + } + /* * The Framework Laptop (and possibly other non-ChromeOS devices) * only exposes the eight I/O ports that are required for the Microchip EC. -- GitLab From 1332b39b7c88a4e1d9c094bce6ddba2226a109d9 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 2 Apr 2024 19:47:13 -0500 Subject: [PATCH 314/456] UPSTREAM: platform/chrome: cros_ec_lpc: add quirks for the Framework Laptop (AMD) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original Framework Laptop 13 platform (Intel 11th, 12th, and 13th Generation at this time) uses a Microchip embedded controller in a standard configuration. The newer devices in this product line--Framework Laptop 13 and 16 (AMD Ryzen)--use a NPCX embedded controller. However, they deviate from the configuration of ChromeOS platforms built with the NPCX EC. * The MMIO region for EC memory begins at port 0xE00 rather than the expected 0x900. cros_ec_lpc's quirks system is used to address this issue. Signed-off-by: Dustin L. Howett Reviewed-by: Thomas Weißschuh Tested-by: Thomas Weißschuh Tested-by: Mario Limonciello Link: https://lore.kernel.org/r/20240403004713.130365-5-dustin@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit c8f460d991df93d87de01a96b783cad5a2da9616) BUG=b:354066052 TEST=Compile Change-Id: Id7b1806ac7a59697aa148e5b505f4b7ed522e24d Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142445 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index b6a711526eeeb..79c979bfea23e 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -529,6 +529,11 @@ static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, cros_ec_lpc_acpi_device_ids); +static const struct lpc_driver_data framework_laptop_amd_lpc_driver_data __initconst = { + .quirks = CROS_EC_LPC_QUIRK_REMAP_MEMORY, + .quirk_mmio_memory_base = 0xE00, +}; + static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { { /* @@ -583,7 +588,16 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { }, /* A small number of non-Chromebook/box machines also use the ChromeOS EC */ { - /* the Framework Laptop */ + /* the Framework Laptop 13 (AMD Ryzen) and 16 (AMD Ryzen) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Framework"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMD Ryzen"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Laptop"), + }, + .driver_data = (void *)&framework_laptop_amd_lpc_driver_data, + }, + { + /* the Framework Laptop (Intel 11th, 12th, 13th Generation) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), DMI_MATCH(DMI_PRODUCT_NAME, "Laptop"), -- GitLab From 0557dd2ac7b5e8885c9aa734d5ceb56f9a7c4f68 Mon Sep 17 00:00:00 2001 From: Ben Walsh Date: Wed, 5 Jun 2024 07:33:47 +0100 Subject: [PATCH 315/456] UPSTREAM: platform/chrome: cros_ec_lpc: MEC access can return error code cros_ec_lpc_io_bytes_mec was returning a u8 checksum of all bytes read/written, which didn't leave room to indicate errors. Change this u8 to an int where negative values indicate an error, and non-negative values are the checksum as before. Tested-by: Dustin L. Howett Signed-off-by: Ben Walsh Link: https://lore.kernel.org/r/20240605063351.14836-2-ben@jubnut.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit 68dbac0a58ef7d82bc78dcb7e5ab5db2c6dfb489) BUG=b:354066052 TEST=Compile Change-Id: I04a088a9c1f53e57302a40680e64a993651f4e2c Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142446 Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 130 ++++++++++++++------- drivers/platform/chrome/cros_ec_lpc_mec.c | 9 +- drivers/platform/chrome/cros_ec_lpc_mec.h | 7 +- drivers/platform/chrome/wilco_ec/mailbox.c | 22 ++-- 4 files changed, 112 insertions(+), 56 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 79c979bfea23e..a2e13155e4bad 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -62,14 +62,16 @@ struct cros_ec_lpc { /** * struct lpc_driver_ops - LPC driver operations - * @read: Copy length bytes from EC address offset into buffer dest. Returns - * the 8-bit checksum of all bytes read. - * @write: Copy length bytes from buffer msg into EC address offset. Returns - * the 8-bit checksum of all bytes written. + * @read: Copy length bytes from EC address offset into buffer dest. + * Returns a negative error code on error, or the 8-bit checksum + * of all bytes read. + * @write: Copy length bytes from buffer msg into EC address offset. + * Returns a negative error code on error, or the 8-bit checksum + * of all bytes written. */ struct lpc_driver_ops { - u8 (*read)(unsigned int offset, unsigned int length, u8 *dest); - u8 (*write)(unsigned int offset, unsigned int length, const u8 *msg); + int (*read)(unsigned int offset, unsigned int length, u8 *dest); + int (*write)(unsigned int offset, unsigned int length, const u8 *msg); }; static struct lpc_driver_ops cros_ec_lpc_ops = { }; @@ -78,10 +80,10 @@ static struct lpc_driver_ops cros_ec_lpc_ops = { }; * A generic instance of the read function of struct lpc_driver_ops, used for * the LPC EC. */ -static u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, - u8 *dest) +static int cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, + u8 *dest) { - int sum = 0; + u8 sum = 0; int i; for (i = 0; i < length; ++i) { @@ -97,10 +99,10 @@ static u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, * A generic instance of the write function of struct lpc_driver_ops, used for * the LPC EC. */ -static u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, - const u8 *msg) +static int cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, + const u8 *msg) { - int sum = 0; + u8 sum = 0; int i; for (i = 0; i < length; ++i) { @@ -116,8 +118,8 @@ static u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, * An instance of the read function of struct lpc_driver_ops, used for the * MEC variant of LPC EC. */ -static u8 cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, - u8 *dest) +static int cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, + u8 *dest) { int in_range = cros_ec_lpc_mec_in_range(offset, length); @@ -135,8 +137,8 @@ static u8 cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, * An instance of the write function of struct lpc_driver_ops, used for the * MEC variant of LPC EC. */ -static u8 cros_ec_lpc_mec_write_bytes(unsigned int offset, unsigned int length, - const u8 *msg) +static int cros_ec_lpc_mec_write_bytes(unsigned int offset, unsigned int length, + const u8 *msg) { int in_range = cros_ec_lpc_mec_in_range(offset, length); @@ -154,11 +156,14 @@ static int ec_response_timed_out(void) { unsigned long one_second = jiffies + HZ; u8 data; + int ret; usleep_range(200, 300); do { - if (!(cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_CMD, 1, &data) & - EC_LPC_STATUS_BUSY_MASK)) + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_CMD, 1, &data); + if (ret < 0) + return ret; + if (!(data & EC_LPC_STATUS_BUSY_MASK)) return 0; usleep_range(100, 200); } while (time_before(jiffies, one_second)); @@ -179,28 +184,41 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, goto done; /* Write buffer */ - cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PACKET, ret, ec->dout); + ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PACKET, ret, ec->dout); + if (ret < 0) + goto done; /* Here we go */ sum = EC_COMMAND_PROTOCOL_3; - cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + if (ret < 0) + goto done; - if (ec_response_timed_out()) { + ret = ec_response_timed_out(); + if (ret < 0) + goto done; + if (ret) { dev_warn(ec->dev, "EC response timed out\n"); ret = -EIO; goto done; } /* Check result */ - msg->result = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + if (ret < 0) + goto done; + msg->result = ret; ret = cros_ec_check_result(ec, msg); if (ret) goto done; /* Read back response */ dout = (u8 *)&response; - sum = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET, sizeof(response), + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET, sizeof(response), dout); + if (ret < 0) + goto done; + sum = ret; msg->result = response.result; @@ -213,9 +231,12 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, } /* Read response and process checksum */ - sum += cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET + - sizeof(response), response.data_len, - msg->data); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET + + sizeof(response), response.data_len, + msg->data); + if (ret < 0) + goto done; + sum += ret; if (sum) { dev_err(ec->dev, @@ -255,32 +276,47 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, sum = msg->command + args.flags + args.command_version + args.data_size; /* Copy data and update checksum */ - sum += cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PARAM, msg->outsize, - msg->data); + ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PARAM, msg->outsize, + msg->data); + if (ret < 0) + goto done; + sum += ret; /* Finalize checksum and write args */ args.checksum = sum; - cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_ARGS, sizeof(args), - (u8 *)&args); + ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_ARGS, sizeof(args), + (u8 *)&args); + if (ret < 0) + goto done; /* Here we go */ sum = msg->command; - cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + if (ret < 0) + goto done; - if (ec_response_timed_out()) { + ret = ec_response_timed_out(); + if (ret < 0) + goto done; + if (ret) { dev_warn(ec->dev, "EC response timed out\n"); ret = -EIO; goto done; } /* Check result */ - msg->result = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + if (ret < 0) + goto done; + msg->result = ret; ret = cros_ec_check_result(ec, msg); if (ret) goto done; /* Read back args */ - cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8 *)&args); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8 *)&args); + if (ret < 0) + goto done; if (args.data_size > msg->insize) { dev_err(ec->dev, @@ -294,8 +330,11 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, sum = msg->command + args.flags + args.command_version + args.data_size; /* Read response and update checksum */ - sum += cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PARAM, args.data_size, - msg->data); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PARAM, args.data_size, + msg->data); + if (ret < 0) + goto done; + sum += ret; /* Verify checksum */ if (args.checksum != sum) { @@ -320,19 +359,24 @@ static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset, int i = offset; char *s = dest; int cnt = 0; + int ret; if (offset >= EC_MEMMAP_SIZE - bytes) return -EINVAL; /* fixed length */ if (bytes) { - cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + offset, bytes, s); + ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + offset, bytes, s); + if (ret < 0) + return ret; return bytes; } /* string */ for (; i < EC_MEMMAP_SIZE; i++, s++) { - cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + i, 1, s); + ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + i, 1, s); + if (ret < 0) + return ret; cnt++; if (!*s) break; @@ -425,7 +469,9 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) */ cros_ec_lpc_ops.read = cros_ec_lpc_mec_read_bytes; cros_ec_lpc_ops.write = cros_ec_lpc_mec_write_bytes; - cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); + ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); + if (ret < 0) + return ret; if (buf[0] != 'E' || buf[1] != 'C') { if (!devm_request_region(dev, ec_lpc->mmio_memory_base, EC_MEMMAP_SIZE, dev_name(dev))) { @@ -436,8 +482,10 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) /* Re-assign read/write operations for the non MEC variant */ cros_ec_lpc_ops.read = cros_ec_lpc_read_bytes; cros_ec_lpc_ops.write = cros_ec_lpc_write_bytes; - cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2, - buf); + ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2, + buf); + if (ret < 0) + return ret; if (buf[0] != 'E' || buf[1] != 'C') { dev_err(dev, "EC ID not detected\n"); return -ENODEV; diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.c b/drivers/platform/chrome/cros_ec_lpc_mec.c index 63b6b261b8e58..dfad934e65ca6 100644 --- a/drivers/platform/chrome/cros_ec_lpc_mec.c +++ b/drivers/platform/chrome/cros_ec_lpc_mec.c @@ -119,11 +119,12 @@ int cros_ec_lpc_mec_in_range(unsigned int offset, unsigned int length) * @length: Number of bytes to read / write * @buf: Destination / source buffer * - * Return: 8-bit checksum of all bytes read / written + * @return: A negative error code on error, or 8-bit checksum of all + * bytes read / written */ -u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, - unsigned int offset, unsigned int length, - u8 *buf) +int cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, + unsigned int offset, unsigned int length, + u8 *buf) { int i = 0; int io_addr; diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.h b/drivers/platform/chrome/cros_ec_lpc_mec.h index 3f3af37e58a50..69f9d8786f61c 100644 --- a/drivers/platform/chrome/cros_ec_lpc_mec.h +++ b/drivers/platform/chrome/cros_ec_lpc_mec.h @@ -75,9 +75,10 @@ int cros_ec_lpc_mec_in_range(unsigned int offset, unsigned int length); * @length: Number of bytes to read / write * @buf: Destination / source buffer * - * @return 8-bit checksum of all bytes read / written + * @return: A negative error code on error, or 8-bit checksum of all + * bytes read / written */ -u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, - unsigned int offset, unsigned int length, u8 *buf); +int cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, + unsigned int offset, unsigned int length, u8 *buf); #endif /* __CROS_EC_LPC_MEC_H */ diff --git a/drivers/platform/chrome/wilco_ec/mailbox.c b/drivers/platform/chrome/wilco_ec/mailbox.c index 0f98358ea824c..4d8273b47cdee 100644 --- a/drivers/platform/chrome/wilco_ec/mailbox.c +++ b/drivers/platform/chrome/wilco_ec/mailbox.c @@ -117,13 +117,17 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec, struct wilco_ec_request *rq) { struct wilco_ec_response *rs; - u8 checksum; + int ret; u8 flag; /* Write request header, then data */ - cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, 0, sizeof(*rq), (u8 *)rq); - cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, sizeof(*rq), msg->request_size, - msg->request_data); + ret = cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, 0, sizeof(*rq), (u8 *)rq); + if (ret < 0) + return ret; + ret = cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, sizeof(*rq), msg->request_size, + msg->request_data); + if (ret < 0) + return ret; /* Start the command */ outb(EC_MAILBOX_START_COMMAND, ec->io_command->start); @@ -149,10 +153,12 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec, /* Read back response */ rs = ec->data_buffer; - checksum = cros_ec_lpc_io_bytes_mec(MEC_IO_READ, 0, - sizeof(*rs) + EC_MAILBOX_DATA_SIZE, - (u8 *)rs); - if (checksum) { + ret = cros_ec_lpc_io_bytes_mec(MEC_IO_READ, 0, + sizeof(*rs) + EC_MAILBOX_DATA_SIZE, + (u8 *)rs); + if (ret < 0) + return ret; + if (ret) { dev_dbg(ec->dev, "bad packet checksum 0x%02x\n", rs->checksum); return -EBADMSG; } -- GitLab From ec928c8b5c6397cd5148dcacde6530bce7948542 Mon Sep 17 00:00:00 2001 From: Ben Walsh Date: Wed, 5 Jun 2024 07:33:49 +0100 Subject: [PATCH 316/456] UPSTREAM: platform/chrome: cros_ec_lpc: Add a new quirk for ACPI id Framework Laptops' ACPI exposes the EC with id "PNP0C09". But "PNP0C09" is part of the ACPI standard; there are lots of computers with EC chips with this id, and most of them don't support the cros_ec protocol. The driver could find the ACPI device by having "PNP0C09" in the acpi_match_table, but this would match devices which don't support the cros_ec protocol. Instead, add a new quirk "CROS_EC_LPC_QUIRK_ACPI_ID" which allows the id to be specified. This quirk is applied after the DMI check shows that the device is supported. Tested-by: Dustin L. Howett Signed-off-by: Ben Walsh Link: https://lore.kernel.org/r/20240605063351.14836-4-ben@jubnut.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit 040159e0912c31fe959d8671f9700bda105ab63a) BUG=b:354066052 TEST=Compile Change-Id: Ifdc57064d6aee239c7259d5db11d5c2b16850fa5 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142447 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 50 ++++++++++++++++++++------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index a2e13155e4bad..86542a9160fff 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -39,6 +39,11 @@ static bool cros_ec_lpc_acpi_device_found; * be used as the base port for EC mapped memory. */ #define CROS_EC_LPC_QUIRK_REMAP_MEMORY BIT(0) +/* + * Indicates that lpc_driver_data.quirk_acpi_id should be used to find + * the ACPI device. + */ +#define CROS_EC_LPC_QUIRK_ACPI_ID BIT(1) /** * struct lpc_driver_data - driver data attached to a DMI device ID to indicate @@ -46,10 +51,12 @@ static bool cros_ec_lpc_acpi_device_found; * @quirks: a bitfield composed of quirks from CROS_EC_LPC_QUIRK_* * @quirk_mmio_memory_base: The first I/O port addressing EC mapped memory (used * when quirk ...REMAP_MEMORY is set.) + * @quirk_acpi_id: An ACPI HID to be used to find the ACPI device. */ struct lpc_driver_data { u32 quirks; u16 quirk_mmio_memory_base; + const char *quirk_acpi_id; }; /** @@ -418,6 +425,26 @@ static void cros_ec_lpc_acpi_notify(acpi_handle device, u32 value, void *data) pm_system_wakeup(); } +static acpi_status cros_ec_lpc_parse_device(acpi_handle handle, u32 level, + void *context, void **retval) +{ + *(struct acpi_device **)context = acpi_fetch_acpi_dev(handle); + return AE_CTRL_TERMINATE; +} + +static struct acpi_device *cros_ec_lpc_get_device(const char *id) +{ + struct acpi_device *adev = NULL; + acpi_status status = acpi_get_devices(id, cros_ec_lpc_parse_device, + &adev, NULL); + if (ACPI_FAILURE(status)) { + pr_warn(DRV_NAME ": Looking for %s failed\n", id); + return NULL; + } + + return adev; +} + static int cros_ec_lpc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -445,6 +472,16 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) if (quirks & CROS_EC_LPC_QUIRK_REMAP_MEMORY) ec_lpc->mmio_memory_base = driver_data->quirk_mmio_memory_base; + + if (quirks & CROS_EC_LPC_QUIRK_ACPI_ID) { + adev = cros_ec_lpc_get_device(driver_data->quirk_acpi_id); + if (!adev) { + dev_err(dev, "failed to get ACPI device '%s'", + driver_data->quirk_acpi_id); + return -ENODEV; + } + ACPI_COMPANION_SET(dev, adev); + } } /* @@ -711,23 +748,12 @@ static struct platform_device cros_ec_lpc_device = { .name = DRV_NAME }; -static acpi_status cros_ec_lpc_parse_device(acpi_handle handle, u32 level, - void *context, void **retval) -{ - *(bool *)context = true; - return AE_CTRL_TERMINATE; -} - static int __init cros_ec_lpc_init(void) { int ret; - acpi_status status; const struct dmi_system_id *dmi_match; - status = acpi_get_devices(ACPI_DRV_NAME, cros_ec_lpc_parse_device, - &cros_ec_lpc_acpi_device_found, NULL); - if (ACPI_FAILURE(status)) - pr_warn(DRV_NAME ": Looking for %s failed\n", ACPI_DRV_NAME); + cros_ec_lpc_acpi_device_found = !!cros_ec_lpc_get_device(ACPI_DRV_NAME); dmi_match = dmi_first_match(cros_ec_lpc_dmi_table); -- GitLab From 2e8ebf12c18bc82eac7eceb477e4395e709f2d01 Mon Sep 17 00:00:00 2001 From: Ben Walsh Date: Wed, 5 Jun 2024 07:33:50 +0100 Subject: [PATCH 317/456] UPSTREAM: platform/chrome: cros_ec_lpc: Add a new quirk for AML mutex Add a new quirk "CROS_EC_LPC_QUIRK_AML_MUTEX" which provides the name of an AML mutex to protect MEC memory access. Tested-by: Dustin L. Howett Signed-off-by: Ben Walsh Link: https://lore.kernel.org/r/20240605063351.14836-5-ben@jubnut.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit 38c31b1d737ba4cab571dbf9090a1cabf164bea2) BUG=b:354066052 TEST=Compile Change-Id: I6b34cc3fa6c20cfa61dc111e2995e4880a7544a9 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142448 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 86542a9160fff..867408f1c3c11 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -44,6 +44,11 @@ static bool cros_ec_lpc_acpi_device_found; * the ACPI device. */ #define CROS_EC_LPC_QUIRK_ACPI_ID BIT(1) +/* + * Indicates that lpc_driver_data.quirk_aml_mutex_name should be used + * to find an AML mutex to protect access to Microchip EC. + */ +#define CROS_EC_LPC_QUIRK_AML_MUTEX BIT(2) /** * struct lpc_driver_data - driver data attached to a DMI device ID to indicate @@ -52,11 +57,14 @@ static bool cros_ec_lpc_acpi_device_found; * @quirk_mmio_memory_base: The first I/O port addressing EC mapped memory (used * when quirk ...REMAP_MEMORY is set.) * @quirk_acpi_id: An ACPI HID to be used to find the ACPI device. + * @quirk_aml_mutex_name: The name of an AML mutex to be used to protect access + * to Microchip EC. */ struct lpc_driver_data { u32 quirks; u16 quirk_mmio_memory_base; const char *quirk_acpi_id; + const char *quirk_aml_mutex_name; }; /** @@ -482,6 +490,17 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) } ACPI_COMPANION_SET(dev, adev); } + + if (quirks & CROS_EC_LPC_QUIRK_AML_MUTEX) { + const char *name + = driver_data->quirk_aml_mutex_name; + ret = cros_ec_lpc_mec_acpi_mutex(ACPI_COMPANION(dev), name); + if (ret) { + dev_err(dev, "failed to get AML mutex '%s'", name); + return ret; + } + dev_info(dev, "got AML mutex '%s'", name); + } } /* -- GitLab From e7990a0d1f3d82a8a647d03f66c91e0f56cc6829 Mon Sep 17 00:00:00 2001 From: Ben Walsh Date: Wed, 5 Jun 2024 07:33:51 +0100 Subject: [PATCH 318/456] UPSTREAM: platform/chrome: cros_ec_lpc: Add quirks for Framework Laptop For Framework Laptops with Microchip EC (MEC), use the ACPI id "PNP0C09" to find the ACPI device, and AML mutex "ECMT" to protect EC memory access. Tested-by: Dustin L. Howett Signed-off-by: Ben Walsh Link: https://lore.kernel.org/r/20240605063351.14836-6-ben@jubnut.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit 04ca0a51f1e63bd553fd4af8e9af0fe094fa4f0a) BUG=b:354066052 TEST=Compile Change-Id: If2bdcefa9a5ce4be495e1a120036c1d7844b8750 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142449 Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 867408f1c3c11..efe996e2432e1 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -638,6 +638,12 @@ static const struct lpc_driver_data framework_laptop_amd_lpc_driver_data __initc .quirk_mmio_memory_base = 0xE00, }; +static const struct lpc_driver_data framework_laptop_11_lpc_driver_data __initconst = { + .quirks = CROS_EC_LPC_QUIRK_ACPI_ID|CROS_EC_LPC_QUIRK_AML_MUTEX, + .quirk_acpi_id = "PNP0C09", + .quirk_aml_mutex_name = "ECMT", +}; + static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { { /* @@ -706,6 +712,7 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), DMI_MATCH(DMI_PRODUCT_NAME, "Laptop"), }, + .driver_data = (void *)&framework_laptop_11_lpc_driver_data, }, { /* sentinel */ } }; -- GitLab From dbc6486b92281890a1fcca3f5c395c0fc1c835a1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Jun 2024 16:55:14 +0300 Subject: [PATCH 319/456] UPSTREAM: platform/chrome: cros_ec_lpc: Fix error code in cros_ec_lpc_mec_read_bytes() We changed these functions to returning negative error codes, but this first error path was accidentally overlooked. It leads to a Smatch warning: drivers/platform/chrome/cros_ec_lpc.c:181 ec_response_timed_out() error: uninitialized symbol 'data'. Fix this by returning the error code instead of success. Fixes: 68dbac0a58ef ("platform/chrome: cros_ec_lpc: MEC access can return error code") Signed-off-by: Dan Carpenter Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/e0b43fb5-ecc8-4fb4-9b76-c06dea8cc4c4@moroto.mountain Signed-off-by: Tzung-Bi Shih (cherry picked from commit 77a714325d09e1527d865dc011ef91c4972ffedd) BUG=b:354066052 TEST=Compile Change-Id: Id65780e8bd62320168e3703af6b8ee628a299bdb Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142450 Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index efe996e2432e1..f0165e4493572 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -139,7 +139,7 @@ static int cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, int in_range = cros_ec_lpc_mec_in_range(offset, length); if (in_range < 0) - return 0; + return in_range; return in_range ? cros_ec_lpc_io_bytes_mec(MEC_IO_READ, @@ -158,7 +158,7 @@ static int cros_ec_lpc_mec_write_bytes(unsigned int offset, unsigned int length, int in_range = cros_ec_lpc_mec_in_range(offset, length); if (in_range < 0) - return 0; + return in_range; return in_range ? cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, -- GitLab From eaa32f357cd70604cbf496a33432c1059c0a66b8 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 6 Aug 2024 21:54:09 -0500 Subject: [PATCH 320/456] UPSTREAM: platform/chrome: cros_ec_lpc: switch primary DMI data for Framework Laptop Framework Computer appears to be moving away from the Microchip embedded controller seen in the Framework Laptop 13 with Intel Core 11th, 12th and 13th generation processors. All newer models use a Nuvoton NPCX embedded controller. Changing the default DMI match for Framework's products to match their newer product lines will reduce churn in this part of the cros_ec_lpc driver. The new match tables are: - Microchip EC models - "Laptop" (product, exact match) for the 11th gen. Intel Core - "12th Gen Intel Core" (product, exact match) - "13th Gen Intel Core" (product, exact match) - Nuvoton NPCX models - "Laptop" (product family, partial match) Signed-off-by: Dustin L. Howett Reviewed-by: Alexandru M Stan Link: https://lore.kernel.org/r/20240806-platform-chrome-cros_ec_lpcs-change-the-default-disposition-of-the-framework-laptop-v1-1-09e0d602b215@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit 62be134abf4250474a7a694837064bc783d2b291) BUG=b:354066052 TEST=Compile Change-Id: Id9ef18bab45ace30bc30e2fa30a62b67f2349a89 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142451 Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 36 ++++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index f0165e4493572..c559596a5e20b 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -633,12 +633,12 @@ static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, cros_ec_lpc_acpi_device_ids); -static const struct lpc_driver_data framework_laptop_amd_lpc_driver_data __initconst = { +static const struct lpc_driver_data framework_laptop_npcx_lpc_driver_data __initconst = { .quirks = CROS_EC_LPC_QUIRK_REMAP_MEMORY, .quirk_mmio_memory_base = 0xE00, }; -static const struct lpc_driver_data framework_laptop_11_lpc_driver_data __initconst = { +static const struct lpc_driver_data framework_laptop_mec_lpc_driver_data __initconst = { .quirks = CROS_EC_LPC_QUIRK_ACPI_ID|CROS_EC_LPC_QUIRK_AML_MUTEX, .quirk_acpi_id = "PNP0C09", .quirk_aml_mutex_name = "ECMT", @@ -698,21 +698,39 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { }, /* A small number of non-Chromebook/box machines also use the ChromeOS EC */ { - /* the Framework Laptop 13 (AMD Ryzen) and 16 (AMD Ryzen) */ + /* Framework Laptop (11th Gen Intel Core) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMD Ryzen"), - DMI_MATCH(DMI_PRODUCT_FAMILY, "Laptop"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop"), + }, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, + }, + { + /* Framework Laptop (12th Gen Intel Core) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Framework"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "12th Gen Intel Core"), + }, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, + }, + { + /* Framework Laptop (13th Gen Intel Core) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Framework"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "13th Gen Intel Core"), }, - .driver_data = (void *)&framework_laptop_amd_lpc_driver_data, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, }, { - /* the Framework Laptop (Intel 11th, 12th, 13th Generation) */ + /* + * All remaining Framework Laptop models (13 AMD Ryzen, 16 AMD + * Ryzen, Intel Core Ultra) + */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_MATCH(DMI_PRODUCT_NAME, "Laptop"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Laptop"), }, - .driver_data = (void *)&framework_laptop_11_lpc_driver_data, + .driver_data = (void *)&framework_laptop_npcx_lpc_driver_data, }, { /* sentinel */ } }; -- GitLab From 364af114db57befed17203625f6fbf7f3544639e Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 24 Dec 2024 12:55:58 -0600 Subject: [PATCH 321/456] UPSTREAM: platform/chrome: cros_ec_lpc: fix product identity for early Framework Laptops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The product names for the Framework Laptop (12th and 13th Generation Intel Core) are incorrect as of 62be134abf42. Fixes: 62be134abf42 ("platform/chrome: cros_ec_lpc: switch primary DMI data for Framework Laptop") Cc: stable@vger.kernel.org # 6.12.x Signed-off-by: Dustin L. Howett Reviewed-by: Thomas Weißschuh Link: https://lore.kernel.org/r/20241224-platform-chrome-cros_ec_lpc-fix-product-identity-for-early-framework-laptops-v1-1-0d31d6e1d22c@howett.net Signed-off-by: Tzung-Bi Shih (cherry picked from commit dcd59d0d7d51b2a4b768fc132b0d74a97dfd6d6a) BUG=b:354066052 TEST=Compile Change-Id: I19a7039781a8c9a1d3463f5708a7a4897595f7da Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6149730 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index c559596a5e20b..89957ad3c99cf 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -709,7 +709,7 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { /* Framework Laptop (12th Gen Intel Core) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "12th Gen Intel Core"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"), }, .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, }, @@ -717,7 +717,7 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { /* Framework Laptop (13th Gen Intel Core) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "13th Gen Intel Core"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"), }, .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, }, -- GitLab From 237b24867328c807623703e62b34d4d9b134e877 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 7 Jan 2025 09:45:13 -0800 Subject: [PATCH 322/456] FROMGIT: platform/chrome: cros_ec_lpc: Merge lpc_driver_ops into ec private structure Remove cros_ec_lpc_ops global variable, since EC specific info can be stored in the device private structure, introduced in commit e4dbf9d65e4218 ("platform/chrome: cros_ec_lpc: add a "quirks" system"). Add ec_lpc pointer to read/write function to be able to access ec specific data. Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20250107174514.2748108-2-gwendal@chromium.org Signed-off-by: Tzung-Bi Shih (cherry picked from commit 58517215304b6113beaa3a319ed19cdd9f8fbcc1 https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git for-next) BUG=b:354066052 TEST=Compile Change-Id: I0787a65ec5979bfca2f8066636b11d61df9fbf2c Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6142452 Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 86 +++++++++++++-------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 89957ad3c99cf..c61e69d50938d 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -70,13 +70,6 @@ struct lpc_driver_data { /** * struct cros_ec_lpc - LPC device-specific data * @mmio_memory_base: The first I/O port addressing EC mapped memory. - */ -struct cros_ec_lpc { - u16 mmio_memory_base; -}; - -/** - * struct lpc_driver_ops - LPC driver operations * @read: Copy length bytes from EC address offset into buffer dest. * Returns a negative error code on error, or the 8-bit checksum * of all bytes read. @@ -84,18 +77,19 @@ struct cros_ec_lpc { * Returns a negative error code on error, or the 8-bit checksum * of all bytes written. */ -struct lpc_driver_ops { - int (*read)(unsigned int offset, unsigned int length, u8 *dest); - int (*write)(unsigned int offset, unsigned int length, const u8 *msg); +struct cros_ec_lpc { + u16 mmio_memory_base; + int (*read)(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, u8 *dest); + int (*write)(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, const u8 *msg); }; -static struct lpc_driver_ops cros_ec_lpc_ops = { }; - /* * A generic instance of the read function of struct lpc_driver_ops, used for * the LPC EC. */ -static int cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, +static int cros_ec_lpc_read_bytes(struct cros_ec_lpc *_, unsigned int offset, unsigned int length, u8 *dest) { u8 sum = 0; @@ -114,7 +108,7 @@ static int cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, * A generic instance of the write function of struct lpc_driver_ops, used for * the LPC EC. */ -static int cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, +static int cros_ec_lpc_write_bytes(struct cros_ec_lpc *_, unsigned int offset, unsigned int length, const u8 *msg) { u8 sum = 0; @@ -133,8 +127,8 @@ static int cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, * An instance of the read function of struct lpc_driver_ops, used for the * MEC variant of LPC EC. */ -static int cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, - u8 *dest) +static int cros_ec_lpc_mec_read_bytes(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, u8 *dest) { int in_range = cros_ec_lpc_mec_in_range(offset, length); @@ -145,15 +139,15 @@ static int cros_ec_lpc_mec_read_bytes(unsigned int offset, unsigned int length, cros_ec_lpc_io_bytes_mec(MEC_IO_READ, offset - EC_HOST_CMD_REGION0, length, dest) : - cros_ec_lpc_read_bytes(offset, length, dest); + cros_ec_lpc_read_bytes(ec_lpc, offset, length, dest); } /* * An instance of the write function of struct lpc_driver_ops, used for the * MEC variant of LPC EC. */ -static int cros_ec_lpc_mec_write_bytes(unsigned int offset, unsigned int length, - const u8 *msg) +static int cros_ec_lpc_mec_write_bytes(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, const u8 *msg) { int in_range = cros_ec_lpc_mec_in_range(offset, length); @@ -164,10 +158,11 @@ static int cros_ec_lpc_mec_write_bytes(unsigned int offset, unsigned int length, cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, offset - EC_HOST_CMD_REGION0, length, (u8 *)msg) : - cros_ec_lpc_write_bytes(offset, length, msg); + cros_ec_lpc_write_bytes(ec_lpc, offset, length, msg); +} } -static int ec_response_timed_out(void) +static int ec_response_timed_out(struct cros_ec_lpc *ec_lpc) { unsigned long one_second = jiffies + HZ; u8 data; @@ -175,7 +170,7 @@ static int ec_response_timed_out(void) usleep_range(200, 300); do { - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_CMD, 1, &data); + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_CMD, 1, &data); if (ret < 0) return ret; if (!(data & EC_LPC_STATUS_BUSY_MASK)) @@ -189,6 +184,7 @@ static int ec_response_timed_out(void) static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, struct cros_ec_command *msg) { + struct cros_ec_lpc *ec_lpc = ec->priv; struct ec_host_response response; u8 sum; int ret = 0; @@ -199,17 +195,17 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, goto done; /* Write buffer */ - ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PACKET, ret, ec->dout); + ret = ec_lpc->write(ec_lpc, EC_LPC_ADDR_HOST_PACKET, ret, ec->dout); if (ret < 0) goto done; /* Here we go */ sum = EC_COMMAND_PROTOCOL_3; - ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + ret = ec_lpc->write(ec_lpc, EC_LPC_ADDR_HOST_CMD, 1, &sum); if (ret < 0) goto done; - ret = ec_response_timed_out(); + ret = ec_response_timed_out(ec_lpc); if (ret < 0) goto done; if (ret) { @@ -219,7 +215,7 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, } /* Check result */ - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_DATA, 1, &sum); if (ret < 0) goto done; msg->result = ret; @@ -229,7 +225,7 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, /* Read back response */ dout = (u8 *)&response; - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET, sizeof(response), + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_PACKET, sizeof(response), dout); if (ret < 0) goto done; @@ -246,7 +242,7 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, } /* Read response and process checksum */ - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PACKET + + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_PACKET + sizeof(response), response.data_len, msg->data); if (ret < 0) @@ -270,6 +266,7 @@ done: static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, struct cros_ec_command *msg) { + struct cros_ec_lpc *ec_lpc = ec->priv; struct ec_lpc_host_args args; u8 sum; int ret = 0; @@ -291,7 +288,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, sum = msg->command + args.flags + args.command_version + args.data_size; /* Copy data and update checksum */ - ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_PARAM, msg->outsize, + ret = ec_lpc->write(ec_lpc, EC_LPC_ADDR_HOST_PARAM, msg->outsize, msg->data); if (ret < 0) goto done; @@ -299,18 +296,18 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, /* Finalize checksum and write args */ args.checksum = sum; - ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_ARGS, sizeof(args), + ret = ec_lpc->write(ec_lpc, EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8 *)&args); if (ret < 0) goto done; /* Here we go */ sum = msg->command; - ret = cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); + ret = ec_lpc->write(ec_lpc, EC_LPC_ADDR_HOST_CMD, 1, &sum); if (ret < 0) goto done; - ret = ec_response_timed_out(); + ret = ec_response_timed_out(ec_lpc); if (ret < 0) goto done; if (ret) { @@ -320,7 +317,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, } /* Check result */ - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_DATA, 1, &sum); + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_DATA, 1, &sum); if (ret < 0) goto done; msg->result = ret; @@ -329,7 +326,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, goto done; /* Read back args */ - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8 *)&args); + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8 *)&args); if (ret < 0) goto done; @@ -345,7 +342,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, sum = msg->command + args.flags + args.command_version + args.data_size; /* Read response and update checksum */ - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_HOST_PARAM, args.data_size, + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_HOST_PARAM, args.data_size, msg->data); if (ret < 0) goto done; @@ -381,7 +378,7 @@ static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset, /* fixed length */ if (bytes) { - ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + offset, bytes, s); + ret = ec_lpc->read(ec_lpc, ec_lpc->mmio_memory_base + offset, bytes, s); if (ret < 0) return ret; return bytes; @@ -389,7 +386,7 @@ static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset, /* string */ for (; i < EC_MEMMAP_SIZE; i++, s++) { - ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + i, 1, s); + ret = ec_lpc->read(ec_lpc, ec_lpc->mmio_memory_base + i, 1, s); if (ret < 0) return ret; cnt++; @@ -492,8 +489,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) } if (quirks & CROS_EC_LPC_QUIRK_AML_MUTEX) { - const char *name - = driver_data->quirk_aml_mutex_name; + const char *name = driver_data->quirk_aml_mutex_name; ret = cros_ec_lpc_mec_acpi_mutex(ACPI_COMPANION(dev), name); if (ret) { dev_err(dev, "failed to get AML mutex '%s'", name); @@ -523,9 +519,9 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) * protocol fails, fallback to the non MEC variant and try to * read again the ID. */ - cros_ec_lpc_ops.read = cros_ec_lpc_mec_read_bytes; - cros_ec_lpc_ops.write = cros_ec_lpc_mec_write_bytes; - ret = cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); + ec_lpc->read = cros_ec_lpc_mec_read_bytes; + ec_lpc->write = cros_ec_lpc_mec_write_bytes; + ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); if (ret < 0) return ret; if (buf[0] != 'E' || buf[1] != 'C') { @@ -536,9 +532,9 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) } /* Re-assign read/write operations for the non MEC variant */ - cros_ec_lpc_ops.read = cros_ec_lpc_read_bytes; - cros_ec_lpc_ops.write = cros_ec_lpc_write_bytes; - ret = cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2, + ec_lpc->read = cros_ec_lpc_read_bytes; + ec_lpc->write = cros_ec_lpc_write_bytes; + ret = ec_lpc->read(ec_lpc, ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2, buf); if (ret < 0) return ret; -- GitLab From effe4a7e3f4b42e8de59bc4473637cf74d86c8f9 Mon Sep 17 00:00:00 2001 From: Ben Walsh Date: Thu, 13 Jun 2024 22:25:42 +0100 Subject: [PATCH 323/456] UPSTREAM: platform/chrome: cros_ec_lpc: Handle zero length read/write cros_ec_lpc_mec_read_bytes and cros_ec_lpc_mec_write_bytes call cros_ec_lpc_mec_in_range, which checks if addresses are in the MEC address range, and returns -EINVAL if the range given is not sensible. However cros_ec_lpc_mec_in_range was also returning -EINVAL for a zero length range. A zero length range should not be an error condition. cros_ec_lpc_mec_in_range now returns 1 in this case. cros_ec_lpc_io_bytes_mec checks for zero length, and returns immediately without beginning a transfer. Fixes: 68dbac0a58ef ("platform/chrome: cros_ec_lpc: MEC access can return error code") Fixes: 77a714325d09 ("platform/chrome: cros_ec_lpc: Fix error code in cros_ec_lpc_mec_read_bytes()") Signed-off-by: Ben Walsh Link: https://lore.kernel.org/r/20240613212542.403-1-ben@jubnut.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit b57cd5703a1618e87772094ac12c5ee7d6c35e2f) BUG=b:354066052 TEST=Compile Change-Id: I4dee94726db6b0c079d4b2855b78fa64f7f63487 Signed-off-by: Gwendal Grignou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6150013 Reviewed-by: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc_mec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.c b/drivers/platform/chrome/cros_ec_lpc_mec.c index dfad934e65ca6..a56584171168c 100644 --- a/drivers/platform/chrome/cros_ec_lpc_mec.c +++ b/drivers/platform/chrome/cros_ec_lpc_mec.c @@ -93,9 +93,6 @@ static void cros_ec_lpc_mec_emi_write_address(u16 addr, */ int cros_ec_lpc_mec_in_range(unsigned int offset, unsigned int length) { - if (length == 0) - return -EINVAL; - if (WARN_ON(mec_emi_base == 0 || mec_emi_end == 0)) return -EINVAL; @@ -132,6 +129,9 @@ int cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, enum cros_ec_lpc_mec_emi_access_mode access, new_access; int ret; + if (length == 0) + return 0; + /* Return checksum of 0 if window is not initialized */ WARN_ON(mec_emi_base == 0 || mec_emi_end == 0); if (mec_emi_base == 0 || mec_emi_end == 0) -- GitLab From 32d7c227f0d5828859635e4f3519abc1555ec5b6 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 7 Jan 2025 09:45:14 -0800 Subject: [PATCH 324/456] FROMGIT: platform/chrome: cros_ec_lpc: Support direct EC register memory access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to access EC memory region HOST command and ACPI memory region directly. The memory region comes from the CRS ACPI resource descriptor. The driver retrieves the memory information by adding a resource walker for the CRS region. If a memory region is found, it is mapped and the driver uses a new set of read/write primitives to access the EC doorbell and external registers. Once the memory is mapped, it belongs to the driver: grep GOOG0004 /proc/iomem     fe0b0000-fe0bffff : GOOG0004:00 We can verify the communication is established checking the EC version, or monitoring the commands using the cros-ec kernel tracer. Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20250107174514.2748108-3-gwendal@chromium.org Signed-off-by: Tzung-Bi Shih (cherry picked from commit be4fccb5e1fb5c732f2868b9a278e71d9be0283c https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git for-next) BUG=b:354066052 TEST=Check on Brox the commands are flowing Change-Id: I6ce50539128c6504d85588e2dfccc6e2f0b19d5b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6050671 Commit-Queue: Gwendal Grignou Tested-by: Gwendal Grignou Reviewed-by: Tzung-Bi Shih Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 121 +++++++++++++++++++++----- 1 file changed, 100 insertions(+), 21 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index c61e69d50938d..288ef9198bb0a 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -70,6 +70,8 @@ struct lpc_driver_data { /** * struct cros_ec_lpc - LPC device-specific data * @mmio_memory_base: The first I/O port addressing EC mapped memory. + * @base: For EC supporting memory mapping, base address of the mapped region. + * @mem32: Information about the memory mapped register region, if present. * @read: Copy length bytes from EC address offset into buffer dest. * Returns a negative error code on error, or the 8-bit checksum * of all bytes read. @@ -79,6 +81,8 @@ struct lpc_driver_data { */ struct cros_ec_lpc { u16 mmio_memory_base; + void __iomem *base; + struct acpi_resource_fixed_memory32 mem32; int (*read)(struct cros_ec_lpc *ec_lpc, unsigned int offset, unsigned int length, u8 *dest); int (*write)(struct cros_ec_lpc *ec_lpc, unsigned int offset, @@ -160,6 +164,45 @@ static int cros_ec_lpc_mec_write_bytes(struct cros_ec_lpc *ec_lpc, unsigned int length, (u8 *)msg) : cros_ec_lpc_write_bytes(ec_lpc, offset, length, msg); } + +static int cros_ec_lpc_direct_read(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, u8 *dest) +{ + int sum = 0; + int i; + + if (offset < EC_HOST_CMD_REGION0 || offset > EC_LPC_ADDR_MEMMAP + + EC_MEMMAP_SIZE) { + return cros_ec_lpc_read_bytes(ec_lpc, offset, length, dest); + } + + for (i = 0; i < length; ++i) { + dest[i] = readb(ec_lpc->base + offset - EC_HOST_CMD_REGION0 + i); + sum += dest[i]; + } + + /* Return checksum of all bytes read */ + return sum; +} + +static int cros_ec_lpc_direct_write(struct cros_ec_lpc *ec_lpc, unsigned int offset, + unsigned int length, const u8 *msg) +{ + int sum = 0; + int i; + + if (offset < EC_HOST_CMD_REGION0 || offset > EC_LPC_ADDR_MEMMAP + + EC_MEMMAP_SIZE) { + return cros_ec_lpc_write_bytes(ec_lpc, offset, length, msg); + } + + for (i = 0; i < length; ++i) { + writeb(msg[i], ec_lpc->base + offset - EC_HOST_CMD_REGION0 + i); + sum += msg[i]; + } + + /* Return checksum of all bytes written */ + return sum; } static int ec_response_timed_out(struct cros_ec_lpc *ec_lpc) @@ -450,6 +493,20 @@ static struct acpi_device *cros_ec_lpc_get_device(const char *id) return adev; } +static acpi_status cros_ec_lpc_resources(struct acpi_resource *res, void *data) +{ + struct cros_ec_lpc *ec_lpc = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + ec_lpc->mem32 = res->data.fixed_memory32; + break; + default: + break; + } + return AE_OK; +} + static int cros_ec_lpc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -498,29 +555,52 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) dev_info(dev, "got AML mutex '%s'", name); } } - - /* - * The Framework Laptop (and possibly other non-ChromeOS devices) - * only exposes the eight I/O ports that are required for the Microchip EC. - * Requesting a larger reservation will fail. - */ - if (!devm_request_region(dev, EC_HOST_CMD_REGION0, - EC_HOST_CMD_MEC_REGION_SIZE, dev_name(dev))) { - dev_err(dev, "couldn't reserve MEC region\n"); - return -EBUSY; + adev = ACPI_COMPANION(dev); + if (adev) { + /* + * Retrieve the resource information in the CRS register, if available. + */ + status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + cros_ec_lpc_resources, ec_lpc); + if (ACPI_FAILURE(status)) { + dev_err(dev, "failed to get resources\n"); + return -ENODEV; + } + if (ec_lpc->mem32.address_length) { + ec_lpc->base = devm_ioremap(dev, + ec_lpc->mem32.address, + ec_lpc->mem32.address_length); + if (!ec_lpc->base) + return -EINVAL; + + ec_lpc->read = cros_ec_lpc_direct_read; + ec_lpc->write = cros_ec_lpc_direct_write; + } } + if (!ec_lpc->read) { + /* + * The Framework Laptop (and possibly other non-ChromeOS devices) + * only exposes the eight I/O ports that are required for the Microchip EC. + * Requesting a larger reservation will fail. + */ + if (!devm_request_region(dev, EC_HOST_CMD_REGION0, + EC_HOST_CMD_MEC_REGION_SIZE, dev_name(dev))) { + dev_err(dev, "couldn't reserve MEC region\n"); + return -EBUSY; + } - cros_ec_lpc_mec_init(EC_HOST_CMD_REGION0, - EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE); + cros_ec_lpc_mec_init(EC_HOST_CMD_REGION0, + EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE); - /* - * Read the mapped ID twice, the first one is assuming the - * EC is a Microchip Embedded Controller (MEC) variant, if the - * protocol fails, fallback to the non MEC variant and try to - * read again the ID. - */ - ec_lpc->read = cros_ec_lpc_mec_read_bytes; - ec_lpc->write = cros_ec_lpc_mec_write_bytes; + /* + * Read the mapped ID twice, the first one is assuming the + * EC is a Microchip Embedded Controller (MEC) variant, if the + * protocol fails, fallback to the non MEC variant and try to + * read again the ID. + */ + ec_lpc->read = cros_ec_lpc_mec_read_bytes; + ec_lpc->write = cros_ec_lpc_mec_write_bytes; + } ret = ec_lpc->read(ec_lpc, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); if (ret < 0) return ret; @@ -594,7 +674,6 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) * Connect a notify handler to process MKBP messages if we have a * companion ACPI device. */ - adev = ACPI_COMPANION(dev); if (adev) { status = acpi_install_notify_handler(adev->handle, ACPI_ALL_NOTIFY, -- GitLab From f4bb0e5d56df495b40b90b4b99196681f013a344 Mon Sep 17 00:00:00 2001 From: Noah Shen Date: Mon, 4 Nov 2024 20:47:59 +0800 Subject: [PATCH 325/456] CHROMIUM: spi: mtk-nor: refine mtk nor clock struct Enable all of snfc clock to solve the boot failure problem. BUG=b:376509056 BUG=b:383247850 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:379034916 Signed-off-by: Noah Shen Change-Id: Icc583e68e4a4f97807a344455123a0002da149c9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073707 Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/spi/spi-mtk-nor.c | 103 ++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index cf4ee8b19e423..8c11ffada79c9 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -99,6 +99,8 @@ #define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000) +#define MAX_CLOCK_CNT 6 + struct mtk_nor_caps { u8 dma_bits; @@ -116,10 +118,8 @@ struct mtk_nor { void __iomem *base; u8 *buffer; dma_addr_t buffer_dma; - struct clk *spi_clk; - struct clk *ctlr_clk; - struct clk *axi_clk; - struct clk *axi_s_clk; + struct clk_bulk_data clocks[MAX_CLOCK_CNT]; + int clock_cnt; unsigned int spi_freq; bool wbuf_en; bool has_irq; @@ -703,44 +703,68 @@ msg_done: static void mtk_nor_disable_clk(struct mtk_nor *sp) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - clk_disable_unprepare(sp->axi_clk); - clk_disable_unprepare(sp->axi_s_clk); + clk_bulk_disable_unprepare(sp->clock_cnt, sp->clocks); } static int mtk_nor_enable_clk(struct mtk_nor *sp) { int ret; + int i; - ret = clk_prepare_enable(sp->spi_clk); - if (ret) - return ret; - - ret = clk_prepare_enable(sp->ctlr_clk); + ret = clk_bulk_prepare_enable(sp->clock_cnt, sp->clocks); if (ret) { - clk_disable_unprepare(sp->spi_clk); + dev_err(sp->dev, "enable clk failed\n"); return ret; } - ret = clk_prepare_enable(sp->axi_clk); - if (ret) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - return ret; - } + for (i = 0; i < sp->clock_cnt; i++) { + if (IS_ERR(sp->clocks[i].clk)) { + dev_err(sp->dev, "get %s fail\n",sp->clocks[i].id); + return PTR_ERR(sp->clocks[i].clk); + } - ret = clk_prepare_enable(sp->axi_s_clk); - if (ret) { - clk_disable_unprepare(sp->spi_clk); - clk_disable_unprepare(sp->ctlr_clk); - clk_disable_unprepare(sp->axi_clk); - return ret; + if(strcmp(sp->clocks[i].id, "spi")) + sp->spi_freq = clk_get_rate(sp->clocks[i].clk); } return 0; } +static int mtk_nor_parse_clk(struct device *dev, struct mtk_nor *sp) +{ + struct device_node *np = dev->of_node; + int ret; + const char *name; + int cnt,i; + + cnt = of_property_count_strings(np, "clock-names"); + if (!cnt || (cnt == -EINVAL)) { + dev_err(dev, "Unable to find clocks\n"); + ret = -EINVAL; + goto out; + } else if (cnt < 0) { + dev_err(dev, "Count clock strings failed, err %d\n", cnt); + ret = cnt; + goto out; + } + + sp->clock_cnt = cnt; + for (i = 0; i < cnt; i ++) { + ret = of_property_read_string_index(np, "clock-names", i, &name); + if (ret) { + dev_err(dev, "failed to get clock string\n"); + return ret; + } + + sp->clocks[i].id = name; + } + + ret = devm_clk_bulk_get(dev, sp->clock_cnt, sp->clocks); + +out: + return ret; +} + static void mtk_nor_init(struct mtk_nor *sp) { writel(0, sp->base + MTK_NOR_REG_IRQ_EN); @@ -813,29 +837,12 @@ static int mtk_nor_probe(struct platform_device *pdev) struct mtk_nor *sp; struct mtk_nor_caps *caps; void __iomem *base; - struct clk *spi_clk, *ctlr_clk, *axi_clk, *axi_s_clk; int ret, irq; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); - spi_clk = devm_clk_get(&pdev->dev, "spi"); - if (IS_ERR(spi_clk)) - return PTR_ERR(spi_clk); - - ctlr_clk = devm_clk_get(&pdev->dev, "sf"); - if (IS_ERR(ctlr_clk)) - return PTR_ERR(ctlr_clk); - - axi_clk = devm_clk_get_optional(&pdev->dev, "axi"); - if (IS_ERR(axi_clk)) - return PTR_ERR(axi_clk); - - axi_s_clk = devm_clk_get_optional(&pdev->dev, "axi_s"); - if (IS_ERR(axi_s_clk)) - return PTR_ERR(axi_s_clk); - caps = (struct mtk_nor_caps *)of_device_get_match_data(&pdev->dev); ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(caps->dma_bits)); @@ -868,10 +875,6 @@ static int mtk_nor_probe(struct platform_device *pdev) sp->wbuf_en = false; sp->ctlr = ctlr; sp->dev = &pdev->dev; - sp->spi_clk = spi_clk; - sp->ctlr_clk = ctlr_clk; - sp->axi_clk = axi_clk; - sp->axi_s_clk = axi_s_clk; sp->caps = caps; sp->high_dma = caps->dma_bits > 32; sp->buffer = dmam_alloc_coherent(&pdev->dev, @@ -885,11 +888,13 @@ static int mtk_nor_probe(struct platform_device *pdev) return -ENOMEM; } - ret = mtk_nor_enable_clk(sp); + ret = mtk_nor_parse_clk(sp->dev, sp); if (ret < 0) return ret; - sp->spi_freq = clk_get_rate(sp->spi_clk); + ret = mtk_nor_enable_clk(sp); + if (ret < 0) + return ret; mtk_nor_init(sp); -- GitLab From 7d90e52bf758cf7fbd4733fdbfeabc195ff58903 Mon Sep 17 00:00:00 2001 From: Runyang Chen Date: Tue, 26 Mar 2024 14:18:20 +0800 Subject: [PATCH 326/456] CHROMIUM: soc: mediatek: dapc: porting dapc driver DAPC(Device Access Permission Control) prevents a bus slave accessed by an unexpected master. It includes the bus id info, so it's not recommended to upstream. BUG=b:383916441 UPSTREAM-TASK=b:383957588 TEST=build pass and boot to shell Signed-off-by: Runyang Chen Change-Id: I052bb2920cb633880cedde3e823d434f0f26c1ff Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073741 Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-devapc.c | 163 ++++++++++++++++++++++++------ 1 file changed, 131 insertions(+), 32 deletions(-) diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c index b28feb9675402..decf382a3a51c 100644 --- a/drivers/soc/mediatek/mtk-devapc.c +++ b/drivers/soc/mediatek/mtk-devapc.c @@ -26,9 +26,19 @@ struct mtk_devapc_vio_dbgs { u32 addr_h:4; u32 resv:4; } dbg0_bits; + + struct { + u32 dmnid:6; + u32 vio_w:1; + u32 vio_r:1; + u32 addr_h:4; + u32 resv:20; + } dbg0_bits_ver2; }; u32 vio_dbg1; + u32 vio_dbg2; + u32 vio_dbg3; }; struct mtk_devapc_regs_ofs { @@ -37,6 +47,8 @@ struct mtk_devapc_regs_ofs { u32 vio_sta_offset; u32 vio_dbg0_offset; u32 vio_dbg1_offset; + u32 vio_dbg2_offset; + u32 vio_dbg3_offset; u32 apc_con_offset; u32 vio_shift_sta_offset; u32 vio_shift_sel_offset; @@ -44,16 +56,20 @@ struct mtk_devapc_regs_ofs { }; struct mtk_devapc_data { - /* numbers of violation index */ - u32 vio_idx_num; + u32 version; + /* Default numbers of violation index */ + u32 default_vio_idx_num; const struct mtk_devapc_regs_ofs *regs_ofs; }; struct mtk_devapc_context { struct device *dev; - void __iomem *infra_base; + void __iomem *base; struct clk *infra_clk; const struct mtk_devapc_data *data; + + /* numbers of violation index */ + u32 vio_idx_num; }; static void clear_vio_status(struct mtk_devapc_context *ctx) @@ -61,12 +77,12 @@ static void clear_vio_status(struct mtk_devapc_context *ctx) void __iomem *reg; int i; - reg = ctx->infra_base + ctx->data->regs_ofs->vio_sta_offset; + reg = ctx->base + ctx->data->regs_ofs->vio_sta_offset; - for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++) + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num - 1); i++) writel(GENMASK(31, 0), reg + 4 * i); - writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0), + writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1), 0), reg + 4 * i); } @@ -76,22 +92,22 @@ static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask) u32 val; int i; - reg = ctx->infra_base + ctx->data->regs_ofs->vio_mask_offset; + reg = ctx->base + ctx->data->regs_ofs->vio_mask_offset; if (mask) val = GENMASK(31, 0); else val = 0; - for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++) + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num - 1); i++) writel(val, reg + 4 * i); val = readl(reg + 4 * i); if (mask) - val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, + val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1), 0); else - val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, + val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1), 0); writel(val, reg + 4 * i); @@ -118,11 +134,11 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx) int ret; u32 val; - pd_vio_shift_sta_reg = ctx->infra_base + + pd_vio_shift_sta_reg = ctx->base + ctx->data->regs_ofs->vio_shift_sta_offset; - pd_vio_shift_sel_reg = ctx->infra_base + + pd_vio_shift_sel_reg = ctx->base + ctx->data->regs_ofs->vio_shift_sel_offset; - pd_vio_shift_con_reg = ctx->infra_base + + pd_vio_shift_con_reg = ctx->base + ctx->data->regs_ofs->vio_shift_con_offset; /* Find the minimum shift group which has violation */ @@ -160,25 +176,55 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx) */ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx) { - struct mtk_devapc_vio_dbgs vio_dbgs; + struct mtk_devapc_vio_dbgs vio_dbgs = { 0 }; void __iomem *vio_dbg0_reg; void __iomem *vio_dbg1_reg; + void __iomem *vio_dbg2_reg; + void __iomem *vio_dbg3_reg; + u32 vio_addr_l, vio_addr_h, bus_id, domain_id; + u32 vio_w, vio_r; + u64 vio_addr; - vio_dbg0_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg0_offset; - vio_dbg1_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg1_offset; + vio_dbg0_reg = ctx->base + ctx->data->regs_ofs->vio_dbg0_offset; + vio_dbg1_reg = ctx->base + ctx->data->regs_ofs->vio_dbg1_offset; + vio_dbg2_reg = ctx->base + ctx->data->regs_ofs->vio_dbg2_offset; + vio_dbg3_reg = ctx->base + ctx->data->regs_ofs->vio_dbg3_offset; vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg); vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg); + if (ctx->data->version >= 2U) + vio_dbgs.vio_dbg2 = readl(vio_dbg2_reg); + if (ctx->data->version >= 3U) + vio_dbgs.vio_dbg3 = readl(vio_dbg3_reg); + + if (ctx->data->version == 1U) { + /* arch version 1 */ + bus_id = vio_dbgs.dbg0_bits.mstid; + vio_addr = vio_dbgs.vio_dbg1; + domain_id = vio_dbgs.dbg0_bits.dmnid; + vio_w = vio_dbgs.dbg0_bits.vio_w; + vio_r = vio_dbgs.dbg0_bits.vio_r; + } else { + /* arch version 2 & 3 */ + bus_id = vio_dbgs.vio_dbg1; + + vio_addr_l = vio_dbgs.vio_dbg2; + vio_addr_h = ctx->data->version == 2U ? vio_dbgs.dbg0_bits_ver2.addr_h : + vio_dbgs.vio_dbg3; + vio_addr = ((u64)vio_addr_h << 32) + vio_addr_l; + domain_id = vio_dbgs.dbg0_bits_ver2.dmnid; + vio_w = vio_dbgs.dbg0_bits_ver2.vio_w; + vio_r = vio_dbgs.dbg0_bits_ver2.vio_r; + } /* Print violation information */ - if (vio_dbgs.dbg0_bits.vio_w) + if (vio_w) dev_info(ctx->dev, "Write Violation\n"); - else if (vio_dbgs.dbg0_bits.vio_r) + else if (vio_r) dev_info(ctx->dev, "Read Violation\n"); - dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n", - vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid, - vio_dbgs.vio_dbg1); + dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%llx\n", + bus_id, domain_id, vio_addr); } /* @@ -190,11 +236,15 @@ static irqreturn_t devapc_violation_irq(int irq_number, void *data) { struct mtk_devapc_context *ctx = data; + mask_module_irq(ctx, true); + while (devapc_sync_vio_dbg(ctx)) devapc_extract_vio_dbg(ctx); clear_vio_status(ctx); + mask_module_irq(ctx, false); + return IRQ_HANDLED; } @@ -203,7 +253,10 @@ static irqreturn_t devapc_violation_irq(int irq_number, void *data) */ static void start_devapc(struct mtk_devapc_context *ctx) { - writel(BIT(31), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset); + writel(BIT(31), ctx->base + ctx->data->regs_ofs->apc_con_offset); + + devapc_violation_irq(0, ctx); + dev_info(ctx->dev, "%s: Clear pending violation done...\n", __func__); mask_module_irq(ctx, false); } @@ -215,7 +268,7 @@ static void stop_devapc(struct mtk_devapc_context *ctx) { mask_module_irq(ctx, true); - writel(BIT(2), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset); + writel(BIT(2), ctx->base + ctx->data->regs_ofs->apc_con_offset); } static const struct mtk_devapc_regs_ofs devapc_regs_ofs_mt6779 = { @@ -229,16 +282,34 @@ static const struct mtk_devapc_regs_ofs devapc_regs_ofs_mt6779 = { .vio_shift_con_offset = 0xF20, }; +static const struct mtk_devapc_regs_ofs devapc_regs_ofs_mt8196 = { + .vio_mask_offset = 0x0, + .vio_sta_offset = 0x400, + .vio_dbg0_offset = 0x900, + .vio_dbg1_offset = 0x904, + .vio_dbg2_offset = 0x908, + .vio_dbg3_offset = 0x90C, + .apc_con_offset = 0xF00, + .vio_shift_sta_offset = 0xF20, + .vio_shift_sel_offset = 0xF30, + .vio_shift_con_offset = 0xF10, +}; + static const struct mtk_devapc_data devapc_mt6779 = { - .vio_idx_num = 511, + .default_vio_idx_num = 511, .regs_ofs = &devapc_regs_ofs_mt6779, }; static const struct mtk_devapc_data devapc_mt8186 = { - .vio_idx_num = 519, + .default_vio_idx_num = 519, .regs_ofs = &devapc_regs_ofs_mt6779, }; +static const struct mtk_devapc_data devapc_mt8196 = { + .version = 3, + .regs_ofs = &devapc_regs_ofs_mt8196, +}; + static const struct of_device_id mtk_devapc_dt_match[] = { { .compatible = "mediatek,mt6779-devapc", @@ -246,6 +317,9 @@ static const struct of_device_id mtk_devapc_dt_match[] = { }, { .compatible = "mediatek,mt8186-devapc", .data = &devapc_mt8186, + }, { + .compatible = "mediatek,mt8196-devapc", + .data = &devapc_mt8196, }, { }, }; @@ -268,22 +342,44 @@ static int mtk_devapc_probe(struct platform_device *pdev) ctx->data = of_device_get_match_data(&pdev->dev); ctx->dev = &pdev->dev; - ctx->infra_base = of_iomap(node, 0); - if (!ctx->infra_base) + ctx->base = of_iomap(node, 0); + if (!ctx->base) return -EINVAL; + /* + * Set effective vio_idx_num from default value. + * If vio_idx_num is 0, get the info from DT. + */ + ctx->vio_idx_num = ctx->data->default_vio_idx_num; + if (ctx->vio_idx_num == 0) + if (of_property_read_u32(node, + "vio-idx-num", + &ctx->vio_idx_num)) + return -EINVAL; + devapc_irq = irq_of_parse_and_map(node, 0); if (!devapc_irq) return -EINVAL; - ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock"); - if (IS_ERR(ctx->infra_clk)) - return -EINVAL; + /* + * The new design of DAPC clock is controlled by HW power domains, + * making it unnecessary to provide the clock control driver. + */ + ctx->infra_clk = devm_clk_get_optional(&pdev->dev, "devapc-infra-clock"); + if (!ctx->infra_clk) { + if (clk_prepare_enable(ctx->infra_clk)) + return -EINVAL; + } else { + dev_dbg(ctx->dev, "Cannot get devapc clock from CCF\n"); + } ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq, - IRQF_TRIGGER_NONE, "devapc", ctx); - if (ret) + IRQF_TRIGGER_NONE | IRQF_SHARED, "devapc", ctx); + if (ret) { + if (!ctx->infra_clk) + clk_disable_unprepare(ctx->infra_clk); return ret; + } platform_set_drvdata(pdev, ctx); @@ -298,6 +394,9 @@ static int mtk_devapc_remove(struct platform_device *pdev) stop_devapc(ctx); + if (!ctx->infra_clk) + clk_disable_unprepare(ctx->infra_clk); + return 0; } -- GitLab From 7f11552713c0366c382b38aecc6b0a02ea695757 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 29 Oct 2024 14:00:37 +0200 Subject: [PATCH 327/456] CHROMIUM: iwl7000: Revert "wifi: iwlwifi: mvm: remove STARTING state" This reverts commit 3aa5c2a02f74bd613467cc21ac22fb8649436629. The patch that is is fixing: 55077d95db5a, is also being reverted. BUG=b:385666021 Signed-off-by: Miri Korenblit Change-Id: I42685b4bbd76d696fe8ce59665ffd51a5b77c5a9 iwl7000-tree: 4ebf94348af460190fe5ece200a51b45d507d185 Signed-off-by: Miri Korenblit Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6158203 Reviewed-by: Arowa Suliman Reviewed-by: Nicolas Norvez Tested-by: Arowa Suliman Commit-Queue: Arowa Suliman Tested-by: Miriam Rachel Korenblit Signed-off-by: Hubert Mazur --- drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c index 89e2ef15ba29b..44381b520a24c 100644 --- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mac80211.c @@ -1398,8 +1398,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) /* we are starting the mac not in error flow, and restart is enabled */ if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && - iwlwifi_mod_params.fw_restart) + iwlwifi_mod_params.fw_restart) { max_retry = IWL_MAX_INIT_RETRY; + /* + * This will prevent mac80211 recovery flows to trigger during + * init failures + */ + set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); + } for (retry = 0; retry <= max_retry; retry++) { ret = __iwl_mvm_mac_start(mvm); @@ -1408,6 +1414,7 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) IWL_ERR(mvm, "mac start retry %d\n", retry); } + clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); mutex_unlock(&mvm->mutex); -- GitLab From 5894562cccd2f63c1cc46bf6a805308b638489b4 Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 8 Jan 2025 14:57:51 -0800 Subject: [PATCH 328/456] FROMLIST: drm/msm/dpu: Force disabling commits to take non-async path Force commit that are disabling a plane in the async_crtc to take the non-async commit tail path. In cases where there are two consecutive async cursor updates (one regular non-NULL update followed by a disabling NULL FB update), it is possible for the second NULL update to not be queued (due to the pending_crtc_mask check) or otherwise not be run before the cursor FB is deallocated by drm_atomic_helper_cleanup_planes(). This would cause a context fault since the hardware would try to fetch the old plane state with the stale FB address. Avoid this issue by forcing cursor updates that will disable the cursor plane to be blocking commits. This will ensure that hardware clears and stops fetching the FB source address before the driver deallocates the FB Fixes: 2d99ced787e3 ("drm/msm: async commit support") Signed-off-by: Jessica Zhang (am from https://patchwork.kernel.org/patch/13931699/) (also found at https://lore.kernel.org/r/20250108-async-disable-fix-v1-1-3f93eb600a3a@quicinc.com) UPSTREAM-TASK=b:389094006 BUG=b:332414449 TEST=Plug / unplug DP Change-Id: Ibc906faaa36f24598bade09a99b9a96b81191311 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6167528 Reviewed-by: Rob Clark Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/msm/msm_atomic.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 9c45d641b5212..ddc74c68148c6 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -142,6 +142,7 @@ static bool can_do_async(struct drm_atomic_state *state, struct drm_connector_state *connector_state; struct drm_connector *connector; struct drm_crtc_state *crtc_state; + struct drm_plane_state *plane_state; struct drm_crtc *crtc; int i, num_crtcs = 0; @@ -162,6 +163,18 @@ static bool can_do_async(struct drm_atomic_state *state, *async_crtc = crtc; } + /* + * Force a blocking commit if the cursor is being disabled. This is to + * ensure that the registers are cleared and hardware doesn't try to + * fetch from a stale address. + */ + if (*async_crtc) { + plane_state = drm_atomic_get_new_plane_state(state, + (*async_crtc)->cursor); + if (plane_state && !plane_state->fb) + return false; + } + return true; } -- GitLab From 16b98c07c7a271ea65d04055b58b963e87140ee5 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Fri, 10 Jan 2025 03:59:08 +0000 Subject: [PATCH 329/456] CHROMIUM: config: drop DRM_POWERVR_ROGUE_1_17 Devices run with chromeos-6.6 no longer require the downstream IMG drivers. Drop the config. $ echo CONFIG_DRM_POWERVR_ROGUE_1_17=n \ >>chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config $ ./chromeos/scripts/kernelconfig olddefconfig BUG=b:388792840 TEST=./chromeos/scripts/kernelconfig checkconfig Change-Id: I6c93dca042cbd6e18bd76fc1b5267806c9cd8cd8 Signed-off-by: Tzung-Bi Shih Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166780 Reviewed-by: Douglas Anderson Signed-off-by: Hubert Mazur --- .../config/chromeos/arm64/chromiumos-mediatek.flavour.config | 1 - 1 file changed, 1 deletion(-) diff --git a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config index b1284ecb4193a..002f2656eb0fd 100644 --- a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config +++ b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config @@ -43,7 +43,6 @@ CONFIG_DRM_PANEL_ILITEK_ILI9882T=y CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y CONFIG_DRM_PARADE_PS8640=y -CONFIG_DRM_POWERVR_ROGUE_1_17=y CONFIG_EEPROM_AT24=y # CONFIG_EFI is not set CONFIG_EXTCON_USBC_CROS_EC=y -- GitLab From 96830dfe9936684e16a79a6cd6f7485415dd15b4 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Fri, 10 Jan 2025 04:08:22 +0000 Subject: [PATCH 330/456] CHROMIUM: drm/img-rogue: Remove 1.17 IMG PowerVR Rogue driver Devices run with chromeos-6.6 no longer require the downstream IMG drivers. Drop the drivers. Instead of reverting all commits, this is simply: $ git rm -rf drivers/gpu/drm/img-rogue/ BUG=b:388792840 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I44084aa904e1c970f89f1876671e87366845dfa9 Signed-off-by: Tzung-Bi Shih Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166781 Reviewed-by: Douglas Anderson Signed-off-by: Hubert Mazur --- drivers/gpu/drm/Kconfig | 2 - drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/img-rogue/1.17/Makefile | 13 - drivers/gpu/drm/img-rogue/1.17/allocmem.c | 422 - drivers/gpu/drm/img-rogue/1.17/allocmem.h | 224 - drivers/gpu/drm/img-rogue/1.17/cache_km.c | 1630 ---- drivers/gpu/drm/img-rogue/1.17/cache_km.h | 151 - drivers/gpu/drm/img-rogue/1.17/cache_ops.h | 61 - .../drm/img-rogue/1.17/client_cache_bridge.h | 80 - .../1.17/client_cache_direct_bridge.c | 112 - .../1.17/client_devicememhistory_bridge.h | 111 - .../client_devicememhistory_direct_bridge.c | 195 - .../img-rogue/1.17/client_htbuffer_bridge.h | 71 - .../1.17/client_htbuffer_direct_bridge.c | 85 - .../gpu/drm/img-rogue/1.17/client_mm_bridge.h | 313 - .../img-rogue/1.17/client_mm_direct_bridge.c | 978 -- .../drm/img-rogue/1.17/client_pdump_bridge.h | 93 - .../1.17/client_pdump_direct_bridge.c | 151 - .../img-rogue/1.17/client_pdumpctrl_bridge.h | 73 - .../1.17/client_pdumpctrl_direct_bridge.c | 106 - .../img-rogue/1.17/client_pdumpmm_bridge.h | 125 - .../1.17/client_pdumpmm_direct_bridge.c | 239 - .../drm/img-rogue/1.17/client_pvrtl_bridge.h | 93 - .../1.17/client_pvrtl_direct_bridge.c | 175 - .../img-rogue/1.17/client_rgxpdump_bridge.h | 73 - .../1.17/client_rgxpdump_direct_bridge.c | 128 - .../gpu/drm/img-rogue/1.17/client_ri_bridge.h | 89 - .../img-rogue/1.17/client_ri_direct_bridge.c | 182 - .../drm/img-rogue/1.17/client_sync_bridge.h | 102 - .../1.17/client_sync_direct_bridge.c | 262 - .../1.17/client_synctracking_bridge.h | 68 - .../1.17/client_synctracking_direct_bridge.c | 92 - .../drm/img-rogue/1.17/common_cache_bridge.h | 126 - .../drm/img-rogue/1.17/common_cmm_bridge.h | 114 - .../1.17/common_devicememhistory_bridge.h | 185 - .../gpu/drm/img-rogue/1.17/common_di_bridge.h | 153 - .../drm/img-rogue/1.17/common_dmabuf_bridge.h | 150 - .../img-rogue/1.17/common_htbuffer_bridge.h | 104 - .../gpu/drm/img-rogue/1.17/common_mm_bridge.h | 1056 --- .../drm/img-rogue/1.17/common_pdump_bridge.h | 155 - .../img-rogue/1.17/common_pdumpctrl_bridge.h | 149 - .../img-rogue/1.17/common_pdumpmm_bridge.h | 259 - .../drm/img-rogue/1.17/common_pvrtl_bridge.h | 214 - .../1.17/common_rgxbreakpoint_bridge.h | 149 - .../drm/img-rogue/1.17/common_rgxcmp_bridge.h | 229 - .../img-rogue/1.17/common_rgxfwdbg_bridge.h | 200 - .../img-rogue/1.17/common_rgxhwperf_bridge.h | 172 - .../1.17/common_rgxkicksync_bridge.h | 143 - .../img-rogue/1.17/common_rgxpdump_bridge.h | 161 - .../1.17/common_rgxregconfig_bridge.h | 146 - .../img-rogue/1.17/common_rgxta3d_bridge.h | 449 - .../1.17/common_rgxtimerquery_bridge.h | 112 - .../drm/img-rogue/1.17/common_rgxtq2_bridge.h | 228 - .../drm/img-rogue/1.17/common_rgxtq_bridge.h | 176 - .../gpu/drm/img-rogue/1.17/common_ri_bridge.h | 225 - .../img-rogue/1.17/common_srvcore_bridge.h | 369 - .../drm/img-rogue/1.17/common_sync_bridge.h | 254 - .../1.17/common_synctracking_bridge.h | 97 - .../gpu/drm/img-rogue/1.17/config_kernel.h | 187 - .../gpu/drm/img-rogue/1.17/config_kernel.mk | 51 - .../1.17/configs/rgxconfig_km_4.V.2.51.h | 89 - .../drm/img-rogue/1.17/connection_server.c | 491 - .../drm/img-rogue/1.17/connection_server.h | 144 - .../1.17/cores/rgxcore_km_4.40.2.51.h | 73 - drivers/gpu/drm/img-rogue/1.17/debug_common.c | 1646 ---- drivers/gpu/drm/img-rogue/1.17/debug_common.h | 55 - drivers/gpu/drm/img-rogue/1.17/device.h | 540 -- .../drm/img-rogue/1.17/device_connection.h | 123 - drivers/gpu/drm/img-rogue/1.17/devicemem.c | 2984 ------ drivers/gpu/drm/img-rogue/1.17/devicemem.h | 730 -- .../drm/img-rogue/1.17/devicemem_heapcfg.c | 184 - .../drm/img-rogue/1.17/devicemem_heapcfg.h | 192 - .../img-rogue/1.17/devicemem_history_server.c | 1971 ---- .../img-rogue/1.17/devicemem_history_server.h | 157 - .../gpu/drm/img-rogue/1.17/devicemem_pdump.c | 404 - .../gpu/drm/img-rogue/1.17/devicemem_pdump.h | 363 - .../gpu/drm/img-rogue/1.17/devicemem_server.c | 2727 ------ .../gpu/drm/img-rogue/1.17/devicemem_server.h | 768 -- .../img-rogue/1.17/devicemem_server_utils.h | 198 - .../drm/img-rogue/1.17/devicemem_typedefs.h | 138 - .../gpu/drm/img-rogue/1.17/devicemem_utils.c | 1298 --- .../gpu/drm/img-rogue/1.17/devicemem_utils.h | 605 -- drivers/gpu/drm/img-rogue/1.17/devicememx.h | 223 - .../gpu/drm/img-rogue/1.17/devicememx_pdump.c | 74 - .../gpu/drm/img-rogue/1.17/devicememx_pdump.h | 81 - drivers/gpu/drm/img-rogue/1.17/di_common.h | 236 - drivers/gpu/drm/img-rogue/1.17/di_impl_brg.c | 894 -- drivers/gpu/drm/img-rogue/1.17/di_impl_brg.h | 92 - .../drm/img-rogue/1.17/di_impl_brg_intern.h | 61 - drivers/gpu/drm/img-rogue/1.17/di_server.c | 785 -- drivers/gpu/drm/img-rogue/1.17/di_server.h | 219 - drivers/gpu/drm/img-rogue/1.17/dllist.h | 408 - drivers/gpu/drm/img-rogue/1.17/dma_km.h | 83 - drivers/gpu/drm/img-rogue/1.17/dma_support.c | 523 -- drivers/gpu/drm/img-rogue/1.17/dma_support.h | 117 - .../gpu/drm/img-rogue/1.17/env_connection.h | 92 - drivers/gpu/drm/img-rogue/1.17/event.c | 514 -- drivers/gpu/drm/img-rogue/1.17/event.h | 54 - drivers/gpu/drm/img-rogue/1.17/fwload.c | 255 - drivers/gpu/drm/img-rogue/1.17/fwload.h | 158 - .../gpu/drm/img-rogue/1.17/fwtrace_string.h | 52 - drivers/gpu/drm/img-rogue/1.17/handle.c | 2486 ----- drivers/gpu/drm/img-rogue/1.17/handle.h | 206 - drivers/gpu/drm/img-rogue/1.17/handle_idr.c | 440 - drivers/gpu/drm/img-rogue/1.17/handle_impl.h | 89 - drivers/gpu/drm/img-rogue/1.17/handle_types.h | 90 - drivers/gpu/drm/img-rogue/1.17/hash.c | 734 -- drivers/gpu/drm/img-rogue/1.17/hash.h | 247 - drivers/gpu/drm/img-rogue/1.17/htb_debug.c | 1190 --- drivers/gpu/drm/img-rogue/1.17/htb_debug.h | 64 - drivers/gpu/drm/img-rogue/1.17/htbserver.c | 870 -- drivers/gpu/drm/img-rogue/1.17/htbserver.h | 228 - drivers/gpu/drm/img-rogue/1.17/htbuffer.c | 197 - drivers/gpu/drm/img-rogue/1.17/htbuffer.h | 135 - .../gpu/drm/img-rogue/1.17/htbuffer_init.h | 114 - drivers/gpu/drm/img-rogue/1.17/htbuffer_sf.h | 241 - .../gpu/drm/img-rogue/1.17/htbuffer_types.h | 118 - drivers/gpu/drm/img-rogue/1.17/img_3dtypes.h | 248 - drivers/gpu/drm/img-rogue/1.17/img_defs.h | 567 -- drivers/gpu/drm/img-rogue/1.17/img_elf.h | 111 - drivers/gpu/drm/img-rogue/1.17/img_types.h | 324 - .../gpu/drm/img-rogue/1.17/img_types_check.h | 58 - drivers/gpu/drm/img-rogue/1.17/info_page.h | 99 - .../gpu/drm/img-rogue/1.17/info_page_client.h | 89 - .../gpu/drm/img-rogue/1.17/info_page_defs.h | 91 - drivers/gpu/drm/img-rogue/1.17/info_page_km.c | 142 - .../drm/img-rogue/1.17/interrupt_support.c | 151 - .../drm/img-rogue/1.17/interrupt_support.h | 103 - .../drm/img-rogue/1.17/kernel_compatibility.h | 521 -- .../1.17/kernel_config_compatibility.h | 54 - .../gpu/drm/img-rogue/1.17/kernel_nospec.h | 71 - drivers/gpu/drm/img-rogue/1.17/kernel_types.h | 137 - .../drm/img-rogue/1.17/km/rgx_bvnc_defs_km.h | 377 - .../drm/img-rogue/1.17/km/rgx_bvnc_table_km.h | 396 - .../drm/img-rogue/1.17/km/rgx_cr_defs_km.h | 8077 ----------------- .../gpu/drm/img-rogue/1.17/km/rgxdefs_km.h | 338 - .../gpu/drm/img-rogue/1.17/km/rgxmhdefs_km.h | 286 - .../gpu/drm/img-rogue/1.17/km/rgxmmudefs_km.h | 216 - drivers/gpu/drm/img-rogue/1.17/km_apphint.c | 1749 ---- drivers/gpu/drm/img-rogue/1.17/km_apphint.h | 99 - .../gpu/drm/img-rogue/1.17/km_apphint_defs.h | 160 - .../img-rogue/1.17/km_apphint_defs_common.h | 280 - drivers/gpu/drm/img-rogue/1.17/linkage.h | 52 - .../gpu/drm/img-rogue/1.17/linux_sw_sync.h | 52 - drivers/gpu/drm/img-rogue/1.17/lists.c | 60 - drivers/gpu/drm/img-rogue/1.17/lists.h | 367 - drivers/gpu/drm/img-rogue/1.17/lock.h | 431 - drivers/gpu/drm/img-rogue/1.17/lock_types.h | 92 - drivers/gpu/drm/img-rogue/1.17/log2.h | 417 - drivers/gpu/drm/img-rogue/1.17/mem_utils.c | 449 - drivers/gpu/drm/img-rogue/1.17/mmu_common.c | 4462 --------- drivers/gpu/drm/img-rogue/1.17/mmu_common.h | 792 -- .../gpu/drm/img-rogue/1.17/module_common.c | 730 -- .../gpu/drm/img-rogue/1.17/module_common.h | 101 - .../gpu/drm/img-rogue/1.17/mt8173/Makefile | 5 - .../drm/img-rogue/1.17/mt8173/mt8173_mfgsys.c | 359 - .../drm/img-rogue/1.17/mt8173/mt8173_mfgsys.h | 67 - .../img-rogue/1.17/mt8173/mt8173_sysconfig.c | 552 -- .../gpu/drm/img-rogue/1.17/mt8173/sysinfo.h | 40 - .../gpu/drm/img-rogue/1.17/multicore_defs.h | 53 - drivers/gpu/drm/img-rogue/1.17/opaque_types.h | 56 - drivers/gpu/drm/img-rogue/1.17/os_cpu_cache.h | 69 - .../gpu/drm/img-rogue/1.17/os_srvinit_param.h | 328 - .../drm/img-rogue/1.17/osconnection_server.c | 157 - .../drm/img-rogue/1.17/osconnection_server.h | 133 - drivers/gpu/drm/img-rogue/1.17/osdi_impl.h | 201 - drivers/gpu/drm/img-rogue/1.17/osfunc.c | 2601 ------ drivers/gpu/drm/img-rogue/1.17/osfunc.h | 1696 ---- drivers/gpu/drm/img-rogue/1.17/osfunc_arm64.c | 290 - .../gpu/drm/img-rogue/1.17/osfunc_common.h | 300 - drivers/gpu/drm/img-rogue/1.17/osfunc_x86.c | 134 - drivers/gpu/drm/img-rogue/1.17/oskm_apphint.h | 186 - drivers/gpu/drm/img-rogue/1.17/osmmap.h | 115 - drivers/gpu/drm/img-rogue/1.17/osmmap_stub.c | 146 - .../gpu/drm/img-rogue/1.17/ospvr_gputrace.h | 167 - drivers/gpu/drm/img-rogue/1.17/pdump.h | 238 - drivers/gpu/drm/img-rogue/1.17/pdump_km.h | 1136 --- drivers/gpu/drm/img-rogue/1.17/pdump_mmu.c | 908 -- drivers/gpu/drm/img-rogue/1.17/pdump_mmu.h | 180 - .../gpu/drm/img-rogue/1.17/pdump_physmem.c | 670 -- .../gpu/drm/img-rogue/1.17/pdump_physmem.h | 257 - drivers/gpu/drm/img-rogue/1.17/pdump_server.c | 5565 ------------ .../drm/img-rogue/1.17/pdump_symbolicaddr.h | 55 - drivers/gpu/drm/img-rogue/1.17/pdumpdefs.h | 249 - drivers/gpu/drm/img-rogue/1.17/pdumpdesc.h | 226 - drivers/gpu/drm/img-rogue/1.17/physheap.c | 1184 --- drivers/gpu/drm/img-rogue/1.17/physheap.h | 497 - .../gpu/drm/img-rogue/1.17/physheap_config.h | 119 - drivers/gpu/drm/img-rogue/1.17/physmem.c | 847 -- drivers/gpu/drm/img-rogue/1.17/physmem.h | 343 - .../gpu/drm/img-rogue/1.17/physmem_dmabuf.c | 1309 --- .../gpu/drm/img-rogue/1.17/physmem_dmabuf.h | 124 - .../gpu/drm/img-rogue/1.17/physmem_hostmem.c | 204 - .../gpu/drm/img-rogue/1.17/physmem_hostmem.h | 65 - drivers/gpu/drm/img-rogue/1.17/physmem_lma.c | 1962 ---- drivers/gpu/drm/img-rogue/1.17/physmem_lma.h | 93 - .../gpu/drm/img-rogue/1.17/physmem_osmem.h | 142 - .../drm/img-rogue/1.17/physmem_osmem_linux.c | 3950 -------- .../drm/img-rogue/1.17/physmem_osmem_linux.h | 49 - drivers/gpu/drm/img-rogue/1.17/physmem_test.c | 710 -- drivers/gpu/drm/img-rogue/1.17/physmem_test.h | 51 - drivers/gpu/drm/img-rogue/1.17/pmr.c | 3863 -------- drivers/gpu/drm/img-rogue/1.17/pmr.h | 1112 --- drivers/gpu/drm/img-rogue/1.17/pmr_impl.h | 539 -- drivers/gpu/drm/img-rogue/1.17/pmr_os.c | 634 -- drivers/gpu/drm/img-rogue/1.17/pmr_os.h | 62 - drivers/gpu/drm/img-rogue/1.17/power.c | 929 -- drivers/gpu/drm/img-rogue/1.17/power.h | 430 - .../img-rogue/1.17/powervr/buffer_attribs.h | 193 - .../drm/img-rogue/1.17/powervr/mem_types.h | 64 - .../img-rogue/1.17/powervr/pvrsrv_sync_ext.h | 72 - drivers/gpu/drm/img-rogue/1.17/private_data.h | 59 - drivers/gpu/drm/img-rogue/1.17/proc_stats.h | 135 - .../gpu/drm/img-rogue/1.17/process_stats.c | 3358 ------- .../gpu/drm/img-rogue/1.17/process_stats.h | 223 - drivers/gpu/drm/img-rogue/1.17/pvr_bridge.h | 457 - drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.c | 585 -- drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.h | 103 - .../gpu/drm/img-rogue/1.17/pvr_buffer_sync.c | 739 -- .../gpu/drm/img-rogue/1.17/pvr_buffer_sync.h | 125 - .../img-rogue/1.17/pvr_buffer_sync_shared.h | 57 - .../img-rogue/1.17/pvr_counting_timeline.c | 273 - .../img-rogue/1.17/pvr_counting_timeline.h | 33 - drivers/gpu/drm/img-rogue/1.17/pvr_debug.c | 481 - drivers/gpu/drm/img-rogue/1.17/pvr_debug.h | 898 -- drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.c | 624 -- drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.h | 50 - drivers/gpu/drm/img-rogue/1.17/pvr_dicommon.h | 59 - drivers/gpu/drm/img-rogue/1.17/pvr_dma_resv.h | 80 - drivers/gpu/drm/img-rogue/1.17/pvr_drm.c | 336 - drivers/gpu/drm/img-rogue/1.17/pvr_drm.h | 146 - drivers/gpu/drm/img-rogue/1.17/pvr_drv.h | 106 - drivers/gpu/drm/img-rogue/1.17/pvr_dvfs.h | 138 - .../gpu/drm/img-rogue/1.17/pvr_dvfs_device.c | 810 -- .../gpu/drm/img-rogue/1.17/pvr_dvfs_device.h | 62 - .../drm/img-rogue/1.17/pvr_fd_sync_kernel.h | 64 - drivers/gpu/drm/img-rogue/1.17/pvr_fence.c | 1133 --- drivers/gpu/drm/img-rogue/1.17/pvr_fence.h | 239 - .../gpu/drm/img-rogue/1.17/pvr_fence_trace.h | 225 - drivers/gpu/drm/img-rogue/1.17/pvr_gputrace.c | 1281 --- .../gpu/drm/img-rogue/1.17/pvr_intrinsics.h | 70 - .../gpu/drm/img-rogue/1.17/pvr_ion_stats.h | 80 - .../gpu/drm/img-rogue/1.17/pvr_linux_fence.h | 103 - drivers/gpu/drm/img-rogue/1.17/pvr_notifier.c | 647 -- drivers/gpu/drm/img-rogue/1.17/pvr_notifier.h | 326 - .../gpu/drm/img-rogue/1.17/pvr_platform_drv.c | 344 - drivers/gpu/drm/img-rogue/1.17/pvr_procfs.h | 50 - drivers/gpu/drm/img-rogue/1.17/pvr_ricommon.h | 68 - drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.c | 164 - drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.h | 25 - drivers/gpu/drm/img-rogue/1.17/pvr_sync.h | 120 - drivers/gpu/drm/img-rogue/1.17/pvr_sync2.c | 2759 ------ drivers/gpu/drm/img-rogue/1.17/pvr_sync_api.h | 63 - .../gpu/drm/img-rogue/1.17/pvr_sync_file.c | 1059 --- .../img-rogue/1.17/pvr_sync_ioctl_common.c | 277 - .../img-rogue/1.17/pvr_sync_ioctl_common.h | 71 - .../drm/img-rogue/1.17/pvr_sync_ioctl_drm.c | 168 - .../drm/img-rogue/1.17/pvr_sync_ioctl_drm.h | 62 - drivers/gpu/drm/img-rogue/1.17/pvr_uaccess.h | 99 - drivers/gpu/drm/img-rogue/1.17/pvr_vmap.h | 83 - drivers/gpu/drm/img-rogue/1.17/pvrmodule.h | 48 - drivers/gpu/drm/img-rogue/1.17/pvrsrv.c | 3003 ------ drivers/gpu/drm/img-rogue/1.17/pvrsrv.h | 542 -- .../gpu/drm/img-rogue/1.17/pvrsrv_apphint.h | 71 - .../drm/img-rogue/1.17/pvrsrv_bridge_init.c | 385 - .../drm/img-rogue/1.17/pvrsrv_bridge_init.h | 53 - .../gpu/drm/img-rogue/1.17/pvrsrv_cleanup.h | 177 - .../gpu/drm/img-rogue/1.17/pvrsrv_device.h | 401 - .../drm/img-rogue/1.17/pvrsrv_device_types.h | 55 - .../gpu/drm/img-rogue/1.17/pvrsrv_devvar.h | 291 - drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.c | 61 - drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.h | 61 - .../gpu/drm/img-rogue/1.17/pvrsrv_errors.h | 411 - .../drm/img-rogue/1.17/pvrsrv_firmware_boot.h | 87 - .../img-rogue/1.17/pvrsrv_memalloc_physheap.h | 170 - .../drm/img-rogue/1.17/pvrsrv_memallocflags.h | 969 -- .../1.17/pvrsrv_memallocflags_internal.h | 78 - drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.c | 260 - drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.h | 135 - .../gpu/drm/img-rogue/1.17/pvrsrv_sync_km.h | 65 - .../drm/img-rogue/1.17/pvrsrv_sync_server.h | 278 - .../gpu/drm/img-rogue/1.17/pvrsrv_tlcommon.h | 260 - .../gpu/drm/img-rogue/1.17/pvrsrv_tlstreams.h | 61 - drivers/gpu/drm/img-rogue/1.17/pvrsrvkm.mk | 165 - drivers/gpu/drm/img-rogue/1.17/pvrversion.h | 68 - drivers/gpu/drm/img-rogue/1.17/ra.c | 2166 ----- drivers/gpu/drm/img-rogue/1.17/ra.h | 386 - drivers/gpu/drm/img-rogue/1.17/rgx_bridge.h | 243 - .../gpu/drm/img-rogue/1.17/rgx_bridge_init.c | 111 - .../gpu/drm/img-rogue/1.17/rgx_bridge_init.h | 55 - drivers/gpu/drm/img-rogue/1.17/rgx_common.h | 235 - .../drm/img-rogue/1.17/rgx_common_asserts.h | 73 - .../gpu/drm/img-rogue/1.17/rgx_compat_bvnc.h | 140 - drivers/gpu/drm/img-rogue/1.17/rgx_fw_info.h | 141 - .../drm/img-rogue/1.17/rgx_fwif_alignchecks.h | 192 - .../gpu/drm/img-rogue/1.17/rgx_fwif_hwperf.h | 252 - drivers/gpu/drm/img-rogue/1.17/rgx_fwif_km.h | 2341 ----- .../img-rogue/1.17/rgx_fwif_resetframework.h | 70 - drivers/gpu/drm/img-rogue/1.17/rgx_fwif_sf.h | 932 -- .../gpu/drm/img-rogue/1.17/rgx_fwif_shared.h | 335 - .../drm/img-rogue/1.17/rgx_heap_firmware.h | 120 - drivers/gpu/drm/img-rogue/1.17/rgx_heaps.h | 68 - drivers/gpu/drm/img-rogue/1.17/rgx_hwperf.h | 1607 ---- .../drm/img-rogue/1.17/rgx_hwperf_common.h | 482 - .../gpu/drm/img-rogue/1.17/rgx_hwperf_table.c | 635 -- .../gpu/drm/img-rogue/1.17/rgx_hwperf_table.h | 116 - .../drm/img-rogue/1.17/rgx_memallocflags.h | 58 - drivers/gpu/drm/img-rogue/1.17/rgx_meta.h | 385 - drivers/gpu/drm/img-rogue/1.17/rgx_mips.h | 374 - drivers/gpu/drm/img-rogue/1.17/rgx_options.h | 304 - .../gpu/drm/img-rogue/1.17/rgx_pdump_panics.h | 64 - drivers/gpu/drm/img-rogue/1.17/rgx_riscv.h | 250 - .../gpu/drm/img-rogue/1.17/rgx_tq_shared.h | 63 - drivers/gpu/drm/img-rogue/1.17/rgxapi_km.h | 336 - .../gpu/drm/img-rogue/1.17/rgxbreakpoint.c | 290 - .../gpu/drm/img-rogue/1.17/rgxbreakpoint.h | 141 - drivers/gpu/drm/img-rogue/1.17/rgxbvnc.c | 852 -- drivers/gpu/drm/img-rogue/1.17/rgxbvnc.h | 90 - drivers/gpu/drm/img-rogue/1.17/rgxccb.c | 2800 ------ drivers/gpu/drm/img-rogue/1.17/rgxccb.h | 356 - drivers/gpu/drm/img-rogue/1.17/rgxcompute.c | 1324 --- drivers/gpu/drm/img-rogue/1.17/rgxcompute.h | 173 - drivers/gpu/drm/img-rogue/1.17/rgxdebug.c | 5785 ------------ drivers/gpu/drm/img-rogue/1.17/rgxdebug.h | 229 - drivers/gpu/drm/img-rogue/1.17/rgxdevice.h | 828 -- .../gpu/drm/img-rogue/1.17/rgxfw_log_helper.h | 79 - drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.c | 282 - drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.h | 113 - .../gpu/drm/img-rogue/1.17/rgxfwimageutils.c | 1155 --- .../gpu/drm/img-rogue/1.17/rgxfwimageutils.h | 223 - .../drm/img-rogue/1.17/rgxfwtrace_strings.c | 56 - drivers/gpu/drm/img-rogue/1.17/rgxfwutils.c | 7825 ---------------- drivers/gpu/drm/img-rogue/1.17/rgxfwutils.h | 1362 --- .../gpu/drm/img-rogue/1.17/rgxheapconfig.h | 290 - .../drm/img-rogue/1.17/rgxheapconfig_65273.h | 124 - drivers/gpu/drm/img-rogue/1.17/rgxhwperf.c | 694 -- drivers/gpu/drm/img-rogue/1.17/rgxhwperf.h | 74 - .../gpu/drm/img-rogue/1.17/rgxhwperf_common.c | 3712 -------- .../gpu/drm/img-rogue/1.17/rgxhwperf_common.h | 512 -- drivers/gpu/drm/img-rogue/1.17/rgxinit.c | 5127 ----------- drivers/gpu/drm/img-rogue/1.17/rgxinit.h | 281 - drivers/gpu/drm/img-rogue/1.17/rgxkicksync.c | 794 -- drivers/gpu/drm/img-rogue/1.17/rgxkicksync.h | 128 - drivers/gpu/drm/img-rogue/1.17/rgxlayer.h | 812 -- .../gpu/drm/img-rogue/1.17/rgxlayer_impl.c | 1318 --- .../gpu/drm/img-rogue/1.17/rgxlayer_impl.h | 67 - drivers/gpu/drm/img-rogue/1.17/rgxmem.c | 947 -- drivers/gpu/drm/img-rogue/1.17/rgxmem.h | 147 - .../gpu/drm/img-rogue/1.17/rgxmipsmmuinit.c | 1045 --- .../gpu/drm/img-rogue/1.17/rgxmipsmmuinit.h | 97 - drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.c | 1079 --- drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.h | 60 - drivers/gpu/drm/img-rogue/1.17/rgxmulticore.c | 224 - drivers/gpu/drm/img-rogue/1.17/rgxmulticore.h | 54 - drivers/gpu/drm/img-rogue/1.17/rgxpdump.c | 708 -- drivers/gpu/drm/img-rogue/1.17/rgxpdump.h | 228 - drivers/gpu/drm/img-rogue/1.17/rgxpower.c | 1628 ---- drivers/gpu/drm/img-rogue/1.17/rgxpower.h | 286 - drivers/gpu/drm/img-rogue/1.17/rgxregconfig.c | 319 - drivers/gpu/drm/img-rogue/1.17/rgxregconfig.h | 130 - drivers/gpu/drm/img-rogue/1.17/rgxshader.c | 302 - drivers/gpu/drm/img-rogue/1.17/rgxshader.h | 83 - drivers/gpu/drm/img-rogue/1.17/rgxsrvinit.c | 1641 ---- drivers/gpu/drm/img-rogue/1.17/rgxstartstop.c | 1331 --- drivers/gpu/drm/img-rogue/1.17/rgxstartstop.h | 84 - drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.c | 184 - drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.h | 76 - drivers/gpu/drm/img-rogue/1.17/rgxta3d.c | 5549 ----------- drivers/gpu/drm/img-rogue/1.17/rgxta3d.h | 522 -- .../gpu/drm/img-rogue/1.17/rgxtdmtransfer.c | 1329 --- .../gpu/drm/img-rogue/1.17/rgxtdmtransfer.h | 132 - drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.c | 648 -- drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.h | 272 - .../gpu/drm/img-rogue/1.17/rgxtimerquery.c | 244 - .../gpu/drm/img-rogue/1.17/rgxtimerquery.h | 123 - drivers/gpu/drm/img-rogue/1.17/rgxtransfer.c | 1805 ---- drivers/gpu/drm/img-rogue/1.17/rgxtransfer.h | 153 - .../drm/img-rogue/1.17/rgxtransfer_shader.h | 61 - drivers/gpu/drm/img-rogue/1.17/rgxutils.c | 221 - drivers/gpu/drm/img-rogue/1.17/rgxutils.h | 185 - drivers/gpu/drm/img-rogue/1.17/ri_server.c | 2123 ----- drivers/gpu/drm/img-rogue/1.17/ri_server.h | 106 - drivers/gpu/drm/img-rogue/1.17/ri_typedefs.h | 52 - .../drm/img-rogue/1.17/rogue_trace_events.h | 542 -- .../drm/img-rogue/1.17/server_cache_bridge.c | 460 - .../drm/img-rogue/1.17/server_cmm_bridge.c | 414 - .../1.17/server_devicememhistory_bridge.c | 874 -- .../gpu/drm/img-rogue/1.17/server_di_bridge.c | 676 -- .../drm/img-rogue/1.17/server_dmabuf_bridge.c | 702 -- .../img-rogue/1.17/server_htbuffer_bridge.c | 354 - .../gpu/drm/img-rogue/1.17/server_mm_bridge.c | 4725 ---------- .../drm/img-rogue/1.17/server_pdump_bridge.c | 595 -- .../img-rogue/1.17/server_pdumpctrl_bridge.c | 250 - .../img-rogue/1.17/server_pdumpmm_bridge.c | 981 -- .../drm/img-rogue/1.17/server_pvrtl_bridge.c | 851 -- .../1.17/server_rgxbreakpoint_bridge.c | 380 - .../drm/img-rogue/1.17/server_rgxcmp_bridge.c | 1185 --- .../img-rogue/1.17/server_rgxfwdbg_bridge.c | 319 - .../img-rogue/1.17/server_rgxhwperf_bridge.c | 662 -- .../1.17/server_rgxkicksync_bridge.c | 586 -- .../img-rogue/1.17/server_rgxpdump_bridge.c | 264 - .../1.17/server_rgxregconfig_bridge.c | 246 - .../img-rogue/1.17/server_rgxta3d_bridge.c | 2771 ------ .../1.17/server_rgxtimerquery_bridge.c | 171 - .../drm/img-rogue/1.17/server_rgxtq2_bridge.c | 1225 --- .../drm/img-rogue/1.17/server_rgxtq_bridge.c | 1230 --- .../gpu/drm/img-rogue/1.17/server_ri_bridge.c | 776 -- .../img-rogue/1.17/server_srvcore_bridge.c | 1104 --- .../drm/img-rogue/1.17/server_sync_bridge.c | 763 -- .../1.17/server_synctracking_bridge.c | 337 - .../img-rogue/1.17/services_kernel_client.h | 291 - drivers/gpu/drm/img-rogue/1.17/services_km.h | 180 - drivers/gpu/drm/img-rogue/1.17/servicesext.h | 156 - drivers/gpu/drm/img-rogue/1.17/sofunc_pvr.h | 94 - drivers/gpu/drm/img-rogue/1.17/sofunc_rgx.h | 95 - drivers/gpu/drm/img-rogue/1.17/srvcore.c | 1453 --- drivers/gpu/drm/img-rogue/1.17/srvcore.h | 240 - drivers/gpu/drm/img-rogue/1.17/srvinit.h | 68 - drivers/gpu/drm/img-rogue/1.17/srvkm.h | 145 - drivers/gpu/drm/img-rogue/1.17/sync.c | 907 -- drivers/gpu/drm/img-rogue/1.17/sync.h | 292 - .../gpu/drm/img-rogue/1.17/sync_checkpoint.c | 2979 ------ .../gpu/drm/img-rogue/1.17/sync_checkpoint.h | 666 -- .../img-rogue/1.17/sync_checkpoint_external.h | 83 - .../drm/img-rogue/1.17/sync_checkpoint_init.h | 82 - .../img-rogue/1.17/sync_checkpoint_internal.h | 288 - .../drm/img-rogue/1.17/sync_fallback_server.h | 204 - .../gpu/drm/img-rogue/1.17/sync_internal.h | 127 - .../drm/img-rogue/1.17/sync_prim_internal.h | 84 - drivers/gpu/drm/img-rogue/1.17/sync_server.c | 1223 --- drivers/gpu/drm/img-rogue/1.17/sync_server.h | 249 - drivers/gpu/drm/img-rogue/1.17/syscommon.h | 146 - .../gpu/drm/img-rogue/1.17/sysvalidation.h | 62 - drivers/gpu/drm/img-rogue/1.17/tlclient.c | 500 - drivers/gpu/drm/img-rogue/1.17/tlclient.h | 257 - drivers/gpu/drm/img-rogue/1.17/tlintern.c | 442 - drivers/gpu/drm/img-rogue/1.17/tlintern.h | 345 - drivers/gpu/drm/img-rogue/1.17/tlserver.c | 747 -- drivers/gpu/drm/img-rogue/1.17/tlserver.h | 97 - drivers/gpu/drm/img-rogue/1.17/tlstream.c | 1625 ---- drivers/gpu/drm/img-rogue/1.17/tlstream.h | 600 -- drivers/gpu/drm/img-rogue/1.17/trace_events.c | 265 - drivers/gpu/drm/img-rogue/1.17/trace_events.h | 198 - drivers/gpu/drm/img-rogue/1.17/tutils_km.h | 172 - drivers/gpu/drm/img-rogue/1.17/tutilsdefs.h | 230 - .../drm/img-rogue/1.17/uniq_key_splay_tree.c | 280 - .../drm/img-rogue/1.17/uniq_key_splay_tree.h | 90 - drivers/gpu/drm/img-rogue/1.17/vmm_impl.h | 186 - .../gpu/drm/img-rogue/1.17/vmm_pvz_client.c | 138 - .../gpu/drm/img-rogue/1.17/vmm_pvz_client.h | 77 - .../gpu/drm/img-rogue/1.17/vmm_pvz_common.h | 65 - .../gpu/drm/img-rogue/1.17/vmm_pvz_server.c | 245 - .../gpu/drm/img-rogue/1.17/vmm_pvz_server.h | 121 - .../gpu/drm/img-rogue/1.17/vmm_type_stub.c | 108 - drivers/gpu/drm/img-rogue/1.17/vz_vm.h | 61 - drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.c | 183 - drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.h | 79 - drivers/gpu/drm/img-rogue/1.17/vz_vmm_vm.c | 221 - drivers/gpu/drm/img-rogue/Kconfig | 30 - 459 files changed, 243397 deletions(-) delete mode 100644 drivers/gpu/drm/img-rogue/1.17/Makefile delete mode 100644 drivers/gpu/drm/img-rogue/1.17/allocmem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/allocmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/cache_km.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/cache_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/cache_ops.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_cache_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_cache_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_htbuffer_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_htbuffer_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_mm_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_mm_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdump_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdump_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pvrtl_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_pvrtl_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_ri_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_ri_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_sync_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_sync_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_synctracking_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/client_synctracking_direct_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_cache_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_cmm_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_devicememhistory_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_di_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_dmabuf_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_htbuffer_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_mm_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_pdump_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_pdumpctrl_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_pdumpmm_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_pvrtl_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxbreakpoint_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxcmp_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxfwdbg_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxhwperf_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxkicksync_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxpdump_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxregconfig_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxta3d_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxtimerquery_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxtq2_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_rgxtq_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_ri_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_srvcore_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_sync_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/common_synctracking_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/config_kernel.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/config_kernel.mk delete mode 100644 drivers/gpu/drm/img-rogue/1.17/configs/rgxconfig_km_4.V.2.51.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/connection_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/connection_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/cores/rgxcore_km_4.40.2.51.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/debug_common.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/debug_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/device.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/device_connection.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_server_utils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_typedefs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_utils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicemem_utils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicememx.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_impl_brg.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_impl_brg.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_impl_brg_intern.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/di_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/dllist.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/dma_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/dma_support.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/dma_support.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/env_connection.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/event.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/event.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/fwload.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/fwload.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/fwtrace_string.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/handle.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/handle.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/handle_idr.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/handle_impl.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/handle_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/hash.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/hash.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htb_debug.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htb_debug.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbserver.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbserver.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbuffer.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbuffer.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbuffer_init.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbuffer_sf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/htbuffer_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/img_3dtypes.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/img_defs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/img_elf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/img_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/img_types_check.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/info_page.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/info_page_client.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/info_page_defs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/info_page_km.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/interrupt_support.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/interrupt_support.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/kernel_compatibility.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/kernel_config_compatibility.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/kernel_nospec.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/kernel_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_defs_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_table_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgx_cr_defs_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgxdefs_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgxmhdefs_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km/rgxmmudefs_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km_apphint.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km_apphint.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km_apphint_defs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/km_apphint_defs_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/linkage.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/linux_sw_sync.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/lists.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/lists.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/lock.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/lock_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/log2.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mem_utils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mmu_common.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mmu_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/module_common.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/module_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mt8173/Makefile delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_sysconfig.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/mt8173/sysinfo.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/multicore_defs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/opaque_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/os_cpu_cache.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/os_srvinit_param.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osconnection_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osconnection_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osdi_impl.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osfunc.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osfunc.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osfunc_arm64.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osfunc_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osfunc_x86.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/oskm_apphint.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osmmap.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/osmmap_stub.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ospvr_gputrace.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_mmu.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_mmu.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_physmem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_physmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdump_symbolicaddr.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdumpdefs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pdumpdesc.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physheap.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physheap.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physheap_config.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_lma.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_lma.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_osmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_test.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/physmem_test.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pmr.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pmr.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pmr_impl.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pmr_os.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pmr_os.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/power.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/power.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/powervr/buffer_attribs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/powervr/mem_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/powervr/pvrsrv_sync_ext.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/private_data.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/proc_stats.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/process_stats.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/process_stats.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync_shared.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_debug.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_debug.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_dicommon.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_dma_resv.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_drm.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_drm.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_drv.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_dvfs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_fd_sync_kernel.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_fence.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_fence.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_fence_trace.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_gputrace.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_intrinsics.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_ion_stats.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_linux_fence.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_notifier.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_notifier.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_procfs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_ricommon.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync2.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_api.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_file.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_uaccess.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvr_vmap.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrmodule.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_apphint.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_cleanup.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_device.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_device_types.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_devvar.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_errors.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_firmware_boot.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_memalloc_physheap.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags_internal.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlcommon.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlstreams.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrsrvkm.mk delete mode 100644 drivers/gpu/drm/img-rogue/1.17/pvrversion.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ra.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ra.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_bridge.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_common_asserts.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_compat_bvnc.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fw_info.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_alignchecks.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_hwperf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_resetframework.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_sf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_fwif_shared.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_heap_firmware.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_heaps.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_hwperf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_memallocflags.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_meta.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_mips.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_options.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_pdump_panics.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_riscv.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgx_tq_shared.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxapi_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxbvnc.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxbvnc.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxccb.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxccb.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxcompute.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxcompute.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxdebug.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxdebug.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxdevice.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfw_log_helper.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwtrace_strings.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwutils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxfwutils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxheapconfig.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxheapconfig_65273.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxhwperf.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxhwperf.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxinit.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxinit.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxkicksync.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxkicksync.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxlayer.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmem.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmem.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmulticore.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxmulticore.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxpdump.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxpdump.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxpower.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxpower.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxregconfig.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxregconfig.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxshader.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxshader.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxsrvinit.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxstartstop.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxstartstop.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxta3d.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxta3d.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtransfer.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtransfer.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxtransfer_shader.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxutils.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rgxutils.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ri_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ri_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/ri_typedefs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/rogue_trace_events.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_cache_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_cmm_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_devicememhistory_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_di_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_dmabuf_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_htbuffer_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_mm_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_pdump_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_pdumpctrl_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_pdumpmm_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_pvrtl_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxbreakpoint_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxcmp_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxfwdbg_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxhwperf_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxkicksync_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxpdump_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxregconfig_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxta3d_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxtimerquery_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxtq2_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_rgxtq_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_ri_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_srvcore_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_sync_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/server_synctracking_bridge.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/services_kernel_client.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/services_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/servicesext.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sofunc_pvr.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sofunc_rgx.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/srvcore.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/srvcore.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/srvinit.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/srvkm.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_external.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_init.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_internal.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_fallback_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_internal.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_prim_internal.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sync_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/syscommon.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/sysvalidation.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlclient.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlclient.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlintern.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlintern.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlserver.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlserver.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlstream.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tlstream.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/trace_events.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/trace_events.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tutils_km.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/tutilsdefs.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_impl.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_pvz_common.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vmm_type_stub.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vz_vm.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.c delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.h delete mode 100644 drivers/gpu/drm/img-rogue/1.17/vz_vmm_vm.c delete mode 100644 drivers/gpu/drm/img-rogue/Kconfig diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8c840421fc404..b7e7ffca8bf69 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -391,8 +391,6 @@ source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" -source "drivers/gpu/drm/img-rogue/Kconfig" - config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 9d9e36f7f45d2..982986273ee21 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -175,7 +175,6 @@ obj-y += imx/ obj-$(CONFIG_DRM_INGENIC) += ingenic/ obj-$(CONFIG_DRM_LOGICVC) += logicvc/ obj-$(CONFIG_DRM_MEDIATEK) += mediatek/ -obj-$(CONFIG_DRM_POWERVR_ROGUE_1_17) += img-rogue/1.17/ obj-$(CONFIG_DRM_MESON) += meson/ obj-y += i2c/ obj-y += panel/ diff --git a/drivers/gpu/drm/img-rogue/1.17/Makefile b/drivers/gpu/drm/img-rogue/1.17/Makefile deleted file mode 100644 index d7891303490c7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -img_basedir := $(srctree)/drivers/gpu/drm/img-rogue/1.17 -include $(img_basedir)/config_kernel.mk - -obj-$(CONFIG_DRM_POWERVR_ROGUE_1_17) += pvrsrvkm_1_17.o - -ccflags-y += \ - -include config_kernel.h \ - -I$(img_basedir) \ - -I$(img_basedir)/km \ - -D__linux__ - -include $(img_basedir)/pvrsrvkm.mk -include $(img_basedir)/mt8173/Makefile diff --git a/drivers/gpu/drm/img-rogue/1.17/allocmem.c b/drivers/gpu/drm/img-rogue/1.17/allocmem.c deleted file mode 100644 index 5d7c85da1f987..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/allocmem.c +++ /dev/null @@ -1,422 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Host memory management implementation for Linux -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "process_stats.h" -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) -#include "pvrsrv.h" -#endif -#include "osfunc.h" - - -/* - * When memory statistics are disabled, memory records are used instead. - * In order for these to work, the PID of the process that requested the - * allocation needs to be stored at the end of the kmalloc'd memory, making - * sure 4 extra bytes are allocated to fit the PID. - * - * There is no need for this extra allocation when memory statistics are - * enabled, since all allocations are tracked in DebugFS mem_area files. - */ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_ENABLE_MEMORY_STATS) -#define ALLOCMEM_MEMSTATS_PADDING sizeof(IMG_UINT32) -#else -#define ALLOCMEM_MEMSTATS_PADDING 0UL -#endif - -/* How many times kmalloc can fail before the allocation threshold is reduced */ -static const IMG_UINT32 g_ui32kmallocFailLimit = 10; -/* How many kmalloc failures happened since the last allocation threshold change */ -static IMG_UINT32 g_ui32kmallocFailCount = 0; -/* Current kmalloc threshold value in bytes */ -static IMG_UINT32 g_ui32kmallocThreshold = PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD; -/* Spinlock used so that the global variables above may not be modified by more than 1 thread at a time */ -static DEFINE_SPINLOCK(kmalloc_lock); - -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) -static DEFINE_SPINLOCK(kmalloc_leak_lock); -static IMG_UINT32 g_ui32kmallocLeakCounter = 0; -#endif - -static inline void OSTryDecreaseKmallocThreshold(void) -{ - unsigned long flags; - spin_lock_irqsave(&kmalloc_lock, flags); - - g_ui32kmallocFailCount++; - - if (g_ui32kmallocFailCount >= g_ui32kmallocFailLimit) - { - g_ui32kmallocFailCount = 0; - if (g_ui32kmallocThreshold > PAGE_SIZE) - { - g_ui32kmallocThreshold >>= 1; - printk(KERN_INFO "Threshold is now set to %d\n", g_ui32kmallocThreshold); - } - } - - spin_unlock_irqrestore(&kmalloc_lock, flags); -} - -static inline void OSResetKmallocFailCount(void) -{ - unsigned long flags; - spin_lock_irqsave(&kmalloc_lock, flags); - - g_ui32kmallocFailCount = 0; - - spin_unlock_irqrestore(&kmalloc_lock, flags); -} - -static inline void _pvr_vfree(const void* pvAddr) -{ -#if defined(DEBUG) - /* Size harder to come by for vmalloc and since vmalloc allocates - * a whole number of pages, poison the minimum size known to have - * been allocated. - */ - OSCachedMemSet((void*)pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE, - PAGE_SIZE); -#endif - vfree(pvAddr); -} - -static inline void _pvr_kfree(const void* pvAddr) -{ -#if defined(DEBUG) - /* Poison whole memory block */ - OSCachedMemSet((void*)pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE, - ksize(pvAddr)); -#endif - kfree(pvAddr); -} - -static inline void _pvr_alloc_stats_add(void *pvAddr, IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS) -{ -#if !defined(PVRSRV_ENABLE_PROCESS_STATS) - PVR_UNREFERENCED_PARAMETER(pvAddr); -#else - if (!is_vmalloc_addr(pvAddr)) - { -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - IMG_CPU_PHYADDR sCpuPAddr; - sCpuPAddr.uiAddr = 0; - - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, - pvAddr, - sCpuPAddr, - ksize(pvAddr), - NULL, - OSGetCurrentClientProcessIDKM() - DEBUG_MEMSTATS_ARGS); -#else - { - /* Store the PID in the final additional 4 bytes allocated */ - IMG_UINT32 *puiTemp = IMG_OFFSET_ADDR(pvAddr, ksize(pvAddr) - ALLOCMEM_MEMSTATS_PADDING); - *puiTemp = OSGetCurrentClientProcessIDKM(); - } - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvAddr), OSGetCurrentClientProcessIDKM()); -#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ - } - else - { -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - IMG_CPU_PHYADDR sCpuPAddr; - sCpuPAddr.uiAddr = 0; - - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC, - pvAddr, - sCpuPAddr, - ((ui32Size + PAGE_SIZE-1) & ~(PAGE_SIZE-1)), - NULL, - OSGetCurrentClientProcessIDKM() - DEBUG_MEMSTATS_ARGS); -#else - PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC, - ((ui32Size + PAGE_SIZE-1) & ~(PAGE_SIZE-1)), - (IMG_UINT64)(uintptr_t) pvAddr, - OSGetCurrentClientProcessIDKM()); -#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ - } -#endif /* !defined(PVRSRV_ENABLE_PROCESS_STATS) */ -} - -static inline void _pvr_alloc_stats_remove(void *pvAddr) -{ -#if !defined(PVRSRV_ENABLE_PROCESS_STATS) - PVR_UNREFERENCED_PARAMETER(pvAddr); -#else - if (!is_vmalloc_addr(pvAddr)) - { -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - { - IMG_UINT32 *puiTemp = IMG_OFFSET_ADDR(pvAddr, ksize(pvAddr) - ALLOCMEM_MEMSTATS_PADDING); - PVRSRVStatsDecrMemKAllocStat(ksize(pvAddr), *puiTemp); - } -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, - (IMG_UINT64)(uintptr_t) pvAddr, - OSGetCurrentClientProcessIDKM()); -#endif - } - else - { -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC, - (IMG_UINT64)(uintptr_t) pvAddr); -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC, - (IMG_UINT64)(uintptr_t) pvAddr, - OSGetCurrentClientProcessIDKM()); -#endif - } -#endif /* !defined(PVRSRV_ENABLE_PROCESS_STATS) */ -} - -void *(OSAllocMem)(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS) -{ - void *pvRet = NULL; - - if ((ui32Size + ALLOCMEM_MEMSTATS_PADDING) <= g_ui32kmallocThreshold) - { - pvRet = kmalloc(ui32Size + ALLOCMEM_MEMSTATS_PADDING, GFP_KERNEL); - if (pvRet == NULL) - { - OSTryDecreaseKmallocThreshold(); - } - else - { - OSResetKmallocFailCount(); - } - } - - if (pvRet == NULL) - { - pvRet = vmalloc(ui32Size); - } - - if (pvRet != NULL) - { - _pvr_alloc_stats_add(pvRet, ui32Size DEBUG_MEMSTATS_ARGS); - } - - return pvRet; -} - -void *(OSAllocZMem)(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS) -{ - void *pvRet = NULL; - - if ((ui32Size + ALLOCMEM_MEMSTATS_PADDING) <= g_ui32kmallocThreshold) - { - pvRet = kzalloc(ui32Size + ALLOCMEM_MEMSTATS_PADDING, GFP_KERNEL); - if (pvRet == NULL) - { - OSTryDecreaseKmallocThreshold(); - } - else - { - OSResetKmallocFailCount(); - } - } - - if (pvRet == NULL) - { - pvRet = vzalloc(ui32Size); - } - - if (pvRet != NULL) - { - _pvr_alloc_stats_add(pvRet, ui32Size DEBUG_MEMSTATS_ARGS); - } - - return pvRet; -} - -/* - * The parentheses around OSFreeMem prevent the macro in allocmem.h from - * applying, as it would break the function's definition. - */ -void (OSFreeMem)(void *pvMem) -{ -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) - unsigned long flags; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if (psPVRSRVData) - { - IMG_UINT32 ui32kmallocLeakMax = psPVRSRVData->sMemLeakIntervals.ui32OSAlloc; - - spin_lock_irqsave(&kmalloc_leak_lock, flags); - - g_ui32kmallocLeakCounter++; - if (ui32kmallocLeakMax && (g_ui32kmallocLeakCounter >= ui32kmallocLeakMax)) - { - g_ui32kmallocLeakCounter = 0; - spin_unlock_irqrestore(&kmalloc_leak_lock, flags); - - PVR_DPF((PVR_DBG_WARNING, - "%s: Skipped freeing of pointer 0x%p to trigger memory leak.", - __func__, - pvMem)); - return; - } - - spin_unlock_irqrestore(&kmalloc_leak_lock, flags); - } -#endif - if (pvMem != NULL) - { - _pvr_alloc_stats_remove(pvMem); - - if (!is_vmalloc_addr(pvMem)) - { - _pvr_kfree(pvMem); - } - else - { - _pvr_vfree(pvMem); - } - } -} - -void *OSAllocMemNoStats(IMG_UINT32 ui32Size) -{ - void *pvRet = NULL; - - if (ui32Size <= g_ui32kmallocThreshold) - { - pvRet = kmalloc(ui32Size, GFP_KERNEL); - if (pvRet == NULL) - { - OSTryDecreaseKmallocThreshold(); - } - else - { - OSResetKmallocFailCount(); - } - } - - if (pvRet == NULL) - { - pvRet = vmalloc(ui32Size); - } - - return pvRet; -} - -void *OSAllocZMemNoStats(IMG_UINT32 ui32Size) -{ - void *pvRet = NULL; - - if (ui32Size <= g_ui32kmallocThreshold) - { - pvRet = kzalloc(ui32Size, GFP_KERNEL); - if (pvRet == NULL) - { - OSTryDecreaseKmallocThreshold(); - } - else - { - OSResetKmallocFailCount(); - } - } - - if (pvRet == NULL) - { - pvRet = vzalloc(ui32Size); - } - - return pvRet; -} - -/* - * The parentheses around OSFreeMemNoStats prevent the macro in allocmem.h from - * applying, as it would break the function's definition. - */ -void (OSFreeMemNoStats)(void *pvMem) -{ -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) - unsigned long flags; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if (psPVRSRVData) - { - IMG_UINT32 ui32kmallocLeakMax = psPVRSRVData->sMemLeakIntervals.ui32OSAlloc; - - spin_lock_irqsave(&kmalloc_leak_lock, flags); - - g_ui32kmallocLeakCounter++; - if (ui32kmallocLeakMax && (g_ui32kmallocLeakCounter >= ui32kmallocLeakMax)) - { - g_ui32kmallocLeakCounter = 0; - spin_unlock_irqrestore(&kmalloc_leak_lock, flags); - - PVR_DPF((PVR_DBG_WARNING, - "%s: Skipped freeing of pointer 0x%p to trigger memory leak.", - __func__, - pvMem)); - return; - } - - spin_unlock_irqrestore(&kmalloc_leak_lock, flags); - } -#endif - if (pvMem != NULL) - { - if (!is_vmalloc_addr(pvMem)) - { - _pvr_kfree(pvMem); - } - else - { - _pvr_vfree(pvMem); - } - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/allocmem.h b/drivers/gpu/drm/img-rogue/1.17/allocmem.h deleted file mode 100644 index 3de9e6781fbdf..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/allocmem.h +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************/ /*! -@File allocmem.h -@Title memory allocation header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Memory-Allocation API definitions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 ALLOCMEM_H -#define ALLOCMEM_H - -#include "img_types.h" -#include "pvr_debug.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * PVRSRV_ENABLE_PROCESS_STATS enables process statistics regarding events, - * resources and memory across all processes - * PVRSRV_ENABLE_MEMORY_STATS enables recording of Linux kernel memory - * allocations, provided that PVRSRV_ENABLE_PROCESS_STATS is enabled - * - Output can be found in: - * /(sys/kernel/debug|proc)/pvr/proc_stats/[live|retired]_pids_stats/mem_area - * PVRSRV_DEBUG_LINUX_MEMORY_STATS provides more details about memory - * statistics in conjunction with PVRSRV_ENABLE_MEMORY_STATS - * PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON is defined to encompass both memory - * allocation statistics functionalities described above in a single macro - */ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && defined(PVRSRV_ENABLE_MEMORY_STATS) && defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) && defined(DEBUG) -#define PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON -#endif - -/* - * When using detailed memory allocation statistics, the line number and - * file name where the allocation happened are also provided. - * When this feature is not used, these parameters are not needed. - */ -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON) -#define DEBUG_MEMSTATS_PARAMS ,void *pvAllocFromFile, IMG_UINT32 ui32AllocFromLine -#define DEBUG_MEMSTATS_ARGS ,pvAllocFromFile, ui32AllocFromLine -#define DEBUG_MEMSTATS_UNREF (void)pvAllocFromFile; (void)ui32AllocFromLine; -#define DEBUG_MEMSTATS_VALUES ,__FILE__, __LINE__ -#else -#define DEBUG_MEMSTATS_PARAMS /*!< - * Used for PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON - * build option. */ -#define DEBUG_MEMSTATS_ARGS /*!< - * Used for PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON - * build option. */ -#define DEBUG_MEMSTATS_UNREF /*!< - * Used for PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON - * build option. */ -#define DEBUG_MEMSTATS_VALUES /*!< - * Used for PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON - * build option. */ -#endif - - -/**************************************************************************/ /*! -@Function OSAllocMem -@Description Allocates CPU memory. Contents are uninitialized. - If passed a size of zero, function should not assert, - but just return a NULL pointer. -@Input ui32Size Size of required allocation (in bytes) -@Return Pointer to allocated memory on success. - Otherwise NULL. - */ /**************************************************************************/ -#if defined(DOXYGEN) -void *OSAllocMem(IMG_UINT32 ui32Size); -#else -void *OSAllocMem(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS); -#define OSAllocMem(_size) (OSAllocMem)((_size) DEBUG_MEMSTATS_VALUES) -#endif - -/**************************************************************************/ /*! -@Function OSAllocZMem -@Description Allocates CPU memory and initializes the contents to zero. - If passed a size of zero, function should not assert, - but just return a NULL pointer. -@Input ui32Size Size of required allocation (in bytes) -@Return Pointer to allocated memory on success. - Otherwise NULL. - */ /**************************************************************************/ -#if defined(DOXYGEN) -void *OSAllocZMem(IMG_UINT32 ui32Size); -#else -void *OSAllocZMem(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS); -#define OSAllocZMem(_size) (OSAllocZMem)((_size) DEBUG_MEMSTATS_VALUES) -#endif - - -/**************************************************************************/ /*! -@Function OSAllocMemNoStats -@Description Allocates CPU memory. Contents are uninitialized. - If passed a size of zero, function should not assert, - but just return a NULL pointer. - The allocated memory is not accounted for by process stats. - Process stats are an optional feature (enabled only when - PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount - of memory allocated to help in debugging. Where this is not - required, OSAllocMem() and OSAllocMemNoStats() equate to - the same operation. -@Input ui32Size Size of required allocation (in bytes) -@Return Pointer to allocated memory on success. - Otherwise NULL. - */ /**************************************************************************/ -void *OSAllocMemNoStats(IMG_UINT32 ui32Size); - -/**************************************************************************/ /*! -@Function OSAllocZMemNoStats -@Description Allocates CPU memory and initializes the contents to zero. - If passed a size of zero, function should not assert, - but just return a NULL pointer. - The allocated memory is not accounted for by process stats. - Process stats are an optional feature (enabled only when - PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount - of memory allocated to help in debugging. Where this is not - required, OSAllocZMem() and OSAllocZMemNoStats() equate to - the same operation. -@Input ui32Size Size of required allocation (in bytes) -@Return Pointer to allocated memory on success. - Otherwise NULL. - */ /**************************************************************************/ -void *OSAllocZMemNoStats(IMG_UINT32 ui32Size); - -/**************************************************************************/ /*! -@Function OSFreeMem -@Description Frees previously allocated CPU memory. -@Input pvCpuVAddr Pointer to the memory to be freed. -@Return None. - */ /**************************************************************************/ -void OSFreeMem(void *pvCpuVAddr); - -/**************************************************************************/ /*! -@Function OSFreeMemNoStats -@Description Frees previously allocated CPU memory. - The freed memory does not update the figures in process stats. - Process stats are an optional feature (enabled only when - PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount - of memory allocated to help in debugging. Where this is not - required, OSFreeMem() and OSFreeMemNoStats() equate to the - same operation. -@Input pvCpuVAddr Pointer to the memory to be freed. -@Return None. - */ /**************************************************************************/ -void OSFreeMemNoStats(void *pvCpuVAddr); - -/* - * These macros allow us to catch double-free bugs on DEBUG builds and - * prevent crashes on RELEASE builds. - */ - -/*! @cond Doxygen_Suppress */ -#if defined(DEBUG) -#define double_free_sentinel ((void *)&OSFreeMem) -#define ALLOCMEM_ASSERT(exp) PVR_ASSERT(exp) -#else -#define double_free_sentinel NULL -#define ALLOCMEM_ASSERT(exp) do {} while (0) -#endif -/*! @endcond */ - -/*! Frees memory allocated by OSAllocMem(). */ -#define OSFreeMem(_ptr) do { \ - ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \ - (OSFreeMem)(_ptr); \ - (_ptr) = double_free_sentinel; \ - MSC_SUPPRESS_4127 \ - } while (0) - -/*! Frees memory allocated by OSAllocMemNoStats(). */ -#define OSFreeMemNoStats(_ptr) do { \ - ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \ - (OSFreeMemNoStats)(_ptr); \ - (_ptr) = double_free_sentinel; \ - MSC_SUPPRESS_4127 \ - } while (0) - -#if defined(__cplusplus) -} -#endif - -#endif /* ALLOCMEM_H */ - -/****************************************************************************** - End of file (allocmem.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/cache_km.c b/drivers/gpu/drm/img-rogue/1.17/cache_km.c deleted file mode 100644 index 71ed28342d3df..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/cache_km.c +++ /dev/null @@ -1,1630 +0,0 @@ -/*************************************************************************/ /*! -@File cache_km.c -@Title CPU d-cache maintenance operations framework -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements server side code for CPU d-cache maintenance taking - into account the idiosyncrasies of the various types of CPU - d-cache instruction-set architecture (ISA) maintenance - mechanisms. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -#if defined(__linux__) -#include -#include -#include -#include -#include -#include -#endif - -#include "pmr.h" -#include "log2.h" -#include "device.h" -#include "pvrsrv.h" -#include "osfunc.h" -#include "cache_km.h" -#include "pvr_debug.h" -#include "lock_types.h" -#include "allocmem.h" -#include "process_stats.h" -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) -#include "ri_server.h" -#endif -#include "devicemem.h" -#include "pvrsrv_apphint.h" -#include "pvrsrv_sync_server.h" -#include "km_apphint_defs.h" -#include "km_apphint_defs_common.h" -#include "oskm_apphint.h" -#include "di_server.h" - -/* This header must always be included last */ -#if defined(__linux__) -#include "kernel_compatibility.h" -#endif - -/* Top-level file-local build definitions */ -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) && defined(__linux__) -#define CACHEOP_DEBUG -#define CACHEOP_STATS_ITEMS_MAX 32 -#define INCR_WRAP(x) ((x+1) >= CACHEOP_STATS_ITEMS_MAX ? 0 : (x+1)) -#define DECR_WRAP(x) ((x-1) < 0 ? (CACHEOP_STATS_ITEMS_MAX-1) : (x-1)) -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) -/* Refer to CacheOpStatsExecLogHeader() for header item names */ -#define CACHEOP_RI_PRINTF_HEADER "%-8s %-8s %-10s %-10s %-5s %-16s %-16s %-10s %-10s %-18s" -#define CACHEOP_RI_PRINTF "%-8d %-8d %-10s %-10s %-5s 0x%-14llx 0x%-14llx 0x%-8llx 0x%-8llx %-18llu\n" -#else -#define CACHEOP_PRINTF_HEADER "%-8s %-8s %-10s %-10s %-5s %-10s %-10s %-18s" -#define CACHEOP_PRINTF "%-8d %-8d %-10s %-10s %-5s 0x%-8llx 0x%-8llx %-18llu\n" -#endif -#endif - -//#define CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING /* Force OS page (not cache line) flush granularity */ -#define CACHEOP_PVR_ASSERT(x) /* Define as PVR_ASSERT(x), enable for swdev & testing */ -#define CACHEOP_DEVMEM_OOR_ERROR_STRING "cacheop device memory request is out of range" -#define CACHEOP_MAX_DEBUG_MESSAGE_LEN 160 - -typedef struct _CACHEOP_WORK_ITEM_ -{ - PMR *psPMR; - IMG_DEVMEM_SIZE_T uiSize; - PVRSRV_CACHE_OP uiCacheOp; - IMG_DEVMEM_OFFSET_T uiOffset; - PVRSRV_TIMELINE iTimeline; - SYNC_TIMELINE_OBJ sSWTimelineObj; - PVRSRV_DEVICE_NODE *psDevNode; -#if defined(CACHEOP_DEBUG) - IMG_UINT64 ui64StartTime; - IMG_UINT64 ui64EndTime; - IMG_BOOL bKMReq; - IMG_PID pid; -#endif -} CACHEOP_WORK_ITEM; - -typedef struct _CACHEOP_STATS_EXEC_ITEM_ -{ - IMG_UINT32 ui32DeviceID; - IMG_PID pid; - PVRSRV_CACHE_OP uiCacheOp; - IMG_DEVMEM_SIZE_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT64 ui64StartTime; - IMG_UINT64 ui64EndTime; - IMG_BOOL bKMReq; -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEV_PHYADDR sDevPAddr; -#endif -} CACHEOP_STATS_EXEC_ITEM; - -typedef enum _CACHEOP_CONFIG_ -{ - CACHEOP_CONFIG_DEFAULT = 0, - /* cache flush mechanism types */ - CACHEOP_CONFIG_URBF = 4, - /* sw-emulated deferred flush mechanism */ - CACHEOP_CONFIG_KDF = 8, - /* pseudo configuration items */ - CACHEOP_CONFIG_LAST = 16, - CACHEOP_CONFIG_KLOG = 16, - CACHEOP_CONFIG_ALL = 31 -} CACHEOP_CONFIG; - -typedef struct _CACHEOP_WORK_QUEUE_ -{ -/* - * Init. state & primary device node framework - * is anchored on. - */ - IMG_BOOL bInit; -/* - MMU page size/shift & d-cache line size - */ - size_t uiPageSize; - IMG_UINT32 uiLineSize; - IMG_UINT32 uiLineShift; - IMG_UINT32 uiPageShift; - OS_CACHE_OP_ADDR_TYPE uiCacheOpAddrType; - PMR *psInfoPagePMR; - IMG_UINT32 *pui32InfoPage; - -#if defined(CACHEOP_DEBUG) -/* - CacheOp statistics - */ - DI_ENTRY *psDIEntry; - IMG_HANDLE hStatsExecLock; - - IMG_UINT32 ui32ServerOps; - IMG_UINT32 ui32ClientOps; - IMG_UINT32 ui32TotalOps; - IMG_UINT32 ui32ServerOpUsedUMVA; - IMG_UINT32 ui32AvgExecTime; - IMG_UINT32 ui32AvgExecTimeRemainder; - - IMG_INT32 i32StatsExecWriteIdx; - CACHEOP_STATS_EXEC_ITEM asStatsExecuted[CACHEOP_STATS_ITEMS_MAX]; -#endif - - DI_ENTRY *psConfigTune; - IMG_HANDLE hConfigLock; - CACHEOP_CONFIG eConfig; - IMG_UINT32 ui32Config; - IMG_BOOL bSupportsUMFlush; -} CACHEOP_WORK_QUEUE; - -/* Top-level CacheOp framework object */ -static CACHEOP_WORK_QUEUE gsCwq; - -#define CacheOpConfigSupports(e) ((gsCwq.eConfig & (e)) ? IMG_TRUE : IMG_FALSE) - -#if defined(CACHEOP_DEBUG) -static INLINE void CacheOpStatsExecLogHeader(IMG_CHAR szBuffer[CACHEOP_MAX_DEBUG_MESSAGE_LEN]) -{ - OSSNPrintf(szBuffer, CACHEOP_MAX_DEBUG_MESSAGE_LEN, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - CACHEOP_RI_PRINTF_HEADER, -#else - CACHEOP_PRINTF_HEADER, -#endif - "DevID", - "Pid", - "CacheOp", - "Type", - "Origin", -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - "DevVAddr", - "DevPAddr", -#endif - "Offset", - "Size", - "xTime (us)"); -} - -static void CacheOpStatsExecLogWrite(CACHEOP_WORK_ITEM *psCacheOpWorkItem) -{ - IMG_INT32 i32WriteOffset; - IMG_UINT32 ui32ExecTime; - printk("log write\n"); - if (!psCacheOpWorkItem->uiCacheOp) - { - return; - } - else if (psCacheOpWorkItem->bKMReq && !CacheOpConfigSupports(CACHEOP_CONFIG_KLOG)) - { - /* KM logs spams the history due to frequency, this removes it completely */ - return; - } - - OSLockAcquire(gsCwq.hStatsExecLock); - - i32WriteOffset = gsCwq.i32StatsExecWriteIdx; - gsCwq.i32StatsExecWriteIdx = INCR_WRAP(gsCwq.i32StatsExecWriteIdx); - gsCwq.asStatsExecuted[i32WriteOffset].ui32DeviceID = psCacheOpWorkItem->psDevNode ? psCacheOpWorkItem->psDevNode->sDevId.ui32InternalID : -1; - gsCwq.asStatsExecuted[i32WriteOffset].pid = psCacheOpWorkItem->pid; - gsCwq.asStatsExecuted[i32WriteOffset].uiSize = psCacheOpWorkItem->uiSize; - gsCwq.asStatsExecuted[i32WriteOffset].bKMReq = psCacheOpWorkItem->bKMReq; - gsCwq.asStatsExecuted[i32WriteOffset].uiOffset = psCacheOpWorkItem->uiOffset; - gsCwq.asStatsExecuted[i32WriteOffset].uiCacheOp = psCacheOpWorkItem->uiCacheOp; - gsCwq.asStatsExecuted[i32WriteOffset].ui64StartTime = psCacheOpWorkItem->ui64StartTime; - gsCwq.asStatsExecuted[i32WriteOffset].ui64EndTime = psCacheOpWorkItem->ui64EndTime; - - CACHEOP_PVR_ASSERT(gsCwq.asStatsExecuted[i32WriteOffset].pid); -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - if (gsCwq.bInit && psCacheOpWorkItem->psPMR) - { - IMG_CPU_PHYADDR sDevPAddr; - PVRSRV_ERROR eError, eLockError; - IMG_BOOL bValid; - - /* Get more detailed information regarding the sub allocations that - PMR has from RI manager for process that requested the CacheOp */ - eError = RIDumpProcessListKM(psCacheOpWorkItem->psPMR, - gsCwq.asStatsExecuted[i32WriteOffset].pid, - gsCwq.asStatsExecuted[i32WriteOffset].uiOffset, - &gsCwq.asStatsExecuted[i32WriteOffset].sDevVAddr); - PVR_GOTO_IF_ERROR(eError, e0); - - /* (Re)lock here as some PMR might have not been locked */ - eLockError = PMRLockSysPhysAddresses(psCacheOpWorkItem->psPMR); - PVR_GOTO_IF_ERROR(eLockError, e0); - - eError = PMR_CpuPhysAddr(psCacheOpWorkItem->psPMR, - gsCwq.uiPageShift, - 1, - gsCwq.asStatsExecuted[i32WriteOffset].uiOffset, - &sDevPAddr, - &bValid); - - eLockError = PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR); - PVR_LOG_IF_ERROR(eLockError, "PMRUnlockSysPhysAddresses"); - - PVR_GOTO_IF_ERROR(eError, e0); - - - - gsCwq.asStatsExecuted[i32WriteOffset].sDevPAddr.uiAddr = sDevPAddr.uiAddr; - } -#endif - - /* Calculate the approximate cumulative moving average execution time. - * This calculation is based on standard equation: - * - * CMAnext = (new + count * CMAprev) / (count + 1) - * - * but in simplified form: - * - * CMAnext = CMAprev + (new - CMAprev) / (count + 1) - * - * this gets rid of multiplication and prevents overflow. - * - * Also to increase accuracy that we lose with integer division, - * we hold the moving remainder of the division and add it. - * - * CMAnext = CMAprev + (new - CMAprev + CMRprev) / (count + 1) - * - * Multiple tests proved it to be the best solution for approximating - * CMA using integers. - * - */ - - ui32ExecTime = - gsCwq.asStatsExecuted[i32WriteOffset].ui64EndTime - - gsCwq.asStatsExecuted[i32WriteOffset].ui64StartTime; - - { - - IMG_INT32 i32Div = - (IMG_INT32) ui32ExecTime - - (IMG_INT32) gsCwq.ui32AvgExecTime + - (IMG_INT32) gsCwq.ui32AvgExecTimeRemainder; - - gsCwq.ui32AvgExecTime += i32Div / (IMG_INT32)(gsCwq.ui32TotalOps + 1); - gsCwq.ui32AvgExecTimeRemainder = i32Div % (IMG_INT32)(gsCwq.ui32TotalOps + 1); - - gsCwq.ui32TotalOps++; - - } - - if (!gsCwq.asStatsExecuted[i32WriteOffset].bKMReq) - { - /* This operation queues only UM CacheOp in per-PID process statistics database */ - PVRSRVStatsUpdateCacheOpStats( - gsCwq.asStatsExecuted[i32WriteOffset].uiCacheOp, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - gsCwq.asStatsExecuted[i32WriteOffset].sDevVAddr, - gsCwq.asStatsExecuted[i32WriteOffset].sDevPAddr, -#endif - gsCwq.asStatsExecuted[i32WriteOffset].uiOffset, - gsCwq.asStatsExecuted[i32WriteOffset].uiSize, - ui32ExecTime, - !gsCwq.asStatsExecuted[i32WriteOffset].bKMReq, - psCacheOpWorkItem->pid); - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) -e0: -#endif - OSLockRelease(gsCwq.hStatsExecLock); -} - -static int CacheOpStatsExecLogRead(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - IMG_CHAR *pszFlushType; - IMG_CHAR *pszCacheOpType; - IMG_CHAR *pszFlushSource; - IMG_INT32 i32ReadOffset; - IMG_INT32 i32WriteOffset; - - IMG_CHAR szBuffer[CACHEOP_MAX_DEBUG_MESSAGE_LEN] = {0}; - PVR_UNREFERENCED_PARAMETER(pvData); - - OSLockAcquire(gsCwq.hStatsExecLock); - - DIPrintf(psEntry, - "Primary CPU d-cache architecture: LSZ: 0x%x, URBF: %s\n", - gsCwq.uiLineSize, - gsCwq.bSupportsUMFlush ? "Yes" : "No"); - - DIPrintf(psEntry, - "Configuration: UKT: %d, URBF: %s\n", - gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD], - gsCwq.eConfig & CACHEOP_CONFIG_URBF ? "Yes" : "No"); - - DIPrintf(psEntry, - "Summary: Total Ops [%d] - Server(using UMVA)/Client [%d(%d)/%d]. Avg execution time [%d]\n", - gsCwq.ui32TotalOps, gsCwq.ui32ServerOps, gsCwq.ui32ServerOpUsedUMVA, gsCwq.ui32ClientOps, gsCwq.ui32AvgExecTime); - - - CacheOpStatsExecLogHeader(szBuffer); - DIPrintf(psEntry, "%s\n", szBuffer); - - i32WriteOffset = gsCwq.i32StatsExecWriteIdx; - for (i32ReadOffset = DECR_WRAP(i32WriteOffset); - i32ReadOffset != i32WriteOffset; - i32ReadOffset = DECR_WRAP(i32ReadOffset)) - { - IMG_UINT64 ui64ExecTime = - gsCwq.asStatsExecuted[i32ReadOffset].ui64EndTime - - gsCwq.asStatsExecuted[i32ReadOffset].ui64StartTime; - - IMG_DEVMEM_SIZE_T ui64NumOfPages = - gsCwq.asStatsExecuted[i32ReadOffset].uiSize >> gsCwq.uiPageShift; - - - if (!gsCwq.asStatsExecuted[i32ReadOffset].uiCacheOp) - { - break; - } - if (ui64NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC) - { - pszFlushType = "RBF.Fast"; - } - else - { - pszFlushType = "RBF.Slow"; - } - - pszFlushSource = gsCwq.asStatsExecuted[i32ReadOffset].bKMReq ? " KM" : " UM"; - - switch (gsCwq.asStatsExecuted[i32ReadOffset].uiCacheOp) - { - case PVRSRV_CACHE_OP_NONE: - pszCacheOpType = "None"; - break; - case PVRSRV_CACHE_OP_CLEAN: - pszCacheOpType = "Clean"; - break; - case PVRSRV_CACHE_OP_INVALIDATE: - pszCacheOpType = "Invalidate"; - break; - case PVRSRV_CACHE_OP_FLUSH: - pszCacheOpType = "Flush"; - break; - case PVRSRV_CACHE_OP_TIMELINE: - pszCacheOpType = "Timeline"; - pszFlushType = " "; - break; - default: - pszCacheOpType = "Unknown"; - break; - } - - DIPrintf(psEntry, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - CACHEOP_RI_PRINTF, -#else - CACHEOP_PRINTF, -#endif - gsCwq.asStatsExecuted[i32ReadOffset].ui32DeviceID, - gsCwq.asStatsExecuted[i32ReadOffset].pid, - pszCacheOpType, - pszFlushType, - pszFlushSource, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - gsCwq.asStatsExecuted[i32ReadOffset].sDevVAddr.uiAddr, - gsCwq.asStatsExecuted[i32ReadOffset].sDevPAddr.uiAddr, -#endif - gsCwq.asStatsExecuted[i32ReadOffset].uiOffset, - gsCwq.asStatsExecuted[i32ReadOffset].uiSize, - ui64ExecTime); - - } - - OSLockRelease(gsCwq.hStatsExecLock); - - return 0; -} -#endif /* defined(CACHEOP_DEBUG) */ - -static INLINE void CacheOpStatsReset(void) -{ -#if defined(CACHEOP_DEBUG) - gsCwq.ui32ServerOps = 0; - gsCwq.ui32ClientOps = 0; - gsCwq.ui32TotalOps = 0; - gsCwq.ui32ServerOpUsedUMVA = 0; - gsCwq.ui32AvgExecTime = 0; - gsCwq.ui32AvgExecTimeRemainder = 0; - - gsCwq.i32StatsExecWriteIdx = 0; - - OSCachedMemSet(gsCwq.asStatsExecuted, 0, sizeof(gsCwq.asStatsExecuted)); -#endif -} - -static void CacheOpConfigUpdate(IMG_UINT32 ui32Config) -{ - OSLockAcquire(gsCwq.hConfigLock); - - /* Step 0, set the gsCwq.eConfig bits */ - if (!(ui32Config & (CACHEOP_CONFIG_LAST - 1))) - { - gsCwq.eConfig = CACHEOP_CONFIG_KDF; - if (gsCwq.bSupportsUMFlush) - { - gsCwq.eConfig |= CACHEOP_CONFIG_URBF; - } - } - else - { - if (ui32Config & CACHEOP_CONFIG_KDF) - { - gsCwq.eConfig |= CACHEOP_CONFIG_KDF; - } - else - { - gsCwq.eConfig &= ~CACHEOP_CONFIG_KDF; - } - - if (gsCwq.bSupportsUMFlush && (ui32Config & CACHEOP_CONFIG_URBF)) - { - gsCwq.eConfig |= CACHEOP_CONFIG_URBF; - } - else - { - gsCwq.eConfig &= ~CACHEOP_CONFIG_URBF; - } - } - - if (ui32Config & CACHEOP_CONFIG_KLOG) - { - /* Suppress logs from KM caller */ - gsCwq.eConfig |= CACHEOP_CONFIG_KLOG; - } - else - { - gsCwq.eConfig &= ~CACHEOP_CONFIG_KLOG; - } - - /* Step 1, set gsCwq.ui32Config based on gsCwq.eConfig */ - ui32Config = 0; - - if (gsCwq.eConfig & CACHEOP_CONFIG_KDF) - { - ui32Config |= CACHEOP_CONFIG_KDF; - } - if (gsCwq.eConfig & CACHEOP_CONFIG_URBF) - { - ui32Config |= CACHEOP_CONFIG_URBF; - } - if (gsCwq.eConfig & CACHEOP_CONFIG_KLOG) - { - ui32Config |= CACHEOP_CONFIG_KLOG; - } - gsCwq.ui32Config = ui32Config; - - - /* Step 3, in certain cases where a CacheOp/VA is provided, this threshold determines at what point - the optimisation due to the presence of said VA (i.e. us not having to remap the PMR pages in KM) - is clawed-back because of the overhead of maintaining such large request which might stalls the - user thread; so to hide this latency have these CacheOps executed on deferred CacheOp thread */ - gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD] = (IMG_UINT32)(PVR_DIRTY_BYTES_FLUSH_THRESHOLD >> 2); - - /* Step 4, if no UM support, all requests are done in KM so zero these forcing all client requests - to come down into the KM for maintenance */ - gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = 0; - - if (gsCwq.bSupportsUMFlush) - { - /* With URBF enabled we never go to the kernel */ - if (gsCwq.eConfig & CACHEOP_CONFIG_URBF) - { - gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = (IMG_UINT32)~0; - } - } - - /* Step 5, reset stats. */ - CacheOpStatsReset(); - - OSLockRelease(gsCwq.hConfigLock); -} - -static int CacheOpConfigRead(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVR_UNREFERENCED_PARAMETER(pvData); - - DIPrintf(psEntry, "URBF: %s\n", - gsCwq.eConfig & CACHEOP_CONFIG_URBF ? "Yes" : "No"); - - return 0; -} - -static INLINE PVRSRV_ERROR CacheOpConfigQuery(const PVRSRV_DEVICE_NODE *psDevNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - IMG_UINT32 ui32ID = (IMG_UINT32)(uintptr_t) psPrivate; - PVR_UNREFERENCED_PARAMETER(psDevNode); - - switch (ui32ID) - { - case APPHINT_ID_CacheOpConfig: - *pui32Value = gsCwq.ui32Config; - break; - - case APPHINT_ID_CacheOpUMKMThresholdSize: - *pui32Value = gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD]; - break; - - default: - break; - } - - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR CacheOpConfigSet(const PVRSRV_DEVICE_NODE *psDevNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - IMG_UINT32 ui32ID = (IMG_UINT32)(uintptr_t) psPrivate; - PVR_UNREFERENCED_PARAMETER(psDevNode); - - switch (ui32ID) - { - case APPHINT_ID_CacheOpConfig: - CacheOpConfigUpdate(ui32Value & CACHEOP_CONFIG_ALL); - break; - - - case APPHINT_ID_CacheOpUMKMThresholdSize: - { - if (!ui32Value || !gsCwq.bSupportsUMFlush) - { - /* CPU ISA does not support UM flush, therefore every request goes down into - the KM, silently ignore request to adjust threshold */ - PVR_ASSERT(! gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD]); - break; - } - else if (ui32Value < gsCwq.uiPageSize) - { - /* Silently round-up to OS page size */ - ui32Value = gsCwq.uiPageSize; - } - - /* Align to OS page size */ - ui32Value &= ~(gsCwq.uiPageSize - 1); - - gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = ui32Value; - - break; - } - - default: - break; - } - - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR CacheOpTimelineBind(PVRSRV_DEVICE_NODE *psDevNode, - CACHEOP_WORK_ITEM *psCacheOpWorkItem, - PVRSRV_TIMELINE iTimeline) -{ - PVRSRV_ERROR eError; - - /* Always default the incoming CacheOp work-item to safe values */ - SyncClearTimelineObj(&psCacheOpWorkItem->sSWTimelineObj); - psCacheOpWorkItem->iTimeline = PVRSRV_NO_TIMELINE; - psCacheOpWorkItem->psDevNode = psDevNode; - if (iTimeline == PVRSRV_NO_TIMELINE) - { - return PVRSRV_OK; - } - - psCacheOpWorkItem->iTimeline = iTimeline; - eError = SyncSWGetTimelineObj(iTimeline, &psCacheOpWorkItem->sSWTimelineObj); - PVR_LOG_IF_ERROR(eError, "SyncSWGetTimelineObj"); - - return eError; -} - -static INLINE PVRSRV_ERROR CacheOpTimelineExec(CACHEOP_WORK_ITEM *psCacheOpWorkItem) -{ - PVRSRV_ERROR eError; - - if (psCacheOpWorkItem->iTimeline == PVRSRV_NO_TIMELINE) - { - return PVRSRV_OK; - } - CACHEOP_PVR_ASSERT(psCacheOpWorkItem->sSWTimelineObj.pvTlObj); - - eError = SyncSWTimelineAdvanceKM(psCacheOpWorkItem->psDevNode, - &psCacheOpWorkItem->sSWTimelineObj); - (void) SyncSWTimelineReleaseKM(&psCacheOpWorkItem->sSWTimelineObj); - - return eError; -} - -static INLINE void CacheOpExecRangeBased(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_CACHE_OP uiCacheOp, - IMG_BYTE *pbCpuVirtAddr, - IMG_CPU_PHYADDR sCpuPhyAddr, - IMG_DEVMEM_OFFSET_T uiPgAlignedOffset, - IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset, - IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset) -{ - IMG_BYTE *pbCpuVirtAddrEnd; - IMG_BYTE *pbCpuVirtAddrStart; - IMG_CPU_PHYADDR sCpuPhyAddrEnd; - IMG_CPU_PHYADDR sCpuPhyAddrStart; - IMG_DEVMEM_SIZE_T uiRelFlushSize; - IMG_DEVMEM_OFFSET_T uiRelFlushOffset; - IMG_DEVMEM_SIZE_T uiNextPgAlignedOffset; - - /* These quantities allows us to perform cache operations - at cache-line granularity thereby ensuring we do not - perform more than is necessary */ - CACHEOP_PVR_ASSERT(uiPgAlignedOffset < uiCLAlignedEndOffset); - uiRelFlushSize = (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize; - uiRelFlushOffset = 0; - - if (uiCLAlignedStartOffset > uiPgAlignedOffset) - { - /* Zero unless initially starting at an in-page offset */ - uiRelFlushOffset = uiCLAlignedStartOffset - uiPgAlignedOffset; - uiRelFlushSize -= uiRelFlushOffset; - } - - /* uiRelFlushSize is gsCwq.uiPageSize unless current outstanding CacheOp - size is smaller. The 1st case handles in-page CacheOp range and - the 2nd case handles multiple-page CacheOp range with a last - CacheOp size that is less than gsCwq.uiPageSize */ - uiNextPgAlignedOffset = uiPgAlignedOffset + (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize; - if (uiNextPgAlignedOffset < uiPgAlignedOffset) - { - /* uiNextPgAlignedOffset is greater than uiCLAlignedEndOffset - by implication of this wrap-round; this only happens when - uiPgAlignedOffset is the last page aligned offset */ - uiRelFlushSize = uiRelFlushOffset ? - uiCLAlignedEndOffset - uiCLAlignedStartOffset : - uiCLAlignedEndOffset - uiPgAlignedOffset; - } - else - { - if (uiNextPgAlignedOffset > uiCLAlignedEndOffset) - { - uiRelFlushSize = uiRelFlushOffset ? - uiCLAlignedEndOffset - uiCLAlignedStartOffset : - uiCLAlignedEndOffset - uiPgAlignedOffset; - } - } - - /* More efficient to request cache maintenance operation for full - relative range as opposed to multiple cache-aligned ranges */ - sCpuPhyAddrStart.uiAddr = sCpuPhyAddr.uiAddr + uiRelFlushOffset; - sCpuPhyAddrEnd.uiAddr = sCpuPhyAddrStart.uiAddr + uiRelFlushSize; - if (pbCpuVirtAddr) - { - pbCpuVirtAddrStart = pbCpuVirtAddr + uiRelFlushOffset; - pbCpuVirtAddrEnd = pbCpuVirtAddrStart + uiRelFlushSize; - } - else - { - /* Some OS/Env layer support functions expect NULL(s) */ - pbCpuVirtAddrStart = NULL; - pbCpuVirtAddrEnd = NULL; - } - - /* Perform requested CacheOp on the CPU data cache for successive cache - line worth of bytes up to page or in-page cache-line boundary */ - switch (uiCacheOp) - { - case PVRSRV_CACHE_OP_CLEAN: - OSCPUCacheCleanRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd, - sCpuPhyAddrStart, sCpuPhyAddrEnd); - break; - case PVRSRV_CACHE_OP_INVALIDATE: - OSCPUCacheInvalidateRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd, - sCpuPhyAddrStart, sCpuPhyAddrEnd); - break; - case PVRSRV_CACHE_OP_FLUSH: - OSCPUCacheFlushRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd, - sCpuPhyAddrStart, sCpuPhyAddrEnd); - break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d", - __func__, uiCacheOp)); - break; - } - -} - -static INLINE void CacheOpExecRangeBasedVA(PVRSRV_DEVICE_NODE *psDevNode, - IMG_CPU_VIRTADDR pvAddress, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_CACHE_OP uiCacheOp) -{ - IMG_CPU_PHYADDR sCpuPhyAddrUnused = - { IMG_CAST_TO_CPUPHYADDR_UINT(0xCAFEF00DDEADBEEFULL) }; - IMG_BYTE *pbEnd = (IMG_BYTE*)((uintptr_t)pvAddress + (uintptr_t)uiSize); - IMG_BYTE *pbStart = (IMG_BYTE*)((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiLineSize-1)); - - /* - If the start/end address isn't aligned to cache line size, round it up to the - nearest multiple; this ensures that we flush all the cache lines affected by - unaligned start/end addresses. - */ - pbEnd = (IMG_BYTE *) PVR_ALIGN((uintptr_t)pbEnd, (uintptr_t)gsCwq.uiLineSize); - switch (uiCacheOp) - { - case PVRSRV_CACHE_OP_CLEAN: - OSCPUCacheCleanRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused); - break; - case PVRSRV_CACHE_OP_INVALIDATE: - OSCPUCacheInvalidateRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused); - break; - case PVRSRV_CACHE_OP_FLUSH: - OSCPUCacheFlushRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused); - break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d", - __func__, uiCacheOp)); - break; - } - -} - -static INLINE PVRSRV_ERROR CacheOpValidateUMVA(PMR *psPMR, - IMG_CPU_VIRTADDR pvAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_CACHE_OP uiCacheOp, - void **ppvOutAddress) -{ - PVRSRV_ERROR eError = PVRSRV_OK; -#if defined(__linux__) && !defined(CACHEFLUSH_NO_KMRBF_USING_UMVA) - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; -#endif - void __user *pvAddr; - - IMG_BOOL bReadOnlyInvalidate = - (uiCacheOp == PVRSRV_CACHE_OP_INVALIDATE) && - !PVRSRV_CHECK_CPU_WRITEABLE(PMR_Flags(psPMR)); - - if (!pvAddress || bReadOnlyInvalidate) - { - /* As pvAddress is optional, NULL is expected from UM/KM requests */ - /* Also don't allow invalidates for UMVA of read-only memory */ - pvAddr = NULL; - goto e0; - } - - - -#if !defined(__linux__) || defined(CACHEFLUSH_NO_KMRBF_USING_UMVA) - pvAddr = NULL; -#else - /* Validate VA, assume most basic address limit access_ok() check */ - pvAddr = (void __user *)(uintptr_t)((uintptr_t)pvAddress + uiOffset); - if (!access_ok(pvAddr, uiSize)) - { - pvAddr = NULL; - if (! mm) - { - /* Bad KM request, don't silently ignore */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_CPU_ADDR, e0); - } - } - else if (mm) - { - mmap_read_lock(mm); - vma = find_vma(mm, (unsigned long)(uintptr_t)pvAddr); - - if (!vma || - vma->vm_start > (unsigned long)(uintptr_t)pvAddr || - vma->vm_end < (unsigned long)(uintptr_t)pvAddr + uiSize || - vma->vm_private_data != psPMR) - { - /* - * Request range is not fully mapped or is not matching the PMR - * Ignore request's VA. - */ - pvAddr = NULL; - } - mmap_read_unlock(mm); - } -#endif - -e0: - *ppvOutAddress = (IMG_CPU_VIRTADDR __force) pvAddr; - return eError; -} - -static PVRSRV_ERROR CacheOpPMRExec (PMR *psPMR, - IMG_CPU_VIRTADDR pvAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_CACHE_OP uiCacheOp, - IMG_BOOL bIsRequestValidated) - -{ - IMG_HANDLE hPrivOut = NULL; - IMG_BOOL bPMRIsSparse; - IMG_UINT32 ui32PageIndex; - IMG_UINT32 ui32NumOfPages; - size_t uiOutSize; /* Effectively unused */ - PVRSRV_DEVICE_NODE *psDevNode; - IMG_DEVMEM_SIZE_T uiPgAlignedSize; - IMG_DEVMEM_OFFSET_T uiPgAlignedOffset; - IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset; - IMG_DEVMEM_OFFSET_T uiPgAlignedEndOffset; - IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset; - IMG_DEVMEM_OFFSET_T uiPgAlignedStartOffset; - IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_CPU_PHYADDR asCpuPhyAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_CPU_PHYADDR *psCpuPhyAddr = asCpuPhyAddr; - IMG_BOOL bIsPMRInfoValid = IMG_FALSE; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BYTE *pbCpuVirtAddr = NULL; - IMG_BOOL *pbValid = abValid; - - if (uiCacheOp == PVRSRV_CACHE_OP_NONE || uiCacheOp == PVRSRV_CACHE_OP_TIMELINE) - { - return PVRSRV_OK; - } - - if (! bIsRequestValidated) - { - IMG_DEVMEM_SIZE_T uiLPhysicalSize; - - /* Need to validate parameters before proceeding */ - eError = PMR_PhysicalSize(psPMR, &uiLPhysicalSize); - PVR_LOG_RETURN_IF_ERROR(eError, "uiLPhysicalSize"); - - PVR_LOG_RETURN_IF_FALSE(((uiOffset+uiSize) <= uiLPhysicalSize), CACHEOP_DEVMEM_OOR_ERROR_STRING, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE); - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_LOG_RETURN_IF_ERROR(eError, "PMRLockSysPhysAddresses"); - } - - /* Fast track the request if a CPU VA is provided and CPU ISA supports VA only maintenance */ - eError = CacheOpValidateUMVA(psPMR, pvAddress, uiOffset, uiSize, uiCacheOp, (void**)&pbCpuVirtAddr); - if (eError == PVRSRV_OK) - { - pvAddress = pbCpuVirtAddr; - - if (pvAddress && gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - CacheOpExecRangeBasedVA(PMR_DeviceNode(psPMR), pvAddress, uiSize, uiCacheOp); - - if (!bIsRequestValidated) - { - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses"); - } -#if defined(CACHEOP_DEBUG) - gsCwq.ui32ServerOpUsedUMVA += 1; -#endif - return PVRSRV_OK; - } - else if (pvAddress) - { - /* Round down the incoming VA (if any) down to the nearest page aligned VA */ - pvAddress = (void*)((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiPageSize-1)); -#if defined(CACHEOP_DEBUG) - gsCwq.ui32ServerOpUsedUMVA += 1; -#endif - } - } - else - { - /* - * This validation pathway has been added to accommodate any/all requests that might - * cause the kernel to Oops; essentially, KM requests should prevalidate cache maint. - * parameters but if this fails then we would rather fail gracefully than cause the - * kernel to Oops so instead we log the fact that an invalid KM virtual address was - * supplied and what action was taken to mitigate against kernel Oops(ing) if any. - */ - CACHEOP_PVR_ASSERT(pbCpuVirtAddr == NULL); - - if (gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_PHYSICAL) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Invalid vaddress 0x%p in CPU d-cache maint. op, using paddress", - __func__, - pvAddress)); - - /* We can still proceed as kernel/cpu uses CPU PA for d-cache maintenance */ - pvAddress = NULL; - } - else - { - /* - * The approach here is to attempt a reacquisition of the PMR kernel VA and see if - * said VA corresponds to the parameter VA, if so fail requested cache maint. op. - * cause this indicates some kind of internal, memory and/or meta-data corruption - * else we reissue the request using this (re)acquired alias PMR kernel VA. - */ - if (PMR_IsSparse(psPMR)) - { - eError = PMRAcquireSparseKernelMappingData(psPMR, - 0, - gsCwq.uiPageSize, - (void **)&pbCpuVirtAddr, - &uiOutSize, - &hPrivOut); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireSparseKernelMappingData", e0); - } - else - { - eError = PMRAcquireKernelMappingData(psPMR, - 0, - gsCwq.uiPageSize, - (void **)&pbCpuVirtAddr, - &uiOutSize, - &hPrivOut); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", e0); - } - - /* Here, we only compare these CPU virtual addresses at granularity of the OS page size */ - if ((uintptr_t)pbCpuVirtAddr == ((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiPageSize-1))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid vaddress 0x%p in CPU d-cache maint. op, no alt. so failing request", - __func__, - pvAddress)); - - eError = PMRReleaseKernelMappingData(psPMR, hPrivOut); - PVR_LOG_GOTO_WITH_ERROR("PMRReleaseKernelMappingData", eError, PVRSRV_ERROR_INVALID_CPU_ADDR, e0); - } - else if (gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Bad vaddress 0x%p in CPU d-cache maint. op, using reacquired vaddress 0x%p", - __func__, - pvAddress, - pbCpuVirtAddr)); - - /* Note that this might still fail if there is kernel memory/meta-data corruption; - there is not much we can do here but at the least we will be informed of this - before the kernel Oops(ing) */ - CacheOpExecRangeBasedVA(PMR_DeviceNode(psPMR), pbCpuVirtAddr, uiSize, uiCacheOp); - - eError = PMRReleaseKernelMappingData(psPMR, hPrivOut); - PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData"); - - eError = PVRSRV_OK; - goto e0; - } - else - { - /* At this junction, we have exhausted every possible work-around possible but we do - know that VA reacquisition returned another/alias page-aligned VA; so with this - future expectation of PMRAcquireKernelMappingData(), we proceed */ - PVR_DPF((PVR_DBG_WARNING, - "%s: Bad vaddress %p in CPU d-cache maint. op, will use reacquired vaddress", - __func__, - pvAddress)); - - eError = PMRReleaseKernelMappingData(psPMR, hPrivOut); - PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData"); - - /* NULL this to force per-page reacquisition down-stream */ - pvAddress = NULL; - } - } - } - - /* NULL clobbered var., OK to proceed */ - pbCpuVirtAddr = NULL; - eError = PVRSRV_OK; - - /* Need this for kernel mapping */ - bPMRIsSparse = PMR_IsSparse(psPMR); - psDevNode = PMR_DeviceNode(psPMR); - - /* Round the incoming offset down to the nearest cache-line / page aligned-address */ - uiCLAlignedEndOffset = uiOffset + uiSize; - uiCLAlignedEndOffset = PVR_ALIGN(uiCLAlignedEndOffset, (IMG_DEVMEM_SIZE_T)gsCwq.uiLineSize); - uiCLAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)gsCwq.uiLineSize-1)); - - uiPgAlignedEndOffset = uiCLAlignedEndOffset; - uiPgAlignedEndOffset = PVR_ALIGN(uiPgAlignedEndOffset, (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize); - uiPgAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)gsCwq.uiPageSize-1)); - uiPgAlignedSize = uiPgAlignedEndOffset - uiPgAlignedStartOffset; - -#if defined(CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING) - /* For internal debug if cache-line optimised - flushing is suspected of causing data corruption */ - uiCLAlignedStartOffset = uiPgAlignedStartOffset; - uiCLAlignedEndOffset = uiPgAlignedEndOffset; -#endif - - /* Type of allocation backing the PMR data */ - ui32NumOfPages = uiPgAlignedSize >> gsCwq.uiPageShift; - if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - /* The pbValid array is allocated first as it is needed in - both physical/virtual cache maintenance methods */ - pbValid = OSAllocZMem(ui32NumOfPages * sizeof(IMG_BOOL)); - if (! pbValid) - { - pbValid = abValid; - } - else if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - psCpuPhyAddr = OSAllocZMem(ui32NumOfPages * sizeof(IMG_CPU_PHYADDR)); - if (! psCpuPhyAddr) - { - psCpuPhyAddr = asCpuPhyAddr; - OSFreeMem(pbValid); - pbValid = abValid; - } - } - } - - /* We always retrieve PMR data in bulk, up-front if number of pages is within - PMR_MAX_TRANSLATION_STACK_ALLOC limits else we check to ensure that a - dynamic buffer has been allocated to satisfy requests outside limits */ - if (ui32NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC || pbValid != abValid) - { - if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - /* Look-up PMR CpuPhyAddr once, if possible */ - eError = PMR_CpuPhysAddr(psPMR, - gsCwq.uiPageShift, - ui32NumOfPages, - uiPgAlignedStartOffset, - psCpuPhyAddr, - pbValid); - if (eError == PVRSRV_OK) - { - bIsPMRInfoValid = IMG_TRUE; - } - } - else - { - /* Look-up PMR per-page validity once, if possible */ - eError = PMR_IsOffsetValid(psPMR, - gsCwq.uiPageShift, - ui32NumOfPages, - uiPgAlignedStartOffset, - pbValid); - bIsPMRInfoValid = (eError == PVRSRV_OK) ? IMG_TRUE : IMG_FALSE; - } - } - - /* For each (possibly non-contiguous) PMR page(s), carry out the requested cache maint. op. */ - for (uiPgAlignedOffset = uiPgAlignedStartOffset, ui32PageIndex = 0; - uiPgAlignedOffset < uiPgAlignedEndOffset; - uiPgAlignedOffset += (IMG_DEVMEM_OFFSET_T) gsCwq.uiPageSize, ui32PageIndex += 1) - { - - if (! bIsPMRInfoValid) - { - /* Never cross page boundary without looking up corresponding PMR page physical - address and/or page validity if these were not looked-up, in bulk, up-front */ - ui32PageIndex = 0; - if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - eError = PMR_CpuPhysAddr(psPMR, - gsCwq.uiPageShift, - 1, - uiPgAlignedOffset, - psCpuPhyAddr, - pbValid); - PVR_LOG_GOTO_IF_ERROR(eError, "PMR_CpuPhysAddr", e0); - } - else - { - eError = PMR_IsOffsetValid(psPMR, - gsCwq.uiPageShift, - 1, - uiPgAlignedOffset, - pbValid); - PVR_LOG_GOTO_IF_ERROR(eError, "PMR_IsOffsetValid", e0); - } - } - - /* Skip invalid PMR pages (i.e. sparse) */ - if (pbValid[ui32PageIndex] == IMG_FALSE) - { - CACHEOP_PVR_ASSERT(bPMRIsSparse); - continue; - } - - if (pvAddress) - { - /* The caller has supplied either a KM/UM CpuVA, so use it unconditionally */ - pbCpuVirtAddr = - (void *)(uintptr_t)((uintptr_t)pvAddress + (uintptr_t)(uiPgAlignedOffset-uiPgAlignedStartOffset)); - } - /* Skip CpuVA acquire if CacheOp can be maintained entirely using CpuPA */ - else if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_PHYSICAL) - { - if (bPMRIsSparse) - { - eError = - PMRAcquireSparseKernelMappingData(psPMR, - uiPgAlignedOffset, - gsCwq.uiPageSize, - (void **)&pbCpuVirtAddr, - &uiOutSize, - &hPrivOut); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireSparseKernelMappingData", e0); - } - else - { - eError = - PMRAcquireKernelMappingData(psPMR, - uiPgAlignedOffset, - gsCwq.uiPageSize, - (void **)&pbCpuVirtAddr, - &uiOutSize, - &hPrivOut); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", e0); - } - } - - /* Issue actual cache maintenance for PMR */ - CacheOpExecRangeBased(psDevNode, - uiCacheOp, - pbCpuVirtAddr, - (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL) ? - psCpuPhyAddr[ui32PageIndex] : psCpuPhyAddr[0], - uiPgAlignedOffset, - uiCLAlignedStartOffset, - uiCLAlignedEndOffset); - - if (! pvAddress) - { - /* The caller has not supplied either a KM/UM CpuVA, release mapping */ - if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_PHYSICAL) - { - eError = PMRReleaseKernelMappingData(psPMR, hPrivOut); - PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData"); - } - } - } - -e0: - if (psCpuPhyAddr != asCpuPhyAddr) - { - OSFreeMem(psCpuPhyAddr); - } - - if (pbValid != abValid) - { - OSFreeMem(pbValid); - } - - if (! bIsRequestValidated) - { - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses"); - } - - return eError; -} - -static PVRSRV_ERROR CacheOpBatchExecTimeline(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE iTimeline) -{ - PVRSRV_ERROR eError; - CACHEOP_WORK_ITEM sCacheOpWorkItem = {NULL}; - - eError = CacheOpTimelineBind(psDevNode, &sCacheOpWorkItem, iTimeline); - PVR_LOG_RETURN_IF_ERROR(eError, "CacheOpTimelineBind"); - - eError = CacheOpTimelineExec(&sCacheOpWorkItem); - PVR_LOG_IF_ERROR(eError, "CacheOpTimelineExec"); - - return eError; -} - -static PVRSRV_ERROR CacheOpBatchExecRangeBased(PVRSRV_DEVICE_NODE *psDevNode, - PMR **ppsPMR, - IMG_CPU_VIRTADDR *pvAddress, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_DEVMEM_SIZE_T *puiSize, - PVRSRV_CACHE_OP *puiCacheOp, - IMG_UINT32 ui32NumCacheOps, - PVRSRV_TIMELINE uiTimeline) -{ - IMG_UINT32 ui32Idx; - IMG_BOOL bBatchHasTimeline; - PVRSRV_ERROR eError = PVRSRV_OK; - -#if defined(CACHEOP_DEBUG) - CACHEOP_WORK_ITEM sCacheOpWorkItem = {0}; - sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM(); -#endif - - /* Check if batch has an associated timeline update */ - bBatchHasTimeline = puiCacheOp[ui32NumCacheOps-1] & PVRSRV_CACHE_OP_TIMELINE; - puiCacheOp[ui32NumCacheOps-1] &= ~(PVRSRV_CACHE_OP_TIMELINE); - - for (ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++) - { - /* Fail UM request, don't silently ignore */ - PVR_GOTO_IF_INVALID_PARAM(puiSize[ui32Idx], eError, e0); - -#if defined(CACHEOP_DEBUG) - sCacheOpWorkItem.ui64StartTime = OSClockus64(); -#endif - - eError = CacheOpPMRExec(ppsPMR[ui32Idx], - pvAddress[ui32Idx], - puiOffset[ui32Idx], - puiSize[ui32Idx], - puiCacheOp[ui32Idx], - IMG_FALSE); - PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpExecPMR", e0); - -#if defined(CACHEOP_DEBUG) - sCacheOpWorkItem.ui64EndTime = OSClockus64(); - - sCacheOpWorkItem.psDevNode = psDevNode; - sCacheOpWorkItem.psPMR = ppsPMR[ui32Idx]; - sCacheOpWorkItem.uiSize = puiSize[ui32Idx]; - sCacheOpWorkItem.uiOffset = puiOffset[ui32Idx]; - sCacheOpWorkItem.uiCacheOp = puiCacheOp[ui32Idx]; - CacheOpStatsExecLogWrite(&sCacheOpWorkItem); - - gsCwq.ui32ServerOps += 1; -#endif - } - -e0: - if (bBatchHasTimeline) - { - eError = CacheOpBatchExecTimeline(psDevNode, uiTimeline); - } - - return eError; -} - - -PVRSRV_ERROR CacheOpExec (PPVRSRV_DEVICE_NODE psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd, - PVRSRV_CACHE_OP uiCacheOp) -{ -#if defined(CACHEOP_DEBUG) - IMG_UINT64 ui64StartTime = OSClockus64(); -#endif - - switch (uiCacheOp) - { - case PVRSRV_CACHE_OP_CLEAN: - OSCPUCacheCleanRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd); - break; - case PVRSRV_CACHE_OP_INVALIDATE: - OSCPUCacheInvalidateRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd); - break; - case PVRSRV_CACHE_OP_FLUSH: - OSCPUCacheFlushRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd); - break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d", - __func__, uiCacheOp)); - break; - } - -#if defined(CACHEOP_DEBUG) - if (CacheOpConfigSupports(CACHEOP_CONFIG_KLOG)) - { - CACHEOP_WORK_ITEM sCacheOpWorkItem = {0}; - - gsCwq.ui32ServerOps += 1; - - sCacheOpWorkItem.uiOffset = 0; - sCacheOpWorkItem.bKMReq = IMG_TRUE; - sCacheOpWorkItem.uiCacheOp = uiCacheOp; - /* Use information page PMR for logging KM request */ - sCacheOpWorkItem.psPMR = gsCwq.psInfoPagePMR; - sCacheOpWorkItem.psDevNode = psDevNode; - sCacheOpWorkItem.ui64StartTime = ui64StartTime; - sCacheOpWorkItem.ui64EndTime = OSClockus64(); - sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM(); - sCacheOpWorkItem.uiSize = (sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr); - - CacheOpStatsExecLogWrite(&sCacheOpWorkItem); - } -#endif - - return PVRSRV_OK; -} - -PVRSRV_ERROR CacheOpValExec(PMR *psPMR, - IMG_UINT64 uiAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_CACHE_OP uiCacheOp) -{ - PVRSRV_ERROR eError; - IMG_CPU_VIRTADDR pvAddress = (IMG_CPU_VIRTADDR)(uintptr_t)uiAddress; -#if defined(CACHEOP_DEBUG) - CACHEOP_WORK_ITEM sCacheOpWorkItem = {0}; - - sCacheOpWorkItem.ui64StartTime = OSClockus64(); -#endif - - eError = CacheOpPMRExec(psPMR, - pvAddress, - uiOffset, - uiSize, - uiCacheOp, - IMG_FALSE); - PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpPMRExec", e0); - -#if defined(CACHEOP_DEBUG) - sCacheOpWorkItem.ui64EndTime = OSClockus64(); - - sCacheOpWorkItem.psDevNode = PMR_DeviceNode(psPMR); - sCacheOpWorkItem.psPMR = psPMR; - sCacheOpWorkItem.uiSize = uiSize; - sCacheOpWorkItem.uiOffset = uiOffset; - sCacheOpWorkItem.uiCacheOp = uiCacheOp; - sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM(); - CacheOpStatsExecLogWrite(&sCacheOpWorkItem); - - gsCwq.ui32ServerOps += 1; -#endif - -e0: - return eError; -} - -PVRSRV_ERROR CacheOpQueue (CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32NumCacheOps, - PMR **ppsPMR, - IMG_UINT64 *puiAddress, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_DEVMEM_SIZE_T *puiSize, - PVRSRV_CACHE_OP *puiCacheOp, - IMG_UINT32 ui32OpTimeline) -{ - PVRSRV_ERROR eError; - PVRSRV_TIMELINE uiTimeline = (PVRSRV_TIMELINE)ui32OpTimeline; - IMG_CPU_VIRTADDR *pvAddress = (IMG_CPU_VIRTADDR*)(uintptr_t)puiAddress; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (!gsCwq.bInit) - { - PVR_LOG(("CacheOp framework not initialised, failing request")); - return PVRSRV_ERROR_NOT_INITIALISED; - } - else if (! ui32NumCacheOps) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - /* Ensure any single timeline CacheOp request is processed immediately */ - else if (ui32NumCacheOps == 1 && puiCacheOp[0] == PVRSRV_CACHE_OP_TIMELINE) - { - eError = CacheOpBatchExecTimeline(psDevNode, uiTimeline); - } - /* This is the default entry for all client requests */ - else - { - if (!(gsCwq.eConfig & (CACHEOP_CONFIG_LAST-1))) - { - /* default the configuration before execution */ - CacheOpConfigUpdate(CACHEOP_CONFIG_DEFAULT); - } - - eError = - CacheOpBatchExecRangeBased(psDevNode, - ppsPMR, - pvAddress, - puiOffset, - puiSize, - puiCacheOp, - ui32NumCacheOps, - uiTimeline); - } - - return eError; -} - -PVRSRV_ERROR CacheOpLog (PMR *psPMR, - IMG_UINT64 puiAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT64 ui64StartTime, - IMG_UINT64 ui64EndTime, - PVRSRV_CACHE_OP uiCacheOp) -{ -#if defined(CACHEOP_DEBUG) - CACHEOP_WORK_ITEM sCacheOpWorkItem = {0}; - PVR_UNREFERENCED_PARAMETER(puiAddress); - - sCacheOpWorkItem.psDevNode = PMR_DeviceNode(psPMR); - sCacheOpWorkItem.psPMR = psPMR; - sCacheOpWorkItem.uiSize = uiSize; - sCacheOpWorkItem.uiOffset = uiOffset; - sCacheOpWorkItem.uiCacheOp = uiCacheOp; - sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM(); - - sCacheOpWorkItem.ui64StartTime = ui64StartTime; - sCacheOpWorkItem.ui64EndTime = ui64EndTime; - - gsCwq.ui32ClientOps += 1; - - CacheOpStatsExecLogWrite(&sCacheOpWorkItem); -#else - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiCacheOp); - PVR_UNREFERENCED_PARAMETER(puiAddress); - PVR_UNREFERENCED_PARAMETER(ui64StartTime); - PVR_UNREFERENCED_PARAMETER(ui64EndTime); -#endif - return PVRSRV_OK; -} - -PVRSRV_ERROR CacheOpInit2 (void) -{ - PVRSRV_ERROR eError; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - /* Apphint read/write is not concurrent, so lock protects against this */ - eError = OSLockCreate((POS_LOCK*)&gsCwq.hConfigLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0); - - -#if defined(CACHEFLUSH_ISA_SUPPORTS_UM_FLUSH) - gsCwq.bSupportsUMFlush = IMG_TRUE; -#else - gsCwq.bSupportsUMFlush = IMG_FALSE; -#endif - - gsCwq.pui32InfoPage = psPVRSRVData->pui32InfoPage; - gsCwq.psInfoPagePMR = psPVRSRVData->psInfoPagePMR; - - /* Normally, platforms should use their default configurations, put exceptions here */ -#if defined(__i386__) || defined(__x86_64__) -#if !defined(TC_MEMORY_CONFIG) - CacheOpConfigUpdate(CACHEOP_CONFIG_URBF | CACHEOP_CONFIG_KDF); -#else - CacheOpConfigUpdate(CACHEOP_CONFIG_KDF); -#endif -#else /* defined(__x86__) */ - CacheOpConfigUpdate(CACHEOP_CONFIG_DEFAULT); -#endif - - /* Initialise the remaining occupants of the CacheOp information page */ - gsCwq.pui32InfoPage[CACHEOP_INFO_PGSIZE] = (IMG_UINT32)gsCwq.uiPageSize; - gsCwq.pui32InfoPage[CACHEOP_INFO_LINESIZE] = (IMG_UINT32)gsCwq.uiLineSize; - - /* Set before spawning thread */ - gsCwq.bInit = IMG_TRUE; - - { - DI_ITERATOR_CB sIterator = {.pfnShow = CacheOpConfigRead}; - /* Writing the unsigned integer binary encoding of CACHEOP_CONFIG - into this file cycles through avail. configuration(s) */ - eError = DICreateEntry("cacheop_config", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &gsCwq.psConfigTune); - PVR_LOG_GOTO_IF_FALSE(gsCwq.psConfigTune, "DICreateEntry", e0); - } - - /* Register the CacheOp framework (re)configuration handlers */ - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_CacheOpConfig, - CacheOpConfigQuery, - CacheOpConfigSet, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) APPHINT_ID_CacheOpConfig); - - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_CacheOpUMKMThresholdSize, - CacheOpConfigQuery, - CacheOpConfigSet, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) APPHINT_ID_CacheOpUMKMThresholdSize); - - return PVRSRV_OK; -e0: - CacheOpDeInit2(); - return eError; -} - -void CacheOpDeInit2 (void) -{ - gsCwq.bInit = IMG_FALSE; - - if (gsCwq.hConfigLock) - { - OSLockDestroy(gsCwq.hConfigLock); - gsCwq.hConfigLock = NULL; - } - - if (gsCwq.psConfigTune) - { - DIDestroyEntry(gsCwq.psConfigTune); - gsCwq.psConfigTune = NULL; - } - - gsCwq.pui32InfoPage = NULL; - gsCwq.psInfoPagePMR = NULL; -} - -PVRSRV_ERROR CacheOpInit (void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - gsCwq.uiPageSize = OSGetPageSize(); - gsCwq.uiPageShift = OSGetPageShift(); - gsCwq.uiLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE); - gsCwq.uiLineShift = ExactLog2(gsCwq.uiLineSize); - PVR_LOG_RETURN_IF_FALSE((gsCwq.uiLineSize && gsCwq.uiPageSize && gsCwq.uiPageShift), "", PVRSRV_ERROR_INIT_FAILURE); - gsCwq.uiCacheOpAddrType = OSCPUCacheOpAddressType(); - -#if defined(CACHEOP_DEBUG) - /* debugfs file read-out is not concurrent, so lock protects against this */ - eError = OSLockCreate((POS_LOCK*)&gsCwq.hStatsExecLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0); - - gsCwq.i32StatsExecWriteIdx = 0; - OSCachedMemSet(gsCwq.asStatsExecuted, 0, sizeof(gsCwq.asStatsExecuted)); - - { - DI_ITERATOR_CB sIterator = {.pfnShow = CacheOpStatsExecLogRead}; - /* File captures the most recent subset of CacheOp(s) executed */ - eError = DICreateEntry("cacheop_history", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &gsCwq.psDIEntry); - PVR_LOG_GOTO_IF_ERROR(eError, "DICreateEntry", e0); - } -e0: -#endif - return eError; -} - -void CacheOpDeInit (void) -{ -#if defined(CACHEOP_DEBUG) - if (gsCwq.hStatsExecLock) - { - OSLockDestroy(gsCwq.hStatsExecLock); - gsCwq.hStatsExecLock = NULL; - } - - if (gsCwq.psDIEntry) - { - DIDestroyEntry(gsCwq.psDIEntry); - gsCwq.psDIEntry = NULL; - } -#endif -} diff --git a/drivers/gpu/drm/img-rogue/1.17/cache_km.h b/drivers/gpu/drm/img-rogue/1.17/cache_km.h deleted file mode 100644 index 282ff5bc5f0f8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/cache_km.h +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************/ /*! -@File cache_km.h -@Title CPU cache management header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CACHE_KM_H -#define CACHE_KM_H - -#if defined(__linux__) -#include -#else -#define KERNEL_VERSION -#endif - -#include "pvrsrv_error.h" -#include "os_cpu_cache.h" -#include "img_types.h" -#include "cache_ops.h" -#include "device.h" -#include "pmr.h" - -typedef IMG_UINT32 PVRSRV_CACHE_OP_ADDR_TYPE; /*!< Represents CPU address type required for CPU d-cache maintenance */ -#define PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL 0x1 /*!< Operation requires CPU virtual address only */ -#define PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL 0x2 /*!< Operation requires CPU physical address only */ -#define PVRSRV_CACHE_OP_ADDR_TYPE_BOTH 0x3 /*!< Operation requires both CPU virtual & physical addresses */ - -#include "connection_server.h" - -/* - * CacheOpInit() & CacheOpDeInit() - * - * This must be called to initialise the KM cache maintenance framework. - * This is called early during the driver/module (un)loading phase. - */ -PVRSRV_ERROR CacheOpInit(void); -void CacheOpDeInit(void); - -/* - * CacheOpInit2() & CacheOpDeInit2() - * - * This must be called to initialise the UM cache maintenance framework. - * This is called when the driver is loaded/unloaded from the kernel. - */ -PVRSRV_ERROR CacheOpInit2(void); -void CacheOpDeInit2(void); - -/* - * CacheOpExec() - * - * This is the primary CPU data-cache maintenance interface and it is - * always guaranteed to be synchronous; the arguments supplied must be - * pre-validated for performance reasons else the d-cache maintenance - * operation might cause the underlying OS kernel to fault. - */ -PVRSRV_ERROR CacheOpExec(PPVRSRV_DEVICE_NODE psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd, - PVRSRV_CACHE_OP uiCacheOp); - -/* - * CacheOpValExec() - * - * Same as CacheOpExec(), except arguments are _Validated_ before being - * presented to the underlying OS kernel for CPU data-cache maintenance. - * The uiAddress is the start CPU virtual address for the to-be d-cache - * maintained PMR, it can be NULL in which case a remap will be performed - * internally, if required for cache maintenance. This is primarily used - * as the services client bridge call handler for synchronous user-mode - * cache maintenance requests. - */ -PVRSRV_ERROR CacheOpValExec(PMR *psPMR, - IMG_UINT64 uiAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_CACHE_OP uiCacheOp); - -/* - * CacheOpQueue() - * - * This is the secondary cache maintenance interface and it is not - * guaranteed to be synchronous in that requests could be deferred - * and executed asynchronously. This interface is primarily meant - * as services client bridge call handler. Both uiInfoPgGFSeqNum - * and ui32[Current,Next]FenceSeqNum implements an internal client - * server queueing protocol so making use of this interface outside - * of services client is not recommended and should not be done. - */ -PVRSRV_ERROR CacheOpQueue(CONNECTION_DATA *psConnection, - PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32OpCount, - PMR **ppsPMR, - IMG_UINT64 *puiAddress, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_DEVMEM_SIZE_T *puiSize, - PVRSRV_CACHE_OP *puiCacheOp, - IMG_UINT32 ui32OpTimeline); - -/* - * CacheOpLog() - * - * This is used for logging client cache maintenance operations that - * was executed in user-space. - */ -PVRSRV_ERROR CacheOpLog(PMR *psPMR, - IMG_UINT64 uiAddress, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT64 ui64StartTime, - IMG_UINT64 ui64EndTime, - PVRSRV_CACHE_OP uiCacheOp); - -#endif /* CACHE_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/cache_ops.h b/drivers/gpu/drm/img-rogue/1.17/cache_ops.h deleted file mode 100644 index a1d714519d59f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/cache_ops.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services cache management header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines for cache management which are visible internally - and externally -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CACHE_OPS_H -#define CACHE_OPS_H -#include "img_types.h" -/*! -* @Defgroup CPUCacheAPIs -* @{ -*/ -#define CACHE_BATCH_MAX (8U) -#define MAX_DMA_OPS (34) -typedef IMG_UINT32 PVRSRV_CACHE_OP; /*!< Type represents cache maintenance operation */ -#define PVRSRV_CACHE_OP_NONE 0x0U /*!< No operation */ -#define PVRSRV_CACHE_OP_CLEAN 0x1U /*!< Flush w/o invalidate */ -#define PVRSRV_CACHE_OP_INVALIDATE 0x2U /*!< Invalidate w/o flush */ -#define PVRSRV_CACHE_OP_FLUSH 0x3U /*!< Flush w/ invalidate */ -/*! @} End of Defgroup CPUCacheAPIs */ - -#endif /* CACHE_OPS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_cache_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_cache_bridge.h deleted file mode 100644 index 1dec13fccce75..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_cache_bridge.h +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for cache -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for cache -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_CACHE_BRIDGE_H -#define CLIENT_CACHE_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_cache_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpQueue(IMG_HANDLE hBridge, - IMG_UINT32 ui32NumCacheOps, - IMG_HANDLE * phPMR, - IMG_UINT64 * pui64Address, - IMG_DEVMEM_OFFSET_T * puiOffset, - IMG_DEVMEM_SIZE_T * puiSize, - PVRSRV_CACHE_OP * piuCacheOp, - IMG_UINT32 ui32OpTimeline); - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpExec(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_UINT64 ui64Address, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, PVRSRV_CACHE_OP iuCacheOp); - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpLog(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_UINT64 ui64Address, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_INT64 i64StartTime, - IMG_INT64 i64EndTime, PVRSRV_CACHE_OP iuCacheOp); - -#endif /* CLIENT_CACHE_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_cache_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_cache_direct_bridge.c deleted file mode 100644 index 9691bae9352f7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_cache_direct_bridge.c +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for cache -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for cache - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_cache_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "cache_ops.h" - -#include "cache_km.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpQueue(IMG_HANDLE hBridge, - IMG_UINT32 ui32NumCacheOps, - IMG_HANDLE * phPMR, - IMG_UINT64 * pui64Address, - IMG_DEVMEM_OFFSET_T * puiOffset, - IMG_DEVMEM_SIZE_T * puiSize, - PVRSRV_CACHE_OP * piuCacheOp, - IMG_UINT32 ui32OpTimeline) -{ - PVRSRV_ERROR eError; - PMR **psPMRInt; - - psPMRInt = (PMR **) phPMR; - - eError = - CacheOpQueue(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32NumCacheOps, - psPMRInt, pui64Address, puiOffset, puiSize, piuCacheOp, ui32OpTimeline); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpExec(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_UINT64 ui64Address, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, PVRSRV_CACHE_OP iuCacheOp) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = CacheOpValExec(psPMRInt, ui64Address, uiOffset, uiSize, iuCacheOp); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpLog(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_UINT64 ui64Address, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_INT64 i64StartTime, - IMG_INT64 i64EndTime, PVRSRV_CACHE_OP iuCacheOp) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - CacheOpLog(psPMRInt, - ui64Address, uiOffset, uiSize, i64StartTime, i64EndTime, iuCacheOp); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_bridge.h deleted file mode 100644 index bfa6bfb9c0379..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_bridge.h +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for devicememhistory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for devicememhistory -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_DEVICEMEMHISTORY_BRIDGE_H -#define CLIENT_DEVICEMEMHISTORY_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_devicememhistory_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMap(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut); - -#endif /* CLIENT_DEVICEMEMHISTORY_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_direct_bridge.c deleted file mode 100644 index a593a7e2cc7a4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_devicememhistory_direct_bridge.c +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for devicememhistory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for devicememhistory - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_devicememhistory_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "img_types.h" -#include "img_defs.h" -#include "devicemem_typedefs.h" - -#include "pmr.h" -#include "devicemem_history_server.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMap(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - DevicememHistoryMapKM(psPMRInt, - uiOffset, - sDevVAddr, - uiSize, - puiText, - ui32Log2PageSize, ui32AllocationIndex, pui32AllocationIndexOut); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - DevicememHistoryUnmapKM(psPMRInt, - uiOffset, - sDevVAddr, - uiSize, - puiText, - ui32Log2PageSize, ui32AllocationIndex, pui32AllocationIndexOut); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut) -{ - PVRSRV_ERROR eError; - - eError = - DevicememHistoryMapVRangeKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - sBaseDevVAddr, - ui32ui32StartPage, - ui32NumPages, - uiAllocSize, - puiText, - ui32Log2PageSize, - ui32AllocationIndex, pui32AllocationIndexOut); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut) -{ - PVRSRV_ERROR eError; - - eError = - DevicememHistoryUnmapVRangeKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - sBaseDevVAddr, - ui32ui32StartPage, - ui32NumPages, - uiAllocSize, - puiText, - ui32Log2PageSize, - ui32AllocationIndex, pui32AllocationIndexOut); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR * puiText, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 * pui32AllocationIndexOut) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - DevicememHistorySparseChangeKM(psPMRInt, - uiOffset, - sDevVAddr, - uiSize, - puiText, - ui32Log2PageSize, - ui32AllocPageCount, - pui32AllocPageIndices, - ui32FreePageCount, - pui32FreePageIndices, - ui32AllocationIndex, pui32AllocationIndexOut); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_bridge.h deleted file mode 100644 index b3514eaba9b82..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_bridge.h +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for htbuffer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for htbuffer -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_HTBUFFER_BRIDGE_H -#define CLIENT_HTBUFFER_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_htbuffer_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeHTBControl(IMG_HANDLE hBridge, - IMG_UINT32 ui32NumGroups, - IMG_UINT32 * pui32GroupEnable, - IMG_UINT32 ui32LogLevel, - IMG_UINT32 ui32EnablePID, - IMG_UINT32 ui32LogMode, IMG_UINT32 ui32OpMode); - -IMG_INTERNAL PVRSRV_ERROR BridgeHTBLog(IMG_HANDLE hBridge, - IMG_UINT32 ui32PID, - IMG_UINT32 ui32TID, - IMG_UINT64 ui64TimeStamp, - IMG_UINT32 ui32SF, - IMG_UINT32 ui32NumArgs, IMG_UINT32 * pui32Args); - -#endif /* CLIENT_HTBUFFER_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_direct_bridge.c deleted file mode 100644 index 9c58331160757..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_htbuffer_direct_bridge.c +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for htbuffer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for htbuffer - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_htbuffer_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "devicemem_typedefs.h" -#include "htbuffer_types.h" - -#include "htbserver.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeHTBControl(IMG_HANDLE hBridge, - IMG_UINT32 ui32NumGroups, - IMG_UINT32 * pui32GroupEnable, - IMG_UINT32 ui32LogLevel, - IMG_UINT32 ui32EnablePID, - IMG_UINT32 ui32LogMode, IMG_UINT32 ui32OpMode) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = - HTBControlKM(ui32NumGroups, - pui32GroupEnable, ui32LogLevel, ui32EnablePID, ui32LogMode, ui32OpMode); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeHTBLog(IMG_HANDLE hBridge, - IMG_UINT32 ui32PID, - IMG_UINT32 ui32TID, - IMG_UINT64 ui64TimeStamp, - IMG_UINT32 ui32SF, - IMG_UINT32 ui32NumArgs, IMG_UINT32 * pui32Args) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = HTBLogKM(ui32PID, ui32TID, ui64TimeStamp, ui32SF, ui32NumArgs, pui32Args); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_mm_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_mm_bridge.h deleted file mode 100644 index 02a2d5d5f92c2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_mm_bridge.h +++ /dev/null @@ -1,313 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for mm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for mm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_MM_BRIDGE_H -#define CLIENT_MM_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_mm_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePMRExportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_HANDLE * phPMRExport, - IMG_UINT64 * pui64Size, - IMG_UINT32 * pui32Log2Contig, - IMG_UINT64 * pui64Password); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnexportPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMRExport); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRGetUID(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, IMG_UINT64 * pui64UID); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRMakeLocalImportHandle(IMG_HANDLE hBridge, - IMG_HANDLE hBuffer, IMG_HANDLE * phExtMem); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnmakeLocalImportHandle(IMG_HANDLE hBridge, IMG_HANDLE hExtMem); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRImportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMRExport, - IMG_UINT64 ui64uiPassword, - IMG_UINT64 ui64uiSize, - IMG_UINT32 ui32uiLog2Contig, IMG_HANDLE * phPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRLocalImportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hExtHandle, - IMG_HANDLE * phPMR, - IMG_DEVMEM_SIZE_T * puiSize, - IMG_DEVMEM_ALIGN_T * puiAlign); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefUnlockPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 * pui32MappingTable, - IMG_UINT32 ui32Log2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32AnnotationLength, - const IMG_CHAR * puiAnnotation, - IMG_PID ui32PID, - IMG_HANDLE * phPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T * puiOutFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedLockedPMR(IMG_HANDLE hBridge, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 * pui32MappingTable, - IMG_UINT32 ui32Log2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32AnnotationLength, - const IMG_CHAR * puiAnnotation, - IMG_PID ui32PID, - IMG_HANDLE * phPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T * puiOutFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPin(IMG_HANDLE hBridge, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpin(IMG_HANDLE hBridge, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPinValidate(IMG_HANDLE hBridge, - IMG_HANDLE hMapping, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpinInvalidate(IMG_HANDLE hBridge, - IMG_HANDLE hMapping, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge, - IMG_BOOL bbKernelMemoryCtx, - IMG_HANDLE * phDevMemServerContext, - IMG_HANDLE * phPrivData, - IMG_UINT32 * pui32CPUCacheLineSize); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerContext); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sHeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_UINT32 ui32Log2DataPageSize, - IMG_HANDLE * phDevmemHeapPtr); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge, IMG_HANDLE hDevmemHeap); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - IMG_HANDLE * phMapping); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge, IMG_HANDLE hMapping); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_HANDLE * phReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem(IMG_HANDLE hBridge, - IMG_HANDLE hSrvDevMemHeap, - IMG_HANDLE hPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32SparseFlags, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_UINT64 ui64CPUVAddr); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysicalPgOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddr); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_UINT32 ui32PageCount); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sAddress); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemFlushDevSLCRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemInvalidateFBSCTable(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT64 ui64FBSCEntries); - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge, - IMG_UINT32 * pui32NumHeapConfigs); - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapCount(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 * pui32NumHeaps); - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 ui32HeapConfigNameBufSz, - IMG_CHAR * puiHeapConfigName); - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 ui32HeapIndex, - IMG_UINT32 ui32HeapNameBufSz, - IMG_CHAR * puiHeapNameOut, - IMG_DEV_VIRTADDR * psDevVAddrBase, - IMG_DEVMEM_SIZE_T * puiHeapLength, - IMG_DEVMEM_SIZE_T * puiReservedRegionLength, - IMG_UINT32 * pui32Log2DataPageSizeOut, - IMG_UINT32 * pui32Log2ImportAlignmentOut); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge, - IMG_HANDLE hDevm, - IMG_UINT32 ui32PID, IMG_BOOL bRegister); - -IMG_INTERNAL PVRSRV_ERROR BridgeGetMaxPhysHeapCount(IMG_HANDLE hBridge, - IMG_UINT32 * pui32PhysHeapCount); - -IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfo(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP * peaPhysHeapID, - PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats); - -IMG_INTERNAL PVRSRV_ERROR BridgeGetDefaultPhysicalHeap(IMG_HANDLE hBridge, - PVRSRV_PHYS_HEAP * peHeap); - -IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsage(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemGetFaultAddress(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR * psFaultAddress); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVUpdateOOMStats(IMG_HANDLE hBridge, - IMG_UINT32 ui32ui32StatType, IMG_PID ui32pid); - -IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfoPkd(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP * peaPhysHeapID, - PHYS_HEAP_MEM_STATS_PKD * - psapPhysHeapMemStats); - -IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsagePkd(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS_PKD * - psapPhysHeapMemStats); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntReserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_HANDLE * phReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntUnreserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntMapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysPageOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32VirtPageOffset); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntUnmapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_UINT32 ui32VirtPageOffset, - IMG_UINT32 ui32PageCount); - -IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem2(IMG_HANDLE hBridge, - IMG_HANDLE hSrvDevMemHeap, - IMG_HANDLE hPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32SparseFlags, - IMG_HANDLE hReservation, IMG_UINT64 ui64CPUVAddr); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange2(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE * phReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange2(IMG_HANDLE hBridge, - IMG_HANDLE hReservation); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR2(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_HANDLE hReservation, IMG_HANDLE hPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR2(IMG_HANDLE hBridge, IMG_HANDLE hReservation); - -#endif /* CLIENT_MM_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_mm_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_mm_direct_bridge.c deleted file mode 100644 index 30ca919ee1e4c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_mm_direct_bridge.c +++ /dev/null @@ -1,978 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for mm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for mm - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_mm_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "pvrsrv_memallocflags.h" -#include "pvrsrv_memalloc_physheap.h" -#include "devicemem_typedefs.h" - -#include "pvrsrv_memalloc_physheap.h" -#include "devicemem.h" -#include "devicemem_server.h" -#include "pmr.h" -#include "devicemem_heapcfg.h" -#include "physmem.h" -#include "devicemem_utils.h" -#include "process_stats.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePMRExportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_HANDLE * phPMRExport, - IMG_UINT64 * pui64Size, - IMG_UINT32 * pui32Log2Contig, - IMG_UINT64 * pui64Password) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PMR_EXPORT *psPMRExportInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRExportPMR(psPMRInt, &psPMRExportInt, pui64Size, pui32Log2Contig, pui64Password); - - *phPMRExport = psPMRExportInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnexportPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMRExport) -{ - PVRSRV_ERROR eError; - PMR_EXPORT *psPMRExportInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRExportInt = (PMR_EXPORT *) hPMRExport; - - eError = PMRUnexportPMR(psPMRExportInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRGetUID(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, IMG_UINT64 * pui64UID) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRGetUID(psPMRInt, pui64UID); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRMakeLocalImportHandle(IMG_HANDLE hBridge, - IMG_HANDLE hBuffer, IMG_HANDLE * phExtMem) -{ - PVRSRV_ERROR eError; - PMR *psBufferInt; - PMR *psExtMemInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psBufferInt = (PMR *) hBuffer; - - eError = PMRMakeLocalImportHandle(psBufferInt, &psExtMemInt); - - *phExtMem = psExtMemInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnmakeLocalImportHandle(IMG_HANDLE hBridge, IMG_HANDLE hExtMem) -{ - PVRSRV_ERROR eError; - PMR *psExtMemInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psExtMemInt = (PMR *) hExtMem; - - eError = PMRUnmakeLocalImportHandle(psExtMemInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRImportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMRExport, - IMG_UINT64 ui64uiPassword, - IMG_UINT64 ui64uiSize, - IMG_UINT32 ui32uiLog2Contig, IMG_HANDLE * phPMR) -{ - PVRSRV_ERROR eError; - PMR_EXPORT *psPMRExportInt; - PMR *psPMRInt = NULL; - - psPMRExportInt = (PMR_EXPORT *) hPMRExport; - - eError = - PhysmemImportPMR(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - psPMRExportInt, - ui64uiPassword, ui64uiSize, ui32uiLog2Contig, &psPMRInt); - - *phPMR = psPMRInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRLocalImportPMR(IMG_HANDLE hBridge, - IMG_HANDLE hExtHandle, - IMG_HANDLE * phPMR, - IMG_DEVMEM_SIZE_T * puiSize, - IMG_DEVMEM_ALIGN_T * puiAlign) -{ - PVRSRV_ERROR eError; - PMR *psExtHandleInt; - PMR *psPMRInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psExtHandleInt = (PMR *) hExtHandle; - - eError = PMRLocalImportPMR(psExtHandleInt, &psPMRInt, puiSize, puiAlign); - - *phPMR = psPMRInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRUnrefPMR(psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefUnlockPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRUnrefUnlockPMR(psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 * pui32MappingTable, - IMG_UINT32 ui32Log2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32AnnotationLength, - const IMG_CHAR * puiAnnotation, - IMG_PID ui32PID, - IMG_HANDLE * phPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T * puiOutFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRPtrInt = NULL; - - eError = - PhysmemNewRamBackedPMR_direct(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - ui32Log2PageSize, - uiFlags, - ui32AnnotationLength, - puiAnnotation, - ui32PID, &psPMRPtrInt, ui32PDumpFlags, puiOutFlags); - - *phPMRPtr = psPMRPtrInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedLockedPMR(IMG_HANDLE hBridge, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 * pui32MappingTable, - IMG_UINT32 ui32Log2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32AnnotationLength, - const IMG_CHAR * puiAnnotation, - IMG_PID ui32PID, - IMG_HANDLE * phPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T * puiOutFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRPtrInt = NULL; - - eError = - PhysmemNewRamBackedLockedPMR(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - ui32Log2PageSize, - uiFlags, - ui32AnnotationLength, - puiAnnotation, - ui32PID, &psPMRPtrInt, ui32PDumpFlags, puiOutFlags); - - *phPMRPtr = psPMRPtrInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPin(IMG_HANDLE hBridge, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = DevmemIntPin(psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpin(IMG_HANDLE hBridge, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = DevmemIntUnpin(psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPinValidate(IMG_HANDLE hBridge, - IMG_HANDLE hMapping, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - DEVMEMINT_MAPPING *psMappingInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psMappingInt = (DEVMEMINT_MAPPING *) hMapping; - psPMRInt = (PMR *) hPMR; - - eError = DevmemIntPinValidate(psMappingInt, psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpinInvalidate(IMG_HANDLE hBridge, - IMG_HANDLE hMapping, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - DEVMEMINT_MAPPING *psMappingInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psMappingInt = (DEVMEMINT_MAPPING *) hMapping; - psPMRInt = (PMR *) hPMR; - - eError = DevmemIntUnpinInvalidate(psMappingInt, psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge, - IMG_BOOL bbKernelMemoryCtx, - IMG_HANDLE * phDevMemServerContext, - IMG_HANDLE * phPrivData, - IMG_UINT32 * pui32CPUCacheLineSize) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevMemServerContextInt = NULL; - IMG_HANDLE hPrivDataInt = NULL; - - eError = - DevmemIntCtxCreate(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - bbKernelMemoryCtx, - &psDevMemServerContextInt, &hPrivDataInt, pui32CPUCacheLineSize); - - *phDevMemServerContext = psDevMemServerContextInt; - *phPrivData = hPrivDataInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerContext) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemServerContextInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerContextInt = (DEVMEMINT_CTX *) hDevmemServerContext; - - eError = DevmemIntCtxDestroy(psDevmemServerContextInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sHeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_UINT32 ui32Log2DataPageSize, - IMG_HANDLE * phDevmemHeapPtr) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - DEVMEMINT_HEAP *psDevmemHeapPtrInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = - DevmemIntHeapCreate(psDevmemCtxInt, - sHeapBaseAddr, - uiHeapLength, ui32Log2DataPageSize, &psDevmemHeapPtrInt); - - *phDevmemHeapPtr = psDevmemHeapPtrInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge, IMG_HANDLE hDevmemHeap) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemHeapInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemHeapInt = (DEVMEMINT_HEAP *) hDevmemHeap; - - eError = DevmemIntHeapDestroy(psDevmemHeapInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - IMG_HANDLE * phMapping) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemServerHeapInt; - DEVMEMINT_RESERVATION *psReservationInt; - PMR *psPMRInt; - DEVMEMINT_MAPPING *psMappingInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap; - psReservationInt = (DEVMEMINT_RESERVATION *) hReservation; - psPMRInt = (PMR *) hPMR; - - eError = - DevmemIntMapPMR(psDevmemServerHeapInt, - psReservationInt, psPMRInt, uiMapFlags, &psMappingInt); - - *phMapping = psMappingInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge, IMG_HANDLE hMapping) -{ - PVRSRV_ERROR eError; - DEVMEMINT_MAPPING *psMappingInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psMappingInt = (DEVMEMINT_MAPPING *) hMapping; - - eError = DevmemIntUnmapPMR(psMappingInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_HANDLE * phReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemServerHeapInt; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap; - - eError = - DevmemIntReserveRange(psDevmemServerHeapInt, sAddress, uiLength, &psReservationInt); - - *phReservation = psReservationInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge, IMG_HANDLE hReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMINT_RESERVATION *) hReservation; - - eError = DevmemIntUnreserveRange(psReservationInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem(IMG_HANDLE hBridge, - IMG_HANDLE hSrvDevMemHeap, - IMG_HANDLE hPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32SparseFlags, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddr, IMG_UINT64 ui64CPUVAddr) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psSrvDevMemHeapInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSrvDevMemHeapInt = (DEVMEMINT_HEAP *) hSrvDevMemHeap; - psPMRInt = (PMR *) hPMR; - - eError = - DevmemIntChangeSparse(psSrvDevMemHeapInt, - psPMRInt, - ui32AllocPageCount, - pui32AllocPageIndices, - ui32FreePageCount, - pui32FreePageIndices, - ui32SparseFlags, uiFlags, sDevVAddr, ui64CPUVAddr); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysicalPgOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddr) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION *psReservationInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMINT_RESERVATION *) hReservation; - psPMRInt = (PMR *) hPMR; - - eError = - DevmemIntMapPages(psReservationInt, - psPMRInt, ui32PageCount, ui32PhysicalPgOffset, uiFlags, sDevVAddr); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_UINT32 ui32PageCount) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMINT_RESERVATION *) hReservation; - - eError = DevmemIntUnmapPages(psReservationInt, sDevVAddr, ui32PageCount); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sAddress) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = - DevmemIntIsVDevAddrValid(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - psDevmemCtxInt, sAddress); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemFlushDevSLCRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate) -{ -#if defined(RGX_SRV_SLC_RANGEBASED_CFI_SUPPORTED) - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = DevmemIntFlushDevSLCRange(psDevmemCtxInt, sAddress, uiSize, bInvalidate); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hDevmemCtx); - PVR_UNREFERENCED_PARAMETER(sAddress); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(bInvalidate); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemInvalidateFBSCTable(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT64 ui64FBSCEntries) -{ -#if defined(RGX_FEATURE_FBCDC) - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = DevmemIntInvalidateFBSCTable(psDevmemCtxInt, ui64FBSCEntries); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hDevmemCtx); - PVR_UNREFERENCED_PARAMETER(ui64FBSCEntries); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge, - IMG_UINT32 * pui32NumHeapConfigs) -{ - PVRSRV_ERROR eError; - - eError = - HeapCfgHeapConfigCount(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - pui32NumHeapConfigs); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapCount(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 * pui32NumHeaps) -{ - PVRSRV_ERROR eError; - - eError = - HeapCfgHeapCount(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32HeapConfigIndex, pui32NumHeaps); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 ui32HeapConfigNameBufSz, - IMG_CHAR * puiHeapConfigName) -{ - PVRSRV_ERROR eError; - - eError = - HeapCfgHeapConfigName(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32HeapConfigIndex, ui32HeapConfigNameBufSz, puiHeapConfigName); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge, - IMG_UINT32 ui32HeapConfigIndex, - IMG_UINT32 ui32HeapIndex, - IMG_UINT32 ui32HeapNameBufSz, - IMG_CHAR * puiHeapNameOut, - IMG_DEV_VIRTADDR * psDevVAddrBase, - IMG_DEVMEM_SIZE_T * puiHeapLength, - IMG_DEVMEM_SIZE_T * puiReservedRegionLength, - IMG_UINT32 * pui32Log2DataPageSizeOut, - IMG_UINT32 * pui32Log2ImportAlignmentOut) -{ - PVRSRV_ERROR eError; - - eError = - HeapCfgHeapDetails(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32HeapConfigIndex, - ui32HeapIndex, - ui32HeapNameBufSz, - puiHeapNameOut, - psDevVAddrBase, - puiHeapLength, - puiReservedRegionLength, - pui32Log2DataPageSizeOut, pui32Log2ImportAlignmentOut); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge, - IMG_HANDLE hDevm, - IMG_UINT32 ui32PID, IMG_BOOL bRegister) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmInt = (DEVMEMINT_CTX *) hDevm; - - eError = DevmemIntRegisterPFNotifyKM(psDevmInt, ui32PID, bRegister); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeGetMaxPhysHeapCount(IMG_HANDLE hBridge, - IMG_UINT32 * pui32PhysHeapCount) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVGetMaxPhysHeapCountKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - pui32PhysHeapCount); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfo(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP * peaPhysHeapID, - PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPhysHeapGetMemInfoKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PhysHeapCount, peaPhysHeapID, pasapPhysHeapMemStats); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeGetDefaultPhysicalHeap(IMG_HANDLE hBridge, - PVRSRV_PHYS_HEAP * peHeap) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVGetDefaultPhysicalHeapKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), peHeap); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsage(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVGetHeapPhysMemUsageKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PhysHeapCount, pasapPhysHeapMemStats); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemGetFaultAddress(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_DEV_VIRTADDR * psFaultAddress) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = - DevmemIntGetFaultAddress(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - psDevmemCtxInt, psFaultAddress); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVUpdateOOMStats(IMG_HANDLE hBridge, - IMG_UINT32 ui32ui32StatType, IMG_PID ui32pid) -{ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = PVRSRVServerUpdateOOMStats(ui32ui32StatType, ui32pid); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(ui32ui32StatType); - PVR_UNREFERENCED_PARAMETER(ui32pid); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfoPkd(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP * peaPhysHeapID, - PHYS_HEAP_MEM_STATS_PKD * - psapPhysHeapMemStats) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPhysHeapGetMemInfoPkdKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PhysHeapCount, peaPhysHeapID, psapPhysHeapMemStats); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsagePkd(IMG_HANDLE hBridge, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS_PKD * - psapPhysHeapMemStats) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVGetHeapPhysMemUsagePkdKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PhysHeapCount, psapPhysHeapMemStats); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntReserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_HANDLE * phReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemServerHeapInt; - DEVMEMXINT_RESERVATION *psReservationInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap; - - eError = - DevmemXIntReserveRange(psDevmemServerHeapInt, sAddress, uiLength, &psReservationInt); - - *phReservation = psReservationInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntUnreserveRange(IMG_HANDLE hBridge, - IMG_HANDLE hReservation) -{ - PVRSRV_ERROR eError; - DEVMEMXINT_RESERVATION *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMXINT_RESERVATION *) hReservation; - - eError = DevmemXIntUnreserveRange(psReservationInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntMapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_HANDLE hPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysPageOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32VirtPageOffset) -{ - PVRSRV_ERROR eError; - DEVMEMXINT_RESERVATION *psReservationInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMXINT_RESERVATION *) hReservation; - psPMRInt = (PMR *) hPMR; - - eError = - DevmemXIntMapPages(psReservationInt, - psPMRInt, - ui32PageCount, ui32PhysPageOffset, uiFlags, ui32VirtPageOffset); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemXIntUnmapPages(IMG_HANDLE hBridge, - IMG_HANDLE hReservation, - IMG_UINT32 ui32VirtPageOffset, - IMG_UINT32 ui32PageCount) -{ - PVRSRV_ERROR eError; - DEVMEMXINT_RESERVATION *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMXINT_RESERVATION *) hReservation; - - eError = DevmemXIntUnmapPages(psReservationInt, ui32VirtPageOffset, ui32PageCount); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem2(IMG_HANDLE hBridge, - IMG_HANDLE hSrvDevMemHeap, - IMG_HANDLE hPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 * pui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 * pui32FreePageIndices, - IMG_UINT32 ui32SparseFlags, - IMG_HANDLE hReservation, IMG_UINT64 ui64CPUVAddr) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psSrvDevMemHeapInt; - PMR *psPMRInt; - DEVMEMINT_RESERVATION2 *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSrvDevMemHeapInt = (DEVMEMINT_HEAP *) hSrvDevMemHeap; - psPMRInt = (PMR *) hPMR; - psReservationInt = (DEVMEMINT_RESERVATION2 *) hReservation; - - eError = - DevmemIntChangeSparse2(psSrvDevMemHeapInt, - psPMRInt, - ui32AllocPageCount, - pui32AllocPageIndices, - ui32FreePageCount, - pui32FreePageIndices, - ui32SparseFlags, psReservationInt, ui64CPUVAddr); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange2(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiLength, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE * phReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemServerHeapInt; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap; - - eError = - DevmemIntReserveRange2(psDevmemServerHeapInt, - sAddress, uiLength, uiFlags, &psReservationInt); - - *phReservation = psReservationInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange2(IMG_HANDLE hBridge, - IMG_HANDLE hReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION2 *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMINT_RESERVATION2 *) hReservation; - - eError = DevmemIntUnreserveRange2(psReservationInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR2(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerHeap, - IMG_HANDLE hReservation, IMG_HANDLE hPMR) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemServerHeapInt; - DEVMEMINT_RESERVATION2 *psReservationInt; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap; - psReservationInt = (DEVMEMINT_RESERVATION2 *) hReservation; - psPMRInt = (PMR *) hPMR; - - eError = DevmemIntMapPMR2(psDevmemServerHeapInt, psReservationInt, psPMRInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR2(IMG_HANDLE hBridge, IMG_HANDLE hReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION2 *psReservationInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psReservationInt = (DEVMEMINT_RESERVATION2 *) hReservation; - - eError = DevmemIntUnmapPMR2(psReservationInt); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdump_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_pdump_bridge.h deleted file mode 100644 index 2bf967bfcea9e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdump_bridge.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for pdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for pdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_PDUMP_BRIDGE_H -#define CLIENT_PDUMP_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_pdump_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpImageDescriptor(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT32 ui32StringSize, - const IMG_CHAR * puiFileName, - IMG_DEV_VIRTADDR sDataDevAddr, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixelFormat, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 * pui32FBCClearColour, - PDUMP_FBC_SWIZZLE eeFBCSwizzle, - IMG_DEV_VIRTADDR sHeaderDevAddr, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpComment(IMG_HANDLE hBridge, - IMG_UINT32 ui32CommentSize, - IMG_CHAR * puiComment, IMG_UINT32 ui32Flags); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpSetFrame(IMG_HANDLE hBridge, IMG_UINT32 ui32Frame); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpDataDescriptor(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT32 ui32StringSize, - const IMG_CHAR * puiFileName, - IMG_DEV_VIRTADDR sDataDevAddr, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags); - -#endif /* CLIENT_PDUMP_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdump_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_pdump_direct_bridge.c deleted file mode 100644 index 7c012dbcf21e4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdump_direct_bridge.c +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for pdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for pdump - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_pdump_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "devicemem_typedefs.h" -#include "pdumpdefs.h" -#include - -#include "devicemem_server.h" -#include "pdump_km.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpImageDescriptor(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT32 ui32StringSize, - const IMG_CHAR * puiFileName, - IMG_DEV_VIRTADDR sDataDevAddr, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixelFormat, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 * pui32FBCClearColour, - PDUMP_FBC_SWIZZLE eeFBCSwizzle, - IMG_DEV_VIRTADDR sHeaderDevAddr, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = - DevmemIntPDumpImageDescriptor(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - psDevmemCtxInt, - ui32StringSize, - puiFileName, - sDataDevAddr, - ui32DataSize, - ui32LogicalWidth, - ui32LogicalHeight, - ui32PhysicalWidth, - ui32PhysicalHeight, - ePixelFormat, - eMemLayout, - eFBCompression, - pui32FBCClearColour, - eeFBCSwizzle, - sHeaderDevAddr, ui32HeaderSize, ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpComment(IMG_HANDLE hBridge, - IMG_UINT32 ui32CommentSize, - IMG_CHAR * puiComment, IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eError; - - eError = - PDumpCommentKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32CommentSize, puiComment, ui32Flags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpSetFrame(IMG_HANDLE hBridge, IMG_UINT32 ui32Frame) -{ - PVRSRV_ERROR eError; - - eError = PDumpSetFrameKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), ui32Frame); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpDataDescriptor(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemCtx, - IMG_UINT32 ui32StringSize, - const IMG_CHAR * puiFileName, - IMG_DEV_VIRTADDR sDataDevAddr, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtxInt; - - psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx; - - eError = - DevmemIntPDumpDataDescriptor(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - psDevmemCtxInt, - ui32StringSize, - puiFileName, - sDataDevAddr, - ui32DataSize, - ui32HeaderType, - ui32ElementType, ui32ElementCount, ui32PDumpFlags); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_bridge.h deleted file mode 100644 index 8bda83aeb2992..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_bridge.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for pdumpctrl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for pdumpctrl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_PDUMPCTRL_BRIDGE_H -#define CLIENT_PDUMPCTRL_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_pdumpctrl_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpGetState(IMG_HANDLE hBridge, IMG_UINT64 * pui64State); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpGetFrame(IMG_HANDLE hBridge, IMG_UINT32 * pui32Frame); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpSetDefaultCaptureParams(IMG_HANDLE hBridge, - IMG_UINT32 ui32Mode, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, - IMG_UINT32 ui32Interval, - IMG_UINT32 ui32MaxParamFileSize); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpIsLastCaptureFrame(IMG_HANDLE hBridge, - IMG_BOOL * pbpbIsLastCaptureFrame); - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpForceCaptureStop(IMG_HANDLE hBridge); - -#endif /* CLIENT_PDUMPCTRL_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_direct_bridge.c deleted file mode 100644 index 7ba92988a462d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdumpctrl_direct_bridge.c +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for pdumpctrl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for pdumpctrl - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_pdumpctrl_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ - -#include "pdump_km.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpGetState(IMG_HANDLE hBridge, IMG_UINT64 * pui64State) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = PDumpGetStateKM(pui64State); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpGetFrame(IMG_HANDLE hBridge, IMG_UINT32 * pui32Frame) -{ - PVRSRV_ERROR eError; - - eError = PDumpGetFrameKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), pui32Frame); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpSetDefaultCaptureParams(IMG_HANDLE hBridge, - IMG_UINT32 ui32Mode, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, - IMG_UINT32 ui32Interval, - IMG_UINT32 ui32MaxParamFileSize) -{ - PVRSRV_ERROR eError; - - eError = - PDumpSetDefaultCaptureParamsKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32Mode, - ui32Start, ui32End, ui32Interval, ui32MaxParamFileSize); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpIsLastCaptureFrame(IMG_HANDLE hBridge, - IMG_BOOL * pbpbIsLastCaptureFrame) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = PDumpIsLastCaptureFrameKM(pbpbIsLastCaptureFrame); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVPDumpForceCaptureStop(IMG_HANDLE hBridge) -{ - PVRSRV_ERROR eError; - - eError = PDumpForceCaptureStopKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge)); - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_bridge.h deleted file mode 100644 index a4368477e2256..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_bridge.h +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for pdumpmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for pdumpmm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_PDUMPMM_BRIDGE_H -#define CLIENT_PDUMPMM_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_pdumpmm_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMem(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32PDumpFlags, IMG_BOOL bbZero); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMemValue32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMemValue64(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpSaveToFile(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32ArraySize, - const IMG_CHAR * puiFileName, - IMG_UINT32 ui32uiFileOffset); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpSymbolicAddr(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32MemspaceNameLen, - IMG_CHAR * puiMemspaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR * puiSymbolicAddr, - IMG_DEVMEM_OFFSET_T * puiNewOffset, - IMG_DEVMEM_OFFSET_T * puiNextSymName); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpPol32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpCheck32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpCBP(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize); - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPDumpSaveToFileVirtual(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerContext, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32ArraySize, - const IMG_CHAR * puiFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PDumpFlags); - -#endif /* CLIENT_PDUMPMM_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_direct_bridge.c deleted file mode 100644 index b1906b385871c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pdumpmm_direct_bridge.c +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for pdumpmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for pdumpmm - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_pdumpmm_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "pdump.h" -#include "pdumpdefs.h" -#include "pvrsrv_memallocflags.h" -#include "devicemem_typedefs.h" - -#include "devicemem_server.h" -#include "pmr.h" -#include "physmem.h" -#include "pdump_physmem.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMem(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32PDumpFlags, IMG_BOOL bbZero) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRPDumpLoadMem(psPMRInt, uiOffset, uiSize, ui32PDumpFlags, bbZero); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMemValue32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRPDumpLoadMemValue32(psPMRInt, uiOffset, ui32Value, ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpLoadMemValue64(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRPDumpLoadMemValue64(psPMRInt, uiOffset, ui64Value, ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpSaveToFile(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32ArraySize, - const IMG_CHAR * puiFileName, - IMG_UINT32 ui32uiFileOffset) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - PMRPDumpSaveToFile(psPMRInt, - uiOffset, uiSize, ui32ArraySize, puiFileName, ui32uiFileOffset); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpSymbolicAddr(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32MemspaceNameLen, - IMG_CHAR * puiMemspaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR * puiSymbolicAddr, - IMG_DEVMEM_OFFSET_T * puiNewOffset, - IMG_DEVMEM_OFFSET_T * puiNextSymName) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - PMR_PDumpSymbolicAddr(psPMRInt, - uiOffset, - ui32MemspaceNameLen, - puiMemspaceName, - ui32SymbolicAddrLen, - puiSymbolicAddr, puiNewOffset, puiNextSymName); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpPol32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRPDumpPol32(psPMRInt, uiOffset, ui32Value, ui32Mask, eOperator, ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpCheck32(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = - PMRPDumpCheck32(psPMRInt, uiOffset, ui32Value, ui32Mask, eOperator, ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePMRPDumpCBP(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVRSRV_ERROR eError; - PMR *psPMRInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRInt = (PMR *) hPMR; - - eError = PMRPDumpCBP(psPMRInt, uiReadOffset, uiWriteOffset, uiPacketSize, uiBufferSize); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPDumpSaveToFileVirtual(IMG_HANDLE hBridge, - IMG_HANDLE hDevmemServerContext, - IMG_DEV_VIRTADDR sAddress, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32ArraySize, - const IMG_CHAR * puiFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemServerContextInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psDevmemServerContextInt = (DEVMEMINT_CTX *) hDevmemServerContext; - - eError = - DevmemIntPDumpSaveToFileVirtual(psDevmemServerContextInt, - sAddress, - uiSize, - ui32ArraySize, - puiFileName, ui32FileOffset, ui32PDumpFlags); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_bridge.h deleted file mode 100644 index 2cfafd5a83e15..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_bridge.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for pvrtl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for pvrtl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_PVRTL_BRIDGE_H -#define CLIENT_PVRTL_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_pvrtl_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeTLOpenStream(IMG_HANDLE hBridge, - const IMG_CHAR * puiName, - IMG_UINT32 ui32Mode, - IMG_HANDLE * phSD, IMG_HANDLE * phTLPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLCloseStream(IMG_HANDLE hBridge, IMG_HANDLE hSD); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLAcquireData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 * pui32ReadOffset, - IMG_UINT32 * pui32ReadLen); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLReleaseData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 ui32ReadOffset, IMG_UINT32 ui32ReadLen); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLDiscoverStreams(IMG_HANDLE hBridge, - const IMG_CHAR * puiNamePattern, - IMG_UINT32 ui32Size, - IMG_CHAR * puiStreams, - IMG_UINT32 * pui32NumFound); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLReserveStream(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 * pui32BufferOffset, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32 * pui32Available); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLCommitStream(IMG_HANDLE hBridge, - IMG_HANDLE hSD, IMG_UINT32 ui32ReqSize); - -IMG_INTERNAL PVRSRV_ERROR BridgeTLWriteData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size, IMG_BYTE * pui8Data); - -#endif /* CLIENT_PVRTL_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_direct_bridge.c deleted file mode 100644 index fa2fbed9595b9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_pvrtl_direct_bridge.c +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for pvrtl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for pvrtl - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_pvrtl_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "devicemem_typedefs.h" -#include "pvrsrv_tlcommon.h" - -#include "tlserver.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeTLOpenStream(IMG_HANDLE hBridge, - const IMG_CHAR * puiName, - IMG_UINT32 ui32Mode, - IMG_HANDLE * phSD, IMG_HANDLE * phTLPMR) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt = NULL; - PMR *psTLPMRInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = TLServerOpenStreamKM(puiName, ui32Mode, &psSDInt, &psTLPMRInt); - - *phSD = psSDInt; - *phTLPMR = psTLPMRInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLCloseStream(IMG_HANDLE hBridge, IMG_HANDLE hSD) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = TLServerCloseStreamKM(psSDInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLAcquireData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 * pui32ReadOffset, - IMG_UINT32 * pui32ReadLen) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = TLServerAcquireDataKM(psSDInt, pui32ReadOffset, pui32ReadLen); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLReleaseData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 ui32ReadOffset, IMG_UINT32 ui32ReadLen) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = TLServerReleaseDataKM(psSDInt, ui32ReadOffset, ui32ReadLen); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLDiscoverStreams(IMG_HANDLE hBridge, - const IMG_CHAR * puiNamePattern, - IMG_UINT32 ui32Size, - IMG_CHAR * puiStreams, IMG_UINT32 * pui32NumFound) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = TLServerDiscoverStreamsKM(puiNamePattern, ui32Size, puiStreams, pui32NumFound); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLReserveStream(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 * pui32BufferOffset, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, IMG_UINT32 * pui32Available) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = - TLServerReserveStreamKM(psSDInt, - pui32BufferOffset, ui32Size, ui32SizeMin, pui32Available); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLCommitStream(IMG_HANDLE hBridge, - IMG_HANDLE hSD, IMG_UINT32 ui32ReqSize) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = TLServerCommitStreamKM(psSDInt, ui32ReqSize); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeTLWriteData(IMG_HANDLE hBridge, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size, IMG_BYTE * pui8Data) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC *psSDInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSDInt = (TL_STREAM_DESC *) hSD; - - eError = TLServerWriteDataKM(psSDInt, ui32Size, pui8Data); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_bridge.h deleted file mode 100644 index ed5a664ef17e3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_bridge.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for rgxpdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for rgxpdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_RGXPDUMP_BRIDGE_H -#define CLIENT_RGXPDUMP_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_rgxpdump_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpTraceBuffer(IMG_HANDLE hBridge, IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpSignatureBuffer(IMG_HANDLE hBridge, IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpComputeCRCSignatureCheck(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpCRCSignatureCheck(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpValCheckPreCommand(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpValCheckPostCommand(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags); - -#endif /* CLIENT_RGXPDUMP_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_direct_bridge.c deleted file mode 100644 index ed34b211c1355..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_rgxpdump_direct_bridge.c +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for rgxpdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for rgxpdump - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_rgxpdump_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "rgx_bridge.h" - -#include "rgxpdump.h" - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpTraceBuffer(IMG_HANDLE hBridge, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpTraceBufferKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpSignatureBuffer(IMG_HANDLE hBridge, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpSignatureBufferKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpComputeCRCSignatureCheck(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags) -{ -#if defined(SUPPORT_VALIDATION) - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpComputeCRCSignatureCheckKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpCRCSignatureCheck(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpCRCSignatureCheckKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpValCheckPreCommand(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpValCheckPreCommandKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgePDumpValCheckPostCommand(IMG_HANDLE hBridge, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVPDumpValCheckPostCommandKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - ui32PDumpFlags); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_ri_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_ri_bridge.h deleted file mode 100644 index b3c42e6f496e4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_ri_bridge.h +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for ri -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for ri -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_RI_BRIDGE_H -#define CLIENT_RI_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_ri_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntry(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge, - IMG_HANDLE hPMRHandle, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR * puiTextB, - IMG_UINT64 ui64Offset, - IMG_UINT64 ui64Size, - IMG_BOOL bIsImport, - IMG_BOOL bIsSuballoc, IMG_HANDLE * phRIHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteProcListEntry(IMG_HANDLE hBridge, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR * puiTextB, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64DevVAddr, - IMG_HANDLE * phRIHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge, - IMG_HANDLE hRIHandle, IMG_DEV_VIRTADDR sAddr); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge, IMG_HANDLE hRIHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpList(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpAll(IMG_HANDLE hBridge); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpProcess(IMG_HANDLE hBridge, IMG_PID ui32Pid); - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntryWithOwner(IMG_HANDLE hBridge, - IMG_HANDLE hPMRHandle, IMG_PID ui32Owner); - -#endif /* CLIENT_RI_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_ri_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_ri_direct_bridge.c deleted file mode 100644 index 2a9934cc4316a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_ri_direct_bridge.c +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for ri -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for ri - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_ri_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "ri_typedefs.h" - -#include "ri_server.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntry(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle) -{ - PVRSRV_ERROR eError; - PMR *psPMRHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRHandleInt = (PMR *) hPMRHandle; - - eError = RIWritePMREntryKM(psPMRHandleInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge, - IMG_HANDLE hPMRHandle, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR * puiTextB, - IMG_UINT64 ui64Offset, - IMG_UINT64 ui64Size, - IMG_BOOL bIsImport, - IMG_BOOL bIsSuballoc, IMG_HANDLE * phRIHandle) -{ - PVRSRV_ERROR eError; - PMR *psPMRHandleInt; - RI_HANDLE psRIHandleInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRHandleInt = (PMR *) hPMRHandle; - - eError = - RIWriteMEMDESCEntryKM(psPMRHandleInt, - ui32TextBSize, - puiTextB, - ui64Offset, ui64Size, bIsImport, bIsSuballoc, &psRIHandleInt); - - *phRIHandle = psRIHandleInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteProcListEntry(IMG_HANDLE hBridge, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR * puiTextB, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64DevVAddr, - IMG_HANDLE * phRIHandle) -{ - PVRSRV_ERROR eError; - RI_HANDLE psRIHandleInt = NULL; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = - RIWriteProcListEntryKM(ui32TextBSize, puiTextB, ui64Size, ui64DevVAddr, &psRIHandleInt); - - *phRIHandle = psRIHandleInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge, - IMG_HANDLE hRIHandle, IMG_DEV_VIRTADDR sAddr) -{ - PVRSRV_ERROR eError; - RI_HANDLE psRIHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psRIHandleInt = (RI_HANDLE) hRIHandle; - - eError = RIUpdateMEMDESCAddrKM(psRIHandleInt, sAddr); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge, IMG_HANDLE hRIHandle) -{ - PVRSRV_ERROR eError; - RI_HANDLE psRIHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psRIHandleInt = (RI_HANDLE) hRIHandle; - - eError = RIDeleteMEMDESCEntryKM(psRIHandleInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpList(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle) -{ - PVRSRV_ERROR eError; - PMR *psPMRHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRHandleInt = (PMR *) hPMRHandle; - - eError = RIDumpListKM(psPMRHandleInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpAll(IMG_HANDLE hBridge) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = RIDumpAllKM(); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpProcess(IMG_HANDLE hBridge, IMG_PID ui32Pid) -{ - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = RIDumpProcessKM(ui32Pid); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntryWithOwner(IMG_HANDLE hBridge, - IMG_HANDLE hPMRHandle, IMG_PID ui32Owner) -{ - PVRSRV_ERROR eError; - PMR *psPMRHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psPMRHandleInt = (PMR *) hPMRHandle; - - eError = RIWritePMREntryWithOwnerKM(psPMRHandleInt, ui32Owner); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_sync_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_sync_bridge.h deleted file mode 100644 index 19f1b0ece5b9f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_sync_bridge.h +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for sync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for sync -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_SYNC_BRIDGE_H -#define CLIENT_SYNC_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_sync_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge, - IMG_HANDLE * phSyncHandle, - IMG_UINT32 * pui32SyncPrimVAddr, - IMG_UINT32 * pui32SyncPrimBlockSize, - IMG_HANDLE * phhSyncPMR); - -IMG_INTERNAL PVRSRV_ERROR BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge, IMG_HANDLE hSyncHandle); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimSet(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Index, IMG_UINT32 ui32Value); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDump(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, IMG_UINT32 ui32Offset); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiPDumpFlags); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncAllocEvent(IMG_HANDLE hBridge, - IMG_BOOL bServerSync, - IMG_UINT32 ui32FWAddr, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR * puiClassName); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncFreeEvent(IMG_HANDLE hBridge, IMG_UINT32 ui32FWAddr); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncCheckpointSignalledPDumpPol(IMG_HANDLE hBridge, - PVRSRV_FENCE hFence); - -#endif /* CLIENT_SYNC_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_sync_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_sync_direct_bridge.c deleted file mode 100644 index d631aea421adb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_sync_direct_bridge.c +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for sync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for sync - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_sync_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ -#include "pdump.h" -#include "pdumpdefs.h" -#include "devicemem_typedefs.h" -#include "pvrsrv_sync_km.h" -#include - -#include "sync.h" -#include "sync_server.h" -#include "pdump.h" -#include "pvrsrv_sync_km.h" -#include "sync_fallback_server.h" -#include "sync_checkpoint.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge, - IMG_HANDLE * phSyncHandle, - IMG_UINT32 * pui32SyncPrimVAddr, - IMG_UINT32 * pui32SyncPrimBlockSize, - IMG_HANDLE * phhSyncPMR) -{ - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - PMR *pshSyncPMRInt = NULL; - - eError = - PVRSRVAllocSyncPrimitiveBlockKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - &psSyncHandleInt, - pui32SyncPrimVAddr, - pui32SyncPrimBlockSize, &pshSyncPMRInt); - - *phSyncHandle = psSyncHandleInt; - *phhSyncPMR = pshSyncPMRInt; - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge, IMG_HANDLE hSyncHandle) -{ - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimSet(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Index, IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = PVRSRVSyncPrimSetKM(psSyncHandleInt, ui32Index, ui32Value); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDump(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, IMG_UINT32 ui32Offset) -{ -#if defined(PDUMP) - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = PVRSRVSyncPrimPDumpKM(psSyncHandleInt, ui32Offset); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hSyncHandle); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -{ -#if defined(PDUMP) - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = PVRSRVSyncPrimPDumpValueKM(psSyncHandleInt, ui32Offset, ui32Value); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hSyncHandle); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiPDumpFlags) -{ -#if defined(PDUMP) - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = - PVRSRVSyncPrimPDumpPolKM(psSyncHandleInt, - ui32Offset, ui32Value, ui32Mask, eOperator, uiPDumpFlags); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hSyncHandle); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge, - IMG_HANDLE hSyncHandle, - IMG_UINT32 ui32Offset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ -#if defined(PDUMP) - PVRSRV_ERROR eError; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle; - - eError = - PVRSRVSyncPrimPDumpCBPKM(psSyncHandleInt, - ui32Offset, uiWriteOffset, uiPacketSize, uiBufferSize); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hSyncHandle); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncAllocEvent(IMG_HANDLE hBridge, - IMG_BOOL bServerSync, - IMG_UINT32 ui32FWAddr, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR * puiClassName) -{ - PVRSRV_ERROR eError; - - eError = - PVRSRVSyncAllocEventKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - bServerSync, ui32FWAddr, ui32ClassNameSize, puiClassName); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncFreeEvent(IMG_HANDLE hBridge, IMG_UINT32 ui32FWAddr) -{ - PVRSRV_ERROR eError; - - eError = PVRSRVSyncFreeEventKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), ui32FWAddr); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncCheckpointSignalledPDumpPol(IMG_HANDLE hBridge, - PVRSRV_FENCE hFence) -{ -#if defined(PDUMP) - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(hBridge); - - eError = PVRSRVSyncCheckpointSignalledPDumpPolKM(hFence); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(hFence); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#endif -} diff --git a/drivers/gpu/drm/img-rogue/1.17/client_synctracking_bridge.h b/drivers/gpu/drm/img-rogue/1.17/client_synctracking_bridge.h deleted file mode 100644 index 544efd9628345..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_synctracking_bridge.h +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* -@File -@Title Client bridge header for synctracking -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exports the client bridge functions for synctracking -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 CLIENT_SYNCTRACKING_BRIDGE_H -#define CLIENT_SYNCTRACKING_BRIDGE_H - -#include "img_defs.h" -#include "pvrsrv_error.h" - -#if defined(PVR_INDIRECT_BRIDGE_CLIENTS) -#include "pvr_bridge_client.h" -#include "pvr_bridge.h" -#endif - -#include "common_synctracking_bridge.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge, IMG_HANDLE hhRecord); - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordAdd(IMG_HANDLE hBridge, - IMG_HANDLE * phhRecord, - IMG_HANDLE hhServerSyncPrimBlock, - IMG_UINT32 ui32ui32FwBlockAddr, - IMG_UINT32 ui32ui32SyncOffset, - IMG_BOOL bbServerSync, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR * puiClassName); - -#endif /* CLIENT_SYNCTRACKING_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/client_synctracking_direct_bridge.c b/drivers/gpu/drm/img-rogue/1.17/client_synctracking_direct_bridge.c deleted file mode 100644 index baeb89a6a0aed..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/client_synctracking_direct_bridge.c +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* -@File -@Title Direct client bridge for synctracking -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the client side of the bridge for synctracking - which is used in calls from Server context. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "client_synctracking_bridge.h" -#include "img_defs.h" -#include "pvr_debug.h" - -/* Module specific includes */ - -#include "sync.h" -#include "sync_server.h" - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge, IMG_HANDLE hhRecord) -{ - PVRSRV_ERROR eError; - SYNC_RECORD_HANDLE pshRecordInt; - PVR_UNREFERENCED_PARAMETER(hBridge); - - pshRecordInt = (SYNC_RECORD_HANDLE) hhRecord; - - eError = PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordAdd(IMG_HANDLE hBridge, - IMG_HANDLE * phhRecord, - IMG_HANDLE hhServerSyncPrimBlock, - IMG_UINT32 ui32ui32FwBlockAddr, - IMG_UINT32 ui32ui32SyncOffset, - IMG_BOOL bbServerSync, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR * puiClassName) -{ - PVRSRV_ERROR eError; - SYNC_RECORD_HANDLE pshRecordInt = NULL; - SYNC_PRIMITIVE_BLOCK *pshServerSyncPrimBlockInt; - - pshServerSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK *) hhServerSyncPrimBlock; - - eError = - PVRSRVSyncRecordAddKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), - &pshRecordInt, - pshServerSyncPrimBlockInt, - ui32ui32FwBlockAddr, - ui32ui32SyncOffset, - bbServerSync, ui32ClassNameSize, puiClassName); - - *phhRecord = pshRecordInt; - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/common_cache_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_cache_bridge.h deleted file mode 100644 index cc848753f7fa5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_cache_bridge.h +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for cache -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for cache -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_CACHE_BRIDGE_H -#define COMMON_CACHE_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "cache_ops.h" - -#define PVRSRV_BRIDGE_CACHE_CMD_FIRST 0 -#define PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE PVRSRV_BRIDGE_CACHE_CMD_FIRST+0 -#define PVRSRV_BRIDGE_CACHE_CACHEOPEXEC PVRSRV_BRIDGE_CACHE_CMD_FIRST+1 -#define PVRSRV_BRIDGE_CACHE_CACHEOPLOG PVRSRV_BRIDGE_CACHE_CMD_FIRST+2 -#define PVRSRV_BRIDGE_CACHE_CMD_LAST (PVRSRV_BRIDGE_CACHE_CMD_FIRST+2) - -/******************************************* - CacheOpQueue - *******************************************/ - -/* Bridge in structure for CacheOpQueue */ -typedef struct PVRSRV_BRIDGE_IN_CACHEOPQUEUE_TAG -{ - PVRSRV_CACHE_OP *piuCacheOp; - IMG_UINT64 *pui64Address; - IMG_DEVMEM_OFFSET_T *puiOffset; - IMG_DEVMEM_SIZE_T *puiSize; - IMG_HANDLE *phPMR; - IMG_UINT32 ui32NumCacheOps; - IMG_UINT32 ui32OpTimeline; -} __packed PVRSRV_BRIDGE_IN_CACHEOPQUEUE; - -/* Bridge out structure for CacheOpQueue */ -typedef struct PVRSRV_BRIDGE_OUT_CACHEOPQUEUE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_CACHEOPQUEUE; - -/******************************************* - CacheOpExec - *******************************************/ - -/* Bridge in structure for CacheOpExec */ -typedef struct PVRSRV_BRIDGE_IN_CACHEOPEXEC_TAG -{ - IMG_UINT64 ui64Address; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - PVRSRV_CACHE_OP iuCacheOp; -} __packed PVRSRV_BRIDGE_IN_CACHEOPEXEC; - -/* Bridge out structure for CacheOpExec */ -typedef struct PVRSRV_BRIDGE_OUT_CACHEOPEXEC_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_CACHEOPEXEC; - -/******************************************* - CacheOpLog - *******************************************/ - -/* Bridge in structure for CacheOpLog */ -typedef struct PVRSRV_BRIDGE_IN_CACHEOPLOG_TAG -{ - IMG_INT64 i64EndTime; - IMG_INT64 i64StartTime; - IMG_UINT64 ui64Address; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - PVRSRV_CACHE_OP iuCacheOp; -} __packed PVRSRV_BRIDGE_IN_CACHEOPLOG; - -/* Bridge out structure for CacheOpLog */ -typedef struct PVRSRV_BRIDGE_OUT_CACHEOPLOG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_CACHEOPLOG; - -#endif /* COMMON_CACHE_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_cmm_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_cmm_bridge.h deleted file mode 100644 index da48de3598be1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_cmm_bridge.h +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for cmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for cmm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_CMM_BRIDGE_H -#define COMMON_CMM_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "devicemem_typedefs.h" - -#define PVRSRV_BRIDGE_CMM_CMD_FIRST 0 -#define PVRSRV_BRIDGE_CMM_DEVMEMINTEXPORTCTX PVRSRV_BRIDGE_CMM_CMD_FIRST+0 -#define PVRSRV_BRIDGE_CMM_DEVMEMINTUNEXPORTCTX PVRSRV_BRIDGE_CMM_CMD_FIRST+1 -#define PVRSRV_BRIDGE_CMM_DEVMEMINTACQUIREREMOTECTX PVRSRV_BRIDGE_CMM_CMD_FIRST+2 -#define PVRSRV_BRIDGE_CMM_CMD_LAST (PVRSRV_BRIDGE_CMM_CMD_FIRST+2) - -/******************************************* - DevmemIntExportCtx - *******************************************/ - -/* Bridge in structure for DevmemIntExportCtx */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX_TAG -{ - IMG_HANDLE hContext; - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX; - -/* Bridge out structure for DevmemIntExportCtx */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX_TAG -{ - IMG_HANDLE hContextExport; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX; - -/******************************************* - DevmemIntUnexportCtx - *******************************************/ - -/* Bridge in structure for DevmemIntUnexportCtx */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX_TAG -{ - IMG_HANDLE hContextExport; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX; - -/* Bridge out structure for DevmemIntUnexportCtx */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX; - -/******************************************* - DevmemIntAcquireRemoteCtx - *******************************************/ - -/* Bridge in structure for DevmemIntAcquireRemoteCtx */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX; - -/* Bridge out structure for DevmemIntAcquireRemoteCtx */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX_TAG -{ - IMG_HANDLE hContext; - IMG_HANDLE hPrivData; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX; - -#endif /* COMMON_CMM_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_devicememhistory_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_devicememhistory_bridge.h deleted file mode 100644 index 800f98dd28363..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_devicememhistory_bridge.h +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for devicememhistory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for devicememhistory -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_DEVICEMEMHISTORY_BRIDGE_H -#define COMMON_DEVICEMEMHISTORY_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "img_types.h" -#include "img_defs.h" -#include "devicemem_typedefs.h" - -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST 0 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+0 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+2 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+3 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+4 -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+4) - -/******************************************* - DevicememHistoryMap - *******************************************/ - -/* Bridge in structure for DevicememHistoryMap */ -typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEVMEM_SIZE_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - const IMG_CHAR *puiText; - IMG_UINT32 ui32AllocationIndex; - IMG_UINT32 ui32Log2PageSize; -} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP; - -/* Bridge out structure for DevicememHistoryMap */ -typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32AllocationIndexOut; -} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP; - -/******************************************* - DevicememHistoryUnmap - *******************************************/ - -/* Bridge in structure for DevicememHistoryUnmap */ -typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEVMEM_SIZE_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - const IMG_CHAR *puiText; - IMG_UINT32 ui32AllocationIndex; - IMG_UINT32 ui32Log2PageSize; -} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP; - -/* Bridge out structure for DevicememHistoryUnmap */ -typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32AllocationIndexOut; -} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP; - -/******************************************* - DevicememHistoryMapVRange - *******************************************/ - -/* Bridge in structure for DevicememHistoryMapVRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE_TAG -{ - IMG_DEV_VIRTADDR sBaseDevVAddr; - IMG_DEVMEM_SIZE_T uiAllocSize; - const IMG_CHAR *puiText; - IMG_UINT32 ui32AllocationIndex; - IMG_UINT32 ui32Log2PageSize; - IMG_UINT32 ui32NumPages; - IMG_UINT32 ui32ui32StartPage; -} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE; - -/* Bridge out structure for DevicememHistoryMapVRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32AllocationIndexOut; -} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE; - -/******************************************* - DevicememHistoryUnmapVRange - *******************************************/ - -/* Bridge in structure for DevicememHistoryUnmapVRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE_TAG -{ - IMG_DEV_VIRTADDR sBaseDevVAddr; - IMG_DEVMEM_SIZE_T uiAllocSize; - const IMG_CHAR *puiText; - IMG_UINT32 ui32AllocationIndex; - IMG_UINT32 ui32Log2PageSize; - IMG_UINT32 ui32NumPages; - IMG_UINT32 ui32ui32StartPage; -} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE; - -/* Bridge out structure for DevicememHistoryUnmapVRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32AllocationIndexOut; -} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE; - -/******************************************* - DevicememHistorySparseChange - *******************************************/ - -/* Bridge in structure for DevicememHistorySparseChange */ -typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEVMEM_SIZE_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - IMG_UINT32 *pui32AllocPageIndices; - IMG_UINT32 *pui32FreePageIndices; - const IMG_CHAR *puiText; - IMG_UINT32 ui32AllocPageCount; - IMG_UINT32 ui32AllocationIndex; - IMG_UINT32 ui32FreePageCount; - IMG_UINT32 ui32Log2PageSize; -} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE; - -/* Bridge out structure for DevicememHistorySparseChange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32AllocationIndexOut; -} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE; - -#endif /* COMMON_DEVICEMEMHISTORY_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_di_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_di_bridge.h deleted file mode 100644 index 8591006140b62..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_di_bridge.h +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for di -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for di -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_DI_BRIDGE_H -#define COMMON_DI_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pvrsrv_tlcommon.h" -#include "pvr_dicommon.h" - -#define PVRSRV_BRIDGE_DI_CMD_FIRST 0 -#define PVRSRV_BRIDGE_DI_DICREATECONTEXT PVRSRV_BRIDGE_DI_CMD_FIRST+0 -#define PVRSRV_BRIDGE_DI_DIDESTROYCONTEXT PVRSRV_BRIDGE_DI_CMD_FIRST+1 -#define PVRSRV_BRIDGE_DI_DIREADENTRY PVRSRV_BRIDGE_DI_CMD_FIRST+2 -#define PVRSRV_BRIDGE_DI_DIWRITEENTRY PVRSRV_BRIDGE_DI_CMD_FIRST+3 -#define PVRSRV_BRIDGE_DI_DILISTALLENTRIES PVRSRV_BRIDGE_DI_CMD_FIRST+4 -#define PVRSRV_BRIDGE_DI_CMD_LAST (PVRSRV_BRIDGE_DI_CMD_FIRST+4) - -/******************************************* - DICreateContext - *******************************************/ - -/* Bridge in structure for DICreateContext */ -typedef struct PVRSRV_BRIDGE_IN_DICREATECONTEXT_TAG -{ - IMG_CHAR *puiStreamName; -} __packed PVRSRV_BRIDGE_IN_DICREATECONTEXT; - -/* Bridge out structure for DICreateContext */ -typedef struct PVRSRV_BRIDGE_OUT_DICREATECONTEXT_TAG -{ - IMG_HANDLE hContext; - IMG_CHAR *puiStreamName; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DICREATECONTEXT; - -/******************************************* - DIDestroyContext - *******************************************/ - -/* Bridge in structure for DIDestroyContext */ -typedef struct PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT_TAG -{ - IMG_HANDLE hContext; -} __packed PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT; - -/* Bridge out structure for DIDestroyContext */ -typedef struct PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT; - -/******************************************* - DIReadEntry - *******************************************/ - -/* Bridge in structure for DIReadEntry */ -typedef struct PVRSRV_BRIDGE_IN_DIREADENTRY_TAG -{ - IMG_UINT64 ui64Offset; - IMG_UINT64 ui64Size; - IMG_HANDLE hContext; - const IMG_CHAR *puiEntryPath; -} __packed PVRSRV_BRIDGE_IN_DIREADENTRY; - -/* Bridge out structure for DIReadEntry */ -typedef struct PVRSRV_BRIDGE_OUT_DIREADENTRY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DIREADENTRY; - -/******************************************* - DIWriteEntry - *******************************************/ - -/* Bridge in structure for DIWriteEntry */ -typedef struct PVRSRV_BRIDGE_IN_DIWRITEENTRY_TAG -{ - IMG_HANDLE hContext; - const IMG_CHAR *puiEntryPath; - const IMG_CHAR *puiValue; - IMG_UINT32 ui32ValueSize; -} __packed PVRSRV_BRIDGE_IN_DIWRITEENTRY; - -/* Bridge out structure for DIWriteEntry */ -typedef struct PVRSRV_BRIDGE_OUT_DIWRITEENTRY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DIWRITEENTRY; - -/******************************************* - DIListAllEntries - *******************************************/ - -/* Bridge in structure for DIListAllEntries */ -typedef struct PVRSRV_BRIDGE_IN_DILISTALLENTRIES_TAG -{ - IMG_HANDLE hContext; -} __packed PVRSRV_BRIDGE_IN_DILISTALLENTRIES; - -/* Bridge out structure for DIListAllEntries */ -typedef struct PVRSRV_BRIDGE_OUT_DILISTALLENTRIES_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DILISTALLENTRIES; - -#endif /* COMMON_DI_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_dmabuf_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_dmabuf_bridge.h deleted file mode 100644 index 7547d9f762979..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_dmabuf_bridge.h +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for dmabuf -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for dmabuf -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_DMABUF_BRIDGE_H -#define COMMON_DMABUF_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pvrsrv_memallocflags.h" - -#define PVRSRV_BRIDGE_DMABUF_CMD_FIRST 0 -#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+0 -#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUFLOCKED PVRSRV_BRIDGE_DMABUF_CMD_FIRST+1 -#define PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+2 -#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+3 -#define PVRSRV_BRIDGE_DMABUF_CMD_LAST (PVRSRV_BRIDGE_DMABUF_CMD_FIRST+3) - -/******************************************* - PhysmemImportDmaBuf - *******************************************/ - -/* Bridge in structure for PhysmemImportDmaBuf */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF_TAG -{ - const IMG_CHAR *puiName; - IMG_INT ifd; - IMG_UINT32 ui32NameSize; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF; - -/* Bridge out structure for PhysmemImportDmaBuf */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF_TAG -{ - IMG_DEVMEM_ALIGN_T uiAlign; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMRPtr; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF; - -/******************************************* - PhysmemImportDmaBufLocked - *******************************************/ - -/* Bridge in structure for PhysmemImportDmaBufLocked */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED_TAG -{ - const IMG_CHAR *puiName; - IMG_INT ifd; - IMG_UINT32 ui32NameSize; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED; - -/* Bridge out structure for PhysmemImportDmaBufLocked */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED_TAG -{ - IMG_DEVMEM_ALIGN_T uiAlign; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMRPtr; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED; - -/******************************************* - PhysmemExportDmaBuf - *******************************************/ - -/* Bridge in structure for PhysmemExportDmaBuf */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF; - -/* Bridge out structure for PhysmemExportDmaBuf */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF_TAG -{ - PVRSRV_ERROR eError; - IMG_INT iFd; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF; - -/******************************************* - PhysmemImportSparseDmaBuf - *******************************************/ - -/* Bridge in structure for PhysmemImportSparseDmaBuf */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF_TAG -{ - IMG_DEVMEM_SIZE_T uiChunkSize; - IMG_UINT32 *pui32MappingTable; - const IMG_CHAR *puiName; - IMG_INT ifd; - IMG_UINT32 ui32NameSize; - IMG_UINT32 ui32NumPhysChunks; - IMG_UINT32 ui32NumVirtChunks; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF; - -/* Bridge out structure for PhysmemImportSparseDmaBuf */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF_TAG -{ - IMG_DEVMEM_ALIGN_T uiAlign; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMRPtr; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF; - -#endif /* COMMON_DMABUF_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_htbuffer_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_htbuffer_bridge.h deleted file mode 100644 index 69a406b253d93..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_htbuffer_bridge.h +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for htbuffer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for htbuffer -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_HTBUFFER_BRIDGE_H -#define COMMON_HTBUFFER_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "devicemem_typedefs.h" -#include "htbuffer_types.h" - -#define PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST 0 -#define PVRSRV_BRIDGE_HTBUFFER_HTBCONTROL PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+0 -#define PVRSRV_BRIDGE_HTBUFFER_HTBLOG PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+1 -#define PVRSRV_BRIDGE_HTBUFFER_CMD_LAST (PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+1) - -/******************************************* - HTBControl - *******************************************/ - -/* Bridge in structure for HTBControl */ -typedef struct PVRSRV_BRIDGE_IN_HTBCONTROL_TAG -{ - IMG_UINT32 *pui32GroupEnable; - IMG_UINT32 ui32EnablePID; - IMG_UINT32 ui32LogLevel; - IMG_UINT32 ui32LogMode; - IMG_UINT32 ui32NumGroups; - IMG_UINT32 ui32OpMode; -} __packed PVRSRV_BRIDGE_IN_HTBCONTROL; - -/* Bridge out structure for HTBControl */ -typedef struct PVRSRV_BRIDGE_OUT_HTBCONTROL_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_HTBCONTROL; - -/******************************************* - HTBLog - *******************************************/ - -/* Bridge in structure for HTBLog */ -typedef struct PVRSRV_BRIDGE_IN_HTBLOG_TAG -{ - IMG_UINT64 ui64TimeStamp; - IMG_UINT32 *pui32Args; - IMG_UINT32 ui32NumArgs; - IMG_UINT32 ui32PID; - IMG_UINT32 ui32SF; - IMG_UINT32 ui32TID; -} __packed PVRSRV_BRIDGE_IN_HTBLOG; - -/* Bridge out structure for HTBLog */ -typedef struct PVRSRV_BRIDGE_OUT_HTBLOG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_HTBLOG; - -#endif /* COMMON_HTBUFFER_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_mm_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_mm_bridge.h deleted file mode 100644 index ac0e316bbf1ab..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_mm_bridge.h +++ /dev/null @@ -1,1056 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for mm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for mm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_MM_BRIDGE_H -#define COMMON_MM_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pvrsrv_memallocflags.h" -#include "pvrsrv_memalloc_physheap.h" -#include "devicemem_typedefs.h" - -#define PVRSRV_BRIDGE_MM_CMD_FIRST 0 -#define PVRSRV_BRIDGE_MM_PMREXPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+0 -#define PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+1 -#define PVRSRV_BRIDGE_MM_PMRGETUID PVRSRV_BRIDGE_MM_CMD_FIRST+2 -#define PVRSRV_BRIDGE_MM_PMRMAKELOCALIMPORTHANDLE PVRSRV_BRIDGE_MM_CMD_FIRST+3 -#define PVRSRV_BRIDGE_MM_PMRUNMAKELOCALIMPORTHANDLE PVRSRV_BRIDGE_MM_CMD_FIRST+4 -#define PVRSRV_BRIDGE_MM_PMRIMPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+5 -#define PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+6 -#define PVRSRV_BRIDGE_MM_PMRUNREFPMR PVRSRV_BRIDGE_MM_CMD_FIRST+7 -#define PVRSRV_BRIDGE_MM_PMRUNREFUNLOCKPMR PVRSRV_BRIDGE_MM_CMD_FIRST+8 -#define PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR PVRSRV_BRIDGE_MM_CMD_FIRST+9 -#define PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDLOCKEDPMR PVRSRV_BRIDGE_MM_CMD_FIRST+10 -#define PVRSRV_BRIDGE_MM_DEVMEMINTPIN PVRSRV_BRIDGE_MM_CMD_FIRST+11 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNPIN PVRSRV_BRIDGE_MM_CMD_FIRST+12 -#define PVRSRV_BRIDGE_MM_DEVMEMINTPINVALIDATE PVRSRV_BRIDGE_MM_CMD_FIRST+13 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNPININVALIDATE PVRSRV_BRIDGE_MM_CMD_FIRST+14 -#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE PVRSRV_BRIDGE_MM_CMD_FIRST+15 -#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY PVRSRV_BRIDGE_MM_CMD_FIRST+16 -#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE PVRSRV_BRIDGE_MM_CMD_FIRST+17 -#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY PVRSRV_BRIDGE_MM_CMD_FIRST+18 -#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR PVRSRV_BRIDGE_MM_CMD_FIRST+19 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR PVRSRV_BRIDGE_MM_CMD_FIRST+20 -#define PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+21 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+22 -#define PVRSRV_BRIDGE_MM_CHANGESPARSEMEM PVRSRV_BRIDGE_MM_CMD_FIRST+23 -#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+24 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+25 -#define PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID PVRSRV_BRIDGE_MM_CMD_FIRST+26 -#define PVRSRV_BRIDGE_MM_DEVMEMFLUSHDEVSLCRANGE PVRSRV_BRIDGE_MM_CMD_FIRST+27 -#define PVRSRV_BRIDGE_MM_DEVMEMINVALIDATEFBSCTABLE PVRSRV_BRIDGE_MM_CMD_FIRST+28 -#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+29 -#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+30 -#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME PVRSRV_BRIDGE_MM_CMD_FIRST+31 -#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS PVRSRV_BRIDGE_MM_CMD_FIRST+32 -#define PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM PVRSRV_BRIDGE_MM_CMD_FIRST+33 -#define PVRSRV_BRIDGE_MM_GETMAXPHYSHEAPCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+34 -#define PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFO PVRSRV_BRIDGE_MM_CMD_FIRST+35 -#define PVRSRV_BRIDGE_MM_GETDEFAULTPHYSICALHEAP PVRSRV_BRIDGE_MM_CMD_FIRST+36 -#define PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGE PVRSRV_BRIDGE_MM_CMD_FIRST+37 -#define PVRSRV_BRIDGE_MM_DEVMEMGETFAULTADDRESS PVRSRV_BRIDGE_MM_CMD_FIRST+38 -#define PVRSRV_BRIDGE_MM_PVRSRVUPDATEOOMSTATS PVRSRV_BRIDGE_MM_CMD_FIRST+39 -#define PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFOPKD PVRSRV_BRIDGE_MM_CMD_FIRST+40 -#define PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGEPKD PVRSRV_BRIDGE_MM_CMD_FIRST+41 -#define PVRSRV_BRIDGE_MM_DEVMEMXINTRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+42 -#define PVRSRV_BRIDGE_MM_DEVMEMXINTUNRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+43 -#define PVRSRV_BRIDGE_MM_DEVMEMXINTMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+44 -#define PVRSRV_BRIDGE_MM_DEVMEMXINTUNMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+45 -#define PVRSRV_BRIDGE_MM_CHANGESPARSEMEM2 PVRSRV_BRIDGE_MM_CMD_FIRST+46 -#define PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE2 PVRSRV_BRIDGE_MM_CMD_FIRST+47 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE2 PVRSRV_BRIDGE_MM_CMD_FIRST+48 -#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR2 PVRSRV_BRIDGE_MM_CMD_FIRST+49 -#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR2 PVRSRV_BRIDGE_MM_CMD_FIRST+50 -#define PVRSRV_BRIDGE_MM_CMD_LAST (PVRSRV_BRIDGE_MM_CMD_FIRST+50) - -/******************************************* - PMRExportPMR - *******************************************/ - -/* Bridge in structure for PMRExportPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMREXPORTPMR_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PMREXPORTPMR; - -/* Bridge out structure for PMRExportPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMREXPORTPMR_TAG -{ - IMG_UINT64 ui64Password; - IMG_UINT64 ui64Size; - IMG_HANDLE hPMRExport; - PVRSRV_ERROR eError; - IMG_UINT32 ui32Log2Contig; -} __packed PVRSRV_BRIDGE_OUT_PMREXPORTPMR; - -/******************************************* - PMRUnexportPMR - *******************************************/ - -/* Bridge in structure for PMRUnexportPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR_TAG -{ - IMG_HANDLE hPMRExport; -} __packed PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR; - -/* Bridge out structure for PMRUnexportPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR; - -/******************************************* - PMRGetUID - *******************************************/ - -/* Bridge in structure for PMRGetUID */ -typedef struct PVRSRV_BRIDGE_IN_PMRGETUID_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PMRGETUID; - -/* Bridge out structure for PMRGetUID */ -typedef struct PVRSRV_BRIDGE_OUT_PMRGETUID_TAG -{ - IMG_UINT64 ui64UID; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRGETUID; - -/******************************************* - PMRMakeLocalImportHandle - *******************************************/ - -/* Bridge in structure for PMRMakeLocalImportHandle */ -typedef struct PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE_TAG -{ - IMG_HANDLE hBuffer; -} __packed PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE; - -/* Bridge out structure for PMRMakeLocalImportHandle */ -typedef struct PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE_TAG -{ - IMG_HANDLE hExtMem; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE; - -/******************************************* - PMRUnmakeLocalImportHandle - *******************************************/ - -/* Bridge in structure for PMRUnmakeLocalImportHandle */ -typedef struct PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE_TAG -{ - IMG_HANDLE hExtMem; -} __packed PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE; - -/* Bridge out structure for PMRUnmakeLocalImportHandle */ -typedef struct PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE; - -/******************************************* - PMRImportPMR - *******************************************/ - -/* Bridge in structure for PMRImportPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMRIMPORTPMR_TAG -{ - IMG_UINT64 ui64uiPassword; - IMG_UINT64 ui64uiSize; - IMG_HANDLE hPMRExport; - IMG_UINT32 ui32uiLog2Contig; -} __packed PVRSRV_BRIDGE_IN_PMRIMPORTPMR; - -/* Bridge out structure for PMRImportPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMRIMPORTPMR_TAG -{ - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRIMPORTPMR; - -/******************************************* - PMRLocalImportPMR - *******************************************/ - -/* Bridge in structure for PMRLocalImportPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR_TAG -{ - IMG_HANDLE hExtHandle; -} __packed PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR; - -/* Bridge out structure for PMRLocalImportPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR_TAG -{ - IMG_DEVMEM_ALIGN_T uiAlign; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR; - -/******************************************* - PMRUnrefPMR - *******************************************/ - -/* Bridge in structure for PMRUnrefPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMRUNREFPMR_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PMRUNREFPMR; - -/* Bridge out structure for PMRUnrefPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMRUNREFPMR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRUNREFPMR; - -/******************************************* - PMRUnrefUnlockPMR - *******************************************/ - -/* Bridge in structure for PMRUnrefUnlockPMR */ -typedef struct PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR; - -/* Bridge out structure for PMRUnrefUnlockPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR; - -/******************************************* - PhysmemNewRamBackedPMR - *******************************************/ - -/* Bridge in structure for PhysmemNewRamBackedPMR */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR_TAG -{ - IMG_DEVMEM_SIZE_T uiChunkSize; - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT32 *pui32MappingTable; - const IMG_CHAR *puiAnnotation; - IMG_UINT32 ui32AnnotationLength; - IMG_UINT32 ui32Log2PageSize; - IMG_UINT32 ui32NumPhysChunks; - IMG_UINT32 ui32NumVirtChunks; - IMG_UINT32 ui32PDumpFlags; - IMG_PID ui32PID; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR; - -/* Bridge out structure for PhysmemNewRamBackedPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR_TAG -{ - IMG_HANDLE hPMRPtr; - PVRSRV_ERROR eError; - PVRSRV_MEMALLOCFLAGS_T uiOutFlags; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR; - -/******************************************* - PhysmemNewRamBackedLockedPMR - *******************************************/ - -/* Bridge in structure for PhysmemNewRamBackedLockedPMR */ -typedef struct PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR_TAG -{ - IMG_DEVMEM_SIZE_T uiChunkSize; - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT32 *pui32MappingTable; - const IMG_CHAR *puiAnnotation; - IMG_UINT32 ui32AnnotationLength; - IMG_UINT32 ui32Log2PageSize; - IMG_UINT32 ui32NumPhysChunks; - IMG_UINT32 ui32NumVirtChunks; - IMG_UINT32 ui32PDumpFlags; - IMG_PID ui32PID; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR; - -/* Bridge out structure for PhysmemNewRamBackedLockedPMR */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR_TAG -{ - IMG_HANDLE hPMRPtr; - PVRSRV_ERROR eError; - PVRSRV_MEMALLOCFLAGS_T uiOutFlags; -} __packed PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR; - -/******************************************* - DevmemIntPin - *******************************************/ - -/* Bridge in structure for DevmemIntPin */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPIN_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTPIN; - -/* Bridge out structure for DevmemIntPin */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPIN_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTPIN; - -/******************************************* - DevmemIntUnpin - *******************************************/ - -/* Bridge in structure for DevmemIntUnpin */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN; - -/* Bridge out structure for DevmemIntUnpin */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN; - -/******************************************* - DevmemIntPinValidate - *******************************************/ - -/* Bridge in structure for DevmemIntPinValidate */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE_TAG -{ - IMG_HANDLE hMapping; - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE; - -/* Bridge out structure for DevmemIntPinValidate */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE; - -/******************************************* - DevmemIntUnpinInvalidate - *******************************************/ - -/* Bridge in structure for DevmemIntUnpinInvalidate */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE_TAG -{ - IMG_HANDLE hMapping; - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE; - -/* Bridge out structure for DevmemIntUnpinInvalidate */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE; - -/******************************************* - DevmemIntCtxCreate - *******************************************/ - -/* Bridge in structure for DevmemIntCtxCreate */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE_TAG -{ - IMG_BOOL bbKernelMemoryCtx; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE; - -/* Bridge out structure for DevmemIntCtxCreate */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE_TAG -{ - IMG_HANDLE hDevMemServerContext; - IMG_HANDLE hPrivData; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CPUCacheLineSize; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE; - -/******************************************* - DevmemIntCtxDestroy - *******************************************/ - -/* Bridge in structure for DevmemIntCtxDestroy */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY_TAG -{ - IMG_HANDLE hDevmemServerContext; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY; - -/* Bridge out structure for DevmemIntCtxDestroy */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY; - -/******************************************* - DevmemIntHeapCreate - *******************************************/ - -/* Bridge in structure for DevmemIntHeapCreate */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE_TAG -{ - IMG_DEV_VIRTADDR sHeapBaseAddr; - IMG_DEVMEM_SIZE_T uiHeapLength; - IMG_HANDLE hDevmemCtx; - IMG_UINT32 ui32Log2DataPageSize; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE; - -/* Bridge out structure for DevmemIntHeapCreate */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE_TAG -{ - IMG_HANDLE hDevmemHeapPtr; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE; - -/******************************************* - DevmemIntHeapDestroy - *******************************************/ - -/* Bridge in structure for DevmemIntHeapDestroy */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY_TAG -{ - IMG_HANDLE hDevmemHeap; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY; - -/* Bridge out structure for DevmemIntHeapDestroy */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY; - -/******************************************* - DevmemIntMapPMR - *******************************************/ - -/* Bridge in structure for DevmemIntMapPMR */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR_TAG -{ - IMG_HANDLE hDevmemServerHeap; - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - PVRSRV_MEMALLOCFLAGS_T uiMapFlags; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR; - -/* Bridge out structure for DevmemIntMapPMR */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR_TAG -{ - IMG_HANDLE hMapping; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR; - -/******************************************* - DevmemIntUnmapPMR - *******************************************/ - -/* Bridge in structure for DevmemIntUnmapPMR */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR_TAG -{ - IMG_HANDLE hMapping; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR; - -/* Bridge out structure for DevmemIntUnmapPMR */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR; - -/******************************************* - DevmemIntReserveRange - *******************************************/ - -/* Bridge in structure for DevmemIntReserveRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_DEVMEM_SIZE_T uiLength; - IMG_HANDLE hDevmemServerHeap; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE; - -/* Bridge out structure for DevmemIntReserveRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE_TAG -{ - IMG_HANDLE hReservation; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE; - -/******************************************* - DevmemIntUnreserveRange - *******************************************/ - -/* Bridge in structure for DevmemIntUnreserveRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE_TAG -{ - IMG_HANDLE hReservation; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE; - -/* Bridge out structure for DevmemIntUnreserveRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE; - -/******************************************* - ChangeSparseMem - *******************************************/ - -/* Bridge in structure for ChangeSparseMem */ -typedef struct PVRSRV_BRIDGE_IN_CHANGESPARSEMEM_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_UINT64 ui64CPUVAddr; - IMG_HANDLE hPMR; - IMG_HANDLE hSrvDevMemHeap; - IMG_UINT32 *pui32AllocPageIndices; - IMG_UINT32 *pui32FreePageIndices; - IMG_UINT32 ui32AllocPageCount; - IMG_UINT32 ui32FreePageCount; - IMG_UINT32 ui32SparseFlags; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_CHANGESPARSEMEM; - -/* Bridge out structure for ChangeSparseMem */ -typedef struct PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM; - -/******************************************* - DevmemIntMapPages - *******************************************/ - -/* Bridge in structure for DevmemIntMapPages */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - IMG_UINT32 ui32PageCount; - IMG_UINT32 ui32PhysicalPgOffset; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES; - -/* Bridge out structure for DevmemIntMapPages */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES; - -/******************************************* - DevmemIntUnmapPages - *******************************************/ - -/* Bridge in structure for DevmemIntUnmapPages */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; - IMG_HANDLE hReservation; - IMG_UINT32 ui32PageCount; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES; - -/* Bridge out structure for DevmemIntUnmapPages */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES; - -/******************************************* - DevmemIsVDevAddrValid - *******************************************/ - -/* Bridge in structure for DevmemIsVDevAddrValid */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_HANDLE hDevmemCtx; -} __packed PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID; - -/* Bridge out structure for DevmemIsVDevAddrValid */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID; - -/******************************************* - DevmemFlushDevSLCRange - *******************************************/ - -/* Bridge in structure for DevmemFlushDevSLCRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hDevmemCtx; - IMG_BOOL bInvalidate; -} __packed PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE; - -/* Bridge out structure for DevmemFlushDevSLCRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE; - -/******************************************* - DevmemInvalidateFBSCTable - *******************************************/ - -/* Bridge in structure for DevmemInvalidateFBSCTable */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE_TAG -{ - IMG_UINT64 ui64FBSCEntries; - IMG_HANDLE hDevmemCtx; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE; - -/* Bridge out structure for DevmemInvalidateFBSCTable */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE; - -/******************************************* - HeapCfgHeapConfigCount - *******************************************/ - -/* Bridge in structure for HeapCfgHeapConfigCount */ -typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT; - -/* Bridge out structure for HeapCfgHeapConfigCount */ -typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32NumHeapConfigs; -} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT; - -/******************************************* - HeapCfgHeapCount - *******************************************/ - -/* Bridge in structure for HeapCfgHeapCount */ -typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT_TAG -{ - IMG_UINT32 ui32HeapConfigIndex; -} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT; - -/* Bridge out structure for HeapCfgHeapCount */ -typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32NumHeaps; -} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT; - -/******************************************* - HeapCfgHeapConfigName - *******************************************/ - -/* Bridge in structure for HeapCfgHeapConfigName */ -typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME_TAG -{ - IMG_CHAR *puiHeapConfigName; - IMG_UINT32 ui32HeapConfigIndex; - IMG_UINT32 ui32HeapConfigNameBufSz; -} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME; - -/* Bridge out structure for HeapCfgHeapConfigName */ -typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME_TAG -{ - IMG_CHAR *puiHeapConfigName; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME; - -/******************************************* - HeapCfgHeapDetails - *******************************************/ - -/* Bridge in structure for HeapCfgHeapDetails */ -typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS_TAG -{ - IMG_CHAR *puiHeapNameOut; - IMG_UINT32 ui32HeapConfigIndex; - IMG_UINT32 ui32HeapIndex; - IMG_UINT32 ui32HeapNameBufSz; -} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS; - -/* Bridge out structure for HeapCfgHeapDetails */ -typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS_TAG -{ - IMG_DEV_VIRTADDR sDevVAddrBase; - IMG_DEVMEM_SIZE_T uiHeapLength; - IMG_DEVMEM_SIZE_T uiReservedRegionLength; - IMG_CHAR *puiHeapNameOut; - PVRSRV_ERROR eError; - IMG_UINT32 ui32Log2DataPageSizeOut; - IMG_UINT32 ui32Log2ImportAlignmentOut; -} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS; - -/******************************************* - DevmemIntRegisterPFNotifyKM - *******************************************/ - -/* Bridge in structure for DevmemIntRegisterPFNotifyKM */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM_TAG -{ - IMG_HANDLE hDevm; - IMG_BOOL bRegister; - IMG_UINT32 ui32PID; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM; - -/* Bridge out structure for DevmemIntRegisterPFNotifyKM */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM; - -/******************************************* - GetMaxPhysHeapCount - *******************************************/ - -/* Bridge in structure for GetMaxPhysHeapCount */ -typedef struct PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT; - -/* Bridge out structure for GetMaxPhysHeapCount */ -typedef struct PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32PhysHeapCount; -} __packed PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT; - -/******************************************* - PhysHeapGetMemInfo - *******************************************/ - -/* Bridge in structure for PhysHeapGetMemInfo */ -typedef struct PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO_TAG -{ - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats; - PVRSRV_PHYS_HEAP *peaPhysHeapID; - IMG_UINT32 ui32PhysHeapCount; -} __packed PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO; - -/* Bridge out structure for PhysHeapGetMemInfo */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO_TAG -{ - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO; - -/******************************************* - GetDefaultPhysicalHeap - *******************************************/ - -/* Bridge in structure for GetDefaultPhysicalHeap */ -typedef struct PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP; - -/* Bridge out structure for GetDefaultPhysicalHeap */ -typedef struct PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_PHYS_HEAP eHeap; -} __packed PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP; - -/******************************************* - GetHeapPhysMemUsage - *******************************************/ - -/* Bridge in structure for GetHeapPhysMemUsage */ -typedef struct PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE_TAG -{ - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats; - IMG_UINT32 ui32PhysHeapCount; -} __packed PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE; - -/* Bridge out structure for GetHeapPhysMemUsage */ -typedef struct PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE_TAG -{ - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE; - -/******************************************* - DevmemGetFaultAddress - *******************************************/ - -/* Bridge in structure for DevmemGetFaultAddress */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS_TAG -{ - IMG_HANDLE hDevmemCtx; -} __packed PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS; - -/* Bridge out structure for DevmemGetFaultAddress */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS_TAG -{ - IMG_DEV_VIRTADDR sFaultAddress; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS; - -/******************************************* - PVRSRVUpdateOOMStats - *******************************************/ - -/* Bridge in structure for PVRSRVUpdateOOMStats */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS_TAG -{ - IMG_PID ui32pid; - IMG_UINT32 ui32ui32StatType; -} __packed PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS; - -/* Bridge out structure for PVRSRVUpdateOOMStats */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS; - -/******************************************* - PhysHeapGetMemInfoPkd - *******************************************/ - -/* Bridge in structure for PhysHeapGetMemInfoPkd */ -typedef struct PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFOPKD_TAG -{ - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStats; - PVRSRV_PHYS_HEAP *peaPhysHeapID; - IMG_UINT32 ui32PhysHeapCount; -} __packed PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFOPKD; - -/* Bridge out structure for PhysHeapGetMemInfoPkd */ -typedef struct PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFOPKD_TAG -{ - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStats; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFOPKD; - -/******************************************* - GetHeapPhysMemUsagePkd - *******************************************/ - -/* Bridge in structure for GetHeapPhysMemUsagePkd */ -typedef struct PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGEPKD_TAG -{ - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStats; - IMG_UINT32 ui32PhysHeapCount; -} __packed PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGEPKD; - -/* Bridge out structure for GetHeapPhysMemUsagePkd */ -typedef struct PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGEPKD_TAG -{ - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStats; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGEPKD; - -/******************************************* - DevmemXIntReserveRange - *******************************************/ - -/* Bridge in structure for DevmemXIntReserveRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMXINTRESERVERANGE_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_DEVMEM_SIZE_T uiLength; - IMG_HANDLE hDevmemServerHeap; -} __packed PVRSRV_BRIDGE_IN_DEVMEMXINTRESERVERANGE; - -/* Bridge out structure for DevmemXIntReserveRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMXINTRESERVERANGE_TAG -{ - IMG_HANDLE hReservation; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMXINTRESERVERANGE; - -/******************************************* - DevmemXIntUnreserveRange - *******************************************/ - -/* Bridge in structure for DevmemXIntUnreserveRange */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMXINTUNRESERVERANGE_TAG -{ - IMG_HANDLE hReservation; -} __packed PVRSRV_BRIDGE_IN_DEVMEMXINTUNRESERVERANGE; - -/* Bridge out structure for DevmemXIntUnreserveRange */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMXINTUNRESERVERANGE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMXINTUNRESERVERANGE; - -/******************************************* - DevmemXIntMapPages - *******************************************/ - -/* Bridge in structure for DevmemXIntMapPages */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMXINTMAPPAGES_TAG -{ - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - IMG_UINT32 ui32PageCount; - IMG_UINT32 ui32PhysPageOffset; - IMG_UINT32 ui32VirtPageOffset; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_DEVMEMXINTMAPPAGES; - -/* Bridge out structure for DevmemXIntMapPages */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMXINTMAPPAGES_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMXINTMAPPAGES; - -/******************************************* - DevmemXIntUnmapPages - *******************************************/ - -/* Bridge in structure for DevmemXIntUnmapPages */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMXINTUNMAPPAGES_TAG -{ - IMG_HANDLE hReservation; - IMG_UINT32 ui32PageCount; - IMG_UINT32 ui32VirtPageOffset; -} __packed PVRSRV_BRIDGE_IN_DEVMEMXINTUNMAPPAGES; - -/* Bridge out structure for DevmemXIntUnmapPages */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMXINTUNMAPPAGES_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMXINTUNMAPPAGES; - -/******************************************* - ChangeSparseMem2 - *******************************************/ - -/* Bridge in structure for ChangeSparseMem2 */ -typedef struct PVRSRV_BRIDGE_IN_CHANGESPARSEMEM2_TAG -{ - IMG_UINT64 ui64CPUVAddr; - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - IMG_HANDLE hSrvDevMemHeap; - IMG_UINT32 *pui32AllocPageIndices; - IMG_UINT32 *pui32FreePageIndices; - IMG_UINT32 ui32AllocPageCount; - IMG_UINT32 ui32FreePageCount; - IMG_UINT32 ui32SparseFlags; -} __packed PVRSRV_BRIDGE_IN_CHANGESPARSEMEM2; - -/* Bridge out structure for ChangeSparseMem2 */ -typedef struct PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM2_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM2; - -/******************************************* - DevmemIntReserveRange2 - *******************************************/ - -/* Bridge in structure for DevmemIntReserveRange2 */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE2_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_DEVMEM_SIZE_T uiLength; - IMG_HANDLE hDevmemServerHeap; - PVRSRV_MEMALLOCFLAGS_T uiFlags; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE2; - -/* Bridge out structure for DevmemIntReserveRange2 */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE2_TAG -{ - IMG_HANDLE hReservation; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE2; - -/******************************************* - DevmemIntUnreserveRange2 - *******************************************/ - -/* Bridge in structure for DevmemIntUnreserveRange2 */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE2_TAG -{ - IMG_HANDLE hReservation; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE2; - -/* Bridge out structure for DevmemIntUnreserveRange2 */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE2_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE2; - -/******************************************* - DevmemIntMapPMR2 - *******************************************/ - -/* Bridge in structure for DevmemIntMapPMR2 */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR2_TAG -{ - IMG_HANDLE hDevmemServerHeap; - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR2; - -/* Bridge out structure for DevmemIntMapPMR2 */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR2_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR2; - -/******************************************* - DevmemIntUnmapPMR2 - *******************************************/ - -/* Bridge in structure for DevmemIntUnmapPMR2 */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR2_TAG -{ - IMG_HANDLE hReservation; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR2; - -/* Bridge out structure for DevmemIntUnmapPMR2 */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR2_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR2; - -#endif /* COMMON_MM_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_pdump_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_pdump_bridge.h deleted file mode 100644 index eb6ab9488a20c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_pdump_bridge.h +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for pdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for pdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_PDUMP_BRIDGE_H -#define COMMON_PDUMP_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "devicemem_typedefs.h" -#include "pdumpdefs.h" -#include - -#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST 0 -#define PVRSRV_BRIDGE_PDUMP_PDUMPIMAGEDESCRIPTOR PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0 -#define PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPCOMMENT PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1 -#define PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPSETFRAME PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2 -#define PVRSRV_BRIDGE_PDUMP_PDUMPDATADESCRIPTOR PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3 -#define PVRSRV_BRIDGE_PDUMP_CMD_LAST (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3) - -/******************************************* - PDumpImageDescriptor - *******************************************/ - -/* Bridge in structure for PDumpImageDescriptor */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPIMAGEDESCRIPTOR_TAG -{ - IMG_DEV_VIRTADDR sDataDevAddr; - IMG_DEV_VIRTADDR sHeaderDevAddr; - IMG_HANDLE hDevmemCtx; - const IMG_UINT32 *pui32FBCClearColour; - const IMG_CHAR *puiFileName; - IMG_FB_COMPRESSION eFBCompression; - IMG_MEMLAYOUT eMemLayout; - PDUMP_PIXEL_FORMAT ePixelFormat; - PDUMP_FBC_SWIZZLE eeFBCSwizzle; - IMG_UINT32 ui32DataSize; - IMG_UINT32 ui32HeaderSize; - IMG_UINT32 ui32LogicalHeight; - IMG_UINT32 ui32LogicalWidth; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32PhysicalHeight; - IMG_UINT32 ui32PhysicalWidth; - IMG_UINT32 ui32StringSize; -} __packed PVRSRV_BRIDGE_IN_PDUMPIMAGEDESCRIPTOR; - -/* Bridge out structure for PDumpImageDescriptor */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPIMAGEDESCRIPTOR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPIMAGEDESCRIPTOR; - -/******************************************* - PVRSRVPDumpComment - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpComment */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT_TAG -{ - IMG_CHAR *puiComment; - IMG_UINT32 ui32CommentSize; - IMG_UINT32 ui32Flags; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT; - -/* Bridge out structure for PVRSRVPDumpComment */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT; - -/******************************************* - PVRSRVPDumpSetFrame - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpSetFrame */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME_TAG -{ - IMG_UINT32 ui32Frame; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME; - -/* Bridge out structure for PVRSRVPDumpSetFrame */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME; - -/******************************************* - PDumpDataDescriptor - *******************************************/ - -/* Bridge in structure for PDumpDataDescriptor */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPDATADESCRIPTOR_TAG -{ - IMG_DEV_VIRTADDR sDataDevAddr; - IMG_HANDLE hDevmemCtx; - const IMG_CHAR *puiFileName; - IMG_UINT32 ui32DataSize; - IMG_UINT32 ui32ElementCount; - IMG_UINT32 ui32ElementType; - IMG_UINT32 ui32HeaderType; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32StringSize; -} __packed PVRSRV_BRIDGE_IN_PDUMPDATADESCRIPTOR; - -/* Bridge out structure for PDumpDataDescriptor */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPDATADESCRIPTOR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPDATADESCRIPTOR; - -#endif /* COMMON_PDUMP_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_pdumpctrl_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_pdumpctrl_bridge.h deleted file mode 100644 index 4c327816079d3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_pdumpctrl_bridge.h +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for pdumpctrl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for pdumpctrl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_PDUMPCTRL_BRIDGE_H -#define COMMON_PDUMPCTRL_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#define PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST 0 -#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETSTATE PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+0 -#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETFRAME PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+1 -#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+2 -#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISLASTCAPTUREFRAME PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+3 -#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPFORCECAPTURESTOP PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+4 -#define PVRSRV_BRIDGE_PDUMPCTRL_CMD_LAST (PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+4) - -/******************************************* - PVRSRVPDumpGetState - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpGetState */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETSTATE_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETSTATE; - -/* Bridge out structure for PVRSRVPDumpGetState */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETSTATE_TAG -{ - IMG_UINT64 ui64State; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETSTATE; - -/******************************************* - PVRSRVPDumpGetFrame - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpGetFrame */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME; - -/* Bridge out structure for PVRSRVPDumpGetFrame */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32Frame; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME; - -/******************************************* - PVRSRVPDumpSetDefaultCaptureParams - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpSetDefaultCaptureParams */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS_TAG -{ - IMG_UINT32 ui32End; - IMG_UINT32 ui32Interval; - IMG_UINT32 ui32MaxParamFileSize; - IMG_UINT32 ui32Mode; - IMG_UINT32 ui32Start; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS; - -/* Bridge out structure for PVRSRVPDumpSetDefaultCaptureParams */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS; - -/******************************************* - PVRSRVPDumpIsLastCaptureFrame - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpIsLastCaptureFrame */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME; - -/* Bridge out structure for PVRSRVPDumpIsLastCaptureFrame */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME_TAG -{ - IMG_BOOL bpbIsLastCaptureFrame; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME; - -/******************************************* - PVRSRVPDumpForceCaptureStop - *******************************************/ - -/* Bridge in structure for PVRSRVPDumpForceCaptureStop */ -typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPFORCECAPTURESTOP_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_PVRSRVPDUMPFORCECAPTURESTOP; - -/* Bridge out structure for PVRSRVPDumpForceCaptureStop */ -typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPFORCECAPTURESTOP_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PVRSRVPDUMPFORCECAPTURESTOP; - -#endif /* COMMON_PDUMPCTRL_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_pdumpmm_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_pdumpmm_bridge.h deleted file mode 100644 index 6554132ca9c32..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_pdumpmm_bridge.h +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for pdumpmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for pdumpmm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_PDUMPMM_BRIDGE_H -#define COMMON_PDUMPMM_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pdump.h" -#include "pdumpdefs.h" -#include "pvrsrv_memallocflags.h" -#include "devicemem_typedefs.h" - -#define PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST 0 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEM PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+0 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE32 PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+1 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE64 PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+2 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSAVETOFILE PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+3 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSYMBOLICADDR PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+4 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPPOL32 PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+5 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCHECK32 PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+6 -#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCBP PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+7 -#define PVRSRV_BRIDGE_PDUMPMM_DEVMEMINTPDUMPSAVETOFILEVIRTUAL PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+8 -#define PVRSRV_BRIDGE_PDUMPMM_CMD_LAST (PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+8) - -/******************************************* - PMRPDumpLoadMem - *******************************************/ - -/* Bridge in structure for PMRPDumpLoadMem */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - IMG_BOOL bbZero; - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM; - -/* Bridge out structure for PMRPDumpLoadMem */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM; - -/******************************************* - PMRPDumpLoadMemValue32 - *******************************************/ - -/* Bridge in structure for PMRPDumpLoadMemValue32 */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_HANDLE hPMR; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32Value; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32; - -/* Bridge out structure for PMRPDumpLoadMemValue32 */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32; - -/******************************************* - PMRPDumpLoadMemValue64 - *******************************************/ - -/* Bridge in structure for PMRPDumpLoadMemValue64 */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64_TAG -{ - IMG_UINT64 ui64Value; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_HANDLE hPMR; - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64; - -/* Bridge out structure for PMRPDumpLoadMemValue64 */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64; - -/******************************************* - PMRPDumpSaveToFile - *******************************************/ - -/* Bridge in structure for PMRPDumpSaveToFile */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hPMR; - const IMG_CHAR *puiFileName; - IMG_UINT32 ui32ArraySize; - IMG_UINT32 ui32uiFileOffset; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE; - -/* Bridge out structure for PMRPDumpSaveToFile */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE; - -/******************************************* - PMRPDumpSymbolicAddr - *******************************************/ - -/* Bridge in structure for PMRPDumpSymbolicAddr */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_HANDLE hPMR; - IMG_CHAR *puiMemspaceName; - IMG_CHAR *puiSymbolicAddr; - IMG_UINT32 ui32MemspaceNameLen; - IMG_UINT32 ui32SymbolicAddrLen; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR; - -/* Bridge out structure for PMRPDumpSymbolicAddr */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR_TAG -{ - IMG_DEVMEM_OFFSET_T uiNewOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_CHAR *puiMemspaceName; - IMG_CHAR *puiSymbolicAddr; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR; - -/******************************************* - PMRPDumpPol32 - *******************************************/ - -/* Bridge in structure for PMRPDumpPol32 */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPPOL32_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_HANDLE hPMR; - PDUMP_POLL_OPERATOR eOperator; - IMG_UINT32 ui32Mask; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32Value; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPPOL32; - -/* Bridge out structure for PMRPDumpPol32 */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32; - -/******************************************* - PMRPDumpCheck32 - *******************************************/ - -/* Bridge in structure for PMRPDumpCheck32 */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPCHECK32_TAG -{ - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_HANDLE hPMR; - PDUMP_POLL_OPERATOR eOperator; - IMG_UINT32 ui32Mask; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32Value; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPCHECK32; - -/* Bridge out structure for PMRPDumpCheck32 */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPCHECK32_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPCHECK32; - -/******************************************* - PMRPDumpCBP - *******************************************/ - -/* Bridge in structure for PMRPDumpCBP */ -typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPCBP_TAG -{ - IMG_DEVMEM_SIZE_T uiBufferSize; - IMG_DEVMEM_SIZE_T uiPacketSize; - IMG_DEVMEM_OFFSET_T uiReadOffset; - IMG_DEVMEM_OFFSET_T uiWriteOffset; - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_PMRPDUMPCBP; - -/* Bridge out structure for PMRPDumpCBP */ -typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPCBP_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PMRPDUMPCBP; - -/******************************************* - DevmemIntPDumpSaveToFileVirtual - *******************************************/ - -/* Bridge in structure for DevmemIntPDumpSaveToFileVirtual */ -typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL_TAG -{ - IMG_DEV_VIRTADDR sAddress; - IMG_DEVMEM_SIZE_T uiSize; - IMG_HANDLE hDevmemServerContext; - const IMG_CHAR *puiFileName; - IMG_UINT32 ui32ArraySize; - IMG_UINT32 ui32FileOffset; - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL; - -/* Bridge out structure for DevmemIntPDumpSaveToFileVirtual */ -typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL; - -#endif /* COMMON_PDUMPMM_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_pvrtl_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_pvrtl_bridge.h deleted file mode 100644 index edc8223752220..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_pvrtl_bridge.h +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for pvrtl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for pvrtl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_PVRTL_BRIDGE_H -#define COMMON_PVRTL_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "devicemem_typedefs.h" -#include "pvrsrv_tlcommon.h" - -#define PVRSRV_BRIDGE_PVRTL_CMD_FIRST 0 -#define PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+0 -#define PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+1 -#define PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+2 -#define PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+3 -#define PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS PVRSRV_BRIDGE_PVRTL_CMD_FIRST+4 -#define PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+5 -#define PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+6 -#define PVRSRV_BRIDGE_PVRTL_TLWRITEDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7 -#define PVRSRV_BRIDGE_PVRTL_CMD_LAST (PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7) - -/******************************************* - TLOpenStream - *******************************************/ - -/* Bridge in structure for TLOpenStream */ -typedef struct PVRSRV_BRIDGE_IN_TLOPENSTREAM_TAG -{ - const IMG_CHAR *puiName; - IMG_UINT32 ui32Mode; -} __packed PVRSRV_BRIDGE_IN_TLOPENSTREAM; - -/* Bridge out structure for TLOpenStream */ -typedef struct PVRSRV_BRIDGE_OUT_TLOPENSTREAM_TAG -{ - IMG_HANDLE hSD; - IMG_HANDLE hTLPMR; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_TLOPENSTREAM; - -/******************************************* - TLCloseStream - *******************************************/ - -/* Bridge in structure for TLCloseStream */ -typedef struct PVRSRV_BRIDGE_IN_TLCLOSESTREAM_TAG -{ - IMG_HANDLE hSD; -} __packed PVRSRV_BRIDGE_IN_TLCLOSESTREAM; - -/* Bridge out structure for TLCloseStream */ -typedef struct PVRSRV_BRIDGE_OUT_TLCLOSESTREAM_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_TLCLOSESTREAM; - -/******************************************* - TLAcquireData - *******************************************/ - -/* Bridge in structure for TLAcquireData */ -typedef struct PVRSRV_BRIDGE_IN_TLACQUIREDATA_TAG -{ - IMG_HANDLE hSD; -} __packed PVRSRV_BRIDGE_IN_TLACQUIREDATA; - -/* Bridge out structure for TLAcquireData */ -typedef struct PVRSRV_BRIDGE_OUT_TLACQUIREDATA_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32ReadLen; - IMG_UINT32 ui32ReadOffset; -} __packed PVRSRV_BRIDGE_OUT_TLACQUIREDATA; - -/******************************************* - TLReleaseData - *******************************************/ - -/* Bridge in structure for TLReleaseData */ -typedef struct PVRSRV_BRIDGE_IN_TLRELEASEDATA_TAG -{ - IMG_HANDLE hSD; - IMG_UINT32 ui32ReadLen; - IMG_UINT32 ui32ReadOffset; -} __packed PVRSRV_BRIDGE_IN_TLRELEASEDATA; - -/* Bridge out structure for TLReleaseData */ -typedef struct PVRSRV_BRIDGE_OUT_TLRELEASEDATA_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_TLRELEASEDATA; - -/******************************************* - TLDiscoverStreams - *******************************************/ - -/* Bridge in structure for TLDiscoverStreams */ -typedef struct PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS_TAG -{ - const IMG_CHAR *puiNamePattern; - IMG_CHAR *puiStreams; - IMG_UINT32 ui32Size; -} __packed PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS; - -/* Bridge out structure for TLDiscoverStreams */ -typedef struct PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS_TAG -{ - IMG_CHAR *puiStreams; - PVRSRV_ERROR eError; - IMG_UINT32 ui32NumFound; -} __packed PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS; - -/******************************************* - TLReserveStream - *******************************************/ - -/* Bridge in structure for TLReserveStream */ -typedef struct PVRSRV_BRIDGE_IN_TLRESERVESTREAM_TAG -{ - IMG_HANDLE hSD; - IMG_UINT32 ui32Size; - IMG_UINT32 ui32SizeMin; -} __packed PVRSRV_BRIDGE_IN_TLRESERVESTREAM; - -/* Bridge out structure for TLReserveStream */ -typedef struct PVRSRV_BRIDGE_OUT_TLRESERVESTREAM_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32Available; - IMG_UINT32 ui32BufferOffset; -} __packed PVRSRV_BRIDGE_OUT_TLRESERVESTREAM; - -/******************************************* - TLCommitStream - *******************************************/ - -/* Bridge in structure for TLCommitStream */ -typedef struct PVRSRV_BRIDGE_IN_TLCOMMITSTREAM_TAG -{ - IMG_HANDLE hSD; - IMG_UINT32 ui32ReqSize; -} __packed PVRSRV_BRIDGE_IN_TLCOMMITSTREAM; - -/* Bridge out structure for TLCommitStream */ -typedef struct PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM; - -/******************************************* - TLWriteData - *******************************************/ - -/* Bridge in structure for TLWriteData */ -typedef struct PVRSRV_BRIDGE_IN_TLWRITEDATA_TAG -{ - IMG_HANDLE hSD; - IMG_BYTE *pui8Data; - IMG_UINT32 ui32Size; -} __packed PVRSRV_BRIDGE_IN_TLWRITEDATA; - -/* Bridge out structure for TLWriteData */ -typedef struct PVRSRV_BRIDGE_OUT_TLWRITEDATA_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_TLWRITEDATA; - -#endif /* COMMON_PVRTL_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxbreakpoint_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxbreakpoint_bridge.h deleted file mode 100644 index 7b83d9abce6cb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxbreakpoint_bridge.h +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxbreakpoint -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxbreakpoint -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXBREAKPOINT_BRIDGE_H -#define COMMON_RGXBREAKPOINT_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" - -#define PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXSETBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXCLEARBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXENABLEBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXDISABLEBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXOVERALLOCATEBPREGISTERS PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_LAST (PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+4) - -/******************************************* - RGXSetBreakpoint - *******************************************/ - -/* Bridge in structure for RGXSetBreakpoint */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT_TAG -{ - IMG_HANDLE hPrivData; - IMG_UINT32 eFWDataMaster; - IMG_UINT32 ui32BreakpointAddr; - IMG_UINT32 ui32DM; - IMG_UINT32 ui32HandlerAddr; -} __packed PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT; - -/* Bridge out structure for RGXSetBreakpoint */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT; - -/******************************************* - RGXClearBreakpoint - *******************************************/ - -/* Bridge in structure for RGXClearBreakpoint */ -typedef struct PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT_TAG -{ - IMG_HANDLE hPrivData; -} __packed PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT; - -/* Bridge out structure for RGXClearBreakpoint */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT; - -/******************************************* - RGXEnableBreakpoint - *******************************************/ - -/* Bridge in structure for RGXEnableBreakpoint */ -typedef struct PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT_TAG -{ - IMG_HANDLE hPrivData; -} __packed PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT; - -/* Bridge out structure for RGXEnableBreakpoint */ -typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT; - -/******************************************* - RGXDisableBreakpoint - *******************************************/ - -/* Bridge in structure for RGXDisableBreakpoint */ -typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT_TAG -{ - IMG_HANDLE hPrivData; -} __packed PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT; - -/* Bridge out structure for RGXDisableBreakpoint */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT; - -/******************************************* - RGXOverallocateBPRegisters - *******************************************/ - -/* Bridge in structure for RGXOverallocateBPRegisters */ -typedef struct PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS_TAG -{ - IMG_UINT32 ui32SharedRegs; - IMG_UINT32 ui32TempRegs; -} __packed PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS; - -/* Bridge out structure for RGXOverallocateBPRegisters */ -typedef struct PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS; - -#endif /* COMMON_RGXBREAKPOINT_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxcmp_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxcmp_bridge.h deleted file mode 100644 index 396bd3f01585c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxcmp_bridge.h +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxcmp -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxcmp -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXCMP_BRIDGE_H -#define COMMON_RGXCMP_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "pvrsrv_sync_km.h" - -#define PVRSRV_BRIDGE_RGXCMP_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM2 PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPROPERTY PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+6 -#define PVRSRV_BRIDGE_RGXCMP_RGXGETLASTDEVICEERROR PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+7 -#define PVRSRV_BRIDGE_RGXCMP_CMD_LAST (PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+7) - -/******************************************* - RGXCreateComputeContext - *******************************************/ - -/* Bridge in structure for RGXCreateComputeContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT_TAG -{ - IMG_UINT64 ui64RobustnessAddress; - IMG_HANDLE hPrivData; - IMG_BYTE *pui8FrameworkCmd; - IMG_BYTE *pui8StaticComputeContextState; - IMG_UINT32 ui32ContextFlags; - IMG_UINT32 ui32FrameworkCmdize; - IMG_UINT32 ui32MaxDeadlineMS; - IMG_UINT32 ui32PackedCCBSizeU88; - IMG_UINT32 ui32Priority; - IMG_UINT32 ui32StaticComputeContextStateSize; -} __packed PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT; - -/* Bridge out structure for RGXCreateComputeContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT_TAG -{ - IMG_HANDLE hComputeContext; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT; - -/******************************************* - RGXDestroyComputeContext - *******************************************/ - -/* Bridge in structure for RGXDestroyComputeContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT_TAG -{ - IMG_HANDLE hComputeContext; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT; - -/* Bridge out structure for RGXDestroyComputeContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT; - -/******************************************* - RGXFlushComputeData - *******************************************/ - -/* Bridge in structure for RGXFlushComputeData */ -typedef struct PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA_TAG -{ - IMG_HANDLE hComputeContext; -} __packed PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA; - -/* Bridge out structure for RGXFlushComputeData */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA; - -/******************************************* - RGXSetComputeContextPriority - *******************************************/ - -/* Bridge in structure for RGXSetComputeContextPriority */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY_TAG -{ - IMG_HANDLE hComputeContext; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY; - -/* Bridge out structure for RGXSetComputeContextPriority */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY; - -/******************************************* - RGXNotifyComputeWriteOffsetUpdate - *******************************************/ - -/* Bridge in structure for RGXNotifyComputeWriteOffsetUpdate */ -typedef struct PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG -{ - IMG_HANDLE hComputeContext; -} __packed PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE; - -/* Bridge out structure for RGXNotifyComputeWriteOffsetUpdate */ -typedef struct PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE; - -/******************************************* - RGXKickCDM2 - *******************************************/ - -/* Bridge in structure for RGXKickCDM2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXKICKCDM2_TAG -{ - IMG_UINT64 ui64DeadlineInus; - IMG_HANDLE hComputeContext; - IMG_UINT32 *pui32ClientUpdateOffset; - IMG_UINT32 *pui32ClientUpdateValue; - IMG_UINT32 *pui32SyncPMRFlags; - IMG_BYTE *pui8DMCmd; - IMG_CHAR *puiUpdateFenceName; - IMG_HANDLE *phClientUpdateUFOSyncPrimBlock; - IMG_HANDLE *phSyncPMRs; - PVRSRV_FENCE hCheckFenceFd; - PVRSRV_TIMELINE hUpdateTimeline; - IMG_UINT32 ui32ClientUpdateCount; - IMG_UINT32 ui32CmdSize; - IMG_UINT32 ui32ExtJobRef; - IMG_UINT32 ui32NumOfWorkgroups; - IMG_UINT32 ui32NumOfWorkitems; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32SyncPMRCount; -} __packed PVRSRV_BRIDGE_IN_RGXKICKCDM2; - -/* Bridge out structure for RGXKickCDM2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXKICKCDM2_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_FENCE hUpdateFence; -} __packed PVRSRV_BRIDGE_OUT_RGXKICKCDM2; - -/******************************************* - RGXSetComputeContextProperty - *******************************************/ - -/* Bridge in structure for RGXSetComputeContextProperty */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Input; - IMG_HANDLE hComputeContext; - IMG_UINT32 ui32Property; -} __packed PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY; - -/* Bridge out structure for RGXSetComputeContextProperty */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Output; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY; - -/******************************************* - RGXGetLastDeviceError - *******************************************/ - -/* Bridge in structure for RGXGetLastDeviceError */ -typedef struct PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR; - -/* Bridge out structure for RGXGetLastDeviceError */ -typedef struct PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32Error; -} __packed PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR; - -#endif /* COMMON_RGXCMP_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxfwdbg_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxfwdbg_bridge.h deleted file mode 100644 index 68c79e57344d3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxfwdbg_bridge.h +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxfwdbg -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxfwdbg -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXFWDBG_BRIDGE_H -#define COMMON_RGXFWDBG_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "devicemem_typedefs.h" -#include "rgx_bridge.h" -#include "pvrsrv_memallocflags.h" - -#define PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETFWLOG PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGDUMPFREELISTPAGELIST PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETHCSDEADLINE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSIDPRIORITY PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSNEWONLINESTATE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGPHRCONFIGURE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGWDGCONFIGURE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+6 -#define PVRSRV_BRIDGE_RGXFWDBG_RGXCURRENTTIME PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+7 -#define PVRSRV_BRIDGE_RGXFWDBG_CMD_LAST (PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+7) - -/******************************************* - RGXFWDebugSetFWLog - *******************************************/ - -/* Bridge in structure for RGXFWDebugSetFWLog */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG_TAG -{ - IMG_UINT32 ui32RGXFWLogType; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG; - -/* Bridge out structure for RGXFWDebugSetFWLog */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG; - -/******************************************* - RGXFWDebugDumpFreelistPageList - *******************************************/ - -/* Bridge in structure for RGXFWDebugDumpFreelistPageList */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST; - -/* Bridge out structure for RGXFWDebugDumpFreelistPageList */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST; - -/******************************************* - RGXFWDebugSetHCSDeadline - *******************************************/ - -/* Bridge in structure for RGXFWDebugSetHCSDeadline */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE_TAG -{ - IMG_UINT32 ui32RGXHCSDeadline; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE; - -/* Bridge out structure for RGXFWDebugSetHCSDeadline */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE; - -/******************************************* - RGXFWDebugSetOSidPriority - *******************************************/ - -/* Bridge in structure for RGXFWDebugSetOSidPriority */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY_TAG -{ - IMG_UINT32 ui32OSid; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY; - -/* Bridge out structure for RGXFWDebugSetOSidPriority */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY; - -/******************************************* - RGXFWDebugSetOSNewOnlineState - *******************************************/ - -/* Bridge in structure for RGXFWDebugSetOSNewOnlineState */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE_TAG -{ - IMG_UINT32 ui32OSNewState; - IMG_UINT32 ui32OSid; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE; - -/* Bridge out structure for RGXFWDebugSetOSNewOnlineState */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE; - -/******************************************* - RGXFWDebugPHRConfigure - *******************************************/ - -/* Bridge in structure for RGXFWDebugPHRConfigure */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE_TAG -{ - IMG_UINT32 ui32ui32PHRMode; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE; - -/* Bridge out structure for RGXFWDebugPHRConfigure */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE; - -/******************************************* - RGXFWDebugWdgConfigure - *******************************************/ - -/* Bridge in structure for RGXFWDebugWdgConfigure */ -typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE_TAG -{ - IMG_UINT32 ui32ui32WdgPeriodUs; -} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE; - -/* Bridge out structure for RGXFWDebugWdgConfigure */ -typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE; - -/******************************************* - RGXCurrentTime - *******************************************/ - -/* Bridge in structure for RGXCurrentTime */ -typedef struct PVRSRV_BRIDGE_IN_RGXCURRENTTIME_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXCURRENTTIME; - -/* Bridge out structure for RGXCurrentTime */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCURRENTTIME_TAG -{ - IMG_UINT64 ui64Time; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCURRENTTIME; - -#endif /* COMMON_RGXFWDBG_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxhwperf_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxhwperf_bridge.h deleted file mode 100644 index 08e80bb46279f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxhwperf_bridge.h +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxhwperf -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxhwperf -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXHWPERF_BRIDGE_H -#define COMMON_RGXHWPERF_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "rgx_hwperf.h" - -#define PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXGETHWPERFBVNCFEATUREFLAGS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGMUXHWPERFCOUNTERS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONTROLHWPERFBLOCKS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGUREHWPERFBLOCKS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXHWPERF_CMD_LAST (PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+5) - -/******************************************* - RGXCtrlHWPerf - *******************************************/ - -/* Bridge in structure for RGXCtrlHWPerf */ -typedef struct PVRSRV_BRIDGE_IN_RGXCTRLHWPERF_TAG -{ - IMG_UINT64 ui64Mask; - IMG_BOOL bToggle; - IMG_UINT32 ui32StreamId; -} __packed PVRSRV_BRIDGE_IN_RGXCTRLHWPERF; - -/* Bridge out structure for RGXCtrlHWPerf */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF; - -/******************************************* - RGXGetHWPerfBvncFeatureFlags - *******************************************/ - -/* Bridge in structure for RGXGetHWPerfBvncFeatureFlags */ -typedef struct PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS; - -/* Bridge out structure for RGXGetHWPerfBvncFeatureFlags */ -typedef struct PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS_TAG -{ - RGX_HWPERF_BVNC sBVNC; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS; - -/******************************************* - RGXConfigMuxHWPerfCounters - *******************************************/ - -/* Bridge in structure for RGXConfigMuxHWPerfCounters */ -typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS_TAG -{ - RGX_HWPERF_CONFIG_MUX_CNTBLK *psBlockConfigs; - IMG_UINT32 ui32ArrayLen; -} __packed PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS; - -/* Bridge out structure for RGXConfigMuxHWPerfCounters */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS; - -/******************************************* - RGXControlHWPerfBlocks - *******************************************/ - -/* Bridge in structure for RGXControlHWPerfBlocks */ -typedef struct PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS_TAG -{ - IMG_UINT16 *pui16BlockIDs; - IMG_BOOL bEnable; - IMG_UINT32 ui32ArrayLen; -} __packed PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS; - -/* Bridge out structure for RGXControlHWPerfBlocks */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS; - -/******************************************* - RGXConfigCustomCounters - *******************************************/ - -/* Bridge in structure for RGXConfigCustomCounters */ -typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS_TAG -{ - IMG_UINT32 *pui32CustomCounterIDs; - IMG_UINT16 ui16CustomBlockID; - IMG_UINT16 ui16NumCustomCounters; -} __packed PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS; - -/* Bridge out structure for RGXConfigCustomCounters */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS; - -/******************************************* - RGXConfigureHWPerfBlocks - *******************************************/ - -/* Bridge in structure for RGXConfigureHWPerfBlocks */ -typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS_TAG -{ - RGX_HWPERF_CONFIG_CNTBLK *psBlockConfigs; - IMG_UINT32 ui32ArrayLen; - IMG_UINT32 ui32CtrlWord; -} __packed PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS; - -/* Bridge out structure for RGXConfigureHWPerfBlocks */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS; - -#endif /* COMMON_RGXHWPERF_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxkicksync_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxkicksync_bridge.h deleted file mode 100644 index afd882ca7529b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxkicksync_bridge.h +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxkicksync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxkicksync -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXKICKSYNC_BRIDGE_H -#define COMMON_RGXKICKSYNC_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "pvrsrv_sync_km.h" - -#define PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXCREATEKICKSYNCCONTEXT PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXDESTROYKICKSYNCCONTEXT PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXKICKSYNC2 PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXSETKICKSYNCCONTEXTPROPERTY PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXKICKSYNC_CMD_LAST (PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+3) - -/******************************************* - RGXCreateKickSyncContext - *******************************************/ - -/* Bridge in structure for RGXCreateKickSyncContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT_TAG -{ - IMG_HANDLE hPrivData; - IMG_UINT32 ui32ContextFlags; - IMG_UINT32 ui32PackedCCBSizeU88; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT; - -/* Bridge out structure for RGXCreateKickSyncContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT_TAG -{ - IMG_HANDLE hKickSyncContext; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT; - -/******************************************* - RGXDestroyKickSyncContext - *******************************************/ - -/* Bridge in structure for RGXDestroyKickSyncContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT_TAG -{ - IMG_HANDLE hKickSyncContext; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT; - -/* Bridge out structure for RGXDestroyKickSyncContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT; - -/******************************************* - RGXKickSync2 - *******************************************/ - -/* Bridge in structure for RGXKickSync2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNC2_TAG -{ - IMG_HANDLE hKickSyncContext; - IMG_UINT32 *pui32UpdateDevVarOffset; - IMG_UINT32 *pui32UpdateValue; - IMG_CHAR *puiUpdateFenceName; - IMG_HANDLE *phUpdateUFODevVarBlock; - PVRSRV_FENCE hCheckFenceFD; - PVRSRV_TIMELINE hTimelineFenceFD; - IMG_UINT32 ui32ClientUpdateCount; - IMG_UINT32 ui32ExtJobRef; -} __packed PVRSRV_BRIDGE_IN_RGXKICKSYNC2; - -/* Bridge out structure for RGXKickSync2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNC2_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_FENCE hUpdateFenceFD; -} __packed PVRSRV_BRIDGE_OUT_RGXKICKSYNC2; - -/******************************************* - RGXSetKickSyncContextProperty - *******************************************/ - -/* Bridge in structure for RGXSetKickSyncContextProperty */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Input; - IMG_HANDLE hKickSyncContext; - IMG_UINT32 ui32Property; -} __packed PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY; - -/* Bridge out structure for RGXSetKickSyncContextProperty */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Output; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY; - -#endif /* COMMON_RGXKICKSYNC_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxpdump_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxpdump_bridge.h deleted file mode 100644 index 37317acb4707f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxpdump_bridge.h +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxpdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxpdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXPDUMP_BRIDGE_H -#define COMMON_RGXPDUMP_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" - -#define PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPTRACEBUFFER PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPSIGNATUREBUFFER PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPCOMPUTECRCSIGNATURECHECK PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPCRCSIGNATURECHECK PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPRECOMMAND PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPOSTCOMMAND PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXPDUMP_CMD_LAST (PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+5) - -/******************************************* - PDumpTraceBuffer - *******************************************/ - -/* Bridge in structure for PDumpTraceBuffer */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER; - -/* Bridge out structure for PDumpTraceBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER; - -/******************************************* - PDumpSignatureBuffer - *******************************************/ - -/* Bridge in structure for PDumpSignatureBuffer */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER; - -/* Bridge out structure for PDumpSignatureBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER; - -/******************************************* - PDumpComputeCRCSignatureCheck - *******************************************/ - -/* Bridge in structure for PDumpComputeCRCSignatureCheck */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPCOMPUTECRCSIGNATURECHECK_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPCOMPUTECRCSIGNATURECHECK; - -/* Bridge out structure for PDumpComputeCRCSignatureCheck */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPCOMPUTECRCSIGNATURECHECK_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPCOMPUTECRCSIGNATURECHECK; - -/******************************************* - PDumpCRCSignatureCheck - *******************************************/ - -/* Bridge in structure for PDumpCRCSignatureCheck */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPCRCSIGNATURECHECK_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPCRCSIGNATURECHECK; - -/* Bridge out structure for PDumpCRCSignatureCheck */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPCRCSIGNATURECHECK_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPCRCSIGNATURECHECK; - -/******************************************* - PDumpValCheckPreCommand - *******************************************/ - -/* Bridge in structure for PDumpValCheckPreCommand */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPVALCHECKPRECOMMAND_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPVALCHECKPRECOMMAND; - -/* Bridge out structure for PDumpValCheckPreCommand */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPRECOMMAND_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPRECOMMAND; - -/******************************************* - PDumpValCheckPostCommand - *******************************************/ - -/* Bridge in structure for PDumpValCheckPostCommand */ -typedef struct PVRSRV_BRIDGE_IN_PDUMPVALCHECKPOSTCOMMAND_TAG -{ - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_PDUMPVALCHECKPOSTCOMMAND; - -/* Bridge out structure for PDumpValCheckPostCommand */ -typedef struct PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPOSTCOMMAND_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPOSTCOMMAND; - -#endif /* COMMON_RGXPDUMP_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxregconfig_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxregconfig_bridge.h deleted file mode 100644 index 942b7e4b06d00..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxregconfig_bridge.h +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxregconfig -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxregconfig -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXREGCONFIG_BRIDGE_H -#define COMMON_RGXREGCONFIG_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" - -#define PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXSETREGCONFIGTYPE PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXADDREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXCLEARREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXENABLEREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXDISABLEREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXREGCONFIG_CMD_LAST (PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+4) - -/******************************************* - RGXSetRegConfigType - *******************************************/ - -/* Bridge in structure for RGXSetRegConfigType */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE_TAG -{ - IMG_UINT8 ui8RegPowerIsland; -} __packed PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE; - -/* Bridge out structure for RGXSetRegConfigType */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE; - -/******************************************* - RGXAddRegconfig - *******************************************/ - -/* Bridge in structure for RGXAddRegconfig */ -typedef struct PVRSRV_BRIDGE_IN_RGXADDREGCONFIG_TAG -{ - IMG_UINT64 ui64RegMask; - IMG_UINT64 ui64RegValue; - IMG_UINT32 ui32RegAddr; -} __packed PVRSRV_BRIDGE_IN_RGXADDREGCONFIG; - -/* Bridge out structure for RGXAddRegconfig */ -typedef struct PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG; - -/******************************************* - RGXClearRegConfig - *******************************************/ - -/* Bridge in structure for RGXClearRegConfig */ -typedef struct PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG; - -/* Bridge out structure for RGXClearRegConfig */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG; - -/******************************************* - RGXEnableRegConfig - *******************************************/ - -/* Bridge in structure for RGXEnableRegConfig */ -typedef struct PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG; - -/* Bridge out structure for RGXEnableRegConfig */ -typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG; - -/******************************************* - RGXDisableRegConfig - *******************************************/ - -/* Bridge in structure for RGXDisableRegConfig */ -typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG; - -/* Bridge out structure for RGXDisableRegConfig */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG; - -#endif /* COMMON_RGXREGCONFIG_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxta3d_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxta3d_bridge.h deleted file mode 100644 index d5feeb67766fc..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxta3d_bridge.h +++ /dev/null @@ -1,449 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxta3d -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxta3d -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXTA3D_BRIDGE_H -#define COMMON_RGXTA3D_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "rgx_fwif_shared.h" -#include "devicemem_typedefs.h" -#include "pvrsrv_sync_km.h" - -#define PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATASET PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATASET PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+6 -#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+7 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+8 -#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+9 -#define PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+10 -#define PVRSRV_BRIDGE_RGXTA3D_RGXRENDERCONTEXTSTALLED PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+11 -#define PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D2 PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+12 -#define PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+13 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER2 PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+14 -#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST2 PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+15 -#define PVRSRV_BRIDGE_RGXTA3D_CMD_LAST (PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+15) - -/******************************************* - RGXCreateHWRTDataSet - *******************************************/ - -/* Bridge in structure for RGXCreateHWRTDataSet */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET_TAG -{ - IMG_UINT64 ui64FlippedMultiSampleCtl; - IMG_UINT64 ui64MultiSampleCtl; - IMG_DEV_VIRTADDR *psMacrotileArrayDevVAddr; - IMG_DEV_VIRTADDR *psPMMlistDevVAddr; - IMG_DEV_VIRTADDR *psRTCDevVAddr; - IMG_DEV_VIRTADDR *psRgnHeaderDevVAddr; - IMG_DEV_VIRTADDR *psTailPtrsDevVAddr; - IMG_DEV_VIRTADDR *psVHeapTableDevVAddr; - IMG_HANDLE *phKmHwRTDataSet; - IMG_HANDLE *phapsFreeLists; - IMG_UINT32 ui32ISPMergeLowerX; - IMG_UINT32 ui32ISPMergeLowerY; - IMG_UINT32 ui32ISPMergeScaleX; - IMG_UINT32 ui32ISPMergeScaleY; - IMG_UINT32 ui32ISPMergeUpperX; - IMG_UINT32 ui32ISPMergeUpperY; - IMG_UINT32 ui32ISPMtileSize; - IMG_UINT32 ui32MTileStride; - IMG_UINT32 ui32PPPScreen; - IMG_UINT32 ui32RgnHeaderSize; - IMG_UINT32 ui32TEAA; - IMG_UINT32 ui32TEMTILE1; - IMG_UINT32 ui32TEMTILE2; - IMG_UINT32 ui32TEScreen; - IMG_UINT32 ui32TPCSize; - IMG_UINT32 ui32TPCStride; - IMG_UINT16 ui16MaxRTs; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET; - -/* Bridge out structure for RGXCreateHWRTDataSet */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET_TAG -{ - IMG_HANDLE *phKmHwRTDataSet; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET; - -/******************************************* - RGXDestroyHWRTDataSet - *******************************************/ - -/* Bridge in structure for RGXDestroyHWRTDataSet */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET_TAG -{ - IMG_HANDLE hKmHwRTDataSet; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET; - -/* Bridge out structure for RGXDestroyHWRTDataSet */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET; - -/******************************************* - RGXCreateZSBuffer - *******************************************/ - -/* Bridge in structure for RGXCreateZSBuffer */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER_TAG -{ - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - PVRSRV_MEMALLOCFLAGS_T uiMapFlags; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER; - -/* Bridge out structure for RGXCreateZSBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER_TAG -{ - IMG_HANDLE hsZSBufferKM; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER; - -/******************************************* - RGXDestroyZSBuffer - *******************************************/ - -/* Bridge in structure for RGXDestroyZSBuffer */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER_TAG -{ - IMG_HANDLE hsZSBufferMemDesc; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER; - -/* Bridge out structure for RGXDestroyZSBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER; - -/******************************************* - RGXPopulateZSBuffer - *******************************************/ - -/* Bridge in structure for RGXPopulateZSBuffer */ -typedef struct PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER_TAG -{ - IMG_HANDLE hsZSBufferKM; -} __packed PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER; - -/* Bridge out structure for RGXPopulateZSBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER_TAG -{ - IMG_HANDLE hsPopulation; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER; - -/******************************************* - RGXUnpopulateZSBuffer - *******************************************/ - -/* Bridge in structure for RGXUnpopulateZSBuffer */ -typedef struct PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER_TAG -{ - IMG_HANDLE hsPopulation; -} __packed PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER; - -/* Bridge out structure for RGXUnpopulateZSBuffer */ -typedef struct PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER; - -/******************************************* - RGXCreateFreeList - *******************************************/ - -/* Bridge in structure for RGXCreateFreeList */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEFREELIST_TAG -{ - IMG_DEV_VIRTADDR spsFreeListDevVAddr; - IMG_DEVMEM_OFFSET_T uiPMROffset; - IMG_HANDLE hMemCtxPrivData; - IMG_HANDLE hsFreeListPMR; - IMG_HANDLE hsGlobalFreeList; - IMG_BOOL bbFreeListCheck; - IMG_UINT32 ui32GrowFLPages; - IMG_UINT32 ui32GrowParamThreshold; - IMG_UINT32 ui32InitFLPages; - IMG_UINT32 ui32MaxFLPages; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEFREELIST; - -/* Bridge out structure for RGXCreateFreeList */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST_TAG -{ - IMG_HANDLE hCleanupCookie; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST; - -/******************************************* - RGXDestroyFreeList - *******************************************/ - -/* Bridge in structure for RGXDestroyFreeList */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST_TAG -{ - IMG_HANDLE hCleanupCookie; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST; - -/* Bridge out structure for RGXDestroyFreeList */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST; - -/******************************************* - RGXCreateRenderContext - *******************************************/ - -/* Bridge in structure for RGXCreateRenderContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT_TAG -{ - IMG_DEV_VIRTADDR sVDMCallStackAddr; - IMG_UINT64 ui64RobustnessAddress; - IMG_HANDLE hPrivData; - IMG_BYTE *pui8FrameworkCmd; - IMG_BYTE *pui8StaticRenderContextState; - IMG_UINT32 ui32ContextFlags; - IMG_UINT32 ui32FrameworkCmdSize; - IMG_UINT32 ui32Max3DDeadlineMS; - IMG_UINT32 ui32MaxTADeadlineMS; - IMG_UINT32 ui32PackedCCBSizeU8888; - IMG_UINT32 ui32Priority; - IMG_UINT32 ui32StaticRenderContextStateSize; - IMG_UINT32 ui32ui32CallStackDepth; -} __packed PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT; - -/* Bridge out structure for RGXCreateRenderContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT_TAG -{ - IMG_HANDLE hRenderContext; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT; - -/******************************************* - RGXDestroyRenderContext - *******************************************/ - -/* Bridge in structure for RGXDestroyRenderContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT_TAG -{ - IMG_HANDLE hCleanupCookie; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT; - -/* Bridge out structure for RGXDestroyRenderContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT; - -/******************************************* - RGXSetRenderContextPriority - *******************************************/ - -/* Bridge in structure for RGXSetRenderContextPriority */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY_TAG -{ - IMG_HANDLE hRenderContext; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY; - -/* Bridge out structure for RGXSetRenderContextPriority */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY; - -/******************************************* - RGXRenderContextStalled - *******************************************/ - -/* Bridge in structure for RGXRenderContextStalled */ -typedef struct PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED_TAG -{ - IMG_HANDLE hRenderContext; -} __packed PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED; - -/* Bridge out structure for RGXRenderContextStalled */ -typedef struct PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED; - -/******************************************* - RGXKickTA3D2 - *******************************************/ - -/* Bridge in structure for RGXKickTA3D2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXKICKTA3D2_TAG -{ - IMG_UINT64 ui64Deadline; - IMG_HANDLE hKMHWRTDataSet; - IMG_HANDLE hMSAAScratchBuffer; - IMG_HANDLE hPRFenceUFOSyncPrimBlock; - IMG_HANDLE hRenderContext; - IMG_HANDLE hZSBuffer; - IMG_UINT32 *pui32Client3DUpdateSyncOffset; - IMG_UINT32 *pui32Client3DUpdateValue; - IMG_UINT32 *pui32ClientTAFenceSyncOffset; - IMG_UINT32 *pui32ClientTAFenceValue; - IMG_UINT32 *pui32ClientTAUpdateSyncOffset; - IMG_UINT32 *pui32ClientTAUpdateValue; - IMG_UINT32 *pui32SyncPMRFlags; - IMG_BYTE *pui83DCmd; - IMG_BYTE *pui83DPRCmd; - IMG_BYTE *pui8TACmd; - IMG_CHAR *puiUpdateFenceName; - IMG_CHAR *puiUpdateFenceName3D; - IMG_HANDLE *phClient3DUpdateSyncPrimBlock; - IMG_HANDLE *phClientTAFenceSyncPrimBlock; - IMG_HANDLE *phClientTAUpdateSyncPrimBlock; - IMG_HANDLE *phSyncPMRs; - IMG_BOOL bbAbort; - IMG_BOOL bbKick3D; - IMG_BOOL bbKickPR; - IMG_BOOL bbKickTA; - PVRSRV_FENCE hCheckFence; - PVRSRV_FENCE hCheckFence3D; - PVRSRV_TIMELINE hUpdateTimeline; - PVRSRV_TIMELINE hUpdateTimeline3D; - IMG_UINT32 ui323DCmdSize; - IMG_UINT32 ui323DPRCmdSize; - IMG_UINT32 ui32Client3DUpdateCount; - IMG_UINT32 ui32ClientTAFenceCount; - IMG_UINT32 ui32ClientTAUpdateCount; - IMG_UINT32 ui32ExtJobRef; - IMG_UINT32 ui32NumberOfDrawCalls; - IMG_UINT32 ui32NumberOfIndices; - IMG_UINT32 ui32NumberOfMRTs; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32PRFenceUFOSyncOffset; - IMG_UINT32 ui32PRFenceValue; - IMG_UINT32 ui32RenderTargetSize; - IMG_UINT32 ui32SyncPMRCount; - IMG_UINT32 ui32TACmdSize; -} __packed PVRSRV_BRIDGE_IN_RGXKICKTA3D2; - -/* Bridge out structure for RGXKickTA3D2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXKICKTA3D2_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_FENCE hUpdateFence; - PVRSRV_FENCE hUpdateFence3D; -} __packed PVRSRV_BRIDGE_OUT_RGXKICKTA3D2; - -/******************************************* - RGXSetRenderContextProperty - *******************************************/ - -/* Bridge in structure for RGXSetRenderContextProperty */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Input; - IMG_HANDLE hRenderContext; - IMG_UINT32 ui32Property; -} __packed PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY; - -/* Bridge out structure for RGXSetRenderContextProperty */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Output; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY; - -/******************************************* - RGXCreateZSBuffer2 - *******************************************/ - -/* Bridge in structure for RGXCreateZSBuffer2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER2_TAG -{ - IMG_HANDLE hPMR; - IMG_HANDLE hReservation; - PVRSRV_MEMALLOCFLAGS_T uiMapFlags; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER2; - -/* Bridge out structure for RGXCreateZSBuffer2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER2_TAG -{ - IMG_HANDLE hsZSBufferKM; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER2; - -/******************************************* - RGXCreateFreeList2 - *******************************************/ - -/* Bridge in structure for RGXCreateFreeList2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATEFREELIST2_TAG -{ - IMG_HANDLE hFreeListReservation; - IMG_HANDLE hMemCtxPrivData; - IMG_HANDLE hsGlobalFreeList; - IMG_BOOL bbFreeListCheck; - IMG_UINT32 ui32GrowFLPages; - IMG_UINT32 ui32GrowParamThreshold; - IMG_UINT32 ui32InitFLPages; - IMG_UINT32 ui32MaxFLPages; -} __packed PVRSRV_BRIDGE_IN_RGXCREATEFREELIST2; - -/* Bridge out structure for RGXCreateFreeList2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST2_TAG -{ - IMG_HANDLE hCleanupCookie; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST2; - -#endif /* COMMON_RGXTA3D_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxtimerquery_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxtimerquery_bridge.h deleted file mode 100644 index 34d7c2c56a2c7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxtimerquery_bridge.h +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxtimerquery -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxtimerquery -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXTIMERQUERY_BRIDGE_H -#define COMMON_RGXTIMERQUERY_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" - -#define PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXBEGINTIMERQUERY PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXENDTIMERQUERY PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXQUERYTIMER PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_LAST (PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+2) - -/******************************************* - RGXBeginTimerQuery - *******************************************/ - -/* Bridge in structure for RGXBeginTimerQuery */ -typedef struct PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY_TAG -{ - IMG_UINT32 ui32QueryId; -} __packed PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY; - -/* Bridge out structure for RGXBeginTimerQuery */ -typedef struct PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY; - -/******************************************* - RGXEndTimerQuery - *******************************************/ - -/* Bridge in structure for RGXEndTimerQuery */ -typedef struct PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY; - -/* Bridge out structure for RGXEndTimerQuery */ -typedef struct PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY; - -/******************************************* - RGXQueryTimer - *******************************************/ - -/* Bridge in structure for RGXQueryTimer */ -typedef struct PVRSRV_BRIDGE_IN_RGXQUERYTIMER_TAG -{ - IMG_UINT32 ui32QueryId; -} __packed PVRSRV_BRIDGE_IN_RGXQUERYTIMER; - -/* Bridge out structure for RGXQueryTimer */ -typedef struct PVRSRV_BRIDGE_OUT_RGXQUERYTIMER_TAG -{ - IMG_UINT64 ui64EndTime; - IMG_UINT64 ui64StartTime; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXQUERYTIMER; - -#endif /* COMMON_RGXTIMERQUERY_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxtq2_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxtq2_bridge.h deleted file mode 100644 index 9489ddae2a05c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxtq2_bridge.h +++ /dev/null @@ -1,228 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxtq2 -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxtq2 -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXTQ2_BRIDGE_H -#define COMMON_RGXTQ2_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "pvrsrv_sync_km.h" - -#define PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER2 PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMGETSHAREDMEMORY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMRELEASESHAREDMEMORY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+6 -#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+7 -#define PVRSRV_BRIDGE_RGXTQ2_CMD_LAST (PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+7) - -/******************************************* - RGXTDMCreateTransferContext - *******************************************/ - -/* Bridge in structure for RGXTDMCreateTransferContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT_TAG -{ - IMG_UINT64 ui64RobustnessAddress; - IMG_HANDLE hPrivData; - IMG_BYTE *pui8FrameworkCmd; - IMG_UINT32 ui32ContextFlags; - IMG_UINT32 ui32FrameworkCmdSize; - IMG_UINT32 ui32PackedCCBSizeU88; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT; - -/* Bridge out structure for RGXTDMCreateTransferContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT_TAG -{ - IMG_HANDLE hTransferContext; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT; - -/******************************************* - RGXTDMDestroyTransferContext - *******************************************/ - -/* Bridge in structure for RGXTDMDestroyTransferContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT_TAG -{ - IMG_HANDLE hTransferContext; -} __packed PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT; - -/* Bridge out structure for RGXTDMDestroyTransferContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT; - -/******************************************* - RGXTDMSetTransferContextPriority - *******************************************/ - -/* Bridge in structure for RGXTDMSetTransferContextPriority */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG -{ - IMG_HANDLE hTransferContext; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY; - -/* Bridge out structure for RGXTDMSetTransferContextPriority */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY; - -/******************************************* - RGXTDMNotifyWriteOffsetUpdate - *******************************************/ - -/* Bridge in structure for RGXTDMNotifyWriteOffsetUpdate */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG -{ - IMG_HANDLE hTransferContext; - IMG_UINT32 ui32PDumpFlags; -} __packed PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE; - -/* Bridge out structure for RGXTDMNotifyWriteOffsetUpdate */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE; - -/******************************************* - RGXTDMSubmitTransfer2 - *******************************************/ - -/* Bridge in structure for RGXTDMSubmitTransfer2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2_TAG -{ - IMG_UINT64 ui64DeadlineInus; - IMG_HANDLE hTransferContext; - IMG_UINT32 *pui32SyncPMRFlags; - IMG_UINT32 *pui32UpdateSyncOffset; - IMG_UINT32 *pui32UpdateValue; - IMG_UINT8 *pui8FWCommand; - IMG_CHAR *puiUpdateFenceName; - IMG_HANDLE *phSyncPMRs; - IMG_HANDLE *phUpdateUFOSyncPrimBlock; - PVRSRV_FENCE hCheckFenceFD; - PVRSRV_TIMELINE hUpdateTimeline; - IMG_UINT32 ui32Characteristic1; - IMG_UINT32 ui32Characteristic2; - IMG_UINT32 ui32ClientUpdateCount; - IMG_UINT32 ui32CommandSize; - IMG_UINT32 ui32ExternalJobReference; - IMG_UINT32 ui32PDumpFlags; - IMG_UINT32 ui32SyncPMRCount; -} __packed PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2; - -/* Bridge out structure for RGXTDMSubmitTransfer2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_FENCE hUpdateFence; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2; - -/******************************************* - RGXTDMGetSharedMemory - *******************************************/ - -/* Bridge in structure for RGXTDMGetSharedMemory */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY; - -/* Bridge out structure for RGXTDMGetSharedMemory */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY_TAG -{ - IMG_HANDLE hCLIPMRMem; - IMG_HANDLE hUSCPMRMem; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY; - -/******************************************* - RGXTDMReleaseSharedMemory - *******************************************/ - -/* Bridge in structure for RGXTDMReleaseSharedMemory */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY_TAG -{ - IMG_HANDLE hPMRMem; -} __packed PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY; - -/* Bridge out structure for RGXTDMReleaseSharedMemory */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY; - -/******************************************* - RGXTDMSetTransferContextProperty - *******************************************/ - -/* Bridge in structure for RGXTDMSetTransferContextProperty */ -typedef struct PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Input; - IMG_HANDLE hTransferContext; - IMG_UINT32 ui32Property; -} __packed PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY; - -/* Bridge out structure for RGXTDMSetTransferContextProperty */ -typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Output; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY; - -#endif /* COMMON_RGXTQ2_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_rgxtq_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_rgxtq_bridge.h deleted file mode 100644 index b8642845ee7c8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_rgxtq_bridge.h +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for rgxtq -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for rgxtq -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RGXTQ_BRIDGE_H -#define COMMON_RGXTQ_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "rgx_bridge.h" -#include "pvrsrv_sync_km.h" - -#define PVRSRV_BRIDGE_RGXTQ_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2 PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RGXTQ_CMD_LAST (PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4) - -/******************************************* - RGXCreateTransferContext - *******************************************/ - -/* Bridge in structure for RGXCreateTransferContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT_TAG -{ - IMG_UINT64 ui64RobustnessAddress; - IMG_HANDLE hPrivData; - IMG_BYTE *pui8FrameworkCmd; - IMG_UINT32 ui32ContextFlags; - IMG_UINT32 ui32FrameworkCmdize; - IMG_UINT32 ui32PackedCCBSizeU8888; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT; - -/* Bridge out structure for RGXCreateTransferContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT_TAG -{ - IMG_HANDLE hCLIPMRMem; - IMG_HANDLE hTransferContext; - IMG_HANDLE hUSCPMRMem; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT; - -/******************************************* - RGXDestroyTransferContext - *******************************************/ - -/* Bridge in structure for RGXDestroyTransferContext */ -typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT_TAG -{ - IMG_HANDLE hTransferContext; -} __packed PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT; - -/* Bridge out structure for RGXDestroyTransferContext */ -typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT; - -/******************************************* - RGXSetTransferContextPriority - *******************************************/ - -/* Bridge in structure for RGXSetTransferContextPriority */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY_TAG -{ - IMG_HANDLE hTransferContext; - IMG_UINT32 ui32Priority; -} __packed PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY; - -/* Bridge out structure for RGXSetTransferContextPriority */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY; - -/******************************************* - RGXSubmitTransfer2 - *******************************************/ - -/* Bridge in structure for RGXSubmitTransfer2 */ -typedef struct PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2_TAG -{ - IMG_HANDLE hTransferContext; - IMG_UINT32 *pui32ClientUpdateCount; - IMG_UINT32 *pui32CommandSize; - IMG_UINT32 *pui32SyncPMRFlags; - IMG_UINT32 *pui32TQPrepareFlags; - IMG_UINT32 **pui32UpdateSyncOffset; - IMG_UINT32 **pui32UpdateValue; - IMG_UINT8 **pui8FWCommand; - IMG_CHAR *puiUpdateFenceName; - IMG_HANDLE *phSyncPMRs; - IMG_HANDLE **phUpdateUFOSyncPrimBlock; - PVRSRV_TIMELINE h2DUpdateTimeline; - PVRSRV_TIMELINE h3DUpdateTimeline; - PVRSRV_FENCE hCheckFenceFD; - IMG_UINT32 ui32ExtJobRef; - IMG_UINT32 ui32PrepareCount; - IMG_UINT32 ui32SyncPMRCount; -} __packed PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2; - -/* Bridge out structure for RGXSubmitTransfer2 */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2_TAG -{ - PVRSRV_ERROR eError; - PVRSRV_FENCE h2DUpdateFence; - PVRSRV_FENCE h3DUpdateFence; -} __packed PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2; - -/******************************************* - RGXSetTransferContextProperty - *******************************************/ - -/* Bridge in structure for RGXSetTransferContextProperty */ -typedef struct PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Input; - IMG_HANDLE hTransferContext; - IMG_UINT32 ui32Property; -} __packed PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY; - -/* Bridge out structure for RGXSetTransferContextProperty */ -typedef struct PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY_TAG -{ - IMG_UINT64 ui64Output; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY; - -#endif /* COMMON_RGXTQ_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_ri_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_ri_bridge.h deleted file mode 100644 index ca9b68751b138..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_ri_bridge.h +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for ri -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for ri -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_RI_BRIDGE_H -#define COMMON_RI_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "ri_typedefs.h" - -#define PVRSRV_BRIDGE_RI_CMD_FIRST 0 -#define PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+0 -#define PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+1 -#define PVRSRV_BRIDGE_RI_RIWRITEPROCLISTENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+2 -#define PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR PVRSRV_BRIDGE_RI_CMD_FIRST+3 -#define PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+4 -#define PVRSRV_BRIDGE_RI_RIDUMPLIST PVRSRV_BRIDGE_RI_CMD_FIRST+5 -#define PVRSRV_BRIDGE_RI_RIDUMPALL PVRSRV_BRIDGE_RI_CMD_FIRST+6 -#define PVRSRV_BRIDGE_RI_RIDUMPPROCESS PVRSRV_BRIDGE_RI_CMD_FIRST+7 -#define PVRSRV_BRIDGE_RI_RIWRITEPMRENTRYWITHOWNER PVRSRV_BRIDGE_RI_CMD_FIRST+8 -#define PVRSRV_BRIDGE_RI_CMD_LAST (PVRSRV_BRIDGE_RI_CMD_FIRST+8) - -/******************************************* - RIWritePMREntry - *******************************************/ - -/* Bridge in structure for RIWritePMREntry */ -typedef struct PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY_TAG -{ - IMG_HANDLE hPMRHandle; -} __packed PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY; - -/* Bridge out structure for RIWritePMREntry */ -typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY; - -/******************************************* - RIWriteMEMDESCEntry - *******************************************/ - -/* Bridge in structure for RIWriteMEMDESCEntry */ -typedef struct PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY_TAG -{ - IMG_UINT64 ui64Offset; - IMG_UINT64 ui64Size; - IMG_HANDLE hPMRHandle; - const IMG_CHAR *puiTextB; - IMG_BOOL bIsImport; - IMG_BOOL bIsSuballoc; - IMG_UINT32 ui32TextBSize; -} __packed PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY; - -/* Bridge out structure for RIWriteMEMDESCEntry */ -typedef struct PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY_TAG -{ - IMG_HANDLE hRIHandle; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY; - -/******************************************* - RIWriteProcListEntry - *******************************************/ - -/* Bridge in structure for RIWriteProcListEntry */ -typedef struct PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY_TAG -{ - IMG_UINT64 ui64DevVAddr; - IMG_UINT64 ui64Size; - const IMG_CHAR *puiTextB; - IMG_UINT32 ui32TextBSize; -} __packed PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY; - -/* Bridge out structure for RIWriteProcListEntry */ -typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY_TAG -{ - IMG_HANDLE hRIHandle; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY; - -/******************************************* - RIUpdateMEMDESCAddr - *******************************************/ - -/* Bridge in structure for RIUpdateMEMDESCAddr */ -typedef struct PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR_TAG -{ - IMG_DEV_VIRTADDR sAddr; - IMG_HANDLE hRIHandle; -} __packed PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR; - -/* Bridge out structure for RIUpdateMEMDESCAddr */ -typedef struct PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR; - -/******************************************* - RIDeleteMEMDESCEntry - *******************************************/ - -/* Bridge in structure for RIDeleteMEMDESCEntry */ -typedef struct PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY_TAG -{ - IMG_HANDLE hRIHandle; -} __packed PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY; - -/* Bridge out structure for RIDeleteMEMDESCEntry */ -typedef struct PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY; - -/******************************************* - RIDumpList - *******************************************/ - -/* Bridge in structure for RIDumpList */ -typedef struct PVRSRV_BRIDGE_IN_RIDUMPLIST_TAG -{ - IMG_HANDLE hPMRHandle; -} __packed PVRSRV_BRIDGE_IN_RIDUMPLIST; - -/* Bridge out structure for RIDumpList */ -typedef struct PVRSRV_BRIDGE_OUT_RIDUMPLIST_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIDUMPLIST; - -/******************************************* - RIDumpAll - *******************************************/ - -/* Bridge in structure for RIDumpAll */ -typedef struct PVRSRV_BRIDGE_IN_RIDUMPALL_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_RIDUMPALL; - -/* Bridge out structure for RIDumpAll */ -typedef struct PVRSRV_BRIDGE_OUT_RIDUMPALL_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIDUMPALL; - -/******************************************* - RIDumpProcess - *******************************************/ - -/* Bridge in structure for RIDumpProcess */ -typedef struct PVRSRV_BRIDGE_IN_RIDUMPPROCESS_TAG -{ - IMG_PID ui32Pid; -} __packed PVRSRV_BRIDGE_IN_RIDUMPPROCESS; - -/* Bridge out structure for RIDumpProcess */ -typedef struct PVRSRV_BRIDGE_OUT_RIDUMPPROCESS_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIDUMPPROCESS; - -/******************************************* - RIWritePMREntryWithOwner - *******************************************/ - -/* Bridge in structure for RIWritePMREntryWithOwner */ -typedef struct PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER_TAG -{ - IMG_HANDLE hPMRHandle; - IMG_PID ui32Owner; -} __packed PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER; - -/* Bridge out structure for RIWritePMREntryWithOwner */ -typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER; - -#endif /* COMMON_RI_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_srvcore_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_srvcore_bridge.h deleted file mode 100644 index 7e9ac6eed8a14..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_srvcore_bridge.h +++ /dev/null @@ -1,369 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for srvcore -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for srvcore -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_SRVCORE_BRIDGE_H -#define COMMON_SRVCORE_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pvrsrv_device_types.h" -#include "cache_ops.h" - -#define PVRSRV_BRIDGE_SRVCORE_CMD_FIRST 0 -#define PVRSRV_BRIDGE_SRVCORE_CONNECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+0 -#define PVRSRV_BRIDGE_SRVCORE_DISCONNECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+1 -#define PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+2 -#define PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+3 -#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+4 -#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+5 -#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+6 -#define PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+7 -#define PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+8 -#define PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+9 -#define PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+10 -#define PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+11 -#define PVRSRV_BRIDGE_SRVCORE_GETMULTICOREINFO PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+12 -#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13 -#define PVRSRV_BRIDGE_SRVCORE_FINDPROCESSMEMSTATS PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+14 -#define PVRSRV_BRIDGE_SRVCORE_ACQUIREINFOPAGE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+15 -#define PVRSRV_BRIDGE_SRVCORE_RELEASEINFOPAGE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16 -#define PVRSRV_BRIDGE_SRVCORE_CMD_LAST (PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16) - -/******************************************* - Connect - *******************************************/ - -/* Bridge in structure for Connect */ -typedef struct PVRSRV_BRIDGE_IN_CONNECT_TAG -{ - IMG_UINT32 ui32ClientBuildOptions; - IMG_UINT32 ui32ClientDDKBuild; - IMG_UINT32 ui32ClientDDKVersion; - IMG_UINT32 ui32Flags; -} __packed PVRSRV_BRIDGE_IN_CONNECT; - -/* Bridge out structure for Connect */ -typedef struct PVRSRV_BRIDGE_OUT_CONNECT_TAG -{ - IMG_UINT64 ui64PackedBvnc; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CapabilityFlags; - IMG_UINT8 ui8KernelArch; -} __packed PVRSRV_BRIDGE_OUT_CONNECT; - -/******************************************* - Disconnect - *******************************************/ - -/* Bridge in structure for Disconnect */ -typedef struct PVRSRV_BRIDGE_IN_DISCONNECT_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_DISCONNECT; - -/* Bridge out structure for Disconnect */ -typedef struct PVRSRV_BRIDGE_OUT_DISCONNECT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DISCONNECT; - -/******************************************* - AcquireGlobalEventObject - *******************************************/ - -/* Bridge in structure for AcquireGlobalEventObject */ -typedef struct PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT; - -/* Bridge out structure for AcquireGlobalEventObject */ -typedef struct PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT_TAG -{ - IMG_HANDLE hGlobalEventObject; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT; - -/******************************************* - ReleaseGlobalEventObject - *******************************************/ - -/* Bridge in structure for ReleaseGlobalEventObject */ -typedef struct PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT_TAG -{ - IMG_HANDLE hGlobalEventObject; -} __packed PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT; - -/* Bridge out structure for ReleaseGlobalEventObject */ -typedef struct PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT; - -/******************************************* - EventObjectOpen - *******************************************/ - -/* Bridge in structure for EventObjectOpen */ -typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN_TAG -{ - IMG_HANDLE hEventObject; -} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN; - -/* Bridge out structure for EventObjectOpen */ -typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN_TAG -{ - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN; - -/******************************************* - EventObjectWait - *******************************************/ - -/* Bridge in structure for EventObjectWait */ -typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT_TAG -{ - IMG_HANDLE hOSEventKM; -} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT; - -/* Bridge out structure for EventObjectWait */ -typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT; - -/******************************************* - EventObjectClose - *******************************************/ - -/* Bridge in structure for EventObjectClose */ -typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE_TAG -{ - IMG_HANDLE hOSEventKM; -} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE; - -/* Bridge out structure for EventObjectClose */ -typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE; - -/******************************************* - DumpDebugInfo - *******************************************/ - -/* Bridge in structure for DumpDebugInfo */ -typedef struct PVRSRV_BRIDGE_IN_DUMPDEBUGINFO_TAG -{ - IMG_UINT32 ui32VerbLevel; -} __packed PVRSRV_BRIDGE_IN_DUMPDEBUGINFO; - -/* Bridge out structure for DumpDebugInfo */ -typedef struct PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO; - -/******************************************* - GetDevClockSpeed - *******************************************/ - -/* Bridge in structure for GetDevClockSpeed */ -typedef struct PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED; - -/* Bridge out structure for GetDevClockSpeed */ -typedef struct PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32ClockSpeed; -} __packed PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED; - -/******************************************* - HWOpTimeout - *******************************************/ - -/* Bridge in structure for HWOpTimeout */ -typedef struct PVRSRV_BRIDGE_IN_HWOPTIMEOUT_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_HWOPTIMEOUT; - -/* Bridge out structure for HWOpTimeout */ -typedef struct PVRSRV_BRIDGE_OUT_HWOPTIMEOUT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_HWOPTIMEOUT; - -/******************************************* - AlignmentCheck - *******************************************/ - -/* Bridge in structure for AlignmentCheck */ -typedef struct PVRSRV_BRIDGE_IN_ALIGNMENTCHECK_TAG -{ - IMG_UINT32 *pui32AlignChecks; - IMG_UINT32 ui32AlignChecksSize; -} __packed PVRSRV_BRIDGE_IN_ALIGNMENTCHECK; - -/* Bridge out structure for AlignmentCheck */ -typedef struct PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK; - -/******************************************* - GetDeviceStatus - *******************************************/ - -/* Bridge in structure for GetDeviceStatus */ -typedef struct PVRSRV_BRIDGE_IN_GETDEVICESTATUS_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_GETDEVICESTATUS; - -/* Bridge out structure for GetDeviceStatus */ -typedef struct PVRSRV_BRIDGE_OUT_GETDEVICESTATUS_TAG -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32DeviceSatus; -} __packed PVRSRV_BRIDGE_OUT_GETDEVICESTATUS; - -/******************************************* - GetMultiCoreInfo - *******************************************/ - -/* Bridge in structure for GetMultiCoreInfo */ -typedef struct PVRSRV_BRIDGE_IN_GETMULTICOREINFO_TAG -{ - IMG_UINT64 *pui64Caps; - IMG_UINT32 ui32CapsSize; -} __packed PVRSRV_BRIDGE_IN_GETMULTICOREINFO; - -/* Bridge out structure for GetMultiCoreInfo */ -typedef struct PVRSRV_BRIDGE_OUT_GETMULTICOREINFO_TAG -{ - IMG_UINT64 *pui64Caps; - PVRSRV_ERROR eError; - IMG_UINT32 ui32NumCores; -} __packed PVRSRV_BRIDGE_OUT_GETMULTICOREINFO; - -/******************************************* - EventObjectWaitTimeout - *******************************************/ - -/* Bridge in structure for EventObjectWaitTimeout */ -typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT_TAG -{ - IMG_UINT64 ui64uiTimeoutus; - IMG_HANDLE hOSEventKM; -} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT; - -/* Bridge out structure for EventObjectWaitTimeout */ -typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT; - -/******************************************* - FindProcessMemStats - *******************************************/ - -/* Bridge in structure for FindProcessMemStats */ -typedef struct PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS_TAG -{ - IMG_UINT32 *pui32MemStatsArray; - IMG_BOOL bbAllProcessStats; - IMG_UINT32 ui32ArrSize; - IMG_UINT32 ui32PID; -} __packed PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS; - -/* Bridge out structure for FindProcessMemStats */ -typedef struct PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS_TAG -{ - IMG_UINT32 *pui32MemStatsArray; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS; - -/******************************************* - AcquireInfoPage - *******************************************/ - -/* Bridge in structure for AcquireInfoPage */ -typedef struct PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE; - -/* Bridge out structure for AcquireInfoPage */ -typedef struct PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE_TAG -{ - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE; - -/******************************************* - ReleaseInfoPage - *******************************************/ - -/* Bridge in structure for ReleaseInfoPage */ -typedef struct PVRSRV_BRIDGE_IN_RELEASEINFOPAGE_TAG -{ - IMG_HANDLE hPMR; -} __packed PVRSRV_BRIDGE_IN_RELEASEINFOPAGE; - -/* Bridge out structure for ReleaseInfoPage */ -typedef struct PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE; - -#endif /* COMMON_SRVCORE_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_sync_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_sync_bridge.h deleted file mode 100644 index db48d2e90baad..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_sync_bridge.h +++ /dev/null @@ -1,254 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for sync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for sync -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_SYNC_BRIDGE_H -#define COMMON_SYNC_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#include "pdump.h" -#include "pdumpdefs.h" -#include "devicemem_typedefs.h" -#include "pvrsrv_sync_km.h" -#include - -#define PVRSRV_BRIDGE_SYNC_CMD_FIRST 0 -#define PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK PVRSRV_BRIDGE_SYNC_CMD_FIRST+0 -#define PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK PVRSRV_BRIDGE_SYNC_CMD_FIRST+1 -#define PVRSRV_BRIDGE_SYNC_SYNCPRIMSET PVRSRV_BRIDGE_SYNC_CMD_FIRST+2 -#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP PVRSRV_BRIDGE_SYNC_CMD_FIRST+3 -#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE PVRSRV_BRIDGE_SYNC_CMD_FIRST+4 -#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL PVRSRV_BRIDGE_SYNC_CMD_FIRST+5 -#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP PVRSRV_BRIDGE_SYNC_CMD_FIRST+6 -#define PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT PVRSRV_BRIDGE_SYNC_CMD_FIRST+7 -#define PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT PVRSRV_BRIDGE_SYNC_CMD_FIRST+8 -#define PVRSRV_BRIDGE_SYNC_SYNCCHECKPOINTSIGNALLEDPDUMPPOL PVRSRV_BRIDGE_SYNC_CMD_FIRST+9 -#define PVRSRV_BRIDGE_SYNC_CMD_LAST (PVRSRV_BRIDGE_SYNC_CMD_FIRST+9) - -/******************************************* - AllocSyncPrimitiveBlock - *******************************************/ - -/* Bridge in structure for AllocSyncPrimitiveBlock */ -typedef struct PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK_TAG -{ - IMG_UINT32 ui32EmptyStructPlaceholder; -} __packed PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK; - -/* Bridge out structure for AllocSyncPrimitiveBlock */ -typedef struct PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK_TAG -{ - IMG_HANDLE hSyncHandle; - IMG_HANDLE hhSyncPMR; - PVRSRV_ERROR eError; - IMG_UINT32 ui32SyncPrimBlockSize; - IMG_UINT32 ui32SyncPrimVAddr; -} __packed PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK; - -/******************************************* - FreeSyncPrimitiveBlock - *******************************************/ - -/* Bridge in structure for FreeSyncPrimitiveBlock */ -typedef struct PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK_TAG -{ - IMG_HANDLE hSyncHandle; -} __packed PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK; - -/* Bridge out structure for FreeSyncPrimitiveBlock */ -typedef struct PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK; - -/******************************************* - SyncPrimSet - *******************************************/ - -/* Bridge in structure for SyncPrimSet */ -typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSET_TAG -{ - IMG_HANDLE hSyncHandle; - IMG_UINT32 ui32Index; - IMG_UINT32 ui32Value; -} __packed PVRSRV_BRIDGE_IN_SYNCPRIMSET; - -/* Bridge out structure for SyncPrimSet */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSET_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMSET; - -/******************************************* - SyncPrimPDump - *******************************************/ - -/* Bridge in structure for SyncPrimPDump */ -typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP_TAG -{ - IMG_HANDLE hSyncHandle; - IMG_UINT32 ui32Offset; -} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP; - -/* Bridge out structure for SyncPrimPDump */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP; - -/******************************************* - SyncPrimPDumpValue - *******************************************/ - -/* Bridge in structure for SyncPrimPDumpValue */ -typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE_TAG -{ - IMG_HANDLE hSyncHandle; - IMG_UINT32 ui32Offset; - IMG_UINT32 ui32Value; -} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE; - -/* Bridge out structure for SyncPrimPDumpValue */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE; - -/******************************************* - SyncPrimPDumpPol - *******************************************/ - -/* Bridge in structure for SyncPrimPDumpPol */ -typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL_TAG -{ - IMG_HANDLE hSyncHandle; - PDUMP_POLL_OPERATOR eOperator; - IMG_UINT32 ui32Mask; - IMG_UINT32 ui32Offset; - IMG_UINT32 ui32Value; - PDUMP_FLAGS_T uiPDumpFlags; -} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL; - -/* Bridge out structure for SyncPrimPDumpPol */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL; - -/******************************************* - SyncPrimPDumpCBP - *******************************************/ - -/* Bridge in structure for SyncPrimPDumpCBP */ -typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP_TAG -{ - IMG_DEVMEM_SIZE_T uiBufferSize; - IMG_DEVMEM_SIZE_T uiPacketSize; - IMG_DEVMEM_OFFSET_T uiWriteOffset; - IMG_HANDLE hSyncHandle; - IMG_UINT32 ui32Offset; -} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP; - -/* Bridge out structure for SyncPrimPDumpCBP */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP; - -/******************************************* - SyncAllocEvent - *******************************************/ - -/* Bridge in structure for SyncAllocEvent */ -typedef struct PVRSRV_BRIDGE_IN_SYNCALLOCEVENT_TAG -{ - const IMG_CHAR *puiClassName; - IMG_BOOL bServerSync; - IMG_UINT32 ui32ClassNameSize; - IMG_UINT32 ui32FWAddr; -} __packed PVRSRV_BRIDGE_IN_SYNCALLOCEVENT; - -/* Bridge out structure for SyncAllocEvent */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT; - -/******************************************* - SyncFreeEvent - *******************************************/ - -/* Bridge in structure for SyncFreeEvent */ -typedef struct PVRSRV_BRIDGE_IN_SYNCFREEEVENT_TAG -{ - IMG_UINT32 ui32FWAddr; -} __packed PVRSRV_BRIDGE_IN_SYNCFREEEVENT; - -/* Bridge out structure for SyncFreeEvent */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCFREEEVENT_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCFREEEVENT; - -/******************************************* - SyncCheckpointSignalledPDumpPol - *******************************************/ - -/* Bridge in structure for SyncCheckpointSignalledPDumpPol */ -typedef struct PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL_TAG -{ - PVRSRV_FENCE hFence; -} __packed PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL; - -/* Bridge out structure for SyncCheckpointSignalledPDumpPol */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL; - -#endif /* COMMON_SYNC_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/common_synctracking_bridge.h b/drivers/gpu/drm/img-rogue/1.17/common_synctracking_bridge.h deleted file mode 100644 index 036c7dce629b3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/common_synctracking_bridge.h +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* -@File -@Title Common bridge header for synctracking -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declares common defines and structures used by both the client - and server side of the bridge for synctracking -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 COMMON_SYNCTRACKING_BRIDGE_H -#define COMMON_SYNCTRACKING_BRIDGE_H - -#include - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST 0 -#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+0 -#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1 -#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_LAST (PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1) - -/******************************************* - SyncRecordRemoveByHandle - *******************************************/ - -/* Bridge in structure for SyncRecordRemoveByHandle */ -typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE_TAG -{ - IMG_HANDLE hhRecord; -} __packed PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE; - -/* Bridge out structure for SyncRecordRemoveByHandle */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE_TAG -{ - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE; - -/******************************************* - SyncRecordAdd - *******************************************/ - -/* Bridge in structure for SyncRecordAdd */ -typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDADD_TAG -{ - IMG_HANDLE hhServerSyncPrimBlock; - const IMG_CHAR *puiClassName; - IMG_BOOL bbServerSync; - IMG_UINT32 ui32ClassNameSize; - IMG_UINT32 ui32ui32FwBlockAddr; - IMG_UINT32 ui32ui32SyncOffset; -} __packed PVRSRV_BRIDGE_IN_SYNCRECORDADD; - -/* Bridge out structure for SyncRecordAdd */ -typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDADD_TAG -{ - IMG_HANDLE hhRecord; - PVRSRV_ERROR eError; -} __packed PVRSRV_BRIDGE_OUT_SYNCRECORDADD; - -#endif /* COMMON_SYNCTRACKING_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/config_kernel.h b/drivers/gpu/drm/img-rogue/1.17/config_kernel.h deleted file mode 100644 index bbc9aa53300de..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/config_kernel.h +++ /dev/null @@ -1,187 +0,0 @@ -#define CHROMIUMOS_KERNEL -#define DEVICE_MEMSETCPY_ALIGN_IN_BYTES 16 -#define FIX_DUSTS_POW_ON_INIT -#define GPUVIRT_VALIDATION_NUM_OS 8 -#define ION_DEFAULT_HEAP_ID_MASK (1 << ION_HEAP_TYPE_SYSTEM) -#define ION_DEFAULT_HEAP_NAME "ion_system_heap" -#define PDVFS_COM PDVFS_COM_HOST -#define PDVFS_COM_AP 2 -#define PDVFS_COM_HOST 1 -#define PDVFS_COM_IMG_CLKDIV 4 -#define PDVFS_COM_PMC 3 -#define PVRSRV_APPHINT_ASSERTONHWRTRIGGER IMG_FALSE -#define PVRSRV_APPHINT_ASSERTOUTOFMEMORY IMG_FALSE -#define PVRSRV_APPHINT_CACHEOPCONFIG 0 -#define PVRSRV_APPHINT_CACHEOPTHREADPRIORITY 1 -#define PVRSRV_APPHINT_CACHEOPUMKMHRESHOLDSIZE 0 -#define PVRSRV_APPHINT_CHECKMLIST APPHNT_BLDVAR_DEBUG -#define PVRSRV_APPHINT_CLEANUPTHREADPRIORITY 5 -#define PVRSRV_APPHINT_DISABLECLOCKGATING 0 -#define PVRSRV_APPHINT_DISABLEDMOVERLAP 0 -#define PVRSRV_APPHINT_DISABLEFEDLOGGING IMG_FALSE -#define PVRSRV_APPHINT_DISABLEPDUMPPANIC IMG_FALSE -#define PVRSRV_APPHINT_DRIVERMODE 0x7FFFFFFF -#define PVRSRV_APPHINT_EMUMAXFREQ 0 -#define PVRSRV_APPHINT_ENABLEAPM RGX_ACTIVEPM_DEFAULT -#define PVRSRV_APPHINT_ENABLECDMKILLINGRANDMODE 0 -#define PVRSRV_APPHINT_ENABLEFTRACEGPU IMG_FALSE -#define PVRSRV_APPHINT_ENABLEFULLSYNCTRACKING IMG_FALSE -#define PVRSRV_APPHINT_ENABLEFWCONTEXTSWITCH RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL -#define PVRSRV_APPHINT_ENABLEHTBLOGGROUP 0 -#define PVRSRV_APPHINT_ENABLELOGGROUP RGXFWIF_LOG_TYPE_NONE -#define PVRSRV_APPHINT_ENABLEPAGEFAULTDEBUG APPHNT_BLDVAR_ENABLEPAGEFAULTDEBUG -#define PVRSRV_APPHINT_ENABLERANDOMCONTEXTSWITCH 0 -#define PVRSRV_APPHINT_ENABLERDPOWERISLAND RGX_RD_POWER_ISLAND_DEFAULT -#define PVRSRV_APPHINT_ENABLESIGNATURECHECKS APPHNT_BLDVAR_ENABLESIGNATURECHECKS -#define PVRSRV_APPHINT_ENABLESOFTRESETCNTEXTSWITCH 0 -#define PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG IMG_FALSE -#define PVRSRV_APPHINT_FBCDCVERSIONOVERRIDE 0 -#define PVRSRV_APPHINT_FIRMWARELOGTYPE 0 -#define PVRSRV_APPHINT_FIRMWAREPERF FW_PERF_CONF_NONE -#define PVRSRV_APPHINT_FIRMWARE_HEAP_POLICY 5 -#define PVRSRV_APPHINT_FWCONTEXTSWITCHPROFILE RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN -#define PVRSRV_APPHINT_FWPOISONONFREEVALUE 0xBD -#define PVRSRV_APPHINT_FWTRACEBUFSIZEINDWORDS RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS -#define PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE 0x4000 -#define PVRSRV_APPHINT_GPIOVALIDATIONMODE 0 -#define PVRSRV_APPHINT_GPUUNITSPOWERCHANGE IMG_FALSE -#define PVRSRV_APPHINT_HTBOPERATIONMODE HTB_OPMODE_DROPOLDEST -#define PVRSRV_APPHINT_HTBUFFERSIZE 64 -#define PVRSRV_APPHINT_HWPERFCLIENTBUFFERSIZE 786432 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_EGL 0 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENCL 0 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGL 0 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGLES 0 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_SERVICES 0 -#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_VULKAN 0 -#define PVRSRV_APPHINT_HWPERFDISABLECUSTOMCOUNTERFILTER 0 -#define PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB 2048 -#define PVRSRV_APPHINT_HWPERFFWFILTER 0 -#define PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB 2048 -#define PVRSRV_APPHINT_HWPERFHOSTFILTER 0 -#define PVRSRV_APPHINT_HWPERFHOSTTHREADTIMEOUTINMS 50 -#define PVRSRV_APPHINT_HWRDEBUGDUMPLIMIT APPHNT_BLDVAR_DBGDUMPLIMIT -#define PVRSRV_APPHINT_IGNOREHWREPORTEDBVNC IMG_FALSE -#define PVRSRV_APPHINT_JONESDISABLEMASK 0 -#define PVRSRV_APPHINT_KCCB_SIZE_LOG2 7 -#define PVRSRV_APPHINT_NEWFILTERINGMODE 1 -#define PVRSRV_APPHINT_PHYSMEMTESTPASSES APPHNT_PHYSMEMTEST_ENABLE -#define PVRSRV_APPHINT_RGXBVNC "" -#define PVRSRV_APPHINT_RISCVDMITEST 0 -#define PVRSRV_APPHINT_SIGNATURECHECKSBUFSIZE RGXFW_SIG_BUFFER_SIZE_MIN -#define PVRSRV_APPHINT_TESTSLRINTERVAL 0 -#define PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLGROUP 0 -#define PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLSCHEME 0 -#define PVRSRV_APPHINT_TIMECORRCLOCK 0 -#define PVRSRV_APPHINT_TRUNCATEMODE 0 -#define PVRSRV_APPHINT_VALIDATEIRQ 0 -#define PVRSRV_APPHINT_VALIDATESOCUSCTIMERS 0 -#define PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY 0 -#define PVRSRV_APPHINT_ZEROFREELIST IMG_FALSE -#define PVRSRV_DEVICE_INIT_MODE PVRSRV_LINUX_DEV_INIT_ON_CONNECT -#define PVRSRV_ENABLE_CCCB_GROW -#define PVRSRV_ENABLE_PROCESS_STATS -#define PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN 256 -#define PVRSRV_HWPERF_COUNTERS_PERBLK 12 -#define PVRSRV_MODNAME "pvrsrvkm_1_17" -#define PVRSRV_NEED_PVR_DPF -#define PVRSRV_POISON_ON_ALLOC_VALUE 0xd9 -#define PVRSRV_POISON_ON_FREE_VALUE 0x63 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_3D 17 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_CDM 15 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_KICKSYNC 13 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_RDM 15 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TA 16 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TDM 17 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ2D 17 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ3D 17 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_3D 16 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_CDM 13 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_KICKSYNC 13 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_RDM 13 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TA 15 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TDM 14 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ2D 14 -#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ3D 14 -#define PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE 16 -#define PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE 4 -#define PVRSRV_STALLED_CCB_ACTION -#define PVRSYNC_MODNAME "pvr_sync" -#define PVR_BUILD_DIR "mt8173_linux" -#define PVR_DIRTY_BYTES_FLUSH_THRESHOLD 524288 -#define PVR_DRM_NAME "pvr" -#define PVR_GPIO_MODE PVR_GPIO_MODE_GENERAL -#define PVR_GPIO_MODE_GENERAL 1 -#define PVR_GPIO_MODE_POWMON_PIN 2 -#define PVR_LDM_DRIVER_REGISTRATION_NAME "pvrsrvkm_1_17" -#define PVR_LDM_PLATFORM_PRE_REGISTERED -#define PVR_LINUX_HIGHORDER_ALLOCATION_THRESHOLD 256 -#define PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD 16384 -#define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM 2 -#define PVR_LINUX_PHYSMEM_MAX_EXCESS_POOL_PAGES 20480 -#define PVR_LINUX_PHYSMEM_MAX_POOL_PAGES 10240 -#define PVR_POWER_ACTOR_MEASUREMENT_PERIOD_MS 10U -#define PVR_POWER_MONITOR_HWPERF -#define RGXFW_SAFETY_WATCHDOG_PERIOD_IN_US 1000000 -#define RGX_BNC_CONFIG_KM_HEADER "configs/rgxconfig_km_4.V.2.51.h" -#define RGX_BVNC_CORE_KM_HEADER "cores/rgxcore_km_4.40.2.51.h" -#define RGX_FW_FILENAME "rgx.fw" -#define RGX_FW_HEAP_SHIFT 25 -#define RGX_HCS_DEFAULT_DEADLINE_MS 0xFFFFFFFFU -#define RGX_INITIAL_SLR_HOLDOFF_PERIOD_MS 0 -#define RGX_NUM_OS_SUPPORTED 1 -#define RGX_OSID_0_DEFAULT_PRIORITY (1 - 0) -#define RGX_OSID_1_DEFAULT_PRIORITY (1 - 1) -#define RGX_OSID_2_DEFAULT_PRIORITY (1 - 2) -#define RGX_OSID_3_DEFAULT_PRIORITY (1 - 3) -#define RGX_OSID_4_DEFAULT_PRIORITY (1 - 4) -#define RGX_OSID_5_DEFAULT_PRIORITY (1 - 5) -#define RGX_OSID_6_DEFAULT_PRIORITY (1 - 6) -#define RGX_OSID_7_DEFAULT_PRIORITY (1 - 7) -#define RGX_SH_FILENAME "rgx.sh" -#define SOC_TIMER_FREQ 20 -#define SUPPORT_BUFFER_SYNC 1 -#define SUPPORT_DI_BRG_IMPL -#define SUPPORT_LINUX_DVFS -#define SUPPORT_NATIVE_FENCE_SYNC -#define SUPPORT_POWMON_COMPONENT -#define SUPPORT_RGX 1 -#define CACHEFLUSH_NO_KMRBF_USING_UMVA 1 -#define SUPPORT_RGXTQ_BRIDGE -#define SUPPORT_USC_BREAKPOINT -#define UPDATE_FENCE_CHECKPOINT_COUNT 1 -#define CHROMIUMOS_KERNEL_HAS_DMA_FENCE -#define PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES -#ifdef CONFIG_DRM_POWERVR_ROGUE_DEBUG -#define DEBUG -#define DEBUG_BRIDGE_KM -#define PVRSRV_APPHINT_ENABLEFWPOISONONFREE IMG_TRUE -#define PVRSRV_DEBUG_HANDLE_LOCK -#define PVRSRV_ENABLE_GPU_MEMORY_INFO -#define PVRSRV_ENABLE_SYNC_POISONING -#define PVRSRV_TIMER_CORRELATION_HISTORY -#define PVR_BUILD_TYPE "debug" -#define TRACK_FW_BOOT -#define PVR_ANNOTATION_MAX_LEN 96 -#define PVRSRV_ENABLE_HTB -#else -#define PVR_ANNOTATION_MAX_LEN 40 -#define PVRSRV_APPHINT_ENABLEFWPOISONONFREE IMG_FALSE -#define PVR_BUILD_TYPE "release" -#define RELEASE -#endif -#ifdef CONFIG_DRM_POWERVR_ROGUE_PDUMP -#define PDUMP -#define PDUMP_PARAM_BLOCK_STREAM_SIZE 0x0 -#define PDUMP_PARAM_DEINIT_STREAM_SIZE 0x10000 -#define PDUMP_PARAM_INIT_STREAM_SIZE 0x200000 -#define PDUMP_PARAM_MAIN_STREAM_SIZE 0x1000000 -#define PDUMP_SCRIPT_BLOCK_STREAM_SIZE 0x800000 -#define PDUMP_SCRIPT_DEINIT_STREAM_SIZE 0x10000 -#define PDUMP_SCRIPT_INIT_STREAM_SIZE 0x80000 -#define PDUMP_SCRIPT_MAIN_STREAM_SIZE 0x800000 -#define PDUMP_SPLIT_64BIT_REGISTER_ACCESS -#define SUPPORT_TBI_INTERFACE -#else -#define SUPPORT_PHYSMEM_TEST -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/config_kernel.mk b/drivers/gpu/drm/img-rogue/1.17/config_kernel.mk deleted file mode 100644 index d52432e503648..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/config_kernel.mk +++ /dev/null @@ -1,51 +0,0 @@ -override CHROMIUMOS_KERNEL := 1 -override CHROMIUMOS_KERNEL_HAS_DMA_FENCE := 1 -override HOST_ALL_ARCH := host_x86_64 host_i386 -override KERNEL_CC := aarch64-linux-gnu-gcc-5 -override KERNEL_DRIVER_DIR := drivers/gpu/drm/img-rogue/1.17 -override METAG_VERSION_NEEDED := 2.8.1.0.3 -override MIPS_VERSION_NEEDED := 2014.07-1 -override PDVFS_COM := PDVFS_COM_HOST -override PDVFS_COM_AP := 2 -override PDVFS_COM_HOST := 1 -override PDVFS_COM_IMG_CLKDIV := 4 -override PDVFS_COM_PMC := 3 -override PVRSRV_DIR := services -override PVRSRV_MODNAME := pvrsrvkm_1_17 -override PVR_ARCH := rogue -override PVR_BUILD_DIR := mt8173_linux -override PVR_GPIO_MODE := PVR_GPIO_MODE_GENERAL -override PVR_GPIO_MODE_GENERAL := 1 -override PVR_GPIO_MODE_POWMON_PIN := 2 -override PVR_HANDLE_BACKEND := idr -override PVR_SYSTEM := mt8173 -override RGX_BNC := 4.V.2.51 -override RGX_NUM_OS_SUPPORTED := 1 -override RGX_TIMECORR_CLOCK := mono -override RISCV_VERSION_NEEDED := 1.0.1 -override SORT_BRIDGE_STRUCTS := 1 -override SUPPORT_BUFFER_SYNC := 1 -override SUPPORT_DI_BRG_IMPL := 1 -override SUPPORT_DMABUF_BRIDGE := 1 -override SUPPORT_LINUX_DVFS := 1 -override SUPPORT_MIPS_64K_PAGE_SIZE := -override SUPPORT_NATIVE_FENCE_SYNC := 1 -override SUPPORT_POWMON_COMPONENT := 1 -override SUPPORT_RGX := 1 -override SUPPORT_USC_BREAKPOINT := 1 -override VMM_TYPE := stub -override WINDOW_SYSTEM := lws-generic -ifeq ($(CONFIG_DRM_POWERVR_ROGUE_DEBUG),y) -override BUILD := debug -override PVRSRV_ENABLE_GPU_MEMORY_INFO := 1 -override PVR_BUILD_TYPE := debug -override PVR_SERVICES_DEBUG := 1 -else -override BUILD := release -override PVR_BUILD_TYPE := release -endif -ifeq ($(CONFIG_DRM_POWERVR_ROGUE_PDUMP),y) -override PDUMP := 1 -else -override SUPPORT_PHYSMEM_TEST := 1 -endif diff --git a/drivers/gpu/drm/img-rogue/1.17/configs/rgxconfig_km_4.V.2.51.h b/drivers/gpu/drm/img-rogue/1.17/configs/rgxconfig_km_4.V.2.51.h deleted file mode 100644 index b12f3c22f1a33..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/configs/rgxconfig_km_4.V.2.51.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************/ /*! -@Title RGX Configuration for BVNC 4.V.2.51 (kernel defines) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXCONFIG_KM_4_V_2_51_H -#define RGXCONFIG_KM_4_V_2_51_H - -/***** Automatically generated file. Do not edit manually ********************/ - -/****************************************************************************** - * B.V.N.C Validation defines - *****************************************************************************/ -#define RGX_BNC_KM_B 4 -#define RGX_BNC_KM_N 2 -#define RGX_BNC_KM_C 51 - -/****************************************************************************** - * DDK Defines - *****************************************************************************/ -#define RGX_FEATURE_AXI_ACELITE -#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (1U) -#define RGX_FEATURE_CLUSTER_GROUPING -#define RGX_FEATURE_COMPUTE -#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE -#define RGX_FEATURE_COMPUTE_OVERLAP -#define RGX_FEATURE_DYNAMIC_DUST_POWER -#define RGX_FEATURE_FBCDC_ALGORITHM (2U) -#define RGX_FEATURE_FBCDC_ARCHITECTURE (2U) -#define RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS (0U) -#define RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS (0U) -#define RGX_FEATURE_GS_RTA_SUPPORT -#define RGX_FEATURE_LAYOUT_MARS (0U) -#define RGX_FEATURE_META (LTP218) -#define RGX_FEATURE_META_COREMEM_SIZE (32U) -#define RGX_FEATURE_NUM_CLUSTERS (2U) -#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8U) -#define RGX_FEATURE_NUM_RASTER_PIPES (1U) -#define RGX_FEATURE_PERFBUS -#define RGX_FEATURE_PERF_COUNTER_BATCH -#define RGX_FEATURE_PHYS_BUS_WIDTH (40U) -#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512U) -#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (128U) -#define RGX_FEATURE_SOC_TIMER -#define RGX_FEATURE_TILE_SIZE_X (32U) -#define RGX_FEATURE_TILE_SIZE_Y (32U) -#define RGX_FEATURE_TLA -#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS -#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL -#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40U) -#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE - -#endif /* RGXCONFIG_KM_4_V_2_51_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/connection_server.c b/drivers/gpu/drm/img-rogue/1.17/connection_server.c deleted file mode 100644 index 92e0551e7d765..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/connection_server.c +++ /dev/null @@ -1,491 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Server side connection management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Handles connections coming from the client and the management - connection based information -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "handle.h" -#include "pvrsrv.h" -#include "connection_server.h" -#include "osconnection_server.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "sync_server.h" -#include "process_stats.h" -#include "pdump_km.h" -#include "osfunc.h" -#include "tlstream.h" -#include "rgxhwperf_common.h" - -/* PID associated with Connection currently being purged by Cleanup thread */ -static IMG_PID gCurrentPurgeConnectionPid; - -static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection) -{ - PVRSRV_ERROR eError; - PROCESS_HANDLE_BASE *psProcessHandleBase; - IMG_UINT64 ui64MaxBridgeTime; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if (psPVRSRVData->bUnload) - { - /* driver is unloading so do not allow the bridge lock to be released */ - ui64MaxBridgeTime = 0; - } - else - { - ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS; - } - - PVR_ASSERT(psConnection != NULL); - PVR_LOG_RETURN_IF_INVALID_PARAM(psConnection, "psConnection"); - - /* Close HWPerfClient stream here even though we created it in - * PVRSRVConnectKM(). */ - if (psConnection->hClientTLStream) - { - TLStreamClose(psConnection->hClientTLStream); - psConnection->hClientTLStream = NULL; - PVR_DPF((PVR_DBG_MESSAGE, "Destroyed private stream.")); - } - - /* Get process handle base to decrement the refcount */ - psProcessHandleBase = psConnection->psProcessHandleBase; - - if (psProcessHandleBase != NULL) - { - eError = PVRSRVReleaseProcessHandleBase(psProcessHandleBase, psConnection->pid, - ui64MaxBridgeTime); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVReleaseProcessHandleBase"); - - psConnection->psProcessHandleBase = NULL; - } - - /* Free handle base for this connection */ - if (psConnection->psHandleBase != NULL) - { - eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime); - /* - * If we get PVRSRV_ERROR_RETRY we need to pass this back to the caller - * who will schedule a retry. - * Do not log this as it is an expected exception. - * This can occur if the Firmware is still processing a workload from - * the client when a tear-down request is received. - * Retrying will allow the in-flight work to be completed and the - * tear-down request can be completed when the FW is no longer busy. - */ - if (PVRSRV_ERROR_RETRY == eError) - { - return eError; - } - else - { - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeHandleBase:2"); - } - - psConnection->psHandleBase = NULL; - } - - if (psConnection->psSyncConnectionData != NULL) - { - SyncUnregisterConnection(psConnection->psSyncConnectionData); - psConnection->psSyncConnectionData = NULL; - } - - if (psConnection->psPDumpConnectionData != NULL) - { - PDumpUnregisterConnection(psConnection->psPDumpConnectionData); - psConnection->psPDumpConnectionData = NULL; - } - - /* Call environment specific connection data deinit function */ - if (psConnection->hOsPrivateData != NULL) - { - eError = OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData); - PVR_LOG_RETURN_IF_ERROR(eError, "OSConnectionPrivateDataDeInit"); - - psConnection->hOsPrivateData = NULL; - } - - /* Close the PID stats entry as late as possible to catch all frees */ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - if (psConnection->hProcessStats != NULL) - { - PVRSRVStatsDeregisterProcess(psConnection->hProcessStats); - psConnection->hProcessStats = NULL; - } -#endif - - OSFreeMemNoStats(psConnection); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVCommonConnectionConnect(void **ppvPrivData, void *pvOSData) -{ - CONNECTION_DATA *psConnection; - PVRSRV_ERROR eError; - PROCESS_HANDLE_BASE *psProcessHandleBase; - - /* Allocate connection data area, no stats since process not registered yet */ - psConnection = OSAllocZMemNoStats(sizeof(*psConnection)); - PVR_LOG_RETURN_IF_NOMEM(psConnection, "psConnection"); - - /* Allocate process statistics as early as possible to catch all allocs */ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVStatsRegisterProcess", failure); -#endif - - /* Call environment specific connection data init function */ - eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData); - PVR_LOG_GOTO_IF_ERROR(eError, "OSConnectionPrivateDataInit", failure); - - psConnection->pid = OSGetCurrentClientProcessIDKM(); - psConnection->vpid = OSGetCurrentVirtualProcessID(); - psConnection->tid = (IMG_UINT32)OSGetCurrentClientThreadIDKM(); - OSStringLCopy(psConnection->pszProcName, OSGetCurrentClientProcessNameKM(), PVRSRV_CONNECTION_PROCESS_NAME_LEN); - -#if defined(SUPPORT_DMA_TRANSFER) - OSLockCreate(&psConnection->hDmaReqLock); - - eError = OSEventObjectCreate("Dma transfer cleanup event object", - &psConnection->hDmaEventObject); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", failure); - - OSAtomicWrite(&psConnection->ui32NumDmaTransfersInFlight, 0); - psConnection->bAcceptDmaRequests = IMG_TRUE; -#endif - - /* Register this connection with the sync core */ - eError = SyncRegisterConnection(&psConnection->psSyncConnectionData); - PVR_LOG_GOTO_IF_ERROR(eError, "SyncRegisterConnection", failure); - - /* - * Register this connection and Sync PDump callback with - * the pdump core. Pass in the Sync connection data. - */ - eError = PDumpRegisterConnection(psConnection->psSyncConnectionData, - SyncConnectionPDumpSyncBlocks, - &psConnection->psPDumpConnectionData); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpRegisterConnection", failure); - - /* Allocate handle base for this connection */ - eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase, - PVRSRV_HANDLE_BASE_TYPE_CONNECTION); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAllocHandleBase", failure); - - /* get process handle base (if it doesn't exist it will be allocated) */ - eError = PVRSRVAcquireProcessHandleBase(psConnection->pid, &psProcessHandleBase); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAcquireProcessHandleBase", failure); - - /* hConnectionsLock now resides in PVRSRV_DEVICE_NODE */ - { - IMG_BOOL bHostStreamIsNull; - PVRSRV_RGXDEV_INFO *psRgxDevInfo; - PVRSRV_DEVICE_NODE *psDevNode = OSGetDevNode(psConnection); - - OSLockAcquire(psDevNode->hConnectionsLock); - dllist_add_to_tail(&psDevNode->sConnections, &psConnection->sConnectionListNode); -#if defined(DEBUG) || defined(PDUMP) - PVR_LOG(("%s connected - (devID = %u)", psConnection->pszProcName, - psDevNode->sDevId.ui32InternalID)); -#endif - OSLockRelease(psDevNode->hConnectionsLock); - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - psRgxDevInfo = _RGX_DEVICE_INFO_FROM_NODE(psDevNode); - - OSLockAcquire(psRgxDevInfo->hLockHWPerfHostStream); - bHostStreamIsNull = (IMG_BOOL)(psRgxDevInfo->hHWPerfHostStream == NULL); - OSLockRelease(psRgxDevInfo->hLockHWPerfHostStream); - - if (!bHostStreamIsNull) - { - if (TLStreamIsOpenForReading(psRgxDevInfo->hHWPerfHostStream)) - { - /* Announce this client connection in the host stream, if event mask is set */ - RGXSRV_HWPERF_HOST_CLIENT_INFO_PROCESS_NAME(psDevNode, psConnection->pid, psConnection->pszProcName); - } - } - } - } - - psConnection->psProcessHandleBase = psProcessHandleBase; - - *ppvPrivData = psConnection; - - return PVRSRV_OK; - -failure: - ConnectionDataDestroy(psConnection); - - return eError; -} - -static PVRSRV_ERROR _CleanupThreadPurgeConnectionData(void *pvConnectionData) -{ - PVRSRV_ERROR eErrorConnection, eErrorKernel; - CONNECTION_DATA *psConnectionData = pvConnectionData; - - gCurrentPurgeConnectionPid = psConnectionData->pid; - - eErrorConnection = ConnectionDataDestroy(psConnectionData); - if (eErrorConnection != PVRSRV_OK) - { - if (eErrorConnection == PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Failed to purge connection data %p " - "(deferring destruction)", - __func__, - psConnectionData)); - } - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Connection data %p deferred destruction finished", - __func__, - psConnectionData)); - } - - /* Check if possible resize the global handle base */ - eErrorKernel = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE); - PVR_LOG_IF_ERROR(eErrorKernel, "PVRSRVPurgeHandles"); - - gCurrentPurgeConnectionPid = 0; - - return eErrorConnection; -} - -#if defined(SUPPORT_DMA_TRANSFER) -static void WaitForOutstandingDma(CONNECTION_DATA *psConnectionData) -{ - - PVRSRV_ERROR eError; - IMG_HANDLE hEvent; - IMG_UINT32 ui32Tries = 100; - -#if defined(DMA_VERBOSE) - PVR_DPF((PVR_DBG_ERROR, - "Waiting on %d DMA transfers in flight...", OSAtomicRead(&psConnectionData->ui32NumDmaTransfersInFlight))); -#endif - - eError = OSEventObjectOpen(psConnectionData->hDmaEventObject, &hEvent); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to open event object", __func__)); - return; - } - - while (OSAtomicRead(&psConnectionData->ui32NumDmaTransfersInFlight) != 0) - { - /* - #define DMA_TRANSFER_TIMEOUT_US (5000000ULL) - - This currently doesn't work properly. Wait time is not as requested. - Using OSSleepms instead - - OSEventObjectWaitKernel(hEvent, DMA_TRANSFER_TIMEOUT_US); - */ - OSSleepms(50); - if (!ui32Tries) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Timeout while waiting on outstanding DMA transfers!", __func__)); - break; - } - - ui32Tries--; - } - - OSEventObjectClose(hEvent); -} -#endif - -void PVRSRVCommonConnectionDisconnect(void *pvDataPtr) -{ - CONNECTION_DATA *psConnectionData = pvDataPtr; - PVRSRV_DEVICE_NODE *psDevNode = OSGetDevNode(psConnectionData); - - OSLockAcquire(psDevNode->hConnectionsLock); - dllist_remove_node(&psConnectionData->sConnectionListNode); - OSLockRelease(psDevNode->hConnectionsLock); - - /* Notify the PDump core if the pdump control client is disconnecting */ - if (psConnectionData->ui32ClientFlags & SRV_FLAGS_PDUMPCTRL) - { - PDumpDisconnectionNotify(psDevNode); - } -#if defined(SUPPORT_DMA_TRANSFER) - OSLockAcquire(psConnectionData->hDmaReqLock); - - psConnectionData->bAcceptDmaRequests = IMG_FALSE; - - OSLockRelease(psConnectionData->hDmaReqLock); - - WaitForOutstandingDma(psConnectionData); - - OSEventObjectDestroy(psConnectionData->hDmaEventObject); - OSLockDestroy(psConnectionData->hDmaReqLock); -#endif - -#if defined(DEBUG) || defined(PDUMP) - PVR_LOG(("%s disconnected - (devID = %u)", psConnectionData->pszProcName, - psDevNode->sDevId.ui32InternalID)); -#endif - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK) -#endif - { - /* Defer the release of the connection data */ - psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData; - psConnectionData->sCleanupThreadFn.pvData = psConnectionData; - psConnectionData->sCleanupThreadFn.bDependsOnHW = IMG_FALSE; - CLEANUP_THREAD_SET_RETRY_COUNT(&psConnectionData->sCleanupThreadFn, - CLEANUP_THREAD_RETRY_COUNT_DEFAULT); - PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn); - } -} - -IMG_PID PVRSRVGetPurgeConnectionPid(void) -{ - return gCurrentPurgeConnectionPid; -} - -/* Prefix for debug messages about Active Connections */ -#define DEBUG_DUMP_CONNECTION_FORMAT_STR " P%d-V%d-T%d-%s," -#define CONNECTIONS_PREFIX "Connections Device ID:%u(%d)" -#define MAX_CONNECTIONS_PREFIX (29) -#define MAX_DEBUG_DUMP_CONNECTION_STR_LEN (1+10+10+10+7+PVRSRV_CONNECTION_PROCESS_NAME_LEN) -#define MAX_DEBUG_DUMP_STRING_LEN (1+MAX_CONNECTIONS_PREFIX+(3*MAX_DEBUG_DUMP_CONNECTION_STR_LEN)) - -void PVRSRVConnectionDebugNotify(PVRSRV_DEVICE_NODE *psDevNode, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PDLLIST_NODE pNext, pNode; - - /* We must check for an initialised device before accessing its mutex. - * The mutex is initialised as part of DeviceInitialize() which occurs - * on first access to the device node. - */ - if (psDevNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - PVR_DUMPDEBUG_LOG("Connections: No Devices: No active connections"); - return; - } - - OSLockAcquire(psDevNode->hConnectionsLock); - if (dllist_is_empty(&psDevNode->sConnections)) - { - PVR_DUMPDEBUG_LOG(CONNECTIONS_PREFIX " No active connections", - (unsigned char)psDevNode->sDevId.ui32InternalID, - (unsigned char)psDevNode->sDevId.i32OsDeviceID); - } - else - { - IMG_CHAR sActiveConnections[MAX_DEBUG_DUMP_STRING_LEN]; - IMG_UINT16 i, uiPos = 0; - IMG_BOOL bPrinted = IMG_FALSE; - size_t uiSize = sizeof(sActiveConnections); - - IMG_CHAR szTmpConBuff[MAX_CONNECTIONS_PREFIX + 1]; - i = OSSNPrintf(szTmpConBuff, - MAX_CONNECTIONS_PREFIX, - CONNECTIONS_PREFIX, - (unsigned char)psDevNode->sDevId.ui32InternalID, - (unsigned char)psDevNode->sDevId.i32OsDeviceID); - OSStringLCopy(sActiveConnections+uiPos, szTmpConBuff, uiSize); - - /* Move the write offset to the end of the current string */ - uiPos += i; - /* Update the amount of remaining space available to copy into */ - uiSize -= i; - - dllist_foreach_node(&psDevNode->sConnections, pNode, pNext) - { - CONNECTION_DATA *sData = IMG_CONTAINER_OF(pNode, CONNECTION_DATA, sConnectionListNode); - - IMG_CHAR sTmpBuff[MAX_DEBUG_DUMP_CONNECTION_STR_LEN]; - i = OSSNPrintf(sTmpBuff, MAX_DEBUG_DUMP_CONNECTION_STR_LEN, - DEBUG_DUMP_CONNECTION_FORMAT_STR, sData->pid, sData->vpid, sData->tid, sData->pszProcName); - i = MIN(MAX_DEBUG_DUMP_CONNECTION_STR_LEN, i); - bPrinted = IMG_FALSE; - - OSStringLCopy(sActiveConnections+uiPos, sTmpBuff, uiSize); - - /* Move the write offset to the end of the current string */ - uiPos += i; - /* Update the amount of remaining space available to copy into */ - uiSize -= i; - - /* If there is not enough space to add another connection to this line, output the line */ - if (uiSize <= MAX_DEBUG_DUMP_CONNECTION_STR_LEN) - { - PVR_DUMPDEBUG_LOG("%s", sActiveConnections); - - /* - * Remove the "Connections:" prefix from the buffer. - * Leave the subsequent buffer contents indented by the same - * amount to aid in interpreting the debug output. - */ - uiPos = sizeof(CONNECTIONS_PREFIX) - 1; - /* Reset the amount of space available to copy into */ - uiSize = MAX_DEBUG_DUMP_STRING_LEN - uiPos; - bPrinted = IMG_TRUE; - } - } - - /* Only print the current line if it hasn't already been printed */ - if (!bPrinted) - { - /* Strip off the final comma */ - sActiveConnections[OSStringNLength(sActiveConnections, MAX_DEBUG_DUMP_STRING_LEN) - 1] = '\0'; - PVR_DUMPDEBUG_LOG("%s", sActiveConnections); - } -#undef MAX_DEBUG_DUMP_STRING_LEN -#undef MAX_DEBUG_DUMP_CONNECTIONS_PER_LINE - } - OSLockRelease(psDevNode->hConnectionsLock); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/connection_server.h b/drivers/gpu/drm/img-rogue/1.17/connection_server.h deleted file mode 100644 index d11a6eae8bd92..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/connection_server.h +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Server side connection management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description API for server side connection management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(CONNECTION_SERVER_H) -#define CONNECTION_SERVER_H - - -#include "img_types.h" -#include "img_defs.h" -#include "handle.h" -#include "pvrsrv_cleanup.h" - -/* Variable used to hold in memory the timeout for the current time slice*/ -extern IMG_UINT64 gui64TimesliceLimit; -/* Counter number of handle data freed during the current time slice */ -extern IMG_UINT32 gui32HandleDataFreeCounter; -/* Set the maximum time the freeing of the resources can keep the lock */ -#define CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS (3000 * 1000) /* 3ms */ - -typedef struct _CONNECTION_DATA_ -{ - PVRSRV_HANDLE_BASE *psHandleBase; - PROCESS_HANDLE_BASE *psProcessHandleBase; - struct _SYNC_CONNECTION_DATA_ *psSyncConnectionData; - struct _PDUMP_CONNECTION_DATA_ *psPDumpConnectionData; - - /* Holds the client flags supplied at connection time */ - IMG_UINT32 ui32ClientFlags; - - /* - * OS specific data can be stored via this handle. - * See osconnection_server.h for a generic mechanism - * for initialising this field. - */ - IMG_HANDLE hOsPrivateData; - -#define PVRSRV_CONNECTION_PROCESS_NAME_LEN (16) - IMG_PID pid; - IMG_PID vpid; - IMG_UINT32 tid; - IMG_CHAR pszProcName[PVRSRV_CONNECTION_PROCESS_NAME_LEN]; - - IMG_HANDLE hProcessStats; - - IMG_HANDLE hClientTLStream; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* - * Connection-based values per application which can be modified by the - * AppHint settings 'OSid, OSidReg, bOSidAxiProtReg' for each application. - * These control where the connection's memory allocation is sourced from. - * ui32OSid, ui32OSidReg range from 0..(GPUVIRT_VALIDATION_NUM_OS - 1). - */ - IMG_UINT32 ui32OSid; - IMG_UINT32 ui32OSidReg; - IMG_BOOL bOSidAxiProtReg; -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - -#if defined(SUPPORT_DMA_TRANSFER) - IMG_BOOL bAcceptDmaRequests; - ATOMIC_T ui32NumDmaTransfersInFlight; - POS_LOCK hDmaReqLock; - IMG_HANDLE hDmaEventObject; -#endif - /* Structure which is hooked into the cleanup thread work list */ - PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn; - - DLLIST_NODE sConnectionListNode; - - /* List navigation for deferred freeing of connection data */ - struct _CONNECTION_DATA_ **ppsThis; - struct _CONNECTION_DATA_ *psNext; -} CONNECTION_DATA; - -#include "osconnection_server.h" - -PVRSRV_ERROR PVRSRVCommonConnectionConnect(void **ppvPrivData, void *pvOSData); -void PVRSRVCommonConnectionDisconnect(void *pvPrivData); - -/**************************************************************************/ /*! -@Function PVRSRVGetPurgeConnectionPid - -@Description Returns PID associated with Connection currently being purged by - Cleanup Thread. If no Connection is purged 0 is returned. - -@Return PID associated with currently purged connection or 0 if no - connection is being purged -*/ /***************************************************************************/ -IMG_PID PVRSRVGetPurgeConnectionPid(void); - -void PVRSRVConnectionDebugNotify(PVRSRV_DEVICE_NODE *psDevNode, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVConnectionPrivateData) -#endif -static INLINE -IMG_HANDLE PVRSRVConnectionPrivateData(CONNECTION_DATA *psConnection) -{ - return (psConnection != NULL) ? psConnection->hOsPrivateData : NULL; -} - -#endif /* !defined(CONNECTION_SERVER_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/cores/rgxcore_km_4.40.2.51.h b/drivers/gpu/drm/img-rogue/1.17/cores/rgxcore_km_4.40.2.51.h deleted file mode 100644 index c00a3e6fc9305..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/cores/rgxcore_km_4.40.2.51.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************/ /*! -@Title RGX Core BVNC 4.40.2.51 -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXCORE_KM_4_40_2_51_H -#define RGXCORE_KM_4_40_2_51_H - -/* Automatically generated file (04/10/2021 09:01:50): Do not edit manually */ -/* CS: @3254374 */ - -/****************************************************************************** - * BVNC = 4.40.2.51 - *****************************************************************************/ -#define RGX_BVNC_KM_B 4 -#define RGX_BVNC_KM_V 40 -#define RGX_BVNC_KM_N 2 -#define RGX_BVNC_KM_C 51 - -/****************************************************************************** - * Errata - *****************************************************************************/ - -#define FIX_HW_BRN_50767 -#define FIX_HW_BRN_63142 - - - -/****************************************************************************** - * Enhancements - *****************************************************************************/ -#define HW_ERN_42290 -#define HW_ERN_42606 - - - -#endif /* RGXCORE_KM_4_40_2_51_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/debug_common.c b/drivers/gpu/drm/img-rogue/1.17/debug_common.c deleted file mode 100644 index ee17281cb3a91..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/debug_common.c +++ /dev/null @@ -1,1646 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Debug Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Creates common debug info entries. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(__linux__) -#include -#endif /* #if !defined(__linux__) */ - -#include "debug_common.h" -#include "pvrsrv.h" -#include "di_server.h" -#include "lists.h" -#include "pvrversion.h" -#include "rgx_options.h" -#include "allocmem.h" -#include "rgxfwutils.h" - -#ifdef SUPPORT_RGX -#include "rgxdevice.h" -#include "rgxdebug.h" -#include "rgxinit.h" -#include "rgxmmudefs_km.h" -static IMG_HANDLE ghGpuUtilUserDebugFS; -#endif - -static DI_ENTRY *gpsVersionDIEntry; -static DI_ENTRY *gpsStatusDIEntry; - -#ifdef SUPPORT_VALIDATION -static DI_ENTRY *gpsTestMemLeakDIEntry; -#endif /* SUPPORT_VALIDATION */ -#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) -static DI_ENTRY *gpsDebugLevelDIEntry; -#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */ - -static void _DumpDebugDIPrintfWrapper(void *pvDumpDebugFile, const IMG_CHAR *pszFormat, ...) -{ - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; - va_list ArgList; - - OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, "%s\n", pszFormat); - - va_start(ArgList, pszFormat); - DIVPrintf(pvDumpDebugFile, szBuffer, ArgList); - va_end(ArgList); -} - -/*************************************************************************/ /*! - Version DebugFS entry -*/ /**************************************************************************/ - -static void *_DebugVersionCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode, - va_list va) -{ - IMG_UINT64 *pui64CurrentPosition = va_arg(va, IMG_UINT64 *); - IMG_UINT64 ui64Position = va_arg(va, IMG_UINT64); - IMG_UINT64 ui64CurrentPosition = *pui64CurrentPosition; - - (*pui64CurrentPosition)++; - - return (ui64CurrentPosition == ui64Position) ? psDevNode : NULL; -} - -static void *_VersionDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos) -{ - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - IMG_UINT64 uiCurrentPosition = 1; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PVR_UNREFERENCED_PARAMETER(psEntry); - - if (psPVRSRVData == NULL) { - PVR_DPF((PVR_DBG_ERROR, "psPVRSRVData = NULL")); - return NULL; - } - - if (*pui64Pos == 0) - { - return DI_START_TOKEN; - } - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList, - _DebugVersionCompare_AnyVaCb, - &uiCurrentPosition, - *pui64Pos); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - return psDeviceNode; -} - -static void _VersionDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvPriv) -{ - PVR_UNREFERENCED_PARAMETER(psEntry); - PVR_UNREFERENCED_PARAMETER(pvPriv); -} - -static void *_VersionDINext(OSDI_IMPL_ENTRY *psEntry,void *pvPriv, - IMG_UINT64 *pui64Pos) -{ - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - IMG_UINT64 uiCurrentPosition = 1; - PVRSRV_DEVICE_NODE *psDeviceNode; - - (*pui64Pos)++; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList, - _DebugVersionCompare_AnyVaCb, - &uiCurrentPosition, - *pui64Pos); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - return psDeviceNode; -} - -#define DI_PRINT_VERSION_FMTSPEC \ - "%s Version: %u.%u @ %u (%s) build options: 0x%08x %s\n" -#define STR_DEBUG "debug" -#define STR_RELEASE "release" - -#if defined(DEBUG) || defined(SUPPORT_VALIDATION) -#define BUILD_OPT_LEN 80 - -static inline void _AppendOptionStr(IMG_CHAR pszBuildOptions[], const IMG_CHAR* str, OSDI_IMPL_ENTRY *psEntry, IMG_UINT32* pui32BuildOptionLen) -{ - IMG_UINT32 ui32BuildOptionLen = *pui32BuildOptionLen; - const IMG_UINT32 strLen = OSStringLength(str); - const IMG_UINT32 optStrLen = sizeof(IMG_CHAR) * (BUILD_OPT_LEN-1); - - if ((ui32BuildOptionLen + strLen) > optStrLen) - { - pszBuildOptions[ui32BuildOptionLen] = '\0'; - DIPrintf(psEntry, "%s\n", pszBuildOptions); - ui32BuildOptionLen = 0; - } - if (strLen < optStrLen) - { - OSStringLCopy(pszBuildOptions+ui32BuildOptionLen, str, strLen); - ui32BuildOptionLen += strLen - 1; - } - *pui32BuildOptionLen = ui32BuildOptionLen; -} -#endif /* DEBUG || SUPPORT_VALIDATION */ - -static int _VersionDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvPriv) -{ - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - - if (pvPriv == DI_START_TOKEN) - { - if (psPVRSRVData->sDriverInfo.bIsNoMatch) - { - const BUILD_INFO *psBuildInfo; - - psBuildInfo = &psPVRSRVData->sDriverInfo.sUMBuildInfo; - DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC, - "UM Driver", - PVRVERSION_UNPACK_MAJ(psBuildInfo->ui32BuildVersion), - PVRVERSION_UNPACK_MIN(psBuildInfo->ui32BuildVersion), - psBuildInfo->ui32BuildRevision, - (psBuildInfo->ui32BuildType == BUILD_TYPE_DEBUG) ? - STR_DEBUG : STR_RELEASE, - psBuildInfo->ui32BuildOptions, - PVR_BUILD_DIR); - - psBuildInfo = &psPVRSRVData->sDriverInfo.sKMBuildInfo; - DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC, - "KM Driver (" PVR_ARCH_NAME ")", - PVRVERSION_UNPACK_MAJ(psBuildInfo->ui32BuildVersion), - PVRVERSION_UNPACK_MIN(psBuildInfo->ui32BuildVersion), - psBuildInfo->ui32BuildRevision, - (psBuildInfo->ui32BuildType == BUILD_TYPE_DEBUG) ? - STR_DEBUG : STR_RELEASE, - psBuildInfo->ui32BuildOptions, - PVR_BUILD_DIR); - } - else - { - /* bIsNoMatch is `false` in one of the following cases: - * - UM & KM version parameters actually match. - * - A comparison between UM & KM has not been made yet, because no - * client ever connected. - * - * In both cases, available (KM) version info is the best output we - * can provide. - */ - DIPrintf(psEntry, "Driver Version: %s (%s) (%s) build options: " - "0x%08lx %s\n", PVRVERSION_STRING, PVR_ARCH_NAME, - PVR_BUILD_TYPE, RGX_BUILD_OPTIONS_KM, PVR_BUILD_DIR); - } - } - else if (pvPriv != NULL) - { - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) pvPriv; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; -#ifdef SUPPORT_RGX - PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice; -#if defined(DEBUG) || defined(SUPPORT_VALIDATION) - IMG_CHAR pszBuildOptions[BUILD_OPT_LEN]; - IMG_UINT32 ui32BuildOptionLen = 0; - static const char* aszOptions[] = RGX_BUILD_OPTIONS_LIST; - int i = 0; -#endif -#endif /* SUPPORT_RGX */ - IMG_BOOL bFwVersionInfoPrinted = IMG_FALSE; - - DIPrintf(psEntry, "\nDevice Name: %s\n", psDevConfig->pszName); - DIPrintf(psEntry, "Device ID: %u:%d\n", psDevNode->sDevId.ui32InternalID, - psDevNode->sDevId.i32OsDeviceID); - - if (psDevConfig->pszVersion) - { - DIPrintf(psEntry, "Device Version: %s\n", - psDevConfig->pszVersion); - } - - if (psDevNode->pfnDeviceVersionString) - { - IMG_CHAR *pszVerStr; - - if (psDevNode->pfnDeviceVersionString(psDevNode, - &pszVerStr) == PVRSRV_OK) - { - DIPrintf(psEntry, "%s\n", pszVerStr); - - OSFreeMem(pszVerStr); - } - } - -#ifdef SUPPORT_RGX - /* print device's firmware version info */ - if (psDevInfo->psRGXFWIfOsInitMemDesc != NULL) - { - /* psDevInfo->psRGXFWIfOsInitMemDesc should be permanently mapped */ - if (psDevInfo->psRGXFWIfOsInit != NULL) - { - if (psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated) - { - const RGXFWIF_COMPCHECKS *psRGXCompChecks = - &psDevInfo->psRGXFWIfOsInit->sRGXCompChecks; - IMG_UINT32 ui32DDKVer = psRGXCompChecks->ui32DDKVersion; - - DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC, - "Firmware", - PVRVERSION_UNPACK_MAJ(ui32DDKVer), - PVRVERSION_UNPACK_MIN(ui32DDKVer), - psRGXCompChecks->ui32DDKBuild, - ((psRGXCompChecks->ui32BuildOptions & - OPTIONS_DEBUG_MASK) ? STR_DEBUG : STR_RELEASE), - psRGXCompChecks->ui32BuildOptions, - PVR_BUILD_DIR); - bFwVersionInfoPrinted = IMG_TRUE; - -#if defined(DEBUG) || defined(SUPPORT_VALIDATION) - DIPrintf(psEntry, "Firmware Build Options:\n"); - - for (i = 0; i < ARRAY_SIZE(aszOptions); i++) - { - if ((psRGXCompChecks->ui32BuildOptions & 1<pvDevice, - RGXFWIF_DM_GP, - &sCounterDumpCmd, - 0, - PDUMP_FLAGS_CONTINUOUS, - pui32kCCBCommandSlot); - PVR_LOG_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot"); - - return eError; -} - -static int _DebugPowerDataDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(pvData); - - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - PVR_DPF((PVR_DBG_ERROR, "Device not initialised when " - "power counter data was requested!")); - return -EIO; - } - - OSLockAcquire(psDevInfo->hCounterDumpingLock); - - eError = SendPowerCounterCommand(psDeviceNode, - RGXFWIF_PWR_COUNTER_DUMP_SAMPLE, - &ui32kCCBCommandSlot); - - if (eError != PVRSRV_OK) - { - OSLockRelease(psDevInfo->hCounterDumpingLock); - return -EIO; - } - - /* Wait for FW complete completion */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, - ui32kCCBCommandSlot, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); - OSLockRelease(psDevInfo->hCounterDumpingLock); - return -EIO; - } - - /* Read back the buffer */ - { - IMG_UINT32* pui32PowerBuffer; - IMG_UINT32 ui32NumOfRegs, ui32SamplePeriod; - IMG_UINT32 i, j; - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psCounterBufferMemDesc, - (void**)&pui32PowerBuffer); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "DevmemAcquireCpuVirtAddr"); - OSLockRelease(psDevInfo->hCounterDumpingLock); - return -EIO; - } - - ui32NumOfRegs = *pui32PowerBuffer++; - ui32SamplePeriod = *pui32PowerBuffer++; - - if (ui32NumOfRegs) - { - DIPrintf(psEntry, "Power counter data for device\n"); - DIPrintf(psEntry, "Sample period: 0x%08x\n", ui32SamplePeriod); - - for (i = 0; i < ui32NumOfRegs; i++) - { - IMG_UINT32 ui32High, ui32Low; - IMG_UINT32 ui32RegOffset = *pui32PowerBuffer++; - IMG_UINT32 ui32NumOfInstances = *pui32PowerBuffer++; - - PVR_ASSERT(ui32NumOfInstances); - - DIPrintf(psEntry, "0x%08x:", ui32RegOffset); - - for (j = 0; j < ui32NumOfInstances; j++) - { - ui32Low = *pui32PowerBuffer++; - ui32High = *pui32PowerBuffer++; - - DIPrintf(psEntry, " 0x%016llx", - (IMG_UINT64) ui32Low | (IMG_UINT64) ui32High << 32); - } - - DIPrintf(psEntry, "\n"); - } - } - - DevmemReleaseCpuVirtAddr(psDevInfo->psCounterBufferMemDesc); - } - - OSLockRelease(psDevInfo->hCounterDumpingLock); - - return eError; -} - -static IMG_INT64 PowerDataSet(const IMG_CHAR __user *pcBuffer, - IMG_UINT64 ui64Count, IMG_UINT64 *pui64Pos, - void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_COUNTER_DUMP_REQUEST eRequest; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO); - PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO); - PVR_RETURN_IF_FALSE(ui64Count >= 1, -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL); - - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - PVR_DPF((PVR_DBG_ERROR, "Device not initialised when " - "power counter data was requested!")); - return -EIO; - } - - if (pcBuffer[0] == '1') - { - eRequest = RGXFWIF_PWR_COUNTER_DUMP_START; - } - else if (pcBuffer[0] == '0') - { - eRequest = RGXFWIF_PWR_COUNTER_DUMP_STOP; - } - else - { - return -EINVAL; - } - - OSLockAcquire(psDevInfo->hCounterDumpingLock); - - SendPowerCounterCommand(psDeviceNode, - eRequest, - &ui32kCCBCommandSlot); - - OSLockRelease(psDevInfo->hCounterDumpingLock); - - *pui64Pos += ui64Count; - return ui64Count; -} - -#endif /* defined(SUPPORT_RGX) && defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) */ - -/*************************************************************************/ /*! - Status DebugFS entry -*/ /**************************************************************************/ - -static void *_DebugStatusCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode, - va_list va) -{ - IMG_UINT64 *pui64CurrentPosition = va_arg(va, IMG_UINT64 *); - IMG_UINT64 ui64Position = va_arg(va, IMG_UINT64); - IMG_UINT64 ui64CurrentPosition = *pui64CurrentPosition; - - (*pui64CurrentPosition)++; - - return (ui64CurrentPosition == ui64Position) ? psDevNode : NULL; -} - -static void *_DebugStatusDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos) -{ - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - IMG_UINT64 uiCurrentPosition = 1; - PVRSRV_DEVICE_NODE *psDeviceNode; - - if (*pui64Pos == 0) - { - return DI_START_TOKEN; - } - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList, - _DebugStatusCompare_AnyVaCb, - &uiCurrentPosition, - *pui64Pos); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - return psDeviceNode; -} - -static void _DebugStatusDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVR_UNREFERENCED_PARAMETER(psEntry); - PVR_UNREFERENCED_PARAMETER(pvData); -} - -static void *_DebugStatusDINext(OSDI_IMPL_ENTRY *psEntry, - void *pvData, - IMG_UINT64 *pui64Pos) -{ - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - IMG_UINT64 uiCurrentPosition = 1; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PVR_UNREFERENCED_PARAMETER(pvData); - - (*pui64Pos)++; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList, - _DebugStatusCompare_AnyVaCb, - &uiCurrentPosition, - *pui64Pos); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - return psDeviceNode; -} - -static int _DebugStatusDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - if (pvData == DI_START_TOKEN) - { - PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry); - - if (psPVRSRVData != NULL) - { - switch (psPVRSRVData->eServicesState) - { - case PVRSRV_SERVICES_STATE_OK: - DIPrintf(psEntry, "Driver Status: OK\n"); - break; - case PVRSRV_SERVICES_STATE_BAD: - DIPrintf(psEntry, "Driver Status: BAD\n"); - break; - case PVRSRV_SERVICES_STATE_UNDEFINED: - DIPrintf(psEntry, "Driver Status: UNDEFINED\n"); - break; - default: - DIPrintf(psEntry, "Driver Status: UNKNOWN (%d)\n", - psPVRSRVData->eServicesState); - break; - } - } - } - else if (pvData != NULL) - { - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; - IMG_CHAR *pszStatus = ""; - IMG_CHAR *pszReason = ""; - PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus; - PVRSRV_DEVICE_HEALTH_REASON eHealthReason; - - DIPrintf(psEntry, "\nDevice ID: %u:%d\n", psDeviceNode->sDevId.ui32InternalID, - psDeviceNode->sDevId.i32OsDeviceID); - - /* Update the health status now if possible... */ - if (psDeviceNode->pfnUpdateHealthStatus) - { - psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, IMG_FALSE); - } - eHealthStatus = OSAtomicRead(&psDeviceNode->eHealthStatus); - eHealthReason = OSAtomicRead(&psDeviceNode->eHealthReason); - - switch (eHealthStatus) - { - case PVRSRV_DEVICE_HEALTH_STATUS_OK: pszStatus = "OK"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING: pszStatus = "NOT RESPONDING"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_DEAD: pszStatus = "DEAD"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_FAULT: pszStatus = "FAULT"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED: pszStatus = "UNDEFINED"; break; - default: pszStatus = "UNKNOWN"; break; - } - - switch (eHealthReason) - { - case PVRSRV_DEVICE_HEALTH_REASON_NONE: pszReason = ""; break; - case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED: pszReason = " (Asserted)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING: pszReason = " (Poll failing)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS: pszReason = " (Global Event Object timeouts rising)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT: pszReason = " (KCCB offset invalid)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED: pszReason = " (KCCB stalled)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_IDLING: pszReason = " (Idling)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_RESTARTING: pszReason = " (Restarting)"; break; - case PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS: pszReason = " (Missing interrupts)"; break; - default: pszReason = " (Unknown reason)"; break; - } - - DIPrintf(psEntry, "Firmware Status: %s%s\n", pszStatus, pszReason); - if (PVRSRV_ERROR_LIMIT_REACHED) - { - DIPrintf(psEntry, "Server Errors: %d+\n", IMG_UINT32_MAX); - } - else - { - DIPrintf(psEntry, "Server Errors: %d\n", PVRSRV_KM_ERRORS); - } - - - /* Write other useful stats to aid the test cycle... */ - if (psDeviceNode->pvDevice != NULL) - { -#ifdef SUPPORT_RGX - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const RGXFWIF_HWRINFOBUF *psHWRInfoBuf = psDevInfo->psRGXFWIfHWRInfoBufCtl; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - -#ifdef PVRSRV_DEBUG_LISR_EXECUTION - /* Show the detected #LISR, #MISR scheduled calls */ - DIPrintf(psEntry, "RGX #LISR: %llu\n", psDeviceNode->ui64nLISR); - DIPrintf(psEntry, "RGX #MISR: %llu\n", psDeviceNode->ui64nMISR); -#endif /* PVRSRV_DEBUG_LISR_EXECUTION */ - - /* Calculate the number of HWR events in total across all the DMs... */ - if (psHWRInfoBuf != NULL) - { - IMG_UINT32 ui32HWREventCount = 0; - IMG_UINT32 ui32CRREventCount = 0; - IMG_UINT32 ui32DMIndex; - - for (ui32DMIndex = 0; ui32DMIndex < RGXFWIF_DM_MAX; ui32DMIndex++) - { - ui32HWREventCount += psHWRInfoBuf->aui32HwrDmLockedUpCount[ui32DMIndex]; - ui32CRREventCount += psHWRInfoBuf->aui32HwrDmOverranCount[ui32DMIndex]; - } - - DIPrintf(psEntry, "HWR Event Count: %d\n", ui32HWREventCount); - DIPrintf(psEntry, "CRR Event Count: %d\n", ui32CRREventCount); -#ifdef PVRSRV_STALLED_CCB_ACTION - /* Write the number of Sync Lockup Recovery (SLR) events... */ - DIPrintf(psEntry, "SLR Event Count: %d\n", psDevInfo->psRGXFWIfFwOsData->ui32ForcedUpdatesRequested); -#endif /* PVRSRV_STALLED_CCB_ACTION */ - } - - /* Show error counts */ - DIPrintf(psEntry, "WGP Error Count: %d\n", psDevInfo->sErrorCounts.ui32WGPErrorCount); - DIPrintf(psEntry, "TRP Error Count: %d\n", psDevInfo->sErrorCounts.ui32TRPErrorCount); - - /* - * Guest drivers do not support the following functionality: - * - Perform actual on-chip fw tracing. - * - Collect actual on-chip GPU utilization stats. - * - Perform actual on-chip GPU power/dvfs management. - * - As a result no more information can be provided. - */ - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - if (psFwSysData != NULL) - { - DIPrintf(psEntry, "FWF Event Count: %d\n", psFwSysData->ui32FWFaults); - } - - /* Write the number of APM events... */ - DIPrintf(psEntry, "APM Event Count: %d\n", psDevInfo->ui32ActivePMReqTotal); - - /* Write the current GPU Utilisation values... */ - if (psDevInfo->pfnGetGpuUtilStats && - eHealthStatus == PVRSRV_DEVICE_HEALTH_STATUS_OK) - { - RGXFWIF_GPU_UTIL_STATS sGpuUtilStats; - PVRSRV_ERROR eError = PVRSRV_OK; - - eError = psDevInfo->pfnGetGpuUtilStats(psDeviceNode, - ghGpuUtilUserDebugFS, - &sGpuUtilStats); - - if ((eError == PVRSRV_OK) && - ((IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative)) - { - IMG_UINT64 util; - IMG_UINT32 rem; - - util = 100 * sGpuUtilStats.ui64GpuStatActive; - util = OSDivide64(util, (IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative, &rem); - - DIPrintf(psEntry, "GPU Utilisation: %u%%\n", (IMG_UINT32)util); - } - else - { - DIPrintf(psEntry, "GPU Utilisation: -\n"); - } - } - } -#endif /* SUPPORT_RGX */ - } - } - - return 0; -} - -static IMG_INT64 DebugStatusSet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO); - PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO); - PVR_RETURN_IF_FALSE(ui64Count >= 1, -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[0] == 'k' || pcBuffer[0] == 'K', -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL); - - psPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_BAD; - - *pui64Pos += ui64Count; - return ui64Count; -} - -/*************************************************************************/ /*! - Dump Debug DebugFS entry -*/ /**************************************************************************/ - -static int _DebugDumpDebugDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - - PVR_UNREFERENCED_PARAMETER(pvData); - - if (psDeviceNode->pvDevice != NULL) - { - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, - _DumpDebugDIPrintfWrapper, psEntry); - } - - return 0; -} - -#ifdef SUPPORT_RGX - -/*************************************************************************/ /*! - Firmware Trace DebugFS entry -*/ /**************************************************************************/ - -static int _DebugFWTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (psDevInfo != NULL) - { - RGXDumpFirmwareTrace(_DumpDebugDIPrintfWrapper, psEntry, psDevInfo); - } - - return 0; -} - -/*************************************************************************/ /*! - Firmware Translated Page Tables DebugFS entry -*/ /**************************************************************************/ - -static void _DocumentFwMapping(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FwVA, - IMG_CPU_PHYADDR sCpuPA, - IMG_DEV_PHYADDR sDevPA, - IMG_UINT64 ui64PTE) -{ -#if defined(RGX_FEATURE_MIPS_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - DIPrintf(psEntry, "| 0x%8X | " - "0x%16" IMG_UINT64_FMTSPECX " | " - "0x%16" IMG_UINT64_FMTSPECX " | " - "%s%s%s |\n", - ui32FwVA, - (IMG_UINT64) sCpuPA.uiAddr, - sDevPA.uiAddr, - gapszMipsPermissionPTFlags[RGXMIPSFW_TLB_GET_INHIBIT(ui64PTE)], - gapszMipsDirtyGlobalValidPTFlags[RGXMIPSFW_TLB_GET_DGV(ui64PTE)], - gapszMipsCoherencyPTFlags[RGXMIPSFW_TLB_GET_COHERENCY(ui64PTE)]); - } - else -#endif - { - /* META and RISCV use a subset of the GPU's virtual address space */ - DIPrintf(psEntry, "| 0x%8X | " - "0x%16" IMG_UINT64_FMTSPECX " | " - "0x%16" IMG_UINT64_FMTSPECX " | " - "%s%s%s%s%s%s |\n", - ui32FwVA, - (IMG_UINT64) sCpuPA.uiAddr, - sDevPA.uiAddr, - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN) ? "P" : " ", - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_PM_SRC_EN) ? "PM" : " ", -#if defined(RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN) - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN) ? "B" : " ", -#else - " ", -#endif - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_CC_EN) ? "C" : " ", - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_READ_ONLY_EN) ? "RO" : "RW", - BITMASK_HAS(ui64PTE, RGX_MMUCTRL_PT_DATA_VALID_EN) ? "V" : " "); - } -} - -static int _FirmwareMappingsDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32FwVA; - IMG_UINT32 ui32FwPageSize; - IMG_UINT32 ui32OSID; - - psDeviceNode = DIGetPrivData(psEntry); - - if ((psDeviceNode == NULL) || - (psDeviceNode->pvDevice == NULL) || - (((PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice)->psKernelMMUCtx == NULL)) - { - /* The Kernel MMU context containing the Firmware mappings is not initialised */ - return 0; - } - - psDevInfo = psDeviceNode->pvDevice; - - DIPrintf(psEntry, "+-----------------+------------------------+------------------------+--------------+\n" - "| Firmware | CPU | Device | PTE |\n" - "| Virtual Address | Physical Address | Physical Address | Flags |\n" - "+-----------------+------------------------+------------------------+ +\n"); - -#if defined(RGX_FEATURE_MIPS_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - DIPrintf(psEntry, "| RI/XI = Read / Execution Inhibit |\n" - "| C = Cache Coherent |\n" - "| D = Dirty Page Table Entry |\n" - "| V = Valid Page Table Entry |\n" - "| G = Global Page Table Entry |\n" - "+-----------------+------------------------+------------------------+--------------+\n"); - - /* MIPS uses the same page size as the OS */ - ui32FwPageSize = OSGetPageSize(); - } - else -#endif - { - DIPrintf(psEntry, "| P = Pending Page Table Entry |\n" - "| PM = Parameter Manager Source |\n" - "| B = Bypass SLC |\n" - "| C = Cache Coherent |\n" - "| RW/RO = Device Access Rights |\n" - "| V = Valid Page Table Entry |\n" - "+-----------------+------------------------+------------------------+--------------+\n"); - - ui32FwPageSize = BIT(RGX_MMUCTRL_PAGE_4KB_RANGE_SHIFT); - } - - for (ui32OSID = 0; ui32OSID < RGX_NUM_OS_SUPPORTED; ui32OSID++) - { - IMG_UINT32 ui32FwHeapBase = (IMG_UINT32) ((RGX_FIRMWARE_RAW_HEAP_BASE + - (ui32OSID * RGX_FIRMWARE_RAW_HEAP_SIZE)) & UINT_MAX); - IMG_UINT32 ui32FwHeapEnd = ui32FwHeapBase + (IMG_UINT32) (RGX_FIRMWARE_RAW_HEAP_SIZE & UINT_MAX); - - DIPrintf(psEntry, "| OS ID %u |\n" - "+-----------------+------------------------+------------------------+--------------+\n", ui32OSID); - - for (ui32FwVA = ui32FwHeapBase; - ui32FwVA < ui32FwHeapEnd; - ui32FwVA += ui32FwPageSize) - { - PVRSRV_ERROR eError; - IMG_UINT64 ui64PTE = 0U; - IMG_CPU_PHYADDR sCpuPA = {0U}; - IMG_DEV_PHYADDR sDevPA = {0U}; - - eError = RGXGetFwMapping(psDevInfo, ui32FwVA, &sCpuPA, &sDevPA, &ui64PTE); - - if (eError == PVRSRV_OK) - { - _DocumentFwMapping(psEntry, psDevInfo, ui32FwVA, sCpuPA, sDevPA, ui64PTE); - } - else if (eError != PVRSRV_ERROR_DEVICEMEM_NO_MAPPING) - { - PVR_LOG_ERROR(eError, "RGXGetFwMapping"); - return -EIO; - } - } - - DIPrintf(psEntry, "+-----------------+------------------------+------------------------+--------------+\n"); - - if (PVRSRV_VZ_MODE_IS(NATIVE)) - { - break; - } - } - - return 0; -} - -#ifdef SUPPORT_FIRMWARE_GCOV - -static void *_FirmwareGcovDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (psDevInfo != NULL) - { - if (psDevInfo->psFirmwareGcovBufferMemDesc != NULL) - { - void *pvCpuVirtAddr; - DevmemAcquireCpuVirtAddr(psDevInfo->psFirmwareGcovBufferMemDesc, &pvCpuVirtAddr); - return *pui64Pos ? NULL : pvCpuVirtAddr; - } - } - - return NULL; -} - -static void _FirmwareGcovDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(pvData); - - if (psDevInfo != NULL) - { - if (psDevInfo->psFirmwareGcovBufferMemDesc != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psFirmwareGcovBufferMemDesc); - } - } -} - -static void *_FirmwareGcovDINext(OSDI_IMPL_ENTRY *psEntry, - void *pvData, - IMG_UINT64 *pui64Pos) -{ - PVR_UNREFERENCED_PARAMETER(psEntry); - PVR_UNREFERENCED_PARAMETER(pvData); - PVR_UNREFERENCED_PARAMETER(pui64Pos); - return NULL; -} - -static int _FirmwareGcovDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (psDevInfo != NULL) - { - DIWrite(psEntry, pvData, psDevInfo->ui32FirmwareGcovSize); - } - return 0; -} - -#endif /* SUPPORT_FIRMWARE_GCOV */ - -#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS - -/*************************************************************************/ /*! - Power monitoring DebugFS entry -*/ /**************************************************************************/ - -static int _PowMonTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(pvData); - - if (psDevInfo != NULL) - { - RGXDumpPowerMonitoring(_DumpDebugDIPrintfWrapper, psEntry, psDevInfo); - } - - return 0; -} - -#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */ - -#ifdef SUPPORT_VALIDATION - -#ifndef SYS_RGX_DEV_UNMAPPED_FW_REG -#define SYS_RGX_DEV_UNMAPPED_FW_REG 0XFFFFFFFF -#endif -#define DI_RGXREGS_TIMEOUT_MS 1000 - -/*************************************************************************/ /*! - RGX Registers Dump DebugFS entry -*/ /**************************************************************************/ - -static IMG_INT64 _RgxRegsSeek(IMG_UINT64 ui64Offset, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -1); - - psDevInfo = psDeviceNode->pvDevice; - - PVR_LOG_RETURN_IF_FALSE(ui64Offset <= (psDevInfo->ui32RegSize - 4), - "register offset is too big", -1); - - return ui64Offset; -} - -static IMG_INT64 _RgxRegsRead(IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT64 ui64RegVal = 0; - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT64 ui64CompRes; - - PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -ENXIO); - PVR_LOG_RETURN_IF_FALSE(ui64Count == 4 || ui64Count == 8, - "wrong RGX register size", -EIO); - PVR_LOG_RETURN_IF_FALSE(!(*pui64Pos & (ui64Count - 1)), - "register read offset isn't aligned", -EINVAL); - - psDevInfo = psDeviceNode->pvDevice; - - if (*pui64Pos >= SYS_RGX_DEV_UNMAPPED_FW_REG) - { - if (!psDevInfo->bFirmwareInitialised) - { - PVR_DPF((PVR_DBG_ERROR, "RGX Register offset is above PCI mapped range but " - "Firmware isn't yet initialised\n")); - return -EIO; - } - - reinit_completion(&psDevInfo->sFwRegs.sRegComp); - - eError = RGXScheduleRgxRegCommand(psDevInfo, - 0x00, - ui64Count, - (IMG_UINT32) *pui64Pos, - IMG_FALSE); - - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "RGXScheduleRgxRegCommand"); - return -EIO; - } - - ui64CompRes = wait_for_completion_timeout(&psDevInfo->sFwRegs.sRegComp, - msecs_to_jiffies(DI_RGXREGS_TIMEOUT_MS)); - if (!ui64CompRes) - { - PVR_DPF((PVR_DBG_ERROR, "FW RGX Register access timeout %#x\n", - (IMG_UINT32) *pui64Pos)); - return -EIO; - } - - OSCachedMemCopy(pcBuffer, &psDevInfo->sFwRegs.ui64RegVal, ui64Count); - } - else - { - ui64RegVal = ui64Count == 4 ? - OSReadHWReg32(psDevInfo->pvRegsBaseKM, *pui64Pos) : - OSReadHWReg64(psDevInfo->pvRegsBaseKM, *pui64Pos); - OSCachedMemCopy(pcBuffer, &ui64RegVal, ui64Count); - } - - return ui64Count; -} - -static IMG_INT64 _RgxRegsWrite(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT64 ui64RegVal = 0; - PVRSRV_RGXDEV_INFO *psDevInfo; - - /* ignore the '\0' character */ - ui64Count -= 1; - - PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -ENXIO); - PVR_LOG_RETURN_IF_FALSE(ui64Count == 4 || ui64Count == 8, - "wrong RGX register size", -EIO); - PVR_LOG_RETURN_IF_FALSE(!(*pui64Pos & (ui64Count - 1)), - "register read offset isn't aligned", -EINVAL); - - psDevInfo = psDeviceNode->pvDevice; - - if (*pui64Pos >= SYS_RGX_DEV_UNMAPPED_FW_REG) - { - if (!psDevInfo->bFirmwareInitialised) - { - PVR_DPF((PVR_DBG_ERROR, "RGX Register offset is above PCI mapped range but " - "Firmware isn't yet initialised\n")); - return -EIO; - } - - if (ui64Count == 4) - ui64RegVal = (IMG_UINT64) *((IMG_UINT32 *) pcBuffer); - else - ui64RegVal = *((IMG_UINT64 *) pcBuffer); - - eError = RGXScheduleRgxRegCommand(psDevInfo, - ui64RegVal, - ui64Count, - (IMG_UINT32) *pui64Pos, - IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "RGXScheduleRgxRegCommand"); - return -EIO; - } - - } - else - { - if (ui64Count == 4) - { - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, *pui64Pos, - *((IMG_UINT32 *) (void *) pcBuffer)); - } - else - { - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, *pui64Pos, - *((IMG_UINT64 *) (void *) pcBuffer)); - } - } - - return ui64Count; -} - -#endif /* SUPPORT_VALIDATION */ - -#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB) -#define RISCV_DMI_SIZE (8U) - -static IMG_INT64 _RiscvDmiRead(IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; - PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo; - - ui64Count = MIN(RISCV_DMI_SIZE, ui64Count); - memcpy(pcBuffer, &psDebugInfo->ui64RiscvDmi, ui64Count); - - return ui64Count; -} - -static IMG_INT64 _RiscvDmiWrite(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo; - - if (psDevInfo == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: devinfo is NULL", __func__)); - return 0; - } - - ui64Count -= 1; /* Drop `\0` */ - ui64Count = MIN(RISCV_DMI_SIZE, ui64Count); - - memcpy(&psDebugInfo->ui64RiscvDmi, pcBuffer, ui64Count); - - RGXRiscvDmiOp(psDevInfo, &psDebugInfo->ui64RiscvDmi); - - return ui64Count; -} -#endif - -#endif /* SUPPORT_RGX */ - -#ifdef SUPPORT_VALIDATION - -static int TestMemLeakDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - PVR_UNREFERENCED_PARAMETER(pvData); - - PVR_RETURN_IF_FALSE(pvData != NULL, -EINVAL); - - DIPrintf(psEntry, "os: %s, %u\ngpu: %s, %u\nmmu: %s, %u\n", - psPVRSRVData->sMemLeakIntervals.ui32OSAlloc ? "enabled" : "disabled", - psPVRSRVData->sMemLeakIntervals.ui32OSAlloc, - psPVRSRVData->sMemLeakIntervals.ui32GPU ? "enabled" : "disabled", - psPVRSRVData->sMemLeakIntervals.ui32GPU, - psPVRSRVData->sMemLeakIntervals.ui32MMU ? "enabled" : "disabled", - psPVRSRVData->sMemLeakIntervals.ui32MMU); - - return 0; -} - -static IMG_INT64 TestMemLeakDISet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_CHAR *pcTemp; - unsigned long ui32MemLeakInterval; - - PVR_UNREFERENCED_PARAMETER(pvData); - - PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO); - PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO); - PVR_RETURN_IF_FALSE(ui64Count <= 16, -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL); - - pcTemp = strchr(pcBuffer, ','); - - if (kstrtoul(pcTemp+1, 0, &ui32MemLeakInterval) != 0) - { - return -EINVAL; - } - - if (strncmp(pcBuffer, "os", pcTemp-pcBuffer) == 0) - { - psPVRSRVData->sMemLeakIntervals.ui32OSAlloc = ui32MemLeakInterval; - } - else if (strncmp(pcBuffer, "gpu", pcTemp-pcBuffer) == 0) - { - psPVRSRVData->sMemLeakIntervals.ui32GPU = ui32MemLeakInterval; - } - else if (strncmp(pcBuffer, "mmu", pcTemp-pcBuffer) == 0) - { - psPVRSRVData->sMemLeakIntervals.ui32MMU = ui32MemLeakInterval; - } - else - { - return -EINVAL; - } - - *pui64Pos += ui64Count; - return ui64Count; -} - -#endif /* SUPPORT_VALIDATION */ - -#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) - -/*************************************************************************/ /*! - Debug level DebugFS entry -*/ /**************************************************************************/ - -static int DebugLevelDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - DIPrintf(psEntry, "%u\n", OSDebugLevel()); - - return 0; -} - -#ifndef __GNUC__ -static int __builtin_ffsl(long int x) -{ - for (size_t i = 0; i < sizeof(x) * 8; i++) - { - if (x & (1 << i)) - { - return i + 1; - } - } - return 0; -} -#endif /* __GNUC__ */ - -static IMG_INT64 DebugLevelSet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - const IMG_UINT uiMaxBufferSize = 6; - IMG_UINT32 ui32Level; - - PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO); - PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO); - PVR_RETURN_IF_FALSE(ui64Count > 0 && ui64Count < uiMaxBufferSize, -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL); - - if (sscanf(pcBuffer, "%u", &ui32Level) == 0) - { - return -EINVAL; - } - - OSSetDebugLevel(ui32Level & ((1 << __builtin_ffsl(DBGPRIV_LAST)) - 1)); - - *pui64Pos += ui64Count; - return ui64Count; -} -#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */ - -PVRSRV_ERROR DebugCommonInitDriver(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_ERROR eError; - - PVR_ASSERT(psPVRSRVData != NULL); - - /* - * The DebugFS entries are designed to work in a single device system but - * this function will be called multiple times in a multi-device system. - * Return an error in this case. - */ - if (gpsVersionDIEntry) - { - return -EEXIST; - } - -#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE) - if (SORgxGpuUtilStatsRegister(&ghGpuUtilUserDebugFS) != PVRSRV_OK) - { - return -ENOMEM; - } -#endif /* defined(SUPPORT_RGX) && !defined(NO_HARDWARE) */ - - { - DI_ITERATOR_CB sIterator = { - .pfnStart = _VersionDIStart, - .pfnStop = _VersionDIStop, - .pfnNext = _VersionDINext, - .pfnShow = _VersionDIShow - }; - - eError = DICreateEntry("version", NULL, &sIterator, psPVRSRVData, - DI_ENTRY_TYPE_GENERIC, &gpsVersionDIEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - - { - DI_ITERATOR_CB sIterator = { - .pfnStart = _DebugStatusDIStart, - .pfnStop = _DebugStatusDIStop, - .pfnNext = _DebugStatusDINext, - .pfnShow = _DebugStatusDIShow, - .pfnWrite = DebugStatusSet, - //'K' expected + Null terminator - .ui32WriteLenMax= ((1U)+1U) - }; - eError = DICreateEntry("status", NULL, &sIterator, psPVRSRVData, - DI_ENTRY_TYPE_GENERIC, &gpsStatusDIEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - -#ifdef SUPPORT_VALIDATION - { - DI_ITERATOR_CB sIterator = { - .pfnShow = TestMemLeakDIShow, - .pfnWrite = TestMemLeakDISet, - //Function only allows max 15 chars + Null terminator - .ui32WriteLenMax = ((15U)+1U) - }; - eError = DICreateEntry("test_memleak", NULL, &sIterator, psPVRSRVData, - DI_ENTRY_TYPE_GENERIC, &gpsTestMemLeakDIEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* SUPPORT_VALIDATION */ - -#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) - { - DI_ITERATOR_CB sIterator = { - .pfnShow = DebugLevelDIShow, - .pfnWrite = DebugLevelSet, - //Max value of 255(3 char) + Null terminator - .ui32WriteLenMax =((3U)+1U) - }; - eError = DICreateEntry("debug_level", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &gpsDebugLevelDIEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */ - - return PVRSRV_OK; - -return_error_: - DebugCommonDeInitDriver(); - - return eError; -} - -void DebugCommonDeInitDriver(void) -{ -#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) - if (gpsDebugLevelDIEntry != NULL) - { - DIDestroyEntry(gpsDebugLevelDIEntry); - } -#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */ - -#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE) - if (ghGpuUtilUserDebugFS != NULL) - { - SORgxGpuUtilStatsUnregister(ghGpuUtilUserDebugFS); - ghGpuUtilUserDebugFS = NULL; - } -#endif /* defined(SUPPORT_RGX) && !defined(NO_HARDWARE) */ - -#ifdef SUPPORT_VALIDATION - if (gpsTestMemLeakDIEntry != NULL) - { - DIDestroyEntry(gpsTestMemLeakDIEntry); - } -#endif /* SUPPORT_VALIDATION */ - - if (gpsStatusDIEntry != NULL) - { - DIDestroyEntry(gpsStatusDIEntry); - } - - if (gpsVersionDIEntry != NULL) - { - DIDestroyEntry(gpsVersionDIEntry); - } -} - -PVRSRV_ERROR DebugCommonInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo; - PVRSRV_ERROR eError; - - { - IMG_CHAR pszDeviceId[sizeof("gpu4294967296")]; - - OSSNPrintf(pszDeviceId, sizeof(pszDeviceId), "gpu%02d", - psDeviceNode->sDevId.ui32InternalID); - - eError = DICreateGroup(pszDeviceId, NULL, &psDebugInfo->psGroup); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - - { - DI_ITERATOR_CB sIterator = {.pfnShow = _DebugDumpDebugDIShow}; - eError = DICreateEntry("debug_dump", psDebugInfo->psGroup, &sIterator, - psDeviceNode, DI_ENTRY_TYPE_GENERIC, - &psDebugInfo->psDumpDebugEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - -#ifdef SUPPORT_RGX - if (! PVRSRV_VZ_MODE_IS(GUEST)) - { - { - DI_ITERATOR_CB sIterator = {.pfnShow = _DebugFWTraceDIShow}; - eError = DICreateEntry("firmware_trace", psDebugInfo->psGroup, &sIterator, - psDeviceNode, DI_ENTRY_TYPE_GENERIC, - &psDebugInfo->psFWTraceEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - -#ifdef SUPPORT_FIRMWARE_GCOV - { - DI_ITERATOR_CB sIterator = { - .pfnStart = _FirmwareGcovDIStart, - .pfnStop = _FirmwareGcovDIStop, - .pfnNext = _FirmwareGcovDINext, - .pfnShow = _FirmwareGcovDIShow - }; - - eError = DICreateEntry("firmware_gcov", psDebugInfo->psGroup, &sIterator, - psDeviceNode, DI_ENTRY_TYPE_GENERIC, - &psDebugInfo->psFWGCOVEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* SUPPORT_FIRMWARE_GCOV */ - - { - DI_ITERATOR_CB sIterator = {.pfnShow = _FirmwareMappingsDIShow}; - eError = DICreateEntry("firmware_mappings", psDebugInfo->psGroup, &sIterator, - psDeviceNode, DI_ENTRY_TYPE_GENERIC, - &psDebugInfo->psFWMappingsEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } - -#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB) - { - DI_ITERATOR_CB sIterator = { - .pfnRead = _RiscvDmiRead, - .pfnWrite = _RiscvDmiWrite, - .ui32WriteLenMax = ((RISCV_DMI_SIZE)+1U) - }; - eError = DICreateEntry("riscv_dmi", psDebugInfo->psGroup, &sIterator, psDeviceNode, - DI_ENTRY_TYPE_RANDOM_ACCESS, &psDebugInfo->psRiscvDmiDIEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - psDebugInfo->ui64RiscvDmi = 0ULL; - } -#endif /* SUPPORT_VALIDATION || SUPPORT_RISCV_GDB */ - } -#ifdef SUPPORT_VALIDATION - { - DI_ITERATOR_CB sIterator = { - .pfnSeek = _RgxRegsSeek, - .pfnRead = _RgxRegsRead, - .pfnWrite = _RgxRegsWrite, - //Max size of input binary data is 4 bytes (UINT32) or 8 bytes (UINT64) - .ui32WriteLenMax = ((8U)+1U) - }; - eError = DICreateEntry("rgxregs", psDebugInfo->psGroup, &sIterator, psDeviceNode, - DI_ENTRY_TYPE_RANDOM_ACCESS, &psDebugInfo->psRGXRegsEntry); - - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* SUPPORT_VALIDATION */ - -#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS - if (! PVRSRV_VZ_MODE_IS(GUEST)) - { - DI_ITERATOR_CB sIterator = { - .pfnShow = _PowMonTraceDIShow - }; - eError = DICreateEntry("power_mon", psDebugInfo->psGroup, &sIterator, psDeviceNode, - DI_ENTRY_TYPE_GENERIC, &psDebugInfo->psPowMonEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */ -#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS - { - DI_ITERATOR_CB sIterator = { - .pfnShow = _DebugPowerDataDIShow, - .pfnWrite = PowerDataSet, - //Expects '0' or '1' plus Null terminator - .ui32WriteLenMax = ((1U)+1U) - }; - eError = DICreateEntry("power_data", psDebugInfo->psGroup, &sIterator, psDeviceNode, - DI_ENTRY_TYPE_GENERIC, &psDebugInfo->psPowerDataEntry); - PVR_GOTO_IF_ERROR(eError, return_error_); - } -#endif /* SUPPORT_POWER_SAMPLING_VIA_DEBUGFS */ -#endif /* SUPPORT_RGX */ - - return PVRSRV_OK; - -return_error_: - DebugCommonDeInitDevice(psDeviceNode); - - return eError; -} - -void DebugCommonDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo; - -#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS - if (psDebugInfo->psPowerDataEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psPowerDataEntry); - psDebugInfo->psPowerDataEntry = NULL; - } -#endif /* SUPPORT_POWER_SAMPLING_VIA_DEBUGFS */ - -#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS - if (psDebugInfo->psPowMonEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psPowMonEntry); - psDebugInfo->psPowMonEntry = NULL; - } -#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */ - -#ifdef SUPPORT_VALIDATION - if (psDebugInfo->psRGXRegsEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psRGXRegsEntry); - psDebugInfo->psRGXRegsEntry = NULL; - } -#endif /* SUPPORT_VALIDATION */ - -#ifdef SUPPORT_RGX - if (psDebugInfo->psFWTraceEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psFWTraceEntry); - psDebugInfo->psFWTraceEntry = NULL; - } - -#ifdef SUPPORT_FIRMWARE_GCOV - if (psDebugInfo->psFWGCOVEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psFWGCOVEntry); - psDebugInfo->psFWGCOVEntry = NULL; - } -#endif - - if (psDebugInfo->psFWMappingsEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psFWMappingsEntry); - psDebugInfo->psFWMappingsEntry = NULL; - } - -#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB) - if (psDebugInfo->psRiscvDmiDIEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psRiscvDmiDIEntry); - psDebugInfo->psRiscvDmiDIEntry = NULL; - } -#endif -#endif /* SUPPORT_RGX */ - - if (psDebugInfo->psDumpDebugEntry != NULL) - { - DIDestroyEntry(psDebugInfo->psDumpDebugEntry); - psDebugInfo->psDumpDebugEntry = NULL; - } - - if (psDebugInfo->psGroup != NULL) - { - DIDestroyGroup(psDebugInfo->psGroup); - psDebugInfo->psGroup = NULL; - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/debug_common.h b/drivers/gpu/drm/img-rogue/1.17/debug_common.h deleted file mode 100644 index e8b902f47114a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/debug_common.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common debug definitions and functions. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEBUG_COMMON_H -#define DEBUG_COMMON_H - -#include "pvrsrv_error.h" -#include "device.h" - -PVRSRV_ERROR DebugCommonInitDriver(void); -void DebugCommonDeInitDriver(void); - -PVRSRV_ERROR DebugCommonInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode); -void DebugCommonDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* DEBUG_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/device.h b/drivers/gpu/drm/img-rogue/1.17/device.h deleted file mode 100644 index f5948d773cc12..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/device.h +++ /dev/null @@ -1,540 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Common Device header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device related function templates and defines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICE_H -#define DEVICE_H - -#include "devicemem_heapcfg.h" -#include "mmu_common.h" -#include "ra.h" /* RA_ARENA */ -#include "pvrsrv_device.h" -#include "sync_checkpoint.h" -#include "srvkm.h" -#include "physheap.h" -#include "sync_internal.h" -#include "sysinfo.h" -#include "dllist.h" - -#include "rgx_bvnc_defs_km.h" - -#include "lock.h" - -#include "power.h" - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -typedef struct _PVRSRV_POWER_DEV_TAG_ *PPVRSRV_POWER_DEV; - -struct SYNC_RECORD; - -struct _CONNECTION_DATA_; - -/*************************************************************************/ /*! - @Function AllocUFOBlockCallback - @Description Device specific callback for allocation of a UFO block - - @Input psDeviceNode Pointer to device node to allocate - the UFO for. - @Output ppsMemDesc Pointer to pointer for the memdesc of - the allocation - @Output pui32SyncAddr FW Base address of the UFO block - @Output puiSyncPrimBlockSize Size of the UFO block - - @Return PVRSRV_OK if allocation was successful -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*AllocUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - DEVMEM_MEMDESC **ppsMemDesc, - IMG_UINT32 *pui32SyncAddr, - IMG_UINT32 *puiSyncPrimBlockSize); - -/*************************************************************************/ /*! - @Function FreeUFOBlockCallback - @Description Device specific callback for freeing of a UFO - - @Input psDeviceNode Pointer to device node that the UFO block was - allocated from. - @Input psMemDesc Pointer to pointer for the memdesc of the UFO - block to free. -*/ /**************************************************************************/ -typedef void (*FreeUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - DEVMEM_MEMDESC *psMemDesc); - -typedef struct _PVRSRV_DEVICE_IDENTIFIER_ -{ - /* Pdump memory and register bank names */ - IMG_CHAR *pszPDumpDevName; - IMG_CHAR *pszPDumpRegName; - - /* Under Linux, this is the minor number of RenderNode corresponding to this Device */ - IMG_INT32 i32OsDeviceID; - /* Services layer enumeration of the device used in pvrdebug */ - IMG_UINT32 ui32InternalID; -} PVRSRV_DEVICE_IDENTIFIER; - -typedef struct _DEVICE_MEMORY_INFO_ -{ - /* Heap count. Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */ - IMG_UINT32 ui32HeapCount; - - /* Blueprints for creating new device memory contexts */ - IMG_UINT32 uiNumHeapConfigs; - DEVMEM_HEAP_CONFIG *psDeviceMemoryHeapConfigArray; - DEVMEM_HEAP_BLUEPRINT *psDeviceMemoryHeap; -} DEVICE_MEMORY_INFO; - -#define MMU_BAD_PHYS_ADDR (0xbadbad00badULL) -#define DUMMY_PAGE ("DUMMY_PAGE") -#define DEV_ZERO_PAGE ("DEV_ZERO_PAGE") -#define PVR_DUMMY_PAGE_INIT_VALUE (0x0) -#define PVR_ZERO_PAGE_INIT_VALUE (0x0) - -typedef struct __DEFAULT_PAGE__ -{ - /*Page handle for the page allocated (UMA/LMA)*/ - PG_HANDLE sPageHandle; - POS_LOCK psPgLock; - ATOMIC_T atRefCounter; - /*Default page size in terms of log2 */ - IMG_UINT32 ui32Log2PgSize; - IMG_UINT64 ui64PgPhysAddr; -#if defined(PDUMP) - IMG_HANDLE hPdumpPg; -#endif -} PVRSRV_DEF_PAGE; - -typedef enum _PVRSRV_DEVICE_STATE_ -{ - PVRSRV_DEVICE_STATE_UNDEFINED = 0, - PVRSRV_DEVICE_STATE_INIT, - PVRSRV_DEVICE_STATE_ACTIVE, - PVRSRV_DEVICE_STATE_DEINIT, - PVRSRV_DEVICE_STATE_BAD, -} PVRSRV_DEVICE_STATE; - -typedef enum _PVRSRV_DEVICE_HEALTH_STATUS_ -{ - PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED = 0, - PVRSRV_DEVICE_HEALTH_STATUS_OK, - PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING, - PVRSRV_DEVICE_HEALTH_STATUS_DEAD, - PVRSRV_DEVICE_HEALTH_STATUS_FAULT -} PVRSRV_DEVICE_HEALTH_STATUS; - -typedef enum _PVRSRV_DEVICE_HEALTH_REASON_ -{ - PVRSRV_DEVICE_HEALTH_REASON_NONE = 0, - PVRSRV_DEVICE_HEALTH_REASON_ASSERTED, - PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING, - PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS, - PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT, - PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED, - PVRSRV_DEVICE_HEALTH_REASON_IDLING, - PVRSRV_DEVICE_HEALTH_REASON_RESTARTING, - PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS -} PVRSRV_DEVICE_HEALTH_REASON; - -typedef enum _PVRSRV_DEVICE_DEBUG_DUMP_STATUS_ -{ - PVRSRV_DEVICE_DEBUG_DUMP_NONE = 0, - PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE -} PVRSRV_DEVICE_DEBUG_DUMP_STATUS; - -#ifndef DI_GROUP_DEFINED -#define DI_GROUP_DEFINED -typedef struct DI_GROUP DI_GROUP; -#endif -#ifndef DI_ENTRY_DEFINED -#define DI_ENTRY_DEFINED -typedef struct DI_ENTRY DI_ENTRY; -#endif - -typedef struct _PVRSRV_DEVICE_DEBUG_INFO_ -{ - DI_GROUP *psGroup; - DI_ENTRY *psDumpDebugEntry; -#ifdef SUPPORT_RGX - DI_ENTRY *psFWTraceEntry; -#ifdef SUPPORT_FIRMWARE_GCOV - DI_ENTRY *psFWGCOVEntry; -#endif - DI_ENTRY *psFWMappingsEntry; -#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB) - DI_ENTRY *psRiscvDmiDIEntry; - IMG_UINT64 ui64RiscvDmi; -#endif -#endif /* SUPPORT_RGX */ -#ifdef SUPPORT_VALIDATION - DI_ENTRY *psRGXRegsEntry; -#endif /* SUPPORT_VALIDATION */ -#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS - DI_ENTRY *psPowMonEntry; -#endif -#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS - DI_ENTRY *psPowerDataEntry; -#endif -} PVRSRV_DEVICE_DEBUG_INFO; - -#if defined(PVRSRV_DEBUG_LISR_EXECUTION) -#define RGX_LISR_INIT (0U) -#define RGX_LISR_DEVICE_NOT_POWERED (1U) -#define RGX_LISR_NOT_TRIGGERED_BY_HW (2U) -#define RGX_LISR_FW_IRQ_COUNTER_NOT_UPDATED (3U) -#define RGX_LISR_PROCESSED (4U) - -typedef IMG_UINT32 LISR_STATUS; - -typedef struct _LISR_EXECUTION_INFO_ -{ - /* status of last LISR invocation */ - LISR_STATUS ui32Status; - - /* snapshot from the last LISR invocation */ -#if defined(RGX_FW_IRQ_OS_COUNTERS) - IMG_UINT32 aui32InterruptCountSnapshot[RGX_NUM_OS_SUPPORTED]; -#else - IMG_UINT32 aui32InterruptCountSnapshot[RGXFW_THREAD_NUM]; -#endif - - /* time of the last LISR invocation */ - IMG_UINT64 ui64Clockns; -} LISR_EXECUTION_INFO; - -#define UPDATE_LISR_DBG_STATUS(status) psDeviceNode->sLISRExecutionInfo.ui32Status = (status) -#define UPDATE_LISR_DBG_SNAPSHOT(idx, val) psDeviceNode->sLISRExecutionInfo.aui32InterruptCountSnapshot[idx] = (val) -#define UPDATE_LISR_DBG_TIMESTAMP() psDeviceNode->sLISRExecutionInfo.ui64Clockns = OSClockns64() -#define UPDATE_LISR_DBG_COUNTER() psDeviceNode->ui64nLISR++ -#define UPDATE_MISR_DBG_COUNTER() psDeviceNode->ui64nMISR++ -#else -#define UPDATE_LISR_DBG_STATUS(status) -#define UPDATE_LISR_DBG_SNAPSHOT(idx, val) -#define UPDATE_LISR_DBG_TIMESTAMP() -#define UPDATE_LISR_DBG_COUNTER() -#define UPDATE_MISR_DBG_COUNTER() -#endif /* defined(PVRSRV_DEBUG_LISR_EXECUTION) */ - -typedef struct _PVRSRV_DEVICE_NODE_ -{ - PVRSRV_DEVICE_IDENTIFIER sDevId; - - PVRSRV_DEVICE_STATE eDevState; - PVRSRV_DEVICE_FABRIC_TYPE eDevFabricType; - - ATOMIC_T eHealthStatus; /* Holds values from PVRSRV_DEVICE_HEALTH_STATUS */ - ATOMIC_T eHealthReason; /* Holds values from PVRSRV_DEVICE_HEALTH_REASON */ - ATOMIC_T eDebugDumpRequested; /* Holds values from PVRSRV_DEVICE_DEBUG_DUMP_STATUS */ - - IMG_HANDLE *hDebugTable; - - /* device specific MMU attributes */ - MMU_DEVICEATTRIBS *psMMUDevAttrs; - /* Device specific MMU firmware attributes, used only in some devices */ - MMU_DEVICEATTRIBS *psFirmwareMMUDevAttrs; - - PHYS_HEAP *psMMUPhysHeap; - - /* lock for power state transitions */ - POS_LOCK hPowerLock; - IMG_PID uiPwrLockOwnerPID; /* Only valid between lock and corresponding unlock - operations of hPowerLock */ - - /* current system device power state */ - PVRSRV_SYS_POWER_STATE eCurrentSysPowerState; - PPVRSRV_POWER_DEV psPowerDev; - - /* multicore configuration information */ - IMG_UINT32 ui32MultiCoreNumCores; /* total cores primary + secondaries. 0 for non-multi core */ - IMG_UINT32 ui32MultiCorePrimaryId; /* primary core id for this device */ - IMG_UINT64 *pui64MultiCoreCapabilities; /* capabilities for each core */ - - /* - callbacks the device must support: - */ - - PVRSRV_ERROR (*pfnDevSLCFlushRange)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate); - - PVRSRV_ERROR (*pfnInvalFBSCTable)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_CONTEXT *psMMUContext, - IMG_UINT64 ui64FBSCEntries); - - PVRSRV_ERROR (*pfnValidateOrTweakPhysAddrs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_DEVICEATTRIBS *psDevAttrs, - IMG_UINT64 *pui64Addr); - - void (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_CONTEXT *psMMUContext, - MMU_LEVEL eLevel, - IMG_BOOL bUnmap); - - PVRSRV_ERROR (*pfnMMUCacheInvalidateKick)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_UINT32 *pui32NextMMUInvalidateUpdate); - - IMG_UINT32 (*pfnMMUCacheGetInvalidateCounter)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - - void (*pfnDumpDebugInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - PVRSRV_ERROR (*pfnUpdateHealthStatus)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_BOOL bIsTimerPoll); - -#if defined(SUPPORT_AUTOVZ) - void (*pfnUpdateAutoVzWatchdog)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); -#endif - - PVRSRV_ERROR (*pfnValidationGPUUnitsPowerChange)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32NewState); - - PVRSRV_ERROR (*pfnResetHWRLogs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - PVRSRV_ERROR (*pfnVerifyBVNC)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64GivenBVNC, IMG_UINT64 ui64CoreIdMask); - - /* Method to drain device HWPerf packets from firmware buffer to host buffer */ - PVRSRV_ERROR (*pfnServiceHWPerf)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - PVRSRV_ERROR (*pfnDeviceVersionString)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_CHAR **ppszVersionString); - - PVRSRV_ERROR (*pfnDeviceClockSpeed)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_PUINT32 pui32RGXClockSpeed); - - PVRSRV_ERROR (*pfnSoftReset)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64ResetValue1, IMG_UINT64 ui64ResetValue2); - - PVRSRV_ERROR (*pfnAlignmentCheck)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32FWAlignChecksSize, IMG_UINT32 aui32FWAlignChecks[]); - IMG_BOOL (*pfnCheckDeviceFeature)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask); - - IMG_INT32 (*pfnGetDeviceFeatureValue)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, enum _RGX_FEATURE_WITH_VALUE_INDEX_ eFeatureIndex); - - PVRSRV_ERROR (*pfnGetMultiCoreInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32CapsSize, - IMG_UINT32 *pui32NumCores, IMG_UINT64 *pui64Caps); - - IMG_BOOL (*pfnHasFBCDCVersion31)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - MMU_DEVICEATTRIBS* (*pfnGetMMUDeviceAttributes)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_BOOL bKernelMemoryCtx); - - PVRSRV_DEVICE_CONFIG *psDevConfig; - - /* device post-finalise compatibility check */ - PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*); - - /* initialise device-specific physheaps */ - PVRSRV_ERROR (*pfnPhysMemDeviceHeapsInit) (struct _PVRSRV_DEVICE_NODE_ *); - - /* initialise fw mmu, if FW not using GPU mmu, NULL otherwise. */ - PVRSRV_ERROR (*pfnFwMMUInit) (struct _PVRSRV_DEVICE_NODE_ *); - - /* information about the device's address space and heaps */ - DEVICE_MEMORY_INFO sDevMemoryInfo; - - /* device's shared-virtual-memory heap max virtual address */ - IMG_UINT64 ui64GeneralSVMHeapTopVA; - - ATOMIC_T iNumClockSpeedChanges; - - /* private device information */ - void *pvDevice; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - RA_ARENA *psOSSharedArena; - RA_ARENA *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS]; -#endif - - /* FW_MAIN, FW_CONFIG and FW_GUEST heaps. Should be part of registered heaps? */ - PHYS_HEAP *psFWMainPhysHeap; - PHYS_HEAP *psFWCfgPhysHeap; - PHYS_HEAP *apsFWPremapPhysHeap[RGX_NUM_OS_SUPPORTED]; - - IMG_UINT32 ui32RegisteredPhysHeaps; - PHYS_HEAP **papsRegisteredPhysHeaps; - - /* PHYS_HEAP Mapping table to the platform's physical memory heap(s) - * used by this device. The physical heaps are created based on - * the PHYS_HEAP_CONFIG data from the platform's system layer at device - * creation time. - * - * Contains PVRSRV_PHYS_HEAP_LAST entries for all the possible physical heaps allowed in the design. - * It allows the system layer PhysHeaps for the device to be identified for use in creating new PMRs. - * See PhysHeapCreatePMR() - */ - PHYS_HEAP *apsPhysHeap[PVRSRV_PHYS_HEAP_LAST]; - IMG_UINT32 ui32UserAllocHeapCount; - -#if defined(SUPPORT_AUTOVZ) - /* Phys Heap reserved for storing the MMU mappings of firmware. - * The memory backing up this Phys Heap must persist between driver or OS reboots */ - PHYS_HEAP *psFwMMUReservedPhysHeap; -#endif - - /* Flag indicating if the firmware has been initialised during the - * 1st boot of the Host driver according to the AutoVz life-cycle. */ - IMG_BOOL bAutoVzFwIsUp; - - struct _PVRSRV_DEVICE_NODE_ *psNext; - struct _PVRSRV_DEVICE_NODE_ **ppsThis; - - /* Functions for notification about memory contexts */ - PVRSRV_ERROR (*pfnRegisterMemoryContext)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - MMU_CONTEXT *psMMUContext, - IMG_HANDLE *hPrivData); - void (*pfnUnregisterMemoryContext)(IMG_HANDLE hPrivData); - - /* Functions for allocation/freeing of UFOs */ - AllocUFOBlockCallback pfnAllocUFOBlock; /*!< Callback for allocation of a block of UFO memory */ - FreeUFOBlockCallback pfnFreeUFOBlock; /*!< Callback for freeing of a block of UFO memory */ - - IMG_HANDLE hSyncServerRecordNotify; - POS_LOCK hSyncServerRecordLock; - IMG_UINT32 ui32SyncServerRecordCount; - IMG_UINT32 ui32SyncServerRecordCountHighWatermark; - DLLIST_NODE sSyncServerRecordList; - struct SYNC_RECORD *apsSyncServerRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; - IMG_UINT32 uiSyncServerRecordFreeIdx; - - IMG_HANDLE hSyncCheckpointRecordNotify; - POS_LOCK hSyncCheckpointRecordLock; - IMG_UINT32 ui32SyncCheckpointRecordCount; - IMG_UINT32 ui32SyncCheckpointRecordCountHighWatermark; - DLLIST_NODE sSyncCheckpointRecordList; - struct SYNC_CHECKPOINT_RECORD *apsSyncCheckpointRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; - IMG_UINT32 uiSyncCheckpointRecordFreeIdx; - - IMG_HANDLE hSyncCheckpointNotify; - POS_SPINLOCK hSyncCheckpointListLock; /*!< Protects sSyncCheckpointSyncsList */ - DLLIST_NODE sSyncCheckpointSyncsList; - - PSYNC_CHECKPOINT_CONTEXT hSyncCheckpointContext; - PSYNC_PRIM_CONTEXT hSyncPrimContext; - - /* With this sync-prim we make sure the MMU cache is flushed - * before we free the page table memory */ - PVRSRV_CLIENT_SYNC_PRIM *psMMUCacheSyncPrim; - IMG_UINT32 ui32NextMMUInvalidateUpdate; - - IMG_HANDLE hCmdCompNotify; - IMG_HANDLE hDbgReqNotify; - IMG_HANDLE hAppHintDbgReqNotify; - IMG_HANDLE hPhysHeapDbgReqNotify; - - PVRSRV_DEF_PAGE sDummyPage; - PVRSRV_DEF_PAGE sDevZeroPage; - - POSWR_LOCK hMemoryContextPageFaultNotifyListLock; - DLLIST_NODE sMemoryContextPageFaultNotifyListHead; - - /* System DMA capability */ - IMG_BOOL bHasSystemDMA; - IMG_HANDLE hDmaTxChan; - IMG_HANDLE hDmaRxChan; - -#if defined(PDUMP) - /* - * FBC clear color register default value to use. - */ - IMG_UINT64 ui64FBCClearColour; - - /* Device-level callback which is called when pdump.exe starts. - * Should be implemented in device-specific init code, e.g. rgxinit.c - */ - PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); - /* device-level callback to return pdump ID associated to a memory context */ - IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext); - - IMG_UINT8 *pui8DeferredSyncCPSignal; /*! Deferred fence events buffer */ - - IMG_UINT16 ui16SyncCPReadIdx; /*! Read index in the above deferred fence events buffer */ - - IMG_UINT16 ui16SyncCPWriteIdx; /*! Write index in the above deferred fence events buffer */ - - POS_LOCK hSyncCheckpointSignalLock; /*! Guards data shared between an sleepable-contexts */ - - void *pvSyncCPMISR; /*! MISR to emit pending/deferred fence signals */ - - void *hTransition; /*!< SyncCheckpoint PdumpTransition Cookie */ - - DLLIST_NODE sSyncCheckpointContextListHead; /*!< List head for the sync chkpt contexts */ - - POS_LOCK hSyncCheckpointContextListLock; /*! lock for accessing sync chkpt contexts list */ - -#endif - -#if defined(SUPPORT_VALIDATION) - POS_LOCK hValidationLock; -#endif - - /* Members for linking which connections are open on this device */ - POS_LOCK hConnectionsLock; /*!< Lock protecting sConnections */ - DLLIST_NODE sConnections; /*!< The list of currently active connection objects for this device node */ - -#if defined(PVRSRV_DEBUG_LISR_EXECUTION) - LISR_EXECUTION_INFO sLISRExecutionInfo; /*!< Information about the last execution of the LISR */ - IMG_UINT64 ui64nLISR; /*!< Number of LISR calls seen */ - IMG_UINT64 ui64nMISR; /*!< Number of MISR calls made */ -#endif - - PVRSRV_DEVICE_DEBUG_INFO sDebugInfo; -} PVRSRV_DEVICE_NODE; - -/* - * Macros to be used instead of calling directly the pfns since these macros - * will expand the feature passed as argument into the bitmask/index to work - * with the macros defined in rgx_bvnc_defs_km.h - */ -#define PVRSRV_IS_FEATURE_SUPPORTED(psDevNode, Feature) \ - psDevNode->pfnCheckDeviceFeature(psDevNode, RGX_FEATURE_##Feature##_BIT_MASK) -#define PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, Feature) \ - psDevNode->pfnGetDeviceFeatureValue(psDevNode, RGX_FEATURE_##Feature##_IDX) - -PVRSRV_ERROR PVRSRVDeviceFinalise(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bInitSuccessful); - -PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); - -PVRSRV_ERROR RGXClientConnectCompatCheck_ClientAgainstFW(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32ClientBuildOptions); - - -#endif /* DEVICE_H */ - -/****************************************************************************** - End of file (device.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/device_connection.h b/drivers/gpu/drm/img-rogue/1.17/device_connection.h deleted file mode 100644 index 24917745fb560..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/device_connection.h +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************/ /*! -@File device_connection.h -@Title -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(DEVICE_CONNECTION_H) -#define DEVICE_CONNECTION_H - -#include "img_types.h" -#include "img_defs.h" - -#if defined(__KERNEL__) -typedef struct _PVRSRV_DEVICE_NODE_ *SHARED_DEV_CONNECTION; -#else -#include "connection.h" -typedef const struct PVRSRV_DEV_CONNECTION_TAG *SHARED_DEV_CONNECTION; -#endif - -/****************************************************************************** - * Device capability flags and masks - * - * Following bitmask shows allocated ranges and values for our device - * capability settings: - * - * 31 27 23 19 15 11 7 3 0 - * |...|...|...|...|...|...|...|... - * ** CACHE_COHERENT [0x1..0x2] - * x PVRSRV_CACHE_COHERENT_DEVICE_FLAG - * x. PVRSRV_CACHE_COHERENT_CPU_FLAG - * *... NONMAPPABLE_MEMORY [0x8] - * x... PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG - * *.... PDUMP_IS_RECORDING [0x10] - * x.... PVRSRV_PDUMP_IS_RECORDING - * ***........ DEVMEM_SVM_ALLOC [0x100..0x400] - * x........ PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED - * x......... PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED - * x.......... PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL - * *........... FBCDC_V3_1 [0x800] - * x........... FBCDC_V3_1_USED - * *............ PVRSRV_SYSTEM_DMA - * x............ PVRSRV_SYSTEM_DMA_USED - * |...|...|...|...|...|...|...|... - *****************************************************************************/ - -/* Flag to be passed over the bridge during connection stating whether CPU cache coherent is available*/ -#define PVRSRV_CACHE_COHERENT_SHIFT (0) -#define PVRSRV_CACHE_COHERENT_DEVICE_FLAG (1U << PVRSRV_CACHE_COHERENT_SHIFT) -#define PVRSRV_CACHE_COHERENT_CPU_FLAG (2U << PVRSRV_CACHE_COHERENT_SHIFT) -#define PVRSRV_CACHE_COHERENT_EMULATE_FLAG (4U << PVRSRV_CACHE_COHERENT_SHIFT) -#define PVRSRV_CACHE_COHERENT_MASK (7U << PVRSRV_CACHE_COHERENT_SHIFT) - -/* Flag to be passed over the bridge during connection stating whether CPU non-mappable memory is present */ -#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT (7) -#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG (1U << PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT) - -/* Flag to be passed over the bridge to indicate PDump activity */ -#define PVRSRV_PDUMP_IS_RECORDING_SHIFT (4) -#define PVRSRV_PDUMP_IS_RECORDING (1U << PVRSRV_PDUMP_IS_RECORDING_SHIFT) - -/* Flag to be passed over the bridge during connection stating SVM allocation availability */ -#define PVRSRV_DEVMEM_SVM_ALLOC_SHIFT (8) -#define PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED (1U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT) -#define PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED (2U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT) -#define PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL (4U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT) - -/* Flag to be passed over the bridge during connection stating whether GPU uses FBCDC v3.1 */ -#define PVRSRV_FBCDC_V3_1_USED_SHIFT (11) -#define PVRSRV_FBCDC_V3_1_USED (1U << PVRSRV_FBCDC_V3_1_USED_SHIFT) - -/* Flag to be passed over the bridge during connection stating whether System has - DMA transfer capability to and from device memory */ -#define PVRSRV_SYSTEM_DMA_SHIFT (12) -#define PVRSRV_SYSTEM_DMA_USED (1U << PVRSRV_SYSTEM_DMA_SHIFT) - -static INLINE IMG_HANDLE GetBridgeHandle(SHARED_DEV_CONNECTION hDevConnection) -{ -#if defined(__KERNEL__) - return hDevConnection; -#else - return hDevConnection->hServices; -#endif -} - - -#endif /* !defined(DEVICE_CONNECTION_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem.c b/drivers/gpu/drm/img-rogue/1.17/devicemem.c deleted file mode 100644 index 0f3d0bcbb4e72..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem.c +++ /dev/null @@ -1,2984 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Front End (nominally Client side part, but now invokable - from server too) of device memory management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "devicemem.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "allocmem.h" -#include "ra.h" -#include "osfunc.h" -#include "osmmap.h" -#include "devicemem_utils.h" -#include "client_mm_bridge.h" -#include "client_cache_bridge.h" -#include "services_km.h" -#include "pvrsrv_memallocflags_internal.h" - -#if defined(PDUMP) -#if defined(__KERNEL__) -#include "pdump_km.h" -#else -#include "pdump_um.h" -#endif -#include "devicemem_pdump.h" -#endif -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "client_ri_bridge.h" -#endif -#include "client_devicememhistory_bridge.h" -#include "info_page_client.h" - -#include "rgx_heaps.h" -#if defined(__KERNEL__) -#include "pvrsrv.h" -#include "rgxdefs_km.h" -#include "rgx_bvnc_defs_km.h" -#include "device.h" -#include "rgxdevice.h" -#include "pvr_ricommon.h" -#include "pvrsrv_apphint.h" -#include "oskm_apphint.h" -#include "srvcore.h" -#if defined(__linux__) -#include "linux/kernel.h" -#endif -#else -#include "srvcore_intern.h" -#include "rgxdefs.h" -#endif - -#if defined(__KERNEL__) && defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -extern PVRSRV_ERROR RIDumpAllKM(void); -#endif - -#if defined(__KERNEL__) -#define GET_ERROR_STRING(eError) PVRSRVGetErrorString(eError) -#else -#define GET_ERROR_STRING(eError) PVRSRVGetErrorString(eError) -#endif - -#if defined(__KERNEL__) -/* Derive the virtual from the hPMR */ -static -IMG_UINT64 _GetPremappedVA(PMR *psPMR, PVRSRV_DEVICE_NODE *psDevNode) -{ - PVRSRV_ERROR eError; - IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS; - - IMG_DEV_PHYADDR sDevAddr; - IMG_BOOL bValid; - PHYS_HEAP *psPhysHeap = psDevNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]; - IMG_DEV_PHYADDR sHeapAddr; - - eError = PhysHeapGetDevPAddr(psPhysHeap, &sHeapAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapGetDevPAddr", fail); - -#if defined(PVR_PMR_TRANSLATE_UMA_ADDRESSES) -{ - if (PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_UMA || - PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_DMA) - { - IMG_DEV_PHYADDR sDevPAddrCorrected; - - PhysHeapCpuPAddrToDevPAddr(psPhysHeap, 1, &sDevPAddrCorrected, (IMG_CPU_PHYADDR *)&sHeapAddr); - sHeapAddr.uiAddr = sDevPAddrCorrected.uiAddr; - } -} -#endif - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRLockSysPhysAddr", fail); - - eError = PMR_DevPhysAddr(psPMR, OSGetPageShift(), 1, 0, &sDevAddr, &bValid); - if (eError != PVRSRV_OK) - { - PVR_LOG_IF_ERROR(eError, "PMR_DevPhysAddr"); - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddr"); - goto fail; - } - - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddr"); - - ui64OptionalMapAddress = RGX_FIRMWARE_RAW_HEAP_BASE | (sDevAddr.uiAddr - sHeapAddr.uiAddr); - - PVR_DPF((PVR_DBG_ALLOC, "%s: sDevAddr.uiAddr = 0x%"IMG_UINT64_FMTSPECx" sHeapAddr.uiAddr = 0x%"IMG_UINT64_FMTSPECx" => ui64OptionalMapAddress = 0x%"IMG_UINT64_FMTSPECx, - __func__, sDevAddr.uiAddr, sHeapAddr.uiAddr, ui64OptionalMapAddress)); -fail: - return ui64OptionalMapAddress; -} -#endif - -/***************************************************************************** - * Sub allocation internals * - *****************************************************************************/ -static INLINE PVRSRV_MEMALLOCFLAGS_T -DevmemOverrideFlagsOrPassThrough(SHARED_DEV_CONNECTION hDevConnection, PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ -#if defined(__KERNEL__) && defined(RGX_FEATURE_GPU_CPU_COHERENCY) - /* - * Override the requested memory flags of FW allocations only, - * non-FW allocations pass-through unmodified. - * - * On fully coherent platforms: - * - We upgrade uncached, CPU-only cached or GPU-only cached to - * full coherency. This gives caching improvements for free. - * - * On ace-lite platforms: - * - If the allocation is not CPU cached, then there is nothing - * for the GPU to snoop regardless of the GPU cache setting. - * - If the allocation is not GPU cached, then the SLC will not - * be used and will not snoop the CPU even if it is CPU cached. - * - Therefore only the GPU setting can be upgraded to coherent - * if it is already GPU cached incoherent and the CPU is cached. - * - * All other platforms: - * - Do not modify the allocation flags. - */ - if (PVRSRV_CHECK_FW_MAIN(uiFlags)) - { - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)hDevConnection; - - if (PVRSRVSystemSnoopingOfDeviceCache(psDevNode->psDevConfig) && - PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig)) - { - /* Clear existing flags, mark the allocation as fully coherent. */ - uiFlags &= ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK); - uiFlags |= PVRSRV_MEMALLOCFLAG_CACHE_COHERENT; - } - else if ((PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) || PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags)) && - (PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags)) && - PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig) && - psDevNode->eDevFabricType == PVRSRV_DEVICE_FABRIC_ACELITE) - { - /* Upgrade the allocation from GPU cached incoherent to GPU cached coherent. */ - uiFlags &= ~PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK; - uiFlags |= PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT; - } - } -#else - PVR_UNREFERENCED_PARAMETER(hDevConnection); -#endif - - return uiFlags; -} - -static INLINE void -CheckAnnotationLength(const IMG_CHAR *pszAnnotation) -{ - IMG_UINT32 length = OSStringLength(pszAnnotation); - - if (length >= DEVMEM_ANNOTATION_MAX_LEN) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Annotation \"%s\" has been truncated to %d characters from %d characters", - __func__, pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN - 1, length)); - } -} - -static PVRSRV_ERROR -AllocateDeviceMemory(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiLog2Quantum, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_BOOL bExportable, - const IMG_CHAR *pszAnnotation, - DEVMEM_IMPORT **ppsImport) -{ - DEVMEM_IMPORT *psImport; - PVRSRV_MEMALLOCFLAGS_T uiOutFlags; - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; - - eError = DevmemImportStructAlloc(hDevConnection, - &psImport); - PVR_GOTO_IF_ERROR(eError, failAlloc); - - /* check if shift value is not too big (sizeof(1ULL)) */ - PVR_ASSERT(uiLog2Quantum < sizeof(unsigned long long) * 8); - /* Check the size is a multiple of the quantum */ - PVR_ASSERT((uiSize & ((1ULL<psImport; - SHARED_DEV_CONNECTION hDevConnection; - IMG_HANDLE hPMR; - IMG_HANDLE hSrvDevMemHeap; - POS_LOCK hLock; - IMG_HANDLE hReservation; - IMG_CPU_VIRTADDR pvCpuVAddr; - DEVMEM_PROPERTIES_T uiProperties; - - if (NULL == psImport) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Sparse memory import", __func__)); - goto e0; - } - - hDevConnection = psImport->hDevConnection; - hPMR = psImport->hPMR; - hLock = psImport->hLock; - hReservation = psImport->sDeviceImport.hReservation; - pvCpuVAddr = psImport->sCPUImport.pvCPUVAddr; - - if (NULL == hDevConnection) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Bridge handle", __func__)); - goto e0; - } - - if (NULL == hPMR) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid PMR handle", __func__)); - goto e0; - } - - if ((uiSparseFlags & SPARSE_RESIZE_BOTH) && (hReservation == LACK_OF_RESERVATION_POISON)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Device Virtual Map", __func__)); - goto e0; - } - - if ((uiSparseFlags & SPARSE_MAP_CPU_ADDR) && (NULL == pvCpuVAddr)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid CPU Virtual Map", __func__)); - goto e0; - } - - uiProperties = GetImportProperties(psMemDesc->psImport); - - if (uiProperties & DEVMEM_PROPERTIES_SECURE) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Secure buffers currently do not support sparse changes", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This memory descriptor doesn't support sparse changes", - __func__)); - eError = PVRSRV_ERROR_INVALID_REQUEST; - goto e0; - } - -#ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE - if (psMemDesc->sCPUMemDesc.ui32RefCount > 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This memory descriptor is mapped more than once (refcnt: %u)into " - "CPU Address space.\nRelease all CPU maps of this object and retry...", - __func__, psMemDesc->sCPUMemDesc.ui32RefCount)); - eError = PVRSRV_ERROR_OBJECT_STILL_REFERENCED; - goto e0; - } -#endif - - /* If we got here the validation check above for hReservation was successful - * meaning the memdesc must have been mapped. Therefore the psHeap is also - * valid. */ - PVR_ASSERT(psImport->sDeviceImport.psHeap != NULL); - - hSrvDevMemHeap = psImport->sDeviceImport.psHeap->hDevMemServerHeap; - - OSLockAcquire(hLock); - - eError = BridgeChangeSparseMem2(GetBridgeHandle(hDevConnection), - hSrvDevMemHeap, - hPMR, - ui32AllocPageCount, - paui32AllocPageIndices, - ui32FreePageCount, - pauiFreePageIndices, - uiSparseFlags, - hReservation, - (IMG_UINT64) ((uintptr_t) pvCpuVAddr)); - if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - /* Try the original bridge function */ - IMG_DEV_VIRTADDR sDevVAddr = psImport->sDeviceImport.sDevVAddr; - PVR_ASSERT(sDevVAddr.uiAddr != 0); - - eError = BridgeChangeSparseMem(GetBridgeHandle(hDevConnection), - hSrvDevMemHeap, - hPMR, - ui32AllocPageCount, - paui32AllocPageIndices, - ui32FreePageCount, - pauiFreePageIndices, - uiSparseFlags, - psImport->uiFlags, - sDevVAddr, - (IMG_UINT64) ((uintptr_t) pvCpuVAddr)); - } - - OSLockRelease(hLock); - - if (eError != PVRSRV_OK) - { - goto e0; - } - - if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - BridgeDevicememHistorySparseChange(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset, - psMemDesc->sDeviceMemDesc.sDevVAddr, - psMemDesc->uiAllocSize, - psMemDesc->szText, - DevmemGetHeapLog2PageSize(psImport->sDeviceImport.psHeap), - ui32AllocPageCount, - paui32AllocPageIndices, - ui32FreePageCount, - pauiFreePageIndices, - psMemDesc->ui32AllocationIndex, - &psMemDesc->ui32AllocationIndex); - } - -e0: - return eError; -} - -static void -FreeDeviceMemory(DEVMEM_IMPORT *psImport) -{ - DevmemImportStructRelease(psImport); -} - -static PVRSRV_ERROR -SubAllocImportAlloc(RA_PERARENA_HANDLE hArena, - RA_LENGTH_T uiSize, - RA_FLAGS_T _flags, - const IMG_CHAR *pszAnnotation, - /* returned data */ - RA_BASE_T *puiBase, - RA_LENGTH_T *puiActualSize, - RA_PERISPAN_HANDLE *phImport) -{ - /* When suballocations need a new lump of memory, the RA calls - back here. Later, in the kernel, we must construct a new PMR - and a pairing between the new lump of virtual memory and the - PMR (whether or not such PMR is backed by physical memory) */ - DEVMEM_HEAP *psHeap; - DEVMEM_IMPORT *psImport; - IMG_DEVMEM_ALIGN_T uiAlign; - PVRSRV_ERROR eError; - IMG_UINT32 ui32MappingTable = 0; - PVRSRV_MEMALLOCFLAGS_T uiFlags = (PVRSRV_MEMALLOCFLAGS_T) _flags; - IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS; - - /* Per-arena private handle is, for us, the heap */ - psHeap = hArena; - - /* align to the l.s.b. of the size... e.g. 96kiB aligned to - 32kiB. NB: There is an argument to say that the RA should never - ask us for Non-power-of-2 size anyway, but I don't want to make - that restriction arbitrarily now */ - uiAlign = uiSize & ~(uiSize-1); - - /* Technically this is only required for guest drivers due to - fw heaps being pre-allocated and pre-mapped resulting in - a 1:1 (i.e. virtual : physical) offset correlation but we - force this behaviour for all drivers to maintain consistency - (i.e. heap->VA uiAlign <= heap->PA uiLog2Quantum) */ - if (uiAlign > (IMG_DEVMEM_ALIGN_T)(1ULL << psHeap->uiLog2Quantum)) - { - uiAlign = (IMG_DEVMEM_ALIGN_T)(1ULL << psHeap->uiLog2Quantum); - } - - /* The RA should not have invoked us with a size that is not a - multiple of the quantum anyway */ - PVR_ASSERT((uiSize & ((1ULL<uiLog2Quantum)-1)) == 0); - - eError = AllocateDeviceMemory(psHeap->psCtx->hDevConnection, - psHeap->uiLog2Quantum, - uiSize, - uiSize, - 1, - 1, - &ui32MappingTable, - uiAlign, - uiFlags, - IMG_FALSE, - "PMR sub-allocated", - &psImport); - PVR_GOTO_IF_ERROR(eError, failAlloc); - -#if defined(PDUMP) && defined(DEBUG) -#if defined(__KERNEL__) - PDUMPCOMMENTWITHFLAGS(PMR_DeviceNode((PMR*)psImport->hPMR), PDUMP_CONT, - "Created PMR for sub-allocations with handle ID: 0x%p Annotation: \"%s\" (PID %u)", - psImport->hPMR, pszAnnotation, OSGetCurrentProcessID()); -#else - PDUMPCOMMENTF(psHeap->psCtx->hDevConnection, PDUMP_FLAGS_CONTINUOUS, - "Created PMR for sub-allocations with handle ID: %p Annotation: \"%s\" (PID %u)", - psImport->hPMR, pszAnnotation, OSGetCurrentProcessID()); -#endif -#else - PVR_UNREFERENCED_PARAMETER(pszAnnotation); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { -#if defined(__KERNEL__) - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psHeap->psCtx->hDevConnection; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDevNode->pvDevice; - - PVR_ASSERT(PVRSRV_CHECK_FW_MAIN(uiFlags)); - - /* If allocation is made by the Kernel from the firmware heap, account for it - * under the PVR_SYS_ALLOC_PID. - */ - if ((psHeap == psDevInfo->psFirmwareMainHeap) || (psHeap == psDevInfo->psFirmwareConfigHeap)) - { - eError = BridgeRIWritePMREntryWithOwner (GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR, - PVR_SYS_ALLOC_PID); - PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntryWithOwner"); - } - else -#endif - { - eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR); - PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry"); - } - } -#endif - -#if defined(__KERNEL__) - if (psHeap->bPremapped) - { - ui64OptionalMapAddress = _GetPremappedVA(psImport->hPMR, psHeap->psCtx->hDevConnection); - } -#endif - - /* - Suballocations always get mapped into the device was we need to - key the RA off something and as we can't export suballocations - there is no valid reason to request an allocation an not map it - */ - eError = DevmemImportStructDevMap(psHeap, - IMG_TRUE, - psImport, - ui64OptionalMapAddress); - PVR_GOTO_IF_ERROR(eError, failMap); - - OSLockAcquire(psImport->hLock); - /* Mark this import struct as zeroed so we can save some PDump LDBs - * and do not have to CPU map + mem set()*/ - if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) - { - psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_ZEROED; - } - else if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC) - { - psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_POISONED; - } - psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_CLEAN; - OSLockRelease(psImport->hLock); - - *puiBase = psImport->sDeviceImport.sDevVAddr.uiAddr; - *puiActualSize = uiSize; - *phImport = psImport; - - return PVRSRV_OK; - - /* error exit paths follow */ - -failMap: - FreeDeviceMemory(psImport); -failAlloc: - - return eError; -} - -static void -SubAllocImportFree(RA_PERARENA_HANDLE hArena, - RA_BASE_T uiBase, - RA_PERISPAN_HANDLE hImport) -{ - DEVMEM_IMPORT *psImport = hImport; -#if !defined(PVRSRV_NEED_PVR_ASSERT) - PVR_UNREFERENCED_PARAMETER(hArena); - PVR_UNREFERENCED_PARAMETER(uiBase); -#endif - - PVR_ASSERT(psImport != NULL); - PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap); - PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr); - - (void) DevmemImportStructDevUnmap(psImport); - (void) DevmemImportStructRelease(psImport); -} - -/***************************************************************************** - * Devmem context internals * - *****************************************************************************/ - -static PVRSRV_ERROR -PopulateContextFromBlueprint(struct DEVMEM_CONTEXT_TAG *psCtx, - DEVMEM_HEAPCFGID uiHeapBlueprintID) -{ - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - struct DEVMEM_HEAP_TAG **ppsHeapArray; - IMG_UINT32 uiNumHeaps; - IMG_UINT32 uiHeapsToUnwindOnError; - IMG_UINT32 uiHeapIndex; - IMG_DEV_VIRTADDR sDevVAddrBase; - IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH]; - IMG_DEVMEM_SIZE_T uiHeapLength; - IMG_DEVMEM_SIZE_T uiReservedRegionLength; - IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize; - IMG_DEVMEM_LOG2ALIGN_T uiLog2ImportAlignment; - - eError = DevmemHeapCount(psCtx->hDevConnection, - uiHeapBlueprintID, - &uiNumHeaps); - PVR_GOTO_IF_ERROR(eError, e0); - - if (uiNumHeaps == 0) - { - ppsHeapArray = NULL; - } - else - { - ppsHeapArray = OSAllocMem(sizeof(*ppsHeapArray) * uiNumHeaps); - PVR_GOTO_IF_NOMEM(ppsHeapArray, eError, e0); - } - - uiHeapsToUnwindOnError = 0; - - for (uiHeapIndex = 0; uiHeapIndex < uiNumHeaps; uiHeapIndex++) - { - eError = DevmemHeapDetails(psCtx->hDevConnection, - uiHeapBlueprintID, - uiHeapIndex, - &aszHeapName[0], - sizeof(aszHeapName), - &sDevVAddrBase, - &uiHeapLength, - &uiReservedRegionLength, - &uiLog2DataPageSize, - &uiLog2ImportAlignment); - PVR_GOTO_IF_ERROR(eError, e1); - - eError = DevmemCreateHeap(psCtx, - sDevVAddrBase, - uiHeapLength, - uiReservedRegionLength, - uiLog2DataPageSize, - uiLog2ImportAlignment, - aszHeapName, - uiHeapBlueprintID, - &ppsHeapArray[uiHeapIndex]); - PVR_GOTO_IF_ERROR(eError, e1); - - uiHeapsToUnwindOnError = uiHeapIndex + 1; - } - - psCtx->uiAutoHeapCount = uiNumHeaps; - psCtx->ppsAutoHeapArray = ppsHeapArray; - - PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount); - PVR_ASSERT(psCtx->uiAutoHeapCount == uiNumHeaps); - - return PVRSRV_OK; - - /* error exit paths */ -e1: - for (uiHeapIndex = 0; uiHeapIndex < uiHeapsToUnwindOnError; uiHeapIndex++) - { - eError2 = DevmemDestroyHeap(ppsHeapArray[uiHeapIndex]); - PVR_ASSERT(eError2 == PVRSRV_OK); - } - - if (uiNumHeaps != 0) - { - OSFreeMem(ppsHeapArray); - } - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static PVRSRV_ERROR -UnpopulateContextFromBlueprint(struct DEVMEM_CONTEXT_TAG *psCtx) -{ - PVRSRV_ERROR eReturn = PVRSRV_OK; - PVRSRV_ERROR eError2; - IMG_UINT32 uiHeapIndex; - IMG_BOOL bDoCheck = IMG_TRUE; -#if defined(__KERNEL__) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - bDoCheck = IMG_FALSE; - } -#endif - - for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++) - { - if (!psCtx->ppsAutoHeapArray[uiHeapIndex]) - { - continue; - } - - eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]); - if (eError2 != PVRSRV_OK) - { - eReturn = eError2; - } - else - { - psCtx->ppsAutoHeapArray[uiHeapIndex] = NULL; - } - } - - if ((!bDoCheck || (eReturn == PVRSRV_OK)) && psCtx->ppsAutoHeapArray) - { - OSFreeMem(psCtx->ppsAutoHeapArray); - psCtx->ppsAutoHeapArray = NULL; - psCtx->uiAutoHeapCount = 0; - } - - return eReturn; -} - -/***************************************************************************** - * Devmem context functions * - *****************************************************************************/ - -IMG_INTERNAL PVRSRV_ERROR -DevmemCreateContext(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_HEAPCFGID uiHeapBlueprintID, - DEVMEM_CONTEXT **ppsCtxPtr) -{ - PVRSRV_ERROR eError; - DEVMEM_CONTEXT *psCtx; - /* handle to the server-side counterpart of the device memory - context (specifically, for handling mapping to device MMU) */ - IMG_HANDLE hDevMemServerContext; - IMG_HANDLE hPrivData; - IMG_BOOL bHeapCfgMetaId = (uiHeapBlueprintID == DEVMEM_HEAPCFG_META); - - PVR_GOTO_IF_NOMEM(ppsCtxPtr, eError, e0); - - psCtx = OSAllocMem(sizeof(*psCtx)); - PVR_GOTO_IF_NOMEM(psCtx, eError, e0); - - psCtx->uiNumHeaps = 0; - - psCtx->hDevConnection = hDevConnection; - - /* Create (server-side) Device Memory context */ - eError = BridgeDevmemIntCtxCreate(GetBridgeHandle(psCtx->hDevConnection), - bHeapCfgMetaId, - &hDevMemServerContext, - &hPrivData, - &psCtx->ui32CPUCacheLineSize); - PVR_GOTO_IF_ERROR(eError, e1); - - psCtx->hDevMemServerContext = hDevMemServerContext; - psCtx->hPrivData = hPrivData; - - /* automagic heap creation */ - psCtx->uiAutoHeapCount = 0; - - eError = PopulateContextFromBlueprint(psCtx, uiHeapBlueprintID); - PVR_GOTO_IF_ERROR(eError, e2); - - *ppsCtxPtr = psCtx; - - PVR_ASSERT(psCtx->uiNumHeaps == psCtx->uiAutoHeapCount); - return PVRSRV_OK; - - /* error exit paths follow */ - -e2: - PVR_ASSERT(psCtx->uiAutoHeapCount == 0); - PVR_ASSERT(psCtx->uiNumHeaps == 0); - BridgeDevmemIntCtxDestroy(GetBridgeHandle(psCtx->hDevConnection), hDevMemServerContext); - -e1: - OSFreeMem(psCtx); - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx, - IMG_HANDLE *hPrivData) -{ - PVRSRV_ERROR eError; - - PVR_GOTO_IF_INVALID_PARAM(psCtx, eError, e0); - PVR_GOTO_IF_INVALID_PARAM(hPrivData, eError, e0); - - *hPrivData = psCtx->hPrivData; - return PVRSRV_OK; - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx) -{ - PVRSRV_ERROR eError; - - PVR_GOTO_IF_INVALID_PARAM(psCtx, eError, e0); - return PVRSRV_OK; - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -IMG_INTERNAL PVRSRV_ERROR -DevmemFindHeapByName(const struct DEVMEM_CONTEXT_TAG *psCtx, - const IMG_CHAR *pszHeapName, - struct DEVMEM_HEAP_TAG **ppsHeapRet) -{ - IMG_UINT32 uiHeapIndex; - - /* N.B. This func is only useful for finding "automagic" heaps by name */ - for (uiHeapIndex = 0; - uiHeapIndex < psCtx->uiAutoHeapCount; - uiHeapIndex++) - { - if (!OSStringNCompare(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName, pszHeapName, OSStringLength(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName) + 1)) - { - *ppsHeapRet = psCtx->ppsAutoHeapArray[uiHeapIndex]; - return PVRSRV_OK; - } - } - - return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemDestroyContext(DEVMEM_CONTEXT *psCtx) -{ - PVRSRV_ERROR eError; - IMG_BOOL bDoCheck = IMG_TRUE; - -#if defined(__KERNEL__) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - bDoCheck = IMG_FALSE; - } -#endif - - PVR_RETURN_IF_INVALID_PARAM(psCtx); - - eError = UnpopulateContextFromBlueprint(psCtx); - if (bDoCheck && eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: UnpopulateContextFromBlueprint failed (%d) leaving %d heaps", - __func__, eError, psCtx->uiNumHeaps)); - goto e1; - } - - eError = DestroyServerResource(psCtx->hDevConnection, - NULL, - BridgeDevmemIntCtxDestroy, - psCtx->hDevMemServerContext); - if (bDoCheck) - { - PVR_LOG_GOTO_IF_ERROR(eError, "BridgeDevMemIntCtxDestroy", e1); - - /* should be no more heaps left */ - if (psCtx->uiNumHeaps) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Additional heaps remain in DEVMEM_CONTEXT", - __func__)); - eError = PVRSRV_ERROR_DEVICEMEM_ADDITIONAL_HEAPS_IN_CONTEXT; - goto e1; - } - } - - OSCachedMemSet(psCtx, 0, sizeof(*psCtx)); - OSFreeMem(psCtx); - -e1: - return eError; -} - -/***************************************************************************** - * Devmem heap query functions * - *****************************************************************************/ - -IMG_INTERNAL PVRSRV_ERROR -DevmemHeapConfigCount(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 *puiNumHeapConfigsOut) -{ - PVRSRV_ERROR eError; - eError = BridgeHeapCfgHeapConfigCount(GetBridgeHandle(hDevConnection), - puiNumHeapConfigsOut); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemHeapCount(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 *puiNumHeapsOut) -{ - PVRSRV_ERROR eError; - eError = BridgeHeapCfgHeapCount(GetBridgeHandle(hDevConnection), - uiHeapConfigIndex, - puiNumHeapsOut); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemHeapConfigName(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_CHAR *pszConfigNameOut, - IMG_UINT32 uiConfigNameBufSz) -{ - PVRSRV_ERROR eError; - eError = BridgeHeapCfgHeapConfigName(GetBridgeHandle(hDevConnection), - uiHeapConfigIndex, - uiConfigNameBufSz, - pszConfigNameOut); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemHeapDetails(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapIndex, - IMG_CHAR *pszHeapNameOut, - IMG_UINT32 uiHeapNameBufSz, - IMG_DEV_VIRTADDR *psDevVAddrBaseOut, - IMG_DEVMEM_SIZE_T *puiHeapLengthOut, - IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut, - IMG_UINT32 *puiLog2DataPageSizeOut, - IMG_UINT32 *puiLog2ImportAlignmentOut) -{ - PVRSRV_ERROR eError; - - eError = BridgeHeapCfgHeapDetails(GetBridgeHandle(hDevConnection), - uiHeapConfigIndex, - uiHeapIndex, - uiHeapNameBufSz, - pszHeapNameOut, - psDevVAddrBaseOut, - puiHeapLengthOut, - puiReservedRegionLengthOut, - puiLog2DataPageSizeOut, - puiLog2ImportAlignmentOut); - - VG_MARK_INITIALIZED(pszHeapNameOut, uiHeapNameBufSz); - - return eError; -} - -/***************************************************************************** - * Devmem heap functions * - *****************************************************************************/ - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetHeapInt(DEVMEM_HEAP *psHeap, - IMG_HANDLE *phDevmemHeap) -{ - PVR_RETURN_IF_INVALID_PARAM(psHeap); - *phDevmemHeap = psHeap->hDevMemServerHeap; - return PVRSRV_OK; -} - -/* See devicemem.h for important notes regarding the arguments - to this function */ -IMG_INTERNAL PVRSRV_ERROR -DevmemCreateHeap(DEVMEM_CONTEXT *psCtx, - IMG_DEV_VIRTADDR sBaseAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_DEVMEM_SIZE_T uiReservedRegionLength, - IMG_UINT32 ui32Log2Quantum, - IMG_UINT32 ui32Log2ImportAlignment, - const IMG_CHAR *pszName, - DEVMEM_HEAPCFGID uiHeapBlueprintID, - DEVMEM_HEAP **ppsHeapPtr) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_ERROR eError2; - DEVMEM_HEAP *psHeap; - /* handle to the server-side counterpart of the device memory heap - (specifically, for handling mapping to device MMU) */ - IMG_HANDLE hDevMemServerHeap; - IMG_UINT32 ui32Policy = RA_POLICY_DEFAULT, ui32PolicyVMRA; - - IMG_CHAR aszBuf[100]; - IMG_CHAR *pszStr; - IMG_UINT32 ui32pszStrSize; - - if (ppsHeapPtr == NULL || - uiReservedRegionLength % DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, e0); - } - - ui32PolicyVMRA = RA_POLICY_DEFAULT; - - PVR_ASSERT(uiReservedRegionLength + DEVMEM_HEAP_MINIMUM_SIZE <= uiLength); - - psHeap = OSAllocMem(sizeof(*psHeap)); - PVR_GOTO_IF_NOMEM(psHeap, eError, e0); - - /* Need to keep local copy of heap name, so caller may free theirs */ - ui32pszStrSize = OSStringLength(pszName) + 1; - pszStr = OSAllocMem(ui32pszStrSize); - PVR_GOTO_IF_NOMEM(pszStr, eError, e1); - OSStringLCopy(pszStr, pszName, ui32pszStrSize); - psHeap->pszName = pszStr; - - psHeap->uiSize = uiLength; - psHeap->uiReservedRegionSize = uiReservedRegionLength; - psHeap->sBaseAddress = sBaseAddress; - psHeap->bPremapped = IMG_FALSE; - OSAtomicWrite(&psHeap->hImportCount, 0); - - OSSNPrintf(aszBuf, sizeof(aszBuf), - "NDM heap '%s' (suballocs) ctx:%p", - pszName, psCtx); - ui32pszStrSize = OSStringLength(aszBuf) + 1; - pszStr = OSAllocMem(ui32pszStrSize); - PVR_GOTO_IF_NOMEM(pszStr, eError, e2); - OSStringLCopy(pszStr, aszBuf, ui32pszStrSize); - psHeap->pszSubAllocRAName = pszStr; - -#if defined(__KERNEL__) - if (uiHeapBlueprintID == DEVMEM_HEAPCFG_META) - { - void *pvAppHintState = NULL; - IMG_UINT32 ui32FirmwarePolicydefault = 0, ui32FirmwarePolicy=0; - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, DevMemFWHeapPolicy, - &ui32FirmwarePolicydefault, &ui32FirmwarePolicy); - ui32PolicyVMRA = ui32Policy = ui32FirmwarePolicy; - OSFreeKMAppHintState(pvAppHintState); - } -#endif - -#if defined(PDUMP) - /* The META heap is shared globally so a single physical memory import - * may be used to satisfy allocations of different processes. - * This is problematic when PDumping because the physical memory - * import used to satisfy a new allocation may actually have been - * imported (and thus the PDump MALLOC generated) before the PDump - * client was started, leading to the MALLOC being missing. - * - * This is solved by disabling splitting of imports for the META physmem - * RA, meaning that every firmware allocation gets its own import, thus - * ensuring the MALLOC is present for every allocation made within the - * pdump capture range - */ - if (uiHeapBlueprintID == DEVMEM_HEAPCFG_META) - { - ui32Policy |= RA_POLICY_NO_SPLIT; - } -#else - PVR_UNREFERENCED_PARAMETER(uiHeapBlueprintID); -#endif - - psHeap->psSubAllocRA = RA_Create(psHeap->pszSubAllocRAName, - /* Subsequent imports: */ - ui32Log2Quantum, - RA_LOCKCLASS_2, - SubAllocImportAlloc, - SubAllocImportFree, - (RA_PERARENA_HANDLE) psHeap, - ui32Policy); - if (psHeap->psSubAllocRA == NULL) - { - eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA; - goto e3; - } - - psHeap->uiLog2ImportAlignment = ui32Log2ImportAlignment; - psHeap->uiLog2Quantum = ui32Log2Quantum; - - if (!OSStringNCompare(pszName, RGX_GENERAL_SVM_HEAP_IDENT, sizeof(RGX_GENERAL_SVM_HEAP_IDENT))) - { - /* The SVM heap normally starts out as this type though - it may transition to DEVMEM_HEAP_MANAGER_USER - on platforms with more processor virtual address - bits than device virtual address bits */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_KERNEL; - } - else if (uiReservedRegionLength != 0) - { - /* Heaps which specify reserved VA space range are dual managed: - * - sBaseAddress to (sBaseAddress+uiReservedRegionLength-1): User managed - * - (sBaseAddress+uiReservedRegionLength) to uiLength: RA managed - */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_DUAL_USER_RA; - } - else - { - /* Otherwise, heap manager is decided (USER or RA) at first map */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_UNKNOWN; - } - - /* Mark the heap to be managed by RA */ - if (!OSStringNCompare(pszName, RGX_VK_CAPT_REPLAY_HEAP_IDENT, - sizeof(RGX_VK_CAPT_REPLAY_HEAP_IDENT))) - { - psHeap->ui32HeapManagerFlags |= DEVMEM_HEAP_MANAGER_RA; - } - - OSSNPrintf(aszBuf, sizeof(aszBuf), - "NDM heap '%s' (QVM) ctx:%p", - pszName, psCtx); - ui32pszStrSize = OSStringLength(aszBuf) + 1; - pszStr = OSAllocMem(ui32pszStrSize); - if (pszStr == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e4; - } - OSStringLCopy(pszStr, aszBuf, ui32pszStrSize); - psHeap->pszQuantizedVMRAName = pszStr; - - psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName, - /* Subsequent import: */ - 0, RA_LOCKCLASS_1, NULL, NULL, - (RA_PERARENA_HANDLE) psHeap, - ui32PolicyVMRA); - if (psHeap->psQuantizedVMRA == NULL) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA, e5); - } - - if (!RA_Add(psHeap->psQuantizedVMRA, - /* Make sure the VMRA doesn't allocate from reserved VAs */ - (RA_BASE_T)sBaseAddress.uiAddr + uiReservedRegionLength, - (RA_LENGTH_T)uiLength, - (RA_FLAGS_T)0, /* This RA doesn't use or need flags */ - NULL /* per ispan handle */)) - { - RA_Delete(psHeap->psQuantizedVMRA); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA, e5); - } - - psHeap->psCtx = psCtx; - - - /* Create server-side counterpart of Device Memory heap */ - eError = BridgeDevmemIntHeapCreate(GetBridgeHandle(psCtx->hDevConnection), - psCtx->hDevMemServerContext, - sBaseAddress, - uiLength, - ui32Log2Quantum, - &hDevMemServerHeap); - PVR_GOTO_IF_ERROR(eError, e6); - - psHeap->hDevMemServerHeap = hDevMemServerHeap; - - eError = OSLockCreate(&psHeap->hLock); - PVR_GOTO_IF_ERROR(eError, e7); - - psHeap->psCtx->uiNumHeaps++; - *ppsHeapPtr = psHeap; - -#if defined(PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING) - psHeap->psMemDescList = NULL; -#endif /* PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING */ - - return PVRSRV_OK; - - /* error exit paths */ -e7: - eError2 = BridgeDevmemIntHeapDestroy(GetBridgeHandle(psCtx->hDevConnection), - psHeap->hDevMemServerHeap); - PVR_ASSERT (eError2 == PVRSRV_OK); -e6: - if (psHeap->psQuantizedVMRA) - RA_Delete(psHeap->psQuantizedVMRA); -e5: - if (psHeap->pszQuantizedVMRAName) - OSFreeMem(psHeap->pszQuantizedVMRAName); -e4: - RA_Delete(psHeap->psSubAllocRA); -e3: - OSFreeMem(psHeap->pszSubAllocRAName); -e2: - OSFreeMem(psHeap->pszName); -e1: - OSFreeMem(psHeap); -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetHeapBaseDevVAddr(struct DEVMEM_HEAP_TAG *psHeap, - IMG_DEV_VIRTADDR *pDevVAddr) -{ - PVR_RETURN_IF_INVALID_PARAM(psHeap); - - *pDevVAddr = psHeap->sBaseAddress; - - return PVRSRV_OK; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - IMG_DEVMEM_SIZE_T uiSize = *puiSize; - IMG_DEVMEM_ALIGN_T uiAlign = *puiAlign; - - /* Just in case someone changes definition of IMG_DEVMEM_ALIGN_T. */ - static_assert(sizeof(unsigned long long) == sizeof(uiAlign), - "invalid uiAlign size"); - /* This value is used for shifting so it cannot be greater than number - * of bits in unsigned long long (sizeof(1ULL)). Using greater value is - * undefined behaviour. */ - if (uiLog2Quantum >= sizeof(unsigned long long) * 8) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if ((1ULL << uiLog2Quantum) > uiAlign) - { - uiAlign = 1ULL << uiLog2Quantum; - } - uiSize = (uiSize + uiAlign - 1) & ~(uiAlign - 1); - - *puiSize = uiSize; - *puiAlign = uiAlign; - - return PVRSRV_OK; -} - - -IMG_INTERNAL PVRSRV_ERROR -DevmemDestroyHeap(DEVMEM_HEAP *psHeap) -{ - PVRSRV_ERROR eError; - IMG_INT uiImportCount; -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - IMG_BOOL bDoCheck = IMG_TRUE; -#if defined(__KERNEL__) - if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - bDoCheck = IMG_FALSE; - } -#endif -#endif - - PVR_RETURN_IF_INVALID_PARAM(psHeap); - - uiImportCount = OSAtomicRead(&psHeap->hImportCount); - if (uiImportCount > 0) - { - PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", uiImportCount, psHeap->pszName)); -#if defined(__KERNEL__) -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - PVR_DPF((PVR_DBG_ERROR, "Details of remaining allocated device memory (for all processes):")); - RIDumpAllKM(); -#else - PVR_DPF((PVR_DBG_ERROR, "Compile with PVRSRV_ENABLE_GPU_MEMORY_INFO=1 to get a full " - "list of all driver allocations.")); -#endif -#endif -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (bDoCheck) -#endif - { - return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP; - } - } - - eError = DestroyServerResource(psHeap->psCtx->hDevConnection, - NULL, - BridgeDevmemIntHeapDestroy, - psHeap->hDevMemServerHeap); - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (bDoCheck) -#endif - { - PVR_LOG_RETURN_IF_ERROR(eError, "BridgeDevmemIntHeapDestroy"); - } - - PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0); - psHeap->psCtx->uiNumHeaps--; - - OSLockDestroy(psHeap->hLock); - - if (psHeap->psQuantizedVMRA) - { - RA_Delete(psHeap->psQuantizedVMRA); - } - if (psHeap->pszQuantizedVMRAName) - { - OSFreeMem(psHeap->pszQuantizedVMRAName); - } - - RA_Delete(psHeap->psSubAllocRA); - OSFreeMem(psHeap->pszSubAllocRAName); - - OSFreeMem(psHeap->pszName); - - OSCachedMemSet(psHeap, 0, sizeof(*psHeap)); - OSFreeMem(psHeap); - - return PVRSRV_OK; -} - -/***************************************************************************** - * Devmem allocation/free functions * - *****************************************************************************/ - -IMG_INTERNAL PVRSRV_ERROR -DevmemSubAllocateAndMap(IMG_UINT8 uiPreAllocMultiplier, - DEVMEM_HEAP *psHeap, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr, - IMG_DEV_VIRTADDR *psDevVirtAddr) -{ - PVRSRV_ERROR eError; - eError = DevmemSubAllocate(uiPreAllocMultiplier, - psHeap, - uiSize, - uiAlign, - uiFlags, - pszText, - ppsMemDescPtr); - PVR_GOTO_IF_ERROR(eError, fail_alloc); - - eError = DevmemMapToDevice(*ppsMemDescPtr, - psHeap, - psDevVirtAddr); - PVR_GOTO_IF_ERROR(eError, fail_map); - - return PVRSRV_OK; - -fail_map: - DevmemFree(*ppsMemDescPtr); -fail_alloc: - *ppsMemDescPtr = NULL; - PVR_ASSERT(eError != PVRSRV_OK); - return eError; - -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemSubAllocate(IMG_UINT8 uiPreAllocMultiplier, - DEVMEM_HEAP *psHeap, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - RA_BASE_T uiAllocatedAddr = 0; - RA_LENGTH_T uiAllocatedSize; - RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */ - PVRSRV_ERROR eError; - DEVMEM_MEMDESC *psMemDesc = NULL; - IMG_DEVMEM_OFFSET_T uiOffset = 0; - DEVMEM_IMPORT *psImport; - IMG_UINT32 ui32CPUCacheLineSize; - void *pvAddr = NULL; - - IMG_BOOL bImportClean; - IMG_BOOL bCPUCleanFlag = PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags); - IMG_BOOL bZero = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags); - IMG_BOOL bPoisonOnAlloc = PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags); - IMG_BOOL bCPUCached = (PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) || - PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags)); - IMG_BOOL bGPUCached = (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) || - PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags)); - IMG_BOOL bAlign = ! (PVRSRV_CHECK_NO_CACHE_LINE_ALIGN(uiFlags)); - PVRSRV_CACHE_OP eOp = PVRSRV_CACHE_OP_INVALIDATE; - IMG_UINT32 ui32CacheLineSize = 0; - DEVMEM_PROPERTIES_T uiProperties; - - if (uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) - { - /* Deferred Allocation not supported on SubAllocs*/ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failParams); - } - - PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams); - PVR_GOTO_IF_INVALID_PARAM(psHeap->psCtx, eError, failParams); - PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams); - - uiFlags = DevmemOverrideFlagsOrPassThrough(psHeap->psCtx->hDevConnection, uiFlags); - -#if defined(__KERNEL__) - { - /* The hDevConnection holds two different types of pointers depending on the - * address space in which it is used. - * In this instance the variable points to the device node in server */ - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psHeap->psCtx->hDevConnection; - ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, SLC_CACHE_LINE_SIZE_BITS)); - } -#else - ui32CacheLineSize = ROGUE_CACHE_LINE_SIZE; -#endif - - /* The following logic makes sure that any cached memory is aligned to both the CPU and GPU. - * To be aligned on both you have to take the Lowest Common Multiple (LCM) of the cache line sizes of each. - * As the possibilities are all powers of 2 then simply the largest number can be picked as the LCM. - * Therefore this algorithm just picks the highest from the CPU, GPU and given alignments. - */ - ui32CPUCacheLineSize = psHeap->psCtx->ui32CPUCacheLineSize; - /* If the CPU cache line size is larger than the alignment given then it is the lowest common multiple - * Also checking if the allocation is going to be cached on the CPU - * Currently there is no check for the validity of the cache coherent option. - * In this case, the alignment could be applied but the mode could still fall back to uncached. - */ - if (bAlign && ui32CPUCacheLineSize > uiAlign && bCPUCached) - { - uiAlign = ui32CPUCacheLineSize; - } - - /* If the GPU cache line size is larger than the alignment given then it is the lowest common multiple - * Also checking if the allocation is going to be cached on the GPU via checking for any of the cached options. - * Currently there is no check for the validity of the cache coherent option. - * In this case, the alignment could be applied but the mode could still fall back to uncached. - */ - if (bAlign && ui32CacheLineSize > uiAlign && bGPUCached) - { - uiAlign = ui32CacheLineSize; - } - - eError = DevmemValidateParams(uiSize, - uiAlign, - &uiFlags); - PVR_GOTO_IF_ERROR(eError, failParams); - - eError = DevmemMemDescAlloc(&psMemDesc); - PVR_GOTO_IF_ERROR(eError, failMemDescAlloc); - - /* No request for exportable memory so use the RA */ - eError = RA_Alloc(psHeap->psSubAllocRA, - uiSize, - uiPreAllocMultiplier, - uiFlags, - uiAlign, - pszText, - &uiAllocatedAddr, - &uiAllocatedSize, - &hImport); - PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc); - - psImport = hImport; - - /* This assignment is assuming the RA returns an hImport where suballocations - * can be made from if uiSize is NOT a page multiple of the passed heap. - * - * So we check if uiSize is a page multiple and mark it as exportable - * if it is not. - * */ - OSLockAcquire(psImport->hLock); - if (!(uiSize & ((1ULL << psHeap->uiLog2Quantum) - 1)) && - (uiPreAllocMultiplier == RA_NO_IMPORT_MULTIPLIER)) - { - psImport->uiProperties |= DEVMEM_PROPERTIES_EXPORTABLE; - } - psImport->uiProperties |= DEVMEM_PROPERTIES_SUBALLOCATABLE; - uiProperties = psImport->uiProperties; - OSLockRelease(psImport->hLock); - - uiOffset = uiAllocatedAddr - psImport->sDeviceImport.sDevVAddr.uiAddr; - -#if defined(PDUMP) && defined(DEBUG) -#if defined(__KERNEL__) - PDUMPCOMMENTWITHFLAGS(PMR_DeviceNode((PMR*)psImport->hPMR), PDUMP_CONT, - "Suballocated %u Byte for \"%s\" from PMR with handle ID: 0x%p (PID %u)", - (IMG_UINT32) uiSize, pszText, psImport->hPMR, OSGetCurrentProcessID()); -#else - PDUMPCOMMENTF(psHeap->psCtx->hDevConnection, PDUMP_FLAGS_CONTINUOUS, - "Suballocated %u Byte for \"%s\" from PMR with handle ID: %p (PID %u)", - (IMG_UINT32) uiSize, - pszText, - psImport->hPMR, - OSGetCurrentProcessID()); -#endif -#endif - - DevmemMemDescInit(psMemDesc, - uiOffset, - psImport, - uiSize); - -#if defined(DEBUG) - DevmemMemDescSetPoF(psMemDesc, uiFlags); -#endif - - bImportClean = ((uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_CLEAN) != 0); - - /* Zero the memory */ - if (bZero) - { - /* Has the import been zeroed on allocation and were no suballocations returned to it so far? */ - bImportClean = bImportClean && ((uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_ZEROED) != 0); - - if (!bImportClean) - { - eOp = PVRSRV_CACHE_OP_FLUSH; - - eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr); - PVR_GOTO_IF_ERROR(eError, failMaintenance); - - /* uiSize is a 64-bit quantity whereas the 3rd argument - * to OSDeviceMemSet is a 32-bit quantity on 32-bit systems - * hence a compiler warning of implicit cast and loss of data. - * Added explicit cast and assert to remove warning. - */ - PVR_ASSERT(uiSize < IMG_UINT32_MAX); - - DevmemCPUMemSet(pvAddr, 0, uiSize, uiFlags); - -#if defined(PDUMP) - DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS); -#endif - } - } - else if (bPoisonOnAlloc) - { - /* Has the import been poisoned on allocation and were no suballocations returned to it so far? */ - bPoisonOnAlloc = (uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_POISONED) != 0; - - if (!bPoisonOnAlloc) - { - eOp = PVRSRV_CACHE_OP_FLUSH; - - eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr); - PVR_GOTO_IF_ERROR(eError, failMaintenance); - - DevmemCPUMemSet(pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE, uiSize, uiFlags); - - bPoisonOnAlloc = IMG_TRUE; - } - } - - /* Flush or invalidate */ - if (bCPUCached && !bImportClean && (bZero || bCPUCleanFlag || bPoisonOnAlloc)) - { - eError = BridgeCacheOpExec (GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - (IMG_UINT64)(uintptr_t) - pvAddr - psMemDesc->uiOffset, - psMemDesc->uiOffset, - psMemDesc->uiAllocSize, - eOp); - PVR_GOTO_IF_ERROR(eError, failMaintenance); - } - - if (pvAddr) - { - DevmemReleaseCpuVirtAddr(psMemDesc); - pvAddr = NULL; - } - - /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when - * the allocation gets mapped/unmapped - */ - CheckAnnotationLength(pszText); - OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - /* Attach RI information */ - eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - OSStringNLength(psMemDesc->szText, DEVMEM_ANNOTATION_MAX_LEN), - psMemDesc->szText, - psMemDesc->uiOffset, - uiAllocatedSize, - IMG_FALSE, - IMG_TRUE, - &(psMemDesc->hRIHandle)); - PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry"); - } -#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - PVR_UNREFERENCED_PARAMETER (pszText); -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - *ppsMemDescPtr = psMemDesc; - - return PVRSRV_OK; - - /* error exit paths follow */ - -failMaintenance: - if (pvAddr) - { - DevmemReleaseCpuVirtAddr(psMemDesc); - pvAddr = NULL; - } - DevmemMemDescRelease(psMemDesc); - psMemDesc = NULL; /* Make sure we don't do a discard after the release */ -failDeviceMemAlloc: - if (psMemDesc) - { - DevmemMemDescDiscard(psMemDesc); - } -failMemDescAlloc: -failParams: - PVR_ASSERT(eError != PVRSRV_OK); - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC, - __func__, - PVRSRVGETERRORSTRING(eError), - uiSize)); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_UINT32 uiLog2HeapPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - PVRSRV_ERROR eError; - DEVMEM_MEMDESC *psMemDesc = NULL; - DEVMEM_IMPORT *psImport; - IMG_UINT32 ui32MappingTable = 0; - - eError = DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize, - &uiSize, - &uiAlign); - PVR_GOTO_IF_ERROR(eError, failParams); - - uiFlags = DevmemOverrideFlagsOrPassThrough(hDevConnection, uiFlags); - - eError = DevmemValidateParams(uiSize, - uiAlign, - &uiFlags); - PVR_GOTO_IF_ERROR(eError, failParams); - - eError = DevmemMemDescAlloc(&psMemDesc); - PVR_GOTO_IF_ERROR(eError, failMemDescAlloc); - - eError = AllocateDeviceMemory(hDevConnection, - uiLog2HeapPageSize, - uiSize, - uiSize, - 1, - 1, - &ui32MappingTable, - uiAlign, - uiFlags, - IMG_TRUE, - pszText, - &psImport); - PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc); - - DevmemMemDescInit(psMemDesc, - 0, - psImport, - uiSize); - -#if defined(DEBUG) - DevmemMemDescSetPoF(psMemDesc, uiFlags); -#endif - - *ppsMemDescPtr = psMemDesc; - - /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when - * the allocation gets mapped/unmapped - */ - CheckAnnotationLength(pszText); - OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR); - PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry"); - - /* Attach RI information */ - eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR, - sizeof("^"), - "^", - psMemDesc->uiOffset, - uiSize, - IMG_FALSE, - IMG_FALSE, - &psMemDesc->hRIHandle); - PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry"); - } -#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - PVR_UNREFERENCED_PARAMETER (pszText); -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - return PVRSRV_OK; - - /* error exit paths follow */ - -failDeviceMemAlloc: - DevmemMemDescDiscard(psMemDesc); - -failMemDescAlloc: -failParams: - PVR_ASSERT(eError != PVRSRV_OK); - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC, - __func__, - PVRSRVGETERRORSTRING(eError), - uiSize)); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_UINT32 uiLog2HeapPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - PVRSRV_ERROR eError; - DEVMEM_MEMDESC *psMemDesc = NULL; - DEVMEM_IMPORT *psImport; - - eError = DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize, - &uiSize, - &uiAlign); - PVR_GOTO_IF_ERROR(eError, failParams); - - uiFlags = DevmemOverrideFlagsOrPassThrough(hDevConnection, uiFlags); - - eError = DevmemValidateParams(uiSize, - uiAlign, - &uiFlags); - PVR_GOTO_IF_ERROR(eError, failParams); - - eError = DevmemMemDescAlloc(&psMemDesc); - PVR_GOTO_IF_ERROR(eError, failMemDescAlloc); - - eError = AllocateDeviceMemory(hDevConnection, - uiLog2HeapPageSize, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiAlign, - uiFlags, - IMG_TRUE, - pszText, - &psImport); - PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc); - - DevmemMemDescInit(psMemDesc, - 0, - psImport, - uiSize); - -#if defined(DEBUG) - DevmemMemDescSetPoF(psMemDesc, uiFlags); -#endif - - /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when - * the allocation gets mapped/unmapped - */ - CheckAnnotationLength(pszText); - OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR); - PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry"); - - /* Attach RI information */ - eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - sizeof("^"), - "^", - psMemDesc->uiOffset, - uiSize, - IMG_FALSE, - IMG_FALSE, - &psMemDesc->hRIHandle); - PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry"); - } -#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - PVR_UNREFERENCED_PARAMETER (pszText); -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - *ppsMemDescPtr = psMemDesc; - - return PVRSRV_OK; - - /* error exit paths follow */ - -failDeviceMemAlloc: - DevmemMemDescDiscard(psMemDesc); - -failMemDescAlloc: -failParams: - PVR_ASSERT(eError != PVRSRV_OK); - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC, - __func__, - PVRSRVGETERRORSTRING(eError), - uiSize)); - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemMakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hServerHandle, - IMG_HANDLE *hLocalImportHandle) -{ - return BridgePMRMakeLocalImportHandle(GetBridgeHandle(hDevConnection), - hServerHandle, - hLocalImportHandle); -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemUnmakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hLocalImportHandle) -{ - return DestroyServerResource(hDevConnection, - NULL, - BridgePMRUnmakeLocalImportHandle, - hLocalImportHandle); -} - -/***************************************************************************** - * Devmem unsecure export functions * - *****************************************************************************/ - -#if defined(SUPPORT_INSECURE_EXPORT) - -static PVRSRV_ERROR -_Mapping_Export(DEVMEM_IMPORT *psImport, - DEVMEM_EXPORTHANDLE *phPMRExportHandlePtr, - DEVMEM_EXPORTKEY *puiExportKeyPtr, - DEVMEM_SIZE_T *puiSize, - DEVMEM_LOG2ALIGN_T *puiLog2Contig) -{ - /* Gets an export handle and key for the PMR used for this mapping */ - /* Can only be done if there are no suballocations for this mapping */ - - PVRSRV_ERROR eError; - DEVMEM_EXPORTHANDLE hPMRExportHandle; - DEVMEM_EXPORTKEY uiExportKey; - IMG_DEVMEM_SIZE_T uiSize; - IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig; - - PVR_GOTO_IF_INVALID_PARAM(psImport, eError, failParams); - - if ((GetImportProperties(psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION, failParams); - } - - eError = BridgePMRExportPMR(GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR, - &hPMRExportHandle, - &uiSize, - &uiLog2Contig, - &uiExportKey); - PVR_GOTO_IF_ERROR(eError, failExport); - - PVR_ASSERT(uiSize == psImport->uiSize); - - *phPMRExportHandlePtr = hPMRExportHandle; - *puiExportKeyPtr = uiExportKey; - *puiSize = uiSize; - *puiLog2Contig = uiLog2Contig; - - return PVRSRV_OK; - - /* error exit paths follow */ - -failExport: -failParams: - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; - -} - -static void -_Mapping_Unexport(DEVMEM_IMPORT *psImport, - DEVMEM_EXPORTHANDLE hPMRExportHandle) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT (psImport != NULL); - - eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgePMRUnexportPMR, - hPMRExportHandle); - PVR_ASSERT(eError == PVRSRV_OK); -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemExport(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_EXPORTCOOKIE *psExportCookie) -{ - /* Caller to provide storage for export cookie struct */ - PVRSRV_ERROR eError; - IMG_HANDLE hPMRExportHandle = 0; - IMG_UINT64 uiPMRExportPassword = 0; - IMG_DEVMEM_SIZE_T uiSize = 0; - IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig = 0; - - PVR_GOTO_IF_INVALID_PARAM(psMemDesc, eError, e0); - PVR_GOTO_IF_INVALID_PARAM(psExportCookie, eError, e0); - - if (DEVMEM_PROPERTIES_EXPORTABLE != - (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This Memory (0x%p) cannot be exported!...", - __func__, psMemDesc)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_REQUEST, e0); - } - - eError = _Mapping_Export(psMemDesc->psImport, - &hPMRExportHandle, - &uiPMRExportPassword, - &uiSize, - &uiLog2Contig); - if (eError != PVRSRV_OK) - { - psExportCookie->uiSize = 0; - goto e0; - } - - psExportCookie->hPMRExportHandle = hPMRExportHandle; - psExportCookie->uiPMRExportPassword = uiPMRExportPassword; - psExportCookie->uiSize = uiSize; - psExportCookie->uiLog2ContiguityGuarantee = uiLog2Contig; - - return PVRSRV_OK; - - /* error exit paths follow */ - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -IMG_INTERNAL void -DevmemUnexport(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_EXPORTCOOKIE *psExportCookie) -{ - _Mapping_Unexport(psMemDesc->psImport, - psExportCookie->hPMRExportHandle); - - psExportCookie->uiSize = 0; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemImport(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_EXPORTCOOKIE *psCookie, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - DEVMEM_MEMDESC *psMemDesc = NULL; - DEVMEM_IMPORT *psImport; - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; - - PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams); - - eError = DevmemMemDescAlloc(&psMemDesc); - PVR_GOTO_IF_ERROR(eError, failMemDescAlloc); - - eError = DevmemImportStructAlloc(hDevConnection, - &psImport); - if (eError != PVRSRV_OK) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, failImportAlloc); - } - - /* Get a handle to the PMR (inc refcount) */ - eError = BridgePMRImportPMR(GetBridgeHandle(hDevConnection), - psCookie->hPMRExportHandle, - psCookie->uiPMRExportPassword, - psCookie->uiSize, /* not trusted - just for validation */ - psCookie->uiLog2ContiguityGuarantee, /* not trusted - just for validation */ - &hPMR); - PVR_GOTO_IF_ERROR(eError, failImport); - - DevmemImportStructInit(psImport, - psCookie->uiSize, - 1ULL << psCookie->uiLog2ContiguityGuarantee, - uiFlags, - hPMR, - DEVMEM_PROPERTIES_IMPORTED | - DEVMEM_PROPERTIES_EXPORTABLE); - - DevmemMemDescInit(psMemDesc, - 0, - psImport, - psImport->uiSize); - - *ppsMemDescPtr = psMemDesc; - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - /* Attach RI information */ - eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - sizeof("^"), - "^", - psMemDesc->uiOffset, - psMemDesc->psImport->uiSize, - IMG_TRUE, - IMG_TRUE, - &psMemDesc->hRIHandle); - PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry"); - } -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - return PVRSRV_OK; - - /* error exit paths follow */ - -failImport: - DevmemImportDiscard(psImport); -failImportAlloc: - DevmemMemDescDiscard(psMemDesc); -failMemDescAlloc: -failParams: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -#endif /* SUPPORT_INSECURE_EXPORT */ - -/***************************************************************************** - * Common MemDesc functions * - *****************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -DevmemUnpin(DEVMEM_MEMDESC *psMemDesc) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - DEVMEM_IMPORT *psImport = psMemDesc->psImport; - DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psImport); - - if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE) - { - eError = PVRSRV_ERROR_INVALID_REQUEST; - PVR_DPF((PVR_DBG_ERROR, - "%s: The passed allocation is not valid to unpin", - __func__)); - - goto e_exit; - } - - /* Stop if the allocation might have suballocations. */ - if (!(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE)) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: The passed allocation is not valid to unpin because " - "there might be suballocations on it. Make sure you allocate a page multiple " - "of the heap when using PVRSRVAllocDeviceMem()", - __func__)); - - goto e_exit; - } - - /* Stop if the Import is still mapped to CPU */ - if (psImport->sCPUImport.ui32RefCount) - { - eError = PVRSRV_ERROR_STILL_MAPPED; - PVR_DPF((PVR_DBG_ERROR, - "%s: There are still %u references on the CPU mapping. " - "Please remove all CPU mappings before unpinning.", - __func__, - psImport->sCPUImport.ui32RefCount)); - - goto e_exit; - } - - /* Only unpin if it is not already unpinned - * Return PVRSRV_OK */ - if (uiProperties & DEVMEM_PROPERTIES_UNPINNED) - { - goto e_exit; - } - - /* Unpin it and invalidate mapping */ - if (psImport->sDeviceImport.bMapped) - { - eError = BridgeDevmemIntUnpinInvalidate(GetBridgeHandle(psImport->hDevConnection), - psImport->sDeviceImport.hMapping, - psImport->hPMR); - } - else - { - /* Or just unpin it */ - eError = BridgeDevmemIntUnpin(GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR); - } - - /* Update flags and RI when call was successful */ - if (eError == PVRSRV_OK) - { - OSLockAcquire(psImport->hLock); - psImport->uiProperties |= DEVMEM_PROPERTIES_UNPINNED; - OSLockRelease(psImport->hLock); - } - else - { - /* Or just show what went wrong */ - PVR_DPF((PVR_DBG_ERROR, "%s: Unpin aborted because of error %d", - __func__, - eError)); - } - -e_exit: - return eError; -} - - -IMG_INTERNAL PVRSRV_ERROR -DevmemPin(DEVMEM_MEMDESC *psMemDesc) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - DEVMEM_IMPORT *psImport = psMemDesc->psImport; - DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psImport); - - if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_REQUEST, e_exit); - } - - /* Only pin if it is unpinned */ - if ((uiProperties & DEVMEM_PROPERTIES_UNPINNED) == 0) - { - goto e_exit; - } - - /* Pin it and make mapping valid */ - if (psImport->sDeviceImport.bMapped) - { - eError = BridgeDevmemIntPinValidate(GetBridgeHandle(psImport->hDevConnection), - psImport->sDeviceImport.hMapping, - psImport->hPMR); - } - else - { - /* Or just pin it */ - eError = BridgeDevmemIntPin(GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR); - } - - if ((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_PMR_NEW_MEMORY)) - { - OSLockAcquire(psImport->hLock); - psImport->uiProperties &= ~DEVMEM_PROPERTIES_UNPINNED; - OSLockRelease(psImport->hLock); - } - else - { - /* Or just show what went wrong */ - PVR_DPF((PVR_DBG_ERROR, "%s: Pin aborted because of error %d", - __func__, - eError)); - } - -e_exit: - return eError; -} - - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetSize(DEVMEM_MEMDESC *psMemDesc, IMG_DEVMEM_SIZE_T* puiSize) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - *puiSize = psMemDesc->uiAllocSize; - - return eError; -} - -IMG_INTERNAL void -DevmemGetAnnotation(DEVMEM_MEMDESC *psMemDesc, IMG_CHAR **pszAnnotation) -{ - /* - * It is expected that psMemDesc->szText is a valid NUL-terminated string, - * since DevmemMemDescAlloc uses OSAllocZMem to create the memdesc. - */ - *pszAnnotation = psMemDesc->szText; -} - -/* - This function is called for freeing any class of memory - */ -IMG_INTERNAL IMG_BOOL -DevmemFree(DEVMEM_MEMDESC *psMemDesc) -{ - if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_SECURE) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Please use methods dedicated to secure buffers.", - __func__)); - return IMG_FALSE; - } - - return DevmemMemDescRelease(psMemDesc); -} - -IMG_INTERNAL IMG_BOOL -DevmemReleaseDevAddrAndFree(DEVMEM_MEMDESC *psMemDesc) -{ - DevmemReleaseDevVirtAddr(psMemDesc); - return DevmemFree(psMemDesc); -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_HEAP *psHeap, - IMG_DEV_VIRTADDR *psDevVirtAddr) -{ - DEVMEM_IMPORT *psImport; - IMG_DEV_VIRTADDR sDevVAddr; - PVRSRV_ERROR eError; - IMG_BOOL bMap = IMG_TRUE; - IMG_BOOL bDestroyed = IMG_FALSE; - IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS; - DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psMemDesc->psImport); - - /* Do not try to map unpinned memory */ - if (uiProperties & DEVMEM_PROPERTIES_UNPINNED) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failFlags); - } - - OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock); - PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams); - - if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED, failCheck); - } - - /* Don't map memory for deferred allocations */ - if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) - { - PVR_ASSERT(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE); - bMap = IMG_FALSE; - } - - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sDeviceMemDesc.ui32RefCount, - psMemDesc->sDeviceMemDesc.ui32RefCount+1); - - psImport = psMemDesc->psImport; - DevmemMemDescAcquire(psMemDesc); - -#if defined(__KERNEL__) - if (psHeap->bPremapped) - { - ui64OptionalMapAddress = _GetPremappedVA(psImport->hPMR, psHeap->psCtx->hDevConnection); - } -#endif - - eError = DevmemImportStructDevMap(psHeap, - bMap, - psImport, - ui64OptionalMapAddress); - PVR_GOTO_IF_ERROR(eError, failMap); - - sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr; - sDevVAddr.uiAddr += psMemDesc->uiOffset; - psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr; - psMemDesc->sDeviceMemDesc.ui32RefCount++; - - *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr; - - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - - if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - BridgeDevicememHistoryMap(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset, - psMemDesc->sDeviceMemDesc.sDevVAddr, - psMemDesc->uiAllocSize, - psMemDesc->szText, - DevmemGetHeapLog2PageSize(psHeap), - psMemDesc->ui32AllocationIndex, - &psMemDesc->ui32AllocationIndex); - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - if (psMemDesc->hRIHandle) - { - eError = BridgeRIUpdateMEMDESCAddr(GetBridgeHandle(psImport->hDevConnection), - psMemDesc->hRIHandle, - psImport->sDeviceImport.sDevVAddr); - PVR_LOG_IF_ERROR(eError, "BridgeRIUpdateMEMDESCAddr"); - } - } -#endif - - return PVRSRV_OK; - -failMap: - bDestroyed = DevmemMemDescRelease(psMemDesc); -failCheck: -failParams: - if (!bDestroyed) - { - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - } - PVR_ASSERT(eError != PVRSRV_OK); -failFlags: - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemMapToDeviceAddress(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_HEAP *psHeap, - IMG_DEV_VIRTADDR sDevVirtAddr) -{ - DEVMEM_IMPORT *psImport; - IMG_DEV_VIRTADDR sDevVAddr; - PVRSRV_ERROR eError; - IMG_BOOL bMap = IMG_TRUE; - IMG_BOOL bDestroyed = IMG_FALSE; - DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psMemDesc->psImport); - - /* Do not try to map unpinned memory */ - if (uiProperties & DEVMEM_PROPERTIES_UNPINNED) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failFlags); - } - - OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock); - PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams); - - if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED, failCheck); - } - - /* Don't map memory for deferred allocations */ - if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) - { - PVR_ASSERT(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE); - bMap = IMG_FALSE; - } - - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sDeviceMemDesc.ui32RefCount, - psMemDesc->sDeviceMemDesc.ui32RefCount+1); - - psImport = psMemDesc->psImport; - DevmemMemDescAcquire(psMemDesc); - - eError = DevmemImportStructDevMap(psHeap, - bMap, - psImport, - sDevVirtAddr.uiAddr); - PVR_GOTO_IF_ERROR(eError, failMap); - - sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr; - sDevVAddr.uiAddr += psMemDesc->uiOffset; - psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr; - psMemDesc->sDeviceMemDesc.ui32RefCount++; - - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - - if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - BridgeDevicememHistoryMap(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset, - psMemDesc->sDeviceMemDesc.sDevVAddr, - psMemDesc->uiAllocSize, - psMemDesc->szText, - DevmemGetHeapLog2PageSize(psHeap), - psMemDesc->ui32AllocationIndex, - &psMemDesc->ui32AllocationIndex); - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - if (psMemDesc->hRIHandle) - { - eError = BridgeRIUpdateMEMDESCAddr(GetBridgeHandle(psImport->hDevConnection), - psMemDesc->hRIHandle, - psImport->sDeviceImport.sDevVAddr); - PVR_LOG_IF_ERROR(eError, "BridgeRIUpdateMEMDESCAddr"); - } - } -#endif - - return PVRSRV_OK; - -failMap: - bDestroyed = DevmemMemDescRelease(psMemDesc); -failCheck: -failParams: - if (!bDestroyed) - { - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - } - PVR_ASSERT(eError != PVRSRV_OK); -failFlags: - return eError; -} - -IMG_INTERNAL IMG_DEV_VIRTADDR -DevmemGetDevVirtAddr(DEVMEM_MEMDESC *psMemDesc) -{ - if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0) - { - PVR_LOG_ERROR(PVRSRV_ERROR_DEVICEMEM_NO_MAPPING, "DevmemGetDevVirtAddr"); - } - - PVR_ASSERT(psMemDesc->sDeviceMemDesc.sDevVAddr.uiAddr !=0 ); - - return psMemDesc->sDeviceMemDesc.sDevVAddr; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc, - IMG_DEV_VIRTADDR *psDevVirtAddr) -{ - PVRSRV_ERROR eError; - - /* Do not try to map unpinned memory */ - if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_UNPINNED) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failCheck); - } - - OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sDeviceMemDesc.ui32RefCount, - psMemDesc->sDeviceMemDesc.ui32RefCount+1); - - if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_NO_MAPPING, failRelease); - } - psMemDesc->sDeviceMemDesc.ui32RefCount++; - - *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr; - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - - return PVRSRV_OK; - -failRelease: - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - PVR_ASSERT(eError != PVRSRV_OK); -failCheck: - return eError; -} - -IMG_INTERNAL void -DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc) -{ - PVR_ASSERT(psMemDesc != NULL); - - OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sDeviceMemDesc.ui32RefCount, - psMemDesc->sDeviceMemDesc.ui32RefCount-1); - - PVR_ASSERT(psMemDesc->sDeviceMemDesc.ui32RefCount != 0); - - if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0) - { - if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - BridgeDevicememHistoryUnmap(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset, - psMemDesc->sDeviceMemDesc.sDevVAddr, - psMemDesc->uiAllocSize, - psMemDesc->szText, - DevmemGetHeapLog2PageSize(psMemDesc->psImport->sDeviceImport.psHeap), - psMemDesc->ui32AllocationIndex, - &psMemDesc->ui32AllocationIndex); - } - - /* When device mapping destroyed, zero Dev VA so DevmemGetDevVirtAddr() - * returns 0 */ - if (DevmemImportStructDevUnmap(psMemDesc->psImport) == IMG_TRUE) - { - psMemDesc->sDeviceMemDesc.sDevVAddr.uiAddr = 0; - } - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - - DevmemMemDescRelease(psMemDesc); - } - else - { - OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); - } -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc, - void **ppvCpuVirtAddr) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psMemDesc != NULL); - PVR_ASSERT(ppvCpuVirtAddr != NULL); - - eError = DevmemCPUMapCheckImportProperties(psMemDesc); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemCPUMapCheckImportProperties"); - - OSLockAcquire(psMemDesc->sCPUMemDesc.hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sCPUMemDesc.ui32RefCount, - psMemDesc->sCPUMemDesc.ui32RefCount+1); - - if (psMemDesc->sCPUMemDesc.ui32RefCount++ == 0) - { - DEVMEM_IMPORT *psImport = psMemDesc->psImport; - IMG_UINT8 *pui8CPUVAddr; - - DevmemMemDescAcquire(psMemDesc); - eError = DevmemImportStructCPUMap(psImport); - PVR_GOTO_IF_ERROR(eError, failMap); - - pui8CPUVAddr = psImport->sCPUImport.pvCPUVAddr; - pui8CPUVAddr += psMemDesc->uiOffset; - psMemDesc->sCPUMemDesc.pvCPUVAddr = pui8CPUVAddr; - } - *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr; - - VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize); - - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); - - return PVRSRV_OK; - -failMap: - PVR_ASSERT(eError != PVRSRV_OK); - psMemDesc->sCPUMemDesc.ui32RefCount--; - - if (!DevmemMemDescRelease(psMemDesc)) - { - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); - } - return eError; -} - -IMG_INTERNAL void -DevmemReacquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc, - void **ppvCpuVirtAddr) -{ - PVR_ASSERT(psMemDesc != NULL); - PVR_ASSERT(ppvCpuVirtAddr != NULL); - - if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_NO_CPU_MAPPING) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: CPU UnMapping is not possible on this allocation!", - __func__)); - return; - } - - OSLockAcquire(psMemDesc->sCPUMemDesc.hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sCPUMemDesc.ui32RefCount, - psMemDesc->sCPUMemDesc.ui32RefCount+1); - - *ppvCpuVirtAddr = NULL; - if (psMemDesc->sCPUMemDesc.ui32RefCount) - { - *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr; - psMemDesc->sCPUMemDesc.ui32RefCount += 1; - } - - VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize); - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); -} - -IMG_INTERNAL void -DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc) -{ - PVR_ASSERT(psMemDesc != NULL); - - if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_NO_CPU_MAPPING) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: CPU UnMapping is not possible on this allocation!", - __func__)); - return; - } - - OSLockAcquire(psMemDesc->sCPUMemDesc.hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - psMemDesc->sCPUMemDesc.ui32RefCount, - psMemDesc->sCPUMemDesc.ui32RefCount-1); - - PVR_ASSERT(psMemDesc->sCPUMemDesc.ui32RefCount != 0); - - if (--psMemDesc->sCPUMemDesc.ui32RefCount == 0) - { - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); - DevmemImportStructCPUUnmap(psMemDesc->psImport); - DevmemMemDescRelease(psMemDesc); - } - else - { - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); - } -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *phImport) -{ - if ((GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0) - { - return PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION; - } - - *phImport = psMemDesc->psImport->hPMR; - - return PVRSRV_OK; -} - -#if !defined(__KERNEL__) -IMG_INTERNAL PVRSRV_ERROR -DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc, - IMG_UINT64 *pui64UID) -{ - DEVMEM_IMPORT *psImport = psMemDesc->psImport; - PVRSRV_ERROR eError; - - if (!(GetImportProperties(psImport) & (DEVMEM_PROPERTIES_IMPORTED | - DEVMEM_PROPERTIES_EXPORTABLE))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This Memory (0x%p) doesn't support the functionality requested...", - __func__, psMemDesc)); - return PVRSRV_ERROR_INVALID_REQUEST; - } - - eError = BridgePMRGetUID(GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR, - pui64UID); - - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *hReservation) -{ - DEVMEM_IMPORT *psImport; - - PVR_ASSERT(psMemDesc); - psImport = psMemDesc->psImport; - - PVR_ASSERT(psImport); - *hReservation = psImport->sDeviceImport.hReservation; - - return PVRSRV_OK; -} - -#endif /* !__KERNEL__ */ - -/* Kernel usage of this function will only work with - * memdescs of buffers allocated in the FW memory context - * that is created in the Server - */ -void -DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *phPMR, - IMG_DEVMEM_OFFSET_T *puiPMROffset) -{ - DEVMEM_IMPORT *psImport; - - PVR_ASSERT(psMemDesc); - *puiPMROffset = psMemDesc->uiOffset; - psImport = psMemDesc->psImport; - - PVR_ASSERT(psImport); - *phPMR = psImport->hPMR; -} - -#if defined(__KERNEL__) -IMG_INTERNAL void -DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc, - PVRSRV_MEMALLOCFLAGS_T *puiFlags) -{ - DEVMEM_IMPORT *psImport; - - PVR_ASSERT(psMemDesc); - psImport = psMemDesc->psImport; - - PVR_ASSERT(psImport); - *puiFlags = psImport->uiFlags; -} - -IMG_INTERNAL SHARED_DEV_CONNECTION -DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc) -{ - return psMemDesc->psImport->hDevConnection; -} -#endif /* __KERNEL__ */ - -IMG_INTERNAL PVRSRV_ERROR -DevmemLocalImport(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hExtHandle, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEM_MEMDESC **ppsMemDescPtr, - IMG_DEVMEM_SIZE_T *puiSizePtr, - const IMG_CHAR *pszAnnotation) -{ - DEVMEM_MEMDESC *psMemDesc = NULL; - DEVMEM_IMPORT *psImport; - IMG_DEVMEM_SIZE_T uiSize; - IMG_DEVMEM_ALIGN_T uiAlign; - IMG_HANDLE hPMR; - PVRSRV_ERROR eError; - - PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams); - - eError = DevmemMemDescAlloc(&psMemDesc); - PVR_GOTO_IF_ERROR(eError, failMemDescAlloc); - - eError = DevmemImportStructAlloc(hDevConnection, - &psImport); - if (eError != PVRSRV_OK) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, failImportAlloc); - } - - /* Get the PMR handle and its size from the server */ - eError = BridgePMRLocalImportPMR(GetBridgeHandle(hDevConnection), - hExtHandle, - &hPMR, - &uiSize, - &uiAlign); - PVR_GOTO_IF_ERROR(eError, failImport); - - DevmemImportStructInit(psImport, - uiSize, - uiAlign, - uiFlags, - hPMR, - DEVMEM_PROPERTIES_IMPORTED | - DEVMEM_PROPERTIES_EXPORTABLE); - - DevmemMemDescInit(psMemDesc, - 0, - psImport, - uiSize); - - *ppsMemDescPtr = psMemDesc; - if (puiSizePtr) - *puiSizePtr = uiSize; - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI)) - { - /* Attach RI information. - * Set backed size to 0 since this allocation has been allocated - * by the same process and has been accounted for. */ - eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - sizeof("^"), - "^", - psMemDesc->uiOffset, - psMemDesc->psImport->uiSize, - IMG_TRUE, - IMG_FALSE, - &(psMemDesc->hRIHandle)); - PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry"); - } -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - - /* Copy the allocation descriptive name and size so it can be passed - * to DevicememHistory when the allocation gets mapped/unmapped - */ - CheckAnnotationLength(pszAnnotation); - OSStringLCopy(psMemDesc->szText, pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN); - - return PVRSRV_OK; - -failImport: - DevmemImportDiscard(psImport); -failImportAlloc: - DevmemMemDescDiscard(psMemDesc); -failMemDescAlloc: -failParams: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -#if !defined(__KERNEL__) -IMG_INTERNAL PVRSRV_ERROR -DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext, - IMG_DEV_VIRTADDR sDevVAddr) -{ - return BridgeDevmemIsVDevAddrValid(GetBridgeHandle(psContext->hDevConnection), - psContext->hDevMemServerContext, - sDevVAddr); -} - - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetFaultAddress(DEVMEM_CONTEXT *psContext, - IMG_DEV_VIRTADDR *psFaultAddress) -{ - return BridgeDevmemGetFaultAddress(GetBridgeHandle(psContext->hDevConnection), - psContext->hDevMemServerContext, - psFaultAddress); -} -IMG_INTERNAL PVRSRV_ERROR -DevmemFlushDeviceSLCRange(DEVMEM_MEMDESC *psMemDesc, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate) -{ - DEVMEM_IMPORT *psImport = psMemDesc->psImport; - return BridgeDevmemFlushDevSLCRange(GetBridgeHandle(psImport->hDevConnection), - psImport->sDeviceImport.psHeap->psCtx->hDevMemServerContext, - sDevVAddr, - uiSize, - bInvalidate); -} - -#if defined(RGX_FEATURE_FBCDC) -IMG_INTERNAL PVRSRV_ERROR -DevmemInvalidateFBSCTable(DEVMEM_CONTEXT *psContext, - IMG_UINT64 ui64FBSCEntries) -{ - return BridgeDevmemInvalidateFBSCTable(GetBridgeHandle(psContext->hDevConnection), - psContext->hDevMemServerContext, - ui64FBSCEntries); -} -#endif - -#endif /* !__KERNEL__ */ - -IMG_INTERNAL IMG_UINT32 -DevmemGetHeapLog2PageSize(DEVMEM_HEAP *psHeap) -{ - return psHeap->uiLog2Quantum; -} - -IMG_INTERNAL PVRSRV_MEMALLOCFLAGS_T -DevmemGetMemAllocFlags(DEVMEM_MEMDESC *psMemDesc) -{ - return psMemDesc->psImport->uiFlags; -} - -IMG_INTERNAL IMG_DEVMEM_SIZE_T -DevmemGetHeapReservedSize(DEVMEM_HEAP *psHeap) -{ - return psHeap->uiReservedRegionSize; -} - -#if !defined(__KERNEL__) -/**************************************************************************/ /*! -@Function RegisterDevMemPFNotify -@Description Registers that the application wants to be signaled when a page - fault occurs. - -@Input psContext Memory context the process that would like to - be notified about. -@Input ui32PID The PID of the calling process. -@Input bRegister If true, register. If false, de-register. -@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code - */ /***************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext, - IMG_UINT32 ui32PID, - IMG_BOOL bRegister) -{ - PVRSRV_ERROR eError; - - eError = BridgeDevmemIntRegisterPFNotifyKM(GetBridgeHandle(psContext->hDevConnection), - psContext->hDevMemServerContext, - ui32PID, - bRegister); - if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - PVR_LOG_ERROR(eError, "BridgeDevmemIntRegisterPFNotifyKM"); - } - - return eError; -} -#endif /* !__KERNEL__ */ - -IMG_INTERNAL void -DevmemHeapSetPremapStatus(DEVMEM_HEAP *psHeap, IMG_BOOL IsPremapped) -{ - psHeap->bPremapped = IsPremapped; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem.h b/drivers/gpu/drm/img-rogue/1.17/devicemem.h deleted file mode 100644 index 1466eb387baf8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem.h +++ /dev/null @@ -1,730 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management core internal -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services internal interface to core device memory management - functions that are shared between client and server code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVCLIENT_DEVICEMEM_H -#define SRVCLIENT_DEVICEMEM_H - -/****************************************************************************** - * * - * +------------+ +------------+ +--------------+ +--------------+ * - * | a sub- | | a sub- | | an | | allocation | * - * | allocation | | allocation | | allocation | | also mapped | * - * | | | | | in proc 1 | | into proc 2 | * - * +------------+ +------------+ +--------------+ +--------------+ * - * | | | | * - * +--------------+ +--------------+ +--------------+ * - * | page gran- | | page gran- | | page gran- | * - * | ular mapping | | ular mapping | | ular mapping | * - * +--------------+ +--------------+ +--------------+ * - * | | | * - * | | | * - * | | | * - * +--------------+ +--------------+ * - * | | | | * - * | A "P.M.R." | | A "P.M.R." | * - * | | | | * - * +--------------+ +--------------+ * - * * - ******************************************************************************/ - -/* - All device memory allocations are ultimately a view upon (not - necessarily the whole of) a "PMR". - - A PMR is a "Physical Memory Resource", which may be a - "pre-faulted" lump of physical memory, or it may be a - representation of some physical memory that will be instantiated - at some future time. - - PMRs always represent multiple of some power-of-2 "contiguity" - promised by the PMR, which will allow them to be mapped in whole - pages into the device MMU. As memory allocations may be smaller - than a page, these mappings may be suballocated and thus shared - between multiple allocations in one process. A PMR may also be - mapped simultaneously into multiple device memory contexts - (cross-process scenario), however, for security reasons, it is not - legal to share a PMR "both ways" at once, that is, mapped into - multiple processes and divided up amongst several suballocations. - - This PMR terminology is introduced here for background - information, but is generally of little concern to the caller of - this API. This API handles suballocations and mappings, and the - caller thus deals primarily with MEMORY DESCRIPTORS representing - an allocation or suballocation, HEAPS representing ranges of - virtual addresses in a CONTEXT. -*/ - -/* - |<---------------------------context------------------------------>| - |<-------heap------->| |<-------heap------->|<-------heap------->| - |<-alloc->| | |<-alloc->|<-alloc->|| |<-alloc->| | -*/ - -#include "img_types.h" -#include "img_defs.h" -#include "devicemem_typedefs.h" -#include "pdumpdefs.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" - -#include "pdump.h" - -#include "device_connection.h" - - -typedef IMG_UINT32 DEVMEM_HEAPCFGID; -#define DEVMEM_HEAPCFG_FORCLIENTS 0 -#define DEVMEM_HEAPCFG_META 1 - - -/* - In order to call the server side functions, we need a bridge handle. - We abstract that here, as we may wish to change its form. - */ - -typedef IMG_HANDLE DEVMEM_BRIDGE_HANDLE; - -/*************************************************************************/ /*! -@Function DevmemUnpin -@Description This is the counterpart to DevmemPin(). It is meant to be - called before repinning an allocation. - - For a detailed description see client API documentation. - -@Input phMemDesc The MemDesc that is going to be unpinned. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is - registered to be reclaimed. Error otherwise. -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -DevmemUnpin(DEVMEM_MEMDESC *psMemDesc); - -/*************************************************************************/ /*! -@Function DevmemPin -@Description This is the counterpart to DevmemUnpin(). It is meant to be - called after unpinning an allocation. - - For a detailed description see client API documentation. - -@Input phMemDesc The MemDesc that is going to be pinned. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content - was successfully restored. - - PVRSRV_ERROR_PMR_NEW_MEMORY when the content - could not be restored and new physical memory - was allocated. - - A different error otherwise. -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -DevmemPin(DEVMEM_MEMDESC *psMemDesc); - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetHeapInt(DEVMEM_HEAP *psHeap, - IMG_HANDLE *phDevmemHeap); - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetSize(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_SIZE_T* puiSize); - -IMG_INTERNAL void -DevmemGetAnnotation(DEVMEM_MEMDESC *psMemDesc, - IMG_CHAR **pszAnnotation); - -/* - * DevmemCreateContext() - * - * Create a device memory context - * - * This must be called before any heap is created in this context - * - * Caller to provide bridge handle which will be recorded internally and used - * for all future operations on items from this memory context. Caller also - * to provide devicenode handle, as this is used for MMU configuration and - * also to determine the heap configuration for the auto-instantiated heaps. - * - * Note that when compiled in services/server, the hBridge is not used and - * is thrown away by the "fake" direct bridge. (This may change. It is - * recommended that NULL be passed for the handle for now.) - * - * hDeviceNode and uiHeapBlueprintID shall together dictate which heap-config - * to use. - * - * This will cause the server side counterpart to be created also. - * - * If you call DevmemCreateContext() (and the call succeeds) you are promising - * that you will later call Devmem_ContextDestroy(), except for abnormal - * process termination in which case it is expected it will be destroyed as - * part of handle clean up. - * - * Caller to provide storage for the pointer to the newly created - * NEWDEVMEM_CONTEXT object. - */ -PVRSRV_ERROR -DevmemCreateContext(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_HEAPCFGID uiHeapBlueprintID, - DEVMEM_CONTEXT **ppsCtxPtr); - -/* - * DevmemAcquireDevPrivData() - * - * Acquire the device private data for this memory context - */ -PVRSRV_ERROR -DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx, - IMG_HANDLE *hPrivData); - -/* - * DevmemReleaseDevPrivData() - * - * Release the device private data for this memory context - */ -PVRSRV_ERROR -DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx); - -/* - * DevmemDestroyContext() - * - * Undoes that done by DevmemCreateContext() - */ -PVRSRV_ERROR -DevmemDestroyContext(DEVMEM_CONTEXT *psCtx); - -/* - * DevmemCreateHeap() - * - * Create a heap in the given context. - * - * N.B. Not intended to be called directly, though it can be. - * Normally, heaps are instantiated at context creation time according - * to the specified blueprint. See DevmemCreateContext() for details. - * - * This will cause MMU code to set up data structures for the heap, - * but may not cause page tables to be modified until allocations are - * made from the heap. - * - * uiReservedRegionLength Reserved address space for static VAs shared - * between clients and firmware - * - * The "Quantum" is both the device MMU page size to be configured for - * this heap, and the unit multiples of which "quantized" allocations - * are made (allocations smaller than this, known as "suballocations" - * will be made from a "sub alloc RA" and will "import" chunks - * according to this quantum) - * - * Where imported PMRs (or, for example, PMRs created by device class - * buffers) are mapped into this heap, it is important that the - * physical contiguity guarantee offered by the PMR is greater than or - * equal to the quantum size specified here, otherwise the attempt to - * map it will fail. "Normal" allocations via Devmem_Allocate - * shall automatically meet this requirement, as each "import" will - * trigger the creation of a PMR with the desired contiguity. The - * supported quantum sizes in that case shall be dictated by the OS - * specific implementation of PhysmemNewOSRamBackedPMR() (see) - */ -PVRSRV_ERROR -DevmemCreateHeap(DEVMEM_CONTEXT *psCtxPtr, - /* base and length of heap */ - IMG_DEV_VIRTADDR sBaseAddress, - IMG_DEVMEM_SIZE_T uiLength, - IMG_DEVMEM_SIZE_T uiReservedRegionLength, - /* log2 of allocation quantum, i.e. "page" size. - All allocations (that go to server side) are - multiples of this. We use a client-side RA to - make sub-allocations from this */ - IMG_UINT32 ui32Log2Quantum, - /* The minimum import alignment for this heap */ - IMG_UINT32 ui32Log2ImportAlignment, - /* Name of heap for debug */ - /* N.B. Okay to exist on caller's stack - this - func takes a copy if it needs it. */ - const IMG_CHAR *pszName, - DEVMEM_HEAPCFGID uiHeapBlueprintID, - DEVMEM_HEAP **ppsHeapPtr); -/* - * DevmemDestroyHeap() - * - * Reverses DevmemCreateHeap() - * - * N.B. All allocations must have been freed and all mappings must - * have been unmapped before invoking this call - */ -PVRSRV_ERROR -DevmemDestroyHeap(DEVMEM_HEAP *psHeap); - -/* - * DevmemExportalignAdjustSizeAndAlign() - * Compute the Size and Align passed to avoid suballocations - * (used when allocation with PVRSRV_MEMALLOCFLAG_EXPORTALIGN). - * - * Returns PVRSRV_ERROR_INVALID_PARAMS if uiLog2Quantum has invalid value. - */ -IMG_INTERNAL PVRSRV_ERROR -DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign); - -/* - * DevmemSubAllocate() - * - * Makes an allocation (possibly a "suballocation", as described - * below) of device virtual memory from this heap. - * - * The size and alignment of the allocation will be honoured by the RA - * that allocates the "suballocation". The resulting allocation will - * be mapped into GPU virtual memory and the physical memory to back - * it will exist, by the time this call successfully completes. - * - * The size must be a positive integer multiple of the alignment. - * (i.e. the alignment specifies the alignment of both the start and - * the end of the resulting allocation.) - * - * Allocations made via this API are routed through a "suballocation - * RA" which is responsible for ensuring that small allocations can be - * made without wasting physical memory in the server. Furthermore, - * such suballocations can be made entirely client side without - * needing to go to the server unless the allocation spills into a new - * page. - * - * Such suballocations cause many allocations to share the same "PMR". - * This happens only when the flags match exactly. - * - */ - -PVRSRV_ERROR -DevmemSubAllocate(IMG_UINT8 uiPreAllocMultiplier, - DEVMEM_HEAP *psHeap, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr); - -#define DevmemAllocate(...) \ - DevmemSubAllocate(DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER, __VA_ARGS__) - -PVRSRV_ERROR -DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_UINT32 uiLog2HeapPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr); - -PVRSRV_ERROR -DeviceMemChangeSparse(DEVMEM_MEMDESC *psMemDesc, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *paui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pauiFreePageIndices, - SPARSE_MEM_RESIZE_FLAGS uiFlags); - -PVRSRV_ERROR -DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_UINT32 uiLog2HeapPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr); - -PVRSRV_ERROR -DevmemSubAllocateAndMap(IMG_UINT8 uiPreAllocMultiplier, - DEVMEM_HEAP *psHeap, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr, - IMG_DEV_VIRTADDR *psDevVirtAddr); - -#define DevmemAllocateAndMap(...) \ - DevmemSubAllocateAndMap(DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER, __VA_ARGS__) - -/* - * DevmemFree() - * - * Reverses that done by DevmemSubAllocate() N.B. The underlying - * mapping and server side allocation _may_ not be torn down, for - * example, if the allocation has been exported, or if multiple - * allocations were suballocated from the same mapping, but this is - * properly refcounted, so the caller does not have to care. - */ - -IMG_BOOL -DevmemFree(DEVMEM_MEMDESC *psMemDesc); - -IMG_BOOL -DevmemReleaseDevAddrAndFree(DEVMEM_MEMDESC *psMemDesc); - -/* - DevmemMapToDevice: - - Map an allocation to the device it was allocated from. - This function _must_ be called before any call to - DevmemAcquireDevVirtAddr is made as it binds the allocation - to the heap. - DevmemReleaseDevVirtAddr is used to release the reference - to the device mapping this function created, but it doesn't - mean that the memory will actually be unmapped from the - device as other references to the mapping obtained via - DevmemAcquireDevVirtAddr could still be active. -*/ -PVRSRV_ERROR DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_HEAP *psHeap, - IMG_DEV_VIRTADDR *psDevVirtAddr); - -/* - DevmemMapToDeviceAddress: - - Same as DevmemMapToDevice but the caller chooses the address - to map to. -*/ -IMG_INTERNAL PVRSRV_ERROR -DevmemMapToDeviceAddress(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_HEAP *psHeap, - IMG_DEV_VIRTADDR sDevVirtAddr); - -/* - DevmemGetDevVirtAddr - - Obtain the MemDesc's device virtual address. - This function _must_ be called after DevmemMapToDevice(Address) - and is expected to be used be functions which didn't allocate - the MemDesc but need to know it's address. - It will PVR_ASSERT if no device mapping exists and 0 is returned. - */ -IMG_DEV_VIRTADDR -DevmemGetDevVirtAddr(DEVMEM_MEMDESC *psMemDesc); - -/* - DevmemAcquireDevVirtAddr - - Acquire the MemDesc's device virtual address. - This function _must_ be called after DevmemMapToDevice - and is expected to be used be functions which didn't allocate - the MemDesc but need to know it's address - */ -PVRSRV_ERROR DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc, - IMG_DEV_VIRTADDR *psDevVirtAddrRet); - -/* - * DevmemReleaseDevVirtAddr() - * - * give up the licence to use the device virtual address that was - * acquired by "Acquire" or "MapToDevice" - */ -void -DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc); - -/* - * DevmemAcquireCpuVirtAddr() - * - * Acquires a license to use the cpu virtual address of this mapping. - * Note that the memory may not have been mapped into cpu virtual - * memory prior to this call. On first "acquire" the memory will be - * mapped in (if it wasn't statically mapped in) and on last put it - * _may_ become unmapped. Later calling "Acquire" again, _may_ cause - * the memory to be mapped at a different address. - */ -PVRSRV_ERROR DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc, - void **ppvCpuVirtAddr); - -/* - * DevmemReacquireCpuVirtAddr() - * - * (Re)acquires license to use the cpu virtual address of this mapping - * if (and only if) there is already a pre-existing license to use the - * cpu virtual address for the mapping, returns NULL otherwise. - */ -void DevmemReacquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc, - void **ppvCpuVirtAddr); - -/* - * DevmemReleaseDevVirtAddr() - * - * give up the licence to use the cpu virtual address that was granted - * with the "Get" call. - */ -void -DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc); - -#if defined(SUPPORT_INSECURE_EXPORT) -/* - * DevmemExport() - * - * Given a memory allocation allocated with DevmemAllocateExportable() - * create a "cookie" that can be passed intact by the caller's own choice - * of secure IPC to another process and used as the argument to "map" - * to map this memory into a heap in the target processes. N.B. This can - * also be used to map into multiple heaps in one process, though that's not - * the intention. - * - * Note, the caller must later call Unexport before freeing the - * memory. - */ -PVRSRV_ERROR DevmemExport(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_EXPORTCOOKIE *psExportCookie); - - -void DevmemUnexport(DEVMEM_MEMDESC *psMemDesc, - DEVMEM_EXPORTCOOKIE *psExportCookie); - -PVRSRV_ERROR -DevmemImport(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_EXPORTCOOKIE *psCookie, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEM_MEMDESC **ppsMemDescPtr); -#endif /* SUPPORT_INSECURE_EXPORT */ - -/* - * DevmemMakeLocalImportHandle() - * - * This is a "special case" function for making a server export cookie - * which went through the direct bridge into an export cookie that can - * be passed through the client bridge. - */ -PVRSRV_ERROR -DevmemMakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hServerExport, - IMG_HANDLE *hClientExport); - -/* - * DevmemUnmakeLocalImportHandle() - * - * Free any resource associated with the Make operation - */ -PVRSRV_ERROR -DevmemUnmakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hClientExport); - -/* - * - * The following set of functions is specific to the heap "blueprint" - * stuff, for automatic creation of heaps when a context is created - * - */ - - -/* Devmem_HeapConfigCount: returns the number of heap configs that - this device has. Note that there is no acquire/release semantics - required, as this data is guaranteed to be constant for the - lifetime of the device node */ -PVRSRV_ERROR -DevmemHeapConfigCount(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 *puiNumHeapConfigsOut); - -/* Devmem_HeapCount: returns the number of heaps that a given heap - config on this device has. Note that there is no acquire/release - semantics required, as this data is guaranteed to be constant for - the lifetime of the device node */ -PVRSRV_ERROR -DevmemHeapCount(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 *puiNumHeapsOut); -/* Devmem_HeapConfigName: return the name of the given heap config. - The caller is to provide the storage for the returned string and - indicate the number of bytes (including null terminator) for such - string in the BufSz arg. Note that there is no acquire/release - semantics required, as this data is guaranteed to be constant for - the lifetime of the device node. - */ -PVRSRV_ERROR -DevmemHeapConfigName(SHARED_DEV_CONNECTION hsDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_CHAR *pszConfigNameOut, - IMG_UINT32 uiConfigNameBufSz); - -/* Devmem_HeapDetails: fetches all the metadata that is recorded in - this heap "blueprint". Namely: heap name (caller to provide - storage, and indicate buffer size (including null terminator) in - BufSz arg), device virtual address and length, log2 of data page - size (will be one of 12, 14, 16, 18, 20, 21, at time of writing). - Note that there is no acquire/release semantics required, as this - data is guaranteed to be constant for the lifetime of the device - node. */ -PVRSRV_ERROR -DevmemHeapDetails(SHARED_DEV_CONNECTION hDevConnection, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapIndex, - IMG_CHAR *pszHeapNameOut, - IMG_UINT32 uiHeapNameBufSz, - IMG_DEV_VIRTADDR *psDevVAddrBaseOut, - IMG_DEVMEM_SIZE_T *puiHeapLengthOut, - IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut, - IMG_UINT32 *puiLog2DataPageSize, - IMG_UINT32 *puiLog2ImportAlignmentOut); - -/* - * Devmem_FindHeapByName() - * - * returns the heap handle for the named _automagic_ heap in this - * context. "automagic" heaps are those that are born with the - * context from a blueprint - */ -PVRSRV_ERROR -DevmemFindHeapByName(const DEVMEM_CONTEXT *psCtx, - const IMG_CHAR *pszHeapName, - DEVMEM_HEAP **ppsHeapRet); - -/* - * DevmemGetHeapBaseDevVAddr() - * - * returns the device virtual address of the base of the heap. - */ - -PVRSRV_ERROR -DevmemGetHeapBaseDevVAddr(DEVMEM_HEAP *psHeap, - IMG_DEV_VIRTADDR *pDevVAddr); - -PVRSRV_ERROR -DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *phImport); - -PVRSRV_ERROR -DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc, - IMG_UINT64 *pui64UID); - -PVRSRV_ERROR -DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *hReservation); - -IMG_INTERNAL void -DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *hPMR, - IMG_DEVMEM_OFFSET_T *puiPMROffset); - -IMG_INTERNAL void -DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc, - PVRSRV_MEMALLOCFLAGS_T *puiFlags); - -IMG_INTERNAL SHARED_DEV_CONNECTION -DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc); - -PVRSRV_ERROR -DevmemLocalImport(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hExtHandle, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEM_MEMDESC **ppsMemDescPtr, - IMG_DEVMEM_SIZE_T *puiSizePtr, - const IMG_CHAR *pszAnnotation); - -IMG_INTERNAL PVRSRV_ERROR -DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext, - IMG_DEV_VIRTADDR sDevVAddr); - -IMG_INTERNAL PVRSRV_ERROR -DevmemGetFaultAddress(DEVMEM_CONTEXT *psContext, - IMG_DEV_VIRTADDR *psFaultAddress); - -IMG_INTERNAL PVRSRV_ERROR -DevmemFlushDeviceSLCRange(DEVMEM_MEMDESC *psMemDesc, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate); - -IMG_INTERNAL PVRSRV_ERROR -DevmemInvalidateFBSCTable(DEVMEM_CONTEXT *psContext, - IMG_UINT64 ui64FBSCEntries); - -/* DevmemGetHeapLog2PageSize() - * - * Get the page size used for a certain heap. - */ -IMG_UINT32 -DevmemGetHeapLog2PageSize(DEVMEM_HEAP *psHeap); - -/* DevmemGetMemFlags() - * - * Get the memalloc flags for a certain memdesc. - */ -PVRSRV_MEMALLOCFLAGS_T -DevmemGetMemAllocFlags(DEVMEM_MEMDESC *psMemDesc); - -/* DevmemGetHeapReservedSize() - * - * Get the reserved size used for a certain heap. - */ -IMG_DEVMEM_SIZE_T -DevmemGetHeapReservedSize(DEVMEM_HEAP *psHeap); - -/*************************************************************************/ /*! -@Function RegisterDevMemPFNotify -@Description Registers that the application wants to be signaled when a page - fault occurs. - -@Input psContext Memory context the process that would like to - be notified about. -@Input ui32PID The PID of the calling process. -@Input bRegister If true, register. If false, de-register. -@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext, - IMG_UINT32 ui32PID, - IMG_BOOL bRegister); - -/*************************************************************************/ /*! -@Function DevmemHeapSetPremapStatus -@Description In some special cases like virtualisation, a device memory heap - must be entirely backed by physical memory and mapped into the - device's virtual address space. This is done at context creation. - When objects are allocated from such a heap, the mapping part - must be skipped. The 'bPremapped' flag dictates if allocations - are to be mapped or not. - -@Input psHeap Device memory heap to be updated -@Input IsPremapped The premapping status to be set -*/ /**************************************************************************/ -IMG_INTERNAL void -DevmemHeapSetPremapStatus(DEVMEM_HEAP *psHeap, IMG_BOOL IsPremapped); - -#endif /* #ifndef SRVCLIENT_DEVICEMEM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.c b/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.c deleted file mode 100644 index f38a612cd14dc..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.c +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************/ /*! -@File devicemem_heapcfg.c -@Title Device Heap Configuration Helper Functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device memory management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -/* our exported API */ -#include "devicemem_heapcfg.h" -#include "devicemem_utils.h" - -#include "device.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "osfunc.h" - -#include "connection_server.h" - -static INLINE void _CheckBlueprintHeapAlignment(DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint) -{ - IMG_UINT32 ui32OSPageSize = OSGetPageShift(); - - /* Any heap length should at least match OS page size at the minimum or - * a multiple of OS page size */ - if ((psHeapBlueprint->uiHeapLength < DEVMEM_HEAP_MINIMUM_SIZE) || - (psHeapBlueprint->uiHeapLength & (ui32OSPageSize - 1))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid Heap \"%s\" Size: " - "%"IMG_UINT64_FMTSPEC - "("IMG_DEVMEM_SIZE_FMTSPEC")", - __func__, - psHeapBlueprint->pszName, - psHeapBlueprint->uiHeapLength, - psHeapBlueprint->uiHeapLength)); - PVR_DPF((PVR_DBG_ERROR, - "Heap Size should always be a non-zero value and a " - "multiple of OS Page Size:%u(0x%x)", - ui32OSPageSize, ui32OSPageSize)); - PVR_ASSERT(psHeapBlueprint->uiHeapLength >= ui32OSPageSize); - } - - - PVR_ASSERT(psHeapBlueprint->uiReservedRegionLength % DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY == 0); -} - -void HeapCfgBlueprintInit(const IMG_CHAR *pszName, - IMG_UINT64 ui64HeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_DEVMEM_SIZE_T uiReservedRegionLength, - IMG_UINT32 ui32Log2DataPageSize, - IMG_UINT32 uiLog2ImportAlignment, - DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint) -{ - psHeapBlueprint->pszName = pszName; - psHeapBlueprint->sHeapBaseAddr.uiAddr = ui64HeapBaseAddr; - psHeapBlueprint->uiHeapLength = uiHeapLength; - psHeapBlueprint->uiReservedRegionLength = uiReservedRegionLength; - psHeapBlueprint->uiLog2DataPageSize = ui32Log2DataPageSize; - psHeapBlueprint->uiLog2ImportAlignment = uiLog2ImportAlignment; - - _CheckBlueprintHeapAlignment(psHeapBlueprint); -} - -PVRSRV_ERROR -HeapCfgHeapConfigCount(CONNECTION_DATA * psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *puiNumHeapConfigsOut) -{ - - PVR_UNREFERENCED_PARAMETER(psConnection); - - *puiNumHeapConfigsOut = psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -HeapCfgHeapCount(CONNECTION_DATA * psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 *puiNumHeapsOut) -{ - if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs) - { - return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX; - } - - *puiNumHeapsOut = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -HeapCfgHeapConfigName(CONNECTION_DATA * psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapConfigNameBufSz, - IMG_CHAR *pszHeapConfigNameOut) -{ - if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs) - { - return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX; - } - - OSSNPrintf(pszHeapConfigNameOut, uiHeapConfigNameBufSz, "%s", psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].pszName); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -HeapCfgHeapDetails(CONNECTION_DATA * psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapIndex, - IMG_UINT32 uiHeapNameBufSz, - IMG_CHAR *pszHeapNameOut, - IMG_DEV_VIRTADDR *psDevVAddrBaseOut, - IMG_DEVMEM_SIZE_T *puiHeapLengthOut, - IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut, - IMG_UINT32 *puiLog2DataPageSizeOut, - IMG_UINT32 *puiLog2ImportAlignmentOut) -{ - DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint; - - if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs) - { - return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX; - } - - if (uiHeapIndex >= psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps) - { - return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX; - } - - psHeapBlueprint = &psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].psHeapBlueprintArray[uiHeapIndex]; - - OSSNPrintf(pszHeapNameOut, uiHeapNameBufSz, "%s", psHeapBlueprint->pszName); - *psDevVAddrBaseOut = psHeapBlueprint->sHeapBaseAddr; - *puiHeapLengthOut = psHeapBlueprint->uiHeapLength; - *puiReservedRegionLengthOut = psHeapBlueprint->uiReservedRegionLength; - *puiLog2DataPageSizeOut = psHeapBlueprint->uiLog2DataPageSize; - *puiLog2ImportAlignmentOut = psHeapBlueprint->uiLog2ImportAlignment; - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.h deleted file mode 100644 index 3f0bb7c94e869..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_heapcfg.h +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Device Heap Configuration Helper Functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device memory management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEMHEAPCFG_H -#define DEVICEMEMHEAPCFG_H - -#include - -#include "img_types.h" -#include "pvrsrv_error.h" - -/* - * Supported log2 page size values for RGX_GENERAL_NON_4K_HEAP_ID - */ -#define RGX_HEAP_PAGE_SHIFTS_DEF \ - X(4KB, 12U) \ - X(16KB, 14U) \ - X(64KB, 16U) \ - X(256KB, 18U) \ - X(1MB, 20U) \ - X(2MB, 21U) - -typedef enum RGX_HEAP_PAGE_SHIFTS_TAG -{ -#define X(_name, _shift) RGX_HEAP_ ## _name ## _PAGE_SHIFT = _shift, - RGX_HEAP_PAGE_SHIFTS_DEF -#undef X -} RGX_HEAP_PAGE_SHIFTS; - -struct _PVRSRV_DEVICE_NODE_; -struct _CONNECTION_DATA_; - - -/* - A "heap config" is a blueprint to be used for initial setting up of heaps - when a device memory context is created. - - We define a data structure to define this, but it's really down to the - caller to populate it. This is all expected to be in-kernel. We provide an - API that client code can use to enquire about the blueprint, such that it may - do the heap set-up during the context creation call on behalf of the user. -*/ - -/* Blueprint for a single heap */ -typedef struct _DEVMEM_HEAP_BLUEPRINT_ -{ - /* Name of this heap - for debug purposes, and perhaps for lookup - by name */ - const IMG_CHAR *pszName; - - /* Virtual address of the beginning of the heap. This _must_ be a - multiple of the data page size for the heap. It is - _recommended_ that it be coarser than that - especially, it - should begin on a boundary appropriate to the MMU for the - device. For Rogue, this is a Page Directory boundary, or 1GB - (virtual address a multiple of 0x0040000000). */ - IMG_DEV_VIRTADDR sHeapBaseAddr; - - /* Length of the heap. Given that the END address of the heap has - a similar restriction to that of the _beginning_ of the heap. - That is the heap length _must_ be a whole number of data pages. - Again, the recommendation is that it ends on a 1GB boundary. - Again, this is not essential, but we do know that (at the time - of writing) the current implementation of mmu_common.c is such - that no two heaps may share a page directory, thus the - remaining virtual space would be wasted if the length were not - a multiple of 1GB */ - IMG_DEVMEM_SIZE_T uiHeapLength; - - /* VA space starting sHeapBaseAddr to uiReservedRegionLength-1 are reserved - for statically defined addresses (shared/known between clients and FW). - Services never maps allocations into this reserved address space _unless_ - explicitly requested via PVRSRVMapToDeviceAddress by passing sDevVirtAddr - which falls within this reserved range. Since this range is completely for - clients to manage (where allocations are page granular), it _must_ again be - a whole number of data pages. Additionally, another constraint enforces this - to be a multiple of DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY (which evaluates to - max page size supported) to support varied pages sizes */ - IMG_DEVMEM_SIZE_T uiReservedRegionLength; - - /* Data page size. This is the page size that is going to get - programmed into the MMU, so it needs to be a valid one for the - device. Importantly, the start address and length _must_ be - multiples of this page size. Note that the page size is - specified as the log 2 relative to 1 byte (e.g. 12 indicates - 4kB) */ - IMG_UINT32 uiLog2DataPageSize; - - /* Import alignment. Force imports to this heap to be - aligned to at least this value */ - IMG_UINT32 uiLog2ImportAlignment; - -} DEVMEM_HEAP_BLUEPRINT; - -void HeapCfgBlueprintInit(const IMG_CHAR *pszName, - IMG_UINT64 ui64HeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_DEVMEM_SIZE_T uiReservedRegionLength, - IMG_UINT32 ui32Log2DataPageSize, - IMG_UINT32 uiLog2ImportAlignment, - DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint); - -/* Entire named heap config */ -typedef struct _DEVMEM_HEAP_CONFIG_ -{ - /* Name of this heap config - for debug and maybe lookup */ - const IMG_CHAR *pszName; - - /* Number of heaps in this config */ - IMG_UINT32 uiNumHeaps; - - /* Array of individual heap blueprints as defined above */ - DEVMEM_HEAP_BLUEPRINT *psHeapBlueprintArray; -} DEVMEM_HEAP_CONFIG; - - -PVRSRV_ERROR -HeapCfgHeapConfigCount(struct _CONNECTION_DATA_ *psConnection, - const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - IMG_UINT32 *puiNumHeapConfigsOut -); - -PVRSRV_ERROR -HeapCfgHeapCount(struct _CONNECTION_DATA_ *psConnection, - const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 *puiNumHeapsOut -); - -PVRSRV_ERROR -HeapCfgHeapConfigName(struct _CONNECTION_DATA_ *psConnection, - const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapConfigNameBufSz, - IMG_CHAR *pszHeapConfigNameOut -); - -PVRSRV_ERROR -HeapCfgHeapDetails(struct _CONNECTION_DATA_ *psConnection, - const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - IMG_UINT32 uiHeapConfigIndex, - IMG_UINT32 uiHeapIndex, - IMG_UINT32 uiHeapNameBufSz, - IMG_CHAR *pszHeapNameOut, - IMG_DEV_VIRTADDR *psDevVAddrBaseOut, - IMG_DEVMEM_SIZE_T *puiHeapLengthOut, - IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut, - IMG_UINT32 *puiLog2DataPageSizeOut, - IMG_UINT32 *puiLog2ImportAlignmentOut -); - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.c b/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.c deleted file mode 100644 index 3f49ee118d657..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.c +++ /dev/null @@ -1,1971 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Devicemem history functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Devicemem history functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "allocmem.h" -#include "img_defs.h" -#include "pmr.h" -#include "pvrsrv.h" -#include "pvrsrv_device.h" -#include "pvr_debug.h" -#include "devicemem_server.h" -#include "lock.h" -#include "devicemem_history_server.h" -#include "pdump_km.h" -#include "di_server.h" - -#define ALLOCATION_LIST_NUM_ENTRIES 10000 - -/* data type to hold an allocation index. - * we make it 16 bits wide if possible - */ -#if ALLOCATION_LIST_NUM_ENTRIES <= 0xFFFF -typedef uint16_t ALLOC_INDEX_T; -#else -typedef uint32_t ALLOC_INDEX_T; -#endif - -/* a record describing a single allocation known to DeviceMemHistory. - * this is an element in a doubly linked list of allocations - */ -typedef struct _RECORD_ALLOCATION_ -{ - /* time when this RECORD_ALLOCATION was created/initialised */ - IMG_UINT64 ui64CreationTime; - /* serial number of the PMR relating to this allocation */ - IMG_UINT64 ui64Serial; - /* base DevVAddr of this allocation */ - IMG_DEV_VIRTADDR sDevVAddr; - /* size in bytes of this allocation */ - IMG_DEVMEM_SIZE_T uiSize; - /* Log2 page size of this allocation's GPU pages */ - IMG_UINT32 ui32Log2PageSize; - /* Process ID (PID) this allocation belongs to */ - IMG_PID uiPID; - /* index of previous allocation in the list */ - ALLOC_INDEX_T ui32Prev; - /* index of next allocation in the list */ - ALLOC_INDEX_T ui32Next; - /* annotation/name of this allocation */ - IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN]; -} RECORD_ALLOCATION; - -/* each command in the circular buffer is prefixed with an 8-bit value - * denoting the command type - */ -typedef enum _COMMAND_TYPE_ -{ - COMMAND_TYPE_NONE, - COMMAND_TYPE_TIMESTAMP, - COMMAND_TYPE_MAP_ALL, - COMMAND_TYPE_UNMAP_ALL, - COMMAND_TYPE_MAP_RANGE, - COMMAND_TYPE_UNMAP_RANGE, - /* sentinel value */ - COMMAND_TYPE_COUNT, -} COMMAND_TYPE; - -/* Timestamp command: - * This command is inserted into the circular buffer to provide an updated - * timestamp. - * The nanosecond-accuracy timestamp is packed into a 56-bit integer, in order - * for the whole command to fit into 8 bytes. - */ -typedef struct _COMMAND_TIMESTAMP_ -{ - IMG_UINT8 aui8TimeNs[7]; -} COMMAND_TIMESTAMP; - -/* MAP_ALL command: - * This command denotes the allocation at the given index was wholly mapped - * in to the GPU MMU - */ -typedef struct _COMMAND_MAP_ALL_ -{ - ALLOC_INDEX_T uiAllocIndex; -} COMMAND_MAP_ALL; - -/* UNMAP_ALL command: - * This command denotes the allocation at the given index was wholly unmapped - * from the GPU MMU - * Note: COMMAND_MAP_ALL and COMMAND_UNMAP_ALL commands have the same layout. - */ -typedef COMMAND_MAP_ALL COMMAND_UNMAP_ALL; - -/* packing attributes for the MAP_RANGE command */ -#define MAP_RANGE_MAX_START ((1 << 18) - 1) -#define MAP_RANGE_MAX_RANGE ((1 << 12) - 1) - -/* MAP_RANGE command: - * Denotes a range of pages within the given allocation being mapped. - * The range is expressed as [Page Index] + [Page Count] - * This information is packed into a 40-bit integer, in order to make - * the command size 8 bytes. - */ - -typedef struct _COMMAND_MAP_RANGE_ -{ - IMG_UINT8 aui8Data[5]; - ALLOC_INDEX_T uiAllocIndex; -} COMMAND_MAP_RANGE; - -/* UNMAP_RANGE command: - * Denotes a range of pages within the given allocation being mapped. - * The range is expressed as [Page Index] + [Page Count] - * This information is packed into a 40-bit integer, in order to make - * the command size 8 bytes. - * Note: COMMAND_MAP_RANGE and COMMAND_UNMAP_RANGE commands have the same layout. - */ -typedef COMMAND_MAP_RANGE COMMAND_UNMAP_RANGE; - -/* wrapper structure for a command */ -typedef struct _COMMAND_WRAPPER_ -{ - IMG_UINT8 ui8Type; - union { - COMMAND_TIMESTAMP sTimeStamp; - COMMAND_MAP_ALL sMapAll; - COMMAND_UNMAP_ALL sUnmapAll; - COMMAND_MAP_RANGE sMapRange; - COMMAND_UNMAP_RANGE sUnmapRange; - } u; -} COMMAND_WRAPPER; - -/* target size for the circular buffer of commands */ -#define CIRCULAR_BUFFER_SIZE_KB 2048 -/* turn the circular buffer target size into a number of commands */ -#define CIRCULAR_BUFFER_NUM_COMMANDS ((CIRCULAR_BUFFER_SIZE_KB * 1024) / sizeof(COMMAND_WRAPPER)) - -/* index value denoting the end of a list */ -#define END_OF_LIST 0xFFFFFFFF -#define ALLOC_INDEX_TO_PTR(idx) (&(gsDevicememHistoryData.sRecords.pasAllocations[idx])) -#define CHECK_ALLOC_INDEX(idx) (idx < ALLOCATION_LIST_NUM_ENTRIES) - -/* wrapper structure for the allocation records and the commands circular buffer */ -typedef struct _RECORDS_ -{ - RECORD_ALLOCATION *pasAllocations; - IMG_UINT32 ui32AllocationsListHead; - - IMG_UINT32 ui32Head; - IMG_UINT32 ui32Tail; - COMMAND_WRAPPER *pasCircularBuffer; -} RECORDS; - -typedef struct _DEVICEMEM_HISTORY_DATA_ -{ - /* DI entry */ - DI_ENTRY *psDIEntry; - - RECORDS sRecords; - POS_LOCK hLock; -} DEVICEMEM_HISTORY_DATA; - -static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData; - -/* gsDevicememHistoryData is static, hLock is NULL unless - * EnablePageFaultDebug is set and DevicememHistoryInitKM() - * was called. - */ -static void DevicememHistoryLock(void) -{ - if (gsDevicememHistoryData.hLock) - { - OSLockAcquire(gsDevicememHistoryData.hLock); - } -} - -static void DevicememHistoryUnlock(void) -{ - if (gsDevicememHistoryData.hLock) - { - OSLockRelease(gsDevicememHistoryData.hLock); - } -} - -/* given a time stamp, calculate the age in nanoseconds */ -static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Now, - IMG_UINT64 ui64Then, - IMG_UINT64 ui64Max) -{ - if (ui64Now >= ui64Then) - { - /* no clock wrap */ - return ui64Now - ui64Then; - } - else - { - /* clock has wrapped */ - return (ui64Max - ui64Then) + ui64Now + 1; - } -} - -/* AcquireCBSlot: - * Acquire the next slot in the circular buffer and - * move the circular buffer head along by one - * Returns a pointer to the acquired slot. - */ -static COMMAND_WRAPPER *AcquireCBSlot(void) -{ - COMMAND_WRAPPER *psSlot; - - psSlot = &gsDevicememHistoryData.sRecords.pasCircularBuffer[gsDevicememHistoryData.sRecords.ui32Head]; - - gsDevicememHistoryData.sRecords.ui32Head = - (gsDevicememHistoryData.sRecords.ui32Head + 1) - % CIRCULAR_BUFFER_NUM_COMMANDS; - - return psSlot; -} - -/* TimeStampPack: - * Packs the given timestamp value into the COMMAND_TIMESTAMP structure. - * This takes a 64-bit nanosecond timestamp and packs it in to a 56-bit - * integer in the COMMAND_TIMESTAMP command. - */ -static void TimeStampPack(COMMAND_TIMESTAMP *psTimeStamp, IMG_UINT64 ui64Now) -{ - IMG_UINT32 i; - - for (i = 0; i < ARRAY_SIZE(psTimeStamp->aui8TimeNs); i++) - { - psTimeStamp->aui8TimeNs[i] = ui64Now & 0xFF; - ui64Now >>= 8; - } -} - -/* packing a 64-bit nanosecond into a 7-byte integer loses the - * top 8 bits of data. This must be taken into account when - * comparing a full timestamp against an unpacked timestamp - */ -#define TIME_STAMP_MASK ((1LLU << 56) - 1) -#define DO_TIME_STAMP_MASK(ns64) (ns64 & TIME_STAMP_MASK) - -/* TimeStampUnpack: - * Unpack the timestamp value from the given COMMAND_TIMESTAMP command - */ -static IMG_UINT64 TimeStampUnpack(COMMAND_TIMESTAMP *psTimeStamp) -{ - IMG_UINT64 ui64TimeNs = 0; - IMG_UINT32 i; - - for (i = ARRAY_SIZE(psTimeStamp->aui8TimeNs); i > 0; i--) - { - ui64TimeNs <<= 8; - ui64TimeNs |= (IMG_UINT64) psTimeStamp->aui8TimeNs[i - 1]; - } - - return ui64TimeNs; -} - -#if defined(PDUMP) - -static void EmitPDumpAllocation(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocationIndex, - RECORD_ALLOCATION *psAlloc) -{ - PDUMPCOMMENT(psDeviceNode, - "[SrvPFD] Allocation: %u" - " Addr: " IMG_DEV_VIRTADDR_FMTSPEC - " Size: " IMG_DEVMEM_SIZE_FMTSPEC - " Page size: %u" - " PID: %u" - " Process: %s" - " Name: %s", - ui32AllocationIndex, - psAlloc->sDevVAddr.uiAddr, - psAlloc->uiSize, - 1U << psAlloc->ui32Log2PageSize, - psAlloc->uiPID, - OSGetCurrentClientProcessNameKM(), - psAlloc->szName); -} - -static void EmitPDumpMapUnmapAll(PVRSRV_DEVICE_NODE *psDeviceNode, - COMMAND_TYPE eType, - IMG_UINT32 ui32AllocationIndex) -{ - const IMG_CHAR *pszOpName; - - switch (eType) - { - case COMMAND_TYPE_MAP_ALL: - pszOpName = "MAP_ALL"; - break; - case COMMAND_TYPE_UNMAP_ALL: - pszOpName = "UNMAP_ALL"; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapAll: Invalid type: %u", - eType)); - return; - - } - - PDUMPCOMMENT(psDeviceNode, - "[SrvPFD] Op: %s Allocation: %u", - pszOpName, - ui32AllocationIndex); -} - -static void EmitPDumpMapUnmapRange(PVRSRV_DEVICE_NODE *psDeviceNode, - COMMAND_TYPE eType, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32Count) -{ - const IMG_CHAR *pszOpName; - - switch (eType) - { - case COMMAND_TYPE_MAP_RANGE: - pszOpName = "MAP_RANGE"; - break; - case COMMAND_TYPE_UNMAP_RANGE: - pszOpName = "UNMAP_RANGE"; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapRange: Invalid type: %u", - eType)); - return; - } - - PDUMPCOMMENT(psDeviceNode, - "[SrvPFD] Op: %s Allocation: %u Start Page: %u Count: %u", - pszOpName, - ui32AllocationIndex, - ui32StartPage, - ui32Count); -} - -#endif - -/* InsertTimeStampCommand: - * Insert a timestamp command into the circular buffer. - */ -static void InsertTimeStampCommand(IMG_UINT64 ui64Now) -{ - COMMAND_WRAPPER *psCommand; - - psCommand = AcquireCBSlot(); - - psCommand->ui8Type = COMMAND_TYPE_TIMESTAMP; - - TimeStampPack(&psCommand->u.sTimeStamp, ui64Now); -} - -/* InsertMapAllCommand: - * Insert a "MAP_ALL" command for the given allocation into the circular buffer - */ -static void InsertMapAllCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocIndex) -{ - COMMAND_WRAPPER *psCommand; - - psCommand = AcquireCBSlot(); - - psCommand->ui8Type = COMMAND_TYPE_MAP_ALL; - psCommand->u.sMapAll.uiAllocIndex = ui32AllocIndex; - -#if defined(PDUMP) - EmitPDumpMapUnmapAll(psDeviceNode, COMMAND_TYPE_MAP_ALL, ui32AllocIndex); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif -} - -/* InsertUnmapAllCommand: - * Insert a "UNMAP_ALL" command for the given allocation into the circular buffer - */ -static void InsertUnmapAllCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocIndex) -{ - COMMAND_WRAPPER *psCommand; - - psCommand = AcquireCBSlot(); - - psCommand->ui8Type = COMMAND_TYPE_UNMAP_ALL; - psCommand->u.sUnmapAll.uiAllocIndex = ui32AllocIndex; - -#if defined(PDUMP) - EmitPDumpMapUnmapAll(psDeviceNode, COMMAND_TYPE_UNMAP_ALL, ui32AllocIndex); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif -} - -/* MapRangePack: - * Pack the given StartPage and Count values into the 40-bit representation - * in the MAP_RANGE command. - */ -static void MapRangePack(COMMAND_MAP_RANGE *psMapRange, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32Count) -{ - IMG_UINT64 ui64Data; - IMG_UINT32 i; - - /* we must encode the data into 40 bits: - * 18 bits for the start page index - * 12 bits for the range - */ - PVR_ASSERT(ui32StartPage <= MAP_RANGE_MAX_START); - PVR_ASSERT(ui32Count <= MAP_RANGE_MAX_RANGE); - - ui64Data = (((IMG_UINT64) ui32StartPage) << 12) | ui32Count; - - for (i = 0; i < ARRAY_SIZE(psMapRange->aui8Data); i++) - { - psMapRange->aui8Data[i] = ui64Data & 0xFF; - ui64Data >>= 8; - } -} - -/* MapRangePack: - * Unpack the StartPage and Count values from the 40-bit representation - * in the MAP_RANGE command. - */ -static void MapRangeUnpack(COMMAND_MAP_RANGE *psMapRange, - IMG_UINT32 *pui32StartPage, - IMG_UINT32 *pui32Count) -{ - IMG_UINT64 ui64Data = 0; - IMG_UINT32 i; - - for (i = ARRAY_SIZE(psMapRange->aui8Data); i > 0; i--) - { - ui64Data <<= 8; - ui64Data |= (IMG_UINT64) psMapRange->aui8Data[i - 1]; - } - - *pui32StartPage = (ui64Data >> 12); - *pui32Count = ui64Data & ((1 << 12) - 1); -} - -/* InsertMapRangeCommand: - * Insert a MAP_RANGE command into the circular buffer with the given - * StartPage and Count values. - */ -static void InsertMapRangeCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocIndex, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32Count) -{ - COMMAND_WRAPPER *psCommand; - - psCommand = AcquireCBSlot(); - - psCommand->ui8Type = COMMAND_TYPE_MAP_RANGE; - psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex; - - MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count); - -#if defined(PDUMP) - EmitPDumpMapUnmapRange(psDeviceNode, - COMMAND_TYPE_MAP_RANGE, - ui32AllocIndex, - ui32StartPage, - ui32Count); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif -} - -/* InsertUnmapRangeCommand: - * Insert a UNMAP_RANGE command into the circular buffer with the given - * StartPage and Count values. - */ -static void InsertUnmapRangeCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocIndex, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32Count) -{ - COMMAND_WRAPPER *psCommand; - - psCommand = AcquireCBSlot(); - - psCommand->ui8Type = COMMAND_TYPE_UNMAP_RANGE; - psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex; - - MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count); - -#if defined(PDUMP) - EmitPDumpMapUnmapRange(psDeviceNode, - COMMAND_TYPE_UNMAP_RANGE, - ui32AllocIndex, - ui32StartPage, - ui32Count); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif -} - -/* InsertAllocationToList: - * Helper function for the allocation list. - * Inserts the given allocation at the head of the list, whose current head is - * pointed to by pui32ListHead - */ -static void InsertAllocationToList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc) -{ - RECORD_ALLOCATION *psAlloc; - - psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc); - - if (*pui32ListHead == END_OF_LIST) - { - /* list is currently empty, so just replace it */ - *pui32ListHead = ui32Alloc; - psAlloc->ui32Next = psAlloc->ui32Prev = *pui32ListHead; - } - else - { - RECORD_ALLOCATION *psHeadAlloc; - RECORD_ALLOCATION *psTailAlloc; - - psHeadAlloc = ALLOC_INDEX_TO_PTR(*pui32ListHead); - psTailAlloc = ALLOC_INDEX_TO_PTR(psHeadAlloc->ui32Prev); - - /* make the new alloc point forwards to the previous head */ - psAlloc->ui32Next = *pui32ListHead; - /* make the new alloc point backwards to the previous tail */ - psAlloc->ui32Prev = psHeadAlloc->ui32Prev; - - /* the head is now our new alloc */ - *pui32ListHead = ui32Alloc; - - /* the old head now points back to the new head */ - psHeadAlloc->ui32Prev = *pui32ListHead; - - /* the tail now points forward to the new head */ - psTailAlloc->ui32Next = ui32Alloc; - } -} - -static void InsertAllocationToBusyList(IMG_UINT32 ui32Alloc) -{ - InsertAllocationToList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc); -} - -/* RemoveAllocationFromList: - * Helper function for the allocation list. - * Removes the given allocation from the list, whose head is - * pointed to by pui32ListHead - */ -static void RemoveAllocationFromList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc) -{ - RECORD_ALLOCATION *psAlloc; - - psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc); - - /* if this is the only element in the list then just make the list empty */ - if ((*pui32ListHead == ui32Alloc) && (psAlloc->ui32Next == ui32Alloc)) - { - *pui32ListHead = END_OF_LIST; - } - else - { - RECORD_ALLOCATION *psPrev, *psNext; - - psPrev = ALLOC_INDEX_TO_PTR(psAlloc->ui32Prev); - psNext = ALLOC_INDEX_TO_PTR(psAlloc->ui32Next); - - /* remove the allocation from the list */ - psPrev->ui32Next = psAlloc->ui32Next; - psNext->ui32Prev = psAlloc->ui32Prev; - - /* if this allocation is the head then update the head */ - if (*pui32ListHead == ui32Alloc) - { - *pui32ListHead = psAlloc->ui32Prev; - } - } -} - -static void RemoveAllocationFromBusyList(IMG_UINT32 ui32Alloc) -{ - RemoveAllocationFromList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc); -} - -/* TouchBusyAllocation: - * Move the given allocation to the head of the list - */ -static void TouchBusyAllocation(IMG_UINT32 ui32Alloc) -{ - RemoveAllocationFromBusyList(ui32Alloc); - InsertAllocationToBusyList(ui32Alloc); -} - -/* GetOldestBusyAllocation: - * Returns the index of the oldest allocation in the MRU list - */ -static IMG_UINT32 GetOldestBusyAllocation(void) -{ - IMG_UINT32 ui32Alloc; - RECORD_ALLOCATION *psAlloc; - - ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead; - - if (ui32Alloc == END_OF_LIST) - { - return END_OF_LIST; - } - - psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc); - - return psAlloc->ui32Prev; -} - -static IMG_UINT32 GetFreeAllocation(void) -{ - IMG_UINT32 ui32Alloc; - - ui32Alloc = GetOldestBusyAllocation(); - - return ui32Alloc; -} - - -/* InitialiseAllocation: - * Initialise the given allocation structure with the given properties - */ -static void InitialiseAllocation(RECORD_ALLOCATION *psAlloc, - const IMG_CHAR *pszName, - IMG_UINT64 ui64Serial, - IMG_PID uiPID, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32Log2PageSize) -{ - OSStringLCopy(psAlloc->szName, pszName, sizeof(psAlloc->szName)); - psAlloc->ui64Serial = ui64Serial; - psAlloc->uiPID = uiPID; - psAlloc->sDevVAddr = sDevVAddr; - psAlloc->uiSize = uiSize; - psAlloc->ui32Log2PageSize = ui32Log2PageSize; - psAlloc->ui64CreationTime = OSClockns64(); -} - -/* CreateAllocation: - * Creates a new allocation with the given properties then outputs the - * index of the allocation - */ -static PVRSRV_ERROR CreateAllocation(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszName, - IMG_UINT64 ui64Serial, - IMG_PID uiPID, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32Log2PageSize, - IMG_BOOL bAutoPurge, - IMG_UINT32 *puiAllocationIndex) -{ - IMG_UINT32 ui32Alloc; - RECORD_ALLOCATION __maybe_unused *psAlloc; - - ui32Alloc = GetFreeAllocation(); - - psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc); - - InitialiseAllocation(ALLOC_INDEX_TO_PTR(ui32Alloc), - pszName, - ui64Serial, - uiPID, - sDevVAddr, - uiSize, - ui32Log2PageSize); - - /* put the newly initialised allocation at the front of the MRU list */ - TouchBusyAllocation(ui32Alloc); - - *puiAllocationIndex = ui32Alloc; - -#if defined(PDUMP) - EmitPDumpAllocation(psDeviceNode, ui32Alloc, psAlloc); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif - - return PVRSRV_OK; -} - -/* MatchAllocation: - * Tests if the allocation at the given index matches the supplied properties. - * Returns IMG_TRUE if it is a match, otherwise IMG_FALSE. - */ -static IMG_BOOL MatchAllocation(IMG_UINT32 ui32AllocationIndex, - IMG_UINT64 ui64Serial, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszName, - IMG_UINT32 ui32Log2PageSize, - IMG_PID uiPID) -{ - RECORD_ALLOCATION *psAlloc; - - psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocationIndex); - - return (psAlloc->ui64Serial == ui64Serial) && - (psAlloc->sDevVAddr.uiAddr == sDevVAddr.uiAddr) && - (psAlloc->uiSize == uiSize) && - (psAlloc->ui32Log2PageSize == ui32Log2PageSize) && - (OSStringNCompare(psAlloc->szName, pszName, DEVMEM_ANNOTATION_MAX_LEN) == 0); -} - -/* FindOrCreateAllocation: - * Convenience function. - * Given a set of allocation properties (serial, DevVAddr, size, name, etc), - * this function will look for an existing record of this allocation and - * create the allocation if there is no existing record - */ -static PVRSRV_ERROR FindOrCreateAllocation(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AllocationIndexHint, - IMG_UINT64 ui64Serial, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char *pszName, - IMG_UINT32 ui32Log2PageSize, - IMG_PID uiPID, - IMG_BOOL bSparse, - IMG_UINT32 *pui32AllocationIndexOut, - IMG_BOOL *pbCreated) -{ - IMG_UINT32 ui32AllocationIndex; - PVRSRV_ERROR eError; - - if (ui32AllocationIndexHint != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) - { - IMG_BOOL bHaveAllocation; - - /* first, try to match against the index given by the client. - * if the caller provided a hint but the allocation record is no longer - * there, it must have been purged, so go ahead and create a new allocation - */ - bHaveAllocation = MatchAllocation(ui32AllocationIndexHint, - ui64Serial, - sDevVAddr, - uiSize, - pszName, - ui32Log2PageSize, - uiPID); - if (bHaveAllocation) - { - *pbCreated = IMG_FALSE; - *pui32AllocationIndexOut = ui32AllocationIndexHint; - return PVRSRV_OK; - } - } - - /* if there is no record of the allocation then we - * create it now - */ - eError = CreateAllocation(psDeviceNode, - pszName, - ui64Serial, - uiPID, - sDevVAddr, - uiSize, - ui32Log2PageSize, - IMG_TRUE, - &ui32AllocationIndex); - - if (eError == PVRSRV_OK) - { - *pui32AllocationIndexOut = ui32AllocationIndex; - *pbCreated = IMG_TRUE; - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to create record for allocation %s", - __func__, - pszName)); - } - - return eError; -} - -/* GenerateMapUnmapCommandsForSparsePMR: - * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the PMR's - * current mapping table - * - * PMR: The PMR whose mapping table to read. - * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to. - * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping - * - * This function goes through every page in the PMR's mapping table and looks for - * virtually contiguous ranges to record as being mapped or unmapped. - */ -static void GenerateMapUnmapCommandsForSparsePMR(PMR *psPMR, - IMG_UINT32 ui32AllocIndex, - IMG_BOOL bMap) -{ - PMR_MAPPING_TABLE *psMappingTable; - IMG_UINT32 ui32DonePages = 0; - IMG_UINT32 ui32NumPages; - IMG_UINT32 i; - IMG_BOOL bInARun = IMG_FALSE; - IMG_UINT32 ui32CurrentStart = 0; - IMG_UINT32 ui32RunCount = 0; - - psMappingTable = PMR_GetMappingTable(psPMR); - ui32NumPages = psMappingTable->ui32NumPhysChunks; - - if (ui32NumPages == 0) - { - /* nothing to do */ - return; - } - - for (i = 0; i < psMappingTable->ui32NumVirtChunks; i++) - { - if (psMappingTable->aui32Translation[i] != TRANSLATION_INVALID) - { - if (!bInARun) - { - bInARun = IMG_TRUE; - ui32CurrentStart = i; - ui32RunCount = 1; - } - else - { - ui32RunCount++; - } - } - - if (bInARun) - { - /* test if we need to end this current run and generate the command, - * either because the next page is not virtually contiguous - * to the current page, we have reached the maximum range, - * or this is the last page in the mapping table - */ - if ((psMappingTable->aui32Translation[i] == TRANSLATION_INVALID) || - (ui32RunCount == MAP_RANGE_MAX_RANGE) || - (i == (psMappingTable->ui32NumVirtChunks - 1))) - { - if (bMap) - { - InsertMapRangeCommand(PMR_DeviceNode(psPMR), - ui32AllocIndex, - ui32CurrentStart, - ui32RunCount); - } - else - { - InsertUnmapRangeCommand(PMR_DeviceNode(psPMR), - ui32AllocIndex, - ui32CurrentStart, - ui32RunCount); - } - - ui32DonePages += ui32RunCount; - - if (ui32DonePages == ui32NumPages) - { - break; - } - - bInARun = IMG_FALSE; - } - } - } - -} - -/* GenerateMapUnmapCommandsForChangeList: - * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the - * list of page change (page map or page unmap) indices given. - * - * ui32NumPages: Number of pages which have changed. - * pui32PageList: List of indices of the pages which have changed. - * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to. - * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping - * - * This function goes through every page in the list and looks for - * virtually contiguous ranges to record as being mapped or unmapped. - */ -static void GenerateMapUnmapCommandsForChangeList(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32NumPages, - IMG_UINT32 *pui32PageList, - IMG_UINT32 ui32AllocIndex, - IMG_BOOL bMap) -{ - IMG_UINT32 i; - IMG_BOOL bInARun = IMG_FALSE; - IMG_UINT32 ui32CurrentStart = 0; - IMG_UINT32 ui32RunCount = 0; - - for (i = 0; i < ui32NumPages; i++) - { - if (!bInARun) - { - bInARun = IMG_TRUE; - ui32CurrentStart = pui32PageList[i]; - } - - ui32RunCount++; - - /* we flush if: - * - the next page in the list is not one greater than the current page - * - this is the last page in the list - * - we have reached the maximum range size - */ - if ((i == (ui32NumPages - 1)) || - ((pui32PageList[i] + 1) != pui32PageList[i + 1]) || - (ui32RunCount == MAP_RANGE_MAX_RANGE)) - { - if (bMap) - { - InsertMapRangeCommand(psDeviceNode, - ui32AllocIndex, - ui32CurrentStart, - ui32RunCount); - } - else - { - InsertUnmapRangeCommand(psDeviceNode, - ui32AllocIndex, - ui32CurrentStart, - ui32RunCount); - } - - bInARun = IMG_FALSE; - ui32RunCount = 0; - } - } -} - -/* DevicememHistoryMapKM: - * Entry point for when an allocation is mapped into the MMU GPU - * - * psPMR: The PMR to which the allocation belongs. - * ui32Offset: The offset within the PMR at which the allocation begins. - * sDevVAddr: The DevVAddr at which the allocation begins. - * szName: Annotation/name for the allocation. - * ui32Log2PageSize: Page size of the allocation, expressed in log2 form. - * ui32AllocationIndex: Allocation index as provided by the client. - * We will use this as a short-cut to find the allocation - * in our records. - * pui32AllocationIndexOut: An updated allocation index for the client. - * This may be a new value if we just created the - * allocation record. - */ -PVRSRV_ERROR DevicememHistoryMapKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut) -{ - IMG_BOOL bSparse = PMR_IsSparse(psPMR); - IMG_UINT64 ui64Serial; - IMG_PID uiPID = OSGetCurrentClientProcessIDKM(); - PVRSRV_ERROR eError; - IMG_BOOL bCreated; - - if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) && - !CHECK_ALLOC_INDEX(ui32AllocationIndex)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u", - __func__, - ui32AllocationIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PMRGetUID(psPMR, &ui64Serial); - - DevicememHistoryLock(); - - eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR), - ui32AllocationIndex, - ui64Serial, - sDevVAddr, - uiSize, - szName, - ui32Log2PageSize, - uiPID, - bSparse, - &ui32AllocationIndex, - &bCreated); - - if ((eError == PVRSRV_OK) && !bCreated) - { - /* touch the allocation so it goes to the head of our MRU list */ - TouchBusyAllocation(ui32AllocationIndex); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)", - __func__, - szName, - PVRSRVGETERRORSTRING(eError))); - goto out_unlock; - } - - if (!bSparse) - { - InsertMapAllCommand(PMR_DeviceNode(psPMR), ui32AllocationIndex); - } - else - { - GenerateMapUnmapCommandsForSparsePMR(psPMR, - ui32AllocationIndex, - IMG_TRUE); - } - - InsertTimeStampCommand(OSClockns64()); - - *pui32AllocationIndexOut = ui32AllocationIndex; - -out_unlock: - DevicememHistoryUnlock(); - - return eError; -} - -static void VRangeInsertMapUnmapCommands(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bMap, - IMG_UINT32 ui32AllocationIndex, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32NumPages, - const IMG_CHAR *pszName) -{ - while (ui32NumPages > 0) - { - IMG_UINT32 ui32PagesToAdd; - - ui32PagesToAdd = MIN(ui32NumPages, MAP_RANGE_MAX_RANGE); - - if (ui32StartPage > MAP_RANGE_MAX_START) - { - PVR_DPF((PVR_DBG_WARNING, "Cannot record %s range beginning at page " - "%u on allocation %s", - bMap ? "map" : "unmap", - ui32StartPage, - pszName)); - return; - } - - if (bMap) - { - InsertMapRangeCommand(psDeviceNode, - ui32AllocationIndex, - ui32StartPage, - ui32PagesToAdd); - } - else - { - InsertUnmapRangeCommand(psDeviceNode, - ui32AllocationIndex, - ui32StartPage, - ui32PagesToAdd); - } - - ui32StartPage += ui32PagesToAdd; - ui32NumPages -= ui32PagesToAdd; - } -} - -PVRSRV_ERROR DevicememHistoryMapVRangeKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut) -{ - IMG_PID uiPID = OSGetCurrentClientProcessIDKM(); - PVRSRV_ERROR eError; - IMG_BOOL bCreated; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) && - !CHECK_ALLOC_INDEX(ui32AllocationIndex)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u", - __func__, - ui32AllocationIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - DevicememHistoryLock(); - - eError = FindOrCreateAllocation(psDeviceNode, - ui32AllocationIndex, - 0, - sBaseDevVAddr, - uiAllocSize, - szName, - ui32Log2PageSize, - uiPID, - IMG_FALSE, - &ui32AllocationIndex, - &bCreated); - - if ((eError == PVRSRV_OK) && !bCreated) - { - /* touch the allocation so it goes to the head of our MRU list */ - TouchBusyAllocation(ui32AllocationIndex); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)", - __func__, - szName, - PVRSRVGETERRORSTRING(eError))); - goto out_unlock; - } - - VRangeInsertMapUnmapCommands(psDeviceNode, - IMG_TRUE, - ui32AllocationIndex, - sBaseDevVAddr, - ui32StartPage, - ui32NumPages, - szName); - - *pui32AllocationIndexOut = ui32AllocationIndex; - -out_unlock: - DevicememHistoryUnlock(); - - return eError; - -} - -PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut) -{ - IMG_PID uiPID = OSGetCurrentClientProcessIDKM(); - PVRSRV_ERROR eError; - IMG_BOOL bCreated; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) && - !CHECK_ALLOC_INDEX(ui32AllocationIndex)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u", - __func__, - ui32AllocationIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - DevicememHistoryLock(); - - eError = FindOrCreateAllocation(psDeviceNode, - ui32AllocationIndex, - 0, - sBaseDevVAddr, - uiAllocSize, - szName, - ui32Log2PageSize, - uiPID, - IMG_FALSE, - &ui32AllocationIndex, - &bCreated); - - if ((eError == PVRSRV_OK) && !bCreated) - { - /* touch the allocation so it goes to the head of our MRU list */ - TouchBusyAllocation(ui32AllocationIndex); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)", - __func__, - szName, - PVRSRVGETERRORSTRING(eError))); - goto out_unlock; - } - - VRangeInsertMapUnmapCommands(psDeviceNode, - IMG_FALSE, - ui32AllocationIndex, - sBaseDevVAddr, - ui32StartPage, - ui32NumPages, - szName); - - *pui32AllocationIndexOut = ui32AllocationIndex; - -out_unlock: - DevicememHistoryUnlock(); - - return eError; -} - - - -/* DevicememHistoryUnmapKM: - * Entry point for when an allocation is unmapped from the MMU GPU - * - * psPMR: The PMR to which the allocation belongs. - * ui32Offset: The offset within the PMR at which the allocation begins. - * sDevVAddr: The DevVAddr at which the allocation begins. - * szName: Annotation/name for the allocation. - * ui32Log2PageSize: Page size of the allocation, expressed in log2 form. - * ui32AllocationIndex: Allocation index as provided by the client. - * We will use this as a short-cut to find the allocation - * in our records. - * pui32AllocationIndexOut: An updated allocation index for the client. - * This may be a new value if we just created the - * allocation record. - */ -PVRSRV_ERROR DevicememHistoryUnmapKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut) -{ - IMG_BOOL bSparse = PMR_IsSparse(psPMR); - IMG_UINT64 ui64Serial; - IMG_PID uiPID = OSGetCurrentClientProcessIDKM(); - PVRSRV_ERROR eError; - IMG_BOOL bCreated; - - if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) && - !CHECK_ALLOC_INDEX(ui32AllocationIndex)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u", - __func__, - ui32AllocationIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PMRGetUID(psPMR, &ui64Serial); - - DevicememHistoryLock(); - - eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR), - ui32AllocationIndex, - ui64Serial, - sDevVAddr, - uiSize, - szName, - ui32Log2PageSize, - uiPID, - bSparse, - &ui32AllocationIndex, - &bCreated); - - if ((eError == PVRSRV_OK) && !bCreated) - { - /* touch the allocation so it goes to the head of our MRU list */ - TouchBusyAllocation(ui32AllocationIndex); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)", - __func__, - szName, - PVRSRVGETERRORSTRING(eError))); - goto out_unlock; - } - - if (!bSparse) - { - InsertUnmapAllCommand(PMR_DeviceNode(psPMR), ui32AllocationIndex); - } - else - { - GenerateMapUnmapCommandsForSparsePMR(psPMR, - ui32AllocationIndex, - IMG_FALSE); - } - - InsertTimeStampCommand(OSClockns64()); - - *pui32AllocationIndexOut = ui32AllocationIndex; - -out_unlock: - DevicememHistoryUnlock(); - - return eError; -} - -/* DevicememHistorySparseChangeKM: - * Entry point for when a sparse allocation is changed, such that some of the - * pages within the sparse allocation are mapped or unmapped. - * - * psPMR: The PMR to which the allocation belongs. - * ui32Offset: The offset within the PMR at which the allocation begins. - * sDevVAddr: The DevVAddr at which the allocation begins. - * szName: Annotation/name for the allocation. - * ui32Log2PageSize: Page size of the allocation, expressed in log2 form. - * ui32AllocPageCount: Number of pages which have been mapped. - * paui32AllocPageIndices: Indices of pages which have been mapped. - * ui32FreePageCount: Number of pages which have been unmapped. - * paui32FreePageIndices: Indices of pages which have been unmapped. - * ui32AllocationIndex: Allocation index as provided by the client. - * We will use this as a short-cut to find the allocation - * in our records. - * pui32AllocationIndexOut: An updated allocation index for the client. - * This may be a new value if we just created the - * allocation record. - */ -PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *paui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *paui32FreePageIndices, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut) -{ - IMG_UINT64 ui64Serial; - IMG_PID uiPID = OSGetCurrentClientProcessIDKM(); - PVRSRV_ERROR eError; - IMG_BOOL bCreated; - - if (!PMRValidateSize((IMG_UINT64) ui32AllocPageCount << ui32Log2PageSize)) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "PMR size exceeds limit #Chunks: %u ChunkSz %"IMG_UINT64_FMTSPECX"", - ui32AllocPageCount, - (IMG_UINT64) 1ULL << ui32Log2PageSize); - return PVRSRV_ERROR_PMR_TOO_LARGE; - } - - if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) && - !CHECK_ALLOC_INDEX(ui32AllocationIndex)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u", - __func__, - ui32AllocationIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PMRGetUID(psPMR, &ui64Serial); - - DevicememHistoryLock(); - - eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR), - ui32AllocationIndex, - ui64Serial, - sDevVAddr, - uiSize, - szName, - ui32Log2PageSize, - uiPID, - IMG_TRUE /* bSparse */, - &ui32AllocationIndex, - &bCreated); - - if ((eError == PVRSRV_OK) && !bCreated) - { - /* touch the allocation so it goes to the head of our MRU list */ - TouchBusyAllocation(ui32AllocationIndex); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)", - __func__, - szName, - PVRSRVGETERRORSTRING(eError))); - goto out_unlock; - } - - GenerateMapUnmapCommandsForChangeList(PMR_DeviceNode(psPMR), - ui32AllocPageCount, - paui32AllocPageIndices, - ui32AllocationIndex, - IMG_TRUE); - - GenerateMapUnmapCommandsForChangeList(PMR_DeviceNode(psPMR), - ui32FreePageCount, - paui32FreePageIndices, - ui32AllocationIndex, - IMG_FALSE); - - InsertTimeStampCommand(OSClockns64()); - - *pui32AllocationIndexOut = ui32AllocationIndex; - -out_unlock: - DevicememHistoryUnlock(); - - return eError; - -} - -/* CircularBufferIterateStart: - * Initialise local state for iterating over the circular buffer - */ -static void CircularBufferIterateStart(IMG_UINT32 *pui32Head, IMG_UINT32 *pui32Iter) -{ - *pui32Head = gsDevicememHistoryData.sRecords.ui32Head; - - if (*pui32Head != 0) - { - *pui32Iter = *pui32Head - 1; - } - else - { - *pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1; - } -} - -/* CircularBufferIteratePrevious: - * Iterate to the previous item in the circular buffer. - * This is called repeatedly to iterate over the whole circular buffer. - */ -static COMMAND_WRAPPER *CircularBufferIteratePrevious(IMG_UINT32 ui32Head, - IMG_UINT32 *pui32Iter, - COMMAND_TYPE *peType, - IMG_BOOL *pbLast) -{ - IMG_UINT8 *pui8Header; - COMMAND_WRAPPER *psOut = NULL; - - psOut = gsDevicememHistoryData.sRecords.pasCircularBuffer + *pui32Iter; - - pui8Header = (void *) psOut; - - /* Check the command looks valid. - * this condition should never happen, but check for it anyway - * and try to handle it - */ - if (*pui8Header >= COMMAND_TYPE_COUNT) - { - /* invalid header detected. Circular buffer corrupted? */ - PVR_DPF((PVR_DBG_ERROR, "CircularBufferIteratePrevious: " - "Invalid header: %u", - *pui8Header)); - *pbLast = IMG_TRUE; - return NULL; - } - - *peType = *pui8Header; - - if (*pui32Iter != 0) - { - (*pui32Iter)--; - } - else - { - *pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1; - } - - - /* inform the caller this is the last command if either we have reached - * the head (where we started) or if we have reached an empty command, - * which means we have covered all populated entries - */ - if ((*pui32Iter == ui32Head) || (*peType == COMMAND_TYPE_NONE)) - { - /* this is the final iteration */ - *pbLast = IMG_TRUE; - } - - return psOut; -} - -/* MapUnmapCommandGetInfo: - * Helper function to get the address and mapping information from a MAP_ALL, UNMAP_ALL, - * MAP_RANGE or UNMAP_RANGE command - */ -static void MapUnmapCommandGetInfo(COMMAND_WRAPPER *psCommand, - COMMAND_TYPE eType, - IMG_DEV_VIRTADDR *psDevVAddrStart, - IMG_DEV_VIRTADDR *psDevVAddrEnd, - IMG_BOOL *pbMap, - IMG_UINT32 *pui32AllocIndex) -{ - if ((eType == COMMAND_TYPE_MAP_ALL) || ((eType == COMMAND_TYPE_UNMAP_ALL))) - { - COMMAND_MAP_ALL *psMapAll = &psCommand->u.sMapAll; - RECORD_ALLOCATION *psAlloc; - - *pbMap = (eType == COMMAND_TYPE_MAP_ALL); - *pui32AllocIndex = psMapAll->uiAllocIndex; - - psAlloc = ALLOC_INDEX_TO_PTR(psMapAll->uiAllocIndex); - - *psDevVAddrStart = psAlloc->sDevVAddr; - psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr + psAlloc->uiSize - 1; - } - else if ((eType == COMMAND_TYPE_MAP_RANGE) || ((eType == COMMAND_TYPE_UNMAP_RANGE))) - { - COMMAND_MAP_RANGE *psMapRange = &psCommand->u.sMapRange; - RECORD_ALLOCATION *psAlloc; - IMG_UINT32 ui32StartPage, ui32Count; - - *pbMap = (eType == COMMAND_TYPE_MAP_RANGE); - *pui32AllocIndex = psMapRange->uiAllocIndex; - - psAlloc = ALLOC_INDEX_TO_PTR(psMapRange->uiAllocIndex); - - MapRangeUnpack(psMapRange, &ui32StartPage, &ui32Count); - - psDevVAddrStart->uiAddr = psAlloc->sDevVAddr.uiAddr + - ((1ULL << psAlloc->ui32Log2PageSize) * ui32StartPage); - - psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr + - ((1ULL << psAlloc->ui32Log2PageSize) * ui32Count) - 1; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid command type: %u", - __func__, - eType)); - } -} - -/* DevicememHistoryQuery: - * Entry point for rgxdebug to look up addresses relating to a page fault - */ -IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, - DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut, - IMG_UINT32 ui32PageSizeBytes, - IMG_BOOL bMatchAnyAllocInPage) -{ - IMG_UINT32 ui32Head, ui32Iter; - COMMAND_TYPE eType = COMMAND_TYPE_NONE; - COMMAND_WRAPPER *psCommand = NULL; - IMG_BOOL bLast = IMG_FALSE; - IMG_UINT64 ui64StartTime = OSClockns64(); - IMG_UINT64 ui64TimeNs = 0; - - /* initialise the results count for the caller */ - psQueryOut->ui32NumResults = 0; - - DevicememHistoryLock(); - - /* if the search is constrained to a particular PID then we - * first search the list of allocations to see if this - * PID is known to us - */ - if (psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY) - { - IMG_UINT32 ui32Alloc; - ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead; - - while (ui32Alloc != END_OF_LIST) - { - RECORD_ALLOCATION *psAlloc; - - psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc); - - if (psAlloc->uiPID == psQueryIn->uiPID) - { - goto found_pid; - } - - if (ui32Alloc == gsDevicememHistoryData.sRecords.ui32AllocationsListHead) - { - /* gone through whole list */ - break; - } - } - - /* PID not found, so we do not have any suitable data for this - * page fault - */ - goto out_unlock; - } - -found_pid: - - CircularBufferIterateStart(&ui32Head, &ui32Iter); - - while (!bLast) - { - psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast); - - if (eType == COMMAND_TYPE_TIMESTAMP) - { - ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp); - continue; - } - - if ((eType == COMMAND_TYPE_MAP_ALL) || - (eType == COMMAND_TYPE_UNMAP_ALL) || - (eType == COMMAND_TYPE_MAP_RANGE) || - (eType == COMMAND_TYPE_UNMAP_RANGE)) - { - RECORD_ALLOCATION *psAlloc; - IMG_DEV_VIRTADDR sAllocStartAddrOrig, sAllocEndAddrOrig; - IMG_DEV_VIRTADDR sAllocStartAddr, sAllocEndAddr; - IMG_BOOL bMap; - IMG_UINT32 ui32AllocIndex; - - MapUnmapCommandGetInfo(psCommand, - eType, - &sAllocStartAddrOrig, - &sAllocEndAddrOrig, - &bMap, - &ui32AllocIndex); - - sAllocStartAddr = sAllocStartAddrOrig; - sAllocEndAddr = sAllocEndAddrOrig; - - psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex); - - /* skip this command if we need to search within - * a particular PID, and this allocation is not from - * that PID - */ - if ((psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY) && - (psAlloc->uiPID != psQueryIn->uiPID)) - { - continue; - } - - /* if the allocation was created after this event, then this - * event must be for an old/removed allocation, so skip it - */ - if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs) - { - continue; - } - - /* if the caller wants us to match any allocation in the - * same page as the allocation then tweak the real start/end - * addresses of the allocation here - */ - if (bMatchAnyAllocInPage) - { - sAllocStartAddr.uiAddr = sAllocStartAddr.uiAddr & ~(IMG_UINT64) (ui32PageSizeBytes - 1); - sAllocEndAddr.uiAddr = (sAllocEndAddr.uiAddr + ui32PageSizeBytes - 1) & ~(IMG_UINT64) (ui32PageSizeBytes - 1); - } - - if ((psQueryIn->sDevVAddr.uiAddr >= sAllocStartAddr.uiAddr) && - (psQueryIn->sDevVAddr.uiAddr < sAllocEndAddr.uiAddr)) - { - DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults]; - - OSStringLCopy(psResult->szString, psAlloc->szName, sizeof(psResult->szString)); - psResult->sBaseDevVAddr = psAlloc->sDevVAddr; - psResult->uiSize = psAlloc->uiSize; - psResult->bMap = bMap; - psResult->ui64Age = _CalculateAge(ui64StartTime, ui64TimeNs, TIME_STAMP_MASK); - psResult->ui64When = ui64TimeNs; - /* write the responsible PID in the placeholder */ - psResult->sProcessInfo.uiPID = psAlloc->uiPID; - - if ((eType == COMMAND_TYPE_MAP_ALL) || (eType == COMMAND_TYPE_UNMAP_ALL)) - { - psResult->bRange = IMG_FALSE; - psResult->bAll = IMG_TRUE; - } - else - { - psResult->bRange = IMG_TRUE; - MapRangeUnpack(&psCommand->u.sMapRange, - &psResult->ui32StartPage, - &psResult->ui32PageCount); - psResult->bAll = (psResult->ui32PageCount * (1U << psAlloc->ui32Log2PageSize)) - == psAlloc->uiSize; - psResult->sMapStartAddr = sAllocStartAddrOrig; - psResult->sMapEndAddr = sAllocEndAddrOrig; - } - - psQueryOut->ui32NumResults++; - - if (psQueryOut->ui32NumResults == DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS) - { - break; - } - } - } - } - -out_unlock: - DevicememHistoryUnlock(); - - return psQueryOut->ui32NumResults > 0; -} - -static void DeviceMemHistoryFmt(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN], - IMG_PID uiPID, - const IMG_CHAR *pszName, - const IMG_CHAR *pszAction, - IMG_DEV_VIRTADDR sDevVAddrStart, - IMG_DEV_VIRTADDR sDevVAddrEnd, - IMG_UINT64 ui64TimeNs) -{ - - OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, - /* PID NAME MAP/UNMAP MIN-MAX SIZE AbsUS AgeUS*/ - "%04u %-40s %-10s " - IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC " " - "0x%08" IMG_UINT64_FMTSPECX " " - "%013" IMG_UINT64_FMTSPEC, /* 13 digits is over 2 hours of ns */ - uiPID, - pszName, - pszAction, - sDevVAddrStart.uiAddr, - sDevVAddrEnd.uiAddr, - sDevVAddrEnd.uiAddr - sDevVAddrStart.uiAddr + 1, - ui64TimeNs); -} - -static void DeviceMemHistoryFmtHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]) -{ - OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, - "%-4s %-40s %-6s %10s %10s %8s %13s", - "PID", - "NAME", - "ACTION", - "ADDR MIN", - "ADDR MAX", - "SIZE", - "ABS NS"); -} - -static const char *CommandTypeToString(COMMAND_TYPE eType) -{ - switch (eType) - { - case COMMAND_TYPE_MAP_ALL: - return "MapAll"; - case COMMAND_TYPE_UNMAP_ALL: - return "UnmapAll"; - case COMMAND_TYPE_MAP_RANGE: - return "MapRange"; - case COMMAND_TYPE_UNMAP_RANGE: - return "UnmapRange"; - case COMMAND_TYPE_TIMESTAMP: - return "TimeStamp"; - default: - return "???"; - } -} - -static void DevicememHistoryPrintAll(OSDI_IMPL_ENTRY *psEntry) -{ - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; - IMG_UINT32 ui32Iter; - IMG_UINT32 ui32Head; - IMG_BOOL bLast = IMG_FALSE; - IMG_UINT64 ui64TimeNs = 0; - IMG_UINT64 ui64StartTime = OSClockns64(); - - DeviceMemHistoryFmtHeader(szBuffer); - DIPrintf(psEntry, "%s\n", szBuffer); - - CircularBufferIterateStart(&ui32Head, &ui32Iter); - - while (!bLast) - { - COMMAND_WRAPPER *psCommand; - COMMAND_TYPE eType = COMMAND_TYPE_NONE; - - psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, - &bLast); - - if (eType == COMMAND_TYPE_TIMESTAMP) - { - ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp); - continue; - } - - - if ((eType == COMMAND_TYPE_MAP_ALL) || - (eType == COMMAND_TYPE_UNMAP_ALL) || - (eType == COMMAND_TYPE_MAP_RANGE) || - (eType == COMMAND_TYPE_UNMAP_RANGE)) - { - RECORD_ALLOCATION *psAlloc; - IMG_DEV_VIRTADDR sDevVAddrStart, sDevVAddrEnd; - IMG_BOOL bMap; - IMG_UINT32 ui32AllocIndex; - - MapUnmapCommandGetInfo(psCommand, - eType, - &sDevVAddrStart, - &sDevVAddrEnd, - &bMap, - &ui32AllocIndex); - - psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex); - - if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs) - { - /* if this event relates to an allocation we - * are no longer tracking then do not print it - */ - continue; - } - - DeviceMemHistoryFmt(szBuffer, - psAlloc->uiPID, - psAlloc->szName, - CommandTypeToString(eType), - sDevVAddrStart, - sDevVAddrEnd, - ui64TimeNs); - - DIPrintf(psEntry, "%s\n", szBuffer); - } - } - - DIPrintf(psEntry, "\nTimestamp reference: %013" IMG_UINT64_FMTSPEC "\n", - ui64StartTime); -} - -static int DevicememHistoryPrintAllWrapper(OSDI_IMPL_ENTRY *psEntry, - void *pvData) -{ - PVR_UNREFERENCED_PARAMETER(pvData); - - DevicememHistoryLock(); - DevicememHistoryPrintAll(psEntry); - DevicememHistoryUnlock(); - - return 0; -} - -static PVRSRV_ERROR CreateRecords(void) -{ - gsDevicememHistoryData.sRecords.pasAllocations = - OSAllocZMem(sizeof(RECORD_ALLOCATION) * ALLOCATION_LIST_NUM_ENTRIES); - - PVR_RETURN_IF_NOMEM(gsDevicememHistoryData.sRecords.pasAllocations); - - /* Allocated and initialise the circular buffer with zeros so every - * command is initialised as a command of type COMMAND_TYPE_NONE. */ - gsDevicememHistoryData.sRecords.pasCircularBuffer = - OSAllocZMem(sizeof(COMMAND_WRAPPER) * CIRCULAR_BUFFER_NUM_COMMANDS); - - if (gsDevicememHistoryData.sRecords.pasCircularBuffer == NULL) - { - OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - return PVRSRV_OK; -} - -static void DestroyRecords(void) -{ - OSFreeMem(gsDevicememHistoryData.sRecords.pasCircularBuffer); - OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations); -} - -static void InitialiseRecords(void) -{ - IMG_UINT32 i; - - /* initialise the allocations list */ - - gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Prev = ALLOCATION_LIST_NUM_ENTRIES - 1; - gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Next = 1; - - for (i = 1; i < ALLOCATION_LIST_NUM_ENTRIES; i++) - { - gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Prev = i - 1; - gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Next = i + 1; - } - - gsDevicememHistoryData.sRecords.pasAllocations[ALLOCATION_LIST_NUM_ENTRIES - 1].ui32Next = 0; - - gsDevicememHistoryData.sRecords.ui32AllocationsListHead = 0; -} - -PVRSRV_ERROR DevicememHistoryInitKM(void) -{ - PVRSRV_ERROR eError; - DI_ITERATOR_CB sIterator = {.pfnShow = DevicememHistoryPrintAllWrapper}; - - eError = OSLockCreate(&gsDevicememHistoryData.hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", err_lock); - - eError = CreateRecords(); - PVR_LOG_GOTO_IF_ERROR(eError, "CreateRecords", err_allocations); - - InitialiseRecords(); - - eError = DICreateEntry("devicemem_history", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, - &gsDevicememHistoryData.psDIEntry); - PVR_LOG_GOTO_IF_ERROR(eError, "DICreateEntry", err_di_creation); - - return PVRSRV_OK; - -err_di_creation: - DestroyRecords(); -err_allocations: - OSLockDestroy(gsDevicememHistoryData.hLock); - gsDevicememHistoryData.hLock = NULL; -err_lock: - return eError; -} - -void DevicememHistoryDeInitKM(void) -{ - if (gsDevicememHistoryData.psDIEntry != NULL) - { - DIDestroyEntry(gsDevicememHistoryData.psDIEntry); - } - - DestroyRecords(); - - if (gsDevicememHistoryData.hLock != NULL) - { - OSLockDestroy(gsDevicememHistoryData.hLock); - gsDevicememHistoryData.hLock = NULL; - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.h deleted file mode 100644 index 8e7ca59a6905c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_history_server.h +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ /*! -@File devicemem_history_server.h -@Title Resource Information abstraction -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Devicemem History functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEM_HISTORY_SERVER_H -#define DEVICEMEM_HISTORY_SERVER_H - -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "rgxmem.h" -#include "devicemem_utils.h" -#include "connection_server.h" - -PVRSRV_ERROR DevicememHistoryInitKM(void); - -void DevicememHistoryDeInitKM(void); - -PVRSRV_ERROR DevicememHistoryMapKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut); - -PVRSRV_ERROR DevicememHistoryUnmapKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut); - -PVRSRV_ERROR DevicememHistoryMapVRangeKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *ui32AllocationIndexOut); - -PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR sBaseDevVAddr, - IMG_UINT32 ui32StartPage, - IMG_UINT32 ui32NumPages, - IMG_DEVMEM_SIZE_T uiAllocSize, - const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32AllocationIndex, - IMG_UINT32 *ui32AllocationIndexOut); - -PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR, - IMG_UINT32 ui32Offset, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - const char szName[DEVMEM_ANNOTATION_MAX_LEN], - IMG_UINT32 ui32PageSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *paui32AllocPageIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pauiFreePageIndices, - IMG_UINT32 AllocationIndex, - IMG_UINT32 *pui32AllocationIndexOut); - -/* used when the PID does not matter */ -#define DEVICEMEM_HISTORY_PID_ANY 0xFFFFFFFE - -typedef struct _DEVICEMEM_HISTORY_QUERY_IN_ -{ - IMG_PID uiPID; - IMG_DEV_VIRTADDR sDevVAddr; -} DEVICEMEM_HISTORY_QUERY_IN; - -/* Store up to 4 results for a lookup. In the case of the faulting page being - * re-mapped between the page fault occurring on HW and the page fault analysis - * being done, the second result entry will show the allocation being unmapped. - * A further 2 entries are added to cater for multiple buffers in the same page. - */ -#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 4 - -typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_RESULT_ -{ - IMG_CHAR szString[DEVMEM_ANNOTATION_MAX_LEN]; - IMG_DEV_VIRTADDR sBaseDevVAddr; - IMG_DEVMEM_SIZE_T uiSize; - IMG_BOOL bMap; - IMG_BOOL bRange; - IMG_BOOL bAll; - IMG_UINT64 ui64When; - IMG_UINT64 ui64Age; - /* info for sparse map/unmap operations (i.e. bRange=IMG_TRUE) */ - IMG_UINT32 ui32StartPage; - IMG_UINT32 ui32PageCount; - IMG_DEV_VIRTADDR sMapStartAddr; - IMG_DEV_VIRTADDR sMapEndAddr; - RGXMEM_PROCESS_INFO sProcessInfo; -} DEVICEMEM_HISTORY_QUERY_OUT_RESULT; - -typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_ -{ - IMG_UINT32 ui32NumResults; - /* result 0 is the newest */ - DEVICEMEM_HISTORY_QUERY_OUT_RESULT sResults[DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS]; -} DEVICEMEM_HISTORY_QUERY_OUT; - -IMG_BOOL -DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, - DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut, - IMG_UINT32 ui32PageSizeBytes, - IMG_BOOL bMatchAnyAllocInPage); - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.c b/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.c deleted file mode 100644 index 639f93a174559..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.c +++ /dev/null @@ -1,404 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Shared device memory management PDump functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements common (client & server) PDump functions for the - memory management code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ /**************************************************************************/ - -#if defined(PDUMP) - -#include "allocmem.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "pdump.h" -#include "devicemem.h" -#include "devicemem_utils.h" -#include "devicemem_pdump.h" -#include "client_pdump_bridge.h" -#include "client_pdumpmm_bridge.h" -#if defined(__linux__) && !defined(__KERNEL__) -#include -#endif - -IMG_INTERNAL void -DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(uiOffset + uiSize <= psMemDesc->psImport->uiSize); - - eError = BridgePMRPDumpLoadMem(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - uiSize, - uiPDumpFlags, - IMG_FALSE); - - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpLoadMem"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL void -DevmemPDumpLoadZeroMem(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(uiOffset + uiSize <= psMemDesc->psImport->uiSize); - - eError = BridgePMRPDumpLoadMem(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - uiSize, - uiPDumpFlags, - IMG_TRUE); - - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpLoadMem"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL void -DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = BridgePMRPDumpLoadMemValue32(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - ui32Value, - uiPDumpFlags); - - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpLoadMemValue32"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL void -DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = BridgePMRPDumpLoadMemValue64(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - ui64Value, - uiPDumpFlags); - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpLoadMemValue64"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T *puiMemOffset, - IMG_CHAR *pszName, - IMG_UINT32 ui32Size) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[100]; - IMG_CHAR aszSymbolicName[100]; - IMG_DEVMEM_OFFSET_T uiNextSymName; - - *puiMemOffset += psMemDesc->uiOffset; - - eError = BridgePMRPDumpSymbolicAddr(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - *puiMemOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - puiMemOffset, - &uiNextSymName); - - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpSymbolicAddr"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } - - OSSNPrintf(pszName, ui32Size, "%s:%s", &aszMemspaceName[0], &aszSymbolicName[0]); - return eError; -} - -IMG_INTERNAL void -DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset) -{ - PVRSRV_ERROR eError; - - eError = BridgePMRPDumpSaveToFile(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - uiSize, - OSStringLength(pszFilename) + 1, - pszFilename, - uiFileOffset); - - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpSaveToFile"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL void -DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PdumpFlags) -{ - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR sDevAddrStart; - - sDevAddrStart = psMemDesc->psImport->sDeviceImport.sDevVAddr; - sDevAddrStart.uiAddr += psMemDesc->uiOffset; - sDevAddrStart.uiAddr += uiOffset; - - eError = BridgeDevmemIntPDumpSaveToFileVirtual(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->sDeviceImport.psHeap->psCtx->hDevMemServerContext, - sDevAddrStart, - uiSize, - OSStringLength(pszFilename) + 1, - pszFilename, - ui32FileOffset, - ui32PdumpFlags); - - PVR_LOG_IF_ERROR(eError, "BridgeDevmemIntPDumpSaveToFileVirtual"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL void -DevmemPDumpDataDescriptor(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PdumpFlags) -{ - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR sDevAddrStart; - - sDevAddrStart = psMemDesc->psImport->sDeviceImport.sDevVAddr; - sDevAddrStart.uiAddr += psMemDesc->uiOffset; - sDevAddrStart.uiAddr += uiOffset; - - eError = BridgePDumpDataDescriptor(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->sDeviceImport.psHeap->psCtx->hDevMemServerContext, - OSStringLength(pszFilename) + 1, - pszFilename, - sDevAddrStart, - uiSize, - ui32HeaderType, - ui32ElementType, - ui32ElementCount, - ui32PdumpFlags); - - PVR_LOG_IF_ERROR(eError, "BridgePDumpDataDescriptor"); - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -IMG_INTERNAL PVRSRV_ERROR -DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_DEVMEM_SIZE_T uiNumBytes; - - uiNumBytes = 4; - - if (psMemDesc->uiOffset + uiOffset + uiNumBytes > psMemDesc->psImport->uiSize) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE, e0); - } - - eError = BridgePMRPDumpPol32(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - ui32Value, - ui32Mask, - eOperator, - ui32PDumpFlags); - PVR_GOTO_IF_ERROR(eError, e0); - - return PVRSRV_OK; - - /* - error exit paths follow - */ - -e0: - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError != PVRSRV_OK); - } - return eError; -} - -#if defined(__KERNEL__) -IMG_INTERNAL PVRSRV_ERROR -DevmemPDumpDevmemCheck32(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_DEVMEM_SIZE_T uiNumBytes; - - uiNumBytes = 4; - - if (psMemDesc->uiOffset + uiOffset + uiNumBytes >= psMemDesc->psImport->uiSize) - { - eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE; - goto e0; - } - - eError = BridgePMRPDumpCheck32(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiOffset, - ui32Value, - ui32Mask, - eOperator, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - goto e0; - } - - return PVRSRV_OK; - - /* - error exit paths follow - */ - -e0: - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError != PVRSRV_OK); - } - return eError; -} -#endif /* defined(__KERNEL__) */ - -IMG_INTERNAL PVRSRV_ERROR -DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVRSRV_ERROR eError; - - if ((psMemDesc->uiOffset + uiReadOffset) > psMemDesc->psImport->uiSize) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE, e0); - } - - eError = BridgePMRPDumpCBP(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - psMemDesc->uiOffset + uiReadOffset, - uiWriteOffset, - uiPacketSize, - uiBufferSize); - PVR_GOTO_IF_ERROR(eError, e0); - - return PVRSRV_OK; - -e0: - /* If PDump was rejected for this device, suppress silently */ - if (eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - PVR_ASSERT(eError != PVRSRV_OK); - } - return eError; -} - -#endif /* PDUMP */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.h deleted file mode 100644 index 09b28afe7e51a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_pdump.h +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management PDump internal -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services internal interface to PDump device memory management - functions that are shared between client and server code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEM_PDUMP_H -#define DEVICEMEM_PDUMP_H - -#include "devicemem.h" -#include "pdumpdefs.h" -#include "pdump.h" - -#if defined(PDUMP) -/* - * DevmemPDumpLoadMem() - * - * takes a memory descriptor, offset, and size, and takes the current contents - * of the memory at that location and writes it to the prm pdump file, and - * emits a pdump LDB to load the data from that file. The intention here is - * that the contents of the simulated buffer upon pdump playback will be made - * to be the same as they are when this command is run, enabling pdump of - * cases where the memory has been modified externally, i.e. by the host cpu - * or by a third party. - */ -void -DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * DevmemPDumpLoadZeroMem() - * - * As DevmemPDumpLoadMem() but the PDump allocation will be populated with - * zeros from the zero page in the parameter stream - */ -void -DevmemPDumpLoadZeroMem(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * DevmemPDumpLoadMemValue32() - * - * As above but dumps the value at a dword-aligned address in plain text to - * the pdump script2 file. Useful for patching a buffer at pdump playback by - * simply editing the script output file. - * - * (The same functionality can be achieved by the above function but the - * binary PARAM file must be patched in that case.) - */ -IMG_INTERNAL void -DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * DevmemPDumpMemValue64() - * - * As above but dumps the 64bit-value at a dword-aligned address in plain text - * to the pdump script2 file. Useful for patching a buffer at pdump playback by - * simply editing the script output file. - * - * (The same functionality can be achieved by the above function but the - * binary PARAM file must be patched in that case.) - */ -IMG_INTERNAL void -DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * DevmemPDumpPageCatBaseToSAddr() - * - * Returns the symbolic address of a piece of memory represented by an offset - * into the mem descriptor. - */ -PVRSRV_ERROR -DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T *puiMemOffset, - IMG_CHAR *pszName, - IMG_UINT32 ui32Size); - -/* - * DevmemPDumpSaveToFile() - * - * Emits a pdump SAB to cause the current contents of the memory to be written - * to the given file during playback - */ -void -DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset); - -/* - * DevmemPDumpSaveToFileVirtual() - * - * Emits a pdump SAB, just like DevmemPDumpSaveToFile(), but uses the virtual - * address and device MMU context to cause the pdump player to traverse the - * MMU page tables itself. - */ -void -DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PdumpFlags); - -/* - * DevmemPDumpDataDescriptor() - * - * Emits a pdump CMD:OutputData, using the virtual address and device MMU - * context. Provides more flexibility than a pdump SAB because metadata can - * be passed to an external pdump player library via the command header. - */ -void -DevmemPDumpDataDescriptor(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PdumpFlags); - - -/* - * - * DevmemPDumpDevmemPol32() - * - * Writes a PDump 'POL' command to wait for a masked 32-bit memory location to - * become the specified value. - */ -PVRSRV_ERROR -DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags); - -#if defined(__KERNEL__) -/* - * - * DevmemPDumpDevmemCheck32() - * - * Writes a PDump 'POL' command to run a single-shot check for a masked - * 32-bit memory location to match the specified value. - */ -PVRSRV_ERROR -DevmemPDumpDevmemCheck32(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags); -#endif - -/* - * DevmemPDumpCBP() - * - * Polls for space in circular buffer. Reads the read offset from memory and - * waits until there is enough space to write the packet. - * - * psMemDesc - MemDesc which contains the read offset - * uiReadOffset - Offset into MemDesc to the read offset - * uiWriteOffset - Current write offset - * uiPacketSize - Size of packet to write - * uiBufferSize - Size of circular buffer - */ -PVRSRV_ERROR -DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize); - -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpLoadMem) -#endif -static INLINE void -DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpLoadMemValue32) -#endif -static INLINE void -DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpLoadMemValue64) -#endif -static INLINE void -DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(ui64Value); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpPageCatBaseToSAddr) -#endif -static INLINE PVRSRV_ERROR -DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T *puiMemOffset, - IMG_CHAR *pszName, - IMG_UINT32 ui32Size) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(puiMemOffset); - PVR_UNREFERENCED_PARAMETER(pszName); - PVR_UNREFERENCED_PARAMETER(ui32Size); - - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpSaveToFile) -#endif -static INLINE void -DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(pszFilename); - PVR_UNREFERENCED_PARAMETER(uiFileOffset); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpSaveToFileVirtual) -#endif -static INLINE void -DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PdumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(pszFilename); - PVR_UNREFERENCED_PARAMETER(ui32FileOffset); - PVR_UNREFERENCED_PARAMETER(ui32PdumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpDevmemPol32) -#endif -static INLINE PVRSRV_ERROR -DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemPDumpCBP) -#endif -static INLINE PVRSRV_ERROR -DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVR_UNREFERENCED_PARAMETER(psMemDesc); - PVR_UNREFERENCED_PARAMETER(uiReadOffset); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); - - return PVRSRV_OK; -} -#endif /* PDUMP */ -#endif /* DEVICEMEM_PDUMP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_server.c b/drivers/gpu/drm/img-rogue/1.17/devicemem_server.c deleted file mode 100644 index 5f399e9f5aa40..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_server.c +++ /dev/null @@ -1,2727 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Server-side component of the Device Memory Management. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -/* our exported API */ -#include "devicemem_server.h" -#include "devicemem_utils.h" -#include "devicemem.h" - -#include "device.h" /* For device node */ -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -#include "mmu_common.h" -#include "pdump_km.h" -#include "pmr.h" -#include "physmem.h" -#include "pdumpdesc.h" - -#include "allocmem.h" -#include "osfunc.h" -#include "lock.h" - -#include "pvrsrv.h" /* for PVRSRVGetPVRSRVData() */ - -#define DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE (1 << 0) -#define DEVMEMHEAP_REFCOUNT_MIN 1 -#define DEVMEMHEAP_REFCOUNT_MAX IMG_INT32_MAX -#define DEVMEMRESERVATION_REFCOUNT_MIN 1 -#define DEVMEMRESERVATION_REFCOUNT_MAX IMG_INT32_MAX - -struct _DEVMEMINT_CTX_ -{ - PVRSRV_DEVICE_NODE *psDevNode; - - /* MMU common code needs to have a context. There's a one-to-one - correspondence between device memory context and MMU context, - but we have the abstraction here so that we don't need to care - what the MMU does with its context, and the MMU code need not - know about us at all. */ - MMU_CONTEXT *psMMUContext; - - ATOMIC_T hRefCount; - - /* This handle is for devices that require notification when a new - memory context is created and they need to store private data that - is associated with the context. */ - IMG_HANDLE hPrivData; - - /* Protects access to sProcessNotifyListHead */ - POSWR_LOCK hListLock; - - /* The following tracks UM applications that need to be notified of a - * page fault */ - DLLIST_NODE sProcessNotifyListHead; - /* The following is a node for the list of registered devmem contexts */ - DLLIST_NODE sPageFaultNotifyListElem; - - /* Device virtual address of a page fault on this context */ - IMG_DEV_VIRTADDR sFaultAddress; - - /* General purpose flags */ - IMG_UINT32 ui32Flags; -}; - -struct _DEVMEMINT_CTX_EXPORT_ -{ - DEVMEMINT_CTX *psDevmemCtx; - PMR *psPMR; - ATOMIC_T hRefCount; - DLLIST_NODE sNode; -}; - -struct _DEVMEMINT_HEAP_ -{ - struct _DEVMEMINT_CTX_ *psDevmemCtx; - IMG_UINT32 uiLog2PageSize; - IMG_DEV_VIRTADDR sBaseAddr; - IMG_DEV_VIRTADDR sLastAddr; - ATOMIC_T uiRefCount; -}; - -struct _DEVMEMINT_RESERVATION_ -{ - struct _DEVMEMINT_HEAP_ *psDevmemHeap; - IMG_DEV_VIRTADDR sBase; - IMG_DEVMEM_SIZE_T uiLength; - /* lock used to guard against potential race when freeing reservation */ - POS_LOCK hLock; - IMG_INT32 i32RefCount; -}; - -struct _DEVMEMINT_RESERVATION2_ -{ - struct _DEVMEMINT_HEAP_ *psDevmemHeap; - IMG_DEV_VIRTADDR sBase; - IMG_DEVMEM_SIZE_T uiLength; - /* lock used to guard against potential race when freeing reservation */ - POS_LOCK hLock; - IMG_INT32 i32RefCount; - PVRSRV_MEMALLOCFLAGS_T uiFlags; - - /* We keep a reference to the single PMR associated with this reservation - * once mapped. When creating the reservation this is null. Used in - * ChangeSparse to validate parameters. We could have a sparse PMR with - * no backing and have it mapped to a reservation. - */ - PMR *psMappedPMR; - - /* Array of bitfields of size `uiNumPages / MAP_MASK_SHIFT`. - * This array represents the mapping between a PMR (psMappedPMR) and - * the reservation. Each bit represents an index of a physical page - a value - * 1 means the page is mapped and vice versa. - */ - IMG_UINT8 *pui8Map; - #define MAP_MASK_SHIFT 3 -}; - -struct _DEVMEMINT_MAPPING_ -{ - struct _DEVMEMINT_RESERVATION_ *psReservation; - PMR *psPMR; - IMG_UINT32 uiNumPages; -}; - -/*! Object representing a virtual range reservation and mapping between - * the virtual range and a set of PMRs. - * - * The physical allocations may be mapped entirely or partially to the entire - * or partial virtual range. */ -struct _DEVMEMXINT_RESERVATION_ -{ - /*! Pointer to a device memory heap this reservation is made on. */ - struct _DEVMEMINT_HEAP_ *psDevmemHeap; - /*! Base device virtual address of this reservation. */ - IMG_DEV_VIRTADDR sBase; - /*! Size of this reservation (in bytes). */ - IMG_DEVMEM_SIZE_T uiLength; - /*! Lock for protecting concurrent operations on the mapping. */ - POS_LOCK hLock; - /*! Array of PMRs of size `uiNumPages`. This array represents how the - * physical memory is mapped to the virtual range. Each entry in the array - * represents to one device page which means that one PMR may be spread - * across many indices. */ - PMR **ppsPMR; -}; - -struct _DEVMEMINT_PF_NOTIFY_ -{ - IMG_UINT32 ui32PID; - DLLIST_NODE sProcessNotifyListElem; -}; - -/** Computes division using log2 of divisor. */ -#define LOG2_DIV(x, log2) ((x) >> (log2)) - -/** Computes modulo of a power of 2. */ -#define LOG2_MOD(x, log2) ((x) & ((1 << (log2)) - 1)) - -static INLINE IMG_UINT32 _DevmemReservationPageCount(DEVMEMINT_RESERVATION2 *psRsrv); - -/*************************************************************************/ /*! -@Function DevmemIntReservationIsIndexMapped -@Description Checks whether a particular index in the reservation has been - mapped to a page in psMappedPMR. - -@Return IMG_TRUE if mapped or IMG_FALSE if not. -*/ /**************************************************************************/ -static INLINE IMG_BOOL DevmemIntReservationIsIndexMapped(DEVMEMINT_RESERVATION2 *psReservation, - IMG_UINT32 ui32Index) -{ - IMG_UINT32 ui32MapIndex = LOG2_DIV(ui32Index, MAP_MASK_SHIFT); - - PVR_ASSERT(psReservation != NULL); - PVR_ASSERT(ui32Index < _DevmemReservationPageCount(psReservation)); - - return BIT_ISSET(psReservation->pui8Map[ui32MapIndex], LOG2_MOD(ui32Index, MAP_MASK_SHIFT)); -} - -/*************************************************************************/ /*! -@Function DevmemIntReservationSetMappingIndex -@Description Sets an index of the reservation map to indicate a mapped or - unmapped PMR page. - -@Note The reservations hLock must be acquired before calling this - function. - -@Return None -*/ /**************************************************************************/ -static void DevmemIntReservationSetMappingIndex(DEVMEMINT_RESERVATION2 *psReservation, - IMG_UINT32 ui32Index, - IMG_BOOL bMap) -{ - IMG_UINT32 ui32MapIndex = LOG2_DIV(ui32Index, MAP_MASK_SHIFT); - - PVR_ASSERT(psReservation != NULL); - PVR_ASSERT(ui32Index < _DevmemReservationPageCount(psReservation)); - - if (bMap) - { - BIT_SET(psReservation->pui8Map[ui32MapIndex], LOG2_MOD(ui32Index, MAP_MASK_SHIFT)); - } - else - { - BIT_UNSET(psReservation->pui8Map[ui32MapIndex], LOG2_MOD(ui32Index, MAP_MASK_SHIFT)); - } -} - -/*************************************************************************/ /*! -@Function DevmemIntCtxAcquire -@Description Acquire a reference to the provided device memory context. -@Return None -*/ /**************************************************************************/ -static INLINE void DevmemIntCtxAcquire(DEVMEMINT_CTX *psDevmemCtx) -{ - OSAtomicIncrement(&psDevmemCtx->hRefCount); -} - -/*************************************************************************/ /*! -@Function DevmemIntCtxRelease -@Description Release the reference to the provided device memory context. - If this is the last reference which was taken then the - memory context will be freed. -@Return None -*/ /**************************************************************************/ -static INLINE void DevmemIntCtxRelease(DEVMEMINT_CTX *psDevmemCtx) -{ - if (OSAtomicDecrement(&psDevmemCtx->hRefCount) == 0) - { - /* The last reference has gone, destroy the context */ - PVRSRV_DEVICE_NODE *psDevNode = psDevmemCtx->psDevNode; - DLLIST_NODE *psNode, *psNodeNext; - - /* If there are any PIDs registered for page fault notification. - * Loop through the registered PIDs and free each one */ - dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext) - { - DEVMEMINT_PF_NOTIFY *psNotifyNode = - IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem); - dllist_remove_node(psNode); - OSFreeMem(psNotifyNode); - } - - /* If this context is in the list registered for a debugger, remove - * from that list */ - if (dllist_node_is_in_list(&psDevmemCtx->sPageFaultNotifyListElem)) - { - dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem); - } - - if (psDevNode->pfnUnregisterMemoryContext) - { - psDevNode->pfnUnregisterMemoryContext(psDevmemCtx->hPrivData); - } - MMU_ContextDestroy(psDevmemCtx->psMMUContext); - - OSWRLockDestroy(psDevmemCtx->hListLock); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed memory context %p", - __func__, psDevmemCtx)); - OSFreeMem(psDevmemCtx); - } -} - -/*************************************************************************/ /*! -@Function DevmemIntHeapAcquire -@Description Acquire a reference to the provided device memory heap. -@Return IMG_TRUE if referenced and IMG_FALSE in case of error -*/ /**************************************************************************/ -static INLINE IMG_BOOL DevmemIntHeapAcquire(DEVMEMINT_HEAP *psDevmemHeap) -{ - IMG_BOOL bSuccess = OSAtomicAddUnless(&psDevmemHeap->uiRefCount, 1, - DEVMEMHEAP_REFCOUNT_MAX); - - if (!bSuccess) - { - PVR_DPF((PVR_DBG_ERROR, "%s(): Failed to acquire the device memory " - "heap, reference count has overflowed.", __func__)); - return IMG_FALSE; - } - - return IMG_TRUE; -} - -/*************************************************************************/ /*! -@Function DevmemIntHeapRelease -@Description Release the reference to the provided device memory heap. - If this is the last reference which was taken then the - memory context will be freed. -@Return None -*/ /**************************************************************************/ -static INLINE void DevmemIntHeapRelease(DEVMEMINT_HEAP *psDevmemHeap) -{ - IMG_BOOL bSuccess = OSAtomicSubtractUnless(&psDevmemHeap->uiRefCount, 1, - DEVMEMHEAP_REFCOUNT_MIN); - - if (!bSuccess) - { - PVR_DPF((PVR_DBG_ERROR, "%s(): Failed to acquire the device memory " - "heap, reference count has underflowed.", __func__)); - } -} - -PVRSRV_ERROR -DevmemIntUnpin(PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntUnpinInvalidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemMapping); - PVR_UNREFERENCED_PARAMETER(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} -PVRSRV_ERROR -DevmemIntPin(PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntPinValidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemMapping); - PVR_UNREFERENCED_PARAMETER(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -static IMG_BOOL DevmemIntReservationAcquireUnlocked(DEVMEMINT_RESERVATION2 *psDevmemReservation) -{ -#if defined(DEBUG) - if (!OSLockIsLocked(psDevmemReservation->hLock)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Reservation is not locked", __func__)); - return IMG_FALSE; - } -#endif - - if (psDevmemReservation->i32RefCount == DEVMEMRESERVATION_REFCOUNT_MAX) - { - PVR_DPF((PVR_DBG_ERROR, "%s(): Failed to acquire the device memory " - "reservation, reference count has overflowed.", __func__)); - - return IMG_FALSE; - } - - psDevmemReservation->i32RefCount++; - - return IMG_TRUE; -} - -static void DevmemIntReservationReleaseUnlocked(DEVMEMINT_RESERVATION2 *psDevmemReservation) -{ -#if defined(DEBUG) - if (!OSLockIsLocked(psDevmemReservation->hLock)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Reservation is not locked", __func__)); - return; - } -#endif - - if (psDevmemReservation->i32RefCount == DEVMEMRESERVATION_REFCOUNT_MIN) - { - PVR_DPF((PVR_DBG_ERROR, "%s(): Failed to release the device memory " - "reservation, reference count has underflowed.", __func__)); - - /* for better debugging */ - PVR_ASSERT(psDevmemReservation->i32RefCount == DEVMEMRESERVATION_REFCOUNT_MIN); - - return; - } - - psDevmemReservation->i32RefCount--; -} - -/*************************************************************************/ /*! -@Function DevmemIntReservationAcquire -@Description Acquire a reference to the provided device memory reservation. -@Return IMG_TRUE if referenced and IMG_FALSE in case of error -*/ /**************************************************************************/ -IMG_BOOL DevmemIntReservationAcquire(DEVMEMINT_RESERVATION2 *psDevmemReservation) -{ - IMG_BOOL bSuccess; - - OSLockAcquire(psDevmemReservation->hLock); - bSuccess = DevmemIntReservationAcquireUnlocked(psDevmemReservation); - OSLockRelease(psDevmemReservation->hLock); - - return bSuccess; -} - -/*************************************************************************/ /*! -@Function DevmemIntReservationRelease -@Description Release the reference to the provided device memory reservation. - If this is the last reference which was taken then the - reservation will be freed. -@Return None. -*/ /**************************************************************************/ -void DevmemIntReservationRelease(DEVMEMINT_RESERVATION2 *psDevmemReservation) -{ - OSLockAcquire(psDevmemReservation->hLock); - DevmemIntReservationReleaseUnlocked(psDevmemReservation); - OSLockRelease(psDevmemReservation->hLock); -} - -/*************************************************************************/ /*! -@Function DevmemServerGetImportHandle -@Description For given exportable memory descriptor returns PMR handle. -@Return Memory is exportable - Success - PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *phImport) -{ - PVRSRV_ERROR eError; - - if ((GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION, e0); - } - - /* A new handle means a new import tracking the PMR. - * Hence the source PMR memory layout should be marked fixed - * to make sure the importer view of the memory is the same as - * the exporter throughout its lifetime */ - PMR_SetLayoutFixed((PMR *)psMemDesc->psImport->hPMR, IMG_TRUE); - - *phImport = psMemDesc->psImport->hPMR; - return PVRSRV_OK; - -e0: - return eError; -} - -/*************************************************************************/ /*! -@Function DevmemServerGetHeapHandle -@Description For given reservation returns the Heap handle. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION2 *psReservation, - IMG_HANDLE *phHeap) -{ - if (psReservation == NULL || phHeap == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *phHeap = psReservation->psDevmemHeap; - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function DevmemServerGetContext -@Description For given heap returns the context. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemServerGetContext(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_CTX **ppsDevmemCtxPtr) -{ - if (psDevmemHeap == NULL || ppsDevmemCtxPtr == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *ppsDevmemCtxPtr = psDevmemHeap->psDevmemCtx; - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function DevmemServerGetPrivData -@Description For given context returns the private data handle. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemServerGetPrivData(DEVMEMINT_CTX *psDevmemCtx, - IMG_HANDLE *phPrivData) -{ - if (psDevmemCtx == NULL || phPrivData == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *phPrivData = psDevmemCtx->hPrivData; - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function DevmemIntCtxCreate -@Description Creates and initialises a device memory context. -@Return valid Device Memory context handle - Success - PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntCtxCreate(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bKernelMemoryCtx, - DEVMEMINT_CTX **ppsDevmemCtxPtr, - IMG_HANDLE *hPrivData, - IMG_UINT32 *pui32CPUCacheLineSize) -{ - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtx; - IMG_HANDLE hPrivDataInt = NULL; - MMU_DEVICEATTRIBS *psMMUDevAttrs = psDeviceNode->pfnGetMMUDeviceAttributes(psDeviceNode, - bKernelMemoryCtx); - - PVR_DPF((PVR_DBG_MESSAGE, "%s", __func__)); - - /* Only allow request for a kernel context that comes from a direct bridge - * (psConnection == NULL). Only the FW/KM Ctx is created over the direct bridge. */ - PVR_LOG_RETURN_IF_INVALID_PARAM(!bKernelMemoryCtx || psConnection == NULL, - "bKernelMemoryCtx && psConnection"); - - /* - * Ensure that we are safe to perform unaligned accesses on memory - * we mark write-combine, as the compiler might generate - * instructions operating on this memory which require this - * assumption to be true. - */ - PVR_ASSERT(OSIsWriteCombineUnalignedSafe()); - - /* allocate a Devmem context */ - psDevmemCtx = OSAllocMem(sizeof(*psDevmemCtx)); - PVR_LOG_GOTO_IF_NOMEM(psDevmemCtx, eError, fail_alloc); - - OSAtomicWrite(&psDevmemCtx->hRefCount, 1); - psDevmemCtx->psDevNode = psDeviceNode; - - /* Call down to MMU context creation */ - - eError = MMU_ContextCreate(psConnection, - psDeviceNode, - &psDevmemCtx->psMMUContext, - psMMUDevAttrs); - PVR_LOG_GOTO_IF_ERROR(eError, "MMU_ContextCreate", fail_mmucontext); - - if (psDeviceNode->pfnRegisterMemoryContext) - { - eError = psDeviceNode->pfnRegisterMemoryContext(psDeviceNode, psDevmemCtx->psMMUContext, &hPrivDataInt); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnRegisterMemoryContext", fail_register); - } - - /* Store the private data as it is required to unregister the memory context */ - psDevmemCtx->hPrivData = hPrivDataInt; - *hPrivData = hPrivDataInt; - *ppsDevmemCtxPtr = psDevmemCtx; - - /* Pass the CPU cache line size through the bridge to the user mode as it can't be queried in user mode.*/ - *pui32CPUCacheLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE); - - /* Initialise the PID notify list */ - OSWRLockCreate(&psDevmemCtx->hListLock); - dllist_init(&(psDevmemCtx->sProcessNotifyListHead)); - psDevmemCtx->sPageFaultNotifyListElem.psNextNode = NULL; - psDevmemCtx->sPageFaultNotifyListElem.psPrevNode = NULL; - - /* Initialise page fault address */ - psDevmemCtx->sFaultAddress.uiAddr = 0ULL; - - /* Initialise flags */ - psDevmemCtx->ui32Flags = 0; - - return PVRSRV_OK; - -fail_register: - MMU_ContextDestroy(psDevmemCtx->psMMUContext); -fail_mmucontext: - OSFreeMem(psDevmemCtx); -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/*************************************************************************/ /*! -@Function DevmemIntHeapCreate -@Description Creates and initialises a device memory heap. -@Return valid Device Memory heap handle - Success - PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntHeapCreate(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sHeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_UINT32 uiLog2DataPageSize, - DEVMEMINT_HEAP **ppsDevmemHeapPtr) -{ - DEVMEMINT_HEAP *psDevmemHeap; - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR sBlueprintHeapBaseAddr; - IMG_DEVMEM_SIZE_T uiBlueprintHeapLength; - IMG_DEVMEM_SIZE_T uiBlueprintResRgnLength; - IMG_UINT32 ui32BlueprintLog2DataPageSize; - IMG_UINT32 ui32BlueprintLog2ImportAlignment; - IMG_UINT32 ui32NumHeapConfigsOut; - IMG_UINT32 ui32NumHeapsOut; - IMG_BOOL bHeapParamsValidated = IMG_FALSE; - - IMG_INT uiHeapConfigIndex, uiHeapIndex; - - PVR_DPF((PVR_DBG_MESSAGE, "%s", __func__)); - - /* allocate a Devmem context */ - psDevmemHeap = OSAllocMem(sizeof(*psDevmemHeap)); - PVR_LOG_RETURN_IF_NOMEM(psDevmemHeap, "psDevmemHeap"); - - psDevmemHeap->psDevmemCtx = psDevmemCtx; - - DevmemIntCtxAcquire(psDevmemHeap->psDevmemCtx); - - OSAtomicWrite(&psDevmemHeap->uiRefCount, 1); - - /* getting number of heaps and heap configs */ - eError = HeapCfgHeapConfigCount(NULL, psDevmemHeap->psDevmemCtx->psDevNode, &ui32NumHeapConfigsOut); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Cannot retrieve the number of heap configs.\n", __func__)); - eError = PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO; - goto ErrorCtxRelease; - } - - for(uiHeapConfigIndex = 0; uiHeapConfigIndex < ui32NumHeapConfigsOut; uiHeapConfigIndex++) - { - eError = HeapCfgHeapCount(NULL, psDevmemHeap->psDevmemCtx->psDevNode, uiHeapConfigIndex, &ui32NumHeapsOut); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to retrieve the number of heaps for heap config index %d.\n", - __func__, uiHeapConfigIndex)); - eError = PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO; - goto ErrorCtxRelease; - } - else - { - for(uiHeapIndex = 0; uiHeapIndex < ui32NumHeapsOut; uiHeapIndex++) - { - /* Check page size and base addr match the heap blueprint */ - eError = HeapCfgHeapDetails(NULL, - psDevmemHeap->psDevmemCtx->psDevNode, - uiHeapConfigIndex, - uiHeapIndex, - 0, NULL, - &sBlueprintHeapBaseAddr, - &uiBlueprintHeapLength, - &uiBlueprintResRgnLength, - &ui32BlueprintLog2DataPageSize, - &ui32BlueprintLog2ImportAlignment); - if (eError == PVRSRV_OK) - { - if ((ui32BlueprintLog2DataPageSize == uiLog2DataPageSize) && - (sHeapBaseAddr.uiAddr == sBlueprintHeapBaseAddr.uiAddr) && - (uiBlueprintHeapLength == uiHeapLength)) - { - bHeapParamsValidated = IMG_TRUE; - break; - } - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: HeapCfgHeapDetails call fail with Heap Config Index: %d, and Heap Index: %d.\n" - ,__func__, uiHeapConfigIndex, uiHeapIndex)); - eError = PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO; - goto ErrorCtxRelease; - } - } - } - - if (bHeapParamsValidated == IMG_TRUE) - { - break; - } - } - - if (bHeapParamsValidated != IMG_TRUE) - { - PVR_DPF((PVR_DBG_ERROR, "%s:The passed parameters do not match with any heap blueprint.\n", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto ErrorCtxRelease; - } - - psDevmemHeap->uiLog2PageSize = uiLog2DataPageSize; - psDevmemHeap->sBaseAddr = sHeapBaseAddr; - /* Store the last accessible address as our LastAddr. We can access - * every address between sHeapBaseAddr and sHeapBaseAddr + HeapLength - 1 - */ - psDevmemHeap->sLastAddr.uiAddr = sHeapBaseAddr.uiAddr + uiBlueprintHeapLength - 1; - - *ppsDevmemHeapPtr = psDevmemHeap; - - return PVRSRV_OK; - -ErrorCtxRelease: - DevmemIntCtxRelease(psDevmemHeap->psDevmemCtx); - OSFreeMem(psDevmemHeap); - - return eError; -} - -PVRSRV_ERROR DevmemIntAllocDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_DEF_PAGE *psDefPage, - IMG_INT uiInitValue, - IMG_CHAR *pcDefPageName, - IMG_BOOL bInitPage) -{ - IMG_UINT32 ui32RefCnt; - PVRSRV_ERROR eError = PVRSRV_OK; - - OSLockAcquire(psDefPage->psPgLock); - - /* We know there will not be 4G number of sparse PMR's */ - ui32RefCnt = OSAtomicIncrement(&psDefPage->atRefCounter); - - if (1 == ui32RefCnt) - { - IMG_DEV_PHYADDR sDevPhysAddr = {0}; - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, "Alloc %s page object", pcDefPageName); -#endif - - /* Allocate the dummy page required for sparse backing */ - eError = DevPhysMemAlloc(psDevNode, - (1 << psDefPage->ui32Log2PgSize), - 0, - uiInitValue, - bInitPage, -#if defined(PDUMP) - psDevNode->psMMUDevAttrs->pszMMUPxPDumpMemSpaceName, - pcDefPageName, - &psDefPage->hPdumpPg, -#endif - &psDefPage->sPageHandle, - &sDevPhysAddr); - if (PVRSRV_OK != eError) - { - OSAtomicDecrement(&psDefPage->atRefCounter); - } - else - { - psDefPage->ui64PgPhysAddr = sDevPhysAddr.uiAddr; - } - } - - OSLockRelease(psDefPage->psPgLock); - - return eError; -} - -void DevmemIntFreeDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_DEF_PAGE *psDefPage, - IMG_CHAR *pcDefPageName) -{ - IMG_UINT32 ui32RefCnt; - - ui32RefCnt = OSAtomicRead(&psDefPage->atRefCounter); - - /* For the cases where the dummy page allocation fails due to lack of memory - * The refcount can still be 0 even for a sparse allocation */ - if (0 != ui32RefCnt) - { - OSLockAcquire(psDefPage->psPgLock); - - /* We know there will not be 4G number of sparse PMR's */ - ui32RefCnt = OSAtomicDecrement(&psDefPage->atRefCounter); - - if (0 == ui32RefCnt) - { - PDUMPCOMMENT(psDevNode, "Free %s page object", pcDefPageName); - - /* Free the dummy page when refcount reaches zero */ - DevPhysMemFree(psDevNode, -#if defined(PDUMP) - psDefPage->hPdumpPg, -#endif - &psDefPage->sPageHandle); - -#if defined(PDUMP) - psDefPage->hPdumpPg = NULL; -#endif - psDefPage->ui64PgPhysAddr = MMU_BAD_PHYS_ADDR; - } - - OSLockRelease(psDefPage->psPgLock); - } - -} - -PVRSRV_ERROR -DevmemIntMapPages(DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysicalPgOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddrBase) -{ - PVR_UNREFERENCED_PARAMETER(psReservation); - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(ui32PageCount); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalPgOffset); - PVR_UNREFERENCED_PARAMETER(uiFlags); - PVR_UNREFERENCED_PARAMETER(sDevVAddrBase); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntUnmapPages(DEVMEMINT_RESERVATION *psReservation, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT32 ui32PageCount) -{ - PVR_UNREFERENCED_PARAMETER(psReservation); - PVR_UNREFERENCED_PARAMETER(sDevVAddrBase); - PVR_UNREFERENCED_PARAMETER(ui32PageCount); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -static INLINE IMG_UINT32 -_DevmemXReservationPageCount(DEVMEMXINT_RESERVATION *psRsrv) -{ - return psRsrv->uiLength >> psRsrv->psDevmemHeap->uiLog2PageSize; -} - -static INLINE IMG_DEV_VIRTADDR -_DevmemXReservationPageAddress(DEVMEMXINT_RESERVATION *psRsrv, IMG_UINT32 uiVirtPageOffset) -{ - IMG_DEV_VIRTADDR sAddr = { - .uiAddr = psRsrv->sBase.uiAddr + (uiVirtPageOffset << psRsrv->psDevmemHeap->uiLog2PageSize) - }; - - return sAddr; -} - -static INLINE PVRSRV_ERROR ReserveRangeParamValidation(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize) -{ - IMG_DEV_VIRTADDR sLastReserveAddr; - IMG_UINT64 ui64InvalidSizeMask = (1 << psDevmemHeap->uiLog2PageSize) - 1; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevmemHeap != NULL, "psDevmemHeap"); - - sLastReserveAddr.uiAddr = sAllocationDevVAddr.uiAddr + uiAllocationSize - 1; - - /* Check that the requested address is not less than the base address of the heap. */ - if (sAllocationDevVAddr.uiAddr < psDevmemHeap->sBaseAddr.uiAddr) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "sAllocationDevVAddr ("IMG_DEV_VIRTADDR_FMTSPEC") is invalid! " - "Must be greater or equal to "IMG_DEV_VIRTADDR_FMTSPEC, - sAllocationDevVAddr.uiAddr, - psDevmemHeap->sBaseAddr.uiAddr); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Check the allocation size is valid (must be page granular). */ - if ((uiAllocationSize & ui64InvalidSizeMask) != 0 || uiAllocationSize == 0) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "uiAllocationSize ("IMG_DEVMEM_SIZE_FMTSPEC") is invalid! Must a multiple of %u and greater than 0", - uiAllocationSize, - 1 << psDevmemHeap->uiLog2PageSize); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (uiAllocationSize > PMR_MAX_SUPPORTED_SIZE) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "uiAllocationSize must be less than or equal to the max PMR size (" - IMG_DEVMEM_SIZE_FMTSPEC")", - PMR_MAX_SUPPORTED_SIZE); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Check that requested address + size fits in our heap. */ - if (sLastReserveAddr.uiAddr > psDevmemHeap->sLastAddr.uiAddr) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "sAllocationDevVAddr ("IMG_DEV_VIRTADDR_FMTSPEC") is invalid! " - "Must be lower than "IMG_DEV_VIRTADDR_FMTSPEC, - sAllocationDevVAddr.uiAddr, - psDevmemHeap->sLastAddr.uiAddr - uiAllocationSize + 1); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemXIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - DEVMEMXINT_RESERVATION **ppsRsrv) -{ - DEVMEMXINT_RESERVATION *psRsrv; - IMG_UINT32 uiNumPages; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsRsrv != NULL, "ppsRsrv"); - - eError = ReserveRangeParamValidation(psDevmemHeap, - sAllocationDevVAddr, - uiAllocationSize); - PVR_LOG_RETURN_IF_ERROR(eError, "ReserveRangeParamValidation"); - - - if (!DevmemIntHeapAcquire(psDevmemHeap)) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_REFCOUNT_OVERFLOW, ErrorReturnError); - } - - uiNumPages = uiAllocationSize >> psDevmemHeap->uiLog2PageSize; - psRsrv = OSAllocZMem(sizeof(*psRsrv->ppsPMR) * uiNumPages + sizeof(*psRsrv)); - PVR_LOG_GOTO_IF_NOMEM(psRsrv, eError, ErrorUnreferenceHeap); - - eError = OSLockCreate(&psRsrv->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", ErrorFreeReservation); - - psRsrv->sBase = sAllocationDevVAddr; - psRsrv->uiLength = uiAllocationSize; - psRsrv->ppsPMR = IMG_OFFSET_ADDR(psRsrv, sizeof(*psRsrv)); - - eError = MMU_Alloc(psDevmemHeap->psDevmemCtx->psMMUContext, - uiAllocationSize, - &uiAllocationSize, - 0, /* IMG_UINT32 uiProtFlags */ - 0, /* alignment is n/a since we supply devvaddr */ - &sAllocationDevVAddr, - psDevmemHeap->uiLog2PageSize); - PVR_GOTO_IF_ERROR(eError, ErrorDestroyLock); - - /* since we supplied the virt addr, MMU_Alloc shouldn't have - chosen a new one for us */ - PVR_ASSERT(sAllocationDevVAddr.uiAddr == psRsrv->sBase.uiAddr); - - psRsrv->psDevmemHeap = psDevmemHeap; - *ppsRsrv = psRsrv; - - return PVRSRV_OK; - -ErrorDestroyLock: - OSLockDestroy(psRsrv->hLock); -ErrorFreeReservation: - OSFreeMem(psRsrv); -ErrorUnreferenceHeap: - DevmemIntHeapRelease(psDevmemHeap); -ErrorReturnError: - return eError; -} - -PVRSRV_ERROR -DevmemXIntUnreserveRange(DEVMEMXINT_RESERVATION *psRsrv) -{ - IMG_UINT32 i; - - MMU_Free(psRsrv->psDevmemHeap->psDevmemCtx->psMMUContext, - psRsrv->sBase, - psRsrv->uiLength, - psRsrv->psDevmemHeap->uiLog2PageSize); - - /* No need to lock the mapping here since this is a handle destruction path which can not be - * executed while there are outstanding handle lookups, i.e. other operations are performed - * on the mapping. Bridge and handle framework also make sure this path can also not be executed - * concurrently. */ - - for (i = 0; i < _DevmemXReservationPageCount(psRsrv); i++) - { - if (psRsrv->ppsPMR[i] != NULL) - { - PMRUnrefPMR2(psRsrv->ppsPMR[i]); - } - } - - /* Don't bother with refcount on reservation, as a reservation only ever - * holds one mapping, so we directly decrement the refcount on the heap - * instead. - * Function will print an error if the heap could not be unreferenced. */ - DevmemIntHeapRelease(psRsrv->psDevmemHeap); - - OSLockDestroy(psRsrv->hLock); - OSFreeMem(psRsrv); - - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR -DevmemValidateFlags(PMR *psPMR, PVRSRV_MEMALLOCFLAGS_T uiMapFlags) -{ - PMR_FLAGS_T uiPMRFlags = PMR_Flags(psPMR); - PVRSRV_ERROR eError = PVRSRV_OK; - - if (PVRSRV_CHECK_SHARED_BUFFER(uiPMRFlags) && PVRSRV_CHECK_GPU_READABLE(uiMapFlags) && !PVRSRV_CHECK_GPU_READABLE(uiPMRFlags)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR is not GPU readable.", __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_FLAGS, ErrorReturnError); - } - - if (PVRSRV_CHECK_SHARED_BUFFER(uiPMRFlags) && PVRSRV_CHECK_GPU_WRITEABLE(uiMapFlags) && !PVRSRV_CHECK_GPU_WRITEABLE(uiPMRFlags)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR is not GPU writeable.", __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_FLAGS, ErrorReturnError); - } - -ErrorReturnError: - return eError; -} - -PVRSRV_ERROR -DevmemXIntMapPages(DEVMEMXINT_RESERVATION *psRsrv, - PMR *psPMR, - IMG_UINT32 uiPageCount, - IMG_UINT32 uiPhysPageOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiVirtPageOffset) -{ - PVRSRV_ERROR eError; - IMG_UINT32 uiPMRMaxChunkCount = PMRGetMaxChunkCount(psPMR); - DEVMEMINT_HEAP *psDevmemHeap = psRsrv->psDevmemHeap; - IMG_UINT32 uiLog2PageSize = psDevmemHeap->uiLog2PageSize; - IMG_UINT32 i; - - PVR_LOG_RETURN_IF_INVALID_PARAM((uiPageCount + uiPhysPageOffset) <= uiPMRMaxChunkCount, "uiPageCount+uiPhysPageOffset"); - - /* The range is not valid for the given virtual descriptor */ - PVR_LOG_RETURN_IF_FALSE((uiVirtPageOffset + uiPageCount) <= _DevmemXReservationPageCount(psRsrv), - "mapping offset out of range", PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE); - PVR_LOG_RETURN_IF_FALSE((uiFlags & ~PVRSRV_MEMALLOCFLAGS_DEVMEMX_VIRTUAL_MASK) == 0, - "invalid flags", PVRSRV_ERROR_INVALID_FLAGS); - - if (uiLog2PageSize > PMR_GetLog2Contiguity(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Device heap and PMR have incompatible " - "Log2Contiguity (%u - %u). PMR contiguity must be a multiple " - "of the heap contiguity!", __func__, uiLog2PageSize, - PMR_GetLog2Contiguity(psPMR))); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = DevmemValidateFlags(psPMR, uiFlags); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemValidateFlags"); - - OSLockAcquire(psRsrv->hLock); - - eError = MMU_MapPages(psDevmemHeap->psDevmemCtx->psMMUContext, - uiFlags, - _DevmemXReservationPageAddress(psRsrv, uiVirtPageOffset), - psPMR, - uiPhysPageOffset, - uiPageCount, - NULL, - psDevmemHeap->uiLog2PageSize); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - - for (i = uiVirtPageOffset; i < (uiVirtPageOffset + uiPageCount); i++) - { - PMRRefPMR2(psPMR); - - if (psRsrv->ppsPMR[i] != NULL) - { - PMRUnrefPMR2(psRsrv->ppsPMR[i]); - } - - psRsrv->ppsPMR[i] = psPMR; - } - - OSLockRelease(psRsrv->hLock); - - return PVRSRV_OK; - -ErrUnlock: - OSLockRelease(psRsrv->hLock); - - return eError; -} - -PVRSRV_ERROR -DevmemXIntUnmapPages(DEVMEMXINT_RESERVATION *psRsrv, - IMG_UINT32 uiVirtPageOffset, - IMG_UINT32 uiPageCount) -{ - DEVMEMINT_HEAP *psDevmemHeap = psRsrv->psDevmemHeap; - IMG_UINT32 i; - - PVR_LOG_RETURN_IF_FALSE((uiVirtPageOffset + uiPageCount) <= _DevmemXReservationPageCount(psRsrv), - "mapping offset out of range", PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE); - - OSLockAcquire(psRsrv->hLock); - - /* Unmap the pages and mark them invalid in the MMU PTE */ - MMU_UnmapPages(psDevmemHeap->psDevmemCtx->psMMUContext, - 0, - _DevmemXReservationPageAddress(psRsrv, uiVirtPageOffset), - uiPageCount, - NULL, - psDevmemHeap->uiLog2PageSize, - 0); - - for (i = uiVirtPageOffset; i < (uiVirtPageOffset + uiPageCount); i++) - { - if (psRsrv->ppsPMR[i] != NULL) - { - PMRUnrefPMR2(psRsrv->ppsPMR[i]); - psRsrv->ppsPMR[i] = NULL; - } - } - - OSLockRelease(psRsrv->hLock); - - return PVRSRV_OK; -} - -static INLINE IMG_UINT32 -_DevmemReservationPageCount(DEVMEMINT_RESERVATION2 *psRsrv) -{ - return psRsrv->uiLength >> psRsrv->psDevmemHeap->uiLog2PageSize; -} - -PVRSRV_ERROR -DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - DEVMEMINT_MAPPING **ppsMappingPtr) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemHeap); - PVR_UNREFERENCED_PARAMETER(psReservation); - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiMapFlags); - PVR_UNREFERENCED_PARAMETER(ppsMappingPtr); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntMapPMR2(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_RESERVATION2 *psReservation, - PMR *psPMR) -{ - PVRSRV_ERROR eError; - /* number of pages (device pages) that allocation spans */ - IMG_UINT32 ui32NumDevPages; - /* device virtual address of start of allocation */ - IMG_DEV_VIRTADDR sAllocationDevVAddr; - /* and its length */ - IMG_DEVMEM_SIZE_T uiAllocationSize; - IMG_UINT32 uiLog2HeapContiguity = psReservation->psDevmemHeap->uiLog2PageSize; - PVRSRV_MEMALLOCFLAGS_T uiMapFlags = psReservation->uiFlags; - IMG_BOOL bIsSparse = IMG_FALSE, bNeedBacking = IMG_FALSE; - PVRSRV_DEVICE_NODE *psDevNode = psReservation->psDevmemHeap->psDevmemCtx->psDevNode; - PMR_FLAGS_T uiPMRFlags; - PVRSRV_DEF_PAGE *psDefPage; - IMG_CHAR *pszPageName; - IMG_DEV_PHYADDR *psDevPAddr; - IMG_BOOL *pbValid; - IMG_DEVMEM_SIZE_T uiPMRLogicalSize; - IMG_UINT32 i; - - PVR_UNREFERENCED_PARAMETER(psDevmemHeap); - - PMR_LogicalSize(psPMR, &uiPMRLogicalSize); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psReservation->psMappedPMR == NULL, "psReservation"); - PVR_LOG_RETURN_IF_INVALID_PARAM(uiPMRLogicalSize == psReservation->uiLength, "psPMR logical size"); - - if (uiLog2HeapContiguity > PMR_GetLog2Contiguity(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Device heap and PMR have incompatible contiguity (%u - %u). " - "Heap contiguity must be a multiple of the heap contiguity!", - __func__, - uiLog2HeapContiguity, - PMR_GetLog2Contiguity(psPMR) )); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, ErrorReturnError); - } - - eError = DevmemValidateFlags(psPMR, uiMapFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemValidateFlags", ErrorReturnError); - - OSLockAcquire(psReservation->hLock); - - if (!DevmemIntReservationAcquireUnlocked(psReservation)) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_REFCOUNT_OVERFLOW, ErrorReturnError); - } - - uiAllocationSize = psReservation->uiLength; - - ui32NumDevPages = 0xffffffffU & ( ( (uiAllocationSize - 1) >> uiLog2HeapContiguity) + 1); - PVR_ASSERT((IMG_DEVMEM_SIZE_T) ui32NumDevPages << uiLog2HeapContiguity == uiAllocationSize); - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_GOTO_IF_ERROR(eError, ErrorUnreference); - - sAllocationDevVAddr = psReservation->sBase; - - /*Check if the PMR that needs to be mapped is sparse */ - bIsSparse = PMR_IsSparse(psPMR); - if (bIsSparse) - { - /*Get the flags*/ - uiPMRFlags = PMR_Flags(psPMR); - bNeedBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiPMRFlags); - - if (bNeedBacking) - { - IMG_INT uiInitValue; - - if (PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiPMRFlags)) - { - psDefPage = &psDevNode->sDevZeroPage; - uiInitValue = PVR_ZERO_PAGE_INIT_VALUE; - pszPageName = DEV_ZERO_PAGE; - } - else - { - psDefPage = &psDevNode->sDummyPage; - uiInitValue = PVR_DUMMY_PAGE_INIT_VALUE; - pszPageName = DUMMY_PAGE; - } - - /* Error is logged with in the function if any failures. - * As the allocation fails we need to fail the map request and - * return appropriate error - * - * Allocation of dummy/zero page is done after locking the pages for PMR physically - * By implementing this way, the best case path of dummy/zero page being most likely to be - * allocated after physically locking down pages, is considered. - * If the dummy/zero page allocation fails, we do unlock the physical address and the impact - * is a bit more in on demand mode of operation */ - eError = DevmemIntAllocDefBackingPage(psDevNode, - psDefPage, - uiInitValue, - pszPageName, - IMG_TRUE); - PVR_GOTO_IF_ERROR(eError, ErrorUnlockPhysAddr); - } - - /* N.B. We pass mapping permission flags to MMU_MapPages and let - * it reject the mapping if the permissions on the PMR are not compatible. */ - eError = MMU_MapPages(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext, - uiMapFlags, - sAllocationDevVAddr, - psPMR, - 0, - ui32NumDevPages, - NULL, - uiLog2HeapContiguity); - PVR_GOTO_IF_ERROR(eError, ErrorFreeDefBackingPage); - - psDevPAddr = OSAllocMem(ui32NumDevPages * sizeof(IMG_DEV_PHYADDR)); - PVR_LOG_GOTO_IF_NOMEM(psDevPAddr, eError, ErrorUnmapSparseMap); - - pbValid = OSAllocMem(ui32NumDevPages * sizeof(IMG_BOOL)); - PVR_LOG_GOTO_IF_NOMEM(pbValid, eError, ErrorFreePAddrMappingArray); - - /* Determine which entries of the PMR are valid */ - eError = PMR_DevPhysAddr(psPMR, - uiLog2HeapContiguity, - ui32NumDevPages, - 0, - psDevPAddr, - pbValid); - PVR_GOTO_IF_ERROR(eError, ErrorFreeValidArray); - - for (i = 0; i < ui32NumDevPages; i++) - { - if (DevmemIntReservationIsIndexMapped(psReservation, i)) - { - PMRUnrefPMR2(psReservation->psMappedPMR); - DevmemIntReservationSetMappingIndex(psReservation, i, IMG_FALSE); - } - - if (pbValid[i]) - { - PMRRefPMR2(psPMR); - DevmemIntReservationSetMappingIndex(psReservation, i, IMG_TRUE); - } - } - - OSFreeMem(psDevPAddr); - OSFreeMem(pbValid); - } - else - { - eError = MMU_MapPMRFast(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext, - sAllocationDevVAddr, - psPMR, - (IMG_DEVMEM_SIZE_T) ui32NumDevPages << uiLog2HeapContiguity, - uiMapFlags, - uiLog2HeapContiguity); - PVR_GOTO_IF_ERROR(eError, ErrorUnlockPhysAddr); - } - - psReservation->psMappedPMR = psPMR; - - OSLockRelease(psReservation->hLock); - - return PVRSRV_OK; - -ErrorFreeValidArray: - OSFreeMem(pbValid); -ErrorFreePAddrMappingArray: - OSFreeMem(psDevPAddr); -ErrorUnmapSparseMap: - MMU_UnmapPages(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext, - 0, - sAllocationDevVAddr, - ui32NumDevPages, - NULL, - uiLog2HeapContiguity, - 0); -ErrorFreeDefBackingPage: - if (bNeedBacking) - { - /*if the mapping failed, the allocated dummy ref count need - * to be handled accordingly */ - DevmemIntFreeDefBackingPage(psDevNode, - psDefPage, - pszPageName); - } -ErrorUnlockPhysAddr: - { - PVRSRV_ERROR eError1 = PVRSRV_OK; - eError1 = PMRUnlockSysPhysAddresses(psPMR); - PVR_LOG_IF_ERROR(eError1, "PMRUnlockSysPhysAddresses"); - } - -ErrorUnreference: - /* if fails there's not much to do (the function will print an error) */ - DevmemIntReservationReleaseUnlocked(psReservation); - - OSLockRelease(psReservation->hLock); - -ErrorReturnError: - PVR_ASSERT (eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -DevmemIntUnreserveRangeAndUnmapPMR2(DEVMEMINT_RESERVATION2 *psReservation) -{ - PVRSRV_ERROR eError; - - if (psReservation->psMappedPMR != NULL) - { - eError = DevmemIntUnmapPMR2(psReservation); - PVR_GOTO_IF_ERROR(eError, ErrorReturnError); - } - - eError = DevmemIntUnreserveRange2(psReservation); - PVR_GOTO_IF_ERROR(eError, ErrorReturnError); - - return PVRSRV_OK; - -ErrorReturnError: - return eError; -} - -PVRSRV_ERROR -DevmemIntGetReservationData(DEVMEMINT_RESERVATION2* psReservation, PMR** ppsPMR, IMG_DEV_VIRTADDR* psDevVAddr) -{ - /* Reservation might not have a PMR if a mapping was not yet performed */ - if (psReservation->psMappedPMR == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevVAddr->uiAddr = psReservation->sBase.uiAddr; - *ppsPMR = psReservation->psMappedPMR; - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping) -{ - PVR_UNREFERENCED_PARAMETER(psMapping); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntUnmapPMR2(DEVMEMINT_RESERVATION2 *psReservation) -{ - PVRSRV_ERROR eError; - DEVMEMINT_HEAP *psDevmemHeap = psReservation->psDevmemHeap; - /* device virtual address of start of allocation */ - IMG_DEV_VIRTADDR sAllocationDevVAddr; - /* number of pages (device pages) that allocation spans */ - IMG_UINT32 ui32NumDevPages; - IMG_BOOL bIsSparse = IMG_FALSE, bNeedBacking = IMG_FALSE; - IMG_UINT32 i; - - PVR_RETURN_IF_INVALID_PARAM(psReservation->psMappedPMR != NULL); - - ui32NumDevPages = _DevmemReservationPageCount(psReservation); - sAllocationDevVAddr = psReservation->sBase; - - OSLockAcquire(psReservation->hLock); - bIsSparse = PMR_IsSparse(psReservation->psMappedPMR); - - if (bIsSparse) - { - /*Get the flags*/ - PMR_FLAGS_T uiPMRFlags = PMR_Flags(psReservation->psMappedPMR); - bNeedBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiPMRFlags); - - if (bNeedBacking) - { - if (PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiPMRFlags)) - { - DevmemIntFreeDefBackingPage(psDevmemHeap->psDevmemCtx->psDevNode, - &psDevmemHeap->psDevmemCtx->psDevNode->sDevZeroPage, - DEV_ZERO_PAGE); - } - else - { - DevmemIntFreeDefBackingPage(psDevmemHeap->psDevmemCtx->psDevNode, - &psDevmemHeap->psDevmemCtx->psDevNode->sDummyPage, - DUMMY_PAGE); - } - } - - MMU_UnmapPages (psDevmemHeap->psDevmemCtx->psMMUContext, - 0, - sAllocationDevVAddr, - ui32NumDevPages, - NULL, - psDevmemHeap->uiLog2PageSize, - 0); - /* We are unmapping the whole PMR */ - for (i = 0; i < ui32NumDevPages; i++) - { - if (DevmemIntReservationIsIndexMapped(psReservation, i)) - { - /* All PMRs in the range should be the same, set local PMR - * for Unlocking phys addrs later */ - PMRUnrefPMR2(psReservation->psMappedPMR); - DevmemIntReservationSetMappingIndex(psReservation, i, IMG_FALSE); - } - } - } - else - { - MMU_UnmapPMRFast(psDevmemHeap->psDevmemCtx->psMMUContext, - sAllocationDevVAddr, - ui32NumDevPages, - psDevmemHeap->uiLog2PageSize); - } - - eError = PMRUnlockSysPhysAddresses(psReservation->psMappedPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - psReservation->psMappedPMR = NULL; - - DevmemIntReservationReleaseUnlocked(psReservation); - - OSLockRelease(psReservation->hLock); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - DEVMEMINT_RESERVATION **ppsReservationPtr) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemHeap); - PVR_UNREFERENCED_PARAMETER(sAllocationDevVAddr); - PVR_UNREFERENCED_PARAMETER(uiAllocationSize); - PVR_UNREFERENCED_PARAMETER(ppsReservationPtr); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntReserveRange2(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEMINT_RESERVATION2 **ppsReservationPtr) -{ - PVRSRV_ERROR eError; - DEVMEMINT_RESERVATION2 *psReservation; - IMG_UINT32 uiNumPages; - IMG_UINT64 ui64MapSize; - - PVR_ASSERT(ppsReservationPtr != NULL); - - eError = ReserveRangeParamValidation(psDevmemHeap, - sAllocationDevVAddr, - uiAllocationSize); - PVR_LOG_RETURN_IF_ERROR(eError, "ReserveRangeParamValidation"); - - if (!DevmemIntHeapAcquire(psDevmemHeap)) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_REFCOUNT_OVERFLOW, - ErrorReturnError); - } - - uiNumPages = uiAllocationSize >> psDevmemHeap->uiLog2PageSize; - - /* allocate memory to record the reservation info */ - ui64MapSize = sizeof(*psReservation->pui8Map) * LOG2_DIV(uiNumPages, MAP_MASK_SHIFT); - if (LOG2_MOD(uiNumPages, MAP_MASK_SHIFT) != 0) - { - ui64MapSize += 1; - } - - psReservation = OSAllocZMem(sizeof(*psReservation) + ui64MapSize); - PVR_LOG_GOTO_IF_NOMEM(psReservation, eError, ErrorUnreference); - - /* Create lock */ - eError = OSLockCreate(&psReservation->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", ErrorFreeReservation); - - /* Initialise refcount */ - psReservation->i32RefCount = 1; - - psReservation->uiFlags = uiFlags; - psReservation->sBase = sAllocationDevVAddr; - psReservation->uiLength = uiAllocationSize; - psReservation->pui8Map = IMG_OFFSET_ADDR(psReservation, sizeof(*psReservation)); - - eError = MMU_Alloc(psDevmemHeap->psDevmemCtx->psMMUContext, - uiAllocationSize, - &uiAllocationSize, - 0, /* IMG_UINT32 uiProtFlags */ - 0, /* alignment is n/a since we supply devvaddr */ - &sAllocationDevVAddr, - psDevmemHeap->uiLog2PageSize); - PVR_GOTO_IF_ERROR(eError, ErrorDestroyLock); - - /* since we supplied the virt addr, MMU_Alloc shouldn't have - chosen a new one for us */ - PVR_ASSERT(sAllocationDevVAddr.uiAddr == psReservation->sBase.uiAddr); - - psReservation->psDevmemHeap = psDevmemHeap; - *ppsReservationPtr = psReservation; - - return PVRSRV_OK; - - /* - * error exit paths follow - */ - -ErrorDestroyLock: - OSLockDestroy(psReservation->hLock); - -ErrorFreeReservation: - OSFreeMem(psReservation); - -ErrorUnreference: - /* if fails there's not much to do (the function will print an error) */ - DevmemIntHeapRelease(psDevmemHeap); - -ErrorReturnError: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psReservation) -{ - PVR_UNREFERENCED_PARAMETER(psReservation); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR -DevmemIntUnreserveRange2(DEVMEMINT_RESERVATION2 *psReservation) -{ - IMG_UINT32 i; - DEVMEMINT_HEAP *psDevmemHeap = psReservation->psDevmemHeap; - - OSLockAcquire(psReservation->hLock); - - if (psReservation->i32RefCount != DEVMEMRESERVATION_REFCOUNT_MIN) - { - PVR_DPF((PVR_DBG_ERROR, "%s called but still has existing references " - "(%d), free existing reservations & mappings first.", __func__, - psReservation->i32RefCount)); - - OSLockRelease(psReservation->hLock); - - return PVRSRV_ERROR_RETRY; - } - - OSLockRelease(psReservation->hLock); - - MMU_Free(psDevmemHeap->psDevmemCtx->psMMUContext, - psReservation->sBase, - psReservation->uiLength, - psDevmemHeap->uiLog2PageSize); - - for (i = 0; i < _DevmemReservationPageCount(psReservation); i++) - { - if (DevmemIntReservationIsIndexMapped(psReservation, i)) - { - PMRUnrefPMR2(psReservation->psMappedPMR); - DevmemIntReservationSetMappingIndex(psReservation, i, IMG_FALSE); - } - } - - OSLockDestroy(psReservation->hLock); - OSFreeMem(psReservation); - - DevmemIntHeapRelease(psDevmemHeap); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -DevmemIntHeapDestroy(DEVMEMINT_HEAP *psDevmemHeap) -{ - if (OSAtomicRead(&psDevmemHeap->uiRefCount) != DEVMEMHEAP_REFCOUNT_MIN) - { - PVR_DPF((PVR_DBG_ERROR, "%s called but still has existing references " - "(%d), free existing reservations & mappings first.", __func__, - OSAtomicRead(&psDevmemHeap->uiRefCount))); - - /* - * Try again later when you've freed all the memory - * - * Note: - * We don't expect the application to retry (after all this call would - * succeed if the client had freed all the memory which it should have - * done before calling this function). However, given there should be - * an associated handle, when the handle base is destroyed it will free - * any allocations leaked by the client and then it will retry this call, - * which should then succeed. - */ - return PVRSRV_ERROR_RETRY; - } - - PVR_ASSERT(OSAtomicRead(&psDevmemHeap->uiRefCount) == DEVMEMHEAP_REFCOUNT_MIN); - - DevmemIntCtxRelease(psDevmemHeap->psDevmemCtx); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed heap %p", __func__, psDevmemHeap)); - OSFreeMem(psDevmemHeap); - - return PVRSRV_OK; -} -PVRSRV_ERROR -DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap, - PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - SPARSE_MEM_RESIZE_FLAGS uiSparseFlags, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT64 sCpuVAddrBase) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemHeap); - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(ui32AllocPageCount); - PVR_UNREFERENCED_PARAMETER(pai32AllocIndices); - PVR_UNREFERENCED_PARAMETER(ui32FreePageCount); - PVR_UNREFERENCED_PARAMETER(uiSparseFlags); - PVR_UNREFERENCED_PARAMETER(uiFlags); - PVR_UNREFERENCED_PARAMETER(sDevVAddrBase); - PVR_UNREFERENCED_PARAMETER(sCpuVAddrBase); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -static PVRSRV_ERROR -DevmemIntValidateSparsePMRIndices(IMG_UINT32 ui32PMRLogicalChunkCount, - IMG_UINT32 *paui32LogicalIndices, - IMG_UINT32 ui32LogicalIndiceCount) -{ - IMG_UINT32 i; - IMG_UINT8 *paui8TrackedIndices; - IMG_UINT32 ui32AllocSize; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(ui32PMRLogicalChunkCount != 0); - PVR_ASSERT(paui32LogicalIndices != NULL); - PVR_ASSERT(ui32LogicalIndiceCount != 0 && ui32LogicalIndiceCount <= ui32PMRLogicalChunkCount); - - ui32AllocSize = LOG2_DIV(ui32PMRLogicalChunkCount, 3); - if (LOG2_MOD(ui32PMRLogicalChunkCount, 3) != 0) - { - ++ui32AllocSize; - } - - paui8TrackedIndices = OSAllocZMem(ui32AllocSize); - if (paui8TrackedIndices == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - for (i = 0; i < ui32LogicalIndiceCount; i++) - { - IMG_UINT32 ui32LogicalIndex = paui32LogicalIndices[i]; - - if (ui32LogicalIndex >= ui32PMRLogicalChunkCount) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Reservation index %u is OOB", - __func__, - ui32LogicalIndex)); - - eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE; - break; - } - - if (BIT_ISSET(paui8TrackedIndices[LOG2_DIV(ui32LogicalIndex, 3)], LOG2_MOD(ui32LogicalIndex, 3))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Duplicate index found: %u", - __func__, - ui32LogicalIndex)); - - eError = PVRSRV_ERROR_PMR_INVALID_MAP_INDEX_ARRAY; - break; - } - - BIT_SET(paui8TrackedIndices[LOG2_DIV(ui32LogicalIndex, 3)], LOG2_MOD(ui32LogicalIndex, 3)); - } - - OSFreeMem(paui8TrackedIndices); - return eError; -} - -PVRSRV_ERROR -DevmemIntChangeSparse2(DEVMEMINT_HEAP *psDevmemHeap, - PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - SPARSE_MEM_RESIZE_FLAGS uiSparseFlags, - DEVMEMINT_RESERVATION2 *psReservation, - IMG_UINT64 sCpuVAddrBase) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - IMG_UINT32 uiLog2PMRContiguity; - IMG_UINT32 uiLog2HeapContiguity; - IMG_UINT32 uiOrderDiff; - PVRSRV_MEMALLOCFLAGS_T uiFlags; - - IMG_UINT32 *pai32MapIndices; - IMG_UINT32 *pai32UnmapIndices; - IMG_UINT32 uiMapPageCount; - IMG_UINT32 uiUnmapPageCount; - - IMG_UINT64 ui64PMRLogicalSize; - IMG_UINT32 ui32LogicalChunkCount; - - PVR_UNREFERENCED_PARAMETER(psDevmemHeap); - - PMR_LogicalSize(psPMR, &ui64PMRLogicalSize); - ui32LogicalChunkCount = ui64PMRLogicalSize >> PMR_GetLog2Contiguity(psPMR); - - /* Ensure a PMR has been mapped to this reservation. */ - PVR_LOG_RETURN_IF_INVALID_PARAM(psReservation->psMappedPMR != NULL, "psReservation"); - - { - IMG_UINT64 ui64PMRUID; - IMG_UINT64 ui64ResPMRUID; - - /* Check the PMR that was used during mapping is being used now. */ - (void)PMRGetUID(psPMR, &ui64PMRUID); - (void)PMRGetUID(psReservation->psMappedPMR, &ui64ResPMRUID); - if (ui64ResPMRUID != ui64PMRUID) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Reservation doesn't represent virtual range associated" - " with given mapped PMR", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - psPMR = psReservation->psMappedPMR; - - if (!PMR_IsSparse(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Given PMR is not Sparse", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - uiLog2PMRContiguity = PMR_GetLog2Contiguity(psPMR); - uiLog2HeapContiguity = psReservation->psDevmemHeap->uiLog2PageSize; - - /* This is check is made in DevmemIntMapPMR - no need to do it again in release. */ - PVR_ASSERT(uiLog2HeapContiguity <= uiLog2PMRContiguity); - - if (uiSparseFlags & SPARSE_RESIZE_ALLOC) - { - PVR_LOG_RETURN_IF_INVALID_PARAM(ui32AllocPageCount != 0, "ui32AllocPageCount"); - PVR_LOG_RETURN_IF_FALSE(ui32AllocPageCount <= ui32LogicalChunkCount, - "ui32AllocPageCount is invalid", - PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE); - } - - if (uiSparseFlags & SPARSE_RESIZE_FREE) - { - PVR_LOG_RETURN_IF_INVALID_PARAM(ui32FreePageCount != 0, "ui32FreePageCount"); - PVR_LOG_RETURN_IF_FALSE(ui32FreePageCount <= ui32LogicalChunkCount, - "ui32FreePageCount is invalid", - PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE); - } - - if (PMR_IsMemLayoutFixed(psPMR) || PMR_IsCpuMapped(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This PMR layout cannot be changed - PMR_IsMemLayoutFixed()=%c, _PMR_IsMapped()=%c", - __func__, - PMR_IsMemLayoutFixed(psPMR) ? 'Y' : 'n', - PMR_IsCpuMapped(psPMR) ? 'Y' : 'n')); - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - uiFlags = psReservation->uiFlags; - eError = DevmemValidateFlags(psPMR, uiFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemValidateFlags", e0); - - pai32MapIndices = pai32AllocIndices; - pai32UnmapIndices = pai32FreeIndices; - uiMapPageCount = ui32AllocPageCount; - uiUnmapPageCount = ui32FreePageCount; - - OSLockAcquire(psReservation->hLock); - - /* - * The order of steps in which this request is done is given below. The order of - * operations is very important in this case: - * - * 1. The parameters are validated in function PMR_ChangeSparseMem below. - * A successful response indicates all the parameters are correct. - * In failure case we bail out from here without processing further. - * 2. On success, get the PMR specific operations done. this includes page alloc, page free - * and the corresponding PMR status changes. - * when this call fails, it is ensured that the state of the PMR before is - * not disturbed. If it succeeds, then we can go ahead with the subsequent steps. - * 3. Invalidate the GPU page table entries for the pages to be freed. - * 4. Write the GPU page table entries for the pages that got allocated. - * 5. Change the corresponding CPU space map. - * - * The above steps can be selectively controlled using flags. - */ - if (uiSparseFlags & SPARSE_RESIZE_BOTH) - { - /* Pre check free indices against reservation given */ - if (uiSparseFlags & SPARSE_RESIZE_FREE) - { - eError = DevmemIntValidateSparsePMRIndices(ui32LogicalChunkCount, - pai32FreeIndices, - ui32FreePageCount); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemIntValidateSparsePMRIndices", e0); - } - - /* Pre check alloc indices against reservation given */ - if (uiSparseFlags & SPARSE_RESIZE_ALLOC) - { - eError = DevmemIntValidateSparsePMRIndices(ui32LogicalChunkCount, - pai32AllocIndices, - ui32AllocPageCount); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemIntValidateSparsePMRIndices", e0); - } - - uiOrderDiff = uiLog2PMRContiguity - uiLog2HeapContiguity; - - /* Special case: - * Adjust indices if we map into a heap that uses smaller page sizes - * than the physical allocation itself. - * The incoming parameters are all based on the page size of the PMR - * but the mapping functions expects parameters to be in terms of heap page sizes. */ - if (uiOrderDiff != 0) - { - IMG_UINT32 uiPgIdx, uiPgOffset; - IMG_UINT32 uiPagesPerOrder = 1 << uiOrderDiff; - - uiMapPageCount = (uiMapPageCount << uiOrderDiff); - uiUnmapPageCount = (uiUnmapPageCount << uiOrderDiff); - - pai32MapIndices = OSAllocMem(uiMapPageCount * sizeof(*pai32MapIndices)); - PVR_GOTO_IF_NOMEM(pai32MapIndices, eError, e0); - - pai32UnmapIndices = OSAllocMem(uiUnmapPageCount * sizeof(*pai32UnmapIndices)); - if (!pai32UnmapIndices) - { - OSFreeMem(pai32MapIndices); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, e0); - } - - /* Every chunk index needs to be translated from physical indices - * into heap based indices. */ - for (uiPgIdx = 0; uiPgIdx < ui32AllocPageCount; uiPgIdx++) - { - for (uiPgOffset = 0; uiPgOffset < uiPagesPerOrder; uiPgOffset++) - { - pai32MapIndices[uiPgIdx*uiPagesPerOrder + uiPgOffset] = - pai32AllocIndices[uiPgIdx]*uiPagesPerOrder + uiPgOffset; - } - } - - for (uiPgIdx = 0; uiPgIdx < ui32FreePageCount; uiPgIdx++) - { - for (uiPgOffset = 0; uiPgOffset < uiPagesPerOrder; uiPgOffset++) - { - pai32UnmapIndices[uiPgIdx*uiPagesPerOrder + uiPgOffset] = - pai32FreeIndices[uiPgIdx]*uiPagesPerOrder + uiPgOffset; - } - } - } - - /* Validate the virtual indices to be freed. */ - if (uiSparseFlags & SPARSE_RESIZE_FREE) - { - IMG_UINT32 i; - for (i = 0; i < uiUnmapPageCount; i++) - { - IMG_BOOL bIsMapped = DevmemIntReservationIsIndexMapped(psReservation, - pai32UnmapIndices[i]); - if (!bIsMapped) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Reservation index %u is not mapped into the reservation", - __func__, - pai32UnmapIndices[i])); - PVR_GOTO_WITH_ERROR(eError, - PVRSRV_ERROR_DEVICEMEM_NO_MAPPING, - e1); - } - } - } - - /* Validate the virtual indices to be allocated. */ - if (uiSparseFlags & SPARSE_RESIZE_ALLOC) - { - IMG_UINT32 i; - for (i = 0; i < uiMapPageCount; i++) - { - IMG_BOOL bIsMapped = DevmemIntReservationIsIndexMapped(psReservation, - pai32MapIndices[i]); - if (bIsMapped) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Reservation index %u is mapped into the reservation", - __func__, - pai32MapIndices[i])); - PVR_GOTO_WITH_ERROR(eError, - PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED, - e1); - } - } - } - - /* Do the PMR specific changes first */ - eError = PMR_ChangeSparseMem(psPMR, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices, - uiSparseFlags); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Failed to do PMR specific changes.", - __func__)); - goto e1; - } - - /* Invalidate the page table entries for the free pages. - * Optimisation later would be not to touch the ones that gets re-mapped */ - if (uiSparseFlags & SPARSE_RESIZE_FREE) - { - PMR_FLAGS_T uiPMRFlags; - IMG_UINT32 i; - - /*Get the flags*/ - uiPMRFlags = PMR_Flags(psPMR); - - /* Unmap the pages and mark them invalid in the MMU PTE */ - MMU_UnmapPages (psReservation->psDevmemHeap->psDevmemCtx->psMMUContext, - uiFlags, - psReservation->sBase, - uiUnmapPageCount, - pai32UnmapIndices, - uiLog2HeapContiguity, - uiPMRFlags); - - for (i = 0; i < uiUnmapPageCount; i++) - { - IMG_UINT32 uiIndex = pai32UnmapIndices[i]; - - if (DevmemIntReservationIsIndexMapped(psReservation, uiIndex)) - { - PMRUnrefPMR2(psReservation->psMappedPMR); - DevmemIntReservationSetMappingIndex(psReservation, - uiIndex, - IMG_FALSE); - } - } - } - - /* Wire the pages tables that got allocated */ - if (uiSparseFlags & SPARSE_RESIZE_ALLOC) - { - IMG_UINT32 i; - /* Map the pages and mark them Valid in the MMU PTE */ - eError = MMU_MapPages (psReservation->psDevmemHeap->psDevmemCtx->psMMUContext, - uiFlags, - psReservation->sBase, - psPMR, - 0, - uiMapPageCount, - pai32MapIndices, - uiLog2HeapContiguity); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Failed to map alloc indices.", - __func__)); - goto e1; - } - - for (i = 0; i < uiMapPageCount; i++) - { - IMG_UINT32 uiIndex = pai32MapIndices[i]; - - if (!DevmemIntReservationIsIndexMapped(psReservation, uiIndex)) - { - PMRRefPMR2(psReservation->psMappedPMR); - DevmemIntReservationSetMappingIndex(psReservation, - uiIndex, - IMG_TRUE); - } - } - } - } - -#ifndef PVRSRV_UNMAP_ON_SPARSE_CHANGE - /* Do the changes in sparse on to the CPU virtual map accordingly */ - if (uiSparseFlags & SPARSE_MAP_CPU_ADDR) - { - if (sCpuVAddrBase != 0) - { - eError = PMR_ChangeSparseMemCPUMap(psPMR, - sCpuVAddrBase, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Failed to map to CPU addr space.", - __func__)); - goto e1; - } - } - } -#endif - -e1: - if (pai32MapIndices != pai32AllocIndices) - { - OSFreeMem(pai32MapIndices); - } - if (pai32UnmapIndices != pai32FreeIndices) - { - OSFreeMem(pai32UnmapIndices); - } -e0: - OSLockRelease(psReservation->hLock); - return eError; -} - -/*************************************************************************/ /*! -@Function DevmemIntCtxDestroy -@Description Destroy that created by DevmemIntCtxCreate -@Input psDevmemCtx Device Memory context -@Return cannot fail. -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntCtxDestroy(DEVMEMINT_CTX *psDevmemCtx) -{ - /* - We can't determine if we should be freeing the context here - as a refcount!=1 could be due to either the fact that heap(s) - remain with allocations on them, or that this memory context - has been exported. - As the client couldn't do anything useful with this information - anyway and the fact that the refcount will ensure we only - free the context when _all_ references have been released - don't bother checking and just return OK regardless. - */ - DevmemIntCtxRelease(psDevmemCtx); - return PVRSRV_OK; -} - -PVRSRV_ERROR DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_DEV_VIRTADDR sDevAddr) -{ - IMG_UINT32 i, j, uiLog2HeapPageSize = 0; - DEVICE_MEMORY_INFO *psDinfo = &psDevNode->sDevMemoryInfo; - DEVMEM_HEAP_CONFIG *psConfig = psDinfo->psDeviceMemoryHeapConfigArray; - - IMG_BOOL bFound = IMG_FALSE; - - for (i = 0; - i < psDinfo->uiNumHeapConfigs && !bFound; - i++) - { - for (j = 0; - j < psConfig[i].uiNumHeaps && !bFound; - j++) - { - IMG_DEV_VIRTADDR uiBase = - psConfig[i].psHeapBlueprintArray[j].sHeapBaseAddr; - IMG_DEVMEM_SIZE_T uiSize = - psConfig[i].psHeapBlueprintArray[j].uiHeapLength; - - if ((sDevAddr.uiAddr >= uiBase.uiAddr) && - (sDevAddr.uiAddr < (uiBase.uiAddr + uiSize))) - { - uiLog2HeapPageSize = - psConfig[i].psHeapBlueprintArray[j].uiLog2DataPageSize; - bFound = IMG_TRUE; - } - } - } - - if (uiLog2HeapPageSize == 0) - { - return PVRSRV_ERROR_INVALID_GPU_ADDR; - } - - return MMU_IsVDevAddrValid(psDevMemContext->psMMUContext, - uiLog2HeapPageSize, - sDevAddr) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_GPU_ADDR; -} - -PVRSRV_ERROR -DevmemIntFlushDevSLCRange(DEVMEMINT_CTX *psDevMemContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate) -{ - PVRSRV_DEVICE_NODE *psDevNode = psDevMemContext->psDevNode; - MMU_CONTEXT *psMMUContext = psDevMemContext->psMMUContext; - - if (psDevNode->pfnDevSLCFlushRange) - { - return psDevNode->pfnDevSLCFlushRange(psDevNode, - psMMUContext, - sDevVAddr, - uiSize, - bInvalidate); - } - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR -DevmemIntInvalidateFBSCTable(DEVMEMINT_CTX *psDevMemContext, - IMG_UINT64 ui64FBSCEntryMask) -{ - PVRSRV_DEVICE_NODE *psDevNode = psDevMemContext->psDevNode; - MMU_CONTEXT *psMMUContext = psDevMemContext->psMMUContext; - - if (psDevNode->pfnInvalFBSCTable) - { - return psDevNode->pfnInvalFBSCTable(psDevNode, - psMMUContext, - ui64FBSCEntryMask); - } - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR DevmemIntGetFaultAddress(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_DEV_VIRTADDR *psFaultAddress) -{ - if ((psDevMemContext->ui32Flags & DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE) == 0) - { - return PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - - *psFaultAddress = psDevMemContext->sFaultAddress; - psDevMemContext->ui32Flags &= ~DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE; - - return PVRSRV_OK; -} - -static POSWR_LOCK g_hExportCtxListLock; -static DLLIST_NODE g_sExportCtxList; - -PVRSRV_ERROR -DevmemIntInit(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - dllist_init(&g_sExportCtxList); - - eError = OSWRLockCreate(&g_hExportCtxListLock); - - return eError; -} - -PVRSRV_ERROR -DevmemIntDeInit(void) -{ - PVR_ASSERT(dllist_is_empty(&g_sExportCtxList)); - - OSWRLockDestroy(g_hExportCtxListLock); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemIntExportCtx(DEVMEMINT_CTX *psContext, - PMR *psPMR, - DEVMEMINT_CTX_EXPORT **ppsContextExport) -{ - DEVMEMINT_CTX_EXPORT *psCtxExport; - - psCtxExport = OSAllocMem(sizeof(DEVMEMINT_CTX_EXPORT)); - PVR_LOG_RETURN_IF_NOMEM(psCtxExport, "psCtxExport"); - - DevmemIntCtxAcquire(psContext); - PMRRefPMR(psPMR); - /* Now that the source PMR is exported, the layout - * can't change as there could be outstanding importers - * This is to make sure both exporter and importers view of - * the memory is same */ - PMR_SetLayoutFixed(psPMR, IMG_TRUE); - psCtxExport->psDevmemCtx = psContext; - psCtxExport->psPMR = psPMR; - OSWRLockAcquireWrite(g_hExportCtxListLock); - dllist_add_to_tail(&g_sExportCtxList, &psCtxExport->sNode); - OSWRLockReleaseWrite(g_hExportCtxListLock); - - *ppsContextExport = psCtxExport; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemIntUnexportCtx(DEVMEMINT_CTX_EXPORT *psContextExport) -{ - PMRUnrefPMR(psContextExport->psPMR); - DevmemIntCtxRelease(psContextExport->psDevmemCtx); - OSWRLockAcquireWrite(g_hExportCtxListLock); - dllist_remove_node(&psContextExport->sNode); - OSWRLockReleaseWrite(g_hExportCtxListLock); - OSFreeMem(psContextExport); - - /* Unable to find exported context, return error */ - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemIntAcquireRemoteCtx(PMR *psPMR, - DEVMEMINT_CTX **ppsContext, - IMG_HANDLE *phPrivData) -{ - PDLLIST_NODE psListNode, psListNodeNext; - DEVMEMINT_CTX_EXPORT *psCtxExport; - - OSWRLockAcquireRead(g_hExportCtxListLock); - /* Find context from list using PMR as key */ - dllist_foreach_node(&g_sExportCtxList, psListNode, psListNodeNext) - { - psCtxExport = IMG_CONTAINER_OF(psListNode, DEVMEMINT_CTX_EXPORT, sNode); - if (psCtxExport->psPMR == psPMR) - { - DevmemIntCtxAcquire(psCtxExport->psDevmemCtx); - *ppsContext = psCtxExport->psDevmemCtx; - *phPrivData = psCtxExport->psDevmemCtx->hPrivData; - - OSWRLockReleaseRead(g_hExportCtxListLock); - - /* PMR should have been already exported to import it - * If a PMR is exported, its immutable and the same is - * checked here */ - PVR_ASSERT(IMG_TRUE == PMR_IsMemLayoutFixed(psPMR)); - - return PVRSRV_OK; - } - } - OSWRLockReleaseRead(g_hExportCtxListLock); - - /* Unable to find exported context, return error */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire remote context. Could not retrieve context with given PMR", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; -} - -/*************************************************************************/ /*! -@Function DevmemIntRegisterPFNotify -@Description Registers a PID to be notified when a page fault occurs on a - specific device memory context. -@Input psDevmemCtx The context to be notified about. -@Input ui32PID The PID of the process that would like to be - notified. -@Input bRegister If true, register. If false, de-register. -@Return PVRSRV_ERROR. -*/ /**************************************************************************/ -PVRSRV_ERROR DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx, - IMG_INT32 ui32PID, - IMG_BOOL bRegister) -{ - PVRSRV_DEVICE_NODE *psDevNode; - DLLIST_NODE *psNode, *psNodeNext; - DEVMEMINT_PF_NOTIFY *psNotifyNode; - IMG_BOOL bPresent = IMG_FALSE; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevmemCtx, "psDevmemCtx"); - - /* Acquire write lock for the duration, to avoid resource free - * while trying to read (no need to then also acquire the read lock - * as we have exclusive access while holding the write lock) - */ - OSWRLockAcquireWrite(psDevmemCtx->hListLock); - - psDevNode = psDevmemCtx->psDevNode; - - if (bRegister) - { - /* If this is the first PID in the list, the device memory context - * needs to be registered for notification */ - if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead)) - { - OSWRLockAcquireWrite(psDevNode->hMemoryContextPageFaultNotifyListLock); - dllist_add_to_tail(&psDevNode->sMemoryContextPageFaultNotifyListHead, - &psDevmemCtx->sPageFaultNotifyListElem); - OSWRLockReleaseWrite(psDevNode->hMemoryContextPageFaultNotifyListLock); - } - } - - /* Loop through the registered PIDs and check whether this one is - * present */ - dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext) - { - psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem); - - if (psNotifyNode->ui32PID == ui32PID) - { - bPresent = IMG_TRUE; - break; - } - } - - if (bRegister) - { - if (bPresent) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Trying to register a PID that is already registered", - __func__)); - eError = PVRSRV_ERROR_PID_ALREADY_REGISTERED; - goto err_already_registered; - } - - psNotifyNode = OSAllocMem(sizeof(*psNotifyNode)); - if (psNotifyNode == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unable to allocate memory for the notify list", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_out_of_mem; - } - psNotifyNode->ui32PID = ui32PID; - /* Write lock is already held */ - dllist_add_to_tail(&(psDevmemCtx->sProcessNotifyListHead), &(psNotifyNode->sProcessNotifyListElem)); - } - else - { - if (!bPresent) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Trying to unregister a PID that is not registered", - __func__)); - eError = PVRSRV_ERROR_PID_NOT_REGISTERED; - goto err_not_registered; - } - /* Write lock is already held */ - dllist_remove_node(psNode); - psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem); - OSFreeMem(psNotifyNode); - - /* If the last process in the list is being unregistered, then also - * unregister the device memory context from the notify list. */ - if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead)) - { - OSWRLockAcquireWrite(psDevNode->hMemoryContextPageFaultNotifyListLock); - dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem); - OSWRLockReleaseWrite(psDevNode->hMemoryContextPageFaultNotifyListLock); - } - } - eError = PVRSRV_OK; - -err_already_registered: -err_out_of_mem: -err_not_registered: - - OSWRLockReleaseWrite(psDevmemCtx->hListLock); - return eError; -} - -/*************************************************************************/ /*! -@Function DevmemIntPFNotify -@Description Notifies any processes that have registered themselves to be - notified when a page fault happens on a specific device memory - context. -@Input *psDevNode The device node. -@Input ui64FaultedPCAddress The page catalogue address that faulted. -@Input sFaultAddress The address that triggered the fault. -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT64 ui64FaultedPCAddress, - IMG_DEV_VIRTADDR sFaultAddress) -{ - DLLIST_NODE *psNode, *psNodeNext; - DEVMEMINT_PF_NOTIFY *psNotifyNode; - PVRSRV_ERROR eError; - DEVMEMINT_CTX *psDevmemCtx = NULL; - IMG_BOOL bFailed = IMG_FALSE; - - OSWRLockAcquireRead(psDevNode->hMemoryContextPageFaultNotifyListLock); - if (dllist_is_empty(&(psDevNode->sMemoryContextPageFaultNotifyListHead))) - { - OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock); - return PVRSRV_OK; - } - - dllist_foreach_node(&(psDevNode->sMemoryContextPageFaultNotifyListHead), psNode, psNodeNext) - { - DEVMEMINT_CTX *psThisContext = - IMG_CONTAINER_OF(psNode, DEVMEMINT_CTX, sPageFaultNotifyListElem); - IMG_DEV_PHYADDR sPCDevPAddr; - - eError = MMU_AcquireBaseAddr(psThisContext->psMMUContext, &sPCDevPAddr); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "MMU_AcquireBaseAddr"); - OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock); - return eError; - } - - if (sPCDevPAddr.uiAddr == ui64FaultedPCAddress) - { - psDevmemCtx = psThisContext; - break; - } - } - OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock); - - if (psDevmemCtx == NULL) - { - /* Not found, just return */ - return PVRSRV_OK; - } - OSWRLockAcquireRead(psDevmemCtx->hListLock); - - /* - * Store the first occurrence of a page fault address, - * until that address is consumed by a client. - */ - if ((psDevmemCtx->ui32Flags & DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE) == 0) - { - psDevmemCtx->sFaultAddress = sFaultAddress; - psDevmemCtx->ui32Flags |= DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE; - } - - /* Loop through each registered PID and send a signal to the process */ - dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext) - { - psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem); - - eError = OSDebugSignalPID(psNotifyNode->ui32PID); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unable to signal process for PID: %u", - __func__, - psNotifyNode->ui32PID)); - - PVR_ASSERT(!"Unable to signal process"); - - bFailed = IMG_TRUE; - } - } - OSWRLockReleaseRead(psDevmemCtx->hListLock); - - if (bFailed) - { - return PVRSRV_ERROR_SIGNAL_FAILED; - } - - return PVRSRV_OK; -} - -#if defined(PDUMP) -IMG_UINT32 DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext) -{ - IMG_UINT32 ui32MMUContextID; - MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32MMUContextID, PDUMP_FLAGS_CONTINUOUS); - return ui32MMUContextID; -} - -PVRSRV_ERROR -DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sDevAddrStart, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 ui32ArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_UINT32 uiPDumpMMUCtx; - - PVR_UNREFERENCED_PARAMETER(ui32ArraySize); - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored in PVRSRV_DATA. - */ - if (psDevmemCtx->psDevNode->sDevId.ui32InternalID != - (PVRSRVGetPVRSRVData())->ui32PDumpBoundDevice) - { - return PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE; - } - - eError = MMU_AcquirePDumpMMUContext(psDevmemCtx->psMMUContext, - &uiPDumpMMUCtx, - ui32PDumpFlags); - - PVR_ASSERT(eError == PVRSRV_OK); - - /* - The following SYSMEM refers to the 'MMU Context', hence it - should be the MMU context, not the PMR, that says what the PDump - MemSpace tag is? - From a PDump P.O.V. it doesn't matter which name space we use as long - as that MemSpace is used on the 'MMU Context' we're dumping from - */ - eError = PDumpMMUSAB(psDevmemCtx->psDevNode, - psDevmemCtx->psDevNode->sDevId.pszPDumpDevName, - uiPDumpMMUCtx, - sDevAddrStart, - uiSize, - pszFilename, - ui32FileOffset, - ui32PDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - MMU_ReleasePDumpMMUContext(psDevmemCtx->psMMUContext, ui32PDumpFlags); - return PVRSRV_OK; -} - -PVRSRV_ERROR -DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags) -{ - IMG_UINT32 ui32ContextID; - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(ui32Size); - - eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID, ui32PDumpFlags); - PVR_LOG_RETURN_IF_ERROR(eError, "MMU_AcquirePDumpMMUContext"); - - eError = PDumpImageDescriptor(psDeviceNode, - ui32ContextID, - (IMG_CHAR *)pszFileName, - sData, - ui32DataSize, - ui32LogicalWidth, - ui32LogicalHeight, - ui32PhysicalWidth, - ui32PhysicalHeight, - ePixFmt, - eMemLayout, - eFBCompression, - paui32FBCClearColour, - eFBCSwizzle, - sHeader, - ui32HeaderSize, - ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "PDumpImageDescriptor"); - - /* Don't care about return value */ - (void) MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext, ui32PDumpFlags); - - return eError; -} - -PVRSRV_ERROR -DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags) -{ - IMG_UINT32 ui32ContextID; - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(ui32Size); - - if ((ui32HeaderType != IBIN_HEADER_TYPE) && - (ui32HeaderType != DATA_HEADER_TYPE)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid header type (%u)", - __func__, - ui32HeaderType)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID, ui32PDumpFlags); - PVR_LOG_RETURN_IF_ERROR(eError, "MMU_AcquirePDumpMMUContext"); - - eError = PDumpDataDescriptor(psDeviceNode, - ui32ContextID, - (IMG_CHAR *)pszFileName, - sData, - ui32DataSize, - ui32HeaderType, - ui32ElementType, - ui32ElementCount, - ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "PDumpDataDescriptor"); - - /* Don't care about return value */ - (void) MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext, ui32PDumpFlags); - - return eError; -} - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_server.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_server.h deleted file mode 100644 index a4927179476f9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_server.h +++ /dev/null @@ -1,768 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Server side component for device memory management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEM_SERVER_H -#define DEVICEMEM_SERVER_H - -#include "device.h" /* For device node */ -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -#include "connection_server.h" -#include "pmr.h" - -typedef struct _DEVMEMINT_CTX_ DEVMEMINT_CTX; -typedef struct _DEVMEMINT_CTX_EXPORT_ DEVMEMINT_CTX_EXPORT; -typedef struct _DEVMEMINT_HEAP_ DEVMEMINT_HEAP; - -typedef struct _DEVMEMINT_RESERVATION_ DEVMEMINT_RESERVATION; -typedef struct _DEVMEMINT_RESERVATION2_ DEVMEMINT_RESERVATION2; - -typedef struct _DEVMEMINT_MAPPING_ DEVMEMINT_MAPPING; -typedef struct _DEVMEMXINT_RESERVATION_ DEVMEMXINT_RESERVATION; -typedef struct _DEVMEMINT_PF_NOTIFY_ DEVMEMINT_PF_NOTIFY; - - -/*************************************************************************/ /*! -@Function DevmemIntUnpin -@Description This is the counterpart to DevmemPin(). It is meant to be - called when the allocation is NOT mapped in the device virtual - space. - -@Input psPMR The physical memory to unpin. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is - registered to be reclaimed. Error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR DevmemIntUnpin(PMR *psPMR); - -/*************************************************************************/ /*! -@Function DevmemIntUnpinInvalidate -@Description This is the counterpart to DevmemIntPinValidate(). It is meant - to be called for allocations that ARE mapped in the device - virtual space and we have to invalidate the mapping. - -@Input psPMR The physical memory to unpin. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is - registered to be reclaimed. Error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntUnpinInvalidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR); - -/*************************************************************************/ /*! -@Function DevmemIntPin -@Description This is the counterpart to DevmemIntUnpin(). - Is meant to be called if there is NO device mapping present. - -@Input psPMR The physical memory to pin. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content - was successfully restored. - - PVRSRV_ERROR_PMR_NEW_MEMORY when the content - could not be restored and new physical memory - was allocated. - - A different error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR DevmemIntPin(PMR *psPMR); - -/*************************************************************************/ /*! -@Function DevmemIntPinValidate -@Description This is the counterpart to DevmemIntUnpinInvalidate(). - Is meant to be called if there is IS a device mapping present - that needs to be taken care of. - -@Input psDevmemMapping The mapping structure used for the passed PMR. - -@Input psPMR The physical memory to pin. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content - was successfully restored. - - PVRSRV_ERROR_PMR_NEW_MEMORY when the content - could not be restored and new physical memory - was allocated. - - A different error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntPinValidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR); -/* - * DevmemServerGetImportHandle() - * - * For given exportable memory descriptor returns PMR handle - * - */ -PVRSRV_ERROR -DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc, - IMG_HANDLE *phImport); - -/* - * DevmemServerGetHeapHandle() - * - * For given reservation returns the Heap handle - * - */ -PVRSRV_ERROR -DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION2 *psReservation, - IMG_HANDLE *phHeap); - -/* - * DevmemServerGetContext() - * - * For given heap returns the context. - * - */ -PVRSRV_ERROR -DevmemServerGetContext(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_CTX **ppsDevmemCtxPtr); - -/* - * DevmemServerGetPrivData() - * - * For given context returns the private data handle. - * - */ -PVRSRV_ERROR -DevmemServerGetPrivData(DEVMEMINT_CTX *psDevmemCtx, - IMG_HANDLE *phPrivData); - -/* - * DevmemIntAllocDefBackingPage - * - * This function allocates default backing page and initializes it - * with a given default value - * - */ -PVRSRV_ERROR DevmemIntAllocDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_DEF_PAGE *psDefPage, - IMG_INT uiInitValue, - IMG_CHAR *pcDefPageName, - IMG_BOOL bInitPage); -/* - * DevmemIntFreeDefBackingPage - * - * Frees a given page - */ -void DevmemIntFreeDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_DEF_PAGE *psDefPage, - IMG_CHAR *pcDefPageName); - - -/* - * DevmemIntCtxCreate() - * - * Create a Server-side Device Memory Context. This is usually the counterpart - * of the client side memory context, and indeed is usually created at the - * same time. - * - * You must have one of these before creating any heaps. - * - * All heaps must have been destroyed before calling - * DevmemIntCtxDestroy() - * - * If you call DevmemIntCtxCreate() (and it succeeds) you are promising to - * later call DevmemIntCtxDestroy() - * - * Note that this call will cause the device MMU code to do some work for - * creating the device memory context, but it does not guarantee that a page - * catalogue will have been created, as this may be deferred until the first - * allocation. - * - * Caller to provide storage for a pointer to the DEVMEM_CTX object that will - * be created by this call. - */ -PVRSRV_ERROR -DevmemIntCtxCreate(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - /* devnode / perproc etc */ - IMG_BOOL bKernelMemoryCtx, - DEVMEMINT_CTX **ppsDevmemCtxPtr, - IMG_HANDLE *hPrivData, - IMG_UINT32 *pui32CPUCacheLineSize); -/* - * DevmemIntCtxDestroy() - * - * Undoes a prior DevmemIntCtxCreate or DevmemIntCtxImport. - */ -PVRSRV_ERROR -DevmemIntCtxDestroy(DEVMEMINT_CTX *psDevmemCtx); - -/* - * DevmemIntHeapCreate() - * - * Creates a new heap in this device memory context. This will cause a call - * into the MMU code to allocate various data structures for managing this - * heap. It will not necessarily cause any page tables to be set up, as this - * can be deferred until first allocation. (i.e. we shouldn't care - it's up - * to the MMU code) - * - * Note that the data page size must be specified (as log 2). The data page - * size as specified here will be communicated to the mmu module, and thus may - * determine the page size configured in page directory entries for subsequent - * allocations from this heap. It is essential that the page size here is less - * than or equal to the "minimum contiguity guarantee" of any PMR that you - * subsequently attempt to map to this heap. - * - * If you call DevmemIntHeapCreate() (and the call succeeds) you are promising - * that you shall subsequently call DevmemIntHeapDestroy() - * - * Caller to provide storage for a pointer to the DEVMEM_HEAP object that will - * be created by this call. - */ -PVRSRV_ERROR -DevmemIntHeapCreate(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sHeapBaseAddr, - IMG_DEVMEM_SIZE_T uiHeapLength, - IMG_UINT32 uiLog2DataPageSize, - DEVMEMINT_HEAP **ppsDevmemHeapPtr); -/* - * DevmemIntHeapDestroy() - * - * Destroys a heap previously created with DevmemIntHeapCreate() - * - * All allocations from his heap must have been freed before this - * call. - */ -PVRSRV_ERROR -DevmemIntHeapDestroy(DEVMEMINT_HEAP *psDevmemHeap); - -/* - * DevmemIntMapPMR() - * - * Maps the given PMR to the virtual range previously allocated with - * DevmemIntReserveRange() - * - * If appropriate, the PMR must have had its physical backing committed, as - * this call will call into the MMU code to set up the page tables for this - * allocation, which shall in turn request the physical addresses from the - * PMR. Alternatively, the PMR implementation can choose to do so off the - * the back of the "lock" callback, which it will receive as a result - * (indirectly) of this call. - * - * This function makes no promise w.r.t. the circumstances that it can be - * called, and these would be "inherited" from the implementation of the PMR. - * For example if the PMR "lock" callback causes pages to be pinned at that - * time (which may cause scheduling or disk I/O etc.) then it would not be - * legal to "Map" the PMR in a context where scheduling events are disallowed. - * - * If you call DevmemIntMapPMR() (and the call succeeds) then you are promising - * that you shall later call DevmemIntUnmapPMR() - */ -PVRSRV_ERROR -DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - DEVMEMINT_MAPPING **ppsMappingPtr); - -PVRSRV_ERROR -DevmemIntMapPMR2(DEVMEMINT_HEAP *psDevmemHeap, - DEVMEMINT_RESERVATION2 *psReservation, - PMR *psPMR); -/* - * DevmemIntUnmapPMR() - * - * Reverses the mapping caused by DevmemIntMapPMR() - */ -PVRSRV_ERROR -DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping); - -PVRSRV_ERROR -DevmemIntUnmapPMR2(DEVMEMINT_RESERVATION2 *psReservation); - -/* DevmemIntMapPages() - * - * Maps an arbitrary amount of pages from a PMR to a reserved range - * - * @input psReservation Reservation handle for the range - * @input psPMR PMR that is mapped - * @input ui32PageCount Number of consecutive pages that are - * mapped - * @input ui32PhysicalPgOffset Logical offset in the PMR - * @input uiFlags Mapping flags - * @input sDevVAddrBase Virtual address base to start the - * mapping from - */ -PVRSRV_ERROR -DevmemIntMapPages(DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - IMG_UINT32 ui32PageCount, - IMG_UINT32 ui32PhysicalPgOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddrBase); - -/* DevmemIntUnmapPages() - * - * Unmaps an arbitrary amount of pages from a reserved range - * - * @input psReservation Reservation handle for the range - * @input sDevVAddrBase Virtual address base to start from - * @input ui32PageCount Number of consecutive pages that are - * unmapped - */ -PVRSRV_ERROR -DevmemIntUnmapPages(DEVMEMINT_RESERVATION *psReservation, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT32 ui32PageCount); - -PVRSRV_ERROR -DevmemIntUnreserveRangeAndUnmapPMR2(DEVMEMINT_RESERVATION2 *psReservation); - -/* - * DevmemIntReserveRange() - * - * Indicates that the specified range should be reserved from the given heap. - * - * In turn causes the page tables to be allocated to cover the specified range. - * - * If you call DevmemIntReserveRange() (and the call succeeds) then you are - * promising that you shall later call DevmemIntUnreserveRange() - */ -PVRSRV_ERROR -DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - DEVMEMINT_RESERVATION **ppsReservationPtr); - -PVRSRV_ERROR -DevmemIntReserveRange2(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - DEVMEMINT_RESERVATION2 **ppsReservationPtr); -/* - * DevmemIntUnreserveRange() - * - * Undoes the state change caused by DevmemIntReserveRage() - */ -PVRSRV_ERROR -DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psDevmemReservation); - -PVRSRV_ERROR -DevmemIntUnreserveRange2(DEVMEMINT_RESERVATION2 *psDevmemReservation); - -PVRSRV_ERROR -DevmemIntGetReservationData(DEVMEMINT_RESERVATION2* psReservation, PMR** ppsPMR, IMG_DEV_VIRTADDR* psDevVAddr); - -/*************************************************************************/ /*! - * @Function DevmemXIntReserveRange() - * @Description Indicates that the specified range should be reserved from the - * given heap. - * - * In turn causes the page tables to be allocated to cover the - * specified range. - * - * If you call DevmemIntReserveRange() (and the call succeeds) - * then you are promising that you shall later call - * DevmemIntUnreserveRange(). - * - * @Input psDevmemHeap Pointer to the heap the reservation is made - * on - * @Input sAllocationDevVAddr Virtual address of the reservation - * @Input uiAllocationSize Size of the reservation (in bytes) - * @Input ppsRsrv Return pointer to the reservation object - * - * @Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemXIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap, - IMG_DEV_VIRTADDR sAllocationDevVAddr, - IMG_DEVMEM_SIZE_T uiAllocationSize, - DEVMEMXINT_RESERVATION **ppsRsrv); - -/*************************************************************************/ /*! - * @Function DevmemXIntUnreserveRange() - * @Description Undoes the state change caused by DevmemXIntReserveRage() - * - * @Input psRsrv Reservation handle for the range - * - * @Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemXIntUnreserveRange(DEVMEMXINT_RESERVATION *psRsrv); - -/*************************************************************************/ /*! -@Function DevmemIntReservationAcquire -@Description Acquire a reference to the provided device memory reservation. -@Return IMG_TRUE if referenced and IMG_FALSE in case of error -*/ /**************************************************************************/ -IMG_BOOL -DevmemIntReservationAcquire(DEVMEMINT_RESERVATION2 *psDevmemReservation); - -/*************************************************************************/ /*! -@Function DevmemIntReservationRelease -@Description Release the reference to the provided device memory reservation. - If this is the last reference which was taken then the - reservation will be freed. -@Return None. -*/ /**************************************************************************/ -void -DevmemIntReservationRelease(DEVMEMINT_RESERVATION2 *psDevmemReservation); - -/*************************************************************************/ /*! - * @Function DevmemXIntMapPages() - * @Description Maps an arbitrary amount of pages from a PMR to a reserved range - * and takes references on the PMR. - * - * @Input psRsrv Reservation handle for the range - * @Input psPMR PMR that is mapped - * @Input uiPageCount Number of consecutive pages that are - * mapped - * @Input uiPhysPageOffset Logical offset in the PMR (measured in pages) - * @Input uiFlags Mapping flags - * @Input uiVirtPageOffset Offset from the reservation base to start the - * mapping from (measured in pages) - * - * @Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemXIntMapPages(DEVMEMXINT_RESERVATION *psRsrv, - PMR *psPMR, - IMG_UINT32 uiPageCount, - IMG_UINT32 uiPhysPageOffset, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiVirtPageOffset); - -/*************************************************************************/ /*! - * @Function DevmemXIntUnmapPages() - * @Description Unmaps an arbitrary amount of pages from a reserved range and - * releases references on associated PMRs. - * - * @Input psRsrv Reservation handle for the range - * @Input uiVirtPageOffset Offset from the reservation base to start the - * mapping from (measured in pages) - * @Input uiPageCount Number of consecutive pages that are - * unmapped - * - * @Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemXIntUnmapPages(DEVMEMXINT_RESERVATION *psRsrv, - IMG_UINT32 uiVirtPageOffset, - IMG_UINT32 uiPageCount); - -/*************************************************************************/ /*! -@Function DevmemIntChangeSparse -@Description Changes the sparse allocations of a PMR by allocating and freeing - pages and changing their corresponding CPU and GPU mappings. - -@input psDevmemHeap Pointer to the heap we map on -@input psPMR The PMR we want to map -@input ui32AllocPageCount Number of pages to allocate -@input pai32AllocIndices The logical PMR indices where pages will - be allocated. May be NULL. -@input ui32FreePageCount Number of pages to free -@input pai32FreeIndices The logical PMR indices where pages will - be freed. May be NULL. -@input uiSparseFlags Flags passed in to determine which kind - of sparse change the user wanted. - See devicemem_typedefs.h for details. -@input uiFlags Memalloc flags for this virtual range. -@input sDevVAddrBase The base address of the virtual range of - this sparse allocation. -@input sCpuVAddrBase The CPU base address of this allocation. - May be 0 if not existing. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap, - PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - SPARSE_MEM_RESIZE_FLAGS uiSparseFlags, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT64 sCpuVAddrBase); - -PVRSRV_ERROR -DevmemIntChangeSparse2(DEVMEMINT_HEAP *psDevmemHeap, - PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - SPARSE_MEM_RESIZE_FLAGS uiSparseFlags, - DEVMEMINT_RESERVATION2 *psReservation, - IMG_UINT64 sCpuVAddrBase); - -/* - * DevmemIntFlushDevSLCRange() - * - * Flush specified device context's virtual address range from SLC. - */ -PVRSRV_ERROR -DevmemIntFlushDevSLCRange(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate); - -/* - * DevmemIntRGXInvalidateFBSCTable() - * - * Invalidate selected FBSC table indices. - * - */ -PVRSRV_ERROR -DevmemIntInvalidateFBSCTable(DEVMEMINT_CTX *psDevmemCtx, - IMG_UINT64 ui64FBSCEntryMask); - -PVRSRV_ERROR -DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_DEV_VIRTADDR sDevAddr); - -PVRSRV_ERROR -DevmemIntGetFaultAddress(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_DEV_VIRTADDR *psFaultAddress); - -/*************************************************************************/ /*! -@Function DevmemIntRegisterPFNotifyKM -@Description Registers a PID to be notified when a page fault occurs on a - specific device memory context. -@Input psDevmemCtx The context to be notified about. -@Input ui32PID The PID of the process that would like to be - notified. -@Input bRegister If true, register. If false, de-register. -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR -DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx, - IMG_INT32 ui32PID, - IMG_BOOL bRegister); - -/*************************************************************************/ /*! -@Function DevmemIntPFNotify -@Description Notifies any processes that have registered themselves to be - notified when a page fault happens on a specific device memory - context. -@Input *psDevNode The device node. -@Input ui64FaultedPCAddress The page catalogue address that faulted. -@Input sFaultAddress The address that triggered the fault. -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT64 ui64FaultedPCAddress, - IMG_DEV_VIRTADDR sFaultAddress); - -#if defined(PDUMP) -/* - * DevmemIntPDumpSaveToFileVirtual() - * - * Writes out PDump "SAB" commands with the data found in memory at - * the given virtual address. - */ -PVRSRV_ERROR -DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sDevAddrStart, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PDumpFlags); - -IMG_UINT32 -DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext); - -PVRSRV_ERROR -DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR -DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags); -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemIntPDumpSaveToFileVirtual) -#endif -static INLINE PVRSRV_ERROR -DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx, - IMG_DEV_VIRTADDR sDevAddrStart, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDevmemCtx); - PVR_UNREFERENCED_PARAMETER(sDevAddrStart); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiArraySize); - PVR_UNREFERENCED_PARAMETER(pszFilename); - PVR_UNREFERENCED_PARAMETER(ui32FileOffset); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemIntPDumpImageDescriptor) -#endif -static INLINE PVRSRV_ERROR -DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psDevMemContext); - PVR_UNREFERENCED_PARAMETER(ui32Size); - PVR_UNREFERENCED_PARAMETER(pszFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32LogicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32LogicalHeight); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalHeight); - PVR_UNREFERENCED_PARAMETER(ePixFmt); - PVR_UNREFERENCED_PARAMETER(eMemLayout); - PVR_UNREFERENCED_PARAMETER(eFBCompression); - PVR_UNREFERENCED_PARAMETER(paui32FBCClearColour); - PVR_UNREFERENCED_PARAMETER(eFBCSwizzle); - PVR_UNREFERENCED_PARAMETER(sHeader); - PVR_UNREFERENCED_PARAMETER(ui32HeaderSize); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemIntPDumpDataDescriptor) -#endif -static INLINE PVRSRV_ERROR -DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_CTX *psDevMemContext, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psDevMemContext); - PVR_UNREFERENCED_PARAMETER(ui32Size); - PVR_UNREFERENCED_PARAMETER(pszFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32ElementType); - PVR_UNREFERENCED_PARAMETER(ui32ElementCount); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#endif /* PDUMP */ - -PVRSRV_ERROR -DevmemIntInit(void); - -PVRSRV_ERROR -DevmemIntDeInit(void); - -PVRSRV_ERROR -DevmemIntExportCtx(DEVMEMINT_CTX *psContext, - PMR *psPMR, - DEVMEMINT_CTX_EXPORT **ppsContextExport); - -PVRSRV_ERROR -DevmemIntUnexportCtx(DEVMEMINT_CTX_EXPORT *psContextExport); - -PVRSRV_ERROR -DevmemIntAcquireRemoteCtx(PMR *psPMR, - DEVMEMINT_CTX **ppsContext, - IMG_HANDLE *phPrivData); - -#endif /* DEVICEMEM_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_server_utils.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_server_utils.h deleted file mode 100644 index ad85c07cdcf66..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_server_utils.h +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header file utilities that are specific to device memory functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "img_types.h" -#include "device.h" -#include "pvrsrv_memallocflags.h" -#include "pvrsrv.h" - -static INLINE PVRSRV_ERROR DevmemCPUCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_MEMALLOCFLAGS_T ulFlags, - IMG_UINT32 *pui32Ret) -{ - IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags); - IMG_UINT32 ui32Ret; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags)); - - switch (ui32CPUCacheMode) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED; - break; - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC; - break; - - case PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT: - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED; - break; - - case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT: - - /* - * If system has no coherency but coherency has been requested for CPU - * and GPU we currently fall back to write-combine. - * This avoids errors on arm64 when uncached is turned into ordered device memory - * and suffers from problems with unaligned access. - */ - if ( (PVRSRV_GPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) && - !(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) ) - { - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC; - } - else - { - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED; - } - break; - - default: - PVR_LOG(("DevmemCPUCacheMode: Unknown CPU cache mode 0x%08x", ui32CPUCacheMode)); - PVR_ASSERT(0); - /* - We should never get here, but if we do then setting the mode - to uncached is the safest thing to do. - */ - ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED; - eError = PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE; - break; - } - - *pui32Ret = ui32Ret; - - return eError; -} - -static INLINE PVRSRV_ERROR DevmemDeviceCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_MEMALLOCFLAGS_T ulFlags, - IMG_UINT32 *pui32Ret) -{ - IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags); - IMG_UINT32 ui32Ret; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags)); - - switch (ui32DeviceCacheMode) - { - case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED: - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED; - break; - - case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC: - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC; - break; - - case PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT: - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED; - break; - - case PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT: - - /* - * If system has no coherency but coherency has been requested for CPU - * and GPU we currently fall back to write-combine. - * This avoids errors on arm64 when uncached is turned into ordered device memory - * and suffers from problems with unaligned access. - */ - if ( (PVRSRV_CPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) && - !(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) ) - { - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC; - } - else - { - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED; - } - break; - - default: - PVR_LOG(("DevmemDeviceCacheMode: Unknown device cache mode 0x%08x", ui32DeviceCacheMode)); - PVR_ASSERT(0); - /* - We should never get here, but if we do then setting the mode - to uncached is the safest thing to do. - */ - ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED; - eError = PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE; - break; - } - - *pui32Ret = ui32Ret; - - return eError; -} - -static INLINE IMG_BOOL DevmemCPUCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_MEMALLOCFLAGS_T ulFlags) -{ - IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags); - IMG_BOOL bRet = IMG_FALSE; - - PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags)); - - if (ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) - { - bRet = PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig); - } - return bRet; -} - -static INLINE IMG_BOOL DevmemDeviceCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_MEMALLOCFLAGS_T ulFlags) -{ - IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags); - IMG_BOOL bRet = IMG_FALSE; - - PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags)); - - if (ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) - { - bRet = PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig); - } - return bRet; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_typedefs.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_typedefs.h deleted file mode 100644 index 5079629448297..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_typedefs.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Client side part of device memory management -- this file - is forked from new_devmem_allocation.h as this one has to - reside in the top level include so that client code is able - to make use of the typedefs. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEM_TYPEDEFS_H -#define DEVICEMEM_TYPEDEFS_H - -#include -#include "img_types.h" -#include "pvrsrv_memallocflags.h" - -typedef struct DEVMEM_CONTEXT_TAG DEVMEM_CONTEXT; /*!< Convenience typedef for struct DEVMEM_CONTEXT_TAG */ -typedef struct DEVMEM_HEAP_TAG DEVMEM_HEAP; /*!< Convenience typedef for struct DEVMEM_HEAP_TAG */ -typedef struct DEVMEM_MEMDESC_TAG DEVMEM_MEMDESC; /*!< Convenience typedef for struct DEVMEM_MEMDESC_TAG */ -typedef struct DEVMEM_PAGELIST_TAG DEVMEM_PAGELIST; /*!< Convenience typedef for struct DEVMEM_PAGELIST_TAG */ - -typedef IMG_HANDLE DEVMEM_EXPORTHANDLE; /*!< Typedef for DeviceMem Export Handle */ -typedef IMG_UINT64 DEVMEM_EXPORTKEY; /*!< Typedef for DeviceMem Export Key */ -typedef IMG_DEVMEM_SIZE_T DEVMEM_SIZE_T; /*!< Typedef for DeviceMem SIZE_T */ -typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T; /*!< Typedef for DeviceMem LOG2 Alignment */ - -typedef struct DEVMEMX_PHYS_MEMDESC_TAG DEVMEMX_PHYSDESC; /*!< Convenience typedef for DevmemX physical */ -typedef struct DEVMEMX_VIRT_MEMDESC_TAG DEVMEMX_VIRTDESC; /*!< Convenience typedef for DevmemX virtual */ - -/*! calling code needs all the info in this struct, to be able to pass it around */ -typedef struct -{ - /*! A handle to the PMR. */ - IMG_HANDLE hPMRExportHandle; - /*! The "key" to prove we have authorisation to use this PMR */ - IMG_UINT64 uiPMRExportPassword; - /*! Size and alignment properties for this PMR. Note, these - numbers are not trusted in kernel, but we need to cache them - client-side in order to allocate from the VM arena. The kernel - will know the actual alignment and size of the PMR and thus - would prevent client code from breaching security here. Ditto - for physmem granularity (aka page size) if this is different - from alignment */ - IMG_DEVMEM_SIZE_T uiSize; - /*! We call this "contiguity guarantee" to be more precise than - calling it "alignment" or "page size", terms which may seem - similar but have different emphasis. The number reported here - is the minimum contiguity guarantee from the creator of the - PMR. Now, there is no requirement to allocate that coarsely - from the RA. The alignment given to the RA simply needs to be - at least as coarse as the device page size for the heap we - ultimately intend to map into. What is important is that the - device MMU data page size is not greater than the minimum - contiguity guarantee from the PMR. This value is reported to - the client in order that it can choose to make early checks and - perhaps decide which heap (in a variable page size scenario) it - would be safe to map this PMR into. For convenience, the - client may choose to use this argument as the alignment of the - virtual range he chooses to allocate, but this is _not_ - necessary and in many cases would be able to get away with a - finer alignment, should the heap into which this PMR will be - mapped support it. */ - IMG_DEVMEM_LOG2ALIGN_T uiLog2ContiguityGuarantee; -} DEVMEM_EXPORTCOOKIE; - -/* Enum that describes the operation associated with changing sparse memory */ -typedef IMG_UINT32 SPARSE_MEM_RESIZE_FLAGS; -#define SPARSE_RESIZE_NONE 0U - - /* This should be set to indicate the change needs allocation */ -#define SPARSE_RESIZE_ALLOC 1U - - /* This should be set to indicate the change needs free */ -#define SPARSE_RESIZE_FREE 2U - -#define SPARSE_RESIZE_BOTH (SPARSE_RESIZE_ALLOC | SPARSE_RESIZE_FREE) - -/* Remap functionality not supported, reserved for compatibility. */ -#define SPARSE_REMAP_MEM 4U - - /* Should be set to get the sparse changes appear in cpu virtual map */ -#define SPARSE_MAP_CPU_ADDR 8U - - -/* To be used with all the sparse allocations that gets mapped to CPU Virtual - * space. The sparse allocation CPU mapping is torn down and re-mapped every - * time the sparse allocation layout changes. - */ -#define PVRSRV_UNMAP_ON_SPARSE_CHANGE 1 - -/* To use with DevmemSubAllocate() as the default factor if no over-allocation - * is desired. - */ -#define DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER (1U) - -/* Defines the max length for PMR, MemDesc, Device memory History and RI debug - * annotations stored in memory, including the null terminator. - */ -#define DEVMEM_ANNOTATION_MAX_LEN ((IMG_UINT32)PVR_ANNOTATION_MAX_LEN + 1U) - -#endif /* #ifndef DEVICEMEM_TYPEDEFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.c b/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.c deleted file mode 100644 index 1f35b613a5da8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.c +++ /dev/null @@ -1,1298 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management internal utility functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Utility functions used internally by device memory management - code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "allocmem.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "ra.h" -#include "devicemem_utils.h" -#include "client_mm_bridge.h" -#include "client_cache_bridge.h" -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "client_ri_bridge.h" -#if defined(__KERNEL__) -#include "pvrsrv.h" -#else -#include "pvr_bridge_client.h" -#endif -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "proc_stats.h" -#endif - -#if defined(__KERNEL__) -#include "srvcore.h" -#else -#include "srvcore_intern.h" -#endif - -/* - SVM heap management support functions for CPU (un)mapping - */ -#define DEVMEM_MAP_SVM_USER_MANAGED_RETRY 2 - -static inline PVRSRV_ERROR -DevmemCPUMapSVMKernelManaged(DEVMEM_HEAP *psHeap, - DEVMEM_IMPORT *psImport, - IMG_UINT64 *ui64MapAddress) -{ - PVRSRV_ERROR eError; - IMG_UINT64 ui64SvmMapAddr; - IMG_UINT64 ui64SvmMapAddrEnd; - IMG_UINT64 ui64SvmHeapAddrEnd; - - /* SVM heap management always has XXX_MANAGER_KERNEL unless we - have triggered the fall back code-path in which case we - should not be calling into this code-path */ - PVR_ASSERT(psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_KERNEL); - - /* By acquiring the CPU virtual address here, it essentially - means we lock-down the virtual address for the duration - of the life-cycle of the allocation until a de-allocation - request comes in. Thus the allocation is guaranteed not to - change its virtual address on the CPU during its life-time. - NOTE: Import might have already been CPU Mapped before now, - normally this is not a problem, see fall back */ - eError = DevmemImportStructCPUMap(psImport); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "DevmemImportStructCPUMap"); - eError = PVRSRV_ERROR_DEVICEMEM_MAP_FAILED; - goto failSVM; - } - - /* Supplied kernel mmap virtual address is also device virtual address; - calculate the heap & kernel supplied mmap virtual address limits */ - ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr; - ui64SvmHeapAddrEnd = psHeap->sBaseAddress.uiAddr + psHeap->uiSize; - ui64SvmMapAddrEnd = ui64SvmMapAddr + psImport->uiSize; - PVR_ASSERT(ui64SvmMapAddr != (IMG_UINT64)0); - - /* SVM limit test may fail if processor has more virtual address bits than device */ - if ((ui64SvmMapAddr >= ui64SvmHeapAddrEnd || ui64SvmMapAddrEnd > ui64SvmHeapAddrEnd) || - (ui64SvmMapAddr & ~(ui64SvmHeapAddrEnd - 1))) - { - /* Unmap incompatible SVM virtual address, this - may not release address if it was elsewhere - CPU Mapped before call into this function */ - DevmemImportStructCPUUnmap(psImport); - - /* Flag incompatible SVM mapping */ - eError = PVRSRV_ERROR_BAD_MAPPING; - goto failSVM; - } - - *ui64MapAddress = ui64SvmMapAddr; -failSVM: - /* either OK, MAP_FAILED or BAD_MAPPING */ - return eError; -} - -static inline void -DevmemCPUUnmapSVMKernelManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport) -{ - PVR_UNREFERENCED_PARAMETER(psHeap); - DevmemImportStructCPUUnmap(psImport); -} - -static inline PVRSRV_ERROR -DevmemCPUMapSVMUserManaged(DEVMEM_HEAP *psHeap, - DEVMEM_IMPORT *psImport, - IMG_UINT uiAlign, - IMG_UINT64 *ui64MapAddress) -{ - RA_LENGTH_T uiAllocatedSize; - RA_BASE_T uiAllocatedAddr; - IMG_UINT64 ui64SvmMapAddr; - IMG_UINT uiRetry = 0; - PVRSRV_ERROR eError; - - /* If SVM heap management has transitioned to XXX_MANAGER_USER, - this is essentially a fall back approach that ensures we - continue to satisfy SVM alloc. This approach is not without - hazards in that we may specify a virtual address that is - already in use by the user process */ - PVR_ASSERT(psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER); - - /* Normally, for SVM heap allocations, CPUMap _must_ be done - before DevMap; ideally the initial CPUMap should be done by - SVM functions though this is not a hard requirement as long - as the prior elsewhere obtained CPUMap virtual address meets - SVM address requirements. This is a fall-back code-pathway - so we have to test that this assumption holds before we - progress any further */ - OSLockAcquire(psImport->sCPUImport.hLock); - - if (psImport->sCPUImport.ui32RefCount) - { - /* Already CPU Mapped SVM heap allocation, this prior elsewhere - obtained virtual address is responsible for the above - XXX_MANAGER_KERNEL failure. As we are not responsible for - this, we cannot progress any further so need to fail */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Previously obtained CPU map address not SVM compatible" - , __func__)); - - /* Revert SVM heap to DEVMEM_HEAP_MANAGER_KERNEL */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_KERNEL; - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Reverting SVM heap back to kernel managed", - __func__)); - - OSLockRelease(psImport->sCPUImport.hLock); - - /* Do we need a more specific error code here */ - eError = PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED; - goto failSVM; - } - - OSLockRelease(psImport->sCPUImport.hLock); - - do - { - /* Next we proceed to instruct the kernel to use the RA_Alloc supplied - virtual address to map-in this SVM import suballocation; there is no - guarantee that this RA_Alloc virtual address may not collide with an - already in-use VMA range in the process */ - eError = RA_Alloc(psHeap->psQuantizedVMRA, - psImport->uiSize, - RA_NO_IMPORT_MULTIPLIER, - 0, /* flags: this RA doesn't use flags*/ - uiAlign, - "SVM_Virtual_Alloc", - &uiAllocatedAddr, - &uiAllocatedSize, - NULL /* don't care about per-import priv data */); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "RA_Alloc"); -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - if (eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL) - { - PVRSRV_ERROR eErr; - eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection), - PVRSRV_PROCESS_STAT_TYPE_OOM_VIRTMEM_COUNT, - OSGetCurrentProcessID()); - PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats"); - } -#endif - goto failSVM; - } - - /* No reason for allocated virtual size to be different from - the PMR's size */ - psImport->sCPUImport.pvCPUVAddr = (void*)(uintptr_t)uiAllocatedAddr; - PVR_ASSERT(uiAllocatedSize == psImport->uiSize); - - /* Map the import or allocation using the RA_Alloc virtual address; - the kernel may fail the request if the supplied virtual address - is already in-use in which case we re-try using another virtual - address obtained from the RA_Alloc */ - eError = DevmemImportStructCPUMap(psImport); - if (eError != PVRSRV_OK) - { - /* For now we simply discard failed RA_Alloc() obtained virtual - address (i.e. plenty of virtual space), this prevents us from - re-using these and furthermore essentially blacklists these - addresses from future SVM consideration; We exit fall-back - attempt if retry exceeds the fall-back retry limit */ - if (uiRetry++ > DEVMEM_MAP_SVM_USER_MANAGED_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Cannot find SVM compatible address, bad mapping", - __func__)); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto failSVM; - } - } - else - { - /* Found compatible SVM virtual address, set as device virtual address */ - ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr; - } - } while (eError != PVRSRV_OK); - - *ui64MapAddress = ui64SvmMapAddr; -failSVM: - return eError; -} - -static inline void -DevmemCPUUnmapSVMUserManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport) -{ - RA_BASE_T uiAllocatedAddr; - - /* We only free SVM compatible addresses, all addresses in - the blacklist are essentially excluded from future RA_Alloc */ - uiAllocatedAddr = psImport->sDeviceImport.sDevVAddr.uiAddr; - RA_Free(psHeap->psQuantizedVMRA, uiAllocatedAddr); - - DevmemImportStructCPUUnmap(psImport); -} - -static inline PVRSRV_ERROR -DevmemImportStructDevMapSVM(DEVMEM_HEAP *psHeap, - DEVMEM_IMPORT *psImport, - IMG_UINT uiAlign, - IMG_UINT64 *ui64MapAddress) -{ - PVRSRV_ERROR eError; - - switch (psHeap->ui32HeapManagerFlags) - { - case DEVMEM_HEAP_MANAGER_KERNEL: - eError = DevmemCPUMapSVMKernelManaged(psHeap, - psImport, - ui64MapAddress); - if (eError == PVRSRV_ERROR_BAD_MAPPING) - { - /* If the SVM map address is outside of SVM heap limits, - change heap type to DEVMEM_HEAP_MANAGER_USER */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_USER; - - PVR_DPF((PVR_DBG_WARNING, - "%s: Kernel managed SVM heap is now user managed", - __func__)); - - /* Retry using user managed fall-back approach */ - eError = DevmemCPUMapSVMUserManaged(psHeap, - psImport, - uiAlign, - ui64MapAddress); - } - break; - - case DEVMEM_HEAP_MANAGER_USER: - eError = DevmemCPUMapSVMUserManaged(psHeap, - psImport, - uiAlign, - ui64MapAddress); - break; - - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - - return eError; -} - -static inline void -DevmemImportStructDevUnmapSVM(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport) -{ - switch (psHeap->ui32HeapManagerFlags) - { - case DEVMEM_HEAP_MANAGER_KERNEL: - DevmemCPUUnmapSVMKernelManaged(psHeap, psImport); - break; - - case DEVMEM_HEAP_MANAGER_USER: - DevmemCPUUnmapSVMUserManaged(psHeap, psImport); - break; - - default: - break; - } -} - -/* - The Devmem import structure is the structure we use - to manage memory that is "imported" (which is page - granular) from the server into our process, this - includes allocations. - - This allows memory to be imported without requiring - any CPU or device mapping. Memory can then be mapped - into the device or CPU on demand, but neither is - required. - */ - -IMG_INTERNAL -void DevmemImportStructAcquire(DEVMEM_IMPORT *psImport) -{ - IMG_INT iRefCount = OSAtomicIncrement(&psImport->hRefCount); - PVR_UNREFERENCED_PARAMETER(iRefCount); - PVR_ASSERT(iRefCount != 1); - - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - iRefCount-1, - iRefCount); -} - -IMG_INTERNAL -IMG_BOOL DevmemImportStructRelease(DEVMEM_IMPORT *psImport) -{ - IMG_INT iRefCount = OSAtomicDecrement(&psImport->hRefCount); - PVR_ASSERT(iRefCount >= 0); - - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - iRefCount+1, - iRefCount); - - if (iRefCount == 0) - { - PVRSRV_ERROR eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgePMRUnrefPMR, - psImport->hPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - OSLockDestroy(psImport->sCPUImport.hLock); - OSLockDestroy(psImport->sDeviceImport.hLock); - OSLockDestroy(psImport->hLock); - OSFreeMem(psImport); - - return IMG_TRUE; - } - - return IMG_FALSE; -} - -IMG_INTERNAL -void DevmemImportDiscard(DEVMEM_IMPORT *psImport) -{ - PVR_ASSERT(OSAtomicRead(&psImport->hRefCount) == 0); - OSLockDestroy(psImport->sCPUImport.hLock); - OSLockDestroy(psImport->sDeviceImport.hLock); - OSLockDestroy(psImport->hLock); - OSFreeMem(psImport); -} - -IMG_INTERNAL -PVRSRV_ERROR DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc) -{ - DEVMEM_MEMDESC *psMemDesc; - PVRSRV_ERROR eError; - - /* Must be zeroed in case it needs to be freed before it is initialised */ - psMemDesc = OSAllocZMem(sizeof(DEVMEM_MEMDESC)); - PVR_GOTO_IF_NOMEM(psMemDesc, eError, failAlloc); - - eError = OSLockCreate(&psMemDesc->hLock); - PVR_GOTO_IF_ERROR(eError, failMDLock); - - eError = OSLockCreate(&psMemDesc->sDeviceMemDesc.hLock); - PVR_GOTO_IF_ERROR(eError, failDMDLock); - - eError = OSLockCreate(&psMemDesc->sCPUMemDesc.hLock); - PVR_GOTO_IF_ERROR(eError, failCMDLock); - - OSAtomicWrite(&psMemDesc->hRefCount, 0); - - *ppsMemDesc = psMemDesc; - - return PVRSRV_OK; - -failCMDLock: - OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock); -failDMDLock: - OSLockDestroy(psMemDesc->hLock); -failMDLock: - OSFreeMem(psMemDesc); -failAlloc: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -/* - Init the MemDesc structure - */ -IMG_INTERNAL -void DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - DEVMEM_IMPORT *psImport, - IMG_DEVMEM_SIZE_T uiSize) -{ - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - 0, - 1); - - psMemDesc->psImport = psImport; - psMemDesc->uiOffset = uiOffset; - - psMemDesc->sDeviceMemDesc.ui32RefCount = 0; - psMemDesc->sCPUMemDesc.ui32RefCount = 0; - psMemDesc->uiAllocSize = uiSize; - psMemDesc->hPrivData = NULL; - psMemDesc->ui32AllocationIndex = DEVICEMEM_HISTORY_ALLOC_INDEX_NONE; - -#if defined(DEBUG) - psMemDesc->bPoisonOnFree = IMG_FALSE; -#endif - - OSAtomicWrite(&psMemDesc->hRefCount, 1); -} - -#if defined(DEBUG) -IMG_INTERNAL -void DevmemMemDescSetPoF(DEVMEM_MEMDESC *psMemDesc, PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ - if (PVRSRV_CHECK_POISON_ON_FREE(uiFlags)) - { - psMemDesc->bPoisonOnFree = IMG_TRUE; - } -} -#endif - -IMG_INTERNAL -void DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc) -{ - IMG_INT iRefCount = 0; - - iRefCount = OSAtomicIncrement(&psMemDesc->hRefCount); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - iRefCount-1, - iRefCount); - - PVR_UNREFERENCED_PARAMETER(iRefCount); -} - -#if defined(DEBUG) -static void _DevmemPoisonOnFree(DEVMEM_MEMDESC *psMemDesc) -{ - void *pvAddr = NULL; - IMG_UINT8 *pui8CPUVAddr; - PVRSRV_ERROR eError; - - eError = DevmemCPUMapCheckImportProperties(psMemDesc); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "DevmemCPUMapCheckImportProperties"); - - OSLockAcquire(psMemDesc->sCPUMemDesc.hLock); - eError = DevmemImportStructCPUMap(psMemDesc->psImport); - OSLockRelease(psMemDesc->sCPUMemDesc.hLock); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "DevmemImportStructCPUMap"); - - pui8CPUVAddr = psMemDesc->psImport->sCPUImport.pvCPUVAddr; - pui8CPUVAddr += psMemDesc->uiOffset; - pvAddr = pui8CPUVAddr; - - DevmemCPUMemSet(pvAddr, - PVRSRV_POISON_ON_FREE_VALUE, - psMemDesc->uiAllocSize, - psMemDesc->psImport->uiFlags); - - if (PVRSRV_CHECK_CPU_CACHE_COHERENT(psMemDesc->psImport->uiFlags) || - PVRSRV_CHECK_CPU_CACHE_INCOHERENT(psMemDesc->psImport->uiFlags)) - { - eError = BridgeCacheOpExec(GetBridgeHandle(psMemDesc->psImport->hDevConnection), - psMemDesc->psImport->hPMR, - (IMG_UINT64) (uintptr_t) - pvAddr - psMemDesc->uiOffset, - psMemDesc->uiOffset, - psMemDesc->uiAllocSize, - PVRSRV_CACHE_OP_FLUSH); - PVR_LOG_IF_ERROR(eError, "BridgeCacheOpExec"); - } - - DevmemImportStructCPUUnmap(psMemDesc->psImport); - pvAddr = NULL; -} -#endif - -IMG_INTERNAL -IMG_BOOL DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc) -{ - IMG_INT iRefCount; - PVR_ASSERT(psMemDesc != NULL); - - iRefCount = OSAtomicDecrement(&psMemDesc->hRefCount); - PVR_ASSERT(iRefCount >= 0); - - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psMemDesc, - iRefCount+1, - iRefCount); - - if (iRefCount == 0) - { -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI) && - (psMemDesc->hRIHandle)) - { - PVRSRV_ERROR eError; - - eError = DestroyServerResource(psMemDesc->psImport->hDevConnection, - NULL, - BridgeRIDeleteMEMDESCEntry, - psMemDesc->hRIHandle); - PVR_LOG_IF_ERROR(eError, "BridgeRIDeleteMEMDESCEntry"); - } -#endif - - OSLockAcquire(psMemDesc->psImport->hLock); - if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_SUBALLOCATABLE) - { - /* As soon as the first sub-allocation on the psImport is freed - * we might get dirty memory when reusing it. - * We have to delete the ZEROED, CLEAN & POISONED flag */ - psMemDesc->psImport->uiProperties &= - ~(DEVMEM_PROPERTIES_IMPORT_IS_ZEROED | - DEVMEM_PROPERTIES_IMPORT_IS_CLEAN | - DEVMEM_PROPERTIES_IMPORT_IS_POISONED); - - OSLockRelease(psMemDesc->psImport->hLock); - -#if defined(DEBUG) - if (psMemDesc->bPoisonOnFree) - { - _DevmemPoisonOnFree(psMemDesc); - } -#endif - - RA_Free(psMemDesc->psImport->sDeviceImport.psHeap->psSubAllocRA, - psMemDesc->psImport->sDeviceImport.sDevVAddr.uiAddr + - psMemDesc->uiOffset); - } - else - { - OSLockRelease(psMemDesc->psImport->hLock); - DevmemImportStructRelease(psMemDesc->psImport); - } - - OSLockDestroy(psMemDesc->sCPUMemDesc.hLock); - OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock); - OSLockDestroy(psMemDesc->hLock); - OSFreeMem(psMemDesc); - - return IMG_TRUE; - } - - return IMG_FALSE; -} - -IMG_INTERNAL -void DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc) -{ - PVR_ASSERT(OSAtomicRead(&psMemDesc->hRefCount) == 0); - - OSLockDestroy(psMemDesc->sCPUMemDesc.hLock); - OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock); - OSLockDestroy(psMemDesc->hLock); - OSFreeMem(psMemDesc); -} - - -IMG_INTERNAL -PVRSRV_ERROR DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T *puiFlags) -{ - if ((*puiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) && - (*puiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Zero on Alloc and Poison on Alloc are mutually exclusive.", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (uiAlign & (uiAlign-1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: The requested alignment is not a power of two.", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (uiSize == 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Please request a non-zero size value.", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* If zero or poison flags are set we have to have write access to the page. */ - if (PVRSRV_CHECK_ZERO_ON_ALLOC(*puiFlags) || - PVRSRV_CHECK_POISON_ON_ALLOC(*puiFlags) || -#if defined(DEBUG) - PVRSRV_CHECK_POISON_ON_FREE(*puiFlags) || -#endif - PVRSRV_CHECK_CPU_WRITEABLE(*puiFlags)) - { - (*puiFlags) |= PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE; - } - - return PVRSRV_OK; -} - -/* - Allocate and init an import structure - */ -IMG_INTERNAL -PVRSRV_ERROR DevmemImportStructAlloc(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_IMPORT **ppsImport) -{ - DEVMEM_IMPORT *psImport; - PVRSRV_ERROR eError; - - psImport = OSAllocMem(sizeof(*psImport)); - PVR_RETURN_IF_FALSE(psImport != NULL, PVRSRV_ERROR_OUT_OF_MEMORY); - - /* Setup some known bad values for things we don't have yet */ - psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON; - psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON; - psImport->sDeviceImport.psHeap = NULL; - psImport->sDeviceImport.bMapped = IMG_FALSE; - - eError = OSLockCreate(&psImport->sDeviceImport.hLock); - PVR_GOTO_IF_ERROR(eError, failDIOSLockCreate); - - psImport->sCPUImport.hOSMMapData = NULL; - psImport->sCPUImport.pvCPUVAddr = NULL; - - eError = OSLockCreate(&psImport->sCPUImport.hLock); - PVR_GOTO_IF_ERROR(eError, failCIOSLockCreate); - - /* Set up common elements */ - psImport->hDevConnection = hDevConnection; - - /* Setup properties */ - psImport->uiProperties = 0; - - /* Setup refcounts */ - psImport->sDeviceImport.ui32RefCount = 0; - psImport->sCPUImport.ui32RefCount = 0; - OSAtomicWrite(&psImport->hRefCount, 0); - - /* Create the lock */ - eError = OSLockCreate(&psImport->hLock); - PVR_GOTO_IF_ERROR(eError, failILockAlloc); - - *ppsImport = psImport; - - return PVRSRV_OK; - -failILockAlloc: - OSLockDestroy(psImport->sCPUImport.hLock); -failCIOSLockCreate: - OSLockDestroy(psImport->sDeviceImport.hLock); -failDIOSLockCreate: - OSFreeMem(psImport); - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -/* - Initialise the import structure - */ -IMG_INTERNAL -void DevmemImportStructInit(DEVMEM_IMPORT *psImport, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE hPMR, - DEVMEM_PROPERTIES_T uiProperties) -{ - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - 0, - 1); - - psImport->uiSize = uiSize; - psImport->uiAlign = uiAlign; - psImport->uiFlags = uiFlags; - psImport->hPMR = hPMR; - psImport->uiProperties = uiProperties; - OSAtomicWrite(&psImport->hRefCount, 1); -} - -/* Allocate the requested device virtual address region - * from the heap */ -static PVRSRV_ERROR DevmemReserveVARange(DEVMEM_HEAP *psHeap, - DEVMEM_SIZE_T uiSize, - IMG_UINT uiAlign, - RA_LENGTH_T *puiAllocatedSize, - IMG_UINT64 ui64OptionalMapAddress) -{ - PVRSRV_ERROR eError; - - /* Allocate space in the VM */ - eError = RA_Alloc_Range(psHeap->psQuantizedVMRA, - uiSize, - 0, - uiAlign, - ui64OptionalMapAddress, - puiAllocatedSize); - - if (PVRSRV_OK != eError) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - if ((eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL) || - (eError == PVRSRV_ERROR_RA_REQUEST_VIRT_ADDR_FAIL)) - { - PVRSRV_ERROR eErr; - eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection), - PVRSRV_PROCESS_STAT_TYPE_INVALID_VIRTMEM, - OSGetCurrentProcessID()); - PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats"); - } -#endif - return eError; - } - - /* No reason for the allocated virtual size to be different from - the PMR's size */ - PVR_ASSERT(*puiAllocatedSize == uiSize); - - return PVRSRV_OK; -} - -/* - Map an import to the device - */ -IMG_INTERNAL -PVRSRV_ERROR DevmemImportStructDevMap(DEVMEM_HEAP *psHeap, - IMG_BOOL bMap, - DEVMEM_IMPORT *psImport, - IMG_UINT64 ui64OptionalMapAddress) -{ - DEVMEM_DEVICE_IMPORT *psDeviceImport; - RA_BASE_T uiAllocatedAddr; - RA_LENGTH_T uiAllocatedSize; - IMG_DEV_VIRTADDR sBase; - PVRSRV_ERROR eError; - IMG_UINT uiAlign; - IMG_BOOL bDestroyed = IMG_FALSE; - - /* Round the provided import alignment to the configured heap alignment */ - uiAlign = 1ULL << psHeap->uiLog2ImportAlignment; - uiAlign = (psImport->uiAlign + uiAlign - 1) & ~(uiAlign-1); - - psDeviceImport = &psImport->sDeviceImport; - - OSLockAcquire(psDeviceImport->hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - psDeviceImport->ui32RefCount, - psDeviceImport->ui32RefCount+1); - - if (psDeviceImport->ui32RefCount++ == 0) - { - DevmemImportStructAcquire(psImport); - - OSAtomicIncrement(&psHeap->hImportCount); - - if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags)) - { - /* SVM (shared virtual memory) imports or allocations always - need to acquire CPU virtual address first as address is - used to map the allocation into the device virtual address - space; i.e. the virtual address of the allocation for both - the CPU/GPU must be identical. */ - eError = DevmemImportStructDevMapSVM(psHeap, - psImport, - uiAlign, - &ui64OptionalMapAddress); - PVR_GOTO_IF_ERROR(eError, failVMRAAlloc); - } - - if (ui64OptionalMapAddress == 0) - { - /* If heap is _completely_ managed by USER or KERNEL, we shouldn't - * be here, as this is RA manager code-path */ - if (psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER || - psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_KERNEL) - { - PVR_DPF((PVR_DBG_ERROR, - psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER ? - "%s: Heap is user managed, please use PVRSRVMapToDeviceAddress().": - "%s: Heap is kernel managed, use right allocation flags (e.g. SVM).", - __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc); - } - - if (psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_UNKNOWN) - { - /* Only set the heap manager (to RA) at first map when heap manager - * is unknown. It might be a dual heap (both, user and RA managed), - * in which case heap manager is set at creation time */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_RA; - } - - /* Allocate space in the VM */ - eError = RA_Alloc(psHeap->psQuantizedVMRA, - psImport->uiSize, - RA_NO_IMPORT_MULTIPLIER, - 0, /* flags: this RA doesn't use flags*/ - uiAlign, - "Virtual_Alloc", - &uiAllocatedAddr, - &uiAllocatedSize, - NULL /* don't care about per-import priv data */ - ); - if (PVRSRV_OK != eError) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - if (eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL) - { - PVRSRV_ERROR eErr; - eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection), - PVRSRV_PROCESS_STAT_TYPE_OOM_VIRTMEM_COUNT, - OSGetCurrentProcessID()); - PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats"); - } -#endif - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM, failVMRAAlloc); - } - - /* No reason for the allocated virtual size to be different from - the PMR's size */ - PVR_ASSERT(uiAllocatedSize == psImport->uiSize); - - sBase.uiAddr = uiAllocatedAddr; - - } - else - { - IMG_UINT64 ui64ValidEndAddr; - - /* Ensure supplied ui64OptionalMapAddress is within heap range */ - ui64ValidEndAddr = psHeap->sBaseAddress.uiAddr + psHeap->uiSize; - if ((ui64OptionalMapAddress + psImport->uiSize > ui64ValidEndAddr) || - (ui64OptionalMapAddress < psHeap->sBaseAddress.uiAddr)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ui64OptionalMapAddress %p is outside of heap limits <%p:%p>." - , __func__ - , (void*)(uintptr_t)ui64OptionalMapAddress - , (void*)(uintptr_t)psHeap->sBaseAddress.uiAddr - , (void*)(uintptr_t)ui64ValidEndAddr)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc); - } - - switch (psHeap->ui32HeapManagerFlags) - { - case DEVMEM_HEAP_MANAGER_UNKNOWN: - /* DEVMEM_HEAP_MANAGER_USER can apply to _any_ heap and can only - * be determined here. This heap type transitions from - * DEVMEM_HEAP_MANAGER_UNKNOWN to DEVMEM_HEAP_MANAGER_USER on - * 1st alloc. */ - psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_USER; - break; - - case DEVMEM_HEAP_MANAGER_USER: - case DEVMEM_HEAP_MANAGER_KERNEL: - if (! psHeap->uiSize) - { - PVR_DPF((PVR_DBG_ERROR, - psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER ? - "%s: Heap DEVMEM_HEAP_MANAGER_USER is disabled.": - "%s: Heap DEVMEM_HEAP_MANAGER_KERNEL is disabled." - , __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_HEAP, failVMRAAlloc); - } - break; - - case DEVMEM_HEAP_MANAGER_DUAL_USER_RA: - /* When the heap is dual managed, ensure supplied ui64OptionalMapAddress - * and import size are within heap address space range */ - if (ui64OptionalMapAddress + psImport->uiSize <= - psHeap->sBaseAddress.uiAddr + psHeap->uiReservedRegionSize) - { - break; - } - else - { - /* Allocate requested VM range */ - eError = DevmemReserveVARange(psHeap, - psImport->uiSize, - uiAlign, - &uiAllocatedSize, - ui64OptionalMapAddress); - if (eError != PVRSRV_OK) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED, failVMRAAlloc); - } - - } - break; - case DEVMEM_HEAP_MANAGER_RA: - /* Allocate requested VM range */ - eError = DevmemReserveVARange(psHeap, - psImport->uiSize, - uiAlign, - &uiAllocatedSize, - ui64OptionalMapAddress); - if (eError != PVRSRV_OK) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED, failVMRAAlloc); - } - break; - - default: - break; - } - - if (ui64OptionalMapAddress & ((1 << psHeap->uiLog2Quantum) - 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid address to map to. Please provide an " - "address aligned to a page multiple of the heap." - , __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc); - } - - if (psImport->uiSize & ((1 << psHeap->uiLog2Quantum) - 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid heap to map to. " - "Please choose a heap that can handle smaller page sizes." - , __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc); - } - - uiAllocatedAddr = ui64OptionalMapAddress; - uiAllocatedSize = psImport->uiSize; - sBase.uiAddr = uiAllocatedAddr; - } - - if (psHeap->bPremapped) - { - /* no virtual address reservation and mapping are required for memory that's already mapped */ - psDeviceImport->hReservation = LACK_OF_RESERVATION_POISON; - psDeviceImport->hMapping = LACK_OF_MAPPING_POISON; - } - else - { - PVRSRV_MEMALLOCFLAGS_T uiFlags; - uiFlags = psImport->uiFlags & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK; - - /* Setup page tables for the allocated VM space */ - eError = BridgeDevmemIntReserveRange2(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psHeap->hDevMemServerHeap, - sBase, - uiAllocatedSize, - uiFlags, - &psDeviceImport->hReservation); - if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - eError = BridgeDevmemIntReserveRange(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psHeap->hDevMemServerHeap, - sBase, - uiAllocatedSize, - &psDeviceImport->hReservation); - } - PVR_GOTO_IF_ERROR(eError, failReserve); - - if (bMap) - { - eError = BridgeDevmemIntMapPMR2(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psHeap->hDevMemServerHeap, - psDeviceImport->hReservation, - psImport->hPMR); - if (eError == PVRSRV_OK) - { - psDeviceImport->hMapping = LACK_OF_MAPPING_POISON; - } - else if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - eError = BridgeDevmemIntMapPMR(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psHeap->hDevMemServerHeap, - psDeviceImport->hReservation, - psImport->hPMR, - uiFlags, - &psDeviceImport->hMapping); - } - PVR_GOTO_IF_ERROR(eError, failMap); - - psDeviceImport->bMapped = IMG_TRUE; - } - } - - /* Setup device mapping specific parts of the mapping info */ - psDeviceImport->sDevVAddr.uiAddr = uiAllocatedAddr; - psDeviceImport->psHeap = psHeap; - } - else - { - /* - Check that we've been asked to map it into the - same heap 2nd time around - */ - if (psHeap != psDeviceImport->psHeap) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_HEAP, failParams); - } - } - OSLockRelease(psDeviceImport->hLock); - - return PVRSRV_OK; - -failMap: - if (!psHeap->bPremapped) - { - PVRSRV_ERROR eError2; - - eError2 = BridgeDevmemIntUnreserveRange2(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psDeviceImport->hReservation); - if (eError2 == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - eError2 = BridgeDevmemIntUnreserveRange(GetBridgeHandle(psHeap->psCtx->hDevConnection), - psDeviceImport->hReservation); - } - } -failReserve: - if (ui64OptionalMapAddress == 0) - { - RA_Free(psHeap->psQuantizedVMRA, - uiAllocatedAddr); - } -failVMRAAlloc: - if ((ui64OptionalMapAddress) && PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags)) - { - DevmemImportStructDevUnmapSVM(psHeap, psImport); - } - bDestroyed = DevmemImportStructRelease(psImport); - OSAtomicDecrement(&psHeap->hImportCount); -failParams: - if (!bDestroyed) - { - psDeviceImport->ui32RefCount--; - OSLockRelease(psDeviceImport->hLock); - } - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/* - Unmap an import from the Device - */ -IMG_INTERNAL -IMG_BOOL DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport) -{ - PVRSRV_ERROR eError; - DEVMEM_DEVICE_IMPORT *psDeviceImport; - - psDeviceImport = &psImport->sDeviceImport; - - OSLockAcquire(psDeviceImport->hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - psDeviceImport->ui32RefCount, - psDeviceImport->ui32RefCount-1); - - if (--psDeviceImport->ui32RefCount == 0) - { - DEVMEM_HEAP *psHeap = psDeviceImport->psHeap; - - if (!psHeap->bPremapped) - { - if (psDeviceImport->bMapped) - { - if (psDeviceImport->hMapping == LACK_OF_MAPPING_POISON) - { - eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgeDevmemIntUnmapPMR2, - psDeviceImport->hReservation); - PVR_ASSERT(eError == PVRSRV_OK); - } - else - { - eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgeDevmemIntUnmapPMR, - psDeviceImport->hMapping); - PVR_ASSERT(eError == PVRSRV_OK); - } - } - eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgeDevmemIntUnreserveRange2, - psDeviceImport->hReservation); - if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED) - { - eError = DestroyServerResource(psImport->hDevConnection, - NULL, - BridgeDevmemIntUnreserveRange, - psDeviceImport->hReservation); - } - PVR_ASSERT(eError == PVRSRV_OK); - } - - psDeviceImport->bMapped = IMG_FALSE; - psDeviceImport->hMapping = LACK_OF_MAPPING_POISON; - psDeviceImport->hReservation = LACK_OF_RESERVATION_POISON; - - /* DEVMEM_HEAP_MANAGER_RA can also come from a dual managed heap in which case, - we need to check if the allocated VA falls within RA managed range */ - if ((psHeap->ui32HeapManagerFlags & DEVMEM_HEAP_MANAGER_RA) && - psDeviceImport->sDevVAddr.uiAddr >= (psHeap->sBaseAddress.uiAddr + psHeap->uiReservedRegionSize) && - psDeviceImport->sDevVAddr.uiAddr < (psHeap->sBaseAddress.uiAddr + psHeap->uiSize)) - { - RA_Free(psHeap->psQuantizedVMRA, psDeviceImport->sDevVAddr.uiAddr); - } - - if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags)) - { - DevmemImportStructDevUnmapSVM(psHeap, psImport); - } - - OSLockRelease(psDeviceImport->hLock); - - DevmemImportStructRelease(psImport); - - OSAtomicDecrement(&psHeap->hImportCount); - - return IMG_TRUE; - } - else - { - OSLockRelease(psDeviceImport->hLock); - return IMG_FALSE; - } -} - -/* - Map an import into the CPU - */ -IMG_INTERNAL -PVRSRV_ERROR DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport) -{ - PVRSRV_ERROR eError; - DEVMEM_CPU_IMPORT *psCPUImport; - size_t uiMappingLength; - - psCPUImport = &psImport->sCPUImport; - - OSLockAcquire(psCPUImport->hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - psCPUImport->ui32RefCount, - psCPUImport->ui32RefCount+1); - - if (psCPUImport->ui32RefCount++ == 0) - { - DevmemImportStructAcquire(psImport); - - eError = OSMMapPMR(GetBridgeHandle(psImport->hDevConnection), - psImport->hPMR, - psImport->uiSize, - psImport->uiFlags, - &psCPUImport->hOSMMapData, - &psCPUImport->pvCPUVAddr, - &uiMappingLength); - PVR_GOTO_IF_ERROR(eError, failMap); - - /* MappingLength might be rounded up to page size */ - PVR_ASSERT(uiMappingLength >= psImport->uiSize); - } - OSLockRelease(psCPUImport->hLock); - - return PVRSRV_OK; - -failMap: - psCPUImport->ui32RefCount--; - if (!DevmemImportStructRelease(psImport)) - { - OSLockRelease(psCPUImport->hLock); - } - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/* - Unmap an import from the CPU - */ -IMG_INTERNAL -void DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport) -{ - DEVMEM_CPU_IMPORT *psCPUImport; - - psCPUImport = &psImport->sCPUImport; - - OSLockAcquire(psCPUImport->hLock); - DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d", - __func__, - psImport, - psCPUImport->ui32RefCount, - psCPUImport->ui32RefCount-1); - - if (--psCPUImport->ui32RefCount == 0) - { - /* psImport->uiSize is a 64-bit quantity whereas the 5th - * argument to OSUnmapPMR is a 32-bit quantity on 32-bit systems - * hence a compiler warning of implicit cast and loss of data. - * Added explicit cast and assert to remove warning. - */ -#if defined(__linux__) && defined(__i386__) - PVR_ASSERT(psImport->uiSizehDevConnection), - psImport->hPMR, - psCPUImport->hOSMMapData, - psCPUImport->pvCPUVAddr, - (size_t)psImport->uiSize); - - psCPUImport->hOSMMapData = NULL; - psCPUImport->pvCPUVAddr = NULL; - - OSLockRelease(psCPUImport->hLock); - - DevmemImportStructRelease(psImport); - } - else - { - OSLockRelease(psCPUImport->hLock); - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.h b/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.h deleted file mode 100644 index 3dcef24fa33c2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicemem_utils.h +++ /dev/null @@ -1,605 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management internal utility functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Utility functions used internally by device memory management - code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEM_UTILS_H -#define DEVICEMEM_UTILS_H - -#include "devicemem.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvr_debug.h" -#include "allocmem.h" -#include "ra.h" -#include "osfunc.h" -#include "lock.h" -#include "osmmap.h" -#include "pvrsrv_memallocflags_internal.h" - -#define DEVMEM_HEAPNAME_MAXLENGTH 160 - -/* - * Reserved VA space of a heap must always be multiple of DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY, - * this check is validated in the DDK. Note this is only reserving "Virtual Address" space and - * physical allocations (and mappings thereon) should only be done as much as required (to avoid - * wastage). - * Granularity has been chosen to support the max possible practically used OS page size. - */ -#define DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY 0x10000 /* 64KB is MAX anticipated OS page size */ - -/* - * VA heap size should be at least OS page size. This check is validated in the DDK. - */ -#define DEVMEM_HEAP_MINIMUM_SIZE 0x10000 /* 64KB is MAX anticipated OS page size */ - -#if defined(DEVMEM_DEBUG) && defined(REFCOUNT_DEBUG) -#define DEVMEM_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_ERROR, __FILE__, __LINE__, fmt, __VA_ARGS__) -#else -#define DEVMEM_REFCOUNT_PRINT(fmt, ...) -#endif - -/* If we need a "hMapping" but we don't have a server-side mapping, we poison - * the entry with this value so that it's easily recognised in the debugger. - * Note that this is potentially a valid handle, but then so is NULL, which is - * no better, indeed worse, as it's not obvious in the debugger. The value - * doesn't matter. We _never_ use it (and because it's valid, we never assert - * it isn't this) but it's nice to have a value in the source code that we can - * grep for if things go wrong. - */ -#define LACK_OF_MAPPING_POISON ((IMG_HANDLE)0x6116dead) -#define LACK_OF_RESERVATION_POISON ((IMG_HANDLE)0x7117dead) - -#define DEVICEMEM_HISTORY_ALLOC_INDEX_NONE 0xFFFFFFFF - -struct DEVMEM_CONTEXT_TAG -{ - - SHARED_DEV_CONNECTION hDevConnection; - - /* Number of heaps that have been created in this context - * (regardless of whether they have allocations) - */ - IMG_UINT32 uiNumHeaps; - - /* Each "DEVMEM_CONTEXT" has a counterpart in the server, which - * is responsible for handling the mapping into device MMU. - * We have a handle to that here. - */ - IMG_HANDLE hDevMemServerContext; - - /* Number of automagically created heaps in this context, - * i.e. those that are born at context creation time from the - * chosen "heap config" or "blueprint" - */ - IMG_UINT32 uiAutoHeapCount; - - /* Pointer to array of such heaps */ - struct DEVMEM_HEAP_TAG **ppsAutoHeapArray; - - /* The cache line size for use when allocating memory, - * as it is not queryable on the client side - */ - IMG_UINT32 ui32CPUCacheLineSize; - - /* Private data handle for device specific data */ - IMG_HANDLE hPrivData; -}; - -/* Flags that record how a heaps virtual address space is managed. */ -#define DEVMEM_HEAP_MANAGER_UNKNOWN 0 -/* Heap VAs assigned by the client of Services APIs, heap's RA not used at all. */ -#define DEVMEM_HEAP_MANAGER_USER (1U << 0) -/* Heap VAs managed by the OSs kernel, VA from CPU mapping call used */ -#define DEVMEM_HEAP_MANAGER_KERNEL (1U << 1) -/* Heap VAs managed by the heap's own RA */ -#define DEVMEM_HEAP_MANAGER_RA (1U << 2) -/* Heap VAs managed jointly by Services and the client of Services. - * The reserved region of the heap is managed explicitly by the client of Services - * The non-reserved region of the heap is managed by the heap's own RA */ -#define DEVMEM_HEAP_MANAGER_DUAL_USER_RA (DEVMEM_HEAP_MANAGER_USER | DEVMEM_HEAP_MANAGER_RA) - -struct DEVMEM_HEAP_TAG -{ - /* Name of heap - for debug and lookup purposes. */ - IMG_CHAR *pszName; - - /* Number of live imports in the heap */ - ATOMIC_T hImportCount; - - /* Base address and size of heap, required by clients due to some - * requesters not being full range - */ - IMG_DEV_VIRTADDR sBaseAddress; - DEVMEM_SIZE_T uiSize; - - DEVMEM_SIZE_T uiReservedRegionSize; /* uiReservedRegionLength in DEVMEM_HEAP_BLUEPRINT */ - - /* The heap manager, describing if the space is managed by the user, an RA, - * kernel or combination */ - IMG_UINT32 ui32HeapManagerFlags; - - /* This RA is for managing sub-allocations within the imports (PMRs) - * within the heap's virtual space. RA only used in DevmemSubAllocate() - * to track sub-allocated buffers. - * - * Resource Span - a PMR import added when the RA calls the - * imp_alloc CB (SubAllocImportAlloc) which returns the - * PMR import and size (span length). - * Resource - an allocation/buffer i.e. a MemDesc. Resource size represents - * the size of the sub-allocation. - */ - RA_ARENA *psSubAllocRA; - IMG_CHAR *pszSubAllocRAName; - - /* The psQuantizedVMRA is for the coarse allocation (PMRs) of virtual - * space from the heap. - * - * Resource Span - the heap's VM space from base to base+length, - * only one is added at heap creation. - * Resource - a PMR import associated with the heap. Dynamic number - * as memory is allocated/freed from or mapped/unmapped to - * the heap. Resource size follows PMR logical size. - */ - RA_ARENA *psQuantizedVMRA; - IMG_CHAR *pszQuantizedVMRAName; - - /* We also need to store a copy of the quantum size in order to feed - * this down to the server. - */ - IMG_UINT32 uiLog2Quantum; - - /* Store a copy of the minimum import alignment */ - IMG_UINT32 uiLog2ImportAlignment; - - /* The parent memory context for this heap */ - struct DEVMEM_CONTEXT_TAG *psCtx; - - /* Lock to protect this structure */ - POS_LOCK hLock; - - /* Each "DEVMEM_HEAP" has a counterpart in the server, which is - * responsible for handling the mapping into device MMU. - * We have a handle to that here. - */ - IMG_HANDLE hDevMemServerHeap; - - /* This heap is fully allocated and premapped into the device address space. - * Used in virtualisation for firmware heaps of Guest and optionally Host drivers. */ - IMG_BOOL bPremapped; -}; - -typedef IMG_UINT32 DEVMEM_PROPERTIES_T; /*!< Typedef for Devicemem properties */ -#define DEVMEM_PROPERTIES_EXPORTABLE (1UL<<0) /*!< Is it exportable? */ -#define DEVMEM_PROPERTIES_IMPORTED (1UL<<1) /*!< Is it imported from another process? */ -#define DEVMEM_PROPERTIES_SUBALLOCATABLE (1UL<<2) /*!< Is it suballocatable? */ -#define DEVMEM_PROPERTIES_UNPINNED (1UL<<3) /*!< Is it currently pinned? */ -#define DEVMEM_PROPERTIES_IMPORT_IS_ZEROED (1UL<<4) /*!< Is the memory fully zeroed? */ -#define DEVMEM_PROPERTIES_IMPORT_IS_CLEAN (1UL<<5) /*!< Is the memory clean, i.e. not been used before? */ -#define DEVMEM_PROPERTIES_SECURE (1UL<<6) /*!< Is it a special secure buffer? No CPU maps allowed! */ -#define DEVMEM_PROPERTIES_IMPORT_IS_POISONED (1UL<<7) /*!< Is the memory fully poisoned? */ -#define DEVMEM_PROPERTIES_NO_CPU_MAPPING (1UL<<8) /* No CPU Mapping is allowed, RW attributes - are further derived from allocation memory flags */ -#define DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE (1UL<<9) /* No sparse resizing allowed, once a memory - layout is chosen, no change allowed later, - This includes pinning and unpinning */ - - -typedef struct DEVMEM_DEVICE_IMPORT_TAG -{ - DEVMEM_HEAP *psHeap; /*!< Heap this import is bound to */ - IMG_DEV_VIRTADDR sDevVAddr; /*!< Device virtual address of the import */ - IMG_UINT32 ui32RefCount; /*!< Refcount of the device virtual address */ - IMG_HANDLE hReservation; /*!< Device memory reservation handle */ - IMG_HANDLE hMapping; /*!< Device mapping handle */ - IMG_BOOL bMapped; /*!< This is import mapped? */ - POS_LOCK hLock; /*!< Lock to protect the device import */ -} DEVMEM_DEVICE_IMPORT; - -typedef struct DEVMEM_CPU_IMPORT_TAG -{ - void *pvCPUVAddr; /*!< CPU virtual address of the import */ - IMG_UINT32 ui32RefCount; /*!< Refcount of the CPU virtual address */ - IMG_HANDLE hOSMMapData; /*!< CPU mapping handle */ - POS_LOCK hLock; /*!< Lock to protect the CPU import */ -} DEVMEM_CPU_IMPORT; - -typedef struct DEVMEM_IMPORT_TAG -{ - SHARED_DEV_CONNECTION hDevConnection; - IMG_DEVMEM_ALIGN_T uiAlign; /*!< Alignment of the PMR */ - DEVMEM_SIZE_T uiSize; /*!< Size of import */ - ATOMIC_T hRefCount; /*!< Refcount for this import */ - DEVMEM_PROPERTIES_T uiProperties; /*!< Stores properties of an import like if - it is exportable, pinned or suballocatable */ - IMG_HANDLE hPMR; /*!< Handle to the PMR */ - PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */ - POS_LOCK hLock; /*!< Lock to protect the import */ - - DEVMEM_DEVICE_IMPORT sDeviceImport; /*!< Device specifics of the import */ - DEVMEM_CPU_IMPORT sCPUImport; /*!< CPU specifics of the import */ -} DEVMEM_IMPORT; - -typedef struct DEVMEM_DEVICE_MEMDESC_TAG -{ - IMG_DEV_VIRTADDR sDevVAddr; /*!< Device virtual address of the allocation */ - IMG_UINT32 ui32RefCount; /*!< Refcount of the device virtual address */ - POS_LOCK hLock; /*!< Lock to protect device memdesc */ -} DEVMEM_DEVICE_MEMDESC; - -typedef struct DEVMEM_CPU_MEMDESC_TAG -{ - void *pvCPUVAddr; /*!< CPU virtual address of the import */ - IMG_UINT32 ui32RefCount; /*!< Refcount of the device CPU address */ - POS_LOCK hLock; /*!< Lock to protect CPU memdesc */ -} DEVMEM_CPU_MEMDESC; - -struct DEVMEM_MEMDESC_TAG -{ - DEVMEM_IMPORT *psImport; /*!< Import this memdesc is on */ - IMG_DEVMEM_OFFSET_T uiOffset; /*!< Offset into import where our allocation starts */ - IMG_DEVMEM_SIZE_T uiAllocSize; /*!< Size of the allocation */ - ATOMIC_T hRefCount; /*!< Refcount of the memdesc */ - POS_LOCK hLock; /*!< Lock to protect memdesc */ - IMG_HANDLE hPrivData; - - DEVMEM_DEVICE_MEMDESC sDeviceMemDesc; /*!< Device specifics of the memdesc */ - DEVMEM_CPU_MEMDESC sCPUMemDesc; /*!< CPU specifics of the memdesc */ - - IMG_CHAR szText[DEVMEM_ANNOTATION_MAX_LEN]; /*!< Annotation for this memdesc */ - - IMG_UINT32 ui32AllocationIndex; - -#if defined(DEBUG) - IMG_BOOL bPoisonOnFree; -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - IMG_HANDLE hRIHandle; /*!< Handle to RI information */ -#endif -}; - -/* The physical descriptor used to store handles and information of device - * physical allocations. - */ -struct DEVMEMX_PHYS_MEMDESC_TAG -{ - IMG_UINT32 uiNumPages; /*!< Number of pages that the import has*/ - IMG_UINT32 uiLog2PageSize; /*!< Page size */ - ATOMIC_T hRefCount; /*!< Refcount of the memdesc */ - PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */ - IMG_HANDLE hPMR; /*!< Handle to the PMR */ - DEVMEM_CPU_IMPORT sCPUImport; /*!< CPU specifics of the memdesc */ - DEVMEM_BRIDGE_HANDLE hBridge; /*!< Bridge connection for the server */ - void *pvUserData; /*!< User data */ -}; - -/* The virtual descriptor used to store handles and information of a device - * virtual range and the mappings to it. - */ -struct DEVMEMX_VIRT_MEMDESC_TAG -{ - IMG_UINT32 uiNumPages; /*!< Number of pages that the import has*/ - PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */ - DEVMEMX_PHYSDESC **apsPhysDescTable; /*!< Table to store links to physical descs */ - DEVMEM_DEVICE_IMPORT sDeviceImport; /*!< Device specifics of the memdesc */ - - IMG_CHAR szText[DEVMEM_ANNOTATION_MAX_LEN]; /*!< Annotation for this virt memdesc */ - IMG_UINT32 ui32AllocationIndex; /*!< To track mappings in this range */ - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - IMG_HANDLE hRIHandle; /*!< Handle to RI information */ -#endif -}; - -#define DEVICEMEM_UTILS_NO_ADDRESS 0 - -/****************************************************************************** -@Function DevmemValidateParams -@Description Check if flags are conflicting and if align is a size multiple. - -@Input uiSize Size of the import. -@Input uiAlign Alignment of the import. -@Input puiFlags Pointer to the flags for the import. -@return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T *puiFlags); - -/****************************************************************************** -@Function DevmemImportStructAlloc -@Description Allocates memory for an import struct. Does not allocate a PMR! - Create locks for CPU and Devmem mappings. - -@Input hDevConnection Connection to use for calls from the import. -@Input ppsImport The import to allocate. -@return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR DevmemImportStructAlloc(SHARED_DEV_CONNECTION hDevConnection, - DEVMEM_IMPORT **ppsImport); - -/****************************************************************************** -@Function DevmemImportStructInit -@Description Initialises the import struct with the given parameters. - Set it's refcount to 1! - -@Input psImport The import to initialise. -@Input uiSize Size of the import. -@Input uiAlign Alignment of allocations in the import. -@Input uiMapFlags -@Input hPMR Reference to the PMR of this import struct. -@Input uiProperties Properties of the import. Is it exportable, - imported, suballocatable, unpinned? -******************************************************************************/ -void DevmemImportStructInit(DEVMEM_IMPORT *psImport, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - IMG_HANDLE hPMR, - DEVMEM_PROPERTIES_T uiProperties); - -/****************************************************************************** -@Function DevmemImportStructDevMap -@Description NEVER call after the last DevmemMemDescRelease() - Maps the PMR referenced by the import struct to the device's - virtual address space. - Does nothing but increase the cpu mapping refcount if the - import struct was already mapped. - -@Input psHeap The heap to map to. -@Input bMap Caller can choose if the import should be really - mapped in the page tables or if just a virtual range - should be reserved and the refcounts increased. -@Input psImport The import we want to map. -@Input uiOptionalMapAddress An optional address to map to. - Pass DEVICEMEM_UTILS_NOADDRESS if not used. -@return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR DevmemImportStructDevMap(DEVMEM_HEAP *psHeap, - IMG_BOOL bMap, - DEVMEM_IMPORT *psImport, - IMG_UINT64 uiOptionalMapAddress); - -/****************************************************************************** -@Function DevmemImportStructDevUnmap -@Description Unmaps the PMR referenced by the import struct from the - device's virtual address space. - If this was not the last remaining CPU mapping on the import - struct only the cpu mapping refcount is decreased. -@return A boolean to signify if the import was unmapped. -******************************************************************************/ -IMG_BOOL DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport); - -/****************************************************************************** -@Function DevmemImportStructCPUMap -@Description NEVER call after the last DevmemMemDescRelease() - Maps the PMR referenced by the import struct to the CPU's - virtual address space. - Does nothing but increase the cpu mapping refcount if the - import struct was already mapped. -@return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport); - -/****************************************************************************** -@Function DevmemImportStructCPUUnmap -@Description Unmaps the PMR referenced by the import struct from the CPU's - virtual address space. - If this was not the last remaining CPU mapping on the import - struct only the cpu mapping refcount is decreased. -******************************************************************************/ -void DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport); - - -/****************************************************************************** -@Function DevmemImportStructAcquire -@Description Acquire an import struct by increasing it's refcount. -******************************************************************************/ -void DevmemImportStructAcquire(DEVMEM_IMPORT *psImport); - -/****************************************************************************** -@Function DevmemImportStructRelease -@Description Reduces the refcount of the import struct. - Destroys the import in the case it was the last reference. - Destroys underlying PMR if this import was the last reference - to it. -@return A boolean to signal if the import was destroyed. True = yes. -******************************************************************************/ -IMG_BOOL DevmemImportStructRelease(DEVMEM_IMPORT *psImport); - -/****************************************************************************** -@Function DevmemImportDiscard -@Description Discard a created, but uninitialised import structure. - This must only be called before DevmemImportStructInit - after which DevmemImportStructRelease must be used to - "free" the import structure. -******************************************************************************/ -void DevmemImportDiscard(DEVMEM_IMPORT *psImport); - -/****************************************************************************** -@Function DevmemMemDescAlloc -@Description Allocates a MemDesc and create it's various locks. - Zero the allocated memory. -@return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc); - -#if defined(DEBUG) -/****************************************************************************** -@Function DevmemMemDescSetPoF -@Description Sets the Poison on Free flag to true for this MemDesc if the - given MemAllocFlags have the Poison on Free bit set. - Poison on Free is a debug only feature. -******************************************************************************/ -void DevmemMemDescSetPoF(DEVMEM_MEMDESC *psMemDesc, PVRSRV_MEMALLOCFLAGS_T uiFlags); -#endif - -/****************************************************************************** -@Function DevmemMemDescInit -@Description Sets the given offset and import struct fields in the MemDesc. - Initialises refcount to 1 and other values to 0. - -@Input psMemDesc MemDesc to initialise. -@Input uiOffset Offset in the import structure. -@Input psImport Import the MemDesc is on. -@Input uiAllocSize Size of the allocation -******************************************************************************/ -void DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc, - IMG_DEVMEM_OFFSET_T uiOffset, - DEVMEM_IMPORT *psImport, - IMG_DEVMEM_SIZE_T uiAllocSize); - -/****************************************************************************** -@Function DevmemMemDescAcquire -@Description Acquires the MemDesc by increasing it's refcount. -******************************************************************************/ -void DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc); - -/****************************************************************************** -@Function DevmemMemDescRelease -@Description Releases the MemDesc by reducing it's refcount. - Destroy the MemDesc if it's recount is 0. - Destroy the import struct the MemDesc is on if that was the - last MemDesc on the import, probably following the destruction - of the underlying PMR. -@return A boolean to signal if the MemDesc was destroyed. True = yes. -******************************************************************************/ -IMG_BOOL DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc); - -/****************************************************************************** -@Function DevmemMemDescDiscard -@Description Discard a created, but uninitialised MemDesc structure. - This must only be called before DevmemMemDescInit after - which DevmemMemDescRelease must be used to "free" the - MemDesc structure. -******************************************************************************/ -void DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc); - - -/****************************************************************************** -@Function GetImportProperties -@Description Atomically read psImport->uiProperties - It's possible that another thread modifies uiProperties - immediately after this function returns, making its result - stale. So, it's recommended to use this function only to - check if certain non-volatile flags were set. -******************************************************************************/ -static INLINE DEVMEM_PROPERTIES_T GetImportProperties(DEVMEM_IMPORT *psImport) -{ - DEVMEM_PROPERTIES_T uiProperties; - - OSLockAcquire(psImport->hLock); - uiProperties = psImport->uiProperties; - OSLockRelease(psImport->hLock); - return uiProperties; -} - -/****************************************************************************** -@Function DevmemCPUMemSet -@Description Given a CPU Mapped Devmem address, set the memory at that - range (address, address + size) to the uiPattern provided. - Flags determine the OS abstracted MemSet method to use. -******************************************************************************/ -static INLINE void DevmemCPUMemSet(void *pvMem, - IMG_UINT8 uiPattern, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ - if (PVRSRV_CHECK_CPU_UNCACHED(uiFlags)) - { - OSDeviceMemSet(pvMem, uiPattern, uiSize); - } - else - { - /* it's safe to use OSCachedMemSet() for cached and wc memory */ - OSCachedMemSet(pvMem, uiPattern, uiSize); - } -} - -/****************************************************************************** -@Function DevmemCPUMapCheckImportProperties -@Description Given a MemDesc check that the import properties are correct - to allow for mapping the MemDesc to the CPU. - Returns PVRSRV_OK on success. -******************************************************************************/ -static INLINE PVRSRV_ERROR DevmemCPUMapCheckImportProperties(DEVMEM_MEMDESC *psMemDesc) -{ - DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psMemDesc->psImport); - - if (uiProperties & - (DEVMEM_PROPERTIES_UNPINNED | DEVMEM_PROPERTIES_SECURE)) - { -#if defined(SUPPORT_SECURITY_VALIDATION) - if (uiProperties & DEVMEM_PROPERTIES_SECURE) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Allocation is a secure buffer. " - "It should not be possible to map to CPU, but for security " - "validation this will be allowed for testing purposes, " - "as long as the buffer is pinned.", - __func__)); - } - - if (uiProperties & DEVMEM_PROPERTIES_UNPINNED) -#endif - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Allocation is currently unpinned or a secure buffer. " - "Not possible to map to CPU!", - __func__)); - return PVRSRV_ERROR_INVALID_MAP_REQUEST; - } - } - - if (uiProperties & DEVMEM_PROPERTIES_NO_CPU_MAPPING) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: CPU Mapping is not possible on this allocation!", - __func__)); - return PVRSRV_ERROR_INVALID_MAP_REQUEST; - } - - return PVRSRV_OK; -} - -#endif /* DEVICEMEM_UTILS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicememx.h b/drivers/gpu/drm/img-rogue/1.17/devicememx.h deleted file mode 100644 index 769d2dc4e6df2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicememx.h +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title X Device Memory Management core internal -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Internal interface for extended device memory management. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEMX_H -#define DEVICEMEMX_H - -#include "img_types.h" -#include "devicemem_typedefs.h" -#include "devicemem_utils.h" -#include "pdumpdefs.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "osfunc.h" - -/* DevmemXAllocPhysical() - * - * Allocate physical device memory and return a physical - * descriptor for it. - */ -PVRSRV_ERROR -DevmemXAllocPhysical(DEVMEM_CONTEXT *psCtx, - IMG_UINT32 uiNumPages, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEMX_PHYSDESC **ppsPhysDesc); - -/* DevmemXReleasePhysical() - * - * Removes a physical device allocation if all references - * to it are dropped, otherwise just decreases the refcount. - */ -void -DevmemXReleasePhysical(DEVMEMX_PHYSDESC *psPhysDesc); - -/* DevmemAllocVirtualAddr() - * - * Reserve a requested device virtual range and return - * a virtual descriptor for it. - */ -IMG_INTERNAL PVRSRV_ERROR -DevmemXAllocVirtualAddr(DEVMEM_HEAP* hHeap, - IMG_UINT32 uiNumPages, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - IMG_DEV_VIRTADDR sVirtAddr, - DEVMEMX_VIRTDESC **ppsVirtDesc); - -/* DevmemAllocVirtual() - * - * Allocate and reserve a device virtual range and return - * a virtual descriptor for it. - */ -PVRSRV_ERROR -DevmemXAllocVirtual(DEVMEM_HEAP* hHeap, - IMG_UINT32 uiNumPages, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEMX_VIRTDESC **ppsVirtDesc, - IMG_DEV_VIRTADDR *psVirtAddr); - -/* DevmemXFreeVirtual() - * - * Removes a device virtual range if all mappings on it - * have been removed. - */ -PVRSRV_ERROR -DevmemXFreeVirtual(DEVMEMX_VIRTDESC *psVirtDesc); - -/* DevmemXMapVirtualRange() - * - * Map memory from a physical descriptor into a virtual range. - */ -PVRSRV_ERROR -DevmemXMapVirtualRange(IMG_UINT32 ui32PageCount, - DEVMEMX_PHYSDESC *psPhysDesc, - IMG_UINT32 ui32PhysOffset, - DEVMEMX_VIRTDESC *psVirtDesc, - IMG_UINT32 ui32VirtOffset); - -/* DevmemXUnmapVirtualRange() - * - * Unmap pages from a device virtual range. - */ -PVRSRV_ERROR -DevmemXUnmapVirtualRange(IMG_UINT32 ui32PageCount, - DEVMEMX_VIRTDESC *psVirtDesc, - IMG_UINT32 ui32VirtPgOffset); - -/* DevmemXMapPhysicalToCPU() - * - * Map a full physical descriptor to CPU space. - */ -PVRSRV_ERROR -DevmemXMapPhysicalToCPU(DEVMEMX_PHYSDESC *psMemAllocPhys, - IMG_CPU_VIRTADDR *psVirtAddr); - -/* DevmemXUnmapPhysicalToCPU() - * - * Remove the CPU mapping from the descriptor. - */ -PVRSRV_ERROR -DevmemXUnmapPhysicalToCPU(DEVMEMX_PHYSDESC *psMemAllocPhys); - -/* DevmemXReacquireCpuVirtAddr() - * - * Reacquire the CPU mapping by incrementing the refcount. - */ -void -DevmemXReacquireCpuVirtAddr(DEVMEMX_PHYSDESC *psPhysDesc, - void **ppvCpuVirtAddr); - -/* DevmemXReleaseCpuVirtAddr() - * - * Release CPU mapping by decrementing the refcount. - */ -void -DevmemXReleaseCpuVirtAddr(DEVMEMX_PHYSDESC *psPhysDesc); - -/* DevmemXCreateDevmemMemDescVA() - * - * (Deprecated) - * - * Create a devmem memdesc from a virtual address. - * Always destroy with DevmemXFreeDevmemMemDesc(). - */ - -PVRSRV_ERROR -DevmemXCreateDevmemMemDescVA(const IMG_DEV_VIRTADDR sVirtualAddress, - DEVMEM_MEMDESC **ppsMemDesc); - -/* DevmemXCreateDevmemMemDesc() - * - * Create a devmem memdesc from a physical and - * virtual descriptor. - * Always destroy with DevmemXFreeDevmemMemDesc(). - */ - -PVRSRV_ERROR -DevmemXCreateDevmemMemDesc(DEVMEMX_PHYSDESC *psPhysDesc, - DEVMEMX_VIRTDESC *psVirtDesc, - DEVMEM_MEMDESC **ppsMemDesc); - -/* DevmemXFreeDevmemMemDesc() - * - * Free the memdesc again. Has no impact on the underlying - * physical and virtual descriptors. - */ -PVRSRV_ERROR -DevmemXFreeDevmemMemDesc(DEVMEM_MEMDESC *psMemDesc); - -PVRSRV_ERROR -DevmemXFlagCompatibilityCheck(PVRSRV_MEMALLOCFLAGS_T uiPhysFlags, - PVRSRV_MEMALLOCFLAGS_T uiVirtFlags); - -PVRSRV_ERROR -DevmemXPhysDescAlloc(DEVMEMX_PHYSDESC **ppsPhysDesc); - -void -DevmemXPhysDescInit(DEVMEMX_PHYSDESC *psPhysDesc, - IMG_HANDLE hPMR, - IMG_UINT32 uiNumPages, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE hBridge); - -void -DevmemXPhysDescFree(DEVMEMX_PHYSDESC *psPhysDesc); - -void -DevmemXPhysDescAcquire(DEVMEMX_PHYSDESC *psPhysDesc, - IMG_UINT32 uiAcquireCount); -void -DevmemXPhysDescRelease(DEVMEMX_PHYSDESC *psPhysDesc, - IMG_UINT32 uiReleaseCount); - -#if !defined(__KERNEL__) -IMG_INTERNAL PVRSRV_ERROR -DevmemXGetImportUID(DEVMEMX_PHYSDESC *psMemDescPhys, - IMG_UINT64 *pui64UID); -#endif - -#endif /* DEVICEMEMX_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.c b/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.c deleted file mode 100644 index 9950d4d817d19..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Shared X device memory management PDump functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements common (client & server) PDump functions for the - memory management code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - - -#if defined(PDUMP) - -#include "devicememx_pdump.h" -#include "pdump.h" -#include "client_pdumpmm_bridge.h" -#include "devicemem_utils.h" - -IMG_INTERNAL void -DevmemXPDumpLoadMem(DEVMEMX_PHYSDESC *psMemDescPhys, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(uiSize != 0); - PVR_ASSERT(uiOffset + uiSize <= (psMemDescPhys->uiNumPages << - psMemDescPhys->uiLog2PageSize)); - - eError = BridgePMRPDumpLoadMem(psMemDescPhys->hBridge, - psMemDescPhys->hPMR, - uiOffset, - uiSize, - uiPDumpFlags, - IMG_FALSE); - PVR_LOG_IF_ERROR(eError, "BridgePMRPDumpLoadMem"); -} - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.h b/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.h deleted file mode 100644 index b6e99f7eca663..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/devicememx_pdump.h +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title X Device Memory Management PDump internal -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services internal interface to PDump device memory management - functions that are shared between client and server code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DEVICEMEMX_PDUMP_H -#define DEVICEMEMX_PDUMP_H - -#include "devicememx.h" -#include "pdumpdefs.h" -#include "pdump.h" - -#if defined(PDUMP) -/* - * DevmemXPDumpLoadMem() - * - * Same as DevmemPDumpLoadMem(). - */ -IMG_INTERNAL void -DevmemXPDumpLoadMem(DEVMEMX_PHYSDESC *psMemDescPhys, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags); -#else - -#ifdef INLINE_IS_PRAGMA -#pragma inline(DevmemXPDumpLoadMem) -#endif - -static INLINE void -DevmemXPDumpLoadMem(DEVMEMX_PHYSDESC *psMemDescPhys, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMemDescPhys); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); -} -#endif /* PDUMP */ -#endif /* DEVICEMEMX_PDUMP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/di_common.h b/drivers/gpu/drm/img-rogue/1.17/di_common.h deleted file mode 100644 index a10178708a754..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_common.h +++ /dev/null @@ -1,236 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common types for Debug Info framework. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DI_COMMON_H -#define DI_COMMON_H - -#include "img_types.h" - -/* Token that signals that a header should be printed. */ -#define DI_START_TOKEN ((void *) 1) - -/* This is a public handle to an entry. */ -#ifndef DI_GROUP_DEFINED -#define DI_GROUP_DEFINED -typedef struct DI_GROUP DI_GROUP; -#endif -#ifndef DI_ENTRY_DEFINED -#define DI_ENTRY_DEFINED -typedef struct DI_ENTRY DI_ENTRY; -#endif -typedef struct OSDI_IMPL_ENTRY OSDI_IMPL_ENTRY; - -/*! Debug Info entries types. */ -typedef enum DI_ENTRY_TYPE -{ - DI_ENTRY_TYPE_GENERIC, /*!< generic entry type, implements - start/stop/next/show iterator - interface */ - DI_ENTRY_TYPE_RANDOM_ACCESS, /*!< random access entry, implements - seek/read iterator interface */ -} DI_ENTRY_TYPE; - -/*! @Function DI_PFN_START - * - * @Description - * Start operation returns first entry and passes it to Show operation. - * - * @Input psEntry pointer to the implementation entry - * @InOut pui64Pos current data position in the entry - * - * @Return pointer to data that will be passed to the other iterator - * functions in pvData argument - */ -typedef void *(*DI_PFN_START)(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos); - -/*! @Function DI_PFN_STOP - * - * @Description - * Stop operations is called after iterator reaches end of data. - * - * If pvData was allocated in pfnStart it should be freed here. - * - * @Input psEntry pointer to the implementation entry - * @Input pvData pointer to data returned from pfnStart/pfnNext - */ -typedef void (*DI_PFN_STOP)(OSDI_IMPL_ENTRY *psEntry, void *pvData); - -/*! @Function DI_PFN_NEXT - * - * @Description - * Next returns next data entry and passes it to Show operation. - * - * @Input psEntry pointer to the implementation entry - * @Input pvData pointer to data returned from pfnStart/pfnNext - * @InOut pui64Pos current data position in the entry - */ -typedef void *(*DI_PFN_NEXT)(OSDI_IMPL_ENTRY *psEntry, void *pvData, - IMG_UINT64 *pui64Pos); - -/*! @Function DI_PFN_SHOW - * - * @Description - * Outputs the data element. - * - * @Input psEntry pointer to the implementation entry - * @Input pvData pointer to data returned from pfnStart/pfnNext - */ -typedef int (*DI_PFN_SHOW)(OSDI_IMPL_ENTRY *psEntry, void *pvData); - -/*! @Function DI_PFN_SEEK - * - * @Description - * Changes position of the entry data pointer - * - * @Input uiOffset new entry offset (absolute) - * @Input pvData private data provided during entry creation - */ -typedef IMG_INT64 (*DI_PFN_SEEK)(IMG_UINT64 ui64Offset, void *pvData); - -/*! @Function DI_PFN_READ - * - * @Description - * Retrieves data from the entry from position previously set by Seek. - * - * @Input pszBuffer output buffer - * @Input ui64Count length of the output buffer - * @InOut pui64Pos pointer to the current position in the entry - * @Input pvData private data provided during entry creation - */ -typedef IMG_INT64 (*DI_PFN_READ)(IMG_CHAR *pszBuffer, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData); - -/*! @Function DI_PFN_WRITE - * - * @Description - * Handle writes operation to the entry. - * - * @Input pszBuffer NUL-terminated buffer containing written data - * @Input ui64Count length of the data in pszBuffer (length of the buffer) - * @InOut pui64Pos pointer to the current position in the entry - * @Input pvData private data provided during entry creation - */ -typedef IMG_INT64 (*DI_PFN_WRITE)(const IMG_CHAR *pszBuffer, - IMG_UINT64 ui64Count, IMG_UINT64 *pui64Pos, - void *pvData); - -/*! Debug info entry iterator. - * - * This covers all entry types: GENERIC and RANDOM_ACCESS. - * - * The GENERIC entry type - * - * The GENERIC type should implement either a full set of following callbacks: - * pfnStart, pfnStop, pfnNext and pfnShow, or pfnShow only. If only pfnShow - * callback is given the framework will use default handlers in place of the - * other ones. - * - * e.g. for generic entry: - * - * struct sIter = { - * .pfnStart = StartCb, .pfnStop = StopCb, pfnNext = NextCb, - * .pfnShow = ShowCb - * }; - * - * The use case for implementing pfnShow only is if the data for the given - * entry is short and can be printed in one go because the pfnShow callback - * will be called only once. - * - * e.g. for one-shot print generic entry: - * - * struct sIter = { - * .pfnShow = SingleShowCb - * }; - * - * The DICreateEntry() function will return error if DI_ENTRY_TYPE_GENERIC - * type is used and invalid combination of callbacks is given. - * - * The RANDOM_ACCESS entry - * - * The RANDOM_ACCESS type should implement either both pfnSeek and pfnRead - * or pfnRead only callbacks. - * - * e.g. of seekable and readable random access entry: - * - * struct sIter = { - * .pfnSeek = SeekCb, .pfnRead = ReadCb - * }; - * - * The DICreateEntry() function will return error if DI_ENTRY_TYPE_RANDOM_ACCESS - * type is used and invalid combination of callbacks is given. - * - * Writing to file (optional) - * - * The iterator allows also to pass a pfnWrite callback that allows implementing - * write operation on the entry. The write operation is entry type agnostic - * which means that it can be defined for both GENERIC and RANDOM_ACCESS - * entries. - * - * e.g. for writable one-shot print generic entry - * - * struct sIter = { - * .pfnShow = SingleShowCb, .pfnWrite = WriteCb - * }; - */ -typedef struct DI_ITERATOR_CB -{ - /* Generic entry interface. */ - - DI_PFN_START pfnStart; /*!< Starts iteration and returns first element - of entry's data. */ - DI_PFN_STOP pfnStop; /*!< Stops iteration. */ - DI_PFN_NEXT pfnNext; /*!< Returns next element of entry's data. */ - DI_PFN_SHOW pfnShow; /*!< Shows current data element of an entry. */ - - /* Optional random access entry interface. */ - - DI_PFN_SEEK pfnSeek; /*!< Sets data pointer in an entry. */ - DI_PFN_READ pfnRead; /*!< Reads data from an entry. */ - - /* Optional writing to entry interface. Null terminated. */ - - DI_PFN_WRITE pfnWrite; /*!< Performs write operation on an entry. */ - IMG_UINT32 ui32WriteLenMax; /*!< Maximum char length of entry - accepted for write. Includes \0 */ -} DI_ITERATOR_CB; - -#endif /* DI_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.c b/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.c deleted file mode 100644 index b6503b949c632..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.c +++ /dev/null @@ -1,894 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS agnostic implementation of Debug Info interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements osdi_impl.h API to provide access to driver's - debug data via pvrdebug. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "allocmem.h" -#include "hash.h" -#include "img_defs.h" -#include "img_types.h" -#include "lock.h" -#include "osfunc_common.h" -#include "osfunc.h" /* for thread */ -#include "tlstream.h" -#include "dllist.h" - -#include "osdi_impl.h" -#include "di_impl_brg.h" -#include "di_impl_brg_intern.h" -#include "pvr_dicommon.h" -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) -#include "pvrsrv.h" -#endif - -#define ENTRIES_TABLE_INIT_SIZE 64 -#define STREAM_BUFFER_SIZE 0x4000 /* 16KB */ -#define STREAM_LINE_LENGTH 512 - -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) -#define WRITER_THREAD_SLEEP_TIMEOUT 0ull -#else -#define WRITER_THREAD_SLEEP_TIMEOUT 28800000000ull -#endif -#define WRITER_THREAD_DESTROY_TIMEOUT 100000ull -#define WRITER_THREAD_DESTROY_RETRIES 10u - -#define WRITE_RETRY_COUNT 10 /* retry a write to a TL buffer 10 times */ -#define WRITE_RETRY_WAIT_TIME 100 /* wait 10ms between write retries */ - -typedef enum THREAD_STATE -{ - THREAD_STATE_NULL, - THREAD_STATE_ALIVE, - THREAD_STATE_TERMINATED, -} THREAD_STATE; - -static struct DIIB_IMPL -{ - HASH_TABLE *psEntriesTable; /*!< Table of entries. */ - POS_LOCK psEntriesLock; /*!< Protects psEntriesTable. */ - IMG_HANDLE hWriterThread; - IMG_HANDLE hWriterEventObject; - ATOMIC_T eThreadState; - - DLLIST_NODE sWriterQueue; - POS_LOCK psWriterLock; /*!< Protects sWriterQueue. */ -} *_g_psImpl; - -struct DIIB_GROUP -{ - const IMG_CHAR *pszName; - struct DIIB_GROUP *psParentGroup; -}; - -struct DIIB_ENTRY -{ - struct DIIB_GROUP *psParentGroup; - OSDI_IMPL_ENTRY sImplEntry; - DI_ITERATOR_CB sIterCb; - DI_ENTRY_TYPE eType; - IMG_CHAR pszFullPath[DI_IMPL_BRG_PATH_LEN]; - void *pvPrivData; - - POS_LOCK hLock; /*!< Protects access to entry's iterator. */ -}; - -struct DI_CONTEXT_TAG -{ - IMG_HANDLE hStream; - ATOMIC_T iRefCnt; - IMG_BOOL bClientConnected; /*!< Indicated that the client is or is not - connected to the DI. */ -}; - -struct DIIB_WORK_ITEM -{ - DI_CONTEXT *psContext; - DIIB_ENTRY *psEntry; - IMG_UINT64 ui64Size; - IMG_UINT64 ui64Offset; - - DLLIST_NODE sQueueElement; -}; - -/* Declaring function here to avoid dependencies that are introduced by - * including osfunc.h. */ -IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2, - size_t uiSize); - -/* djb2 hash function is public domain */ -static IMG_UINT32 _Hash(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen) -{ - IMG_CHAR *pszStr = pKey; - IMG_UINT32 ui32Hash = 5381, ui32Char; - - PVR_UNREFERENCED_PARAMETER(uKeySize); - PVR_UNREFERENCED_PARAMETER(uHashTabLen); - - while ((ui32Char = *pszStr++) != '\0') - { - ui32Hash = ((ui32Hash << 5) + ui32Hash) + ui32Char; /* hash * 33 + c */ - } - - return ui32Hash; -} - -static IMG_BOOL _Compare(size_t uKeySize, void *pKey1, void *pKey2) -{ - IMG_CHAR *pszKey1 = pKey1, *pszKey2 = pKey2; - - return OSStringNCompare(pszKey1, pszKey2, uKeySize) == 0; -} - -/* ----- native callbacks interface ----------------------------------------- */ - -static void _WriteWithRetires(void *pvNativeHandle, const IMG_CHAR *pszStr, - IMG_UINT uiLen) -{ - PVRSRV_ERROR eError; - IMG_INT iRetry = 0; - IMG_UINT32 ui32Flags = TL_FLAG_NO_WRITE_FAILED; - - do - { - /* Try to write to the buffer but don't inject MOST_RECENT_WRITE_FAILED - * packet in case of failure because we're going to retry. */ - eError = TLStreamWriteRetFlags(pvNativeHandle, (IMG_UINT8 *) pszStr, - uiLen, &ui32Flags); - if (eError == PVRSRV_ERROR_STREAM_FULL) - { - // wait to give the client a change to read - OSSleepms(WRITE_RETRY_WAIT_TIME); - } - } - while (eError == PVRSRV_ERROR_STREAM_FULL && iRetry++ < WRITE_RETRY_COUNT); - - /* One last try to write to the buffer. In this case upon failure - * a MOST_RECENT_WRITE_FAILED packet will be inject to the buffer to - * indicate data loss. */ - if (eError == PVRSRV_ERROR_STREAM_FULL) - { - eError = TLStreamWrite(pvNativeHandle, (IMG_UINT8 *) pszStr, uiLen); - } - - PVR_LOG_IF_ERROR(eError, "TLStreamWrite"); -} - -static void _WriteData(void *pvNativeHandle, const void *pvData, - IMG_UINT32 uiSize) -{ - _WriteWithRetires(pvNativeHandle, pvData, uiSize); -} - -__printf(2, 0) -static void _VPrintf(void *pvNativeHandle, const IMG_CHAR *pszFmt, - va_list pArgs) -{ - IMG_CHAR pcBuffer[STREAM_LINE_LENGTH]; - IMG_UINT uiLen = OSVSNPrintf(pcBuffer, sizeof(pcBuffer) - 1, pszFmt, pArgs); - pcBuffer[uiLen] = '\0'; - - _WriteWithRetires(pvNativeHandle, pcBuffer, uiLen + 1); -} - -static void _Puts(void *pvNativeHandle, const IMG_CHAR *pszStr) -{ - _WriteWithRetires(pvNativeHandle, pszStr, OSStringLength(pszStr) + 1); -} - -static IMG_BOOL _HasOverflowed(void *pvNativeHandle) -{ - PVR_UNREFERENCED_PARAMETER(pvNativeHandle); - return IMG_FALSE; -} - -static OSDI_IMPL_ENTRY_CB _g_sEntryCallbacks = { - .pfnWrite = _WriteData, - .pfnVPrintf = _VPrintf, - .pfnPuts = _Puts, - .pfnHasOverflowed = _HasOverflowed, -}; - -/* ----- entry operations --------------------------------------------------- */ - -static PVRSRV_ERROR _ContextUnrefAndMaybeDestroy(DI_CONTEXT *psContext) -{ - if (OSAtomicDecrement(&psContext->iRefCnt) == 0) - { - TLStreamClose(psContext->hStream); - OSFreeMem(psContext); - } - - return PVRSRV_OK; -} - -static IMG_INT64 _ReadGeneric(const DI_CONTEXT *psContext, DIIB_ENTRY *psEntry) -{ - IMG_INT64 iRet = 0; - IMG_UINT64 ui64Pos = 0; - DI_ITERATOR_CB *psIter = &psEntry->sIterCb; - OSDI_IMPL_ENTRY *psImplEntry = &psEntry->sImplEntry; - PVRSRV_ERROR eError; - - if (psIter->pfnStart != NULL) - { - /* this is a full sequence of the operation */ - void *pvData = psIter->pfnStart(psImplEntry, &ui64Pos); - - while (pvData != NULL && psContext->bClientConnected) - { - iRet = psIter->pfnShow(psImplEntry, pvData); - if (iRet < 0) - { - break; - } - - pvData = psIter->pfnNext(psImplEntry, pvData, &ui64Pos); - } - - psIter->pfnStop(psImplEntry, pvData); - } - else if (psIter->pfnShow != NULL) - { - /* this is a simplified sequence of the operation */ - iRet = psIter->pfnShow(psImplEntry, NULL); - } - - eError = TLStreamMarkEOS(psImplEntry->pvNative, IMG_FALSE); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamMarkEOS", return_error_); - - return iRet; - -return_error_: - return -1; -} - -static IMG_INT64 _ReadRndAccess(DIIB_ENTRY *psEntry, IMG_UINT64 ui64Count, - IMG_UINT64 *pui64Pos, void *pvData) -{ - PVRSRV_ERROR eError; - IMG_UINT8 *pui8Buffer; - IMG_HANDLE hStream = psEntry->sImplEntry.pvNative; - - if (psEntry->sIterCb.pfnRead == NULL) - { - return -1; - } - - eError = TLStreamReserve(hStream, &pui8Buffer, ui64Count); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamReserve", return_error_); - - psEntry->sIterCb.pfnRead((IMG_CHAR *) pui8Buffer, ui64Count, pui64Pos, - pvData); - - eError = TLStreamCommit(hStream, ui64Count); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCommit", return_error_); - - eError = TLStreamMarkEOS(psEntry->sImplEntry.pvNative, IMG_FALSE); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamMarkEOS", return_error_); - - return 0; - -return_error_: - return -1; -} - -static void _WriterThread(void *pvArg) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hEvent; - DLLIST_NODE *psNode; - - eError = OSEventObjectOpen(_g_psImpl->hWriterEventObject, &hEvent); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectOpen"); - -#ifdef PVRSRV_FORCE_UNLOAD_IF_BAD_STATE - while (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK && - OSAtomicRead(&_g_psImpl->eThreadState) == THREAD_STATE_ALIVE) -#else - while (OSAtomicRead(&_g_psImpl->eThreadState) == THREAD_STATE_ALIVE) -#endif - { - struct DIIB_WORK_ITEM *psItem = NULL; - - OSLockAcquire(_g_psImpl->psWriterLock); - /* Get element from list tail so that we always get the oldest element - * (elements are added to head). */ - while ((psNode = dllist_get_prev_node(&_g_psImpl->sWriterQueue)) != NULL) - { - IMG_INT64 i64Ret; - DIIB_ENTRY *psEntry; - OSDI_IMPL_ENTRY *psImplEntry; - - dllist_remove_node(psNode); - OSLockRelease(_g_psImpl->psWriterLock); - - psItem = IMG_CONTAINER_OF(psNode, struct DIIB_WORK_ITEM, - sQueueElement); - - psEntry = psItem->psEntry; - psImplEntry = &psItem->psEntry->sImplEntry; - - /* if client has already disconnected we can just drop this item */ - if (psItem->psContext->bClientConnected) - { - - PVR_ASSERT(psItem->psContext->hStream != NULL); - - psImplEntry->pvNative = psItem->psContext->hStream; - - if (psEntry->eType == DI_ENTRY_TYPE_GENERIC) - { - i64Ret = _ReadGeneric(psItem->psContext, psEntry); - PVR_LOG_IF_FALSE(i64Ret >= 0, "generic access read operation " - "failed"); - } - else if (psEntry->eType == DI_ENTRY_TYPE_RANDOM_ACCESS) - { - IMG_UINT64 ui64Pos = psItem->ui64Offset; - - i64Ret = _ReadRndAccess(psEntry, psItem->ui64Size, &ui64Pos, - psEntry->pvPrivData); - PVR_LOG_IF_FALSE(i64Ret >= 0, "random access read operation " - "failed"); - } - else - { - PVR_ASSERT(psEntry->eType == DI_ENTRY_TYPE_GENERIC || - psEntry->eType == DI_ENTRY_TYPE_RANDOM_ACCESS); - } - - psImplEntry->pvNative = NULL; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "client reading entry \"%s\" has " - "disconnected", psEntry->pszFullPath)); - } - - _ContextUnrefAndMaybeDestroy(psItem->psContext); - OSFreeMemNoStats(psItem); - - OSLockAcquire(_g_psImpl->psWriterLock); - } - OSLockRelease(_g_psImpl->psWriterLock); - - eError = OSEventObjectWaitKernel(hEvent, WRITER_THREAD_SLEEP_TIMEOUT); - if (eError != PVRSRV_OK && eError != PVRSRV_ERROR_TIMEOUT) - { - PVR_LOG_ERROR(eError, "OSEventObjectWaitKernel"); - } - } - - OSLockAcquire(_g_psImpl->psWriterLock); - /* clear the queue if there are any items pending */ - while ((psNode = dllist_get_prev_node(&_g_psImpl->sWriterQueue)) != NULL) - { - struct DIIB_WORK_ITEM *psItem = IMG_CONTAINER_OF(psNode, - struct DIIB_WORK_ITEM, - sQueueElement); - - dllist_remove_node(psNode); - _ContextUnrefAndMaybeDestroy(psItem->psContext); - OSFreeMem(psItem); - } - OSLockRelease(_g_psImpl->psWriterLock); - - eError = OSEventObjectClose(hEvent); - PVR_LOG_IF_ERROR(eError, "OSEventObjectClose"); - - OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_TERMINATED); -} - -/* ----- DI internal API ---------------------------------------------------- */ - -DIIB_ENTRY *DIImplBrgFind(const IMG_CHAR *pszPath) -{ - DIIB_ENTRY *psEntry; - - OSLockAcquire(_g_psImpl->psEntriesLock); - psEntry = (void *) HASH_Retrieve_Extended(_g_psImpl->psEntriesTable, - (IMG_CHAR *) pszPath); - OSLockRelease(_g_psImpl->psEntriesLock); - - return psEntry; -} - -/* ----- DI bridge interface ------------------------------------------------ */ - -static PVRSRV_ERROR _CreateStream(IMG_CHAR *pszStreamName, IMG_HANDLE *phStream) -{ - IMG_UINT32 iRet; - IMG_HANDLE hStream; - PVRSRV_ERROR eError; - - /* for now only one stream can be created. Should we be able to create - * per context stream? */ - iRet = OSSNPrintf(pszStreamName, PRVSRVTL_MAX_STREAM_NAME_SIZE, - "di_stream_%x", OSGetCurrentClientProcessIDKM()); - if (iRet >= PRVSRVTL_MAX_STREAM_NAME_SIZE) - { - /* this check is superfluous because it can never happen but in case - * someone changes the definition of PRVSRVTL_MAX_STREAM_NAME_SIZE - * handle this case */ - pszStreamName[0] = '\0'; - return PVRSRV_ERROR_INTERNAL_ERROR; - } - - eError = TLStreamCreate(&hStream, pszStreamName, STREAM_BUFFER_SIZE, - TL_OPMODE_DROP_NEWER, NULL, NULL, NULL, NULL); - PVR_RETURN_IF_ERROR(eError); - - *phStream = hStream; - - return PVRSRV_OK; -} - -PVRSRV_ERROR DICreateContextKM(IMG_CHAR *pszStreamName, DI_CONTEXT **ppsContext) -{ - PVRSRV_ERROR eError; - DI_CONTEXT *psContext; - IMG_HANDLE hStream = NULL; - THREAD_STATE eTState; - - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsContext != NULL, "ppsContext"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pszStreamName != NULL, "pszStreamName"); - - psContext = OSAllocMem(sizeof(*psContext)); - PVR_LOG_GOTO_IF_NOMEM(psContext, eError, return_); - - eError = _CreateStream(pszStreamName, &hStream); - PVR_LOG_GOTO_IF_ERROR(eError, "_CreateStream", free_desc_); - - psContext->hStream = hStream; - /* indicated to the write thread if the client is still connected and - * waiting for the data */ - psContext->bClientConnected = IMG_TRUE; - OSAtomicWrite(&psContext->iRefCnt, 1); - - eTState = OSAtomicCompareExchange(&_g_psImpl->eThreadState, - THREAD_STATE_NULL, - THREAD_STATE_ALIVE); - - /* if the thread has not been started yet do it */ - if (eTState == THREAD_STATE_NULL) - { - PVR_ASSERT(_g_psImpl->hWriterThread == NULL); - - eError = OSThreadCreate(&_g_psImpl->hWriterThread, "di_writer", - _WriterThread, NULL, IMG_FALSE, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreate", free_close_stream_); - } - - *ppsContext = psContext; - - return PVRSRV_OK; - -free_close_stream_: - TLStreamClose(psContext->hStream); - OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_TERMINATED); -free_desc_: - OSFreeMem(psContext); -return_: - return eError; -} - -PVRSRV_ERROR DIDestroyContextKM(DI_CONTEXT *psContext) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext"); - - /* pass the information to the write thread that the client has - * disconnected */ - psContext->bClientConnected = IMG_FALSE; - - return _ContextUnrefAndMaybeDestroy(psContext); -} - -PVRSRV_ERROR DIReadEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath, - IMG_UINT64 ui64Offset, IMG_UINT64 ui64Size) -{ - PVRSRV_ERROR eError; - struct DIIB_WORK_ITEM *psItem; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pszEntryPath != NULL, "pszEntryPath"); - - /* 'no stats' to avoid acquiring the process stats locks */ - psItem = OSAllocMemNoStats(sizeof(*psItem)); - PVR_LOG_GOTO_IF_NOMEM(psItem, eError, return_); - - psItem->psContext = psContext; - psItem->psEntry = DIImplBrgFind(pszEntryPath); - PVR_LOG_GOTO_IF_FALSE_VA(psItem->psEntry != NULL, free_item_, - "entry %s does not exist", pszEntryPath); - psItem->ui64Size = ui64Size; - psItem->ui64Offset = ui64Offset; - - /* increment ref count on the context so that it doesn't get freed - * before it gets processed by the writer thread. */ - if (!OSAtomicAddUnless(&psContext->iRefCnt, 1, IMG_INT32_MAX)) - { - /* Job is not scheduled to the writer queue; there are too many waiting. */ - PVR_LOG_GOTO_WITH_ERROR("OSAtomicAddUnless", eError, PVRSRV_ERROR_REFCOUNT_OVERFLOW, overflow_); - } - - OSLockAcquire(_g_psImpl->psWriterLock); - dllist_add_to_head(&_g_psImpl->sWriterQueue, &psItem->sQueueElement); - OSLockRelease(_g_psImpl->psWriterLock); - - eError = OSEventObjectSignal(_g_psImpl->hWriterEventObject); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - - return PVRSRV_OK; - -free_item_: - eError = PVRSRV_ERROR_NOT_FOUND; -overflow_: - OSFreeMemNoStats(psItem); -return_: - return eError; -} - -PVRSRV_ERROR DIWriteEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath, - IMG_UINT32 ui32ValueSize, const IMG_CHAR *pszValue) -{ - DIIB_ENTRY *psEntry; - DI_PFN_WRITE pfnEntryPuts; - IMG_INT64 i64Length = 0; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pszEntryPath != NULL, "pszEntryPath"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pszValue != NULL, "pszValue"); - - psEntry = DIImplBrgFind(pszEntryPath); - PVR_LOG_RETURN_IF_FALSE_VA(psEntry != NULL, PVRSRV_ERROR_NOT_FOUND, - "entry %s does not exist", pszEntryPath); - - pfnEntryPuts = psEntry->sIterCb.pfnWrite; - if (pfnEntryPuts != NULL) - { - i64Length = pfnEntryPuts(pszValue, ui32ValueSize, (IMG_UINT64*)&i64Length, psEntry->pvPrivData); - - /* To deal with -EINVAL being returned */ - PVR_LOG_RETURN_IF_INVALID_PARAM(i64Length >= 0, pszValue); - } - else - { - PVR_LOG_MSG(PVR_DBG_WARNING, "Unable to write to Entry. Write callback not enabled"); - return PVRSRV_ERROR_INVALID_REQUEST; - } - return PVRSRV_OK; -} - -static PVRSRV_ERROR _listName(uintptr_t k, - uintptr_t v, - void* hStream) -{ - PVRSRV_ERROR eError; - DIIB_ENTRY *psEntry; - IMG_UINT32 ui32Size; - IMG_CHAR aszName[DI_IMPL_BRG_PATH_LEN]; - - psEntry = (DIIB_ENTRY*) v; - PVR_ASSERT(psEntry != NULL); - PVR_UNREFERENCED_PARAMETER(k); - - ui32Size = OSSNPrintf(aszName, DI_IMPL_BRG_PATH_LEN, "%s\n", psEntry->pszFullPath); - PVR_LOG_IF_FALSE(ui32Size > 5, "ui32Size too small, Error suspected!"); - eError = TLStreamWrite(hStream, (IMG_UINT8 *)aszName, ui32Size+1); - - return eError; -} - - -PVRSRV_ERROR DIListAllEntriesKM(DI_CONTEXT *psContext) -{ - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext"); - - eError = HASH_Iterate(_g_psImpl->psEntriesTable, _listName, psContext->hStream); - PVR_LOG_IF_ERROR(eError, "HASH_Iterate_Extended"); - - eError = TLStreamMarkEOS(psContext->hStream, IMG_FALSE); - return eError; -} - -/* ----- DI implementation interface ---------------------------------------- */ - -static PVRSRV_ERROR _Init(void) -{ - PVRSRV_ERROR eError; - - _g_psImpl = OSAllocMem(sizeof(*_g_psImpl)); - PVR_LOG_GOTO_IF_NOMEM(_g_psImpl, eError, return_); - - _g_psImpl->psEntriesTable = HASH_Create_Extended(ENTRIES_TABLE_INIT_SIZE, - DI_IMPL_BRG_PATH_LEN, - _Hash, _Compare); - PVR_LOG_GOTO_IF_NOMEM(_g_psImpl->psEntriesTable, eError, free_impl_); - - eError = OSLockCreate(&_g_psImpl->psEntriesLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSCreateLock", free_table_); - - eError = OSLockCreate(&_g_psImpl->psWriterLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSCreateLock", free_entries_lock_); - - eError = OSEventObjectCreate("DI_WRITER_EO", - &_g_psImpl->hWriterEventObject); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", free_writer_lock_); - - _g_psImpl->hWriterThread = NULL; - OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_NULL); - - dllist_init(&_g_psImpl->sWriterQueue); - - return PVRSRV_OK; - -free_writer_lock_: - OSLockDestroy(_g_psImpl->psWriterLock); -free_entries_lock_: - OSLockDestroy(_g_psImpl->psEntriesLock); -free_table_: - HASH_Delete_Extended(_g_psImpl->psEntriesTable, IMG_FALSE); -free_impl_: - OSFreeMem(_g_psImpl); - _g_psImpl = NULL; -return_: - return eError; -} - -static void _DeInit(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - THREAD_STATE eTState; - - eTState = OSAtomicCompareExchange(&_g_psImpl->eThreadState, - THREAD_STATE_ALIVE, - THREAD_STATE_TERMINATED); - - if (eTState == THREAD_STATE_ALIVE) - { - if (_g_psImpl->hWriterEventObject != NULL) - { - eError = OSEventObjectSignal(_g_psImpl->hWriterEventObject); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - - LOOP_UNTIL_TIMEOUT(WRITER_THREAD_DESTROY_TIMEOUT) - { - eError = OSThreadDestroy(_g_psImpl->hWriterThread); - if (eError == PVRSRV_OK) - { - break; - } - OSWaitus(WRITER_THREAD_DESTROY_TIMEOUT/WRITER_THREAD_DESTROY_RETRIES); - } END_LOOP_UNTIL_TIMEOUT(); - - PVR_LOG_IF_ERROR(eError, "OSThreadDestroy"); - } - - if (_g_psImpl->hWriterEventObject != NULL) - { - eError = OSEventObjectDestroy(_g_psImpl->hWriterEventObject); - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - } - - HASH_Delete_Extended(_g_psImpl->psEntriesTable, IMG_FALSE); - OSLockDestroy(_g_psImpl->psWriterLock); - OSLockDestroy(_g_psImpl->psEntriesLock); - OSFreeMem(_g_psImpl); - _g_psImpl = NULL; -} - -/* Recursively traverses the ancestors list up to the root group and - * appends their names preceded by "/" to the path in reverse order - * (root group's name first and psGroup group's name last). - * Returns current offset in the path (the current path length without the - * NUL character). If there is no more space in the path returns -1 - * to indicate an error (the path is too long to fit into the buffer). */ -static IMG_INT _BuildGroupPath(IMG_CHAR *pszPath, const DIIB_GROUP *psGroup) -{ - IMG_INT iOff; - - if (psGroup == NULL) - { - return 0; - } - - PVR_ASSERT(pszPath != NULL); - - iOff = _BuildGroupPath(pszPath, psGroup->psParentGroup); - PVR_RETURN_IF_FALSE(iOff != -1, -1); - - iOff += OSStringLCopy(pszPath + iOff, "/", - DI_IMPL_BRG_PATH_LEN - iOff); - PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, -1); - - iOff += OSStringLCopy(pszPath + iOff, psGroup->pszName, - DI_IMPL_BRG_PATH_LEN - iOff); - PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, -1); - - return iOff; -} - -static PVRSRV_ERROR _BuildEntryPath(IMG_CHAR *pszPath, const IMG_CHAR *pszName, - const DIIB_GROUP *psGroup) -{ - IMG_INT iOff = _BuildGroupPath(pszPath, psGroup); - PVR_RETURN_IF_FALSE(iOff != -1, PVRSRV_ERROR_INVALID_OFFSET); - - iOff += OSStringLCopy(pszPath + iOff, "/", DI_IMPL_BRG_PATH_LEN - iOff); - PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, - PVRSRV_ERROR_INVALID_OFFSET); - - iOff += OSStringLCopy(pszPath + iOff, pszName, DI_IMPL_BRG_PATH_LEN - iOff); - PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, - PVRSRV_ERROR_INVALID_OFFSET); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _CreateEntry(const IMG_CHAR *pszName, - DI_ENTRY_TYPE eType, - const DI_ITERATOR_CB *psIterCb, - void *pvPrivData, - void *pvParentGroup, - void **pvEntry) -{ - DIIB_GROUP *psParentGroup = pvParentGroup; - DIIB_ENTRY *psEntry; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pvEntry != NULL, "pvEntry"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pvParentGroup != NULL, "pvParentGroup"); - - switch (eType) - { - case DI_ENTRY_TYPE_GENERIC: - break; - case DI_ENTRY_TYPE_RANDOM_ACCESS: - break; - default: - PVR_DPF((PVR_DBG_ERROR, "eType invalid in %s()", __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, return_); - } - - psEntry = OSAllocMem(sizeof(*psEntry)); - PVR_LOG_GOTO_IF_NOMEM(psEntry, eError, return_); - - eError = OSLockCreate(&psEntry->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", free_entry_); - - psEntry->eType = eType; - psEntry->sIterCb = *psIterCb; - psEntry->pvPrivData = pvPrivData; - psEntry->psParentGroup = psParentGroup; - psEntry->pszFullPath[0] = '\0'; - - psEntry->sImplEntry.pvPrivData = pvPrivData; - psEntry->sImplEntry.pvNative = NULL; - psEntry->sImplEntry.psCb = &_g_sEntryCallbacks; - - eError = _BuildEntryPath(psEntry->pszFullPath, pszName, - psEntry->psParentGroup); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s() failed in _BuildEntryPath() for \"%s\" " - "entry", __func__, pszName)); - goto destroy_lock_; - } - - OSLockAcquire(_g_psImpl->psEntriesLock); - eError = HASH_Insert_Extended(_g_psImpl->psEntriesTable, - psEntry->pszFullPath, - (uintptr_t) psEntry) ? - PVRSRV_OK : PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - OSLockRelease(_g_psImpl->psEntriesLock); - PVR_LOG_GOTO_IF_ERROR(eError, "HASH_Insert_Extended failed", destroy_lock_); - - *pvEntry = psEntry; - - return PVRSRV_OK; - -destroy_lock_: - OSLockDestroy(psEntry->hLock); -free_entry_: - OSFreeMem(psEntry); -return_: - return eError; -} - -static void _DestroyEntry(void *pvEntry) -{ - DIIB_ENTRY *psEntry = pvEntry; - PVR_ASSERT(psEntry != NULL); - - OSLockAcquire(_g_psImpl->psEntriesLock); - HASH_Remove_Extended(_g_psImpl->psEntriesTable, psEntry->pszFullPath); - OSLockRelease(_g_psImpl->psEntriesLock); - - OSLockDestroy(psEntry->hLock); - OSFreeMem(psEntry); -} - -static PVRSRV_ERROR _CreateGroup(const IMG_CHAR *pszName, - void *pvParentGroup, - void **ppvGroup) -{ - DIIB_GROUP *psNewGroup; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName"); - PVR_LOG_RETURN_IF_INVALID_PARAM(ppvGroup != NULL, "ppvGroup"); - - psNewGroup = OSAllocMem(sizeof(*psNewGroup)); - PVR_LOG_RETURN_IF_NOMEM(psNewGroup, "OSAllocMem"); - - psNewGroup->pszName = pszName; - psNewGroup->psParentGroup = pvParentGroup; - - *ppvGroup = psNewGroup; - - return PVRSRV_OK; -} - -static void _DestroyGroup(void *pvGroup) -{ - DIIB_GROUP *psGroup = pvGroup; - PVR_ASSERT(psGroup != NULL); - - OSFreeMem(psGroup); -} - -PVRSRV_ERROR PVRDIImplBrgRegister(void) -{ - OSDI_IMPL_CB sImplCb = { - .pfnInit = _Init, - .pfnDeInit = _DeInit, - .pfnCreateEntry = _CreateEntry, - .pfnDestroyEntry = _DestroyEntry, - .pfnCreateGroup = _CreateGroup, - .pfnDestroyGroup = _DestroyGroup - }; - - return DIRegisterImplementation("impl_brg", &sImplCb); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.h b/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.h deleted file mode 100644 index 7d5a6ca757e8e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS agnostic implementation of Debug Info interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_IMPL_BRG_H -#define PVR_IMPL_BRG_H - -#include "pvrsrv_error.h" - -typedef struct DI_CONTEXT_TAG DI_CONTEXT; -typedef struct DI_ENTRY_DESC DI_ENTRY_DESC; - -PVRSRV_ERROR PVRDIImplBrgRegister(void); - -/*! @Function DICreateContextKM - * - * @Description - * Creates DI context which among others also creates a TL stream for reading - * entries. - * - * @Output pszStreamName: name of the TL stream created in this context - * @Output ppsContext: pointer to the new context - * - * @Return PVRSRV_ERROR error code - * PVRSRV_OK in case of a success - * PVRSRV_ERROR_INVALID_PARAMS if any of the parameters is invalid - * PVRSRV_ERROR_OUT_OF_MEMORY if any of the memory allocations failed - * error codes returned by TLStreamCreate() - */ -PVRSRV_ERROR DICreateContextKM(IMG_CHAR *pszStreamName, - DI_CONTEXT **ppsContext); - -/*! @Function DIDestroyContextKM - * - * @Description - * Destroy the DI context and all underlying dependencies. - * - * @Input psContext: pointer to the context - * - * @Return PVRSRV_ERROR error code - * PVRSRV_OK in case of a success - * PVRSRV_ERROR_INVALID_PARAMS if invalid context pointer given - */ -PVRSRV_ERROR DIDestroyContextKM(DI_CONTEXT *psContext); - -PVRSRV_ERROR DIReadEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath, - IMG_UINT64 ui64Offset, IMG_UINT64 ui64Size); - -PVRSRV_ERROR DIWriteEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath, - IMG_UINT32 ui32ValueSize, const IMG_CHAR *pszValue); - -PVRSRV_ERROR DIListAllEntriesKM(DI_CONTEXT *psContext); - -#endif /* PVR_IMPL_BRG_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg_intern.h b/drivers/gpu/drm/img-rogue/1.17/di_impl_brg_intern.h deleted file mode 100644 index 5e11cac598543..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_impl_brg_intern.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS agnostic implementation of Debug Info internal interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_IMPL_BRG_INTERN_H -#define PVR_IMPL_BRG_INTERN_H - -typedef struct DIIB_GROUP DIIB_GROUP; -typedef struct DIIB_ENTRY DIIB_ENTRY; - -/*! @Function DIImplBrgFind - * - * @Description - * Retrieves an entry based on a given path. - * - * @Input pszPath: Full entry path in form of - * /rootGroup/.../parentGroup/entryName. - * - * @Return Returns entry object if exists or NULL otherwise. - */ -DIIB_ENTRY *DIImplBrgFind(const IMG_CHAR *pszPath); - -#endif /* PVR_IMPL_BRG_INTERN_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/di_server.c b/drivers/gpu/drm/img-rogue/1.17/di_server.c deleted file mode 100644 index 4be6ded7706d3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_server.c +++ /dev/null @@ -1,785 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Debug Info framework functions and types. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "di_server.h" -#include "osdi_impl.h" -#include "pvrsrv_error.h" -#include "dllist.h" -#include "lock.h" -#include "allocmem.h" -#include "osfunc.h" - -#if defined(MODULE) -#define ROOT_GROUP_NAME (PVR_DRM_NAME "_1_17") -#else -#define ROOT_GROUP_NAME PVR_DRM_NAME -#endif - -/*! Implementation object. */ -typedef struct DI_IMPL -{ - const IMG_CHAR *pszName; /*pszName = OSAllocMem(sizeof(ROOT_GROUP_NAME)); - PVR_LOG_GOTO_IF_NOMEM(_g_psRootGroup->pszName, eError, cleanup_name_); - OSStringLCopy(_g_psRootGroup->pszName, ROOT_GROUP_NAME, - sizeof(ROOT_GROUP_NAME)); - - dllist_init(&_g_psRootGroup->sListNode); - dllist_init(&_g_psRootGroup->sGroupList); - dllist_init(&_g_psRootGroup->sEntryList); - dllist_init(&_g_psRootGroup->sNativeHandleList); - - return PVRSRV_OK; - -cleanup_name_: - OSFreeMem(_g_psRootGroup); -destroy_lock_: - OSLockDestroy(_g_hLock); -return_: - return eError; -} - -/* Destroys the whole tree of group and entries for a given group as a root. */ -static void _DeInitGroupRecursively(DI_GROUP *psGroup) -{ - DLLIST_NODE *psThis, *psNext; - - dllist_foreach_node(&psGroup->sEntryList, psThis, psNext) - { - DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode); - DIDestroyEntry(psThisEntry); - } - - dllist_foreach_node(&psGroup->sGroupList, psThis, psNext) - { - DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode); - - _DeInitGroupRecursively(psThisGroup); - } - - DIDestroyGroup(psGroup); -} - -void DIDeInit(void) -{ - DLLIST_NODE *psThis, *psNext; - - OSLockAcquire(_g_hLock); - - if (!dllist_is_empty(&_g_psRootGroup->sGroupList) || - !dllist_is_empty(&_g_psRootGroup->sEntryList)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: entries or groups still exist during " - "de-initialisation process, destroying all", __func__)); - } - - _DeInitGroupRecursively(_g_psRootGroup); - _g_psRootGroup = NULL; - - /* Remove all of the implementations. */ - dllist_foreach_node(&_g_sImpls, psThis, psNext) - { - DI_IMPL *psDiImpl = IMG_CONTAINER_OF(psThis, DI_IMPL, sListNode); - - if (psDiImpl->bInitialised) - { - psDiImpl->sCb.pfnDeInit(); - psDiImpl->bInitialised = IMG_FALSE; - } - - dllist_remove_node(&psDiImpl->sListNode); - OSFreeMem(psDiImpl); - } - - OSLockRelease(_g_hLock); - - /* all resources freed so free the lock itself too */ - - OSLockDestroy(_g_hLock); -} - -static IMG_BOOL _ValidateIteratorCb(const DI_ITERATOR_CB *psIterCb, - DI_ENTRY_TYPE eType) -{ - IMG_UINT32 uiFlags = 0; - - if (psIterCb == NULL) - { - return IMG_FALSE; - } - - if (eType == DI_ENTRY_TYPE_GENERIC) - { - uiFlags |= psIterCb->pfnShow != NULL ? BIT(0) : 0; - uiFlags |= psIterCb->pfnStart != NULL ? BIT(1) : 0; - uiFlags |= psIterCb->pfnStop != NULL ? BIT(2) : 0; - uiFlags |= psIterCb->pfnNext != NULL ? BIT(3) : 0; - - /* either only pfnShow or all callbacks need to be set */ - if (uiFlags != BIT(0) && !BITMASK_HAS(uiFlags, 0x0f)) - { - return IMG_FALSE; - } - } - else if (eType == DI_ENTRY_TYPE_RANDOM_ACCESS) - { - uiFlags |= psIterCb->pfnRead != NULL ? BIT(0) : 0; - uiFlags |= psIterCb->pfnSeek != NULL ? BIT(1) : 0; - - /* either only pfnRead or all callbacks need to be set */ - if (uiFlags != BIT(0) && !BITMASK_HAS(uiFlags, 0x03)) - { - return IMG_FALSE; - } - } - else - { - return IMG_FALSE; - } - - return IMG_TRUE; -} - -static PVRSRV_ERROR _CreateNativeEntry(DI_ENTRY *psEntry, - const DI_NATIVE_HANDLE *psNativeParent) -{ - PVRSRV_ERROR eError; - DI_IMPL *psImpl = psNativeParent->psDiImpl; - - DI_NATIVE_HANDLE *psNativeEntry = OSAllocMem(sizeof(*psNativeEntry)); - PVR_LOG_GOTO_IF_NOMEM(psNativeEntry, eError, return_); - - eError = psImpl->sCb.pfnCreateEntry(psEntry->pszName, - psEntry->eType, - &psEntry->sIterCb, - psEntry->pvPrivData, - psNativeParent->pvHandle, - &psNativeEntry->pvHandle); - PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateEntry", free_memory_); - - psNativeEntry->psDiImpl = psImpl; - - dllist_add_to_head(&psEntry->sNativeHandleList, &psNativeEntry->sListNode); - - return PVRSRV_OK; - -free_memory_: - OSFreeMem(psNativeEntry); -return_: - return eError; -} - -static void _DestroyNativeEntry(DI_NATIVE_HANDLE *psNativeEntry) -{ - dllist_remove_node(&psNativeEntry->sListNode); - OSFreeMem(psNativeEntry); -} - -PVRSRV_ERROR DICreateEntry(const IMG_CHAR *pszName, - DI_GROUP *psGroup, - const DI_ITERATOR_CB *psIterCb, - void *pvPriv, - DI_ENTRY_TYPE eType, - DI_ENTRY **ppsEntry) -{ - PVRSRV_ERROR eError; - DLLIST_NODE *psThis, *psNext; - DI_ENTRY *psEntry; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName"); - PVR_LOG_RETURN_IF_INVALID_PARAM(_ValidateIteratorCb(psIterCb, eType), - "psIterCb"); - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsEntry != NULL, "psEntry"); - - psEntry = OSAllocMem(sizeof(*psEntry)); - PVR_LOG_RETURN_IF_NOMEM(psEntry, "OSAllocMem"); - - if (psGroup == NULL) - { - psGroup = _g_psRootGroup; - } - - psEntry->pszName = pszName; - psEntry->pvPrivData = pvPriv; - psEntry->eType = eType; - psEntry->sIterCb = *psIterCb; - dllist_init(&psEntry->sNativeHandleList); - - OSLockAcquire(_g_hLock); - - dllist_add_to_tail(&psGroup->sEntryList, &psEntry->sListNode); - - /* Iterate over all of the native handles of parent group to create - * the entry for every registered implementation. */ - dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeGroup = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - eError = _CreateNativeEntry(psEntry, psNativeGroup); - PVR_GOTO_IF_ERROR(eError, cleanup_); - } - - OSLockRelease(_g_hLock); - - *ppsEntry = psEntry; - - return PVRSRV_OK; - -cleanup_: - OSLockRelease(_g_hLock); - - /* Something went wrong so if there were any native entries created remove - * them from the list, free them and free the DI entry itself. */ - dllist_foreach_node(&psEntry->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeEntry = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - _DestroyNativeEntry(psNativeEntry); - } - - OSFreeMem(psEntry); - - return eError; -} - -void DIDestroyEntry(DI_ENTRY *psEntry) -{ - DLLIST_NODE *psThis, *psNext; - - PVR_LOG_RETURN_VOID_IF_FALSE(psEntry != NULL, - "psEntry invalid in DIDestroyEntry()"); - - /* Iterate through all of the native entries of the DI entry, remove - * them from the list and then destroy them. After that, destroy the - * DI entry itself. */ - dllist_foreach_node(&psEntry->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNative = IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, - sListNode); - - /* The implementation must ensure that entry is not removed if any - * operations are being executed on the entry. If this is the case - * the implementation should block until all of them are finished - * and prevent any further operations. - * This will guarantee proper synchronisation between the DI framework - * and underlying implementations and prevent destruction/access - * races. */ - psNative->psDiImpl->sCb.pfnDestroyEntry(psNative->pvHandle); - dllist_remove_node(&psNative->sListNode); - OSFreeMem(psNative); - } - - dllist_remove_node(&psEntry->sListNode); - - OSFreeMem(psEntry); -} - -static PVRSRV_ERROR _CreateNativeGroup(DI_GROUP *psGroup, - const DI_NATIVE_HANDLE *psNativeParent, - DI_NATIVE_HANDLE **ppsNativeGroup) -{ - PVRSRV_ERROR eError; - DI_IMPL *psImpl = psNativeParent->psDiImpl; - - DI_NATIVE_HANDLE *psNativeGroup = OSAllocMem(sizeof(*psNativeGroup)); - PVR_LOG_GOTO_IF_NOMEM(psNativeGroup, eError, return_); - - eError = psImpl->sCb.pfnCreateGroup(psGroup->pszName, - psNativeParent->pvHandle, - &psNativeGroup->pvHandle); - PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateGroup", free_memory_); - - psNativeGroup->psDiImpl = psImpl; - - dllist_add_to_head(&psGroup->sNativeHandleList, &psNativeGroup->sListNode); - - *ppsNativeGroup = psNativeGroup; - - return PVRSRV_OK; - -free_memory_: - OSFreeMem(psNativeGroup); -return_: - return eError; -} - -static void _DestroyNativeGroup(DI_NATIVE_HANDLE *psNativeEntry) -{ - dllist_remove_node(&psNativeEntry->sListNode); - OSFreeMem(psNativeEntry); -} - -PVRSRV_ERROR DICreateGroup(const IMG_CHAR *pszName, - DI_GROUP *psParent, - DI_GROUP **ppsGroup) -{ - PVRSRV_ERROR eError; - DLLIST_NODE *psThis, *psNext; - DI_GROUP *psGroup; - size_t uSize; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName"); - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsGroup != NULL, "ppsDiGroup"); - - psGroup = OSAllocMem(sizeof(*psGroup)); - PVR_LOG_RETURN_IF_NOMEM(psGroup, "OSAllocMem"); - - if (psParent == NULL) - { - psParent = _g_psRootGroup; - } - - uSize = OSStringLength(pszName) + 1; - psGroup->pszName = OSAllocMem(uSize * sizeof(*psGroup->pszName)); - PVR_LOG_GOTO_IF_NOMEM(psGroup->pszName, eError, cleanup_name_); - OSStringLCopy(psGroup->pszName, pszName, uSize); - - psGroup->psParent = psParent; - dllist_init(&psGroup->sGroupList); - dllist_init(&psGroup->sEntryList); - dllist_init(&psGroup->sNativeHandleList); - - OSLockAcquire(_g_hLock); - - dllist_add_to_tail(&psParent->sGroupList, &psGroup->sListNode); - - /* Iterate over all of the native handles of parent group to create - * the group for every registered implementation. */ - dllist_foreach_node(&psParent->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeGroup = NULL, *psNativeParent = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - eError = _CreateNativeGroup(psGroup, psNativeParent, &psNativeGroup); - PVR_GOTO_IF_ERROR(eError, cleanup_); - } - - OSLockRelease(_g_hLock); - - *ppsGroup = psGroup; - - return PVRSRV_OK; - -cleanup_: - OSLockRelease(_g_hLock); - - /* Something went wrong so if there were any native groups created remove - * them from the list, free them and free the DI group itself. */ - dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeGroup = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - dllist_remove_node(&psNativeGroup->sListNode); - OSFreeMem(psNativeGroup); - } - - OSFreeMem(psGroup->pszName); -cleanup_name_: - OSFreeMem(psGroup); - - return eError; -} - -void DIDestroyGroup(DI_GROUP *psGroup) -{ - DLLIST_NODE *psThis, *psNext; - - PVR_LOG_RETURN_VOID_IF_FALSE(psGroup != NULL, - "psGroup invalid in DIDestroyGroup()"); - - /* Iterate through all of the native groups of the DI group, remove - * them from the list and then destroy them. After that destroy the - * DI group itself. */ - dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNative = IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, - sListNode); - - psNative->psDiImpl->sCb.pfnDestroyGroup(psNative->pvHandle); - dllist_remove_node(&psNative->sListNode); - OSFreeMem(psNative); - } - - dllist_remove_node(&psGroup->sListNode); - - OSFreeMem(psGroup->pszName); - OSFreeMem(psGroup); -} - -void *DIGetPrivData(const OSDI_IMPL_ENTRY *psEntry) -{ - PVR_ASSERT(psEntry != NULL); - - return psEntry->pvPrivData; -} - -void DIWrite(const OSDI_IMPL_ENTRY *psEntry, const void *pvData, - IMG_UINT32 uiSize) -{ - PVR_ASSERT(psEntry != NULL); - PVR_ASSERT(psEntry->psCb != NULL); - PVR_ASSERT(psEntry->psCb->pfnWrite != NULL); - PVR_ASSERT(psEntry->pvNative != NULL); - - psEntry->psCb->pfnWrite(psEntry->pvNative, pvData, uiSize); -} - -void DIPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, ...) -{ - va_list args; - - PVR_ASSERT(psEntry != NULL); - PVR_ASSERT(psEntry->psCb != NULL); - PVR_ASSERT(psEntry->psCb->pfnVPrintf != NULL); - PVR_ASSERT(psEntry->pvNative != NULL); - - va_start(args, pszFmt); - psEntry->psCb->pfnVPrintf(psEntry->pvNative, pszFmt, args); - va_end(args); -} - -__printf(2, 0) -void DIVPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, - va_list pArgs) -{ - PVR_ASSERT(psEntry != NULL); - PVR_ASSERT(psEntry->psCb != NULL); - PVR_ASSERT(psEntry->psCb->pfnVPrintf != NULL); - PVR_ASSERT(psEntry->pvNative != NULL); - - psEntry->psCb->pfnVPrintf(psEntry->pvNative, pszFmt, pArgs); -} - -void DIPuts(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszStr) -{ - PVR_ASSERT(psEntry != NULL); - PVR_ASSERT(psEntry->psCb != NULL); - PVR_ASSERT(psEntry->psCb->pfnPuts != NULL); - PVR_ASSERT(psEntry->pvNative != NULL); - - psEntry->psCb->pfnPuts(psEntry->pvNative, pszStr); -} - -IMG_BOOL DIHasOverflowed(const OSDI_IMPL_ENTRY *psEntry) -{ - PVR_ASSERT(psEntry != NULL); - PVR_ASSERT(psEntry->psCb != NULL); - PVR_ASSERT(psEntry->psCb->pfnHasOverflowed != NULL); - PVR_ASSERT(psEntry->pvNative != NULL); - - return psEntry->psCb->pfnHasOverflowed(psEntry->pvNative); -} - -/* ---- OS implementation API ---------------------------------------------- */ - -static IMG_BOOL _ValidateImplCb(const OSDI_IMPL_CB *psImplCb) -{ - PVR_GOTO_IF_FALSE(psImplCb->pfnInit != NULL, failed_); - PVR_GOTO_IF_FALSE(psImplCb->pfnDeInit != NULL, failed_); - PVR_GOTO_IF_FALSE(psImplCb->pfnCreateGroup != NULL, failed_); - PVR_GOTO_IF_FALSE(psImplCb->pfnDestroyGroup != NULL, failed_); - PVR_GOTO_IF_FALSE(psImplCb->pfnCreateEntry != NULL, failed_); - PVR_GOTO_IF_FALSE(psImplCb->pfnDestroyEntry != NULL, failed_); - - return IMG_TRUE; - -failed_: - return IMG_FALSE; -} - -/* Walks the tree of groups and entries and create all of the native handles - * for the given implementation for all of the already existing groups and - * entries. */ -static PVRSRV_ERROR _InitNativeHandlesRecursively(DI_IMPL *psImpl, - DI_GROUP *psGroup, - DI_NATIVE_HANDLE *psNativeParent) -{ - PVRSRV_ERROR eError; - DLLIST_NODE *psThis, *psNext; - DI_NATIVE_HANDLE *psNativeGroup; - - psNativeGroup = OSAllocMem(sizeof(*psNativeGroup)); - PVR_LOG_RETURN_IF_NOMEM(psNativeGroup, "OSAllocMem"); - - eError = psImpl->sCb.pfnCreateGroup(psGroup->pszName, - psNativeParent ? psNativeParent->pvHandle : NULL, - &psNativeGroup->pvHandle); - PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateGroup", free_memory_); - - psNativeGroup->psDiImpl = psImpl; - - dllist_add_to_head(&psGroup->sNativeHandleList, - &psNativeGroup->sListNode); - - dllist_foreach_node(&psGroup->sGroupList, psThis, psNext) - { - DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode); - - // and then walk the new group - eError = _InitNativeHandlesRecursively(psImpl, psThisGroup, - psNativeGroup); - PVR_LOG_RETURN_IF_ERROR(eError, "_InitNativeHandlesRecursively"); - } - - dllist_foreach_node(&psGroup->sEntryList, psThis, psNext) - { - DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode); - - eError = _CreateNativeEntry(psThisEntry, psNativeGroup); - PVR_LOG_RETURN_IF_ERROR(eError, "_CreateNativeEntry"); - } - - return PVRSRV_OK; - -free_memory_: - OSFreeMem(psNativeGroup); - - return eError; -} - -/* Walks the tree of groups and entries and destroys all of the native handles - * for the given implementation. */ -static void _DeInitNativeHandlesRecursively(DI_IMPL *psImpl, DI_GROUP *psGroup) -{ - DLLIST_NODE *psThis, *psNext; - - dllist_foreach_node(&psGroup->sEntryList, psThis, psNext) - { - DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode); - - // free all of the native entries that belong to this implementation - dllist_foreach_node(&psThisEntry->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeEntry = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - if (psNativeEntry->psDiImpl == psImpl) - { - _DestroyNativeEntry(psNativeEntry); - // there can be only one entry on the list for a given - // implementation - break; - } - } - } - - dllist_foreach_node(&psGroup->sGroupList, psThis, psNext) - { - DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode); - - // and then walk the new group - _DeInitNativeHandlesRecursively(psImpl, psThisGroup); - } - - // free all of the native entries that belong to this implementation - dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext) - { - DI_NATIVE_HANDLE *psNativeGroup = - IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode); - - if (psNativeGroup->psDiImpl == psImpl) - { - _DestroyNativeGroup(psNativeGroup); - // there can be only one entry on the list for a given - // implementation - break; - } - } -} - -static PVRSRV_ERROR _InitImpl(DI_IMPL *psImpl) -{ - PVRSRV_ERROR eError; - // DI_NATIVE_HANDLE *psNativeGroup; - - eError = psImpl->sCb.pfnInit(); - PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->pfnInit()", return_); - - /* if the implementation is being created after any groups or entries - * have been created we need to walk the current tree and create - * native groups and entries for all of the existing ones */ - eError = _InitNativeHandlesRecursively(psImpl, _g_psRootGroup, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "_InitNativeHandlesRecursively", - free_native_handles_and_deinit_); - - psImpl->bInitialised = IMG_TRUE; - - return PVRSRV_OK; - -free_native_handles_and_deinit_: - /* something went wrong so we need to walk the tree and remove all of the - * native entries and groups that we've created before we can destroy - * the implementation */ - _DeInitNativeHandlesRecursively(psImpl, _g_psRootGroup); - psImpl->sCb.pfnDeInit(); -return_: - return eError; -} - -PVRSRV_ERROR DIRegisterImplementation(const IMG_CHAR *pszName, - const OSDI_IMPL_CB *psImplCb) -{ - DI_IMPL *psImpl; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName"); - PVR_LOG_RETURN_IF_INVALID_PARAM(_ValidateImplCb(psImplCb), "psImplCb"); - /* if root group does not exist it can mean 2 things: - * - DIInit() was not called so initialisation order is incorrect and needs - * to be fixed - * - DIInit() failed but if that happens we should never make it here */ - PVR_ASSERT(_g_psRootGroup != NULL); - - psImpl = OSAllocMem(sizeof(*psImpl)); - PVR_LOG_RETURN_IF_NOMEM(psImpl, "OSAllocMem"); - - psImpl->pszName = pszName; - psImpl->sCb = *psImplCb; - - OSLockAcquire(_g_hLock); - - eError = _InitImpl(psImpl); - if (eError != PVRSRV_OK) - { - /* implementation could not be initialised so remove it from the - * list, free the memory and forget about it */ - - PVR_DPF((PVR_DBG_ERROR, "%s: could not initialise \"%s\" debug " - "info implementation, discarding", __func__, - psImpl->pszName)); - - goto free_impl_; - } - - psImpl->bInitialised = IMG_TRUE; - - dllist_add_to_tail(&_g_sImpls, &psImpl->sListNode); - - OSLockRelease(_g_hLock); - - return PVRSRV_OK; - -free_impl_: - OSLockRelease(_g_hLock); - - OSFreeMem(psImpl); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/di_server.h b/drivers/gpu/drm/img-rogue/1.17/di_server.h deleted file mode 100644 index a68894b1b4305..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/di_server.h +++ /dev/null @@ -1,219 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Functions for creating Debug Info groups and entries. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DI_SERVER_H -#define DI_SERVER_H - -#if defined(__linux__) - #include - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ -#else - #include -#endif /* __linux__ */ - -#include "di_common.h" -#include "pvrsrv_error.h" -#include "img_defs.h" - -/*! @Function DIInit - * - * @Description - * Initialises Debug Info framework. This function will create common resources - * for the framework. - * - * Note: This function must be called before first call to - * DIRegisterImplementation() all of the implementations. - */ -PVRSRV_ERROR DIInit(void); - -/*! @Function DIDeInit - * - * @Description - * De-initialises Debug Info framework. This function will call pfnDeInit() - * on each implementation and clean up common resources. - * - * In case some of the entries and groups have not been cleaned up this function - * will also perform recursive sweep and remove all entries and group for - * all implementations. - */ -void DIDeInit(void); - -/*! @Function DICreateEntry - * - * @Description - * Creates debug info entry. Depending on different implementations the entry - * might be for example a DebugFS file or something totally different. - * - * The entry will belong to a parent group if provided or to the root group - * if not. - * - * @Input pszName: name of the new entry - * @Input psDiGroup: parent group, if NULL entry will belong to the root group - * @Input psIterCb: implementation of the iterator for the entry - * @Input psPriv: private data that will be passed to the iterator operations - * @Input eType: type of the entry - * - * @Output ppsEntry: handle to the newly created entry - * - * @Return PVRSRV_ERROR error code - */ -PVRSRV_ERROR DICreateEntry(const IMG_CHAR *pszName, - DI_GROUP *psGroup, - const DI_ITERATOR_CB *psIterCb, - void *psPriv, - DI_ENTRY_TYPE eType, - DI_ENTRY **ppsEntry); - -/*! @Function DIDestroyEntry - * - * @Description - * Destroys debug info entry. - * - * @Input psEntry: handle to the entry - */ -void DIDestroyEntry(DI_ENTRY *psEntry); - -/*! @Function DICreateGroup - * - * @Description - * Creates debug info group. Depending on different implementations the group - * might be for example a DebugFS directory or something totally different. - * - * The group will belong to a parent group if provided or to the root group - * if not. - * - * @Input pszName: name of the new entry - * @Input psParent: parent group, if NULL entry will belong to the root group - * - * @Output ppsGroup: handle to the newly created entry - * - * @Return PVRSRV_ERROR error code - */ -PVRSRV_ERROR DICreateGroup(const IMG_CHAR *pszName, - DI_GROUP *psParent, - DI_GROUP **ppsGroup); - -/*! @Function DIDestroyGroup - * - * @Description - * Destroys debug info group. - * - * @Input psGroup: handle to the group - */ -void DIDestroyGroup(DI_GROUP *psGroup); - -/*! @Function DIGetPrivData - * - * @Description - * Retrieves private data from psEntry. The data is either passed during - * entry creation via psPriv parameter of DICreateEntry() function - * or by explicitly setting it with DIGetPrivData() function. - * - * @Input psEntry pointer to OSDI_IMPL_ENTRY object - * - * @Returns pointer to the private data (can be NULL if private data - * has not been specified) - */ -void *DIGetPrivData(const OSDI_IMPL_ENTRY *psEntry); - -/*! @Function DIWrite - * - * @Description - * Writes the binary data of the DI entry to the output sync, whatever that may - * be for the DI implementation. - * - * @Input psEntry pointer to OSDI_IMPL_ENTRY object - * @Input pvData data - * @Input uiSize pvData length - */ -void DIWrite(const OSDI_IMPL_ENTRY *psEntry, const void *pvData, - IMG_UINT32 uiSize); - -/*! @Function DIPrintf - * - * @Description - * Prints formatted string to the DI entry. - * - * @Input psEntry pointer to OSDI_IMPL_ENTRY object - * @Input pszFmt NUL-terminated format string - */ -void DIPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, ...) - __printf(2, 3); - -/*! @Function DIVPrintf - * - * @Description - * Prints formatted string to the DI entry. Equivalent to DIPrintf but takes - * va_list instead of a variable number of arguments. - * - * @Input psEntry pointer to OSDI_IMPL_ENTRY object - * @Input pszFmt NUL-terminated format string - * @Input pArgs vs_list object - */ -void DIVPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, - va_list pArgs); - -/*! @Function DIPrintf - * - * @Description - * Prints a string to the DI entry. - * - * @Input psEntry pointer to OSDI_IMPL_ENTRY object - * @Input pszFmt NUL-terminated string - */ -void DIPuts(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszStr); - -/*! @Function DIHasOverflowed - * - * @Description - * Checks if the DI buffer has overflowed. - * - * @Return IMG_TRUE if buffer overflowed - */ -IMG_BOOL DIHasOverflowed(const OSDI_IMPL_ENTRY *psEntry); - -#endif /* DI_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/dllist.h b/drivers/gpu/drm/img-rogue/1.17/dllist.h deleted file mode 100644 index fa73dff59c44e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/dllist.h +++ /dev/null @@ -1,408 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Double linked list header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Double linked list interface -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DLLIST_H -#define DLLIST_H - -#include "img_types.h" -#include "img_defs.h" - -/*! - Pointer to a linked list node -*/ -typedef struct DLLIST_NODE_ *PDLLIST_NODE; - - -/*! - Node in a linked list -*/ -/* - * Note: the following structure's size is architecture-dependent and clients - * may need to create a mirror of the structure definition if it needs to be - * used in a structure shared between host and device. - * Consider such clients if any changes are made to this structure. - */ -typedef struct DLLIST_NODE_ -{ - struct DLLIST_NODE_ *psPrevNode; - struct DLLIST_NODE_ *psNextNode; -} DLLIST_NODE; - - -/*! - Static initialiser -*/ -#define DECLARE_DLLIST(n) \ -DLLIST_NODE (n) = {&(n), &(n)} - -/*************************************************************************/ /*! -@Function dllist_foreach_node - -@Description Walk through all the nodes on the list. - Safe against removal of (node). - -@Input list_head List node to start the operation -@Input node Current list node -@Input next Node after the current one - -*/ -/*****************************************************************************/ -#define dllist_foreach_node(list_head, node, next) \ - for ((node) = (list_head)->psNextNode, (next) = (node)->psNextNode; \ - (node) != (list_head); \ - (node) = (next), (next) = (node)->psNextNode) - -#define dllist_foreach_node_backwards(list_head, node, prev) \ - for ((node) = (list_head)->psPrevNode, (prev) = (node)->psPrevNode; \ - (node) != (list_head); \ - (node) = (prev), (prev) = (node)->psPrevNode) - - -/*************************************************************************/ /*! -@Function dllist_foreach - -@Description Simplification of dllist_foreach_node. - Walk through all the nodes on the list. - Safe against removal of currently-iterated node. - - Adds utility-macro dllist_cur() to typecast the current node. - -@Input list_head List node to start the operation - -*/ -/*****************************************************************************/ -#define dllist_foreach(list_head) \ - for (DLLIST_NODE *_DllNode = (list_head).psNextNode, *_DllNext = _DllNode->psNextNode; \ - _DllNode != &(list_head); \ - _DllNode = _DllNext, _DllNext = _DllNode->psNextNode) - -#define dllist_foreach_backwards(list_head) \ - for (DLLIST_NODE *_DllNode = (list_head).psPrevNode, *_DllPrev = _DllNode->psPrevNode; \ - _DllNode != &(list_head); \ - _DllNode = _DllPrev, _DllPrev = _DllNode->psPrevNode) - -#define dllist_cur(type, member) IMG_CONTAINER_OF(_DllNode, type, member) - -/*************************************************************************/ /*! -@Function dllist_init - -@Description Initialize a new double linked list - -@Input psListHead List head Node - -*/ -/*****************************************************************************/ -static INLINE -void dllist_init(PDLLIST_NODE psListHead) -{ - psListHead->psPrevNode = psListHead; - psListHead->psNextNode = psListHead; -} - -/*************************************************************************/ /*! -@Function dllist_is_empty - -@Description Returns whether the list is empty - -@Input psListHead List head Node - -*/ -/*****************************************************************************/ -static INLINE -bool dllist_is_empty(PDLLIST_NODE psListHead) -{ - return ((psListHead->psPrevNode == psListHead) - && (psListHead->psNextNode == psListHead)); -} - -/*************************************************************************/ /*! -@Function dllist_add_to_head - -@Description Add psNewNode to head of list psListHead - -@Input psListHead Head Node -@Input psNewNode New Node - -*/ -/*****************************************************************************/ -static INLINE -void dllist_add_to_head(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode) -{ - PDLLIST_NODE psTmp; - - psTmp = psListHead->psNextNode; - - psListHead->psNextNode = psNewNode; - psNewNode->psNextNode = psTmp; - - psTmp->psPrevNode = psNewNode; - psNewNode->psPrevNode = psListHead; -} - - -/*************************************************************************/ /*! -@Function dllist_add_to_tail - -@Description Add psNewNode to tail of list psListHead - -@Input psListHead Head Node -@Input psNewNode New Node - -*/ -/*****************************************************************************/ -static INLINE -void dllist_add_to_tail(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode) -{ - PDLLIST_NODE psTmp; - - psTmp = psListHead->psPrevNode; - - psListHead->psPrevNode = psNewNode; - psNewNode->psPrevNode = psTmp; - - psTmp->psNextNode = psNewNode; - psNewNode->psNextNode = psListHead; -} - -/*************************************************************************/ /*! -@Function dllist_node_is_in_list - -@Description Returns true if psNode is in a list - -@Input psNode List node - -*/ -/*****************************************************************************/ -static INLINE -bool dllist_node_is_in_list(PDLLIST_NODE psNode) -{ - return (psNode->psNextNode != NULL); -} - -/*************************************************************************/ /*! -@Function dllist_get_next_node - -@Description Returns the list node after psListHead or NULL psListHead is - the only element in the list. - -@Input psListHead List node to start the operation - -*/ -/*****************************************************************************/ -static INLINE -PDLLIST_NODE dllist_get_next_node(PDLLIST_NODE psListHead) -{ - if (psListHead->psNextNode == psListHead) - { - return NULL; - } - else - { - return psListHead->psNextNode; - } -} - -/*************************************************************************/ /*! -@Function dllist_get_prev_node - -@Description Returns the list node preceding psListHead or NULL if - psListHead is the only element in the list. - -@Input psListHead List node to start the operation - -*/ -/*****************************************************************************/ -static INLINE -PDLLIST_NODE dllist_get_prev_node(PDLLIST_NODE psListHead) -{ - if (psListHead->psPrevNode == psListHead) - { - return NULL; - } - else - { - return psListHead->psPrevNode; - } -} - -/*************************************************************************/ /*! -@Function dllist_remove_node - -@Description Removes psListNode from the list where it currently belongs - -@Input psListNode List node to be removed - -*/ -/*****************************************************************************/ -static INLINE -void dllist_remove_node(PDLLIST_NODE psListNode) -{ - psListNode->psNextNode->psPrevNode = psListNode->psPrevNode; - psListNode->psPrevNode->psNextNode = psListNode->psNextNode; - - /* Clear the node to show it's not in a list */ - psListNode->psPrevNode = NULL; - psListNode->psNextNode = NULL; -} - -/*************************************************************************/ /*! -@Function dllist_replace_head - -@Description Moves the list from psOldHead to psNewHead - -@Input psOldHead List node to be replaced. Will become a - head node of an empty list. -@Input psNewHead List node to be inserted. Must be an - empty list head. - -*/ -/*****************************************************************************/ -static INLINE -void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead) -{ - if (dllist_is_empty(psOldHead)) - { - psNewHead->psNextNode = psNewHead; - psNewHead->psPrevNode = psNewHead; - } - else - { - /* Change the neighbouring nodes */ - psOldHead->psNextNode->psPrevNode = psNewHead; - psOldHead->psPrevNode->psNextNode = psNewHead; - - /* Copy the old data to the new node */ - psNewHead->psNextNode = psOldHead->psNextNode; - psNewHead->psPrevNode = psOldHead->psPrevNode; - - /* Remove links to the previous list */ - psOldHead->psNextNode = psOldHead; - psOldHead->psPrevNode = psOldHead; - } -} - -/**************************************************************************/ /*! -@Function dllist_insert_list_at_head - -@Description Inserts psInHead list into the head of the psOutHead list. - After this operation psOutHead will contain psInHead at the - head of the list and the remaining elements that were - already in psOutHead will be places after the psInList (so - at a tail of the original list). - -@Input psOutHead List node psInHead will be inserted to. -@Input psInHead List node to be inserted to psOutHead. - After this operation this becomes an empty list. -*/ /***************************************************************************/ -static INLINE -void dllist_insert_list_at_head(PDLLIST_NODE psOutHead, PDLLIST_NODE psInHead) -{ - PDLLIST_NODE psInHeadNextNode = psInHead->psNextNode; - PDLLIST_NODE psOutHeadNextNode = psOutHead->psNextNode; - - if (!dllist_is_empty(psInHead)) - { - psOutHead->psNextNode = psInHeadNextNode; - psInHeadNextNode->psPrevNode = psOutHead; - - psInHead->psPrevNode->psNextNode = psOutHeadNextNode; - psOutHeadNextNode->psPrevNode = psInHead->psPrevNode; - - dllist_init(psInHead); - } - } - -/*************************************************************************/ /*! -@Description Pointer to a dllist comparison callback function. -@Input psNode Pointer to a node in a dllist. -@Input psNext Pointer to psNode's next neighbour. -*/ /**************************************************************************/ -typedef bool (*DLLIST_CMP_CB)(const DLLIST_NODE *psNode, const DLLIST_NODE *psNext); - -/*************************************************************************/ /*! -@Function dllist_sort - -@Description Insert-sorts the List in place - The cmpr function passes the current and next node, - From which the user writes the function responsible - for choosing to swap order or not. - The function returns true if a swap is required - -@Input psListHead List Head to be sorted. - -@Input cmpr Function pointer to use for sorting - -*/ -/*****************************************************************************/ -static INLINE void dllist_sort(PDLLIST_NODE psListHead, - DLLIST_CMP_CB cmpr) -{ - DLLIST_NODE *node, *next; - DLLIST_NODE sTempHead; - - dllist_init(&sTempHead); - - dllist_foreach_node(psListHead, node, next) - { - dllist_remove_node(node); - dllist_add_to_head(&sTempHead, node); - } - - while (!dllist_is_empty(&sTempHead)) - { - DLLIST_NODE *psSmallestNode = NULL; - - dllist_foreach_node(&sTempHead, node, next) - { - if (!psSmallestNode || cmpr(psSmallestNode, node)) - { - psSmallestNode = node; - } - } - - dllist_remove_node(psSmallestNode); - dllist_add_to_tail(psListHead, psSmallestNode); - } -} - -#endif /* DLLIST_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/dma_km.h b/drivers/gpu/drm/img-rogue/1.17/dma_km.h deleted file mode 100644 index 185d4ff291948..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/dma_km.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************/ /*! -@File dma_km.h -@Title DMA transfer module header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DMA_KM_H -#define DMA_KM_H - -#if defined(__linux__) -#include -#else -#define KERNEL_VERSION -#endif - -#include "pvrsrv_error.h" -#include "img_types.h" -#include "cache_ops.h" -#include "device.h" -#include "pmr.h" -#include "pvrsrv_sync_km.h" -#include "connection_server.h" - -PVRSRV_ERROR DmaDeviceParams(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 *ui32DmaBuffAlign, - IMG_UINT32 *ui32DmaTransferMult); - -PVRSRV_ERROR DmaSparseMappingTable(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32SizeInPages, - IMG_BOOL *pbTable); - -PVRSRV_ERROR DmaTransfer(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 uiNumDMAs, - PMR** ppsPMR, - IMG_UINT64 *puiAddress, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_BOOL bMemToDev, - PVRSRV_TIMELINE iUpdateTimeline); - -PVRSRV_ERROR PVRSRVInitialiseDMA(PVRSRV_DEVICE_NODE *psDeviceNode); -void PVRSRVDeInitialiseDMA(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* DMA_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/dma_support.c b/drivers/gpu/drm/img-rogue/1.17/dma_support.c deleted file mode 100644 index 16485857148a8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/dma_support.c +++ /dev/null @@ -1,523 +0,0 @@ -/*************************************************************************/ /*! -@File dma_support.c -@Title System DMA support -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides a contiguous memory allocator (i.e. DMA allocator); - APIs are used for allocation/ioremapping (DMA/PA <-> CPU/VA) -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#include - -#include "allocmem.h" -#include "dma_support.h" -#include "pvr_vmap.h" -#include "kernel_compatibility.h" - -#define DMA_MAX_IOREMAP_ENTRIES 2 -static IMG_BOOL gbEnableDmaIoRemapping = IMG_FALSE; -static DMA_ALLOC gsDmaIoRemapArray[DMA_MAX_IOREMAP_ENTRIES] = {{0}}; - -static void* -SysDmaAcquireKernelAddress(struct page *psPage, IMG_UINT64 ui64Size, DMA_ALLOC *psDmaAlloc) -{ - IMG_BOOL bPageByPage = IMG_TRUE; - IMG_UINT32 uiIdx; - void *pvVirtAddr = NULL; - IMG_UINT32 ui32PgCount = (IMG_UINT32)(ui64Size >> OSGetPageShift()); - PVRSRV_DEVICE_NODE *psDevNode = OSAllocZMemNoStats(sizeof(*psDevNode)); - PVRSRV_DEVICE_CONFIG *psDevConfig = OSAllocZMemNoStats(sizeof(*psDevConfig)); - struct page **pagearray = OSAllocZMemNoStats(ui32PgCount * sizeof(struct page *)); - void *pvOSDevice = psDmaAlloc->pvOSDevice; -#if defined(CONFIG_ARM64) - pgprot_t prot = pgprot_writecombine(PAGE_KERNEL); -#else - pgprot_t prot = pgprot_noncached(PAGE_KERNEL); -#endif - - /* Validate all required dynamic tmp buffer allocations */ - if (psDevNode == NULL || psDevConfig == NULL || pagearray == NULL) - { - if (psDevNode) - { - OSFreeMem(psDevNode); - } - - if (psDevConfig) - { - OSFreeMem(psDevConfig); - } - - if (pagearray) - { - OSFreeMem(pagearray); - } - - goto e0; - } - - /* Fake psDevNode->psDevConfig->pvOSDevice */ - psDevConfig->pvOSDevice = pvOSDevice; - psDevNode->psDevConfig = psDevConfig; - - /* Evict any page data contents from d-cache */ - for (uiIdx = 0; uiIdx < ui32PgCount; uiIdx++) - { - void *pvVirtStart, *pvVirtEnd; - IMG_CPU_PHYADDR sCPUPhysStart, sCPUPhysEnd; - - /* Prepare array required for vmap */ - pagearray[uiIdx] = &psPage[uiIdx]; - - if (bPageByPage) - { -#if defined(CONFIG_64BIT) - bPageByPage = IMG_FALSE; - - pvVirtStart = kmap(&psPage[uiIdx]); - pvVirtEnd = pvVirtStart + ui64Size; - - sCPUPhysStart.uiAddr = page_to_phys(&psPage[uiIdx]); - sCPUPhysEnd.uiAddr = sCPUPhysStart.uiAddr + ui64Size; - /* all pages have a kernel linear address, flush entire range */ -#else - pvVirtStart = kmap(&psPage[uiIdx]); - pvVirtEnd = pvVirtStart + PAGE_SIZE; - - sCPUPhysStart.uiAddr = page_to_phys(&psPage[uiIdx]); - sCPUPhysEnd.uiAddr = sCPUPhysStart.uiAddr + PAGE_SIZE; - /* pages might be from HIGHMEM, need to kmap/flush per page */ -#endif - - /* Fallback to range-based d-cache flush */ - OSCPUCacheInvalidateRangeKM(psDevNode, - pvVirtStart, pvVirtEnd, - sCPUPhysStart, sCPUPhysEnd); - - kunmap(&psPage[uiIdx]); - } - } - - /* Remap pages into VMALLOC space */ - pvVirtAddr = pvr_vmap(pagearray, ui32PgCount, VM_READ | VM_WRITE, prot); - psDmaAlloc->PageProps = prot; - - /* Clean-up tmp buffers */ - OSFreeMem(psDevConfig); - OSFreeMem(psDevNode); - OSFreeMem(pagearray); - -e0: - return pvVirtAddr; -} - -static void SysDmaReleaseKernelAddress(void *pvVirtAddr, IMG_UINT64 ui64Size, pgprot_t pgprot) -{ - pvr_vunmap(pvVirtAddr, ui64Size >> OSGetPageShift(), pgprot); -} - -/*! -****************************************************************************** - @Function SysDmaAllocMem - - @Description Allocates physically contiguous memory - - @Return PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code - ******************************************************************************/ -PVRSRV_ERROR SysDmaAllocMem(DMA_ALLOC *psDmaAlloc) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - struct device *psDev; - struct page *psPage; - size_t uiSize; - - if (psDmaAlloc == NULL || - psDmaAlloc->hHandle || - psDmaAlloc->pvVirtAddr || - psDmaAlloc->ui64Size == 0 || - psDmaAlloc->sBusAddr.uiAddr || - psDmaAlloc->pvOSDevice == NULL) - { - PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter"); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE); - psDev = (struct device *)psDmaAlloc->pvOSDevice; - - psDmaAlloc->hHandle = dma_alloc_coherent(psDev, uiSize, (dma_addr_t *)&psDmaAlloc->sBusAddr.uiAddr, GFP_KERNEL); - - if (psDmaAlloc->hHandle) - { - psDmaAlloc->pvVirtAddr = psDmaAlloc->hHandle; - - PVR_DPF((PVR_DBG_MESSAGE, - "Allocated DMA buffer V:0x%p P:0x%llx S:0x"IMG_SIZE_FMTSPECX, - psDmaAlloc->pvVirtAddr, - psDmaAlloc->sBusAddr.uiAddr, - uiSize)); - } - else if ((psPage = alloc_pages(GFP_KERNEL, get_order(uiSize)))) - { - psDmaAlloc->sBusAddr.uiAddr = dma_map_page(psDev, psPage, 0, uiSize, DMA_BIDIRECTIONAL); - if (dma_mapping_error(psDev, psDmaAlloc->sBusAddr.uiAddr)) - { - PVR_DPF((PVR_DBG_ERROR, - "dma_map_page() failed, page 0x%p order %d", - psPage, - get_order(uiSize))); - __free_pages(psPage, get_order(uiSize)); - goto e0; - } - psDmaAlloc->psPage = psPage; - - psDmaAlloc->pvVirtAddr = SysDmaAcquireKernelAddress(psPage, uiSize, psDmaAlloc); - if (! psDmaAlloc->pvVirtAddr) - { - PVR_DPF((PVR_DBG_ERROR, - "SysDmaAcquireKernelAddress() failed, page 0x%p order %d", - psPage, - get_order(uiSize))); - dma_unmap_page(psDev, psDmaAlloc->sBusAddr.uiAddr, uiSize, DMA_BIDIRECTIONAL); - __free_pages(psPage, get_order(uiSize)); - goto e0; - } - - PVR_DPF((PVR_DBG_MESSAGE, - "Allocated contiguous buffer V:0x%p P:0x%llx S:0x"IMG_SIZE_FMTSPECX, - psDmaAlloc->pvVirtAddr, - psDmaAlloc->sBusAddr.uiAddr, - uiSize)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "Unable to allocate contiguous buffer, size: 0x"IMG_SIZE_FMTSPECX, uiSize)); - eError = PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; - } - -e0: - PVR_LOG_RETURN_IF_FALSE((psDmaAlloc->pvVirtAddr), "DMA/CMA allocation failed", PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES); - return eError; -} - -/*! -****************************************************************************** - @Function SysDmaFreeMem - - @Description Free physically contiguous memory - - @Return void - ******************************************************************************/ -void SysDmaFreeMem(DMA_ALLOC *psDmaAlloc) -{ - size_t uiSize; - struct device *psDev; - - if (psDmaAlloc == NULL || - psDmaAlloc->ui64Size == 0 || - psDmaAlloc->pvOSDevice == NULL || - psDmaAlloc->pvVirtAddr == NULL || - psDmaAlloc->sBusAddr.uiAddr == 0) - { - PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter"); - return; - } - - uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE); - psDev = (struct device *)psDmaAlloc->pvOSDevice; - - if (psDmaAlloc->pvVirtAddr != psDmaAlloc->hHandle) - { - SysDmaReleaseKernelAddress(psDmaAlloc->pvVirtAddr, uiSize, psDmaAlloc->PageProps); - } - - if (! psDmaAlloc->hHandle) - { - struct page *psPage; - dma_unmap_page(psDev, psDmaAlloc->sBusAddr.uiAddr, uiSize, DMA_BIDIRECTIONAL); - psPage = psDmaAlloc->psPage; - __free_pages(psPage, get_order(uiSize)); - return; - } - - dma_free_coherent(psDev, uiSize, psDmaAlloc->hHandle, (dma_addr_t )psDmaAlloc->sBusAddr.uiAddr); -} - -/*! -****************************************************************************** - @Function SysDmaRegisterForIoRemapping - - @Description Registers DMA_ALLOC for manual I/O remapping - - @Return PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code - ******************************************************************************/ -PVRSRV_ERROR SysDmaRegisterForIoRemapping(DMA_ALLOC *psDmaAlloc) -{ - size_t uiSize; - IMG_UINT32 ui32Idx; - IMG_BOOL bTabEntryFound = IMG_TRUE; - PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS; - - if (psDmaAlloc == NULL || - psDmaAlloc->ui64Size == 0 || - psDmaAlloc->pvOSDevice == NULL || - psDmaAlloc->pvVirtAddr == NULL || - psDmaAlloc->sBusAddr.uiAddr == 0) - { - PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter"); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE); - - for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx) - { - /* Check if an I/O remap entry exists for remapping */ - if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr == NULL) - { - PVR_ASSERT(gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr == 0); - PVR_ASSERT(gsDmaIoRemapArray[ui32Idx].ui64Size == 0); - break; - } - } - - if (ui32Idx >= DMA_MAX_IOREMAP_ENTRIES) - { - bTabEntryFound = IMG_FALSE; - } - - if (bTabEntryFound) - { - IMG_BOOL bSameVAddr, bSamePAddr, bSameSize; - - bSamePAddr = gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr == psDmaAlloc->sBusAddr.uiAddr; - bSameVAddr = gsDmaIoRemapArray[ui32Idx].pvVirtAddr == psDmaAlloc->pvVirtAddr; - bSameSize = gsDmaIoRemapArray[ui32Idx].ui64Size == uiSize; - - if (bSameVAddr) - { - if (bSamePAddr && bSameSize) - { - eError = PVRSRV_OK; - } - else - { - eError = PVRSRV_ERROR_ALREADY_EXISTS; - } - } - else - { - PVR_ASSERT(bSamePAddr == IMG_FALSE); - - gsDmaIoRemapArray[ui32Idx].ui64Size = uiSize; - gsDmaIoRemapArray[ui32Idx].sBusAddr = psDmaAlloc->sBusAddr; - gsDmaIoRemapArray[ui32Idx].pvVirtAddr = psDmaAlloc->pvVirtAddr; - - PVR_DPF((PVR_DBG_MESSAGE, - "DMA: register I/O remap: " - "VA: 0x%p, PA: 0x%llx, Size: 0x"IMG_SIZE_FMTSPECX, - psDmaAlloc->pvVirtAddr, - psDmaAlloc->sBusAddr.uiAddr, - uiSize)); - - gbEnableDmaIoRemapping = IMG_TRUE; - eError = PVRSRV_OK; - } - } - - return eError; -} - -/*! -****************************************************************************** - @Function SysDmaDeregisterForIoRemapping - - @Description Deregisters DMA_ALLOC from manual I/O remapping - - @Return void - ******************************************************************************/ -void SysDmaDeregisterForIoRemapping(DMA_ALLOC *psDmaAlloc) -{ - size_t __maybe_unused uiSize; - IMG_UINT32 ui32Idx; - - if (psDmaAlloc == NULL || - psDmaAlloc->ui64Size == 0 || - psDmaAlloc->pvOSDevice == NULL || - psDmaAlloc->pvVirtAddr == NULL || - psDmaAlloc->sBusAddr.uiAddr == 0) - { - PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter"); - return; - } - - uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE); - - /* Remove specified entries from list of I/O remap entries */ - for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx) - { - if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr == psDmaAlloc->pvVirtAddr) - { - gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr = 0; - gsDmaIoRemapArray[ui32Idx].pvVirtAddr = NULL; - gsDmaIoRemapArray[ui32Idx].ui64Size = 0; - - PVR_DPF((PVR_DBG_MESSAGE, - "DMA: deregister I/O remap: " - "VA: 0x%p, PA: 0x%llx, Size: 0x"IMG_SIZE_FMTSPECX, - psDmaAlloc->pvVirtAddr, - psDmaAlloc->sBusAddr.uiAddr, - uiSize)); - - break; - } - } - - /* Check if no other I/O remap entries exists for remapping */ - for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx) - { - if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr != NULL) - { - break; - } - } - - if (ui32Idx == DMA_MAX_IOREMAP_ENTRIES) - { - /* No entries found so disable remapping */ - gbEnableDmaIoRemapping = IMG_FALSE; - } -} - -/*! -****************************************************************************** - @Function SysDmaDevPAddrToCpuVAddr - - @Description Maps a DMA_ALLOC physical address to CPU virtual address - - @Return IMG_CPU_VIRTADDR on success. Otherwise, a NULL - ******************************************************************************/ -IMG_CPU_VIRTADDR SysDmaDevPAddrToCpuVAddr(IMG_UINT64 uiAddr, IMG_UINT64 ui64Size) -{ - IMG_CPU_VIRTADDR pvDMAVirtAddr = NULL; - DMA_ALLOC *psHeapDmaAlloc; - IMG_UINT32 ui32Idx; - - if (gbEnableDmaIoRemapping == IMG_FALSE) - { - return pvDMAVirtAddr; - } - - for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx) - { - psHeapDmaAlloc = &gsDmaIoRemapArray[ui32Idx]; - if (psHeapDmaAlloc->sBusAddr.uiAddr && uiAddr >= psHeapDmaAlloc->sBusAddr.uiAddr) - { - IMG_UINT64 uiSpan = psHeapDmaAlloc->ui64Size; - IMG_UINT64 uiOffset = uiAddr - psHeapDmaAlloc->sBusAddr.uiAddr; - - if (uiOffset < uiSpan) - { - PVR_ASSERT((uiOffset+ui64Size-1) < uiSpan); - pvDMAVirtAddr = psHeapDmaAlloc->pvVirtAddr + uiOffset; - - PVR_DPF((PVR_DBG_MESSAGE, - "DMA: remap: PA: 0x%llx => VA: 0x%p", - uiAddr, pvDMAVirtAddr)); - - break; - } - } - } - - return pvDMAVirtAddr; -} - -/*! -****************************************************************************** - @Function SysDmaCpuVAddrToDevPAddr - - @Description Maps a DMA_ALLOC CPU virtual address to physical address - - @Return Non-zero value on success. Otherwise, a 0 - ******************************************************************************/ -IMG_UINT64 SysDmaCpuVAddrToDevPAddr(IMG_CPU_VIRTADDR pvDMAVirtAddr) -{ - IMG_UINT64 uiAddr = 0; - DMA_ALLOC *psHeapDmaAlloc; - IMG_UINT32 ui32Idx; - - if (gbEnableDmaIoRemapping == IMG_FALSE) - { - return uiAddr; - } - - for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx) - { - psHeapDmaAlloc = &gsDmaIoRemapArray[ui32Idx]; - if (psHeapDmaAlloc->pvVirtAddr && pvDMAVirtAddr >= psHeapDmaAlloc->pvVirtAddr) - { - IMG_UINT64 uiSpan = psHeapDmaAlloc->ui64Size; - IMG_UINT64 uiOffset = pvDMAVirtAddr - psHeapDmaAlloc->pvVirtAddr; - - if (uiOffset < uiSpan) - { - uiAddr = psHeapDmaAlloc->sBusAddr.uiAddr + uiOffset; - - PVR_DPF((PVR_DBG_MESSAGE, - "DMA: remap: VA: 0x%p => PA: 0x%llx", - pvDMAVirtAddr, uiAddr)); - - break; - } - } - } - - return uiAddr; -} - -/****************************************************************************** - End of file (dma_support.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/dma_support.h b/drivers/gpu/drm/img-rogue/1.17/dma_support.h deleted file mode 100644 index c1d22bddf5236..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/dma_support.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************/ /*! -@File dma_support.h -@Title Device contiguous memory allocator and I/O re-mapper -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides a contiguous memory allocator API; mainly - used for allocating / ioremapping (DMA/PA <-> CPU/VA) -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 DMA_SUPPORT_H -#define DMA_SUPPORT_H - -#include "osfunc.h" -#include "pvrsrv.h" - -typedef struct _DMA_ALLOC_ -{ - IMG_UINT64 ui64Size; - IMG_CPU_VIRTADDR pvVirtAddr; - IMG_DEV_PHYADDR sBusAddr; - IMG_HANDLE hHandle; -#if defined(__linux__) - struct page *psPage; - pgprot_t PageProps; -#endif - void *pvOSDevice; -} DMA_ALLOC; - -/*! -******************************************************************************* - @Function SysDmaAllocMem - @Description Allocates physically contiguous memory - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR SysDmaAllocMem(DMA_ALLOC *psDmaAlloc); - -/*! -******************************************************************************* - @Function SysDmaFreeMem - @Description Free physically contiguous memory - @Return void -******************************************************************************/ -void SysDmaFreeMem(DMA_ALLOC *psCmaAlloc); - -/*! -******************************************************************************* - @Function SysDmaRegisterForIoRemapping - @Description Registers DMA_ALLOC for manual I/O remapping - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR SysDmaRegisterForIoRemapping(DMA_ALLOC *psPhysHeapDmaAlloc); - -/*! -******************************************************************************* - @Function SysDmaDeregisterForIoRemapping - @Description Deregisters DMA_ALLOC from manual I/O remapping - @Return void -******************************************************************************/ -void SysDmaDeregisterForIoRemapping(DMA_ALLOC *psPhysHeapDmaAlloc); - -/*! -******************************************************************************* - @Function SysDmaDevPAddrToCpuVAddr - @Description Maps a DMA_ALLOC physical address to CPU virtual address - @Return IMG_CPU_VIRTADDR on success. Otherwise, a NULL -******************************************************************************/ -IMG_CPU_VIRTADDR -SysDmaDevPAddrToCpuVAddr(IMG_UINT64 uiAddr, IMG_UINT64 ui64Size); - -/*! -******************************************************************************* - @Function SysDmaCpuVAddrToDevPAddr - @Description Maps a DMA_ALLOC CPU virtual address to physical address - @Return Non-zero value on success. Otherwise, a 0 -******************************************************************************/ -IMG_UINT64 SysDmaCpuVAddrToDevPAddr(IMG_CPU_VIRTADDR pvDMAVirtAddr); - -#endif /* DMA_SUPPORT_H */ - -/****************************************************************************** - End of file (dma_support.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/env_connection.h b/drivers/gpu/drm/img-rogue/1.17/env_connection.h deleted file mode 100644 index 2a6c7d05c4126..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/env_connection.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Server side connection management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Linux specific server side connection management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(ENV_CONNECTION_H) -#define ENV_CONNECTION_H - -#include -#include -#include - -#include "handle.h" -#include "pvr_debug.h" -#include "device.h" - -#if defined(SUPPORT_ION) -#include PVR_ANDROID_ION_HEADER -#include "ion_sys.h" -#include "allocmem.h" -#endif - -typedef struct _ENV_CONNECTION_PRIVATE_DATA_ -{ - PVRSRV_DEVICE_NODE *psDevNode; -} ENV_CONNECTION_PRIVATE_DATA; - -#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) -#define ION_CLIENT_NAME_SIZE 50 - -typedef struct _ENV_ION_CONNECTION_DATA_ -{ - IMG_CHAR azIonClientName[ION_CLIENT_NAME_SIZE]; - struct ion_device *psIonDev; - struct ion_client *psIonClient; -} ENV_ION_CONNECTION_DATA; -#endif - -typedef struct _ENV_CONNECTION_DATA_ -{ - pid_t owner; - - PVRSRV_DEVICE_NODE *psDevNode; - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - void *pvPvrSyncPrivateData; -#endif - -#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - ENV_ION_CONNECTION_DATA *psIonData; -#endif -} ENV_CONNECTION_DATA; - -#endif /* !defined(ENV_CONNECTION_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/event.c b/drivers/gpu/drm/img-rogue/1.17/event.c deleted file mode 100644 index aec0fc8a02dda..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/event.c +++ /dev/null @@ -1,514 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Event Object -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) -#include -#endif -#include -#include -#include -#include -#include -#include - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "allocmem.h" -#include "event.h" -#include "pvr_debug.h" -#include "pvrsrv.h" -#include "pvr_bridge_k.h" - -#include "osfunc.h" - -/* Uncomment to enable event object stats that are useful for debugging. - * The stats can be gotten at any time (during lifetime of event object) - * using OSEventObjectDumpdebugInfo API */ -// #define LINUX_EVENT_OBJECT_STATS - - -typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG -{ - rwlock_t sLock; - /* Counts how many times event object was signalled i.e. how many times - * LinuxEventObjectSignal() was called on a given event object. - * Used for detecting pending signals. - * Note that this is in no way related to OS signals. */ - atomic_t sEventSignalCount; - struct list_head sList; -} PVRSRV_LINUX_EVENT_OBJECT_LIST; - - -typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG -{ - IMG_UINT32 ui32EventSignalCountPrevious; -#if defined(DEBUG) - IMG_UINT ui32Stats; -#endif - -#ifdef LINUX_EVENT_OBJECT_STATS - POS_LOCK hLock; - IMG_UINT32 ui32ScheduleAvoided; - IMG_UINT32 ui32ScheduleCalled; - IMG_UINT32 ui32ScheduleSleptFully; - IMG_UINT32 ui32ScheduleSleptPartially; - IMG_UINT32 ui32ScheduleReturnedImmediately; -#endif - wait_queue_head_t sWait; - struct list_head sList; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList; -} PVRSRV_LINUX_EVENT_OBJECT; - -/*! -****************************************************************************** - - @Function LinuxEventObjectListCreate - - @Description - - Linux wait object list creation - - @Output hOSEventKM : Pointer to the event object list handle - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList) -{ - PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList; - - psEvenObjectList = OSAllocMem(sizeof(*psEvenObjectList)); - if (psEvenObjectList == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - INIT_LIST_HEAD(&psEvenObjectList->sList); - - rwlock_init(&psEvenObjectList->sLock); - atomic_set(&psEvenObjectList->sEventSignalCount, 0); - - *phEventObjectList = (IMG_HANDLE *) psEvenObjectList; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function LinuxEventObjectListDestroy - - @Description - - Linux wait object list destruction - - @Input hOSEventKM : Event object list handle - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList) -{ - PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList; - - if (psEvenObjectList) - { - if (!list_empty(&psEvenObjectList->sList)) - { - PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty")); - return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; - } - OSFreeMem(psEvenObjectList); - /*not nulling pointer, copy on stack*/ - } - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function LinuxEventObjectDelete - - @Description - - Linux wait object removal - - @Input hOSEventObject : Event object handle - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject) -{ - if (hOSEventObject) - { - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList; - - write_lock_bh(&psLinuxEventObjectList->sLock); - list_del(&psLinuxEventObject->sList); - write_unlock_bh(&psLinuxEventObjectList->sLock); - -#ifdef LINUX_EVENT_OBJECT_STATS - OSLockDestroy(psLinuxEventObject->hLock); -#endif - -#if defined(DEBUG) -// PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDelete: Event object waits: %u", psLinuxEventObject->ui32Stats)); -#endif - - OSFreeMem(psLinuxEventObject); - /*not nulling pointer, copy on stack*/ - - return PVRSRV_OK; - } - return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; -} - -/*! -****************************************************************************** - - @Function LinuxEventObjectAdd - - @Description - - Linux wait object addition - - @Input hOSEventObjectList : Event object list handle - @Output phOSEventObject : Pointer to the event object handle - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject) - { - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; - - /* allocate completion variable */ - psLinuxEventObject = OSAllocMem(sizeof(*psLinuxEventObject)); - if (psLinuxEventObject == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - INIT_LIST_HEAD(&psLinuxEventObject->sList); - - /* Start with the timestamp at which event object was added to the list */ - psLinuxEventObject->ui32EventSignalCountPrevious = atomic_read(&psLinuxEventObjectList->sEventSignalCount); - -#ifdef LINUX_EVENT_OBJECT_STATS - PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&psLinuxEventObject->hLock), "OSLockCreate"); - psLinuxEventObject->ui32ScheduleAvoided = 0; - psLinuxEventObject->ui32ScheduleCalled = 0; - psLinuxEventObject->ui32ScheduleSleptFully = 0; - psLinuxEventObject->ui32ScheduleSleptPartially = 0; - psLinuxEventObject->ui32ScheduleReturnedImmediately = 0; -#endif - -#if defined(DEBUG) - psLinuxEventObject->ui32Stats = 0; -#endif - init_waitqueue_head(&psLinuxEventObject->sWait); - - psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList; - - write_lock_bh(&psLinuxEventObjectList->sLock); - list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList); - write_unlock_bh(&psLinuxEventObjectList->sLock); - - *phOSEventObject = psLinuxEventObject; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function LinuxEventObjectSignal - - @Description - - Linux wait object signaling function - - @Input hOSEventObjectList : Event object list handle - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList) -{ - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; - struct list_head *psListEntry, *psListEntryTemp, *psList; - psList = &psLinuxEventObjectList->sList; - - /* Move the timestamp ahead for this call, so a potential "Wait" from any - * EventObject/s doesn't wait for the signal to occur before returning. Early - * setting/incrementing of timestamp reduces the window where a concurrent - * "Wait" call might block while "this" Signal call is being processed */ - atomic_inc(&psLinuxEventObjectList->sEventSignalCount); - - read_lock_bh(&psLinuxEventObjectList->sLock); - list_for_each_safe(psListEntry, psListEntryTemp, psList) - { - psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList); - wake_up_interruptible(&psLinuxEventObject->sWait); - } - read_unlock_bh(&psLinuxEventObjectList->sLock); - - return PVRSRV_OK; -} - -static void _TryToFreeze(void) -{ - /* if we reach zero it means that all of the threads called try_to_freeze */ - LinuxBridgeNumActiveKernelThreadsDecrement(); - - /* Returns true if the thread was frozen, should we do anything with this - * information? What do we return? Which one is the error case? */ - try_to_freeze(); - - LinuxBridgeNumActiveKernelThreadsIncrement(); -} - -void LinuxEventObjectDumpDebugInfo(IMG_HANDLE hOSEventObject) -{ -#ifdef LINUX_EVENT_OBJECT_STATS - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; - - OSLockAcquire(psLinuxEventObject->hLock); - PVR_LOG(("%s: EvObj(%p) schedule: Avoided(%u) Called(%u) ReturnedImmediately(%u) SleptFully(%u) SleptPartially(%u)", - __func__, psLinuxEventObject, psLinuxEventObject->ui32ScheduleAvoided, - psLinuxEventObject->ui32ScheduleCalled, psLinuxEventObject->ui32ScheduleReturnedImmediately, - psLinuxEventObject->ui32ScheduleSleptFully, psLinuxEventObject->ui32ScheduleSleptPartially)); - OSLockRelease(psLinuxEventObject->hLock); -#else - PVR_LOG(("%s: LINUX_EVENT_OBJECT_STATS disabled!", __func__)); -#endif -} - -/*! -****************************************************************************** - - @Function LinuxEventObjectWait - - @Description - - Linux wait object routine - - @Input hOSEventObject : Event object handle - - @Input ui64Timeoutus : Time out value in usec - - @Return PVRSRV_ERROR : Error code - -******************************************************************************/ -PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, - IMG_UINT64 ui64Timeoutus, - IMG_BOOL bFreezable) -{ - IMG_UINT32 ui32EventSignalCount; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_UINT32 ui32Remainder; - long timeOutJiffies; -#ifdef LINUX_EVENT_OBJECT_STATS - long totalTimeoutJiffies; - IMG_BOOL bScheduleCalled = IMG_FALSE; -#endif - - DEFINE_WAIT(sWait); - - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList; - - /* Check if the driver is good shape */ - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - /* usecs_to_jiffies only takes an uint. So if our timeout is bigger than an - * uint use the msec version. With such a long timeout we really don't need - * the high resolution of usecs. */ - if (ui64Timeoutus > 0xffffffffULL) - timeOutJiffies = msecs_to_jiffies(OSDivide64(ui64Timeoutus, 1000, &ui32Remainder)); - else - timeOutJiffies = usecs_to_jiffies(ui64Timeoutus); - -#ifdef LINUX_EVENT_OBJECT_STATS - totalTimeoutJiffies = timeOutJiffies; -#endif - - do - { - prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE); - ui32EventSignalCount = (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount); - - if (psLinuxEventObject->ui32EventSignalCountPrevious != ui32EventSignalCount) - { - /* There is a pending event signal i.e. LinuxEventObjectSignal() - * was called on the event object since the last time we checked. - * Return without waiting. */ - break; - } - - if (signal_pending(current)) - { - /* There is an OS signal pending so return. - * This allows to kill/interrupt user space processes which - * are waiting on this event object. */ - break; - } - -#ifdef LINUX_EVENT_OBJECT_STATS - bScheduleCalled = IMG_TRUE; -#endif - timeOutJiffies = schedule_timeout(timeOutJiffies); - - if (bFreezable) - { - _TryToFreeze(); - } - -#if defined(DEBUG) - psLinuxEventObject->ui32Stats++; -#endif - - - } while (timeOutJiffies); - - finish_wait(&psLinuxEventObject->sWait, &sWait); - - psLinuxEventObject->ui32EventSignalCountPrevious = ui32EventSignalCount; - -#ifdef LINUX_EVENT_OBJECT_STATS - OSLockAcquire(psLinuxEventObject->hLock); - if (bScheduleCalled) - { - psLinuxEventObject->ui32ScheduleCalled++; - if (totalTimeoutJiffies == timeOutJiffies) - { - psLinuxEventObject->ui32ScheduleReturnedImmediately++; - } - else if (timeOutJiffies == 0) - { - psLinuxEventObject->ui32ScheduleSleptFully++; - } - else - { - psLinuxEventObject->ui32ScheduleSleptPartially++; - } - } - else - { - psLinuxEventObject->ui32ScheduleAvoided++; - } - OSLockRelease(psLinuxEventObject->hLock); -#endif - - if (signal_pending(current)) - { - return PVRSRV_ERROR_INTERRUPTED; - } - else - { - return timeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT; - } -} - -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - -PVRSRV_ERROR LinuxEventObjectWaitUntilSignalled(IMG_HANDLE hOSEventObject) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - DEFINE_WAIT(sWait); - - PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = - (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject; - PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = - psLinuxEventObject->psLinuxEventObjectList; - - /* Check if the driver is in good shape */ - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE); - - if (psLinuxEventObject->ui32EventSignalCountPrevious != - (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount)) - { - /* There is a pending signal, so return without waiting */ - goto finish; - } - - schedule(); - - _TryToFreeze(); - -finish: - finish_wait(&psLinuxEventObject->sWait, &sWait); - - psLinuxEventObject->ui32EventSignalCountPrevious = - (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount); - - return PVRSRV_OK; -} - -#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/event.h b/drivers/gpu/drm/img-rogue/1.17/event.h deleted file mode 100644 index bb378cb9220f4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/event.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Event Object -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList); -PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList); -PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject); -PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject); -PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList); -PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, - IMG_UINT64 ui64Timeoutus, - IMG_BOOL bFreezable); -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) -PVRSRV_ERROR LinuxEventObjectWaitUntilSignalled(IMG_HANDLE hOSEventObject); -#endif -void LinuxEventObjectDumpDebugInfo(IMG_HANDLE hOSEventObject); diff --git a/drivers/gpu/drm/img-rogue/1.17/fwload.c b/drivers/gpu/drm/img-rogue/1.17/fwload.c deleted file mode 100644 index 35e52af56a2e8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/fwload.c +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services firmware load and access routines for Linux -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "device.h" -#include "module_common.h" -#include "fwload.h" -#include "pvr_debug.h" -#include "srvkm.h" - -#if defined(RGX_FW_SIGNED) - -#include -#include -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -#include -#else -#define PKEY_ID_PKCS7 2 -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) */ - -#include "signfw.h" -#endif /* RGX_FW_SIGNED */ - -struct OS_FW_IMAGE_t -{ - const struct firmware *psFW; - size_t uSignatureSize; -}; - -#if defined(RGX_FW_SIGNED) - -static int OSCheckSignature(const struct FirmwareSignatureHeader *psHeader, size_t uSize) -{ - if (be32_to_cpu(psHeader->ui32SignatureLen) >= uSize - sizeof(*psHeader)) - { - return -EBADMSG; - } - - if (psHeader->ui8IDType != PKEY_ID_PKCS7) - { - return -ENOPKG; - } - - if (psHeader->ui8Algo != 0 || psHeader->ui8HashAlgo != 0 || - psHeader->ui8SignerLen != 0 || psHeader->ui8KeyIDLen != 0 || - psHeader->__ui8Padding[0] != 0 || psHeader->__ui8Padding[1] != 0 || - psHeader->__ui8Padding[2] != 0) - { - return -EBADMSG; - } - - return 0; -} - -bool OSVerifyFirmware(OS_FW_IMAGE *psFWImage) -{ - const struct firmware *psFW = psFWImage->psFW; - const u8 *pui8FWData = psFW->data; - size_t uFWSize = psFW->size; - uint32_t ui32MagicLen = sizeof(MODULE_SIG_STRING) - 1; - struct FirmwareSignatureHeader sHeader; - int err; - - if (uFWSize <= ui32MagicLen) - { - return false; - } - - /* - * Linux Kernel's sign-file utility is primarily intended for signing - * modules, and so appends the MODULE_SIG_STRING magic at the end of - * the signature. Only proceed with verification if this magic is found. - */ - if (memcmp(pui8FWData + uFWSize - ui32MagicLen, MODULE_SIG_STRING, ui32MagicLen) != 0) - { - return false; - } - - uFWSize -= ui32MagicLen; - if (uFWSize <= sizeof(sHeader)) - { - return false; - } - - /* - * After the magic, a header is placed which informs about the digest / - * crypto algorithm etc. Copy that header and ensure that it has valid - * contents (We only support RSA Crypto, SHA Hash, X509 certificate and - * PKCS#7 signature). - */ - memcpy(&sHeader, pui8FWData + (uFWSize - sizeof(sHeader)), sizeof(sHeader)); - if (OSCheckSignature(&sHeader, uFWSize) != 0) - { - return false; - } - - /* - * As all information is now extracted, we can go ahead and ask PKCS - * module to verify the sign. - */ - uFWSize -= be32_to_cpu(sHeader.ui32SignatureLen) + sizeof(sHeader); - err = verify_pkcs7_signature(pui8FWData, uFWSize, pui8FWData + uFWSize, - be32_to_cpu(sHeader.ui32SignatureLen), NULL, - VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL); - if (err == 0) - { - psFWImage->uSignatureSize = psFW->size - uFWSize; - PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware Successfully Verified", - __func__)); - return true; - } - - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Verification Failed (%d)", - __func__, err)); - return false; -} - -#else /* defined(RGX_FW_SIGNED) */ - -inline bool OSVerifyFirmware(OS_FW_IMAGE *psFWImage) -{ - return true; -} - -#endif /* defined(RGX_FW_SIGNED) */ - -PVRSRV_ERROR -OSLoadFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, const IMG_CHAR *pszBVNCString, - bool (*pfnVerifyFirmware)(OS_FW_IMAGE*), OS_FW_IMAGE **ppsFWImage) -{ - const struct firmware *psFW = NULL; - OS_FW_IMAGE *psFWImage; - IMG_INT32 res; - PVRSRV_ERROR eError; - - res = request_firmware(&psFW, pszBVNCString, psDeviceNode->psDevConfig->pvOSDevice); - if (res != 0) - { - release_firmware(psFW); - if (res == -ENOENT) - { - PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') not found (%d)", - __func__, pszBVNCString, res)); - eError = PVRSRV_ERROR_NOT_FOUND; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') not ready (%d)", - __func__, pszBVNCString, res)); - eError = PVRSRV_ERROR_NOT_READY; - } - goto err_exit; - } - - psFWImage = OSAllocZMem(sizeof(*psFWImage)); - if (psFWImage == NULL) - { - PVR_DPF((PVR_DBG_WARNING, "%s: OSAllocZMem('%s') failed.", - __func__, pszBVNCString)); - - release_firmware(psFW); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_exit; - } - - psFWImage->psFW = psFW; - if (pfnVerifyFirmware != NULL && !pfnVerifyFirmware(psFWImage)) - { - release_firmware(psFW); - OSFreeMem(psFWImage); - eError = PVRSRV_ERROR_NOT_AUTHENTICATED; - goto err_exit; - } - - *ppsFWImage = psFWImage; - return PVRSRV_OK; - -err_exit: - *ppsFWImage = NULL; - return eError; -} - -void -OSUnloadFirmware(OS_FW_IMAGE *psFWImage) -{ - const struct firmware *psFW = psFWImage->psFW; - - release_firmware(psFW); - OSFreeMem(psFWImage); -} - -size_t -OSFirmwareSize(OS_FW_IMAGE *psFWImage) -{ - const struct firmware *psFW = psFWImage->psFW; - return psFW->size - psFWImage->uSignatureSize; -} - -const void * -OSFirmwareData(OS_FW_IMAGE *psFWImage) -{ - const struct firmware *psFW = psFWImage->psFW; - - return psFW->data; -} - -/****************************************************************************** - End of file (fwload.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/fwload.h b/drivers/gpu/drm/img-rogue/1.17/fwload.h deleted file mode 100644 index 08e7f533b6663..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/fwload.h +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services RGX OS Interface for loading the firmware -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This file defines the OS interface through which the RGX - device initialisation code in the kernel/server will obtain - the RGX firmware binary image. The API is used during the - initialisation of an RGX device via the - PVRSRVCommonDeviceInitialise() - call sequence. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 FWLOAD_H -#define FWLOAD_H - -#include "img_defs.h" -#include "device_connection.h" -#include "device.h" - -/*! Opaque type handle defined and known to the OS layer implementation of this - * fwload.h OS API. This private data is allocated in the implementation of - * OSLoadFirmware() and contains whatever data and information needed to be - * able to acquire and return the firmware binary image to the Services - * kernel/server during initialisation. - * It is no longer required and may be freed when OSUnloadFirmware() is called. - */ -typedef struct OS_FW_IMAGE_t OS_FW_IMAGE; - -#if defined(__linux__) - -bool OSVerifyFirmware(OS_FW_IMAGE* psFWImage); - -#endif - -/*************************************************************************/ /*! -@Function OSLoadFirmware -@Description The OS implementation must load or acquire the firmware (FW) - image binary needed by the driver stack. - A handle to the common layer device node is given to identify - which device instance in the system is being initialised. The - BVNC string is also supplied so that the implementation knows - which FW image to retrieve since each FW image only supports one - GPU type/revision. - The calling server code supports multiple GPU types and revisions - and will detect the specific GPU type and revision before calling - this API. It will also have runtime configuration of the VZ mode, - hence this API must be able to retrieve different FW binary - images based on the pszBVNCString given. The purpose of the end - platform/system is key to understand which FW images must be - available to the kernel server. - On exit the implementation must return a pointer to some private - data it uses to hold the FW image information and data. It will - be passed onto later API calls by the kernel server code. - NULL should be returned if the FW image could not be retrieved. - The format of the BVNC string is as follows ([x] denotes - optional field): - "rgx.fw[.signed].B.V[p].N.C[.vz]" - The implementation must first try to load the FW identified - by the pszBVpNCString parameter. If this is not available then it - should drop back to retrieving the FW identified by the - pszBVNCString parameter. The fields in the string are: - B, V, N, C are all unsigned integer identifying type/revision. - [.signed] is present when RGX_FW_SIGNED=1 is defined in the - server build. - [p] denotes a provisional (pre-silicon) GPU configuration. - [.vz] is present when the kernel server is loaded on the HOST - of a virtualised platform. See the DriverMode server - AppHint for details. - -@Input psDeviceNode Device instance identifier. -@Input pszBVNCString Identifier string of the FW image to - be loaded/acquired in production driver. -@Input pfnVerifyFirmware Callback which checks validity of FW image. -@Output ppsFWImage Ptr to private data on success, - NULL otherwise. -@Return PVRSRV_ERROR PVRSRV_OK on success, - PVRSRV_ERROR_NOT_READY if filesystem is not - ready/initialised, - PVRSRV_ERROR_NOT_FOUND if no suitable FW - image could be found - PVRSRV_ERROR_OUT_OF_MEMORY if unable to alloc - memory for FW image - PVRSRV_ERROR_NOT_AUTHENTICATED if FW image - cannot be verified. -*/ /**************************************************************************/ -PVRSRV_ERROR OSLoadFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszBVNCString, - bool (*pfnVerifyFirmware)(OS_FW_IMAGE*), - OS_FW_IMAGE **ppsFWImage); - -/*************************************************************************/ /*! -@Function OSFirmwareData -@Description This function returns a pointer to the start of the FW image - binary data held in memory. It must remain valid until - OSUnloadFirmware() is called. -@Input psFWImage Private data opaque handle -@Return void* Ptr to FW binary image to start on GPU. -*/ /**************************************************************************/ -const void* OSFirmwareData(OS_FW_IMAGE *psFWImage); - -/*************************************************************************/ /*! -@Function OSFirmwareSize -@Description This function returns the size of the FW image binary data. -@Input psFWImage Private data opaque handle -@Return size_t Size in bytes of the firmware binary image -*/ /**************************************************************************/ -size_t OSFirmwareSize(OS_FW_IMAGE *psFWImage); - -/*************************************************************************/ /*! -@Function OSUnloadFirmware -@Description This is called when the server has completed firmware - initialisation and no longer needs the private data, possibly - allocated by OSLoadFirmware(). -@Input psFWImage Private data opaque handle -*/ /**************************************************************************/ -void OSUnloadFirmware(OS_FW_IMAGE *psFWImage); - -#endif /* FWLOAD_H */ - -/****************************************************************************** - End of file (fwload.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/fwtrace_string.h b/drivers/gpu/drm/img-rogue/1.17/fwtrace_string.h deleted file mode 100644 index a2ab95c3a8159..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/fwtrace_string.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ /*! -@File fwtrace_string.h -@Title RGX Firmware trace strings for KM -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Platform Generic -@Description This file defines SFs tuple. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 KM_TRACE_STRING_H -#define KM_TRACE_STRING_H - -#include "rgx_fwif_sf.h" - -extern const RGXKM_STID_FMT SFs[]; -extern const IMG_UINT32 g_ui32SFsCount; - -#endif /* KM_TRACE_STRING_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/handle.c b/drivers/gpu/drm/img-rogue/1.17/handle.c deleted file mode 100644 index 6369ed6e46051..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/handle.c +++ /dev/null @@ -1,2486 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Resource Handle Manager -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide resource handle management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -/* See handle.h for a description of the handle API. */ - -/* - * The implementation supports movable handle structures, allowing the address - * of a handle structure to change without having to fix up pointers in - * any of the handle structures. For example, the linked list mechanism - * used to link subhandles together uses handle array indices rather than - * pointers to the structures themselves. - */ - -#if defined(__linux__) -#include -#else -#include -#endif - -#include "img_defs.h" -#include "handle.h" -#include "handle_impl.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "osfunc.h" -#include "lock.h" -#include "connection_server.h" - -#define HANDLE_HASH_TAB_INIT_SIZE 32 -#define HANDLE_PROC_HANDLE_HASH_INIT_SIZE 10 - -#define TEST_FLAG(v, f) BITMASK_HAS(v, f) -#define TEST_ALLOC_FLAG(psHandleData, f) BITMASK_HAS((psHandleData)->eFlag, f) - - -/* Linked list structure. Used for both the list head and list items */ -typedef struct _HANDLE_LIST_ -{ - IMG_HANDLE hPrev; - IMG_HANDLE hNext; - IMG_HANDLE hParent; -} HANDLE_LIST; - -typedef struct _HANDLE_DATA_ -{ - /* The handle that represents this structure */ - IMG_HANDLE hHandle; - - /* Handle type */ - PVRSRV_HANDLE_TYPE eType; - - /* Flags specified when the handle was allocated */ - PVRSRV_HANDLE_ALLOC_FLAG eFlag; - - /* Pointer to the data that the handle represents */ - void *pvData; - - /* - * Callback specified at handle allocation time to - * release/destroy/free the data represented by the - * handle when it's reference count reaches 0. This - * should always be NULL for subhandles. - */ - PFN_HANDLE_RELEASE pfnReleaseData; - - /* List head for subhandles of this handle */ - HANDLE_LIST sChildren; - - /* List entry for sibling subhandles */ - HANDLE_LIST sSiblings; - - /* Reference count of lookups made. It helps track which resources are in - * use in concurrent bridge calls. */ - IMG_INT32 iLookupCount; - /* State of a handle. If the handle was already destroyed this is false. - * If this is false and iLookupCount is 0 the pfnReleaseData callback is - * called on the handle. */ - IMG_BOOL bCanLookup; - -#if defined(PVRSRV_DEBUG_HANDLE_LOCK) - /* Store the handle base used for this handle, so we - * can later access the handle base lock (or check if - * it has been already acquired) - */ - PVRSRV_HANDLE_BASE *psBase; -#endif - -} HANDLE_DATA; - -struct _HANDLE_BASE_ -{ - /* Pointer to a handle implementations base structure */ - HANDLE_IMPL_BASE *psImplBase; - - /* - * Pointer to handle hash table. - * The hash table is used to do reverse lookups, converting data - * pointers to handles. - */ - HASH_TABLE *psHashTab; - - /* Type specific (connection/global/process) Lock handle */ - POS_LOCK hLock; - - /* Can be connection, process, global */ - PVRSRV_HANDLE_BASE_TYPE eType; -}; - -/* - * The key for the handle hash table is an array of three elements, the - * pointer to the resource, the resource type and the parent handle (or - * NULL if there is no parent). The eHandKey enumeration gives the - * array indices of the elements making up the key. - */ -enum eHandKey -{ - HAND_KEY_DATA = 0, - HAND_KEY_TYPE, - HAND_KEY_PARENT, - HAND_KEY_LEN /* Must be last item in list */ -}; - -/* HAND_KEY is the type of the hash table key */ -typedef uintptr_t HAND_KEY[HAND_KEY_LEN]; - -typedef struct FREE_HANDLE_DATA_TAG -{ - PVRSRV_HANDLE_BASE *psBase; - PVRSRV_HANDLE_TYPE eHandleFreeType; - /* timing data (ns) to release bridge lock upon the deadline */ - IMG_UINT64 ui64TimeStart; - IMG_UINT64 ui64MaxBridgeTime; -} FREE_HANDLE_DATA; - -typedef struct FREE_KERNEL_HANDLE_DATA_TAG -{ - PVRSRV_HANDLE_BASE *psBase; - HANDLE_DATA *psProcessHandleData; - IMG_HANDLE hKernelHandle; -} FREE_KERNEL_HANDLE_DATA; - -/* Stores a pointer to the function table of the handle back-end in use */ -static HANDLE_IMPL_FUNCTAB const *gpsHandleFuncs; - -static POS_LOCK gKernelHandleLock; -static IMG_BOOL gbLockInitialised = IMG_FALSE; -/* Pointer to process handle base currently being freed */ -static PVRSRV_HANDLE_BASE *g_psProcessHandleBaseBeingFreed; -/* Lock for the process handle base table */ -static POS_LOCK g_hProcessHandleBaseLock; -/* Hash table with process handle bases */ -static HASH_TABLE *g_psProcessHandleBaseTable; - -void LockHandle(PVRSRV_HANDLE_BASE *psBase) -{ - OSLockAcquire(psBase->hLock); -} - -void UnlockHandle(PVRSRV_HANDLE_BASE *psBase) -{ - OSLockRelease(psBase->hLock); -} - -/* - * Kernel handle base structure. This is used for handles that are not - * allocated on behalf of a particular process. - */ -PVRSRV_HANDLE_BASE *gpsKernelHandleBase = NULL; - -/* Increase the lookup reference count on the given handle. - * The handle lock must already be acquired. - * Returns: the reference count after the increment - */ -static inline IMG_UINT32 HandleGet(HANDLE_DATA *psHandleData) -{ -#if defined(PVRSRV_DEBUG_HANDLE_LOCK) - if (!OSLockIsLocked(psHandleData->psBase->hLock)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__)); - OSDumpStack(); - } -#endif - -#ifdef DEBUG_REFCNT - PVR_DPF((PVR_DBG_ERROR, "%s: bCanLookup = %u, iLookupCount %d -> %d", - __func__, psHandleData->bCanLookup, psHandleData->iLookupCount, - psHandleData->iLookupCount + 1)); -#endif /* DEBUG_REFCNT */ - - PVR_ASSERT(psHandleData->bCanLookup); - - return ++psHandleData->iLookupCount; -} - -/* Decrease the lookup reference count on the given handle. - * The handle lock must already be acquired. - * Returns: the reference count after the decrement - */ -static inline IMG_UINT32 HandlePut(HANDLE_DATA *psHandleData) -{ -#if defined(PVRSRV_DEBUG_HANDLE_LOCK) - if (!OSLockIsLocked(psHandleData->psBase->hLock)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__)); - OSDumpStack(); - } -#endif - -#ifdef DEBUG_REFCNT - PVR_DPF((PVR_DBG_ERROR, "%s: bCanLookup = %u, iLookupCount %d -> %d", - __func__, psHandleData->bCanLookup, psHandleData->iLookupCount, - psHandleData->iLookupCount - 1)); -#endif /* DEBUG_REFCNT */ - - /* psHandleData->bCanLookup can be false at this point */ - PVR_ASSERT(psHandleData->iLookupCount > 0); - - return --psHandleData->iLookupCount; -} - -static inline IMG_BOOL IsRetryError(PVRSRV_ERROR eError) -{ - return eError == PVRSRV_ERROR_RETRY || eError == PVRSRV_ERROR_KERNEL_CCB_FULL; -} - -#if defined(PVRSRV_NEED_PVR_DPF) -static const IMG_CHAR *HandleTypeToString(PVRSRV_HANDLE_TYPE eType) -{ - #define HANDLETYPE(x) \ - case PVRSRV_HANDLE_TYPE_##x: \ - return #x; - switch (eType) - { - #include "handle_types.h" - #undef HANDLETYPE - - default: - return "INVALID"; - } -} - -static const IMG_CHAR *HandleBaseTypeToString(PVRSRV_HANDLE_BASE_TYPE eType) -{ - #define HANDLEBASETYPE(x) \ - case PVRSRV_HANDLE_BASE_TYPE_##x: \ - return #x; - switch (eType) - { - HANDLEBASETYPE(CONNECTION); - HANDLEBASETYPE(PROCESS); - HANDLEBASETYPE(GLOBAL); - #undef HANDLEBASETYPE - - default: - return "INVALID"; - } -} -#endif - -static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFree(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType); - -static PVRSRV_ERROR HandleFreePrivData(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType); - -static PVRSRV_ERROR HandleFreeDestroy(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType); - -/*! -******************************************************************************* - @Function GetHandleData - @Description Get the handle data structure for a given handle - @Input psBase - pointer to handle base structure - hHandle - handle from client - eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the handle - type is not to be checked. - @Output ppsHandleData - pointer to a pointer to the handle data struct - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(GetHandleData) -#endif -static INLINE -PVRSRV_ERROR GetHandleData(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA **ppsHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - HANDLE_DATA *psHandleData; - PVRSRV_ERROR eError; - - eError = gpsHandleFuncs->pfnGetHandleData(psBase->psImplBase, - hHandle, - (void **)&psHandleData); - PVR_RETURN_IF_ERROR(eError); - - /* - * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function, - * check handle is of the correct type. - */ - if (unlikely(eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandleData->eType)) - { - PVR_DPF((PVR_DBG_ERROR, - "GetHandleData: Type mismatch. Lookup request: Handle %p, type: %s (%u) but stored handle is type %s (%u)", - hHandle, - HandleTypeToString(eType), - eType, - HandleTypeToString(psHandleData->eType), - psHandleData->eType)); - return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH; - } - - /* Return the handle structure */ - *ppsHandleData = psHandleData; - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function HandleListInit - @Description Initialise a linked list structure embedded in a handle - structure. - @Input hHandle - handle containing the linked list structure - psList - pointer to linked list structure - hParent - parent handle or NULL -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListInit) -#endif -static INLINE -void HandleListInit(IMG_HANDLE hHandle, HANDLE_LIST *psList, IMG_HANDLE hParent) -{ - psList->hPrev = hHandle; - psList->hNext = hHandle; - psList->hParent = hParent; -} - -/*! -******************************************************************************* - @Function InitParentList - @Description Initialise the children list head in a handle structure. - The children are the subhandles of this handle. - @Input psHandleData - pointer to handle data structure -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitParentList) -#endif -static INLINE -void InitParentList(HANDLE_DATA *psHandleData) -{ - IMG_HANDLE hParent = psHandleData->hHandle; - - HandleListInit(hParent, &psHandleData->sChildren, hParent); -} - -/*! -******************************************************************************* - - @Function InitChildEntry - @Description Initialise the child list entry in a handle structure. The list - entry is used to link together subhandles of a given handle. - @Input psHandleData - pointer to handle data structure -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitChildEntry) -#endif -static INLINE -void InitChildEntry(HANDLE_DATA *psHandleData) -{ - HandleListInit(psHandleData->hHandle, &psHandleData->sSiblings, NULL); -} - -/*! -******************************************************************************* - @Function HandleListIsEmpty - @Description Determine whether a given linked list is empty. - @Input hHandle - handle containing the list head - psList - pointer to the list head - @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't. -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListIsEmpty) -#endif -static INLINE -IMG_BOOL HandleListIsEmpty(IMG_HANDLE hHandle, HANDLE_LIST *psList) /* Instead of passing in the handle can we not just do (psList->hPrev == psList->hNext) ? IMG_TRUE : IMG_FALSE ??? */ -{ - IMG_BOOL bIsEmpty; - - bIsEmpty = (IMG_BOOL)(psList->hNext == hHandle); - -#ifdef DEBUG - { - IMG_BOOL bIsEmpty2; - - bIsEmpty2 = (IMG_BOOL)(psList->hPrev == hHandle); - PVR_ASSERT(bIsEmpty == bIsEmpty2); - } -#endif - - return bIsEmpty; -} - -#ifdef DEBUG -/*! -******************************************************************************* - @Function NoChildren - @Description Determine whether a handle has any subhandles - @Input psHandleData - pointer to handle data structure - @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does. -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(NoChildren) -#endif -static INLINE -IMG_BOOL NoChildren(HANDLE_DATA *psHandleData) -{ - PVR_ASSERT(psHandleData->sChildren.hParent == psHandleData->hHandle); - - return HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sChildren); -} - -/*! -******************************************************************************* - @Function NoParent - @Description Determine whether a handle is a subhandle - @Input psHandleData - pointer to handle data structure - @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is. -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(NoParent) -#endif -static INLINE -IMG_BOOL NoParent(HANDLE_DATA *psHandleData) -{ - if (HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sSiblings)) - { - PVR_ASSERT(psHandleData->sSiblings.hParent == NULL); - - return IMG_TRUE; - } - - PVR_ASSERT(psHandleData->sSiblings.hParent != NULL); - return IMG_FALSE; -} -#endif /*DEBUG*/ - -/*! -******************************************************************************* - @Function ParentHandle - @Description Determine the parent of a handle - @Input psHandleData - pointer to handle data structure - @Return Parent handle, or NULL if the handle is not a subhandle. -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(ParentHandle) -#endif -static INLINE -IMG_HANDLE ParentHandle(HANDLE_DATA *psHandleData) -{ - return psHandleData->sSiblings.hParent; -} - -/* - * GetHandleListFromHandleAndOffset is used to generate either a - * pointer to the subhandle list head, or a pointer to the linked list - * structure of an item on a subhandle list. - * The list head is itself on the list, but is at a different offset - * in the handle structure to the linked list structure for items on - * the list. The two linked list structures are differentiated by - * the third parameter, containing the parent handle. The parent field - * in the list head structure references the handle structure that contains - * it. For items on the list, the parent field in the linked list structure - * references the parent handle, which will be different from the handle - * containing the linked list structure. - */ -#ifdef INLINE_IS_PRAGMA -#pragma inline(GetHandleListFromHandleAndOffset) -#endif -static INLINE -HANDLE_LIST *GetHandleListFromHandleAndOffset(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hEntry, - IMG_HANDLE hParent, - size_t uiParentOffset, - size_t uiEntryOffset) -{ - HANDLE_DATA *psHandleData = NULL; - - PVR_ASSERT(psBase != NULL); - - if (GetHandleData(psBase, &psHandleData, hEntry, - PVRSRV_HANDLE_TYPE_NONE) != PVRSRV_OK) - { - return NULL; - } - - if (hEntry == hParent) - { - return (HANDLE_LIST *)IMG_OFFSET_ADDR(psHandleData, uiParentOffset); - } - else - { - return (HANDLE_LIST *)IMG_OFFSET_ADDR(psHandleData, uiEntryOffset); - } -} - -/*! -******************************************************************************* - @Function HandleListInsertBefore - @Description Insert a handle before a handle currently on the list. - @Input hEntry - handle to be inserted after - psEntry - pointer to handle structure to be inserted after - uiParentOffset - offset to list head struct in handle structure - hNewEntry - handle to be inserted - psNewEntry - pointer to handle structure of item to be inserted - uiEntryOffset - offset of list item struct in handle structure - hParent - parent handle of hNewEntry - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListInsertBefore) -#endif -static INLINE -PVRSRV_ERROR HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hEntry, - HANDLE_LIST *psEntry, - size_t uiParentOffset, - IMG_HANDLE hNewEntry, - HANDLE_LIST *psNewEntry, - size_t uiEntryOffset, - IMG_HANDLE hParent) -{ - HANDLE_LIST *psPrevEntry; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psEntry != NULL, "psEntry"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psNewEntry != NULL, "psNewEntry"); - - psPrevEntry = GetHandleListFromHandleAndOffset(psBase, - psEntry->hPrev, - hParent, - uiParentOffset, - uiEntryOffset); - if (psPrevEntry == NULL) - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - PVR_ASSERT(psNewEntry->hParent == NULL); - PVR_ASSERT(hEntry == psPrevEntry->hNext); - -#if defined(DEBUG) - { - HANDLE_LIST *psParentList; - - psParentList = GetHandleListFromHandleAndOffset(psBase, - hParent, - hParent, - uiParentOffset, - uiParentOffset); - PVR_ASSERT(psParentList && psParentList->hParent == hParent); - } -#endif /* defined(DEBUG) */ - - psNewEntry->hPrev = psEntry->hPrev; - psEntry->hPrev = hNewEntry; - - psNewEntry->hNext = hEntry; - psPrevEntry->hNext = hNewEntry; - - psNewEntry->hParent = hParent; - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function AdoptChild - @Description Assign a subhandle to a handle - @Input psParentData - pointer to handle structure of parent handle - psChildData - pointer to handle structure of child subhandle - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(AdoptChild) -#endif -static INLINE -PVRSRV_ERROR AdoptChild(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psParentData, - HANDLE_DATA *psChildData) -{ - IMG_HANDLE hParent = psParentData->sChildren.hParent; - - PVR_ASSERT(hParent == psParentData->hHandle); - - return HandleListInsertBefore(psBase, - hParent, - &psParentData->sChildren, - offsetof(HANDLE_DATA, sChildren), - psChildData->hHandle, - &psChildData->sSiblings, - offsetof(HANDLE_DATA, sSiblings), - hParent); -} - -/*! -******************************************************************************* - @Function HandleListRemove - @Description Remove a handle from a list - @Input hEntry - handle to be removed - psEntry - pointer to handle structure of item to be removed - uiEntryOffset - offset of list item struct in handle structure - uiParentOffset - offset to list head struct in handle structure - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListRemove) -#endif -static INLINE -PVRSRV_ERROR HandleListRemove(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hEntry, - HANDLE_LIST *psEntry, - size_t uiEntryOffset, - size_t uiParentOffset) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psEntry != NULL, "psEntry"); - - if (!HandleListIsEmpty(hEntry, psEntry)) - { - HANDLE_LIST *psPrev; - HANDLE_LIST *psNext; - - psPrev = GetHandleListFromHandleAndOffset(psBase, - psEntry->hPrev, - psEntry->hParent, - uiParentOffset, - uiEntryOffset); - if (psPrev == NULL) - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - psNext = GetHandleListFromHandleAndOffset(psBase, - psEntry->hNext, - psEntry->hParent, - uiParentOffset, - uiEntryOffset); - if (psNext == NULL) - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - /* - * The list head is on the list, and we don't want to - * remove it. - */ - PVR_ASSERT(psEntry->hParent != NULL); - - psPrev->hNext = psEntry->hNext; - psNext->hPrev = psEntry->hPrev; - - HandleListInit(hEntry, psEntry, NULL); - } - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function UnlinkFromParent - @Description Remove a subhandle from its parents list - @Input psHandleData - pointer to handle data structure of child - subhandle. - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(UnlinkFromParent) -#endif -static INLINE -PVRSRV_ERROR UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData) -{ - return HandleListRemove(psBase, - psHandleData->hHandle, - &psHandleData->sSiblings, - offsetof(HANDLE_DATA, sSiblings), - offsetof(HANDLE_DATA, sChildren)); -} - -/*! -******************************************************************************* - @Function HandleListIterate - @Description Iterate over the items in a list - @Input psHead - pointer to list head - uiParentOffset - offset to list head struct in handle structure - uiEntryOffset - offset of list item struct in handle structure - pfnIterFunc - function to be called for each handle in the list - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListIterate) -#endif -static INLINE -PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, - HANDLE_LIST *psHead, - size_t uiParentOffset, - size_t uiEntryOffset, - PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE)) -{ - IMG_HANDLE hHandle = psHead->hNext; - IMG_HANDLE hParent = psHead->hParent; - IMG_HANDLE hNext; - - PVR_ASSERT(psHead->hParent != NULL); - - /* - * Follow the next chain from the list head until we reach - * the list head again, which signifies the end of the list. - */ - while (hHandle != hParent) - { - HANDLE_LIST *psEntry; - PVRSRV_ERROR eError; - - psEntry = GetHandleListFromHandleAndOffset(psBase, - hHandle, - hParent, - uiParentOffset, - uiEntryOffset); - if (psEntry == NULL) - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - PVR_ASSERT(psEntry->hParent == psHead->hParent); - - /* - * Get the next index now, in case the list item is - * modified by the iteration function. - */ - hNext = psEntry->hNext; - - eError = (*pfnIterFunc)(psBase, hHandle); - PVR_RETURN_IF_ERROR(eError); - - hHandle = hNext; - } - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function IterateOverChildren - @Description Iterate over the subhandles of a parent handle - @Input psParentData - pointer to parent handle structure - pfnIterFunc - function to be called for each subhandle - @Return Error code or PVRSRV_OK -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(IterateOverChildren) -#endif -static INLINE -PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psParentData, - PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE)) -{ - return HandleListIterate(psBase, - &psParentData->sChildren, - offsetof(HANDLE_DATA, sChildren), - offsetof(HANDLE_DATA, sSiblings), - pfnIterFunc); -} - -/*! -******************************************************************************* - @Function ParentIfPrivate - @Description Return the parent handle if the handle was allocated with - PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return NULL. - @Input psHandleData - pointer to handle data structure - @Return Parent handle or NULL -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(ParentIfPrivate) -#endif -static INLINE -IMG_HANDLE ParentIfPrivate(HANDLE_DATA *psHandleData) -{ - return TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? - ParentHandle(psHandleData) : NULL; -} - -/*! -******************************************************************************* - @Function InitKey - @Description Initialise a hash table key for the current process - @Input aKey - pointer to key - psBase - pointer to handle base structure - pvData - pointer to the resource the handle represents - eType - type of resource -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitKey) -#endif -static INLINE -void InitKey(HAND_KEY aKey, - PVRSRV_HANDLE_BASE *psBase, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - IMG_HANDLE hParent) -{ - PVR_UNREFERENCED_PARAMETER(psBase); - - aKey[HAND_KEY_DATA] = (uintptr_t)pvData; - aKey[HAND_KEY_TYPE] = (uintptr_t)eType; - aKey[HAND_KEY_PARENT] = (uintptr_t)hParent; -} - -/*! -******************************************************************************* - @Function FindHandle - @Description Find handle corresponding to a resource pointer - @Input psBase - pointer to handle base structure - pvData - pointer to resource to be associated with the handle - eType - the type of resource - @Return The handle, or NULL if not found -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(FindHandle) -#endif -static INLINE -IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - IMG_HANDLE hParent) -{ - HAND_KEY aKey; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - InitKey(aKey, psBase, pvData, eType, hParent); - - return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey); -} - -/*! -******************************************************************************* - @Function AllocHandle - @Description Allocate a new handle - @Input phHandle - location for new handle - pvData - pointer to resource to be associated with the handle - eType - the type of resource - hParent - parent handle or NULL - pfnReleaseData - Function to release resource at handle release - time - @Output phHandle - points to new handle - @Return Error code or PVRSRV_OK -******************************************************************************/ -static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - PVRSRV_HANDLE_ALLOC_FLAG eFlag, - IMG_HANDLE hParent, - PFN_HANDLE_RELEASE pfnReleaseData) -{ - HANDLE_DATA *psNewHandleData; - IMG_HANDLE hHandle; - PVRSRV_ERROR eError; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(psBase != NULL && psBase->psHashTab != NULL); - PVR_ASSERT(gpsHandleFuncs); - - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - /* Handle must not already exist */ - PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == NULL); - } - - psNewHandleData = OSAllocZMem(sizeof(*psNewHandleData)); - PVR_LOG_RETURN_IF_NOMEM(psNewHandleData, "OSAllocZMem"); - - eError = gpsHandleFuncs->pfnAcquireHandle(psBase->psImplBase, &hHandle, - psNewHandleData); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnAcquireHandle", - ErrorFreeHandleData); - - /* - * If a data pointer can be associated with multiple handles, we - * don't put the handle in the hash table, as the data pointer - * may not map to a unique handle - */ - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - HAND_KEY aKey; - - /* Initialise hash key */ - InitKey(aKey, psBase, pvData, eType, hParent); - - /* Put the new handle in the hash table */ - eError = HASH_Insert_Extended(psBase->psHashTab, aKey, (uintptr_t)hHandle) ? - PVRSRV_OK : PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "couldn't add handle to hash table", - ErrorReleaseHandle); - } - - psNewHandleData->hHandle = hHandle; - psNewHandleData->eType = eType; - psNewHandleData->eFlag = eFlag; - psNewHandleData->pvData = pvData; - psNewHandleData->pfnReleaseData = pfnReleaseData; - psNewHandleData->iLookupCount = 0; - psNewHandleData->bCanLookup = IMG_TRUE; - -#ifdef DEBUG_REFCNT - PVR_DPF((PVR_DBG_ERROR, "%s: bCanLookup = true", __func__)); -#endif /* DEBUG_REFCNT */ - - InitParentList(psNewHandleData); -#if defined(DEBUG) - PVR_ASSERT(NoChildren(psNewHandleData)); -#endif - - InitChildEntry(psNewHandleData); -#if defined(DEBUG) - PVR_ASSERT(NoParent(psNewHandleData)); -#endif - -#if defined(PVRSRV_DEBUG_HANDLE_LOCK) - psNewHandleData->psBase = psBase; -#endif - - /* Return the new handle to the client */ - *phHandle = psNewHandleData->hHandle; - - return PVRSRV_OK; - -ErrorReleaseHandle: - (void)gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, hHandle, NULL); - -ErrorFreeHandleData: - OSFreeMem(psNewHandleData); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVAllocHandle - @Description Allocate a handle - @Input psBase - pointer to handle base structure - pvData - pointer to resource to be associated with the handle - eType - the type of resource - pfnReleaseData - Function to release resource at handle release - time - @Output phHandle - points to new handle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - PVRSRV_HANDLE_ALLOC_FLAG eFlag, - PFN_HANDLE_RELEASE pfnReleaseData) -{ - PVRSRV_ERROR eError; - - LockHandle(psBase); - eError = PVRSRVAllocHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, pfnReleaseData); - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVAllocHandleUnlocked - @Description Allocate a handle without acquiring/releasing the handle lock. - The function assumes you hold the lock when called. - @Input phHandle - location for new handle - pvData - pointer to resource to be associated with the handle - eType - the type of resource - pfnReleaseData - Function to release resource at handle release - time - @Output phHandle - points to new handle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - PVRSRV_HANDLE_ALLOC_FLAG eFlag, - PFN_HANDLE_RELEASE pfnReleaseData) -{ - *phHandle = NULL; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pfnReleaseData != NULL, "pfnReleaseData"); - - return AllocHandle(psBase, phHandle, pvData, eType, eFlag, NULL, pfnReleaseData); -} - -/*! -******************************************************************************* - @Function PVRSRVAllocSubHandle - @Description Allocate a subhandle - @Input pvData - pointer to resource to be associated with the subhandle - eType - the type of resource - hParent - parent handle - @Output phHandle - points to new subhandle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - PVRSRV_HANDLE_ALLOC_FLAG eFlag, - IMG_HANDLE hParent) -{ - PVRSRV_ERROR eError; - - LockHandle(psBase); - eError = PVRSRVAllocSubHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, hParent); - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVAllocSubHandleUnlocked - @Description Allocate a subhandle without acquiring/releasing the handle - lock. The function assumes you hold the lock when called. - @Input pvData - pointer to resource to be associated with the subhandle - eType - the type of resource - hParent - parent handle - @Output phHandle - points to new subhandle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType, - PVRSRV_HANDLE_ALLOC_FLAG eFlag, - IMG_HANDLE hParent) -{ - HANDLE_DATA *psPHandleData = NULL; - HANDLE_DATA *psCHandleData = NULL; - IMG_HANDLE hParentKey; - IMG_HANDLE hHandle; - PVRSRV_ERROR eError; - - *phHandle = NULL; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_GOTO_IF_INVALID_PARAM(psBase, eError, Exit); - - hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : NULL; - - /* Lookup the parent handle */ - eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "failed to get parent handle structure", - Exit); - - eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey, NULL); - PVR_GOTO_IF_ERROR(eError, Exit); - - eError = GetHandleData(psBase, &psCHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE); - /* If we were able to allocate the handle then there should be no reason why we - * can't also get it's handle structure. Otherwise something has gone badly wrong. - */ - PVR_ASSERT(eError == PVRSRV_OK); - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "Failed to get parent handle structure", - ExitFreeHandle); - - /* - * Get the parent handle structure again, in case the handle - * structure has moved (depending on the implementation - * of AllocHandle). - */ - eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "failed to get parent handle structure", - ExitFreeHandle); - - eError = AdoptChild(psBase, psPHandleData, psCHandleData); - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "parent handle failed to adopt subhandle", - ExitFreeHandle); - - *phHandle = hHandle; - - return PVRSRV_OK; - -ExitFreeHandle: - PVRSRVDestroyHandleUnlocked(psBase, hHandle, eType); -Exit: - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVFindHandle - @Description Find handle corresponding to a resource pointer - @Input pvData - pointer to resource to be associated with the handle - eType - the type of resource - @Output phHandle - points to returned handle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType) -{ - PVRSRV_ERROR eError; - - LockHandle(psBase); - eError = PVRSRVFindHandleUnlocked(psBase, phHandle, pvData, eType); - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVFindHandleUnlocked - @Description Find handle corresponding to a resource pointer without - acquiring/releasing the handle lock. The function assumes you - hold the lock when called. - @Input pvData - pointer to resource to be associated with the handle - eType - the type of resource - @Output phHandle - points to the returned handle - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData, - PVRSRV_HANDLE_TYPE eType) -{ - IMG_HANDLE hHandle; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - /* See if there is a handle for this data pointer */ - hHandle = FindHandle(psBase, pvData, eType, NULL); - if (hHandle == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error finding handle. Type %u", - __func__, - eType)); - - return PVRSRV_ERROR_HANDLE_NOT_FOUND; - } - - *phHandle = hHandle; - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function PVRSRVLookupHandle - @Description Lookup the data pointer corresponding to a handle - @Input hHandle - handle from client - eType - handle type - bRef - If TRUE, a reference will be added on the handle if the - lookup is successful. - @Output ppvData - points to the return data pointer - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, - void **ppvData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType, - IMG_BOOL bRef) -{ - PVRSRV_ERROR eError; - - LockHandle(psBase); - eError = PVRSRVLookupHandleUnlocked(psBase, ppvData, hHandle, eType, bRef); - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVLookupHandleUnlocked - @Description Lookup the data pointer corresponding to a handle without - acquiring/releasing the handle lock. The function assumes you - hold the lock when called. - @Input hHandle - handle from client - eType - handle type - bRef - If TRUE, a reference will be added on the handle if the - lookup is successful. - @Output ppvData - points to the returned data pointer - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - void **ppvData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType, - IMG_BOOL bRef) -{ - HANDLE_DATA *psHandleData = NULL; - PVRSRV_ERROR eError; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - eError = GetHandleData(psBase, &psHandleData, hHandle, eType); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error looking up handle (%s) for base %p of type %s. Handle %p, type %s", - __func__, - PVRSRVGetErrorString(eError), - psBase, - HandleBaseTypeToString(psBase->eType), - (void*) hHandle, - HandleTypeToString(eType))); -#if defined(DEBUG) || defined(PVRSRV_NEED_PVR_DPF) - OSDumpStack(); -#endif - return eError; - } - - /* If bCanLookup is false it means that a destroy operation was already - * called on this handle; therefore it can no longer be looked up. */ - if (!psHandleData->bCanLookup) - { - return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED; - } - - if (bRef) - { - HandleGet(psHandleData); - } - - *ppvData = psHandleData->pvData; - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function PVRSRVLookupSubHandle - @Description Lookup the data pointer corresponding to a subhandle - @Input hHandle - handle from client - eType - handle type - hAncestor - ancestor handle - @Output ppvData - points to the returned data pointer - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, - void **ppvData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType, - IMG_HANDLE hAncestor) -{ - HANDLE_DATA *psPHandleData = NULL; - HANDLE_DATA *psCHandleData = NULL; - PVRSRV_ERROR eError; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - LockHandle(psBase); - - eError = GetHandleData(psBase, &psCHandleData, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error looking up subhandle (%s). Handle %p, type %u", - __func__, - PVRSRVGetErrorString(eError), - (void*) hHandle, - eType)); - OSDumpStack(); - goto ExitUnlock; - } - - /* Look for hAncestor among the handle's ancestors */ - for (psPHandleData = psCHandleData; ParentHandle(psPHandleData) != hAncestor; ) - { - eError = GetHandleData(psBase, &psPHandleData, ParentHandle(psPHandleData), PVRSRV_HANDLE_TYPE_NONE); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "GetHandleData"); - eError = PVRSRV_ERROR_INVALID_SUBHANDLE; - goto ExitUnlock; - } - } - - *ppvData = psCHandleData->pvData; - - eError = PVRSRV_OK; - -ExitUnlock: - UnlockHandle(psBase); - - return eError; -} - - -/*! -******************************************************************************* - @Function PVRSRVReleaseHandle - @Description Release a handle that is no longer needed - @Input hHandle - handle from client - eType - handle type - @Return Error code or PVRSRV_OK -******************************************************************************/ -void PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - LockHandle(psBase); - PVRSRVReleaseHandleUnlocked(psBase, hHandle, eType); - UnlockHandle(psBase); -} - - -/*! -******************************************************************************* - @Function PVRSRVReleaseHandleUnlocked - @Description Release a handle that is no longer needed without - acquiring/releasing the handle lock. The function assumes you - hold the lock when called. - @Input hHandle - handle from client - eType - handle type -******************************************************************************/ -void PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - HANDLE_DATA *psHandleData = NULL; - PVRSRV_ERROR eError; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(psBase != NULL); - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_VOID_IF_FALSE(psBase != NULL, "invalid psBase"); - - eError = GetHandleData(psBase, &psHandleData, hHandle, eType); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error (%s) looking up handle %p of type %s " - "for base %p of type %s.", __func__, PVRSRVGetErrorString(eError), - (void*) hHandle, HandleTypeToString(eType), psBase, - HandleBaseTypeToString(psBase->eType))); - - PVR_ASSERT(eError == PVRSRV_OK); - - return; - } - - PVR_ASSERT(psHandleData->bCanLookup); - PVR_ASSERT(psHandleData->iLookupCount > 0); - - /* If there are still outstanding lookups for this handle or the handle - * has not been destroyed yet, return early */ - HandlePut(psHandleData); -} - -/*! -******************************************************************************* - @Function PVRSRVPurgeHandles - @Description Purge handles for a given handle base - @Input psBase - pointer to handle base structure - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - LockHandle(psBase); - eError = gpsHandleFuncs->pfnPurgeHandles(psBase->psImplBase); - UnlockHandle(psBase); - - return eError; -} - -static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFreeWrapper(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle) -{ - HANDLE_DATA *psHandleData; - PVRSRV_ERROR eError = GetHandleData(psBase, &psHandleData, hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_RETURN_IF_ERROR(eError); - - return HandleUnrefAndMaybeMarkForFree(psBase, psHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE); -} - -static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFree(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - PVRSRV_ERROR eError; - - /* If bCanLookup is false it means that the destructor was called more than - * once on this handle. */ - if (!psHandleData->bCanLookup) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Handle %p of type %s already freed.", - __func__, psHandleData->hHandle, - HandleTypeToString(psHandleData->eType))); - return PVRSRV_ERROR_HANDLE_NOT_FOUND; - } - - if (psHandleData->iLookupCount > 0) - { - return PVRSRV_ERROR_OBJECT_STILL_REFERENCED; - } - - /* Mark this handle as freed only if it's no longer referenced by any - * lookup. The user space should retry freeing this handle once there are - * no outstanding lookups. */ - psHandleData->bCanLookup = IMG_FALSE; - -#ifdef DEBUG_REFCNT - PVR_DPF((PVR_DBG_ERROR, "%s: bCanLookup = false, iLookupCount = %d", __func__, - psHandleData->iLookupCount)); -#endif /* DEBUG_REFCNT */ - - /* Prepare children for destruction */ - eError = IterateOverChildren(psBase, psHandleData, - HandleUnrefAndMaybeMarkForFreeWrapper); - PVR_LOG_RETURN_IF_ERROR(eError, "HandleUnrefAndMaybeMarkForFreeWrapper"); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR HandleFreePrivDataWrapper(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle) -{ - HANDLE_DATA *psHandleData; - PVRSRV_ERROR eError = GetHandleData(psBase, &psHandleData, hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_RETURN_IF_ERROR(eError); - - return HandleFreePrivData(psBase, psHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE); -} - -static PVRSRV_ERROR HandleFreePrivData(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - PVRSRV_ERROR eError; - - /* Call the release data callback for each reference on the handle */ - if (psHandleData->pfnReleaseData != NULL) - { - eError = psHandleData->pfnReleaseData(psHandleData->pvData); - if (eError != PVRSRV_OK) - { - if (IsRetryError(eError)) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Got retry while calling release " - "data callback for handle %p of type = %s", __func__, - hHandle, HandleTypeToString(psHandleData->eType))); - } - else - { - PVR_LOG_ERROR(eError, "pfnReleaseData"); - } - - return eError; - } - - /* we don't need this so make sure it's not called on - * the pvData for the second time - */ - psHandleData->pfnReleaseData = NULL; - } - - /* Free children's data */ - eError = IterateOverChildren(psBase, psHandleData, - HandleFreePrivDataWrapper); - PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren->HandleFreePrivData"); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR HandleFreeDestroyWrapper(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle) -{ - HANDLE_DATA *psHandleData; - PVRSRV_ERROR eError = GetHandleData(psBase, &psHandleData, hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_RETURN_IF_ERROR(eError); - - return HandleFreeDestroy(psBase, psHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE); -} - -static PVRSRV_ERROR HandleFreeDestroy(PVRSRV_HANDLE_BASE *psBase, - HANDLE_DATA *psHandleData, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - HANDLE_DATA *psReleasedHandleData; - PVRSRV_ERROR eError; - - eError = UnlinkFromParent(psBase, psHandleData); - PVR_LOG_RETURN_IF_ERROR(eError, "UnlinkFromParent"); - - if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - HAND_KEY aKey; - IMG_HANDLE hRemovedHandle; - - InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, - ParentIfPrivate(psHandleData)); - - hRemovedHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, - aKey); - - PVR_ASSERT(hRemovedHandle != NULL); - PVR_ASSERT(hRemovedHandle == psHandleData->hHandle); - PVR_UNREFERENCED_PARAMETER(hRemovedHandle); - } - - /* Free children */ - eError = IterateOverChildren(psBase, psHandleData, HandleFreeDestroyWrapper); - PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren->HandleFreeDestroy"); - - eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, - psHandleData->hHandle, - (void **)&psReleasedHandleData); - OSFreeMem(psHandleData); - PVR_LOG_RETURN_IF_ERROR(eError, "pfnReleaseHandle"); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR DestroyHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType, - IMG_BOOL bReleaseLock) -{ - PVRSRV_ERROR eError; - HANDLE_DATA *psHandleData = NULL; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - eError = GetHandleData(psBase, &psHandleData, hHandle, eType); - PVR_RETURN_IF_ERROR(eError); - - eError = HandleUnrefAndMaybeMarkForFree(psBase, psHandleData, hHandle, eType); - PVR_RETURN_IF_ERROR(eError); - - if (bReleaseLock) - { - UnlockHandle(psBase); - } - - eError = HandleFreePrivData(psBase, psHandleData, hHandle, eType); - if (eError != PVRSRV_OK) - { - if (bReleaseLock) - { - LockHandle(psBase); - } - - /* If the data could not be freed due to a temporary condition the - * handle must be kept alive so that the next destroy call can try again */ - if (IsRetryError(eError)) - { - psHandleData->bCanLookup = IMG_TRUE; - } - - return eError; - } - - if (bReleaseLock) - { - LockHandle(psBase); - } - - return HandleFreeDestroy(psBase, psHandleData, hHandle, eType); -} - -/*! -******************************************************************************* - @Function PVRSRVDestroyHandle - @Description Destroys a handle that is no longer needed. Will - acquiring the handle lock for duration of the call. - Can return RETRY or KERNEL_CCB_FULL if resource could not be - destroyed, caller should retry sometime later. - @Input psBase - pointer to handle base structure - hHandle - handle from client - eType - handle type - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVDestroyHandle(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - PVRSRV_ERROR eError; - - LockHandle(psBase); - eError = DestroyHandle(psBase, hHandle, eType, IMG_FALSE); - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVDestroyHandleUnlocked - @Description Destroys a handle that is no longer needed without - acquiring/releasing the handle lock. The function assumes you - hold the lock when called. - Can return RETRY or KERNEL_CCB_FULL if resource could not be - destroyed, caller should retry sometime later. - @Input psBase - pointer to handle base structure - hHandle - handle from client - eType - handle type - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVDestroyHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - return DestroyHandle(psBase, hHandle, eType, IMG_FALSE); -} - -/*! -******************************************************************************* - @Function PVRSRVDestroyHandleStagedUnlocked - @Description Destroys a handle that is no longer needed without - acquiring/releasing the handle lock. The function assumes you - hold the lock when called. This function, unlike - PVRSRVDestroyHandleUnlocked(), releases the handle lock while - destroying handle private data. This is done to open the - bridge for other bridge calls. - Can return RETRY or KERNEL_CCB_FULL if resource could not be - destroyed, caller should retry sometime later. - @Input psBase - pointer to handle base structure - hHandle - handle from client - eType - handle type - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVDestroyHandleStagedUnlocked(PVRSRV_HANDLE_BASE *psBase, - IMG_HANDLE hHandle, - PVRSRV_HANDLE_TYPE eType) -{ - return DestroyHandle(psBase, hHandle, eType, IMG_TRUE); -} - -/*! -******************************************************************************* - @Function PVRSRVAllocHandleBase - @Description Allocate a handle base structure for a process - @Input eType - handle type - @Output ppsBase - points to handle base structure pointer - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase, - PVRSRV_HANDLE_BASE_TYPE eType) -{ - PVRSRV_HANDLE_BASE *psBase; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_FALSE(gpsHandleFuncs != NULL, "handle management not initialised", - PVRSRV_ERROR_NOT_READY); - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsBase != NULL, "ppsBase"); - - psBase = OSAllocZMem(sizeof(*psBase)); - PVR_LOG_RETURN_IF_NOMEM(psBase, "psBase"); - - eError = OSLockCreate(&psBase->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", ErrorFreeHandleBase); - - psBase->eType = eType; - - LockHandle(psBase); - - eError = gpsHandleFuncs->pfnCreateHandleBase(&psBase->psImplBase); - PVR_GOTO_IF_ERROR(eError, ErrorUnlock); - - psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, - sizeof(HAND_KEY), - HASH_Func_Default, - HASH_Key_Comp_Default); - PVR_LOG_GOTO_IF_FALSE(psBase->psHashTab != NULL, "couldn't create data pointer" - " hash table", ErrorDestroyHandleBase); - - *ppsBase = psBase; - - UnlockHandle(psBase); - - return PVRSRV_OK; - -ErrorDestroyHandleBase: - (void)gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase); - -ErrorUnlock: - UnlockHandle(psBase); - OSLockDestroy(psBase->hLock); - -ErrorFreeHandleBase: - OSFreeMem(psBase); - - return eError; -} - -#if defined(DEBUG) -typedef struct _COUNT_HANDLE_DATA_ -{ - PVRSRV_HANDLE_BASE *psBase; - IMG_UINT32 uiHandleDataCount; -} COUNT_HANDLE_DATA; - -/* Used to count the number of handles that have data associated with them */ -static PVRSRV_ERROR CountHandleDataWrapper(IMG_HANDLE hHandle, void *pvData) -{ - COUNT_HANDLE_DATA *psData = (COUNT_HANDLE_DATA *)pvData; - HANDLE_DATA *psHandleData = NULL; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psData != NULL, "psData"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psData->psBase != NULL, "psData->psBase"); - - eError = GetHandleData(psData->psBase, - &psHandleData, - hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData"); - - if (psHandleData != NULL) - { - psData->uiHandleDataCount++; - } - - return PVRSRV_OK; -} - -/* Print a handle in the handle base. Used with the iterator callback. */ -static PVRSRV_ERROR ListHandlesInBase(IMG_HANDLE hHandle, void *pvData) -{ - PVRSRV_HANDLE_BASE *psBase = (PVRSRV_HANDLE_BASE*) pvData; - HANDLE_DATA *psHandleData = NULL; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase"); - - eError = GetHandleData(psBase, - &psHandleData, - hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData"); - - if (psHandleData != NULL) - { - PVR_DPF((PVR_DBG_WARNING, - " Handle: %6u, CanLookup: %u, LookupCount: %3u, Type: %s (%u), pvData<%p>", - (IMG_UINT32) (uintptr_t) psHandleData->hHandle, psHandleData->bCanLookup, - psHandleData->iLookupCount, HandleTypeToString(psHandleData->eType), - psHandleData->eType, psHandleData->pvData)); - } - - return PVRSRV_OK; -} - -#endif /* defined(DEBUG) */ - -static INLINE IMG_BOOL _CheckIfMaxTimeExpired(IMG_UINT64 ui64TimeStart, IMG_UINT64 ui64MaxBridgeTime) -{ - /* unsigned arithmetic is well defined so this will wrap around correctly */ - return (IMG_BOOL)((OSClockns64() - ui64TimeStart) >= ui64MaxBridgeTime); -} - -static PVRSRV_ERROR FreeKernelHandlesWrapperIterKernel(IMG_HANDLE hHandle, void *pvData) -{ - FREE_KERNEL_HANDLE_DATA *psData = (FREE_KERNEL_HANDLE_DATA *)pvData; - HANDLE_DATA *psKernelHandleData = NULL; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - /* Get kernel handle data. */ - eError = GetHandleData(KERNEL_HANDLE_BASE, - &psKernelHandleData, - hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData"); - - if (psKernelHandleData->pvData == psData->psProcessHandleData->pvData) - { - /* This kernel handle belongs to our process handle. */ - psData->hKernelHandle = hHandle; - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR FreeKernelHandlesWrapperIterProcess(IMG_HANDLE hHandle, void *pvData) -{ - FREE_KERNEL_HANDLE_DATA *psData = (FREE_KERNEL_HANDLE_DATA *)pvData; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - /* Get process handle data. */ - eError = GetHandleData(psData->psBase, - &psData->psProcessHandleData, - hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData"); - - if (psData->psProcessHandleData->eFlag == PVRSRV_HANDLE_ALLOC_FLAG_MULTI -#if defined(SUPPORT_INSECURE_EXPORT) - || psData->psProcessHandleData->eType == PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_EXPORT -#endif - ) - { - /* Only multi alloc process handles might be in kernel handle base. */ - psData->hKernelHandle = NULL; - /* Iterate over kernel handles. */ - eError = gpsHandleFuncs->pfnIterateOverHandles(KERNEL_HANDLE_BASE->psImplBase, - &FreeKernelHandlesWrapperIterKernel, - (void *)psData); - PVR_LOG_RETURN_IF_FALSE(eError == PVRSRV_OK, "failed to iterate over kernel handles", - eError); - - if (psData->hKernelHandle) - { - /* Release kernel handle which belongs to our process handle. */ - eError = gpsHandleFuncs->pfnReleaseHandle(KERNEL_HANDLE_BASE->psImplBase, - psData->hKernelHandle, - NULL); - PVR_LOG_RETURN_IF_FALSE(eError == PVRSRV_OK, "couldn't release kernel handle", - eError); - } - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR FreeHandleDataWrapper(IMG_HANDLE hHandle, void *pvData) -{ - FREE_HANDLE_DATA *psData = (FREE_HANDLE_DATA *)pvData; - HANDLE_DATA *psHandleData = NULL; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - PVR_LOG_RETURN_IF_INVALID_PARAM(psData != NULL, "psData"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psData->psBase != NULL, "psData->psBase"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psData->eHandleFreeType != PVRSRV_HANDLE_TYPE_NONE, - "psData->eHandleFreeType"); - - eError = GetHandleData(psData->psBase, - &psHandleData, - hHandle, - PVRSRV_HANDLE_TYPE_NONE); - PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData"); - - if (psHandleData == NULL || psHandleData->eType != psData->eHandleFreeType) - { - return PVRSRV_OK; - } - - PVR_ASSERT(psHandleData->bCanLookup && psHandleData->iLookupCount == 0); - - if (psHandleData->bCanLookup) - { - if (psHandleData->pfnReleaseData != NULL) - { - eError = psHandleData->pfnReleaseData(psHandleData->pvData); - if (eError == PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Got retry while calling release " - "data callback for handle %p of type = %s", __func__, - hHandle, HandleTypeToString(psHandleData->eType))); - - return eError; - } - else if (eError != PVRSRV_OK) - { - return eError; - } - } - - psHandleData->bCanLookup = IMG_FALSE; - } - - if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - HAND_KEY aKey; - IMG_HANDLE hRemovedHandle; - - InitKey(aKey, - psData->psBase, - psHandleData->pvData, - psHandleData->eType, - ParentIfPrivate(psHandleData)); - - hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psData->psBase->psHashTab, aKey); - - PVR_ASSERT(hRemovedHandle != NULL); - PVR_ASSERT(hRemovedHandle == psHandleData->hHandle); - PVR_UNREFERENCED_PARAMETER(hRemovedHandle); - } - - eError = gpsHandleFuncs->pfnSetHandleData(psData->psBase->psImplBase, hHandle, NULL); - PVR_RETURN_IF_ERROR(eError); - - OSFreeMem(psHandleData); - - /* If we reach the end of the time slice release we can release the global - * lock, invoke the scheduler and reacquire the lock */ - if ((psData->ui64MaxBridgeTime != 0) && _CheckIfMaxTimeExpired(psData->ui64TimeStart, psData->ui64MaxBridgeTime)) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Lock timeout (timeout: %" IMG_UINT64_FMTSPEC")", - __func__, - psData->ui64MaxBridgeTime)); - UnlockHandle(psData->psBase); - /* Invoke the scheduler to check if other processes are waiting for the lock */ - OSReleaseThreadQuanta(); - LockHandle(psData->psBase); - /* Set again lock timeout and reset the counter */ - psData->ui64TimeStart = OSClockns64(); - PVR_DPF((PVR_DBG_MESSAGE, "%s: Lock acquired again", __func__)); - } - - return PVRSRV_OK; -} - -/* The Ordered Array of PVRSRV_HANDLE_TYPE Enum Entries. - * - * Some handles must be destroyed prior to other handles, - * such relationships are established with respect to handle types. - * Therefore elements of this array have to maintain specific order, - * e.g. the PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET must be placed - * before PVRSRV_HANDLE_TYPE_RGX_FREELIST. - * - * If ordering is incorrect driver may fail on the ground of cleanup - * routines. Unfortunately, we can mainly rely on the actual definition of - * the array, there is no explicit information about all relationships - * between handle types. These relationships do not necessarily come from - * bridge-specified handle attributes such as 'sub handle' and 'parent - * handle'. They may come from internal/private ref-counters contained by - * objects referenced by our kernel handles. - * - * For example, at the bridge level, PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET - * and PVRSRV_HANDLE_TYPE_RGX_FREELIST have no explicit relationship, meaning - * none of them is a sub-handle for the other. - * However the freelist contains internal ref-count that is decremented by - * the destroy routine for KM_HW_RT_DATASET. - * - * BE CAREFUL when adding/deleting/moving handle types. - */ -static const PVRSRV_HANDLE_TYPE g_aeOrderedFreeList[] = -{ - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, - PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC, - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET, - PVRSRV_HANDLE_TYPE_RGX_FREELIST, - PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK, - PVRSRV_HANDLE_TYPE_RGX_POPULATION, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT, -#if defined(PVR_TESTING_UTILS) && defined(SUPPORT_VALIDATION) - PVRSRV_HANDLE_TYPE_RGX_SERVER_GPUMAP_CONTEXT, -#endif - PVRSRV_HANDLE_TYPE_RI_HANDLE, - PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - PVRSRV_HANDLE_TYPE_PVRSRV_TIMELINE_SERVER, - PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_EXPORT, - PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_SERVER, - PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT, - PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_PAGELIST, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE, - PVRSRV_HANDLE_TYPE_DC_BUFFER, - PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT, - PVRSRV_HANDLE_TYPE_DC_DEVICE, - PVRSRV_HANDLE_TYPE_PVR_TL_SD, - PVRSRV_HANDLE_TYPE_DI_CONTEXT, - PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP -}; - -/*! -******************************************************************************* - @Function PVRSRVFreeKernelHandles - @Description Free kernel handles which belongs to process handles - @Input psBase - pointer to handle base structure - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVFreeKernelHandles(PVRSRV_HANDLE_BASE *psBase) -{ - FREE_KERNEL_HANDLE_DATA sHandleData = {NULL}; - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsHandleFuncs); - - LockHandle(psBase); - - sHandleData.psBase = psBase; - /* Iterate over process handles. */ - eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase, - &FreeKernelHandlesWrapperIterProcess, - (void *)&sHandleData); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnIterateOverHandles", ExitUnlock); - - eError = PVRSRV_OK; - -ExitUnlock: - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVRetrieveProcessHandleBase - @Description Returns a pointer to the process handle base for the current - process. If the current process is the cleanup thread, then the - process handle base for the process currently being cleaned up - is returned - @Return Pointer to the process handle base, or NULL if not found. -******************************************************************************/ -PVRSRV_HANDLE_BASE *PVRSRVRetrieveProcessHandleBase(void) -{ - PVRSRV_HANDLE_BASE *psHandleBase = NULL; - PROCESS_HANDLE_BASE *psProcHandleBase = NULL; - IMG_PID ui32PurgePid = PVRSRVGetPurgeConnectionPid(); - IMG_PID uiCleanupPid = PVRSRVCleanupThreadGetPid(); - uintptr_t uiCleanupTid = PVRSRVCleanupThreadGetTid(); - - OSLockAcquire(g_hProcessHandleBaseLock); - - /* Check to see if we're being called from the cleanup thread... */ - if ((OSGetCurrentProcessID() == uiCleanupPid) && - (OSGetCurrentThreadID() == uiCleanupTid) && - (ui32PurgePid > 0)) - { - /* Check to see if the cleanup thread has already removed the - * process handle base from the HASH table. - */ - psHandleBase = g_psProcessHandleBaseBeingFreed; - /* psHandleBase shouldn't be null, as cleanup thread - * should be removing this from the HASH table before - * we get here, so assert if not. - */ - PVR_ASSERT(psHandleBase); - } - else - { - /* Not being called from the cleanup thread, so return the process - * handle base for the current process. - */ - psProcHandleBase = (PROCESS_HANDLE_BASE *) - HASH_Retrieve(g_psProcessHandleBaseTable, OSGetCurrentClientProcessIDKM()); - } - - OSLockRelease(g_hProcessHandleBaseLock); - - if (psHandleBase == NULL && psProcHandleBase != NULL) - { - psHandleBase = psProcHandleBase->psHandleBase; - } - return psHandleBase; -} - -/*! -******************************************************************************* - @Function PVRSRVAcquireProcessHandleBase - @Description Increments reference count on a process handle base identified - by uiPid and returns pointer to the base. If the handle base - does not exist it will be allocated. - @Inout uiPid - PID of a process - @Output ppsBase - pointer to a handle base for the process identified by - uiPid - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVAcquireProcessHandleBase(IMG_PID uiPid, PROCESS_HANDLE_BASE **ppsBase) -{ - PROCESS_HANDLE_BASE *psBase; - PVRSRV_ERROR eError; - - OSLockAcquire(g_hProcessHandleBaseLock); - - psBase = (PROCESS_HANDLE_BASE*) HASH_Retrieve(g_psProcessHandleBaseTable, uiPid); - - /* In case there is none we are going to allocate one */ - if (psBase == NULL) - { - IMG_BOOL bSuccess; - - psBase = OSAllocZMem(sizeof(*psBase)); - PVR_LOG_GOTO_IF_NOMEM(psBase, eError, ErrorUnlock); - - /* Allocate handle base for this process */ - eError = PVRSRVAllocHandleBase(&psBase->psHandleBase, PVRSRV_HANDLE_BASE_TYPE_PROCESS); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAllocHandleBase", ErrorFreeProcessHandleBase); - - /* Insert the handle base into the global hash table */ - bSuccess = HASH_Insert(g_psProcessHandleBaseTable, uiPid, (uintptr_t) psBase); - PVR_LOG_GOTO_IF_FALSE(bSuccess, "HASH_Insert failed", ErrorFreeHandleBase); - } - - OSAtomicIncrement(&psBase->iRefCount); - - OSLockRelease(g_hProcessHandleBaseLock); - - *ppsBase = psBase; - - return PVRSRV_OK; - -ErrorFreeHandleBase: - PVRSRVFreeHandleBase(psBase->psHandleBase, 0); -ErrorFreeProcessHandleBase: - OSFreeMem(psBase); -ErrorUnlock: - OSLockRelease(g_hProcessHandleBaseLock); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVReleaseProcessHandleBase - @Description Decrements reference count on a process handle base psBase - for a process identified by uiPid. If the reference count - reaches 0 the handle base will be freed.. - @Input psBase - pointer to a process handle base - @Inout uiPid - PID of a process - @Inout ui64MaxBridgeTime - maximum time a handle destroy operation - can hold the handle base lock (after that - time a lock will be release and reacquired - for another time slice) - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVReleaseProcessHandleBase(PROCESS_HANDLE_BASE *psBase, IMG_PID uiPid, - IMG_UINT64 ui64MaxBridgeTime) -{ - PVRSRV_ERROR eError; - IMG_INT iRefCount; - uintptr_t uiHashValue; - - OSLockAcquire(g_hProcessHandleBaseLock); - - iRefCount = OSAtomicDecrement(&psBase->iRefCount); - - if (iRefCount != 0) - { - OSLockRelease(g_hProcessHandleBaseLock); - return PVRSRV_OK; - } - - /* in case the refcount becomes 0 we can remove the process handle base - * and all related objects */ - - uiHashValue = HASH_Remove(g_psProcessHandleBaseTable, uiPid); - OSLockRelease(g_hProcessHandleBaseLock); - - PVR_LOG_RETURN_IF_FALSE(uiHashValue != 0, "HASH_Remove failed", - PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE); - - eError = PVRSRVFreeKernelHandles(psBase->psHandleBase); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeKernelHandles"); - - eError = PVRSRVFreeHandleBase(psBase->psHandleBase, ui64MaxBridgeTime); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeHandleBase"); - - OSFreeMem(psBase); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - @Function PVRSRVFreeHandleBase - @Description Free a handle base structure - @Input psBase - pointer to handle base structure - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime) -{ -#if defined(DEBUG) - COUNT_HANDLE_DATA sCountData = {NULL}; -#endif - FREE_HANDLE_DATA sHandleData = {NULL}; - IMG_UINT32 i; - PVRSRV_ERROR eError; - IMG_PID uiCleanupPid = PVRSRVCleanupThreadGetPid(); - uintptr_t uiCleanupTid = PVRSRVCleanupThreadGetTid(); - - PVR_ASSERT(gpsHandleFuncs); - - LockHandle(psBase); - - /* If this is a process handle base being freed by the cleanup - * thread, store this in g_psProcessHandleBaseBeingFreed - */ - if ((OSGetCurrentProcessID() == uiCleanupPid) && - (OSGetCurrentThreadID() == uiCleanupTid) && - (psBase->eType == PVRSRV_HANDLE_BASE_TYPE_PROCESS)) - { - g_psProcessHandleBaseBeingFreed = psBase; - } - - sHandleData.psBase = psBase; - sHandleData.ui64TimeStart = OSClockns64(); - sHandleData.ui64MaxBridgeTime = ui64MaxBridgeTime; - - -#if defined(DEBUG) - - sCountData.psBase = psBase; - - eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase, - &CountHandleDataWrapper, - (void *)&sCountData); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnIterateOverHandles", ExitUnlock); - - if (sCountData.uiHandleDataCount != 0) - { - IMG_BOOL bList = (IMG_BOOL)(sCountData.uiHandleDataCount < HANDLE_DEBUG_LISTING_MAX_NUM); - - PVR_DPF((PVR_DBG_WARNING, - "%s: %u remaining handles in handle base 0x%p " - "(PVRSRV_HANDLE_BASE_TYPE %u).%s", - __func__, - sCountData.uiHandleDataCount, - psBase, - psBase->eType, - bList ? "": " Skipping details, too many items...")); - - if (bList) - { - PVR_DPF((PVR_DBG_WARNING, "-------- Listing Handles --------")); - (void) gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase, - &ListHandlesInBase, - psBase); - PVR_DPF((PVR_DBG_WARNING, "-------- Done Listing --------")); - } - } - -#endif /* defined(DEBUG) */ - - /* - * As we're freeing handles based on type, make sure all - * handles have actually had their data freed to avoid - * resources being leaked - */ - for (i = 0; i < ARRAY_SIZE(g_aeOrderedFreeList); i++) - { - sHandleData.eHandleFreeType = g_aeOrderedFreeList[i]; - - /* Make sure all handles have been freed before destroying the handle base */ - eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase, - &FreeHandleDataWrapper, - (void *)&sHandleData); - PVR_GOTO_IF_ERROR(eError, ExitUnlock); - } - - - if (psBase->psHashTab != NULL) - { - HASH_Delete(psBase->psHashTab); - } - - eError = gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase); - PVR_GOTO_IF_ERROR(eError, ExitUnlock); - - UnlockHandle(psBase); - OSLockDestroy(psBase->hLock); - OSFreeMem(psBase); - - return eError; - -ExitUnlock: - if ((OSGetCurrentProcessID() == uiCleanupPid) && - (OSGetCurrentThreadID() == uiCleanupTid)) - { - g_psProcessHandleBaseBeingFreed = NULL; - } - UnlockHandle(psBase); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVHandleInit - @Description Initialise handle management - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVHandleInit(void) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsKernelHandleBase == NULL); - PVR_ASSERT(gpsHandleFuncs == NULL); - PVR_ASSERT(g_hProcessHandleBaseLock == NULL); - PVR_ASSERT(g_psProcessHandleBaseTable == NULL); - PVR_ASSERT(!gbLockInitialised); - - eError = OSLockCreate(&gKernelHandleLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate:1"); - - eError = OSLockCreate(&g_hProcessHandleBaseLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate:2", ErrorHandleDeinit); - - gbLockInitialised = IMG_TRUE; - - eError = PVRSRVHandleGetFuncTable(&gpsHandleFuncs); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVHandleGetFuncTable", ErrorHandleDeinit); - - eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase, - PVRSRV_HANDLE_BASE_TYPE_GLOBAL); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAllocHandleBase", ErrorHandleDeinit); - - g_psProcessHandleBaseTable = HASH_Create(HANDLE_PROC_HANDLE_HASH_INIT_SIZE); - PVR_LOG_GOTO_IF_NOMEM(g_psProcessHandleBaseTable, eError, ErrorHandleDeinit); - - eError = gpsHandleFuncs->pfnEnableHandlePurging(gpsKernelHandleBase->psImplBase); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnEnableHandlePurging", ErrorHandleDeinit); - - return PVRSRV_OK; - -ErrorHandleDeinit: - (void) PVRSRVHandleDeInit(); - - return eError; -} - -/*! -******************************************************************************* - @Function PVRSRVHandleDeInit - @Description De-initialise handle management - @Return Error code or PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR PVRSRVHandleDeInit(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (gpsHandleFuncs != NULL) - { - if (gpsKernelHandleBase != NULL) - { - eError = PVRSRVFreeHandleBase(gpsKernelHandleBase, 0 /* do not release bridge lock */); - if (eError == PVRSRV_OK) - { - gpsKernelHandleBase = NULL; - } - else - { - PVR_LOG_ERROR(eError, "PVRSRVFreeHandleBase"); - } - } - - if (eError == PVRSRV_OK) - { - gpsHandleFuncs = NULL; - } - } - else - { - /* If we don't have a handle function table we shouldn't have a handle base either */ - PVR_ASSERT(gpsKernelHandleBase == NULL); - } - - if (g_psProcessHandleBaseTable != NULL) - { - HASH_Delete(g_psProcessHandleBaseTable); - g_psProcessHandleBaseTable = NULL; - } - - if (g_hProcessHandleBaseLock != NULL) - { - OSLockDestroy(g_hProcessHandleBaseLock); - g_hProcessHandleBaseLock = NULL; - } - - if (gKernelHandleLock != NULL) - { - OSLockDestroy(gKernelHandleLock); - gbLockInitialised = IMG_FALSE; - } - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/handle.h b/drivers/gpu/drm/img-rogue/1.17/handle.h deleted file mode 100644 index 92946b6fbb365..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/handle.h +++ /dev/null @@ -1,206 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Handle Manager API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide handle management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(HANDLE_API_H) -#define HANDLE_API_H - -#include "lock_types.h" - -/* - * Handle API - * ---------- - * The handle API is intended to provide handles for kernel resources, which - * can then be passed back to user space processes. - * - * The following functions comprise the API. Each function takes a pointer to - * a PVRSRV_HANDLE_BASE structure, one of which is allocated for each process, - * and stored in the per-process data area. Use KERNEL_HANDLE_BASE for handles - * not allocated for a particular process, or for handles that need to be - * allocated before the PVRSRV_HANDLE_BASE structure for the process is - * available. - * - * PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, - * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, - * PVRSRV_HANDLE_ALLOC_FLAG eFlag); - * - * Allocate a handle phHandle, for the resource of type eType pointed to by - * pvData. - * - * For handles that have a definite lifetime, where the corresponding resource - * is explicitly created and destroyed, eFlag should be zero. - * - * If a particular resource may be referenced multiple times by a given - * process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI will allow multiple - * handles to be allocated for the resource. Such handles cannot be found with - * PVRSRVFindHandle. - * - * PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, - * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, - * PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); - * - * This function is similar to PVRSRVAllocHandle, except that the allocated - * handles are associated with a parent handle, hParent, that has been - * allocated previously. Subhandles are automatically deallocated when their - * parent handle is deallocated. - * Subhandles can be treated as ordinary handles. For example, they may have - * subhandles of their own, and may be explicitly deallocated using - * PVRSRVReleaseHandle (see below). - * - * PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, - * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType); - * - * Find the handle previously allocated for the resource pointed to by pvData, - * of type eType. Handles allocated with the flag - * PVRSRV_HANDLE_ALLOC_FLAG_MULTI cannot be found using this function. - * - * PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, - * void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); - * - * Given a handle for a resource of type eType, return the pointer to the - * resource. - * - * PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, - * void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, - * IMH_HANDLE hAncestor); - * - * Similar to PVRSRVLookupHandle, but checks the handle is a descendant - * of hAncestor. - * - * PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, - * IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); - * - * Deallocate a handle of given type. - * - * Return the parent of a handle in *phParent, or NULL if the handle has - * no parent. - */ - -#include "img_types.h" -#include "img_defs.h" -#include "hash.h" - -typedef enum -{ - #define HANDLETYPE(x) PVRSRV_HANDLE_TYPE_##x, - #include "handle_types.h" - #undef HANDLETYPE -} PVRSRV_HANDLE_TYPE; - -static_assert(PVRSRV_HANDLE_TYPE_NONE == 0, "PVRSRV_HANDLE_TYPE_NONE must be zero"); - -typedef enum -{ - PVRSRV_HANDLE_BASE_TYPE_CONNECTION, - PVRSRV_HANDLE_BASE_TYPE_PROCESS, - PVRSRV_HANDLE_BASE_TYPE_GLOBAL -} PVRSRV_HANDLE_BASE_TYPE; - - -typedef enum -{ - /* No flags */ - PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0, - /* Multiple handles can point at the given data pointer */ - PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x01, - /* Subhandles are allocated in a private handle space */ - PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x02 -} PVRSRV_HANDLE_ALLOC_FLAG; - -typedef struct _HANDLE_BASE_ PVRSRV_HANDLE_BASE; - -typedef struct _PROCESS_HANDLE_BASE_ -{ - PVRSRV_HANDLE_BASE *psHandleBase; - ATOMIC_T iRefCount; -} PROCESS_HANDLE_BASE; - -extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase; -#define KERNEL_HANDLE_BASE (gpsKernelHandleBase) - -#define HANDLE_DEBUG_LISTING_MAX_NUM 20 - -typedef PVRSRV_ERROR (*PFN_HANDLE_RELEASE)(void *pvData); - -PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData); -PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData); - -PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); -PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); - -PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType); -PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType); - -PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef); -PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef); - -PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor); - -void PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -void PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); - -PVRSRV_ERROR PVRSRVDestroyHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -PVRSRV_ERROR PVRSRVDestroyHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -PVRSRV_ERROR PVRSRVDestroyHandleStagedUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); - -PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase); - -PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase, - PVRSRV_HANDLE_BASE_TYPE eType); - -PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime); - -PVRSRV_ERROR PVRSRVFreeKernelHandles(PVRSRV_HANDLE_BASE *psBase); - -PVRSRV_ERROR PVRSRVHandleInit(void); - -PVRSRV_ERROR PVRSRVHandleDeInit(void); - -PVRSRV_HANDLE_BASE *PVRSRVRetrieveProcessHandleBase(void); - -PVRSRV_ERROR PVRSRVAcquireProcessHandleBase(IMG_PID uiPid, PROCESS_HANDLE_BASE **ppsBase); -PVRSRV_ERROR PVRSRVReleaseProcessHandleBase(PROCESS_HANDLE_BASE *psBase, IMG_PID uiPid, IMG_UINT64 ui64MaxBridgeTime); - -void LockHandle(PVRSRV_HANDLE_BASE *psBase); -void UnlockHandle(PVRSRV_HANDLE_BASE *psBase); - -#endif /* !defined(HANDLE_API_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/handle_idr.c b/drivers/gpu/drm/img-rogue/1.17/handle_idr.c deleted file mode 100644 index c40e096bfaa54..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/handle_idr.c +++ /dev/null @@ -1,440 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Resource Handle Manager - IDR Back-end -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide IDR based resource handle management back-end -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "handle_impl.h" -#include "allocmem.h" -#include "osfunc.h" -#include "pvr_debug.h" - -#define ID_VALUE_MIN 1 -#define ID_VALUE_MAX INT_MAX - -#define ID_TO_HANDLE(i) ((IMG_HANDLE)(uintptr_t)(i)) -#define HANDLE_TO_ID(h) ((IMG_INT)(uintptr_t)(h)) - -struct _HANDLE_IMPL_BASE_ -{ - struct idr sIdr; - - IMG_UINT32 ui32MaxHandleValue; - - IMG_UINT32 ui32TotalHandCount; -}; - -typedef struct _HANDLE_ITER_DATA_WRAPPER_ -{ - PFN_HANDLE_ITER pfnHandleIter; - void *pvHandleIterData; -} HANDLE_ITER_DATA_WRAPPER; - - -static int HandleIterFuncWrapper(int id, void *data, void *iter_data) -{ - HANDLE_ITER_DATA_WRAPPER *psIterData = (HANDLE_ITER_DATA_WRAPPER *)iter_data; - - PVR_UNREFERENCED_PARAMETER(data); - - return (int)psIterData->pfnHandleIter(ID_TO_HANDLE(id), psIterData->pvHandleIterData); -} - -/*! -****************************************************************************** - - @Function AcquireHandle - - @Description Acquire a new handle - - @Input psBase - Pointer to handle base structure - phHandle - Points to a handle pointer - pvData - Pointer to resource to be associated with the handle - - @Output phHandle - Points to a handle pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR AcquireHandle(HANDLE_IMPL_BASE *psBase, - IMG_HANDLE *phHandle, - void *pvData) -{ - int id; - int result; - - PVR_ASSERT(psBase != NULL); - PVR_ASSERT(phHandle != NULL); - PVR_ASSERT(pvData != NULL); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) - idr_preload(GFP_KERNEL); - id = idr_alloc(&psBase->sIdr, pvData, ID_VALUE_MIN, psBase->ui32MaxHandleValue + 1, 0); - idr_preload_end(); - - result = id; -#else - do - { - if (idr_pre_get(&psBase->sIdr, GFP_KERNEL) == 0) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - result = idr_get_new_above(&psBase->sIdr, pvData, ID_VALUE_MIN, &id); - } while (result == -EAGAIN); - - if ((IMG_UINT32)id > psBase->ui32MaxHandleValue) - { - idr_remove(&psBase->sIdr, id); - result = -ENOSPC; - } -#endif - - if (result < 0) - { - if (result == -ENOSPC) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Limit of %u handles reached", - __func__, psBase->ui32MaxHandleValue)); - - return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - } - - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psBase->ui32TotalHandCount++; - - *phHandle = ID_TO_HANDLE(id); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function ReleaseHandle - - @Description Release a handle that is no longer needed. - - @Input psBase - Pointer to handle base structure - hHandle - Handle to release - ppvData - Points to a void data pointer - - @Output ppvData - Points to a void data pointer - - @Return PVRSRV_OK or PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR ReleaseHandle(HANDLE_IMPL_BASE *psBase, - IMG_HANDLE hHandle, - void **ppvData) -{ - int id = HANDLE_TO_ID(hHandle); - void *pvData; - - PVR_ASSERT(psBase); - - /* Get the data associated with the handle. If we get back NULL then - it's an invalid handle */ - - pvData = idr_find(&psBase->sIdr, id); - if (likely(pvData)) - { - idr_remove(&psBase->sIdr, id); - psBase->ui32TotalHandCount--; - } - - if (unlikely(pvData == NULL)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Handle out of range (%u > %u)", - __func__, id, psBase->ui32TotalHandCount)); - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - if (ppvData) - { - *ppvData = pvData; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function GetHandleData - - @Description Get the data associated with the given handle - - @Input psBase - Pointer to handle base structure - hHandle - Handle from which data should be retrieved - ppvData - Points to a void data pointer - - @Output ppvData - Points to a void data pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR GetHandleData(HANDLE_IMPL_BASE *psBase, - IMG_HANDLE hHandle, - void **ppvData) -{ - int id = HANDLE_TO_ID(hHandle); - void *pvData; - - PVR_ASSERT(psBase); - PVR_ASSERT(ppvData); - - pvData = idr_find(&psBase->sIdr, id); - if (likely(pvData)) - { - *ppvData = pvData; - - return PVRSRV_OK; - } - else - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } -} - -/*! -****************************************************************************** - - @Function SetHandleData - - @Description Set the data associated with the given handle - - @Input psBase - Pointer to handle base structure - hHandle - Handle for which data should be changed - pvData - Pointer to new data to be associated with the handle - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR SetHandleData(HANDLE_IMPL_BASE *psBase, - IMG_HANDLE hHandle, - void *pvData) -{ - int id = HANDLE_TO_ID(hHandle); - void *pvOldData; - - PVR_ASSERT(psBase); - - pvOldData = idr_replace(&psBase->sIdr, pvData, id); - if (IS_ERR(pvOldData)) - { - if (PTR_ERR(pvOldData) == -ENOENT) - { - return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED; - } - else - { - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR IterateOverHandles(HANDLE_IMPL_BASE *psBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData) -{ - HANDLE_ITER_DATA_WRAPPER sIterData; - - PVR_ASSERT(psBase); - PVR_ASSERT(pfnHandleIter); - - sIterData.pfnHandleIter = pfnHandleIter; - sIterData.pvHandleIterData = pvHandleIterData; - - return (PVRSRV_ERROR)idr_for_each(&psBase->sIdr, HandleIterFuncWrapper, &sIterData); -} - -/*! -****************************************************************************** - - @Function EnableHandlePurging - - @Description Enable purging for a given handle base - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR EnableHandlePurging(HANDLE_IMPL_BASE *psBase) -{ - PVR_UNREFERENCED_PARAMETER(psBase); - PVR_ASSERT(psBase); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PurgeHandles - - @Description Purge handles for a given handle base - - @Input psBase - Pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR PurgeHandles(HANDLE_IMPL_BASE *psBase) -{ - PVR_UNREFERENCED_PARAMETER(psBase); - PVR_ASSERT(psBase); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function CreateHandleBase - - @Description Create a handle base structure - - @Input ppsBase - pointer to handle base structure pointer - - @Output ppsBase - points to handle base structure pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR CreateHandleBase(HANDLE_IMPL_BASE **ppsBase) -{ - HANDLE_IMPL_BASE *psBase; - - PVR_ASSERT(ppsBase); - - psBase = OSAllocZMem(sizeof(*psBase)); - if (psBase == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't allocate generic handle base", - __func__)); - - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - idr_init(&psBase->sIdr); - - psBase->ui32MaxHandleValue = ID_VALUE_MAX; - psBase->ui32TotalHandCount = 0; - - *ppsBase = psBase; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function DestroyHandleBase - - @Description Destroy a handle base structure - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR DestroyHandleBase(HANDLE_IMPL_BASE *psBase) -{ - PVR_ASSERT(psBase); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) - idr_remove_all(&psBase->sIdr); -#endif - - /* Finally destroy the idr */ - idr_destroy(&psBase->sIdr); - - OSFreeMem(psBase); - - return PVRSRV_OK; -} - - -static const HANDLE_IMPL_FUNCTAB g_sHandleFuncTab = -{ - .pfnAcquireHandle = AcquireHandle, - .pfnReleaseHandle = ReleaseHandle, - .pfnGetHandleData = GetHandleData, - .pfnSetHandleData = SetHandleData, - .pfnIterateOverHandles = IterateOverHandles, - .pfnEnableHandlePurging = EnableHandlePurging, - .pfnPurgeHandles = PurgeHandles, - .pfnCreateHandleBase = CreateHandleBase, - .pfnDestroyHandleBase = DestroyHandleBase -}; - -PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs) -{ - static IMG_BOOL bAcquired = IMG_FALSE; - - if (bAcquired) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Function table already acquired", - __func__)); - return PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - - if (ppsFuncs == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *ppsFuncs = &g_sHandleFuncTab; - - bAcquired = IMG_TRUE; - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/handle_impl.h b/drivers/gpu/drm/img-rogue/1.17/handle_impl.h deleted file mode 100644 index 94305979d1307..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/handle_impl.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Implementation Callbacks for Handle Manager API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the handle manager API. This file is for declarations - and definitions that are private/internal to the handle manager - API but need to be shared between the generic handle manager - code and the various handle manager backends, i.e. the code that - implements the various callbacks. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(HANDLE_IMPL_H) -#define HANDLE_IMPL_H - -#include "img_types.h" -#include "pvrsrv_error.h" - -typedef struct _HANDLE_IMPL_BASE_ HANDLE_IMPL_BASE; - -typedef PVRSRV_ERROR (*PFN_HANDLE_ITER)(IMG_HANDLE hHandle, void *pvData); - -typedef struct _HANDLE_IMPL_FUNCTAB_ -{ - /* Acquire a new handle which is associated with the given data */ - PVRSRV_ERROR (*pfnAcquireHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE *phHandle, void *pvData); - - /* Release the given handle (optionally returning the data associated with it) */ - PVRSRV_ERROR (*pfnReleaseHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData); - - /* Get the data associated with the given handle */ - PVRSRV_ERROR (*pfnGetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData); - - /* Set the data associated with the given handle */ - PVRSRV_ERROR (*pfnSetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void *pvData); - - PVRSRV_ERROR (*pfnIterateOverHandles)(HANDLE_IMPL_BASE *psHandleBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData); - - /* Enable handle purging on the given handle base */ - PVRSRV_ERROR (*pfnEnableHandlePurging)(HANDLE_IMPL_BASE *psHandleBase); - - /* Purge handles on the given handle base */ - PVRSRV_ERROR (*pfnPurgeHandles)(HANDLE_IMPL_BASE *psHandleBase); - - /* Create handle base */ - PVRSRV_ERROR (*pfnCreateHandleBase)(HANDLE_IMPL_BASE **psHandleBase); - - /* Destroy handle base */ - PVRSRV_ERROR (*pfnDestroyHandleBase)(HANDLE_IMPL_BASE *psHandleBase); -} HANDLE_IMPL_FUNCTAB; - -PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs); - -#endif /* !defined(HANDLE_IMPL_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/handle_types.h b/drivers/gpu/drm/img-rogue/1.17/handle_types.h deleted file mode 100644 index 11bde35d46853..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/handle_types.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Handle Manager handle types -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide handle management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ -/* NOTE: Do not add include guards to this file */ - -HANDLETYPE(NONE) -HANDLETYPE(SHARED_EVENT_OBJECT) -HANDLETYPE(EVENT_OBJECT_CONNECT) -HANDLETYPE(PMR_LOCAL_EXPORT_HANDLE) -HANDLETYPE(PHYSMEM_PMR) -HANDLETYPE(PHYSMEM_PMR_EXPORT) -HANDLETYPE(PHYSMEM_PMR_SECURE_EXPORT) -HANDLETYPE(DEVMEMINT_CTX) -HANDLETYPE(DEVMEMINT_CTX_EXPORT) -HANDLETYPE(DEVMEMINT_HEAP) -HANDLETYPE(DEVMEMINT_RESERVATION) -HANDLETYPE(DEVMEMXINT_RESERVATION) -HANDLETYPE(DEVMEMINT_MAPPING) -HANDLETYPE(RGX_FW_MEMDESC) -HANDLETYPE(RGX_FREELIST) -HANDLETYPE(RGX_MEMORY_BLOCK) -HANDLETYPE(RGX_SERVER_RENDER_CONTEXT) -HANDLETYPE(RGX_SERVER_TQ_CONTEXT) -HANDLETYPE(RGX_SERVER_TQ_TDM_CONTEXT) -HANDLETYPE(RGX_SERVER_COMPUTE_CONTEXT) -HANDLETYPE(RGX_SERVER_RAY_CONTEXT) -HANDLETYPE(RGX_SERVER_KICKSYNC_CONTEXT) -#if defined(PVR_TESTING_UTILS) && defined(SUPPORT_VALIDATION) -HANDLETYPE(RGX_SERVER_GPUMAP_CONTEXT) -#endif -HANDLETYPE(SYNC_PRIMITIVE_BLOCK) -HANDLETYPE(SYNC_RECORD_HANDLE) -HANDLETYPE(PVRSRV_TIMELINE_SERVER) -HANDLETYPE(PVRSRV_FENCE_SERVER) -HANDLETYPE(PVRSRV_FENCE_EXPORT) -HANDLETYPE(RGX_KM_HW_RT_DATASET) -HANDLETYPE(RGX_FWIF_ZSBUFFER) -HANDLETYPE(RGX_POPULATION) -HANDLETYPE(DC_DEVICE) -HANDLETYPE(DC_DISPLAY_CONTEXT) -HANDLETYPE(DC_BUFFER) -HANDLETYPE(DC_PIN_HANDLE) -HANDLETYPE(DEVMEM_MEM_IMPORT) -HANDLETYPE(PHYSMEM_PMR_PAGELIST) -HANDLETYPE(PVR_TL_SD) -HANDLETYPE(RI_HANDLE) -HANDLETYPE(DEV_PRIV_DATA) -HANDLETYPE(MM_PLAT_CLEANUP) -HANDLETYPE(WORKEST_RETURN_DATA) -HANDLETYPE(DI_CONTEXT) -HANDLETYPE(DEVMEMINT_RESERVATION2) diff --git a/drivers/gpu/drm/img-rogue/1.17/hash.c b/drivers/gpu/drm/img-rogue/1.17/hash.c deleted file mode 100644 index 994ae5871f5fe..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/hash.c +++ /dev/null @@ -1,734 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Self scaling hash tables. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description - Implements simple self scaling hash tables. Hash collisions are handled by - chaining entries together. Hash tables are increased in size when they - become more than (50%?) full and decreased in size when less than (25%?) - full. Hash tables are never decreased below their initial size. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "img_types.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -/* services/shared/include/ */ -#include "hash.h" - -/* services/client/include/ or services/server/include/ */ -#include "osfunc_common.h" -#include "allocmem.h" - -//#define PERF_DBG_RESIZE -#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE) -#include -#endif - -#if defined(__KERNEL__) -#include "pvrsrv.h" -#endif - -#define KEY_TO_INDEX(pHash, key, uSize) \ - ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize)) - -#define KEY_COMPARE(pHash, pKey1, pKey2) \ - ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2))) - -#if defined(__linux__) && defined(__KERNEL__) -#define _AllocMem OSAllocMemNoStats -#define _AllocZMem OSAllocZMemNoStats -#define _FreeMem OSFreeMemNoStats -#else -#define _AllocMem OSAllocMem -#define _AllocZMem OSAllocZMem -#define _FreeMem OSFreeMem -#endif - -#define NO_SHRINK 0 - -/* Each entry in a hash table is placed into a bucket */ -typedef struct _BUCKET_ -{ - struct _BUCKET_ *pNext; /*!< the next bucket on the same chain */ - uintptr_t v; /*!< entry value */ - uintptr_t k[]; /* PRQA S 0642 */ - /* override dynamic array declaration warning */ -} BUCKET; - -struct _HASH_TABLE_ -{ - IMG_UINT32 uSize; /*!< current size of the hash table */ - IMG_UINT32 uCount; /*!< number of entries currently in the hash table */ - IMG_UINT32 uMinimumSize; /*!< the minimum size that the hash table should be re-sized to */ - IMG_UINT32 uKeySize; /*!< size of key in bytes */ - IMG_UINT32 uShrinkThreshold; /*!< The threshold at which to trigger a shrink */ - IMG_UINT32 uGrowThreshold; /*!< The threshold at which to trigger a grow */ - HASH_FUNC* pfnHashFunc; /*!< hash function */ - HASH_KEY_COMP* pfnKeyComp; /*!< key comparison function */ - BUCKET** ppBucketTable; /*!< the hash table array */ -#if defined(DEBUG) - const char* pszFile; - unsigned int ui32LineNum; -#endif -}; - -/*************************************************************************/ /*! -@Function HASH_Func_Default -@Description Hash function intended for hashing keys composed of uintptr_t - arrays. -@Input uKeySize The size of the hash key, in bytes. -@Input pKey A pointer to the key to hash. -@Input uHashTabLen The length of the hash table. -@Return The hash value. -*/ /**************************************************************************/ -IMG_INTERNAL IMG_UINT32 -HASH_Func_Default(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen) -{ - uintptr_t *p = (uintptr_t *)pKey; - IMG_UINT32 uKeyLen = uKeySize / sizeof(uintptr_t); - IMG_UINT32 ui; - IMG_UINT32 uHashKey = 0; - - PVR_UNREFERENCED_PARAMETER(uHashTabLen); - - PVR_ASSERT((uKeySize % sizeof(uintptr_t)) == 0); - - for (ui = 0; ui < uKeyLen; ui++) - { - IMG_UINT32 uHashPart = (IMG_UINT32)*p++; - - uHashPart += (uHashPart << 12); - uHashPart ^= (uHashPart >> 22); - uHashPart += (uHashPart << 4); - uHashPart ^= (uHashPart >> 9); - uHashPart += (uHashPart << 10); - uHashPart ^= (uHashPart >> 2); - uHashPart += (uHashPart << 7); - uHashPart ^= (uHashPart >> 12); - - uHashKey += uHashPart; - } - - return uHashKey; -} - -/*************************************************************************/ /*! -@Function HASH_Key_Comp_Default -@Description Compares keys composed of uintptr_t arrays. -@Input uKeySize The size of the hash key, in bytes. -@Input pKey1 Pointer to first hash key to compare. -@Input pKey2 Pointer to second hash key to compare. -@Return IMG_TRUE - The keys match. - IMG_FALSE - The keys don't match. -*/ /**************************************************************************/ -IMG_INTERNAL IMG_BOOL -HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2) -{ - uintptr_t *p1 = (uintptr_t *)pKey1; - uintptr_t *p2 = (uintptr_t *)pKey2; - IMG_UINT32 uKeyLen = uKeySize / sizeof(uintptr_t); - IMG_UINT32 ui; - - PVR_ASSERT((uKeySize % sizeof(uintptr_t)) == 0); - - for (ui = 0; ui < uKeyLen; ui++) - { - if (*p1++ != *p2++) - return IMG_FALSE; - } - - return IMG_TRUE; -} - -/*************************************************************************/ /*! -@Function _ChainInsert -@Description Insert a bucket into the appropriate hash table chain. -@Input pBucket The bucket -@Input ppBucketTable The hash table -@Input uSize The size of the hash table -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static void -_ChainInsert(HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize) -{ - IMG_UINT32 uIndex; - - /* We assume that all parameters passed by the caller are valid. */ - PVR_ASSERT(pBucket != NULL); - PVR_ASSERT(ppBucketTable != NULL); - PVR_ASSERT(uSize != 0); - - uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); /* PRQA S 0432,0541 */ /* ignore dynamic array warning */ - pBucket->pNext = ppBucketTable[uIndex]; - ppBucketTable[uIndex] = pBucket; -} - -/*************************************************************************/ /*! -@Function _Rehash -@Description Iterate over every entry in an old hash table and rehash into - the new table. -@Input ppOldTable The old hash table -@Input uOldSize The size of the old hash table -@Input ppNewTable The new hash table -@Input uNewSize The size of the new hash table -@Return None -*/ /**************************************************************************/ -static void -_Rehash(HASH_TABLE *pHash, - BUCKET **ppOldTable, IMG_UINT32 uOldSize, - BUCKET **ppNewTable, IMG_UINT32 uNewSize) -{ - IMG_UINT32 uIndex; - for (uIndex=0; uIndex< uOldSize; uIndex++) - { - BUCKET *pBucket; - pBucket = ppOldTable[uIndex]; - while (pBucket != NULL) - { - BUCKET *pNextBucket = pBucket->pNext; - _ChainInsert(pHash, pBucket, ppNewTable, uNewSize); - pBucket = pNextBucket; - } - } -} - -/*************************************************************************/ /*! -@Function _Resize -@Description Attempt to resize a hash table, failure to allocate a new - larger hash table is not considered a hard failure. We simply - continue and allow the table to fill up, the effect is to - allow hash chains to become longer. -@Input pHash Hash table to resize. -@Input uNewSize Required table size. -@Return IMG_TRUE Success - IMG_FALSE Failed -*/ /**************************************************************************/ -static IMG_BOOL -_Resize(HASH_TABLE *pHash, IMG_UINT32 uNewSize) -{ - BUCKET **ppNewTable; - IMG_UINT32 uiThreshold = uNewSize >> 2; -#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE) - struct timeval start, end; -#endif - - if (uNewSize == pHash->uSize) - { - return IMG_TRUE; - } - -#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE) - gettimeofday(&start, NULL); -#endif - - ppNewTable = _AllocZMem(sizeof(BUCKET *) * uNewSize); - if (ppNewTable == NULL) - { - return IMG_FALSE; - } - - _Rehash(pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize); - - _FreeMem(pHash->ppBucketTable); - -#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE) - gettimeofday(&end, NULL); - if (start.tv_usec > end.tv_usec) - { - end.tv_usec = 1000000 - start.tv_usec + end.tv_usec; - } - else - { - end.tv_usec -= start.tv_usec; - } - - PVR_DPF((PVR_DBG_ERROR, "%s: H:%p O:%d N:%d C:%d G:%d S:%d T:%06luus", __func__, pHash, pHash->uSize, uNewSize, pHash->uCount, pHash->uGrowThreshold, pHash->uShrinkThreshold, end.tv_usec)); -#endif - - /*not nulling pointer, being reassigned just below*/ - pHash->ppBucketTable = ppNewTable; - pHash->uSize = uNewSize; - - pHash->uGrowThreshold = uiThreshold * 3; - pHash->uShrinkThreshold = (uNewSize <= pHash->uMinimumSize) ? NO_SHRINK : uiThreshold; - - return IMG_TRUE; -} - - -/*************************************************************************/ /*! -@Function HASH_Create_Extended -@Description Create a self scaling hash table, using the supplied key size, - and the supplied hash and key comparison functions. -@Input uInitialLen Initial and minimum length of the hash table, - where the length refers to the number of entries - in the hash table, not its size in bytes. -@Input uKeySize The size of the key, in bytes. -@Input pfnHashFunc Pointer to hash function. -@Input pfnKeyComp Pointer to key comparison function. -@Return NULL or hash table handle. -*/ /**************************************************************************/ -IMG_INTERNAL -HASH_TABLE * HASH_Create_Extended_Int (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp) -{ - HASH_TABLE *pHash; - - if (uInitialLen == 0 || uKeySize == 0 || pfnHashFunc == NULL || pfnKeyComp == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid input parameters", __func__)); - return NULL; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: InitialSize=0x%x", __func__, uInitialLen)); - - pHash = _AllocMem(sizeof(HASH_TABLE)); - if (pHash == NULL) - { - return NULL; - } - - pHash->uCount = 0; - pHash->uSize = uInitialLen; - pHash->uMinimumSize = uInitialLen; - pHash->uKeySize = uKeySize; - pHash->uGrowThreshold = (uInitialLen >> 2) * 3; - pHash->uShrinkThreshold = NO_SHRINK; - pHash->pfnHashFunc = pfnHashFunc; - pHash->pfnKeyComp = pfnKeyComp; - - pHash->ppBucketTable = _AllocZMem(sizeof(BUCKET *) * pHash->uSize); - if (pHash->ppBucketTable == NULL) - { - _FreeMem(pHash); - /*not nulling pointer, out of scope*/ - return NULL; - } - - return pHash; -} - -#if defined(DEBUG) -IMG_INTERNAL -HASH_TABLE * HASH_Create_Extended_Debug (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp, - const char *file, const unsigned int line) -{ - HASH_TABLE *hash; - hash = HASH_Create_Extended_Int(uInitialLen, uKeySize, - pfnHashFunc, pfnKeyComp); - if (hash) - { - hash->pszFile = file; - hash->ui32LineNum = line; - } - return hash; -} -#endif - -/*************************************************************************/ /*! -@Function HASH_Create -@Description Create a self scaling hash table with a key consisting of a - single uintptr_t, and using the default hash and key - comparison functions. -@Input uInitialLen Initial and minimum length of the hash table, - where the length refers to the number of entries - in the hash table, not its size in bytes. -@Return NULL or hash table handle. -*/ /**************************************************************************/ -IMG_INTERNAL -HASH_TABLE * HASH_Create_Int (IMG_UINT32 uInitialLen) -{ - return HASH_Create_Extended_Int(uInitialLen, sizeof(uintptr_t), - &HASH_Func_Default, &HASH_Key_Comp_Default); -} - -#if defined(DEBUG) -IMG_INTERNAL -HASH_TABLE * HASH_Create_Debug(IMG_UINT32 uInitialLen, const char *file, const unsigned int line) -{ - HASH_TABLE *hash; - hash = HASH_Create_Extended_Int(uInitialLen, sizeof(uintptr_t), - &HASH_Func_Default, &HASH_Key_Comp_Default); - if (hash) - { - hash->pszFile = file; - hash->ui32LineNum = line; - } - return hash; -} -#endif - -/*************************************************************************/ /*! -@Function HASH_Delete_Extended -@Description Delete a hash table created by HASH_Create_Extended or - HASH_Create. All entries in the table should have been removed - before calling this function. -@Input pHash Hash table -@Input bWarn Set false to suppress warnings in the case of - deletion with active entries. -*/ /**************************************************************************/ -IMG_INTERNAL void -HASH_Delete_Extended(HASH_TABLE *pHash, IMG_BOOL bWarn) -{ - IMG_BOOL bDoCheck = IMG_TRUE; -#if defined(__KERNEL__) && !defined(__QNXNTO__) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if (psPVRSRVData != NULL) - { - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - bDoCheck = IMG_FALSE; - } - } -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - else - { - bDoCheck = IMG_FALSE; - } -#endif -#endif - if (pHash != NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "HASH_Delete")); - - if (bDoCheck) - { - PVR_ASSERT(pHash->uCount==0); - } - if (pHash->uCount != 0) - { - IMG_UINT32 i; - if (bWarn) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Leak detected in hash table!", __func__)); - PVR_DPF((PVR_DBG_ERROR, "%s: Likely Cause: client drivers not freeing allocations before destroying devmem context", __func__)); - PVR_DPF((PVR_DBG_ERROR, "%s: Removing remaining %u hash entries.", __func__, pHash->uCount)); -#if defined(DEBUG) - PVR_DPF ((PVR_DBG_ERROR, "%s: Hash %p created at %s:%u.", __func__, (uintptr_t*)pHash, pHash->pszFile, pHash->ui32LineNum)); -#endif - } - - for (i = 0; i < pHash->uSize; i++) - { - BUCKET *pBucket = pHash->ppBucketTable[i]; - while (pBucket != NULL) - { - BUCKET *pNextBucket = pBucket->pNext; - _FreeMem(pBucket); - pBucket = pNextBucket; - } - } - - } - _FreeMem(pHash->ppBucketTable); - pHash->ppBucketTable = NULL; - _FreeMem(pHash); - /*not nulling pointer, copy on stack*/ - } -} - -/*************************************************************************/ /*! -@Function HASH_Delete -@Description Delete a hash table created by HASH_Create_Extended or - HASH_Create. All entries in the table must have been removed - before calling this function. -@Input pHash Hash table -*/ /**************************************************************************/ -IMG_INTERNAL void -HASH_Delete(HASH_TABLE *pHash) -{ - HASH_Delete_Extended(pHash, IMG_TRUE); -} - -/*************************************************************************/ /*! -@Function HASH_Insert_Extended -@Description Insert a key value pair into a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to the key. -@Input v The value associated with the key. -@Return IMG_TRUE - success. - IMG_FALSE - failure. -*/ /**************************************************************************/ -IMG_INTERNAL IMG_BOOL -HASH_Insert_Extended(HASH_TABLE *pHash, void *pKey, uintptr_t v) -{ - BUCKET *pBucket; - - PVR_ASSERT(pHash != NULL); - - if (pHash == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter", __func__)); - return IMG_FALSE; - } - - pBucket = _AllocMem(sizeof(BUCKET) + pHash->uKeySize); - if (pBucket == NULL) - { - return IMG_FALSE; - } - - pBucket->v = v; - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/ - OSCachedMemCopy(pBucket->k, pKey, pHash->uKeySize); - - _ChainInsert(pHash, pBucket, pHash->ppBucketTable, pHash->uSize); - - pHash->uCount++; - - /* check if we need to think about re-balancing */ - if (pHash->uCount > pHash->uGrowThreshold) - { - /* Ignore the return code from _Resize because the hash table is - still in a valid state and although not ideally sized, it is still - functional */ - _Resize(pHash, pHash->uSize << 1); - } - - return IMG_TRUE; -} - -/*************************************************************************/ /*! -@Function HASH_Insert -@Description Insert a key value pair into a hash table created with - HASH_Create. -@Input pHash The hash table. -@Input k The key value. -@Input v The value associated with the key. -@Return IMG_TRUE - success. - IMG_FALSE - failure. -*/ /**************************************************************************/ -IMG_INTERNAL IMG_BOOL -HASH_Insert(HASH_TABLE *pHash, uintptr_t k, uintptr_t v) -{ - return HASH_Insert_Extended(pHash, &k, v); -} - -/*************************************************************************/ /*! -@Function HASH_Remove_Extended -@Description Remove a key from a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -IMG_INTERNAL uintptr_t -HASH_Remove_Extended(HASH_TABLE *pHash, void *pKey) -{ - BUCKET **ppBucket; - IMG_UINT32 uIndex; - - PVR_ASSERT(pHash != NULL); - - if (pHash == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Null hash table", __func__)); - return 0; - } - - uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); - - for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; ppBucket = &((*ppBucket)->pNext)) - { - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ - if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) - { - BUCKET *pBucket = *ppBucket; - uintptr_t v = pBucket->v; - (*ppBucket) = pBucket->pNext; - - _FreeMem(pBucket); - /*not nulling original pointer, already overwritten*/ - - pHash->uCount--; - - /* check if we need to think about re-balancing, when the shrink - * threshold is 0 we are at the minimum size, no further shrink */ - if (pHash->uCount < pHash->uShrinkThreshold) - { - /* Ignore the return code from _Resize because the - hash table is still in a valid state and although - not ideally sized, it is still functional */ - _Resize(pHash, MAX(pHash->uSize >> 1, pHash->uMinimumSize)); - } - - return v; - } - } - return 0; -} - -/*************************************************************************/ /*! -@Function HASH_Remove -@Description Remove a key value pair from a hash table created with - HASH_Create. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -IMG_INTERNAL uintptr_t -HASH_Remove(HASH_TABLE *pHash, uintptr_t k) -{ - return HASH_Remove_Extended(pHash, &k); -} - -/*************************************************************************/ /*! -@Function HASH_Retrieve_Extended -@Description Retrieve a value from a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -IMG_INTERNAL uintptr_t -HASH_Retrieve_Extended(HASH_TABLE *pHash, void *pKey) -{ - BUCKET **ppBucket; - IMG_UINT32 uIndex; - - PVR_ASSERT(pHash != NULL); - - if (pHash == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Null hash table", __func__)); - return 0; - } - - uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); - - for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; ppBucket = &((*ppBucket)->pNext)) - { - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ - if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) - { - BUCKET *pBucket = *ppBucket; - uintptr_t v = pBucket->v; - - return v; - } - } - return 0; -} - -/*************************************************************************/ /*! -@Function HASH_Retrieve -@Description Retrieve a value from a hash table created with HASH_Create. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -IMG_INTERNAL uintptr_t -HASH_Retrieve(HASH_TABLE *pHash, uintptr_t k) -{ - return HASH_Retrieve_Extended(pHash, &k); -} - -/*************************************************************************/ /*! -@Function HASH_Iterate -@Description Iterate over every entry in the hash table. -@Input pHash Hash table to iterate. -@Input pfnCallback Callback to call with the key and data for each -. entry in the hash table -@Return Callback error if any, otherwise PVRSRV_OK -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback, void* args) -{ - IMG_UINT32 uIndex; - for (uIndex=0; uIndex < pHash->uSize; uIndex++) - { - BUCKET *pBucket; - pBucket = pHash->ppBucketTable[uIndex]; - while (pBucket != NULL) - { - PVRSRV_ERROR eError; - BUCKET *pNextBucket = pBucket->pNext; - - eError = pfnCallback((uintptr_t) ((void *) *(pBucket->k)), pBucket->v, args); - - /* The callback might want us to break out early */ - if (eError != PVRSRV_OK) - return eError; - - pBucket = pNextBucket; - } - } - return PVRSRV_OK; -} - -#ifdef HASH_TRACE -/*************************************************************************/ /*! -@Function HASH_Dump -@Description Dump out some information about a hash table. -@Input pHash The hash table. -*/ /**************************************************************************/ -void -HASH_Dump(HASH_TABLE *pHash) -{ - IMG_UINT32 uIndex; - IMG_UINT32 uMaxLength=0; - IMG_UINT32 uEmptyCount=0; - - PVR_ASSERT(pHash != NULL); - for (uIndex=0; uIndexuSize; uIndex++) - { - BUCKET *pBucket; - IMG_UINT32 uLength = 0; - if (pHash->ppBucketTable[uIndex] == NULL) - { - uEmptyCount++; - } - for (pBucket=pHash->ppBucketTable[uIndex]; - pBucket != NULL; - pBucket = pBucket->pNext) - { - uLength++; - } - uMaxLength = MAX(uMaxLength, uLength); - } - - PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d", - pHash->uMinimumSize, pHash->uSize, pHash->uCount)); - PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength)); -} -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/hash.h b/drivers/gpu/drm/img-rogue/1.17/hash.h deleted file mode 100644 index 92d48990af828..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/hash.h +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Self scaling hash tables -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements simple self scaling hash tables. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HASH_H -#define HASH_H - -#include "img_types.h" -#include "pvrsrv_error.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * Keys passed to the comparison function are only guaranteed to be aligned on - * an uintptr_t boundary. - */ -typedef IMG_UINT32 HASH_FUNC(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen); -typedef IMG_BOOL HASH_KEY_COMP(size_t uKeySize, void *pKey1, void *pKey2); - -typedef struct _HASH_TABLE_ HASH_TABLE; - -typedef PVRSRV_ERROR (*HASH_pfnCallback) ( - uintptr_t k, - uintptr_t v, - void* pvPriv -); - -#if defined(DEBUG) -#else -#define HASH_CREATE(LEN) HASH_Create(LEN) -#endif - -/*************************************************************************/ /*! -@Function HASH_Func_Default -@Description Hash function intended for hashing keys composed of uintptr_t - arrays. -@Input uKeySize The size of the hash key, in bytes. -@Input pKey A pointer to the key to hash. -@Input uHashTabLen The length of the hash table. -@Return The hash value. -*/ /**************************************************************************/ -IMG_UINT32 HASH_Func_Default(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen); - -/*************************************************************************/ /*! -@Function HASH_Key_Comp_Default -@Description Compares keys composed of uintptr_t arrays. -@Input uKeySize The size of the hash key, in bytes. -@Input pKey1 Pointer to first hash key to compare. -@Input pKey2 Pointer to second hash key to compare. -@Return IMG_TRUE - The keys match. - IMG_FALSE - The keys don't match. -*/ /**************************************************************************/ -IMG_BOOL HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2); - -/*************************************************************************/ /*! -@Function HASH_Create_Extended -@Description Create a self scaling hash table, using the supplied key size, - and the supplied hash and key comparison functions. -@Input uInitialLen Initial and minimum length of the hash table, - where the length refers to the number of entries - in the hash table, not its size in bytes. -@Input uKeySize The size of the key, in bytes. -@Input pfnHashFunc Pointer to hash function. -@Input pfnKeyComp Pointer to key comparison function. -@Return NULL or hash table handle. -*/ /**************************************************************************/ -HASH_TABLE * HASH_Create_Extended_Int(IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp); -#if defined(DEBUG) -#define HASH_Create_Extended(LEN, KS, FUN, CMP) HASH_Create_Extended_Debug(LEN, KS, FUN, CMP, __FILE__, __LINE__) -HASH_TABLE * HASH_Create_Extended_Debug (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp, - const char *file, const unsigned int line); -#else -#define HASH_Create_Extended HASH_Create_Extended_Int -#endif - -/*************************************************************************/ /*! -@Function HASH_Create -@Description Create a self scaling hash table with a key consisting of a - single uintptr_t, and using the default hash and key - comparison functions. -@Input uInitialLen Initial and minimum length of the hash table, - where the length refers to the number of entries - in the hash table, not its size in bytes. -@Return NULL or hash table handle. -*/ /**************************************************************************/ -HASH_TABLE * HASH_Create_Int(IMG_UINT32 uInitialLen); -#if defined(DEBUG) -#define HASH_Create(LEN) HASH_Create_Debug(LEN, __FILE__, __LINE__) -HASH_TABLE * HASH_Create_Debug (IMG_UINT32 uInitialLen, const char *file, const unsigned int line); -#else -#define HASH_Create HASH_Create_Int -#endif - -/*************************************************************************/ /*! -@Function HASH_Delete_Extended -@Description Delete a hash table created by HASH_Create_Extended or - HASH_Create. All entries in the table should have been removed - before calling this function. -@Input pHash Hash table -@Input bWarn Set false to suppress warnings in the case of - deletion with active entries. -@Return None -*/ /**************************************************************************/ -void HASH_Delete_Extended(HASH_TABLE *pHash, IMG_BOOL bWarn); - -/*************************************************************************/ /*! -@Function HASH_Delete -@Description Delete a hash table created by HASH_Create_Extended or - HASH_Create. All entries in the table must have been removed - before calling this function. -@Input pHash Hash table -@Return None -*/ /**************************************************************************/ -void HASH_Delete(HASH_TABLE *pHash); - -/*************************************************************************/ /*! -@Function HASH_Insert_Extended -@Description Insert a key value pair into a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to the key. -@Input v The value associated with the key. -@Return IMG_TRUE - success. - IMG_FALSE - failure. -*/ /**************************************************************************/ -IMG_BOOL HASH_Insert_Extended(HASH_TABLE *pHash, void *pKey, uintptr_t v); - -/*************************************************************************/ /*! -@Function HASH_Insert -@Description Insert a key value pair into a hash table created with - HASH_Create. -@Input pHash The hash table. -@Input k The key value. -@Input v The value associated with the key. -@Return IMG_TRUE - success. - IMG_FALSE - failure. -*/ /**************************************************************************/ -IMG_BOOL HASH_Insert(HASH_TABLE *pHash, uintptr_t k, uintptr_t v); - -/*************************************************************************/ /*! -@Function HASH_Remove_Extended -@Description Remove a key from a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -uintptr_t HASH_Remove_Extended(HASH_TABLE *pHash, void *pKey); - -/*************************************************************************/ /*! -@Function HASH_Remove -@Description Remove a key value pair from a hash table created with - HASH_Create. -@Input pHash The hash table. -@Input k The key value. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -uintptr_t HASH_Remove(HASH_TABLE *pHash, uintptr_t k); - -/*************************************************************************/ /*! -@Function HASH_Retrieve_Extended -@Description Retrieve a value from a hash table created with - HASH_Create_Extended. -@Input pHash The hash table. -@Input pKey Pointer to key. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -uintptr_t HASH_Retrieve_Extended(HASH_TABLE *pHash, void *pKey); - -/*************************************************************************/ /*! -@Function HASH_Retrieve -@Description Retrieve a value from a hash table created with HASH_Create. -@Input pHash The hash table. -@Input k The key value. -@Return 0 if the key is missing, or the value associated with the key. -*/ /**************************************************************************/ -uintptr_t HASH_Retrieve(HASH_TABLE *pHash, uintptr_t k); - -/*************************************************************************/ /*! -@Function HASH_Iterate -@Description Iterate over every entry in the hash table. -@Input pHash Hash table to iterate. -@Input pfnCallback Callback to call with the key and data for each -. entry in the hash table -@Return Callback error if any, otherwise PVRSRV_OK -*/ /**************************************************************************/ -PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback, void* args); - -#ifdef HASH_TRACE -/*************************************************************************/ /*! -@Function HASH_Dump -@Description Dump out some information about a hash table. -@Input pHash The hash table. -*/ /**************************************************************************/ -void HASH_Dump(HASH_TABLE *pHash); -#endif - -#if defined(__cplusplus) -} -#endif - -#endif /* HASH_H */ - -/****************************************************************************** - End of file (hash.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/htb_debug.c b/drivers/gpu/drm/img-rogue/1.17/htb_debug.c deleted file mode 100644 index 2581d9f0f5d9a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htb_debug.c +++ /dev/null @@ -1,1190 +0,0 @@ -/*************************************************************************/ /*! -@File htb_debug.c -@Title Debug Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides kernel side debugFS Functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxdevice.h" -#include "htbserver.h" -#include "htbuffer.h" -#include "htbuffer_types.h" -#include "tlstream.h" -#include "tlclient.h" -#include "pvrsrv_tlcommon.h" -#include "di_server.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "osfunc.h" -#include "allocmem.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "htb_debug.h" - -// Global data handles for buffer manipulation and processing - -typedef struct { - IMG_PBYTE pBuf; /* Raw data buffer from TL stream */ - IMG_UINT32 uiBufLen; /* Amount of data to process from 'pBuf' */ - IMG_UINT32 uiTotal; /* Total bytes processed */ - IMG_UINT32 uiMsgLen; /* Length of HTB message to be processed */ - IMG_PBYTE pCurr; /* pointer to current message to be decoded */ - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; /* Output string */ -} HTB_Sentinel_t; - -typedef struct -{ - DI_ENTRY *psDumpHostDiEntry; /* debug info entry */ - HTB_Sentinel_t sSentinel; /* private control structure for HTB DI - operations */ - IMG_HANDLE hStream; /* stream handle for debugFS use */ -} HTB_DBG_INFO; - -static HTB_DBG_INFO g_sHTBData; - -// Comment out for extra debug level -// #define HTB_CHATTY_PRINT(x) PVR_DPF(x) -#define HTB_CHATTY_PRINT(x) - -typedef void (DI_PRINTF)(const OSDI_IMPL_ENTRY *, const IMG_CHAR *, ...) __attribute__ ((format (printf, 2, 3))); - -/****************************************************************************** - * debugFS display routines - *****************************************************************************/ -static int HTBDumpBuffer(DI_PRINTF, OSDI_IMPL_ENTRY *, void *); - -static int _DebugHBTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - int retVal; - - PVR_ASSERT(psEntry != NULL); - - /* psEntry should never be NULL */ - if (psEntry == NULL) - { - return -1; - } - - /* Ensure that we have a valid address to use to dump info from. If NULL we - * return a failure code to terminate the DI read call. pvData is either - * DI_START_TOKEN (for the initial call) or an HTB buffer address for - * subsequent calls [returned from the NEXT function]. */ - if (pvData == NULL) - { - return -1; - } - - retVal = HTBDumpBuffer(DIPrintf, psEntry, pvData); - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %d", __func__, retVal)); - - return retVal; -} - -static IMG_UINT32 idToLogIdx(IMG_UINT32); /* Forward declaration */ - -/* - * HTB_GetNextMessage - * - * Get next non-empty message block from the buffer held in pSentinel->pBuf - * If we exhaust the data buffer we refill it (after releasing the previous - * message(s) [only one non-NULL message, but PAD messages will get released - * as we traverse them]. - * - * Input: - * pSentinel references the already acquired data buffer - * - * Output: - * pSentinel - * -> uiMsglen updated to the size of the non-NULL message - * - * Returns: - * Address of first non-NULL message in the buffer (if any) - * NULL if there is no further data available from the stream and the buffer - * contents have been drained. - */ -static IMG_PBYTE HTB_GetNextMessage(HTB_Sentinel_t *pSentinel) -{ - void *pNext, *pLast, *pStart, *pData = NULL; - void *pCurrent; /* Current processing point within buffer */ - PVRSRVTL_PPACKETHDR ppHdr; /* Current packet header */ - IMG_UINT32 uiHdrType; /* Packet header type */ - IMG_UINT32 uiMsgSize; /* Message size of current packet (bytes) */ - IMG_BOOL bUnrecognizedErrorPrinted = IMG_FALSE; - IMG_UINT32 ui32Data; - IMG_UINT32 ui32LogIdx; - PVRSRV_ERROR eError; - - PVR_ASSERT(pSentinel != NULL); - - pLast = pSentinel->pBuf + pSentinel->uiBufLen; - - pStart = pSentinel->pBuf; - - pNext = pStart; - pSentinel->uiMsgLen = 0; // Reset count for this message - uiMsgSize = 0; // nothing processed so far - ui32LogIdx = HTB_SF_LAST; // Loop terminator condition - - do - { - /* - * If we've drained the buffer we must RELEASE and ACQUIRE some more. - */ - if (pNext >= pLast) - { - eError = TLClientReleaseData(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen); - - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'", __func__, - "TLClientAcquireData", PVRSRVGETERRORSTRING(eError))); - return NULL; - } - - // Reset our limits - if we've returned an empty buffer we're done. - pLast = pSentinel->pBuf + pSentinel->uiBufLen; - pStart = pSentinel->pBuf; - pNext = pStart; - - if (pStart == NULL || pLast == NULL) - { - return NULL; - } - } - - /* - * We should have a header followed by data block(s) in the stream. - */ - - pCurrent = pNext; - ppHdr = GET_PACKET_HDR(pCurrent); - - if (ppHdr == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unexpected NULL packet in Host Trace buffer", - __func__)); - pSentinel->uiMsgLen += uiMsgSize; - return NULL; // This should never happen - } - - /* - * This should *NEVER* fire. If it does it means we have got some - * dubious packet header back from the HTB stream. In this case - * the sensible thing is to abort processing and return to - * the caller - */ - uiHdrType = GET_PACKET_TYPE(ppHdr); - - PVR_ASSERT(uiHdrType < PVRSRVTL_PACKETTYPE_LAST && - uiHdrType > PVRSRVTL_PACKETTYPE_UNDEF); - - if (uiHdrType < PVRSRVTL_PACKETTYPE_LAST && - uiHdrType > PVRSRVTL_PACKETTYPE_UNDEF) - { - /* - * We have a (potentially) valid data header. We should see if - * the associated packet header matches one of our expected - * types. - */ - pNext = GET_NEXT_PACKET_ADDR(ppHdr); - - PVR_ASSERT(pNext != NULL); - - uiMsgSize = (IMG_UINT32)((size_t)pNext - (size_t)ppHdr); - - pSentinel->uiMsgLen += uiMsgSize; - - pData = GET_PACKET_DATA_PTR(ppHdr); - - /* - * Handle non-DATA packet types. These include PAD fields which - * may have data associated and other types. We simply discard - * these as they have no decodable information within them. - */ - if (uiHdrType != PVRSRVTL_PACKETTYPE_DATA) - { - /* - * Now release the current non-data packet and proceed to the - * next entry (if any). - */ - eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, uiMsgSize); - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Packet Type %x " - "Length %u", __func__, uiHdrType, uiMsgSize)); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - '%s' message" - " size %u", __func__, "TLClientReleaseDataLess", - PVRSRVGETERRORSTRING(eError), uiMsgSize)); - } - - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen); - - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - %s Giving up", - __func__, "TLClientAcquireData", - PVRSRVGETERRORSTRING(eError))); - - return NULL; - } - pSentinel->uiMsgLen = 0; - // Reset our limits - if we've returned an empty buffer we're done. - pLast = pSentinel->pBuf + pSentinel->uiBufLen; - pStart = pSentinel->pBuf; - pNext = pStart; - - if (pStart == NULL || pLast == NULL) - { - return NULL; - } - continue; - } - if (pData == NULL || pData >= pLast) - { - continue; - } - ui32Data = *(IMG_UINT32 *)pData; - ui32LogIdx = idToLogIdx(ui32Data); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "Unexpected Header @%p value %x", - ppHdr, uiHdrType)); - - return NULL; - } - - /* - * Check if the unrecognized ID is valid and therefore, tracebuf - * needs updating. - */ - if (HTB_SF_LAST == ui32LogIdx && HTB_LOG_VALIDID(ui32Data) - && IMG_FALSE == bUnrecognizedErrorPrinted) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Unrecognised LOG value '%x' GID %x Params %d ID %x @ '%p'", - __func__, ui32Data, HTB_SF_GID(ui32Data), - HTB_SF_PARAMNUM(ui32Data), ui32Data & 0xfff, pData)); - bUnrecognizedErrorPrinted = IMG_FALSE; - } - - } while (HTB_SF_LAST == ui32LogIdx); - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning data @ %p Log value '%x'", - __func__, pCurrent, ui32Data)); - - return pCurrent; -} - -/* - * HTB_GetFirstMessage - * - * Called from START to obtain the buffer address of the first message within - * pSentinel->pBuf. Will ACQUIRE data if the buffer is empty. - * - * Input: - * pSentinel - * pui64Pos Offset within the debugFS file - * - * Output: - * pSentinel->pCurr Set to reference the first valid non-NULL message within - * the buffer. If no valid message is found set to NULL. - * pSentinel - * ->pBuf if unset on entry - * ->uiBufLen if pBuf unset on entry - * - * Side-effects: - * HTB TL stream will be updated to bypass any zero-length PAD messages before - * the first non-NULL message (if any). - */ -static void HTB_GetFirstMessage(HTB_Sentinel_t *pSentinel, IMG_UINT64 *pui64Pos) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(pui64Pos); - - if (pSentinel == NULL) - return; - - if (pSentinel->pBuf == NULL) - { - /* Acquire data */ - pSentinel->uiMsgLen = 0; - - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen); - - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'", - __func__, "TLClientAcquireData", PVRSRVGETERRORSTRING(eError))); - - pSentinel->pBuf = NULL; - pSentinel->pCurr = NULL; - } - else - { - /* - * If there is no data available we set pSentinel->pCurr to NULL - * and return. This is expected behaviour if we've drained the - * data and nothing else has yet been produced. - */ - if (pSentinel->uiBufLen == 0 || pSentinel->pBuf == NULL) - { - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Empty Buffer @ %p", - __func__, pSentinel->pBuf)); - - pSentinel->pCurr = NULL; - return; - } - } - } - - /* Locate next message within buffer. NULL => no more data to process */ - pSentinel->pCurr = HTB_GetNextMessage(pSentinel); -} - -/* - * _DebugHBTraceDIStart: - * - * Returns the address to use for subsequent 'Show', 'Next', 'Stop' file ops. - * Return DI_START_TOKEN for the very first call and allocate a sentinel for - * use by the 'Show' routine and its helpers. - * This is stored in the psEntry's private hook field. - * - * We obtain access to the TLstream associated with the HTB. If this doesn't - * exist (because no pvrdebug capture trace has been set) we simply return with - * a NULL value which will stop the DI traversal. - */ -static void *_DebugHBTraceDIStart(OSDI_IMPL_ENTRY *psEntry, - IMG_UINT64 *pui64Pos) -{ - HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry); - PVRSRV_ERROR eError; - IMG_UINT32 uiTLMode; - void *retVal; - IMG_HANDLE hStream; - - /* The sentinel object should have been allocated during the creation - * of the DI entry. If it's not there it means that something went - * wrong. Return NULL in such case. */ - if (pSentinel == NULL) - { - return NULL; - } - - /* Check to see if the HTB stream has been configured yet. If not, there is - * nothing to display so we just return NULL to stop the stream access. - */ - if (!HTBIsConfigured()) - { - return NULL; - } - - /* Open the stream in non-blocking mode so that we can determine if there - * is no data to consume. Also disable the producer callback (if any) and - * the open callback so that we do not generate spurious trace data when - * accessing the stream. - */ - uiTLMode = PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING| - PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK| - PVRSRV_STREAM_FLAG_IGNORE_OPEN_CALLBACK; - - /* If two or more processes try to read from this file at the same time - * the TLClientOpenStream() function will handle this by allowing only - * one of them to actually open the stream. The other process will get - * an error stating that the stream is already open. The open function - * is threads safe. */ - eError = TLClientOpenStream(DIRECT_BRIDGE_HANDLE, HTB_STREAM_NAME, uiTLMode, - &hStream); - - if (eError == PVRSRV_ERROR_ALREADY_OPEN) - { - /* Stream allows only one reader so return error if it's already - * opened. */ - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Stream handle %p already " - "exists for %s", __func__, g_sHTBData.hStream, - HTB_STREAM_NAME)); - return NULL; - } - else if (eError != PVRSRV_OK) - { - /* - * No stream available so nothing to report - */ - return NULL; - } - - /* There is a window where hStream can be NULL but the stream is already - * opened. This shouldn't matter since the TLClientOpenStream() will make - * sure that only one stream can be opened and only one process can reach - * this place at a time. Also the .stop function will be always called - * after this function returns so there should be no risk of stream - * not being closed. */ - PVR_ASSERT(g_sHTBData.hStream == NULL); - g_sHTBData.hStream = hStream; - - /* We're starting the read operation so ensure we properly zero the - * sentinel object. */ - memset(pSentinel, 0, sizeof(*pSentinel)); - - /* - * Find the first message location within pSentinel->pBuf - * => for DI_START_TOKEN we must issue our first ACQUIRE, also for the - * subsequent re-START calls (if any). - */ - - HTB_GetFirstMessage(pSentinel, pui64Pos); - - retVal = *pui64Pos == 0 ? DI_START_TOKEN : pSentinel->pCurr; - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %p, Stream %s @ %p", - __func__, retVal, HTB_STREAM_NAME, g_sHTBData.hStream)); - - return retVal; -} - -/* - * _DebugTBTraceDIStop: - * - * Stop processing data collection and release any previously allocated private - * data structure if we have exhausted the previously filled data buffers. - */ -static void _DebugHBTraceDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry); - IMG_UINT32 uiMsgLen; - PVRSRV_ERROR eError; - - if (pSentinel == NULL) - { - return; - } - - uiMsgLen = pSentinel->uiMsgLen; - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: MsgLen = %d", __func__, uiMsgLen)); - - /* If we get here the handle should never be NULL because - * _DebugHBTraceDIStart() shouldn't allow that. */ - if (g_sHTBData.hStream == NULL) - { - return; - } - - if (uiMsgLen != 0) - { - eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, uiMsgLen); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - %s, nBytes %u", - __func__, "TLClientReleaseDataLess", - PVRSRVGETERRORSTRING(eError), uiMsgLen)); - } - } - - eError = TLClientCloseStream(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()", - "TLClientCloseStream", PVRSRVGETERRORSTRING(eError), - __func__)); - } - - g_sHTBData.hStream = NULL; -} - - -/* - * _DebugHBTraceDINext: - * - * This is where we release any acquired data which has been processed by the - * DIShow routine. If we have encountered a DI entry overflow we stop - * processing and return NULL. Otherwise we release the message that we - * previously processed and simply update our position pointer to the next - * valid HTB message (if any) - */ -static void *_DebugHBTraceDINext(OSDI_IMPL_ENTRY *psEntry, void *pvPriv, - IMG_UINT64 *pui64Pos) -{ - HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry); - IMG_UINT64 ui64CurPos; - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(pvPriv); - - if (pui64Pos) - { - ui64CurPos = *pui64Pos; - *pui64Pos = ui64CurPos + 1; - } - - /* Determine if we've had an overflow on the previous 'Show' call. If so - * we leave the previously acquired data in the queue (by releasing 0 bytes) - * and return NULL to end this DI entry iteration. - * If we have not overflowed we simply get the next HTB message and use that - * for our display purposes. */ - - if (DIHasOverflowed(psEntry)) - { - (void) TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream, - 0); - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: OVERFLOW - returning NULL", - __func__)); - - return NULL; - } - else - { - eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, - pSentinel->uiMsgLen); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s' @ %p Length %d", - __func__, "TLClientReleaseDataLess", - PVRSRVGETERRORSTRING(eError), pSentinel->pCurr, - pSentinel->uiMsgLen)); - PVR_DPF((PVR_DBG_WARNING, "%s: Buffer @ %p..%p", __func__, - pSentinel->pBuf, - (IMG_PBYTE) (pSentinel->pBuf + pSentinel->uiBufLen))); - - } - - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - g_sHTBData.hStream, &pSentinel->pBuf, - &pSentinel->uiBufLen); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'\nPrev message len %d", - __func__, "TLClientAcquireData", - PVRSRVGETERRORSTRING(eError), pSentinel->uiMsgLen)); - pSentinel->pBuf = NULL; - } - - pSentinel->uiMsgLen = 0; /* We don't (yet) know the message size */ - } - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %p Msglen %d", __func__, - pSentinel->pBuf, pSentinel->uiMsgLen)); - - if (pSentinel->pBuf == NULL || pSentinel->uiBufLen == 0) - { - return NULL; - } - - pSentinel->pCurr = HTB_GetNextMessage(pSentinel); - - return pSentinel->pCurr; -} - -/****************************************************************************** - * HTB Dumping routines and definitions - *****************************************************************************/ -#define IS_VALID_FMT_STRING(FMT) (strchr(FMT, '%') != NULL) -#define MAX_STRING_SIZE (128) - -typedef enum -{ - TRACEBUF_ARG_TYPE_INT, - TRACEBUF_ARG_TYPE_ERR, - TRACEBUF_ARG_TYPE_NONE -} TRACEBUF_ARG_TYPE; - -/* - * Array of all Host Trace log IDs used to convert the tracebuf data - */ -typedef struct _HTB_TRACEBUF_LOG_ { - HTB_LOG_SFids eSFId; - IMG_CHAR *pszName; - IMG_CHAR *pszFmt; - IMG_UINT32 ui32ArgNum; -} HTB_TRACEBUF_LOG; - -static const HTB_TRACEBUF_LOG aLogs[] = { -#define X(a, b, c, d, e) {HTB_LOG_CREATESFID(a,b,e), #c, d, e}, - HTB_LOG_SFIDLIST -#undef X -}; - -static const IMG_CHAR *aGroups[] = { -#define X(A,B) #B, - HTB_LOG_SFGROUPLIST -#undef X -}; -static const IMG_UINT32 uiMax_aGroups = ARRAY_SIZE(aGroups) - 1; - -static TRACEBUF_ARG_TYPE ExtractOneArgFmt(IMG_CHAR **, IMG_CHAR *); -/* - * ExtractOneArgFmt - * - * Scan the input 'printf-like' string *ppszFmt and return the next - * value string to be displayed. If there is no '%' format field in the - * string we return 'TRACEBUF_ARG_TYPE_NONE' and leave the input string - * untouched. - * - * Input - * ppszFmt reference to format string to be decoded - * pszOneArgFmt single field format from *ppszFmt - * - * Returns - * TRACEBUF_ARG_TYPE_ERR unrecognised argument - * TRACEBUF_ARG_TYPE_INT variable is of numeric type - * TRACEBUF_ARG_TYPE_NONE no variable reference in *ppszFmt - * - * Side-effect - * *ppszFmt is updated to reference the next part of the format string - * to be scanned - */ -static TRACEBUF_ARG_TYPE ExtractOneArgFmt( - IMG_CHAR **ppszFmt, - IMG_CHAR *pszOneArgFmt) -{ - IMG_CHAR *pszFmt; - IMG_CHAR *psT; - IMG_UINT32 ui32Count = MAX_STRING_SIZE; - IMG_UINT32 ui32OneArgSize; - TRACEBUF_ARG_TYPE eRet = TRACEBUF_ARG_TYPE_ERR; - - if (NULL == ppszFmt) - return TRACEBUF_ARG_TYPE_ERR; - - pszFmt = *ppszFmt; - if (NULL == pszFmt) - return TRACEBUF_ARG_TYPE_ERR; - - /* - * Find the first '%' - * NOTE: we can be passed a simple string to display which will have no - * parameters embedded within it. In this case we simply return - * TRACEBUF_ARG_TYPE_NONE and the string contents will be the full pszFmt - */ - psT = strchr(pszFmt, '%'); - if (psT == NULL) - { - return TRACEBUF_ARG_TYPE_NONE; - } - - /* Find next conversion identifier after the initial '%' */ - while ((*psT++) && (ui32Count-- > 0)) - { - switch (*psT) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - { - eRet = TRACEBUF_ARG_TYPE_INT; - goto _found_arg; - } - case 's': - { - eRet = TRACEBUF_ARG_TYPE_ERR; - goto _found_arg; - } - } - } - - if ((psT == NULL) || (ui32Count == 0)) return TRACEBUF_ARG_TYPE_ERR; - -_found_arg: - ui32OneArgSize = psT - pszFmt + 1; - OSCachedMemCopy(pszOneArgFmt, pszFmt, ui32OneArgSize); - pszOneArgFmt[ui32OneArgSize] = '\0'; - - *ppszFmt = psT + 1; - - return eRet; -} - -static IMG_UINT32 idToLogIdx(IMG_UINT32 ui32CheckData) -{ - IMG_UINT32 i = 0; - for (i = 0; aLogs[i].eSFId != HTB_SF_LAST; i++) - { - if ( ui32CheckData == aLogs[i].eSFId ) - return i; - } - /* Nothing found, return max value */ - return HTB_SF_LAST; -} - -/* - * DecodeHTB - * - * Decode the data buffer message located at pBuf. This should be a valid - * HTB message as we are provided with the start of the buffer. If empty there - * is no message to process. We update the uiMsgLen field with the size of the - * HTB message that we have processed so that it can be returned to the system - * on successful logging of the message to the output file. - * - * Input - * pSentinel reference to newly read data and pending completion data - * from a previous invocation [handle DI entry buffer overflow] - * -> pBuf reference to raw data that we are to parse - * -> uiBufLen total number of bytes of data available - * -> pCurr start of message to decode - * - * pvDumpDebugFile output file - * pfnDumpDebugPrintf output generating routine - * - * Output - * pSentinel - * -> uiMsgLen length of the decoded message which will be freed to - * the system on successful completion of the DI entry - * update via _DebugHBTraceDINext(), - * Return Value - * 0 successful decode - * -1 unsuccessful decode - */ -static int -DecodeHTB(HTB_Sentinel_t *pSentinel, OSDI_IMPL_ENTRY *pvDumpDebugFile, - DI_PRINTF pfnDumpDebugPrintf) -{ - IMG_UINT32 ui32Data, ui32LogIdx, ui32ArgsCur; - IMG_CHAR *pszFmt = NULL; - IMG_CHAR aszOneArgFmt[MAX_STRING_SIZE]; - IMG_BOOL bUnrecognizedErrorPrinted = IMG_FALSE; - - size_t nPrinted; - - void *pNext, *pLast, *pStart, *pData = NULL; - PVRSRVTL_PPACKETHDR ppHdr; /* Current packet header */ - IMG_UINT32 uiHdrType; /* Packet header type */ - IMG_UINT32 uiMsgSize; /* Message size of current packet (bytes) */ - IMG_BOOL bPacketsDropped; - - pLast = pSentinel->pBuf + pSentinel->uiBufLen; - pStart = pSentinel->pCurr; - - pSentinel->uiMsgLen = 0; // Reset count for this message - - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Buf @ %p..%p, Length = %d", - __func__, pStart, pLast, pSentinel->uiBufLen)); - - /* - * We should have a DATA header with the necessary information following - */ - ppHdr = GET_PACKET_HDR(pStart); - - if (ppHdr == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unexpected NULL packet in Host Trace buffer", __func__)); - return -1; - } - - uiHdrType = GET_PACKET_TYPE(ppHdr); - PVR_ASSERT(uiHdrType == PVRSRVTL_PACKETTYPE_DATA); - - pNext = GET_NEXT_PACKET_ADDR(ppHdr); - - PVR_ASSERT(pNext != NULL); - - uiMsgSize = (IMG_UINT32)((size_t)pNext - (size_t)ppHdr); - - pSentinel->uiMsgLen += uiMsgSize; - - pData = GET_PACKET_DATA_PTR(ppHdr); - - if (pData == NULL || pData >= pLast) - { - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: pData = %p, pLast = %p " - "Returning 0", __func__, pData, pLast)); - return 0; - } - - ui32Data = *(IMG_UINT32 *)pData; - ui32LogIdx = idToLogIdx(ui32Data); - - /* - * Check if the unrecognised ID is valid and therefore, tracebuf - * needs updating. - */ - if (ui32LogIdx == HTB_SF_LAST) - { - if (HTB_LOG_VALIDID(ui32Data)) - { - if (!bUnrecognizedErrorPrinted) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Unrecognised LOG value '%x' GID %x Params %d ID %x @ '%p'", - __func__, ui32Data, HTB_SF_GID(ui32Data), - HTB_SF_PARAMNUM(ui32Data), ui32Data & 0xfff, pData)); - bUnrecognizedErrorPrinted = IMG_TRUE; - } - - return 0; - } - - PVR_DPF((PVR_DBG_ERROR, - "%s: Unrecognised and invalid LOG value detected '%x'", - __func__, ui32Data)); - - return -1; - } - - /* The string format we are going to display */ - /* - * The display will show the header (log-ID, group-ID, number of params) - * The maximum parameter list length = 15 (only 4bits used to encode) - * so we need HEADER + 15 * sizeof(UINT32) and the displayed string - * describing the event. We use a buffer in the per-process pSentinel - * structure to hold the data. - */ - pszFmt = aLogs[ui32LogIdx].pszFmt; - - /* add the message payload size to the running count */ - ui32ArgsCur = HTB_SF_PARAMNUM(ui32Data); - - /* Determine if we've over-filled the buffer and had to drop packets */ - bPacketsDropped = CHECK_PACKETS_DROPPED(ppHdr); - if (bPacketsDropped || - (uiHdrType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED)) - { - /* Flag this as it is useful to know ... */ - - PVR_DUMPDEBUG_LOG("\n<========================== *** PACKETS DROPPED *** ======================>\n"); - } - - { - IMG_UINT32 ui32Timestampns, ui32PID, ui32TID; - IMG_UINT64 ui64Timestamp, ui64TimestampSec; - IMG_CHAR *szBuffer = pSentinel->szBuffer; // Buffer start - IMG_CHAR *pszBuffer = pSentinel->szBuffer; // Current place in buf - size_t uBufBytesAvailable = sizeof(pSentinel->szBuffer); - IMG_UINT32 *pui32Data = (IMG_UINT32 *)pData; - IMG_UINT32 ui_aGroupIdx; - - // Get PID field from data stream - pui32Data++; - ui32PID = *pui32Data; - // Get TID field from data stream - pui32Data++; - ui32TID = *pui32Data; - // Get Timestamp part 1 from data stream - pui32Data++; - ui64Timestamp = (IMG_UINT64) *pui32Data << 32; - // Get Timestamp part 2 from data stream - pui32Data++; - ui64Timestamp |= (IMG_UINT64) *pui32Data; - // Move to start of message contents data - pui32Data++; - - /* - * We need to snprintf the data to a local in-kernel buffer - * and then PVR_DUMPDEBUG_LOG() that in one shot - */ - ui_aGroupIdx = MIN(HTB_SF_GID(ui32Data), uiMax_aGroups); - - /* Divide by 1B to get seconds & mod using output var (nanosecond resolution)*/ - ui64TimestampSec = OSDivide64r64(ui64Timestamp, 1000000000, &ui32Timestampns); - - nPrinted = OSSNPrintf(szBuffer, uBufBytesAvailable, "%010"IMG_UINT64_FMTSPEC".%09u:%-5u-%-5u-%s> ", - ui64TimestampSec, ui32Timestampns, ui32PID, ui32TID, aGroups[ui_aGroupIdx]); - if (nPrinted >= uBufBytesAvailable) - { - PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed," - " max space "IMG_SIZE_FMTSPEC"\n", nPrinted, - uBufBytesAvailable); - - nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */ - } - - PVR_DUMPDEBUG_LOG("%s", pszBuffer); - /* Update where our next 'output' point in the buffer is */ - pszBuffer += nPrinted; - uBufBytesAvailable -= nPrinted; - - /* - * Print one argument at a time as this simplifies handling variable - * number of arguments. Special case handling for no arguments. - * This is the case for simple format strings such as - * HTB_SF_MAIN_KICK_UNCOUNTED. - */ - if (ui32ArgsCur == 0) - { - if (pszFmt) - { - nPrinted = OSStringLCopy(pszBuffer, pszFmt, uBufBytesAvailable); - if (nPrinted >= uBufBytesAvailable) - { - PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed," - " max space "IMG_SIZE_FMTSPEC"\n", nPrinted, - uBufBytesAvailable); - nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */ - } - PVR_DUMPDEBUG_LOG("%s", pszBuffer); - pszBuffer += nPrinted; - /* Don't update the uBufBytesAvailable as we have finished this - * message decode. pszBuffer - szBuffer is the total amount of - * data we have decoded. - */ - } - } - else - { - if (HTB_SF_GID(ui32Data) == HTB_GID_CTRL && HTB_SF_ID(ui32Data) == HTB_ID_MARK_SCALE) - { - IMG_UINT32 i; - IMG_UINT32 ui32ArgArray[HTB_MARK_SCALE_ARG_ARRAY_SIZE]; - IMG_UINT64 ui64OSTS = 0; - IMG_UINT32 ui32OSTSRem = 0; - IMG_UINT64 ui64CRTS = 0; - - /* Retrieve 6 args to an array */ - for (i = 0; i < ARRAY_SIZE(ui32ArgArray); i++) - { - ui32ArgArray[i] = *pui32Data; - pui32Data++; - --ui32ArgsCur; - } - - ui64OSTS = (IMG_UINT64) ui32ArgArray[HTB_ARG_OSTS_PT1] << 32 | ui32ArgArray[HTB_ARG_OSTS_PT2]; - ui64CRTS = (IMG_UINT64) ui32ArgArray[HTB_ARG_CRTS_PT1] << 32 | ui32ArgArray[HTB_ARG_CRTS_PT2]; - - /* Divide by 1B to get seconds, remainder in nano seconds*/ - ui64OSTS = OSDivide64r64(ui64OSTS, 1000000000, &ui32OSTSRem); - - nPrinted = OSSNPrintf(pszBuffer, - uBufBytesAvailable, - "HTBFWMkSync Mark=%u OSTS=%010" IMG_UINT64_FMTSPEC ".%09u CRTS=%" IMG_UINT64_FMTSPEC " CalcClkSpd=%u\n", - ui32ArgArray[HTB_ARG_SYNCMARK], - ui64OSTS, - ui32OSTSRem, - ui64CRTS, - ui32ArgArray[HTB_ARG_CLKSPD]); - - if (nPrinted >= uBufBytesAvailable) - { - PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed," - " max space "IMG_SIZE_FMTSPEC"\n", nPrinted, - uBufBytesAvailable); - nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */ - } - - PVR_DUMPDEBUG_LOG("%s", pszBuffer); - pszBuffer += nPrinted; - uBufBytesAvailable -= nPrinted; - } - else - { - while (IS_VALID_FMT_STRING(pszFmt) && (uBufBytesAvailable > 0)) - { - IMG_UINT32 ui32TmpArg = *pui32Data; - TRACEBUF_ARG_TYPE eArgType; - - eArgType = ExtractOneArgFmt(&pszFmt, aszOneArgFmt); - - pui32Data++; - ui32ArgsCur--; - - switch (eArgType) - { - case TRACEBUF_ARG_TYPE_INT: - nPrinted = OSSNPrintf(pszBuffer, uBufBytesAvailable, - aszOneArgFmt, ui32TmpArg); - break; - - case TRACEBUF_ARG_TYPE_NONE: - nPrinted = OSStringLCopy(pszBuffer, pszFmt, - uBufBytesAvailable); - break; - - default: - nPrinted = OSSNPrintf(pszBuffer, uBufBytesAvailable, - "Error processing arguments, type not " - "recognized (fmt: %s)", aszOneArgFmt); - break; - } - if (nPrinted >= uBufBytesAvailable) - { - PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed," - " max space "IMG_SIZE_FMTSPEC"\n", nPrinted, - uBufBytesAvailable); - nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */ - } - PVR_DUMPDEBUG_LOG("%s", pszBuffer); - pszBuffer += nPrinted; - uBufBytesAvailable -= nPrinted; - } - /* Display any remaining text in pszFmt string */ - if (pszFmt) - { - nPrinted = OSStringLCopy(pszBuffer, pszFmt, uBufBytesAvailable); - if (nPrinted >= uBufBytesAvailable) - { - PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed," - " max space "IMG_SIZE_FMTSPEC"\n", nPrinted, - uBufBytesAvailable); - nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */ - } - PVR_DUMPDEBUG_LOG("%s", pszBuffer); - pszBuffer += nPrinted; - /* Don't update the uBufBytesAvailable as we have finished this - * message decode. pszBuffer - szBuffer is the total amount of - * data we have decoded. - */ - } - } - } - - /* Update total bytes processed */ - pSentinel->uiTotal += (pszBuffer - szBuffer); - } - return 0; -} - -/* - * HTBDumpBuffer: Dump the Host Trace Buffer using the TLClient API - * - * This routine just parses *one* message from the buffer. - * The stream will be opened by the Start() routine, closed by the Stop() and - * updated for data consumed by this routine once we have DebugPrintf'd it. - * We use the new TLReleaseDataLess() routine which enables us to update the - * HTB contents with just the amount of data we have successfully processed. - * If we need to leave the data available we can call this with a 0 count. - * This will happen in the case of a buffer overflow so that we can reprocess - * any data which wasn't handled before. - * - * In case of overflow or an error we return -1 otherwise 0 - * - * Input: - * pfnPrintf output routine to display data - * psEntry handle to debug frontend - * pvData data address to start dumping from - * (set by Start() / Next()) - */ -static int HTBDumpBuffer(DI_PRINTF pfnPrintf, OSDI_IMPL_ENTRY *psEntry, - void *pvData) -{ - HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry); - - PVR_ASSERT(pvData != NULL); - - if (pvData == DI_START_TOKEN) - { - if (pSentinel->pCurr == NULL) - { - HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: DI_START_TOKEN, " - "Empty buffer", __func__)); - return 0; - } - PVR_ASSERT(pSentinel->pCurr != NULL); - - /* Display a Header as we have data to process */ - pfnPrintf(psEntry, "%-20s:%-5s-%-5s-%s %s\n", "Timestamp", "PID", "TID", "Group>", - "Log Entry"); - } - else - { - if (pvData != NULL) - { - PVR_ASSERT(pSentinel->pCurr == pvData); - } - } - - return DecodeHTB(pSentinel, psEntry, pfnPrintf); -} - - -/****************************************************************************** - * External Entry Point routines ... - *****************************************************************************/ -/*************************************************************************/ /*! - @Function HTB_CreateDIEntry - - @Description Create the debugFS entry-point for the host-trace-buffer - - @Returns eError internal error code, PVRSRV_OK on success - - */ /*************************************************************************/ -PVRSRV_ERROR HTB_CreateDIEntry(void) -{ - PVRSRV_ERROR eError; - - DI_ITERATOR_CB sIterator = { - .pfnStart = _DebugHBTraceDIStart, - .pfnStop = _DebugHBTraceDIStop, - .pfnNext = _DebugHBTraceDINext, - .pfnShow = _DebugHBTraceDIShow, - }; - - eError = DICreateEntry("host_trace", NULL, &sIterator, - &g_sHTBData.sSentinel, - DI_ENTRY_TYPE_GENERIC, - &g_sHTBData.psDumpHostDiEntry); - PVR_LOG_RETURN_IF_ERROR(eError, "DICreateEntry"); - - return PVRSRV_OK; -} - - -/*************************************************************************/ /*! - @Function HTB_DestroyDIEntry - - @Description Destroy the debugFS entry-point created by earlier - HTB_CreateDIEntry() call. -*/ /**************************************************************************/ -void HTB_DestroyDIEntry(void) -{ - if (g_sHTBData.psDumpHostDiEntry != NULL) - { - DIDestroyEntry(g_sHTBData.psDumpHostDiEntry); - g_sHTBData.psDumpHostDiEntry = NULL; - } -} - -/* EOF */ diff --git a/drivers/gpu/drm/img-rogue/1.17/htb_debug.h b/drivers/gpu/drm/img-rogue/1.17/htb_debug.h deleted file mode 100644 index 04132e13c3022..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htb_debug.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ /*! -@File htb_debug.h -@Title Linux debugFS routine setup header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HTB_DEBUG_H -#define HTB_DEBUG_H - -/**************************************************************************/ /*! - @Function HTB_CreateDIEntry - - @Description Create the debugFS entry-point for the host-trace-buffer - - @Returns eError internal error code, PVRSRV_OK on success - - */ /**************************************************************************/ -PVRSRV_ERROR HTB_CreateDIEntry(void); - -/**************************************************************************/ /*! - @Function HTB_DestroyFSEntry - - @Description Destroy the debugFS entry-point created by earlier - HTB_CreateDIEntry() call. -*/ /**************************************************************************/ -void HTB_DestroyDIEntry(void); - -#endif /* HTB_DEBUG_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbserver.c b/drivers/gpu/drm/img-rogue/1.17/htbserver.c deleted file mode 100644 index 43f92ebe58e9f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbserver.c +++ /dev/null @@ -1,870 +0,0 @@ -/*************************************************************************/ /*! -@File htbserver.c -@Title Host Trace Buffer server implementation. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Host Trace Buffer provides a mechanism to log Host events to a - buffer in a similar way to the Firmware Trace mechanism. - Host Trace Buffer logs data using a Transport Layer buffer. - The Transport Layer and pvrtld tool provides the mechanism to - retrieve the trace data. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "htbserver.h" -#include "htbuffer.h" -#include "htbuffer_types.h" -#include "tlstream.h" -#include "pvrsrv_tlcommon.h" -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "osfunc.h" -#include "allocmem.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "pvrsrv_apphint.h" -#include "oskm_apphint.h" - -/* size of circular buffer controlling the maximum number of concurrent PIDs logged */ -#define HTB_MAX_NUM_PID 8 - -/* number of times to try rewriting a log entry */ -#define HTB_LOG_RETRY_COUNT 5 - -/*************************************************************************/ /*! - Host Trace Buffer control information structure -*/ /**************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32BufferSize; /*!< Requested buffer size in bytes - Once set this may not be changed */ - - HTB_OPMODE_CTRL eOpMode; /*!< Control what trace data is dropped if - the buffer is full. - Once set this may not be changed */ - -/* IMG_UINT32 ui32GroupEnable; */ /*!< Flags word controlling groups to be - logged */ - - IMG_UINT32 ui32LogLevel; /*!< Log level to control messages logged */ - - IMG_UINT32 aui32EnablePID[HTB_MAX_NUM_PID]; /*!< PIDs to enable logging for - a specific set of processes */ - - IMG_UINT32 ui32PIDCount; /*!< Current number of PIDs being logged */ - - IMG_UINT32 ui32PIDHead; /*!< Head of the PID circular buffer */ - - HTB_LOGMODE_CTRL eLogMode; /*!< Logging mode control */ - - IMG_BOOL bLogDropSignalled; /*!< Flag indicating if a log message has - been signalled as dropped */ - - /* synchronisation parameters */ - IMG_UINT64 ui64SyncOSTS; - IMG_UINT64 ui64SyncCRTS; - IMG_UINT32 ui32SyncCalcClkSpd; - IMG_UINT32 ui32SyncMarker; - - IMG_BOOL bInitDone; /* Set by HTBInit, reset by HTBDeInit */ - - POS_SPINLOCK hRepeatMarkerLock; /*!< Spinlock used in HTBLogKM to protect global variables - (ByteCount, OSTS, CRTS ClkSpeed) - from becoming inconsistent due to calls from - both KM and UM */ - - IMG_UINT32 ui32ByteCount; /* Byte count used for triggering repeat sync point */ - /* static variables containing details of previous sync point */ - IMG_UINT64 ui64OSTS; - IMG_UINT64 ui64CRTS; - IMG_UINT32 ui32ClkSpeed; - -} HTB_CTRL_INFO; - - -/*************************************************************************/ /*! -*/ /**************************************************************************/ -static const IMG_UINT32 MapFlags[] = -{ - 0, /* HTB_OPMODE_UNDEF = 0 */ - TL_OPMODE_DROP_NEWER, /* HTB_OPMODE_DROPLATEST */ - TL_OPMODE_DROP_OLDEST,/* HTB_OPMODE_DROPOLDEST */ - TL_OPMODE_BLOCK /* HTB_OPMODE_BLOCK */ -}; - -static_assert(0 == HTB_OPMODE_UNDEF, "Unexpected value for HTB_OPMODE_UNDEF"); -static_assert(1 == HTB_OPMODE_DROPLATEST, "Unexpected value for HTB_OPMODE_DROPLATEST"); -static_assert(2 == HTB_OPMODE_DROPOLDEST, "Unexpected value for HTB_OPMODE_DROPOLDEST"); -static_assert(3 == HTB_OPMODE_BLOCK, "Unexpected value for HTB_OPMODE_BLOCK"); - -static_assert(1 == TL_OPMODE_DROP_NEWER, "Unexpected value for TL_OPMODE_DROP_NEWER"); -static_assert(2 == TL_OPMODE_DROP_OLDEST, "Unexpected value for TL_OPMODE_DROP_OLDEST"); -static_assert(3 == TL_OPMODE_BLOCK, "Unexpected value for TL_OPMODE_BLOCK"); - -static const IMG_UINT32 g_ui32TLBaseFlags; //TL_FLAG_NO_SIGNAL_ON_COMMIT - -/* Minimum TL buffer size. - * Large enough for around 60 worst case messages or 200 average messages - */ -#define HTB_TL_BUFFER_SIZE_MIN (0x10000) - -/* Minimum concentration of HTB packets in a TL Stream is 60% - * If we just put the HTB header in the TL stream (12 bytes), the TL overhead - * is 8 bytes for its own header, so for the smallest possible (and most - * inefficient) packet we have 3/5 of the buffer used for actual HTB data. - * This shift is used as a guaranteed estimation on when to produce a repeat - * packet. By shifting the size of the buffer by 1 we effectively /2 this - * under the 60% boundary chance we may have overwritten the marker and thus - * guaranteed to always have a marker in the stream */ -#define HTB_MARKER_PREDICTION_THRESHOLD(val) (val >> 1) - -static HTB_CTRL_INFO g_sCtrl; -static IMG_BOOL g_bConfigured = IMG_FALSE; -static IMG_HANDLE g_hTLStream; - -static IMG_HANDLE hHtbDbgReqNotify; - - -/************************************************************************/ /*! - @Function _LookupFlags - @Description Convert HTBuffer Operation mode to TLStream flags - - @Input eModeHTBuffer Operation Mode - - @Return IMG_UINT32 TLStream FLags -*/ /**************************************************************************/ -static IMG_UINT32 -_LookupFlags( HTB_OPMODE_CTRL eMode ) -{ - return (eMode < ARRAY_SIZE(MapFlags)) ? MapFlags[eMode] : 0; -} - - -/************************************************************************/ /*! - @Function _HTBLogDebugInfo - @Description Debug dump handler used to dump the state of the HTB module. - Called for each verbosity level during a debug dump. Function - only prints state when called for High verbosity. - - @Input hDebugRequestHandle See PFN_DBGREQ_NOTIFY - - @Input ui32VerbLevel See PFN_DBGREQ_NOTIFY - - @Input pfnDumpDebugPrintf See PFN_DBGREQ_NOTIFY - - @Input pvDumpDebugFile See PFN_DBGREQ_NOTIFY - -*/ /**************************************************************************/ -static void _HTBLogDebugInfo( - PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile -) -{ - PVR_UNREFERENCED_PARAMETER(hDebugRequestHandle); - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH)) - { - - if (g_bConfigured) - { - IMG_INT i; - - PVR_DUMPDEBUG_LOG("------[ HTB Log state: On ]------"); - - PVR_DUMPDEBUG_LOG("HTB Log mode: %d", g_sCtrl.eLogMode); - PVR_DUMPDEBUG_LOG("HTB Log level: %d", g_sCtrl.ui32LogLevel); - PVR_DUMPDEBUG_LOG("HTB Buffer Opmode: %d", g_sCtrl.eOpMode); - - for (i=0; i < HTB_FLAG_NUM_EL; i++) - { - PVR_DUMPDEBUG_LOG("HTB Log group %d: %x", i, g_auiHTBGroupEnable[i]); - } - } - else - { - PVR_DUMPDEBUG_LOG("------[ HTB Log state: Off ]------"); - } - } -} - -static IMG_UINT32 g_ui32HTBufferSize = HTB_TL_BUFFER_SIZE_MIN; - -/* - * AppHint access routine forward definitions - */ -static PVRSRV_ERROR _HTBSetLogGroup(const PVRSRV_DEVICE_NODE *, const void *, - IMG_UINT32); -static PVRSRV_ERROR _HTBReadLogGroup(const PVRSRV_DEVICE_NODE *, const void *, - IMG_UINT32 *); - -static PVRSRV_ERROR _HTBSetOpMode(const PVRSRV_DEVICE_NODE *, const void *, - IMG_UINT32); -static PVRSRV_ERROR _HTBReadOpMode(const PVRSRV_DEVICE_NODE *, const void *, - IMG_UINT32 *); - -static void _OnTLReaderOpenCallback(void *); - -/************************************************************************/ /*! - @Function HTBInit - @Description Allocate and initialise the Host Trace Buffer - The buffer size may be changed by specifying - HTBufferSizeInKB=xxxx - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBInit(void) -{ - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault; - IMG_UINT32 ui32BufBytes; - PVRSRV_ERROR eError; - - if (g_sCtrl.bInitDone) - { - PVR_DPF((PVR_DBG_ERROR, "HTBInit: Driver already initialised")); - return PVRSRV_ERROR_ALREADY_EXISTS; - } - - /* - * Buffer Size can be configured by specifying a value in the AppHint - * This will only take effect at module load time so there is no query - * or setting mechanism available. - */ - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HTBufferSizeInKB, - NULL, - NULL, - APPHINT_OF_DRIVER_NO_DEVICE, - NULL); - - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_EnableHTBLogGroup, - _HTBReadLogGroup, - _HTBSetLogGroup, - APPHINT_OF_DRIVER_NO_DEVICE, - NULL); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HTBOperationMode, - _HTBReadOpMode, - _HTBSetOpMode, - APPHINT_OF_DRIVER_NO_DEVICE, - NULL); - - /* - * Now get whatever values have been configured for our AppHints - */ - OSCreateKMAppHintState(&pvAppHintState); - ui32AppHintDefault = HTB_TL_BUFFER_SIZE_MIN / 1024; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, HTBufferSizeInKB, - &ui32AppHintDefault, &g_ui32HTBufferSize); - OSFreeKMAppHintState(pvAppHintState); - - ui32BufBytes = g_ui32HTBufferSize * 1024; - - /* initialise rest of state */ - g_sCtrl.ui32BufferSize = - (ui32BufBytes < HTB_TL_BUFFER_SIZE_MIN) - ? HTB_TL_BUFFER_SIZE_MIN - : ui32BufBytes; - g_sCtrl.eOpMode = HTB_OPMODE_DROPOLDEST; - g_sCtrl.ui32LogLevel = 0; - g_sCtrl.ui32PIDCount = 0; - g_sCtrl.ui32PIDHead = 0; - g_sCtrl.eLogMode = HTB_LOGMODE_ALLPID; - g_sCtrl.bLogDropSignalled = IMG_FALSE; - - eError = OSSpinLockCreate(&g_sCtrl.hRepeatMarkerLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSSpinLockCreate"); - - eError = PVRSRVRegisterDriverDbgRequestNotify(&hHtbDbgReqNotify, - _HTBLogDebugInfo, DEBUG_REQUEST_HTB, NULL); - PVR_LOG_IF_ERROR(eError, "PVRSRVRegisterDeviceDbgRequestNotify"); - - g_sCtrl.bInitDone = IMG_TRUE; - - /* Log the current driver parameter setting for the HTBufferSizeInKB. - * We do this here as there is no other infrastructure for obtaining - * the value. - */ - if (g_ui32HTBufferSize != ui32AppHintDefault) - { - PVR_LOG(("Increasing HTBufferSize to %uKB", g_ui32HTBufferSize)); - } - - - return PVRSRV_OK; -} - -/************************************************************************/ /*! - @Function HTBDeInit - @Description Close the Host Trace Buffer and free all resources. Must - perform a no-op if already de-initialised. - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBDeInit( void ) -{ - if (!g_sCtrl.bInitDone) - return PVRSRV_OK; - - if (hHtbDbgReqNotify) - { - /* Not much we can do if it fails, driver unloading */ - (void)PVRSRVUnregisterDriverDbgRequestNotify(hHtbDbgReqNotify); - hHtbDbgReqNotify = NULL; - } - - if (g_hTLStream) - { - TLStreamClose( g_hTLStream ); - g_hTLStream = NULL; - } - - if (g_sCtrl.hRepeatMarkerLock != NULL) - { - OSSpinLockDestroy(g_sCtrl.hRepeatMarkerLock); - g_sCtrl.hRepeatMarkerLock = NULL; - } - - g_sCtrl.bInitDone = IMG_FALSE; - return PVRSRV_OK; -} - - -/*************************************************************************/ /*! - AppHint interface functions -*/ /**************************************************************************/ -static -PVRSRV_ERROR _HTBSetLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psPrivate); - - return HTBControlKM(1, &ui32Value, 0, 0, - HTB_LOGMODE_UNDEF, HTB_OPMODE_UNDEF); -} - -static -PVRSRV_ERROR _HTBReadLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psPrivate); - - *pui32Value = g_auiHTBGroupEnable[0]; - return PVRSRV_OK; -} - -static -PVRSRV_ERROR _HTBSetOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psPrivate); - - return HTBControlKM(0, NULL, 0, 0, HTB_LOGMODE_UNDEF, ui32Value); -} - -static -PVRSRV_ERROR _HTBReadOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psPrivate); - - *pui32Value = (IMG_UINT32)g_sCtrl.eOpMode; - return PVRSRV_OK; -} - - -static void -_OnTLReaderOpenCallback( void *pvArg ) -{ - if ( g_hTLStream ) - { - IMG_UINT64 ui64Time; - OSClockMonotonicns64(&ui64Time); - (void) HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE, - g_sCtrl.ui32SyncMarker, - ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)), - ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)), - ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)), - ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)), - g_sCtrl.ui32SyncCalcClkSpd); - } - - PVR_UNREFERENCED_PARAMETER(pvArg); -} - - -/*************************************************************************/ /*! - @Function HTBControlKM - @Description Update the configuration of the Host Trace Buffer - - @Input ui32NumFlagGroups Number of group enable flags words - - @Input aui32GroupEnable Flags words controlling groups to be logged - - @Input ui32LogLevel Log level to record - - @Input ui32EnablePID PID to enable logging for a specific process - - @Input eLogMode Enable logging for all or specific processes, - - @Input eOpMode Control the behaviour of the data buffer - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBControlKM( - const IMG_UINT32 ui32NumFlagGroups, - const IMG_UINT32 * aui32GroupEnable, - const IMG_UINT32 ui32LogLevel, - const IMG_UINT32 ui32EnablePID, - const HTB_LOGMODE_CTRL eLogMode, - const HTB_OPMODE_CTRL eOpMode -) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32RetryCount = HTB_LOG_RETRY_COUNT; - IMG_UINT32 i; - IMG_UINT64 ui64Time; - OSClockMonotonicns64(&ui64Time); - - if ( !g_bConfigured && ui32NumFlagGroups ) - { - eError = TLStreamCreate( - &g_hTLStream, - HTB_STREAM_NAME, - g_sCtrl.ui32BufferSize, - _LookupFlags(HTB_OPMODE_DROPOLDEST) | g_ui32TLBaseFlags, - _OnTLReaderOpenCallback, NULL, NULL, NULL); - PVR_LOG_RETURN_IF_ERROR(eError, "TLStreamCreate"); - g_bConfigured = IMG_TRUE; - } - - if (HTB_OPMODE_UNDEF != eOpMode && g_sCtrl.eOpMode != eOpMode) - { - g_sCtrl.eOpMode = eOpMode; - eError = TLStreamReconfigure(g_hTLStream, _LookupFlags(g_sCtrl.eOpMode | g_ui32TLBaseFlags)); - while ( PVRSRV_ERROR_NOT_READY == eError && ui32RetryCount-- ) - { - OSReleaseThreadQuanta(); - eError = TLStreamReconfigure(g_hTLStream, _LookupFlags(g_sCtrl.eOpMode | g_ui32TLBaseFlags)); - } - PVR_LOG_RETURN_IF_ERROR(eError, "TLStreamReconfigure"); - } - - if ( ui32EnablePID ) - { - g_sCtrl.aui32EnablePID[g_sCtrl.ui32PIDHead] = ui32EnablePID; - g_sCtrl.ui32PIDHead++; - g_sCtrl.ui32PIDHead %= HTB_MAX_NUM_PID; - g_sCtrl.ui32PIDCount++; - if ( g_sCtrl.ui32PIDCount > HTB_MAX_NUM_PID ) - { - g_sCtrl.ui32PIDCount = HTB_MAX_NUM_PID; - } - } - - /* HTB_LOGMODE_ALLPID overrides ui32EnablePID */ - if ( HTB_LOGMODE_ALLPID == eLogMode ) - { - OSCachedMemSet(g_sCtrl.aui32EnablePID, 0, sizeof(g_sCtrl.aui32EnablePID)); - g_sCtrl.ui32PIDCount = 0; - g_sCtrl.ui32PIDHead = 0; - } - if ( HTB_LOGMODE_UNDEF != eLogMode ) - { - g_sCtrl.eLogMode = eLogMode; - } - - if ( ui32NumFlagGroups ) - { - for (i = 0; i < HTB_FLAG_NUM_EL && i < ui32NumFlagGroups; i++) - { - g_auiHTBGroupEnable[i] = aui32GroupEnable[i]; - } - for (; i < HTB_FLAG_NUM_EL; i++) - { - g_auiHTBGroupEnable[i] = 0; - } - } - - if ( ui32LogLevel ) - { - g_sCtrl.ui32LogLevel = ui32LogLevel; - } - - /* Dump the current configuration state */ - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_OPMODE, g_sCtrl.eOpMode); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_ENABLE_GROUP, g_auiHTBGroupEnable[0]); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_LOG_LEVEL, g_sCtrl.ui32LogLevel); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_LOGMODE, g_sCtrl.eLogMode); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - for (i = 0; i < g_sCtrl.ui32PIDCount; i++) - { - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_ENABLE_PID, g_sCtrl.aui32EnablePID[i]); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - } - /* Else should never be hit as we set the spd when the power state is updated */ - if (0 != g_sCtrl.ui32SyncMarker && 0 != g_sCtrl.ui32SyncCalcClkSpd) - { - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE, - g_sCtrl.ui32SyncMarker, - ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)), - ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)), - g_sCtrl.ui32SyncCalcClkSpd); - PVR_LOG_IF_ERROR(eError, "HTBLog"); - } - - return eError; -} - -#if defined(PVRSRV_ENABLE_HTB) -/*************************************************************************/ /*! -*/ /**************************************************************************/ -static IMG_BOOL -_ValidPID( IMG_UINT32 PID ) -{ - IMG_UINT32 i; - - for (i = 0; i < g_sCtrl.ui32PIDCount; i++) - { - if ( g_sCtrl.aui32EnablePID[i] == PID ) - { - return IMG_TRUE; - } - } - return IMG_FALSE; -} -#endif /* PVRSRV_ENABLE_HTB */ - - -/*************************************************************************/ /*! - @Function HTBSyncPartitionMarker - @Description Write an HTB sync partition marker to the HTB log - - @Input ui33Marker Marker value - -*/ /**************************************************************************/ -void -HTBSyncPartitionMarker( - const IMG_UINT32 ui32Marker -) -{ - g_sCtrl.ui32SyncMarker = ui32Marker; - if ( g_hTLStream ) - { - PVRSRV_ERROR eError; - IMG_UINT64 ui64Time; - OSClockMonotonicns64(&ui64Time); - - /* Else should never be hit as we set the spd when the power state is updated */ - if (0 != g_sCtrl.ui32SyncCalcClkSpd) - { - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE, - ui32Marker, - ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)), - ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)), - g_sCtrl.ui32SyncCalcClkSpd); - PVR_WARN_IF_ERROR(eError, "HTBLog"); - } - } -} - -/*************************************************************************/ /*! - @Function HTBSyncPartitionMarkerRepeat - @Description Write a HTB sync partition marker to the HTB log, given - the previous values to repeat. - - @Input ui33Marker Marker value - @Input ui64SyncOSTS previous OSTS - @Input ui64SyncCRTS previous CRTS - @Input ui32ClkSpeed previous Clock speed - -*/ /**************************************************************************/ -void -HTBSyncPartitionMarkerRepeat( - const IMG_UINT32 ui32Marker, - const IMG_UINT64 ui64SyncOSTS, - const IMG_UINT64 ui64SyncCRTS, - const IMG_UINT32 ui32ClkSpeed -) -{ - if ( g_hTLStream ) - { - PVRSRV_ERROR eError; - IMG_UINT64 ui64Time; - OSClockMonotonicns64(&ui64Time); - - /* Else should never be hit as we set the spd when the power state is updated */ - if (0 != ui32ClkSpeed) - { - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE, - ui32Marker, - ((IMG_UINT32)((ui64SyncOSTS>>32)&0xffffffffU)), ((IMG_UINT32)(ui64SyncOSTS&0xffffffffU)), - ((IMG_UINT32)((ui64SyncCRTS>>32)&0xffffffffU)), ((IMG_UINT32)(ui64SyncCRTS&0xffffffffU)), - ui32ClkSpeed); - PVR_WARN_IF_ERROR(eError, "HTBLog"); - } - } -} - -/*************************************************************************/ /*! - @Function HTBSyncScale - @Description Write FW-Host synchronisation data to the HTB log when clocks - change or are re-calibrated - - @Input bLogValues IMG_TRUE if value should be immediately written - out to the log - - @Input ui32OSTS OS Timestamp - - @Input ui32CRTS Rogue timestamp - - @Input ui32CalcClkSpd Calculated clock speed - -*/ /**************************************************************************/ -void -HTBSyncScale( - const IMG_BOOL bLogValues, - const IMG_UINT64 ui64OSTS, - const IMG_UINT64 ui64CRTS, - const IMG_UINT32 ui32CalcClkSpd -) -{ - g_sCtrl.ui64SyncOSTS = ui64OSTS; - g_sCtrl.ui64SyncCRTS = ui64CRTS; - g_sCtrl.ui32SyncCalcClkSpd = ui32CalcClkSpd; - if (g_hTLStream && bLogValues) - { - PVRSRV_ERROR eError; - IMG_UINT64 ui64Time; - OSClockMonotonicns64(&ui64Time); - eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE, - g_sCtrl.ui32SyncMarker, - ((IMG_UINT32)((ui64OSTS>>32)&0xffffffff)), ((IMG_UINT32)(ui64OSTS&0xffffffff)), - ((IMG_UINT32)((ui64CRTS>>32)&0xffffffff)), ((IMG_UINT32)(ui64CRTS&0xffffffff)), - ui32CalcClkSpd); - /* - * Don't spam the log with non-failure cases - */ - PVR_WARN_IF_ERROR(eError, "HTBLog"); - } -} - - -/*************************************************************************/ /*! - @Function HTBLogKM - @Description Record a Host Trace Buffer log event - - @Input PID The PID of the process the event is associated - with. This is provided as an argument rather - than querying internally so that events associated - with a particular process, but performed by - another can be logged correctly. - - @Input ui64TimeStamp The timestamp to be associated with this log event - - @Input SF The log event ID - - @Input ... Log parameters - - @Return PVRSRV_OK Success. - -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBLogKM( - IMG_UINT32 PID, - IMG_UINT32 TID, - IMG_UINT64 ui64TimeStamp, - HTB_LOG_SFids SF, - IMG_UINT32 ui32NumArgs, - IMG_UINT32 * aui32Args -) -{ -#if defined(PVRSRV_ENABLE_HTB) - OS_SPINLOCK_FLAGS uiSpinLockFlags; - IMG_UINT32 ui32ReturnFlags = 0; - - /* Local snapshot variables of global counters */ - IMG_UINT64 ui64OSTSSnap; - IMG_UINT64 ui64CRTSSnap; - IMG_UINT32 ui32ClkSpeedSnap; - - /* format of messages is: SF:PID:TID:TIMEPT1:TIMEPT2:[PARn]* - * Buffer is on the stack so we don't need a semaphore to guard it - */ - IMG_UINT32 aui32MessageBuffer[HTB_LOG_HEADER_SIZE+HTB_LOG_MAX_PARAMS]; - - /* Min HTB size is HTB_TL_BUFFER_SIZE_MIN : 10000 bytes and Max message/ - * packet size is 4*(HTB_LOG_HEADER_SIZE+HTB_LOG_MAX_PARAMS) = 80 bytes, - * hence with these constraints this design is unlikely to get - * PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED error - */ - PVRSRV_ERROR eError = PVRSRV_ERROR_NOT_ENABLED; - IMG_UINT32 ui32RetryCount = HTB_LOG_RETRY_COUNT; - IMG_UINT32 * pui32Message = aui32MessageBuffer; - IMG_UINT32 ui32MessageSize = 4 * (HTB_LOG_HEADER_SIZE+ui32NumArgs); - - PVR_LOG_GOTO_IF_INVALID_PARAM(aui32Args != NULL, eError, ReturnError); - PVR_LOG_GOTO_IF_INVALID_PARAM(ui32NumArgs == HTB_SF_PARAMNUM(SF), eError, ReturnError); - PVR_LOG_GOTO_IF_INVALID_PARAM(ui32NumArgs <= HTB_LOG_MAX_PARAMS, eError, ReturnError); - - if ( g_hTLStream - && ( 0 == PID || ~0 == PID || HTB_LOGMODE_ALLPID == g_sCtrl.eLogMode || _ValidPID(PID) ) -/* && ( g_sCtrl.ui32GroupEnable & (0x1 << HTB_SF_GID(SF)) ) */ -/* && ( g_sCtrl.ui32LogLevel >= HTB_SF_LVL(SF) ) */ - ) - { - *pui32Message++ = SF; - *pui32Message++ = PID; - *pui32Message++ = TID; - *pui32Message++ = ((IMG_UINT32)((ui64TimeStamp>>32)&0xffffffff)); - *pui32Message++ = ((IMG_UINT32)(ui64TimeStamp&0xffffffff)); - while ( ui32NumArgs ) - { - ui32NumArgs--; - pui32Message[ui32NumArgs] = aui32Args[ui32NumArgs]; - } - - eError = TLStreamWriteRetFlags( g_hTLStream, (IMG_UINT8*)aui32MessageBuffer, ui32MessageSize, &ui32ReturnFlags ); - while ( PVRSRV_ERROR_NOT_READY == eError && ui32RetryCount-- ) - { - OSReleaseThreadQuanta(); - eError = TLStreamWriteRetFlags( g_hTLStream, (IMG_UINT8*)aui32MessageBuffer, ui32MessageSize, &ui32ReturnFlags ); - } - - if ( PVRSRV_OK == eError ) - { - g_sCtrl.bLogDropSignalled = IMG_FALSE; - } - else if ( PVRSRV_ERROR_STREAM_FULL != eError || !g_sCtrl.bLogDropSignalled ) - { - PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()", "TLStreamWrite", PVRSRVGETERRORSTRING(eError), __func__)); - } - if ( PVRSRV_ERROR_STREAM_FULL == eError ) - { - g_sCtrl.bLogDropSignalled = IMG_TRUE; - } - - } - - if (SF == HTB_SF_CTRL_FWSYNC_MARK_SCALE) - { - OSSpinLockAcquire(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags); - - /* If a marker is being placed reset byte count from last marker */ - g_sCtrl.ui32ByteCount = 0; - g_sCtrl.ui64OSTS = (IMG_UINT64)aui32Args[HTB_ARG_OSTS_PT1] << 32 | aui32Args[HTB_ARG_OSTS_PT2]; - g_sCtrl.ui64CRTS = (IMG_UINT64)aui32Args[HTB_ARG_CRTS_PT1] << 32 | aui32Args[HTB_ARG_CRTS_PT2]; - g_sCtrl.ui32ClkSpeed = aui32Args[HTB_ARG_CLKSPD]; - - OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags); - } - else - { - OSSpinLockAcquire(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags); - /* Increase global count */ - g_sCtrl.ui32ByteCount += ui32MessageSize; - - /* Check if packet has overwritten last marker/rpt && - If the packet count is over half the size of the buffer */ - if (ui32ReturnFlags & TL_FLAG_OVERWRITE_DETECTED && - g_sCtrl.ui32ByteCount > HTB_MARKER_PREDICTION_THRESHOLD(g_sCtrl.ui32BufferSize)) - { - /* Take snapshot of global variables */ - ui64OSTSSnap = g_sCtrl.ui64OSTS; - ui64CRTSSnap = g_sCtrl.ui64CRTS; - ui32ClkSpeedSnap = g_sCtrl.ui32ClkSpeed; - /* Reset global variable counter */ - g_sCtrl.ui32ByteCount = 0; - OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags); - - /* Produce a repeat marker */ - HTBSyncPartitionMarkerRepeat(g_sCtrl.ui32SyncMarker, ui64OSTSSnap, ui64CRTSSnap, ui32ClkSpeedSnap); - } - else - { - OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags); - } - } - -ReturnError: - return eError; -#else - /* HTB support is disabled. Just return PVRSRV_OK and do nothing. */ - PVR_UNREFERENCED_PARAMETER(PID); - PVR_UNREFERENCED_PARAMETER(TID); - PVR_UNREFERENCED_PARAMETER(ui64TimeStamp); - PVR_UNREFERENCED_PARAMETER(SF); - PVR_UNREFERENCED_PARAMETER(aui32Args); - - return PVRSRV_OK; -#endif -} - -/*************************************************************************/ /*! - @Function HTBIsConfigured - @Description Determine if HTB stream has been configured - - @Input none - - @Return IMG_FALSE Stream has not been configured - IMG_TRUE Stream has been configured - -*/ /**************************************************************************/ -IMG_BOOL -HTBIsConfigured(void) -{ - return g_bConfigured; -} -/* EOF */ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbserver.h b/drivers/gpu/drm/img-rogue/1.17/htbserver.h deleted file mode 100644 index c30556c3501af..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbserver.h +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************/ /*! -@File htbserver.h -@Title Host Trace Buffer server implementation. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - -@Description Host Trace Buffer provides a mechanism to log Host events to a - buffer in a similar way to the Firmware Trace mechanism. - Host Trace Buffer logs data using a Transport Layer buffer. - The Transport Layer and pvrtld tool provides the mechanism to - retrieve the trace data. - - A Host Trace can be merged with a corresponding Firmware Trace. - This is achieved by inserting synchronisation data into both - traces and post processing to merge them. - - The FW Trace will contain a "Sync Partition Marker". This is - updated every time the RGX is brought out of reset (RGX clock - timestamps reset at this point) and is repeated when the FW - Trace buffer wraps to ensure there is always at least 1 - partition marker in the Firmware Trace buffer whenever it is - read. - - The Host Trace will contain corresponding "Sync Partition - Markers" - #HTBSyncPartitionMarker(). Each partition is then - subdivided into "Sync Scale" sections - #HTBSyncScale(). The - "Sync Scale" data allows the timestamps from the two traces to - be correlated. The "Sync Scale" data is updated as part of the - standard RGX time correlation code (rgxtimecorr.c) and is - updated periodically including on power and clock changes. - -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HTBSERVER_H -#define HTBSERVER_H - -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv.h" -#include "htbuffer.h" - -/************************************************************************/ /*! - @Function HTBInit - @Description Initialise the Host Trace Buffer and allocate all resources - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBInit(void); - -/************************************************************************/ /*! - @Function HTBDeInit - @Description Close the Host Trace Buffer and free all resources - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBDeInit(void); - -/*************************************************************************/ /*! - @Function HTBConfigureKM - @Description Configure or update the configuration of the Host Trace Buffer - - @Input ui32NameSize Size of the pszName string - - @Input pszName Name to use for the underlying data buffer - - @Input ui32BufferSize Size of the underlying data buffer - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBConfigureKM(IMG_UINT32 ui32NameSize, const IMG_CHAR * pszName, - const IMG_UINT32 ui32BufferSize); - - -/*************************************************************************/ /*! - @Function HTBControlKM - @Description Update the configuration of the Host Trace Buffer - - @Input ui32NumFlagGroups Number of group enable flags words - - @Input aui32GroupEnable Flags words controlling groups to be logged - - @Input ui32LogLevel Log level to record - - @Input ui32EnablePID PID to enable logging for a specific process - - @Input eLogMode Enable logging for all or specific processes, - - @Input eOpMode Control the behaviour of the data buffer - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBControlKM(const IMG_UINT32 ui32NumFlagGroups, - const IMG_UINT32 *aui32GroupEnable, - const IMG_UINT32 ui32LogLevel, - const IMG_UINT32 ui32EnablePID, - const HTB_LOGMODE_CTRL eLogMode, - const HTB_OPMODE_CTRL eOpMode); - - -/*************************************************************************/ /*! - @Function HTBSyncPartitionMarker - @Description Write an HTB sync partition marker to the HTB log - - @Input ui32Marker Marker value - -*/ /**************************************************************************/ -void -HTBSyncPartitionMarker(const IMG_UINT32 ui32Marker); - -/*************************************************************************/ /*! - @Function HTBSyncPartitionMarkerRpt - @Description Write a HTB sync partition marker to the HTB log, given - the previous values to repeat. - - @Input ui32Marker Marker value - @Input ui64SyncOSTS previous OSTS - @Input ui64SyncCRTS previous CRTS - @Input ui32ClkSpeed previous Clockspeed - -*/ /**************************************************************************/ -void -HTBSyncPartitionMarkerRepeat(const IMG_UINT32 ui32Marker, - const IMG_UINT64 ui64SyncOSTS, - const IMG_UINT64 ui64SyncCRTS, - const IMG_UINT32 ui32ClkSpeed); - -/*************************************************************************/ /*! - @Function HTBSyncScale - @Description Write FW-Host synchronisation data to the HTB log when clocks - change or are re-calibrated - - @Input bLogValues IMG_TRUE if value should be immediately written - out to the log - - @Input ui64OSTS OS Timestamp - - @Input ui64CRTS Rogue timestamp - - @Input ui32CalcClkSpd Calculated clock speed - -*/ /**************************************************************************/ -void -HTBSyncScale(const IMG_BOOL bLogValues, const IMG_UINT64 ui64OSTS, - const IMG_UINT64 ui64CRTS, const IMG_UINT32 ui32CalcClkSpd); - -/*************************************************************************/ /*! - @Function HTBLogKM - @Description Record a Host Trace Buffer log event - - @Input PID The PID of the process the event is associated - with. This is provided as an argument rather - than querying internally so that events associated - with a particular process, but performed by - another can be logged correctly. - - @Input TID The TID of the process the event is associated with. - - @Input ui64TimeStamp The timestamp to be associated with this log event - - @Input SF The log event ID - - @Input ... Log parameters - - @Return PVRSRV_OK Success. - -*/ /**************************************************************************/ -PVRSRV_ERROR -HTBLogKM(IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStamp, HTB_LOG_SFids SF, - IMG_UINT32 ui32NumArgs, IMG_UINT32 *aui32Args); - -/*************************************************************************/ /*! - @Function HTBIsConfigured - @Description Determine if HTB stream has been configured - - @Input none - - @Return IMG_FALSE Stream has not been configured - IMG_TRUE Stream has been configured - -*/ /**************************************************************************/ -IMG_BOOL -HTBIsConfigured(void); -#endif /* HTBSERVER_H */ - -/* EOF */ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbuffer.c b/drivers/gpu/drm/img-rogue/1.17/htbuffer.c deleted file mode 100644 index c326ae261b7e8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbuffer.c +++ /dev/null @@ -1,197 +0,0 @@ -/*************************************************************************/ /*! -@File htbuffer.c -@Title Host Trace Buffer shared API. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Host Trace Buffer provides a mechanism to log Host events to a - buffer in a similar way to the Firmware Trace mechanism. - Host Trace Buffer logs data using a Transport Layer buffer. - The Transport Layer and pvrtld tool provides the mechanism to - retrieve the trace data. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(__linux__) - #include - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ -#else - #include -#endif /* __linux__ */ - -#include "htbuffer.h" -#include "osfunc.h" -#include "client_htbuffer_bridge.h" - -/* The group flags array of ints large enough to store all the group flags - * NB: This will only work while all logging is in the kernel - */ -IMG_INTERNAL HTB_FLAG_EL_T g_auiHTBGroupEnable[HTB_FLAG_NUM_EL] = {0}; - - -/*************************************************************************/ /*! - @Function HTBControl - @Description Update the configuration of the Host Trace Buffer - @Input hSrvHandle Server Handle - @Input ui32NumFlagGroups Number of group enable flags words - @Input aui32GroupEnable Flags words controlling groups to be logged - @Input ui32LogLevel Log level to record - @Input ui32EnablePID PID to enable logging for a specific process - @Input eLogPidMode Enable logging for all or specific processes, - @Input eOpMode Control what trace data is dropped if the TL - buffer is full - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HTBControl( - IMG_HANDLE hSrvHandle, - IMG_UINT32 ui32NumFlagGroups, - IMG_UINT32 * aui32GroupEnable, - IMG_UINT32 ui32LogLevel, - IMG_UINT32 ui32EnablePID, - HTB_LOGMODE_CTRL eLogPidMode, - HTB_OPMODE_CTRL eOpMode -) -{ - return BridgeHTBControl( - hSrvHandle, - ui32NumFlagGroups, - aui32GroupEnable, - ui32LogLevel, - ui32EnablePID, - eLogPidMode, - eOpMode - ); -} - - -/*************************************************************************/ /*! -*/ /**************************************************************************/ -static PVRSRV_ERROR -_HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStampus, - HTB_LOG_SFids SF, va_list args) -{ -#if defined(__KERNEL__) - IMG_UINT32 i; - IMG_UINT32 ui32NumArgs = HTB_SF_PARAMNUM(SF); -#if defined(__KLOCWORK__) - IMG_UINT32 aui32Args[HTB_LOG_MAX_PARAMS + 1]; // Prevent KW False-positive -#else - IMG_UINT32 aui32Args[HTB_LOG_MAX_PARAMS]; -#endif - - PVR_ASSERT(ui32NumArgs <= HTB_LOG_MAX_PARAMS); - ui32NumArgs = (ui32NumArgs>HTB_LOG_MAX_PARAMS) ? - HTB_LOG_MAX_PARAMS : ui32NumArgs; - - /* unpack var args before sending over bridge */ - for (i=0; i>32)&0xffffffff)) -#define HTBLOG_PTR_BITS_LOW(p) ((IMG_UINT32)(((IMG_UINT64)((uintptr_t)p))&0xffffffff)) - -/* macros to cast 64-bit integers into 32-bit integer components for Host Trace */ -#define HTBLOG_U64_BITS_HIGH(u) ((IMG_UINT32)((u>>32)&0xffffffff)) -#define HTBLOG_U64_BITS_LOW(u) ((IMG_UINT32)(u&0xffffffff)) - -/*************************************************************************/ /*! - @Function HTBLog - @Description Record a Host Trace Buffer log event - - @Input PID The PID of the process the event is associated - with. This is provided as an argument rather - than querying internally so that events associated - with a particular process, but performed by - another can be logged correctly. - - @Input TID The TID (Thread ID) of the thread the event is - associated with. - - @Input TimeStampus The timestamp in us for this event - - @Input SF The log event ID - - @Input ... Log parameters - - @Return PVRSRV_OK Success. - -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStampns, IMG_UINT32 SF, ...); - - -/*************************************************************************/ /*! - @Function HTBLogSimple - @Description Record a Host Trace Buffer log event with implicit PID and Timestamp - - @Input SF The log event ID - - @Input ... Log parameters - - @Return PVRSRV_OK Success. - -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HTBLogSimple(IMG_HANDLE hSrvHandle, IMG_UINT32 SF, ...); - - - -/* DEBUG log group enable */ -#if !defined(HTB_DEBUG_LOG_GROUP) -#undef HTB_LOG_TYPE_DBG /* No trace statements in this log group should be checked in */ -#define HTB_LOG_TYPE_DBG __BUILDERROR__ -#endif - - -#if defined(__cplusplus) -} -#endif - -#endif /* HTBUFFER_H */ -/***************************************************************************** - End of file (htbuffer.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbuffer_init.h b/drivers/gpu/drm/img-rogue/1.17/htbuffer_init.h deleted file mode 100644 index d114579964b4c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbuffer_init.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************/ /*! -@File htbuffer_init.h -@Title Host Trace Buffer functions needed for Services initialisation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HTBUFFER_INIT_H -#define HTBUFFER_INIT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_types.h" -#include "img_defs.h" - -/*************************************************************************/ /*! - @Function HTBConfigure - @Description Configure the Host Trace Buffer. - Once these parameters are set they may not be changed - - @Input hSrvHandle Server Handle - - @Input pszBufferName Name to use for the TL buffer, this will be - required to request trace data from the TL - - @Input ui32BufferSize Requested TL buffer size in bytes - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HTBConfigure( - IMG_HANDLE hSrvHandle, - IMG_CHAR * pszBufferName, - IMG_UINT32 ui32BufferSize -); - -/*************************************************************************/ /*! - @Function HTBControl - @Description Update the configuration of the Host Trace Buffer - - @Input hSrvHandle Server Handle - - @Input ui32NumFlagGroups Number of group enable flags words - - @Input aui32GroupEnable Flags words controlling groups to be logged - - @Input ui32LogLevel Log level to record - - @Input ui32EnablePID PID to enable logging for a specific process - - @Input eLogMode Enable logging for all or specific processes, - - @Input eOpMode Control what trace data is dropped if the TL - buffer is full - - @Return eError Internal services call returned eError error - number -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -HTBControl( - IMG_HANDLE hSrvHandle, - IMG_UINT32 ui32NumFlagGroups, - IMG_UINT32 * aui32GroupEnable, - IMG_UINT32 ui32LogLevel, - IMG_UINT32 ui32EnablePID, - HTB_LOGMODE_CTRL eLogMode, - HTB_OPMODE_CTRL eOpMode -); - -#if defined(__cplusplus) -} -#endif - -#endif /* HTBUFFER_INIT_H */ -/***************************************************************************** - End of file (htbuffer_init.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbuffer_sf.h b/drivers/gpu/drm/img-rogue/1.17/htbuffer_sf.h deleted file mode 100644 index 9042de20cd8f9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbuffer_sf.h +++ /dev/null @@ -1,241 +0,0 @@ -/*************************************************************************/ /*! -@File htbuffer_sf.h -@Title Host Trace Buffer interface string format specifiers -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the Host Trace Buffer logging messages. The following - list are the messages the host driver prints. Changing anything - but the first column or spelling mistakes in the strings will - break compatibility with log files created with older/newer - driver versions. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HTBUFFER_SF_H -#define HTBUFFER_SF_H - -#if defined(__cplusplus) -extern "C" { -#endif - - -/****************************************************************************** - * *DO*NOT* rearrange or delete lines in SFIDLIST or SFGROUPLIST or you - * WILL BREAK host tracing message compatibility with previous - * driver versions. Only add new ones, if so required. - *****************************************************************************/ - - -/* String used in pvrdebug -h output */ -#define HTB_LOG_GROUPS_STRING_LIST "ctrl,mmu,sync,main,brg" - -/* Used in print statements to display log group state, one %s per group defined */ -#define HTB_LOG_ENABLED_GROUPS_LIST_PFSPEC "%s%s%s%s%s" - -/* Available log groups - Master template - * - * Group usage is as follows: - * CTRL - Internal Host Trace information and synchronisation data - * MMU - MMU page mapping information - * SYNC - Synchronisation debug - * MAIN - Data master kicks, etc. tying in with the MAIN group in FWTrace - * DBG - Temporary debugging group, logs not to be left in the driver - * - */ -#define HTB_LOG_SFGROUPLIST \ - X( HTB_GROUP_NONE, NONE ) \ -/* gid, group flag / apphint name */ \ - X( HTB_GROUP_CTRL, CTRL ) \ - X( HTB_GROUP_MMU, MMU ) \ - X( HTB_GROUP_SYNC, SYNC ) \ - X( HTB_GROUP_MAIN, MAIN ) \ - X( HTB_GROUP_BRG, BRG ) \ -/* Debug group HTB_GROUP_DBG must always be last */ \ - X( HTB_GROUP_DBG, DBG ) - - -/* Table of String Format specifiers, the group they belong and the number of - * arguments each expects. Xmacro styled macros are used to generate what is - * needed without requiring hand editing. - * - * id : unique id within a group - * gid : group id as defined above - * sym name : symbolic name of enumerations used to identify message strings - * string : Actual string - * #args : number of arguments the string format requires - */ -#define HTB_LOG_SFIDLIST \ -/*id, gid, sym name, string, # arguments */ \ -X( 0, HTB_GROUP_NONE, HTB_SF_FIRST, "You should not use this string", 0) \ -\ -X( 1, HTB_GROUP_CTRL, HTB_SF_CTRL_LOGMODE, "HTB log mode set to %d (1- all PID, 2 - restricted PID)\n", 1) \ -X( 2, HTB_GROUP_CTRL, HTB_SF_CTRL_ENABLE_PID, "HTB enable logging for PID %d\n", 1) \ -X( 3, HTB_GROUP_CTRL, HTB_SF_CTRL_ENABLE_GROUP, "HTB enable logging groups 0x%08x\n", 1) \ -X( 4, HTB_GROUP_CTRL, HTB_SF_CTRL_LOG_LEVEL, "HTB log level set to %d\n", 1) \ -X( 5, HTB_GROUP_CTRL, HTB_SF_CTRL_OPMODE, "HTB operating mode set to %d (1 - droplatest, 2 - drop oldest, 3 - block)\n", 1) \ -X( 6, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_SCALE, "HTBFWSync OSTS=%08x%08x CRTS=%08x%08x CalcClkSpd=%d\n", 5) \ -X( 7, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_SCALE_RPT, "FW Sync scale info OSTS=%08x%08x CRTS=%08x%08x CalcClkSpd=%d\n", 5) \ -X( 8, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK, "FW Sync Partition marker: %d\n", 1) \ -X( 9, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK_RPT, "FW Sync Partition repeat: %d\n", 1) \ -X( 10, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK_SCALE, "Text not used", 6)\ -\ -X( 1, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_TABLE, "MMU page op table entry page_id=%08x%08x index=%d level=%d val=%08x%08x map=%d\n", 7) \ -X( 2, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_ALLOC, "MMU allocating DevVAddr from %08x%08x to %08x%08x\n", 4) \ -X( 3, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_FREE, "MMU freeing DevVAddr from %08x%08x to %08x%08x\n", 4) \ -X( 4, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_MAP, "MMU mapping DevVAddr %08x%08x to DevPAddr %08x%08x\n", 4) \ -X( 5, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_PMRMAP, "MMU mapping PMR DevVAddr %08x%08x to DevPAddr %08x%08x\n", 4) \ -X( 6, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_UNMAP, "MMU unmapping DevVAddr %08x%08x\n", 2) \ -\ -X( 1, HTB_GROUP_SYNC, HTB_SF_SYNC_SERVER_ALLOC, "Server sync allocation [%08X]\n", 1) \ -X( 2, HTB_GROUP_SYNC, HTB_SF_SYNC_SERVER_UNREF, "Server sync unreferenced [%08X]\n", 1) \ -X( 3, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_CREATE, "Sync OP create 0x%08x, block count=%d, server syncs=%d, client syncs=%d\n", 4) \ -X( 4, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_TAKE, "Sync OP take 0x%08x server syncs=%d, client syncs=%d\n", 3) \ -X( 5, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_COMPLETE, "Sync OP complete 0x%08x\n", 1) \ -X( 6, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_DESTROY, "Sync OP destroy 0x%08x\n", 1) \ -\ -X( 1, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_TA_DEPRECATED, "Kick TA: FWCtx %08X @ %d\n", 2) \ -X( 2, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_3D_DEPRECATED, "Kick 3D: FWCtx %08X @ %d\n", 2) \ -X( 3, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_CDM_DEPRECATED,"Kick CDM: FWCtx %08X @ %d\n", 2) \ -X( 4, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_RTU, "Kick RTU: FWCtx %08X @ %d\n", 2) \ -X( 5, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_SHG, "Kick SHG: FWCtx %08X @ %d\n", 2) \ -X( 6, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_2D_DEPRECATED, "Kick 2D: FWCtx %08X @ %d\n", 2) \ -X( 7, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_UNCOUNTED, "Kick (uncounted) for all DMs\n", 0) \ -X( 8, HTB_GROUP_MAIN, HTB_SF_MAIN_FWCCB_CMD, "FW CCB Cmd: %d\n", 1) \ -X( 9, HTB_GROUP_MAIN, HTB_SF_MAIN_PRE_POWER, "Pre-power duration @ phase [%d] (0-shutdown,1-startup) RGX: %llu ns SYS: %llu ns\n", 3) \ -X(10, HTB_GROUP_MAIN, HTB_SF_MAIN_POST_POWER, "Post-power duration @ phase [%d] (0-shutdown,1-startup) SYS: %llu ns RGX: %llu ns\n", 3) \ -X(11, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_TA, "Kick TA: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \ -X(12, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_3D, "Kick 3D: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \ -X(13, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_CDM, "Kick CDM: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \ -X(14, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_2D, "Kick 2D: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \ -\ -X( 1, HTB_GROUP_BRG, HTB_SF_BRG_BRIDGE_CALL, "Bridge call: start: %010u: bid %03d fid %d\n", 3) \ -X( 2, HTB_GROUP_BRG, HTB_SF_BRG_BRIDGE_CALL_ERR, "Bridge call: start: %010u: bid %03d fid %d error %d\n", 4) \ -\ -X( 1, HTB_GROUP_DBG, HTB_SF_DBG_INTPAIR, "0x%8.8x 0x%8.8x\n", 2) \ -\ -X( 65535, HTB_GROUP_NONE, HTB_SF_LAST, "You should not use this string\n", 15) - - - -/* gid - Group numbers */ -typedef enum _HTB_LOG_SFGROUPS { -#define X(A,B) A, - HTB_LOG_SFGROUPLIST -#undef X -} HTB_LOG_SFGROUPS; - - -/* Group flags are stored in an array of elements. - * Each of which have a certain number of bits. - */ -#define HTB_FLAG_EL_T IMG_UINT32 -#define HTB_FLAG_NUM_BITS_IN_EL (sizeof(HTB_FLAG_EL_T) * 8) - -#define HTB_LOG_GROUP_FLAG_GROUP(gid) ((gid-1) / HTB_FLAG_NUM_BITS_IN_EL) -#define HTB_LOG_GROUP_FLAG(gid) (gid ? (0x1 << ((gid-1)%HTB_FLAG_NUM_BITS_IN_EL)) : 0) -#define HTB_LOG_GROUP_FLAG_NAME(gid) HTB_LOG_TYPE_ ## gid - -/* Group enable flags */ -typedef enum _HTB_LOG_TYPE { -#define X(a, b) HTB_LOG_GROUP_FLAG_NAME(b) = HTB_LOG_GROUP_FLAG(a), - HTB_LOG_SFGROUPLIST -#undef X -} HTB_LOG_TYPE; - - - -/* The symbolic names found in the table above are assigned an ui32 value of - * the following format: - * 31 30 28 27 20 19 16 15 12 11 0 bits - * - --- ---- ---- ---- ---- ---- ---- ---- - * 0-11: id number - * 12-15: group id number - * 16-19: number of parameters - * 20-27: unused - * 28-30: active: identify SF packet, otherwise regular int32 - * 31: reserved for signed/unsigned compatibility - * - * The following macro assigns those values to the enum generated SF ids list. - */ -#define HTB_LOG_IDMARKER (0x70000000) -#define HTB_LOG_CREATESFID(a,b,e) (((a) | (b << 12) | (e << 16)) | HTB_LOG_IDMARKER) - -#define HTB_LOG_IDMASK (0xFFF00000) -#define HTB_LOG_VALIDID(I) ( ((I) & HTB_LOG_IDMASK) == HTB_LOG_IDMARKER ) - -typedef enum HTB_LOG_SFids { -#define X(a, b, c, d, e) c = HTB_LOG_CREATESFID(a,b,e), - HTB_LOG_SFIDLIST -#undef X -} HTB_LOG_SFids; - -/* Return the group id that the given (enum generated) id belongs to */ -#define HTB_SF_GID(x) (((x)>>12) & 0xf) -/* Future improvement to support log levels */ -#define HTB_SF_LVL(x) (0) -/* Returns how many arguments the SF(string format) for the given - * (enum generated) id requires. - */ -#define HTB_SF_PARAMNUM(x) (((x)>>16) & 0xf) -/* Returns the id of given enum */ -#define HTB_SF_ID(x) (x & 0xfff) - -/* Format of messages is: SF:PID:TID:TIMEPT1:TIMEPT2:[PARn]* - */ -#define HTB_LOG_HEADER_SIZE 5 -#define HTB_LOG_MAX_PARAMS 15 - -#if defined(__cplusplus) -} -#endif - -/* Defines for handling MARK_SCALE special case */ -#define HTB_GID_CTRL 1 -#define HTB_ID_MARK_SCALE 10 -#define HTB_MARK_SCALE_ARG_ARRAY_SIZE 6 - -/* Defines for extracting args from array for special case MARK_SCALE */ -#define HTB_ARG_SYNCMARK 0 -#define HTB_ARG_OSTS_PT1 1 -#define HTB_ARG_OSTS_PT2 2 -#define HTB_ARG_CRTS_PT1 3 -#define HTB_ARG_CRTS_PT2 4 -#define HTB_ARG_CLKSPD 5 - -#endif /* HTBUFFER_SF_H */ -/***************************************************************************** - End of file (htbuffer_sf.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/htbuffer_types.h b/drivers/gpu/drm/img-rogue/1.17/htbuffer_types.h deleted file mode 100644 index a404bf8b7b100..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/htbuffer_types.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************/ /*! -@File htbuffer_types.h -@Title Host Trace Buffer types. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Host Trace Buffer provides a mechanism to log Host events to a - buffer in a similar way to the Firmware Trace mechanism. - Host Trace Buffer logs data using a Transport Layer buffer. - The Transport Layer and pvrtld tool provides the mechanism to - retrieve the trace data. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 HTBUFFER_TYPES_H -#define HTBUFFER_TYPES_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" -#include "htbuffer_sf.h" - -/* The group flags array of ints large enough to store all the group flags */ -#define HTB_FLAG_NUM_EL (((HTB_GROUP_DBG-1) / HTB_FLAG_NUM_BITS_IN_EL) + 1) -extern IMG_INTERNAL HTB_FLAG_EL_T g_auiHTBGroupEnable[HTB_FLAG_NUM_EL]; - -#define HTB_GROUP_ENABLED(SF) (g_auiHTBGroupEnable[HTB_LOG_GROUP_FLAG_GROUP(HTB_SF_GID(SF))] & HTB_LOG_GROUP_FLAG(HTB_SF_GID(SF))) - -/*************************************************************************/ /*! - Host Trace Buffer operation mode - Care must be taken if changing this enum to ensure the MapFlags[] array - in htbserver.c is kept in-step. -*/ /**************************************************************************/ -typedef enum -{ - /*! Undefined operation mode */ - HTB_OPMODE_UNDEF = 0, - - /*! Drop latest, intended for continuous logging to a UM daemon. - * If the daemon does not keep up, the most recent log data - * will be dropped - */ - HTB_OPMODE_DROPLATEST, - - /*! Drop oldest, intended for crash logging. - * Data will be continuously written to a circular buffer. - * After a crash the buffer will contain events leading up to the crash - */ - HTB_OPMODE_DROPOLDEST, - - /*! Block write if buffer is full */ - HTB_OPMODE_BLOCK, - - HTB_OPMODE_LAST = HTB_OPMODE_BLOCK -} HTB_OPMODE_CTRL; - - -/*************************************************************************/ /*! - Host Trace Buffer log mode control -*/ /**************************************************************************/ -typedef enum -{ - /*! Undefined log mode, used if update is not applied */ - HTB_LOGMODE_UNDEF = 0, - - /*! Log trace messages for all PIDs. */ - HTB_LOGMODE_ALLPID, - - /*! Log trace messages for specific PIDs only. */ - HTB_LOGMODE_RESTRICTEDPID, - - HTB_LOGMODE_LAST = HTB_LOGMODE_RESTRICTEDPID -} HTB_LOGMODE_CTRL; - - -#if defined(__cplusplus) -} -#endif - -#endif /* HTBUFFER_TYPES_H */ - -/****************************************************************************** - End of file (htbuffer_types.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/img_3dtypes.h b/drivers/gpu/drm/img-rogue/1.17/img_3dtypes.h deleted file mode 100644 index 657c18c8712d9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/img_3dtypes.h +++ /dev/null @@ -1,248 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Global 3D types for use by IMG APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines 3D types for use by IMG APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 IMG_3DTYPES_H -#define IMG_3DTYPES_H - -#include -#include "img_types.h" -#include "img_defs.h" - -/* - * Comparison functions - * This comparison function is defined as: - * A {CmpFunc} B - * A is a reference value, e.g., incoming depth etc. - * B is the sample value, e.g., value in depth buffer. - */ -typedef enum _IMG_COMPFUNC_ -{ - IMG_COMPFUNC_NEVER, /**< The comparison never succeeds */ - IMG_COMPFUNC_LESS, /**< The comparison is a less-than operation */ - IMG_COMPFUNC_EQUAL, /**< The comparison is an equal-to operation */ - IMG_COMPFUNC_LESS_EQUAL, /**< The comparison is a less-than or equal-to - operation */ - IMG_COMPFUNC_GREATER, /**< The comparison is a greater-than operation - */ - IMG_COMPFUNC_NOT_EQUAL, /**< The comparison is a no-equal-to operation - */ - IMG_COMPFUNC_GREATER_EQUAL, /**< The comparison is a greater-than or - equal-to operation */ - IMG_COMPFUNC_ALWAYS, /**< The comparison always succeeds */ -} IMG_COMPFUNC; - -/* - * Stencil op functions - */ -typedef enum _IMG_STENCILOP_ -{ - IMG_STENCILOP_KEEP, /**< Keep original value */ - IMG_STENCILOP_ZERO, /**< Set stencil to 0 */ - IMG_STENCILOP_REPLACE, /**< Replace stencil entry */ - IMG_STENCILOP_INCR_SAT, /**< Increment stencil entry, clamping to max */ - IMG_STENCILOP_DECR_SAT, /**< Decrement stencil entry, clamping to zero */ - IMG_STENCILOP_INVERT, /**< Invert bits in stencil entry */ - IMG_STENCILOP_INCR, /**< Increment stencil entry, - wrapping if necessary */ - IMG_STENCILOP_DECR, /**< Decrement stencil entry, - wrapping if necessary */ -} IMG_STENCILOP; - -/* - * Alpha blending allows colours and textures on one surface - * to be blended with transparency onto another surface. - * These definitions apply to both source and destination blending - * states - */ -typedef enum _IMG_BLEND_ -{ - IMG_BLEND_ZERO = 0, /**< Blend factor is (0,0,0,0) */ - IMG_BLEND_ONE, /**< Blend factor is (1,1,1,1) */ - IMG_BLEND_SRC_COLOUR, /**< Blend factor is the source colour */ - IMG_BLEND_INV_SRC_COLOUR, /**< Blend factor is the inverted source colour - (i.e. 1-src_col) */ - IMG_BLEND_SRC_ALPHA, /**< Blend factor is the source alpha */ - IMG_BLEND_INV_SRC_ALPHA, /**< Blend factor is the inverted source alpha - (i.e. 1-src_alpha) */ - IMG_BLEND_DEST_ALPHA, /**< Blend factor is the destination alpha */ - IMG_BLEND_INV_DEST_ALPHA, /**< Blend factor is the inverted destination - alpha */ - IMG_BLEND_DEST_COLOUR, /**< Blend factor is the destination colour */ - IMG_BLEND_INV_DEST_COLOUR, /**< Blend factor is the inverted destination - colour */ - IMG_BLEND_SRC_ALPHASAT, /**< Blend factor is the alpha saturation (the - minimum of (Src alpha, - 1 - destination alpha)) */ - IMG_BLEND_BLEND_FACTOR, /**< Blend factor is a constant */ - IMG_BLEND_INVBLEND_FACTOR, /**< Blend factor is a constant (inverted)*/ - IMG_BLEND_SRC1_COLOUR, /**< Blend factor is the colour outputted from - the pixel shader */ - IMG_BLEND_INV_SRC1_COLOUR, /**< Blend factor is the inverted colour - outputted from the pixel shader */ - IMG_BLEND_SRC1_ALPHA, /**< Blend factor is the alpha outputted from - the pixel shader */ - IMG_BLEND_INV_SRC1_ALPHA /**< Blend factor is the inverted alpha - outputted from the pixel shader */ -} IMG_BLEND; - -/* - * The arithmetic operation to perform when blending - */ -typedef enum _IMG_BLENDOP_ -{ - IMG_BLENDOP_ADD = 0, /**< Result = (Source + Destination) */ - IMG_BLENDOP_SUBTRACT, /**< Result = (Source - Destination) */ - IMG_BLENDOP_REV_SUBTRACT, /**< Result = (Destination - Source) */ - IMG_BLENDOP_MIN, /**< Result = min (Source, Destination) */ - IMG_BLENDOP_MAX /**< Result = max (Source, Destination) */ -} IMG_BLENDOP; - -/* - * Logical operation to perform when logic ops are enabled - */ -typedef enum _IMG_LOGICOP_ -{ - IMG_LOGICOP_CLEAR = 0, /**< Result = 0 */ - IMG_LOGICOP_SET, /**< Result = -1 */ - IMG_LOGICOP_COPY, /**< Result = Source */ - IMG_LOGICOP_COPY_INVERTED, /**< Result = ~Source */ - IMG_LOGICOP_NOOP, /**< Result = Destination */ - IMG_LOGICOP_INVERT, /**< Result = ~Destination */ - IMG_LOGICOP_AND, /**< Result = Source & Destination */ - IMG_LOGICOP_NAND, /**< Result = ~(Source & Destination) */ - IMG_LOGICOP_OR, /**< Result = Source | Destination */ - IMG_LOGICOP_NOR, /**< Result = ~(Source | Destination) */ - IMG_LOGICOP_XOR, /**< Result = Source ^ Destination */ - IMG_LOGICOP_EQUIV, /**< Result = ~(Source ^ Destination) */ - IMG_LOGICOP_AND_REVERSE, /**< Result = Source & ~Destination */ - IMG_LOGICOP_AND_INVERTED, /**< Result = ~Source & Destination */ - IMG_LOGICOP_OR_REVERSE, /**< Result = Source | ~Destination */ - IMG_LOGICOP_OR_INVERTED /**< Result = ~Source | Destination */ -} IMG_LOGICOP; - -/* - * Type of fog blending supported - */ -typedef enum _IMG_FOGMODE_ -{ - IMG_FOGMODE_NONE, /**< No fog blending - fog calculations are - * based on the value output from the vertex phase */ - IMG_FOGMODE_LINEAR, /**< Linear interpolation */ - IMG_FOGMODE_EXP, /**< Exponential */ - IMG_FOGMODE_EXP2, /**< Exponential squaring */ -} IMG_FOGMODE; - -/* - * Types of filtering - */ -typedef enum _IMG_FILTER_ -{ - IMG_FILTER_DONTCARE, /**< Any filtering mode is acceptable */ - IMG_FILTER_POINT, /**< Point filtering */ - IMG_FILTER_LINEAR, /**< Bi-linear filtering */ - IMG_FILTER_BICUBIC, /**< Bi-cubic filtering */ -} IMG_FILTER; - -/* - * Addressing modes for textures - */ -typedef enum _IMG_ADDRESSMODE_ -{ - IMG_ADDRESSMODE_REPEAT, /**< Texture repeats continuously */ - IMG_ADDRESSMODE_FLIP, /**< Texture flips on odd integer part */ - IMG_ADDRESSMODE_CLAMP, /**< Texture clamped at 0 or 1 */ - IMG_ADDRESSMODE_FLIPCLAMP, /**< Flipped once, then clamp */ - IMG_ADDRESSMODE_CLAMPBORDER, - IMG_ADDRESSMODE_OGL_CLAMP, - IMG_ADDRESSMODE_OVG_TILEFILL, - IMG_ADDRESSMODE_DONTCARE, -} IMG_ADDRESSMODE; - -/* - * Culling based on winding order of triangle. - */ -typedef enum _IMG_CULLMODE_ -{ - IMG_CULLMODE_NONE, /**< Don't cull */ - IMG_CULLMODE_FRONTFACING, /**< Front facing triangles */ - IMG_CULLMODE_BACKFACING, /**< Back facing triangles */ -} IMG_CULLMODE; - -/* - * Colour for clearing surfaces. - * The four elements of the 4 x 32 bit array will map to colour - * R,G,B,A components, in order. - * For YUV colour space the order is Y,U,V. - * For Depth and Stencil formats D maps to R and S maps to G. - */ -typedef union IMG_CLEAR_COLOUR_TAG { - IMG_UINT32 aui32[4]; - IMG_INT32 ai32[4]; - IMG_FLOAT af32[4]; -} IMG_CLEAR_COLOUR; - -static_assert(sizeof(IMG_FLOAT) == sizeof(IMG_INT32), "Size of IMG_FLOAT is not 32 bits."); - -/*! ************************************************************************//** -@brief Specifies the MSAA resolve operation. -*/ /**************************************************************************/ -typedef enum _IMG_RESOLVE_OP_ -{ - IMG_RESOLVE_BLEND = 0, /*!< box filter on the samples */ - IMG_RESOLVE_MIN = 1, /*!< minimum of the samples */ - IMG_RESOLVE_MAX = 2, /*!< maximum of the samples */ - IMG_RESOLVE_SAMPLE0 = 3, /*!< choose sample 0 */ - IMG_RESOLVE_SAMPLE1 = 4, /*!< choose sample 1 */ - IMG_RESOLVE_SAMPLE2 = 5, /*!< choose sample 2 */ - IMG_RESOLVE_SAMPLE3 = 6, /*!< choose sample 3 */ - IMG_RESOLVE_SAMPLE4 = 7, /*!< choose sample 4 */ - IMG_RESOLVE_SAMPLE5 = 8, /*!< choose sample 5 */ - IMG_RESOLVE_SAMPLE6 = 9, /*!< choose sample 6 */ - IMG_RESOLVE_SAMPLE7 = 10, /*!< choose sample 7 */ -} IMG_RESOLVE_OP; - - -#endif /* IMG_3DTYPES_H */ -/****************************************************************************** - End of file (img_3dtypes.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/img_defs.h b/drivers/gpu/drm/img-rogue/1.17/img_defs.h deleted file mode 100644 index a79e8a65d3cf0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/img_defs.h +++ /dev/null @@ -1,567 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common header containing type definitions for portability -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Contains variable and structure definitions. Any platform - specific types should be defined in this file. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 IMG_DEFS_H -#define IMG_DEFS_H - -#if defined(__linux__) && defined(__KERNEL__) -#include -#else -#include -#endif -#if !(defined(__linux__) && defined(__KERNEL__)) -#include -#endif - -#include "img_types.h" - -#if defined(NO_INLINE_FUNCS) - #define INLINE - #define FORCE_INLINE -#else -#if defined(__cplusplus) || defined(INTEGRITY_OS) - #if !defined(INLINE) - #define INLINE inline - #endif - #define FORCE_INLINE static inline -#else -#if !defined(INLINE) - #define INLINE __inline -#endif -#if (defined(UNDER_WDDM) || defined(WINDOWS_WDF)) && defined(_X86_) - #define FORCE_INLINE __forceinline -#else - #define FORCE_INLINE static __inline -#endif -#endif -#endif - -/* True if the GCC version is at least the given version. False for older - * versions of GCC, or other compilers. - */ -#if defined(__GNUC__) -#define GCC_VERSION_AT_LEAST(major, minor) \ - (__GNUC__ > (major) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) -#else -#define GCC_VERSION_AT_LEAST(major, minor) 0 -#endif - -/* Use Clang's __has_extension and __has_builtin macros if available. */ -#if defined(__has_extension) -#define has_clang_extension(e) __has_extension(e) -#else -#define has_clang_extension(e) 0 -#endif - -#if defined(__has_builtin) -#define has_clang_builtin(e) __has_builtin(e) -#else -#define has_clang_builtin(e) 0 -#endif - -/* Use this in any file, or use attributes under GCC - see below */ -#ifndef PVR_UNREFERENCED_PARAMETER -#define PVR_UNREFERENCED_PARAMETER(param) ((void)(param)) -#endif - -/* static_assert(condition, "message to print if it fails"); - * - * Assert something at compile time. If the assertion fails, try to print - * the message, otherwise do nothing. static_assert is available if: - * - * - It's already defined as a macro (e.g. by in C11) - * - We're using MSVC which exposes static_assert unconditionally - * - We're using a C++ compiler that supports C++11 - * - We're using GCC 4.6 and up in C mode (in which case it's available as - * _Static_assert) - * - * In all other cases, fall back to an equivalent that makes an invalid - * declaration. - */ -#if !defined(static_assert) && !defined(_MSC_VER) && \ - (!defined(__cplusplus) || __cplusplus < 201103L) || defined(__KLOCWORK__) - /* static_assert isn't already available */ - #if !defined(__cplusplus) && (GCC_VERSION_AT_LEAST(4, 6) || \ - (defined(__clang__) && has_clang_extension(c_static_assert))) - #define static_assert _Static_assert - #else - #define static_assert(expr, message) \ - extern int static_assert_failed[(expr) ? 1 : -1] __attribute__((unused)) - #endif -#endif - -/* - * unreachable("explanation") can be used to indicate to the compiler that - * some parts of the code can never be reached, like the default branch - * of a switch that covers all real-world possibilities, even though there - * are other ints that exist for instance. - * - * The message will be printed as an assert() when debugging. - * - * Note: there is no need to add a 'return' or any error handling after - * calling unreachable(), as this call will never return. - */ -#if defined(__linux__) && defined(__KERNEL__) -/* Kernel has its own unreachable(), which is a simple infinite loop */ -#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable) - #define unreachable(msg) \ - do { \ - assert(!(msg)); \ - __builtin_unreachable(); \ - } while (false) -#elif defined(_MSC_VER) - #define unreachable(msg) \ - do { \ - assert(!(msg)); \ - __assume(0); \ - } while (false) -#else - #define unreachable(msg) \ - do { \ - assert(!(msg)); \ - while (1); \ - } while (false) -#endif - -/* - * assume(x > 2 && x <= 7) works like an assert(), except it hints to the - * compiler what it can assume to optimise the code, like a limited range - * of parameter values. - */ -#if has_clang_builtin(__builtin_assume) - #define assume(expr) \ - do { \ - assert(expr); \ - __builtin_assume(expr); \ - } while (false) -#elif defined(_MSC_VER) - #define assume(expr) \ - do { \ - assert(expr); \ - __assume(expr); \ - } while (false) -#elif defined(__linux__) && defined(__KERNEL__) - #define assume(expr) ((void)(expr)) -#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable) - #define assume(expr) \ - do { \ - if (unlikely(!(expr))) \ - unreachable("Assumption isn't true: " # expr); \ - } while (false) -#else - #define assume(expr) assert(expr) -#endif - -/*! Macro to calculate the n-byte aligned value from that supplied rounding up. - * n must be a power of two. - * - * Both arguments should be of a type with the same size otherwise the macro may - * cut off digits, e.g. imagine a 64 bit address in _x and a 32 bit value in _n. - */ -#define PVR_ALIGN(_x, _n) (((_x)+((_n)-1U)) & ~((_n)-1U)) - -#if defined(_WIN32) - -#if defined(WINDOWS_WDF) - - /* - * For WINDOWS_WDF drivers we don't want these defines to overwrite calling conventions propagated through the build system. - * This 'empty' choice helps to resolve all the calling conv issues. - * - */ - #define IMG_CALLCONV - #define C_CALLCONV - - #define IMG_INTERNAL - #define IMG_RESTRICT __restrict - - /* - * The proper way of dll linking under MS compilers is made of two things: - * - decorate implementation with __declspec(dllexport) - * this decoration helps compiler with making the so called - * 'export library' - * - decorate forward-declaration (in a source dependent on a dll) with - * __declspec(dllimport), this decoration helps the compiler to make - * faster and smaller code in terms of calling dll-imported functions - * - * Usually these decorations are performed by having a single macro define - * making that expands to a proper __declspec() depending on the - * translation unit, dllexport inside the dll source and dllimport outside - * the dll source. Having IMG_EXPORT and IMG_IMPORT resolving to the same - * __declspec() makes no sense, but at least works. - */ - #define IMG_IMPORT __declspec(dllexport) - #define IMG_EXPORT __declspec(dllexport) - -#else - - #define IMG_CALLCONV __stdcall - #define IMG_INTERNAL - #define IMG_EXPORT __declspec(dllexport) - #define IMG_RESTRICT __restrict - #define C_CALLCONV __cdecl - - /* - * IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations - * match. Some compilers require the header to be declared IMPORT, while - * the implementation is declared EXPORT. - */ - #define IMG_IMPORT IMG_EXPORT - -#endif - -#if defined(UNDER_WDDM) - #ifndef _INC_STDLIB - #if defined(__mips) - /* do nothing */ - #elif defined(UNDER_MSBUILD) - /* do nothing */ - #else - _CRTIMP void __cdecl abort(void); - #endif - #endif -#endif /* UNDER_WDDM */ -#else - #if (defined(__linux__) || defined(__QNXNTO__)) && defined(__KERNEL__) - #define IMG_INTERNAL - #define IMG_EXPORT - #define IMG_CALLCONV - #elif defined(__linux__) || defined(__METAG) || defined(__mips) || defined(__QNXNTO__) || defined(__riscv) - #define IMG_CALLCONV - #define C_CALLCONV - - #if defined(__METAG) - #define IMG_INTERNAL - #else - #define IMG_INTERNAL __attribute__((visibility("hidden"))) - #endif - - #define IMG_EXPORT __attribute__((visibility("default"))) - #define IMG_RESTRICT __restrict__ - #elif defined(INTEGRITY_OS) - #define IMG_CALLCONV - #define IMG_INTERNAL - #define IMG_EXPORT - #define IMG_RESTRICT - #define C_CALLCONV - #define __cdecl - - #ifndef USE_CODE - #define IMG_ABORT() printf("IMG_ABORT was called.\n") - #endif - #else - #error("define an OS") - #endif - -#endif - -/* Use default definition if not overridden */ -#ifndef IMG_ABORT - #if defined(EXIT_ON_ABORT) - #define IMG_ABORT() exit(1) - #else - #define IMG_ABORT() abort() - #endif -#endif - -/* The best way to suppress unused parameter warnings using GCC is to use a - * variable attribute. Place the __maybe_unused between the type and name of an - * unused parameter in a function parameter list e.g. 'int __maybe_unused var'. - * This should only be used in GCC build environments, for example, in files - * that compile only on Linux. - * Other files should use PVR_UNREFERENCED_PARAMETER - */ - -/* Kernel macros for compiler attributes */ -/* Note: param positions start at 1 */ -#if defined(__linux__) && defined(__KERNEL__) - #include - - #if !defined(__fallthrough) - #if GCC_VERSION_AT_LEAST(7, 0) - #define __fallthrough __attribute__((__fallthrough__)) - #else - #define __fallthrough - #endif - #endif -#elif defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES) - #define __must_check __attribute__((warn_unused_result)) - #define __maybe_unused __attribute__((unused)) - #define __malloc __attribute__((malloc)) - - /* Bionic's might have defined these already */ - /* See https://android.googlesource.com/platform/bionic.git/+/master/libc/include/sys/cdefs.h */ - #if !defined(__packed) - #define __packed __attribute__((packed)) - #endif - #if !defined(__aligned) - #define __aligned(n) __attribute__((aligned(n))) - #endif - #if !defined(__noreturn) - #define __noreturn __attribute__((noreturn)) - #endif - - /* That one compiler that supports attributes but doesn't support - * the printf attribute... */ - #if defined(__GNUC__) - #define __printf(fmt, va) __attribute__((format(printf, (fmt), (va)))) - #else - #define __printf(fmt, va) - #endif /* defined(__GNUC__) */ - - #if defined(__cplusplus) && (__cplusplus >= 201703L) - #define __fallthrough [[fallthrough]] - #elif GCC_VERSION_AT_LEAST(7, 0) - #define __fallthrough __attribute__((__fallthrough__)) - #else - #define __fallthrough - #endif - - #define __user - #define __force - #define __iomem -#else - /* Silently ignore those attributes */ - #define __printf(fmt, va) - #define __packed - #define __aligned(n) - #define __must_check - #define __maybe_unused - #define __malloc - - #if defined(_MSC_VER) || defined(CC_ARM) - #define __noreturn __declspec(noreturn) - #else - #define __noreturn - #endif - - /* This may already been defined, e.g. by SAL (Source Annotation Language) */ - #if !defined(__fallthrough) - #define __fallthrough - #endif - - #define __user - #define __force - #define __iomem -#endif - - -/* Other attributes, following the same style */ -#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES) - #define __const_function __attribute__((const)) -#else - #define __const_function -#endif - - -/* GCC builtins */ -#if defined(__linux__) && defined(__KERNEL__) - #include -#elif defined(__GNUC__) || defined(INTEGRITY_OS) - -/* Klocwork does not support __builtin_expect, which makes the actual condition - * expressions hidden during analysis, affecting it negatively. */ -#if !defined(__KLOCWORK__) && !defined(INTEGRITY_OS) && !defined(DEBUG) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#endif - - /* Compiler memory barrier to prevent reordering */ - #define barrier() __asm__ __volatile__("": : :"memory") -#else - #define barrier() static_assert(0, "barrier() isn't supported by your compiler"); -#endif - -/* That one OS that defines one but not the other... */ -#ifndef likely - #define likely(x) (x) -#endif -#ifndef unlikely - #define unlikely(x) (x) -#endif - -/* These two macros are also provided by the kernel */ -#ifndef BIT -#define BIT(b) (1UL << (b)) -#endif - -#ifndef BIT_ULL -#define BIT_ULL(b) (1ULL << (b)) -#endif - -#define BIT_SET(f, b) BITMASK_SET((f), BIT(b)) -#define BIT_UNSET(f, b) BITMASK_UNSET((f), BIT(b)) -#define BIT_TOGGLE(f, b) BITMASK_TOGGLE((f), BIT(b)) -#define BIT_ISSET(f, b) BITMASK_HAS((f), BIT(b)) - -#define BITMASK_SET(f, m) do { ((f) |= (m)); } while (false) -#define BITMASK_UNSET(f, m) do { ((f) &= ~(m)); } while (false) -#define BITMASK_TOGGLE(f, m) do { ((f) ^= (m)); } while (false) -#define BITMASK_HAS(f, m) (((f) & (m)) == (m)) /* the bits from the mask are all set */ -#define BITMASK_ANY(f, m) (((f) & (m)) != 0U) /* any bit from the mask is set */ - -#ifndef MAX -#define MAX(a ,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef CLAMP -#define CLAMP(min, max, n) ((n) < (min) ? (min) : ((n) > (max) ? (max) : (n))) -#endif - -#define SWAP(X, Y) (X) ^= (Y); (Y) ^= (X); (X) ^= (Y); - - -#if defined(__linux__) && defined(__KERNEL__) - #include - #include -#endif - -/* Get a structure's address from the address of a member */ -#define IMG_CONTAINER_OF(ptr, type, member) \ - (type *) ((uintptr_t) (ptr) - offsetof(type, member)) - -/* Get a new pointer with an offset (in bytes) from a base address, useful - * when traversing byte buffers and accessing data in buffers through struct - * pointers. - * Note, this macro is not equivalent to or replacing offsetof() */ -#define IMG_OFFSET_ADDR(addr, offset_in_bytes) \ - (void*)&(((IMG_UINT8*)(void*)(addr))[offset_in_bytes]) - -/* Get a new pointer with an offset (in dwords) from a base address, useful - * when traversing byte buffers and accessing data in buffers through struct - * pointers. - * Note, this macro is not equivalent to or replacing offsetof() */ -#define IMG_OFFSET_ADDR_DW(addr, offset_in_dwords) \ - (void*)(((IMG_UINT32*)(void*)(addr)) + (offset_in_dwords)) - -/* The number of elements in a fixed-sized array */ -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(ARR) (sizeof(ARR) / sizeof((ARR)[0])) -#endif - -/* To guarantee that __func__ can be used, define it as a macro here if it - isn't already provided by the compiler. */ -#if defined(_MSC_VER) || (defined(__cplusplus) && __cplusplus < 201103L) -#define __func__ __FUNCTION__ -#endif - -#if defined(__cplusplus) -/* C++ Specific: - * Disallow use of copy and assignment operator within a class. - * Should be placed under private. */ -#define IMG_DISALLOW_COPY_AND_ASSIGN(C) \ - C(const C&); \ - void operator=(const C&) -#endif - -#if defined(SUPPORT_PVR_VALGRIND) && !defined(__METAG) && !defined(__mips) && !defined(__riscv) - #include "/usr/include/valgrind/memcheck.h" - - #define VG_MARK_INITIALIZED(pvData,ui32Size) VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size) - #define VG_MARK_NOACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_NOACCESS(pvData,ui32Size) - #define VG_MARK_ACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_UNDEFINED(pvData,ui32Size) - #define VG_ASSERT_DEFINED(pvData,ui32Size) VALGRIND_CHECK_MEM_IS_DEFINED(pvData,ui32Size) -#else - #if defined(_MSC_VER) - # define PVR_MSC_SUPPRESS_4127 __pragma(warning(suppress:4127)) - #else - # define PVR_MSC_SUPPRESS_4127 - #endif - - #define VG_MARK_INITIALIZED(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (false) - #define VG_MARK_NOACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (false) - #define VG_MARK_ACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (false) - #define VG_ASSERT_DEFINED(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (false) -#endif - -#define IMG_STRINGIFY_IMPL(x) # x -#define IMG_STRINGIFY(x) IMG_STRINGIFY_IMPL(x) - -#if defined(INTEGRITY_OS) - /* Definitions not present in INTEGRITY. */ - #define PATH_MAX 200 -#endif - -#if defined(__clang__) || defined(__GNUC__) - /* __SIZEOF_POINTER__ is defined already by these compilers */ -#elif defined(INTEGRITY_OS) - #if defined(__Ptr_Is_64) - #define __SIZEOF_POINTER__ 8 - #else - #define __SIZEOF_POINTER__ 4 - #endif -#elif defined(_WIN32) - #define __SIZEOF_POINTER__ sizeof(char *) -#else - #warning Unknown OS - using default method to determine whether CPU arch is 64-bit. - #define __SIZEOF_POINTER__ sizeof(char *) -#endif - -/* RDI8567: gcc/clang/llvm load/store optimisations may cause issues with - * uncached device memory allocations. Some pointers are made 'volatile' - * to prevent those optimisations being applied to writes through those - * pointers. - */ -#if (GCC_VERSION_AT_LEAST(7, 0) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) -#define NOLDSTOPT volatile -/* after applying 'volatile' to a pointer, we may need to cast it to 'void *' - * to keep it compatible with its existing uses. - */ -#define NOLDSTOPT_VOID (void *) - -#define NOLDSTOPT_REQUIRED 1 -#else -#define NOLDSTOPT -#define NOLDSTOPT_VOID -#endif - -#endif /* IMG_DEFS_H */ -/***************************************************************************** - End of file (img_defs.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/img_elf.h b/drivers/gpu/drm/img-rogue/1.17/img_elf.h deleted file mode 100644 index 8837d95925996..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/img_elf.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ /*! -@File img_elf.h -@Title IMG ELF file definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Platform RGX -@Description Definitions for ELF file structures used in the DDK. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(IMG_ELF_H) -#define IMG_ELF_H - -#include "img_types.h" - -/* ELF format defines */ -#define ELF_PT_LOAD (0x1U) /* Program header identifier as Load */ -#define ELF_SHT_SYMTAB (0x2U) /* Section identifier as Symbol Table */ -#define ELF_SHT_STRTAB (0x3U) /* Section identifier as String Table */ -#define MAX_STRTAB_NUM (0x8U) /* Maximum number of string table in the ELF file */ - -/* Redefined structs of ELF format */ -typedef struct -{ - IMG_UINT8 ui32Eident[16]; - IMG_UINT16 ui32Etype; - IMG_UINT16 ui32Emachine; - IMG_UINT32 ui32Eversion; - IMG_UINT32 ui32Eentry; - IMG_UINT32 ui32Ephoff; - IMG_UINT32 ui32Eshoff; - IMG_UINT32 ui32Eflags; - IMG_UINT16 ui32Eehsize; - IMG_UINT16 ui32Ephentsize; - IMG_UINT16 ui32Ephnum; - IMG_UINT16 ui32Eshentsize; - IMG_UINT16 ui32Eshnum; - IMG_UINT16 ui32Eshtrndx; -} IMG_ELF_HDR; - -typedef struct -{ - IMG_UINT32 ui32Stname; - IMG_UINT32 ui32Stvalue; - IMG_UINT32 ui32Stsize; - IMG_UINT8 ui32Stinfo; - IMG_UINT8 ui32Stother; - IMG_UINT16 ui32Stshndx; -} IMG_ELF_SYM; - -typedef struct -{ - IMG_UINT32 ui32Shname; - IMG_UINT32 ui32Shtype; - IMG_UINT32 ui32Shflags; - IMG_UINT32 ui32Shaddr; - IMG_UINT32 ui32Shoffset; - IMG_UINT32 ui32Shsize; - IMG_UINT32 ui32Shlink; - IMG_UINT32 ui32Shinfo; - IMG_UINT32 ui32Shaddralign; - IMG_UINT32 ui32Shentsize; -} IMG_ELF_SHDR; - -typedef struct -{ - IMG_UINT32 ui32Ptype; - IMG_UINT32 ui32Poffset; - IMG_UINT32 ui32Pvaddr; - IMG_UINT32 ui32Ppaddr; - IMG_UINT32 ui32Pfilesz; - IMG_UINT32 ui32Pmemsz; - IMG_UINT32 ui32Pflags; - IMG_UINT32 ui32Palign; -} IMG_ELF_PROGRAM_HDR; - -#endif /* IMG_ELF_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/img_types.h b/drivers/gpu/drm/img-rogue/1.17/img_types.h deleted file mode 100644 index c2654d21edb3d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/img_types.h +++ /dev/null @@ -1,324 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Global types for use by IMG APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines type aliases for use by IMG APIs. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 IMG_TYPES_H -#define IMG_TYPES_H -#if defined(__cplusplus) -extern "C" { -#endif - -/* To use C99 types and definitions, there are two special cases we need to - * cater for: - * - * - Visual Studio: in VS2010 or later, some standard headers are available, - * and MSVC has its own built-in sized types. We can define the C99 types - * in terms of these. - * - * - Linux kernel code: C99 sized types are defined in , but - * some other features (like macros for constants or printf format - * strings) are missing, so we need to fill in the gaps ourselves. - * - * For other cases (userspace code under Linux, Android or Neutrino, or - * firmware code), we can include the standard headers. - */ -#if defined(_MSC_VER) - #include /* bool */ - #include "msvc_types.h" -#elif defined(__linux__) && defined(__KERNEL__) - #include - #include - #include "kernel_types.h" -#elif defined(__linux__) || defined(__METAG) || defined(__MINGW32__) || \ - defined(__QNXNTO__) || defined(INTEGRITY_OS) || defined(__riscv) - #include /* NULL */ - #include - #include /* intX_t/uintX_t, format specifiers */ - #include /* INT_MIN, etc */ - #include /* bool */ -#elif defined(__mips) - #include /* NULL */ - #include /* intX_t/uintX_t, format specifiers */ - #include /* bool */ -#else - #error C99 support not set up for this build -#endif - -/* - * Due to a Klocwork bug, 'true'/'false' constants are not recognized to be of - * boolean type. This results in large number of false-positives being reported - * (MISRA.ETYPE.ASSIGN.2012: "An expression value of essential type 'signed char' - * is assigned to an object of essential type 'bool'"). Work around this by - * redefining those constants with cast to bool added. - */ -#if defined(__KLOCWORK__) && !defined(__cplusplus) -#undef true -#undef false -#define true ((bool) 1) -#define false ((bool) 0) -#endif - -typedef unsigned int IMG_UINT; -typedef int IMG_INT; - -typedef uint8_t IMG_UINT8, *IMG_PUINT8; -typedef uint8_t IMG_BYTE, *IMG_PBYTE; -typedef int8_t IMG_INT8; -typedef char IMG_CHAR, *IMG_PCHAR; - -typedef uint16_t IMG_UINT16, *IMG_PUINT16; -typedef int16_t IMG_INT16; -typedef uint32_t IMG_UINT32, *IMG_PUINT32; -typedef int32_t IMG_INT32, *IMG_PINT32; -#if defined(INTEGRITY_OS) -#if __INT_BIT >= 32U -#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## U)) -#elif __LONG_BIT >= 32U -#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## UL)) -#elif defined(__LLONG_BIT) && __LLONG_BIT >= 32U -#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## ULL)) -#endif -#else /* defined(INTEGRITY_OS) */ -#define IMG_UINT32_C(c) ((IMG_UINT32)UINT32_C(c)) -#endif /* defined(INTEGRITY_OS) */ - -typedef uint64_t IMG_UINT64, *IMG_PUINT64; -typedef int64_t IMG_INT64; -#define IMG_INT64_C(c) INT64_C(c) -#if defined(INTEGRITY_OS) -#if __INT_BIT >= 64U -#define IMG_UINT64_C(n) (n ## U) -#elif defined(__LONG_BIT) && __LONG_BIT >= 64U -#define IMG_UINT64_C(n) (n ## UL) -#elif defined(__LLONG_BIT) && __LLONG_BIT >= 64U -#define IMG_UINT64_C(n) (n ## ULL) -#endif -#else /* defined(INTEGRITY_OS) */ -#define IMG_UINT64_C(c) UINT64_C(c) -#endif /* defined(INTEGRITY_OS) */ -#define IMG_UINT16_C(c) UINT16_C(c) -#define IMG_UINT64_FMTSPEC PRIu64 -#define IMG_UINT64_FMTSPECX PRIX64 -#define IMG_UINT64_FMTSPECx PRIx64 -#define IMG_UINT64_FMTSPECo PRIo64 -#define IMG_INT64_FMTSPECd PRId64 - -#define IMG_UINT16_MAX UINT16_MAX -#define IMG_UINT32_MAX UINT32_MAX -#define IMG_UINT64_MAX UINT64_MAX - -#define IMG_INT16_MAX INT16_MAX -#define IMG_INT32_MAX INT32_MAX -#define IMG_INT64_MAX INT64_MAX - -/* Linux kernel mode does not use floating point */ -typedef float IMG_FLOAT, *IMG_PFLOAT; -typedef double IMG_DOUBLE; - -typedef union -{ - IMG_UINT32 ui32; - IMG_FLOAT f; -} IMG_UINT32_FLOAT; - -typedef int IMG_SECURE_TYPE; - -typedef enum tag_img_bool -{ - IMG_FALSE = 0, - IMG_TRUE = 1, - IMG_FORCE_ALIGN = 0x7FFFFFFF -} IMG_BOOL, *IMG_PBOOL; - -#if defined(UNDER_WDDM) || defined(WINDOWS_WDF) -typedef IMG_CHAR const* IMG_PCCHAR; -#endif - -/* Format specifiers for 'size_t' type */ -#if defined(_MSC_VER) || defined(__MINGW32__) -#define IMG_SIZE_FMTSPEC "%Iu" -#define IMG_SIZE_FMTSPECX "%Ix" -#else -#define IMG_SIZE_FMTSPEC "%zu" -#define IMG_SIZE_FMTSPECX "%zx" -#endif - -#if defined(__linux__) && defined(__KERNEL__) -/* prints the function name when used with printk */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#define IMG_PFN_FMTSPEC "%ps" -#else -#define IMG_PFN_FMTSPEC "%pf" -#endif -#else -#define IMG_PFN_FMTSPEC "%p" -#endif - -typedef void *IMG_HANDLE; - -/* Process IDs */ -typedef IMG_UINT32 IMG_PID; - -/* OS connection type */ -typedef int IMG_OS_CONNECTION; - - -/* - * Address types. - * All types used to refer to a block of memory are wrapped in structures - * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot - * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the - * same thing. - * - * There is an assumption that the system contains at most one non-cpu mmu, - * and a memory block is only mapped by the MMU once. - * - * Different devices could have offset views of the physical address space. - * - */ - - -/* - * - * +------------+ +------------+ +------------+ +------------+ - * | CPU | | DEV | | DEV | | DEV | - * +------------+ +------------+ +------------+ +------------+ - * | | | | - * | void * |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR | - * | \-------------------/ | - * | | | - * +------------+ +------------+ | - * | MMU | | MMU | | - * +------------+ +------------+ | - * | | | - * | | | - * | | | - * +--------+ +---------+ +--------+ - * | Offset | | (Offset)| | Offset | - * +--------+ +---------+ +--------+ - * | | IMG_DEV_PHYADDR | - * | | | - * | | IMG_DEV_PHYADDR | - * +---------------------------------------------------------------------+ - * | System Address bus | - * +---------------------------------------------------------------------+ - * - */ - -#define IMG_DEV_VIRTADDR_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX -#define IMG_DEVMEM_SIZE_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX -#define IMG_DEVMEM_ALIGN_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX -#define IMG_DEVMEM_OFFSET_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX - -/* cpu physical address */ -typedef struct -{ -#if defined(UNDER_WDDM) || defined(WINDOWS_WDF) - uintptr_t uiAddr; -#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (uintptr_t)(var) -#define CPUPHYADDR_FMTARG(var) (IMG_UINT64)(var) -#define CPUPHYADDR_UINT_FMTSPEC "0x%016" IMG_UINT64_FMTSPECx -#elif defined(__linux__) && defined(__KERNEL__) - phys_addr_t uiAddr; -#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (phys_addr_t)(var) -#define CPUPHYADDR_FMTARG(var) (&var) -#define CPUPHYADDR_UINT_FMTSPEC "%pa" -#else - IMG_UINT64 uiAddr; -#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (IMG_UINT64)(var) -#define CPUPHYADDR_FMTARG(var) (var) -#define CPUPHYADDR_UINT_FMTSPEC "0x%016" IMG_UINT64_FMTSPECx -#endif -} IMG_CPU_PHYADDR; - -/* device physical address */ -typedef struct -{ - IMG_UINT64 uiAddr; -} IMG_DEV_PHYADDR; - -/* dma address */ -typedef struct -{ - IMG_UINT64 uiAddr; -} IMG_DMA_ADDR; - -/* - rectangle structure -*/ -typedef struct -{ - IMG_INT32 x0; - IMG_INT32 y0; - IMG_INT32 x1; - IMG_INT32 y1; -} IMG_RECT; - -typedef struct -{ - IMG_INT16 x0; - IMG_INT16 y0; - IMG_INT16 x1; - IMG_INT16 y1; -} IMG_RECT_16; - -/* - * box structure - */ -typedef struct -{ - IMG_INT32 x0; - IMG_INT32 y0; - IMG_INT32 z0; - IMG_INT32 x1; - IMG_INT32 y1; - IMG_INT32 z1; -} IMG_BOX; - -#if defined(__cplusplus) -} -#endif - -#endif /* IMG_TYPES_H */ -/****************************************************************************** - End of file (img_types.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/img_types_check.h b/drivers/gpu/drm/img-rogue/1.17/img_types_check.h deleted file mode 100644 index 4708583b6c234..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/img_types_check.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Global types for use by IMG APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Performs size checks on some of the IMG types. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 IMG_TYPES_CHECK_H -#define IMG_TYPES_CHECK_H - -#ifndef __KERNEL__ -#include -#endif /* __KERNEL__ */ -#include "img_types.h" -#include "pvrsrv_error.h" - -static_assert(sizeof(IMG_BOOL) == 4, "invalid size of IMG_BOOL"); -static_assert(sizeof(IMG_INT) == 4, "invalid size of IMG_INT"); -static_assert(sizeof(IMG_UINT) == 4, "invalid size of IMG_UINT"); -static_assert(sizeof(PVRSRV_ERROR) == 4, "invalid size of PVRSRV_ERROR"); - -#endif /* IMG_TYPES_CHECK_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/info_page.h b/drivers/gpu/drm/img-rogue/1.17/info_page.h deleted file mode 100644 index 4caa5348bf6e9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/info_page.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Kernel/User mode general purpose shared memory. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description General purpose memory shared between kernel driver and user - mode. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 INFO_PAGE_KM_H -#define INFO_PAGE_KM_H - -#include "pvrsrv_error.h" - -#include "pmr.h" -#include "pvrsrv.h" -#include "info_page_defs.h" - -/* - * @Function InfoPageCreate - * @Description Allocates resources for global information page. - * @Input psData pointer to PVRSRV data - * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error. - */ -PVRSRV_ERROR InfoPageCreate(PVRSRV_DATA *psData); - -/* - * @Function InfoPageDestroy - * @Description Frees all of the resource of global information page. - * @Input psData pointer to PVRSRV data - * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error. - */ -void InfoPageDestroy(PVRSRV_DATA *psData); - -/* - * @Function PVRSRVAcquireInfoPageKM() - * @Description This interface is used for obtaining the global information page - * which acts as a general purpose shared memory between KM and UM. - * The use of this information page outside of services is _not_ - * recommended. - * @Output ppsPMR handle to exported PMR - * @Return - */ -PVRSRV_ERROR PVRSRVAcquireInfoPageKM(PMR **ppsPMR); - -/* - * @Function PVRSRVReleaseInfoPageKM() - * @Description This function matches PVRSRVAcquireInfoPageKM(). - * @Input psPMR handle to exported PMR - * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error. - */ -PVRSRV_ERROR PVRSRVReleaseInfoPageKM(PMR *psPMR); - -/* - * @Function GetInfoPageDebugFlagsKM() - * @Description Return info page debug flags - * @Return info page debug flags - */ -static INLINE IMG_UINT32 GetInfoPageDebugFlagsKM(void) -{ - return (PVRSRVGetPVRSRVData())->pui32InfoPage[DEBUG_FEATURE_FLAGS]; -} - -#endif /* INFO_PAGE_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/info_page_client.h b/drivers/gpu/drm/img-rogue/1.17/info_page_client.h deleted file mode 100644 index 9df2461b55fba..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/info_page_client.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Kernel/User mode general purpose shared memory. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description General purpose shared memory (i.e. information page) mapped by - kernel space driver and user space clients. All info page - entries are sizeof(IMG_UINT32) on both 32/64-bit environments. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 INFO_PAGE_CLIENT_H -#define INFO_PAGE_CLIENT_H - -#include "device_connection.h" -#include "info_page_defs.h" -#if defined(__KERNEL__) -#include "pvrsrv.h" -#endif - -/*************************************************************************/ /*! -@Function GetInfoPage - -@Description Return Info Page address - -@Input hDevConnection - Services device connection - -@Return Info Page address -*/ -/*****************************************************************************/ -static INLINE IMG_PUINT32 GetInfoPage(SHARED_DEV_CONNECTION hDevConnection) -{ -#if defined(__KERNEL__) - return (PVRSRVGetPVRSRVData())->pui32InfoPage; -#else - return hDevConnection->pui32InfoPage; -#endif -} - -/*************************************************************************/ /*! -@Function GetInfoPageDebugFlags - -@Description Return Info Page debug flags - -@Input hDevConnection - Services device connection - -@Return Info Page debug flags -*/ -/*****************************************************************************/ -static INLINE IMG_UINT32 GetInfoPageDebugFlags(SHARED_DEV_CONNECTION hDevConnection) -{ - return GetInfoPage(hDevConnection)[DEBUG_FEATURE_FLAGS]; -} - -#endif /* INFO_PAGE_CLIENT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/info_page_defs.h b/drivers/gpu/drm/img-rogue/1.17/info_page_defs.h deleted file mode 100644 index d3bc1538a0c7e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/info_page_defs.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Kernel/User mode general purpose shared memory. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description General purpose shared memory (i.e. information page) mapped by - kernel space driver and user space clients. All information page - entries are sizeof(IMG_UINT32) on both 32/64-bit environments. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 INFO_PAGE_DEFS_H -#define INFO_PAGE_DEFS_H - - -/* CacheOp information page entries */ -#define CACHEOP_INFO_IDX_START 0x00 -#define CACHEOP_INFO_UMKMTHRESHLD (CACHEOP_INFO_IDX_START + 1) /*!< UM=>KM routing threshold in bytes */ -#define CACHEOP_INFO_KMDFTHRESHLD (CACHEOP_INFO_IDX_START + 2) /*!< KM/DF threshold in bytes */ -#define CACHEOP_INFO_LINESIZE (CACHEOP_INFO_IDX_START + 3) /*!< CPU data cache line size */ -#define CACHEOP_INFO_PGSIZE (CACHEOP_INFO_IDX_START + 4) /*!< CPU MMU page size */ -#define CACHEOP_INFO_IDX_END (CACHEOP_INFO_IDX_START + 5) - -/* HWPerf information page entries */ -#define HWPERF_INFO_IDX_START (CACHEOP_INFO_IDX_END) -#define HWPERF_FILTER_SERVICES_IDX (HWPERF_INFO_IDX_START + 0) -#define HWPERF_FILTER_EGL_IDX (HWPERF_INFO_IDX_START + 1) -#define HWPERF_FILTER_OPENGLES_IDX (HWPERF_INFO_IDX_START + 2) -#define HWPERF_FILTER_OPENCL_IDX (HWPERF_INFO_IDX_START + 3) -#define HWPERF_FILTER_VULKAN_IDX (HWPERF_INFO_IDX_START + 4) -#define HWPERF_FILTER_OPENGL_IDX (HWPERF_INFO_IDX_START + 5) -#define HWPERF_INFO_IDX_END (HWPERF_INFO_IDX_START + 6) - -/* timeout values */ -#define TIMEOUT_INFO_IDX_START (HWPERF_INFO_IDX_END) -#define TIMEOUT_INFO_VALUE_RETRIES (TIMEOUT_INFO_IDX_START + 0) -#define TIMEOUT_INFO_VALUE_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 1) -#define TIMEOUT_INFO_CONDITION_RETRIES (TIMEOUT_INFO_IDX_START + 2) -#define TIMEOUT_INFO_CONDITION_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 3) -#define TIMEOUT_INFO_TASK_QUEUE_RETRIES (TIMEOUT_INFO_IDX_START + 4) -#define TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 5) -#define TIMEOUT_INFO_IDX_END (TIMEOUT_INFO_IDX_START + 6) - -/* Bridge Info */ -#define BRIDGE_INFO_IDX_START (TIMEOUT_INFO_IDX_END) -#define BRIDGE_INFO_RGX_BRIDGES (BRIDGE_INFO_IDX_START + 0) -#define BRIDGE_INFO_PVR_BRIDGES (BRIDGE_INFO_IDX_START + 1) -#define BRIDGE_INFO_IDX_END (BRIDGE_INFO_IDX_START + 2) - -/* Debug features */ -#define DEBUG_FEATURE_FLAGS (BRIDGE_INFO_IDX_END) -#define DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED 0x1 -#define DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED 0x2 -#define DEBUG_FEATURE_FLAGS_IDX_END (DEBUG_FEATURE_FLAGS + 1) - - -#endif /* INFO_PAGE_DEFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/info_page_km.c b/drivers/gpu/drm/img-rogue/1.17/info_page_km.c deleted file mode 100644 index 19345bcad00b4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/info_page_km.c +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************/ /*! -@File info_page_km.c -@Title Kernel/User space shared memory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements general purpose shared memory between kernel driver - and user mode. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "info_page_defs.h" -#include "info_page.h" -#include "pvrsrv.h" -#include "devicemem.h" -#include "pmr.h" - -PVRSRV_ERROR InfoPageCreate(PVRSRV_DATA *psData) -{ - const PVRSRV_MEMALLOCFLAGS_T uiMemFlags = PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(CPU_LOCAL); - PVRSRV_ERROR eError; - - PVR_ASSERT(psData != NULL); - - /* Allocate single page of memory for driver information page */ - eError = DevmemAllocateExportable(psData->psHostMemDeviceNode, - OSGetPageSize(), - OSGetPageSize(), - OSGetPageShift(), - uiMemFlags, - "PVRSRVInfoPage", - &psData->psInfoPageMemDesc); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAllocateExportable", e0); - - eError = DevmemAcquireCpuVirtAddr(psData->psInfoPageMemDesc, - (void **) &psData->pui32InfoPage); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAllocateExportable", e0); - - /* Look-up the memory descriptor PMR handle */ - eError = DevmemLocalGetImportHandle(psData->psInfoPageMemDesc, - (void **) &psData->psInfoPagePMR); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemLocalGetImportHandle", e0); - - eError = OSLockCreate(&psData->hInfoPageLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0); - - /* Because the memory is allocated read only we need to explicitly set it to - * 0. The reason for this is that if the memory is allocated with - * ZERO_ON_ALLOC a WRITEABLE attribute is implicitly added to the flags (see - * DevmemValidateParams()). */ - OSCachedMemSet(psData->pui32InfoPage, 0, OSGetPageSize()); - - return PVRSRV_OK; - -e0: - InfoPageDestroy(psData); - return eError; -} - -void InfoPageDestroy(PVRSRV_DATA *psData) -{ - if (psData->psInfoPageMemDesc) - { - if (psData->pui32InfoPage != NULL) - { - DevmemReleaseCpuVirtAddr(psData->psInfoPageMemDesc); - psData->pui32InfoPage = NULL; - } - - DevmemFree(psData->psInfoPageMemDesc); - psData->psInfoPageMemDesc = NULL; - } - - if (psData->hInfoPageLock) - { - OSLockDestroy(psData->hInfoPageLock); - psData->hInfoPageLock = NULL; - } -} - -PVRSRV_ERROR PVRSRVAcquireInfoPageKM(PMR **ppsPMR) -{ - PVRSRV_DATA *psData = PVRSRVGetPVRSRVData(); - - PVR_LOG_RETURN_IF_FALSE(psData->psInfoPageMemDesc != NULL, "invalid MEMDESC" - " handle", PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE(psData->psInfoPagePMR != NULL, "invalid PMR handle", - PVRSRV_ERROR_INVALID_PARAMS); - - /* Copy the PMR import handle back */ - *ppsPMR = psData->psInfoPagePMR; - - /* Mark the PMR such that no layout changes can happen - * This is a fixed layout created during early stages of - * driver loading and shouldn't change later */ - PMR_SetLayoutFixed(psData->psInfoPagePMR, IMG_TRUE); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVReleaseInfoPageKM(PMR *ppsPMR) -{ - /* Nothing to do here as PMR is singleton */ - PVR_UNREFERENCED_PARAMETER(ppsPMR); - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/interrupt_support.c b/drivers/gpu/drm/img-rogue/1.17/interrupt_support.c deleted file mode 100644 index c67d453520508..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/interrupt_support.c +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_debug.h" -#include "allocmem.h" -#include "interrupt_support.h" - -typedef struct LISR_DATA_TAG -{ - IMG_UINT32 ui32IRQ; - PFN_SYS_LISR pfnLISR; - void *pvData; -} LISR_DATA; - -static irqreturn_t SystemISRWrapper(int irq, void *dev_id) -{ - LISR_DATA *psLISRData = (LISR_DATA *)dev_id; - - PVR_UNREFERENCED_PARAMETER(irq); - - if (psLISRData) - { - if (psLISRData->pfnLISR(psLISRData->pvData)) - { - return IRQ_HANDLED; - } - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: Missing interrupt data", __func__)); - } - - return IRQ_NONE; -} - -PVRSRV_ERROR OSInstallSystemLISR(IMG_HANDLE *phLISR, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszDevName, - PFN_SYS_LISR pfnLISR, - void *pvData, - IMG_UINT32 ui32Flags) -{ - LISR_DATA *psLISRData; - unsigned long ulIRQFlags = 0; - - if (pfnLISR == NULL || pvData == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32Flags & ~SYS_IRQ_FLAG_MASK) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - switch (ui32Flags & SYS_IRQ_FLAG_TRIGGER_MASK) - { - case SYS_IRQ_FLAG_TRIGGER_DEFAULT: - break; - case SYS_IRQ_FLAG_TRIGGER_LOW: - ulIRQFlags |= IRQF_TRIGGER_LOW; - break; - case SYS_IRQ_FLAG_TRIGGER_HIGH: - ulIRQFlags |= IRQF_TRIGGER_HIGH; - break; - default: - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32Flags & SYS_IRQ_FLAG_SHARED) - { - ulIRQFlags |= IRQF_SHARED; - } - - psLISRData = OSAllocMem(sizeof(*psLISRData)); - if (psLISRData == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psLISRData->ui32IRQ = ui32IRQ; - psLISRData->pfnLISR = pfnLISR; - psLISRData->pvData = pvData; - - if (request_irq(ui32IRQ, SystemISRWrapper, ulIRQFlags, pszDevName, psLISRData)) - { - OSFreeMem(psLISRData); - - return PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER; - } - - *phLISR = (IMG_HANDLE)psLISRData; - - return PVRSRV_OK; -} - -PVRSRV_ERROR OSUninstallSystemLISR(IMG_HANDLE hLISR) -{ - LISR_DATA *psLISRData = (LISR_DATA *)hLISR; - - if (psLISRData == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - free_irq(psLISRData->ui32IRQ, psLISRData); - - OSFreeMem(psLISRData); - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/interrupt_support.h b/drivers/gpu/drm/img-rogue/1.17/interrupt_support.h deleted file mode 100644 index b87772d223cb0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/interrupt_support.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(INTERRUPT_SUPPORT_H) -#define INTERRUPT_SUPPORT_H - -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_device.h" - -/*! Default trigger type for the interrupt line. */ -#define SYS_IRQ_FLAG_TRIGGER_DEFAULT (0x0 << 0) -/*! Interrupt triggered when interrupt line is low. */ -#define SYS_IRQ_FLAG_TRIGGER_LOW (0x1 << 0) -/*! Interrupt triggered when interrupt line is high. */ -#define SYS_IRQ_FLAG_TRIGGER_HIGH (0x2 << 0) -/*! Interrupt trigger mask. */ -#define SYS_IRQ_FLAG_TRIGGER_MASK (SYS_IRQ_FLAG_TRIGGER_DEFAULT | \ - SYS_IRQ_FLAG_TRIGGER_LOW | \ - SYS_IRQ_FLAG_TRIGGER_HIGH) -/*! The irq is allowed to be shared among several devices. */ -#define SYS_IRQ_FLAG_SHARED (0x1 << 8) - -/*! Interrupt flags mask. */ -#define SYS_IRQ_FLAG_MASK (SYS_IRQ_FLAG_TRIGGER_MASK | \ - SYS_IRQ_FLAG_SHARED) - -/*************************************************************************/ /*! -@Description Pointer to a system Low-level Interrupt Service Routine (LISR). -@Input pvData Private data provided to the LISR. -@Return IMG_TRUE if interrupt handled, IMG_FALSE otherwise. -*/ /**************************************************************************/ -typedef IMG_BOOL (*PFN_SYS_LISR)(void *pvData); - -/*************************************************************************/ /*! -@Function OSInstallSystemLISR -@Description Installs a system low-level interrupt handler -@Output phLISR On return, contains a handle to the - installed LISR -@Input ui32IRQ The IRQ number for which the - interrupt handler should be installed -@Input pszDevName Name of the device for which the handler - is being installed -@Input pfnLISR A pointer to an interrupt handler - function -@Input pvData A pointer to data that should be passed - to pfnLISR when it is called -@Input ui32Flags Interrupt flags -@Return PVRSRV_OK on success, a failure code otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR OSInstallSystemLISR(IMG_HANDLE *phLISR, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszDevName, - PFN_SYS_LISR pfnLISR, - void *pvData, - IMG_UINT32 ui32Flags); - -/*************************************************************************/ /*! -@Function OSUninstallSystemLISR -@Description Uninstalls a system low-level interrupt handler -@Input hLISRData The handle to the LISR to uninstall -@Return PVRSRV_OK on success, a failure code otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR OSUninstallSystemLISR(IMG_HANDLE hLISRData); -#endif /* !defined(INTERRUPT_SUPPORT_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/kernel_compatibility.h b/drivers/gpu/drm/img-rogue/1.17/kernel_compatibility.h deleted file mode 100644 index 6a94c8c12b297..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/kernel_compatibility.h +++ /dev/null @@ -1,521 +0,0 @@ -/*************************************************************************/ /*! -@Title Kernel versions compatibility macros -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Per-version macros to allow code to seamlessly use older kernel -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 __KERNEL_COMPATIBILITY_H__ -#define __KERNEL_COMPATIBILITY_H__ - -#include - -/* - * Stop supporting an old kernel? Remove the top block. - * New incompatible kernel? Append a new block at the bottom. - * - * Please write you version test as `VERSION < X.Y`, and use the earliest - * possible version :) - */ - -/* Linux 3.6 introduced seq_vprintf(). Earlier versions don't have this - * so we work around the limitation by vsnprintf() + seq_puts(). - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) -#define seq_vprintf(seq_file, fmt, args) \ -do { \ - char aszBuffer[512]; /* maximum message buffer size */ \ - vsnprintf(aszBuffer, sizeof(aszBuffer), fmt, args); \ - seq_puts(seq_file, aszBuffer); \ -} while (0) -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) - -/* Linux 3.7 split VM_RESERVED into VM_DONTDUMP and VM_DONTEXPAND */ -#define VM_DONTDUMP VM_RESERVED - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) */ - -/* - * Note: this fix had to be written backwards because get_unused_fd_flags - * was already defined but not exported on kernels < 3.7 - * - * When removing support for kernels < 3.7, this block should be removed - * and all `get_unused_fd()` should be manually replaced with - * `get_unused_fd_flags(0)` - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) - -/* Linux 3.19 removed get_unused_fd() */ -/* get_unused_fd_flags was introduced in 3.7 */ -#define get_unused_fd() get_unused_fd_flags(0) - -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) - -/* - * Headers shouldn't normally be included by this file but this is a special - * case as it's not obvious from the name that devfreq_add_device needs this - * include. - */ -#include - -#define devfreq_add_device(dev, profile, name, data) \ - ({ \ - struct devfreq *__devfreq; \ - if (name && !strcmp(name, "simple_ondemand")) \ - __devfreq = devfreq_add_device(dev, profile, \ - &devfreq_simple_ondemand, data); \ - else \ - __devfreq = ERR_PTR(-EINVAL); \ - __devfreq; \ - }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) - -#define DRIVER_RENDER 0 -#define DRM_RENDER_ALLOW 0 - -/* Linux 3.12 introduced a new shrinker API */ -#define SHRINK_STOP (~0UL) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - -#define dev_pm_opp_get_opp_count(dev) opp_get_opp_count(dev) -#define dev_pm_opp_get_freq(opp) opp_get_freq(opp) -#define dev_pm_opp_get_voltage(opp) opp_get_voltage(opp) -#define dev_pm_opp_add(dev, freq, u_volt) opp_add(dev, freq, u_volt) -#define dev_pm_opp_find_freq_ceil(dev, freq) opp_find_freq_ceil(dev, freq) - -#if defined(CONFIG_ARM) -/* Linux 3.13 renamed ioremap_cached to ioremap_cache */ -#define ioremap_cache(cookie, size) ioremap_cached(cookie, size) -#endif /* defined(CONFIG_ARM) */ - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - -/* Linux 3.14 introduced a new set of sized min and max defines */ -#ifndef U32_MAX -#define U32_MAX ((u32)UINT_MAX) -#endif - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) - -/* Linux 3.17 changed the 3rd argument from a `struct page ***pages` to - * `struct page **pages` */ -#define map_vm_area(area, prot, pages) map_vm_area(area, prot, &pages) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) - -/* - * Linux 4.7 removed this function but its replacement was available since 3.19. - */ -#define drm_crtc_send_vblank_event(crtc, e) drm_send_vblank_event((crtc)->dev, drm_crtc_index(crtc), e) - -/* seq_has_overflowed() was introduced in 3.19 but the structure elements - * have been available since 2.x - */ -#include -static inline bool seq_has_overflowed(struct seq_file *m) -{ - return m->count == m->size; -} - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) - -#define debugfs_create_file_size(name, mode, parent, data, fops, file_size) \ - ({ \ - struct dentry *de; \ - de = debugfs_create_file(name, mode, parent, data, fops); \ - if (de) \ - de->d_inode->i_size = file_size; \ - de; \ - }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) -#define drm_fb_helper_unregister_fbi(fb_helper) \ - ({ \ - if ((fb_helper) && (fb_helper)->fbdev) \ - unregister_framebuffer((fb_helper)->fbdev); \ - }) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) - -/* Linux 4.4 renamed GFP_WAIT to GFP_RECLAIM */ -#define __GFP_RECLAIM __GFP_WAIT - -#if !defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) -#define dev_pm_opp_of_add_table(dev) of_init_opp_table(dev) -#define dev_pm_opp_of_remove_table(dev) of_free_opp_table(dev) -#else -#define sync_fence_create(data_name, sync_pt) sync_fence_create(data_name, &(sync_pt)->base) -#endif - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) && \ - (!defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))) - -/* Linux 4.5 added a new printf-style parameter for debug messages */ - -#define drm_encoder_init(dev, encoder, funcs, encoder_type, name, ...) \ - drm_encoder_init(dev, encoder, funcs, encoder_type) - -#define drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, format_modifiers, type, name, ...) \ - ({ (void) format_modifiers; drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, type); }) - -#define drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, name, ...) \ - drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs) - -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) - -#define drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, format_modifiers, type, name, ...) \ - ({ (void) format_modifiers; drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, type, name, ##__VA_ARGS__); }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) - -/* - * Linux 4.6 removed the first two parameters, the "struct task_struct" type - * pointer "current" is defined in asm/current.h, which makes it pointless - * to pass it on every function call. -*/ -#define get_user_pages(start, nr_pages, gup_flags, pages, vmas) \ - get_user_pages(current, current->mm, start, nr_pages, gup_flags & FOLL_WRITE, gup_flags & FOLL_FORCE, pages, vmas) - -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) - -/* Linux 4.9 replaced the write/force parameters with "gup_flags" */ -#define get_user_pages(start, nr_pages, gup_flags, pages, vmas) \ - get_user_pages(start, nr_pages, gup_flags & FOLL_WRITE, gup_flags & FOLL_FORCE, pages, vmas) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && \ - (!defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))) - -/* - * Linux 4.6 removed the start and end arguments as it now always maps - * the entire DMA-BUF. - * Additionally, dma_buf_end_cpu_access() now returns an int error. - */ -#define dma_buf_begin_cpu_access(DMABUF, DIRECTION) dma_buf_begin_cpu_access(DMABUF, 0, DMABUF->size, DIRECTION) -#define dma_buf_end_cpu_access(DMABUF, DIRECTION) ({ dma_buf_end_cpu_access(DMABUF, 0, DMABUF->size, DIRECTION); 0; }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && \ - (!defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) - -/* Linux 4.7 removed the first arguments as it's never been used */ -#define drm_gem_object_lookup(filp, handle) drm_gem_object_lookup((filp)->minor->dev, filp, handle) - -/* Linux 4.7 replaced nla_put_u64 with nla_put_u64_64bit */ -#define nla_put_u64_64bit(skb, attrtype, value, padattr) nla_put_u64(skb, attrtype, value) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) - -/* Linux 4.9 changed the second argument to a drm_file pointer */ -#define drm_vma_node_is_allowed(node, file_priv) drm_vma_node_is_allowed(node, (file_priv)->filp) -#define drm_vma_node_allow(node, file_priv) drm_vma_node_allow(node, (file_priv)->filp) -#define drm_vma_node_revoke(node, file_priv) drm_vma_node_revoke(node, (file_priv)->filp) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) -#define refcount_read(r) atomic_read(r) -#define drm_mm_insert_node(mm, node, size) drm_mm_insert_node(mm, node, size, 0, DRM_MM_SEARCH_DEFAULT) - -#define drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd) drm_helper_mode_fill_fb_struct(fb, mode_cmd) - -/* - * In Linux Kernels >= 4.12 for x86 another level of page tables has been - * added. The added level (p4d) sits between pgd and pud, so when it - * doesn`t exist, pud_offset function takes pgd as a parameter instead - * of p4d. - */ -#define p4d_t pgd_t -#define p4d_offset(pgd, address) (pgd) -#define p4d_none(p4d) (0) -#define p4d_bad(p4d) (0) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - -#define drm_mode_object_get(obj) drm_mode_object_reference(obj) -#define drm_mode_object_put(obj) drm_mode_object_unreference(obj) -#define drm_connector_get(obj) drm_connector_reference(obj) -#define drm_connector_put(obj) drm_connector_unreference(obj) -#define drm_framebuffer_get(obj) drm_framebuffer_reference(obj) -#define drm_framebuffer_put(obj) drm_framebuffer_unreference(obj) -#define drm_gem_object_get(obj) drm_gem_object_reference(obj) -#define drm_gem_object_put_locked(obj) drm_gem_object_unreference(obj) -#define __drm_gem_object_put(obj) __drm_gem_object_unreference(obj) -#define drm_property_blob_get(obj) drm_property_reference_blob(obj) -#define drm_property_blob_put(obj) drm_property_unreference_blob(obj) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) - -#define drm_dev_put(dev) drm_dev_unref(dev) - -#define drm_mode_object_find(dev, file_priv, id, type) drm_mode_object_find(dev, id, type) -#define drm_encoder_find(dev, file_priv, id) drm_encoder_find(dev, id) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) - -#define drm_atomic_helper_check_plane_state(plane_state, crtc_state, \ - min_scale, max_scale, \ - can_position, can_update_disabled) \ - ({ \ - const struct drm_rect __clip = { \ - .x2 = crtc_state->crtc->mode.hdisplay, \ - .y2 = crtc_state->crtc->mode.vdisplay, \ - }; \ - int __ret = drm_plane_helper_check_state(plane_state, \ - &__clip, \ - min_scale, max_scale, \ - can_position, \ - can_update_disabled); \ - __ret; \ - }) - -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) - -#define drm_atomic_helper_check_plane_state(plane_state, crtc_state, \ - min_scale, max_scale, \ - can_position, can_update_disabled) \ - ({ \ - const struct drm_rect __clip = { \ - .x2 = crtc_state->crtc->mode.hdisplay, \ - .y2 = crtc_state->crtc->mode.vdisplay, \ - }; \ - int __ret = drm_atomic_helper_check_plane_state(plane_state, \ - crtc_state, \ - &__clip, \ - min_scale, max_scale, \ - can_position, \ - can_update_disabled); \ - __ret; \ - }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) - -#define drm_connector_attach_encoder(connector, encoder) \ - drm_mode_connector_attach_encoder(connector, encoder) - -#define drm_connector_update_edid_property(connector, edid) \ - drm_mode_connector_update_edid_property(connector, edid) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) */ - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) - -/* - * Work around architectures, e.g. MIPS, that define copy_from_user and - * copy_to_user as macros that call access_ok, as this gets redefined below. - * As of kernel 4.12, these functions are no longer defined per-architecture - * so this work around isn't needed. - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) -#if defined(copy_from_user) - /* - * NOTE: This function should not be called directly as it exists simply to - * work around copy_from_user being defined as a macro that calls access_ok. - */ -static inline int -__pvr_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - return copy_from_user(to, from, n); -} - -#undef copy_from_user -#define copy_from_user(to, from, n) __copy_from_user(to, from, n) -#endif - -#if defined(copy_to_user) - /* - * NOTE: This function should not be called directly as it exists simply to - * work around copy_to_user being defined as a macro that calls access_ok. - */ -static inline int -__pvr_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - return copy_to_user(to, from, n); -} - -#undef copy_to_user -#define copy_to_user(to, from, n) __copy_to_user(to, from, n) -#endif -#endif - -/* - * Linux 5.0 dropped the type argument. - * - * This is unused in at least Linux 3.4 and above for all architectures other - * than 'um' (User Mode Linux), which stopped using it in 4.2. - */ -#if defined(access_ok) - /* - * NOTE: This function should not be called directly as it exists simply to - * work around access_ok being defined as a macro. - */ -static inline int -__pvr_access_ok_compat(int type, const void __user * addr, unsigned long size) -{ - return access_ok(type, addr, size); -} - -#undef access_ok -#define access_ok(addr, size) __pvr_access_ok_compat(0, addr, size) -#else -#define access_ok(addr, size) access_ok(0, addr, size) -#endif - -#endif - -/* - * Before v5.8, the "struct mm" has a semaphore named "mmap_sem" which is - * renamed to "mmap_lock" in v5.8. Moreover, new APIs are provided to - * access this lock starting from v5.8. - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - -#define mmap_write_lock(mm) down_write(&mm->mmap_sem) -#define mmap_write_unlock(mm) up_write(&mm->mmap_sem) - -#define mmap_read_lock(mm) down_read(&mm->mmap_sem) -#define mmap_read_unlock(mm) up_read(&mm->mmap_sem) - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) -#define drm_gem_object_put(obj) drm_gem_object_unreference_unlocked(obj) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) -#define drm_gem_object_put(obj) drm_gem_object_put_unlocked(obj) -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) - -#define drm_prime_pages_to_sg(dev, pages, nr_pages) \ - drm_prime_pages_to_sg(pages, nr_pages) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) - -struct dma_buf_map { - void *vaddr; -}; - -#define dma_buf_vmap(dmabuf, map) \ - ({ \ - (map)->vaddr = dma_buf_vmap(dmabuf); \ - (map)->vaddr ? 0 : ((dmabuf) && (dmabuf)->ops->vmap) ? -ENOMEM : -EINVAL; \ - }) - -#define dma_buf_vunmap(dmabuf, map) \ - ({ \ - dma_buf_vunmap(dmabuf, (map)->vaddr); \ - (map)->vaddr = NULL; \ - }) - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - -#define drm_prime_sg_to_page_array(sgt, pages, npages) \ - drm_prime_sg_to_page_addr_arrays(sgt, pages, NULL, npages) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) - -#define drm_gem_plane_helper_prepare_fb drm_gem_fb_prepare_fb - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) */ - -/* - * Linux 5.11 renames the privileged uaccess routines for arm64 and Android - * kernel v5.10 merges the change as well. These routines are only used for - * arm64 so CONFIG_ARM64 testing can be ignored. - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) || \ - ((LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) && !defined(ANDROID)) -#define uaccess_enable_privileged() uaccess_enable() -#define uaccess_disable_privileged() uaccess_disable() -#endif - -#endif /* __KERNEL_COMPATIBILITY_H__ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/kernel_config_compatibility.h b/drivers/gpu/drm/img-rogue/1.17/kernel_config_compatibility.h deleted file mode 100644 index 63effd65ecf9f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/kernel_config_compatibility.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ /*! -@Title Kernel config compatibility define options -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This file is exclusively for Linux config kernel options. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 __KERNEL_CONFIG_COMPATIBILITY_H__ -#define __KERNEL_CONFIG_COMPATIBILITY_H__ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)) -#ifdef SUPPORT_DRM_FBDEV_EMULATION -#define CONFIG_DRM_FBDEV_EMULATION -#endif -#endif - -#endif /* __KERNEL_CONFIG_COMPATIBILITY_H__ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/kernel_nospec.h b/drivers/gpu/drm/img-rogue/1.17/kernel_nospec.h deleted file mode 100644 index e27a3ebc2ac6a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/kernel_nospec.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************/ /*! -@Title Macro to limit CPU speculative execution in kernel code -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Per-version macros to allow code to seamlessly use older kernel -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 __KERNEL_NOSPEC_H__ -#define __KERNEL_NOSPEC_H__ - -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 2) || \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18)) || \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 81)) || \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 118))) -#include -#include -#include -#else -#define array_index_nospec(index, size) (index) -#endif - -/* - * For Ubuntu kernels, the features available for a given Linux version code - * may not match those in upstream kernels. This is the case for the - * availability of the array_index_nospec macro. - */ -#if !defined(array_index_nospec) -#define array_index_nospec(index, size) (index) -#endif - -#endif /* __KERNEL_NOSPEC_H__ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/kernel_types.h b/drivers/gpu/drm/img-rogue/1.17/kernel_types.h deleted file mode 100644 index c3305102fc208..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/kernel_types.h +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************/ /*! -@Title C99-compatible types and definitions for Linux kernel code -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -/* Limits of specified-width integer types */ - -/* S8_MIN, etc were added in kernel version 3.14. The other versions are for - * earlier kernels. They can be removed once older kernels don't need to be - * supported. - */ -#ifdef S8_MIN - #define INT8_MIN S8_MIN -#else - #define INT8_MIN (-128) -#endif - -#ifdef S8_MAX - #define INT8_MAX S8_MAX -#else - #define INT8_MAX 127 -#endif - -#ifdef U8_MAX - #define UINT8_MAX U8_MAX -#else - #define UINT8_MAX 0xFF -#endif - -#ifdef S16_MIN - #define INT16_MIN S16_MIN -#else - #define INT16_MIN (-32768) -#endif - -#ifdef S16_MAX - #define INT16_MAX S16_MAX -#else - #define INT16_MAX 32767 -#endif - -#ifdef U16_MAX - #define UINT16_MAX U16_MAX -#else - #define UINT16_MAX 0xFFFF -#endif - -#ifdef S32_MIN - #define INT32_MIN S32_MIN -#else - #define INT32_MIN (-2147483647 - 1) -#endif - -#ifdef S32_MAX - #define INT32_MAX S32_MAX -#else - #define INT32_MAX 2147483647 -#endif - -#ifdef U32_MAX - #define UINT32_MAX U32_MAX -#else - #define UINT32_MAX 0xFFFFFFFF -#endif - -#ifdef S64_MIN - #define INT64_MIN S64_MIN -#else - #define INT64_MIN (-9223372036854775807LL) -#endif - -#ifdef S64_MAX - #define INT64_MAX S64_MAX -#else - #define INT64_MAX 9223372036854775807LL -#endif - -#ifdef U64_MAX - #define UINT64_MAX U64_MAX -#else - #define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL -#endif - -/* Macros for integer constants */ -#define INT8_C S8_C -#define UINT8_C U8_C -#define INT16_C S16_C -#define UINT16_C U16_C -#define INT32_C S32_C -#define UINT32_C U32_C -#define INT64_C S64_C -#define UINT64_C U64_C - -/* Format conversion of integer types */ - -#define PRIX64 "llX" -#define PRIx64 "llx" -#define PRIu64 "llu" -#define PRId64 "lld" diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_defs_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_defs_km.h deleted file mode 100644 index 0aa00beb115c7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_defs_km.h +++ /dev/null @@ -1,377 +0,0 @@ -/*************************************************************************/ /*! -@Title Hardware definition file rgx_bvnc_defs_km.h -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/****************************************************************************** - * Auto generated file by rgxbvnc_tablegen.py * - * This file should not be edited manually * - *****************************************************************************/ - -#ifndef RGX_BVNC_DEFS_KM_H -#define RGX_BVNC_DEFS_KM_H - -#include "img_types.h" -#include "img_defs.h" - -#if defined(RGX_BVNC_DEFS_UM_H) -#error "This file should not be included in conjunction with rgx_bvnc_defs_um.h" -#endif - -#define BVNC_FIELD_WIDTH (16U) - -#define PVR_ARCH_NAME "rogue" - - -/****************************************************************************** - * Mask and bit-position macros for features without values - *****************************************************************************/ - -#define RGX_FEATURE_AXI_ACELITE_POS (0U) -#define RGX_FEATURE_AXI_ACELITE_BIT_MASK (IMG_UINT64_C(0x0000000000000001)) - -#define RGX_FEATURE_CLUSTER_GROUPING_POS (1U) -#define RGX_FEATURE_CLUSTER_GROUPING_BIT_MASK (IMG_UINT64_C(0x0000000000000002)) - -#define RGX_FEATURE_COMPUTE_POS (2U) -#define RGX_FEATURE_COMPUTE_BIT_MASK (IMG_UINT64_C(0x0000000000000004)) - -#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE_POS (3U) -#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE_BIT_MASK (IMG_UINT64_C(0x0000000000000008)) - -#define RGX_FEATURE_COMPUTE_ONLY_POS (4U) -#define RGX_FEATURE_COMPUTE_ONLY_BIT_MASK (IMG_UINT64_C(0x0000000000000010)) - -#define RGX_FEATURE_COMPUTE_OVERLAP_POS (5U) -#define RGX_FEATURE_COMPUTE_OVERLAP_BIT_MASK (IMG_UINT64_C(0x0000000000000020)) - -#define RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS_POS (6U) -#define RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS_BIT_MASK (IMG_UINT64_C(0x0000000000000040)) - -#define RGX_FEATURE_COREID_PER_OS_POS (7U) -#define RGX_FEATURE_COREID_PER_OS_BIT_MASK (IMG_UINT64_C(0x0000000000000080)) - -#define RGX_FEATURE_DUST_POWER_ISLAND_S7_POS (8U) -#define RGX_FEATURE_DUST_POWER_ISLAND_S7_BIT_MASK (IMG_UINT64_C(0x0000000000000100)) - -#define RGX_FEATURE_DYNAMIC_DUST_POWER_POS (9U) -#define RGX_FEATURE_DYNAMIC_DUST_POWER_BIT_MASK (IMG_UINT64_C(0x0000000000000200)) - -#define RGX_FEATURE_FASTRENDER_DM_POS (10U) -#define RGX_FEATURE_FASTRENDER_DM_BIT_MASK (IMG_UINT64_C(0x0000000000000400)) - -#define RGX_FEATURE_GPU_MULTICORE_SUPPORT_POS (11U) -#define RGX_FEATURE_GPU_MULTICORE_SUPPORT_BIT_MASK (IMG_UINT64_C(0x0000000000000800)) - -#define RGX_FEATURE_GPU_VIRTUALISATION_POS (12U) -#define RGX_FEATURE_GPU_VIRTUALISATION_BIT_MASK (IMG_UINT64_C(0x0000000000001000)) - -#define RGX_FEATURE_GS_RTA_SUPPORT_POS (13U) -#define RGX_FEATURE_GS_RTA_SUPPORT_BIT_MASK (IMG_UINT64_C(0x0000000000002000)) - -#define RGX_FEATURE_IRQ_PER_OS_POS (14U) -#define RGX_FEATURE_IRQ_PER_OS_BIT_MASK (IMG_UINT64_C(0x0000000000004000)) - -#define RGX_FEATURE_META_DMA_POS (15U) -#define RGX_FEATURE_META_DMA_BIT_MASK (IMG_UINT64_C(0x0000000000008000)) - -#define RGX_FEATURE_MIPS_POS (16U) -#define RGX_FEATURE_MIPS_BIT_MASK (IMG_UINT64_C(0x0000000000010000)) - -#define RGX_FEATURE_PBE2_IN_XE_POS (17U) -#define RGX_FEATURE_PBE2_IN_XE_BIT_MASK (IMG_UINT64_C(0x0000000000020000)) - -#define RGX_FEATURE_PBE_CHECKSUM_2D_POS (18U) -#define RGX_FEATURE_PBE_CHECKSUM_2D_BIT_MASK (IMG_UINT64_C(0x0000000000040000)) - -#define RGX_FEATURE_PBVNC_COREID_REG_POS (19U) -#define RGX_FEATURE_PBVNC_COREID_REG_BIT_MASK (IMG_UINT64_C(0x0000000000080000)) - -#define RGX_FEATURE_PDS_PER_DUST_POS (20U) -#define RGX_FEATURE_PDS_PER_DUST_BIT_MASK (IMG_UINT64_C(0x0000000000100000)) - -#define RGX_FEATURE_PDS_TEMPSIZE8_POS (21U) -#define RGX_FEATURE_PDS_TEMPSIZE8_BIT_MASK (IMG_UINT64_C(0x0000000000200000)) - -#define RGX_FEATURE_PERFBUS_POS (22U) -#define RGX_FEATURE_PERFBUS_BIT_MASK (IMG_UINT64_C(0x0000000000400000)) - -#define RGX_FEATURE_PERF_COUNTER_BATCH_POS (23U) -#define RGX_FEATURE_PERF_COUNTER_BATCH_BIT_MASK (IMG_UINT64_C(0x0000000000800000)) - -#define RGX_FEATURE_PM_MMU_VFP_POS (24U) -#define RGX_FEATURE_PM_MMU_VFP_BIT_MASK (IMG_UINT64_C(0x0000000001000000)) - -#define RGX_FEATURE_RISCV_FW_PROCESSOR_POS (25U) -#define RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK (IMG_UINT64_C(0x0000000002000000)) - -#define RGX_FEATURE_ROGUEXE_POS (26U) -#define RGX_FEATURE_ROGUEXE_BIT_MASK (IMG_UINT64_C(0x0000000004000000)) - -#define RGX_FEATURE_S7_CACHE_HIERARCHY_POS (27U) -#define RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK (IMG_UINT64_C(0x0000000008000000)) - -#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE_POS (28U) -#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK (IMG_UINT64_C(0x0000000010000000)) - -#define RGX_FEATURE_SCALABLE_VDM_GPP_POS (29U) -#define RGX_FEATURE_SCALABLE_VDM_GPP_BIT_MASK (IMG_UINT64_C(0x0000000020000000)) - -#define RGX_FEATURE_SIGNAL_SNOOPING_POS (30U) -#define RGX_FEATURE_SIGNAL_SNOOPING_BIT_MASK (IMG_UINT64_C(0x0000000040000000)) - -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_POS (31U) -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_BIT_MASK (IMG_UINT64_C(0x0000000080000000)) - -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_V1_POS (32U) -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_V1_BIT_MASK (IMG_UINT64_C(0x0000000100000000)) - -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_V2_POS (33U) -#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_V2_BIT_MASK (IMG_UINT64_C(0x0000000200000000)) - -#define RGX_FEATURE_SINGLE_BIF_POS (34U) -#define RGX_FEATURE_SINGLE_BIF_BIT_MASK (IMG_UINT64_C(0x0000000400000000)) - -#define RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128_POS (35U) -#define RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128_BIT_MASK (IMG_UINT64_C(0x0000000800000000)) - -#define RGX_FEATURE_SLC_SIZE_CONFIGURABLE_POS (36U) -#define RGX_FEATURE_SLC_SIZE_CONFIGURABLE_BIT_MASK (IMG_UINT64_C(0x0000001000000000)) - -#define RGX_FEATURE_SLC_VIVT_POS (37U) -#define RGX_FEATURE_SLC_VIVT_BIT_MASK (IMG_UINT64_C(0x0000002000000000)) - -#define RGX_FEATURE_SOC_TIMER_POS (38U) -#define RGX_FEATURE_SOC_TIMER_BIT_MASK (IMG_UINT64_C(0x0000004000000000)) - -#define RGX_FEATURE_SYS_BUS_SECURE_RESET_POS (39U) -#define RGX_FEATURE_SYS_BUS_SECURE_RESET_BIT_MASK (IMG_UINT64_C(0x0000008000000000)) - -#define RGX_FEATURE_TDM_PDS_CHECKSUM_POS (40U) -#define RGX_FEATURE_TDM_PDS_CHECKSUM_BIT_MASK (IMG_UINT64_C(0x0000010000000000)) - -#define RGX_FEATURE_TESSELLATION_POS (41U) -#define RGX_FEATURE_TESSELLATION_BIT_MASK (IMG_UINT64_C(0x0000020000000000)) - -#define RGX_FEATURE_TFBC_DELTA_CORRELATION_POS (42U) -#define RGX_FEATURE_TFBC_DELTA_CORRELATION_BIT_MASK (IMG_UINT64_C(0x0000040000000000)) - -#define RGX_FEATURE_TFBC_LOSSY_37_PERCENT_POS (43U) -#define RGX_FEATURE_TFBC_LOSSY_37_PERCENT_BIT_MASK (IMG_UINT64_C(0x0000080000000000)) - -#define RGX_FEATURE_TFBC_NATIVE_YUV10_POS (44U) -#define RGX_FEATURE_TFBC_NATIVE_YUV10_BIT_MASK (IMG_UINT64_C(0x0000100000000000)) - -#define RGX_FEATURE_TILE_REGION_PROTECTION_POS (45U) -#define RGX_FEATURE_TILE_REGION_PROTECTION_BIT_MASK (IMG_UINT64_C(0x0000200000000000)) - -#define RGX_FEATURE_TLA_POS (46U) -#define RGX_FEATURE_TLA_BIT_MASK (IMG_UINT64_C(0x0000400000000000)) - -#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS_POS (47U) -#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS_BIT_MASK (IMG_UINT64_C(0x0000800000000000)) - -#define RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS_POS (48U) -#define RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS_BIT_MASK (IMG_UINT64_C(0x0001000000000000)) - -#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL_POS (49U) -#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL_BIT_MASK (IMG_UINT64_C(0x0002000000000000)) - -#define RGX_FEATURE_VDM_DRAWINDIRECT_POS (50U) -#define RGX_FEATURE_VDM_DRAWINDIRECT_BIT_MASK (IMG_UINT64_C(0x0004000000000000)) - -#define RGX_FEATURE_VDM_OBJECT_LEVEL_LLS_POS (51U) -#define RGX_FEATURE_VDM_OBJECT_LEVEL_LLS_BIT_MASK (IMG_UINT64_C(0x0008000000000000)) - -#define RGX_FEATURE_WATCHDOG_TIMER_POS (52U) -#define RGX_FEATURE_WATCHDOG_TIMER_BIT_MASK (IMG_UINT64_C(0x0010000000000000)) - -#define RGX_FEATURE_WORKGROUP_PROTECTION_POS (53U) -#define RGX_FEATURE_WORKGROUP_PROTECTION_BIT_MASK (IMG_UINT64_C(0x0020000000000000)) - -#define RGX_FEATURE_XE_MEMORY_HIERARCHY_POS (54U) -#define RGX_FEATURE_XE_MEMORY_HIERARCHY_BIT_MASK (IMG_UINT64_C(0x0040000000000000)) - -#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE_POS (55U) -#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE_BIT_MASK (IMG_UINT64_C(0x0080000000000000)) - - -/****************************************************************************** - * Defines for each feature with values used - * for handling the corresponding values - *****************************************************************************/ - -#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_MAX_VALUE_IDX (2) -#define RGX_FEATURE_ECC_RAMS_MAX_VALUE_IDX (2) -#define RGX_FEATURE_FBCDC_MAX_VALUE_IDX (4) -#define RGX_FEATURE_FBCDC_ALGORITHM_MAX_VALUE_IDX (6) -#define RGX_FEATURE_FBCDC_ARCHITECTURE_MAX_VALUE_IDX (4) -#define RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_MAX_VALUE_IDX (2) -#define RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_MAX_VALUE_IDX (2) -#define RGX_FEATURE_LAYOUT_MARS_MAX_VALUE_IDX (3) -#define RGX_FEATURE_META_MAX_VALUE_IDX (4) -#define RGX_FEATURE_META_COREMEM_BANKS_MAX_VALUE_IDX (1) -#define RGX_FEATURE_META_COREMEM_SIZE_MAX_VALUE_IDX (3) -#define RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX (1) -#define RGX_FEATURE_NUM_CLUSTERS_MAX_VALUE_IDX (5) -#define RGX_FEATURE_NUM_ISP_IPP_PIPES_MAX_VALUE_IDX (9) -#define RGX_FEATURE_NUM_OSIDS_MAX_VALUE_IDX (3) -#define RGX_FEATURE_NUM_RASTER_PIPES_MAX_VALUE_IDX (3) -#define RGX_FEATURE_PHYS_BUS_WIDTH_MAX_VALUE_IDX (4) -#define RGX_FEATURE_SCALABLE_TE_ARCH_MAX_VALUE_IDX (1) -#define RGX_FEATURE_SCALABLE_VCE_MAX_VALUE_IDX (1) -#define RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_MAX_VALUE_IDX (3) -#define RGX_FEATURE_SLC_BANKS_MAX_VALUE_IDX (4) -#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_MAX_VALUE_IDX (2) -#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_MAX_VALUE_IDX (6) -#define RGX_FEATURE_TILE_SIZE_X_MAX_VALUE_IDX (3) -#define RGX_FEATURE_TILE_SIZE_Y_MAX_VALUE_IDX (3) -#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_MAX_VALUE_IDX (2) -#define RGX_FEATURE_XE_ARCHITECTURE_MAX_VALUE_IDX (2) -#define RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_MAX_VALUE_IDX (2) -#define RGX_FEATURE_XPU_MAX_SLAVES_MAX_VALUE_IDX (2) -#define RGX_FEATURE_XPU_REGISTER_BROADCAST_MAX_VALUE_IDX (2) - -/****************************************************************************** - * Features with values indexes - *****************************************************************************/ - -typedef enum _RGX_FEATURE_WITH_VALUE_INDEX_ { - RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_IDX, - RGX_FEATURE_ECC_RAMS_IDX, - RGX_FEATURE_FBCDC_IDX, - RGX_FEATURE_FBCDC_ALGORITHM_IDX, - RGX_FEATURE_FBCDC_ARCHITECTURE_IDX, - RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_IDX, - RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_IDX, - RGX_FEATURE_LAYOUT_MARS_IDX, - RGX_FEATURE_META_IDX, - RGX_FEATURE_META_COREMEM_BANKS_IDX, - RGX_FEATURE_META_COREMEM_SIZE_IDX, - RGX_FEATURE_META_DMA_CHANNEL_COUNT_IDX, - RGX_FEATURE_NUM_CLUSTERS_IDX, - RGX_FEATURE_NUM_ISP_IPP_PIPES_IDX, - RGX_FEATURE_NUM_OSIDS_IDX, - RGX_FEATURE_NUM_RASTER_PIPES_IDX, - RGX_FEATURE_PHYS_BUS_WIDTH_IDX, - RGX_FEATURE_SCALABLE_TE_ARCH_IDX, - RGX_FEATURE_SCALABLE_VCE_IDX, - RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_IDX, - RGX_FEATURE_SLC_BANKS_IDX, - RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_IDX, - RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_IDX, - RGX_FEATURE_TILE_SIZE_X_IDX, - RGX_FEATURE_TILE_SIZE_Y_IDX, - RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_IDX, - RGX_FEATURE_XE_ARCHITECTURE_IDX, - RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_IDX, - RGX_FEATURE_XPU_MAX_SLAVES_IDX, - RGX_FEATURE_XPU_REGISTER_BROADCAST_IDX, - RGX_FEATURE_WITH_VALUES_MAX_IDX, -} RGX_FEATURE_WITH_VALUE_INDEX; - - -/****************************************************************************** - * Mask and bit-position macros for ERNs and BRNs - *****************************************************************************/ - -#define FIX_HW_BRN_38344_POS (0U) -#define FIX_HW_BRN_38344_BIT_MASK (IMG_UINT64_C(0x0000000000000001)) - -#define HW_ERN_42290_POS (1U) -#define HW_ERN_42290_BIT_MASK (IMG_UINT64_C(0x0000000000000002)) - -#define FIX_HW_BRN_42321_POS (2U) -#define FIX_HW_BRN_42321_BIT_MASK (IMG_UINT64_C(0x0000000000000004)) - -#define HW_ERN_42606_POS (3U) -#define HW_ERN_42606_BIT_MASK (IMG_UINT64_C(0x0000000000000008)) - -#define HW_ERN_46066_POS (4U) -#define HW_ERN_46066_BIT_MASK (IMG_UINT64_C(0x0000000000000010)) - -#define HW_ERN_47025_POS (5U) -#define HW_ERN_47025_BIT_MASK (IMG_UINT64_C(0x0000000000000020)) - -#define HW_ERN_50539_POS (6U) -#define HW_ERN_50539_BIT_MASK (IMG_UINT64_C(0x0000000000000040)) - -#define FIX_HW_BRN_50767_POS (7U) -#define FIX_HW_BRN_50767_BIT_MASK (IMG_UINT64_C(0x0000000000000080)) - -#define HW_ERN_57596_POS (8U) -#define HW_ERN_57596_BIT_MASK (IMG_UINT64_C(0x0000000000000100)) - -#define FIX_HW_BRN_60084_POS (9U) -#define FIX_HW_BRN_60084_BIT_MASK (IMG_UINT64_C(0x0000000000000200)) - -#define HW_ERN_61389_POS (10U) -#define HW_ERN_61389_BIT_MASK (IMG_UINT64_C(0x0000000000000400)) - -#define FIX_HW_BRN_61450_POS (11U) -#define FIX_HW_BRN_61450_BIT_MASK (IMG_UINT64_C(0x0000000000000800)) - -#define FIX_HW_BRN_63142_POS (12U) -#define FIX_HW_BRN_63142_BIT_MASK (IMG_UINT64_C(0x0000000000001000)) - -#define FIX_HW_BRN_63553_POS (13U) -#define FIX_HW_BRN_63553_BIT_MASK (IMG_UINT64_C(0x0000000000002000)) - -#define FIX_HW_BRN_64502_POS (14U) -#define FIX_HW_BRN_64502_BIT_MASK (IMG_UINT64_C(0x0000000000004000)) - -#define FIX_HW_BRN_65101_POS (15U) -#define FIX_HW_BRN_65101_BIT_MASK (IMG_UINT64_C(0x0000000000008000)) - -#define FIX_HW_BRN_65273_POS (16U) -#define FIX_HW_BRN_65273_BIT_MASK (IMG_UINT64_C(0x0000000000010000)) - -#define HW_ERN_66622_POS (17U) -#define HW_ERN_66622_BIT_MASK (IMG_UINT64_C(0x0000000000020000)) - -#define FIX_HW_BRN_68186_POS (18U) -#define FIX_HW_BRN_68186_BIT_MASK (IMG_UINT64_C(0x0000000000040000)) - -/* Macro used for padding the unavailable values for features with values */ -#define RGX_FEATURE_VALUE_INVALID (0xFFFFFFFEU) - -/* Macro used for marking a feature with value as disabled for a specific bvnc */ -#define RGX_FEATURE_VALUE_DISABLED (0xFFFFFFFFU) - -#endif /* RGX_BVNC_DEFS_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_table_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_table_km.h deleted file mode 100644 index d761ad0f2cce2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgx_bvnc_table_km.h +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************/ /*! -@Title Hardware definition file rgx_bvnc_table_km.h -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/****************************************************************************** - * Auto generated file by rgxbvnc_tablegen.py * - * This file should not be edited manually * - *****************************************************************************/ - -#ifndef RGX_BVNC_TABLE_KM_H -#define RGX_BVNC_TABLE_KM_H - -#include "img_types.h" -#include "img_defs.h" -#include "rgxdefs_km.h" -#include "rgx_bvnc_defs_km.h" - -#ifndef RGXBVNC_C -#error "This file should only be included from rgxbvnc.c" -#endif - -#if defined(RGX_BVNC_TABLE_UM_H) -#error "This file should not be included in conjunction with rgx_bvnc_table_um.h" -#endif - - -/****************************************************************************** - * Arrays for each feature with values used - * for handling the corresponding values - *****************************************************************************/ - -static const IMG_UINT16 aui16_RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_values[RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_ECC_RAMS_values[RGX_FEATURE_ECC_RAMS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 2, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_FBCDC_values[RGX_FEATURE_FBCDC_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 3, 4, 50, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_FBCDC_ALGORITHM_values[RGX_FEATURE_FBCDC_ALGORITHM_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, 3, 4, 50, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_FBCDC_ARCHITECTURE_values[RGX_FEATURE_FBCDC_ARCHITECTURE_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, 7, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_values[RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 0, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_values[RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 0, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_LAYOUT_MARS_values[RGX_FEATURE_LAYOUT_MARS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 0, 1, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_META_values[RGX_FEATURE_META_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, LTP217, LTP218, MTP218, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_META_COREMEM_BANKS_values[RGX_FEATURE_META_COREMEM_BANKS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_META_COREMEM_SIZE_values[RGX_FEATURE_META_COREMEM_SIZE_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 0, 32, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_META_DMA_CHANNEL_COUNT_values[RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_NUM_CLUSTERS_values[RGX_FEATURE_NUM_CLUSTERS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, 4, 6, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_NUM_ISP_IPP_PIPES_values[RGX_FEATURE_NUM_ISP_IPP_PIPES_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, 3, 4, 6, 7, 8, 12, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_NUM_OSIDS_values[RGX_FEATURE_NUM_OSIDS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 2, 8, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_NUM_RASTER_PIPES_values[RGX_FEATURE_NUM_RASTER_PIPES_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_PHYS_BUS_WIDTH_values[RGX_FEATURE_PHYS_BUS_WIDTH_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 32, 36, 40, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SCALABLE_TE_ARCH_values[RGX_FEATURE_SCALABLE_TE_ARCH_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SCALABLE_VCE_values[RGX_FEATURE_SCALABLE_VCE_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_values[RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SLC_BANKS_values[RGX_FEATURE_SLC_BANKS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, 2, 4, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_values[RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 512, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_values[RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 2, 8, 16, 64, 128, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_TILE_SIZE_X_values[RGX_FEATURE_TILE_SIZE_X_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 16, 32, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_TILE_SIZE_Y_values[RGX_FEATURE_TILE_SIZE_Y_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 16, 32, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_values[RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 40, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_XE_ARCHITECTURE_values[RGX_FEATURE_XE_ARCHITECTURE_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_values[RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 19, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_XPU_MAX_SLAVES_values[RGX_FEATURE_XPU_MAX_SLAVES_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 3, }; - -static const IMG_UINT16 aui16_RGX_FEATURE_XPU_REGISTER_BROADCAST_values[RGX_FEATURE_XPU_REGISTER_BROADCAST_MAX_VALUE_IDX] = {(IMG_UINT16)RGX_FEATURE_VALUE_DISABLED, 1, }; - - -/****************************************************************************** - * Table contains pointers to each feature value array for features that have - * values. - * Indexed using enum RGX_FEATURE_WITH_VALUE_INDEX from rgx_bvnc_defs_km.h - *****************************************************************************/ - -static const IMG_UINT16 * const gaFeaturesValues[RGX_FEATURE_WITH_VALUES_MAX_IDX] = { - aui16_RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_values, - aui16_RGX_FEATURE_ECC_RAMS_values, - aui16_RGX_FEATURE_FBCDC_values, - aui16_RGX_FEATURE_FBCDC_ALGORITHM_values, - aui16_RGX_FEATURE_FBCDC_ARCHITECTURE_values, - aui16_RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_values, - aui16_RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_values, - aui16_RGX_FEATURE_LAYOUT_MARS_values, - aui16_RGX_FEATURE_META_values, - aui16_RGX_FEATURE_META_COREMEM_BANKS_values, - aui16_RGX_FEATURE_META_COREMEM_SIZE_values, - aui16_RGX_FEATURE_META_DMA_CHANNEL_COUNT_values, - aui16_RGX_FEATURE_NUM_CLUSTERS_values, - aui16_RGX_FEATURE_NUM_ISP_IPP_PIPES_values, - aui16_RGX_FEATURE_NUM_OSIDS_values, - aui16_RGX_FEATURE_NUM_RASTER_PIPES_values, - aui16_RGX_FEATURE_PHYS_BUS_WIDTH_values, - aui16_RGX_FEATURE_SCALABLE_TE_ARCH_values, - aui16_RGX_FEATURE_SCALABLE_VCE_values, - aui16_RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_values, - aui16_RGX_FEATURE_SLC_BANKS_values, - aui16_RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_values, - aui16_RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_values, - aui16_RGX_FEATURE_TILE_SIZE_X_values, - aui16_RGX_FEATURE_TILE_SIZE_Y_values, - aui16_RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_values, - aui16_RGX_FEATURE_XE_ARCHITECTURE_values, - aui16_RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_values, - aui16_RGX_FEATURE_XPU_MAX_SLAVES_values, - aui16_RGX_FEATURE_XPU_REGISTER_BROADCAST_values, -}; - - -/****************************************************************************** - * Array containing the lengths of the arrays containing the values. - * Used for indexing the aui16__values defined upwards - *****************************************************************************/ - - -static const IMG_UINT16 gaFeaturesValuesMaxIndexes[] = { - RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_MAX_VALUE_IDX, - RGX_FEATURE_ECC_RAMS_MAX_VALUE_IDX, - RGX_FEATURE_FBCDC_MAX_VALUE_IDX, - RGX_FEATURE_FBCDC_ALGORITHM_MAX_VALUE_IDX, - RGX_FEATURE_FBCDC_ARCHITECTURE_MAX_VALUE_IDX, - RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_MAX_VALUE_IDX, - RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_MAX_VALUE_IDX, - RGX_FEATURE_LAYOUT_MARS_MAX_VALUE_IDX, - RGX_FEATURE_META_MAX_VALUE_IDX, - RGX_FEATURE_META_COREMEM_BANKS_MAX_VALUE_IDX, - RGX_FEATURE_META_COREMEM_SIZE_MAX_VALUE_IDX, - RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX, - RGX_FEATURE_NUM_CLUSTERS_MAX_VALUE_IDX, - RGX_FEATURE_NUM_ISP_IPP_PIPES_MAX_VALUE_IDX, - RGX_FEATURE_NUM_OSIDS_MAX_VALUE_IDX, - RGX_FEATURE_NUM_RASTER_PIPES_MAX_VALUE_IDX, - RGX_FEATURE_PHYS_BUS_WIDTH_MAX_VALUE_IDX, - RGX_FEATURE_SCALABLE_TE_ARCH_MAX_VALUE_IDX, - RGX_FEATURE_SCALABLE_VCE_MAX_VALUE_IDX, - RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_MAX_VALUE_IDX, - RGX_FEATURE_SLC_BANKS_MAX_VALUE_IDX, - RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_MAX_VALUE_IDX, - RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_MAX_VALUE_IDX, - RGX_FEATURE_TILE_SIZE_X_MAX_VALUE_IDX, - RGX_FEATURE_TILE_SIZE_Y_MAX_VALUE_IDX, - RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_MAX_VALUE_IDX, - RGX_FEATURE_XE_ARCHITECTURE_MAX_VALUE_IDX, - RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_MAX_VALUE_IDX, - RGX_FEATURE_XPU_MAX_SLAVES_MAX_VALUE_IDX, - RGX_FEATURE_XPU_REGISTER_BROADCAST_MAX_VALUE_IDX, -}; - - -/****************************************************************************** - * Bit-positions for features with values - *****************************************************************************/ - -static const IMG_UINT16 aui16FeaturesWithValuesBitPositions[] = { - (0U), /* RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_POS */ - (2U), /* RGX_FEATURE_ECC_RAMS_POS */ - (4U), /* RGX_FEATURE_FBCDC_POS */ - (7U), /* RGX_FEATURE_FBCDC_ALGORITHM_POS */ - (10U), /* RGX_FEATURE_FBCDC_ARCHITECTURE_POS */ - (13U), /* RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_POS */ - (15U), /* RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_POS */ - (17U), /* RGX_FEATURE_LAYOUT_MARS_POS */ - (19U), /* RGX_FEATURE_META_POS */ - (22U), /* RGX_FEATURE_META_COREMEM_BANKS_POS */ - (23U), /* RGX_FEATURE_META_COREMEM_SIZE_POS */ - (25U), /* RGX_FEATURE_META_DMA_CHANNEL_COUNT_POS */ - (26U), /* RGX_FEATURE_NUM_CLUSTERS_POS */ - (29U), /* RGX_FEATURE_NUM_ISP_IPP_PIPES_POS */ - (33U), /* RGX_FEATURE_NUM_OSIDS_POS */ - (35U), /* RGX_FEATURE_NUM_RASTER_PIPES_POS */ - (37U), /* RGX_FEATURE_PHYS_BUS_WIDTH_POS */ - (40U), /* RGX_FEATURE_SCALABLE_TE_ARCH_POS */ - (41U), /* RGX_FEATURE_SCALABLE_VCE_POS */ - (42U), /* RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_POS */ - (44U), /* RGX_FEATURE_SLC_BANKS_POS */ - (47U), /* RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_POS */ - (49U), /* RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_POS */ - (52U), /* RGX_FEATURE_TILE_SIZE_X_POS */ - (54U), /* RGX_FEATURE_TILE_SIZE_Y_POS */ - (56U), /* RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_POS */ - (58U), /* RGX_FEATURE_XE_ARCHITECTURE_POS */ - (60U), /* RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_POS */ - (62U), /* RGX_FEATURE_XPU_MAX_SLAVES_POS */ - (64U), /* RGX_FEATURE_XPU_REGISTER_BROADCAST_POS */ -}; - - -/****************************************************************************** - * Bit-masks for features with values - *****************************************************************************/ - -static const IMG_UINT64 aui64FeaturesWithValuesBitMasks[] = { - (IMG_UINT64_C(0x0000000000000003)), /* RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_BIT_MASK */ - (IMG_UINT64_C(0x000000000000000C)), /* RGX_FEATURE_ECC_RAMS_BIT_MASK */ - (IMG_UINT64_C(0x0000000000000070)), /* RGX_FEATURE_FBCDC_BIT_MASK */ - (IMG_UINT64_C(0x0000000000000380)), /* RGX_FEATURE_FBCDC_ALGORITHM_BIT_MASK */ - (IMG_UINT64_C(0x0000000000001C00)), /* RGX_FEATURE_FBCDC_ARCHITECTURE_BIT_MASK */ - (IMG_UINT64_C(0x0000000000006000)), /* RGX_FEATURE_FBC_MAX_DEFAULT_DESCRIPTORS_BIT_MASK */ - (IMG_UINT64_C(0x0000000000018000)), /* RGX_FEATURE_FBC_MAX_LARGE_DESCRIPTORS_BIT_MASK */ - (IMG_UINT64_C(0x0000000000060000)), /* RGX_FEATURE_LAYOUT_MARS_BIT_MASK */ - (IMG_UINT64_C(0x0000000000380000)), /* RGX_FEATURE_META_BIT_MASK */ - (IMG_UINT64_C(0x0000000000400000)), /* RGX_FEATURE_META_COREMEM_BANKS_BIT_MASK */ - (IMG_UINT64_C(0x0000000001800000)), /* RGX_FEATURE_META_COREMEM_SIZE_BIT_MASK */ - (IMG_UINT64_C(0x0000000002000000)), /* RGX_FEATURE_META_DMA_CHANNEL_COUNT_BIT_MASK */ - (IMG_UINT64_C(0x000000001C000000)), /* RGX_FEATURE_NUM_CLUSTERS_BIT_MASK */ - (IMG_UINT64_C(0x00000001E0000000)), /* RGX_FEATURE_NUM_ISP_IPP_PIPES_BIT_MASK */ - (IMG_UINT64_C(0x0000000600000000)), /* RGX_FEATURE_NUM_OSIDS_BIT_MASK */ - (IMG_UINT64_C(0x0000001800000000)), /* RGX_FEATURE_NUM_RASTER_PIPES_BIT_MASK */ - (IMG_UINT64_C(0x000000E000000000)), /* RGX_FEATURE_PHYS_BUS_WIDTH_BIT_MASK */ - (IMG_UINT64_C(0x0000010000000000)), /* RGX_FEATURE_SCALABLE_TE_ARCH_BIT_MASK */ - (IMG_UINT64_C(0x0000020000000000)), /* RGX_FEATURE_SCALABLE_VCE_BIT_MASK */ - (IMG_UINT64_C(0x00000C0000000000)), /* RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION_BIT_MASK */ - (IMG_UINT64_C(0x0000700000000000)), /* RGX_FEATURE_SLC_BANKS_BIT_MASK */ - (IMG_UINT64_C(0x0001800000000000)), /* RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_BIT_MASK */ - (IMG_UINT64_C(0x000E000000000000)), /* RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_BIT_MASK */ - (IMG_UINT64_C(0x0030000000000000)), /* RGX_FEATURE_TILE_SIZE_X_BIT_MASK */ - (IMG_UINT64_C(0x00C0000000000000)), /* RGX_FEATURE_TILE_SIZE_Y_BIT_MASK */ - (IMG_UINT64_C(0x0300000000000000)), /* RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_BIT_MASK */ - (IMG_UINT64_C(0x0C00000000000000)), /* RGX_FEATURE_XE_ARCHITECTURE_BIT_MASK */ - (IMG_UINT64_C(0x3000000000000000)), /* RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH_BIT_MASK */ - (IMG_UINT64_C(0xC000000000000000)), /* RGX_FEATURE_XPU_MAX_SLAVES_BIT_MASK */ - (IMG_UINT64_C(0x0000000000000003)), /* RGX_FEATURE_XPU_REGISTER_BROADCAST_BIT_MASK */ -}; - - -/****************************************************************************** - * Table mapping bitmasks for features and features with values - *****************************************************************************/ - - -static const IMG_UINT64 gaFeatures[][4]= -{ - { IMG_UINT64_C(0x0004000000020033), IMG_UINT64_C(0x0082c04000c0222f), IMG_UINT64_C(0x01aa8068e912a901), IMG_UINT64_C(0x0000000000000000) }, /* 4.0.2.51 */ -}; - -/****************************************************************************** - * Table mapping bitmasks for ERNs/BRNs - *****************************************************************************/ - - -static const IMG_UINT64 gaErnsBrns[][2]= -{ - { IMG_UINT64_C(0x0004002800020033), IMG_UINT64_C(0x000000000000108a) }, /* 4.40.2.51 */ -}; - -#if defined(DEBUG) - -#define FEATURE_NO_VALUES_NAMES_MAX_IDX (56) - -static const IMG_CHAR * const gaszFeaturesNoValuesNames[FEATURE_NO_VALUES_NAMES_MAX_IDX] = -{ - "AXI_ACELITE", - "CLUSTER_GROUPING", - "COMPUTE", - "COMPUTE_MORTON_CAPABLE", - "COMPUTE_ONLY", - "COMPUTE_OVERLAP", - "COMPUTE_OVERLAP_WITH_BARRIERS", - "COREID_PER_OS", - "DUST_POWER_ISLAND_S7", - "DYNAMIC_DUST_POWER", - "FASTRENDER_DM", - "GPU_MULTICORE_SUPPORT", - "GPU_VIRTUALISATION", - "GS_RTA_SUPPORT", - "IRQ_PER_OS", - "META_DMA", - "MIPS", - "PBE2_IN_XE", - "PBE_CHECKSUM_2D", - "PBVNC_COREID_REG", - "PDS_PER_DUST", - "PDS_TEMPSIZE8", - "PERFBUS", - "PERF_COUNTER_BATCH", - "PM_MMU_VFP", - "RISCV_FW_PROCESSOR", - "ROGUEXE", - "S7_CACHE_HIERARCHY", - "S7_TOP_INFRASTRUCTURE", - "SCALABLE_VDM_GPP", - "SIGNAL_SNOOPING", - "SIMPLE_INTERNAL_PARAMETER_FORMAT", - "SIMPLE_INTERNAL_PARAMETER_FORMAT_V1", - "SIMPLE_INTERNAL_PARAMETER_FORMAT_V2", - "SINGLE_BIF", - "SLC_HYBRID_CACHELINE_64_128", - "SLC_SIZE_CONFIGURABLE", - "SLC_VIVT", - "SOC_TIMER", - "SYS_BUS_SECURE_RESET", - "TDM_PDS_CHECKSUM", - "TESSELLATION", - "TFBC_DELTA_CORRELATION", - "TFBC_LOSSY_37_PERCENT", - "TFBC_NATIVE_YUV10", - "TILE_REGION_PROTECTION", - "TLA", - "TPU_CEM_DATAMASTER_GLOBAL_REGISTERS", - "TPU_DM_GLOBAL_REGISTERS", - "TPU_FILTERING_MODE_CONTROL", - "VDM_DRAWINDIRECT", - "VDM_OBJECT_LEVEL_LLS", - "WATCHDOG_TIMER", - "WORKGROUP_PROTECTION", - "XE_MEMORY_HIERARCHY", - "XT_TOP_INFRASTRUCTURE", -}; - -#define ERNSBRNS_IDS_MAX_IDX (19) - -static const IMG_UINT32 gaui64ErnsBrnsIDs[ERNSBRNS_IDS_MAX_IDX] = -{ - 38344, - 42290, - 42321, - 42606, - 46066, - 47025, - 50539, - 50767, - 57596, - 60084, - 61389, - 61450, - 63142, - 63553, - 64502, - 65101, - 65273, - 66622, - 68186, -}; - -#endif /* defined(DEBUG) */ -#endif /* RGX_BVNC_TABLE_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgx_cr_defs_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgx_cr_defs_km.h deleted file mode 100644 index 2464d91a7bd3e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgx_cr_defs_km.h +++ /dev/null @@ -1,8077 +0,0 @@ -/*************************************************************************/ /*! -@Title Hardware definition file rgx_cr_defs_km.h -@Brief The file contains auto-generated hardware definitions without - BVNC-specific compile time conditionals. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* **** Autogenerated C -- do not edit **** */ - -/* - */ - - -#ifndef RGX_CR_DEFS_KM_H -#define RGX_CR_DEFS_KM_H - -#if !defined(IMG_EXPLICIT_INCLUDE_HWDEFS) -#error This file may only be included if explicitly defined -#endif - -#include "img_types.h" -#include "img_defs.h" - - -#define RGX_CR_DEFS_KM_REVISION 1 - -/* - Register RGX_CR_RASTERISATION_INDIRECT -*/ -#define RGX_CR_RASTERISATION_INDIRECT (0x8238U) -#define RGX_CR_RASTERISATION_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_RASTERISATION_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_RASTERISATION_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_USC_INDIRECT -*/ -#define RGX_CR_USC_INDIRECT (0x8000U) -#define RGX_CR_USC_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_USC_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_USC_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_PBE_INDIRECT -*/ -#define RGX_CR_PBE_INDIRECT (0x83E0U) -#define RGX_CR_PBE_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_PBE_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_PBE_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_PBE_PERF_INDIRECT -*/ -#define RGX_CR_PBE_PERF_INDIRECT (0x83D8U) -#define RGX_CR_PBE_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_PBE_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_PBE_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_TPU_PERF_INDIRECT -*/ -#define RGX_CR_TPU_PERF_INDIRECT (0x83F0U) -#define RGX_CR_TPU_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_TPU_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_TPU_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF8U) - - -/* - Register RGX_CR_RASTERISATION_PERF_INDIRECT -*/ -#define RGX_CR_RASTERISATION_PERF_INDIRECT (0x8318U) -#define RGX_CR_RASTERISATION_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_RASTERISATION_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_RASTERISATION_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_TPU_MCU_L0_PERF_INDIRECT -*/ -#define RGX_CR_TPU_MCU_L0_PERF_INDIRECT (0x8028U) -#define RGX_CR_TPU_MCU_L0_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_TPU_MCU_L0_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_TPU_MCU_L0_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF8U) - - -/* - Register RGX_CR_USC_PERF_INDIRECT -*/ -#define RGX_CR_USC_PERF_INDIRECT (0x8030U) -#define RGX_CR_USC_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_USC_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_USC_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_BLACKPEARL_INDIRECT -*/ -#define RGX_CR_BLACKPEARL_INDIRECT (0x8388U) -#define RGX_CR_BLACKPEARL_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_BLACKPEARL_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_BLACKPEARL_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_BLACKPEARL_PERF_INDIRECT -*/ -#define RGX_CR_BLACKPEARL_PERF_INDIRECT (0x83F8U) -#define RGX_CR_BLACKPEARL_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_BLACKPEARL_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_BLACKPEARL_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_TEXAS3_PERF_INDIRECT -*/ -#define RGX_CR_TEXAS3_PERF_INDIRECT (0x83D0U) -#define RGX_CR_TEXAS3_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_TEXAS3_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_TEXAS3_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFF8U) - - -/* - Register RGX_CR_TEXAS_PERF_INDIRECT -*/ -#define RGX_CR_TEXAS_PERF_INDIRECT (0x8288U) -#define RGX_CR_TEXAS_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_TEXAS_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_TEXAS_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_BX_TU_PERF_INDIRECT -*/ -#define RGX_CR_BX_TU_PERF_INDIRECT (0xC900U) -#define RGX_CR_BX_TU_PERF_INDIRECT_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_BX_TU_PERF_INDIRECT_ADDRESS_SHIFT (0U) -#define RGX_CR_BX_TU_PERF_INDIRECT_ADDRESS_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_CLK_CTRL -*/ -#define RGX_CR_CLK_CTRL (0x0000U) -#define RGX_CR_CLK_CTRL__PBE2_XE__MASKFULL (IMG_UINT64_C(0xFFFFFF003F3FFFFF)) -#define RGX_CR_CLK_CTRL__S7_TOP__MASKFULL (IMG_UINT64_C(0xCFCF03000F3F3F0F)) -#define RGX_CR_CLK_CTRL_MASKFULL (IMG_UINT64_C(0xFFFFFF003F3FFFFF)) -#define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT (62U) -#define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK (IMG_UINT64_C(0x3FFFFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO (IMG_UINT64_C(0x8000000000000000)) -#define RGX_CR_CLK_CTRL_IPP_SHIFT (60U) -#define RGX_CR_CLK_CTRL_IPP_CLRMSK (IMG_UINT64_C(0xCFFFFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_IPP_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_IPP_ON (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_CLK_CTRL_IPP_AUTO (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_CLK_CTRL_FBC_SHIFT (58U) -#define RGX_CR_CLK_CTRL_FBC_CLRMSK (IMG_UINT64_C(0xF3FFFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_FBC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_FBC_ON (IMG_UINT64_C(0x0400000000000000)) -#define RGX_CR_CLK_CTRL_FBC_AUTO (IMG_UINT64_C(0x0800000000000000)) -#define RGX_CR_CLK_CTRL_FBDC_SHIFT (56U) -#define RGX_CR_CLK_CTRL_FBDC_CLRMSK (IMG_UINT64_C(0xFCFFFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_FBDC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_FBDC_ON (IMG_UINT64_C(0x0100000000000000)) -#define RGX_CR_CLK_CTRL_FBDC_AUTO (IMG_UINT64_C(0x0200000000000000)) -#define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT (54U) -#define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK (IMG_UINT64_C(0xFF3FFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON (IMG_UINT64_C(0x0040000000000000)) -#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO (IMG_UINT64_C(0x0080000000000000)) -#define RGX_CR_CLK_CTRL_USCS_SHIFT (52U) -#define RGX_CR_CLK_CTRL_USCS_CLRMSK (IMG_UINT64_C(0xFFCFFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_USCS_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_USCS_ON (IMG_UINT64_C(0x0010000000000000)) -#define RGX_CR_CLK_CTRL_USCS_AUTO (IMG_UINT64_C(0x0020000000000000)) -#define RGX_CR_CLK_CTRL_PBE_SHIFT (50U) -#define RGX_CR_CLK_CTRL_PBE_CLRMSK (IMG_UINT64_C(0xFFF3FFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_PBE_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_PBE_ON (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_CLK_CTRL_PBE_AUTO (IMG_UINT64_C(0x0008000000000000)) -#define RGX_CR_CLK_CTRL_MCU_L1_SHIFT (48U) -#define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK (IMG_UINT64_C(0xFFFCFFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_MCU_L1_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_MCU_L1_ON (IMG_UINT64_C(0x0001000000000000)) -#define RGX_CR_CLK_CTRL_MCU_L1_AUTO (IMG_UINT64_C(0x0002000000000000)) -#define RGX_CR_CLK_CTRL_CDM_SHIFT (46U) -#define RGX_CR_CLK_CTRL_CDM_CLRMSK (IMG_UINT64_C(0xFFFF3FFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_CDM_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_CDM_ON (IMG_UINT64_C(0x0000400000000000)) -#define RGX_CR_CLK_CTRL_CDM_AUTO (IMG_UINT64_C(0x0000800000000000)) -#define RGX_CR_CLK_CTRL_SIDEKICK_SHIFT (44U) -#define RGX_CR_CLK_CTRL_SIDEKICK_CLRMSK (IMG_UINT64_C(0xFFFFCFFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_SIDEKICK_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_SIDEKICK_ON (IMG_UINT64_C(0x0000100000000000)) -#define RGX_CR_CLK_CTRL_SIDEKICK_AUTO (IMG_UINT64_C(0x0000200000000000)) -#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_SHIFT (42U) -#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_CLRMSK (IMG_UINT64_C(0xFFFFF3FFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_ON (IMG_UINT64_C(0x0000040000000000)) -#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_AUTO (IMG_UINT64_C(0x0000080000000000)) -#define RGX_CR_CLK_CTRL_BIF_SHIFT (40U) -#define RGX_CR_CLK_CTRL_BIF_CLRMSK (IMG_UINT64_C(0xFFFFFCFFFFFFFFFF)) -#define RGX_CR_CLK_CTRL_BIF_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_BIF_ON (IMG_UINT64_C(0x0000010000000000)) -#define RGX_CR_CLK_CTRL_BIF_AUTO (IMG_UINT64_C(0x0000020000000000)) -#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_SHIFT (28U) -#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFCFFFFFFF)) -#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON (IMG_UINT64_C(0x0000000010000000)) -#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_CLK_CTRL_MCU_L0_SHIFT (26U) -#define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF3FFFFFF)) -#define RGX_CR_CLK_CTRL_MCU_L0_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_MCU_L0_ON (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_CLK_CTRL_MCU_L0_AUTO (IMG_UINT64_C(0x0000000008000000)) -#define RGX_CR_CLK_CTRL_TPU_SHIFT (24U) -#define RGX_CR_CLK_CTRL_TPU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFCFFFFFF)) -#define RGX_CR_CLK_CTRL_TPU_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_TPU_ON (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_CLK_CTRL_TPU_AUTO (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_CLK_CTRL_USC_SHIFT (20U) -#define RGX_CR_CLK_CTRL_USC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFCFFFFF)) -#define RGX_CR_CLK_CTRL_USC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_USC_ON (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_CLK_CTRL_USC_AUTO (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_CLK_CTRL_TLA_SHIFT (18U) -#define RGX_CR_CLK_CTRL_TLA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF3FFFF)) -#define RGX_CR_CLK_CTRL_TLA_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_TLA_ON (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_CLK_CTRL_TLA_AUTO (IMG_UINT64_C(0x0000000000080000)) -#define RGX_CR_CLK_CTRL_SLC_SHIFT (16U) -#define RGX_CR_CLK_CTRL_SLC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFCFFFF)) -#define RGX_CR_CLK_CTRL_SLC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_SLC_ON (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_CLK_CTRL_SLC_AUTO (IMG_UINT64_C(0x0000000000020000)) -#define RGX_CR_CLK_CTRL_UVS_SHIFT (14U) -#define RGX_CR_CLK_CTRL_UVS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF3FFF)) -#define RGX_CR_CLK_CTRL_UVS_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_UVS_ON (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_CLK_CTRL_UVS_AUTO (IMG_UINT64_C(0x0000000000008000)) -#define RGX_CR_CLK_CTRL_PDS_SHIFT (12U) -#define RGX_CR_CLK_CTRL_PDS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFCFFF)) -#define RGX_CR_CLK_CTRL_PDS_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_PDS_ON (IMG_UINT64_C(0x0000000000001000)) -#define RGX_CR_CLK_CTRL_PDS_AUTO (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_CLK_CTRL_VDM_SHIFT (10U) -#define RGX_CR_CLK_CTRL_VDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF3FF)) -#define RGX_CR_CLK_CTRL_VDM_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_VDM_ON (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_CLK_CTRL_VDM_AUTO (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_CLK_CTRL_PM_SHIFT (8U) -#define RGX_CR_CLK_CTRL_PM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFCFF)) -#define RGX_CR_CLK_CTRL_PM_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_PM_ON (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_CLK_CTRL_PM_AUTO (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_CLK_CTRL_GPP_SHIFT (6U) -#define RGX_CR_CLK_CTRL_GPP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF3F)) -#define RGX_CR_CLK_CTRL_GPP_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_GPP_ON (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_CLK_CTRL_GPP_AUTO (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_CLK_CTRL_TE_SHIFT (4U) -#define RGX_CR_CLK_CTRL_TE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFCF)) -#define RGX_CR_CLK_CTRL_TE_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_TE_ON (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_CLK_CTRL_TE_AUTO (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_CLK_CTRL_TSP_SHIFT (2U) -#define RGX_CR_CLK_CTRL_TSP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF3)) -#define RGX_CR_CLK_CTRL_TSP_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_TSP_ON (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_CLK_CTRL_TSP_AUTO (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_CLK_CTRL_ISP_SHIFT (0U) -#define RGX_CR_CLK_CTRL_ISP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFC)) -#define RGX_CR_CLK_CTRL_ISP_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL_ISP_ON (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_CLK_CTRL_ISP_AUTO (IMG_UINT64_C(0x0000000000000002)) - - -/* - Register RGX_CR_CLK_STATUS -*/ -#define RGX_CR_CLK_STATUS (0x0008U) -#define RGX_CR_CLK_STATUS__PBE2_XE__MASKFULL (IMG_UINT64_C(0x00000001FFF077FF)) -#define RGX_CR_CLK_STATUS__S7_TOP__MASKFULL (IMG_UINT64_C(0x00000001B3101773)) -#define RGX_CR_CLK_STATUS_MASKFULL (IMG_UINT64_C(0x00000001FFF077FF)) -#define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT (32U) -#define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT (31U) -#define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_CLK_STATUS_IPP_SHIFT (30U) -#define RGX_CR_CLK_STATUS_IPP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFBFFFFFFF)) -#define RGX_CR_CLK_STATUS_IPP_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_IPP_RUNNING (IMG_UINT64_C(0x0000000040000000)) -#define RGX_CR_CLK_STATUS_FBC_SHIFT (29U) -#define RGX_CR_CLK_STATUS_FBC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFDFFFFFFF)) -#define RGX_CR_CLK_STATUS_FBC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_FBC_RUNNING (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_CLK_STATUS_FBDC_SHIFT (28U) -#define RGX_CR_CLK_STATUS_FBDC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFEFFFFFFF)) -#define RGX_CR_CLK_STATUS_FBDC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_FBDC_RUNNING (IMG_UINT64_C(0x0000000010000000)) -#define RGX_CR_CLK_STATUS_FB_TLCACHE_SHIFT (27U) -#define RGX_CR_CLK_STATUS_FB_TLCACHE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF7FFFFFF)) -#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING (IMG_UINT64_C(0x0000000008000000)) -#define RGX_CR_CLK_STATUS_USCS_SHIFT (26U) -#define RGX_CR_CLK_STATUS_USCS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFBFFFFFF)) -#define RGX_CR_CLK_STATUS_USCS_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_USCS_RUNNING (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_CLK_STATUS_PBE_SHIFT (25U) -#define RGX_CR_CLK_STATUS_PBE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFDFFFFFF)) -#define RGX_CR_CLK_STATUS_PBE_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_PBE_RUNNING (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_CLK_STATUS_MCU_L1_SHIFT (24U) -#define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFEFFFFFF)) -#define RGX_CR_CLK_STATUS_MCU_L1_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_CLK_STATUS_CDM_SHIFT (23U) -#define RGX_CR_CLK_STATUS_CDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF7FFFFF)) -#define RGX_CR_CLK_STATUS_CDM_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_CDM_RUNNING (IMG_UINT64_C(0x0000000000800000)) -#define RGX_CR_CLK_STATUS_SIDEKICK_SHIFT (22U) -#define RGX_CR_CLK_STATUS_SIDEKICK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFBFFFFF)) -#define RGX_CR_CLK_STATUS_SIDEKICK_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_SIDEKICK_RUNNING (IMG_UINT64_C(0x0000000000400000)) -#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_SHIFT (21U) -#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_RUNNING (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_CLK_STATUS_BIF_SHIFT (20U) -#define RGX_CR_CLK_STATUS_BIF_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFEFFFFF)) -#define RGX_CR_CLK_STATUS_BIF_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_BIF_RUNNING (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_SHIFT (14U) -#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFBFFF)) -#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_CLK_STATUS_MCU_L0_SHIFT (13U) -#define RGX_CR_CLK_STATUS_MCU_L0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFDFFF)) -#define RGX_CR_CLK_STATUS_MCU_L0_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_CLK_STATUS_TPU_SHIFT (12U) -#define RGX_CR_CLK_STATUS_TPU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFEFFF)) -#define RGX_CR_CLK_STATUS_TPU_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_TPU_RUNNING (IMG_UINT64_C(0x0000000000001000)) -#define RGX_CR_CLK_STATUS_USC_SHIFT (10U) -#define RGX_CR_CLK_STATUS_USC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_CLK_STATUS_USC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_USC_RUNNING (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_CLK_STATUS_TLA_SHIFT (9U) -#define RGX_CR_CLK_STATUS_TLA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFDFF)) -#define RGX_CR_CLK_STATUS_TLA_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_TLA_RUNNING (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_CLK_STATUS_SLC_SHIFT (8U) -#define RGX_CR_CLK_STATUS_SLC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_CLK_STATUS_SLC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_SLC_RUNNING (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_CLK_STATUS_UVS_SHIFT (7U) -#define RGX_CR_CLK_STATUS_UVS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF7F)) -#define RGX_CR_CLK_STATUS_UVS_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_UVS_RUNNING (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_CLK_STATUS_PDS_SHIFT (6U) -#define RGX_CR_CLK_STATUS_PDS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFBF)) -#define RGX_CR_CLK_STATUS_PDS_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_PDS_RUNNING (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_CLK_STATUS_VDM_SHIFT (5U) -#define RGX_CR_CLK_STATUS_VDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_CLK_STATUS_VDM_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_VDM_RUNNING (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_CLK_STATUS_PM_SHIFT (4U) -#define RGX_CR_CLK_STATUS_PM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_CLK_STATUS_PM_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_PM_RUNNING (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_CLK_STATUS_GPP_SHIFT (3U) -#define RGX_CR_CLK_STATUS_GPP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_CLK_STATUS_GPP_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_GPP_RUNNING (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_CLK_STATUS_TE_SHIFT (2U) -#define RGX_CR_CLK_STATUS_TE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_CLK_STATUS_TE_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_TE_RUNNING (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_CLK_STATUS_TSP_SHIFT (1U) -#define RGX_CR_CLK_STATUS_TSP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_CLK_STATUS_TSP_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_TSP_RUNNING (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_CLK_STATUS_ISP_SHIFT (0U) -#define RGX_CR_CLK_STATUS_ISP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_CLK_STATUS_ISP_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS_ISP_RUNNING (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_CORE_ID -*/ -#define RGX_CR_CORE_ID__PBVNC (0x0020U) -#define RGX_CR_CORE_ID__PBVNC__MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_CORE_ID__PBVNC__BRANCH_ID_SHIFT (48U) -#define RGX_CR_CORE_ID__PBVNC__BRANCH_ID_CLRMSK (IMG_UINT64_C(0x0000FFFFFFFFFFFF)) -#define RGX_CR_CORE_ID__PBVNC__VERSION_ID_SHIFT (32U) -#define RGX_CR_CORE_ID__PBVNC__VERSION_ID_CLRMSK (IMG_UINT64_C(0xFFFF0000FFFFFFFF)) -#define RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_SHIFT (16U) -#define RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000FFFF)) -#define RGX_CR_CORE_ID__PBVNC__CONFIG_ID_SHIFT (0U) -#define RGX_CR_CORE_ID__PBVNC__CONFIG_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_CORE_ID -*/ -#define RGX_CR_CORE_ID (0x0018U) -#define RGX_CR_CORE_ID_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_CORE_ID_ID_SHIFT (16U) -#define RGX_CR_CORE_ID_ID_CLRMSK (0x0000FFFFU) -#define RGX_CR_CORE_ID_CONFIG_SHIFT (0U) -#define RGX_CR_CORE_ID_CONFIG_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_CORE_REVISION -*/ -#define RGX_CR_CORE_REVISION (0x0020U) -#define RGX_CR_CORE_REVISION_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_CORE_REVISION_DESIGNER_SHIFT (24U) -#define RGX_CR_CORE_REVISION_DESIGNER_CLRMSK (0x00FFFFFFU) -#define RGX_CR_CORE_REVISION_MAJOR_SHIFT (16U) -#define RGX_CR_CORE_REVISION_MAJOR_CLRMSK (0xFF00FFFFU) -#define RGX_CR_CORE_REVISION_MINOR_SHIFT (8U) -#define RGX_CR_CORE_REVISION_MINOR_CLRMSK (0xFFFF00FFU) -#define RGX_CR_CORE_REVISION_MAINTENANCE_SHIFT (0U) -#define RGX_CR_CORE_REVISION_MAINTENANCE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_DESIGNER_REV_FIELD1 -*/ -#define RGX_CR_DESIGNER_REV_FIELD1 (0x0028U) -#define RGX_CR_DESIGNER_REV_FIELD1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT (0U) -#define RGX_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_DESIGNER_REV_FIELD2 -*/ -#define RGX_CR_DESIGNER_REV_FIELD2 (0x0030U) -#define RGX_CR_DESIGNER_REV_FIELD2_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT (0U) -#define RGX_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_CHANGESET_NUMBER -*/ -#define RGX_CR_CHANGESET_NUMBER (0x0040U) -#define RGX_CR_CHANGESET_NUMBER_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_CHANGESET_NUMBER_CHANGESET_NUMBER_SHIFT (0U) -#define RGX_CR_CHANGESET_NUMBER_CHANGESET_NUMBER_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SOC_TIMER_GRAY -*/ -#define RGX_CR_SOC_TIMER_GRAY (0x00E0U) -#define RGX_CR_SOC_TIMER_GRAY_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SOC_TIMER_GRAY_VALUE_SHIFT (0U) -#define RGX_CR_SOC_TIMER_GRAY_VALUE_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SOC_TIMER_BINARY -*/ -#define RGX_CR_SOC_TIMER_BINARY (0x00E8U) -#define RGX_CR_SOC_TIMER_BINARY_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SOC_TIMER_BINARY_VALUE_SHIFT (0U) -#define RGX_CR_SOC_TIMER_BINARY_VALUE_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_CLK_XTPLUS_CTRL -*/ -#define RGX_CR_CLK_XTPLUS_CTRL (0x0080U) -#define RGX_CR_CLK_XTPLUS_CTRL_MASKFULL (IMG_UINT64_C(0x0000003FFFFF0000)) -#define RGX_CR_CLK_XTPLUS_CTRL_TDM_SHIFT (36U) -#define RGX_CR_CLK_XTPLUS_CTRL_TDM_CLRMSK (IMG_UINT64_C(0xFFFFFFCFFFFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_TDM_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_TDM_ON (IMG_UINT64_C(0x0000001000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_TDM_AUTO (IMG_UINT64_C(0x0000002000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_SHIFT (34U) -#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_CLRMSK (IMG_UINT64_C(0xFFFFFFF3FFFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_ON (IMG_UINT64_C(0x0000000400000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_AUTO (IMG_UINT64_C(0x0000000800000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_IPF_SHIFT (32U) -#define RGX_CR_CLK_XTPLUS_CTRL_IPF_CLRMSK (IMG_UINT64_C(0xFFFFFFFCFFFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_IPF_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_IPF_ON (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_IPF_AUTO (IMG_UINT64_C(0x0000000200000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_SHIFT (30U) -#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_CLRMSK (IMG_UINT64_C(0xFFFFFFFF3FFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_ON (IMG_UINT64_C(0x0000000040000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_AUTO (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_SHIFT (28U) -#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFCFFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_ON (IMG_UINT64_C(0x0000000010000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_AUTO (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_SHIFT (26U) -#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF3FFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_ON (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_AUTO (IMG_UINT64_C(0x0000000008000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_SHIFT (24U) -#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFCFFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_ON (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_AUTO (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_SHIFT (22U) -#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF3FFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_ON (IMG_UINT64_C(0x0000000000400000)) -#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_AUTO (IMG_UINT64_C(0x0000000000800000)) -#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_SHIFT (20U) -#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFCFFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_ON (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_AUTO (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_SHIFT (18U) -#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF3FFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_ON (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_AUTO (IMG_UINT64_C(0x0000000000080000)) -#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_SHIFT (16U) -#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFCFFFF)) -#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_ON (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_AUTO (IMG_UINT64_C(0x0000000000020000)) - - -/* - Register RGX_CR_CLK_XTPLUS_STATUS -*/ -#define RGX_CR_CLK_XTPLUS_STATUS (0x0088U) -#define RGX_CR_CLK_XTPLUS_STATUS_MASKFULL (IMG_UINT64_C(0x00000000000007FF)) -#define RGX_CR_CLK_XTPLUS_STATUS_TDM_SHIFT (10U) -#define RGX_CR_CLK_XTPLUS_STATUS_TDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_CLK_XTPLUS_STATUS_TDM_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_TDM_RUNNING (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_CLK_XTPLUS_STATUS_IPF_SHIFT (9U) -#define RGX_CR_CLK_XTPLUS_STATUS_IPF_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFDFF)) -#define RGX_CR_CLK_XTPLUS_STATUS_IPF_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_IPF_RUNNING (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_SHIFT (8U) -#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_RUNNING (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_SHIFT (7U) -#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF7F)) -#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_RUNNING (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_SHIFT (6U) -#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFBF)) -#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_RUNNING (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_SHIFT (5U) -#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_RUNNING (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_SHIFT (4U) -#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_RUNNING (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_SHIFT (3U) -#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_RUNNING (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_SHIFT (2U) -#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_RUNNING (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_SHIFT (1U) -#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_RUNNING (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_SHIFT (0U) -#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_RUNNING (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_SOFT_RESET -*/ -#define RGX_CR_SOFT_RESET (0x0100U) -#define RGX_CR_SOFT_RESET__PBE2_XE__MASKFULL (IMG_UINT64_C(0xFFEFFFFFFFFFFC3D)) -#define RGX_CR_SOFT_RESET_MASKFULL (IMG_UINT64_C(0x00E7FFFFFFFFFC3D)) -#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_SHIFT (63U) -#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_CLRMSK (IMG_UINT64_C(0x7FFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_EN (IMG_UINT64_C(0x8000000000000000)) -#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_SHIFT (62U) -#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_SOFT_RESET_BERNADO2_CORE_SHIFT (61U) -#define RGX_CR_SOFT_RESET_BERNADO2_CORE_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_BERNADO2_CORE_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_SOFT_RESET_JONES_CORE_SHIFT (60U) -#define RGX_CR_SOFT_RESET_JONES_CORE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_JONES_CORE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_SOFT_RESET_TILING_CORE_SHIFT (59U) -#define RGX_CR_SOFT_RESET_TILING_CORE_CLRMSK (IMG_UINT64_C(0xF7FFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_TILING_CORE_EN (IMG_UINT64_C(0x0800000000000000)) -#define RGX_CR_SOFT_RESET_TE3_SHIFT (58U) -#define RGX_CR_SOFT_RESET_TE3_CLRMSK (IMG_UINT64_C(0xFBFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_TE3_EN (IMG_UINT64_C(0x0400000000000000)) -#define RGX_CR_SOFT_RESET_VCE_SHIFT (57U) -#define RGX_CR_SOFT_RESET_VCE_CLRMSK (IMG_UINT64_C(0xFDFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_VCE_EN (IMG_UINT64_C(0x0200000000000000)) -#define RGX_CR_SOFT_RESET_VBS_SHIFT (56U) -#define RGX_CR_SOFT_RESET_VBS_CLRMSK (IMG_UINT64_C(0xFEFFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_VBS_EN (IMG_UINT64_C(0x0100000000000000)) -#define RGX_CR_SOFT_RESET_DPX1_CORE_SHIFT (55U) -#define RGX_CR_SOFT_RESET_DPX1_CORE_CLRMSK (IMG_UINT64_C(0xFF7FFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DPX1_CORE_EN (IMG_UINT64_C(0x0080000000000000)) -#define RGX_CR_SOFT_RESET_DPX0_CORE_SHIFT (54U) -#define RGX_CR_SOFT_RESET_DPX0_CORE_CLRMSK (IMG_UINT64_C(0xFFBFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DPX0_CORE_EN (IMG_UINT64_C(0x0040000000000000)) -#define RGX_CR_SOFT_RESET_FBA_SHIFT (53U) -#define RGX_CR_SOFT_RESET_FBA_CLRMSK (IMG_UINT64_C(0xFFDFFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_FBA_EN (IMG_UINT64_C(0x0020000000000000)) -#define RGX_CR_SOFT_RESET_FB_CDC_SHIFT (51U) -#define RGX_CR_SOFT_RESET_FB_CDC_CLRMSK (IMG_UINT64_C(0xFFF7FFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_FB_CDC_EN (IMG_UINT64_C(0x0008000000000000)) -#define RGX_CR_SOFT_RESET_SH_SHIFT (50U) -#define RGX_CR_SOFT_RESET_SH_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_SH_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_SOFT_RESET_VRDM_SHIFT (49U) -#define RGX_CR_SOFT_RESET_VRDM_CLRMSK (IMG_UINT64_C(0xFFFDFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_VRDM_EN (IMG_UINT64_C(0x0002000000000000)) -#define RGX_CR_SOFT_RESET_MCU_FBTC_SHIFT (48U) -#define RGX_CR_SOFT_RESET_MCU_FBTC_CLRMSK (IMG_UINT64_C(0xFFFEFFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_MCU_FBTC_EN (IMG_UINT64_C(0x0001000000000000)) -#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_SHIFT (47U) -#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_CLRMSK (IMG_UINT64_C(0xFFFF7FFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_EN (IMG_UINT64_C(0x0000800000000000)) -#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_SHIFT (46U) -#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_CLRMSK (IMG_UINT64_C(0xFFFFBFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_EN (IMG_UINT64_C(0x0000400000000000)) -#define RGX_CR_SOFT_RESET_BERNADO1_CORE_SHIFT (45U) -#define RGX_CR_SOFT_RESET_BERNADO1_CORE_CLRMSK (IMG_UINT64_C(0xFFFFDFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_BERNADO1_CORE_EN (IMG_UINT64_C(0x0000200000000000)) -#define RGX_CR_SOFT_RESET_BERNADO0_CORE_SHIFT (44U) -#define RGX_CR_SOFT_RESET_BERNADO0_CORE_CLRMSK (IMG_UINT64_C(0xFFFFEFFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_BERNADO0_CORE_EN (IMG_UINT64_C(0x0000100000000000)) -#define RGX_CR_SOFT_RESET_IPP_SHIFT (43U) -#define RGX_CR_SOFT_RESET_IPP_CLRMSK (IMG_UINT64_C(0xFFFFF7FFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_IPP_EN (IMG_UINT64_C(0x0000080000000000)) -#define RGX_CR_SOFT_RESET_BIF_TEXAS_SHIFT (42U) -#define RGX_CR_SOFT_RESET_BIF_TEXAS_CLRMSK (IMG_UINT64_C(0xFFFFFBFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_BIF_TEXAS_EN (IMG_UINT64_C(0x0000040000000000)) -#define RGX_CR_SOFT_RESET_TORNADO_CORE_SHIFT (41U) -#define RGX_CR_SOFT_RESET_TORNADO_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFDFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_TORNADO_CORE_EN (IMG_UINT64_C(0x0000020000000000)) -#define RGX_CR_SOFT_RESET_DUST_H_CORE_SHIFT (40U) -#define RGX_CR_SOFT_RESET_DUST_H_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFEFFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_H_CORE_EN (IMG_UINT64_C(0x0000010000000000)) -#define RGX_CR_SOFT_RESET_DUST_G_CORE_SHIFT (39U) -#define RGX_CR_SOFT_RESET_DUST_G_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFF7FFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_G_CORE_EN (IMG_UINT64_C(0x0000008000000000)) -#define RGX_CR_SOFT_RESET_DUST_F_CORE_SHIFT (38U) -#define RGX_CR_SOFT_RESET_DUST_F_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFBFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_F_CORE_EN (IMG_UINT64_C(0x0000004000000000)) -#define RGX_CR_SOFT_RESET_DUST_E_CORE_SHIFT (37U) -#define RGX_CR_SOFT_RESET_DUST_E_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFDFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_E_CORE_EN (IMG_UINT64_C(0x0000002000000000)) -#define RGX_CR_SOFT_RESET_DUST_D_CORE_SHIFT (36U) -#define RGX_CR_SOFT_RESET_DUST_D_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFEFFFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_D_CORE_EN (IMG_UINT64_C(0x0000001000000000)) -#define RGX_CR_SOFT_RESET_DUST_C_CORE_SHIFT (35U) -#define RGX_CR_SOFT_RESET_DUST_C_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFF7FFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_C_CORE_EN (IMG_UINT64_C(0x0000000800000000)) -#define RGX_CR_SOFT_RESET_MMU_SHIFT (34U) -#define RGX_CR_SOFT_RESET_MMU_CLRMSK (IMG_UINT64_C(0xFFFFFFFBFFFFFFFF)) -#define RGX_CR_SOFT_RESET_MMU_EN (IMG_UINT64_C(0x0000000400000000)) -#define RGX_CR_SOFT_RESET_BIF1_SHIFT (33U) -#define RGX_CR_SOFT_RESET_BIF1_CLRMSK (IMG_UINT64_C(0xFFFFFFFDFFFFFFFF)) -#define RGX_CR_SOFT_RESET_BIF1_EN (IMG_UINT64_C(0x0000000200000000)) -#define RGX_CR_SOFT_RESET_GARTEN_SHIFT (32U) -#define RGX_CR_SOFT_RESET_GARTEN_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_SOFT_RESET_GARTEN_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_SOFT_RESET_CPU_SHIFT (32U) -#define RGX_CR_SOFT_RESET_CPU_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_SOFT_RESET_CPU_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_SOFT_RESET_RASCAL_CORE_SHIFT (31U) -#define RGX_CR_SOFT_RESET_RASCAL_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_SOFT_RESET_RASCAL_CORE_EN (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_SOFT_RESET_DUST_B_CORE_SHIFT (30U) -#define RGX_CR_SOFT_RESET_DUST_B_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFBFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_B_CORE_EN (IMG_UINT64_C(0x0000000040000000)) -#define RGX_CR_SOFT_RESET_DUST_A_CORE_SHIFT (29U) -#define RGX_CR_SOFT_RESET_DUST_A_CORE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFDFFFFFFF)) -#define RGX_CR_SOFT_RESET_DUST_A_CORE_EN (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_SOFT_RESET_FB_TLCACHE_SHIFT (28U) -#define RGX_CR_SOFT_RESET_FB_TLCACHE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFEFFFFFFF)) -#define RGX_CR_SOFT_RESET_FB_TLCACHE_EN (IMG_UINT64_C(0x0000000010000000)) -#define RGX_CR_SOFT_RESET_SLC_SHIFT (27U) -#define RGX_CR_SOFT_RESET_SLC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF7FFFFFF)) -#define RGX_CR_SOFT_RESET_SLC_EN (IMG_UINT64_C(0x0000000008000000)) -#define RGX_CR_SOFT_RESET_TLA_SHIFT (26U) -#define RGX_CR_SOFT_RESET_TLA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFBFFFFFF)) -#define RGX_CR_SOFT_RESET_TLA_EN (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_SOFT_RESET_UVS_SHIFT (25U) -#define RGX_CR_SOFT_RESET_UVS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFDFFFFFF)) -#define RGX_CR_SOFT_RESET_UVS_EN (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_SOFT_RESET_TE_SHIFT (24U) -#define RGX_CR_SOFT_RESET_TE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFEFFFFFF)) -#define RGX_CR_SOFT_RESET_TE_EN (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_SOFT_RESET_GPP_SHIFT (23U) -#define RGX_CR_SOFT_RESET_GPP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF7FFFFF)) -#define RGX_CR_SOFT_RESET_GPP_EN (IMG_UINT64_C(0x0000000000800000)) -#define RGX_CR_SOFT_RESET_FBDC_SHIFT (22U) -#define RGX_CR_SOFT_RESET_FBDC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFBFFFFF)) -#define RGX_CR_SOFT_RESET_FBDC_EN (IMG_UINT64_C(0x0000000000400000)) -#define RGX_CR_SOFT_RESET_FBC_SHIFT (21U) -#define RGX_CR_SOFT_RESET_FBC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_SOFT_RESET_FBC_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_SOFT_RESET_PM_SHIFT (20U) -#define RGX_CR_SOFT_RESET_PM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFEFFFFF)) -#define RGX_CR_SOFT_RESET_PM_EN (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_SOFT_RESET_PBE_SHIFT (19U) -#define RGX_CR_SOFT_RESET_PBE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF7FFFF)) -#define RGX_CR_SOFT_RESET_PBE_EN (IMG_UINT64_C(0x0000000000080000)) -#define RGX_CR_SOFT_RESET_USC_SHARED_SHIFT (18U) -#define RGX_CR_SOFT_RESET_USC_SHARED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFBFFFF)) -#define RGX_CR_SOFT_RESET_USC_SHARED_EN (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_SOFT_RESET_MCU_L1_SHIFT (17U) -#define RGX_CR_SOFT_RESET_MCU_L1_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFDFFFF)) -#define RGX_CR_SOFT_RESET_MCU_L1_EN (IMG_UINT64_C(0x0000000000020000)) -#define RGX_CR_SOFT_RESET_BIF_SHIFT (16U) -#define RGX_CR_SOFT_RESET_BIF_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFEFFFF)) -#define RGX_CR_SOFT_RESET_BIF_EN (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_SOFT_RESET_CDM_SHIFT (15U) -#define RGX_CR_SOFT_RESET_CDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF7FFF)) -#define RGX_CR_SOFT_RESET_CDM_EN (IMG_UINT64_C(0x0000000000008000)) -#define RGX_CR_SOFT_RESET_VDM_SHIFT (14U) -#define RGX_CR_SOFT_RESET_VDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFBFFF)) -#define RGX_CR_SOFT_RESET_VDM_EN (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_SOFT_RESET_TESS_SHIFT (13U) -#define RGX_CR_SOFT_RESET_TESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFDFFF)) -#define RGX_CR_SOFT_RESET_TESS_EN (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_SOFT_RESET_PDS_SHIFT (12U) -#define RGX_CR_SOFT_RESET_PDS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFEFFF)) -#define RGX_CR_SOFT_RESET_PDS_EN (IMG_UINT64_C(0x0000000000001000)) -#define RGX_CR_SOFT_RESET_ISP_SHIFT (11U) -#define RGX_CR_SOFT_RESET_ISP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF7FF)) -#define RGX_CR_SOFT_RESET_ISP_EN (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_SOFT_RESET_TSP_SHIFT (10U) -#define RGX_CR_SOFT_RESET_TSP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_SOFT_RESET_TSP_EN (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_SOFT_RESET_SYSARB_SHIFT (5U) -#define RGX_CR_SOFT_RESET_SYSARB_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_SOFT_RESET_SYSARB_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_SHIFT (4U) -#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_EN (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_SOFT_RESET_MCU_L0_SHIFT (3U) -#define RGX_CR_SOFT_RESET_MCU_L0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_SOFT_RESET_MCU_L0_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_SOFT_RESET_TPU_SHIFT (2U) -#define RGX_CR_SOFT_RESET_TPU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_SOFT_RESET_TPU_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_SOFT_RESET_USC_SHIFT (0U) -#define RGX_CR_SOFT_RESET_USC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_SOFT_RESET_USC_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_SOFT_RESET2 -*/ -#define RGX_CR_SOFT_RESET2 (0x0108U) -#define RGX_CR_SOFT_RESET2_MASKFULL (IMG_UINT64_C(0x00000000001FFFFF)) -#define RGX_CR_SOFT_RESET2_SPFILTER_SHIFT (12U) -#define RGX_CR_SOFT_RESET2_SPFILTER_CLRMSK (0xFFE00FFFU) -#define RGX_CR_SOFT_RESET2_TDM_SHIFT (11U) -#define RGX_CR_SOFT_RESET2_TDM_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_SOFT_RESET2_TDM_EN (0x00000800U) -#define RGX_CR_SOFT_RESET2_ASTC_SHIFT (10U) -#define RGX_CR_SOFT_RESET2_ASTC_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_SOFT_RESET2_ASTC_EN (0x00000400U) -#define RGX_CR_SOFT_RESET2_BLACKPEARL_SHIFT (9U) -#define RGX_CR_SOFT_RESET2_BLACKPEARL_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_SOFT_RESET2_BLACKPEARL_EN (0x00000200U) -#define RGX_CR_SOFT_RESET2_USCPS_SHIFT (8U) -#define RGX_CR_SOFT_RESET2_USCPS_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_SOFT_RESET2_USCPS_EN (0x00000100U) -#define RGX_CR_SOFT_RESET2_IPF_SHIFT (7U) -#define RGX_CR_SOFT_RESET2_IPF_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SOFT_RESET2_IPF_EN (0x00000080U) -#define RGX_CR_SOFT_RESET2_GEOMETRY_SHIFT (6U) -#define RGX_CR_SOFT_RESET2_GEOMETRY_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SOFT_RESET2_GEOMETRY_EN (0x00000040U) -#define RGX_CR_SOFT_RESET2_USC_SHARED_SHIFT (5U) -#define RGX_CR_SOFT_RESET2_USC_SHARED_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SOFT_RESET2_USC_SHARED_EN (0x00000020U) -#define RGX_CR_SOFT_RESET2_PDS_SHARED_SHIFT (4U) -#define RGX_CR_SOFT_RESET2_PDS_SHARED_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SOFT_RESET2_PDS_SHARED_EN (0x00000010U) -#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_SHIFT (3U) -#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_EN (0x00000008U) -#define RGX_CR_SOFT_RESET2_PIXEL_SHIFT (2U) -#define RGX_CR_SOFT_RESET2_PIXEL_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SOFT_RESET2_PIXEL_EN (0x00000004U) -#define RGX_CR_SOFT_RESET2_CDM_SHIFT (1U) -#define RGX_CR_SOFT_RESET2_CDM_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SOFT_RESET2_CDM_EN (0x00000002U) -#define RGX_CR_SOFT_RESET2_VERTEX_SHIFT (0U) -#define RGX_CR_SOFT_RESET2_VERTEX_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SOFT_RESET2_VERTEX_EN (0x00000001U) - - -/* - Register RGX_CR_EVENT_STATUS -*/ -#define RGX_CR_EVENT_STATUS (0x0130U) -#define RGX_CR_EVENT_STATUS__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000E01DFFFF)) -#define RGX_CR_EVENT_STATUS__SIGNALS__MASKFULL (IMG_UINT64_C(0x00000000E007FFFF)) -#define RGX_CR_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_SHIFT (31U) -#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_CLRMSK (0x7FFFFFFFU) -#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_EN (0x80000000U) -#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_SHIFT (30U) -#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_EN (0x40000000U) -#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_SHIFT (29U) -#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_EN (0x20000000U) -#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_SHIFT (28U) -#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_EN (0x10000000U) -#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_SHIFT (27U) -#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_EN (0x08000000U) -#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_SHIFT (26U) -#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_CLRMSK (0xFBFFFFFFU) -#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_EN (0x04000000U) -#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_SHIFT (25U) -#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_CLRMSK (0xFDFFFFFFU) -#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_EN (0x02000000U) -#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_SHIFT (24U) -#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_CLRMSK (0xFEFFFFFFU) -#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_EN (0x01000000U) -#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_SHIFT (23U) -#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_CLRMSK (0xFF7FFFFFU) -#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_EN (0x00800000U) -#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_SHIFT (22U) -#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_EN (0x00400000U) -#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_SHIFT (21U) -#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_EN (0x00200000U) -#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_SHIFT (20U) -#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_EN (0x00100000U) -#define RGX_CR_EVENT_STATUS_SAFETY_SHIFT (20U) -#define RGX_CR_EVENT_STATUS_SAFETY_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_EVENT_STATUS_SAFETY_EN (0x00100000U) -#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_SHIFT (19U) -#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_EN (0x00080000U) -#define RGX_CR_EVENT_STATUS_SLAVE_REQ_SHIFT (19U) -#define RGX_CR_EVENT_STATUS_SLAVE_REQ_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_EVENT_STATUS_SLAVE_REQ_EN (0x00080000U) -#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_SHIFT (18U) -#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_EN (0x00040000U) -#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_SHIFT (18U) -#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_EN (0x00040000U) -#define RGX_CR_EVENT_STATUS_SHG_FINISHED_SHIFT (17U) -#define RGX_CR_EVENT_STATUS_SHG_FINISHED_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_EVENT_STATUS_SHG_FINISHED_EN (0x00020000U) -#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_SHIFT (17U) -#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_EN (0x00020000U) -#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_SHIFT (16U) -#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_EN (0x00010000U) -#define RGX_CR_EVENT_STATUS_USC_TRIGGER_SHIFT (15U) -#define RGX_CR_EVENT_STATUS_USC_TRIGGER_CLRMSK (0xFFFF7FFFU) -#define RGX_CR_EVENT_STATUS_USC_TRIGGER_EN (0x00008000U) -#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_SHIFT (14U) -#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_CLRMSK (0xFFFFBFFFU) -#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_EN (0x00004000U) -#define RGX_CR_EVENT_STATUS_GPIO_ACK_SHIFT (13U) -#define RGX_CR_EVENT_STATUS_GPIO_ACK_CLRMSK (0xFFFFDFFFU) -#define RGX_CR_EVENT_STATUS_GPIO_ACK_EN (0x00002000U) -#define RGX_CR_EVENT_STATUS_GPIO_REQ_SHIFT (12U) -#define RGX_CR_EVENT_STATUS_GPIO_REQ_CLRMSK (0xFFFFEFFFU) -#define RGX_CR_EVENT_STATUS_GPIO_REQ_EN (0x00001000U) -#define RGX_CR_EVENT_STATUS_POWER_ABORT_SHIFT (11U) -#define RGX_CR_EVENT_STATUS_POWER_ABORT_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_EVENT_STATUS_POWER_ABORT_EN (0x00000800U) -#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_SHIFT (10U) -#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_EN (0x00000400U) -#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_SHIFT (9U) -#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_EN (0x00000200U) -#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_SHIFT (8U) -#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_EN (0x00000100U) -#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_SHIFT (7U) -#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_EN (0x00000080U) -#define RGX_CR_EVENT_STATUS_TA_TERMINATE_SHIFT (6U) -#define RGX_CR_EVENT_STATUS_TA_TERMINATE_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_EVENT_STATUS_TA_TERMINATE_EN (0x00000040U) -#define RGX_CR_EVENT_STATUS_TA_FINISHED_SHIFT (5U) -#define RGX_CR_EVENT_STATUS_TA_FINISHED_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_EVENT_STATUS_TA_FINISHED_EN (0x00000020U) -#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_SHIFT (4U) -#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_EN (0x00000010U) -#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT (3U) -#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_EN (0x00000008U) -#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_SHIFT (2U) -#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_EN (0x00000004U) -#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_SHIFT (1U) -#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_EN (0x00000002U) -#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_SHIFT (0U) -#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_EN (0x00000001U) - - -/* - Register RGX_CR_EVENT_CLEAR -*/ -#define RGX_CR_EVENT_CLEAR (0x0138U) -#define RGX_CR_EVENT_CLEAR__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000E01DFFFF)) -#define RGX_CR_EVENT_CLEAR__SIGNALS__MASKFULL (IMG_UINT64_C(0x00000000E007FFFF)) -#define RGX_CR_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_SHIFT (31U) -#define RGX_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_CLRMSK (0x7FFFFFFFU) -#define RGX_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_EN (0x80000000U) -#define RGX_CR_EVENT_CLEAR_TDM_BUFFER_STALL_SHIFT (30U) -#define RGX_CR_EVENT_CLEAR_TDM_BUFFER_STALL_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_EVENT_CLEAR_TDM_BUFFER_STALL_EN (0x40000000U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_SHIFT (29U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_EN (0x20000000U) -#define RGX_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_SHIFT (28U) -#define RGX_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_EN (0x10000000U) -#define RGX_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_SHIFT (27U) -#define RGX_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_EN (0x08000000U) -#define RGX_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_SHIFT (26U) -#define RGX_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_CLRMSK (0xFBFFFFFFU) -#define RGX_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_EN (0x04000000U) -#define RGX_CR_EVENT_CLEAR_FBA_FC3_FINISHED_SHIFT (25U) -#define RGX_CR_EVENT_CLEAR_FBA_FC3_FINISHED_CLRMSK (0xFDFFFFFFU) -#define RGX_CR_EVENT_CLEAR_FBA_FC3_FINISHED_EN (0x02000000U) -#define RGX_CR_EVENT_CLEAR_FBA_FC2_FINISHED_SHIFT (24U) -#define RGX_CR_EVENT_CLEAR_FBA_FC2_FINISHED_CLRMSK (0xFEFFFFFFU) -#define RGX_CR_EVENT_CLEAR_FBA_FC2_FINISHED_EN (0x01000000U) -#define RGX_CR_EVENT_CLEAR_FBA_FC1_FINISHED_SHIFT (23U) -#define RGX_CR_EVENT_CLEAR_FBA_FC1_FINISHED_CLRMSK (0xFF7FFFFFU) -#define RGX_CR_EVENT_CLEAR_FBA_FC1_FINISHED_EN (0x00800000U) -#define RGX_CR_EVENT_CLEAR_FBA_FC0_FINISHED_SHIFT (22U) -#define RGX_CR_EVENT_CLEAR_FBA_FC0_FINISHED_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_EVENT_CLEAR_FBA_FC0_FINISHED_EN (0x00400000U) -#define RGX_CR_EVENT_CLEAR_RDM_FC3_FINISHED_SHIFT (21U) -#define RGX_CR_EVENT_CLEAR_RDM_FC3_FINISHED_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_EVENT_CLEAR_RDM_FC3_FINISHED_EN (0x00200000U) -#define RGX_CR_EVENT_CLEAR_RDM_FC2_FINISHED_SHIFT (20U) -#define RGX_CR_EVENT_CLEAR_RDM_FC2_FINISHED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_EVENT_CLEAR_RDM_FC2_FINISHED_EN (0x00100000U) -#define RGX_CR_EVENT_CLEAR_SAFETY_SHIFT (20U) -#define RGX_CR_EVENT_CLEAR_SAFETY_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_EVENT_CLEAR_SAFETY_EN (0x00100000U) -#define RGX_CR_EVENT_CLEAR_RDM_FC1_FINISHED_SHIFT (19U) -#define RGX_CR_EVENT_CLEAR_RDM_FC1_FINISHED_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_EVENT_CLEAR_RDM_FC1_FINISHED_EN (0x00080000U) -#define RGX_CR_EVENT_CLEAR_SLAVE_REQ_SHIFT (19U) -#define RGX_CR_EVENT_CLEAR_SLAVE_REQ_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_EVENT_CLEAR_SLAVE_REQ_EN (0x00080000U) -#define RGX_CR_EVENT_CLEAR_RDM_FC0_FINISHED_SHIFT (18U) -#define RGX_CR_EVENT_CLEAR_RDM_FC0_FINISHED_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_EVENT_CLEAR_RDM_FC0_FINISHED_EN (0x00040000U) -#define RGX_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_SHIFT (18U) -#define RGX_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_EN (0x00040000U) -#define RGX_CR_EVENT_CLEAR_SHG_FINISHED_SHIFT (17U) -#define RGX_CR_EVENT_CLEAR_SHG_FINISHED_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_EVENT_CLEAR_SHG_FINISHED_EN (0x00020000U) -#define RGX_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_SHIFT (17U) -#define RGX_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_EN (0x00020000U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_SHIFT (16U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_EN (0x00010000U) -#define RGX_CR_EVENT_CLEAR_USC_TRIGGER_SHIFT (15U) -#define RGX_CR_EVENT_CLEAR_USC_TRIGGER_CLRMSK (0xFFFF7FFFU) -#define RGX_CR_EVENT_CLEAR_USC_TRIGGER_EN (0x00008000U) -#define RGX_CR_EVENT_CLEAR_ZLS_FINISHED_SHIFT (14U) -#define RGX_CR_EVENT_CLEAR_ZLS_FINISHED_CLRMSK (0xFFFFBFFFU) -#define RGX_CR_EVENT_CLEAR_ZLS_FINISHED_EN (0x00004000U) -#define RGX_CR_EVENT_CLEAR_GPIO_ACK_SHIFT (13U) -#define RGX_CR_EVENT_CLEAR_GPIO_ACK_CLRMSK (0xFFFFDFFFU) -#define RGX_CR_EVENT_CLEAR_GPIO_ACK_EN (0x00002000U) -#define RGX_CR_EVENT_CLEAR_GPIO_REQ_SHIFT (12U) -#define RGX_CR_EVENT_CLEAR_GPIO_REQ_CLRMSK (0xFFFFEFFFU) -#define RGX_CR_EVENT_CLEAR_GPIO_REQ_EN (0x00001000U) -#define RGX_CR_EVENT_CLEAR_POWER_ABORT_SHIFT (11U) -#define RGX_CR_EVENT_CLEAR_POWER_ABORT_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_EVENT_CLEAR_POWER_ABORT_EN (0x00000800U) -#define RGX_CR_EVENT_CLEAR_POWER_COMPLETE_SHIFT (10U) -#define RGX_CR_EVENT_CLEAR_POWER_COMPLETE_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_EVENT_CLEAR_POWER_COMPLETE_EN (0x00000400U) -#define RGX_CR_EVENT_CLEAR_MMU_PAGE_FAULT_SHIFT (9U) -#define RGX_CR_EVENT_CLEAR_MMU_PAGE_FAULT_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_EVENT_CLEAR_MMU_PAGE_FAULT_EN (0x00000200U) -#define RGX_CR_EVENT_CLEAR_PM_3D_MEM_FREE_SHIFT (8U) -#define RGX_CR_EVENT_CLEAR_PM_3D_MEM_FREE_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_EVENT_CLEAR_PM_3D_MEM_FREE_EN (0x00000100U) -#define RGX_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_SHIFT (7U) -#define RGX_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_EN (0x00000080U) -#define RGX_CR_EVENT_CLEAR_TA_TERMINATE_SHIFT (6U) -#define RGX_CR_EVENT_CLEAR_TA_TERMINATE_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_EVENT_CLEAR_TA_TERMINATE_EN (0x00000040U) -#define RGX_CR_EVENT_CLEAR_TA_FINISHED_SHIFT (5U) -#define RGX_CR_EVENT_CLEAR_TA_FINISHED_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_EVENT_CLEAR_TA_FINISHED_EN (0x00000020U) -#define RGX_CR_EVENT_CLEAR_ISP_END_MACROTILE_SHIFT (4U) -#define RGX_CR_EVENT_CLEAR_ISP_END_MACROTILE_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_EVENT_CLEAR_ISP_END_MACROTILE_EN (0x00000010U) -#define RGX_CR_EVENT_CLEAR_PIXELBE_END_RENDER_SHIFT (3U) -#define RGX_CR_EVENT_CLEAR_PIXELBE_END_RENDER_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_EVENT_CLEAR_PIXELBE_END_RENDER_EN (0x00000008U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_FINISHED_SHIFT (2U) -#define RGX_CR_EVENT_CLEAR_COMPUTE_FINISHED_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_EVENT_CLEAR_COMPUTE_FINISHED_EN (0x00000004U) -#define RGX_CR_EVENT_CLEAR_KERNEL_FINISHED_SHIFT (1U) -#define RGX_CR_EVENT_CLEAR_KERNEL_FINISHED_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_EVENT_CLEAR_KERNEL_FINISHED_EN (0x00000002U) -#define RGX_CR_EVENT_CLEAR_TLA_COMPLETE_SHIFT (0U) -#define RGX_CR_EVENT_CLEAR_TLA_COMPLETE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_EVENT_CLEAR_TLA_COMPLETE_EN (0x00000001U) - - -/* - Register RGX_CR_TIMER -*/ -#define RGX_CR_TIMER (0x0160U) -#define RGX_CR_TIMER_MASKFULL (IMG_UINT64_C(0x8000FFFFFFFFFFFF)) -#define RGX_CR_TIMER_BIT31_SHIFT (63U) -#define RGX_CR_TIMER_BIT31_CLRMSK (IMG_UINT64_C(0x7FFFFFFFFFFFFFFF)) -#define RGX_CR_TIMER_BIT31_EN (IMG_UINT64_C(0x8000000000000000)) -#define RGX_CR_TIMER_VALUE_SHIFT (0U) -#define RGX_CR_TIMER_VALUE_CLRMSK (IMG_UINT64_C(0xFFFF000000000000)) - - -/* - Register RGX_CR_TLA_STATUS -*/ -#define RGX_CR_TLA_STATUS (0x0178U) -#define RGX_CR_TLA_STATUS_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_TLA_STATUS_BLIT_COUNT_SHIFT (39U) -#define RGX_CR_TLA_STATUS_BLIT_COUNT_CLRMSK (IMG_UINT64_C(0x0000007FFFFFFFFF)) -#define RGX_CR_TLA_STATUS_REQUEST_SHIFT (7U) -#define RGX_CR_TLA_STATUS_REQUEST_CLRMSK (IMG_UINT64_C(0xFFFFFF800000007F)) -#define RGX_CR_TLA_STATUS_FIFO_FULLNESS_SHIFT (1U) -#define RGX_CR_TLA_STATUS_FIFO_FULLNESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF81)) -#define RGX_CR_TLA_STATUS_BUSY_SHIFT (0U) -#define RGX_CR_TLA_STATUS_BUSY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_TLA_STATUS_BUSY_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_PM_PARTIAL_RENDER_ENABLE -*/ -#define RGX_CR_PM_PARTIAL_RENDER_ENABLE (0x0338U) -#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_SHIFT (0U) -#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_EN (0x00000001U) - - -/* - Register RGX_CR_SIDEKICK_IDLE -*/ -#define RGX_CR_SIDEKICK_IDLE (0x03C8U) -#define RGX_CR_SIDEKICK_IDLE_MASKFULL (IMG_UINT64_C(0x000000000000007F)) -#define RGX_CR_SIDEKICK_IDLE_FB_CDC_SHIFT (6U) -#define RGX_CR_SIDEKICK_IDLE_FB_CDC_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SIDEKICK_IDLE_FB_CDC_EN (0x00000040U) -#define RGX_CR_SIDEKICK_IDLE_MMU_SHIFT (5U) -#define RGX_CR_SIDEKICK_IDLE_MMU_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SIDEKICK_IDLE_MMU_EN (0x00000020U) -#define RGX_CR_SIDEKICK_IDLE_BIF128_SHIFT (4U) -#define RGX_CR_SIDEKICK_IDLE_BIF128_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SIDEKICK_IDLE_BIF128_EN (0x00000010U) -#define RGX_CR_SIDEKICK_IDLE_TLA_SHIFT (3U) -#define RGX_CR_SIDEKICK_IDLE_TLA_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SIDEKICK_IDLE_TLA_EN (0x00000008U) -#define RGX_CR_SIDEKICK_IDLE_GARTEN_SHIFT (2U) -#define RGX_CR_SIDEKICK_IDLE_GARTEN_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SIDEKICK_IDLE_GARTEN_EN (0x00000004U) -#define RGX_CR_SIDEKICK_IDLE_HOSTIF_SHIFT (1U) -#define RGX_CR_SIDEKICK_IDLE_HOSTIF_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SIDEKICK_IDLE_HOSTIF_EN (0x00000002U) -#define RGX_CR_SIDEKICK_IDLE_SOCIF_SHIFT (0U) -#define RGX_CR_SIDEKICK_IDLE_SOCIF_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SIDEKICK_IDLE_SOCIF_EN (0x00000001U) - - -/* - Register RGX_CR_MARS_IDLE -*/ -#define RGX_CR_MARS_IDLE (0x08F8U) -#define RGX_CR_MARS_IDLE_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_MARS_IDLE_MH_SYSARB0_SHIFT (2U) -#define RGX_CR_MARS_IDLE_MH_SYSARB0_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_MARS_IDLE_MH_SYSARB0_EN (0x00000004U) -#define RGX_CR_MARS_IDLE_CPU_SHIFT (1U) -#define RGX_CR_MARS_IDLE_CPU_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_MARS_IDLE_CPU_EN (0x00000002U) -#define RGX_CR_MARS_IDLE_SOCIF_SHIFT (0U) -#define RGX_CR_MARS_IDLE_SOCIF_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MARS_IDLE_SOCIF_EN (0x00000001U) - - -/* - Register RGX_CR_VDM_CONTEXT_STORE_STATUS -*/ -#define RGX_CR_VDM_CONTEXT_STORE_STATUS (0x0430U) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_MASKFULL (IMG_UINT64_C(0x00000000000000F3)) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_LAST_PIPE_SHIFT (4U) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_LAST_PIPE_CLRMSK (0xFFFFFF0FU) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_SHIFT (1U) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_EN (0x00000002U) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_EN (0x00000001U) - - -/* - Register RGX_CR_VDM_CONTEXT_STORE_TASK0 -*/ -#define RGX_CR_VDM_CONTEXT_STORE_TASK0 (0x0438U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK0_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE1_SHIFT (32U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE1_CLRMSK (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE0_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE0_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_VDM_CONTEXT_STORE_TASK1 -*/ -#define RGX_CR_VDM_CONTEXT_STORE_TASK1 (0x0440U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_STORE_TASK1_PDS_STATE2_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK1_PDS_STATE2_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_VDM_CONTEXT_STORE_TASK2 -*/ -#define RGX_CR_VDM_CONTEXT_STORE_TASK2 (0x0448U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK2_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT2_SHIFT (32U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT2_CLRMSK (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT1_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT1_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_VDM_CONTEXT_RESUME_TASK0 -*/ -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0 (0x0450U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE1_SHIFT (32U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE1_CLRMSK (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE0_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE0_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_VDM_CONTEXT_RESUME_TASK1 -*/ -#define RGX_CR_VDM_CONTEXT_RESUME_TASK1 (0x0458U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_PDS_STATE2_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_PDS_STATE2_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_VDM_CONTEXT_RESUME_TASK2 -*/ -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2 (0x0460U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT2_SHIFT (32U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT2_CLRMSK (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT1_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT1_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_CDM_CONTEXT_STORE_STATUS -*/ -#define RGX_CR_CDM_CONTEXT_STORE_STATUS (0x04A0U) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_SHIFT (1U) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_EN (0x00000002U) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_SHIFT (0U) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_EN (0x00000001U) - - -/* - Register RGX_CR_CDM_CONTEXT_PDS0 -*/ -#define RGX_CR_CDM_CONTEXT_PDS0 (0x04A8U) -#define RGX_CR_CDM_CONTEXT_PDS0_MASKFULL (IMG_UINT64_C(0xFFFFFFF0FFFFFFF0)) -#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_SHIFT (36U) -#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_CLRMSK (IMG_UINT64_C(0x0000000FFFFFFFFF)) -#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_ALIGNSIZE (16U) -#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_SHIFT (4U) -#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000000F)) -#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_ALIGNSIZE (16U) - - -/* - Register RGX_CR_CDM_CONTEXT_PDS1 -*/ -#define RGX_CR_CDM_CONTEXT_PDS1 (0x04B0U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__MASKFULL (IMG_UINT64_C(0x000000007FFFFFFF)) -#define RGX_CR_CDM_CONTEXT_PDS1_MASKFULL (IMG_UINT64_C(0x000000003FFFFFFF)) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0x40000000U) -#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_SHIFT (28U) -#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_EN (0x10000000U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_SHIFT (28U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_EN (0x10000000U) -#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_SHIFT (27U) -#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_EN (0x08000000U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0xF03FFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_SHIFT (21U) -#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_CLRMSK (0xF81FFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0x00200000U) -#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_SHIFT (20U) -#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_EN (0x00100000U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0xFFE00FFFU) -#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_SHIFT (11U) -#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_CLRMSK (0xFFF007FFU) -#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_CLRMSK (0xFFFFF87FU) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0xFFFFF07FU) -#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_SHIFT (1U) -#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_CLRMSK (0xFFFFFF81U) -#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_SHIFT (0U) -#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_EN (0x00000001U) - - -/* - Register RGX_CR_CDM_TERMINATE_PDS -*/ -#define RGX_CR_CDM_TERMINATE_PDS (0x04B8U) -#define RGX_CR_CDM_TERMINATE_PDS_MASKFULL (IMG_UINT64_C(0xFFFFFFF0FFFFFFF0)) -#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_SHIFT (36U) -#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_CLRMSK (IMG_UINT64_C(0x0000000FFFFFFFFF)) -#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_ALIGNSIZE (16U) -#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_SHIFT (4U) -#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000000F)) -#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_ALIGNSIZE (16U) - - -/* - Register RGX_CR_CDM_TERMINATE_PDS1 -*/ -#define RGX_CR_CDM_TERMINATE_PDS1 (0x04C0U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__MASKFULL (IMG_UINT64_C(0x000000007FFFFFFF)) -#define RGX_CR_CDM_TERMINATE_PDS1_MASKFULL (IMG_UINT64_C(0x000000003FFFFFFF)) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0x40000000U) -#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_SHIFT (28U) -#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_EN (0x10000000U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_SHIFT (28U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_EN (0x10000000U) -#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_SHIFT (27U) -#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_EN (0x08000000U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0xF03FFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_SHIFT (21U) -#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_CLRMSK (0xF81FFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0x00200000U) -#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_SHIFT (20U) -#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_EN (0x00100000U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0xFFE00FFFU) -#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_SHIFT (11U) -#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_CLRMSK (0xFFF007FFU) -#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_CLRMSK (0xFFFFF87FU) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0xFFFFF07FU) -#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_SHIFT (1U) -#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_CLRMSK (0xFFFFFF81U) -#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_SHIFT (0U) -#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_EN (0x00000001U) - - -/* - Register RGX_CR_CDM_CONTEXT_LOAD_PDS0 -*/ -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0 (0x04D8U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_MASKFULL (IMG_UINT64_C(0xFFFFFFF0FFFFFFF0)) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_DATA_ADDR_SHIFT (36U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_DATA_ADDR_CLRMSK (IMG_UINT64_C(0x0000000FFFFFFFFF)) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_DATA_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_DATA_ADDR_ALIGNSIZE (16U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_CODE_ADDR_SHIFT (4U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_CODE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000000F)) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_CODE_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS0_CODE_ADDR_ALIGNSIZE (16U) - - -/* - Register RGX_CR_CDM_CONTEXT_LOAD_PDS1 -*/ -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1 (0x04E0U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__MASKFULL (IMG_UINT64_C(0x000000007FFFFFFF)) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_MASKFULL (IMG_UINT64_C(0x000000003FFFFFFF)) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0x40000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0x20000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_SHIFT (28U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_EN (0x10000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_SHIFT (28U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_EN (0x10000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_SHIFT (27U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_EN (0x08000000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0xF03FFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_SHIFT (21U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_CLRMSK (0xF81FFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0x00200000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_SHIFT (20U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_EN (0x00100000U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0xFFE00FFFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_SHIFT (11U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_CLRMSK (0xFFF007FFU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_CLRMSK (0xFFFFF87FU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0xFFFFF07FU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_SHIFT (1U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_CLRMSK (0xFFFFFF81U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_SHIFT (0U) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_CONFIG -*/ -#define RGX_CR_MIPS_WRAPPER_CONFIG (0x0810U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_MASKFULL (IMG_UINT64_C(0x000001030F01FFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_FW_IDLE_ENABLE_SHIFT (40U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_FW_IDLE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFEFFFFFFFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_FW_IDLE_ENABLE_EN (IMG_UINT64_C(0x0000010000000000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_DISABLE_BOOT_SHIFT (33U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_DISABLE_BOOT_CLRMSK (IMG_UINT64_C(0xFFFFFFFDFFFFFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_DISABLE_BOOT_EN (IMG_UINT64_C(0x0000000200000000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_SHIFT (32U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_OS_ID_SHIFT (25U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF1FFFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_SHIFT (24U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFEFFFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_EN (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_SHIFT (16U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFEFFFF)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MIPS32 (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_MIPS_WRAPPER_CONFIG_REGBANK_BASE_ADDR_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_CONFIG_REGBANK_BASE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP1_CONFIG1 -*/ -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1 (0x0818U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_MASKFULL (IMG_UINT64_C(0x00000000FFFFF001)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP1_CONFIG2 -*/ -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2 (0x0820U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF1FF)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_SHIFT (6U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFE3F)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_SHIFT (5U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_REGION_SIZE_POW2_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE0)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP2_CONFIG1 -*/ -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1 (0x0828U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_MASKFULL (IMG_UINT64_C(0x00000000FFFFF001)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP2_CONFIG2 -*/ -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2 (0x0830U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF1FF)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_OS_ID_SHIFT (6U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFE3F)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_SHIFT (5U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_REGION_SIZE_POW2_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE0)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP3_CONFIG1 -*/ -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1 (0x0838U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_MASKFULL (IMG_UINT64_C(0x00000000FFFFF001)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP3_CONFIG2 -*/ -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2 (0x0840U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF1FF)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_OS_ID_SHIFT (6U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFE3F)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_SHIFT (5U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_REGION_SIZE_POW2_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE0)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP4_CONFIG1 -*/ -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1 (0x0848U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MASKFULL (IMG_UINT64_C(0x00000000FFFFF001)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP4_CONFIG2 -*/ -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2 (0x0850U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF1FF)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_ADDR_OUT_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_ADDR_OUT_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_OS_ID_SHIFT (6U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFE3F)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_SHIFT (5U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_REGION_SIZE_POW2_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE0)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP5_CONFIG1 -*/ -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1 (0x0858U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MASKFULL (IMG_UINT64_C(0x00000000FFFFF001)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP5_CONFIG2 -*/ -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2 (0x0860U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF1FF)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_OS_ID_SHIFT (6U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFE3F)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_SHIFT (5U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_REGION_SIZE_POW2_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE0)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS -*/ -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS (0x0868U) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_MASKFULL (IMG_UINT64_C(0x00000001FFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_EVENT_SHIFT (32U) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_EVENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_EVENT_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_ADDRESS_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR -*/ -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR (0x0870U) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR_EVENT_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR_EVENT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_ADDR_REMAP_UNMAPPED_CLEAR_EVENT_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG -*/ -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG (0x0878U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_MASKFULL (IMG_UINT64_C(0xFFFFFFF7FFFFFFBF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_ADDR_OUT_SHIFT (36U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_ADDR_OUT_CLRMSK (IMG_UINT64_C(0x0000000FFFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_OS_ID_SHIFT (32U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFF8FFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_TRUSTED_SHIFT (11U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF7FF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_TRUSTED_EN (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_SHIFT (7U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF87F)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_4KB (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_16KB (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_64KB (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_256KB (IMG_UINT64_C(0x0000000000000180)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_1MB (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_4MB (IMG_UINT64_C(0x0000000000000280)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_16MB (IMG_UINT64_C(0x0000000000000300)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_64MB (IMG_UINT64_C(0x0000000000000380)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_REGION_SIZE_256MB (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_ENTRY_SHIFT (1U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_ENTRY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFC1)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_CONFIG_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP_RANGE_READ -*/ -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ (0x0880U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_MASKFULL (IMG_UINT64_C(0x000000000000003F)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_ENTRY_SHIFT (1U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_ENTRY_CLRMSK (0xFFFFFFC1U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_REQUEST_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_REQUEST_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_READ_REQUEST_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA -*/ -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA (0x0888U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_MASKFULL (IMG_UINT64_C(0xFFFFFFF7FFFFFF81)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_ADDR_OUT_SHIFT (36U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_ADDR_OUT_CLRMSK (IMG_UINT64_C(0x0000000FFFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_OS_ID_SHIFT (32U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_OS_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFF8FFFFFFFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_BASE_ADDR_IN_SHIFT (12U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000FFF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_TRUSTED_SHIFT (11U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_TRUSTED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF7FF)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_TRUSTED_EN (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_REGION_SIZE_SHIFT (7U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_REGION_SIZE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF87F)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_MODE_ENABLE_SHIFT (0U) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MIPS_ADDR_REMAP_RANGE_DATA_MODE_ENABLE_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MIPS_WRAPPER_IRQ_ENABLE -*/ -#define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE (0x08A0U) -#define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE_EVENT_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE_EVENT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE_EVENT_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_IRQ_STATUS -*/ -#define RGX_CR_MIPS_WRAPPER_IRQ_STATUS (0x08A8U) -#define RGX_CR_MIPS_WRAPPER_IRQ_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_IRQ_CLEAR -*/ -#define RGX_CR_MIPS_WRAPPER_IRQ_CLEAR (0x08B0U) -#define RGX_CR_MIPS_WRAPPER_IRQ_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_NMI_ENABLE -*/ -#define RGX_CR_MIPS_WRAPPER_NMI_ENABLE (0x08B8U) -#define RGX_CR_MIPS_WRAPPER_NMI_ENABLE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_WRAPPER_NMI_ENABLE_EVENT_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_NMI_ENABLE_EVENT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_WRAPPER_NMI_ENABLE_EVENT_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_NMI_EVENT -*/ -#define RGX_CR_MIPS_WRAPPER_NMI_EVENT (0x08C0U) -#define RGX_CR_MIPS_WRAPPER_NMI_EVENT_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_WRAPPER_NMI_EVENT_TRIGGER_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_NMI_EVENT_TRIGGER_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_WRAPPER_NMI_EVENT_TRIGGER_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_DEBUG_CONFIG -*/ -#define RGX_CR_MIPS_DEBUG_CONFIG (0x08C8U) -#define RGX_CR_MIPS_DEBUG_CONFIG_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_MIPS_DEBUG_CONFIG_DISABLE_PROBE_DEBUG_SHIFT (0U) -#define RGX_CR_MIPS_DEBUG_CONFIG_DISABLE_PROBE_DEBUG_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_DEBUG_CONFIG_DISABLE_PROBE_DEBUG_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_EXCEPTION_STATUS -*/ -#define RGX_CR_MIPS_EXCEPTION_STATUS (0x08D0U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000003F)) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_SLEEP_SHIFT (5U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_SLEEP_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_SLEEP_EN (0x00000020U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_SHIFT (4U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_EN (0x00000010U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_EXL_SHIFT (3U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_EXL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_EXL_EN (0x00000008U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_ERL_SHIFT (2U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_ERL_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_NEST_ERL_EN (0x00000004U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_EXL_SHIFT (1U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_EXL_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_EXL_EN (0x00000002U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_SHIFT (0U) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_EN (0x00000001U) - - -/* - Register RGX_CR_MIPS_WRAPPER_STATUS -*/ -#define RGX_CR_MIPS_WRAPPER_STATUS (0x08E8U) -#define RGX_CR_MIPS_WRAPPER_STATUS_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_MIPS_WRAPPER_STATUS_OUTSTANDING_REQUESTS_SHIFT (0U) -#define RGX_CR_MIPS_WRAPPER_STATUS_OUTSTANDING_REQUESTS_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_XPU_BROADCAST -*/ -#define RGX_CR_XPU_BROADCAST (0x0890U) -#define RGX_CR_XPU_BROADCAST_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_XPU_BROADCAST_MASK_SHIFT (0U) -#define RGX_CR_XPU_BROADCAST_MASK_CLRMSK (0xFFFFFE00U) - - -/* - Register RGX_CR_META_SP_MSLVDATAX -*/ -#define RGX_CR_META_SP_MSLVDATAX (0x0A00U) -#define RGX_CR_META_SP_MSLVDATAX_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_META_SP_MSLVDATAX_MSLVDATAX_SHIFT (0U) -#define RGX_CR_META_SP_MSLVDATAX_MSLVDATAX_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_META_SP_MSLVDATAT -*/ -#define RGX_CR_META_SP_MSLVDATAT (0x0A08U) -#define RGX_CR_META_SP_MSLVDATAT_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_META_SP_MSLVDATAT_MSLVDATAT_SHIFT (0U) -#define RGX_CR_META_SP_MSLVDATAT_MSLVDATAT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_META_SP_MSLVCTRL0 -*/ -#define RGX_CR_META_SP_MSLVCTRL0 (0x0A10U) -#define RGX_CR_META_SP_MSLVCTRL0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_META_SP_MSLVCTRL0_ADDR_SHIFT (2U) -#define RGX_CR_META_SP_MSLVCTRL0_ADDR_CLRMSK (0x00000003U) -#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_SHIFT (1U) -#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_EN (0x00000002U) -#define RGX_CR_META_SP_MSLVCTRL0_RD_SHIFT (0U) -#define RGX_CR_META_SP_MSLVCTRL0_RD_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_META_SP_MSLVCTRL0_RD_EN (0x00000001U) - - -/* - Register RGX_CR_META_SP_MSLVCTRL1 -*/ -#define RGX_CR_META_SP_MSLVCTRL1 (0x0A18U) -#define RGX_CR_META_SP_MSLVCTRL1_MASKFULL (IMG_UINT64_C(0x00000000F7F4003F)) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERRTHREAD_SHIFT (30U) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERRTHREAD_CLRMSK (0x3FFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_SHIFT (29U) -#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_EN (0x20000000U) -#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_SHIFT (28U) -#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_EN (0x10000000U) -#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_SHIFT (26U) -#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_CLRMSK (0xFBFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN (0x04000000U) -#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_SHIFT (25U) -#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_CLRMSK (0xFDFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_EN (0x02000000U) -#define RGX_CR_META_SP_MSLVCTRL1_READY_SHIFT (24U) -#define RGX_CR_META_SP_MSLVCTRL1_READY_CLRMSK (0xFEFFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_READY_EN (0x01000000U) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERRID_SHIFT (21U) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERRID_CLRMSK (0xFF1FFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_SHIFT (20U) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_EN (0x00100000U) -#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_SHIFT (18U) -#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_EN (0x00040000U) -#define RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT (4U) -#define RGX_CR_META_SP_MSLVCTRL1_THREAD_CLRMSK (0xFFFFFFCFU) -#define RGX_CR_META_SP_MSLVCTRL1_TRANS_SIZE_SHIFT (2U) -#define RGX_CR_META_SP_MSLVCTRL1_TRANS_SIZE_CLRMSK (0xFFFFFFF3U) -#define RGX_CR_META_SP_MSLVCTRL1_BYTE_ROUND_SHIFT (0U) -#define RGX_CR_META_SP_MSLVCTRL1_BYTE_ROUND_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_META_SP_MSLVHANDSHKE -*/ -#define RGX_CR_META_SP_MSLVHANDSHKE (0x0A50U) -#define RGX_CR_META_SP_MSLVHANDSHKE_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_META_SP_MSLVHANDSHKE_INPUT_SHIFT (2U) -#define RGX_CR_META_SP_MSLVHANDSHKE_INPUT_CLRMSK (0xFFFFFFF3U) -#define RGX_CR_META_SP_MSLVHANDSHKE_OUTPUT_SHIFT (0U) -#define RGX_CR_META_SP_MSLVHANDSHKE_OUTPUT_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_META_SP_MSLVT0KICK -*/ -#define RGX_CR_META_SP_MSLVT0KICK (0x0A80U) -#define RGX_CR_META_SP_MSLVT0KICK_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT0KICK_MSLVT0KICK_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT0KICK_MSLVT0KICK_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT0KICKI -*/ -#define RGX_CR_META_SP_MSLVT0KICKI (0x0A88U) -#define RGX_CR_META_SP_MSLVT0KICKI_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT0KICKI_MSLVT0KICKI_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT0KICKI_MSLVT0KICKI_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT1KICK -*/ -#define RGX_CR_META_SP_MSLVT1KICK (0x0A90U) -#define RGX_CR_META_SP_MSLVT1KICK_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT1KICK_MSLVT1KICK_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT1KICK_MSLVT1KICK_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT1KICKI -*/ -#define RGX_CR_META_SP_MSLVT1KICKI (0x0A98U) -#define RGX_CR_META_SP_MSLVT1KICKI_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT1KICKI_MSLVT1KICKI_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT1KICKI_MSLVT1KICKI_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT2KICK -*/ -#define RGX_CR_META_SP_MSLVT2KICK (0x0AA0U) -#define RGX_CR_META_SP_MSLVT2KICK_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT2KICK_MSLVT2KICK_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT2KICK_MSLVT2KICK_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT2KICKI -*/ -#define RGX_CR_META_SP_MSLVT2KICKI (0x0AA8U) -#define RGX_CR_META_SP_MSLVT2KICKI_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT2KICKI_MSLVT2KICKI_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT2KICKI_MSLVT2KICKI_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT3KICK -*/ -#define RGX_CR_META_SP_MSLVT3KICK (0x0AB0U) -#define RGX_CR_META_SP_MSLVT3KICK_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT3KICK_MSLVT3KICK_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT3KICK_MSLVT3KICK_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVT3KICKI -*/ -#define RGX_CR_META_SP_MSLVT3KICKI (0x0AB8U) -#define RGX_CR_META_SP_MSLVT3KICKI_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_META_SP_MSLVT3KICKI_MSLVT3KICKI_SHIFT (0U) -#define RGX_CR_META_SP_MSLVT3KICKI_MSLVT3KICKI_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_META_SP_MSLVRST -*/ -#define RGX_CR_META_SP_MSLVRST (0x0AC0U) -#define RGX_CR_META_SP_MSLVRST_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_META_SP_MSLVRST_SOFTRESET_SHIFT (0U) -#define RGX_CR_META_SP_MSLVRST_SOFTRESET_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_META_SP_MSLVRST_SOFTRESET_EN (0x00000001U) - - -/* - Register RGX_CR_META_SP_MSLVIRQSTATUS -*/ -#define RGX_CR_META_SP_MSLVIRQSTATUS (0x0AC8U) -#define RGX_CR_META_SP_MSLVIRQSTATUS_MASKFULL (IMG_UINT64_C(0x000000000000000C)) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_SHIFT (3U) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_EN (0x00000008U) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_SHIFT (2U) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN (0x00000004U) - - -/* - Register RGX_CR_META_SP_MSLVIRQENABLE -*/ -#define RGX_CR_META_SP_MSLVIRQENABLE (0x0AD0U) -#define RGX_CR_META_SP_MSLVIRQENABLE_MASKFULL (IMG_UINT64_C(0x000000000000000C)) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_SHIFT (3U) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_EN (0x00000008U) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_SHIFT (2U) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_EN (0x00000004U) - - -/* - Register RGX_CR_META_SP_MSLVIRQLEVEL -*/ -#define RGX_CR_META_SP_MSLVIRQLEVEL (0x0AD8U) -#define RGX_CR_META_SP_MSLVIRQLEVEL_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_SHIFT (0U) -#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_EN (0x00000001U) - - -/* - Register RGX_CR_MTS_SCHEDULE -*/ -#define RGX_CR_MTS_SCHEDULE (0x0B00U) -#define RGX_CR_MTS_SCHEDULE_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE1 -*/ -#define RGX_CR_MTS_SCHEDULE1 (0x10B00U) -#define RGX_CR_MTS_SCHEDULE1_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE1_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE1_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE1_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE1_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE1_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE1_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE1_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE1_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE1_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE1_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE1_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE1_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE1_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE1_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE1_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE2 -*/ -#define RGX_CR_MTS_SCHEDULE2 (0x20B00U) -#define RGX_CR_MTS_SCHEDULE2_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE2_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE2_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE2_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE2_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE2_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE2_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE2_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE2_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE2_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE2_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE2_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE2_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE2_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE2_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE2_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE3 -*/ -#define RGX_CR_MTS_SCHEDULE3 (0x30B00U) -#define RGX_CR_MTS_SCHEDULE3_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE3_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE3_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE3_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE3_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE3_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE3_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE3_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE3_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE3_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE3_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE3_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE3_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE3_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE3_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE3_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE4 -*/ -#define RGX_CR_MTS_SCHEDULE4 (0x40B00U) -#define RGX_CR_MTS_SCHEDULE4_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE4_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE4_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE4_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE4_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE4_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE4_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE4_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE4_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE4_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE4_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE4_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE4_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE4_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE4_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE4_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE5 -*/ -#define RGX_CR_MTS_SCHEDULE5 (0x50B00U) -#define RGX_CR_MTS_SCHEDULE5_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE5_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE5_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE5_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE5_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE5_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE5_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE5_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE5_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE5_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE5_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE5_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE5_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE5_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE5_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE5_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE6 -*/ -#define RGX_CR_MTS_SCHEDULE6 (0x60B00U) -#define RGX_CR_MTS_SCHEDULE6_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE6_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE6_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE6_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE6_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE6_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE6_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE6_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE6_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE6_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE6_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE6_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE6_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE6_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE6_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE6_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_SCHEDULE7 -*/ -#define RGX_CR_MTS_SCHEDULE7 (0x70B00U) -#define RGX_CR_MTS_SCHEDULE7_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_MTS_SCHEDULE7_HOST_SHIFT (8U) -#define RGX_CR_MTS_SCHEDULE7_HOST_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_MTS_SCHEDULE7_HOST_BG_TIMER (0x00000000U) -#define RGX_CR_MTS_SCHEDULE7_HOST_HOST (0x00000100U) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_SHIFT (6U) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT1 (0x00000040U) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT2 (0x00000080U) -#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT3 (0x000000C0U) -#define RGX_CR_MTS_SCHEDULE7_CONTEXT_SHIFT (5U) -#define RGX_CR_MTS_SCHEDULE7_CONTEXT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SCHEDULE7_CONTEXT_BGCTX (0x00000000U) -#define RGX_CR_MTS_SCHEDULE7_CONTEXT_INTCTX (0x00000020U) -#define RGX_CR_MTS_SCHEDULE7_TASK_SHIFT (4U) -#define RGX_CR_MTS_SCHEDULE7_TASK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SCHEDULE7_TASK_NON_COUNTED (0x00000000U) -#define RGX_CR_MTS_SCHEDULE7_TASK_COUNTED (0x00000010U) -#define RGX_CR_MTS_SCHEDULE7_DM_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE7_DM_CLRMSK (0xFFFFFFF0U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM0 (0x00000000U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM1 (0x00000001U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM2 (0x00000002U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM3 (0x00000003U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM4 (0x00000004U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM5 (0x00000005U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM6 (0x00000006U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM7 (0x00000007U) -#define RGX_CR_MTS_SCHEDULE7_DM_DM_ALL (0x0000000FU) - - -/* - Register RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC -*/ -#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC (0x0B30U) -#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_SHIFT (0U) -#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC -*/ -#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC (0x0B38U) -#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_SHIFT (0U) -#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC -*/ -#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC (0x0B40U) -#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_SHIFT (0U) -#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC -*/ -#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC (0x0B48U) -#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_SHIFT (0U) -#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_MTS_GARTEN_WRAPPER_CONFIG -*/ -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG (0x0B50U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__MASKFULL (IMG_UINT64_C(0x000FF0FFFFFFF701)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_MASKFULL (IMG_UINT64_C(0x0000FFFFFFFFF001)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT (44U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0xFFFF0FFFFFFFFFFF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_SHIFT (44U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0xFFF00FFFFFFFFFFF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT (40U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_CLRMSK (IMG_UINT64_C(0xFFFFF0FFFFFFFFFF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_SHIFT (12U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_SHIFT (9U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF9FF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_SHIFT (8U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_EN (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_SHIFT (0U) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MTS_DM0_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM0_INTERRUPT_ENABLE (0x0B58U) -#define RGX_CR_MTS_DM0_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM0_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM0_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_DM1_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM1_INTERRUPT_ENABLE (0x0B60U) -#define RGX_CR_MTS_DM1_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM1_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM1_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_DM2_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM2_INTERRUPT_ENABLE (0x0B68U) -#define RGX_CR_MTS_DM2_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM2_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM2_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_DM3_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM3_INTERRUPT_ENABLE (0x0B70U) -#define RGX_CR_MTS_DM3_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM3_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM3_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_DM4_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM4_INTERRUPT_ENABLE (0x0B78U) -#define RGX_CR_MTS_DM4_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM4_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM4_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_DM5_INTERRUPT_ENABLE -*/ -#define RGX_CR_MTS_DM5_INTERRUPT_ENABLE (0x0B80U) -#define RGX_CR_MTS_DM5_INTERRUPT_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_DM5_INTERRUPT_ENABLE_INT_ENABLE_SHIFT (0U) -#define RGX_CR_MTS_DM5_INTERRUPT_ENABLE_INT_ENABLE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_INTCTX -*/ -#define RGX_CR_MTS_INTCTX (0x0B98U) -#define RGX_CR_MTS_INTCTX_MASKFULL (IMG_UINT64_C(0x000000003FFFFFFF)) -#define RGX_CR_MTS_INTCTX_DM_HOST_SCHEDULE_SHIFT (22U) -#define RGX_CR_MTS_INTCTX_DM_HOST_SCHEDULE_CLRMSK (0xC03FFFFFU) -#define RGX_CR_MTS_INTCTX_DM_PTR_SHIFT (18U) -#define RGX_CR_MTS_INTCTX_DM_PTR_CLRMSK (0xFFC3FFFFU) -#define RGX_CR_MTS_INTCTX_THREAD_ACTIVE_SHIFT (16U) -#define RGX_CR_MTS_INTCTX_THREAD_ACTIVE_CLRMSK (0xFFFCFFFFU) -#define RGX_CR_MTS_INTCTX_DM_TIMER_SCHEDULE_SHIFT (8U) -#define RGX_CR_MTS_INTCTX_DM_TIMER_SCHEDULE_CLRMSK (0xFFFF00FFU) -#define RGX_CR_MTS_INTCTX_DM_INTERRUPT_SCHEDULE_SHIFT (0U) -#define RGX_CR_MTS_INTCTX_DM_INTERRUPT_SCHEDULE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_MTS_BGCTX -*/ -#define RGX_CR_MTS_BGCTX (0x0BA0U) -#define RGX_CR_MTS_BGCTX_MASKFULL (IMG_UINT64_C(0x0000000000003FFF)) -#define RGX_CR_MTS_BGCTX_DM_PTR_SHIFT (10U) -#define RGX_CR_MTS_BGCTX_DM_PTR_CLRMSK (0xFFFFC3FFU) -#define RGX_CR_MTS_BGCTX_THREAD_ACTIVE_SHIFT (8U) -#define RGX_CR_MTS_BGCTX_THREAD_ACTIVE_CLRMSK (0xFFFFFCFFU) -#define RGX_CR_MTS_BGCTX_DM_NONCOUNTED_SCHEDULE_SHIFT (0U) -#define RGX_CR_MTS_BGCTX_DM_NONCOUNTED_SCHEDULE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE -*/ -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE (0x0BA8U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_SHIFT (56U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_CLRMSK (IMG_UINT64_C(0x00FFFFFFFFFFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_SHIFT (48U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_CLRMSK (IMG_UINT64_C(0xFF00FFFFFFFFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_SHIFT (40U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_CLRMSK (IMG_UINT64_C(0xFFFF00FFFFFFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM4_SHIFT (32U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM4_CLRMSK (IMG_UINT64_C(0xFFFFFF00FFFFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM3_SHIFT (24U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM3_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00FFFFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM2_SHIFT (16U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF00FFFF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM1_SHIFT (8U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM1_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF00FF)) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM0_SHIFT (0U) -#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF00)) - - -/* - Register RGX_CR_MTS_GPU_INT_STATUS -*/ -#define RGX_CR_MTS_GPU_INT_STATUS (0x0BB0U) -#define RGX_CR_MTS_GPU_INT_STATUS_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MTS_GPU_INT_STATUS_STATUS_SHIFT (0U) -#define RGX_CR_MTS_GPU_INT_STATUS_STATUS_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_MTS_SCHEDULE_ENABLE -*/ -#define RGX_CR_MTS_SCHEDULE_ENABLE (0x0BC8U) -#define RGX_CR_MTS_SCHEDULE_ENABLE_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_MTS_SCHEDULE_ENABLE_MASK_SHIFT (0U) -#define RGX_CR_MTS_SCHEDULE_ENABLE_MASK_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_IRQ_OS0_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS0_EVENT_STATUS (0x0BD8U) -#define RGX_CR_IRQ_OS0_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS0_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS0_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS0_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS0_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS0_EVENT_CLEAR (0x0BE8U) -#define RGX_CR_IRQ_OS0_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS0_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS0_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS0_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS1_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS1_EVENT_STATUS (0x10BD8U) -#define RGX_CR_IRQ_OS1_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS1_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS1_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS1_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS1_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS1_EVENT_CLEAR (0x10BE8U) -#define RGX_CR_IRQ_OS1_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS1_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS1_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS1_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS2_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS2_EVENT_STATUS (0x20BD8U) -#define RGX_CR_IRQ_OS2_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS2_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS2_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS2_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS2_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS2_EVENT_CLEAR (0x20BE8U) -#define RGX_CR_IRQ_OS2_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS2_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS2_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS2_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS3_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS3_EVENT_STATUS (0x30BD8U) -#define RGX_CR_IRQ_OS3_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS3_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS3_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS3_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS3_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS3_EVENT_CLEAR (0x30BE8U) -#define RGX_CR_IRQ_OS3_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS3_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS3_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS3_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS4_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS4_EVENT_STATUS (0x40BD8U) -#define RGX_CR_IRQ_OS4_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS4_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS4_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS4_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS4_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS4_EVENT_CLEAR (0x40BE8U) -#define RGX_CR_IRQ_OS4_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS4_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS4_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS4_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS5_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS5_EVENT_STATUS (0x50BD8U) -#define RGX_CR_IRQ_OS5_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS5_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS5_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS5_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS5_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS5_EVENT_CLEAR (0x50BE8U) -#define RGX_CR_IRQ_OS5_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS5_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS5_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS5_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS6_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS6_EVENT_STATUS (0x60BD8U) -#define RGX_CR_IRQ_OS6_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS6_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS6_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS6_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS6_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS6_EVENT_CLEAR (0x60BE8U) -#define RGX_CR_IRQ_OS6_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS6_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS6_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS6_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS7_EVENT_STATUS -*/ -#define RGX_CR_IRQ_OS7_EVENT_STATUS (0x70BD8U) -#define RGX_CR_IRQ_OS7_EVENT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS7_EVENT_STATUS_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS7_EVENT_STATUS_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS7_EVENT_STATUS_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_IRQ_OS7_EVENT_CLEAR -*/ -#define RGX_CR_IRQ_OS7_EVENT_CLEAR (0x70BE8U) -#define RGX_CR_IRQ_OS7_EVENT_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_IRQ_OS7_EVENT_CLEAR_SOURCE_SHIFT (0U) -#define RGX_CR_IRQ_OS7_EVENT_CLEAR_SOURCE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_IRQ_OS7_EVENT_CLEAR_SOURCE_EN (0x00000001U) - - -/* - Register RGX_CR_META_BOOT -*/ -#define RGX_CR_META_BOOT (0x0BF8U) -#define RGX_CR_META_BOOT_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_META_BOOT_MODE_SHIFT (0U) -#define RGX_CR_META_BOOT_MODE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_META_BOOT_MODE_EN (0x00000001U) - - -/* - Register RGX_CR_GARTEN_SLC -*/ -#define RGX_CR_GARTEN_SLC (0x0BB8U) -#define RGX_CR_GARTEN_SLC_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_SHIFT (0U) -#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_EN (0x00000001U) - - -/* - Register RGX_CR_PPP -*/ -#define RGX_CR_PPP (0x0CD0U) -#define RGX_CR_PPP_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PPP_CHECKSUM_SHIFT (0U) -#define RGX_CR_PPP_CHECKSUM_CLRMSK (0x00000000U) - - -#define RGX_CR_ISP_RENDER_DIR_TYPE_MASK (0x00000003U) -/* -Top-left to bottom-right */ -#define RGX_CR_ISP_RENDER_DIR_TYPE_TL2BR (0x00000000U) -/* -Top-right to bottom-left */ -#define RGX_CR_ISP_RENDER_DIR_TYPE_TR2BL (0x00000001U) -/* -Bottom-left to top-right */ -#define RGX_CR_ISP_RENDER_DIR_TYPE_BL2TR (0x00000002U) -/* -Bottom-right to top-left */ -#define RGX_CR_ISP_RENDER_DIR_TYPE_BR2TL (0x00000003U) - - -#define RGX_CR_ISP_RENDER_MODE_TYPE_MASK (0x00000003U) -/* -Normal render */ -#define RGX_CR_ISP_RENDER_MODE_TYPE_NORM (0x00000000U) -/* -Fast 2D render */ -#define RGX_CR_ISP_RENDER_MODE_TYPE_FAST_2D (0x00000002U) -/* -Fast scale render */ -#define RGX_CR_ISP_RENDER_MODE_TYPE_FAST_SCALE (0x00000003U) - - -/* - Register RGX_CR_ISP_RENDER -*/ -#define RGX_CR_ISP_RENDER (0x0F08U) -#define RGX_CR_ISP_RENDER_MASKFULL (IMG_UINT64_C(0x00000000000001FF)) -#define RGX_CR_ISP_RENDER_FAST_RENDER_FORCE_PROTECT_SHIFT (8U) -#define RGX_CR_ISP_RENDER_FAST_RENDER_FORCE_PROTECT_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_ISP_RENDER_FAST_RENDER_FORCE_PROTECT_EN (0x00000100U) -#define RGX_CR_ISP_RENDER_PROCESS_PROTECTED_TILES_SHIFT (7U) -#define RGX_CR_ISP_RENDER_PROCESS_PROTECTED_TILES_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_ISP_RENDER_PROCESS_PROTECTED_TILES_EN (0x00000080U) -#define RGX_CR_ISP_RENDER_PROCESS_UNPROTECTED_TILES_SHIFT (6U) -#define RGX_CR_ISP_RENDER_PROCESS_UNPROTECTED_TILES_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_ISP_RENDER_PROCESS_UNPROTECTED_TILES_EN (0x00000040U) -#define RGX_CR_ISP_RENDER_DISABLE_EOMT_SHIFT (5U) -#define RGX_CR_ISP_RENDER_DISABLE_EOMT_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_ISP_RENDER_DISABLE_EOMT_EN (0x00000020U) -#define RGX_CR_ISP_RENDER_RESUME_SHIFT (4U) -#define RGX_CR_ISP_RENDER_RESUME_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_ISP_RENDER_RESUME_EN (0x00000010U) -#define RGX_CR_ISP_RENDER_DIR_SHIFT (2U) -#define RGX_CR_ISP_RENDER_DIR_CLRMSK (0xFFFFFFF3U) -#define RGX_CR_ISP_RENDER_DIR_TL2BR (0x00000000U) -#define RGX_CR_ISP_RENDER_DIR_TR2BL (0x00000004U) -#define RGX_CR_ISP_RENDER_DIR_BL2TR (0x00000008U) -#define RGX_CR_ISP_RENDER_DIR_BR2TL (0x0000000CU) -#define RGX_CR_ISP_RENDER_MODE_SHIFT (0U) -#define RGX_CR_ISP_RENDER_MODE_CLRMSK (0xFFFFFFFCU) -#define RGX_CR_ISP_RENDER_MODE_NORM (0x00000000U) -#define RGX_CR_ISP_RENDER_MODE_FAST_2D (0x00000002U) -#define RGX_CR_ISP_RENDER_MODE_FAST_SCALE (0x00000003U) - - -/* - Register RGX_CR_ISP_CTL -*/ -#define RGX_CR_ISP_CTL (0x0F38U) -#define RGX_CR_ISP_CTL_MASKFULL (IMG_UINT64_C(0x00000000FFFFF3FF)) -#define RGX_CR_ISP_CTL_SKIP_INIT_HDRS_SHIFT (31U) -#define RGX_CR_ISP_CTL_SKIP_INIT_HDRS_CLRMSK (0x7FFFFFFFU) -#define RGX_CR_ISP_CTL_SKIP_INIT_HDRS_EN (0x80000000U) -#define RGX_CR_ISP_CTL_LINE_STYLE_SHIFT (30U) -#define RGX_CR_ISP_CTL_LINE_STYLE_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_ISP_CTL_LINE_STYLE_EN (0x40000000U) -#define RGX_CR_ISP_CTL_LINE_STYLE_PIX_SHIFT (29U) -#define RGX_CR_ISP_CTL_LINE_STYLE_PIX_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_ISP_CTL_LINE_STYLE_PIX_EN (0x20000000U) -#define RGX_CR_ISP_CTL_PAIR_TILES_VERT_SHIFT (28U) -#define RGX_CR_ISP_CTL_PAIR_TILES_VERT_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_ISP_CTL_PAIR_TILES_VERT_EN (0x10000000U) -#define RGX_CR_ISP_CTL_PAIR_TILES_SHIFT (27U) -#define RGX_CR_ISP_CTL_PAIR_TILES_CLRMSK (0xF7FFFFFFU) -#define RGX_CR_ISP_CTL_PAIR_TILES_EN (0x08000000U) -#define RGX_CR_ISP_CTL_CREQ_BUF_EN_SHIFT (26U) -#define RGX_CR_ISP_CTL_CREQ_BUF_EN_CLRMSK (0xFBFFFFFFU) -#define RGX_CR_ISP_CTL_CREQ_BUF_EN_EN (0x04000000U) -#define RGX_CR_ISP_CTL_TILE_AGE_EN_SHIFT (25U) -#define RGX_CR_ISP_CTL_TILE_AGE_EN_CLRMSK (0xFDFFFFFFU) -#define RGX_CR_ISP_CTL_TILE_AGE_EN_EN (0x02000000U) -#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_SHIFT (23U) -#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_CLRMSK (0xFE7FFFFFU) -#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_DX9 (0x00000000U) -#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_DX10 (0x00800000U) -#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_OGL (0x01000000U) -#define RGX_CR_ISP_CTL_NUM_TILES_PER_USC_SHIFT (21U) -#define RGX_CR_ISP_CTL_NUM_TILES_PER_USC_CLRMSK (0xFF9FFFFFU) -#define RGX_CR_ISP_CTL_DBIAS_IS_INT_SHIFT (20U) -#define RGX_CR_ISP_CTL_DBIAS_IS_INT_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_ISP_CTL_DBIAS_IS_INT_EN (0x00100000U) -#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_SHIFT (19U) -#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_EN (0x00080000U) -#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_SHIFT (18U) -#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_EN (0x00040000U) -#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_SHIFT (17U) -#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_EN (0x00020000U) -#define RGX_CR_ISP_CTL_SAMPLE_POS_SHIFT (16U) -#define RGX_CR_ISP_CTL_SAMPLE_POS_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_ISP_CTL_SAMPLE_POS_EN (0x00010000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_SHIFT (12U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_ONE (0x00000000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TWO (0x00001000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_THREE (0x00002000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FOUR (0x00003000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FIVE (0x00004000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SIX (0x00005000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SEVEN (0x00006000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_EIGHT (0x00007000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_NINE (0x00008000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TEN (0x00009000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_ELEVEN (0x0000A000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TWELVE (0x0000B000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_THIRTEEN (0x0000C000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FOURTEEN (0x0000D000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FIFTEEN (0x0000E000U) -#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SIXTEEN (0x0000F000U) -#define RGX_CR_ISP_CTL_VALID_ID_SHIFT (4U) -#define RGX_CR_ISP_CTL_VALID_ID_CLRMSK (0xFFFFFC0FU) -#define RGX_CR_ISP_CTL_UPASS_START_SHIFT (0U) -#define RGX_CR_ISP_CTL_UPASS_START_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_ISP_STATUS -*/ -#define RGX_CR_ISP_STATUS (0x1038U) -#define RGX_CR_ISP_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_ISP_STATUS_SPLIT_MAX_SHIFT (2U) -#define RGX_CR_ISP_STATUS_SPLIT_MAX_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_ISP_STATUS_SPLIT_MAX_EN (0x00000004U) -#define RGX_CR_ISP_STATUS_ACTIVE_SHIFT (1U) -#define RGX_CR_ISP_STATUS_ACTIVE_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_ISP_STATUS_ACTIVE_EN (0x00000002U) -#define RGX_CR_ISP_STATUS_EOR_SHIFT (0U) -#define RGX_CR_ISP_STATUS_EOR_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_ISP_STATUS_EOR_EN (0x00000001U) - - -/* - Register group: RGX_CR_ISP_XTP_RESUME, with 64 repeats -*/ -#define RGX_CR_ISP_XTP_RESUME_REPEATCOUNT (64U) -/* - Register RGX_CR_ISP_XTP_RESUME0 -*/ -#define RGX_CR_ISP_XTP_RESUME0 (0x3A00U) -#define RGX_CR_ISP_XTP_RESUME0_MASKFULL (IMG_UINT64_C(0x00000000003FF3FF)) -#define RGX_CR_ISP_XTP_RESUME0_TILE_X_SHIFT (12U) -#define RGX_CR_ISP_XTP_RESUME0_TILE_X_CLRMSK (0xFFC00FFFU) -#define RGX_CR_ISP_XTP_RESUME0_TILE_Y_SHIFT (0U) -#define RGX_CR_ISP_XTP_RESUME0_TILE_Y_CLRMSK (0xFFFFFC00U) - - -/* - Register group: RGX_CR_ISP_XTP_STORE, with 32 repeats -*/ -#define RGX_CR_ISP_XTP_STORE_REPEATCOUNT (32U) -/* - Register RGX_CR_ISP_XTP_STORE0 -*/ -#define RGX_CR_ISP_XTP_STORE0 (0x3C00U) -#define RGX_CR_ISP_XTP_STORE0_MASKFULL (IMG_UINT64_C(0x000000007F3FF3FF)) -#define RGX_CR_ISP_XTP_STORE0_ACTIVE_SHIFT (30U) -#define RGX_CR_ISP_XTP_STORE0_ACTIVE_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_ISP_XTP_STORE0_ACTIVE_EN (0x40000000U) -#define RGX_CR_ISP_XTP_STORE0_EOR_SHIFT (29U) -#define RGX_CR_ISP_XTP_STORE0_EOR_CLRMSK (0xDFFFFFFFU) -#define RGX_CR_ISP_XTP_STORE0_EOR_EN (0x20000000U) -#define RGX_CR_ISP_XTP_STORE0_TILE_LAST_SHIFT (28U) -#define RGX_CR_ISP_XTP_STORE0_TILE_LAST_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_ISP_XTP_STORE0_TILE_LAST_EN (0x10000000U) -#define RGX_CR_ISP_XTP_STORE0_MT_SHIFT (24U) -#define RGX_CR_ISP_XTP_STORE0_MT_CLRMSK (0xF0FFFFFFU) -#define RGX_CR_ISP_XTP_STORE0_TILE_X_SHIFT (12U) -#define RGX_CR_ISP_XTP_STORE0_TILE_X_CLRMSK (0xFFC00FFFU) -#define RGX_CR_ISP_XTP_STORE0_TILE_Y_SHIFT (0U) -#define RGX_CR_ISP_XTP_STORE0_TILE_Y_CLRMSK (0xFFFFFC00U) - - -/* - Register group: RGX_CR_BIF_CAT_BASE, with 8 repeats -*/ -#define RGX_CR_BIF_CAT_BASE_REPEATCOUNT (8U) -/* - Register RGX_CR_BIF_CAT_BASE0 -*/ -#define RGX_CR_BIF_CAT_BASE0 (0x1200U) -#define RGX_CR_BIF_CAT_BASE0_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE0_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE0_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE1 -*/ -#define RGX_CR_BIF_CAT_BASE1 (0x1208U) -#define RGX_CR_BIF_CAT_BASE1_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE1_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE1_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE1_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE1_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE2 -*/ -#define RGX_CR_BIF_CAT_BASE2 (0x1210U) -#define RGX_CR_BIF_CAT_BASE2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE2_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE2_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE2_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE2_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE3 -*/ -#define RGX_CR_BIF_CAT_BASE3 (0x1218U) -#define RGX_CR_BIF_CAT_BASE3_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE3_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE3_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE3_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE3_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE4 -*/ -#define RGX_CR_BIF_CAT_BASE4 (0x1220U) -#define RGX_CR_BIF_CAT_BASE4_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE4_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE4_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE4_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE4_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE5 -*/ -#define RGX_CR_BIF_CAT_BASE5 (0x1228U) -#define RGX_CR_BIF_CAT_BASE5_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE5_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE5_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE5_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE5_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE6 -*/ -#define RGX_CR_BIF_CAT_BASE6 (0x1230U) -#define RGX_CR_BIF_CAT_BASE6_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE6_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE6_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE6_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE6_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE7 -*/ -#define RGX_CR_BIF_CAT_BASE7 (0x1238U) -#define RGX_CR_BIF_CAT_BASE7_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_BIF_CAT_BASE7_ADDR_SHIFT (12U) -#define RGX_CR_BIF_CAT_BASE7_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_CAT_BASE7_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_BIF_CAT_BASE7_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_CAT_BASE_INDEX -*/ -#define RGX_CR_BIF_CAT_BASE_INDEX (0x1240U) -#define RGX_CR_BIF_CAT_BASE_INDEX_MASKFULL (IMG_UINT64_C(0x00070707073F0707)) -#define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_SHIFT (48U) -#define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_CLRMSK (IMG_UINT64_C(0xFFF8FFFFFFFFFFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_RAY_SHIFT (40U) -#define RGX_CR_BIF_CAT_BASE_INDEX_RAY_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_HOST_SHIFT (32U) -#define RGX_CR_BIF_CAT_BASE_INDEX_HOST_CLRMSK (IMG_UINT64_C(0xFFFFFFF8FFFFFFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_TLA_SHIFT (24U) -#define RGX_CR_BIF_CAT_BASE_INDEX_TLA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF8FFFFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_TDM_SHIFT (19U) -#define RGX_CR_BIF_CAT_BASE_INDEX_TDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFC7FFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_CDM_SHIFT (16U) -#define RGX_CR_BIF_CAT_BASE_INDEX_CDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF8FFFF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_SHIFT (8U) -#define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF8FF)) -#define RGX_CR_BIF_CAT_BASE_INDEX_TA_SHIFT (0U) -#define RGX_CR_BIF_CAT_BASE_INDEX_TA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF8)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_VCE0 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_VCE0 (0x1248U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_TE0 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_TE0 (0x1250U) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_ALIST0 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0 (0x1260U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_VCE1 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_VCE1 (0x1268U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_TE1 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_TE1 (0x1270U) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_PM_CAT_BASE_ALIST1 -*/ -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1 (0x1280U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFFF003)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_INIT_PAGE_SHIFT (40U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_INIT_PAGE_CLRMSK (IMG_UINT64_C(0xF00000FFFFFFFFFF)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_ADDR_SHIFT (12U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_SHIFT (1U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_SHIFT (0U) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_BIF_MMU_ENTRY_STATUS -*/ -#define RGX_CR_BIF_MMU_ENTRY_STATUS (0x1288U) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF0F3)) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_SHIFT (12U) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_SHIFT (4U) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF0F)) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_SHIFT (0U) -#define RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFC)) - - -/* - Register RGX_CR_BIF_MMU_ENTRY -*/ -#define RGX_CR_BIF_MMU_ENTRY (0x1290U) -#define RGX_CR_BIF_MMU_ENTRY_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_BIF_MMU_ENTRY_ENABLE_SHIFT (1U) -#define RGX_CR_BIF_MMU_ENTRY_ENABLE_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_MMU_ENTRY_ENABLE_EN (0x00000002U) -#define RGX_CR_BIF_MMU_ENTRY_PENDING_SHIFT (0U) -#define RGX_CR_BIF_MMU_ENTRY_PENDING_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_MMU_ENTRY_PENDING_EN (0x00000001U) - - -/* - Register RGX_CR_BIF_CTRL_INVAL -*/ -#define RGX_CR_BIF_CTRL_INVAL (0x12A0U) -#define RGX_CR_BIF_CTRL_INVAL_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_BIF_CTRL_INVAL_TLB1_SHIFT (3U) -#define RGX_CR_BIF_CTRL_INVAL_TLB1_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_BIF_CTRL_INVAL_TLB1_EN (0x00000008U) -#define RGX_CR_BIF_CTRL_INVAL_PC_SHIFT (2U) -#define RGX_CR_BIF_CTRL_INVAL_PC_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_CTRL_INVAL_PC_EN (0x00000004U) -#define RGX_CR_BIF_CTRL_INVAL_PD_SHIFT (1U) -#define RGX_CR_BIF_CTRL_INVAL_PD_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_CTRL_INVAL_PD_EN (0x00000002U) -#define RGX_CR_BIF_CTRL_INVAL_PT_SHIFT (0U) -#define RGX_CR_BIF_CTRL_INVAL_PT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_CTRL_INVAL_PT_EN (0x00000001U) - - -/* - Register RGX_CR_BIF_CTRL -*/ -#define RGX_CR_BIF_CTRL (0x12A8U) -#define RGX_CR_BIF_CTRL__XE_MEM__MASKFULL (IMG_UINT64_C(0x000000000000033F)) -#define RGX_CR_BIF_CTRL_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_CPU_SHIFT (9U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_CPU_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_CPU_EN (0x00000200U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF4_SHIFT (8U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF4_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF4_EN (0x00000100U) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_SHIFT (7U) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_EN (0x00000080U) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_SHIFT (6U) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_EN (0x00000040U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_SHIFT (5U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_EN (0x00000020U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_SHIFT (4U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_EN (0x00000010U) -#define RGX_CR_BIF_CTRL_PAUSE_BIF1_SHIFT (3U) -#define RGX_CR_BIF_CTRL_PAUSE_BIF1_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_BIF_CTRL_PAUSE_BIF1_EN (0x00000008U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_SHIFT (2U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_EN (0x00000004U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_SHIFT (1U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_EN (0x00000002U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_SHIFT (0U) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_EN (0x00000001U) - - -/* - Register RGX_CR_BIF_FAULT_BANK0_MMU_STATUS -*/ -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS (0x12B0U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000F775)) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT (12U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT (8U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK (0xFFFFF8FFU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT (5U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK (0xFFFFFF9FU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_SHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN (0x00000010U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN (0x00000004U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_SHIFT (0U) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_BIF_FAULT_BANK0_REQ_STATUS -*/ -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS (0x12B8U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__MASKFULL (IMG_UINT64_C(0x001FFFFFFFFFFFF0)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_MASKFULL (IMG_UINT64_C(0x0007FFFFFFFFFFF0)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__RNW_SHIFT (52U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__RNW_CLRMSK (IMG_UINT64_C(0xFFEFFFFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__RNW_EN (IMG_UINT64_C(0x0010000000000000)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_SHIFT (50U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_SHIFT (46U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_CLRMSK (IMG_UINT64_C(0xFFF03FFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT (44U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFFC0FFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT (40U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFF0FFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_SHIFT (40U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFC0FFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSIZE (16U) - - -/* - Register RGX_CR_BIF_FAULT_BANK1_MMU_STATUS -*/ -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS (0x12C0U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000F775)) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_CAT_BASE_SHIFT (12U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_CAT_BASE_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_PAGE_SIZE_SHIFT (8U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_PAGE_SIZE_CLRMSK (0xFFFFF8FFU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_DATA_TYPE_SHIFT (5U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_DATA_TYPE_CLRMSK (0xFFFFFF9FU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_SHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_EN (0x00000010U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_EN (0x00000004U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_SHIFT (0U) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_BIF_FAULT_BANK1_REQ_STATUS -*/ -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS (0x12C8U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_MASKFULL (IMG_UINT64_C(0x0007FFFFFFFFFFF0)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_SHIFT (50U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_SB_SHIFT (44U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFFC0FFFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_ID_SHIFT (40U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFF0FFFFFFFFFF)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_SHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U) -#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_ALIGNSIZE (16U) - - -/* - Register RGX_CR_BIF_MMU_STATUS -*/ -#define RGX_CR_BIF_MMU_STATUS (0x12D0U) -#define RGX_CR_BIF_MMU_STATUS__XE_MEM__MASKFULL (IMG_UINT64_C(0x000000001FFFFFF7)) -#define RGX_CR_BIF_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000001FFFFFF7)) -#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_SHIFT (28U) -#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_EN (0x10000000U) -#define RGX_CR_BIF_MMU_STATUS_PC_DATA_SHIFT (20U) -#define RGX_CR_BIF_MMU_STATUS_PC_DATA_CLRMSK (0xF00FFFFFU) -#define RGX_CR_BIF_MMU_STATUS_PD_DATA_SHIFT (12U) -#define RGX_CR_BIF_MMU_STATUS_PD_DATA_CLRMSK (0xFFF00FFFU) -#define RGX_CR_BIF_MMU_STATUS_PT_DATA_SHIFT (4U) -#define RGX_CR_BIF_MMU_STATUS_PT_DATA_CLRMSK (0xFFFFF00FU) -#define RGX_CR_BIF_MMU_STATUS_STALLED_SHIFT (2U) -#define RGX_CR_BIF_MMU_STATUS_STALLED_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_MMU_STATUS_STALLED_EN (0x00000004U) -#define RGX_CR_BIF_MMU_STATUS_PAUSED_SHIFT (1U) -#define RGX_CR_BIF_MMU_STATUS_PAUSED_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_MMU_STATUS_PAUSED_EN (0x00000002U) -#define RGX_CR_BIF_MMU_STATUS_BUSY_SHIFT (0U) -#define RGX_CR_BIF_MMU_STATUS_BUSY_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_MMU_STATUS_BUSY_EN (0x00000001U) - - -/* - Register group: RGX_CR_BIF_TILING_CFG, with 8 repeats -*/ -#define RGX_CR_BIF_TILING_CFG_REPEATCOUNT (8U) -/* - Register RGX_CR_BIF_TILING_CFG0 -*/ -#define RGX_CR_BIF_TILING_CFG0 (0x12D8U) -#define RGX_CR_BIF_TILING_CFG0_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG0_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG0_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG0_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG0_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG0_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG0_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG0_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG0_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG0_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG0_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG0_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG0_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG0_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG1 -*/ -#define RGX_CR_BIF_TILING_CFG1 (0x12E0U) -#define RGX_CR_BIF_TILING_CFG1_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG1_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG1_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG1_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG1_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG1_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG1_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG1_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG1_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG1_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG1_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG1_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG1_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG1_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG2 -*/ -#define RGX_CR_BIF_TILING_CFG2 (0x12E8U) -#define RGX_CR_BIF_TILING_CFG2_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG2_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG2_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG2_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG2_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG2_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG2_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG2_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG2_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG2_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG2_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG2_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG2_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG2_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG3 -*/ -#define RGX_CR_BIF_TILING_CFG3 (0x12F0U) -#define RGX_CR_BIF_TILING_CFG3_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG3_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG3_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG3_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG3_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG3_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG3_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG3_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG3_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG3_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG3_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG3_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG3_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG3_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG4 -*/ -#define RGX_CR_BIF_TILING_CFG4 (0x12F8U) -#define RGX_CR_BIF_TILING_CFG4_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG4_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG4_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG4_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG4_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG4_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG4_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG4_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG4_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG4_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG4_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG4_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG4_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG4_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG5 -*/ -#define RGX_CR_BIF_TILING_CFG5 (0x1300U) -#define RGX_CR_BIF_TILING_CFG5_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG5_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG5_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG5_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG5_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG5_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG5_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG5_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG5_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG5_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG5_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG5_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG5_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG5_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG6 -*/ -#define RGX_CR_BIF_TILING_CFG6 (0x1308U) -#define RGX_CR_BIF_TILING_CFG6_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG6_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG6_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG6_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG6_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG6_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG6_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG6_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG6_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG6_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG6_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG6_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG6_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG6_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_TILING_CFG7 -*/ -#define RGX_CR_BIF_TILING_CFG7 (0x1310U) -#define RGX_CR_BIF_TILING_CFG7_MASKFULL (IMG_UINT64_C(0xFFFFFFFF0FFFFFFF)) -#define RGX_CR_BIF_TILING_CFG7_XSTRIDE_SHIFT (61U) -#define RGX_CR_BIF_TILING_CFG7_XSTRIDE_CLRMSK (IMG_UINT64_C(0x1FFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG7_ENABLE_SHIFT (60U) -#define RGX_CR_BIF_TILING_CFG7_ENABLE_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG7_ENABLE_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_BIF_TILING_CFG7_MAX_ADDRESS_SHIFT (32U) -#define RGX_CR_BIF_TILING_CFG7_MAX_ADDRESS_CLRMSK (IMG_UINT64_C(0xF0000000FFFFFFFF)) -#define RGX_CR_BIF_TILING_CFG7_MAX_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG7_MAX_ADDRESS_ALIGNSIZE (4096U) -#define RGX_CR_BIF_TILING_CFG7_MIN_ADDRESS_SHIFT (0U) -#define RGX_CR_BIF_TILING_CFG7_MIN_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF0000000)) -#define RGX_CR_BIF_TILING_CFG7_MIN_ADDRESS_ALIGNSHIFT (12U) -#define RGX_CR_BIF_TILING_CFG7_MIN_ADDRESS_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_BIF_READS_EXT_STATUS -*/ -#define RGX_CR_BIF_READS_EXT_STATUS (0x1320U) -#define RGX_CR_BIF_READS_EXT_STATUS_MASKFULL (IMG_UINT64_C(0x000000000FFFFFFF)) -#define RGX_CR_BIF_READS_EXT_STATUS_MMU_SHIFT (16U) -#define RGX_CR_BIF_READS_EXT_STATUS_MMU_CLRMSK (0xF000FFFFU) -#define RGX_CR_BIF_READS_EXT_STATUS_BANK1_SHIFT (0U) -#define RGX_CR_BIF_READS_EXT_STATUS_BANK1_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIF_READS_INT_STATUS -*/ -#define RGX_CR_BIF_READS_INT_STATUS (0x1328U) -#define RGX_CR_BIF_READS_INT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000007FFFFFF)) -#define RGX_CR_BIF_READS_INT_STATUS_MMU_SHIFT (16U) -#define RGX_CR_BIF_READS_INT_STATUS_MMU_CLRMSK (0xF800FFFFU) -#define RGX_CR_BIF_READS_INT_STATUS_BANK1_SHIFT (0U) -#define RGX_CR_BIF_READS_INT_STATUS_BANK1_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIFPM_READS_INT_STATUS -*/ -#define RGX_CR_BIFPM_READS_INT_STATUS (0x1330U) -#define RGX_CR_BIFPM_READS_INT_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_BIFPM_READS_INT_STATUS_BANK0_SHIFT (0U) -#define RGX_CR_BIFPM_READS_INT_STATUS_BANK0_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIFPM_READS_EXT_STATUS -*/ -#define RGX_CR_BIFPM_READS_EXT_STATUS (0x1338U) -#define RGX_CR_BIFPM_READS_EXT_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_BIFPM_READS_EXT_STATUS_BANK0_SHIFT (0U) -#define RGX_CR_BIFPM_READS_EXT_STATUS_BANK0_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIFPM_STATUS_MMU -*/ -#define RGX_CR_BIFPM_STATUS_MMU (0x1350U) -#define RGX_CR_BIFPM_STATUS_MMU_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_BIFPM_STATUS_MMU_REQUESTS_SHIFT (0U) -#define RGX_CR_BIFPM_STATUS_MMU_REQUESTS_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_BIF_STATUS_MMU -*/ -#define RGX_CR_BIF_STATUS_MMU (0x1358U) -#define RGX_CR_BIF_STATUS_MMU_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_BIF_STATUS_MMU_REQUESTS_SHIFT (0U) -#define RGX_CR_BIF_STATUS_MMU_REQUESTS_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_BIF_FAULT_READ -*/ -#define RGX_CR_BIF_FAULT_READ (0x13E0U) -#define RGX_CR_BIF_FAULT_READ_MASKFULL (IMG_UINT64_C(0x000000FFFFFFFFF0)) -#define RGX_CR_BIF_FAULT_READ_ADDRESS_SHIFT (4U) -#define RGX_CR_BIF_FAULT_READ_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_BIF_FAULT_READ_ADDRESS_ALIGNSHIFT (4U) -#define RGX_CR_BIF_FAULT_READ_ADDRESS_ALIGNSIZE (16U) - - -/* - Register RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS -*/ -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS (0x1430U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000F775)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT (12U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT (8U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK (0xFFFFF8FFU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT (5U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK (0xFFFFFF9FU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_SHIFT (4U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN (0x00000010U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN (0x00000004U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_SHIFT (0U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS -*/ -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS (0x1438U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_MASKFULL (IMG_UINT64_C(0x0007FFFFFFFFFFF0)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_SHIFT (50U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT (44U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFFC0FFFFFFFFFFF)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT (40U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFF0FFFFFFFFFF)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT (4U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U) -#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSIZE (16U) - - -/* - Register RGX_CR_TFBC_COMPRESSION_CONTROL -*/ -#define RGX_CR_TFBC_COMPRESSION_CONTROL (0x14A0U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_YUV10_OVERRIDE_SHIFT (7U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_YUV10_OVERRIDE_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_YUV10_OVERRIDE_EN (0x00000080U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_QUALITY_SHIFT_SHIFT (4U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_QUALITY_SHIFT_CLRMSK (0xFFFFFF8FU) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_QUALITY_ENABLE_SHIFT (3U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_QUALITY_ENABLE_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_QUALITY_ENABLE_EN (0x00000008U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_SHIFT (1U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_CLRMSK (0xFFFFFFF9U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_DEFAULT (0x00000000U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_TFBC_DELTA_STANDARD_AND_CORRELATION (0x00000002U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_TFBC_DELTA_STANDARD (0x00000004U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_RESERVED (0x00000006U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_SHIFT (0U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_GROUP_0 (0x00000000U) -#define RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_GROUP_1 (0x00000001U) - - -/* - Register RGX_CR_MCU_FENCE -*/ -#define RGX_CR_MCU_FENCE (0x1740U) -#define RGX_CR_MCU_FENCE_MASKFULL (IMG_UINT64_C(0x000007FFFFFFFFE0)) -#define RGX_CR_MCU_FENCE_DM_SHIFT (40U) -#define RGX_CR_MCU_FENCE_DM_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_MCU_FENCE_DM_VERTEX (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_MCU_FENCE_DM_PIXEL (IMG_UINT64_C(0x0000010000000000)) -#define RGX_CR_MCU_FENCE_DM_COMPUTE (IMG_UINT64_C(0x0000020000000000)) -#define RGX_CR_MCU_FENCE_DM_RAY_VERTEX (IMG_UINT64_C(0x0000030000000000)) -#define RGX_CR_MCU_FENCE_DM_RAY (IMG_UINT64_C(0x0000040000000000)) -#define RGX_CR_MCU_FENCE_DM_FASTRENDER (IMG_UINT64_C(0x0000050000000000)) -#define RGX_CR_MCU_FENCE_ADDR_SHIFT (5U) -#define RGX_CR_MCU_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF000000001F)) -#define RGX_CR_MCU_FENCE_ADDR_ALIGNSHIFT (5U) -#define RGX_CR_MCU_FENCE_ADDR_ALIGNSIZE (32U) - - -/* - Register group: RGX_CR_SCRATCH, with 16 repeats -*/ -#define RGX_CR_SCRATCH_REPEATCOUNT (16U) -/* - Register RGX_CR_SCRATCH0 -*/ -#define RGX_CR_SCRATCH0 (0x1A00U) -#define RGX_CR_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH1 -*/ -#define RGX_CR_SCRATCH1 (0x1A08U) -#define RGX_CR_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH2 -*/ -#define RGX_CR_SCRATCH2 (0x1A10U) -#define RGX_CR_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH2_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH3 -*/ -#define RGX_CR_SCRATCH3 (0x1A18U) -#define RGX_CR_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH3_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH4 -*/ -#define RGX_CR_SCRATCH4 (0x1A20U) -#define RGX_CR_SCRATCH4_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH4_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH4_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH5 -*/ -#define RGX_CR_SCRATCH5 (0x1A28U) -#define RGX_CR_SCRATCH5_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH5_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH5_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH6 -*/ -#define RGX_CR_SCRATCH6 (0x1A30U) -#define RGX_CR_SCRATCH6_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH6_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH6_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH7 -*/ -#define RGX_CR_SCRATCH7 (0x1A38U) -#define RGX_CR_SCRATCH7_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH7_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH7_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH8 -*/ -#define RGX_CR_SCRATCH8 (0x1A40U) -#define RGX_CR_SCRATCH8_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH8_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH8_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH9 -*/ -#define RGX_CR_SCRATCH9 (0x1A48U) -#define RGX_CR_SCRATCH9_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH9_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH9_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH10 -*/ -#define RGX_CR_SCRATCH10 (0x1A50U) -#define RGX_CR_SCRATCH10_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH10_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH10_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH11 -*/ -#define RGX_CR_SCRATCH11 (0x1A58U) -#define RGX_CR_SCRATCH11_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH11_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH11_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH12 -*/ -#define RGX_CR_SCRATCH12 (0x1A60U) -#define RGX_CR_SCRATCH12_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH12_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH12_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH13 -*/ -#define RGX_CR_SCRATCH13 (0x1A68U) -#define RGX_CR_SCRATCH13_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH13_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH13_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH14 -*/ -#define RGX_CR_SCRATCH14 (0x1A70U) -#define RGX_CR_SCRATCH14_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH14_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH14_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SCRATCH15 -*/ -#define RGX_CR_SCRATCH15 (0x1A78U) -#define RGX_CR_SCRATCH15_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SCRATCH15_DATA_SHIFT (0U) -#define RGX_CR_SCRATCH15_DATA_CLRMSK (0x00000000U) - - -/* - Register group: RGX_CR_OS0_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS0_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS0_SCRATCH0 -*/ -#define RGX_CR_OS0_SCRATCH0 (0x1A80U) -#define RGX_CR_OS0_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS0_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS0_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS0_SCRATCH1 -*/ -#define RGX_CR_OS0_SCRATCH1 (0x1A88U) -#define RGX_CR_OS0_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS0_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS0_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS0_SCRATCH2 -*/ -#define RGX_CR_OS0_SCRATCH2 (0x1A90U) -#define RGX_CR_OS0_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS0_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS0_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS0_SCRATCH3 -*/ -#define RGX_CR_OS0_SCRATCH3 (0x1A98U) -#define RGX_CR_OS0_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS0_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS0_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS1_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS1_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS1_SCRATCH0 -*/ -#define RGX_CR_OS1_SCRATCH0 (0x11A80U) -#define RGX_CR_OS1_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS1_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS1_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS1_SCRATCH1 -*/ -#define RGX_CR_OS1_SCRATCH1 (0x11A88U) -#define RGX_CR_OS1_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS1_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS1_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS1_SCRATCH2 -*/ -#define RGX_CR_OS1_SCRATCH2 (0x11A90U) -#define RGX_CR_OS1_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS1_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS1_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS1_SCRATCH3 -*/ -#define RGX_CR_OS1_SCRATCH3 (0x11A98U) -#define RGX_CR_OS1_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS1_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS1_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS2_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS2_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS2_SCRATCH0 -*/ -#define RGX_CR_OS2_SCRATCH0 (0x21A80U) -#define RGX_CR_OS2_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS2_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS2_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS2_SCRATCH1 -*/ -#define RGX_CR_OS2_SCRATCH1 (0x21A88U) -#define RGX_CR_OS2_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS2_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS2_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS2_SCRATCH2 -*/ -#define RGX_CR_OS2_SCRATCH2 (0x21A90U) -#define RGX_CR_OS2_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS2_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS2_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS2_SCRATCH3 -*/ -#define RGX_CR_OS2_SCRATCH3 (0x21A98U) -#define RGX_CR_OS2_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS2_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS2_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS3_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS3_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS3_SCRATCH0 -*/ -#define RGX_CR_OS3_SCRATCH0 (0x31A80U) -#define RGX_CR_OS3_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS3_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS3_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS3_SCRATCH1 -*/ -#define RGX_CR_OS3_SCRATCH1 (0x31A88U) -#define RGX_CR_OS3_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS3_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS3_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS3_SCRATCH2 -*/ -#define RGX_CR_OS3_SCRATCH2 (0x31A90U) -#define RGX_CR_OS3_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS3_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS3_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS3_SCRATCH3 -*/ -#define RGX_CR_OS3_SCRATCH3 (0x31A98U) -#define RGX_CR_OS3_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS3_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS3_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS4_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS4_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS4_SCRATCH0 -*/ -#define RGX_CR_OS4_SCRATCH0 (0x41A80U) -#define RGX_CR_OS4_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS4_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS4_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS4_SCRATCH1 -*/ -#define RGX_CR_OS4_SCRATCH1 (0x41A88U) -#define RGX_CR_OS4_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS4_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS4_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS4_SCRATCH2 -*/ -#define RGX_CR_OS4_SCRATCH2 (0x41A90U) -#define RGX_CR_OS4_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS4_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS4_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS4_SCRATCH3 -*/ -#define RGX_CR_OS4_SCRATCH3 (0x41A98U) -#define RGX_CR_OS4_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS4_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS4_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS5_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS5_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS5_SCRATCH0 -*/ -#define RGX_CR_OS5_SCRATCH0 (0x51A80U) -#define RGX_CR_OS5_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS5_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS5_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS5_SCRATCH1 -*/ -#define RGX_CR_OS5_SCRATCH1 (0x51A88U) -#define RGX_CR_OS5_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS5_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS5_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS5_SCRATCH2 -*/ -#define RGX_CR_OS5_SCRATCH2 (0x51A90U) -#define RGX_CR_OS5_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS5_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS5_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS5_SCRATCH3 -*/ -#define RGX_CR_OS5_SCRATCH3 (0x51A98U) -#define RGX_CR_OS5_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS5_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS5_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS6_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS6_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS6_SCRATCH0 -*/ -#define RGX_CR_OS6_SCRATCH0 (0x61A80U) -#define RGX_CR_OS6_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS6_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS6_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS6_SCRATCH1 -*/ -#define RGX_CR_OS6_SCRATCH1 (0x61A88U) -#define RGX_CR_OS6_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS6_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS6_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS6_SCRATCH2 -*/ -#define RGX_CR_OS6_SCRATCH2 (0x61A90U) -#define RGX_CR_OS6_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS6_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS6_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS6_SCRATCH3 -*/ -#define RGX_CR_OS6_SCRATCH3 (0x61A98U) -#define RGX_CR_OS6_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS6_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS6_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register group: RGX_CR_OS7_SCRATCH, with 2 repeats -*/ -#define RGX_CR_OS7_SCRATCH_REPEATCOUNT (2U) -/* - Register RGX_CR_OS7_SCRATCH0 -*/ -#define RGX_CR_OS7_SCRATCH0 (0x71A80U) -#define RGX_CR_OS7_SCRATCH0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS7_SCRATCH0_DATA_SHIFT (0U) -#define RGX_CR_OS7_SCRATCH0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS7_SCRATCH1 -*/ -#define RGX_CR_OS7_SCRATCH1 (0x71A88U) -#define RGX_CR_OS7_SCRATCH1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_OS7_SCRATCH1_DATA_SHIFT (0U) -#define RGX_CR_OS7_SCRATCH1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OS7_SCRATCH2 -*/ -#define RGX_CR_OS7_SCRATCH2 (0x71A90U) -#define RGX_CR_OS7_SCRATCH2_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS7_SCRATCH2_DATA_SHIFT (0U) -#define RGX_CR_OS7_SCRATCH2_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_OS7_SCRATCH3 -*/ -#define RGX_CR_OS7_SCRATCH3 (0x71A98U) -#define RGX_CR_OS7_SCRATCH3_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_OS7_SCRATCH3_DATA_SHIFT (0U) -#define RGX_CR_OS7_SCRATCH3_DATA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_SPFILTER_SIGNAL_DESCR -*/ -#define RGX_CR_SPFILTER_SIGNAL_DESCR (0x2700U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_SHIFT (0U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_CLRMSK (0xFFFF0000U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_ALIGNSHIFT (4U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_ALIGNSIZE (16U) - - -/* - Register RGX_CR_SPFILTER_SIGNAL_DESCR_MIN -*/ -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN (0x2708U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_MASKFULL (IMG_UINT64_C(0x000000FFFFFFFFF0)) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_SHIFT (4U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_ALIGNSHIFT (4U) -#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_ALIGNSIZE (16U) - - -/* - Register group: RGX_CR_FWCORE_ADDR_REMAP_CONFIG, with 16 repeats -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG_REPEATCOUNT (16U) -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG0 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0 (0x3000U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG1 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1 (0x3008U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG2 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2 (0x3010U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG3 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3 (0x3018U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG4 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4 (0x3020U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG5 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5 (0x3028U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG6 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6 (0x3030U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG7 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7 (0x3038U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG8 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8 (0x3040U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG9 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9 (0x3048U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG10 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10 (0x3050U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG11 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11 (0x3058U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG12 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12 (0x3060U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG13 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13 (0x3068U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG14 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14 (0x3070U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_ADDR_REMAP_CONFIG15 -*/ -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15 (0x3078U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_MASKFULL (IMG_UINT64_C(0x7FFFF7FFFFFFF000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_SHIFT (62U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_SHIFT (61U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_CLRMSK (IMG_UINT64_C(0xDFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_EN (IMG_UINT64_C(0x2000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_SHIFT (60U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_CLRMSK (IMG_UINT64_C(0xEFFFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_EN (IMG_UINT64_C(0x1000000000000000)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_SIZE_SHIFT (44U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_SIZE_CLRMSK (IMG_UINT64_C(0xF0000FFFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_CBASE_SHIFT (40U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_CBASE_CLRMSK (IMG_UINT64_C(0xFFFFF8FFFFFFFFFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_SHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_BOOT -*/ -#define RGX_CR_FWCORE_BOOT (0x3090U) -#define RGX_CR_FWCORE_BOOT_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_FWCORE_BOOT_ENABLE_SHIFT (0U) -#define RGX_CR_FWCORE_BOOT_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_BOOT_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_RESET_ADDR -*/ -#define RGX_CR_FWCORE_RESET_ADDR (0x3098U) -#define RGX_CR_FWCORE_RESET_ADDR_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFE)) -#define RGX_CR_FWCORE_RESET_ADDR_ADDR_SHIFT (1U) -#define RGX_CR_FWCORE_RESET_ADDR_ADDR_CLRMSK (0x00000001U) -#define RGX_CR_FWCORE_RESET_ADDR_ADDR_ALIGNSHIFT (1U) -#define RGX_CR_FWCORE_RESET_ADDR_ADDR_ALIGNSIZE (2U) - - -/* - Register RGX_CR_FWCORE_WRAPPER_NMI_ADDR -*/ -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR (0x30A0U) -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFE)) -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR_ADDR_SHIFT (1U) -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR_ADDR_CLRMSK (0x00000001U) -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR_ADDR_ALIGNSHIFT (1U) -#define RGX_CR_FWCORE_WRAPPER_NMI_ADDR_ADDR_ALIGNSIZE (2U) - - -/* - Register RGX_CR_FWCORE_WRAPPER_NMI_EVENT -*/ -#define RGX_CR_FWCORE_WRAPPER_NMI_EVENT (0x30A8U) -#define RGX_CR_FWCORE_WRAPPER_NMI_EVENT_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_FWCORE_WRAPPER_NMI_EVENT_TRIGGER_EN_SHIFT (0U) -#define RGX_CR_FWCORE_WRAPPER_NMI_EVENT_TRIGGER_EN_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_WRAPPER_NMI_EVENT_TRIGGER_EN_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS -*/ -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS (0x30B0U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000F771)) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_CAT_BASE_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_CAT_BASE_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_PAGE_SIZE_SHIFT (8U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_PAGE_SIZE_CLRMSK (0xFFFFF8FFU) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_DATA_TYPE_SHIFT (5U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_DATA_TYPE_CLRMSK (0xFFFFFF9FU) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_RO_SHIFT (4U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_RO_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_RO_EN (0x00000010U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_SHIFT (0U) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS -*/ -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS (0x30B8U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_MASKFULL (IMG_UINT64_C(0x001FFFFFFFFFFFF0)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_RNW_SHIFT (52U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFFEFFFFFFFFFFFFF)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_RNW_EN (IMG_UINT64_C(0x0010000000000000)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_SHIFT (46U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFF03FFFFFFFFFFF)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_SHIFT (40U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFC0FFFFFFFFFF)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_SHIFT (4U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U) -#define RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_ALIGNSIZE (16U) - - -/* - Register RGX_CR_FWCORE_MEM_CTRL_INVAL -*/ -#define RGX_CR_FWCORE_MEM_CTRL_INVAL (0x30C0U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_TLB_SHIFT (3U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_TLB_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_TLB_EN (0x00000008U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PC_SHIFT (2U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PC_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PC_EN (0x00000004U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PD_SHIFT (1U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PD_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PD_EN (0x00000002U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PT_SHIFT (0U) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_MEM_CTRL_INVAL_PT_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_MEM_MMU_STATUS -*/ -#define RGX_CR_FWCORE_MEM_MMU_STATUS (0x30C8U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000FFFFFF7)) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PC_DATA_SHIFT (20U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PC_DATA_CLRMSK (0xF00FFFFFU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PD_DATA_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PD_DATA_CLRMSK (0xFFF00FFFU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PT_DATA_SHIFT (4U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PT_DATA_CLRMSK (0xFFFFF00FU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_STALLED_SHIFT (2U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_STALLED_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_STALLED_EN (0x00000004U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PAUSED_SHIFT (1U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PAUSED_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_PAUSED_EN (0x00000002U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_BUSY_SHIFT (0U) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_BUSY_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_MEM_MMU_STATUS_BUSY_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_MEM_READS_EXT_STATUS -*/ -#define RGX_CR_FWCORE_MEM_READS_EXT_STATUS (0x30D8U) -#define RGX_CR_FWCORE_MEM_READS_EXT_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000000FFF)) -#define RGX_CR_FWCORE_MEM_READS_EXT_STATUS_MMU_SHIFT (0U) -#define RGX_CR_FWCORE_MEM_READS_EXT_STATUS_MMU_CLRMSK (0xFFFFF000U) - - -/* - Register RGX_CR_FWCORE_MEM_READS_INT_STATUS -*/ -#define RGX_CR_FWCORE_MEM_READS_INT_STATUS (0x30E0U) -#define RGX_CR_FWCORE_MEM_READS_INT_STATUS_MASKFULL (IMG_UINT64_C(0x00000000000007FF)) -#define RGX_CR_FWCORE_MEM_READS_INT_STATUS_MMU_SHIFT (0U) -#define RGX_CR_FWCORE_MEM_READS_INT_STATUS_MMU_CLRMSK (0xFFFFF800U) - - -/* - Register RGX_CR_FWCORE_WRAPPER_FENCE -*/ -#define RGX_CR_FWCORE_WRAPPER_FENCE (0x30E8U) -#define RGX_CR_FWCORE_WRAPPER_FENCE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_FWCORE_WRAPPER_FENCE_ID_SHIFT (0U) -#define RGX_CR_FWCORE_WRAPPER_FENCE_ID_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_WRAPPER_FENCE_ID_EN (0x00000001U) - - -/* - Register group: RGX_CR_FWCORE_MEM_CAT_BASE, with 8 repeats -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE_REPEATCOUNT (8U) -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE0 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE0 (0x30F0U) -#define RGX_CR_FWCORE_MEM_CAT_BASE0_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE1 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE1 (0x30F8U) -#define RGX_CR_FWCORE_MEM_CAT_BASE1_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE1_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE1_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE1_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE1_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE2 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE2 (0x3100U) -#define RGX_CR_FWCORE_MEM_CAT_BASE2_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE2_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE2_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE2_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE2_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE3 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE3 (0x3108U) -#define RGX_CR_FWCORE_MEM_CAT_BASE3_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE3_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE3_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE3_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE3_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE4 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE4 (0x3110U) -#define RGX_CR_FWCORE_MEM_CAT_BASE4_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE4_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE4_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE4_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE4_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE5 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE5 (0x3118U) -#define RGX_CR_FWCORE_MEM_CAT_BASE5_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE5_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE5_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE5_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE5_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE6 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE6 (0x3120U) -#define RGX_CR_FWCORE_MEM_CAT_BASE6_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE6_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE6_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE6_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE6_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_MEM_CAT_BASE7 -*/ -#define RGX_CR_FWCORE_MEM_CAT_BASE7 (0x3128U) -#define RGX_CR_FWCORE_MEM_CAT_BASE7_MASKFULL (IMG_UINT64_C(0x000000FFFFFFF000)) -#define RGX_CR_FWCORE_MEM_CAT_BASE7_ADDR_SHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE7_ADDR_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_CR_FWCORE_MEM_CAT_BASE7_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_FWCORE_MEM_CAT_BASE7_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_FWCORE_WDT_RESET -*/ -#define RGX_CR_FWCORE_WDT_RESET (0x3130U) -#define RGX_CR_FWCORE_WDT_RESET_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_FWCORE_WDT_RESET_EN_SHIFT (0U) -#define RGX_CR_FWCORE_WDT_RESET_EN_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_WDT_RESET_EN_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_WDT_CTRL -*/ -#define RGX_CR_FWCORE_WDT_CTRL (0x3138U) -#define RGX_CR_FWCORE_WDT_CTRL_MASKFULL (IMG_UINT64_C(0x00000000FFFF1F01)) -#define RGX_CR_FWCORE_WDT_CTRL_PROT_SHIFT (16U) -#define RGX_CR_FWCORE_WDT_CTRL_PROT_CLRMSK (0x0000FFFFU) -#define RGX_CR_FWCORE_WDT_CTRL_THRESHOLD_SHIFT (8U) -#define RGX_CR_FWCORE_WDT_CTRL_THRESHOLD_CLRMSK (0xFFFFE0FFU) -#define RGX_CR_FWCORE_WDT_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_FWCORE_WDT_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_WDT_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_WDT_COUNT -*/ -#define RGX_CR_FWCORE_WDT_COUNT (0x3140U) -#define RGX_CR_FWCORE_WDT_COUNT_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_WDT_COUNT_VALUE_SHIFT (0U) -#define RGX_CR_FWCORE_WDT_COUNT_VALUE_CLRMSK (0x00000000U) - - -/* - Register group: RGX_CR_FWCORE_DMI_RESERVED0, with 4 repeats -*/ -#define RGX_CR_FWCORE_DMI_RESERVED0_REPEATCOUNT (4U) -/* - Register RGX_CR_FWCORE_DMI_RESERVED00 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED00 (0x3400U) -#define RGX_CR_FWCORE_DMI_RESERVED00_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED01 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED01 (0x3408U) -#define RGX_CR_FWCORE_DMI_RESERVED01_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED02 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED02 (0x3410U) -#define RGX_CR_FWCORE_DMI_RESERVED02_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED03 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED03 (0x3418U) -#define RGX_CR_FWCORE_DMI_RESERVED03_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_DATA0 -*/ -#define RGX_CR_FWCORE_DMI_DATA0 (0x3420U) -#define RGX_CR_FWCORE_DMI_DATA0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_DATA0_VAL_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_DATA0_VAL_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FWCORE_DMI_DATA1 -*/ -#define RGX_CR_FWCORE_DMI_DATA1 (0x3428U) -#define RGX_CR_FWCORE_DMI_DATA1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_DATA1_VAL_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_DATA1_VAL_CLRMSK (0x00000000U) - - -/* - Register group: RGX_CR_FWCORE_DMI_RESERVED1, with 10 repeats -*/ -#define RGX_CR_FWCORE_DMI_RESERVED1_REPEATCOUNT (10U) -/* - Register RGX_CR_FWCORE_DMI_RESERVED10 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED10 (0x3430U) -#define RGX_CR_FWCORE_DMI_RESERVED10_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED11 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED11 (0x3438U) -#define RGX_CR_FWCORE_DMI_RESERVED11_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED12 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED12 (0x3440U) -#define RGX_CR_FWCORE_DMI_RESERVED12_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED13 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED13 (0x3448U) -#define RGX_CR_FWCORE_DMI_RESERVED13_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED14 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED14 (0x3450U) -#define RGX_CR_FWCORE_DMI_RESERVED14_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_DMCONTROL -*/ -#define RGX_CR_FWCORE_DMI_DMCONTROL (0x3480U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_MASKFULL (IMG_UINT64_C(0x00000000D0000003)) -#define RGX_CR_FWCORE_DMI_DMCONTROL_HALTREQ_SHIFT (31U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_HALTREQ_CLRMSK (0x7FFFFFFFU) -#define RGX_CR_FWCORE_DMI_DMCONTROL_HALTREQ_EN (0x80000000U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_RESUMEREQ_SHIFT (30U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_RESUMEREQ_CLRMSK (0xBFFFFFFFU) -#define RGX_CR_FWCORE_DMI_DMCONTROL_RESUMEREQ_EN (0x40000000U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_ACKHAVERESET_SHIFT (28U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_ACKHAVERESET_CLRMSK (0xEFFFFFFFU) -#define RGX_CR_FWCORE_DMI_DMCONTROL_ACKHAVERESET_EN (0x10000000U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_NDMRESET_SHIFT (1U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_NDMRESET_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_FWCORE_DMI_DMCONTROL_NDMRESET_EN (0x00000002U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_DMI_DMSTATUS -*/ -#define RGX_CR_FWCORE_DMI_DMSTATUS (0x3488U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_MASKFULL (IMG_UINT64_C(0x00000000004FFFFF)) -#define RGX_CR_FWCORE_DMI_DMSTATUS_IMPEBREAK_SHIFT (22U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_IMPEBREAK_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_IMPEBREAK_EN (0x00400000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHAVERESET_SHIFT (19U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHAVERESET_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHAVERESET_EN (0x00080000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHAVERESET_SHIFT (18U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHAVERESET_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHAVERESET_EN (0x00040000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_SHIFT (17U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_EN (0x00020000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRESUMEACK_SHIFT (16U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRESUMEACK_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRESUMEACK_EN (0x00010000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLNONEXISTENT_SHIFT (15U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLNONEXISTENT_CLRMSK (0xFFFF7FFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLNONEXISTENT_EN (0x00008000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYNONEXISTENT_SHIFT (14U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYNONEXISTENT_CLRMSK (0xFFFFBFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYNONEXISTENT_EN (0x00004000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLUNAVAIL_SHIFT (13U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLUNAVAIL_CLRMSK (0xFFFFDFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLUNAVAIL_EN (0x00002000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYUNAVAIL_SHIFT (12U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYUNAVAIL_CLRMSK (0xFFFFEFFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYUNAVAIL_EN (0x00001000U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRUNNING_SHIFT (11U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRUNNING_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLRUNNING_EN (0x00000800U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRUNNING_SHIFT (10U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRUNNING_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYRUNNING_EN (0x00000400U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_SHIFT (9U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN (0x00000200U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHALTED_SHIFT (8U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHALTED_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_ANYHALTED_EN (0x00000100U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHENTICATED_SHIFT (7U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHENTICATED_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHENTICATED_EN (0x00000080U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHBUSY_SHIFT (6U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHBUSY_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_AUTHBUSY_EN (0x00000040U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_HASRESETHALTREQ_SHIFT (5U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_HASRESETHALTREQ_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_HASRESETHALTREQ_EN (0x00000020U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_CONFSTRPTRVALID_SHIFT (4U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_CONFSTRPTRVALID_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_FWCORE_DMI_DMSTATUS_CONFSTRPTRVALID_EN (0x00000010U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_VERSION_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_DMSTATUS_VERSION_CLRMSK (0xFFFFFFF0U) - - -/* - Register group: RGX_CR_FWCORE_DMI_RESERVED2, with 4 repeats -*/ -#define RGX_CR_FWCORE_DMI_RESERVED2_REPEATCOUNT (4U) -/* - Register RGX_CR_FWCORE_DMI_RESERVED20 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED20 (0x3490U) -#define RGX_CR_FWCORE_DMI_RESERVED20_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED21 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED21 (0x3498U) -#define RGX_CR_FWCORE_DMI_RESERVED21_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED22 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED22 (0x34A0U) -#define RGX_CR_FWCORE_DMI_RESERVED22_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED23 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED23 (0x34A8U) -#define RGX_CR_FWCORE_DMI_RESERVED23_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_ABSTRACTCS -*/ -#define RGX_CR_FWCORE_DMI_ABSTRACTCS (0x34B0U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_MASKFULL (IMG_UINT64_C(0x000000001F00170F)) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_PROGBUFSIZE_SHIFT (24U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_PROGBUFSIZE_CLRMSK (0xE0FFFFFFU) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_SHIFT (12U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_CLRMSK (0xFFFFEFFFU) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN (0x00001000U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_SHIFT (8U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_CLRMSK (0xFFFFF8FFU) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_DATACOUNT_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_ABSTRACTCS_DATACOUNT_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_FWCORE_DMI_COMMAND -*/ -#define RGX_CR_FWCORE_DMI_COMMAND (0x34B8U) -#define RGX_CR_FWCORE_DMI_COMMAND_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT (24U) -#define RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_CLRMSK (0x00FFFFFFU) -#define RGX_CR_FWCORE_DMI_COMMAND_CONTROL_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_COMMAND_CONTROL_CLRMSK (0xFF000000U) - - -/* - Register group: RGX_CR_FWCORE_DMI_RESERVED3, with 32 repeats -*/ -#define RGX_CR_FWCORE_DMI_RESERVED3_REPEATCOUNT (32U) -/* - Register RGX_CR_FWCORE_DMI_RESERVED30 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED30 (0x34C0U) -#define RGX_CR_FWCORE_DMI_RESERVED30_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_RESERVED31 -*/ -#define RGX_CR_FWCORE_DMI_RESERVED31 (0x34C8U) -#define RGX_CR_FWCORE_DMI_RESERVED31_MASKFULL (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_FWCORE_DMI_SBCS -*/ -#define RGX_CR_FWCORE_DMI_SBCS (0x35C0U) -#define RGX_CR_FWCORE_DMI_SBCS_MASKFULL (IMG_UINT64_C(0x00000000E07FFFFF)) -#define RGX_CR_FWCORE_DMI_SBCS_SBVERSION_SHIFT (29U) -#define RGX_CR_FWCORE_DMI_SBCS_SBVERSION_CLRMSK (0x1FFFFFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSYERROR_SHIFT (22U) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSYERROR_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSYERROR_EN (0x00400000U) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSY_SHIFT (21U) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSY_CLRMSK (0xFFDFFFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBBUSY_EN (0x00200000U) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONADDR_SHIFT (20U) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONADDR_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONADDR_EN (0x00100000U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS_SHIFT (17U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS_CLRMSK (0xFFF1FFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBAUTOINCREMENT_SHIFT (16U) -#define RGX_CR_FWCORE_DMI_SBCS_SBAUTOINCREMENT_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBAUTOINCREMENT_EN (0x00010000U) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONDATA_SHIFT (15U) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONDATA_CLRMSK (0xFFFF7FFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBREADONDATA_EN (0x00008000U) -#define RGX_CR_FWCORE_DMI_SBCS_SBERROR_SHIFT (12U) -#define RGX_CR_FWCORE_DMI_SBCS_SBERROR_CLRMSK (0xFFFF8FFFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBASIZE_SHIFT (5U) -#define RGX_CR_FWCORE_DMI_SBCS_SBASIZE_CLRMSK (0xFFFFF01FU) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS128_SHIFT (4U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS128_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS128_EN (0x00000010U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS64_SHIFT (3U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS64_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS64_EN (0x00000008U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS32_SHIFT (2U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS32_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS32_EN (0x00000004U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS16_SHIFT (1U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS16_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS16_EN (0x00000002U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS8_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS8_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FWCORE_DMI_SBCS_SBACCESS8_EN (0x00000001U) - - -/* - Register RGX_CR_FWCORE_DMI_SBADDRESS0 -*/ -#define RGX_CR_FWCORE_DMI_SBADDRESS0 (0x35C8U) -#define RGX_CR_FWCORE_DMI_SBADDRESS0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_SBADDRESS0_ADDRESS_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBADDRESS0_ADDRESS_CLRMSK (0x00000000U) - - -/* - Register group: RGX_CR_FWCORE_DMI_SBDATA, with 4 repeats -*/ -#define RGX_CR_FWCORE_DMI_SBDATA_REPEATCOUNT (4U) -/* - Register RGX_CR_FWCORE_DMI_SBDATA0 -*/ -#define RGX_CR_FWCORE_DMI_SBDATA0 (0x35E0U) -#define RGX_CR_FWCORE_DMI_SBDATA0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_SBDATA0_DATA_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBDATA0_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FWCORE_DMI_SBDATA1 -*/ -#define RGX_CR_FWCORE_DMI_SBDATA1 (0x35E8U) -#define RGX_CR_FWCORE_DMI_SBDATA1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_SBDATA1_DATA_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBDATA1_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FWCORE_DMI_SBDATA2 -*/ -#define RGX_CR_FWCORE_DMI_SBDATA2 (0x35F0U) -#define RGX_CR_FWCORE_DMI_SBDATA2_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_SBDATA2_DATA_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBDATA2_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FWCORE_DMI_SBDATA3 -*/ -#define RGX_CR_FWCORE_DMI_SBDATA3 (0x35F8U) -#define RGX_CR_FWCORE_DMI_SBDATA3_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_SBDATA3_DATA_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_SBDATA3_DATA_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FWCORE_DMI_HALTSUM0 -*/ -#define RGX_CR_FWCORE_DMI_HALTSUM0 (0x3600U) -#define RGX_CR_FWCORE_DMI_HALTSUM0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FWCORE_DMI_HALTSUM0_VAL_SHIFT (0U) -#define RGX_CR_FWCORE_DMI_HALTSUM0_VAL_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SLC_CTRL_MISC -*/ -#define RGX_CR_SLC_CTRL_MISC (0x3800U) -#define RGX_CR_SLC_CTRL_MISC_MASKFULL (IMG_UINT64_C(0xFFFFFFFF03FF010F)) -#define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_SHIFT (32U) -#define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_CLRMSK (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SLC_CTRL_MISC_TAG_ID_LIMIT_CONTROL_SHIFT (25U) -#define RGX_CR_SLC_CTRL_MISC_TAG_ID_LIMIT_CONTROL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFDFFFFFF)) -#define RGX_CR_SLC_CTRL_MISC_TAG_ID_LIMIT_CONTROL_EN (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_SHIFT (24U) -#define RGX_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFEFFFFFF)) -#define RGX_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_EN (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SHIFT (16U) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF00FFFF)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_64_BYTE (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_128_BYTE (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH1 (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH2 (IMG_UINT64_C(0x0000000000110000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1 (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH2_SCRAMBLE (IMG_UINT64_C(0x0000000000210000)) -#define RGX_CR_SLC_CTRL_MISC_PAUSE_SHIFT (8U) -#define RGX_CR_SLC_CTRL_MISC_PAUSE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_SLC_CTRL_MISC_PAUSE_EN (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_SLC_CTRL_MISC_RESP_PRIORITY_SHIFT (3U) -#define RGX_CR_SLC_CTRL_MISC_RESP_PRIORITY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_SLC_CTRL_MISC_RESP_PRIORITY_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_SHIFT (2U) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_SHIFT (1U) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_SHIFT (0U) -#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_SLC_CTRL_FLUSH_INVAL -*/ -#define RGX_CR_SLC_CTRL_FLUSH_INVAL (0x3818U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_MASKFULL (IMG_UINT64_C(0x0000000080000FFF)) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_SHIFT (31U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_CLRMSK (0x7FFFFFFFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_EN (0x80000000U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FASTRENDER_SHIFT (11U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FASTRENDER_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FASTRENDER_EN (0x00000800U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_SHIFT (10U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_EN (0x00000400U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_SHIFT (9U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_EN (0x00000200U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_SHIFT (8U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_EN (0x00000100U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_SHIFT (7U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_EN (0x00000080U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_SHIFT (6U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_EN (0x00000040U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_SHIFT (5U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_EN (0x00000020U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_SHIFT (4U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_EN (0x00000010U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_SHIFT (3U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_EN (0x00000008U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_SHIFT (2U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_EN (0x00000004U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_SHIFT (1U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_EN (0x00000002U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_SHIFT (0U) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN (0x00000001U) - - -/* - Register RGX_CR_SLC_STATUS0 -*/ -#define RGX_CR_SLC_STATUS0 (0x3820U) -#define RGX_CR_SLC_STATUS0_MASKFULL (IMG_UINT64_C(0x0000000000000007)) -#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_SHIFT (2U) -#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_EN (0x00000004U) -#define RGX_CR_SLC_STATUS0_INVAL_PENDING_SHIFT (1U) -#define RGX_CR_SLC_STATUS0_INVAL_PENDING_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SLC_STATUS0_INVAL_PENDING_EN (0x00000002U) -#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_SHIFT (0U) -#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_EN (0x00000001U) - - -/* - Register RGX_CR_SLC_CTRL_BYPASS -*/ -#define RGX_CR_SLC_CTRL_BYPASS (0x3828U) -#define RGX_CR_SLC_CTRL_BYPASS__XE_MEM__MASKFULL (IMG_UINT64_C(0x0FFFFFFFFFFF7FFF)) -#define RGX_CR_SLC_CTRL_BYPASS_MASKFULL (IMG_UINT64_C(0x000000000FFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_ZLS_SHIFT (59U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_ZLS_CLRMSK (IMG_UINT64_C(0xF7FFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_ZLS_EN (IMG_UINT64_C(0x0800000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_HEADER_SHIFT (58U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_HEADER_CLRMSK (IMG_UINT64_C(0xFBFFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_HEADER_EN (IMG_UINT64_C(0x0400000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_HEADER_SHIFT (57U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_HEADER_CLRMSK (IMG_UINT64_C(0xFDFFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_HEADER_EN (IMG_UINT64_C(0x0200000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_DATA_SHIFT (56U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_DATA_CLRMSK (IMG_UINT64_C(0xFEFFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_ZLS_DATA_EN (IMG_UINT64_C(0x0100000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_DATA_SHIFT (55U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_DATA_CLRMSK (IMG_UINT64_C(0xFF7FFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_DECOMP_TCU_DATA_EN (IMG_UINT64_C(0x0080000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_PBE_SHIFT (54U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_PBE_CLRMSK (IMG_UINT64_C(0xFFBFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TFBC_COMP_PBE_EN (IMG_UINT64_C(0x0040000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_DM_COMPUTE_SHIFT (53U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_DM_COMPUTE_CLRMSK (IMG_UINT64_C(0xFFDFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_DM_COMPUTE_EN (IMG_UINT64_C(0x0020000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_PDSRW_NOLINEFILL_SHIFT (52U) -#define RGX_CR_SLC_CTRL_BYPASS_PDSRW_NOLINEFILL_CLRMSK (IMG_UINT64_C(0xFFEFFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_PDSRW_NOLINEFILL_EN (IMG_UINT64_C(0x0010000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_PBE_NOLINEFILL_SHIFT (51U) -#define RGX_CR_SLC_CTRL_BYPASS_PBE_NOLINEFILL_CLRMSK (IMG_UINT64_C(0xFFF7FFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_PBE_NOLINEFILL_EN (IMG_UINT64_C(0x0008000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBC_SHIFT (50U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBC_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBC_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_RREQ_SHIFT (49U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_RREQ_CLRMSK (IMG_UINT64_C(0xFFFDFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_RREQ_EN (IMG_UINT64_C(0x0002000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CREQ_SHIFT (48U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CREQ_CLRMSK (IMG_UINT64_C(0xFFFEFFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CREQ_EN (IMG_UINT64_C(0x0001000000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_PREQ_SHIFT (47U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_PREQ_CLRMSK (IMG_UINT64_C(0xFFFF7FFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_PREQ_EN (IMG_UINT64_C(0x0000800000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_DBSC_SHIFT (46U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_DBSC_CLRMSK (IMG_UINT64_C(0xFFFFBFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_DBSC_EN (IMG_UINT64_C(0x0000400000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_SHIFT (45U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_CLRMSK (IMG_UINT64_C(0xFFFFDFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TCU_EN (IMG_UINT64_C(0x0000200000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PBE_SHIFT (44U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PBE_CLRMSK (IMG_UINT64_C(0xFFFFEFFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PBE_EN (IMG_UINT64_C(0x0000100000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_ISP_SHIFT (43U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_ISP_CLRMSK (IMG_UINT64_C(0xFFFFF7FFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_ISP_EN (IMG_UINT64_C(0x0000080000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PM_SHIFT (42U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PM_CLRMSK (IMG_UINT64_C(0xFFFFFBFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PM_EN (IMG_UINT64_C(0x0000040000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TDM_SHIFT (41U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TDM_CLRMSK (IMG_UINT64_C(0xFFFFFDFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TDM_EN (IMG_UINT64_C(0x0000020000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_CDM_SHIFT (40U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_CDM_CLRMSK (IMG_UINT64_C(0xFFFFFEFFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_CDM_EN (IMG_UINT64_C(0x0000010000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_PDS_STATE_SHIFT (39U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_PDS_STATE_CLRMSK (IMG_UINT64_C(0xFFFFFF7FFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_PDS_STATE_EN (IMG_UINT64_C(0x0000008000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_DB_SHIFT (38U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_DB_CLRMSK (IMG_UINT64_C(0xFFFFFFBFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_DB_EN (IMG_UINT64_C(0x0000004000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_VTX_VAR_SHIFT (37U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_VTX_VAR_CLRMSK (IMG_UINT64_C(0xFFFFFFDFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TSPF_VTX_VAR_EN (IMG_UINT64_C(0x0000002000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_VDM_SHIFT (36U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_VDM_CLRMSK (IMG_UINT64_C(0xFFFFFFEFFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_VDM_EN (IMG_UINT64_C(0x0000001000000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_STREAM_SHIFT (35U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_STREAM_CLRMSK (IMG_UINT64_C(0xFFFFFFF7FFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_STREAM_EN (IMG_UINT64_C(0x0000000800000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_REGION_SHIFT (34U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_REGION_CLRMSK (IMG_UINT64_C(0xFFFFFFFBFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PSG_REGION_EN (IMG_UINT64_C(0x0000000400000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_VCE_SHIFT (33U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_VCE_CLRMSK (IMG_UINT64_C(0xFFFFFFFDFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_VCE_EN (IMG_UINT64_C(0x0000000200000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PPP_SHIFT (32U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PPP_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_PPP_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FASTRENDER_SHIFT (31U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FASTRENDER_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FASTRENDER_EN (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PM_ALIST_SHIFT (30U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PM_ALIST_CLRMSK (IMG_UINT64_C(0xFFFFFFFFBFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PM_ALIST_EN (IMG_UINT64_C(0x0000000040000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_TE_SHIFT (29U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_TE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFDFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_TE_EN (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_VCE_SHIFT (28U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_VCE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFEFFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PB_VCE_EN (IMG_UINT64_C(0x0000000010000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_SHIFT (27U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF7FFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_EN (IMG_UINT64_C(0x0000000008000000)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_SHIFT (26U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFBFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_EN (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_SHIFT (25U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFDFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_EN (IMG_UINT64_C(0x0000000002000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_SHIFT (24U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFEFFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_EN (IMG_UINT64_C(0x0000000001000000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_SHIFT (23U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF7FFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_EN (IMG_UINT64_C(0x0000000000800000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_SHIFT (22U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFBFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_EN (IMG_UINT64_C(0x0000000000400000)) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_SHIFT (21U) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_SHIFT (20U) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFEFFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_EN (IMG_UINT64_C(0x0000000000100000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_SHIFT (19U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF7FFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_EN (IMG_UINT64_C(0x0000000000080000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_SHIFT (18U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFBFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_EN (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_SHIFT (17U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFDFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_EN (IMG_UINT64_C(0x0000000000020000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_SHIFT (16U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFEFFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_EN (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SHIFT (15U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF7FFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_EN (IMG_UINT64_C(0x0000000000008000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_SHIFT (14U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFBFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_EN (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_SHIFT (13U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFDFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_EN (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_SHIFT (12U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFEFFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_EN (IMG_UINT64_C(0x0000000000001000)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_SHIFT (11U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF7FF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_EN (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_SHIFT (10U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_EN (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_SHIFT (9U) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFDFF)) -#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_EN (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_SHIFT (8U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_EN (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_SHIFT (7U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF7F)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_EN (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_SHIFT (6U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFBF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_EN (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_SHIFT (5U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_SHIFT (4U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_EN (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_SHIFT (3U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT (2U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_SHIFT (1U) -#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_SLC_CTRL_BYPASS_ALL_SHIFT (0U) -#define RGX_CR_SLC_CTRL_BYPASS_ALL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_SLC_CTRL_BYPASS_ALL_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_SLC_STATUS1 -*/ -#define RGX_CR_SLC_STATUS1 (0x3870U) -#define RGX_CR_SLC_STATUS1_MASKFULL (IMG_UINT64_C(0x800003FF03FFFFFF)) -#define RGX_CR_SLC_STATUS1_PAUSED_SHIFT (63U) -#define RGX_CR_SLC_STATUS1_PAUSED_CLRMSK (IMG_UINT64_C(0x7FFFFFFFFFFFFFFF)) -#define RGX_CR_SLC_STATUS1_PAUSED_EN (IMG_UINT64_C(0x8000000000000000)) -#define RGX_CR_SLC_STATUS1_READS1_SHIFT (32U) -#define RGX_CR_SLC_STATUS1_READS1_CLRMSK (IMG_UINT64_C(0xFFFFFC00FFFFFFFF)) -#define RGX_CR_SLC_STATUS1_READS0_SHIFT (16U) -#define RGX_CR_SLC_STATUS1_READS0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFC00FFFF)) -#define RGX_CR_SLC_STATUS1_READS1_EXT_SHIFT (8U) -#define RGX_CR_SLC_STATUS1_READS1_EXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF00FF)) -#define RGX_CR_SLC_STATUS1_READS0_EXT_SHIFT (0U) -#define RGX_CR_SLC_STATUS1_READS0_EXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF00)) - - -/* - Register RGX_CR_SLC_IDLE -*/ -#define RGX_CR_SLC_IDLE (0x3898U) -#define RGX_CR_SLC_IDLE__XE_MEM__MASKFULL (IMG_UINT64_C(0x00000000000003FF)) -#define RGX_CR_SLC_IDLE_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_SLC_IDLE_MH_SYSARB1_SHIFT (9U) -#define RGX_CR_SLC_IDLE_MH_SYSARB1_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_SLC_IDLE_MH_SYSARB1_EN (0x00000200U) -#define RGX_CR_SLC_IDLE_MH_SYSARB0_SHIFT (8U) -#define RGX_CR_SLC_IDLE_MH_SYSARB0_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_SLC_IDLE_MH_SYSARB0_EN (0x00000100U) -#define RGX_CR_SLC_IDLE_IMGBV4_SHIFT (7U) -#define RGX_CR_SLC_IDLE_IMGBV4_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SLC_IDLE_IMGBV4_EN (0x00000080U) -#define RGX_CR_SLC_IDLE_CACHE_BANKS_SHIFT (6U) -#define RGX_CR_SLC_IDLE_CACHE_BANKS_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SLC_IDLE_CACHE_BANKS_EN (0x00000040U) -#define RGX_CR_SLC_IDLE_RBOFIFO_SHIFT (5U) -#define RGX_CR_SLC_IDLE_RBOFIFO_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SLC_IDLE_RBOFIFO_EN (0x00000020U) -#define RGX_CR_SLC_IDLE_FRC_CONV_SHIFT (4U) -#define RGX_CR_SLC_IDLE_FRC_CONV_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SLC_IDLE_FRC_CONV_EN (0x00000010U) -#define RGX_CR_SLC_IDLE_VXE_CONV_SHIFT (3U) -#define RGX_CR_SLC_IDLE_VXE_CONV_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SLC_IDLE_VXE_CONV_EN (0x00000008U) -#define RGX_CR_SLC_IDLE_VXD_CONV_SHIFT (2U) -#define RGX_CR_SLC_IDLE_VXD_CONV_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SLC_IDLE_VXD_CONV_EN (0x00000004U) -#define RGX_CR_SLC_IDLE_BIF1_CONV_SHIFT (1U) -#define RGX_CR_SLC_IDLE_BIF1_CONV_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SLC_IDLE_BIF1_CONV_EN (0x00000002U) -#define RGX_CR_SLC_IDLE_CBAR_SHIFT (0U) -#define RGX_CR_SLC_IDLE_CBAR_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SLC_IDLE_CBAR_EN (0x00000001U) - - -/* - Register RGX_CR_SLC_STATUS2 -*/ -#define RGX_CR_SLC_STATUS2 (0x3908U) -#define RGX_CR_SLC_STATUS2_MASKFULL (IMG_UINT64_C(0x000003FF03FFFFFF)) -#define RGX_CR_SLC_STATUS2_READS3_SHIFT (32U) -#define RGX_CR_SLC_STATUS2_READS3_CLRMSK (IMG_UINT64_C(0xFFFFFC00FFFFFFFF)) -#define RGX_CR_SLC_STATUS2_READS2_SHIFT (16U) -#define RGX_CR_SLC_STATUS2_READS2_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFC00FFFF)) -#define RGX_CR_SLC_STATUS2_READS3_EXT_SHIFT (8U) -#define RGX_CR_SLC_STATUS2_READS3_EXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF00FF)) -#define RGX_CR_SLC_STATUS2_READS2_EXT_SHIFT (0U) -#define RGX_CR_SLC_STATUS2_READS2_EXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF00)) - - -/* - Register RGX_CR_SLC_CTRL_MISC2 -*/ -#define RGX_CR_SLC_CTRL_MISC2 (0x3930U) -#define RGX_CR_SLC_CTRL_MISC2_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SLC_CTRL_MISC2_SCRAMBLE_BITS_SHIFT (0U) -#define RGX_CR_SLC_CTRL_MISC2_SCRAMBLE_BITS_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SLC_CROSSBAR_LOAD_BALANCE -*/ -#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE (0x3938U) -#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_SHIFT (0U) -#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_EN (0x00000001U) - - -/* - Register RGX_CR_SLC_SIZE_IN_KB -*/ -#define RGX_CR_SLC_SIZE_IN_KB (0x3970U) -#define RGX_CR_SLC_SIZE_IN_KB_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_SLC_SIZE_IN_KB_SIZE_SHIFT (0U) -#define RGX_CR_SLC_SIZE_IN_KB_SIZE_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_USC_TIMER -*/ -#define RGX_CR_USC_TIMER (0x46C8U) -#define RGX_CR_USC_TIMER_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_TIMER_CNT_SHIFT (0U) -#define RGX_CR_USC_TIMER_CNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_TIMER_CNT -*/ -#define RGX_CR_USC_TIMER_CNT (0x46D0U) -#define RGX_CR_USC_TIMER_CNT_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_USC_TIMER_CNT_RESET_SHIFT (0U) -#define RGX_CR_USC_TIMER_CNT_RESET_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_USC_TIMER_CNT_RESET_EN (0x00000001U) - - -/* - Register RGX_CR_USC_UVS0_CHECKSUM -*/ -#define RGX_CR_USC_UVS0_CHECKSUM (0x5000U) -#define RGX_CR_USC_UVS0_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS0_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS0_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVS1_CHECKSUM -*/ -#define RGX_CR_USC_UVS1_CHECKSUM (0x5008U) -#define RGX_CR_USC_UVS1_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS1_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS1_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVS2_CHECKSUM -*/ -#define RGX_CR_USC_UVS2_CHECKSUM (0x5010U) -#define RGX_CR_USC_UVS2_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS2_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS2_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVS3_CHECKSUM -*/ -#define RGX_CR_USC_UVS3_CHECKSUM (0x5018U) -#define RGX_CR_USC_UVS3_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS3_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS3_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PPP_SIGNATURE -*/ -#define RGX_CR_PPP_SIGNATURE (0x5020U) -#define RGX_CR_PPP_SIGNATURE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PPP_SIGNATURE_VALUE_SHIFT (0U) -#define RGX_CR_PPP_SIGNATURE_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TE_SIGNATURE -*/ -#define RGX_CR_TE_SIGNATURE (0x5028U) -#define RGX_CR_TE_SIGNATURE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TE_SIGNATURE_VALUE_SHIFT (0U) -#define RGX_CR_TE_SIGNATURE_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TE_CHECKSUM -*/ -#define RGX_CR_TE_CHECKSUM (0x5110U) -#define RGX_CR_TE_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TE_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_TE_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVB_CHECKSUM -*/ -#define RGX_CR_USC_UVB_CHECKSUM (0x5118U) -#define RGX_CR_USC_UVB_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVB_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVB_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_VCE_CHECKSUM -*/ -#define RGX_CR_VCE_CHECKSUM (0x5030U) -#define RGX_CR_VCE_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_VCE_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_VCE_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_ISP_PDS_CHECKSUM -*/ -#define RGX_CR_ISP_PDS_CHECKSUM (0x5038U) -#define RGX_CR_ISP_PDS_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_ISP_PDS_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_ISP_PDS_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_ISP_TPF_CHECKSUM -*/ -#define RGX_CR_ISP_TPF_CHECKSUM (0x5040U) -#define RGX_CR_ISP_TPF_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_ISP_TPF_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_ISP_TPF_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TFPU_PLANE0_CHECKSUM -*/ -#define RGX_CR_TFPU_PLANE0_CHECKSUM (0x5048U) -#define RGX_CR_TFPU_PLANE0_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TFPU_PLANE0_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_TFPU_PLANE0_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TFPU_PLANE1_CHECKSUM -*/ -#define RGX_CR_TFPU_PLANE1_CHECKSUM (0x5050U) -#define RGX_CR_TFPU_PLANE1_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TFPU_PLANE1_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_TFPU_PLANE1_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PBE_CHECKSUM -*/ -#define RGX_CR_PBE_CHECKSUM (0x5058U) -#define RGX_CR_PBE_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PBE_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_PBE_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PDS_DOUTM_STM_SIGNATURE -*/ -#define RGX_CR_PDS_DOUTM_STM_SIGNATURE (0x5060U) -#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_VALUE_SHIFT (0U) -#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_IFPU_ISP_CHECKSUM -*/ -#define RGX_CR_IFPU_ISP_CHECKSUM (0x5068U) -#define RGX_CR_IFPU_ISP_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_IFPU_ISP_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_IFPU_ISP_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVS4_CHECKSUM -*/ -#define RGX_CR_USC_UVS4_CHECKSUM (0x5100U) -#define RGX_CR_USC_UVS4_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS4_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS4_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_UVS5_CHECKSUM -*/ -#define RGX_CR_USC_UVS5_CHECKSUM (0x5108U) -#define RGX_CR_USC_UVS5_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_UVS5_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_USC_UVS5_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PPP_CLIP_CHECKSUM -*/ -#define RGX_CR_PPP_CLIP_CHECKSUM (0x5120U) -#define RGX_CR_PPP_CLIP_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PPP_CLIP_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_PPP_CLIP_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_TA_PHASE -*/ -#define RGX_CR_PERF_TA_PHASE (0x6008U) -#define RGX_CR_PERF_TA_PHASE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_TA_PHASE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_TA_PHASE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_3D_PHASE -*/ -#define RGX_CR_PERF_3D_PHASE (0x6010U) -#define RGX_CR_PERF_3D_PHASE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_3D_PHASE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_3D_PHASE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_COMPUTE_PHASE -*/ -#define RGX_CR_PERF_COMPUTE_PHASE (0x6018U) -#define RGX_CR_PERF_COMPUTE_PHASE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_COMPUTE_PHASE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_COMPUTE_PHASE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_TA_CYCLE -*/ -#define RGX_CR_PERF_TA_CYCLE (0x6020U) -#define RGX_CR_PERF_TA_CYCLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_TA_CYCLE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_TA_CYCLE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_3D_CYCLE -*/ -#define RGX_CR_PERF_3D_CYCLE (0x6028U) -#define RGX_CR_PERF_3D_CYCLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_3D_CYCLE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_3D_CYCLE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_COMPUTE_CYCLE -*/ -#define RGX_CR_PERF_COMPUTE_CYCLE (0x6030U) -#define RGX_CR_PERF_COMPUTE_CYCLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_COMPUTE_CYCLE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_COMPUTE_CYCLE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_TA_OR_3D_CYCLE -*/ -#define RGX_CR_PERF_TA_OR_3D_CYCLE (0x6038U) -#define RGX_CR_PERF_TA_OR_3D_CYCLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_TA_OR_3D_CYCLE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_TA_OR_3D_CYCLE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_INITIAL_TA_CYCLE -*/ -#define RGX_CR_PERF_INITIAL_TA_CYCLE (0x6040U) -#define RGX_CR_PERF_INITIAL_TA_CYCLE_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_INITIAL_TA_CYCLE_COUNT_SHIFT (0U) -#define RGX_CR_PERF_INITIAL_TA_CYCLE_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC0_READ_STALL -*/ -#define RGX_CR_PERF_SLC0_READ_STALL (0x60B8U) -#define RGX_CR_PERF_SLC0_READ_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC0_READ_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC0_READ_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC0_WRITE_STALL -*/ -#define RGX_CR_PERF_SLC0_WRITE_STALL (0x60C0U) -#define RGX_CR_PERF_SLC0_WRITE_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC0_WRITE_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC0_WRITE_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC1_READ_STALL -*/ -#define RGX_CR_PERF_SLC1_READ_STALL (0x60E0U) -#define RGX_CR_PERF_SLC1_READ_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC1_READ_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC1_READ_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC1_WRITE_STALL -*/ -#define RGX_CR_PERF_SLC1_WRITE_STALL (0x60E8U) -#define RGX_CR_PERF_SLC1_WRITE_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC1_WRITE_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC1_WRITE_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC2_READ_STALL -*/ -#define RGX_CR_PERF_SLC2_READ_STALL (0x6158U) -#define RGX_CR_PERF_SLC2_READ_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC2_READ_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC2_READ_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC2_WRITE_STALL -*/ -#define RGX_CR_PERF_SLC2_WRITE_STALL (0x6160U) -#define RGX_CR_PERF_SLC2_WRITE_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC2_WRITE_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC2_WRITE_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC3_READ_STALL -*/ -#define RGX_CR_PERF_SLC3_READ_STALL (0x6180U) -#define RGX_CR_PERF_SLC3_READ_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC3_READ_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC3_READ_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_SLC3_WRITE_STALL -*/ -#define RGX_CR_PERF_SLC3_WRITE_STALL (0x6188U) -#define RGX_CR_PERF_SLC3_WRITE_STALL_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_SLC3_WRITE_STALL_COUNT_SHIFT (0U) -#define RGX_CR_PERF_SLC3_WRITE_STALL_COUNT_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PERF_3D_SPINUP -*/ -#define RGX_CR_PERF_3D_SPINUP (0x6220U) -#define RGX_CR_PERF_3D_SPINUP_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PERF_3D_SPINUP_CYCLES_SHIFT (0U) -#define RGX_CR_PERF_3D_SPINUP_CYCLES_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_AXI_ACE_LITE_CONFIGURATION -*/ -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION (0x38C0U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_MASKFULL (IMG_UINT64_C(0x00003FFFFFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ENABLE_FENCE_OUT_SHIFT (45U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ENABLE_FENCE_OUT_CLRMSK (IMG_UINT64_C(0xFFFFDFFFFFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ENABLE_FENCE_OUT_EN (IMG_UINT64_C(0x0000200000000000)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_OSID_SECURITY_SHIFT (37U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_OSID_SECURITY_CLRMSK (IMG_UINT64_C(0xFFFFE01FFFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_SHIFT (36U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_CLRMSK (IMG_UINT64_C(0xFFFFFFEFFFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_EN (IMG_UINT64_C(0x0000001000000000)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_SHIFT (35U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_CLRMSK (IMG_UINT64_C(0xFFFFFFF7FFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_EN (IMG_UINT64_C(0x0000000800000000)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_SHIFT (34U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_CLRMSK (IMG_UINT64_C(0xFFFFFFFBFFFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_EN (IMG_UINT64_C(0x0000000400000000)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT (30U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_CLRMSK (IMG_UINT64_C(0xFFFFFFFC3FFFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT (26U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFC3FFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT (22U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFC3FFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_BARRIER_SHIFT (20U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_BARRIER_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFCFFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_BARRIER_SHIFT (18U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_BARRIER_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF3FFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT (16U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFCFFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT (14U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF3FFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT (12U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFCFFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT (10U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF3FF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT (8U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFCFF)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_NON_SNOOPING_SHIFT (4U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF0F)) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_NON_SNOOPING_SHIFT (0U) -#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF0)) - - -/* - Register RGX_CR_POWER_ESTIMATE_RESULT -*/ -#define RGX_CR_POWER_ESTIMATE_RESULT (0x6328U) -#define RGX_CR_POWER_ESTIMATE_RESULT_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_POWER_ESTIMATE_RESULT_VALUE_SHIFT (0U) -#define RGX_CR_POWER_ESTIMATE_RESULT_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TA_PERF -*/ -#define RGX_CR_TA_PERF (0x7600U) -#define RGX_CR_TA_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_TA_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_TA_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_TA_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_TA_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_TA_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_TA_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_TA_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_TA_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_TA_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_TA_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_TA_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_TA_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_TA_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_TA_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TA_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_TA_PERF_SELECT0 -*/ -#define RGX_CR_TA_PERF_SELECT0 (0x7608U) -#define RGX_CR_TA_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TA_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TA_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TA_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_TA_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TA_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TA_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TA_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TA_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TA_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TA_PERF_SELECT1 -*/ -#define RGX_CR_TA_PERF_SELECT1 (0x7610U) -#define RGX_CR_TA_PERF_SELECT1_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TA_PERF_SELECT1_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TA_PERF_SELECT1_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT1_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TA_PERF_SELECT1_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT1_MODE_SHIFT (21U) -#define RGX_CR_TA_PERF_SELECT1_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TA_PERF_SELECT1_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TA_PERF_SELECT1_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TA_PERF_SELECT1_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TA_PERF_SELECT1_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TA_PERF_SELECT1_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TA_PERF_SELECT2 -*/ -#define RGX_CR_TA_PERF_SELECT2 (0x7618U) -#define RGX_CR_TA_PERF_SELECT2_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TA_PERF_SELECT2_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TA_PERF_SELECT2_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT2_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TA_PERF_SELECT2_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT2_MODE_SHIFT (21U) -#define RGX_CR_TA_PERF_SELECT2_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TA_PERF_SELECT2_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TA_PERF_SELECT2_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TA_PERF_SELECT2_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TA_PERF_SELECT2_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TA_PERF_SELECT2_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TA_PERF_SELECT3 -*/ -#define RGX_CR_TA_PERF_SELECT3 (0x7620U) -#define RGX_CR_TA_PERF_SELECT3_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TA_PERF_SELECT3_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TA_PERF_SELECT3_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT3_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TA_PERF_SELECT3_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TA_PERF_SELECT3_MODE_SHIFT (21U) -#define RGX_CR_TA_PERF_SELECT3_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TA_PERF_SELECT3_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TA_PERF_SELECT3_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TA_PERF_SELECT3_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TA_PERF_SELECT3_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TA_PERF_SELECT3_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TA_PERF_SELECTED_BITS -*/ -#define RGX_CR_TA_PERF_SELECTED_BITS (0x7648U) -#define RGX_CR_TA_PERF_SELECTED_BITS_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG3_SHIFT (48U) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG3_CLRMSK (IMG_UINT64_C(0x0000FFFFFFFFFFFF)) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG2_SHIFT (32U) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG2_CLRMSK (IMG_UINT64_C(0xFFFF0000FFFFFFFF)) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG1_SHIFT (16U) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG1_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000FFFF)) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG0_SHIFT (0U) -#define RGX_CR_TA_PERF_SELECTED_BITS_REG0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TA_PERF_COUNTER_0 -*/ -#define RGX_CR_TA_PERF_COUNTER_0 (0x7650U) -#define RGX_CR_TA_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TA_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_TA_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TA_PERF_COUNTER_1 -*/ -#define RGX_CR_TA_PERF_COUNTER_1 (0x7658U) -#define RGX_CR_TA_PERF_COUNTER_1_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TA_PERF_COUNTER_1_REG_SHIFT (0U) -#define RGX_CR_TA_PERF_COUNTER_1_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TA_PERF_COUNTER_2 -*/ -#define RGX_CR_TA_PERF_COUNTER_2 (0x7660U) -#define RGX_CR_TA_PERF_COUNTER_2_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TA_PERF_COUNTER_2_REG_SHIFT (0U) -#define RGX_CR_TA_PERF_COUNTER_2_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TA_PERF_COUNTER_3 -*/ -#define RGX_CR_TA_PERF_COUNTER_3 (0x7668U) -#define RGX_CR_TA_PERF_COUNTER_3_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TA_PERF_COUNTER_3_REG_SHIFT (0U) -#define RGX_CR_TA_PERF_COUNTER_3_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_RASTERISATION_PERF -*/ -#define RGX_CR_RASTERISATION_PERF (0x7700U) -#define RGX_CR_RASTERISATION_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_RASTERISATION_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_RASTERISATION_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_RASTERISATION_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_RASTERISATION_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_RASTERISATION_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_RASTERISATION_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_RASTERISATION_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_RASTERISATION_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_RASTERISATION_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_RASTERISATION_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_RASTERISATION_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_RASTERISATION_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_RASTERISATION_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_RASTERISATION_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_RASTERISATION_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_RASTERISATION_PERF_SELECT0 -*/ -#define RGX_CR_RASTERISATION_PERF_SELECT0 (0x7708U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_RASTERISATION_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_RASTERISATION_PERF_COUNTER_0 -*/ -#define RGX_CR_RASTERISATION_PERF_COUNTER_0 (0x7750U) -#define RGX_CR_RASTERISATION_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_RASTERISATION_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_RASTERISATION_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_HUB_BIFPMCACHE_PERF -*/ -#define RGX_CR_HUB_BIFPMCACHE_PERF (0x7800U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_HUB_BIFPMCACHE_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0 -*/ -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0 (0x7808U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0 -*/ -#define RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0 (0x7850U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TPU_MCU_L0_PERF -*/ -#define RGX_CR_TPU_MCU_L0_PERF (0x7900U) -#define RGX_CR_TPU_MCU_L0_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_TPU_MCU_L0_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_TPU_MCU_L0_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_TPU_MCU_L0_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TPU_MCU_L0_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_TPU_MCU_L0_PERF_SELECT0 -*/ -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0 (0x7908U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TPU_MCU_L0_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TPU_MCU_L0_PERF_COUNTER_0 -*/ -#define RGX_CR_TPU_MCU_L0_PERF_COUNTER_0 (0x7950U) -#define RGX_CR_TPU_MCU_L0_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TPU_MCU_L0_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_TPU_MCU_L0_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_USC_PERF -*/ -#define RGX_CR_USC_PERF (0x8100U) -#define RGX_CR_USC_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_USC_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_USC_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_USC_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_USC_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_USC_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_USC_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_USC_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_USC_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_USC_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_USC_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_USC_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_USC_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_USC_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_USC_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_USC_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_USC_PERF_SELECT0 -*/ -#define RGX_CR_USC_PERF_SELECT0 (0x8108U) -#define RGX_CR_USC_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_USC_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_USC_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_USC_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_USC_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_USC_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_USC_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_USC_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_USC_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_USC_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_USC_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_USC_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_USC_PERF_COUNTER_0 -*/ -#define RGX_CR_USC_PERF_COUNTER_0 (0x8150U) -#define RGX_CR_USC_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_USC_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_USC_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_JONES_IDLE -*/ -#define RGX_CR_JONES_IDLE (0x8328U) -#define RGX_CR_JONES_IDLE_MASKFULL (IMG_UINT64_C(0x0000000000007FFF)) -#define RGX_CR_JONES_IDLE_TDM_SHIFT (14U) -#define RGX_CR_JONES_IDLE_TDM_CLRMSK (0xFFFFBFFFU) -#define RGX_CR_JONES_IDLE_TDM_EN (0x00004000U) -#define RGX_CR_JONES_IDLE_FB_CDC_TLA_SHIFT (13U) -#define RGX_CR_JONES_IDLE_FB_CDC_TLA_CLRMSK (0xFFFFDFFFU) -#define RGX_CR_JONES_IDLE_FB_CDC_TLA_EN (0x00002000U) -#define RGX_CR_JONES_IDLE_FB_CDC_SHIFT (12U) -#define RGX_CR_JONES_IDLE_FB_CDC_CLRMSK (0xFFFFEFFFU) -#define RGX_CR_JONES_IDLE_FB_CDC_EN (0x00001000U) -#define RGX_CR_JONES_IDLE_MMU_SHIFT (11U) -#define RGX_CR_JONES_IDLE_MMU_CLRMSK (0xFFFFF7FFU) -#define RGX_CR_JONES_IDLE_MMU_EN (0x00000800U) -#define RGX_CR_JONES_IDLE_TLA_SHIFT (10U) -#define RGX_CR_JONES_IDLE_TLA_CLRMSK (0xFFFFFBFFU) -#define RGX_CR_JONES_IDLE_TLA_EN (0x00000400U) -#define RGX_CR_JONES_IDLE_GARTEN_SHIFT (9U) -#define RGX_CR_JONES_IDLE_GARTEN_CLRMSK (0xFFFFFDFFU) -#define RGX_CR_JONES_IDLE_GARTEN_EN (0x00000200U) -#define RGX_CR_JONES_IDLE_HOSTIF_SHIFT (8U) -#define RGX_CR_JONES_IDLE_HOSTIF_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_JONES_IDLE_HOSTIF_EN (0x00000100U) -#define RGX_CR_JONES_IDLE_SOCIF_SHIFT (7U) -#define RGX_CR_JONES_IDLE_SOCIF_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_JONES_IDLE_SOCIF_EN (0x00000080U) -#define RGX_CR_JONES_IDLE_TILING_SHIFT (6U) -#define RGX_CR_JONES_IDLE_TILING_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_JONES_IDLE_TILING_EN (0x00000040U) -#define RGX_CR_JONES_IDLE_IPP_SHIFT (5U) -#define RGX_CR_JONES_IDLE_IPP_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_JONES_IDLE_IPP_EN (0x00000020U) -#define RGX_CR_JONES_IDLE_USCS_SHIFT (4U) -#define RGX_CR_JONES_IDLE_USCS_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_JONES_IDLE_USCS_EN (0x00000010U) -#define RGX_CR_JONES_IDLE_PM_SHIFT (3U) -#define RGX_CR_JONES_IDLE_PM_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_JONES_IDLE_PM_EN (0x00000008U) -#define RGX_CR_JONES_IDLE_CDM_SHIFT (2U) -#define RGX_CR_JONES_IDLE_CDM_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_JONES_IDLE_CDM_EN (0x00000004U) -#define RGX_CR_JONES_IDLE_VDM_SHIFT (1U) -#define RGX_CR_JONES_IDLE_VDM_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_JONES_IDLE_VDM_EN (0x00000002U) -#define RGX_CR_JONES_IDLE_BIF_SHIFT (0U) -#define RGX_CR_JONES_IDLE_BIF_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_JONES_IDLE_BIF_EN (0x00000001U) - - -/* - Register RGX_CR_TORNADO_PERF -*/ -#define RGX_CR_TORNADO_PERF (0x8228U) -#define RGX_CR_TORNADO_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_TORNADO_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_TORNADO_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_TORNADO_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_TORNADO_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_TORNADO_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_TORNADO_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_TORNADO_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_TORNADO_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_TORNADO_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_TORNADO_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_TORNADO_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_TORNADO_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_TORNADO_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_TORNADO_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TORNADO_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_TORNADO_PERF_SELECT0 -*/ -#define RGX_CR_TORNADO_PERF_SELECT0 (0x8230U) -#define RGX_CR_TORNADO_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_TORNADO_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TORNADO_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TORNADO_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TORNADO_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TORNADO_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_TORNADO_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_TORNADO_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_TORNADO_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TORNADO_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_TORNADO_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TORNADO_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TORNADO_PERF_COUNTER_0 -*/ -#define RGX_CR_TORNADO_PERF_COUNTER_0 (0x8268U) -#define RGX_CR_TORNADO_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TORNADO_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_TORNADO_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_TEXAS_PERF -*/ -#define RGX_CR_TEXAS_PERF (0x8290U) -#define RGX_CR_TEXAS_PERF_MASKFULL (IMG_UINT64_C(0x000000000000007F)) -#define RGX_CR_TEXAS_PERF_CLR_5_SHIFT (6U) -#define RGX_CR_TEXAS_PERF_CLR_5_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_TEXAS_PERF_CLR_5_EN (0x00000040U) -#define RGX_CR_TEXAS_PERF_CLR_4_SHIFT (5U) -#define RGX_CR_TEXAS_PERF_CLR_4_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_TEXAS_PERF_CLR_4_EN (0x00000020U) -#define RGX_CR_TEXAS_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_TEXAS_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_TEXAS_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_TEXAS_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_TEXAS_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_TEXAS_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_TEXAS_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_TEXAS_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_TEXAS_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_TEXAS_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_TEXAS_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_TEXAS_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_TEXAS_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_TEXAS_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_TEXAS_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_TEXAS_PERF_SELECT0 -*/ -#define RGX_CR_TEXAS_PERF_SELECT0 (0x8298U) -#define RGX_CR_TEXAS_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF803FFFFF)) -#define RGX_CR_TEXAS_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_TEXAS_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_TEXAS_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_TEXAS_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_TEXAS_PERF_SELECT0_MODE_SHIFT (31U) -#define RGX_CR_TEXAS_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_TEXAS_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_TEXAS_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_TEXAS_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFC0FFFF)) -#define RGX_CR_TEXAS_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_TEXAS_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_TEXAS_PERF_COUNTER_0 -*/ -#define RGX_CR_TEXAS_PERF_COUNTER_0 (0x82D8U) -#define RGX_CR_TEXAS_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_TEXAS_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_TEXAS_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_JONES_PERF -*/ -#define RGX_CR_JONES_PERF (0x8330U) -#define RGX_CR_JONES_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_JONES_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_JONES_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_JONES_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_JONES_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_JONES_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_JONES_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_JONES_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_JONES_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_JONES_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_JONES_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_JONES_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_JONES_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_JONES_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_JONES_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_JONES_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_JONES_PERF_SELECT0 -*/ -#define RGX_CR_JONES_PERF_SELECT0 (0x8338U) -#define RGX_CR_JONES_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_JONES_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_JONES_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_JONES_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_JONES_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_JONES_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_JONES_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_JONES_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_JONES_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_JONES_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_JONES_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_JONES_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_JONES_PERF_COUNTER_0 -*/ -#define RGX_CR_JONES_PERF_COUNTER_0 (0x8368U) -#define RGX_CR_JONES_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_JONES_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_JONES_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_BLACKPEARL_PERF -*/ -#define RGX_CR_BLACKPEARL_PERF (0x8400U) -#define RGX_CR_BLACKPEARL_PERF_MASKFULL (IMG_UINT64_C(0x000000000000007F)) -#define RGX_CR_BLACKPEARL_PERF_CLR_5_SHIFT (6U) -#define RGX_CR_BLACKPEARL_PERF_CLR_5_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_BLACKPEARL_PERF_CLR_5_EN (0x00000040U) -#define RGX_CR_BLACKPEARL_PERF_CLR_4_SHIFT (5U) -#define RGX_CR_BLACKPEARL_PERF_CLR_4_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_BLACKPEARL_PERF_CLR_4_EN (0x00000020U) -#define RGX_CR_BLACKPEARL_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_BLACKPEARL_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BLACKPEARL_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_BLACKPEARL_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_BLACKPEARL_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_BLACKPEARL_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_BLACKPEARL_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_BLACKPEARL_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BLACKPEARL_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_BLACKPEARL_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_BLACKPEARL_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BLACKPEARL_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_BLACKPEARL_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_BLACKPEARL_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BLACKPEARL_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_BLACKPEARL_PERF_SELECT0 -*/ -#define RGX_CR_BLACKPEARL_PERF_SELECT0 (0x8408U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF803FFFFF)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_MODE_SHIFT (31U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFC0FFFF)) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_BLACKPEARL_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_BLACKPEARL_PERF_COUNTER_0 -*/ -#define RGX_CR_BLACKPEARL_PERF_COUNTER_0 (0x8448U) -#define RGX_CR_BLACKPEARL_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_BLACKPEARL_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_BLACKPEARL_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_PBE_PERF -*/ -#define RGX_CR_PBE_PERF (0x8478U) -#define RGX_CR_PBE_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_PBE_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_PBE_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_PBE_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_PBE_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_PBE_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_PBE_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_PBE_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_PBE_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_PBE_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_PBE_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_PBE_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_PBE_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_PBE_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_PBE_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_PBE_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_PBE_PERF_SELECT0 -*/ -#define RGX_CR_PBE_PERF_SELECT0 (0x8480U) -#define RGX_CR_PBE_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_PBE_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_PBE_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_PBE_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_PBE_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_PBE_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_PBE_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_PBE_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_PBE_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_PBE_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_PBE_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_PBE_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_PBE_PERF_COUNTER_0 -*/ -#define RGX_CR_PBE_PERF_COUNTER_0 (0x84B0U) -#define RGX_CR_PBE_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_PBE_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_PBE_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_OCP_REVINFO -*/ -#define RGX_CR_OCP_REVINFO (0x9000U) -#define RGX_CR_OCP_REVINFO_MASKFULL (IMG_UINT64_C(0x00000007FFFFFFFF)) -#define RGX_CR_OCP_REVINFO_HWINFO_SYSBUS_SHIFT (33U) -#define RGX_CR_OCP_REVINFO_HWINFO_SYSBUS_CLRMSK (IMG_UINT64_C(0xFFFFFFF9FFFFFFFF)) -#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_SHIFT (32U) -#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_OCP_REVINFO_REVISION_SHIFT (0U) -#define RGX_CR_OCP_REVINFO_REVISION_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_OCP_SYSCONFIG -*/ -#define RGX_CR_OCP_SYSCONFIG (0x9010U) -#define RGX_CR_OCP_SYSCONFIG_MASKFULL (IMG_UINT64_C(0x0000000000000FFF)) -#define RGX_CR_OCP_SYSCONFIG_DUST2_STANDBY_MODE_SHIFT (10U) -#define RGX_CR_OCP_SYSCONFIG_DUST2_STANDBY_MODE_CLRMSK (0xFFFFF3FFU) -#define RGX_CR_OCP_SYSCONFIG_DUST1_STANDBY_MODE_SHIFT (8U) -#define RGX_CR_OCP_SYSCONFIG_DUST1_STANDBY_MODE_CLRMSK (0xFFFFFCFFU) -#define RGX_CR_OCP_SYSCONFIG_DUST0_STANDBY_MODE_SHIFT (6U) -#define RGX_CR_OCP_SYSCONFIG_DUST0_STANDBY_MODE_CLRMSK (0xFFFFFF3FU) -#define RGX_CR_OCP_SYSCONFIG_RASCAL_STANDBYMODE_SHIFT (4U) -#define RGX_CR_OCP_SYSCONFIG_RASCAL_STANDBYMODE_CLRMSK (0xFFFFFFCFU) -#define RGX_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT (2U) -#define RGX_CR_OCP_SYSCONFIG_STANDBY_MODE_CLRMSK (0xFFFFFFF3U) -#define RGX_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT (0U) -#define RGX_CR_OCP_SYSCONFIG_IDLE_MODE_CLRMSK (0xFFFFFFFCU) - - -/* - Register RGX_CR_OCP_IRQSTATUS_RAW_0 -*/ -#define RGX_CR_OCP_IRQSTATUS_RAW_0 (0x9020U) -#define RGX_CR_OCP_IRQSTATUS_RAW_0_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQSTATUS_RAW_1 -*/ -#define RGX_CR_OCP_IRQSTATUS_RAW_1 (0x9028U) -#define RGX_CR_OCP_IRQSTATUS_RAW_1_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQSTATUS_RAW_2 -*/ -#define RGX_CR_OCP_IRQSTATUS_RAW_2 (0x9030U) -#define RGX_CR_OCP_IRQSTATUS_RAW_2_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQSTATUS_0 -*/ -#define RGX_CR_OCP_IRQSTATUS_0 (0x9038U) -#define RGX_CR_OCP_IRQSTATUS_0_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQSTATUS_1 -*/ -#define RGX_CR_OCP_IRQSTATUS_1 (0x9040U) -#define RGX_CR_OCP_IRQSTATUS_1_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQSTATUS_2 -*/ -#define RGX_CR_OCP_IRQSTATUS_2 (0x9048U) -#define RGX_CR_OCP_IRQSTATUS_2_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_SHIFT (0U) -#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_SET_0 -*/ -#define RGX_CR_OCP_IRQENABLE_SET_0 (0x9050U) -#define RGX_CR_OCP_IRQENABLE_SET_0_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_SET_1 -*/ -#define RGX_CR_OCP_IRQENABLE_SET_1 (0x9058U) -#define RGX_CR_OCP_IRQENABLE_SET_1_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_SET_2 -*/ -#define RGX_CR_OCP_IRQENABLE_SET_2 (0x9060U) -#define RGX_CR_OCP_IRQENABLE_SET_2_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_CLR_0 -*/ -#define RGX_CR_OCP_IRQENABLE_CLR_0 (0x9068U) -#define RGX_CR_OCP_IRQENABLE_CLR_0_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_CLR_1 -*/ -#define RGX_CR_OCP_IRQENABLE_CLR_1 (0x9070U) -#define RGX_CR_OCP_IRQENABLE_CLR_1_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQENABLE_CLR_2 -*/ -#define RGX_CR_OCP_IRQENABLE_CLR_2 (0x9078U) -#define RGX_CR_OCP_IRQENABLE_CLR_2_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_SHIFT (0U) -#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_IRQ_EVENT -*/ -#define RGX_CR_OCP_IRQ_EVENT (0x9080U) -#define RGX_CR_OCP_IRQ_EVENT_MASKFULL (IMG_UINT64_C(0x00000000000FFFFF)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_SHIFT (19U) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF7FFFF)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_EN (IMG_UINT64_C(0x0000000000080000)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_SHIFT (18U) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFBFFFF)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_EN (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_SHIFT (17U) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFDFFFF)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_EN (IMG_UINT64_C(0x0000000000020000)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_SHIFT (16U) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFEFFFF)) -#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_EN (IMG_UINT64_C(0x0000000000010000)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_SHIFT (15U) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF7FFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0x0000000000008000)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_SHIFT (14U) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFBFFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_EN (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_SHIFT (13U) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFDFFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_EN (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_SHIFT (12U) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFEFFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0x0000000000001000)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_SHIFT (11U) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF7FF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_SHIFT (10U) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_EN (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_SHIFT (9U) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFDFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_EN (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_SHIFT (8U) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFEFF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_SHIFT (7U) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF7F)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_SHIFT (6U) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFBF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_EN (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_SHIFT (5U) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_SHIFT (4U) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_SHIFT (3U) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_SHIFT (2U) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_SHIFT (1U) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_SHIFT (0U) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_OCP_DEBUG_CONFIG -*/ -#define RGX_CR_OCP_DEBUG_CONFIG (0x9088U) -#define RGX_CR_OCP_DEBUG_CONFIG_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_OCP_DEBUG_CONFIG_REG_SHIFT (0U) -#define RGX_CR_OCP_DEBUG_CONFIG_REG_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_OCP_DEBUG_CONFIG_REG_EN (0x00000001U) - - -/* - Register RGX_CR_OCP_DEBUG_STATUS -*/ -#define RGX_CR_OCP_DEBUG_STATUS (0x9090U) -#define RGX_CR_OCP_DEBUG_STATUS_MASKFULL (IMG_UINT64_C(0x001F1F77FFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SDISCACK_SHIFT (51U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SDISCACK_CLRMSK (IMG_UINT64_C(0xFFE7FFFFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_SHIFT (50U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFBFFFFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_EN (IMG_UINT64_C(0x0004000000000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_MCONNECT_SHIFT (48U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFCFFFFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SDISCACK_SHIFT (43U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SDISCACK_CLRMSK (IMG_UINT64_C(0xFFFFE7FFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_SHIFT (42U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFBFFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_EN (IMG_UINT64_C(0x0000040000000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_MCONNECT_SHIFT (40U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFCFFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_SHIFT (38U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_CLRMSK (IMG_UINT64_C(0xFFFFFFBFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_EN (IMG_UINT64_C(0x0000004000000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_SHIFT (37U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_CLRMSK (IMG_UINT64_C(0xFFFFFFDFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_EN (IMG_UINT64_C(0x0000002000000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_SHIFT (36U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_CLRMSK (IMG_UINT64_C(0xFFFFFFEFFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_EN (IMG_UINT64_C(0x0000001000000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_SHIFT (34U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_CLRMSK (IMG_UINT64_C(0xFFFFFFFBFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_EN (IMG_UINT64_C(0x0000000400000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_SHIFT (33U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_CLRMSK (IMG_UINT64_C(0xFFFFFFFDFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_EN (IMG_UINT64_C(0x0000000200000000)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_SHIFT (32U) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_CLRMSK (IMG_UINT64_C(0xFFFFFFFEFFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_EN (IMG_UINT64_C(0x0000000100000000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_SHIFT (31U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_CLRMSK (IMG_UINT64_C(0xFFFFFFFF7FFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_EN (IMG_UINT64_C(0x0000000080000000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_SHIFT (30U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFBFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_EN (IMG_UINT64_C(0x0000000040000000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_SHIFT (29U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_CLRMSK (IMG_UINT64_C(0xFFFFFFFFDFFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_EN (IMG_UINT64_C(0x0000000020000000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCACK_SHIFT (27U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFE7FFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_SHIFT (26U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFBFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_EN (IMG_UINT64_C(0x0000000004000000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MCONNECT_SHIFT (24U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFCFFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_SHIFT (23U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF7FFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_EN (IMG_UINT64_C(0x0000000000800000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_SHIFT (22U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFBFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_EN (IMG_UINT64_C(0x0000000000400000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_SHIFT (21U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCACK_SHIFT (19U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE7FFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_SHIFT (18U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFBFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_EN (IMG_UINT64_C(0x0000000000040000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MCONNECT_SHIFT (16U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFCFFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_SHIFT (15U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF7FFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_EN (IMG_UINT64_C(0x0000000000008000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_SHIFT (14U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFBFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_EN (IMG_UINT64_C(0x0000000000004000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_SHIFT (13U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFDFFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_EN (IMG_UINT64_C(0x0000000000002000)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCACK_SHIFT (11U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFE7FF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_SHIFT (10U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFBFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_EN (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MCONNECT_SHIFT (8U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFCFF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_SHIFT (7U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF7F)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_EN (IMG_UINT64_C(0x0000000000000080)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_SHIFT (6U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFBF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_EN (IMG_UINT64_C(0x0000000000000040)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_SHIFT (5U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCACK_SHIFT (3U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFE7)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_SHIFT (2U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MCONNECT_SHIFT (0U) -#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MCONNECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFC)) - - -#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_SHIFT (6U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_EN (0x00000040U) -#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_SHIFT (5U) -#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_EN (0x00000020U) -#define RGX_CR_BIF_TRUST_DM_TYPE_META_SHIFT (4U) -#define RGX_CR_BIF_TRUST_DM_TYPE_META_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BIF_TRUST_DM_TYPE_META_EN (0x00000010U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_SHIFT (3U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_EN (0x00000008U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_SHIFT (2U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_EN (0x00000004U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_SHIFT (1U) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_EN (0x00000002U) -#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_SHIFT (0U) -#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_EN (0x00000001U) - - -#define RGX_CR_BIF_TRUST_DM_MASK (0x0000007FU) - - -/* - Register RGX_CR_BIF_TRUST -*/ -#define RGX_CR_BIF_TRUST (0xA000U) -#define RGX_CR_BIF_TRUST_MASKFULL (IMG_UINT64_C(0x00000000001FFFFF)) -#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_SHIFT (20U) -#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_CLRMSK (0xFFEFFFFFU) -#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_EN (0x00100000U) -#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_SHIFT (19U) -#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_CLRMSK (0xFFF7FFFFU) -#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_EN (0x00080000U) -#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_SHIFT (18U) -#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_CLRMSK (0xFFFBFFFFU) -#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_EN (0x00040000U) -#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_SHIFT (17U) -#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_EN (0x00020000U) -#define RGX_CR_BIF_TRUST_ENABLE_SHIFT (16U) -#define RGX_CR_BIF_TRUST_ENABLE_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_BIF_TRUST_ENABLE_EN (0x00010000U) -#define RGX_CR_BIF_TRUST_DM_TRUSTED_SHIFT (9U) -#define RGX_CR_BIF_TRUST_DM_TRUSTED_CLRMSK (0xFFFF01FFU) -#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_SHIFT (8U) -#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_EN (0x00000100U) -#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_SHIFT (7U) -#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_EN (0x00000080U) -#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_SHIFT (6U) -#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_EN (0x00000040U) -#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_SHIFT (5U) -#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_EN (0x00000020U) -#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_SHIFT (4U) -#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_EN (0x00000010U) -#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_SHIFT (3U) -#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_EN (0x00000008U) -#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_SHIFT (2U) -#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_EN (0x00000004U) -#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_SHIFT (1U) -#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_EN (0x00000002U) -#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_SHIFT (0U) -#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_EN (0x00000001U) - - -/* - Register RGX_CR_SYS_BUS_SECURE -*/ -#define RGX_CR_SYS_BUS_SECURE (0xA100U) -#define RGX_CR_SYS_BUS_SECURE__SECR__MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_SYS_BUS_SECURE_MASKFULL (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_SYS_BUS_SECURE_ENABLE_SHIFT (0U) -#define RGX_CR_SYS_BUS_SECURE_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SYS_BUS_SECURE_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_FBA_FC0_CHECKSUM -*/ -#define RGX_CR_FBA_FC0_CHECKSUM (0xD170U) -#define RGX_CR_FBA_FC0_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FBA_FC0_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_FBA_FC0_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FBA_FC1_CHECKSUM -*/ -#define RGX_CR_FBA_FC1_CHECKSUM (0xD178U) -#define RGX_CR_FBA_FC1_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FBA_FC1_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_FBA_FC1_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FBA_FC2_CHECKSUM -*/ -#define RGX_CR_FBA_FC2_CHECKSUM (0xD180U) -#define RGX_CR_FBA_FC2_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FBA_FC2_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_FBA_FC2_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_FBA_FC3_CHECKSUM -*/ -#define RGX_CR_FBA_FC3_CHECKSUM (0xD188U) -#define RGX_CR_FBA_FC3_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_FBA_FC3_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_FBA_FC3_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_CLK_CTRL2 -*/ -#define RGX_CR_CLK_CTRL2 (0xD200U) -#define RGX_CR_CLK_CTRL2_MASKFULL (IMG_UINT64_C(0x0000000000000F33)) -#define RGX_CR_CLK_CTRL2_MCU_FBTC_SHIFT (10U) -#define RGX_CR_CLK_CTRL2_MCU_FBTC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF3FF)) -#define RGX_CR_CLK_CTRL2_MCU_FBTC_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL2_MCU_FBTC_ON (IMG_UINT64_C(0x0000000000000400)) -#define RGX_CR_CLK_CTRL2_MCU_FBTC_AUTO (IMG_UINT64_C(0x0000000000000800)) -#define RGX_CR_CLK_CTRL2_VRDM_SHIFT (8U) -#define RGX_CR_CLK_CTRL2_VRDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFCFF)) -#define RGX_CR_CLK_CTRL2_VRDM_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL2_VRDM_ON (IMG_UINT64_C(0x0000000000000100)) -#define RGX_CR_CLK_CTRL2_VRDM_AUTO (IMG_UINT64_C(0x0000000000000200)) -#define RGX_CR_CLK_CTRL2_SH_SHIFT (4U) -#define RGX_CR_CLK_CTRL2_SH_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFCF)) -#define RGX_CR_CLK_CTRL2_SH_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL2_SH_ON (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_CLK_CTRL2_SH_AUTO (IMG_UINT64_C(0x0000000000000020)) -#define RGX_CR_CLK_CTRL2_FBA_SHIFT (0U) -#define RGX_CR_CLK_CTRL2_FBA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFC)) -#define RGX_CR_CLK_CTRL2_FBA_OFF (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_CTRL2_FBA_ON (IMG_UINT64_C(0x0000000000000001)) -#define RGX_CR_CLK_CTRL2_FBA_AUTO (IMG_UINT64_C(0x0000000000000002)) - - -/* - Register RGX_CR_CLK_STATUS2 -*/ -#define RGX_CR_CLK_STATUS2 (0xD208U) -#define RGX_CR_CLK_STATUS2_MASKFULL (IMG_UINT64_C(0x0000000000000015)) -#define RGX_CR_CLK_STATUS2_VRDM_SHIFT (4U) -#define RGX_CR_CLK_STATUS2_VRDM_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_CR_CLK_STATUS2_VRDM_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS2_VRDM_RUNNING (IMG_UINT64_C(0x0000000000000010)) -#define RGX_CR_CLK_STATUS2_SH_SHIFT (2U) -#define RGX_CR_CLK_STATUS2_SH_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_CR_CLK_STATUS2_SH_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS2_SH_RUNNING (IMG_UINT64_C(0x0000000000000004)) -#define RGX_CR_CLK_STATUS2_FBA_SHIFT (0U) -#define RGX_CR_CLK_STATUS2_FBA_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_CLK_STATUS2_FBA_GATED (IMG_UINT64_C(0x0000000000000000)) -#define RGX_CR_CLK_STATUS2_FBA_RUNNING (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_RPM_SHF_FPL -*/ -#define RGX_CR_RPM_SHF_FPL (0xD520U) -#define RGX_CR_RPM_SHF_FPL_MASKFULL (IMG_UINT64_C(0x3FFFFFFFFFFFFFFC)) -#define RGX_CR_RPM_SHF_FPL_SIZE_SHIFT (40U) -#define RGX_CR_RPM_SHF_FPL_SIZE_CLRMSK (IMG_UINT64_C(0xC00000FFFFFFFFFF)) -#define RGX_CR_RPM_SHF_FPL_BASE_SHIFT (2U) -#define RGX_CR_RPM_SHF_FPL_BASE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000003)) -#define RGX_CR_RPM_SHF_FPL_BASE_ALIGNSHIFT (2U) -#define RGX_CR_RPM_SHF_FPL_BASE_ALIGNSIZE (4U) - - -/* - Register RGX_CR_RPM_SHF_FPL_READ -*/ -#define RGX_CR_RPM_SHF_FPL_READ (0xD528U) -#define RGX_CR_RPM_SHF_FPL_READ_MASKFULL (IMG_UINT64_C(0x00000000007FFFFF)) -#define RGX_CR_RPM_SHF_FPL_READ_TOGGLE_SHIFT (22U) -#define RGX_CR_RPM_SHF_FPL_READ_TOGGLE_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_RPM_SHF_FPL_READ_TOGGLE_EN (0x00400000U) -#define RGX_CR_RPM_SHF_FPL_READ_OFFSET_SHIFT (0U) -#define RGX_CR_RPM_SHF_FPL_READ_OFFSET_CLRMSK (0xFFC00000U) - - -/* - Register RGX_CR_RPM_SHF_FPL_WRITE -*/ -#define RGX_CR_RPM_SHF_FPL_WRITE (0xD530U) -#define RGX_CR_RPM_SHF_FPL_WRITE_MASKFULL (IMG_UINT64_C(0x00000000007FFFFF)) -#define RGX_CR_RPM_SHF_FPL_WRITE_TOGGLE_SHIFT (22U) -#define RGX_CR_RPM_SHF_FPL_WRITE_TOGGLE_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_RPM_SHF_FPL_WRITE_TOGGLE_EN (0x00400000U) -#define RGX_CR_RPM_SHF_FPL_WRITE_OFFSET_SHIFT (0U) -#define RGX_CR_RPM_SHF_FPL_WRITE_OFFSET_CLRMSK (0xFFC00000U) - - -/* - Register RGX_CR_RPM_SHG_FPL -*/ -#define RGX_CR_RPM_SHG_FPL (0xD538U) -#define RGX_CR_RPM_SHG_FPL_MASKFULL (IMG_UINT64_C(0x3FFFFFFFFFFFFFFC)) -#define RGX_CR_RPM_SHG_FPL_SIZE_SHIFT (40U) -#define RGX_CR_RPM_SHG_FPL_SIZE_CLRMSK (IMG_UINT64_C(0xC00000FFFFFFFFFF)) -#define RGX_CR_RPM_SHG_FPL_BASE_SHIFT (2U) -#define RGX_CR_RPM_SHG_FPL_BASE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000003)) -#define RGX_CR_RPM_SHG_FPL_BASE_ALIGNSHIFT (2U) -#define RGX_CR_RPM_SHG_FPL_BASE_ALIGNSIZE (4U) - - -/* - Register RGX_CR_RPM_SHG_FPL_READ -*/ -#define RGX_CR_RPM_SHG_FPL_READ (0xD540U) -#define RGX_CR_RPM_SHG_FPL_READ_MASKFULL (IMG_UINT64_C(0x00000000007FFFFF)) -#define RGX_CR_RPM_SHG_FPL_READ_TOGGLE_SHIFT (22U) -#define RGX_CR_RPM_SHG_FPL_READ_TOGGLE_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_RPM_SHG_FPL_READ_TOGGLE_EN (0x00400000U) -#define RGX_CR_RPM_SHG_FPL_READ_OFFSET_SHIFT (0U) -#define RGX_CR_RPM_SHG_FPL_READ_OFFSET_CLRMSK (0xFFC00000U) - - -/* - Register RGX_CR_RPM_SHG_FPL_WRITE -*/ -#define RGX_CR_RPM_SHG_FPL_WRITE (0xD548U) -#define RGX_CR_RPM_SHG_FPL_WRITE_MASKFULL (IMG_UINT64_C(0x00000000007FFFFF)) -#define RGX_CR_RPM_SHG_FPL_WRITE_TOGGLE_SHIFT (22U) -#define RGX_CR_RPM_SHG_FPL_WRITE_TOGGLE_CLRMSK (0xFFBFFFFFU) -#define RGX_CR_RPM_SHG_FPL_WRITE_TOGGLE_EN (0x00400000U) -#define RGX_CR_RPM_SHG_FPL_WRITE_OFFSET_SHIFT (0U) -#define RGX_CR_RPM_SHG_FPL_WRITE_OFFSET_CLRMSK (0xFFC00000U) - - -/* - Register RGX_CR_SH_PERF -*/ -#define RGX_CR_SH_PERF (0xD5F8U) -#define RGX_CR_SH_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_SH_PERF_CLR_3_SHIFT (4U) -#define RGX_CR_SH_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SH_PERF_CLR_3_EN (0x00000010U) -#define RGX_CR_SH_PERF_CLR_2_SHIFT (3U) -#define RGX_CR_SH_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SH_PERF_CLR_2_EN (0x00000008U) -#define RGX_CR_SH_PERF_CLR_1_SHIFT (2U) -#define RGX_CR_SH_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SH_PERF_CLR_1_EN (0x00000004U) -#define RGX_CR_SH_PERF_CLR_0_SHIFT (1U) -#define RGX_CR_SH_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SH_PERF_CLR_0_EN (0x00000002U) -#define RGX_CR_SH_PERF_CTRL_ENABLE_SHIFT (0U) -#define RGX_CR_SH_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SH_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register RGX_CR_SH_PERF_SELECT0 -*/ -#define RGX_CR_SH_PERF_SELECT0 (0xD600U) -#define RGX_CR_SH_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define RGX_CR_SH_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define RGX_CR_SH_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define RGX_CR_SH_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define RGX_CR_SH_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define RGX_CR_SH_PERF_SELECT0_MODE_SHIFT (21U) -#define RGX_CR_SH_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define RGX_CR_SH_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define RGX_CR_SH_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define RGX_CR_SH_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define RGX_CR_SH_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define RGX_CR_SH_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_SH_PERF_COUNTER_0 -*/ -#define RGX_CR_SH_PERF_COUNTER_0 (0xD628U) -#define RGX_CR_SH_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SH_PERF_COUNTER_0_REG_SHIFT (0U) -#define RGX_CR_SH_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SHF_SHG_CHECKSUM -*/ -#define RGX_CR_SHF_SHG_CHECKSUM (0xD1C0U) -#define RGX_CR_SHF_SHG_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SHF_SHG_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_SHF_SHG_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SHF_VERTEX_BIF_CHECKSUM -*/ -#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM (0xD1C8U) -#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SHF_VARY_BIF_CHECKSUM -*/ -#define RGX_CR_SHF_VARY_BIF_CHECKSUM (0xD1D0U) -#define RGX_CR_SHF_VARY_BIF_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SHF_VARY_BIF_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_SHF_VARY_BIF_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_RPM_BIF_CHECKSUM -*/ -#define RGX_CR_RPM_BIF_CHECKSUM (0xD1D8U) -#define RGX_CR_RPM_BIF_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_RPM_BIF_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_RPM_BIF_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SHG_BIF_CHECKSUM -*/ -#define RGX_CR_SHG_BIF_CHECKSUM (0xD1E0U) -#define RGX_CR_SHG_BIF_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SHG_BIF_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_SHG_BIF_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register RGX_CR_SHG_FE_BE_CHECKSUM -*/ -#define RGX_CR_SHG_FE_BE_CHECKSUM (0xD1E8U) -#define RGX_CR_SHG_FE_BE_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_SHG_FE_BE_CHECKSUM_VALUE_SHIFT (0U) -#define RGX_CR_SHG_FE_BE_CHECKSUM_VALUE_CLRMSK (0x00000000U) - - -/* - Register DPX_CR_BF_PERF -*/ -#define DPX_CR_BF_PERF (0xC458U) -#define DPX_CR_BF_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define DPX_CR_BF_PERF_CLR_3_SHIFT (4U) -#define DPX_CR_BF_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define DPX_CR_BF_PERF_CLR_3_EN (0x00000010U) -#define DPX_CR_BF_PERF_CLR_2_SHIFT (3U) -#define DPX_CR_BF_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define DPX_CR_BF_PERF_CLR_2_EN (0x00000008U) -#define DPX_CR_BF_PERF_CLR_1_SHIFT (2U) -#define DPX_CR_BF_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_BF_PERF_CLR_1_EN (0x00000004U) -#define DPX_CR_BF_PERF_CLR_0_SHIFT (1U) -#define DPX_CR_BF_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define DPX_CR_BF_PERF_CLR_0_EN (0x00000002U) -#define DPX_CR_BF_PERF_CTRL_ENABLE_SHIFT (0U) -#define DPX_CR_BF_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_BF_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register DPX_CR_BF_PERF_SELECT0 -*/ -#define DPX_CR_BF_PERF_SELECT0 (0xC460U) -#define DPX_CR_BF_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define DPX_CR_BF_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define DPX_CR_BF_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define DPX_CR_BF_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define DPX_CR_BF_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define DPX_CR_BF_PERF_SELECT0_MODE_SHIFT (21U) -#define DPX_CR_BF_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define DPX_CR_BF_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define DPX_CR_BF_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define DPX_CR_BF_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define DPX_CR_BF_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define DPX_CR_BF_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register DPX_CR_BF_PERF_COUNTER_0 -*/ -#define DPX_CR_BF_PERF_COUNTER_0 (0xC488U) -#define DPX_CR_BF_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_BF_PERF_COUNTER_0_REG_SHIFT (0U) -#define DPX_CR_BF_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register DPX_CR_BT_PERF -*/ -#define DPX_CR_BT_PERF (0xC3D0U) -#define DPX_CR_BT_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define DPX_CR_BT_PERF_CLR_3_SHIFT (4U) -#define DPX_CR_BT_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define DPX_CR_BT_PERF_CLR_3_EN (0x00000010U) -#define DPX_CR_BT_PERF_CLR_2_SHIFT (3U) -#define DPX_CR_BT_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define DPX_CR_BT_PERF_CLR_2_EN (0x00000008U) -#define DPX_CR_BT_PERF_CLR_1_SHIFT (2U) -#define DPX_CR_BT_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_BT_PERF_CLR_1_EN (0x00000004U) -#define DPX_CR_BT_PERF_CLR_0_SHIFT (1U) -#define DPX_CR_BT_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define DPX_CR_BT_PERF_CLR_0_EN (0x00000002U) -#define DPX_CR_BT_PERF_CTRL_ENABLE_SHIFT (0U) -#define DPX_CR_BT_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_BT_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register DPX_CR_BT_PERF_SELECT0 -*/ -#define DPX_CR_BT_PERF_SELECT0 (0xC3D8U) -#define DPX_CR_BT_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define DPX_CR_BT_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define DPX_CR_BT_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define DPX_CR_BT_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define DPX_CR_BT_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define DPX_CR_BT_PERF_SELECT0_MODE_SHIFT (21U) -#define DPX_CR_BT_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define DPX_CR_BT_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define DPX_CR_BT_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define DPX_CR_BT_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define DPX_CR_BT_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define DPX_CR_BT_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register DPX_CR_BT_PERF_COUNTER_0 -*/ -#define DPX_CR_BT_PERF_COUNTER_0 (0xC420U) -#define DPX_CR_BT_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_BT_PERF_COUNTER_0_REG_SHIFT (0U) -#define DPX_CR_BT_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register DPX_CR_RQ_USC_DEBUG -*/ -#define DPX_CR_RQ_USC_DEBUG (0xC110U) -#define DPX_CR_RQ_USC_DEBUG_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_RQ_USC_DEBUG_CHECKSUM_SHIFT (0U) -#define DPX_CR_RQ_USC_DEBUG_CHECKSUM_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register DPX_CR_BIF_FAULT_BANK_MMU_STATUS -*/ -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS (0xC5C8U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000000F775)) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_CAT_BASE_SHIFT (12U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_CAT_BASE_CLRMSK (0xFFFF0FFFU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_PAGE_SIZE_SHIFT (8U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_PAGE_SIZE_CLRMSK (0xFFFFF8FFU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_DATA_TYPE_SHIFT (5U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_DATA_TYPE_CLRMSK (0xFFFFFF9FU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_SHIFT (4U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_CLRMSK (0xFFFFFFEFU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_EN (0x00000010U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_EN (0x00000004U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_SHIFT (0U) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_EN (0x00000001U) - - -/* - Register DPX_CR_BIF_FAULT_BANK_REQ_STATUS -*/ -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS (0xC5D0U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_MASKFULL (IMG_UINT64_C(0x03FFFFFFFFFFFFF0)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_SHIFT (57U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFDFFFFFFFFFFFFFF)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_EN (IMG_UINT64_C(0x0200000000000000)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_SB_SHIFT (44U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFE000FFFFFFFFFFF)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_ID_SHIFT (40U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0xFFFFF0FFFFFFFFFF)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_SHIFT (4U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0xFFFFFF000000000F)) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U) -#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_ALIGNSIZE (16U) - - -/* - Register DPX_CR_BIF_MMU_STATUS -*/ -#define DPX_CR_BIF_MMU_STATUS (0xC5D8U) -#define DPX_CR_BIF_MMU_STATUS_MASKFULL (IMG_UINT64_C(0x000000000FFFFFF7)) -#define DPX_CR_BIF_MMU_STATUS_PC_DATA_SHIFT (20U) -#define DPX_CR_BIF_MMU_STATUS_PC_DATA_CLRMSK (0xF00FFFFFU) -#define DPX_CR_BIF_MMU_STATUS_PD_DATA_SHIFT (12U) -#define DPX_CR_BIF_MMU_STATUS_PD_DATA_CLRMSK (0xFFF00FFFU) -#define DPX_CR_BIF_MMU_STATUS_PT_DATA_SHIFT (4U) -#define DPX_CR_BIF_MMU_STATUS_PT_DATA_CLRMSK (0xFFFFF00FU) -#define DPX_CR_BIF_MMU_STATUS_STALLED_SHIFT (2U) -#define DPX_CR_BIF_MMU_STATUS_STALLED_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_BIF_MMU_STATUS_STALLED_EN (0x00000004U) -#define DPX_CR_BIF_MMU_STATUS_PAUSED_SHIFT (1U) -#define DPX_CR_BIF_MMU_STATUS_PAUSED_CLRMSK (0xFFFFFFFDU) -#define DPX_CR_BIF_MMU_STATUS_PAUSED_EN (0x00000002U) -#define DPX_CR_BIF_MMU_STATUS_BUSY_SHIFT (0U) -#define DPX_CR_BIF_MMU_STATUS_BUSY_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_BIF_MMU_STATUS_BUSY_EN (0x00000001U) - - -/* - Register DPX_CR_RT_PERF -*/ -#define DPX_CR_RT_PERF (0xC700U) -#define DPX_CR_RT_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define DPX_CR_RT_PERF_CLR_3_SHIFT (4U) -#define DPX_CR_RT_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define DPX_CR_RT_PERF_CLR_3_EN (0x00000010U) -#define DPX_CR_RT_PERF_CLR_2_SHIFT (3U) -#define DPX_CR_RT_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define DPX_CR_RT_PERF_CLR_2_EN (0x00000008U) -#define DPX_CR_RT_PERF_CLR_1_SHIFT (2U) -#define DPX_CR_RT_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_RT_PERF_CLR_1_EN (0x00000004U) -#define DPX_CR_RT_PERF_CLR_0_SHIFT (1U) -#define DPX_CR_RT_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define DPX_CR_RT_PERF_CLR_0_EN (0x00000002U) -#define DPX_CR_RT_PERF_CTRL_ENABLE_SHIFT (0U) -#define DPX_CR_RT_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_RT_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register DPX_CR_RT_PERF_SELECT0 -*/ -#define DPX_CR_RT_PERF_SELECT0 (0xC708U) -#define DPX_CR_RT_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define DPX_CR_RT_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define DPX_CR_RT_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define DPX_CR_RT_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define DPX_CR_RT_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define DPX_CR_RT_PERF_SELECT0_MODE_SHIFT (21U) -#define DPX_CR_RT_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define DPX_CR_RT_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define DPX_CR_RT_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define DPX_CR_RT_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define DPX_CR_RT_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define DPX_CR_RT_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register DPX_CR_RT_PERF_COUNTER_0 -*/ -#define DPX_CR_RT_PERF_COUNTER_0 (0xC730U) -#define DPX_CR_RT_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_RT_PERF_COUNTER_0_REG_SHIFT (0U) -#define DPX_CR_RT_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register DPX_CR_BX_TU_PERF -*/ -#define DPX_CR_BX_TU_PERF (0xC908U) -#define DPX_CR_BX_TU_PERF_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define DPX_CR_BX_TU_PERF_CLR_3_SHIFT (4U) -#define DPX_CR_BX_TU_PERF_CLR_3_CLRMSK (0xFFFFFFEFU) -#define DPX_CR_BX_TU_PERF_CLR_3_EN (0x00000010U) -#define DPX_CR_BX_TU_PERF_CLR_2_SHIFT (3U) -#define DPX_CR_BX_TU_PERF_CLR_2_CLRMSK (0xFFFFFFF7U) -#define DPX_CR_BX_TU_PERF_CLR_2_EN (0x00000008U) -#define DPX_CR_BX_TU_PERF_CLR_1_SHIFT (2U) -#define DPX_CR_BX_TU_PERF_CLR_1_CLRMSK (0xFFFFFFFBU) -#define DPX_CR_BX_TU_PERF_CLR_1_EN (0x00000004U) -#define DPX_CR_BX_TU_PERF_CLR_0_SHIFT (1U) -#define DPX_CR_BX_TU_PERF_CLR_0_CLRMSK (0xFFFFFFFDU) -#define DPX_CR_BX_TU_PERF_CLR_0_EN (0x00000002U) -#define DPX_CR_BX_TU_PERF_CTRL_ENABLE_SHIFT (0U) -#define DPX_CR_BX_TU_PERF_CTRL_ENABLE_CLRMSK (0xFFFFFFFEU) -#define DPX_CR_BX_TU_PERF_CTRL_ENABLE_EN (0x00000001U) - - -/* - Register DPX_CR_BX_TU_PERF_SELECT0 -*/ -#define DPX_CR_BX_TU_PERF_SELECT0 (0xC910U) -#define DPX_CR_BX_TU_PERF_SELECT0_MASKFULL (IMG_UINT64_C(0x3FFF3FFF003FFFFF)) -#define DPX_CR_BX_TU_PERF_SELECT0_BATCH_MAX_SHIFT (48U) -#define DPX_CR_BX_TU_PERF_SELECT0_BATCH_MAX_CLRMSK (IMG_UINT64_C(0xC000FFFFFFFFFFFF)) -#define DPX_CR_BX_TU_PERF_SELECT0_BATCH_MIN_SHIFT (32U) -#define DPX_CR_BX_TU_PERF_SELECT0_BATCH_MIN_CLRMSK (IMG_UINT64_C(0xFFFFC000FFFFFFFF)) -#define DPX_CR_BX_TU_PERF_SELECT0_MODE_SHIFT (21U) -#define DPX_CR_BX_TU_PERF_SELECT0_MODE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFDFFFFF)) -#define DPX_CR_BX_TU_PERF_SELECT0_MODE_EN (IMG_UINT64_C(0x0000000000200000)) -#define DPX_CR_BX_TU_PERF_SELECT0_GROUP_SELECT_SHIFT (16U) -#define DPX_CR_BX_TU_PERF_SELECT0_GROUP_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE0FFFF)) -#define DPX_CR_BX_TU_PERF_SELECT0_BIT_SELECT_SHIFT (0U) -#define DPX_CR_BX_TU_PERF_SELECT0_BIT_SELECT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register DPX_CR_BX_TU_PERF_COUNTER_0 -*/ -#define DPX_CR_BX_TU_PERF_COUNTER_0 (0xC938U) -#define DPX_CR_BX_TU_PERF_COUNTER_0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_BX_TU_PERF_COUNTER_0_REG_SHIFT (0U) -#define DPX_CR_BX_TU_PERF_COUNTER_0_REG_CLRMSK (0x00000000U) - - -/* - Register DPX_CR_RS_PDS_RR_CHECKSUM -*/ -#define DPX_CR_RS_PDS_RR_CHECKSUM (0xC0F0U) -#define DPX_CR_RS_PDS_RR_CHECKSUM_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define DPX_CR_RS_PDS_RR_CHECKSUM_VALUE_SHIFT (0U) -#define DPX_CR_RS_PDS_RR_CHECKSUM_VALUE_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00000000)) - - -/* - Register RGX_CR_MMU_CBASE_MAPPING_CONTEXT -*/ -#define RGX_CR_MMU_CBASE_MAPPING_CONTEXT (0xE140U) -#define RGX_CR_MMU_CBASE_MAPPING_CONTEXT_MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_MMU_CBASE_MAPPING_CONTEXT_ID_SHIFT (0U) -#define RGX_CR_MMU_CBASE_MAPPING_CONTEXT_ID_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_MMU_CBASE_MAPPING -*/ -#define RGX_CR_MMU_CBASE_MAPPING (0xE148U) -#define RGX_CR_MMU_CBASE_MAPPING_MASKFULL (IMG_UINT64_C(0x000000000FFFFFFF)) -#define RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_SHIFT (0U) -#define RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_CLRMSK (0xF0000000U) -#define RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_ALIGNSHIFT (12U) -#define RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_ALIGNSIZE (4096U) - - -/* - Register RGX_CR_MMU_FAULT_STATUS -*/ -#define RGX_CR_MMU_FAULT_STATUS (0xE150U) -#define RGX_CR_MMU_FAULT_STATUS_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT (28U) -#define RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0x000000000FFFFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT (20U) -#define RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF00FFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT (12U) -#define RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF00FFF)) -#define RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT (6U) -#define RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF03F)) -#define RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT (4U) -#define RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFCF)) -#define RGX_CR_MMU_FAULT_STATUS_RNW_SHIFT (3U) -#define RGX_CR_MMU_FAULT_STATUS_RNW_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_MMU_FAULT_STATUS_RNW_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT (1U) -#define RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF9)) -#define RGX_CR_MMU_FAULT_STATUS_FAULT_SHIFT (0U) -#define RGX_CR_MMU_FAULT_STATUS_FAULT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MMU_FAULT_STATUS_FAULT_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_MMU_FAULT_STATUS_META -*/ -#define RGX_CR_MMU_FAULT_STATUS_META (0xE158U) -#define RGX_CR_MMU_FAULT_STATUS_META_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_SHIFT (28U) -#define RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_CLRMSK (IMG_UINT64_C(0x000000000FFFFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_SHIFT (20U) -#define RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFF00FFFFF)) -#define RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_SHIFT (12U) -#define RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFF00FFF)) -#define RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_SHIFT (6U) -#define RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF03F)) -#define RGX_CR_MMU_FAULT_STATUS_META_LEVEL_SHIFT (4U) -#define RGX_CR_MMU_FAULT_STATUS_META_LEVEL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFCF)) -#define RGX_CR_MMU_FAULT_STATUS_META_RNW_SHIFT (3U) -#define RGX_CR_MMU_FAULT_STATUS_META_RNW_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_CR_MMU_FAULT_STATUS_META_RNW_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT (1U) -#define RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF9)) -#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_SHIFT (0U) -#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_EN (IMG_UINT64_C(0x0000000000000001)) - - -/* - Register RGX_CR_SLC3_CTRL_MISC -*/ -#define RGX_CR_SLC3_CTRL_MISC (0xE200U) -#define RGX_CR_SLC3_CTRL_MISC_MASKFULL (IMG_UINT64_C(0x0000000000000107)) -#define RGX_CR_SLC3_CTRL_MISC_WRITE_COMBINER_SHIFT (8U) -#define RGX_CR_SLC3_CTRL_MISC_WRITE_COMBINER_CLRMSK (0xFFFFFEFFU) -#define RGX_CR_SLC3_CTRL_MISC_WRITE_COMBINER_EN (0x00000100U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SHIFT (0U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_CLRMSK (0xFFFFFFF8U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_LINEAR (0x00000000U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_IN_PAGE_HASH (0x00000001U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_FIXED_PVR_HASH (0x00000002U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SCRAMBLE_PVR_HASH (0x00000003U) -#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_WEAVED_HASH (0x00000004U) - - -/* - Register RGX_CR_SLC3_SCRAMBLE -*/ -#define RGX_CR_SLC3_SCRAMBLE (0xE208U) -#define RGX_CR_SLC3_SCRAMBLE_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SLC3_SCRAMBLE_BITS_SHIFT (0U) -#define RGX_CR_SLC3_SCRAMBLE_BITS_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SLC3_SCRAMBLE2 -*/ -#define RGX_CR_SLC3_SCRAMBLE2 (0xE210U) -#define RGX_CR_SLC3_SCRAMBLE2_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SLC3_SCRAMBLE2_BITS_SHIFT (0U) -#define RGX_CR_SLC3_SCRAMBLE2_BITS_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SLC3_SCRAMBLE3 -*/ -#define RGX_CR_SLC3_SCRAMBLE3 (0xE218U) -#define RGX_CR_SLC3_SCRAMBLE3_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SLC3_SCRAMBLE3_BITS_SHIFT (0U) -#define RGX_CR_SLC3_SCRAMBLE3_BITS_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SLC3_SCRAMBLE4 -*/ -#define RGX_CR_SLC3_SCRAMBLE4 (0xE260U) -#define RGX_CR_SLC3_SCRAMBLE4_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SLC3_SCRAMBLE4_BITS_SHIFT (0U) -#define RGX_CR_SLC3_SCRAMBLE4_BITS_CLRMSK (IMG_UINT64_C(0x0000000000000000)) - - -/* - Register RGX_CR_SLC3_STATUS -*/ -#define RGX_CR_SLC3_STATUS (0xE220U) -#define RGX_CR_SLC3_STATUS_MASKFULL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) -#define RGX_CR_SLC3_STATUS_WRITES1_SHIFT (48U) -#define RGX_CR_SLC3_STATUS_WRITES1_CLRMSK (IMG_UINT64_C(0x0000FFFFFFFFFFFF)) -#define RGX_CR_SLC3_STATUS_WRITES0_SHIFT (32U) -#define RGX_CR_SLC3_STATUS_WRITES0_CLRMSK (IMG_UINT64_C(0xFFFF0000FFFFFFFF)) -#define RGX_CR_SLC3_STATUS_READS1_SHIFT (16U) -#define RGX_CR_SLC3_STATUS_READS1_CLRMSK (IMG_UINT64_C(0xFFFFFFFF0000FFFF)) -#define RGX_CR_SLC3_STATUS_READS0_SHIFT (0U) -#define RGX_CR_SLC3_STATUS_READS0_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF0000)) - - -/* - Register RGX_CR_SLC3_IDLE -*/ -#define RGX_CR_SLC3_IDLE (0xE228U) -#define RGX_CR_SLC3_IDLE_MASKFULL (IMG_UINT64_C(0x00000000000FFFFF)) -#define RGX_CR_SLC3_IDLE_ORDERQ_DUST2_SHIFT (18U) -#define RGX_CR_SLC3_IDLE_ORDERQ_DUST2_CLRMSK (0xFFF3FFFFU) -#define RGX_CR_SLC3_IDLE_MMU_SHIFT (17U) -#define RGX_CR_SLC3_IDLE_MMU_CLRMSK (0xFFFDFFFFU) -#define RGX_CR_SLC3_IDLE_MMU_EN (0x00020000U) -#define RGX_CR_SLC3_IDLE_RDI_SHIFT (16U) -#define RGX_CR_SLC3_IDLE_RDI_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_SLC3_IDLE_RDI_EN (0x00010000U) -#define RGX_CR_SLC3_IDLE_IMGBV4_SHIFT (12U) -#define RGX_CR_SLC3_IDLE_IMGBV4_CLRMSK (0xFFFF0FFFU) -#define RGX_CR_SLC3_IDLE_CACHE_BANKS_SHIFT (4U) -#define RGX_CR_SLC3_IDLE_CACHE_BANKS_CLRMSK (0xFFFFF00FU) -#define RGX_CR_SLC3_IDLE_ORDERQ_DUST_SHIFT (2U) -#define RGX_CR_SLC3_IDLE_ORDERQ_DUST_CLRMSK (0xFFFFFFF3U) -#define RGX_CR_SLC3_IDLE_ORDERQ_JONES_SHIFT (1U) -#define RGX_CR_SLC3_IDLE_ORDERQ_JONES_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SLC3_IDLE_ORDERQ_JONES_EN (0x00000002U) -#define RGX_CR_SLC3_IDLE_XBAR_SHIFT (0U) -#define RGX_CR_SLC3_IDLE_XBAR_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SLC3_IDLE_XBAR_EN (0x00000001U) - - -/* - Register RGX_CR_SLC3_FAULT_STOP_STATUS -*/ -#define RGX_CR_SLC3_FAULT_STOP_STATUS (0xE248U) -#define RGX_CR_SLC3_FAULT_STOP_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000001FFF)) -#define RGX_CR_SLC3_FAULT_STOP_STATUS_BIF_SHIFT (0U) -#define RGX_CR_SLC3_FAULT_STOP_STATUS_BIF_CLRMSK (0xFFFFE000U) - - -/* - Register RGX_CR_VDM_CONTEXT_STORE_MODE -*/ -#define RGX_CR_VDM_CONTEXT_STORE_MODE (0xF048U) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MASKFULL (IMG_UINT64_C(0x0000000000000003)) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_SHIFT (0U) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_CLRMSK (0xFFFFFFFCU) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INDEX (0x00000000U) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INSTANCE (0x00000001U) -#define RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_LIST (0x00000002U) - - -/* - Register RGX_CR_CONTEXT_MAPPING0 -*/ -#define RGX_CR_CONTEXT_MAPPING0 (0xF078U) -#define RGX_CR_CONTEXT_MAPPING0_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_CONTEXT_MAPPING0_2D_SHIFT (24U) -#define RGX_CR_CONTEXT_MAPPING0_2D_CLRMSK (0x00FFFFFFU) -#define RGX_CR_CONTEXT_MAPPING0_CDM_SHIFT (16U) -#define RGX_CR_CONTEXT_MAPPING0_CDM_CLRMSK (0xFF00FFFFU) -#define RGX_CR_CONTEXT_MAPPING0_3D_SHIFT (8U) -#define RGX_CR_CONTEXT_MAPPING0_3D_CLRMSK (0xFFFF00FFU) -#define RGX_CR_CONTEXT_MAPPING0_TA_SHIFT (0U) -#define RGX_CR_CONTEXT_MAPPING0_TA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_CONTEXT_MAPPING1 -*/ -#define RGX_CR_CONTEXT_MAPPING1 (0xF080U) -#define RGX_CR_CONTEXT_MAPPING1_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_CONTEXT_MAPPING1_HOST_SHIFT (8U) -#define RGX_CR_CONTEXT_MAPPING1_HOST_CLRMSK (0xFFFF00FFU) -#define RGX_CR_CONTEXT_MAPPING1_TLA_SHIFT (0U) -#define RGX_CR_CONTEXT_MAPPING1_TLA_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_CONTEXT_MAPPING2 -*/ -#define RGX_CR_CONTEXT_MAPPING2 (0xF088U) -#define RGX_CR_CONTEXT_MAPPING2_MASKFULL (IMG_UINT64_C(0x0000000000FFFFFF)) -#define RGX_CR_CONTEXT_MAPPING2_ALIST0_SHIFT (16U) -#define RGX_CR_CONTEXT_MAPPING2_ALIST0_CLRMSK (0xFF00FFFFU) -#define RGX_CR_CONTEXT_MAPPING2_TE0_SHIFT (8U) -#define RGX_CR_CONTEXT_MAPPING2_TE0_CLRMSK (0xFFFF00FFU) -#define RGX_CR_CONTEXT_MAPPING2_VCE0_SHIFT (0U) -#define RGX_CR_CONTEXT_MAPPING2_VCE0_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_CONTEXT_MAPPING3 -*/ -#define RGX_CR_CONTEXT_MAPPING3 (0xF090U) -#define RGX_CR_CONTEXT_MAPPING3_MASKFULL (IMG_UINT64_C(0x0000000000FFFFFF)) -#define RGX_CR_CONTEXT_MAPPING3_ALIST1_SHIFT (16U) -#define RGX_CR_CONTEXT_MAPPING3_ALIST1_CLRMSK (0xFF00FFFFU) -#define RGX_CR_CONTEXT_MAPPING3_TE1_SHIFT (8U) -#define RGX_CR_CONTEXT_MAPPING3_TE1_CLRMSK (0xFFFF00FFU) -#define RGX_CR_CONTEXT_MAPPING3_VCE1_SHIFT (0U) -#define RGX_CR_CONTEXT_MAPPING3_VCE1_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_BIF_JONES_OUTSTANDING_READ -*/ -#define RGX_CR_BIF_JONES_OUTSTANDING_READ (0xF098U) -#define RGX_CR_BIF_JONES_OUTSTANDING_READ_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_BIF_JONES_OUTSTANDING_READ_COUNTER_SHIFT (0U) -#define RGX_CR_BIF_JONES_OUTSTANDING_READ_COUNTER_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIF_BLACKPEARL_OUTSTANDING_READ -*/ -#define RGX_CR_BIF_BLACKPEARL_OUTSTANDING_READ (0xF0A0U) -#define RGX_CR_BIF_BLACKPEARL_OUTSTANDING_READ_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_BIF_BLACKPEARL_OUTSTANDING_READ_COUNTER_SHIFT (0U) -#define RGX_CR_BIF_BLACKPEARL_OUTSTANDING_READ_COUNTER_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_BIF_DUST_OUTSTANDING_READ -*/ -#define RGX_CR_BIF_DUST_OUTSTANDING_READ (0xF0A8U) -#define RGX_CR_BIF_DUST_OUTSTANDING_READ_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_BIF_DUST_OUTSTANDING_READ_COUNTER_SHIFT (0U) -#define RGX_CR_BIF_DUST_OUTSTANDING_READ_COUNTER_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_JONES_FIX -*/ -#define RGX_CR_JONES_FIX (0xF0C0U) -#define RGX_CR_JONES_FIX__ROGUE3__MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_JONES_FIX_MASKFULL (IMG_UINT64_C(0x000000000000FFFF)) -#define RGX_CR_JONES_FIX_DISABLE_SHIFT (0U) -#define RGX_CR_JONES_FIX_DISABLE_CLRMSK (0xFFFF0000U) - - -/* - Register RGX_CR_CONTEXT_MAPPING4 -*/ -#define RGX_CR_CONTEXT_MAPPING4 (0xF210U) -#define RGX_CR_CONTEXT_MAPPING4_MASKFULL (IMG_UINT64_C(0x0000FFFFFFFFFFFF)) -#define RGX_CR_CONTEXT_MAPPING4_3D_MMU_STACK_SHIFT (40U) -#define RGX_CR_CONTEXT_MAPPING4_3D_MMU_STACK_CLRMSK (IMG_UINT64_C(0xFFFF00FFFFFFFFFF)) -#define RGX_CR_CONTEXT_MAPPING4_3D_UFSTACK_SHIFT (32U) -#define RGX_CR_CONTEXT_MAPPING4_3D_UFSTACK_CLRMSK (IMG_UINT64_C(0xFFFFFF00FFFFFFFF)) -#define RGX_CR_CONTEXT_MAPPING4_3D_FSTACK_SHIFT (24U) -#define RGX_CR_CONTEXT_MAPPING4_3D_FSTACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFF00FFFFFF)) -#define RGX_CR_CONTEXT_MAPPING4_TA_MMU_STACK_SHIFT (16U) -#define RGX_CR_CONTEXT_MAPPING4_TA_MMU_STACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFF00FFFF)) -#define RGX_CR_CONTEXT_MAPPING4_TA_UFSTACK_SHIFT (8U) -#define RGX_CR_CONTEXT_MAPPING4_TA_UFSTACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFF00FF)) -#define RGX_CR_CONTEXT_MAPPING4_TA_FSTACK_SHIFT (0U) -#define RGX_CR_CONTEXT_MAPPING4_TA_FSTACK_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFF00)) - - -/* - Register RGX_CR_MULTICORE_GPU -*/ -#define RGX_CR_MULTICORE_GPU (0xF300U) -#define RGX_CR_MULTICORE_GPU_MASKFULL (IMG_UINT64_C(0x000000000000007F)) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_FRAGMENT_SHIFT (6U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_FRAGMENT_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_FRAGMENT_EN (0x00000040U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_GEOMETRY_SHIFT (5U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_GEOMETRY_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_GEOMETRY_EN (0x00000020U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_COMPUTE_SHIFT (4U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_COMPUTE_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_COMPUTE_EN (0x00000010U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_PRIMARY_SHIFT (3U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_PRIMARY_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_MULTICORE_GPU_CAPABILITY_PRIMARY_EN (0x00000008U) -#define RGX_CR_MULTICORE_GPU_ID_SHIFT (0U) -#define RGX_CR_MULTICORE_GPU_ID_CLRMSK (0xFFFFFFF8U) - - -/* - Register RGX_CR_MULTICORE_SYSTEM -*/ -#define RGX_CR_MULTICORE_SYSTEM (0xF308U) -#define RGX_CR_MULTICORE_SYSTEM_MASKFULL (IMG_UINT64_C(0x000000000000000F)) -#define RGX_CR_MULTICORE_SYSTEM_GPU_COUNT_SHIFT (0U) -#define RGX_CR_MULTICORE_SYSTEM_GPU_COUNT_CLRMSK (0xFFFFFFF0U) - - -/* - Register RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON -*/ -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON (0xF310U) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_WORKLOAD_TYPE_SHIFT (30U) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_WORKLOAD_TYPE_CLRMSK (0x3FFFFFFFU) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_SHIFT (8U) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_CLRMSK (0xC00000FFU) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_GPU_ENABLE_SHIFT (0U) -#define RGX_CR_MULTICORE_FRAGMENT_CTRL_COMMON_GPU_ENABLE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON -*/ -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON (0xF320U) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_WORKLOAD_TYPE_SHIFT (30U) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_WORKLOAD_TYPE_CLRMSK (0x3FFFFFFFU) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_SHIFT (8U) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_CLRMSK (0xC00000FFU) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_GPU_ENABLE_SHIFT (0U) -#define RGX_CR_MULTICORE_GEOMETRY_CTRL_COMMON_GPU_ENABLE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON -*/ -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON (0xF330U) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_MASKFULL (IMG_UINT64_C(0x00000000FFFFFFFF)) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_WORKLOAD_TYPE_SHIFT (30U) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_WORKLOAD_TYPE_CLRMSK (0x3FFFFFFFU) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_SHIFT (8U) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_WORKLOAD_EXECUTE_COUNT_CLRMSK (0xC00000FFU) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_GPU_ENABLE_SHIFT (0U) -#define RGX_CR_MULTICORE_COMPUTE_CTRL_COMMON_GPU_ENABLE_CLRMSK (0xFFFFFF00U) - - -/* - Register RGX_CR_ECC_RAM_ERR_INJ -*/ -#define RGX_CR_ECC_RAM_ERR_INJ (0xF340U) -#define RGX_CR_ECC_RAM_ERR_INJ_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_SHIFT (4U) -#define RGX_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_EN (0x00000010U) -#define RGX_CR_ECC_RAM_ERR_INJ_USC_SHIFT (3U) -#define RGX_CR_ECC_RAM_ERR_INJ_USC_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_ECC_RAM_ERR_INJ_USC_EN (0x00000008U) -#define RGX_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_SHIFT (2U) -#define RGX_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_EN (0x00000004U) -#define RGX_CR_ECC_RAM_ERR_INJ_RASCAL_SHIFT (1U) -#define RGX_CR_ECC_RAM_ERR_INJ_RASCAL_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_ECC_RAM_ERR_INJ_RASCAL_EN (0x00000002U) -#define RGX_CR_ECC_RAM_ERR_INJ_MARS_SHIFT (0U) -#define RGX_CR_ECC_RAM_ERR_INJ_MARS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_ECC_RAM_ERR_INJ_MARS_EN (0x00000001U) - - -/* - Register RGX_CR_ECC_RAM_INIT_KICK -*/ -#define RGX_CR_ECC_RAM_INIT_KICK (0xF348U) -#define RGX_CR_ECC_RAM_INIT_KICK_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_ECC_RAM_INIT_KICK_SLC_SIDEKICK_SHIFT (4U) -#define RGX_CR_ECC_RAM_INIT_KICK_SLC_SIDEKICK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_ECC_RAM_INIT_KICK_SLC_SIDEKICK_EN (0x00000010U) -#define RGX_CR_ECC_RAM_INIT_KICK_USC_SHIFT (3U) -#define RGX_CR_ECC_RAM_INIT_KICK_USC_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_ECC_RAM_INIT_KICK_USC_EN (0x00000008U) -#define RGX_CR_ECC_RAM_INIT_KICK_TPU_MCU_L0_SHIFT (2U) -#define RGX_CR_ECC_RAM_INIT_KICK_TPU_MCU_L0_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_ECC_RAM_INIT_KICK_TPU_MCU_L0_EN (0x00000004U) -#define RGX_CR_ECC_RAM_INIT_KICK_RASCAL_SHIFT (1U) -#define RGX_CR_ECC_RAM_INIT_KICK_RASCAL_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_ECC_RAM_INIT_KICK_RASCAL_EN (0x00000002U) -#define RGX_CR_ECC_RAM_INIT_KICK_MARS_SHIFT (0U) -#define RGX_CR_ECC_RAM_INIT_KICK_MARS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_ECC_RAM_INIT_KICK_MARS_EN (0x00000001U) - - -/* - Register RGX_CR_ECC_RAM_INIT_DONE -*/ -#define RGX_CR_ECC_RAM_INIT_DONE (0xF350U) -#define RGX_CR_ECC_RAM_INIT_DONE_MASKFULL (IMG_UINT64_C(0x000000000000001F)) -#define RGX_CR_ECC_RAM_INIT_DONE_SLC_SIDEKICK_SHIFT (4U) -#define RGX_CR_ECC_RAM_INIT_DONE_SLC_SIDEKICK_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_ECC_RAM_INIT_DONE_SLC_SIDEKICK_EN (0x00000010U) -#define RGX_CR_ECC_RAM_INIT_DONE_USC_SHIFT (3U) -#define RGX_CR_ECC_RAM_INIT_DONE_USC_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_ECC_RAM_INIT_DONE_USC_EN (0x00000008U) -#define RGX_CR_ECC_RAM_INIT_DONE_TPU_MCU_L0_SHIFT (2U) -#define RGX_CR_ECC_RAM_INIT_DONE_TPU_MCU_L0_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_ECC_RAM_INIT_DONE_TPU_MCU_L0_EN (0x00000004U) -#define RGX_CR_ECC_RAM_INIT_DONE_RASCAL_SHIFT (1U) -#define RGX_CR_ECC_RAM_INIT_DONE_RASCAL_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_ECC_RAM_INIT_DONE_RASCAL_EN (0x00000002U) -#define RGX_CR_ECC_RAM_INIT_DONE_MARS_SHIFT (0U) -#define RGX_CR_ECC_RAM_INIT_DONE_MARS_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_ECC_RAM_INIT_DONE_MARS_EN (0x00000001U) - - -/* - Register RGX_CR_SAFETY_EVENT_ENABLE -*/ -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE (0xF390U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_SHIFT (7U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_EN (0x00000080U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_SHIFT (6U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_EN (0x00000040U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_SHIFT (5U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_EN (0x00000020U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_SHIFT (4U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_EN (0x00000010U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_SHIFT (3U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_EN (0x00000008U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_SHIFT (2U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_EN (0x00000004U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_SHIFT (1U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_EN (0x00000002U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_SHIFT (0U) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_SAFETY_EVENT_STATUS -*/ -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE (0xF398U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_LOCKUP_SHIFT (7U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_LOCKUP_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_LOCKUP_EN (0x00000080U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__CPU_PAGE_FAULT_SHIFT (6U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__CPU_PAGE_FAULT_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__CPU_PAGE_FAULT_EN (0x00000040U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__SAFE_COMPUTE_FAIL_SHIFT (5U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__SAFE_COMPUTE_FAIL_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__SAFE_COMPUTE_FAIL_EN (0x00000020U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_SHIFT (4U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN (0x00000010U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__TRP_FAIL_SHIFT (3U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__TRP_FAIL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__TRP_FAIL_EN (0x00000008U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_SHIFT (2U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN (0x00000004U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_GPU_SHIFT (1U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_GPU_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_GPU_EN (0x00000002U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_PAGE_FAULT_SHIFT (0U) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_PAGE_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__GPU_PAGE_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_SAFETY_EVENT_CLEAR -*/ -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE (0xF3A0U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_LOCKUP_SHIFT (7U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_LOCKUP_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_LOCKUP_EN (0x00000080U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__CPU_PAGE_FAULT_SHIFT (6U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__CPU_PAGE_FAULT_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__CPU_PAGE_FAULT_EN (0x00000040U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__SAFE_COMPUTE_FAIL_SHIFT (5U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__SAFE_COMPUTE_FAIL_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__SAFE_COMPUTE_FAIL_EN (0x00000020U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__WATCHDOG_TIMEOUT_SHIFT (4U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__WATCHDOG_TIMEOUT_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__WATCHDOG_TIMEOUT_EN (0x00000010U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__TRP_FAIL_SHIFT (3U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__TRP_FAIL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__TRP_FAIL_EN (0x00000008U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_FW_SHIFT (2U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_FW_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_FW_EN (0x00000004U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_GPU_SHIFT (1U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_GPU_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__FAULT_GPU_EN (0x00000002U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_PAGE_FAULT_SHIFT (0U) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_PAGE_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_PAGE_FAULT_EN (0x00000001U) - - -/* - Register RGX_CR_FAULT_FW_STATUS -*/ -#define RGX_CR_FAULT_FW_STATUS (0xF3B0U) -#define RGX_CR_FAULT_FW_STATUS_MASKFULL (IMG_UINT64_C(0x0000000000010001)) -#define RGX_CR_FAULT_FW_STATUS_CPU_CORRECT_SHIFT (16U) -#define RGX_CR_FAULT_FW_STATUS_CPU_CORRECT_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_FAULT_FW_STATUS_CPU_CORRECT_EN (0x00010000U) -#define RGX_CR_FAULT_FW_STATUS_CPU_DETECT_SHIFT (0U) -#define RGX_CR_FAULT_FW_STATUS_CPU_DETECT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FAULT_FW_STATUS_CPU_DETECT_EN (0x00000001U) - - -/* - Register RGX_CR_FAULT_FW_CLEAR -*/ -#define RGX_CR_FAULT_FW_CLEAR (0xF3B8U) -#define RGX_CR_FAULT_FW_CLEAR_MASKFULL (IMG_UINT64_C(0x0000000000010001)) -#define RGX_CR_FAULT_FW_CLEAR_CPU_CORRECT_SHIFT (16U) -#define RGX_CR_FAULT_FW_CLEAR_CPU_CORRECT_CLRMSK (0xFFFEFFFFU) -#define RGX_CR_FAULT_FW_CLEAR_CPU_CORRECT_EN (0x00010000U) -#define RGX_CR_FAULT_FW_CLEAR_CPU_DETECT_SHIFT (0U) -#define RGX_CR_FAULT_FW_CLEAR_CPU_DETECT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_FAULT_FW_CLEAR_CPU_DETECT_EN (0x00000001U) - - -/* - Register RGX_CR_MTS_SAFETY_EVENT_ENABLE -*/ -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE (0xF3D8U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__MASKFULL (IMG_UINT64_C(0x00000000000000FF)) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_SHIFT (7U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_CLRMSK (0xFFFFFF7FU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_LOCKUP_EN (0x00000080U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_SHIFT (6U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_CLRMSK (0xFFFFFFBFU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__CPU_PAGE_FAULT_EN (0x00000040U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_SHIFT (5U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_CLRMSK (0xFFFFFFDFU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__SAFE_COMPUTE_FAIL_EN (0x00000020U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_SHIFT (4U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_CLRMSK (0xFFFFFFEFU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__WATCHDOG_TIMEOUT_EN (0x00000010U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_SHIFT (3U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_CLRMSK (0xFFFFFFF7U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__TRP_FAIL_EN (0x00000008U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_SHIFT (2U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_CLRMSK (0xFFFFFFFBU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_FW_EN (0x00000004U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_SHIFT (1U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_CLRMSK (0xFFFFFFFDU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__FAULT_GPU_EN (0x00000002U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_SHIFT (0U) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_CLRMSK (0xFFFFFFFEU) -#define RGX_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__GPU_PAGE_FAULT_EN (0x00000001U) - - -#endif /* RGX_CR_DEFS_KM_H */ -/***************************************************************************** - End of file (rgx_cr_defs_km.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgxdefs_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgxdefs_km.h deleted file mode 100644 index 64f4b366a59bb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgxdefs_km.h +++ /dev/null @@ -1,338 +0,0 @@ -/*************************************************************************/ /*! -@Title Rogue hw definitions (kernel mode) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXDEFS_KM_H -#define RGXDEFS_KM_H - -#if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER) -#include RGX_BVNC_CORE_KM_HEADER -#include RGX_BNC_CONFIG_KM_HEADER -#endif - -#define IMG_EXPLICIT_INCLUDE_HWDEFS -#if defined(__KERNEL__) -#include "rgx_cr_defs_km.h" -#endif -#undef IMG_EXPLICIT_INCLUDE_HWDEFS - -#include "rgx_heap_firmware.h" - -/* The following Macros are picked up through BVNC headers for no hardware - * operations to be compatible with old build infrastructure. - */ -#if defined(NO_HARDWARE) -/****************************************************************************** - * Check for valid B.X.N.C - *****************************************************************************/ -#if !defined(RGX_BVNC_KM_B) || !defined(RGX_BVNC_KM_V) || !defined(RGX_BVNC_KM_N) || !defined(RGX_BVNC_KM_C) -#error "Need to specify BVNC (RGX_BVNC_KM_B, RGX_BVNC_KM_V, RGX_BVNC_KM_N and RGX_BVNC_C)" -#endif - -/* Check core/config compatibility */ -#if (RGX_BVNC_KM_B != RGX_BNC_KM_B) || (RGX_BVNC_KM_N != RGX_BNC_KM_N) || (RGX_BVNC_KM_C != RGX_BNC_KM_C) -#error "BVNC headers are mismatching (KM core/config)" -#endif -#endif - -/****************************************************************************** - * RGX Version name - *****************************************************************************/ -#define RGX_BVNC_KM_ST2(S) #S -#define RGX_BVNC_KM_ST(S) RGX_BVNC_KM_ST2(S) -#define RGX_BVNC_KM RGX_BVNC_KM_ST(RGX_BVNC_KM_B) "." RGX_BVNC_KM_ST(RGX_BVNC_KM_V) "." RGX_BVNC_KM_ST(RGX_BVNC_KM_N) "." RGX_BVNC_KM_ST(RGX_BVNC_KM_C) -#define RGX_BVNC_KM_V_ST RGX_BVNC_KM_ST(RGX_BVNC_KM_V) - -/* Maximum string size is [bb.vvvp.nnnn.cccc\0], includes null char */ -#define RGX_BVNC_STR_SIZE_MAX (2U+1U+4U+1U+4U+1U+4U+1U) -#define RGX_BVNC_STR_FMTSPEC "%u.%u.%u.%u" -#define RGX_BVNC_STRP_FMTSPEC "%u.%up.%u.%u" - - -/****************************************************************************** - * RGX Defines - *****************************************************************************/ - -#define BVNC_FIELD_MASK ((1UL << BVNC_FIELD_WIDTH) - 1U) -#define C_POSITION (0U) -#define N_POSITION ((C_POSITION) + (BVNC_FIELD_WIDTH)) -#define V_POSITION ((N_POSITION) + (BVNC_FIELD_WIDTH)) -#define B_POSITION ((V_POSITION) + (BVNC_FIELD_WIDTH)) - -#define B_POSTION_MASK (((IMG_UINT64)(BVNC_FIELD_MASK) << (B_POSITION))) -#define V_POSTION_MASK (((IMG_UINT64)(BVNC_FIELD_MASK) << (V_POSITION))) -#define N_POSTION_MASK (((IMG_UINT64)(BVNC_FIELD_MASK) << (N_POSITION))) -#define C_POSTION_MASK (((IMG_UINT64)(BVNC_FIELD_MASK) << (C_POSITION))) - -#define GET_B(x) (((x) & (B_POSTION_MASK)) >> (B_POSITION)) -#define GET_V(x) (((x) & (V_POSTION_MASK)) >> (V_POSITION)) -#define GET_N(x) (((x) & (N_POSTION_MASK)) >> (N_POSITION)) -#define GET_C(x) (((x) & (C_POSTION_MASK)) >> (C_POSITION)) - -#define BVNC_PACK(B,V,N,C) ((((IMG_UINT64)(B))) << (B_POSITION) | \ - (((IMG_UINT64)(V))) << (V_POSITION) | \ - (((IMG_UINT64)(N))) << (N_POSITION) | \ - (((IMG_UINT64)(C))) << (C_POSITION) \ - ) - -#define RGX_CR_CORE_ID_CONFIG_N_SHIFT (8U) -#define RGX_CR_CORE_ID_CONFIG_C_SHIFT (0U) - -#define RGX_CR_CORE_ID_CONFIG_N_CLRMSK (0XFFFF00FFU) -#define RGX_CR_CORE_ID_CONFIG_C_CLRMSK (0XFFFFFF00U) - -#define RGXFW_MAX_NUM_OS (8U) -#define RGXFW_HOST_OS (0U) -#define RGXFW_GUEST_OSID_START (1U) - -#define RGXFW_THREAD_0 (0U) -#define RGXFW_THREAD_1 (1U) - -/* META cores (required for the RGX_FEATURE_META) */ -#define MTP218 (1U) -#define MTP219 (2U) -#define LTP218 (3U) -#define LTP217 (4U) - -/* META Core memory feature depending on META variants */ -#define RGX_META_COREMEM_32K (32*1024) -#define RGX_META_COREMEM_48K (48*1024) -#define RGX_META_COREMEM_64K (64*1024) -#define RGX_META_COREMEM_96K (96*1024) -#define RGX_META_COREMEM_128K (128*1024) -#define RGX_META_COREMEM_256K (256*1024) - -#if !defined(__KERNEL__) -#if (!defined(SUPPORT_TRUSTED_DEVICE) || defined(RGX_FEATURE_META_DMA)) && \ - (defined(RGX_FEATURE_META_COREMEM_SIZE) && RGX_FEATURE_META_COREMEM_SIZE != 0) -#define RGX_META_COREMEM_SIZE (RGX_FEATURE_META_COREMEM_SIZE*1024U) -#define RGX_META_COREMEM (1) -#define RGX_META_COREMEM_CODE (1) -#if !defined(FIX_HW_BRN_50767) && defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED == 1) -#define RGX_META_COREMEM_DATA (1) -#endif -#else -#undef SUPPORT_META_COREMEM -#undef RGX_FEATURE_META_COREMEM_SIZE -#undef RGX_FEATURE_META_DMA -#define RGX_FEATURE_META_COREMEM_SIZE (0) -#define RGX_META_COREMEM_SIZE (0) -#endif -#endif - -#define GET_ROGUE_CACHE_LINE_SIZE(x) ((((IMG_UINT32)(x)) > 0U) ? ((IMG_UINT32)(x)/8U) : (0U)) - - -#if defined(SUPPORT_AGP) -#define MAX_HW_TA3DCONTEXTS 3U -#else -#define MAX_HW_TA3DCONTEXTS 2U -#endif - -#define RGX_CR_CLK_CTRL_ALL_ON (IMG_UINT64_C(0x5555555555555555)&RGX_CR_CLK_CTRL_MASKFULL) -#define RGX_CR_CLK_CTRL_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&RGX_CR_CLK_CTRL_MASKFULL) -#define RGX_CR_CLK_CTRL2_ALL_ON (IMG_UINT64_C(0x5555555555555555)&RGX_CR_CLK_CTRL2_MASKFULL) -#define RGX_CR_CLK_CTRL2_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&RGX_CR_CLK_CTRL2_MASKFULL) -#define RGX_CR_CLK_XTPLUS_CTRL_ALL_ON (IMG_UINT64_C(0x5555555555555555)&RGX_CR_CLK_XTPLUS_CTRL_MASKFULL) -#define RGX_CR_CLK_XTPLUS_CTRL_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&RGX_CR_CLK_XTPLUS_CTRL_MASKFULL) -#define DPX_CR_DPX_CLK_CTRL_ALL_ON (IMG_UINT64_C(0x5555555555555555)&DPX_CR_DPX_CLK_CTRL_MASKFULL) -#define DPX_CR_DPX_CLK_CTRL_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&DPX_CR_DPX_CLK_CTRL_MASKFULL) - -#define RGX_CR_SOFT_RESET_DUST_n_CORE_EN (RGX_CR_SOFT_RESET_DUST_A_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_B_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_C_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_D_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_E_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_F_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_G_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_H_CORE_EN) - -/* SOFT_RESET Rascal and DUSTs bits */ -#define RGX_CR_SOFT_RESET_RASCALDUSTS_EN (RGX_CR_SOFT_RESET_RASCAL_CORE_EN | \ - RGX_CR_SOFT_RESET_DUST_n_CORE_EN) - - - - -/* SOFT_RESET steps as defined in the TRM */ -#define RGX_S7_SOFT_RESET_DUSTS (RGX_CR_SOFT_RESET_DUST_n_CORE_EN) - -#define RGX_S7_SOFT_RESET_JONES (RGX_CR_SOFT_RESET_PM_EN | \ - RGX_CR_SOFT_RESET_VDM_EN | \ - RGX_CR_SOFT_RESET_ISP_EN) - -#define RGX_S7_SOFT_RESET_JONES_ALL (RGX_S7_SOFT_RESET_JONES | \ - RGX_CR_SOFT_RESET_BIF_EN | \ - RGX_CR_SOFT_RESET_SLC_EN | \ - RGX_CR_SOFT_RESET_GARTEN_EN) - -#define RGX_S7_SOFT_RESET2 (RGX_CR_SOFT_RESET2_BLACKPEARL_EN | \ - RGX_CR_SOFT_RESET2_PIXEL_EN | \ - RGX_CR_SOFT_RESET2_CDM_EN | \ - RGX_CR_SOFT_RESET2_VERTEX_EN) - - - -#define RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT (12U) -#define RGX_BIF_PM_PHYSICAL_PAGE_SIZE (1UL << RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT) - -#define RGX_BIF_PM_VIRTUAL_PAGE_ALIGNSHIFT (14U) -#define RGX_BIF_PM_VIRTUAL_PAGE_SIZE (1UL << RGX_BIF_PM_VIRTUAL_PAGE_ALIGNSHIFT) - -#define RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE (16U) - -/* To get the number of required Dusts, divide the number of - * clusters by 2 and round up - */ -#define RGX_REQ_NUM_DUSTS(CLUSTERS) (((CLUSTERS) + 1U) / 2U) - -/* To get the number of required Bernado/Phantom(s), divide - * the number of clusters by 4 and round up - */ -#define RGX_REQ_NUM_PHANTOMS(CLUSTERS) (((CLUSTERS) + 3U) / 4U) -#define RGX_REQ_NUM_BERNADOS(CLUSTERS) (((CLUSTERS) + 3U) / 4U) -#define RGX_REQ_NUM_BLACKPEARLS(CLUSTERS) (((CLUSTERS) + 3U) / 4U) - -#if !defined(__KERNEL__) -# define RGX_NUM_PHANTOMS (RGX_REQ_NUM_PHANTOMS(RGX_FEATURE_NUM_CLUSTERS)) -#endif - - -/* META second thread feature depending on META variants and - * available CoreMem - */ -#if defined(RGX_FEATURE_META) && (RGX_FEATURE_META == MTP218 || RGX_FEATURE_META == MTP219) && defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && (RGX_FEATURE_META_COREMEM_SIZE == 256) -#define RGXFW_META_SUPPORT_2ND_THREAD -#endif - - -/* - * FW MMU contexts - */ -#if defined(SUPPORT_TRUSTED_DEVICE) && defined(RGX_FEATURE_META) -#define MMU_CONTEXT_MAPPING_FWPRIV (0x0U) /* FW code/private data */ -#define MMU_CONTEXT_MAPPING_FWIF (0x7U) /* Host/FW data */ -#else -#define MMU_CONTEXT_MAPPING_FWPRIV (0x0U) -#define MMU_CONTEXT_MAPPING_FWIF (0x0U) -#endif - - -/* - * Utility macros to calculate CAT_BASE register addresses - */ -#define BIF_CAT_BASEx(n) \ - (RGX_CR_BIF_CAT_BASE0 + ((n) * (RGX_CR_BIF_CAT_BASE1 - RGX_CR_BIF_CAT_BASE0))) - -#define FWCORE_MEM_CAT_BASEx(n) \ - (RGX_CR_FWCORE_MEM_CAT_BASE0 + ((n) * (RGX_CR_FWCORE_MEM_CAT_BASE1 - RGX_CR_FWCORE_MEM_CAT_BASE0))) - -/* - * FWCORE wrapper register defines - */ -#define FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_SHIFT -#define FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_CLRMSK RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_CLRMSK -#define FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT (12U) - - -/****************************************************************************** - * WA HWBRNs - *****************************************************************************/ - -#if defined(RGX_CR_JONES_IDLE_MASKFULL) -/* Workaround for HW BRN 57289 */ -#if (RGX_CR_JONES_IDLE_MASKFULL != 0x0000000000007FFF) -#error This WA must be updated if RGX_CR_JONES_IDLE is expanded!!! -#endif -#undef RGX_CR_JONES_IDLE_MASKFULL -#undef RGX_CR_JONES_IDLE_TDM_SHIFT -#undef RGX_CR_JONES_IDLE_TDM_CLRMSK -#undef RGX_CR_JONES_IDLE_TDM_EN -#define RGX_CR_JONES_IDLE_MASKFULL (IMG_UINT64_C(0x0000000000003FFF)) -#endif - -#if !defined(__KERNEL__) - -#if defined(RGX_FEATURE_ROGUEXE) -#define RGX_NUM_RASTERISATION_MODULES RGX_FEATURE_NUM_CLUSTERS -#else -#define RGX_NUM_RASTERISATION_MODULES RGX_NUM_PHANTOMS -#endif - -#endif /* defined(__KERNEL__) */ - -/* GPU CR timer tick in GPU cycles */ -#define RGX_CRTIME_TICK_IN_CYCLES (256U) - -/* for nohw multicore return max cores possible to client */ -#define RGX_MULTICORE_MAX_NOHW_CORES (4U) - -/* - If the size of the SLC is less than this value then the TPU bypasses the SLC. - */ -#define RGX_TPU_CACHED_SLC_SIZE_THRESHOLD_KB (128U) - -/* - * If the size of the SLC is bigger than this value then the TCU must not be bypassed in the SLC. - * In XE_MEMORY_HIERARCHY cores, the TCU is bypassed by default. - */ -#define RGX_TCU_CACHED_SLC_SIZE_THRESHOLD_KB (32U) - -/* - * Register used by the FW to track the current boot stage (not used in MIPS) - */ -#define RGX_FW_BOOT_STAGE_REGISTER (RGX_CR_POWER_ESTIMATE_RESULT) - -/* - * Virtualisation definitions - */ -#define RGX_VIRTUALISATION_REG_SIZE_PER_OS (RGX_CR_MTS_SCHEDULE1 - RGX_CR_MTS_SCHEDULE) - -/* - * Macro used to indicate which version of HWPerf is active - */ -#define RGX_FEATURE_HWPERF_ROGUE - -/* - * Maximum number of cores supported by TRP - */ -#define RGX_TRP_MAX_NUM_CORES (4U) - -#endif /* RGXDEFS_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgxmhdefs_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgxmhdefs_km.h deleted file mode 100644 index fe8272b8584f5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgxmhdefs_km.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************/ /*! -@Title Hardware definition file rgxmhdefs_km.h -@Brief The file contains auto-generated hardware definitions without - BVNC-specific compile time conditionals. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* **** Autogenerated C -- do not edit **** */ - -/* - * rogue_mh.def - */ - - -#ifndef RGXMHDEFS_KM_H -#define RGXMHDEFS_KM_H - -#include "img_types.h" -#include "img_defs.h" - - -#define RGXMHDEFS_KM_REVISION 0 - -#define RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_FENCE (0x00000000U) -#define RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_CONTEXT (0x00000001U) -#define RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_QUEUE (0x00000002U) - - -#define RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_CTL_STREAM (0x00000000U) -#define RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_CTX_BUFFER (0x00000001U) -#define RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_QUEUE_CTL (0x00000002U) - - -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAFSTACK (0x00000008U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAMLIST (0x00000009U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DFSTACK (0x0000000aU) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DMLIST (0x0000000bU) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_PMCTX0 (0x0000000cU) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_PMCTX1 (0x0000002dU) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_UFSTACK (0x0000000fU) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAMMUSTACK (0x00000012U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DMMUSTACK (0x00000013U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAUFSTACK (0x00000016U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DUFSTACK (0x00000017U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DVFP (0x00000019U) -#define RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAVFP (0x0000001aU) - - -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAFSTACK (0x00000000U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAMLIST (0x00000001U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DFSTACK (0x00000002U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DMLIST (0x00000003U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_PMCTX0 (0x00000004U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_PMCTX1 (0x00000025U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_MAVP (0x00000006U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_UFSTACK (0x00000007U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAMMUSTACK (0x00000008U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DMMUSTACK (0x00000009U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAUFSTACK (0x00000014U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DUFSTACK (0x00000015U) -#define RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAVFP (0x00000018U) - - -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_PPP (0x00000008U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_VCERTC (0x00000007U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_TEACRTC (0x00000006U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_PSGRTC (0x00000005U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_PSGR (0x00000004U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_PSGS (0x00000003U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_TPC (0x00000002U) -#define RGX_MH_TAG_SB_TA_ENCODING_TA_TAG_VCE (0x00000001U) - - -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_CREQ00 (0x00000000U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_CREQ01 (0x00000001U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_PREQ00 (0x00000002U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_PREQ01 (0x00000003U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_RREQ (0x00000004U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_DBSC (0x00000005U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_CPF (0x00000006U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_2_ENCODING_IPF_TAG_DELTA (0x00000007U) - - -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_CREQ00 (0x00000000U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_CREQ01 (0x00000001U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_CREQ02 (0x00000002U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_CREQ03 (0x00000003U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_PREQ00 (0x00000004U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_PREQ01 (0x00000005U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_PREQ02 (0x00000006U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_PREQ03 (0x00000007U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_RREQ (0x00000008U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_DBSC (0x00000009U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_CPF (0x0000000aU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_4_ENCODING_IPF_TAG_DELTA (0x0000000bU) - - -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ00 (0x00000000U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ01 (0x00000001U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ02 (0x00000002U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ03 (0x00000003U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ04 (0x00000004U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ05 (0x00000005U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CREQ06 (0x00000006U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ00 (0x00000007U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ01 (0x00000008U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ02 (0x00000009U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ03 (0x0000000aU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ04 (0x0000000bU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ05 (0x0000000cU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_PREQ06 (0x0000000dU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_RREQ (0x0000000eU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_DBSC (0x0000000fU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_CPF (0x00000010U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_7_ENCODING_IPF_TAG_DELTA (0x00000011U) - - -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ00 (0x00000000U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ01 (0x00000001U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ02 (0x00000002U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ03 (0x00000003U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ04 (0x00000004U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ05 (0x00000005U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ06 (0x00000006U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ07 (0x00000007U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ08 (0x00000008U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ09 (0x00000009U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ10 (0x0000000aU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ11 (0x0000000bU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ12 (0x0000000cU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CREQ13 (0x0000000dU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ00 (0x0000000eU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ01 (0x0000000fU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ02 (0x00000010U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ03 (0x00000011U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ04 (0x00000012U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ05 (0x00000013U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ06 (0x00000014U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ07 (0x00000015U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ08 (0x00000016U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ09 (0x00000017U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ10 (0x00000018U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ11 (0x00000019U) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ12 (0x0000001aU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_PREQ13 (0x0000001bU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_RREQ (0x0000001cU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_DBSC (0x0000001dU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_CPF (0x0000001eU) -#define RGX_MH_TAG_SB_IPF_IPF_NUM_PIPES_14_ENCODING_IPF_TAG_DELTA (0x0000001fU) - - -#define RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_PDS_STATE (0x00000000U) -#define RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_DEPTH_BIAS (0x00000001U) -#define RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_FLOOR_OFFSET_DATA (0x00000002U) -#define RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_DELTA_DATA (0x00000003U) - - -#define RGX_MH_TAG_SB_ISP_ENCODING_ISP_TAG_ZLS (0x00000000U) -#define RGX_MH_TAG_SB_ISP_ENCODING_ISP_TAG_DS (0x00000001U) - - -#define RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_CONTROL (0x00000000U) -#define RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_STATE (0x00000001U) -#define RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_INDEX (0x00000002U) -#define RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_STACK (0x00000004U) -#define RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_CONTEXT (0x00000008U) - - -#define RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_CONTROL_STREAM (0x00000000U) -#define RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_INDIRECT_DATA (0x00000001U) -#define RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_EVENT_DATA (0x00000002U) -#define RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_CONTEXT_STATE (0x00000003U) - - -#define RGX_MH_TAG_SB_MIPS_ENCODING_MIPS_TAG_OPCODE_FETCH (0x00000002U) -#define RGX_MH_TAG_SB_MIPS_ENCODING_MIPS_TAG_DATA_ACCESS (0x00000003U) - - -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PT_REQUEST (0x00000000U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PD_REQUEST (0x00000001U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PC_REQUEST (0x00000002U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PT_REQUEST (0x00000003U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PD_REQUEST (0x00000004U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PC_REQUEST (0x00000005U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PD_WREQUEST (0x00000006U) -#define RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PC_WREQUEST (0x00000007U) - - -#define RGX_MH_TAG_ENCODING_MH_TAG_MMU (0x00000000U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_MMU (0x00000001U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_IFU (0x00000002U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_LSU (0x00000003U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MIPS (0x00000004U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG0 (0x00000005U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG1 (0x00000006U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG2 (0x00000007U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG3 (0x00000008U) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG0 (0x00000009U) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG1 (0x0000000aU) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG2 (0x0000000bU) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG3 (0x0000000cU) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG4 (0x0000000dU) -#define RGX_MH_TAG_ENCODING_MH_TAG_PDS_0 (0x0000000eU) -#define RGX_MH_TAG_ENCODING_MH_TAG_PDS_1 (0x0000000fU) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCA (0x00000010U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCB (0x00000011U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCC (0x00000012U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCD (0x00000013U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCA (0x00000014U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCB (0x00000015U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCC (0x00000016U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCD (0x00000017U) -#define RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDSRW (0x00000018U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TCU_0 (0x00000019U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TCU_1 (0x0000001aU) -#define RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_0 (0x0000001bU) -#define RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_1 (0x0000001cU) -#define RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_2 (0x0000001dU) -#define RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_3 (0x0000001eU) -#define RGX_MH_TAG_ENCODING_MH_TAG_USC (0x0000001fU) -#define RGX_MH_TAG_ENCODING_MH_TAG_ISP_ZLS (0x00000020U) -#define RGX_MH_TAG_ENCODING_MH_TAG_ISP_DS (0x00000021U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TPF (0x00000022U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TPF_PBCDBIAS (0x00000023U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TPF_SPF (0x00000024U) -#define RGX_MH_TAG_ENCODING_MH_TAG_IPF_CREQ (0x00000025U) -#define RGX_MH_TAG_ENCODING_MH_TAG_IPF_OTHERS (0x00000026U) -#define RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG5 (0x00000027U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_PPP (0x00000028U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_TPWRTC (0x00000029U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_TEACRTC (0x0000002aU) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGRTC (0x0000002bU) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGREGION (0x0000002cU) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGSTREAM (0x0000002dU) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_TPW (0x0000002eU) -#define RGX_MH_TAG_ENCODING_MH_TAG_TA_TPC (0x0000002fU) -#define RGX_MH_TAG_ENCODING_MH_TAG_PM_ALLOC (0x00000030U) -#define RGX_MH_TAG_ENCODING_MH_TAG_PM_DEALLOC (0x00000031U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TDM_DMA (0x00000032U) -#define RGX_MH_TAG_ENCODING_MH_TAG_TDM_CTL (0x00000033U) -#define RGX_MH_TAG_ENCODING_MH_TAG_PBE0 (0x00000034U) -#define RGX_MH_TAG_ENCODING_MH_TAG_PBE1 (0x00000035U) -#define RGX_MH_TAG_ENCODING_MH_TAG_PBE2 (0x00000036U) -#define RGX_MH_TAG_ENCODING_MH_TAG_PBE3 (0x00000037U) - - -#endif /* RGXMHDEFS_KM_H */ -/***************************************************************************** - End of file (rgxmhdefs_km.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/km/rgxmmudefs_km.h b/drivers/gpu/drm/img-rogue/1.17/km/rgxmmudefs_km.h deleted file mode 100644 index 65186643a20ae..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km/rgxmmudefs_km.h +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************************************/ /*! -@Title Hardware definition file rgxmmudefs_km.h -@Brief The file contains auto-generated hardware definitions without - BVNC-specific compile time conditionals. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* **** Autogenerated C -- do not edit **** */ - -/* - * rogue_bif.def - */ - - -#ifndef RGXMMUDEFS_KM_H -#define RGXMMUDEFS_KM_H - -#include "img_types.h" -#include "img_defs.h" - - -#define RGXMMUDEFS_KM_REVISION 0 - -#define RGX_BIF_DM_ENCODING_VERTEX (0x00000000U) -#define RGX_BIF_DM_ENCODING_PIXEL (0x00000001U) -#define RGX_BIF_DM_ENCODING_COMPUTE (0x00000002U) -#define RGX_BIF_DM_ENCODING_TLA (0x00000003U) -#define RGX_BIF_DM_ENCODING_PB_VCE (0x00000004U) -#define RGX_BIF_DM_ENCODING_PB_TE (0x00000005U) -#define RGX_BIF_DM_ENCODING_META (0x00000007U) -#define RGX_BIF_DM_ENCODING_HOST (0x00000008U) -#define RGX_BIF_DM_ENCODING_PM_ALIST (0x00000009U) - - -#define RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT (30U) -#define RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK (IMG_UINT64_C(0xFFFFFF003FFFFFFF)) -#define RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT (21U) -#define RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFC01FFFFF)) -#define RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT (12U) -#define RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFE00FFF)) - - -#define RGX_MMUCTRL_ENTRIES_PC_VALUE (0x00000400U) - - -#define RGX_MMUCTRL_ENTRIES_PD_VALUE (0x00000200U) - - -#define RGX_MMUCTRL_ENTRIES_PT_VALUE (0x00000200U) - - -#define RGX_MMUCTRL_ENTRY_SIZE_PC_VALUE (0x00000020U) - - -#define RGX_MMUCTRL_ENTRY_SIZE_PD_VALUE (0x00000040U) - - -#define RGX_MMUCTRL_ENTRY_SIZE_PT_VALUE (0x00000040U) - - -#define RGX_MMUCTRL_PAGE_SIZE_MASK (0x00000007U) -#define RGX_MMUCTRL_PAGE_SIZE_4KB (0x00000000U) -#define RGX_MMUCTRL_PAGE_SIZE_16KB (0x00000001U) -#define RGX_MMUCTRL_PAGE_SIZE_64KB (0x00000002U) -#define RGX_MMUCTRL_PAGE_SIZE_256KB (0x00000003U) -#define RGX_MMUCTRL_PAGE_SIZE_1MB (0x00000004U) -#define RGX_MMUCTRL_PAGE_SIZE_2MB (0x00000005U) - - -#define RGX_MMUCTRL_PAGE_4KB_RANGE_SHIFT (12U) -#define RGX_MMUCTRL_PAGE_4KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) - - -#define RGX_MMUCTRL_PAGE_16KB_RANGE_SHIFT (14U) -#define RGX_MMUCTRL_PAGE_16KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000003FFF)) - - -#define RGX_MMUCTRL_PAGE_64KB_RANGE_SHIFT (16U) -#define RGX_MMUCTRL_PAGE_64KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF000000FFFF)) - - -#define RGX_MMUCTRL_PAGE_256KB_RANGE_SHIFT (18U) -#define RGX_MMUCTRL_PAGE_256KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF000003FFFF)) - - -#define RGX_MMUCTRL_PAGE_1MB_RANGE_SHIFT (20U) -#define RGX_MMUCTRL_PAGE_1MB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF00000FFFFF)) - - -#define RGX_MMUCTRL_PAGE_2MB_RANGE_SHIFT (21U) -#define RGX_MMUCTRL_PAGE_2MB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF00001FFFFF)) - - -#define RGX_MMUCTRL_PT_BASE_4KB_RANGE_SHIFT (12U) -#define RGX_MMUCTRL_PT_BASE_4KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) - - -#define RGX_MMUCTRL_PT_BASE_16KB_RANGE_SHIFT (10U) -#define RGX_MMUCTRL_PT_BASE_16KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF00000003FF)) - - -#define RGX_MMUCTRL_PT_BASE_64KB_RANGE_SHIFT (8U) -#define RGX_MMUCTRL_PT_BASE_64KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF00000000FF)) - - -#define RGX_MMUCTRL_PT_BASE_256KB_RANGE_SHIFT (6U) -#define RGX_MMUCTRL_PT_BASE_256KB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF000000003F)) - - -#define RGX_MMUCTRL_PT_BASE_1MB_RANGE_SHIFT (5U) -#define RGX_MMUCTRL_PT_BASE_1MB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF000000001F)) - - -#define RGX_MMUCTRL_PT_BASE_2MB_RANGE_SHIFT (5U) -#define RGX_MMUCTRL_PT_BASE_2MB_RANGE_CLRMSK (IMG_UINT64_C(0xFFFFFF000000001F)) - - -#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_SHIFT (62U) -#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_CLRMSK (IMG_UINT64_C(0xBFFFFFFFFFFFFFFF)) -#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN (IMG_UINT64_C(0x4000000000000000)) -#define RGX_MMUCTRL_PT_DATA_VP_PAGE_HI_SHIFT (40U) -#define RGX_MMUCTRL_PT_DATA_VP_PAGE_HI_CLRMSK (IMG_UINT64_C(0xC00000FFFFFFFFFF)) -#define RGX_MMUCTRL_PT_DATA_PAGE_SHIFT (12U) -#define RGX_MMUCTRL_PT_DATA_PAGE_CLRMSK (IMG_UINT64_C(0xFFFFFF0000000FFF)) -#define RGX_MMUCTRL_PT_DATA_VP_PAGE_LO_SHIFT (6U) -#define RGX_MMUCTRL_PT_DATA_VP_PAGE_LO_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFF03F)) -#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_SHIFT (5U) -#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFDF)) -#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN (IMG_UINT64_C(0x0000000000000020)) -#define RGX_MMUCTRL_PT_DATA_PM_SRC_SHIFT (4U) -#define RGX_MMUCTRL_PT_DATA_PM_SRC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFEF)) -#define RGX_MMUCTRL_PT_DATA_PM_SRC_EN (IMG_UINT64_C(0x0000000000000010)) -#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_SHIFT (3U) -#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF7)) -#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN (IMG_UINT64_C(0x0000000000000008)) -#define RGX_MMUCTRL_PT_DATA_CC_SHIFT (2U) -#define RGX_MMUCTRL_PT_DATA_CC_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFB)) -#define RGX_MMUCTRL_PT_DATA_CC_EN (IMG_UINT64_C(0x0000000000000004)) -#define RGX_MMUCTRL_PT_DATA_READ_ONLY_SHIFT (1U) -#define RGX_MMUCTRL_PT_DATA_READ_ONLY_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFD)) -#define RGX_MMUCTRL_PT_DATA_READ_ONLY_EN (IMG_UINT64_C(0x0000000000000002)) -#define RGX_MMUCTRL_PT_DATA_VALID_SHIFT (0U) -#define RGX_MMUCTRL_PT_DATA_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_MMUCTRL_PT_DATA_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_SHIFT (40U) -#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_CLRMSK (IMG_UINT64_C(0xFFFFFEFFFFFFFFFF)) -#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN (IMG_UINT64_C(0x0000010000000000)) -#define RGX_MMUCTRL_PD_DATA_PT_BASE_SHIFT (5U) -#define RGX_MMUCTRL_PD_DATA_PT_BASE_CLRMSK (IMG_UINT64_C(0xFFFFFF000000001F)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_SHIFT (1U) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFF1)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB (IMG_UINT64_C(0x0000000000000000)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB (IMG_UINT64_C(0x0000000000000002)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB (IMG_UINT64_C(0x0000000000000004)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB (IMG_UINT64_C(0x0000000000000006)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB (IMG_UINT64_C(0x0000000000000008)) -#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB (IMG_UINT64_C(0x000000000000000a)) -#define RGX_MMUCTRL_PD_DATA_VALID_SHIFT (0U) -#define RGX_MMUCTRL_PD_DATA_VALID_CLRMSK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFE)) -#define RGX_MMUCTRL_PD_DATA_VALID_EN (IMG_UINT64_C(0x0000000000000001)) - - -#define RGX_MMUCTRL_PC_DATA_PD_BASE_SHIFT (4U) -#define RGX_MMUCTRL_PC_DATA_PD_BASE_CLRMSK (0x0000000FU) -#define RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT (12U) -#define RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSIZE (4096U) -#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_SHIFT (1U) -#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_CLRMSK (0xFFFFFFFDU) -#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN (0x00000002U) -#define RGX_MMUCTRL_PC_DATA_VALID_SHIFT (0U) -#define RGX_MMUCTRL_PC_DATA_VALID_CLRMSK (0xFFFFFFFEU) -#define RGX_MMUCTRL_PC_DATA_VALID_EN (0x00000001U) - - -#endif /* RGXMMUDEFS_KM_H */ -/***************************************************************************** - End of file (rgxmmudefs_km.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/km_apphint.c b/drivers/gpu/drm/img-rogue/1.17/km_apphint.c deleted file mode 100644 index 2be972dc2f695..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km_apphint.c +++ /dev/null @@ -1,1749 +0,0 @@ -/*************************************************************************/ /*! -@File km_apphint.c -@Title Apphint routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "di_server.h" -#include "pvr_uaccess.h" -#include -#include -#include -#include - -/* Common and SO layer */ -#include "img_defs.h" -#include "sofunc_pvr.h" - -/* for action device access */ -#include "pvrsrv.h" -#include "device.h" -#include "rgxdevice.h" -#include "rgxfwutils.h" -#include "rgxhwperf.h" -#include "htbserver.h" -#include "rgxutils.h" -#include "rgxapi_km.h" - - -/* defines for default values */ -#include "rgx_fwif_km.h" -#include "htbuffer_types.h" - -#include "pvr_notifier.h" - -#include "km_apphint_defs.h" -#include "km_apphint.h" - -#if defined(PDUMP) -#include -#include "pdump_km.h" -#endif - -/* Size of temporary buffers used to read and write AppHint data. - * Must be large enough to contain any strings read or written but no larger - * than 4096: which is the buffer size for the kernel_param_ops .get - * function. And less than 1024 to keep the stack frame size within bounds. - */ -#define APPHINT_BUFFER_SIZE 512 - -#define APPHINT_DEVICES_MAX 16 - -/* Apphint Debug output level */ -#define APPHINT_DPF_LEVEL PVR_DBG_VERBOSE - -/* -******************************************************************************* - * AppHint mnemonic data type helper tables -******************************************************************************/ -struct apphint_lookup { - const char *name; - int value; -}; - -static const struct apphint_lookup fwt_logtype_tbl[] = { - { "trace", 0}, - { "none", 0} -#if defined(SUPPORT_TBI_INTERFACE) - , { "tbi", 1} -#endif -}; - -static const struct apphint_lookup fwt_loggroup_tbl[] = { - RGXFWIF_LOG_GROUP_NAME_VALUE_MAP -}; - -static const struct apphint_lookup htb_loggroup_tbl[] = { -#define X(a, b) { #b, HTB_LOG_GROUP_FLAG(a) }, - HTB_LOG_SFGROUPLIST -#undef X -}; - -static const struct apphint_lookup htb_opmode_tbl[] = { - { "droplatest", HTB_OPMODE_DROPLATEST}, - { "dropoldest", HTB_OPMODE_DROPOLDEST}, - { "block", HTB_OPMODE_BLOCK} -}; - -__maybe_unused -static const struct apphint_lookup htb_logmode_tbl[] = { - { "all", HTB_LOGMODE_ALLPID}, - { "restricted", HTB_LOGMODE_RESTRICTEDPID} -}; - -__maybe_unused -static const struct apphint_lookup timecorr_clk_tbl[] = { - { "mono", 0 }, - { "mono_raw", 1 }, - { "sched", 2 } -}; - -/* -******************************************************************************* - Data types -******************************************************************************/ -union apphint_value { - IMG_UINT64 UINT64; - IMG_UINT32 UINT32; - IMG_BOOL BOOL; - IMG_CHAR *STRING; -}; - -union apphint_query_action { - PVRSRV_ERROR (*UINT64)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_UINT64 *value); - PVRSRV_ERROR (*UINT32)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_UINT32 *value); - PVRSRV_ERROR (*BOOL)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_BOOL *value); - PVRSRV_ERROR (*STRING)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_CHAR **value); -}; - -union apphint_set_action { - PVRSRV_ERROR (*UINT64)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_UINT64 value); - PVRSRV_ERROR (*UINT32)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_UINT32 value); - PVRSRV_ERROR (*BOOL)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_BOOL value); - PVRSRV_ERROR (*STRING)(const PVRSRV_DEVICE_NODE *device, - const void *private_data, IMG_CHAR *value); -}; - -struct apphint_action { - union apphint_query_action query; /*!< Query callbacks. */ - union apphint_set_action set; /*!< Set callbacks. */ - const PVRSRV_DEVICE_NODE *device; /*!< Pointer to the device node.*/ - const void *private_data; /*!< Opaque data passed to `query` and - `set` callbacks. */ - union apphint_value stored; /*!< Value of the AppHint. */ - bool free; /*!< Flag indicating that memory has been - allocated for this AppHint and it - needs to be freed on deinit. */ - bool initialised; /*!< Flag indicating if the AppHint has - been already initialised. */ -}; - -struct apphint_param { - IMG_UINT32 id; - APPHINT_DATA_TYPE data_type; - const void *data_type_helper; - IMG_UINT32 helper_size; -}; - -struct apphint_init_data { - IMG_UINT32 id; /* index into AppHint Table */ - APPHINT_CLASS class; - const IMG_CHAR *name; - union apphint_value default_value; -}; - -struct apphint_init_data_mapping { - IMG_UINT32 device_apphint_id; - IMG_UINT32 modparam_apphint_id; -}; - -struct apphint_class_state { - APPHINT_CLASS class; - IMG_BOOL enabled; -}; - -struct apphint_work { - struct work_struct work; - union apphint_value new_value; - struct apphint_action *action; -}; - -/* -******************************************************************************* - Initialization / configuration table data -******************************************************************************/ -#define UINT32Bitfield UINT32 -#define UINT32List UINT32 - -static const struct apphint_init_data init_data_buildvar[] = { -#define X(a, b, c, d, e) \ - {APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} }, - APPHINT_LIST_BUILDVAR_COMMON - APPHINT_LIST_BUILDVAR -#undef X -}; - -static const struct apphint_init_data init_data_modparam[] = { -#define X(a, b, c, d, e) \ - {APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} }, - APPHINT_LIST_MODPARAM_COMMON - APPHINT_LIST_MODPARAM -#undef X -}; - -static const struct apphint_init_data init_data_debuginfo[] = { -#define X(a, b, c, d, e) \ - {APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} }, - APPHINT_LIST_DEBUGINFO_COMMON - APPHINT_LIST_DEBUGINFO -#undef X -}; - -static const struct apphint_init_data init_data_debuginfo_device[] = { -#define X(a, b, c, d, e) \ - {APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} }, - APPHINT_LIST_DEBUGINFO_DEVICE_COMMON - APPHINT_LIST_DEBUGINFO_DEVICE -#undef X -}; - -static const struct apphint_init_data_mapping init_data_debuginfo_device_to_modparams[] = { -#define X(a, b) \ - {APPHINT_ID_ ## a, APPHINT_ID_ ## b}, - APPHINT_LIST_DEBUIGINFO_DEVICE_X_MODPARAM_INIT_COMMON - APPHINT_LIST_DEBUIGINFO_DEVICE_X_MODPARAM_INIT -#undef X -}; - -#undef UINT32Bitfield -#undef UINT32List - -__maybe_unused static const char NO_PARAM_TABLE[] = {}; - -static const struct apphint_param param_lookup[] = { -#define X(a, b, c, d, e) \ - {APPHINT_ID_ ## a, APPHINT_DATA_TYPE_ ## b, e, ARRAY_SIZE(e) }, - APPHINT_LIST_ALL -#undef X -}; - -static const struct apphint_class_state class_state[] = { -#define X(a) {APPHINT_CLASS_ ## a, APPHINT_ENABLED_CLASS_ ## a}, - APPHINT_CLASS_LIST -#undef X -}; - -/* -******************************************************************************* - Global state -******************************************************************************/ -/* If the union apphint_value becomes such that it is not possible to read - * and write atomically, a mutex may be desirable to prevent a read returning - * a partially written state. - * This would require a statically initialized mutex outside of the - * struct apphint_state to prevent use of an uninitialized mutex when - * module_params are provided on the command line. - * static DEFINE_MUTEX(apphint_mutex); - */ -static struct apphint_state -{ - struct workqueue_struct *workqueue; - DI_GROUP *debuginfo_device_rootdir[APPHINT_DEVICES_MAX]; - DI_ENTRY *debuginfo_device_entry[APPHINT_DEVICES_MAX][APPHINT_DEBUGINFO_DEVICE_ID_MAX]; - DI_GROUP *debuginfo_rootdir; - DI_ENTRY *debuginfo_entry[APPHINT_DEBUGINFO_ID_MAX]; - DI_GROUP *buildvar_rootdir; - DI_ENTRY *buildvar_entry[APPHINT_BUILDVAR_ID_MAX]; - - unsigned int num_devices; - PVRSRV_DEVICE_NODE *devices[APPHINT_DEVICES_MAX]; - unsigned int initialized; - - /* Array contains value space for 1 copy of all apphint values defined - * (for device 1) and N copies of device specific apphint values for - * multi-device platforms. - */ - struct apphint_action val[APPHINT_ID_MAX + ((APPHINT_DEVICES_MAX-1)*APPHINT_DEBUGINFO_DEVICE_ID_MAX)]; - -} apphint = { -/* statically initialise default values to ensure that any module_params - * provided on the command line are not overwritten by defaults. - */ - .val = { -#define UINT32Bitfield UINT32 -#define UINT32List UINT32 -#define X(a, b, c, d, e) \ - { {NULL}, {NULL}, NULL, NULL, {.b=d}, false }, - APPHINT_LIST_ALL -#undef X -#undef UINT32Bitfield -#undef UINT32List - }, - .initialized = 0, - .num_devices = 0 -}; - -#define APPHINT_DEBUGINFO_DEVICE_ID_OFFSET (APPHINT_ID_MAX-APPHINT_DEBUGINFO_DEVICE_ID_MAX) - -static inline void -get_apphint_id_from_action_addr(const struct apphint_action * const addr, - APPHINT_ID * const id) -{ - *id = (APPHINT_ID)(addr - apphint.val); - if (*id >= APPHINT_ID_MAX) { - *id -= APPHINT_DEBUGINFO_DEVICE_ID_OFFSET; - *id %= APPHINT_DEBUGINFO_DEVICE_ID_MAX; - *id += APPHINT_DEBUGINFO_DEVICE_ID_OFFSET; - } -} - -static inline void -get_value_offset_from_device(const PVRSRV_DEVICE_NODE * const device, - int * const offset, - APPHINT_ID id) -{ - int i; - IMG_BOOL bFound = IMG_FALSE; - - /* No device offset if not a device specific apphint */ - if (APPHINT_OF_DRIVER_NO_DEVICE == device) { - *offset = 0; - return; - } - - /* Check that the specified ID is a device-specific one. If not we - * set the offset to 0 for the global MODPARAM / BUILDVAR etc. AppHint - */ - for (i = 0; i < ARRAY_SIZE(init_data_debuginfo_device); i++) - { - const struct apphint_init_data *device_init = &init_data_debuginfo_device[i]; - - if ((IMG_UINT32)id == device_init->id) { - bFound = IMG_TRUE; - break; - } - } - - if (!bFound) { - *offset = 0; - return; - } - - for (i = 0; device && i < APPHINT_DEVICES_MAX; i++) { - if (apphint.devices[i] == device) - break; - } - if (APPHINT_DEVICES_MAX == i) { - PVR_DPF((PVR_DBG_WARNING, "%s: Unregistered device", __func__)); - i = 0; - } - *offset = i * APPHINT_DEBUGINFO_DEVICE_ID_MAX; -} - -/* - * apphint_action_worker - perform an action after an AppHint update has been - * requested by a UM process - * And update the record of the current active value - */ -static void apphint_action_worker(struct work_struct *work) -{ - struct apphint_work *work_pkt = container_of(work, - struct apphint_work, - work); - struct apphint_action *a = work_pkt->action; - union apphint_value value = work_pkt->new_value; - APPHINT_ID id; - PVRSRV_ERROR result = PVRSRV_OK; - - get_apphint_id_from_action_addr(a, &id); - - if (a->set.UINT64) { - switch (param_lookup[id].data_type) { - case APPHINT_DATA_TYPE_UINT64: - result = a->set.UINT64(a->device, - a->private_data, - value.UINT64); - break; - - case APPHINT_DATA_TYPE_UINT32: - case APPHINT_DATA_TYPE_UINT32Bitfield: - case APPHINT_DATA_TYPE_UINT32List: - result = a->set.UINT32(a->device, - a->private_data, - value.UINT32); - break; - - case APPHINT_DATA_TYPE_BOOL: - result = a->set.BOOL(a->device, - a->private_data, - value.BOOL); - break; - - case APPHINT_DATA_TYPE_STRING: - result = a->set.STRING(a->device, - a->private_data, - value.STRING); - kfree(value.STRING); - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: unrecognised data type (%d), index (%d)", - __func__, param_lookup[id].data_type, id)); - } - - /* Do not log errors if running in GUEST mode */ - if ((PVRSRV_OK != result) && !PVRSRV_VZ_MODE_IS(GUEST)) { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed (%s)", - __func__, PVRSRVGetErrorString(result))); - } - } else { - if (a->free) { - kfree(a->stored.STRING); - } - a->stored = value; - if (param_lookup[id].data_type == APPHINT_DATA_TYPE_STRING) { - a->free = true; - } - PVR_DPF((PVR_DBG_MESSAGE, - "%s: AppHint value updated before handler is registered, ID(%d)", - __func__, id)); - } - kfree((void *)work_pkt); -} - -static void apphint_action(union apphint_value new_value, - struct apphint_action *action) -{ - struct apphint_work *work_pkt = kmalloc(sizeof(*work_pkt), GFP_KERNEL); - - /* queue apphint update on a serialized workqueue to avoid races */ - if (work_pkt) { - work_pkt->new_value = new_value; - work_pkt->action = action; - INIT_WORK(&work_pkt->work, apphint_action_worker); - if (0 == queue_work(apphint.workqueue, &work_pkt->work)) { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to queue apphint change request", - __func__)); - goto err_exit; - } - } else { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to alloc memory for apphint change request", - __func__)); - goto err_exit; - } - return; -err_exit: - kfree(new_value.STRING); -} - -/* - * apphint_read - read the different AppHint data types - * return -errno or the buffer size - */ -static int apphint_read(char *buffer, size_t count, APPHINT_ID ue, - union apphint_value *value) -{ - APPHINT_DATA_TYPE data_type = param_lookup[ue].data_type; - int result = 0; - - switch (data_type) { - case APPHINT_DATA_TYPE_UINT64: - if (kstrtou64(buffer, 0, &value->UINT64) < 0) { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid UINT64 input data for id %d: %s", - __func__, ue, buffer)); - result = -EINVAL; - goto err_exit; - } - break; - case APPHINT_DATA_TYPE_UINT32: - if (kstrtou32(buffer, 0, &value->UINT32) < 0) { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid UINT32 input data for id %d: %s", - __func__, ue, buffer)); - result = -EINVAL; - goto err_exit; - } - break; - case APPHINT_DATA_TYPE_BOOL: - switch (buffer[0]) { - case '0': - case 'n': - case 'N': - case 'f': - case 'F': - value->BOOL = IMG_FALSE; - break; - case '1': - case 'y': - case 'Y': - case 't': - case 'T': - value->BOOL = IMG_TRUE; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid BOOL input data for id %d: %s", - __func__, ue, buffer)); - result = -EINVAL; - goto err_exit; - } - break; - case APPHINT_DATA_TYPE_UINT32List: - { - int i; - struct apphint_lookup *lookup = - (struct apphint_lookup *) - param_lookup[ue].data_type_helper; - int size = param_lookup[ue].helper_size; - /* buffer may include '\n', remove it */ - char *arg = strsep(&buffer, "\n"); - - if (lookup == (struct apphint_lookup *)NO_PARAM_TABLE) { - result = -EINVAL; - goto err_exit; - } - - for (i = 0; i < size; i++) { - if (strcasecmp(lookup[i].name, arg) == 0) { - value->UINT32 = lookup[i].value; - break; - } - } - if (i == size) { - if (OSStringLength(arg) == 0) { - PVR_DPF((PVR_DBG_ERROR, - "%s: No value set for AppHint", - __func__)); - } else { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unrecognised AppHint value (%s)", - __func__, arg)); - } - result = -EINVAL; - } - break; - } - case APPHINT_DATA_TYPE_UINT32Bitfield: - { - int i; - struct apphint_lookup *lookup = - (struct apphint_lookup *) - param_lookup[ue].data_type_helper; - int size = param_lookup[ue].helper_size; - /* buffer may include '\n', remove it */ - char *string = strsep(&buffer, "\n"); - char *token = strsep(&string, ","); - - if (lookup == (struct apphint_lookup *)NO_PARAM_TABLE) { - result = -EINVAL; - goto err_exit; - } - - value->UINT32 = 0; - /* empty string is valid to clear the bitfield */ - while (token && *token) { - for (i = 0; i < size; i++) { - if (strcasecmp(lookup[i].name, token) == 0) { - value->UINT32 |= lookup[i].value; - break; - } - } - if (i == size) { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unrecognised AppHint value (%s)", - __func__, token)); - result = -EINVAL; - goto err_exit; - } - token = strsep(&string, ","); - } - break; - } - case APPHINT_DATA_TYPE_STRING: - { - /* buffer may include '\n', remove it */ - char *string = strsep(&buffer, "\n"); - size_t len = OSStringLength(string); - - if (!len) { - result = -EINVAL; - goto err_exit; - } - - ++len; - - value->STRING = kmalloc(len , GFP_KERNEL); - if (!value->STRING) { - result = -ENOMEM; - goto err_exit; - } - - OSStringLCopy(value->STRING, string, len); - break; - } - default: - result = -EINVAL; - goto err_exit; - } - -err_exit: - return (result < 0) ? result : count; -} - -static PVRSRV_ERROR get_apphint_value_from_action(const struct apphint_action * const action, - union apphint_value * const value, - const PVRSRV_DEVICE_NODE * const psDevNode) -{ - APPHINT_ID id; - APPHINT_DATA_TYPE data_type; - PVRSRV_ERROR result = PVRSRV_OK; - const PVRSRV_DEVICE_NODE *psDevice; - - get_apphint_id_from_action_addr(action, &id); - data_type = param_lookup[id].data_type; - - /* If we've got an entry that is APPHINT_OF_DRIVER_NO_DEVICE we should use - * the higher-level psDevNode value instead. This is the device-node that is - * associated with the original debug_dump request. - * Note: if we're called with psDevNode == APPHINT_OF_DRIVER_NO_DEVICE - * we attempt to use the first registered apphint.devices[0] (if any - * devices have been presented). If we have no devices hooked into the - * apphint mechanism we just return the default value for the AppHint. - */ - if (psDevNode == APPHINT_OF_DRIVER_NO_DEVICE) { - if (action->device == APPHINT_OF_DRIVER_NO_DEVICE) { - if (apphint.num_devices > 0) { - psDevice = apphint.devices[0]; - } else { - PVR_DPF((PVR_DBG_ERROR, - "Uninitialised AppHint device for AppHint index (%d)", - id)); - return PVRSRV_ERROR_RETRY; - } - } else { - psDevice = action->device; - } - } else { - if (action->device == APPHINT_OF_DRIVER_NO_DEVICE) { - psDevice = psDevNode; - } else { - psDevice = action->device; - } - } - - if (action->query.UINT64) { - switch (data_type) { - case APPHINT_DATA_TYPE_UINT64: - result = action->query.UINT64(psDevice, - action->private_data, - &value->UINT64); - break; - - case APPHINT_DATA_TYPE_UINT32: - case APPHINT_DATA_TYPE_UINT32Bitfield: - case APPHINT_DATA_TYPE_UINT32List: - result = action->query.UINT32(psDevice, - action->private_data, - &value->UINT32); - break; - - case APPHINT_DATA_TYPE_BOOL: - result = action->query.BOOL(psDevice, - action->private_data, - &value->BOOL); - break; - - case APPHINT_DATA_TYPE_STRING: - result = action->query.STRING(psDevice, - action->private_data, - &value->STRING); - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: unrecognised data type (%d), index (%d)", - __func__, data_type, id)); - } - } else { - *value = action->stored; - } - - if (PVRSRV_OK != result) { - PVR_DPF((PVR_DBG_ERROR, "%s: failed (%d), index (%d)", __func__, result, id)); - } - - return result; -} - -/* - * apphint_write - write the current AppHint data to a buffer - * - * Returns length written or -errno - */ -static int apphint_write(char *buffer, const size_t size, - const struct apphint_action *a) -{ - const struct apphint_param *hint; - int result = 0; - APPHINT_ID id; - union apphint_value value; - - get_apphint_id_from_action_addr(a, &id); - hint = ¶m_lookup[id]; - - result = get_apphint_value_from_action(a, &value, a->device); - - switch (hint->data_type) { - case APPHINT_DATA_TYPE_UINT64: - result += snprintf(buffer + result, size - result, - "0x%016llx", - value.UINT64); - break; - case APPHINT_DATA_TYPE_UINT32: - result += snprintf(buffer + result, size - result, - "0x%08x", - value.UINT32); - break; - case APPHINT_DATA_TYPE_BOOL: - result += snprintf(buffer + result, size - result, - "%s", - value.BOOL ? "Y" : "N"); - break; - case APPHINT_DATA_TYPE_STRING: - if (value.STRING) { - result += snprintf(buffer + result, size - result, - "%s", - *value.STRING ? value.STRING : "(none)"); - } else { - result += snprintf(buffer + result, size - result, - "(none)"); - } - break; - case APPHINT_DATA_TYPE_UINT32List: - { - struct apphint_lookup *lookup = - (struct apphint_lookup *) hint->data_type_helper; - IMG_UINT32 i; - - if (lookup == (struct apphint_lookup *)NO_PARAM_TABLE) { - result = -EINVAL; - goto err_exit; - } - - for (i = 0; i < hint->helper_size; i++) { - if (lookup[i].value == value.UINT32) { - result += snprintf(buffer + result, - size - result, - "%s", - lookup[i].name); - break; - } - } - break; - } - case APPHINT_DATA_TYPE_UINT32Bitfield: - { - struct apphint_lookup *lookup = - (struct apphint_lookup *) hint->data_type_helper; - IMG_UINT32 i; - - if (lookup == (struct apphint_lookup *)NO_PARAM_TABLE) { - result = -EINVAL; - goto err_exit; - } - - for (i = 0; i < hint->helper_size; i++) { - if (lookup[i].value & value.UINT32) { - result += snprintf(buffer + result, - size - result, - "%s,", - lookup[i].name); - } - } - if (result) { - /* remove any trailing ',' */ - --result; - *(buffer + result) = '\0'; - } else { - result += snprintf(buffer + result, - size - result, "none"); - } - break; - } - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: unrecognised data type (%d), index (%d)", - __func__, hint->data_type, id)); - result = -EINVAL; - } - -err_exit: - return result; -} - -/* -******************************************************************************* - Module parameters initialization - different from debuginfo -******************************************************************************/ -/* - * apphint_kparam_set - Handle an update of a module parameter - * - * Returns 0, or -errno. arg is in kp->arg. - */ -static int apphint_kparam_set(const char *val, const struct kernel_param *kp) -{ - char val_copy[APPHINT_BUFFER_SIZE]; - APPHINT_ID id; - union apphint_value value; - int result; - - /* need to discard const in case of string comparison */ - result = strlcpy(val_copy, val, APPHINT_BUFFER_SIZE); - - get_apphint_id_from_action_addr(kp->arg, &id); - if (result < APPHINT_BUFFER_SIZE) { - result = apphint_read(val_copy, result, id, &value); - if (result >= 0) { - ((struct apphint_action *)kp->arg)->stored = value; - ((struct apphint_action *)kp->arg)->initialised = true; - if (param_lookup[id].data_type == APPHINT_DATA_TYPE_STRING) { - ((struct apphint_action *)kp->arg)->free = true; - } - } - } else { - PVR_DPF((PVR_DBG_ERROR, "%s: String too long", __func__)); - } - return (result > 0) ? 0 : result; -} - -/* - * apphint_kparam_get - handle a read of a module parameter - * - * Returns length written or -errno. Buffer is 4k (ie. be short!) - */ -static int apphint_kparam_get(char *buffer, const struct kernel_param *kp) -{ - return apphint_write(buffer, PAGE_SIZE, kp->arg); -} - -__maybe_unused -static const struct kernel_param_ops apphint_kparam_fops = { - .set = apphint_kparam_set, - .get = apphint_kparam_get, -}; - -/* - * call module_param_cb() for all AppHints listed in APPHINT_LIST_MODPARAM_COMMON + APPHINT_LIST_MODPARAM - * apphint_modparam_class_ ## resolves to apphint_modparam_enable() except for - * AppHint classes that have been disabled. - */ - -#define apphint_modparam_enable(name, number, perm) \ - module_param_cb(name, &apphint_kparam_fops, &apphint.val[number], perm); - -#define X(a, b, c, d, e) \ - apphint_modparam_class_ ##c(a, APPHINT_ID_ ## a, 0444) - APPHINT_LIST_MODPARAM_COMMON - APPHINT_LIST_MODPARAM -#undef X - -/* -******************************************************************************* - Debug Info get (seq file) operations - supporting functions -******************************************************************************/ -static void *apphint_di_start(OSDI_IMPL_ENTRY *s, IMG_UINT64 *pos) -{ - if (*pos == 0) { - /* We want only one entry in the sequence, one call to show() */ - return (void *) 1; - } - - PVR_UNREFERENCED_PARAMETER(s); - - return NULL; -} - -static void apphint_di_stop(OSDI_IMPL_ENTRY *s, void *v) -{ - PVR_UNREFERENCED_PARAMETER(s); - PVR_UNREFERENCED_PARAMETER(v); -} - -static void *apphint_di_next(OSDI_IMPL_ENTRY *s, void *v, IMG_UINT64 *pos) -{ - PVR_UNREFERENCED_PARAMETER(s); - PVR_UNREFERENCED_PARAMETER(v); - PVR_UNREFERENCED_PARAMETER(pos); - return NULL; -} - -static int apphint_di_show(OSDI_IMPL_ENTRY *s, void *v) -{ - IMG_CHAR km_buffer[APPHINT_BUFFER_SIZE]; - int result; - void *private = DIGetPrivData(s); - - PVR_UNREFERENCED_PARAMETER(v); - - result = apphint_write(km_buffer, APPHINT_BUFFER_SIZE, private); - if (result < 0) { - PVR_DPF((PVR_DBG_ERROR, "%s: failure", __func__)); - } else { - /* debuginfo requires a trailing \n, module_params don't */ - result += snprintf(km_buffer + result, - APPHINT_BUFFER_SIZE - result, - "\n"); - DIPuts(s, km_buffer); - } - - /* have to return 0 to see output */ - return (result < 0) ? result : 0; -} - -/* -******************************************************************************* - Debug Info supporting functions -******************************************************************************/ - -/* - * apphint_set - Handle a DI value update - */ -static IMG_INT64 apphint_set(const IMG_CHAR *buffer, IMG_UINT64 count, - IMG_UINT64 *ppos, void *data) -{ - APPHINT_ID id; - union apphint_value value; - struct apphint_action *action = data; - char km_buffer[APPHINT_BUFFER_SIZE]; - int result = 0; - - if (ppos == NULL) - return -EIO; - - if (count >= APPHINT_BUFFER_SIZE) { - PVR_DPF((PVR_DBG_ERROR, "%s: String too long (%" IMG_INT64_FMTSPECd ")", - __func__, count)); - result = -EINVAL; - goto err_exit; - } - - /* apphint_read() modifies the buffer so we need to copy it */ - memcpy(km_buffer, buffer, count); - /* count is larger than real buffer by 1 because DI framework appends - * a '\0' character at the end, but here we're ignoring this */ - count -= 1; - km_buffer[count] = '\0'; - - get_apphint_id_from_action_addr(action, &id); - result = apphint_read(km_buffer, count, id, &value); - if (result >= 0) - apphint_action(value, action); - - *ppos += count; -err_exit: - return result; -} - -/* - * apphint_debuginfo_init - Create the specified debuginfo entries - */ -static int apphint_debuginfo_init(const char *sub_dir, - unsigned int device_num, - unsigned int init_data_size, - const struct apphint_init_data *init_data, - DI_GROUP *parentdir, - DI_GROUP **rootdir, - DI_ENTRY *entry[]) -{ - PVRSRV_ERROR result; - unsigned int i; - unsigned int device_value_offset = device_num * APPHINT_DEBUGINFO_DEVICE_ID_MAX; - const DI_ITERATOR_CB iterator = { - .pfnStart = apphint_di_start, .pfnStop = apphint_di_stop, - .pfnNext = apphint_di_next, .pfnShow = apphint_di_show, - .pfnWrite = apphint_set, .ui32WriteLenMax = APPHINT_BUFFER_SIZE - }; - - if (*rootdir) { - PVR_DPF((PVR_DBG_WARNING, - "AppHint DebugFS already created, skipping")); - result = -EEXIST; - goto err_exit; - } - - result = DICreateGroup(sub_dir, parentdir, rootdir); - if (result != PVRSRV_OK) { - PVR_DPF((PVR_DBG_WARNING, - "Failed to create \"%s\" DebugFS directory.", sub_dir)); - goto err_exit; - } - - for (i = 0; i < init_data_size; i++) { - if (!class_state[init_data[i].class].enabled) - continue; - - result = DICreateEntry(init_data[i].name, - *rootdir, - &iterator, - (void *) &apphint.val[init_data[i].id + device_value_offset], - DI_ENTRY_TYPE_GENERIC, - &entry[i]); - if (result != PVRSRV_OK) { - PVR_DPF((PVR_DBG_WARNING, - "Failed to create \"%s/%s\" DebugFS entry.", - sub_dir, init_data[i].name)); - } - } - - return 0; - -err_exit: - return result; -} - -/* - * apphint_debuginfo_deinit- destroy the debuginfo entries - */ -static void apphint_debuginfo_deinit(unsigned int num_entries, - DI_GROUP **rootdir, - DI_ENTRY *entry[]) -{ - unsigned int i; - - for (i = 0; i < num_entries; i++) { - if (entry[i]) { - DIDestroyEntry(entry[i]); - } - } - - if (*rootdir) { - DIDestroyGroup(*rootdir); - *rootdir = NULL; - } -} - -/* -******************************************************************************* - AppHint status dump implementation -******************************************************************************/ -#if defined(PDUMP) -static void __attribute__ ((format (printf, 2, 3))) -apphint_pdump_values(void *pvDeviceNode, - const IMG_CHAR *format, ...) -{ - char km_buffer[APPHINT_BUFFER_SIZE]; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; - va_list ap; - - va_start(ap, format); - (void)vsnprintf(km_buffer, APPHINT_BUFFER_SIZE, format, ap); - va_end(ap); - - /* ui32CommentSize set to 0 here as function does not make use of the value. */ - PDumpCommentKM(NULL, (PVRSRV_DEVICE_NODE*)pvDeviceNode, 0, km_buffer, ui32Flags); -} -#endif - -static IMG_BOOL is_apphint_value_equal(const APPHINT_DATA_TYPE data_type, - const union apphint_value * const left, - const union apphint_value * const right) -{ - switch (data_type) { - case APPHINT_DATA_TYPE_UINT64: - return left->UINT64 == right->UINT64; - case APPHINT_DATA_TYPE_UINT32: - case APPHINT_DATA_TYPE_UINT32List: - case APPHINT_DATA_TYPE_UINT32Bitfield: - return left->UINT32 == right->UINT32; - case APPHINT_DATA_TYPE_BOOL: - return left->BOOL == right->BOOL; - case APPHINT_DATA_TYPE_STRING: - return (OSStringNCompare(left->STRING, right->STRING, OSStringLength(right->STRING) + 1) == 0 ? IMG_TRUE : IMG_FALSE); - default: - PVR_DPF((PVR_DBG_WARNING, "%s: unhandled data type (%d)", __func__, data_type)); - return IMG_FALSE; - } -} - -static void apphint_dump_values(const char *group_name, - int device_num, - const struct apphint_init_data *group_data, - int group_size, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - bool list_all, - PVRSRV_DEVICE_NODE *psDevNode) -{ - int i, result; - int device_value_offset = device_num * APPHINT_DEBUGINFO_DEVICE_ID_MAX; - char km_buffer[APPHINT_BUFFER_SIZE]; - char count = 0; - - PVR_DUMPDEBUG_LOG(" %s", group_name); - for (i = 0; i < group_size; i++) - { - IMG_UINT32 id = group_data[i].id; - APPHINT_DATA_TYPE data_type = param_lookup[id].data_type; - const struct apphint_action *action = &apphint.val[id + device_value_offset]; - union apphint_value value; - - result = get_apphint_value_from_action(action, &value, psDevNode); - - if (PVRSRV_OK != result) { - continue; - } - - /* List only apphints with non-default values */ - if (!list_all && - is_apphint_value_equal(data_type, &value, &group_data[i].default_value)) { - continue; - } - - result = apphint_write(km_buffer, APPHINT_BUFFER_SIZE, action); - count++; - - if (result <= 0) { - PVR_DUMPDEBUG_LOG(" %s: ", - group_data[i].name); - } else { - PVR_DUMPDEBUG_LOG(" %s: %s", - group_data[i].name, km_buffer); - } - } - - if (count == 0) { - PVR_DUMPDEBUG_LOG(" none"); - } -} - -/* - * Callback for debug dump - */ -static void apphint_dump_state(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - int i, result; - char km_buffer[APPHINT_BUFFER_SIZE]; - PVRSRV_DEVICE_NODE *device = (PVRSRV_DEVICE_NODE *)hDebugRequestHandle; - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH)) { - PVR_DUMPDEBUG_LOG("------[ AppHint Settings ]------"); - - apphint_dump_values("Build Vars", 0, - init_data_buildvar, ARRAY_SIZE(init_data_buildvar), - pfnDumpDebugPrintf, pvDumpDebugFile, true, device); - - apphint_dump_values("Module Params", 0, - init_data_modparam, ARRAY_SIZE(init_data_modparam), - pfnDumpDebugPrintf, pvDumpDebugFile, false, device); - - apphint_dump_values("Debug Info Params", 0, - init_data_debuginfo, ARRAY_SIZE(init_data_debuginfo), - pfnDumpDebugPrintf, pvDumpDebugFile, false, device); - - for (i = 0; i < APPHINT_DEVICES_MAX; i++) { - if (!apphint.devices[i] - || (device && device != apphint.devices[i])) - continue; - - result = snprintf(km_buffer, - APPHINT_BUFFER_SIZE, - "Debug Info Params Device ID: %d", - i); - if (0 > result) - continue; - - apphint_dump_values(km_buffer, i, - init_data_debuginfo_device, - ARRAY_SIZE(init_data_debuginfo_device), - pfnDumpDebugPrintf, - pvDumpDebugFile, - false, device); - } - } -} - -/* -******************************************************************************* - Public interface -******************************************************************************/ -int pvr_apphint_init(void) -{ - int result, i; - - if (apphint.initialized) { - result = -EEXIST; - goto err_out; - } - - for (i = 0; i < APPHINT_DEVICES_MAX; i++) - apphint.devices[i] = NULL; - - /* create workqueue with strict execution ordering to ensure no - * race conditions when setting/updating apphints from different - * contexts - */ - apphint.workqueue = alloc_workqueue("apphint_workqueue", - WQ_UNBOUND | WQ_FREEZABLE, 1); - if (!apphint.workqueue) { - result = -ENOMEM; - goto err_out; - } - - result = apphint_debuginfo_init("apphint", 0, - ARRAY_SIZE(init_data_debuginfo), init_data_debuginfo, - NULL, - &apphint.debuginfo_rootdir, apphint.debuginfo_entry); - if (0 != result) - goto err_out; - - result = apphint_debuginfo_init("buildvar", 0, - ARRAY_SIZE(init_data_buildvar), init_data_buildvar, - NULL, - &apphint.buildvar_rootdir, apphint.buildvar_entry); - - apphint.initialized = 1; - -err_out: - return result; -} - -int pvr_apphint_device_register(PVRSRV_DEVICE_NODE *device) -{ - int result, i; - char device_num[APPHINT_BUFFER_SIZE]; - unsigned int device_value_offset; - - if (!apphint.initialized) { - result = -EAGAIN; - goto err_out; - } - - if (apphint.num_devices+1 > APPHINT_DEVICES_MAX) { - result = -EMFILE; - goto err_out; - } - - result = snprintf(device_num, APPHINT_BUFFER_SIZE, "%u", apphint.num_devices); - if (result < 0) { - PVR_DPF((PVR_DBG_WARNING, - "snprintf failed (%d)", result)); - result = -EINVAL; - goto err_out; - } - - /* Set the default values for the new device */ - device_value_offset = apphint.num_devices * APPHINT_DEBUGINFO_DEVICE_ID_MAX; - for (i = 0; i < APPHINT_DEBUGINFO_DEVICE_ID_MAX; i++) { - apphint.val[init_data_debuginfo_device[i].id + device_value_offset].stored - = init_data_debuginfo_device[i].default_value; - } - - /* Set value of an apphint if mapping to module param exists for it - * and this module parameter has been initialised */ - for (i = 0; i < ARRAY_SIZE(init_data_debuginfo_device_to_modparams); i++) { - const struct apphint_init_data_mapping *mapping = - &init_data_debuginfo_device_to_modparams[i]; - const struct apphint_action *modparam_action = - &apphint.val[mapping->modparam_apphint_id]; - struct apphint_action *device_action = - &apphint.val[mapping->device_apphint_id + device_value_offset]; - - /* Set only if the module parameter was explicitly set during the module - * load. */ - if (modparam_action->initialised) { - device_action->stored = modparam_action->stored; - } - } - - result = apphint_debuginfo_init(device_num, apphint.num_devices, - ARRAY_SIZE(init_data_debuginfo_device), - init_data_debuginfo_device, - apphint.debuginfo_rootdir, - &apphint.debuginfo_device_rootdir[apphint.num_devices], - apphint.debuginfo_device_entry[apphint.num_devices]); - if (0 != result) - goto err_out; - - apphint.devices[apphint.num_devices] = device; - apphint.num_devices++; - - (void)SOPvrDbgRequestNotifyRegister( - &device->hAppHintDbgReqNotify, - device, - apphint_dump_state, - DEBUG_REQUEST_APPHINT, - device); - -err_out: - return result; -} - -void pvr_apphint_device_unregister(PVRSRV_DEVICE_NODE *device) -{ - int i; - - if (!apphint.initialized) - return; - - /* find the device */ - for (i = 0; i < APPHINT_DEVICES_MAX; i++) { - if (apphint.devices[i] == device) - break; - } - - if (APPHINT_DEVICES_MAX == i) - return; - - if (device->hAppHintDbgReqNotify) { - (void)SOPvrDbgRequestNotifyUnregister( - device->hAppHintDbgReqNotify); - device->hAppHintDbgReqNotify = NULL; - } - - apphint_debuginfo_deinit(APPHINT_DEBUGINFO_DEVICE_ID_MAX, - &apphint.debuginfo_device_rootdir[i], - apphint.debuginfo_device_entry[i]); - - apphint.devices[i] = NULL; - - WARN_ON(apphint.num_devices==0); - apphint.num_devices--; -} - -void pvr_apphint_deinit(void) -{ - int i; - - if (!apphint.initialized) - return; - - /* remove any remaining device data */ - for (i = 0; apphint.num_devices && i < APPHINT_DEVICES_MAX; i++) { - if (apphint.devices[i]) - pvr_apphint_device_unregister(apphint.devices[i]); - } - - /* free all alloc'd string apphints and set to NULL */ - for (i = 0; i < ARRAY_SIZE(apphint.val); i++) { - if (apphint.val[i].free && apphint.val[i].stored.STRING) { - kfree(apphint.val[i].stored.STRING); - apphint.val[i].stored.STRING = NULL; - apphint.val[i].free = false; - } - } - - apphint_debuginfo_deinit(APPHINT_DEBUGINFO_ID_MAX, - &apphint.debuginfo_rootdir, apphint.debuginfo_entry); - apphint_debuginfo_deinit(APPHINT_BUILDVAR_ID_MAX, - &apphint.buildvar_rootdir, apphint.buildvar_entry); - - destroy_workqueue(apphint.workqueue); - - apphint.initialized = 0; -} - -void pvr_apphint_dump_state(PVRSRV_DEVICE_NODE *device) -{ -#if defined(PDUMP) - /* NB. apphint_pdump_values() is the pfnDumpDebugPrintf - * function used when PDUMP is defined. - * apphintpdump_values() calls PDumpCommentKM(), which - * requires the device but as it is only called as a - * DUMPDEBUG_PRINTF_FUNC it is only passed pvDumpDebugFile - * (which happens to be the 4th parameter in the call to - * apphint_dump_state() below). - * Hence, we also need to pass device in the 4th parameter. - */ - apphint_dump_state(device, DEBUG_REQUEST_VERBOSITY_HIGH, - apphint_pdump_values, device); -#endif - apphint_dump_state(device, DEBUG_REQUEST_VERBOSITY_HIGH, - NULL, NULL); -} - - -int pvr_apphint_get_uint64(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT64 *pVal) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if (ue < APPHINT_ID_MAX) { - if ((int)ue > APPHINT_DEBUGINFO_DEVICE_ID_OFFSET) // From this point, we're in the device apphints - { - *pVal = apphint.val[ue + device_offset].stored.UINT64; - error = 0; - } - else - { - *pVal = apphint.val[ue].stored.UINT64; - error = 0; - } - } - return error; -} - -int pvr_apphint_get_uint32(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT32 *pVal) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if (ue < APPHINT_ID_MAX) { - if ((int)ue > APPHINT_DEBUGINFO_DEVICE_ID_OFFSET) // From this point, we're in the device apphints - { - *pVal = apphint.val[ue + device_offset].stored.UINT32; - error = 0; - } - else - { - *pVal = apphint.val[ue].stored.UINT32; - error = 0; - } - } - return error; -} - -int pvr_apphint_get_bool(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_BOOL *pVal) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if (ue < APPHINT_ID_MAX) { - if ((int)ue > APPHINT_DEBUGINFO_DEVICE_ID_OFFSET) // From this point, we're in the device apphints - { - *pVal = apphint.val[ue + device_offset].stored.BOOL; - error = 0; - } - else - { - *pVal = apphint.val[ue].stored.BOOL; - error = 0; - } - } - return error; -} - -int pvr_apphint_get_string(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if (ue < APPHINT_ID_MAX && apphint.val[ue].stored.STRING) { - if ((int)ue > APPHINT_DEBUGINFO_DEVICE_ID_OFFSET) // From this point, we're in the device apphints - { - if (OSStringLCopy(pBuffer, apphint.val[ue + device_offset].stored.STRING, size) < size) { - error = 0; - } - } - else - { - if (OSStringLCopy(pBuffer, apphint.val[ue].stored.STRING, size) < size) { - error = 0; - } - } - } - return error; -} - -int pvr_apphint_set_uint64(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT64 Val) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if ((ue < APPHINT_ID_MAX) && - (param_lookup[ue].data_type == APPHINT_DATA_TYPE_UINT64)) { - - if (apphint.val[ue + device_offset].set.UINT64) { - apphint.val[ue + device_offset].set.UINT64(apphint.val[ue + device_offset].device, - apphint.val[ue + device_offset].private_data, - Val); - } else { - apphint.val[ue + device_offset].stored.UINT64 = Val; - } - apphint.val[ue].device = device; - error = 0; - } - - return error; -} - -int pvr_apphint_set_uint32(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT32 Val) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if ((ue < APPHINT_ID_MAX) && - (param_lookup[ue].data_type == APPHINT_DATA_TYPE_UINT32)) { - - if (apphint.val[ue + device_offset].set.UINT32) { - apphint.val[ue + device_offset].set.UINT32(apphint.val[ue + device_offset].device, - apphint.val[ue + device_offset].private_data, - Val); - } else { - apphint.val[ue + device_offset].stored.UINT32 = Val; - } - apphint.val[ue].device = device; - error = 0; - } - - return error; -} - -int pvr_apphint_set_bool(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_BOOL Val) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if ((ue < APPHINT_ID_MAX) && - (param_lookup[ue].data_type == APPHINT_DATA_TYPE_BOOL)) { - - error = 0; - if (apphint.val[ue + device_offset].set.BOOL) { - apphint.val[ue + device_offset].set.BOOL(apphint.val[ue + device_offset].device, - apphint.val[ue + device_offset].private_data, - Val); - } else { - apphint.val[ue + device_offset].stored.BOOL = Val; - } - apphint.val[ue].device = device; - } - - return error; -} - -int pvr_apphint_set_string(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size) -{ - int error = -ERANGE; - int device_offset = (device != NULL) ? device->sDevId.ui32InternalID * APPHINT_DEBUGINFO_DEVICE_ID_MAX : 0; - - if ((ue < APPHINT_ID_MAX) && - ((param_lookup[ue].data_type == APPHINT_DATA_TYPE_STRING) && - apphint.val[ue + device_offset].stored.STRING)) { - - if (apphint.val[ue + device_offset].set.STRING) { - error = apphint.val[ue + device_offset].set.STRING(apphint.val[ue + device_offset].device, - apphint.val[ue + device_offset].private_data, - pBuffer); - } else { - if (strlcpy(apphint.val[ue + device_offset].stored.STRING, pBuffer, size) < size) { - error = 0; - } - } - apphint.val[ue].device = device; - } - - return error; -} - -void pvr_apphint_register_handlers_uint64(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data) -{ - int device_value_offset; - - PVR_DPF((APPHINT_DPF_LEVEL, "%s(%d, %p, %p, %p, %p)", - __func__, id, query, set, device, private_data)); - - if (id >= APPHINT_ID_MAX) { - PVR_DPF((PVR_DBG_ERROR, - "%s: AppHint ID (%d) is out of range, max (%d)", - __func__, id, APPHINT_ID_MAX-1)); - return; - } - - get_value_offset_from_device(device, &device_value_offset, id); - - switch (param_lookup[id].data_type) { - case APPHINT_DATA_TYPE_UINT64: - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Does not match AppHint data type for ID (%d)", - __func__, id)); - return; - } - - apphint.val[id + device_value_offset] = (struct apphint_action){ - .query.UINT64 = query, - .set.UINT64 = set, - .device = device, - .private_data = private_data, - .stored = apphint.val[id + device_value_offset].stored - }; -} - -void pvr_apphint_register_handlers_uint32(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data) -{ - int device_value_offset; - - PVR_DPF((APPHINT_DPF_LEVEL, "%s(%d, %p, %p, %p, %p)", - __func__, id, query, set, device, private_data)); - - if (id >= APPHINT_ID_MAX) { - PVR_DPF((PVR_DBG_ERROR, - "%s: AppHint ID (%d) is out of range, max (%d)", - __func__, id, APPHINT_ID_MAX-1)); - return; - } - - get_value_offset_from_device(device, &device_value_offset, id); - - switch (param_lookup[id].data_type) { - case APPHINT_DATA_TYPE_UINT32: - case APPHINT_DATA_TYPE_UINT32Bitfield: - case APPHINT_DATA_TYPE_UINT32List: - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Does not match AppHint data type for ID (%d)", - __func__, id)); - return; - } - - apphint.val[id + device_value_offset] = (struct apphint_action){ - .query.UINT32 = query, - .set.UINT32 = set, - .device = device, - .private_data = private_data, - .stored = apphint.val[id + device_value_offset].stored - }; -} - -void pvr_apphint_register_handlers_bool(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data) -{ - int device_value_offset; - - PVR_DPF((APPHINT_DPF_LEVEL, "%s(%d, %p, %p, %p, %p)", - __func__, id, query, set, device, private_data)); - - if (id >= APPHINT_ID_MAX) { - PVR_DPF((PVR_DBG_ERROR, - "%s: AppHint ID (%d) is out of range, max (%d)", - __func__, id, APPHINT_ID_MAX-1)); - return; - } - - get_value_offset_from_device(device, &device_value_offset, id); - - switch (param_lookup[id].data_type) { - case APPHINT_DATA_TYPE_BOOL: - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Does not match AppHint data type for ID (%d)", - __func__, id)); - return; - } - - apphint.val[id + device_value_offset] = (struct apphint_action){ - .query.BOOL = query, - .set.BOOL = set, - .device = device, - .private_data = private_data, - .stored = apphint.val[id + device_value_offset].stored - }; -} - -void pvr_apphint_register_handlers_string(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data) -{ - int device_value_offset; - - PVR_DPF((APPHINT_DPF_LEVEL, "%s(%d, %p, %p, %p, %p)", - __func__, id, query, set, device, private_data)); - - if (id >= APPHINT_ID_MAX) { - PVR_DPF((PVR_DBG_ERROR, - "%s: AppHint ID (%d) is out of range, max (%d)", - __func__, id, APPHINT_ID_MAX-1)); - return; - } - - get_value_offset_from_device(device, &device_value_offset, id); - - switch (param_lookup[id].data_type) { - case APPHINT_DATA_TYPE_STRING: - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Does not match AppHint data type for ID (%d)", - __func__, id)); - return; - } - - apphint.val[id + device_value_offset] = (struct apphint_action){ - .query.STRING = query, - .set.STRING = set, - .device = device, - .private_data = private_data, - .stored = apphint.val[id + device_value_offset].stored - }; -} - -/* EOF */ diff --git a/drivers/gpu/drm/img-rogue/1.17/km_apphint.h b/drivers/gpu/drm/img-rogue/1.17/km_apphint.h deleted file mode 100644 index 71e2ce94000a9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km_apphint.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************/ /*! -@File km_apphint.h -@Title Apphint internal header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Linux kernel AppHint control -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 KM_APPHINT_H -#define KM_APPHINT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "pvrsrv_apphint.h" -#include "km_apphint_defs.h" -#include "device.h" - -int pvr_apphint_init(void); -void pvr_apphint_deinit(void); -int pvr_apphint_device_register(PVRSRV_DEVICE_NODE *device); -void pvr_apphint_device_unregister(PVRSRV_DEVICE_NODE *device); -void pvr_apphint_dump_state(PVRSRV_DEVICE_NODE *device); - -int pvr_apphint_get_uint64(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT64 *pVal); -int pvr_apphint_get_uint32(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT32 *pVal); -int pvr_apphint_get_bool(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_BOOL *pVal); -int pvr_apphint_get_string(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size); - -int pvr_apphint_set_uint64(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT64 Val); -int pvr_apphint_set_uint32(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_UINT32 Val); -int pvr_apphint_set_bool(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_BOOL Val); -int pvr_apphint_set_string(PVRSRV_DEVICE_NODE *device, APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size); - -void pvr_apphint_register_handlers_uint64(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value), - const PVRSRV_DEVICE_NODE *device, - const void * private_data); -void pvr_apphint_register_handlers_uint32(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data); -void pvr_apphint_register_handlers_bool(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data); -void pvr_apphint_register_handlers_string(APPHINT_ID id, - PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value), - PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value), - const PVRSRV_DEVICE_NODE *device, - const void *private_data); - -#if defined(__cplusplus) -} -#endif -#endif /* KM_APPHINT_H */ - -/****************************************************************************** - End of file (km_apphint.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs.h b/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs.h deleted file mode 100644 index 16fc36b4e0a1e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs.h +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services AppHint definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "km_apphint_defs_common.h" - -#ifndef KM_APPHINT_DEFS_H -#define KM_APPHINT_DEFS_H - -/* NB: The 'DEVICE' AppHints must be last in this list as they will be - * duplicated in the case of a driver supporting multiple devices - */ -#define APPHINT_LIST_ALL \ - APPHINT_LIST_BUILDVAR_COMMON \ - APPHINT_LIST_BUILDVAR \ - APPHINT_LIST_MODPARAM_COMMON \ - APPHINT_LIST_MODPARAM \ - APPHINT_LIST_DEBUGINFO_COMMON \ - APPHINT_LIST_DEBUGINFO \ - APPHINT_LIST_DEBUGINFO_DEVICE_COMMON \ - APPHINT_LIST_DEBUGINFO_DEVICE - - -/* -******************************************************************************* - Build variables (rogue-specific) - All of these should be configurable only through the 'default' value -******************************************************************************/ -#define APPHINT_LIST_BUILDVAR - -/* -******************************************************************************* - Module parameters (rogue-specific) -******************************************************************************/ -#define APPHINT_LIST_MODPARAM \ -/* name, type, class, default, helper, */ \ -X(EnableCDMKillingRandMode, BOOL, VALIDATION, PVRSRV_APPHINT_ENABLECDMKILLINGRANDMODE, NO_PARAM_TABLE ) \ -\ -X(HWPerfDisableCustomCounterFilter, BOOL, VALIDATION, PVRSRV_APPHINT_HWPERFDISABLECUSTOMCOUNTERFILTER, NO_PARAM_TABLE ) \ -X(ValidateSOCUSCTimer, BOOL, VALIDATION, PVRSRV_APPHINT_VALIDATESOCUSCTIMERS, NO_PARAM_TABLE ) \ -X(ECCRAMErrInj, UINT32, VALIDATION, 0, NO_PARAM_TABLE ) \ -\ -X(TFBCCompressionControlGroup, UINT32, VALIDATION, PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLGROUP, NO_PARAM_TABLE ) \ -X(TFBCCompressionControlScheme, UINT32, VALIDATION, PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLSCHEME, NO_PARAM_TABLE ) \ -X(TFBCCompressionControlYUVFormat, BOOL, VALIDATION, 0, NO_PARAM_TABLE ) \ - -/* -******************************************************************************* - Debugfs parameters (rogue-specific) - driver configuration -******************************************************************************/ -#define APPHINT_LIST_DEBUGINFO \ -/* name, type, class, default, helper, */ \ - -/* -******************************************************************************* - Debugfs parameters (rogue-specific) - device configuration -******************************************************************************/ -#define APPHINT_LIST_DEBUGINFO_DEVICE \ -/* name, type, class, default, helper, */ \ - -/* -******************************************************************************* - Mapping between debugfs parameters and module parameters. - This mapping is used to initialise device specific apphints from module - parameters. Each entry in this table will provide a default value to all - devices (i.e. if there is more than one device each device's value will - be initialised). -******************************************************************************/ -#define APPHINT_LIST_DEBUIGINFO_DEVICE_X_MODPARAM_INIT \ -/* debuginfo device apphint name modparam name */ - -/* -******************************************************************************* - - Table generated enums - -******************************************************************************/ -/* Unique ID for all AppHints */ -typedef enum { -#define X(a, b, c, d, e) APPHINT_ID_ ## a, - APPHINT_LIST_ALL -#undef X - APPHINT_ID_MAX -} APPHINT_ID; - -/* ID for build variable Apphints - used for build variable only structures */ -typedef enum { -#define X(a, b, c, d, e) APPHINT_BUILDVAR_ID_ ## a, - APPHINT_LIST_BUILDVAR_COMMON - APPHINT_LIST_BUILDVAR -#undef X - APPHINT_BUILDVAR_ID_MAX -} APPHINT_BUILDVAR_ID; - -/* ID for Modparam Apphints - used for modparam only structures */ -typedef enum { -#define X(a, b, c, d, e) APPHINT_MODPARAM_ID_ ## a, - APPHINT_LIST_MODPARAM_COMMON - APPHINT_LIST_MODPARAM -#undef X - APPHINT_MODPARAM_ID_MAX -} APPHINT_MODPARAM_ID; - -/* ID for Debugfs Apphints - used for debugfs only structures */ -typedef enum { -#define X(a, b, c, d, e) APPHINT_DEBUGINFO_ID_ ## a, - APPHINT_LIST_DEBUGINFO_COMMON - APPHINT_LIST_DEBUGINFO -#undef X - APPHINT_DEBUGINFO_ID_MAX -} APPHINT_DEBUGINFO_ID; - -/* ID for Debugfs Device Apphints - used for debugfs device only structures */ -typedef enum { -#define X(a, b, c, d, e) APPHINT_DEBUGINFO_DEVICE_ID_ ## a, - APPHINT_LIST_DEBUGINFO_DEVICE_COMMON - APPHINT_LIST_DEBUGINFO_DEVICE -#undef X - APPHINT_DEBUGINFO_DEVICE_ID_MAX -} APPHINT_DEBUGINFO_DEVICE_ID; - -#endif /* KM_APPHINT_DEFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs_common.h b/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs_common.h deleted file mode 100644 index 987d37c10c424..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/km_apphint_defs_common.h +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services AppHint definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 KM_APPHINT_DEFS_COMMON_H -#define KM_APPHINT_DEFS_COMMON_H - -/* -******************************************************************************* - Build variables - All of these should be configurable only through the 'default' value -******************************************************************************/ -#define APPHINT_LIST_BUILDVAR_COMMON \ -/* name, type, class, default, helper, */ \ -X(EnableTrustedDeviceAceConfig, BOOL, GPUVIRT_VAL, PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG, NO_PARAM_TABLE ) \ -X(CleanupThreadPriority, UINT32, NEVER, PVRSRV_APPHINT_CLEANUPTHREADPRIORITY, NO_PARAM_TABLE ) \ -X(WatchdogThreadPriority, UINT32, NEVER, PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY, NO_PARAM_TABLE ) \ -X(HWPerfClientBufferSize, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTBUFFERSIZE, NO_PARAM_TABLE ) \ - -/* -******************************************************************************* - Module parameters -******************************************************************************/ -#define APPHINT_LIST_MODPARAM_COMMON \ -/* name, type, class, default, helper, */ \ -X(GeneralNon4KHeapPageSize, UINT32, ALWAYS, PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE, NO_PARAM_TABLE ) \ -\ -X(EnableSignatureChecks, BOOL, PDUMP, PVRSRV_APPHINT_ENABLESIGNATURECHECKS, NO_PARAM_TABLE ) \ -X(SignatureChecksBufSize, UINT32, PDUMP, PVRSRV_APPHINT_SIGNATURECHECKSBUFSIZE, NO_PARAM_TABLE ) \ -\ -X(DisableClockGating, BOOL, ALWAYS, PVRSRV_APPHINT_DISABLECLOCKGATING, NO_PARAM_TABLE ) \ -X(DisableDMOverlap, BOOL, ALWAYS, PVRSRV_APPHINT_DISABLEDMOVERLAP, NO_PARAM_TABLE ) \ -\ -X(EnableRandomContextSwitch, BOOL, VALIDATION, PVRSRV_APPHINT_ENABLERANDOMCONTEXTSWITCH, NO_PARAM_TABLE ) \ -X(EnableSoftResetContextSwitch, BOOL, ALWAYS, PVRSRV_APPHINT_ENABLESOFTRESETCNTEXTSWITCH, NO_PARAM_TABLE ) \ -X(EnableFWContextSwitch, UINT32, ALWAYS, PVRSRV_APPHINT_ENABLEFWCONTEXTSWITCH, NO_PARAM_TABLE ) \ -X(FWContextSwitchProfile, UINT32, VALIDATION, PVRSRV_APPHINT_FWCONTEXTSWITCHPROFILE, NO_PARAM_TABLE ) \ -\ -X(EnableRDPowerIsland, UINT32, ALWAYS, PVRSRV_APPHINT_ENABLERDPOWERISLAND, NO_PARAM_TABLE ) \ -\ -X(DriverMode, UINT32, ALWAYS, PVRSRV_APPHINT_DRIVERMODE, NO_PARAM_TABLE ) \ -\ -X(FirmwarePerf, UINT32, VALIDATION, PVRSRV_APPHINT_FIRMWAREPERF, NO_PARAM_TABLE ) \ -\ -X(HWPerfFWBufSizeInKB, UINT32, VALIDATION, PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB, NO_PARAM_TABLE ) \ -X(HWPerfHostBufSizeInKB, UINT32, VALIDATION, PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB, NO_PARAM_TABLE ) \ -X(HWPerfHostThreadTimeoutInMS, UINT32, VALIDATION, PVRSRV_APPHINT_HWPERFHOSTTHREADTIMEOUTINMS, NO_PARAM_TABLE ) \ -\ -X(JonesDisableMask, UINT32, VALIDATION, PVRSRV_APPHINT_JONESDISABLEMASK, NO_PARAM_TABLE ) \ -X(NewFilteringMode, BOOL, VALIDATION, PVRSRV_APPHINT_NEWFILTERINGMODE, NO_PARAM_TABLE ) \ -X(TruncateMode, UINT32, VALIDATION, PVRSRV_APPHINT_TRUNCATEMODE, NO_PARAM_TABLE ) \ -X(EmuMaxFreq, UINT32, ALWAYS, PVRSRV_APPHINT_EMUMAXFREQ, NO_PARAM_TABLE ) \ -X(GPIOValidationMode, UINT32, VALIDATION, PVRSRV_APPHINT_GPIOVALIDATIONMODE, NO_PARAM_TABLE ) \ -X(RGXBVNC, STRING, ALWAYS, PVRSRV_APPHINT_RGXBVNC, NO_PARAM_TABLE ) \ -\ -X(FWContextSwitchCrossDM, UINT32, ALWAYS, 0, NO_PARAM_TABLE ) \ -X(ValidateIrq, BOOL, VALIDATION, PVRSRV_APPHINT_VALIDATEIRQ, NO_PARAM_TABLE ) \ -\ -X(TPUTrilinearFracMaskPDM, UINT32, VALIDATION, 0xF, NO_PARAM_TABLE ) \ -X(TPUTrilinearFracMaskVDM, UINT32, VALIDATION, 0xF, NO_PARAM_TABLE ) \ -X(TPUTrilinearFracMaskCDM, UINT32, VALIDATION, 0xF, NO_PARAM_TABLE ) \ -X(TPUTrilinearFracMaskTDM, UINT32, VALIDATION, 0xF, NO_PARAM_TABLE ) \ -X(HTBufferSizeInKB, UINT32, ALWAYS, PVRSRV_APPHINT_HTBUFFERSIZE, NO_PARAM_TABLE ) \ -X(FWTraceBufSizeInDWords, UINT32, ALWAYS, PVRSRV_APPHINT_FWTRACEBUFSIZEINDWORDS, NO_PARAM_TABLE ) \ -\ -X(EnablePageFaultDebug, BOOL, ALWAYS, PVRSRV_APPHINT_ENABLEPAGEFAULTDEBUG, NO_PARAM_TABLE ) \ -X(EnableFullSyncTracking, BOOL, ALWAYS, PVRSRV_APPHINT_ENABLEFULLSYNCTRACKING, NO_PARAM_TABLE ) \ -X(IgnoreHWReportedBVNC, BOOL, ALWAYS, PVRSRV_APPHINT_IGNOREHWREPORTEDBVNC, NO_PARAM_TABLE ) \ -\ -X(PhysMemTestPasses, UINT32, ALWAYS, PVRSRV_APPHINT_PHYSMEMTESTPASSES, NO_PARAM_TABLE ) \ -\ -X(FBCDCVersionOverride, UINT32, VALIDATION, PVRSRV_APPHINT_FBCDCVERSIONOVERRIDE, NO_PARAM_TABLE ) \ -X(TestSLRInterval, UINT32, VALIDATION, PVRSRV_APPHINT_TESTSLRINTERVAL, NO_PARAM_TABLE ) \ -X(EnablePollOnChecksumErrorStatus, UINT32, VALIDATION, 0, NO_PARAM_TABLE ) \ -X(RiscvDmiTest, BOOL, VALIDATION, PVRSRV_APPHINT_RISCVDMITEST, NO_PARAM_TABLE ) \ -X(DevMemFWHeapPolicy, UINT32, ALWAYS, PVRSRV_APPHINT_FIRMWARE_HEAP_POLICY, NO_PARAM_TABLE ) \ -\ -X(EnableAPMAll, UINT32, VALIDATION, PVRSRV_APPHINT_ENABLEAPM, NO_PARAM_TABLE ) \ -X(KernelCCBSizeLog2, UINT32, VALIDATION, PVRSRV_APPHINT_KCCB_SIZE_LOG2, NO_PARAM_TABLE ) - -/* -******************************************************************************* - Debugfs parameters - driver configuration -******************************************************************************/ -#define APPHINT_LIST_DEBUGINFO_COMMON \ -/* name, type, class, default, helper, */ \ -X(EnableHTBLogGroup, UINT32Bitfield, ALWAYS, PVRSRV_APPHINT_ENABLEHTBLOGGROUP, htb_loggroup_tbl ) \ -X(HTBOperationMode, UINT32List, ALWAYS, PVRSRV_APPHINT_HTBOPERATIONMODE, htb_opmode_tbl ) \ -X(EnableFTraceGPU, BOOL, ALWAYS, PVRSRV_APPHINT_ENABLEFTRACEGPU, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_Services, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_SERVICES, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_EGL, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_EGL, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_OpenGLES, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGLES, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_OpenCL, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENCL, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_Vulkan, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_VULKAN, NO_PARAM_TABLE ) \ -X(HWPerfClientFilter_OpenGL, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGL, NO_PARAM_TABLE ) \ -X(CacheOpConfig, UINT32, ALWAYS, PVRSRV_APPHINT_CACHEOPCONFIG, NO_PARAM_TABLE ) \ -X(CacheOpUMKMThresholdSize, UINT32, ALWAYS, PVRSRV_APPHINT_CACHEOPUMKMHRESHOLDSIZE, NO_PARAM_TABLE ) \ - -/* -******************************************************************************* - Debugfs parameters - device configuration -******************************************************************************/ -#define APPHINT_LIST_DEBUGINFO_DEVICE_COMMON \ -/* name, type, class, default, helper, */ \ -/* Device Firmware config */\ -X(AssertOnHWRTrigger, BOOL, ALWAYS, APPHNT_BLDVAR_ASSERTONHWRTRIGGER, NO_PARAM_TABLE ) \ -X(AssertOutOfMemory, BOOL, ALWAYS, PVRSRV_APPHINT_ASSERTOUTOFMEMORY, NO_PARAM_TABLE ) \ -X(CheckMList, BOOL, ALWAYS, PVRSRV_APPHINT_CHECKMLIST, NO_PARAM_TABLE ) \ -X(EnableLogGroup, UINT32Bitfield, ALWAYS, PVRSRV_APPHINT_ENABLELOGGROUP, fwt_loggroup_tbl ) \ -X(FirmwareLogType, UINT32List, ALWAYS, PVRSRV_APPHINT_FIRMWARELOGTYPE, fwt_logtype_tbl ) \ -X(HWRDebugDumpLimit, UINT32, ALWAYS, PVRSRV_APPHINT_HWRDEBUGDUMPLIMIT, NO_PARAM_TABLE ) \ -X(TimeCorrClock, UINT32List, ALWAYS, PVRSRV_APPHINT_TIMECORRCLOCK, timecorr_clk_tbl ) \ -X(HWPerfFWFilter, UINT64, ALWAYS, PVRSRV_APPHINT_HWPERFFWFILTER, NO_PARAM_TABLE ) \ -/* Device host config */ \ -X(EnableAPM, UINT32, ALWAYS, PVRSRV_APPHINT_ENABLEAPM, NO_PARAM_TABLE ) \ -X(DisableFEDLogging, BOOL, ALWAYS, PVRSRV_APPHINT_DISABLEFEDLOGGING, NO_PARAM_TABLE ) \ -X(ZeroFreelist, BOOL, ALWAYS, PVRSRV_APPHINT_ZEROFREELIST, NO_PARAM_TABLE ) \ -X(DisablePDumpPanic, BOOL, PDUMP, PVRSRV_APPHINT_DISABLEPDUMPPANIC, NO_PARAM_TABLE ) \ -X(EnableFWPoisonOnFree, BOOL, DEBUG, PVRSRV_APPHINT_ENABLEFWPOISONONFREE, NO_PARAM_TABLE ) \ -X(GPUUnitsPowerChange, BOOL, VALIDATION, PVRSRV_APPHINT_GPUUNITSPOWERCHANGE, NO_PARAM_TABLE ) \ -X(HWPerfHostFilter, UINT32, ALWAYS, PVRSRV_APPHINT_HWPERFHOSTFILTER, NO_PARAM_TABLE ) - -/* -******************************************************************************* - Mapping between debugfs parameters and module parameters. - This mapping is used to initialise device specific apphints from module - parameters. -******************************************************************************/ -#define APPHINT_LIST_DEBUIGINFO_DEVICE_X_MODPARAM_INIT_COMMON \ -/* debuginfo device apphint name modparam name */ \ -X(EnableAPM, EnableAPMAll) - -/* -******************************************************************************* - * Types used in the APPHINT_LIST_ lists must be defined here. - * New types require specific handling code to be added -******************************************************************************/ -#define APPHINT_DATA_TYPE_LIST \ -X(BOOL) \ -X(UINT64) \ -X(UINT32) \ -X(UINT32Bitfield) \ -X(UINT32List) \ -X(STRING) - -#define APPHINT_CLASS_LIST \ -X(ALWAYS) \ -X(NEVER) \ -X(DEBUG) \ -X(PDUMP) \ -X(VALIDATION) \ -X(GPUVIRT_VAL) - -/* -******************************************************************************* - Visibility control for module parameters - These bind build variables to AppHint Visibility Groups. -******************************************************************************/ -#define APPHINT_ENABLED_CLASS_ALWAYS IMG_TRUE -#define APPHINT_ENABLED_CLASS_NEVER IMG_FALSE -#define apphint_modparam_class_ALWAYS(a, b, c) apphint_modparam_enable(a, b, c) -#if defined(DEBUG) - #define APPHINT_ENABLED_CLASS_DEBUG IMG_TRUE - #define apphint_modparam_class_DEBUG(a, b, c) apphint_modparam_enable(a, b, c) -#else - #define APPHINT_ENABLED_CLASS_DEBUG IMG_FALSE - #define apphint_modparam_class_DEBUG(a, b, c) -#endif -#if defined(PDUMP) - #define APPHINT_ENABLED_CLASS_PDUMP IMG_TRUE - #define apphint_modparam_class_PDUMP(a, b, c) apphint_modparam_enable(a, b, c) -#else - #define APPHINT_ENABLED_CLASS_PDUMP IMG_FALSE - #define apphint_modparam_class_PDUMP(a, b, c) -#endif -#if defined(SUPPORT_VALIDATION) - #define APPHINT_ENABLED_CLASS_VALIDATION IMG_TRUE - #define apphint_modparam_class_VALIDATION(a, b, c) apphint_modparam_enable(a, b, c) -#else - #define APPHINT_ENABLED_CLASS_VALIDATION IMG_FALSE - #define apphint_modparam_class_VALIDATION(a, b, c) -#endif -#if defined(SUPPORT_GPUVIRT_VALIDATION) - #define APPHINT_ENABLED_CLASS_GPUVIRT_VAL IMG_TRUE - #define apphint_modparam_class_GPUVIRT_VAL(a, b, c) apphint_modparam_enable(a, b, c) -#else - #define APPHINT_ENABLED_CLASS_GPUVIRT_VAL IMG_FALSE - #define apphint_modparam_class_GPUVIRT_VAL(a, b, c) -#endif - -/* -******************************************************************************* - AppHint defaults based on other build parameters -******************************************************************************/ -#if defined(ASSERTONHWRTRIGGER_DEFAULT_ENABLED) - #define APPHNT_BLDVAR_ASSERTONHWRTRIGGER 1 -#else - #define APPHNT_BLDVAR_ASSERTONHWRTRIGGER 0 -#endif -#if defined(DEBUG) - #define APPHNT_BLDVAR_DEBUG 1 - #define APPHNT_BLDVAR_DBGDUMPLIMIT RGXFWIF_HWR_DEBUG_DUMP_ALL -#else - #define APPHNT_BLDVAR_DEBUG 0 - #define APPHNT_BLDVAR_DBGDUMPLIMIT 1 -#endif -#if defined(PDUMP) -#define APPHNT_BLDVAR_ENABLESIGNATURECHECKS IMG_TRUE -#else -#define APPHNT_BLDVAR_ENABLESIGNATURECHECKS IMG_FALSE -#endif -#if defined(DEBUG) || defined(SUPPORT_VALIDATION) -#define APPHNT_BLDVAR_ENABLEPAGEFAULTDEBUG IMG_TRUE -#else -#define APPHNT_BLDVAR_ENABLEPAGEFAULTDEBUG IMG_FALSE -#endif - -#if defined(DEBUG) - #define APPHNT_PHYSMEMTEST_ENABLE 1 -#else - #define APPHNT_PHYSMEMTEST_ENABLE 0 -#endif - -/* Data types and actions */ -typedef enum { - APPHINT_DATA_TYPE_INVALID = 0, -#define X(a) APPHINT_DATA_TYPE_ ## a, - APPHINT_DATA_TYPE_LIST -#undef X - APPHINT_DATA_TYPE_MAX -} APPHINT_DATA_TYPE; - -typedef enum { -#define X(a) APPHINT_CLASS_ ## a, - APPHINT_CLASS_LIST -#undef X - APPHINT_CLASS_MAX -} APPHINT_CLASS; - -#endif /* KM_APPHINT_DEFS_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/linkage.h b/drivers/gpu/drm/img-rogue/1.17/linkage.h deleted file mode 100644 index 3f24dc68eff60..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/linkage.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linux specific Services code internal interfaces -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Interfaces between various parts of the Linux specific - Services code, that don't have any other obvious - header file to go into. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(LINKAGE_H) -#define LINKAGE_H - -PVRSRV_ERROR PVROSFuncInit(void); -void PVROSFuncDeInit(void); - -#endif /* !defined(LINKAGE_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/linux_sw_sync.h b/drivers/gpu/drm/img-rogue/1.17/linux_sw_sync.h deleted file mode 100644 index c12c650294a2d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/linux_sw_sync.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ /*! -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _UAPI_LINUX_PVR_SW_SYNC_H -#define _UAPI_LINUX_PVR_SW_SYNC_H - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - -#include - -#include "pvrsrv_sync_km.h" -#include "pvr_drm.h" - -#endif /* defined(SUPPORT_NATIVE_FENCE_SYNC) */ -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/lists.c b/drivers/gpu/drm/img-rogue/1.17/lists.c deleted file mode 100644 index e8e7088a3296e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/lists.c +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linked list shared functions implementation. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implementation of the list iterators for types shared among - more than one file in the services code. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "lists.h" - -/*=================================================================== - LIST ITERATOR FUNCTIONS USED IN MORE THAN ONE FILE (those used just - once are implemented locally). - ===================================================================*/ - -IMPLEMENT_LIST_ANY(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, IMG_BOOL, IMG_FALSE) -IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_INSERT_TAIL(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE) diff --git a/drivers/gpu/drm/img-rogue/1.17/lists.h b/drivers/gpu/drm/img-rogue/1.17/lists.h deleted file mode 100644 index 2e2c29a0b7b0b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/lists.h +++ /dev/null @@ -1,367 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linked list shared functions templates. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Definition of the linked list function templates. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 LISTS_UTILS_H -#define LISTS_UTILS_H - -/* instruct QAC to ignore warnings about the following custom formatted macros */ -/* PRQA S 0881,3410 ++ */ - -#if defined(__linux__) - #include - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ -#else - #include -#endif /* __linux__ */ - -#include "img_types.h" -#include "device.h" -#include "power.h" - -/* - - USAGE - - - The list functions work with any structure that provides the fields psNext and - ppsThis. In order to make a function available for a given type, it is required - to use the function template macro that creates the actual code. - - There are 5 main types of functions: - - INSERT : given a pointer to the head pointer of the list and a pointer - to the node, inserts it as the new head. - - INSERT TAIL : given a pointer to the head pointer of the list and a pointer - to the node, inserts the node at the tail of the list. - - REMOVE : given a pointer to a node, removes it from its list. - - FOR EACH : apply a function over all the elements of a list. - - ANY : apply a function over the elements of a list, until one of them - return a non null value, and then returns it. - - The two last functions can have a variable argument form, with allows to pass - additional parameters to the callback function. In order to do this, the - callback function must take two arguments, the first is the current node and - the second is a list of variable arguments (va_list). - - The ANY functions have also another for which specifies the return type of the - callback function and the default value returned by the callback function. - -*/ - -/*************************************************************************/ /*! -@Function List_##TYPE##_ForEach -@Description Apply a callback function to all the elements of a list. -@Input psHead The head of the list to be processed. -@Input pfnCallBack The function to be applied to each element of the list. -*/ /**************************************************************************/ -#define DECLARE_LIST_FOR_EACH(TYPE) \ -void List_##TYPE##_ForEach(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode)) - -#define IMPLEMENT_LIST_FOR_EACH(TYPE) \ -void List_##TYPE##_ForEach(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode))\ -{\ - while (psHead)\ - {\ - pfnCallBack(psHead);\ - psHead = psHead->psNext;\ - }\ -} - -/*************************************************************************/ /*! -@Function List_##TYPE##_ForEachSafe -@Description Apply a callback function to all the elements of a list. Do it - in a safe way that handles the fact that a node might remove - itself from the list during the iteration. -@Input psHead The head of the list to be processed. -@Input pfnCallBack The function to be applied to each element of the list. -*/ /**************************************************************************/ -#define DECLARE_LIST_FOR_EACH_SAFE(TYPE) \ -void List_##TYPE##_ForEachSafe(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode)) - -#define IMPLEMENT_LIST_FOR_EACH_SAFE(TYPE) \ -void List_##TYPE##_ForEachSafe(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode))\ -{\ - TYPE *psNext;\ -\ - while (psHead)\ - {\ - psNext = psHead->psNext; \ - pfnCallBack(psHead);\ - psHead = psNext;\ - }\ -} - - -#define DECLARE_LIST_FOR_EACH_VA(TYPE) \ -void List_##TYPE##_ForEach_va(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode, va_list va), ...) - -#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \ -void List_##TYPE##_ForEach_va(TYPE *psHead, void(*pfnCallBack)(TYPE* psNode, va_list va), ...) \ -{\ - va_list ap;\ - while (psHead)\ - {\ - va_start(ap, pfnCallBack);\ - pfnCallBack(psHead, ap);\ - psHead = psHead->psNext;\ - va_end(ap);\ - }\ -} - - -/*************************************************************************/ /*! -@Function List_##TYPE##_Any -@Description Applies a callback function to the elements of a list until - the function returns a non null value, then returns it. -@Input psHead The head of the list to be processed. -@Input pfnCallBack The function to be applied to each element of the list. -@Return The first non null value returned by the callback function. -*/ /**************************************************************************/ -#define DECLARE_LIST_ANY(TYPE) \ -void* List_##TYPE##_Any(TYPE *psHead, void* (*pfnCallBack)(TYPE* psNode)) - -#define IMPLEMENT_LIST_ANY(TYPE) \ -void* List_##TYPE##_Any(TYPE *psHead, void* (*pfnCallBack)(TYPE* psNode))\ -{ \ - void *pResult;\ - TYPE *psNextNode;\ - pResult = NULL;\ - psNextNode = psHead;\ - while (psHead && !pResult)\ - {\ - psNextNode = psNextNode->psNext;\ - pResult = pfnCallBack(psHead);\ - psHead = psNextNode;\ - }\ - return pResult;\ -} - - -/*with variable arguments, that will be passed as a va_list to the callback function*/ - -#define DECLARE_LIST_ANY_VA(TYPE) \ -void* List_##TYPE##_Any_va(TYPE *psHead, void*(*pfnCallBack)(TYPE* psNode, va_list va), ...) - -#define IMPLEMENT_LIST_ANY_VA(TYPE) \ -void* List_##TYPE##_Any_va(TYPE *psHead, void*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\ -{\ - va_list ap;\ - TYPE *psNextNode;\ - void* pResult = NULL;\ - while (psHead && !pResult)\ - {\ - psNextNode = psHead->psNext;\ - va_start(ap, pfnCallBack);\ - pResult = pfnCallBack(psHead, ap);\ - va_end(ap);\ - psHead = psNextNode;\ - }\ - return pResult;\ -} - -/*those ones are for extra type safety, so there's no need to use castings for the results*/ - -#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \ -RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode)) - -#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \ -RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\ -{ \ - RTYPE result;\ - TYPE *psNextNode;\ - result = CONTINUE;\ - psNextNode = psHead;\ - while (psHead && result == CONTINUE)\ - {\ - psNextNode = psNextNode->psNext;\ - result = pfnCallBack(psHead);\ - psHead = psNextNode;\ - }\ - return result;\ -} - - -#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \ -RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...) - -#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \ -RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\ -{\ - va_list ap;\ - TYPE *psNextNode;\ - RTYPE result = CONTINUE;\ - while (psHead && result == CONTINUE)\ - {\ - psNextNode = psHead->psNext;\ - va_start(ap, pfnCallBack);\ - result = pfnCallBack(psHead, ap);\ - va_end(ap);\ - psHead = psNextNode;\ - }\ - return result;\ -} - - -/*************************************************************************/ /*! -@Function List_##TYPE##_Remove -@Description Removes a given node from the list. -@Input psNode The pointer to the node to be removed. -*/ /**************************************************************************/ -#define DECLARE_LIST_REMOVE(TYPE) \ -void List_##TYPE##_Remove(TYPE *psNode) - -#define IMPLEMENT_LIST_REMOVE(TYPE) \ -void List_##TYPE##_Remove(TYPE *psNode)\ -{\ - (*psNode->ppsThis)=psNode->psNext;\ - if (psNode->psNext)\ - {\ - psNode->psNext->ppsThis = psNode->ppsThis;\ - }\ -} - -/*************************************************************************/ /*! -@Function List_##TYPE##_Insert -@Description Inserts a given node at the beginning of the list. -@Input psHead The pointer to the pointer to the head node. -@Input psNode The pointer to the node to be inserted. -*/ /**************************************************************************/ -#define DECLARE_LIST_INSERT(TYPE) \ -void List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode) - -#define IMPLEMENT_LIST_INSERT(TYPE) \ -void List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\ -{\ - psNewNode->ppsThis = ppsHead;\ - psNewNode->psNext = *ppsHead;\ - *ppsHead = psNewNode;\ - if (psNewNode->psNext)\ - {\ - psNewNode->psNext->ppsThis = &(psNewNode->psNext);\ - }\ -} - -/*************************************************************************/ /*! -@Function List_##TYPE##_InsertTail -@Description Inserts a given node at the end of the list. -@Input psHead The pointer to the pointer to the head node. -@Input psNode The pointer to the node to be inserted. -*/ /**************************************************************************/ -#define DECLARE_LIST_INSERT_TAIL(TYPE) \ -void List_##TYPE##_InsertTail(TYPE **ppsHead, TYPE *psNewNode) - -#define IMPLEMENT_LIST_INSERT_TAIL(TYPE) \ -void List_##TYPE##_InsertTail(TYPE **ppsHead, TYPE *psNewNode)\ -{\ - TYPE *psTempNode = *ppsHead;\ - if (psTempNode != NULL)\ - {\ - while (psTempNode->psNext)\ - psTempNode = psTempNode->psNext;\ - ppsHead = &psTempNode->psNext;\ - }\ - psNewNode->ppsThis = ppsHead;\ - psNewNode->psNext = NULL;\ - *ppsHead = psNewNode;\ -} - -/*************************************************************************/ /*! -@Function List_##TYPE##_Reverse -@Description Reverse a list in place -@Input ppsHead The pointer to the pointer to the head node. -*/ /**************************************************************************/ -#define DECLARE_LIST_REVERSE(TYPE) \ -void List_##TYPE##_Reverse(TYPE **ppsHead) - -#define IMPLEMENT_LIST_REVERSE(TYPE) \ -void List_##TYPE##_Reverse(TYPE **ppsHead)\ -{\ - TYPE *psTmpNode1; \ - TYPE *psTmpNode2; \ - TYPE *psCurNode; \ - psTmpNode1 = NULL; \ - psCurNode = *ppsHead; \ - while (psCurNode) { \ - psTmpNode2 = psCurNode->psNext; \ - psCurNode->psNext = psTmpNode1; \ - psTmpNode1 = psCurNode; \ - psCurNode = psTmpNode2; \ - if (psCurNode) \ - { \ - psTmpNode1->ppsThis = &(psCurNode->psNext); \ - } \ - else \ - { \ - psTmpNode1->ppsThis = ppsHead; \ - } \ - } \ - *ppsHead = psTmpNode1; \ -} - -#define IS_LAST_ELEMENT(x) ((x)->psNext == NULL) - - -DECLARE_LIST_ANY(PVRSRV_DEVICE_NODE); -DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, IMG_BOOL, IMG_FALSE); -DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK); -DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE); -DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK); -DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE); -DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE); -DECLARE_LIST_INSERT_TAIL(PVRSRV_DEVICE_NODE); -DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE); - -#undef DECLARE_LIST_ANY_2 -#undef DECLARE_LIST_ANY_VA -#undef DECLARE_LIST_ANY_VA_2 -#undef DECLARE_LIST_FOR_EACH -#undef DECLARE_LIST_FOR_EACH_VA -#undef DECLARE_LIST_INSERT -#undef DECLARE_LIST_REMOVE - -#endif - -/* re-enable warnings */ -/* PRQA S 0881,3410 -- */ diff --git a/drivers/gpu/drm/img-rogue/1.17/lock.h b/drivers/gpu/drm/img-rogue/1.17/lock.h deleted file mode 100644 index 3ef78215f624b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/lock.h +++ /dev/null @@ -1,431 +0,0 @@ -/*************************************************************************/ /*! -@File lock.h -@Title Locking interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services internal locking interface -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 LOCK_H -#define LOCK_H - -/* In Linux kernel mode we are using the kernel mutex implementation directly - * with macros. This allows us to use the kernel lockdep feature for lock - * debugging. */ -#include "lock_types.h" - -#if defined(__linux__) && defined(__KERNEL__) - -#include "allocmem.h" -#include - -#define OSLockCreateNoStats(phLock) ({ \ - PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \ - *(phLock) = OSAllocMemNoStats(sizeof(struct mutex)); \ - if (*(phLock)) { mutex_init(*(phLock)); e = PVRSRV_OK; }; \ - e;}) -#define OSLockCreate(phLock) ({ \ - PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \ - *(phLock) = OSAllocMem(sizeof(struct mutex)); \ - if (*(phLock)) { mutex_init(*(phLock)); e = PVRSRV_OK; }; \ - e;}) -#define OSLockDestroy(hLock) ({mutex_destroy((hLock)); OSFreeMem((hLock));}) -#define OSLockDestroyNoStats(hLock) ({mutex_destroy((hLock)); OSFreeMemNoStats((hLock));}) - -#define OSLockAcquire(hLock) ({mutex_lock((hLock));}) -#define OSLockAcquireNested(hLock, subclass) ({mutex_lock_nested((hLock), (subclass));}) -#define OSLockRelease(hLock) ({mutex_unlock((hLock));}) - -#define OSLockIsLocked(hLock) ((mutex_is_locked((hLock)) == 1) ? IMG_TRUE : IMG_FALSE) -#define OSTryLockAcquire(hLock) ((mutex_trylock(hLock) == 1) ? IMG_TRUE : IMG_FALSE) - -#define OSSpinLockCreate(_ppsLock) ({ \ - PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \ - *(_ppsLock) = OSAllocMem(sizeof(spinlock_t)); \ - if (*(_ppsLock)) {spin_lock_init(*(_ppsLock)); e = PVRSRV_OK;} \ - e;}) -#define OSSpinLockDestroy(_psLock) ({OSFreeMem(_psLock);}) - -typedef unsigned long OS_SPINLOCK_FLAGS; -#define OSSpinLockAcquire(_pLock, _flags) spin_lock_irqsave(_pLock, _flags) -#define OSSpinLockRelease(_pLock, _flags) spin_unlock_irqrestore(_pLock, _flags) - -/* These _may_ be reordered or optimized away entirely by the compiler/hw */ -#define OSAtomicRead(pCounter) atomic_read(pCounter) -#define OSAtomicWrite(pCounter, i) atomic_set(pCounter, i) - -/* The following atomic operations, in addition to being SMP-safe, also - imply a memory barrier around the operation */ -#define OSAtomicIncrement(pCounter) atomic_inc_return(pCounter) -#define OSAtomicDecrement(pCounter) atomic_dec_return(pCounter) -#define OSAtomicCompareExchange(pCounter, oldv, newv) atomic_cmpxchg(pCounter,oldv,newv) -#define OSAtomicExchange(pCounter, iNewVal) atomic_xchg(pCounter, iNewVal) - -static inline IMG_INT OSAtomicOr(ATOMIC_T *pCounter, IMG_INT iVal) -{ - IMG_INT iOldVal, iLastVal, iNewVal; - - iLastVal = OSAtomicRead(pCounter); - do - { - iOldVal = iLastVal; - iNewVal = iOldVal | iVal; - - iLastVal = OSAtomicCompareExchange(pCounter, iOldVal, iNewVal); - } - while (iOldVal != iLastVal); - - return iNewVal; -} - -#define OSAtomicAdd(pCounter, incr) atomic_add_return(incr,pCounter) -#define OSAtomicAddUnless(pCounter, incr, test) atomic_add_unless(pCounter, (incr), (test)) - -#define OSAtomicSubtract(pCounter, incr) atomic_add_return(-(incr),pCounter) -#define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), (test)) - -#else /* defined(__linux__) && defined(__KERNEL__) */ - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" - -/**************************************************************************/ /*! -@Function OSLockCreate -@Description Creates an operating system lock object. -@Output phLock The created lock. -@Return PVRSRV_OK on success. PVRSRV_ERROR_OUT_OF_MEMORY if the driver - cannot allocate CPU memory needed for the lock. - PVRSRV_ERROR_INIT_FAILURE if the Operating System fails to - allocate the lock. - */ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR OSLockCreate(POS_LOCK *phLock); -#if defined(INTEGRITY_OS) -#define OSLockCreateNoStats OSLockCreate -#endif - -/**************************************************************************/ /*! -@Function OSLockDestroy -@Description Destroys an operating system lock object. -@Input hLock The lock to be destroyed. -@Return None. - */ /**************************************************************************/ -IMG_INTERNAL -void OSLockDestroy(POS_LOCK hLock); - -#if defined(INTEGRITY_OS) -#define OSLockDestroyNoStats OSLockDestroy -#endif -/**************************************************************************/ /*! -@Function OSLockAcquire -@Description Acquires an operating system lock. - NB. This function must not return until the lock is acquired - (meaning the implementation should not timeout or return with - an error, as the caller will assume they have the lock). -@Input hLock The lock to be acquired. -@Return None. - */ /**************************************************************************/ -IMG_INTERNAL -void OSLockAcquire(POS_LOCK hLock); - -/**************************************************************************/ /*! -@Function OSTryLockAcquire -@Description Try to acquire an operating system lock. - NB. If lock is acquired successfully in the first attempt, - then the function returns true and else it will return false. -@Input hLock The lock to be acquired. -@Return IMG_TRUE if lock acquired successfully, - IMG_FALSE otherwise. - */ /**************************************************************************/ -IMG_INTERNAL -IMG_BOOL OSTryLockAcquire(POS_LOCK hLock); - -/* Nested notation isn't used in UM or other OS's */ -/**************************************************************************/ /*! -@Function OSLockAcquireNested -@Description For operating systems other than Linux, this equates to an - OSLockAcquire() call. On Linux, this function wraps a call - to mutex_lock_nested(). This recognises the scenario where - there may be multiple subclasses within a particular class - of lock. In such cases, the order in which the locks belonging - these various subclasses are acquired is important and must be - validated. -@Input hLock The lock to be acquired. -@Input subclass The subclass of the lock. -@Return None. - */ /**************************************************************************/ -#define OSLockAcquireNested(hLock, subclass) OSLockAcquire((hLock)) - -/**************************************************************************/ /*! -@Function OSLockRelease -@Description Releases an operating system lock. -@Input hLock The lock to be released. -@Return None. - */ /**************************************************************************/ -IMG_INTERNAL -void OSLockRelease(POS_LOCK hLock); - -/**************************************************************************/ /*! -@Function OSLockIsLocked -@Description Tests whether or not an operating system lock is currently - locked. -@Input hLock The lock to be tested. -@Return IMG_TRUE if locked, IMG_FALSE if not locked. - */ /**************************************************************************/ -IMG_INTERNAL -IMG_BOOL OSLockIsLocked(POS_LOCK hLock); - -#if defined(__linux__) - -/* Use GCC intrinsics (read/write semantics consistent with kernel-side implementation) */ -#define OSAtomicRead(pCounter) (*(volatile IMG_INT32 *)&(pCounter)->counter) -#define OSAtomicWrite(pCounter, i) ((pCounter)->counter = (IMG_INT32) i) -#define OSAtomicIncrement(pCounter) __sync_add_and_fetch((&(pCounter)->counter), 1) -#define OSAtomicDecrement(pCounter) __sync_sub_and_fetch((&(pCounter)->counter), 1) -#define OSAtomicCompareExchange(pCounter, oldv, newv) \ - __sync_val_compare_and_swap((&(pCounter)->counter), oldv, newv) -#define OSAtomicOr(pCounter, iVal) __sync_or_and_fetch((&(pCounter)->counter), iVal) - -static inline IMG_UINT32 OSAtomicExchange(ATOMIC_T *pCounter, IMG_UINT32 iNewVal) -{ - IMG_UINT32 iOldVal; - IMG_UINT32 iLastVal; - - iLastVal = OSAtomicRead(pCounter); - do - { - iOldVal = iLastVal; - iLastVal = OSAtomicCompareExchange(pCounter, iOldVal, iNewVal); - } - while (iOldVal != iLastVal); - - return iOldVal; -} - -#define OSAtomicAdd(pCounter, incr) __sync_add_and_fetch((&(pCounter)->counter), incr) -#define OSAtomicAddUnless(pCounter, incr, test) ({ \ - IMG_INT32 c; IMG_INT32 old; \ - c = OSAtomicRead(pCounter); \ - while (1) { \ - if (c == (test)) break; \ - old = OSAtomicCompareExchange(pCounter, c, c+(incr)); \ - if (old == c) break; \ - c = old; \ - } c; }) - -#define OSAtomicSubtract(pCounter, incr) OSAtomicAdd(pCounter, -(incr)) -#define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), test) - -#else - -/*************************************************************************/ /*! -@Function OSAtomicRead -@Description Read the value of a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to read -@Return The value of the atomic variable -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicRead(const ATOMIC_T *pCounter); - -/*************************************************************************/ /*! -@Function OSAtomicWrite -@Description Write the value of a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be written to -@Input v The value to write -@Return None -*/ /**************************************************************************/ -IMG_INTERNAL -void OSAtomicWrite(ATOMIC_T *pCounter, IMG_INT32 v); - -/* For the following atomic operations, in addition to being SMP-safe, - should also have a memory barrier around each operation */ -/*************************************************************************/ /*! -@Function OSAtomicIncrement -@Description Increment the value of a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be incremented -@Return The new value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicIncrement(ATOMIC_T *pCounter); - -/*************************************************************************/ /*! -@Function OSAtomicDecrement -@Description Decrement the value of a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be decremented -@Return The new value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicDecrement(ATOMIC_T *pCounter); - -/*************************************************************************/ /*! -@Function OSAtomicAdd -@Description Add a specified value to a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to add the value to -@Input v The value to be added -@Return The new value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicAdd(ATOMIC_T *pCounter, IMG_INT32 v); - -/*************************************************************************/ /*! -@Function OSAtomicAddUnless -@Description Add a specified value to a variable atomically unless it - already equals a particular value. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to add the value to -@Input v The value to be added to 'pCounter' -@Input t The test value. If 'pCounter' equals this, - its value will not be adjusted -@Return The old value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicAddUnless(ATOMIC_T *pCounter, IMG_INT32 v, IMG_INT32 t); - -/*************************************************************************/ /*! -@Function OSAtomicSubtract -@Description Subtract a specified value to a variable atomically. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to subtract the value from -@Input v The value to be subtracted -@Return The new value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicSubtract(ATOMIC_T *pCounter, IMG_INT32 v); - -/*************************************************************************/ /*! -@Function OSAtomicSubtractUnless -@Description Subtract a specified value from a variable atomically unless - it already equals a particular value. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to subtract the value from -@Input v The value to be subtracted from 'pCounter' -@Input t The test value. If 'pCounter' equals this, - its value will not be adjusted -@Return The old value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicSubtractUnless(ATOMIC_T *pCounter, IMG_INT32 v, IMG_INT32 t); - -/*************************************************************************/ /*! -@Function OSAtomicCompareExchange -@Description Set a variable to a given value only if it is currently - equal to a specified value. The whole operation must be atomic. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be checked and - possibly updated -@Input oldv The value the atomic variable must have in - order to be modified -@Input newv The value to write to the atomic variable if - it equals 'oldv' -@Return The old value of *pCounter -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicCompareExchange(ATOMIC_T *pCounter, IMG_INT32 oldv, IMG_INT32 newv); - -/*************************************************************************/ /*! -@Function OSAtomicExchange -@Description Set a variable to a given value and retrieve previous value. - The whole operation must be atomic. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be updated -@Input iNewVal The value to write to the atomic variable -@Return The previous value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicExchange(ATOMIC_T *pCounter, IMG_INT32 iNewVal); - -/*************************************************************************/ /*! -@Function OSAtomicOr -@Description Set a variable to the bitwise or of its current value and the - specified value. Equivalent to *pCounter |= iVal. - The whole operation must be atomic. - Atomic functions must be implemented in a manner that - is both symmetric multiprocessor (SMP) safe and has a memory - barrier around each operation. -@Input pCounter The atomic variable to be updated -@Input iVal The value to bitwise or against -@Return The new value of *pCounter. -*/ /**************************************************************************/ -IMG_INTERNAL -IMG_INT32 OSAtomicOr(ATOMIC_T *pCounter, IMG_INT32 iVal); - -/* For now, spin-locks are required on Linux only, so other platforms fake - * spinlocks with normal mutex locks */ -/*! Type definitions for OS_SPINLOCK accessor and creation / deletion */ -typedef unsigned long OS_SPINLOCK_FLAGS; -/*! Pointer to an OS Spinlock */ -#define POS_SPINLOCK POS_LOCK -/*! Wrapper for OSLockCreate() */ -#define OSSpinLockCreate(ppLock) OSLockCreate(ppLock) -/*! Wrapper for OSLockDestroy() */ -#define OSSpinLockDestroy(pLock) OSLockDestroy(pLock) -/*! Wrapper for OSLockAcquire() */ -#define OSSpinLockAcquire(pLock, flags) {flags = 0; OSLockAcquire(pLock);} -/*! Wrapper for OSLockRelease() */ -#define OSSpinLockRelease(pLock, flags) {flags = 0; OSLockRelease(pLock);} - -#endif /* defined(__linux__) */ -#endif /* defined(__linux__) && defined(__KERNEL__) */ - -#endif /* LOCK_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/lock_types.h b/drivers/gpu/drm/img-rogue/1.17/lock_types.h deleted file mode 100644 index 370ffc025d054..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/lock_types.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************/ /*! -@File lock_types.h -@Title Locking types -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Locking specific enums, defines and structures -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 LOCK_TYPES_H -#define LOCK_TYPES_H - -/* In Linux kernel mode we are using the kernel mutex implementation directly - * with macros. This allows us to use the kernel lockdep feature for lock - * debugging. */ -#if defined(__linux__) && defined(__KERNEL__) - -#include -#include -/* The mutex is defined as a pointer to be compatible with the other code. This - * isn't ideal and usually you wouldn't do that in kernel code. */ -typedef struct mutex *POS_LOCK; -typedef struct rw_semaphore *POSWR_LOCK; -typedef spinlock_t *POS_SPINLOCK; -typedef atomic_t ATOMIC_T; - -#else /* defined(__linux__) && defined(__KERNEL__) */ -#include "img_types.h" /* needed for IMG_INT */ -typedef struct OS_LOCK_TAG *POS_LOCK; - -#if defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) -typedef struct OSWR_LOCK_TAG *POSWR_LOCK; -#else /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */ -typedef struct OSWR_LOCK_TAG { - IMG_UINT32 ui32Dummy; -} *POSWR_LOCK; -#endif /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */ - -#if defined(__linux__) - typedef struct OS_ATOMIC_TAG {IMG_INT32 counter;} ATOMIC_T; -#elif defined(__QNXNTO__) - typedef struct OS_ATOMIC_TAG {IMG_INT32 counter;} ATOMIC_T; -#elif defined(_WIN32) - /* - * Dummy definition. WDDM doesn't use Services, but some headers - * still have to be shared. This is one such case. - */ - typedef struct OS_ATOMIC_TAG {IMG_INT32 counter;} ATOMIC_T; -#elif defined(INTEGRITY_OS) - /* Only lower 32bits are used in OS ATOMIC APIs to have consistent behaviour across all OS */ - typedef struct OS_ATOMIC_TAG {IMG_INT64 counter;} ATOMIC_T; -#else - #error "Please type-define an atomic lock for this environment" -#endif - -#endif /* defined(__linux__) && defined(__KERNEL__) */ - -#endif /* LOCK_TYPES_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/log2.h b/drivers/gpu/drm/img-rogue/1.17/log2.h deleted file mode 100644 index 2182a0223ca6f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/log2.h +++ /dev/null @@ -1,417 +0,0 @@ -/*************************************************************************/ /*! -@Title Integer log2 and related functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 LOG2_H -#define LOG2_H - -#include "img_defs.h" - -/*************************************************************************/ /*! -@Description Determine if a number is a power of two. -@Input n -@Return True if n is a power of 2, false otherwise. True if n == 0. -*/ /**************************************************************************/ -static INLINE IMG_BOOL __const_function IsPower2(uint32_t n) -{ - /* C++ needs this cast. */ - return (IMG_BOOL)((n & (n - 1U)) == 0U); -} - -/*************************************************************************/ /*! -@Description Determine if a number is a power of two. -@Input n -@Return True if n is a power of 2, false otherwise. True if n == 0. -*/ /**************************************************************************/ -static INLINE IMG_BOOL __const_function IsPower2_64(uint64_t n) -{ - /* C++ needs this cast. */ - return (IMG_BOOL)((n & (n - 1U)) == 0U); -} - -/* Code using GNU GCC intrinsics */ -#if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) - -/* CHAR_BIT is typically found in . For all the platforms where - * CHAR_BIT is not available, defined it here with the assumption that there - * are 8 bits in a byte */ -#ifndef CHAR_BIT -#define CHAR_BIT 8U -#endif - -/*************************************************************************/ /*! -@Description Compute floor(log2(n)) -@Input n -@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function FloorLog2(uint32_t n) -{ - if (unlikely(n == 0U)) - { - return 0; - } - else - { - uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n); - return uNumBits - (uint32_t)__builtin_clz(n) - 1U; - } -} - -/*************************************************************************/ /*! -@Description Compute floor(log2(n)) -@Input n -@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function FloorLog2_64(uint64_t n) -{ - if (unlikely(n == 0U)) - { - return 0; - } - else - { - uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n); - return uNumBits - (uint32_t)__builtin_clzll(n) - 1U; - } -} - -/*************************************************************************/ /*! -@Description Compute ceil(log2(n)) -@Input n -@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function CeilLog2(uint32_t n) -{ - if (unlikely(n == 0U || n == 1U)) - { - return 0; - } - else - { - uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n); - - n--; /* Handle powers of 2 */ - return uNumBits - (uint32_t)__builtin_clz(n); - } -} - -/*************************************************************************/ /*! -@Description Compute ceil(log2(n)) -@Input n -@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function CeilLog2_64(uint64_t n) -{ - if (unlikely(n == 0U || n == 1U)) - { - return 0; - } - else - { - uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n); - - n--; /* Handle powers of 2 */ - return uNumBits - (uint32_t)__builtin_clzll(n); - } -} - -/*************************************************************************/ /*! -@Description Compute log2(n) for exact powers of two only -@Input n Must be a power of two -@Return log2(n) -*/ /**************************************************************************/ -static INLINE uint32_t __const_function ExactLog2(uint32_t n) -{ - return (uint32_t)CHAR_BIT * (uint32_t)sizeof(n) - (uint32_t)__builtin_clz(n) - 1U; -} - -/*************************************************************************/ /*! -@Description Compute log2(n) for exact powers of two only -@Input n Must be a power of two -@Return log2(n) -*/ /**************************************************************************/ -static INLINE uint32_t __const_function ExactLog2_64(uint64_t n) -{ - return (uint32_t)CHAR_BIT * (uint32_t)sizeof(n) - (uint32_t)__builtin_clzll(n) - 1U; -} - -/*************************************************************************/ /*! -@Description Round a non-power-of-two number up to the next power of two. -@Input n -@Return n rounded up to the next power of two. If n is zero or - already a power of two, return n unmodified. -*/ /**************************************************************************/ -static INLINE uint32_t __const_function RoundUpToNextPowerOfTwo(uint32_t n) -{ - /* Cases with n greater than 2^31 needs separate handling - * as result of (1<<32) is undefined. */ - if (unlikely( n == 0U || n > (uint32_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - 1U))) - { - return 0; - } - - /* Return n if it is already a power of 2 */ - if ((IMG_BOOL)((n & (n - 1U)) == 0U)) - { - return n; - } - - return (uint32_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - (uint32_t)__builtin_clz(n)); -} - -/*************************************************************************/ /*! -@Description Round a non-power-of-two number up to the next power of two. -@Input n -@Return n rounded up to the next power of two. If n is zero or - already a power of two, return n unmodified. -*/ /**************************************************************************/ -static INLINE uint64_t __const_function RoundUpToNextPowerOfTwo_64(uint64_t n) -{ - /* Cases with n greater than 2^63 needs separate handling - * as result of (1<<64) is undefined. */ - if (unlikely( n == 0U || n > (uint64_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - 1U))) - { - return 0; - } - - /* Return n if it is already a power of 2 */ - if ((IMG_BOOL)((n & (n - 1U)) == 0U)) - { - return n; - } - - return (uint64_t)1 << ((uint64_t)CHAR_BIT * sizeof(n) - (uint64_t)__builtin_clzll(n)); -} - -#else /* #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) */ - -/*************************************************************************/ /*! -@Description Round a non-power-of-two number up to the next power of two. -@Input n -@Return n rounded up to the next power of two. If n is zero or - already a power of two, return n unmodified. -*/ /**************************************************************************/ -static INLINE uint32_t __const_function RoundUpToNextPowerOfTwo(uint32_t n) -{ - n--; - n |= n >> 1; /* handle 2 bit numbers */ - n |= n >> 2; /* handle 4 bit numbers */ - n |= n >> 4; /* handle 8 bit numbers */ - n |= n >> 8; /* handle 16 bit numbers */ - n |= n >> 16; /* handle 32 bit numbers */ - n++; - - return n; -} - -/*************************************************************************/ /*! -@Description Round a non-power-of-two number up to the next power of two. -@Input n -@Return n rounded up to the next power of two. If n is zero or - already a power of two, return n unmodified. -*/ /**************************************************************************/ -static INLINE uint64_t __const_function RoundUpToNextPowerOfTwo_64(uint64_t n) -{ - n--; - n |= n >> 1; /* handle 2 bit numbers */ - n |= n >> 2; /* handle 4 bit numbers */ - n |= n >> 4; /* handle 8 bit numbers */ - n |= n >> 8; /* handle 16 bit numbers */ - n |= n >> 16; /* handle 32 bit numbers */ - n |= n >> 32; /* handle 64 bit numbers */ - n++; - - return n; -} - -/*************************************************************************/ /*! -@Description Compute floor(log2(n)) -@Input n -@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function FloorLog2(uint32_t n) -{ - uint32_t ui32log2 = 0; - - while ((n >>= 1) != 0U) - { - ui32log2++; - } - - return ui32log2; -} - -/*************************************************************************/ /*! -@Description Compute floor(log2(n)) -@Input n -@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function FloorLog2_64(uint64_t n) -{ - uint32_t ui32log2 = 0; - - while ((n >>= 1) != 0U) - { - ui32log2++; - } - - return ui32log2; -} - -/*************************************************************************/ /*! -@Description Compute ceil(log2(n)) -@Input n -@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function CeilLog2(uint32_t n) -{ - uint32_t ui32log2 = 0; - - if (n == 0U) - { - return 0; - } - - n--; /* Handle powers of 2 */ - - while (n != 0U) - { - ui32log2++; - n >>= 1; - } - - return ui32log2; -} - -/*************************************************************************/ /*! -@Description Compute ceil(log2(n)) -@Input n -@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0 -*/ /**************************************************************************/ -static INLINE uint32_t __const_function CeilLog2_64(uint64_t n) -{ - uint32_t ui32log2 = 0; - - if (n == 0U) - { - return 0; - } - - n--; /* Handle powers of 2 */ - - while (n != 0U) - { - ui32log2++; - n >>= 1; - } - - return ui32log2; -} - -/*************************************************************************/ /*! -@Description Compute log2(n) for exact powers of two only -@Input n Must be a power of two -@Return log2(n) -*/ /**************************************************************************/ -static INLINE uint32_t __const_function ExactLog2(uint32_t n) -{ - static const uint32_t b[] = - {0xAAAAAAAAU, 0xCCCCCCCCU, 0xF0F0F0F0U, 0xFF00FF00U, 0xFFFF0000U}; - uint32_t r = (n & b[0]) != 0U; - - r |= (uint32_t) ((n & b[4]) != 0U) << 4; - r |= (uint32_t) ((n & b[3]) != 0U) << 3; - r |= (uint32_t) ((n & b[2]) != 0U) << 2; - r |= (uint32_t) ((n & b[1]) != 0U) << 1; - - return r; -} - -/*************************************************************************/ /*! -@Description Compute log2(n) for exact powers of two only -@Input n Must be a power of two -@Return log2(n) -*/ /**************************************************************************/ -static INLINE uint32_t __const_function ExactLog2_64(uint64_t n) -{ - static const uint64_t b[] = - {0xAAAAAAAAAAAAAAAAULL, 0xCCCCCCCCCCCCCCCCULL, - 0xF0F0F0F0F0F0F0F0ULL, 0xFF00FF00FF00FF00ULL, - 0xFFFF0000FFFF0000ULL, 0xFFFFFFFF00000000ULL}; - uint32_t r = (n & b[0]) != 0U; - - r |= (uint32_t) ((n & b[5]) != 0U) << 5; - r |= (uint32_t) ((n & b[4]) != 0U) << 4; - r |= (uint32_t) ((n & b[3]) != 0U) << 3; - r |= (uint32_t) ((n & b[2]) != 0U) << 2; - r |= (uint32_t) ((n & b[1]) != 0U) << 1; - - return r; -} - -#endif /* #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) */ - -/*************************************************************************/ /*! -@Description Compute floor(log2(size)) , where size is the max of 3 sizes - This is almost always the ONLY EVER valid use of FloorLog2. - Usually CeilLog2() should be used instead. - For a 5x5x1 texture, the 3 miplevels are: - 0: 5x5x1 - 1: 2x2x1 - 2: 1x1x1 - - For an 8x8x1 texture, the 4 miplevels are: - 0: 8x8x1 - 1: 4x4x1 - 2: 2x2x1 - 3: 1x1x1 - - -@Input sizeX, sizeY, sizeZ -@Return Count of mipmap levels for given dimensions -*/ /**************************************************************************/ -static INLINE uint32_t __const_function NumMipLevels(uint32_t sizeX, uint32_t sizeY, uint32_t sizeZ) -{ - - uint32_t maxSize = MAX(MAX(sizeX, sizeY), sizeZ); - return FloorLog2(maxSize) + 1U; -} - -#endif /* LOG2_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/mem_utils.c b/drivers/gpu/drm/img-rogue/1.17/mem_utils.c deleted file mode 100644 index 1244e246afb92..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mem_utils.c +++ /dev/null @@ -1,449 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Memory manipulation functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Memory related functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "osfunc_common.h" -#include "img_defs.h" - -/* This workaround is only *required* on ARM64. Avoid building or including - * it by default on other architectures, unless the 'safe memcpy' test flag - * is enabled. (The code should work on other architectures.) - */ - - - -/* NOTE: This C file is compiled with -ffreestanding to avoid pattern matching - * by the compiler to stdlib functions, and it must only use the below - * headers. Do not include any IMG or services headers in this file. - */ -#if defined(__KERNEL__) && defined(__linux__) -#include -#else -#include -#endif - -/* The attribute "vector_size" will generate floating point instructions - * and use FPU registers. In kernel OS, the FPU registers might be corrupted - * when CPU is doing context switch because FPU registers are not expected to - * be stored. - * GCC enables compiler option, -mgeneral-regs-only, by default. - * This option restricts the generated code to use general registers only - * so that we don't have issues on that. - */ -#if defined(__KERNEL__) && defined(__clang__) - -#define DEVICE_MEMSETCPY_NON_VECTOR_KM -#if !defined(BITS_PER_BYTE) -#define BITS_PER_BYTE (8) -#endif /* BITS_PER_BYTE */ - -/* Loading or storing 16 or 32 bytes is only supported on 64-bit machines. */ -#if DEVICE_MEMSETCPY_ALIGN_IN_BYTES > 8 -typedef __uint128_t uint128_t; - -typedef struct -{ - uint128_t ui128DataFields[2]; -} -uint256_t; -#endif - -#endif - -/* This file is only intended to be used on platforms which use GCC or Clang, - * due to its requirement on __attribute__((vector_size(n))), typeof() and - * __SIZEOF__ macros. - */ - -#if defined(__GNUC__) - -#ifndef MIN -#define MIN(a, b) \ - ({__typeof(a) _a = (a); __typeof(b) _b = (b); _a > _b ? _b : _a;}) -#endif - -#if !defined(DEVICE_MEMSETCPY_ALIGN_IN_BYTES) -#define DEVICE_MEMSETCPY_ALIGN_IN_BYTES __SIZEOF_LONG__ -#endif -#if (DEVICE_MEMSETCPY_ALIGN_IN_BYTES & (DEVICE_MEMSETCPY_ALIGN_IN_BYTES - 1)) != 0 -#error "DEVICE_MEMSETCPY_ALIGN_IN_BYTES must be a power of 2" -#endif -#if DEVICE_MEMSETCPY_ALIGN_IN_BYTES < 4 -#error "DEVICE_MEMSETCPY_ALIGN_IN_BYTES must be equal or greater than 4" -#endif - -#if __SIZEOF_POINTER__ != __SIZEOF_LONG__ -#error No support for architectures where void* and long are sized differently -#endif - -#if __SIZEOF_LONG__ > DEVICE_MEMSETCPY_ALIGN_IN_BYTES -/* Meaningless, and harder to do correctly */ -# error Cannot handle DEVICE_MEMSETCPY_ALIGN_IN_BYTES < sizeof(long) -typedef unsigned long block_t; -#elif __SIZEOF_LONG__ <= DEVICE_MEMSETCPY_ALIGN_IN_BYTES -# if defined(DEVICE_MEMSETCPY_NON_VECTOR_KM) -# if DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 8 - typedef uint64_t block_t; -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 16 - typedef uint128_t block_t; -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 32 - typedef uint256_t block_t; -# endif -# else -typedef unsigned int block_t - __attribute__((vector_size(DEVICE_MEMSETCPY_ALIGN_IN_BYTES))); -# endif -# if defined(__arm64__) || defined(__aarch64__) -# if DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 8 -# define DEVICE_MEMSETCPY_ARM64 -# define REGSZ "w" -# define REGCL "w" -# define BVCLB "r" -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 16 -# define DEVICE_MEMSETCPY_ARM64 -# define REGSZ "x" -# define REGCL "x" -# define BVCLB "r" -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 32 -# if defined(__ARM_NEON_FP) -# define DEVICE_MEMSETCPY_ARM64 -# define REGSZ "q" -# define REGCL "v" -# define BVCLB "w" -# endif -# endif -# if defined(DEVICE_MEMSETCPY_ARM64) -# if defined(DEVICE_MEMSETCPY_ARM64_NON_TEMPORAL) -# define NSHLD() __asm__ ("dmb nshld") -# define NSHST() __asm__ ("dmb nshst") -# define LDP "ldnp" -# define STP "stnp" -# else -# define NSHLD() -# define NSHST() -# define LDP "ldp" -# define STP "stp" -# endif -# if defined(DEVICE_MEMSETCPY_NON_VECTOR_KM) -# if DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 8 -typedef uint32_t block_half_t; -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 16 -typedef uint64_t block_half_t; -# elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 32 -typedef uint128_t block_half_t; -# endif -# else - typedef unsigned int block_half_t - __attribute__((vector_size(DEVICE_MEMSETCPY_ALIGN_IN_BYTES / 2))); -# endif -# endif -# endif -#endif - -__attribute__((visibility("hidden"))) -void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t uSize) -{ - volatile const char *pcSrc = pvSrc; - volatile char *pcDst = pvDst; - size_t uPreambleBytes; - int bBlockCopy = 0; - - size_t uSrcUnaligned = (size_t)pcSrc % sizeof(block_t); - size_t uDstUnaligned = (size_t)pcDst % sizeof(block_t); - - if (!uSrcUnaligned && !uDstUnaligned) - { - /* Neither pointer is unaligned. Optimal case. */ - bBlockCopy = 1; - } - else - { - if (uSrcUnaligned == uDstUnaligned) - { - /* Neither pointer is usefully aligned, but they are misaligned in - * the same way, so we can copy a preamble in a slow way, then - * optimize the rest. - */ - uPreambleBytes = MIN(sizeof(block_t) - uDstUnaligned, uSize); - uSize -= uPreambleBytes; - while (uPreambleBytes) - { - *pcDst++ = *pcSrc++; - uPreambleBytes--; - } - - bBlockCopy = 1; - } - else if ((uSrcUnaligned | uDstUnaligned) % sizeof(int) == 0) - { - /* Both pointers are at least 32-bit aligned, and we assume that - * the processor must handle all kinds of 32-bit load-stores. - * NOTE: Could we optimize this with a non-temporal version? - */ - if (uSize >= sizeof(int)) - { - volatile int *piSrc = (int *)((void *)pcSrc); - volatile int *piDst = (int *)((void *)pcDst); - - while (uSize >= sizeof(int)) - { - *piDst++ = *piSrc++; - uSize -= sizeof(int); - } - - pcSrc = (char *)((void *)piSrc); - pcDst = (char *)((void *)piDst); - } - } - } - - if (bBlockCopy && uSize >= sizeof(block_t)) - { - volatile block_t *pSrc = (block_t *)((void *)pcSrc); - volatile block_t *pDst = (block_t *)((void *)pcDst); - -#if defined(DEVICE_MEMSETCPY_ARM64) - NSHLD(); -#endif - - while (uSize >= sizeof(block_t)) - { -#if defined(DEVICE_MEMSETCPY_ARM64) - __asm__ (LDP " " REGSZ "0, " REGSZ "1, [%[pSrc]]\n\t" - STP " " REGSZ "0, " REGSZ "1, [%[pDst]]" - : - : [pSrc] "r" (pSrc), [pDst] "r" (pDst) - : "memory", REGCL "0", REGCL "1"); -#else - *pDst = *pSrc; -#endif - pDst++; - pSrc++; - uSize -= sizeof(block_t); - } - -#if defined(DEVICE_MEMSETCPY_ARM64) - NSHST(); -#endif - - pcSrc = (char *)((void *)pSrc); - pcDst = (char *)((void *)pDst); - } - - while (uSize) - { - *pcDst++ = *pcSrc++; - uSize--; - } -} - -__attribute__((visibility("hidden"))) -void DeviceMemSet(void *pvDst, unsigned char ui8Value, size_t uSize) -{ - volatile char *pcDst = pvDst; - size_t uPreambleBytes; - - size_t uDstUnaligned = (size_t)pcDst % sizeof(block_t); - - if (uDstUnaligned) - { - uPreambleBytes = MIN(sizeof(block_t) - uDstUnaligned, uSize); - uSize -= uPreambleBytes; - while (uPreambleBytes) - { - *pcDst++ = ui8Value; - uPreambleBytes--; - } - } - - if (uSize >= sizeof(block_t)) - { - volatile block_t *pDst = (block_t *)((void *)pcDst); - size_t i, uBlockSize; -#if defined(DEVICE_MEMSETCPY_ARM64) - typedef block_half_t BLK_t; -#else - typedef block_t BLK_t; -#endif /* defined(DEVICE_MEMSETCPY_ARM64) */ - -#if defined(DEVICE_MEMSETCPY_NON_VECTOR_KM) - BLK_t bValue = 0; - - uBlockSize = sizeof(BLK_t) / sizeof(ui8Value); - - for (i = 0; i < uBlockSize; i++) - { - bValue |= (BLK_t)ui8Value << ((uBlockSize - i - 1) * BITS_PER_BYTE); - } -#else - BLK_t bValue = {0}; - - uBlockSize = sizeof(bValue) / sizeof(unsigned int); - for (i = 0; i < uBlockSize; i++) - bValue[i] = ui8Value << 24U | - ui8Value << 16U | - ui8Value << 8U | - ui8Value; -#endif /* defined(DEVICE_MEMSETCPY_NON_VECTOR_KM) */ - -#if defined(DEVICE_MEMSETCPY_ARM64) - NSHLD(); -#endif - - while (uSize >= sizeof(block_t)) - { -#if defined(DEVICE_MEMSETCPY_ARM64) - __asm__ (STP " %" REGSZ "[bValue], %" REGSZ "[bValue], [%[pDst]]" - : - : [bValue] BVCLB (bValue), [pDst] "r" (pDst) - : "memory"); -#else - *pDst = bValue; -#endif - pDst++; - uSize -= sizeof(block_t); - } - -#if defined(DEVICE_MEMSETCPY_ARM64) - NSHST(); -#endif - - pcDst = (char *)((void *)pDst); - } - - while (uSize) - { - *pcDst++ = ui8Value; - uSize--; - } -} - -#endif /* defined(__GNUC__) */ - -/* Potentially very slow (but safe) fallbacks for non-GNU C compilers */ -IMG_INTERNAL -void DeviceMemCopyBytes(void *pvDst, const void *pvSrc, size_t uSize) -{ - volatile const char *pcSrc = pvSrc; - volatile char *pcDst = pvDst; - - while (uSize) - { - *pcDst++ = *pcSrc++; - uSize--; - } -} - -IMG_INTERNAL -void DeviceMemSetBytes(void *pvDst, unsigned char ui8Value, size_t uSize) -{ - volatile char *pcDst = pvDst; - - while (uSize) - { - *pcDst++ = ui8Value; - uSize--; - } -} - -#if !defined(__QNXNTO__) /* Ignore Neutrino as it uses strlcpy */ - -#if defined(__KERNEL__) && defined(__linux__) -/* - * In case of Linux kernel-mode in a debug build, choose the variant - * of StringLCopy that uses strlcpy and logs truncation via a stack dump. - * For Linux kernel-mode in a release build, strlcpy alone is used. - */ -#if defined(DEBUG) -IMG_INTERNAL -size_t StringLCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDataSize) -{ - /* - * Let strlcpy handle any truncation cases correctly. - * We will definitely get a NUL-terminated string set in pszDest - */ - size_t uSrcSize = strlcpy(pszDest, pszSrc, uDataSize); - -#if defined(PVR_DEBUG_STRLCPY) - /* Handle truncation by dumping calling stack if debug allows */ - if (uSrcSize >= uDataSize) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: String truncated Src = '<%s>' %ld bytes, Dest = '%s'", - __func__, pszSrc, (long)uDataSize, pszDest)); - OSDumpStack(); - } -#endif /* defined(PVR_DEBUG_STRLCPY) && defined(DEBUG) */ - - return uSrcSize; -} -#endif /* defined(DEBUG) */ - -#else /* defined(__KERNEL__) && defined(__linux__) */ -/* - * For every other platform, make use of the strnlen and strncpy - * implementation of StringLCopy. - * NOTE: It is crucial to avoid memcpy as this has a hidden side-effect of - * dragging in whatever the build-environment flavour of GLIBC is which can - * cause unexpected failures for host-side command execution. - */ -IMG_INTERNAL -size_t StringLCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDataSize) -{ - size_t uSrcSize = strnlen(pszSrc, uDataSize); - - (void)strncpy(pszDest, pszSrc, uSrcSize); - if (uSrcSize == uDataSize) - { - pszDest[uSrcSize-1] = '\0'; - } - else - { - pszDest[uSrcSize] = '\0'; - } - - return uSrcSize; -} - -#endif /* defined(__KERNEL__) && defined(__linux__) */ - -#endif /* !defined(__QNXNTO__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/mmu_common.c b/drivers/gpu/drm/img-rogue/1.17/mmu_common.c deleted file mode 100644 index 4ed3ce0738904..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mmu_common.c +++ /dev/null @@ -1,4462 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common MMU Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements basic low level control of MMU. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "pvrsrv_error.h" -#include "pvr_debug.h" -#include "dllist.h" -#include "osfunc.h" -#include "allocmem.h" - -#if defined(SUPPORT_RGX) -# include "rgx_memallocflags.h" -# include "rgxmmudefs_km.h" -#endif - -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "htbuffer.h" -#include "pvr_ricommon.h" - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -# include "process_stats.h" -# include "proc_stats.h" -#endif - -#if defined(PDUMP) -#include "pdump_km.h" -#include "pdump_physmem.h" -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "physmem_lma.h" -#endif - -/* -Major Interfaces to other modules: - -Let's keep this graph up-to-date: - - +-----------+ - | devicemem | - +-----------+ - | - +============+ - | mmu_common | - +============+ - | - +-----------------+ - | | - +---------+ +----------+ - | pmr | | device | - +---------+ +----------+ - */ - -#include "mmu_common.h" -#include "pmr.h" -#include "devicemem_server_utils.h" - -/* #define MMU_OBJECT_REFCOUNT_DEBUGING 1 */ -#if defined(MMU_OBJECT_REFCOUNT_DEBUGING) -#define MMU_OBJ_DBG(x) PVR_DPF(x) -#else -#define MMU_OBJ_DBG(x) -#endif - -/*! - * Refcounted structure that is shared between the context and - * the cleanup thread items. - * It is used to keep track of all cleanup items and whether the creating - * MMU context has been destroyed and therefore is not allowed to be - * accessed any more. - * - * The cleanup thread is used to defer the freeing of the page tables - * because we have to make sure that the MMU cache has been invalidated. - * If we don't take care of this the MMU might partially access cached - * and uncached tables which might lead to inconsistencies and in the - * worst case to MMU pending faults on random memory. - */ -typedef struct _MMU_CTX_CLEANUP_DATA_ -{ - /*! Refcount to know when this structure can be destroyed */ - ATOMIC_T iRef; - /*! Protect items in this structure, especially the refcount */ - POS_LOCK hCleanupLock; - /*! List of all cleanup items currently in flight */ - DLLIST_NODE sMMUCtxCleanupItemsHead; - /*! Was the MMU context destroyed and should not be accessed any more? */ - IMG_BOOL bMMUContextExists; -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /*! Associated OSid for this context */ - IMG_UINT32 ui32OSid; -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ -} MMU_CTX_CLEANUP_DATA; - - -/*! - * Structure holding one or more page tables that need to be - * freed after the MMU cache has been flushed which is signalled when - * the stored sync has a value that is <= the required value. - */ -typedef struct _MMU_CLEANUP_ITEM_ -{ - /*! Cleanup thread data */ - PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn; - /*! List to hold all the MMU_MEMORY_MAPPINGs, i.e. page tables */ - DLLIST_NODE sMMUMappingHead; - /*! Node of the cleanup item list for the context */ - DLLIST_NODE sMMUCtxCleanupItem; - /* Pointer to the cleanup meta data */ - MMU_CTX_CLEANUP_DATA *psMMUCtxCleanupData; - /* Sync to query if the MMU cache was flushed */ - PVRSRV_CLIENT_SYNC_PRIM *psSync; - /*! The update value of the sync to signal that the cache was flushed */ - IMG_UINT32 uiRequiredSyncVal; - /*! The device node needed to free the page tables */ - PVRSRV_DEVICE_NODE *psDevNode; -} MMU_CLEANUP_ITEM; - -/*! - All physical allocations and frees are relative to this context, so - we would get all the allocations of PCs, PDs, and PTs from the same - RA. - - We have one per MMU context in case we have mixed UMA/LMA devices - within the same system. - */ -typedef struct _MMU_PHYSMEM_CONTEXT_ -{ - /*! Associated MMU_CONTEXT */ - struct _MMU_CONTEXT_ *psMMUContext; - - /*! Parent device node */ - PVRSRV_DEVICE_NODE *psDevNode; - - /*! Refcount so we know when to free up the arena */ - IMG_UINT32 uiNumAllocations; - - /*! Arena from which physical memory is derived */ - RA_ARENA *psPhysMemRA; - /*! Arena name */ - IMG_CHAR *pszPhysMemRAName; - /*! Size of arena name string */ - size_t uiPhysMemRANameAllocSize; - - /*! Meta data for deferred cleanup */ - MMU_CTX_CLEANUP_DATA *psCleanupData; - /*! Temporary list of all deferred MMU_MEMORY_MAPPINGs. */ - DLLIST_NODE sTmpMMUMappingHead; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - IMG_UINT32 ui32OSid; - IMG_UINT32 ui32OSidReg; - IMG_BOOL bOSidAxiProt; -#endif - -} MMU_PHYSMEM_CONTEXT; - -/*! - Mapping structure for MMU memory allocation - */ -typedef struct _MMU_MEMORY_MAPPING_ -{ - /*! Physmem context to allocate from */ - MMU_PHYSMEM_CONTEXT *psContext; - /*! OS/system Handle for this allocation */ - PG_HANDLE sMemHandle; - /*! CPU virtual address of this allocation */ - void *pvCpuVAddr; - /*! Device physical address of this allocation */ - IMG_DEV_PHYADDR sDevPAddr; - /*! Size of this allocation */ - size_t uiSize; - /*! Number of current mappings of this allocation */ - IMG_UINT32 uiCpuVAddrRefCount; - /*! Node for the defer free list */ - DLLIST_NODE sMMUMappingItem; -} MMU_MEMORY_MAPPING; - -/*! - Memory descriptor for MMU objects. There can be more than one memory - descriptor per MMU memory allocation. - */ -typedef struct _MMU_MEMORY_DESC_ -{ - /* NB: bValid is set if this descriptor describes physical - memory. This allows "empty" descriptors to exist, such that we - can allocate them in batches. */ - /*! Does this MMU object have physical backing */ - IMG_BOOL bValid; - /*! Device Physical address of physical backing */ - IMG_DEV_PHYADDR sDevPAddr; - /*! CPU virtual address of physical backing */ - void *pvCpuVAddr; - /*! Mapping data for this MMU object */ - MMU_MEMORY_MAPPING *psMapping; - /*! Memdesc offset into the psMapping */ - IMG_UINT32 uiOffset; - /*! Size of the Memdesc */ - IMG_UINT32 uiSize; -} MMU_MEMORY_DESC; - -/*! - MMU levelx structure. This is generic and is used - for all levels (PC, PD, PT). - */ -typedef struct _MMU_Levelx_INFO_ -{ - /*! The Number of entries in this level */ - IMG_UINT32 ui32NumOfEntries; - - /*! Number of times this level has been reference. Note: For Level1 (PTE) - we still take/drop the reference when setting up the page tables rather - then at map/unmap time as this simplifies things */ - IMG_UINT32 ui32RefCount; - - /*! MemDesc for this level */ - MMU_MEMORY_DESC sMemDesc; - - /*! Array of infos for the next level. Must be last member in structure */ - struct _MMU_Levelx_INFO_ *apsNextLevel[1]; -} MMU_Levelx_INFO; - -/*! - MMU context structure - */ -struct _MMU_CONTEXT_ -{ - /*! Originating Connection */ - CONNECTION_DATA *psConnection; - - MMU_DEVICEATTRIBS *psDevAttrs; - - /*! For allocation and deallocation of the physical memory where - the pagetables live */ - struct _MMU_PHYSMEM_CONTEXT_ *psPhysMemCtx; - -#if defined(PDUMP) - /*! PDump context ID (required for PDump commands with virtual addresses) */ - IMG_UINT32 uiPDumpContextID; - - /*! The refcount of the PDump context ID */ - IMG_UINT32 ui32PDumpContextIDRefCount; -#endif - - /*! MMU cache invalidation flags (only used on Volcanic driver) */ - ATOMIC_T sCacheFlags; - - /*! Lock to ensure exclusive access when manipulating the MMU context or - * reading and using its content - */ - POS_LOCK hLock; - - /*! Base level info structure. Must be last member in structure */ - MMU_Levelx_INFO sBaseLevelInfo; - /* NO OTHER MEMBERS AFTER THIS STRUCTURE ! */ -}; - -static const IMG_DEV_PHYADDR gsBadDevPhyAddr = {MMU_BAD_PHYS_ADDR}; - -#if defined(DEBUG) -#include "log2.h" -#endif - -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) && defined(__linux__) -static IMG_UINT32 g_ui32MMULeakCounter = 0; -static DEFINE_MUTEX(g_sMMULeakMutex); -#endif - -/***************************************************************************** - * Utility functions * - *****************************************************************************/ - -/*************************************************************************/ /*! -@Function _FreeMMUMapping - -@Description Free a given dllist of MMU_MEMORY_MAPPINGs and the page tables - they represent. - -@Input psDevNode Device node - -@Input psTmpMMUMappingHead List of MMU_MEMORY_MAPPINGs to free - */ -/*****************************************************************************/ -static void -_FreeMMUMapping(PVRSRV_DEVICE_NODE *psDevNode, - PDLLIST_NODE psTmpMMUMappingHead) -{ - PDLLIST_NODE psNode, psNextNode; - - /* Free the current list unconditionally */ - dllist_foreach_node(psTmpMMUMappingHead, - psNode, - psNextNode) - { - MMU_MEMORY_MAPPING *psMapping = IMG_CONTAINER_OF(psNode, - MMU_MEMORY_MAPPING, - sMMUMappingItem); - - PhysHeapPagesFree(psDevNode->psMMUPhysHeap, &psMapping->sMemHandle); - dllist_remove_node(psNode); - OSFreeMem(psMapping); - } -} - -/*************************************************************************/ /*! -@Function _CleanupThread_FreeMMUMapping - -@Description Function to be executed by the cleanup thread to free - MMU_MEMORY_MAPPINGs after the MMU cache has been invalidated. - - This function will request a MMU cache invalidate once and - retry to free the MMU_MEMORY_MAPPINGs until the invalidate - has been executed. - - If the memory context that created this cleanup item has been - destroyed in the meantime this function will directly free the - MMU_MEMORY_MAPPINGs without waiting for any MMU cache - invalidation. - -@Input pvData Cleanup data in form of a MMU_CLEANUP_ITEM - -@Return PVRSRV_OK if successful otherwise PVRSRV_ERROR_RETRY - */ -/*****************************************************************************/ -static PVRSRV_ERROR -_CleanupThread_FreeMMUMapping(void* pvData) -{ - PVRSRV_ERROR eError; - MMU_CLEANUP_ITEM *psCleanup = (MMU_CLEANUP_ITEM *)pvData; - MMU_CTX_CLEANUP_DATA *psMMUCtxCleanupData = psCleanup->psMMUCtxCleanupData; - PVRSRV_DEVICE_NODE *psDevNode = psCleanup->psDevNode; - IMG_BOOL bFreeNow; - IMG_UINT32 uiSyncCurrent; - IMG_UINT32 uiSyncReq; - - OSLockAcquire(psMMUCtxCleanupData->hCleanupLock); - - /* Don't attempt to free anything when the context has been destroyed. - * Especially don't access any device specific structures any more!*/ - if (!psMMUCtxCleanupData->bMMUContextExists) - { - OSFreeMem(psCleanup); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_OK, e0); - } - - if (psCleanup->psSync == NULL) - { - /* Kick to invalidate the MMU caches and get sync info */ - eError = psDevNode->pfnMMUCacheInvalidateKick(psDevNode, - &psCleanup->uiRequiredSyncVal); - if (eError != PVRSRV_OK) - { - OSLockRelease(psMMUCtxCleanupData->hCleanupLock); - return PVRSRV_ERROR_RETRY; - } - psCleanup->psSync = psDevNode->psMMUCacheSyncPrim; - } - - uiSyncCurrent = OSReadDeviceMem32(psCleanup->psSync->pui32LinAddr); - uiSyncReq = psCleanup->uiRequiredSyncVal; - - /* Has the invalidate executed */ - bFreeNow = (uiSyncCurrent >= uiSyncReq) ? - /* ... with the counter wrapped around ... - * There can't be 3*1024*1024 transactions completed, so consider wrapped */ - (((uiSyncCurrent - uiSyncReq) > 0xF0000000UL)? IMG_FALSE : IMG_TRUE): - /* There can't be 3*1024*1024 transactions pending, so consider wrapped */ - (((uiSyncReq - uiSyncCurrent) > 0xF0000000UL)? IMG_TRUE : IMG_FALSE); - -#if defined(NO_HARDWARE) - /* In NOHW the syncs will never be updated so just free the tables */ - bFreeNow = IMG_TRUE; -#endif - /* If the Invalidate operation is not completed, check if the operation timed out */ - if (!bFreeNow) - { - /* If the time left for the completion of invalidate operation is - * within 500ms of time-out, consider the operation as timed out */ - if ((psCleanup->sCleanupThreadFn.ui32TimeEnd - psCleanup->sCleanupThreadFn.ui32TimeStart - 500) <= - (OSClockms() - psCleanup->sCleanupThreadFn.ui32TimeStart)) - { - /* Consider the operation is timed out */ - bFreeNow = IMG_TRUE; - } - } - - /* Free if the invalidate operation completed or the operation itself timed out */ - if (bFreeNow) - { - _FreeMMUMapping(psDevNode, &psCleanup->sMMUMappingHead); - - dllist_remove_node(&psCleanup->sMMUCtxCleanupItem); - OSFreeMem(psCleanup); - - eError = PVRSRV_OK; - } - else - { - eError = PVRSRV_ERROR_RETRY; - } - -e0: - - /* If this cleanup task has been successfully executed we can - * decrease the context cleanup data refcount. Successfully - * means here that the MMU_MEMORY_MAPPINGs have been freed by - * either this cleanup task of when the MMU context has been - * destroyed. */ - if (eError == PVRSRV_OK) - { - OSLockRelease(psMMUCtxCleanupData->hCleanupLock); - - if (OSAtomicDecrement(&psMMUCtxCleanupData->iRef) == 0) - { - OSLockDestroy(psMMUCtxCleanupData->hCleanupLock); - OSFreeMem(psMMUCtxCleanupData); - } - } - else - { - OSLockRelease(psMMUCtxCleanupData->hCleanupLock); - } - - - return eError; -} - -/*************************************************************************/ /*! -@Function _SetupCleanup_FreeMMUMapping - -@Description Setup a cleanup item for the cleanup thread that will - kick off a MMU invalidate request and free the associated - MMU_MEMORY_MAPPINGs when the invalidate was successful. - -@Input psPhysMemCtx The current MMU physmem context - */ -/*****************************************************************************/ -static void -_SetupCleanup_FreeMMUMapping(MMU_PHYSMEM_CONTEXT *psPhysMemCtx) -{ - - MMU_CLEANUP_ITEM *psCleanupItem; - MMU_CTX_CLEANUP_DATA *psCleanupData = psPhysMemCtx->psCleanupData; - PVRSRV_DEVICE_NODE *psDevNode = psPhysMemCtx->psDevNode; - - if (dllist_is_empty(&psPhysMemCtx->sTmpMMUMappingHead)) - { - goto e0; - } - -#if defined(PDUMP) - /* Free the page tables immediately in case of pdump, which avoids - * changing script files due to the additional invalidation kick */ - goto e1; -#endif - - /* Don't defer the freeing if we are currently unloading the driver - * or if the sync has been destroyed */ - if (PVRSRVGetPVRSRVData()->bUnload || - psDevNode->psMMUCacheSyncPrim == NULL) - { - goto e1; - } - - /* Allocate a cleanup item */ - psCleanupItem = OSAllocMem(sizeof(*psCleanupItem)); - if (!psCleanupItem) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to get memory for deferred page table cleanup. " - "Freeing tables immediately", - __func__)); - goto e1; - } - - /* Set sync to NULL to indicate we did not interact with - * the FW yet. Kicking off an MMU cache invalidate should - * be done in the cleanup thread to not waste time here. */ - psCleanupItem->psSync = NULL; - psCleanupItem->uiRequiredSyncVal = 0; - psCleanupItem->psDevNode = psDevNode; - psCleanupItem->psMMUCtxCleanupData = psCleanupData; - - OSAtomicIncrement(&psCleanupData->iRef); - - /* Move the page tables to free to the cleanup item */ - dllist_replace_head(&psPhysMemCtx->sTmpMMUMappingHead, - &psCleanupItem->sMMUMappingHead); - - /* Add the cleanup item itself to the context list */ - dllist_add_to_tail(&psCleanupData->sMMUCtxCleanupItemsHead, - &psCleanupItem->sMMUCtxCleanupItem); - - /* Setup the cleanup thread data and add the work item */ - psCleanupItem->sCleanupThreadFn.pfnFree = _CleanupThread_FreeMMUMapping; - psCleanupItem->sCleanupThreadFn.pvData = psCleanupItem; - psCleanupItem->sCleanupThreadFn.bDependsOnHW = IMG_TRUE; - CLEANUP_THREAD_SET_RETRY_TIMEOUT(&psCleanupItem->sCleanupThreadFn, - CLEANUP_THREAD_RETRY_TIMEOUT_MS_DEFAULT); - - PVRSRVCleanupThreadAddWork(&psCleanupItem->sCleanupThreadFn); - - return; - -e1: - /* Free the page tables now */ - _FreeMMUMapping(psDevNode, &psPhysMemCtx->sTmpMMUMappingHead); -e0: - return; -} - -/*************************************************************************/ /*! -@Function _CalcPCEIdx - -@Description Calculate the page catalogue index - -@Input sDevVAddr Device virtual address - -@Input psDevVAddrConfig Configuration of the virtual address - -@Input bRoundUp Round up the index - -@Return The page catalogue index - */ -/*****************************************************************************/ -static IMG_UINT32 _CalcPCEIdx(IMG_DEV_VIRTADDR sDevVAddr, - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig, - IMG_BOOL bRoundUp) -{ - IMG_DEV_VIRTADDR sTmpDevVAddr; - IMG_UINT32 ui32RetVal; - - sTmpDevVAddr = sDevVAddr; - - if (bRoundUp) - { - sTmpDevVAddr.uiAddr--; - } - ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPCIndexMask) - >> psDevVAddrConfig->uiPCIndexShift); - - if (bRoundUp) - { - ui32RetVal++; - } - - return ui32RetVal; -} - - -/*************************************************************************/ /*! -@Function _CalcPDEIdx - -@Description Calculate the page directory index - -@Input sDevVAddr Device virtual address - -@Input psDevVAddrConfig Configuration of the virtual address - -@Input bRoundUp Round up the index - -@Return The page directory index - */ -/*****************************************************************************/ -static IMG_UINT32 _CalcPDEIdx(IMG_DEV_VIRTADDR sDevVAddr, - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig, - IMG_BOOL bRoundUp) -{ - IMG_DEV_VIRTADDR sTmpDevVAddr; - IMG_UINT32 ui32RetVal; - - sTmpDevVAddr = sDevVAddr; - - if (bRoundUp) - { - sTmpDevVAddr.uiAddr--; - } - ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPDIndexMask) - >> psDevVAddrConfig->uiPDIndexShift); - - if (bRoundUp) - { - ui32RetVal++; - } - - return ui32RetVal; -} - - -/*************************************************************************/ /*! -@Function _CalcPTEIdx - -@Description Calculate the page entry index - -@Input sDevVAddr Device virtual address - -@Input psDevVAddrConfig Configuration of the virtual address - -@Input bRoundUp Round up the index - -@Return The page entry index - */ -/*****************************************************************************/ -static IMG_UINT32 _CalcPTEIdx(IMG_DEV_VIRTADDR sDevVAddr, - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig, - IMG_BOOL bRoundUp) -{ - IMG_DEV_VIRTADDR sTmpDevVAddr; - IMG_UINT32 ui32RetVal; - - sTmpDevVAddr = sDevVAddr; - sTmpDevVAddr.uiAddr -= psDevVAddrConfig->uiOffsetInBytes; - if (bRoundUp) - { - sTmpDevVAddr.uiAddr--; - } - ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPTIndexMask) - >> psDevVAddrConfig->uiPTIndexShift); - - if (bRoundUp) - { - ui32RetVal++; - } - - return ui32RetVal; -} - -#if defined(RGX_BRN71422_TARGET_HARDWARE_PHYSICAL_ADDR) -/* - * RGXMapBRN71422TargetPhysicalAddress - * - * Set-up a special MMU tree mapping with a single page that eventually points to - * RGX_BRN71422_TARGET_HARDWARE_PHYSICAL_ADDR. - * - * PC entries are 32b, with the last 4 bits being 0 except for the LSB bit that should be 1 (Valid). Addr is 4KB aligned. - * PD entries are 64b, with addr in bits 39:5 and everything else 0 except for LSB bit that is Valid. Addr is byte aligned? - * PT entries are 64b, with phy addr in bits 39:12 and everything else 0 except for LSB bit that is Valid. Addr is 4KB aligned. - * So, we can construct the page tables in a single page like this: - * 0x00 : PCE (PCE index 0) - * 0x04 : 0x0 - * 0x08 : PDEa (PDE index 1) - * 0x0C : PDEb - * 0x10 : PTEa (PTE index 2) - * 0x14 : PTEb - * - * With the PCE and the PDE pointing to this same page. - * The VA address that we are mapping is therefore: - * VA = PCE_idx*PCE_size + PDE_idx*PDE_size + PTE_idx*PTE_size = - * = 0 * 1GB + 1 * 2MB + 2 * 4KB = - * = 0 + 0x20_0000 + 0x2000 = - * = 0x00_0020_2000 - */ -void RGXMapBRN71422TargetPhysicalAddress(MMU_CONTEXT *psMMUContext) -{ - MMU_MEMORY_DESC *psMemDesc = &psMMUContext->sBaseLevelInfo.sMemDesc; - IMG_DEV_PHYADDR sPhysAddrPC = psMemDesc->sDevPAddr; - IMG_UINT32 *pui32Px = psMemDesc->pvCpuVAddr; - IMG_UINT64 *pui64Px = psMemDesc->pvCpuVAddr; - IMG_UINT64 ui64Entry; - - /* PCE points to PC */ - ui64Entry = sPhysAddrPC.uiAddr; - ui64Entry = ui64Entry >> RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT; - ui64Entry = ui64Entry << RGX_MMUCTRL_PC_DATA_PD_BASE_SHIFT; - ui64Entry = ui64Entry & ~RGX_MMUCTRL_PC_DATA_PD_BASE_CLRMSK; - ui64Entry = ui64Entry | RGX_MMUCTRL_PC_DATA_VALID_EN; - pui32Px[0] = (IMG_UINT32) ui64Entry; - - /* PDE points to PC */ - ui64Entry = sPhysAddrPC.uiAddr; - ui64Entry = ui64Entry & ~RGX_MMUCTRL_PD_DATA_PT_BASE_CLRMSK; - ui64Entry = ui64Entry | RGX_MMUCTRL_PD_DATA_VALID_EN; - pui64Px[1] = ui64Entry; - - /* PTE points to PAddr */ - ui64Entry = RGX_BRN71422_TARGET_HARDWARE_PHYSICAL_ADDR; - ui64Entry = ui64Entry & ~RGX_MMUCTRL_PT_DATA_PAGE_CLRMSK; - ui64Entry = ui64Entry | RGX_MMUCTRL_PT_DATA_VALID_EN; - pui64Px[2] = ui64Entry; - - { - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psMMUContext->psPhysMemCtx->psDevNode; - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psMemDesc->psMapping->sMemHandle, - psMemDesc->uiOffset, - psMemDesc->uiSize); - PVR_LOG_IF_ERROR(eError, "pfnDevPxClean"); - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapping the BRN71422 workaround to target physical address 0x%" IMG_UINT64_FMTSPECx ".", - __func__, RGX_BRN71422_TARGET_HARDWARE_PHYSICAL_ADDR)); -} -#endif - -/***************************************************************************** - * MMU memory allocation/management functions (mem desc) * - *****************************************************************************/ - -/*************************************************************************/ /*! -@Function _MMU_PhysMem_RAImportAlloc - -@Description Imports MMU Px memory into the RA. This is where the - actual allocation of physical memory happens. - -@Input hArenaHandle Handle that was passed in during the - creation of the RA - -@Input uiSize Size of the memory to import - -@Input uiFlags Flags that where passed in the allocation. - -@Output puiBase The address of where to insert this import - -@Output puiActualSize The actual size of the import - -@Output phPriv Handle which will be passed back when - this import is freed - -@Return PVRSRV_OK if import alloc was successful - */ -/*****************************************************************************/ -static PVRSRV_ERROR _MMU_PhysMem_RAImportAlloc(RA_PERARENA_HANDLE hArenaHandle, - RA_LENGTH_T uiSize, - RA_FLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *puiBase, - RA_LENGTH_T *puiActualSize, - RA_PERISPAN_HANDLE *phPriv) -{ - MMU_PHYSMEM_CONTEXT *psPhysMemCtx = (MMU_PHYSMEM_CONTEXT *)hArenaHandle; - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psPhysMemCtx->psDevNode; - MMU_MEMORY_MAPPING *psMapping; - PVRSRV_ERROR eError; - IMG_UINT32 uiPid = 0; - - PVR_UNREFERENCED_PARAMETER(pszAnnotation); - PVR_UNREFERENCED_PARAMETER(uiFlags); - - PVR_ASSERT(psDevNode != NULL); - PVR_GOTO_IF_INVALID_PARAM(psDevNode, eError, e0); - - psMapping = OSAllocMem(sizeof(MMU_MEMORY_MAPPING)); - PVR_GOTO_IF_NOMEM(psMapping, eError, e0); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - uiPid = psDevNode->eDevState == PVRSRV_DEVICE_STATE_INIT ? - PVR_SYS_ALLOC_PID : OSGetCurrentClientProcessIDKM(); -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* - * Store the OSid in the PG_HANDLE.uiOSid field for use by the - * pfnDevPxFree() routine. - */ - psMapping->sMemHandle.uiOSid = psPhysMemCtx->ui32OSid; - eError = PhysHeapPagesAllocGPV(psDevNode->psMMUPhysHeap, - TRUNCATE_64BITS_TO_SIZE_T(uiSize), - &psMapping->sMemHandle, - &psMapping->sDevPAddr, - psPhysMemCtx->ui32OSid, - uiPid); -#else - eError = PhysHeapPagesAlloc(psDevNode->psMMUPhysHeap, - TRUNCATE_64BITS_TO_SIZE_T(uiSize), - &psMapping->sMemHandle, - &psMapping->sDevPAddr, - uiPid); -#endif - if (eError != PVRSRV_OK) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRVStatsUpdateOOMStats(PVRSRV_PROCESS_STAT_TYPE_OOM_PHYSMEM_COUNT, - OSGetCurrentClientProcessIDKM()); -#endif - goto e1; - } - - psMapping->psContext = psPhysMemCtx; - psMapping->uiSize = TRUNCATE_64BITS_TO_SIZE_T(uiSize); - - psMapping->uiCpuVAddrRefCount = 0; - - *phPriv = (RA_PERISPAN_HANDLE) psMapping; - - /* Note: This assumes this memory never gets paged out */ - *puiBase = (RA_BASE_T)psMapping->sDevPAddr.uiAddr; - *puiActualSize = uiSize; - - return PVRSRV_OK; - -e1: - OSFreeMem(psMapping); -e0: - return eError; -} - -/*************************************************************************/ /*! -@Function _MMU_PhysMem_RAImportFree - -@Description Imports MMU Px memory into the RA. This is where the - actual free of physical memory happens. - -@Input hArenaHandle Handle that was passed in during the - creation of the RA - -@Input puiBase The address of where to insert this import - -@Output phPriv Private data that the import alloc provided - -@Return None - */ -/*****************************************************************************/ -static void _MMU_PhysMem_RAImportFree(RA_PERARENA_HANDLE hArenaHandle, - RA_BASE_T uiBase, - RA_PERISPAN_HANDLE hPriv) -{ - MMU_MEMORY_MAPPING *psMapping = (MMU_MEMORY_MAPPING *)hPriv; - MMU_PHYSMEM_CONTEXT *psPhysMemCtx = (MMU_PHYSMEM_CONTEXT *)hArenaHandle; - - PVR_UNREFERENCED_PARAMETER(uiBase); - - /* Check we have dropped all CPU mappings */ - PVR_ASSERT(psMapping->uiCpuVAddrRefCount == 0); - - /* Add mapping to defer free list */ - psMapping->psContext = NULL; - dllist_add_to_tail(&psPhysMemCtx->sTmpMMUMappingHead, &psMapping->sMMUMappingItem); -} - -/*************************************************************************/ /*! -@Function _MMU_PhysMemAlloc - -@Description Allocates physical memory for MMU objects - -@Input psPhysMemCtx Physmem context to do the allocation from - -@Output psMemDesc Allocation description - -@Input uiBytes Size of the allocation in bytes - -@Input uiAlignment Alignment requirement of this allocation - -@Return PVRSRV_OK if allocation was successful - */ -/*****************************************************************************/ - -static PVRSRV_ERROR _MMU_PhysMemAlloc(MMU_PHYSMEM_CONTEXT *psPhysMemCtx, - MMU_MEMORY_DESC *psMemDesc, - size_t uiBytes, - size_t uiAlignment) -{ - PVRSRV_ERROR eError; - RA_BASE_T uiPhysAddr; - - PVR_RETURN_IF_INVALID_PARAM(psMemDesc); - PVR_RETURN_IF_INVALID_PARAM(!psMemDesc->bValid); - - eError = RA_Alloc(psPhysMemCtx->psPhysMemRA, - uiBytes, - RA_NO_IMPORT_MULTIPLIER, - 0, /* flags */ - uiAlignment, - "", - &uiPhysAddr, - NULL, - (RA_PERISPAN_HANDLE *)&psMemDesc->psMapping); - - PVR_LOG_RETURN_IF_ERROR(eError, "RA_Alloc"); - - psMemDesc->bValid = IMG_TRUE; - psMemDesc->pvCpuVAddr = NULL; - psMemDesc->sDevPAddr.uiAddr = (IMG_UINT64) uiPhysAddr; - - if (psMemDesc->psMapping->uiCpuVAddrRefCount == 0) - { - eError = PhysHeapPagesMap(psPhysMemCtx->psDevNode->psMMUPhysHeap, - &psMemDesc->psMapping->sMemHandle, - psMemDesc->psMapping->uiSize, - &psMemDesc->psMapping->sDevPAddr, - &psMemDesc->psMapping->pvCpuVAddr); - if (eError != PVRSRV_OK) - { - RA_Free(psPhysMemCtx->psPhysMemRA, psMemDesc->sDevPAddr.uiAddr); - return eError; - } - } - - psMemDesc->psMapping->uiCpuVAddrRefCount++; - psMemDesc->uiOffset = (psMemDesc->sDevPAddr.uiAddr - psMemDesc->psMapping->sDevPAddr.uiAddr); - psMemDesc->pvCpuVAddr = (IMG_UINT8 *)psMemDesc->psMapping->pvCpuVAddr + psMemDesc->uiOffset; - psMemDesc->uiSize = uiBytes; - PVR_ASSERT(psMemDesc->pvCpuVAddr != NULL); - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function _MMU_PhysMemFree - -@Description Allocates physical memory for MMU objects - -@Input psPhysMemCtx Physmem context to do the free on - -@Input psMemDesc Allocation description - -@Return None - */ -/*****************************************************************************/ -static void _MMU_PhysMemFree(MMU_PHYSMEM_CONTEXT *psPhysMemCtx, - MMU_MEMORY_DESC *psMemDesc) -{ - RA_BASE_T uiPhysAddr; - - PVR_ASSERT(psMemDesc->bValid); - - if (--psMemDesc->psMapping->uiCpuVAddrRefCount == 0) - { - PhysHeapPagesUnMap(psPhysMemCtx->psDevNode->psMMUPhysHeap, - &psMemDesc->psMapping->sMemHandle, - psMemDesc->psMapping->pvCpuVAddr); - } - - psMemDesc->pvCpuVAddr = NULL; - - uiPhysAddr = psMemDesc->sDevPAddr.uiAddr; - RA_Free(psPhysMemCtx->psPhysMemRA, uiPhysAddr); - - psMemDesc->bValid = IMG_FALSE; -} - - -/***************************************************************************** - * MMU object allocation/management functions * - *****************************************************************************/ - -static INLINE PVRSRV_ERROR _MMU_ConvertDevMemFlags(IMG_BOOL bInvalidate, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - MMU_PROTFLAGS_T *uiMMUProtFlags, - MMU_CONTEXT *psMMUContext) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 uiGPUCacheMode; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - /* Do flag conversion between devmem flags and MMU generic flags */ - if (bInvalidate == IMG_FALSE) - { - *uiMMUProtFlags |= ((uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK) - >> PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET) - << MMU_PROTFLAGS_DEVICE_OFFSET; - - if (PVRSRV_CHECK_GPU_READABLE(uiMappingFlags)) - { - *uiMMUProtFlags |= MMU_PROTFLAGS_READABLE; - } - if (PVRSRV_CHECK_GPU_WRITEABLE(uiMappingFlags)) - { - *uiMMUProtFlags |= MMU_PROTFLAGS_WRITEABLE; - } - - eError = DevmemDeviceCacheMode(psDevNode, uiMappingFlags, &uiGPUCacheMode); - PVR_RETURN_IF_ERROR(eError); - - switch (uiGPUCacheMode) - { - case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED: - case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC: - break; - case PVRSRV_MEMALLOCFLAG_GPU_CACHED: - *uiMMUProtFlags |= MMU_PROTFLAGS_CACHED; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Wrong parameters", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (DevmemDeviceCacheCoherency(psDevNode, uiMappingFlags)) - { - *uiMMUProtFlags |= MMU_PROTFLAGS_CACHE_COHERENT; - } - /* Only compile if RGX_FEATURE_MIPS_BIT_MASK is defined to avoid compilation - * errors on volcanic cores. - */ - #if defined(SUPPORT_RGX) && defined(RGX_FEATURE_MIPS_BIT_MASK) - if ((psDevNode->pfnCheckDeviceFeature) && - PVRSRV_IS_FEATURE_SUPPORTED(psDevNode, MIPS)) - { - /* If we are allocating on the MMU of the firmware processor, the - * cached/uncached attributes must depend on the FIRMWARE_CACHED - * allocation flag. - */ - if (psMMUContext->psDevAttrs == psDevNode->psFirmwareMMUDevAttrs) - { - if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)) - { - *uiMMUProtFlags |= MMU_PROTFLAGS_CACHED; - } - else - { - *uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHED; - - } - *uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHE_COHERENT; - } - } -#endif - } - else - { - *uiMMUProtFlags |= MMU_PROTFLAGS_INVALID; - } - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function _PxMemAlloc - -@Description Allocates physical memory for MMU objects, initialises - and PDumps it. - -@Input psMMUContext MMU context - -@Input uiNumEntries Number of entries to allocate - -@Input psConfig MMU Px config - -@Input eMMULevel MMU level that that allocation is for - -@Output psMemDesc Description of allocation - -@Return PVRSRV_OK if allocation was successful - */ -/*****************************************************************************/ -static PVRSRV_ERROR _PxMemAlloc(MMU_CONTEXT *psMMUContext, - IMG_UINT32 uiNumEntries, - const MMU_PxE_CONFIG *psConfig, - MMU_LEVEL eMMULevel, - MMU_MEMORY_DESC *psMemDesc, - IMG_UINT32 uiLog2Align) -{ - PVRSRV_ERROR eError; - size_t uiBytes; - size_t uiAlign; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - PVR_ASSERT(psConfig->uiBytesPerEntry != 0); - - uiBytes = uiNumEntries * psConfig->uiBytesPerEntry; - /* We need here the alignment of the previous level because that is the entry for we generate here */ - uiAlign = 1 << uiLog2Align; - - /* - * If the hardware specifies an alignment requirement for a page table then - * it also requires that all memory up to the next aligned address is - * zeroed. - * - * Failing to do this can result in uninitialised data outside of the actual - * page table range being read by the MMU and treated as valid, e.g. the - * pending flag. - * - * Typically this will affect 1MiB, 2MiB PT pages which have a size of 16 - * and 8 bytes respectively but an alignment requirement of 64 bytes each. - */ - uiBytes = PVR_ALIGN(uiBytes, uiAlign); - - /* allocate the object */ - eError = _MMU_PhysMemAlloc(psMMUContext->psPhysMemCtx, - psMemDesc, uiBytes, uiAlign); - if (eError != PVRSRV_OK) - { - PVR_LOG_GOTO_WITH_ERROR("_MMU_PhysMemAlloc", eError, PVRSRV_ERROR_OUT_OF_MEMORY, e0); - } - - /* - Clear the object - Note: if any MMUs are cleared with non-zero values then will need a - custom clear function - Note: 'Cached' is wrong for the LMA + ARM64 combination, but this is - unlikely - */ - OSCachedMemSet(psMemDesc->pvCpuVAddr, 0, uiBytes); - - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psMemDesc->psMapping->sMemHandle, - psMemDesc->uiOffset, - psMemDesc->uiSize); - PVR_GOTO_IF_ERROR(eError, e1); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, "Alloc MMU object"); - - PDumpMMUMalloc(psDevNode, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - eMMULevel, - &psMemDesc->sDevPAddr, - uiBytes, - uiAlign, - psMMUContext->psDevAttrs->eMMUType); - - PDumpMMUDumpPxEntries(psDevNode, - eMMULevel, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - psMemDesc->pvCpuVAddr, - psMemDesc->sDevPAddr, - 0, - uiNumEntries, - NULL, NULL, 0, /* pdump symbolic info is irrelevant here */ - psConfig->uiBytesPerEntry, - uiLog2Align, - psConfig->uiAddrShift, - psConfig->uiAddrMask, - psConfig->uiProtMask, - psConfig->uiValidEnMask, - 0, - psMMUContext->psDevAttrs->eMMUType); -#endif - - return PVRSRV_OK; -e1: - _MMU_PhysMemFree(psMMUContext->psPhysMemCtx, - psMemDesc); -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/*************************************************************************/ /*! -@Function _PxMemFree - -@Description Frees physical memory for MMU objects, de-initialises - and PDumps it. - -@Input psMemDesc Description of allocation - -@Return PVRSRV_OK if allocation was successful - */ -/*****************************************************************************/ - -static void _PxMemFree(MMU_CONTEXT *psMMUContext, - MMU_MEMORY_DESC *psMemDesc, MMU_LEVEL eMMULevel) -{ -#if defined(MMU_CLEARMEM_ON_FREE) - /* - Clear the MMU object - Note: if any MMUs are cleared with non-zero values then will need a - custom clear function - Note: 'Cached' is wrong for the LMA + ARM64 combination, but this is - unlikely - */ - OSCachedMemSet(psMemDesc->pvCpuVAddr, 0, psMemDesc->ui32Bytes); - -#if defined(PDUMP) - PDUMPCOMMENT(psMMUContext->psPhysMemCtx->psDevNode, "Clear MMU object before freeing it"); -#endif -#endif/* MMU_CLEARMEM_ON_FREE */ - -#if defined(PDUMP) - PDUMPCOMMENT(psMMUContext->psPhysMemCtx->psDevNode, "Free MMU object"); - PDumpMMUFree(psMMUContext->psPhysMemCtx->psDevNode, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - eMMULevel, - &psMemDesc->sDevPAddr, - psMMUContext->psDevAttrs->eMMUType); -#else - PVR_UNREFERENCED_PARAMETER(eMMULevel); -#endif - /* free the PC */ - _MMU_PhysMemFree(psMMUContext->psPhysMemCtx, psMemDesc); -} - -static INLINE PVRSRV_ERROR _SetupPTE(MMU_CONTEXT *psMMUContext, - MMU_Levelx_INFO *psLevel, - IMG_UINT32 uiIndex, - const MMU_PxE_CONFIG *psConfig, - const IMG_DEV_PHYADDR *psDevPAddr, - IMG_BOOL bUnmap, -#if defined(PDUMP) - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset, -#endif - IMG_UINT64 uiProtFlags) -{ - MMU_MEMORY_DESC *psMemDesc = &psLevel->sMemDesc; - IMG_UINT64 ui64PxE64; - IMG_UINT64 uiAddr = psDevPAddr->uiAddr; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - if (psDevNode->pfnValidateOrTweakPhysAddrs) - { - PVRSRV_ERROR eErr = psDevNode->pfnValidateOrTweakPhysAddrs(psDevNode, - psMMUContext->psDevAttrs, - &uiAddr); - /* return if error */ - PVR_LOG_RETURN_IF_ERROR(eErr, "_SetupPTE"); - } - - /* Calculate Entry */ - ui64PxE64 = uiAddr /* Calculate the offset to that base */ - >> psConfig->uiAddrLog2Align /* Shift away the useless bits, because the alignment is very coarse and we address by alignment */ - << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */ - & psConfig->uiAddrMask; /* Delete unused bits */ - ui64PxE64 |= uiProtFlags; - - /* Set the entry */ - if (psConfig->uiBytesPerEntry == 8) - { - IMG_UINT64 *pui64Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */ - - pui64Px[uiIndex] = ui64PxE64; - } - else if (psConfig->uiBytesPerEntry == 4) - { - IMG_UINT32 *pui32Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */ - - /* assert that the result fits into 32 bits before writing - it into the 32-bit array with a cast */ - PVR_ASSERT(ui64PxE64 == (ui64PxE64 & 0xffffffffU)); - - pui32Px[uiIndex] = (IMG_UINT32) ui64PxE64; - } - else - { - return PVRSRV_ERROR_MMU_CONFIG_IS_WRONG; - } - - - /* Log modification */ - HTBLOGK(HTB_SF_MMU_PAGE_OP_TABLE, - HTBLOG_PTR_BITS_HIGH(psLevel), HTBLOG_PTR_BITS_LOW(psLevel), - uiIndex, MMU_LEVEL_1, - HTBLOG_U64_BITS_HIGH(ui64PxE64), HTBLOG_U64_BITS_LOW(ui64PxE64), - !bUnmap); - -#if defined(PDUMP) - PDumpMMUDumpPxEntries(psDevNode, - MMU_LEVEL_1, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - psMemDesc->pvCpuVAddr, - psMemDesc->sDevPAddr, - uiIndex, - 1, - pszMemspaceName, - pszSymbolicAddr, - uiSymbolicAddrOffset, - psConfig->uiBytesPerEntry, - psConfig->uiAddrLog2Align, - psConfig->uiAddrShift, - psConfig->uiAddrMask, - psConfig->uiProtMask, - psConfig->uiValidEnMask, - 0, - psMMUContext->psDevAttrs->eMMUType); -#endif /*PDUMP*/ - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function _SetupPxE - -@Description Sets up an entry of an MMU object to point to the - provided address - -@Input psMMUContext MMU context to operate on - -@Input psLevel Level info for MMU object - -@Input uiIndex Index into the MMU object to setup - -@Input psConfig MMU Px config - -@Input eMMULevel Level of MMU object - -@Input psDevPAddr Address to setup the MMU object to point to - -@Input pszMemspaceName Name of the PDump memory space that the entry - will point to - -@Input pszSymbolicAddr PDump symbolic address that the entry will - point to - -@Input uiProtFlags MMU protection flags - -@Return PVRSRV_OK if the setup was successful - */ -/*****************************************************************************/ -static PVRSRV_ERROR _SetupPxE(MMU_CONTEXT *psMMUContext, - MMU_Levelx_INFO *psLevel, - IMG_UINT32 uiIndex, - const MMU_PxE_CONFIG *psConfig, - MMU_LEVEL eMMULevel, - const IMG_DEV_PHYADDR *psDevPAddr, -#if defined(PDUMP) - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset, -#endif - MMU_PROTFLAGS_T uiProtFlags, - IMG_UINT32 uiLog2DataPageSize) -{ - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - MMU_MEMORY_DESC *psMemDesc = &psLevel->sMemDesc; - - IMG_UINT32 (*pfnDerivePxEProt4)(IMG_UINT32); - IMG_UINT64 (*pfnDerivePxEProt8)(IMG_UINT32, IMG_UINT32); - - if (!psDevPAddr) - { - /* Invalidate entry */ - if (~uiProtFlags & MMU_PROTFLAGS_INVALID) - { - PVR_DPF((PVR_DBG_ERROR, "Error, no physical address specified, but not invalidating entry")); - uiProtFlags |= MMU_PROTFLAGS_INVALID; - } - psDevPAddr = &gsBadDevPhyAddr; - } - else - { - if (uiProtFlags & MMU_PROTFLAGS_INVALID) - { - PVR_DPF((PVR_DBG_ERROR, "A physical address was specified when requesting invalidation of entry")); - uiProtFlags |= MMU_PROTFLAGS_INVALID; - } - } - - switch (eMMULevel) - { - case MMU_LEVEL_3: - pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePCEProt4; - pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePCEProt8; - break; - - case MMU_LEVEL_2: - pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePDEProt4; - pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePDEProt8; - break; - - case MMU_LEVEL_1: - pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePTEProt4; - pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePTEProt8; - break; - - default: - PVR_DPF((PVR_DBG_ERROR, "%s: invalid MMU level", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* How big is a PxE in bytes? */ - /* Filling the actual Px entry with an address */ - switch (psConfig->uiBytesPerEntry) - { - case 4: - { - IMG_UINT32 *pui32Px; - IMG_UINT64 ui64PxE64; - - pui32Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */ - - ui64PxE64 = psDevPAddr->uiAddr /* Calculate the offset to that base */ - >> psConfig->uiAddrLog2Align /* Shift away the unnecessary bits of the address */ - << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */ - & psConfig->uiAddrMask; /* Delete unused higher bits */ - - ui64PxE64 |= (IMG_UINT64)pfnDerivePxEProt4(uiProtFlags); - /* assert that the result fits into 32 bits before writing - it into the 32-bit array with a cast */ - PVR_ASSERT(ui64PxE64 == (ui64PxE64 & 0xffffffffU)); - - /* We should never invalidate an invalid page */ - if (uiProtFlags & MMU_PROTFLAGS_INVALID) - { - PVR_ASSERT(pui32Px[uiIndex] != ui64PxE64); - } - pui32Px[uiIndex] = (IMG_UINT32) ui64PxE64; - HTBLOGK(HTB_SF_MMU_PAGE_OP_TABLE, - HTBLOG_PTR_BITS_HIGH(psLevel), HTBLOG_PTR_BITS_LOW(psLevel), - uiIndex, eMMULevel, - HTBLOG_U64_BITS_HIGH(ui64PxE64), HTBLOG_U64_BITS_LOW(ui64PxE64), - (uiProtFlags & MMU_PROTFLAGS_INVALID)? 0: 1); - break; - } - case 8: - { - IMG_UINT64 *pui64Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */ - - pui64Px[uiIndex] = psDevPAddr->uiAddr /* Calculate the offset to that base */ - >> psConfig->uiAddrLog2Align /* Shift away the unnecessary bits of the address */ - << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */ - & psConfig->uiAddrMask; /* Delete unused higher bits */ - pui64Px[uiIndex] |= pfnDerivePxEProt8(uiProtFlags, uiLog2DataPageSize); - - HTBLOGK(HTB_SF_MMU_PAGE_OP_TABLE, - HTBLOG_PTR_BITS_HIGH(psLevel), HTBLOG_PTR_BITS_LOW(psLevel), - uiIndex, eMMULevel, - HTBLOG_U64_BITS_HIGH(pui64Px[uiIndex]), HTBLOG_U64_BITS_LOW(pui64Px[uiIndex]), - (uiProtFlags & MMU_PROTFLAGS_INVALID)? 0: 1); - break; - } - default: - PVR_DPF((PVR_DBG_ERROR, "%s: PxE size not supported (%d) for level %d", - __func__, psConfig->uiBytesPerEntry, eMMULevel)); - - return PVRSRV_ERROR_MMU_CONFIG_IS_WRONG; - } - -#if defined(PDUMP) - PDumpMMUDumpPxEntries(psDevNode, - eMMULevel, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - psMemDesc->pvCpuVAddr, - psMemDesc->sDevPAddr, - uiIndex, - 1, - pszMemspaceName, - pszSymbolicAddr, - uiSymbolicAddrOffset, - psConfig->uiBytesPerEntry, - psConfig->uiAddrLog2Align, - psConfig->uiAddrShift, - psConfig->uiAddrMask, - psConfig->uiProtMask, - psConfig->uiValidEnMask, - 0, - psMMUContext->psDevAttrs->eMMUType); -#endif - - psDevNode->pfnMMUCacheInvalidate(psDevNode, psMMUContext, - eMMULevel, - uiProtFlags & MMU_PROTFLAGS_INVALID); - - return PVRSRV_OK; -} - -/***************************************************************************** - * MMU host control functions (Level Info) * - *****************************************************************************/ - - -/*************************************************************************/ /*! -@Function _MMU_FreeLevel - -@Description Recursively frees the specified range of Px entries. If any - level has its last reference dropped then the MMU object - memory and the MMU_Levelx_Info will be freed. - - At each level we might be crossing a boundary from one Px to - another. The values for auiStartArray should be by used for - the first call into each level and the values in auiEndArray - should only be used in the last call for each level. - In order to determine if this is the first/last call we pass - in bFirst and bLast. - When one level calls down to the next only if bFirst/bLast is set - and it's the first/last iteration of the loop at its level will - bFirst/bLast set for the next recursion. - This means that each iteration has the knowledge of the previous - level which is required. - -@Input psMMUContext MMU context to operate on - -@Input psLevel Level info on which to free the - specified range - -@Input auiStartArray Array of start indexes (one for each level) - -@Input auiEndArray Array of end indexes (one for each level) - -@Input auiEntriesPerPxArray Array of number of entries for the Px - (one for each level) - -@Input apsConfig Array of PxE configs (one for each level) - -@Input aeMMULevel Array of MMU levels (one for each level) - -@Input pui32CurrentLevel Pointer to a variable which is set to our - current level - -@Input uiStartIndex Start index of the range to free - -@Input uiEndIndex End index of the range to free - -@Input bFirst This is the first call for this level - -@Input bLast This is the last call for this level - -@Return IMG_TRUE if the last reference to psLevel was dropped - */ -/*****************************************************************************/ -static IMG_BOOL _MMU_FreeLevel(MMU_CONTEXT *psMMUContext, - MMU_Levelx_INFO *psLevel, - IMG_UINT32 auiStartArray[], - IMG_UINT32 auiEndArray[], - IMG_UINT32 auiEntriesPerPxArray[], - const MMU_PxE_CONFIG *apsConfig[], - MMU_LEVEL aeMMULevel[], - IMG_UINT32 *pui32CurrentLevel, - IMG_UINT32 uiStartIndex, - IMG_UINT32 uiEndIndex, - IMG_BOOL bFirst, - IMG_BOOL bLast, - IMG_UINT32 uiLog2DataPageSize) -{ - IMG_UINT32 uiThisLevel = *pui32CurrentLevel; - const MMU_PxE_CONFIG *psConfig = apsConfig[uiThisLevel]; - IMG_UINT32 i; - IMG_BOOL bFreed = IMG_FALSE; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - /* Parameter checks */ - PVR_ASSERT(*pui32CurrentLevel < MMU_MAX_LEVEL); - PVR_ASSERT(psLevel != NULL); - - MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_FreeLevel: level = %d, range %d - %d, refcount = %d", - aeMMULevel[uiThisLevel], uiStartIndex, - uiEndIndex, psLevel->ui32RefCount)); - - for (i = uiStartIndex;(i < uiEndIndex) && (psLevel != NULL);i++) - { - if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1) - { - MMU_Levelx_INFO *psNextLevel = psLevel->apsNextLevel[i]; - IMG_UINT32 uiNextStartIndex; - IMG_UINT32 uiNextEndIndex; - IMG_BOOL bNextFirst; - IMG_BOOL bNextLast; - - /* If we're crossing a Px then the start index changes */ - if (bFirst && (i == uiStartIndex)) - { - uiNextStartIndex = auiStartArray[uiThisLevel + 1]; - bNextFirst = IMG_TRUE; - } - else - { - uiNextStartIndex = 0; - bNextFirst = IMG_FALSE; - } - - /* If we're crossing a Px then the end index changes */ - if (bLast && (i == (uiEndIndex - 1))) - { - uiNextEndIndex = auiEndArray[uiThisLevel + 1]; - bNextLast = IMG_TRUE; - } - else - { - uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1]; - bNextLast = IMG_FALSE; - } - - /* Recurse into the next level */ - (*pui32CurrentLevel)++; - if (_MMU_FreeLevel(psMMUContext, psNextLevel, auiStartArray, - auiEndArray, auiEntriesPerPxArray, - apsConfig, aeMMULevel, pui32CurrentLevel, - uiNextStartIndex, uiNextEndIndex, - bNextFirst, bNextLast, uiLog2DataPageSize)) - { - PVRSRV_ERROR eError; - - /* Un-wire the entry */ - eError = _SetupPxE(psMMUContext, - psLevel, - i, - psConfig, - aeMMULevel[uiThisLevel], - NULL, -#if defined(PDUMP) - NULL, /* Only required for data page */ - NULL, /* Only required for data page */ - 0, /* Only required for data page */ -#endif - MMU_PROTFLAGS_INVALID, - uiLog2DataPageSize); - - PVR_ASSERT(eError == PVRSRV_OK); - - /* Free table of the level below, pointed to by this table entry. - * We don't destroy the table inside the above _MMU_FreeLevel call because we - * first have to set the table entry of the level above to invalid. */ - _PxMemFree(psMMUContext, &psNextLevel->sMemDesc, aeMMULevel[*pui32CurrentLevel]); - OSFreeMem(psNextLevel); - - /* The level below us is empty, drop the refcount and clear the pointer */ - psLevel->ui32RefCount--; - psLevel->apsNextLevel[i] = NULL; - - /* Check we haven't wrapped around */ - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - } - (*pui32CurrentLevel)--; - } - else - { - psLevel->ui32RefCount--; - } - - /* - Free this level if it is no longer referenced, unless it's the base - level in which case it's part of the MMU context and should be freed - when the MMU context is freed - */ - if ((psLevel->ui32RefCount == 0) && (psLevel != &psMMUContext->sBaseLevelInfo)) - { - bFreed = IMG_TRUE; - } - } - - /* Level one flushing is done when we actually write the table entries */ - if ((aeMMULevel[uiThisLevel] != MMU_LEVEL_1) && (psLevel != NULL)) - { - PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiStartIndex * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiEndIndex - uiStartIndex) * psConfig->uiBytesPerEntry); - } - - MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_FreeLevel end: level = %d, refcount = %d", - aeMMULevel[uiThisLevel], bFreed?0: (psLevel)?psLevel->ui32RefCount:-1)); - - return bFreed; -} - -/*************************************************************************/ /*! -@Function _MMU_AllocLevel - -@Description Recursively allocates the specified range of Px entries. If any - level has its last reference dropped then the MMU object - memory and the MMU_Levelx_Info will be freed. - - At each level we might be crossing a boundary from one Px to - another. The values for auiStartArray should be by used for - the first call into each level and the values in auiEndArray - should only be used in the last call for each level. - In order to determine if this is the first/last call we pass - in bFirst and bLast. - When one level calls down to the next only if bFirst/bLast is set - and it's the first/last iteration of the loop at its level will - bFirst/bLast set for the next recursion. - This means that each iteration has the knowledge of the previous - level which is required. - -@Input psMMUContext MMU context to operate on - -@Input psLevel Level info on which to free the - specified range - -@Input auiStartArray Array of start indexes (one for each level) - -@Input auiEndArray Array of end indexes (one for each level) - -@Input auiEntriesPerPxArray Array of number of entries for the Px - (one for each level) - -@Input apsConfig Array of PxE configs (one for each level) - -@Input aeMMULevel Array of MMU levels (one for each level) - -@Input pui32CurrentLevel Pointer to a variable which is set to our - current level - -@Input uiStartIndex Start index of the range to free - -@Input uiEndIndex End index of the range to free - -@Input bFirst This is the first call for this level - -@Input bLast This is the last call for this level - -@Return IMG_TRUE if the last reference to psLevel was dropped - */ -/*****************************************************************************/ -static PVRSRV_ERROR _MMU_AllocLevel(MMU_CONTEXT *psMMUContext, - MMU_Levelx_INFO *psLevel, - IMG_UINT32 auiStartArray[], - IMG_UINT32 auiEndArray[], - IMG_UINT32 auiEntriesPerPxArray[], - const MMU_PxE_CONFIG *apsConfig[], - MMU_LEVEL aeMMULevel[], - IMG_UINT32 *pui32CurrentLevel, - IMG_UINT32 uiStartIndex, - IMG_UINT32 uiEndIndex, - IMG_BOOL bFirst, - IMG_BOOL bLast, - IMG_UINT32 uiLog2DataPageSize) -{ - IMG_UINT32 uiThisLevel = *pui32CurrentLevel; /* Starting with 0 */ - const MMU_PxE_CONFIG *psConfig = apsConfig[uiThisLevel]; /* The table config for the current level */ - PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY; - IMG_UINT32 uiAllocState = 99; /* Debug info to check what progress was made in the function. Updated during this function. */ - IMG_UINT32 i; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - /* Parameter check */ - PVR_ASSERT(*pui32CurrentLevel < MMU_MAX_LEVEL); - - MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_AllocLevel: level = %d, range %d - %d, refcount = %d", - aeMMULevel[uiThisLevel], uiStartIndex, - uiEndIndex, psLevel->ui32RefCount)); - - /* Go from uiStartIndex to uiEndIndex through the Px */ - for (i = uiStartIndex;i < uiEndIndex;i++) - { - /* Only try an allocation if this is not the last level */ - /*Because a PT allocation is already done while setting the entry in PD */ - if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1) - { - IMG_UINT32 uiNextStartIndex; - IMG_UINT32 uiNextEndIndex; - IMG_BOOL bNextFirst; - IMG_BOOL bNextLast; - - /* If there is already a next Px level existing, do not allocate it */ - if (!psLevel->apsNextLevel[i]) - { - MMU_Levelx_INFO *psNextLevel; - IMG_UINT32 ui32AllocSize; - IMG_UINT32 uiNextEntries; - - /* Allocate and setup the next level */ - uiNextEntries = auiEntriesPerPxArray[uiThisLevel + 1]; - ui32AllocSize = sizeof(MMU_Levelx_INFO); - if (aeMMULevel[uiThisLevel + 1] != MMU_LEVEL_1) - { - ui32AllocSize += sizeof(MMU_Levelx_INFO *) * (uiNextEntries - 1); - } - psNextLevel = OSAllocZMem(ui32AllocSize); - if (psNextLevel == NULL) - { - uiAllocState = 0; - goto e0; - } - - /* Hook in this level for next time */ - psLevel->apsNextLevel[i] = psNextLevel; - - psNextLevel->ui32NumOfEntries = uiNextEntries; - psNextLevel->ui32RefCount = 0; - /* Allocate Px memory for a sub level*/ - eError = _PxMemAlloc(psMMUContext, uiNextEntries, apsConfig[uiThisLevel + 1], - aeMMULevel[uiThisLevel + 1], - &psNextLevel->sMemDesc, - psConfig->uiAddrLog2Align); - if (eError != PVRSRV_OK) - { - uiAllocState = 1; - goto e0; - } - - /* Wire up the entry */ - eError = _SetupPxE(psMMUContext, - psLevel, - i, - psConfig, - aeMMULevel[uiThisLevel], - &psNextLevel->sMemDesc.sDevPAddr, -#if defined(PDUMP) - NULL, /* Only required for data page */ - NULL, /* Only required for data page */ - 0, /* Only required for data page */ -#endif - 0, - uiLog2DataPageSize); - - if (eError != PVRSRV_OK) - { - uiAllocState = 2; - goto e0; - } - - psLevel->ui32RefCount++; - } - - /* If we're crossing a Px then the start index changes */ - if (bFirst && (i == uiStartIndex)) - { - uiNextStartIndex = auiStartArray[uiThisLevel + 1]; - bNextFirst = IMG_TRUE; - } - else - { - uiNextStartIndex = 0; - bNextFirst = IMG_FALSE; - } - - /* If we're crossing a Px then the end index changes */ - if (bLast && (i == (uiEndIndex - 1))) - { - uiNextEndIndex = auiEndArray[uiThisLevel + 1]; - bNextLast = IMG_TRUE; - } - else - { - uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1]; - bNextLast = IMG_FALSE; - } - - /* Recurse into the next level */ - (*pui32CurrentLevel)++; - eError = _MMU_AllocLevel(psMMUContext, psLevel->apsNextLevel[i], - auiStartArray, - auiEndArray, - auiEntriesPerPxArray, - apsConfig, - aeMMULevel, - pui32CurrentLevel, - uiNextStartIndex, - uiNextEndIndex, - bNextFirst, - bNextLast, - uiLog2DataPageSize); - (*pui32CurrentLevel)--; - if (eError != PVRSRV_OK) - { - uiAllocState = 2; - goto e0; - } - } - else - { - /* All we need to do for level 1 is bump the refcount */ - psLevel->ui32RefCount++; - } - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - } - - /* Level one flushing is done when we actually write the table entries */ - if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1) - { - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiStartIndex * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiEndIndex - uiStartIndex) * psConfig->uiBytesPerEntry); - PVR_GOTO_IF_ERROR(eError, e0); - } - - MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_AllocLevel end: level = %d, refcount = %d", - aeMMULevel[uiThisLevel], psLevel->ui32RefCount)); - return PVRSRV_OK; - -e0: - /* Confirm that we've not come down this route unexpectedly */ - PVR_ASSERT(uiAllocState!=99); - PVR_DPF((PVR_DBG_ERROR, "_MMU_AllocLevel: Error %d allocating Px for level %d in stage %d" - ,eError, aeMMULevel[uiThisLevel], uiAllocState)); - - /* The start value of index variable i is not initialised on purpose. - * This clean-up loop deinitialises what was already initialised in - * reverse order, so the i index already has the correct value. - */ - for (/* i already set */; i>= uiStartIndex && i< uiEndIndex; i--) - { - switch (uiAllocState) - { - IMG_UINT32 uiNextStartIndex; - IMG_UINT32 uiNextEndIndex; - IMG_BOOL bNextFirst; - IMG_BOOL bNextLast; - - case 3: - /* If we're crossing a Px then the start index changes */ - if (bFirst && (i == uiStartIndex)) - { - uiNextStartIndex = auiStartArray[uiThisLevel + 1]; - bNextFirst = IMG_TRUE; - } - else - { - uiNextStartIndex = 0; - bNextFirst = IMG_FALSE; - } - - /* If we're crossing a Px then the end index changes */ - if (bLast && (i == (uiEndIndex - 1))) - { - uiNextEndIndex = auiEndArray[uiThisLevel + 1]; - bNextLast = IMG_TRUE; - } - else - { - uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1]; - bNextLast = IMG_FALSE; - } - - if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1) - { - (*pui32CurrentLevel)++; - if (_MMU_FreeLevel(psMMUContext, psLevel->apsNextLevel[i], - auiStartArray, auiEndArray, - auiEntriesPerPxArray, apsConfig, - aeMMULevel, pui32CurrentLevel, - uiNextStartIndex, uiNextEndIndex, - bNextFirst, bNextLast, uiLog2DataPageSize)) - { - psLevel->ui32RefCount--; - psLevel->apsNextLevel[i] = NULL; - - /* Check we haven't wrapped around */ - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - } - (*pui32CurrentLevel)--; - } - else - { - /* We should never come down this path, but it's here - for completeness */ - psLevel->ui32RefCount--; - - /* Check we haven't wrapped around */ - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - } - - fallthrough; - case 2: - if (psLevel->apsNextLevel[i] != NULL && - psLevel->apsNextLevel[i]->ui32RefCount == 0) - { - _PxMemFree(psMMUContext, &psLevel->sMemDesc, - aeMMULevel[uiThisLevel]); - } - - fallthrough; - case 1: - if (psLevel->apsNextLevel[i] != NULL && - psLevel->apsNextLevel[i]->ui32RefCount == 0) - { - OSFreeMem(psLevel->apsNextLevel[i]); - psLevel->apsNextLevel[i] = NULL; - } - - fallthrough; - case 0: - uiAllocState = 3; - break; - } - } - return eError; -} - -/***************************************************************************** - * MMU page table functions * - *****************************************************************************/ - -/*************************************************************************/ /*! -@Function _MMU_GetLevelData - -@Description Get the all the level data and calculates the indexes for the - specified address range - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddrStart Start device virtual address - -@Input sDevVAddrEnd End device virtual address - -@Input uiLog2DataPageSize Log2 of the page size to use - -@Input auiStartArray Array of start indexes (one for each level) - -@Input auiEndArray Array of end indexes (one for each level) - -@Input uiEntriesPerPxArray Array of number of entries for the Px - (one for each level) - -@Input apsConfig Array of PxE configs (one for each level) - -@Input aeMMULevel Array of MMU levels (one for each level) - -@Input ppsMMUDevVAddrConfig Device virtual address config - -@Input phPriv Private data of page size config - -@Return IMG_TRUE if the last reference to psLevel was dropped - */ -/*****************************************************************************/ -static void _MMU_GetLevelData(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrStart, - IMG_DEV_VIRTADDR sDevVAddrEnd, - IMG_UINT32 uiLog2DataPageSize, - IMG_UINT32 auiStartArray[], - IMG_UINT32 auiEndArray[], - IMG_UINT32 auiEntriesPerPx[], - const MMU_PxE_CONFIG *apsConfig[], - MMU_LEVEL aeMMULevel[], - const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv) -{ - const MMU_PxE_CONFIG *psMMUPDEConfig; - const MMU_PxE_CONFIG *psMMUPTEConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs; - PVRSRV_ERROR eError; - IMG_UINT32 i = 0; - - eError = psDevAttrs->pfnGetPageSizeConfiguration(uiLog2DataPageSize, - &psMMUPDEConfig, - &psMMUPTEConfig, - ppsMMUDevVAddrConfig, - phPriv); - PVR_ASSERT(eError == PVRSRV_OK); - - psDevVAddrConfig = *ppsMMUDevVAddrConfig; - - if (psDevVAddrConfig->uiPCIndexMask != 0) - { - auiStartArray[i] = _CalcPCEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE); - auiEndArray[i] = _CalcPCEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE); - auiEntriesPerPx[i] = psDevVAddrConfig->uiNumEntriesPC; - apsConfig[i] = psDevAttrs->psBaseConfig; - aeMMULevel[i] = MMU_LEVEL_3; - i++; - } - - if (psDevVAddrConfig->uiPDIndexMask != 0) - { - auiStartArray[i] = _CalcPDEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE); - auiEndArray[i] = _CalcPDEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE); - auiEntriesPerPx[i] = psDevVAddrConfig->uiNumEntriesPD; - if (i == 0) - { - apsConfig[i] = psDevAttrs->psBaseConfig; - } - else - { - apsConfig[i] = psMMUPDEConfig; - } - aeMMULevel[i] = MMU_LEVEL_2; - i++; - } - - /* - There is always a PTE entry so we have a slightly different behaviour than above. - E.g. for 2 MB RGX pages the uiPTIndexMask is 0x0000000000 but still there - is a PT with one entry. - - */ - auiStartArray[i] = _CalcPTEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE); - if (psDevVAddrConfig->uiPTIndexMask !=0) - { - auiEndArray[i] = _CalcPTEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE); - } - else - { - /* - If the PTE mask is zero it means there is only 1 PTE and thus, as an - an exclusive bound, the end array index is equal to the start index + 1. - */ - - auiEndArray[i] = auiStartArray[i] + 1; - } - - auiEntriesPerPx[i] = psDevVAddrConfig->uiNumEntriesPT; - - if (i == 0) - { - apsConfig[i] = psDevAttrs->psBaseConfig; - } - else - { - apsConfig[i] = psMMUPTEConfig; - } - aeMMULevel[i] = MMU_LEVEL_1; -} - -static void _MMU_PutLevelData(MMU_CONTEXT *psMMUContext, IMG_HANDLE hPriv) -{ - MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs; - - psDevAttrs->pfnPutPageSizeConfiguration(hPriv); -} - -/*************************************************************************/ /*! -@Function _AllocPageTables - -@Description Allocate page tables and any higher level MMU objects required - for the specified virtual range - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddrStart Start device virtual address - -@Input sDevVAddrEnd End device virtual address - -@Input uiLog2DataPageSize Page size of the data pages - -@Return PVRSRV_OK if the allocation was successful - */ -/*****************************************************************************/ -static PVRSRV_ERROR -_AllocPageTables(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrStart, - IMG_DEV_VIRTADDR sDevVAddrEnd, - IMG_UINT32 uiLog2DataPageSize) -{ - PVRSRV_ERROR eError; - IMG_UINT32 auiStartArray[MMU_MAX_LEVEL]; - IMG_UINT32 auiEndArray[MMU_MAX_LEVEL]; - IMG_UINT32 auiEntriesPerPx[MMU_MAX_LEVEL]; - MMU_LEVEL aeMMULevel[MMU_MAX_LEVEL]; - const MMU_PxE_CONFIG *apsConfig[MMU_MAX_LEVEL]; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_HANDLE hPriv; - IMG_UINT32 ui32CurrentLevel = 0; - - PVR_DPF((PVR_DBG_ALLOC, - "_AllocPageTables: vaddr range: "IMG_DEV_VIRTADDR_FMTSPEC":"IMG_DEV_VIRTADDR_FMTSPEC, - sDevVAddrStart.uiAddr, - sDevVAddrEnd.uiAddr - )); - -#if defined(PDUMP) - PDUMPCOMMENT(psMMUContext->psPhysMemCtx->psDevNode, - "Allocating page tables for %"IMG_UINT64_FMTSPEC" bytes virtual range: " - IMG_DEV_VIRTADDR_FMTSPEC":"IMG_DEV_VIRTADDR_FMTSPEC, - (IMG_UINT64)sDevVAddrEnd.uiAddr - (IMG_UINT64)sDevVAddrStart.uiAddr, - (IMG_UINT64)sDevVAddrStart.uiAddr, - (IMG_UINT64)sDevVAddrEnd.uiAddr); -#endif - - _MMU_GetLevelData(psMMUContext, sDevVAddrStart, sDevVAddrEnd, - (IMG_UINT32) uiLog2DataPageSize, auiStartArray, auiEndArray, - auiEntriesPerPx, apsConfig, aeMMULevel, - &psDevVAddrConfig, &hPriv); - - HTBLOGK(HTB_SF_MMU_PAGE_OP_ALLOC, - HTBLOG_U64_BITS_HIGH(sDevVAddrStart.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddrStart.uiAddr), - HTBLOG_U64_BITS_HIGH(sDevVAddrEnd.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddrEnd.uiAddr)); - - eError = _MMU_AllocLevel(psMMUContext, &psMMUContext->sBaseLevelInfo, - auiStartArray, auiEndArray, auiEntriesPerPx, - apsConfig, aeMMULevel, &ui32CurrentLevel, - auiStartArray[0], auiEndArray[0], - IMG_TRUE, IMG_TRUE, uiLog2DataPageSize); - - _MMU_PutLevelData(psMMUContext, hPriv); - - return eError; -} - -/*************************************************************************/ /*! -@Function _FreePageTables - -@Description Free page tables and any higher level MMU objects at are no - longer referenced for the specified virtual range. - This will fill the temporary free list of the MMU context which - needs cleanup after the call. - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddrStart Start device virtual address - -@Input sDevVAddrEnd End device virtual address - -@Input uiLog2DataPageSize Page size of the data pages - -@Return None - */ -/*****************************************************************************/ -static void _FreePageTables(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrStart, - IMG_DEV_VIRTADDR sDevVAddrEnd, - IMG_UINT32 uiLog2DataPageSize) -{ - IMG_UINT32 auiStartArray[MMU_MAX_LEVEL]; - IMG_UINT32 auiEndArray[MMU_MAX_LEVEL]; - IMG_UINT32 auiEntriesPerPx[MMU_MAX_LEVEL]; - MMU_LEVEL aeMMULevel[MMU_MAX_LEVEL]; - const MMU_PxE_CONFIG *apsConfig[MMU_MAX_LEVEL]; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_UINT32 ui32CurrentLevel = 0; - IMG_HANDLE hPriv; - - PVR_DPF((PVR_DBG_ALLOC, - "_FreePageTables: vaddr range: "IMG_DEV_VIRTADDR_FMTSPEC":"IMG_DEV_VIRTADDR_FMTSPEC, - sDevVAddrStart.uiAddr, - sDevVAddrEnd.uiAddr - )); - - _MMU_GetLevelData(psMMUContext, sDevVAddrStart, sDevVAddrEnd, - uiLog2DataPageSize, auiStartArray, auiEndArray, - auiEntriesPerPx, apsConfig, aeMMULevel, - &psDevVAddrConfig, &hPriv); - - HTBLOGK(HTB_SF_MMU_PAGE_OP_FREE, - HTBLOG_U64_BITS_HIGH(sDevVAddrStart.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddrStart.uiAddr), - HTBLOG_U64_BITS_HIGH(sDevVAddrEnd.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddrEnd.uiAddr)); - - /* ignoring return code, in this case there should be no references - * to the level anymore, and at this stage there is nothing to do with - * the return status */ - (void) _MMU_FreeLevel(psMMUContext, &psMMUContext->sBaseLevelInfo, - auiStartArray, auiEndArray, auiEntriesPerPx, - apsConfig, aeMMULevel, &ui32CurrentLevel, - auiStartArray[0], auiEndArray[0], - IMG_TRUE, IMG_TRUE, uiLog2DataPageSize); - - _MMU_PutLevelData(psMMUContext, hPriv); -} - - -/*************************************************************************/ /*! -@Function _MMU_GetPTInfo - -@Description Get the PT level information and PT entry index for the specified - virtual address - -@Input psMMUContext MMU context to operate on - -@Input psDevVAddr Device virtual address to get the PTE info - from. - -@Input psDevVAddrConfig The current virtual address config obtained - by another function call before. - -@Output psLevel Level info of the PT - -@Output pui32PTEIndex Index into the PT the address corresponds to - -@Return None - */ -/*****************************************************************************/ -static INLINE void _MMU_GetPTInfo(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig, - MMU_Levelx_INFO **ppsLevel, - IMG_UINT32 *pui32PTEIndex) -{ - MMU_Levelx_INFO *psLocalLevel = NULL; - MMU_LEVEL eMMULevel = psMMUContext->psDevAttrs->eTopLevel; - IMG_UINT32 uiPCEIndex; - IMG_UINT32 uiPDEIndex; - - if ((eMMULevel <= MMU_LEVEL_0) || (eMMULevel >= MMU_LEVEL_LAST)) - { - PVR_DPF((PVR_DBG_ERROR, "_MMU_GetPTEInfo: Invalid MMU level")); - PVR_ASSERT(0); - } - - for (; eMMULevel > MMU_LEVEL_0; eMMULevel--) - { - if (eMMULevel == MMU_LEVEL_3) - { - /* find the page directory containing the PCE */ - uiPCEIndex = _CalcPCEIdx (sDevVAddr, psDevVAddrConfig, - IMG_FALSE); - psLocalLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiPCEIndex]; - } - - if (eMMULevel == MMU_LEVEL_2) - { - /* find the page table containing the PDE */ - uiPDEIndex = _CalcPDEIdx (sDevVAddr, psDevVAddrConfig, - IMG_FALSE); - if (psLocalLevel != NULL) - { - psLocalLevel = psLocalLevel->apsNextLevel[uiPDEIndex]; - } - else - { - psLocalLevel = - psMMUContext->sBaseLevelInfo.apsNextLevel[uiPDEIndex]; - } - } - - if (eMMULevel == MMU_LEVEL_1) - { - /* find PTE index into page table */ - *pui32PTEIndex = _CalcPTEIdx (sDevVAddr, psDevVAddrConfig, - IMG_FALSE); - if (psLocalLevel == NULL) - { - psLocalLevel = &psMMUContext->sBaseLevelInfo; - } - } - } - *ppsLevel = psLocalLevel; -} - -/*************************************************************************/ /*! -@Function _MMU_GetPTConfig - -@Description Get the level config. Call _MMU_PutPTConfig after use! - -@Input psMMUContext MMU context to operate on - -@Input uiLog2DataPageSize Log 2 of the page size - -@Output ppsConfig Config of the PTE - -@Output phPriv Private data handle to be passed back - when the info is put - -@Output ppsDevVAddrConfig Config of the device virtual addresses - -@Return None - */ -/*****************************************************************************/ -static INLINE void _MMU_GetPTConfig(MMU_CONTEXT *psMMUContext, - IMG_UINT32 uiLog2DataPageSize, - const MMU_PxE_CONFIG **ppsConfig, - IMG_HANDLE *phPriv, - const MMU_DEVVADDR_CONFIG **ppsDevVAddrConfig) -{ - MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - const MMU_PxE_CONFIG *psPDEConfig; - const MMU_PxE_CONFIG *psPTEConfig; - - if (psDevAttrs->pfnGetPageSizeConfiguration(uiLog2DataPageSize, - &psPDEConfig, - &psPTEConfig, - &psDevVAddrConfig, - phPriv) != PVRSRV_OK) - { - /* - There should be no way we got here unless uiLog2DataPageSize - has changed after the MMU_Alloc call (in which case it's a bug in - the MM code) - */ - PVR_DPF((PVR_DBG_ERROR, "_MMU_GetPTConfig: Could not get valid page size config")); - PVR_ASSERT(0); - } - - *ppsConfig = psPTEConfig; - *ppsDevVAddrConfig = psDevVAddrConfig; -} - -/*************************************************************************/ /*! -@Function _MMU_PutPTConfig - -@Description Put the level info. Has to be called after _MMU_GetPTConfig to - ensure correct refcounting. - -@Input psMMUContext MMU context to operate on - -@Input phPriv Private data handle created by - _MMU_GetPTConfig. - -@Return None - */ -/*****************************************************************************/ -static INLINE void _MMU_PutPTConfig(MMU_CONTEXT *psMMUContext, - IMG_HANDLE hPriv) -{ - MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs; - - if (psDevAttrs->pfnPutPageSizeConfiguration(hPriv) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Could not put page size config", - __func__)); - PVR_ASSERT(0); - } -} - - -/***************************************************************************** - * Public interface functions * - *****************************************************************************/ - -/* - MMU_ContextCreate - */ -PVRSRV_ERROR -MMU_ContextCreate(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - MMU_CONTEXT **ppsMMUContext, - MMU_DEVICEATTRIBS *psDevAttrs) -{ - MMU_CONTEXT *psMMUContext; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - const MMU_PxE_CONFIG *psConfig; - MMU_PHYSMEM_CONTEXT *psPhysMemCtx; - IMG_UINT32 ui32BaseObjects; - IMG_UINT32 ui32Size; - IMG_CHAR sBuf[40]; - PVRSRV_ERROR eError = PVRSRV_OK; - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, "MMU context create"); -#endif - - psConfig = psDevAttrs->psBaseConfig; - psDevVAddrConfig = psDevAttrs->psTopLevelDevVAddrConfig; - - switch (psDevAttrs->eTopLevel) - { - case MMU_LEVEL_3: - ui32BaseObjects = psDevVAddrConfig->uiNumEntriesPC; - break; - - case MMU_LEVEL_2: - ui32BaseObjects = psDevVAddrConfig->uiNumEntriesPD; - break; - - case MMU_LEVEL_1: - ui32BaseObjects = psDevVAddrConfig->uiNumEntriesPT; - break; - - default: - PVR_LOG_GOTO_WITH_ERROR("psDevAttrs->eTopLevel", eError, PVRSRV_ERROR_INVALID_PARAMS, e0); - } - - /* Allocate the MMU context with the Level 1 Px info's */ - ui32Size = sizeof(MMU_CONTEXT) + - ((ui32BaseObjects - 1) * sizeof(MMU_Levelx_INFO *)); - - psMMUContext = OSAllocZMem(ui32Size); - PVR_LOG_GOTO_IF_NOMEM(psMMUContext, eError, e0); - -#if defined(PDUMP) - /* Clear the refcount */ - psMMUContext->ui32PDumpContextIDRefCount = 0; -#endif - /* Record Device specific attributes in the context for subsequent use */ - psMMUContext->psDevAttrs = psDevAttrs; - - /* - Allocate physmem context and set it up - */ - psPhysMemCtx = OSAllocZMem(sizeof(MMU_PHYSMEM_CONTEXT)); - PVR_LOG_GOTO_IF_NOMEM(psPhysMemCtx, eError, e1); - - psMMUContext->psPhysMemCtx = psPhysMemCtx; - psMMUContext->psConnection = psConnection; - - psPhysMemCtx->psDevNode = psDevNode; /* Needed for Direct Bridge case */ - psPhysMemCtx->psMMUContext = psMMUContext; /* Back-link to self */ - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* Save the app-specific values for external reference via MMU_GetOSids. */ - if (psConnection != NULL) - { - psPhysMemCtx->ui32OSid = psConnection->ui32OSid; - psPhysMemCtx->ui32OSidReg = psConnection->ui32OSidReg; - psPhysMemCtx->bOSidAxiProt = psConnection->bOSidAxiProtReg; - } - else - { - /* Direct Bridge calling sequence e.g. Firmware */ - psPhysMemCtx->ui32OSid = 0; - psPhysMemCtx->ui32OSidReg = 0; - psPhysMemCtx->bOSidAxiProt = IMG_FALSE; - } -#endif - - OSSNPrintf(sBuf, sizeof(sBuf), "pgtables %p", psPhysMemCtx); - psPhysMemCtx->uiPhysMemRANameAllocSize = OSStringLength(sBuf)+1; - psPhysMemCtx->pszPhysMemRAName = OSAllocMem(psPhysMemCtx->uiPhysMemRANameAllocSize); - PVR_LOG_GOTO_IF_NOMEM(psPhysMemCtx->pszPhysMemRAName, eError, e2); - - OSStringLCopy(psPhysMemCtx->pszPhysMemRAName, sBuf, psPhysMemCtx->uiPhysMemRANameAllocSize); - - psPhysMemCtx->psPhysMemRA = RA_Create(psPhysMemCtx->pszPhysMemRAName, - /* subsequent import */ - PhysHeapGetPageShift(psDevNode->psMMUPhysHeap), - RA_LOCKCLASS_1, - _MMU_PhysMem_RAImportAlloc, - _MMU_PhysMem_RAImportFree, - psPhysMemCtx, /* priv */ - RA_POLICY_DEFAULT); - if (psPhysMemCtx->psPhysMemRA == NULL) - { - OSFreeMem(psPhysMemCtx->pszPhysMemRAName); - psPhysMemCtx->pszPhysMemRAName = NULL; - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, e3); - } - - /* Setup cleanup meta data to check if a MMU context - * has been destroyed and should not be accessed anymore */ - psPhysMemCtx->psCleanupData = OSAllocMem(sizeof(*(psPhysMemCtx->psCleanupData))); - PVR_LOG_GOTO_IF_NOMEM(psPhysMemCtx->psCleanupData, eError, e4); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* Record the originating OSid for all allocation / free for this context */ - psPhysMemCtx->psCleanupData->ui32OSid = psPhysMemCtx->ui32OSid; -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - OSLockCreate(&psPhysMemCtx->psCleanupData->hCleanupLock); - psPhysMemCtx->psCleanupData->bMMUContextExists = IMG_TRUE; - dllist_init(&psPhysMemCtx->psCleanupData->sMMUCtxCleanupItemsHead); - OSAtomicWrite(&psPhysMemCtx->psCleanupData->iRef, 1); - - /* allocate the base level object */ - /* - Note: Although this is not required by the this file until - the 1st allocation is made, a device specific callback - might request the base object address so we allocate - it up front. - */ - if (_PxMemAlloc(psMMUContext, - ui32BaseObjects, - psConfig, - psDevAttrs->eTopLevel, - &psMMUContext->sBaseLevelInfo.sMemDesc, - psDevAttrs->ui32BaseAlign)) - { - PVR_LOG_GOTO_WITH_ERROR("_PxMemAlloc", eError, PVRSRV_ERROR_OUT_OF_MEMORY, e5); - } - - dllist_init(&psMMUContext->psPhysMemCtx->sTmpMMUMappingHead); - - psMMUContext->sBaseLevelInfo.ui32NumOfEntries = ui32BaseObjects; - psMMUContext->sBaseLevelInfo.ui32RefCount = 0; - - eError = OSLockCreate(&psMMUContext->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e6); - - /* return context */ - *ppsMMUContext = psMMUContext; - - return PVRSRV_OK; - -e6: - _PxMemFree(psMMUContext, &psMMUContext->sBaseLevelInfo.sMemDesc, psDevAttrs->eTopLevel); -e5: - OSFreeMem(psPhysMemCtx->psCleanupData); -e4: - RA_Delete(psPhysMemCtx->psPhysMemRA); -e3: - OSFreeMem(psPhysMemCtx->pszPhysMemRAName); -e2: - OSFreeMem(psPhysMemCtx); -e1: - OSFreeMem(psMMUContext); -e0: - return eError; -} - -/* - MMU_ContextDestroy - */ -void -MMU_ContextDestroy (MMU_CONTEXT *psMMUContext) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PDLLIST_NODE psNode, psNextNode; - - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psMMUContext->psPhysMemCtx->psDevNode; - MMU_CTX_CLEANUP_DATA *psCleanupData = psMMUContext->psPhysMemCtx->psCleanupData; - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Enter", __func__)); - - if (psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) - { - /* There should be no way to get here with live pages unless - there is a bug in this module or the MM code */ - PVR_ASSERT(psMMUContext->sBaseLevelInfo.ui32RefCount == 0); - } - - /* Cleanup lock must be acquired before MMUContext lock. Reverse order - * may lead to a deadlock and is reported by lockdep. */ - OSLockAcquire(psCleanupData->hCleanupLock); - OSLockAcquire(psMMUContext->hLock); - - /* Free the top level MMU object - will be put on defer free list. - * This has to be done before the step below that will empty the - * defer-free list. */ - _PxMemFree(psMMUContext, - &psMMUContext->sBaseLevelInfo.sMemDesc, - psMMUContext->psDevAttrs->eTopLevel); - - /* Empty the temporary defer-free list of Px */ - _FreeMMUMapping(psDevNode, &psMMUContext->psPhysMemCtx->sTmpMMUMappingHead); - PVR_ASSERT(dllist_is_empty(&psMMUContext->psPhysMemCtx->sTmpMMUMappingHead)); - - /* Empty the defer free list so the cleanup thread will - * not have to access any MMU context related structures anymore */ - dllist_foreach_node(&psCleanupData->sMMUCtxCleanupItemsHead, - psNode, - psNextNode) - { - MMU_CLEANUP_ITEM *psCleanup = IMG_CONTAINER_OF(psNode, - MMU_CLEANUP_ITEM, - sMMUCtxCleanupItem); - - _FreeMMUMapping(psDevNode, &psCleanup->sMMUMappingHead); - - dllist_remove_node(psNode); - } - PVR_ASSERT(dllist_is_empty(&psCleanupData->sMMUCtxCleanupItemsHead)); - - psCleanupData->bMMUContextExists = IMG_FALSE; - - /* Free physmem context */ - RA_Delete(psMMUContext->psPhysMemCtx->psPhysMemRA); - psMMUContext->psPhysMemCtx->psPhysMemRA = NULL; - OSFreeMem(psMMUContext->psPhysMemCtx->pszPhysMemRAName); - psMMUContext->psPhysMemCtx->pszPhysMemRAName = NULL; - - OSFreeMem(psMMUContext->psPhysMemCtx); - - OSLockRelease(psMMUContext->hLock); - - OSLockRelease(psCleanupData->hCleanupLock); - - if (OSAtomicDecrement(&psCleanupData->iRef) == 0) - { - OSLockDestroy(psCleanupData->hCleanupLock); - OSFreeMem(psCleanupData); - } - - OSLockDestroy(psMMUContext->hLock); - - /* free the context itself. */ - OSFreeMem(psMMUContext); - /*not nulling pointer, copy on stack*/ - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Exit", __func__)); -} - -/* - MMU_Alloc - */ -PVRSRV_ERROR -MMU_Alloc (MMU_CONTEXT *psMMUContext, - IMG_DEVMEM_SIZE_T uSize, - IMG_DEVMEM_SIZE_T *puActualSize, - IMG_UINT32 uiProtFlags, - IMG_DEVMEM_SIZE_T uDevVAddrAlignment, - IMG_DEV_VIRTADDR *psDevVAddr, - IMG_UINT32 uiLog2PageSize) -{ - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR sDevVAddrEnd; - - const MMU_PxE_CONFIG *psPDEConfig; - const MMU_PxE_CONFIG *psPTEConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - - MMU_DEVICEATTRIBS *psDevAttrs; - IMG_HANDLE hPriv; - -#if !defined(DEBUG) - PVR_UNREFERENCED_PARAMETER(uDevVAddrAlignment); -#endif - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: uSize=" IMG_DEVMEM_SIZE_FMTSPEC - ", uiProtFlags=0x%x, align="IMG_DEVMEM_ALIGN_FMTSPEC, - __func__, uSize, uiProtFlags, uDevVAddrAlignment)); - - /* check params */ - PVR_LOG_RETURN_IF_INVALID_PARAM(psMMUContext, "psMMUContext"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevVAddr, "psDevVAddr"); - PVR_LOG_RETURN_IF_INVALID_PARAM(puActualSize, "puActualSize"); - - psDevAttrs = psMMUContext->psDevAttrs; - - eError = psDevAttrs->pfnGetPageSizeConfiguration(uiLog2PageSize, - &psPDEConfig, - &psPTEConfig, - &psDevVAddrConfig, - &hPriv); - PVR_LOG_RETURN_IF_ERROR(eError, "pfnGetPageSizeConfiguration"); - - /* size and alignment must be datapage granular */ - if (((psDevVAddr->uiAddr & psDevVAddrConfig->uiPageOffsetMask) != 0) - || ((uSize & psDevVAddrConfig->uiPageOffsetMask) != 0)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: invalid address or size granularity", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - sDevVAddrEnd = *psDevVAddr; - sDevVAddrEnd.uiAddr += uSize; - - OSLockAcquire(psMMUContext->hLock); - eError = _AllocPageTables(psMMUContext, *psDevVAddr, sDevVAddrEnd, uiLog2PageSize); - OSLockRelease(psMMUContext->hLock); - - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "_AllocPageTables"); - return PVRSRV_ERROR_MMU_FAILED_TO_ALLOCATE_PAGETABLES; - } - - psDevAttrs->pfnPutPageSizeConfiguration(hPriv); - - return PVRSRV_OK; -} - -/* - MMU_Free - */ -void -MMU_Free (MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiLog2DataPageSize) -{ - IMG_DEV_VIRTADDR sDevVAddrEnd; - -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) && defined(__linux__) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_UINT32 ui32MMULeakMax = psPVRSRVData->sMemLeakIntervals.ui32MMU; - - mutex_lock(&g_sMMULeakMutex); - - g_ui32MMULeakCounter++; - if (ui32MMULeakMax && g_ui32MMULeakCounter >= ui32MMULeakMax) - { - g_ui32MMULeakCounter = 0; - mutex_unlock(&g_sMMULeakMutex); - - PVR_DPF((PVR_DBG_WARNING, - "%s: Skipped MMU free for address 0x%016" IMG_UINT64_FMTSPECx " to trigger memory leak.", - __func__, - sDevVAddr.uiAddr)); - return; - } - - mutex_unlock(&g_sMMULeakMutex); -#endif - - PVR_ASSERT(psMMUContext != NULL); - PVR_LOG_RETURN_VOID_IF_FALSE(psMMUContext != NULL, "psMMUContext"); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Freeing DevVAddr " IMG_DEV_VIRTADDR_FMTSPEC, - __func__, sDevVAddr.uiAddr)); - - /* ensure the address range to free is inside the heap */ - sDevVAddrEnd = sDevVAddr; - sDevVAddrEnd.uiAddr += uiSize; - - /* The Cleanup lock has to be taken before the MMUContext hLock to - * prevent deadlock scenarios. It is necessary only for parts of - * _SetupCleanup_FreeMMUMapping though.*/ - OSLockAcquire(psMMUContext->psPhysMemCtx->psCleanupData->hCleanupLock); - - OSLockAcquire(psMMUContext->hLock); - - _FreePageTables(psMMUContext, - sDevVAddr, - sDevVAddrEnd, - uiLog2DataPageSize); - - _SetupCleanup_FreeMMUMapping(psMMUContext->psPhysMemCtx); - - OSLockRelease(psMMUContext->hLock); - - OSLockRelease(psMMUContext->psPhysMemCtx->psCleanupData->hCleanupLock); - - return; -} - -PVRSRV_ERROR -MMU_MapPages(MMU_CONTEXT *psMMUContext, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_DEV_VIRTADDR sDevVAddrBase, - PMR *psPMR, - IMG_UINT32 ui32PhysPgOffset, - IMG_UINT32 ui32MapPageCount, - IMG_UINT32 *paui32MapIndices, - IMG_UINT32 uiLog2HeapPageSize) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hPriv; - - MMU_Levelx_INFO *psLevel = NULL; - - MMU_Levelx_INFO *psPrevLevel = NULL; - - IMG_UINT32 uiPTEIndex = 0; - IMG_UINT32 uiPageSize = (1 << uiLog2HeapPageSize); - IMG_UINT32 uiLoop = 0; - IMG_UINT32 ui32MappedCount = 0; - IMG_DEVMEM_OFFSET_T uiPgOffset = 0; - IMG_UINT32 uiFlushEnd = 0, uiFlushStart = 0; - - IMG_UINT64 uiProtFlags = 0, uiProtFlagsReadOnly = 0, uiDefProtFlags=0; - MMU_PROTFLAGS_T uiMMUProtFlags = 0; - - const MMU_PxE_CONFIG *psConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - - IMG_DEV_VIRTADDR sDevVAddr = sDevVAddrBase; - - IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEV_PHYADDR *psDevPAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_BOOL *pbValid; - IMG_BOOL bValid; - IMG_BOOL bDummyBacking = IMG_FALSE, bZeroBacking = IMG_FALSE; - IMG_BOOL bNeedBacking = IMG_FALSE; - PVRSRV_DEVICE_NODE *psDevNode; - -#if defined(PDUMP) - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset; - - PDUMPCOMMENT(psMMUContext->psPhysMemCtx->psDevNode, "Wire up Page Table entries to point to the Data Pages (%"IMG_INT64_FMTSPECd" bytes)", - (IMG_UINT64)(ui32MapPageCount * uiPageSize)); -#endif /*PDUMP*/ - - /* Validate the most essential parameters */ - PVR_LOG_GOTO_IF_INVALID_PARAM(psMMUContext, eError, e0); - PVR_LOG_GOTO_IF_INVALID_PARAM(psPMR, eError, e0); - - psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - - /* Allocate memory for page-frame-numbers and validity states, - N.B. assert could be triggered by an illegal uiSizeBytes */ - if (ui32MapPageCount > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - psDevPAddr = OSAllocMem(ui32MapPageCount * sizeof(IMG_DEV_PHYADDR)); - PVR_LOG_GOTO_IF_NOMEM(psDevPAddr, eError, e0); - - pbValid = OSAllocMem(ui32MapPageCount * sizeof(IMG_BOOL)); - if (pbValid == NULL) - { - /* Should allocation fail, clean-up here before exit */ - OSFreeMem(psDevPAddr); - PVR_LOG_GOTO_WITH_ERROR("pbValid", eError, PVRSRV_ERROR_OUT_OF_MEMORY, e0); - } - } - else - { - psDevPAddr = asDevPAddr; - pbValid = abValid; - } - - /* Get the Device physical addresses of the pages we are trying to map - * In the case of non indexed mapping we can get all addresses at once */ - if (NULL == paui32MapIndices) - { - eError = PMR_DevPhysAddr(psPMR, - uiLog2HeapPageSize, - ui32MapPageCount, - ((IMG_DEVMEM_OFFSET_T) ui32PhysPgOffset << uiLog2HeapPageSize), - psDevPAddr, - pbValid); - PVR_GOTO_IF_ERROR(eError, e1); - } - - /*Get the Page table level configuration */ - _MMU_GetPTConfig(psMMUContext, - (IMG_UINT32) uiLog2HeapPageSize, - &psConfig, - &hPriv, - &psDevVAddrConfig); - - eError = _MMU_ConvertDevMemFlags(IMG_FALSE, - uiMappingFlags, - &uiMMUProtFlags, - psMMUContext); - PVR_GOTO_IF_ERROR(eError, e2); - - /* Callback to get device specific protection flags */ - if (psConfig->uiBytesPerEntry == 8) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2HeapPageSize); - uiMMUProtFlags |= MMU_PROTFLAGS_READABLE; - uiProtFlagsReadOnly = psMMUContext->psDevAttrs->pfnDerivePTEProt8((uiMMUProtFlags & ~MMU_PROTFLAGS_WRITEABLE), - uiLog2HeapPageSize); - } - else if (psConfig->uiBytesPerEntry == 4) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags); - uiMMUProtFlags |= MMU_PROTFLAGS_READABLE; - uiProtFlagsReadOnly = psMMUContext->psDevAttrs->pfnDerivePTEProt4((uiMMUProtFlags & ~MMU_PROTFLAGS_WRITEABLE)); - } - else - { - PVR_LOG_GOTO_WITH_ERROR("psConfig->uiBytesPerEntry", eError, PVRSRV_ERROR_INVALID_PARAMS, e2); - } - - if (PMR_IsSparse(psPMR)) - { - /* We know there will not be 4G number of PMR's */ - bDummyBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(PMR_Flags(psPMR)); - if (bDummyBacking) - { - bZeroBacking = PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(PMR_Flags(psPMR)); - } - - if (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiMappingFlags)) - { - /* Obtain non-coherent protection flags as we cannot have multiple coherent - virtual pages pointing to the same physical page so all dummy page - mappings have to be non-coherent even in a coherent allocation */ - eError = _MMU_ConvertDevMemFlags(IMG_FALSE, - uiMappingFlags & ~PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT, - &uiMMUProtFlags, - psMMUContext); - PVR_GOTO_IF_ERROR(eError, e2); - - /* Callback to get device specific protection flags */ - if (psConfig->uiBytesPerEntry == 8) - { - psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags, uiLog2HeapPageSize); - } - else - { - /* We've already validated possible values of uiBytesPerEntry at the start of this function */ - PVR_ASSERT(psConfig->uiBytesPerEntry == 4); - psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags); - } - } - } - - OSLockAcquire(psMMUContext->hLock); - - for (uiLoop = 0; uiLoop < ui32MapPageCount; uiLoop++) - { - -#if defined(PDUMP) - IMG_DEVMEM_OFFSET_T uiNextSymName; -#endif /*PDUMP*/ - - if (NULL != paui32MapIndices) - { - uiPgOffset = paui32MapIndices[uiLoop]; - - /*Calculate the Device Virtual Address of the page */ - sDevVAddr.uiAddr = sDevVAddrBase.uiAddr + (uiPgOffset * uiPageSize); - - /* Get the physical address to map */ - eError = PMR_DevPhysAddr(psPMR, - uiLog2HeapPageSize, - 1, - uiPgOffset * uiPageSize, - &sDevPAddr, - &bValid); - PVR_GOTO_IF_ERROR(eError, e3); - } - else - { - uiPgOffset = uiLoop + ui32PhysPgOffset; - sDevPAddr = psDevPAddr[uiLoop]; - bValid = pbValid[uiLoop]; - } - - uiDefProtFlags = uiProtFlags; - /* - The default value of the entry is invalid so we don't need to mark - it as such if the page wasn't valid, we just advance pass that address - */ - if (bValid || bDummyBacking) - { - if (!bValid) - { - if (bZeroBacking) - { - sDevPAddr.uiAddr = psDevNode->sDevZeroPage.ui64PgPhysAddr; - /* Ensure the zero back page PTE is read only */ - uiDefProtFlags = uiProtFlagsReadOnly; - } - else - { - sDevPAddr.uiAddr = psDevNode->sDummyPage.ui64PgPhysAddr; - } - } - else - { - /* check the physical alignment of the memory to map */ - PVR_ASSERT((sDevPAddr.uiAddr & (uiPageSize-1)) == 0); - } - -#if defined(DEBUG) - { - IMG_INT32 i32FeatureVal = 0; - IMG_UINT32 ui32BitLength = FloorLog2(sDevPAddr.uiAddr); - - i32FeatureVal = PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, PHYS_BUS_WIDTH); - do { - /* i32FeatureVal can be negative for cases where this feature is undefined - * In that situation we need to bail out than go ahead with debug comparison */ - if (0 > i32FeatureVal) - break; - - if (ui32BitLength > i32FeatureVal) - { - PVR_DPF((PVR_DBG_ERROR, - "%s Failed. The physical address bitlength (%d)" - " is greater than the chip can handle (%d).", - __func__, ui32BitLength, i32FeatureVal)); - - PVR_ASSERT(ui32BitLength <= i32FeatureVal); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e3; - } - } while (0); - } -#endif /*DEBUG*/ - -#if defined(PDUMP) - if (bValid) - { - eError = PMR_PDumpSymbolicAddr(psPMR, uiPgOffset * uiPageSize, - sizeof(aszMemspaceName), &aszMemspaceName[0], - sizeof(aszSymbolicAddress), &aszSymbolicAddress[0], - &uiSymbolicAddrOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - } -#endif /*PDUMP*/ - - psPrevLevel = psLevel; - /* Calculate PT index and get new table descriptor */ - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - - if (psPrevLevel == psLevel) - { - /* - * Sparse allocations may have page offsets which - * decrement as well as increment, so make sure we - * update the range we will flush correctly. - */ - if (uiPTEIndex > uiFlushEnd) - uiFlushEnd = uiPTEIndex; - else if (uiPTEIndex < uiFlushStart) - uiFlushStart = uiPTEIndex; - } - else - { - /* Flush if we moved to another psLevel, i.e. page table */ - if (psPrevLevel != NULL) - { - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psPrevLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psPrevLevel->sMemDesc.uiOffset, - (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - PVR_GOTO_IF_ERROR(eError, e3); - } - - uiFlushStart = uiPTEIndex; - uiFlushEnd = uiFlushStart; - } - - HTBLOGK(HTB_SF_MMU_PAGE_OP_MAP, - HTBLOG_U64_BITS_HIGH(sDevVAddr.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddr.uiAddr), - HTBLOG_U64_BITS_HIGH(sDevPAddr.uiAddr), HTBLOG_U64_BITS_LOW(sDevPAddr.uiAddr)); - - /* Set the PT entry with the specified address and protection flags */ - eError = _SetupPTE(psMMUContext, - psLevel, - uiPTEIndex, - psConfig, - &sDevPAddr, - IMG_FALSE, -#if defined(PDUMP) - (bValid)?aszMemspaceName:(psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName), - ((bValid)?aszSymbolicAddress:((bZeroBacking)?DEV_ZERO_PAGE:DUMMY_PAGE)), - (bValid)?uiSymbolicAddrOffset:0, -#endif /*PDUMP*/ - uiDefProtFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "_SetupPTE", e3); - - if (bValid) - { - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - PVR_DPF ((PVR_DBG_MESSAGE, - "%s: devVAddr=" IMG_DEV_VIRTADDR_FMTSPEC ", " - "size=" IMG_DEVMEM_OFFSET_FMTSPEC, - __func__, - sDevVAddr.uiAddr, - uiPgOffset * uiPageSize)); - - ui32MappedCount++; - } - } - - sDevVAddr.uiAddr += uiPageSize; - } - - /* Flush the last level we touched */ - if (psLevel != NULL) - { - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - PVR_GOTO_IF_ERROR(eError, e3); - } - - OSLockRelease(psMMUContext->hLock); - - _MMU_PutPTConfig(psMMUContext, hPriv); - - if (psDevPAddr != asDevPAddr) - { - OSFreeMem(pbValid); - OSFreeMem(psDevPAddr); - } - - /* Flush TLB for PTs*/ - psDevNode->pfnMMUCacheInvalidate(psDevNode, - psMMUContext, - MMU_LEVEL_1, - IMG_FALSE); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, "Wired up %d Page Table entries (out of %d)", ui32MappedCount, ui32MapPageCount); -#endif /*PDUMP*/ - - return PVRSRV_OK; - -e3: - OSLockRelease(psMMUContext->hLock); - - if (PMR_IsSparse(psPMR) && PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiMappingFlags)) - { - bNeedBacking = IMG_TRUE; - } - - MMU_UnmapPages(psMMUContext, - (bNeedBacking) ? uiMappingFlags : 0, - sDevVAddrBase, - uiLoop, - paui32MapIndices, - uiLog2HeapPageSize, - PMR_IsSparse(psPMR)); -e2: - _MMU_PutPTConfig(psMMUContext, hPriv); -e1: - if (psDevPAddr != asDevPAddr) - { - OSFreeMem(pbValid); - OSFreeMem(psDevPAddr); - } -e0: - return eError; -} - -/* - MMU_UnmapPages - */ -void -MMU_UnmapPages(MMU_CONTEXT *psMMUContext, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT32 ui32PageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags) -{ - IMG_UINT32 uiPTEIndex = 0, ui32Loop=0; - IMG_UINT32 uiPageSize = 1 << uiLog2PageSize; - IMG_UINT32 uiFlushEnd = 0, uiFlushStart = 0; - MMU_Levelx_INFO *psLevel = NULL; - MMU_Levelx_INFO *psPrevLevel = NULL; - IMG_HANDLE hPriv; - const MMU_PxE_CONFIG *psConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_UINT64 uiProtFlags = 0, uiProtFlagsReadOnly = 0; - MMU_PROTFLAGS_T uiMMUProtFlags = 0, uiMMUReadOnlyProtFlags = 0; - IMG_DEV_VIRTADDR sDevVAddr = sDevVAddrBase; - IMG_DEV_PHYADDR sBackingPgDevPhysAddr; - IMG_BOOL bUnmap = IMG_TRUE, bDummyBacking = IMG_FALSE, bZeroBacking = IMG_FALSE; - IMG_CHAR __maybe_unused *pcBackingPageName = NULL; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, - "Invalidate %d entries in page tables for virtual range: 0x%010"IMG_UINT64_FMTSPECX" to 0x%010"IMG_UINT64_FMTSPECX, - ui32PageCount, - (IMG_UINT64)sDevVAddr.uiAddr, - ((IMG_UINT64)sDevVAddr.uiAddr) + (uiPageSize*ui32PageCount)-1); -#endif - bDummyBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiMemAllocFlags); - bZeroBacking = PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiMemAllocFlags); - - if (bZeroBacking) - { - sBackingPgDevPhysAddr.uiAddr = psDevNode->sDevZeroPage.ui64PgPhysAddr; - pcBackingPageName = DEV_ZERO_PAGE; - } - else - { - sBackingPgDevPhysAddr.uiAddr = psDevNode->sDummyPage.ui64PgPhysAddr; - pcBackingPageName = DUMMY_PAGE; - } - - bUnmap = (uiMappingFlags)? !bDummyBacking : IMG_TRUE; - /* Get PT and address configs */ - _MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2PageSize, - &psConfig, &hPriv, &psDevVAddrConfig); - - if (_MMU_ConvertDevMemFlags(bUnmap, - uiMappingFlags, - &uiMMUProtFlags, - psMMUContext) != PVRSRV_OK) - { - return; - } - - uiMMUReadOnlyProtFlags = (uiMMUProtFlags & ~MMU_PROTFLAGS_WRITEABLE) | MMU_PROTFLAGS_READABLE; - - /* Callback to get device specific protection flags */ - if (psConfig->uiBytesPerEntry == 4) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags); - uiProtFlagsReadOnly = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUReadOnlyProtFlags); - } - else if (psConfig->uiBytesPerEntry == 8) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2PageSize); - uiProtFlagsReadOnly = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUReadOnlyProtFlags, uiLog2PageSize); - } - - - OSLockAcquire(psMMUContext->hLock); - - /* Unmap page by page */ - while (ui32Loop < ui32PageCount) - { - if (NULL != pai32FreeIndices) - { - /*Calculate the Device Virtual Address of the page */ - sDevVAddr.uiAddr = sDevVAddrBase.uiAddr + - pai32FreeIndices[ui32Loop] * (IMG_UINT64) uiPageSize; - } - - psPrevLevel = psLevel; - /* Calculate PT index and get new table descriptor */ - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - - if (psPrevLevel == psLevel) - { - /* - * Sparse allocations may have page offsets which - * decrement as well as increment, so make sure we - * update the range we will flush correctly. - */ - if (uiPTEIndex > uiFlushEnd) - uiFlushEnd = uiPTEIndex; - else if (uiPTEIndex < uiFlushStart) - uiFlushStart = uiPTEIndex; - } - else - { - /* Flush if we moved to another psLevel, i.e. page table */ - if (psPrevLevel != NULL) - { - PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psPrevLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psPrevLevel->sMemDesc.uiOffset, - (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - } - - uiFlushStart = uiPTEIndex; - uiFlushEnd = uiFlushStart; - } - - HTBLOGK(HTB_SF_MMU_PAGE_OP_UNMAP, - HTBLOG_U64_BITS_HIGH(sDevVAddr.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddr.uiAddr)); - - /* Set the PT entry to invalid and poison it with a bad address */ - if (_SetupPTE(psMMUContext, - psLevel, - uiPTEIndex, - psConfig, - (bDummyBacking)? &sBackingPgDevPhysAddr : &gsBadDevPhyAddr, - bUnmap, -#if defined(PDUMP) - (bDummyBacking)? (psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName): NULL, - (bDummyBacking)? pcBackingPageName: NULL, - 0U, -#endif - (bZeroBacking)? uiProtFlagsReadOnly: uiProtFlags) != PVRSRV_OK) - { - goto e0; - } - - /* Check we haven't wrapped around */ - PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries); - ui32Loop++; - sDevVAddr.uiAddr += uiPageSize; - } - - /* Flush the last level we touched */ - if (psLevel != NULL) - { - PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - } - - OSLockRelease(psMMUContext->hLock); - - _MMU_PutPTConfig(psMMUContext, hPriv); - - /* Flush TLB for PTs*/ - psDevNode->pfnMMUCacheInvalidate(psDevNode, - psMMUContext, - MMU_LEVEL_1, - IMG_TRUE); - - return; - -e0: - _MMU_PutPTConfig(psMMUContext, hPriv); - PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Failed to map/unmap page table")); - PVR_ASSERT(0); - OSLockRelease(psMMUContext->hLock); - return; -} - -PVRSRV_ERROR -MMU_MapPMRFast (MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrBase, - const PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSizeBytes, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_UINT32 uiLog2HeapPageSize) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 uiCount, i; - IMG_UINT32 uiPageSize = 1 << uiLog2HeapPageSize; - IMG_UINT32 uiPTEIndex = 0; - IMG_UINT64 uiProtFlags; - MMU_PROTFLAGS_T uiMMUProtFlags = 0; - MMU_Levelx_INFO *psLevel = NULL; - IMG_HANDLE hPriv; - const MMU_PxE_CONFIG *psConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_DEV_VIRTADDR sDevVAddr = sDevVAddrBase; - IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEV_PHYADDR *psDevPAddr; - IMG_BOOL *pbValid; - IMG_UINT32 uiFlushStart = 0; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - -#if defined(PDUMP) - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset; - IMG_UINT32 ui32MappedCount = 0; - PDUMPCOMMENT(psDevNode, "Wire up Page Table entries to point to the Data Pages (%"IMG_INT64_FMTSPECd" bytes)", uiSizeBytes); -#endif /*PDUMP*/ - - /* We should verify the size and contiguity when supporting variable page size */ - - PVR_ASSERT (psMMUContext != NULL); - PVR_ASSERT (psPMR != NULL); - - /* Allocate memory for page-frame-numbers and validity states, - N.B. assert could be triggered by an illegal uiSizeBytes */ - uiCount = uiSizeBytes >> uiLog2HeapPageSize; - PVR_ASSERT((IMG_DEVMEM_OFFSET_T)uiCount << uiLog2HeapPageSize == uiSizeBytes); - if (uiCount > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - psDevPAddr = OSAllocMem(uiCount * sizeof(IMG_DEV_PHYADDR)); - PVR_LOG_GOTO_IF_NOMEM(psDevPAddr, eError, return_error); - - pbValid = OSAllocMem(uiCount * sizeof(IMG_BOOL)); - if (pbValid == NULL) - { - /* Should allocation fail, clean-up here before exit */ - OSFreeMem(psDevPAddr); - PVR_LOG_GOTO_WITH_ERROR("pbValid", eError, PVRSRV_ERROR_OUT_OF_MEMORY, free_paddr_array); - } - } - else - { - psDevPAddr = asDevPAddr; - pbValid = abValid; - } - - /* Get general PT and address configs */ - _MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2HeapPageSize, - &psConfig, &hPriv, &psDevVAddrConfig); - - eError = _MMU_ConvertDevMemFlags(IMG_FALSE, - uiMappingFlags, - &uiMMUProtFlags, - psMMUContext); - PVR_GOTO_IF_ERROR(eError, put_mmu_context); - - /* Callback to get device specific protection flags */ - - if (psConfig->uiBytesPerEntry == 8) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2HeapPageSize); - } - else if (psConfig->uiBytesPerEntry == 4) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags); - } - else - { - PVR_LOG_GOTO_WITH_ERROR("psConfig->uiBytesPerEntry", eError, PVRSRV_ERROR_MMU_CONFIG_IS_WRONG, put_mmu_context); - } - - - /* "uiSize" is the amount of contiguity in the underlying - page. Normally this would be constant for the system, but, - that constant needs to be communicated, in case it's ever - different; caller guarantees that PMRLockSysPhysAddr() has - already been called */ - eError = PMR_DevPhysAddr(psPMR, - uiLog2HeapPageSize, - uiCount, - 0, - psDevPAddr, - pbValid); - PVR_GOTO_IF_ERROR(eError, put_mmu_context); - - OSLockAcquire(psMMUContext->hLock); - - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - uiFlushStart = uiPTEIndex; - - /* Map in all pages of that PMR page by page*/ - for (i=0, uiCount=0; uiCount < uiSizeBytes; i++) - { -#if defined(DEBUG) - { - IMG_INT32 i32FeatureVal = 0; - IMG_UINT32 ui32BitLength = FloorLog2(psDevPAddr[i].uiAddr); - i32FeatureVal = PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, PHYS_BUS_WIDTH); - do { - if (0 > i32FeatureVal) - break; - - if (ui32BitLength > i32FeatureVal) - { - PVR_DPF((PVR_DBG_ERROR, - "%s Failed. The physical address bitlength (%d)" - " is greater than the chip can handle (%d).", - __func__, ui32BitLength, i32FeatureVal)); - - PVR_ASSERT(ui32BitLength <= i32FeatureVal); - OSLockRelease(psMMUContext->hLock); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, put_mmu_context); - } - } while (0); - } -#endif /*DEBUG*/ -#if defined(PDUMP) - { - IMG_DEVMEM_OFFSET_T uiNextSymName; - - eError = PMR_PDumpSymbolicAddr(psPMR, uiCount, - sizeof(aszMemspaceName), &aszMemspaceName[0], - sizeof(aszSymbolicAddress), &aszSymbolicAddress[0], - &uiSymbolicAddrOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - ui32MappedCount++; - } -#endif /*PDUMP*/ - - HTBLOGK(HTB_SF_MMU_PAGE_OP_PMRMAP, - HTBLOG_U64_BITS_HIGH(sDevVAddr.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddr.uiAddr), - HTBLOG_U64_BITS_HIGH(psDevPAddr[i].uiAddr), HTBLOG_U64_BITS_LOW(psDevPAddr[i].uiAddr)); - - /* Set the PT entry with the specified address and protection flags */ - eError = _SetupPTE(psMMUContext, psLevel, uiPTEIndex, - psConfig, &psDevPAddr[i], IMG_FALSE, -#if defined(PDUMP) - aszMemspaceName, - aszSymbolicAddress, - uiSymbolicAddrOffset, -#endif /*PDUMP*/ - uiProtFlags); - PVR_GOTO_IF_ERROR(eError, unlock_mmu_context); - - sDevVAddr.uiAddr += uiPageSize; - uiCount += uiPageSize; - - /* Calculate PT index and get new table descriptor */ - if (uiPTEIndex < (psDevVAddrConfig->uiNumEntriesPT - 1) && (uiCount != uiSizeBytes)) - { - uiPTEIndex++; - } - else - { - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - PVR_GOTO_IF_ERROR(eError, unlock_mmu_context); - - - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - uiFlushStart = uiPTEIndex; - } - } - - OSLockRelease(psMMUContext->hLock); - - - _MMU_PutPTConfig(psMMUContext, hPriv); - - if (psDevPAddr != asDevPAddr) - { - OSFreeMem(pbValid); - OSFreeMem(psDevPAddr); - } - - /* Flush TLB for PTs*/ - psDevNode->pfnMMUCacheInvalidate(psDevNode, - psMMUContext, - MMU_LEVEL_1, - IMG_FALSE); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, "Wired up %d Page Table entries (out of %d)", ui32MappedCount, i); -#endif /*PDUMP*/ - - return PVRSRV_OK; - -unlock_mmu_context: - OSLockRelease(psMMUContext->hLock); - MMU_UnmapPMRFast(psMMUContext, - sDevVAddrBase, - uiSizeBytes >> uiLog2HeapPageSize, - uiLog2HeapPageSize); - -put_mmu_context: - _MMU_PutPTConfig(psMMUContext, hPriv); - - if (pbValid != abValid) - { - OSFreeMem(pbValid); - } - -free_paddr_array: - if (psDevPAddr != asDevPAddr) - { - OSFreeMem(psDevPAddr); - } - -return_error: - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} - -/* - MMU_UnmapPages - */ -void -MMU_UnmapPMRFast(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT32 ui32PageCount, - IMG_UINT32 uiLog2PageSize) -{ - IMG_UINT32 uiPTEIndex = 0, ui32Loop=0; - IMG_UINT32 uiPageSize = 1 << uiLog2PageSize; - MMU_Levelx_INFO *psLevel = NULL; - IMG_HANDLE hPriv; - const MMU_PxE_CONFIG *psConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_DEV_VIRTADDR sDevVAddr = sDevVAddrBase; - IMG_UINT64 uiProtFlags = 0; - MMU_PROTFLAGS_T uiMMUProtFlags = 0; - IMG_UINT64 uiEntry = 0; - IMG_UINT32 uiFlushStart = 0; - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - -#if defined(PDUMP) - PDUMPCOMMENT(psDevNode, - "Invalidate %d entries in page tables for virtual range: 0x%010"IMG_UINT64_FMTSPECX" to 0x%010"IMG_UINT64_FMTSPECX, - ui32PageCount, - (IMG_UINT64)sDevVAddr.uiAddr, - ((IMG_UINT64)sDevVAddr.uiAddr) + (uiPageSize*ui32PageCount)-1); -#endif - - /* Get PT and address configs */ - _MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2PageSize, - &psConfig, &hPriv, &psDevVAddrConfig); - - if (_MMU_ConvertDevMemFlags(IMG_TRUE, - 0, - &uiMMUProtFlags, - psMMUContext) != PVRSRV_OK) - { - return; - } - - /* Callback to get device specific protection flags */ - - if (psConfig->uiBytesPerEntry == 8) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2PageSize); - - /* Fill the entry with a bad address but leave space for protection flags */ - uiEntry = (gsBadDevPhyAddr.uiAddr & ~psConfig->uiProtMask) | uiProtFlags; - } - else if (psConfig->uiBytesPerEntry == 4) - { - uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags); - - /* Fill the entry with a bad address but leave space for protection flags */ - uiEntry = (((IMG_UINT32) gsBadDevPhyAddr.uiAddr) & ~psConfig->uiProtMask) | (IMG_UINT32) uiProtFlags; - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: The page table entry byte length is not supported", - __func__)); - goto e0; - } - - OSLockAcquire(psMMUContext->hLock); - - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - uiFlushStart = uiPTEIndex; - - /* Unmap page by page and keep the loop as quick as possible. - * Only use parts of _SetupPTE that need to be executed. */ - while (ui32Loop < ui32PageCount) - { - - /* Set the PT entry to invalid and poison it with a bad address */ - if (psConfig->uiBytesPerEntry == 8) - { - ((IMG_UINT64*)psLevel->sMemDesc.pvCpuVAddr)[uiPTEIndex] = uiEntry; - } - else - { - PVR_ASSERT(psConfig->uiBytesPerEntry == 4); - ((IMG_UINT32*)psLevel->sMemDesc.pvCpuVAddr)[uiPTEIndex] = (IMG_UINT32) uiEntry; - } - - /* Log modifications */ - HTBLOGK(HTB_SF_MMU_PAGE_OP_UNMAP, - HTBLOG_U64_BITS_HIGH(sDevVAddr.uiAddr), HTBLOG_U64_BITS_LOW(sDevVAddr.uiAddr)); - - HTBLOGK(HTB_SF_MMU_PAGE_OP_TABLE, - HTBLOG_PTR_BITS_HIGH(psLevel), HTBLOG_PTR_BITS_LOW(psLevel), - uiPTEIndex, MMU_LEVEL_1, - HTBLOG_U64_BITS_HIGH(uiEntry), HTBLOG_U64_BITS_LOW(uiEntry), - IMG_FALSE); - -#if defined(PDUMP) - PDumpMMUDumpPxEntries(psDevNode, - MMU_LEVEL_1, - psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName, - psLevel->sMemDesc.pvCpuVAddr, - psLevel->sMemDesc.sDevPAddr, - uiPTEIndex, - 1, - NULL, - NULL, - 0, - psConfig->uiBytesPerEntry, - psConfig->uiAddrLog2Align, - psConfig->uiAddrShift, - psConfig->uiAddrMask, - psConfig->uiProtMask, - psConfig->uiValidEnMask, - 0, - psMMUContext->psDevAttrs->eMMUType); -#endif /*PDUMP*/ - - sDevVAddr.uiAddr += uiPageSize; - ui32Loop++; - - /* Calculate PT index and get new table descriptor */ - if (uiPTEIndex < (psDevVAddrConfig->uiNumEntriesPT - 1) && (ui32Loop != ui32PageCount)) - { - uiPTEIndex++; - } - else - { - PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTEIndex); - uiFlushStart = uiPTEIndex; - } - } - - OSLockRelease(psMMUContext->hLock); - - _MMU_PutPTConfig(psMMUContext, hPriv); - - /* Flush TLB for PTs*/ - psDevNode->pfnMMUCacheInvalidate(psDevNode, - psMMUContext, - MMU_LEVEL_1, - IMG_TRUE); - - return; - -e0: - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map/unmap page table", __func__)); - PVR_ASSERT(0); - return; -} - -/* - MMU_ChangeValidity - */ -PVRSRV_ERROR -MMU_ChangeValidity(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiNumPages, - IMG_UINT32 uiLog2PageSize, - IMG_BOOL bMakeValid, - PMR *psPMR) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - IMG_HANDLE hPriv; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - const MMU_PxE_CONFIG *psConfig; - MMU_Levelx_INFO *psLevel = NULL; - IMG_UINT32 uiFlushStart = 0; - IMG_UINT32 uiPTIndex = 0; - IMG_UINT32 i; - IMG_UINT32 uiPageSize = 1 << uiLog2PageSize; - IMG_BOOL bValid; - - PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psPhysMemCtx->psDevNode; - -#if defined(PDUMP) - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - - PDUMPCOMMENT(psDevNode, - "Change valid bit of the data pages to %d (0x%"IMG_UINT64_FMTSPECX" - 0x%"IMG_UINT64_FMTSPECX")", - bMakeValid, - sDevVAddr.uiAddr, - sDevVAddr.uiAddr + (uiNumPages<uiBytesPerEntry == 8) - { - ((IMG_UINT64 *)psLevel->sMemDesc.pvCpuVAddr)[uiPTIndex] |= (psConfig->uiValidEnMask); - } - else if (psConfig->uiBytesPerEntry == 4) - { - ((IMG_UINT32 *)psLevel->sMemDesc.pvCpuVAddr)[uiPTIndex] |= (psConfig->uiValidEnMask); - } - else - { - PVR_LOG_GOTO_WITH_ERROR("psConfig->uiBytesPerEntry", eError, PVRSRV_ERROR_MMU_CONFIG_IS_WRONG, e_exit); - } - } - } - else - { - if (psConfig->uiBytesPerEntry == 8) - { - ((IMG_UINT64 *)psLevel->sMemDesc.pvCpuVAddr)[uiPTIndex] &= ~(psConfig->uiValidEnMask); - } - else if (psConfig->uiBytesPerEntry == 4) - { - ((IMG_UINT32 *)psLevel->sMemDesc.pvCpuVAddr)[uiPTIndex] &= ~(psConfig->uiValidEnMask); - } - else - { - PVR_LOG_GOTO_WITH_ERROR("psConfig->uiBytesPerEntry", eError, PVRSRV_ERROR_MMU_CONFIG_IS_WRONG, e_exit); - } - } - -#if defined(PDUMP) - - PMR_PDumpSymbolicAddr(psPMR, i<psDevAttrs->pszMMUPxPDumpMemSpaceName, - psLevel->sMemDesc.pvCpuVAddr, - psLevel->sMemDesc.sDevPAddr, - uiPTIndex, - 1, - aszMemspaceName, - aszSymbolicAddress, - uiSymbolicAddrOffset, - psConfig->uiBytesPerEntry, - psConfig->uiAddrLog2Align, - psConfig->uiAddrShift, - psConfig->uiAddrMask, - psConfig->uiProtMask, - psConfig->uiValidEnMask, - 0, - psMMUContext->psDevAttrs->eMMUType); -#endif /*PDUMP*/ - - sDevVAddr.uiAddr += uiPageSize; - i++; - - /* Calculate PT index and get new table descriptor */ - if (uiPTIndex < (psDevVAddrConfig->uiNumEntriesPT - 1) && (i != uiNumPages)) - { - uiPTIndex++; - } - else - { - - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - &psLevel->sMemDesc.psMapping->sMemHandle, - uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset, - (uiPTIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry); - PVR_GOTO_IF_ERROR(eError, e_exit); - - _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig, - &psLevel, &uiPTIndex); - uiFlushStart = uiPTIndex; - } - } - -e_exit: - - _MMU_PutPTConfig(psMMUContext, hPriv); - - /* Flush TLB for PTs*/ - psDevNode->pfnMMUCacheInvalidate(psDevNode, - psMMUContext, - MMU_LEVEL_1, - !bMakeValid); - - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} - - -/* - MMU_AcquireBaseAddr - */ -PVRSRV_ERROR -MMU_AcquireBaseAddr(MMU_CONTEXT *psMMUContext, IMG_DEV_PHYADDR *psPhysAddr) -{ - if (!psMMUContext) - { - psPhysAddr->uiAddr = 0; - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *psPhysAddr = psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr; - - return PVRSRV_OK; -} - -/* - MMU_AcquireCPUBaseAddr - */ -PVRSRV_ERROR -MMU_AcquireCPUBaseAddr(MMU_CONTEXT *psMMUContext, void **ppvCPUVAddr) -{ - if (!psMMUContext) - { - *ppvCPUVAddr = NULL; - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *ppvCPUVAddr = psMMUContext->sBaseLevelInfo.sMemDesc.pvCpuVAddr; - - return PVRSRV_OK; -} - -/* - MMU_ReleaseBaseAddr - */ -void -MMU_ReleaseBaseAddr(MMU_CONTEXT *psMMUContext) -{ - PVR_UNREFERENCED_PARAMETER(psMMUContext); -} - -/* - MMU_AppendCacheFlags, MMU_ExchangeCacheFlags -*/ - -void MMU_AppendCacheFlags(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32AppendFlags) -{ - PVR_ASSERT(psMMUContext != NULL); - - if (psMMUContext == NULL) - { - return; - } - - OSAtomicOr(&psMMUContext->sCacheFlags, (IMG_INT)ui32AppendFlags); -} - -IMG_UINT32 MMU_ExchangeCacheFlags(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32NewCacheFlags) -{ - PVR_ASSERT(psMMUContext != NULL); - - if (psMMUContext == NULL) - { - return 0; - } - - return (IMG_UINT32)OSAtomicExchange(&psMMUContext->sCacheFlags, (IMG_INT)ui32NewCacheFlags); -} - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -/* - MMU_GetOSids - */ - -void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 *pui32OSid, IMG_UINT32 *pui32OSidReg, IMG_BOOL *pbOSidAxiProt) -{ - *pui32OSid = psMMUContext->psPhysMemCtx->ui32OSid; - *pui32OSidReg = psMMUContext->psPhysMemCtx->ui32OSidReg; - *pbOSidAxiProt = psMMUContext->psPhysMemCtx->bOSidAxiProt; - - return; -} - -#endif - -/* - MMU_CheckFaultAddress - */ -void MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR *psDevVAddr, - MMU_FAULT_DATA *psOutFaultData) -{ - /* Ideally the RGX defs should be via callbacks, but the function is only called from RGX. */ -#if defined(SUPPORT_RGX) -# define MMU_MASK_VALID_FOR_32BITS(level) \ - ((RGX_MMUCTRL_##level##_DATA_ENTRY_PENDING_EN | \ - RGX_MMUCTRL_##level##_DATA_VALID_EN) <= 0xFFFFFFFF) -# define MMU_VALID_STR(entry,level) \ - (apszMMUValidStr[((((entry)&(RGX_MMUCTRL_##level##_DATA_ENTRY_PENDING_EN))!=0) << 1)| \ - ((((entry)&(RGX_MMUCTRL_##level##_DATA_VALID_EN))!=0) << 0)]) - static const IMG_PCHAR apszMMUValidStr[1<<2] = {/*--*/ "not valid", - /*-V*/ "valid", - /*P-*/ "pending", - /*PV*/ "inconsistent (pending and valid)"}; -#else -# define MMU_MASK_VALID_FOR_32BITS(level) 0 -# define MMU_VALID_STR(entry,level) ("??") -#endif - MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs; - MMU_LEVEL eMMULevel = psDevAttrs->eTopLevel; - const MMU_PxE_CONFIG *psConfig; - const MMU_PxE_CONFIG *psMMUPDEConfig; - const MMU_PxE_CONFIG *psMMUPTEConfig; - const MMU_DEVVADDR_CONFIG *psMMUDevVAddrConfig; - IMG_HANDLE hPriv; - MMU_Levelx_INFO *psLevel = NULL; - PVRSRV_ERROR eError; - IMG_UINT64 uiIndex; - IMG_UINT32 ui32PCIndex = 0xFFFFFFFF; - IMG_UINT32 ui32PDIndex = 0xFFFFFFFF; - IMG_UINT32 ui32PTIndex = 0xFFFFFFFF; - IMG_UINT32 ui32Log2PageSize; - MMU_FAULT_DATA sMMUFaultData = {0}; - MMU_LEVEL_DATA *psMMULevelData; - - OSLockAcquire(psMMUContext->hLock); - - /* - At this point we don't know the page size so assume it's 4K. - When we get the PD level (MMU_LEVEL_2) we can check to see - if this assumption is correct. - */ - eError = psDevAttrs->pfnGetPageSizeConfiguration(12, - &psMMUPDEConfig, - &psMMUPTEConfig, - &psMMUDevVAddrConfig, - &hPriv); - if (eError != PVRSRV_OK) - { - PVR_LOG(("Failed to get the page size info for log2 page sizeof 12")); - } - - psLevel = &psMMUContext->sBaseLevelInfo; - psConfig = psDevAttrs->psBaseConfig; - - sMMUFaultData.eTopLevel = psDevAttrs->eTopLevel; - sMMUFaultData.eType = MMU_FAULT_TYPE_NON_PM; - - - for (; eMMULevel > MMU_LEVEL_0; eMMULevel--) - { - if (eMMULevel == MMU_LEVEL_3) - { - /* Determine the PC index */ - uiIndex = psDevVAddr->uiAddr & psDevAttrs->psTopLevelDevVAddrConfig->uiPCIndexMask; - uiIndex = uiIndex >> psDevAttrs->psTopLevelDevVAddrConfig->uiPCIndexShift; - ui32PCIndex = (IMG_UINT32) uiIndex; - PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PCIndex)); - - psMMULevelData = &sMMUFaultData.sLevelData[MMU_LEVEL_3]; - psMMULevelData->uiBytesPerEntry = psConfig->uiBytesPerEntry; - psMMULevelData->ui32Index = ui32PCIndex; - - if (ui32PCIndex >= psLevel->ui32NumOfEntries) - { - psMMULevelData->ui32NumOfEntries = psLevel->ui32NumOfEntries; - break; - } - - if (psConfig->uiBytesPerEntry == 4) - { - IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui32Ptr[ui32PCIndex]; - if (MMU_MASK_VALID_FOR_32BITS(PC)) - { - psMMULevelData->psDebugStr = MMU_VALID_STR(pui32Ptr[ui32PCIndex] & psConfig->uiProtMask, PC); - } - else - { - psMMULevelData->psDebugStr = ""; - PVR_LOG(("Invalid RGX_MMUCTRL_PC_DATA_ENTRY mask for 32-bit entry")); - } - } - else - { - IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui64Ptr[ui32PCIndex]; - psMMULevelData->psDebugStr = MMU_VALID_STR(pui64Ptr[ui32PCIndex] & psConfig->uiProtMask, PC); - - } - - psLevel = psLevel->apsNextLevel[ui32PCIndex]; - if (!psLevel) - { - break; - } - psConfig = psMMUPDEConfig; - continue; /* continue to the next level */ - } - - - if (eMMULevel == MMU_LEVEL_2) - { - /* Determine the PD index */ - uiIndex = psDevVAddr->uiAddr & psDevAttrs->psTopLevelDevVAddrConfig->uiPDIndexMask; - uiIndex = uiIndex >> psDevAttrs->psTopLevelDevVAddrConfig->uiPDIndexShift; - ui32PDIndex = (IMG_UINT32) uiIndex; - PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PDIndex)); - - psMMULevelData = &sMMUFaultData.sLevelData[MMU_LEVEL_2]; - psMMULevelData->uiBytesPerEntry = psConfig->uiBytesPerEntry; - psMMULevelData->ui32Index = ui32PDIndex; - - if (ui32PDIndex >= psLevel->ui32NumOfEntries) - { - psMMULevelData->ui32NumOfEntries = psLevel->ui32NumOfEntries; - break; - } - - if (psConfig->uiBytesPerEntry == 4) - { - IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui32Ptr[ui32PDIndex]; - if (MMU_MASK_VALID_FOR_32BITS(PD)) - { - psMMULevelData->psDebugStr = MMU_VALID_STR(pui32Ptr[ui32PDIndex] & psMMUPDEConfig->uiProtMask, PD); - } - else - { - psMMULevelData->psDebugStr = ""; - PVR_LOG(("Invalid RGX_MMUCTRL_PD_DATA_ENTRY mask for 32-bit entry")); - } - - if (psDevAttrs->pfnGetPageSizeFromPDE4(pui32Ptr[ui32PDIndex], &ui32Log2PageSize) != PVRSRV_OK) - { - PVR_LOG(("Failed to get the page size from the PDE")); - } - } - else - { - IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui64Ptr[ui32PDIndex]; - psMMULevelData->psDebugStr = MMU_VALID_STR(pui64Ptr[ui32PDIndex] & psMMUPDEConfig->uiProtMask, PD); - - if (psDevAttrs->pfnGetPageSizeFromVirtAddr != NULL) - { - /* MMU_VERSION >= 4 */ - if (psDevAttrs->pfnGetPageSizeFromVirtAddr(psMMUContext->psPhysMemCtx->psDevNode, *psDevVAddr, &ui32Log2PageSize) != PVRSRV_OK) - { - PVR_LOG(("Failed to get the page size from the virtual address")); - } - } - else if (psDevAttrs->pfnGetPageSizeFromPDE8(pui64Ptr[ui32PDIndex], &ui32Log2PageSize) != PVRSRV_OK) - { - PVR_LOG(("Failed to get the page size from the PDE")); - } - } - - /* - We assumed the page size was 4K, now we have the actual size - from the PDE we can confirm if our assumption was correct. - Until now it hasn't mattered as the PC and PD are the same - regardless of the page size - */ - if (ui32Log2PageSize != 12) - { - /* Put the 4K page size data */ - psDevAttrs->pfnPutPageSizeConfiguration(hPriv); - - /* Get the correct size data */ - eError = psDevAttrs->pfnGetPageSizeConfiguration(ui32Log2PageSize, - &psMMUPDEConfig, - &psMMUPTEConfig, - &psMMUDevVAddrConfig, - &hPriv); - if (eError != PVRSRV_OK) - { - PVR_LOG(("Failed to get the page size info for log2 page sizeof %d", ui32Log2PageSize)); - break; - } - } - psLevel = psLevel->apsNextLevel[ui32PDIndex]; - if (!psLevel) - { - break; - } - psConfig = psMMUPTEConfig; - continue; /* continue to the next level */ - } - - - if (eMMULevel == MMU_LEVEL_1) - { - /* Determine the PT index */ - uiIndex = psDevVAddr->uiAddr & psMMUDevVAddrConfig->uiPTIndexMask; - uiIndex = uiIndex >> psMMUDevVAddrConfig->uiPTIndexShift; - ui32PTIndex = (IMG_UINT32) uiIndex; - PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PTIndex)); - - psMMULevelData = &sMMUFaultData.sLevelData[MMU_LEVEL_1]; - psMMULevelData->uiBytesPerEntry = psConfig->uiBytesPerEntry; - psMMULevelData->ui32Index = ui32PTIndex; - - if (ui32PTIndex >= psLevel->ui32NumOfEntries) - { - psMMULevelData->ui32NumOfEntries = psLevel->ui32NumOfEntries; - break; - } - - if (psConfig->uiBytesPerEntry == 4) - { - IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui32Ptr[ui32PTIndex]; - if (MMU_MASK_VALID_FOR_32BITS(PT)) - { - psMMULevelData->psDebugStr = MMU_VALID_STR(pui32Ptr[ui32PTIndex] & psMMUPTEConfig->uiProtMask, PT); - } - else - { - psMMULevelData->psDebugStr = ""; - PVR_LOG(("Invalid RGX_MMUCTRL_PT_DATA_ENTRY mask for 32-bit entry")); - } - } - else - { - IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr; - - psMMULevelData->ui64Address = pui64Ptr[ui32PTIndex]; - psMMULevelData->psDebugStr = MMU_VALID_STR(pui64Ptr[ui32PTIndex] & psMMUPTEConfig->uiProtMask, PT); - - } - goto e1; - } - - PVR_LOG(("Unsupported MMU setup: %d", eMMULevel)); - break; - } - -e1: - /* Put the page size data back */ - psDevAttrs->pfnPutPageSizeConfiguration(hPriv); - OSLockRelease(psMMUContext->hLock); - - *psOutFaultData = sMMUFaultData; -} - -static IMG_UINT64 MMU_GetVDevAddrPTE(MMU_CONTEXT *psMMUContext, - const MMU_PxE_CONFIG *psConfig, - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig, - IMG_UINT32 uiLog2PageSize, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_BOOL *pbStatusOut) -{ - MMU_Levelx_INFO *psLevel = NULL; - IMG_UINT32 uiIndex = 0; - IMG_BOOL bStatus = IMG_FALSE; - IMG_UINT64 ui64Entry = 0; - - OSLockAcquire(psMMUContext->hLock); - - switch (psMMUContext->psDevAttrs->eTopLevel) - { - case MMU_LEVEL_3: - uiIndex = _CalcPCEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE); - psLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiIndex]; - if (psLevel == NULL) - break; - - fallthrough; - case MMU_LEVEL_2: - uiIndex = _CalcPDEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE); - - if (psLevel != NULL) - psLevel = psLevel->apsNextLevel[uiIndex]; - else - psLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiIndex]; - - if (psLevel == NULL) - break; - - fallthrough; - case MMU_LEVEL_1: - uiIndex = _CalcPTEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE); - - if (psLevel == NULL) - psLevel = &psMMUContext->sBaseLevelInfo; - - ui64Entry = ((IMG_UINT64 *)psLevel->sMemDesc.pvCpuVAddr)[uiIndex]; - bStatus = ui64Entry & psConfig->uiValidEnMask; - - break; - default: - PVR_LOG(("MMU_IsVDevAddrValid: Unsupported MMU setup")); - break; - } - - OSLockRelease(psMMUContext->hLock); - - *pbStatusOut = bStatus; - - return ui64Entry; -} - -IMG_BOOL MMU_IsVDevAddrValid(MMU_CONTEXT *psMMUContext, - IMG_UINT32 uiLog2PageSize, - IMG_DEV_VIRTADDR sDevVAddr) -{ - IMG_BOOL bStatus; - const MMU_PxE_CONFIG *psConfig; - IMG_HANDLE hPriv; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - - _MMU_GetPTConfig(psMMUContext, uiLog2PageSize, &psConfig, &hPriv, &psDevVAddrConfig); - - MMU_GetVDevAddrPTE(psMMUContext, - psConfig, - psDevVAddrConfig, - uiLog2PageSize, - sDevVAddr, - &bStatus); - - _MMU_PutPTConfig(psMMUContext, hPriv); - - return bStatus; -} - -#if defined(PDUMP) -/* - MMU_ContextDerivePCPDumpSymAddr - */ -PVRSRV_ERROR MMU_ContextDerivePCPDumpSymAddr(MMU_CONTEXT *psMMUContext, - IMG_CHAR *pszPDumpSymbolicNameBuffer, - size_t uiPDumpSymbolicNameBufferSize) -{ - size_t uiCount; - IMG_UINT64 ui64PhysAddr; - PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psPhysMemCtx->psDevNode->sDevId; - - if (!psMMUContext->sBaseLevelInfo.sMemDesc.bValid) - { - /* We don't have any allocations. You're not allowed to ask - * for the page catalogue base address until you've made at - * least one allocation. - */ - return PVRSRV_ERROR_MMU_API_PROTOCOL_ERROR; - } - - ui64PhysAddr = (IMG_UINT64)psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr.uiAddr; - - PVR_ASSERT(uiPDumpSymbolicNameBufferSize >= (IMG_UINT32)(21 + OSStringLength(psDevId->pszPDumpDevName))); - - /* Page table Symbolic Name is formed from page table phys addr - prefixed with MMUPT_. */ - uiCount = OSSNPrintf(pszPDumpSymbolicNameBuffer, - uiPDumpSymbolicNameBufferSize, - ":%s:%s%016"IMG_UINT64_FMTSPECX, - psDevId->pszPDumpDevName, - psMMUContext->sBaseLevelInfo.sMemDesc.bValid?"MMUPC_":"XXX", - ui64PhysAddr); - - if (uiCount + 1 > uiPDumpSymbolicNameBufferSize) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - -/* - MMU_PDumpWritePageCatBase - */ -PVRSRV_ERROR -MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext, - const IMG_CHAR *pszSpaceName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32WordSize, - IMG_UINT32 ui32AlignShift, - IMG_UINT32 ui32Shift, - PDUMP_FLAGS_T uiPdumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszPageCatBaseSymbolicAddr[100]; - const IMG_CHAR *pszPDumpDevName = psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName; - - eError = MMU_ContextDerivePCPDumpSymAddr(psMMUContext, - &aszPageCatBaseSymbolicAddr[0], - sizeof(aszPageCatBaseSymbolicAddr)); - if (eError == PVRSRV_OK) - { - eError = PDumpWriteSymbAddress(psMMUContext->psPhysMemCtx->psDevNode, - pszSpaceName, - uiOffset, - aszPageCatBaseSymbolicAddr, - 0, /* offset -- Could be non-zero for var. pgsz */ - pszPDumpDevName, - ui32WordSize, - ui32AlignShift, - ui32Shift, - uiPdumpFlags | PDUMP_FLAGS_CONTINUOUS); - } - - return eError; -} - -/* - MMU_AcquirePDumpMMUContext - */ -PVRSRV_ERROR MMU_AcquirePDumpMMUContext(MMU_CONTEXT *psMMUContext, - IMG_UINT32 *pui32PDumpMMUContextID, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psPhysMemCtx->psDevNode->sDevId; - - if (!psMMUContext->ui32PDumpContextIDRefCount) - { - PDUMP_MMU_ALLOC_MMUCONTEXT(psMMUContext->psPhysMemCtx->psDevNode, - psDevId->pszPDumpDevName, - psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr, - psMMUContext->psDevAttrs->eMMUType, - &psMMUContext->uiPDumpContextID, - ui32PDumpFlags); - } - - psMMUContext->ui32PDumpContextIDRefCount++; - *pui32PDumpMMUContextID = psMMUContext->uiPDumpContextID; - - return PVRSRV_OK; -} - -/* - MMU_ReleasePDumpMMUContext - */ -PVRSRV_ERROR MMU_ReleasePDumpMMUContext(MMU_CONTEXT *psMMUContext, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psPhysMemCtx->psDevNode->sDevId; - - PVR_ASSERT(psMMUContext->ui32PDumpContextIDRefCount != 0); - psMMUContext->ui32PDumpContextIDRefCount--; - - if (psMMUContext->ui32PDumpContextIDRefCount == 0) - { - PDUMP_MMU_FREE_MMUCONTEXT(psMMUContext->psPhysMemCtx->psDevNode, - psDevId->pszPDumpDevName, - psMMUContext->uiPDumpContextID, - ui32PDumpFlags); - } - - return PVRSRV_OK; -} -#endif - -/****************************************************************************** - End of file (mmu_common.c) - ******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/mmu_common.h b/drivers/gpu/drm/img-rogue/1.17/mmu_common.h deleted file mode 100644 index a84fa697f572b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mmu_common.h +++ /dev/null @@ -1,792 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common MMU Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements basic low level control of MMU. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 MMU_COMMON_H -#define MMU_COMMON_H - -/* - The Memory Management Unit (MMU) performs device virtual to physical - translation. - - Terminology: - - page catalogue, PC (optional, 3 tier MMU) - - page directory, PD - - page table, PT (can be variable sized) - - data page, DP (can be variable sized) - Note: PD and PC are fixed size and can't be larger than the native - physical (CPU) page size - Shifts and AlignShift variables: - - 'xxxShift' represent the number of bits a bitfield is shifted left from bit0 - - 'xxxAlignShift' is used to convert a bitfield (based at bit0) into byte units - by applying a bit shift left by 'xxxAlignShift' bits -*/ - -/* - Device Virtual Address Config: - - Incoming Device Virtual Address is deconstructed into up to 4 - fields, where the virtual address is up to 64bits: - MSB-----------------------------------------------LSB - | PC Index: | PD Index: | PT Index: | DP offset: | - | d bits | c bits | b-v bits | a+v bits | - ----------------------------------------------------- - where v is the variable page table modifier, e.g. - v == 0 -> 4KB DP - v == 2 -> 16KB DP - v == 4 -> 64KB DP - v == 6 -> 256KB DP - v == 8 -> 1MB DP - v == 10 -> 4MB DP -*/ - -/* services/server/include/ */ -#include "pmr.h" - -/* include/ */ -#include "img_types.h" -#include "img_defs.h" -#include "pvr_notifier.h" -#include "pvrsrv_error.h" -#include "servicesext.h" - - -/*! - The level of the MMU -*/ -typedef enum -{ - MMU_LEVEL_0 = 0, /* Level 0 = Page */ - - MMU_LEVEL_1, - MMU_LEVEL_2, - MMU_LEVEL_3, - MMU_LEVEL_LAST -} MMU_LEVEL; - -/* moved after declaration of MMU_LEVEL, as pdump_mmu.h references it */ -#include "pdump_mmu.h" - -#define MMU_MAX_LEVEL 3 - -typedef struct _MMU_LEVEL_DATA_ -{ - IMG_UINT32 ui32Index; - IMG_UINT32 ui32NumOfEntries; - IMG_CHAR const *psDebugStr; - IMG_UINT8 uiBytesPerEntry; - IMG_UINT64 ui64Address; -} MMU_LEVEL_DATA; - -typedef enum _MMU_FAULT_TYPE_ -{ - MMU_FAULT_TYPE_UNKNOWN = 0, /* If fault is not analysed by Host */ - MMU_FAULT_TYPE_PM, - MMU_FAULT_TYPE_NON_PM, -} MMU_FAULT_TYPE; - -typedef struct _MMU_FAULT_DATA_ -{ - MMU_LEVEL eTopLevel; - MMU_FAULT_TYPE eType; - MMU_LEVEL_DATA sLevelData[MMU_LEVEL_LAST]; -} MMU_FAULT_DATA; - -struct _MMU_DEVVADDR_CONFIG_; - -/*! - MMU device attributes. This structure is the interface between the generic - MMU code and the device specific MMU code. -*/ -typedef struct _MMU_DEVICEATTRIBS_ -{ - PDUMP_MMU_TYPE eMMUType; - - IMG_CHAR *pszMMUPxPDumpMemSpaceName; - - /*! The type of the top level object */ - MMU_LEVEL eTopLevel; - - /*! Alignment requirement of the base object */ - IMG_UINT32 ui32BaseAlign; - - /*! HW config of the base object */ - struct _MMU_PxE_CONFIG_ *psBaseConfig; - - /*! Address split for the base object */ - const struct _MMU_DEVVADDR_CONFIG_ *psTopLevelDevVAddrConfig; - - /*! Callback for creating protection bits for the page catalogue entry with 8 byte entry */ - IMG_UINT64 (*pfnDerivePCEProt8)(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); - /*! Callback for creating protection bits for the page catalogue entry with 4 byte entry */ - IMG_UINT32 (*pfnDerivePCEProt4)(IMG_UINT32 uiProtFlags); - /*! Callback for creating protection bits for the page directory entry with 8 byte entry */ - IMG_UINT64 (*pfnDerivePDEProt8)(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); - /*! Callback for creating protection bits for the page directory entry with 4 byte entry */ - IMG_UINT32 (*pfnDerivePDEProt4)(IMG_UINT32 uiProtFlags); - /*! Callback for creating protection bits for the page table entry with 8 byte entry */ - IMG_UINT64 (*pfnDerivePTEProt8)(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); - /*! Callback for creating protection bits for the page table entry with 4 byte entry */ - IMG_UINT32 (*pfnDerivePTEProt4)(IMG_UINT32 uiProtFlags); - - /*! Callback for getting the MMU configuration based on the specified page size */ - PVRSRV_ERROR (*pfnGetPageSizeConfiguration)(IMG_UINT32 ui32DataPageSize, - const struct _MMU_PxE_CONFIG_ **ppsMMUPDEConfig, - const struct _MMU_PxE_CONFIG_ **ppsMMUPTEConfig, - const struct _MMU_DEVVADDR_CONFIG_ **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv2); - /*! Callback for putting the MMU configuration obtained from pfnGetPageSizeConfiguration */ - PVRSRV_ERROR (*pfnPutPageSizeConfiguration)(IMG_HANDLE hPriv); - - /*! Callback for getting the page size from the PDE for the page table entry with 4 byte entry */ - PVRSRV_ERROR (*pfnGetPageSizeFromPDE4)(IMG_UINT32, IMG_UINT32 *); - /*! Callback for getting the page size from the PDE for the page table entry with 8 byte entry */ - PVRSRV_ERROR (*pfnGetPageSizeFromPDE8)(IMG_UINT64, IMG_UINT32 *); - /*! Callback for getting the page size directly from the address. Supported on MMU4 */ - PVRSRV_ERROR (*pfnGetPageSizeFromVirtAddr)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_DEV_VIRTADDR, IMG_UINT32 *); - - /*! Private data handle */ - IMG_HANDLE hGetPageSizeFnPriv; -} MMU_DEVICEATTRIBS; - -/*! - MMU virtual address split -*/ -typedef struct _MMU_DEVVADDR_CONFIG_ -{ - /*! Page catalogue index mask */ - IMG_UINT64 uiPCIndexMask; - /*! Page catalogue index shift */ - IMG_UINT8 uiPCIndexShift; - /*! Total number of PC entries */ - IMG_UINT32 uiNumEntriesPC; - /*! Page directory mask */ - IMG_UINT64 uiPDIndexMask; - /*! Page directory shift */ - IMG_UINT8 uiPDIndexShift; - /*! Total number of PD entries */ - IMG_UINT32 uiNumEntriesPD; - /*! Page table mask */ - IMG_UINT64 uiPTIndexMask; - /*! Page index shift */ - IMG_UINT8 uiPTIndexShift; - /*! Total number of PT entries */ - IMG_UINT32 uiNumEntriesPT; - /*! Page offset mask */ - IMG_UINT64 uiPageOffsetMask; - /*! Page offset shift */ - IMG_UINT8 uiPageOffsetShift; - /*! First virtual address mappable for this config */ - IMG_UINT64 uiOffsetInBytes; - -} MMU_DEVVADDR_CONFIG; - -/* - P(C/D/T) Entry Config: - - MSB-----------------------------------------------LSB - | PT Addr: | variable PT ctrl | protection flags: | - | bits c+v | b bits | a bits | - ----------------------------------------------------- - where v is the variable page table modifier and is optional -*/ -/*! - Generic MMU entry description. This is used to describe PC, PD and PT entries. -*/ -typedef struct _MMU_PxE_CONFIG_ -{ - IMG_UINT8 uiBytesPerEntry; /*! Size of an entry in bytes */ - - IMG_UINT64 uiAddrMask; /*! Physical address mask */ - IMG_UINT8 uiAddrShift; /*! Physical address shift */ - IMG_UINT8 uiAddrLog2Align; /*! Physical address Log 2 alignment */ - - IMG_UINT64 uiVarCtrlMask; /*! Variable control mask */ - IMG_UINT8 uiVarCtrlShift; /*! Variable control shift */ - - IMG_UINT64 uiProtMask; /*! Protection flags mask */ - IMG_UINT8 uiProtShift; /*! Protection flags shift */ - - IMG_UINT64 uiValidEnMask; /*! Entry valid bit mask */ - IMG_UINT8 uiValidEnShift; /*! Entry valid bit shift */ -} MMU_PxE_CONFIG; - -/* MMU Protection flags */ - - -/* These are specified generically and in a h/w independent way, and - are interpreted at each level (PC/PD/PT) separately. */ - -/* The following flags are for internal use only, and should not - traverse the API */ -#define MMU_PROTFLAGS_INVALID 0x80000000U - -typedef IMG_UINT32 MMU_PROTFLAGS_T; - -/* The following flags should be supplied by the caller: */ -#define MMU_PROTFLAGS_READABLE (1U<<0) -#define MMU_PROTFLAGS_WRITEABLE (1U<<1) -#define MMU_PROTFLAGS_CACHE_COHERENT (1U<<2) -#define MMU_PROTFLAGS_CACHED (1U<<3) - -/* Device specific flags*/ -#define MMU_PROTFLAGS_DEVICE_OFFSET 16 -#define MMU_PROTFLAGS_DEVICE_MASK 0x000f0000UL -#define MMU_PROTFLAGS_DEVICE(n) \ - (((n) << MMU_PROTFLAGS_DEVICE_OFFSET) & \ - MMU_PROTFLAGS_DEVICE_MASK) - - -typedef struct _MMU_CONTEXT_ MMU_CONTEXT; - -struct _PVRSRV_DEVICE_NODE_; - -struct _CONNECTION_DATA_; - -typedef struct _MMU_PAGESIZECONFIG_ -{ - const MMU_PxE_CONFIG *psPDEConfig; - const MMU_PxE_CONFIG *psPTEConfig; - const MMU_DEVVADDR_CONFIG *psDevVAddrConfig; - IMG_UINT32 uiRefCount; - IMG_UINT32 uiMaxRefCount; -} MMU_PAGESIZECONFIG; - -/*************************************************************************/ /*! -@Function MMU_ContextCreate - -@Description Create a new MMU context - -@Input psConnection Connection requesting the MMU context - creation. Can be NULL for kernel/FW - memory context. -@Input psDevNode Device node of the device to create the - MMU context for -@Output ppsMMUContext The created MMU context - -@Return PVRSRV_OK if the MMU context was successfully created -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_ContextCreate(struct _CONNECTION_DATA_ *psConnection, - struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_CONTEXT **ppsMMUContext, - MMU_DEVICEATTRIBS *psDevAttrs); - - -/*************************************************************************/ /*! -@Function MMU_ContextDestroy - -@Description Destroy a MMU context - -@Input psMMUContext MMU context to destroy - -@Return None -*/ -/*****************************************************************************/ -void -MMU_ContextDestroy(MMU_CONTEXT *psMMUContext); - -/*************************************************************************/ /*! -@Function MMU_Alloc - -@Description Allocate the page tables required for the specified virtual range - -@Input psMMUContext MMU context to operate on - -@Input uSize The size of the allocation - -@Output puActualSize Actual size of allocation - -@Input uiProtFlags Generic MMU protection flags - -@Input uDevVAddrAlignment Alignment requirement of the virtual - allocation - -@Input psDevVAddr Virtual address to start the allocation - from - -@Return PVRSRV_OK if the allocation of the page tables was successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_Alloc(MMU_CONTEXT *psMMUContext, - IMG_DEVMEM_SIZE_T uSize, - IMG_DEVMEM_SIZE_T *puActualSize, - IMG_UINT32 uiProtFlags, - IMG_DEVMEM_SIZE_T uDevVAddrAlignment, - IMG_DEV_VIRTADDR *psDevVAddr, - IMG_UINT32 uiLog2PageSize); - - -/*************************************************************************/ /*! -@Function MMU_Free - -@Description Free the page tables of the specified virtual range - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddr Virtual address to start the free - from - -@Input uiSize The size of the allocation - -@Return None -*/ -/*****************************************************************************/ -void -MMU_Free(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiLog2DataPageSize); - - -/*************************************************************************/ /*! -@Function MMU_MapPages - -@Description Map pages to the MMU. - Two modes of operation: One requires a list of physical page - indices that are going to be mapped, the other just takes - the PMR and a possible offset to map parts of it. - -@Input psMMUContext MMU context to operate on - -@Input uiMappingFlags Memalloc flags for the mapping - -@Input sDevVAddrBase Device virtual address of the 1st page - -@Input psPMR PMR to map - -@Input ui32PhysPgOffset Physical offset into the PMR - -@Input ui32MapPageCount Number of pages to map - -@Input paui32MapIndices List of page indices to map, - can be NULL - -@Input uiLog2PageSize Log2 page size of the pages to map - -@Return PVRSRV_OK if the mapping was successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_MapPages(MMU_CONTEXT *psMMUContext, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_DEV_VIRTADDR sDevVAddrBase, - PMR *psPMR, - IMG_UINT32 ui32PhysPgOffset, - IMG_UINT32 ui32MapPageCount, - IMG_UINT32 *paui32MapIndices, - IMG_UINT32 uiLog2PageSize); - -/*************************************************************************/ /*! -@Function MMU_UnmapPages - -@Description Unmap pages from the MMU. - -@Input psMMUContext MMU context to operate on - -@Input uiMappingFlags Memalloc flags for the mapping - -@Input sDevVAddr Device virtual address of the 1st page - -@Input ui32PageCount Number of pages to unmap - -@Input pai32UnmapIndicies Array of page indices to be unmapped - -@Input uiLog2PageSize log2 size of the page - - -@Input uiMemAllocFlags Indicates if the unmapped regions need - to be backed by dummy or zero page - -@Return None -*/ -/*****************************************************************************/ -void -MMU_UnmapPages(MMU_CONTEXT *psMMUContext, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_UINT32 ui32PageCount, - IMG_UINT32 *pai32UnmapIndicies, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags); - -/*************************************************************************/ /*! -@Function MMU_MapPMRFast - -@Description Map a PMR into the MMU. Must be not sparse. - This is supposed to cover most mappings and, as the name suggests, - should be as fast as possible. - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddr Device virtual address to map the PMR - into - -@Input psPMR PMR to map - -@Input uiSizeBytes Size in bytes to map - -@Input uiMappingFlags Memalloc flags for the mapping - -@Return PVRSRV_OK if the PMR was successfully mapped -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_MapPMRFast(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - const PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSizeBytes, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags, - IMG_UINT32 uiLog2PageSize); - -/*************************************************************************/ /*! -@Function MMU_UnmapPMRFast - -@Description Unmap pages from the MMU as fast as possible. - PMR must be non-sparse! - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddrBase Device virtual address of the 1st page - -@Input ui32PageCount Number of pages to unmap - -@Input uiLog2PageSize log2 size of the page - -@Return None -*/ -/*****************************************************************************/ -void -MMU_UnmapPMRFast(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddrBase, - IMG_UINT32 ui32PageCount, - IMG_UINT32 uiLog2PageSize); - -/*************************************************************************/ /*! -@Function MMU_ChangeValidity - -@Description Sets or unsets the valid bit of page table entries for a given - address range. - -@Input psMMUContext MMU context to operate on - -@Input sDevVAddr The device virtual base address of - the range we want to modify - -@Input uiSizeBytes The size of the range in bytes - -@Input uiLog2PageSize Log2 of the used page size - -@Input bMakeValid Choose to set or unset the valid bit. - (bMakeValid == IMG_TRUE ) -> SET - (bMakeValid == IMG_FALSE) -> UNSET - -@Input psPMR The PMR backing the allocation. - Needed in case we have sparse memory - where we have to check whether a physical - address actually backs the virtual. - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_ChangeValidity(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSizeBytes, - IMG_UINT32 uiLog2PageSize, - IMG_BOOL bMakeValid, - PMR *psPMR); - -/*************************************************************************/ /*! -@Function MMU_AcquireBaseAddr - -@Description Acquire the device physical address of the base level MMU object - -@Input psMMUContext MMU context to operate on - -@Output psPhysAddr Device physical address of the base level - MMU object - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_AcquireBaseAddr(MMU_CONTEXT *psMMUContext, IMG_DEV_PHYADDR *psPhysAddr); - -/*************************************************************************/ /*! -@Function MMU_AcquireCPUBaseAddr - -@Description Acquire the CPU Virtual Address of the base level MMU object - -@Input psMMUContext MMU context to operate on - -@Output ppvCPUVAddr CPU Virtual Address of the base level - MMU object - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_AcquireCPUBaseAddr(MMU_CONTEXT *psMMUContext, void **ppvCPUVAddr); - -/*************************************************************************/ /*! -@Function MMU_ReleaseBaseAddr - -@Description Release the device physical address of the base level MMU object - -@Input psMMUContext MMU context to operate on - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -void -MMU_ReleaseBaseAddr(MMU_CONTEXT *psMMUContext); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -/***********************************************************************************/ /*! -@Function MMU_SetOSid - -@Description Set the OSid associated with the application (and the MMU Context) - -@Input psMMUContext MMU context to store the OSid on - -@Input ui32OSid the OSid in question - -@Input ui32OSidReg The value that the firmware will assign to the - registers. - -@Input bOSidAxiProt Toggles whether the AXI prot bit will be set or - not. -@Return None -*/ -/***********************************************************************************/ - -void MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, - IMG_UINT32 ui32OSidReg, IMG_BOOL bOSidAxiProt); - -/***********************************************************************************/ /*! -@Function MMU_GetOSid - -@Description Retrieve the OSid associated with the MMU context. - -@Input psMMUContext MMU context in which the OSid is stored - -@Output pui32OSid The OSid in question - -@Output pui32OSidReg The OSid that the firmware will assign to the - registers. - -@Output pbOSidAxiProt Toggles whether the AXI prot bit will be set or - not. -@Return None -*/ -/***********************************************************************************/ - -void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 * pui32OSid, - IMG_UINT32 * pui32OSidReg, IMG_BOOL *pbOSidAxiProt); -#endif - -/*************************************************************************/ /*! -@Function MMU_AppendCacheFlags - -@Description Set the cache flags to the bitwise or of themselves and the - specified input flags, i.e. ui32CacheFlags |= ui32NewCacheFlags, - atomically. - -@Input psMMUContext MMU context - -@Input ui32NewCacheFlags Cache flags to append. - -@Return None -*/ -/*****************************************************************************/ -void MMU_AppendCacheFlags(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32NewCacheFlags); - -/*************************************************************************/ /*! -@Function MMU_ExchangeCacheFlags - -@Description Exchange MMU context flags with specified value, atomically. - -@Input psMMUContext MMU context - -@Input ui32CacheFlags Cache flags to set. - -@Return Previous MMU context cache flags. -*/ -/*****************************************************************************/ -IMG_UINT32 MMU_ExchangeCacheFlags(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32NewCacheFlags); - -/*************************************************************************/ /*! -@Function MMU_CheckFaultAddress - -@Description Check the specified MMU context to see if the provided address - should be valid - -@Input psMMUContext MMU context to store the data on - -@Input psDevVAddr Address to check - -@Output psOutFaultData To store fault details after checking - -@Return None -*/ -/*****************************************************************************/ -void MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR *psDevVAddr, - MMU_FAULT_DATA *psOutFaultData); - -/*************************************************************************/ /*! -@Function MMU_IsVDevAddrValid -@Description Checks if given address is valid. -@Input psMMUContext MMU context to store the data on -@Input uiLog2PageSize page size -@Input sDevVAddr Address to check -@Return IMG_TRUE of address is valid -*/ /**************************************************************************/ -IMG_BOOL MMU_IsVDevAddrValid(MMU_CONTEXT *psMMUContext, - IMG_UINT32 uiLog2PageSize, - IMG_DEV_VIRTADDR sDevVAddr); - -#if defined(PDUMP) - -/*************************************************************************/ /*! -@Function MMU_ContextDerivePCPDumpSymAddr - -@Description Derives a PDump Symbolic address for the top level MMU object - -@Input psMMUContext MMU context to operate on - -@Input pszPDumpSymbolicNameBuffer Buffer to write the PDump symbolic - address to - -@Input uiPDumpSymbolicNameBufferSize Size of the buffer - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_ContextDerivePCPDumpSymAddr(MMU_CONTEXT *psMMUContext, - IMG_CHAR *pszPDumpSymbolicNameBuffer, - size_t uiPDumpSymbolicNameBufferSize); - -/*************************************************************************/ /*! -@Function MMU_PDumpWritePageCatBase - -@Description PDump write of the top level MMU object to a device register - -@Input psMMUContext MMU context to operate on - -@Input pszSpaceName PDump name of the mem/reg space - -@Input uiOffset Offset to write the address to - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext, - const IMG_CHAR *pszSpaceName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32WordSize, - IMG_UINT32 ui32AlignShift, - IMG_UINT32 ui32Shift, - PDUMP_FLAGS_T uiPdumpFlags); - -/*************************************************************************/ /*! -@Function MMU_AcquirePDumpMMUContext - -@Description Acquire a reference to the PDump MMU context for this MMU - context - -@Input psMMUContext MMU context to operate on - -@Output pui32PDumpMMUContextID PDump MMU context ID - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_AcquirePDumpMMUContext(MMU_CONTEXT *psMMUContext, - IMG_UINT32 *pui32PDumpMMUContextID, - IMG_UINT32 ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function MMU_ReleasePDumpMMUContext - -@Description Release a reference to the PDump MMU context for this MMU context - -@Input psMMUContext MMU context to operate on - -@Return PVRSRV_OK if successful -*/ -/*****************************************************************************/ -PVRSRV_ERROR -MMU_ReleasePDumpMMUContext(MMU_CONTEXT *psMMUContext, - IMG_UINT32 ui32PDumpFlags); -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(MMU_PDumpWritePageCatBase) -#endif -static INLINE void -MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext, - const IMG_CHAR *pszSpaceName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32WordSize, - IMG_UINT32 ui32AlignShift, - IMG_UINT32 ui32Shift, - PDUMP_FLAGS_T uiPdumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psMMUContext); - PVR_UNREFERENCED_PARAMETER(pszSpaceName); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(ui32WordSize); - PVR_UNREFERENCED_PARAMETER(ui32AlignShift); - PVR_UNREFERENCED_PARAMETER(ui32Shift); - PVR_UNREFERENCED_PARAMETER(uiPdumpFlags); -} -#endif /* PDUMP */ - -void RGXMapBRN71422TargetPhysicalAddress(MMU_CONTEXT *psMMUContext); - -#endif /* #ifdef MMU_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/module_common.c b/drivers/gpu/drm/img-rogue/1.17/module_common.c deleted file mode 100644 index 11bc07ed4707e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/module_common.c +++ /dev/null @@ -1,730 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common Linux module setup -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -#if defined(CONFIG_DEBUG_FS) -#include "pvr_debugfs.h" -#endif /* defined(CONFIG_DEBUG_FS) */ -#if defined(CONFIG_PROC_FS) -#include "pvr_procfs.h" -#endif /* defined(CONFIG_PROC_FS) */ -#include "di_server.h" -#include "private_data.h" -#include "linkage.h" -#include "power.h" -#include "env_connection.h" -#include "process_stats.h" -#include "module_common.h" -#include "pvrsrv.h" -#include "srvcore.h" -#if defined(SUPPORT_RGX) -#include "rgxdevice.h" -#endif -#include "pvrsrv_error.h" -#include "pvr_drv.h" -#include "pvr_bridge_k.h" - -#include "pvr_fence.h" - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) -#include "pvr_sync.h" -#if !defined(USE_PVRSYNC_DEVNODE) -#include "pvr_sync_ioctl_drm.h" -#endif -#endif - -#include "ospvr_gputrace.h" - -#include "km_apphint.h" -#include "srvinit.h" - -#include "pvr_ion_stats.h" - -#if defined(SUPPORT_DISPLAY_CLASS) -/* Display class interface */ -#include "kerneldisplay.h" -EXPORT_SYMBOL(DCRegisterDevice); -EXPORT_SYMBOL(DCUnregisterDevice); -EXPORT_SYMBOL(DCDisplayConfigurationRetired); -EXPORT_SYMBOL(DCDisplayHasPendingCommand); -EXPORT_SYMBOL(DCImportBufferAcquire); -EXPORT_SYMBOL(DCImportBufferRelease); - -/* Physmem interface (required by LMA DC drivers) */ -#include "physheap.h" -EXPORT_SYMBOL(PhysHeapAcquireByUsage); -EXPORT_SYMBOL(PhysHeapRelease); -EXPORT_SYMBOL(PhysHeapGetType); -EXPORT_SYMBOL(PhysHeapGetCpuPAddr); -EXPORT_SYMBOL(PhysHeapGetSize); -EXPORT_SYMBOL(PhysHeapCpuPAddrToDevPAddr); - -EXPORT_SYMBOL(PVRSRVGetDriverStatus); -EXPORT_SYMBOL(PVRSRVSystemInstallDeviceLISR); -EXPORT_SYMBOL(PVRSRVSystemUninstallDeviceLISR); - -#include "pvr_notifier.h" -EXPORT_SYMBOL(PVRSRVCheckStatus); - -#include "pvr_debug.h" -EXPORT_SYMBOL(PVRSRVGetErrorString); -EXPORT_SYMBOL(PVRSRVGetDeviceInstance); -#endif /* defined(SUPPORT_DISPLAY_CLASS) */ - -#if defined(SUPPORT_RGX) -#include "rgxapi_km.h" -#if defined(SUPPORT_SHARED_SLC) -EXPORT_SYMBOL(RGXInitSLC); -#endif -#if !defined(CHROMIUMOS_KERNEL) || !defined(MODULE) -EXPORT_SYMBOL(RGXHWPerfConnect); -EXPORT_SYMBOL(RGXHWPerfDisconnect); -EXPORT_SYMBOL(RGXHWPerfControl); -#if defined(RGX_FEATURE_HWPERF_VOLCANIC) -EXPORT_SYMBOL(RGXHWPerfConfigureCounters); -#else -EXPORT_SYMBOL(RGXHWPerfConfigMuxCounters); -EXPORT_SYMBOL(RGXHWPerfConfigureAndEnableCustomCounters); -#endif -EXPORT_SYMBOL(RGXHWPerfDisableCounters); -EXPORT_SYMBOL(RGXHWPerfAcquireEvents); -EXPORT_SYMBOL(RGXHWPerfReleaseEvents); -EXPORT_SYMBOL(RGXHWPerfConvertCRTimeStamp); -#endif -#if defined(SUPPORT_KERNEL_HWPERF_TEST) -EXPORT_SYMBOL(OSAddTimer); -EXPORT_SYMBOL(OSEnableTimer); -EXPORT_SYMBOL(OSDisableTimer); -EXPORT_SYMBOL(OSRemoveTimer); -#endif -#endif - -static int PVRSRVDeviceSyncOpen(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - struct drm_file *psDRMFile); - -CONNECTION_DATA *LinuxServicesConnectionFromFile(struct file *pFile) -{ - if (pFile) - { - struct drm_file *psDRMFile; - PVRSRV_CONNECTION_PRIV *psConnectionPriv; - - psDRMFile = pFile->private_data; - PVR_LOG_RETURN_IF_FALSE(psDRMFile != NULL, "psDRMFile is NULL", NULL); - - psConnectionPriv = (PVRSRV_CONNECTION_PRIV*)psDRMFile->driver_priv; - PVR_LOG_RETURN_IF_FALSE(psConnectionPriv != NULL, "psConnectionPriv is NULL", NULL); - - return (CONNECTION_DATA*)psConnectionPriv->pvConnectionData; - } - - return NULL; -} - -CONNECTION_DATA *LinuxSyncConnectionFromFile(struct file *pFile) -{ - if (pFile) - { - struct drm_file *psDRMFile = pFile->private_data; - PVRSRV_CONNECTION_PRIV *psConnectionPriv = (PVRSRV_CONNECTION_PRIV*)psDRMFile->driver_priv; - -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - return (CONNECTION_DATA*)psConnectionPriv->pvConnectionData; -#else - return (CONNECTION_DATA*)psConnectionPriv->pvSyncConnectionData; -#endif - } - - return NULL; -} - -/**************************************************************************/ /*! -@Function PVRSRVDriverInit -@Description Common one time driver initialisation -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -int PVRSRVDriverInit(void) -{ - PVRSRV_ERROR error; - int os_err; - - error = PVROSFuncInit(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } - - error = PVRSRVCommonDriverInit(); - if (error != PVRSRV_OK) - { - return -ENODEV; - } - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - error = pvr_sync_register_functions(); - if (error != PVRSRV_OK) - { - return -EPERM; - } - - os_err = pvr_sync_init(); - if (os_err != 0) - { - return os_err; - } -#endif - - os_err = pvr_apphint_init(); - if (os_err != 0) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed AppHint setup(%d)", __func__, - os_err)); - } - -#if defined(SUPPORT_RGX) - error = PVRGpuTraceSupportInit(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } -#endif - -#if defined(ANDROID) -#if defined(CONFIG_PROC_FS) - error = PVRProcFsRegister(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } -#elif defined(CONFIG_DEBUG_FS) - error = PVRDebugFsRegister(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } -#endif /* defined(CONFIG_PROC_FS) || defined(CONFIG_DEBUG_FS) */ -#else -#if defined(CONFIG_DEBUG_FS) - error = PVRDebugFsRegister(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } -#elif defined(CONFIG_PROC_FS) - error = PVRProcFsRegister(); - if (error != PVRSRV_OK) - { - return -ENOMEM; - } -#endif /* defined(CONFIG_DEBUG_FS) || defined(CONFIG_PROC_FS) */ -#endif /* defined(ANDROID) */ - - error = PVRSRVIonStatsInitialise(); - if (error != PVRSRV_OK) - { - return -ENODEV; - } - -#if defined(SUPPORT_RGX) - /* calling here because we need to handle input from the file even - * before the devices are initialised - * note: we're not passing a device node because apphint callbacks don't - * need it */ - PVRGpuTraceInitAppHintCallbacks(NULL); -#endif - - return 0; -} - -/**************************************************************************/ /*! -@Function PVRSRVDriverDeinit -@Description Common one time driver de-initialisation -@Return void -*/ /***************************************************************************/ -void PVRSRVDriverDeinit(void) -{ - pvr_apphint_deinit(); - - PVRSRVIonStatsDestroy(); - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - pvr_sync_deinit(); -#endif - - PVRSRVCommonDriverDeInit(); - -#if defined(SUPPORT_RGX) - PVRGpuTraceSupportDeInit(); -#endif - - PVROSFuncDeInit(); -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceInit -@Description Common device related initialisation. -@Input psDeviceNode The device node for which initialisation should be - performed -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -int PVRSRVDeviceInit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - { - PVRSRV_ERROR eError = pvr_sync_device_init(psDeviceNode->psDevConfig->pvOSDevice); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: unable to create sync (%d)", - __func__, eError)); - return -EBUSY; - } - } -#endif - -#if defined(SUPPORT_RGX) - { - int error = PVRGpuTraceInitDevice(psDeviceNode); - if (error != 0) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: failed to initialise PVR GPU Tracing on device%d (%d)", - __func__, psDeviceNode->sDevId.i32OsDeviceID, error)); - } - } -#endif - - return 0; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceDeinit -@Description Common device related de-initialisation. -@Input psDeviceNode The device node for which de-initialisation should - be performed -@Return void -*/ /***************************************************************************/ -void PVRSRVDeviceDeinit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_RGX) - PVRGpuTraceDeInitDevice(psDeviceNode); -#endif - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - pvr_sync_device_deinit(psDeviceNode->psDevConfig->pvOSDevice); -#endif - -#if defined(SUPPORT_DMA_TRANSFER) - PVRSRVDeInitialiseDMA(psDeviceNode); -#endif - - pvr_fence_cleanup(); -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceShutdown -@Description Common device shutdown. -@Input psDeviceNode The device node representing the device that should - be shutdown -@Return void -*/ /***************************************************************************/ - -void PVRSRVDeviceShutdown(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - /* - * Disable the bridge to stop processes trying to use the driver - * after it has been shut down. - */ - eError = LinuxBridgeBlockClientsAccess(IMG_TRUE); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to suspend driver (%d)", - __func__, eError)); - return; - } - - (void) PVRSRVSetDeviceSystemPowerState(psDeviceNode, - PVRSRV_SYS_POWER_STATE_OFF, - PVRSRV_POWER_FLAGS_NONE); -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceSuspend -@Description Common device suspend. -@Input psDeviceNode The device node representing the device that should - be suspended -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -int PVRSRVDeviceSuspend(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* - * LinuxBridgeBlockClientsAccess prevents processes from using the driver - * while it's suspended (this is needed for Android). Acquire the bridge - * lock first to ensure the driver isn't currently in use. - */ - LinuxBridgeBlockClientsAccess(IMG_FALSE); - -#if defined(SUPPORT_AUTOVZ) - /* To allow the driver to power down the GPU under AutoVz, the firmware must - * declared as offline, otherwise all power requests will be ignored. */ - psDeviceNode->bAutoVzFwIsUp = IMG_FALSE; -#endif - - if (PVRSRVSetDeviceSystemPowerState(psDeviceNode, - PVRSRV_SYS_POWER_STATE_OFF, - PVRSRV_POWER_FLAGS_SUSPEND) != PVRSRV_OK) - { - LinuxBridgeUnblockClientsAccess(); - return -EINVAL; - } - - return 0; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceResume -@Description Common device resume. -@Input psDeviceNode The device node representing the device that should - be resumed -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -int PVRSRVDeviceResume(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (PVRSRVSetDeviceSystemPowerState(psDeviceNode, - PVRSRV_SYS_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_SUSPEND) != PVRSRV_OK) - { - return -EINVAL; - } - - LinuxBridgeUnblockClientsAccess(); - - /* - * Reprocess the device queues in case commands were blocked during - * suspend. - */ - if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_ACTIVE) - { - PVRSRVCheckStatus(NULL); - } - - return 0; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceServicesOpen -@Description Services device open. -@Input psDeviceNode The device node representing the device being - opened by a user mode process -@Input psDRMFile The DRM file data that backs the file handle - returned to the user mode process -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -int PVRSRVDeviceServicesOpen(PVRSRV_DEVICE_NODE *psDeviceNode, - struct drm_file *psDRMFile) -{ - static DEFINE_MUTEX(sDeviceInitMutex); - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - ENV_CONNECTION_PRIVATE_DATA sPrivData; - PVRSRV_CONNECTION_PRIV *psConnectionPriv; - PVRSRV_ERROR eError; - int iErr = 0; - - if (!psPVRSRVData) - { - PVR_DPF((PVR_DBG_ERROR, "%s: No device data", __func__)); - iErr = -ENODEV; - goto out; - } - - mutex_lock(&sDeviceInitMutex); - /* - * If the first attempt already set the state to bad, - * there is no point in going the second time, so get out - */ - if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_BAD) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Driver already in bad state. Device open failed.", - __func__)); - iErr = -ENODEV; - mutex_unlock(&sDeviceInitMutex); - goto out; - } - - if (psDRMFile->driver_priv == NULL) - { - /* Allocate psConnectionPriv (stores private data and release pfn under driver_priv) */ - psConnectionPriv = kzalloc(sizeof(*psConnectionPriv), GFP_KERNEL); - if (!psConnectionPriv) - { - PVR_DPF((PVR_DBG_ERROR, "%s: No memory to allocate driver_priv data", __func__)); - iErr = -ENOMEM; - mutex_unlock(&sDeviceInitMutex); - goto fail_alloc_connection_priv; - } - } - else - { - psConnectionPriv = (PVRSRV_CONNECTION_PRIV*)psDRMFile->driver_priv; - } - - if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT) - { - eError = PVRSRVCommonDeviceInitialise(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to initialise device (%s)", - __func__, PVRSRVGetErrorString(eError))); - iErr = -ENODEV; - mutex_unlock(&sDeviceInitMutex); - goto fail_device_init; - } - -#if defined(SUPPORT_RGX) - PVRGpuTraceInitIfEnabled(psDeviceNode); -#endif - } - mutex_unlock(&sDeviceInitMutex); - - sPrivData.psDevNode = psDeviceNode; - - /* - * Here we pass the file pointer which will passed through to our - * OSConnectionPrivateDataInit function where we can save it so - * we can back reference the file structure from its connection - */ - eError = PVRSRVCommonConnectionConnect(&psConnectionPriv->pvConnectionData, - (void *)&sPrivData); - if (eError != PVRSRV_OK) - { - iErr = -ENOMEM; - goto fail_connect; - } - -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - psConnectionPriv->pfDeviceRelease = PVRSRVCommonConnectionDisconnect; -#endif - psDRMFile->driver_priv = (void*)psConnectionPriv; - goto out; - -fail_connect: -fail_device_init: - kfree(psConnectionPriv); -fail_alloc_connection_priv: -out: - return iErr; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceSyncOpen -@Description Sync device open. -@Input psDeviceNode The device node representing the device being - opened by a user mode process -@Input psDRMFile The DRM file data that backs the file handle - returned to the user mode process -@Return int 0 on success and a Linux error code otherwise -*/ /***************************************************************************/ -static int PVRSRVDeviceSyncOpen(PVRSRV_DEVICE_NODE *psDeviceNode, - struct drm_file *psDRMFile) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - CONNECTION_DATA *psConnection = NULL; - ENV_CONNECTION_PRIVATE_DATA sPrivData; - PVRSRV_CONNECTION_PRIV *psConnectionPriv; - PVRSRV_ERROR eError; - int iErr = 0; - - if (!psPVRSRVData) - { - PVR_DPF((PVR_DBG_ERROR, "%s: No device data", __func__)); - iErr = -ENODEV; - goto out; - } - - if (psDRMFile->driver_priv == NULL) - { - /* Allocate psConnectionPriv (stores private data and release pfn under driver_priv) */ - psConnectionPriv = kzalloc(sizeof(*psConnectionPriv), GFP_KERNEL); - if (!psConnectionPriv) - { - PVR_DPF((PVR_DBG_ERROR, "%s: No memory to allocate driver_priv data", __func__)); - iErr = -ENOMEM; - goto out; - } - } - else - { - psConnectionPriv = (PVRSRV_CONNECTION_PRIV*)psDRMFile->driver_priv; - } - - /* Allocate connection data area, no stats since process not registered yet */ - psConnection = kzalloc(sizeof(*psConnection), GFP_KERNEL); - if (!psConnection) - { - PVR_DPF((PVR_DBG_ERROR, "%s: No memory to allocate connection data", __func__)); - iErr = -ENOMEM; - goto fail_alloc_connection; - } -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - psConnectionPriv->pvConnectionData = (void*)psConnection; -#else - psConnectionPriv->pvSyncConnectionData = (void*)psConnection; -#endif - - sPrivData.psDevNode = psDeviceNode; - - /* Call environment specific connection data init function */ - eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, &sPrivData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OSConnectionPrivateDataInit() failed (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto fail_private_data_init; - } - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE) -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - iErr = pvr_sync_open(psConnectionPriv->pvConnectionData, psDRMFile); -#else - iErr = pvr_sync_open(psConnectionPriv->pvSyncConnectionData, psDRMFile); -#endif - if (iErr) - { - PVR_DPF((PVR_DBG_ERROR, "%s: pvr_sync_open() failed(%d)", - __func__, iErr)); - goto fail_pvr_sync_open; - } -#endif - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE) -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - psConnectionPriv->pfDeviceRelease = pvr_sync_close; -#endif -#endif - psDRMFile->driver_priv = psConnectionPriv; - goto out; - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE) -fail_pvr_sync_open: - OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData); -#endif -fail_private_data_init: - kfree(psConnection); -fail_alloc_connection: - kfree(psConnectionPriv); -out: - return iErr; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceRelease -@Description Common device release. -@Input psDeviceNode The device node for the device that the given file - represents -@Input psDRMFile The DRM file data that's being released -@Return void -*/ /***************************************************************************/ -void PVRSRVDeviceRelease(PVRSRV_DEVICE_NODE *psDeviceNode, - struct drm_file *psDRMFile) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - - if (psDRMFile->driver_priv) - { - PVRSRV_CONNECTION_PRIV *psConnectionPriv = (PVRSRV_CONNECTION_PRIV*)psDRMFile->driver_priv; - - if (psConnectionPriv->pvConnectionData) - { -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - if (psConnectionPriv->pfDeviceRelease) - { - psConnectionPriv->pfDeviceRelease(psConnectionPriv->pvConnectionData); - } -#else - if (psConnectionPriv->pvConnectionData) - PVRSRVCommonConnectionDisconnect(psConnectionPriv->pvConnectionData); - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE) - if (psConnectionPriv->pvSyncConnectionData) - pvr_sync_close(psConnectionPriv->pvSyncConnectionData); -#endif -#endif - } - - kfree(psDRMFile->driver_priv); - psDRMFile->driver_priv = NULL; - } -} - -int -drm_pvr_srvkm_init(struct drm_device *dev, void *arg, struct drm_file *psDRMFile) -{ - struct drm_pvr_srvkm_init_data *data = arg; - struct pvr_drm_private *priv = dev->dev_private; - int iErr = 0; - - switch (data->init_module) - { - case PVR_SRVKM_SYNC_INIT: - { - iErr = PVRSRVDeviceSyncOpen(priv->dev_node, psDRMFile); - break; - } - case PVR_SRVKM_SERVICES_INIT: - { - iErr = PVRSRVDeviceServicesOpen(priv->dev_node, psDRMFile); - break; - } - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid init_module (%d)", - __func__, data->init_module)); - iErr = -EINVAL; - } - } - - return iErr; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/module_common.h b/drivers/gpu/drm/img-rogue/1.17/module_common.h deleted file mode 100644 index 7317a0a79eaa9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/module_common.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ /*! -@File module_common.h -@Title Common linux module setup header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 MODULE_COMMON_H -#define MODULE_COMMON_H - -#include "pvr_drm.h" - -/* DRVNAME is the name we use to register our driver. */ -#define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME - -struct _PVRSRV_DEVICE_NODE_; -struct drm_file; -struct drm_device; - -/* psDRMFile->driver_priv will point to a PVRSV_CONNECTION_PRIV - * struct, which will contain a ptr to the CONNECTION_DATA and - * a pfn to the release function (which will differ depending - * on whether the connection is to Sync or Services). - */ -typedef void (*PFN_PVRSRV_DEV_RELEASE)(void *pvData); -typedef struct -{ - /* pvConnectionData is used to hold Services connection data - * for all PVRSRV_DEVICE_INIT_MODE options. - */ - void *pvConnectionData; - - /* pfDeviceRelease is used to indicate the release function - * to be called when PVRSRV_DEVICE_INIT_MODE is PVRSRV_LINUX_DEV_INIT_ON_CONNECT, - * as we can then have one connections made (either for Services or Sync) per - * psDRMFile, and need to know which type of connection is being released - * (as the ioctl release call is common for both). - */ - PFN_PVRSRV_DEV_RELEASE pfDeviceRelease; - - /* pvSyncConnectionData is used to hold Sync connection data - * when PVRSRV_DEVICE_INIT_MODE is not PVRSRV_LINUX_DEV_INIT_ON_CONNECT, - * as we can then have two connections made (for Services and Sync) to - * the same psDRMFile. - */ - void *pvSyncConnectionData; -} PVRSRV_CONNECTION_PRIV; - -int PVRSRVDriverInit(void); -void PVRSRVDriverDeinit(void); - -int PVRSRVDeviceInit(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -void PVRSRVDeviceDeinit(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); - -void PVRSRVDeviceShutdown(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -int PVRSRVDeviceSuspend(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -int PVRSRVDeviceResume(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); - -int PVRSRVDeviceServicesOpen(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - struct drm_file *psDRMFile); -void PVRSRVDeviceRelease(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, - struct drm_file *psDRMFile); -int drm_pvr_srvkm_init(struct drm_device *dev, - void *arg, struct drm_file *psDRMFile); - -#endif /* MODULE_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/mt8173/Makefile b/drivers/gpu/drm/img-rogue/1.17/mt8173/Makefile deleted file mode 100644 index d13e9c180c313..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mt8173/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -ccflags-y += -I$(img_basedir)/mt8173 - -pvrsrvkm_1_17-y += \ - mt8173/mt8173_mfgsys.o \ - mt8173/mt8173_sysconfig.o diff --git a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.c b/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.c deleted file mode 100644 index dc9237f3fba9a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.c +++ /dev/null @@ -1,359 +0,0 @@ -/* -* Copyright (c) 2014 MediaTek Inc. -* Author: Chiawen Lee -* -* 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. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mt8173_mfgsys.h" - -static const char * const top_mfg_clk_name[] = { - "mfg_mem_in_sel", - "mfg_axi_in_sel", - "top_axi", - "top_mem", -}; - -#define MAX_TOP_MFG_CLK ARRAY_SIZE(top_mfg_clk_name) - -#define REG_MFG_AXI BIT(0) -#define REG_MFG_MEM BIT(1) -#define REG_MFG_G3D BIT(2) -#define REG_MFG_26M BIT(3) -#define REG_MFG_ALL (REG_MFG_AXI | REG_MFG_MEM | REG_MFG_G3D | REG_MFG_26M) - -#define REG_MFG_CG_STA 0x00 -#define REG_MFG_CG_SET 0x04 -#define REG_MFG_CG_CLR 0x08 - -static void mtk_mfg_clr_clock_gating(void __iomem *reg) -{ - writel(REG_MFG_ALL, reg + REG_MFG_CG_CLR); -} - -static int mtk_mfg_prepare_clock(struct mtk_mfg *mfg) -{ - int i; - int ret; - - for (i = 0; i < MAX_TOP_MFG_CLK; i++) { - ret = clk_prepare(mfg->top_clk[i]); - if (ret) - goto unwind; - } - ret = clk_prepare(mfg->top_mfg); - if (ret) - goto unwind; - - return 0; -unwind: - while (i--) - clk_unprepare(mfg->top_clk[i]); - - return ret; -} - -static void mtk_mfg_unprepare_clock(struct mtk_mfg *mfg) -{ - int i; - - clk_unprepare(mfg->top_mfg); - for (i = MAX_TOP_MFG_CLK - 1; i >= 0; i--) - clk_unprepare(mfg->top_clk[i]); -} - -static int mtk_mfg_enable_clock(struct mtk_mfg *mfg) -{ - int i; - int ret; - - for (i = 0; i < MAX_TOP_MFG_CLK; i++) { - ret = clk_enable(mfg->top_clk[i]); - if (ret) - { - dev_warn(mfg->dev, "Enabling %s failed with error %d\n", - __clk_get_name(mfg->top_clk[i]), ret); - goto unwind; - } - } - ret = clk_enable(mfg->top_mfg); - if (ret) - { - dev_warn(mfg->dev, "Enabling %s failed with error %d\n", - __clk_get_name(mfg->top_mfg), ret); - goto unwind; - } - mtk_mfg_clr_clock_gating(mfg->reg_base); - - return 0; -unwind: - while (i--) - clk_disable(mfg->top_clk[i]); - - return ret; -} - -static void mtk_mfg_disable_clock(struct mtk_mfg *mfg) -{ - int i; - - clk_disable(mfg->top_mfg); - for (i = MAX_TOP_MFG_CLK - 1; i >= 0; i--) - clk_disable(mfg->top_clk[i]); -} - -static void mtk_mfg_enable_hw_apm(struct mtk_mfg *mfg) -{ - writel(0x003c3d4d, mfg->reg_base + 0x24); - writel(0x4d45440b, mfg->reg_base + 0x28); - writel(0x7a710184, mfg->reg_base + 0xe0); - writel(0x835f6856, mfg->reg_base + 0xe4); - writel(0x002b0234, mfg->reg_base + 0xe8); - writel(0x80000000, mfg->reg_base + 0xec); - writel(0x08000000, mfg->reg_base + 0xa0); -} - -int mtk_mfg_enable(struct mtk_mfg *mfg) -{ - int ret; - - ret = regulator_enable(mfg->vgpu); - if (ret) - { - dev_err(mfg->dev, "Enable vgpu regulator failed with error %d\n", ret); - return ret; - } - - ret = pm_runtime_get_sync(mfg->dev); - if (ret) - { - dev_err(mfg->dev, "pm_runtime_get_sync failed with error %d\n", ret); - goto err_regulator_disable; - } - - ret = mtk_mfg_enable_clock(mfg); - if (ret) - { - dev_err(mfg->dev, "mtk_mfg_enable_clock failed with error %d\n", ret); - goto err_pm_runtime_put; - } - - mtk_mfg_enable_hw_apm(mfg); - - mtk_mfg_debug(mfg->dev, "Enabled\n"); - - return 0; - -err_pm_runtime_put: - pm_runtime_put_sync(mfg->dev); -err_regulator_disable: - regulator_disable(mfg->vgpu); - return ret; -} - -static void mtk_mfg_disable_hw_apm(struct mtk_mfg *mfg) -{ - writel(0x00, mfg->reg_base + 0xec); -} - -void mtk_mfg_disable(struct mtk_mfg *mfg) -{ - mtk_mfg_disable_hw_apm(mfg); - - mtk_mfg_disable_clock(mfg); - pm_runtime_put_sync(mfg->dev); - regulator_disable(mfg->vgpu); - - mtk_mfg_debug(mfg->dev, "Disabled\n"); -} - -int mtk_mfg_freq_set(struct mtk_mfg *mfg, unsigned long freq) -{ - int ret; - - ret = clk_prepare_enable(mfg->top_mfg); - if (ret) { - dev_err(mfg->dev, "enable and prepare top_mfg failed, %d\n", ret); - return ret; - } - - ret = clk_set_parent(mfg->top_mfg, mfg->clk26m); - if (ret) { - dev_err(mfg->dev, "Set clk parent to clk26m failed, %d\n", ret); - goto unprepare_top_mfg; - } - - ret = clk_set_rate(mfg->mmpll, freq); - if (ret) - dev_err(mfg->dev, "Set freq to %lu Hz failed, %d\n", freq, ret); - - ret = clk_set_parent(mfg->top_mfg, mfg->top_mmpll); - if (ret) - dev_err(mfg->dev, "Set clk parent to top_mmpll failed, %d\n", ret); - -unprepare_top_mfg: - clk_disable_unprepare(mfg->top_mfg); - - if (!ret) - dev_dbg(mfg->dev, "Freq set to %lu Hz\n", freq); - - return ret; -} - -int mtk_mfg_volt_set(struct mtk_mfg *mfg, int volt) -{ - int ret; - - ret = regulator_set_voltage(mfg->vgpu, volt, volt); - if (ret != 0) { - dev_err(mfg->dev, "Set voltage to %u uV failed, %d\n", - volt, ret); - return ret; - } - - dev_dbg(mfg->dev, "Voltage set to %d uV\n", volt); - - return 0; -} - -static int mtk_mfg_bind_device_resource(struct mtk_mfg *mfg) -{ - struct device *dev = mfg->dev; - struct platform_device *pdev = to_platform_device(dev); - int i; - struct resource *res; - - mfg->top_clk = devm_kcalloc(dev, MAX_TOP_MFG_CLK, - sizeof(*mfg->top_clk), GFP_KERNEL); - if (!mfg->top_clk) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - mfg->rgx_start = res->start; - mfg->rgx_size = resource_size(res); - - mfg->rgx_irq = platform_get_irq_byname(pdev, "RGX"); - if (mfg->rgx_irq < 0) - return mfg->rgx_irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - mfg->reg_base = devm_ioremap_resource(dev, res); - if (IS_ERR(mfg->reg_base)) - return PTR_ERR(mfg->reg_base); - - mfg->mmpll = devm_clk_get(dev, "mmpll_clk"); - if (IS_ERR(mfg->mmpll)) { - dev_err(dev, "devm_clk_get mmpll_clk failed !!!\n"); - return PTR_ERR(mfg->mmpll); - } - - for (i = 0; i < MAX_TOP_MFG_CLK; i++) { - mfg->top_clk[i] = devm_clk_get(dev, top_mfg_clk_name[i]); - if (IS_ERR(mfg->top_clk[i])) { - dev_err(dev, "devm_clk_get %s failed !!!\n", - top_mfg_clk_name[i]); - return PTR_ERR(mfg->top_clk[i]); - } - } - - mfg->top_mfg = devm_clk_get(dev, "top_mfg"); - if (IS_ERR(mfg->top_mfg)) { - dev_err(dev, "devm_clk_get top_mfg failed !!!\n"); - return PTR_ERR(mfg->top_mfg); - } - - mfg->top_mmpll = devm_clk_get(dev, "top_mmpll"); - if (IS_ERR(mfg->top_mmpll)) { - dev_err(dev, "devm_clk_get top_mmpll failed !!!\n"); - return PTR_ERR(mfg->top_mmpll); - } - - mfg->clk26m = devm_clk_get(dev, "clk26m"); - if (IS_ERR(mfg->clk26m)) { - dev_err(dev, "devm_clk_get clk26m failed !!!\n"); - return PTR_ERR(mfg->clk26m); - } - -#if defined(CONFIG_DEVFREQ_THERMAL) - mfg->tz = thermal_zone_get_zone_by_name("cpu-thermal"); - if (IS_ERR(mfg->tz)) { - dev_err(dev, "Failed to get cpu-thermal zone\n"); - return PTR_ERR(mfg->tz); - } -#endif - - mfg->vgpu = devm_regulator_get(dev, "mfgsys-power"); - if (IS_ERR(mfg->vgpu)) - return PTR_ERR(mfg->vgpu); - - pm_runtime_enable(dev); - - return 0; -} - -static void mtk_mfg_unbind_device_resource(struct mtk_mfg *mfg) -{ - struct device *dev = mfg->dev; - - pm_runtime_disable(dev); -} - -struct mtk_mfg *mtk_mfg_create(struct device *dev) -{ - int err; - struct mtk_mfg *mfg; - - mtk_mfg_debug("mtk_mfg_create Begin\n"); - - mfg = devm_kzalloc(dev, sizeof(*mfg), GFP_KERNEL); - if (!mfg) - return ERR_PTR(-ENOMEM); - mfg->dev = dev; - - err = mtk_mfg_bind_device_resource(mfg); - if (err != 0) - return ERR_PTR(err); - - mutex_init(&mfg->set_power_state); - - err = mtk_mfg_prepare_clock(mfg); - if (err) - goto err_unbind_resource; - - mtk_mfg_debug("mtk_mfg_create End\n"); - - return mfg; -err_unbind_resource: - mtk_mfg_unbind_device_resource(mfg); - - return ERR_PTR(err); -} - -void mtk_mfg_destroy(struct mtk_mfg *mfg) -{ - mtk_mfg_unprepare_clock(mfg); - - mtk_mfg_unbind_device_resource(mfg); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.h b/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.h deleted file mode 100644 index f8dcc70507456..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_mfgsys.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Copyright (c) 2014 MediaTek Inc. -* Author: Chiawen Lee -* -* 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. -*/ - -#ifndef MT8173_MFGSYS_H -#define MT8173_MFGSYS_H - -#include -#include - -/* unit ms, timeout interval for DVFS detection */ -#define MTK_DVFS_SWITCH_INTERVAL 300 - -#define ENABLE_MTK_MFG_DEBUG 0 - -#if ENABLE_MTK_MFG_DEBUG -#define mtk_mfg_debug(fmt, args...) pr_info("[MFG]" fmt, ##args) -#else -#define mtk_mfg_debug(fmt, args...) do { } while (0) -#endif - -struct mtk_mfg { - struct device *dev; - - struct clk **top_clk; - void __iomem *reg_base; - - resource_size_t rgx_start; - resource_size_t rgx_size; - int rgx_irq; - - /* mutex protect for set power state */ - struct mutex set_power_state; - - /* for gpu device freq/volt update */ - struct regulator *vgpu; - struct clk *mmpll; - struct clk *top_mfg; - struct clk *top_mmpll; - struct clk *clk26m; - -#if (defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - struct thermal_zone_device *tz; -#endif -}; - -struct mtk_mfg *mtk_mfg_create(struct device *dev); -void mtk_mfg_destroy(struct mtk_mfg *mfg); - -int mtk_mfg_enable(struct mtk_mfg *mfg); -void mtk_mfg_disable(struct mtk_mfg *mfg); - -int mtk_mfg_freq_set(struct mtk_mfg *mfg, unsigned long freq); -int mtk_mfg_volt_set(struct mtk_mfg *mfg, int volt); - -#endif /* MT8173_MFGSYS_H*/ diff --git a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_sysconfig.c b/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_sysconfig.c deleted file mode 100644 index 7bdd07632b60c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mt8173/mt8173_sysconfig.c +++ /dev/null @@ -1,552 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title System Configuration -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description System Configuration functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#include -#include -#if defined(CONFIG_DEVFREQ_THERMAL) -#include -#endif - -#include "physheap.h" -#include "pvrsrv_device.h" -#include "rgxdevice.h" -#include "syscommon.h" -#if defined(SUPPORT_ION) -#include "ion_support.h" -#endif - -#include "mt8173_mfgsys.h" - -#define SYS_RGX_ACTIVE_POWER_LATENCY_MS 10 -#define RGX_HW_CORE_CLOCK_SPEED 395000000 - -/* Setup RGX specific timing data */ -static RGX_TIMING_INFORMATION gsRGXTimingInfo = { - .ui32CoreClockSpeed = RGX_HW_CORE_CLOCK_SPEED, - .bEnableActivePM = IMG_TRUE, - .ui32ActivePMLatencyms = SYS_RGX_ACTIVE_POWER_LATENCY_MS, - .bEnableRDPowIsland = IMG_TRUE, -}; - -static RGX_DATA gsRGXData = { - .psRGXTimingInfo = &gsRGXTimingInfo, -}; - -static PVRSRV_DEVICE_CONFIG gsDevice; - -typedef struct -{ - IMG_UINT32 ui32IRQ; - PFN_LISR pfnLISR; - void *pvLISRData; -} LISR_WRAPPER_DATA; - -static irqreturn_t MTKLISRWrapper(int iIrq, void *pvData) -{ - LISR_WRAPPER_DATA *psWrapperData = pvData; - - if (psWrapperData->pfnLISR(psWrapperData->pvLISRData)) - { - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -/* - * CPU to Device physical address translation - */ -static -void UMAPhysHeapCpuPAddrToDevPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_CPU_PHYADDR *psCpuPAddr) -{ - PVR_UNREFERENCED_PARAMETER(hPrivData); - - /* Optimise common case */ - psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr; - if (ui32NumOfAddr > 1) { - IMG_UINT32 ui32Idx; - for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx) - psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr; - } -} - -/* - * Device to CPU physical address translation - */ -static -void UMAPhysHeapDevPAddrToCpuPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_DEV_PHYADDR *psDevPAddr) -{ - PVR_UNREFERENCED_PARAMETER(hPrivData); - - /* Optimise common case */ - psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr; - if (ui32NumOfAddr > 1) { - IMG_UINT32 ui32Idx; - for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx) - psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr; - } -} - -static PHYS_HEAP_FUNCTIONS gsPhysHeapFuncs = { - .pfnCpuPAddrToDevPAddr = UMAPhysHeapCpuPAddrToDevPAddr, - .pfnDevPAddrToCpuPAddr = UMAPhysHeapDevPAddrToCpuPAddr, -}; - -static PHYS_HEAP_CONFIG gsPhysHeapConfig = { - .pszPDumpMemspaceName = "SYSMEM", - .eType = PHYS_HEAP_TYPE_UMA, - .psMemFuncs = &gsPhysHeapFuncs, - .hPrivData = NULL, - .ui32UsageFlags = PHYS_HEAP_USAGE_GPU_LOCAL, -}; - -static PVRSRV_ERROR MTKSysDevPrePowerState( - IMG_HANDLE hSysData, - PVRSRV_SYS_POWER_STATE eNewPowerState, - PVRSRV_SYS_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - struct mtk_mfg *mfg = hSysData; - - mtk_mfg_debug("MTKSysDevPrePowerState (%d->%d), bPwrFlags = 0x%08x\n", - eCurrentPowerState, eNewPowerState, ePwrFlags); - - mutex_lock(&mfg->set_power_state); - - if ((PVRSRV_SYS_POWER_STATE_OFF == eNewPowerState) && - (PVRSRV_SYS_POWER_STATE_ON == eCurrentPowerState)) - mtk_mfg_disable(mfg); - - mutex_unlock(&mfg->set_power_state); - return PVRSRV_OK; -} - -static PVRSRV_ERROR MTKSysDevPostPowerState( - IMG_HANDLE hSysData, - PVRSRV_SYS_POWER_STATE eNewPowerState, - PVRSRV_SYS_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - struct mtk_mfg *mfg = hSysData; - PVRSRV_ERROR ret; - - mtk_mfg_debug("MTKSysDevPostPowerState (%d->%d)\n", - eCurrentPowerState, eNewPowerState); - - mutex_lock(&mfg->set_power_state); - - if ((PVRSRV_SYS_POWER_STATE_ON == eNewPowerState) && - (PVRSRV_SYS_POWER_STATE_OFF == eCurrentPowerState)) { - if (mtk_mfg_enable(mfg)) { - ret = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE; - goto done; - } - } - - ret = PVRSRV_OK; -done: - mutex_unlock(&mfg->set_power_state); - - return ret; -} - -#ifdef SUPPORT_LINUX_DVFS - -#define FALLBACK_STATIC_TEMPERATURE 65000 - -/* Temperatures on power over-temp-and-voltage curve (C) */ -static const int vt_temperatures[] = { 25, 45, 65, 85, 105 }; - -/* Voltages on power over-temp-and-voltage curve (mV) */ -static const int vt_voltages[] = { 900, 1000, 1130 }; - -#define POWER_TABLE_NUM_TEMP ARRAY_SIZE(vt_temperatures) -#define POWER_TABLE_NUM_VOLT ARRAY_SIZE(vt_voltages) - -static const unsigned int -power_table[POWER_TABLE_NUM_VOLT][POWER_TABLE_NUM_TEMP] = { - /* 25 45 65 85 105 */ - { 14540, 35490, 60420, 120690, 230000 }, /* 900 mV */ - { 21570, 41910, 82380, 159140, 298620 }, /* 1000 mV */ - { 32320, 72950, 111320, 209290, 382700 }, /* 1130 mV */ -}; - -/** Frequency and Power in Khz and mW respectively */ -static const int f_range[] = {253500, 299000, 396500, 455000, 494000, 598000}; -static const IMG_UINT32 max_dynamic_power[] = {612, 722, 957, 1100, 1194, 1445}; - -#if defined(CONFIG_DEVFREQ_THERMAL) -static u32 interpolate(int value, const int *x, const unsigned int *y, int len) -{ - u64 tmp64; - u32 dx; - u32 dy; - int i, ret; - - if (value <= x[0]) - return y[0]; - if (value >= x[len - 1]) - return y[len - 1]; - - for (i = 1; i < len - 1; i++) { - /* If value is identical, no need to interpolate */ - if (value == x[i]) - return y[i]; - if (value < x[i]) - break; - } - - /* Linear interpolation between the two (x,y) points */ - dy = y[i] - y[i - 1]; - dx = x[i] - x[i - 1]; - - tmp64 = value - x[i - 1]; - tmp64 *= dy; - do_div(tmp64, dx); - ret = y[i - 1] + tmp64; - - return ret; -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10, 0) -static unsigned long mtk_mfg_get_static_power(struct devfreq *df, - unsigned long voltage) -#else -static unsigned long mtk_mfg_get_static_power(unsigned long voltage) -#endif -{ - struct mtk_mfg *mfg = gsDevice.hSysData; - struct thermal_zone_device *tz = mfg->tz; - unsigned long power; -#if !defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) - unsigned long temperature = FALLBACK_STATIC_TEMPERATURE; -#else - int temperature = FALLBACK_STATIC_TEMPERATURE; -#endif - int low_idx = 0, high_idx = POWER_TABLE_NUM_VOLT - 1; - int i; - - if (!tz) - return 0; - - if (tz->ops->get_temp(tz, &temperature)) - dev_warn(mfg->dev, "Failed to read temperature\n"); - do_div(temperature, 1000); - - for (i = 0; i < POWER_TABLE_NUM_VOLT; i++) { - if (voltage <= vt_voltages[POWER_TABLE_NUM_VOLT - 1 - i]) - high_idx = POWER_TABLE_NUM_VOLT - 1 - i; - - if (voltage >= vt_voltages[i]) - low_idx = i; - } - - if (low_idx == high_idx) { - power = interpolate(temperature, - vt_temperatures, - &power_table[low_idx][0], - POWER_TABLE_NUM_TEMP); - } else { - unsigned long dvt = - vt_voltages[high_idx] - vt_voltages[low_idx]; - unsigned long power1, power2; - - power1 = interpolate(temperature, - vt_temperatures, - &power_table[high_idx][0], - POWER_TABLE_NUM_TEMP); - - power2 = interpolate(temperature, - vt_temperatures, - &power_table[low_idx][0], - POWER_TABLE_NUM_TEMP); - - power = (power1 - power2) * (voltage - vt_voltages[low_idx]); - do_div(power, dvt); - power += power2; - } - - /* convert to mw */ - do_div(power, 1000); - - mtk_mfg_debug("mtk_mfg_get_static_power: %lu at Temperature %d\n", - power, temperature); - return power; -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) -static unsigned long mtk_mfg_get_dynamic_power(struct devfreq *df, - unsigned long freq, - unsigned long voltage) -#else -static unsigned long mtk_mfg_get_dynamic_power(unsigned long freq, - unsigned long voltage) -#endif -{ - #define NUM_RANGE ARRAY_SIZE(f_range) - /** Frequency and Power in Khz and mW respectively */ - IMG_INT32 i, low_idx = 0, high_idx = NUM_RANGE - 1; - IMG_UINT32 power; - - for (i = 0; i < NUM_RANGE; i++) { - if (freq <= f_range[NUM_RANGE - 1 - i]) - high_idx = NUM_RANGE - 1 - i; - - if (freq >= f_range[i]) - low_idx = i; - } - - if (low_idx == high_idx) { - power = max_dynamic_power[low_idx]; - } else { - IMG_UINT32 f_interval = f_range[high_idx] - f_range[low_idx]; - IMG_UINT32 p_interval = max_dynamic_power[high_idx] - - max_dynamic_power[low_idx]; - - power = p_interval * (freq - f_range[low_idx]); - do_div(power, f_interval); - power += max_dynamic_power[low_idx]; - } - - power = (IMG_UINT32)div_u64((IMG_UINT64)power * voltage * voltage, - 1000000UL); - - return power; - #undef NUM_RANGE -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) -static int mtk_mfg_get_real_power(struct devfreq *df, - u32 *power, - unsigned long freq, - unsigned long voltage) -{ - if (!df || !power) - return -EINVAL; - - *power = mtk_mfg_get_static_power(df, voltage) + - mtk_mfg_get_dynamic_power(df, freq, voltage); - - return 0; -} -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) */ - -static struct devfreq_cooling_power sPowerOps = { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) - .get_static_power = mtk_mfg_get_static_power, - .get_dynamic_power = mtk_mfg_get_dynamic_power, -#else - .get_real_power = mtk_mfg_get_real_power, -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */ -}; -#endif - -static void SetFrequency(IMG_UINT32 freq) -{ - struct mtk_mfg *mfg = gsDevice.hSysData; - - /* freq is in Hz */ - mtk_mfg_freq_set(mfg, freq); -} - -static void SetVoltage(IMG_UINT32 volt) -{ - struct mtk_mfg *mfg = gsDevice.hSysData; - - mtk_mfg_volt_set(mfg, volt); -} -#endif - -PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig) -{ - struct device *dev = pvOSDevice; - struct mtk_mfg *mfg; - - if (gsDevice.pvOSDevice) - { - return PVRSRV_ERROR_INVALID_DEVICE; - } - - mfg = mtk_mfg_create(dev); - if (IS_ERR(mfg)) { - if (PTR_ERR(mfg) == -EPROBE_DEFER) - return PVRSRV_ERROR_PROBE_DEFER; - else - return PVRSRV_ERROR_INIT_FAILURE; - } - - dma_set_mask(dev, DMA_BIT_MASK(33)); - - /* Make sure everything we don't care about is set to 0 */ - memset(&gsDevice, 0, sizeof(gsDevice)); - - /* Setup RGX device */ - gsDevice.pvOSDevice = pvOSDevice; - gsDevice.pszName = "mt8173"; - gsDevice.pszVersion = NULL; - - /* Device's physical heaps */ - gsDevice.pasPhysHeaps = &gsPhysHeapConfig; - gsDevice.ui32PhysHeapCount = 1; - gsDevice.eDefaultHeap = PVRSRV_PHYS_HEAP_GPU_LOCAL; - - gsDevice.ui32IRQ = mfg->rgx_irq; - - gsDevice.sRegsCpuPBase.uiAddr = mfg->rgx_start; - gsDevice.ui32RegsSize = mfg->rgx_size; - -#ifdef SUPPORT_LINUX_DVFS - gsDevice.sDVFS.sDVFSDeviceCfg.bIdleReq = IMG_TRUE; - gsDevice.sDVFS.sDVFSDeviceCfg.pfnSetFrequency = SetFrequency; - gsDevice.sDVFS.sDVFSDeviceCfg.pfnSetVoltage = SetVoltage; - gsDevice.sDVFS.sDVFSDeviceCfg.ui32PollMs = MTK_DVFS_SWITCH_INTERVAL; -#if defined(CONFIG_DEVFREQ_THERMAL) - gsDevice.sDVFS.sDVFSDeviceCfg.psPowerOps = &sPowerOps; -#endif - - gsDevice.sDVFS.sDVFSGovernorCfg.ui32UpThreshold = 90; - gsDevice.sDVFS.sDVFSGovernorCfg.ui32DownDifferential = 10; -#endif - - /* power management on HW system */ - gsDevice.pfnPrePowerState = MTKSysDevPrePowerState; - gsDevice.pfnPostPowerState = MTKSysDevPostPowerState; - - /* clock frequency */ - gsDevice.pfnClockFreqGet = NULL; - - gsDevice.hDevData = &gsRGXData; - gsDevice.hSysData = mfg; - - gsDevice.bHasFBCDCVersion31 = IMG_FALSE; - gsDevice.bDevicePA0IsValid = IMG_FALSE; - - *ppsDevConfig = &gsDevice; - -#if defined(SUPPORT_ION) - IonInit(NULL); -#endif - - return PVRSRV_OK; -} - -void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - struct mtk_mfg *mfg = psDevConfig->hSysData; - -#if defined(SUPPORT_ION) - IonDeinit(); -#endif - - mtk_mfg_destroy(mfg); - - psDevConfig->pvOSDevice = NULL; -} - -PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszName, - PFN_LISR pfnLISR, - void *pvData, - IMG_HANDLE *phLISRData) -{ - LISR_WRAPPER_DATA *psWrapperData; - - PVR_UNREFERENCED_PARAMETER(hSysData); - - psWrapperData = OSAllocMem(sizeof(*psWrapperData)); - if (!psWrapperData) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psWrapperData->ui32IRQ = ui32IRQ; - psWrapperData->pfnLISR = pfnLISR; - psWrapperData->pvLISRData = pvData; - - if (request_irq(ui32IRQ, MTKLISRWrapper, IRQF_TRIGGER_LOW, pszName, - psWrapperData)) - { - OSFreeMem(psWrapperData); - - return PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER; - } - - *phLISRData = (IMG_HANDLE) psWrapperData; - - return PVRSRV_OK; -} - -PVRSRV_ERROR SysUninstallDeviceLISR(IMG_HANDLE hLISRData) -{ - LISR_WRAPPER_DATA *psWrapperData = hLISRData; - - free_irq(psWrapperData->ui32IRQ, psWrapperData); - - OSFreeMem(psWrapperData); - - return PVRSRV_OK; -} - -PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVR_UNREFERENCED_PARAMETER(psDevConfig); - PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf); - PVR_UNREFERENCED_PARAMETER(pvDumpDebugFile); - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/mt8173/sysinfo.h b/drivers/gpu/drm/img-rogue/1.17/mt8173/sysinfo.h deleted file mode 100644 index bf4cc3155ac76..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/mt8173/sysinfo.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title System Description Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides system-specific declarations and macros -@License MIT - -The contents of this file are subject to the MIT license as set out below. - -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. - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(__SYSINFO_H__) -#define __SYSINFO_H__ - -/*!< System specific poll/timeout details */ -#define MAX_HW_TIME_US (1000000) -#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT (1500) -#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT (3600000) -#define WAIT_TRY_COUNT (20000) - -#define SYS_RGX_OF_COMPATIBLE "mediatek,mt8173-gpu" - -#endif /* !defined(__SYSINFO_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/multicore_defs.h b/drivers/gpu/drm/img-rogue/1.17/multicore_defs.h deleted file mode 100644 index 2ca4e064d8863..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/multicore_defs.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title RGX Multicore Information flags -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_MULTICORE_DEFS_H -#define RGX_MULTICORE_DEFS_H - -/* Capability bits returned to client in RGXGetMultiCoreInfo */ -#define RGX_MULTICORE_CAPABILITY_FRAGMENT_EN (0x00000040U) -#define RGX_MULTICORE_CAPABILITY_GEOMETRY_EN (0x00000020U) -#define RGX_MULTICORE_CAPABILITY_COMPUTE_EN (0x00000010U) -#define RGX_MULTICORE_CAPABILITY_PRIMARY_EN (0x00000008U) -#define RGX_MULTICORE_ID_CLRMSK (0xFFFFFFF8U) - -#endif /* RGX_MULTICORE_DEFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/opaque_types.h b/drivers/gpu/drm/img-rogue/1.17/opaque_types.h deleted file mode 100644 index 766bc22ea418c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/opaque_types.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Opaque Types -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines opaque types for various services types -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SERVICES_OPAQUE_TYPES_H -#define SERVICES_OPAQUE_TYPES_H - -#include "img_defs.h" -#include "img_types.h" - -typedef struct _PVRSRV_DEVICE_NODE_ *PPVRSRV_DEVICE_NODE; -typedef const struct _PVRSRV_DEVICE_NODE_ *PCPVRSRV_DEVICE_NODE; - -#endif /* SERVICES_OPAQUE_TYPES_H */ - -/****************************************************************************** - End of file (opaque_types.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/os_cpu_cache.h b/drivers/gpu/drm/img-rogue/1.17/os_cpu_cache.h deleted file mode 100644 index 56f92036ff49a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/os_cpu_cache.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS and CPU d-cache maintenance mechanisms -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines for cache management which are visible internally only -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OS_CPU_CACHE_H -#define OS_CPU_CACHE_H - -#include "info_page_defs.h" - -#define PVRSRV_CACHE_OP_TIMELINE 0x8 /*!< Request SW_SYNC timeline notification when executed */ -#define PVRSRV_CACHE_OP_FORCE_SYNCHRONOUS 0x10 /*!< Force all batch members to be executed synchronously */ - -#define CACHEFLUSH_ISA_X86 0x1 /*!< x86/x64 specific UM range-based cache flush */ -#define CACHEFLUSH_ISA_ARM64 0x2 /*!< Aarch64 specific UM range-based cache flush */ -#define CACHEFLUSH_ISA_GENERIC 0x3 /*!< Other ISA's without UM range-based cache flush */ -#ifndef CACHEFLUSH_ISA_TYPE - #if defined(__i386__) || defined(__x86_64__) - #define CACHEFLUSH_ISA_TYPE CACHEFLUSH_ISA_X86 - #elif defined(__arm64__) || defined(__aarch64__) - #define CACHEFLUSH_ISA_TYPE CACHEFLUSH_ISA_ARM64 - #else - #define CACHEFLUSH_ISA_TYPE CACHEFLUSH_ISA_GENERIC - #endif -#endif - -#if (CACHEFLUSH_ISA_TYPE == CACHEFLUSH_ISA_X86) || (CACHEFLUSH_ISA_TYPE == CACHEFLUSH_ISA_ARM64) -#define CACHEFLUSH_ISA_SUPPORTS_UM_FLUSH /*!< x86/x86_64/ARM64 supports user-mode d-cache flush */ -#endif - -#endif /* OS_CPU_CACHE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/os_srvinit_param.h b/drivers/gpu/drm/img-rogue/1.17/os_srvinit_param.h deleted file mode 100644 index a4d77e381ff77..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/os_srvinit_param.h +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services initialisation parameters header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services initialisation parameter support for the Linux kernel. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OS_SRVINIT_PARAM_H -#define OS_SRVINIT_PARAM_H - -#if defined(__linux__) && defined(__KERNEL__) -#include "km_apphint.h" -#include "km_apphint_defs.h" - -/* Supplied to SrvInitParamGetXXX() functions when the param/AppHint is - * applicable to all devices and not a specific device. Typically used - * for server-wide build and module AppHints. - */ -#define INITPARAM_NO_DEVICE (NULL) - -#define SrvInitParamOpen() NULL -#define SrvInitParamClose(pvState) ((void)(pvState)) - -#define SrvInitParamGetBOOL(device, state, name, value) \ - ((void) pvr_apphint_get_bool(device, APPHINT_ID_ ## name, &value)) - -#define SrvInitParamGetUINT32(device, state, name, value) \ - ((void) pvr_apphint_get_uint32(device, APPHINT_ID_ ## name, &value)) - -#define SrvInitParamGetUINT64(device, state, name, value) \ - ((void) pvr_apphint_get_uint64(device, APPHINT_ID_ ## name, &value)) - -#define SrvInitParamGetSTRING(device, state, name, buffer, size) \ - ((void) pvr_apphint_get_string(device, APPHINT_ID_ ## name, buffer, size)) - -#define SrvInitParamGetUINT32BitField(device, state, name, value) \ - ((void) pvr_apphint_get_uint32(device, APPHINT_ID_ ## name, &value)) - -#define SrvInitParamGetUINT32List(device, state, name, value) \ - ((void) pvr_apphint_get_uint32(device, APPHINT_ID_ ## name, &value)) - -#else /* defined(__linux__) && defined(__KERNEL__) */ - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" -#include "img_types.h" - -/*! Lookup item. */ -typedef struct -{ - const IMG_CHAR *pszValue; /*!< looked up name */ - IMG_UINT32 ui32Value; /*!< looked up value */ -} SRV_INIT_PARAM_UINT32_LOOKUP; - -/*************************************************************************/ /*! -@Brief SrvInitParamOpen - -@Description Establish a connection to the Parameter resource store which is - used to hold configuration information associated with the - server instance. - -@Return (void *) Handle to Parameter resource store to be used for - subsequent parameter value queries - -*/ /**************************************************************************/ -void *SrvInitParamOpen(void); - -/*************************************************************************/ /*! -@Brief SrvInitParamClose - -@Description Remove a pre-existing connection to the Parameter resource store - given by 'pvState' and release any temporary storage associated - with the 'pvState' mapping handle - -@Input pvState Handle to Parameter resource store - -*/ /**************************************************************************/ -void SrvInitParamClose(void *pvState); - -/*************************************************************************/ /*! -@Brief _SrvInitParamGetBOOL - -@Description Get the current BOOL value for parameter 'pszName' from the - Parameter resource store attached to 'pvState' - -@Input pvState Handle to Parameter resource store - -@Input pszName Name of parameter to look-up - -@Input pbDefault Value to return if parameter not found - -@Output pbValue Value of parameter 'pszName' or 'pbDefault' - if not found - -*/ /**************************************************************************/ -void _SrvInitParamGetBOOL( - void *pvState, - const IMG_CHAR *pszName, - const IMG_BOOL *pbDefault, - IMG_BOOL *pbValue -); - -/*! Get the BOOL value for parameter 'name' from the parameter resource store - * attached to 'state'. */ -#define SrvInitParamGetBOOL(device, state, name, value) \ - _SrvInitParamGetBOOL(state, # name, & __SrvInitParam_ ## name, &(value)) - -/*! Initialise FLAG type parameter identified by 'name'. */ -#define SrvInitParamInitFLAG(name, defval, unused) \ - static const IMG_BOOL __SrvInitParam_ ## name = defval; - -/*! Initialise BOOL type parameter identified by 'name'. */ -#define SrvInitParamInitBOOL(name, defval, unused) \ - static const IMG_BOOL __SrvInitParam_ ## name = defval; - -/*************************************************************************/ /*! -@Brief _SrvInitParamGetUINT32 - -@Description Get the current IMG_UINT32 value for parameter 'pszName' - from the Parameter resource store attached to 'pvState' - -@Input pvState Handle to Parameter resource store - -@Input pszName Name of parameter to look-up - -@Input pui32Default Value to return if parameter not found - -@Output pui32Value Value of parameter 'pszName' or - 'pui32Default' if not found - -*/ /**************************************************************************/ -void _SrvInitParamGetUINT32( - void *pvState, - const IMG_CHAR *pszName, - const IMG_UINT32 *pui32Default, - IMG_UINT32 *pui32Value -); - -/*! Get the UINT32 value for parameter 'name' from the parameter resource store - * attached to 'state'. */ -#define SrvInitParamGetUINT32(device, state, name, value) \ - _SrvInitParamGetUINT32(state, # name, & __SrvInitParam_ ## name, &(value)) - -/*! Initialise UINT32 type parameter identified by 'name'. */ -#define SrvInitParamInitUINT32(name, defval, unused) \ - static const IMG_UINT32 __SrvInitParam_ ## name = defval; - -/*! Initialise UINT64 type parameter identified by 'name'. */ -#define SrvInitParamInitUINT64(name, defval, unused) \ - static const IMG_UINT64 __SrvInitParam_ ## name = defval; - -/*! @cond Doxygen_Suppress */ -#define SrvInitParamUnreferenced(name) \ - PVR_UNREFERENCED_PARAMETER( __SrvInitParam_ ## name ) -/*! @endcond */ - -/*************************************************************************/ /*! -@Brief _SrvInitParamGetUINT32BitField - -@Description Get the current IMG_UINT32 bitfield value for parameter - 'pszBasename' from the Parameter resource store - attached to 'pvState' - -@Input pvState Handle to Parameter resource store - -@Input pszBaseName Bitfield parameter name to search for - -@Input uiDefault Default return value if parameter not found - -@Input psLookup Bitfield array to traverse - -@Input uiSize number of elements in 'psLookup' - -@Output puiValue Value of bitfield or 'uiDefault' if - parameter not found -*/ /**************************************************************************/ -void _SrvInitParamGetUINT32BitField( - void *pvState, - const IMG_CHAR *pszBaseName, - IMG_UINT32 uiDefault, - const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, - IMG_UINT32 uiSize, - IMG_UINT32 *puiValue -); - -/*! Initialise UINT32 bitfield type parameter identified by 'name' with - * 'inival' value and 'lookup' look up array. */ -#define SrvInitParamInitUINT32Bitfield(name, inival, lookup) \ - static IMG_UINT32 __SrvInitParam_ ## name = inival; \ - static SRV_INIT_PARAM_UINT32_LOOKUP * \ - __SrvInitParamLookup_ ## name = &lookup[0]; \ - static const IMG_UINT32 __SrvInitParamSize_ ## name = \ - ARRAY_SIZE(lookup); - -/*! Get the UINT32 bitfield value for parameter 'name' from the parameter - * resource store attached to 'state'. */ -#define SrvInitParamGetUINT32BitField(device, state, name, value) \ - _SrvInitParamGetUINT32BitField(state, # name, __SrvInitParam_ ## name, __SrvInitParamLookup_ ## name, __SrvInitParamSize_ ## name, &(value)) - -/*************************************************************************/ /*! -@Brief _SrvInitParamGetUINT32List - -@Description Get the current IMG_UINT32 list value for the specified - parameter 'pszName' from the Parameter resource store - attached to 'pvState' - -@Input pvState Handle to Parameter resource store - -@Input pszName Parameter list name to search for - -@Input uiDefault Default value to return if 'pszName' is - not set within 'pvState' - -@Input psLookup parameter list to traverse - -@Input uiSize number of elements in 'psLookup' list - -@Output puiValue value of located list element or - 'uiDefault' if parameter not found - -*/ /**************************************************************************/ -void _SrvInitParamGetUINT32List( - void *pvState, - const IMG_CHAR *pszName, - IMG_UINT32 uiDefault, - const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, - IMG_UINT32 uiSize, - IMG_UINT32 *puiValue -); - -/*! Get the UINT32 list value for parameter 'name' from the parameter - * resource store attached to 'state'. */ -#define SrvInitParamGetUINT32List(device, state, name, value) \ - _SrvInitParamGetUINT32List(state, # name, __SrvInitParam_ ## name, __SrvInitParamLookup_ ## name, __SrvInitParamSize_ ## name, &(value)) - -/*! Initialise UINT32 list type parameter identified by 'name' with - * 'defval' default value and 'lookup' look up list. */ -#define SrvInitParamInitUINT32List(name, defval, lookup) \ - static IMG_UINT32 __SrvInitParam_ ## name = defval; \ - static SRV_INIT_PARAM_UINT32_LOOKUP * \ - __SrvInitParamLookup_ ## name = &lookup[0]; \ - static const IMG_UINT32 __SrvInitParamSize_ ## name = \ - ARRAY_SIZE(lookup); - -/*************************************************************************/ /*! -@Brief _SrvInitParamGetSTRING - -@Description Get the contents of the specified parameter string 'pszName' - from the Parameter resource store attached to 'pvState' - -@Input pvState Handle to Parameter resource store - -@Input pszName Parameter string name to search for - -@Input psDefault Default string to return if 'pszName' is - not set within 'pvState' - -@Input size Size of output 'pBuffer' - -@Output pBuffer Output copy of 'pszName' contents or - copy of 'psDefault' if 'pszName' is not - set within 'pvState' - -*/ /**************************************************************************/ -void _SrvInitParamGetSTRING( - void *pvState, - const IMG_CHAR *pszName, - const IMG_CHAR *psDefault, - IMG_CHAR *pBuffer, - size_t size -); - -/*! Initialise STRING type parameter identified by 'name' with 'defval' default - * value. */ -#define SrvInitParamInitSTRING(name, defval, unused) \ - static const IMG_CHAR *__SrvInitParam_ ## name = defval; - -/*! Get the STRING value for parameter 'name' from the parameter resource store - * attached to 'state'. */ -#define SrvInitParamGetSTRING(device, state, name, buffer, size) \ - _SrvInitParamGetSTRING(state, # name, __SrvInitParam_ ## name, buffer, size) - -#if defined(__cplusplus) -} -#endif - -#endif /* defined(__linux__) && defined(__KERNEL__) */ - -#endif /* OS_SRVINIT_PARAM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/osconnection_server.c b/drivers/gpu/drm/img-rogue/1.17/osconnection_server.c deleted file mode 100644 index a5717bc871575..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osconnection_server.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linux specific per process data functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "connection_server.h" -#include "osconnection_server.h" - -#include "env_connection.h" -#include "allocmem.h" -#include "pvr_debug.h" - -#include - -#if defined(SUPPORT_ION) -#include -#include PVR_ANDROID_ION_HEADER - -/* - The ion device (the base object for all requests) - gets created by the system and we acquire it via - Linux specific functions provided by the system layer -*/ -#include "ion_sys.h" -#endif - -PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, void *pvOSData) -{ - ENV_CONNECTION_PRIVATE_DATA *psPrivData = pvOSData; - ENV_CONNECTION_DATA *psEnvConnection; -#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - ENV_ION_CONNECTION_DATA *psIonConnection; -#endif - - *phOsPrivateData = OSAllocZMem(sizeof(ENV_CONNECTION_DATA)); - - if (*phOsPrivateData == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psEnvConnection = (ENV_CONNECTION_DATA *)*phOsPrivateData; - - psEnvConnection->owner = current->tgid; - - psEnvConnection->psDevNode = psPrivData->psDevNode; - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - psEnvConnection->pvPvrSyncPrivateData = NULL; -#endif - -#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - psIonConnection = (ENV_ION_CONNECTION_DATA *)OSAllocZMem(sizeof(ENV_ION_CONNECTION_DATA)); - if (psIonConnection == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psEnvConnection->psIonData = psIonConnection; - /* - We can have more than one connection per process, so we need - more than the PID to have a unique name. - */ - psEnvConnection->psIonData->psIonDev = IonDevAcquire(); - OSSNPrintf(psEnvConnection->psIonData->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%p-%d", *phOsPrivateData, OSGetCurrentClientProcessIDKM()); - psEnvConnection->psIonData->psIonClient = - ion_client_create(psEnvConnection->psIonData->psIonDev, - psEnvConnection->psIonData->azIonClientName); - - if (IS_ERR_OR_NULL(psEnvConnection->psIonData->psIonClient)) - { - PVR_DPF((PVR_DBG_ERROR, "OSConnectionPrivateDataInit: Couldn't create " - "ion client for per connection data")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } -#endif /* SUPPORT_ION && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) */ - return PVRSRV_OK; -} - -PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData) -{ - ENV_CONNECTION_DATA __maybe_unused *psEnvConnection; - - if (hOsPrivateData == NULL) - { - return PVRSRV_OK; - } - - psEnvConnection = hOsPrivateData; - -#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - PVR_ASSERT(psEnvConnection->psIonData != NULL); - - PVR_ASSERT(psEnvConnection->psIonData->psIonClient != NULL); - ion_client_destroy(psEnvConnection->psIonData->psIonClient); - - IonDevRelease(psEnvConnection->psIonData->psIonDev); - OSFreeMem(psEnvConnection->psIonData); -#endif - - OSFreeMem(hOsPrivateData); - /*not nulling pointer, copy on stack*/ - - return PVRSRV_OK; -} - - -PVRSRV_DEVICE_NODE *OSGetDevNode(CONNECTION_DATA *psConnection) -{ - ENV_CONNECTION_DATA *psEnvConnection; - - psEnvConnection = PVRSRVConnectionPrivateData(psConnection); - PVR_ASSERT(psEnvConnection); - - return psEnvConnection->psDevNode; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/osconnection_server.h b/drivers/gpu/drm/img-rogue/1.17/osconnection_server.h deleted file mode 100644 index 28a6dd3825fba..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osconnection_server.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Server side connection management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description API for OS specific callbacks from server side connection - management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OSCONNECTION_SERVER_H -#define OSCONNECTION_SERVER_H - -#include "handle.h" -#include "osfunc.h" - -/*! Function not implemented definition. */ -#define OSCONNECTION_SERVER_NOT_IMPLEMENTED 0 -/*! Assert used for OSCONNECTION_SERVER_NOT_IMPLEMENTED. */ -#define OSCONNECTION_SERVER_NOT_IMPLEMENTED_ASSERT() PVR_ASSERT(OSCONNECTION_SERVER_NOT_IMPLEMENTED) - -#if defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) -PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, void *pvOSData); -PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData); - -PVRSRV_ERROR OSConnectionSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase); - -PVRSRV_DEVICE_NODE* OSGetDevNode(CONNECTION_DATA *psConnection); - -#else /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */ -#ifdef INLINE_IS_PRAGMA -#pragma inline(OSConnectionPrivateDataInit) -#endif -/*************************************************************************/ /*! -@Function OSConnectionPrivateDataInit -@Description Allocates and initialises any OS-specific private data - relating to a connection. - Called from PVRSRVCommonConnectionConnect(). -@Input pvOSData pointer to any OS private data -@Output phOsPrivateData handle to the created connection - private data -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -static INLINE PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, void *pvOSData) -{ - PVR_UNREFERENCED_PARAMETER(phOsPrivateData); - PVR_UNREFERENCED_PARAMETER(pvOSData); - - OSCONNECTION_SERVER_NOT_IMPLEMENTED_ASSERT(); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(OSConnectionPrivateDataDeInit) -#endif -/*************************************************************************/ /*! -@Function OSConnectionPrivateDataDeInit -@Description Frees previously allocated OS-specific private data - relating to a connection. -@Input hOsPrivateData handle to the connection private data - to be freed -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -static INLINE PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData) -{ - PVR_UNREFERENCED_PARAMETER(hOsPrivateData); - - OSCONNECTION_SERVER_NOT_IMPLEMENTED_ASSERT(); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(OSConnectionSetHandleOptions) -#endif -static INLINE PVRSRV_ERROR OSConnectionSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) -{ - PVR_UNREFERENCED_PARAMETER(psHandleBase); - - OSCONNECTION_SERVER_NOT_IMPLEMENTED_ASSERT(); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(OSGetDevNode) -#endif -static INLINE PVRSRV_DEVICE_NODE* OSGetDevNode(CONNECTION_DATA *psConnection) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - - OSCONNECTION_SERVER_NOT_IMPLEMENTED_ASSERT(); - - return NULL; -} -#endif /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */ - - -#endif /* OSCONNECTION_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/osdi_impl.h b/drivers/gpu/drm/img-rogue/1.17/osdi_impl.h deleted file mode 100644 index 0a7916ad5270f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osdi_impl.h +++ /dev/null @@ -1,201 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Functions and types for creating Debug Info implementations. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OSDI_IMPL_H -#define OSDI_IMPL_H - -#include - -#include "di_common.h" -#include "pvrsrv_error.h" - -/*! Implementation callbacks. Those operations are performed on native - * implementation handles. */ -typedef struct OSDI_IMPL_ENTRY_CB -{ - /*! @Function pfnWrite - * - * @Description - * Writes the binary data of the DI entry to the output sync, whatever that - * may be for the DI implementation. - * - * @Input pvNativeHandle native implementation handle - * @Input pvData data - * @Input uiSize pvData length - */ - void (*pfnWrite)(void *pvNativeHandle, const void *pvData, - IMG_UINT32 uiSize); - - /*! @Function pfnVPrintf - * - * @Description - * Implementation of the 'vprintf' operation. - * - * @Input pvNativeHandle native implementation handle - * @Input pszFmt NUL-terminated format string - * @Input va_list variable length argument list - */ - void (*pfnVPrintf)(void *pvNativeHandle, const IMG_CHAR *pszFmt, va_list pArgs) __printf(2, 0); - - /*! @Function pfnPuts - * - * @Description - * Implementation of the 'puts' operation. - * - * @Input pvNativeHandle native implementation handle - * @Input pszStr NUL-terminated string - */ - void (*pfnPuts)(void *pvNativeHandle, const IMG_CHAR *pszStr); - - /*! @Function pfnHasOverflowed - * - * @Description - * Checks if the native implementation's buffer has overflowed. - * - * @Input pvNativeHandle native implementation handle - */ - IMG_BOOL (*pfnHasOverflowed)(void *pvNativeHandle); -} OSDI_IMPL_ENTRY_CB; - -/*! Debug Info entry specialisation. */ -struct OSDI_IMPL_ENTRY -{ - /*! Pointer to the private data. The data originates from DICreateEntry() - * function. */ - void *pvPrivData; - /*! Pointer to the implementation native handle. */ - void *pvNative; - /*! Implementation entry callbacks. */ - OSDI_IMPL_ENTRY_CB *psCb; -}; /* OSDI_IMPL_ENTRY is already typedef-ed in di_common.h */ - -/*! Debug Info implementation callbacks. */ -typedef struct OSDI_IMPL_CB -{ - /*! Initialise implementation callback. - */ - PVRSRV_ERROR (*pfnInit)(void); - - /*! De-initialise implementation callback. - */ - void (*pfnDeInit)(void); - - /*! @Function pfnCreateEntry - * - * @Description - * Creates entry of eType type with pszName in the pvNativeGroup parent - * group. The entry is an abstract term which depends on the implementation, - * e.g.: a file in DebugFS. - * - * @Input pszName: name of the entry - * @Input eType: type of the entry - * @Input psIterCb: iterator implementation for the entry - * @Input pvPrivData: data that will be passed to the iterator callbacks - * in OSDI_IMPL_ENTRY - it can be retrieved by calling - * DIGetPrivData() function - * @Input pvNativeGroup: implementation specific handle to the parent group - * - * @Output pvNativeEntry: implementation specific handle to the entry - * - * return PVRSRV_ERROR error code - */ - PVRSRV_ERROR (*pfnCreateEntry)(const IMG_CHAR *pszName, - DI_ENTRY_TYPE eType, - const DI_ITERATOR_CB *psIterCb, - void *pvPrivData, - void *pvNativeGroup, - void **pvNativeEntry); - - /*! @Function pfnDestroyEntry - * - * @Description - * Destroys native entry. - * - * @Input psNativeEntry: handle to the entry - */ - void (*pfnDestroyEntry)(void *psNativeEntry); - - /*! @Function pfnCreateGroup - * - * @Description - * Creates group with pszName in the psNativeParentGroup parent group. - * The group is an abstract term which depends on the implementation, - * e.g.: a directory in DebugFS. - * - * @Input pszName: name of the entry - * @Input psNativeParentGroup: implementation specific handle to the parent - * group - * - * @Output psNativeGroup: implementation specific handle to the group - * - * return PVRSRV_ERROR error code - */ - PVRSRV_ERROR (*pfnCreateGroup)(const IMG_CHAR *pszName, - void *psNativeParentGroup, - void **psNativeGroup); - - /*! @Function pfnDestroyGroup - * - * @Description - * Destroys native group. - * - * @Input psNativeGroup: handle to the group - */ - void (*pfnDestroyGroup)(void *psNativeGroup); -} OSDI_IMPL_CB; - -/*! @Function DIRegisterImplementation - * - * @Description - * Registers Debug Info implementations with the framework. The framework takes - * the ownership of the implementation and will clean up the resources when - * it's de-initialised. - * - * @Input pszName: name of the implementation - * @Input psImplCb: implementation callbacks - * - * @Return PVRSRV_ERROR error code - */ -PVRSRV_ERROR DIRegisterImplementation(const IMG_CHAR *pszName, - const OSDI_IMPL_CB *psImplCb); - -#endif /* OSDI_IMPL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/osfunc.c b/drivers/gpu/drm/img-rogue/1.17/osfunc.c deleted file mode 100644 index 0f21bc7e79fd9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osfunc.c +++ /dev/null @@ -1,2601 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Environment related functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) -#include -#include -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) -#include -#include -#else -#include -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) */ - -#include "log2.h" -#include "osfunc.h" -#include "cache_km.h" -#include "img_defs.h" -#include "img_types.h" -#include "allocmem.h" -#include "devicemem_server_utils.h" -#include "event.h" -#include "linkage.h" -#include "pvr_uaccess.h" -#include "pvr_debug.h" -#include "pvr_bridge_k.h" -#include "pvrsrv_memallocflags.h" -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif -#include "physmem_osmem_linux.h" -#include "dma_support.h" -#include "kernel_compatibility.h" - -#include "pvrsrv_sync_server.h" - - -#if defined(VIRTUAL_PLATFORM) -#define EVENT_OBJECT_TIMEOUT_US (120000000ULL) -#else -#if defined(EMULATOR) || defined(TC_APOLLO_TCF5) -#define EVENT_OBJECT_TIMEOUT_US (2000000ULL) -#else -#define EVENT_OBJECT_TIMEOUT_US (100000ULL) -#endif /* EMULATOR */ -#endif - - -typedef struct { - struct task_struct *kthread; - PFN_THREAD pfnThread; - void *hData; - IMG_CHAR *pszThreadName; - IMG_BOOL bIsThreadRunning; - IMG_BOOL bIsSupportingThread; - PFN_THREAD_DEBUG_DUMP pfnDebugDumpCB; - DLLIST_NODE sNode; -} OSThreadData; - -void OSSuspendTaskInterruptible(void) -{ - set_current_state(TASK_INTERRUPTIBLE); - schedule(); -} - -static DLLIST_NODE gsThreadListHead; - -static void _ThreadListAddEntry(OSThreadData *psThreadListNode) -{ - dllist_add_to_tail(&gsThreadListHead, &(psThreadListNode->sNode)); -} - -static void _ThreadListRemoveEntry(OSThreadData *psThreadListNode) -{ - dllist_remove_node(&(psThreadListNode->sNode)); -} - -static void _ThreadSetStopped(OSThreadData *psOSThreadData) -{ - psOSThreadData->bIsThreadRunning = IMG_FALSE; -} - -static void _OSInitThreadList(void) -{ - dllist_init(&gsThreadListHead); -} - -void OSThreadDumpInfo(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PDLLIST_NODE psNodeCurr, psNodeNext; - - dllist_foreach_node(&gsThreadListHead, psNodeCurr, psNodeNext) - { - OSThreadData *psThreadListNode; - psThreadListNode = IMG_CONTAINER_OF(psNodeCurr, OSThreadData, sNode); - - PVR_DUMPDEBUG_LOG(" %s : %s", - psThreadListNode->pszThreadName, - (psThreadListNode->bIsThreadRunning) ? "Running" : "Stopped"); - - if (psThreadListNode->pfnDebugDumpCB) - { - psThreadListNode->pfnDebugDumpCB(pfnDumpDebugPrintf, pvDumpDebugFile); - } - } -} - -PVRSRV_ERROR OSPhyContigPagesAlloc(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid) -{ - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPhysHeap); - struct device *psDev = psDevNode->psDevConfig->pvOSDevice; - IMG_CPU_PHYADDR sCpuPAddr; - struct page *psPage; - IMG_UINT32 ui32Order=0; - gfp_t gfp_flags; - - PVR_ASSERT(uiSize != 0); - /*Align the size to the page granularity */ - uiSize = PAGE_ALIGN(uiSize); - - /*Get the order to be used with the allocation */ - ui32Order = get_order(uiSize); - - gfp_flags = GFP_KERNEL; - -#if !defined(PVR_LINUX_PHYSMEM_USE_HIGHMEM_ONLY) - if (psDev) - { - if (*psDev->dma_mask == DMA_BIT_MASK(32)) - { - /* Limit to 32 bit. - * Achieved by setting __GFP_DMA32 for 64 bit systems */ - gfp_flags |= __GFP_DMA32; - } - else if (*psDev->dma_mask < DMA_BIT_MASK(32)) - { - /* Limit to whatever the size of DMA zone is. */ - gfp_flags |= __GFP_DMA; - } - } -#else - PVR_UNREFERENCED_PARAMETER(psDev); -#endif - - /*allocate the pages */ - psPage = alloc_pages(gfp_flags, ui32Order); - if (psPage == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - uiSize = (1 << ui32Order) * PAGE_SIZE; - - psMemHandle->u.pvHandle = psPage; - psMemHandle->uiOrder = ui32Order; - sCpuPAddr.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(page_to_phys(psPage)); - - /* - * Even when more pages are allocated as base MMU object we still need one single physical address because - * they are physically contiguous. - */ - PhysHeapCpuPAddrToDevPAddr(psPhysHeap, 1, psDevPAddr, &sCpuPAddr); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, - uiSize, - (IMG_UINT64)(uintptr_t) psPage, - uiPid); -#else - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, - psPage, - sCpuPAddr, - uiSize, - NULL, - uiPid - DEBUG_MEMSTATS_VALUES); -#endif -#else - PVR_UNREFERENCED_PARAMETER(uiPid); -#endif - - return PVRSRV_OK; -} - -void OSPhyContigPagesFree(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle) -{ - struct page *psPage = (struct page*) psMemHandle->u.pvHandle; - IMG_UINT32 ui32Order; - - PVR_UNREFERENCED_PARAMETER(psPhysHeap); - - ui32Order = psMemHandle->uiOrder; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, - (IMG_UINT64)(uintptr_t) psPage); -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, - (IMG_UINT64)(uintptr_t) psPage, - OSGetCurrentClientProcessIDKM()); -#endif -#endif - - __free_pages(psPage, ui32Order); - psMemHandle->uiOrder = 0; -} - -PVRSRV_ERROR OSPhyContigPagesMap(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle, - size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr) -{ - size_t actualSize = 1 << (PAGE_SHIFT + psMemHandle->uiOrder); - *pvPtr = kmap((struct page*)psMemHandle->u.pvHandle); - - PVR_UNREFERENCED_PARAMETER(psDevPAddr); - - PVR_UNREFERENCED_PARAMETER(actualSize); /* If we don't take an #ifdef path */ - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(psPhysHeap); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, actualSize, OSGetCurrentClientProcessIDKM()); -#else - { - IMG_CPU_PHYADDR sCpuPAddr; - sCpuPAddr.uiAddr = 0; - - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, - *pvPtr, - sCpuPAddr, - actualSize, - NULL, - OSGetCurrentClientProcessIDKM() - DEBUG_MEMSTATS_VALUES); - } -#endif -#endif - - return PVRSRV_OK; -} - -void OSPhyContigPagesUnmap(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle, void *pvPtr) -{ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - /* Mapping is done a page at a time */ - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, - (1 << (PAGE_SHIFT + psMemHandle->uiOrder)), - OSGetCurrentClientProcessIDKM()); -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, - (IMG_UINT64)(uintptr_t)pvPtr, - OSGetCurrentClientProcessIDKM()); -#endif -#endif - - PVR_UNREFERENCED_PARAMETER(psPhysHeap); - PVR_UNREFERENCED_PARAMETER(pvPtr); - - kunmap((struct page*) psMemHandle->u.pvHandle); -} - -PVRSRV_ERROR OSPhyContigPagesClean(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength) -{ - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPhysHeap); - PVRSRV_ERROR eError = PVRSRV_OK; - struct page* psPage = (struct page*) psMemHandle->u.pvHandle; - - void* pvVirtAddrStart = kmap(psPage) + uiOffset; - IMG_CPU_PHYADDR sPhysStart, sPhysEnd; - - IMG_UINT32 ui32Order; - - if (uiLength == 0) - { - goto e0; - } - - ui32Order = psMemHandle->uiOrder; - if ((uiOffset + uiLength) > ((1 << ui32Order) * PAGE_SIZE)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid size params, uiOffset %u, uiLength %u", - __func__, - uiOffset, - uiLength)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - sPhysStart.uiAddr = page_to_phys(psPage) + uiOffset; - sPhysEnd.uiAddr = sPhysStart.uiAddr + uiLength; - - CacheOpExec(psDevNode, - pvVirtAddrStart, - pvVirtAddrStart + uiLength, - sPhysStart, - sPhysEnd, - PVRSRV_CACHE_OP_CLEAN); - -e0: - kunmap(psPage); - - return eError; -} - -#if defined(__GNUC__) -#define PVRSRV_MEM_ALIGN __attribute__ ((aligned (0x8))) -#define PVRSRV_MEM_ALIGN_MASK (0x7) -#else -#error "PVRSRV Alignment macros need to be defined for this compiler" -#endif - -IMG_UINT32 OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE eCacheAttribute) -{ - IMG_UINT32 uiSize = 0; - - switch (eCacheAttribute) - { - case OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE: - uiSize = cache_line_size(); - break; - - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache attribute type %d", - __func__, (IMG_UINT32)eCacheAttribute)); - PVR_ASSERT(0); - break; - } - - return uiSize; -} - -__scanf(2, 0) -IMG_UINT32 OSVSScanf(const IMG_CHAR *pStr, const IMG_CHAR *pszFormat, ...) -{ - va_list argList; - IMG_INT32 iCount = 0; - - va_start(argList, pszFormat); - iCount = vsscanf(pStr, pszFormat, argList); - va_end(argList); - - return iCount; -} - -IMG_INT OSMemCmp(void *pvBufA, void *pvBufB, size_t uiLen) -{ - return (IMG_INT)memcmp(pvBufA, pvBufB, uiLen); -} - -size_t OSStringLCat(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDstSize) -{ - /* - * Let strlcat handle any truncation cases correctly. - * We will definitely get a NUL-terminated string set in pszDest - */ - size_t uSrcSize = strlcat(pszDest, pszSrc, uDstSize); - -#if defined(PVR_DEBUG_STRLCPY) && defined(DEBUG) - /* Handle truncation by dumping calling stack if debug allows */ - if (uSrcSize >= uDstSize) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: String truncated Src = '<%s>' %ld bytes, Dest = '%s'", - __func__, pszSrc, (long)uDstSize, pszDest)); - OSDumpStack(); - } -#endif /* defined(PVR_DEBUG_STRLCPY) && defined(DEBUG) */ - - return uSrcSize; -} - -IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...) -{ - va_list argList; - IMG_INT32 iCount; - - va_start(argList, pszFormat); - iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList); - va_end(argList); - - return iCount; -} - -IMG_INT32 OSVSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR* pszFormat, va_list vaArgs) -{ - return vsnprintf(pStr, ui32Size, pszFormat, vaArgs); -} - -size_t OSStringLength(const IMG_CHAR *pStr) -{ - return strlen(pStr); -} - -size_t OSStringNLength(const IMG_CHAR *pStr, size_t uiCount) -{ - return strnlen(pStr, uiCount); -} - -IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2, - size_t uiSize) -{ -#if defined(DEBUG) - /* Double-check that we are not passing NULL parameters in. If we are we - * return -1 (for arg1 == NULL, arg2 != NULL) - * 0 (for arg1 == NULL, arg2 == NULL - * +1 (for arg1 != NULL, arg2 == NULL) - * strncmp(arg1, arg2, size) otherwise - */ - if (pStr1 == NULL) - { - if (pStr2 == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s(%p, %p, %d): Both args NULL", - __func__, pStr1, pStr2, (int)uiSize)); - OSDumpStack(); - return 0; /* Both NULL */ - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s(%p, %p, %d): arg1 NULL", - __func__, pStr1, pStr2, (int)uiSize)); - OSDumpStack(); - return -1; /* NULL < non-NULL */ - } - } - else - { - if (pStr2 == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s(%p, %p, %d): arg2 NULL", - __func__, pStr1, pStr2, (int)uiSize)); - OSDumpStack(); - return +1; /* non-NULL > NULL */ - } - else - { - return strncmp(pStr1, pStr2, uiSize); - } - } -#else - return strncmp(pStr1, pStr2, uiSize); -#endif -} - -PVRSRV_ERROR OSStringToUINT32(const IMG_CHAR *pStr, IMG_UINT32 ui32Base, - IMG_UINT32 *ui32Result) -{ - if (kstrtou32(pStr, ui32Base, ui32Result) != 0) - return PVRSRV_ERROR_CONVERSION_FAILED; - - return PVRSRV_OK; -} - -IMG_UINT32 OSStringUINT32ToStr(IMG_CHAR *pszBuf, size_t uSize, - IMG_UINT32 ui32Num) -{ - IMG_UINT32 ui32i, ui32Len = 0, ui32NumCopy = ui32Num; - - /* calculate string length required to hold the number string */ - do - { - ui32Len++; - ui32NumCopy /= 10; - } while (ui32NumCopy != 0); - - if (unlikely(ui32Len >= uSize)) - { - /* insufficient buffer */ - return 0; - } - - for (ui32i = 0; ui32i < ui32Len; ui32i++) - { - pszBuf[ui32Len - (ui32i + 1)] = '0' + ui32Num % 10; - ui32Num = ui32Num / 10; - } - - pszBuf[ui32Len] = '\0'; - return ui32Len; -} - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) || defined(SUPPORT_BUFFER_SYNC) -static struct workqueue_struct *gpFenceStatusWq; - -static PVRSRV_ERROR _NativeSyncInit(void) -{ - gpFenceStatusWq = create_freezable_workqueue("pvr_fence_status"); - if (!gpFenceStatusWq) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create foreign fence status workqueue", - __func__)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - return PVRSRV_OK; -} - -static void _NativeSyncDeinit(void) -{ - destroy_workqueue(gpFenceStatusWq); -} - -struct workqueue_struct *NativeSyncGetFenceStatusWq(void) -{ - if (!gpFenceStatusWq) - { -#if defined(DEBUG) - PVR_ASSERT(gpFenceStatusWq); -#endif - return NULL; - } - - return gpFenceStatusWq; -} -#endif - -PVRSRV_ERROR OSInitEnvData(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - LinuxInitPhysmem(); - - _OSInitThreadList(); - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) || defined(SUPPORT_BUFFER_SYNC) - eError = _NativeSyncInit(); -#endif - - return eError; -} - -void OSDeInitEnvData(void) -{ -#if defined(SUPPORT_NATIVE_FENCE_SYNC) || defined(SUPPORT_BUFFER_SYNC) - _NativeSyncDeinit(); -#endif - - LinuxDeinitPhysmem(); -} - -void OSReleaseThreadQuanta(void) -{ - schedule(); -} - -void OSMemoryBarrier(volatile void *hReadback) -{ - mb(); - - if (hReadback) - { - /* Force a read-back to memory to avoid posted writes on certain buses - * e.g. PCI(E) - */ - (void) OSReadDeviceMem32(hReadback); - } -} - -void OSWriteMemoryBarrier(volatile void *hReadback) -{ - wmb(); - - if (hReadback) - { - /* Force a read-back to memory to avoid posted writes on certain buses - * e.g. PCI(E) - */ - (void) OSReadDeviceMem32(hReadback); - } -} - -/* Not matching/aligning this API to the Clockus() API above to avoid necessary - * multiplication/division operations in calling code. - */ -static inline IMG_UINT64 Clockns64(void) -{ - IMG_UINT64 timenow; - - /* Kernel thread preempt protection. Some architecture implementations - * (ARM) of sched_clock are not preempt safe when the kernel is configured - * as such e.g. CONFIG_PREEMPT and others. - */ - preempt_disable(); - - /* Using sched_clock instead of ktime_get since we need a time stamp that - * correlates with that shown in kernel logs and trace data not one that - * is a bit behind. */ - timenow = sched_clock(); - - preempt_enable(); - - return timenow; -} - -IMG_UINT64 OSClockns64(void) -{ - return Clockns64(); -} - -IMG_UINT64 OSClockus64(void) -{ - IMG_UINT64 timenow = Clockns64(); - IMG_UINT32 remainder; - - return OSDivide64r64(timenow, 1000, &remainder); -} - -IMG_UINT32 OSClockus(void) -{ - return (IMG_UINT32) OSClockus64(); -} - -IMG_UINT32 OSClockms(void) -{ - IMG_UINT64 timenow = Clockns64(); - IMG_UINT32 remainder; - - return OSDivide64(timenow, 1000000, &remainder); -} - -static inline IMG_UINT64 KClockns64(void) -{ - ktime_t sTime = ktime_get(); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - return sTime; -#else - return sTime.tv64; -#endif -} - -PVRSRV_ERROR OSClockMonotonicns64(IMG_UINT64 *pui64Time) -{ - *pui64Time = KClockns64(); - return PVRSRV_OK; -} - -PVRSRV_ERROR OSClockMonotonicus64(IMG_UINT64 *pui64Time) -{ - IMG_UINT64 timenow = KClockns64(); - IMG_UINT32 remainder; - - *pui64Time = OSDivide64r64(timenow, 1000, &remainder); - return PVRSRV_OK; -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -IMG_UINT64 OSClockMonotonicRawns64(void) -{ - struct timespec64 ts; - - ktime_get_raw_ts64(&ts); - return ts.tv_sec * 1000000000 + ts.tv_nsec; -} -#else -IMG_UINT64 OSClockMonotonicRawns64(void) -{ - struct timespec ts; - - getrawmonotonic(&ts); - return (IMG_UINT64) ts.tv_sec * 1000000000 + ts.tv_nsec; -} -#endif - -IMG_UINT64 OSClockMonotonicRawus64(void) -{ - IMG_UINT32 rem; - return OSDivide64r64(OSClockMonotonicRawns64(), 1000, &rem); -} - -/* - OSWaitus -*/ -void OSWaitus(IMG_UINT32 ui32Timeus) -{ - udelay(ui32Timeus); -} - - -/* - OSSleepms -*/ -void OSSleepms(IMG_UINT32 ui32Timems) -{ - msleep(ui32Timems); -} - - -INLINE IMG_UINT64 OSGetCurrentProcessVASpaceSize(void) -{ - return (IMG_UINT64)TASK_SIZE; -} - -INLINE IMG_PID OSGetCurrentProcessID(void) -{ - if (in_interrupt()) - { - return KERNEL_ID; - } - - return (IMG_PID)task_tgid_nr(current); -} - -INLINE IMG_PID OSGetCurrentVirtualProcessID(void) -{ - if (in_interrupt()) - { - return KERNEL_ID; - } - - return (IMG_PID)task_tgid_vnr(current); -} - -INLINE IMG_CHAR *OSGetCurrentProcessName(void) -{ - return current->comm; -} - -INLINE uintptr_t OSGetCurrentThreadID(void) -{ - if (in_interrupt()) - { - return KERNEL_ID; - } - - return current->pid; -} - -IMG_PID OSGetCurrentClientProcessIDKM(void) -{ - return OSGetCurrentProcessID(); -} - -IMG_CHAR *OSGetCurrentClientProcessNameKM(void) -{ - return OSGetCurrentProcessName(); -} - -uintptr_t OSGetCurrentClientThreadIDKM(void) -{ - return OSGetCurrentThreadID(); -} - -size_t OSGetPageSize(void) -{ - return PAGE_SIZE; -} - -size_t OSGetPageShift(void) -{ - return PAGE_SHIFT; -} - -size_t OSGetPageMask(void) -{ - return (OSGetPageSize()-1); -} - -size_t OSGetOrder(size_t uSize) -{ - return get_order(PAGE_ALIGN(uSize)); -} - -IMG_UINT64 OSGetRAMSize(void) -{ - struct sysinfo SI; - si_meminfo(&SI); - - return (PAGE_SIZE * SI.totalram); -} - -typedef struct -{ - int os_error; - PVRSRV_ERROR pvr_error; -} error_map_t; - -/* return -ve versions of POSIX errors as they are used in this form */ -static const error_map_t asErrorMap[] = -{ - {-EFAULT, PVRSRV_ERROR_BRIDGE_EFAULT}, - {-EINVAL, PVRSRV_ERROR_BRIDGE_EINVAL}, - {-ENOMEM, PVRSRV_ERROR_BRIDGE_ENOMEM}, - {-ERANGE, PVRSRV_ERROR_BRIDGE_ERANGE}, - {-EPERM, PVRSRV_ERROR_BRIDGE_EPERM}, - {-ENOTTY, PVRSRV_ERROR_BRIDGE_ENOTTY}, - {-ENOTTY, PVRSRV_ERROR_BRIDGE_CALL_FAILED}, - {-ERANGE, PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL}, - {-ENOMEM, PVRSRV_ERROR_OUT_OF_MEMORY}, - {-EACCES, PVRSRV_ERROR_PMR_NOT_PERMITTED}, - {-EINVAL, PVRSRV_ERROR_INVALID_PARAMS}, - {-EINVAL, PVRSRV_ERROR_BAD_MAPPING}, - - {0, PVRSRV_OK} -}; - -int PVRSRVToNativeError(PVRSRV_ERROR e) -{ - int os_error = -EFAULT; - int i; - - for (i = 0; i < ARRAY_SIZE(asErrorMap); i++) - { - if (e == asErrorMap[i].pvr_error) - { - os_error = asErrorMap[i].os_error; - break; - } - } - return os_error; -} - -typedef struct _MISR_DATA_ { - struct workqueue_struct *psWorkQueue; - struct work_struct sMISRWork; - const IMG_CHAR* pszName; - PFN_MISR pfnMISR; - void *hData; -} MISR_DATA; - -/* - MISRWrapper -*/ -static void MISRWrapper(struct work_struct *data) -{ - MISR_DATA *psMISRData = container_of(data, MISR_DATA, sMISRWork); - - PVR_DPF((PVR_DBG_MESSAGE, "Waking up '%s' MISR %p", psMISRData->pszName, psMISRData)); - - psMISRData->pfnMISR(psMISRData->hData); -} - -/* - OSInstallMISR -*/ -PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR, - void *hData, const IMG_CHAR *pszMisrName) -{ - MISR_DATA *psMISRData; - - psMISRData = OSAllocMem(sizeof(*psMISRData)); - PVR_LOG_RETURN_IF_NOMEM(psMISRData, "psMISRData"); - - psMISRData->hData = hData; - psMISRData->pfnMISR = pfnMISR; - psMISRData->pszName = pszMisrName; - - PVR_DPF((PVR_DBG_MESSAGE, "Installing MISR with cookie %p", psMISRData)); - - psMISRData->psWorkQueue = create_singlethread_workqueue("pvr_misr"); - - if (psMISRData->psWorkQueue == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed")); - OSFreeMem(psMISRData); - return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD; - } - - INIT_WORK(&psMISRData->sMISRWork, MISRWrapper); - - *hMISRData = (IMG_HANDLE) psMISRData; - - return PVRSRV_OK; -} - -/* - OSUninstallMISR -*/ -PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData) -{ - MISR_DATA *psMISRData = (MISR_DATA *) hMISRData; - - PVR_DPF((PVR_DBG_MESSAGE, "Uninstalling MISR with cookie %p", psMISRData)); - - destroy_workqueue(psMISRData->psWorkQueue); - OSFreeMem(psMISRData); - - return PVRSRV_OK; -} - -/* - OSScheduleMISR -*/ -PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData) -{ - MISR_DATA *psMISRData = (MISR_DATA *) hMISRData; - - /* - Note: - - In the case of NO_HARDWARE we want the driver to be synchronous so - that we don't have to worry about waiting for previous operations - to complete - */ -#if defined(NO_HARDWARE) - psMISRData->pfnMISR(psMISRData->hData); - return PVRSRV_OK; -#else - { - bool rc = queue_work(psMISRData->psWorkQueue, &psMISRData->sMISRWork); - return rc ? PVRSRV_OK : PVRSRV_ERROR_ALREADY_EXISTS; - } -#endif -} - -/* OS specific values for thread priority */ -static const IMG_INT32 ai32OSPriorityValues[OS_THREAD_LAST_PRIORITY] = -{ - 0, /* OS_THREAD_NOSET_PRIORITY */ - -20, /* OS_THREAD_HIGHEST_PRIORITY */ - -10, /* OS_THREAD_HIGH_PRIORITY */ - 0, /* OS_THREAD_NORMAL_PRIORITY */ - 9, /* OS_THREAD_LOW_PRIORITY */ - 19, /* OS_THREAD_LOWEST_PRIORITY */ -}; - -static int OSThreadRun(void *data) -{ - OSThreadData *psOSThreadData = data; - - /* count freezable threads */ - LinuxBridgeNumActiveKernelThreadsIncrement(); - - /* Returns true if the thread was frozen, should we do anything with this - * information? What do we return? Which one is the error case? */ - set_freezable(); - - PVR_DPF((PVR_DBG_MESSAGE, "Starting Thread '%s'...", psOSThreadData->pszThreadName)); - - /* Call the client's kernel thread with the client's data pointer */ - psOSThreadData->pfnThread(psOSThreadData->hData); - - if (psOSThreadData->bIsSupportingThread) - { - _ThreadSetStopped(psOSThreadData); - } - - /* Wait for OSThreadDestroy() to call kthread_stop() */ - while (!kthread_freezable_should_stop(NULL)) - { - schedule(); - } - - LinuxBridgeNumActiveKernelThreadsDecrement(); - - return 0; -} - -PVRSRV_ERROR OSThreadCreate(IMG_HANDLE *phThread, - IMG_CHAR *pszThreadName, - PFN_THREAD pfnThread, - PFN_THREAD_DEBUG_DUMP pfnDebugDumpCB, - IMG_BOOL bIsSupportingThread, - void *hData) -{ - return OSThreadCreatePriority(phThread, pszThreadName, pfnThread, - pfnDebugDumpCB, bIsSupportingThread, hData, - OS_THREAD_NOSET_PRIORITY); -} - -PVRSRV_ERROR OSThreadCreatePriority(IMG_HANDLE *phThread, - IMG_CHAR *pszThreadName, - PFN_THREAD pfnThread, - PFN_THREAD_DEBUG_DUMP pfnDebugDumpCB, - IMG_BOOL bIsSupportingThread, - void *hData, - OS_THREAD_LEVEL eThreadPriority) -{ - OSThreadData *psOSThreadData; - PVRSRV_ERROR eError; - - psOSThreadData = OSAllocZMem(sizeof(*psOSThreadData)); - PVR_LOG_GOTO_IF_NOMEM(psOSThreadData, eError, fail_alloc); - - psOSThreadData->pfnThread = pfnThread; - psOSThreadData->hData = hData; - psOSThreadData->kthread = kthread_run(OSThreadRun, psOSThreadData, "%s", pszThreadName); - - if (IS_ERR(psOSThreadData->kthread)) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_kthread; - } - - if (bIsSupportingThread) - { - psOSThreadData->pszThreadName = pszThreadName; - psOSThreadData->pfnDebugDumpCB = pfnDebugDumpCB; - psOSThreadData->bIsThreadRunning = IMG_TRUE; - psOSThreadData->bIsSupportingThread = IMG_TRUE; - - _ThreadListAddEntry(psOSThreadData); - } - - if (eThreadPriority != OS_THREAD_NOSET_PRIORITY && - eThreadPriority < OS_THREAD_LAST_PRIORITY) - { - set_user_nice(psOSThreadData->kthread, - ai32OSPriorityValues[eThreadPriority]); - } - - *phThread = psOSThreadData; - - return PVRSRV_OK; - -fail_kthread: - OSFreeMem(psOSThreadData); -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR OSThreadDestroy(IMG_HANDLE hThread) -{ - OSThreadData *psOSThreadData = hThread; - int ret; - - /* Let the thread know we are ready for it to end and wait for it. */ - ret = kthread_stop(psOSThreadData->kthread); - if (0 != ret) - { - PVR_DPF((PVR_DBG_WARNING, "kthread_stop failed(%d)", ret)); - return PVRSRV_ERROR_RETRY; - } - - if (psOSThreadData->bIsSupportingThread) - { - _ThreadListRemoveEntry(psOSThreadData); - } - - OSFreeMem(psOSThreadData); - - return PVRSRV_OK; -} - -void OSPanic(void) -{ - BUG(); - -#if defined(__KLOCWORK__) - /* Klocwork does not understand that BUG is terminal... */ - abort(); -#endif -} - -void * -OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, - size_t ui32Bytes, - PVRSRV_MEMALLOCFLAGS_T uiMappingFlags) -{ - void __iomem *pvLinAddr; - - if (uiMappingFlags & ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK)) - { - PVR_ASSERT(!"Found non-cpu cache mode flag when mapping to the cpu"); - return NULL; - } - - if (! PVRSRV_VZ_MODE_IS(NATIVE)) - { - /* - This is required to support DMA physheaps for GPU virtualization. - Unfortunately, if a region of kernel managed memory is turned into - a DMA buffer, conflicting mappings can come about easily on Linux - as the original memory is mapped by the kernel as normal cached - memory whilst DMA buffers are mapped mostly as uncached device or - cache-coherent device memory. In both cases the system will have - two conflicting mappings for the same memory region and will have - "undefined behaviour" for most processors notably ARMv6 onwards - and some x86 micro-architectures. As a result, perform ioremapping - manually for DMA physheap allocations by translating from CPU/VA - to BUS/PA thereby preventing the creation of conflicting mappings. - */ - pvLinAddr = (void __iomem *) SysDmaDevPAddrToCpuVAddr(BasePAddr.uiAddr, ui32Bytes); - if (pvLinAddr != NULL) - { - return (void __force *) pvLinAddr; - } - } - - switch (uiMappingFlags) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - pvLinAddr = (void __iomem *)ioremap(BasePAddr.uiAddr, ui32Bytes); - break; - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: -#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) - pvLinAddr = (void __iomem *)ioremap_wc(BasePAddr.uiAddr, ui32Bytes); -#else - pvLinAddr = (void __iomem *)ioremap(BasePAddr.uiAddr, ui32Bytes); -#endif - break; - case PVRSRV_MEMALLOCFLAG_CPU_CACHED: -#if defined(CONFIG_X86) || defined(CONFIG_ARM) - pvLinAddr = (void __iomem *)ioremap_cache(BasePAddr.uiAddr, ui32Bytes); -#else - pvLinAddr = (void __iomem *)ioremap(BasePAddr.uiAddr, ui32Bytes); -#endif - break; - case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT: - case PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT: - PVR_ASSERT(!"Unexpected cpu cache mode"); - pvLinAddr = NULL; - break; - default: - PVR_ASSERT(!"Unsupported cpu cache mode"); - pvLinAddr = NULL; - break; - } - - return (void __force *) pvLinAddr; -} - - -IMG_BOOL -OSUnMapPhysToLin(void *pvLinAddr, size_t ui32Bytes) -{ - PVR_UNREFERENCED_PARAMETER(ui32Bytes); - - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - if (SysDmaCpuVAddrToDevPAddr(pvLinAddr)) - { - return IMG_TRUE; - } - } - - iounmap((void __iomem *) pvLinAddr); - - return IMG_TRUE; -} - -#define OS_MAX_TIMERS 8 - -/* Timer callback structure used by OSAddTimer */ -typedef struct TIMER_CALLBACK_DATA_TAG -{ - IMG_BOOL bInUse; - PFN_TIMER_FUNC pfnTimerFunc; - void *pvData; - struct timer_list sTimer; - IMG_UINT32 ui32Delay; - IMG_BOOL bActive; - struct work_struct sWork; -}TIMER_CALLBACK_DATA; - -static struct workqueue_struct *psTimerWorkQueue; - -static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS]; - -static DEFINE_MUTEX(sTimerStructLock); - -static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData) -{ - if (!psTimerCBData->bActive) - return; - - /* call timer callback */ - psTimerCBData->pfnTimerFunc(psTimerCBData->pvData); - - /* reset timer */ - mod_timer(&psTimerCBData->sTimer, psTimerCBData->sTimer.expires + psTimerCBData->ui32Delay); -} - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) -/*************************************************************************/ /*! -@Function OSTimerCallbackWrapper -@Description OS specific timer callback wrapper function -@Input psTimer Timer list structure -*/ /**************************************************************************/ -static void OSTimerCallbackWrapper(struct timer_list *psTimer) -{ - TIMER_CALLBACK_DATA *psTimerCBData = from_timer(psTimerCBData, psTimer, sTimer); -#else -/*************************************************************************/ /*! -@Function OSTimerCallbackWrapper -@Description OS specific timer callback wrapper function -@Input uData Timer callback data -*/ /**************************************************************************/ -static void OSTimerCallbackWrapper(uintptr_t uData) -{ - TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)uData; -#endif - int res; - - res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork); - if (res == 0) - { - PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued")); - } -} - - -static void OSTimerWorkQueueCallBack(struct work_struct *psWork) -{ - TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork); - - OSTimerCallbackBody(psTimerCBData); -} - -IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32MsTimeout) -{ - TIMER_CALLBACK_DATA *psTimerCBData; - IMG_UINT32 ui32i; - - /* check callback */ - if (!pfnTimerFunc) - { - PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback")); - return NULL; - } - - /* Allocate timer callback data structure */ - mutex_lock(&sTimerStructLock); - for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++) - { - psTimerCBData = &sTimers[ui32i]; - if (!psTimerCBData->bInUse) - { - psTimerCBData->bInUse = IMG_TRUE; - break; - } - } - mutex_unlock(&sTimerStructLock); - if (ui32i >= OS_MAX_TIMERS) - { - PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use")); - return NULL; - } - - psTimerCBData->pfnTimerFunc = pfnTimerFunc; - psTimerCBData->pvData = pvData; - psTimerCBData->bActive = IMG_FALSE; - - /* - HZ = ticks per second - ui32MsTimeout = required ms delay - ticks = (Hz * ui32MsTimeout) / 1000 - */ - psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000) - ? 1 - : ((HZ * ui32MsTimeout) / 1000); - - /* initialise object */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) - timer_setup(&psTimerCBData->sTimer, OSTimerCallbackWrapper, 0); -#else - init_timer(&psTimerCBData->sTimer); - - /* setup timer object */ - psTimerCBData->sTimer.function = (void *)OSTimerCallbackWrapper; - psTimerCBData->sTimer.data = (uintptr_t)psTimerCBData; -#endif - - return (IMG_HANDLE)(uintptr_t)(ui32i + 1); -} - - -static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer) -{ - IMG_UINT32 ui32i = (IMG_UINT32)((uintptr_t)hTimer) - 1; - - PVR_ASSERT(ui32i < OS_MAX_TIMERS); - - return &sTimers[ui32i]; -} - -PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer) -{ - TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); - - PVR_ASSERT(psTimerCBData->bInUse); - PVR_ASSERT(!psTimerCBData->bActive); - - /* free timer callback data struct */ - psTimerCBData->bInUse = IMG_FALSE; - - return PVRSRV_OK; -} - -PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer) -{ - TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); - - PVR_ASSERT(psTimerCBData->bInUse); - PVR_ASSERT(!psTimerCBData->bActive); - - /* Start timer arming */ - psTimerCBData->bActive = IMG_TRUE; - - /* set the expire time */ - psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies; - - /* Add the timer to the list */ - add_timer(&psTimerCBData->sTimer); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer) -{ - TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); - - PVR_ASSERT(psTimerCBData->bInUse); - PVR_ASSERT(psTimerCBData->bActive); - - /* Stop timer from arming */ - psTimerCBData->bActive = IMG_FALSE; - smp_mb(); - - flush_workqueue(psTimerWorkQueue); - - /* remove timer */ - del_timer_sync(&psTimerCBData->sTimer); - - /* - * This second flush is to catch the case where the timer ran - * before we managed to delete it, in which case, it will have - * queued more work for the workqueue. Since the bActive flag - * has been cleared, this second flush won't result in the - * timer being rearmed. - */ - flush_workqueue(psTimerWorkQueue); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, IMG_HANDLE *hEventObject) -{ - PVR_UNREFERENCED_PARAMETER(pszName); - - PVR_LOG_RETURN_IF_INVALID_PARAM(hEventObject, "hEventObject"); - - return LinuxEventObjectListCreate(hEventObject); -} - - -PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(hEventObject, "hEventObject"); - - return LinuxEventObjectListDestroy(hEventObject); -} - -#define _FREEZABLE IMG_TRUE -#define _NON_FREEZABLE IMG_FALSE - -/* - * EventObjectWaitTimeout() - */ -static PVRSRV_ERROR EventObjectWaitTimeout(IMG_HANDLE hOSEventKM, - IMG_UINT64 uiTimeoutus) -{ - PVRSRV_ERROR eError; - - if (hOSEventKM && uiTimeoutus > 0) - { - eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutus, _NON_FREEZABLE); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: invalid arguments %p, %lld", hOSEventKM, uiTimeoutus)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - - return eError; -} - -PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus) -{ - return EventObjectWaitTimeout(hOSEventKM, uiTimeoutus); -} - -PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM) -{ - return OSEventObjectWaitTimeout(hOSEventKM, EVENT_OBJECT_TIMEOUT_US); -} - -PVRSRV_ERROR OSEventObjectWaitKernel(IMG_HANDLE hOSEventKM, - IMG_UINT64 uiTimeoutus) -{ - PVRSRV_ERROR eError; - -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - if (hOSEventKM) - { - if (uiTimeoutus > 0) - eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutus, - _FREEZABLE); - else - eError = LinuxEventObjectWaitUntilSignalled(hOSEventKM); - } -#else /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - if (hOSEventKM && uiTimeoutus > 0) - { - eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutus, - _FREEZABLE); - } -#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - else - { - PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWaitKernel: invalid arguments %p", - hOSEventKM)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - - return eError; -} - -void OSEventObjectDumpDebugInfo(IMG_HANDLE hOSEventKM) -{ - LinuxEventObjectDumpDebugInfo(hOSEventKM); -} - -PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject, IMG_HANDLE *phOSEvent) -{ - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(phOSEvent, "phOSEvent"); - PVR_LOG_GOTO_IF_INVALID_PARAM(hEventObject, eError, error); - - eError = LinuxEventObjectAdd(hEventObject, phOSEvent); - PVR_LOG_GOTO_IF_ERROR(eError, "LinuxEventObjectAdd", error); - - return PVRSRV_OK; - -error: - *phOSEvent = NULL; - return eError; -} - -PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(hOSEventKM, "hOSEventKM"); - - return LinuxEventObjectDelete(hOSEventKM); -} - -PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(hEventObject, "hEventObject"); - - return LinuxEventObjectSignal(hEventObject); -} - -PVRSRV_ERROR OSCopyToUser(void *pvProcess, - void __user *pvDest, - const void *pvSrc, - size_t ui32Bytes) -{ - PVR_UNREFERENCED_PARAMETER(pvProcess); - - if (pvr_copy_to_user(pvDest, pvSrc, ui32Bytes)==0) - return PVRSRV_OK; - else - return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY; -} - -PVRSRV_ERROR OSCopyFromUser(void *pvProcess, - void *pvDest, - const void __user *pvSrc, - size_t ui32Bytes) -{ - PVR_UNREFERENCED_PARAMETER(pvProcess); - - if (likely(pvr_copy_from_user(pvDest, pvSrc, ui32Bytes)==0)) - return PVRSRV_OK; - else - return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY; -} - -IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder) -{ - *pui32Remainder = do_div(ui64Divident, ui32Divisor); - - return ui64Divident; -} - -IMG_UINT32 OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder) -{ - *pui32Remainder = do_div(ui64Divident, ui32Divisor); - - return (IMG_UINT32) ui64Divident; -} - -/* One time osfunc initialisation */ -PVRSRV_ERROR PVROSFuncInit(void) -{ - { - PVR_ASSERT(!psTimerWorkQueue); - - psTimerWorkQueue = create_freezable_workqueue("pvr_timer"); - if (psTimerWorkQueue == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", - __func__)); - return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD; - } - } - - { - IMG_UINT32 ui32i; - - for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++) - { - TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i]; - - INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack); - } - } - return PVRSRV_OK; -} - -/* - * Osfunc deinitialisation. - * Note that PVROSFuncInit may not have been called - */ -void PVROSFuncDeInit(void) -{ - if (psTimerWorkQueue != NULL) - { - destroy_workqueue(psTimerWorkQueue); - psTimerWorkQueue = NULL; - } -} - -void OSDumpStack(void) -{ - dump_stack(); -} - -PVRSRV_ERROR OSChangeSparseMemCPUAddrMap(void **psPageArray, - IMG_UINT64 sCpuVAddrBase, - IMG_CPU_PHYADDR sCpuPAHeapBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_BOOL bIsLMA) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - pfn_t sPFN; -#else - IMG_UINT64 uiPFN; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ - - PVRSRV_ERROR eError; - - struct mm_struct *psMM = current->mm; - struct vm_area_struct *psVMA = NULL; - struct address_space *psMapping = NULL; - struct page *psPage = NULL; - - IMG_UINT64 uiCPUVirtAddr = 0; - IMG_UINT32 ui32Loop = 0; - IMG_UINT32 ui32PageSize = OSGetPageSize(); - IMG_BOOL bMixedMap = IMG_FALSE; - - /* - * Acquire the lock before manipulating the VMA - * In this case only mmap_write_lock would suffice as the pages associated with this VMA - * are never meant to be swapped out. - * - * In the future, in case the pages are marked as swapped, page_table_lock needs - * to be acquired in conjunction with this to disable page swapping. - */ - /* Acquire the memory sem */ - mmap_write_lock(psMM); - - /* Find the Virtual Memory Area associated with the user base address */ - psVMA = find_vma(psMM, (uintptr_t)sCpuVAddrBase); - if (NULL == psVMA) - { - eError = PVRSRV_ERROR_PMR_NO_CPU_MAP_FOUND; - goto eFailed; - } - - - psMapping = psVMA->vm_file->f_mapping; - - /* Set the page offset to the correct value as this is disturbed in MMAP_PMR func */ - psVMA->vm_pgoff = (psVMA->vm_start >> PAGE_SHIFT); - - /* Delete the entries for the pages that got freed */ - if (ui32FreePageCount && (pai32FreeIndices != NULL)) - { - for (ui32Loop = 0; ui32Loop < ui32FreePageCount; ui32Loop++) - { - uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase + (pai32FreeIndices[ui32Loop] * ui32PageSize)); - - unmap_mapping_range(psMapping, uiCPUVirtAddr, ui32PageSize, 1); - -#ifndef PVRSRV_UNMAP_ON_SPARSE_CHANGE - /* - * Still need to map pages in case remap flag is set. - * That is not done until the remap case succeeds - */ -#endif - } - eError = PVRSRV_OK; - } - - if ((psVMA->vm_flags & VM_MIXEDMAP) || bIsLMA) - { - vm_flags_set( psVMA, VM_MIXEDMAP); - bMixedMap = IMG_TRUE; - } - else - { - if (ui32AllocPageCount && (NULL != pai32AllocIndices)) - { - for (ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++) - { - - psPage = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]]; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN = page_to_pfn_t(psPage); - - if (!pfn_t_valid(sPFN) || page_count(pfn_t_to_page(sPFN)) == 0) -#else - uiPFN = page_to_pfn(psPage); - - if (!pfn_valid(uiPFN) || (page_count(pfn_to_page(uiPFN)) == 0)) -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ - { - bMixedMap = IMG_TRUE; - vm_flags_set( psVMA, VM_MIXEDMAP); - break; - } - } - } - } - - /* Map the pages that got allocated */ - if (ui32AllocPageCount && (NULL != pai32AllocIndices)) - { - for (ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++) - { - int err; - - uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase + (pai32AllocIndices[ui32Loop] * ui32PageSize)); - unmap_mapping_range(psMapping, uiCPUVirtAddr, ui32PageSize, 1); - - if (bIsLMA) - { - phys_addr_t uiAddr = sCpuPAHeapBase.uiAddr + - ((IMG_DEV_PHYADDR *)psPageArray)[pai32AllocIndices[ui32Loop]].uiAddr; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN = phys_to_pfn_t(uiAddr, 0); - psPage = pfn_t_to_page(sPFN); -#else - uiPFN = uiAddr >> PAGE_SHIFT; - psPage = pfn_to_page(uiPFN); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ - } - else - { - psPage = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]]; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN = page_to_pfn_t(psPage); -#else - uiPFN = page_to_pfn(psPage); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ - } - - if (bMixedMap) - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - vm_fault_t vmf; - - vmf = vmf_insert_mixed(psVMA, uiCPUVirtAddr, sPFN); - if (vmf & VM_FAULT_ERROR) - { - err = vm_fault_to_errno(vmf, 0); - } - else - { - err = 0; - } -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - err = vm_insert_mixed(psVMA, uiCPUVirtAddr, sPFN); -#else - err = vm_insert_mixed(psVMA, uiCPUVirtAddr, uiPFN); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) */ - } - else - { - err = vm_insert_page(psVMA, uiCPUVirtAddr, psPage); - } - - if (err) - { - PVR_DPF((PVR_DBG_MESSAGE, "Remap failure error code: %d", err)); - eError = PVRSRV_ERROR_PMR_CPU_PAGE_MAP_FAILED; - goto eFailed; - } - } - } - - eError = PVRSRV_OK; -eFailed: - mmap_write_unlock(psMM); - - return eError; -} - -/*************************************************************************/ /*! -@Function OSDebugSignalPID -@Description Sends a SIGTRAP signal to a specific PID in user mode for - debugging purposes. The user mode process can register a handler - against this signal. - This is necessary to support the Rogue debugger. If the Rogue - debugger is not used then this function may be implemented as - a stub. -@Input ui32PID The PID for the signal. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSDebugSignalPID(IMG_UINT32 ui32PID) -{ - int err; - struct pid *psPID; - - psPID = find_vpid(ui32PID); - if (psPID == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get PID struct.", __func__)); - return PVRSRV_ERROR_NOT_FOUND; - } - - err = kill_pid(psPID, SIGTRAP, 0); - if (err != 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Signal Failure %d", __func__, err)); - return PVRSRV_ERROR_SIGNAL_FAILED; - } - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function OSIsKernelThread -@Description This API determines if the current running thread is a kernel - thread (i.e. one not associated with any userland process, - typically an MISR handler.) -@Return IMG_TRUE if it is a kernel thread, otherwise IMG_FALSE. -*/ /**************************************************************************/ -IMG_BOOL OSIsKernelThread(void) -{ - /* - * Kernel threads have a NULL memory descriptor. - * - * See https://www.kernel.org/doc/Documentation/vm/active_mm.txt - */ - return current->mm == NULL; -} - -void OSDumpVersionInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVR_DUMPDEBUG_LOG("OS kernel info: %s %s %s %s", - utsname()->sysname, - utsname()->release, - utsname()->version, - utsname()->machine); -} -#if defined(SUPPORT_DMA_TRANSFER) - -typedef struct _OS_CLEANUP_DATA_ -{ - IMG_BOOL bSucceed; - IMG_BOOL bAdvanceTimeline; - IMG_UINT uiRefCount; - IMG_UINT uiNumDMA; - IMG_UINT uiCount; - - struct dma_async_tx_descriptor** ppsDescriptors; - - - PVRSRV_DEVICE_NODE *psDevNode; - PFN_SERVER_CLEANUP pfnServerCleanup; - void* pvServerCleanupData; - - enum dma_transfer_direction eDirection; - struct sg_table **ppsSg; - struct page ***pages; - IMG_UINT32* puiNumPages; - spinlock_t spinlock; - - struct completion start_cleanup; - struct completion *sync_completion; - - /* Sparse PMR transfer information */ - IMG_BOOL *pbIsSparse; - IMG_UINT *uiNumValidPages; - struct sg_table ***ppsSgSparse; - struct dma_async_tx_descriptor*** ppsDescriptorsSparse; - -} OS_CLEANUP_DATA; - -static int cleanup_thread(void *pvData) -{ - IMG_UINT32 i, j; - struct completion *sync_completion = NULL; - OS_CLEANUP_DATA *psOSCleanup = (OS_CLEANUP_DATA*)pvData; - IMG_BOOL bSucceed = psOSCleanup->bSucceed; - - sync_completion = psOSCleanup->sync_completion; - -#if defined(DMA_VERBOSE) - PVR_DPF((PVR_DBG_ERROR, "Cleanup thread waiting (%p) on completion", pvData)); -#endif - - wait_for_completion(&psOSCleanup->start_cleanup); - -#if defined(DMA_VERBOSE) - PVR_DPF((PVR_DBG_ERROR, "Cleanup thread notified (%p)", pvData)); -#endif - /* Free resources */ - for (i=0; iuiCount; i++) - { - if (!psOSCleanup->pbIsSparse[i]) - { - dma_sync_sg_for_cpu(psOSCleanup->psDevNode->psDevConfig->pvOSDevice, - psOSCleanup->ppsSg[i]->sgl, - psOSCleanup->ppsSg[i]->nents, - psOSCleanup->eDirection); - - dma_unmap_sg(psOSCleanup->psDevNode->psDevConfig->pvOSDevice, - psOSCleanup->ppsSg[i]->sgl, - psOSCleanup->ppsSg[i]->nents, - psOSCleanup->eDirection); - - sg_free_table(psOSCleanup->ppsSg[i]); - - OSFreeMem(psOSCleanup->ppsSg[i]); - - /* Unpin pages */ - for (j=0; jpuiNumPages[i]; j++) - { - if (psOSCleanup->eDirection == DMA_DEV_TO_MEM) - { - set_page_dirty_lock(psOSCleanup->pages[i][j]); - } - put_page(psOSCleanup->pages[i][j]); - } - } - else - { - for (j = 0; j < psOSCleanup->puiNumPages[i]; j++) - { - if (psOSCleanup->ppsSgSparse[i][j]) { - dma_sync_sg_for_cpu(psOSCleanup->psDevNode->psDevConfig->pvOSDevice, - psOSCleanup->ppsSgSparse[i][j]->sgl, - psOSCleanup->ppsSgSparse[i][j]->nents, - psOSCleanup->eDirection); - - - dma_unmap_sg(psOSCleanup->psDevNode->psDevConfig->pvOSDevice, - psOSCleanup->ppsSgSparse[i][j]->sgl, - psOSCleanup->ppsSgSparse[i][j]->nents, - psOSCleanup->eDirection); - - sg_free_table(psOSCleanup->ppsSgSparse[i][j]); - - OSFreeMem(psOSCleanup->ppsSgSparse[i][j]); - - } - } - - OSFreeMem(psOSCleanup->ppsSgSparse[i]); - OSFreeMem(psOSCleanup->ppsDescriptorsSparse[i]); - - /* Unpin pages */ - for (j=0; jpuiNumPages[i]*2; j++) - { - /* - * Some pages might've been pinned twice - * Others may have not been pinned at all - */ - if (psOSCleanup->pages[i][j]) - { - if (psOSCleanup->eDirection == DMA_DEV_TO_MEM) - { - set_page_dirty_lock(psOSCleanup->pages[i][j]); - } - put_page(psOSCleanup->pages[i][j]); - } - } - } - - OSFreeMem(psOSCleanup->pages[i]); - } - - psOSCleanup->pfnServerCleanup(psOSCleanup->pvServerCleanupData, - psOSCleanup->bAdvanceTimeline); - - OSFreeMem(psOSCleanup->ppsSg); - OSFreeMem(psOSCleanup->pages); - OSFreeMem(psOSCleanup->puiNumPages); - OSFreeMem(psOSCleanup->ppsSgSparse); - OSFreeMem(psOSCleanup->ppsDescriptorsSparse); - OSFreeMem(psOSCleanup->ppsDescriptors); - OSFreeMem(psOSCleanup->pbIsSparse); - OSFreeMem(psOSCleanup->uiNumValidPages); - OSFreeMem(psOSCleanup); - - if (sync_completion && bSucceed) - { - complete(sync_completion); - } - - do_exit(0); - return 0; -} - -static void dma_callback(void *pvOSCleanup) -{ - OS_CLEANUP_DATA *psOSCleanup = (OS_CLEANUP_DATA*)pvOSCleanup; - unsigned long flags; - -#if defined(DMA_VERBOSE) - PVR_DPF((PVR_DBG_ERROR, "dma_callback (%p) refcount decreased to %d", psOSCleanup, psOSCleanup->uiRefCount - 1)); -#endif - spin_lock_irqsave(&psOSCleanup->spinlock, flags); - - psOSCleanup->uiRefCount--; - - if (psOSCleanup->uiRefCount==0) - { - /* Notify the cleanup thread */ - spin_unlock_irqrestore(&psOSCleanup->spinlock, flags); - complete(&psOSCleanup->start_cleanup); - return; - } - - spin_unlock_irqrestore(&psOSCleanup->spinlock, flags); -} - -#if defined(SUPPORT_VALIDATION) && defined(PVRSRV_DEBUG_DMA) -static void -DMADumpPhysicalAddresses(struct page **ppsHostMemPages, - IMG_UINT32 uiNumPages, - IMG_DMA_ADDR *sDmaAddr, - IMG_UINT64 ui64Offset) -{ - IMG_CPU_PHYADDR sPagePhysAddr; - IMG_UINT32 uiIdx; - - PVR_DPF((PVR_DBG_MESSAGE, "DMA Transfer Address Dump")); - PVR_DPF((PVR_DBG_MESSAGE, "Hostmem phys addresses:")); - - for (uiIdx = 0; uiIdx < uiNumPages; uiIdx++) - { - sPagePhysAddr.uiAddr = page_to_phys(ppsHostMemPages[uiIdx]); - if (uiIdx == 0) - { - sPagePhysAddr.uiAddr += ui64Offset; - PVR_DPF((PVR_DBG_MESSAGE, "\tHost mem start at 0x%llX", sPagePhysAddr.uiAddr)); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "\tHost Mem Page %d at 0x%llX", uiIdx, - sPagePhysAddr.uiAddr)); - } - } - PVR_DPF((PVR_DBG_MESSAGE, "Devmem CPU phys address: 0x%llX", - sDmaAddr->uiAddr)); -} -#endif - -PVRSRV_ERROR OSDmaSubmitTransfer(PVRSRV_DEVICE_NODE *psDevNode, void *pvOSData, - void *pvChan, IMG_BOOL bSynchronous) -{ - OS_CLEANUP_DATA *psOSCleanup = (OS_CLEANUP_DATA*)pvOSData; - struct completion* sync_completion = NULL; - - psOSCleanup->bSucceed = IMG_TRUE; - psOSCleanup->bAdvanceTimeline = IMG_TRUE; - - if (bSynchronous) - { - sync_completion = OSAllocZMem(sizeof(struct completion)); - init_completion(sync_completion); - } - - PVR_UNREFERENCED_PARAMETER(psDevNode); - /* Wait only on number of ops scheduled. This might be different to NumDMAs - in certain error conditions */ - psOSCleanup->uiRefCount = psOSCleanup->uiCount; - psOSCleanup->sync_completion = sync_completion; - - { - IMG_UINT32 i,j; - for (i=0; iuiCount; i++) - { - if (psOSCleanup->pbIsSparse[i]) - { - for (j=0; jpuiNumPages[i]; j++) - { - if (psOSCleanup->ppsDescriptorsSparse[i][j]) - dmaengine_submit(psOSCleanup->ppsDescriptorsSparse[i][j]); - } - } - else - { - dmaengine_submit(psOSCleanup->ppsDescriptors[i]); - } - } - } - - dma_async_issue_pending(pvChan); - - if (bSynchronous) - { - wait_for_completion(sync_completion); - OSFreeMem(sync_completion); - } - - return PVRSRV_OK; -} - -void OSDmaForceCleanup(PVRSRV_DEVICE_NODE *psDevNode, void *pvChan, - void *pvOSData, void *pvServerCleanupParam, - PFN_SERVER_CLEANUP pfnServerCleanup) -{ - OS_CLEANUP_DATA *psOSCleanup = (OS_CLEANUP_DATA *)pvOSData; - IMG_UINT ui32Retries; - - PVR_UNREFERENCED_PARAMETER(psDevNode); - - psOSCleanup->bSucceed = IMG_FALSE; - psOSCleanup->bAdvanceTimeline = IMG_TRUE; - - /* Need to wait for outstanding DMA Engine ops before advancing the - user-supplied timeline in case of error. dmaengine_terminate_sync - cannot be called from within atomic context, so cannot invoke it - from inside the cleanup kernel thread. */ - for (ui32Retries = 0; ui32Retries < DMA_ERROR_SYNC_RETRIES; ui32Retries++) - { - if (dmaengine_terminate_sync(pvChan) == 0) - { - break; - } - } - if (ui32Retries == DMA_ERROR_SYNC_RETRIES) - { - /* We cannot guarantee all outstanding DMAs were terminated - * so we let the UM fence time out as a fallback mechanism */ - psOSCleanup->bAdvanceTimeline = IMG_FALSE; - } - - if (psOSCleanup->uiCount > 0) - { - complete(&psOSCleanup->start_cleanup); - } - else - { - /* Cleanup kthread never run, need to manually wind down */ - pfnServerCleanup(pvServerCleanupParam, psOSCleanup->bAdvanceTimeline); - - OSFreeMem(psOSCleanup->ppsSg); - OSFreeMem(psOSCleanup->pages); - OSFreeMem(psOSCleanup->puiNumPages); - OSFreeMem(psOSCleanup->ppsSgSparse); - OSFreeMem(psOSCleanup->pbIsSparse); - OSFreeMem(psOSCleanup->uiNumValidPages); - OSFreeMem(psOSCleanup->ppsDescriptors); - OSFreeMem(psOSCleanup->ppsDescriptorsSparse); - - OSFreeMem(psOSCleanup); - } -} - -PVRSRV_ERROR OSDmaAllocData(PVRSRV_DEVICE_NODE *psDevNode, IMG_UINT32 uiNumDMA, void **pvOutData) -{ - PVRSRV_ERROR eError; - OS_CLEANUP_DATA *psOSCleanup = OSAllocZMem(sizeof(OS_CLEANUP_DATA)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup, eError, e0); - - psOSCleanup->uiNumDMA = uiNumDMA; - psOSCleanup->psDevNode = psDevNode; - - spin_lock_init(&psOSCleanup->spinlock); - - init_completion(&psOSCleanup->start_cleanup); - - psOSCleanup->ppsDescriptors = OSAllocZMem(uiNumDMA * sizeof(struct dma_async_tx_descriptor*)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->ppsDescriptors, eError, e0); - - psOSCleanup->ppsDescriptorsSparse = OSAllocZMem(uiNumDMA * sizeof(struct dma_async_tx_descriptor*)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->ppsDescriptorsSparse, eError, e11); - - psOSCleanup->ppsSg = OSAllocZMem(uiNumDMA * sizeof(struct sg_table*)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->ppsSg, eError, e1); - - psOSCleanup->ppsSgSparse = OSAllocZMem(uiNumDMA * sizeof(struct sg_table*)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->ppsSgSparse, eError, e12); - - psOSCleanup->pbIsSparse = OSAllocZMem(uiNumDMA * sizeof(IMG_BOOL)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->pbIsSparse, eError, e13); - - psOSCleanup->uiNumValidPages = OSAllocZMem(uiNumDMA * sizeof(IMG_UINT)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->uiNumValidPages, eError, e14); - - psOSCleanup->pages = OSAllocZMem(uiNumDMA * sizeof(struct page **)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->pages, eError, e2); - - psOSCleanup->puiNumPages = OSAllocZMem(uiNumDMA * sizeof(IMG_UINT32)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanup->puiNumPages, eError, e3); - - *pvOutData = psOSCleanup; - - return PVRSRV_OK; - -e3: - OSFreeMem(psOSCleanup->pages); -e2: - OSFreeMem(psOSCleanup->uiNumValidPages); -e14: - OSFreeMem(psOSCleanup->pbIsSparse); -e13: - OSFreeMem(psOSCleanup->ppsSgSparse); -e12: - OSFreeMem(psOSCleanup->ppsSg); -e1: - OSFreeMem(psOSCleanup->ppsDescriptorsSparse); -e11: - OSFreeMem(psOSCleanup->ppsDescriptors); -e0: - OSFreeMem(psOSCleanup); - return eError; -} - -/*************************************************************************/ /*! -@Function OSDmaTransfer -@Description This API is used to ask OS to perform a DMA transfer operation -@Return -*/ /**************************************************************************/ -PVRSRV_ERROR OSDmaPrepareTransfer(PVRSRV_DEVICE_NODE *psDevNode, - void* pvChan, - IMG_DMA_ADDR* psDmaAddr, IMG_UINT64* puiAddress, - IMG_UINT64 uiSize, IMG_BOOL bMemToDev, - void* pvOSData, - void* pvServerCleanupParam, PFN_SERVER_CLEANUP pfnServerCleanup, IMG_BOOL bFirst) -{ - - IMG_INT iRet; - PVRSRV_ERROR eError; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - OS_CLEANUP_DATA* psOSCleanupData = pvOSData; - - struct dma_slave_config sConfig = {0}; - struct dma_async_tx_descriptor *psDesc; - - unsigned long offset = (unsigned long)puiAddress & ((1 << PAGE_SHIFT) - 1); - unsigned int num_pages = (uiSize + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - int num_pinned_pages = 0; - unsigned int gup_flags = 0; - - struct sg_table *psSg = OSAllocZMem(sizeof(struct sg_table)); - PVR_LOG_GOTO_IF_NOMEM(psSg, eError, e0); - - psOSCleanupData->pages[psOSCleanupData->uiCount] = OSAllocZMem(num_pages * sizeof(struct page *)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanupData->pages[psOSCleanupData->uiCount], eError, e1); - - gup_flags |= bMemToDev ? 0 : FOLL_WRITE; - - num_pinned_pages = get_user_pages_fast( - (unsigned long)puiAddress, - (int)num_pages, - gup_flags, - psOSCleanupData->pages[psOSCleanupData->uiCount]); - if (num_pinned_pages != num_pages) - { - PVR_DPF((PVR_DBG_ERROR, "get_user_pages_fast failed: (%d - %u)", num_pinned_pages, num_pages)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e2; - } - -#if defined(SUPPORT_VALIDATION) && defined(PVRSRV_DEBUG_DMA) - DMADumpPhysicalAddresses(psOSCleanupData->pages[psOSCleanupData->uiCount], - num_pages, psDmaAddr, offset); -#endif - - psOSCleanupData->puiNumPages[psOSCleanupData->uiCount] = num_pinned_pages; - - if (sg_alloc_table_from_pages(psSg, psOSCleanupData->pages[psOSCleanupData->uiCount], num_pages, offset, uiSize, GFP_KERNEL) != 0) - { - eError = PVRSRV_ERROR_BAD_MAPPING; - PVR_DPF((PVR_DBG_ERROR, "sg_alloc_table_from_pages failed")); - goto e3; - } - - if (bMemToDev) - { - sConfig.direction = DMA_MEM_TO_DEV; - sConfig.src_addr = 0; - sConfig.dst_addr = psDmaAddr->uiAddr; - } - else - { - sConfig.direction = DMA_DEV_TO_MEM; - sConfig.src_addr = psDmaAddr->uiAddr; - sConfig.dst_addr = 0; - } - dmaengine_slave_config(pvChan, &sConfig); - - iRet = dma_map_sg(psDevConfig->pvOSDevice, psSg->sgl, psSg->nents, sConfig.direction); - if (!iRet) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error mapping SG list", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e4; - } - - dma_sync_sg_for_device(psDevConfig->pvOSDevice, psSg->sgl,(unsigned int)iRet, sConfig.direction); - - psDesc = dmaengine_prep_slave_sg(pvChan, psSg->sgl, (unsigned int)iRet, sConfig.direction, 0); - if (!psDesc) - { - PVR_DPF((PVR_DBG_ERROR, "%s: dmaengine_prep_slave_sg failed", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e5; - } - - psOSCleanupData->eDirection = sConfig.direction; - psOSCleanupData->ppsSg[psOSCleanupData->uiCount] = psSg; - psOSCleanupData->pfnServerCleanup = pfnServerCleanup; - psOSCleanupData->pvServerCleanupData = pvServerCleanupParam; - - psDesc->callback_param = psOSCleanupData; - psDesc->callback = dma_callback; - - if (bFirst) - { - struct task_struct* t1; - t1 = kthread_run(cleanup_thread, psOSCleanupData, "dma-cleanup-thread"); - } - psOSCleanupData->ppsDescriptors[psOSCleanupData->uiCount] = psDesc; - - psOSCleanupData->uiCount++; - - return PVRSRV_OK; - -e5: - dma_unmap_sg(psDevConfig->pvOSDevice, psSg->sgl, psSg->nents, sConfig.direction); -e4: - sg_free_table(psSg); -e3: - { - IMG_UINT32 i; - /* Unpin pages */ - for (i=0; ipuiNumPages[psOSCleanupData->uiCount]; i++) - { - put_page(psOSCleanupData->pages[psOSCleanupData->uiCount][i]); - } - } -e2: - OSFreeMem(psOSCleanupData->pages[psOSCleanupData->uiCount]); -e1: - OSFreeMem(psSg); -e0: - return eError; -} - -static IMG_UINT32 -CalculateValidPages(IMG_BOOL *pbValid, - IMG_UINT32 ui32SizeInPages) -{ - IMG_UINT32 ui32nValid; - IMG_UINT32 ui32Idx; - - for (ui32Idx = 0, ui32nValid = 0; ui32Idx < ui32SizeInPages; ui32Idx++) - { - ui32nValid += pbValid[ui32Idx] ? 1 : 0; - } - - return ui32nValid; -} - -PVRSRV_ERROR OSDmaPrepareTransferSparse(PVRSRV_DEVICE_NODE *psDevNode, - void* pvChan, - IMG_DMA_ADDR* psDmaAddr, - IMG_BOOL *pbValid, - IMG_UINT64* puiAddress, - IMG_UINT64 uiSize, - IMG_UINT32 uiOffsetInFirstPMRPage, - IMG_UINT32 ui32SizeInPages, - IMG_BOOL bMemToDev, - void* pvOSData, - void* pvServerCleanupParam, - PFN_SERVER_CLEANUP pfnServerCleanup, - IMG_BOOL bFirst) -{ - - IMG_INT iRet; - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - OS_CLEANUP_DATA* psOSCleanupData = pvOSData; - IMG_UINT32 ui32PageSize = OSGetPageSize(); - void *pvNextAddress = puiAddress; - IMG_UINT32 ui32Idx; - IMG_INT32 i32Rwd; - - struct dma_slave_config sConfig = {0}; - struct dma_async_tx_descriptor *psDesc; - - unsigned long offset = (unsigned long)puiAddress & ((1 << PAGE_SHIFT) - 1); - unsigned int num_pages = (uiSize + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - unsigned int num_valid_pages = CalculateValidPages(pbValid, ui32SizeInPages); - unsigned int num_pinned_pages = 0; - unsigned int gup_flags = 0; - unsigned int valid_idx; - size_t transfer_size; - struct page ** next_pages; - struct sg_table *psSg; - - psOSCleanupData->uiNumValidPages[psOSCleanupData->uiCount] = num_valid_pages; - psOSCleanupData->pbIsSparse[psOSCleanupData->uiCount] = IMG_TRUE; - - /* - * If an SG transfer from virtual memory to card memory goes over a page boundary in - * main memory, it'll span two different pages - therefore, total number of pages to - * keep track of should be twice as many as for a simple transfer. This twice-as-big - * allocation is also necessary because the same virtual memory page might be present - * in more than one SG DMA transfer, because of differences in first-page offset between - * the sparse device PMR and the virtual memory buffer. - */ - psOSCleanupData->pages[psOSCleanupData->uiCount] = OSAllocZMem(2*num_valid_pages * sizeof(struct page *)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanupData->pages[psOSCleanupData->uiCount], eError, e0); - - psOSCleanupData->ppsSgSparse[psOSCleanupData->uiCount] = OSAllocZMem(num_valid_pages * sizeof(struct sg_table *)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanupData->ppsSgSparse[psOSCleanupData->uiCount], eError, e1); - - psOSCleanupData->ppsDescriptorsSparse[psOSCleanupData->uiCount] = OSAllocZMem(num_valid_pages * sizeof(struct dma_async_tx_descriptor *)); - PVR_LOG_GOTO_IF_NOMEM(psOSCleanupData->ppsDescriptorsSparse[psOSCleanupData->uiCount], eError, e11); - - gup_flags |= bMemToDev ? 0 : FOLL_WRITE; - - for (ui32Idx = 0, valid_idx = 0; ui32Idx < ui32SizeInPages; ui32Idx++) - { - if (valid_idx == num_valid_pages) - { - break; - } - if (!pbValid[ui32Idx]) - { - pvNextAddress += (ui32Idx == 0) ? ui32PageSize - uiOffsetInFirstPMRPage : ui32PageSize; - continue; - } - - /* Pick transfer size */ - if (ui32Idx == 0) - { - if (uiOffsetInFirstPMRPage + uiSize <= ui32PageSize) - { - PVR_ASSERT(num_valid_pages == 1); - transfer_size = uiSize; - } - else - { - transfer_size = ui32PageSize - uiOffsetInFirstPMRPage; - } - } - else - { - /* Last valid LMA page */ - if (valid_idx == num_valid_pages - 1) - { - transfer_size = ((uiOffsetInFirstPMRPage + uiSize - 1) % ui32PageSize) + 1; - } - else - { - transfer_size = ui32PageSize; - } - } - - if (((unsigned long long)pvNextAddress & (ui32PageSize - 1)) + transfer_size > ui32PageSize) - { - num_pages = 2; - } - else - { - num_pages = 1; - } - - next_pages = psOSCleanupData->pages[psOSCleanupData->uiCount] + (valid_idx * 2); - - num_pinned_pages = get_user_pages_fast( - (unsigned long)pvNextAddress, - (int)num_pages, - gup_flags, - next_pages); - if (num_pinned_pages != num_pages) - { - PVR_DPF((PVR_DBG_ERROR, "get_user_pages_fast for sparse failed: (%d - %u)", num_pinned_pages, num_pages)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e2; - } - -#if defined(SUPPORT_VALIDATION) && defined(PVRSRV_DEBUG_DMA) - DMADumpPhysicalAddresses(next_pages, num_pages, - &psDmaAddr[ui32Idx], - (unsigned long)pvNextAddress & (ui32PageSize - 1)); -#endif - - psSg = OSAllocZMem(sizeof(struct sg_table)); - PVR_LOG_GOTO_IF_NOMEM(psSg, eError, e3); - - if (sg_alloc_table_from_pages(psSg, next_pages, num_pages, - (unsigned long)pvNextAddress & (ui32PageSize - 1), - transfer_size, - GFP_KERNEL) != 0) - { - eError = PVRSRV_ERROR_BAD_MAPPING; - PVR_DPF((PVR_DBG_ERROR, "sg_alloc_table_from_pages failed")); - goto e4; - } - - pvNextAddress += transfer_size; - - if (bMemToDev) - { - sConfig.direction = DMA_MEM_TO_DEV; - sConfig.src_addr = 0; - sConfig.dst_addr = psDmaAddr[ui32Idx].uiAddr; - } - else - { - sConfig.direction = DMA_DEV_TO_MEM; - sConfig.src_addr = psDmaAddr[ui32Idx].uiAddr; - sConfig.dst_addr = 0; - } - dmaengine_slave_config(pvChan, &sConfig); - - iRet = dma_map_sg(psDevConfig->pvOSDevice, psSg->sgl, psSg->nents, sConfig.direction); - if (!iRet) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error mapping SG list", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e5; - } - dma_sync_sg_for_device(psDevConfig->pvOSDevice, psSg->sgl,(unsigned int)iRet, sConfig.direction); - - psDesc = dmaengine_prep_slave_sg(pvChan, psSg->sgl, (unsigned int)iRet, sConfig.direction, 0); - if (!psDesc) - { - PVR_DPF((PVR_DBG_ERROR, "%s: dmaengine_prep_slave_sg failed", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto e6; - } - - psOSCleanupData->ppsSgSparse[psOSCleanupData->uiCount][valid_idx] = psSg; - psOSCleanupData->ppsDescriptorsSparse[psOSCleanupData->uiCount][valid_idx] = psDesc; - psOSCleanupData->puiNumPages[psOSCleanupData->uiCount] = ++valid_idx; - - if (valid_idx == num_valid_pages) - { - psDesc->callback_param = psOSCleanupData; - psDesc->callback = dma_callback; - - if (bFirst) - { - struct task_struct* t1; - - psOSCleanupData->eDirection = sConfig.direction; - psOSCleanupData->pfnServerCleanup = pfnServerCleanup; - psOSCleanupData->pvServerCleanupData = pvServerCleanupParam; - - t1 = kthread_run(cleanup_thread, psOSCleanupData, "dma-cleanup-thread"); - } - - psOSCleanupData->uiCount++; - } - - } - - return PVRSRV_OK; - -e6: - dma_unmap_sg(psDevConfig->pvOSDevice, psSg->sgl, psSg->nents, sConfig.direction); -e5: - sg_free_table(psSg); -e4: - OSFreeMem(psSg); -e3: - /* Unpin last */ - put_page(psOSCleanupData->pages[psOSCleanupData->uiCount][valid_idx]); - if (psOSCleanupData->pages[psOSCleanupData->uiCount][valid_idx+1]) - { - put_page(psOSCleanupData->pages[psOSCleanupData->uiCount][valid_idx+1]); - } -e2: - /* rewind */ - for (i32Rwd=valid_idx-1; i32Rwd >= 0; i32Rwd--) - { - IMG_UINT32 i; - - psSg = psOSCleanupData->ppsSgSparse[psOSCleanupData->uiCount][i32Rwd]; - dma_unmap_sg(psDevConfig->pvOSDevice, psSg->sgl, psSg->nents, sConfig.direction); - sg_free_table(psSg); - - /* Unpin pages */ - for (i=0; i < psOSCleanupData->puiNumPages[psOSCleanupData->uiCount]*2; i++) - { - if (psOSCleanupData->pages[psOSCleanupData->uiCount][i]) - { - put_page(psOSCleanupData->pages[psOSCleanupData->uiCount][i]); - } - } - } - OSFreeMem(psOSCleanupData->ppsDescriptorsSparse[psOSCleanupData->uiCount]); -e11: - OSFreeMem(psOSCleanupData->ppsSgSparse[psOSCleanupData->uiCount]); -e1: - OSFreeMem(psOSCleanupData->pages[psOSCleanupData->uiCount]); -e0: - return eError; -} - -#endif /* SUPPORT_DMA_TRANSFER */ diff --git a/drivers/gpu/drm/img-rogue/1.17/osfunc.h b/drivers/gpu/drm/img-rogue/1.17/osfunc.h deleted file mode 100644 index 4226f77da8c69..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osfunc.h +++ /dev/null @@ -1,1696 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS functions header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS specific API definitions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#ifdef DEBUG_RELEASE_BUILD -#pragma optimize( "", off ) -#define DEBUG 1 -#endif - -#ifndef OSFUNC_H -/*! @cond Doxygen_Suppress */ -#define OSFUNC_H -/*! @endcond */ - -#if defined(__linux__) && defined(__KERNEL__) -#include "kernel_nospec.h" -#if !defined(NO_HARDWARE) -#include - -#endif -#endif - -#include - -#if defined(__QNXNTO__) -#include -#include -#endif - -#if defined(INTEGRITY_OS) -#include -#include -#endif - -#include "img_types.h" -#include "img_defs.h" -#include "device.h" -#include "pvrsrv_device.h" -#include "cache_ops.h" -#include "osfunc_common.h" -#if defined(SUPPORT_DMA_TRANSFER) -#include "dma_km.h" -#include "pmr.h" -#endif - -/****************************************************************************** - * Static defines - *****************************************************************************/ -/*! - * Returned by OSGetCurrentProcessID() and OSGetCurrentThreadID() if the OS - * is currently operating in the interrupt context. - */ -#define KERNEL_ID 0xffffffffL - -#if defined(__linux__) && defined(__KERNEL__) -#define OSConfineArrayIndexNoSpeculation(index, size) array_index_nospec((index), (size)) -#elif defined(__QNXNTO__) -#define OSConfineArrayIndexNoSpeculation(index, size) (index) -#define PVRSRV_MISSING_NO_SPEC_IMPL -#elif defined(INTEGRITY_OS) -#define OSConfineArrayIndexNoSpeculation(index, size) (index) -#define PVRSRV_MISSING_NO_SPEC_IMPL -#else -/*************************************************************************/ /*! -@Function OSConfineArrayIndexNoSpeculation -@Description This macro aims to avoid code exposure to Cache Timing - Side-Channel Mechanisms which rely on speculative code - execution (Variant 1). It does so by ensuring a value to be - used as an array index will be set to zero if outside of the - bounds of the array, meaning any speculative execution of code - which uses this suitably adjusted index value will not then - attempt to load data from memory outside of the array bounds. - Code calling this macro must still first verify that the - original unmodified index value is within the bounds of the - array, and should then only use the modified value returned - by this function when accessing the array itself. - NB. If no OS-specific implementation of this macro is - defined, the original index is returned unmodified and no - protection against the potential exploit is provided. -@Input index The original array index value that would be used to - access the array. -@Input size The number of elements in the array being accessed. -@Return The value to use for the array index, modified so that it - remains within array bounds. -*/ /**************************************************************************/ -#define OSConfineArrayIndexNoSpeculation(index, size) (index) -#if !defined(DOXYGEN) -#define PVRSRV_MISSING_NO_SPEC_IMPL -#endif -#endif - -/*************************************************************************/ /*! -@Function OSClockns64 -@Description This function returns the number of ticks since system boot - expressed in nanoseconds. Unlike OSClockns, OSClockns64 has - a near 64-bit range. -@Return The 64-bit clock value, in nanoseconds. -*/ /**************************************************************************/ -IMG_UINT64 OSClockns64(void); - -/*************************************************************************/ /*! -@Function OSClockus64 -@Description This function returns the number of ticks since system boot - expressed in microseconds. Unlike OSClockus, OSClockus64 has - a near 64-bit range. -@Return The 64-bit clock value, in microseconds. -*/ /**************************************************************************/ -IMG_UINT64 OSClockus64(void); - -/*************************************************************************/ /*! -@Function OSClockus -@Description This function returns the number of ticks since system boot - in microseconds. -@Return The 32-bit clock value, in microseconds. -*/ /**************************************************************************/ -IMG_UINT32 OSClockus(void); - -/*************************************************************************/ /*! -@Function OSClockms -@Description This function returns the number of ticks since system boot - in milliseconds. -@Return The 32-bit clock value, in milliseconds. -*/ /**************************************************************************/ -IMG_UINT32 OSClockms(void); - -/*************************************************************************/ /*! -@Function OSClockMonotonicns64 -@Description This function returns a clock value based on the system - monotonic clock. -@Output pui64Time The 64-bit clock value, in nanoseconds. -@Return Error Code. -*/ /**************************************************************************/ -PVRSRV_ERROR OSClockMonotonicns64(IMG_UINT64 *pui64Time); - -/*************************************************************************/ /*! -@Function OSClockMonotonicus64 -@Description This function returns a clock value based on the system - monotonic clock. -@Output pui64Time The 64-bit clock value, in microseconds. -@Return Error Code. -*/ /**************************************************************************/ -PVRSRV_ERROR OSClockMonotonicus64(IMG_UINT64 *pui64Time); - -/*************************************************************************/ /*! -@Function OSClockMonotonicRawns64 -@Description This function returns a clock value based on the system - monotonic raw clock. -@Return 64bit ns timestamp -*/ /**************************************************************************/ -IMG_UINT64 OSClockMonotonicRawns64(void); - -/*************************************************************************/ /*! -@Function OSClockMonotonicRawus64 -@Description This function returns a clock value based on the system - monotonic raw clock. -@Return 64bit us timestamp -*/ /**************************************************************************/ -IMG_UINT64 OSClockMonotonicRawus64(void); - -/*************************************************************************/ /*! -@Function OSGetPageSize -@Description This function returns the page size. - If the OS is not using memory mappings it should return a - default value of 4096. -@Return The size of a page, in bytes. -*/ /**************************************************************************/ -size_t OSGetPageSize(void); - -/*************************************************************************/ /*! -@Function OSGetPageShift -@Description This function returns the page size expressed as a power of - two. A number of pages, left-shifted by this value, gives the - equivalent size in bytes. - If the OS is not using memory mappings it should return a - default value of 12. -@Return The page size expressed as a power of two. -*/ /**************************************************************************/ -size_t OSGetPageShift(void); - -/*************************************************************************/ /*! -@Function OSGetPageMask -@Description This function returns a bitmask that may be applied to an - address to mask off the least-significant bits so as to - leave the start address of the page containing that address. -@Return The page mask. -*/ /**************************************************************************/ -size_t OSGetPageMask(void); - -/*************************************************************************/ /*! -@Function OSGetOrder -@Description This function returns the order of power of two for a given - size. Eg. for a uSize of 4096 bytes the function would - return 12 (4096 = 2^12). -@Input uSize The size in bytes. -@Return The order of power of two. -*/ /**************************************************************************/ -size_t OSGetOrder(size_t uSize); - -/*************************************************************************/ /*! -@Function OSGetRAMSize -@Description This function returns the total amount of GPU-addressable - memory provided by the system. In other words, after loading - the driver this would be the largest allocation an - application would reasonably expect to be able to make. - Note that this is function is not expected to return the - current available memory but the amount which would be - available on startup. -@Return Total GPU-addressable memory size, in bytes. -*/ /**************************************************************************/ -IMG_UINT64 OSGetRAMSize(void); - -/*************************************************************************/ /*! -@Description Pointer to a Mid-level Interrupt Service Routine (MISR). -@Input pvData Pointer to MISR specific data. -*/ /**************************************************************************/ -typedef void (*PFN_MISR)(void *pvData); - -/*************************************************************************/ /*! -@Description Pointer to a thread entry point function. -@Input pvData Pointer to thread specific data. -*/ /**************************************************************************/ -typedef void (*PFN_THREAD)(void *pvData); - -/*************************************************************************/ /*! -@Function OSChangeSparseMemCPUAddrMap -@Description This function changes the CPU mapping of the underlying - sparse allocation. It is used by a PMR 'factory' - implementation if that factory supports sparse - allocations. -@Input psPageArray array representing the pages in the - sparse allocation -@Input sCpuVAddrBase the virtual base address of the sparse - allocation ('first' page) -@Input sCpuPAHeapBase the physical address of the virtual - base address 'sCpuVAddrBase' -@Input ui32AllocPageCount the number of pages referenced in - 'pai32AllocIndices' -@Input pai32AllocIndices list of indices of pages within - 'psPageArray' that we now want to - allocate and map -@Input ui32FreePageCount the number of pages referenced in - 'pai32FreeIndices' -@Input pai32FreeIndices list of indices of pages within - 'psPageArray' we now want to - unmap and free -@Input bIsLMA flag indicating if the sparse allocation - is from LMA or UMA memory -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSChangeSparseMemCPUAddrMap(void **psPageArray, - IMG_UINT64 sCpuVAddrBase, - IMG_CPU_PHYADDR sCpuPAHeapBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_BOOL bIsLMA); - -/*************************************************************************/ /*! -@Function OSInstallMISR -@Description Installs a Mid-level Interrupt Service Routine (MISR) - which handles higher-level processing of interrupts from - the device (GPU). - An MISR runs outside of interrupt context, and so may be - descheduled. This means it can contain code that would - not be permitted in the LISR. - An MISR is invoked when OSScheduleMISR() is called. This - call should be made by installed LISR once it has completed - its interrupt processing. - Multiple MISRs may be installed by the driver to handle - different causes of interrupt. -@Input pfnMISR pointer to the function to be installed - as the MISR -@Input hData private data provided to the MISR -@Input pszMisrName Name describing purpose of MISR worker thread - (Must be a string literal). -@Output hMISRData handle to the installed MISR (to be used - for a subsequent uninstall) -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData, - PFN_MISR pfnMISR, - void *hData, - const IMG_CHAR *pszMisrName); - -/*************************************************************************/ /*! -@Function OSUninstallMISR -@Description Uninstalls a Mid-level Interrupt Service Routine (MISR). -@Input hMISRData handle to the installed MISR -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData); - -/*************************************************************************/ /*! -@Function OSScheduleMISR -@Description Schedules a Mid-level Interrupt Service Routine (MISR) to be - executed. An MISR should be executed outside of interrupt - context, for example in a work queue. -@Input hMISRData handle to the installed MISR -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData); - -/*************************************************************************/ /*! -@Description Pointer to a function implementing debug dump of thread-specific - data. -@Input pfnDumpDebugPrintf Used to specify the print function used - to dump any debug information. If this - argument is NULL then a default print - function will be used. -@Input pvDumpDebugFile File identifier to be passed to the - print function if specified. -*/ /**************************************************************************/ - -typedef void (*PFN_THREAD_DEBUG_DUMP)(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -/*************************************************************************/ /*! -@Function OSThreadCreate -@Description Creates a kernel thread and starts it running. The caller - is responsible for informing the thread that it must finish - and return from the pfnThread function. It is not possible - to kill or terminate it. The new thread runs with the default - priority provided by the Operating System. - Note: Kernel threads are freezable which means that they - can be frozen by the kernel on for example driver suspend. - Because of that only OSEventObjectWaitKernel() function should - be used to put kernel threads in waiting state. -@Output phThread Returned handle to the thread. -@Input pszThreadName Name to assign to the thread. -@Input pfnThread Thread entry point function. -@Input pfnDebugDumpCB Used to dump info of the created thread -@Input bIsSupportingThread Set, if summary of this thread needs to - be dumped in debug_dump -@Input hData Thread specific data pointer for pfnThread(). -@Return Standard PVRSRV_ERROR error code. -*/ /**************************************************************************/ - -PVRSRV_ERROR OSThreadCreate(IMG_HANDLE *phThread, - IMG_CHAR *pszThreadName, - PFN_THREAD pfnThread, - PFN_THREAD_DEBUG_DUMP pfnDebugDumpCB, - IMG_BOOL bIsSupportingThread, - void *hData); - -/*! Available priority levels for the creation of a new Kernel Thread. */ -typedef enum priority_levels -{ - OS_THREAD_NOSET_PRIORITY = 0, /* With this option the priority level is the default for the given OS */ - OS_THREAD_HIGHEST_PRIORITY, - OS_THREAD_HIGH_PRIORITY, - OS_THREAD_NORMAL_PRIORITY, - OS_THREAD_LOW_PRIORITY, - OS_THREAD_LOWEST_PRIORITY, - OS_THREAD_LAST_PRIORITY /* This must be always the last entry */ -} OS_THREAD_LEVEL; - -/*************************************************************************/ /*! -@Function OSThreadCreatePriority -@Description As OSThreadCreate, this function creates a kernel thread and - starts it running. The difference is that with this function - is possible to specify the priority used to schedule the new - thread. - -@Output phThread Returned handle to the thread. -@Input pszThreadName Name to assign to the thread. -@Input pfnThread Thread entry point function. -@Input pfnDebugDumpCB Used to dump info of the created thread -@Input bIsSupportingThread Set, if summary of this thread needs to - be dumped in debug_dump -@Input hData Thread specific data pointer for pfnThread(). -@Input eThreadPriority Priority level to assign to the new thread. -@Return Standard PVRSRV_ERROR error code. -*/ /**************************************************************************/ -PVRSRV_ERROR OSThreadCreatePriority(IMG_HANDLE *phThread, - IMG_CHAR *pszThreadName, - PFN_THREAD pfnThread, - PFN_THREAD_DEBUG_DUMP pfnDebugDumpCB, - IMG_BOOL bIsSupportingThread, - void *hData, - OS_THREAD_LEVEL eThreadPriority); - -/*************************************************************************/ /*! -@Function OSThreadDestroy -@Description Waits for the thread to end and then destroys the thread - handle memory. This function will block and wait for the - thread to finish successfully, thereby providing a sync point - for the thread completing its work. No attempt is made to kill - or otherwise terminate the thread. -@Input hThread The thread handle returned by OSThreadCreate(). -@Return Standard PVRSRV_ERROR error code. -*/ /**************************************************************************/ -PVRSRV_ERROR OSThreadDestroy(IMG_HANDLE hThread); - -/*************************************************************************/ /*! -@Function OSMapPhysToLin -@Description Maps physical memory into a linear address range. -@Input BasePAddr physical CPU address -@Input ui32Bytes number of bytes to be mapped -@Input uiFlags flags denoting the caching mode to be employed - for the mapping (uncached/write-combined, - cached coherent or cached incoherent). - See pvrsrv_memallocflags.h for full flag bit - definitions. -@Return Pointer to the new mapping if successful, NULL otherwise. -*/ /**************************************************************************/ -void *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, size_t ui32Bytes, PVRSRV_MEMALLOCFLAGS_T uiFlags); - -/*************************************************************************/ /*! -@Function OSUnMapPhysToLin -@Description Unmaps physical memory previously mapped by OSMapPhysToLin(). -@Input pvLinAddr the linear mapping to be unmapped -@Input ui32Bytes number of bytes to be unmapped -@Return IMG_TRUE if unmapping was successful, IMG_FALSE otherwise. -*/ /**************************************************************************/ -IMG_BOOL OSUnMapPhysToLin(void *pvLinAddr, size_t ui32Bytes); - -/*************************************************************************/ /*! -@Function OSCPUCacheFlushRangeKM -@Description Clean and invalidate the CPU cache for the specified - address range. -@Input psDevNode device on which the allocation was made -@Input pvVirtStart virtual start address of the range to be - flushed -@Input pvVirtEnd virtual end address of the range to be - flushed -@Input sCPUPhysStart physical start address of the range to be - flushed -@Input sCPUPhysEnd physical end address of the range to be - flushed -@Return None -*/ /**************************************************************************/ -void OSCPUCacheFlushRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd); - -/*************************************************************************/ /*! -@Function OSCPUCacheCleanRangeKM -@Description Clean the CPU cache for the specified address range. - This writes out the contents of the cache and clears the - 'dirty' bit (which indicates the physical memory is - consistent with the cache contents). -@Input psDevNode device on which the allocation was made -@Input pvVirtStart virtual start address of the range to be - cleaned -@Input pvVirtEnd virtual end address of the range to be - cleaned -@Input sCPUPhysStart physical start address of the range to be - cleaned -@Input sCPUPhysEnd physical end address of the range to be - cleaned -@Return None -*/ /**************************************************************************/ -void OSCPUCacheCleanRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd); - -/*************************************************************************/ /*! -@Function OSCPUCacheInvalidateRangeKM -@Description Invalidate the CPU cache for the specified address range. - The cache must reload data from those addresses if they - are accessed. -@Input psDevNode device on which the allocation was made -@Input pvVirtStart virtual start address of the range to be - invalidated -@Input pvVirtEnd virtual end address of the range to be - invalidated -@Input sCPUPhysStart physical start address of the range to be - invalidated -@Input sCPUPhysEnd physical end address of the range to be - invalidated -@Return None -*/ /**************************************************************************/ -void OSCPUCacheInvalidateRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd); - -/*! CPU Cache operations address domain type */ -typedef enum -{ - OS_CACHE_OP_ADDR_TYPE_VIRTUAL, /*!< Operation requires CPU virtual address only */ - OS_CACHE_OP_ADDR_TYPE_PHYSICAL, /*!< Operation requires CPU physical address only */ - OS_CACHE_OP_ADDR_TYPE_BOTH /*!< Operation requires both CPU virtual & physical addresses */ -} OS_CACHE_OP_ADDR_TYPE; - -/*************************************************************************/ /*! -@Function OSCPUCacheOpAddressType -@Description Returns the address type (i.e. virtual/physical/both) the CPU - architecture performs cache maintenance operations under. - This is used to infer whether the virtual or physical address - supplied to the OSCPUCacheXXXRangeKM functions can be omitted - when called. -@Return OS_CACHE_OP_ADDR_TYPE -*/ /**************************************************************************/ -OS_CACHE_OP_ADDR_TYPE OSCPUCacheOpAddressType(void); - -/*! CPU Cache attributes available for retrieval, DCache unless specified */ -typedef enum _OS_CPU_CACHE_ATTRIBUTE_ -{ - OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE, /*!< The cache line size */ - OS_CPU_CACHE_ATTRIBUTE_COUNT /*!< The number of attributes (must be last) */ -} OS_CPU_CACHE_ATTRIBUTE; - -/*************************************************************************/ /*! -@Function OSCPUCacheAttributeSize -@Description Returns the size of a given cache attribute. - Typically this function is used to return the cache line - size, but may be extended to return the size of other - cache attributes. -@Input eCacheAttribute the cache attribute whose size should - be returned. -@Return The size of the specified cache attribute, in bytes. -*/ /**************************************************************************/ -IMG_UINT32 OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE eCacheAttribute); - -/*************************************************************************/ /*! -@Function OSGetCurrentProcessID -@Description Returns ID of current process (thread group) -@Return ID of current process -*****************************************************************************/ -IMG_PID OSGetCurrentProcessID(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentVirtualProcessID -@Description Returns ID of current process (thread group of current - PID namespace) -@Return ID of current process in PID namespace -*****************************************************************************/ -IMG_PID OSGetCurrentVirtualProcessID(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentProcessName -@Description Gets the name of current process -@Return Process name -*****************************************************************************/ -IMG_CHAR *OSGetCurrentProcessName(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentProcessVASpaceSize -@Description Returns the CPU virtual address space size of current process -@Return Process VA space size -*/ /**************************************************************************/ -IMG_UINT64 OSGetCurrentProcessVASpaceSize(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentThreadID -@Description Returns ID for current thread -@Return ID of current thread -*****************************************************************************/ -uintptr_t OSGetCurrentThreadID(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentClientProcessIDKM -@Description Returns ID of current client process (thread group) which - has made a bridge call into the server. - For some operating systems, this may simply be the current - process id. For others, it may be that a dedicated thread - is used to handle the processing of bridge calls and that - some additional processing is required to obtain the ID of - the client process making the bridge call. -@Return ID of current client process -*****************************************************************************/ -IMG_PID OSGetCurrentClientProcessIDKM(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentClientProcessNameKM -@Description Gets the name of current client process -@Return Client process name -*****************************************************************************/ -IMG_CHAR *OSGetCurrentClientProcessNameKM(void); - -/*************************************************************************/ /*! -@Function OSGetCurrentClientThreadIDKM -@Description Returns ID for current client thread - For some operating systems, this may simply be the current - thread id. For others, it may be that a dedicated thread - is used to handle the processing of bridge calls and that - some additional processing is require to obtain the ID of - the client thread making the bridge call. -@Return ID of current client thread -*****************************************************************************/ -uintptr_t OSGetCurrentClientThreadIDKM(void); - -/*************************************************************************/ /*! -@Function OSMemCmp -@Description Compares two blocks of memory for equality. -@Input pvBufA Pointer to the first block of memory -@Input pvBufB Pointer to the second block of memory -@Input uiLen The number of bytes to be compared -@Return Value < 0 if pvBufA is less than pvBufB. - Value > 0 if pvBufB is less than pvBufA. - Value = 0 if pvBufA is equal to pvBufB. -*****************************************************************************/ -IMG_INT OSMemCmp(void *pvBufA, void *pvBufB, size_t uiLen); - -/*************************************************************************/ /*! -@Function OSPhyContigPagesAlloc -@Description Allocates a number of contiguous physical pages. - If allocations made by this function are CPU cached then - OSPhyContigPagesClean has to be implemented to write the - cached data to memory. -@Input psPhysHeap the heap from which to allocate -@Input uiSize the size of the required allocation (in bytes) -@Output psMemHandle a returned handle to be used to refer to this - allocation -@Output psDevPAddr the physical address of the allocation -@Input uiPid the process ID that this allocation should - be associated with -@Return PVRSRV_OK on success, a failure code otherwise. -*****************************************************************************/ -PVRSRV_ERROR OSPhyContigPagesAlloc(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid); - -/*************************************************************************/ /*! -@Function OSPhyContigPagesFree -@Description Frees a previous allocation of contiguous physical pages -@Input psPhysHeap the heap from which to allocate -@Input psMemHandle the handle of the allocation to be freed -@Return None. -*****************************************************************************/ -void OSPhyContigPagesFree(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle); - -/*************************************************************************/ /*! -@Function OSPhyContigPagesMap -@Description Maps the specified allocation of contiguous physical pages - to a kernel virtual address -@Input psPhysHeap the heap from which to allocate -@Input psMemHandle the handle of the allocation to be mapped -@Input uiSize the size of the allocation (in bytes) -@Input psDevPAddr the physical address of the allocation -@Output pvPtr the virtual kernel address to which the - allocation is now mapped -@Return PVRSRV_OK on success, a failure code otherwise. -*****************************************************************************/ -PVRSRV_ERROR OSPhyContigPagesMap(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle, - size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr); - -/*************************************************************************/ /*! -@Function OSPhyContigPagesUnmap -@Description Unmaps the kernel mapping for the specified allocation of - contiguous physical pages -@Input psPhysHeap the heap from which to allocate -@Input psMemHandle the handle of the allocation to be unmapped -@Input pvPtr the virtual kernel address to which the - allocation is currently mapped -@Return None. -*****************************************************************************/ -void OSPhyContigPagesUnmap(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle, void *pvPtr); - -/*************************************************************************/ /*! -@Function OSPhyContigPagesClean -@Description Write the content of the specified allocation from CPU cache to - memory from (start + uiOffset) to (start + uiOffset + uiLength) - It is expected to be implemented as a cache clean operation but - it is allowed to fall back to a cache clean + invalidate - (i.e. flush). - If allocations returned by OSPhyContigPagesAlloc are always - uncached this can be implemented as nop. -@Input psPhysHeap the heap from which to allocate -@Input psMemHandle the handle of the allocation to be flushed -@Input uiOffset the offset in bytes from the start of the - allocation from where to start flushing -@Input uiLength the amount to flush from the offset in bytes -@Return PVRSRV_OK on success, a failure code otherwise. -*****************************************************************************/ -PVRSRV_ERROR OSPhyContigPagesClean(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength); - - -/*************************************************************************/ /*! -@Function OSInitEnvData -@Description Called to initialise any environment-specific data. This - could include initialising the bridge calling infrastructure - or device memory management infrastructure. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSInitEnvData(void); - -/*************************************************************************/ /*! -@Function OSDeInitEnvData -@Description The counterpart to OSInitEnvData(). Called to free any - resources which may have been allocated by OSInitEnvData(). -@Return None. -*/ /**************************************************************************/ -void OSDeInitEnvData(void); - -/*************************************************************************/ /*! -@Function OSVSScanf -@Description OS function to support the standard C vsscanf() function. -*/ /**************************************************************************/ -IMG_UINT32 OSVSScanf(const IMG_CHAR *pStr, const IMG_CHAR *pszFormat, ...); - -/*************************************************************************/ /*! -@Function OSStringLCat -@Description OS function to support the BSD C strlcat() function. -*/ /**************************************************************************/ -size_t OSStringLCat(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDstSize); - -/*************************************************************************/ /*! -@Function OSSNPrintf -@Description OS function to support the standard C snprintf() function. -@Output pStr char array to print into -@Input ui32Size maximum size of data to write (chars) -@Input pszFormat format string -*/ /**************************************************************************/ -IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...) __printf(3, 4); - -/*************************************************************************/ /*! -@Function OSVSNPrintf -@Description Printf to IMG string using variable args (see stdarg.h). - This is necessary because the '...' notation does not - support nested function calls. -@Input ui32Size maximum size of data to write (chars) -@Input pszFormat format string -@Input vaArgs variable args structure (from stdarg.h) -@Output pStr char array to print into -@Return Number of character written in buffer if successful other wise -1 on error -*/ /**************************************************************************/ -IMG_INT32 OSVSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR* pszFormat, va_list vaArgs) __printf(3, 0); - -/*************************************************************************/ /*! -@Function OSStringLength -@Description OS function to support the standard C strlen() function. -*/ /**************************************************************************/ -size_t OSStringLength(const IMG_CHAR *pStr); - -/*************************************************************************/ /*! -@Function OSStringNLength -@Description Return the length of a string, excluding the terminating null - byte ('\0'), but return at most 'uiCount' bytes. Only the first - 'uiCount' bytes of 'pStr' are interrogated. -@Input pStr pointer to the string -@Input uiCount the maximum length to return -@Return Length of the string if less than 'uiCount' bytes, otherwise - 'uiCount'. -*/ /**************************************************************************/ -size_t OSStringNLength(const IMG_CHAR *pStr, size_t uiCount); - -/*************************************************************************/ /*! -@Function OSStringNCompare -@Description OS function to support the standard C strncmp() function. -*/ /**************************************************************************/ -IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2, - size_t uiSize); - -/*************************************************************************/ /*! -@Function OSStringToUINT32 -@Description Changes string to IMG_UINT32. -*/ /**************************************************************************/ -PVRSRV_ERROR OSStringToUINT32(const IMG_CHAR *pStr, IMG_UINT32 ui32Base, - IMG_UINT32 *ui32Result); - -/*************************************************************************/ /*! -@Function OSStringUINT32ToStr -@Description Changes IMG_UINT32 to string -@Input pszBuf Buffer to write output number string -@Input uSize Size of buffer provided, i.e. size of pszBuf -@Input ui32Num Number to convert to string -@Return Returns 0 if buffer is not sufficient to hold the number string, - else returns length of number string -*/ /**************************************************************************/ -IMG_UINT32 OSStringUINT32ToStr(IMG_CHAR *pszBuf, size_t uSize, IMG_UINT32 ui32Num); - -/*************************************************************************/ /*! -@Function OSEventObjectCreate -@Description Create an event object. -@Input pszName name to assign to the new event object. -@Output EventObject the created event object. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, - IMG_HANDLE *EventObject); - -/*************************************************************************/ /*! -@Function OSEventObjectDestroy -@Description Destroy an event object. -@Input hEventObject the event object to destroy. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject); - -/*************************************************************************/ /*! -@Function OSEventObjectSignal -@Description Signal an event object. Any thread waiting on that event - object will be woken. -@Input hEventObject the event object to signal. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject); - -/*************************************************************************/ /*! -@Function OSEventObjectWait -@Description Wait for an event object to signal. The function is passed - an OS event object handle (which allows the OS to have the - calling thread wait on the associated event object). - The calling thread will be rescheduled when the associated - event object signals. - If the event object has not signalled after a default timeout - period (defined in EVENT_OBJECT_TIMEOUT_MS), the function - will return with the result code PVRSRV_ERROR_TIMEOUT. - - -@Input hOSEventKM the OS event object handle associated with - the event object. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM); - -/*************************************************************************/ /*! -@Function OSEventObjectWaitKernel -@Description Wait for an event object to signal. The function is passed - an OS event object handle (which allows the OS to have the - calling thread wait on the associated event object). - The calling thread will be rescheduled when the associated - event object signals. - If the event object has not signalled after a default timeout - period (defined in EVENT_OBJECT_TIMEOUT_MS), the function - will return with the result code PVRSRV_ERROR_TIMEOUT. - - Note: This function should be used only by kernel thread. - This is because all kernel threads are freezable and - this function allows the kernel to freeze the threads - when waiting. - - See OSEventObjectWait() for more details. - -@Input hOSEventKM the OS event object handle associated with - the event object. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -#if defined(__linux__) && defined(__KERNEL__) -PVRSRV_ERROR OSEventObjectWaitKernel(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus); -#else -#define OSEventObjectWaitKernel OSEventObjectWaitTimeout -#endif - -/*************************************************************************/ /*! -@Function OSSuspendTaskInterruptible -@Description Suspend the current task into interruptible state. -@Return none. -*/ /**************************************************************************/ -#if defined(__linux__) && defined(__KERNEL__) -void OSSuspendTaskInterruptible(void); -#endif - -/*************************************************************************/ /*! -@Function OSEventObjectWaitTimeout -@Description Wait for an event object to signal or timeout. The function - is passed an OS event object handle (which allows the OS to - have the calling thread wait on the associated event object). - The calling thread will be rescheduled when the associated - event object signals. - If the event object has not signalled after the specified - timeout period (passed in 'uiTimeoutus'), the function - will return with the result code PVRSRV_ERROR_TIMEOUT. -@Input hOSEventKM the OS event object handle associated with - the event object. -@Input uiTimeoutus the timeout period (in usecs) -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus); - -/*************************************************************************/ /*! -@Function OSEventObjectDumpDebugInfo -@Description Emits debug counters/stats related to the event object passed -@Input hOSEventKM the OS event object handle associated with - the event object. -@Return None. -*/ /**************************************************************************/ -void OSEventObjectDumpDebugInfo(IMG_HANDLE hOSEventKM); - -/*************************************************************************/ /*! -@Function OSEventObjectOpen -@Description Open an OS handle on the specified event object. - This OS handle may then be used to make a thread wait for - that event object to signal. -@Input hEventObject Event object handle. -@Output phOSEvent OS handle to the returned event object. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject, - IMG_HANDLE *phOSEvent); - -/*************************************************************************/ /*! -@Function OSEventObjectClose -@Description Close an OS handle previously opened for an event object. -@Input hOSEventKM OS event object handle to close. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM); - -/*************************************************************************/ /*! -@Function OSWaitus -@Description Implements a busy wait of the specified number of microseconds. - This function does NOT release thread quanta. -@Input ui32Timeus The duration of the wait period (in us) -@Return None. -*/ /**************************************************************************/ -void OSWaitus(IMG_UINT32 ui32Timeus); - -/*************************************************************************/ /*! -@Function OSSleepms -@Description Implements a sleep of the specified number of milliseconds. - This function may allow pre-emption, meaning the thread - may potentially not be rescheduled for a longer period. -@Input ui32Timems The duration of the sleep (in ms) -@Return None. -*/ /**************************************************************************/ -void OSSleepms(IMG_UINT32 ui32Timems); - -/*************************************************************************/ /*! -@Function OSReleaseThreadQuanta -@Description Relinquishes the current thread's execution time-slice, - permitting the OS scheduler to schedule another thread. -@Return None. -*/ /**************************************************************************/ -void OSReleaseThreadQuanta(void); - -#if defined(__linux__) && defined(__KERNEL__) -#define OSReadMemoryBarrier() rmb() -#else -/*************************************************************************/ /*! -@Function OSReadMemoryBarrier -@Description Insert a read memory barrier. - The read memory barrier guarantees that all load (read) - operations specified before the barrier will appear to happen - before all of the load operations specified after the barrier. -*/ /**************************************************************************/ -void OSReadMemoryBarrier(void); -#endif -/*************************************************************************/ /*! -@Function OSMemoryBarrier -@Description Insert a read/write memory barrier. - The read and write memory barrier guarantees that all load - (read) and all store (write) operations specified before the - barrier will appear to happen before all of the load/store - operations specified after the barrier. -@Input hReadback Optional pointer to memory to read back, can be - useful for flushing queues in bus interconnects to RAM before - device (GPU) access the shared memory. -@Return None. -*/ /**************************************************************************/ -void OSMemoryBarrier(volatile void *hReadback); -/*************************************************************************/ /*! -@Function OSWriteMemoryBarrier -@Description Insert a write memory barrier. - The write memory barrier guarantees that all store operations - (writes) specified before the barrier will appear to happen - before all of the store operations specified after the barrier. -@Input hReadback Optional pointer to memory to read back, can be - useful for flushing queues in bus interconnects to RAM before - device (GPU) access the shared memory. -@Return None. -*/ /**************************************************************************/ -void OSWriteMemoryBarrier(volatile void *hReadback); - -/*************************************************************************/ /*! -*/ /**************************************************************************/ - -/* The access method is dependent on the location of the physical memory that - * makes up the PhyHeaps defined for the system and the CPU architecture. These - * macros may change in future to accommodate different access requirements. - */ -/*! Performs a 32 bit word read from the device memory. */ -#define OSReadDeviceMem32(addr) (*((volatile IMG_UINT32 __force *)((void*)addr))) -/*! Performs a 32 bit word write to the device memory. */ -#define OSWriteDeviceMem32(addr, val) (*((volatile IMG_UINT32 __force *)((void*)addr)) = (IMG_UINT32)(val)) -/*! Performs a 32 bit word write to the device memory and issues a write memory barrier */ -#define OSWriteDeviceMem32WithWMB(addr, val) \ - do { \ - *((volatile IMG_UINT32 __force *)((void*)addr)) = (IMG_UINT32)(val); \ - OSWriteMemoryBarrier(addr); \ - } while (0) - -#if defined(__linux__) && defined(__KERNEL__) && !defined(NO_HARDWARE) - #define OSReadHWReg8(addr, off) ((IMG_UINT8)readb((IMG_BYTE __iomem *)(addr) + (off))) - #define OSReadHWReg16(addr, off) ((IMG_UINT16)readw((IMG_BYTE __iomem *)(addr) + (off))) - #define OSReadHWReg32(addr, off) ((IMG_UINT32)readl((IMG_BYTE __iomem *)(addr) + (off))) - - /* Little endian support only */ - #define OSReadHWReg64(addr, off) \ - ({ \ - __typeof__(addr) _addr = addr; \ - __typeof__(off) _off = off; \ - (IMG_UINT64) \ - ( \ - ( (IMG_UINT64)(readl((IMG_BYTE __iomem *)(_addr) + (_off) + 4)) << 32) \ - | readl((IMG_BYTE __iomem *)(_addr) + (_off)) \ - ); \ - }) - - #define OSWriteHWReg8(addr, off, val) writeb((IMG_UINT8)(val), (IMG_BYTE __iomem *)(addr) + (off)) - #define OSWriteHWReg16(addr, off, val) writew((IMG_UINT16)(val), (IMG_BYTE __iomem *)(addr) + (off)) - #define OSWriteHWReg32(addr, off, val) writel((IMG_UINT32)(val), (IMG_BYTE __iomem *)(addr) + (off)) - /* Little endian support only */ - #define OSWriteHWReg64(addr, off, val) do \ - { \ - __typeof__(addr) _addr = addr; \ - __typeof__(off) _off = off; \ - __typeof__(val) _val = val; \ - writel((IMG_UINT32)((_val) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off)); \ - writel((IMG_UINT32)(((IMG_UINT64)(_val) >> 32) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off) + 4); \ - } while (0) - - -#elif defined(NO_HARDWARE) - /* OSReadHWReg operations skipped in no hardware builds */ - #define OSReadHWReg8(addr, off) ((void)(addr), 0x4eU) - #define OSReadHWReg16(addr, off) ((void)(addr), 0x3a4eU) - #define OSReadHWReg32(addr, off) ((void)(addr), 0x30f73a4eU) -#if defined(__QNXNTO__) && __SIZEOF_LONG__ == 8 - /* This is needed for 64-bit QNX builds where the size of a long is 64 bits */ - #define OSReadHWReg64(addr, off) ((void)(addr), 0x5b376c9d30f73a4eUL) -#else - #define OSReadHWReg64(addr, off) ((void)(addr), 0x5b376c9d30f73a4eULL) -#endif - - #define OSWriteHWReg8(addr, off, val) - #define OSWriteHWReg16(addr, off, val) - #define OSWriteHWReg32(addr, off, val) - #define OSWriteHWReg64(addr, off, val) - -#else -/*************************************************************************/ /*! -@Function OSReadHWReg8 -@Description Read from an 8-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to read from a location - but instead returns a constant value. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be read. -@Return The byte read. -*/ /**************************************************************************/ - IMG_UINT8 OSReadHWReg8(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset); - -/*************************************************************************/ /*! -@Function OSReadHWReg16 -@Description Read from a 16-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to read from a location - but instead returns a constant value. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be read. -@Return The word read. -*/ /**************************************************************************/ - IMG_UINT16 OSReadHWReg16(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset); - -/*************************************************************************/ /*! -@Function OSReadHWReg32 -@Description Read from a 32-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to read from a location - but instead returns a constant value. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be read. -@Return The long word read. -*/ /**************************************************************************/ - IMG_UINT32 OSReadHWReg32(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset); - -/*************************************************************************/ /*! -@Function OSReadHWReg64 -@Description Read from a 64-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to read from a location - but instead returns a constant value. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be read. -@Return The long long word read. -*/ /**************************************************************************/ - IMG_UINT64 OSReadHWReg64(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset); - -/*************************************************************************/ /*! -@Function OSWriteHWReg8 -@Description Write to an 8-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to write to a location. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be written to. -@Input ui8Value The byte to be written to the register. -@Return None. -*/ /**************************************************************************/ - void OSWriteHWReg8(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 ui8Value); - -/*************************************************************************/ /*! -@Function OSWriteHWReg16 -@Description Write to a 16-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to write to a location. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be written to. -@Input ui16Value The word to be written to the register. -@Return None. -*/ /**************************************************************************/ - void OSWriteHWReg16(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT16 ui16Value); - -/*************************************************************************/ /*! -@Function OSWriteHWReg32 -@Description Write to a 32-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to write to a location. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be written to. -@Input ui32Value The long word to be written to the register. -@Return None. -*/ /**************************************************************************/ - void OSWriteHWReg32(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); - -/*************************************************************************/ /*! -@Function OSWriteHWReg64 -@Description Write to a 64-bit memory-mapped device register. - The implementation should not permit the compiler to - reorder the I/O sequence. - The implementation should ensure that for a NO_HARDWARE - build the code does not attempt to write to a location. -@Input pvLinRegBaseAddr The virtual base address of the register - block. -@Input ui32Offset The byte offset from the base address of - the register to be written to. -@Input ui64Value The long long word to be written to the - register. -@Return None. -*/ /**************************************************************************/ - void OSWriteHWReg64(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value); -#endif - -/*************************************************************************/ /*! -@Description Pointer to a timer callback function. -@Input pvData Pointer to timer specific data. -*/ /**************************************************************************/ -typedef void (*PFN_TIMER_FUNC)(void* pvData); - -/*************************************************************************/ /*! -@Function OSAddTimer -@Description OS specific function to install a timer callback. The - timer will then need to be enabled, as it is disabled by - default. - When enabled, the callback will be invoked once the specified - timeout has elapsed. -@Input pfnTimerFunc Timer callback -@Input *pvData Callback data -@Input ui32MsTimeout Callback period -@Return Valid handle on success, NULL if a failure -*/ /**************************************************************************/ -IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32MsTimeout); - -/*************************************************************************/ /*! -@Function OSRemoveTimer -@Description Removes the specified timer. The handle becomes invalid and - should no longer be used. -@Input hTimer handle of the timer to be removed -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSRemoveTimer(IMG_HANDLE hTimer); - -/*************************************************************************/ /*! -@Function OSEnableTimer -@Description Enable the specified timer. after enabling, the timer will - invoke the associated callback at an interval determined by - the configured timeout period until disabled. -@Input hTimer handle of the timer to be enabled -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSEnableTimer(IMG_HANDLE hTimer); - -/*************************************************************************/ /*! -@Function OSDisableTimer -@Description Disable the specified timer -@Input hTimer handle of the timer to be disabled -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSDisableTimer(IMG_HANDLE hTimer); - - -/*************************************************************************/ /*! - @Function OSPanic - @Description Take action in response to an unrecoverable driver error - @Return None -*/ /**************************************************************************/ -void OSPanic(void); - -/*************************************************************************/ /*! -@Function OSCopyToUser -@Description Copy data to user-addressable memory from kernel-addressable - memory. - Note that pvDest may be an invalid address or NULL and the - function should return an error in this case. - For operating systems that do not have a user/kernel space - distinction, this function should be implemented as a stub - which simply returns PVRSRV_ERROR_NOT_SUPPORTED. -@Input pvProcess handle of the connection -@Input pvDest pointer to the destination User memory -@Input pvSrc pointer to the source Kernel memory -@Input ui32Bytes size of the data to be copied -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSCopyToUser(void *pvProcess, void __user *pvDest, const void *pvSrc, size_t ui32Bytes); - -/*************************************************************************/ /*! -@Function OSCopyFromUser -@Description Copy data from user-addressable memory to kernel-addressable - memory. - Note that pvSrc may be an invalid address or NULL and the - function should return an error in this case. - For operating systems that do not have a user/kernel space - distinction, this function should be implemented as a stub - which simply returns PVRSRV_ERROR_NOT_SUPPORTED. -@Input pvProcess handle of the connection -@Input pvDest pointer to the destination Kernel memory -@Input pvSrc pointer to the source User memory -@Input ui32Bytes size of the data to be copied -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSCopyFromUser(void *pvProcess, void *pvDest, const void __user *pvSrc, size_t ui32Bytes); - -#if defined(__linux__) || defined(INTEGRITY_OS) -#define OSBridgeCopyFromUser OSCopyFromUser -#define OSBridgeCopyToUser OSCopyToUser -#else -/*************************************************************************/ /*! -@Function OSBridgeCopyFromUser -@Description Copy data from user-addressable memory into kernel-addressable - memory as part of a bridge call operation. - For operating systems that do not have a user/kernel space - distinction, this function will require whatever implementation - is needed to pass data for making the bridge function call. - For operating systems which do have a user/kernel space - distinction (such as Linux) this function may be defined so - as to equate to a call to OSCopyFromUser(). -@Input pvProcess handle of the connection -@Input pvDest pointer to the destination Kernel memory -@Input pvSrc pointer to the source User memory -@Input ui32Bytes size of the data to be copied -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSBridgeCopyFromUser (void *pvProcess, - void *pvDest, - const void *pvSrc, - size_t ui32Bytes); - -/*************************************************************************/ /*! -@Function OSBridgeCopyToUser -@Description Copy data to user-addressable memory from kernel-addressable - memory as part of a bridge call operation. - For operating systems that do not have a user/kernel space - distinction, this function will require whatever implementation - is needed to pass data for making the bridge function call. - For operating systems which do have a user/kernel space - distinction (such as Linux) this function may be defined so - as to equate to a call to OSCopyToUser(). -@Input pvProcess handle of the connection -@Input pvDest pointer to the destination User memory -@Input pvSrc pointer to the source Kernel memory -@Input ui32Bytes size of the data to be copied -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSBridgeCopyToUser (void *pvProcess, - void *pvDest, - const void *pvSrc, - size_t ui32Bytes); -#endif - -/* To be increased if required in future */ -#define PVRSRV_MAX_BRIDGE_IN_SIZE 0x2000 /*!< Size of the memory block used to hold data passed in to a bridge call */ -#define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000 /*!< Size of the memory block used to hold data returned from a bridge call */ - -/*************************************************************************/ /*! -@Function OSPlatformBridgeInit -@Description Called during device creation to allow the OS port to register - other bridge modules and related resources that it requires. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSPlatformBridgeInit(void); - -/*************************************************************************/ /*! -@Function OSPlatformBridgeDeInit -@Description Called during device destruction to allow the OS port to - deregister its OS specific bridges and clean up other - related resources. -*/ /**************************************************************************/ -void OSPlatformBridgeDeInit(void); - -/*************************************************************************/ /*! -@Function PVRSRVToNativeError -@Description Returns the OS-specific equivalent error number/code for - the specified PVRSRV_ERROR value. - If there is no equivalent, or the PVRSRV_ERROR value is - PVRSRV_OK (no error), 0 is returned. -@Return The OS equivalent error code. -*/ /**************************************************************************/ -int PVRSRVToNativeError(PVRSRV_ERROR e); -/** See PVRSRVToNativeError(). */ -#define OSPVRSRVToNativeError(e) ( (PVRSRV_OK == e)? 0: PVRSRVToNativeError(e) ) - - -#if defined(__linux__) && defined(__KERNEL__) - -/* Provide LockDep friendly definitions for Services RW locks */ -#include -#include -#include "allocmem.h" - -#define OSWRLockCreate(ppsLock) ({ \ - PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \ - *(ppsLock) = OSAllocMem(sizeof(struct rw_semaphore)); \ - if (*(ppsLock)) { init_rwsem(*(ppsLock)); e = PVRSRV_OK; }; \ - e;}) -#define OSWRLockDestroy(psLock) ({OSFreeMem(psLock); PVRSRV_OK;}) - -#define OSWRLockAcquireRead(psLock) ({down_read(psLock); PVRSRV_OK;}) -#define OSWRLockAcquireReadNested(psLock, subclass) ({down_read_nested((psLock), (subclass)); PVRSRV_OK;}) -#define OSWRLockReleaseRead(psLock) ({up_read(psLock); PVRSRV_OK;}) -#define OSWRLockAcquireWrite(psLock) ({down_write(psLock); PVRSRV_OK;}) -#define OSWRLockReleaseWrite(psLock) ({up_write(psLock); PVRSRV_OK;}) - -#elif defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) -/* User-mode unit tests use these definitions on Linux */ - -PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock); -void OSWRLockDestroy(POSWR_LOCK psLock); -void OSWRLockAcquireRead(POSWR_LOCK psLock); -#define OSWRLockAcquireReadNested(psLock, subclass) OSWRLockAcquireRead((psLock)) -void OSWRLockReleaseRead(POSWR_LOCK psLock); -void OSWRLockAcquireWrite(POSWR_LOCK psLock); -void OSWRLockReleaseWrite(POSWR_LOCK psLock); - -#else - -/*! Function not implemented definition. */ -#define OSFUNC_NOT_IMPLEMENTED 0 -/*! Assert used for OSFUNC_NOT_IMPLEMENTED. */ -#define OSFUNC_NOT_IMPLEMENTED_ASSERT() PVR_ASSERT(OSFUNC_NOT_IMPLEMENTED) - -/*************************************************************************/ /*! -@Function OSWRLockCreate -@Description Create a writer/reader lock. - This type of lock allows multiple concurrent readers but - only a single writer, allowing for optimized performance. -@Output ppsLock A handle to the created WR lock. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -static INLINE PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock) -{ - PVR_UNREFERENCED_PARAMETER(ppsLock); - - OSFUNC_NOT_IMPLEMENTED_ASSERT(); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -/*************************************************************************/ /*! -@Function OSWRLockDestroy -@Description Destroys a writer/reader lock. -@Input psLock The handle of the WR lock to be destroyed. -@Return None. -*/ /**************************************************************************/ -static INLINE void OSWRLockDestroy(POSWR_LOCK psLock) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} - -/*************************************************************************/ /*! -@Function OSWRLockAcquireRead -@Description Acquire a writer/reader read lock. - If the write lock is already acquired, the caller will - block until it is released. -@Input psLock The handle of the WR lock to be acquired for - reading. -@Return None. -*/ /**************************************************************************/ -static INLINE void OSWRLockAcquireRead(POSWR_LOCK psLock) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} - -/*************************************************************************/ /*! -@Function OSWRLockAcquireReadNested -@Description Acquire a nested writer/reader read lock. - If the write lock is already acquired, the caller will - block until it is released. - For operating systems other than Linux, this equates to an - OSWRLockAcquireRead() call. On Linux, this function wraps a call - to down_read_nested(). This recognises the scenario where - there may be multiple subclasses within a particular class - of lock. In such cases, the order in which the locks belonging - these various subclasses are acquired is important and must be - validated. -@Input psLock The handle of the WR lock to be acquired for - reading. -@Input iSubclass The subclass of the lock. -@Return None. -*/ /**************************************************************************/ -static INLINE void OSWRLockAcquireReadNested(POSWR_LOCK psLock, IMG_INT iSubclass) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - PVR_UNREFERENCED_PARAMETER(iSubclass); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} - -/*************************************************************************/ /*! -@Function OSWRLockReleaseRead -@Description Release a writer/reader read lock. -@Input psLock The handle of the WR lock whose read lock is to - be released. -@Return None. -*/ /**************************************************************************/ -static INLINE void OSWRLockReleaseRead(POSWR_LOCK psLock) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} - -/*************************************************************************/ /*! -@Function OSWRLockAcquireWrite -@Description Acquire a writer/reader write lock. - If the write lock or any read lock are already acquired, - the caller will block until all are released. -@Input psLock The handle of the WR lock to be acquired for - writing. -@Return None. -*/ /**************************************************************************/ -static INLINE void OSWRLockAcquireWrite(POSWR_LOCK psLock) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} - -/*************************************************************************/ /*! -@Function OSWRLockReleaseWrite -@Description Release a writer/reader write lock. -@Input psLock The handle of the WR lock whose write lock is to - be released. -@Return None -*/ /**************************************************************************/ -static INLINE void OSWRLockReleaseWrite(POSWR_LOCK psLock) -{ - PVR_UNREFERENCED_PARAMETER(psLock); - OSFUNC_NOT_IMPLEMENTED_ASSERT(); -} -#endif - -/*************************************************************************/ /*! -@Function OSDivide64r64 -@Description Divide a 64-bit value by a 32-bit value. Return the 64-bit - quotient. - The remainder is also returned in 'pui32Remainder'. -@Input ui64Divident The number to be divided. -@Input ui32Divisor The 32-bit value 'ui64Divident' is to - be divided by. -@Output pui32Remainder The remainder of the division. -@Return The 64-bit quotient (result of the division). -*/ /**************************************************************************/ -IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder); - -/*************************************************************************/ /*! -@Function OSDivide64 -@Description Divide a 64-bit value by a 32-bit value. Return a 32-bit - quotient. - The remainder is also returned in 'pui32Remainder'. - This function allows for a more optional implementation - of a 64-bit division when the result is known to be - representable in 32-bits. -@Input ui64Divident The number to be divided. -@Input ui32Divisor The 32-bit value 'ui64Divident' is to - be divided by. -@Output pui32Remainder The remainder of the division. -@Return The 32-bit quotient (result of the division). -*/ /**************************************************************************/ -IMG_UINT32 OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder); - -/*************************************************************************/ /*! -@Function OSDumpStack -@Description Dump the current task information and its stack trace. -@Return None -*/ /**************************************************************************/ -void OSDumpStack(void); - -/*************************************************************************/ /*! -@Function OSUserModeAccessToPerfCountersEn -@Description Permit User-mode access to CPU performance counter - registers. - This function is called during device initialisation. - Certain CPU architectures may need to explicitly permit - User mode access to performance counters - if this is - required, the necessary code should be implemented inside - this function. -@Return None. -*/ /**************************************************************************/ -void OSUserModeAccessToPerfCountersEn(void); - -/*************************************************************************/ /*! -@Function OSDebugSignalPID -@Description Sends a SIGTRAP signal to a specific PID in user mode for - debugging purposes. The user mode process can register a handler - against this signal. - This is necessary to support the Rogue debugger. If the Rogue - debugger is not used then this function may be implemented as - a stub. -@Input ui32PID The PID for the signal. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR OSDebugSignalPID(IMG_UINT32 ui32PID); - -#if defined(__linux__) && defined(__KERNEL__) && !defined(DOXYGEN) -#define OSWarnOn(a) WARN_ON(a) -#else -/*************************************************************************/ /*! -@Function OSWarnOn -@Description This API allows the driver to emit a special token and stack - dump to the server log when an issue is detected that needs the - OS to be notified. The token or call may be used to trigger - log collection by the OS environment. - PVR_DPF log messages will have been emitted prior to this call. -@Input a Expression to evaluate, if true trigger Warn signal -@Return None -*/ /**************************************************************************/ -#define OSWarnOn(a) do { if ((a)) { OSDumpStack(); } } while (0) -#endif - -/*************************************************************************/ /*! -@Function OSIsKernelThread -@Description This API determines if the current running thread is a kernel - thread (i.e. one not associated with any userland process, - typically an MISR handler.) -@Return IMG_TRUE if it is a kernel thread, otherwise IMG_FALSE. -*/ /**************************************************************************/ -IMG_BOOL OSIsKernelThread(void); - -/*************************************************************************/ /*! -@Function OSThreadDumpInfo -@Description Traverse the thread list and call each of the stored - callbacks to dump the info in debug_dump. -@Input pfnDumpDebugPrintf The 'printf' function to be called to - display the debug info -@Input pvDumpDebugFile Optional file identifier to be passed to - the 'printf' function if required -*/ /**************************************************************************/ -void OSThreadDumpInfo(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -/*************************************************************************/ /*! -@Function OSDumpVersionInfo -@Description Store OS version information in debug dump. -@Input pfnDumpDebugPrintf The 'printf' function to be called to - display the debug info -@Input pvDumpDebugFile Optional file identifier to be passed to - the 'printf' function if required -*/ /**************************************************************************/ -void OSDumpVersionInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -/*************************************************************************/ /*! -@Function OSIsWriteCombineUnalignedSafe -@Description Determine if unaligned accesses to write-combine memory are - safe to perform, i.e. whether we are safe from a CPU fault - occurring. This test is specifically aimed at ARM64 platforms - which cannot provide this guarantee if the memory is 'device' - memory rather than 'normal' under the ARM memory architecture. -@Return IMG_TRUE if safe, IMG_FALSE otherwise. -*/ /**************************************************************************/ -IMG_BOOL OSIsWriteCombineUnalignedSafe(void); - -/*************************************************************************/ /*! -@Function OSDebugLevel -@Description Returns current value of the debug level. -@Return Debug level. -*/ /**************************************************************************/ -IMG_UINT32 OSDebugLevel(void); - -/*************************************************************************/ /*! -@Function PVRSRVSetDebugLevel -@Description Sets the current value of the debug level to ui32DebugLevel. -@Input ui32DebugLevel New debug level value. -*/ /**************************************************************************/ -void OSSetDebugLevel(IMG_UINT32 ui32DebugLevel); - -/*************************************************************************/ /*! -@Function PVRSRVIsDebugLevel -@Description Tests if a given debug level is enabled. -@Input ui32DebugLevel IMG_TRUE if debug level is enabled - and IMG_FALSE otherwise. -*/ /**************************************************************************/ -IMG_BOOL OSIsDebugLevel(IMG_UINT32 ui32DebugLevel); - -#if defined(SUPPORT_DMA_TRANSFER) - -typedef void (*PFN_SERVER_CLEANUP)(void *pvData, IMG_BOOL bAdvanceTimeline); - -#define DMA_COMPLETION_TIMEOUT_MS 60000 -#define DMA_ERROR_SYNC_RETRIES 100 - -PVRSRV_ERROR OSDmaPrepareTransfer(PVRSRV_DEVICE_NODE *psDevNode, void *psChan, - IMG_DMA_ADDR* psDmaAddr, IMG_UINT64* puiAddress, - IMG_UINT64 uiSize, IMG_BOOL bMemToDev, - IMG_HANDLE pvOSData, - IMG_HANDLE pvServerCleanupParam,PFN_SERVER_CLEANUP pfnServerCleanup, IMG_BOOL bFirst); - -PVRSRV_ERROR OSDmaPrepareTransferSparse(PVRSRV_DEVICE_NODE *psDevNode, IMG_HANDLE pvChan, - IMG_DMA_ADDR* psDmaAddr, IMG_BOOL *pbValid, - IMG_UINT64* puiAddress, IMG_UINT64 uiSize, - IMG_UINT32 uiOffsetInPage, - IMG_UINT32 ui32SizeInPages, - IMG_BOOL bMemToDev, - IMG_HANDLE pvOSData, - IMG_HANDLE pvServerCleanupParam, PFN_SERVER_CLEANUP pfnServerCleanup, - IMG_BOOL bFirst); - -PVRSRV_ERROR OSDmaAllocData(PVRSRV_DEVICE_NODE *psDevNode,IMG_UINT32 uiNumDMA, void **pvAllocedData); -PVRSRV_ERROR OSDmaSubmitTransfer(PVRSRV_DEVICE_NODE *psDevNode, void *pvOSData, void *psChan, IMG_BOOL bSynchronous); -void OSDmaForceCleanup(PVRSRV_DEVICE_NODE *psDevNode, void *pvChan, - void *pvOSData, IMG_HANDLE pvServerCleanupParam, - PFN_SERVER_CLEANUP pfnServerCleanup); -#endif -#endif /* OSFUNC_H */ - -/****************************************************************************** - End of file (osfunc.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/osfunc_arm64.c b/drivers/gpu/drm/img-rogue/1.17/osfunc_arm64.c deleted file mode 100644 index 68d1285b00bef..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osfunc_arm64.c +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title arm64 specific OS functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Processor specific OS functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv_error.h" -#include "img_types.h" -#include "img_defs.h" -#include "osfunc.h" -#include "pvr_debug.h" - -#include "kernel_compatibility.h" - -#if defined(CONFIG_OUTER_CACHE) - /* If you encounter a 64-bit ARM system with an outer cache, you'll need - * to add the necessary code to manage that cache. See osfunc_arm.c - * for an example of how to do so. - */ - #error "CONFIG_OUTER_CACHE not supported on arm64." -#endif - -static inline void begin_user_mode_access(void) -{ -#if defined(CONFIG_ARM64) && defined(CONFIG_ARM64_SW_TTBR0_PAN) - uaccess_enable_privileged(); -#endif -} - -static inline void end_user_mode_access(void) -{ -#if defined(CONFIG_ARM64) && defined(CONFIG_ARM64_SW_TTBR0_PAN) - uaccess_disable_privileged(); -#endif -} - -static inline void FlushRange(void *pvRangeAddrStart, - void *pvRangeAddrEnd, - PVRSRV_CACHE_OP eCacheOp) -{ - IMG_UINT32 ui32CacheLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE); - IMG_BYTE *pbStart = pvRangeAddrStart; - IMG_BYTE *pbEnd = pvRangeAddrEnd; - IMG_BYTE *pbBase; - - /* - On arm64, the TRM states in D5.8.1 (data and unified caches) that if cache - maintenance is performed on a memory location using a VA, the effect of - that cache maintenance is visible to all VA aliases of the physical memory - location. So here it's quicker to issue the machine cache maintenance - instruction directly without going via the Linux kernel DMA framework as - this is sufficient to maintain the CPU d-caches on arm64. - */ - - begin_user_mode_access(); - - pbEnd = (IMG_BYTE *) PVR_ALIGN((uintptr_t)pbEnd, (uintptr_t)ui32CacheLineSize); - for (pbBase = pbStart; pbBase < pbEnd; pbBase += ui32CacheLineSize) - { - switch (eCacheOp) - { - case PVRSRV_CACHE_OP_CLEAN: - asm volatile ("dc cvac, %0" :: "r" (pbBase)); - break; - - case PVRSRV_CACHE_OP_INVALIDATE: - asm volatile ("dc ivac, %0" :: "r" (pbBase)); - break; - - case PVRSRV_CACHE_OP_FLUSH: - asm volatile ("dc civac, %0" :: "r" (pbBase)); - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Cache maintenance operation type %d is invalid", - __func__, eCacheOp)); - break; - } - } - - end_user_mode_access(); -} - -void OSCPUCacheFlushRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - struct device *dev; - - if (pvVirtStart) - { - FlushRange(pvVirtStart, pvVirtEnd, PVRSRV_CACHE_OP_FLUSH); - return; - } - - dev = psDevNode->psDevConfig->pvOSDevice; - - if (dev) - { - dma_sync_single_for_device(dev, sCPUPhysStart.uiAddr, - sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, - DMA_TO_DEVICE); - dma_sync_single_for_cpu(dev, sCPUPhysStart.uiAddr, - sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, - DMA_FROM_DEVICE); - } - else - { - /* - * Allocations done prior to obtaining device pointer may - * affect in cache operations being scheduled. - * - * Ignore operations with null device pointer. - * This prevents crashes on newer kernels that don't return dummy ops - * when null pointer is passed to get_dma_ops. - * - */ - - /* Don't spam on nohw */ -#if !defined(NO_HARDWARE) - PVR_DPF((PVR_DBG_WARNING, "Cache operation cannot be completed!")); -#endif - } - -} - -void OSCPUCacheCleanRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - struct device *dev; - - if (pvVirtStart) - { - FlushRange(pvVirtStart, pvVirtEnd, PVRSRV_CACHE_OP_CLEAN); - return; - } - - dev = psDevNode->psDevConfig->pvOSDevice; - - if (dev) - { - dma_sync_single_for_device(dev, sCPUPhysStart.uiAddr, - sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, - DMA_TO_DEVICE); - } - else - { - /* - * Allocations done prior to obtaining device pointer may - * affect in cache operations being scheduled. - * - * Ignore operations with null device pointer. - * This prevents crashes on newer kernels that don't return dummy ops - * when null pointer is passed to get_dma_ops. - * - */ - - - /* Don't spam on nohw */ -#if !defined(NO_HARDWARE) - PVR_DPF((PVR_DBG_WARNING, "Cache operation cannot be completed!")); -#endif - } - -} - -void OSCPUCacheInvalidateRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - struct device *dev; - - if (pvVirtStart) - { - FlushRange(pvVirtStart, pvVirtEnd, PVRSRV_CACHE_OP_INVALIDATE); - return; - } - - dev = psDevNode->psDevConfig->pvOSDevice; - - if (dev) - { - dma_sync_single_for_cpu(dev, sCPUPhysStart.uiAddr, - sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, - DMA_FROM_DEVICE); - } - else - { - /* - * Allocations done prior to obtaining device pointer may - * affect in cache operations being scheduled. - * - * Ignore operations with null device pointer. - * This prevents crashes on newer kernels that don't return dummy ops - * when null pointer is passed to get_dma_ops. - * - */ - - /* Don't spam on nohw */ -#if !defined(NO_HARDWARE) - PVR_DPF((PVR_DBG_WARNING, "Cache operation cannot be completed!")); -#endif - } -} - - -OS_CACHE_OP_ADDR_TYPE OSCPUCacheOpAddressType(void) -{ - return OS_CACHE_OP_ADDR_TYPE_PHYSICAL; -} - -void OSUserModeAccessToPerfCountersEn(void) -{ -} - -IMG_BOOL OSIsWriteCombineUnalignedSafe(void) -{ - /* - * Under ARM64 there is the concept of 'device' [0] and 'normal' [1] memory. - * Unaligned access on device memory is explicitly disallowed [2]: - * - * 'Further, unaligned accesses are only allowed to regions marked as Normal - * memory type. - * ... - * Attempts to perform unaligned accesses when not allowed will cause an - * alignment fault (data abort).' - * - * Write-combine on ARM64 can be implemented as either normal non-cached - * memory (NORMAL_NC) or as device memory with gathering enabled - * (DEVICE_GRE.) Kernel 3.13 changed this from the latter to the former. - * - * [0]:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/CHDBDIDF.html - * [1]:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch13s01s01.html - * [2]:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html - */ - - pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); - - return (pgprot_val(pgprot) & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL_NC); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/osfunc_common.h b/drivers/gpu/drm/img-rogue/1.17/osfunc_common.h deleted file mode 100644 index 539ef2c042d1c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osfunc_common.h +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS functions header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS specific API definitions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OSFUNC_COMMON_H -/*! @cond Doxygen_Suppress */ -#define OSFUNC_COMMON_H -/*! @endcond */ - -#if defined(__KERNEL__) && defined(__linux__) -#include -#else -#include -#endif - -#include "img_types.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/**************************************************************************/ /*! -@Function DeviceMemSet -@Description Set memory, whose mapping may be uncached, to a given value. - Safe implementation for all architectures for uncached mapping, - optimised for speed where supported by tool chains. - In such cases, OSDeviceMemSet() is defined as a call to this - function. -@Input pvDest void pointer to the memory to be set -@Input ui8Value byte containing the value to be set -@Input ui32Size the number of bytes to be set to the given value -@Return None - */ /**************************************************************************/ -void DeviceMemSet(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size); - -/**************************************************************************/ /*! -@Function DeviceMemCopy -@Description Copy values from one area of memory. Safe implementation for - all architectures for uncached mapping, of either the source - or destination, optimised for speed where supported by tool - chains. In such cases, OSDeviceMemCopy() is defined as a call - to this function. -@Input pvDst void pointer to the destination memory -@Input pvSrc void pointer to the source memory -@Input ui32Size the number of bytes to be copied -@Return None - */ /**************************************************************************/ -void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t ui32Size); - -/**************************************************************************/ /*! -@Function DeviceMemSetBytes -@Description Potentially very slow (but safe) memset fallback for non-GNU C - compilers for arm64/aarch64 -@Input pvDest void pointer to the memory to be set -@Input ui8Value byte containing the value to be set -@Input ui32Size the number of bytes to be set to the given value -@Return None - */ /**************************************************************************/ -void DeviceMemSetBytes(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size); - -/**************************************************************************/ /*! -@Function DeviceMemCopyBytes -@Description Potentially very slow (but safe) memcpy fallback for non-GNU C - compilers for arm64/aarch64 -@Input pvDst void pointer to the destination memory -@Input pvSrc void pointer to the source memory -@Input ui32Size the number of bytes to be copied -@Return None - */ /**************************************************************************/ -void DeviceMemCopyBytes(void *pvDst, const void *pvSrc, size_t ui32Size); - -/**************************************************************************/ /*! -@Function StringLCopy -@Description Copy at most uDataSize-1 bytes from pszSrc to pszDest. - If no null byte ('\0') is contained within the first uDataSize-1 - characters of the source string, the destination string will be - truncated. If the length of the source string is less than uDataSize - an additional NUL byte will be copied to the destination string - to ensure that the string is NUL-terminated. -@Input pszDest char pointer to the destination string -@Input pszSrc const char pointer to the source string -@Input uDataSize the maximum number of bytes to be copied -@Return Size of the source string - */ /**************************************************************************/ -size_t StringLCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDataSize); - -#if defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY) -#if defined(__GNUC__) -/* Workarounds for assumptions made that memory will not be mapped uncached - * in kernel or user address spaces on arm64 platforms (or other testing). - */ - -#define OSDeviceMemSet(a,b,c) DeviceMemSet((a), (b), (c)) -#define OSDeviceMemCopy(a,b,c) DeviceMemCopy((a), (b), (c)) - -#else /* defined __GNUC__ */ - -#define OSDeviceMemSet(a,b,c) DeviceMemSetBytes((a), (b), (c)) -#define OSDeviceMemCopy(a,b,c) DeviceMemCopyBytes((a), (b), (c)) - -#endif /* defined __GNUC__ */ - -#else /* (defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */ - -/* Everything else */ - -/**************************************************************************/ /*! -@Function OSDeviceMemSet -@Description Set memory, whose mapping may be uncached, to a given value. - On some architectures, additional processing may be needed - if the mapping is uncached. -@Input a void pointer to the memory to be set -@Input b byte containing the value to be set -@Input c the number of bytes to be set to the given value -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#define OSDeviceMemSet(a,b,c) \ - do { \ - if ((c) != 0) \ - { \ - (void) memset((a), (b), (c)); \ - (void) *(volatile IMG_UINT32*)((void*)(a)); \ - } \ - } while (false) - -/**************************************************************************/ /*! -@Function OSDeviceMemCopy -@Description Copy values from one area of memory, to another, when one - or both mappings may be uncached. - On some architectures, additional processing may be needed - if mappings are uncached. -@Input a void pointer to the destination memory -@Input b void pointer to the source memory -@Input c the number of bytes to be copied -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#define OSDeviceMemCopy(a,b,c) \ - do { \ - if ((c) != 0) \ - { \ - memcpy((a), (b), (c)); \ - (void) *(volatile IMG_UINT32*)((void*)(a)); \ - } \ - } while (false) - -#endif /* (defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */ - -/**************************************************************************/ /*! -@Function OSCachedMemSet -@Description Set memory, where the mapping is known to be cached, to a - given value. This function exists to allow an optimal memset - to be performed when memory is known to be cached. -@Input a void pointer to the memory to be set -@Input b byte containing the value to be set -@Input c the number of bytes to be set to the given value -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#define OSCachedMemSet(a,b,c) (void) memset((a), (b), (c)) - -/**************************************************************************/ /*! -@Function OSCachedMemCopy -@Description Copy values from one area of memory, to another, when both - mappings are known to be cached. - This function exists to allow an optimal memcpy to be - performed when memory is known to be cached. -@Input a void pointer to the destination memory -@Input b void pointer to the source memory -@Input c the number of bytes to be copied -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#define OSCachedMemCopy(a,b,c) memcpy((a), (b), (c)) - -#if defined(__KERNEL__) - -/**************************************************************************/ /*! -@Function OSCachedMemSetWMB -@Description Set memory, where the mapping is known to be cached or - write-combine, to a given value and issue a write memory barrier - after. This - function exists to allow an optimal memset to be performed when - memory is known to be cached or write-combine. -@Input a void pointer to the memory to be set -@Input b byte containing the value to be set -@Input c the number of bytes to be set to the given value -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#if !defined(SERVICES_SC) -#define OSCachedMemSetWMB(a,b,c) \ - do { \ - if ((c) != 0) \ - { \ - (void) memset((a), (b), (c)); \ - OSWriteMemoryBarrier(a); \ - } \ - } while (false) -#else -#define OSCachedMemSetWMB(a,b,c) \ - do { \ - (void) memset((a), (b), (c)); \ - OSWriteMemoryBarrier(); \ - } while (false) -#endif /* !defined(SERVICES_SC) */ -/**************************************************************************/ /*! -@Function OSCachedMemCopy -@Description Copy values from one area of memory, to another, when both - mappings are known to be cached or write-combine and issue - a write memory barrier after. - This function exists to allow an optimal memcpy to be - performed when memory is known to be cached or write-combine. -@Input a void pointer to the destination memory -@Input b void pointer to the source memory -@Input c the number of bytes to be copied -@Return Pointer to the destination memory. - */ /**************************************************************************/ -#if !defined(SERVICES_SC) -#define OSCachedMemCopyWMB(a,b,c) \ - do { \ - if ((c) != 0) \ - { \ - (void) memcpy((a), (b), (c)); \ - OSWriteMemoryBarrier(a); \ - } \ - } while (false) -#else -#define OSCachedMemCopyWMB(a,b,c) \ - do { \ - (void) memcpy((a), (b), (c)); \ - OSWriteMemoryBarrier(); \ - } while (false) -#endif /* !defined(SERVICES_SC) */ -#endif /* defined(__KERNEL__) */ - -/**************************************************************************/ /*! -@Function OSStringLCopy -@Description Copy at most uDataSize-1 bytes from pszSrc to pszDest. - If no null byte ('\0') is contained within the first uDataSize-1 - characters of the source string, the destination string will be - truncated. If the length of the source string is less than uDataSize - an additional NUL byte will be copied to the destination string - to ensure that the string is NUL-terminated. -@Input a char pointer to the destination string -@Input b const char pointer to the source string -@Input c the maximum number of bytes to be copied -@Return Size of the source string - */ /**************************************************************************/ -#if defined(__QNXNTO__) || (defined(__linux__) && defined(__KERNEL__) && !defined(DEBUG)) -#define OSStringLCopy(a,b,c) strlcpy((a), (b), (c)) -#else /* defined(__QNXNTO__) ... */ -#define OSStringLCopy(a,b,c) StringLCopy((a), (b), (c)) -#endif /* defined(__QNXNTO__) ... */ - -#ifdef __cplusplus -} -#endif - -#endif /* OSFUNC_COMMON_H */ - -/****************************************************************************** - End of file (osfunc_common.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/osfunc_x86.c b/drivers/gpu/drm/img-rogue/1.17/osfunc_x86.c deleted file mode 100644 index 2c271d8f4c6f0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osfunc_x86.c +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title x86 specific OS functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Processor specific OS functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv_error.h" -#include "img_types.h" -#include "img_defs.h" -#include "osfunc.h" -#include "pvr_debug.h" - -static void x86_flush_cache_range(const void *pvStart, const void *pvEnd) -{ - IMG_BYTE *pbStart = (IMG_BYTE *)pvStart; - IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd; - IMG_BYTE *pbBase; - - pbEnd = (IMG_BYTE *)PVR_ALIGN((uintptr_t)pbEnd, - (uintptr_t)boot_cpu_data.x86_clflush_size); - - mb(); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,168)) - __uaccess_begin(); -#endif - - for (pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size) - { - clflush(pbBase); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,168)) - __uaccess_end(); -#endif - - mb(); -} - -void OSCPUCacheFlushRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(sCPUPhysStart); - PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd); - - x86_flush_cache_range(pvVirtStart, pvVirtEnd); -} - -void OSCPUCacheCleanRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(sCPUPhysStart); - PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd); - - /* No clean feature on x86 */ - x86_flush_cache_range(pvVirtStart, pvVirtEnd); -} - -void OSCPUCacheInvalidateRangeKM(PVRSRV_DEVICE_NODE *psDevNode, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd) -{ - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(sCPUPhysStart); - PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd); - - /* No invalidate-only support */ - x86_flush_cache_range(pvVirtStart, pvVirtEnd); -} - -OS_CACHE_OP_ADDR_TYPE OSCPUCacheOpAddressType(void) -{ - return OS_CACHE_OP_ADDR_TYPE_VIRTUAL; -} - -void OSUserModeAccessToPerfCountersEn(void) -{ - /* Not applicable to x86 architecture. */ -} - -IMG_BOOL OSIsWriteCombineUnalignedSafe(void) -{ - return IMG_TRUE; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/oskm_apphint.h b/drivers/gpu/drm/img-rogue/1.17/oskm_apphint.h deleted file mode 100644 index 78d40407dcf48..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/oskm_apphint.h +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************/ /*! -@File oskm_apphint.h -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS-independent interface for retrieving KM apphints -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#if defined(__linux__) -#include "km_apphint.h" -#include "device.h" -#else -#include "services_client_porting.h" -#endif -#if !defined(OSKM_APPHINT_H) -#define OSKM_APPHINT_H - -/*! Supplied to os_get_km_apphint_XXX() functions when the param/AppHint is - * applicable to all devices and not a specific device. Typically used - * for server-wide build and module AppHints. - */ -#define APPHINT_NO_DEVICE (NULL) - -#if defined(__linux__) && !defined(DOXYGEN) -static INLINE IMG_UINT os_get_km_apphint_UINT32(PVRSRV_DEVICE_NODE *device, void *state, APPHINT_ID id, const IMG_UINT32 *pAppHintDefault, IMG_UINT32 *pVal) { - return !pvr_apphint_get_uint32(device, id, pVal); -} -static INLINE IMG_UINT os_get_km_apphint_UINT64(PVRSRV_DEVICE_NODE *device, void *state, APPHINT_ID id, const IMG_UINT64 *pAppHintDefault, IMG_UINT64 *pVal) { - return !pvr_apphint_get_uint64(device, id, pVal); -} -static INLINE IMG_UINT os_get_km_apphint_BOOL(PVRSRV_DEVICE_NODE *device, void *state, APPHINT_ID id, const IMG_BOOL *pAppHintDefault, IMG_BOOL *pVal) { - return !pvr_apphint_get_bool(device, id, pVal); -} -static INLINE IMG_UINT os_get_km_apphint_STRING(PVRSRV_DEVICE_NODE *device, void *state, APPHINT_ID id, const IMG_CHAR *pAppHintDefault, IMG_CHAR *buffer, size_t size) { - return !pvr_apphint_get_string(device, id, buffer, size); -} - -#define OSGetKMAppHintUINT32(device, state, name, appHintDefault, value) \ - os_get_km_apphint_UINT32(device, state, APPHINT_ID_ ## name, appHintDefault, value) - -#define OSGetKMAppHintUINT64(device, state, name, appHintDefault, value) \ - os_get_km_apphint_UINT64(device, state, APPHINT_ID_ ## name, appHintDefault, value) - -#define OSGetKMAppHintBOOL(device, state, name, appHintDefault, value) \ - os_get_km_apphint_BOOL(device, state, APPHINT_ID_ ## name, appHintDefault, value) - -#define OSGetKMAppHintSTRING(device, state, name, appHintDefault, buffer, size) \ - os_get_km_apphint_STRING(device, state, APPHINT_ID_ ## name, appHintDefault, buffer, size) - - -#define OSCreateKMAppHintState(state) \ - PVR_UNREFERENCED_PARAMETER(state) - -#define OSFreeKMAppHintState(state) \ - PVR_UNREFERENCED_PARAMETER(state) - -#else /* defined(__linux__) && !defined(DOXYGEN) */ - -/**************************************************************************/ /*! -@def OSGetKMAppHintUINT32(state, name, appHintDefault, value) -@Description Interface for retrieval of uint32 km app hint. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVGetAppHint() declared in - services_client_porting.h, effectively making it 'shared' code. -@Input device Device node -@Input state App hint state -@Input name Name used to identify app hint -@Input appHintDefault Default value to be returned if no - app hint is found. -@Output value Pointer to returned app hint value. - */ /**************************************************************************/ -#define OSGetKMAppHintUINT32(device, state, name, appHintDefault, value) \ - PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value) - -/**************************************************************************/ /*! -@def OSGetKMAppHintUINT64(state, name, appHintDefault, value) -@Description Interface for retrieval of uint64 km app hint. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVGetAppHint() declared in - services_client_porting.h, effectively making it 'shared' code. -@Input device Device node -@Input state App hint state -@Input name Name used to identify app hint -@Input appHintDefault Default value to be returned if no - app hint is found. -@Output value Pointer to returned app hint value. - */ /**************************************************************************/ -#define OSGetKMAppHintUINT64(device, state, name, appHintDefault, value) \ - PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value) - -/**************************************************************************/ /*! -@def OSGetKMAppHintBOOL(state, name, appHintDefault, value) -@Description Interface for retrieval of IMG_BOOL km app hint. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVGetAppHint() declared in - services_client_porting.h, effectively making it 'shared' code. -@Input device Device node -@Input state App hint state -@Input name Name used to identify app hint -@Input appHintDefault Default value to be returned if no - app hint is found. -@Output value Pointer to returned app hint value. - */ /**************************************************************************/ -#define OSGetKMAppHintBOOL(device, state, name, appHintDefault, value) \ - PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value) - -/**************************************************************************/ /*! -@def OSGetKMAppHintSTRING(state, name, appHintDefault, buffer, size) -@Description Interface for retrieval of string km app hint. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVGetAppHint() declared in - services_client_porting.h, effectively making it 'shared' code. -@Input device Device node -@Input state App hint state -@Input name Name used to identify app hint -@Input appHintDefault Default value to be returned if no - app hint is found. -@Output buffer Buffer used to return app hint string. -@Input size Size of the buffer. - */ /**************************************************************************/ -#define OSGetKMAppHintSTRING(device, state, name, appHintDefault, buffer, size) \ - (PVR_UNREFERENCED_PARAMETER(size), PVRSRVGetAppHint(state, # name, IMG_STRING_TYPE, appHintDefault, buffer)) - -/**************************************************************************/ /*! -@def OSCreateKMAppHintState(state) -@Description Creates the app hint state. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVCreateAppHintState() declared in - services_client_porting.h, effectively making it 'shared' code. -@Output state App hint state - */ /**************************************************************************/ -#define OSCreateKMAppHintState(state) \ - PVRSRVCreateAppHintState(IMG_SRV_UM, 0, state) - -/**************************************************************************/ /*! -@def OSFreeKMAppHintState -@Description Free the app hint state. - For non-linux operating systems, this macro implements a call - from server code to PVRSRVCreateAppHintState() declared in - services_client_porting.h, effectively making it 'shared' code. -@Output state App hint state - */ /**************************************************************************/ -#define OSFreeKMAppHintState(state) \ - PVRSRVFreeAppHintState(IMG_SRV_UM, state) - -#endif /* defined(__linux__) */ - -#endif /* OSKM_APPHINT_H */ - -/****************************************************************************** - End of file (oskm_apphint.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/osmmap.h b/drivers/gpu/drm/img-rogue/1.17/osmmap.h deleted file mode 100644 index 40a509d194404..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osmmap.h +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS Interface for mapping PMRs into CPU space. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS abstraction for the mmap2 interface for mapping PMRs into - User Mode memory -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 OSMMAP_H -#define OSMMAP_H - -#include - -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" - -/*************************************************************************/ /*! -@Function OSMMapPMR -@Description Maps the specified PMR into CPU memory so that it may be - accessed by the user process. - Whether the memory is mapped read only, read/write, or not at - all, is dependent on the PMR itself. - The PMR handle is opaque to the user, and lower levels of this - stack ensure that the handle is private to this process, such - that this API cannot be abused to gain access to other people's - PMRs. The OS implementation of this function should return the - virtual address and length for the User to use. The "PrivData" - is to be stored opaquely by the caller (N.B. he should make no - assumptions, in particular, NULL is a valid handle) and given - back to the call to OSMUnmapPMR. - The OS implementation is free to use the PrivData handle for - any purpose it sees fit. -@Input hBridge The bridge handle. -@Input hPMR The handle of the PMR to be mapped. -@Input uiPMRLength The size of the PMR. -@Input uiFlags Flags indicating how the mapping should - be done (read-only, etc). These may not - be honoured if the PMR does not permit - them. -@Output phOSMMapPrivDataOut Returned private data. -@Output ppvMappingAddressOut The returned mapping. -@Output puiMappingLengthOut The size of the returned mapping. -@Return PVRSRV_OK on success, failure code otherwise. - */ /*************************************************************************/ -PVRSRV_ERROR -OSMMapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiPMRLength, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE *phOSMMapPrivDataOut, - void **ppvMappingAddressOut, - size_t *puiMappingLengthOut); - -/*************************************************************************/ /*! -@Function OSMUnmapPMR -@Description Unmaps the specified PMR from CPU memory. - This function is the counterpart to OSMMapPMR. - The caller is required to pass the PMR handle back in along - with the same 3-tuple of information that was returned by the - call to OSMMapPMR in phOSMMapPrivDataOut. - It is possible to unmap only part of the original mapping - with this call, by specifying only the address range to be - unmapped in pvMappingAddress and uiMappingLength. -@Input hBridge The bridge handle. -@Input hPMR The handle of the PMR to be unmapped. -@Input hOSMMapPrivData The OS private data of the mapping. -@Input pvMappingAddress The address to be unmapped. -@Input uiMappingLength The size to be unmapped. -@Return PVRSRV_OK on success, failure code otherwise. - */ /*************************************************************************/ -void -OSMUnmapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_HANDLE hOSMMapPrivData, - void *pvMappingAddress, - size_t uiMappingLength); - -#endif /* OSMMAP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/osmmap_stub.c b/drivers/gpu/drm/img-rogue/1.17/osmmap_stub.c deleted file mode 100644 index 74bad7073c58a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/osmmap_stub.c +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS abstraction for the mmap2 interface for mapping PMRs into - User Mode memory -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* our exported API */ -#include "osmmap.h" - -/* include/ */ -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -/* services/include/ */ - -/* services/include/srvhelper/ */ -#include "ra.h" - -#include "pmr.h" - -PVRSRV_ERROR -OSMMapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_DEVMEM_SIZE_T uiPMRSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_HANDLE *phOSMMapPrivDataOut, - void **ppvMappingAddressOut, - size_t *puiMappingLengthOut) -{ - PVRSRV_ERROR eError; - PMR *psPMR; - void *pvKernelAddress; - size_t uiLength; - IMG_HANDLE hPriv; - - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(uiFlags); - - /* - Normally this function would mmap a PMR into the memory space of - user process, but in this case we're taking a PMR and mapping it - into kernel virtual space. We keep the same function name for - symmetry as this allows the higher layers of the software stack - to not care whether they are user mode or kernel - */ - - psPMR = hPMR; - - if (PMR_IsSparse(psPMR)) - { - eError = PMRAcquireSparseKernelMappingData(psPMR, - 0, - 0, - &pvKernelAddress, - &uiLength, - &hPriv); - } - else - { - eError = PMRAcquireKernelMappingData(psPMR, - 0, - 0, - &pvKernelAddress, - &uiLength, - &hPriv); - } - if (eError != PVRSRV_OK) - { - goto e0; - } - - *phOSMMapPrivDataOut = hPriv; - *ppvMappingAddressOut = pvKernelAddress; - *puiMappingLengthOut = uiLength; - - /* MappingLength might be rounded up to page size */ - PVR_ASSERT(*puiMappingLengthOut >= uiPMRSize); - - return PVRSRV_OK; - - /* - error exit paths follow - */ - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -void -OSMUnmapPMR(IMG_HANDLE hBridge, - IMG_HANDLE hPMR, - IMG_HANDLE hOSMMapPrivData, - void *pvMappingAddress, - size_t uiMappingLength) -{ - PMR *psPMR; - - PVR_UNREFERENCED_PARAMETER(hBridge); - PVR_UNREFERENCED_PARAMETER(pvMappingAddress); - PVR_UNREFERENCED_PARAMETER(uiMappingLength); - - psPMR = hPMR; - PMRReleaseKernelMappingData(psPMR, - hOSMMapPrivData); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/ospvr_gputrace.h b/drivers/gpu/drm/img-rogue/1.17/ospvr_gputrace.h deleted file mode 100644 index 0d6b89f23e3b1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ospvr_gputrace.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************/ /*! -@File ospvr_gputrace.h -@Title PVR GPU Trace module common environment interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_GPUTRACE_H_ -#define PVR_GPUTRACE_H_ - -#include "img_types.h" -#include "img_defs.h" -#include "rgx_hwperf.h" -#include "device.h" - -#if defined(__linux__) - -void PVRGpuTraceEnqueueEvent( - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32FirmwareCtx, - IMG_UINT32 ui32ExternalJobRef, - IMG_UINT32 ui32InternalJobRef, - RGX_HWPERF_KICK_TYPE eKickType); - -/* Early initialisation of GPU Trace events logic. - * This function is called on *driver* initialisation. */ -PVRSRV_ERROR PVRGpuTraceSupportInit(void); - -/* GPU Trace resources final cleanup. - * This function is called on driver de-initialisation. */ -void PVRGpuTraceSupportDeInit(void); - -/* Initialisation for AppHints callbacks. - * This function is called during the late stage of driver initialisation but - * before the device initialisation but after the debugfs sub-system has been - * initialised. */ -void PVRGpuTraceInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode); - -/* Per-device initialisation of the GPU Trace resources */ -PVRSRV_ERROR PVRGpuTraceInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -/* Per-device cleanup for the GPU Trace resources. */ -void PVRGpuTraceDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -/* Enables the gpu trace sub-system for a given device. */ -PVRSRV_ERROR PVRGpuTraceSetEnabled( - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bNewValue); - -/* Returns IMG_TRUE if the gpu trace sub-system has been enabled (but not - * necessarily initialised). */ -IMG_BOOL PVRGpuTraceIsEnabled(void); - -/* Performs some initialisation steps if the feature was enabled - * on driver startup. */ -void PVRGpuTraceInitIfEnabled(PVRSRV_DEVICE_NODE *psDeviceNode); - -/* FTrace events callbacks interface */ - -void PVRGpuTraceEnableUfoCallback(void); -void PVRGpuTraceDisableUfoCallback(void); - -void PVRGpuTraceEnableFirmwareActivityCallback(void); -void PVRGpuTraceDisableFirmwareActivityCallback(void); - -#else /* defined(__linux__) */ - -static inline void PVRGpuTraceEnqueueEvent( - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32FirmwareCtx, - IMG_UINT32 ui32ExternalJobRef, - IMG_UINT32 ui32InternalJobRef, - RGX_HWPERF_KICK_TYPE eKickType) -{ - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(ui32ExternalJobRef); - PVR_UNREFERENCED_PARAMETER(ui32InternalJobRef); - PVR_UNREFERENCED_PARAMETER(eKickType); -} - -static inline PVRSRV_ERROR PVRGpuTraceSupportInit(void) { - return PVRSRV_OK; -} - -static inline void PVRGpuTraceSupportDeInit(void) {} - -static inline void PVRGpuTraceInitAppHintCallbacks( - const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -static inline PVRSRV_ERROR PVRGpuTraceInitDevice( - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - return PVRSRV_OK; -} - -static inline void PVRGpuTraceDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -static inline PVRSRV_ERROR PVRGpuTraceSetEnabled( - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bNewValue) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(bNewValue); - return PVRSRV_OK; -} - -static inline IMG_BOOL PVRGpuTraceIsEnabled(void) -{ - return IMG_FALSE; -} - -static inline void PVRGpuTraceInitIfEnabled(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -static inline void PVRGpuTraceEnableUfoCallback(void) {} -static inline void PVRGpuTraceDisableUfoCallback(void) {} - -static inline void PVRGpuTraceEnableFirmwareActivityCallback(void) {} -static inline void PVRGpuTraceDisableFirmwareActivityCallback(void) {} - -#endif /* defined(__linux__) */ - -#endif /* PVR_GPUTRACE_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdump.h b/drivers/gpu/drm/img-rogue/1.17/pdump.h deleted file mode 100644 index 3ef71846446e2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdump.h +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SERVICES_PDUMP_H -#define SERVICES_PDUMP_H - -#include "img_types.h" -#include "services_km.h" - - -/* A PDump out2.txt script is made up of 3 sections from three buffers: - * * - * - Init phase buffer - holds PDump data written during driver - * initialisation, non-volatile. - * - Main phase buffer - holds PDump data written after driver init, - * volatile. - * - Deinit phase buffer - holds PDump data needed to shutdown HW/play back, - * written only during driver initialisation using - * the DEINIT flag. - * - * Volatile in this sense means that the buffer is drained and cleared when - * the pdump capture application connects and transfers the data to file. - * - * The PDump sub-system uses the driver state (init/post-init), whether - * the pdump capture application is connected or not (capture range set/unset) - * and, if pdump connected whether the frame is in the range set, to decide - * which of the 3 buffers to write the PDump data. Hence there are several - * key time periods in the lifetime of the kernel driver that is enabled - * with PDUMP=1 (flag XX labels below time line): - * - * Events:load init pdump enter exit pdump - * driver done connects range range disconnects - * |__________________|____________|__________|______________|____________|______ . . . - * State: | init phase | no capture | <- capture client connected -> | no capture - * | | | | - * |__________________|____________|______________________________________|_____ . . . - * Flag: | CT,DI | NONE,CT,PR | NONE,CT,PR | See no - * | Never NONE or PR | Never DI | Never DI | capture - * |__________________|____________|______________________________________|_____ . . . - * Write | NONE -undef | -No write | -No write | -Main buf | -No write | See no - * buffer | CT -Init buf | -Main buf | -Main buf | -Main buf | -Main buf | capture - * | PR -undef | -Init buf | -undef | -Init & Main | -undef | - * | DI -Deinit buf | -undef | -undef | -undef | -undef | - * |__________________|____________|___________|______________|___________|_____ . . . - * - * Note: The time line could repeat if the pdump capture application is - * disconnected and reconnected without unloading the driver module. - * - * The DEINIT (DI) | CONTINUOUS (CT) | PERSISTENT (PR) flags must never - * be OR'd together and given to a PDump call since undefined behaviour may - * result and produce an invalid PDump which does not play back cleanly. - * - * The decision on which flag to use comes down to which time period the - * client or server driver makes the PDump write call AND the nature/purpose - * of the data. - * - * Note: This is a simplified time line, not all conditions represented. - * - */ - -typedef IMG_UINT32 PDUMP_FLAGS_T; - -#define PDUMP_FLAGS_NONE PDUMP_NONE /* - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ - #else - #include - #endif /* __linux__ */ -#endif /* PDUMP */ - -/* services/srvkm/include/ */ -#include "device.h" - -/* include/ */ -#include "pvrsrv_error.h" - - -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - -#include "connection_server.h" -/* Pull in pdump flags from services include */ -#include "pdump.h" -#include "pdumpdefs.h" - -/* Define this to enable the PDUMP_HERE trace in the server */ -#undef PDUMP_TRACE - -#if defined(PDUMP_TRACE) -#define PDUMP_HERE_VAR __maybe_unused IMG_UINT32 here = 0; -#define PDUMP_HERE(a) { here = (a); if (ui32Flags & PDUMP_FLAGS_DEBUG) PVR_DPF((PVR_DBG_WARNING, "HERE %d", (a))); } -#define PDUMP_HEREA(a) { here = (a); PVR_DPF((PVR_DBG_WARNING, "HERE ALWAYS %d", (a))); } -#else -#define PDUMP_HERE_VAR __maybe_unused IMG_UINT32 here = 0; -#define PDUMP_HERE(a) here = (a); -#define PDUMP_HEREA(a) here = (a); -#endif - -#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0 -#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0 - -/* Invalid value for PDump block number */ -#define PDUMP_BLOCKNUM_INVALID IMG_UINT32_MAX - -typedef struct _PDUMP_CONNECTION_DATA_ PDUMP_CONNECTION_DATA; - -/* PDump transition events */ -typedef enum _PDUMP_TRANSITION_EVENT_ -{ - PDUMP_TRANSITION_EVENT_NONE, /* No event */ - PDUMP_TRANSITION_EVENT_BLOCK_FINISHED, /* Block mode event, current PDump-block has finished */ - PDUMP_TRANSITION_EVENT_BLOCK_STARTED, /* Block mode event, new PDump-block has started */ - PDUMP_TRANSITION_EVENT_RANGE_ENTERED, /* Transition into capture range */ - PDUMP_TRANSITION_EVENT_RANGE_EXITED, /* Transition out of capture range */ -} PDUMP_TRANSITION_EVENT; - -typedef PVRSRV_ERROR (*PFN_PDUMP_TRANSITION)(void *pvData, void *pvDevice, PDUMP_TRANSITION_EVENT eEvent, IMG_UINT32 ui32PDumpFlags); -typedef void (*PFN_PDUMP_SYNCBLOCKS)(PVRSRV_DEVICE_NODE *psDevNode, void *pvData, PDUMP_TRANSITION_EVENT eEvent); - -typedef PVRSRV_ERROR (*PFN_PDUMP_TRANSITION_FENCE_SYNC)(void *pvData, PDUMP_TRANSITION_EVENT eEvent); - -#ifdef PDUMP - -/*! Macro used to record a panic in the PDump script stream */ -#define PDUMP_PANIC(_dev, _id, _msg) do \ - { PVRSRV_ERROR _eE;\ - _eE = PDumpPanic((_dev), ((RGX_PDUMP_PANIC_ ## _id) & 0xFFFF), _msg, __func__, __LINE__); \ - PVR_LOG_IF_ERROR(_eE, "PDumpPanic");\ - MSC_SUPPRESS_4127\ - } while (0) - -/*! Macro used to record a driver error in the PDump script stream to invalidate the capture */ -#define PDUMP_ERROR(_dev, _err, _msg) \ - (void)PDumpCaptureError((_dev), _err, _msg, __func__, __LINE__) - -#define SZ_MSG_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE -#define SZ_SCRIPT_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE -#define SZ_FILENAME_SIZE_MAX (PVRSRV_PDUMP_MAX_FILENAME_SIZE+sizeof(PDUMP_PARAM_N_FILE_NAME)) - -#define PDUMP_GET_SCRIPT_STRING() \ - IMG_HANDLE hScript; \ - void *pvScriptAlloc; \ - IMG_UINT32 ui32MaxLen = SZ_SCRIPT_SIZE_MAX-1; \ - pvScriptAlloc = OSAllocMem( SZ_SCRIPT_SIZE_MAX ); \ - if (!pvScriptAlloc) \ - { \ - PVR_DPF((PVR_DBG_ERROR, "PDUMP_GET_SCRIPT_STRING() failed to allocate memory for script buffer")); \ - return PVRSRV_ERROR_OUT_OF_MEMORY; \ - } \ - \ - hScript = (IMG_HANDLE) pvScriptAlloc; - -#define PDUMP_GET_MSG_STRING() \ - IMG_CHAR *pszMsg; \ - void *pvMsgAlloc; \ - IMG_UINT32 ui32MaxLen = SZ_MSG_SIZE_MAX-1; \ - pvMsgAlloc = OSAllocMem( SZ_MSG_SIZE_MAX ); \ - if (!pvMsgAlloc) \ - { \ - PVR_DPF((PVR_DBG_ERROR, "PDUMP_GET_MSG_STRING() failed to allocate memory for message buffer")); \ - return PVRSRV_ERROR_OUT_OF_MEMORY; \ - } \ - pszMsg = (IMG_CHAR *)pvMsgAlloc; - -#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \ - IMG_HANDLE hScript; \ - IMG_CHAR *pszFileName; \ - IMG_UINT32 ui32MaxLenScript = SZ_SCRIPT_SIZE_MAX-1; \ - void *pvScriptAlloc; \ - void *pvFileAlloc; \ - pvScriptAlloc = OSAllocMem( SZ_SCRIPT_SIZE_MAX ); \ - if (!pvScriptAlloc) \ - { \ - PVR_DPF((PVR_DBG_ERROR, "PDUMP_GET_SCRIPT_AND_FILE_STRING() failed to allocate memory for script buffer")); \ - return PVRSRV_ERROR_OUT_OF_MEMORY; \ - } \ - \ - hScript = (IMG_HANDLE) pvScriptAlloc; \ - pvFileAlloc = OSAllocMem( SZ_FILENAME_SIZE_MAX ); \ - if (!pvFileAlloc) \ - { \ - PVR_DPF((PVR_DBG_ERROR, "PDUMP_GET_SCRIPT_AND_FILE_STRING() failed to allocate memory for filename buffer")); \ - OSFreeMem(pvScriptAlloc); \ - return PVRSRV_ERROR_OUT_OF_MEMORY; \ - } \ - pszFileName = (IMG_CHAR *)pvFileAlloc; - -#define PDUMP_RELEASE_SCRIPT_STRING() \ - if (pvScriptAlloc) \ - { \ - OSFreeMem(pvScriptAlloc); \ - pvScriptAlloc = NULL; \ - } - -#define PDUMP_RELEASE_MSG_STRING() \ - if (pvMsgAlloc) \ - { \ - OSFreeMem(pvMsgAlloc); \ - pvMsgAlloc = NULL; \ - } - -#define PDUMP_RELEASE_FILE_STRING() \ - if (pvFileAlloc) \ - { \ - OSFreeMem(pvFileAlloc); \ - pvFileAlloc = NULL; \ - } - -#define PDUMP_RELEASE_SCRIPT_AND_FILE_STRING() \ - if (pvScriptAlloc) \ - { \ - OSFreeMem(pvScriptAlloc); \ - pvScriptAlloc = NULL; \ - } \ - if (pvFileAlloc) \ - { \ - OSFreeMem(pvFileAlloc); \ - pvFileAlloc = NULL; \ - } - - -/* Shared across pdump_x files */ -PVRSRV_ERROR PDumpInitCommon(void); -void PDumpDeInitCommon(void); -PVRSRV_ERROR PDumpReady(void); -void PDumpGetParameterZeroPageInfo(PDUMP_FILEOFFSET_T *puiZeroPageOffset, - size_t *puiZeroPageSize, - const IMG_CHAR **ppszZeroPageFilename); - -void PDumpConnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode); -void PDumpDisconnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode); - -void PDumpStopInitPhase(PVRSRV_DEVICE_NODE *psDeviceNode); -PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Frame); -PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32* pui32Frame); -PVRSRV_ERROR PDumpCommentKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CommentSize, - IMG_CHAR *pszComment, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Mode, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, - IMG_UINT32 ui32Interval, - IMG_UINT32 ui32MaxParamFileSize); - - -PVRSRV_ERROR PDumpReg32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegLabelToReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegDst, - IMG_UINT32 ui32RegSrc, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpPhysHandleToInternalVar64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszInternalVar, - IMG_HANDLE hPdumpPages, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpMemLabelToInternalVar64(IMG_CHAR *pszInternalVar, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpInternalVarToMemLabel(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpWriteVarORValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PDumpWriteVarANDValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PDumpWriteVarSHRValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PDumpWriteVarORVarOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszInternalVar2, - const IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PDumpWriteVarANDVarOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszInternalVar2, - const IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PDumpInternalVarToReg32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpInternalVarToReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpMemLabelToMem32(PMR *psPMRSource, - PMR *psPMRDest, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpMemLabelToMem64(PMR *psPMRSource, - PMR *psPMRDest, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegLabelToMem32(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegLabelToMem64(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegLabelToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpSAW(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszDevSpaceName, - IMG_UINT32 ui32HPOffsetBytes, - IMG_UINT32 ui32NumSaveBytes, - IMG_CHAR *pszOutfileName, - IMG_UINT32 ui32OutfileOffsetByte, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR PDumpRegPolKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator); - - -/**************************************************************************/ /*! -@Function PDumpImageDescriptor -@Description PDumps image data out as an IMGBv2 data section -@Input psDeviceNode Pointer to device node. -@Input ui32MMUContextID PDUMP MMU context ID. -@Input pszSABFileName Pointer to string containing file name of - Image being SABed -@Input sData GPU virtual address of this surface. -@Input ui32DataSize Image data size -@Input ui32LogicalWidth Image logical width -@Input ui32LogicalHeight Image logical height -@Input ui32PhysicalWidth Image physical width -@Input ui32PhysicalHeight Image physical height -@Input ePixFmt Image pixel format -@Input eFBCompression FB compression mode -@Input paui32FBCClearColour FB clear colour (Only applicable to FBC surfaces) -@Input eFBCSwizzle FBC channel swizzle (Only applicable to FBC surfaces) -@Input sHeader GPU virtual address of the headers of this - surface (Only applicable to FBC surfaces) -@Input ui32HeaderSize Header size (Only applicable to FBC surfaces) -@Input ui32PDumpFlags PDUMP flags -@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -*/ /***************************************************************************/ -PVRSRV_ERROR PDumpImageDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags); - -/**************************************************************************/ /*! -@Function PDumpDataDescriptor -@Description PDumps non-image data out as an IMGCv1 data section -@Input psDeviceNode Pointer to device node. -@Input ui32MMUContextID PDUMP MMU context ID. -@Input pszSABFileName Pointer to string containing file name of - Data being SABed -@Input sData GPU virtual address of this data. -@Input ui32DataSize Data size -@Input ui32HeaderType Header type -@Input ui32ElementType Data element type -@Input ui32ElementCount Number of data elements -@Input ui32PDumpFlags PDUMP flags -@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -*/ /***************************************************************************/ -PVRSRV_ERROR PDumpDataDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags); - - -PVRSRV_ERROR PDumpReadRegKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32Address, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32PDumpFlags); - -__printf(3, 4) -PVRSRV_ERROR PDumpCommentWithFlags(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - IMG_CHAR* pszFormat, - ...); - -PVRSRV_ERROR PDumpCommentWithFlagsVA(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - const IMG_CHAR * pszFormat, - va_list args); - -PVRSRV_ERROR PDumpPanic(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PanicNo, - IMG_CHAR* pszPanicMsg, - const IMG_CHAR* pszPPFunc, - IMG_UINT32 ui32PPline); - -PVRSRV_ERROR PDumpCaptureError(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_ERROR ui32ErrorNo, - IMG_CHAR* pszErrorMsg, - const IMG_CHAR* pszPPFunc, - IMG_UINT32 ui32PPline); - -PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame); - -PVRSRV_ERROR PDumpGetStateKM(IMG_UINT64 *ui64State); - -PVRSRV_ERROR PDumpForceCaptureStopKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -PVRSRV_ERROR PDumpRegRead32ToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegOffset, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegRead32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - const IMG_UINT32 dwRegOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegRead64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - const IMG_UINT32 dwRegOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpRegRead64ToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_CHAR *pszInternalVar, - const IMG_UINT32 dwRegOffset, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpIDLWithFlags(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Clocks, - IMG_UINT32 ui32Flags); -PVRSRV_ERROR PDumpIDL(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Clocks); - -PVRSRV_ERROR PDumpRegBasedCBP(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32WPosVal, - IMG_UINT32 ui32PacketSize, - IMG_UINT32 ui32BufferSize, - IMG_UINT32 ui32Flags); - -PVRSRV_ERROR PDumpTRG(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszMemSpace, - IMG_UINT32 ui32MMUCtxID, - IMG_UINT32 ui32RegionID, - IMG_BOOL bEnable, - IMG_UINT64 ui64VAddr, - IMG_UINT64 ui64LenBytes, - IMG_UINT32 ui32XStride, - IMG_UINT32 ui32Flags); - -void PDumpLock(void); -void PDumpUnlock(void); - -PVRSRV_ERROR PDumpRegCondStr(IMG_CHAR **ppszPDumpCond, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator); - -PVRSRV_ERROR PDumpInternalValCondStr(IMG_CHAR **ppszPDumpCond, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator); - -PVRSRV_ERROR PDumpIfKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags); -PVRSRV_ERROR PDumpElseKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags); -PVRSRV_ERROR PDumpFiKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags); -PVRSRV_ERROR PDumpStartDoLoopKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags); -PVRSRV_ERROR PDumpEndDoWhileLoopKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpWhileCond, - IMG_UINT32 ui32PDumpFlags); -PVRSRV_ERROR PDumpCOMCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags, - const IMG_CHAR *pszPDump); - -void PDumpPowerTransitionStart(PVRSRV_DEVICE_NODE *psDeviceNode); -void PDumpPowerTransitionEnd(PVRSRV_DEVICE_NODE *psDeviceNode); -IMG_BOOL PDumpCheckFlagsWrite(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags); - -/*! - * @name PDumpWriteParameter - * @brief General function for writing to PDump stream. Used - * mainly for memory dumps to parameter stream. - * Usually more convenient to use PDumpWriteScript below - * for the script stream. - * @param psDeviceNode - device PDump pertains to - * @param psui8Data - data to write - * @param ui32Size - size of write - * @param ui32Flags - PDump flags - * @param pui32FileOffset - on return contains the file offset to - * the start of the parameter data - * @param aszFilenameStr - pointer to at least a 20 char buffer to - * return the parameter filename - * @return error - */ -PVRSRV_ERROR PDumpWriteParameter(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 *psui8Data, IMG_UINT32 ui32Size, - IMG_UINT32 ui32Flags, IMG_UINT32* pui32FileOffset, - IMG_CHAR* aszFilenameStr); - -/*! - * @name PDumpWriteScript - * @brief Write an PDumpOS created string to the "script" output stream - * @param psDeviceNode - device PDump pertains to - * @param hString - PDump OS layer handle of string buffer to write - * @param ui32Flags - PDump flags - * @return IMG_TRUE on success. - */ -IMG_BOOL PDumpWriteScript(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hString, IMG_UINT32 ui32Flags); - -/**************************************************************************/ /*! -@Function PDumpSNPrintf -@Description Printf to OS-specific PDump state buffer. This function is - only called if PDUMP is defined. -@Input hBuf handle of buffer to write into -@Input ui32ScriptSizeMax maximum size of data to write (chars) -@Input pszFormat format string -@Return None -*/ /**************************************************************************/ -__printf(3, 4) -PVRSRV_ERROR PDumpSNPrintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...); - - -/* - PDumpWriteShiftedMaskedValue(): - - loads the "reference" address into an internal PDump register, - optionally shifts it right, - optionally shifts it left, - optionally masks it - then finally writes the computed value to the given destination address - - i.e. it emits pdump language equivalent to this expression: - - dest = ((&ref) >> SHRamount << SHLamount) & MASK -*/ -PVRSRV_ERROR -PDumpWriteShiftedMaskedValue(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDestRegspaceName, - const IMG_CHAR *pszDestSymbolicName, - IMG_DEVMEM_OFFSET_T uiDestOffset, - const IMG_CHAR *pszRefRegspaceName, - const IMG_CHAR *pszRefSymbolicName, - IMG_DEVMEM_OFFSET_T uiRefOffset, - IMG_UINT32 uiSHRAmount, - IMG_UINT32 uiSHLAmount, - IMG_UINT32 uiMask, - IMG_DEVMEM_SIZE_T uiWordSize, - IMG_UINT32 uiPDumpFlags); - -/* - PDumpWriteSymbAddress(): - writes the address of the "reference" to the offset given -*/ -PVRSRV_ERROR -PDumpWriteSymbAddress(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDestSpaceName, - IMG_DEVMEM_OFFSET_T uiDestOffset, - const IMG_CHAR *pszRefSymbolicName, - IMG_DEVMEM_OFFSET_T uiRefOffset, - const IMG_CHAR *pszPDumpDevName, - IMG_UINT32 ui32WordSize, - IMG_UINT32 ui32AlignShift, - IMG_UINT32 ui32Shift, - IMG_UINT32 uiPDumpFlags); - -/* Register the connection with the PDump subsystem */ -PVRSRV_ERROR -PDumpRegisterConnection(void *hSyncPrivData, - PFN_PDUMP_SYNCBLOCKS pfnPDumpSyncBlocks, - PDUMP_CONNECTION_DATA **ppsPDumpConnectionData); - -/* Unregister the connection with the PDump subsystem */ -void -PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData); - -/* Register for notification of PDump Transition into/out of capture range */ -PVRSRV_ERROR -PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PFN_PDUMP_TRANSITION pfnCallback, - void *hPrivData, - void *pvDevice, - void **ppvHandle); - -/* Unregister notification of PDump Transition */ -void -PDumpUnregisterTransitionCallback(void *pvHandle); - -PVRSRV_ERROR -PDumpRegisterTransitionCallbackFenceSync(void *hPrivData, - PFN_PDUMP_TRANSITION_FENCE_SYNC pfnCallback, - void **ppvHandle); - -void -PDumpUnregisterTransitionCallbackFenceSync(void *pvHandle); - -/* Notify PDump of a Transition into/out of capture range */ -PVRSRV_ERROR -PDumpTransition(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PDUMP_TRANSITION_EVENT eEvent, - IMG_UINT32 ui32PDumpFlags); - -/* Check if writing to a PDump file is permitted for the given device */ -IMG_BOOL PDumpIsDevicePermitted(PVRSRV_DEVICE_NODE *psDeviceNode); - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMP_LOCK(_ui32PDumpFlags) do \ - { if ((_ui32PDumpFlags & PDUMP_FLAGS_PDUMP_LOCK_HELD) == 0)\ - {\ - PDumpLock();\ - }\ - MSC_SUPPRESS_4127\ - } while (0) - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMP_UNLOCK(_ui32PDumpFlags) do \ - { if ((_ui32PDumpFlags & PDUMP_FLAGS_PDUMP_LOCK_HELD) == 0)\ - {\ - PDumpUnlock();\ - }\ - MSC_SUPPRESS_4127\ - } while (0) - -#define PDUMPINIT PDumpInitCommon -#define PDUMPDEINIT PDumpDeInitCommon -#define PDUMPREG32 PDumpReg32 -#define PDUMPREG64 PDumpReg64 -#define PDUMPREGREAD32 PDumpRegRead32 -#define PDUMPREGREAD64 PDumpRegRead64 -#define PDUMPCOMMENT(d, ...) PDumpCommentWithFlags(d, PDUMP_FLAGS_CONTINUOUS, __VA_ARGS__) -#define PDUMPCOMMENTWITHFLAGS PDumpCommentWithFlags -#define PDUMPREGPOL PDumpRegPolKM -#define PDUMPREGBASEDCBP PDumpRegBasedCBP -#define PDUMPENDINITPHASE PDumpStopInitPhase -#define PDUMPIDLWITHFLAGS PDumpIDLWithFlags -#define PDUMPIDL PDumpIDL -#define PDUMPPOWCMDSTART PDumpPowerTransitionStart -#define PDUMPPOWCMDEND PDumpPowerTransitionEnd -#define PDUMPCOM PDumpCOMCommand - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMP_BLKSTART(_ui32PDumpFlags) do \ - { PDUMP_LOCK(_ui32PDumpFlags);\ - _ui32PDumpFlags |= PDUMP_FLAGS_PDUMP_LOCK_HELD;\ - MSC_SUPPRESS_4127\ - } while (0) - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMP_BLKEND(_ui32PDumpFlags) do \ - { _ui32PDumpFlags &= ~PDUMP_FLAGS_PDUMP_LOCK_HELD;\ - PDUMP_UNLOCK(_ui32PDumpFlags);\ - MSC_SUPPRESS_4127\ - } while (0) - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMPIF(_dev,_msg,_ui32PDumpFlags) do \ - {PDUMP_BLKSTART(_ui32PDumpFlags);\ - PDumpIfKM(_dev,_msg,_ui32PDumpFlags);\ - MSC_SUPPRESS_4127\ - } while (0) - -#define PDUMPELSE PDumpElseKM - -/* _ui32PDumpFlags must be a variable in the local scope */ -#define PDUMPFI(_dev,_msg,_ui32PDumpFlags) do \ - { PDumpFiKM(_dev,_msg,_ui32PDumpFlags);\ - PDUMP_BLKEND(_ui32PDumpFlags);\ - MSC_SUPPRESS_4127\ - } while (0) - -#else -/* - We should be clearer about which functions can be called - across the bridge as this looks rather unbalanced -*/ - -/*! Macro used to record a panic in the PDump script stream */ -#define PDUMP_PANIC(_dev, _id, _msg) ((void)0) - -/*! Macro used to record a driver error in the PDump script stream to invalidate the capture */ -#define PDUMP_ERROR(_dev, _err, _msg) ((void)0) - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpInitCommon) -#endif -static INLINE PVRSRV_ERROR -PDumpInitCommon(void) -{ - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpConnectionNotify) -#endif -static INLINE void -PDumpConnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpDisconnectionNotify) -#endif -static INLINE void -PDumpDisconnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpLock) -#endif -static INLINE void -PDumpLock(void) -{ -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpUnlock) -#endif -static INLINE void -PDumpUnlock(void) -{ -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpStopInitPhase) -#endif -static INLINE void -PDumpStopInitPhase(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpSetFrameKM) -#endif -static INLINE PVRSRV_ERROR -PDumpSetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32Frame) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(ui32Frame); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpGetFrameKM) -#endif -static INLINE PVRSRV_ERROR -PDumpGetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32* pui32Frame) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(pui32Frame); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpCommentKM) -#endif -static INLINE PVRSRV_ERROR -PDumpCommentKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CommentSize, - IMG_CHAR *pszComment, - IMG_UINT32 ui32Flags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32CommentSize); - PVR_UNREFERENCED_PARAMETER(pszComment); - PVR_UNREFERENCED_PARAMETER(ui32Flags); - return PVRSRV_OK; -} - - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpSetDefaultCaptureParamsKM) -#endif -static INLINE PVRSRV_ERROR -PDumpSetDefaultCaptureParamsKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Mode, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, - IMG_UINT32 ui32Interval, - IMG_UINT32 ui32MaxParamFileSize) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32Mode); - PVR_UNREFERENCED_PARAMETER(ui32Start); - PVR_UNREFERENCED_PARAMETER(ui32End); - PVR_UNREFERENCED_PARAMETER(ui32Interval); - PVR_UNREFERENCED_PARAMETER(ui32MaxParamFileSize); - - return PVRSRV_OK; -} - - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpPanic) -#endif -static INLINE PVRSRV_ERROR -PDumpPanic(IMG_UINT32 ui32PanicNo, - IMG_CHAR* pszPanicMsg, - const IMG_CHAR* pszPPFunc, - IMG_UINT32 ui32PPline) -{ - PVR_UNREFERENCED_PARAMETER(ui32PanicNo); - PVR_UNREFERENCED_PARAMETER(pszPanicMsg); - PVR_UNREFERENCED_PARAMETER(pszPPFunc); - PVR_UNREFERENCED_PARAMETER(ui32PPline); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpCaptureError) -#endif -static INLINE PVRSRV_ERROR -PDumpCaptureError(PVRSRV_ERROR ui32ErrorNo, - IMG_CHAR* pszErrorMsg, - const IMG_CHAR* pszPPFunc, - IMG_UINT32 ui32PPline) -{ - PVR_UNREFERENCED_PARAMETER(ui32ErrorNo); - PVR_UNREFERENCED_PARAMETER(pszErrorMsg); - PVR_UNREFERENCED_PARAMETER(pszPPFunc); - PVR_UNREFERENCED_PARAMETER(ui32PPline); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpIsLastCaptureFrameKM) -#endif -static INLINE PVRSRV_ERROR -PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame) -{ - *pbIsLastCaptureFrame = IMG_FALSE; - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpGetStateKM) -#endif -static INLINE PVRSRV_ERROR -PDumpGetStateKM(IMG_UINT64 *ui64State) -{ - *ui64State = 0; - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpForceCaptureStopKM) -#endif -static INLINE PVRSRV_ERROR -PDumpForceCaptureStopKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpImageDescriptor) -#endif -static INLINE PVRSRV_ERROR -PDumpImageDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32MMUContextID); - PVR_UNREFERENCED_PARAMETER(pszSABFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32LogicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32LogicalHeight); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalHeight); - PVR_UNREFERENCED_PARAMETER(ePixFmt); - PVR_UNREFERENCED_PARAMETER(eMemLayout); - PVR_UNREFERENCED_PARAMETER(eFBCompression); - PVR_UNREFERENCED_PARAMETER(paui32FBCClearColour); - PVR_UNREFERENCED_PARAMETER(eFBCSwizzle); - PVR_UNREFERENCED_PARAMETER(sHeader); - PVR_UNREFERENCED_PARAMETER(ui32HeaderSize); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpDataDescriptor) -#endif -static INLINE PVRSRV_ERROR -PDumpDataDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32MMUContextID); - PVR_UNREFERENCED_PARAMETER(pszSABFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32ElementType); - PVR_UNREFERENCED_PARAMETER(ui32ElementCount); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpRegisterConnection) -#endif -static INLINE PVRSRV_ERROR -PDumpRegisterConnection(void *hSyncPrivData, - PFN_PDUMP_SYNCBLOCKS pfnPDumpSyncBlocks, - PDUMP_CONNECTION_DATA **ppsPDumpConnectionData) -{ - PVR_UNREFERENCED_PARAMETER(hSyncPrivData); - PVR_UNREFERENCED_PARAMETER(pfnPDumpSyncBlocks); - PVR_UNREFERENCED_PARAMETER(ppsPDumpConnectionData); - - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpUnregisterConnection) -#endif -static INLINE void -PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData) -{ - PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpRegisterTransitionCallback) -#endif -static INLINE PVRSRV_ERROR -PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PFN_PDUMP_TRANSITION pfnCallback, - void *hPrivData, - void *pvDevice, - void **ppvHandle) -{ - PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData); - PVR_UNREFERENCED_PARAMETER(pfnCallback); - PVR_UNREFERENCED_PARAMETER(hPrivData); - PVR_UNREFERENCED_PARAMETER(pvDevice); - PVR_UNREFERENCED_PARAMETER(ppvHandle); - - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpUnregisterTransitionCallback) -#endif -static INLINE void -PDumpUnregisterTransitionCallback(void *pvHandle) -{ - PVR_UNREFERENCED_PARAMETER(pvHandle); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpRegisterTransitionCallback) -#endif -static INLINE PVRSRV_ERROR -PDumpRegisterTransitionCallbackFenceSync(void *hPrivData, - PFN_PDUMP_TRANSITION_FENCE_SYNC pfnCallback, - void **ppvHandle) -{ - PVR_UNREFERENCED_PARAMETER(pfnCallback); - PVR_UNREFERENCED_PARAMETER(hPrivData); - PVR_UNREFERENCED_PARAMETER(ppvHandle); - - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpUnregisterTransitionCallbackFenceSync) -#endif -static INLINE void -PDumpUnregisterTransitionCallbackFenceSync(void *pvHandle) -{ - PVR_UNREFERENCED_PARAMETER(pvHandle); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpTransition) -#endif -static INLINE PVRSRV_ERROR -PDumpTransition(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PDUMP_TRANSITION_EVENT eEvent, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData); - PVR_UNREFERENCED_PARAMETER(eEvent); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#if defined(__linux__) || defined(GCC_IA32) || defined(GCC_ARM) || defined(__QNXNTO__) || defined(INTEGRITY_OS) - #define PDUMPINIT PDumpInitCommon - #define PDUMPDEINIT(args...) - #define PDUMPREG32(args...) - #define PDUMPREG64(args...) - #define PDUMPREGREAD32(args...) - #define PDUMPREGREAD64(args...) - #define PDUMPCOMMENT(args...) - #define PDUMPREGPOL(args...) - #define PDUMPSYNC(args...) - #define PDUMPCOPYTOMEM(args...) - #define PDUMPWRITE(args...) - #define PDUMPREGBASEDCBP(args...) - #define PDUMPCOMMENTWITHFLAGS(args...) - #define PDUMPENDINITPHASE(args...) - #define PDUMPIDLWITHFLAGS(args...) - #define PDUMPIDL(args...) - #define PDUMPPOWCMDSTART(args...) - #define PDUMPPOWCMDEND(args...) - #define PDUMP_LOCK(args...) - #define PDUMP_UNLOCK(args...) - #define PDUMPIF(args...) - #define PDUMPFI(args...) - #define PDUMPCOM(args...) -#else - #error Compiler not specified -#endif - -#endif /* PDUMP */ - -#endif /* PDUMP_KM_H */ - -/****************************************************************************** - End of file (pdump_km.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdump_mmu.c b/drivers/gpu/drm/img-rogue/1.17/pdump_mmu.c deleted file mode 100644 index 5b195d6fa0cb7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdump_mmu.c +++ /dev/null @@ -1,908 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title MMU PDump functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Common PDump (MMU specific) functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if defined(PDUMP) - -#include "img_types.h" -#include "img_defs.h" -#include "pdump_mmu.h" -#include "pdump_km.h" -#include "pdump_physmem.h" -#include "osfunc.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "allocmem.h" - -#define MAX_PDUMP_MMU_CONTEXTS (10) -static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1< 0) - { - /* do some tests for contiguity. If it fails, we flush anyway */ - if (pvBeyondLastPointer != pvBytes || - ui32SymAddrOffset != ui32BeyondLastOffset - /* NB: ought to check that symbolic name agrees too, but - we know this always to be the case in the current use-case */ - ) - { - bFlush = IMG_TRUE; - } - } - - /* Flush if necessary */ - if (bFlush && uiAccumulatedBytes > 0) - { - eErr = PDumpWriteParameter(psDeviceNode, - (IMG_UINT8 *)(uintptr_t)pvBasePointer, - uiAccumulatedBytes, ui32Flags, - &ui32ParamOutPos, pszFileName); - if (eErr == PVRSRV_OK) - { - eErr = PDumpSNPrintf(hScript, ui32MaxLenScript, - "LDB %s:0x%X 0x%X 0x%X %s", - /* dest */ - pszSymbolicName, - ui32BaseOffset, - /* size */ - uiAccumulatedBytes, - /* file offset */ - ui32ParamOutPos, - /* filename */ - pszFileName); - PVR_LOG_GOTO_IF_ERROR(eErr, "PDumpSNPrintf", ErrOut); - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - } - else if (eErr != PVRSRV_ERROR_PDUMP_NOT_ALLOWED) - { - PVR_LOG_GOTO_IF_ERROR(eErr, "PDumpWriteParameter", ErrOut); - } - else - { - /* else Write to parameter file prevented under the flags and - * current state of the driver so skip write to script and error IF. - * this is normal e.g. no in capture range for example. - */ - eErr = PVRSRV_OK; - } - - uiAccumulatedBytes = 0; - } - - /* Initialise offsets and pointers if necessary */ - if (uiAccumulatedBytes == 0) - { - ui32BaseOffset = ui32BeyondLastOffset = ui32SymAddrOffset; - pvBeyondLastPointer = pvBasePointer = (const IMG_CHAR *)pvBytes; - } - - /* Accumulate some bytes */ - ui32BeyondLastOffset += uiNumBytes; - pvBeyondLastPointer += uiNumBytes; - uiAccumulatedBytes += uiNumBytes; - -ErrOut: - PDUMP_RELEASE_SCRIPT_AND_FILE_STRING(); - return eErr; -} - -/************************************************************************** - * Function Name : PDumpMMUMalloc - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : -**************************************************************************/ -PVRSRV_ERROR PDumpMMUMalloc(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszPDumpDevName, - MMU_LEVEL eMMULevel, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32Align, - PDUMP_MMU_TYPE eMMUType) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_BLKDATA; - IMG_UINT64 ui64SymbolicAddr; - IMG_CHAR *pszMMUPX; - - PDUMP_GET_SCRIPT_STRING(); - - PVR_GOTO_IF_INVALID_PARAM(eMMULevel < MMU_LEVEL_LAST, eErr, ErrOut); - - PDUMP_LOCK(ui32Flags); - - /* - Write a comment to the PDump2 script streams indicating the memory allocation - */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "-- CALLOC :%s:%s Size=0x%08X Alignment=0x%08X 0x0 DevPAddr=0x%08"IMG_UINT64_FMTSPECX, - pszPDumpDevName, - apszMMULevelStringLookup[eMMULevel], - ui32Size, - ui32Align, - psDevPAddr->uiAddr); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - /* - construct the symbolic address - */ - ui64SymbolicAddr = (IMG_UINT64)psDevPAddr->uiAddr; - - /* - Write to the MMU script stream indicating the memory allocation - */ - if (eMMUType == PDUMP_MMU_TYPE_MIPS_MICROAPTIV) - { - pszMMUPX = MIPSMMUPX_FMT(eMMULevel); - } - else - { - pszMMUPX = MMUPX_FMT(eMMULevel); - } - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "CALLOC :%s:%s%016"IMG_UINT64_FMTSPECX" 0x%X 0x%X 0x0", - pszPDumpDevName, - pszMMUPX, - ui64SymbolicAddr, - ui32Size, - ui32Align - /* don't need this sDevPAddr.uiAddr*/); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -ErrUnlock: - PDUMP_UNLOCK(ui32Flags); -ErrOut: - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; -} - -/************************************************************************** - * Function Name : PDumpMMUFree - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : -**************************************************************************/ -PVRSRV_ERROR PDumpMMUFree(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszPDumpDevName, - MMU_LEVEL eMMULevel, - IMG_DEV_PHYADDR *psDevPAddr, - PDUMP_MMU_TYPE eMMUType) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - IMG_UINT64 ui64SymbolicAddr; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_BLKDATA; - IMG_CHAR *pszMMUPX; - - PDUMP_GET_SCRIPT_STRING(); - - PVR_GOTO_IF_INVALID_PARAM(eMMULevel < MMU_LEVEL_LAST, eErr, ErrOut); - - PDUMP_LOCK(ui32Flags); - /* - Write a comment to the PDUMP2 script streams indicating the memory free - */ - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "-- FREE :%s:%s", - pszPDumpDevName, apszMMULevelStringLookup[eMMULevel]); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - /* - construct the symbolic address - */ - ui64SymbolicAddr = (IMG_UINT64)psDevPAddr->uiAddr; - - /* - Write to the MMU script stream indicating the memory free - */ - if (eMMUType == PDUMP_MMU_TYPE_MIPS_MICROAPTIV) - { - pszMMUPX = MIPSMMUPX_FMT(eMMULevel); - } - else - { - pszMMUPX = MMUPX_FMT(eMMULevel); - } - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "FREE :%s:%s%016"IMG_UINT64_FMTSPECX, - pszPDumpDevName, - pszMMUPX, - ui64SymbolicAddr); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -ErrUnlock: - PDUMP_UNLOCK(ui32Flags); -ErrOut: - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; -} - -/******************************************************************************************************* - * Function Name : PDumpPTBaseObjectToMem64 - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory write from the baseobject - * for MIPS MMU device type -********************************************************************************************************/ -PVRSRV_ERROR PDumpPTBaseObjectToMem64(const IMG_CHAR *pszPDumpDevName, - PMR *psPMRDest, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest, - IMG_UINT32 ui32Flags, - MMU_LEVEL eMMULevel, - IMG_UINT64 ui64PxSymAddr, - IMG_UINT64 ui64PxOffset) -{ - - IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest; - IMG_DEVMEM_OFFSET_T uiNextSymNameDest; - PVRSRV_ERROR eErr = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eErr = PMR_PDumpSymbolicAddr(psPMRDest, - uiLogicalOffsetDest, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceNameDest, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicNameDest, - &uiPDumpSymbolicOffsetDest, - &uiNextSymNameDest); - - PVR_GOTO_IF_ERROR(eErr, Err); - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "WRW64 :%s:%s:0x%"IMG_UINT64_FMTSPECX" :%s:%s%016"IMG_UINT64_FMTSPECX":0x%"IMG_UINT64_FMTSPECX, - aszMemspaceNameDest, aszSymbolicNameDest, uiPDumpSymbolicOffsetDest, - pszPDumpDevName, MIPSMMUPX_FMT(eMMULevel), ui64PxSymAddr, ui64PxOffset); - - PVR_GOTO_IF_ERROR(eErr, Err); - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(PMR_DeviceNode(psPMRDest), hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - -Err: - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; -} - -/************************************************************************** - * Function Name : PDumpMMUDumpPxEntries - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : -**************************************************************************/ -PVRSRV_ERROR PDumpMMUDumpPxEntries(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_LEVEL eMMULevel, - const IMG_CHAR *pszPDumpDevName, - void *pvPxMem, - IMG_DEV_PHYADDR sPxDevPAddr, - IMG_UINT32 uiFirstEntry, - IMG_UINT32 uiNumEntries, - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicAddr, - IMG_UINT64 uiSymbolicAddrOffset, - IMG_UINT32 uiBytesPerEntry, - IMG_UINT32 uiLog2Align, - IMG_UINT32 uiAddrShift, - IMG_UINT64 uiAddrMask, - IMG_UINT64 uiPxEProtMask, - IMG_UINT64 uiDataValidEnable, - IMG_UINT32 ui32Flags, - PDUMP_MMU_TYPE eMMUType) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - IMG_UINT64 ui64PxSymAddr; - IMG_UINT64 ui64PxEValueSymAddr; - IMG_UINT32 ui32SymAddrOffset = 0; - IMG_UINT32 *pui32PxMem; - IMG_UINT64 *pui64PxMem; - IMG_BOOL bPxEValid; - IMG_UINT32 uiPxEIdx; - IMG_INT32 iShiftAmount; - IMG_CHAR *pszWrwSuffix = NULL; - void *pvRawBytes = NULL; - IMG_CHAR aszPxSymbolicAddr[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_UINT64 ui64PxE64; - IMG_UINT64 ui64Protflags64; - IMG_CHAR *pszMMUPX; - - PDUMP_GET_SCRIPT_STRING(); - ui32Flags |= (PDUMP_FLAGS_BLKDATA | PDUMP_FLAGS_CONTINUOUS); - - eErr = PDumpReady(); - if (eErr != PVRSRV_OK) - { - /* Mask suspension from caller as this is terminal & logged */ - eErr = (eErr == PVRSRV_ERROR_PDUMP_NOT_ACTIVE) ? PVRSRV_OK : eErr; - goto ErrOut; - } - - PVR_GOTO_IF_INVALID_PARAM(pvPxMem, eErr, ErrOut); - - /* - create the symbolic address of the Px - */ - ui64PxSymAddr = sPxDevPAddr.uiAddr; - - if (eMMUType == PDUMP_MMU_TYPE_MIPS_MICROAPTIV) - { - pszMMUPX = MIPSMMUPX_FMT(eMMULevel); - } - else - { - pszMMUPX = MMUPX_FMT(eMMULevel); - } - - OSSNPrintf(aszPxSymbolicAddr, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - ":%s:%s%016"IMG_UINT64_FMTSPECX, - pszPDumpDevName, - pszMMUPX, - ui64PxSymAddr); - - PDUMP_LOCK(ui32Flags); - - /* - traverse PxEs, dumping entries - */ - for (uiPxEIdx = uiFirstEntry; - uiPxEIdx < uiFirstEntry + uiNumEntries; - uiPxEIdx++) - { - /* Calc the symbolic address offset of the PxE location - This is what we have to add to the table address to get to a certain entry */ - ui32SymAddrOffset = (uiPxEIdx*uiBytesPerEntry); - - /* Calc the symbolic address of the PxE value and HW protflags */ - /* just read it here */ - switch (uiBytesPerEntry) - { - case 4: - { - pui32PxMem = pvPxMem; - ui64PxE64 = pui32PxMem[uiPxEIdx]; - pszWrwSuffix = ""; - pvRawBytes = &pui32PxMem[uiPxEIdx]; - break; - } - case 8: - { - pui64PxMem = pvPxMem; - ui64PxE64 = pui64PxMem[uiPxEIdx]; - pszWrwSuffix = "64"; - pvRawBytes = &pui64PxMem[uiPxEIdx]; - break; - } - default: - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMMUPxEntries: error")); - ui64PxE64 = 0; - //!!error - break; - } - } - - ui64PxEValueSymAddr = (ui64PxE64 & uiAddrMask) >> uiAddrShift << uiLog2Align; - ui64Protflags64 = ui64PxE64 & uiPxEProtMask; - bPxEValid = (ui64Protflags64 & uiDataValidEnable) ? IMG_TRUE : IMG_FALSE; - - if (!bPxEValid) - { - /* If the entry was "invalid", simply write the actual - value found to the memory location */ - eErr = _ContiguousPDumpBytes(psDeviceNode,aszPxSymbolicAddr, - ui32SymAddrOffset, IMG_FALSE, - uiBytesPerEntry, pvRawBytes, - ui32Flags); - if (eErr == PVRSRV_OK) - { - goto done; - } - else - { - goto ErrUnlock; - } - } - - _ContiguousPDumpBytes(psDeviceNode, aszPxSymbolicAddr, - ui32SymAddrOffset, IMG_TRUE, - 0, NULL, - ui32Flags); - - iShiftAmount = (IMG_INT32)(uiLog2Align - uiAddrShift); - - /* First put the symbolic representation of the actual - address of the entry into a pdump internal register */ - /* MOV seemed cleaner here, since (a) it's 64-bit; (b) the - target is not memory. However, MOV cannot do the - "reference" of the symbolic address. Apparently WRW is - correct. */ - - if (pszSymbolicAddr == NULL) - { - pszSymbolicAddr = "none"; - } - - if (eMMULevel == MMU_LEVEL_1) - { - if (iShiftAmount == 0) - { - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:%s%016"IMG_UINT64_FMTSPECX":0x%08X :%s:%s:0x%"IMG_UINT64_FMTSPECX" | 0x%"IMG_UINT64_FMTSPECX"\n", - pszWrwSuffix, - /* dest */ - pszPDumpDevName, - pszMMUPX, - ui64PxSymAddr, - ui32SymAddrOffset, - /* src */ - pszMemspaceName, - pszSymbolicAddr, - uiSymbolicAddrOffset, - /* ORing prot flags */ - ui64Protflags64); - } - else - { - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW :%s:$1 :%s:%s:0x%"IMG_UINT64_FMTSPECX"\n", - /* dest */ - pszPDumpDevName, - /* src */ - pszMemspaceName, - pszSymbolicAddr, - uiSymbolicAddrOffset); - } - } - else - { - if (eMMUType == PDUMP_MMU_TYPE_MIPS_MICROAPTIV) - { - pszMMUPX = MIPSMMUPX_FMT(eMMULevel - 1); - } - else - { - pszMMUPX = MMUPX_FMT(eMMULevel - 1); - } - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW :%s:$1 :%s:%s%016"IMG_UINT64_FMTSPECX":0x0", - /* dest */ - pszPDumpDevName, - /* src */ - pszPDumpDevName, - pszMMUPX, - ui64PxEValueSymAddr); - if (eMMUType == PDUMP_MMU_TYPE_MIPS_MICROAPTIV) - { - pszMMUPX = MIPSMMUPX_FMT(eMMULevel); - } - else - { - pszMMUPX = MMUPX_FMT(eMMULevel); - } - } - - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - /* Now shift it to the right place, if necessary: */ - /* Now shift that value down, by the "Align shift" - amount, to get it into units (ought to assert that - we get an integer - i.e. we don't shift any bits - off the bottom, don't know how to do PDUMP - assertions yet) and then back up by the right - amount to get it into the position of the field. - This is optimised into a single shift right by the - difference between the two. */ - if (iShiftAmount > 0) - { - /* Page X Address is specified in units larger - than the position in the PxE would suggest. */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHR :%s:$1 :%s:$1 0x%X", - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - iShiftAmount); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - } - else if (iShiftAmount < 0) - { - /* Page X Address is specified in units smaller - than the position in the PxE would suggest. */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHL :%s:$1 :%s:$1 0x%X", - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - -iShiftAmount); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - } - - if (eMMULevel == MMU_LEVEL_1) - { - if (iShiftAmount != 0) - { - /* Now we can "or" in the protection flags */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "OR :%s:$1 :%s:$1 0x%"IMG_UINT64_FMTSPECX, - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - ui64Protflags64); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:%s%016"IMG_UINT64_FMTSPECX":0x%08X :%s:$1", - pszWrwSuffix, - /* dest */ - pszPDumpDevName, - pszMMUPX, - ui64PxSymAddr, - ui32SymAddrOffset, - /* src */ - pszPDumpDevName); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - } - } - else - { - /* Now we can "or" in the protection flags */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "OR :%s:$1 :%s:$1 0x%"IMG_UINT64_FMTSPECX, - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - ui64Protflags64); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - /* Finally, we write the register into the actual PxE */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:%s%016"IMG_UINT64_FMTSPECX":0x%08X :%s:$1", - pszWrwSuffix, - /* dest */ - pszPDumpDevName, - pszMMUPX, - ui64PxSymAddr, - ui32SymAddrOffset, - /* src */ - pszPDumpDevName); - PVR_GOTO_IF_ERROR(eErr, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - } - } - -done: - /* flush out any partly accumulated stuff for LDB */ - _ContiguousPDumpBytes(psDeviceNode, aszPxSymbolicAddr, - ui32SymAddrOffset, IMG_TRUE, - 0, NULL, - ui32Flags); - -ErrUnlock: - PDUMP_UNLOCK(ui32Flags); -ErrOut: - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; -} - -/************************************************************************** - * Function Name : _PdumpAllocMMUContext - * Inputs : pui32MMUContextID - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : pdump util to allocate MMU contexts -**************************************************************************/ -static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) -{ - IMG_UINT32 i; - - /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */ - for (i=0; i -#else -#include -#endif - -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -#include "pdump_physmem.h" -#include "pdump_km.h" - -#include "allocmem.h" -#include "osfunc.h" - -#include "pvrsrv.h" - -/* #define MAX_PDUMP_MMU_CONTEXTS (10) */ -/* static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1<= 'a' && sym <= 'z') - return IMG_TRUE; - else - return IMG_FALSE; -} - -void PDumpMakeStringValid(IMG_CHAR *pszString, - IMG_UINT32 ui32StrLen) -{ - IMG_UINT32 i; - - if (pszString) - { - for (i = 0; i < ui32StrLen; i++) - { - if (_IsAllowedSym(pszString[i])) - { - if (_IsLowerCaseSym(pszString[i])) - pszString[i] = pszString[i]-32; - else - pszString[i] = pszString[i]; - } - else - { - pszString[i] = '_'; - } - } - } -} - -/************************************************************************** - * Function Name : PDumpGetSymbolicAddr - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : - **************************************************************************/ -PVRSRV_ERROR PDumpGetSymbolicAddr(const IMG_HANDLE hPhysmemPDumpHandle, - IMG_CHAR **ppszSymbolicAddress) -{ - PDUMP_PHYSMEM_INFO_T *psPDumpAllocationInfo; - - PVR_RETURN_IF_INVALID_PARAM(hPhysmemPDumpHandle); - - psPDumpAllocationInfo = (PDUMP_PHYSMEM_INFO_T *)hPhysmemPDumpHandle; - *ppszSymbolicAddress = psPDumpAllocationInfo->aszSymbolicAddress; - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpMalloc - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : - **************************************************************************/ -PVRSRV_ERROR PDumpMalloc(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicAddress, - IMG_UINT64 ui64Size, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phHandlePtr, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_PHYSMEM_INFO_T *psPDumpAllocationInfo; - - PDUMP_GET_SCRIPT_STRING() - - psPDumpAllocationInfo = OSAllocMem(sizeof*psPDumpAllocationInfo); - PVR_ASSERT(psPDumpAllocationInfo != NULL); - - /* - * PDUMP_CONT and PDUMP_PERSIST flag can't set together. - */ - if (ui32PDumpFlags == PDUMP_NONE) - { - /* - Set continuous flag because there is no way of knowing beforehand which - allocation is needed for playback of the captured range. - */ - ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS; - } - - ui32PDumpFlags |= PDUMP_FLAGS_BLKDATA; - - /* - construct the symbolic address - */ - - OSSNPrintf(psPDumpAllocationInfo->aszSymbolicAddress, - sizeof(psPDumpAllocationInfo->aszSymbolicAddress), - ":%s:%s", - pszDevSpace, - pszSymbolicAddress); - - /* - Write to the MMU script stream indicating the memory allocation - */ - if (bInitialise) - { - eError = PDumpSNPrintf(hScript, ui32MaxLen, "CALLOC %s 0x%"IMG_UINT64_FMTSPECX" 0x%"IMG_UINT64_FMTSPECX" 0x%X\n", - psPDumpAllocationInfo->aszSymbolicAddress, - ui64Size, - uiAlign, - ui32InitValue); - } - else - { - eError = PDumpSNPrintf(hScript, ui32MaxLen, "MALLOC %s 0x%"IMG_UINT64_FMTSPECX" 0x%"IMG_UINT64_FMTSPECX"\n", - psPDumpAllocationInfo->aszSymbolicAddress, - ui64Size, - uiAlign); - } - - if (eError != PVRSRV_OK) - { - OSFreeMem(psPDumpAllocationInfo); - goto _return; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - psPDumpAllocationInfo->ui64Size = ui64Size; - psPDumpAllocationInfo->ui32Align = TRUNCATE_64BITS_TO_32BITS(uiAlign); - - *phHandlePtr = (IMG_HANDLE)psPDumpAllocationInfo; - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - - -/************************************************************************** - * Function Name : PDumpFree - * Inputs : - * Outputs : - * Returns : PVRSRV_ERROR - * Description : - **************************************************************************/ -PVRSRV_ERROR PDumpFree(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hPDumpAllocationInfoHandle) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_BLKDATA; - - PDUMP_PHYSMEM_INFO_T *psPDumpAllocationInfo; - - PDUMP_GET_SCRIPT_STRING() - - psPDumpAllocationInfo = (PDUMP_PHYSMEM_INFO_T *)hPDumpAllocationInfoHandle; - - /* - Write to the MMU script stream indicating the memory free - */ - eError = PDumpSNPrintf(hScript, ui32MaxLen, "FREE %s\n", - psPDumpAllocationInfo->aszSymbolicAddress); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - OSFreeMem(psPDumpAllocationInfo); - PDUMP_UNLOCK(ui32Flags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRWRW32(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - PMR_VALUE32_FMTSPEC, - pszDevSpace, - pszSymbolicName, - uiOffset, - ui32Value); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRWRW32InternalVarToMem(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - const IMG_CHAR *pszInternalVar, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s", - pszDevSpace, - pszSymbolicName, - uiOffset, - pszInternalVar); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRRDW32MemToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "RDW %s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC, - pszInternalVar, - pszDevSpace, - pszSymbolicName, - uiOffset); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRWRW64(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW64 :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - PMR_VALUE64_FMTSPEC, - pszDevSpace, - pszSymbolicName, - uiOffset, - ui64Value); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRWRW64InternalVarToMem(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - const IMG_CHAR *pszInternalVar, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW64 :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s", - pszDevSpace, - pszSymbolicName, - uiOffset, - pszInternalVar); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRRDW64MemToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "RDW64 %s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC, - pszInternalVar, - pszDevSpace, - pszSymbolicName, - uiOffset); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRLDB(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "LDB :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - IMG_DEVMEM_SIZE_FMTSPEC " " - PDUMP_FILEOFFSET_FMTSPEC " %s\n", - pszDevSpace, - pszSymbolicName, - uiOffset, - uiSize, - uiFileOffset, - pszFilename); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR PDumpPMRSAB(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFileName, - IMG_UINT32 uiFileOffset) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 uiPDumpFlags; - - PDUMP_GET_SCRIPT_STRING() - - uiPDumpFlags = 0; - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SAB :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - IMG_DEVMEM_SIZE_FMTSPEC " " - "0x%08X %s.bin\n", - pszDevSpace, - pszSymbolicName, - uiOffset, - uiSize, - uiFileOffset, - pszFileName); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRPOL(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 uiCount, - IMG_UINT32 uiDelay, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "POL :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - "0x%08X 0x%08X %d %d %d\n", - pszMemspaceName, - pszSymbolicName, - uiOffset, - ui32Value, - ui32Mask, - eOperator, - uiCount, - uiDelay); - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpPMRCBP(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PDUMP_FLAGS_T uiPDumpFlags = 0; - - PDUMP_GET_SCRIPT_STRING() - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "CBP :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " " - IMG_DEVMEM_OFFSET_FMTSPEC " " IMG_DEVMEM_SIZE_FMTSPEC " " IMG_DEVMEM_SIZE_FMTSPEC "\n", - pszMemspaceName, - pszSymbolicName, - uiReadOffset, - uiWriteOffset, - uiPacketSize, - uiBufferSize); - - PVR_GOTO_IF_ERROR(eError, _return); - - PDUMP_LOCK(uiPDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - -_return: - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/* Checking that the request is for the PDump-bound device - * should be done before the following function is called - */ -PVRSRV_ERROR -PDumpWriteParameterBlob(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 *pcBuffer, - size_t uiNumBytes, - PDUMP_FLAGS_T uiPDumpFlags, - IMG_CHAR *pszFilenameOut, - size_t uiFilenameBufSz, - PDUMP_FILEOFFSET_T *puiOffsetOut) -{ - PVRSRV_ERROR eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_UNREFERENCED_PARAMETER(uiFilenameBufSz); - - PVR_ASSERT(uiNumBytes > 0); - - eError = PDumpReady(); - if (eError != PVRSRV_OK) - { - /* Mask suspension from caller as this is terminal & logged */ - eError = (eError == PVRSRV_ERROR_PDUMP_NOT_ACTIVE) ? - PVRSRV_ERROR_PDUMP_NOT_ALLOWED : - eError; - return eError; - } - - PVR_ASSERT(uiFilenameBufSz <= PDUMP_PARAM_MAX_FILE_NAME); - - PDUMP_LOCK(uiPDumpFlags); - - eError = PDumpWriteParameter(psDeviceNode, pcBuffer, uiNumBytes, - uiPDumpFlags, puiOffsetOut, pszFilenameOut); - PDUMP_UNLOCK(uiPDumpFlags); - - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_PDUMP_NOT_ALLOWED)) - { - PVR_LOG_RETURN_IF_ERROR(eError, "PDumpWriteParameter"); - } - /* else Write to parameter file Ok or Prevented under the flags or - * current state of the driver so skip further writes and let caller know. - */ - return eError; -} - -#endif /* PDUMP */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdump_physmem.h b/drivers/gpu/drm/img-rogue/1.17/pdump_physmem.h deleted file mode 100644 index a5a6f37409e6a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdump_physmem.h +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title pdump functions to assist with physmem allocations -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements basic low level control of MMU. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PDUMP_PHYSMEM_H -#define SRVSRV_PDUMP_PHYSMEM_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "pmr.h" -#include "device.h" /* For device node */ - -#define PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH 40 -#define PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH 60 -#define PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH (PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH + PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH) - -typedef struct _PDUMP_PHYSMEM_INFO_T_ PDUMP_PHYSMEM_INFO_T; - -#if defined(PDUMP) -PVRSRV_ERROR -PDumpGetSymbolicAddr(const IMG_HANDLE hPhysmemPDumpHandle, - IMG_CHAR **ppszSymbolicAddress); - -PVRSRV_ERROR -PDumpMalloc(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicAddress, - IMG_UINT64 ui64Size, - /* alignment is alignment of start of buffer _and_ - minimum contiguity - i.e. smallest allowable - page-size. */ - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phHandlePtr, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR -PDumpFree(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hPDumpAllocationInfoHandle); - -void -PDumpMakeStringValid(IMG_CHAR *pszString, - IMG_UINT32 ui32StrLen); -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PDumpGetSymbolicAddr) -#endif -static INLINE PVRSRV_ERROR -PDumpGetSymbolicAddr(const IMG_HANDLE hPhysmemPDumpHandle, - IMG_CHAR **ppszSymbolicAddress) -{ - PVR_UNREFERENCED_PARAMETER(hPhysmemPDumpHandle); - PVR_UNREFERENCED_PARAMETER(ppszSymbolicAddress); - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR -PDumpMalloc(const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicAddress, - IMG_UINT64 ui64Size, - IMG_DEVMEM_ALIGN_T uiAlign, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phHandlePtr, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(pszDevSpace); - PVR_UNREFERENCED_PARAMETER(pszSymbolicAddress); - PVR_UNREFERENCED_PARAMETER(ui64Size); - PVR_UNREFERENCED_PARAMETER(uiAlign); - PVR_UNREFERENCED_PARAMETER(bInitialise); - PVR_UNREFERENCED_PARAMETER(ui32InitValue); - PVR_UNREFERENCED_PARAMETER(phHandlePtr); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR -PDumpFree(IMG_HANDLE hPDumpAllocationInfoHandle) -{ - PVR_UNREFERENCED_PARAMETER(hPDumpAllocationInfoHandle); - return PVRSRV_OK; -} -#endif /* PDUMP */ - -#define PMR_DEFAULT_PREFIX "PMR" -#define PMR_SYMBOLICADDR_FMTSPEC "%s%"IMG_UINT64_FMTSPEC"_%"IMG_UINT64_FMTSPEC"_%s" -#define PMR_MEMSPACE_FMTSPEC "%s" -#define PMR_MEMSPACE_CACHE_COHERENT_FMTSPEC "CC_%s" - -#if defined(PDUMP) -#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr) \ - PDumpMalloc(pszPDumpMemDevName, PMR_OSALLOCPAGES_PREFIX, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr, PDUMP_NONE) -#define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \ - PDumpFree(hHandle) -#else -#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr) \ - ((void)(*phHandlePtr=NULL)) -#define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \ - ((void)(0)) -#endif /* PDUMP */ - -PVRSRV_ERROR -PDumpPMRWRW32(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRWRW32InternalVarToMem(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - const IMG_CHAR *pszInternalVar, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRRDW32MemToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRWRW64(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRWRW64InternalVarToMem(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - const IMG_CHAR *pszInternalVar, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRRDW64MemToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRLDB(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRSAB(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - const IMG_CHAR *pszFileName, - IMG_UINT32 uiFileOffset); - -/* - PDumpPMRPOL() - - Emits a POL to the PDUMP. -*/ -PVRSRV_ERROR -PDumpPMRPOL(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszMempaceName, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 uiCount, - IMG_UINT32 uiDelay, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PDumpPMRCBP(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszMemspaceName, - const IMG_CHAR *pszSymbolicName, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize); - -/* - * PDumpWriteParameterBlob() - * - * Writes a binary blob to the pdump param stream containing the current - * contents of the memory, and returns the filename and offset of where - * that blob is located (for use in a subsequent LDB, for example). - * - * Caller to provide buffer to receive filename, and declare the size of - * that buffer. - */ -PVRSRV_ERROR -PDumpWriteParameterBlob(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 *pcBuffer, - size_t uiNumBytes, - PDUMP_FLAGS_T uiPDumpFlags, - IMG_CHAR *pszFilenameOut, - size_t uiFilenameBufSz, - PDUMP_FILEOFFSET_T *puiOffsetOut); - -#endif /* #ifndef SRVSRV_PDUMP_PHYSMEM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdump_server.c b/drivers/gpu/drm/img-rogue/1.17/pdump_server.c deleted file mode 100644 index 5b2cc239a8099..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdump_server.c +++ /dev/null @@ -1,5565 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Common Server PDump functions layer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(PDUMP) - -#if defined(__linux__) - #include - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ -#else - #include -#endif /* __linux__ */ - -#include "pvrversion.h" -#include "allocmem.h" -#include "osfunc.h" -#include "pvrsrv.h" -#include "pvr_debug.h" -#include "srvkm.h" -#include "pdump_physmem.h" -#include "hash.h" -#include "connection_server.h" -#include "services_km.h" -#include -#include "oskm_apphint.h" - -/* pdump headers */ -#include "tlstream.h" -#include "pdump_km.h" - -#include "pdumpdesc.h" -#include "rgxpdump.h" - -#include "tutilsdefs.h" -#include "tutils_km.h" -/* Allow temporary buffer size override */ -#if !defined(PDUMP_TEMP_BUFFER_SIZE) -#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U) -#endif - -#define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x))) -#define VPTR_PLUS(p, x) PTR_PLUS(void *, p, x) -#define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x)) -#define MAX_PDUMP_MMU_CONTEXTS (32) - -#define PRM_FILE_SIZE_MAX 0x7FDFFFFFU /*!< Default maximum file size to split output files, 2GB-2MB as fwrite limits it to 2GB-1 on 32bit systems */ - -#define MAX_PDUMP_WRITE_RETRIES 200 /*!< Max number of retries to dump pdump data in to respective buffers */ - -/* 'Magic' cookie used in this file only, where no psDeviceNode is available - * but writing to the PDump log should be permitted - */ -#define PDUMP_MAGIC_COOKIE 0x9E0FF - -static ATOMIC_T g_sConnectionCount; - -/* - * Structure to store some essential attributes of a PDump stream buffer. - */ -typedef struct -{ - IMG_CHAR* pszName; /*!< Name of the PDump TL Stream buffer */ - IMG_HANDLE hTL; /*!< Handle of created TL stream buffer */ - IMG_UINT32 ui32BufferSize; /*!< The size of the buffer in bytes */ - IMG_UINT32 ui32BufferFullRetries; /*!< The number of times the buffer got full */ - IMG_UINT32 ui32BufferFullAborts; /*!< The number of times we failed to write data */ - IMG_UINT32 ui32HighestRetriesWatermark; /*!< Max number of retries try to dump pdump data */ - IMG_UINT32 ui32MaxAllowedWriteSize; /*!< Max allowed write packet size */ -} PDUMP_STREAM; - -typedef struct -{ - PDUMP_STREAM sInitStream; /*!< Driver initialisation PDump stream */ - PDUMP_STREAM sMainStream; /*!< App framed PDump stream */ - PDUMP_STREAM sDeinitStream; /*!< Driver/HW de-initialisation PDump stream */ - PDUMP_STREAM sBlockStream; /*!< Block mode PDump block data stream - currently its script only */ -} PDUMP_CHANNEL; - -typedef struct -{ - PDUMP_CHANNEL sCh; /*!< Channel handles */ - IMG_UINT32 ui32FileIdx; /*!< File index gets incremented on script out file split */ -} PDUMP_SCRIPT; - -typedef struct -{ - IMG_UINT32 ui32Init; /*!< Count of bytes written to the init phase stream */ - IMG_UINT32 ui32Main; /*!< Count of bytes written to the main stream */ - IMG_UINT32 ui32Deinit; /*!< Count of bytes written to the deinit stream */ - IMG_UINT32 ui32Block; /*!< Count of bytes written to the block stream */ -} PDUMP_CHANNEL_WOFFSETS; - -typedef struct -{ - PDUMP_CHANNEL sCh; /*!< Channel handles */ - PDUMP_CHANNEL_WOFFSETS sWOff; /*!< Channel file write offsets */ - IMG_UINT32 ui32FileIdx; /*!< File index used when file size limit reached and a new file is started, parameter channel only */ - IMG_UINT32 ui32MaxFileSize; /*!< Maximum file size for parameter files */ - - PDUMP_FILEOFFSET_T uiZeroPageOffset; /*!< Offset of the zero page in the parameter file */ - size_t uiZeroPageSize; /*!< Size of the zero page in the parameter file */ - IMG_CHAR szZeroPageFilename[PDUMP_PARAM_MAX_FILE_NAME]; /*< PRM file name where the zero page was pdumped */ -} PDUMP_PARAMETERS; - -/* PDump lock to keep pdump write atomic. - * Which will protect g_PDumpScript & g_PDumpParameters pdump - * specific shared variable. - */ -static POS_LOCK g_hPDumpWriteLock; - -static PDUMP_SCRIPT g_PDumpScript = { { - { PDUMP_SCRIPT_INIT_STREAM_NAME, NULL, - PDUMP_SCRIPT_INIT_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_SCRIPT_MAIN_STREAM_NAME, NULL, - PDUMP_SCRIPT_MAIN_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_SCRIPT_DEINIT_STREAM_NAME, NULL, - PDUMP_SCRIPT_DEINIT_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_SCRIPT_BLOCK_STREAM_NAME, NULL, - PDUMP_SCRIPT_BLOCK_STREAM_SIZE, 0, 0, 0 }, - }, 0 }; -static PDUMP_PARAMETERS g_PDumpParameters = { { - { PDUMP_PARAM_INIT_STREAM_NAME, NULL, - PDUMP_PARAM_INIT_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_PARAM_MAIN_STREAM_NAME, NULL, - PDUMP_PARAM_MAIN_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_PARAM_DEINIT_STREAM_NAME, NULL, - PDUMP_PARAM_DEINIT_STREAM_SIZE, 0, 0, 0 }, - { PDUMP_PARAM_BLOCK_STREAM_NAME, NULL, - PDUMP_PARAM_BLOCK_STREAM_SIZE, 0, 0, 0 }, - }, {0, 0, 0, 0}, 0, PRM_FILE_SIZE_MAX}; - - -#if defined(PDUMP_DEBUG_OUTFILES) -/* counter increments each time debug write is called */ -ATOMIC_T g_sEveryLineCounter; -#endif - -// #define PDUMP_DEBUG_TRANSITION -#if defined(PDUMP_DEBUG_TRANSITION) -# define DEBUG_OUTFILES_COMMENT(dev, fmt, ...) (void)PDumpCommentWithFlags(dev, PDUMP_FLAGS_CONTINUOUS, fmt, __VA_ARGS__) -#else -# define DEBUG_OUTFILES_COMMENT(dev, fmt, ...) -#endif - -#if defined(PDUMP_DEBUG) || defined(REFCOUNT_DEBUG) -# define PDUMP_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__) -#else -# define PDUMP_REFCOUNT_PRINT(fmt, ...) -#endif - -/* Prototype for the test/debug state dump routine used in debugging */ -#if defined(PDUMP_TRACE_STATE) || defined(PVR_TESTING_UTILS) -void PDumpCommonDumpState(void); -#endif - - -/*****************************************************************************/ -/* PDump Control Module Definitions */ -/*****************************************************************************/ - -/* - * struct _PDUMP_CAPTURE_RANGE_ is interpreted differently in different modes of PDump - * - * Non-Block mode: - * ui32Start - Start frame number of range - * ui32End - End frame number of range - * ui32Interval - Frame sample rate interval - * - * Block mode: - * ui32Start - If set to '0', first PDump-block will of minimal (i.e. PDUMP_BLOCKLEN_MIN) - * length, else all blocks will be of block-length provided - * - * ui32End - By default this is set to PDUMP_FRAME_MAX so that Blocked PDump - * will be captured indefinitely till stopped externally. On force capture - * stop, this will be set to (ui32CurrentFrame + 1) to stop capture from - * next frame onwards - * - * ui32Interval - This will be interpreted as PDump block-length provided - **/ -typedef struct _PDUMP_CAPTURE_RANGE_ -{ - IMG_UINT32 ui32Start; - IMG_UINT32 ui32End; - IMG_UINT32 ui32Interval; -} PDUMP_CAPTURE_RANGE; - -/* PDump Block mode specific controls */ -typedef struct _PDUMP_BLOCK_CTRL_ -{ - IMG_UINT32 ui32BlockLength; /*!< PDump block length in term of number of frames per block */ - IMG_UINT32 ui32CurrentBlock; /*!< Current block number */ -} PDUMP_BLOCK_CTRL; - -/*! PDump common module State Machine states */ -typedef enum _PDUMP_SM_ -{ - PDUMP_SM_UNINITIALISED, /*!< Starting state */ - PDUMP_SM_INITIALISING, /*!< Module is initialising */ - PDUMP_SM_READY, /*!< Module is initialised and ready */ - PDUMP_SM_READY_CLIENT_CONNECTED, /*!< Module is ready and capture client connected */ - PDUMP_SM_FORCED_SUSPENDED, /*!< Module forced error, PDumping suspended, this is to force driver reload before next capture */ - PDUMP_SM_ERROR_SUSPENDED, /*!< Module fatal error, PDumping suspended semi-final state */ - PDUMP_SM_DEINITIALISED /*!< Final state */ -} PDUMP_SM; - -/*! PDump control flags */ -#define FLAG_IS_DRIVER_IN_INIT_PHASE 0x1 /*! Control flag that keeps track of State of driver initialisation phase */ -#define FLAG_IS_IN_CAPTURE_RANGE 0x2 /*! Control flag that keeps track of Current capture status, is current frame in range */ -#define FLAG_IS_IN_CAPTURE_INTERVAL 0x4 /*! Control flag that keeps track of Current capture status, is current frame in an interval where no capture takes place. */ - -#define CHECK_PDUMP_CONTROL_FLAG(PDUMP_CONTROL_FLAG) BITMASK_HAS(g_PDumpCtrl.ui32Flags, PDUMP_CONTROL_FLAG) -#define SET_PDUMP_CONTROL_FLAG(PDUMP_CONTROL_FLAG) BITMASK_SET(g_PDumpCtrl.ui32Flags, PDUMP_CONTROL_FLAG) -#define UNSET_PDUMP_CONTROL_FLAG(PDUMP_CONTROL_FLAG) BITMASK_UNSET(g_PDumpCtrl.ui32Flags, PDUMP_CONTROL_FLAG) - -/* No direct access to members from outside the control module - please */ -typedef struct _PDUMP_CTRL_STATE_ -{ - PDUMP_SM eServiceState; /*!< State of the pdump_common module */ - IMG_UINT32 ui32Flags; - - IMG_UINT32 ui32DefaultCapMode; /*!< Capture mode of the dump */ - PDUMP_CAPTURE_RANGE sCaptureRange; /*|< The capture range for capture mode 'framed' */ - IMG_UINT32 ui32CurrentFrame; /*!< Current frame number */ - - PDUMP_BLOCK_CTRL sBlockCtrl; /*!< Pdump block mode ctrl data */ - - POS_LOCK hLock; /*!< Exclusive lock to this structure */ - IMG_PID InPowerTransitionPID;/*!< pid of thread requesting power transition */ -} PDUMP_CTRL_STATE; - -static PDUMP_CTRL_STATE g_PDumpCtrl = -{ - PDUMP_SM_UNINITIALISED, - - FLAG_IS_DRIVER_IN_INIT_PHASE, - - PDUMP_CAPMODE_UNSET, - { - PDUMP_FRAME_UNSET, - PDUMP_FRAME_UNSET, - 0 - }, - 0, - - { - 0, - PDUMP_BLOCKNUM_INVALID, - }, - - NULL, - 0 -}; - -static void PDumpAssertWriteLockHeld(void); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - -/*************************************************************************/ /*! - @Function PDumpCreateIncVarNameStr - @Description When 64 bit register access is split between two 32 bit - accesses, it needs two PDump Internal variables to store register value. - This function creates the string for the second PDump Internal variable - for example if Passed Variable name is :SYSMEM:$1 this function will - generate the string :SYSMEM:$2 - - @Input pszInternalVar String for PDump internal variable in use - - @Return IMG_CHAR* String for second PDump internal variable to be used -*/ /**************************************************************************/ -static INLINE IMG_CHAR* PDumpCreateIncVarNameStr(const IMG_CHAR* pszInternalVar) -{ - IMG_CHAR *pszPDumpVarName; - IMG_UINT32 ui32Size = (IMG_UINT32)OSStringLength(pszInternalVar); - if (ui32Size == 0) - { - return NULL; - } - - ui32Size++; - pszPDumpVarName = (IMG_CHAR*)OSAllocMem((ui32Size) * sizeof(IMG_CHAR)); - if (pszPDumpVarName == NULL) - { - return NULL; - } - - OSStringLCopy(pszPDumpVarName, pszInternalVar, ui32Size); - /* Increase the number on the second variable */ - pszPDumpVarName[ui32Size-2] += 1; - return pszPDumpVarName; -} - -/*************************************************************************/ /*! - @Function PDumpFreeIncVarNameStr - @Description Free the string created by function PDumpCreateIncVarNameStr - - @Input pszPDumpVarName String to free - - @Return void -*/ /**************************************************************************/ -static INLINE void PDumpFreeIncVarNameStr(IMG_CHAR* pszPDumpVarName) -{ - if (pszPDumpVarName != NULL) - { - OSFreeMem(pszPDumpVarName); - } -} -#endif - -static PVRSRV_ERROR PDumpCtrlInit(void) -{ - g_PDumpCtrl.eServiceState = PDUMP_SM_INITIALISING; - - /* Create lock for PDUMP_CTRL_STATE struct, which is shared between pdump client - and PDumping app. This lock will help us serialize calls from pdump client - and PDumping app */ - PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&g_PDumpCtrl.hLock), "OSLockCreate"); - - return PVRSRV_OK; -} - -static void PDumpCtrlDeInit(void) -{ - if (g_PDumpCtrl.hLock) - { - OSLockDestroy(g_PDumpCtrl.hLock); - g_PDumpCtrl.hLock = NULL; - } -} - -static INLINE void PDumpCtrlLockAcquire(void) -{ - OSLockAcquire(g_PDumpCtrl.hLock); -} - -static INLINE void PDumpCtrlLockRelease(void) -{ - OSLockRelease(g_PDumpCtrl.hLock); -} - -static INLINE PDUMP_SM PDumpCtrlGetModuleState(void) -{ - return g_PDumpCtrl.eServiceState; -} - -PVRSRV_ERROR PDumpReady(void) -{ - switch (PDumpCtrlGetModuleState()) - { - case PDUMP_SM_READY: - case PDUMP_SM_READY_CLIENT_CONNECTED: - return PVRSRV_OK; - - case PDUMP_SM_FORCED_SUSPENDED: - case PDUMP_SM_ERROR_SUSPENDED: - return PVRSRV_ERROR_PDUMP_NOT_ACTIVE; - - case PDUMP_SM_UNINITIALISED: - case PDUMP_SM_INITIALISING: - case PDUMP_SM_DEINITIALISED: - return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; - - default: - /* Bad state */ - PVR_ASSERT(1); - return PVRSRV_ERROR_BAD_MAPPING; - } -} - - -/****************************************************************************** - NOTE: - The following PDumpCtrl*** functions require the PDUMP_CTRL_STATE lock be - acquired BEFORE they are called. This is because the PDUMP_CTRL_STATE data - is shared between the PDumping App and the PDump client, hence an exclusive - access is required. The lock can be acquired and released by using the - PDumpCtrlLockAcquire & PDumpCtrlLockRelease functions respectively. -******************************************************************************/ - -static void PDumpCtrlUpdateCaptureStatus(void) -{ - if (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_FRAMED) - { - if ((g_PDumpCtrl.ui32CurrentFrame >= g_PDumpCtrl.sCaptureRange.ui32Start) && - (g_PDumpCtrl.ui32CurrentFrame <= g_PDumpCtrl.sCaptureRange.ui32End)) - { - if (((g_PDumpCtrl.ui32CurrentFrame - g_PDumpCtrl.sCaptureRange.ui32Start) % g_PDumpCtrl.sCaptureRange.ui32Interval) == 0) - { - SET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - } - else - { - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - SET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - } - } - else - { - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - } - } - else if ((g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_CONTINUOUS) || (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_BLOCKED)) - { - SET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - } - else if (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_UNSET) - { - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - } - else - { - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE); - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL); - PVR_DPF((PVR_DBG_ERROR, "PDumpCtrlUpdateCaptureStatus: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode)); - } - -} - -static INLINE IMG_UINT32 PDumpCtrlCapModIsBlocked(void) -{ - return (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_BLOCKED); -} - -static INLINE IMG_UINT32 PDumpCtrlMinimalFirstBlock(void) -{ - /* If ui32Start is set to zero, first block length will be set to minimum - * (i.e. PDUMP_BLOCKLEN_MIN), else it will be of same length as that of - * rest of the blocks (i.e. ui32BlockLength) - * - * Having shorter first block reduces playback time of final capture. - * */ - - return (PDumpCtrlCapModIsBlocked() && (g_PDumpCtrl.sCaptureRange.ui32Start == 0)); -} - -static void PDumpCtrlSetBlock(IMG_UINT32 ui32BlockNum) -{ - g_PDumpCtrl.sBlockCtrl.ui32CurrentBlock = PDumpCtrlCapModIsBlocked()? ui32BlockNum : PDUMP_BLOCKNUM_INVALID; -} - -static INLINE IMG_UINT32 PDumpCtrlGetBlock(void) -{ - return PDumpCtrlCapModIsBlocked()? g_PDumpCtrl.sBlockCtrl.ui32CurrentBlock : PDUMP_BLOCKNUM_INVALID; -} - -static PVRSRV_ERROR PDumpCtrlForcedStop(void) -{ - /* In block-mode on forced stop request, capture will be stopped after (current_frame + 1)th frame number. - * This ensures that DumpAfterRender always be called on last frame before exiting the PDump capturing - * */ - g_PDumpCtrl.sCaptureRange.ui32End = g_PDumpCtrl.ui32CurrentFrame + 1; - - return PVRSRV_OK; -} - -static INLINE IMG_BOOL PDumpCtrlIsCaptureForceStopped(void) -{ - return (PDumpCtrlCapModIsBlocked() && (g_PDumpCtrl.ui32CurrentFrame > g_PDumpCtrl.sCaptureRange.ui32End)); -} - -static void PDumpCtrlSetCurrentFrame(IMG_UINT32 ui32Frame) -{ - g_PDumpCtrl.ui32CurrentFrame = ui32Frame; - - PDumpCtrlUpdateCaptureStatus(); - - /* Force PDump module to suspend PDumping on forced capture stop */ - if ((PDumpCtrlGetModuleState() != PDUMP_SM_FORCED_SUSPENDED) && PDumpCtrlIsCaptureForceStopped()) - { - PVR_LOG(("PDump forced capture stop received. Suspend PDumping to force driver reload before next capture.")); - g_PDumpCtrl.eServiceState = PDUMP_SM_FORCED_SUSPENDED; - } -#if defined(PDUMP_TRACE_STATE) - PDumpCommonDumpState(); -#endif -} - -static void PDumpCtrlSetDefaultCaptureParams(IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32End, IMG_UINT32 ui32Interval) -{ - /* Set the capture range to that supplied by the PDump client tool - */ - g_PDumpCtrl.ui32DefaultCapMode = ui32Mode; - g_PDumpCtrl.sCaptureRange.ui32Start = ui32Start; - g_PDumpCtrl.sCaptureRange.ui32End = ui32End; - g_PDumpCtrl.sCaptureRange.ui32Interval = ui32Interval; - - /* Set pdump block mode ctrl variables */ - g_PDumpCtrl.sBlockCtrl.ui32BlockLength = (ui32Mode == PDUMP_CAPMODE_BLOCKED)? ui32Interval : 0; /* ui32Interval is interpreted as block length */ - g_PDumpCtrl.sBlockCtrl.ui32CurrentBlock = PDUMP_BLOCKNUM_INVALID; - - /* Change module state to record capture client connected */ - if (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_UNSET) - g_PDumpCtrl.eServiceState = PDUMP_SM_READY; - else - g_PDumpCtrl.eServiceState = PDUMP_SM_READY_CLIENT_CONNECTED; - - /* Reset the current frame on reset of the capture range, the helps to - * avoid inter-pdump start frame issues when the driver is not reloaded. - * No need to call PDumpCtrlUpdateCaptureStatus() direct as the set - * current frame call will. - */ - PDumpCtrlSetCurrentFrame(0); - -} - -static IMG_UINT32 PDumpCtrlGetCurrentFrame(void) -{ - return g_PDumpCtrl.ui32CurrentFrame; -} - -static INLINE IMG_BOOL PDumpCtrlCaptureOn(void) -{ - return ((g_PDumpCtrl.eServiceState == PDUMP_SM_READY_CLIENT_CONNECTED) && - CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE)) ? IMG_TRUE : IMG_FALSE; -} - -static INLINE IMG_BOOL PDumpCtrlCaptureInInterval(void) -{ - return ((g_PDumpCtrl.eServiceState == PDUMP_SM_READY_CLIENT_CONNECTED) && - CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL)) ? IMG_TRUE : IMG_FALSE; -} - -static INLINE IMG_BOOL PDumpCtrlCaptureRangePast(void) -{ - return (g_PDumpCtrl.ui32CurrentFrame > g_PDumpCtrl.sCaptureRange.ui32End); -} - -static IMG_BOOL PDumpCtrlIsLastCaptureFrame(void) -{ - if (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_FRAMED) - { - /* Is the next capture frame within the range end limit? */ - if ((g_PDumpCtrl.ui32CurrentFrame + g_PDumpCtrl.sCaptureRange.ui32Interval) > g_PDumpCtrl.sCaptureRange.ui32End) - { - return IMG_TRUE; - } - } - else if (g_PDumpCtrl.ui32DefaultCapMode == PDUMP_CAPMODE_BLOCKED) - { - if (g_PDumpCtrl.ui32CurrentFrame == g_PDumpCtrl.sCaptureRange.ui32End) - { - return IMG_TRUE; - } - } - /* Return false for all other conditions: framed mode but not last frame, - * continuous mode; unset mode. - */ - return IMG_FALSE; -} - -static INLINE IMG_BOOL PDumpCtrlInitPhaseComplete(void) -{ - return !CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_DRIVER_IN_INIT_PHASE); -} - -static INLINE void PDumpCtrlSetInitPhaseComplete(IMG_BOOL bIsComplete) -{ - PDUMP_HERE_VAR; - - if (bIsComplete) - { - UNSET_PDUMP_CONTROL_FLAG(FLAG_IS_DRIVER_IN_INIT_PHASE); - PDUMP_HEREA(102); - } - else - { - SET_PDUMP_CONTROL_FLAG(FLAG_IS_DRIVER_IN_INIT_PHASE); - PDUMP_HEREA(103); - } -} - -static INLINE void PDumpCtrlPowerTransitionStart(void) -{ - g_PDumpCtrl.InPowerTransitionPID = OSGetCurrentProcessID(); -} - -static INLINE void PDumpCtrlPowerTransitionEnd(void) -{ - g_PDumpCtrl.InPowerTransitionPID = 0; -} - -static INLINE IMG_PID PDumpCtrlInPowerTransitionPID(void) -{ - return g_PDumpCtrl.InPowerTransitionPID; -} - -static INLINE IMG_BOOL PDumpCtrlInPowerTransition(void) -{ - IMG_BOOL bPDumpInPowerTransition = IMG_FALSE; - if (PDumpCtrlInPowerTransitionPID()) - { - bPDumpInPowerTransition = IMG_TRUE; - } - return bPDumpInPowerTransition; -} - -static PVRSRV_ERROR PDumpCtrlGetState(IMG_UINT64 *ui64State) -{ - PDUMP_SM eState; - - *ui64State = 0; - - if (PDumpCtrlCaptureOn()) - { - *ui64State |= PDUMP_STATE_CAPTURE_FRAME; - } - - if (PDumpCtrlCaptureInInterval()) - { - *ui64State |= PDUMP_STATE_CAPTURE_IN_INTERVAL; - } - - eState = PDumpCtrlGetModuleState(); - - if (eState == PDUMP_SM_READY_CLIENT_CONNECTED) - { - *ui64State |= PDUMP_STATE_CONNECTED; - } - - if (eState == PDUMP_SM_ERROR_SUSPENDED) - { - *ui64State |= PDUMP_STATE_SUSPENDED; - } - - return PVRSRV_OK; -} - -/****************************************************************************** - End of PDumpCtrl*** functions -******************************************************************************/ - -/* - Wrapper functions which need to be exposed in pdump_km.h for use in other - pdump_*** modules safely. These functions call the specific PDumpCtrl layer - function after acquiring the PDUMP_CTRL_STATE lock, hence making the calls - from other modules hassle free by avoiding the acquire/release CtrlLock - calls. -*/ - -static INLINE void PDumpModuleTransitionState(PDUMP_SM eNewState) -{ - PDumpCtrlLockAcquire(); - g_PDumpCtrl.eServiceState = eNewState; - PDumpCtrlLockRelease(); -} - -void PDumpPowerTransitionStart(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (PDumpIsDevicePermitted(psDeviceNode)) - { - PDumpCtrlLockAcquire(); - PDumpCtrlPowerTransitionStart(); - PDumpCtrlLockRelease(); - } -} - -void PDumpPowerTransitionEnd(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (PDumpIsDevicePermitted(psDeviceNode)) - { - PDumpCtrlLockAcquire(); - PDumpCtrlPowerTransitionEnd(); - PDumpCtrlLockRelease(); - } -} - -static PVRSRV_ERROR PDumpGetCurrentBlockKM(IMG_UINT32 *pui32BlockNum) -{ - PDumpCtrlLockAcquire(); - *pui32BlockNum = PDumpCtrlGetBlock(); - PDumpCtrlLockRelease(); - - return PVRSRV_OK; -} - -static IMG_BOOL PDumpIsClientConnected(void) -{ - IMG_BOOL bPDumpClientConnected; - - PDumpCtrlLockAcquire(); - bPDumpClientConnected = (PDumpCtrlGetModuleState() == PDUMP_SM_READY_CLIENT_CONNECTED); - PDumpCtrlLockRelease(); - - return bPDumpClientConnected; -} - -/* Prototype write allowed for exposure in PDumpCheckFlagsWrite */ -static IMG_BOOL PDumpWriteAllowed(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, IMG_UINT32* ui32ExitHere); - -IMG_BOOL PDumpCheckFlagsWrite(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags) -{ - return PDumpWriteAllowed(psDeviceNode, ui32Flags, NULL); -} - -/*****************************************************************************/ -/* PDump Common Write Layer just above common Transport Layer */ -/*****************************************************************************/ - - -/*! - * \name _PDumpOSGetStreamOffset - */ -static IMG_BOOL _PDumpSetSplitMarker(IMG_HANDLE hStream, IMG_BOOL bRemoveOld) -{ - PVRSRV_ERROR eError; - /* We have to indicate the reader that we wish to split. Insert an EOS packet in the TL stream */ - eError = TLStreamMarkEOS(hStream, bRemoveOld); - - /* If unsuccessful, return false */ - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "TLStreamMarkEOS"); - - return IMG_FALSE; - } - - return IMG_TRUE; -} - -IMG_BOOL PDumpIsDevicePermitted(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if ((void*)psDeviceNode == (void*)PDUMP_MAGIC_COOKIE) - { - /* Always permit PDumping if passed 'magic' cookie */ - return IMG_TRUE; - } - - if (psDeviceNode) - { - if ((psDeviceNode->sDevId.ui32InternalID > PVRSRV_MAX_DEVICES) || - ((psPVRSRVData->ui32PDumpBoundDevice < PVRSRV_MAX_DEVICES) && - (psDeviceNode->sDevId.ui32InternalID != psPVRSRVData->ui32PDumpBoundDevice))) - { - return IMG_FALSE; - } - } - else - { - /* Assert if provided with a NULL psDeviceNode */ - OSDumpStack(); - PVR_ASSERT(psDeviceNode); - return IMG_FALSE; - } - return IMG_TRUE; -} - -/* - Checks in this method were seeded from the original PDumpWriteILock() - and DBGDrivWriteCM() and have grown since to ensure PDump output - matches legacy output. - Note: the order of the checks in this method is important as some - writes have multiple pdump flags set! - */ -static IMG_BOOL PDumpWriteAllowed(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, IMG_UINT32* ui32ExitHere) -{ - PDUMP_HERE_VAR; - - /* No writes if for a different device than the PDump-bound device - * NB. psDeviceNode may be NULL if called during initialisation - */ - if (!PDumpIsDevicePermitted(psDeviceNode)) - { - PDUMP_HERE(5); - goto returnFalse; - } - - /* PDUMP_FLAGS_CONTINUOUS and PDUMP_FLAGS_PERSISTENT can't come together. */ - PVR_ASSERT(IMG_FALSE == ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) && - (ui32Flags & PDUMP_FLAGS_PERSISTENT))); - - /* Lock down the PDUMP_CTRL_STATE struct before calling the following - PDumpCtrl*** functions. This is to avoid updates to the Control data - while we are reading from it */ - PDumpCtrlLockAcquire(); - - /* No writes if in framed mode and range pasted */ - if (PDumpCtrlCaptureRangePast()) - { - PDUMP_HERE(10); - goto unlockAndReturnFalse; - } - - /* No writes while PDump is not ready or is suspended */ - if (PDumpReady() != PVRSRV_OK) - { - PDUMP_HERE(11); - goto unlockAndReturnFalse; - } - - /* Prevent PDumping during a power transition */ - if (PDumpCtrlInPowerTransition()) - { /* except when it's flagged */ - if (ui32Flags & PDUMP_FLAGS_POWER) - { - PDUMP_HERE(20); - goto unlockAndReturnTrue; - } - else if (PDumpCtrlInPowerTransitionPID() == OSGetCurrentProcessID()) - { - PDUMP_HERE(16); - goto unlockAndReturnFalse; - } - } - - /* Always allow dumping in init phase and when persistent flagged */ - if (ui32Flags & PDUMP_FLAGS_PERSISTENT) - { - PDUMP_HERE(12); - goto unlockAndReturnTrue; - } - if (!PDumpCtrlInitPhaseComplete()) - { - PDUMP_HERE(15); - goto unlockAndReturnTrue; - } - - /* The following checks are made when the driver has completed initialisation */ - /* No last/deinit statements allowed when not in initialisation phase */ - else /* init phase over */ - { - if (ui32Flags & PDUMP_FLAGS_DEINIT) - { - PVR_ASSERT(0); - PDUMP_HERE(17); - goto unlockAndReturnFalse; - } - } - - /* If PDump client connected allow continuous flagged writes */ - if (PDUMP_IS_CONTINUOUS(ui32Flags)) - { - if (PDumpCtrlGetModuleState() != PDUMP_SM_READY_CLIENT_CONNECTED) /* Is client connected? */ - { - PDUMP_HERE(13); - goto unlockAndReturnFalse; - } - PDUMP_HERE(14); - goto unlockAndReturnTrue; - } - - /* If in a capture interval but a write is still required. - * Force write out if FLAGS_INTERVAL has been set and we are in - * a capture interval */ - if (ui32Flags & PDUMP_FLAGS_INTERVAL) - { - if (PDumpCtrlCaptureInInterval()){ - PDUMP_HERE(21); - goto unlockAndReturnTrue; - } - } - - /* - If no flags are provided then it is FRAMED output and the frame - range must be checked matching expected behaviour. - */ - if (!PDumpCtrlCaptureOn()) - { - PDUMP_HERE(18); - goto unlockAndReturnFalse; - } - - PDUMP_HERE(19); - -unlockAndReturnTrue: - /* Allow the write to take place */ - - PDumpCtrlLockRelease(); - return IMG_TRUE; - -unlockAndReturnFalse: - PDumpCtrlLockRelease(); -returnFalse: - if (ui32ExitHere != NULL) - { - *ui32ExitHere = here; - } - return IMG_FALSE; -} - - -/*************************************************************************/ /*! - @Function PDumpWriteToBuffer - @Description Write the supplied data to the PDump stream buffer and attempt - to handle any buffer full conditions to ensure all the data - requested to be written, is. - - @Input psDeviceNode The device the PDump pertains to - @Input psStream The address of the PDump stream buffer to write to - @Input pui8Data Pointer to the data to be written - @Input ui32BCount Number of bytes to write - @Input ui32Flags PDump statement flags. - - @Return IMG_UINT32 Actual number of bytes written, may be less than - ui32BCount when buffer full condition could not - be avoided. -*/ /**************************************************************************/ -static IMG_UINT32 PDumpWriteToBuffer(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_STREAM* psStream, - IMG_UINT8 *pui8Data, - IMG_UINT32 ui32BCount, - IMG_UINT32 ui32Flags) -{ - IMG_UINT32 ui32BytesToBeWritten; - IMG_UINT32 ui32Off = 0; - IMG_BYTE *pbyDataBuffer; - IMG_UINT32 ui32BytesAvailable = 0; - static IMG_UINT32 ui32TotalBytesWritten; - PVRSRV_ERROR eError; - IMG_UINT32 uiRetries = 0; - - /* Check PDump stream validity */ - if (psStream->hTL == NULL) - { - PVR_DPF((PVR_DBG_WARNING, "PDumpWriteToBuffer: PDump stream '%s' is invalid", psStream->pszName)); - return 0; - } - - /* This API always called by holding pdump write lock - * to ensure atomic pdump write happened and - * if not holding pdump lock then assert. - */ - PDumpAssertWriteLockHeld(); - - /* No need to check size of data to write as this is asserted - * higher up in the call stack as 1KB and 16KB for each channel - * respectively. */ - - while (ui32BCount > 0) - { - ui32BytesToBeWritten = MIN ( ui32BCount, psStream->ui32MaxAllowedWriteSize ); - - eError = TLStreamReserve2(psStream->hTL, &pbyDataBuffer, ui32BytesToBeWritten, 0, &ui32BytesAvailable, NULL); - if (eError == PVRSRV_ERROR_STREAM_FULL) - { - psStream->ui32BufferFullRetries++; - - /*! Retry write2 only if available bytes is at least 1024 or more. */ - if (ui32BytesAvailable >= 0x400) - { - ui32BytesToBeWritten = ui32BytesAvailable; - PVR_DPF((PVR_DBG_WARNING, "PDumpWriteToBuffer: TL buffer '%s' retrying write2=%u out of %u", psStream->pszName, ui32BytesToBeWritten, ui32BCount)); - eError = TLStreamReserve(psStream->hTL, &pbyDataBuffer, ui32BytesToBeWritten); - /*! Not expected to get PVRSRV_ERROR_STREAM_FULL error and other error may get */ - PVR_ASSERT(eError != PVRSRV_ERROR_STREAM_FULL); - } - else - { - uiRetries++; - PVR_DPF((PVR_DBG_WARNING, "PDumpWriteToBuffer: TL buffer '%s' full, rq=%u, av=%u, retrying write", psStream->pszName, ui32BCount, ui32BytesAvailable)); - - /* Check if we are out of retries , if so then print warning */ - if (uiRetries >= MAX_PDUMP_WRITE_RETRIES) - { - PVR_DPF((PVR_DBG_ERROR, - "PDumpWriteToBuffer: PDump writes blocked to dump %d bytes, %s TLBuffers full for %d seconds, check system", - ui32BCount, - psStream->pszName, - ((200 * uiRetries)/1000))); - - if (uiRetries > psStream->ui32HighestRetriesWatermark) - { - psStream->ui32HighestRetriesWatermark = uiRetries; - } - - psStream->ui32BufferFullAborts++; - uiRetries = 0; - - /* As uiRetries exceed max write retries that means, - * something went wrong in system and thus suspend pdump. - */ - PDumpModuleTransitionState(PDUMP_SM_ERROR_SUSPENDED); - return 0; - } - - OSSleepms(100); - continue; - } - } - - if (eError == PVRSRV_OK) - { - ui32TotalBytesWritten += ui32BytesToBeWritten; - - PVR_ASSERT(pbyDataBuffer != NULL); - - OSDeviceMemCopy((void*)pbyDataBuffer, pui8Data + ui32Off, ui32BytesToBeWritten); - - eError = TLStreamCommit(psStream->hTL, ui32BytesToBeWritten); - if (PVRSRV_OK != eError) - { - return 0; - } - - if (uiRetries > psStream->ui32HighestRetriesWatermark) - { - psStream->ui32HighestRetriesWatermark = uiRetries; - } - - uiRetries = 0; - ui32Off += ui32BytesToBeWritten; - ui32BCount -= ui32BytesToBeWritten; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToBuffer: TLStreamReserve2(%s) unrecoverable error %s", psStream->pszName, PVRSRVGETERRORSTRING(eError))); - /* Fatal -suspend PDump to prevent flooding kernel log buffer */ - PVR_LOG(("Unrecoverable error, PDump suspended!")); - - PDumpModuleTransitionState(PDUMP_SM_ERROR_SUSPENDED); - return 0; - } - - /* - if the capture range is unset - (which is detected via PDumpWriteAllowed()) - */ - - if (!PDumpWriteAllowed(psDeviceNode, ui32Flags, NULL)) - { - psStream->ui32BufferFullAborts++; - break; - } - } - - return ui32Off; -} - -/*************************************************************************/ /*! - @Function PDumpWriteToChannel - @Description Write the supplied data to the PDump channel specified obeying - flags to write to the necessary channel buffers. - - @Input psDeviceNode The device the PDump pertains to - @Input psChannel Address of the script or parameter channel object - @Input/Output psWOff Address of the channel write offsets object to - update on successful writing - @Input pui8Data Pointer to the data to be written - @Input ui32Size Number of bytes to write - @Input ui32Flags PDump statement flags, they may be clear (no flags) - or persistent flagged and they determine how the - which implies framed data, continuous flagged, data - is output. On the first test app run after driver - load, the Display Controller dumps a resource that - is persistent and this needs writing to both the - init (persistent) and main (continuous) channel - buffers to ensure the data is dumped in subsequent - test runs without reloading the driver. - In subsequent runs the PDump client 'freezes' the - init buffer so that only one dump of persistent - data for the "extended init phase" is captured to - the init buffer. - @Return IMG_BOOL True when the data has been consumed, false otherwise -*/ /**************************************************************************/ -static IMG_BOOL PDumpWriteToChannel(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CHANNEL* psChannel, - PDUMP_CHANNEL_WOFFSETS* psWOff, - IMG_UINT8* pui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32Flags) -{ - IMG_UINT32 ui32BytesWritten = 0; - PDUMP_HERE_VAR; - - PDUMP_HERE(210); - - /* At this point, PDumpWriteAllowed() has returned TRUE (or called from - * PDumpParameterChannelZeroedPageBlock() during driver init) we know the - * write must proceed because: - * - pdump is not suspended and - * - there is not an ongoing power transition or POWER override flag is set or - * - in driver init phase with ANY flag set or - * - post init with the pdump client connected and - * - - PERSIST flag is present, xor - * - - the CONTINUOUS flag is present, xor - * - - in capture frame range - */ - PDumpAssertWriteLockHeld(); - - /* Dump data to deinit buffer when flagged as deinit */ - if (ui32Flags & PDUMP_FLAGS_DEINIT) - { - PDUMP_HERE(211); - ui32BytesWritten = PDumpWriteToBuffer(psDeviceNode, - &psChannel->sDeinitStream, - pui8Data, ui32Size, ui32Flags); - if (ui32BytesWritten != ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: DEINIT Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size)); - PDUMP_HERE(212); - return IMG_FALSE; - } - - if (psWOff) - { - psWOff->ui32Deinit += ui32Size; - } - - } - else - { - IMG_BOOL bDumpedToInitAlready = IMG_FALSE; - IMG_BOOL bMainStreamData = IMG_FALSE; - PDUMP_STREAM* psStream = NULL; - IMG_UINT32* pui32Offset = NULL; - - /* Always append persistent data to init phase so it's available on - * subsequent app runs, but also to the main stream if client connected */ - if (ui32Flags & PDUMP_FLAGS_PERSISTENT) - { - PDUMP_HERE(213); - ui32BytesWritten = PDumpWriteToBuffer(psDeviceNode, - &psChannel->sInitStream, - pui8Data, ui32Size, ui32Flags); - if (ui32BytesWritten != ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: PERSIST Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size)); - PDUMP_HERE(214); - return IMG_FALSE; - } - - bDumpedToInitAlready = IMG_TRUE; - if (psWOff) - { - psWOff->ui32Init += ui32Size; - } - - /* Don't write continuous data if client not connected */ - if (PDumpCtrlGetModuleState() != PDUMP_SM_READY_CLIENT_CONNECTED) - { - return IMG_TRUE; - } - } - - /* Prepare to write the data to the main stream for - * persistent, continuous or framed data. Override and use init - * stream if driver still in init phase and we have not written - * to it yet.*/ - PDumpCtrlLockAcquire(); - if (!PDumpCtrlInitPhaseComplete() && !bDumpedToInitAlready) - { - PDUMP_HERE(215); - psStream = &psChannel->sInitStream; - if (psWOff) - { - pui32Offset = &psWOff->ui32Init; - } - } - else - { - PDUMP_HERE(216); - psStream = &psChannel->sMainStream; - if (psWOff) - { - pui32Offset = &psWOff->ui32Main; - } - bMainStreamData = IMG_TRUE; - - } - PDumpCtrlLockRelease(); - - if (PDumpCtrlCapModIsBlocked() && bMainStreamData && !psWOff) - { - /* if PDUMP_FLAGS_BLKDATA flag is set in Blocked mode, Make copy of Main script stream data to Block script stream as well */ - if (ui32Flags & PDUMP_FLAGS_BLKDATA) - { - PDUMP_HERE(217); - ui32BytesWritten = PDumpWriteToBuffer(psDeviceNode, - &psChannel->sBlockStream, - pui8Data, ui32Size, ui32Flags); - if (ui32BytesWritten != ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: BLOCK Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size)); - PDUMP_HERE(218); - return IMG_FALSE; - } - } - } - - /* Write the data to the stream */ - ui32BytesWritten = PDumpWriteToBuffer(psDeviceNode, - psStream, pui8Data, - ui32Size, ui32Flags); - if (ui32BytesWritten != ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: MAIN Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size)); - PDUMP_HERE(219); - return IMG_FALSE; - } - - if (pui32Offset) - { - *pui32Offset += ui32BytesWritten; - } - } - - return IMG_TRUE; -} - -#if defined(PDUMP_DEBUG_OUTFILES) - -static IMG_UINT32 _GenerateChecksum(void *pvData, size_t uiSize) -{ - IMG_UINT32 ui32Sum = 0; - IMG_UINT32 *pui32Data = pvData; - IMG_UINT8 *pui8Data = pvData; - IMG_UINT32 i; - IMG_UINT32 ui32LeftOver; - - for (i = 0; i < uiSize / sizeof(IMG_UINT32); i++) - { - ui32Sum += pui32Data[i]; - } - - ui32LeftOver = uiSize % sizeof(IMG_UINT32); - - while (ui32LeftOver) - { - ui32Sum += pui8Data[uiSize - ui32LeftOver]; - ui32LeftOver--; - } - - return ui32Sum; -} - -#endif - -PVRSRV_ERROR PDumpWriteParameter(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 *pui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32Flags, - IMG_UINT32* pui32FileOffset, - IMG_CHAR* aszFilenameStr) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BOOL bPDumpCtrlInitPhaseComplete = IMG_FALSE; - IMG_UINT32 here = 0; - IMG_INT32 iCount; - - PDumpAssertWriteLockHeld(); - - PVR_ASSERT(pui8Data && (ui32Size!=0)); - PVR_ASSERT(pui32FileOffset && aszFilenameStr); - - PDUMP_HERE(1); - - /* Check if write can proceed? */ - if (!PDumpWriteAllowed(psDeviceNode, ui32Flags, &here)) - { - /* Abort write for the above reason but indicate what happened to - * caller to avoid disrupting the driver, caller should treat it as OK - * but skip any related PDump writes to the script file. */ - return PVRSRV_ERROR_PDUMP_NOT_ALLOWED; - } - - PDUMP_HERE(2); - - PDumpCtrlLockAcquire(); - bPDumpCtrlInitPhaseComplete = PDumpCtrlInitPhaseComplete(); - PDumpCtrlLockRelease(); - - if (!bPDumpCtrlInitPhaseComplete || (ui32Flags & PDUMP_FLAGS_PERSISTENT)) - { - PDUMP_HERE(3); - - /* Init phase stream not expected to get above the file size max */ - PVR_ASSERT(g_PDumpParameters.sWOff.ui32Init < g_PDumpParameters.ui32MaxFileSize); - - /* Return the file write offset at which the parameter data was dumped */ - *pui32FileOffset = g_PDumpParameters.sWOff.ui32Init; - } - else - { - PDUMP_HERE(4); - - /* Do we need to signal the PDump client that a split is required? */ - if (g_PDumpParameters.sWOff.ui32Main + ui32Size > g_PDumpParameters.ui32MaxFileSize) - { - PDUMP_HERE(5); - _PDumpSetSplitMarker(g_PDumpParameters.sCh.sMainStream.hTL, IMG_FALSE); - g_PDumpParameters.ui32FileIdx++; - g_PDumpParameters.sWOff.ui32Main = 0; - } - - /* Return the file write offset at which the parameter data was dumped */ - *pui32FileOffset = g_PDumpParameters.sWOff.ui32Main; - } - - /* Create the parameter file name, based on index, to be used in the script */ - if (g_PDumpParameters.ui32FileIdx == 0) - { - iCount = OSSNPrintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_0_FILE_NAME); - } - else - { - PDUMP_HERE(6); - iCount = OSSNPrintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_N_FILE_NAME, g_PDumpParameters.ui32FileIdx); - } - - PVR_LOG_GOTO_IF_FALSE(((iCount != -1) && (iCount < PDUMP_PARAM_MAX_FILE_NAME)), "OSSNPrintf", errExit); - - /* Write the parameter data to the parameter channel */ - eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL; - if (!PDumpWriteToChannel(psDeviceNode, &g_PDumpParameters.sCh, - &g_PDumpParameters.sWOff, pui8Data, - ui32Size, ui32Flags)) - { - PDUMP_HERE(7); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpWrite", errExit); - } -#if defined(PDUMP_DEBUG_OUTFILES) - else - { - IMG_UINT32 ui32Checksum; - PDUMP_GET_SCRIPT_STRING(); - - ui32Checksum = _GenerateChecksum(pui8Data, ui32Size); - - /* CHK CHKSUM SIZE PRMOFFSET PRMFILE */ - eError = PDumpSNPrintf(hScript, ui32MaxLen, "-- CHK 0x%08X 0x%08X 0x%08X %s", - ui32Checksum, - ui32Size, - *pui32FileOffset, - aszFilenameStr); - PVR_GOTO_IF_ERROR(eError, errExit); - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_RELEASE_SCRIPT_STRING(); - } -#endif - - return PVRSRV_OK; - -errExit: - return eError; -} - - -IMG_BOOL PDumpWriteScript(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hString, IMG_UINT32 ui32Flags) -{ - PDUMP_HERE_VAR; - - PVR_ASSERT(hString); - - PDumpAssertWriteLockHeld(); - - PDUMP_HERE(201); - -#if defined(DEBUG) - /* Since buffer sizes and buffer writing/reading are a balancing act to - * avoid buffer full errors, check here our assumption on the maximum write size. - */ - { - IMG_UINT32 ui32Size = (IMG_UINT32) OSStringLength((const IMG_CHAR *)hString); - if (ui32Size > 0x400) // 1KB - { - PVR_DPF((PVR_DBG_ERROR, "PDUMP large script write %u bytes", ui32Size)); - OSDumpStack(); - } - } -#endif - - if (!PDumpWriteAllowed(psDeviceNode, ui32Flags, NULL)) - { - /* Abort write for the above reasons but indicated it was OK to - * caller to avoid disrupting the driver */ - return IMG_TRUE; - } - - if (PDumpCtrlCapModIsBlocked()) - { - if (ui32Flags & PDUMP_FLAGS_FORCESPLIT) - { - IMG_UINT32 ui32CurrentBlock; - - PDumpGetCurrentBlockKM(&ui32CurrentBlock); - /* Keep Main stream script output files belongs to first and last block only */ - if (ui32CurrentBlock == 1) - { - /* To keep first(0th) block, do not remove old script file while - * splitting to second(1st) block (i.e. bRemoveOld=IMG_FALSE). - * */ - _PDumpSetSplitMarker(g_PDumpScript.sCh.sMainStream.hTL, IMG_FALSE); - } - else - { - /* Previous block's Main script output file will be removed - * before splitting to next - * */ - _PDumpSetSplitMarker(g_PDumpScript.sCh.sMainStream.hTL, IMG_TRUE); - } - - /* Split Block stream output file - * - * We are keeping block script output files from all PDump blocks. - * */ - _PDumpSetSplitMarker(g_PDumpScript.sCh.sBlockStream.hTL, IMG_FALSE); - g_PDumpScript.ui32FileIdx++; - } - } - - return PDumpWriteToChannel(psDeviceNode, &g_PDumpScript.sCh, NULL, - (IMG_UINT8*) hString, - (IMG_UINT32) OSStringLength((IMG_CHAR*) hString), - ui32Flags); -} - - -/*****************************************************************************/ - - -struct _PDUMP_CONNECTION_DATA_ { - ATOMIC_T sRefCount; - POS_LOCK hLock; /*!< Protects access to sListHead. */ - DLLIST_NODE sListHead; - IMG_UINT32 ui32LastSetFrameNumber; - PDUMP_TRANSITION_EVENT eLastEvent; /*!< Last processed transition event */ - PDUMP_TRANSITION_EVENT eFailedEvent; /*!< Failed transition event to retry */ - PFN_PDUMP_SYNCBLOCKS pfnPDumpSyncBlocks; /*!< Callback to PDump sync blocks */ - void *hSyncPrivData; /*!< Sync private data */ -}; - -static PDUMP_CONNECTION_DATA * _PDumpConnectionAcquire(PDUMP_CONNECTION_DATA *psPDumpConnectionData) -{ - IMG_INT iRefCount = OSAtomicIncrement(&psPDumpConnectionData->sRefCount); - - PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d", __func__, - psPDumpConnectionData, iRefCount); - PVR_UNREFERENCED_PARAMETER(iRefCount); - - return psPDumpConnectionData; -} - -static void _PDumpConnectionRelease(PDUMP_CONNECTION_DATA *psPDumpConnectionData) -{ - IMG_INT iRefCount = OSAtomicDecrement(&psPDumpConnectionData->sRefCount); - if (iRefCount == 0) - { - OSLockDestroy(psPDumpConnectionData->hLock); - PVR_ASSERT(dllist_is_empty(&psPDumpConnectionData->sListHead)); - OSFreeMem(psPDumpConnectionData); - } - - PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d", __func__, - psPDumpConnectionData, iRefCount); -} - -/****************************************************************************** - * Function Name : PDumpInitStreams - * Outputs : None - * Returns : - * Description : Create the PDump streams -******************************************************************************/ -static PVRSRV_ERROR PDumpInitStreams(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript) -{ - - PVRSRV_ERROR eError; - TL_STREAM_INFO sTLStreamInfo; - - /* TL - Create the streams */ - - /**************************** Parameter stream ***************************/ - - /* Parameter - Init */ - eError = TLStreamCreate(&psParam->sInitStream.hTL, - psParam->sInitStream.pszName, psParam->sInitStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER | TL_FLAG_PERMANENT_NO_WRAP, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ParamInit", end); - - TLStreamInfo(psParam->sInitStream.hTL, &sTLStreamInfo); - psParam->sInitStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Parameter - Main */ - eError = TLStreamCreate(&psParam->sMainStream.hTL, - psParam->sMainStream.pszName, psParam->sMainStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER , - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ParamMain", param_main_failed); - - TLStreamInfo(psParam->sMainStream.hTL, &sTLStreamInfo); - psParam->sMainStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Parameter - Deinit */ - eError = TLStreamCreate(&psParam->sDeinitStream.hTL, - psParam->sDeinitStream.pszName, psParam->sDeinitStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER | TL_FLAG_PERMANENT_NO_WRAP, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ParamDeinit", param_deinit_failed); - - TLStreamInfo(psParam->sDeinitStream.hTL, &sTLStreamInfo); - psParam->sDeinitStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Parameter - Block */ - /* As in current implementation Block script stream is just a filtered - * Main script stream using PDUMP_FLAGS_BLKDATA flag, no separate - * Parameter stream is needed. Block script will be referring to the - * same Parameters as that of Main script stream. - */ - - /***************************** Script streams ****************************/ - - /* Script - Init */ - eError = TLStreamCreate(&psScript->sInitStream.hTL, - psScript->sInitStream.pszName, psScript->sInitStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER | TL_FLAG_PERMANENT_NO_WRAP, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ScriptInit", script_init_failed); - - TLStreamInfo(psScript->sInitStream.hTL, &sTLStreamInfo); - psScript->sInitStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Script - Main */ - eError = TLStreamCreate(&psScript->sMainStream.hTL, - psScript->sMainStream.pszName, psScript->sMainStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ScriptMain", script_main_failed); - - TLStreamInfo(psScript->sMainStream.hTL, &sTLStreamInfo); - psScript->sMainStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Script - Deinit */ - eError = TLStreamCreate(&psScript->sDeinitStream.hTL, - psScript->sDeinitStream.pszName, psScript->sDeinitStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER | TL_FLAG_PERMANENT_NO_WRAP, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ScriptDeinit", script_deinit_failed); - - TLStreamInfo(psScript->sDeinitStream.hTL, &sTLStreamInfo); - psScript->sDeinitStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - /* Script - Block */ - eError = TLStreamCreate(&psScript->sBlockStream.hTL, - psScript->sBlockStream.pszName, psScript->sBlockStream.ui32BufferSize, - TL_OPMODE_DROP_NEWER, - NULL, NULL, - NULL, NULL); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate ScriptBlock", script_block_failed); - - TLStreamInfo(psScript->sBlockStream.hTL, &sTLStreamInfo); - psScript->sBlockStream.ui32MaxAllowedWriteSize = sTLStreamInfo.maxTLpacketSize; - - return PVRSRV_OK; - -script_block_failed: - TLStreamClose(psScript->sDeinitStream.hTL); - -script_deinit_failed: - TLStreamClose(psScript->sMainStream.hTL); - -script_main_failed: - TLStreamClose(psScript->sInitStream.hTL); - -script_init_failed: - TLStreamClose(psParam->sDeinitStream.hTL); - -param_deinit_failed: - TLStreamClose(psParam->sMainStream.hTL); - -param_main_failed: - TLStreamClose(psParam->sInitStream.hTL); - -end: - return eError; -} -/****************************************************************************** - * Function Name : PDumpDeInitStreams - * Inputs : psParam, psScript - * Outputs : None - * Returns : None - * Description : Deinitialises the PDump streams -******************************************************************************/ -static void PDumpDeInitStreams(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript) -{ - /* Script streams */ - TLStreamClose(psScript->sDeinitStream.hTL); - TLStreamClose(psScript->sMainStream.hTL); - TLStreamClose(psScript->sInitStream.hTL); - TLStreamClose(psScript->sBlockStream.hTL); - - /* Parameter streams */ - TLStreamClose(psParam->sDeinitStream.hTL); - TLStreamClose(psParam->sMainStream.hTL); - TLStreamClose(psParam->sInitStream.hTL); - -} - -/****************************************************************************** - * Function Name : PDumpParameterChannelZeroedPageBlock - * Inputs : psDeviceNode - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Set up the zero page block in the parameter stream -******************************************************************************/ -static PVRSRV_ERROR PDumpParameterChannelZeroedPageBlock(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_UINT8 aui8Zero[32] = { 0 }; - size_t uiBytesToWrite; - PVRSRV_ERROR eError; - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault = PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE; - IMG_UINT32 ui32GeneralNon4KHeapPageSize; - - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, GeneralNon4KHeapPageSize, - &ui32AppHintDefault, &ui32GeneralNon4KHeapPageSize); - OSFreeKMAppHintState(pvAppHintState); - - /* ZeroPageSize can't be smaller than page size */ - g_PDumpParameters.uiZeroPageSize = MAX(ui32GeneralNon4KHeapPageSize, OSGetPageSize()); - - /* ensure the zero page size of a multiple of the zero source on the stack */ - PVR_ASSERT(g_PDumpParameters.uiZeroPageSize % sizeof(aui8Zero) == 0); - - /* the first write gets the parameter file name and stream offset, - * then subsequent writes do not need to know this as the data is - * contiguous in the stream - */ - PDUMP_LOCK(0); - eError = PDumpWriteParameter(psDeviceNode, aui8Zero, - sizeof(aui8Zero), - 0, - &g_PDumpParameters.uiZeroPageOffset, - g_PDumpParameters.szZeroPageFilename); - - /* Also treat PVRSRV_ERROR_PDUMP_NOT_ALLOWED as an error in this case - * as it should never happen since all writes during driver Init are - * allowed. - */ - PVR_GOTO_IF_ERROR(eError, err_write); - - uiBytesToWrite = g_PDumpParameters.uiZeroPageSize - sizeof(aui8Zero); - - while (uiBytesToWrite) - { - IMG_BOOL bOK; - - bOK = PDumpWriteToChannel(psDeviceNode, - &g_PDumpParameters.sCh, - &g_PDumpParameters.sWOff, - aui8Zero, - sizeof(aui8Zero), 0); - - if (!bOK) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PDUMP_BUFFER_FULL, err_write); - } - - uiBytesToWrite -= sizeof(aui8Zero); - } - -err_write: - PDUMP_UNLOCK(0); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to initialise parameter stream zero block")); - } - - return eError; -} - -/****************************************************************************** - * Function Name : PDumpGetParameterZeroPageInfo - * Inputs : None - * Outputs : puiZeroPageOffset: set to the offset of the zero page - * : puiZeroPageSize: set to the size of the zero page - * : ppszZeroPageFilename: set to a pointer to the PRM file name - * : containing the zero page - * Returns : None - * Description : Get information about the zero page -******************************************************************************/ -void PDumpGetParameterZeroPageInfo(PDUMP_FILEOFFSET_T *puiZeroPageOffset, - size_t *puiZeroPageSize, - const IMG_CHAR **ppszZeroPageFilename) -{ - *puiZeroPageOffset = g_PDumpParameters.uiZeroPageOffset; - *puiZeroPageSize = g_PDumpParameters.uiZeroPageSize; - *ppszZeroPageFilename = g_PDumpParameters.szZeroPageFilename; -} - - -PVRSRV_ERROR PDumpInitCommon(void) -{ - PVRSRV_ERROR eError; - PDUMP_HERE_VAR; - - PDUMP_HEREA(2010); - - /* Initialised with default initial value */ - OSAtomicWrite(&g_sConnectionCount, 0); -#if defined(PDUMP_DEBUG_OUTFILES) - OSAtomicWrite(&g_sEveryLineCounter, 1); -#endif - - eError = OSLockCreate(&g_hPDumpWriteLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", errRet); - - /* Initialise PDump control module in common layer, also sets - * state to PDUMP_SM_INITIALISING. - */ - eError = PDumpCtrlInit(); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpCtrlInit", errRetLock); - - /* Call environment specific PDump initialisation Part 2*/ - eError = PDumpInitStreams(&g_PDumpParameters.sCh, &g_PDumpScript.sCh); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpInitStreams", errRetCtrl); - - /* PDump now ready for write calls */ - PDumpModuleTransitionState(PDUMP_SM_READY); - - PDUMP_HEREA(2011); - - /* Test PDump initialised and ready by logging driver details */ - eError = PDumpCommentWithFlags((PVRSRV_DEVICE_NODE*)PDUMP_MAGIC_COOKIE, - PDUMP_FLAGS_CONTINUOUS, - "Driver Product Version: %s - %s (%s)", - PVRVERSION_STRING, PVR_BUILD_DIR, PVR_BUILD_TYPE); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpCommentWithFlags", errRetState); - - eError = PDumpCommentWithFlags((PVRSRV_DEVICE_NODE*)PDUMP_MAGIC_COOKIE, - PDUMP_FLAGS_CONTINUOUS, - "Start of Init Phase"); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpCommentWithFlags", errRetState); - - eError = PDumpParameterChannelZeroedPageBlock((PVRSRV_DEVICE_NODE*)PDUMP_MAGIC_COOKIE); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpParameterChannelZeroedPageBlock", errRetState); - - PDUMP_HEREA(2012); -ret: - return eError; - - -errRetState: - PDumpModuleTransitionState(PDUMP_SM_UNINITIALISED); - PDumpDeInitStreams(&g_PDumpParameters.sCh, &g_PDumpScript.sCh); -errRetCtrl: - PDumpCtrlDeInit(); -errRetLock: - OSLockDestroy(g_hPDumpWriteLock); - PDUMP_HEREA(2013); -errRet: - goto ret; -} -void PDumpDeInitCommon(void) -{ - PDUMP_HERE_VAR; - - PDUMP_HEREA(2020); - - /* Suspend PDump as we want PDumpWriteAllowed to deliberately fail during PDump deinit */ - PDumpModuleTransitionState(PDUMP_SM_DEINITIALISED); - - /*Call environment specific PDump Deinitialisation */ - PDumpDeInitStreams(&g_PDumpParameters.sCh, &g_PDumpScript.sCh); - - /* DeInit the PDUMP_CTRL_STATE data */ - PDumpCtrlDeInit(); - - /* take down the global PDump lock */ - OSLockDestroy(g_hPDumpWriteLock); -} - -void PDumpStopInitPhase(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_UINT32 ui32PDumpBoundDevice = PVRSRVGetPVRSRVData()->ui32PDumpBoundDevice; - - /* Stop the init phase for the PDump-bound device only */ - if (psDeviceNode->sDevId.ui32InternalID == ui32PDumpBoundDevice) - { - /* output this comment to indicate init phase ending OSs */ - PDUMPCOMMENT(psDeviceNode, "Stop Init Phase"); - - PDumpCtrlLockAcquire(); - PDumpCtrlSetInitPhaseComplete(IMG_TRUE); - PDumpCtrlLockRelease(); - } -} - -PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame) -{ - PDumpCtrlLockAcquire(); - *pbIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame(); - PDumpCtrlLockRelease(); - - return PVRSRV_OK; -} - - - -typedef struct _PDUMP_Transition_DATA_ -{ - PFN_PDUMP_TRANSITION pfnCallback; - void *hPrivData; - void *pvDevice; - PDUMP_CONNECTION_DATA *psPDumpConnectionData; - DLLIST_NODE sNode; -} PDUMP_Transition_DATA; - -PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PFN_PDUMP_TRANSITION pfnCallback, - void *hPrivData, - void *pvDevice, - void **ppvHandle) -{ - PDUMP_Transition_DATA *psData; - PVRSRV_ERROR eError; - - psData = OSAllocMem(sizeof(*psData)); - PVR_GOTO_IF_NOMEM(psData, eError, fail_alloc); - - /* Setup the callback and add it to the list for this process */ - psData->pfnCallback = pfnCallback; - psData->hPrivData = hPrivData; - psData->pvDevice = pvDevice; - - OSLockAcquire(psPDumpConnectionData->hLock); - dllist_add_to_head(&psPDumpConnectionData->sListHead, &psData->sNode); - OSLockRelease(psPDumpConnectionData->hLock); - - /* Take a reference on the connection so it doesn't get freed too early */ - psData->psPDumpConnectionData =_PDumpConnectionAcquire(psPDumpConnectionData); - *ppvHandle = psData; - - return PVRSRV_OK; - -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -void PDumpUnregisterTransitionCallback(void *pvHandle) -{ - PDUMP_Transition_DATA *psData = pvHandle; - - OSLockAcquire(psData->psPDumpConnectionData->hLock); - dllist_remove_node(&psData->sNode); - OSLockRelease(psData->psPDumpConnectionData->hLock); - _PDumpConnectionRelease(psData->psPDumpConnectionData); - OSFreeMem(psData); -} - -typedef struct _PDUMP_Transition_DATA_FENCE_SYNC_ -{ - PFN_PDUMP_TRANSITION_FENCE_SYNC pfnCallback; - void *hPrivData; -} PDUMP_Transition_DATA_FENCE_SYNC; - -PVRSRV_ERROR PDumpRegisterTransitionCallbackFenceSync(void *hPrivData, - PFN_PDUMP_TRANSITION_FENCE_SYNC pfnCallback, void **ppvHandle) -{ - PDUMP_Transition_DATA_FENCE_SYNC *psData; - PVRSRV_ERROR eError; - - psData = OSAllocMem(sizeof(*psData)); - PVR_GOTO_IF_NOMEM(psData, eError, fail_alloc_exit); - - /* Setup the callback and add it to the list for this process */ - psData->pfnCallback = pfnCallback; - psData->hPrivData = hPrivData; - - *ppvHandle = psData; - return PVRSRV_OK; - -fail_alloc_exit: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -void PDumpUnregisterTransitionCallbackFenceSync(void *pvHandle) -{ - PDUMP_Transition_DATA_FENCE_SYNC *psData = pvHandle; - - OSFreeMem(psData); -} - -static PVRSRV_ERROR _PDumpTransition(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PDUMP_TRANSITION_EVENT eEvent, - IMG_UINT32 ui32PDumpFlags) -{ - DLLIST_NODE *psNode, *psNext; - PVRSRV_ERROR eError; - - /* Only call the callbacks if we've really got new event */ - if ((eEvent != psPDumpConnectionData->eLastEvent) && (eEvent != PDUMP_TRANSITION_EVENT_NONE)) - { - OSLockAcquire(psPDumpConnectionData->hLock); - - dllist_foreach_node(&psPDumpConnectionData->sListHead, psNode, psNext) - { - PDUMP_Transition_DATA *psData = - IMG_CONTAINER_OF(psNode, PDUMP_Transition_DATA, sNode); - - eError = psData->pfnCallback(psData->hPrivData, psData->pvDevice, eEvent, ui32PDumpFlags); - - if (eError != PVRSRV_OK) - { - OSLockRelease(psPDumpConnectionData->hLock); - psPDumpConnectionData->eFailedEvent = eEvent; /* Save failed event to retry */ - return eError; - } - } - OSLockRelease(psPDumpConnectionData->hLock); - - /* PDump sync blocks: - * - * Client sync prims are managed in blocks. - * - * sync-blocks gets re-dumped each time we enter into capture range or - * enter into new PDump block. Ensure that live-FW thread and app-thread - * are synchronised before this. - * - * At playback time, script-thread and sim-FW threads needs to be - * synchronised before re-loading sync-blocks. - * */ - psPDumpConnectionData->pfnPDumpSyncBlocks(psDeviceNode, psPDumpConnectionData->hSyncPrivData, eEvent); - - if (psDeviceNode->hTransition) - { - PDUMP_Transition_DATA_FENCE_SYNC *psData = (PDUMP_Transition_DATA_FENCE_SYNC*)psDeviceNode->hTransition; - psData->pfnCallback(psData->hPrivData, eEvent); - } - - psPDumpConnectionData->eLastEvent = eEvent; - psPDumpConnectionData->eFailedEvent = PDUMP_TRANSITION_EVENT_NONE; /* Clear failed event on success */ - } - return PVRSRV_OK; -} - -static PVRSRV_ERROR _PDumpBlockTransition(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PDUMP_TRANSITION_EVENT eEvent, - IMG_UINT32 ui32PDumpFlags) -{ - - /* Need to follow following sequence for Block transition: - * - * (1) _PDumpTransition with BLOCK_FINISHED event for current block - * (2) Split MAIN and Block script files - * (3) _PDumpTransition with BLOCK_STARTED event for new block - * - * */ - - PVRSRV_ERROR eError; - IMG_UINT32 ui32CurrentBlock; - IMG_UINT32 ui32Flags = (PDUMP_FLAGS_BLKDATA | PDUMP_FLAGS_CONTINUOUS); /* Internal Block mode specific PDump flags */ - - PDumpGetCurrentBlockKM(&ui32CurrentBlock); - - if (eEvent == PDUMP_TRANSITION_EVENT_BLOCK_FINISHED) - { - /* (1) Current block has finished */ - eError = _PDumpTransition(psDeviceNode, - psPDumpConnectionData, - PDUMP_TRANSITION_EVENT_BLOCK_FINISHED, - ui32PDumpFlags); - PVR_RETURN_IF_ERROR(eError); - - (void) PDumpCommentWithFlags(psDeviceNode, ui32Flags, - "}PDUMP_BLOCK_END_0x%08X", - ui32CurrentBlock - 1); /* Add pdump-block end marker */ - - /* (2) Split MAIN and BLOCK script out files on current pdump-block end */ - ui32Flags |= PDUMP_FLAGS_FORCESPLIT; - - (void) PDumpCommentWithFlags(psDeviceNode, ui32Flags, - "PDUMP_BLOCK_START_0x%08X{", - ui32CurrentBlock); /* Add pdump-block start marker */ - } - - /* (3) New block has started */ - return _PDumpTransition(psDeviceNode, - psPDumpConnectionData, - PDUMP_TRANSITION_EVENT_BLOCK_STARTED, - ui32PDumpFlags); -} - - -PVRSRV_ERROR PDumpTransition(PVRSRV_DEVICE_NODE *psDeviceNode, - PDUMP_CONNECTION_DATA *psPDumpConnectionData, - PDUMP_TRANSITION_EVENT eEvent, - IMG_UINT32 ui32PDumpFlags) -{ - if ((eEvent == PDUMP_TRANSITION_EVENT_BLOCK_FINISHED) || (eEvent == PDUMP_TRANSITION_EVENT_BLOCK_STARTED)) - { - /* Block mode transition events */ - PVR_ASSERT(PDumpCtrlCapModIsBlocked()); - return _PDumpBlockTransition(psDeviceNode, psPDumpConnectionData, eEvent, ui32PDumpFlags); - } - else - { - /* Non-block mode transition events */ - return _PDumpTransition(psDeviceNode, psPDumpConnectionData, eEvent, ui32PDumpFlags); - } -} - -static PVRSRV_ERROR PDumpIsCaptureFrame(IMG_BOOL *bInCaptureRange) -{ - IMG_UINT64 ui64State = 0; - PVRSRV_ERROR eError; - - eError = PDumpCtrlGetState(&ui64State); - - *bInCaptureRange = (ui64State & PDUMP_STATE_CAPTURE_FRAME) ? IMG_TRUE : IMG_FALSE; - - return eError; -} - -PVRSRV_ERROR PDumpGetStateKM(IMG_UINT64 *ui64State) -{ - PVRSRV_ERROR eError; - - PDumpCtrlLockAcquire(); - eError = PDumpCtrlGetState(ui64State); - PDumpCtrlLockRelease(); - - return eError; -} - -/****************************************************************************** - * Function Name : PDumpUpdateBlockCtrlStatus - * Inputs : ui32Frame - frame number - * Outputs : None - * Returns : IMG_TRUE if Block transition is required, else IMG_FALSE - * Description : Updates Block Ctrl status and checks if block transition - * is required or not -******************************************************************************/ -static INLINE IMG_BOOL PDumpUpdateBlockCtrlStatus(IMG_UINT32 ui32Frame) -{ - IMG_BOOL bForceBlockTransition; - - /* Default length of first block will be PDUMP_BLOCKLEN_MIN. - * User can force it to be same as block length provided (i.e. ui32BlockLength) - * through pdump client. - * - * Here is how blocks will be created. - * - * Assume, - * ui32BlockLength = 20 - * PDUMP_BLOCKLEN_MIN = 10 - * - * Then different pdump blocks will have following number of frames in it: - * - * if(!PDumpCtrlMinimalFirstBlock()) - * { - * //pdump -b - * block 0 -> 00...09 -->minimal first block - * block 1 -> 10...29 - * block 2 -> 30...49 - * block 3 -> 50...69 - * ... - * } - * else - * { - * //pdump -bf - * block 0 -> 00...19 - * block 1 -> 20...39 - * block 2 -> 40...59 - * block 3 -> 60...79 - * ... - * } - * - * */ - - if (PDumpCtrlMinimalFirstBlock()) - { - bForceBlockTransition = ((ui32Frame >= PDUMP_BLOCKLEN_MIN) && !((ui32Frame - PDUMP_BLOCKLEN_MIN) % g_PDumpCtrl.sBlockCtrl.ui32BlockLength)) || (ui32Frame == 0); - } - else - { - bForceBlockTransition = !(ui32Frame % g_PDumpCtrl.sBlockCtrl.ui32BlockLength); - } - - if (bForceBlockTransition) /* Entering in new pdump-block */ - { - /* Update block number - * - * Logic below is to maintain block number and frame number mappings - * in case of some applications where setFrame(0) gets called twice - * at the start. - * */ - PDumpCtrlLockAcquire(); - PDumpCtrlSetBlock((ui32Frame == 0)? 0 : (PDumpCtrlGetBlock() + 1)); - PDumpCtrlLockRelease(); - - if (ui32Frame > 0) /* Do not do transition on first frame itself */ - { - return IMG_TRUE; /* Transition */ - } - } - return IMG_FALSE; /* No transition */ -} - -PVRSRV_ERROR PDumpForceCaptureStopKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* If call is not for the pdump-bound device, return immediately - * taking no action. - */ - if (!PDumpIsDevicePermitted(psDeviceNode)) - { - return PVRSRV_OK; - } - - if (!PDumpCtrlCapModIsBlocked()) - { - PVR_DPF((PVR_DBG_ERROR, "%s: This call is valid only in Block mode of PDump i.e. pdump -b", __func__)); - return PVRSRV_ERROR_PDUMP_NOT_ALLOWED; - } - - (void) PDumpCommentWithFlags(psDeviceNode, - PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_BLKDATA, - "PDdump forced STOP capture request received at frame %u", - g_PDumpCtrl.ui32CurrentFrame); - - PDumpCtrlLockAcquire(); - eError = PDumpCtrlForcedStop(); - PDumpCtrlLockRelease(); - - return eError; -} - -static PVRSRV_ERROR _PDumpSetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Frame) -{ - PDUMP_CONNECTION_DATA *psPDumpConnectionData = psConnection->psPDumpConnectionData; - PDUMP_TRANSITION_EVENT eTransitionEvent = PDUMP_TRANSITION_EVENT_NONE; - IMG_BOOL bWasInCaptureRange = IMG_FALSE; - IMG_BOOL bIsInCaptureRange = IMG_FALSE; - PVRSRV_ERROR eError; - - /* - Note: - As we can't test to see if the new frame will be in capture range - before we set the frame number and we don't want to roll back the - frame number if we fail then we have to save the "transient" data - which decides if we're entering or exiting capture range along - with a failure boolean so we know what's required on a retry - */ - if (psPDumpConnectionData->ui32LastSetFrameNumber != ui32Frame) - { - (void) PDumpCommentWithFlags(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Set pdump frame %u", ui32Frame); - - /* - The boolean values below decide if the PDump transition - should trigger because of the current context setting the - frame number, hence the functions below should execute - atomically and do not give a chance to some other context - to transition - */ - PDumpCtrlLockAcquire(); - - PDumpIsCaptureFrame(&bWasInCaptureRange); - PDumpCtrlSetCurrentFrame(ui32Frame); - PDumpIsCaptureFrame(&bIsInCaptureRange); - - PDumpCtrlLockRelease(); - - psPDumpConnectionData->ui32LastSetFrameNumber = ui32Frame; - - /* Check for any transition event only if client is connected */ - if (PDumpIsClientConnected()) - { - if (!bWasInCaptureRange && bIsInCaptureRange) - { - eTransitionEvent = PDUMP_TRANSITION_EVENT_RANGE_ENTERED; - } - else if (bWasInCaptureRange && !bIsInCaptureRange) - { - eTransitionEvent = PDUMP_TRANSITION_EVENT_RANGE_EXITED; - } - - if (PDumpCtrlCapModIsBlocked()) - { - /* Update block ctrl status and check for block transition */ - if (PDumpUpdateBlockCtrlStatus(ui32Frame)) - { - PVR_ASSERT(eTransitionEvent == PDUMP_TRANSITION_EVENT_NONE); /* Something went wrong, can't handle two events at same time */ - eTransitionEvent = PDUMP_TRANSITION_EVENT_BLOCK_FINISHED; - } - } - } - } - else if (psPDumpConnectionData->eFailedEvent != PDUMP_TRANSITION_EVENT_NONE) - { - /* Load the Transition data so we can try again */ - eTransitionEvent = psPDumpConnectionData->eFailedEvent; - } - else - { - /* New frame is the same as the last frame set and the last - * transition succeeded, no need to perform another transition. - */ - return PVRSRV_OK; - } - - if (eTransitionEvent != PDUMP_TRANSITION_EVENT_NONE) - { - DEBUG_OUTFILES_COMMENT(psDeviceNode, "PDump transition event(%u)-begin frame %u (post)", eTransitionEvent, ui32Frame); - eError = PDumpTransition(psDeviceNode, psPDumpConnectionData, eTransitionEvent, PDUMP_FLAGS_NONE); - DEBUG_OUTFILES_COMMENT(psDeviceNode, "PDump transition event(%u)-complete frame %u (post)", eTransitionEvent, ui32Frame); - PVR_RETURN_IF_ERROR(eError); - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Frame) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* If call is not for the pdump-bound device, return immediately - * taking no action. - */ - if (!PDumpIsDevicePermitted(psDeviceNode)) - { - return PVRSRV_OK; - } - -#if defined(PDUMP_TRACE_STATE) - PVR_DPF((PVR_DBG_WARNING, "PDumpSetFrameKM: ui32Frame( %d )", ui32Frame)); -#endif - - DEBUG_OUTFILES_COMMENT(psDeviceNode, "(pre) Set pdump frame %u", ui32Frame); - - eError = _PDumpSetFrameKM(psConnection, psDeviceNode, ui32Frame); - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) - { - PVR_LOG_ERROR(eError, "_PDumpSetFrameKM"); - } - - DEBUG_OUTFILES_COMMENT(psDeviceNode, "(post) Set pdump frame %u", ui32Frame); - - return eError; -} - -PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32* pui32Frame) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* - It may be safe to avoid acquiring this lock here as all the other calls - which read/modify current frame will wait on the PDump Control bridge - lock first. Also, in no way as of now, does the PDumping app modify the - current frame through a call which acquires the global bridge lock. - Still, as a legacy we acquire and then read. - */ - PDumpCtrlLockAcquire(); - - *pui32Frame = PDumpCtrlGetCurrentFrame(); - - PDumpCtrlLockRelease(); - return eError; -} - -PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Mode, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, - IMG_UINT32 ui32Interval, - IMG_UINT32 ui32MaxParamFileSize) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* NB. We choose not to check that the device is the pdump-bound - * device here, as this particular bridge call is made only from the pdump - * tool itself (which may only connect to the bound device). - */ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - - eError = PDumpReady(); - PVR_LOG_RETURN_IF_ERROR(eError, "PDumpReady"); - - /* Validate parameters */ - if ((ui32End < ui32Start) || (ui32Mode > PDUMP_CAPMODE_MAX)) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - else if (ui32Mode == PDUMP_CAPMODE_BLOCKED) - { - if ((ui32Interval < PDUMP_BLOCKLEN_MIN) || (ui32Interval > PDUMP_BLOCKLEN_MAX)) - { - /* Force client to set ui32Interval (i.e. block length) in valid range */ - eError = PVRSRV_ERROR_PDUMP_INVALID_BLOCKLEN; - } - - if (ui32End != PDUMP_FRAME_MAX) - { - /* Force client to set ui32End to PDUMP_FRAME_MAX */ - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - } - else if ((ui32Mode != PDUMP_CAPMODE_UNSET) && (ui32Interval < 1)) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_LOG_RETURN_IF_ERROR(eError, "PDumpSetDefaultCaptureParamsKM"); - - /* - Acquire PDUMP_CTRL_STATE struct lock before modifications as a - PDumping app may be reading the state data for some checks - */ - PDumpCtrlLockAcquire(); - PDumpCtrlSetDefaultCaptureParams(ui32Mode, ui32Start, ui32End, ui32Interval); - PDumpCtrlLockRelease(); - - if (ui32MaxParamFileSize == 0) - { - g_PDumpParameters.ui32MaxFileSize = PRM_FILE_SIZE_MAX; - } - else - { - g_PDumpParameters.ui32MaxFileSize = ui32MaxParamFileSize; - } - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpReg32 - * Inputs : pszPDumpDevName, Register offset, and value to write - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write -******************************************************************************/ -PVRSRV_ERROR PDumpReg32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_UINT32 ui32Data, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", pszPDumpRegName, ui32Reg, ui32Data); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpReg64 - * Inputs : pszPDumpDevName, Register offset, and value to write - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write -******************************************************************************/ -PVRSRV_ERROR PDumpReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_UINT64 ui64Data, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_UINT32 ui32UpperValue = (IMG_UINT32) (ui64Data >> 32); - IMG_UINT32 ui32LowerValue = (IMG_UINT32) (ui64Data); -#endif - - PDUMP_GET_SCRIPT_STRING() - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", - pszPDumpRegName, ui32Reg, ui32LowerValue); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", - pszPDumpRegName, ui32Reg + 4, ui32UpperValue); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#else - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X 0x%010" IMG_UINT64_FMTSPECX, pszPDumpRegName, ui32Reg, ui64Data); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#endif - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpRegLabelToReg64 - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write - * from a register label -******************************************************************************/ -PVRSRV_ERROR PDumpRegLabelToReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegDst, - IMG_UINT32 ui32RegSrc, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X :%s:0x%08X", pszPDumpRegName, ui32RegDst, pszPDumpRegName, ui32RegSrc); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; - -} - -/****************************************************************************** - * Function Name : PDumpRegLabelToMem32 - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory write - * from a register label -******************************************************************************/ -PVRSRV_ERROR PDumpRegLabelToMem32(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMR); - - eErr = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceName, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicName, - &uiPDumpSymbolicOffset, - &uiNextSymName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%"IMG_UINT64_FMTSPECX" :%s:0x%08X",aszMemspaceName, aszSymbolicName, - uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpRegLabelToMem64 - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory write - * from a register label -******************************************************************************/ -PVRSRV_ERROR PDumpRegLabelToMem64(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMR); - - eErr = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceName, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicName, - &uiPDumpSymbolicOffset, - &uiNextSymName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW64 :%s:%s:0x%"IMG_UINT64_FMTSPECX" :%s:0x%08X",aszMemspaceName, aszSymbolicName, - uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpPhysHandleToInternalVar64 - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents an internal var - write using a PDump pages handle -******************************************************************************/ -PVRSRV_ERROR PDumpPhysHandleToInternalVar64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszInternalVar, - IMG_HANDLE hPdumpPages, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR *pszSymbolicName; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpGetSymbolicAddr(hPdumpPages, - &pszSymbolicName); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "WRW %s %s:0x%llX", - pszInternalVar, pszSymbolicName, 0llu); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s 0x%X", pszPDumpVarName, 0); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#endif - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpMemLabelToInternalVar64 - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents an internal var - * write using a memory label -******************************************************************************/ -PVRSRV_ERROR PDumpMemLabelToInternalVar64(IMG_CHAR *pszInternalVar, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - PVRSRV_DEVICE_NODE *psDeviceNode; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMR); - - eErr = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceName, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicName, - &uiPDumpSymbolicOffset, - &uiNextSymName); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s :%s:%s:0x%"IMG_UINT64_FMTSPECX, pszInternalVar, - aszMemspaceName, aszSymbolicName, uiPDumpSymbolicOffset); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s :%s:%s:0x%"IMG_UINT64_FMTSPECX, pszPDumpVarName, - aszMemspaceName, aszSymbolicName, uiPDumpSymbolicOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "SHR %s %s 0x20", pszPDumpVarName, pszPDumpVarName); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#endif - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpInternalVarToMemLabel - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory label - * write using an internal var -******************************************************************************/ -PVRSRV_ERROR PDumpInternalVarToMemLabel(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - PVRSRV_DEVICE_NODE *psDeviceNode; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMR); - - eErr = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceName, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicName, - &uiPDumpSymbolicOffset, - &uiNextSymName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%"IMG_UINT64_FMTSPECX" %s", - aszMemspaceName, aszSymbolicName, uiPDumpSymbolicOffset, pszInternalVar); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s 0x%X", pszPDumpVarName, 0); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#endif - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function PDumpWriteRegORValueOp - - @Description - - Emits the PDump commands for the logical OR operation - Var <- Var OR Value - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpWriteVarORValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; - IMG_UINT32 ui32UpperValue = (IMG_UINT32) (ui64Value >> 32); - IMG_UINT32 ui32LowerValue = (IMG_UINT32) (ui64Value); -#endif - - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - "OR %s %s 0x%X", -#else - "OR %s %s 0x%"IMG_UINT64_FMTSPECX, -#endif - pszInternalVariable, - pszInternalVariable, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - ui32LowerValue -#else - ui64Value -#endif - ); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVariable); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "OR %s %s 0x%X", - pszPDumpVarName, - pszPDumpVarName, - ui32UpperValue); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); -#endif - - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function PDumpWriteVarORVarOp - - @Description - - Emits the PDump commands for the logical OR operation - Var <- Var OR Var2 - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpWriteVarORVarOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszInternalVar2, - const IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "OR %s %s %s", - pszInternalVar, - pszInternalVar, - pszInternalVar2); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - PDUMP_UNLOCK(ui32PDumpFlags); - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function PDumpWriteVarANDVarOp - - @Description - - Emits the PDump commands for the logical AND operation - Var <- Var AND Var2 - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpWriteVarANDVarOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVar, - const IMG_CHAR *pszInternalVar2, - const IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "AND %s %s %s", - pszInternalVar, - pszInternalVar, - pszInternalVar2); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - PDUMP_UNLOCK(ui32PDumpFlags); - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpRegLabelToInternalVar - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which writes a register label into - * an internal variable -******************************************************************************/ -PVRSRV_ERROR PDumpRegLabelToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s :%s:0x%08X", pszInternalVar, pszPDumpRegName, ui32Reg); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW %s :%s:0x%08X", pszPDumpVarName, pszPDumpRegName, ui32Reg + 4); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); -#endif - - PDUMP_UNLOCK(ui32Flags); - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; - -} - -/****************************************************************************** - * Function Name : PDumpInternalVarToReg32 - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write - * from an internal variable -******************************************************************************/ -PVRSRV_ERROR PDumpInternalVarToReg32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpInternalVarToReg64 - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write - * from an internal variable -******************************************************************************/ -PVRSRV_ERROR PDumpInternalVarToReg64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - PDUMP_GET_SCRIPT_STRING() - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW :%s:0x%08X %s", pszPDumpRegName, ui32Reg + 4, pszPDumpVarName); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - -#else - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#endif - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - - - -/****************************************************************************** - * Function Name : PDumpMemLabelToMem32 - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory write from - * a memory label -******************************************************************************/ -PVRSRV_ERROR PDumpMemLabelToMem32(PMR *psPMRSource, - PMR *psPMRDest, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest; - IMG_DEVMEM_OFFSET_T uiNextSymNameSource; - IMG_DEVMEM_OFFSET_T uiNextSymNameDest; - PVRSRV_DEVICE_NODE *psDeviceNode; - - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMRSource); - - eErr = PMR_PDumpSymbolicAddr(psPMRSource, - uiLogicalOffsetSource, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceNameSource, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicNameSource, - &uiPDumpSymbolicOffsetSource, - &uiNextSymNameSource); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PMR_PDumpSymbolicAddr(psPMRDest, - uiLogicalOffsetDest, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceNameDest, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicNameDest, - &uiPDumpSymbolicOffsetDest, - &uiNextSymNameDest); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "WRW :%s:%s:0x%"IMG_UINT64_FMTSPECX" :%s:%s:0x%"IMG_UINT64_FMTSPECX, - aszMemspaceNameDest, aszSymbolicNameDest, - uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, - aszSymbolicNameSource, uiPDumpSymbolicOffsetSource); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpMemLabelToMem64 - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a memory write from - * a memory label -******************************************************************************/ -PVRSRV_ERROR PDumpMemLabelToMem64(PMR *psPMRSource, - PMR *psPMRDest, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource, - IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest; - IMG_DEVMEM_OFFSET_T uiNextSymNameSource; - IMG_DEVMEM_OFFSET_T uiNextSymNameDest; - PVRSRV_DEVICE_NODE *psDeviceNode; - - - PDUMP_GET_SCRIPT_STRING() - - psDeviceNode = PMR_DeviceNode(psPMRSource); - - eErr = PMR_PDumpSymbolicAddr(psPMRSource, - uiLogicalOffsetSource, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceNameSource, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicNameSource, - &uiPDumpSymbolicOffsetSource, - &uiNextSymNameSource); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PMR_PDumpSymbolicAddr(psPMRDest, - uiLogicalOffsetDest, - PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH, - aszMemspaceNameDest, - PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH, - aszSymbolicNameDest, - &uiPDumpSymbolicOffsetDest, - &uiNextSymNameDest); - - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "WRW64 :%s:%s:0x%"IMG_UINT64_FMTSPECX" :%s:%s:0x%"IMG_UINT64_FMTSPECX, - aszMemspaceNameDest, aszSymbolicNameDest, - uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, - aszSymbolicNameSource, uiPDumpSymbolicOffsetSource); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - - -/*! -******************************************************************************* - - @Function PDumpWriteVarSHRValueOp - - @Description - - Emits the PDump commands for the logical SHR operation - Var <- Var SHR Value - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpWriteVarSHRValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; - IMG_UINT32 ui32UpperValue = (IMG_UINT32) (ui64Value >> 32); - IMG_UINT32 ui32LowerValue = (IMG_UINT32) (ui64Value); -#endif - - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - "SHR %s %s 0x%X", -#else - "SHR %s %s 0x%"IMG_UINT64_FMTSPECX, -#endif - pszInternalVariable, - pszInternalVariable, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - ui32LowerValue -#else - ui64Value -#endif - ); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVariable); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHR %s %s 0x%X", - pszPDumpVarName, - pszPDumpVarName, - ui32UpperValue); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); -#endif - - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - -/*! -******************************************************************************* - - @Function PDumpWriteRegANDValueOp - - @Description - - Emits the PDump commands for the logical AND operation - Var <- Var AND Value - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpWriteVarANDValueOp(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszInternalVariable, - const IMG_UINT64 ui64Value, - const IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; - IMG_UINT32 ui32UpperValue = (IMG_UINT32) (ui64Value >> 32); - IMG_UINT32 ui32LowerValue = (IMG_UINT32) (ui64Value); -#endif - - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - "AND %s %s 0x%X", -#else - "AND %s %s 0x%"IMG_UINT64_FMTSPECX, -#endif - pszInternalVariable, - pszInternalVariable, -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - ui32LowerValue -#else - ui64Value -#endif - ); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVariable); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "AND %s %s 0x%X", - pszPDumpVarName, - pszPDumpVarName, - ui32UpperValue); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32PDumpFlags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); -#endif - - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpSAW - * Inputs : pszDevSpaceName -- device space from which to output - * ui32Offset -- offset value from register base - * ui32NumSaveBytes -- number of bytes to output - * pszOutfileName -- name of file to output to - * ui32OutfileOffsetByte -- offset into output file to write - * uiPDumpFlags -- flags to pass to PDumpOSWriteScript - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Dumps the contents of a register bank into a file - * NB: ui32NumSaveBytes must be divisible by 4 -******************************************************************************/ -PVRSRV_ERROR PDumpSAW(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszDevSpaceName, - IMG_UINT32 ui32HPOffsetBytes, - IMG_UINT32 ui32NumSaveBytes, - IMG_CHAR *pszOutfileName, - IMG_UINT32 ui32OutfileOffsetByte, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - PDUMP_GET_SCRIPT_STRING() - - PVR_DPF((PVR_DBG_ERROR, "PDumpSAW")); - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SAW :%s:0x%x 0x%x 0x%x %s\n", - pszDevSpaceName, - ui32HPOffsetBytes, - ui32NumSaveBytes / (IMG_UINT32)sizeof(IMG_UINT32), - ui32OutfileOffsetByte, - pszOutfileName); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpSNPrintf failed: eError=%u", eError)); - PDUMP_RELEASE_SCRIPT_STRING() - return eError; - } - - PDUMP_LOCK(uiPDumpFlags); - if (! PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags)) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpWriteScript failed!")); - } - PDUMP_UNLOCK(uiPDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; - -} - - -/****************************************************************************** - * Function Name : PDumpRegPolKM - * Inputs : Description of what this register read is trying to do - * pszPDumpDevName - * Register offset - * expected value - * mask for that value - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents a register read - * with the expected value -******************************************************************************/ -PVRSRV_ERROR PDumpRegPolKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator) -{ - /* Timings correct for Linux and XP */ - /* Timings should be passed in */ - #define POLL_DELAY 1000U - #define POLL_COUNT_LONG (2000000000U / POLL_DELAY) - #define POLL_COUNT_SHORT (1000000U / POLL_DELAY) - - PVRSRV_ERROR eErr; - IMG_UINT32 ui32PollCount; - - PDUMP_GET_SCRIPT_STRING(); - - ui32PollCount = POLL_COUNT_LONG; - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d", - pszPDumpRegName, ui32RegAddr, ui32RegValue, - ui32Mask, eOperator, ui32PollCount, POLL_DELAY); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING() - return PVRSRV_OK; -} - -/*! - * \name PDumpOSVerifyLineEnding - */ -static void _PDumpVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax) -{ - IMG_UINT32 ui32Count; - IMG_CHAR* pszBuf = hBuffer; - - /* strlen */ - ui32Count = OSStringNLength(pszBuf, ui32BufferSizeMax); - - /* Put \n sequence at the end if it isn't already there */ - if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count= (PVRSRV_PDUMP_MAX_COMMENT_SIZE+80))) - { - eErr = PVRSRV_ERROR_PDUMP_BUF_OVERFLOW; - } - - /* Append the comment to the script stream */ - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "-- %s", - pszTemp); -#else - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "-- %s", - pszComment); -#endif - if ((eErr != PVRSRV_OK) && - (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW)) - { - PVR_LOG_GOTO_IF_ERROR(eErr, "PDumpSNPrintf", ErrUnlock); - } - - if (!PDumpWriteScript(psDeviceNode, hScript, ui32Flags)) - { - if (PDUMP_IS_CONTINUOUS(ui32Flags)) - { - eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL; - PVR_LOG_GOTO_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock); - } - else - { - eErr = PVRSRV_ERROR_CMD_NOT_PROCESSED; - PVR_LOG_GOTO_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock); - } - } - -ErrUnlock: - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCommentKM - * Inputs : ui32CommentSize, pszComment, ui32Flags - * Outputs : None - * Returns : None - * Description : Dumps a pre-formatted comment, primarily called from the - * : bridge. -******************************************************************************/ -PVRSRV_ERROR PDumpCommentKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CommentSize, - IMG_CHAR *pszComment, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(ui32CommentSize); /* Generated bridge code appends null char to pszComment. */ - - PDUMP_LOCK(ui32Flags); - - eErr = _PDumpWriteComment(psDeviceNode, pszComment, ui32Flags); - - PDUMP_UNLOCK(ui32Flags); - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCommentWithFlagsNoLockVA - * Inputs : ui32Flags - PDump flags - * : pszFormat - format string for comment - * : args - pre-started va_list args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comment, caller need to acquire pdump lock - * explicitly before calling this function -******************************************************************************/ -static PVRSRV_ERROR __attribute__ ((format (printf, 3, 0))) -PDumpCommentWithFlagsNoLockVA(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - const IMG_CHAR * pszFormat, va_list args) -{ - IMG_INT32 iCount; - PVRSRV_ERROR eErr = PVRSRV_OK; - PDUMP_GET_MSG_STRING(); - - /* Construct the string */ - iCount = OSVSNPrintf(pszMsg, ui32MaxLen, pszFormat, args); - PVR_LOG_GOTO_IF_FALSE(((iCount != -1) && (iCount < ui32MaxLen)), "OSVSNPrintf", exit); - - eErr = _PDumpWriteComment(psDeviceNode, pszMsg, ui32Flags); - -exit: - PDUMP_RELEASE_MSG_STRING(); - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCommentWithFlagsNoLock - * Inputs : ui32Flags - PDump flags - * : pszFormat - format string for comment - * : ... - args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comment, caller need to acquire pdump lock - * explicitly before calling this function. -******************************************************************************/ -__printf(3, 4) -static PVRSRV_ERROR PDumpCommentWithFlagsNoLock(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - IMG_CHAR *pszFormat, ...) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - va_list args; - - va_start(args, pszFormat); - PDumpCommentWithFlagsNoLockVA(psDeviceNode, ui32Flags, pszFormat, args); - va_end(args); - - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCommentWithFlags - * Inputs : ui32Flags - PDump flags - * : pszFormat - format string for comment - * : ... - args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comments -******************************************************************************/ -PVRSRV_ERROR PDumpCommentWithFlags(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - IMG_CHAR * pszFormat, ...) -{ - PVRSRV_ERROR eErr = PVRSRV_OK; - va_list args; - - va_start(args, pszFormat); - PDumpCommentWithFlagsVA(psDeviceNode, ui32Flags, pszFormat, args); - va_end(args); - - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCommentWithFlagsVA - * Inputs : ui32Flags - PDump flags - * : pszFormat - format string for comment - * : args - pre-started va_list args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comments -******************************************************************************/ -PVRSRV_ERROR __attribute__ ((format (printf, 3, 0))) -PDumpCommentWithFlagsVA(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Flags, - const IMG_CHAR * pszFormat, va_list args) -{ - IMG_INT32 iCount; - PVRSRV_ERROR eErr = PVRSRV_OK; - PDUMP_GET_MSG_STRING(); - - /* Construct the string */ - iCount = OSVSNPrintf(pszMsg, ui32MaxLen, pszFormat, args); - PVR_LOG_GOTO_IF_FALSE(((iCount != -1) && (iCount < ui32MaxLen)), "OSVSNPrintf", exit); - - PDUMP_LOCK(ui32Flags); - eErr = _PDumpWriteComment(psDeviceNode, pszMsg, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - -exit: - PDUMP_RELEASE_MSG_STRING(); - return eErr; -} - -/****************************************************************************** - * Function Name : PDumpCOMCommand - * Inputs : ui32PDumpFlags - PDump flags - * : pszPdumpStr - string for COM command - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : PDumps a COM command -******************************************************************************/ -PVRSRV_ERROR PDumpCOMCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags, - const IMG_CHAR * pszPdumpStr) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "COM %s\n", pszPdumpStr); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/*************************************************************************/ /*! - * Function Name : PDumpPanic - * Inputs : ui32PanicNo - Unique number for panic condition - * : pszPanicMsg - Panic reason message limited to ~90 chars - * : pszPPFunc - Function name string where panic occurred - * : ui32PPline - Source line number where panic occurred - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : PDumps a panic assertion. Used when the host driver - * : detects a condition that will lead to an invalid PDump - * : script that cannot be played back off-line. - */ /*************************************************************************/ -PVRSRV_ERROR PDumpPanic(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PanicNo, - IMG_CHAR* pszPanicMsg, - const IMG_CHAR* pszPPFunc, - IMG_UINT32 ui32PPline) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PDUMP_FLAGS_T uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS; - PDUMP_GET_SCRIPT_STRING(); - - /* Log the panic condition to the live kern.log in both REL and DEB mode - * to aid user PDump troubleshooting. */ - PVR_LOG(("PDUMP PANIC %08x: %s", ui32PanicNo, pszPanicMsg)); - PVR_DPF((PVR_DBG_MESSAGE, "PDUMP PANIC start %s:%d", pszPPFunc, ui32PPline)); - - /* Check the supplied panic reason string is within length limits */ - PVR_ASSERT(OSStringLength(pszPanicMsg)+sizeof("PANIC ") < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1); - - /* Obtain lock to keep the multi-line - * panic statement together in a single atomic write */ - PDUMP_BLKSTART(uiPDumpFlags); - - - /* Write -- Panic start (Function:line) */ - eError = PDumpSNPrintf(hScript, ui32MaxLen, "-- Panic start (%s:%d)", pszPPFunc, ui32PPline); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpSNPrintf", e1); - (void)PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - /* Write COM messages */ - eError = PDumpCOMCommand(psDeviceNode, uiPDumpFlags, - "**** Script invalid and not compatible with off-line playback. ****"); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpCOMCommand", e1); - - eError = PDumpCOMCommand(psDeviceNode, uiPDumpFlags, - "**** Check test parameters and driver configuration, stop imminent. ****"); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpCOMCommand", e1); - - /* Write PANIC no msg command */ - eError = PDumpSNPrintf(hScript, ui32MaxLen, "PANIC %08x %s", ui32PanicNo, pszPanicMsg); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpSNPrintf", e1); - (void)PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - /* Write -- Panic end */ - eError = PDumpSNPrintf(hScript, ui32MaxLen, "-- Panic end"); - PVR_LOG_GOTO_IF_ERROR(eError, "PDumpSNPrintf", e1); - (void)PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - -e1: - PDUMP_BLKEND(uiPDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return eError; -} - -/*************************************************************************/ /*! - * Function Name : PDumpCaptureError - * Inputs : ui32ErrorNo - Unique number for panic condition - * : pszErrorMsg - Panic reason message limited to ~90 chars - * : pszPPFunc - Function name string where panic occurred - * : ui32PPline - Source line number where panic occurred - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : PDumps an error string to the script file to interrupt - * : play back to inform user of a fatal issue that occurred - * : during PDump capture. - */ /*************************************************************************/ -PVRSRV_ERROR PDumpCaptureError(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_ERROR ui32ErrorNo, - IMG_CHAR* pszErrorMsg, - const IMG_CHAR *pszPPFunc, - IMG_UINT32 ui32PPline) -{ - IMG_CHAR* pszFormatStr = "DRIVER_ERROR: %3d: %s"; - PDUMP_FLAGS_T uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS; - - /* Need to return an error using this macro */ - PDUMP_GET_SCRIPT_STRING(); - - /* Check the supplied panic reason string is within length limits */ - PVR_ASSERT(OSStringLength(pszErrorMsg)+sizeof(pszFormatStr) < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1); - - /* Write driver error message to the script file */ - (void) PDumpSNPrintf(hScript, ui32MaxLen, pszFormatStr, ui32ErrorNo, pszErrorMsg); - - /* Obtain lock to keep the multi-line - * panic statement together in a single atomic write */ - PDUMP_LOCK(uiPDumpFlags); - (void) PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - PDUMP_UNLOCK(uiPDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function PDumpImageDescriptor - - @Description - - Dumps an OutputImage command and its associated header info. - - @Input psDeviceNode : device - @Input ui32MMUContextID : MMU context - @Input pszSABFileName : filename string - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR PDumpImageDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_DEV_VIRTADDR sHeader, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32PDumpFlags) -{ -#if !defined(SUPPORT_RGX) - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32MMUContextID); - PVR_UNREFERENCED_PARAMETER(pszSABFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32LogicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32LogicalHeight); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalWidth); - PVR_UNREFERENCED_PARAMETER(ui32PhysicalHeight); - PVR_UNREFERENCED_PARAMETER(ePixFmt); - PVR_UNREFERENCED_PARAMETER(eMemLayout); - PVR_UNREFERENCED_PARAMETER(eFBCompression); - PVR_UNREFERENCED_PARAMETER(paui32FBCClearColour); - PVR_UNREFERENCED_PARAMETER(eFBCSwizzle); - PVR_UNREFERENCED_PARAMETER(sHeader); - PVR_UNREFERENCED_PARAMETER(ui32HeaderSize); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#else - PVRSRV_ERROR eErr = PVRSRV_OK; - IMG_CHAR *pszPDumpDevName = psDeviceNode->sDevId.pszPDumpDevName; - IMG_BYTE abyPDumpDesc[IMAGE_HEADER_SIZE]; - IMG_UINT32 ui32ParamOutPos, ui32SABOffset = 0; - IMG_BOOL bRawImageData = IMG_FALSE; - - PDUMP_GET_SCRIPT_AND_FILE_STRING(); - - if (pszSABFileName == NULL) - { - eErr = PVRSRV_ERROR_INVALID_PARAMS; - goto error_release_script; - } - - /* Writing image descriptor to persistent buffer is not permitted */ - if (ui32PDumpFlags & PDUMP_FLAGS_PERSISTENT) - { - goto error_release_script; - } - - /* Prepare OutputImage descriptor header */ - eErr = RGXPDumpPrepareOutputImageDescriptorHdr(psDeviceNode, - ui32HeaderSize, - ui32DataSize, - ui32LogicalWidth, - ui32LogicalHeight, - ui32PhysicalWidth, - ui32PhysicalHeight, - ePixFmt, - eMemLayout, - eFBCompression, - paui32FBCClearColour, - eFBCSwizzle, - &(abyPDumpDesc[0])); - PVR_LOG_GOTO_IF_ERROR(eErr, "RGXPDumpPrepareOutputImageDescriptorHdr", error_release_script); - - PDUMP_LOCK(ui32PDumpFlags); - - PDumpCommentWithFlagsNoLock(psDeviceNode, ui32PDumpFlags, "Dump Image descriptor"); - - bRawImageData = - (ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 - || ePixFmt == PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888); - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_FBCDC_SIGNATURE_CHECK) - { - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - - /* - * The render data may be corrupted, so write out the raw - * image buffer to avoid errors in the post-processing tools. - */ - bRawImageData |= (psDevInfo->ui32ValidationFlags & RGX_VAL_SIG_CHECK_ERR_EN); - } -#endif - - if (bRawImageData) - { - IMG_UINT32 ui32ElementType; - IMG_UINT32 ui32ElementCount; - - PDumpCommentWithFlagsNoLock(psDeviceNode, ui32PDumpFlags, - "YUV data. Switching from OutputImage to SAB. Width=0x%08X Height=0x%08X", - ui32LogicalWidth, ui32LogicalHeight); - - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_AND_FILE_STRING(); - - ui32ElementType = 0; - ui32ElementCount = 0; - - /* Switch to CMD:OutputData with IBIN header. */ - return PDumpDataDescriptor(psDeviceNode, - ui32MMUContextID, - pszSABFileName, - sData, - ui32DataSize, - IBIN_HEADER_TYPE, - ui32ElementType, - ui32ElementCount, - ui32PDumpFlags); - } - - /* Write OutputImage descriptor header to parameter file */ - eErr = PDumpWriteParameter(psDeviceNode, - abyPDumpDesc, - IMAGE_HEADER_SIZE, - ui32PDumpFlags, - &ui32ParamOutPos, - pszFileName); - if (eErr != PVRSRV_OK) - { - if (eErr != PVRSRV_ERROR_PDUMP_NOT_ALLOWED) - { - PDUMP_ERROR(psDeviceNode, eErr, - "Failed to write device allocation to parameter file"); - PVR_LOG_ERROR(eErr, "PDumpWriteParameter"); - } - else - { - /* - * Write to parameter file prevented under the flags and - * current state of the driver so skip write to script and return. - */ - eErr = PVRSRV_OK; - } - goto error; - } - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "MALLOC :%s:BINHEADER 0x%08X 0x%08X\n", - pszPDumpDevName, - IMAGE_HEADER_SIZE, - IMAGE_HEADER_SIZE); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "LDB :%s:BINHEADER:0x00 0x%08x 0x%08x %s\n", - pszPDumpDevName, - IMAGE_HEADER_SIZE, - ui32ParamOutPos, - pszFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "SAB :%s:BINHEADER:0x00 0x%08X 0x00000000 %s.bin\n", - pszPDumpDevName, - IMAGE_HEADER_SIZE, - pszSABFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - ui32SABOffset += IMAGE_HEADER_SIZE; - - /* - * Write out the header section if image is FB compressed - */ - if (eFBCompression != IMG_FB_COMPRESSION_NONE) - { - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "SAB :%s:v%x:0x%010"IMG_UINT64_FMTSPECX" 0x%08X 0x%08X %s.bin\n", - pszPDumpDevName, - ui32MMUContextID, - (IMG_UINT64)sHeader.uiAddr, - ui32HeaderSize, - ui32SABOffset, - pszSABFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - ui32SABOffset += ui32HeaderSize; - } - - /* - * Now dump out the actual data associated with the surface - */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "SAB :%s:v%x:0x%010"IMG_UINT64_FMTSPECX" 0x%08X 0x%08X %s.bin\n", - pszPDumpDevName, - ui32MMUContextID, - (IMG_UINT64)sData.uiAddr, - ui32DataSize, - ui32SABOffset, - pszSABFileName); - - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - /* - * The OutputImage command is required to trigger processing of the output - * data - */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "CMD:OutputImage %s.bin\n", - pszSABFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "FREE :%s:BINHEADER\n", - pszPDumpDevName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - -error: - PDUMP_UNLOCK(ui32PDumpFlags); -error_release_script: - PDUMP_RELEASE_SCRIPT_AND_FILE_STRING() - return eErr; -#endif -} - -/*! -******************************************************************************* - - @Function PDumpDataDescriptor - - @Description - - Dumps an OutputData command and its associated header info. - - @Input psDeviceNode : device - @Input ui32MMUContextID : MMU context - @Input pszSABFileName : filename string - @Input sData : GPU virtual address of data - @Input ui32HeaderType : Header type - @Input ui32DataSize : Data size - @Input ui32ElementType : Element type being dumped - @Input ui32ElementCount : Number of elements to be dumped - @Input ui32PDumpFlags : PDump flags - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR PDumpDataDescriptor(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32MMUContextID, - IMG_CHAR *pszSABFileName, - IMG_DEV_VIRTADDR sData, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_UINT32 ui32PDumpFlags) -{ -#if !defined(SUPPORT_RGX) - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32MMUContextID); - PVR_UNREFERENCED_PARAMETER(pszSABFileName); - PVR_UNREFERENCED_PARAMETER(sData); - PVR_UNREFERENCED_PARAMETER(ui32DataSize); - PVR_UNREFERENCED_PARAMETER(ui32ElementType); - PVR_UNREFERENCED_PARAMETER(ui32ElementCount); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -#else - PVRSRV_ERROR eErr = PVRSRV_OK; - IMG_CHAR *pszPDumpDevName = psDeviceNode->sDevId.pszPDumpDevName; - IMG_BYTE abyPDumpDesc[DATA_HEADER_SIZE]; - IMG_UINT32 ui32ParamOutPos, ui32SABOffset = 0; - IMG_UINT32 ui32HeaderSize; - - PDUMP_GET_SCRIPT_AND_FILE_STRING(); - - PVR_GOTO_IF_INVALID_PARAM(pszSABFileName, eErr, error_release_script); - - if (ui32HeaderType == DATA_HEADER_TYPE) - { - ui32HeaderSize = DATA_HEADER_SIZE; - } - else if (ui32HeaderType == IBIN_HEADER_TYPE) - { - ui32HeaderSize = IBIN_HEADER_SIZE; - } - else - { - PVR_GOTO_WITH_ERROR(eErr, PVRSRV_ERROR_INVALID_PARAMS, error_release_script); - } - - /* Writing data descriptor to persistent buffer is not permitted */ - if (ui32PDumpFlags & PDUMP_FLAGS_PERSISTENT) - { - goto error_release_script; - } - - /* Prepare OutputData descriptor header */ - eErr = RGXPDumpPrepareOutputDataDescriptorHdr(psDeviceNode, - ui32HeaderType, - ui32DataSize, - ui32ElementType, - ui32ElementCount, - &(abyPDumpDesc[0])); - PVR_LOG_GOTO_IF_ERROR(eErr, "RGXPDumpPrepareOutputDataDescriptorHdr", error_release_script); - - PDUMP_LOCK(ui32PDumpFlags); - - PDumpCommentWithFlagsNoLock(psDeviceNode, ui32PDumpFlags, "Dump Data descriptor"); - - /* Write OutputImage command header to parameter file */ - eErr = PDumpWriteParameter(psDeviceNode, - abyPDumpDesc, - ui32HeaderSize, - ui32PDumpFlags, - &ui32ParamOutPos, - pszFileName); - if (eErr != PVRSRV_OK) - { - if (eErr != PVRSRV_ERROR_PDUMP_NOT_ALLOWED) - { - PDUMP_ERROR(psDeviceNode, eErr, - "Failed to write device allocation to parameter file"); - PVR_LOG_ERROR(eErr, "PDumpWriteParameter"); - } - else - { - /* - * Write to parameter file prevented under the flags and - * current state of the driver so skip write to script and return. - */ - eErr = PVRSRV_OK; - } - goto error; - } - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "MALLOC :%s:BINHEADER 0x%08X 0x%08X\n", - pszPDumpDevName, - ui32HeaderSize, - ui32HeaderSize); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "LDB :%s:BINHEADER:0x00 0x%08x 0x%08x %s\n", - pszPDumpDevName, - ui32HeaderSize, - ui32ParamOutPos, - pszFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "SAB :%s:BINHEADER:0x00 0x%08X 0x00000000 %s.bin\n", - pszPDumpDevName, - ui32HeaderSize, - pszSABFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - ui32SABOffset += ui32HeaderSize; - - /* - * Now dump out the actual data associated - */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "SAB :%s:v%x:0x%010"IMG_UINT64_FMTSPECX" 0x%08X 0x%08X %s.bin\n", - pszPDumpDevName, - ui32MMUContextID, - (IMG_UINT64)sData.uiAddr, - ui32DataSize, - ui32SABOffset, - pszSABFileName); - - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - /* - * The OutputData command is required to trigger processing of the output - * data - */ - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "CMD:OutputData %s.bin\n", - pszSABFileName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLenScript, - "FREE :%s:BINHEADER\n", - pszPDumpDevName); - PVR_GOTO_IF_ERROR(eErr, error); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - -error: - PDUMP_UNLOCK(ui32PDumpFlags); -error_release_script: - PDUMP_RELEASE_SCRIPT_AND_FILE_STRING() - return eErr; -#endif -} - -/*! -******************************************************************************* - - @Function PDumpReadRegKM - - @Description - - Dumps a read from a device register to a file - - @Input psConnection : connection info - @Input pszFileName - @Input ui32FileOffset - @Input ui32Address - @Input ui32Size - @Input ui32PDumpFlags - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR PDumpReadRegKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32Address, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - PVR_UNREFERENCED_PARAMETER(ui32Size); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "SAB :%s:0x%08X 0x%08X %s", - pszPDumpRegName, - ui32Address, - ui32FileOffset, - pszFileName); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpRegRead32ToInternalVar - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which reads register into an - * internal variable -******************************************************************************/ -PVRSRV_ERROR PDumpRegRead32ToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32Flags) - -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "RDW %s :%s:0x%08X", - pszInternalVar, - pszPDumpRegName, - ui32Reg); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/****************************************************************************** - @name PDumpRegRead32 - @brief Dump 32-bit register read to script - @param pszPDumpDevName - pdump device name - @param ui32RegOffset - register offset - @param ui32Flags - pdump flags - @return Error -******************************************************************************/ -PVRSRV_ERROR PDumpRegRead32(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - const IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW :%s:0x%X", - pszPDumpRegName, - ui32RegOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/****************************************************************************** - @name PDumpRegRead64ToInternalVar - @brief Read 64-bit register into an internal variable - @param pszPDumpDevName - pdump device name - @param ui32RegOffset - register offset - @param ui32Flags - pdump flags - @return Error -******************************************************************************/ -PVRSRV_ERROR PDumpRegRead64ToInternalVar(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_CHAR *pszInternalVar, - const IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - IMG_CHAR *pszPDumpVarName; -#endif - PDUMP_GET_SCRIPT_STRING(); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW %s :%s:0x%X", - pszInternalVar, - pszPDumpRegName, - ui32RegOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - pszPDumpVarName = PDumpCreateIncVarNameStr(pszInternalVar); - if (pszPDumpVarName == NULL) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW %s :%s:0x%X", - pszPDumpVarName, - pszPDumpRegName, - ui32RegOffset + 4); - - PDumpFreeIncVarNameStr(pszPDumpVarName); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - -#else - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW64 %s :%s:0x%X", - pszInternalVar, - pszPDumpRegName, - ui32RegOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#endif - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - -/****************************************************************************** - @name PDumpRegRead64 - @brief Dump 64-bit register read to script - @param pszPDumpDevName - pdump device name - @param ui32RegOffset - register offset - @param ui32Flags - pdump flags - @return Error -******************************************************************************/ -PVRSRV_ERROR PDumpRegRead64(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - const IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - -#if defined(PDUMP_SPLIT_64BIT_REGISTER_ACCESS) - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW :%s:0x%X", - pszPDumpRegName, ui32RegOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - return eErr; - } - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW :%s:0x%X", - pszPDumpRegName, ui32RegOffset + 4); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING() - PDUMP_UNLOCK(ui32Flags); - return eErr; - } - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#else - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "RDW64 :%s:0x%X", - pszPDumpRegName, - ui32RegOffset); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); -#endif - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - -/****************************************************************************** - FUNCTION : PDumpWriteShiftedMaskedValue - - PURPOSE : Emits the PDump commands for writing a masked shifted address - into another location - - PARAMETERS : PDump symbolic name and offset of target word - PDump symbolic name and offset of source address - right shift amount - left shift amount - mask - - RETURNS : None -******************************************************************************/ -PVRSRV_ERROR -PDumpWriteShiftedMaskedValue(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDestRegspaceName, - const IMG_CHAR *pszDestSymbolicName, - IMG_DEVMEM_OFFSET_T uiDestOffset, - const IMG_CHAR *pszRefRegspaceName, - const IMG_CHAR *pszRefSymbolicName, - IMG_DEVMEM_OFFSET_T uiRefOffset, - IMG_UINT32 uiSHRAmount, - IMG_UINT32 uiSHLAmount, - IMG_UINT32 uiMask, - IMG_DEVMEM_SIZE_T uiWordSize, - IMG_UINT32 uiPDumpFlags) -{ - PVRSRV_ERROR eError; - - /* Suffix of WRW command in PDump (i.e. WRW or WRW64) */ - const IMG_CHAR *pszWrwSuffix; - - /* Internal PDump register used for interim calculation */ - const IMG_CHAR *pszPDumpIntRegSpace; - IMG_UINT32 uiPDumpIntRegNum; - - PDUMP_GET_SCRIPT_STRING(); - - if ((uiWordSize != 4) && (uiWordSize != 8)) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_ERROR_NOT_SUPPORTED; - } - - pszWrwSuffix = (uiWordSize == 8) ? "64" : ""; - - /* Should really "Acquire" a pdump register here */ - pszPDumpIntRegSpace = pszDestRegspaceName; - uiPDumpIntRegNum = 1; - - PDUMP_LOCK(uiPDumpFlags); - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - /* Should this be "MOV" instead? */ - "WRW :%s:$%d :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n", - /* dest */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src */ - pszRefRegspaceName, - pszRefSymbolicName, - uiRefOffset); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - if (uiSHRAmount > 0) - { - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHR :%s:$%d :%s:$%d 0x%X\n", - /* dest */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src A */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src B */ - uiSHRAmount); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - } - - if (uiSHLAmount > 0) - { - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHL :%s:$%d :%s:$%d 0x%X\n", - /* dest */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src A */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src B */ - uiSHLAmount); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - } - - if (uiMask != (1ULL << (8*uiWordSize))-1) - { - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "AND :%s:$%d :%s:$%d 0x%X\n", - /* dest */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src A */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum, - /* src B */ - uiMask); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - } - - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " :%s:$%d\n", - pszWrwSuffix, - /* dest */ - pszDestRegspaceName, - pszDestSymbolicName, - uiDestOffset, - /* src */ - pszPDumpIntRegSpace, - uiPDumpIntRegNum); - PVR_GOTO_IF_ERROR(eError, ErrUnlock); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - -ErrUnlock: - PDUMP_UNLOCK(uiPDumpFlags); - PDUMP_RELEASE_SCRIPT_STRING(); - - return eError; -} - - -PVRSRV_ERROR -PDumpWriteSymbAddress(PVRSRV_DEVICE_NODE *psDeviceNode, - const IMG_CHAR *pszDestSpaceName, - IMG_DEVMEM_OFFSET_T uiDestOffset, - const IMG_CHAR *pszRefSymbolicName, - IMG_DEVMEM_OFFSET_T uiRefOffset, - const IMG_CHAR *pszPDumpDevName, - IMG_UINT32 ui32WordSize, - IMG_UINT32 ui32AlignShift, - IMG_UINT32 ui32Shift, - IMG_UINT32 uiPDumpFlags) -{ - const IMG_CHAR *pszWrwSuffix = ""; - PVRSRV_ERROR eError = PVRSRV_OK; - - PDUMP_GET_SCRIPT_STRING(); - - if (ui32WordSize == 8) - { - pszWrwSuffix = "64"; - } - - PDUMP_LOCK(uiPDumpFlags); - - if (ui32AlignShift != ui32Shift) - { - /* Write physical address into a variable */ - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:$1 %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n", - pszWrwSuffix, - /* dest */ - pszPDumpDevName, - /* src */ - pszRefSymbolicName, - uiRefOffset); - PVR_GOTO_IF_ERROR(eError, symbAddress_error); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - /* apply address alignment */ - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHR :%s:$1 :%s:$1 0x%X", - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - ui32AlignShift); - PVR_GOTO_IF_ERROR(eError, symbAddress_error); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - /* apply address shift */ - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "SHL :%s:$1 :%s:$1 0x%X", - /* dest */ - pszPDumpDevName, - /* src A */ - pszPDumpDevName, - /* src B */ - ui32Shift); - PVR_GOTO_IF_ERROR(eError, symbAddress_error); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - - - /* write result to register */ - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:0x%08X :%s:$1", - pszWrwSuffix, - pszDestSpaceName, - (IMG_UINT32)uiDestOffset, - pszPDumpDevName); - PVR_GOTO_IF_ERROR(eError, symbAddress_error); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - } - else - { - eError = PDumpSNPrintf(hScript, - ui32MaxLen, - "WRW%s :%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n", - pszWrwSuffix, - /* dest */ - pszDestSpaceName, - uiDestOffset, - /* src */ - pszRefSymbolicName, - uiRefOffset); - PVR_GOTO_IF_ERROR(eError, symbAddress_error); - PDumpWriteScript(psDeviceNode, hScript, uiPDumpFlags); - } - -symbAddress_error: - PDUMP_UNLOCK(uiPDumpFlags); - PDUMP_RELEASE_SCRIPT_STRING(); - - return eError; -} - -/****************************************************************************** - * Function Name : PDumpIDLWithFlags - * Inputs : Idle time in clocks - * Outputs : None - * Returns : Error - * Description : Dump IDL command to script -******************************************************************************/ -PVRSRV_ERROR PDumpIDLWithFlags(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "IDL %u", ui32Clocks); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpIDL - * Inputs : Idle time in clocks - * Outputs : None - * Returns : Error - * Description : Dump IDL command to script -******************************************************************************/ -PVRSRV_ERROR PDumpIDL(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Clocks) -{ - return PDumpIDLWithFlags(psDeviceNode, ui32Clocks, PDUMP_FLAGS_CONTINUOUS); -} - -/****************************************************************************** - * Function Name : PDumpRegBasedCBP - * Inputs : pszPDumpRegName, ui32RegOffset, ui32WPosVal, ui32PacketSize - * ui32BufferSize, ui32Flags - * Outputs : None - * Returns : Error - * Description : Dump CBP command to script -******************************************************************************/ -PVRSRV_ERROR PDumpRegBasedCBP(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32WPosVal, - IMG_UINT32 ui32PacketSize, - IMG_UINT32 ui32BufferSize, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpSNPrintf(hScript, - ui32MaxLen, - "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X", - pszPDumpRegName, - ui32RegOffset, - ui32WPosVal, - ui32PacketSize, - ui32BufferSize); - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -PVRSRV_ERROR PDumpTRG(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszMemSpace, - IMG_UINT32 ui32MMUCtxID, - IMG_UINT32 ui32RegionID, - IMG_BOOL bEnable, - IMG_UINT64 ui64VAddr, - IMG_UINT64 ui64LenBytes, - IMG_UINT32 ui32XStride, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - if (bEnable) - { - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "TRG :%s:v%u %u 0x%08"IMG_UINT64_FMTSPECX" 0x%08"IMG_UINT64_FMTSPECX" %u", - pszMemSpace, ui32MMUCtxID, ui32RegionID, - ui64VAddr, ui64LenBytes, ui32XStride); - } - else - { - eErr = PDumpSNPrintf(hScript, ui32MaxLen, - "TRG :%s:v%u %u", - pszMemSpace, ui32MMUCtxID, ui32RegionID); - - } - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32Flags); - PDumpWriteScript(psDeviceNode, hScript, ui32Flags); - PDUMP_UNLOCK(ui32Flags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpConnectionNotify - * Description : Called by the srvcore to tell PDump core that the - * PDump capture and control client has connected -******************************************************************************/ -void PDumpConnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(TL_BUFFER_STATS) - PVRSRV_ERROR eErr; -#endif - - OSAtomicIncrement(&g_sConnectionCount); - - /* Reset the parameter file attributes */ - g_PDumpParameters.sWOff.ui32Main = g_PDumpParameters.sWOff.ui32Init; - g_PDumpParameters.ui32FileIdx = 0; - - /* Reset the script file attributes */ - g_PDumpScript.ui32FileIdx = 0; - - /* The Main script & parameter buffers should be empty after the previous - * PDump capture if it completed correctly. - * When PDump client is not connected, writes are prevented to Main - * buffers in PDumpWriteAllowed() since no capture range, no client, - * no writes to Main buffers for continuous flagged and regular writes. - */ - if (!TLStreamOutOfData(g_PDumpParameters.sCh.sMainStream.hTL)) /* !empty */ - { - PVR_DPF((PVR_DBG_ERROR, "PDump Main parameter buffer not empty, capture will be corrupt!")); - } - if (!TLStreamOutOfData(g_PDumpScript.sCh.sMainStream.hTL)) /* !empty */ - { - PVR_DPF((PVR_DBG_ERROR, "PDump Main script buffer not empty, capture will be corrupt!")); - } - -#if defined(TL_BUFFER_STATS) - eErr = TLStreamResetProducerByteCount(g_PDumpParameters.sCh.sMainStream.hTL, g_PDumpParameters.sWOff.ui32Init); - PVR_LOG_IF_ERROR(eErr, "TLStreamResetByteCount Parameter Main"); - - eErr = TLStreamResetProducerByteCount(g_PDumpScript.sCh.sMainStream.hTL, 0); - PVR_LOG_IF_ERROR(eErr, "TLStreamResetByteCount Script Main"); -#endif - - if (psDeviceNode->pfnPDumpInitDevice) - { - /* Reset pdump according to connected device */ - psDeviceNode->pfnPDumpInitDevice(psDeviceNode); - } -} - -/****************************************************************************** - * Function Name : PDumpDisconnectionNotify - * Description : Called by the connection_server to tell PDump core that - * the PDump capture and control client has disconnected -******************************************************************************/ -void PDumpDisconnectionNotify(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eErr; - - if (PDumpCtrlCaptureOn()) - { - PVR_LOG(("pdump killed, capture files may be invalid or incomplete!")); - - /* Disable capture in server, in case PDump client was killed and did - * not get a chance to reset the capture parameters. - * Will set module state back to READY. - */ - eErr = PDumpSetDefaultCaptureParamsKM(NULL, psDeviceNode, PDUMP_CAPMODE_UNSET, - PDUMP_FRAME_UNSET, PDUMP_FRAME_UNSET, 0, 0); - PVR_LOG_IF_ERROR(eErr, "PDumpSetDefaultCaptureParamsKM"); - } -} - -/****************************************************************************** - * Function Name : PDumpRegCondStr - * Inputs : Description of what this register read is trying to do - * pszPDumpDevName - * Register offset - * expected value - * mask for that value - * Outputs : PDump conditional test for use with 'IF' and 'DOW' - * Returns : None - * Description : Create a PDUMP conditional test. The string is allocated - * on the heap and should be freed by the caller on success. -******************************************************************************/ -PVRSRV_ERROR PDumpRegCondStr(IMG_CHAR **ppszPDumpCond, - IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator) -{ - IMG_UINT32 ui32PollCount; - - PDUMP_GET_MSG_STRING(); - - ui32PollCount = POLL_COUNT_SHORT; - - if (0 == OSSNPrintf(pszMsg, ui32MaxLen, ":%s:0x%08X 0x%08X 0x%08X %d %u %d", - pszPDumpRegName, ui32RegAddr, ui32RegValue, - ui32Mask, eOperator, ui32PollCount, POLL_DELAY)) - { - PDUMP_RELEASE_MSG_STRING() - return PVRSRV_ERROR_INTERNAL_ERROR; - } - - *ppszPDumpCond = pszMsg; - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpInternalValCondStr - * Inputs : Description of what this register read is trying to do - * pszPDumpDevName - * Internal variable - * expected value - * mask for that value - * Outputs : PDump conditional test for use with 'IF' and 'DOW' - * Returns : None - * Description : Create a PDUMP conditional test. The string is allocated - * on the heap and should be freed by the caller on success. -******************************************************************************/ -PVRSRV_ERROR PDumpInternalValCondStr(IMG_CHAR **ppszPDumpCond, - IMG_CHAR *pszInternalVar, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator) -{ - IMG_UINT32 ui32PollCount; - - PDUMP_GET_MSG_STRING(); - - ui32PollCount = POLL_COUNT_SHORT; - - if (0 == OSSNPrintf(pszMsg, ui32MaxLen, "%s 0x%08X 0x%08X %d %u %d", - pszInternalVar, ui32RegValue, - ui32Mask, eOperator, ui32PollCount, POLL_DELAY)) - { - PDUMP_RELEASE_MSG_STRING() - return PVRSRV_ERROR_INTERNAL_ERROR; - } - - *ppszPDumpCond = pszMsg; - - return PVRSRV_OK; -} - - -/****************************************************************************** - * Function Name : PDumpIfKM - * Inputs : pszPDumpCond - string for condition - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents IF command - with condition. -******************************************************************************/ -PVRSRV_ERROR PDumpIfKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "IF %s\n", pszPDumpCond); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpElseKM - * Inputs : pszPDumpCond - string for condition - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents ELSE command - with condition. -******************************************************************************/ -PVRSRV_ERROR PDumpElseKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "ELSE %s\n", pszPDumpCond); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpFiKM - * Inputs : pszPDumpCond - string for condition - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents FI command - with condition. -******************************************************************************/ -PVRSRV_ERROR PDumpFiKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpCond, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "FI %s\n", pszPDumpCond); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpStartDoLoopKM - * Inputs : None - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents SDO command - with condition. -******************************************************************************/ -PVRSRV_ERROR PDumpStartDoLoopKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "SDO"); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - -/****************************************************************************** - * Function Name : PDumpEndDoWhileLoopKM - * Inputs : pszPDumpWhileCond - string for loop condition - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents DOW command - with condition. -******************************************************************************/ -PVRSRV_ERROR PDumpEndDoWhileLoopKM(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszPDumpWhileCond, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - - eErr = PDumpSNPrintf(hScript, ui32MaxLen, "DOW %s\n", pszPDumpWhileCond); - - if (eErr != PVRSRV_OK) - { - PDUMP_RELEASE_SCRIPT_STRING(); - return eErr; - } - - PDUMP_LOCK(ui32PDumpFlags); - PDumpWriteScript(psDeviceNode, hScript, ui32PDumpFlags); - PDUMP_UNLOCK(ui32PDumpFlags); - - PDUMP_RELEASE_SCRIPT_STRING(); - - return PVRSRV_OK; -} - - -void PDumpLock(void) -{ - OSLockAcquire(g_hPDumpWriteLock); -} -void PDumpUnlock(void) -{ - OSLockRelease(g_hPDumpWriteLock); -} -static void PDumpAssertWriteLockHeld(void) -{ - /* It is expected to be g_hPDumpWriteLock is locked at this point. */ - PVR_ASSERT(OSLockIsLocked(g_hPDumpWriteLock)); -} - -#if defined(PDUMP_TRACE_STATE) || defined(PVR_TESTING_UTILS) -void PDumpCommonDumpState(void) -{ - PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.*.hTL (In, Mn, De, Bk) ( %p, %p, %p, %p )", - g_PDumpScript.sCh.sInitStream.hTL, g_PDumpScript.sCh.sMainStream.hTL, g_PDumpScript.sCh.sDeinitStream.hTL, g_PDumpScript.sCh.sBlockStream.hTL)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.*.ui32BufferFullRetries (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpScript.sCh.sInitStream.ui32BufferFullRetries, - g_PDumpScript.sCh.sMainStream.ui32BufferFullRetries, - g_PDumpScript.sCh.sDeinitStream.ui32BufferFullRetries, - g_PDumpScript.sCh.sBlockStream.ui32BufferFullRetries)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.*.ui32BufferFullAborts (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpScript.sCh.sInitStream.ui32BufferFullAborts, - g_PDumpScript.sCh.sMainStream.ui32BufferFullAborts, - g_PDumpScript.sCh.sDeinitStream.ui32BufferFullAborts, - g_PDumpScript.sCh.sBlockStream.ui32BufferFullAborts)); - - PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.*.ui32HighestRetriesWatermark (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpScript.sCh.sInitStream.ui32HighestRetriesWatermark, - g_PDumpScript.sCh.sMainStream.ui32HighestRetriesWatermark, - g_PDumpScript.sCh.sDeinitStream.ui32HighestRetriesWatermark, - g_PDumpScript.sCh.sBlockStream.ui32HighestRetriesWatermark)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.ui32FileIdx( %d )", g_PDumpScript.ui32FileIdx)); - - - - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.*.hTL (In, Mn, De, Bk) ( %p, %p, %p, %p )", - g_PDumpParameters.sCh.sInitStream.hTL, g_PDumpParameters.sCh.sMainStream.hTL, g_PDumpParameters.sCh.sDeinitStream.hTL, g_PDumpParameters.sCh.sBlockStream.hTL)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.*.ui32BufferFullRetries (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpParameters.sCh.sInitStream.ui32BufferFullRetries, - g_PDumpParameters.sCh.sMainStream.ui32BufferFullRetries, - g_PDumpParameters.sCh.sDeinitStream.ui32BufferFullRetries, - g_PDumpParameters.sCh.sBlockStream.ui32BufferFullRetries)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.*.ui32BufferFullAborts (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpParameters.sCh.sInitStream.ui32BufferFullAborts, - g_PDumpParameters.sCh.sMainStream.ui32BufferFullAborts, - g_PDumpParameters.sCh.sDeinitStream.ui32BufferFullAborts, - g_PDumpParameters.sCh.sBlockStream.ui32BufferFullAborts)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.*.ui32HighestRetriesWatermark (In, Mn, De, Bk) ( %5d, %5d, %5d, %5d )", - g_PDumpParameters.sCh.sInitStream.ui32HighestRetriesWatermark, - g_PDumpParameters.sCh.sMainStream.ui32HighestRetriesWatermark, - g_PDumpParameters.sCh.sDeinitStream.ui32HighestRetriesWatermark, - g_PDumpParameters.sCh.sBlockStream.ui32HighestRetriesWatermark)); - - - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sWOff.* (In, Mn, De, Bk) ( %d, %d, %d, %d )", - g_PDumpParameters.sWOff.ui32Init, g_PDumpParameters.sWOff.ui32Main, g_PDumpParameters.sWOff.ui32Deinit, g_PDumpParameters.sWOff.ui32Block)); - PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.ui32FileIdx( %d )", g_PDumpParameters.ui32FileIdx)); - - PVR_LOG(("--- PDUMP COMMON: g_PDumpCtrl( %p ) eServiceState( %d ), IsDriverInInitPhase( %s ) ui32Flags( %x )", - &g_PDumpCtrl, g_PDumpCtrl.eServiceState, CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_DRIVER_IN_INIT_PHASE) ? "yes" : "no", g_PDumpCtrl.ui32Flags)); - PVR_LOG(("--- PDUMP COMMON: ui32DefaultCapMode( %d ) ui32CurrentFrame( %d )", - g_PDumpCtrl.ui32DefaultCapMode, g_PDumpCtrl.ui32CurrentFrame)); - PVR_LOG(("--- PDUMP COMMON: sCaptureRange.ui32Start( %x ) sCaptureRange.ui32End( %x ) sCaptureRange.ui32Interval( %u )", - g_PDumpCtrl.sCaptureRange.ui32Start, g_PDumpCtrl.sCaptureRange.ui32End, g_PDumpCtrl.sCaptureRange.ui32Interval)); - PVR_LOG(("--- PDUMP COMMON: IsInCaptureRange( %s ) IsInCaptureInterval( %s ) InPowerTransition( %d )", - CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_RANGE) ? "yes" : "no", - CHECK_PDUMP_CONTROL_FLAG(FLAG_IS_IN_CAPTURE_INTERVAL) ? "yes" : "no", - PDumpCtrlInPowerTransition())); - PVR_LOG(("--- PDUMP COMMON: sBlockCtrl.ui32BlockLength( %d ), sBlockCtrl.ui32CurrentBlock( %d )", - g_PDumpCtrl.sBlockCtrl.ui32BlockLength, g_PDumpCtrl.sBlockCtrl.ui32CurrentBlock)); -} -#endif /* defined(PDUMP_TRACE_STATE) || defined(PVR_TESTING_UTILS) */ - - -PVRSRV_ERROR PDumpRegisterConnection(void *hSyncPrivData, - PFN_PDUMP_SYNCBLOCKS pfnPDumpSyncBlocks, - PDUMP_CONNECTION_DATA **ppsPDumpConnectionData) -{ - PDUMP_CONNECTION_DATA *psPDumpConnectionData; - PVRSRV_ERROR eError; - - PVR_ASSERT(ppsPDumpConnectionData != NULL); - PVR_ASSERT(pfnPDumpSyncBlocks != NULL); - PVR_ASSERT(hSyncPrivData != NULL); - - psPDumpConnectionData = OSAllocMem(sizeof(*psPDumpConnectionData)); - PVR_GOTO_IF_NOMEM(psPDumpConnectionData, eError, fail_alloc); - - eError = OSLockCreate(&psPDumpConnectionData->hLock); - PVR_GOTO_IF_ERROR(eError, fail_lockcreate); - - dllist_init(&psPDumpConnectionData->sListHead); - OSAtomicWrite(&psPDumpConnectionData->sRefCount, 1); - psPDumpConnectionData->ui32LastSetFrameNumber = PDUMP_FRAME_UNSET; - psPDumpConnectionData->eLastEvent = PDUMP_TRANSITION_EVENT_NONE; - psPDumpConnectionData->eFailedEvent = PDUMP_TRANSITION_EVENT_NONE; - - /* - * Although we don't take a ref count here, handle base destruction - * will ensure that any resource that might trigger us to do a Transition - * will have been freed before the sync blocks which are keeping the sync - * connection data alive. - */ - psPDumpConnectionData->hSyncPrivData = hSyncPrivData; - psPDumpConnectionData->pfnPDumpSyncBlocks = pfnPDumpSyncBlocks; - - *ppsPDumpConnectionData = psPDumpConnectionData; - - return PVRSRV_OK; - -fail_lockcreate: - OSFreeMem(psPDumpConnectionData); -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -void PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData) -{ - _PDumpConnectionRelease(psPDumpConnectionData); -} - - -/*! - * \name PDumpSNPrintf - */ -PVRSRV_ERROR PDumpSNPrintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) -{ - IMG_CHAR* pszBuf = hBuf; - IMG_INT32 n; - va_list vaArgs; - - va_start(vaArgs, pszFormat); - - n = OSVSNPrintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs); - - va_end(vaArgs); - - if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */ - { - PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete.")); - - return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW; - } - -#if defined(PDUMP_DEBUG_OUTFILES) - OSAtomicIncrement(&g_sEveryLineCounter); -#endif - - /* Put line ending sequence at the end if it isn't already there */ - _PDumpVerifyLineEnding(pszBuf, ui32ScriptSizeMax); - - return PVRSRV_OK; -} - -#endif /* defined(PDUMP) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdump_symbolicaddr.h b/drivers/gpu/drm/img-rogue/1.17/pdump_symbolicaddr.h deleted file mode 100644 index ed912a5096c95..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdump_symbolicaddr.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Abstraction of PDUMP symbolic address derivation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Allows pdump functions to derive symbolic addresses on-the-fly -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVKM_PDUMP_SYMBOLICADDR_H -#define SRVKM_PDUMP_SYMBOLICADDR_H - -#include "img_types.h" - -#include "pvrsrv_error.h" - -/* pdump symbolic addresses are generated on-the-fly with a callback */ - -typedef PVRSRV_ERROR (*PVRSRV_SYMADDRFUNCPTR)(IMG_HANDLE hPriv, IMG_UINT32 uiOffset, IMG_CHAR *pszSymbolicAddr, IMG_UINT32 ui32SymbolicAddrLen, IMG_UINT32 *pui32NewOffset); - -#endif /* #ifndef SRVKM_PDUMP_SYMBOLICADDR_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdumpdefs.h b/drivers/gpu/drm/img-rogue/1.17/pdumpdefs.h deleted file mode 100644 index 3f8cccabc8247..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdumpdefs.h +++ /dev/null @@ -1,249 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PDUMP definitions header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description PDUMP definitions header -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PDUMPDEFS_H -#define PDUMPDEFS_H - -/*! PDump Pixel Format Enumeration */ -typedef enum _PDUMP_PIXEL_FORMAT_ -{ - PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0, - PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1, - PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2, - PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3, - PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4, - PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5, - PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6, - PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7, - PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9, -/* PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10, */ - PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11, - PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12, - PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13, - PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15, - PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16, - PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17, - PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18, - PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20, - PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25, - PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26, - PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27, - PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28, - PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29, - PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30, - PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31, - PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32, - PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33, - PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34, - PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35, - PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36, - PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37, - PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38, - PVRSRV_PDUMP_PIXEL_FORMAT_RGBA8888 = 39, - PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40, - PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41, - PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42, - PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43, - PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44, - PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45, - PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46, - PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47, - PVRSRV_PDUMP_PIXEL_FORMAT_F16F16F16F16 = 49, - PVRSRV_PDUMP_PIXEL_FORMAT_A4 = 50, - PVRSRV_PDUMP_PIXEL_FORMAT_ARGB2101010 = 51, - PVRSRV_PDUMP_PIXEL_FORMAT_RSGSBS888 = 52, - PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32F32 = 53, - PVRSRV_PDUMP_PIXEL_FORMAT_F16F16 = 54, - PVRSRV_PDUMP_PIXEL_FORMAT_F32F32 = 55, - PVRSRV_PDUMP_PIXEL_FORMAT_F16F16F16 = 56, - PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32 = 57, - PVRSRV_PDUMP_PIXEL_FORMAT_U8 = 58, - PVRSRV_PDUMP_PIXEL_FORMAT_U8U8 = 59, - PVRSRV_PDUMP_PIXEL_FORMAT_U16 = 60, - PVRSRV_PDUMP_PIXEL_FORMAT_U16U16 = 61, - PVRSRV_PDUMP_PIXEL_FORMAT_U16U16U16U16 = 62, - PVRSRV_PDUMP_PIXEL_FORMAT_U32 = 63, - PVRSRV_PDUMP_PIXEL_FORMAT_U32U32 = 64, - PVRSRV_PDUMP_PIXEL_FORMAT_U32U32U32U32 = 65, - PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32 = 66, - - PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff - -} PDUMP_PIXEL_FORMAT; - -typedef enum _PDUMP_FBC_SWIZZLE_ -{ - PVRSRV_PDUMP_FBC_SWIZZLE_ARGB = 0x0, - PVRSRV_PDUMP_FBC_SWIZZLE_ARBG = 0x1, - PVRSRV_PDUMP_FBC_SWIZZLE_AGRB = 0x2, - PVRSRV_PDUMP_FBC_SWIZZLE_AGBR = 0x3, - PVRSRV_PDUMP_FBC_SWIZZLE_ABGR = 0x4, - PVRSRV_PDUMP_FBC_SWIZZLE_ABRG = 0x5, - PVRSRV_PDUMP_FBC_SWIZZLE_RGBA = 0x8, - PVRSRV_PDUMP_FBC_SWIZZLE_RBGA = 0x9, - PVRSRV_PDUMP_FBC_SWIZZLE_GRBA = 0xA, - PVRSRV_PDUMP_FBC_SWIZZLE_GBRA = 0xB, - PVRSRV_PDUMP_FBC_SWIZZLE_BGRA = 0xC, - PVRSRV_PDUMP_FBC_SWIZZLE_BRGA = 0xD, -} PDUMP_FBC_SWIZZLE; - -/*! PDump addrmode */ -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT 0 -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_MASK 0x000000FF - -#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT 8 -#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_NEGATIVE (1U << PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT) - -#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_SHIFT 12 -#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_MASK 0x000FF000 - -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT 20 -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_MASK 0x00F00000 - -#define PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT 24 -#define PVRSRV_PDUMP_ADDRMODE_FBCLOSSY_SHIFT 25 - -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT 28 -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_MASK 0xF0000000 - -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_STRIDE (0U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE1 (1U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE2 (2U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE3 (3U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE4 (4U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE5 (5U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE6 (6U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE7 (7U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_TWIDDLED (9U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_PAGETILED (11U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_ZTWIDDLED (12U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT) - -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_NONE (0U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_DIRECT (1U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_DIRECT (2U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_32X2_DIRECT (3U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT (4U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT (5U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT_4TILE (6U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT_4TILE (7U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT) - -#define PVRSRV_PDUMP_ADDRMODE_FBC_DECOR (1U << PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT) - -#define PVRSRV_PDUMP_ADDRMODE_FBC_LOSSY (1U << PVRSRV_PDUMP_ADDRMODE_FBCLOSSY_SHIFT) - -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_BASE (1U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_ENHANCED (2U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V2 (3U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_SURFACE (4U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_RESOURCE (5U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_1_SURFACE (6U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_1_RESOURCE (7U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V4 (8U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V4PLUS (9U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) -#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_TFBCDC (10U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT) - -/*! PDump Poll Operator */ -typedef enum _PDUMP_POLL_OPERATOR -{ - PDUMP_POLL_OPERATOR_EQUAL = 0, - PDUMP_POLL_OPERATOR_LESS = 1, - PDUMP_POLL_OPERATOR_LESSEQUAL = 2, - PDUMP_POLL_OPERATOR_GREATER = 3, - PDUMP_POLL_OPERATOR_GREATEREQUAL = 4, - PDUMP_POLL_OPERATOR_NOTEQUAL = 5, -} PDUMP_POLL_OPERATOR; - - -#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 75 /*!< Max length of a pdump log file name */ -#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 350 /*!< Max length of a pdump comment */ - -/*! - PDump MMU type - (Maps to values listed in "PowerVR Tools.Pdump2 Script Functions.doc" Sec 2.13) -*/ -typedef enum -{ - PDUMP_MMU_TYPE_4KPAGE_32BIT_STDTILE = 1, - PDUMP_MMU_TYPE_VARPAGE_32BIT_STDTILE = 2, - PDUMP_MMU_TYPE_4KPAGE_36BIT_EXTTILE = 3, - PDUMP_MMU_TYPE_4KPAGE_32BIT_EXTTILE = 4, - PDUMP_MMU_TYPE_4KPAGE_36BIT_STDTILE = 5, - PDUMP_MMU_TYPE_VARPAGE_40BIT = 6, - PDUMP_MMU_TYPE_VIDEO_40BIT_STDTILE = 7, - PDUMP_MMU_TYPE_VIDEO_40BIT_EXTTILE = 8, - PDUMP_MMU_TYPE_MIPS_MICROAPTIV = 9, - PDUMP_MMU_TYPE_LAST -} PDUMP_MMU_TYPE; - -/*! - PDump states - These values are used by the bridge call PVRSRVPDumpGetState -*/ -#define PDUMP_STATE_CAPTURE_FRAME (1U) /*!< Flag represents the PDump being in capture range or not*/ -#define PDUMP_STATE_CONNECTED (2U) /*!< Flag represents the PDump Client App being connected on not */ -#define PDUMP_STATE_SUSPENDED (4U) /*!< Flag represents the PDump being suspended or not */ -#define PDUMP_STATE_CAPTURE_IN_INTERVAL (8U) /*!< Flag represents the PDump being in a capture range interval */ - -/*! - PDump Capture modes - Values used with calls to PVRSRVPDumpSetDefaultCaptureParams -*/ -#define PDUMP_CAPMODE_UNSET 0x00000000UL -#define PDUMP_CAPMODE_FRAMED 0x00000001UL -#define PDUMP_CAPMODE_CONTINUOUS 0x00000002UL -#define PDUMP_CAPMODE_BLOCKED 0x00000003UL - -#define PDUMP_CAPMODE_MAX PDUMP_CAPMODE_BLOCKED - -#endif /* PDUMPDEFS_H */ - -/***************************************************************************** - End of file (pdumpdefs.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pdumpdesc.h b/drivers/gpu/drm/img-rogue/1.17/pdumpdesc.h deleted file mode 100644 index d159bf4ee3348..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pdumpdesc.h +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************/ /*! -@File pdumpdesc.h -@Title PDump Descriptor format -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Describes PDump descriptors that may be passed to the - extraction routines (SAB). -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PDUMPDESC_H) -#define PDUMPDESC_H - -#include "pdumpdefs.h" - -/* - * Common fields - */ -#define HEADER_WORD0_TYPE_SHIFT (0) -#define HEADER_WORD0_TYPE_CLRMSK (0xFFFFFFFFU) - -#define HEADER_WORD1_SIZE_SHIFT (0) -#define HEADER_WORD1_SIZE_CLRMSK (0x0000FFFFU) -#define HEADER_WORD1_VERSION_SHIFT (16) -#define HEADER_WORD1_VERSION_CLRMSK (0xFFFF0000U) - -#define HEADER_WORD2_DATA_SIZE_SHIFT (0) -#define HEADER_WORD2_DATA_SIZE_CLRMSK (0xFFFFFFFFU) - - -/* - * The image type descriptor - */ - -/* - * Header type (IMGBv2) - 'IMGB' in hex + VERSION 2 - * Header size - 64 bytes - */ -#define IMAGE_HEADER_TYPE (0x42474D49) -#define IMAGE_HEADER_SIZE (64) -#define IMAGE_HEADER_VERSION (2) - -/* - * Image type-specific fields - */ -#define IMAGE_HEADER_WORD3_LOGICAL_WIDTH_SHIFT (0) -#define IMAGE_HEADER_WORD3_LOGICAL_WIDTH_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD4_LOGICAL_HEIGHT_SHIFT (0) -#define IMAGE_HEADER_WORD4_LOGICAL_HEIGHT_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD5_FORMAT_SHIFT (0) -#define IMAGE_HEADER_WORD5_FORMAT_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD6_PHYSICAL_WIDTH_SHIFT (0) -#define IMAGE_HEADER_WORD6_PHYSICAL_WIDTH_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD7_PHYSICAL_HEIGHT_SHIFT (0) -#define IMAGE_HEADER_WORD7_PHYSICAL_HEIGHT_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD8_TWIDDLING_SHIFT (0) -#define IMAGE_HEADER_WORD8_TWIDDLING_CLRMSK (0x000000FFU) -#define IMAGE_HEADER_WORD8_TWIDDLING_STRIDED (0 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT) -#define IMAGE_HEADER_WORD8_TWIDDLING_NTWIDDLE (9 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT) -#define IMAGE_HEADER_WORD8_TWIDDLING_ZTWIDDLE (12 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT) - - -#define IMAGE_HEADER_WORD8_STRIDE_SHIFT (8) -#define IMAGE_HEADER_WORD8_STRIDE_CLRMSK (0x0000FF00U) -#define IMAGE_HEADER_WORD8_STRIDE_POSITIVE (0 << IMAGE_HEADER_WORD8_STRIDE_SHIFT) -#define IMAGE_HEADER_WORD8_STRIDE_NEGATIVE (1 << IMAGE_HEADER_WORD8_STRIDE_SHIFT) - -#define IMAGE_HEADER_WORD8_BIFTYPE_SHIFT (16) -#define IMAGE_HEADER_WORD8_BIFTYPE_CLRMSK (0x00FF0000U) -#define IMAGE_HEADER_WORD8_BIFTYPE_NONE (0 << IMAGE_HEADER_WORD8_BIFTYPE_SHIFT) - -#define IMAGE_HEADER_WORD8_FBCTYPE_SHIFT (24) -#define IMAGE_HEADER_WORD8_FBCTYPE_CLRMSK (0xFF000000U) -#define IMAGE_HEADER_WORD8_FBCTYPE_8X8 (1 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT) -#define IMAGE_HEADER_WORD8_FBCTYPE_16x4 (2 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT) -#define IMAGE_HEADER_WORD8_FBCTYPE_32x2 (3 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT) - -#define IMAGE_HEADER_WORD9_FBCDECOR_SHIFT (0) -#define IMAGE_HEADER_WORD9_FBCDECOR_CLRMSK (0x000000FFU) -#define IMAGE_HEADER_WORD9_FBCDECOR_ENABLE (1 << IMAGE_HEADER_WORD9_FBCDECOR_SHIFT) - -/* Align with fbcomp_export_c.h in pdump_tools branch */ -#define IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT (8) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_CLRMSK (0x0000FF00U) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_SAME_AS_GPU (0 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_BASE (1 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_TWIDDLED_EN (2 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* TWIDDLED_ENHANCED */ -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V2 (3 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_0_LAYOUT1 (4 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_0_LAYOUT2 (5 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* V30_WITH_HEADER_REMAP */ -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_1_LAYOUT1 (6 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_1_LAYOUT2 (7 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* V31_WITH_HEADER_REMAP */ -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V4 (8 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_V4_PLUS (9 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) -#define IMAGE_HEADER_WORD9_FBCCOMPAT_TFBC (10 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) - -#define IMAGE_HEADER_WORD9_LOSSY_SHIFT (16) -#define IMAGE_HEADER_WORD9_LOSSY_CLRMSK (0x00FF0000U) -/* Non-TFBC */ -#define IMAGE_HEADER_WORD9_LOSSY_ON (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) - -/* TFBC */ -#define IMAGE_HEADER_WORD9_LOSSY_75 (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) -#define IMAGE_HEADER_WORD9_LOSSY_37 (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) -#define IMAGE_HEADER_WORD9_LOSSY_50 (2 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) -#define IMAGE_HEADER_WORD9_LOSSY_25 (3 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) -#define IMAGE_HEADER_WORD9_LOSSY_OFF (0 << IMAGE_HEADER_WORD9_LOSSY_SHIFT) - -#define IMAGE_HEADER_WORD9_SWIZZLE_SHIFT (24) -#define IMAGE_HEADER_WORD9_SWIZZLE_CLRMSK (0xFF000000U) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ARGB (0x0 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ARBG (0x1 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_AGRB (0x2 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_AGBR (0x3 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ABGR (0x4 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ABRG (0x5 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_RGBA (0x8 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_RBGA (0x9 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_GRBA (0xA << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_GBRA (0xB << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_BGRA (0xC << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) -#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_BRGA (0xD << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) - -#define IMAGE_HEADER_WORD10_FBCCLEAR_CH0_SHIFT (0) -#define IMAGE_HEADER_WORD10_FBCCLEAR_CH0_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD11_FBCCLEAR_CH1_SHIFT (0) -#define IMAGE_HEADER_WORD11_FBCCLEAR_CH1_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD12_FBCCLEAR_CH2_SHIFT (0) -#define IMAGE_HEADER_WORD12_FBCCLEAR_CH2_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD13_FBCCLEAR_CH3_SHIFT (0) -#define IMAGE_HEADER_WORD13_FBCCLEAR_CH3_CLRMSK (0xFFFFFFFFU) - -#define IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT (0) -#define IMAGE_HEADER_WORD14_TFBC_GROUP_CLRMSK (0x000000FFU) -#define IMAGE_HEADER_WORD14_TFBC_GROUP_25_50_75 (0 << IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT) -#define IMAGE_HEADER_WORD14_TFBC_GROUP_25_37_50 (1 << IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT) - -#define IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT (8) -#define IMAGE_HEADER_WORD14_COMP_SCHEME_CLRMSK (0x0000FF00U) -#define IMAGE_HEADER_WORD14_COMP_SCHEME_ALL (0 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT) -#define IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_CORR (1 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT) -#define IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_ONLY (2 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT) -#define IMAGE_HEADER_WORD14_COMP_SCHEME_PTC_ONLY (3 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT) - -#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_SHIFT (16) -#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_CLRMSK (0x00FF0000U) -#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_EN (1 << IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_SHIFT) /* Treat YUV10 optimal formats as 8 bits */ - -/* IMAGE_HEADER_WORD15_RESERVED2 */ - -/* - * The data type descriptor - */ - -/* - * Header type (IMGCv1) - 'IMGC' in hex + VERSION 0 - * Header size - 20 bytes (5 x 32 bit WORDS) - */ -#define DATA_HEADER_TYPE (0x43474D49) -#define DATA_HEADER_SIZE (20) -#define DATA_HEADER_VERSION (0) - -/* - * The IBIN type descriptor - */ - -/* - * Header type (IBIN) - 'IBIN' in hex + VERSION 0 - * Header size - 12 bytes (3 x 32 bit WORDS) - */ -#define IBIN_HEADER_TYPE (0x4e494249) -#define IBIN_HEADER_SIZE (12) -#define IBIN_HEADER_VERSION (0) - -/* - * Data type-specific fields - */ -#define DATA_HEADER_WORD3_ELEMENT_TYPE_SHIFT (0) -#define DATA_HEADER_WORD3_ELEMENT_TYPE_CLRMSK (0xFFFFFFFFU) - -#define DATA_HEADER_WORD4_ELEMENT_COUNT_SHIFT (0) -#define DATA_HEADER_WORD4_ELEMENT_COUNT_CLRMSK (0xFFFFFFFFU) - -#endif /* PDUMPDESC_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physheap.c b/drivers/gpu/drm/img-rogue/1.17/physheap.c deleted file mode 100644 index 2155bcbe93425..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physheap.c +++ /dev/null @@ -1,1184 +0,0 @@ -/*************************************************************************/ /*! -@File physheap.c -@Title Physical heap management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Management functions for the physical heap(s). A heap contains - all the information required by services when using memory from - that heap (such as CPU <> Device physical address translation). - A system must register one heap but can have more then one which - is why a heap must register with a (system) unique ID. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "physheap.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "osfunc.h" -#include "pvrsrv.h" -#include "physmem.h" -#include "physmem_hostmem.h" -#include "physmem_lma.h" -#include "physmem_osmem.h" - -struct _PHYS_HEAP_ -{ - /*! The type of this heap */ - PHYS_HEAP_TYPE eType; - /* Config flags */ - PHYS_HEAP_USAGE_FLAGS ui32UsageFlags; - - /*! Pointer to device node struct */ - PPVRSRV_DEVICE_NODE psDevNode; - /*! PDump name of this physical memory heap */ - IMG_CHAR *pszPDumpMemspaceName; - /*! Private data for the translate routines */ - IMG_HANDLE hPrivData; - /*! Function callbacks */ - PHYS_HEAP_FUNCTIONS *psMemFuncs; - - /*! Refcount */ - IMG_UINT32 ui32RefCount; - - /*! Implementation specific */ - PHEAP_IMPL_DATA pvImplData; - PHEAP_IMPL_FUNCS *psImplFuncs; - - /*! Pointer to next physical heap */ - struct _PHYS_HEAP_ *psNext; -}; - -static PHYS_HEAP *g_psPhysHeapList; -static POS_LOCK g_hPhysHeapLock; - -#if defined(REFCOUNT_DEBUG) -#define PHYSHEAP_REFCOUNT_PRINT(fmt, ...) \ - PVRSRVDebugPrintf(PVR_DBG_WARNING, \ - __FILE__, \ - __LINE__, \ - fmt, \ - __VA_ARGS__) -#else -#define PHYSHEAP_REFCOUNT_PRINT(fmt, ...) -#endif - - - -typedef struct PHYS_HEAP_PROPERTIES_TAG -{ - PVRSRV_PHYS_HEAP eFallbackHeap; - IMG_BOOL bPVRLayerAcquire; - IMG_BOOL bUserModeAlloc; -} PHYS_HEAP_PROPERTIES; - -/* NOTE: Table entries and order must match enum PVRSRV_PHYS_HEAP to ensure - * correct operation of PhysHeapCreatePMR(). - */ -static PHYS_HEAP_PROPERTIES gasHeapProperties[PVRSRV_PHYS_HEAP_LAST] = -{ - /* eFallbackHeap, bPVRLayerAcquire, bUserModeAlloc */ - { PVRSRV_PHYS_HEAP_DEFAULT, IMG_TRUE, IMG_TRUE }, /* DEFAULT */ - { PVRSRV_PHYS_HEAP_DEFAULT, IMG_TRUE, IMG_TRUE }, /* GPU_LOCAL */ - { PVRSRV_PHYS_HEAP_DEFAULT, IMG_TRUE, IMG_TRUE }, /* CPU_LOCAL */ - { PVRSRV_PHYS_HEAP_DEFAULT, IMG_TRUE, IMG_TRUE }, /* GPU_PRIVATE */ - { PVRSRV_PHYS_HEAP_GPU_LOCAL, IMG_FALSE, IMG_FALSE }, /* FW_MAIN */ - { PVRSRV_PHYS_HEAP_GPU_LOCAL, IMG_TRUE, IMG_FALSE }, /* EXTERNAL */ - { PVRSRV_PHYS_HEAP_GPU_LOCAL, IMG_TRUE, IMG_FALSE }, /* GPU_COHERENT */ - { PVRSRV_PHYS_HEAP_GPU_LOCAL, IMG_TRUE, IMG_TRUE }, /* GPU_SECURE */ - { PVRSRV_PHYS_HEAP_FW_MAIN, IMG_FALSE, IMG_FALSE }, /* FW_CONFIG */ - { PVRSRV_PHYS_HEAP_FW_MAIN, IMG_FALSE, IMG_FALSE }, /* FW_CODE */ - { PVRSRV_PHYS_HEAP_FW_MAIN, IMG_FALSE, IMG_FALSE }, /* FW_DATA */ - { PVRSRV_PHYS_HEAP_FW_PREMAP0, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP0 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP1, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP1 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP2, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP2 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP3, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP3 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP4, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP4 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP5, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP5 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP6, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP6 */ - { PVRSRV_PHYS_HEAP_FW_PREMAP7, IMG_FALSE, IMG_FALSE }, /* FW_PREMAP7 */ -}; - -static_assert((ARRAY_SIZE(gasHeapProperties) == PVRSRV_PHYS_HEAP_LAST), - "Size or order of gasHeapProperties entries incorrect for PVRSRV_PHYS_HEAP enum"); - -void PVRSRVGetDevicePhysHeapCount(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 *pui32PhysHeapCount) -{ - *pui32PhysHeapCount = psDevNode->ui32UserAllocHeapCount; -} - -static IMG_UINT32 PhysHeapOSGetPageShift(void) -{ - return (IMG_UINT32)OSGetPageShift(); -} - -static PHEAP_IMPL_FUNCS _sPHEAPImplFuncs = -{ - .pfnDestroyData = NULL, - .pfnGetPMRFactoryMemStats = PhysmemGetOSRamMemStats, - .pfnCreatePMR = PhysmemNewOSRamBackedPMR, - .pfnPagesAlloc = &OSPhyContigPagesAlloc, - .pfnPagesFree = &OSPhyContigPagesFree, - .pfnPagesMap = &OSPhyContigPagesMap, - .pfnPagesUnMap = &OSPhyContigPagesUnmap, - .pfnPagesClean = &OSPhyContigPagesClean, - .pfnGetPageShift = &PhysHeapOSGetPageShift, -}; - -/*************************************************************************/ /*! -@Function _PhysHeapDebugRequest -@Description This function is used to output debug information for a given - device's PhysHeaps. -@Input pfnDbgRequestHandle Data required by this function that is - passed through the RegisterDeviceDbgRequestNotify - function. -@Input ui32VerbLevel The maximum verbosity of the debug request. -@Input pfnDumpDebugPrintf The specified print function that should be - used to dump any debug information - (see PVRSRVDebugRequest). -@Input pvDumpDebugFile Optional file identifier to be passed to - the print function if required. -@Return void -*/ /**************************************************************************/ -static void _PhysHeapDebugRequest(PVRSRV_DBGREQ_HANDLE pfnDbgRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - static const IMG_CHAR *const pszTypeStrings[] = { - "UNKNOWN", - "UMA", - "LMA", - "DMA", -#if defined(SUPPORT_WRAP_EXTMEMOBJECT) - "WRAP" -#endif - }; - - PPVRSRV_DEVICE_NODE psDeviceNode = (PPVRSRV_DEVICE_NODE)pfnDbgRequestHandle; - PHYS_HEAP *psPhysHeap = NULL; - IMG_UINT64 ui64TotalSize; - IMG_UINT64 ui64FreeSize; - IMG_UINT32 i; - - PVR_LOG_RETURN_VOID_IF_FALSE(psDeviceNode != NULL, - "Phys Heap debug request failed. psDeviceNode was NULL"); - - PVR_DUMPDEBUG_LOG("------[ Device ID: %d - Phys Heaps ]------", - psDeviceNode->sDevId.i32OsDeviceID); - - for (i = 0; i < psDeviceNode->ui32RegisteredPhysHeaps; i++) - { - psPhysHeap = psDeviceNode->papsRegisteredPhysHeaps[i]; - - if (psPhysHeap->eType >= ARRAY_SIZE(pszTypeStrings)) - { - PVR_DPF((PVR_DBG_ERROR, - "PhysHeap at address %p eType is not a PHYS_HEAP_TYPE", - psPhysHeap)); - break; - } - - psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats(psPhysHeap->pvImplData, - &ui64TotalSize, - &ui64FreeSize); - - if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA) - { - IMG_CPU_PHYADDR sCPUPAddr; - IMG_DEV_PHYADDR sGPUPAddr; - PVRSRV_ERROR eError; - - PVR_ASSERT(psPhysHeap->psImplFuncs->pfnGetCPUPAddr != NULL); - PVR_ASSERT(psPhysHeap->psImplFuncs->pfnGetDevPAddr != NULL); - - eError = psPhysHeap->psImplFuncs->pfnGetCPUPAddr(psPhysHeap->pvImplData, - &sCPUPAddr); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "pfnGetCPUPAddr"); - sCPUPAddr.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(IMG_UINT64_MAX); - } - - eError = psPhysHeap->psImplFuncs->pfnGetDevPAddr(psPhysHeap->pvImplData, - &sGPUPAddr); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "pfnGetDevPAddr"); - sGPUPAddr.uiAddr = IMG_UINT64_MAX; - } - - PVR_DUMPDEBUG_LOG("0x%p -> Name: %s, Type: %s, " - - "CPU PA Base: " CPUPHYADDR_UINT_FMTSPEC", " - "GPU PA Base: 0x%08"IMG_UINT64_FMTSPECx", " - "Usage Flags: 0x%08x, Refs: %d, " - "Free Size: %"IMG_UINT64_FMTSPEC", " - "Total Size: %"IMG_UINT64_FMTSPEC, - psPhysHeap, - psPhysHeap->pszPDumpMemspaceName, - pszTypeStrings[psPhysHeap->eType], - CPUPHYADDR_FMTARG(sCPUPAddr.uiAddr), - sGPUPAddr.uiAddr, - psPhysHeap->ui32UsageFlags, - psPhysHeap->ui32RefCount, - ui64FreeSize, - ui64TotalSize); - } - else - { - PVR_DUMPDEBUG_LOG("0x%p -> Name: %s, Type: %s, " - "Usage Flags: 0x%08x, Refs: %d, " - "Free Size: %"IMG_UINT64_FMTSPEC", " - "Total Size: %"IMG_UINT64_FMTSPEC, - psPhysHeap, - psPhysHeap->pszPDumpMemspaceName, - pszTypeStrings[psPhysHeap->eType], - psPhysHeap->ui32UsageFlags, - psPhysHeap->ui32RefCount, - ui64FreeSize, - ui64TotalSize); - } - } -} - -PVRSRV_ERROR -PhysHeapCreateHeapFromConfig(PVRSRV_DEVICE_NODE *psDevNode, - PHYS_HEAP_CONFIG *psConfig, - PHYS_HEAP **ppsPhysHeap) -{ - PVRSRV_ERROR eResult; - - if (psConfig->eType == PHYS_HEAP_TYPE_UMA -#if defined(SUPPORT_WRAP_EXTMEMOBJECT) - || psConfig->eType == PHYS_HEAP_TYPE_WRAP -#endif - ) - { - eResult = PhysHeapCreate(psDevNode, psConfig, NULL, - &_sPHEAPImplFuncs, ppsPhysHeap); - } - else if (psConfig->eType == PHYS_HEAP_TYPE_LMA || - psConfig->eType == PHYS_HEAP_TYPE_DMA) - { - eResult = PhysmemCreateHeapLMA(psDevNode, psConfig, "GPU LMA (Sys)", ppsPhysHeap); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s Invalid phys heap type: %d", - __func__, psConfig->eType)); - eResult = PVRSRV_ERROR_INVALID_PARAMS; - } - - return eResult; -} - -PVRSRV_ERROR -PhysHeapCreateDeviceHeapsFromConfigs(PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP_CONFIG *pasConfigs, - IMG_UINT32 ui32NumConfigs) -{ - IMG_UINT32 i; - PVRSRV_ERROR eError; - - /* Register the physical memory heaps */ - psDevNode->papsRegisteredPhysHeaps = - OSAllocZMem(sizeof(*psDevNode->papsRegisteredPhysHeaps) * ui32NumConfigs); - PVR_LOG_RETURN_IF_NOMEM(psDevNode->papsRegisteredPhysHeaps, "OSAllocZMem"); - - psDevNode->ui32RegisteredPhysHeaps = 0; - - for (i = 0; i < ui32NumConfigs; i++) - { - eError = PhysHeapCreateHeapFromConfig(psDevNode, - pasConfigs + i, - psDevNode->papsRegisteredPhysHeaps + i); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysmemCreateHeap"); - - psDevNode->ui32RegisteredPhysHeaps++; - } - -#if defined(SUPPORT_PHYSMEM_TEST) - /* For a temporary device node there will never be a debug dump - * request targeting it */ - if (psDevNode->hDebugTable != NULL) -#endif - { - eError = PVRSRVRegisterDeviceDbgRequestNotify(&psDevNode->hPhysHeapDbgReqNotify, - psDevNode, - _PhysHeapDebugRequest, - DEBUG_REQUEST_SYS, - psDevNode); - - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVRegisterDeviceDbgRequestNotify"); - } - return PVRSRV_OK; -} - -PVRSRV_ERROR PhysHeapCreate(PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP_CONFIG *psConfig, - PHEAP_IMPL_DATA pvImplData, - PHEAP_IMPL_FUNCS *psImplFuncs, - PHYS_HEAP **ppsPhysHeap) -{ - PHYS_HEAP *psNew; - - PVR_DPF_ENTERED; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevNode != NULL, "psDevNode"); - - if (psConfig->eType == PHYS_HEAP_TYPE_UNKNOWN) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_LOG_RETURN_IF_INVALID_PARAM(psImplFuncs != NULL, "psImplFuncs"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psImplFuncs->pfnCreatePMR != NULL, "psImplFuncs->pfnCreatePMR"); - - psNew = OSAllocMem(sizeof(PHYS_HEAP)); - PVR_RETURN_IF_NOMEM(psNew); - psNew->psDevNode = psDevNode; - psNew->eType = psConfig->eType; - psNew->psMemFuncs = psConfig->psMemFuncs; - psNew->hPrivData = psConfig->hPrivData; - psNew->ui32RefCount = 0; - psNew->pszPDumpMemspaceName = psConfig->pszPDumpMemspaceName; - psNew->ui32UsageFlags = psConfig->ui32UsageFlags; - - psNew->pvImplData = pvImplData; - psNew->psImplFuncs = psImplFuncs; - - psNew->psNext = g_psPhysHeapList; - g_psPhysHeapList = psNew; - - *ppsPhysHeap = psNew; - - PVR_DPF_RETURN_RC1(PVRSRV_OK, *ppsPhysHeap); -} - -void PhysHeapDestroyDeviceHeaps(PPVRSRV_DEVICE_NODE psDevNode) -{ - IMG_UINT32 i; - - if (psDevNode->hPhysHeapDbgReqNotify) - { - PVRSRVUnregisterDeviceDbgRequestNotify(psDevNode->hPhysHeapDbgReqNotify); - } - - /* Unregister heaps */ - for (i = 0; i < psDevNode->ui32RegisteredPhysHeaps; i++) - { - PhysHeapDestroy(psDevNode->papsRegisteredPhysHeaps[i]); - } - - OSFreeMem(psDevNode->papsRegisteredPhysHeaps); -} - -void PhysHeapDestroy(PHYS_HEAP *psPhysHeap) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - - PVR_DPF_ENTERED1(psPhysHeap); - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK) -#endif - { - PVR_ASSERT(psPhysHeap->ui32RefCount == 0); - } - - if (g_psPhysHeapList == psPhysHeap) - { - g_psPhysHeapList = psPhysHeap->psNext; - } - else - { - PHYS_HEAP *psTmp = g_psPhysHeapList; - - while (psTmp->psNext != psPhysHeap) - { - psTmp = psTmp->psNext; - } - psTmp->psNext = psPhysHeap->psNext; - } - - if (psImplFuncs->pfnDestroyData != NULL) - { - psImplFuncs->pfnDestroyData(psPhysHeap->pvImplData); - } - - OSFreeMem(psPhysHeap); - - PVR_DPF_RETURN; -} - -PVRSRV_ERROR PhysHeapAcquire(PHYS_HEAP *psPhysHeap) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(psPhysHeap != NULL, "psPhysHeap"); - - psPhysHeap->ui32RefCount++; - - return PVRSRV_OK; -} - -PVRSRV_ERROR PhysHeapAcquireByUsage(PHYS_HEAP_USAGE_FLAGS ui32UsageFlag, - PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP **ppsPhysHeap) -{ - PHYS_HEAP *psNode = g_psPhysHeapList; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_INVALID_PARAM(ui32UsageFlag != 0, "ui32UsageFlag"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevNode != NULL, "psDevNode"); - - PVR_DPF_ENTERED1(ui32UsageFlag); - - OSLockAcquire(g_hPhysHeapLock); - - while (psNode) - { - if (psNode->psDevNode != psDevNode) - { - psNode = psNode->psNext; - continue; - } - if (BITMASK_ANY(psNode->ui32UsageFlags, ui32UsageFlag)) - { - break; - } - psNode = psNode->psNext; - } - - if (psNode == NULL) - { - eError = PVRSRV_ERROR_PHYSHEAP_ID_INVALID; - } - else - { - psNode->ui32RefCount++; - PHYSHEAP_REFCOUNT_PRINT("%s: Heap %p, refcount = %d", - __func__, psNode, psNode->ui32RefCount); - } - - OSLockRelease(g_hPhysHeapLock); - - *ppsPhysHeap = psNode; - PVR_DPF_RETURN_RC1(eError, *ppsPhysHeap); -} - -static PHYS_HEAP * _PhysHeapFindHeap(PVRSRV_PHYS_HEAP ePhysHeap, - PPVRSRV_DEVICE_NODE psDevNode) -{ - PHYS_HEAP *psPhysHeapNode = g_psPhysHeapList; - PVRSRV_PHYS_HEAP eFallback; - - if (ePhysHeap == PVRSRV_PHYS_HEAP_DEFAULT) - { - ePhysHeap = psDevNode->psDevConfig->eDefaultHeap; - } - - while (psPhysHeapNode) - { - if ((psPhysHeapNode->psDevNode == psDevNode) && - BIT_ISSET(psPhysHeapNode->ui32UsageFlags, ePhysHeap)) - { - return psPhysHeapNode; - } - - psPhysHeapNode = psPhysHeapNode->psNext; - } - - eFallback = gasHeapProperties[ePhysHeap].eFallbackHeap; - - if (ePhysHeap == eFallback) - { - return NULL; - } - else - { - return _PhysHeapFindHeap(eFallback, psDevNode); - } -} - -PVRSRV_ERROR PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP eDevPhysHeap, - PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP **ppsPhysHeap) -{ - PHYS_HEAP *psPhysHeap; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_INVALID_PARAM(eDevPhysHeap != PVRSRV_PHYS_HEAP_DEFAULT, "eDevPhysHeap"); - PVR_LOG_RETURN_IF_INVALID_PARAM(eDevPhysHeap < PVRSRV_PHYS_HEAP_LAST, "eDevPhysHeap"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevNode != NULL, "psDevNode"); - - PVR_DPF_ENTERED1(ui32Flags); - - OSLockAcquire(g_hPhysHeapLock); - - psPhysHeap = _PhysHeapFindHeap(eDevPhysHeap, psDevNode); - - if (psPhysHeap != NULL) - { - psPhysHeap->ui32RefCount++; - PHYSHEAP_REFCOUNT_PRINT("%s: Heap %p, refcount = %d", - __func__, psPhysHeap, psPhysHeap->ui32RefCount); - } - else - { - eError = PVRSRV_ERROR_PHYSHEAP_ID_INVALID; - } - - OSLockRelease(g_hPhysHeapLock); - - *ppsPhysHeap = psPhysHeap; - PVR_DPF_RETURN_RC1(eError, *ppsPhysHeap); -} - -void PhysHeapRelease(PHYS_HEAP *psPhysHeap) -{ - PVR_DPF_ENTERED1(psPhysHeap); - - OSLockAcquire(g_hPhysHeapLock); - psPhysHeap->ui32RefCount--; - PHYSHEAP_REFCOUNT_PRINT("%s: Heap %p, refcount = %d", - __func__, psPhysHeap, psPhysHeap->ui32RefCount); - OSLockRelease(g_hPhysHeapLock); - - PVR_DPF_RETURN; -} - -PHEAP_IMPL_DATA PhysHeapGetImplData(PHYS_HEAP *psPhysHeap) -{ - return psPhysHeap->pvImplData; -} - -PHYS_HEAP_TYPE PhysHeapGetType(PHYS_HEAP *psPhysHeap) -{ - PVR_ASSERT(psPhysHeap->eType != PHYS_HEAP_TYPE_UNKNOWN); - return psPhysHeap->eType; -} - -PHYS_HEAP_USAGE_FLAGS PhysHeapGetFlags(PHYS_HEAP *psPhysHeap) -{ - return psPhysHeap->ui32UsageFlags; -} - -IMG_BOOL PhysHeapValidateDefaultHeapExists(PPVRSRV_DEVICE_NODE psDevNode) -{ - PHYS_HEAP *psDefaultHeap; - IMG_BOOL bDefaultHeapFound; - PhysHeapAcquireByUsage(1<<(psDevNode->psDevConfig->eDefaultHeap), psDevNode, &psDefaultHeap); - if (psDefaultHeap == NULL) - { - bDefaultHeapFound = IMG_FALSE; - } - else - { - PhysHeapRelease(psDefaultHeap); - bDefaultHeapFound = IMG_TRUE; - } - return bDefaultHeapFound; -} - - -/* - * This function will set the psDevPAddr to whatever the system layer - * has set it for the referenced region. - * It will not fail if the psDevPAddr is invalid. - */ -PVRSRV_ERROR PhysHeapGetDevPAddr(PHYS_HEAP *psPhysHeap, - IMG_DEV_PHYADDR *psDevPAddr) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnGetDevPAddr != NULL) - { - eResult = psImplFuncs->pfnGetDevPAddr(psPhysHeap->pvImplData, - psDevPAddr); - } - - return eResult; -} - -/* - * This function will set the psCpuPAddr to whatever the system layer - * has set it for the referenced region. - * It will not fail if the psCpuPAddr is invalid. - */ -PVRSRV_ERROR PhysHeapGetCpuPAddr(PHYS_HEAP *psPhysHeap, - IMG_CPU_PHYADDR *psCpuPAddr) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnGetCPUPAddr != NULL) - { - eResult = psImplFuncs->pfnGetCPUPAddr(psPhysHeap->pvImplData, - psCpuPAddr); - } - - return eResult; -} - -PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap, - IMG_UINT64 *puiSize) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnGetSize != NULL) - { - eResult = psImplFuncs->pfnGetSize(psPhysHeap->pvImplData, - puiSize); - } - - return eResult; -} - -PVRSRV_ERROR -PhysHeapGetMemInfo(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PTR paPhysHeapMemStats) -{ - IMG_UINT32 i = 0; - PHYS_HEAP *psPhysHeap; - - PVR_ASSERT(ui32PhysHeapCount <= PVRSRV_PHYS_HEAP_LAST); - - for (i = 0; i < ui32PhysHeapCount; i++) - { - if (paePhysHeapID[i] >= PVRSRV_PHYS_HEAP_LAST) - { - return PVRSRV_ERROR_PHYSHEAP_ID_INVALID; - } - - if (paePhysHeapID[i] == PVRSRV_PHYS_HEAP_DEFAULT) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psPhysHeap = _PhysHeapFindHeap(paePhysHeapID[i], psDevNode); - - paPhysHeapMemStats[i].ui32PhysHeapFlags = 0; - - if (psPhysHeap && PhysHeapUserModeAlloc(paePhysHeapID[i]) - && psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats) - { - psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats(psPhysHeap->pvImplData, - &paPhysHeapMemStats[i].ui64TotalSize, - &paPhysHeapMemStats[i].ui64FreeSize); - paPhysHeapMemStats[i].ui32PhysHeapFlags |= PhysHeapGetType(psPhysHeap); - - if (paePhysHeapID[i] == psDevNode->psDevConfig->eDefaultHeap) - { - paPhysHeapMemStats[i].ui32PhysHeapFlags |= PVRSRV_PHYS_HEAP_FLAGS_IS_DEFAULT; - } - } - else - { - paPhysHeapMemStats[i].ui64TotalSize = 0; - paPhysHeapMemStats[i].ui64FreeSize = 0; - } - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PhysHeapGetMemInfoPkd(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PKD_PTR paPhysHeapMemStats) -{ - IMG_UINT32 i = 0; - PHYS_HEAP *psPhysHeap; - - PVR_ASSERT(ui32PhysHeapCount <= PVRSRV_PHYS_HEAP_LAST); - - for (i = 0; i < ui32PhysHeapCount; i++) - { - if (paePhysHeapID[i] >= PVRSRV_PHYS_HEAP_LAST) - { - return PVRSRV_ERROR_PHYSHEAP_ID_INVALID; - } - - if (paePhysHeapID[i] == PVRSRV_PHYS_HEAP_DEFAULT) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psPhysHeap = _PhysHeapFindHeap(paePhysHeapID[i], psDevNode); - - paPhysHeapMemStats[i].ui32PhysHeapFlags = 0; - - if (psPhysHeap && PhysHeapUserModeAlloc(paePhysHeapID[i]) - && psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats) - { - psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats(psPhysHeap->pvImplData, - &paPhysHeapMemStats[i].ui64TotalSize, - &paPhysHeapMemStats[i].ui64FreeSize); - paPhysHeapMemStats[i].ui32PhysHeapFlags |= PhysHeapGetType(psPhysHeap); - - if (paePhysHeapID[i] == psDevNode->psDevConfig->eDefaultHeap) - { - paPhysHeapMemStats[i].ui32PhysHeapFlags |= PVRSRV_PHYS_HEAP_FLAGS_IS_DEFAULT; - } - } - else - { - paPhysHeapMemStats[i].ui64TotalSize = 0; - paPhysHeapMemStats[i].ui64FreeSize = 0; - } - } - - return PVRSRV_OK; -} - -void PhysheapGetPhysMemUsage(PHYS_HEAP *psPhysHeap, IMG_UINT64 *pui64TotalSize, IMG_UINT64 *pui64FreeSize) -{ - if (psPhysHeap && psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats) - { - psPhysHeap->psImplFuncs->pfnGetPMRFactoryMemStats(psPhysHeap->pvImplData, - pui64TotalSize, - pui64FreeSize); - } - else - { - *pui64TotalSize = *pui64FreeSize = 0; - } -} - -void PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap, - IMG_UINT32 ui32NumOfAddr, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_CPU_PHYADDR *psCpuPAddr) -{ - psPhysHeap->psMemFuncs->pfnCpuPAddrToDevPAddr(psPhysHeap->hPrivData, - ui32NumOfAddr, - psDevPAddr, - psCpuPAddr); -} - -void PhysHeapDevPAddrToCpuPAddr(PHYS_HEAP *psPhysHeap, - IMG_UINT32 ui32NumOfAddr, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_DEV_PHYADDR *psDevPAddr) -{ - psPhysHeap->psMemFuncs->pfnDevPAddrToCpuPAddr(psPhysHeap->hPrivData, - ui32NumOfAddr, - psCpuPAddr, - psDevPAddr); -} - -IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap) -{ - return psPhysHeap->pszPDumpMemspaceName; -} - -PVRSRV_ERROR PhysHeapCreatePMR(PHYS_HEAP *psPhysHeap, - struct _CONNECTION_DATA_ *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - - return psImplFuncs->pfnCreatePMR(psPhysHeap, - psConnection, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2PageSize, - uiFlags, - pszAnnotation, - uiPid, - ppsPMRPtr, - ui32PDumpFlags); -} - -PVRSRV_ERROR PhysHeapInit(void) -{ - PVRSRV_ERROR eError; - - g_psPhysHeapList = NULL; - - eError = OSLockCreate(&g_hPhysHeapLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate"); - - return PVRSRV_OK; -} - -void PhysHeapDeinit(void) -{ - PVR_ASSERT(g_psPhysHeapList == NULL); - - OSLockDestroy(g_hPhysHeapLock); -} - -PPVRSRV_DEVICE_NODE PhysHeapDeviceNode(PHYS_HEAP *psPhysHeap) -{ - PVR_ASSERT(psPhysHeap != NULL); - - return psPhysHeap->psDevNode; -} - -IMG_BOOL PhysHeapPVRLayerAcquire(PVRSRV_PHYS_HEAP ePhysHeap) -{ - PVR_ASSERT(ePhysHeap < PVRSRV_PHYS_HEAP_LAST); - - return gasHeapProperties[ePhysHeap].bPVRLayerAcquire; -} - -IMG_BOOL PhysHeapUserModeAlloc(PVRSRV_PHYS_HEAP ePhysHeap) -{ - PVR_ASSERT(ePhysHeap < PVRSRV_PHYS_HEAP_LAST); - - return gasHeapProperties[ePhysHeap].bUserModeAlloc; -} - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -/*************************************************************************/ /*! -@Function CreateGpuVirtValArenas -@Description Create virtualization validation arenas -@Input psDeviceNode The device node -@Return PVRSRV_ERROR PVRSRV_OK on success -*/ /**************************************************************************/ -static PVRSRV_ERROR CreateGpuVirtValArenas(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* aui64OSidMin and aui64OSidMax are what we program into HW registers. - The values are different from base/size of arenas. */ - IMG_UINT64 aui64OSidMin[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS]; - IMG_UINT64 aui64OSidMax[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS]; - PHYS_HEAP_CONFIG *psGPULocalHeap = FindPhysHeapConfig(psDeviceNode->psDevConfig, PHYS_HEAP_USAGE_GPU_LOCAL); - PHYS_HEAP_CONFIG *psDisplayHeap = FindPhysHeapConfig(psDeviceNode->psDevConfig, PHYS_HEAP_USAGE_DISPLAY); - IMG_UINT64 uBase; - IMG_UINT64 uSize; - IMG_UINT64 uBaseShared; - IMG_UINT64 uSizeShared; - IMG_UINT64 uSizeSharedReg; - IMG_UINT32 i; - - /* Shared region is fixed size, the remaining space is divided amongst OSes */ - uSizeShared = PVR_ALIGN(GPUVIRT_SIZEOF_SHARED, (IMG_DEVMEM_SIZE_T)OSGetPageSize()); - uSize = psGPULocalHeap->uiSize - uSizeShared; - uSize /= GPUVIRT_VALIDATION_NUM_OS; - uSize = uSize & ~((IMG_UINT64)OSGetPageSize() - 1ULL); /* Align, round down */ - - uBase = psGPULocalHeap->sCardBase.uiAddr; - uBaseShared = uBase + uSize * GPUVIRT_VALIDATION_NUM_OS; - uSizeShared = psGPULocalHeap->uiSize - (uBaseShared - uBase); - - PVR_LOG(("GPUVIRT_VALIDATION split GPU_LOCAL base: 0x%" IMG_UINT64_FMTSPECX ", size: 0x%" IMG_UINT64_FMTSPECX ".", - psGPULocalHeap->sCardBase.uiAddr, - psGPULocalHeap->uiSize)); - - /* If a display heap config exists, include the display heap in the non-secure regions */ - if (psDisplayHeap) - { - /* Only works when DISPLAY heap follows GPU_LOCAL heap. */ - PVR_LOG(("GPUVIRT_VALIDATION include DISPLAY in shared, base: 0x%" IMG_UINT64_FMTSPECX ", size: 0x%" IMG_UINT64_FMTSPECX ".", - psDisplayHeap->sCardBase.uiAddr, - psDisplayHeap->uiSize)); - - uSizeSharedReg = uSizeShared + psDisplayHeap->uiSize; - } - else - { - uSizeSharedReg = uSizeShared; - } - - PVR_ASSERT(uSize >= GPUVIRT_MIN_SIZE); - PVR_ASSERT(uSizeSharedReg >= GPUVIRT_SIZEOF_SHARED); - - for (i = 0; i < GPUVIRT_VALIDATION_NUM_OS; i++) - { - IMG_CHAR aszOSRAName[RA_MAX_NAME_LENGTH]; - - PVR_LOG(("GPUVIRT_VALIDATION create arena OS: %d, base: 0x%" IMG_UINT64_FMTSPECX ", size: 0x%" IMG_UINT64_FMTSPECX ".", i, uBase, uSize)); - - OSSNPrintf(aszOSRAName, RA_MAX_NAME_LENGTH, "GPUVIRT_OS%d", i); - - psDeviceNode->psOSidSubArena[i] = RA_Create_With_Span(aszOSRAName, - OSGetPageShift(), - 0, - uBase, - uSize); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode->psOSidSubArena[i], "RA_Create_With_Span"); - - aui64OSidMin[GPUVIRT_VAL_REGION_SECURE][i] = uBase; - - if (i == 0) - { - /* OSid0 has access to all regions */ - aui64OSidMax[GPUVIRT_VAL_REGION_SECURE][i] = psGPULocalHeap->uiSize - 1ULL; - } - else - { - aui64OSidMax[GPUVIRT_VAL_REGION_SECURE][i] = uBase + uSize - 1ULL; - } - - /* uSizeSharedReg includes display heap */ - aui64OSidMin[GPUVIRT_VAL_REGION_SHARED][i] = uBaseShared; - aui64OSidMax[GPUVIRT_VAL_REGION_SHARED][i] = uBaseShared + uSizeSharedReg - 1ULL; - - PVR_LOG(("GPUVIRT_VALIDATION HW reg regions %d: min[0]: 0x%" IMG_UINT64_FMTSPECX ", max[0]: 0x%" IMG_UINT64_FMTSPECX ", min[1]: 0x%" IMG_UINT64_FMTSPECX ", max[1]: 0x%" IMG_UINT64_FMTSPECX ",", - i, - aui64OSidMin[GPUVIRT_VAL_REGION_SECURE][i], - aui64OSidMax[GPUVIRT_VAL_REGION_SECURE][i], - aui64OSidMin[GPUVIRT_VAL_REGION_SHARED][i], - aui64OSidMax[GPUVIRT_VAL_REGION_SHARED][i])); - uBase += uSize; - } - - PVR_LOG(("GPUVIRT_VALIDATION create arena Shared, base: 0x%" IMG_UINT64_FMTSPECX ", size: 0x%" IMG_UINT64_FMTSPECX ".", uBaseShared, uSizeShared)); - - PVR_ASSERT(uSizeShared >= GPUVIRT_SIZEOF_SHARED); - - /* uSizeShared does not include display heap */ - psDeviceNode->psOSSharedArena = RA_Create_With_Span("GPUVIRT_SHARED", - OSGetPageShift(), - 0, - uBaseShared, - uSizeShared); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode->psOSSharedArena, "RA_Create_With_Span"); - - if (psDeviceNode->psDevConfig->pfnSysDevVirtInit != NULL) - { - psDeviceNode->psDevConfig->pfnSysDevVirtInit(aui64OSidMin, aui64OSidMax); - } - - return PVRSRV_OK; -} - -/* - * Counter-part to CreateGpuVirtValArenas. - */ -static void DestroyGpuVirtValArenas(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_UINT32 uiCounter = 0; - - /* - * NOTE: We overload psOSidSubArena[0] into the psLocalMemArena so we must - * not free it here as it gets cleared later. - */ - for (uiCounter = 1; uiCounter < GPUVIRT_VALIDATION_NUM_OS; uiCounter++) - { - if (psDeviceNode->psOSidSubArena[uiCounter] == NULL) - { - continue; - } - RA_Delete(psDeviceNode->psOSidSubArena[uiCounter]); - } - - if (psDeviceNode->psOSSharedArena != NULL) - { - RA_Delete(psDeviceNode->psOSSharedArena); - } -} -#endif - -PVRSRV_ERROR PhysHeapMMUPxSetup(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - PHYS_HEAP_TYPE eHeapType; - PVRSRV_ERROR eError; - - eError = PhysHeapAcquireByDevPhysHeap(psDeviceNode->psDevConfig->eDefaultHeap, - psDeviceNode, &psDeviceNode->psMMUPhysHeap); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquireByDevPhysHeap", ErrorDeinit); - - eHeapType = PhysHeapGetType(psDeviceNode->psMMUPhysHeap); - - if (eHeapType == PHYS_HEAP_TYPE_UMA) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: GPU physical heap uses OS System memory (UMA)", __func__)); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - PVR_DPF((PVR_DBG_ERROR, "%s: Virtualisation Validation builds are currently only" - " supported on systems with local memory (LMA).", __func__)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - goto ErrorDeinit; -#endif - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: GPU physical heap uses local memory managed by the driver (LMA)", __func__)); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - eError = CreateGpuVirtValArenas(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "CreateGpuVirtValArenas", ErrorDeinit); -#endif - } - - return PVRSRV_OK; -ErrorDeinit: - return eError; -} - -void PhysHeapMMUPxDeInit(PPVRSRV_DEVICE_NODE psDeviceNode) -{ -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* Remove local LMA subarenas */ - DestroyGpuVirtValArenas(psDeviceNode); -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - - if (psDeviceNode->psMMUPhysHeap != NULL) - { - PhysHeapRelease(psDeviceNode->psMMUPhysHeap); - psDeviceNode->psMMUPhysHeap = NULL; - } -} - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -PVRSRV_ERROR PhysHeapPagesAllocGPV(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 ui32OSid, IMG_PID uiPid) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnPagesAllocGPV != NULL) - { - eResult = psImplFuncs->pfnPagesAllocGPV(psPhysHeap, - uiSize, psMemHandle, psDevPAddr, ui32OSid, uiPid); - } - - return eResult; -} -#endif - -PVRSRV_ERROR PhysHeapPagesAlloc(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnPagesAlloc != NULL) - { - eResult = psImplFuncs->pfnPagesAlloc(psPhysHeap, - uiSize, psMemHandle, psDevPAddr, uiPid); - } - - return eResult; -} - -void PhysHeapPagesFree(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - - PVR_ASSERT(psImplFuncs->pfnPagesFree != NULL); - - if (psImplFuncs->pfnPagesFree != NULL) - { - psImplFuncs->pfnPagesFree(psPhysHeap, - psMemHandle); - } -} - -PVRSRV_ERROR PhysHeapPagesMap(PHYS_HEAP *psPhysHeap, PG_HANDLE *pshMemHandle, size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnPagesMap != NULL) - { - eResult = psImplFuncs->pfnPagesMap(psPhysHeap, - pshMemHandle, uiSize, psDevPAddr, pvPtr); - } - - return eResult; -} - -void PhysHeapPagesUnMap(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle, void *pvPtr) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - - PVR_ASSERT(psImplFuncs->pfnPagesUnMap != NULL); - - if (psImplFuncs->pfnPagesUnMap != NULL) - { - psImplFuncs->pfnPagesUnMap(psPhysHeap, - psMemHandle, pvPtr); - } -} - -PVRSRV_ERROR PhysHeapPagesClean(PHYS_HEAP *psPhysHeap, PG_HANDLE *pshMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - PVRSRV_ERROR eResult = PVRSRV_ERROR_NOT_IMPLEMENTED; - - if (psImplFuncs->pfnPagesClean != NULL) - { - eResult = psImplFuncs->pfnPagesClean(psPhysHeap, - pshMemHandle, uiOffset, uiLength); - } - - return eResult; -} - -IMG_UINT32 PhysHeapGetPageShift(PHYS_HEAP *psPhysHeap) -{ - PHEAP_IMPL_FUNCS *psImplFuncs = psPhysHeap->psImplFuncs; - IMG_UINT32 ui32PageShift = 0; - - PVR_ASSERT(psImplFuncs->pfnGetPageShift != NULL); - - if (psImplFuncs->pfnGetPageShift != NULL) - { - ui32PageShift = psImplFuncs->pfnGetPageShift(); - } - - return ui32PageShift; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physheap.h b/drivers/gpu/drm/img-rogue/1.17/physheap.h deleted file mode 100644 index 060c5cd0e4dfa..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physheap.h +++ /dev/null @@ -1,497 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Physical heap management header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the interface for the physical heap management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "devicemem_typedefs.h" -#include "opaque_types.h" -#include "pmr_impl.h" -#include "physheap_config.h" - -#ifndef PHYSHEAP_H -#define PHYSHEAP_H - -typedef struct _PHYS_HEAP_ PHYS_HEAP; -#define INVALID_PHYS_HEAP 0xDEADDEAD - -struct _CONNECTION_DATA_; - -typedef struct _PG_HANDLE_ -{ - union - { - void *pvHandle; - IMG_UINT64 ui64Handle; - }u; - /* The allocation order is log2 value of the number of pages to allocate. - * As such this is a correspondingly small value. E.g, for order 4 we - * are talking 2^4 * PAGE_SIZE contiguous allocation. - * DevPxAlloc API does not need to support orders higher than 4. - */ -#if defined(SUPPORT_GPUVIRT_VALIDATION) - IMG_BYTE uiOrder; /* Order of the corresponding allocation */ - IMG_BYTE uiOSid; /* OSid to use for allocation arena. - * Connection-specific. */ - IMG_BYTE uiPad1, - uiPad2; /* Spare */ -#else - IMG_BYTE uiOrder; /* Order of the corresponding allocation */ - IMG_BYTE uiPad1, - uiPad2, - uiPad3; /* Spare */ -#endif -} PG_HANDLE; - -/*! Pointer to private implementation specific data */ -typedef void *PHEAP_IMPL_DATA; - -/*************************************************************************/ /*! -@Function Callback function PFN_DESTROY_DATA -@Description Destroy private implementation specific data. -@Input PHEAP_IMPL_DATA Pointer to implementation data. -*/ /**************************************************************************/ -typedef void (*PFN_DESTROY_DATA)(PHEAP_IMPL_DATA); -/*************************************************************************/ /*! -@Function Callback function PFN_GET_DEV_PADDR -@Description Get heap device physical address. -@Input PHEAP_IMPL_DATA Pointer to implementation data. -@Output IMG_DEV_PHYADDR Device physical address. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_GET_DEV_PADDR)(PHEAP_IMPL_DATA, IMG_DEV_PHYADDR*); -/*************************************************************************/ /*! -@Function Callback function PFN_GET_CPU_PADDR -@Description Get heap CPU physical address. -@Input PHEAP_IMPL_DATA Pointer to implementation data. -@Output IMG_CPU_PHYADDR CPU physical address. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_GET_CPU_PADDR)(PHEAP_IMPL_DATA, IMG_CPU_PHYADDR*); -/*************************************************************************/ /*! -@Function Callback function PFN_GET_SIZE -@Description Get size of heap. -@Input PHEAP_IMPL_DATA Pointer to implementation data. -@Output IMG_UINT64 Size of heap. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_GET_SIZE)(PHEAP_IMPL_DATA, IMG_UINT64*); -/*************************************************************************/ /*! -@Function Callback function PFN_GET_PAGE_SHIFT -@Description Get heap log2 page shift. -@Return IMG_UINT32 Log2 page shift -*/ /**************************************************************************/ -typedef IMG_UINT32 (*PFN_GET_PAGE_SHIFT)(void); - -/*************************************************************************/ /*! -@Function Callback function PFN_GET_MEM_STATS -@Description Get total and free memory size of the physical heap managed by - the PMR Factory. -@Input PHEAP_IMPL_DATA Pointer to implementation data. -@Output IMG_UINT64 total Size of heap. -@Output IMG_UINT64 free Size available in a heap. -@Return none -*/ /**************************************************************************/ -typedef void (*PFN_GET_MEM_STATS)(PHEAP_IMPL_DATA, IMG_UINT64 *, IMG_UINT64 *); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -typedef PVRSRV_ERROR (*PFN_PAGES_ALLOC_GPV)(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 ui32OSid, IMG_PID uiPid); -#endif -typedef PVRSRV_ERROR (*PFN_PAGES_ALLOC)(PHYS_HEAP *psPhysHeap, size_t uiSize, - PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid); - -typedef void (*PFN_PAGES_FREE)(PHYS_HEAP *psPhysHeap, PG_HANDLE *psMemHandle); - -typedef PVRSRV_ERROR (*PFN_PAGES_MAP)(PHYS_HEAP *psPhysHeap, PG_HANDLE *pshMemHandle, - size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr); - -typedef void (*PFN_PAGES_UNMAP)(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, void *pvPtr); - -typedef PVRSRV_ERROR (*PFN_PAGES_CLEAN)(PHYS_HEAP *psPhysHeap, - PG_HANDLE *pshMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength); - -/*************************************************************************/ /*! -@Function Callback function PFN_CREATE_PMR -@Description Create a PMR physical allocation and back with RAM on creation, - if required. The RAM page comes either directly from - the Phys Heap's associated pool of memory or from an OS API. -@Input psPhysHeap Pointer to Phys Heap. -@Input psConnection Pointer to device connection. -@Input uiSize Allocation size. -@Input uiChunkSize Chunk size. -@Input ui32NumPhysChunks Physical chunk count. -@Input ui32NumVirtChunks Virtual chunk count. -@Input pui32MappingTable Mapping Table. -@Input uiLog2PageSize Page size. -@Input uiFlags Memalloc flags. -@Input pszAnnotation Annotation. -@Input uiPid Process ID. -@Output ppsPMRPtr Pointer to PMR. -@Input ui32PDumpFlag PDump flags. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_CREATE_PMR)(PHYS_HEAP *psPhysHeap, - struct _CONNECTION_DATA_ *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags); - -/*! Implementation specific function table */ -typedef struct PHEAP_IMPL_FUNCS_TAG -{ - PFN_DESTROY_DATA pfnDestroyData; - PFN_GET_DEV_PADDR pfnGetDevPAddr; - PFN_GET_CPU_PADDR pfnGetCPUPAddr; - PFN_GET_SIZE pfnGetSize; - PFN_GET_PAGE_SHIFT pfnGetPageShift; - PFN_GET_MEM_STATS pfnGetPMRFactoryMemStats; - PFN_CREATE_PMR pfnCreatePMR; -#if defined(SUPPORT_GPUVIRT_VALIDATION) - PFN_PAGES_ALLOC_GPV pfnPagesAllocGPV; -#endif - PFN_PAGES_ALLOC pfnPagesAlloc; - PFN_PAGES_FREE pfnPagesFree; - PFN_PAGES_MAP pfnPagesMap; - PFN_PAGES_UNMAP pfnPagesUnMap; - PFN_PAGES_CLEAN pfnPagesClean; -} PHEAP_IMPL_FUNCS; - -/*************************************************************************/ /*! -@Function PhysHeapCreateDeviceHeapsFromConfigs -@Description Create new heaps for a device from configs. -@Input psDevNode Pointer to device node struct -@Input pasConfigs Pointer to array of Heap configurations. -@Input ui32NumConfigs Number of configurations in array. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysHeapCreateDeviceHeapsFromConfigs(PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP_CONFIG *pasConfigs, - IMG_UINT32 ui32NumConfigs); - -/*************************************************************************/ /*! -@Function PhysHeapCreateHeapFromConfig -@Description Create a new heap. Calls specific heap API depending - on heap type. -@Input psDevNode Pointer to device node struct. -@Input psConfig Heap configuration. -@Output ppsPhysHeap Pointer to the created heap. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysHeapCreateHeapFromConfig(PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP_CONFIG *psConfig, - PHYS_HEAP **ppsPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapCreate -@Description Create a new heap. Allocated and stored internally. - Destroy with PhysHeapDestroy when no longer required. -@Input psDevNode Pointer to device node struct -@Input psConfig Heap configuration. -@Input pvImplData Implementation specific data. Can be NULL. -@Input psImplFuncs Implementation specific function table. Must be - a valid pointer. -@Output ppsPhysHeap Pointer to the created heap. Must be a valid - pointer. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR PhysHeapCreate(PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP_CONFIG *psConfig, - PHEAP_IMPL_DATA pvImplData, - PHEAP_IMPL_FUNCS *psImplFuncs, - PHYS_HEAP **ppsPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapDestroyDeviceHeaps -@Description Destroys all heaps referenced by a device. -@Input psDevNode Pointer to a device node struct. -@Return void -*/ /**************************************************************************/ -void PhysHeapDestroyDeviceHeaps(PPVRSRV_DEVICE_NODE psDevNode); - -void PhysHeapDestroy(PHYS_HEAP *psPhysHeap); - -PVRSRV_ERROR PhysHeapAcquire(PHYS_HEAP *psPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapAcquireByUsage -@Description Acquire PhysHeap by usage flag. -@Input ui32UsageFlag PhysHeap usage flag -@Input psDevNode Pointer to device node struct -@Output ppsPhysHeap PhysHeap if found. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR PhysHeapAcquireByUsage(PHYS_HEAP_USAGE_FLAGS ui32UsageFlag, - PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP **ppsPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapAcquireByDevPhysHeap -@Description Acquire PhysHeap by DevPhysHeap. -@Input eDevPhysHeap Device Phys Heap. -@Input psDevNode Pointer to device node struct -@Output ppsPhysHeap PhysHeap if found. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP eDevPhysHeap, - PPVRSRV_DEVICE_NODE psDevNode, - PHYS_HEAP **ppsPhysHeap); - -void PhysHeapRelease(PHYS_HEAP *psPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapGetImplData -@Description Get physical heap implementation specific data. -@Input psPhysHeap Pointer to physical heap. -@Input psConfig Heap configuration. -@Return pvImplData Implementation specific data. Can be NULL. -*/ /**************************************************************************/ -PHEAP_IMPL_DATA PhysHeapGetImplData(PHYS_HEAP *psPhysHeap); - -PHYS_HEAP_TYPE PhysHeapGetType(PHYS_HEAP *psPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapGetFlags -@Description Get phys heap usage flags. -@Input psPhysHeap Pointer to physical heap. -@Return PHYS_HEAP_USAGE_FLAGS Phys heap usage flags. -*/ /**************************************************************************/ -PHYS_HEAP_USAGE_FLAGS PhysHeapGetFlags(PHYS_HEAP *psPhysHeap); - -IMG_BOOL PhysHeapValidateDefaultHeapExists(PPVRSRV_DEVICE_NODE psDevNode); - -PVRSRV_ERROR PhysHeapGetCpuPAddr(PHYS_HEAP *psPhysHeap, - IMG_CPU_PHYADDR *psCpuPAddr); - - -PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap, - IMG_UINT64 *puiSize); - -/*************************************************************************/ /*! -@Function PVRSRVGetDevicePhysHeapCount -@Description Get the physical heap count supported by the device. -@Input psDevNode Device node, the heap count is requested for. -@Output pui32PhysHeapCount Buffer that holds the heap count -@Return None -*/ /**************************************************************************/ -void PVRSRVGetDevicePhysHeapCount(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 *pui32PhysHeapCount); - -/*************************************************************************/ /*! -@Function PhysHeapGetMemInfo -@Description Get phys heap memory statistics for a given physical heap ID. -@Input psDevNode Pointer to device node struct -@Input ui32PhysHeapCount Physical heap count -@Input paePhysHeapID Physical heap ID -@Output paPhysHeapMemStats Buffer that holds the memory statistics -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysHeapGetMemInfo(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PTR paPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PhysHeapGetMemInfoPkd -@Description Get phys heap memory statistics for a given physical heap ID. -@Input psDevNode Pointer to device node struct -@Input ui32PhysHeapCount Physical heap count -@Input paePhysHeapID Physical heap ID -@Output paPhysHeapMemStats Buffer that holds the memory statistics -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysHeapGetMemInfoPkd(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PKD_PTR paPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PhysheapGetPhysMemUsage -@Description Get memory statistics for a given physical heap. -@Input psPhysHeap Physical heap -@Output pui64TotalSize Buffer that holds the total memory size of the - given physical heap. -@Output pui64FreeSize Buffer that holds the free memory available in - a given physical heap. -@Return none -*/ /**************************************************************************/ -void PhysheapGetPhysMemUsage(PHYS_HEAP *psPhysHeap, - IMG_UINT64 *pui64TotalSize, - IMG_UINT64 *pui64FreeSize); - -PVRSRV_ERROR PhysHeapGetDevPAddr(PHYS_HEAP *psPhysHeap, - IMG_DEV_PHYADDR *psDevPAddr); - -void PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap, - IMG_UINT32 ui32NumOfAddr, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_CPU_PHYADDR *psCpuPAddr); - -void PhysHeapDevPAddrToCpuPAddr(PHYS_HEAP *psPhysHeap, - IMG_UINT32 ui32NumOfAddr, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_DEV_PHYADDR *psDevPAddr); - -IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapCreatePMR -@Description Function calls an implementation-specific function pointer. - See function pointer for details. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR PhysHeapCreatePMR(PHYS_HEAP *psPhysHeap, - struct _CONNECTION_DATA_ *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PhysHeapInit(void); -void PhysHeapDeinit(void); - -/*************************************************************************/ /*! -@Function PhysHeapDeviceNode -@Description Get pointer to the device node this heap belongs to. -@Input psPhysHeap Pointer to physical heap. -@Return PPVRSRV_DEVICE_NODE Pointer to device node. -*/ /**************************************************************************/ -PPVRSRV_DEVICE_NODE PhysHeapDeviceNode(PHYS_HEAP *psPhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapPVRLayerAcquire -@Description Is phys heap to be acquired in PVR layer? -@Input ePhysHeap phys heap -@Return IMG_BOOL return IMG_TRUE if yes -*/ /**************************************************************************/ -IMG_BOOL PhysHeapPVRLayerAcquire(PVRSRV_PHYS_HEAP ePhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapUserModeAlloc -@Description Is allocation from UM allowed? -@Input ePhysHeap phys heap -@Return IMG_BOOL return IMG_TRUE if yes -*/ /**************************************************************************/ -IMG_BOOL PhysHeapUserModeAlloc(PVRSRV_PHYS_HEAP ePhysHeap); - -/*************************************************************************/ /*! -@Function PhysHeapMMUPxSetup -@Description Setup MMU Px allocation function pointers. -@Input psDeviceNode Pointer to device node struct -@Return PVRSRV_ERROR PVRSRV_OK on success. -*/ /**************************************************************************/ -PVRSRV_ERROR PhysHeapMMUPxSetup(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*************************************************************************/ /*! -@Function PhysHeapMMUPxDeInit -@Description Deinit after PhysHeapMMUPxSetup. -@Input psDeviceNode Pointer to device node struct -*/ /**************************************************************************/ -void PhysHeapMMUPxDeInit(PPVRSRV_DEVICE_NODE psDeviceNode); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -PVRSRV_ERROR PhysHeapPagesAllocGPV(PHYS_HEAP *psPhysHeap, - size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 ui32OSid, IMG_PID uiPid); -#endif - -PVRSRV_ERROR PhysHeapPagesAlloc(PHYS_HEAP *psPhysHeap, - size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid); - -void PhysHeapPagesFree(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle); - -PVRSRV_ERROR PhysHeapPagesMap(PHYS_HEAP *psPhysHeap, - PG_HANDLE *pshMemHandle, - size_t uiSize, - IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr); - -void PhysHeapPagesUnMap(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - void *pvPtr); - -PVRSRV_ERROR PhysHeapPagesClean(PHYS_HEAP *psPhysHeap, - PG_HANDLE *pshMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength); - -/*************************************************************************/ /*! -@Function PhysHeapGetPageShift -@Description Get phys heap page shift. -@Input psPhysHeap Pointer to physical heap. -@Return IMG_UINT32 Log2 page shift -*/ /**************************************************************************/ -IMG_UINT32 PhysHeapGetPageShift(PHYS_HEAP *psPhysHeap); - -#endif /* PHYSHEAP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physheap_config.h b/drivers/gpu/drm/img-rogue/1.17/physheap_config.h deleted file mode 100644 index 9d4d786dd0781..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physheap_config.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************/ /*! -@File physheap_config.h -@Title Physical heap Config API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Physical heap configs are created in the system layer and - stored against each device node for use in the Services Server - common layer. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PHYSHEAP_CONFIG_H -#define PHYSHEAP_CONFIG_H - -#include "img_types.h" -#include "pvrsrv_memallocflags.h" -#include "pvrsrv_memalloc_physheap.h" - -typedef IMG_UINT32 PHYS_HEAP_USAGE_FLAGS; - -#define PHYS_HEAP_USAGE_GPU_LOCAL (1< - -module_param(gPMRAllocFail, uint, 0644); -MODULE_PARM_DESC(gPMRAllocFail, "When number of PMR allocs reaches " - "this value, it will fail (default value is 0 which " - "means that alloc function will behave normally)."); -#endif /* defined(__linux__) */ -#endif /* defined(DEBUG) */ - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#include "proc_stats.h" -#endif - -PVRSRV_ERROR DevPhysMemAlloc(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32MemSize, - IMG_UINT32 ui32Log2Align, - const IMG_UINT8 u8Value, - IMG_BOOL bInitPage, -#if defined(PDUMP) - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicAddress, - IMG_HANDLE *phHandlePtr, -#endif - IMG_HANDLE hMemHandle, - IMG_DEV_PHYADDR *psDevPhysAddr) -{ - void *pvCpuVAddr; - PVRSRV_ERROR eError; -#if defined(PDUMP) - IMG_CHAR szFilenameOut[PDUMP_PARAM_MAX_FILE_NAME]; - PDUMP_FILEOFFSET_T uiOffsetOut; - IMG_UINT32 ui32PageSize; - IMG_UINT32 ui32PDumpMemSize = ui32MemSize; - PVRSRV_ERROR ePDumpError; -#endif - PG_HANDLE *psMemHandle; - IMG_UINT64 uiMask; - IMG_DEV_PHYADDR sDevPhysAddr_int; - IMG_PID uiPid = 0; - - psMemHandle = hMemHandle; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - uiPid = psDevNode->eDevState == PVRSRV_DEVICE_STATE_INIT ? - PVR_SYS_ALLOC_PID : OSGetCurrentClientProcessIDKM(); -#endif - - /* Allocate the pages */ - eError = PhysHeapPagesAlloc(psDevNode->psMMUPhysHeap, - TRUNCATE_64BITS_TO_SIZE_T(ui32MemSize), - psMemHandle, - &sDevPhysAddr_int, - uiPid); - PVR_LOG_RETURN_IF_ERROR(eError, "pfnDevPxAlloc:1"); - - /* Check to see if the page allocator returned pages with our desired - * alignment, which is not unlikely - */ - uiMask = (1 << ui32Log2Align) - 1; - if (ui32Log2Align && (sDevPhysAddr_int.uiAddr & uiMask)) - { - /* use over allocation instead */ - PhysHeapPagesFree(psDevNode->psMMUPhysHeap, psMemHandle); - - ui32MemSize += (IMG_UINT32) uiMask; - eError = PhysHeapPagesAlloc(psDevNode->psMMUPhysHeap, - TRUNCATE_64BITS_TO_SIZE_T(ui32MemSize), - psMemHandle, - &sDevPhysAddr_int, - uiPid); - PVR_LOG_RETURN_IF_ERROR(eError, "pfnDevPxAlloc:2"); - - sDevPhysAddr_int.uiAddr += uiMask; - sDevPhysAddr_int.uiAddr &= ~uiMask; - } - *psDevPhysAddr = sDevPhysAddr_int; - -#if defined(PDUMP) - ui32PageSize = ui32Log2Align? (1 << ui32Log2Align) : OSGetPageSize(); - eError = PDumpMalloc(psDevNode, - pszDevSpace, - pszSymbolicAddress, - ui32PDumpMemSize, - ui32PageSize, - IMG_FALSE, - 0, - phHandlePtr, - PDUMP_NONE); - if (PVRSRV_OK != eError) - { - PDUMPCOMMENT(psDevNode, "Allocating pages failed"); - *phHandlePtr = NULL; - } - ePDumpError = eError; -#endif - - if (bInitPage) - { - /*Map the page to the CPU VA space */ - eError = PhysHeapPagesMap(psDevNode->psMMUPhysHeap, - psMemHandle, - ui32MemSize, - &sDevPhysAddr_int, - &pvCpuVAddr); - if (PVRSRV_OK != eError) - { - PVR_LOG_ERROR(eError, "DevPxMap"); - PhysHeapPagesFree(psDevNode->psMMUPhysHeap, psMemHandle); - return eError; - } - - /*Fill the memory with given content */ - OSDeviceMemSet(pvCpuVAddr, u8Value, ui32MemSize); - - /*Map the page to the CPU VA space */ - eError = PhysHeapPagesClean(psDevNode->psMMUPhysHeap, - psMemHandle, - 0, - ui32MemSize); - if (PVRSRV_OK != eError) - { - PVR_LOG_ERROR(eError, "DevPxClean"); - PhysHeapPagesUnMap(psDevNode->psMMUPhysHeap, psMemHandle, pvCpuVAddr); - PhysHeapPagesFree(psDevNode->psMMUPhysHeap, psMemHandle); - return eError; - } - -#if defined(PDUMP) - if (ePDumpError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) - { - /* PDumping of the page contents can be done in two ways - * 1. Store the single byte init value to the .prm file - * and load the same value to the entire dummy page buffer - * This method requires lot of LDB's inserted into the out2.txt - * - * 2. Store the entire contents of the buffer to the .prm file - * and load them back. - * This only needs a single LDB instruction in the .prm file - * and chosen this method - * size of .prm file might go up but that's not huge at least - * for this allocation - */ - /* Write the buffer contents to the prm file */ - eError = PDumpWriteParameterBlob(psDevNode, - pvCpuVAddr, - ui32PDumpMemSize, - PDUMP_FLAGS_CONTINUOUS, - szFilenameOut, - sizeof(szFilenameOut), - &uiOffsetOut); - if (PVRSRV_OK == eError) - { - /* Load the buffer back to the allocated memory when playing the pdump */ - eError = PDumpPMRLDB(psDevNode, - pszDevSpace, - pszSymbolicAddress, - 0, - ui32PDumpMemSize, - szFilenameOut, - uiOffsetOut, - PDUMP_FLAGS_CONTINUOUS); - if (PVRSRV_OK != eError) - { - PDUMP_ERROR(psDevNode, eError, "Failed to write LDB statement to script file"); - PVR_LOG_ERROR(eError, "PDumpPMRLDB"); - } - } - else if (eError != PVRSRV_ERROR_PDUMP_NOT_ALLOWED) - { - PDUMP_ERROR(psDevNode, eError, "Failed to write device allocation to parameter file"); - PVR_LOG_ERROR(eError, "PDumpWriteParameterBlob"); - } - else - { - /* Else write to parameter file prevented under the flags and - * current state of the driver so skip write to script and error IF. - * This is expected e.g., if not in the capture range. - */ - eError = PVRSRV_OK; - } - } -#endif - - /* Unmap the page */ - PhysHeapPagesUnMap(psDevNode->psMMUPhysHeap, - psMemHandle, - pvCpuVAddr); - } - - return PVRSRV_OK; -} - -void DevPhysMemFree(PVRSRV_DEVICE_NODE *psDevNode, -#if defined(PDUMP) - IMG_HANDLE hPDUMPMemHandle, -#endif - IMG_HANDLE hMemHandle) -{ - PG_HANDLE *psMemHandle; - - psMemHandle = hMemHandle; - PhysHeapPagesFree(psDevNode->psMMUPhysHeap, psMemHandle); -#if defined(PDUMP) - if (NULL != hPDUMPMemHandle) - { - PDumpFree(psDevNode, hPDUMPMemHandle); - } -#endif - -} - - -/* Checks the input parameters and adjusts them if possible and necessary */ -PVRSRV_ERROR PhysMemValidateParams(IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 *puiLog2AllocPageSize, - IMG_DEVMEM_SIZE_T *puiSize, - PMR_SIZE_T *puiChunkSize) -{ - IMG_UINT32 uiLog2AllocPageSize = *puiLog2AllocPageSize; - IMG_DEVMEM_SIZE_T uiSize = *puiSize; - PMR_SIZE_T uiChunkSize = *puiChunkSize; - /* Sparse if we have different number of virtual and physical chunks plus - * in general all allocations with more than one virtual chunk */ - IMG_BOOL bIsSparse = (ui32NumVirtChunks != ui32NumPhysChunks || - ui32NumVirtChunks > 1) ? IMG_TRUE : IMG_FALSE; - - if (ui32NumVirtChunks == 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Number of virtual chunks cannot be 0", - __func__)); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Protect against invalid page sizes */ - switch (uiLog2AllocPageSize) - { - #define X(_name, _shift) case _shift: - RGX_HEAP_PAGE_SHIFTS_DEF - #undef X - break; - default: - PVR_LOG_VA(PVR_DBG_ERROR, - "page size of %" IMG_UINT64_FMTSPEC " is invalid.", - IMG_UINT64_C(1) << uiLog2AllocPageSize); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Range check of the alloc size */ - if (!PMRValidateSize(uiSize)) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "PMR size exceeds limit #Chunks: %u ChunkSz %"IMG_UINT64_FMTSPECX"", - ui32NumVirtChunks, - (IMG_UINT64)IMG_UINT64_C(1) << uiLog2AllocPageSize); - return PVRSRV_ERROR_PMR_TOO_LARGE; - } - - /* Fail if requesting coherency on one side but uncached on the other */ - if (PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) && - (PVRSRV_CHECK_GPU_UNCACHED(uiFlags) || PVRSRV_CHECK_GPU_WRITE_COMBINE(uiFlags))) - { - PVR_DPF((PVR_DBG_ERROR, "Request for CPU coherency but specifying GPU uncached " - "Please use GPU cached flags for coherency.")); - return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE; - } - - if (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) && - (PVRSRV_CHECK_CPU_UNCACHED(uiFlags) || PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags))) - { - PVR_DPF((PVR_DBG_ERROR, "Request for GPU coherency but specifying CPU uncached " - "Please use CPU cached flags for coherency.")); - return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE; - } - - if (PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags) && PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Zero on Alloc and Poison on Alloc are mutually exclusive.", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (bIsSparse) - { - /* For sparse we need correct parameters like a suitable page size.... */ - if (OSGetPageShift() > uiLog2AllocPageSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid log2-contiguity for sparse allocation. " - "Requested %u, required minimum %zd", - __func__, - uiLog2AllocPageSize, - OSGetPageShift() )); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* ... chunk size must be a equal to page size ... */ - if (uiChunkSize != (1 << uiLog2AllocPageSize)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid chunk size for sparse allocation. Requested " - "%#" IMG_UINT64_FMTSPECx ", must be same as page size %#x.", - __func__, uiChunkSize, 1 << uiLog2AllocPageSize)); - - return PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE; - } - - if (ui32NumVirtChunks * uiChunkSize != uiSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Total alloc size (%#" IMG_UINT64_FMTSPECx ") " - "is not equal to virtual chunks * chunk size " - "(%#" IMG_UINT64_FMTSPECx ")", - __func__, - uiSize, - (IMG_UINT64)ui32NumVirtChunks << uiLog2AllocPageSize)); - - return PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE; - } - - if (ui32NumPhysChunks > ui32NumVirtChunks) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Number of physical chunks (%u) must not be greater " - "than number of virtual chunks (%u)", - __func__, - ui32NumPhysChunks, - ui32NumVirtChunks)); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - else - { - /* - * Silently round up alignment/pagesize if request was less that PAGE_SHIFT - * because it would never be harmful for memory to be _more_ contiguous that - * was desired. - */ - uiLog2AllocPageSize = OSGetPageShift() > uiLog2AllocPageSize ? - OSGetPageShift() : uiLog2AllocPageSize; - - /* Same for total size */ - uiSize = PVR_ALIGN(uiSize, (IMG_DEVMEM_SIZE_T)OSGetPageSize()); - *puiChunkSize = uiSize; - } - - if ((uiSize & ((1ULL << uiLog2AllocPageSize) - 1)) != 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Total size (%#" IMG_UINT64_FMTSPECx ") " - "must be a multiple of the requested contiguity (%" - IMG_UINT64_FMTSPEC ")", __func__, uiSize, - (IMG_UINT64) (1ULL << uiLog2AllocPageSize))); - return PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE; - } - - *puiLog2AllocPageSize = uiLog2AllocPageSize; - *puiSize = uiSize; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _DevPhysHeapFromFlags(PVRSRV_MEMALLOCFLAGS_T uiFlags, - PVRSRV_PHYS_HEAP *peDevPhysHeap) -{ - PVRSRV_PHYS_HEAP eHeap = PVRSRV_GET_PHYS_HEAP_HINT(uiFlags); - - switch (eHeap) - { - case PVRSRV_PHYS_HEAP_FW_PREMAP0: - case PVRSRV_PHYS_HEAP_FW_PREMAP1: - case PVRSRV_PHYS_HEAP_FW_PREMAP2: - case PVRSRV_PHYS_HEAP_FW_PREMAP3: - case PVRSRV_PHYS_HEAP_FW_PREMAP4: - case PVRSRV_PHYS_HEAP_FW_PREMAP5: - case PVRSRV_PHYS_HEAP_FW_PREMAP6: - case PVRSRV_PHYS_HEAP_FW_PREMAP7: - { - /* keep heap (with check) */ - PVR_RETURN_IF_INVALID_PARAM(PVRSRV_VZ_MODE_IS(HOST)); - break; - } - case PVRSRV_PHYS_HEAP_LAST: - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - default: - { - break; - } - } - - *peDevPhysHeap = eHeap; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PhysmemNewRamBackedPMR_direct(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2AllocPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags) -{ - PVRSRV_ERROR eError; - PVRSRV_PHYS_HEAP ePhysHeapIdx; - PVRSRV_MEMALLOCFLAGS_T uiPMRFlags = uiFlags; - PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE pfnCheckMemAllocSize = - psDevNode->psDevConfig->pfnCheckMemAllocSize; - - PVR_UNREFERENCED_PARAMETER(uiAnnotationLength); - - eError = PhysMemValidateParams(ui32NumPhysChunks, - ui32NumVirtChunks, - uiFlags, - &uiLog2AllocPageSize, - &uiSize, - &uiChunkSize); - PVR_RETURN_IF_ERROR(eError); - - eError = _DevPhysHeapFromFlags(uiFlags, &ePhysHeapIdx); - PVR_RETURN_IF_ERROR(eError); - - if (ePhysHeapIdx == PVRSRV_PHYS_HEAP_DEFAULT) - { - ePhysHeapIdx = psDevNode->psDevConfig->eDefaultHeap; - PVRSRV_CHANGE_PHYS_HEAP_HINT(ePhysHeapIdx, uiPMRFlags); - } - - if (ePhysHeapIdx == PVRSRV_PHYS_HEAP_GPU_LOCAL) - { - if ((uiFlags & PVRSRV_MEMALLOCFLAGS_CPU_MAPPABLE_MASK) == 0) - { - ePhysHeapIdx = PVRSRV_PHYS_HEAP_GPU_PRIVATE; - PVRSRV_SET_PHYS_HEAP_HINT(GPU_PRIVATE, uiPMRFlags); - PVR_DPF((PVR_DBG_VERBOSE, "%s: Consider explicit use of GPU_PRIVATE for PMR %s." - " Implicit conversion to GPU PRIVATE performed", - __func__, pszAnnotation)); - } - else if (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) && - PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig)) - { - ePhysHeapIdx = PVRSRV_PHYS_HEAP_GPU_COHERENT; - PVRSRV_SET_PHYS_HEAP_HINT(GPU_COHERENT, uiPMRFlags); - } - } - else if (ePhysHeapIdx == PVRSRV_PHYS_HEAP_GPU_PRIVATE) - { - if (uiFlags & PVRSRV_MEMALLOCFLAGS_CPU_MAPPABLE_MASK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid flags for PMR %s!" - " Client requested GPU_PRIVATE physical heap with CPU access flags.", - __func__, pszAnnotation)); - return PVRSRV_ERROR_INVALID_HEAP; - } - } - - if (NULL == psDevNode->apsPhysHeap[ePhysHeapIdx]) - { - /* In case a heap hasn't been acquired for this type, return invalid heap error */ - PVR_DPF((PVR_DBG_ERROR, "%s: Requested allocation on device node (%p) from " - "an invalid heap (HeapIndex=%d)", - __func__, psDevNode, ePhysHeapIdx)); - return PVRSRV_ERROR_INVALID_HEAP; - } - - /* Apply memory budgeting policy */ - if (pfnCheckMemAllocSize) - { - IMG_UINT64 uiMemSize = (IMG_UINT64)uiChunkSize * ui32NumPhysChunks; - - eError = pfnCheckMemAllocSize(psDevNode->psDevConfig->hSysData, uiMemSize); - PVR_RETURN_IF_ERROR(eError); - } - -#if defined(DEBUG) - if (gPMRAllocFail > 0) - { - static IMG_UINT32 ui32AllocCount = 1; - - if (ui32AllocCount < gPMRAllocFail) - { - ui32AllocCount++; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s failed on %d allocation.", - __func__, ui32AllocCount)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } -#endif /* defined(DEBUG) */ - - /* If the driver is in an 'init' state all of the allocated memory - * should be attributed to the driver (PID 1) rather than to the - * process those allocations are made under. Same applies to the memory - * allocated for the Firmware. */ - if (psDevNode->eDevState == PVRSRV_DEVICE_STATE_INIT || - PVRSRV_CHECK_FW_MAIN(uiFlags)) - { - uiPid = PVR_SYS_ALLOC_PID; - } - - eError = PhysHeapCreatePMR(psDevNode->apsPhysHeap[ePhysHeapIdx], - psConnection, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2AllocPageSize, - uiFlags, - pszAnnotation, - uiPid, - ppsPMRPtr, - ui32PDumpFlags); - - if (puiPMRFlags != NULL) - { - *puiPMRFlags = uiPMRFlags; - } - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - if (eError != PVRSRV_OK) - { - PVRSRVStatsUpdateOOMStats(PVRSRV_PROCESS_STAT_TYPE_OOM_PHYSMEM_COUNT, - OSGetCurrentClientProcessIDKM()); - } -#endif - - return eError; -} - -PVRSRV_ERROR -PhysmemNewRamBackedPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2AllocPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags) -{ - PVRSRV_PHYS_HEAP ePhysHeap = PVRSRV_GET_PHYS_HEAP_HINT(uiFlags); - - PVR_LOG_RETURN_IF_INVALID_PARAM(ePhysHeap < PVRSRV_PHYS_HEAP_LAST, "uiFlags"); - PVR_LOG_RETURN_IF_INVALID_PARAM(uiAnnotationLength != 0, "uiAnnotationLength"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pszAnnotation != NULL, "pszAnnotation"); - - if (ePhysHeap == PVRSRV_PHYS_HEAP_DEFAULT) - { - ePhysHeap = psDevNode->psDevConfig->eDefaultHeap; - } - - if (!PhysHeapUserModeAlloc(ePhysHeap)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid phys heap hint: %d.", __func__, ePhysHeap)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PhysmemNewRamBackedPMR_direct(psConnection, - psDevNode, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2AllocPageSize, - uiFlags, - uiAnnotationLength, - pszAnnotation, - uiPid, - ppsPMRPtr, - ui32PDumpFlags, - puiPMRFlags); -} - -PVRSRV_ERROR -PhysmemNewRamBackedLockedPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags) -{ - - PVRSRV_ERROR eError; - eError = PhysmemNewRamBackedPMR(psConnection, - psDevNode, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2PageSize, - uiFlags, - uiAnnotationLength, - pszAnnotation, - uiPid, - ppsPMRPtr, - ui32PDumpFlags, - puiPMRFlags); - - if (eError == PVRSRV_OK) - { - eError = PMRLockSysPhysAddresses(*ppsPMRPtr); - } - - return eError; -} - -PVRSRV_ERROR -PVRSRVGetMaxPhysHeapCountKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 *pui32PhysHeapCount) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVRSRVGetDevicePhysHeapCount(psDevNode, pui32PhysHeapCount); - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVGetDefaultPhysicalHeapKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_PHYS_HEAP *peHeap) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - *peHeap = psDevNode->psDevConfig->eDefaultHeap; - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVGetHeapPhysMemUsageKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS *apPhysHeapMemStats) -{ - PHYS_HEAP *psPhysHeap; - IMG_UINT uiHeapIndex, i = 0; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui32PhysHeapCount != psDevNode->ui32UserAllocHeapCount) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - for (uiHeapIndex = PVRSRV_PHYS_HEAP_DEFAULT+1; (uiHeapIndex < PVRSRV_PHYS_HEAP_LAST); uiHeapIndex++) - { - psPhysHeap = psDevNode->apsPhysHeap[uiHeapIndex]; - - if (psPhysHeap && PhysHeapUserModeAlloc(uiHeapIndex)) - { - PVR_ASSERT(i < ui32PhysHeapCount); - - PhysheapGetPhysMemUsage(psPhysHeap, &apPhysHeapMemStats[i].ui64TotalSize, - &apPhysHeapMemStats[i].ui64FreeSize); - - i++; - } - } - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVGetHeapPhysMemUsagePkdKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS_PKD *apPhysHeapMemStats) -{ - PHYS_HEAP *psPhysHeap; - IMG_UINT uiHeapIndex, i = 0; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui32PhysHeapCount != psDevNode->ui32UserAllocHeapCount) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - for (uiHeapIndex = PVRSRV_PHYS_HEAP_DEFAULT+1; (uiHeapIndex < PVRSRV_PHYS_HEAP_LAST); uiHeapIndex++) - { - psPhysHeap = psDevNode->apsPhysHeap[uiHeapIndex]; - - if (psPhysHeap && PhysHeapUserModeAlloc(uiHeapIndex)) - { - PVR_ASSERT(i < ui32PhysHeapCount); - - PhysheapGetPhysMemUsage(psPhysHeap, &apPhysHeapMemStats[i].ui64TotalSize, - &apPhysHeapMemStats[i].ui64FreeSize); - - i++; - } - } - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVPhysHeapGetMemInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS *paPhysHeapMemStats) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - return PhysHeapGetMemInfo(psDevNode, - ui32PhysHeapCount, - paePhysHeapID, - paPhysHeapMemStats); -} - -PVRSRV_ERROR -PVRSRVPhysHeapGetMemInfoPkdKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PKD *paPhysHeapMemStats) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - return PhysHeapGetMemInfoPkd(psDevNode, - ui32PhysHeapCount, - paePhysHeapID, - paPhysHeapMemStats); -} - -/* 'Wrapper' function to call PMRImportPMR(), which first checks the PMR is - * for the current device. This avoids the need to do this in pmr.c, which - * would then need PVRSRV_DEVICE_NODE (defining this type in pmr.h causes a - * typedef redefinition issue). - */ -PVRSRV_ERROR -PhysmemImportPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PMR_EXPORT *psPMRExport, - PMR_PASSWORD_T uiPassword, - PMR_SIZE_T uiSize, - PMR_LOG2ALIGN_T uiLog2Contig, - PMR **ppsPMR) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (PMRGetExportDeviceNode(psPMRExport) != psDevNode) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR invalid for this device", __func__)); - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - return PMRImportPMR(psPMRExport, - uiPassword, - uiSize, - uiLog2Contig, - ppsPMR); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem.h b/drivers/gpu/drm/img-rogue/1.17/physmem.h deleted file mode 100644 index 6f7325fc53b2c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem.h +++ /dev/null @@ -1,343 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Physmem header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for common entry point for creation of RAM backed PMR's -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PHYSMEM_H -#define SRVSRV_PHYSMEM_H - -/* include/ */ -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "connection_server.h" - -/* services/server/include/ */ -#include "pmr.h" -#include "pmr_impl.h" - -/* Valid values for TC_MEMORY_CONFIG configuration option */ -#define TC_MEMORY_LOCAL (1) -#define TC_MEMORY_HOST (2) -#define TC_MEMORY_HYBRID (3) - -/* Valid values for the PLATO_MEMORY_CONFIG configuration option */ -#define PLATO_MEMORY_LOCAL (1) -#define PLATO_MEMORY_HOST (2) -#define PLATO_MEMORY_HYBRID (3) - -/*************************************************************************/ /*! -@Function DevPhysMemAlloc -@Description Allocate memory from device specific heaps directly. -@Input psDevNode device node to operate on -@Input ui32MemSize Size of the memory to be allocated -@Input u8Value Value to be initialised to. -@Input bInitPage Flag to control initialisation -@Input pszDevSpace PDUMP memory space in which the - allocation is to be done -@Input pszSymbolicAddress Symbolic name of the allocation -@Input phHandlePtr PDUMP handle to the allocation -@Output hMemHandle Handle to the allocated memory -@Output psDevPhysAddr Device Physical address of allocated - page -@Return PVRSRV_OK if the allocation is successful -*/ /**************************************************************************/ -PVRSRV_ERROR -DevPhysMemAlloc(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32MemSize, - IMG_UINT32 ui32Log2Align, - const IMG_UINT8 u8Value, - IMG_BOOL bInitPage, -#if defined(PDUMP) - const IMG_CHAR *pszDevSpace, - const IMG_CHAR *pszSymbolicAddress, - IMG_HANDLE *phHandlePtr, -#endif - IMG_HANDLE hMemHandle, - IMG_DEV_PHYADDR *psDevPhysAddr); - -/*************************************************************************/ /*! -@Function DevPhysMemFree -@Description Free memory to device specific heaps directly. -@Input psDevNode device node to operate on -@Input hPDUMPMemHandle Pdump handle to allocated memory -@Input hMemHandle Devmem handle to allocated memory -@Return None -*/ /**************************************************************************/ -void -DevPhysMemFree(PVRSRV_DEVICE_NODE *psDevNode, -#if defined(PDUMP) - IMG_HANDLE hPDUMPMemHandle, -#endif - IMG_HANDLE hMemHandle); - -/* - * PhysmemNewRamBackedPMR - * - * This function will create a RAM backed PMR using the device specific - * callback, this allows control at a per-devicenode level to select the - * memory source thus supporting mixed UMA/LMA systems. - * - * The size must be a multiple of page size. The page size is specified in - * log2. It should be regarded as a minimum contiguity of which the - * resulting memory must be a multiple. It may be that this should be a fixed - * number. It may be that the allocation size needs to be a multiple of some - * coarser "page size" than that specified in the page size argument. - * For example, take an OS whose page granularity is a fixed 16kB, but the - * caller requests memory in page sizes of 4kB. The request can be satisfied - * if and only if the SIZE requested is a multiple of 16kB. If the arguments - * supplied are such that this OS cannot grant the request, - * PVRSRV_ERROR_INVALID_PARAMS will be returned. - * - * The caller should supply storage of a pointer. Upon successful return a - * PMR object will have been created and a pointer to it returned in the - * PMROut argument. - * - * A PMR successfully created should be destroyed with PhysmemUnrefPMR. - * - * Note that this function may cause memory allocations and on some operating - * systems this may cause scheduling events, so it is important that this - * function be called with interrupts enabled and in a context where - * scheduling events and memory allocations are permitted. - * - * The flags may be used by the implementation to change its behaviour if - * required. The flags will also be stored in the PMR as immutable metadata - * and returned to mmu_common when it asks for it. - * - * The PID specified is used to tie this allocation to the process context - * that the allocation is made on behalf of. - */ -PVRSRV_ERROR -PhysmemNewRamBackedPMR(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMROut, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags); - -PVRSRV_ERROR -PhysmemNewRamBackedPMR_direct(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMROut, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags); - -/* - * PhysmemNewRamBackedLockedPMR - * - * Same as function above but is additionally locking down the PMR. - * - * Get the physical memory and lock down the PMR directly, we do not want to - * defer the actual allocation to mapping time. - * - * In general the concept of on-demand allocations is not useful for - * allocations where we give the users the freedom to map and unmap memory at - * will. The user is not expecting their memory contents to suddenly vanish - * just because they unmapped the buffer. - * Even if they would know and be ok with it, we do not want to check for - * every page we unmap whether we have to unlock the underlying PMR. -*/ -PVRSRV_ERROR -PhysmemNewRamBackedLockedPMR(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 uiAnnotationLength, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags, - PVRSRV_MEMALLOCFLAGS_T *puiPMRFlags); - -/*************************************************************************/ /*! -@Function PhysmemImportPMR -@Description Import PMR a previously exported PMR -@Input psPMRExport The exported PMR token -@Input uiPassword Authorisation password - for the PMR being imported -@Input uiSize Size of the PMR being imported - (for verification) -@Input uiLog2Contig Log2 continuity of the PMR being - imported (for verification) -@Output ppsPMR The imported PMR -@Return PVRSRV_ERROR_PMR_NOT_PERMITTED if not for the same device - PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR if password incorrect - PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES if size or contiguity incorrect - PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysmemImportPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PMR_EXPORT *psPMRExport, - PMR_PASSWORD_T uiPassword, - PMR_SIZE_T uiSize, - PMR_LOG2ALIGN_T uiLog2Contig, - PMR **ppsPMR); - -/*************************************************************************/ /*! -@Function PVRSRVGetMaxPhysHeapCountKM -@Description Get the user accessible physical heap count -@Output puiPhysHeapCount user accessible physical heap count -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVGetMaxPhysHeapCountKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 *puiPhysHeapCount); - -/*************************************************************************/ /*! -@Function PVRSRVGetDefaultPhysicalHeapKM -@Description For the specified device, get the physical heap used for - allocations when the PVRSRV_PHYS_HEAP_DEFAULT - physical heap hint is set in memalloc flags. -@Output peHeap Default Heap return value -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVGetDefaultPhysicalHeapKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_PHYS_HEAP *peHeap); - -/*************************************************************************/ /*! -@Function PVRSRVGetHeapPhysMemUsageKM -@Description Get the memory usage statistics for all user accessible - physical heaps -@Input ui32PhysHeapCount Total user accessible physical heaps -@Output apPhysHeapMemStats Buffer to hold the memory statistics -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVGetHeapPhysMemUsageKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS *apPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PVRSRVGetHeapPhysMemUsagePkdKM -@Description Get the memory usage statistics for all user accessible - physical heaps -@Input ui32PhysHeapCount Total user accessible physical heaps -@Output apPhysHeapMemStats Buffer to hold the memory statistics -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVGetHeapPhysMemUsagePkdKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PHYS_HEAP_MEM_STATS_PKD *apPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PVRSRVPhysHeapGetMemInfoKM -@Description Get the memory usage statistics for a given physical heap ID -@Input ui32PhysHeapCount Physical Heap count -@Input paePhysHeapID Array of Physical Heap ID's -@Output paPhysHeapMemStats Buffer to hold the memory statistics -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVPhysHeapGetMemInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS *paPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PVRSRVPhysHeapGetMemInfoPkdKM -@Description Get the memory usage statistics for a given physical heap ID -@Input ui32PhysHeapCount Physical Heap count -@Input paePhysHeapID Array of Physical Heap ID's -@Output paPhysHeapMemStats Buffer to hold the memory statistics -@Return PVRSRV_OK if successful -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVPhysHeapGetMemInfoPkdKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32PhysHeapCount, - PVRSRV_PHYS_HEAP *paePhysHeapID, - PHYS_HEAP_MEM_STATS_PKD *paPhysHeapMemStats); - -/*************************************************************************/ /*! -@Function PhysMemValidateParams -@Description Checks the PMR creation parameters and adjusts them - if possible and necessary -@Input ui32NumPhysChunks Number of physical chunks. -@Input ui32NumVirtChunks Number of virtual chunks. -@Input uiFlags Allocation flags. -@Inout puiLog2AllocPageSize Log2 of allocation page size. - May be adjusted. -@Inout puiSize Size of the allocation. - May be adjusted. -@Inout puiChunkSize Size of a backed or unbacked chunk -@Return PVRSRV_OK if parameters are valid. -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysMemValidateParams(IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 *puiLog2AllocPageSize, - IMG_DEVMEM_SIZE_T *puiSize, - PMR_SIZE_T *puiChunkSize); - -#endif /* SRVSRV_PHYSMEM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.c b/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.c deleted file mode 100644 index 545ddd56c6421..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.c +++ /dev/null @@ -1,1309 +0,0 @@ -/*************************************************************************/ /*! -@File physmem_dmabuf.c -@Title dmabuf memory allocator -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - implementing the function callbacks for dmabuf memory. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "physmem_dmabuf.h" -#include "physmem.h" -#include "pvrsrv.h" -#include "pmr.h" - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) || defined(SUPPORT_ION) || defined(KERNEL_HAS_DMABUF_VMAP_MMAP) - -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -#include -#endif -#include - -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" - -#include "allocmem.h" -#include "osfunc.h" -#include "pmr_impl.h" -#include "hash.h" -#include "private_data.h" -#include "module_common.h" -#include "pvr_ion_stats.h" - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "ri_server.h" -#endif - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) -#include "mmap_stats.h" -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif - -#include "kernel_compatibility.h" - -/* - * dma_buf_ops - * - * These are all returning errors if used. - * The point is to prevent anyone outside of our driver from importing - * and using our dmabuf. - */ - -static int PVRDmaBufOpsAttach(struct dma_buf *psDmaBuf, -#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) && \ - !((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && (defined(CHROMIUMOS_KERNEL)))) - struct device *psDev, -#endif - struct dma_buf_attachment *psAttachment) -{ - return -ENOSYS; -} - -static struct sg_table *PVRDmaBufOpsMap(struct dma_buf_attachment *psAttachment, - enum dma_data_direction eDirection) -{ - /* Attach hasn't been called yet */ - return ERR_PTR(-EINVAL); -} - -static void PVRDmaBufOpsUnmap(struct dma_buf_attachment *psAttachment, - struct sg_table *psTable, - enum dma_data_direction eDirection) -{ -} - -static void PVRDmaBufOpsRelease(struct dma_buf *psDmaBuf) -{ - PMR *psPMR = (PMR *) psDmaBuf->priv; - - PMRUnrefPMR(psPMR); -} - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) -static void *PVRDmaBufOpsKMap(struct dma_buf *psDmaBuf, unsigned long uiPageNum) -{ - return ERR_PTR(-ENOSYS); -} -#endif - -static int PVRDmaBufOpsMMap(struct dma_buf *psDmaBuf, struct vm_area_struct *psVMA) -{ - return -ENOSYS; -} - -static const struct dma_buf_ops sPVRDmaBufOps = -{ - .attach = PVRDmaBufOpsAttach, - .map_dma_buf = PVRDmaBufOpsMap, - .unmap_dma_buf = PVRDmaBufOpsUnmap, - .release = PVRDmaBufOpsRelease, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) -#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) && \ - !((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && (defined(CHROMIUMOS_KERNEL)))) - .map_atomic = PVRDmaBufOpsKMap, -#endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) - .map = PVRDmaBufOpsKMap, -#endif -#else - .kmap_atomic = PVRDmaBufOpsKMap, - .kmap = PVRDmaBufOpsKMap, -#endif - .mmap = PVRDmaBufOpsMMap, -}; - -/* end of dma_buf_ops */ - - -typedef struct _PMR_DMA_BUF_DATA_ -{ - /* Filled in at PMR create time */ - PHYS_HEAP *psPhysHeap; - struct dma_buf_attachment *psAttachment; - PFN_DESTROY_DMABUF_PMR pfnDestroy; - IMG_BOOL bPoisonOnFree; - - /* Mapping information. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - struct iosys_map sMap; -#else - struct dma_buf_map sMap; -#endif - - /* Modified by PMR lock/unlock */ - struct sg_table *psSgTable; - IMG_DEV_PHYADDR *pasDevPhysAddr; - IMG_UINT32 ui32PhysPageCount; - IMG_UINT32 ui32VirtPageCount; -} PMR_DMA_BUF_DATA; - -/* Start size of the g_psDmaBufHash hash table */ -#define DMA_BUF_HASH_SIZE 20 - -static DEFINE_MUTEX(g_HashLock); - -static HASH_TABLE *g_psDmaBufHash; -static IMG_UINT32 g_ui32HashRefCount; - -#if defined(PVR_ANDROID_ION_USE_SG_LENGTH) -#define pvr_sg_length(sg) ((sg)->length) -#else -#define pvr_sg_length(sg) sg_dma_len(sg) -#endif - -static int -DmaBufSetValue(struct dma_buf *psDmaBuf, int iValue, const char *szFunc) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - struct iosys_map sMap; -#else - struct dma_buf_map sMap; -#endif - int err, err_end_access; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) - int i; -#endif - - err = dma_buf_begin_cpu_access(psDmaBuf, DMA_FROM_DEVICE); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to begin cpu access (err=%d)", - szFunc, err)); - goto err_out; - } - - err = dma_buf_vmap(psDmaBuf, &sMap); - if (err) - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map page (err=%d)", - szFunc, err)); - goto exit_end_access; -#else - for (i = 0; i < psDmaBuf->size / PAGE_SIZE; i++) - { - void *pvKernAddr; - - pvKernAddr = dma_buf_kmap(psDmaBuf, i); - if (IS_ERR_OR_NULL(pvKernAddr)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map page (err=%ld)", - szFunc, - pvKernAddr ? PTR_ERR(pvKernAddr) : -ENOMEM)); - err = !pvKernAddr ? -ENOMEM : -EINVAL; - - goto exit_end_access; - } - - memset(pvKernAddr, iValue, PAGE_SIZE); - - dma_buf_kunmap(psDmaBuf, i, pvKernAddr); - } -#endif - } - else - { - memset(sMap.vaddr, iValue, psDmaBuf->size); - - dma_buf_vunmap(psDmaBuf, &sMap); - } - - err = 0; - -exit_end_access: - do { - err_end_access = dma_buf_end_cpu_access(psDmaBuf, DMA_TO_DEVICE); - } while (err_end_access == -EAGAIN || err_end_access == -EINTR); - - if (err_end_access) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to end cpu access (err=%d)", - szFunc, err_end_access)); - if (!err) - { - err = err_end_access; - } - } - -err_out: - return err; -} - -/***************************************************************************** - * PMR callback functions * - *****************************************************************************/ - -static PVRSRV_ERROR PMRFinalizeDmaBuf(PMR_IMPL_PRIVDATA pvPriv) -{ - PMR_DMA_BUF_DATA *psPrivData = pvPriv; - struct dma_buf_attachment *psAttachment = psPrivData->psAttachment; - struct dma_buf *psDmaBuf = psAttachment->dmabuf; - struct sg_table *psSgTable = psPrivData->psSgTable; - PMR *psPMR; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psDmaBuf->ops != &sPVRDmaBufOps) - { - if (g_psDmaBufHash) - { - /* We have a hash table so check if we've seen this dmabuf before */ - psPMR = (PMR *) HASH_Retrieve(g_psDmaBufHash, (uintptr_t) psDmaBuf); - - if (psPMR) - { - if (!PMRIsPMRLive(psPMR)) - { - HASH_Remove(g_psDmaBufHash, (uintptr_t) psDmaBuf); - g_ui32HashRefCount--; - - if (g_ui32HashRefCount == 0) - { - HASH_Delete(g_psDmaBufHash); - g_psDmaBufHash = NULL; - } - } - else{ - eError = PVRSRV_ERROR_PMR_STILL_REFERENCED; - } - } - PVRSRVIonRemoveMemAllocRecord(psDmaBuf); - } - }else - { - psPMR = (PMR *) psDmaBuf->priv; - if (PMRIsPMRLive(psPMR)) - { - eError = PVRSRV_ERROR_PMR_STILL_REFERENCED; - } - - } - - if (PVRSRV_OK != eError) - { - return eError; - } - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT, - psPrivData->ui32PhysPageCount << PAGE_SHIFT, - OSGetCurrentClientProcessIDKM()); -#endif - - psPrivData->ui32PhysPageCount = 0; - - dma_buf_unmap_attachment(psAttachment, psSgTable, DMA_BIDIRECTIONAL); - - - if (psPrivData->bPoisonOnFree) - { - int err; - - err = DmaBufSetValue(psDmaBuf, PVRSRV_POISON_ON_FREE_VALUE, __func__); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to poison allocation before " - "free", __func__)); - PVR_ASSERT(IMG_FALSE); - } - } - - if (psPrivData->pfnDestroy) - { - eError = psPrivData->pfnDestroy(psPrivData->psPhysHeap, psPrivData->psAttachment); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - OSFreeMem(psPrivData->pasDevPhysAddr); - OSFreeMem(psPrivData); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR PMRLockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv) -{ - PVR_UNREFERENCED_PARAMETER(pvPriv); - return PVRSRV_OK; -} - -static PVRSRV_ERROR PMRUnlockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv) -{ - PVR_UNREFERENCED_PARAMETER(pvPriv); - return PVRSRV_OK; -} - -static void PMRGetFactoryLock(void) -{ - mutex_lock(&g_HashLock); -} - -static void PMRReleaseFactoryLock(void) -{ - mutex_unlock(&g_HashLock); -} - -static PVRSRV_ERROR PMRDevPhysAddrDmaBuf(PMR_IMPL_PRIVDATA pvPriv, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_BOOL *pbValid, - IMG_DEV_PHYADDR *psDevPAddr) -{ - PMR_DMA_BUF_DATA *psPrivData = pvPriv; - IMG_UINT32 ui32PageIndex; - IMG_UINT32 idx; - - if (ui32Log2PageSize != PAGE_SHIFT) - { - return PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY; - } - - for (idx=0; idx < ui32NumOfPages; idx++) - { - if (pbValid[idx]) - { - IMG_UINT32 ui32InPageOffset; - - ui32PageIndex = puiOffset[idx] >> PAGE_SHIFT; - ui32InPageOffset = puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)ui32PageIndex << PAGE_SHIFT); - - PVR_LOG_RETURN_IF_FALSE(ui32PageIndex < psPrivData->ui32VirtPageCount, - "puiOffset out of range", PVRSRV_ERROR_OUT_OF_RANGE); - - PVR_ASSERT(ui32InPageOffset < PAGE_SIZE); - psDevPAddr[idx].uiAddr = psPrivData->pasDevPhysAddr[ui32PageIndex].uiAddr + ui32InPageOffset; - } - } - return PVRSRV_OK; -} - -static PVRSRV_ERROR -PMRAcquireKernelMappingDataDmaBuf(PMR_IMPL_PRIVDATA pvPriv, - size_t uiOffset, - size_t uiSize, - void **ppvKernelAddressOut, - IMG_HANDLE *phHandleOut, - PMR_FLAGS_T ulFlags) -{ - PMR_DMA_BUF_DATA *psPrivData = pvPriv; - struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf; - PVRSRV_ERROR eError; - int err; - - if (psPrivData->ui32PhysPageCount != psPrivData->ui32VirtPageCount) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Kernel mappings for sparse DMABufs " - "are not allowed!", __func__)); - eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING; - goto fail; - } - - err = dma_buf_begin_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL); - if (err) - { - eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING; - goto fail; - } - - err = dma_buf_vmap(psDmaBuf, &psPrivData->sMap); - if (err != 0 || psPrivData->sMap.vaddr == NULL) - { - eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING; - goto fail_kmap; - } - - *ppvKernelAddressOut = psPrivData->sMap.vaddr + uiOffset; - *phHandleOut = psPrivData->sMap.vaddr; - - return PVRSRV_OK; - -fail_kmap: - do { - err = dma_buf_end_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL); - } while (err == -EAGAIN || err == -EINTR); - -fail: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void PMRReleaseKernelMappingDataDmaBuf(PMR_IMPL_PRIVDATA pvPriv, - IMG_HANDLE hHandle) -{ - PMR_DMA_BUF_DATA *psPrivData = pvPriv; - struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf; - int err; - - dma_buf_vunmap(psDmaBuf, &psPrivData->sMap); - - do { - err = dma_buf_end_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL); - } while (err == -EAGAIN || err == -EINTR); -} - -static PVRSRV_ERROR PMRMMapDmaBuf(PMR_IMPL_PRIVDATA pvPriv, - PMR *psPMR, - PMR_MMAP_DATA pOSMMapData) -{ - PMR_DMA_BUF_DATA *psPrivData = pvPriv; - struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf; - struct vm_area_struct *psVma = pOSMMapData; - int err; - - if (psPrivData->ui32PhysPageCount != psPrivData->ui32VirtPageCount) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Not possible to MMAP sparse DMABufs", - __func__)); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - err = dma_buf_mmap(psDmaBuf, psVma, 0); - if (err) - { - return (err == -EINVAL) ? PVRSRV_ERROR_NOT_SUPPORTED : PVRSRV_ERROR_BAD_MAPPING; - } - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) - MMapStatsAddOrUpdatePMR(psPMR, psVma->vm_end - psVma->vm_start); -#endif - - return PVRSRV_OK; -} - -static PMR_IMPL_FUNCTAB _sPMRDmaBufFuncTab = -{ - .pfnLockPhysAddresses = PMRLockPhysAddressesDmaBuf, - .pfnUnlockPhysAddresses = PMRUnlockPhysAddressesDmaBuf, - .pfnDevPhysAddr = PMRDevPhysAddrDmaBuf, - .pfnAcquireKernelMappingData = PMRAcquireKernelMappingDataDmaBuf, - .pfnReleaseKernelMappingData = PMRReleaseKernelMappingDataDmaBuf, - .pfnMMap = PMRMMapDmaBuf, - .pfnFinalize = PMRFinalizeDmaBuf, - .pfnGetPMRFactoryLock = PMRGetFactoryLock, - .pfnReleasePMRFactoryLock = PMRReleaseFactoryLock, -}; - -/***************************************************************************** - * Public facing interface * - *****************************************************************************/ - -PVRSRV_ERROR -PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap, - struct dma_buf_attachment *psAttachment, - PFN_DESTROY_DMABUF_PMR pfnDestroy, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr) -{ - struct dma_buf *psDmaBuf = psAttachment->dmabuf; - PMR_DMA_BUF_DATA *psPrivData; - PMR_FLAGS_T uiPMRFlags; - IMG_BOOL bZeroOnAlloc; - IMG_BOOL bPoisonOnAlloc; - IMG_BOOL bPoisonOnFree; - PVRSRV_ERROR eError; - IMG_UINT32 i, j; - IMG_UINT32 uiPagesPerChunk = uiChunkSize >> PAGE_SHIFT; - IMG_UINT32 ui32PageCount = 0; - struct scatterlist *sg; - struct sg_table *table; - IMG_UINT32 uiSglOffset; - IMG_CHAR pszAnnotation[DEVMEM_ANNOTATION_MAX_LEN]; - IMG_UINT32 ui32ActualDmaBufPageCount; - - bZeroOnAlloc = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags); - bPoisonOnAlloc = PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags); -#if defined(DEBUG) - bPoisonOnFree = PVRSRV_CHECK_POISON_ON_FREE(uiFlags); -#else - bPoisonOnFree = IMG_FALSE; -#endif - if (bZeroOnAlloc && bPoisonOnFree) - { - /* Zero on Alloc and Poison on Alloc are mutually exclusive */ - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errReturn; - } - - if (!PMRValidateSize((IMG_UINT64) ui32NumVirtChunks * uiChunkSize)) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "PMR size exceeds limit #Chunks: %u ChunkSz %"IMG_UINT64_FMTSPECX"", - ui32NumVirtChunks, - uiChunkSize); - eError = PVRSRV_ERROR_PMR_TOO_LARGE; - goto errReturn; - } - - psPrivData = OSAllocZMem(sizeof(*psPrivData)); - if (psPrivData == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto errReturn; - } - - psPrivData->psPhysHeap = psHeap; - psPrivData->psAttachment = psAttachment; - psPrivData->pfnDestroy = pfnDestroy; - psPrivData->bPoisonOnFree = bPoisonOnFree; - psPrivData->ui32VirtPageCount = - (ui32NumVirtChunks * uiChunkSize) >> PAGE_SHIFT; - - psPrivData->pasDevPhysAddr = - OSAllocZMem(sizeof(*(psPrivData->pasDevPhysAddr)) * - psPrivData->ui32VirtPageCount); - if (!psPrivData->pasDevPhysAddr) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate buffer for physical addresses (oom)", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto errFreePrivData; - } - - if (bZeroOnAlloc || bPoisonOnAlloc) - { - int iValue = bZeroOnAlloc ? 0 : PVRSRV_POISON_ON_ALLOC_VALUE; - int err; - - err = DmaBufSetValue(psDmaBuf, iValue, __func__); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map buffer for %s", - __func__, - bZeroOnAlloc ? "zeroing" : "poisoning")); - - eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING; - goto errFreePhysAddr; - } - } - - table = dma_buf_map_attachment(psAttachment, DMA_BIDIRECTIONAL); - if (IS_ERR_OR_NULL(table)) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errFreePhysAddr; - } - - /* - * We do a two pass process: first work out how many pages there - * are and second, fill in the data. - */ - for_each_sg(table->sgl, sg, table->nents, i) - { - ui32PageCount += PAGE_ALIGN(pvr_sg_length(sg)) / PAGE_SIZE; - } - - if (WARN_ON(!ui32PageCount)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Number of phys. pages must not be zero", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errUnmap; - } - - /* Obtain actual page count of dma buf */ - ui32ActualDmaBufPageCount = psAttachment->dmabuf->size / PAGE_SIZE; - - if (WARN_ON(ui32ActualDmaBufPageCount < ui32NumPhysChunks * uiPagesPerChunk)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Requested physical chunks greater than " - "number of physical dma buf pages", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errUnmap; - } - - psPrivData->ui32PhysPageCount = ui32ActualDmaBufPageCount; - psPrivData->psSgTable = table; - ui32PageCount = 0; - sg = table->sgl; - uiSglOffset = 0; - - - /* Fill physical address array */ - for (i = 0; i < ui32NumPhysChunks; i++) - { - for (j = 0; j < uiPagesPerChunk; j++) - { - IMG_UINT32 uiIdx = pui32MappingTable[i] * uiPagesPerChunk + j; - - psPrivData->pasDevPhysAddr[uiIdx].uiAddr = - sg_dma_address(sg) + uiSglOffset; - - /* Get the next offset for the current sgl or the next sgl */ - uiSglOffset += PAGE_SIZE; - if (uiSglOffset >= pvr_sg_length(sg)) - { - sg = sg_next(sg); - uiSglOffset = 0; - - /* Check that we haven't looped */ - if (WARN_ON(sg == table->sgl)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to fill phys. address " - "array", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errUnmap; - } - } - } - } - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT, - psPrivData->ui32PhysPageCount << PAGE_SHIFT, - OSGetCurrentClientProcessIDKM()); -#endif - - uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK); - - /* - * Check no significant bits were lost in cast due to different - * bit widths for flags - */ - PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK)); - - if (OSSNPrintf((IMG_CHAR *)pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN, "ImpDmaBuf:%s", (IMG_CHAR *)pszName) < 0) - { - pszAnnotation[0] = '\0'; - } - else - { - pszAnnotation[DEVMEM_ANNOTATION_MAX_LEN-1] = '\0'; - } - - eError = PMRCreatePMR(psHeap, - ui32NumVirtChunks * uiChunkSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - PAGE_SHIFT, - uiPMRFlags, - pszAnnotation, - &_sPMRDmaBufFuncTab, - psPrivData, - PMR_TYPE_DMABUF, - ppsPMRPtr, - PDUMP_NONE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create PMR (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto errFreePhysAddr; - } - - return PVRSRV_OK; - -errUnmap: - dma_buf_unmap_attachment(psAttachment, table, DMA_BIDIRECTIONAL); -errFreePhysAddr: - OSFreeMem(psPrivData->pasDevPhysAddr); -errFreePrivData: - OSFreeMem(psPrivData); -errReturn: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static PVRSRV_ERROR PhysmemDestroyDmaBuf(PHYS_HEAP *psHeap, - struct dma_buf_attachment *psAttachment) -{ - struct dma_buf *psDmaBuf = psAttachment->dmabuf; - - PVR_UNREFERENCED_PARAMETER(psHeap); - - dma_buf_detach(psDmaBuf, psAttachment); - dma_buf_put(psDmaBuf); - - return PVRSRV_OK; -} - -struct dma_buf * -PhysmemGetDmaBuf(PMR *psPMR) -{ - PMR_DMA_BUF_DATA *psPrivData; - - psPrivData = PMRGetPrivateData(psPMR, &_sPMRDmaBufFuncTab); - if (psPrivData) - { - return psPrivData->psAttachment->dmabuf; - } - - return NULL; -} - -PVRSRV_ERROR -PhysmemExportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PMR *psPMR, - IMG_INT *piFd) -{ - struct dma_buf *psDmaBuf; - IMG_DEVMEM_SIZE_T uiPMRSize; - PVRSRV_ERROR eError; - IMG_INT iFd; - - mutex_lock(&g_HashLock); - - PMRRefPMR(psPMR); - - PMR_LogicalSize(psPMR, &uiPMRSize); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - { - DEFINE_DMA_BUF_EXPORT_INFO(sDmaBufExportInfo); - - sDmaBufExportInfo.priv = psPMR; - sDmaBufExportInfo.ops = &sPVRDmaBufOps; - sDmaBufExportInfo.size = uiPMRSize; - sDmaBufExportInfo.flags = O_RDWR; - - psDmaBuf = dma_buf_export(&sDmaBufExportInfo); - } -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) - psDmaBuf = dma_buf_export(psPMR, &sPVRDmaBufOps, - uiPMRSize, O_RDWR, NULL); -#else - psDmaBuf = dma_buf_export(psPMR, &sPVRDmaBufOps, - uiPMRSize, O_RDWR); -#endif - - if (IS_ERR_OR_NULL(psDmaBuf)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to export buffer (err=%ld)", - __func__, psDmaBuf ? PTR_ERR(psDmaBuf) : -ENOMEM)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_pmr_ref; - } - - iFd = dma_buf_fd(psDmaBuf, O_RDWR); - if (iFd < 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get dma-buf fd (err=%d)", - __func__, iFd)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_dma_buf; - } - - mutex_unlock(&g_HashLock); - *piFd = iFd; - - /* A PMR memory lay out can't change once exported - * This makes sure the exported and imported parties see - * the same layout of the memory */ - PMR_SetLayoutFixed(psPMR, IMG_TRUE); - - return PVRSRV_OK; - -fail_dma_buf: - dma_buf_put(psDmaBuf); - -fail_pmr_ref: - mutex_unlock(&g_HashLock); - PMRUnrefPMR(psPMR); - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PhysmemImportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT32 ui32MappingTable = 0; - struct dma_buf *psDmaBuf; - PVRSRV_ERROR eError; - - /* Get the buffer handle */ - psDmaBuf = dma_buf_get(fd); - if (IS_ERR_OR_NULL(psDmaBuf)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get dma-buf from fd (err=%ld)", - __func__, psDmaBuf ? PTR_ERR(psDmaBuf) : -ENOMEM)); - return PVRSRV_ERROR_BAD_MAPPING; - - } - - uiSize = psDmaBuf->size; - - eError = PhysmemImportSparseDmaBuf(psConnection, - psDevNode, - fd, - uiFlags, - uiSize, - 1, - 1, - &ui32MappingTable, - ui32NameSize, - pszName, - ppsPMRPtr, - puiSize, - puiAlign); - - dma_buf_put(psDmaBuf); - - return eError; -} - -PVRSRV_ERROR -PhysmemImportDmaBufLocked(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - PMR *psPMRPtr; - PVRSRV_ERROR eError; - - eError = PhysmemImportDmaBuf(psConnection, - psDevNode, - fd, - uiFlags, - ui32NameSize, - pszName, - &psPMRPtr, - puiSize, - puiAlign); - - if (eError == PVRSRV_OK) - { - eError = PMRLockSysPhysAddresses(psPMRPtr); - if (eError == PVRSRV_OK) - { - *ppsPMRPtr = psPMRPtr; - } - else - { - PMRUnrefPMR(psPMRPtr); - } - } - - return eError; -} - -PVRSRV_ERROR -PhysmemImportSparseDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - PMR *psPMR = NULL; - struct dma_buf_attachment *psAttachment; - struct dma_buf *psDmaBuf; - PVRSRV_ERROR eError; - IMG_BOOL bHashTableCreated = IMG_FALSE; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (!psDevNode) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errReturn; - } - - /* Terminate string from bridge to prevent corrupt annotations in RI */ - if (pszName != NULL) - { - IMG_CHAR* pszName0 = (IMG_CHAR*) pszName; - pszName0[ui32NameSize-1] = '\0'; - } - - mutex_lock(&g_HashLock); - - /* Get the buffer handle */ - psDmaBuf = dma_buf_get(fd); - if (IS_ERR_OR_NULL(psDmaBuf)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get dma-buf from fd (err=%ld)", - __func__, psDmaBuf ? PTR_ERR(psDmaBuf) : -ENOMEM)); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto errUnlockReturn; - } - - if (psDmaBuf->ops == &sPVRDmaBufOps) - { - PVRSRV_DEVICE_NODE *psPMRDevNode; - - /* We exported this dma_buf, so we can just get its PMR */ - psPMR = (PMR *) psDmaBuf->priv; - - /* However, we can't import it if it belongs to a different device */ - psPMRDevNode = PMR_DeviceNode(psPMR); - if (psPMRDevNode != psDevNode) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR invalid for this device", - __func__)); - eError = PVRSRV_ERROR_PMR_NOT_PERMITTED; - goto err; - } - } - else - { - if (g_psDmaBufHash) - { - /* We have a hash table so check if we've seen this dmabuf before */ - psPMR = (PMR *) HASH_Retrieve(g_psDmaBufHash, (uintptr_t) psDmaBuf); - } - else - { - /* - * As different processes may import the same dmabuf we need to - * create a hash table so we don't generate a duplicate PMR but - * rather just take a reference on an existing one. - */ - g_psDmaBufHash = HASH_Create(DMA_BUF_HASH_SIZE); - if (!g_psDmaBufHash) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err; - } - bHashTableCreated = IMG_TRUE; - } - } - - if (psPMR) - { - /* Reuse the PMR we already created */ - PMRRefPMR(psPMR); - - *ppsPMRPtr = psPMR; - PMR_LogicalSize(psPMR, puiSize); - *puiAlign = PAGE_SIZE; - } - /* No errors so far */ - eError = PVRSRV_OK; - -err: - if (psPMR || (PVRSRV_OK != eError)) - { - mutex_unlock(&g_HashLock); - dma_buf_put(psDmaBuf); - - if (PVRSRV_OK == eError) - { - /* - * We expect a PMR to be immutable at this point - * But its explicitly set here to cover a corner case - * where a PMR created through non-DMA interface could be - * imported back again through DMA interface */ - PMR_SetLayoutFixed(psPMR, IMG_TRUE); - } - return eError; - } - - { /* Parameter validation - Mapping table entries*/ - IMG_UINT32 i; - for (i = 0; i < ui32NumPhysChunks; i++) - { - if (pui32MappingTable[i] > ui32NumVirtChunks) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Requesting sparse buffer: " - "Entry in mapping table (%u) is out of allocation " - "bounds (%u)", __func__, - (IMG_UINT32) pui32MappingTable[i], - (IMG_UINT32) ui32NumVirtChunks)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, - errUnlockAndDMAPut); - } - } - } - - /* Do we want this to be a sparse PMR? */ - if (ui32NumVirtChunks > 1) - { - /* Parameter validation */ - if (psDmaBuf->size < (uiChunkSize * ui32NumPhysChunks) || - uiChunkSize != PAGE_SIZE) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Requesting sparse buffer: " - "uiChunkSize ("IMG_DEVMEM_SIZE_FMTSPEC") must be equal to " - "OS page size (%lu). uiChunkSize * ui32NumPhysChunks " - "("IMG_DEVMEM_SIZE_FMTSPEC") must" - " not be greater than the buffer size ("IMG_SIZE_FMTSPEC").", - __func__, - uiChunkSize, - PAGE_SIZE, - uiChunkSize * ui32NumPhysChunks, - psDmaBuf->size)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errUnlockAndDMAPut; - } - } - else - { - /* if ui32NumPhysChunks == 0 then pui32MappingTable == NULL - * this is handled by the generated bridge code. - * Because ui32NumPhysChunks is set to 1 below, we don't allow NULL array */ - if (pui32MappingTable == NULL) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errUnlockAndDMAPut; - } - - /* Make sure parameters are valid for non-sparse allocations as well */ - uiChunkSize = psDmaBuf->size; - ui32NumPhysChunks = 1; - ui32NumVirtChunks = 1; - } - - { - IMG_DEVMEM_SIZE_T uiSize = ui32NumVirtChunks * uiChunkSize; - IMG_UINT32 uiLog2PageSize = PAGE_SHIFT; /* log2(uiChunkSize) */ - eError = PhysMemValidateParams(ui32NumPhysChunks, ui32NumVirtChunks, uiFlags, &uiLog2PageSize, &uiSize, &uiChunkSize); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysMemValidateParams", errUnlockAndDMAPut); - } - - psAttachment = dma_buf_attach(psDmaBuf, psDevNode->psDevConfig->pvOSDevice); - if (IS_ERR_OR_NULL(psAttachment)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to attach to dma-buf (err=%ld)", - __func__, psAttachment? PTR_ERR(psAttachment) : -ENOMEM)); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto errUnlockAndDMAPut; - } - - /* - * Note: - * While we have no way to determine the type of the buffer we just - * assume that all dmabufs are from the same physical heap. - */ - eError = PhysmemCreateNewDmaBufBackedPMR(psDevNode->apsPhysHeap[PVRSRV_PHYS_HEAP_EXTERNAL], - psAttachment, - PhysmemDestroyDmaBuf, - uiFlags, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - ui32NameSize, - pszName, - &psPMR); - if (eError != PVRSRV_OK) - { - goto errDMADetach; - } - - /* First time we've seen this dmabuf so store it in the hash table */ - HASH_Insert(g_psDmaBufHash, (uintptr_t) psDmaBuf, (uintptr_t) psPMR); - g_ui32HashRefCount++; - - mutex_unlock(&g_HashLock); - - PVRSRVIonAddMemAllocRecord(psDmaBuf); - - *ppsPMRPtr = psPMR; - *puiSize = ui32NumVirtChunks * uiChunkSize; - *puiAlign = PAGE_SIZE; - - /* The memory that's just imported is owned by some other entity. - * Hence the memory layout cannot be changed through our API */ - PMR_SetLayoutFixed(psPMR, IMG_TRUE); - - return PVRSRV_OK; - -errDMADetach: - dma_buf_detach(psDmaBuf, psAttachment); - -errUnlockAndDMAPut: - if (IMG_TRUE == bHashTableCreated) - { - HASH_Delete(g_psDmaBufHash); - g_psDmaBufHash = NULL; - } - dma_buf_put(psDmaBuf); - -errUnlockReturn: - mutex_unlock(&g_HashLock); - -errReturn: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) || defined(SUPPORT_ION) */ - -PVRSRV_ERROR -PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap, - struct dma_buf_attachment *psAttachment, - PFN_DESTROY_DMABUF_PMR pfnDestroy, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr) -{ - PVR_UNREFERENCED_PARAMETER(psHeap); - PVR_UNREFERENCED_PARAMETER(psAttachment); - PVR_UNREFERENCED_PARAMETER(pfnDestroy); - PVR_UNREFERENCED_PARAMETER(uiFlags); - PVR_UNREFERENCED_PARAMETER(uiChunkSize); - PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks); - PVR_UNREFERENCED_PARAMETER(ui32NumVirtChunks); - PVR_UNREFERENCED_PARAMETER(pui32MappingTable); - PVR_UNREFERENCED_PARAMETER(ui32NameSize); - PVR_UNREFERENCED_PARAMETER(pszName); - PVR_UNREFERENCED_PARAMETER(ppsPMRPtr); - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -struct dma_buf * -PhysmemGetDmaBuf(PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - - return NULL; -} - -PVRSRV_ERROR -PhysmemExportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PMR *psPMR, - IMG_INT *piFd) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(piFd); - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR -PhysmemImportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(fd); - PVR_UNREFERENCED_PARAMETER(uiFlags); - PVR_UNREFERENCED_PARAMETER(ui32NameSize); - PVR_UNREFERENCED_PARAMETER(pszName); - PVR_UNREFERENCED_PARAMETER(ppsPMRPtr); - PVR_UNREFERENCED_PARAMETER(puiSize); - PVR_UNREFERENCED_PARAMETER(puiAlign); - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR -PhysmemImportSparseDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(fd); - PVR_UNREFERENCED_PARAMETER(uiFlags); - PVR_UNREFERENCED_PARAMETER(ppsPMRPtr); - PVR_UNREFERENCED_PARAMETER(puiSize); - PVR_UNREFERENCED_PARAMETER(puiAlign); - PVR_UNREFERENCED_PARAMETER(uiChunkSize); - PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks); - PVR_UNREFERENCED_PARAMETER(ui32NumVirtChunks); - PVR_UNREFERENCED_PARAMETER(pui32MappingTable); - PVR_UNREFERENCED_PARAMETER(ui32NameSize); - PVR_UNREFERENCED_PARAMETER(pszName); - - return PVRSRV_ERROR_NOT_SUPPORTED; -} -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) || defined(SUPPORT_ION) || defined(KERNEL_HAS_DMABUF_VMAP_MMAP) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.h b/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.h deleted file mode 100644 index 99b5c3365fb05..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_dmabuf.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************/ /*! -@File physmem_dmabuf.h -@Title Header for dmabuf PMR factory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - implementing the function callbacks importing Ion allocations -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(PHYSMEM_DMABUF_H) -#define PHYSMEM_DMABUF_H - -#include - -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "connection_server.h" - -#include "pmr.h" - -typedef PVRSRV_ERROR (*PFN_DESTROY_DMABUF_PMR)(PHYS_HEAP *psHeap, - struct dma_buf_attachment *psAttachment); - -PVRSRV_ERROR -PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap, - struct dma_buf_attachment *psAttachment, - PFN_DESTROY_DMABUF_PMR pfnDestroy, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr); - -struct dma_buf * -PhysmemGetDmaBuf(PMR *psPMR); - -PVRSRV_ERROR -PhysmemExportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PMR *psPMR, - IMG_INT *piFd); - -PVRSRV_ERROR -PhysmemImportDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign); - -PVRSRV_ERROR -PhysmemImportDmaBufLocked(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign); - -PVRSRV_ERROR -PhysmemImportSparseDmaBuf(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_INT fd, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 ui32NameSize, - const IMG_CHAR pszName[DEVMEM_ANNOTATION_MAX_LEN], - PMR **ppsPMRPtr, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign); - -#endif /* !defined(PHYSMEM_DMABUF_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.c b/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.c deleted file mode 100644 index b1e1252482c30..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.c +++ /dev/null @@ -1,204 +0,0 @@ -/*************************************************************************/ /*! -@File physmem_hostmem.c -@Title Host memory device node functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Functions relevant to device memory allocations made from host - mem device node. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "physmem_hostmem.h" - -#include "img_defs.h" -#include "img_types.h" -#include "allocmem.h" -#include "physheap.h" -#include "pvrsrv_device.h" -#include "physheap.h" -#include "physmem_osmem.h" - -static void HostMemCpuPAddrToDevPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_CPU_PHYADDR *psCpuPAddr); - -static void HostMemDevPAddrToCpuPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_DEV_PHYADDR *psDevPAddr); - -/* heap callbacks for host driver's device's heap */ -static PHYS_HEAP_FUNCTIONS gsHostMemDevPhysHeapFuncs = -{ - .pfnCpuPAddrToDevPAddr = HostMemCpuPAddrToDevPAddr, - .pfnDevPAddrToCpuPAddr = HostMemDevPAddrToCpuPAddr, -}; - -static PVRSRV_DEVICE_CONFIG gsHostMemDevConfig[]; - -/* heap configuration for host driver's device */ -static PHYS_HEAP_CONFIG gsPhysHeapConfigHostMemDevice[] = -{ - { - PHYS_HEAP_TYPE_UMA, - "SYSMEM", - &gsHostMemDevPhysHeapFuncs, - {0}, - {0}, - 0, - (IMG_HANDLE)&gsHostMemDevConfig[0], - PHYS_HEAP_USAGE_CPU_LOCAL, - } -}; - -/* device configuration for host driver's device */ -static PVRSRV_DEVICE_CONFIG gsHostMemDevConfig[] = -{ - { - .pszName = "HostMemDevice", - .eCacheSnoopingMode = PVRSRV_DEVICE_SNOOP_NONE, - .pasPhysHeaps = &gsPhysHeapConfigHostMemDevice[0], - .ui32PhysHeapCount = ARRAY_SIZE(gsPhysHeapConfigHostMemDevice), - } -}; - -static void HostMemCpuPAddrToDevPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_CPU_PHYADDR *psCpuPAddr) -{ - PVR_UNREFERENCED_PARAMETER(hPrivData); - /* Optimise common case */ - psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr; - if (ui32NumOfAddr > 1) - { - IMG_UINT32 ui32Idx; - for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx) - { - psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr; - } - } -} - -static void HostMemDevPAddrToCpuPAddr(IMG_HANDLE hPrivData, - IMG_UINT32 ui32NumOfAddr, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_DEV_PHYADDR *psDevPAddr) -{ - PVR_UNREFERENCED_PARAMETER(hPrivData); - /* Optimise common case */ - psCpuPAddr[0].uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(psDevPAddr[0].uiAddr); - if (ui32NumOfAddr > 1) - { - IMG_UINT32 ui32Idx; - for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx) - { - psCpuPAddr[ui32Idx].uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(psDevPAddr[ui32Idx].uiAddr); - } - } -} - -PVRSRV_ERROR HostMemDeviceCreate(PVRSRV_DEVICE_NODE **ppsDeviceNode) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = &gsHostMemDevConfig[0]; - - /* Assert ensures HostMemory device isn't already created and - * that data is initialised */ - PVR_ASSERT(*ppsDeviceNode == NULL); - - /* for now, we only know a single heap (UMA) config for host device */ - PVR_ASSERT(psDevConfig->ui32PhysHeapCount == 1 && - psDevConfig->pasPhysHeaps[0].eType == PHYS_HEAP_TYPE_UMA); - - /* N.B.- In case of any failures in this function, we just return error to - the caller, as clean-up is taken care by _HostMemDeviceDestroy function */ - - psDeviceNode = OSAllocZMem(sizeof(*psDeviceNode)); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode, "OSAllocZMem"); - - /* early save return pointer to aid clean-up */ - *ppsDeviceNode = psDeviceNode; - - psDeviceNode->psDevConfig = psDevConfig; - psDeviceNode->papsRegisteredPhysHeaps = - OSAllocZMem(sizeof(*psDeviceNode->papsRegisteredPhysHeaps) * - psDevConfig->ui32PhysHeapCount); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode->papsRegisteredPhysHeaps, "OSAllocZMem"); - - eError = PhysHeapCreateHeapFromConfig(psDeviceNode, - &psDevConfig->pasPhysHeaps[0], - &psDeviceNode->papsRegisteredPhysHeaps[0]); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysHeapCreateHeapFromConfig"); - psDeviceNode->ui32RegisteredPhysHeaps = 1; - - /* Only CPU local heap is valid on host-mem DevNode, so enable minimal callbacks */ - eError = PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP_CPU_LOCAL, - psDeviceNode, - &psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_CPU_LOCAL]); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysHeapAcquire"); - - return PVRSRV_OK; -} - -void HostMemDeviceDestroy(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (!psDeviceNode) - { - return; - } - - if (psDeviceNode->papsRegisteredPhysHeaps) - { - if (psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_CPU_LOCAL]) - { - PhysHeapRelease(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_CPU_LOCAL]); - } - - if (psDeviceNode->papsRegisteredPhysHeaps[0]) - { - /* clean-up function as well is aware of only one heap */ - PVR_ASSERT(psDeviceNode->ui32RegisteredPhysHeaps == 1); - PhysHeapDestroy(psDeviceNode->papsRegisteredPhysHeaps[0]); - } - - OSFreeMem(psDeviceNode->papsRegisteredPhysHeaps); - } - OSFreeMem(psDeviceNode); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.h b/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.h deleted file mode 100644 index cfa453de343a2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_hostmem.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************/ /*! -@File physmem_hostmem.h -@Title Host memory device node header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PHYSMEM_HOSTMEM_H) -#define PHYSMEM_HOSTMEM_H - -#include "pvrsrv_device.h" -#include "device.h" - -/*************************************************************************/ /*! -@Function HostMemDeviceCreate -@Description Allocate memory for and create host memory device node. -@Output ppsDeviceNode Pointer to device node pointer. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR HostMemDeviceCreate(PVRSRV_DEVICE_NODE **ppsDeviceNode); - -/*************************************************************************/ /*! -@Function HostMemDeviceDestroy -@Description Destroy host memory device node. -@Input psDeviceNode Pointer to device node. -*/ /**************************************************************************/ -void HostMemDeviceDestroy(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* !defined(PHYSMEM_HOSTMEM_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_lma.c b/drivers/gpu/drm/img-rogue/1.17/physmem_lma.c deleted file mode 100644 index c3cb0cdb3700f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_lma.c +++ /dev/null @@ -1,1962 +0,0 @@ -/*************************************************************************/ /*! -@File physmem_lma.c -@Title Local card memory allocator -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - implementing the function callbacks for local card memory. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "rgx_pdump_panics.h" -#include "allocmem.h" -#include "osfunc.h" -#include "pvrsrv.h" -#include "devicemem_server_utils.h" -#include "physmem_lma.h" -#include "pdump_km.h" -#include "pmr.h" -#include "pmr_impl.h" -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "rgxutils.h" -#endif - -#if defined(INTEGRITY_OS) -#include "mm.h" -#include "integrity_memobject.h" -#endif - -/* Since 0x0 is a valid DevPAddr, we rely on max 64-bit value to be an invalid - * page address */ -#define INVALID_PAGE_ADDR ~((IMG_UINT64)0x0) - -typedef struct _PMR_LMALLOCARRAY_DATA_ { - IMG_PID uiPid; - IMG_INT32 iNumPagesAllocated; - /* - * uiTotalNumPages: - * Total number of pages supported by this PMR. - * (Fixed as of now due the fixed Page table array size) - */ - IMG_UINT32 uiTotalNumPages; - IMG_UINT32 uiPagesToAlloc; - - IMG_UINT32 uiLog2AllocSize; - IMG_UINT32 uiContigAllocSize; - IMG_DEV_PHYADDR *pasDevPAddr; - - IMG_BOOL bZeroOnAlloc; - IMG_BOOL bPoisonOnAlloc; - - IMG_BOOL bOnDemand; - - /* - Record at alloc time whether poisoning will be required when the - PMR is freed. - */ - IMG_BOOL bPoisonOnFree; - - /* Physical heap and arena pointers for this allocation */ - PHYS_HEAP* psPhysHeap; - RA_ARENA* psArena; - PVRSRV_MEMALLOCFLAGS_T uiAllocFlags; - - /* - Connection data for this requests' originating process. NULL for - direct-bridge originating calls - */ - CONNECTION_DATA *psConnection; -} PMR_LMALLOCARRAY_DATA; - -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) && defined(__linux__) -/* Global structure to manage GPU memory leak */ -static DEFINE_MUTEX(g_sLMALeakMutex); -static IMG_UINT32 g_ui32LMALeakCounter = 0; -#endif - -typedef struct PHYSMEM_LMA_DATA_TAG { - RA_ARENA *psRA; - - IMG_CPU_PHYADDR sStartAddr; - IMG_DEV_PHYADDR sCardBase; - IMG_UINT64 uiSize; -} PHYSMEM_LMA_DATA; - -/* - * This function will set the psDevPAddr to whatever the system layer - * has set it for the referenced heap. - * It will not fail if the psDevPAddr is invalid. - */ -static PVRSRV_ERROR -_GetDevPAddr(PHEAP_IMPL_DATA pvImplData, - IMG_DEV_PHYADDR *psDevPAddr) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - *psDevPAddr = psLMAData->sCardBase; - - return PVRSRV_OK; -} - -/* - * This function will set the psCpuPAddr to whatever the system layer - * has set it for the referenced heap. - * It will not fail if the psCpuPAddr is invalid. - */ -static PVRSRV_ERROR -_GetCPUPAddr(PHEAP_IMPL_DATA pvImplData, - IMG_CPU_PHYADDR *psCpuPAddr) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - *psCpuPAddr = psLMAData->sStartAddr; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_GetSize(PHEAP_IMPL_DATA pvImplData, - IMG_UINT64 *puiSize) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - *puiSize = psLMAData->uiSize; - - return PVRSRV_OK; -} - -static IMG_UINT32 -_GetPageShift(void) -{ - return PVRSRV_4K_PAGE_SIZE_ALIGNSHIFT; -} - -static void PhysmemGetLocalRamMemStats(PHEAP_IMPL_DATA pvImplData, - IMG_UINT64 *pui64TotalSize, - IMG_UINT64 *pui64FreeSize) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - RA_USAGE_STATS sRAUsageStats; - - RA_Get_Usage_Stats(psLMAData->psRA, &sRAUsageStats); - - *pui64TotalSize = sRAUsageStats.ui64TotalArenaSize; - *pui64FreeSize = sRAUsageStats.ui64FreeArenaSize; -} - -static PVRSRV_ERROR -PhysmemGetArenaLMA(PHYS_HEAP *psPhysHeap, - RA_ARENA **ppsArena) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)PhysHeapGetImplData(psPhysHeap); - - PVR_LOG_RETURN_IF_FALSE(psLMAData != NULL, "psLMAData", PVRSRV_ERROR_NOT_IMPLEMENTED); - - *ppsArena = psLMAData->psRA; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_CreateArenas(PHEAP_IMPL_DATA pvImplData, IMG_CHAR *pszLabel) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - psLMAData->psRA = RA_Create_With_Span(pszLabel, - OSGetPageShift(), - psLMAData->sStartAddr.uiAddr, - psLMAData->sCardBase.uiAddr, - psLMAData->uiSize); - PVR_LOG_RETURN_IF_NOMEM(psLMAData->psRA, "RA_Create_With_Span"); - - return PVRSRV_OK; -} - -static void -_DestroyArenas(PHEAP_IMPL_DATA pvImplData) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - /* Remove RAs and RA names for local card memory */ - if (psLMAData->psRA) - { - OSFreeMem(psLMAData->psRA); - psLMAData->psRA = NULL; - } -} - -static void -_DestroyImplData(PHEAP_IMPL_DATA pvImplData) -{ - PHYSMEM_LMA_DATA *psLMAData = (PHYSMEM_LMA_DATA*)pvImplData; - - _DestroyArenas(pvImplData); - - OSFreeMem(psLMAData); -} - -struct _PHYS_HEAP_ITERATOR_ { - PHYS_HEAP *psPhysHeap; - RA_ARENA_ITERATOR *psRAIter; - - IMG_UINT64 uiTotalSize; - IMG_UINT64 uiInUseSize; -}; - -PVRSRV_ERROR LMA_HeapIteratorCreate(PVRSRV_DEVICE_NODE *psDevNode, - PHYS_HEAP_USAGE_FLAGS ui32Flags, - PHYS_HEAP_ITERATOR **ppsIter) -{ - PVRSRV_ERROR eError; - PHYSMEM_LMA_DATA *psLMAData; - PHYS_HEAP_ITERATOR *psHeapIter; - PHYS_HEAP *psPhysHeap = NULL; - RA_USAGE_STATS sStats; - - PVR_LOG_RETURN_IF_INVALID_PARAM(ppsIter != NULL, "ppsIter"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevNode != NULL, "psDevNode"); - PVR_LOG_RETURN_IF_INVALID_PARAM(ui32Flags != 0, "ui32Flags"); - - eError = PhysHeapAcquireByUsage(ui32Flags, psDevNode, &psPhysHeap); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysHeapAcquireByUsage"); - - PVR_LOG_GOTO_IF_FALSE(PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_LMA, - "PhysHeap must be of LMA type", release_heap); - - psLMAData = (PHYSMEM_LMA_DATA *) PhysHeapGetImplData(psPhysHeap); - - psHeapIter = OSAllocMem(sizeof(*psHeapIter)); - PVR_LOG_GOTO_IF_NOMEM(psHeapIter, eError, release_heap); - - psHeapIter->psPhysHeap = psPhysHeap; - psHeapIter->psRAIter = RA_IteratorAcquire(psLMAData->psRA, IMG_FALSE); - PVR_LOG_GOTO_IF_NOMEM(psHeapIter->psRAIter, eError, free_heap_iter); - - /* get heap usage */ - RA_Get_Usage_Stats(psLMAData->psRA, &sStats); - - psHeapIter->uiTotalSize = sStats.ui64TotalArenaSize; - psHeapIter->uiInUseSize = sStats.ui64TotalArenaSize - sStats.ui64FreeArenaSize; - - *ppsIter = psHeapIter; - - return PVRSRV_OK; - -free_heap_iter: - OSFreeMem(psHeapIter); - -release_heap: - PhysHeapRelease(psPhysHeap); - - return eError; -} - -void LMA_HeapIteratorDestroy(PHYS_HEAP_ITERATOR *psIter) -{ - PHYS_HEAP_ITERATOR *psHeapIter = psIter; - - PVR_LOG_RETURN_VOID_IF_FALSE(psHeapIter != NULL, "psHeapIter is NULL"); - - PhysHeapRelease(psHeapIter->psPhysHeap); - RA_IteratorRelease(psHeapIter->psRAIter); - OSFreeMem(psHeapIter); -} - -PVRSRV_ERROR LMA_HeapIteratorReset(PHYS_HEAP_ITERATOR *psIter) -{ - PHYS_HEAP_ITERATOR *psHeapIter = psIter; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psHeapIter != NULL, "ppsIter"); - - RA_IteratorReset(psHeapIter->psRAIter); - - return PVRSRV_OK; -} - -IMG_BOOL LMA_HeapIteratorNext(PHYS_HEAP_ITERATOR *psIter, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT64 *puiSize) -{ - PHYS_HEAP_ITERATOR *psHeapIter = psIter; - RA_ITERATOR_DATA sData = {0}; - - if (psHeapIter == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "psHeapIter in %s() is NULL", __func__)); - return IMG_FALSE; - } - - if (!RA_IteratorNext(psHeapIter->psRAIter, &sData)) - { - return IMG_FALSE; - } - - PVR_ASSERT(sData.uiSize != 0); - - psDevPAddr->uiAddr = sData.uiAddr; - *puiSize = sData.uiSize; - - return IMG_TRUE; -} - -PVRSRV_ERROR LMA_HeapIteratorGetHeapStats(PHYS_HEAP_ITERATOR *psIter, - IMG_UINT64 *puiTotalSize, - IMG_UINT64 *puiInUseSize) -{ - PHYS_HEAP_ITERATOR *psHeapIter = psIter; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psHeapIter != NULL, "psHeapIter"); - - *puiTotalSize = psHeapIter->uiTotalSize; - *puiInUseSize = psHeapIter->uiInUseSize; - - return PVRSRV_OK; -} - - -static PVRSRV_ERROR -_LMA_DoPhyContigPagesAlloc(RA_ARENA *pArena, - size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid) -{ - RA_BASE_T uiCardAddr = 0; - RA_LENGTH_T uiActualSize; - PVRSRV_ERROR eError; -#if defined(DEBUG) - static IMG_UINT32 ui32MaxLog2NumPages = 4; /* 16 pages => 64KB */ -#endif /* defined(DEBUG) */ - - IMG_UINT32 ui32Log2NumPages = 0; - - PVR_ASSERT(uiSize != 0); - ui32Log2NumPages = OSGetOrder(uiSize); - uiSize = (1 << ui32Log2NumPages) * OSGetPageSize(); - - eError = RA_Alloc(pArena, - uiSize, - RA_NO_IMPORT_MULTIPLIER, - 0, /* No flags */ - uiSize, - "LMA_PhyContigPagesAlloc", - &uiCardAddr, - &uiActualSize, - NULL); /* No private handle */ - - PVR_ASSERT(uiSize == uiActualSize); - - psMemHandle->u.ui64Handle = uiCardAddr; - psDevPAddr->uiAddr = (IMG_UINT64) uiCardAddr; - - if (PVRSRV_OK == eError) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, - uiSize, - uiCardAddr, - uiPid); -#else - IMG_CPU_PHYADDR sCpuPAddr; - sCpuPAddr.uiAddr = psDevPAddr->uiAddr; - - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, - NULL, - sCpuPAddr, - uiSize, - NULL, - uiPid - DEBUG_MEMSTATS_VALUES); -#endif -#endif -#if defined(SUPPORT_GPUVIRT_VALIDATION) - PVR_DPF((PVR_DBG_MESSAGE, - "%s: (GPU Virtualisation) Allocated 0x" IMG_SIZE_FMTSPECX " at 0x%" IMG_UINT64_FMTSPECX ", Arena ID %u", - __func__, uiSize, psDevPAddr->uiAddr, psMemHandle->uiOSid)); -#endif - -#if defined(DEBUG) - PVR_ASSERT((ui32Log2NumPages <= ui32MaxLog2NumPages)); - if (ui32Log2NumPages > ui32MaxLog2NumPages) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ui32MaxLog2NumPages = %u, increasing to %u", __func__, - ui32MaxLog2NumPages, ui32Log2NumPages )); - ui32MaxLog2NumPages = ui32Log2NumPages; - } -#endif /* defined(DEBUG) */ - psMemHandle->uiOrder = ui32Log2NumPages; - } - - return eError; -} - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -static PVRSRV_ERROR -LMA_PhyContigPagesAllocGPV(PHYS_HEAP *psPhysHeap, - size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 ui32OSid, - IMG_PID uiPid) -{ - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPhysHeap); - RA_ARENA *pArena; - IMG_UINT32 ui32Log2NumPages = 0; - PVRSRV_ERROR eError; - - PVR_ASSERT(uiSize != 0); - ui32Log2NumPages = OSGetOrder(uiSize); - uiSize = (1 << ui32Log2NumPages) * OSGetPageSize(); - - PVR_ASSERT(ui32OSid < GPUVIRT_VALIDATION_NUM_OS); - if (ui32OSid >= GPUVIRT_VALIDATION_NUM_OS) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Arena index %u defaulting to 0", - __func__, ui32OSid)); - ui32OSid = 0; - } - - pArena = psDevNode->psOSidSubArena[ui32OSid]; - - if (psMemHandle->uiOSid != ui32OSid) - { - PVR_LOG(("%s: Unexpected OSid value %u - expecting %u", __func__, - psMemHandle->uiOSid, ui32OSid)); - } - - psMemHandle->uiOSid = ui32OSid; /* For Free() use */ - - eError = _LMA_DoPhyContigPagesAlloc(pArena, uiSize, psMemHandle, - psDevPAddr, uiPid); - PVR_LOG_IF_ERROR(eError, "_LMA_DoPhyContigPagesAlloc"); - - return eError; -} -#endif - -static PVRSRV_ERROR -LMA_PhyContigPagesAlloc(PHYS_HEAP *psPhysHeap, - size_t uiSize, - PG_HANDLE *psMemHandle, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_PID uiPid) -{ -#if defined(SUPPORT_GPUVIRT_VALIDATION) - IMG_UINT32 ui32OSid = 0; - return LMA_PhyContigPagesAllocGPV(psPhysHeap, uiSize, psMemHandle, psDevPAddr, - ui32OSid, uiPid); -#else - PVRSRV_ERROR eError; - - RA_ARENA *pArena; - IMG_UINT32 ui32Log2NumPages = 0; - - eError = PhysmemGetArenaLMA(psPhysHeap, &pArena); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysmemGetArenaLMA"); - - PVR_ASSERT(uiSize != 0); - ui32Log2NumPages = OSGetOrder(uiSize); - uiSize = (1 << ui32Log2NumPages) * OSGetPageSize(); - - eError = _LMA_DoPhyContigPagesAlloc(pArena, uiSize, psMemHandle, - psDevPAddr, uiPid); - PVR_LOG_IF_ERROR(eError, "_LMA_DoPhyContigPagesAlloc"); - - return eError; -#endif -} - -static void -LMA_PhyContigPagesFree(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle) -{ - RA_BASE_T uiCardAddr = (RA_BASE_T) psMemHandle->u.ui64Handle; - RA_ARENA *pArena; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPhysHeap); - IMG_UINT32 ui32OSid = psMemHandle->uiOSid; - - /* - * The Arena ID is set by the originating allocation, and maintained via - * the call stacks into this function. We have a limited range of IDs - * and if the passed value falls outside this we simply treat it as a - * 'global' arena ID of 0. This is where all default OS-specific allocations - * are created. - */ - PVR_ASSERT(ui32OSid < GPUVIRT_VALIDATION_NUM_OS); - if (ui32OSid >= GPUVIRT_VALIDATION_NUM_OS) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Arena index %u PhysAddr 0x%" - IMG_UINT64_FMTSPECx " Reverting to Arena 0", __func__, - ui32OSid, uiCardAddr)); - /* - * No way of determining what we're trying to free so default to the - * global default arena index 0. - */ - ui32OSid = 0; - } - - pArena = psDevNode->psOSidSubArena[ui32OSid]; - - PVR_DPF((PVR_DBG_MESSAGE, "%s: (GPU Virtualisation) Freeing 0x%" - IMG_UINT64_FMTSPECx ", Arena %u", __func__, - uiCardAddr, ui32OSid)); - -#else - PhysmemGetArenaLMA(psPhysHeap, &pArena); -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, - (IMG_UINT64)uiCardAddr); -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, - (IMG_UINT64)uiCardAddr, - OSGetCurrentClientProcessIDKM()); -#endif -#endif - - RA_Free(pArena, uiCardAddr); - psMemHandle->uiOrder = 0; -} - -static PVRSRV_ERROR -LMA_PhyContigPagesMap(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr, - void **pvPtr) -{ - IMG_CPU_PHYADDR sCpuPAddr; - IMG_UINT32 ui32NumPages = (1 << psMemHandle->uiOrder); - PVR_UNREFERENCED_PARAMETER(uiSize); - - PhysHeapDevPAddrToCpuPAddr(psPhysHeap, 1, &sCpuPAddr, psDevPAddr); - *pvPtr = OSMapPhysToLin(sCpuPAddr, - ui32NumPages * OSGetPageSize(), - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC); - PVR_RETURN_IF_NOMEM(*pvPtr); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, - ui32NumPages * OSGetPageSize(), - OSGetCurrentClientProcessIDKM()); -#else - { - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, - *pvPtr, - sCpuPAddr, - ui32NumPages * OSGetPageSize(), - NULL, - OSGetCurrentClientProcessIDKM() - DEBUG_MEMSTATS_VALUES); - } -#endif -#endif - return PVRSRV_OK; -} - -static void -LMA_PhyContigPagesUnmap(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - void *pvPtr) -{ - IMG_UINT32 ui32NumPages = (1 << psMemHandle->uiOrder); - PVR_UNREFERENCED_PARAMETER(psPhysHeap); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, - ui32NumPages * OSGetPageSize(), - OSGetCurrentClientProcessIDKM()); -#else - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, - (IMG_UINT64)(uintptr_t)pvPtr, - OSGetCurrentClientProcessIDKM()); -#endif -#endif - - OSUnMapPhysToLin(pvPtr, ui32NumPages * OSGetPageSize()); -} - -static PVRSRV_ERROR -LMA_PhyContigPagesClean(PHYS_HEAP *psPhysHeap, - PG_HANDLE *psMemHandle, - IMG_UINT32 uiOffset, - IMG_UINT32 uiLength) -{ - /* No need to flush because we map as uncached */ - PVR_UNREFERENCED_PARAMETER(psPhysHeap); - PVR_UNREFERENCED_PARAMETER(psMemHandle); - PVR_UNREFERENCED_PARAMETER(uiOffset); - PVR_UNREFERENCED_PARAMETER(uiLength); - - return PVRSRV_OK; -} - -static PHEAP_IMPL_FUNCS _sPHEAPImplFuncs = -{ - .pfnDestroyData = &_DestroyImplData, - .pfnGetDevPAddr = &_GetDevPAddr, - .pfnGetCPUPAddr = &_GetCPUPAddr, - .pfnGetSize = &_GetSize, - .pfnGetPageShift = &_GetPageShift, - .pfnGetPMRFactoryMemStats = &PhysmemGetLocalRamMemStats, - .pfnCreatePMR = &PhysmemNewLocalRamBackedPMR, -#if defined(SUPPORT_GPUVIRT_VALIDATION) - .pfnPagesAllocGPV = &LMA_PhyContigPagesAllocGPV, -#endif - .pfnPagesAlloc = &LMA_PhyContigPagesAlloc, - .pfnPagesFree = &LMA_PhyContigPagesFree, - .pfnPagesMap = &LMA_PhyContigPagesMap, - .pfnPagesUnMap = &LMA_PhyContigPagesUnmap, - .pfnPagesClean = &LMA_PhyContigPagesClean, -}; - -PVRSRV_ERROR -PhysmemCreateHeapLMA(PVRSRV_DEVICE_NODE *psDevNode, - PHYS_HEAP_CONFIG *psConfig, - IMG_CHAR *pszLabel, - PHYS_HEAP **ppsPhysHeap) -{ - PHYSMEM_LMA_DATA *psLMAData; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszLabel != NULL, "pszLabel"); - - psLMAData = OSAllocMem(sizeof(*psLMAData)); - PVR_LOG_RETURN_IF_NOMEM(psLMAData, "OSAllocMem"); - - psLMAData->sStartAddr = psConfig->sStartAddr; - psLMAData->sCardBase = psConfig->sCardBase; - psLMAData->uiSize = psConfig->uiSize; - - - eError = PhysHeapCreate(psDevNode, - psConfig, - (PHEAP_IMPL_DATA)psLMAData, - &_sPHEAPImplFuncs, - ppsPhysHeap); - if (eError != PVRSRV_OK) - { - OSFreeMem(psLMAData); - return eError; - } - - eError = _CreateArenas(psLMAData, pszLabel); - PVR_LOG_RETURN_IF_ERROR(eError, "_CreateArenas"); - - - return eError; -} - -static PVRSRV_ERROR _MapAlloc(PHYS_HEAP *psPhysHeap, - IMG_DEV_PHYADDR *psDevPAddr, - size_t uiSize, - PMR_FLAGS_T ulFlags, - void **pvPtr) -{ - IMG_UINT32 ui32CPUCacheFlags; - IMG_CPU_PHYADDR sCpuPAddr; - PVRSRV_ERROR eError; - - eError = DevmemCPUCacheMode(PhysHeapDeviceNode(psPhysHeap), ulFlags, &ui32CPUCacheFlags); - PVR_RETURN_IF_ERROR(eError); - - PhysHeapDevPAddrToCpuPAddr(psPhysHeap, 1, &sCpuPAddr, psDevPAddr); - - *pvPtr = OSMapPhysToLin(sCpuPAddr, uiSize, ui32CPUCacheFlags); - PVR_RETURN_IF_NOMEM(*pvPtr); - - return PVRSRV_OK; -} - -static void _UnMapAlloc(size_t uiSize, - void *pvPtr) -{ - OSUnMapPhysToLin(pvPtr, uiSize); -} - -static PVRSRV_ERROR -_PoisonAlloc(PHYS_HEAP *psPhysHeap, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 uiContigAllocSize, - IMG_BYTE ui8PoisonValue) -{ - PVRSRV_ERROR eError; - void *pvKernLin = NULL; - - eError = _MapAlloc(psPhysHeap, - psDevPAddr, - uiContigAllocSize, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC, - &pvKernLin); - PVR_GOTO_IF_ERROR(eError, map_failed); - - OSCachedMemSetWMB(pvKernLin, ui8PoisonValue, uiContigAllocSize); - - _UnMapAlloc(uiContigAllocSize, pvKernLin); - - return PVRSRV_OK; - -map_failed: - PVR_DPF((PVR_DBG_ERROR, "Failed to poison allocation")); - return eError; -} - -static PVRSRV_ERROR -_ZeroAlloc(PHYS_HEAP *psPhysHeap, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT32 uiContigAllocSize) -{ - void *pvKernLin = NULL; - PVRSRV_ERROR eError; - - eError = _MapAlloc(psPhysHeap, - psDevPAddr, - uiContigAllocSize, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC, - &pvKernLin); - PVR_GOTO_IF_ERROR(eError, map_failed); - - OSCachedMemSetWMB(pvKernLin, 0, uiContigAllocSize); - - _UnMapAlloc(uiContigAllocSize, pvKernLin); - - return PVRSRV_OK; - -map_failed: - PVR_DPF((PVR_DBG_ERROR, "Failed to zero allocation")); - return eError; -} - -static PVRSRV_ERROR -_AllocLMPageArray(PMR_SIZE_T uiSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pabMappingTable, - IMG_UINT32 uiLog2AllocPageSize, - IMG_BOOL bZero, - IMG_BOOL bPoisonOnAlloc, - IMG_BOOL bPoisonOnFree, - IMG_BOOL bContig, - IMG_BOOL bOnDemand, - PHYS_HEAP* psPhysHeap, - PVRSRV_MEMALLOCFLAGS_T uiAllocFlags, - IMG_PID uiPid, - PMR_LMALLOCARRAY_DATA **ppsPageArrayDataPtr, - CONNECTION_DATA *psConnection - ) -{ - PMR_LMALLOCARRAY_DATA *psPageArrayData = NULL; - IMG_UINT32 ui32Index; - PVRSRV_ERROR eError; - - PVR_ASSERT(!bZero || !bPoisonOnAlloc); - PVR_ASSERT(OSGetPageShift() <= uiLog2AllocPageSize); - - psPageArrayData = OSAllocZMem(sizeof(PMR_LMALLOCARRAY_DATA)); - PVR_GOTO_IF_NOMEM(psPageArrayData, eError, errorOnAllocArray); - - if (bContig) - { - /* - Some allocations require kernel mappings in which case in order - to be virtually contiguous we also have to be physically contiguous. - */ - psPageArrayData->uiTotalNumPages = 1; - psPageArrayData->uiPagesToAlloc = psPageArrayData->uiTotalNumPages; - psPageArrayData->uiContigAllocSize = TRUNCATE_64BITS_TO_32BITS(uiSize); - psPageArrayData->uiLog2AllocSize = uiLog2AllocPageSize; - } - else - { - IMG_UINT32 uiNumPages; - - /* Use of cast below is justified by the assertion that follows to - prove that no significant bits have been truncated */ - uiNumPages = (IMG_UINT32)(((uiSize - 1) >> uiLog2AllocPageSize) + 1); - PVR_ASSERT(((PMR_SIZE_T)uiNumPages << uiLog2AllocPageSize) == uiSize); - - psPageArrayData->uiTotalNumPages = uiNumPages; - - if ((ui32NumVirtChunks != ui32NumPhysChunks) || (1 < ui32NumVirtChunks)) - { - psPageArrayData->uiPagesToAlloc = ui32NumPhysChunks; - } - else - { - psPageArrayData->uiPagesToAlloc = uiNumPages; - } - psPageArrayData->uiContigAllocSize = 1 << uiLog2AllocPageSize; - psPageArrayData->uiLog2AllocSize = uiLog2AllocPageSize; - } - psPageArrayData->psConnection = psConnection; - psPageArrayData->uiPid = uiPid; - psPageArrayData->pasDevPAddr = OSAllocMem(sizeof(IMG_DEV_PHYADDR) * - psPageArrayData->uiTotalNumPages); - PVR_GOTO_IF_NOMEM(psPageArrayData->pasDevPAddr, eError, errorOnAllocAddr); - - /* Since no pages are allocated yet, initialise page addresses to INVALID_PAGE_ADDR */ - for (ui32Index = 0; ui32Index < psPageArrayData->uiTotalNumPages; ui32Index++) - { - psPageArrayData->pasDevPAddr[ui32Index].uiAddr = INVALID_PAGE_ADDR; - } - - psPageArrayData->iNumPagesAllocated = 0; - psPageArrayData->bZeroOnAlloc = bZero; - psPageArrayData->bPoisonOnAlloc = bPoisonOnAlloc; - psPageArrayData->bPoisonOnFree = bPoisonOnFree; - psPageArrayData->bOnDemand = bOnDemand; - psPageArrayData->psPhysHeap = psPhysHeap; - psPageArrayData->uiAllocFlags = uiAllocFlags; - - *ppsPageArrayDataPtr = psPageArrayData; - - return PVRSRV_OK; - - /* - error exit paths follow: - */ -errorOnAllocAddr: - OSFreeMem(psPageArrayData); - -errorOnAllocArray: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -static PVRSRV_ERROR -_AllocLMPages(PMR_LMALLOCARRAY_DATA *psPageArrayData, IMG_UINT32 *pui32MapTable) -{ - PVRSRV_ERROR eError; - RA_BASE_T uiCardAddr; - RA_LENGTH_T uiActualSize; - IMG_UINT32 i, ui32Index = 0; - IMG_UINT32 uiContigAllocSize; - IMG_UINT32 uiLog2AllocSize; - PVRSRV_DEVICE_NODE __maybe_unused *psDevNode; - IMG_BOOL bPoisonOnAlloc; - IMG_BOOL bZeroOnAlloc; - RA_ARENA *pArena; - - PVR_ASSERT(NULL != psPageArrayData); - PVR_ASSERT(0 <= psPageArrayData->iNumPagesAllocated); - - psDevNode = PhysHeapDeviceNode(psPageArrayData->psPhysHeap); - uiContigAllocSize = psPageArrayData->uiContigAllocSize; - uiLog2AllocSize = psPageArrayData->uiLog2AllocSize; - bPoisonOnAlloc = psPageArrayData->bPoisonOnAlloc; - bZeroOnAlloc = psPageArrayData->bZeroOnAlloc; - - /* Get suitable local memory region for this GPU physheap allocation */ - eError = PhysmemGetArenaLMA(psPageArrayData->psPhysHeap, &pArena); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysmemGetArenaLMA"); - - if (psPageArrayData->uiTotalNumPages < - (psPageArrayData->iNumPagesAllocated + psPageArrayData->uiPagesToAlloc)) - { - PVR_DPF((PVR_DBG_ERROR, "Pages requested to allocate don't fit PMR alloc Size. " - "Allocated: %u + Requested: %u > Total Allowed: %u", - psPageArrayData->iNumPagesAllocated, - psPageArrayData->uiPagesToAlloc, - psPageArrayData->uiTotalNumPages)); - return PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE; - } - - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - { - IMG_UINT32 ui32OSid=0; - - /* Obtain the OSid specific data from our connection handle */ - if (psPageArrayData->psConnection != NULL) - { - ui32OSid = psPageArrayData->psConnection->ui32OSid; - } - - if (PVRSRV_CHECK_SHARED_BUFFER(psPageArrayData->uiAllocFlags)) - { - pArena=psDevNode->psOSSharedArena; - PVR_DPF((PVR_DBG_MESSAGE, - "(GPU Virtualization Validation): Giving from shared mem")); - } - else - { - pArena=psDevNode->psOSidSubArena[ui32OSid]; - PVR_DPF((PVR_DBG_MESSAGE, - "(GPU Virtualization Validation): Giving from OS slot %d", - ui32OSid)); - } - } -#endif - - psPageArrayData->psArena = pArena; - - for (i = 0; i < psPageArrayData->uiPagesToAlloc; i++) - { - /* This part of index finding should happen before allocating the page. - * Just avoiding intricate paths */ - if (psPageArrayData->uiTotalNumPages == psPageArrayData->uiPagesToAlloc) - { - ui32Index = i; - } - else - { - if (NULL == pui32MapTable) - { - PVR_LOG_GOTO_WITH_ERROR("pui32MapTable", eError, PVRSRV_ERROR_PMR_INVALID_MAP_INDEX_ARRAY, errorOnRAAlloc); - } - - ui32Index = pui32MapTable[i]; - if (ui32Index >= psPageArrayData->uiTotalNumPages) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Page alloc request Index out of bounds for PMR @0x%p", - __func__, - psPageArrayData)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE, errorOnRAAlloc); - } - - if (INVALID_PAGE_ADDR != psPageArrayData->pasDevPAddr[ui32Index].uiAddr) - { - PVR_LOG_GOTO_WITH_ERROR("Mapping already exists", eError, PVRSRV_ERROR_PMR_MAPPING_ALREADY_EXISTS, errorOnRAAlloc); - } - } - - eError = RA_Alloc(pArena, - uiContigAllocSize, - RA_NO_IMPORT_MULTIPLIER, - 0, /* No flags */ - 1ULL << uiLog2AllocSize, - "LMA_Page_Alloc", - &uiCardAddr, - &uiActualSize, - NULL); /* No private handle */ - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to Allocate the page @index:%d, size = 0x%llx", - ui32Index, 1ULL << uiLog2AllocSize)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES, errorOnRAAlloc); - } - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -{ - PVR_DPF((PVR_DBG_MESSAGE, - "(GPU Virtualization Validation): Address: 0x%"IMG_UINT64_FMTSPECX, - uiCardAddr)); -} -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - /* Allocation is done a page at a time */ - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, uiActualSize, psPageArrayData->uiPid); -#else - { - IMG_CPU_PHYADDR sLocalCpuPAddr; - - sLocalCpuPAddr.uiAddr = (IMG_UINT64)uiCardAddr; - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, - NULL, - sLocalCpuPAddr, - uiActualSize, - NULL, - psPageArrayData->uiPid - DEBUG_MEMSTATS_VALUES); - } -#endif -#endif - - psPageArrayData->pasDevPAddr[ui32Index].uiAddr = uiCardAddr; - if (bPoisonOnAlloc) - { - eError = _PoisonAlloc(psPageArrayData->psPhysHeap, - &psPageArrayData->pasDevPAddr[ui32Index], - uiContigAllocSize, - PVRSRV_POISON_ON_ALLOC_VALUE); - PVR_LOG_GOTO_IF_ERROR(eError, "_PoisonAlloc", errorOnPoison); - } - - if (bZeroOnAlloc) - { - eError = _ZeroAlloc(psPageArrayData->psPhysHeap, - &psPageArrayData->pasDevPAddr[ui32Index], - uiContigAllocSize); - PVR_LOG_GOTO_IF_ERROR(eError, "_ZeroAlloc", errorOnZero); - } - } - psPageArrayData->iNumPagesAllocated += psPageArrayData->uiPagesToAlloc; - - return PVRSRV_OK; - - /* - error exit paths follow: - */ -errorOnZero: -errorOnPoison: - eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES; -errorOnRAAlloc: - PVR_DPF((PVR_DBG_ERROR, - "%s: alloc_pages failed to honour request %d @index: %d of %d pages: (%s)", - __func__, - ui32Index, - i, - psPageArrayData->uiPagesToAlloc, - PVRSRVGetErrorString(eError))); - while (--i < psPageArrayData->uiPagesToAlloc) - { - if (psPageArrayData->uiTotalNumPages == psPageArrayData->uiPagesToAlloc) - { - ui32Index = i; - } - else - { - if (NULL == pui32MapTable) - { - break; - } - - ui32Index = pui32MapTable[i]; - } - - if (ui32Index < psPageArrayData->uiTotalNumPages) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - /* Allocation is done a page at a time */ - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, - uiContigAllocSize, - psPageArrayData->uiPid); -#else - { - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, - psPageArrayData->pasDevPAddr[ui32Index].uiAddr, - psPageArrayData->uiPid); - } -#endif -#endif - RA_Free(pArena, psPageArrayData->pasDevPAddr[ui32Index].uiAddr); - psPageArrayData->pasDevPAddr[ui32Index].uiAddr = INVALID_PAGE_ADDR; - } - } - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static PVRSRV_ERROR -_FreeLMPageArray(PMR_LMALLOCARRAY_DATA *psPageArrayData) -{ - OSFreeMem(psPageArrayData->pasDevPAddr); - - PVR_DPF((PVR_DBG_MESSAGE, - "physmem_lma.c: freed local memory array structure for PMR @0x%p", - psPageArrayData)); - - OSFreeMem(psPageArrayData); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_FreeLMPages(PMR_LMALLOCARRAY_DATA *psPageArrayData, - IMG_UINT32 *pui32FreeIndices, - IMG_UINT32 ui32FreePageCount) -{ - IMG_UINT32 uiContigAllocSize; - IMG_UINT32 i, ui32PagesToFree=0, ui32PagesFreed=0, ui32Index=0; - RA_ARENA *pArena = psPageArrayData->psArena; - - PVR_ASSERT(psPageArrayData->iNumPagesAllocated != 0); - - uiContigAllocSize = psPageArrayData->uiContigAllocSize; - - ui32PagesToFree = (NULL == pui32FreeIndices) ? - psPageArrayData->uiTotalNumPages : ui32FreePageCount; - - for (i = 0; i < ui32PagesToFree; i++) - { - if (NULL == pui32FreeIndices) - { - ui32Index = i; - } - else - { - ui32Index = pui32FreeIndices[i]; - } - - if (INVALID_PAGE_ADDR != psPageArrayData->pasDevPAddr[ui32Index].uiAddr) - { - ui32PagesFreed++; - if (psPageArrayData->bPoisonOnFree) - { - _PoisonAlloc(psPageArrayData->psPhysHeap, - &psPageArrayData->pasDevPAddr[ui32Index], - uiContigAllocSize, - PVRSRV_POISON_ON_FREE_VALUE); - } - - RA_Free(pArena, psPageArrayData->pasDevPAddr[ui32Index].uiAddr); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) - /* Allocation is done a page at a time */ - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, - uiContigAllocSize, - psPageArrayData->uiPid); -#else - { - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, - psPageArrayData->pasDevPAddr[ui32Index].uiAddr, - psPageArrayData->uiPid); - } -#endif -#endif - psPageArrayData->pasDevPAddr[ui32Index].uiAddr = INVALID_PAGE_ADDR; - } - } - psPageArrayData->iNumPagesAllocated -= ui32PagesFreed; - - PVR_ASSERT(0 <= psPageArrayData->iNumPagesAllocated); - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: freed %d local memory for PMR @0x%p", - __func__, - (ui32PagesFreed * uiContigAllocSize), - psPageArrayData)); - - return PVRSRV_OK; -} - -/* - * - * Implementation of callback functions - * - */ - -/* destructor func is called after last reference disappears, but - before PMR itself is freed. */ -static PVRSRV_ERROR -PMRFinalizeLocalMem(PMR_IMPL_PRIVDATA pvPriv) -{ - PVRSRV_ERROR eError; - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = NULL; - - psLMAllocArrayData = pvPriv; - - /* We can't free pages until now. */ - if (psLMAllocArrayData->iNumPagesAllocated != 0) - { -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) && defined(__linux__) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_UINT32 ui32LMALeakMax = psPVRSRVData->sMemLeakIntervals.ui32GPU; - - mutex_lock(&g_sLMALeakMutex); - - g_ui32LMALeakCounter++; - if (ui32LMALeakMax && g_ui32LMALeakCounter >= ui32LMALeakMax) - { - g_ui32LMALeakCounter = 0; - mutex_unlock(&g_sLMALeakMutex); - - PVR_DPF((PVR_DBG_WARNING, "%s: Skipped freeing of PMR 0x%p to trigger memory leak.", __func__, pvPriv)); - return PVRSRV_OK; - } - - mutex_unlock(&g_sLMALeakMutex); -#endif - eError = _FreeLMPages(psLMAllocArrayData, NULL, 0); - PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */ - } - - eError = _FreeLMPageArray(psLMAllocArrayData); - PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */ - - return PVRSRV_OK; -} - -/* callback function for locking the system physical page addresses. - As we are LMA there is nothing to do as we control physical memory. */ -static PVRSRV_ERROR -PMRLockSysPhysAddressesLocalMem(PMR_IMPL_PRIVDATA pvPriv) -{ - - PVRSRV_ERROR eError; - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData; - - psLMAllocArrayData = pvPriv; - - if (psLMAllocArrayData->bOnDemand) - { - /* Allocate Memory for deferred allocation */ - eError = _AllocLMPages(psLMAllocArrayData, NULL); - PVR_RETURN_IF_ERROR(eError); - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -PMRUnlockSysPhysAddressesLocalMem(PMR_IMPL_PRIVDATA pvPriv) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData; - - psLMAllocArrayData = pvPriv; - - if (psLMAllocArrayData->bOnDemand) - { - /* Free Memory for deferred allocation */ - eError = _FreeLMPages(psLMAllocArrayData, NULL, 0); - PVR_RETURN_IF_ERROR(eError); - } - - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} - -/* N.B. It is assumed that PMRLockSysPhysAddressesLocalMem() is called _before_ this function! */ -static PVRSRV_ERROR -PMRSysPhysAddrLocalMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_BOOL *pbValid, - IMG_DEV_PHYADDR *psDevPAddr) -{ - IMG_UINT32 idx; - IMG_UINT32 uiLog2AllocSize; - IMG_UINT32 uiNumAllocs; - IMG_UINT64 uiAllocIndex; - IMG_DEVMEM_OFFSET_T uiInAllocOffset; - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = pvPriv; - - if (psLMAllocArrayData->uiLog2AllocSize < ui32Log2PageSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Requested physical addresses from PMR " - "for incompatible contiguity %u!", - __func__, - ui32Log2PageSize)); - return PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY; - } - - uiNumAllocs = psLMAllocArrayData->uiTotalNumPages; - if (uiNumAllocs > 1) - { - PVR_ASSERT(psLMAllocArrayData->uiLog2AllocSize != 0); - uiLog2AllocSize = psLMAllocArrayData->uiLog2AllocSize; - - for (idx=0; idx < ui32NumOfPages; idx++) - { - if (pbValid[idx]) - { - uiAllocIndex = puiOffset[idx] >> uiLog2AllocSize; - uiInAllocOffset = puiOffset[idx] - (uiAllocIndex << uiLog2AllocSize); - - PVR_LOG_RETURN_IF_FALSE(uiAllocIndex < uiNumAllocs, - "puiOffset out of range", PVRSRV_ERROR_OUT_OF_RANGE); - - PVR_ASSERT(uiInAllocOffset < (1ULL << uiLog2AllocSize)); - - psDevPAddr[idx].uiAddr = psLMAllocArrayData->pasDevPAddr[uiAllocIndex].uiAddr + uiInAllocOffset; - } - } - } - else - { - for (idx=0; idx < ui32NumOfPages; idx++) - { - if (pbValid[idx]) - { - psDevPAddr[idx].uiAddr = psLMAllocArrayData->pasDevPAddr[0].uiAddr + puiOffset[idx]; - } - } - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -PMRAcquireKernelMappingDataLocalMem(PMR_IMPL_PRIVDATA pvPriv, - size_t uiOffset, - size_t uiSize, - void **ppvKernelAddressOut, - IMG_HANDLE *phHandleOut, - PMR_FLAGS_T ulFlags) -{ - PVRSRV_ERROR eError; - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = NULL; - void *pvKernLinAddr = NULL; - IMG_UINT32 ui32PageIndex = 0; - size_t uiOffsetMask = uiOffset; - - psLMAllocArrayData = pvPriv; - - /* Check that we can map this in contiguously */ - if (psLMAllocArrayData->uiTotalNumPages != 1) - { - size_t uiStart = uiOffset; - size_t uiEnd = uiOffset + uiSize - 1; - size_t uiPageMask = ~((1 << psLMAllocArrayData->uiLog2AllocSize) - 1); - - /* We can still map if only one page is required */ - if ((uiStart & uiPageMask) != (uiEnd & uiPageMask)) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY, e0); - } - - /* Locate the desired physical page to map in */ - ui32PageIndex = uiOffset >> psLMAllocArrayData->uiLog2AllocSize; - uiOffsetMask = (1U << psLMAllocArrayData->uiLog2AllocSize) - 1; - } - - PVR_ASSERT(ui32PageIndex < psLMAllocArrayData->uiTotalNumPages); - - eError = _MapAlloc(psLMAllocArrayData->psPhysHeap, - &psLMAllocArrayData->pasDevPAddr[ui32PageIndex], - psLMAllocArrayData->uiContigAllocSize, - ulFlags, - &pvKernLinAddr); - - *ppvKernelAddressOut = ((IMG_CHAR *) pvKernLinAddr) + (uiOffset & uiOffsetMask); - *phHandleOut = pvKernLinAddr; - - return eError; - - /* - error exit paths follow: - */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void PMRReleaseKernelMappingDataLocalMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_HANDLE hHandle) -{ - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = NULL; - void *pvKernLinAddr = NULL; - - psLMAllocArrayData = (PMR_LMALLOCARRAY_DATA *) pvPriv; - pvKernLinAddr = (void *) hHandle; - - _UnMapAlloc(psLMAllocArrayData->uiContigAllocSize, - pvKernLinAddr); -} - - -static PVRSRV_ERROR -CopyBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes, - void (*pfnCopyBytes)(IMG_UINT8 *pcBuffer, - IMG_UINT8 *pcPMR, - size_t uiSize)) -{ - PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = NULL; - size_t uiBytesCopied; - size_t uiBytesToCopy; - size_t uiBytesCopyableFromAlloc; - void *pvMapping = NULL; - IMG_UINT8 *pcKernelPointer = NULL; - size_t uiBufferOffset; - IMG_UINT64 uiAllocIndex; - IMG_DEVMEM_OFFSET_T uiInAllocOffset; - PVRSRV_ERROR eError; - - psLMAllocArrayData = pvPriv; - - uiBytesCopied = 0; - uiBytesToCopy = uiBufSz; - uiBufferOffset = 0; - - if (psLMAllocArrayData->uiTotalNumPages > 1) - { - while (uiBytesToCopy > 0) - { - /* we have to map one alloc in at a time */ - PVR_ASSERT(psLMAllocArrayData->uiLog2AllocSize != 0); - uiAllocIndex = uiOffset >> psLMAllocArrayData->uiLog2AllocSize; - uiInAllocOffset = uiOffset - (uiAllocIndex << psLMAllocArrayData->uiLog2AllocSize); - uiBytesCopyableFromAlloc = uiBytesToCopy; - if (uiBytesCopyableFromAlloc + uiInAllocOffset > (1ULL << psLMAllocArrayData->uiLog2AllocSize)) - { - uiBytesCopyableFromAlloc = TRUNCATE_64BITS_TO_SIZE_T((1ULL << psLMAllocArrayData->uiLog2AllocSize)-uiInAllocOffset); - } - - PVR_ASSERT(uiBytesCopyableFromAlloc != 0); - PVR_ASSERT(uiAllocIndex < psLMAllocArrayData->uiTotalNumPages); - PVR_ASSERT(uiInAllocOffset < (1ULL << psLMAllocArrayData->uiLog2AllocSize)); - - eError = _MapAlloc(psLMAllocArrayData->psPhysHeap, - &psLMAllocArrayData->pasDevPAddr[uiAllocIndex], - psLMAllocArrayData->uiContigAllocSize, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC, - &pvMapping); - PVR_GOTO_IF_ERROR(eError, e0); - pcKernelPointer = pvMapping; - pfnCopyBytes(&pcBuffer[uiBufferOffset], &pcKernelPointer[uiInAllocOffset], uiBytesCopyableFromAlloc); - - _UnMapAlloc(psLMAllocArrayData->uiContigAllocSize, - pvMapping); - - uiBufferOffset += uiBytesCopyableFromAlloc; - uiBytesToCopy -= uiBytesCopyableFromAlloc; - uiOffset += uiBytesCopyableFromAlloc; - uiBytesCopied += uiBytesCopyableFromAlloc; - } - } - else - { - PVR_ASSERT((uiOffset + uiBufSz) <= psLMAllocArrayData->uiContigAllocSize); - PVR_ASSERT(psLMAllocArrayData->uiContigAllocSize != 0); - eError = _MapAlloc(psLMAllocArrayData->psPhysHeap, - &psLMAllocArrayData->pasDevPAddr[0], - psLMAllocArrayData->uiContigAllocSize, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC, - &pvMapping); - PVR_GOTO_IF_ERROR(eError, e0); - pcKernelPointer = pvMapping; - pfnCopyBytes(pcBuffer, &pcKernelPointer[uiOffset], uiBufSz); - - _UnMapAlloc(psLMAllocArrayData->uiContigAllocSize, - pvMapping); - - uiBytesCopied = uiBufSz; - } - *puiNumBytes = uiBytesCopied; - return PVRSRV_OK; -e0: - *puiNumBytes = uiBytesCopied; - return eError; -} - -static void ReadLocalMem(IMG_UINT8 *pcBuffer, - IMG_UINT8 *pcPMR, - size_t uiSize) -{ - /* the memory is mapped as WC (and also aligned to page size) so we can - * safely call "Cached" memcpy */ - OSCachedMemCopy(pcBuffer, pcPMR, uiSize); -} - -static PVRSRV_ERROR -PMRReadBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - return CopyBytesLocalMem(pvPriv, - uiOffset, - pcBuffer, - uiBufSz, - puiNumBytes, - ReadLocalMem); -} - -static void WriteLocalMem(IMG_UINT8 *pcBuffer, - IMG_UINT8 *pcPMR, - size_t uiSize) -{ - /* the memory is mapped as WC (and also aligned to page size) so we can - * safely call "Cached" memcpy but need to issue a write memory barrier - * to flush the write buffers after */ - OSCachedMemCopyWMB(pcPMR, pcBuffer, uiSize); -} - -static PVRSRV_ERROR -PMRWriteBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - return CopyBytesLocalMem(pvPriv, - uiOffset, - pcBuffer, - uiBufSz, - puiNumBytes, - WriteLocalMem); -} - -/*************************************************************************/ /*! -@Function PMRChangeSparseMemLocalMem -@Description This function Changes the sparse mapping by allocating and - freeing of pages. It also changes the GPU maps accordingly. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -static PVRSRV_ERROR -PMRChangeSparseMemLocalMem(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiFlags) -{ - PVRSRV_ERROR eError = PVRSRV_ERROR_INVALID_PARAMS; - - IMG_UINT32 ui32AdtnlAllocPages = 0; - IMG_UINT32 ui32AdtnlFreePages = 0; - IMG_UINT32 ui32CommonRequstCount = 0; - IMG_UINT32 ui32Loop = 0; - IMG_UINT32 ui32Index = 0; - IMG_UINT32 uiAllocpgidx; - IMG_UINT32 uiFreepgidx; - - PMR_LMALLOCARRAY_DATA *psPMRPageArrayData = (PMR_LMALLOCARRAY_DATA *)pPriv; - -#if defined(DEBUG) - IMG_BOOL bPoisonFail = IMG_FALSE; - IMG_BOOL bZeroFail = IMG_FALSE; -#endif - - /* Fetch the Page table array represented by the PMR */ - IMG_DEV_PHYADDR *psPageArray = psPMRPageArrayData->pasDevPAddr; - PMR_MAPPING_TABLE *psPMRMapTable = PMR_GetMappingTable(psPMR); - - /* The incoming request is classified into two operations independent of - * each other: alloc & free pages. - * These operations can be combined with two mapping operations as well - * which are GPU & CPU space mappings. - * - * From the alloc and free page requests, the net amount of pages to be - * allocated or freed is computed. Pages that were requested to be freed - * will be reused to fulfil alloc requests. - * - * The order of operations is: - * 1. Allocate new pages from the OS - * 2. Move the free pages from free request to alloc positions. - * 3. Free the rest of the pages not used for alloc - * - * Alloc parameters are validated at the time of allocation - * and any error will be handled then. */ - - if (SPARSE_RESIZE_BOTH == (uiFlags & SPARSE_RESIZE_BOTH)) - { - ui32CommonRequstCount = (ui32AllocPageCount > ui32FreePageCount) ? - ui32FreePageCount : ui32AllocPageCount; - - PDUMP_PANIC(PMR_DeviceNode(psPMR), SPARSEMEM_SWAP, "Request to swap alloc & free pages not supported"); - } - - if (SPARSE_RESIZE_ALLOC == (uiFlags & SPARSE_RESIZE_ALLOC)) - { - ui32AdtnlAllocPages = ui32AllocPageCount - ui32CommonRequstCount; - } - else - { - ui32AllocPageCount = 0; - } - - if (SPARSE_RESIZE_FREE == (uiFlags & SPARSE_RESIZE_FREE)) - { - ui32AdtnlFreePages = ui32FreePageCount - ui32CommonRequstCount; - } - else - { - ui32FreePageCount = 0; - } - - PVR_LOG_RETURN_IF_FALSE( - (ui32CommonRequstCount | ui32AdtnlAllocPages | ui32AdtnlFreePages) != 0, - "Invalid combination of parameters: ui32CommonRequstCount," - " ui32AdtnlAllocPages and ui32AdtnlFreePages.", - PVRSRV_ERROR_INVALID_PARAMS - ); - - { - /* Validate the free page indices */ - if (ui32FreePageCount) - { - if (NULL != pai32FreeIndices) - { - for (ui32Loop = 0; ui32Loop < ui32FreePageCount; ui32Loop++) - { - uiFreepgidx = pai32FreeIndices[ui32Loop]; - - if (uiFreepgidx >= psPMRPageArrayData->uiTotalNumPages) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE, e0); - } - - if (INVALID_PAGE_ADDR == psPageArray[uiFreepgidx].uiAddr) - { - PVR_LOG_GOTO_WITH_ERROR("psPageArray[uiFreepgidx].uiAddr", eError, PVRSRV_ERROR_INVALID_PARAMS, e0); - } - } - }else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Given non-zero free count but missing indices array", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - /*The following block of code verifies any issues with common alloc page indices */ - for (ui32Loop = ui32AdtnlAllocPages; ui32Loop < ui32AllocPageCount; ui32Loop++) - { - uiAllocpgidx = pai32AllocIndices[ui32Loop]; - if (uiAllocpgidx >= psPMRPageArrayData->uiTotalNumPages) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE, e0); - } - - if ((INVALID_PAGE_ADDR != psPageArray[uiAllocpgidx].uiAddr) || - (TRANSLATION_INVALID != psPMRMapTable->aui32Translation[uiAllocpgidx])) - { - PVR_LOG_GOTO_WITH_ERROR("Trying to allocate already allocated page again", eError, PVRSRV_ERROR_INVALID_PARAMS, e0); - } - } - - - ui32Loop = 0; - - /* Allocate new pages */ - if (0 != ui32AdtnlAllocPages) - { - /* Say how many pages to allocate */ - psPMRPageArrayData->uiPagesToAlloc = ui32AdtnlAllocPages; - - eError = _AllocLMPages(psPMRPageArrayData, pai32AllocIndices); - PVR_LOG_GOTO_IF_ERROR(eError, "_AllocLMPages", e0); - - /* Mark the corresponding pages of translation table as valid */ - for (ui32Loop = 0; ui32Loop < ui32AdtnlAllocPages; ui32Loop++) - { - psPMRMapTable->aui32Translation[pai32AllocIndices[ui32Loop]] = pai32AllocIndices[ui32Loop]; - } - - psPMRMapTable->ui32NumPhysChunks += ui32AdtnlAllocPages; - } - - ui32Index = ui32Loop; - - /* Move the corresponding free pages to alloc request */ - for (ui32Loop = 0; ui32Loop < ui32CommonRequstCount; ui32Loop++, ui32Index++) - { - - uiAllocpgidx = pai32AllocIndices[ui32Index]; - uiFreepgidx = pai32FreeIndices[ui32Loop]; - psPageArray[uiAllocpgidx] = psPageArray[uiFreepgidx]; - - psPMRMapTable->aui32Translation[uiFreepgidx] = TRANSLATION_INVALID; - psPMRMapTable->aui32Translation[uiAllocpgidx] = uiAllocpgidx; - psPageArray[uiFreepgidx].uiAddr = INVALID_PAGE_ADDR; - - /* Be sure to honour the attributes associated with the allocation - * such as zeroing, poisoning etc. */ - if (psPMRPageArrayData->bPoisonOnAlloc) - { - eError = _PoisonAlloc(psPMRPageArrayData->psPhysHeap, - &psPMRPageArrayData->pasDevPAddr[uiAllocpgidx], - psPMRPageArrayData->uiContigAllocSize, - PVRSRV_POISON_ON_ALLOC_VALUE); - - /* Consider this as a soft failure and go ahead but log error to kernel log */ - if (eError != PVRSRV_OK) - { -#if defined(DEBUG) - bPoisonFail = IMG_TRUE; -#endif - } - } - else - { - if (psPMRPageArrayData->bZeroOnAlloc) - { - eError = _ZeroAlloc(psPMRPageArrayData->psPhysHeap, - &psPMRPageArrayData->pasDevPAddr[uiAllocpgidx], - psPMRPageArrayData->uiContigAllocSize); - /* Consider this as a soft failure and go ahead but log error to kernel log */ - if (eError != PVRSRV_OK) - { -#if defined(DEBUG) - /*Don't think we need to zero any pages further*/ - bZeroFail = IMG_TRUE; -#endif - } - } - } - } - - /*Free the additional free pages */ - if (0 != ui32AdtnlFreePages) - { - ui32Index = ui32Loop; - _FreeLMPages(psPMRPageArrayData, &pai32FreeIndices[ui32Loop], ui32AdtnlFreePages); - ui32Loop = 0; - - while (ui32Loop++ < ui32AdtnlFreePages) - { - /*Set the corresponding mapping table entry to invalid address */ - psPMRMapTable->aui32Translation[pai32FreeIndices[ui32Index++]] = TRANSLATION_INVALID; - } - - psPMRMapTable->ui32NumPhysChunks -= ui32AdtnlFreePages; - } - - } - -#if defined(DEBUG) - if (IMG_TRUE == bPoisonFail) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error in poisoning the page", __func__)); - } - - if (IMG_TRUE == bZeroFail) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error in zeroing the page", __func__)); - } -#endif - - /* Update the PMR memory holding information */ - eError = PVRSRV_OK; - -e0: - return eError; -} - -/*************************************************************************/ /*! -@Function PMRChangeSparseMemCPUMapLocalMem -@Description This function Changes CPU maps accordingly -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -static -PVRSRV_ERROR PMRChangeSparseMemCPUMapLocalMem(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT64 sCpuVAddrBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices) -{ - PVRSRV_ERROR eError; - IMG_DEV_PHYADDR *psPageArray; - PMR_LMALLOCARRAY_DATA *psPMRPageArrayData = (PMR_LMALLOCARRAY_DATA *)pPriv; - uintptr_t sCpuVABase = sCpuVAddrBase; - IMG_CPU_PHYADDR sCpuAddrPtr; - IMG_BOOL bValid = IMG_FALSE; - - /*Get the base address of the heap */ - eError = PMR_CpuPhysAddr(psPMR, - psPMRPageArrayData->uiLog2AllocSize, - 1, - 0, /* offset zero here mean first page in the PMR */ - &sCpuAddrPtr, - &bValid); - PVR_LOG_RETURN_IF_ERROR(eError, "PMR_CpuPhysAddr"); - - /* Phys address of heap is computed here by subtracting the offset of this page - * basically phys address of any page = Base address of heap + offset of the page */ - sCpuAddrPtr.uiAddr -= psPMRPageArrayData->pasDevPAddr[0].uiAddr; - psPageArray = psPMRPageArrayData->pasDevPAddr; - - return OSChangeSparseMemCPUAddrMap((void **)psPageArray, - sCpuVABase, - sCpuAddrPtr, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices, - IMG_TRUE); -} - -static PMR_IMPL_FUNCTAB _sPMRLMAFuncTab = { - .pfnLockPhysAddresses = &PMRLockSysPhysAddressesLocalMem, - .pfnUnlockPhysAddresses = &PMRUnlockSysPhysAddressesLocalMem, - .pfnDevPhysAddr = &PMRSysPhysAddrLocalMem, - .pfnAcquireKernelMappingData = &PMRAcquireKernelMappingDataLocalMem, - .pfnReleaseKernelMappingData = &PMRReleaseKernelMappingDataLocalMem, - .pfnReadBytes = &PMRReadBytesLocalMem, - .pfnWriteBytes = &PMRWriteBytesLocalMem, - .pfnChangeSparseMem = &PMRChangeSparseMemLocalMem, - .pfnChangeSparseMemCPUMap = &PMRChangeSparseMemCPUMapLocalMem, - .pfnFinalize = &PMRFinalizeLocalMem, -}; - -PVRSRV_ERROR -PhysmemNewLocalRamBackedPMR(PHYS_HEAP *psPhysHeap, - CONNECTION_DATA *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2AllocPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - PMR *psPMR = NULL; - PMR_LMALLOCARRAY_DATA *psPrivData = NULL; - PMR_FLAGS_T uiPMRFlags; - IMG_BOOL bZero; - IMG_BOOL bPoisonOnAlloc; - IMG_BOOL bPoisonOnFree; - IMG_BOOL bOnDemand; - IMG_BOOL bContig; - - /* For sparse requests we have to do the allocation - * in chunks rather than requesting one contiguous block */ - if (ui32NumPhysChunks != ui32NumVirtChunks || ui32NumVirtChunks > 1) - { - if (PVRSRV_CHECK_KERNEL_CPU_MAPPABLE(uiFlags)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: LMA kernel mapping functions currently " - "don't work with discontiguous memory.", - __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, errorOnParam); - } - bContig = IMG_FALSE; - } - else - { - bContig = IMG_TRUE; - } - - bOnDemand = PVRSRV_CHECK_ON_DEMAND(uiFlags) ? IMG_TRUE : IMG_FALSE; - bZero = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags) ? IMG_TRUE : IMG_FALSE; - bPoisonOnAlloc = PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags) ? IMG_TRUE : IMG_FALSE; -#if defined(DEBUG) - bPoisonOnFree = PVRSRV_CHECK_POISON_ON_FREE(uiFlags) ? IMG_TRUE : IMG_FALSE; -#else - bPoisonOnFree = IMG_FALSE; -#endif - - /* Create Array structure that holds the physical pages */ - eError = _AllocLMPageArray(uiChunkSize * ui32NumVirtChunks, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2AllocPageSize, - bZero, - bPoisonOnAlloc, - bPoisonOnFree, - bContig, - bOnDemand, - psPhysHeap, - uiFlags, - uiPid, - &psPrivData, - psConnection); - PVR_GOTO_IF_ERROR(eError, errorOnAllocPageArray); - - if (!bOnDemand) - { - /* Allocate the physical pages */ - eError = _AllocLMPages(psPrivData, pui32MappingTable); - PVR_GOTO_IF_ERROR(eError, errorOnAllocPages); - } - - /* In this instance, we simply pass flags straight through. - - Generically, uiFlags can include things that control the PMR - factory, but we don't need any such thing (at the time of - writing!), and our caller specifies all PMR flags so we don't - need to meddle with what was given to us. - */ - uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK); - /* check no significant bits were lost in cast due to different - bit widths for flags */ - PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK)); - - if (bOnDemand) - { - PDUMPCOMMENT(PhysHeapDeviceNode(psPhysHeap), "Deferred Allocation PMR (LMA)"); - } - - eError = PMRCreatePMR(psPhysHeap, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2AllocPageSize, - uiPMRFlags, - pszAnnotation, - &_sPMRLMAFuncTab, - psPrivData, - PMR_TYPE_LMA, - &psPMR, - ui32PDumpFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRCreatePMR", errorOnCreate); - - *ppsPMRPtr = psPMR; - return PVRSRV_OK; - -errorOnCreate: - if (!bOnDemand && psPrivData->iNumPagesAllocated) - { - eError2 = _FreeLMPages(psPrivData, NULL, 0); - PVR_ASSERT(eError2 == PVRSRV_OK); - } - -errorOnAllocPages: - eError2 = _FreeLMPageArray(psPrivData); - PVR_ASSERT(eError2 == PVRSRV_OK); - -errorOnAllocPageArray: -errorOnParam: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_lma.h b/drivers/gpu/drm/img-rogue/1.17/physmem_lma.h deleted file mode 100644 index 51f4257b5a826..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_lma.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Header for local card memory allocator -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - implementing the function callbacks for local card memory. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PHYSMEM_LMA_H -#define SRVSRV_PHYSMEM_LMA_H - -/* include/ */ -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" - -/* services/server/include/ */ -#include "pmr.h" -#include "pmr_impl.h" - -/*************************************************************************/ /*! -@Function PhysmemCreateHeapLMA -@Description Create and register new LMA heap with LMA specific details. -@Input psDevNode Pointer to device node struct. -@Input psConfig Heap configuration. -@Input pszLabel Debug identifier label -@Output ppsPhysHeap Pointer to the created heap. -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysmemCreateHeapLMA(PVRSRV_DEVICE_NODE *psDevNode, - PHYS_HEAP_CONFIG *psConfig, - IMG_CHAR *pszLabel, - PHYS_HEAP **ppsPhysHeap); - -/* - * PhysmemNewLocalRamBackedPMR - * - * This function will create a PMR using the local card memory and is OS - * agnostic. - */ -PVRSRV_ERROR -PhysmemNewLocalRamBackedPMR(PHYS_HEAP *psPhysHeap, - CONNECTION_DATA *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags); - -#endif /* #ifndef SRVSRV_PHYSMEM_LMA_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem.h b/drivers/gpu/drm/img-rogue/1.17/physmem_osmem.h deleted file mode 100644 index 1eb7565309029..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem.h +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************/ /*! -@File physmem_osmem.h -@Title OS memory PMR factory API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of Services memory management. This file defines the - OS memory PMR factory API that must be defined so that the - common & device layer code in the Services Server can allocate - new PMRs back with pages from the OS page allocator. Applicable - for UMA based platforms, such platforms must implement this API - in the OS Porting layer, in the "env" directory for that - system. - -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PHYSMEM_OSMEM_H -#define PHYSMEM_OSMEM_H - -/* include/ */ -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" - -/* services/server/include/ */ -#include "pmr.h" -#include "pmr_impl.h" -#include "connection_server.h" -#include "physheap.h" - -/*************************************************************************/ /*! -@Function PhysmemNewOSRamBackedPMR -@Description Rogue Services will call this function to allocate GPU device - memory from the PMR factory supported by the OS DDK port. This - factory typically obtains physical memory from the kernel/OS - API that allocates memory from the default heap of shared - system memory available on the platform. The allocated memory - must be page-aligned and be a whole number of pages. - After allocating the required memory, the implementation must - then call PMRCreatePMR() to obtain the PMR structure that - describes this allocation to the upper layers of the Services. - memory management sub-system. - NB. Implementation of this function is mandatory. If shared - system memory is not to be used in the OS port then the - implementation must return PVRSRV_ERROR_NOT_SUPPORTED. - -@Input psPhysHeap the phys heap -@Input psConnection the connection to the originator process -@Input uiSize the size of the allocation - (must be a multiple of page size) -@Input uiChunkSize when sparse allocations are requested, - this is the allocated chunk size. - For regular allocations, this will be - the same as uiSize. - (must be a multiple of page size) -@Input ui32NumPhysChunks when sparse allocations are requested, - this is the number of physical chunks - to be allocated. - For regular allocations, this will be 1. -@Input ui32NumVirtChunks when sparse allocations are requested, - this is the number of virtual chunks - covering the sparse allocation. - For regular allocations, this will be 1. -@Input pui32MappingTable when sparse allocations are requested, - this is the list of the indices of - each physically-backed virtual chunk - For regular allocations, this will - be NULL. -@Input uiLog2PageSize the physical pagesize in log2(bytes). -@Input uiFlags the allocation flags. -@Input pszAnnotation string describing the PMR (for debug). - This should be passed into the function - PMRCreatePMR(). -@Input uiPid The process ID that this allocation should - be associated with. -@Output ppsPMROut pointer to the PMR created for the - new allocation -@Input ui32PDumpFlags the pdump flags. -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR -PhysmemNewOSRamBackedPMR(PHYS_HEAP *psPhysHeap, - CONNECTION_DATA *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMROut, - IMG_UINT32 ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function PhysmemGetOSRamMemStats -@Description Function that gets the OS memory usage statistics -@Input pvImplData Physical heap private data. -@Output pui64TotalSize Buffer that holds the total OS memory size -@Output pui64FreeSize Buffer that holds the free OS memory size -@Return None. -*/ /**************************************************************************/ -void PhysmemGetOSRamMemStats(PHEAP_IMPL_DATA pvImplData, - IMG_UINT64 *pui64TotalSize, - IMG_UINT64 *pui64FreeSize); - -#endif /* PHYSMEM_OSMEM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.c b/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.c deleted file mode 100644 index 7e629fc87dfa5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.c +++ /dev/null @@ -1,3950 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Implementation of PMR functions for OS managed memory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - implementing the function callbacks for physical memory borrowed - from that normally managed by the operating system. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_X86) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)) -#include -#else -#include -#endif -#endif - -/* include/ */ -#include "rgx_heaps.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "rgx_pdump_panics.h" -/* services/server/include/ */ -#include "allocmem.h" -#include "osfunc.h" -#include "pdump_km.h" -#include "pmr.h" -#include "pmr_impl.h" -#include "cache_km.h" -#include "devicemem_server_utils.h" -#include "pvr_vmap.h" -#include "physheap.h" - -/* ourselves */ -#include "physmem_osmem.h" -#include "physmem_osmem_linux.h" - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#if !defined(PVRSRV_ENABLE_MEMORY_STATS) -#include "hash.h" -#endif -#endif - -#include "kernel_compatibility.h" - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -static IMG_UINT32 g_uiMaxOrder = PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM; -#else -/* split_page not available on older kernels */ -#undef PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM -#define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM 0 -static IMG_UINT32 g_uiMaxOrder; -#endif - -/* - These corresponds to the MMU min/max page sizes and associated PTE - alignment that can be used on the device for an allocation. It is - 4KB (min) and 2MB (max) respectively. -*/ -#define PVR_MIN_PHYSMEM_CONTIG_ALLOC_LOG2PGSZ RGX_HEAP_4KB_PAGE_SHIFT -#define PVR_MAX_PHYSMEM_CONTIG_ALLOC_LOG2PGSZ RGX_HEAP_2MB_PAGE_SHIFT - -/* Defines how many pages should be mapped at once to the kernel */ -#define PVR_LINUX_PHYSMEM_MAX_KMAP_PAGES 1024 /* 4 MB */ - -/* - These are used to get/set/mask lower-order bits in a dma_addr_t - to provide side-band information associated with that address. - These includes whether the address was obtained via alloc_page - or dma_alloc and if address came allocated pre-aligned or an - adjustment was made manually to aligned it. -*/ -#define DMA_SET_ADJUSTED_ADDR(x) ((x) | ((dma_addr_t)0x02)) -#define DMA_IS_ADDR_ADJUSTED(x) ((x) & ((dma_addr_t)0x02)) -#define DMA_SET_ALLOCPG_ADDR(x) ((x) | ((dma_addr_t)0x01)) -#define DMA_IS_ALLOCPG_ADDR(x) ((x) & ((dma_addr_t)0x01)) -#define DMA_GET_ALIGN_ADJUSTMENT(x) ((x>>2) & ((dma_addr_t)0x3ff)) -#define DMA_SET_ALIGN_ADJUSTMENT(x,y) ((x) | (((dma_addr_t)y)<<0x02)) -#define DMA_GET_ADDR(x) (((dma_addr_t)x) & ((dma_addr_t)~0xfff)) -#define DMA_VADDR_NOT_IN_USE 0xCAFEF00DDEADBEEFULL - -#define PVRSRV_ZERO_VALUE 0 - -typedef struct _PMR_OSPAGEARRAY_DATA_ { - /* Device for which this allocation has been made */ - PVRSRV_DEVICE_NODE *psDevNode; - /* The pid that made this allocation */ - IMG_PID uiPid; - - /* - * iNumOSPagesAllocated: - * Number of pages allocated in this PMR so far. - * This allows for up to (2^31 - 1) pages. With 4KB pages, that's 8TB of memory for each PMR. - */ - IMG_INT32 iNumOSPagesAllocated; - - /* - * uiTotalNumOSPages: - * Total number of pages supported by this PMR. (Fixed as of now due the fixed Page table array size) - * number of "pages" (a.k.a. macro pages, compound pages, higher order pages, etc...) - */ - IMG_UINT32 uiTotalNumOSPages; - - /* - uiLog2AllocPageSize; - - size of each "page" -- this would normally be the same as - PAGE_SHIFT, but we support the idea that we may allocate pages - in larger chunks for better contiguity, using order>0 in the - call to alloc_pages() - */ - IMG_UINT32 uiLog2AllocPageSize; - - /* - ui64DmaMask; - */ - IMG_UINT64 ui64DmaMask; - - /* - For non DMA/CMA allocation, pagearray references the pages - thus allocated; one entry per compound page when compound - pages are used. In addition, for DMA/CMA allocations, we - track the returned cpu virtual and device bus address. - */ - struct page **pagearray; - dma_addr_t *dmaphysarray; - void **dmavirtarray; - - -#define FLAG_ZERO (0U) -#define FLAG_POISON_ON_FREE (1U) -#define FLAG_POISON_ON_ALLOC (2U) -#define FLAG_ONDEMAND (3U) -#define FLAG_UNPINNED (4U) -#define FLAG_IS_CMA (5U) -#define FLAG_UNSET_MEMORY_TYPE (6U) - - /* - * Allocation flags related to the pages: - * Zero - Should we Zero memory on alloc - * Poison on free - Should we Poison the memory on free. - * Poison on alloc - Should we Poison the memory on alloc. - * On demand - Is the allocation on Demand i.e Do we defer allocation to time of use. - * Unpinned - Should be protected by page pool lock - * CMA - Is CMA memory allocated via DMA framework - * Unset Memory Type - Upon free do we need to revert the cache type before return to OS - * */ - IMG_UINT32 ui32AllocFlags; - - /* - The cache mode of the PMR. Additionally carrying the CPU-Cache-Clean - flag, advising us to do cache maintenance on behalf of the caller. - Boolean used to track if we need to revert the cache attributes - of the pages used in this allocation. Depends on OS/architecture. - */ - IMG_UINT32 ui32CPUCacheFlags; - /* - * In CMA allocation path, algorithm can allocate double the size of - * requested allocation size to satisfy the alignment. In this case - * the additional pages allocated are tracked through this additional - * variable and are accounted for in the memory statistics */ - IMG_UINT32 ui32CMAAdjustedPageCount; -} PMR_OSPAGEARRAY_DATA; - -/*********************************** - * Page pooling for uncached pages * - ***********************************/ - -static INLINE void -_FreeOSPage_CMA(struct device *dev, - size_t alloc_size, - IMG_UINT32 uiOrder, - void *virt_addr, - dma_addr_t dev_addr, - struct page *psPage); - -static void -_FreeOSPage(IMG_UINT32 uiOrder, - IMG_BOOL bUnsetMemoryType, - struct page *psPage); - -static PVRSRV_ERROR -_FreeOSPages(PMR_OSPAGEARRAY_DATA *psPageArrayData, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 ui32FreePageCount); - -static PVRSRV_ERROR -_FreePagesFromPoolUnlocked(IMG_UINT32 uiMaxPagesToFree, - IMG_UINT32 *puiPagesFreed); - -/* A struct for our page pool holding an array of zeroed (!) pages. - * We always put units of page arrays to the pool but are - * able to take individual pages */ -typedef struct -{ - /* Linkage for page pool LRU list */ - struct list_head sPagePoolItem; - - /* How many items are still in the page array */ - IMG_UINT32 uiItemsRemaining; - /* Array of the actual pages */ - struct page **ppsPageArray; - -} LinuxPagePoolEntry; - -/* CleanupThread structure to put allocation in page pool */ -typedef struct -{ - PVRSRV_CLEANUP_THREAD_WORK sCleanupWork; - IMG_UINT32 ui32CPUCacheMode; - LinuxPagePoolEntry *psPoolEntry; -} LinuxCleanupData; - -/* A struct for the unpinned items */ -typedef struct -{ - struct list_head sUnpinPoolItem; - PMR_OSPAGEARRAY_DATA *psPageArrayDataPtr; -} LinuxUnpinEntry; - - -/* Caches to hold page pool and page array structures */ -static struct kmem_cache *g_psLinuxPagePoolCache; -static struct kmem_cache *g_psLinuxPageArray; - -/* Track what is live, all protected by pool lock. - * x86 needs two page pools because we have to change the memory attributes - * of the pages which is expensive due to an implicit flush. - * See set_pages_array_uc/wc/wb. */ -static IMG_UINT32 g_ui32UnpinPageCount; -static IMG_UINT32 g_ui32PagePoolUCCount; -#if defined(CONFIG_X86) -static IMG_UINT32 g_ui32PagePoolWCCount; -#endif -/* Tracks asynchronous tasks currently accessing the page pool. - * It is incremented if a defer free task - * is created. Both will decrement the value when they finished the work. - * The atomic prevents piling up of deferred work in case the deferred thread - * cannot keep up with the application.*/ -static ATOMIC_T g_iPoolCleanTasks; -/* We don't want too many asynchronous threads trying to access the page pool - * at the same time */ -#define PVR_LINUX_PHYSMEM_MAX_ASYNC_CLEAN_TASKS 128 - -/* Defines how many pages the page cache should hold. */ -#if defined(PVR_LINUX_PHYSMEM_MAX_POOL_PAGES) -static const IMG_UINT32 g_ui32PagePoolMaxEntries = PVR_LINUX_PHYSMEM_MAX_POOL_PAGES; -#else -static const IMG_UINT32 g_ui32PagePoolMaxEntries; -#endif - -/* We double check if we would exceed this limit if we are below MAX_POOL_PAGES - and want to add an allocation to the pool. - This prevents big allocations being given back to the OS just because they - exceed the MAX_POOL_PAGES limit even though the pool is currently empty. */ -#if defined(PVR_LINUX_PHYSMEM_MAX_EXCESS_POOL_PAGES) -static const IMG_UINT32 g_ui32PagePoolMaxExcessEntries = PVR_LINUX_PHYSMEM_MAX_EXCESS_POOL_PAGES; -#else -static const IMG_UINT32 g_ui32PagePoolMaxExcessEntries; -#endif - -#if defined(CONFIG_X86) -#define PHYSMEM_OSMEM_NUM_OF_POOLS 2 -static const IMG_UINT32 g_aui32CPUCacheFlags[PHYSMEM_OSMEM_NUM_OF_POOLS] = { - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC -}; -#else -#define PHYSMEM_OSMEM_NUM_OF_POOLS 1 -static const IMG_UINT32 g_aui32CPUCacheFlags[PHYSMEM_OSMEM_NUM_OF_POOLS] = { - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED -}; -#endif - -/* Global structures we use to manage the page pool */ -static DEFINE_MUTEX(g_sPagePoolMutex); - -/* List holding the page array pointers: */ -static LIST_HEAD(g_sPagePoolList_WC); -static LIST_HEAD(g_sPagePoolList_UC); -static LIST_HEAD(g_sUnpinList); - -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) -/* Global structure to manage GPU memory leak */ -static DEFINE_MUTEX(g_sUMALeakMutex); -static IMG_UINT32 g_ui32UMALeakCounter = 0; -#endif - -static inline IMG_UINT32 -_PagesInPoolUnlocked(void) -{ - IMG_UINT32 uiCnt = g_ui32PagePoolUCCount; -#if defined(CONFIG_X86) - uiCnt += g_ui32PagePoolWCCount; -#endif - return uiCnt; -} - -static inline void -_PagePoolLock(void) -{ - mutex_lock(&g_sPagePoolMutex); -} - -static inline int -_PagePoolTrylock(void) -{ - return mutex_trylock(&g_sPagePoolMutex); -} - -static inline void -_PagePoolUnlock(void) -{ - mutex_unlock(&g_sPagePoolMutex); -} - -static PVRSRV_ERROR -_AddUnpinListEntryUnlocked(PMR_OSPAGEARRAY_DATA *psOSPageArrayData) -{ - LinuxUnpinEntry *psUnpinEntry; - - psUnpinEntry = OSAllocMem(sizeof(*psUnpinEntry)); - if (!psUnpinEntry) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OSAllocMem failed. Cannot add entry to unpin list.", - __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psUnpinEntry->psPageArrayDataPtr = psOSPageArrayData; - - /* Add into pool that the shrinker can access easily*/ - list_add_tail(&psUnpinEntry->sUnpinPoolItem, &g_sUnpinList); - - g_ui32UnpinPageCount += psOSPageArrayData->iNumOSPagesAllocated; - - return PVRSRV_OK; -} - -static void -_RemoveUnpinListEntryUnlocked(PMR_OSPAGEARRAY_DATA *psOSPageArrayData) -{ - LinuxUnpinEntry *psUnpinEntry, *psTempUnpinEntry; - - /* Remove from pool */ - list_for_each_entry_safe(psUnpinEntry, - psTempUnpinEntry, - &g_sUnpinList, - sUnpinPoolItem) - { - if (psUnpinEntry->psPageArrayDataPtr == psOSPageArrayData) - { - list_del(&psUnpinEntry->sUnpinPoolItem); - break; - } - } - - OSFreeMem(psUnpinEntry); - - g_ui32UnpinPageCount -= psOSPageArrayData->iNumOSPagesAllocated; -} - -static inline IMG_BOOL -_GetPoolListHead(IMG_UINT32 ui32CPUCacheFlags, - struct list_head **ppsPoolHead, - IMG_UINT32 **ppuiCounter) -{ - switch (PVRSRV_CPU_CACHE_MODE(ui32CPUCacheFlags)) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: -#if defined(CONFIG_X86) - /* - For x86 we need to keep different lists for uncached - and write-combined as we must always honour the PAT - setting which cares about this difference. - */ - - *ppsPoolHead = &g_sPagePoolList_WC; - *ppuiCounter = &g_ui32PagePoolWCCount; - break; -#endif - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - *ppsPoolHead = &g_sPagePoolList_UC; - *ppuiCounter = &g_ui32PagePoolUCCount; - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Unknown CPU caching mode. " - "Using default UC pool.", - __func__)); - *ppsPoolHead = &g_sPagePoolList_UC; - *ppuiCounter = &g_ui32PagePoolUCCount; - PVR_ASSERT(0); - return IMG_FALSE; - } - return IMG_TRUE; -} - -static struct shrinker g_sShrinker; - -/* Returning the number of pages that still reside in the page pool. */ -static unsigned long -_GetNumberOfPagesInPoolUnlocked(void) -{ - return _PagesInPoolUnlocked() + g_ui32UnpinPageCount; -} - -/* Linux shrinker function that informs the OS about how many pages we are caching and - * it is able to reclaim. */ -static unsigned long -_CountObjectsInPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) -{ - int remain; - - PVR_ASSERT(psShrinker == &g_sShrinker); - (void)psShrinker; - (void)psShrinkControl; - - /* In order to avoid possible deadlock use mutex_trylock in place of mutex_lock */ - if (_PagePoolTrylock() == 0) - return 0; - remain = _GetNumberOfPagesInPoolUnlocked(); - _PagePoolUnlock(); - - return remain; -} - -/* Linux shrinker function to reclaim the pages from our page pool */ -static unsigned long -_ScanObjectsInPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) -{ - unsigned long uNumToScan = psShrinkControl->nr_to_scan; - unsigned long uSurplus = 0; - LinuxUnpinEntry *psUnpinEntry, *psTempUnpinEntry; - IMG_UINT32 uiPagesFreed; - - PVR_ASSERT(psShrinker == &g_sShrinker); - (void)psShrinker; - - /* In order to avoid possible deadlock use mutex_trylock in place of mutex_lock */ - if (_PagePoolTrylock() == 0) - return SHRINK_STOP; - - _FreePagesFromPoolUnlocked(uNumToScan, - &uiPagesFreed); - uNumToScan -= uiPagesFreed; - - if (uNumToScan == 0) - { - goto e_exit; - } - - /* Free unpinned memory, starting with LRU entries */ - list_for_each_entry_safe(psUnpinEntry, - psTempUnpinEntry, - &g_sUnpinList, - sUnpinPoolItem) - { - PMR_OSPAGEARRAY_DATA *psPageArrayDataPtr = psUnpinEntry->psPageArrayDataPtr; - IMG_UINT32 uiNumPages = (psPageArrayDataPtr->uiTotalNumOSPages > psPageArrayDataPtr->iNumOSPagesAllocated)? - psPageArrayDataPtr->iNumOSPagesAllocated:psPageArrayDataPtr->uiTotalNumOSPages; - PVRSRV_ERROR eError; - - /* Free associated pages */ - eError = _FreeOSPages(psPageArrayDataPtr, - NULL, - 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Shrinker is unable to free unpinned pages. Error: %s (%d)", - __func__, - PVRSRVGetErrorString(eError), - eError)); - goto e_exit; - } - - /* Remove item from pool */ - list_del(&psUnpinEntry->sUnpinPoolItem); - - g_ui32UnpinPageCount -= uiNumPages; - - /* Check if there is more to free or if we already surpassed the limit */ - if (uiNumPages < uNumToScan) - { - uNumToScan -= uiNumPages; - - } - else if (uiNumPages > uNumToScan) - { - uSurplus += uiNumPages - uNumToScan; - uNumToScan = 0; - goto e_exit; - } - else - { - uNumToScan -= uiNumPages; - goto e_exit; - } - } - -e_exit: - if (list_empty(&g_sUnpinList)) - { - PVR_ASSERT(g_ui32UnpinPageCount == 0); - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)) - { - int remain; - remain = _GetNumberOfPagesInPoolUnlocked(); - _PagePoolUnlock(); - return remain; - } -#else - /* Returning the number of pages freed during the scan */ - _PagePoolUnlock(); - return psShrinkControl->nr_to_scan - uNumToScan + uSurplus; -#endif -} - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)) -static int -_ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) -{ - if (psShrinkControl->nr_to_scan != 0) - { - return _ScanObjectsInPagePool(psShrinker, psShrinkControl); - } - else - { - /* No pages are being reclaimed so just return the page count */ - return _CountObjectsInPagePool(psShrinker, psShrinkControl); - } -} - -static struct shrinker g_sShrinker = -{ - .shrink = _ShrinkPagePool, - .seeks = DEFAULT_SEEKS -}; -#else -static struct shrinker g_sShrinker = -{ - .count_objects = _CountObjectsInPagePool, - .scan_objects = _ScanObjectsInPagePool, - .seeks = DEFAULT_SEEKS -}; -#endif - -/* Register the shrinker so Linux can reclaim cached pages */ -void LinuxInitPhysmem(void) -{ - g_psLinuxPageArray = kmem_cache_create("pvr-pa", sizeof(PMR_OSPAGEARRAY_DATA), 0, 0, NULL); - - g_psLinuxPagePoolCache = kmem_cache_create("pvr-pp", sizeof(LinuxPagePoolEntry), 0, 0, NULL); - if (g_psLinuxPagePoolCache) - { - /* Only create the shrinker if we created the cache OK */ - register_shrinker(&g_sShrinker, "physmem_osmem_linux"); - } - - OSAtomicWrite(&g_iPoolCleanTasks, 0); -} - -/* Unregister the shrinker and remove all pages from the pool that are still left */ -void LinuxDeinitPhysmem(void) -{ - IMG_UINT32 uiPagesFreed; - - if (OSAtomicRead(&g_iPoolCleanTasks) > 0) - { - PVR_DPF((PVR_DBG_WARNING, "Still deferred cleanup tasks running " - "while deinitialising memory subsystem.")); - } - - _PagePoolLock(); - if (_FreePagesFromPoolUnlocked(IMG_UINT32_MAX, &uiPagesFreed) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Unable to free all pages from page pool when " - "deinitialising memory subsystem.")); - PVR_ASSERT(0); - } - - PVR_ASSERT(_PagesInPoolUnlocked() == 0); - - /* Free the page cache */ - kmem_cache_destroy(g_psLinuxPagePoolCache); - - unregister_shrinker(&g_sShrinker); - _PagePoolUnlock(); - - kmem_cache_destroy(g_psLinuxPageArray); -} - -static void EnableOOMKiller(void) -{ - current->flags &= ~PF_DUMPCORE; -} - -static void DisableOOMKiller(void) -{ - /* PF_DUMPCORE is treated by the VM as if the OOM killer was disabled. - * - * As oom_killer_disable() is an inline, non-exported function, we - * can't use it from a modular driver. Furthermore, the OOM killer - * API doesn't look thread safe, which 'current' is. - */ - WARN_ON(current->flags & PF_DUMPCORE); - current->flags |= PF_DUMPCORE; -} - -/* Prints out the addresses in a page array for debugging purposes - * Define PHYSMEM_OSMEM_DEBUG_DUMP_PAGE_ARRAY locally to activate: */ -/* #define PHYSMEM_OSMEM_DEBUG_DUMP_PAGE_ARRAY 1 */ -static inline void -_DumpPageArray(struct page **pagearray, IMG_UINT32 uiPagesToPrint) -{ -#if defined(PHYSMEM_OSMEM_DEBUG_DUMP_PAGE_ARRAY) - IMG_UINT32 i; - if (pagearray) - { - printk("Array %p:\n", pagearray); - for (i = 0; i < uiPagesToPrint; i++) - { - printk("%p | ", (pagearray)[i]); - } - printk("\n"); - } - else - { - printk("Array is NULL:\n"); - } -#else - PVR_UNREFERENCED_PARAMETER(pagearray); - PVR_UNREFERENCED_PARAMETER(uiPagesToPrint); -#endif -} - -/* Debugging function that dumps out the number of pages for every - * page array that is currently in the page pool. - * Not defined by default. Define locally to activate feature: */ -/* #define PHYSMEM_OSMEM_DEBUG_DUMP_PAGE_POOL 1 */ -static void -_DumpPoolStructure(void) -{ -#if defined(PHYSMEM_OSMEM_DEBUG_DUMP_PAGE_POOL) - LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry; - struct list_head *psPoolHead = NULL; - IMG_UINT32 j; - IMG_UINT32 *puiCounter; - - printk("\n"); - /* Empty all pools */ - for (j = 0; j < PHYSMEM_OSMEM_NUM_OF_POOLS; j++) - { - - printk("pool = %u\n", j); - - /* Get the correct list for this caching mode */ - if (!_GetPoolListHead(g_aui32CPUCacheFlags[j], &psPoolHead, &puiCounter)) - { - break; - } - - list_for_each_entry_safe(psPagePoolEntry, - psTempPoolEntry, - psPoolHead, - sPagePoolItem) - { - printk("%u | ", psPagePoolEntry->uiItemsRemaining); - } - printk("\n"); - } -#endif -} - -/* Free a certain number of pages from the page pool. - * Mainly used in error paths or at deinitialisation to - * empty the whole pool. */ -static PVRSRV_ERROR -_FreePagesFromPoolUnlocked(IMG_UINT32 uiMaxPagesToFree, - IMG_UINT32 *puiPagesFreed) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry; - struct list_head *psPoolHead = NULL; - IMG_UINT32 i, j; - IMG_UINT32 *puiCounter; - - *puiPagesFreed = uiMaxPagesToFree; - - /* Empty all pools */ - for (j = 0; j < PHYSMEM_OSMEM_NUM_OF_POOLS; j++) - { - - /* Get the correct list for this caching mode */ - if (!_GetPoolListHead(g_aui32CPUCacheFlags[j], &psPoolHead, &puiCounter)) - { - break; - } - - /* Free the pages and remove page arrays from the pool if they are exhausted */ - list_for_each_entry_safe(psPagePoolEntry, - psTempPoolEntry, - psPoolHead, - sPagePoolItem) - { - IMG_UINT32 uiItemsToFree; - struct page **ppsPageArray; - - /* Check if we are going to free the whole page array or just parts */ - if (psPagePoolEntry->uiItemsRemaining <= uiMaxPagesToFree) - { - uiItemsToFree = psPagePoolEntry->uiItemsRemaining; - ppsPageArray = psPagePoolEntry->ppsPageArray; - } - else - { - uiItemsToFree = uiMaxPagesToFree; - ppsPageArray = &(psPagePoolEntry->ppsPageArray[psPagePoolEntry->uiItemsRemaining - uiItemsToFree]); - } - -#if defined(CONFIG_X86) - /* Set the correct page caching attributes on x86 */ - if (!PVRSRV_CHECK_CPU_CACHED(g_aui32CPUCacheFlags[j])) - { - int ret; - ret = set_pages_array_wb(ppsPageArray, uiItemsToFree); - if (ret) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to reset page attributes", - __func__)); - eError = PVRSRV_ERROR_FAILED_TO_FREE_PAGES; - goto e_exit; - } - } -#endif - - /* Free the actual pages */ - for (i = 0; i < uiItemsToFree; i++) - { - __free_pages(ppsPageArray[i], 0); - ppsPageArray[i] = NULL; - } - - /* Reduce counters */ - uiMaxPagesToFree -= uiItemsToFree; - *puiCounter -= uiItemsToFree; - psPagePoolEntry->uiItemsRemaining -= uiItemsToFree; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - /* - * MemStats usually relies on having the bridge lock held, however - * the page pool code may call PVRSRVStatsIncrMemAllocPoolStat and - * PVRSRVStatsDecrMemAllocPoolStat without the bridge lock held, so - * the page pool lock is used to ensure these calls are mutually - * exclusive - */ - PVRSRVStatsDecrMemAllocPoolStat(PAGE_SIZE * uiItemsToFree); -#endif - - /* Is this pool entry exhausted, delete it */ - if (psPagePoolEntry->uiItemsRemaining == 0) - { - OSFreeMemNoStats(psPagePoolEntry->ppsPageArray); - list_del(&psPagePoolEntry->sPagePoolItem); - kmem_cache_free(g_psLinuxPagePoolCache, psPagePoolEntry); - } - - /* Return if we have all our pages */ - if (uiMaxPagesToFree == 0) - { - goto e_exit; - } - } - } - -e_exit: - *puiPagesFreed -= uiMaxPagesToFree; - _DumpPoolStructure(); - return eError; -} - -/* Get a certain number of pages from the page pool and - * copy them directly into a given page array. */ -static void -_GetPagesFromPoolUnlocked(IMG_UINT32 ui32CPUCacheFlags, - IMG_UINT32 uiMaxNumPages, - struct page **ppsPageArray, - IMG_UINT32 *puiNumReceivedPages) -{ - LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry; - struct list_head *psPoolHead = NULL; - IMG_UINT32 i; - IMG_UINT32 *puiCounter; - - *puiNumReceivedPages = 0; - - /* Get the correct list for this caching mode */ - if (!_GetPoolListHead(ui32CPUCacheFlags, &psPoolHead, &puiCounter)) - { - return; - } - - /* Check if there are actually items in the list */ - if (list_empty(psPoolHead)) - { - return; - } - - PVR_ASSERT(*puiCounter > 0); - - /* Receive pages from the pool */ - list_for_each_entry_safe(psPagePoolEntry, - psTempPoolEntry, - psPoolHead, - sPagePoolItem) - { - /* Get the pages from this pool entry */ - for (i = psPagePoolEntry->uiItemsRemaining; i != 0 && *puiNumReceivedPages < uiMaxNumPages; i--) - { - ppsPageArray[*puiNumReceivedPages] = psPagePoolEntry->ppsPageArray[i-1]; - (*puiNumReceivedPages)++; - psPagePoolEntry->uiItemsRemaining--; - } - - /* Is this pool entry exhausted, delete it */ - if (psPagePoolEntry->uiItemsRemaining == 0) - { - OSFreeMemNoStats(psPagePoolEntry->ppsPageArray); - list_del(&psPagePoolEntry->sPagePoolItem); - kmem_cache_free(g_psLinuxPagePoolCache, psPagePoolEntry); - } - - /* Return if we have all our pages */ - if (*puiNumReceivedPages == uiMaxNumPages) - { - goto exit_ok; - } - } - -exit_ok: - - /* Update counters */ - *puiCounter -= *puiNumReceivedPages; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - /* MemStats usually relies on having the bridge lock held, however - * the page pool code may call PVRSRVStatsIncrMemAllocPoolStat and - * PVRSRVStatsDecrMemAllocPoolStat without the bridge lock held, so - * the page pool lock is used to ensure these calls are mutually - * exclusive - */ - PVRSRVStatsDecrMemAllocPoolStat(PAGE_SIZE * (*puiNumReceivedPages)); -#endif - - _DumpPoolStructure(); - return; -} - -/* Same as _GetPagesFromPoolUnlocked but handles locking and - * checks first whether pages from the pool are a valid option. */ -static inline void -_GetPagesFromPoolLocked(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32CPUCacheFlags, - IMG_UINT32 uiPagesToAlloc, - IMG_UINT32 uiOrder, - IMG_BOOL bZero, - struct page **ppsPageArray, - IMG_UINT32 *puiPagesFromPool) -{ -#if defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) - PVR_UNREFERENCED_PARAMETER(bZero); -#else - /* Don't get pages from pool if it doesn't provide zeroed pages */ - if (bZero) - { - return; - } -#endif - - /* The page pool stores only order 0 pages. If we need zeroed memory we - * directly allocate from the OS because it is faster than - * doing it within the driver. */ - if (uiOrder == 0 && - !PVRSRV_CHECK_CPU_CACHED(ui32CPUCacheFlags)) - { - - _PagePoolLock(); - _GetPagesFromPoolUnlocked(ui32CPUCacheFlags, - uiPagesToAlloc, - ppsPageArray, - puiPagesFromPool); - _PagePoolUnlock(); - } - - return; -} - -/* Takes a page array and maps it into the kernel to write zeros */ -static PVRSRV_ERROR -_MemsetPageArray(IMG_UINT32 uiNumToClean, - struct page **ppsCleanArray, - pgprot_t pgprot, - IMG_UINT8 ui8Pattern) -{ - IMG_CPU_VIRTADDR pvAddr; - IMG_UINT32 uiMaxPagesToMap = MIN(PVR_LINUX_PHYSMEM_MAX_KMAP_PAGES, - uiNumToClean); - - /* Map and fill the pages with zeros. - * For large page arrays do it PVR_LINUX_PHYSMEM_MAX_KMAP_SIZE - * at a time. */ - while (uiNumToClean != 0) - { - IMG_UINT32 uiToClean = MIN(uiNumToClean, uiMaxPagesToMap); - - pvAddr = pvr_vmap(ppsCleanArray, uiToClean, VM_WRITE, pgprot); - if (!pvAddr) - { - if (uiMaxPagesToMap <= 1) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Out of vmalloc memory, unable to map pages for %s.", - __func__, - ui8Pattern == PVRSRV_ZERO_VALUE ? "zeroing" : "poisoning")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - else - { - /* Halve the pages to map at once and try again. */ - uiMaxPagesToMap = uiMaxPagesToMap >> 1; - continue; - } - } - - if (pgprot_val(pgprot) == pgprot_val(pgprot_noncached(PAGE_KERNEL))) - { - /* this is most likely unnecessary as all pages must be 8-bytes - * aligned so there unaligned access is impossible */ - OSDeviceMemSet(pvAddr, ui8Pattern, PAGE_SIZE * uiToClean); - } - else if (pgprot_val(pgprot) == pgprot_val(pgprot_writecombine(PAGE_KERNEL))) - { - OSCachedMemSetWMB(pvAddr, ui8Pattern, PAGE_SIZE * uiToClean); - } - else - { - OSCachedMemSet(pvAddr, ui8Pattern, PAGE_SIZE * uiToClean); - } - pvr_vunmap(pvAddr, uiToClean, pgprot); - ppsCleanArray = &(ppsCleanArray[uiToClean]); - uiNumToClean -= uiToClean; - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_CleanupThread_CleanPages(void *pvData) -{ - LinuxCleanupData *psCleanupData = (LinuxCleanupData*) pvData; - LinuxPagePoolEntry *psPagePoolEntry = psCleanupData->psPoolEntry; - struct list_head *psPoolHead = NULL; - IMG_UINT32 *puiCounter = NULL; -#if defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) - PVRSRV_ERROR eError; - pgprot_t pgprot; - IMG_UINT32 i; -#endif /* defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) */ - - /* Get the correct pool for this caching mode. */ - _GetPoolListHead(psCleanupData->ui32CPUCacheMode , &psPoolHead, &puiCounter); - -#if defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) - switch (PVRSRV_CPU_CACHE_MODE(psCleanupData->ui32CPUCacheMode)) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: -#if defined(CONFIG_X86) - /* For x86 we can only map with the same attributes - * as in the PAT settings*/ - pgprot = pgprot_noncached(PAGE_KERNEL); - break; -#endif - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: - pgprot = pgprot_writecombine(PAGE_KERNEL); - break; - - default: - PVR_DPF((PVR_DBG_ERROR, - "%s: Unknown caching mode to set page protection flags.", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto eExit; - } - - /* Map and fill the pages with zeros. - * For large page arrays do it PVR_LINUX_PHYSMEM_MAX_KMAP_SIZE - * at a time. */ - eError = _MemsetPageArray(psPagePoolEntry->uiItemsRemaining, - psPagePoolEntry->ppsPageArray, - pgprot, PVRSRV_ZERO_VALUE); - if (eError != PVRSRV_OK) - { - goto eExit; - } -#endif /* defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) */ - - /* Lock down pool and add item */ - _PagePoolLock(); - - /* Pool counters were already updated so don't do it here again*/ - - /* The pages are all zeroed so return them to the pool. */ - list_add_tail(&psPagePoolEntry->sPagePoolItem, psPoolHead); - - _DumpPoolStructure(); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - /* Calling PVRSRVStatsIncrMemAllocPoolStat and PVRSRVStatsDecrMemAllocPoolStat - * inside page pool lock ensures that the stat reflects the state of the pool. */ - PVRSRVStatsIncrMemAllocPoolStat(PAGE_SIZE * psPagePoolEntry->uiItemsRemaining); -#endif - - _PagePoolUnlock(); - - OSFreeMem(pvData); - OSAtomicDecrement(&g_iPoolCleanTasks); - - return PVRSRV_OK; - -#if defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) -eExit: - /* we failed to zero the pages so return the error so we can - * retry during the next spin */ - if ((psCleanupData->sCleanupWork.ui32RetryCount - 1) > 0) - { - return eError; - } - - /* this was the last retry, give up and free pages to OS */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Deferred task error, freeing pages to OS.", - __func__)); - _PagePoolLock(); - - *puiCounter -= psPagePoolEntry->uiItemsRemaining; - - _PagePoolUnlock(); - - for (i = 0; i < psCleanupData->psPoolEntry->uiItemsRemaining; i++) - { - _FreeOSPage(0, IMG_TRUE, psPagePoolEntry->ppsPageArray[i]); - } - OSFreeMemNoStats(psPagePoolEntry->ppsPageArray); - kmem_cache_free(g_psLinuxPagePoolCache, psPagePoolEntry); - OSFreeMem(psCleanupData); - - OSAtomicDecrement(&g_iPoolCleanTasks); - - return PVRSRV_OK; -#endif /* defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) */ -} - -static bool _PagesHaveOtherRefs(struct page **ppsPageArray, IMG_UINT32 uiNumPages) -{ - IMG_UINT32 ui32pageIndex; - - PVR_DPF_ENTERED; - - if (!ppsPageArray) - { - PVR_DPF_RETURN_RC(false); - } - - /* Iterate pages in ppsPageArray and return false if any are found - * to have page_count() > 1. */ - for (ui32pageIndex = 0; ui32pageIndex < uiNumPages; ui32pageIndex++) - { - struct page *psPage = ppsPageArray[ui32pageIndex]; - - if (page_count(psPage) > 1) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: page %d in page array found with page_count() of %d\n", - __func__, ui32pageIndex, page_count(psPage))); - PVR_DPF_RETURN_RC(true); - } - } - - PVR_DPF_RETURN_RC(false); -} - -/* Put page array to the page pool. - * Handles locking and checks whether the pages are - * suitable to be stored in the pool. */ -static inline IMG_BOOL -_PutPagesToPoolLocked(IMG_UINT32 ui32CPUCacheFlags, - struct page **ppsPageArray, - IMG_BOOL bUnpinned, - IMG_UINT32 uiOrder, - IMG_UINT32 uiNumPages) -{ - LinuxCleanupData *psCleanupData; - PVRSRV_CLEANUP_THREAD_WORK *psCleanupThreadFn; -#if defined(SUPPORT_PHYSMEM_TEST) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); -#endif - - if (uiOrder == 0 && - !bUnpinned && - !PVRSRV_CHECK_CPU_CACHED(ui32CPUCacheFlags)) - { - IMG_UINT32 uiEntries; - IMG_UINT32 *puiCounter; - struct list_head *psPoolHead; - - if (_PagesHaveOtherRefs(ppsPageArray, uiNumPages)) - { - /* Pages still have other references, so - * must not be put into our pool. */ - goto eExitFalse; - } - - _PagePoolLock(); - - uiEntries = _PagesInPoolUnlocked(); - - /* Check for number of current page pool entries and whether - * we have other asynchronous tasks in-flight */ - if ( (uiEntries < g_ui32PagePoolMaxEntries) && - ((uiEntries + uiNumPages) < - (g_ui32PagePoolMaxEntries + g_ui32PagePoolMaxExcessEntries) )) - { - if (OSAtomicIncrement(&g_iPoolCleanTasks) <= - PVR_LINUX_PHYSMEM_MAX_ASYNC_CLEAN_TASKS) - { -#if defined(SUPPORT_PHYSMEM_TEST) - if (!psPVRSRVData->hCleanupThread) - { - goto eDecrement; - } -#endif - - psCleanupData = OSAllocMem(sizeof(*psCleanupData)); - - if (!psCleanupData) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to get memory for deferred page pool cleanup. " - "Trying to free pages immediately", - __func__)); - goto eDecrement; - } - - psCleanupThreadFn = &psCleanupData->sCleanupWork; - psCleanupData->ui32CPUCacheMode = ui32CPUCacheFlags; - psCleanupData->psPoolEntry = kmem_cache_alloc(g_psLinuxPagePoolCache, GFP_KERNEL); - - if (!psCleanupData->psPoolEntry) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to get memory for deferred page pool cleanup. " - "Trying to free pages immediately", - __func__)); - goto eFreeCleanupData; - } - - if (!_GetPoolListHead(ui32CPUCacheFlags, &psPoolHead, &puiCounter)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to get correct page pool", - __func__)); - goto eFreePoolEntry; - } - - /* Increase counter here to avoid deferred cleanup tasks piling up */ - *puiCounter = *puiCounter + uiNumPages; - - psCleanupData->psPoolEntry->ppsPageArray = ppsPageArray; - psCleanupData->psPoolEntry->uiItemsRemaining = uiNumPages; - - psCleanupThreadFn->pfnFree = _CleanupThread_CleanPages; - psCleanupThreadFn->pvData = psCleanupData; - psCleanupThreadFn->bDependsOnHW = IMG_FALSE; - CLEANUP_THREAD_SET_RETRY_COUNT(psCleanupThreadFn, - CLEANUP_THREAD_RETRY_COUNT_DEFAULT); - - /* We must not hold the pool lock when calling AddWork because it might call us back to - * free pooled pages directly when unloading the driver */ - _PagePoolUnlock(); - - PVRSRVCleanupThreadAddWork(psCleanupThreadFn); - - - } - else - { - goto eDecrement; - } - - } - else - { - goto eUnlock; - } - } - else - { - goto eExitFalse; - } - - return IMG_TRUE; - -eFreePoolEntry: - OSFreeMem(psCleanupData->psPoolEntry); -eFreeCleanupData: - OSFreeMem(psCleanupData); -eDecrement: - OSAtomicDecrement(&g_iPoolCleanTasks); -eUnlock: - _PagePoolUnlock(); -eExitFalse: - return IMG_FALSE; -} - -/* Get the GFP flags that we pass to the page allocator */ -static inline gfp_t -_GetGFPFlags(IMG_BOOL bZero, - PVRSRV_DEVICE_NODE *psDevNode) -{ - struct device *psDev = psDevNode->psDevConfig->pvOSDevice; - gfp_t gfp_flags = GFP_USER | __GFP_NOWARN | __GFP_NOMEMALLOC; - -#if defined(PVR_LINUX_PHYSMEM_USE_HIGHMEM_ONLY) - /* Force use of HIGHMEM */ - gfp_flags |= __GFP_HIGHMEM; - - PVR_UNREFERENCED_PARAMETER(psDev); -#else - if (psDev) - { -#if defined(CONFIG_64BIT) || defined(CONFIG_ARM_LPAE) || defined(CONFIG_X86_PAE) - if (*psDev->dma_mask > DMA_BIT_MASK(32)) - { - /* If our system is able to handle large addresses use highmem */ - gfp_flags |= __GFP_HIGHMEM; - } - else if (*psDev->dma_mask == DMA_BIT_MASK(32)) - { - /* Limit to 32 bit. - * Achieved by setting __GFP_DMA32 for 64 bit systems */ - gfp_flags |= __GFP_DMA32; - } - else - { - /* Limit to size of DMA zone. */ - gfp_flags |= __GFP_DMA; - } -#else - if (*psDev->dma_mask < DMA_BIT_MASK(32)) - { - gfp_flags |= __GFP_DMA; - } - else - { - gfp_flags |= __GFP_HIGHMEM; - } -#endif /* if defined(CONFIG_64BIT) || defined(CONFIG_ARM_LPAE) || defined(CONFIG_X86_PAE) */ - } - -#endif /* if defined(PVR_LINUX_PHYSMEM_USE_HIGHMEM_ONLY) */ - - if (bZero) - { - gfp_flags |= __GFP_ZERO; - } - - return gfp_flags; -} - -/* - * @Function _PoisonDevicePage - * - * @Description Poisons a device page. In normal case the device page has the - * same size as the OS page and so the ui32DevPageOrder will be - * equal to 0 and page argument will point to one OS page - * structure. In case of Non4K pages the order will be greater - * than 0 and page argument will point to an array of OS - * allocated pages. - * - * @Input psDevNode pointer to the device object - * @Input page array of the pages allocated by from the OS - * @Input ui32DevPageOrder order of the page (same as the one used to allocate - * the page array by alloc_pages()) - * @Input ui32CPUCacheFlags CPU cache flags applied to the page - * @Input ui8PoisonValue value used to poison the page - */ -static void -_PoisonDevicePage(PVRSRV_DEVICE_NODE *psDevNode, - struct page *page, - IMG_UINT32 ui32DevPageOrder, - IMG_UINT32 ui32CPUCacheFlags, - IMG_BYTE ui8PoisonValue) -{ - IMG_UINT32 ui32OsPageIdx; - - for (ui32OsPageIdx = 0; - ui32OsPageIdx < (1U << ui32DevPageOrder); - ui32OsPageIdx++) - { - struct page *current_page = page + ui32OsPageIdx; - IMG_CPU_PHYADDR sCPUPhysAddrStart = {page_to_phys(current_page)}; - IMG_CPU_PHYADDR sCPUPhysAddrEnd = {sCPUPhysAddrStart.uiAddr + PAGE_SIZE}; - - void *kvaddr = kmap_atomic(current_page); - - /* kmap_atomic maps pages as cached so it's safe to use OSCachedMemSet - * here (also pages are always 8 bytes aligned anyway) */ - OSCachedMemSet(kvaddr, ui8PoisonValue, PAGE_SIZE); - - OSCPUCacheFlushRangeKM(psDevNode, kvaddr, kvaddr + PAGE_SIZE, - sCPUPhysAddrStart, sCPUPhysAddrEnd); - - kunmap_atomic(kvaddr); - } -} - -/* Allocate and initialise the structure to hold the metadata of the allocation */ -static PVRSRV_ERROR -_AllocOSPageArray(PVRSRV_DEVICE_NODE *psDevNode, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 uiLog2AllocPageSize, - IMG_UINT32 ui32AllocFlags, - IMG_UINT32 ui32CPUCacheFlags, - IMG_PID uiPid, - PMR_OSPAGEARRAY_DATA **ppsPageArrayDataPtr) -{ - PVRSRV_ERROR eError; - PMR_SIZE_T uiSize = uiChunkSize * ui32NumVirtChunks; - IMG_UINT32 uiNumOSPageSizeVirtPages; - IMG_UINT32 uiNumDevPageSizeVirtPages; - PMR_OSPAGEARRAY_DATA *psPageArrayData; - IMG_UINT64 ui64DmaMask = 0; - PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks); - - /* Use of cast below is justified by the assertion that follows to - * prove that no significant bits have been truncated */ - uiNumOSPageSizeVirtPages = (IMG_UINT32) (((uiSize - 1) >> PAGE_SHIFT) + 1); - PVR_ASSERT(((PMR_SIZE_T) uiNumOSPageSizeVirtPages << PAGE_SHIFT) == uiSize); - - uiNumDevPageSizeVirtPages = uiNumOSPageSizeVirtPages >> (uiLog2AllocPageSize - PAGE_SHIFT); - - /* Allocate the struct to hold the metadata */ - psPageArrayData = kmem_cache_alloc(g_psLinuxPageArray, GFP_KERNEL); - if (psPageArrayData == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OS refused the memory allocation for the private data.", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e_freed_none; - } - - /* - * Allocate the page array - * - * We avoid tracking this memory because this structure might go into the page pool. - * The OS can drain the pool asynchronously and when doing that we have to avoid - * any potential deadlocks. - * - * In one scenario the process stats vmalloc hash table lock is held and then - * the oom-killer softirq is trying to call _ScanObjectsInPagePool(), it must not - * try to acquire the vmalloc hash table lock again. - */ - psPageArrayData->pagearray = OSAllocZMemNoStats(sizeof(struct page *) * uiNumDevPageSizeVirtPages); - if (psPageArrayData->pagearray == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e_free_kmem_cache; - } - else - { - if (BIT_ISSET(ui32AllocFlags, FLAG_IS_CMA)) - { - /* Allocate additional DMA/CMA cpu kernel virtual address & device bus address array state */ - psPageArrayData->dmavirtarray = OSAllocZMemNoStats(sizeof(void*) * uiNumDevPageSizeVirtPages); - if (psPageArrayData->dmavirtarray == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e_free_pagearray; - } - - psPageArrayData->dmaphysarray = OSAllocZMemNoStats(sizeof(dma_addr_t) * uiNumDevPageSizeVirtPages); - if (psPageArrayData->dmaphysarray == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e_free_cpuvirtaddrarray; - } - } - } - - if (psDevNode->psDevConfig && psDevNode->psDevConfig->pvOSDevice) - { - struct device *psDev = psDevNode->psDevConfig->pvOSDevice; - ui64DmaMask = *psDev->dma_mask; - } - - /* Init metadata */ - psPageArrayData->psDevNode = psDevNode; - psPageArrayData->uiPid = uiPid; - psPageArrayData->iNumOSPagesAllocated = 0; - psPageArrayData->uiTotalNumOSPages = uiNumOSPageSizeVirtPages; - psPageArrayData->uiLog2AllocPageSize = uiLog2AllocPageSize; - psPageArrayData->ui64DmaMask = ui64DmaMask; - psPageArrayData->ui32AllocFlags = ui32AllocFlags; - psPageArrayData->ui32CPUCacheFlags = ui32CPUCacheFlags; - psPageArrayData->ui32CMAAdjustedPageCount = 0; - - *ppsPageArrayDataPtr = psPageArrayData; - return PVRSRV_OK; - -/* Error path */ -e_free_cpuvirtaddrarray: - OSFreeMemNoStats(psPageArrayData->dmavirtarray); - -e_free_pagearray: - OSFreeMemNoStats(psPageArrayData->pagearray); - -e_free_kmem_cache: - kmem_cache_free(g_psLinuxPageArray, psPageArrayData); - PVR_DPF((PVR_DBG_ERROR, - "%s: OS refused the memory allocation for the page pointer table. " - "Did you ask for too much?", - __func__)); - -e_freed_none: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static inline void -_ApplyCacheMaintenance(PVRSRV_DEVICE_NODE *psDevNode, - struct page **ppsPage, - IMG_UINT32 uiNumPages) -{ - void * pvAddr; - - if (OSCPUCacheOpAddressType() == OS_CACHE_OP_ADDR_TYPE_VIRTUAL) - { - pgprot_t pgprot = PAGE_KERNEL; - - IMG_UINT32 uiNumToClean = uiNumPages; - struct page **ppsCleanArray = ppsPage; - - /* Map and flush page. - * For large page arrays do it PVR_LINUX_PHYSMEM_MAX_KMAP_SIZE - * at a time. */ - while (uiNumToClean != 0) - { - IMG_UINT32 uiToClean = MIN(PVR_LINUX_PHYSMEM_MAX_KMAP_PAGES, - uiNumToClean); - IMG_CPU_PHYADDR sUnused = - { IMG_CAST_TO_CPUPHYADDR_UINT(0xCAFEF00DDEADBEEFULL) }; - - pvAddr = pvr_vmap(ppsCleanArray, uiToClean, -1, pgprot); - if (!pvAddr) - { - PVR_DPF((PVR_DBG_ERROR, - "Unable to flush page cache for new allocation, skipping flush.")); - return; - } - - CacheOpExec(psDevNode, - pvAddr, - pvAddr + PAGE_SIZE, - sUnused, - sUnused, - PVRSRV_CACHE_OP_FLUSH); - - pvr_vunmap(pvAddr, uiToClean, pgprot); - ppsCleanArray = &(ppsCleanArray[uiToClean]); - uiNumToClean -= uiToClean; - } - } - else - { - IMG_UINT32 ui32Idx; - - for (ui32Idx = 0; ui32Idx < uiNumPages; ++ui32Idx) - { - IMG_CPU_PHYADDR sCPUPhysAddrStart, sCPUPhysAddrEnd; - - pvAddr = kmap(ppsPage[ui32Idx]); - sCPUPhysAddrStart.uiAddr = page_to_phys(ppsPage[ui32Idx]); - sCPUPhysAddrEnd.uiAddr = sCPUPhysAddrStart.uiAddr + PAGE_SIZE; - - /* If we're zeroing, we need to make sure the cleared memory is pushed out - * of the cache before the cache lines are invalidated */ - CacheOpExec(psDevNode, - pvAddr, - pvAddr + PAGE_SIZE, - sCPUPhysAddrStart, - sCPUPhysAddrEnd, - PVRSRV_CACHE_OP_FLUSH); - - kunmap(ppsPage[ui32Idx]); - } - } -} - -/* Change the caching attribute of pages on x86 systems and takes care of - * cache maintenance. This function is supposed to be called once for pages that - * came from alloc_pages(). It expects an array of OS page sized pages! - * - * Flush/Invalidate pages in case the allocation is not cached. Necessary to - * remove pages from the cache that might be flushed later and corrupt memory. */ -static inline PVRSRV_ERROR -_ApplyOSPagesAttribute(PVRSRV_DEVICE_NODE *psDevNode, - struct page **ppsPage, - IMG_UINT32 uiNumPages, - IMG_BOOL bFlush, - IMG_UINT32 ui32CPUCacheFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BOOL bCPUCached = PVRSRV_CHECK_CPU_CACHED(ui32CPUCacheFlags); - IMG_BOOL bCPUUncached = PVRSRV_CHECK_CPU_UNCACHED(ui32CPUCacheFlags); - IMG_BOOL bCPUWriteCombine = PVRSRV_CHECK_CPU_WRITE_COMBINE(ui32CPUCacheFlags); - - if (ppsPage != NULL && uiNumPages != 0) - { -#if defined(CONFIG_X86) - /* On x86 we have to set page cache attributes for non-cached pages. - * The call is implicitly taking care of all flushing/invalidating - * and therefore we can skip the usual cache maintenance after this. */ - if (bCPUUncached || bCPUWriteCombine) - { - /* On x86 if we already have a mapping (e.g. low memory) we need to change the mode of - current mapping before we map it ourselves */ - int ret = IMG_FALSE; - - switch (PVRSRV_CPU_CACHE_MODE(ui32CPUCacheFlags)) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - ret = set_pages_array_uc(ppsPage, uiNumPages); - if (ret) - { - eError = PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE; - PVR_DPF((PVR_DBG_ERROR, "Setting Linux page caching mode to UC failed, returned %d", ret)); - } - break; - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: - ret = set_pages_array_wc(ppsPage, uiNumPages); - if (ret) - { - eError = PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE; - PVR_DPF((PVR_DBG_ERROR, "Setting Linux page caching mode to WC failed, returned %d", ret)); - } - break; - - case PVRSRV_MEMALLOCFLAG_CPU_CACHED: - break; - - default: - break; - } - } - else -#endif - { - if ( bFlush || - bCPUUncached || bCPUWriteCombine || - (bCPUCached && PVRSRV_CHECK_CPU_CACHE_CLEAN(ui32CPUCacheFlags)) ) - { - /* We can be given pages which still remain in the cache. - In order to make sure that the data we write through our mappings - doesn't get overwritten by later cache evictions we invalidate the - pages that are given to us. - - Note: - This still seems to be true if we request cold pages, it's just less - likely to be in the cache. */ - _ApplyCacheMaintenance(psDevNode, - ppsPage, - uiNumPages); - } - } - } - - return eError; -} - -/* Same as _AllocOSPage except it uses DMA framework to perform allocation. - * uiPageIndex is expected to be the pagearray index where to store the higher order page. */ -static PVRSRV_ERROR -_AllocOSPage_CMA(PMR_OSPAGEARRAY_DATA *psPageArrayData, - gfp_t gfp_flags, - IMG_UINT32 ui32AllocOrder, - IMG_UINT32 ui32MinOrder, - IMG_UINT32 uiPageIndex) -{ - void *virt_addr; - struct page *page; - dma_addr_t bus_addr; - IMG_UINT32 uiAllocIsMisaligned; - size_t alloc_size = PAGE_SIZE << ui32AllocOrder; - struct device *dev = psPageArrayData->psDevNode->psDevConfig->pvOSDevice; - PVR_ASSERT(ui32AllocOrder == ui32MinOrder); - - do - { - DisableOOMKiller(); -#if defined(PVR_LINUX_PHYSMEM_SUPPRESS_DMA_AC) - virt_addr = NULL; -#else - virt_addr = dma_alloc_coherent(dev, alloc_size, &bus_addr, gfp_flags); -#endif - if (virt_addr == NULL) - { - /* The idea here is primarily to support some older kernels with - broken or non-functioning DMA/CMA implementations (< Linux-3.4) - and to also handle DMA/CMA allocation failures by attempting a - normal page allocation though we expect dma_alloc_coherent() - already attempts this internally also before failing but - nonetheless it does no harm to retry the allocation ourselves */ - page = alloc_pages(gfp_flags, ui32AllocOrder); - if (page) - { - /* Taint bus_addr as alloc_page, needed when freeing; - also acquire the low memory page address only, this - prevents mapping possible high memory pages into - kernel virtual address space which might exhaust - the VMALLOC address space */ - bus_addr = DMA_SET_ALLOCPG_ADDR(page_to_phys(page)); - virt_addr = (void*)(uintptr_t) DMA_VADDR_NOT_IN_USE; - } - else - { - EnableOOMKiller(); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - else - { -#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) - page = pfn_to_page(bus_addr >> PAGE_SHIFT); -#else - /* Assumes bus address space is identical to physical address space */ - page = phys_to_page(bus_addr); -#endif - } - EnableOOMKiller(); - - /* Physical allocation alignment works/hidden behind the scene transparently, - we do this here if the allocated buffer address does not meet its alignment - requirement by over-allocating using the next power-2 order and reporting - aligned-adjusted values back to meet the requested alignment constraint. - Evidently we waste memory by doing this so should only do so if we do not - initially meet the alignment constraint. */ - uiAllocIsMisaligned = DMA_GET_ADDR(bus_addr) & ((PAGE_SIZE< ui32MinOrder) - { - IMG_BOOL bUsedAllocPages = DMA_IS_ALLOCPG_ADDR(bus_addr); - if (ui32AllocOrder == ui32MinOrder) - { - if (bUsedAllocPages) - { - __free_pages(page, ui32AllocOrder); - } - else - { - dma_free_coherent(dev, alloc_size, virt_addr, bus_addr); - } - - ui32AllocOrder = ui32AllocOrder + 1; - alloc_size = PAGE_SIZE << ui32AllocOrder; - - PVR_ASSERT(uiAllocIsMisaligned != 0); - } - else - { - size_t align_adjust = PAGE_SIZE << ui32MinOrder; - - /* Adjust virtual/bus addresses to meet alignment */ - bus_addr = bUsedAllocPages ? page_to_phys(page) : bus_addr; - align_adjust = PVR_ALIGN((size_t)bus_addr, align_adjust); - align_adjust -= (size_t)bus_addr; - - if (align_adjust) - { - if (bUsedAllocPages) - { - page += align_adjust >> PAGE_SHIFT; - bus_addr = DMA_SET_ALLOCPG_ADDR(page_to_phys(page)); - virt_addr = (void*)(uintptr_t) DMA_VADDR_NOT_IN_USE; - } - else - { - bus_addr += align_adjust; - virt_addr += align_adjust; -#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) - page = pfn_to_page(bus_addr >> PAGE_SHIFT); -#else - /* Assumes bus address space is identical to physical address space */ - page = phys_to_page(bus_addr); -#endif - } - - /* Store adjustments in PAGE_SIZE counts */ - align_adjust = align_adjust >> PAGE_SHIFT; - bus_addr = DMA_SET_ALIGN_ADJUSTMENT(bus_addr, align_adjust); - } - - /* Taint bus_addr due to over-allocation, allows us to free - * memory correctly */ - bus_addr = DMA_SET_ADJUSTED_ADDR(bus_addr); - uiAllocIsMisaligned = 0; - } - } - } while (uiAllocIsMisaligned); - - /* Convert OSPageSize-based index into DevicePageSize-based index */ - psPageArrayData->ui32CMAAdjustedPageCount += (alloc_size - (PAGE_SIZE << ui32AllocOrder )); - - psPageArrayData->dmavirtarray[uiPageIndex] = virt_addr; - psPageArrayData->dmaphysarray[uiPageIndex] = bus_addr; - psPageArrayData->pagearray[uiPageIndex] = page; - - return PVRSRV_OK; -} - -/* Allocate a page of order uiAllocOrder and stores it in the page array ppsPage at - * position uiPageIndex. - * - * If the order is higher than 0, it splits the page into multiples and - * stores them at position uiPageIndex to uiPageIndex+(1<= KERNEL_VERSION(3,10,0)) - /* In case we need to, split the higher order page; - this should only be used for order-0 allocations - as higher order allocations should use DMA/CMA */ - if (uiAllocOrder != 0) - { - split_page(psPage, uiAllocOrder); - } -#endif - - /* Store the page (or multiple split pages) in the page array */ - for (ui32Count = 0; ui32Count < (1 << uiAllocOrder); ui32Count++) - { - psPageArrayData->pagearray[uiPageIndex + ui32Count] = &(psPage[ui32Count]); - } - - return PVRSRV_OK; -} - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - -static inline void _AddMemAllocRecord_UmaPages(PMR_OSPAGEARRAY_DATA *psPageArrayData, - struct page *psPage) -{ - IMG_CPU_PHYADDR sCPUPhysAddr = { page_to_phys(psPage) }; - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, - NULL, sCPUPhysAddr, - 1 << psPageArrayData->uiLog2AllocPageSize, - NULL, psPageArrayData->uiPid - DEBUG_MEMSTATS_VALUES); -} - -static inline void _RemoveMemAllocRecord_UmaPages(PMR_OSPAGEARRAY_DATA *psPageArrayData, - struct page *psPage) -{ - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, - (IMG_UINT64) page_to_phys(psPage), - psPageArrayData->uiPid); -} - -#else /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ - -static inline void _IncrMemAllocStat_UmaPages(size_t uiSize, IMG_PID uiPid) -{ - PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, - uiSize, uiPid); -} - -static inline void _DecrMemAllocStat_UmaPages(size_t uiSize, IMG_PID uiPid) -{ - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, - uiSize, uiPid); -} - -#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ -#endif /* defined(PVRSRV_ENABLE_PROCESS_STATS) */ - -/* Allocation of OS pages: We may allocate 2^N order pages at a time for two reasons. - * - * Firstly to support device pages which are larger than OS. By asking the OS for 2^N - * order OS pages at a time we guarantee the device page is contiguous. - * - * Secondly for performance where we may ask for 2^N order pages to reduce the number - * of calls to alloc_pages, and thus reduce time for huge allocations. - * - * Regardless of page order requested, we need to break them down to track _OS pages. - * The maximum order requested is increased if all max order allocations were successful. - * If any request fails we reduce the max order. - */ -static PVRSRV_ERROR -_AllocOSPages_Fast(PMR_OSPAGEARRAY_DATA *psPageArrayData) -{ - PVRSRV_ERROR eError; - IMG_UINT32 uiArrayIndex = 0; - IMG_UINT32 ui32Order; - IMG_UINT32 ui32MinOrder = psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT; - IMG_BOOL bIncreaseMaxOrder = IMG_TRUE; - - IMG_UINT32 ui32NumPageReq; - IMG_UINT32 uiOSPagesToAlloc; - IMG_UINT32 uiDevPagesFromPool = 0; - - gfp_t gfp_flags = _GetGFPFlags(ui32MinOrder ? BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_ZERO) : IMG_FALSE, /* Zero all pages later as batch */ - psPageArrayData->psDevNode); - gfp_t ui32GfpFlags; - gfp_t ui32HighOrderGfpFlags = ((gfp_flags & ~__GFP_RECLAIM) | __GFP_NORETRY); - - struct page **ppsPageArray = psPageArrayData->pagearray; - struct page **ppsPageAttributeArray = NULL; - - uiOSPagesToAlloc = psPageArrayData->uiTotalNumOSPages; - - /* Try to get pages from the pool since it is faster; - the page pool currently only supports zero-order pages - thus currently excludes all DMA/CMA allocated memory */ - _GetPagesFromPoolLocked(psPageArrayData->psDevNode, - psPageArrayData->ui32CPUCacheFlags, - uiOSPagesToAlloc, - ui32MinOrder, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_ZERO), - ppsPageArray, - &uiDevPagesFromPool); - - uiArrayIndex = uiDevPagesFromPool; - - if ((uiOSPagesToAlloc - uiDevPagesFromPool) < PVR_LINUX_HIGHORDER_ALLOCATION_THRESHOLD) - { /* Small allocations: ask for one device page at a time */ - ui32Order = ui32MinOrder; - bIncreaseMaxOrder = IMG_FALSE; - } - else - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) - /* Large zero-order or none zero-order allocations, ask for - MAX(max-order, min-order) order pages at a time; alloc - failures throttles this down to ZeroOrder allocations */ - ui32Order = MAX(g_uiMaxOrder, ui32MinOrder); -#else - /* Because split_page() is not available on older kernels - we cannot mix-and-match any-order pages in the PMR; - only same-order pages must be present in page array. - So we unconditionally force it to use ui32MinOrder on - these older kernels */ - ui32Order = ui32MinOrder; -#if defined(DEBUG) - if (! BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - /* Check that this is zero */ - PVR_ASSERT(! ui32Order); - } -#endif -#endif - } - - /* Only if asking for more contiguity than we actually need, let it fail */ - ui32GfpFlags = (ui32Order > ui32MinOrder) ? ui32HighOrderGfpFlags : gfp_flags; - ui32NumPageReq = (1 << ui32Order); - - while (uiArrayIndex < uiOSPagesToAlloc) - { - IMG_UINT32 ui32PageRemain = uiOSPagesToAlloc - uiArrayIndex; - - while (ui32NumPageReq > ui32PageRemain) - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) - /* Pages to request is larger than that remaining - so ask for less so never over allocate */ - ui32Order = MAX(ui32Order >> 1, ui32MinOrder); -#else - /* Pages to request is larger than that remaining so - do nothing thus over allocate as we do not support - mix/match of any-order pages in PMR page-array in - older kernels (simplifies page free logic) */ - PVR_ASSERT(ui32Order == ui32MinOrder); -#endif - ui32NumPageReq = (1 << ui32Order); - ui32GfpFlags = (ui32Order > ui32MinOrder) ? ui32HighOrderGfpFlags : gfp_flags; - } - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - /* As the DMA/CMA framework rounds-up request to the - next power-of-two, we request multiple uiMinOrder - pages to satisfy allocation request in order to - minimise wasting memory */ - eError = _AllocOSPage_CMA(psPageArrayData, - ui32GfpFlags, - ui32Order, - ui32MinOrder, - uiArrayIndex >> ui32MinOrder); - } - else - { - /* Allocate uiOrder pages at uiArrayIndex */ - eError = _AllocOSPage(psPageArrayData, - ui32GfpFlags, - ui32Order, - ui32MinOrder, - uiArrayIndex); - } - - if (eError == PVRSRV_OK) - { - /* Successful request. Move onto next. */ - uiArrayIndex += ui32NumPageReq; - } - else - { - if (ui32Order > ui32MinOrder) - { - /* Last request failed. Let's ask for less next time */ - ui32Order = MAX(ui32Order >> 1, ui32MinOrder); - bIncreaseMaxOrder = IMG_FALSE; - ui32NumPageReq = (1 << ui32Order); - ui32GfpFlags = (ui32Order > ui32MinOrder) ? ui32HighOrderGfpFlags : gfp_flags; - g_uiMaxOrder = ui32Order; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) - /* We should not trigger this code path in older kernels, - this is enforced by ensuring ui32Order == ui32MinOrder */ - PVR_ASSERT(ui32Order == ui32MinOrder); -#endif - } - else - { - /* Failed to alloc pages at required contiguity. Failed allocation */ - PVR_DPF((PVR_DBG_ERROR, "%s: %s failed to honour request at %u of %u, flags = %x, order = %u (%s)", - __func__, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA) ? "dma_alloc_coherent" : "alloc_pages", - uiArrayIndex, - uiOSPagesToAlloc, - ui32GfpFlags, - ui32Order, - PVRSRVGetErrorString(eError))); - eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES; - goto e_free_pages; - } - } - } - - if (bIncreaseMaxOrder && (g_uiMaxOrder < PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM)) - { /* All successful allocations on max order. Let's ask for more next time */ - g_uiMaxOrder++; - } - - /* Construct table of page pointers to apply attributes */ - ppsPageAttributeArray = &ppsPageArray[uiDevPagesFromPool]; - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 uiIdx, uiIdy, uiIdz; - - ppsPageAttributeArray = OSAllocMem(sizeof(struct page *) * uiOSPagesToAlloc); - PVR_LOG_GOTO_IF_NOMEM(ppsPageAttributeArray, eError, e_free_pages); - - for (uiIdx = 0; uiIdx < uiOSPagesToAlloc; uiIdx += ui32NumPageReq) - { - uiIdy = uiIdx >> ui32Order; - for (uiIdz = 0; uiIdz < ui32NumPageReq; uiIdz++) - { - ppsPageAttributeArray[uiIdx+uiIdz] = ppsPageArray[uiIdy]; - ppsPageAttributeArray[uiIdx+uiIdz] += uiIdz; - } - } - } - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_ZERO) && ui32MinOrder == 0) - { - eError = _MemsetPageArray(uiOSPagesToAlloc - uiDevPagesFromPool, - ppsPageAttributeArray, PAGE_KERNEL, - PVRSRV_ZERO_VALUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to zero pages (fast)")); - goto e_free_pages; - } - } - else if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_POISON_ON_ALLOC)) - { - /* need to call twice because ppsPageArray and ppsPageAttributeArray - * can point to different allocations: first for pages obtained from - * the pool and then the remaining pages */ - eError = _MemsetPageArray(uiDevPagesFromPool, ppsPageArray, PAGE_KERNEL, - PVRSRV_POISON_ON_ALLOC_VALUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to poison pages (fast)")); - } - eError = _MemsetPageArray(uiOSPagesToAlloc - uiDevPagesFromPool, - ppsPageAttributeArray, PAGE_KERNEL, - PVRSRV_POISON_ON_ALLOC_VALUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to poison pages (fast)")); - } - - /* for poisoning need to also flush the pool pages as the 0s have - * been overwritten */ - _ApplyCacheMaintenance(psPageArrayData->psDevNode, ppsPageArray, - uiDevPagesFromPool); - } - - /* Do the cache management as required */ - eError = _ApplyOSPagesAttribute(psPageArrayData->psDevNode, - ppsPageAttributeArray, - uiOSPagesToAlloc - uiDevPagesFromPool, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_ZERO) || - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_POISON_ON_ALLOC), - psPageArrayData->ui32CPUCacheFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to set page attributes")); - goto e_free_pages; - } - else - { - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - OSFreeMem(ppsPageAttributeArray); - } - } - - /* Update metadata */ - psPageArrayData->iNumOSPagesAllocated = psPageArrayData->uiTotalNumOSPages; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - { -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - IMG_UINT32 ui32NumPages = - psPageArrayData->iNumOSPagesAllocated >> ui32MinOrder; - IMG_UINT32 i; - - for (i = 0; i < ui32NumPages; i++) - { - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - _AddMemAllocRecord_UmaPages(psPageArrayData, ppsPageArray[i]); - } - else - { - _AddMemAllocRecord_UmaPages(psPageArrayData, ppsPageArray[i << ui32MinOrder]); - } - } -#else /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ - _IncrMemAllocStat_UmaPages(((uiOSPagesToAlloc * PAGE_SIZE)+(psPageArrayData->ui32CMAAdjustedPageCount)), - psPageArrayData->uiPid); -#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ - } -#endif /* defined(PVRSRV_ENABLE_PROCESS_STATS) */ - - return PVRSRV_OK; - -/* Error path */ -e_free_pages: - { - IMG_UINT32 ui32PageToFree; - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 uiDevArrayIndex = uiArrayIndex >> ui32Order; - IMG_UINT32 uiDevPageSize = PAGE_SIZE << ui32Order; - PVR_ASSERT(ui32Order == ui32MinOrder); - - if (ppsPageAttributeArray) - { - OSFreeMem(ppsPageAttributeArray); - } - - for (ui32PageToFree = 0; ui32PageToFree < uiDevArrayIndex; ui32PageToFree++) - { - _FreeOSPage_CMA(psPageArrayData->psDevNode->psDevConfig->pvOSDevice, - uiDevPageSize, - ui32MinOrder, - psPageArrayData->dmavirtarray[ui32PageToFree], - psPageArrayData->dmaphysarray[ui32PageToFree], - ppsPageArray[ui32PageToFree]); - psPageArrayData->dmaphysarray[ui32PageToFree]= (dma_addr_t)0; - psPageArrayData->dmavirtarray[ui32PageToFree] = NULL; - ppsPageArray[ui32PageToFree] = NULL; - } - } - else - { - /* Free the pages we got from the pool */ - for (ui32PageToFree = 0; ui32PageToFree < uiDevPagesFromPool; ui32PageToFree++) - { - _FreeOSPage(ui32MinOrder, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_UNSET_MEMORY_TYPE), - ppsPageArray[ui32PageToFree]); - ppsPageArray[ui32PageToFree] = NULL; - } - - for (ui32PageToFree = uiDevPagesFromPool; ui32PageToFree < uiArrayIndex; ui32PageToFree++) - { - _FreeOSPage(ui32MinOrder, IMG_FALSE, ppsPageArray[ui32PageToFree]); - ppsPageArray[ui32PageToFree] = NULL; - } - } - - return eError; - } -} - -static INLINE PVRSRV_ERROR -_CheckIfIndexInRange(IMG_UINT32 ui32Index, IMG_UINT32 *pui32Indices, IMG_UINT32 ui32Limit) -{ - if (pui32Indices[ui32Index] >= ui32Limit) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Given alloc index %u at %u is larger than page array %u.", - __func__, pui32Indices[ui32Index], ui32Index, ui32Limit)); - return PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE; - } - - return PVRSRV_OK; -} - -static INLINE PVRSRV_ERROR -_CheckIfPageNotAllocated(IMG_UINT32 ui32Index, IMG_UINT32 *pui32Indices, struct page **ppsPageArray) -{ - if (ppsPageArray[pui32Indices[ui32Index]] != NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Mapping number %u at page array index %u already exists. " - "Page struct %p", __func__, pui32Indices[ui32Index], ui32Index, - ppsPageArray[pui32Indices[ui32Index]])); - return PVRSRV_ERROR_PMR_MAPPING_ALREADY_EXISTS; - } - - return PVRSRV_OK; -} - -/* Allocation of OS pages: This function is used for sparse allocations. - * - * Sparse allocations provide only a proportion of sparse physical backing within the total - * virtual range. */ -static PVRSRV_ERROR -_AllocOSPages_Sparse(PMR_OSPAGEARRAY_DATA *psPageArrayData, - IMG_UINT32 *puiAllocIndices, - IMG_UINT32 uiDevPagesToAlloc) -{ - PVRSRV_ERROR eError; - IMG_UINT32 i; - struct page **ppsPageArray = psPageArrayData->pagearray; - IMG_UINT32 uiOrder = psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT; - IMG_UINT32 uiDevPagesFromPool = 0; - IMG_UINT32 uiOSPagesToAlloc = uiDevPagesToAlloc * (1 << uiOrder); - IMG_UINT32 uiDevPagesAllocated = psPageArrayData->uiTotalNumOSPages >> uiOrder; - const IMG_UINT32 ui32AllocFlags = psPageArrayData->ui32AllocFlags; - gfp_t ui32GfpFlags = _GetGFPFlags(uiOrder ? BIT_ISSET(ui32AllocFlags, FLAG_ZERO): - IMG_FALSE, /* Zero pages later as batch */ - psPageArrayData->psDevNode); - - /* We use this page array to receive pages from the pool and then reuse it afterwards to - * store pages that need their cache attribute changed on x86 */ - struct page **ppsTempPageArray; - IMG_UINT32 uiTempPageArrayIndex = 0; - - /* Allocate the temporary page array that we need here to receive pages - * from the pool and to store pages that need their caching attributes changed. - * Allocate number of OS pages to be able to use the attribute function later. */ - ppsTempPageArray = OSAllocMem(sizeof(struct page*) * uiOSPagesToAlloc); - PVR_LOG_GOTO_IF_NOMEM(ppsTempPageArray, eError, e_exit); - - /* Check the requested number of pages if they fit in the page array */ - if (uiDevPagesAllocated < - ((psPageArrayData->iNumOSPagesAllocated >> uiOrder) + uiDevPagesToAlloc)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Trying to allocate more pages (Order %u) than this buffer can handle, " - "Request + Allocated < Max! Request %u, Allocated %u, Max %u.", - __func__, - uiOrder, - uiDevPagesToAlloc, - psPageArrayData->iNumOSPagesAllocated >> uiOrder, - uiDevPagesAllocated)); - eError = PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE; - goto e_free_temp_array; - } - - /* Try to get pages from the pool since it is faster. The pages from pool are going to be - * allocated only if: - * - PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES == 1 && uiOrder == 0 - * - PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES == 0 && uiOrder == 0 && - * !BIT_ISSET(ui32AllocFlags, FLAG_ZERO) */ - _GetPagesFromPoolLocked(psPageArrayData->psDevNode, - psPageArrayData->ui32CPUCacheFlags, - uiDevPagesToAlloc, - uiOrder, - BIT_ISSET(ui32AllocFlags, FLAG_ZERO), - ppsTempPageArray, - &uiDevPagesFromPool); - - /* In general device pages can have higher order than 0 but page pool always provides only 0 - * order pages so they can be assigned to the OS pages values (in other words if we're - * allocating non-4k pages uiDevPagesFromPool will always be 0) */ - uiTempPageArrayIndex = uiDevPagesFromPool; - - /* Move pages we got from the pool to the array. */ - for (i = 0; i < uiDevPagesFromPool; i++) - { - eError = _CheckIfIndexInRange(i, puiAllocIndices, uiDevPagesAllocated); - PVR_GOTO_IF_ERROR(eError, e_free_pool_pages); - eError = _CheckIfPageNotAllocated(i, puiAllocIndices, ppsPageArray); - PVR_GOTO_IF_ERROR(eError, e_free_pool_pages); - - ppsPageArray[puiAllocIndices[i]] = ppsTempPageArray[i]; - } - - /* Allocate pages from the OS */ - for (i = uiDevPagesFromPool; i < uiDevPagesToAlloc; i++) - { - eError = _CheckIfIndexInRange(i, puiAllocIndices, uiDevPagesAllocated); - PVR_GOTO_IF_ERROR(eError, e_free_pages); - eError = _CheckIfPageNotAllocated(i, puiAllocIndices, ppsPageArray); - PVR_GOTO_IF_ERROR(eError, e_free_pages); - - /* Allocated pages and assign them the array. */ - if (BIT_ISSET(ui32AllocFlags, FLAG_IS_CMA)) - { - /* As the DMA/CMA framework rounds-up request to the - next power-of-two, we request multiple uiMinOrder - pages to satisfy allocation request in order to - minimise wasting memory */ - eError = _AllocOSPage_CMA(psPageArrayData, - ui32GfpFlags, - uiOrder, - uiOrder, - puiAllocIndices[i]); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to alloc CMA pages")); - goto e_free_pages; - } - } - else - { - DisableOOMKiller(); - ppsPageArray[puiAllocIndices[i]] = alloc_pages(ui32GfpFlags, uiOrder); - EnableOOMKiller(); - } - - if (ppsPageArray[puiAllocIndices[i]] != NULL) - { - /* Append pages to the temporary array so it's easier to process - * them later on. */ - - if (BIT_ISSET(ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 idx; - struct page *psPageAddr; - - psPageAddr = ppsPageArray[puiAllocIndices[i]]; - - /* "divide" CMA pages into OS pages if they have higher order */ - for (idx = 0; idx < (1 << uiOrder); idx++) - { - ppsTempPageArray[uiTempPageArrayIndex + idx] = psPageAddr; - psPageAddr++; - } - uiTempPageArrayIndex += (1 << uiOrder); - } - else - { - ppsTempPageArray[uiTempPageArrayIndex] = ppsPageArray[puiAllocIndices[i]]; - uiTempPageArrayIndex++; - } - } - else - { - /* Failed to alloc pages at required contiguity. Failed allocation */ - PVR_DPF((PVR_DBG_ERROR, - "%s: alloc_pages failed to honour request at %u of %u, flags = %x, order = %u", - __func__, i, uiDevPagesToAlloc, ui32GfpFlags, uiOrder)); - eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES; - goto e_free_pages; - } - } - - if (BIT_ISSET(ui32AllocFlags, FLAG_ZERO) && uiOrder == 0) - { - /* At this point this array contains pages allocated from the page pool at its start - * and pages allocated from the OS after that. - * If there are pages from the pool here they must be zeroed already hence we don't have - * to do it again. This is because if PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES is enabled pool pages - * are zeroed in the cleanup thread. If it's disabled they aren't, and in that case we never - * allocate pages with FLAG_ZERO from the pool. This is why those pages need to be zeroed - * here. - * All of the above is true for the 0 order pages. For higher order we never allocated from - * the pool and those pages are allocated already zeroed from the OS. - * Long story short we can always skip pages allocated from the pool because they are either - * zeroed or we didn't allocate any of them. */ - eError = _MemsetPageArray(uiTempPageArrayIndex - uiDevPagesFromPool, - &ppsTempPageArray[uiDevPagesFromPool], - PAGE_KERNEL, PVRSRV_ZERO_VALUE); - PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "failed to zero pages (sparse)", e_free_pages); - } - else if (BIT_ISSET(ui32AllocFlags, FLAG_POISON_ON_ALLOC)) - { - /* Here we need to poison all of the pages regardless if they were - * allocated from the pool or from the system. */ - eError = _MemsetPageArray(uiTempPageArrayIndex, ppsTempPageArray, - PAGE_KERNEL, PVRSRV_POISON_ON_ALLOC_VALUE); - PVR_LOG_IF_FALSE(eError == PVRSRV_OK, "failed to poison pages (sparse)"); - - /* We need to flush the cache for the poisoned pool pages here. The flush for the pages - * allocated from the system is done below because we also need to add appropriate cache - * attributes to them. Pages allocated from the pool already come with correct caching - * mode. */ - _ApplyCacheMaintenance(psPageArrayData->psDevNode, ppsTempPageArray, uiDevPagesFromPool); - } - - /* Do the cache management as required */ - eError = _ApplyOSPagesAttribute(psPageArrayData->psDevNode, - &ppsTempPageArray[uiDevPagesFromPool], - uiTempPageArrayIndex - uiDevPagesFromPool, - BIT_ISSET(ui32AllocFlags, FLAG_ZERO) || - BIT_ISSET(ui32AllocFlags, FLAG_POISON_ON_ALLOC), - psPageArrayData->ui32CPUCacheFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to set page attributes")); - goto e_free_pages; - } - - /* Update metadata */ - psPageArrayData->iNumOSPagesAllocated += uiOSPagesToAlloc; - - /* Free temporary page array */ - OSFreeMem(ppsTempPageArray); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - for (i = 0; i < uiDevPagesToAlloc; i++) - { - _AddMemAllocRecord_UmaPages(psPageArrayData, - ppsPageArray[puiAllocIndices[i]]); - } -#else - _IncrMemAllocStat_UmaPages(((uiOSPagesToAlloc * PAGE_SIZE)+(psPageArrayData->ui32CMAAdjustedPageCount)), - psPageArrayData->uiPid); -#endif -#endif - - return PVRSRV_OK; - -e_free_pages: - if (BIT_ISSET(ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 uiDevPageSize = PAGE_SIZE << uiOrder; - - /* Free the pages we just allocated from the CMA */ - for (; i > uiDevPagesFromPool; i--) - { - _FreeOSPage_CMA(psPageArrayData->psDevNode->psDevConfig->pvOSDevice, - uiDevPageSize, - uiOrder, - psPageArrayData->dmavirtarray[puiAllocIndices[i-1]], - psPageArrayData->dmaphysarray[puiAllocIndices[i-1]], - ppsPageArray[puiAllocIndices[i-1]]); - psPageArrayData->dmaphysarray[puiAllocIndices[i-1]]= (dma_addr_t) 0; - psPageArrayData->dmavirtarray[puiAllocIndices[i-1]] = NULL; - ppsPageArray[puiAllocIndices[i-1]] = NULL; - } - } - else - { - /* Free the pages we just allocated from the OS */ - for (; i > uiDevPagesFromPool; i--) - { - _FreeOSPage(0, IMG_FALSE, ppsPageArray[puiAllocIndices[i-1]]); - ppsPageArray[puiAllocIndices[i-1]] = NULL; - } - } - -e_free_pool_pages: - /* And now free all of the pages we allocated from the pool. */ - for (i = 0; i < uiDevPagesFromPool; i++) - { - _FreeOSPage(0, BIT_ISSET(ui32AllocFlags, FLAG_UNSET_MEMORY_TYPE), - ppsTempPageArray[i]); - - /* not using _CheckIfIndexInRange() to not print error message */ - if (puiAllocIndices[i] < uiDevPagesAllocated) - { - ppsPageArray[puiAllocIndices[i]] = NULL; - } - } - -e_free_temp_array: - OSFreeMem(ppsTempPageArray); - -e_exit: - return eError; -} - -/* Allocate pages for a given page array. - * - * The executed allocation path depends whether an array with allocation - * indices has been passed or not */ -static PVRSRV_ERROR -_AllocOSPages(PMR_OSPAGEARRAY_DATA *psPageArrayData, - IMG_UINT32 *puiAllocIndices, - IMG_UINT32 uiPagesToAlloc) -{ - PVRSRV_ERROR eError; - struct page **ppsPageArray; - - /* Parameter checks */ - PVR_ASSERT(NULL != psPageArrayData); - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - PVR_ASSERT(psPageArrayData->dmaphysarray != NULL); - PVR_ASSERT(psPageArrayData->dmavirtarray != NULL); - } - PVR_ASSERT(psPageArrayData->pagearray != NULL); - PVR_ASSERT(0 <= psPageArrayData->iNumOSPagesAllocated); - - ppsPageArray = psPageArrayData->pagearray; - - /* Go the sparse alloc path if we have an array with alloc indices.*/ - if (puiAllocIndices != NULL) - { - eError = _AllocOSPages_Sparse(psPageArrayData, - puiAllocIndices, - uiPagesToAlloc); - } - else - { - eError = _AllocOSPages_Fast(psPageArrayData); - } - - if (eError != PVRSRV_OK) - { - goto e_exit; - } - - _DumpPageArray(ppsPageArray, - psPageArrayData->uiTotalNumOSPages >> - (psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT) ); - - PVR_DPF((PVR_DBG_MESSAGE, "physmem_osmem_linux.c: allocated OS memory for PMR @0x%p", psPageArrayData)); - return PVRSRV_OK; - -e_exit: - return eError; -} - -/* Same as _FreeOSPage except free memory using DMA framework */ -static INLINE void -_FreeOSPage_CMA(struct device *dev, - size_t alloc_size, - IMG_UINT32 uiOrder, - void *virt_addr, - dma_addr_t dev_addr, - struct page *psPage) -{ - if (DMA_IS_ALLOCPG_ADDR(dev_addr)) - { -#if defined(CONFIG_X86) - void *pvPageVAddr = page_address(psPage); - if (pvPageVAddr) - { - int ret = set_memory_wb((unsigned long)pvPageVAddr, 1); - if (ret) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to reset page attribute", - __func__)); - } - } -#endif - - if (DMA_IS_ADDR_ADJUSTED(dev_addr)) - { - psPage -= DMA_GET_ALIGN_ADJUSTMENT(dev_addr); - uiOrder += 1; - } - - __free_pages(psPage, uiOrder); - } - else - { - if (DMA_IS_ADDR_ADJUSTED(dev_addr)) - { - size_t align_adjust; - - align_adjust = DMA_GET_ALIGN_ADJUSTMENT(dev_addr); - alloc_size = alloc_size << 1; - - dev_addr = DMA_GET_ADDR(dev_addr); - dev_addr -= align_adjust << PAGE_SHIFT; - virt_addr -= align_adjust << PAGE_SHIFT; - } - - dma_free_coherent(dev, alloc_size, virt_addr, DMA_GET_ADDR(dev_addr)); - } -} - -/* Free a single page back to the OS. - * Make sure the cache type is set back to the default value. - * - * Note: - * We must _only_ check bUnsetMemoryType in the case where we need to free - * the page back to the OS since we may have to revert the cache properties - * of the page to the default as given by the OS when it was allocated. */ -static void -_FreeOSPage(IMG_UINT32 uiOrder, - IMG_BOOL bUnsetMemoryType, - struct page *psPage) -{ - -#if defined(CONFIG_X86) - void *pvPageVAddr; - pvPageVAddr = page_address(psPage); - - if (pvPageVAddr && bUnsetMemoryType) - { - int ret; - - ret = set_memory_wb((unsigned long)pvPageVAddr, 1); - if (ret) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attribute", - __func__)); - } - } -#else - PVR_UNREFERENCED_PARAMETER(bUnsetMemoryType); -#endif - __free_pages(psPage, uiOrder); -} - -/* Free the struct holding the metadata */ -static PVRSRV_ERROR -_FreeOSPagesArray(PMR_OSPAGEARRAY_DATA *psPageArrayData) -{ - PVR_DPF((PVR_DBG_MESSAGE, "physmem_osmem_linux.c: freed OS memory for PMR @0x%p", psPageArrayData)); - - /* Check if the page array actually still exists. - * It might be the case that has been moved to the page pool */ - if (psPageArrayData->pagearray != NULL) - { - OSFreeMemNoStats(psPageArrayData->pagearray); - } - - kmem_cache_free(g_psLinuxPageArray, psPageArrayData); - - return PVRSRV_OK; -} - -/* Free all or some pages from a sparse page array */ -static PVRSRV_ERROR -_FreeOSPages_Sparse(PMR_OSPAGEARRAY_DATA *psPageArrayData, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 ui32FreePageCount) -{ - IMG_BOOL bSuccess; - IMG_UINT32 uiOrder = psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT; - IMG_UINT32 uiPageIndex, i, j, uiTempIdx = 0; - struct page **ppsPageArray = psPageArrayData->pagearray; - IMG_UINT32 uiNumPages; - - struct page **ppsTempPageArray; - IMG_UINT32 uiTempArraySize; - - /* We really should have something to free before we call this */ - PVR_ASSERT(psPageArrayData->iNumOSPagesAllocated != 0); - - if (pai32FreeIndices == NULL) - { - uiNumPages = psPageArrayData->uiTotalNumOSPages >> uiOrder; - uiTempArraySize = psPageArrayData->iNumOSPagesAllocated; - } - else - { - uiNumPages = ui32FreePageCount; - uiTempArraySize = ui32FreePageCount << uiOrder; - } - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && defined(PVRSRV_ENABLE_MEMORY_STATS) - for (i = 0; i < uiNumPages; i++) - { - IMG_UINT32 idx = pai32FreeIndices ? pai32FreeIndices[i] : i; - - if (NULL != ppsPageArray[idx]) - { - _RemoveMemAllocRecord_UmaPages(psPageArrayData, ppsPageArray[idx]); - } - } -#endif - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_POISON_ON_FREE)) - { - for (i = 0; i < uiNumPages; i++) - { - IMG_UINT32 idx = pai32FreeIndices ? pai32FreeIndices[i] : i; - - if (NULL != ppsPageArray[idx]) - { - _PoisonDevicePage(psPageArrayData->psDevNode, - ppsPageArray[idx], - uiOrder, - psPageArrayData->ui32CPUCacheFlags, - PVRSRV_POISON_ON_FREE_VALUE); - } - } - } - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 uiDevNumPages = uiNumPages; - IMG_UINT32 uiDevPageSize = 1<uiLog2AllocPageSize; - - for (i = 0; i < uiDevNumPages; i++) - { - IMG_UINT32 idx = pai32FreeIndices ? pai32FreeIndices[i] : i; - if (NULL != ppsPageArray[idx]) - { - _FreeOSPage_CMA(psPageArrayData->psDevNode->psDevConfig->pvOSDevice, - uiDevPageSize, - uiOrder, - psPageArrayData->dmavirtarray[idx], - psPageArrayData->dmaphysarray[idx], - ppsPageArray[idx]); - psPageArrayData->dmaphysarray[idx] = (dma_addr_t)0; - psPageArrayData->dmavirtarray[idx] = NULL; - ppsPageArray[idx] = NULL; - uiTempIdx++; - } - } - uiTempIdx <<= uiOrder; - } - else - { - - /* OSAllocMemNoStats required because this code may be run without the bridge lock held */ - ppsTempPageArray = OSAllocMemNoStats(sizeof(struct page*) * uiTempArraySize); - if (ppsTempPageArray == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed free_pages metadata allocation", __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* Put pages in a contiguous array so further processing is easier */ - for (i = 0; i < uiNumPages; i++) - { - uiPageIndex = pai32FreeIndices ? pai32FreeIndices[i] : i; - if (NULL != ppsPageArray[uiPageIndex]) - { - struct page *psPage = ppsPageArray[uiPageIndex]; - - for (j = 0; j < (1<ui32CPUCacheFlags, - ppsTempPageArray, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_UNPINNED), - 0, - uiTempIdx); - if (bSuccess) - { - goto exit_ok; - } - - /* Free pages and reset page caching attributes on x86 */ -#if defined(CONFIG_X86) - if (uiTempIdx != 0 && BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_UNSET_MEMORY_TYPE)) - { - int iError; - iError = set_pages_array_wb(ppsTempPageArray, uiTempIdx); - - if (iError) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attributes", __func__)); - } - } -#endif - - /* Free the pages */ - for (i = 0; i < uiTempIdx; i++) - { - __free_pages(ppsTempPageArray[i], 0); - } - - /* Free the temp page array here if it did not move to the pool */ - OSFreeMemNoStats(ppsTempPageArray); - } - -exit_ok: - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_ENABLE_MEMORY_STATS) - _DecrMemAllocStat_UmaPages(((uiTempIdx * PAGE_SIZE)-(psPageArrayData->ui32CMAAdjustedPageCount)), - psPageArrayData->uiPid); -#endif - - if (pai32FreeIndices && ((uiTempIdx >> uiOrder) != ui32FreePageCount)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Probable sparse duplicate indices: ReqFreeCount: %d " - "ActualFreedCount: %d", __func__, ui32FreePageCount, (uiTempIdx >> uiOrder))); - } - /* Update metadata */ - psPageArrayData->iNumOSPagesAllocated -= uiTempIdx; - PVR_ASSERT(0 <= psPageArrayData->iNumOSPagesAllocated); - return PVRSRV_OK; -} - -/* Free all the pages in a page array */ -static PVRSRV_ERROR -_FreeOSPages_Fast(PMR_OSPAGEARRAY_DATA *psPageArrayData) -{ - IMG_BOOL bSuccess; - IMG_UINT32 i; - IMG_UINT32 uiNumPages = psPageArrayData->uiTotalNumOSPages; - IMG_UINT32 uiOrder = psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT; - IMG_UINT32 uiDevNumPages = uiNumPages >> uiOrder; - IMG_UINT32 uiDevPageSize = PAGE_SIZE << uiOrder; - struct page **ppsPageArray = psPageArrayData->pagearray; - - /* We really should have something to free before we call this */ - PVR_ASSERT(psPageArrayData->iNumOSPagesAllocated != 0); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - for (i = 0; i < uiDevNumPages; i++) - { - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - _RemoveMemAllocRecord_UmaPages(psPageArrayData, ppsPageArray[i]); - }else - { - _RemoveMemAllocRecord_UmaPages(psPageArrayData, ppsPageArray[i << uiOrder]); - } - } -#else - _DecrMemAllocStat_UmaPages(((uiNumPages * PAGE_SIZE)-(psPageArrayData->ui32CMAAdjustedPageCount)), - psPageArrayData->uiPid); -#endif -#endif - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_POISON_ON_FREE)) - { - for (i = 0; i < uiDevNumPages; i++) - { - _PoisonDevicePage(psPageArrayData->psDevNode, - ppsPageArray[i], - uiOrder, - psPageArrayData->ui32CPUCacheFlags, - PVRSRV_POISON_ON_FREE_VALUE); - } - } - - /* Try to move the page array to the pool */ - bSuccess = _PutPagesToPoolLocked(psPageArrayData->ui32CPUCacheFlags, - ppsPageArray, - BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_UNPINNED), - uiOrder, - uiNumPages); - if (bSuccess) - { - psPageArrayData->pagearray = NULL; - goto exit_ok; - } - - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_IS_CMA)) - { - for (i = 0; i < uiDevNumPages; i++) - { - _FreeOSPage_CMA(psPageArrayData->psDevNode->psDevConfig->pvOSDevice, - uiDevPageSize, - uiOrder, - psPageArrayData->dmavirtarray[i], - psPageArrayData->dmaphysarray[i], - ppsPageArray[i]); - psPageArrayData->dmaphysarray[i] = (dma_addr_t)0; - psPageArrayData->dmavirtarray[i] = NULL; - ppsPageArray[i] = NULL; - } - } - else - { -#if defined(CONFIG_X86) - if (BIT_ISSET(psPageArrayData->ui32AllocFlags, FLAG_UNSET_MEMORY_TYPE)) - { - int ret; - - ret = set_pages_array_wb(ppsPageArray, uiNumPages); - if (ret) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attributes", - __func__)); - } - } -#endif - - for (i = 0; i < uiNumPages; i++) - { - _FreeOSPage(uiOrder, IMG_FALSE, ppsPageArray[i]); - ppsPageArray[i] = NULL; - } - } - -exit_ok: - /* Update metadata */ - psPageArrayData->iNumOSPagesAllocated = 0; - return PVRSRV_OK; -} - -/* Free pages from a page array. - * Takes care of mem stats and chooses correct free path depending on parameters. */ -static PVRSRV_ERROR -_FreeOSPages(PMR_OSPAGEARRAY_DATA *psPageArrayData, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 ui32FreePageCount) -{ - PVRSRV_ERROR eError; - - /* Go the sparse or non-sparse path */ - if (psPageArrayData->iNumOSPagesAllocated != psPageArrayData->uiTotalNumOSPages - || pai32FreeIndices != NULL) - { - eError = _FreeOSPages_Sparse(psPageArrayData, - pai32FreeIndices, - ui32FreePageCount); - } - else - { - eError = _FreeOSPages_Fast(psPageArrayData); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "_FreeOSPages_FreePages failed")); - } - - _DumpPageArray(psPageArrayData->pagearray, - psPageArrayData->uiTotalNumOSPages >> - (psPageArrayData->uiLog2AllocPageSize - PAGE_SHIFT) ); - - return eError; -} - -/* - * - * Implementation of callback functions - * - */ - -/* Destruction function is called after last reference disappears, - * but before PMR itself is freed. - */ -static PVRSRV_ERROR -PMRFinalizeOSMem(PMR_IMPL_PRIVDATA pvPriv) -{ - PVRSRV_ERROR eError; - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pvPriv; - - /* We can't free pages until now. */ - if (psOSPageArrayData->iNumOSPagesAllocated != 0) - { -#if defined(DEBUG) && defined(SUPPORT_VALIDATION) - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_UINT32 ui32UMALeakMax = psPVRSRVData->sMemLeakIntervals.ui32GPU; - - mutex_lock(&g_sUMALeakMutex); - - g_ui32UMALeakCounter++; - if (ui32UMALeakMax && g_ui32UMALeakCounter >= ui32UMALeakMax) - { - g_ui32UMALeakCounter = 0; - mutex_unlock(&g_sUMALeakMutex); - - PVR_DPF((PVR_DBG_WARNING, "%s: Skipped freeing of PMR 0x%p to trigger memory leak.", __func__, pvPriv)); - return PVRSRV_OK; - } - - mutex_unlock(&g_sUMALeakMutex); -#endif - _PagePoolLock(); - if (BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_UNPINNED)) - { - _RemoveUnpinListEntryUnlocked(psOSPageArrayData); - } - _PagePoolUnlock(); - - eError = _FreeOSPages(psOSPageArrayData, - NULL, - 0); - PVR_ASSERT(eError == PVRSRV_OK); /* can we do better? */ - } - - eError = _FreeOSPagesArray(psOSPageArrayData); - PVR_ASSERT(eError == PVRSRV_OK); /* can we do better? */ - return PVRSRV_OK; -} - -/* Callback function for locking the system physical page addresses. - * This function must be called before the lookup address func. */ -static PVRSRV_ERROR -PMRLockSysPhysAddressesOSMem(PMR_IMPL_PRIVDATA pvPriv) -{ - PVRSRV_ERROR eError; - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pvPriv; - - if (BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_ONDEMAND)) - { - /* Allocate Memory for deferred allocation */ - eError = _AllocOSPages(psOSPageArrayData, NULL, psOSPageArrayData->uiTotalNumOSPages); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - eError = PVRSRV_OK; - return eError; -} - -static PVRSRV_ERROR -PMRUnlockSysPhysAddressesOSMem(PMR_IMPL_PRIVDATA pvPriv) -{ - /* Just drops the refcount. */ - PVRSRV_ERROR eError = PVRSRV_OK; - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pvPriv; - - if (BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_ONDEMAND)) - { - /* Free Memory for deferred allocation */ - eError = _FreeOSPages(psOSPageArrayData, - NULL, - 0); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} - -static INLINE IMG_BOOL IsOffsetValid(const PMR_OSPAGEARRAY_DATA *psOSPageArrayData, - IMG_UINT32 ui32Offset) -{ - return (ui32Offset >> psOSPageArrayData->uiLog2AllocPageSize) < - psOSPageArrayData->uiTotalNumOSPages; -} - -/* Determine PA for specified offset into page array. */ -static IMG_DEV_PHYADDR GetOffsetPA(const PMR_OSPAGEARRAY_DATA *psOSPageArrayData, - IMG_UINT32 ui32Offset) -{ - IMG_UINT32 ui32Log2AllocPageSize = psOSPageArrayData->uiLog2AllocPageSize; - IMG_UINT32 ui32PageIndex = ui32Offset >> ui32Log2AllocPageSize; - IMG_UINT32 ui32InPageOffset = ui32Offset - (ui32PageIndex << ui32Log2AllocPageSize); - IMG_DEV_PHYADDR sPA; - - PVR_ASSERT(ui32InPageOffset < (1U << ui32Log2AllocPageSize)); - - sPA.uiAddr = page_to_phys(psOSPageArrayData->pagearray[ui32PageIndex]); - sPA.uiAddr += ui32InPageOffset; - - return sPA; -} - -/* N.B. It is assumed that PMRLockSysPhysAddressesOSMem() is called _before_ this function! */ -static PVRSRV_ERROR -PMRSysPhysAddrOSMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_BOOL *pbValid, - IMG_DEV_PHYADDR *psDevPAddr) -{ - const PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pvPriv; - IMG_UINT32 uiIdx; - - if (psOSPageArrayData->uiLog2AllocPageSize < ui32Log2PageSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Requested physical addresses from PMR " - "for incompatible contiguity %u!", - __func__, - ui32Log2PageSize)); - return PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY; - } - - for (uiIdx=0; uiIdx < ui32NumOfPages; uiIdx++) - { - if (pbValid[uiIdx]) - { - PVR_LOG_RETURN_IF_FALSE(IsOffsetValid(psOSPageArrayData, puiOffset[uiIdx]), - "puiOffset out of range", PVRSRV_ERROR_OUT_OF_RANGE); - - psDevPAddr[uiIdx] = GetOffsetPA(psOSPageArrayData, puiOffset[uiIdx]); - -#if !defined(PVR_LINUX_PHYSMEM_USE_HIGHMEM_ONLY) - /* this is just a precaution, normally this should be always - * available */ - if (psOSPageArrayData->ui64DmaMask) - { - if (psDevPAddr[uiIdx].uiAddr > psOSPageArrayData->ui64DmaMask) - { - PVR_DPF((PVR_DBG_ERROR, "%s: physical address" - " (%" IMG_UINT64_FMTSPECX ") out of allowable range" - " [0; %" IMG_UINT64_FMTSPECX "]", __func__, - psDevPAddr[uiIdx].uiAddr, - psOSPageArrayData->ui64DmaMask)); - BUG(); - } - } -#endif - } - } - - return PVRSRV_OK; -} - -typedef struct _PMR_OSPAGEARRAY_KERNMAP_DATA_ { - void *pvBase; - IMG_UINT32 ui32PageCount; - pgprot_t PageProps; -} PMR_OSPAGEARRAY_KERNMAP_DATA; - -static PVRSRV_ERROR -PMRAcquireKernelMappingDataOSMem(PMR_IMPL_PRIVDATA pvPriv, - size_t uiOffset, - size_t uiSize, - void **ppvKernelAddressOut, - IMG_HANDLE *phHandleOut, - PMR_FLAGS_T ulFlags) -{ - PVRSRV_ERROR eError; - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pvPriv; - void *pvAddress; - pgprot_t prot = PAGE_KERNEL; - IMG_UINT32 ui32PageOffset=0; - size_t uiMapOffset=0; - IMG_UINT32 ui32PageCount = 0; - IMG_UINT32 uiLog2AllocPageSize = psOSPageArrayData->uiLog2AllocPageSize; - IMG_UINT32 uiOSPageShift = OSGetPageShift(); - IMG_UINT32 uiPageSizeDiff = 0; - struct page **pagearray; - PMR_OSPAGEARRAY_KERNMAP_DATA *psData; - - /* For cases device page size greater than the OS page size, - * multiple physically contiguous OS pages constitute one device page. - * However only the first page address of such an ensemble is stored - * as part of the mapping table in the driver. Hence when mapping the PMR - * in part/full, all OS pages that constitute the device page - * must also be mapped to kernel. - * - * For the case where device page size less than OS page size, - * treat it the same way as the page sizes are equal */ - if (uiLog2AllocPageSize > uiOSPageShift) - { - uiPageSizeDiff = uiLog2AllocPageSize - uiOSPageShift; - } - - /* - Zero offset and size as a special meaning which means map in the - whole of the PMR, this is due to fact that the places that call - this callback might not have access to be able to determine the - physical size - */ - if ((uiOffset == 0) && (uiSize == 0)) - { - ui32PageOffset = 0; - uiMapOffset = 0; - /* Page count = amount of OS pages */ - ui32PageCount = psOSPageArrayData->iNumOSPagesAllocated; - } - else - { - size_t uiEndoffset; - - ui32PageOffset = uiOffset >> uiLog2AllocPageSize; - uiMapOffset = uiOffset - (ui32PageOffset << uiLog2AllocPageSize); - uiEndoffset = uiOffset + uiSize - 1; - /* Add one as we want the count, not the offset */ - /* Page count = amount of device pages (note uiLog2AllocPageSize being used) */ - ui32PageCount = (uiEndoffset >> uiLog2AllocPageSize) + 1; - ui32PageCount -= ui32PageOffset; - - /* The OS page count to be mapped might be different if the - * OS page size is lesser than the device page size */ - ui32PageCount <<= uiPageSizeDiff; - } - - switch (PVRSRV_CPU_CACHE_MODE(psOSPageArrayData->ui32CPUCacheFlags)) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - prot = pgprot_noncached(prot); - break; - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: - prot = pgprot_writecombine(prot); - break; - - case PVRSRV_MEMALLOCFLAG_CPU_CACHED: - break; - - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - if (uiPageSizeDiff) - { - /* Each device page can be broken down into ui32SubPageCount OS pages */ - IMG_UINT32 ui32SubPageCount = 1 << uiPageSizeDiff; - IMG_UINT32 i; - struct page **psPage = &psOSPageArrayData->pagearray[ui32PageOffset]; - - /* Allocate enough memory for the OS page pointers for this mapping */ - pagearray = OSAllocMem(ui32PageCount * sizeof(pagearray[0])); - - if (pagearray == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e0; - } - - /* construct array that holds the page pointers that constitute the requested - * mapping */ - for (i = 0; i < ui32PageCount; i++) - { - IMG_UINT32 ui32OSPageArrayIndex = i / ui32SubPageCount; - IMG_UINT32 ui32OSPageArrayOffset = i % ui32SubPageCount; - - /* - * The driver only stores OS page pointers for the first OS page - * within each device page (psPage[ui32OSPageArrayIndex]). - * Get the next OS page structure at device page granularity, - * then calculate OS page pointers for all the other pages. - */ - pagearray[i] = psPage[ui32OSPageArrayIndex] + ui32OSPageArrayOffset; - } - } - else - { - pagearray = &psOSPageArrayData->pagearray[ui32PageOffset]; - } - - psData = OSAllocMem(sizeof(*psData)); - if (psData == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e1; - } - - pvAddress = pvr_vmap(pagearray, ui32PageCount, VM_READ | VM_WRITE, prot); - if (pvAddress == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e2; - } - - *ppvKernelAddressOut = pvAddress + uiMapOffset; - psData->pvBase = pvAddress; - psData->ui32PageCount = ui32PageCount; - psData->PageProps = prot; - *phHandleOut = psData; - - if (uiPageSizeDiff) - { - OSFreeMem(pagearray); - } - - return PVRSRV_OK; - - /* - error exit paths follow - */ -e2: - OSFreeMem(psData); -e1: - if (uiPageSizeDiff) - { - OSFreeMem(pagearray); - } -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void PMRReleaseKernelMappingDataOSMem(PMR_IMPL_PRIVDATA pvPriv, - IMG_HANDLE hHandle) -{ - PMR_OSPAGEARRAY_KERNMAP_DATA *psData = hHandle; - PVR_UNREFERENCED_PARAMETER(pvPriv); - - pvr_vunmap(psData->pvBase, psData->ui32PageCount, psData->PageProps); - OSFreeMem(psData); -} - -static -PVRSRV_ERROR PMRUnpinOSMem(PMR_IMPL_PRIVDATA pPriv) -{ - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pPriv; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Lock down the pool and add the array to the unpin list */ - _PagePoolLock(); - - /* Check current state */ - PVR_ASSERT(BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_UNPINNED) == IMG_FALSE); - PVR_ASSERT(BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_ONDEMAND) == IMG_FALSE); - - eError = _AddUnpinListEntryUnlocked(psOSPageArrayData); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unable to add allocation to unpinned list (%d).", - __func__, - eError)); - - goto e_exit; - } - - /* Set the Unpinned bit */ - BIT_SET(psOSPageArrayData->ui32AllocFlags, FLAG_UNPINNED); - -e_exit: - _PagePoolUnlock(); - return eError; -} - -static -PVRSRV_ERROR PMRPinOSMem(PMR_IMPL_PRIVDATA pPriv, - PMR_MAPPING_TABLE *psMappingTable) -{ - PVRSRV_ERROR eError; - PMR_OSPAGEARRAY_DATA *psOSPageArrayData = pPriv; - IMG_UINT32 *pui32MapTable = NULL; - IMG_UINT32 i, j = 0, ui32Temp = 0; - - _PagePoolLock(); - - /* Check current state */ - PVR_ASSERT(BIT_ISSET(psOSPageArrayData->ui32AllocFlags, FLAG_UNPINNED)); - - /* Clear unpinned bit */ - BIT_UNSET(psOSPageArrayData->ui32AllocFlags, FLAG_UNPINNED); - - /* If there are still pages in the array remove entries from the pool */ - if (psOSPageArrayData->iNumOSPagesAllocated != 0) - { - _RemoveUnpinListEntryUnlocked(psOSPageArrayData); - _PagePoolUnlock(); - - eError = PVRSRV_OK; - goto e_exit_mapalloc_failure; - } - _PagePoolUnlock(); - - /* If pages were reclaimed we allocate new ones and - * return PVRSRV_ERROR_PMR_NEW_MEMORY */ - if (psMappingTable->ui32NumVirtChunks == 1) - { - eError = _AllocOSPages(psOSPageArrayData, NULL, psOSPageArrayData->uiTotalNumOSPages); - } - else - { - pui32MapTable = (IMG_UINT32 *)OSAllocMem(sizeof(*pui32MapTable) * psMappingTable->ui32NumPhysChunks); - if (NULL == pui32MapTable) - { - eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES; - PVR_DPF((PVR_DBG_ERROR, - "%s: Unable to Alloc Map Table.", - __func__)); - goto e_exit_mapalloc_failure; - } - - for (i = 0, j = 0; i < psMappingTable->ui32NumVirtChunks; i++) - { - ui32Temp = psMappingTable->aui32Translation[i]; - if (TRANSLATION_INVALID != ui32Temp) - { - pui32MapTable[j++] = ui32Temp; - } - } - eError = _AllocOSPages(psOSPageArrayData, pui32MapTable, psMappingTable->ui32NumPhysChunks); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unable to get new pages for unpinned allocation.", - __func__)); - - eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES; - goto e_exit; - } - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Allocating new pages for unpinned allocation. " - "Old content is lost!", - __func__)); - - eError = PVRSRV_ERROR_PMR_NEW_MEMORY; - -e_exit: - OSFreeMem(pui32MapTable); -e_exit_mapalloc_failure: - return eError; -} - -/*************************************************************************/ /*! -@Function PMRChangeSparseMemOSMem -@Description This function Changes the sparse mapping by allocating and - freeing of pages. It changes the GPU and CPU maps accordingly. -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -static PVRSRV_ERROR -PMRChangeSparseMemOSMem(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiFlags) -{ - PVRSRV_ERROR eError; - - PMR_MAPPING_TABLE *psPMRMapTable = PMR_GetMappingTable(psPMR); - PMR_OSPAGEARRAY_DATA *psPMRPageArrayData = (PMR_OSPAGEARRAY_DATA *)pPriv; - struct page **psPageArray = psPMRPageArrayData->pagearray; - void **psDMAVirtArray = psPMRPageArrayData->dmavirtarray; - dma_addr_t *psDMAPhysArray = psPMRPageArrayData->dmaphysarray; - - struct page *psPage; - dma_addr_t psDMAPAddr; - void *pvDMAVAddr; - - IMG_UINT32 ui32AdtnlAllocPages = 0; /*uiLog2AllocPageSize - PAGE_SHIFT; - IMG_BOOL bCMA = BIT_ISSET(psPMRPageArrayData->ui32AllocFlags, FLAG_IS_CMA); - - - /* Check SPARSE flags and calculate pages to allocate and free */ - if (SPARSE_RESIZE_BOTH == (uiFlags & SPARSE_RESIZE_BOTH)) - { - ui32CommonRequestCount = (ui32AllocPageCount > ui32FreePageCount) ? - ui32FreePageCount : ui32AllocPageCount; - - PDUMP_PANIC(PMR_DeviceNode(psPMR), SPARSEMEM_SWAP, "Request to swap alloc & free pages not supported"); - } - - if (SPARSE_RESIZE_ALLOC == (uiFlags & SPARSE_RESIZE_ALLOC)) - { - ui32AdtnlAllocPages = ui32AllocPageCount - ui32CommonRequestCount; - } - else - { - ui32AllocPageCount = 0; - } - - if (SPARSE_RESIZE_FREE == (uiFlags & SPARSE_RESIZE_FREE)) - { - ui32AdtnlFreePages = ui32FreePageCount - ui32CommonRequestCount; - } - else - { - ui32FreePageCount = 0; - } - - if (0 == (ui32CommonRequestCount || ui32AdtnlAllocPages || ui32AdtnlFreePages)) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Missing parameters for number of pages to alloc/free", - __func__)); - return eError; - } - - /* The incoming request is classified into two operations independent of - * each other: alloc & free pages. - * These operations can be combined with two mapping operations as well - * which are GPU & CPU space mappings. - * - * From the alloc and free page requests, the net amount of pages to be - * allocated or freed is computed. Pages that were requested to be freed - * will be reused to fulfil alloc requests. - * - * The order of operations is: - * 1. Allocate new pages from the OS - * 2. Move the free pages from free request to alloc positions. - * 3. Free the rest of the pages not used for alloc - * - * Alloc parameters are validated at the time of allocation - * and any error will be handled then. */ - - /* Validate the free indices */ - if (ui32FreePageCount) - { - if (NULL != pai32FreeIndices){ - - for (ui32Loop = 0; ui32Loop < ui32FreePageCount; ui32Loop++) - { - uiFreepgidx = pai32FreeIndices[ui32Loop]; - - if (uiFreepgidx >= (psPMRPageArrayData->uiTotalNumOSPages >> uiOrder)) - { - eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE; - goto e0; - } - - if (NULL == psPageArray[uiFreepgidx]) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Trying to free non-allocated page", - __func__)); - goto e0; - } - } - } - else - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Given non-zero free count but missing indices array", - __func__)); - return eError; - } - } - - /* Validate the alloc indices */ - for (ui32Loop = ui32AdtnlAllocPages; ui32Loop < ui32AllocPageCount; ui32Loop++) - { - uiAllocpgidx = pai32AllocIndices[ui32Loop]; - - if (uiAllocpgidx >= (psPMRPageArrayData->uiTotalNumOSPages >> uiOrder)) - { - eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE; - goto e0; - } - - if ((NULL != psPageArray[uiAllocpgidx]) || - (TRANSLATION_INVALID != psPMRMapTable->aui32Translation[uiAllocpgidx])) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Trying to allocate already allocated page again", - __func__)); - goto e0; - } - } - - ui32Loop = 0; - - /* Allocate new pages from the OS */ - if (0 != ui32AdtnlAllocPages) - { - eError = _AllocOSPages(psPMRPageArrayData, pai32AllocIndices, ui32AdtnlAllocPages); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: New Addtl Allocation of pages failed", - __func__)); - goto e0; - } - - psPMRMapTable->ui32NumPhysChunks += ui32AdtnlAllocPages; - /*Mark the corresponding pages of translation table as valid */ - for (ui32Loop = 0; ui32Loop < ui32AdtnlAllocPages; ui32Loop++) - { - psPMRMapTable->aui32Translation[pai32AllocIndices[ui32Loop]] = pai32AllocIndices[ui32Loop]; - } - } - - - ui32Index = ui32Loop; - - /* Move the corresponding free pages to alloc request */ - for (ui32Loop = 0; ui32Loop < ui32CommonRequestCount; ui32Loop++, ui32Index++) - { - uiAllocpgidx = pai32AllocIndices[ui32Index]; - uiFreepgidx = pai32FreeIndices[ui32Loop]; - - psPage = psPageArray[uiAllocpgidx]; - psPageArray[uiAllocpgidx] = psPageArray[uiFreepgidx]; - - if (bCMA) - { - pvDMAVAddr = psDMAVirtArray[uiAllocpgidx]; - psDMAPAddr = psDMAPhysArray[uiAllocpgidx]; - psDMAVirtArray[uiAllocpgidx] = psDMAVirtArray[uiFreepgidx]; - psDMAPhysArray[uiAllocpgidx] = psDMAPhysArray[uiFreepgidx]; - } - - psPMRMapTable->aui32Translation[uiFreepgidx] = TRANSLATION_INVALID; - psPMRMapTable->aui32Translation[uiAllocpgidx] = uiAllocpgidx; - psPageArray[uiFreepgidx] = NULL; - if (bCMA) - { - psDMAVirtArray[uiFreepgidx] = NULL; - psDMAPhysArray[uiFreepgidx] = (dma_addr_t)0; - } - } - - /* Free the additional free pages */ - if (0 != ui32AdtnlFreePages) - { - eError = _FreeOSPages(psPMRPageArrayData, - &pai32FreeIndices[ui32Loop], - ui32AdtnlFreePages); - if (eError != PVRSRV_OK) - { - goto e0; - } - psPMRMapTable->ui32NumPhysChunks -= ui32AdtnlFreePages; - while (ui32Loop < ui32FreePageCount) - { - psPMRMapTable->aui32Translation[pai32FreeIndices[ui32Loop]] = TRANSLATION_INVALID; - ui32Loop++; - } - } - - eError = PVRSRV_OK; - -e0: - return eError; -} - -/*************************************************************************/ /*! -@Function PMRChangeSparseMemCPUMapOSMem -@Description This function Changes CPU maps accordingly -@Return PVRSRV_ERROR failure code -*/ /**************************************************************************/ -static -PVRSRV_ERROR PMRChangeSparseMemCPUMapOSMem(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT64 sCpuVAddrBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices) -{ - struct page **psPageArray; - PMR_OSPAGEARRAY_DATA *psPMRPageArrayData = (PMR_OSPAGEARRAY_DATA *)pPriv; - IMG_CPU_PHYADDR sCPUPAddr; - - sCPUPAddr.uiAddr = 0; - psPageArray = psPMRPageArrayData->pagearray; - - return OSChangeSparseMemCPUAddrMap((void **)psPageArray, - sCpuVAddrBase, - sCPUPAddr, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices, - IMG_FALSE); -} - -static PMR_IMPL_FUNCTAB _sPMROSPFuncTab = { - .pfnLockPhysAddresses = &PMRLockSysPhysAddressesOSMem, - .pfnUnlockPhysAddresses = &PMRUnlockSysPhysAddressesOSMem, - .pfnDevPhysAddr = &PMRSysPhysAddrOSMem, - .pfnAcquireKernelMappingData = &PMRAcquireKernelMappingDataOSMem, - .pfnReleaseKernelMappingData = &PMRReleaseKernelMappingDataOSMem, - .pfnReadBytes = NULL, - .pfnWriteBytes = NULL, - .pfnUnpinMem = &PMRUnpinOSMem, - .pfnPinMem = &PMRPinOSMem, - .pfnChangeSparseMem = &PMRChangeSparseMemOSMem, - .pfnChangeSparseMemCPUMap = &PMRChangeSparseMemCPUMapOSMem, - .pfnFinalize = &PMRFinalizeOSMem, -}; - -/* Wrapper around OS page allocation. */ -static PVRSRV_ERROR -DoPageAlloc(PMR_OSPAGEARRAY_DATA *psPrivData, - IMG_UINT32 *puiAllocIndices, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32Log2AllocPageSize) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Do we fill the whole page array or just parts (sparse)? */ - if (ui32NumPhysChunks == ui32NumVirtChunks) - { - /* Allocate the physical pages */ - eError = _AllocOSPages(psPrivData, - NULL, - psPrivData->uiTotalNumOSPages >> - (ui32Log2AllocPageSize - PAGE_SHIFT)); - } - else if (ui32NumPhysChunks != 0) - { - /* Calculate the number of pages we want to allocate */ - IMG_UINT32 ui32PagesToAlloc = - (IMG_UINT32)((((ui32NumPhysChunks * uiChunkSize) - 1) >> ui32Log2AllocPageSize) + 1); - - /* Make sure calculation is correct */ - PVR_ASSERT(((PMR_SIZE_T) ui32PagesToAlloc << ui32Log2AllocPageSize) == - (ui32NumPhysChunks * uiChunkSize)); - - /* Allocate the physical pages */ - eError = _AllocOSPages(psPrivData, puiAllocIndices, - ui32PagesToAlloc); - } - - return eError; -} - -static void _EncodeAllocationFlags(IMG_UINT32 uiLog2AllocPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32* ui32AllocFlags) -{ - - /* - * Use CMA framework if order is greater than OS page size; please note - * that OSMMapPMRGeneric() has the same expectation as well. - */ - /* IsCMA? */ - if (uiLog2AllocPageSize > PAGE_SHIFT) - { - BIT_SET(*ui32AllocFlags, FLAG_IS_CMA); - } - - /* OnDemand? */ - if (PVRSRV_CHECK_ON_DEMAND(uiFlags)) - { - BIT_SET(*ui32AllocFlags, FLAG_ONDEMAND); - } - - /* Zero? */ - if (PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags)) - { - BIT_SET(*ui32AllocFlags, FLAG_ZERO); - } - - /* Poison on alloc? */ - if (PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags)) - { - BIT_SET(*ui32AllocFlags, FLAG_POISON_ON_ALLOC); - } - -#if defined(DEBUG) - /* Poison on free? */ - if (PVRSRV_CHECK_POISON_ON_FREE(uiFlags)) - { - BIT_SET(*ui32AllocFlags, FLAG_POISON_ON_FREE); - } -#endif - - /* Indicate whether this is an allocation with default caching attribute (i.e cached) or not */ - if (PVRSRV_CHECK_CPU_UNCACHED(uiFlags) || - PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags)) - { - BIT_SET(*ui32AllocFlags, FLAG_UNSET_MEMORY_TYPE); - } - -} - -void PhysmemGetOSRamMemStats(PHEAP_IMPL_DATA pvImplData, - IMG_UINT64 *pui64TotalSize, - IMG_UINT64 *pui64FreeSize) -{ - struct sysinfo sMeminfo; - si_meminfo(&sMeminfo); - - PVR_UNREFERENCED_PARAMETER(pvImplData); - - *pui64TotalSize = sMeminfo.totalram * sMeminfo.mem_unit; - *pui64FreeSize = sMeminfo.freeram * sMeminfo.mem_unit; - -} - -PVRSRV_ERROR -PhysmemNewOSRamBackedPMR(PHYS_HEAP *psPhysHeap, - CONNECTION_DATA *psConnection, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *puiAllocIndices, - IMG_UINT32 uiLog2AllocPageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - IMG_PID uiPid, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - PMR *psPMR; - struct _PMR_OSPAGEARRAY_DATA_ *psPrivData; - PMR_FLAGS_T uiPMRFlags; - IMG_UINT32 ui32CPUCacheFlags; - IMG_UINT32 ui32AllocFlags = 0; - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPhysHeap); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* - * The host driver (but not guest) can still use this factory for firmware - * allocations - */ - if (PVRSRV_VZ_MODE_IS(GUEST) && PVRSRV_CHECK_FW_MAIN(uiFlags)) - { - PVR_ASSERT(0); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto errorOnParam; - } - - /* Select correct caching mode */ - eError = DevmemCPUCacheMode(psDevNode, uiFlags, &ui32CPUCacheFlags); - if (eError != PVRSRV_OK) - { - goto errorOnParam; - } - - if (PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags)) - { - ui32CPUCacheFlags |= PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN; - } - - _EncodeAllocationFlags(uiLog2AllocPageSize, uiFlags, &ui32AllocFlags); - - -#if defined(PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES) - /* Overwrite flags and always zero pages that could go back to UM */ - BIT_SET(ui32AllocFlags, FLAG_ZERO); - BIT_UNSET(ui32AllocFlags, FLAG_POISON_ON_ALLOC); -#endif - - /* Physical allocation alignment is generally not supported except under - very restrictive conditions, also there is a maximum alignment value - which must not exceed the largest device page-size. If these are not - met then fail the aligned-requested allocation */ - if (BIT_ISSET(ui32AllocFlags, FLAG_IS_CMA)) - { - IMG_UINT32 uiAlign = 1 << uiLog2AllocPageSize; - if (uiAlign > uiSize || uiAlign > (1 << PVR_MAX_PHYSMEM_CONTIG_ALLOC_LOG2PGSZ)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid PA alignment: size 0x%llx, align 0x%x", - __func__, uiSize, uiAlign)); - eError = PVRSRV_ERROR_INVALID_ALIGNMENT; - goto errorOnParam; - } - PVR_ASSERT(uiLog2AllocPageSize > PVR_MIN_PHYSMEM_CONTIG_ALLOC_LOG2PGSZ); - } - - /* Create Array structure that hold the physical pages */ - eError = _AllocOSPageArray(psDevNode, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - uiLog2AllocPageSize, - ui32AllocFlags, - ui32CPUCacheFlags, - uiPid, - &psPrivData); - if (eError != PVRSRV_OK) - { - goto errorOnAllocPageArray; - } - - if (!BIT_ISSET(ui32AllocFlags, FLAG_ONDEMAND)) - { - eError = DoPageAlloc(psPrivData, puiAllocIndices, ui32NumPhysChunks, - ui32NumVirtChunks, uiChunkSize, uiLog2AllocPageSize); - if (eError != PVRSRV_OK) - { - goto errorOnAllocPages; - } - } - - /* - * In this instance, we simply pass flags straight through. - * - * Generically, uiFlags can include things that control the PMR factory, but - * we don't need any such thing (at the time of writing!), and our caller - * specifies all PMR flags so we don't need to meddle with what was given to - * us. - */ - uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK); - - /* - * Check no significant bits were lost in cast due to different bit widths - * for flags - */ - PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK)); - - if (BIT_ISSET(ui32AllocFlags, FLAG_ONDEMAND)) - { - PDUMPCOMMENT(PhysHeapDeviceNode(psPhysHeap), "Deferred Allocation PMR (UMA)"); - } - - eError = PMRCreatePMR(psPhysHeap, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - puiAllocIndices, - uiLog2AllocPageSize, - uiPMRFlags, - pszAnnotation, - &_sPMROSPFuncTab, - psPrivData, - PMR_TYPE_OSMEM, - &psPMR, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - goto errorOnCreate; - } - - *ppsPMRPtr = psPMR; - - return PVRSRV_OK; - -errorOnCreate: - if (!BIT_ISSET(ui32AllocFlags, FLAG_ONDEMAND)) - { - eError2 = _FreeOSPages(psPrivData, NULL, 0); - PVR_ASSERT(eError2 == PVRSRV_OK); - } - -errorOnAllocPages: - eError2 = _FreeOSPagesArray(psPrivData); - PVR_ASSERT(eError2 == PVRSRV_OK); - -errorOnAllocPageArray: -errorOnParam: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.h b/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.h deleted file mode 100644 index 89706fffdc5cd..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_osmem_linux.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linux OS physmem implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PHYSMEM_OSMEM_LINUX_H -#define PHYSMEM_OSMEM_LINUX_H - -void LinuxInitPhysmem(void); -void LinuxDeinitPhysmem(void); - -#endif /* PHYSMEM_OSMEM_LINUX_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_test.c b/drivers/gpu/drm/img-rogue/1.17/physmem_test.c deleted file mode 100644 index 3874594dcdb0b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_test.c +++ /dev/null @@ -1,710 +0,0 @@ -/*************************************************************************/ /*! -@Title Physmem_test -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Single entry point for testing of page factories -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "physmem_test.h" -#include "device.h" -#include "syscommon.h" -#include "pmr.h" -#include "osfunc.h" -#include "physmem.h" -#include "physmem_osmem.h" -#include "physmem_lma.h" -#include "pvrsrv.h" - -#define PHYSMEM_TEST_PAGES 2 /* Mem test pages */ -#define PHYSMEM_TEST_PASSES_MAX 1000 /* Limit number of passes to some reasonable value */ - - -/* Test patterns for mem test */ - -static const IMG_UINT64 gui64Patterns[] = { - 0, - 0xffffffffffffffffULL, - 0x5555555555555555ULL, - 0xaaaaaaaaaaaaaaaaULL, - 0x1111111111111111ULL, - 0x2222222222222222ULL, - 0x4444444444444444ULL, - 0x8888888888888888ULL, - 0x3333333333333333ULL, - 0x6666666666666666ULL, - 0x9999999999999999ULL, - 0xccccccccccccccccULL, - 0x7777777777777777ULL, - 0xbbbbbbbbbbbbbbbbULL, - 0xddddddddddddddddULL, - 0xeeeeeeeeeeeeeeeeULL, - 0x7a6c7258554e494cULL, -}; - -static const IMG_UINT32 gui32Patterns[] = { - 0, - 0xffffffffU, - 0x55555555U, - 0xaaaaaaaaU, - 0x11111111U, - 0x22222222U, - 0x44444444U, - 0x88888888U, - 0x33333333U, - 0x66666666U, - 0x99999999U, - 0xccccccccU, - 0x77777777U, - 0xbbbbbbbbU, - 0xddddddddU, - 0xeeeeeeeeU, - 0x7a6c725cU, -}; - -static const IMG_UINT16 gui16Patterns[] = { - 0, - 0xffffU, - 0x5555U, - 0xaaaaU, - 0x1111U, - 0x2222U, - 0x4444U, - 0x8888U, - 0x3333U, - 0x6666U, - 0x9999U, - 0xccccU, - 0x7777U, - 0xbbbbU, - 0xddddU, - 0xeeeeU, - 0x7a6cU, -}; - -static const IMG_UINT8 gui8Patterns[] = { - 0, - 0xffU, - 0x55U, - 0xaaU, - 0x11U, - 0x22U, - 0x44U, - 0x88U, - 0x33U, - 0x66U, - 0x99U, - 0xccU, - 0x77U, - 0xbbU, - 0xddU, - 0xeeU, - 0x6cU, -}; - - -/* Following function does minimal required initialisation for mem test using dummy device node */ -static PVRSRV_ERROR -PhysMemTestInit(PVRSRV_DEVICE_NODE **ppsDeviceNode, PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_ERROR eError; - - /* Dummy device node */ - psDeviceNode = OSAllocZMem(sizeof(*psDeviceNode)); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode, "OSAllocZMem"); - - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_INIT; - psDeviceNode->psDevConfig = psDevConfig; - psDeviceNode->eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_ON; - - /* Initialise Phys mem heaps */ - eError = PVRSRVPhysMemHeapsInit(psDeviceNode, psDevConfig); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVPhysMemHeapsInit", ErrorSysDevDeInit); - - *ppsDeviceNode = psDeviceNode; - - return PVRSRV_OK; - -ErrorSysDevDeInit: - psDevConfig->psDevNode = NULL; - OSFreeMem(psDeviceNode); - return eError; -} - -/* Undo initialisation done for mem test */ -static void -PhysMemTestDeInit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* Deinitialise Phys mem heaps */ - PVRSRVPhysMemHeapsDeinit(psDeviceNode); - - OSFreeMem(psDeviceNode); -} - -/* Test for PMR factory validation */ -static PVRSRV_ERROR -PMRValidationTest(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ - PVRSRV_ERROR eError, eError1; - IMG_UINT32 i = 0, j = 0, ui32Index = 0; - IMG_UINT32 *pui32MappingTable = NULL; - PMR *psPMR = NULL; - IMG_BOOL *pbValid; - IMG_DEV_PHYADDR *apsDevPAddr; - IMG_UINT32 ui32NumOfPages = 10, ui32NumOfPhysPages = 5; - size_t uiMappedSize, uiPageSize; - IMG_UINT8 *pcWriteBuffer, *pcReadBuffer; - IMG_HANDLE hPrivData = NULL; - void *pvKernAddr = NULL; - - uiPageSize = OSGetPageSize(); - - /* Allocate OS memory for PMR page list */ - apsDevPAddr = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEV_PHYADDR)); - PVR_LOG_RETURN_IF_NOMEM(apsDevPAddr, "OSAllocMem"); - - /* Allocate OS memory for PMR page state */ - pbValid = OSAllocMem(ui32NumOfPages * sizeof(IMG_BOOL)); - PVR_LOG_GOTO_IF_NOMEM(pbValid, eError, ErrorFreePMRPageListMem); - OSCachedMemSet(pbValid, 0, ui32NumOfPages * sizeof(IMG_BOOL)); - - /* Allocate OS memory for write buffer */ - pcWriteBuffer = OSAllocMem(uiPageSize); - PVR_LOG_GOTO_IF_NOMEM(pcWriteBuffer, eError, ErrorFreePMRPageStateMem); - OSCachedMemSet(pcWriteBuffer, 0xF, uiPageSize); - - /* Allocate OS memory for read buffer */ - pcReadBuffer = OSAllocMem(uiPageSize); - PVR_LOG_GOTO_IF_NOMEM(pcReadBuffer, eError, ErrorFreeWriteBuffer); - - /* Allocate OS memory for mapping table */ - pui32MappingTable = (IMG_UINT32 *)OSAllocMem(ui32NumOfPhysPages * sizeof(*pui32MappingTable)); - PVR_LOG_GOTO_IF_NOMEM(pui32MappingTable, eError, ErrorFreeReadBuffer); - - /* Pages having even index will have physical backing in PMR */ - for (ui32Index=0; ui32Index < ui32NumOfPages; ui32Index+=2) - { - pui32MappingTable[i++] = ui32Index; - } - - /* Allocate Sparse PMR with SPARSE | READ | WRITE | UNCACHED_WC attributes */ - uiFlags |= PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC; - - /* Allocate a sparse PMR from given physical heap - CPU/GPU/FW */ - eError = PhysmemNewRamBackedPMR(NULL, - psDeviceNode, - ui32NumOfPages * uiPageSize, - uiPageSize, - ui32NumOfPhysPages, - ui32NumOfPages, - pui32MappingTable, - OSGetPageShift(), - uiFlags, - sizeof("PMR ValidationTest"), - "PMR ValidationTest", - OSGetCurrentClientProcessIDKM(), - &psPMR, - PDUMP_NONE, - NULL); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to allocate a PMR")); - goto ErrorFreeMappingTable; - } - - /* Check whether allocated PMR can be locked and obtain physical addresses - * of underlying memory pages. - */ - eError = PMRLockSysPhysAddresses(psPMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to lock PMR")); - goto ErrorUnrefPMR; - } - - /* Get the Device physical addresses of the pages */ - eError = PMR_DevPhysAddr(psPMR, OSGetPageShift(), ui32NumOfPages, 0, apsDevPAddr, pbValid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to map PMR pages into device physical addresses")); - goto ErrorUnlockPhysAddresses; - } - - /* Check whether device address of each physical page is OS PAGE_SIZE aligned */ - for (i = 0; i < ui32NumOfPages; i++) - { - if (pbValid[i]) - { - if ((apsDevPAddr[i].uiAddr & OSGetPageMask()) != 0) - { - PVR_DPF((PVR_DBG_ERROR, "Physical memory of PMR is not page aligned")); - eError = PVRSRV_ERROR_MEMORY_TEST_FAILED; - goto ErrorUnlockPhysAddresses; - } - } - } - - /* Acquire kernel virtual address of each physical page and write to it - * and then release it. - */ - for (i = 0; i < ui32NumOfPages; i++) - { - if (pbValid[i]) - { - eError = PMRAcquireSparseKernelMappingData(psPMR, (i * uiPageSize), uiPageSize, &pvKernAddr, &uiMappedSize, &hPrivData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to Acquire Kernel Mapping of PMR")); - goto ErrorUnlockPhysAddresses; - } - OSCachedMemCopyWMB(pvKernAddr, pcWriteBuffer, OSGetPageSize()); - - eError = PMRReleaseKernelMappingData(psPMR, hPrivData); - PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData"); - } - } - - /* Acquire kernel virtual address of each physical page and read - * from it and check where contents are intact. - */ - for (i = 0; i < ui32NumOfPages; i++) - { - if (pbValid[i]) - { - eError = PMRAcquireSparseKernelMappingData(psPMR, (i * uiPageSize), uiPageSize, &pvKernAddr, &uiMappedSize, &hPrivData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to Acquire Kernel Mapping of PMR")); - goto ErrorUnlockPhysAddresses; - } - OSCachedMemSet(pcReadBuffer, 0x0, uiPageSize); - OSCachedMemCopy(pcReadBuffer, pvKernAddr, uiMappedSize); - - eError = PMRReleaseKernelMappingData(psPMR, hPrivData); - PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData"); - - for (j = 0; j < uiPageSize; j++) - { - if (pcReadBuffer[j] != pcWriteBuffer[j]) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", - __func__, pcReadBuffer[j], pcWriteBuffer[j])); - eError = PVRSRV_ERROR_MEMORY_TEST_FAILED; - goto ErrorUnlockPhysAddresses; - } - } - } - } - -ErrorUnlockPhysAddresses: - /* Unlock and Unref the PMR to destroy it */ - eError1 = PMRUnlockSysPhysAddresses(psPMR); - if (eError1 != PVRSRV_OK) - { - eError = (eError == PVRSRV_OK)? eError1 : eError; - PVR_DPF((PVR_DBG_ERROR, "Failed to unlock PMR")); - } - -ErrorUnrefPMR: - eError1 = PMRUnrefPMR(psPMR); - if (eError1 != PVRSRV_OK) - { - eError = (eError == PVRSRV_OK)? eError1 : eError; - PVR_DPF((PVR_DBG_ERROR, "Failed to free PMR")); - } -ErrorFreeMappingTable: - OSFreeMem(pui32MappingTable); -ErrorFreeReadBuffer: - OSFreeMem(pcReadBuffer); -ErrorFreeWriteBuffer: - OSFreeMem(pcWriteBuffer); -ErrorFreePMRPageStateMem: - OSFreeMem(pbValid); -ErrorFreePMRPageListMem: - OSFreeMem(apsDevPAddr); - - return eError; -} - -#define DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, Patterns, NumOfPatterns, Error, ptr, i) \ - for (i = 0; i < NumOfPatterns; i++) \ - { \ - /* Write pattern */ \ - for (ptr = StartAddr; ptr < EndAddr; ptr++) \ - { \ - *ptr = Patterns[i]; \ - } \ - \ - /* Read back and validate pattern */ \ - for (ptr = StartAddr; ptr < EndAddr ; ptr++) \ - { \ - if (*ptr != Patterns[i]) \ - { \ - Error = PVRSRV_ERROR_MEMORY_TEST_FAILED; \ - break; \ - } \ - } \ - \ - if (Error != PVRSRV_OK) \ - { \ - break; \ - } \ - } - -static PVRSRV_ERROR -TestPatternU8(void *pvKernAddr, size_t uiMappedSize) -{ - IMG_UINT8 *StartAddr = (IMG_UINT8 *) pvKernAddr; - IMG_UINT8 *EndAddr = ((IMG_UINT8 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT8)); - IMG_UINT8 *p; - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT8)) == 0); - - DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui8Patterns, sizeof(gui8Patterns)/sizeof(IMG_UINT8), eError, p, i); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", - __func__, *p, gui8Patterns[i])); - } - - return eError; -} - - -static PVRSRV_ERROR -TestPatternU16(void *pvKernAddr, size_t uiMappedSize) -{ - IMG_UINT16 *StartAddr = (IMG_UINT16 *) pvKernAddr; - IMG_UINT16 *EndAddr = ((IMG_UINT16 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT16)); - IMG_UINT16 *p; - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT16)) == 0); - - DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui16Patterns, sizeof(gui16Patterns)/sizeof(IMG_UINT16), eError, p, i); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Test failed. Got (0x%hx), expected (0x%hx)!", - __func__, *p, gui16Patterns[i])); - } - - return eError; -} - -static PVRSRV_ERROR -TestPatternU32(void *pvKernAddr, size_t uiMappedSize) -{ - IMG_UINT32 *StartAddr = (IMG_UINT32 *) pvKernAddr; - IMG_UINT32 *EndAddr = ((IMG_UINT32 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT32)); - IMG_UINT32 *p; - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT32)) == 0); - - DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui32Patterns, sizeof(gui32Patterns)/sizeof(IMG_UINT32), eError, p, i); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Test failed. Got (0x%x), expected (0x%x)!", - __func__, *p, gui32Patterns[i])); - } - - return eError; -} - -static PVRSRV_ERROR -TestPatternU64(void *pvKernAddr, size_t uiMappedSize) -{ - IMG_UINT64 *StartAddr = (IMG_UINT64 *) pvKernAddr; - IMG_UINT64 *EndAddr = ((IMG_UINT64 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT64)); - IMG_UINT64 *p; - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT64)) == 0); - - DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui64Patterns, sizeof(gui64Patterns)/sizeof(IMG_UINT64), eError, p, i); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Test failed. Got (0x%llx), expected (0x%llx)!", - __func__, *p, gui64Patterns[i])); - } - - return eError; -} - -static PVRSRV_ERROR -TestSplitCacheline(void *pvKernAddr, size_t uiMappedSize) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - size_t uiCacheLineSize; - size_t uiBlockSize; - size_t j; - IMG_UINT8 *pcWriteBuffer, *pcReadBuffer; - IMG_UINT8 *StartAddr = (IMG_UINT8 *) pvKernAddr; - IMG_UINT8 *EndAddr, *p; - - uiCacheLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE); - - if (uiCacheLineSize > 0) - { - uiBlockSize = (uiCacheLineSize * 2)/3; /* split cacheline */ - - pcWriteBuffer = OSAllocMem(uiBlockSize); - PVR_LOG_RETURN_IF_NOMEM(pcWriteBuffer, "OSAllocMem"); - - /* Fill the write buffer with test data, 0xAB*/ - OSCachedMemSet(pcWriteBuffer, 0xAB, uiBlockSize); - - pcReadBuffer = OSAllocMem(uiBlockSize); - PVR_LOG_GOTO_IF_NOMEM(pcReadBuffer, eError, ErrorFreeWriteBuffer); - - /* Fit only complete blocks in uiMappedSize, ignore leftover bytes */ - EndAddr = StartAddr + (uiBlockSize * (uiMappedSize / uiBlockSize)); - - /* Write blocks into the memory */ - for (p = StartAddr; p < EndAddr; p += uiBlockSize) - { - OSCachedMemCopy(p, pcWriteBuffer, uiBlockSize); - } - - /* Read back blocks and check */ - for (p = StartAddr; p < EndAddr; p += uiBlockSize) - { - OSCachedMemCopy(pcReadBuffer, p, uiBlockSize); - - for (j = 0; j < uiBlockSize; j++) - { - if (pcReadBuffer[j] != pcWriteBuffer[j]) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", __func__, pcReadBuffer[j], pcWriteBuffer[j])); - eError = PVRSRV_ERROR_MEMORY_TEST_FAILED; - goto ErrorMemTestFailed; - } - } - } - -ErrorMemTestFailed: - OSFreeMem(pcReadBuffer); -ErrorFreeWriteBuffer: - OSFreeMem(pcWriteBuffer); - } - - return eError; -} - -/* Memory test - writes and reads back different patterns to memory and validate the same */ -static PVRSRV_ERROR -MemTestPatterns(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32MappingTable = 0; - PMR *psPMR = NULL; - size_t uiMappedSize, uiPageSize; - IMG_HANDLE hPrivData = NULL; - void *pvKernAddr = NULL; - - uiPageSize = OSGetPageSize(); - - /* Allocate PMR with READ | WRITE | WRITE_COMBINE attributes */ - uiFlags |= PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC; - - /*Allocate a PMR from given physical heap */ - eError = PhysmemNewRamBackedPMR(NULL, - psDeviceNode, - uiPageSize * PHYSMEM_TEST_PAGES, - uiPageSize * PHYSMEM_TEST_PAGES, - 1, - 1, - &ui32MappingTable, - OSGetPageShift(), - uiFlags, - sizeof("PMR PhysMemTest"), - "PMR PhysMemTest", - OSGetCurrentClientProcessIDKM(), - &psPMR, - PDUMP_NONE, - NULL); - PVR_LOG_RETURN_IF_ERROR(eError, "PhysmemNewRamBackedPMR"); - - /* Check whether allocated PMR can be locked and obtain physical - * addresses of underlying memory pages. - */ - eError = PMRLockSysPhysAddresses(psPMR); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRLockSysPhysAddresses", ErrorUnrefPMR); - - /* Map the physical page(s) into kernel space, acquire kernel mapping - * for PMR. - */ - eError = PMRAcquireKernelMappingData(psPMR, 0, uiPageSize * PHYSMEM_TEST_PAGES, &pvKernAddr, &uiMappedSize, &hPrivData); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", ErrorUnlockPhysAddresses); - - PVR_ASSERT((uiPageSize * PHYSMEM_TEST_PAGES) == uiMappedSize); - - /* Test various patterns */ - eError = TestPatternU64(pvKernAddr, uiMappedSize); - if (eError != PVRSRV_OK) - { - goto ErrorReleaseKernelMappingData; - } - - eError = TestPatternU32(pvKernAddr, uiMappedSize); - if (eError != PVRSRV_OK) - { - goto ErrorReleaseKernelMappingData; - } - - eError = TestPatternU16(pvKernAddr, uiMappedSize); - if (eError != PVRSRV_OK) - { - goto ErrorReleaseKernelMappingData; - } - - eError = TestPatternU8(pvKernAddr, uiMappedSize); - if (eError != PVRSRV_OK) - { - goto ErrorReleaseKernelMappingData; - } - - /* Test split cachelines */ - eError = TestSplitCacheline(pvKernAddr, uiMappedSize); - -ErrorReleaseKernelMappingData: - (void) PMRReleaseKernelMappingData(psPMR, hPrivData); - -ErrorUnlockPhysAddresses: - /* Unlock and Unref the PMR to destroy it, ignore returned value */ - (void) PMRUnlockSysPhysAddresses(psPMR); -ErrorUnrefPMR: - (void) PMRUnrefPMR(psPMR); - - return eError; -} - -static PVRSRV_ERROR -PhysMemTestRun(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags, IMG_UINT32 ui32Passes) -{ - PVRSRV_ERROR eError; - IMG_UINT32 i; - - /* PMR validation test */ - eError = PMRValidationTest(psDeviceNode, uiFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: PMR validation test failed!", - __func__)); - return eError; - } - - for (i = 0; i < ui32Passes; i++) - { - /* Mem test */ - eError = MemTestPatterns(psDeviceNode, uiFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: [Pass#%u] MemTestPatterns failed!", - __func__, i)); - break; - } - } - - return eError; -} - -PVRSRV_ERROR -PhysMemTest(void *pvDevConfig, IMG_UINT32 ui32MemTestPasses) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = pvDevConfig; - PVRSRV_ERROR eError; - - /* validate memtest passes requested */ - ui32MemTestPasses = (ui32MemTestPasses > PHYSMEM_TEST_PASSES_MAX)? PHYSMEM_TEST_PASSES_MAX : ui32MemTestPasses; - - /* Do minimal initialisation before test */ - eError = PhysMemTestInit(&psDeviceNode, psDevConfig); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Test failed to initialize", __func__)); - return eError; - } - - /* GPU local mem */ - eError = PhysMemTestRun(psDeviceNode, 0, ui32MemTestPasses); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "GPU local memory test failed!")); - goto ErrorPhysMemTestDeinit; - } - - /* CPU local mem */ - eError = PhysMemTestRun(psDeviceNode, PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(CPU_LOCAL), ui32MemTestPasses); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "CPU local memory test failed!")); - goto ErrorPhysMemTestDeinit; - } - - PVR_LOG(("PhysMemTest: Passed.")); - goto PhysMemTestPassed; - -ErrorPhysMemTestDeinit: - PVR_DPF((PVR_DBG_ERROR, "PhysMemTest: Failed.")); -PhysMemTestPassed: - PhysMemTestDeInit(psDeviceNode); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/physmem_test.h b/drivers/gpu/drm/img-rogue/1.17/physmem_test.h deleted file mode 100644 index 684c729d0e513..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/physmem_test.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************/ /*! -@Title Physmem test header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for single entry point for testing of page factories -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PHYSMEM_TEST_H -#define SRVSRV_PHYSMEM_TEST_H -/* - * PhysMemTest - */ -PVRSRV_ERROR -PhysMemTest(void *pvDevConfig, IMG_UINT32 ui32MemTestPasses); - -#endif /* SRVSRV_PHYSMEM_TEST_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pmr.c b/drivers/gpu/drm/img-rogue/1.17/pmr.c deleted file mode 100644 index 76664806b27bb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pmr.c +++ /dev/null @@ -1,3863 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Physmem (PMR) abstraction -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - the "PMR" abstraction. A PMR (Physical Memory Resource) - represents some unit of physical memory which is - allocated/freed/mapped/unmapped as an indivisible unit - (higher software levels provide an abstraction above that - to deal with dividing this down into smaller manageable units). - Importantly, this module knows nothing of virtual memory, or - of MMUs etc., with one excusable exception. We have the - concept of a "page size", which really means nothing in - physical memory, but represents a "contiguity quantum" such - that the higher level modules which map this memory are able - to verify that it matches the needs of the page size for the - virtual realm into which it is being mapped. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" - -#include "pdump.h" -#include "devicemem_server_utils.h" - -#include "osfunc.h" -#include "pdump_km.h" -#include "pdump_physmem.h" -#include "pmr_impl.h" -#include "pmr_os.h" -#include "pvrsrv.h" - -#include "allocmem.h" -#include "lock.h" -#include "uniq_key_splay_tree.h" - -#if defined(SUPPORT_SECURE_EXPORT) -#include "secure_export.h" -#include "ossecure_export.h" -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "ri_server.h" -#endif - -/* ourselves */ -#include "pmr.h" - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) -#include "mmap_stats.h" -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#include "proc_stats.h" -#endif - -#include "pdump_km.h" - -/* Memalloc flags can be converted into pmr, ra or psplay flags. - * Ensure flags types are same size. - */ -static_assert(sizeof(PVRSRV_MEMALLOCFLAGS_T) == sizeof(PMR_FLAGS_T), - "Mismatch memalloc and pmr flags type size."); -static_assert(sizeof(PVRSRV_MEMALLOCFLAGS_T) == sizeof(RA_FLAGS_T), - "Mismatch memalloc and ra flags type size."); -static_assert(sizeof(PVRSRV_MEMALLOCFLAGS_T) == sizeof(IMG_PSPLAY_FLAGS_T), - "Mismatch memalloc and psplay flags type size."); - -/* A "context" for the physical memory block resource allocator. - * - * Context is probably the wrong word. - * - * There is almost certainly only one of these, ever, in the system. - * But, let's keep the notion of a context anyway, "just-in-case". - */ -static struct _PMR_CTX_ -{ - /* For debugging, and PDump, etc., let's issue a forever incrementing - * serial number to each allocation. - */ - IMG_UINT64 uiNextSerialNum; - - /* For security, we only allow a PMR to be mapped if the caller knows - * its key. We can pseudo-randomly generate keys - */ - IMG_UINT64 uiNextKey; - - /* For debugging only, I guess: Number of live PMRs */ - IMG_UINT32 uiNumLivePMRs; - - /* Lock for this structure */ - POS_LOCK hLock; - - /* In order to seed the uiNextKey, we enforce initialisation at driver - * load time. Also, we can debug check at driver unload that the PMR - * count is zero. - */ - IMG_BOOL bModuleInitialised; -} _gsSingletonPMRContext = { 1, 0, 0, NULL, IMG_FALSE }; - - -/* A PMR. One per physical allocation. May be "shared". - * - * "shared" is ambiguous. We need to be careful with terminology. - * There are two ways in which a PMR may be "shared" and we need to be sure - * that we are clear which we mean. - * - * i) multiple small allocations living together inside one PMR. - * - * ii) one single allocation filling a PMR but mapped into multiple memory - * contexts. - * - * This is more important further up the stack - at this level, all we care is - * that the PMR is being referenced multiple times. - */ -struct _PMR_ -{ - /* This object is strictly refcounted. References include: - * - mapping - * - live handles (to this object) - * - live export handles - * (thus it is normal for allocated and exported memory to have a refcount of 3) - * The object is destroyed when and only when the refcount reaches 0 - */ - - /* Physical address translation (device <> cpu) is done on a per device - * basis which means we need the physical heap info - */ - PHYS_HEAP *psPhysHeap; - - ATOMIC_T iRefCount; - - /* CPU mapping count - this is the number of times the PMR has been - * mapped to the CPU. It is used to determine when it is safe to permit - * modification of a sparse allocation's layout. - * Note that the process of mapping also increments iRefCount - * independently (as that is used to determine when a PMR may safely - * be destroyed). - */ - ATOMIC_T iCpuMapCount; - - /* Lock count - this is the number of times PMRLockSysPhysAddresses() - * has been called, less the number of PMRUnlockSysPhysAddresses() - * calls. This is arguably here for debug reasons only, as the refcount - * is already incremented as a matter of course. - * Really, this just allows us to trap protocol errors: i.e. calling - * PMRSysPhysAddr(), without a lock, or calling - * PMRUnlockSysPhysAddresses() too many or too few times. - */ - ATOMIC_T iLockCount; - - /* Lock for this structure */ - POS_LOCK hLock; - - /* Incrementing serial number to each allocation. */ - IMG_UINT64 uiSerialNum; - - /* For security, we only allow a PMR to be mapped if the caller knows - * its key. We can pseudo-randomly generate keys - */ - PMR_PASSWORD_T uiKey; - - /* Callbacks for per-flavour functions */ - const PMR_IMPL_FUNCTAB *psFuncTab; - - /* Data associated with the "subtype" */ - PMR_IMPL_PRIVDATA pvFlavourData; - - /* What kind of PMR do we have? */ - PMR_IMPL_TYPE eFlavour; - - /* And for pdump */ - const IMG_CHAR *pszPDumpDefaultMemspaceName; - - /* Allocation annotation */ - IMG_CHAR szAnnotation[DEVMEM_ANNOTATION_MAX_LEN]; - -#if defined(PDUMP) - - IMG_HANDLE hPDumpAllocHandle; - - IMG_UINT32 uiNumPDumpBlocks; -#endif - - /* Logical size of allocation. "logical", because a PMR can represent - * memory that will never physically exist. This is the amount of - * virtual space that the PMR would consume when it's mapped into a - * virtual allocation. - */ - PMR_SIZE_T uiLogicalSize; - - /* Mapping table for the allocation. - * PMR's can be sparse in which case not all the "logic" addresses in - * it are valid. We need to know which addresses are and aren't valid - * when mapping or reading the PMR. - * The mapping table translates "logical" offsets into physical offsets - * which is what we always pass to the PMR factory (so it doesn't have - * to be concerned about sparseness issues) - */ - PMR_MAPPING_TABLE *psMappingTable; - - /* Indicates whether this PMR has been allocated as sparse. - * The condition for this variable to be set at allocation time is: - * (numVirtChunks != numPhysChunks) || (numVirtChunks > 1) - */ - IMG_BOOL bSparseAlloc; - - /* Indicates whether this PMR has been unpinned. - * By default, all PMRs are pinned at creation. - */ - IMG_BOOL bIsUnpinned; - - /* - * Flag that conveys mutability of the PMR: - * - TRUE indicates the PMR is immutable (no more memory changes) - * - FALSE means the memory layout associated with the PMR is mutable - * - * A PMR is always mutable by default but is marked immutable on the - * first export for the rest of its life. - * - * Also, any PMRs that track the same memory through imports are - * marked immutable as well. - */ - IMG_BOOL bNoLayoutChange; - - /* Minimum Physical Contiguity Guarantee. Might be called "page size", - * but that would be incorrect, as page size is something meaningful - * only in virtual realm. This contiguity guarantee provides an - * inequality that can be verified/asserted/whatever to ensure that - * this PMR conforms to the page size requirement of the place the PMR - * gets mapped. (May be used to select an appropriate heap in variable - * page size systems) - * - * The absolutely necessary condition is this: - * - * device MMU page size <= actual physical contiguity. - * - * We go one step further in order to be able to provide an early - * warning / early compatibility check and say this: - * - * device MMU page size <= - * 2**(uiLog2ContiguityGuarantee) <= - * actual physical contiguity. - * - * In this way, it is possible to make the page table reservation - * in the device MMU without even knowing the granularity of the - * physical memory (i.e. useful for being able to allocate virtual - * before physical) - */ - PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee; - - /* Flags. We store a copy of the "PMR flags" (usually a subset of the - * flags given at allocation time) and return them to any caller of - * PMR_Flags(). The intention of these flags is that the ones stored - * here are used to represent permissions, such that no one is able - * to map a PMR in a mode in which they are not allowed, e.g., - * writeable for a read-only PMR, etc. - */ - PMR_FLAGS_T uiFlags; - - /* Do we really need this? - * For now we'll keep it, until we know we don't. - * NB: this is not the "memory context" in client terms - this is - * _purely_ the "PMR" context, of which there is almost certainly only - * ever one per system as a whole, but we'll keep the concept anyway, - * just-in-case. - */ - struct _PMR_CTX_ *psContext; - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - /* Stored handle to PMR RI entry */ - void *hRIHandle; -#endif -}; - -/* Do we need a struct for the export handle? - * I'll use one for now, but if nothing goes in it, we'll lose it - */ -struct _PMR_EXPORT_ -{ - struct _PMR_ *psPMR; -}; - -struct _PMR_PAGELIST_ -{ - struct _PMR_ *psReferencePMR; -}; - -void -PMRLockPMR(PMR *psPMR) -{ - OSLockAcquire(psPMR->hLock); -} - -void -PMRUnlockPMR(PMR *psPMR) -{ - OSLockRelease(psPMR->hLock); -} - -#if defined(PDUMP) -static INLINE IMG_BOOL _IsHostDevicePMR(const PMR *const psPMR) -{ - const PVRSRV_DEVICE_NODE *psDevNode = PVRSRVGetPVRSRVData()->psHostMemDeviceNode; - return psPMR->psPhysHeap == psDevNode->apsPhysHeap[PVRSRV_PHYS_HEAP_CPU_LOCAL]; -} - -static void -PDumpPMRFreePMR(PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiBlockSize, - IMG_UINT32 uiLog2Contiguity, - IMG_HANDLE hPDumpAllocationInfoHandle); - -static void -PDumpPMRMallocPMR(PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiBlockSize, - IMG_UINT32 ui32ChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *puiMappingTable, - IMG_UINT32 uiLog2Contiguity, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phPDumpAllocInfoOut, - IMG_UINT32 ui32PDumpFlags); - -static void -PDumpPMRChangeSparsePMR(PMR *psPMR, - IMG_UINT32 uiBlockSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phPDumpAllocInfoOut); -#endif /* defined PDUMP */ - -PPVRSRV_DEVICE_NODE PMRGetExportDeviceNode(PMR_EXPORT *psExportPMR) -{ - PPVRSRV_DEVICE_NODE psReturnedDeviceNode = NULL; - - PVR_ASSERT(psExportPMR != NULL); - if (psExportPMR) - { - PVR_ASSERT(psExportPMR->psPMR != NULL); - if (psExportPMR->psPMR) - { - PVR_ASSERT(OSAtomicRead(&psExportPMR->psPMR->iRefCount) > 0); - if (OSAtomicRead(&psExportPMR->psPMR->iRefCount) > 0) - { - psReturnedDeviceNode = PMR_DeviceNode(psExportPMR->psPMR); - } - } - } - - return psReturnedDeviceNode; -} - -static PVRSRV_ERROR -_PMRCreate(PMR_SIZE_T uiLogicalSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee, - PMR_FLAGS_T uiFlags, - PMR **ppsPMR) -{ - void *pvPMRLinAddr; - PMR *psPMR; - PMR_MAPPING_TABLE *psMappingTable; - struct _PMR_CTX_ *psContext; - IMG_UINT32 i, ui32Temp = 0; - IMG_UINT32 ui32Remainder; - PVRSRV_ERROR eError; - IMG_BOOL bSparse = IMG_FALSE; - - psContext = &_gsSingletonPMRContext; - - /* Do we have a sparse allocation? */ - if ( (ui32NumVirtChunks != ui32NumPhysChunks) || - (ui32NumVirtChunks > 1) ) - { - bSparse = IMG_TRUE; - } - - /* Extra checks required for sparse PMRs */ - if (uiLogicalSize != uiChunkSize) - { - /* Check the logical size and chunk information agree with each other */ - if (uiLogicalSize != (uiChunkSize * ui32NumVirtChunks)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Bad mapping size (uiLogicalSize = 0x%llx, uiChunkSize = 0x%llx, ui32NumVirtChunks = %d)", - __func__, (unsigned long long)uiLogicalSize, (unsigned long long)uiChunkSize, ui32NumVirtChunks)); - return PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE; - } - - /* Check that the chunk size is a multiple of the contiguity */ - OSDivide64(uiChunkSize, (1<< uiLog2ContiguityGuarantee), &ui32Remainder); - if (ui32Remainder) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Bad chunk size, must be a multiple of the contiguity " - "(uiChunkSize = 0x%llx, uiLog2ContiguityGuarantee = %u)", - __func__, - (unsigned long long) uiChunkSize, - uiLog2ContiguityGuarantee)); - return PVRSRV_ERROR_PMR_BAD_CHUNK_SIZE; - } - } - - pvPMRLinAddr = OSAllocMem(sizeof(*psPMR) + sizeof(*psMappingTable) + sizeof(IMG_UINT32) * ui32NumVirtChunks); - PVR_RETURN_IF_NOMEM(pvPMRLinAddr); - - psPMR = (PMR *) pvPMRLinAddr; - psMappingTable = IMG_OFFSET_ADDR(pvPMRLinAddr, sizeof(*psPMR)); - - /* Setup the mapping table */ - psMappingTable->uiChunkSize = uiChunkSize; - psMappingTable->ui32NumVirtChunks = ui32NumVirtChunks; - psMappingTable->ui32NumPhysChunks = ui32NumPhysChunks; - OSCachedMemSet(&psMappingTable->aui32Translation[0], 0xFF, sizeof(psMappingTable->aui32Translation[0])* - ui32NumVirtChunks); - for (i=0; iaui32Translation[ui32Temp] = ui32Temp; - } - else - { - OSFreeMem(psPMR); - return PVRSRV_ERROR_PMR_INVALID_MAP_INDEX_ARRAY; - } - } - - eError = OSLockCreate(&psPMR->hLock); - if (eError != PVRSRV_OK) - { - OSFreeMem(psPMR); - return eError; - } - - /* Setup the PMR */ - OSAtomicWrite(&psPMR->iRefCount, 0); - OSAtomicWrite(&psPMR->iCpuMapCount, 0); - - /* If allocation is not made on demand, it will be backed now and - * backing will not be removed until the PMR is destroyed, therefore - * we can initialise the iLockCount to 1 rather than 0. - */ - OSAtomicWrite(&psPMR->iLockCount, (PVRSRV_CHECK_ON_DEMAND(uiFlags) ? 0 : 1)); - - psPMR->psContext = psContext; - psPMR->uiLogicalSize = uiLogicalSize; - psPMR->uiLog2ContiguityGuarantee = uiLog2ContiguityGuarantee; - psPMR->uiFlags = uiFlags; - psPMR->psMappingTable = psMappingTable; - psPMR->bSparseAlloc = bSparse; - psPMR->bIsUnpinned = IMG_FALSE; - psPMR->bNoLayoutChange = IMG_FALSE; - psPMR->szAnnotation[0] = '\0'; - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - psPMR->hRIHandle = NULL; -#endif - - OSLockAcquire(psContext->hLock); - psPMR->uiKey = psContext->uiNextKey; - psPMR->uiSerialNum = psContext->uiNextSerialNum; - psContext->uiNextKey = (0x80200003 * psContext->uiNextKey) - ^ (0xf00f0081 * (uintptr_t)pvPMRLinAddr); - psContext->uiNextSerialNum++; - *ppsPMR = psPMR; - PVR_DPF((PVR_DBG_MESSAGE, "pmr.c: created PMR @0x%p", psPMR)); - /* Increment live PMR count */ - psContext->uiNumLivePMRs++; - OSLockRelease(psContext->hLock); - - return PVRSRV_OK; -} - -/* This function returns true if the PMR is in use and false otherwise. - * This function is not thread safe and hence the caller - * needs to ensure the thread safety by explicitly taking - * the lock on the PMR or through other means */ -IMG_BOOL PMRIsPMRLive(PMR *psPMR) -{ - return (OSAtomicRead(&psPMR->iRefCount) > 0); -} - -static IMG_UINT32 -_Ref(PMR *psPMR) -{ - if (OSAtomicRead(&psPMR->iRefCount) == 0) - { - PVR_DPF((PVR_DBG_ERROR, "pmr.c: Ref Count == 0 PMR: @0x%p Annot: %s", - psPMR, - psPMR->szAnnotation)); - OSWarnOn(1); - } - return OSAtomicIncrement(&psPMR->iRefCount); -} - -static IMG_UINT32 -_Unref(PMR *psPMR) -{ - if (OSAtomicRead(&psPMR->iRefCount) <= 0) - { - PVR_DPF((PVR_DBG_ERROR, "pmr.c: Unref Count <= 0 PMR: @0x%p Annot: %s RefCount: %d", - psPMR, - psPMR->szAnnotation, - (IMG_INT32) OSAtomicRead(&psPMR->iRefCount))); - OSWarnOn(1); - } - return OSAtomicDecrement(&psPMR->iRefCount); -} - -static void -_UnrefAndMaybeDestroy(PMR *psPMR) -{ - PVRSRV_ERROR eError2; - struct _PMR_CTX_ *psCtx; - IMG_INT iRefCount; - - PVR_ASSERT(psPMR != NULL); - - /* Acquire PMR factory lock if provided */ - if (psPMR->psFuncTab->pfnGetPMRFactoryLock) - { - psPMR->psFuncTab->pfnGetPMRFactoryLock(); - } - - iRefCount = _Unref(psPMR); - - if (iRefCount == 0) - { - if (psPMR->psFuncTab->pfnFinalize != NULL) - { - eError2 = psPMR->psFuncTab->pfnFinalize(psPMR->pvFlavourData); - - /* PMR unref can be called asynchronously by the kernel or other - * third party modules (eg. display) which doesn't go through the - * usual services bridge. The same PMR can be referenced simultaneously - * in a different path that results in a race condition. - * Hence depending on the race condition, a factory may refuse to destroy - * the resource associated with this PMR if a reference on it was taken - * prior to unref. In that case the PMR factory function returns the error. - * - * When such an error is encountered, the factory needs to ensure the state - * associated with PMR is undisturbed. At this point we just bail out from - * freeing the PMR itself. The PMR handle will then be freed at a later point - * when the same PMR is unreferenced. - * */ - if (PVRSRV_ERROR_PMR_STILL_REFERENCED == eError2) - { - if (psPMR->psFuncTab->pfnReleasePMRFactoryLock) - { - psPMR->psFuncTab->pfnReleasePMRFactoryLock(); - } - return; - } - PVR_ASSERT (eError2 == PVRSRV_OK); /* can we do better? */ - } -#if defined(PDUMP) - /* if allocation is done on the host node don't include it in the PDUMP */ - if (!_IsHostDevicePMR(psPMR)) - { - PDumpPMRFreePMR(psPMR, - psPMR->uiLogicalSize, - (1 << psPMR->uiLog2ContiguityGuarantee), - psPMR->uiLog2ContiguityGuarantee, - psPMR->hPDumpAllocHandle); - } -#endif - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) - /* This PMR is about to be destroyed, update its mmap stats record (if present) - * to avoid dangling pointer. Additionally, this is required because mmap stats - * are identified by PMRs and a new PMR down the line "might" get the same address - * as the one we're about to free and we'd like 2 different entries in mmaps - * stats for such cases */ - MMapStatsRemovePMR(psPMR); -#endif - -#ifdef PVRSRV_NEED_PVR_ASSERT - /* If not backed on demand, iLockCount should be 1 otherwise it should be 0 */ - PVR_ASSERT(OSAtomicRead(&psPMR->iLockCount) == (PVRSRV_CHECK_ON_DEMAND(psPMR->uiFlags) ? 0 : 1)); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - { - PVRSRV_ERROR eError; - - /* Delete RI entry */ - if (psPMR->hRIHandle) - { - eError = RIDeletePMREntryKM (psPMR->hRIHandle); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: RIDeletePMREntryKM failed: %s", - __func__, - PVRSRVGetErrorString(eError))); - /* continue destroying the PMR */ - } - } - } -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - psCtx = psPMR->psContext; - - OSLockDestroy(psPMR->hLock); - - /* Release PMR factory lock acquired if any */ - if (psPMR->psFuncTab->pfnReleasePMRFactoryLock) - { - psPMR->psFuncTab->pfnReleasePMRFactoryLock(); - } - - OSFreeMem(psPMR); - - /* Decrement live PMR count. Probably only of interest for debugging */ - PVR_ASSERT(psCtx->uiNumLivePMRs > 0); - - OSLockAcquire(psCtx->hLock); - psCtx->uiNumLivePMRs--; - OSLockRelease(psCtx->hLock); - } - else - { - /* Release PMR factory lock acquired if any */ - if (psPMR->psFuncTab->pfnReleasePMRFactoryLock) - { - psPMR->psFuncTab->pfnReleasePMRFactoryLock(); - } - } -} - -static IMG_BOOL _PMRIsSparse(const PMR *psPMR) -{ - return psPMR->bSparseAlloc; -} - -PVRSRV_ERROR -PMRCreatePMR(PHYS_HEAP *psPhysHeap, - PMR_SIZE_T uiLogicalSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee, - PMR_FLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - const PMR_IMPL_FUNCTAB *psFuncTab, - PMR_IMPL_PRIVDATA pvPrivData, - PMR_IMPL_TYPE eType, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags) -{ - PMR *psPMR = NULL; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszAnnotation != NULL, "pszAnnotation"); - - eError = _PMRCreate(uiLogicalSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - uiLog2ContiguityGuarantee, - uiFlags, - &psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - - psPMR->psPhysHeap = psPhysHeap; - psPMR->psFuncTab = psFuncTab; - psPMR->pszPDumpDefaultMemspaceName = PhysHeapPDumpMemspaceName(psPhysHeap); - psPMR->pvFlavourData = pvPrivData; - psPMR->eFlavour = eType; - OSAtomicWrite(&psPMR->iRefCount, 1); - - OSStringLCopy(psPMR->szAnnotation, pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN); - -#if defined(PDUMP) - /* if allocation was done on the host node don't include it in the PDUMP */ - if (!_IsHostDevicePMR(psPMR)) - { - PMR_FLAGS_T uiFlags = psPMR->uiFlags; - IMG_BOOL bInitialise = IMG_FALSE; - IMG_UINT32 ui32InitValue = 0; - - if (PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags)) - { - bInitialise = IMG_TRUE; - } - else if (PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags)) - { - ui32InitValue = 0xDEADBEEF; - bInitialise = IMG_TRUE; - } - - PDumpPMRMallocPMR(psPMR, - (uiChunkSize * ui32NumVirtChunks), - 1ULL<hPDumpAllocHandle, - ui32PDumpFlags); - } -#endif - - *ppsPMRPtr = psPMR; - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR PMRLockSysPhysAddressesNested(PMR *psPMR, - IMG_UINT32 ui32NestingLevel) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psPMR != NULL); - - /* Note: taking this lock is not required to protect the PMR reference - * count, because the PMR reference count is atomic. Rather, taking - * the lock here guarantees that no caller will exit this function - * without the underlying physical addresses being locked. - */ - OSLockAcquireNested(psPMR->hLock, ui32NestingLevel); - /* We also count the locks as references, so that the PMR is not freed - * while someone is using a physical address. - * "lock" here simply means incrementing the refcount. It means the - * refcount is multipurpose, but that's okay. We only have to promise - * that physical addresses are valid after this point, and remain valid - * until the corresponding PMRUnlockSysPhysAddressesOSMem() - */ - _Ref(psPMR); - - /* Also count locks separately from other types of references, to - * allow for debug assertions - */ - - /* Only call callback if lockcount transitions from 0 to 1 (or 1 to 2 if not backed on demand) */ - if (OSAtomicIncrement(&psPMR->iLockCount) == (PVRSRV_CHECK_ON_DEMAND(psPMR->uiFlags) ? 1 : 2)) - { - if (psPMR->psFuncTab->pfnLockPhysAddresses != NULL) - { - /* must always have lock and unlock in pairs! */ - PVR_ASSERT(psPMR->psFuncTab->pfnUnlockPhysAddresses != NULL); - - eError = psPMR->psFuncTab->pfnLockPhysAddresses(psPMR->pvFlavourData); - - PVR_GOTO_IF_ERROR(eError, e1); - } - } - OSLockRelease(psPMR->hLock); - - return PVRSRV_OK; - -e1: - OSAtomicDecrement(&psPMR->iLockCount); - _Unref(psPMR); - PVR_ASSERT(OSAtomicRead(&psPMR->iRefCount) != 0); - OSLockRelease(psPMR->hLock); - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRLockSysPhysAddresses(PMR *psPMR) -{ - return PMRLockSysPhysAddressesNested(psPMR, 0); -} - -PVRSRV_ERROR -PMRUnlockSysPhysAddresses(PMR *psPMR) -{ - return PMRUnlockSysPhysAddressesNested(psPMR, 2); -} - -PVRSRV_ERROR -PMRUnlockSysPhysAddressesNested(PMR *psPMR, IMG_UINT32 ui32NestingLevel) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psPMR != NULL); - - /* Acquiring the lock here, as well as during the Lock operation ensures - * the lock count hitting zero and the unlocking of the phys addresses is - * an atomic operation - */ - OSLockAcquireNested(psPMR->hLock, ui32NestingLevel); - PVR_ASSERT(OSAtomicRead(&psPMR->iLockCount) > (PVRSRV_CHECK_ON_DEMAND(psPMR->uiFlags) ? 0 : 1)); - - if (OSAtomicDecrement(&psPMR->iLockCount) == (PVRSRV_CHECK_ON_DEMAND(psPMR->uiFlags) ? 0 : 1)) - { - if (psPMR->psFuncTab->pfnUnlockPhysAddresses != NULL) - { - PVR_ASSERT(psPMR->psFuncTab->pfnLockPhysAddresses != NULL); - - eError = psPMR->psFuncTab->pfnUnlockPhysAddresses(psPMR->pvFlavourData); - /* must never fail */ - PVR_ASSERT(eError == PVRSRV_OK); - } - } - - OSLockRelease(psPMR->hLock); - - /* We also count the locks as references, so that the PMR is not - * freed while someone is using a physical address. - */ - _UnrefAndMaybeDestroy(psPMR); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRUnpinPMR(PMR *psPMR, IMG_BOOL bDevMapped) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(psPMR != NULL); - - OSLockAcquire(psPMR->hLock); - /* Stop if we still have references on the PMR */ - if ( ( bDevMapped && (OSAtomicRead(&psPMR->iRefCount) > 2)) - || (!bDevMapped && (OSAtomicRead(&psPMR->iRefCount) > 1)) ) - { - OSLockRelease(psPMR->hLock); - PVR_DPF((PVR_DBG_ERROR, - "%s: PMR is still referenced %u times. " - "That means this PMR is probably exported or used somewhere else. " - "Allowed are 2 references if it is mapped to device, otherwise 1.", - __func__, - OSAtomicRead(&psPMR->iRefCount))); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_STILL_REFERENCED, e_exit); - } - OSLockRelease(psPMR->hLock); - - if (psPMR->psFuncTab->pfnUnpinMem != NULL) - { - eError = psPMR->psFuncTab->pfnUnpinMem(psPMR->pvFlavourData); - if (eError == PVRSRV_OK) - { - psPMR->bIsUnpinned = IMG_TRUE; - } - } - -e_exit: - return eError; -} - -PVRSRV_ERROR -PMRPinPMR(PMR *psPMR) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(psPMR != NULL); - - if (psPMR->psFuncTab->pfnPinMem != NULL) - { - eError = psPMR->psFuncTab->pfnPinMem(psPMR->pvFlavourData, - psPMR->psMappingTable); - if (eError == PVRSRV_OK) - { - psPMR->bIsUnpinned = IMG_FALSE; - } - } - - return eError; -} - -PVRSRV_ERROR -PMRMakeLocalImportHandle(PMR *psPMR, - PMR **ppsPMR) -{ - PMRRefPMR(psPMR); - *ppsPMR = psPMR; - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRUnmakeLocalImportHandle(PMR *psPMR) -{ - PMRUnrefPMR(psPMR); - return PVRSRV_OK; -} - -/* - Note: - We pass back the PMR as it was passed in as a different handle type - (DEVMEM_MEM_IMPORT) and it allows us to change the import structure - type if we should need to embed any meta data in it. - */ -PVRSRV_ERROR -PMRLocalImportPMR(PMR *psPMR, - PMR **ppsPMR, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - _Ref(psPMR); - - /* Return the PMR */ - *ppsPMR = psPMR; - *puiSize = psPMR->uiLogicalSize; - *puiAlign = 1ULL << psPMR->uiLog2ContiguityGuarantee; - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRGetUID(PMR *psPMR, - IMG_UINT64 *pui64UID) -{ - PVR_ASSERT(psPMR != NULL); - - *pui64UID = psPMR->uiSerialNum; - - return PVRSRV_OK; -} - -#if defined(SUPPORT_INSECURE_EXPORT) -PVRSRV_ERROR -PMRExportPMR(PMR *psPMR, - PMR_EXPORT **ppsPMRExportPtr, - PMR_SIZE_T *puiSize, - PMR_LOG2ALIGN_T *puiLog2Contig, - PMR_PASSWORD_T *puiPassword) -{ - IMG_UINT64 uiPassword; - PMR_EXPORT *psPMRExport; - - uiPassword = psPMR->uiKey; - - psPMRExport = OSAllocMem(sizeof(*psPMRExport)); - PVR_RETURN_IF_NOMEM(psPMRExport); - - psPMRExport->psPMR = psPMR; - _Ref(psPMR); - /* The layout of a PMR can't change once exported - * to make sure the importers view of the memory is - * the same as exporter. */ - psPMR->bNoLayoutChange = IMG_TRUE; - - *ppsPMRExportPtr = psPMRExport; - *puiSize = psPMR->uiLogicalSize; - *puiLog2Contig = psPMR->uiLog2ContiguityGuarantee; - *puiPassword = uiPassword; - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PMRUnexportPMR(PMR_EXPORT *psPMRExport) -{ - PVR_ASSERT(psPMRExport != NULL); - PVR_ASSERT(psPMRExport->psPMR != NULL); - PVR_ASSERT(OSAtomicRead(&psPMRExport->psPMR->iRefCount) > 0); - - _UnrefAndMaybeDestroy(psPMRExport->psPMR); - - OSFreeMem(psPMRExport); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PMRImportPMR(PMR_EXPORT *psPMRExport, - PMR_PASSWORD_T uiPassword, - PMR_SIZE_T uiSize, - PMR_LOG2ALIGN_T uiLog2Contig, - PMR **ppsPMR) -{ - PMR *psPMR; - - PVR_ASSERT(OSAtomicRead(&psPMRExport->psPMR->iRefCount) > 0); - - psPMR = psPMRExport->psPMR; - - PVR_ASSERT((psPMR->bNoLayoutChange == IMG_TRUE)); - - if (psPMR->uiKey != uiPassword) - { - PVR_DPF((PVR_DBG_ERROR, - "PMRImport: Import failed, password specified does not match the export")); - return PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR; - } - - if (psPMR->uiLogicalSize != uiSize || psPMR->uiLog2ContiguityGuarantee != uiLog2Contig) - { - return PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES; - } - - _Ref(psPMR); - - *ppsPMR = psPMR; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRUnimportPMR(PMR *psPMR) -{ - _UnrefAndMaybeDestroy(psPMR); - - return PVRSRV_OK; -} - -#else /* if defined(SUPPORT_INSECURE_EXPORT) */ - -PVRSRV_ERROR -PMRExportPMR(PMR *psPMR, - PMR_EXPORT **ppsPMRExportPtr, - PMR_SIZE_T *puiSize, - PMR_LOG2ALIGN_T *puiLog2Contig, - PMR_PASSWORD_T *puiPassword) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(ppsPMRExportPtr); - PVR_UNREFERENCED_PARAMETER(puiSize); - PVR_UNREFERENCED_PARAMETER(puiLog2Contig); - PVR_UNREFERENCED_PARAMETER(puiPassword); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PMRUnexportPMR(PMR_EXPORT *psPMRExport) -{ - PVR_UNREFERENCED_PARAMETER(psPMRExport); - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PMRImportPMR(PMR_EXPORT *psPMRExport, - PMR_PASSWORD_T uiPassword, - PMR_SIZE_T uiSize, - PMR_LOG2ALIGN_T uiLog2Contig, - PMR **ppsPMR) -{ - PVR_UNREFERENCED_PARAMETER(psPMRExport); - PVR_UNREFERENCED_PARAMETER(uiPassword); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiLog2Contig); - PVR_UNREFERENCED_PARAMETER(ppsPMR); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRUnimportPMR(PMR *psPMR) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - return PVRSRV_OK; -} -#endif /* if defined(SUPPORT_INSECURE_EXPORT) */ - -#if defined(SUPPORT_SECURE_EXPORT) -PVRSRV_ERROR PMRSecureUnexportPMR(PMR *psPMR) -{ - _UnrefAndMaybeDestroy(psPMR); - return PVRSRV_OK; -} - -static PVRSRV_ERROR _ReleaseSecurePMR(void *psExport) -{ - return PMRSecureUnexportPMR(psExport); -} - -PVRSRV_ERROR PMRSecureExportPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - PMR *psPMR, - IMG_SECURE_TYPE *phSecure, - PMR **ppsPMR, - CONNECTION_DATA **ppsSecureConnection) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psDevNode); - PVR_UNREFERENCED_PARAMETER(ppsSecureConnection); - - /* We are acquiring reference to PMR here because OSSecureExport - * releases bridge lock and PMR lock for a moment and we don't want PMR - * to be removed by other thread in the meantime. */ - _Ref(psPMR); - - eError = OSSecureExport("secure_pmr", - _ReleaseSecurePMR, - (void *) psPMR, - phSecure); - PVR_GOTO_IF_ERROR(eError, e0); - - *ppsPMR = psPMR; - - /* Mark the PMR immutable once exported - * This allows the importers and exporter to have - * the same view of the memory */ - psPMR->bNoLayoutChange = IMG_TRUE; - - return PVRSRV_OK; -e0: - PVR_ASSERT(eError != PVRSRV_OK); - _UnrefAndMaybeDestroy(psPMR); - return eError; -} - -PVRSRV_ERROR PMRSecureImportPMR(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_SECURE_TYPE hSecure, - PMR **ppsPMR, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign) -{ - PVRSRV_ERROR eError; - PMR *psPMR; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - eError = OSSecureImport(hSecure, (void **) &psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - - PVR_LOG_RETURN_IF_FALSE(PhysHeapDeviceNode(psPMR->psPhysHeap) == psDevNode, - "PMR invalid for this device", - PVRSRV_ERROR_PMR_NOT_PERMITTED); - - _Ref(psPMR); - /* The PMR should be immutable once exported - * This allows the importers and exporter to have - * the same view of the memory */ - PVR_ASSERT(psPMR->bNoLayoutChange == IMG_TRUE); - - /* Return the PMR */ - *ppsPMR = psPMR; - *puiSize = psPMR->uiLogicalSize; - *puiAlign = 1ull << psPMR->uiLog2ContiguityGuarantee; - return PVRSRV_OK; -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR PMRSecureUnimportPMR(PMR *psPMR) -{ - _UnrefAndMaybeDestroy(psPMR); - return PVRSRV_OK; -} -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -PVRSRV_ERROR -PMRStoreRIHandle(PMR *psPMR, - void *hRIHandle) -{ - PVR_ASSERT(psPMR != NULL); - - psPMR->hRIHandle = hRIHandle; - return PVRSRV_OK; -} -#endif - -static PVRSRV_ERROR -_PMRAcquireKernelMappingData(PMR *psPMR, - size_t uiLogicalOffset, - size_t uiSize, - void **ppvKernelAddressOut, - size_t *puiLengthOut, - IMG_HANDLE *phPrivOut, - IMG_BOOL bMapSparse) -{ - PVRSRV_ERROR eError; - void *pvKernelAddress; - IMG_HANDLE hPriv; - - PVR_ASSERT(psPMR != NULL); - - if (_PMRIsSparse(psPMR) && !bMapSparse) - { - /* Mapping of sparse allocations must be signalled. */ - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - /* Acquire/Release functions must be overridden in pairs */ - if (psPMR->psFuncTab->pfnAcquireKernelMappingData == NULL) - { - PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData == NULL); - - /* If PMR implementation does not supply this pair of - * functions, it means they do not permit the PMR to be mapped - * into kernel memory at all - */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_NOT_PERMITTED, e0); - } - PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData != NULL); - - eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData, - uiLogicalOffset, - uiSize, - &pvKernelAddress, - &hPriv, - psPMR->uiFlags); - PVR_GOTO_IF_ERROR(eError, e0); - - *ppvKernelAddressOut = pvKernelAddress; - if (uiSize == 0) - { - /* Zero size means map in the whole PMR ... */ - *puiLengthOut = (size_t)psPMR->uiLogicalSize; - } - else if (uiSize > (1 << psPMR->uiLog2ContiguityGuarantee)) - { - /* ... map in the requested pages ... */ - *puiLengthOut = uiSize; - } - else - { - /* ... otherwise we just map in one page */ - *puiLengthOut = 1 << psPMR->uiLog2ContiguityGuarantee; - } - *phPrivOut = hPriv; - - return PVRSRV_OK; - -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRAcquireKernelMappingData(PMR *psPMR, - size_t uiLogicalOffset, - size_t uiSize, - void **ppvKernelAddressOut, - size_t *puiLengthOut, - IMG_HANDLE *phPrivOut) -{ - return _PMRAcquireKernelMappingData(psPMR, - uiLogicalOffset, - uiSize, - ppvKernelAddressOut, - puiLengthOut, - phPrivOut, - IMG_FALSE); -} - -PVRSRV_ERROR -PMRAcquireSparseKernelMappingData(PMR *psPMR, - size_t uiLogicalOffset, - size_t uiSize, - void **ppvKernelAddressOut, - size_t *puiLengthOut, - IMG_HANDLE *phPrivOut) -{ - return _PMRAcquireKernelMappingData(psPMR, - uiLogicalOffset, - uiSize, - ppvKernelAddressOut, - puiLengthOut, - phPrivOut, - IMG_TRUE); -} - -PVRSRV_ERROR -PMRReleaseKernelMappingData(PMR *psPMR, - IMG_HANDLE hPriv) -{ - PVR_ASSERT (psPMR->psFuncTab->pfnAcquireKernelMappingData != NULL); - PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData != NULL); - - psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData, - hPriv); - - return PVRSRV_OK; -} - -/* - _PMRLogicalOffsetToPhysicalOffset - - Translate between the "logical" offset which the upper levels - provide and the physical offset which is what the PMR - factories works on. - - As well as returning the physical offset we return the number of - bytes remaining till the next chunk and if this chunk is valid. - - For multi-page operations, upper layers communicate their - Log2PageSize else argument is redundant (set to zero). - */ - -static PVRSRV_ERROR -_PMRLogicalOffsetToPhysicalOffset(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_OFFSET_T *puiPhysicalOffset, - IMG_UINT32 *pui32BytesRemain, - IMG_BOOL *bValid) -{ - PMR_MAPPING_TABLE *psMappingTable = psPMR->psMappingTable; - IMG_DEVMEM_OFFSET_T uiPageSize = 1ULL << ui32Log2PageSize; - IMG_DEVMEM_OFFSET_T uiOffset = uiLogicalOffset; - IMG_UINT64 ui64ChunkIndex; - IMG_UINT32 ui32Remain; - IMG_UINT32 idx; - - /* Must be translating at least a page */ - PVR_ASSERT(ui32NumOfPages); - - if (psMappingTable->ui32NumPhysChunks == psMappingTable->ui32NumVirtChunks) - { - /* Fast path the common case, as logical and physical offsets are - equal we assume the ui32NumOfPages span is also valid */ - *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiOffset); - puiPhysicalOffset[0] = uiOffset; - bValid[0] = IMG_TRUE; - - if (ui32NumOfPages > 1) - { - /* initial offset may not be page aligned, round down */ - uiOffset &= ~(uiPageSize-1); - for (idx=1; idx < ui32NumOfPages; idx++) - { - uiOffset += uiPageSize; - puiPhysicalOffset[idx] = uiOffset; - bValid[idx] = IMG_TRUE; - } - } - } - else - { - for (idx=0; idx < ui32NumOfPages; idx++) - { - ui64ChunkIndex = OSDivide64r64( - uiOffset, - TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize), - &ui32Remain); - - /* In some cases ui32NumOfPages can come from the user space which - * means that the uiOffset could go out-of-bounds when the number - * of pages is invalid. */ - if (ui64ChunkIndex >= psMappingTable->ui32NumVirtChunks) - { - return PVRSRV_ERROR_BAD_MAPPING; - } - - if (psMappingTable->aui32Translation[ui64ChunkIndex] == TRANSLATION_INVALID) - { - bValid[idx] = IMG_FALSE; - } - else - { - bValid[idx] = IMG_TRUE; - } - - if (idx == 0) - { - if (ui32Remain == 0) - { - /* Start of chunk so return the chunk size */ - *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize); - } - else - { - *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize - ui32Remain); - } - - /* initial offset may not be page aligned, round down */ - uiOffset &= ~(uiPageSize-1); - } - - puiPhysicalOffset[idx] = psMappingTable->aui32Translation[ui64ChunkIndex] * psMappingTable->uiChunkSize + ui32Remain; - - uiOffset += uiPageSize; - } - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_PMR_ReadBytesPhysical(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiPhysicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - PVRSRV_ERROR eError; - - if (psPMR->psFuncTab->pfnReadBytes != NULL) - { - /* defer to callback if present */ - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - - eError = psPMR->psFuncTab->pfnReadBytes(psPMR->pvFlavourData, - uiPhysicalOffset, - pcBuffer, - uiBufSz, - puiNumBytes); - PMRUnlockSysPhysAddresses(psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - } - else if (psPMR->psFuncTab->pfnAcquireKernelMappingData) - { - /* "default" handler for reading bytes */ - - IMG_HANDLE hKernelMappingHandle; - IMG_UINT8 *pcKernelAddress; - - eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData, - (size_t) uiPhysicalOffset, - uiBufSz, - (void **)&pcKernelAddress, - &hKernelMappingHandle, - psPMR->uiFlags); - PVR_GOTO_IF_ERROR(eError, e0); - - /* Use the conservative 'DeviceMemCopy' here because we can't - * know if this PMR will be mapped cached. - */ - - OSDeviceMemCopy(&pcBuffer[0], pcKernelAddress, uiBufSz); - *puiNumBytes = uiBufSz; - - psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData, - hKernelMappingHandle); - } - else - { - OSPanic(); - PVR_LOG_GOTO_WITH_ERROR("psPMR->psFuncTab", eError, PVRSRV_ERROR_INVALID_PARAMS, e0); - } - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - *puiNumBytes = 0; - return eError; -} - -PVRSRV_ERROR -PMR_ReadBytes(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_DEVMEM_OFFSET_T uiPhysicalOffset; - size_t uiBytesCopied = 0; - - /* Check for integer overflow as uiLogicalOffset might come from the client */ - if (uiLogicalOffset + uiBufSz < uiLogicalOffset) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (uiLogicalOffset + uiBufSz > psPMR->uiLogicalSize) - { - uiBufSz = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiLogicalOffset); - } - PVR_ASSERT(uiBufSz > 0); - PVR_ASSERT(uiBufSz <= psPMR->uiLogicalSize); - - /* PMR implementations can override this. If they don't, a "default" - * handler uses kernel virtual mappings. If the kernel can't - * provide a kernel virtual mapping, this function fails. - */ - PVR_ASSERT(psPMR->psFuncTab->pfnAcquireKernelMappingData != NULL || - psPMR->psFuncTab->pfnReadBytes != NULL); - - while (uiBytesCopied != uiBufSz) - { - IMG_UINT32 ui32Remain; - size_t uiBytesToCopy; - size_t uiRead; - IMG_BOOL bValid; - - eError = _PMRLogicalOffsetToPhysicalOffset(psPMR, - 0, - 1, - uiLogicalOffset, - &uiPhysicalOffset, - &ui32Remain, - &bValid); - PVR_LOG_RETURN_IF_ERROR(eError, "_PMRLogicalOffsetToPhysicalOffset"); - - /* Copy till either then end of the chunk or end - * of the buffer - */ - uiBytesToCopy = MIN(uiBufSz - uiBytesCopied, ui32Remain); - - if (bValid) - { - /* Read the data from the PMR */ - eError = _PMR_ReadBytesPhysical(psPMR, - uiPhysicalOffset, - &pcBuffer[uiBytesCopied], - uiBytesToCopy, - &uiRead); - if ((eError != PVRSRV_OK) || (uiRead != uiBytesToCopy)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to read chunk (eError = %s, uiRead = " IMG_SIZE_FMTSPEC " uiBytesToCopy = " IMG_SIZE_FMTSPEC ")", - __func__, - PVRSRVGetErrorString(eError), - uiRead, - uiBytesToCopy)); - /* Bail out as soon as we hit an error */ - break; - } - } - else - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Invalid phys offset at logical offset (" IMG_DEVMEM_OFFSET_FMTSPEC ") logical size (" IMG_DEVMEM_OFFSET_FMTSPEC ")", - __func__, - uiLogicalOffset, - psPMR->uiLogicalSize)); - /* Fill invalid chunks with 0 */ - OSCachedMemSet(&pcBuffer[uiBytesCopied], 0, uiBytesToCopy); - uiRead = uiBytesToCopy; - eError = PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR; - } - uiLogicalOffset += uiRead; - uiBytesCopied += uiRead; - } - - *puiNumBytes = uiBytesCopied; - return eError; -} - -static PVRSRV_ERROR -_PMR_WriteBytesPhysical(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiPhysicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - PVRSRV_ERROR eError; - - if (psPMR->psFuncTab->pfnWriteBytes != NULL) - { - /* defer to callback if present */ - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - - eError = psPMR->psFuncTab->pfnWriteBytes(psPMR->pvFlavourData, - uiPhysicalOffset, - pcBuffer, - uiBufSz, - puiNumBytes); - PMRUnlockSysPhysAddresses(psPMR); - PVR_GOTO_IF_ERROR(eError, e0); - } - else if (psPMR->psFuncTab->pfnAcquireKernelMappingData) - { - /* "default" handler for reading bytes */ - - IMG_HANDLE hKernelMappingHandle; - IMG_UINT8 *pcKernelAddress; - - eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData, - (size_t) uiPhysicalOffset, - uiBufSz, - (void **)&pcKernelAddress, - &hKernelMappingHandle, - psPMR->uiFlags); - PVR_GOTO_IF_ERROR(eError, e0); - - /* Use the conservative 'DeviceMemCopy' here because we can't know - * if this PMR will be mapped cached. - */ - - OSDeviceMemCopy(pcKernelAddress, &pcBuffer[0], uiBufSz); - *puiNumBytes = uiBufSz; - - psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData, - hKernelMappingHandle); - } - else - { - /* The write callback is optional as it's only required by the - * debug tools - */ - OSPanic(); - PVR_LOG_GOTO_WITH_ERROR("psPMR->psFuncTab", eError, PVRSRV_ERROR_PMR_NOT_PERMITTED, e0); - } - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - *puiNumBytes = 0; - return eError; -} - -PVRSRV_ERROR -PMR_WriteBytes(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_DEVMEM_OFFSET_T uiPhysicalOffset; - size_t uiBytesCopied = 0; - - /* Check for integer overflow as uiLogicalOffset might come from the client */ - if (uiLogicalOffset + uiBufSz < uiLogicalOffset) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (uiLogicalOffset + uiBufSz > psPMR->uiLogicalSize) - { - uiBufSz = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiLogicalOffset); - } - PVR_ASSERT(uiBufSz > 0); - PVR_ASSERT(uiBufSz <= psPMR->uiLogicalSize); - - /* PMR implementations can override this. If they don't, a "default" - * handler uses kernel virtual mappings. If the kernel can't provide - * a kernel virtual mapping, this function fails. - */ - PVR_ASSERT(psPMR->psFuncTab->pfnAcquireKernelMappingData != NULL || - psPMR->psFuncTab->pfnWriteBytes != NULL); - - while (uiBytesCopied != uiBufSz) - { - IMG_UINT32 ui32Remain; - size_t uiBytesToCopy; - size_t uiWrite; - IMG_BOOL bValid; - - eError = _PMRLogicalOffsetToPhysicalOffset(psPMR, - 0, - 1, - uiLogicalOffset, - &uiPhysicalOffset, - &ui32Remain, - &bValid); - PVR_LOG_RETURN_IF_ERROR(eError, "_PMRLogicalOffsetToPhysicalOffset"); - - /* Copy till either then end of the chunk or end of the buffer - */ - uiBytesToCopy = MIN(uiBufSz - uiBytesCopied, ui32Remain); - - if (bValid) - { - /* Write the data to the PMR */ - eError = _PMR_WriteBytesPhysical(psPMR, - uiPhysicalOffset, - &pcBuffer[uiBytesCopied], - uiBytesToCopy, - &uiWrite); - if ((eError != PVRSRV_OK) || (uiWrite != uiBytesToCopy)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to read chunk (eError = %s, uiWrite = " IMG_SIZE_FMTSPEC " uiBytesToCopy = " IMG_SIZE_FMTSPEC ")", - __func__, - PVRSRVGetErrorString(eError), - uiWrite, - uiBytesToCopy)); - /* Bail out as soon as we hit an error */ - break; - } - } - else - { - /* Ignore writes to invalid pages */ - uiWrite = uiBytesToCopy; - } - uiLogicalOffset += uiWrite; - uiBytesCopied += uiWrite; - } - - *puiNumBytes = uiBytesCopied; - return eError; -} - -PVRSRV_ERROR -PMRMMapPMR(PMR *psPMR, PMR_MMAP_DATA pOSMMapData, PVRSRV_MEMALLOCFLAGS_T uiFlags) -{ - /* if writeable mapping is requested on non-writeable PMR then fail */ - PVR_RETURN_IF_FALSE(PVRSRV_CHECK_CPU_WRITEABLE(psPMR->uiFlags) || - !PVRSRV_CHECK_CPU_WRITEABLE(uiFlags), - PVRSRV_ERROR_PMR_NOT_PERMITTED); - - if (psPMR->psFuncTab->pfnMMap) - { - return psPMR->psFuncTab->pfnMMap(psPMR->pvFlavourData, psPMR, pOSMMapData); - } - - return OSMMapPMRGeneric(psPMR, pOSMMapData); -} - -void -PMRRefPMR(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - _Ref(psPMR); -} - -PVRSRV_ERROR -PMRUnrefPMR(PMR *psPMR) -{ - _UnrefAndMaybeDestroy(psPMR); - return PVRSRV_OK; -} - -void -PMRRefPMR2(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - _Ref(psPMR); -} - -void -PMRUnrefPMR2(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - _UnrefAndMaybeDestroy(psPMR); -} - -PVRSRV_ERROR -PMRUnrefUnlockPMR(PMR *psPMR) -{ - PMRUnlockSysPhysAddresses(psPMR); - - PMRUnrefPMR(psPMR); - - return PVRSRV_OK; -} - -#define PMR_CPUMAPCOUNT_MIN 0 -#define PMR_CPUMAPCOUNT_MAX IMG_INT32_MAX -void -PMRCpuMapCountIncr(PMR *psPMR) -{ - IMG_BOOL bSuccess; - - bSuccess = OSAtomicAddUnless(&psPMR->iCpuMapCount, 1, - PMR_CPUMAPCOUNT_MAX); - if (!bSuccess) - { - PVR_DPF((PVR_DBG_ERROR, "%s: iCpuMapCount for PMR: @0x%p (%s) has overflowed.", - __func__, - psPMR, - psPMR->szAnnotation)); - OSWarnOn(1); - } -} - -void -PMRCpuMapCountDecr(PMR *psPMR) -{ - IMG_BOOL bSuccess; - - bSuccess = OSAtomicSubtractUnless(&psPMR->iCpuMapCount, 1, - PMR_CPUMAPCOUNT_MIN); - if (!bSuccess) - { - PVR_DPF((PVR_DBG_ERROR, "%s: iCpuMapCount (now %d) for PMR: @0x%p (%s) has underflowed.", - __func__, - (IMG_INT32) OSAtomicRead(&psPMR->iCpuMapCount), - psPMR, - psPMR->szAnnotation)); - OSWarnOn(1); - } -} - -IMG_BOOL -PMR_IsCpuMapped(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return (OSAtomicRead(&psPMR->iCpuMapCount) > 0); -} - -PVRSRV_DEVICE_NODE * -PMR_DeviceNode(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return PhysHeapDeviceNode(psPMR->psPhysHeap); -} - -PMR_FLAGS_T -PMR_Flags(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return psPMR->uiFlags; -} - -IMG_BOOL -PMR_IsSparse(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return _PMRIsSparse(psPMR); -} - -IMG_BOOL -PMR_IsUnpinned(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return psPMR->bIsUnpinned; -} - -/* Function that alters the mutability property - * of the PMR - * Setting it to TRUE makes sure the PMR memory layout - * can't be changed through future calls */ -void -PMR_SetLayoutFixed(PMR *psPMR, IMG_BOOL bFlag) -{ - PVR_ASSERT(psPMR != NULL); - - psPMR->bNoLayoutChange = bFlag; -} - -IMG_BOOL PMR_IsMemLayoutFixed(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - - return psPMR->bNoLayoutChange; -} - -void -PMR_LogicalSize(const PMR *psPMR, - IMG_DEVMEM_SIZE_T *puiLogicalSize) -{ - PVR_ASSERT(psPMR != NULL); - - *puiLogicalSize = psPMR->uiLogicalSize; -} - -PVRSRV_ERROR -PMR_PhysicalSize(const PMR *psPMR, - IMG_DEVMEM_SIZE_T *puiPhysicalSize) -{ - PVR_ASSERT(psPMR != NULL); - - /* iLockCount will be > 0 for any backed PMR (backed on demand or not) */ - if ((OSAtomicRead(&psPMR->iLockCount) > 0) && !psPMR->bIsUnpinned) - { - if (psPMR->bSparseAlloc) - { - *puiPhysicalSize = psPMR->psMappingTable->uiChunkSize * psPMR->psMappingTable->ui32NumPhysChunks; - } - else - { - *puiPhysicalSize = psPMR->uiLogicalSize; - } - } - else - { - *puiPhysicalSize = 0; - } - return PVRSRV_OK; -} - -PHYS_HEAP * -PMR_PhysHeap(const PMR *psPMR) -{ - return psPMR->psPhysHeap; -} - -PVRSRV_ERROR -PMR_IsOffsetValid(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_BOOL *pbValid) -{ - IMG_DEVMEM_OFFSET_T auiPhysicalOffset[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_UINT32 aui32BytesRemain[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEVMEM_OFFSET_T *puiPhysicalOffset = auiPhysicalOffset; - IMG_UINT32 *pui32BytesRemain = aui32BytesRemain; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(psPMR != NULL); - PVR_ASSERT(psPMR->uiLogicalSize >= uiLogicalOffset); - - if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - puiPhysicalOffset = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEVMEM_OFFSET_T)); - PVR_GOTO_IF_NOMEM(puiPhysicalOffset, eError, e0); - - pui32BytesRemain = OSAllocMem(ui32NumOfPages * sizeof(IMG_UINT32)); - PVR_GOTO_IF_NOMEM(pui32BytesRemain, eError, e0); - } - - eError = _PMRLogicalOffsetToPhysicalOffset(psPMR, - ui32Log2PageSize, - ui32NumOfPages, - uiLogicalOffset, - puiPhysicalOffset, - pui32BytesRemain, - pbValid); - PVR_LOG_IF_ERROR(eError, "_PMRLogicalOffsetToPhysicalOffset"); - -e0: - if (puiPhysicalOffset != auiPhysicalOffset && puiPhysicalOffset != NULL) - { - OSFreeMem(puiPhysicalOffset); - } - - if (pui32BytesRemain != aui32BytesRemain && pui32BytesRemain != NULL) - { - OSFreeMem(pui32BytesRemain); - } - - return eError; -} - -PMR_MAPPING_TABLE * -PMR_GetMappingTable(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return psPMR->psMappingTable; - -} - -IMG_UINT32 -PMR_GetLog2Contiguity(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return psPMR->uiLog2ContiguityGuarantee; -} - -IMG_UINT32 PMRGetMaxChunkCount(PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return (PMR_MAX_SUPPORTED_SIZE >> psPMR->uiLog2ContiguityGuarantee); -} - -const IMG_CHAR * -PMR_GetAnnotation(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return psPMR->szAnnotation; -} - -PMR_IMPL_TYPE -PMR_GetType(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return psPMR->eFlavour; -} - -IMG_INT32 -PMR_GetRefCount(const PMR *psPMR) -{ - PVR_ASSERT(psPMR != NULL); - return OSAtomicRead(&psPMR->iRefCount); -} - -/* must have called PMRLockSysPhysAddresses() before calling this! */ -PVRSRV_ERROR -PMR_DevPhysAddr(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEV_PHYADDR *psDevAddrPtr, - IMG_BOOL *pbValid) -{ - IMG_UINT32 ui32Remain; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_DEVMEM_OFFSET_T auiPhysicalOffset[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEVMEM_OFFSET_T *puiPhysicalOffset = auiPhysicalOffset; - - PVR_ASSERT(psPMR != NULL); - PVR_ASSERT(ui32NumOfPages > 0); - PVR_ASSERT(psPMR->psFuncTab->pfnDevPhysAddr != NULL); - -#ifdef PVRSRV_NEED_PVR_ASSERT - PVR_ASSERT(OSAtomicRead(&psPMR->iLockCount) > (PVRSRV_CHECK_ON_DEMAND(psPMR->uiFlags) ? 0 : 1)); -#endif - - if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - puiPhysicalOffset = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEVMEM_OFFSET_T)); - PVR_RETURN_IF_NOMEM(puiPhysicalOffset); - } - - eError = _PMRLogicalOffsetToPhysicalOffset(psPMR, - ui32Log2PageSize, - ui32NumOfPages, - uiLogicalOffset, - puiPhysicalOffset, - &ui32Remain, - pbValid); - PVR_LOG_GOTO_IF_ERROR(eError, "_PMRLogicalOffsetToPhysicalOffset", FreeOffsetArray); - if (*pbValid || _PMRIsSparse(psPMR)) - { - /* Sparse PMR may not always have the first page valid */ - eError = psPMR->psFuncTab->pfnDevPhysAddr(psPMR->pvFlavourData, - ui32Log2PageSize, - ui32NumOfPages, - puiPhysicalOffset, - pbValid, - psDevAddrPtr); - PVR_GOTO_IF_ERROR(eError, FreeOffsetArray); - -#if defined(PVR_PMR_TRANSLATE_UMA_ADDRESSES) - /* Currently excluded from the default build because of performance - * concerns. - * We do not need this part in all systems because the GPU has the same - * address view of system RAM as the CPU. - * Alternatively this could be implemented as part of the PMR-factories - * directly */ - if (PhysHeapGetType(psPMR->psPhysHeap) == PHYS_HEAP_TYPE_UMA || - PhysHeapGetType(psPMR->psPhysHeap) == PHYS_HEAP_TYPE_DMA) - { - IMG_UINT32 i; - IMG_DEV_PHYADDR sDevPAddrCorrected; - - /* Copy the translated addresses to the correct array */ - for (i = 0; i < ui32NumOfPages; i++) - { - PhysHeapCpuPAddrToDevPAddr(psPMR->psPhysHeap, - 1, - &sDevPAddrCorrected, - (IMG_CPU_PHYADDR *) &psDevAddrPtr[i]); - psDevAddrPtr[i].uiAddr = sDevPAddrCorrected.uiAddr; - } - } -#endif - } - -FreeOffsetArray: - if (puiPhysicalOffset != auiPhysicalOffset) - { - OSFreeMem(puiPhysicalOffset); - } - - return eError; -} - -/* must have called PMRLockSysPhysAddresses() before calling this! */ -PVRSRV_ERROR -PMR_CpuPhysAddr(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_CPU_PHYADDR *psCpuAddrPtr, - IMG_BOOL *pbValid) -{ - IMG_UINT32 idx; - PVRSRV_ERROR eError; - IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEV_PHYADDR *psDevPAddr = asDevPAddr; - - if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - psDevPAddr = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEV_PHYADDR)); - PVR_GOTO_IF_NOMEM(psDevPAddr, eError, e0); - } - - eError = PMR_DevPhysAddr(psPMR, ui32Log2PageSize, ui32NumOfPages, - uiLogicalOffset, psDevPAddr, pbValid); - PVR_GOTO_IF_ERROR(eError, e1); - - if (_PMRIsSparse(psPMR)) - { - /* Loop over each page. - * If Dev addr valid, populate the CPU addr from the Dev addr - */ - for (idx = 0; idx < ui32NumOfPages; idx++) - { - if (pbValid[idx]) - { - PhysHeapDevPAddrToCpuPAddr(psPMR->psPhysHeap, 1, &psCpuAddrPtr[idx], &psDevPAddr[idx]); - } - } - } - else - { - /* In this case all addrs will be valid, so we can block translate */ - PhysHeapDevPAddrToCpuPAddr(psPMR->psPhysHeap, ui32NumOfPages, psCpuAddrPtr, psDevPAddr); - } - - if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - OSFreeMem(psDevPAddr); - } - - return PVRSRV_OK; -e1: - if (psDevPAddr != asDevPAddr) - { - OSFreeMem(psDevPAddr); - } -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR PMR_ChangeSparseMem(PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiSparseFlags) -{ - PVRSRV_ERROR eError; - - PMRLockPMR(psPMR); - - if (!PMR_IsSparse(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid non-sparse PMR", __func__)); - PMRUnlockPMR(psPMR); - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - if (PMR_IsMemLayoutFixed(psPMR) || PMR_IsCpuMapped(psPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This PMR layout cannot be changed - psPMR->bNoLayoutChange=%c, _PMR_IsMapped()=%c", - __func__, - psPMR->bNoLayoutChange ? 'Y' : 'n', - PMR_IsCpuMapped(psPMR) ? 'Y' : 'n')); - PMRUnlockPMR(psPMR); - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - if (NULL == psPMR->psFuncTab->pfnChangeSparseMem) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This type of sparse PMR cannot be changed.", - __func__)); - PMRUnlockPMR(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - eError = psPMR->psFuncTab->pfnChangeSparseMem(psPMR->pvFlavourData, - psPMR, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices, - uiSparseFlags); - if (eError != PVRSRV_OK) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - if (eError == PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES) - { - PVRSRVStatsUpdateOOMStats(PVRSRV_PROCESS_STAT_TYPE_OOM_PHYSMEM_COUNT, - OSGetCurrentClientProcessIDKM()); - } -#endif - goto e0; - } - -#if defined(PDUMP) - { - IMG_BOOL bInitialise = IMG_FALSE; - IMG_UINT32 ui32InitValue = 0; - - if (PVRSRV_CHECK_ZERO_ON_ALLOC(PMR_Flags(psPMR))) - { - bInitialise = IMG_TRUE; - } - else if (PVRSRV_CHECK_POISON_ON_ALLOC(PMR_Flags(psPMR))) - { - ui32InitValue = 0xDEADBEEF; - bInitialise = IMG_TRUE; - } - - PDumpPMRChangeSparsePMR(psPMR, - 1 << psPMR->uiLog2ContiguityGuarantee, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices, - bInitialise, - ui32InitValue, - &psPMR->hPDumpAllocHandle); - } - -#endif - -e0: - PMRUnlockPMR(psPMR); - return eError; -} - - -PVRSRV_ERROR PMR_ChangeSparseMemCPUMap(PMR *psPMR, - IMG_UINT64 sCpuVAddrBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices) -{ - PVRSRV_ERROR eError; - - PMRLockPMR(psPMR); - if ((NULL == psPMR->psFuncTab) || - (NULL == psPMR->psFuncTab->pfnChangeSparseMemCPUMap)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This type of sparse PMR cannot be changed.", - __func__)); - PMRUnlockPMR(psPMR); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - if (IMG_TRUE == psPMR->bNoLayoutChange) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: This PMR layout cannot be changed", - __func__)); - PMRUnlockPMR(psPMR); - return PVRSRV_ERROR_PMR_NOT_PERMITTED; - } - - eError = psPMR->psFuncTab->pfnChangeSparseMemCPUMap(psPMR->pvFlavourData, - psPMR, - sCpuVAddrBase, - ui32AllocPageCount, - pai32AllocIndices, - ui32FreePageCount, - pai32FreeIndices); - - PMRUnlockPMR(psPMR); - return eError; -} - - -#if defined(PDUMP) - -static PVRSRV_ERROR -_PMR_PDumpSymbolicAddrPhysical(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiPhysicalOffset, - IMG_UINT32 ui32MemspaceNameLen, - IMG_CHAR *pszMemspaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T *puiNewOffset, - IMG_DEVMEM_OFFSET_T *puiNextSymName) -{ - PVRSRV_DEVICE_NODE *psDevNode = PhysHeapDeviceNode(psPMR->psPhysHeap); - PVRSRV_ERROR eError = PVRSRV_OK; - -#if defined(SUPPORT_SECURITY_VALIDATION) - if (PVRSRV_CHECK_PHYS_HEAP(FW_CODE, psPMR->uiFlags) || - PVRSRV_CHECK_PHYS_HEAP(FW_PRIV_DATA, psPMR->uiFlags) || - PVRSRV_CHECK_PHYS_HEAP(GPU_SECURE, psPMR->uiFlags)) - { - OSSNPrintf(pszMemspaceName, ui32MemspaceNameLen, PMR_MEMSPACE_FMTSPEC, - psPMR->pszPDumpDefaultMemspaceName); - } - else -#endif - if (DevmemCPUCacheCoherency(psDevNode, psPMR->uiFlags) || - DevmemDeviceCacheCoherency(psDevNode, psPMR->uiFlags)) - { - OSSNPrintf(pszMemspaceName, - ui32MemspaceNameLen, - PMR_MEMSPACE_CACHE_COHERENT_FMTSPEC, - psPMR->pszPDumpDefaultMemspaceName); - } - else - { - OSSNPrintf(pszMemspaceName, ui32MemspaceNameLen, PMR_MEMSPACE_FMTSPEC, - psPMR->pszPDumpDefaultMemspaceName); - } - - OSSNPrintf(pszSymbolicAddr, - ui32SymbolicAddrLen, - PMR_SYMBOLICADDR_FMTSPEC, - PMR_DEFAULT_PREFIX, - psPMR->uiSerialNum, - uiPhysicalOffset >> PMR_GetLog2Contiguity(psPMR), - psPMR->szAnnotation); - - if (pszSymbolicAddr) - { - PDumpMakeStringValid(pszSymbolicAddr, OSStringLength(pszSymbolicAddr)); - } - - - *puiNewOffset = uiPhysicalOffset & ((1 << PMR_GetLog2Contiguity(psPMR))-1); - *puiNextSymName = (IMG_DEVMEM_OFFSET_T) (((uiPhysicalOffset >> PMR_GetLog2Contiguity(psPMR))+1) - << PMR_GetLog2Contiguity(psPMR)); - - return eError; -} - - -PVRSRV_ERROR -PMR_PDumpSymbolicAddr(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32MemspaceNameLen, - IMG_CHAR *pszMemspaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T *puiNewOffset, - IMG_DEVMEM_OFFSET_T *puiNextSymName -) -{ - IMG_DEVMEM_OFFSET_T uiPhysicalOffset; - IMG_UINT32 ui32Remain; - IMG_BOOL bValid; - PVRSRV_ERROR eError; - - PVR_ASSERT(uiLogicalOffset < psPMR->uiLogicalSize); - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - eError = _PMRLogicalOffsetToPhysicalOffset(psPMR, - 0, - 1, - uiLogicalOffset, - &uiPhysicalOffset, - &ui32Remain, - &bValid); - PVR_LOG_RETURN_IF_ERROR(eError, "_PMRLogicalOffsetToPhysicalOffset"); - - if (!bValid) - { - /* For sparse allocations, for a given logical address, there - * may not be a physical memory backing, the virtual range can - * still be valid. - */ - uiPhysicalOffset = uiLogicalOffset; - } - - return _PMR_PDumpSymbolicAddrPhysical(psPMR, - uiPhysicalOffset, - ui32MemspaceNameLen, - pszMemspaceName, - ui32SymbolicAddrLen, - pszSymbolicAddr, - puiNewOffset, - puiNextSymName); -} - -/*! - * @brief Writes a WRW command to the script2 buffer, representing a - * dword write to a physical allocation. Size is always - * sizeof(IMG_UINT32). - * @param psPMR - PMR object representing allocation - * @param uiLogicalOffset - offset - * @param ui32Value - value to write - * @param uiPDumpFlags - pdump flags - * @return PVRSRV_ERROR - */ -PVRSRV_ERROR -PMRPDumpLoadMemValue32(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 uiPMRPageSize = 1 << psPMR->uiLog2ContiguityGuarantee; - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - PVR_ASSERT(uiLogicalOffset + sizeof(ui32Value) <= psPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiLogicalOffset & (uiPMRPageSize-1)) + sizeof(ui32Value)) - <= uiPMRPageSize)); - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Get the symbolic address of the PMR */ - eError = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Write the WRW script command */ - eError = PDumpPMRWRW32(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - ui32Value, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - return PVRSRV_OK; -} - -/*! - * @brief Writes a RDW followed by a WRW command to the pdump script to perform - * an effective copy from memory to memory. Memory copied is of size - * sizeof(IMG_UINT32) - * - * @param psDstPMR - PMR object representing allocation of destination - * @param uiDstLogicalOffset - destination offset - * @param psSrcPMR - PMR object representing allocation of source - * @param uiSrcLogicalOffset - source offset - * @param pszTmpVar - pdump temporary variable used during the copy - * @param uiPDumpFlags - pdump flags - * @return PVRSRV_ERROR - */ -PVRSRV_ERROR -PMRPDumpCopyMem32(PMR *psDstPMR, - IMG_DEVMEM_OFFSET_T uiDstLogicalOffset, - PMR *psSrcPMR, - IMG_DEVMEM_OFFSET_T uiSrcLogicalOffset, - const IMG_CHAR *pszTmpVar, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - const IMG_UINT32 uiDstPMRPageSize = 1 << psDstPMR->uiLog2ContiguityGuarantee; - const IMG_UINT32 uiSrcPMRPageSize = 1 << psSrcPMR->uiLog2ContiguityGuarantee; - - PVR_ASSERT(uiSrcLogicalOffset + sizeof(IMG_UINT32) <= psSrcPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiSrcLogicalOffset & (uiSrcPMRPageSize-1)) + sizeof(IMG_UINT32)) - <= uiSrcPMRPageSize)); - - PVR_ASSERT(uiDstLogicalOffset + sizeof(IMG_UINT32) <= psDstPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiDstLogicalOffset & (uiDstPMRPageSize-1)) + sizeof(IMG_UINT32)) - <= uiDstPMRPageSize)); - - eError = PMRLockSysPhysAddresses(psSrcPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Get the symbolic address of the source PMR */ - eError = PMR_PDumpSymbolicAddr(psSrcPMR, - uiSrcLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Issue PDump read command */ - eError = PDumpPMRRDW32MemToInternalVar(PMR_DeviceNode(psSrcPMR), - pszTmpVar, - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PMRUnlockSysPhysAddresses(psSrcPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - - - eError = PMRLockSysPhysAddresses(psDstPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - - /* Get the symbolic address of the destination PMR */ - eError = PMR_PDumpSymbolicAddr(psDstPMR, - uiDstLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - - /* Write the WRW script command */ - eError = PDumpPMRWRW32InternalVarToMem(PMR_DeviceNode(psDstPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - pszTmpVar, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - - eError = PMRUnlockSysPhysAddresses(psDstPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - return PVRSRV_OK; -} - -/*! - * @brief Writes a WRW64 command to the script2 buffer, representing a - * dword write to a physical allocation. Size is always - * sizeof(IMG_UINT64). - * @param psPMR - PMR object representing allocation - * @param uiLogicalOffset - offset - * @param ui64Value - value to write - * @param uiPDumpFlags - pdump flags - * @return PVRSRV_ERROR - */ -PVRSRV_ERROR -PMRPDumpLoadMemValue64(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 uiPMRPageSize = 1 << psPMR->uiLog2ContiguityGuarantee; - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - PVR_ASSERT(uiLogicalOffset + sizeof(ui64Value) <= psPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiLogicalOffset & (uiPMRPageSize-1)) + sizeof(ui64Value)) - <= uiPMRPageSize)); - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Get the symbolic address of the PMR */ - eError = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Write the WRW script command */ - eError = PDumpPMRWRW64(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - ui64Value, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - return PVRSRV_OK; -} - -/*! - * @brief Writes a RDW64 followed by a WRW64 command to the pdump script to - * perform an effective copy from memory to memory. Memory copied is of - * size sizeof(IMG_UINT32) - * - * @param psDstPMR - PMR object representing allocation of destination - * @param uiDstLogicalOffset - destination offset - * @param psSrcPMR - PMR object representing allocation of source - * @param uiSrcLogicalOffset - source offset - * @param pszTmpVar - pdump temporary variable used during the copy - * @param uiPDumpFlags - pdump flags - * @return PVRSRV_ERROR - */ -PVRSRV_ERROR -PMRPDumpCopyMem64(PMR *psDstPMR, - IMG_DEVMEM_OFFSET_T uiDstLogicalOffset, - PMR *psSrcPMR, - IMG_DEVMEM_OFFSET_T uiSrcLogicalOffset, - const IMG_CHAR *pszTmpVar, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - const IMG_UINT32 uiDstPMRPageSize = 1 << psDstPMR->uiLog2ContiguityGuarantee; - const IMG_UINT32 uiSrcPMRPageSize = 1 << psSrcPMR->uiLog2ContiguityGuarantee; - - PVR_ASSERT(uiSrcLogicalOffset + sizeof(IMG_UINT32) <= psSrcPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiSrcLogicalOffset & (uiSrcPMRPageSize-1)) + sizeof(IMG_UINT32)) - <= uiSrcPMRPageSize)); - - PVR_ASSERT(uiDstLogicalOffset + sizeof(IMG_UINT32) <= psDstPMR->uiLogicalSize); - /* Especially make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiDstLogicalOffset & (uiDstPMRPageSize-1)) + sizeof(IMG_UINT32)) - <= uiDstPMRPageSize)); - - eError = PMRLockSysPhysAddresses(psSrcPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Get the symbolic address of the source PMR */ - eError = PMR_PDumpSymbolicAddr(psSrcPMR, - uiSrcLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Issue PDump read command */ - eError = PDumpPMRRDW64MemToInternalVar(PMR_DeviceNode(psSrcPMR), - pszTmpVar, - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PMRUnlockSysPhysAddresses(psSrcPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - - - eError = PMRLockSysPhysAddresses(psDstPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - - /* Get the symbolic address of the destination PMR */ - eError = PMR_PDumpSymbolicAddr(psDstPMR, - uiDstLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpSymbolicOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - - /* Write the WRW script command */ - eError = PDumpPMRWRW64InternalVarToMem(PMR_DeviceNode(psDstPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpSymbolicOffset, - pszTmpVar, - uiPDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - - - eError = PMRUnlockSysPhysAddresses(psDstPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - return PVRSRV_OK; -} - -/*! - * @brief PDumps the contents of the given allocation. - * If bZero is IMG_TRUE then the zero page in the parameter stream is used - * as the source of data, rather than the allocation's actual backing. - * @param psPMR - PMR object representing allocation - * @param uiLogicalOffset - Offset to write at - * @param uiSize - Number of bytes to write - * @param uiPDumpFlags - PDump flags - * @param bZero - Use the PDump zero page as the source - * @return PVRSRV_ERROR - */ -PVRSRV_ERROR -PMRPDumpLoadMem(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags, - IMG_BOOL bZero) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiOutOffset; - IMG_DEVMEM_OFFSET_T uiCurrentOffset = uiLogicalOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName = 0; - const IMG_CHAR *pszParamStreamFileName; - PDUMP_FILEOFFSET_T uiParamStreamFileOffset; - - /* required when !bZero */ -#define PMR_MAX_PDUMP_BUFSZ (1<<21) - IMG_CHAR aszParamStreamFilename[PDUMP_PARAM_MAX_FILE_NAME]; - IMG_UINT8 *pcBuffer = NULL; - size_t uiBufSz; - IMG_BOOL bValid; - IMG_DEVMEM_SIZE_T uiSizeRemain = uiSize; - PVRSRV_DEVICE_NODE *psDevNode = PMR_DeviceNode(psPMR); - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(psDevNode)) - { - return PVRSRV_OK; - } - - PVR_ASSERT(uiLogicalOffset + uiSize <= psPMR->uiLogicalSize); - - /* Check if pdump client is connected */ - if (!PDumpCheckFlagsWrite(psDevNode, - PDUMP_FLAGS_CONTINUOUS)) - { - /* Dumping of memory in Pdump buffer will be rejected for no client connected case. - * So return early and save reading of data from PMR. */ - return PVRSRV_OK; - } - - /* Get the correct PDump stream file name */ - if (bZero) - { - PDumpCommentWithFlags(psDevNode, - uiPDumpFlags, - "Zeroing allocation (" IMG_DEVMEM_SIZE_FMTSPEC " bytes)", - uiSize); - - /* get the zero page information. it is constant for this function */ - PDumpGetParameterZeroPageInfo(&uiParamStreamFileOffset, - &uiBufSz, - &pszParamStreamFileName); - } - else - { - - uiBufSz = 1 << PMR_GetLog2Contiguity(psPMR); - PVR_ASSERT((1 << PMR_GetLog2Contiguity(psPMR)) <= PMR_MAX_PDUMP_BUFSZ); - - pcBuffer = OSAllocMem(uiBufSz); - - PVR_LOG_RETURN_IF_NOMEM(pcBuffer, "OSAllocMem"); - - eError = PMRLockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - pszParamStreamFileName = aszParamStreamFilename; - } - - /* Loop over all touched symbolic addresses of the PMR and - * emit LDBs to load the contents. */ - while (uiCurrentOffset < (uiLogicalOffset + uiSize)) - { - /* Get the correct symbolic name for the current offset */ - eError = PMR_PDumpSymbolicAddr(psPMR, - uiCurrentOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiOutOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - PVR_ASSERT((uiNextSymName - uiCurrentOffset) <= uiBufSz); - - PMR_IsOffsetValid(psPMR, - 0, - 1, - uiCurrentOffset, - &bValid); - - /* Either just LDB the zeros or read from the PMR and store that - * in the pdump stream */ - if (bValid) - { - size_t uiNumBytes; - - if (bZero) - { - uiNumBytes = MIN(uiSizeRemain, uiNextSymName - uiCurrentOffset); - } - else - { - IMG_DEVMEM_OFFSET_T uiReadOffset; - uiReadOffset = ((uiNextSymName > (uiLogicalOffset + uiSize)) ? - uiLogicalOffset + uiSize - uiCurrentOffset : - uiNextSymName - uiCurrentOffset); - - eError = PMR_ReadBytes(psPMR, - uiCurrentOffset, - pcBuffer, - uiReadOffset, - &uiNumBytes); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PDumpWriteParameterBlob(psDevNode, - pcBuffer, - uiNumBytes, - uiPDumpFlags, - &aszParamStreamFilename[0], - sizeof(aszParamStreamFilename), - &uiParamStreamFileOffset); - if (eError == PVRSRV_ERROR_PDUMP_NOT_ALLOWED) - { - /* Write to parameter file prevented under the flags and - * current state of the driver so skip further writes. - */ - eError = PVRSRV_OK; - } - else if (eError != PVRSRV_OK) - { - PDUMP_ERROR(psDevNode, - eError, "Failed to write PMR memory to parameter file"); - } - } - - /* Emit the LDB command to the current symbolic address */ - eError = PDumpPMRLDB(psDevNode, - aszMemspaceName, - aszSymbolicName, - uiOutOffset, - uiNumBytes, - pszParamStreamFileName, - uiParamStreamFileOffset, - uiPDumpFlags); - uiSizeRemain = uiSizeRemain - uiNumBytes; - } - uiCurrentOffset = uiNextSymName; - } - - if (!bZero) - { - eError = PMRUnlockSysPhysAddresses(psPMR); - PVR_ASSERT(eError == PVRSRV_OK); - - OSFreeMem(pcBuffer); - } - - return PVRSRV_OK; -} - - - -PVRSRV_ERROR -PMRPDumpSaveToFile(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiOutOffset; - IMG_DEVMEM_OFFSET_T uiCurrentOffset = uiLogicalOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName = 0; - IMG_UINT32 uiCurrentFileOffset = uiFileOffset; - - PVR_UNREFERENCED_PARAMETER(uiArraySize); - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - PVR_ASSERT(uiLogicalOffset + uiSize <= psPMR->uiLogicalSize); - - while (uiCurrentOffset < (uiLogicalOffset + uiSize)) - { - IMG_DEVMEM_OFFSET_T uiReadOffset; - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiCurrentOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiOutOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - PVR_ASSERT(uiNextSymName <= psPMR->uiLogicalSize); - - uiReadOffset = ((uiNextSymName > (uiLogicalOffset + uiSize)) ? - uiLogicalOffset + uiSize - uiCurrentOffset : - uiNextSymName - uiCurrentOffset); - - eError = PDumpPMRSAB(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiOutOffset, - uiReadOffset, - pszFilename, - uiCurrentFileOffset); - PVR_ASSERT(eError == PVRSRV_OK); - - uiCurrentFileOffset += uiNextSymName - uiCurrentOffset; - uiCurrentOffset = uiNextSymName; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRPDumpPol32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 uiPMRPageSize = 1 << psPMR->uiLog2ContiguityGuarantee; - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - /* Make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiLogicalOffset & (uiPMRPageSize-1)) + sizeof(ui32Value)) - <= uiPMRPageSize)); - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpOffset, - &uiNextSymName); - PVR_GOTO_IF_ERROR(eError, e0); - -#define _MEMPOLL_DELAY (1000) -#define _MEMPOLL_COUNT (2000000000 / _MEMPOLL_DELAY) - - eError = PDumpPMRPOL(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpOffset, - ui32Value, - ui32Mask, - eOperator, - _MEMPOLL_COUNT, - _MEMPOLL_DELAY, - uiPDumpFlags); - PVR_GOTO_IF_ERROR(eError, e0); - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRPDumpCheck32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 uiPMRPageSize = 1 << psPMR->uiLog2ContiguityGuarantee; - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - /* Make sure to not cross a block boundary */ - PVR_ASSERT(( ((uiLogicalOffset & (uiPMRPageSize-1)) + sizeof(ui32Value)) - < uiPMRPageSize)); - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiLogicalOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpOffset, - &uiNextSymName); - if (eError != PVRSRV_OK) - { - goto e0; - } - - eError = PDumpPMRPOL(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpOffset, - ui32Value, - ui32Mask, - eOperator, - 1, - 1, - uiPDumpFlags); - if (eError != PVRSRV_OK) - { - goto e0; - } - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRPDumpCBP(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVRSRV_ERROR eError; - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPDumpOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - - /* Confirm that the device node's ui32InternalID matches the bound - * PDump device stored* in PVRSRV_DATA. - */ - if (!PDumpIsDevicePermitted(PMR_DeviceNode(psPMR))) - { - return PVRSRV_OK; - } - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiReadOffset, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiPDumpOffset, - &uiNextSymName); - PVR_GOTO_IF_ERROR(eError, e0); - - eError = PDumpPMRCBP(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiPDumpOffset, - uiWriteOffset, - uiPacketSize, - uiBufferSize); - PVR_GOTO_IF_ERROR(eError, e0); - - return PVRSRV_OK; - - /* Error exit paths follow */ -e0: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void -PDumpPMRChangeSparsePMR(PMR *psPMR, - IMG_UINT32 uiBlockSize, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phPDumpAllocInfoOut) -{ - PVRSRV_ERROR eError; - IMG_HANDLE *phPDumpAllocInfo = (IMG_HANDLE*) psPMR->hPDumpAllocHandle; - - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 i, uiIndex; - PVRSRV_DEVICE_NODE *psDevNode = PMR_DeviceNode(psPMR); - - /* Remove pages from the PMR */ - for (i = 0; i < ui32FreePageCount; i++) - { - uiIndex = pai32FreeIndices[i]; - - eError = PDumpFree(psDevNode, - phPDumpAllocInfo[uiIndex]); - PVR_ASSERT(eError == PVRSRV_OK); - phPDumpAllocInfo[uiIndex] = NULL; - } - - /* Add new pages to the PMR */ - for (i = 0; i < ui32AllocPageCount; i++) - { - uiIndex = pai32AllocIndices[i]; - - PVR_ASSERT(phPDumpAllocInfo[uiIndex] == NULL); - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiIndex * uiBlockSize, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PDumpMalloc(psDevNode, - aszMemspaceName, - aszSymbolicName, - uiBlockSize, - uiBlockSize, - bInitialise, - ui32InitValue, - &phPDumpAllocInfo[uiIndex], - PDUMP_NONE); - PVR_ASSERT(eError == PVRSRV_OK); - } - - /* (IMG_HANDLE) <- (IMG_HANDLE*) */ - *phPDumpAllocInfoOut = (IMG_HANDLE) phPDumpAllocInfo; -} - -static void -PDumpPMRFreePMR(PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiBlockSize, - IMG_UINT32 uiLog2Contiguity, - IMG_HANDLE hPDumpAllocationInfoHandle) -{ - PVRSRV_ERROR eError; - IMG_UINT32 i; - - /* (IMG_HANDLE*) <- (IMG_HANDLE) */ - IMG_HANDLE *ahPDumpAllocHandleArray = (IMG_HANDLE*) hPDumpAllocationInfoHandle; - - for (i = 0; i < psPMR->uiNumPDumpBlocks; i++) - { - if (ahPDumpAllocHandleArray[i] != NULL) - { - eError = PDumpFree(PMR_DeviceNode(psPMR), - ahPDumpAllocHandleArray[i]); - PVR_ASSERT(eError == PVRSRV_OK); - ahPDumpAllocHandleArray[i] = NULL; - } - } - - OSFreeMem(ahPDumpAllocHandleArray); -} - -static void -PDumpPMRMallocPMR(PMR *psPMR, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiBlockSize, - IMG_UINT32 ui32ChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *puiMappingTable, - IMG_UINT32 uiLog2Contiguity, - IMG_BOOL bInitialise, - IMG_UINT32 ui32InitValue, - IMG_HANDLE *phPDumpAllocInfoOut, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_HANDLE *phPDumpAllocInfo; - - IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; - IMG_UINT32 uiNumPhysBlocks; - IMG_UINT32 uiNumVirtBlocks; - IMG_UINT32 i, uiIndex; - - if (PMR_IsSparse(psPMR)) - { - uiNumPhysBlocks = (ui32ChunkSize * ui32NumPhysChunks) >> uiLog2Contiguity; - /* Make sure we did not cut off anything */ - PVR_ASSERT(uiNumPhysBlocks << uiLog2Contiguity == (ui32ChunkSize * ui32NumPhysChunks)); - } - else - { - uiNumPhysBlocks = uiSize >> uiLog2Contiguity; - /* Make sure we did not cut off anything */ - PVR_ASSERT(uiNumPhysBlocks << uiLog2Contiguity == uiSize); - } - - uiNumVirtBlocks = uiSize >> uiLog2Contiguity; - PVR_ASSERT(uiNumVirtBlocks << uiLog2Contiguity == uiSize); - - psPMR->uiNumPDumpBlocks = uiNumVirtBlocks; - - phPDumpAllocInfo = (IMG_HANDLE*) OSAllocZMem(uiNumVirtBlocks * sizeof(IMG_HANDLE)); - - - for (i = 0; i < uiNumPhysBlocks; i++) - { - uiIndex = PMR_IsSparse(psPMR) ? puiMappingTable[i] : i; - - eError = PMR_PDumpSymbolicAddr(psPMR, - uiIndex * uiBlockSize, - sizeof(aszMemspaceName), - &aszMemspaceName[0], - sizeof(aszSymbolicName), - &aszSymbolicName[0], - &uiOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PDumpMalloc(PMR_DeviceNode(psPMR), - aszMemspaceName, - aszSymbolicName, - uiBlockSize, - uiBlockSize, - bInitialise, - ui32InitValue, - &phPDumpAllocInfo[uiIndex], - ui32PDumpFlags); - PVR_LOG_RETURN_VOID_IF_FALSE((eError != PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE), - "PDumpPMRMalloc PDump capture bound to other device"); - PVR_ASSERT(eError == PVRSRV_OK); - } - - /* (IMG_HANDLE) <- (IMG_HANDLE*) */ - *phPDumpAllocInfoOut = (IMG_HANDLE) phPDumpAllocInfo; - -} -#endif /* PDUMP */ - - -void *PMRGetPrivateData(const PMR *psPMR, - const PMR_IMPL_FUNCTAB *psFuncTab) -{ - return (psFuncTab == psPMR->psFuncTab) ? psPMR->pvFlavourData : NULL; -} - -#define PMR_PM_WORD_SIZE 4 - -PVRSRV_ERROR -PMRWritePMPageList(/* Target PMR, offset, and length */ - PMR *psPageListPMR, - IMG_DEVMEM_OFFSET_T uiTableOffset, - IMG_DEVMEM_SIZE_T uiTableLength, - /* Referenced PMR, and "page" granularity */ - PMR *psReferencePMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize, - PMR_PAGELIST **ppsPageList) -{ - PVRSRV_ERROR eError; - IMG_DEVMEM_SIZE_T uiWordSize; - IMG_UINT32 uiNumPages; - IMG_UINT32 uiPageIndex; - PMR_FLAGS_T uiFlags = psPageListPMR->uiFlags; - PMR_PAGELIST *psPageList; -#if defined(PDUMP) - IMG_CHAR aszTableEntryMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszTableEntrySymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiTableEntryPDumpOffset; - IMG_CHAR aszPageMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH]; - IMG_CHAR aszPageSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiPagePDumpOffset; - IMG_DEVMEM_OFFSET_T uiNextSymName; -#endif -#if !defined(NO_HARDWARE) - IMG_UINT32 uiPageListPageSize = 1 << psPageListPMR->uiLog2ContiguityGuarantee; - IMG_UINT64 uiPageListPMRPage = 0; - IMG_UINT64 uiPrevPageListPMRPage = 0; - IMG_HANDLE hPrivData = NULL; - void *pvKernAddr = NULL; - IMG_UINT32 *pui32DataPtr = NULL; - IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_DEV_PHYADDR *pasDevAddrPtr; - IMG_BOOL *pbPageIsValid; -#endif - - uiWordSize = PMR_PM_WORD_SIZE; - - /* check we're being asked to write the same number of 4-byte units as there are pages */ - uiNumPages = (IMG_UINT32)(psReferencePMR->uiLogicalSize >> uiLog2PageSize); - - if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psReferencePMR->uiLogicalSize) - { - /* Strictly speaking, it's possible to provoke this error in two ways: - (i) if it's not a whole multiple of the page size; or - (ii) if there are more than 4 billion pages. - The latter is unlikely. :) but the check is required in order to justify the cast. - */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE, return_error); - } - uiWordSize = (IMG_UINT32)uiTableLength / uiNumPages; - if (uiNumPages * uiWordSize != uiTableLength) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE, return_error); - } - - /* Check for integer overflow */ - PVR_GOTO_IF_INVALID_PARAM(uiTableOffset + uiTableLength > uiTableOffset, eError, return_error); - /* Check we're not being asked to write off the end of the PMR */ - PVR_GOTO_IF_INVALID_PARAM(uiTableOffset + uiTableLength <= psPageListPMR->uiLogicalSize, eError, return_error); - - /* the PMR into which we are writing must not be user CPU mappable: */ - if (PVRSRV_CHECK_CPU_READABLE(uiFlags) || PVRSRV_CHECK_CPU_WRITEABLE(uiFlags)) - { - PVR_DPF((PVR_DBG_ERROR, - "Masked flags = 0x%" PVRSRV_MEMALLOCFLAGS_FMTSPEC, - (PMR_FLAGS_T)(uiFlags & (PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE)))); - PVR_DPF((PVR_DBG_ERROR, - "Page list PMR allows CPU mapping (0x%" PVRSRV_MEMALLOCFLAGS_FMTSPEC ")", - uiFlags)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS, return_error); - } - - /* the PMR into which we are writing must not be user CPU cacheable: */ - if (PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags) || - PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) || - PVRSRV_CHECK_CPU_CACHED(uiFlags)) - { - PVR_DPF((PVR_DBG_ERROR, - "Masked flags = 0x%" PVRSRV_MEMALLOCFLAGS_FMTSPEC, - (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK))); - PVR_DPF((PVR_DBG_ERROR, - "Page list PMR allows CPU caching (0x%" PVRSRV_MEMALLOCFLAGS_FMTSPEC ")", - uiFlags)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS, return_error); - } - - if (_PMRIsSparse(psPageListPMR)) - { - PVR_LOG_GOTO_WITH_ERROR("psPageListPMR", eError, PVRSRV_ERROR_INVALID_PARAMS, return_error); - } - - if (_PMRIsSparse(psReferencePMR)) - { - PVR_LOG_GOTO_WITH_ERROR("psReferencePMR", eError, PVRSRV_ERROR_INVALID_PARAMS, return_error); - } - - psPageList = OSAllocMem(sizeof(PMR_PAGELIST)); - PVR_LOG_GOTO_IF_NOMEM(psPageList, eError, return_error); - - psPageList->psReferencePMR = psReferencePMR; - - /* Need to lock down the physical addresses of the reference PMR */ - /* N.B. This also checks that the requested "contiguity" is achievable */ - eError = PMRLockSysPhysAddresses(psReferencePMR); - PVR_GOTO_IF_ERROR(eError, free_page_list); - -#if !defined(NO_HARDWARE) - if (uiNumPages > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - pasDevAddrPtr = OSAllocMem(uiNumPages * sizeof(IMG_DEV_PHYADDR)); - PVR_LOG_GOTO_IF_NOMEM(pasDevAddrPtr, eError, unlock_phys_addrs); - - pbPageIsValid = OSAllocMem(uiNumPages * sizeof(IMG_BOOL)); - if (pbPageIsValid == NULL) - { - /* Clean-up before exit */ - OSFreeMem(pasDevAddrPtr); - - PVR_LOG_GOTO_WITH_ERROR("pbPageIsValid", eError, PVRSRV_ERROR_OUT_OF_MEMORY, free_devaddr_array); - } - } - else - { - pasDevAddrPtr = asDevPAddr; - pbPageIsValid = abValid; - } - - eError = PMR_DevPhysAddr(psReferencePMR, uiLog2PageSize, uiNumPages, 0, - pasDevAddrPtr, pbPageIsValid); - PVR_LOG_GOTO_IF_ERROR(eError, "PMR_DevPhysAddr", free_valid_array); -#endif - - for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++) - { - IMG_DEVMEM_OFFSET_T uiPMROffset = uiTableOffset + (uiWordSize * uiPageIndex); - -#if defined(PDUMP) - eError = PMR_PDumpSymbolicAddr(psPageListPMR, - uiPMROffset, - sizeof(aszTableEntryMemspaceName), - &aszTableEntryMemspaceName[0], - sizeof(aszTableEntrySymbolicName), - &aszTableEntrySymbolicName[0], - &uiTableEntryPDumpOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PMR_PDumpSymbolicAddr(psReferencePMR, - (IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize, - sizeof(aszPageMemspaceName), - &aszPageMemspaceName[0], - sizeof(aszPageSymbolicName), - &aszPageSymbolicName[0], - &uiPagePDumpOffset, - &uiNextSymName); - PVR_ASSERT(eError == PVRSRV_OK); - - eError = PDumpWriteShiftedMaskedValue(PMR_DeviceNode(psReferencePMR), - /* destination */ - aszTableEntryMemspaceName, - aszTableEntrySymbolicName, - uiTableEntryPDumpOffset, - /* source */ - aszPageMemspaceName, - aszPageSymbolicName, - uiPagePDumpOffset, - /* shift right */ - uiLog2PageSize, - /* shift left */ - 0, - /* mask */ - 0xffffffff, - /* word size */ - uiWordSize, - /* flags */ - PDUMP_FLAGS_CONTINUOUS); - PVR_ASSERT(eError == PVRSRV_OK); -#else - PVR_UNREFERENCED_PARAMETER(uiPMROffset); -#endif - -#if !defined(NO_HARDWARE) - - /* - We check for sparse PMR's at function entry, but as we can, - check that every page is valid - */ - PVR_ASSERT(pbPageIsValid[uiPageIndex]); - PVR_ASSERT(pasDevAddrPtr[uiPageIndex].uiAddr != 0); - PVR_ASSERT(((pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize) & 0xFFFFFFFF00000000ll) == 0); - - uiPageListPMRPage = uiPMROffset >> psReferencePMR->uiLog2ContiguityGuarantee; - - if ((pui32DataPtr == NULL) || (uiPageListPMRPage != uiPrevPageListPMRPage)) - { - size_t uiMappingOffset = uiPMROffset & (~(uiPageListPageSize - 1)); - size_t uiMappedSize; - - /* If we already had a page list mapped, we need to unmap it... */ - if (pui32DataPtr != NULL) - { - PMRReleaseKernelMappingData(psPageListPMR, hPrivData); - } - - eError = PMRAcquireKernelMappingData(psPageListPMR, - uiMappingOffset, - uiPageListPageSize, - &pvKernAddr, - &uiMappedSize, - &hPrivData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Error mapping page list PMR page (%" IMG_UINT64_FMTSPEC ") into kernel (%d)", - uiPageListPMRPage, eError)); - goto free_valid_array; - } - - uiPrevPageListPMRPage = uiPageListPMRPage; - PVR_ASSERT(uiMappedSize >= uiPageListPageSize); - PVR_ASSERT(pvKernAddr != NULL); - - pui32DataPtr = IMG_OFFSET_ADDR(pvKernAddr, (uiPMROffset & (uiPageListPageSize - 1))); - } - - PVR_ASSERT(((pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize) & 0xFFFFFFFF00000000ll) == 0); - - /* Write the physical page index into the page list PMR */ - *pui32DataPtr++ = TRUNCATE_64BITS_TO_32BITS(pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize); - - /* Last page so unmap */ - if (uiPageIndex == (uiNumPages - 1)) - { - PMRReleaseKernelMappingData(psPageListPMR, hPrivData); - } -#endif - } - - /* if this memory is allocated as write-combine we must flush write - * buffers */ - if (PVRSRV_CHECK_CPU_WRITE_COMBINE(psPageListPMR->uiFlags)) - { - OSWriteMemoryBarrier(NULL); - } - -#if !defined(NO_HARDWARE) - if (pasDevAddrPtr != asDevPAddr) - { - OSFreeMem(pbPageIsValid); - OSFreeMem(pasDevAddrPtr); - } -#endif - *ppsPageList = psPageList; - return PVRSRV_OK; - - /* Error exit paths follow */ -#if !defined(NO_HARDWARE) - -free_valid_array: - if (pbPageIsValid != abValid) - { - OSFreeMem(pbPageIsValid); - } - -free_devaddr_array: - if (pasDevAddrPtr != asDevPAddr) - { - OSFreeMem(pasDevAddrPtr); - } - -unlock_phys_addrs: - PMRUnlockSysPhysAddresses(psReferencePMR); -#endif - -free_page_list: - OSFreeMem(psPageList); - -return_error: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -PVRSRV_ERROR -PMRUnwritePMPageList(PMR_PAGELIST *psPageList) -{ - PVRSRV_ERROR eError; - - eError = PMRUnlockSysPhysAddresses(psPageList->psReferencePMR); - PVR_ASSERT(eError == PVRSRV_OK); - OSFreeMem(psPageList); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PMRZeroingPMR(PMR *psPMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize) -{ - IMG_UINT32 uiNumPages; - IMG_UINT32 uiPageIndex; - IMG_UINT32 ui32PageSize = 1 << uiLog2PageSize; - IMG_HANDLE hPrivData = NULL; - void *pvKernAddr = NULL; - PVRSRV_ERROR eError = PVRSRV_OK; - size_t uiMappedSize; - - PVR_ASSERT(psPMR); - - /* Calculate number of pages in this PMR */ - uiNumPages = (IMG_UINT32)(psPMR->uiLogicalSize >> uiLog2PageSize); - - /* Verify the logical Size is a multiple or the physical page size */ - if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psPMR->uiLogicalSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: PMR is not a multiple of %u", - __func__, - ui32PageSize)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE, MultiPage_Error); - } - - if (_PMRIsSparse(psPMR)) - { - PVR_LOG_GOTO_WITH_ERROR("psPMR", eError, PVRSRV_ERROR_INVALID_PARAMS, Sparse_Error); - } - - /* Scan through all pages of the PMR */ - for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++) - { - /* map the physical page (for a given PMR offset) into kernel space */ - eError = PMRAcquireKernelMappingData(psPMR, - (size_t)uiPageIndex << uiLog2PageSize, - ui32PageSize, - &pvKernAddr, - &uiMappedSize, - &hPrivData); - PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", AcquireKernelMapping_Error); - - /* ensure the mapped page size is the same as the physical page size */ - if (uiMappedSize != ui32PageSize) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Physical Page size = 0x%08x, Size of Mapping = 0x%016" IMG_UINT64_FMTSPECx, - __func__, - ui32PageSize, - (IMG_UINT64)uiMappedSize)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, MappingSize_Error); - } - - /* Use the conservative 'DeviceMemSet' here because we can't know - * if this PMR will be mapped cached. - */ - OSDeviceMemSet(pvKernAddr, 0, ui32PageSize); - - /* release mapping */ - PMRReleaseKernelMappingData(psPMR, hPrivData); - - } - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Zeroing PMR %p done (num pages %u, page size %u)", - __func__, - psPMR, - uiNumPages, - ui32PageSize)); - - return PVRSRV_OK; - - - /* Error handling */ - -MappingSize_Error: - PMRReleaseKernelMappingData(psPMR, hPrivData); - -AcquireKernelMapping_Error: -Sparse_Error: -MultiPage_Error: - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRDumpPageList(PMR *psPMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize) -{ - IMG_DEV_PHYADDR sDevAddrPtr; - IMG_UINT32 uiNumPages; - IMG_UINT32 uiPageIndex; - IMG_BOOL bPageIsValid; - IMG_UINT32 ui32Col = 16; - IMG_UINT32 ui32SizePerCol = 11; - IMG_UINT32 ui32ByteCount = 0; - IMG_CHAR pszBuffer[16 /* ui32Col */ * 11 /* ui32SizePerCol */ + 1]; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Get number of pages */ - uiNumPages = (IMG_UINT32)(psPMR->uiLogicalSize >> uiLog2PageSize); - - /* Verify the logical Size is a multiple or the physical page size */ - if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psPMR->uiLogicalSize) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR is not a multiple of %" IMG_UINT64_FMTSPEC, - __func__, (IMG_UINT64) (1ULL << uiLog2PageSize))); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE, MultiPage_Error); - } - - if (_PMRIsSparse(psPMR)) - { - PVR_LOG_GOTO_WITH_ERROR("psPMR", eError, PVRSRV_ERROR_INVALID_PARAMS, Sparse_Error); - } - - PVR_LOG((" PMR %p, Number of pages %u, Log2PageSize %d", psPMR, uiNumPages, uiLog2PageSize)); - - /* Print the address of the physical pages */ - for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++) - { - /* Get Device physical Address */ - eError = PMR_DevPhysAddr(psPMR, - uiLog2PageSize, - 1, - (IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize, - &sDevAddrPtr, - &bPageIsValid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMR %p failed to get DevPhysAddr with error %u", - __func__, - psPMR, - eError)); - goto DevPhysAddr_Error; - } - - ui32ByteCount += OSSNPrintf(pszBuffer + ui32ByteCount, ui32SizePerCol + 1, "%08x ", (IMG_UINT32)(sDevAddrPtr.uiAddr >> uiLog2PageSize)); - PVR_ASSERT(ui32ByteCount < ui32Col * ui32SizePerCol); - - if (uiPageIndex % ui32Col == ui32Col-1) - { - PVR_LOG((" Phys Page: %s", pszBuffer)); - ui32ByteCount = 0; - } - } - if (ui32ByteCount > 0) - { - PVR_LOG((" Phys Page: %s", pszBuffer)); - } - - return PVRSRV_OK; - - /* Error handling */ -DevPhysAddr_Error: -Sparse_Error: -MultiPage_Error: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRInit(void) -{ - PVRSRV_ERROR eError; - - /* Singleton PMR context already initialised */ - if (_gsSingletonPMRContext.bModuleInitialised) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR, out); - } - - eError = OSLockCreate(&_gsSingletonPMRContext.hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", out); - - _gsSingletonPMRContext.uiNextSerialNum = 1; - - _gsSingletonPMRContext.uiNextKey = 0x8300f001 * (uintptr_t)&_gsSingletonPMRContext; - - _gsSingletonPMRContext.bModuleInitialised = IMG_TRUE; - - _gsSingletonPMRContext.uiNumLivePMRs = 0; - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) - eError = MMapStatsInit(); - PVR_LOG_GOTO_IF_ERROR(eError, "MMapStatsInit", out); -#endif - -out: - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -PMRDeInit(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - goto out; - } - - /* Singleton PMR context is not initialised */ - if (!_gsSingletonPMRContext.bModuleInitialised) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR, out); - } - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) - MMapStatsDeInit(); -#endif - - if (_gsSingletonPMRContext.uiNumLivePMRs != 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error: %d live PMRs remain", - __func__, - _gsSingletonPMRContext.uiNumLivePMRs)); - PVR_DPF((PVR_DBG_ERROR, "%s: This is an unrecoverable error; a subsequent crash is inevitable", - __func__)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR, out); - } - - OSLockDestroy(_gsSingletonPMRContext.hLock); - - _gsSingletonPMRContext.bModuleInitialised = IMG_FALSE; - -out: - PVR_ASSERT(eError == PVRSRV_OK); - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pmr.h b/drivers/gpu/drm/img-rogue/1.17/pmr.h deleted file mode 100644 index 60abc2dc5bbd8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pmr.h +++ /dev/null @@ -1,1112 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Physmem (PMR) abstraction -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This module is responsible for - the "PMR" abstraction. A PMR (Physical Memory Resource) - represents some unit of physical memory which is - allocated/freed/mapped/unmapped as an indivisible unit - (higher software levels provide an abstraction above that - to deal with dividing this down into smaller manageable units). - Importantly, this module knows nothing of virtual memory, or - of MMUs etc., with one excusable exception. We have the - concept of a "page size", which really means nothing in - physical memory, but represents a "contiguity quantum" such - that the higher level modules which map this memory are able - to verify that it matches the needs of the page size for the - virtual realm into which it is being mapped. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PMR_H -#define SRVSRV_PMR_H - -/* include/ */ -#include "img_types.h" -#include "img_defs.h" -#include "pdumpdefs.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memallocflags.h" -#include "devicemem_typedefs.h" /* Required for export DEVMEM_EXPORTCOOKIE */ - -/* services/include */ -#include "pdump.h" -#include "physheap.h" - -/* services/server/include/ */ -#include "pmr_impl.h" -#include "opaque_types.h" - -#define PMR_MAX_TRANSLATION_STACK_ALLOC (32) - -/* Maximum size PMR can have is 8G of memory */ -#define PMR_MAX_SUPPORTED_SIZE IMG_UINT64_C(0x200000000) -/* Max number of pages in a PMR at 4k page size */ -#define PMR_MAX_SUPPORTED_PAGE_COUNT (PMR_MAX_SUPPORTED_SIZE >> 12ULL) - -typedef IMG_UINT64 PMR_BASE_T; -typedef IMG_UINT64 PMR_SIZE_T; -#define PMR_SIZE_FMTSPEC "0x%010"IMG_UINT64_FMTSPECX -#define PMR_VALUE32_FMTSPEC "0x%08X" -#define PMR_VALUE64_FMTSPEC "0x%016"IMG_UINT64_FMTSPECX -typedef IMG_UINT32 PMR_LOG2ALIGN_T; -typedef IMG_UINT64 PMR_PASSWORD_T; - -struct _PMR_MAPPING_TABLE_ -{ - PMR_SIZE_T uiChunkSize; /*!< Size of a "chunk" */ - IMG_UINT32 ui32NumPhysChunks; /*!< Number of physical chunks that are valid */ - IMG_UINT32 ui32NumVirtChunks; /*!< Number of virtual chunks in the mapping */ - /* Must be last */ - IMG_UINT32 aui32Translation[1]; /*!< Translation mapping for "logical" to physical */ -}; - -#define TRANSLATION_INVALID 0xFFFFFFFFUL - -typedef struct _PMR_EXPORT_ PMR_EXPORT; - -typedef struct _PMR_PAGELIST_ PMR_PAGELIST; - -/* - * PMRValidateSize - * - * Given a size value, check the value against the max supported - * PMR size of 1GB. Return IMG_FALSE if size exceeds max, IMG_TRUE - * otherwise. - */ -static inline IMG_BOOL PMRValidateSize(IMG_UINT64 uiSize) -{ - return (uiSize > PMR_MAX_SUPPORTED_SIZE) ? IMG_FALSE : IMG_TRUE; -} - -/* - * PMRCreatePMR - * - * Not to be called directly, only via implementations of PMR - * factories, e.g. in physmem_osmem.c, deviceclass.c, etc. - * - * Creates a PMR object, with callbacks and private data as per the - * FuncTab/PrivData args. - * - * Note that at creation time the PMR must set in stone the "logical - * size" and the "contiguity guarantee" - * - * Flags are also set at this time. (T.B.D. flags also immutable for - * the life of the PMR?) - * - * Logical size is the amount of Virtual space this allocation would - * take up when mapped. Note that this does not have to be the same - * as the actual physical size of the memory. For example, consider - * the sparsely allocated non-power-of-2 texture case. In this - * instance, the "logical size" would be the virtual size of the - * rounded-up power-of-2 texture. That some pages of physical memory - * may not exist does not affect the logical size calculation. - * - * The PMR must also supply the "contiguity guarantee" which is the - * finest granularity of alignment and size of physical pages that the - * PMR will provide after LockSysPhysAddresses is called. Note that - * the calling code may choose to call PMRSysPhysAddr with a finer - * granularity than this, for example if it were to map into a device - * MMU with a smaller page size, and it's also OK for the PMR to - * supply physical memory in larger chunks than this. But - * importantly, never the other way around. - * - * More precisely, the following inequality must be maintained - * whenever mappings and/or physical addresses exist: - * - * (device MMU page size) <= 2**(uiLog2ContiguityGuarantee) <= (actual contiguity of physical memory) - * - * The function table will contain the following callbacks which may - * be overridden by the PMR implementation: - * - * pfnLockPhysAddresses - * - * Called when someone locks requests that Physical pages are to - * be locked down via the PMRLockSysPhysAddresses() API. Note - * that if physical pages are prefaulted at PMR creation time and - * therefore static, it would not be necessary to override this - * function, in which case NULL may be supplied. - * - * pfnUnlockPhysAddresses - * - * The reverse of pfnLockPhysAddresses. Note that this should be - * NULL if and only if pfnLockPhysAddresses is NULL - * - * pfnSysPhysAddr - * - * This function is mandatory. This is the one which returns the - * system physical address for a given offset into this PMR. The - * "lock" function will have been called, if overridden, before - * this function, thus the implementation should not increase any - * refcount when answering this call. Refcounting, if necessary, - * should be done in the lock/unlock calls. Refcounting would - * not be necessary in the prefaulted/static scenario, as the - * pmr.c abstraction will handle the refcounting for the whole - * PMR. - * - * pfnFinalize - * - * Called when the PMR's refcount reaches zero and it gets - * destroyed. This allows the implementation to free up any - * resource acquired during creation time. - * - */ -PVRSRV_ERROR -PMRCreatePMR(PHYS_HEAP *psPhysHeap, - PMR_SIZE_T uiLogicalSize, - PMR_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee, - PMR_FLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - const PMR_IMPL_FUNCTAB *psFuncTab, - PMR_IMPL_PRIVDATA pvPrivData, - PMR_IMPL_TYPE eType, - PMR **ppsPMRPtr, - IMG_UINT32 ui32PDumpFlags); - -/* - * PMRLockSysPhysAddresses() - * - * Calls the relevant callback to lock down the system physical addresses of - * the memory that makes up the whole PMR. - * - * Before this call, it is not valid to use any of the information - * getting APIs: PMR_Flags(), PMR_SysPhysAddr(), - * [ see note below about lock/unlock semantics ] - * - * The caller of this function does not have to care about how the PMR - * is implemented. He only has to know that he is allowed access to - * the physical addresses _after_ calling this function and _until_ - * calling PMRUnlockSysPhysAddresses(). - * - * - * Notes to callback implementers (authors of PMR Factories): - * - * Some PMR implementations will be such that the physical memory exists for - * the lifetime of the PMR, with a static address, (and normally flags and - * symbolic address are static too) and so it is legal for a PMR - * implementation to not provide an implementation for the lock callback. - * - * Some PMR implementation may wish to page memory in from secondary storage - * on demand. The lock/unlock callbacks _may_ be the place to do this. - * (More likely, there would be a separate API for doing this, but this API - * provides a useful place to assert that it has been done) - */ - -PVRSRV_ERROR -PMRLockSysPhysAddresses(PMR *psPMR); - -PVRSRV_ERROR -PMRLockSysPhysAddressesNested(PMR *psPMR, - IMG_UINT32 ui32NestingLevel); - -/* - * PMRUnlockSysPhysAddresses() - * - * the reverse of PMRLockSysPhysAddresses() - */ -PVRSRV_ERROR -PMRUnlockSysPhysAddresses(PMR *psPMR); - -PVRSRV_ERROR -PMRUnlockSysPhysAddressesNested(PMR *psPMR, IMG_UINT32 ui32NestingLevel); - - -/*************************************************************************/ /*! -@Function PMRUnpinPMR -@Description This is the counterpart to PMRPinPMR(). It is meant to be - called before repinning an allocation. - - For a detailed description see client API documentation. - -@Input psPMR The physical memory to unpin. - -@Input bDevMapped A flag that indicates if this PMR has been - mapped to device virtual space. - Needed to check if this PMR is allowed to be - unpinned or not. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is - registered to be reclaimed. Error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR PMRUnpinPMR(PMR *psPMR, IMG_BOOL bDevMapped); - -/*************************************************************************/ /*! -@Function PMRPinPMR -@Description This is the counterpart to PMRUnpinPMR(). It is meant to be - called after unpinning an allocation. - - For a detailed description see client API documentation. - -@Input psPMR The physical memory to pin. - -@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content - was successfully restored. - - PVRSRV_ERROR_PMR_NEW_MEMORY when the content - could not be restored and new physical memory - was allocated. - - A different error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR PMRPinPMR(PMR *psPMR); - -/* - * PhysmemPMRExport() - * - * Given a PMR, creates a PMR "Export", which is a handle that - * provides sufficient data to be able to "import" this PMR elsewhere. - * The PMR Export is an object in its own right, whose existence - * implies a reference on the PMR, thus the PMR cannot be destroyed - * while the PMR Export exists. The intention is that the PMR Export - * will be wrapped in the devicemem layer by a cross process handle, - * and some IPC by which to communicate the handle value and password - * to other processes. The receiving process is able to unwrap this - * to gain access to the same PMR Export in this layer, and, via - * PhysmemPMRImport(), obtain a reference to the original PMR. - * - * The caller receives, along with the PMR Export object, information - * about the size and contiguity guarantee for the PMR, and also the - * PMRs secret password, in order to authenticate the subsequent - * import. - * - * N.B. If you call PMRExportPMR() (and it succeeds), you are - * promising to later call PMRUnexportPMR() - */ -PVRSRV_ERROR -PMRExportPMR(PMR *psPMR, - PMR_EXPORT **ppsPMRExport, - PMR_SIZE_T *puiSize, - PMR_LOG2ALIGN_T *puiLog2Contig, - PMR_PASSWORD_T *puiPassword); - -/*! -******************************************************************************* - - @Function PMRMakeLocalImportHandle - - @Description - - Transform a general handle type into one that we are able to import. - Takes a PMR reference. - - @Input psPMR The input PMR. - @Output ppsPMR The output PMR that is going to be transformed to the - correct handle type. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR -PMRMakeLocalImportHandle(PMR *psPMR, - PMR **ppsPMR); - -/*! -******************************************************************************* - - @Function PMRUnmakeLocalImportHandle - - @Description - - Take a PMR, destroy the handle and release a reference. - Counterpart to PMRMakeServerExportClientExport(). - - @Input psPMR PMR to destroy. - Created by PMRMakeLocalImportHandle(). - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR -PMRUnmakeLocalImportHandle(PMR *psPMR); - -/* - * PMRUnexporPMRt() - * - * The reverse of PMRExportPMR(). This causes the PMR to no longer be - * exported. If the PMR has already been imported, the imported PMR - * reference will still be valid, but no further imports will be possible. - */ -PVRSRV_ERROR -PMRUnexportPMR(PMR_EXPORT *psPMRExport); - -/* - * PMRImportPMR() - * - * Takes a PMR Export object, as obtained by PMRExportPMR(), and - * obtains a reference to the original PMR. - * - * The password must match, and is assumed to have been (by whatever - * means, IPC etc.) preserved intact from the former call to - * PMRExportPMR() - * - * The size and contiguity arguments are entirely irrelevant for the - * import, however they are verified in order to trap bugs. - * - * N.B. If you call PhysmemPMRImport() (and it succeeds), you are - * promising to later call PhysmemPMRUnimport() - */ -PVRSRV_ERROR -PMRImportPMR(PMR_EXPORT *psPMRExport, - PMR_PASSWORD_T uiPassword, - PMR_SIZE_T uiSize, - PMR_LOG2ALIGN_T uiLog2Contig, - PMR **ppsPMR); - -/* Function that alters the mutability property - * of the PMR - * Setting it to TRUE makes sure the PMR memory layout - * can't be changed through future calls */ -void -PMR_SetLayoutFixed(PMR *psPMR, IMG_BOOL bFlag); - -IMG_BOOL PMR_IsMemLayoutFixed(PMR *psPMR); - -/* - * PMRUnimportPMR() - * - * releases the reference on the PMR as obtained by PMRImportPMR() - */ -PVRSRV_ERROR -PMRUnimportPMR(PMR *psPMR); - -PVRSRV_ERROR -PMRLocalImportPMR(PMR *psPMR, - PMR **ppsPMR, - IMG_DEVMEM_SIZE_T *puiSize, - IMG_DEVMEM_ALIGN_T *puiAlign); - -/* - * Equivalent mapping functions when in kernel mode. - */ -PVRSRV_ERROR -PMRAcquireKernelMappingData(PMR *psPMR, - size_t uiLogicalOffset, - size_t uiSize, - void **ppvKernelAddressOut, - size_t *puiLengthOut, - IMG_HANDLE *phPrivOut); - -PVRSRV_ERROR -PMRAcquireSparseKernelMappingData(PMR *psPMR, - size_t uiLogicalOffset, - size_t uiSize, - void **ppvKernelAddressOut, - size_t *puiLengthOut, - IMG_HANDLE *phPrivOut); - -PVRSRV_ERROR -PMRReleaseKernelMappingData(PMR *psPMR, - IMG_HANDLE hPriv); - -/* - * PMR_ReadBytes() - * - * calls into the PMR implementation to read up to uiBufSz bytes, - * returning the actual number read in *puiNumBytes - * - * this will read up to the end of the PMR, or the next symbolic name - * boundary, or until the requested number of bytes is read, whichever - * comes first - * - * In the case of sparse PMR's the caller doesn't know what offsets are - * valid and which ones aren't so we will just write 0 to invalid offsets - */ -PVRSRV_ERROR -PMR_ReadBytes(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes); - -/* - * PMR_WriteBytes() - * - * calls into the PMR implementation to write up to uiBufSz bytes, - * returning the actual number read in *puiNumBytes - * - * this will write up to the end of the PMR, or the next symbolic name - * boundary, or until the requested number of bytes is written, whichever - * comes first - * - * In the case of sparse PMR's the caller doesn't know what offsets are - * valid and which ones aren't so we will just ignore data at invalid offsets - */ -PVRSRV_ERROR -PMR_WriteBytes(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes); - -/*************************************************************************/ /*! -@Function PMRMMapPMR -@Description Performs the necessary steps to map the PMR into a user process - address space. The caller does not need to call - PMRLockSysPhysAddresses before calling this function. - -@Input psPMR PMR to map. - -@Input pOSMMapData OS specific data needed to create a mapping. - -@Input uiCpuAccessFlags Flags to indicate if the mapping request - requires read, write or both access. - -@Return PVRSRV_ERROR: PVRSRV_OK on success or an error otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR -PMRMMapPMR(PMR *psPMR, - PMR_MMAP_DATA pOSMMapData, - PVRSRV_MEMALLOCFLAGS_T uiCpuAccessFlags); - -/* - * PMRRefPMR() - * - * Take a reference on the passed in PMR - */ -void -PMRRefPMR(PMR *psPMR); - -/* - * PMRUnrefPMR() - * - * This undoes a call to any of the PhysmemNew* family of APIs - * (i.e. any PMR factory "constructor") - * - * This relinquishes a reference to the PMR, and, where the refcount - * reaches 0, causes the PMR to be destroyed (calling the finalizer - * callback on the PMR, if there is one) - */ -PVRSRV_ERROR -PMRUnrefPMR(PMR *psPMR); - -/* - * PMRRefPMR2() - * - * Take a reference on the passed in PMR. - * - * This function does not perform address locking as opposed to PMRRefPMR(). - */ -void -PMRRefPMR2(PMR *psPMR); - -/* - * PMRUnrefPMR2() - * - * This undoes a call to any of the PhysmemNew* family of APIs - * (i.e. any PMR factory "constructor"). - * - * This relinquishes a reference to the PMR, and, where the refcount - * reaches 0, causes the PMR to be destroyed (calling the finalizer - * callback on the PMR, if there is one) - */ -void -PMRUnrefPMR2(PMR *psPMR); - -/* - * PMRUnrefUnlockPMR() - * - * Same as above but also unlocks the PMR. - */ -PVRSRV_ERROR -PMRUnrefUnlockPMR(PMR *psPMR); - -/* - * PMRCpuMapCountIncr() - * - * Increment count of the number of current CPU mappings of the PMR. - * - */ -void -PMRCpuMapCountIncr(PMR *psPMR); - -/* - * PMRCpuMapCountDecr() - * - * Decrement count of the number of current CPU mappings of the PMR. - * - */ -void -PMRCpuMapCountDecr(PMR *psPMR); - -IMG_BOOL -PMR_IsCpuMapped(PMR *psPMR); - -PPVRSRV_DEVICE_NODE -PMR_DeviceNode(const PMR *psPMR); - -/* - * PMRIsPMRLive() - * - * This function returns true if the PMR is in use and false otherwise. - * This function is not thread safe and hence the caller needs to ensure the - * thread safety by explicitly taking PMR or through other means. - */ -IMG_BOOL PMRIsPMRLive(PMR *psPMR); - -/* - * PMR_Flags() - * - * Flags are static and guaranteed for the life of the PMR. Thus this - * function is idempotent and acquire/release semantics is not required. - * - * Returns the flags as specified on the PMR. The flags are to be - * interpreted as mapping permissions - */ -PMR_FLAGS_T -PMR_Flags(const PMR *psPMR); - -IMG_BOOL -PMR_IsSparse(const PMR *psPMR); - -IMG_BOOL -PMR_IsUnpinned(const PMR *psPMR); - -void -PMR_LogicalSize(const PMR *psPMR, - IMG_DEVMEM_SIZE_T *puiLogicalSize); - -PVRSRV_ERROR -PMR_PhysicalSize(const PMR *psPMR, - IMG_DEVMEM_SIZE_T *puiPhysicalSize); - -PHYS_HEAP * -PMR_PhysHeap(const PMR *psPMR); - -PMR_MAPPING_TABLE * -PMR_GetMappingTable(const PMR *psPMR); - -IMG_UINT32 -PMR_GetLog2Contiguity(const PMR *psPMR); - -/* - * PMRGetMaxChunkCount - * - * Given a PMR, calculate the maximum number of chunks supported by - * the PMR from the contiguity and return it. - */ -IMG_UINT32 PMRGetMaxChunkCount(PMR *psPMR); - -const IMG_CHAR * -PMR_GetAnnotation(const PMR *psPMR); - -/* - * PMR_IsOffsetValid() - * - * Returns if an address offset inside a PMR has a valid - * physical backing. - */ -PVRSRV_ERROR -PMR_IsOffsetValid(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_BOOL *pbValid); - -PMR_IMPL_TYPE -PMR_GetType(const PMR *psPMR); - -IMG_INT32 -PMR_GetRefCount(const PMR *psPMR); - -/* - * PMR_DevPhysAddr() - * - * A note regarding Lock/Unlock semantics - * ====================================== - * - * PMR_DevPhysAddr may only be called after PMRLockSysPhysAddresses() - * has been called. The data returned may be used only until - * PMRUnlockSysPhysAddresses() is called after which time the licence - * to use the data is revoked and the information may be invalid. - * - * Given an offset, this function returns the device physical address of the - * corresponding page in the PMR. It may be called multiple times - * until the address of all relevant pages has been determined. - * - * If caller only wants one physical address it is sufficient to pass in: - * ui32Log2PageSize==0 and ui32NumOfPages==1 - */ -PVRSRV_ERROR -PMR_DevPhysAddr(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEV_PHYADDR *psDevAddr, - IMG_BOOL *pbValid); - -/* - * PMR_CpuPhysAddr() - * - * See note above about Lock/Unlock semantics. - * - * Given an offset, this function returns the CPU physical address of the - * corresponding page in the PMR. It may be called multiple times - * until the address of all relevant pages has been determined. - * - */ -PVRSRV_ERROR -PMR_CpuPhysAddr(const PMR *psPMR, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_CPU_PHYADDR *psCpuAddrPtr, - IMG_BOOL *pbValid); - -PVRSRV_ERROR -PMRGetUID(PMR *psPMR, - IMG_UINT64 *pui64UID); -/* - * PMR_ChangeSparseMem() - * - * See note above about Lock/Unlock semantics. - * - * This function alters the memory map of the given PMR in device space by - * adding/deleting the pages as requested. - * - */ -PVRSRV_ERROR PMR_ChangeSparseMem(PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiSparseFlags); - -/* - * PMR_ChangeSparseMemCPUMap() - * - * See note above about Lock/Unlock semantics. - * - * This function alters the memory map of the given PMR in CPU space by - * adding/deleting the pages as requested. - */ -PVRSRV_ERROR PMR_ChangeSparseMemCPUMap(PMR *psPMR, - IMG_UINT64 sCpuVAddrBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices); - -#if defined(PDUMP) - -/* - * PMR_PDumpSymbolicAddr() - * - * Given an offset, returns the pdump memspace name and symbolic - * address of the corresponding page in the PMR. - * - * Note that PDump memspace names and symbolic addresses are static - * and valid for the lifetime of the PMR, therefore we don't require - * acquire/release semantics here. - * - * Note that it is expected that the pdump "mapping" code will call - * this function multiple times as each page is mapped in turn - * - * Note that NextSymName is the offset from the base of the PMR to the - * next pdump symbolic address (or the end of the PMR if the PMR only - * had one PDUMPMALLOC - */ -PVRSRV_ERROR -PMR_PDumpSymbolicAddr(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32NamespaceNameLen, - IMG_CHAR *pszNamespaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T *puiNewOffset, - IMG_DEVMEM_OFFSET_T *puiNextSymName - ); - -/* - * PMRPDumpLoadMemValue32() - * - * writes the current contents of a dword in PMR memory to the pdump - * script stream. Useful for patching a buffer by simply editing the - * script output file in ASCII plain text. - * - */ -PVRSRV_ERROR -PMRPDumpLoadMemValue32(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * PMRPDumpCopyMem32 - * - * Adds in the pdump script stream a copy of a dword in one PMR memory - * location to another PMR memory location. - * - */ -PVRSRV_ERROR -PMRPDumpCopyMem32(PMR *psDstPMR, - IMG_DEVMEM_OFFSET_T uiDstLogicalOffset, - PMR *psSrcPMR, - IMG_DEVMEM_OFFSET_T uiSrcLogicalOffset, - const IMG_CHAR *pszTmpVar, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * PMRPDumpLoadMemValue64() - * - * writes the current contents of a dword in PMR memory to the pdump - * script stream. Useful for patching a buffer by simply editing the - * script output file in ASCII plain text. - * - */ -PVRSRV_ERROR -PMRPDumpLoadMemValue64(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * PMRPDumpCopyMem64 - * - * Adds in the pdump script stream a copy of a quadword in one PMR memory - * location to another PMR memory location. - */ -PVRSRV_ERROR -PMRPDumpCopyMem64(PMR *psDstPMR, - IMG_DEVMEM_OFFSET_T uiDstLogicalOffset, - PMR *psSrcPMR, - IMG_DEVMEM_OFFSET_T uiSrcLogicalOffset, - const IMG_CHAR *pszTmpVar, - PDUMP_FLAGS_T uiPDumpFlags); - -/* - * PMRPDumpLoadMem() - * - * Writes the current contents of the PMR memory to the pdump PRM stream, - * and emits some PDump code to the script stream to LDB said bytes from - * said file. If bZero is IMG_TRUE then the PDump zero page is used as the - * source for the LDB. - */ -PVRSRV_ERROR -PMRPDumpLoadMem(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags, - IMG_BOOL bZero); - -/* - * PMRPDumpSaveToFile() - * - * Emits some PDump that does an SAB (save bytes) using the PDump symbolic - * address of the PMR. Note that this is generally not the preferred way to - * dump the buffer contents. There is an equivalent function in - * devicemem_server.h which also emits SAB but using the virtual address, - * which is the "right" way to dump the buffer contents to a file. - * This function exists just to aid testing by providing a means to dump - * the PMR directly by symbolic address also. - */ -PVRSRV_ERROR -PMRPDumpSaveToFile(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset); -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMR_PDumpSymbolicAddr) -#endif -static INLINE PVRSRV_ERROR -PMR_PDumpSymbolicAddr(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32NamespaceNameLen, - IMG_CHAR *pszNamespaceName, - IMG_UINT32 ui32SymbolicAddrLen, - IMG_CHAR *pszSymbolicAddr, - IMG_DEVMEM_OFFSET_T *puiNewOffset, - IMG_DEVMEM_OFFSET_T *puiNextSymName) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(ui32NamespaceNameLen); - PVR_UNREFERENCED_PARAMETER(pszNamespaceName); - PVR_UNREFERENCED_PARAMETER(ui32SymbolicAddrLen); - PVR_UNREFERENCED_PARAMETER(pszSymbolicAddr); - PVR_UNREFERENCED_PARAMETER(puiNewOffset); - PVR_UNREFERENCED_PARAMETER(puiNextSymName); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpLoadMemValue32) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpLoadMemValue32(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpLoadMemValue64) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpLoadMemValue64(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT64 ui64Value, - PDUMP_FLAGS_T uiPDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(ui64Value); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpLoadMem) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpLoadMem(PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - PDUMP_FLAGS_T uiPDumpFlags, - IMG_BOOL bZero) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); - PVR_UNREFERENCED_PARAMETER(bZero); - return PVRSRV_OK; -} - - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpSaveToFile) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpSaveToFile(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT32 uiArraySize, - const IMG_CHAR *pszFilename, - IMG_UINT32 uiFileOffset) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(uiSize); - PVR_UNREFERENCED_PARAMETER(uiArraySize); - PVR_UNREFERENCED_PARAMETER(pszFilename); - PVR_UNREFERENCED_PARAMETER(uiFileOffset); - return PVRSRV_OK; -} - -#endif /* PDUMP */ - -/* This function returns the private data that a pmr subtype embedded in - * here. We use the function table pointer as "authorisation" that this - * function is being called by the pmr subtype implementation. We can - * assume (assert) that. It would be a bug in the implementation of the - * pmr subtype if this assertion ever fails. - */ -void * -PMRGetPrivateData(const PMR *psPMR, - const PMR_IMPL_FUNCTAB *psFuncTab); - -PVRSRV_ERROR -PMRZeroingPMR(PMR *psPMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize); - -PVRSRV_ERROR -PMRDumpPageList(PMR *psReferencePMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize); - -PVRSRV_ERROR -PMRWritePMPageList(/* Target PMR, offset, and length */ - PMR *psPageListPMR, - IMG_DEVMEM_OFFSET_T uiTableOffset, - IMG_DEVMEM_SIZE_T uiTableLength, - /* Referenced PMR, and "page" granularity */ - PMR *psReferencePMR, - IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize, - PMR_PAGELIST **ppsPageList); - -/* Doesn't actually erase the page list - just releases - * the appropriate refcounts - */ -PVRSRV_ERROR // should be void, surely -PMRUnwritePMPageList(PMR_PAGELIST *psPageList); - -#if defined(PDUMP) -PVRSRV_ERROR -PMRPDumpPol32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiFlags); - -PVRSRV_ERROR -PMRPDumpCheck32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiPDumpFlags); - -PVRSRV_ERROR -PMRPDumpCBP(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize); -#else - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpPol32) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpPol32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiFlags) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(uiFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpCheck32) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpCheck32(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiFlags) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiLogicalOffset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(uiFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PMRPDumpCBP) -#endif -static INLINE PVRSRV_ERROR -PMRPDumpCBP(const PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiReadOffset, - IMG_DEVMEM_OFFSET_T uiWriteOffset, - IMG_DEVMEM_SIZE_T uiPacketSize, - IMG_DEVMEM_SIZE_T uiBufferSize) -{ - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiReadOffset); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); - return PVRSRV_OK; -} -#endif - -PPVRSRV_DEVICE_NODE PMRGetExportDeviceNode(PMR_EXPORT *psExportPMR); - -/* - * PMRInit() - * - * To be called once and only once to initialise the internal data in - * the PMR module (mutexes and such) - * - * Not for general use. Only PVRSRVInit(); should be calling this. - */ -PVRSRV_ERROR -PMRInit(void); - -/* - * PMRDeInit() - * - * To be called once and only once to deinitialise the internal data in - * the PMR module (mutexes and such) and for debug checks - * - * Not for general use. Only PVRSRVDeInit(); should be calling this. - */ -PVRSRV_ERROR -PMRDeInit(void); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -PVRSRV_ERROR -PMRStoreRIHandle(PMR *psPMR, void *hRIHandle); -#endif - -/* - * PMRLockPMR() - * - * To be called when the PMR must not be modified by any other call-stack. - * Acquires the mutex on the passed in PMR. - */ -void -PMRLockPMR(PMR *psPMR); - -/* - * PMRUnlockPMR() - * - * To be called when the PMR is no longer being modified. - * Releases the per-PMR mutex. - */ -void -PMRUnlockPMR(PMR *psPMR); - -#endif /* #ifdef SRVSRV_PMR_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pmr_impl.h b/drivers/gpu/drm/img-rogue/1.17/pmr_impl.h deleted file mode 100644 index cae0b7eef165b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pmr_impl.h +++ /dev/null @@ -1,539 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Implementation Callbacks for Physmem (PMR) abstraction -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Part of the memory management. This file is for definitions - that are private to the world of PMRs, but that need to be - shared between pmr.c itself and the modules that implement the - callbacks for the PMR. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVSRV_PMR_IMPL_H -#define SRVSRV_PMR_IMPL_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" - -/*! Physical Memory Resource type. - */ -typedef struct _PMR_ PMR; - -/*! Per-flavour callbacks need to be shared with generic implementation - * (pmr.c). - */ -typedef void *PMR_IMPL_PRIVDATA; - -/*! Type for holding flags passed to the PMR factory. - */ -typedef PVRSRV_MEMALLOCFLAGS_T PMR_FLAGS_T; - -/*! Mapping table for the allocation. - * - * PMR's can be sparse in which case not all the logical addresses in it are - * valid. The mapping table translates logical offsets into physical offsets. - * - * This table is always passed to the PMR factory regardless if the memory is - * sparse or not. In case of non-sparse memory all virtual offsets are mapped - * to physical offsets. - */ -typedef struct _PMR_MAPPING_TABLE_ PMR_MAPPING_TABLE; - -/*! Private data passed to the ::PFN_MMAP_FN function. - */ -typedef void *PMR_MMAP_DATA; - -/*! PMR factory type. - */ -typedef enum _PMR_IMPL_TYPE_ -{ - PMR_TYPE_NONE = 0, - PMR_TYPE_OSMEM, - PMR_TYPE_LMA, - PMR_TYPE_DMABUF, - PMR_TYPE_EXTMEM, - PMR_TYPE_DC, - PMR_TYPE_TDFWMEM, - PMR_TYPE_TDSECBUF -} PMR_IMPL_TYPE; - -/*************************************************************************/ /*! -@Brief Callback function type PFN_LOCK_PHYS_ADDRESSES_FN - -@Description Called to lock down the physical addresses for all pages - allocated for a PMR. - The default implementation is to simply increment a - lock-count for debugging purposes. - If overridden, the PFN_LOCK_PHYS_ADDRESSES_FN function will - be called when someone first requires a physical address, - and the PFN_UNLOCK_PHYS_ADDRESSES_FN counterpart will be - called when the last such reference is released. - The PMR implementation may assume that physical addresses - will have been "locked" in this manner before any call is - made to the pfnDevPhysAddr() callback - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) - -@Return PVRSRV_OK if the operation was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_LOCK_PHYS_ADDRESSES_FN)(PMR_IMPL_PRIVDATA pvPriv); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_UNLOCK_PHYS_ADDRESSES_FN - -@Description Called to release the lock taken on the physical addresses - for all pages allocated for a PMR. - The default implementation is to simply decrement a - lock-count for debugging purposes. - If overridden, the PFN_UNLOCK_PHYS_ADDRESSES_FN will be - called when the last reference taken on the PMR is - released. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) - -@Return PVRSRV_OK if the operation was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_UNLOCK_PHYS_ADDRESSES_FN)(PMR_IMPL_PRIVDATA pvPriv); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_DEV_PHYS_ADDR_FN - -@Description Called to obtain one or more physical addresses for given - offsets within a PMR. - - The PFN_LOCK_PHYS_ADDRESSES_FN callback (if overridden) is - guaranteed to have been called prior to calling the - PFN_DEV_PHYS_ADDR_FN callback and the caller promises not to - rely on the physical address thus obtained after the - PFN_UNLOCK_PHYS_ADDRESSES_FN callback is called. - - Implementation of this callback is mandatory. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input ui32Log2PageSize The log2 page size. -@Input ui32NumOfAddr The number of addresses to be returned -@Input puiOffset The offset from the start of the PMR - (in bytes) for which the physical - address is required. Where multiple - addresses are requested, this will - contain a list of offsets. -@Output pbValid List of boolean flags indicating which - addresses in the returned list - (psDevAddrPtr) are valid (for sparse - allocations, not all pages may have a - physical backing) -@Output psDevAddrPtr Returned list of physical addresses - -@Return PVRSRV_OK if the operation was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_DEV_PHYS_ADDR_FN)(PMR_IMPL_PRIVDATA pvPriv, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfAddr, - IMG_DEVMEM_OFFSET_T *puiOffset, - IMG_BOOL *pbValid, - IMG_DEV_PHYADDR *psDevAddrPtr); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN - -@Description Called to obtain a kernel-accessible address (mapped to a - virtual address if required) for the PMR for use internally - in Services. - - Implementation of this function for the (default) PMR factory providing - OS-allocations is mandatory (the driver will expect to be able to call - this function for OS-provided allocations). - For other PMR factories, implementation of this function is only necessary - where an MMU mapping is required for the Kernel to be able to access the - allocated memory. - If no mapping is needed, this function can remain unimplemented and the - pfn may be set to NULL. -@Input pvPriv Private data (which was generated by - the PMR factory when PMR was created) -@Input uiOffset Offset from the beginning of the PMR - at which mapping is to start -@Input uiSize Size of mapping (in bytes) -@Output ppvKernelAddressOut Mapped kernel address -@Output phHandleOut Returned handle of the new mapping -@Input ulFlags Mapping flags - -@Return PVRSRV_OK if the mapping was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN)(PMR_IMPL_PRIVDATA pvPriv, - size_t uiOffset, - size_t uiSize, - void **ppvKernelAddressOut, - IMG_HANDLE *phHandleOut, - PMR_FLAGS_T ulFlags); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_RELEASE_KERNEL_MAPPING_DATA_FN - -@Description Called to release a mapped kernel virtual address - - Implementation of this callback is mandatory if - PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN is provided for the PMR factory, - otherwise this function can remain unimplemented and the pfn may be set - to NULL. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input hHandle Handle of the mapping to be released - -@Return None -*/ /**************************************************************************/ -typedef void (*PFN_RELEASE_KERNEL_MAPPING_DATA_FN)(PMR_IMPL_PRIVDATA pvPriv, - IMG_HANDLE hHandle); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_READ_BYTES_FN - -@Description Called to read bytes from an unmapped allocation - - Implementation of this callback is optional - where it is not provided, - the driver will use PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN to map the entire - PMR (if an MMU mapping is required for the Kernel to be able to access the - allocated memory). - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input uiOffset Offset from the beginning of the PMR at - which to begin reading -@Output pcBuffer Buffer in which to return the read data -@Input uiBufSz Number of bytes to be read -@Output puiNumBytes Number of bytes actually read (may be - less than uiBufSz) - -@Return PVRSRV_OK if the read was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_READ_BYTES_FN)(PMR_IMPL_PRIVDATA pvPriv, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_WRITE_BYTES_FN - -@Description Called to write bytes into an unmapped allocation - - Implementation of this callback is optional - where it is not provided, - the driver will use PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN to map the entire - PMR (if an MMU mapping is required for the Kernel to be able to access the - allocated memory). - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input uiOffset Offset from the beginning of the PMR at - which to begin writing -@Input pcBuffer Buffer containing the data to be written -@Input uiBufSz Number of bytes to be written -@Output puiNumBytes Number of bytes actually written (may be - less than uiBufSz) - -@Return PVRSRV_OK if the write was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_WRITE_BYTES_FN)(PMR_IMPL_PRIVDATA pvPriv, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_UINT8 *pcBuffer, - size_t uiBufSz, - size_t *puiNumBytes); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_UNPIN_MEM_FN - -@Description Called to unpin an allocation. - Once unpinned, the pages backing the allocation may be - re-used by the Operating System for another purpose. - When the pages are required again, they may be re-pinned - (by calling PFN_PIN_MEM_FN). The driver will try to return - same pages as before. The caller will be told if the - content of these returned pages has been modified or if - the pages returned are not the original pages. - - Implementation of this callback is optional. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) - -@Return PVRSRV_OK if the unpin was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_UNPIN_MEM_FN)(PMR_IMPL_PRIVDATA pPriv); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_PIN_MEM_FN - -@Description Called to pin a previously unpinned allocation. - The driver will try to return same pages as were previously - assigned to the allocation. The caller will be told if the - content of these returned pages has been modified or if - the pages returned are not the original pages. - - Implementation of this callback is optional. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) - -@Input psMappingTable Mapping table, which describes how - virtual 'chunks' are to be mapped to - physical 'chunks' for the allocation. - -@Return PVRSRV_OK if the original pages were returned unmodified. - PVRSRV_ERROR_PMR_NEW_MEMORY if the memory returned was modified - or different pages were returned. - Another PVRSRV_ERROR code on failure. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_PIN_MEM_FN)(PMR_IMPL_PRIVDATA pPriv, - PMR_MAPPING_TABLE *psMappingTable); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_CHANGE_SPARSE_MEM_FN - -@Description Called to modify the physical backing for a given sparse - allocation. - The caller provides a list of the pages within the sparse - allocation which should be backed with a physical allocation - and a list of the pages which do not require backing. - - Implementation of this callback is mandatory. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input psPMR The PMR of the sparse allocation to be - modified -@Input ui32AllocPageCount The number of pages specified in - pai32AllocIndices -@Input pai32AllocIndices The list of pages in the sparse - allocation that should be backed with a - physical allocation. Pages are - referenced by their index within the - sparse allocation (e.g. in a 10 page - allocation, pages are denoted by - indices 0 to 9) -@Input ui32FreePageCount The number of pages specified in - pai32FreeIndices -@Input pai32FreeIndices The list of pages in the sparse - allocation that do not require - a physical allocation. -@Input ui32Flags Allocation flags - -@Return PVRSRV_OK if the sparse allocation physical backing was updated - successfully, an error code otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_CHANGE_SPARSE_MEM_FN)(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices, - IMG_UINT32 uiFlags); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_CHANGE_SPARSE_MEM_CPU_MAP_FN - -@Description Called to modify which pages are mapped for a given sparse - allocation. - The caller provides a list of the pages within the sparse - allocation which should be given a CPU mapping and a list - of the pages which do not require a CPU mapping. - - Implementation of this callback is mandatory. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input psPMR The PMR of the sparse allocation to be - modified -@Input sCpuVAddrBase The virtual base address of the sparse - allocation -@Input ui32AllocPageCount The number of pages specified in - pai32AllocIndices -@Input pai32AllocIndices The list of pages in the sparse - allocation that should be given a CPU - mapping. Pages are referenced by their - index within the sparse allocation (e.g. - in a 10 page allocation, pages are - denoted by indices 0 to 9) -@Input ui32FreePageCount The number of pages specified in - pai32FreeIndices -@Input pai32FreeIndices The list of pages in the sparse - allocation that do not require a CPU - mapping. - -@Return PVRSRV_OK if the page mappings were updated successfully, an - error code otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_CHANGE_SPARSE_MEM_CPU_MAP_FN)(PMR_IMPL_PRIVDATA pPriv, - const PMR *psPMR, - IMG_UINT64 sCpuVAddrBase, - IMG_UINT32 ui32AllocPageCount, - IMG_UINT32 *pai32AllocIndices, - IMG_UINT32 ui32FreePageCount, - IMG_UINT32 *pai32FreeIndices); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_MMAP_FN - -@Description Called to map pages in the specified PMR. - - Implementation of this callback is optional. - Where it is provided, it will be used in place of OSMMapPMRGeneric(). - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) -@Input psPMR The PMR of the allocation to be mapped -@Input pMMapData OS-specific data to describe how mapping - should be performed - -@Return PVRSRV_OK if the mapping was successful, an error code - otherwise. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_MMAP_FN)(PMR_IMPL_PRIVDATA pPriv, - PMR *psPMR, - PMR_MMAP_DATA pMMapData); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_FINALIZE_FN - -@Description Called to destroy the PMR. - This callback will be called only when all references to - the PMR have been dropped. - The PMR was created via a call to PhysmemNewRamBackedPMR() - and is destroyed via this callback. - - Implementation of this callback is mandatory. - -@Input pvPriv Private data (which was generated by the - PMR factory when PMR was created) - -@Return PVRSRV_OK if the PMR destruction was successful, an error - code otherwise. - Currently PVRSRV_ERROR_PMR_STILL_REFERENCED is the only - error returned from physmem_dmabuf.c layer and on this - error, destroying of the PMR is aborted without disturbing - the PMR state. -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_FINALIZE_FN)(PMR_IMPL_PRIVDATA pvPriv); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_ACQUIRE_PMR_FACTORY_LOCK_FN - -@Description Called to acquire the PMR factory's global lock, if it has one, - hence callback optional. Factories which support entry points - in addition to the normal bridge calls, for example, from the - native OS that manipulate the PMR reference count should - create a factory lock and implementations for these call backs. - - Implementation of this callback is optional. - -@Return None -*/ -/*****************************************************************************/ -typedef void (*PFN_ACQUIRE_PMR_FACTORY_LOCK_FN)(void); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_RELEASE_PMR_FACTORY_LOCK_FN - -@Description Called to release the PMR factory's global lock acquired by calling - pfn_acquire_pmr_factory_lock callback. - - Implementation of this callback is optional. - -@Return None -*/ /**************************************************************************/ -typedef void (*PFN_RELEASE_PMR_FACTORY_LOCK_FN)(void); - -/*! PMR factory callback table. - */ -struct _PMR_IMPL_FUNCTAB_ { - /*! Callback function pointer, see ::PFN_LOCK_PHYS_ADDRESSES_FN */ - PFN_LOCK_PHYS_ADDRESSES_FN pfnLockPhysAddresses; - /*! Callback function pointer, see ::PFN_UNLOCK_PHYS_ADDRESSES_FN */ - PFN_UNLOCK_PHYS_ADDRESSES_FN pfnUnlockPhysAddresses; - - /*! Callback function pointer, see ::PFN_DEV_PHYS_ADDR_FN */ - PFN_DEV_PHYS_ADDR_FN pfnDevPhysAddr; - - /*! Callback function pointer, see ::PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN */ - PFN_ACQUIRE_KERNEL_MAPPING_DATA_FN pfnAcquireKernelMappingData; - /*! Callback function pointer, see ::PFN_RELEASE_KERNEL_MAPPING_DATA_FN */ - PFN_RELEASE_KERNEL_MAPPING_DATA_FN pfnReleaseKernelMappingData; - - /*! Callback function pointer, see ::PFN_READ_BYTES_FN */ - PFN_READ_BYTES_FN pfnReadBytes; - /*! Callback function pointer, see ::PFN_WRITE_BYTES_FN */ - PFN_WRITE_BYTES_FN pfnWriteBytes; - - /*! Callback function pointer, see ::PFN_UNPIN_MEM_FN */ - PFN_UNPIN_MEM_FN pfnUnpinMem; - /*! Callback function pointer, see ::PFN_PIN_MEM_FN */ - PFN_PIN_MEM_FN pfnPinMem; - - /*! Callback function pointer, see ::PFN_CHANGE_SPARSE_MEM_FN */ - PFN_CHANGE_SPARSE_MEM_FN pfnChangeSparseMem; - /*! Callback function pointer, see ::PFN_CHANGE_SPARSE_MEM_CPU_MAP_FN */ - PFN_CHANGE_SPARSE_MEM_CPU_MAP_FN pfnChangeSparseMemCPUMap; - - /*! Callback function pointer, see ::PFN_MMAP_FN */ - PFN_MMAP_FN pfnMMap; - - /*! Callback function pointer, see ::PFN_FINALIZE_FN */ - PFN_FINALIZE_FN pfnFinalize; - - /*! Callback function pointer, see ::PFN_ACQUIRE_PMR_FACTORY_LOCK_FN */ - PFN_ACQUIRE_PMR_FACTORY_LOCK_FN pfnGetPMRFactoryLock; - - /*! Callback function pointer, see ::PFN_RELEASE_PMR_FACTORY_LOCK_FN */ - PFN_RELEASE_PMR_FACTORY_LOCK_FN pfnReleasePMRFactoryLock; -}; - -/*! PMR factory callback table. - */ -typedef struct _PMR_IMPL_FUNCTAB_ PMR_IMPL_FUNCTAB; - -#endif /* SRVSRV_PMR_IMPL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pmr_os.c b/drivers/gpu/drm/img-rogue/1.17/pmr_os.c deleted file mode 100644 index d505760585bdb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pmr_os.c +++ /dev/null @@ -1,634 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linux OS PMR functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) -#include -#include -#endif - -#include "img_defs.h" -#include "pvr_debug.h" -#include "allocmem.h" -#include "devicemem_server_utils.h" -#include "pmr.h" -#include "pmr_os.h" - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) -#include "mmap_stats.h" -#endif - -#include "kernel_compatibility.h" - -/* - * x86_32: - * Use vm_insert_page because remap_pfn_range has issues when mapping HIGHMEM - * pages with default memory attributes; these HIGHMEM pages are skipped in - * set_pages_array_[uc,wc] during allocation; see reserve_pfn_range(). - * Also vm_insert_page is faster. - * - * x86_64: - * Use vm_insert_page because it is faster. - * - * Other platforms: - * Use remap_pfn_range by default because it does not issue a cache flush. - * It is known that ARM32 benefits from this. When other platforms become - * available it has to be investigated if this assumption holds for them as well. - * - * Since vm_insert_page does more precise memory accounting we have the build - * flag PVR_MMAP_USE_VM_INSERT that forces its use. This is useful as a debug - * feature. - * - */ -#if defined(CONFIG_X86) || defined(PVR_MMAP_USE_VM_INSERT) -#define PMR_OS_USE_VM_INSERT_PAGE 1 -#endif - -static void MMapPMROpen(struct vm_area_struct *ps_vma) -{ - PMR *psPMR = ps_vma->vm_private_data; - - /* Our VM flags should ensure this function never gets called */ - PVR_DPF((PVR_DBG_WARNING, - "%s: Unexpected mmap open call, this is probably an application bug.", - __func__)); - PVR_DPF((PVR_DBG_WARNING, - "%s: vma struct: 0x%p, vAddr: %#lX, length: %#lX, PMR pointer: 0x%p", - __func__, - ps_vma, - ps_vma->vm_start, - ps_vma->vm_end - ps_vma->vm_start, - psPMR)); - - /* In case we get called anyway let's do things right by increasing the refcount and - * locking down the physical addresses. - */ - PMRRefPMR(psPMR); - - if (PMRLockSysPhysAddresses(psPMR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Could not lock down physical addresses, aborting.", __func__)); - PMRUnrefPMR(psPMR); - } - else - { - /* MMapPMROpen() is call when a process is forked, but only if - * mappings are to be inherited so increment mapping count of the - * PMR to prevent its layout cannot be changed (if sparse). - */ - PMRCpuMapCountIncr(psPMR); - } -} - -static void MMapPMRClose(struct vm_area_struct *ps_vma) -{ - PMR *psPMR = ps_vma->vm_private_data; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - { - uintptr_t vAddr = ps_vma->vm_start; - - while (vAddr < ps_vma->vm_end) - { - /* USER MAPPING */ - PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, - (IMG_UINT64)vAddr, - OSGetCurrentClientProcessIDKM()); - vAddr += PAGE_SIZE; - } - } -#else - PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, - ps_vma->vm_end - ps_vma->vm_start, - OSGetCurrentClientProcessIDKM()); -#endif -#endif - - PMRUnlockSysPhysAddresses(psPMR); - /* Decrement the mapping count before Unref of PMR (as Unref could destroy the PMR) */ - PMRCpuMapCountDecr(psPMR); - PMRUnrefPMR(psPMR); -} - -/* - * This vma operation is used to read data from mmap regions. It is called - * by access_process_vm, which is called to handle PTRACE_PEEKDATA ptrace - * requests and reads from /proc//mem. - */ -static int MMapVAccess(struct vm_area_struct *ps_vma, unsigned long addr, - void *buf, int len, int write) -{ - PMR *psPMR = ps_vma->vm_private_data; - unsigned long ulOffset = addr - ps_vma->vm_start; - size_t uiBytesCopied; - PVRSRV_ERROR eError; - int iRetVal = -EINVAL; - - if (write) - { - eError = PMR_WriteBytes(psPMR, - (IMG_DEVMEM_OFFSET_T) ulOffset, - buf, - len, - &uiBytesCopied); - } - else - { - eError = PMR_ReadBytes(psPMR, - (IMG_DEVMEM_OFFSET_T) ulOffset, - buf, - len, - &uiBytesCopied); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error from %s (%d)", - __func__, - write ? "PMR_WriteBytes" : "PMR_ReadBytes", - eError)); - } - else - { - iRetVal = uiBytesCopied; - } - - return iRetVal; -} - -static const struct vm_operations_struct gsMMapOps = -{ - .open = &MMapPMROpen, - .close = &MMapPMRClose, - .access = MMapVAccess, -}; - -static INLINE int _OSMMapPMR(PVRSRV_DEVICE_NODE *psDevNode, - struct vm_area_struct *ps_vma, - IMG_DEVMEM_OFFSET_T uiOffset, - IMG_CPU_PHYADDR *psCpuPAddr, - IMG_UINT32 uiLog2PageSize, - IMG_BOOL bUseVMInsertPage, - IMG_BOOL bUseMixedMap) -{ - IMG_INT32 iStatus; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - pfn_t sPFN; -#else - unsigned long uiPFN; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN = phys_to_pfn_t(psCpuPAddr->uiAddr, 0); -#else - uiPFN = psCpuPAddr->uiAddr >> PAGE_SHIFT; - PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == psCpuPAddr->uiAddr); -#endif - - /* - * vm_insert_page() allows insertion of individual pages into user - * VMA space _only_ if page is a order-zero allocated page - */ - if (bUseVMInsertPage) - { - if (bUseMixedMap) - { - /* - * This path is just for debugging. It should be - * equivalent to the remap_pfn_range() path. - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - vm_fault_t vmf; - - vmf = vmf_insert_mixed(ps_vma, - ps_vma->vm_start + uiOffset, - sPFN); - if (vmf & VM_FAULT_ERROR) - { - iStatus = vm_fault_to_errno(vmf, 0); - } - else - { - iStatus = 0; - } -#else - iStatus = vm_insert_mixed(ps_vma, - ps_vma->vm_start + uiOffset, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN); -#else - uiPFN); -#endif -#endif - } - else - { - /* Since kernel 3.7 this sets VM_MIXEDMAP internally */ - iStatus = vm_insert_page(ps_vma, - ps_vma->vm_start + uiOffset, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - pfn_t_to_page(sPFN)); -#else - pfn_to_page(uiPFN)); -#endif - } - } - else - { - /* - NOTE: Regarding absence of dma_mmap_coherent() in _OSMMapPMR() - - The current services mmap model maps in a PMR's full-length size - into the user VMA & applies any user specified offset to the kernel - returned zero-offset based VA in services client; this essentially - means services server ignores ps_vma->vm_pgoff (this houses hPMR) - during a mmap call. - - Furthermore, during a DMA/CMA memory allocation, multiple order-n - pages are used to satisfy an allocation request due to DMA/CMA - framework rounding-up allocation size to next power-of-two which - can lead to wasted memory (so we don't allocate using single call). - - The combination of the above two issues mean that we cannot use the - dma_mmap_coherent() for a number of reasons outlined below: - - - Services mmap semantics does not fit with dma_mmap_coherent() - which requires proper ps_vma->vm_pgoff; seeing this houses a - hPMR handle value, calls into dma_mmap_coherent() fails. This - could be avoided by forcing ps_vma->vm_pgoff to zero but the - ps_vma->vm_pgoff is applied to DMA bus address PFN and not - user VMA which is always mapped at ps_vma->vm_start. - - - As multiple order-n pages are used for DMA/CMA allocations, a - single dma_mmap_coherent() call with a vma->vm_pgoff set to - zero cannot (maybe) be used because there is no guarantee that - all of the multiple order-n pages in the PMR are physically - contiguous from the first entry to the last. Whilst this is - highly likely to be the case, there is no guarantee that it - will be so we cannot depend on this being the case. - - The solution is to manually mmap DMA/CMA pages into user VMA - using remap_pfn_range() directly. Furthermore, accounting is - always compromised for DMA/CMA allocations. - */ - size_t uiNumContiguousBytes = 1ULL << uiLog2PageSize; - - iStatus = remap_pfn_range(ps_vma, - ps_vma->vm_start + uiOffset, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - pfn_t_to_pfn(sPFN), -#else - uiPFN, -#endif - uiNumContiguousBytes, - ps_vma->vm_page_prot); - } - - return iStatus; -} - -PVRSRV_ERROR -OSMMapPMRGeneric(PMR *psPMR, PMR_MMAP_DATA pOSMMapData) -{ - struct vm_area_struct *ps_vma = pOSMMapData; - PVRSRV_DEVICE_NODE *psDevNode = PMR_DeviceNode(psPMR); - PVRSRV_ERROR eError; - size_t uiLength; - IMG_INT32 iStatus; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_UINT32 ui32CPUCacheFlags; - pgprot_t sPageProt; - IMG_CPU_PHYADDR asCpuPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC]; - IMG_UINT32 uiOffsetIdx; - IMG_UINT32 uiNumOfPFNs; - IMG_UINT32 uiLog2PageSize; - IMG_CPU_PHYADDR *psCpuPAddr; - IMG_BOOL *pbValid; - IMG_BOOL bUseMixedMap = IMG_FALSE; - IMG_BOOL bUseVMInsertPage = IMG_FALSE; - IMG_DEVMEM_SIZE_T uiPmrVirtualSize; - - /* if writeable but not shared mapping is requested then fail */ - PVR_RETURN_IF_INVALID_PARAM(((ps_vma->vm_flags & VM_WRITE) == 0) || - ((ps_vma->vm_flags & VM_SHARED) != 0)); - - uiLength = ps_vma->vm_end - ps_vma->vm_start; - - PMR_LogicalSize(psPMR, &uiPmrVirtualSize); - - /* Check early if the requested mapping size doesn't exceed the virtual - * PMR size. */ - if (uiPmrVirtualSize < uiLength) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_BAD_MAPPING, e0); - } - - uiLog2PageSize = PMR_GetLog2Contiguity(psPMR); - - /* Check the number of PFNs to be mapped is valid. */ - uiNumOfPFNs = uiLength >> uiLog2PageSize; - if (uiNumOfPFNs == 0) - { - PVR_LOG_VA(PVR_DBG_ERROR, - "uiLength is invalid. Must be >= %u.", - 1 << uiLog2PageSize); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_BAD_MAPPING, e0); - } - - /* - * Take a reference on the PMR so that it can't be freed while mapped - * into the user process. - */ - PMRRefPMR(psPMR); - - eError = PMRLockSysPhysAddresses(psPMR); - if (eError != PVRSRV_OK) - { - goto ErrUnrefPMR; - } - - /* Increment mapping count of the PMR so that its layout cannot be - * changed (if sparse). - */ - PMRLockPMR(psPMR); - - PMRCpuMapCountIncr(psPMR); - sPageProt = vm_get_page_prot(ps_vma->vm_flags); - - eError = DevmemCPUCacheMode(psDevNode, - PMR_Flags(psPMR), - &ui32CPUCacheFlags); - if (eError != PVRSRV_OK) - { - goto e1; - } - - switch (ui32CPUCacheFlags) - { - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: - sPageProt = pgprot_noncached(sPageProt); - break; - - case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC: - sPageProt = pgprot_writecombine(sPageProt); - break; - - case PVRSRV_MEMALLOCFLAG_CPU_CACHED: - { -/* Do not set to write-combine for plato */ -#if !defined(PLATO_MEMORY_CONFIG) - PHYS_HEAP *psPhysHeap = PMR_PhysHeap(psPMR); - - if (PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_LMA) - sPageProt = pgprot_writecombine(sPageProt); -#endif - break; - } - - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e1; - } - ps_vma->vm_page_prot = sPageProt; - - vm_flags_set(ps_vma, VM_IO); - - /* Don't include the mapping in core dumps */ - vm_flags_set(ps_vma, VM_DONTDUMP); - - /* - * Disable mremap because our nopage handler assumes all - * page requests have already been validated. - */ - vm_flags_set(ps_vma, VM_DONTEXPAND); - - /* Don't allow mapping to be inherited across a process fork */ - vm_flags_set(ps_vma, VM_DONTCOPY); - -#if defined(PMR_OS_USE_VM_INSERT_PAGE) - /* Is this mmap targeting non order-zero pages or does it use pfn mappings? - * If yes, don't use vm_insert_page */ - bUseVMInsertPage = (uiLog2PageSize == PAGE_SHIFT) && (PMR_GetType(psPMR) != PMR_TYPE_EXTMEM); -#endif - - /* Can we use stack allocations */ - if (uiNumOfPFNs > PMR_MAX_TRANSLATION_STACK_ALLOC) - { - psCpuPAddr = OSAllocMem(uiNumOfPFNs * sizeof(*psCpuPAddr)); - if (psCpuPAddr == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e1; - } - - /* Should allocation fail, clean-up here before exiting */ - pbValid = OSAllocMem(uiNumOfPFNs * sizeof(*pbValid)); - if (pbValid == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - OSFreeMem(psCpuPAddr); - goto e2; - } - } - else - { - psCpuPAddr = asCpuPAddr; - pbValid = abValid; - } - - /* Obtain map range pfns */ - eError = PMR_CpuPhysAddr(psPMR, - uiLog2PageSize, - uiNumOfPFNs, - 0, - psCpuPAddr, - pbValid); - if (eError != PVRSRV_OK) - { - goto e3; - } - - /* - * Scan the map range for pfns without struct page* handling. If - * we find one, this is a mixed map, and we can't use vm_insert_page() - * NOTE: vm_insert_page() allows insertion of individual pages into user - * VMA space _only_ if said page is an order-zero allocated page. - */ - if (bUseVMInsertPage) - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - pfn_t sPFN; -#else - unsigned long uiPFN; -#endif - - for (uiOffsetIdx = 0; uiOffsetIdx < uiNumOfPFNs; ++uiOffsetIdx) - { - if (pbValid[uiOffsetIdx]) - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) - sPFN = phys_to_pfn_t(psCpuPAddr[uiOffsetIdx].uiAddr, 0); - - if (!pfn_t_valid(sPFN) || page_count(pfn_t_to_page(sPFN)) == 0) -#else - uiPFN = psCpuPAddr[uiOffsetIdx].uiAddr >> PAGE_SHIFT; - PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == psCpuPAddr[uiOffsetIdx].uiAddr); - - if (!pfn_valid(uiPFN) || page_count(pfn_to_page(uiPFN)) == 0) -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */ - { - bUseMixedMap = IMG_TRUE; - break; - } - } - } - - if (bUseMixedMap) - { - vm_flags_set(ps_vma, VM_MIXEDMAP); - } - } - else - { - vm_flags_set(ps_vma, VM_PFNMAP); - } - - /* For each PMR page-size contiguous bytes, map page(s) into user VMA */ - for (uiOffset = 0; uiOffset < uiLength; uiOffset += 1ULL<> uiLog2PageSize; - /* - * Only map in pages that are valid, any that aren't will be - * picked up by the nopage handler which will return a zeroed - * page for us. - */ - if (pbValid[uiOffsetIdx]) - { - iStatus = _OSMMapPMR(psDevNode, - ps_vma, - uiOffset, - &psCpuPAddr[uiOffsetIdx], - uiLog2PageSize, - bUseVMInsertPage, - bUseMixedMap); - if (iStatus) - { - /* Failure error code doesn't get propagated */ - eError = PVRSRV_ERROR_PMR_CPU_PAGE_MAP_FAILED; - PVR_ASSERT(0); - goto e3; - } - } -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && defined(PVRSRV_ENABLE_MEMORY_STATS) -#define PMR_OS_BAD_CPUADDR 0x0BAD0BAD - { - IMG_CPU_PHYADDR sPAddr; - sPAddr.uiAddr = pbValid[uiOffsetIdx] ? - psCpuPAddr[uiOffsetIdx].uiAddr : - IMG_CAST_TO_CPUPHYADDR_UINT(PMR_OS_BAD_CPUADDR); - - PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, - (void*)(uintptr_t)(ps_vma->vm_start + uiOffset), - sPAddr, - 1<vm_private_data = psPMR; - - /* Install open and close handlers for ref-counting */ - ps_vma->vm_ops = &gsMMapOps; - -#if defined(PVRSRV_ENABLE_LINUX_MMAP_STATS) - /* record the stats */ - MMapStatsAddOrUpdatePMR(psPMR, uiLength); -#endif - - PMRUnlockPMR(psPMR); - return PVRSRV_OK; - - /* Error exit paths follow */ -e3: - if (pbValid != abValid) - { - OSFreeMem(pbValid); - } -e2: - if (psCpuPAddr != asCpuPAddr) - { - OSFreeMem(psCpuPAddr); - } -e1: - PMRCpuMapCountDecr(psPMR); - PMRUnlockPMR(psPMR); - PMRUnlockSysPhysAddresses(psPMR); -ErrUnrefPMR: - PMRUnrefPMR(psPMR); -e0: - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pmr_os.h b/drivers/gpu/drm/img-rogue/1.17/pmr_os.h deleted file mode 100644 index 7b4a2117091c1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pmr_os.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title OS PMR functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description OS specific PMR functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PMR_OS_H) -#define PMR_OS_H - -#include "pmr_impl.h" - -/*************************************************************************/ /*! -@Function OSMMapPMRGeneric -@Description Implements a generic PMR mapping function, which is used - to CPU map a PMR where the PMR does not have a mapping - function defined by the creating PMR factory. -@Input psPMR the PMR to be mapped -@Output pOSMMapData pointer to any private data - needed by the generic mapping function -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR -OSMMapPMRGeneric(PMR *psPMR, PMR_MMAP_DATA pOSMMapData); - -#endif /* !defined(PMR_OS_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/power.c b/drivers/gpu/drm/img-rogue/1.17/power.c deleted file mode 100644 index 5ad6695fc5740..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/power.c +++ /dev/null @@ -1,929 +0,0 @@ -/*************************************************************************/ /*! -@File power.c -@Title Power management functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main APIs for power management functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pdump_km.h" -#include "allocmem.h" -#include "osfunc.h" - -#include "lock.h" -#include "pvrsrv.h" -#include "pvr_debug.h" -#include "process_stats.h" - - -struct _PVRSRV_POWER_DEV_TAG_ -{ - PFN_PRE_POWER pfnDevicePrePower; - PFN_POST_POWER pfnDevicePostPower; - PFN_SYS_PRE_POWER pfnSystemPrePower; - PFN_SYS_POST_POWER pfnSystemPostPower; - PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange; - PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange; - PFN_FORCED_IDLE_REQUEST pfnForcedIdleRequest; - PFN_FORCED_IDLE_CANCEL_REQUEST pfnForcedIdleCancelRequest; - PFN_GPU_UNITS_POWER_CHANGE pfnGPUUnitsPowerChange; - IMG_HANDLE hSysData; - IMG_HANDLE hDevCookie; - PVRSRV_DEV_POWER_STATE eDefaultPowerState; - ATOMIC_T eCurrentPowerState; -}; - -/*! - Typedef for a pointer to a function that will be called for re-acquiring - device powerlock after releasing it temporarily for some timeout period - in function PVRSRVDeviceIdleRequestKM - */ -typedef PVRSRV_ERROR (*PFN_POWER_LOCK_ACQUIRE) (PPVRSRV_DEVICE_NODE psDevNode); - -static inline IMG_UINT64 PVRSRVProcessStatsGetTimeNs(void) -{ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - return OSClockns64(); -#else - return 0; -#endif -} - -static inline IMG_UINT64 PVRSRVProcessStatsGetTimeUs(void) -{ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - return OSClockus(); -#else - return 0; -#endif -} - -/*! -****************************************************************************** - - @Function _IsSystemStatePowered - - @Description Tests whether a given system state represents powered-up. - - @Input eSystemPowerState : a system power state - - @Return IMG_BOOL - -******************************************************************************/ -static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState) -{ - return (eSystemPowerState == PVRSRV_SYS_POWER_STATE_ON); -} - -/* We don't expect PID=0 to acquire device power-lock */ -#define PWR_LOCK_OWNER_PID_CLR_VAL 0 - -PVRSRV_ERROR PVRSRVPowerLockInit(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - PVRSRV_ERROR eError; - - eError = OSLockCreate(&psDeviceNode->hPowerLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate"); - - psDeviceNode->uiPwrLockOwnerPID = PWR_LOCK_OWNER_PID_CLR_VAL; - return PVRSRV_OK; -} - -void PVRSRVPowerLockDeInit(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - psDeviceNode->uiPwrLockOwnerPID = PWR_LOCK_OWNER_PID_CLR_VAL; - OSLockDestroy(psDeviceNode->hPowerLock); -} - -IMG_BOOL PVRSRVPwrLockIsLockedByMe(PCPVRSRV_DEVICE_NODE psDeviceNode) -{ - return OSLockIsLocked(psDeviceNode->hPowerLock) && - OSGetCurrentClientProcessIDKM() == psDeviceNode->uiPwrLockOwnerPID; -} - -PVRSRV_ERROR PVRSRVPowerLock(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - OSLockAcquire(psDeviceNode->hPowerLock); - - /* Only allow to take powerlock when the system power is on */ - if (_IsSystemStatePowered(psDeviceNode->eCurrentSysPowerState)) - { - psDeviceNode->uiPwrLockOwnerPID = OSGetCurrentClientProcessIDKM(); - return PVRSRV_OK; - } - - OSLockRelease(psDeviceNode->hPowerLock); - - return PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF; -} - -PVRSRV_ERROR PVRSRVPowerTryLock(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - if (!(OSTryLockAcquire(psDeviceNode->hPowerLock))) - { - return PVRSRV_ERROR_RETRY; - } - - /* Only allow to take powerlock when the system power is on */ - if (_IsSystemStatePowered(psDeviceNode->eCurrentSysPowerState)) - { - psDeviceNode->uiPwrLockOwnerPID = OSGetCurrentClientProcessIDKM(); - - /* System is powered ON, return OK */ - return PVRSRV_OK; - } - else - { - /* System is powered OFF, release the lock and return error */ - OSLockRelease(psDeviceNode->hPowerLock); - return PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF; - } -} - -/*! -****************************************************************************** - - @Function _PVRSRVForcedPowerLock - - @Description Obtain the mutex for power transitions regardless of system - power state - - @Return Always returns PVRSRV_OK. Function prototype required same as - PFN_POWER_LOCK_ACQUIRE - -******************************************************************************/ -static PVRSRV_ERROR _PVRSRVForcedPowerLock(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - OSLockAcquire(psDeviceNode->hPowerLock); - psDeviceNode->uiPwrLockOwnerPID = OSGetCurrentClientProcessIDKM(); - - return PVRSRV_OK; -} - -void PVRSRVPowerUnlock(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - PVR_ASSERT(PVRSRVPwrLockIsLockedByMe(psDeviceNode)); - - /* Reset uiPwrLockOwnerPID before releasing lock */ - psDeviceNode->uiPwrLockOwnerPID = PWR_LOCK_OWNER_PID_CLR_VAL; - OSLockRelease(psDeviceNode->hPowerLock); -} - -IMG_BOOL PVRSRVDeviceIsDefaultStateOFF(PVRSRV_POWER_DEV *psPowerDevice) -{ - return (psPowerDevice->eDefaultPowerState == PVRSRV_DEV_POWER_STATE_OFF); -} - -PVRSRV_ERROR PVRSRVSetDeviceDefaultPowerState(PCPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_DEV_POWER_STATE eNewPowerState) -{ - PVRSRV_POWER_DEV *psPowerDevice; - - psPowerDevice = psDeviceNode->psPowerDev; - if (psPowerDevice == NULL) - { - return PVRSRV_ERROR_INVALID_DEVICE; - } - - psPowerDevice->eDefaultPowerState = eNewPowerState; - - return PVRSRV_OK; -} - -/* - @Input pfnPowerLockAcquire : Function to re-acquire power-lock in-case - it was necessary to release it. -*/ -static PVRSRV_ERROR _PVRSRVDeviceIdleRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode, - PFN_SYS_DEV_IS_DEFAULT_STATE_OFF pfnIsDefaultStateOff, - IMG_BOOL bDeviceOffPermitted, - PFN_POWER_LOCK_ACQUIRE pfnPowerLockAcquire) -{ - PVRSRV_POWER_DEV *psPowerDev = psDeviceNode->psPowerDev; - PVRSRV_ERROR eError; - - if ((psPowerDev && psPowerDev->pfnForcedIdleRequest) && - (!pfnIsDefaultStateOff || pfnIsDefaultStateOff(psPowerDev))) - { - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = psPowerDev->pfnForcedIdleRequest(psPowerDev->hDevCookie, - bDeviceOffPermitted); - if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED) - { - PVRSRV_ERROR eErrPwrLockAcq; - /* FW denied idle request */ - PVRSRVPowerUnlock(psDeviceNode); - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - - eErrPwrLockAcq = pfnPowerLockAcquire(psDeviceNode); - if (eErrPwrLockAcq != PVRSRV_OK) - { - /* We only understand PVRSRV_ERROR_RETRY, so assert on others. - * Moreover, we've ended-up releasing the power-lock which was - * originally "held" by caller before calling this function - - * since this needs vigilant handling at call-site, we pass - * back an explicit error, for caller(s) to "avoid" calling - * PVRSRVPowerUnlock */ - PVR_ASSERT(eErrPwrLockAcq == PVRSRV_ERROR_RETRY); - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to re-acquire power-lock " - "(%s) after releasing it for a time-out", - __func__, PVRSRVGetErrorString(eErrPwrLockAcq))); - return PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED; - } - } - else - { - /* idle request successful or some other error occurred, return */ - break; - } - } END_LOOP_UNTIL_TIMEOUT(); - } - else - { - return PVRSRV_OK; - } - - return eError; -} - -/* - * Wrapper function helps limiting calling complexity of supplying additional - * PFN_POWER_LOCK_ACQUIRE argument (required by _PVRSRVDeviceIdleRequestKM) - */ -inline PVRSRV_ERROR PVRSRVDeviceIdleRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode, - PFN_SYS_DEV_IS_DEFAULT_STATE_OFF pfnIsDefaultStateOff, - IMG_BOOL bDeviceOffPermitted) -{ - return _PVRSRVDeviceIdleRequestKM(psDeviceNode, - pfnIsDefaultStateOff, - bDeviceOffPermitted, - PVRSRVPowerLock); -} - -PVRSRV_ERROR PVRSRVDeviceIdleCancelRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - PVRSRV_POWER_DEV *psPowerDev = psDeviceNode->psPowerDev; - - if (psPowerDev && psPowerDev->pfnForcedIdleCancelRequest) - { - return psPowerDev->pfnForcedIdleCancelRequest(psPowerDev->hDevCookie); - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVDevicePrePowerStateKM - - @Description - - Perform device-specific processing required before a power transition - - @Input psPowerDevice : Power device - @Input eNewPowerState : New power state - @Input ePwrFlags : Power state change flags - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(PVRSRV_POWER_DEV *psPowerDevice, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_DEV_POWER_STATE eCurrentPowerState; - IMG_UINT64 ui64SysTimer1 = 0; - IMG_UINT64 ui64SysTimer2 = 0; - IMG_UINT64 ui64DevTimer1 = 0; - IMG_UINT64 ui64DevTimer2 = 0; - PVRSRV_ERROR eError; - - PVR_ASSERT(eNewPowerState != PVRSRV_DEV_POWER_STATE_DEFAULT); - - eCurrentPowerState = OSAtomicRead(&psPowerDevice->eCurrentPowerState); - - if (psPowerDevice->pfnDevicePrePower != NULL) - { - ui64DevTimer1 = PVRSRVProcessStatsGetTimeNs(); - - /* Call the device's power callback. */ - eError = psPowerDevice->pfnDevicePrePower(psPowerDevice->hDevCookie, - eNewPowerState, - eCurrentPowerState, - BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED)); - - ui64DevTimer2 = PVRSRVProcessStatsGetTimeNs(); - - PVR_RETURN_IF_ERROR(eError); - } - - /* Do any required system-layer processing. */ - if (psPowerDevice->pfnSystemPrePower != NULL) - { - ui64SysTimer1 = PVRSRVProcessStatsGetTimeNs(); - - eError = psPowerDevice->pfnSystemPrePower(psPowerDevice->hSysData, - (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON) ? - PVRSRV_SYS_POWER_STATE_ON : - PVRSRV_SYS_POWER_STATE_OFF, - (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) ? - PVRSRV_SYS_POWER_STATE_ON : - PVRSRV_SYS_POWER_STATE_OFF, - ePwrFlags); - - ui64SysTimer2 = PVRSRVProcessStatsGetTimeNs(); - - PVR_RETURN_IF_ERROR(eError); - } - - InsertPowerTimeStatistic(ui64SysTimer1, ui64SysTimer2, - ui64DevTimer1, ui64DevTimer2, - BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED), - eNewPowerState == PVRSRV_DEV_POWER_STATE_ON, - IMG_TRUE); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVDevicePostPowerStateKM - - @Description - - Perform device-specific processing required after a power transition - - @Input psPowerDevice : Power device - @Input eNewPowerState : New power state - @Input ePwrFlags : Power state change flags - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(PVRSRV_POWER_DEV *psPowerDevice, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_DEV_POWER_STATE eCurrentPowerState; - IMG_UINT64 ui64SysTimer1 = 0; - IMG_UINT64 ui64SysTimer2 = 0; - IMG_UINT64 ui64DevTimer1 = 0; - IMG_UINT64 ui64DevTimer2 = 0; - PVRSRV_ERROR eError; - - PVR_ASSERT(eNewPowerState != PVRSRV_DEV_POWER_STATE_DEFAULT); - - eCurrentPowerState = OSAtomicRead(&psPowerDevice->eCurrentPowerState); - - /* Do any required system-layer processing. */ - if (psPowerDevice->pfnSystemPostPower != NULL) - { - ui64SysTimer1 = PVRSRVProcessStatsGetTimeNs(); - - eError = psPowerDevice->pfnSystemPostPower(psPowerDevice->hSysData, - (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON) ? - PVRSRV_SYS_POWER_STATE_ON : - PVRSRV_SYS_POWER_STATE_OFF, - (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) ? - PVRSRV_SYS_POWER_STATE_ON : - PVRSRV_SYS_POWER_STATE_OFF, - ePwrFlags); - - ui64SysTimer2 = PVRSRVProcessStatsGetTimeNs(); - - PVR_RETURN_IF_ERROR(eError); - } - - if (psPowerDevice->pfnDevicePostPower != NULL) - { - ui64DevTimer1 = PVRSRVProcessStatsGetTimeNs(); - - /* Call the device's power callback. */ - eError = psPowerDevice->pfnDevicePostPower(psPowerDevice->hDevCookie, - eNewPowerState, - eCurrentPowerState, - BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED)); - - ui64DevTimer2 = PVRSRVProcessStatsGetTimeNs(); - - PVR_RETURN_IF_ERROR(eError); - } - - InsertPowerTimeStatistic(ui64SysTimer1, ui64SysTimer2, - ui64DevTimer1, ui64DevTimer2, - BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED), - eNewPowerState == PVRSRV_DEV_POWER_STATE_ON, - IMG_FALSE); - - OSAtomicWrite(&psPowerDevice->eCurrentPowerState, eNewPowerState); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_ERROR eError; - PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_POWER_DEV *psPowerDevice; - - psPowerDevice = psDeviceNode->psPowerDev; - if (!psPowerDevice) - { - return PVRSRV_OK; - } - - if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) - { - eNewPowerState = psPowerDevice->eDefaultPowerState; - } - - if (OSAtomicRead(&psPowerDevice->eCurrentPowerState) != eNewPowerState) - { - eError = PVRSRVDevicePrePowerStateKM(psPowerDevice, - eNewPowerState, - ePwrFlags); - PVR_GOTO_IF_ERROR(eError, ErrorExit); - - eError = PVRSRVDevicePostPowerStateKM(psPowerDevice, - eNewPowerState, - ePwrFlags); - PVR_GOTO_IF_ERROR(eError, ErrorExit); - - /* Signal Device Watchdog Thread about power mode change. */ - if (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON) - { - psPVRSRVData->ui32DevicesWatchdogPwrTrans++; -#if !defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - if (psPVRSRVData->ui32DevicesWatchdogTimeout == DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT) -#endif - { - eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - } -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - else if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) - { - /* signal watchdog thread and give it a chance to switch to - * longer / infinite wait time */ - eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } -#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - } - - return PVRSRV_OK; - -ErrorExit: - - if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Transition to %d was denied, Flags=0x%08x", - __func__, eNewPowerState, ePwrFlags)); - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Transition to %d FAILED (%s)", - __func__, eNewPowerState, PVRSRVGetErrorString(eError))); - } - - return eError; -} - -PVRSRV_ERROR PVRSRVSetDeviceSystemPowerState(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_SYS_POWER_STATE eNewSysPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_ERROR eError; - IMG_UINT uiStage = 0; - - PVRSRV_DEV_POWER_STATE eNewDevicePowerState = - _IsSystemStatePowered(eNewSysPowerState)? PVRSRV_DEV_POWER_STATE_DEFAULT : PVRSRV_DEV_POWER_STATE_OFF; - - /* If setting devices to default state, force idle all devices whose default state is off */ - PFN_SYS_DEV_IS_DEFAULT_STATE_OFF pfnIsDefaultStateOff = - (eNewDevicePowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? PVRSRVDeviceIsDefaultStateOFF : NULL; - - /* require a proper power state */ - if (eNewSysPowerState == PVRSRV_SYS_POWER_STATE_Unspecified) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Prevent simultaneous SetPowerStateKM calls */ - _PVRSRVForcedPowerLock(psDeviceNode); - - /* no power transition requested, so do nothing */ - if (eNewSysPowerState == psDeviceNode->eCurrentSysPowerState) - { - PVRSRVPowerUnlock(psDeviceNode); - return PVRSRV_OK; - } - - eError = _PVRSRVDeviceIdleRequestKM(psDeviceNode, pfnIsDefaultStateOff, - IMG_TRUE, _PVRSRVForcedPowerLock); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "_PVRSRVDeviceIdleRequestKM"); - uiStage++; - goto ErrorExit; - } - - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, eNewDevicePowerState, - ePwrFlags | PVRSRV_POWER_FLAGS_FORCED); - if (eError != PVRSRV_OK) - { - uiStage++; - goto ErrorExit; - } - - psDeviceNode->eCurrentSysPowerState = eNewSysPowerState; - - PVRSRVPowerUnlock(psDeviceNode); - - return PVRSRV_OK; - -ErrorExit: - PVRSRVPowerUnlock(psDeviceNode); - - PVR_DPF((PVR_DBG_ERROR, - "%s: Transition from %d to %d FAILED (%s) at stage %u. Dumping debug info.", - __func__, psDeviceNode->eCurrentSysPowerState, eNewSysPowerState, - PVRSRVGetErrorString(eError), uiStage)); - - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - - return eError; -} - -PVRSRV_ERROR PVRSRVSetSystemPowerState(PVRSRV_DEVICE_CONFIG *psDevConfig, - PVRSRV_SYS_POWER_STATE eNewSysPowerState) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDevNode = psDevConfig->psDevNode; - PVRSRV_SYS_POWER_STATE eCurrentSysPowerState; - - if (psDevNode != NULL) - { - eCurrentSysPowerState = psDevNode->eCurrentSysPowerState; - } - else - { - /* assume power is off if no device node */ - eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_OFF; - } - - /* no power transition requested, so do nothing */ - if (eNewSysPowerState == eCurrentSysPowerState) - { - return PVRSRV_OK; - } - - if (psDevConfig->pfnPrePowerState != NULL) - { - eError = psDevConfig->pfnPrePowerState(psDevConfig->hSysData, - eNewSysPowerState, - eCurrentSysPowerState, - PVRSRV_POWER_FLAGS_FORCED); - - PVR_RETURN_IF_ERROR(eError); - } - - if (psDevConfig->pfnPostPowerState != NULL) - { - eError = psDevConfig->pfnPostPowerState(psDevConfig->hSysData, - eNewSysPowerState, - eCurrentSysPowerState, - PVRSRV_POWER_FLAGS_FORCED); - - PVR_RETURN_IF_ERROR(eError); - } - - if (psDevNode != NULL) - { - psDevNode->eCurrentSysPowerState = eNewSysPowerState; - } - - return PVRSRV_OK; -} - -void PVRSRVSetPowerCallbacks(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_POWER_DEV *psPowerDevice, - PFN_PRE_POWER pfnDevicePrePower, - PFN_POST_POWER pfnDevicePostPower, - PFN_SYS_PRE_POWER pfnSystemPrePower, - PFN_SYS_POST_POWER pfnSystemPostPower, - PFN_FORCED_IDLE_REQUEST pfnForcedIdleRequest, - PFN_FORCED_IDLE_CANCEL_REQUEST pfnForcedIdleCancelRequest) -{ - if (psPowerDevice != NULL) - { - if (PVRSRV_VZ_MODE_IS(GUEST) || (psDeviceNode->bAutoVzFwIsUp)) - { - psPowerDevice->pfnSystemPrePower = NULL; - psPowerDevice->pfnSystemPostPower = NULL; - } - else - { - psPowerDevice->pfnSystemPrePower = pfnSystemPrePower; - psPowerDevice->pfnSystemPostPower = pfnSystemPostPower; - } - - psPowerDevice->pfnDevicePrePower = pfnDevicePrePower; - psPowerDevice->pfnDevicePostPower = pfnDevicePostPower; - psPowerDevice->pfnForcedIdleRequest = pfnForcedIdleRequest; - psPowerDevice->pfnForcedIdleCancelRequest = pfnForcedIdleCancelRequest; - } -} - -PVRSRV_ERROR PVRSRVRegisterPowerDevice(PPVRSRV_DEVICE_NODE psDeviceNode, - PFN_PRE_POWER pfnDevicePrePower, - PFN_POST_POWER pfnDevicePostPower, - PFN_SYS_PRE_POWER pfnSystemPrePower, - PFN_SYS_POST_POWER pfnSystemPostPower, - PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, - PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, - PFN_FORCED_IDLE_REQUEST pfnForcedIdleRequest, - PFN_FORCED_IDLE_CANCEL_REQUEST pfnForcedIdleCancelRequest, - PFN_GPU_UNITS_POWER_CHANGE pfnGPUUnitsPowerChange, - IMG_HANDLE hDevCookie, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_DEV_POWER_STATE eDefaultPowerState) -{ - PVRSRV_POWER_DEV *psPowerDevice; - - PVR_ASSERT(!psDeviceNode->psPowerDev); - - PVR_ASSERT(eCurrentPowerState != PVRSRV_DEV_POWER_STATE_DEFAULT); - PVR_ASSERT(eDefaultPowerState != PVRSRV_DEV_POWER_STATE_DEFAULT); - - psPowerDevice = OSAllocMem(sizeof(PVRSRV_POWER_DEV)); - PVR_LOG_RETURN_IF_NOMEM(psPowerDevice, "psPowerDevice"); - - /* setup device for power manager */ - PVRSRVSetPowerCallbacks(psDeviceNode, - psPowerDevice, - pfnDevicePrePower, - pfnDevicePostPower, - pfnSystemPrePower, - pfnSystemPostPower, - pfnForcedIdleRequest, - pfnForcedIdleCancelRequest); - - psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange; - psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange; - psPowerDevice->pfnGPUUnitsPowerChange = pfnGPUUnitsPowerChange; - psPowerDevice->hSysData = psDeviceNode->psDevConfig->hSysData; - psPowerDevice->hDevCookie = hDevCookie; - OSAtomicWrite(&psPowerDevice->eCurrentPowerState, eCurrentPowerState); - psPowerDevice->eDefaultPowerState = eDefaultPowerState; - - psDeviceNode->psPowerDev = psPowerDevice; - - return PVRSRV_OK; -} - -void PVRSRVRemovePowerDevice(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - if (psDeviceNode->psPowerDev) - { - OSFreeMem(psDeviceNode->psPowerDev); - psDeviceNode->psPowerDev = NULL; - } -} - -PVRSRV_ERROR PVRSRVGetDevicePowerState(PCPVRSRV_DEVICE_NODE psDeviceNode, - PPVRSRV_DEV_POWER_STATE pePowerState) -{ - PVRSRV_POWER_DEV *psPowerDevice; - - psPowerDevice = psDeviceNode->psPowerDev; - if (psPowerDevice == NULL) - { - return PVRSRV_ERROR_UNKNOWN_POWER_STATE; - } - - *pePowerState = OSAtomicRead(&psPowerDevice->eCurrentPowerState); - - return PVRSRV_OK; -} - -IMG_BOOL PVRSRVIsDevicePowered(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - PVRSRV_DEV_POWER_STATE ePowerState; - - if (PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState) != PVRSRV_OK) - { - return IMG_FALSE; - } - - return (ePowerState == PVRSRV_DEV_POWER_STATE_ON); -} - -PVRSRV_ERROR -PVRSRVDevicePreClockSpeedChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_BOOL bIdleDevice, - void* pvInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_POWER_DEV *psPowerDevice; - IMG_UINT64 ui64StartTimer, ui64StopTimer; - - PVR_UNREFERENCED_PARAMETER(pvInfo); - - ui64StartTimer = PVRSRVProcessStatsGetTimeUs(); - - /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */ - eError = PVRSRVPowerLock(psDeviceNode); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVPowerLock"); - - psPowerDevice = psDeviceNode->psPowerDev; - if (psPowerDevice) - { - PVRSRV_DEV_POWER_STATE eCurrentPowerState = - OSAtomicRead(&psPowerDevice->eCurrentPowerState); - - if ((eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) && bIdleDevice) - { - /* We can change the clock speed if the device is either IDLE or OFF */ - eError = PVRSRVDeviceIdleRequestKM(psDeviceNode, NULL, IMG_TRUE); - - if (eError != PVRSRV_OK) - { - /* FW Can signal denied when busy with SPM or other work it can not idle */ - if (eError != PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Error (%s) from %s()", __func__, - PVRSRVGETERRORSTRING(eError), "PVRSRVDeviceIdleRequestKM")); - } - if (eError != PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED) - { - PVRSRVPowerUnlock(psDeviceNode); - } - return eError; - } - } - - eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, - eCurrentPowerState); - } - - ui64StopTimer = PVRSRVProcessStatsGetTimeUs(); - - InsertPowerTimeStatisticExtraPre(ui64StartTimer, ui64StopTimer); - - return eError; -} - -void -PVRSRVDevicePostClockSpeedChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_BOOL bIdleDevice, - void* pvInfo) -{ - PVRSRV_ERROR eError; - PVRSRV_POWER_DEV *psPowerDevice; - IMG_UINT64 ui64StartTimer, ui64StopTimer; - - PVR_UNREFERENCED_PARAMETER(pvInfo); - - ui64StartTimer = PVRSRVProcessStatsGetTimeUs(); - - psPowerDevice = psDeviceNode->psPowerDev; - if (psPowerDevice) - { - PVRSRV_DEV_POWER_STATE eCurrentPowerState = - OSAtomicRead(&psPowerDevice->eCurrentPowerState); - - eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, - eCurrentPowerState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Device %p failed (%s)", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - } - - if ((eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) && bIdleDevice) - { - eError = PVRSRVDeviceIdleCancelRequestKM(psDeviceNode); - PVR_LOG_IF_ERROR(eError, "PVRSRVDeviceIdleCancelRequestKM"); - } - } - - /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */ - PVRSRVPowerUnlock(psDeviceNode); - - OSAtomicIncrement(&psDeviceNode->iNumClockSpeedChanges); - - ui64StopTimer = PVRSRVProcessStatsGetTimeUs(); - - InsertPowerTimeStatisticExtraPost(ui64StartTimer, ui64StopTimer); -} - -PVRSRV_ERROR PVRSRVDeviceGPUUnitsPowerChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_UINT32 ui32NewValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_POWER_DEV *psPowerDevice; - - psPowerDevice = psDeviceNode->psPowerDev; - if (psPowerDevice) - { - PVRSRV_DEV_POWER_STATE eDevicePowerState; - - eError = PVRSRVPowerLock(psDeviceNode); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVPowerLock"); - - eDevicePowerState = OSAtomicRead(&psPowerDevice->eCurrentPowerState); - if (eDevicePowerState == PVRSRV_DEV_POWER_STATE_ON) - { - /* Device must be idle to change GPU unit(s) power state */ - eError = PVRSRVDeviceIdleRequestKM(psDeviceNode, NULL, IMG_FALSE); - - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "PVRSRVDeviceIdleRequestKM"); - if (eError == PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED) - { - goto ErrorExit; - } - goto ErrorUnlockAndExit; - } - } - - if (psPowerDevice->pfnGPUUnitsPowerChange != NULL) - { - PVRSRV_ERROR eError2 = psPowerDevice->pfnGPUUnitsPowerChange(psPowerDevice->hDevCookie, ui32NewValue); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Device %p failed (%s)", - __func__, psDeviceNode, - PVRSRVGetErrorString(eError2))); - } - } - - if (eDevicePowerState == PVRSRV_DEV_POWER_STATE_ON) - { - eError = PVRSRVDeviceIdleCancelRequestKM(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVDeviceIdleCancelRequestKM", ErrorUnlockAndExit); - } - - PVRSRVPowerUnlock(psDeviceNode); - } - - return eError; - -ErrorUnlockAndExit: - PVRSRVPowerUnlock(psDeviceNode); -ErrorExit: - return eError; -} - -/****************************************************************************** - End of file (power.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/power.h b/drivers/gpu/drm/img-rogue/1.17/power.h deleted file mode 100644 index 333e7992eb346..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/power.h +++ /dev/null @@ -1,430 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Power Management Functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main APIs for power management functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 POWER_H -#define POWER_H - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_device.h" -#include "pvrsrv_error.h" -#include "servicesext.h" -#include "opaque_types.h" - -/*! - ***************************************************************************** - * Power management - *****************************************************************************/ - -typedef struct _PVRSRV_POWER_DEV_TAG_ PVRSRV_POWER_DEV; - -typedef IMG_BOOL (*PFN_SYS_DEV_IS_DEFAULT_STATE_OFF)(PVRSRV_POWER_DEV *psPowerDevice); - -/* Power transition handler prototypes */ - -/*! - Typedef for a pointer to a Function that will be called before a transition - from one power state to another. See also PFN_POST_POWER. - */ -typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); -/*! - Typedef for a pointer to a Function that will be called after a transition - from one power state to another. See also PFN_PRE_POWER. - */ -typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -PVRSRV_ERROR PVRSRVPowerLockInit(PPVRSRV_DEVICE_NODE psDeviceNode); -void PVRSRVPowerLockDeInit(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - - @Function PVRSRVPowerLock - - @Description Obtain the mutex for power transitions. Only allowed when - system power is on. - - @Return PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPowerLock(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - - @Function PVRSRVPowerUnlock - - @Description Release the mutex for power transitions - - @Return PVRSRV_ERROR - -******************************************************************************/ -void PVRSRVPowerUnlock(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - - @Function PVRSRVPowerTryLock - - @Description Try to obtain the mutex for power transitions. Only allowed when - system power is on. - - @Return PVRSRV_ERROR_RETRY or PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF or - PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPowerTryLock(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - - @Function PVRSRVPwrLockIsLockedByMe - - @Description Determine if the calling context is holding the device power-lock - - @Return IMG_BOOL - -******************************************************************************/ -IMG_BOOL PVRSRVPwrLockIsLockedByMe(PCPVRSRV_DEVICE_NODE psDeviceNode); -IMG_BOOL PVRSRVDeviceIsDefaultStateOFF(PVRSRV_POWER_DEV *psPowerDevice); - -/*! -****************************************************************************** - - @Function PVRSRVSetDevicePowerStateKM - - @Description Set the Device into a new state - - @Input psDeviceNode : Device node - @Input eNewPowerState : New power state - @Input ePwrFlags : Power state change flags - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*************************************************************************/ /*! -@Function PVRSRVSetDeviceSystemPowerState -@Description Set the device into a new power state based on the systems power - state -@Input psDeviceNode Device node -@Input eNewSysPowerState New system power state -@Input ePwrFlags Power state change flags -@Return PVRSRV_ERROR PVRSRV_OK on success or an error otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVSetDeviceSystemPowerState(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_SYS_POWER_STATE eNewSysPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*! -****************************************************************************** - - @Function PVRSRVSetDeviceDefaultPowerState - - @Description Set the default device power state to eNewPowerState - - @Input psDeviceNode : Device node - @Input eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVSetDeviceDefaultPowerState(PCPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_DEV_POWER_STATE eNewPowerState); - -/*! -****************************************************************************** - - @Function PVRSRVSetSystemPowerState - - @Description Set the system power state to eNewPowerState - - @Input psDeviceConfig : Device config - @Input eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVSetSystemPowerState(PVRSRV_DEVICE_CONFIG * psDeviceConfig, - PVRSRV_SYS_POWER_STATE eNewSysPowerState); - -/*! -****************************************************************************** - - @Function PVRSRVSetPowerCallbacks - - @Description Initialise the Power Device's function pointers - to the appropriate callbacks depending on driver mode and - system setup. - - @Input psDeviceNode : Device node - @Input psPowerDevice : Power device - @Input pfnDevicePrePower : regular device pre power callback - @Input pfnDevicePostPower : regular device post power callback - @Input pfnSystemPrePower : regular system pre power callback - @Input pfnDevicePostPower : regular system post power callback - @Input pfnSystemPrePower : regular device pre power callback - @Input pfnSystemPostPower : regular device pre power callback - @Input pfnForcedIdleRequest : forced idle request callback - @Input pfnForcedIdleCancelRequest : forced idle request cancel callback - -******************************************************************************/ -void PVRSRVSetPowerCallbacks(PPVRSRV_DEVICE_NODE psDeviceNode, - PVRSRV_POWER_DEV *psPowerDevice, - PFN_PRE_POWER pfnDevicePrePower, - PFN_POST_POWER pfnDevicePostPower, - PFN_SYS_PRE_POWER pfnSystemPrePower, - PFN_SYS_POST_POWER pfnSystemPostPower, - PFN_FORCED_IDLE_REQUEST pfnForcedIdleRequest, - PFN_FORCED_IDLE_CANCEL_REQUEST pfnForcedIdleCancelRequest); - -/* Type PFN_DC_REGISTER_POWER */ -PVRSRV_ERROR PVRSRVRegisterPowerDevice(PPVRSRV_DEVICE_NODE psDeviceNode, - PFN_PRE_POWER pfnDevicePrePower, - PFN_POST_POWER pfnDevicePostPower, - PFN_SYS_PRE_POWER pfnSystemPrePower, - PFN_SYS_POST_POWER pfnSystemPostPower, - PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, - PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, - PFN_FORCED_IDLE_REQUEST pfnForcedIdleRequest, - PFN_FORCED_IDLE_CANCEL_REQUEST pfnForcedIdleCancelRequest, - PFN_GPU_UNITS_POWER_CHANGE pfnGPUUnitsPowerChange, - IMG_HANDLE hDevCookie, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_DEV_POWER_STATE eDefaultPowerState); - -/*! -****************************************************************************** - - @Function PVRSRVRemovePowerDevice - - @Description - - Removes device from power management register. Device is located by Device Index - - @Input psDeviceNode : Device node - -******************************************************************************/ -void PVRSRVRemovePowerDevice(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - - @Function PVRSRVGetDevicePowerState - - @Description - - Return the device power state - - @Input psDeviceNode : Device node - @Output pePowerState : Current power state - - @Return PVRSRV_ERROR_UNKNOWN_POWER_STATE if device could not be found. - PVRSRV_OK otherwise. - -******************************************************************************/ -PVRSRV_ERROR PVRSRVGetDevicePowerState(PCPVRSRV_DEVICE_NODE psDeviceNode, - PPVRSRV_DEV_POWER_STATE pePowerState); - -/*! -****************************************************************************** - - @Function PVRSRVIsDevicePowered - - @Description - - Whether the device is powered, for the purposes of lockup detection. - - @Input psDeviceNode : Device node - - @Return IMG_BOOL - -******************************************************************************/ -IMG_BOOL PVRSRVIsDevicePowered(PPVRSRV_DEVICE_NODE psDeviceNode); - -/**************************************************************************/ /*! -@Function PVRSRVDevicePreClockSpeedChange - -@Description This function is called before a voltage/frequency change is - made to the GPU HW. It informs the host driver of the intention - to make a DVFS change. If allows the host driver to idle - the GPU and begin a hold off period from starting new work - on the GPU. - When this call succeeds the caller *must* call - PVRSRVDevicePostClockSpeedChange() to end the hold off period - to allow new work to be submitted to the GPU. - - Called from system layer or OS layer implementation that - is responsible for triggering a GPU DVFS transition. - -@Input psDeviceNode pointer to the device affected by DVFS transition. -@Input bIdleDevice when True, the driver will wait for the GPU to - reach an idle state before the call returns. -@Input pvInfo unused - -@Return PVRSRV_OK on success, power lock acquired and held on exit, - GPU idle. - PVRSRV_ERROR on failure, power lock not held on exit, do not - call PVRSRVDevicePostClockSpeedChange(). -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_BOOL bIdleDevice, - void *pvInfo); - -/**************************************************************************/ /*! -@Function PVRSRVDevicePostClockSpeedChange - -@Description This function is called after a voltage/frequency change has - been made to the GPU HW following a call to - PVRSRVDevicePreClockSpeedChange(). - Before calling this function the caller must ensure the system - data RGX_DATA->RGX_TIMING_INFORMATION->ui32CoreClockSpeed has - been updated with the new frequency set, measured in Hz. - The function informs the host driver that the DVFS change has - completed. The driver will end the work hold off period, cancel - the device idle period and update its time data records. - When this call returns work submissions are unblocked and - are submitted to the GPU as normal. - This function *must* not be called if the preceding call to - PVRSRVDevicePreClockSpeedChange() failed. - - Called from system layer or OS layer implementation that - is responsible for triggering a GPU DVFS transition. - -@Input psDeviceNode pointer to the device affected by DVFS transition. -@Input bIdleDevice when True, the driver will cancel the GPU - device idle state before the call returns. Value - given must match that used in the call to - PVRSRVDevicePreClockSpeedChange() otherwise - undefined behaviour will result. -@Input pvInfo unused - -@Return void power lock released, no longer held on exit. -*/ /**************************************************************************/ -void PVRSRVDevicePostClockSpeedChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_BOOL bIdleDevice, - void *pvInfo); - -/*! -****************************************************************************** - - @Function PVRSRVDeviceIdleRequestKM - - @Description Perform device-specific processing required to force the device - idle. The device power-lock might be temporarily released (and - again re-acquired) during the course of this call, hence to - maintain lock-ordering power-lock should be the last acquired - lock before calling this function - - @Input psDeviceNode : Device node - - @Input pfnIsDefaultStateOff : When specified, the idle request is only - processed if this function passes. - - @Input bDeviceOffPermitted : IMG_TRUE if the transition should not fail - if device off - IMG_FALSE if the transition should fail if - device off - - @Return PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED - When re-acquisition of power-lock failed. - This error NEEDS EXPLICIT HANDLING at call - site as it signifies the caller needs to - AVOID calling PVRSRVPowerUnlock, since - power-lock is no longer "possessed" by - this context. - - PVRSRV_OK When idle request succeeded. - PVRSRV_ERROR Other system errors. - -******************************************************************************/ -PVRSRV_ERROR PVRSRVDeviceIdleRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode, - PFN_SYS_DEV_IS_DEFAULT_STATE_OFF pfnIsDefaultStateOff, - IMG_BOOL bDeviceOffPermitted); - -/*! -****************************************************************************** - - @Function PVRSRVDeviceIdleCancelRequestKM - - @Description Perform device-specific processing required to cancel the forced idle state - on the device, returning to normal operation. - - @Input psDeviceNode : Device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVDeviceIdleCancelRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode); - -/*! -****************************************************************************** - -@Function PVRSRVDeviceGPUUnitsPowerChange -@Description Request from system layer for changing power state of GPU - units -@Input psDeviceNode RGX Device Node. -@Input ui32NewValue Value indicating the new power state - of GPU units. how this is interpreted - depends upon the device-specific - function subsequently called by the - server via a pfn. -@Return PVRSRV_ERROR. -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVDeviceGPUUnitsPowerChange(PPVRSRV_DEVICE_NODE psDeviceNode, - IMG_UINT32 ui32NewValue); - - -#endif /* POWER_H */ - -/****************************************************************************** - End of file (power.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/powervr/buffer_attribs.h b/drivers/gpu/drm/img-rogue/1.17/powervr/buffer_attribs.h deleted file mode 100644 index 41eaaaecd19e3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/powervr/buffer_attribs.h +++ /dev/null @@ -1,193 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title 3D types for use by IMG APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License MIT - -The contents of this file are subject to the MIT license as set out below. - -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 -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 POWERVR_BUFFER_ATTRIBS_H -#define POWERVR_BUFFER_ATTRIBS_H - -/*! - * Memory layouts - * Defines how pixels are laid out within a surface. - */ -typedef enum -{ - IMG_MEMLAYOUT_STRIDED, /**< Resource is strided, one row at a time */ - IMG_MEMLAYOUT_TWIDDLED, /**< Resource is 2D twiddled to match HW */ - IMG_MEMLAYOUT_3DTWIDDLED, /**< Resource is 3D twiddled, classic style */ - IMG_MEMLAYOUT_TILED, /**< Resource is tiled, tiling config specified elsewhere. */ - IMG_MEMLAYOUT_PAGETILED, /**< Resource is pagetiled */ - IMG_MEMLAYOUT_INVNTWIDDLED, /**< Resource is 2D twiddled !N style */ -} IMG_MEMLAYOUT; - -/*! - * Rotation types - */ -typedef enum -{ - IMG_ROTATION_0DEG = 0, - IMG_ROTATION_90DEG = 1, - IMG_ROTATION_180DEG = 2, - IMG_ROTATION_270DEG = 3, - IMG_ROTATION_FLIP_Y = 4, - - IMG_ROTATION_BAD = 255, -} IMG_ROTATION; - -/*! - * Alpha types. - */ -typedef enum -{ - IMG_COLOURSPACE_FORMAT_UNKNOWN = 0x0UL << 16, - IMG_COLOURSPACE_FORMAT_LINEAR = 0x1UL << 16, - IMG_COLOURSPACE_FORMAT_SRGB = 0x2UL << 16, - IMG_COLOURSPACE_FORMAT_SCRGB = 0x3UL << 16, - IMG_COLOURSPACE_FORMAT_SCRGB_LINEAR = 0x4UL << 16, - IMG_COLOURSPACE_FORMAT_DISPLAY_P3_LINEAR = 0x5UL << 16, - IMG_COLOURSPACE_FORMAT_DISPLAY_P3 = 0x6UL << 16, - IMG_COLOURSPACE_FORMAT_BT2020_PQ = 0x7UL << 16, - IMG_COLOURSPACE_FORMAT_BT2020_LINEAR = 0x8UL << 16, - IMG_COLOURSPACE_FORMAT_DISPLAY_P3_PASSTHROUGH = 0x9UL << 16, - IMG_COLOURSPACE_FORMAT_MASK = 0xFUL << 16, -} IMG_COLOURSPACE_FORMAT; - -/*! - * Determines if FB Compression is Lossy - */ -#define IS_FBCDC_LOSSY(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_TRUE : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_TRUE : IMG_FALSE) - -/*! - * Determines if FB Compression is Packed - */ -#define IS_FBCDC_PACKED(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_TRUE : IMG_FALSE) - -/*! - * Returns type of FB Compression - */ -#define GET_FBCDC_BLOCK_TYPE(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : mode) - -/*! - * Adds Packing compression setting to mode if viable - */ -#define FBCDC_MODE_ADD_PACKING(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_PACKED_8x8 : mode) - -/*! - * Removes Packing compression setting from mode - */ -#define FBCDC_MODE_REMOVE_PACKING(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : mode) - -/*! - * Adds Lossy25 compression setting to mode if viable - */ -#define FBCDC_MODE_ADD_LOSSY25(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2 : mode) - -/*! - * Adds Lossy37 compression setting to mode if viable - */ -#define FBCDC_MODE_ADD_LOSSY37(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2 : mode) - -/*! - * Adds Lossy50 compression setting to mode if viable - */ -#define FBCDC_MODE_ADD_LOSSY50(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2 : mode) - -/*! - * Adds Lossy75 compression setting to mode if viable - */ -#define FBCDC_MODE_ADD_LOSSY75(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2 : mode) - -/*! - * Removes Lossy compression setting from mode - */ -#define FBCDC_MODE_REMOVE_LOSSY(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \ - (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : mode) - -/*! - * Types of framebuffer compression - */ -typedef enum -{ - IMG_FB_COMPRESSION_NONE, - IMG_FB_COMPRESSION_DIRECT_8x8, - IMG_FB_COMPRESSION_DIRECT_16x4, - IMG_FB_COMPRESSION_DIRECT_32x2, - IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8, - IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4, - IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2, - IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8, - IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8, - IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4, - IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2, - IMG_FB_COMPRESSION_DIRECT_PACKED_8x8, - IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4, - IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2, - IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8, - IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4, - IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2, -} IMG_FB_COMPRESSION; - - -#endif /* POWERVR_BUFFER_ATTRIBS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/powervr/mem_types.h b/drivers/gpu/drm/img-rogue/1.17/powervr/mem_types.h deleted file mode 100644 index a6dce8fe9889b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/powervr/mem_types.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Public types -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License MIT - -The contents of this file are subject to the MIT license as set out below. - -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 -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 POWERVR_TYPES_H -#define POWERVR_TYPES_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#if defined(_MSC_VER) - #include "msvc_types.h" -#elif defined(__linux__) && defined(__KERNEL__) - #include - #include -#else - #include - #define __iomem -#endif - -typedef void *IMG_CPU_VIRTADDR; - -/* device virtual address */ -typedef struct -{ - uint64_t uiAddr; -#define IMG_CAST_TO_DEVVADDR_UINT(var) (uint64_t)(var) - -} IMG_DEV_VIRTADDR; - -typedef uint64_t IMG_DEVMEM_SIZE_T; -typedef uint64_t IMG_DEVMEM_ALIGN_T; -typedef uint64_t IMG_DEVMEM_OFFSET_T; -typedef uint32_t IMG_DEVMEM_LOG2ALIGN_T; - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/powervr/pvrsrv_sync_ext.h b/drivers/gpu/drm/img-rogue/1.17/powervr/pvrsrv_sync_ext.h deleted file mode 100644 index 30f7972444cd0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/powervr/pvrsrv_sync_ext.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services external synchronisation interface header -@Description Defines synchronisation structures that are visible internally - and externally -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License MIT - -The contents of this file are subject to the MIT license as set out below. - -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 -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 POWERVR_SYNC_EXT_H -#define POWERVR_SYNC_EXT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * Number of sync prims still used internally in operations - */ -#define PVRSRV_MAX_SYNC_PRIMS 4U - -/*! - * Maximum number of dev var updates passed in a kick call - */ -#define PVRSRV_MAX_DEV_VARS 13U - -/*! - * Number of UFOs in operations - */ -#define PVRSRV_MAX_SYNCS (PVRSRV_MAX_SYNC_PRIMS + PVRSRV_MAX_DEV_VARS) - -/*! Implementation independent types for passing fence/timeline to Services. - */ -typedef int32_t PVRSRV_FENCE; -typedef int32_t PVRSRV_TIMELINE; - -/*! Maximum length for an annotation name string for fence sync model objects. - */ -#define PVRSRV_SYNC_NAME_LENGTH 32U - -/* Macros for API callers using the fence sync model - */ -#define PVRSRV_NO_TIMELINE ((PVRSRV_TIMELINE) -1) -#define PVRSRV_NO_FENCE ((PVRSRV_FENCE) -1) -#define PVRSRV_NO_FENCE_PTR NULL -#define PVRSRV_NO_TIMELINE_PTR NULL - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/private_data.h b/drivers/gpu/drm/img-rogue/1.17/private_data.h deleted file mode 100644 index 60a1fac0b9700..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/private_data.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Linux private data structure -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(INCLUDED_PRIVATE_DATA_H) -#define INCLUDED_PRIVATE_DATA_H - -#include - -#include "connection_server.h" -#include "pvr_drm.h" - -#define PVR_SRVKM_PRIV_DATA_IDX 0 -#define PVR_SYNC_PRIV_DATA_IDX 1 - -#define PVR_NUM_PRIV_DATA_IDXS 2 - -CONNECTION_DATA *LinuxServicesConnectionFromFile(struct file *pFile); -CONNECTION_DATA *LinuxSyncConnectionFromFile(struct file *pFile); - -#endif /* !defined(INCLUDED_PRIVATE_DATA_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/proc_stats.h b/drivers/gpu/drm/img-rogue/1.17/proc_stats.h deleted file mode 100644 index a4e9c786518c4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/proc_stats.h +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Process and driver statistic definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PROC_STATS_H -#define PROC_STATS_H - -/* X-Macro for Process stat keys */ -#define PVRSRV_PROCESS_STAT_KEY \ - X(PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS, "Connections") \ - X(PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS, "ConnectionsMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_OOMS, "RenderContextOutOfMemoryEvents") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_PRS, "RenderContextPartialRenders") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_GROWS, "RenderContextGrows") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_PUSH_GROWS, "RenderContextPushGrows") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES, "RenderContextTAStores") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES, "RenderContext3DStores") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES, "RenderContextCDMStores") \ - X(PVRSRV_PROCESS_STAT_TYPE_RC_TDM_STORES, "RenderContextTDMStores") \ - X(PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP, "ZSBufferRequestsByApp") \ - X(PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW, "ZSBufferRequestsByFirmware") \ - X(PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP, "FreeListGrowRequestsByApp") \ - X(PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW, "FreeListGrowRequestsByFirmware") \ - X(PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT, "FreeListInitialPages") \ - X(PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES, "FreeListMaxPages") \ - X(PVRSRV_PROCESS_STAT_TYPE_KMALLOC, "MemoryUsageKMalloc") \ - X(PVRSRV_PROCESS_STAT_TYPE_KMALLOC_MAX, "MemoryUsageKMallocMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_VMALLOC, "MemoryUsageVMalloc") \ - X(PVRSRV_PROCESS_STAT_TYPE_VMALLOC_MAX, "MemoryUsageVMallocMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, "MemoryUsageAllocPTMemoryUMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA_MAX, "MemoryUsageAllocPTMemoryUMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, "MemoryUsageVMapPTUMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA_MAX, "MemoryUsageVMapPTUMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, "MemoryUsageAllocPTMemoryLMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA_MAX, "MemoryUsageAllocPTMemoryLMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, "MemoryUsageIORemapPTLMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA_MAX, "MemoryUsageIORemapPTLMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, "MemoryUsageAllocGPUMemLMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES_MAX, "MemoryUsageAllocGPUMemLMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, "MemoryUsageAllocGPUMemUMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES_MAX, "MemoryUsageAllocGPUMemUMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, "MemoryUsageMappedGPUMemUMA/LMA") \ - X(PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES_MAX, "MemoryUsageMappedGPUMemUMA/LMAMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT, "MemoryUsageDmaBufImport") \ - X(PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT_MAX, "MemoryUsageDmaBufImportMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_TOTAL, "MemoryUsageTotal") \ - X(PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAX, "MemoryUsageTotalMax") \ - X(PVRSRV_PROCESS_STAT_TYPE_OOM_VIRTMEM_COUNT, "MemoryOOMCountDeviceVirtual") \ - X(PVRSRV_PROCESS_STAT_TYPE_OOM_PHYSMEM_COUNT, "MemoryOOMCountPhysicalHeap") \ - X(PVRSRV_PROCESS_STAT_TYPE_INVALID_VIRTMEM, "MemoryOOMCountDeviceVirtualAtAddress") - - -/* X-Macro for Driver stat keys */ -#define PVRSRV_DRIVER_STAT_KEY \ - X(PVRSRV_DRIVER_STAT_TYPE_KMALLOC, "MemoryUsageKMalloc") \ - X(PVRSRV_DRIVER_STAT_TYPE_KMALLOC_MAX, "MemoryUsageKMallocMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_VMALLOC, "MemoryUsageVMalloc") \ - X(PVRSRV_DRIVER_STAT_TYPE_VMALLOC_MAX, "MemoryUsageVMallocMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA, "MemoryUsageAllocPTMemoryUMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA_MAX, "MemoryUsageAllocPTMemoryUMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA, "MemoryUsageVMapPTUMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA_MAX, "MemoryUsageVMapPTUMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA, "MemoryUsageAllocPTMemoryLMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA_MAX, "MemoryUsageAllocPTMemoryLMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA, "MemoryUsageIORemapPTLMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA_MAX, "MemoryUsageIORemapPTLMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA, "MemoryUsageAllocGPUMemLMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA_MAX, "MemoryUsageAllocGPUMemLMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA, "MemoryUsageAllocGPUMemUMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_MAX, "MemoryUsageAllocGPUMemUMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL, "MemoryUsageAllocGPUMemUMAPool") \ - X(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL_MAX, "MemoryUsageAllocGPUMemUMAPoolMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA, "MemoryUsageMappedGPUMemUMA/LMA") \ - X(PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA_MAX, "MemoryUsageMappedGPUMemUMA/LMAMax") \ - X(PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT, "MemoryUsageDmaBufImport") \ - X(PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT_MAX, "MemoryUsageDmaBufImportMax") - - -typedef enum { -#define X(stat_type, stat_str) stat_type, - PVRSRV_PROCESS_STAT_KEY -#undef X - PVRSRV_PROCESS_STAT_TYPE_COUNT -}PVRSRV_PROCESS_STAT_TYPE; - -typedef enum { -#define X(stat_type, stat_str) stat_type, - PVRSRV_DRIVER_STAT_KEY -#undef X - PVRSRV_DRIVER_STAT_TYPE_COUNT -}PVRSRV_DRIVER_STAT_TYPE; - -extern const IMG_CHAR *const pszProcessStatType[]; - -extern const IMG_CHAR *const pszDriverStatType[]; - -#endif // PROC_STATS_H diff --git a/drivers/gpu/drm/img-rogue/1.17/process_stats.c b/drivers/gpu/drm/img-rogue/1.17/process_stats.c deleted file mode 100644 index 46641d5542187..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/process_stats.c +++ /dev/null @@ -1,3358 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Process based statistics -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Manages a collection of statistics based around a process - and referenced via OS agnostic methods. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "img_types.h" -#include "pvr_debug.h" -#include "lock.h" -#include "allocmem.h" -#include "osfunc.h" -#include "lists.h" -#include "process_stats.h" -#include "ri_server.h" -#include "hash.h" -#include "connection_server.h" -#include "pvrsrv.h" -#include "proc_stats.h" -#include "htbuffer.h" -#include "pvr_ricommon.h" -#include "di_server.h" -#if defined(__linux__) -#include "trace_events.h" -#endif - -/* Enabled OS Statistics entries: DEBUGFS on Linux, undefined for other OSs */ -#if defined(__linux__) && ( \ - defined(PVRSRV_ENABLE_PERPID_STATS) || \ - defined(PVRSRV_ENABLE_CACHEOP_STATS) || \ - defined(PVRSRV_ENABLE_MEMORY_STATS) || \ - defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) ) -#define ENABLE_DEBUGFS_PIDS -#endif - -/* Enable GPU memory accounting tracepoint */ -#if defined(__linux__) && ( \ - defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) ) -#define ENABLE_GPU_MEM_TRACEPOINT -#endif - -/* - * Maximum history of process statistics that will be kept. - */ -#define MAX_DEAD_LIST_PROCESSES (10) - -/* - * Definition of all the strings used to format process based statistics. - */ - -#if defined(PVRSRV_ENABLE_PERPID_STATS) -/* Array of Process stat type defined using the X-Macro */ -#define X(stat_type, stat_str) stat_str, -const IMG_CHAR *const pszProcessStatType[PVRSRV_PROCESS_STAT_TYPE_COUNT] = { PVRSRV_PROCESS_STAT_KEY }; -#undef X -#endif - -/* Array of Driver stat type defined using the X-Macro */ -#define X(stat_type, stat_str) stat_str, -const IMG_CHAR *const pszDriverStatType[PVRSRV_DRIVER_STAT_TYPE_COUNT] = { PVRSRV_DRIVER_STAT_KEY }; -#undef X - -/* structure used in hash table to track statistic entries */ -typedef struct { - size_t uiSizeInBytes; - IMG_PID uiPid; -} _PVR_STATS_TRACKING_HASH_ENTRY; - -/* Function used internally to decrement tracked per-process statistic entries */ -static void _StatsDecrMemTrackedStat(_PVR_STATS_TRACKING_HASH_ENTRY *psTrackingHashEntry, - PVRSRV_MEM_ALLOC_TYPE eAllocType); - -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) -int RawProcessStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData); -#endif -int PowerStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData); -int GlobalStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData); - -/* Note: all of the accesses to the global stats should be protected - * by the gsGlobalStats.hGlobalStatsLock lock. This means all of the - * invocations of macros *_GLOBAL_STAT_VALUE. */ - -/* Macros for fetching stat values */ -#define GET_STAT_VALUE(ptr,var) (ptr)->i32StatValue[(var)] -#define GET_GLOBAL_STAT_VALUE(idx) gsGlobalStats.ui64StatValue[idx] - -#define GET_GPUMEM_GLOBAL_STAT_VALUE() \ - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA) + \ - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA) + \ - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA) + \ - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA) + \ - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT) - -#define GET_GPUMEM_PERPID_STAT_VALUE(ptr) \ - GET_STAT_VALUE((ptr), PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA) + \ - GET_STAT_VALUE((ptr), PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA) + \ - GET_STAT_VALUE((ptr), PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES) + \ - GET_STAT_VALUE((ptr), PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES) + \ - GET_STAT_VALUE((ptr), PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT) -/* - * Macros for updating stat values. - */ -#define UPDATE_MAX_VALUE(a,b) do { if ((b) > (a)) {(a) = (b);} } while (0) -#define INCREASE_STAT_VALUE(ptr,var,val) do { (ptr)->i32StatValue[(var)] += (val); if ((ptr)->i32StatValue[(var)] > (ptr)->i32StatValue[(var##_MAX)]) {(ptr)->i32StatValue[(var##_MAX)] = (ptr)->i32StatValue[(var)];} } while (0) -#define INCREASE_GLOBAL_STAT_VALUE(var,idx,val) do { (var).ui64StatValue[(idx)] += (val); if ((var).ui64StatValue[(idx)] > (var).ui64StatValue[(idx##_MAX)]) {(var).ui64StatValue[(idx##_MAX)] = (var).ui64StatValue[(idx)];} } while (0) -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) -/* Allow stats to go negative */ -#define DECREASE_STAT_VALUE(ptr,var,val) do { (ptr)->i32StatValue[(var)] -= (val); } while (0) -#define DECREASE_GLOBAL_STAT_VALUE(var,idx,val) do { (var).ui64StatValue[(idx)] -= (val); } while (0) -#else -#define DECREASE_STAT_VALUE(ptr,var,val) do { if ((ptr)->i32StatValue[(var)] >= (val)) { (ptr)->i32StatValue[(var)] -= (val); } else { (ptr)->i32StatValue[(var)] = 0; } } while (0) -#define DECREASE_GLOBAL_STAT_VALUE(var,idx,val) do { if ((var).ui64StatValue[(idx)] >= (val)) { (var).ui64StatValue[(idx)] -= (val); } else { (var).ui64StatValue[(idx)] = 0; } } while (0) -#endif -#define MAX_CACHEOP_STAT 16 -#define INCREMENT_CACHEOP_STAT_IDX_WRAP(x) ((x+1) >= MAX_CACHEOP_STAT ? 0 : (x+1)) -#define DECREMENT_CACHEOP_STAT_IDX_WRAP(x) ((x-1) < 0 ? (MAX_CACHEOP_STAT-1) : (x-1)) - -/* - * Structures for holding statistics... - */ -#if defined(PVRSRV_ENABLE_MEMORY_STATS) -typedef struct _PVRSRV_MEM_ALLOC_REC_ -{ - PVRSRV_MEM_ALLOC_TYPE eAllocType; - IMG_UINT64 ui64Key; - void* pvCpuVAddr; - IMG_CPU_PHYADDR sCpuPAddr; - size_t uiBytes; - void* pvPrivateData; -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON) - void* pvAllocdFromFile; - IMG_UINT32 ui32AllocdFromLine; -#endif - IMG_PID pid; - struct _PVRSRV_MEM_ALLOC_REC_* psNext; - struct _PVRSRV_MEM_ALLOC_REC_** ppsThis; -} PVRSRV_MEM_ALLOC_REC; -#endif - -typedef struct _PVRSRV_PROCESS_STATS_ { - - /* Linked list pointers */ - struct _PVRSRV_PROCESS_STATS_* psNext; - struct _PVRSRV_PROCESS_STATS_* psPrev; - - /* Create per process lock that need to be held - * to edit of its members */ - POS_LOCK hLock; - - /* OS level process ID */ - IMG_PID pid; - IMG_UINT32 ui32RefCount; - - /* Stats... */ - IMG_INT32 i32StatValue[PVRSRV_PROCESS_STAT_TYPE_COUNT]; - IMG_UINT32 ui32StatAllocFlags; - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) - struct _CACHEOP_STRUCT_ { - PVRSRV_CACHE_OP uiCacheOp; -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEV_PHYADDR sDevPAddr; - RGXFWIF_DM eFenceOpType; -#endif - IMG_DEVMEM_SIZE_T uiOffset; - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT64 ui64ExecuteTime; - IMG_BOOL bUserModeFlush; - IMG_BOOL bIsFence; - IMG_PID ownerPid; - } asCacheOp[MAX_CACHEOP_STAT]; - IMG_INT32 uiCacheOpWriteIndex; -#endif - - /* Other statistics structures */ -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - PVRSRV_MEM_ALLOC_REC* psMemoryRecords; -#endif -} PVRSRV_PROCESS_STATS; - -#if defined(ENABLE_DEBUGFS_PIDS) - -typedef struct _PVRSRV_OS_STAT_ENTRY_ -{ - DI_GROUP *psStatsDIGroup; - DI_ENTRY *psProcessStatsDIEntry; - DI_ENTRY *psMemStatsDIEntry; - DI_ENTRY *psRIMemStatsDIEntry; - DI_ENTRY *psCacheOpStatsDIEntry; -} PVRSRV_OS_STAT_ENTRY; - -static PVRSRV_OS_STAT_ENTRY gsLiveStatEntries; -static PVRSRV_OS_STAT_ENTRY gsRetiredStatEntries; - -int GenericStatsPrintElementsLive(OSDI_IMPL_ENTRY *psEntry, void *pvData); -int GenericStatsPrintElementsRetired(OSDI_IMPL_ENTRY *psEntry, void *pvData); - -/* - * Functions for printing the information stored... - */ -#if defined(PVRSRV_ENABLE_PERPID_STATS) -void ProcessStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats); -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) -void MemStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -void RIMemStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats); -#endif - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) -void CacheOpStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats); -#endif - -typedef void (PVRSRV_STATS_PRINT_ELEMENTS)(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats); - -typedef enum -{ - PVRSRV_STAT_TYPE_PROCESS, - PVRSRV_STAT_TYPE_MEMORY, - PVRSRV_STAT_TYPE_RIMEMORY, - PVRSRV_STAT_TYPE_CACHEOP, - PVRSRV_STAT_TYPE_LAST -} PVRSRV_STAT_TYPE; - -#define SEPARATOR_STR_LEN 166 - -typedef struct _PVRSRV_STAT_PV_DATA_ { - - PVRSRV_STAT_TYPE eStatType; - PVRSRV_STATS_PRINT_ELEMENTS* pfnStatsPrintElements; - IMG_CHAR szLiveStatsHeaderStr[SEPARATOR_STR_LEN + 1]; - IMG_CHAR szRetiredStatsHeaderStr[SEPARATOR_STR_LEN + 1]; - -} PVRSRV_STAT_PV_DATA; - -static PVRSRV_STAT_PV_DATA g_StatPvDataArr[] = { - { PVRSRV_STAT_TYPE_PROCESS, NULL, " Process" , " Process" }, - { PVRSRV_STAT_TYPE_MEMORY, NULL, " Memory Allocation" , " Memory Allocation" }, - { PVRSRV_STAT_TYPE_RIMEMORY, NULL, " Resource Allocation" , " Resource Allocation" }, - { PVRSRV_STAT_TYPE_CACHEOP, NULL, " Cache Maintenance Ops" , " Cache Maintenance Ops" } - }; - -#define GET_STAT_ENTRY_ID(STAT_TYPE) &g_StatPvDataArr[(STAT_TYPE)] - -/* Generic header strings */ -static const IMG_CHAR g_szLiveHeaderStr[] = " Statistics for LIVE Processes "; -static const IMG_CHAR g_szRetiredHeaderStr[] = " Statistics for RETIRED Processes "; - -/* Separator string used for separating stats for different PIDs */ -static IMG_CHAR g_szSeparatorStr[SEPARATOR_STR_LEN + 1] = ""; - -static inline void -_prepareStatsHeaderString(IMG_CHAR *pszStatsSpecificStr, const IMG_CHAR* pszGenericHeaderStr) -{ - IMG_UINT32 ui32NumSeparators; - IMG_CHAR szStatsHeaderFooterStr[75]; - - /* Prepare text content of the header in a local string */ - OSStringLCopy(szStatsHeaderFooterStr, pszStatsSpecificStr, ARRAY_SIZE(szStatsHeaderFooterStr)); - OSStringLCat(szStatsHeaderFooterStr, pszGenericHeaderStr, ARRAY_SIZE(szStatsHeaderFooterStr)); - - /* Write all '-' characters to the header string */ - memset(pszStatsSpecificStr, '-', SEPARATOR_STR_LEN); - pszStatsSpecificStr[SEPARATOR_STR_LEN] = '\0'; - - /* Find the spot for text content in the header string */ - ui32NumSeparators = (SEPARATOR_STR_LEN - OSStringLength(szStatsHeaderFooterStr)) >> 1; - - /* Finally write the text content */ - OSSNPrintf(pszStatsSpecificStr + ui32NumSeparators, - OSStringLength(szStatsHeaderFooterStr), - "%s", szStatsHeaderFooterStr); - - /* Overwrite the '\0' character added by OSSNPrintf() */ - if (OSStringLength(szStatsHeaderFooterStr) > 0) - { - pszStatsSpecificStr[ui32NumSeparators + OSStringLength(szStatsHeaderFooterStr) - 1] = ' '; - } -} - -static inline void -_prepareSeparatorStrings(void) -{ - IMG_UINT32 i; - - /* Prepare header strings for each stat type */ - for (i = 0; i < PVRSRV_STAT_TYPE_LAST; ++i) - { - _prepareStatsHeaderString(g_StatPvDataArr[i].szLiveStatsHeaderStr, g_szLiveHeaderStr); - _prepareStatsHeaderString(g_StatPvDataArr[i].szRetiredStatsHeaderStr, g_szRetiredHeaderStr); - } - - /* Prepare separator string to separate stats for different PIDs */ - memset(g_szSeparatorStr, '-', SEPARATOR_STR_LEN); - g_szSeparatorStr[SEPARATOR_STR_LEN] = '\0'; -} - -static inline void -_prepareStatsPrivateData(void) -{ -#if defined(PVRSRV_ENABLE_PERPID_STATS) - g_StatPvDataArr[PVRSRV_STAT_TYPE_PROCESS].pfnStatsPrintElements = ProcessStatsPrintElements; -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - g_StatPvDataArr[PVRSRV_STAT_TYPE_MEMORY].pfnStatsPrintElements = MemStatsPrintElements; -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - g_StatPvDataArr[PVRSRV_STAT_TYPE_RIMEMORY].pfnStatsPrintElements = RIMemStatsPrintElements; -#endif - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) - g_StatPvDataArr[PVRSRV_STAT_TYPE_CACHEOP].pfnStatsPrintElements = CacheOpStatsPrintElements; -#endif - - _prepareSeparatorStrings(); -} - -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) -static IMPLEMENT_LIST_INSERT(PVRSRV_MEM_ALLOC_REC) -static IMPLEMENT_LIST_REMOVE(PVRSRV_MEM_ALLOC_REC) -#endif - -/* - * Global Boolean to flag when the statistics are ready to monitor - * memory allocations. - */ -static IMG_BOOL bProcessStatsInitialised = IMG_FALSE; - -/* - * Linked lists for process stats. Live stats are for processes which are still running - * and the dead list holds those that have exited. - */ -static PVRSRV_PROCESS_STATS *g_psLiveList; -static PVRSRV_PROCESS_STATS *g_psDeadList; - -static POS_LOCK g_psLinkedListLock; -/* Lockdep feature in the kernel cannot differentiate between different instances of same lock type. - * This allows it to group all such instances of the same lock type under one class - * The consequence of this is that, if lock acquisition is nested on different instances, it generates - * a false warning message about the possible occurrence of deadlock due to recursive lock acquisition. - * Hence we create the following sub classes to explicitly appraise Lockdep of such safe lock nesting */ -#define PROCESS_LOCK_SUBCLASS_CURRENT 1 -#define PROCESS_LOCK_SUBCLASS_PREV 2 -#define PROCESS_LOCK_SUBCLASS_NEXT 3 -#if defined(ENABLE_DEBUGFS_PIDS) -/* - * Pointer to OS folder to hold PID folders. - */ -static DI_GROUP *psProcStatsDIGroup; -#endif -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) -static DI_ENTRY *psProcStatsDIEntry; -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -/* Global driver PID stats registration handle */ -static IMG_HANDLE g_hDriverProcessStats; -#endif - -/* Global driver-data folders */ -typedef struct _GLOBAL_STATS_ -{ - IMG_UINT64 ui64StatValue[PVRSRV_DRIVER_STAT_TYPE_COUNT]; - POS_LOCK hGlobalStatsLock; -} GLOBAL_STATS; - -static DI_ENTRY *psGlobalMemDIEntry; -static GLOBAL_STATS gsGlobalStats; - -#define HASH_INITIAL_SIZE 5 -/* A hash table used to store the size of any vmalloc'd allocation - * against its address (not needed for kmallocs as we can use ksize()) */ -static HASH_TABLE* gpsSizeTrackingHashTable; -static POS_LOCK gpsSizeTrackingHashTableLock; - -static PVRSRV_ERROR _RegisterProcess(IMG_HANDLE *phProcessStats, IMG_PID ownerPid); - -static void _AddProcessStatsToFrontOfDeadList(PVRSRV_PROCESS_STATS* psProcessStats); -static void _AddProcessStatsToFrontOfLiveList(PVRSRV_PROCESS_STATS* psProcessStats); -static void _RemoveProcessStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats); - -static void _DestroyProcessStat(PVRSRV_PROCESS_STATS* psProcessStats); - -static void _DecreaseProcStatValue(PVRSRV_MEM_ALLOC_TYPE eAllocType, - PVRSRV_PROCESS_STATS* psProcessStats, - IMG_UINT32 uiBytes); -/* - * Power statistics related definitions - */ - -/* For the mean time, use an exponentially weighted moving average with a - * 1/4 weighting for the new measurement. - */ -#define MEAN_TIME(A, B) ( ((3*(A))/4) + ((1 * (B))/4) ) - -#define UPDATE_TIME(time, newtime) \ - ((time) > 0 ? MEAN_TIME((time), (newtime)) : (newtime)) - -/* Enum to be used as input to GET_POWER_STAT_INDEX */ -typedef enum -{ - DEVICE = 0, - SYSTEM = 1, - POST_POWER = 0, - PRE_POWER = 2, - POWER_OFF = 0, - POWER_ON = 4, - NOT_FORCED = 0, - FORCED = 8, -} PVRSRV_POWER_STAT_TYPE; - -/* Macro used to access one of the power timing statistics inside an array */ -#define GET_POWER_STAT_INDEX(forced,powon,prepow,system) \ - ((forced) + (powon) + (prepow) + (system)) - -/* For the power timing stats we need 16 variables to store all the - * combinations of forced/not forced, power-on/power-off, pre-power/post-power - * and device/system statistics - */ -#define NUM_POWER_STATS (16) -static IMG_UINT32 aui32PowerTimingStats[NUM_POWER_STATS]; - -static DI_ENTRY *psPowerStatsDIEntry; - -typedef struct _EXTRA_POWER_STATS_ -{ - IMG_UINT64 ui64PreClockSpeedChangeDuration; - IMG_UINT64 ui64BetweenPreEndingAndPostStartingDuration; - IMG_UINT64 ui64PostClockSpeedChangeDuration; -} EXTRA_POWER_STATS; - -#define NUM_EXTRA_POWER_STATS 10 - -static EXTRA_POWER_STATS asClockSpeedChanges[NUM_EXTRA_POWER_STATS]; -static IMG_UINT32 ui32ClockSpeedIndexStart, ui32ClockSpeedIndexEnd; - - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -void InsertPowerTimeStatistic(IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime, - IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime, - IMG_BOOL bForced, IMG_BOOL bPowerOn, IMG_BOOL bPrePower) -{ - IMG_UINT32 *pui32Stat; - IMG_UINT64 ui64DeviceDiff = ui64DevEndTime - ui64DevStartTime; - IMG_UINT64 ui64SystemDiff = ui64SysEndTime - ui64SysStartTime; - IMG_UINT32 ui32Index; - - if (bPrePower) - { - HTBLOGK(HTB_SF_MAIN_PRE_POWER, bPowerOn, ui64DeviceDiff, ui64SystemDiff); - } - else - { - HTBLOGK(HTB_SF_MAIN_POST_POWER, bPowerOn, ui64SystemDiff, ui64DeviceDiff); - } - - ui32Index = GET_POWER_STAT_INDEX(bForced ? FORCED : NOT_FORCED, - bPowerOn ? POWER_ON : POWER_OFF, - bPrePower ? PRE_POWER : POST_POWER, - DEVICE); - pui32Stat = &aui32PowerTimingStats[ui32Index]; - *pui32Stat = UPDATE_TIME(*pui32Stat, ui64DeviceDiff); - - ui32Index = GET_POWER_STAT_INDEX(bForced ? FORCED : NOT_FORCED, - bPowerOn ? POWER_ON : POWER_OFF, - bPrePower ? PRE_POWER : POST_POWER, - SYSTEM); - pui32Stat = &aui32PowerTimingStats[ui32Index]; - *pui32Stat = UPDATE_TIME(*pui32Stat, ui64SystemDiff); -} - -static IMG_UINT64 ui64PreClockSpeedChangeMark; - -void InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer) -{ - asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PreClockSpeedChangeDuration = ui64Stoptimer - ui64StartTimer; - - ui64PreClockSpeedChangeMark = OSClockus(); -} - -void InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer) -{ - IMG_UINT64 ui64Duration = ui64StartTimer - ui64PreClockSpeedChangeMark; - - PVR_ASSERT(ui64PreClockSpeedChangeMark > 0); - - asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64BetweenPreEndingAndPostStartingDuration = ui64Duration; - asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PostClockSpeedChangeDuration = ui64StopTimer - ui64StartTimer; - - ui32ClockSpeedIndexEnd = (ui32ClockSpeedIndexEnd + 1) % NUM_EXTRA_POWER_STATS; - - if (ui32ClockSpeedIndexEnd == ui32ClockSpeedIndexStart) - { - ui32ClockSpeedIndexStart = (ui32ClockSpeedIndexStart + 1) % NUM_EXTRA_POWER_STATS; - } - - ui64PreClockSpeedChangeMark = 0; -} -#endif - -/*************************************************************************/ /*! -@Function _FindProcessStatsInLiveList -@Description Searches the Live Process List for a statistics structure that - matches the PID given. -@Input pid Process to search for. -@Return Pointer to stats structure for the process. -*/ /**************************************************************************/ -static PVRSRV_PROCESS_STATS* -_FindProcessStatsInLiveList(IMG_PID pid) -{ - PVRSRV_PROCESS_STATS* psProcessStats = g_psLiveList; - - while (psProcessStats != NULL) - { - if (psProcessStats->pid == pid) - { - return psProcessStats; - } - - psProcessStats = psProcessStats->psNext; - } - - return NULL; -} /* _FindProcessStatsInLiveList */ - -/*************************************************************************/ /*! -@Function _FindProcessStatsInDeadList -@Description Searches the Dead Process List for a statistics structure that - matches the PID given. -@Input pid Process to search for. -@Return Pointer to stats structure for the process. -*/ /**************************************************************************/ -static PVRSRV_PROCESS_STATS* -_FindProcessStatsInDeadList(IMG_PID pid) -{ - PVRSRV_PROCESS_STATS* psProcessStats = g_psDeadList; - - while (psProcessStats != NULL) - { - if (psProcessStats->pid == pid) - { - return psProcessStats; - } - - psProcessStats = psProcessStats->psNext; - } - - return NULL; -} /* _FindProcessStatsInDeadList */ - -/*************************************************************************/ /*! -@Function _FindProcessStats -@Description Searches the Live and Dead Process Lists for a statistics - structure that matches the PID given. -@Input pid Process to search for. -@Return Pointer to stats structure for the process. -*/ /**************************************************************************/ -static PVRSRV_PROCESS_STATS* -_FindProcessStats(IMG_PID pid) -{ - PVRSRV_PROCESS_STATS* psProcessStats = _FindProcessStatsInLiveList(pid); - - if (psProcessStats == NULL) - { - psProcessStats = _FindProcessStatsInDeadList(pid); - } - - return psProcessStats; -} /* _FindProcessStats */ - -/*************************************************************************/ /*! -@Function _CompressMemoryUsage -@Description Reduces memory usage by deleting old statistics data. - This function requires that the list lock is not held! -*/ /**************************************************************************/ -static void -_CompressMemoryUsage(void) -{ - PVRSRV_PROCESS_STATS* psProcessStats; - PVRSRV_PROCESS_STATS* psProcessStatsToBeFreed; - IMG_UINT32 ui32ItemsRemaining; - - /* - * We hold the lock whilst checking the list, but we'll release it - * before freeing memory (as that will require the lock too)! - */ - OSLockAcquire(g_psLinkedListLock); - - /* Check that the dead list is not bigger than the max size... */ - psProcessStats = g_psDeadList; - psProcessStatsToBeFreed = NULL; - ui32ItemsRemaining = MAX_DEAD_LIST_PROCESSES; - - while (psProcessStats != NULL && ui32ItemsRemaining > 0) - { - ui32ItemsRemaining--; - if (ui32ItemsRemaining == 0) - { - /* This is the last allowed process, cut the linked list here! */ - psProcessStatsToBeFreed = psProcessStats->psNext; - psProcessStats->psNext = NULL; - } - else - { - psProcessStats = psProcessStats->psNext; - } - } - - OSLockRelease(g_psLinkedListLock); - - /* Any processes stats remaining will need to be destroyed... */ - while (psProcessStatsToBeFreed != NULL) - { - PVRSRV_PROCESS_STATS* psNextProcessStats = psProcessStatsToBeFreed->psNext; - - psProcessStatsToBeFreed->psNext = NULL; - _DestroyProcessStat(psProcessStatsToBeFreed); - psProcessStatsToBeFreed = psNextProcessStats; - } -} /* _CompressMemoryUsage */ - -/* These functions move the process stats from the live to the dead list. - * _MoveProcessToDeadList moves the entry in the global lists and - * it needs to be protected by g_psLinkedListLock. - * _MoveProcessToDeadList performs the OS calls and it - * shouldn't be used under g_psLinkedListLock because this could generate a - * lockdep warning. */ -static void -_MoveProcessToDeadList(PVRSRV_PROCESS_STATS* psProcessStats) -{ - /* Take the element out of the live list and append to the dead list... */ - _RemoveProcessStatsFromList(psProcessStats); - _AddProcessStatsToFrontOfDeadList(psProcessStats); -} /* _MoveProcessToDeadList */ - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) -/* These functions move the process stats from the dead to the live list. - * _MoveProcessToLiveList moves the entry in the global lists and - * it needs to be protected by g_psLinkedListLock. - * _MoveProcessToLiveList performs the OS calls and it - * shouldn't be used under g_psLinkedListLock because this could generate a - * lockdep warning. */ -static void -_MoveProcessToLiveList(PVRSRV_PROCESS_STATS* psProcessStats) -{ - /* Take the element out of the live list and append to the dead list... */ - _RemoveProcessStatsFromList(psProcessStats); - _AddProcessStatsToFrontOfLiveList(psProcessStats); -} /* _MoveProcessToLiveList */ -#endif - -/*************************************************************************/ /*! -@Function _AddProcessStatsToFrontOfLiveList -@Description Add a statistic to the live list head. -@Input psProcessStats Process stats to add. -*/ /**************************************************************************/ -static void -_AddProcessStatsToFrontOfLiveList(PVRSRV_PROCESS_STATS* psProcessStats) -{ - /* This function should always be called under global list lock g_psLinkedListLock. - */ - PVR_ASSERT(psProcessStats != NULL); - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - if (g_psLiveList != NULL) - { - PVR_ASSERT(psProcessStats != g_psLiveList); - OSLockAcquireNested(g_psLiveList->hLock, PROCESS_LOCK_SUBCLASS_PREV); - g_psLiveList->psPrev = psProcessStats; - OSLockRelease(g_psLiveList->hLock); - psProcessStats->psNext = g_psLiveList; - } - - g_psLiveList = psProcessStats; - - OSLockRelease(psProcessStats->hLock); -} /* _AddProcessStatsToFrontOfLiveList */ - -/*************************************************************************/ /*! -@Function _AddProcessStatsToFrontOfDeadList -@Description Add a statistic to the dead list head. -@Input psProcessStats Process stats to add. -*/ /**************************************************************************/ -static void -_AddProcessStatsToFrontOfDeadList(PVRSRV_PROCESS_STATS* psProcessStats) -{ - PVR_ASSERT(psProcessStats != NULL); - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - if (g_psDeadList != NULL) - { - PVR_ASSERT(psProcessStats != g_psDeadList); - OSLockAcquireNested(g_psDeadList->hLock, PROCESS_LOCK_SUBCLASS_PREV); - g_psDeadList->psPrev = psProcessStats; - OSLockRelease(g_psDeadList->hLock); - psProcessStats->psNext = g_psDeadList; - } - - g_psDeadList = psProcessStats; - - OSLockRelease(psProcessStats->hLock); -} /* _AddProcessStatsToFrontOfDeadList */ - -/*************************************************************************/ /*! -@Function _RemoveProcessStatsFromList -@Description Detaches a process from either the live or dead list. -@Input psProcessStats Process stats to remove. -*/ /**************************************************************************/ -static void -_RemoveProcessStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats) -{ - PVR_ASSERT(psProcessStats != NULL); - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - /* Remove the item from the linked lists... */ - if (g_psLiveList == psProcessStats) - { - g_psLiveList = psProcessStats->psNext; - - if (g_psLiveList != NULL) - { - PVR_ASSERT(psProcessStats != g_psLiveList); - OSLockAcquireNested(g_psLiveList->hLock, PROCESS_LOCK_SUBCLASS_PREV); - g_psLiveList->psPrev = NULL; - OSLockRelease(g_psLiveList->hLock); - - } - } - else if (g_psDeadList == psProcessStats) - { - g_psDeadList = psProcessStats->psNext; - - if (g_psDeadList != NULL) - { - PVR_ASSERT(psProcessStats != g_psDeadList); - OSLockAcquireNested(g_psDeadList->hLock, PROCESS_LOCK_SUBCLASS_PREV); - g_psDeadList->psPrev = NULL; - OSLockRelease(g_psDeadList->hLock); - } - } - else - { - PVRSRV_PROCESS_STATS* psNext = psProcessStats->psNext; - PVRSRV_PROCESS_STATS* psPrev = psProcessStats->psPrev; - - if (psProcessStats->psNext != NULL) - { - PVR_ASSERT(psProcessStats != psNext); - OSLockAcquireNested(psNext->hLock, PROCESS_LOCK_SUBCLASS_NEXT); - psProcessStats->psNext->psPrev = psPrev; - OSLockRelease(psNext->hLock); - } - if (psProcessStats->psPrev != NULL) - { - PVR_ASSERT(psProcessStats != psPrev); - OSLockAcquireNested(psPrev->hLock, PROCESS_LOCK_SUBCLASS_PREV); - psProcessStats->psPrev->psNext = psNext; - OSLockRelease(psPrev->hLock); - } - } - - - /* Reset the pointers in this cell, as it is not attached to anything */ - psProcessStats->psNext = NULL; - psProcessStats->psPrev = NULL; - - OSLockRelease(psProcessStats->hLock); - -} /* _RemoveProcessStatsFromList */ - -static PVRSRV_ERROR -_AllocateProcessStats(PVRSRV_PROCESS_STATS **ppsProcessStats, IMG_PID ownerPid) -{ - PVRSRV_ERROR eError; - PVRSRV_PROCESS_STATS *psProcessStats; - - psProcessStats = OSAllocZMemNoStats(sizeof(PVRSRV_PROCESS_STATS)); - PVR_RETURN_IF_NOMEM(psProcessStats); - - psProcessStats->pid = ownerPid; - psProcessStats->ui32RefCount = 1; - - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = 1; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS] = 1; - - eError = OSLockCreateNoStats(&psProcessStats->hLock); - PVR_GOTO_IF_ERROR(eError, e0); - - *ppsProcessStats = psProcessStats; - return PVRSRV_OK; - -e0: - OSFreeMemNoStats(psProcessStats); - return PVRSRV_ERROR_OUT_OF_MEMORY; -} - -/*************************************************************************/ /*! -@Function _DestroyProcessStat -@Description Frees memory and resources held by a process statistic. -@Input psProcessStats Process stats to destroy. -*/ /**************************************************************************/ -static void -_DestroyProcessStat(PVRSRV_PROCESS_STATS* psProcessStats) -{ - PVR_ASSERT(psProcessStats != NULL); - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - /* Free the memory statistics... */ -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - while (psProcessStats->psMemoryRecords) - { - List_PVRSRV_MEM_ALLOC_REC_Remove(psProcessStats->psMemoryRecords); - } -#endif - OSLockRelease(psProcessStats->hLock); - - /*Destroy the lock */ - OSLockDestroyNoStats(psProcessStats->hLock); - - /* Free the memory... */ - OSFreeMemNoStats(psProcessStats); -} /* _DestroyProcessStat */ - -#if defined(ENABLE_DEBUGFS_PIDS) -static inline void -_createStatsFiles(PVRSRV_OS_STAT_ENTRY* psStatsEntries, - DI_PFN_SHOW pfnStatsShow) -{ - PVRSRV_ERROR eError; - DI_ITERATOR_CB sIterator = {.pfnShow = pfnStatsShow}; - -#if defined(PVRSRV_ENABLE_PERPID_STATS) - eError = DICreateEntry("process_stats", psStatsEntries->psStatsDIGroup, - &sIterator, - GET_STAT_ENTRY_ID(PVRSRV_STAT_TYPE_PROCESS), - DI_ENTRY_TYPE_GENERIC, - &psStatsEntries->psProcessStatsDIEntry); - PVR_LOG_IF_ERROR(eError, "DICreateEntry (1)"); -#endif - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) - eError = DICreateEntry("cache_ops_exec", psStatsEntries->psStatsDIGroup, - &sIterator, - GET_STAT_ENTRY_ID(PVRSRV_STAT_TYPE_CACHEOP), - DI_ENTRY_TYPE_GENERIC, - &psStatsEntries->psCacheOpStatsDIEntry); - PVR_LOG_IF_ERROR(eError, "DICreateEntry (2)"); -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - eError = DICreateEntry("mem_area", psStatsEntries->psStatsDIGroup, - &sIterator, - GET_STAT_ENTRY_ID(PVRSRV_STAT_TYPE_MEMORY), - DI_ENTRY_TYPE_GENERIC, - &psStatsEntries->psMemStatsDIEntry); - PVR_LOG_IF_ERROR(eError, "DICreateEntry (3)"); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - eError = DICreateEntry("gpu_mem_area", psStatsEntries->psStatsDIGroup, - &sIterator, - GET_STAT_ENTRY_ID(PVRSRV_STAT_TYPE_RIMEMORY), - DI_ENTRY_TYPE_GENERIC, - &psStatsEntries->psRIMemStatsDIEntry); - PVR_LOG_IF_ERROR(eError, "DICreateEntry (4)"); -#endif -} - -static inline void -_createStatisticsEntries(void) -{ - PVRSRV_ERROR eError; - - eError = DICreateGroup("proc_stats", NULL, &psProcStatsDIGroup); - PVR_LOG_IF_ERROR(eError, "DICreateGroup (1)"); - eError = DICreateGroup("live_pids_stats", psProcStatsDIGroup, - &gsLiveStatEntries.psStatsDIGroup); - PVR_LOG_IF_ERROR(eError, "DICreateGroup (2)"); - eError = DICreateGroup("retired_pids_stats", psProcStatsDIGroup, - &gsRetiredStatEntries.psStatsDIGroup); - PVR_LOG_IF_ERROR(eError, "DICreateGroup (3)"); - - _createStatsFiles(&gsLiveStatEntries, GenericStatsPrintElementsLive); - _createStatsFiles(&gsRetiredStatEntries, GenericStatsPrintElementsRetired); - - _prepareStatsPrivateData(); -} - -static inline void -_removeStatsFiles(PVRSRV_OS_STAT_ENTRY* psStatsEntries) -{ -#if defined(PVRSRV_ENABLE_PERPID_STATS) - DIDestroyEntry(psStatsEntries->psProcessStatsDIEntry); - psStatsEntries->psProcessStatsDIEntry = NULL; -#endif - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) - DIDestroyEntry(psStatsEntries->psCacheOpStatsDIEntry); - psStatsEntries->psCacheOpStatsDIEntry = NULL; -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - DIDestroyEntry(psStatsEntries->psMemStatsDIEntry); - psStatsEntries->psMemStatsDIEntry = NULL; -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - DIDestroyEntry(psStatsEntries->psRIMemStatsDIEntry); - psStatsEntries->psRIMemStatsDIEntry = NULL; -#endif -} - -static inline void -_removeStatisticsEntries(void) -{ - _removeStatsFiles(&gsLiveStatEntries); - _removeStatsFiles(&gsRetiredStatEntries); - - DIDestroyGroup(gsLiveStatEntries.psStatsDIGroup); - gsLiveStatEntries.psStatsDIGroup = NULL; - DIDestroyGroup(gsRetiredStatEntries.psStatsDIGroup); - gsRetiredStatEntries.psStatsDIGroup = NULL; - DIDestroyGroup(psProcStatsDIGroup); - psProcStatsDIGroup = NULL; -} -#endif - -/*************************************************************************/ /*! -@Function PVRSRVStatsInitialise -@Description Entry point for initialising the statistics module. -@Return Standard PVRSRV_ERROR error code. -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVStatsInitialise(void) -{ - PVRSRV_ERROR error; - - PVR_ASSERT(g_psLiveList == NULL); - PVR_ASSERT(g_psDeadList == NULL); - PVR_ASSERT(g_psLinkedListLock == NULL); - PVR_ASSERT(gpsSizeTrackingHashTable == NULL); - PVR_ASSERT(bProcessStatsInitialised == IMG_FALSE); - - /* We need a lock to protect the linked lists... */ - error = OSLockCreate(&g_psLinkedListLock); - PVR_GOTO_IF_ERROR(error, return_); - - /* We also need a lock to protect the hash table used for size tracking. */ - error = OSLockCreate(&gpsSizeTrackingHashTableLock); - PVR_GOTO_IF_ERROR(error, detroy_linked_list_lock_); - - /* We also need a lock to protect the GlobalStat counters */ - error = OSLockCreate(&gsGlobalStats.hGlobalStatsLock); - PVR_GOTO_IF_ERROR(error, destroy_hashtable_lock_); - - /* Flag that we are ready to start monitoring memory allocations. */ - - gpsSizeTrackingHashTable = HASH_Create(HASH_INITIAL_SIZE); - PVR_GOTO_IF_NOMEM(gpsSizeTrackingHashTable, error, destroy_stats_lock_); - - OSCachedMemSet(asClockSpeedChanges, 0, sizeof(asClockSpeedChanges)); - - bProcessStatsInitialised = IMG_TRUE; -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - /* Register our 'system' PID to hold driver-wide alloc stats */ - _RegisterProcess(&g_hDriverProcessStats, PVR_SYS_ALLOC_PID); -#endif - -#if defined(ENABLE_DEBUGFS_PIDS) - _createStatisticsEntries(); -#endif - -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) - { - DI_ITERATOR_CB sIterator = {.pfnShow = RawProcessStatsPrintElements}; - error = DICreateEntry("memtrack_stats", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &psProcStatsDIEntry); - PVR_LOG_IF_ERROR(error, "DICreateEntry (1)"); - } -#endif - - { - DI_ITERATOR_CB sIterator = {.pfnShow = PowerStatsPrintElements}; - /* Create power stats entry... */ - error = DICreateEntry("power_timing_stats", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &psPowerStatsDIEntry); - PVR_LOG_IF_ERROR(error, "DICreateEntry (2)"); - } - - { - DI_ITERATOR_CB sIterator = {.pfnShow = GlobalStatsPrintElements}; - error = DICreateEntry("driver_stats", NULL, &sIterator, NULL, - DI_ENTRY_TYPE_GENERIC, &psGlobalMemDIEntry); - PVR_LOG_IF_ERROR(error, "DICreateEntry (3)"); - } - - return PVRSRV_OK; - -destroy_stats_lock_: - OSLockDestroy(gsGlobalStats.hGlobalStatsLock); - gsGlobalStats.hGlobalStatsLock = NULL; -destroy_hashtable_lock_: - OSLockDestroy(gpsSizeTrackingHashTableLock); - gpsSizeTrackingHashTableLock = NULL; -detroy_linked_list_lock_: - OSLockDestroy(g_psLinkedListLock); - g_psLinkedListLock = NULL; -return_: - return error; - -} - -static PVRSRV_ERROR _DumpAllVMallocEntries (uintptr_t k, uintptr_t v, void* pvPriv) -{ -#if defined(PVRSRV_NEED_PVR_DPF) || defined(DOXYGEN) - _PVR_STATS_TRACKING_HASH_ENTRY *psNewTrackingHashEntry = (_PVR_STATS_TRACKING_HASH_ENTRY *)(uintptr_t)v; - IMG_UINT64 uiCpuVAddr = (IMG_UINT64)k; - - PVR_DPF((PVR_DBG_ERROR, "%s: " IMG_SIZE_FMTSPEC " bytes @ 0x%" IMG_UINT64_FMTSPECx " (PID %u)", __func__, - psNewTrackingHashEntry->uiSizeInBytes, - uiCpuVAddr, - psNewTrackingHashEntry->uiPid)); - - PVR_UNREFERENCED_PARAMETER(pvPriv); -#endif - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function PVRSRVStatsDestroy -@Description Method for destroying the statistics module data. -*/ /**************************************************************************/ -void -PVRSRVStatsDestroy(void) -{ - PVR_ASSERT(bProcessStatsInitialised); - -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) - if (psProcStatsDIEntry != NULL) - { - DIDestroyEntry(psProcStatsDIEntry); - psProcStatsDIEntry = NULL; - } -#endif - - /* Destroy the power stats entry... */ - if (psPowerStatsDIEntry!=NULL) - { - DIDestroyEntry(psPowerStatsDIEntry); - psPowerStatsDIEntry = NULL; - } - - /* Destroy the global data entry */ - if (psGlobalMemDIEntry!=NULL) - { - DIDestroyEntry(psGlobalMemDIEntry); - psGlobalMemDIEntry = NULL; - } - -#if defined(ENABLE_DEBUGFS_PIDS) - _removeStatisticsEntries(); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - /* Deregister our 'system' PID which holds driver-wide alloc stats */ - PVRSRVStatsDeregisterProcess(g_hDriverProcessStats); -#endif - - /* Stop monitoring memory allocations... */ - bProcessStatsInitialised = IMG_FALSE; - - /* Destroy the locks... */ - if (g_psLinkedListLock != NULL) - { - OSLockDestroy(g_psLinkedListLock); - g_psLinkedListLock = NULL; - } - - /* Free the live and dead lists... */ - while (g_psLiveList != NULL) - { - PVRSRV_PROCESS_STATS* psProcessStats = g_psLiveList; - _RemoveProcessStatsFromList(psProcessStats); - _DestroyProcessStat(psProcessStats); - } - - while (g_psDeadList != NULL) - { - PVRSRV_PROCESS_STATS* psProcessStats = g_psDeadList; - _RemoveProcessStatsFromList(psProcessStats); - _DestroyProcessStat(psProcessStats); - } - - if (gpsSizeTrackingHashTable != NULL) - { - /* Dump all remaining entries in HASH table (list any remaining vmallocs) */ - HASH_Iterate(gpsSizeTrackingHashTable, (HASH_pfnCallback)_DumpAllVMallocEntries, NULL); - HASH_Delete(gpsSizeTrackingHashTable); - } - if (gpsSizeTrackingHashTableLock != NULL) - { - OSLockDestroy(gpsSizeTrackingHashTableLock); - gpsSizeTrackingHashTableLock = NULL; - } - - if (NULL != gsGlobalStats.hGlobalStatsLock) - { - OSLockDestroy(gsGlobalStats.hGlobalStatsLock); - gsGlobalStats.hGlobalStatsLock = NULL; - } - -} - -static void _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes) -{ -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - IMG_UINT64 ui64InitialSize; -#endif - - OSLockAcquire(gsGlobalStats.hGlobalStatsLock); - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - ui64InitialSize = GET_GPUMEM_GLOBAL_STAT_VALUE(); -#endif - - switch (eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_KMALLOC, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_VMALLOC, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT: - DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT, uiBytes); - break; - - default: - PVR_ASSERT(0); - break; - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - { - IMG_UINT64 ui64Size = GET_GPUMEM_GLOBAL_STAT_VALUE(); - if (ui64Size != ui64InitialSize) - { - TracepointUpdateGPUMemGlobal(0, ui64Size); - } - } -#endif - - OSLockRelease(gsGlobalStats.hGlobalStatsLock); -} - -static void _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes) -{ -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - IMG_UINT64 ui64InitialSize; -#endif - - OSLockAcquire(gsGlobalStats.hGlobalStatsLock); - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - ui64InitialSize = GET_GPUMEM_GLOBAL_STAT_VALUE(); -#endif - - switch (eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_KMALLOC, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_VMALLOC, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL, uiBytes); - break; - - case PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT: - INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats, PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT, uiBytes); - break; - - default: - PVR_ASSERT(0); - break; - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - { - IMG_UINT64 ui64Size = GET_GPUMEM_GLOBAL_STAT_VALUE(); - if (ui64Size != ui64InitialSize) - { - TracepointUpdateGPUMemGlobal(0, ui64Size); - } - } -#endif - - OSLockRelease(gsGlobalStats.hGlobalStatsLock); -} - -static PVRSRV_ERROR -_RegisterProcess(IMG_HANDLE *phProcessStats, IMG_PID ownerPid) -{ - PVRSRV_PROCESS_STATS* psProcessStats=NULL; - PVRSRV_ERROR eError; - - PVR_ASSERT(phProcessStats != NULL); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Register process PID %d [%s]", - __func__, ownerPid, (ownerPid == PVR_SYS_ALLOC_PID) - ? "system" : OSGetCurrentClientProcessNameKM())); - - /* Check the PID has not already moved to the dead list... */ - OSLockAcquire(g_psLinkedListLock); - psProcessStats = _FindProcessStatsInDeadList(ownerPid); - if (psProcessStats != NULL) - { - /* Move it back onto the live list! */ - _RemoveProcessStatsFromList(psProcessStats); - _AddProcessStatsToFrontOfLiveList(psProcessStats); - } - else - { - /* Check the PID is not already registered in the live list... */ - psProcessStats = _FindProcessStatsInLiveList(ownerPid); - } - - /* If the PID is on the live list then just increment the ref count and return... */ - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - psProcessStats->ui32RefCount++; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount; - UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS]); - OSLockRelease(psProcessStats->hLock); - OSLockRelease(g_psLinkedListLock); - - *phProcessStats = psProcessStats; - - return PVRSRV_OK; - } - OSLockRelease(g_psLinkedListLock); - - /* Allocate a new node structure and initialise it... */ - eError = _AllocateProcessStats(&psProcessStats, ownerPid); - PVR_GOTO_IF_ERROR(eError, e0); - - /* Add it to the live list... */ - OSLockAcquire(g_psLinkedListLock); - _AddProcessStatsToFrontOfLiveList(psProcessStats); - OSLockRelease(g_psLinkedListLock); - - /* Done */ - *phProcessStats = (IMG_HANDLE) psProcessStats; - - return PVRSRV_OK; - -e0: - *phProcessStats = (IMG_HANDLE) NULL; - return PVRSRV_ERROR_OUT_OF_MEMORY; -} /* _RegisterProcess */ - -/*************************************************************************/ /*! -@Function PVRSRVStatsRegisterProcess -@Description Register a process into the list statistics list. -@Output phProcessStats Handle to the process to be used to deregister. -@Return Standard PVRSRV_ERROR error code. -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVStatsRegisterProcess(IMG_HANDLE* phProcessStats) -{ - return _RegisterProcess(phProcessStats, OSGetCurrentClientProcessIDKM()); -} - -/*************************************************************************/ /*! -@Function PVRSRVStatsDeregisterProcess -@Input hProcessStats Handle to the process returned when registered. -@Description Method for destroying the statistics module data. -*/ /**************************************************************************/ -void -PVRSRVStatsDeregisterProcess(IMG_HANDLE hProcessStats) -{ - PVR_DPF((PVR_DBG_MESSAGE, "%s: Deregister process entered PID %d [%s]", - __func__, OSGetCurrentClientProcessIDKM(), - OSGetCurrentProcessName())); - - if (hProcessStats != (IMG_HANDLE) NULL) - { - PVRSRV_PROCESS_STATS* psProcessStats = (PVRSRV_PROCESS_STATS*) hProcessStats; - - /* Lower the reference count, if zero then move it to the dead list */ - OSLockAcquire(g_psLinkedListLock); - if (psProcessStats->ui32RefCount > 0) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - psProcessStats->ui32RefCount--; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount; - -#if !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - if (psProcessStats->ui32RefCount == 0) - { - OSLockRelease(psProcessStats->hLock); - _MoveProcessToDeadList(psProcessStats); - }else -#endif - { - OSLockRelease(psProcessStats->hLock); - } - } - OSLockRelease(g_psLinkedListLock); - - /* Check if the dead list needs to be reduced */ - _CompressMemoryUsage(); - } -} /* PVRSRVStatsDeregisterProcess */ - -void -PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType, - void *pvCpuVAddr, - IMG_CPU_PHYADDR sCpuPAddr, - size_t uiBytes, - void *pvPrivateData, - IMG_PID currentPid - DEBUG_MEMSTATS_PARAMS) -{ -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid(); - PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_MEM_ALLOC_REC* psRecord = NULL; - PVRSRV_PROCESS_STATS* psProcessStats; - enum { PVRSRV_PROC_NOTFOUND, - PVRSRV_PROC_FOUND, - PVRSRV_PROC_RESURRECTED - } eProcSearch = PVRSRV_PROC_FOUND; - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - IMG_UINT64 ui64InitialSize; -#endif - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Called when process statistics module is not initialised", - __func__)); -#endif - return; - } - - /* - * To prevent a recursive loop, we make the memory allocations for our - * memstat records via OSAllocMemNoStats(), which does not try to - * create a memstat record entry. - */ - - /* Allocate the memory record... */ - psRecord = OSAllocZMemNoStats(sizeof(PVRSRV_MEM_ALLOC_REC)); - if (psRecord == NULL) - { - return; - } - - psRecord->eAllocType = eAllocType; - psRecord->pvCpuVAddr = pvCpuVAddr; - psRecord->sCpuPAddr.uiAddr = sCpuPAddr.uiAddr; - psRecord->uiBytes = uiBytes; - psRecord->pvPrivateData = pvPrivateData; - - psRecord->pid = currentPid; - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON) - psRecord->pvAllocdFromFile = pvAllocFromFile; - psRecord->ui32AllocdFromLine = ui32AllocFromLine; -#endif - - _increase_global_stat(eAllocType, uiBytes); - /* Lock while we find the correct process... */ - OSLockAcquire(g_psLinkedListLock); - - if (psPVRSRVData) - { - if ((currentPid == psPVRSRVData->cleanupThreadPid) && - (currentCleanupPid != 0)) - { - psProcessStats = _FindProcessStats(currentCleanupPid); - } - else - { - psProcessStats = _FindProcessStatsInLiveList(currentPid); - if (!psProcessStats) - { - psProcessStats = _FindProcessStatsInDeadList(currentPid); - eProcSearch = PVRSRV_PROC_RESURRECTED; - } - } - } - else - { - psProcessStats = _FindProcessStatsInLiveList(currentPid); - if (!psProcessStats) - { - psProcessStats = _FindProcessStatsInDeadList(currentPid); - eProcSearch = PVRSRV_PROC_RESURRECTED; - } - } - - if (psProcessStats == NULL) - { - eProcSearch = PVRSRV_PROC_NOTFOUND; - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Process stat increment called for 'unknown' process PID(%d)", - __func__, currentPid)); - - if (_AllocateProcessStats(&psProcessStats, currentPid) != PVRSRV_OK) - { - OSLockRelease(g_psLinkedListLock); - PVR_DPF((PVR_DBG_ERROR, - "%s UNABLE TO CREATE process_stats entry for pid %d [%s] (" IMG_SIZE_FMTSPEC " bytes)", - __func__, currentPid, OSGetCurrentProcessName(), uiBytes)); - goto free_record; - } - - /* Add it to the live list... */ - _AddProcessStatsToFrontOfLiveList(psProcessStats); - - OSLockRelease(g_psLinkedListLock); - -#else /* defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) */ - OSLockRelease(g_psLinkedListLock); - goto free_record; -#endif /* defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) */ - } - else - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - if (eProcSearch == PVRSRV_PROC_RESURRECTED) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Process stat incremented on 'dead' process PID(%d)", - __func__, currentPid)); - /* Move process from dead list to live list */ - _MoveProcessToLiveList(psProcessStats); - } -#endif - OSLockRelease(g_psLinkedListLock); - } - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - /* Insert the memory record... */ - if (psRecord != NULL) - { - List_PVRSRV_MEM_ALLOC_REC_Insert(&psProcessStats->psMemoryRecords, psRecord); - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - ui64InitialSize = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); -#endif - - /* Update the memory watermarks... */ - switch (eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_KMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: - { - if (psRecord != NULL) - { - psRecord->ui64Key = sCpuPAddr.uiAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: - { - if (psRecord != NULL) - { - psRecord->ui64Key = sCpuPAddr.uiAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: - { - if (psRecord != NULL) - { - psRecord->ui64Key = sCpuPAddr.uiAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: - { - if (psRecord != NULL) - { - if (pvCpuVAddr == NULL) - { - break; - } - psRecord->ui64Key = (IMG_UINT64)(uintptr_t)pvCpuVAddr; - } - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - default: - { - PVR_ASSERT(0); - } - break; - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - if (psProcessStats->pid != PVR_SYS_ALLOC_PID) - { - IMG_UINT64 ui64Size = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); - if (ui64Size != ui64InitialSize) - { - TracepointUpdateGPUMemPerProcess(0, psProcessStats->pid, ui64Size); - } - } -#endif - - OSLockRelease(psProcessStats->hLock); - - return; - -free_record: - if (psRecord != NULL) - { - OSFreeMemNoStats(psRecord); - } -#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */ -} /* PVRSRVStatsAddMemAllocRecord */ - -void -PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType, - IMG_UINT64 ui64Key, - IMG_PID currentPid) -{ -#if defined(PVRSRV_ENABLE_MEMORY_STATS) - IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid(); - PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_PROCESS_STATS* psProcessStats = NULL; - PVRSRV_MEM_ALLOC_REC* psRecord = NULL; - IMG_BOOL bFound = IMG_FALSE; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Called when process statistics module is not initialised", - __func__)); -#endif - return; - } - - /* Lock while we find the correct process and remove this record... */ - OSLockAcquire(g_psLinkedListLock); - - if (psPVRSRVData) - { - if ((currentPid == psPVRSRVData->cleanupThreadPid) && - (currentCleanupPid != 0)) - { - psProcessStats = _FindProcessStats(currentCleanupPid); - } - else - { - psProcessStats = _FindProcessStats(currentPid); - } - } - else - { - psProcessStats = _FindProcessStats(currentPid); - } - if (psProcessStats != NULL) - { - psRecord = psProcessStats->psMemoryRecords; - while (psRecord != NULL) - { - if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType) - { - bFound = IMG_TRUE; - break; - } - - psRecord = psRecord->psNext; - } - } - - /* If not found, we need to do a full search in case it was allocated to a different PID... */ - if (!bFound) - { - PVRSRV_PROCESS_STATS* psProcessStatsAlreadyChecked = psProcessStats; - - /* Search all live lists first... */ - psProcessStats = g_psLiveList; - while (psProcessStats != NULL) - { - if (psProcessStats != psProcessStatsAlreadyChecked) - { - psRecord = psProcessStats->psMemoryRecords; - while (psRecord != NULL) - { - if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType) - { - bFound = IMG_TRUE; - break; - } - - psRecord = psRecord->psNext; - } - } - - if (bFound) - { - break; - } - - psProcessStats = psProcessStats->psNext; - } - - /* If not found, then search all dead lists next... */ - if (!bFound) - { - psProcessStats = g_psDeadList; - while (psProcessStats != NULL) - { - if (psProcessStats != psProcessStatsAlreadyChecked) - { - psRecord = psProcessStats->psMemoryRecords; - while (psRecord != NULL) - { - if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType) - { - bFound = IMG_TRUE; - break; - } - - psRecord = psRecord->psNext; - } - } - - if (bFound) - { - break; - } - - psProcessStats = psProcessStats->psNext; - } - } - } - - /* Update the watermark and remove this record...*/ - if (bFound) - { - _decrease_global_stat(eAllocType, psRecord->uiBytes); - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - _DecreaseProcStatValue(eAllocType, - psProcessStats, - psRecord->uiBytes); - - List_PVRSRV_MEM_ALLOC_REC_Remove(psRecord); - OSLockRelease(psProcessStats->hLock); - OSLockRelease(g_psLinkedListLock); - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* If all stats are now zero, remove the entry for this thread */ - if (psProcessStats->ui32StatAllocFlags == 0) - { - OSLockAcquire(g_psLinkedListLock); - _MoveProcessToDeadList(psProcessStats); - OSLockRelease(g_psLinkedListLock); - - /* Check if the dead list needs to be reduced */ - _CompressMemoryUsage(); - } -#endif - /* - * Free the record outside the lock so we don't deadlock and so we - * reduce the time the lock is held. - */ - OSFreeMemNoStats(psRecord); - } - else - { - OSLockRelease(g_psLinkedListLock); - } - -#else -PVR_UNREFERENCED_PARAMETER(eAllocType); -PVR_UNREFERENCED_PARAMETER(ui64Key); -#endif -} /* PVRSRVStatsRemoveMemAllocRecord */ - -void -PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_UINT64 uiCpuVAddr, - IMG_PID uiPid) -{ - IMG_BOOL bRes = IMG_FALSE; - _PVR_STATS_TRACKING_HASH_ENTRY *psNewTrackingHashEntry = NULL; - - if (!bProcessStatsInitialised || (gpsSizeTrackingHashTable == NULL)) - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Called when process statistics module is not initialised", - __func__)); -#endif - return; - } - - /* Alloc untracked memory for the new hash table entry */ - psNewTrackingHashEntry = (_PVR_STATS_TRACKING_HASH_ENTRY *)OSAllocMemNoStats(sizeof(*psNewTrackingHashEntry)); - if (psNewTrackingHashEntry == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "*** %s : @ line %d Failed to alloc memory for psNewTrackingHashEntry!", - __func__, __LINE__)); - return; - } - - /* Fill-in the size of the allocation and PID of the allocating process */ - psNewTrackingHashEntry->uiSizeInBytes = uiBytes; - psNewTrackingHashEntry->uiPid = uiPid; - OSLockAcquire(gpsSizeTrackingHashTableLock); - /* Insert address of the new struct into the hash table */ - bRes = HASH_Insert(gpsSizeTrackingHashTable, uiCpuVAddr, (uintptr_t)psNewTrackingHashEntry); - OSLockRelease(gpsSizeTrackingHashTableLock); - if (bRes) - { - PVRSRVStatsIncrMemAllocStat(eAllocType, uiBytes, uiPid); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "*** %s : @ line %d HASH_Insert() failed!", - __func__, __LINE__)); - /* Free the memory allocated for psNewTrackingHashEntry, as we - * failed to insert it into the Hash table. - */ - OSFreeMemNoStats(psNewTrackingHashEntry); - } -} - -void -PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_PID currentPid) - -{ - IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid(); - PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_PROCESS_STATS* psProcessStats = NULL; - enum { PVRSRV_PROC_NOTFOUND, - PVRSRV_PROC_FOUND, - PVRSRV_PROC_RESURRECTED - } __maybe_unused eProcSearch = PVRSRV_PROC_FOUND; - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - IMG_UINT64 ui64InitialSize; -#endif - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Called when process statistics module is not initialised", - __func__)); -#endif - return; - } - - _increase_global_stat(eAllocType, uiBytes); - OSLockAcquire(g_psLinkedListLock); - if (psPVRSRVData) - { - if ((currentPid == psPVRSRVData->cleanupThreadPid) && - (currentCleanupPid != 0)) - { - psProcessStats = _FindProcessStats(currentCleanupPid); - } - else - { - psProcessStats = _FindProcessStatsInLiveList(currentPid); - if (!psProcessStats) - { - psProcessStats = _FindProcessStatsInDeadList(currentPid); - eProcSearch = PVRSRV_PROC_RESURRECTED; - } - } - } - else - { - psProcessStats = _FindProcessStatsInLiveList(currentPid); - if (!psProcessStats) - { - psProcessStats = _FindProcessStatsInDeadList(currentPid); - eProcSearch = PVRSRV_PROC_RESURRECTED; - } - } - - if (psProcessStats == NULL) - { - eProcSearch = PVRSRV_PROC_NOTFOUND; - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - PVR_DPF((PVR_DBG_WARNING, - "%s: Process stat increment called for 'unknown' process PID(%d)", - __func__, currentPid)); - - if (bProcessStatsInitialised) - { - if (_AllocateProcessStats(&psProcessStats, currentPid) != PVRSRV_OK) - { - OSLockRelease(g_psLinkedListLock); - return; - } - /* Add it to the live list... */ - _AddProcessStatsToFrontOfLiveList(psProcessStats); - } -#else - OSLockRelease(g_psLinkedListLock); -#endif /* defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) */ - - } - - if (psProcessStats != NULL) - { -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - if (eProcSearch == PVRSRV_PROC_RESURRECTED) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Process stat incremented on 'dead' process PID(%d)", - __func__, currentPid)); - - /* Move process from dead list to live list */ - _MoveProcessToLiveList(psProcessStats); - } -#endif - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - /* Release the list lock as soon as we acquire the process lock, - * this ensures if the process is in deadlist the entry cannot be - * deleted or modified - */ - OSLockRelease(g_psLinkedListLock); - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - ui64InitialSize = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); -#endif - - /* Update the memory watermarks... */ - switch (eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_KMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, (IMG_UINT32)uiBytes); - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT: - { - INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT, (IMG_UINT32)uiBytes); - psProcessStats->ui32StatAllocFlags |= (IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - break; - - default: - { - PVR_ASSERT(0); - } - break; - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - if (psProcessStats->pid != PVR_SYS_ALLOC_PID) - { - IMG_UINT64 ui64Size = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); - if (ui64Size != ui64InitialSize) - { - TracepointUpdateGPUMemPerProcess(0, psProcessStats->pid, - ui64Size); - } - } -#endif - - OSLockRelease(psProcessStats->hLock); - } - -} - -static void -_DecreaseProcStatValue(PVRSRV_MEM_ALLOC_TYPE eAllocType, - PVRSRV_PROCESS_STATS* psProcessStats, - IMG_UINT32 uiBytes) -{ -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - IMG_UINT64 ui64InitialSize = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); -#endif - - switch (eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_KMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMALLOC-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, (IMG_UINT32)uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - case PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT: - { - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT, (IMG_UINT32)uiBytes); - if (psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT] == 0) - { - psProcessStats->ui32StatAllocFlags &= ~(IMG_UINT32)(1 << (PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT-PVRSRV_PROCESS_STAT_TYPE_KMALLOC)); - } - } - break; - - default: - { - PVR_ASSERT(0); - } - break; - } - -#if defined(ENABLE_GPU_MEM_TRACEPOINT) - if (psProcessStats->pid != PVR_SYS_ALLOC_PID) - { - IMG_UINT64 ui64Size = GET_GPUMEM_PERPID_STAT_VALUE(psProcessStats); - if (ui64Size != ui64InitialSize) - { - TracepointUpdateGPUMemPerProcess(0, psProcessStats->pid, ui64Size); - } - } -#endif -} - -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) -int RawProcessStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_PROCESS_STATS *psProcessStats; - - DIPrintf(psEntry, - "%s,%s,%s,%s,%s,%s,%s\n", - "PID", - "MemoryUsageKMalloc", // PVRSRV_PROCESS_STAT_TYPE_KMALLOC - "MemoryUsageAllocPTMemoryUMA", // PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA - "MemoryUsageAllocPTMemoryLMA", // PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA - "MemoryUsageAllocGPUMemLMA", // PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES - "MemoryUsageAllocGPUMemUMA", // PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES - "MemoryUsageDmaBufImport"); // PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT - - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = g_psLiveList; - - while (psProcessStats != NULL) - { - if (psProcessStats->pid != PVR_SYS_ALLOC_PID) - { - DIPrintf(psEntry, - "%d,%d,%d,%d,%d,%d,%d\n", - psProcessStats->pid, - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES], - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_DMA_BUF_IMPORT]); - } - - psProcessStats = psProcessStats->psNext; - } - - OSLockRelease(g_psLinkedListLock); - - return 0; -} /* RawProcessStatsPrintElements */ -#endif - -void -PVRSRVStatsDecrMemKAllocStat(size_t uiBytes, - IMG_PID decrPID) -{ - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, uiBytes); - - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(decrPID); - - if (psProcessStats != NULL) - { - /* Decrement the kmalloc memory stat... */ - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes); - DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_TOTAL, uiBytes); - } - - OSLockRelease(g_psLinkedListLock); -} - -static void -_StatsDecrMemTrackedStat(_PVR_STATS_TRACKING_HASH_ENTRY *psTrackingHashEntry, - PVRSRV_MEM_ALLOC_TYPE eAllocType) -{ - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - _decrease_global_stat(eAllocType, psTrackingHashEntry->uiSizeInBytes); - - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(psTrackingHashEntry->uiPid); - - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - /* Decrement the memory stat... */ - _DecreaseProcStatValue(eAllocType, - psProcessStats, - psTrackingHashEntry->uiSizeInBytes); - OSLockRelease(psProcessStats->hLock); - } - - OSLockRelease(g_psLinkedListLock); -} - -void -PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE eAllocType, - IMG_UINT64 uiCpuVAddr) -{ - _PVR_STATS_TRACKING_HASH_ENTRY *psTrackingHashEntry = NULL; - - if (!bProcessStatsInitialised || (gpsSizeTrackingHashTable == NULL)) - { - return; - } - - OSLockAcquire(gpsSizeTrackingHashTableLock); - psTrackingHashEntry = (_PVR_STATS_TRACKING_HASH_ENTRY *)HASH_Remove(gpsSizeTrackingHashTable, uiCpuVAddr); - OSLockRelease(gpsSizeTrackingHashTableLock); - if (psTrackingHashEntry) - { - _StatsDecrMemTrackedStat(psTrackingHashEntry, eAllocType); - OSFreeMemNoStats(psTrackingHashEntry); - } -} - -void -PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_PID currentPid) -{ - IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid(); - PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_PROCESS_STATS* psProcessStats = NULL; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - _decrease_global_stat(eAllocType, uiBytes); - - OSLockAcquire(g_psLinkedListLock); - if (psPVRSRVData) - { - if ((currentPid == psPVRSRVData->cleanupThreadPid) && - (currentCleanupPid != 0)) - { - psProcessStats = _FindProcessStats(currentCleanupPid); - } - else - { - psProcessStats = _FindProcessStats(currentPid); - } - } - else - { - psProcessStats = _FindProcessStats(currentPid); - } - - - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - /* Release the list lock as soon as we acquire the process lock, - * this ensures if the process is in deadlist the entry cannot be - * deleted or modified - */ - OSLockRelease(g_psLinkedListLock); - /* Update the memory watermarks... */ - _DecreaseProcStatValue(eAllocType, - psProcessStats, - uiBytes); - OSLockRelease(psProcessStats->hLock); - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* If all stats are now zero, remove the entry for this thread */ - if (psProcessStats->ui32StatAllocFlags == 0) - { - OSLockAcquire(g_psLinkedListLock); - _MoveProcessToDeadList(psProcessStats); - OSLockRelease(g_psLinkedListLock); - - /* Check if the dead list needs to be reduced */ - _CompressMemoryUsage(); - } -#endif - }else{ - OSLockRelease(g_psLinkedListLock); - } -} - -/* For now we do not want to expose the global stats API - * so we wrap it into this specific function for pooled pages. - * As soon as we need to modify the global stats directly somewhere else - * we want to replace these functions with more general ones. - */ -void -PVRSRVStatsIncrMemAllocPoolStat(size_t uiBytes) -{ - _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes); -} - -void -PVRSRVStatsDecrMemAllocPoolStat(size_t uiBytes) -{ - _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes); -} - -void -PVRSRVStatsUpdateOOMStats(IMG_UINT32 ui32OOMStatType, - IMG_PID pidOwner) -{ - PVRSRV_PROCESS_STAT_TYPE eOOMStatType = (PVRSRV_PROCESS_STAT_TYPE) ui32OOMStatType; - IMG_PID pidCurrent = pidOwner; - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - /* Lock while we find the correct process and update the record... */ - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(pidCurrent); - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - psProcessStats->i32StatValue[eOOMStatType]++; - OSLockRelease(psProcessStats->hLock); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVStatsUpdateOOMStats: Process not found for Pid=%d", pidCurrent)); - } - - OSLockRelease(g_psLinkedListLock); -} /* PVRSRVStatsUpdateOOMStats */ - -PVRSRV_ERROR -PVRSRVServerUpdateOOMStats(IMG_UINT32 ui32OOMStatType, - IMG_PID pidOwner) -{ - if (ui32OOMStatType >= PVRSRV_PROCESS_STAT_TYPE_COUNT) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVRSRVStatsUpdateOOMStats(ui32OOMStatType, pidOwner); - - return PVRSRV_OK; -} - -void -PVRSRVStatsUpdateRenderContextStats(IMG_UINT32 ui32TotalNumPartialRenders, - IMG_UINT32 ui32TotalNumOutOfMemory, - IMG_UINT32 ui32NumTAStores, - IMG_UINT32 ui32Num3DStores, - IMG_UINT32 ui32NumCDMStores, - IMG_UINT32 ui32NumTDMStores, - IMG_PID pidOwner) -{ - IMG_PID pidCurrent = pidOwner; - - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - /* Lock while we find the correct process and update the record... */ - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(pidCurrent); - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_PRS] += ui32TotalNumPartialRenders; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_OOMS] += ui32TotalNumOutOfMemory; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES] += ui32NumTAStores; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES] += ui32Num3DStores; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES]+= ui32NumCDMStores; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_TDM_STORES]+= ui32NumTDMStores; - OSLockRelease(psProcessStats->hLock); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVStatsUpdateRenderContextStats: Process not found for Pid=%d", pidCurrent)); - } - - OSLockRelease(g_psLinkedListLock); -} /* PVRSRVStatsUpdateRenderContextStats */ - -void -PVRSRVStatsUpdateZSBufferStats(IMG_UINT32 ui32NumReqByApp, - IMG_UINT32 ui32NumReqByFW, - IMG_PID owner) -{ - IMG_PID currentPid = (owner==0)?OSGetCurrentClientProcessIDKM():owner; - PVRSRV_PROCESS_STATS* psProcessStats; - - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - /* Lock while we find the correct process and update the record... */ - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(currentPid); - if (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP] += ui32NumReqByApp; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW] += ui32NumReqByFW; - OSLockRelease(psProcessStats->hLock); - } - - OSLockRelease(g_psLinkedListLock); -} /* PVRSRVStatsUpdateZSBufferStats */ - -void -PVRSRVStatsUpdateFreelistStats(IMG_UINT32 ui32NumGrowReqByApp, - IMG_UINT32 ui32NumGrowReqByFW, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32NumHighPages, - IMG_PID ownerPid) -{ - IMG_PID currentPid = (ownerPid!=0)?ownerPid:OSGetCurrentClientProcessIDKM(); - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - /* Lock while we find the correct process and update the record... */ - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(currentPid); - - if (psProcessStats != NULL) - { - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP] += ui32NumGrowReqByApp; - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW] += ui32NumGrowReqByFW; - - UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT], - (IMG_INT32) ui32InitFLPages); - - UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES], - (IMG_INT32) ui32NumHighPages); - - OSLockRelease(psProcessStats->hLock); - - } - - OSLockRelease(g_psLinkedListLock); -} /* PVRSRVStatsUpdateFreelistStats */ - - -#if defined(ENABLE_DEBUGFS_PIDS) - -int -GenericStatsPrintElementsLive(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_STAT_PV_DATA *psStatType = DIGetPrivData(psEntry); - PVRSRV_PROCESS_STATS* psProcessStats; - - PVR_UNREFERENCED_PARAMETER(pvData); - - PVR_ASSERT(psStatType->pfnStatsPrintElements != NULL); - - DIPrintf(psEntry, "%s\n", psStatType->szLiveStatsHeaderStr); - - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = g_psLiveList; - - if (psProcessStats == NULL) - { - DIPrintf(psEntry, "No Stats to display\n%s\n", g_szSeparatorStr); - } - else - { - while (psProcessStats != NULL) - { - psStatType->pfnStatsPrintElements(psEntry, psProcessStats); - psProcessStats = psProcessStats->psNext; - DIPrintf(psEntry, "%s\n", g_szSeparatorStr); - } - } - OSLockRelease(g_psLinkedListLock); - - return 0; -} - -int -GenericStatsPrintElementsRetired(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVRSRV_STAT_PV_DATA *psStatType = DIGetPrivData(psEntry); - PVRSRV_PROCESS_STATS* psProcessStats; - - PVR_UNREFERENCED_PARAMETER(pvData); - - PVR_ASSERT(psStatType->pfnStatsPrintElements != NULL); - - DIPrintf(psEntry, "%s\n", psStatType->szRetiredStatsHeaderStr); - - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = g_psDeadList; - - if (psProcessStats == NULL) - { - DIPrintf(psEntry, "No Stats to display\n%s\n", g_szSeparatorStr); - } - else - { - while (psProcessStats != NULL) - { - psStatType->pfnStatsPrintElements(psEntry, psProcessStats); - psProcessStats = psProcessStats->psNext; - DIPrintf(psEntry, "%s\n", g_szSeparatorStr); - } - } - OSLockRelease(g_psLinkedListLock); - - return 0; -} - -#if defined(PVRSRV_ENABLE_PERPID_STATS) -/*************************************************************************/ /*! -@Function ProcessStatsPrintElements -@Description Prints all elements for this process statistic record. -@Input pvStatPtr Pointer to statistics structure. -@Input pfnOSStatsPrintf Printf function to use for output. -*/ /**************************************************************************/ -void -ProcessStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats) -{ - IMG_UINT32 ui32StatNumber; - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - DIPrintf(psEntry, "PID %u\n", psProcessStats->pid); - - /* Loop through all the values and print them... */ - for (ui32StatNumber = 0; - ui32StatNumber < ARRAY_SIZE(pszProcessStatType); - ui32StatNumber++) - { - if (OSStringNCompare(pszProcessStatType[ui32StatNumber], "", 1) != 0) - { -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - if ((ui32StatNumber == PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES) || - (ui32StatNumber == PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES)) - { - /* get the stat from RI */ - IMG_INT32 ui32Total = RITotalAllocProcessKM(psProcessStats->pid, - (ui32StatNumber == PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES) - ? PHYS_HEAP_TYPE_LMA : PHYS_HEAP_TYPE_UMA); - - DIPrintf(psEntry, "%-34s%10d %8dK\n", - pszProcessStatType[ui32StatNumber], ui32Total, ui32Total>>10); - } - else -#endif - { - if (ui32StatNumber >= PVRSRV_PROCESS_STAT_TYPE_KMALLOC && - ui32StatNumber <= PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAX) - { - DIPrintf(psEntry, "%-34s%10d %8dK\n", - pszProcessStatType[ui32StatNumber], - psProcessStats->i32StatValue[ui32StatNumber], - psProcessStats->i32StatValue[ui32StatNumber] >> 10); - } - else - { - DIPrintf(psEntry, "%-34s%10d\n", - pszProcessStatType[ui32StatNumber], - psProcessStats->i32StatValue[ui32StatNumber]); - } - } - } - } - - OSLockRelease(psProcessStats->hLock); -} /* ProcessStatsPrintElements */ -#endif - -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) -void -PVRSRVStatsUpdateCacheOpStats(PVRSRV_CACHE_OP uiCacheOp, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEV_PHYADDR sDevPAddr, -#endif - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT64 ui64ExecuteTime, - IMG_BOOL bUserModeFlush, - IMG_PID ownerPid) -{ - IMG_PID currentPid = (ownerPid!=0)?ownerPid:OSGetCurrentClientProcessIDKM(); - PVRSRV_PROCESS_STATS* psProcessStats; - - /* Don't do anything if we are not initialised or we are shutting down! */ - if (!bProcessStatsInitialised) - { - return; - } - - /* Lock while we find the correct process and update the record... */ - OSLockAcquire(g_psLinkedListLock); - - psProcessStats = _FindProcessStats(currentPid); - - if (psProcessStats != NULL) - { - IMG_INT32 Idx; - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - /* Look-up next buffer write index */ - Idx = psProcessStats->uiCacheOpWriteIndex; - psProcessStats->uiCacheOpWriteIndex = INCREMENT_CACHEOP_STAT_IDX_WRAP(Idx); - - /* Store all CacheOp meta-data */ - psProcessStats->asCacheOp[Idx].uiCacheOp = uiCacheOp; -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - psProcessStats->asCacheOp[Idx].sDevVAddr = sDevVAddr; - psProcessStats->asCacheOp[Idx].sDevPAddr = sDevPAddr; -#endif - psProcessStats->asCacheOp[Idx].uiOffset = uiOffset; - psProcessStats->asCacheOp[Idx].uiSize = uiSize; - psProcessStats->asCacheOp[Idx].bUserModeFlush = bUserModeFlush; - psProcessStats->asCacheOp[Idx].ui64ExecuteTime = ui64ExecuteTime; - - OSLockRelease(psProcessStats->hLock); - } - - OSLockRelease(g_psLinkedListLock); -} /* PVRSRVStatsUpdateCacheOpStats */ - -/*************************************************************************/ /*! -@Function CacheOpStatsPrintElements -@Description Prints all elements for this process statistic CacheOp record. -@Input pvStatPtr Pointer to statistics structure. -@Input pfnOSStatsPrintf Printf function to use for output. -*/ /**************************************************************************/ -void -CacheOpStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats) -{ - IMG_CHAR *pszCacheOpType, *pszFlushType, *pszFlushMode; - IMG_INT32 i32WriteIdx, i32ReadIdx; - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - #define CACHEOP_RI_PRINTF_HEADER \ - "%-10s %-10s %-5s %-16s %-16s %-10s %-10s %-12s\n" - #define CACHEOP_RI_PRINTF \ - "%-10s %-10s %-5s 0x%-14llx 0x%-14llx 0x%-8llx 0x%-8llx %-12llu\n" -#else - #define CACHEOP_PRINTF_HEADER \ - "%-10s %-10s %-5s %-10s %-10s %-12s\n" - #define CACHEOP_PRINTF \ - "%-10s %-10s %-5s 0x%-8llx 0x%-8llx %-12llu\n" -#endif - - DIPrintf(psEntry, "PID %u\n", psProcessStats->pid); - - /* File header info */ - DIPrintf(psEntry, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - CACHEOP_RI_PRINTF_HEADER, -#else - CACHEOP_PRINTF_HEADER, -#endif - "CacheOp", - "Type", - "Mode", -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - "DevVAddr", - "DevPAddr", -#endif - "Offset", - "Size", - "Time (us)"); - - /* Take a snapshot of write index, read backwards in buffer - and wrap round at boundary */ - i32WriteIdx = psProcessStats->uiCacheOpWriteIndex; - for (i32ReadIdx = DECREMENT_CACHEOP_STAT_IDX_WRAP(i32WriteIdx); - i32ReadIdx != i32WriteIdx; - i32ReadIdx = DECREMENT_CACHEOP_STAT_IDX_WRAP(i32ReadIdx)) - { - IMG_UINT64 ui64ExecuteTime = psProcessStats->asCacheOp[i32ReadIdx].ui64ExecuteTime; - IMG_DEVMEM_SIZE_T ui64NumOfPages = psProcessStats->asCacheOp[i32ReadIdx].uiSize >> OSGetPageShift(); - - if (ui64NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC) - { - pszFlushType = "RBF.Fast"; - } - else - { - pszFlushType = "RBF.Slow"; - } - - if (psProcessStats->asCacheOp[i32ReadIdx].bUserModeFlush) - { - pszFlushMode = "UM"; - } - else - { - pszFlushMode = "KM"; - } - - switch (psProcessStats->asCacheOp[i32ReadIdx].uiCacheOp) - { - case PVRSRV_CACHE_OP_NONE: - pszCacheOpType = "None"; - break; - case PVRSRV_CACHE_OP_CLEAN: - pszCacheOpType = "Clean"; - break; - case PVRSRV_CACHE_OP_INVALIDATE: - pszCacheOpType = "Invalidate"; - break; - case PVRSRV_CACHE_OP_FLUSH: - pszCacheOpType = "Flush"; - break; - default: - pszCacheOpType = "Unknown"; - break; - } - - DIPrintf(psEntry, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - CACHEOP_RI_PRINTF, -#else - CACHEOP_PRINTF, -#endif - pszCacheOpType, - pszFlushType, - pszFlushMode, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - psProcessStats->asCacheOp[i32ReadIdx].sDevVAddr.uiAddr, - psProcessStats->asCacheOp[i32ReadIdx].sDevPAddr.uiAddr, -#endif - psProcessStats->asCacheOp[i32ReadIdx].uiOffset, - psProcessStats->asCacheOp[i32ReadIdx].uiSize, - ui64ExecuteTime); - } - -} /* CacheOpStatsPrintElements */ -#endif - -#if defined(PVRSRV_ENABLE_MEMORY_STATS) -/*************************************************************************/ /*! -@Function MemStatsPrintElements -@Description Prints all elements for the memory statistic record. -@Input pvStatPtr Pointer to statistics structure. -@Input pfnOSStatsPrintf Printf function to use for output. -*/ /**************************************************************************/ -void -MemStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats) -{ - IMG_UINT32 ui32VAddrFields = sizeof(void*)/sizeof(IMG_UINT32); - IMG_UINT32 ui32PAddrFields = sizeof(IMG_CPU_PHYADDR)/sizeof(IMG_UINT32); - PVRSRV_MEM_ALLOC_REC *psRecord; - IMG_UINT32 ui32ItemNumber; - - /* Write the header... */ - DIPrintf(psEntry, "PID "); - - DIPrintf(psEntry, "Type VAddress"); - for (ui32ItemNumber = 1; ui32ItemNumber < ui32VAddrFields; ui32ItemNumber++) - { - DIPrintf(psEntry, " "); - } - - DIPrintf(psEntry, " PAddress"); - for (ui32ItemNumber = 1; ui32ItemNumber < ui32PAddrFields; ui32ItemNumber++) - { - DIPrintf(psEntry, " "); - } - - DIPrintf(psEntry, " Size(bytes)\n"); - - psRecord = psProcessStats->psMemoryRecords; - if (psRecord == NULL) - { - DIPrintf(psEntry, "%-5d\n", psProcessStats->pid); - } - - while (psRecord != NULL) - { - IMG_BOOL bPrintStat = IMG_TRUE; - - DIPrintf(psEntry, "%-5d ", psProcessStats->pid); - - switch (psRecord->eAllocType) - { - case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: DIPrintf(psEntry, "KMALLOC "); break; - case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: DIPrintf(psEntry, "VMALLOC "); break; - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: DIPrintf(psEntry, "ALLOC_PAGES_PT_LMA "); break; - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: DIPrintf(psEntry, "ALLOC_PAGES_PT_UMA "); break; - case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: DIPrintf(psEntry, "IOREMAP_PT_LMA "); break; - case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: DIPrintf(psEntry, "VMAP_PT_UMA "); break; - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: DIPrintf(psEntry, "ALLOC_LMA_PAGES "); break; - case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: DIPrintf(psEntry, "ALLOC_UMA_PAGES "); break; - case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: DIPrintf(psEntry, "MAP_UMA_LMA_PAGES "); break; - case PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT: DIPrintf(psEntry, "DMA_BUF_IMPORT "); break; - default: DIPrintf(psEntry, "INVALID "); break; - } - - if (bPrintStat) - { - for (ui32ItemNumber = 0; ui32ItemNumber < ui32VAddrFields; ui32ItemNumber++) - { - DIPrintf(psEntry, "%08x", *(((IMG_UINT32*) &psRecord->pvCpuVAddr) + ui32VAddrFields - ui32ItemNumber - 1)); - } - DIPrintf(psEntry, " "); - - for (ui32ItemNumber = 0; ui32ItemNumber < ui32PAddrFields; ui32ItemNumber++) - { - DIPrintf(psEntry, "%08x", *(((IMG_UINT32*) &psRecord->sCpuPAddr.uiAddr) + ui32PAddrFields - ui32ItemNumber - 1)); - } - -#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON) - DIPrintf(psEntry, " " IMG_SIZE_FMTSPEC, psRecord->uiBytes); - - DIPrintf(psEntry, " %s", (IMG_CHAR*) psRecord->pvAllocdFromFile); - - DIPrintf(psEntry, " %d\n", psRecord->ui32AllocdFromLine); -#else - DIPrintf(psEntry, " " IMG_SIZE_FMTSPEC "\n", psRecord->uiBytes); -#endif - } - /* Move to next record... */ - psRecord = psRecord->psNext; - } -} /* MemStatsPrintElements */ -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -/*************************************************************************/ /*! -@Function RIMemStatsPrintElements -@Description Prints all elements for the RI Memory record. -@Input pvStatPtr Pointer to statistics structure. -@Input pfnOSStatsPrintf Printf function to use for output. -*/ /**************************************************************************/ -void RIMemStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, - PVRSRV_PROCESS_STATS *psProcessStats) -{ - IMG_CHAR *pszStatFmtText = NULL; - IMG_HANDLE *pRIHandle = NULL; - - /* Acquire RI lock */ - RILockAcquireKM(); - - /* - * Loop through the RI system to get each line of text. - */ - while (RIGetListEntryKM(psProcessStats->pid, - &pRIHandle, - &pszStatFmtText)) - { - DIPrintf(psEntry, "%s", pszStatFmtText); - } - - /* Release RI lock */ - RILockReleaseKM(); - -} /* RIMemStatsPrintElements */ -#endif - -#endif - -static IMG_UINT32 ui32FirmwareStartTimestamp; -static IMG_UINT64 ui64FirmwareIdleDuration; - -void SetFirmwareStartTime(IMG_UINT32 ui32Time) -{ - ui32FirmwareStartTimestamp = UPDATE_TIME(ui32FirmwareStartTimestamp, ui32Time); -} - -void SetFirmwareHandshakeIdleTime(IMG_UINT64 ui64Duration) -{ - ui64FirmwareIdleDuration = UPDATE_TIME(ui64FirmwareIdleDuration, ui64Duration); -} - -static INLINE void PowerStatsPrintGroup(IMG_UINT32 *pui32Stats, - OSDI_IMPL_ENTRY *psEntry, - PVRSRV_POWER_STAT_TYPE eForced, - PVRSRV_POWER_STAT_TYPE ePowerOn) -{ - IMG_UINT32 ui32Index; - - ui32Index = GET_POWER_STAT_INDEX(eForced, ePowerOn, PRE_POWER, DEVICE); - DIPrintf(psEntry, " Pre-Device: %9u\n", pui32Stats[ui32Index]); - - ui32Index = GET_POWER_STAT_INDEX(eForced, ePowerOn, PRE_POWER, SYSTEM); - DIPrintf(psEntry, " Pre-System: %9u\n", pui32Stats[ui32Index]); - - ui32Index = GET_POWER_STAT_INDEX(eForced, ePowerOn, POST_POWER, SYSTEM); - DIPrintf(psEntry, " Post-System: %9u\n", pui32Stats[ui32Index]); - - ui32Index = GET_POWER_STAT_INDEX(eForced, ePowerOn, POST_POWER, DEVICE); - DIPrintf(psEntry, " Post-Device: %9u\n", pui32Stats[ui32Index]); -} - -int PowerStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - IMG_UINT32 *pui32Stats = &aui32PowerTimingStats[0]; - IMG_UINT32 ui32Idx; - - PVR_UNREFERENCED_PARAMETER(pvData); - - DIPrintf(psEntry, "Forced Power-on Transition (nanoseconds):\n"); - PowerStatsPrintGroup(pui32Stats, psEntry, FORCED, POWER_ON); - DIPrintf(psEntry, "\n"); - - DIPrintf(psEntry, "Forced Power-off Transition (nanoseconds):\n"); - PowerStatsPrintGroup(pui32Stats, psEntry, FORCED, POWER_OFF); - DIPrintf(psEntry, "\n"); - - DIPrintf(psEntry, "Not Forced Power-on Transition (nanoseconds):\n"); - PowerStatsPrintGroup(pui32Stats, psEntry, NOT_FORCED, POWER_ON); - DIPrintf(psEntry, "\n"); - - DIPrintf(psEntry, "Not Forced Power-off Transition (nanoseconds):\n"); - PowerStatsPrintGroup(pui32Stats, psEntry, NOT_FORCED, POWER_OFF); - DIPrintf(psEntry, "\n"); - - - DIPrintf(psEntry, "FW bootup time (timer ticks): %u\n", ui32FirmwareStartTimestamp); - DIPrintf(psEntry, "Host Acknowledge Time for FW Idle Signal (timer ticks): %u\n", (IMG_UINT32)(ui64FirmwareIdleDuration)); - DIPrintf(psEntry, "\n"); - - DIPrintf(psEntry, "Last %d Clock Speed Change Timers (nanoseconds):\n", NUM_EXTRA_POWER_STATS); - DIPrintf(psEntry, "Prepare DVFS\tDVFS Change\tPost DVFS\n"); - - for (ui32Idx = ui32ClockSpeedIndexStart; ui32Idx !=ui32ClockSpeedIndexEnd; ui32Idx = (ui32Idx + 1) % NUM_EXTRA_POWER_STATS) - { - DIPrintf(psEntry, "%12llu\t%11llu\t%9llu\n",asClockSpeedChanges[ui32Idx].ui64PreClockSpeedChangeDuration, - asClockSpeedChanges[ui32Idx].ui64BetweenPreEndingAndPostStartingDuration, - asClockSpeedChanges[ui32Idx].ui64PostClockSpeedChangeDuration); - } - - return 0; -} /* PowerStatsPrintElements */ - -int GlobalStatsPrintElements(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - IMG_UINT32 ui32StatNumber; - PVR_UNREFERENCED_PARAMETER(pvData); - - OSLockAcquire(gsGlobalStats.hGlobalStatsLock); - - for (ui32StatNumber = 0; - ui32StatNumber < ARRAY_SIZE(pszDriverStatType); - ui32StatNumber++) - { - if (OSStringNCompare(pszDriverStatType[ui32StatNumber], "", 1) != 0) - { - DIPrintf(psEntry, "%-34s%12llu\n", - pszDriverStatType[ui32StatNumber], - GET_GLOBAL_STAT_VALUE(ui32StatNumber)); - } - } - - OSLockRelease(gsGlobalStats.hGlobalStatsLock); - - return 0; -} - -/*************************************************************************/ /*! -@Function PVRSRVFindProcessMemStats -@Description Using the provided PID find memory stats for that process. - Memstats will be provided for live/connected processes only. - Memstat values provided by this API relate only to the physical - memory allocated by the process and does not relate to any of - the mapped or imported memory. -@Input pid Process to search for. -@Input ArraySize Size of the array where memstat - records will be stored -@Input bAllProcessStats Flag to denote if stats for - individual process are requested - stats for all processes are - requested -@Input MemoryStats Handle to the memory where memstats - are stored. -@Output Memory statistics records for the requested pid. -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVFindProcessMemStats(IMG_PID pid, IMG_UINT32 ui32ArrSize, IMG_BOOL bAllProcessStats, IMG_UINT32 *pui32MemoryStats) -{ - IMG_INT i; - PVRSRV_PROCESS_STATS* psProcessStats; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pui32MemoryStats, "pui32MemoryStats"); - - if (bAllProcessStats) - { - PVR_LOG_RETURN_IF_FALSE(ui32ArrSize == PVRSRV_DRIVER_STAT_TYPE_COUNT, - "MemStats array size is incorrect", - PVRSRV_ERROR_INVALID_PARAMS); - - OSLockAcquire(gsGlobalStats.hGlobalStatsLock); - - for (i = 0; i < ui32ArrSize; i++) - { - pui32MemoryStats[i] = GET_GLOBAL_STAT_VALUE(i); - } - - OSLockRelease(gsGlobalStats.hGlobalStatsLock); - - return PVRSRV_OK; - } - - PVR_LOG_RETURN_IF_FALSE(ui32ArrSize == PVRSRV_PROCESS_STAT_TYPE_COUNT, - "MemStats array size is incorrect", - PVRSRV_ERROR_INVALID_PARAMS); - - OSLockAcquire(g_psLinkedListLock); - - /* Search for the given PID in the Live List */ - psProcessStats = _FindProcessStatsInLiveList(pid); - - if (psProcessStats == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "Process %d not found. This process may not be live anymore.", (IMG_INT)pid)); - OSLockRelease(g_psLinkedListLock); - - return PVRSRV_ERROR_PROCESS_NOT_FOUND; - } - - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - for (i = 0; i < ui32ArrSize; i++) - { - pui32MemoryStats[i] = psProcessStats->i32StatValue[i]; - } - OSLockRelease(psProcessStats->hLock); - - OSLockRelease(g_psLinkedListLock); - - return PVRSRV_OK; - -} /* PVRSRVFindProcessMemStats */ - -/*************************************************************************/ /*! -@Function PVRSRVGetProcessMemUsage -@Description Calculate allocated kernel and graphics memory for all live or - connected processes. Memstat values provided by this API relate - only to the physical memory allocated by the process and does - not relate to any of the mapped or imported memory. -@Output pui32TotalMem Total memory usage for all live - PIDs connected to the driver. -@Output pui32NumberOfLivePids Number of live pids currently - connected to the server. -@Output ppsPerProcessMemUsageData Handle to an array of - PVRSRV_PER_PROCESS_MEM_USAGE, - number of elements defined by - pui32NumberOfLivePids. -@Return PVRSRV_OK Success - PVRSRV_ERROR_PROCESS_NOT_FOUND No live processes. - PVRSRV_ERROR_OUT_OF_MEMORY Failed to allocate memory for - ppsPerProcessMemUsageData. -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVGetProcessMemUsage(IMG_UINT32 *pui32TotalMem, - IMG_UINT32 *pui32NumberOfLivePids, - PVRSRV_PER_PROCESS_MEM_USAGE **ppsPerProcessMemUsageData) -{ - IMG_UINT32 ui32Counter = 0; - IMG_UINT32 ui32NumberOfLivePids = 0; - PVRSRV_ERROR eError = PVRSRV_ERROR_PROCESS_NOT_FOUND; - PVRSRV_PROCESS_STATS* psProcessStats = NULL; - PVRSRV_PER_PROCESS_MEM_USAGE* psPerProcessMemUsageData = NULL; - - OSLockAcquire(gsGlobalStats.hGlobalStatsLock); - - *pui32TotalMem = GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_KMALLOC) + - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_VMALLOC) + - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA) + - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA) + - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA) + - GET_GLOBAL_STAT_VALUE(PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA); - - OSLockRelease(gsGlobalStats.hGlobalStatsLock); - - OSLockAcquire(g_psLinkedListLock); - psProcessStats = g_psLiveList; - - while (psProcessStats != NULL) - { - psProcessStats = psProcessStats->psNext; - ui32NumberOfLivePids++; - } - - if (ui32NumberOfLivePids > 0) - { - /* Use OSAllocZMemNoStats to prevent deadlock. */ - psPerProcessMemUsageData = OSAllocZMemNoStats(ui32NumberOfLivePids * sizeof(*psPerProcessMemUsageData)); - - if (psPerProcessMemUsageData) - { - psProcessStats = g_psLiveList; - - while (psProcessStats != NULL) - { - OSLockAcquireNested(psProcessStats->hLock, PROCESS_LOCK_SUBCLASS_CURRENT); - - psPerProcessMemUsageData[ui32Counter].ui32Pid = (IMG_UINT32)psProcessStats->pid; - - psPerProcessMemUsageData[ui32Counter].ui32KernelMemUsage = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] + - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC]; - - psPerProcessMemUsageData[ui32Counter].ui32GraphicsMemUsage = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] + - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES] + - psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES]; - - OSLockRelease(psProcessStats->hLock); - psProcessStats = psProcessStats->psNext; - ui32Counter++; - } - eError = PVRSRV_OK; - } - else - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - - OSLockRelease(g_psLinkedListLock); - *pui32NumberOfLivePids = ui32NumberOfLivePids; - *ppsPerProcessMemUsageData = psPerProcessMemUsageData; - - return eError; - -} /* PVRSRVGetProcessMemUsage */ diff --git a/drivers/gpu/drm/img-rogue/1.17/process_stats.h b/drivers/gpu/drm/img-rogue/1.17/process_stats.h deleted file mode 100644 index 4003997363aa8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/process_stats.h +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Functions for creating and reading proc filesystem entries. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PROCESS_STATS_H -#define PROCESS_STATS_H - -#include - -#include "pvrsrv_error.h" -#include "allocmem.h" -#include "cache_ops.h" - -/* - * The publishing of Process Stats is controlled by the - * PVRSRV_ENABLE_PROCESS_STATS build option. The recording of all Memory - * allocations is controlled by the PVRSRV_ENABLE_MEMORY_STATS build option. - * - * Note: There will be a performance degradation with memory allocation - * recording enabled! - */ - - -/* - * Memory types which can be tracked... - */ -typedef enum { - PVRSRV_MEM_ALLOC_TYPE_KMALLOC, /* memory allocated by kmalloc() */ - PVRSRV_MEM_ALLOC_TYPE_VMALLOC, /* memory allocated by vmalloc() */ - PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, /* pages allocated from UMA to hold page table information */ - PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, /* ALLOC_PAGES_PT_UMA mapped to kernel address space */ - PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, /* pages allocated from LMA to hold page table information */ - PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, /* ALLOC_PAGES_PT_LMA mapped to kernel address space */ - PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, /* pages allocated from LMA */ - PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, /* pages allocated from UMA */ - PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, /* mapped UMA/LMA pages */ - PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, /* pages in the page pool */ - PVRSRV_MEM_ALLOC_TYPE_DMA_BUF_IMPORT, /* dma-buf imports */ - - /* Must be the last enum...*/ - PVRSRV_MEM_ALLOC_TYPE_COUNT -} PVRSRV_MEM_ALLOC_TYPE; - - -/* - * Functions for managing the processes recorded... - */ -PVRSRV_ERROR PVRSRVStatsInitialise(void); -void PVRSRVStatsDestroy(void); - -PVRSRV_ERROR PVRSRVStatsRegisterProcess(IMG_HANDLE* phProcessStats); - -void PVRSRVStatsDeregisterProcess(IMG_HANDLE hProcessStats); - -#define MAX_POWER_STAT_ENTRIES 51 - -/* - * Functions for recording the statistics... - */ - -void PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType, - void *pvCpuVAddr, - IMG_CPU_PHYADDR sCpuPAddr, - size_t uiBytes, - void *pvPrivateData, - IMG_PID uiPid - DEBUG_MEMSTATS_PARAMS); - -void PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType, - IMG_UINT64 ui64Key, - IMG_PID uiPid); - -void PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_PID uiPid); - -/* - * Increases the memory stat for eAllocType. Tracks the allocation size value - * by inserting a value into a hash table with uiCpuVAddr as key. - * Pair with PVRSRVStatsDecrMemAllocStatAndUntrack(). - */ -void PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_UINT64 uiCpuVAddr, - IMG_PID uiPid); - -void PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType, - size_t uiBytes, - IMG_PID uiPid); - -void PVRSRVStatsDecrMemKAllocStat(size_t uiBytes, - IMG_PID decrPID); - -/* - * Decrease the memory stat for eAllocType. Takes the allocation size value - * from the hash table with uiCpuVAddr as key. - * Pair with PVRSRVStatsIncrMemAllocStatAndTrack(). - */ -void PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE eAllocType, - IMG_UINT64 uiCpuVAddr); - -void -PVRSRVStatsIncrMemAllocPoolStat(size_t uiBytes); - -void -PVRSRVStatsDecrMemAllocPoolStat(size_t uiBytes); - -void -PVRSRVStatsUpdateOOMStats(IMG_UINT32 ui32OOMStatType, - IMG_PID pidOwner); - -PVRSRV_ERROR -PVRSRVServerUpdateOOMStats(IMG_UINT32 ui32OOMStatType, - IMG_PID pidOwner); - -void PVRSRVStatsUpdateRenderContextStats(IMG_UINT32 ui32TotalNumPartialRenders, - IMG_UINT32 ui32TotalNumOutOfMemory, - IMG_UINT32 ui32TotalTAStores, - IMG_UINT32 ui32Total3DStores, - IMG_UINT32 ui32TotalCDMStores, - IMG_UINT32 ui32TotalTDMStores, - IMG_PID owner); - -void PVRSRVStatsUpdateZSBufferStats(IMG_UINT32 ui32NumReqByApp, - IMG_UINT32 ui32NumReqByFW, - IMG_PID owner); - -void PVRSRVStatsUpdateFreelistStats(IMG_UINT32 ui32NumGrowReqByApp, - IMG_UINT32 ui32NumGrowReqByFW, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32NumHighPages, - IMG_PID ownerPid); -#if defined(PVRSRV_ENABLE_CACHEOP_STATS) -void PVRSRVStatsUpdateCacheOpStats(PVRSRV_CACHE_OP uiCacheOp, -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG) - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEV_PHYADDR sDevPAddr, -#endif - IMG_DEVMEM_SIZE_T uiOffset, - IMG_DEVMEM_SIZE_T uiSize, - IMG_UINT64 ui64ExecuteTimeMs, - IMG_BOOL bUserModeFlush, - IMG_PID ownerPid); -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -/* Update pre/post power transition timing statistics */ -void InsertPowerTimeStatistic(IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime, - IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime, - IMG_BOOL bForced, IMG_BOOL bPowerOn, IMG_BOOL bPrePower); - -void InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer); -void InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer); -#else -/* Update pre/post power transition timing statistics */ -static inline -void InsertPowerTimeStatistic(IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime, - IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime, - IMG_BOOL bForced, IMG_BOOL bPowerOn, IMG_BOOL bPrePower) {} -static inline -void InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer) {} - -static inline -void InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer) {} -#endif - -void SetFirmwareStartTime(IMG_UINT32 ui32TimeStamp); - -void SetFirmwareHandshakeIdleTime(IMG_UINT64 ui64Duration); - -/* Functions used for calculating the memory usage statistics of a process */ -PVRSRV_ERROR PVRSRVFindProcessMemStats(IMG_PID pid, IMG_UINT32 ui32ArrSize, - IMG_BOOL bAllProcessStats, IMG_UINT32 *pui32MemoryStats); - -typedef struct { - IMG_UINT32 ui32Pid; - IMG_UINT32 ui32KernelMemUsage; - IMG_UINT32 ui32GraphicsMemUsage; -} PVRSRV_PER_PROCESS_MEM_USAGE; - -PVRSRV_ERROR PVRSRVGetProcessMemUsage(IMG_UINT32 *pui32TotalMem, - IMG_UINT32 *pui32NumberOfLivePids, - PVRSRV_PER_PROCESS_MEM_USAGE **ppsPerProcessMemUsageData); - -#endif /* PROCESS_STATS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge.h b/drivers/gpu/drm/img-rogue/1.17/pvr_bridge.h deleted file mode 100644 index dbb6c6336787f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge.h +++ /dev/null @@ -1,457 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR Bridge Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the PVR Bridge code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_BRIDGE_H -#define PVR_BRIDGE_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "pvrsrv_error.h" -#if defined(SUPPORT_DISPLAY_CLASS) -#include "common_dc_bridge.h" -#if defined(SUPPORT_DCPLAT_BRIDGE) -#include "common_dcplat_bridge.h" -#endif -#endif -#include "common_mm_bridge.h" -#if defined(SUPPORT_MMPLAT_BRIDGE) -#include "common_mmplat_bridge.h" -#endif -#if defined(SUPPORT_WRAP_EXTMEM) -#include "common_mmextmem_bridge.h" -#endif -#if !defined(EXCLUDE_CMM_BRIDGE) -#include "common_cmm_bridge.h" -#endif -#if defined(__linux__) -#include "common_dmabuf_bridge.h" -#endif -#if defined(PDUMP) -#include "common_pdump_bridge.h" -#include "common_pdumpctrl_bridge.h" -#include "common_pdumpmm_bridge.h" -#endif -#include "common_cache_bridge.h" -#if defined(SUPPORT_DMA_TRANSFER) -#include "common_dma_bridge.h" -#endif -#include "common_srvcore_bridge.h" -#include "common_sync_bridge.h" -#if defined(SUPPORT_SECURE_EXPORT) -#include "common_smm_bridge.h" -#endif -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) -#include "common_htbuffer_bridge.h" -#endif -#include "common_pvrtl_bridge.h" -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "common_ri_bridge.h" -#endif - -#if defined(SUPPORT_VALIDATION_BRIDGE) -#include "common_validation_bridge.h" -#endif - -#if defined(PVR_TESTING_UTILS) -#include "common_tutils_bridge.h" -#endif - -#include "common_devicememhistory_bridge.h" -#include "common_synctracking_bridge.h" - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) -#include "common_syncfallback_bridge.h" -#endif - -#if defined(SUPPORT_DI_BRG_IMPL) -#include "common_di_bridge.h" -#endif - -/* - * Bridge Cmd Ids - */ - - -/* Note: The pattern - * #define PVRSRV_BRIDGE_FEATURE (PVRSRV_BRIDGE_PREVFEATURE + 1) - * #if defined(SUPPORT_FEATURE) - * #define PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST (PVRSRV_BRIDGE_PREVFEATURE_DISPATCH_LAST + 1) - * #define PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST (PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST + PVRSRV_BRIDGE_FEATURE_CMD_LAST) - * #else - * #define PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST 0 - * #define PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST (PVRSRV_BRIDGE_PREVFEATURE_DISPATCH_LAST) - * #endif - * is used in the macro definitions below to make PVRSRV_BRIDGE_FEATURE_* - * take up no space in the dispatch table if SUPPORT_FEATURE is disabled. - * - * Note however that a bridge always defines PVRSRV_BRIDGE_FEATURE, even where - * the feature is not enabled (each bridge group retains its own ioctl number). - */ - -#define PVRSRV_BRIDGE_FIRST 0UL - -/* 0: Default handler */ -#define PVRSRV_BRIDGE_DEFAULT 0UL -#define PVRSRV_BRIDGE_DEFAULT_DISPATCH_FIRST 0UL -#define PVRSRV_BRIDGE_DEFAULT_DISPATCH_LAST (PVRSRV_BRIDGE_DEFAULT_DISPATCH_FIRST) -/* 1: CORE functions */ -#define PVRSRV_BRIDGE_SRVCORE 1UL -#define PVRSRV_BRIDGE_SRVCORE_DISPATCH_FIRST (PVRSRV_BRIDGE_DEFAULT_DISPATCH_LAST+1) -#define PVRSRV_BRIDGE_SRVCORE_DISPATCH_LAST (PVRSRV_BRIDGE_SRVCORE_DISPATCH_FIRST + PVRSRV_BRIDGE_SRVCORE_CMD_LAST) - -/* 2: SYNC functions */ -#define PVRSRV_BRIDGE_SYNC 2UL -#define PVRSRV_BRIDGE_SYNC_DISPATCH_FIRST (PVRSRV_BRIDGE_SRVCORE_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_SYNC_DISPATCH_LAST (PVRSRV_BRIDGE_SYNC_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNC_CMD_LAST) - -/* 3,4: Reserved */ -#define PVRSRV_BRIDGE_RESERVED1 3UL -#define PVRSRV_BRIDGE_RESERVED1_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RESERVED1_DISPATCH_LAST (PVRSRV_BRIDGE_SYNC_DISPATCH_LAST) - -#define PVRSRV_BRIDGE_RESERVED2 4UL -#define PVRSRV_BRIDGE_RESERVED2_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RESERVED2_DISPATCH_LAST (PVRSRV_BRIDGE_RESERVED1_DISPATCH_LAST) - -/* 5: PDUMP CTRL layer functions */ -#define PVRSRV_BRIDGE_PDUMPCTRL 5UL -#if defined(PDUMP) -#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST (PVRSRV_BRIDGE_SYNC_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_LAST (PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMPCTRL_CMD_LAST) -#else -#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_LAST (PVRSRV_BRIDGE_SYNC_DISPATCH_LAST) -#endif - -/* 6: Memory Management functions */ -#define PVRSRV_BRIDGE_MM 6UL -#define PVRSRV_BRIDGE_MM_DISPATCH_FIRST (PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_MM_DISPATCH_LAST (PVRSRV_BRIDGE_MM_DISPATCH_FIRST + PVRSRV_BRIDGE_MM_CMD_LAST) - -/* 7: Non-Linux Memory Management functions */ -#define PVRSRV_BRIDGE_MMPLAT 7UL -#if defined(SUPPORT_MMPLAT_BRIDGE) -#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST (PVRSRV_BRIDGE_MM_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST (PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST + PVRSRV_BRIDGE_MMPLAT_CMD_LAST) -#else -#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST (PVRSRV_BRIDGE_MM_DISPATCH_LAST) -#endif - -/* 8: Context Memory Management functions */ -#define PVRSRV_BRIDGE_CMM 8UL -#if !defined(EXCLUDE_CMM_BRIDGE) -#define PVRSRV_BRIDGE_CMM_DISPATCH_FIRST (PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_CMM_DISPATCH_LAST (PVRSRV_BRIDGE_CMM_DISPATCH_FIRST + PVRSRV_BRIDGE_CMM_CMD_LAST) -#else -#define PVRSRV_BRIDGE_CMM_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_CMM_DISPATCH_LAST (PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST) -#endif - -/* 9: PDUMP Memory Management functions */ -#define PVRSRV_BRIDGE_PDUMPMM 9UL -#if defined(PDUMP) -#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST (PVRSRV_BRIDGE_CMM_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST (PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMPMM_CMD_LAST) -#else -#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST (PVRSRV_BRIDGE_CMM_DISPATCH_LAST) -#endif - -/* 10: PDUMP functions */ -#define PVRSRV_BRIDGE_PDUMP 10UL -#if defined(PDUMP) -#define PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST (PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST (PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMP_CMD_LAST) -#else -#define PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST (PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST) -#endif - -/* 11: DMABUF functions */ -#define PVRSRV_BRIDGE_DMABUF 11UL -#if defined(__linux__) -#define PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST (PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST (PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST + PVRSRV_BRIDGE_DMABUF_CMD_LAST) -#else -#define PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST (PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST) -#endif - -/* 12: Display Class functions */ -#define PVRSRV_BRIDGE_DC 12UL -#if defined(SUPPORT_DISPLAY_CLASS) -#define PVRSRV_BRIDGE_DC_DISPATCH_FIRST (PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DC_DISPATCH_LAST (PVRSRV_BRIDGE_DC_DISPATCH_FIRST + PVRSRV_BRIDGE_DC_CMD_LAST) -#else -#define PVRSRV_BRIDGE_DC_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_DC_DISPATCH_LAST (PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST) -#endif - -/* 13: Cache interface functions */ -#define PVRSRV_BRIDGE_CACHE 13UL -#define PVRSRV_BRIDGE_CACHE_DISPATCH_FIRST (PVRSRV_BRIDGE_DC_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_CACHE_DISPATCH_LAST (PVRSRV_BRIDGE_CACHE_DISPATCH_FIRST + PVRSRV_BRIDGE_CACHE_CMD_LAST) - -/* 14: Secure Memory Management functions */ -#define PVRSRV_BRIDGE_SMM 14UL -#if defined(SUPPORT_SECURE_EXPORT) -#define PVRSRV_BRIDGE_SMM_DISPATCH_FIRST (PVRSRV_BRIDGE_CACHE_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_SMM_DISPATCH_LAST (PVRSRV_BRIDGE_SMM_DISPATCH_FIRST + PVRSRV_BRIDGE_SMM_CMD_LAST) -#else -#define PVRSRV_BRIDGE_SMM_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_SMM_DISPATCH_LAST (PVRSRV_BRIDGE_CACHE_DISPATCH_LAST) -#endif - -/* 15: Transport Layer interface functions */ -#define PVRSRV_BRIDGE_PVRTL 15UL -#define PVRSRV_BRIDGE_PVRTL_DISPATCH_FIRST (PVRSRV_BRIDGE_SMM_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST (PVRSRV_BRIDGE_PVRTL_DISPATCH_FIRST + PVRSRV_BRIDGE_PVRTL_CMD_LAST) - -/* 16: Resource Information (RI) interface functions */ -#define PVRSRV_BRIDGE_RI 16UL -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#define PVRSRV_BRIDGE_RI_DISPATCH_FIRST (PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RI_DISPATCH_LAST (PVRSRV_BRIDGE_RI_DISPATCH_FIRST + PVRSRV_BRIDGE_RI_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RI_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RI_DISPATCH_LAST (PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST) -#endif - -/* 17: Validation interface functions */ -#define PVRSRV_BRIDGE_VALIDATION 17UL -#if defined(SUPPORT_VALIDATION_BRIDGE) -#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST (PVRSRV_BRIDGE_RI_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST (PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST + PVRSRV_BRIDGE_VALIDATION_CMD_LAST) -#else -#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST (PVRSRV_BRIDGE_RI_DISPATCH_LAST) -#endif - -/* 18: TUTILS interface functions */ -#define PVRSRV_BRIDGE_TUTILS 18UL -#if defined(PVR_TESTING_UTILS) -#define PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST (PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST (PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST + PVRSRV_BRIDGE_TUTILS_CMD_LAST) -#else -#define PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST (PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST) -#endif - -/* 19: DevMem history interface functions */ -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY 19UL -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST (PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST + PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST) - -/* 20: Host Trace Buffer interface functions */ -#define PVRSRV_BRIDGE_HTBUFFER 20UL -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) -#define PVRSRV_BRIDGE_HTBUFFER_DISPATCH_FIRST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_HTBUFFER_DISPATCH_LAST (PVRSRV_BRIDGE_HTBUFFER_DISPATCH_FIRST + PVRSRV_BRIDGE_HTBUFFER_CMD_LAST) -#else -#define PVRSRV_BRIDGE_HTBUFFER_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_HTBUFFER_DISPATCH_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST) -#endif - -/* 21: Non-Linux Display functions */ -#define PVRSRV_BRIDGE_DCPLAT 21UL -#if defined(SUPPORT_DISPLAY_CLASS) && defined(SUPPORT_DCPLAT_BRIDGE) -#define PVRSRV_BRIDGE_DCPLAT_DISPATCH_FIRST (PVRSRV_BRIDGE_HTBUFFER_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DCPLAT_DISPATCH_LAST (PVRSRV_BRIDGE_DCPLAT_DISPATCH_FIRST + PVRSRV_BRIDGE_DCPLAT_CMD_LAST) -#else -#define PVRSRV_BRIDGE_DCPLAT_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_DCPLAT_DISPATCH_LAST (PVRSRV_BRIDGE_HTBUFFER_DISPATCH_LAST) -#endif - -/* 22: Extmem functions */ -#define PVRSRV_BRIDGE_MMEXTMEM 22UL -#if defined(SUPPORT_WRAP_EXTMEM) -#define PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_FIRST (PVRSRV_BRIDGE_DCPLAT_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_LAST (PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_FIRST + PVRSRV_BRIDGE_MMEXTMEM_CMD_LAST) -#else -#define PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_LAST (PVRSRV_BRIDGE_DCPLAT_DISPATCH_LAST) -#endif - -/* 23: Sync tracking functions */ -#define PVRSRV_BRIDGE_SYNCTRACKING 23UL -#define PVRSRV_BRIDGE_SYNCTRACKING_DISPATCH_FIRST (PVRSRV_BRIDGE_MMEXTMEM_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_SYNCTRACKING_DISPATCH_LAST (PVRSRV_BRIDGE_SYNCTRACKING_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNCTRACKING_CMD_LAST) - -/* 24: Sync fallback functions */ -#define PVRSRV_BRIDGE_SYNCFALLBACK 24UL -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) -#define PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_FIRST (PVRSRV_BRIDGE_SYNCTRACKING_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_LAST (PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNCFALLBACK_CMD_LAST) -#else -#define PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_LAST (PVRSRV_BRIDGE_SYNCTRACKING_DISPATCH_LAST) -#endif - -/* 25: Debug Information (DI) interface functions */ -#define PVRSRV_BRIDGE_DI 25UL -#if defined(SUPPORT_DI_BRG_IMPL) -#define PVRSRV_BRIDGE_DI_DISPATCH_FIRST (PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DI_DISPATCH_LAST (PVRSRV_BRIDGE_DI_DISPATCH_FIRST + PVRSRV_BRIDGE_DI_CMD_LAST) -#else -#define PVRSRV_BRIDGE_DI_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_DI_DISPATCH_LAST (PVRSRV_BRIDGE_SYNCFALLBACK_DISPATCH_LAST) -#endif - -/* 26: DMA transfer functions */ - -#define PVRSRV_BRIDGE_DMA 26UL -#if defined(SUPPORT_DMA_TRANSFER) -#define PVRSRV_BRIDGE_DMA_DISPATCH_FIRST (PVRSRV_BRIDGE_DI_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_DMA_DISPATCH_LAST (PVRSRV_BRIDGE_DMA_DISPATCH_FIRST + PVRSRV_BRIDGE_DMA_CMD_LAST) -#else -#define PVRSRV_BRIDGE_DMA_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_DMA_DISPATCH_LAST (PVRSRV_BRIDGE_DI_DISPATCH_LAST) -#endif - -/* NB PVRSRV_BRIDGE_LAST below must be the last bridge group defined above (PVRSRV_BRIDGE_FEATURE) */ -#define PVRSRV_BRIDGE_LAST (PVRSRV_BRIDGE_DMA) -/* NB PVRSRV_BRIDGE_DISPATCH LAST below must be the last dispatch entry defined above (PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST) */ -#define PVRSRV_BRIDGE_DISPATCH_LAST (PVRSRV_BRIDGE_DMA_DISPATCH_LAST) - -/* bit mask representing the enabled PVR bridges */ - -static const IMG_UINT32 __maybe_unused gui32PVRBridges = - (1U << (PVRSRV_BRIDGE_DEFAULT - PVRSRV_BRIDGE_FIRST)) - | (1U << (PVRSRV_BRIDGE_SRVCORE - PVRSRV_BRIDGE_FIRST)) - | (1U << (PVRSRV_BRIDGE_SYNC - PVRSRV_BRIDGE_FIRST)) - -#if defined(PDUMP) - | (1U << (PVRSRV_BRIDGE_PDUMPCTRL - PVRSRV_BRIDGE_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_MM - PVRSRV_BRIDGE_FIRST)) -#if defined(SUPPORT_MMPLAT_BRIDGE) - | (1U << (PVRSRV_BRIDGE_MMPLAT - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_CMM) - | (1U << (PVRSRV_BRIDGE_CMM - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(PDUMP) - | (1U << (PVRSRV_BRIDGE_PDUMPMM - PVRSRV_BRIDGE_FIRST)) - | (1U << (PVRSRV_BRIDGE_PDUMP - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(__linux__) - | (1U << (PVRSRV_BRIDGE_DMABUF - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_DISPLAY_CLASS) - | (1U << (PVRSRV_BRIDGE_DC - PVRSRV_BRIDGE_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_CACHE - PVRSRV_BRIDGE_FIRST)) -#if defined(SUPPORT_SECURE_EXPORT) - | (1U << (PVRSRV_BRIDGE_SMM - PVRSRV_BRIDGE_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_PVRTL - PVRSRV_BRIDGE_FIRST)) -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - | (1U << (PVRSRV_BRIDGE_RI - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_VALIDATION) - | (1U << (PVRSRV_BRIDGE_VALIDATION - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(PVR_TESTING_UTILS) - | (1U << (PVRSRV_BRIDGE_TUTILS - PVRSRV_BRIDGE_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_DEVICEMEMHISTORY - PVRSRV_BRIDGE_FIRST)) -#if defined(SUPPORT_HTBUFFER) - | (1U << (PVRSRV_BRIDGE_HTBUFFER - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_DISPLAY_CLASS) && defined(SUPPORT_DCPLAT_BRIDGE) - | (1U << (PVRSRV_BRIDGE_DCPLAT - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_WRAP_EXTMEM) - | (1U << (PVRSRV_BRIDGE_MMEXTMEM - PVRSRV_BRIDGE_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_SYNCTRACKING - PVRSRV_BRIDGE_FIRST)) -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - | (1U << (PVRSRV_BRIDGE_SYNCFALLBACK - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_DI_BRG_IMPL) - | (1U << (PVRSRV_BRIDGE_DI - PVRSRV_BRIDGE_FIRST)) -#endif -#if defined(SUPPORT_DMA_TRANSFER) - | (1U << (PVRSRV_BRIDGE_DMA - PVRSRV_BRIDGE_FIRST)) -#endif - ; - -/* bit field representing which PVR bridge groups may optionally not - * be present in the server - */ -#define PVR_BRIDGES_OPTIONAL \ - ( \ - (1U << (PVRSRV_BRIDGE_RI - PVRSRV_BRIDGE_FIRST)) \ - ) - -/****************************************************************************** - * Generic bridge structures - *****************************************************************************/ - - -/****************************************************************************** - * bridge packaging structure - *****************************************************************************/ -typedef struct PVRSRV_BRIDGE_PACKAGE_TAG -{ - IMG_UINT32 ui32BridgeID; /*!< ioctl bridge group */ - IMG_UINT32 ui32FunctionID; /*!< ioctl function index */ - IMG_UINT32 ui32Size; /*!< size of structure */ - void __user *pvParamIn; /*!< input data buffer */ - IMG_UINT32 ui32InBufferSize; /*!< size of input data buffer */ - void __user *pvParamOut; /*!< output data buffer */ - IMG_UINT32 ui32OutBufferSize; /*!< size of output data buffer */ -}PVRSRV_BRIDGE_PACKAGE; - -#if defined(__cplusplus) -} -#endif - -#endif /* PVR_BRIDGE_H */ - -/****************************************************************************** - End of file (pvr_bridge.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.c b/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.c deleted file mode 100644 index 64c70aebb1eb9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.c +++ /dev/null @@ -1,585 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR Bridge Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Receives calls from the user portion of services and - despatches them to functions in the kernel portion. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "pvr_bridge.h" -#include "pvr_bridge_k.h" -#include "connection_server.h" -#include "syscommon.h" -#include "pvr_debug.h" -#include "di_server.h" -#include "private_data.h" -#include "linkage.h" -#include "pmr.h" -#include "rgx_bvnc_defs_km.h" -#include "pvrsrv_bridge_init.h" - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#include -#else -#include -#endif - -#include "pvr_drm.h" -#include "pvr_drv.h" - -#include "env_connection.h" -#include -#include - -/* RGX: */ -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif - -#include "srvcore.h" -#include "common_srvcore_bridge.h" - -PVRSRV_ERROR InitDMABUFBridge(void); -void DeinitDMABUFBridge(void); - -#if defined(MODULE_TEST) -/************************************************************************/ -// additional includes for services testing -/************************************************************************/ -#include "pvr_test_bridge.h" -#include "kern_test.h" -/************************************************************************/ -// end of additional includes -/************************************************************************/ -#endif - -/* The mmap code has its own mutex, to prevent possible re-entrant issues - * when the same PMR is mapped from two different connections/processes. - */ -static DEFINE_MUTEX(g_sMMapMutex); - -#define _DRIVER_SUSPENDED 1 -#define _DRIVER_NOT_SUSPENDED 0 -static ATOMIC_T g_iDriverSuspended; -static ATOMIC_T g_iNumActiveDriverThreads; -static ATOMIC_T g_iNumActiveKernelThreads; -static IMG_HANDLE g_hDriverThreadEventObject; - -#if defined(DEBUG_BRIDGE_KM) -static DI_ENTRY *gpsDIBridgeStatsEntry; - -static void *BridgeStatsDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos) -{ - PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = DIGetPrivData(psEntry); - - if (psDispatchTable == NULL || *pui64Pos > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) - { - return NULL; - } - - if (*pui64Pos == 0) - { - return DI_START_TOKEN; - } - - return &(psDispatchTable[*pui64Pos - 1]); -} - -static void BridgeStatsDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - PVR_UNREFERENCED_PARAMETER(psEntry); - PVR_UNREFERENCED_PARAMETER(pvData); -} - -static void *BridgeStatsDINext(OSDI_IMPL_ENTRY *psEntry, void *pvData, - IMG_UINT64 *pui64Pos) -{ - PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = DIGetPrivData(psEntry); - IMG_UINT64 uiItemAskedFor = *pui64Pos; /* pui64Pos on entry is the index to return */ - - PVR_UNREFERENCED_PARAMETER(pvData); - - /* Is the item asked for (starts at 0) a valid table index? */ - if (uiItemAskedFor < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) - { - (*pui64Pos)++; /* on exit it is the next DI index to ask for */ - return &(psDispatchTable[uiItemAskedFor]); - } - - /* Now passed the end of the table to indicate stop */ - return NULL; -} - -static int BridgeStatsDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData) -{ - if (pvData == DI_START_TOKEN) - { - DIPrintf(psEntry, - "Total ioctl call count = %u\n" - "Total number of bytes copied via copy_from_user = %u\n" - "Total number of bytes copied via copy_to_user = %u\n" - "Total number of bytes copied via copy_*_user = %u\n\n" - "%3s: %-60s | %-48s | %10s | %20s | %20s | %20s | %20s\n", - g_BridgeGlobalStats.ui32IOCTLCount, - g_BridgeGlobalStats.ui32TotalCopyFromUserBytes, - g_BridgeGlobalStats.ui32TotalCopyToUserBytes, - g_BridgeGlobalStats.ui32TotalCopyFromUserBytes + - g_BridgeGlobalStats.ui32TotalCopyToUserBytes, - "#", - "Bridge Name", - "Wrapper Function", - "Call Count", - "copy_from_user (B)", - "copy_to_user (B)", - "Total Time (us)", - "Max Time (us)"); - } - else if (pvData != NULL) - { - PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psTableEntry = pvData; - IMG_UINT32 ui32Remainder; - - DIPrintf(psEntry, - "%3d: %-60s %-48s %-10u %-20u %-20u %-20" IMG_UINT64_FMTSPEC " %-20" IMG_UINT64_FMTSPEC "\n", - (IMG_UINT32)(((size_t)psTableEntry-(size_t)g_BridgeDispatchTable)/sizeof(*g_BridgeDispatchTable)), - psTableEntry->pszIOCName, - (psTableEntry->pfFunction != NULL) ? psTableEntry->pszFunctionName : "(null)", - psTableEntry->ui32CallCount, - psTableEntry->ui32CopyFromUserTotalBytes, - psTableEntry->ui32CopyToUserTotalBytes, - OSDivide64r64(psTableEntry->ui64TotalTimeNS, 1000, &ui32Remainder), - OSDivide64r64(psTableEntry->ui64MaxTimeNS, 1000, &ui32Remainder)); - } - - return 0; -} - -static IMG_INT64 BridgeStatsWrite(const IMG_CHAR *pcBuffer, - IMG_UINT64 ui64Count, IMG_UINT64 *pui64Pos, - void *pvData) -{ - IMG_UINT32 i; - - PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO); - PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO); - PVR_RETURN_IF_FALSE(ui64Count >= 1, -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[0] == '0', -EINVAL); - PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL); - - /* Reset stats. */ - - BridgeGlobalStatsLock(); - - g_BridgeGlobalStats.ui32IOCTLCount = 0; - g_BridgeGlobalStats.ui32TotalCopyFromUserBytes = 0; - g_BridgeGlobalStats.ui32TotalCopyToUserBytes = 0; - - for (i = 0; i < ARRAY_SIZE(g_BridgeDispatchTable); i++) - { - g_BridgeDispatchTable[i].ui32CallCount = 0; - g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0; - g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0; - g_BridgeDispatchTable[i].ui64TotalTimeNS = 0; - g_BridgeDispatchTable[i].ui64MaxTimeNS = 0; - } - - BridgeGlobalStatsUnlock(); - - return ui64Count; -} - -#endif /* defined(DEBUG_BRIDGE_KM) */ - -PVRSRV_ERROR OSPlatformBridgeInit(void) -{ - PVRSRV_ERROR eError; - - eError = InitDMABUFBridge(); - PVR_LOG_IF_ERROR(eError, "InitDMABUFBridge"); - - OSAtomicWrite(&g_iDriverSuspended, _DRIVER_NOT_SUSPENDED); - OSAtomicWrite(&g_iNumActiveDriverThreads, 0); - OSAtomicWrite(&g_iNumActiveKernelThreads, 0); - - eError = OSEventObjectCreate("Global driver thread event object", - &g_hDriverThreadEventObject); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", error_); - -#if defined(DEBUG_BRIDGE_KM) - { - DI_ITERATOR_CB sIter = { - .pfnStart = BridgeStatsDIStart, - .pfnStop = BridgeStatsDIStop, - .pfnNext = BridgeStatsDINext, - .pfnShow = BridgeStatsDIShow, - .pfnWrite = BridgeStatsWrite, - - //Expects '0' + Null terminator - .ui32WriteLenMax = ((1U)+1U) - }; - - eError = DICreateEntry("bridge_stats", NULL, &sIter, - &g_BridgeDispatchTable[0], - DI_ENTRY_TYPE_GENERIC, - &gpsDIBridgeStatsEntry); - PVR_LOG_GOTO_IF_ERROR(eError, "DICreateEntry", error_); - } -#endif - - return PVRSRV_OK; - -error_: - if (g_hDriverThreadEventObject) { - OSEventObjectDestroy(g_hDriverThreadEventObject); - g_hDriverThreadEventObject = NULL; - } - - return eError; -} - -void OSPlatformBridgeDeInit(void) -{ -#if defined(DEBUG_BRIDGE_KM) - if (gpsDIBridgeStatsEntry != NULL) - { - DIDestroyEntry(gpsDIBridgeStatsEntry); - } -#endif - - DeinitDMABUFBridge(); - - if (g_hDriverThreadEventObject != NULL) { - OSEventObjectDestroy(g_hDriverThreadEventObject); - g_hDriverThreadEventObject = NULL; - } -} - -PVRSRV_ERROR LinuxBridgeBlockClientsAccess(IMG_BOOL bShutdown) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hEvent; - - eError = OSEventObjectOpen(g_hDriverThreadEventObject, &hEvent); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to open event object", __func__)); - return eError; - } - - if (OSAtomicCompareExchange(&g_iDriverSuspended, _DRIVER_NOT_SUSPENDED, - _DRIVER_SUSPENDED) == _DRIVER_SUSPENDED) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Driver is already suspended", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto out_put; - } - - /* now wait for any threads currently in the server to exit */ - while (OSAtomicRead(&g_iNumActiveDriverThreads) != 0 || - (OSAtomicRead(&g_iNumActiveKernelThreads) != 0 && !bShutdown)) - { - if (OSAtomicRead(&g_iNumActiveDriverThreads) != 0) - { - PVR_LOG(("%s: waiting for user threads (%d)", __func__, - OSAtomicRead(&g_iNumActiveDriverThreads))); - } - if (OSAtomicRead(&g_iNumActiveKernelThreads) != 0) - { - PVR_LOG(("%s: waiting for kernel threads (%d)", __func__, - OSAtomicRead(&g_iNumActiveKernelThreads))); - } - /* Regular wait is called here (and not OSEventObjectWaitKernel) because - * this code is executed by the caller of .suspend/.shutdown callbacks - * which is most likely PM (or other actor responsible for suspend - * process). Because of that this thread shouldn't and most likely - * event cannot be frozen. */ - OSEventObjectWait(hEvent); - } - -out_put: - OSEventObjectClose(hEvent); - - return eError; -} - -PVRSRV_ERROR LinuxBridgeUnblockClientsAccess(void) -{ - PVRSRV_ERROR eError; - - /* resume the driver and then signal so any waiting threads wake up */ - if (OSAtomicCompareExchange(&g_iDriverSuspended, _DRIVER_SUSPENDED, - _DRIVER_NOT_SUSPENDED) == _DRIVER_NOT_SUSPENDED) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Driver is not suspended", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = OSEventObjectSignal(g_hDriverThreadEventObject); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OSEventObjectSignal failed: %s", - __func__, PVRSRVGetErrorString(eError))); - } - - return eError; -} - -static PVRSRV_ERROR LinuxBridgeSignalIfSuspended(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (OSAtomicRead(&g_iDriverSuspended) == _DRIVER_SUSPENDED) - { - PVRSRV_ERROR eError = OSEventObjectSignal(g_hDriverThreadEventObject); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to signal driver thread event" - " object: %s", __func__, PVRSRVGetErrorString(eError))); - } - } - - return eError; -} - -void LinuxBridgeNumActiveKernelThreadsIncrement(void) -{ - OSAtomicIncrement(&g_iNumActiveKernelThreads); -} - -void LinuxBridgeNumActiveKernelThreadsDecrement(void) -{ - OSAtomicDecrement(&g_iNumActiveKernelThreads); - PVR_ASSERT(OSAtomicRead(&g_iNumActiveKernelThreads) >= 0); - - /* Signal on every decrement in case LinuxBridgeBlockClientsAccess() is - * waiting for the threads to freeze. - * (error is logged in called function so ignore, we can't do much with - * it anyway) */ - (void) LinuxBridgeSignalIfSuspended(); -} - -static PVRSRV_ERROR _WaitForDriverUnsuspend(void) -{ - PVRSRV_ERROR eError; - IMG_HANDLE hEvent; - - eError = OSEventObjectOpen(g_hDriverThreadEventObject, &hEvent); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to open event object", __func__)); - return eError; - } - - while (OSAtomicRead(&g_iDriverSuspended) == _DRIVER_SUSPENDED) - { - /* we should be able to use normal (not kernel) wait here since - * we were just unfrozen and most likely we're not going to - * be frozen again (?) */ - OSEventObjectWait(hEvent); - } - - OSEventObjectClose(hEvent); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVDriverThreadEnter(void) -{ - PVRSRV_ERROR eError; - - /* increment first so there is no race between this value and - * g_iDriverSuspended in LinuxBridgeBlockClientsAccess() */ - OSAtomicIncrement(&g_iNumActiveDriverThreads); - - if (OSAtomicRead(&g_iDriverSuspended) == _DRIVER_SUSPENDED) - { - /* decrement here because the driver is going to be suspended and - * this thread is going to be frozen so we don't want to wait for - * it in LinuxBridgeBlockClientsAccess() */ - OSAtomicDecrement(&g_iNumActiveDriverThreads); - - /* during suspend procedure this will put the current thread to - * the freezer but during shutdown this will just return */ - try_to_freeze(); - - /* if the thread was unfrozen but the flag is not yet set to - * _DRIVER_NOT_SUSPENDED wait for it - * in case this is a shutdown the thread was not frozen so we'll - * wait here indefinitely but this is ok (and this is in fact what - * we want) because no thread should be entering the driver in such - * case */ - eError = _WaitForDriverUnsuspend(); - - /* increment here because that means that the thread entered the - * driver */ - OSAtomicIncrement(&g_iNumActiveDriverThreads); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to wait for driver" - " unsuspend: %s", __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - } - - return PVRSRV_OK; -} - -void PVRSRVDriverThreadExit(void) -{ - OSAtomicDecrement(&g_iNumActiveDriverThreads); - /* if the driver is being suspended then we need to signal the - * event object as the thread suspending the driver is waiting - * for active threads to exit - * error is logged in called function so ignore returned error - */ - (void) LinuxBridgeSignalIfSuspended(); -} - -int -PVRSRV_BridgeDispatchKM(struct drm_device __maybe_unused *dev, void *arg, struct drm_file *pDRMFile) -{ - struct drm_pvr_srvkm_cmd *psSrvkmCmd = (struct drm_pvr_srvkm_cmd *) arg; - PVRSRV_BRIDGE_PACKAGE sBridgePackageKM = { 0 }; - CONNECTION_DATA *psConnection = LinuxServicesConnectionFromFile(pDRMFile->filp); - PVRSRV_ERROR error; - - if (psConnection == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "Invalid connection data")); - return -EFAULT; - } - - PVR_ASSERT(psSrvkmCmd != NULL); - - DRM_DEBUG("tgid=%d, tgid_connection=%d, bridge_id=%d, func_id=%d", - task_tgid_nr(current), - ((ENV_CONNECTION_DATA *)PVRSRVConnectionPrivateData(psConnection))->owner, - psSrvkmCmd->bridge_id, - psSrvkmCmd->bridge_func_id); - - error = PVRSRVDriverThreadEnter(); - PVR_LOG_GOTO_IF_ERROR(error, "PVRSRVDriverThreadEnter", e0); - - sBridgePackageKM.ui32BridgeID = psSrvkmCmd->bridge_id; - sBridgePackageKM.ui32FunctionID = psSrvkmCmd->bridge_func_id; - sBridgePackageKM.ui32Size = sizeof(sBridgePackageKM); - sBridgePackageKM.pvParamIn = (void __user *)(uintptr_t)psSrvkmCmd->in_data_ptr; - sBridgePackageKM.ui32InBufferSize = psSrvkmCmd->in_data_size; - sBridgePackageKM.pvParamOut = (void __user *)(uintptr_t)psSrvkmCmd->out_data_ptr; - sBridgePackageKM.ui32OutBufferSize = psSrvkmCmd->out_data_size; - - error = BridgedDispatchKM(psConnection, &sBridgePackageKM); - - PVRSRVDriverThreadExit(); - -e0: - return OSPVRSRVToNativeError(error); -} - -int -PVRSRV_MMap(struct file *pFile, struct vm_area_struct *ps_vma) -{ - CONNECTION_DATA *psConnection = LinuxServicesConnectionFromFile(pFile); - IMG_HANDLE hSecurePMRHandle = (IMG_HANDLE)((uintptr_t)ps_vma->vm_pgoff); - PMR *psPMR; - PVRSRV_ERROR eError; - PVRSRV_MEMALLOCFLAGS_T uiProtFlags = - (BITMASK_HAS(ps_vma->vm_flags, VM_READ) ? PVRSRV_MEMALLOCFLAG_CPU_READABLE : 0) | - (BITMASK_HAS(ps_vma->vm_flags, VM_WRITE) ? PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE : 0); - - if (psConnection == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "Invalid connection data")); - return -ENOENT; - } - - eError = PVRSRVDriverThreadEnter(); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVDriverThreadEnter", e0); - - /* - * The bridge lock used here to protect PVRSRVLookupHandle is replaced - * by a specific lock considering that the handle functions have now - * their own lock. This change was necessary to solve the lockdep issues - * related with the PVRSRV_MMap. - */ - - eError = PVRSRVLookupHandle(psConnection->psHandleBase, - (void **)&psPMR, - hSecurePMRHandle, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - IMG_TRUE); - if (eError != PVRSRV_OK) - { - goto e0; - } - - mutex_lock(&g_sMMapMutex); - /* Note: PMRMMapPMR will take a reference on the PMR. - * Unref the handle immediately, because we have now done - * the required operation on the PMR (whether it succeeded or not) - */ - eError = PMRMMapPMR(psPMR, ps_vma, uiProtFlags); - mutex_unlock(&g_sMMapMutex); - PVRSRVReleaseHandle(psConnection->psHandleBase, hSecurePMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PMRMMapPMR failed (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto e0; - } - - PVRSRVDriverThreadExit(); - - return 0; - -e0: - PVRSRVDriverThreadExit(); - - PVR_DPF((PVR_DBG_ERROR, "Failed with error: %s", PVRSRVGetErrorString(eError))); - PVR_ASSERT(eError != PVRSRV_OK); - - return OSPVRSRVToNativeError(eError); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.h b/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.h deleted file mode 100644 index 859ec641bd1b3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_bridge_k.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR Bridge Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Receives calls from the user portion of services and - despatches them to functions in the kernel portion. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_BRIDGE_K_H -#define PVR_BRIDGE_K_H - -#include "pvrsrv_error.h" - -/*! -****************************************************************************** - @Function LinuxBridgeBlockClientsAccess - @Description This function will wait for any existing threads in the Server - to exit and then disable access to the driver. New threads will - not be allowed to enter the Server until the driver is - unsuspended (see LinuxBridgeUnblockClientsAccess). - @Input bShutdown this flag indicates that the function was called - from a shutdown callback and therefore it will - not wait for the kernel threads to get frozen - (because this doesn't happen during shutdown - procedure) - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR LinuxBridgeBlockClientsAccess(IMG_BOOL bShutdown); - -/*! -****************************************************************************** - @Function LinuxBridgeUnblockClientsAccess - @Description This function will re-enable the bridge and allow any threads - waiting to enter the Server to continue. - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR LinuxBridgeUnblockClientsAccess(void); - -void LinuxBridgeNumActiveKernelThreadsIncrement(void); -void LinuxBridgeNumActiveKernelThreadsDecrement(void); - -/*! -****************************************************************************** - @Function PVRSRVDriverThreadEnter - @Description Increments number of client threads currently operating - in the driver's context. - If the driver is currently being suspended this function - will call try_to_freeze() on behalf of the client thread. - When the driver is resumed the function will exit and allow - the thread into the driver. - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVDriverThreadEnter(void); - -/*! -****************************************************************************** - @Function PVRSRVDriverThreadExit - @Description Decrements the number of client threads currently operating - in the driver's context to match the call to - PVRSRVDriverThreadEnter(). - The function also signals the driver that a thread left the - driver context so if it's waiting to suspend it knows that - the number of threads decreased. -******************************************************************************/ -void PVRSRVDriverThreadExit(void); - -#endif /* PVR_BRIDGE_K_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.c b/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.c deleted file mode 100644 index 6c760b446466f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * @File - * @Title Linux buffer sync interface - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "services_kernel_client.h" -#include "pvr_dma_resv.h" -#include "pvr_buffer_sync.h" -#include "pvr_buffer_sync_shared.h" -#include "pvr_drv.h" -#include "pvr_fence.h" - -struct pvr_buffer_sync_context { - struct mutex ctx_lock; - struct pvr_fence_context *fence_ctx; - struct ww_acquire_ctx acquire_ctx; -}; - -struct pvr_buffer_sync_check_data { - struct dma_fence_cb base; - - u32 nr_fences; - struct pvr_fence **fences; -}; - -struct pvr_buffer_sync_append_data { - struct pvr_buffer_sync_context *ctx; - - u32 nr_pmrs; - struct _PMR_ **pmrs; - u32 *pmr_flags; - - struct pvr_fence *update_fence; - struct pvr_buffer_sync_check_data *check_data; -}; - -static struct dma_resv * -pmr_reservation_object_get(struct _PMR_ *pmr) -{ - struct dma_buf *dmabuf; - - dmabuf = PhysmemGetDmaBuf(pmr); - if (dmabuf) - return dmabuf->resv; - - return NULL; -} - -static int -pvr_buffer_sync_pmrs_lock(struct pvr_buffer_sync_context *ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs) -{ - struct dma_resv *resv, *cresv = NULL, *lresv = NULL; - int i, err; - struct ww_acquire_ctx *acquire_ctx = &ctx->acquire_ctx; - - mutex_lock(&ctx->ctx_lock); - - ww_acquire_init(acquire_ctx, &reservation_ww_class); -retry: - for (i = 0; i < nr_pmrs; i++) { - resv = pmr_reservation_object_get(pmrs[i]); - if (!resv) { - pr_err("%s: Failed to get reservation object from pmr %p\n", - __func__, pmrs[i]); - err = -EINVAL; - goto fail; - } - - if (resv != lresv) { - err = ww_mutex_lock_interruptible(&resv->lock, - acquire_ctx); - if (err) { - cresv = (err == -EDEADLK) ? resv : NULL; - goto fail; - } - } else { - lresv = NULL; - } - } - - ww_acquire_done(acquire_ctx); - - return 0; - -fail: - while (i--) { - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - ww_mutex_unlock(&resv->lock); - } - - if (lresv) - ww_mutex_unlock(&lresv->lock); - - if (cresv) { - err = ww_mutex_lock_slow_interruptible(&cresv->lock, - acquire_ctx); - if (!err) { - lresv = cresv; - cresv = NULL; - goto retry; - } - } - - ww_acquire_fini(acquire_ctx); - - mutex_unlock(&ctx->ctx_lock); - return err; -} - -static void -pvr_buffer_sync_pmrs_unlock(struct pvr_buffer_sync_context *ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs) -{ - struct dma_resv *resv; - int i; - struct ww_acquire_ctx *acquire_ctx = &ctx->acquire_ctx; - - for (i = 0; i < nr_pmrs; i++) { - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - ww_mutex_unlock(&resv->lock); - } - - ww_acquire_fini(acquire_ctx); - - mutex_unlock(&ctx->ctx_lock); -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - -static void -dma_resv_count_fences(struct dma_resv *resv, u32 *read_fence_count_out, u32 *write_fence_count_out) -{ - struct dma_resv_iter cursor; - u32 write_fence_count = 0; - u32 read_fence_count = 0; - struct dma_fence *fence; - - dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_READ); - dma_resv_for_each_fence_unlocked(&cursor, fence) { - if (dma_resv_iter_is_restarted(&cursor)) { - read_fence_count = 0; - write_fence_count = 0; - } - if (dma_resv_iter_usage(&cursor) == DMA_RESV_USAGE_READ) - read_fence_count++; - else if (dma_resv_iter_usage(&cursor) == DMA_RESV_USAGE_WRITE) - write_fence_count++; - } - - *read_fence_count_out = read_fence_count; - *write_fence_count_out = write_fence_count; -} - -static u32 -pvr_buffer_sync_pmrs_fence_count(u32 nr_pmrs, struct _PMR_ **pmrs, - u32 *pmr_flags) -{ - struct dma_resv *resv; - u32 fence_count = 0; - bool exclusive; - int i; - - for (i = 0; i < nr_pmrs; i++) { - u32 write_fence_count = 0; - u32 read_fence_count = 0; - - exclusive = !!(pmr_flags[i] & PVR_BUFFER_FLAG_WRITE); - - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - - dma_resv_count_fences(resv, &read_fence_count, &write_fence_count); - - if (!exclusive || !read_fence_count) - fence_count += write_fence_count; - if (exclusive) - fence_count += read_fence_count; - } - - return fence_count; -} - -static struct pvr_buffer_sync_check_data * -pvr_buffer_sync_check_fences_create(struct pvr_fence_context *fence_ctx, - PSYNC_CHECKPOINT_CONTEXT sync_checkpoint_ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs, - u32 *pmr_flags) -{ - struct pvr_buffer_sync_check_data *data; - struct dma_resv *resv; - struct dma_fence *fence; - u32 fence_count; - bool exclusive; - int i; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return NULL; - - fence_count = pvr_buffer_sync_pmrs_fence_count(nr_pmrs, pmrs, - pmr_flags); - if (fence_count) { - data->fences = kcalloc(fence_count, sizeof(*data->fences), - GFP_KERNEL); - if (!data->fences) - goto err_check_data_free; - } - - for (i = 0; i < nr_pmrs; i++) { - struct dma_resv_iter cursor; - bool include_write_fences; - bool include_read_fences; - u32 write_fence_count = 0; - u32 read_fence_count = 0; - - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - - exclusive = !!(pmr_flags[i] & PVR_BUFFER_FLAG_WRITE); - - dma_resv_count_fences(resv, &read_fence_count, &write_fence_count); - - include_write_fences = (!exclusive || !read_fence_count); - include_read_fences = exclusive; - - dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_READ); - dma_resv_for_each_fence_unlocked(&cursor, fence) { - enum dma_resv_usage usage = dma_resv_iter_usage(&cursor); - - if ((!include_write_fences && usage == DMA_RESV_USAGE_WRITE) || - (!include_read_fences && usage == DMA_RESV_USAGE_READ)) - continue; - - data->fences[data->nr_fences++] = - pvr_fence_create_from_fence(fence_ctx, - sync_checkpoint_ctx, - fence, - PVRSRV_NO_FENCE, - (usage == DMA_RESV_USAGE_WRITE) ? - "write check fence" : - "read check fence"); - if (!data->fences[data->nr_fences - 1]) { - data->nr_fences--; - PVR_FENCE_TRACE(fence, - (usage == DMA_RESV_USAGE_WRITE) ? - "waiting on write fence" : - "waiting on read fence\n"); - WARN_ON(dma_fence_wait(fence, true) <= 0); - } - } - } - - WARN_ON(i != nr_pmrs); - - return data; - -err_check_data_free: - kfree(data); - return NULL; -} - -#else - -static u32 -pvr_buffer_sync_pmrs_fence_count(u32 nr_pmrs, struct _PMR_ **pmrs, - u32 *pmr_flags) -{ - struct dma_resv *resv; - struct dma_resv_list *resv_list; - struct dma_fence *fence; - u32 fence_count = 0; - bool exclusive; - int i; - - for (i = 0; i < nr_pmrs; i++) { - exclusive = !!(pmr_flags[i] & PVR_BUFFER_FLAG_WRITE); - - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - - resv_list = dma_resv_shared_list(resv); - fence = dma_resv_excl_fence(resv); - - if (fence && - (!exclusive || !resv_list || !resv_list->shared_count)) - fence_count++; - - if (exclusive && resv_list) - fence_count += resv_list->shared_count; - } - - return fence_count; -} - -static struct pvr_buffer_sync_check_data * -pvr_buffer_sync_check_fences_create(struct pvr_fence_context *fence_ctx, - PSYNC_CHECKPOINT_CONTEXT sync_checkpoint_ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs, - u32 *pmr_flags) -{ - struct pvr_buffer_sync_check_data *data; - struct dma_resv *resv; - struct dma_resv_list *resv_list; - struct dma_fence *fence; - u32 fence_count; - bool exclusive; - int i, j; - int err; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return NULL; - - fence_count = pvr_buffer_sync_pmrs_fence_count(nr_pmrs, pmrs, - pmr_flags); - if (fence_count) { - data->fences = kcalloc(fence_count, sizeof(*data->fences), - GFP_KERNEL); - if (!data->fences) - goto err_check_data_free; - } - - for (i = 0; i < nr_pmrs; i++) { - resv = pmr_reservation_object_get(pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - - exclusive = !!(pmr_flags[i] & PVR_BUFFER_FLAG_WRITE); - if (!exclusive) { - err = dma_resv_reserve_shared(resv -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - , 1 -#endif - ); - if (err) - goto err_destroy_fences; - } - - resv_list = dma_resv_shared_list(resv); - fence = dma_resv_excl_fence(resv); - - if (fence && - (!exclusive || !resv_list || !resv_list->shared_count)) { - data->fences[data->nr_fences++] = - pvr_fence_create_from_fence(fence_ctx, - sync_checkpoint_ctx, - fence, - PVRSRV_NO_FENCE, - "exclusive check fence"); - if (!data->fences[data->nr_fences - 1]) { - data->nr_fences--; - PVR_FENCE_TRACE(fence, - "waiting on exclusive fence\n"); - WARN_ON(dma_fence_wait(fence, true) <= 0); - } - } - - if (exclusive && resv_list) { - for (j = 0; j < resv_list->shared_count; j++) { - fence = rcu_dereference_protected(resv_list->shared[j], - dma_resv_held(resv)); - data->fences[data->nr_fences++] = - pvr_fence_create_from_fence(fence_ctx, - sync_checkpoint_ctx, - fence, - PVRSRV_NO_FENCE, - "check fence"); - if (!data->fences[data->nr_fences - 1]) { - data->nr_fences--; - PVR_FENCE_TRACE(fence, - "waiting on non-exclusive fence\n"); - WARN_ON(dma_fence_wait(fence, true) <= 0); - } - } - } - } - - WARN_ON((i != nr_pmrs) || (data->nr_fences != fence_count)); - - return data; - -err_destroy_fences: - for (i = 0; i < data->nr_fences; i++) - pvr_fence_destroy(data->fences[i]); - kfree(data->fences); -err_check_data_free: - kfree(data); - return NULL; -} - -#endif - -static void -pvr_buffer_sync_check_fences_destroy(struct pvr_buffer_sync_check_data *data) -{ - int i; - - for (i = 0; i < data->nr_fences; i++) - pvr_fence_destroy(data->fences[i]); - - kfree(data->fences); - kfree(data); -} - -struct pvr_buffer_sync_context * -pvr_buffer_sync_context_create(struct device *dev, const char *name) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - struct pvr_buffer_sync_context *ctx; - int err; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - err = -ENOMEM; - goto err_exit; - } - - ctx->fence_ctx = pvr_fence_context_create(priv->dev_node, - NativeSyncGetFenceStatusWq(), - name); - if (!ctx->fence_ctx) { - err = -ENOMEM; - goto err_free_ctx; - } - - mutex_init(&ctx->ctx_lock); - - return ctx; - -err_free_ctx: - kfree(ctx); -err_exit: - return ERR_PTR(err); -} - -void -pvr_buffer_sync_context_destroy(struct pvr_buffer_sync_context *ctx) -{ - pvr_fence_context_destroy(ctx->fence_ctx); - kfree(ctx); -} - -int -pvr_buffer_sync_resolve_and_create_fences(struct pvr_buffer_sync_context *ctx, - PSYNC_CHECKPOINT_CONTEXT sync_checkpoint_ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs, - u32 *pmr_flags, - u32 *nr_fence_checkpoints_out, - PSYNC_CHECKPOINT **fence_checkpoints_out, - PSYNC_CHECKPOINT *update_checkpoints_out, - struct pvr_buffer_sync_append_data **data_out) -{ - struct pvr_buffer_sync_append_data *data; - PSYNC_CHECKPOINT *fence_checkpoints; - const size_t data_size = sizeof(*data); - const size_t pmrs_size = sizeof(*pmrs) * nr_pmrs; - const size_t pmr_flags_size = sizeof(*pmr_flags) * nr_pmrs; - int i; - int j; - int err; - - if (unlikely((nr_pmrs && !(pmrs && pmr_flags)) || - !nr_fence_checkpoints_out || !fence_checkpoints_out || - !update_checkpoints_out)) - return -EINVAL; - - for (i = 0; i < nr_pmrs; i++) { - if (unlikely(!(pmr_flags[i] & PVR_BUFFER_FLAG_MASK))) { - pr_err("%s: Invalid flags %#08x for pmr %p\n", - __func__, pmr_flags[i], pmrs[i]); - return -EINVAL; - } - } - -#if defined(NO_HARDWARE) - /* - * For NO_HARDWARE there's no checking or updating of sync checkpoints - * which means SW waits on our fences will cause a deadlock (since they - * will never be signalled). Avoid this by not creating any fences. - */ - nr_pmrs = 0; -#endif - - if (!nr_pmrs) { - *nr_fence_checkpoints_out = 0; - *fence_checkpoints_out = NULL; - *update_checkpoints_out = NULL; - *data_out = NULL; - - return 0; - } - - data = kzalloc(data_size + pmrs_size + pmr_flags_size, GFP_KERNEL); - if (unlikely(!data)) - return -ENOMEM; - - data->ctx = ctx; - data->pmrs = (struct _PMR_ **)(void *)(data + 1); - data->pmr_flags = (u32 *)(void *)(data->pmrs + nr_pmrs); - - /* - * It's expected that user space will provide a set of unique PMRs - * but, as a PMR can have multiple handles, it's still possible to - * end up here with duplicates. Take this opportunity to filter out - * any remaining duplicates (updating flags when necessary) before - * trying to process them further. - */ - for (i = 0; i < nr_pmrs; i++) { - for (j = 0; j < data->nr_pmrs; j++) { - if (data->pmrs[j] == pmrs[i]) { - data->pmr_flags[j] |= pmr_flags[i]; - break; - } - } - - if (j == data->nr_pmrs) { - data->pmrs[j] = pmrs[i]; - data->pmr_flags[j] = pmr_flags[i]; - data->nr_pmrs++; - } - } - - err = pvr_buffer_sync_pmrs_lock(ctx, data->nr_pmrs, data->pmrs); - if (unlikely(err)) { - /* - * -EINTR is returned if a signal arrives while trying to acquire a PMR - * lock. In this case the operation should be retried after the signal - * has been serviced. As this is expected behaviour, don't print an - * error in this case. - */ - if (err != -EINTR) { - pr_err("%s: failed to lock pmrs (errno=%d)\n", - __func__, err); - } - goto err_free_data; - } - - /* create the check data */ - data->check_data = pvr_buffer_sync_check_fences_create(ctx->fence_ctx, - sync_checkpoint_ctx, - data->nr_pmrs, - data->pmrs, - data->pmr_flags); - if (unlikely(!data->check_data)) { - err = -ENOMEM; - goto err_pmrs_unlock; - } - - fence_checkpoints = kcalloc(data->check_data->nr_fences, - sizeof(*fence_checkpoints), - GFP_KERNEL); - if (fence_checkpoints) { - pvr_fence_get_checkpoints(data->check_data->fences, - data->check_data->nr_fences, - fence_checkpoints); - } else { - if (unlikely(data->check_data->nr_fences)) { - err = -ENOMEM; - goto err_free_check_data; - } - } - - /* create the update fence */ - data->update_fence = pvr_fence_create(ctx->fence_ctx, - sync_checkpoint_ctx, - SYNC_CHECKPOINT_FOREIGN_CHECKPOINT, "update fence"); - if (unlikely(!data->update_fence)) { - err = -ENOMEM; - goto err_free_fence_checkpoints; - } - - /* - * We need to clean up the fences once the HW has finished with them. - * We can do this using fence callbacks. However, instead of adding a - * callback to every fence, which would result in more work, we can - * simply add one to the update fence since this will be the last fence - * to be signalled. This callback can do all the necessary clean up. - * - * Note: we take an additional reference on the update fence in case - * it signals before we can add it to a reservation object. - */ - PVR_FENCE_TRACE(&data->update_fence->base, - "create fence calling dma_fence_get\n"); - dma_fence_get(&data->update_fence->base); - - *nr_fence_checkpoints_out = data->check_data->nr_fences; - *fence_checkpoints_out = fence_checkpoints; - *update_checkpoints_out = pvr_fence_get_checkpoint(data->update_fence); - *data_out = data; - - return 0; - -err_free_fence_checkpoints: - kfree(fence_checkpoints); -err_free_check_data: - pvr_buffer_sync_check_fences_destroy(data->check_data); -err_pmrs_unlock: - pvr_buffer_sync_pmrs_unlock(ctx, data->nr_pmrs, data->pmrs); -err_free_data: - kfree(data); - return err; -} - -void -pvr_buffer_sync_kick_succeeded(struct pvr_buffer_sync_append_data *data) -{ - struct dma_resv *resv; - int i; - - dma_fence_enable_sw_signaling(&data->update_fence->base); - - for (i = 0; i < data->nr_pmrs; i++) { - resv = pmr_reservation_object_get(data->pmrs[i]); - if (WARN_ON_ONCE(!resv)) - continue; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - dma_resv_reserve_fences(resv, 1); -#endif - if (data->pmr_flags[i] & PVR_BUFFER_FLAG_WRITE) { - PVR_FENCE_TRACE(&data->update_fence->base, - "added exclusive fence (%s) to resv %p\n", - data->update_fence->name, resv); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - dma_resv_add_fence(resv, - &data->update_fence->base, - DMA_RESV_USAGE_WRITE); -#else - dma_resv_add_excl_fence(resv, - &data->update_fence->base); -#endif - } else if (data->pmr_flags[i] & PVR_BUFFER_FLAG_READ) { - PVR_FENCE_TRACE(&data->update_fence->base, - "added non-exclusive fence (%s) to resv %p\n", - data->update_fence->name, resv); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - dma_resv_add_fence(resv, - &data->update_fence->base, - DMA_RESV_USAGE_READ); -#else - dma_resv_add_shared_fence(resv, - &data->update_fence->base); -#endif - } - } - - /* - * Now that the fence has been added to the necessary - * reservation objects we can safely drop the extra reference - * we took in pvr_buffer_sync_resolve_and_create_fences(). - */ - dma_fence_put(&data->update_fence->base); - pvr_buffer_sync_pmrs_unlock(data->ctx, data->nr_pmrs, - data->pmrs); - - /* destroy the check fences */ - pvr_buffer_sync_check_fences_destroy(data->check_data); - /* destroy the update fence */ - pvr_fence_destroy(data->update_fence); - - /* free the append data */ - kfree(data); -} - -void -pvr_buffer_sync_kick_failed(struct pvr_buffer_sync_append_data *data) -{ - - /* drop the extra reference we took on the update fence in - * pvr_buffer_sync_resolve_and_create_fences(). - */ - dma_fence_put(&data->update_fence->base); - - if (data->nr_pmrs > 0) - pvr_buffer_sync_pmrs_unlock(data->ctx, data->nr_pmrs, - data->pmrs); - - /* destroy the check fences */ - pvr_buffer_sync_check_fences_destroy(data->check_data); - /* destroy the update fence */ - pvr_fence_destroy(data->update_fence); - - /* free the append data */ - kfree(data); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.h b/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.h deleted file mode 100644 index 7e85f36faec97..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * @File pvr_buffer_sync.h - * @Title PowerVR Linux buffer sync interface - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_BUFFER_SYNC_H -#define PVR_BUFFER_SYNC_H - -#include -#include -#include - -struct _PMR_; -struct pvr_buffer_sync_context; -struct pvr_buffer_sync_append_data; - -/* - * pvr_buffer_sync_context_create - creates a buffer sync context - * @dev: Linux device - * @name: context name (used for debugging) - * - * pvr_buffer_sync_context_destroy() should be used to clean up the buffer - * sync context. - * - * Return: A buffer sync context or NULL if it fails for any reason. - */ -struct pvr_buffer_sync_context * -pvr_buffer_sync_context_create(struct device *dev, const char *name); - -/* - * pvr_buffer_sync_context_destroy() - frees a buffer sync context - * @ctx: buffer sync context - */ -void -pvr_buffer_sync_context_destroy(struct pvr_buffer_sync_context *ctx); - -/* - * pvr_buffer_sync_resolve_and_create_fences() - create checkpoints from - * buffers - * @ctx: buffer sync context - * @sync_checkpoint_ctx: context in which to create sync checkpoints - * @nr_pmrs: number of buffer objects (PMRs) - * @pmrs: buffer array - * @pmr_flags: internal flags - * @nr_fence_checkpoints_out: returned number of fence sync checkpoints - * @fence_checkpoints_out: returned array of fence sync checkpoints - * @update_checkpoint_out: returned update sync checkpoint - * @data_out: returned buffer sync data - * - * After this call, either pvr_buffer_sync_kick_succeeded() or - * pvr_buffer_sync_kick_failed() must be called. - * - * Return: 0 on success or an error code otherwise. - */ -int -pvr_buffer_sync_resolve_and_create_fences(struct pvr_buffer_sync_context *ctx, - PSYNC_CHECKPOINT_CONTEXT sync_checkpoint_ctx, - u32 nr_pmrs, - struct _PMR_ **pmrs, - u32 *pmr_flags, - u32 *nr_fence_checkpoints_out, - PSYNC_CHECKPOINT **fence_checkpoints_out, - PSYNC_CHECKPOINT *update_checkpoint_out, - struct pvr_buffer_sync_append_data **data_out); - -/* - * pvr_buffer_sync_kick_succeeded() - cleans up after a successful kick - * operation - * @data: buffer sync data returned by - * pvr_buffer_sync_resolve_and_create_fences() - * - * Should only be called following pvr_buffer_sync_resolve_and_create_fences(). - */ -void -pvr_buffer_sync_kick_succeeded(struct pvr_buffer_sync_append_data *data); - -/* - * pvr_buffer_sync_kick_failed() - cleans up after a failed kick operation - * @data: buffer sync data returned by - * pvr_buffer_sync_resolve_and_create_fences() - * - * Should only be called following pvr_buffer_sync_resolve_and_create_fences(). - */ -void -pvr_buffer_sync_kick_failed(struct pvr_buffer_sync_append_data *data); - -#endif /* PVR_BUFFER_SYNC_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync_shared.h b/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync_shared.h deleted file mode 100644 index 7a110910dbd69..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_buffer_sync_shared.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR buffer sync shared -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shared definitions between client and server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_BUFFER_SYNC_SHARED_H -#define PVR_BUFFER_SYNC_SHARED_H - -#define PVR_BUFFER_FLAG_READ (1U << 0) -#define PVR_BUFFER_FLAG_WRITE (1U << 1) -#define PVR_BUFFER_FLAG_MASK (PVR_BUFFER_FLAG_READ | \ - PVR_BUFFER_FLAG_WRITE) - -/* Maximum number of PMRs passed - * in a kick when using buffer sync - */ -#define PVRSRV_MAX_BUFFERSYNC_PMRS 32 - -#endif /* PVR_BUFFER_SYNC_SHARED_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.c b/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.c deleted file mode 100644 index 90bc9eeae5f9a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * @File - * @Title PowerVR Linux software "counting" timeline fence implementation - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Strictly Confidential. - */ - -#include -#include -#include - -#include "services_kernel_client.h" -#include "pvr_counting_timeline.h" -#include "pvr_sw_fence.h" - -#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, fmt, ...) \ - do { \ - if (pfnDumpDebugPrintf) \ - pfnDumpDebugPrintf(pvDumpDebugFile, fmt, \ - ## __VA_ARGS__); \ - else \ - pr_err(fmt "\n", ## __VA_ARGS__); \ - } while (0) - -struct pvr_counting_fence_timeline { - struct pvr_sw_fence_context *context; - - void *dbg_request_handle; - - spinlock_t active_fences_lock; - u64 current_value; /* guarded by active_fences_lock */ - u64 next_value; /* guarded by active_fences_lock */ - struct list_head active_fences; - - struct kref kref; -}; - -struct pvr_counting_fence { - u64 value; - struct dma_fence *fence; - struct list_head active_list_entry; -}; - -void pvr_counting_fence_timeline_dump_timeline( - void *data, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - - struct pvr_counting_fence_timeline *timeline = - (struct pvr_counting_fence_timeline *) data; - unsigned long flags; - - spin_lock_irqsave(&timeline->active_fences_lock, flags); - - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "TL:%s SeqNum: %llu/%llu", - pvr_sw_fence_context_name( - timeline->context), - timeline->current_value, - timeline->next_value); - - spin_unlock_irqrestore(&timeline->active_fences_lock, flags); -} - -static void -pvr_counting_fence_timeline_debug_request(void *data, u32 verbosity, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - struct pvr_counting_fence_timeline *timeline = - (struct pvr_counting_fence_timeline *)data; - struct pvr_counting_fence *obj; - unsigned long flags; - char value[128]; - - if (DD_VERB_LVL_ENABLED(verbosity, DEBUG_REQUEST_VERBOSITY_MEDIUM)) { - spin_lock_irqsave(&timeline->active_fences_lock, flags); - pvr_sw_fence_context_value_str(timeline->context, value, - sizeof(value)); - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "sw: %s @%s cur=%llu", - pvr_sw_fence_context_name(timeline->context), - value, timeline->current_value); - list_for_each_entry(obj, &timeline->active_fences, - active_list_entry) { - obj->fence->ops->fence_value_str(obj->fence, - value, sizeof(value)); - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " @%s: val=%llu", value, obj->value); - } - spin_unlock_irqrestore(&timeline->active_fences_lock, flags); - } -} - -struct pvr_counting_fence_timeline *pvr_counting_fence_timeline_create( - const char *name) -{ - PVRSRV_ERROR srv_err; - struct pvr_counting_fence_timeline *timeline = - kzalloc(sizeof(*timeline), GFP_KERNEL); - - if (!timeline) - goto err_out; - - timeline->context = pvr_sw_fence_context_create(name, - "pvr_sw_sync"); - if (!timeline->context) - goto err_free_timeline; - - srv_err = PVRSRVRegisterDriverDbgRequestNotify( - &timeline->dbg_request_handle, - pvr_counting_fence_timeline_debug_request, - DEBUG_REQUEST_LINUXFENCE, - timeline); - if (srv_err != PVRSRV_OK) { - pr_err("%s: failed to register debug request callback (%s)\n", - __func__, PVRSRVGetErrorString(srv_err)); - goto err_free_timeline_ctx; - } - - timeline->current_value = 0; - timeline->next_value = 1; - kref_init(&timeline->kref); - spin_lock_init(&timeline->active_fences_lock); - INIT_LIST_HEAD(&timeline->active_fences); - -err_out: - return timeline; - -err_free_timeline_ctx: - pvr_sw_fence_context_destroy(timeline->context); - -err_free_timeline: - kfree(timeline); - timeline = NULL; - goto err_out; -} - -void pvr_counting_fence_timeline_force_complete( - struct pvr_counting_fence_timeline *timeline) -{ - struct list_head *entry, *tmp; - unsigned long flags; - - spin_lock_irqsave(&timeline->active_fences_lock, flags); - -#if defined(DEBUG) && !defined(SUPPORT_AUTOVZ) - /* This is just a safety measure. Normally we should never see any - * unsignaled sw fences when we come here. Warn if we still do! - */ - WARN_ON(!list_empty(&timeline->active_fences)); -#endif - - list_for_each_safe(entry, tmp, &timeline->active_fences) { - struct pvr_counting_fence *fence = - list_entry(entry, struct pvr_counting_fence, - active_list_entry); - dma_fence_signal(fence->fence); - dma_fence_put(fence->fence); - fence->fence = NULL; - list_del(&fence->active_list_entry); - kfree(fence); - } - spin_unlock_irqrestore(&timeline->active_fences_lock, flags); -} - -static void pvr_counting_fence_timeline_destroy( - struct kref *kref) -{ - struct pvr_counting_fence_timeline *timeline = - container_of(kref, struct pvr_counting_fence_timeline, kref); - - WARN_ON(!list_empty(&timeline->active_fences)); - - PVRSRVUnregisterDriverDbgRequestNotify(timeline->dbg_request_handle); - - pvr_sw_fence_context_destroy(timeline->context); - kfree(timeline); -} - -void pvr_counting_fence_timeline_put( - struct pvr_counting_fence_timeline *timeline) -{ - kref_put(&timeline->kref, pvr_counting_fence_timeline_destroy); -} - -struct pvr_counting_fence_timeline *pvr_counting_fence_timeline_get( - struct pvr_counting_fence_timeline *timeline) -{ - if (!timeline) - return NULL; - kref_get(&timeline->kref); - return timeline; -} - -struct dma_fence *pvr_counting_fence_create( - struct pvr_counting_fence_timeline *timeline, u64 *sync_pt_idx) -{ - unsigned long flags; - struct dma_fence *sw_fence; - struct pvr_counting_fence *fence = kmalloc(sizeof(*fence), GFP_KERNEL); - - if (!fence) - return NULL; - - sw_fence = pvr_sw_fence_create(timeline->context); - if (!sw_fence) - goto err_free_fence; - - fence->fence = dma_fence_get(sw_fence); - - spin_lock_irqsave(&timeline->active_fences_lock, flags); - - fence->value = timeline->next_value++; - if (sync_pt_idx) - *sync_pt_idx = fence->value; - - list_add_tail(&fence->active_list_entry, &timeline->active_fences); - - spin_unlock_irqrestore(&timeline->active_fences_lock, flags); - - /* Counting fences can be signalled any time after creation */ - dma_fence_enable_sw_signaling(sw_fence); - - return sw_fence; - -err_free_fence: - kfree(fence); - return NULL; -} - -bool pvr_counting_fence_timeline_inc( - struct pvr_counting_fence_timeline *timeline, u64 *sync_pt_idx) -{ - struct list_head *entry, *tmp; - unsigned long flags; - bool res; - - spin_lock_irqsave(&timeline->active_fences_lock, flags); - - if (timeline->current_value == timeline->next_value-1) { - res = false; - goto exit_unlock; - } - - timeline->current_value++; - - if (sync_pt_idx) - *sync_pt_idx = timeline->current_value; - - list_for_each_safe(entry, tmp, &timeline->active_fences) { - struct pvr_counting_fence *fence = - list_entry(entry, struct pvr_counting_fence, - active_list_entry); - if (fence->value <= timeline->current_value) { - dma_fence_signal(fence->fence); - dma_fence_put(fence->fence); - fence->fence = NULL; - list_del(&fence->active_list_entry); - kfree(fence); - } - } - - res = true; - -exit_unlock: - spin_unlock_irqrestore(&timeline->active_fences_lock, flags); - - return res; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.h b/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.h deleted file mode 100644 index f77cfbf1b1162..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_counting_timeline.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * @File - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Strictly Confidential. - */ - -#if !defined(__PVR_COUNTING_TIMELINE_H__) -#define __PVR_COUNTING_TIMELINE_H__ - -#include "pvr_linux_fence.h" - -struct pvr_counting_fence_timeline; - -void pvr_counting_fence_timeline_dump_timeline( - void *data, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file); - -struct pvr_counting_fence_timeline *pvr_counting_fence_timeline_create( - const char *name); -void pvr_counting_fence_timeline_put( - struct pvr_counting_fence_timeline *fence_timeline); -struct pvr_counting_fence_timeline *pvr_counting_fence_timeline_get( - struct pvr_counting_fence_timeline *fence_timeline); -struct dma_fence *pvr_counting_fence_create( - struct pvr_counting_fence_timeline *fence_timeline, u64 *sync_pt_idx); -bool pvr_counting_fence_timeline_inc( - struct pvr_counting_fence_timeline *fence_timeline, u64 *sync_pt_idx); -void pvr_counting_fence_timeline_force_complete( - struct pvr_counting_fence_timeline *fence_timeline); - -#endif /* !defined(__PVR_COUNTING_TIMELINE_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_debug.c b/drivers/gpu/drm/img-rogue/1.17/pvr_debug.c deleted file mode 100644 index 8cd34dc221ada..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_debug.c +++ /dev/null @@ -1,481 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Debug Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides kernel side Debug Functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "linkage.h" -#include "pvrsrv.h" -#include "osfunc.h" -#include "di_server.h" - -#if defined(PVRSRV_NEED_PVR_DPF) - -/******** BUFFERED LOG MESSAGES ********/ - -/* Because we don't want to have to handle CCB wrapping, each buffered - * message is rounded up to PVRSRV_DEBUG_CCB_MESG_MAX bytes. This means - * there is the same fixed number of messages that can be stored, - * regardless of message length. - */ - -#if defined(PVRSRV_DEBUG_CCB_MAX) - -#define PVRSRV_DEBUG_CCB_MESG_MAX PVR_MAX_DEBUG_MESSAGE_LEN - -typedef struct -{ - const IMG_CHAR *pszFile; - IMG_INT iLine; - IMG_UINT32 ui32TID; - IMG_UINT32 ui32PID; - IMG_CHAR pcMesg[PVRSRV_DEBUG_CCB_MESG_MAX]; - struct timeval sTimeVal; -} -PVRSRV_DEBUG_CCB; - -static PVRSRV_DEBUG_CCB gsDebugCCB[PVRSRV_DEBUG_CCB_MAX]; - -static IMG_UINT giOffset; - -/* protects access to gsDebugCCB */ -static DEFINE_SPINLOCK(gsDebugCCBLock); - -static void -AddToBufferCCB(const IMG_CHAR *pszFileName, IMG_UINT32 ui32Line, - const IMG_CHAR *szBuffer) -{ - unsigned long uiFlags; - - spin_lock_irqsave(&gsDebugCCBLock, uiFlags); - - gsDebugCCB[giOffset].pszFile = pszFileName; - gsDebugCCB[giOffset].iLine = ui32Line; - gsDebugCCB[giOffset].ui32TID = current->pid; - gsDebugCCB[giOffset].ui32PID = current->tgid; - - do_gettimeofday(&gsDebugCCB[giOffset].sTimeVal); - - OSStringLCopy(gsDebugCCB[giOffset].pcMesg, szBuffer, - PVRSRV_DEBUG_CCB_MESG_MAX); - - giOffset = (giOffset + 1) % PVRSRV_DEBUG_CCB_MAX; - - spin_unlock_irqrestore(&gsDebugCCBLock, uiFlags); -} - -void PVRSRVDebugPrintfDumpCCB(void) -{ - int i; - unsigned long uiFlags; - - spin_lock_irqsave(&gsDebugCCBLock, uiFlags); - - for (i = 0; i < PVRSRV_DEBUG_CCB_MAX; i++) - { - PVRSRV_DEBUG_CCB *psDebugCCBEntry = - &gsDebugCCB[(giOffset + i) % PVRSRV_DEBUG_CCB_MAX]; - - /* Early on, we won't have PVRSRV_DEBUG_CCB_MAX messages */ - if (!psDebugCCBEntry->pszFile) - { - continue; - } - - printk(KERN_ERR "%s:%d: (%ld.%ld, tid=%u, pid=%u) %s\n", - psDebugCCBEntry->pszFile, - psDebugCCBEntry->iLine, - (long)psDebugCCBEntry->sTimeVal.tv_sec, - (long)psDebugCCBEntry->sTimeVal.tv_usec, - psDebugCCBEntry->ui32TID, - psDebugCCBEntry->ui32PID, - psDebugCCBEntry->pcMesg); - - /* Clear this entry so it doesn't get printed the next time again. */ - psDebugCCBEntry->pszFile = NULL; - } - - spin_unlock_irqrestore(&gsDebugCCBLock, uiFlags); -} - -#else /* defined(PVRSRV_DEBUG_CCB_MAX) */ - -static INLINE void -AddToBufferCCB(const IMG_CHAR *pszFileName, IMG_UINT32 ui32Line, - const IMG_CHAR *szBuffer) -{ - (void)pszFileName; - (void)szBuffer; - (void)ui32Line; -} - -void PVRSRVDebugPrintfDumpCCB(void) -{ - /* Not available */ -} - -#endif /* defined(PVRSRV_DEBUG_CCB_MAX) */ - -static IMG_UINT32 gPVRDebugLevel = - ( - DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING -#if defined(PVRSRV_DEBUG_CCB_MAX) - | DBGPRIV_BUFFERED -#endif /* defined(PVRSRV_DEBUG_CCB_MAX) */ -#if defined(PVR_DPF_ADHOC_DEBUG_ON) - | DBGPRIV_DEBUG -#endif /* defined(PVR_DPF_ADHOC_DEBUG_ON) */ - ); - -module_param(gPVRDebugLevel, uint, 0644); -MODULE_PARM_DESC(gPVRDebugLevel, - "Sets the level of debug output (default 0x7)"); - -IMG_UINT32 OSDebugLevel(void) -{ - return gPVRDebugLevel; -} - -void OSSetDebugLevel(IMG_UINT32 ui32DebugLevel) -{ - gPVRDebugLevel = ui32DebugLevel; -} - -IMG_BOOL OSIsDebugLevel(IMG_UINT32 ui32DebugLevel) -{ - return (gPVRDebugLevel & ui32DebugLevel) != 0; -} - -#else /* defined(PVRSRV_NEED_PVR_DPF) */ - -IMG_UINT32 OSDebugLevel(void) -{ - return 0; -} - -void OSSetDebugLevel(IMG_UINT32 ui32DebugLevel) -{ - PVR_UNREFERENCED_PARAMETER(ui32DebugLevel); -} - -IMG_BOOL OSIsDebugLevel(IMG_UINT32 ui32DebugLevel) -{ - PVR_UNREFERENCED_PARAMETER(ui32DebugLevel); - return IMG_FALSE; -} - -#endif /* defined(PVRSRV_NEED_PVR_DPF) */ - -#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN - -/* Message buffer for messages */ -static IMG_CHAR gszBuffer[PVR_MAX_MSG_LEN + 1]; - -/* The lock is used to control access to gszBuffer */ -static DEFINE_SPINLOCK(gsDebugLock); - -/* - * Append a string to a buffer using formatted conversion. - * The function takes a variable number of arguments, pointed - * to by the var args list. - */ -__printf(3, 0) -static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, va_list VArgs) -{ - IMG_UINT32 ui32Used; - IMG_UINT32 ui32Space; - IMG_INT32 i32Len; - - ui32Used = OSStringLength(pszBuf); - BUG_ON(ui32Used >= ui32BufSiz); - ui32Space = ui32BufSiz - ui32Used; - - i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs); - pszBuf[ui32BufSiz - 1] = 0; - - /* Return true if string was truncated */ - return i32Len < 0 || i32Len >= (IMG_INT32)ui32Space; -} - -/*************************************************************************/ /*! -@Function PVRSRVReleasePrintf -@Description To output an important message to the user in release builds -@Input pszFormat The message format string -@Input ... Zero or more arguments for use by the format string -*/ /**************************************************************************/ -void PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) -{ - va_list vaArgs; - unsigned long ulLockFlags = 0; - IMG_CHAR *pszBuf = gszBuffer; - IMG_UINT32 ui32BufSiz = sizeof(gszBuffer); - IMG_INT32 result; - - va_start(vaArgs, pszFormat); - - spin_lock_irqsave(&gsDebugLock, ulLockFlags); - - result = snprintf(pszBuf, (ui32BufSiz - 2), "PVR_K: %u: ", current->pid); - PVR_ASSERT(result>0); - ui32BufSiz -= result; - - if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs)) - { - printk(KERN_INFO "%s (truncated)\n", pszBuf); - } - else - { - printk(KERN_INFO "%s\n", pszBuf); - } - - spin_unlock_irqrestore(&gsDebugLock, ulLockFlags); - va_end(vaArgs); -} - -#if defined(PVRSRV_NEED_PVR_TRACE) - -/*************************************************************************/ /*! -@Function PVRTrace -@Description To output a debug message to the user -@Input pszFormat The message format string -@Input ... Zero or more arguments for use by the format string -*/ /**************************************************************************/ -void PVRSRVTrace(const IMG_CHAR *pszFormat, ...) -{ - va_list VArgs; - unsigned long ulLockFlags = 0; - IMG_CHAR *pszBuf = gszBuffer; - IMG_UINT32 ui32BufSiz = sizeof(gszBuffer); - IMG_INT32 result; - - va_start(VArgs, pszFormat); - - spin_lock_irqsave(&gsDebugLock, ulLockFlags); - - result = snprintf(pszBuf, (ui32BufSiz - 2), "PVR: %u: ", current->pid); - PVR_ASSERT(result>0); - ui32BufSiz -= result; - - if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs)) - { - printk(KERN_ERR "PVR_K:(Message Truncated): %s\n", pszBuf); - } - else - { - printk(KERN_ERR "%s\n", pszBuf); - } - - spin_unlock_irqrestore(&gsDebugLock, ulLockFlags); - - va_end(VArgs); -} - -#endif /* defined(PVRSRV_NEED_PVR_TRACE) */ - -#if defined(PVRSRV_NEED_PVR_DPF) - -/* - * Append a string to a buffer using formatted conversion. - * The function takes a variable number of arguments, calling - * VBAppend to do the actual work. - */ -__printf(3, 4) -static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...) -{ - va_list VArgs; - IMG_BOOL bTrunc; - - va_start (VArgs, pszFormat); - - bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs); - - va_end (VArgs); - - return bTrunc; -} - -/*************************************************************************/ /*! -@Function PVRSRVDebugPrintf -@Description To output a debug message to the user -@Input uDebugLevel The current debug level -@Input pszFile The source file generating the message -@Input uLine The line of the source file -@Input pszFormat The message format string -@Input ... Zero or more arguments for use by the format string -*/ /**************************************************************************/ -void PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel, - const IMG_CHAR *pszFullFileName, - IMG_UINT32 ui32Line, - const IMG_CHAR *pszFormat, - ...) -{ - const IMG_CHAR *pszFileName = pszFullFileName; - IMG_CHAR *pszLeafName; - va_list vaArgs; - unsigned long ulLockFlags = 0; - IMG_CHAR *pszBuf = gszBuffer; - IMG_UINT32 ui32BufSiz = sizeof(gszBuffer); - - if (!(gPVRDebugLevel & ui32DebugLevel)) - { - return; - } - - va_start(vaArgs, pszFormat); - - spin_lock_irqsave(&gsDebugLock, ulLockFlags); - - switch (ui32DebugLevel) - { - case DBGPRIV_FATAL: - { - OSStringLCopy(pszBuf, "PVR_K:(Fatal): ", ui32BufSiz); - PVRSRV_REPORT_ERROR(); - break; - } - case DBGPRIV_ERROR: - { - OSStringLCopy(pszBuf, "PVR_K:(Error): ", ui32BufSiz); - PVRSRV_REPORT_ERROR(); - break; - } - case DBGPRIV_WARNING: - { - OSStringLCopy(pszBuf, "PVR_K:(Warn): ", ui32BufSiz); - break; - } - case DBGPRIV_MESSAGE: - { - OSStringLCopy(pszBuf, "PVR_K:(Mesg): ", ui32BufSiz); - break; - } - case DBGPRIV_VERBOSE: - { - OSStringLCopy(pszBuf, "PVR_K:(Verb): ", ui32BufSiz); - break; - } - case DBGPRIV_DEBUG: - { - OSStringLCopy(pszBuf, "PVR_K:(Debug): ", ui32BufSiz); - break; - } - case DBGPRIV_CALLTRACE: - case DBGPRIV_ALLOC: - case DBGPRIV_BUFFERED: - default: - { - OSStringLCopy(pszBuf, "PVR_K: ", ui32BufSiz); - break; - } - } - - if (current->pid == task_tgid_nr(current)) - { - (void) BAppend(pszBuf, ui32BufSiz, "%5u: ", current->pid); - } - else - { - (void) BAppend(pszBuf, ui32BufSiz, "%5u-%5u: ", task_tgid_nr(current) /* pid id of group*/, current->pid /* task id */); - } - - if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs)) - { - printk(KERN_ERR "%s (truncated)\n", pszBuf); - } - else - { - IMG_BOOL bTruncated = IMG_FALSE; - -#if !defined(__sh__) - pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '/'); - - if (pszLeafName) - { - pszFileName = pszLeafName+1; - } -#endif /* __sh__ */ - -#if defined(DEBUG) - { - static const IMG_CHAR *lastFile; - - if (lastFile == pszFileName) - { - bTruncated = BAppend(pszBuf, ui32BufSiz, " [%u]", ui32Line); - } - else - { - bTruncated = BAppend(pszBuf, ui32BufSiz, " [%s:%u]", pszFileName, ui32Line); - lastFile = pszFileName; - } - } -#else - bTruncated = BAppend(pszBuf, ui32BufSiz, " [%u]", ui32Line); -#endif - - if (bTruncated) - { - printk(KERN_ERR "%s (truncated)\n", pszBuf); - } - else - { - if (ui32DebugLevel & DBGPRIV_BUFFERED) - { - AddToBufferCCB(pszFileName, ui32Line, pszBuf); - } - else - { - printk(KERN_ERR "%s\n", pszBuf); - } - } - } - - spin_unlock_irqrestore(&gsDebugLock, ulLockFlags); - - va_end (vaArgs); -} - -#endif /* PVRSRV_NEED_PVR_DPF */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_debug.h b/drivers/gpu/drm/img-rogue/1.17/pvr_debug.h deleted file mode 100644 index 56bbb13f1c161..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_debug.h +++ /dev/null @@ -1,898 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR Debug Declarations -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides debug functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_DEBUG_H -#define PVR_DEBUG_H - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" - -/*! @cond Doxygen_Suppress */ -#if defined(_MSC_VER) -# define MSC_SUPPRESS_4127 __pragma(warning(suppress:4127)) -#else -# define MSC_SUPPRESS_4127 -#endif -/*! @endcond */ - -#if defined(__cplusplus) -extern "C" { -#endif - -#define PVR_MAX_DEBUG_MESSAGE_LEN (512) /*!< Max length of a Debug Message */ - -/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */ -#define DBGPRIV_FATAL 0x001UL /*!< Debug-Fatal. Privately used by pvr_debug. */ -#define DBGPRIV_ERROR 0x002UL /*!< Debug-Error. Privately used by pvr_debug. */ -#define DBGPRIV_WARNING 0x004UL /*!< Debug-Warning. Privately used by pvr_debug. */ -#define DBGPRIV_MESSAGE 0x008UL /*!< Debug-Message. Privately used by pvr_debug. */ -#define DBGPRIV_VERBOSE 0x010UL /*!< Debug-Verbose. Privately used by pvr_debug. */ -#define DBGPRIV_CALLTRACE 0x020UL /*!< Debug-CallTrace. Privately used by pvr_debug. */ -#define DBGPRIV_ALLOC 0x040UL /*!< Debug-Alloc. Privately used by pvr_debug. */ -#define DBGPRIV_BUFFERED 0x080UL /*!< Debug-Buffered. Privately used by pvr_debug. */ -#define DBGPRIV_DEBUG 0x100UL /*!< Debug-AdHoc-Debug. Never submitted. Privately used by pvr_debug. */ -#define DBGPRIV_LAST 0x100UL /*!< Always set to highest mask value. Privately used by pvr_debug. */ - -/* Enable DPF logging for locally from some make targets */ -#if defined(PVRSRV_NEED_PVR_DPF_LOCAL) -#undef PVRSRV_NEED_PVR_DPF -#define PVRSRV_NEED_PVR_DPF -#endif - -#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG) -#define PVRSRV_NEED_PVR_ASSERT -#endif - -#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF) -#define PVRSRV_NEED_PVR_DPF -#endif - -#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING)) -#define PVRSRV_NEED_PVR_TRACE -#endif - -#if !defined(DOXYGEN) -/*************************************************************************/ /* -PVRSRVGetErrorString -Returns a string describing the provided PVRSRV_ERROR code -NB No doxygen comments provided as this function does not require porting - for other operating systems -*/ /**************************************************************************/ -const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError); -#define PVRSRVGETERRORSTRING PVRSRVGetErrorString -#endif - -/* PVR_ASSERT() and PVR_DBG_BREAK handling */ - -#if defined(__KLOCWORK__) -/* A dummy no-return function to be used under Klocwork to mark unreachable - paths instead of abort() in order to avoid MISRA.STDLIB.ABORT issues. */ -__noreturn void klocwork_abort(void); -#endif - -#if defined(PVRSRV_NEED_PVR_ASSERT) || defined(DOXYGEN) - -/* Unfortunately the Klocwork static analysis checker doesn't understand our - * ASSERT macros. Thus it reports lots of false positive. Defining our Assert - * macros in a special way when the code is analysed by Klocwork avoids - * them. - */ -#if defined(__KLOCWORK__) -#define PVR_ASSERT(x) do { if (!(x)) {klocwork_abort();} } while (false) -#else /* ! __KLOCWORKS__ */ - -#if defined(_WIN32) -#define PVR_ASSERT(expr) do \ - { \ - MSC_SUPPRESS_4127 \ - if (unlikely(!(expr))) \ - { \ - PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__,\ - "*** Debug assertion failed!"); \ - __debugbreak(); \ - } \ - MSC_SUPPRESS_4127 \ - } while (false) - -#else - -#if defined(__linux__) && defined(__KERNEL__) -#include -#include - -/* In Linux kernel mode, use WARN_ON() directly. This produces the - * correct filename and line number in the warning message. - */ -#define PVR_ASSERT(EXPR) do \ - { \ - if (unlikely(!(EXPR))) \ - { \ - PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__, \ - "Debug assertion failed!"); \ - WARN_ON(1); \ - } \ - } while (false) - -#else /* defined(__linux__) && defined(__KERNEL__) */ - -/*************************************************************************/ /*! -@Function PVRSRVDebugAssertFail -@Description Indicate to the user that a debug assertion has failed and - prevent the program from continuing. - Invoked from the macro PVR_ASSERT(). -@Input pszFile The name of the source file where the assertion failed -@Input ui32Line The line number of the failed assertion -@Input pszAssertion String describing the assertion -@Return NEVER! -*/ /**************************************************************************/ -IMG_EXPORT void IMG_CALLCONV __noreturn -PVRSRVDebugAssertFail(const IMG_CHAR *pszFile, - IMG_UINT32 ui32Line, - const IMG_CHAR *pszAssertion); - -#define PVR_ASSERT(EXPR) do \ - { \ - if (unlikely(!(EXPR))) \ - { \ - PVRSRVDebugAssertFail(__FILE__, __LINE__, #EXPR); \ - } \ - } while (false) - -#endif /* defined(__linux__) && defined(__KERNEL__) */ -#endif /* defined(_WIN32) */ -#endif /* defined(__KLOCWORK__) */ - -#if defined(__KLOCWORK__) - #define PVR_DBG_BREAK do { klocwork_abort(); } while (false) -#else - #if defined(WIN32) - #define PVR_DBG_BREAK __debugbreak() /*!< Implementation of PVR_DBG_BREAK for (non-WinCE) Win32 */ - #else - #if defined(PVR_DBG_BREAK_ASSERT_FAIL) - /*!< Implementation of PVR_DBG_BREAK that maps onto PVRSRVDebugAssertFail */ - #if defined(_WIN32) - #define PVR_DBG_BREAK DBG_BREAK - #else - #if defined(__linux__) && defined(__KERNEL__) - #define PVR_DBG_BREAK BUG() - #else - #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__, "PVR_DBG_BREAK") - #endif - #endif - #else - /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */ - #define PVR_DBG_BREAK - #endif - #endif -#endif - - -#else /* defined(PVRSRV_NEED_PVR_ASSERT) */ - /* Unfortunately the Klocwork static analysis checker doesn't understand our - * ASSERT macros. Thus it reports lots of false positive. Defining our Assert - * macros in a special way when the code is analysed by Klocwork avoids - * them. - */ - #if defined(__KLOCWORK__) && !defined(SERVICES_SC) - #define PVR_ASSERT(EXPR) do { if (!(EXPR)) {klocwork_abort();} } while (false) - #else - #define PVR_ASSERT(EXPR) (void)(EXPR) /*!< Null Implementation of PVR_ASSERT (does nothing) */ - #endif - - #define PVR_DBG_BREAK /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */ - -#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */ - - -/* PVR_DPF() handling */ - -#if defined(PVRSRV_NEED_PVR_DPF) || defined(DOXYGEN) - - /* New logging mechanism */ - #define PVR_DBG_FATAL DBGPRIV_FATAL /*!< Debug level passed to PVRSRVDebugPrintf() for fatal errors. */ - #define PVR_DBG_ERROR DBGPRIV_ERROR /*!< Debug level passed to PVRSRVDebugPrintf() for non-fatal errors. */ - #define PVR_DBG_WARNING DBGPRIV_WARNING /*!< Debug level passed to PVRSRVDebugPrintf() for warnings. */ - #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE /*!< Debug level passed to PVRSRVDebugPrintf() for information only. */ - #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE /*!< Debug level passed to PVRSRVDebugPrintf() for very low-priority debug. */ - #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE /*!< Debug level passed to PVRSRVDebugPrintf() for function tracing purposes. */ - #define PVR_DBG_ALLOC DBGPRIV_ALLOC /*!< Debug level passed to PVRSRVDebugPrintf() for tracking some of drivers memory operations. */ - #define PVR_DBG_BUFFERED DBGPRIV_BUFFERED /*!< Debug level passed to PVRSRVDebugPrintf() when debug should be written to the debug circular buffer. */ - #define PVR_DBG_DEBUG DBGPRIV_DEBUG /*!< Debug level passed to PVRSRVDebugPrintf() for debug messages. */ - - /* These levels are always on with PVRSRV_NEED_PVR_DPF */ - /*! @cond Doxygen_Suppress */ - #define PVR_DPF_0x001UL(...) PVRSRVDebugPrintf(DBGPRIV_FATAL, __VA_ARGS__) - #define PVR_DPF_0x002UL(...) PVRSRVDebugPrintf(DBGPRIV_ERROR, __VA_ARGS__) - #define PVR_DPF_0x080UL(...) PVRSRVDebugPrintf(DBGPRIV_BUFFERED, __VA_ARGS__) - - /* - * The AdHoc-Debug level is only supported when enabled in the local - * build environment and may need to be used in both debug and release - * builds. An error is generated in the formal build if it is checked in. - */ -#if defined(PVR_DPF_ADHOC_DEBUG_ON) - #define PVR_DPF_0x100UL(...) PVRSRVDebugPrintf(DBGPRIV_DEBUG, __VA_ARGS__) -#else - /* Use an undefined token here to stop compilation dead in the offending module */ - #define PVR_DPF_0x100UL(...) __ERROR__PVR_DBG_DEBUG_is_in_use_but_has_not_been_enabled__Note_Debug_DPF_must_not_be_checked_in__Define_PVR_DPF_ADHOC_DEBUG_ON_for_testing -#endif - - /* Some are compiled out completely in release builds */ -#if defined(DEBUG) || defined(DOXYGEN) - #define PVR_DPF_0x004UL(...) PVRSRVDebugPrintf(DBGPRIV_WARNING, __VA_ARGS__) - #define PVR_DPF_0x008UL(...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, __VA_ARGS__) - #define PVR_DPF_0x010UL(...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, __VA_ARGS__) - #define PVR_DPF_0x020UL(...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, __VA_ARGS__) - #define PVR_DPF_0x040UL(...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, __VA_ARGS__) -#else - #define PVR_DPF_0x004UL(...) - #define PVR_DPF_0x008UL(...) - #define PVR_DPF_0x010UL(...) - #define PVR_DPF_0x020UL(...) - #define PVR_DPF_0x040UL(...) -#endif - - /* Translate the different log levels to separate macros - * so they can each be compiled out. - */ -#if defined(DEBUG) - #define PVR_DPF_EX(lvl, ...) PVR_DPF_ ## lvl (__FILE__, __LINE__, __VA_ARGS__) -#else - #define PVR_DPF_EX(lvl, ...) PVR_DPF_ ## lvl ("", __LINE__, __VA_ARGS__) -#endif - /*! @endcond */ - - /* Get rid of the double bracketing */ - #define PVR_DPF(x) PVR_DPF_EX x - - #define PVR_LOG_ERROR(_rc, _call) \ - PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)) - - #define PVR_LOG_IF_ERROR(_rc, _call) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_WARN_IF_ERROR(_rc, _call) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_NOMEM(_expr, _call) do \ - { if (unlikely(_expr == NULL)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s failed (PVRSRV_ERROR_OUT_OF_MEMORY) in %s()", _call, __func__)); \ - return PVRSRV_ERROR_OUT_OF_MEMORY; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_NOMEM(_expr, _err, _go) do \ - { if (unlikely(_expr == NULL)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s failed (PVRSRV_ERROR_OUT_OF_MEMORY) in %s()", #_expr, __func__)); \ - _err = PVRSRV_ERROR_OUT_OF_MEMORY; \ - goto _go; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_ERROR(_rc, _call) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - return _rc; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_VOID_IF_ERROR(_rc, _call) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - return; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_ERROR(_rc, _call, _go) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - goto _go; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_WITH_ERROR(_call, _err, _rc, _go) do \ - { PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \ - _err = _rc; \ - goto _go; \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_IF_FALSE(_expr, _msg) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \ - } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_FALSE(_expr, _msg, _rc) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \ - return _rc; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_VOID_IF_FALSE(_expr, _msg) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \ - return; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_FALSE(_expr, _msg, _go) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \ - goto _go; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_INVALID_PARAM(_expr, _param) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s invalid in %s()", _param, __func__)); \ - return PVRSRV_ERROR_INVALID_PARAMS; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, "%s invalid in %s()", #_expr, __func__)); \ - _err = PVRSRV_ERROR_INVALID_PARAMS; \ - goto _go; } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_MSG(_lvl, _msg) \ - PVR_DPF((_lvl, ("In %s() "_msg), __func__)) - - #define PVR_LOG_VA(_lvl, _msg, ...) \ - PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__)) - - #define PVR_LOG_IF_ERROR_VA(_lvl, _rc, _msg, ...) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__)); \ - } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_IF_FALSE_VA(_lvl, _expr, _msg, ...) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__)); \ - } \ - MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_ERROR_VA(_rc, _msg, ...) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \ - return _rc; \ - } MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_ERROR_VA(_rc, _go, _msg, ...) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \ - goto _go; \ - } MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_RETURN_IF_FALSE_VA(_expr, _rc, _msg, ...) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, ("At %s: "_msg), __func__, __VA_ARGS__)); \ - return _rc; \ - } MSC_SUPPRESS_4127\ - } while (false) - - #define PVR_LOG_GOTO_IF_FALSE_VA(_expr, _go, _msg, ...) do \ - { if (unlikely(!(_expr))) { \ - PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \ - goto _go; \ - } MSC_SUPPRESS_4127\ - } while (false) - -#else /* defined(PVRSRV_NEED_PVR_DPF) */ - - #define PVR_DPF(X) /*!< Null Implementation of PowerVR Debug Printf (does nothing) */ - - #define PVR_LOG_MSG(_lvl, _msg) - #define PVR_LOG_VA(_lvl, _msg, ...) - #define PVR_LOG_ERROR(_rc, _call) (void)(_rc) - #define PVR_LOG_IF_ERROR(_rc, _call) (void)(_rc) - #define PVR_WARN_IF_ERROR(_rc, _call) (void)(_rc) - - #define PVR_LOG_IF_ERROR_VA(_lvl, _rc, _msg, ...) (void)(_rc) - #define PVR_LOG_IF_FALSE_VA(_lvl, _expr, _msg, ...) (void)(_expr) - - #define PVR_LOG_RETURN_IF_NOMEM(_expr, _call) do { if (unlikely(_expr == NULL)) { return PVRSRV_ERROR_OUT_OF_MEMORY; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_IF_NOMEM(_expr, _err, _go) do { if (unlikely(_expr == NULL)) { _err = PVRSRV_ERROR_OUT_OF_MEMORY; goto _go; } MSC_SUPPRESS_4127 } while (false) - - #define PVR_LOG_RETURN_IF_ERROR(_rc, _call) do { if (unlikely(_rc != PVRSRV_OK)) { return (_rc); } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_RETURN_IF_ERROR_VA(_rc, _msg, ...) do { if (unlikely(_rc != PVRSRV_OK)) { return (_rc); } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_RETURN_VOID_IF_ERROR(_rc, _call) do { if (unlikely(_rc != PVRSRV_OK)) { return; } MSC_SUPPRESS_4127 } while (false) - - #define PVR_LOG_GOTO_IF_ERROR(_rc, _call, _go) do { if (unlikely(_rc != PVRSRV_OK)) { goto _go; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_IF_ERROR_VA(_rc, _go, _msg, ...) do { if (unlikely(_rc != PVRSRV_OK)) { goto _go; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_WITH_ERROR(_call, _err, _rc, _go) do { _err = _rc; goto _go; MSC_SUPPRESS_4127 } while (false) - - #define PVR_LOG_IF_FALSE(_expr, _msg) (void)(_expr) - #define PVR_LOG_RETURN_IF_FALSE(_expr, _msg, _rc) do { if (unlikely(!(_expr))) { return (_rc); } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_RETURN_IF_FALSE_VA(_expr, _rc, _msg, ...) do { if (unlikely(!(_expr))) { return (_rc); } MSC_SUPPRESS_4127 } while (false) - - #define PVR_LOG_RETURN_VOID_IF_FALSE(_expr, _msg) do { if (unlikely(!(_expr))) { return; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_IF_FALSE(_expr, _msg, _go) do { if (unlikely(!(_expr))) { goto _go; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_IF_FALSE_VA(_expr, _go, _msg, ...) do { if (unlikely(!(_expr))) { goto _go; } MSC_SUPPRESS_4127 } while (false) - - #define PVR_LOG_RETURN_IF_INVALID_PARAM(_expr, _param) do { if (unlikely(!(_expr))) { return PVRSRV_ERROR_INVALID_PARAMS; } MSC_SUPPRESS_4127 } while (false) - #define PVR_LOG_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do { if (unlikely(!(_expr))) { _err = PVRSRV_ERROR_INVALID_PARAMS; goto _go; } MSC_SUPPRESS_4127 } while (false) - - #undef PVR_DPF_FUNCTION_TRACE_ON - -#endif /* defined(PVRSRV_NEED_PVR_DPF) */ - -/*************************************************************************/ /*! -@Function PVRSRVDebugPrintf -@Description Output a debug message to the user, using an OS-specific - method, to a log or console which can be read by developers - Invoked from the macro PVR_DPF(). -@Input ui32DebugLevel The debug level of the message. This can - be used to restrict the output of debug - messages based on their severity. - If this is PVR_DBG_BUFFERED, the message - should be written into a debug circular - buffer instead of being output immediately - (useful when performance would otherwise - be adversely affected). - The debug circular buffer shall only be - output when PVRSRVDebugPrintfDumpCCB() is - called. -@Input pszFileName The source file containing the code that is - generating the message -@Input ui32Line The line number in the source file -@Input pszFormat The formatted message string -@Input ... Zero or more arguments for use by the - formatted string -@Return None -*/ /**************************************************************************/ -IMG_EXPORT void IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel, - const IMG_CHAR *pszFileName, - IMG_UINT32 ui32Line, - const IMG_CHAR *pszFormat, - ...) __printf(4, 5); - -/*************************************************************************/ /*! -@Function PVRSRVDebugPrintfDumpCCB -@Description When PVRSRVDebugPrintf() is called with the ui32DebugLevel - specified as DBGPRIV_BUFFERED, the debug shall be written to - the debug circular buffer instead of being output immediately. - (This could be used to obtain debug without incurring a - performance hit by printing it at that moment). - This function shall dump the contents of that debug circular - buffer to be output in an OS-specific method to a log or - console which can be read by developers. -@Return None -*/ /**************************************************************************/ -IMG_EXPORT void IMG_CALLCONV PVRSRVDebugPrintfDumpCCB(void); - -#if !defined(DOXYGEN) -#define PVR_DPF_FUNC__(lvl, message, ...) PVR_DPF((lvl, "%s: " message, __func__, ##__VA_ARGS__)) -#define PVR_DPF_FUNC(x) PVR_DPF_FUNC__ x -#endif /*!defined(DOXYGEN) */ - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_RETURN_IF_ERROR macro. - */ -#define PVR_RETURN_IF_ERROR(_rc) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - return _rc; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_RETURN_IF_FALSE macro. - */ -#define PVR_RETURN_IF_FALSE(_expr, _rc) do \ - { if (unlikely(!(_expr))) { \ - return _rc; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_RETURN_IF_INVALID_PARAM macro. - */ -#define PVR_RETURN_IF_INVALID_PARAM(_expr) do \ - { if (unlikely(!(_expr))) { \ - return PVRSRV_ERROR_INVALID_PARAMS; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_RETURN_IF_NOMEM macro. - */ -#define PVR_RETURN_IF_NOMEM(_expr) do \ - { if (unlikely(!(_expr))) { \ - return PVRSRV_ERROR_OUT_OF_MEMORY; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_GOTO_IF_NOMEM macro. - */ -#define PVR_GOTO_IF_NOMEM(_expr, _err, _go) do \ - { if (unlikely(_expr == NULL)) { \ - _err = PVRSRV_ERROR_OUT_OF_MEMORY; \ - goto _go; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_GOTO_IF_INVALID_PARAM macro. - */ -#define PVR_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do \ - { if (unlikely(!(_expr))) { \ - _err = PVRSRV_ERROR_INVALID_PARAMS; \ - goto _go; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_GOTO_IF_FALSE macro. - */ -#define PVR_GOTO_IF_FALSE(_expr, _go) do \ - { if (unlikely(!(_expr))) { \ - goto _go; } \ - MSC_SUPPRESS_4127 \ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_GOTO_IF_ERROR macro. - */ -#define PVR_GOTO_IF_ERROR(_rc, _go) do \ - { if (unlikely(_rc != PVRSRV_OK)) { \ - goto _go; } \ - MSC_SUPPRESS_4127\ - } while (false) - -/* Note: Use only when a log message due to the error absolutely should not - * be printed. Otherwise use PVR_LOG_GOTO_WITH_ERROR macro. - */ -#define PVR_GOTO_WITH_ERROR(_err, _rc, _go) do \ - { _err = _rc; goto _go; \ - MSC_SUPPRESS_4127 \ - } while (false) - -/*! @cond Doxygen_Suppress */ -#if defined(PVR_DPF_FUNCTION_TRACE_ON) - - #define PVR_DPF_ENTERED \ - PVR_DPF((PVR_DBG_CALLTRACE, "|-> %s:%d entered", __func__, __LINE__)) - - #define PVR_DPF_ENTERED1(p1) \ - PVR_DPF((PVR_DBG_CALLTRACE, "|-> %s:%d entered (0x%lx)", __func__, __LINE__, ((unsigned long)p1))) - - #define PVR_DPF_RETURN_RC(a) \ - do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned %d", __func__, __LINE__, (_r))); return (_r); MSC_SUPPRESS_4127 } while (false) - - #define PVR_DPF_RETURN_RC1(a,p1) \ - do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned %d (0x%lx)", __func__, __LINE__, (_r), ((unsigned long)p1))); return (_r); MSC_SUPPRESS_4127 } while (false) - - #define PVR_DPF_RETURN_VAL(a) \ - do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned with value", __func__, __LINE__)); return (a); MSC_SUPPRESS_4127 } while (false) - - #define PVR_DPF_RETURN_OK \ - do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned ok", __func__, __LINE__)); return PVRSRV_OK; MSC_SUPPRESS_4127 } while (false) - - #define PVR_DPF_RETURN \ - do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned", __func__, __LINE__)); return; MSC_SUPPRESS_4127 } while (false) - - #if !defined(DEBUG) - #error PVR DPF Function trace enabled in release build, rectify - #endif - -#else /* defined(PVR_DPF_FUNCTION_TRACE_ON) */ - - #define PVR_DPF_ENTERED - #define PVR_DPF_ENTERED1(p1) - #define PVR_DPF_RETURN_RC(a) return (a) - #define PVR_DPF_RETURN_RC1(a,p1) return (a) - #define PVR_DPF_RETURN_VAL(a) return (a) - #define PVR_DPF_RETURN_OK return PVRSRV_OK - #define PVR_DPF_RETURN return - -#endif /* defined(PVR_DPF_FUNCTION_TRACE_ON) */ -/*! @endcond */ - -#if defined(__KERNEL__) || defined(DOXYGEN) || defined(__QNXNTO__) -/*Use PVR_DPF() unless message is necessary in release build */ -#define PVR_LOG(X) PVRSRVReleasePrintf X - -/*************************************************************************/ /*! -@Function PVRSRVReleasePrintf -@Description Output an important message, using an OS-specific method, - to the Server log or console which will always be output in - both release and debug builds. - Invoked from the macro PVR_LOG(). Used in Services Server only. -@Input pszFormat The message format string -@Input ... Zero or more arguments for use by the format string -@Return None -*/ /**************************************************************************/ -void IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) __printf(1, 2); -#endif - -/* PVR_TRACE() handling */ - -#if defined(PVRSRV_NEED_PVR_TRACE) || defined(DOXYGEN) - - #define PVR_TRACE(X) PVRSRVTrace X /*!< PowerVR Debug Trace Macro */ - /* Empty string implementation that is -O0 build friendly */ - #define PVR_TRACE_EMPTY_LINE() PVR_TRACE(("%s", "")) - -/*************************************************************************/ /*! -@Function PVRTrace -@Description Output a debug message to the user - Invoked from the macro PVR_TRACE(). -@Input pszFormat The message format string -@Input ... Zero or more arguments for use by the format string -*/ /**************************************************************************/ -IMG_EXPORT void IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... ) - __printf(1, 2); - -#else /* defined(PVRSRV_NEED_PVR_TRACE) */ - /*! Null Implementation of PowerVR Debug Trace Macro (does nothing) */ - #define PVR_TRACE(X) - -#endif /* defined(PVRSRV_NEED_PVR_TRACE) */ - - -#if defined(PVRSRV_NEED_PVR_ASSERT) -#ifdef INLINE_IS_PRAGMA -#pragma inline(TRUNCATE_64BITS_TO_32BITS) -#endif - INLINE static IMG_UINT32 TRUNCATE_64BITS_TO_32BITS(IMG_UINT64 uiInput) - { - IMG_UINT32 uiTruncated; - - uiTruncated = (IMG_UINT32)uiInput; - PVR_ASSERT(uiInput == uiTruncated); - return uiTruncated; - } - - -#ifdef INLINE_IS_PRAGMA -#pragma inline(TRUNCATE_64BITS_TO_SIZE_T) -#endif - INLINE static size_t TRUNCATE_64BITS_TO_SIZE_T(IMG_UINT64 uiInput) - { - size_t uiTruncated; - - uiTruncated = (size_t)uiInput; - PVR_ASSERT(uiInput == uiTruncated); - return uiTruncated; - } - - -#ifdef INLINE_IS_PRAGMA -#pragma inline(TRUNCATE_SIZE_T_TO_32BITS) -#endif - INLINE static IMG_UINT32 TRUNCATE_SIZE_T_TO_32BITS(size_t uiInput) - { - IMG_UINT32 uiTruncated; - - uiTruncated = (IMG_UINT32)uiInput; - PVR_ASSERT(uiInput == uiTruncated); - return uiTruncated; - } - - -#else /* defined(PVRSRV_NEED_PVR_ASSERT) */ - #define TRUNCATE_64BITS_TO_32BITS(expr) ((IMG_UINT32)(expr)) - #define TRUNCATE_64BITS_TO_SIZE_T(expr) ((size_t)(expr)) - #define TRUNCATE_SIZE_T_TO_32BITS(expr) ((IMG_UINT32)(expr)) -#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */ - -/*! @cond Doxygen_Suppress */ -/* Macros used to trace calls */ -#if defined(DEBUG) - #define PVR_DBG_FILELINE , (__FILE__), (__LINE__) - #define PVR_DBG_FILELINE_PARAM , const IMG_CHAR *pszaFile, IMG_UINT32 ui32Line - #define PVR_DBG_FILELINE_ARG , pszaFile, ui32Line - #define PVR_DBG_FILELINE_FMT " %s:%u" - #define PVR_DBG_FILELINE_UNREF() do { PVR_UNREFERENCED_PARAMETER(pszaFile); \ - PVR_UNREFERENCED_PARAMETER(ui32Line); } while (false) -#else - #define PVR_DBG_FILELINE - #define PVR_DBG_FILELINE_PARAM - #define PVR_DBG_FILELINE_ARG - #define PVR_DBG_FILELINE_FMT - #define PVR_DBG_FILELINE_UNREF() -#endif -/*! @endcond */ - -#if defined(__cplusplus) -} -#endif - -/*! - @def PVR_ASSERT - @brief Aborts the program if assertion fails. - - The macro will be defined only when PVRSRV_NEED_PVR_ASSERT macro is - enabled. It's ignored otherwise. - - @def PVR_DPF - @brief PowerVR Debug Printf logging macro used throughout the driver. - - The macro allows to print logging messages to appropriate log. The - destination log is based on the component (user space / kernel space) and - operating system (Linux, Android, etc.). - - The macro also supports severity levels that allow to turn on/off messages - based on their importance. - - This macro will print messages with severity level higher that error only - if PVRSRV_NEED_PVR_DPF macro is defined. - - @def PVR_LOG_ERROR - @brief Logs error. - - @def PVR_LOG_IF_ERROR - @brief Logs error if not PVRSRV_OK. - - @def PVR_WARN_IF_ERROR - @brief Logs warning if not PVRSRV_OK. - - @def PVR_LOG_RETURN_IF_NOMEM - @brief Logs error if expression is NULL and returns PVRSRV_ERROR_OUT_OF_MEMORY. - - @def PVR_LOG_GOTO_IF_NOMEM - @brief Logs error if expression is NULL and jumps to given label. - - @def PVR_LOG_RETURN_IF_ERROR - @brief Logs error if not PVRSRV_OK and returns the error. - - @def PVR_LOG_RETURN_VOID_IF_ERROR - @brief Logs error if not PVRSRV_OK and returns (used in function that return void). - - @def PVR_LOG_GOTO_IF_ERROR - @brief Logs error if not PVRSRV_OK and jumps to label. - - @def PVR_LOG_GOTO_WITH_ERROR - @brief Logs error, goes to a label and sets the error code. - - @def PVR_LOG_IF_FALSE - @brief Prints error message if expression is false. - - @def PVR_LOG_RETURN_IF_FALSE - @brief Prints error message if expression is false and returns given error. - - @def PVR_LOG_RETURN_VOID_IF_FALSE - @brief Prints error message if expression is false and returns (used in function that return void). - - @def PVR_LOG_GOTO_IF_FALSE - @brief Prints error message if expression is false and jumps to label. - - @def PVR_LOG_RETURN_IF_INVALID_PARAM - @brief Prints error message if expression is false and returns PVRSRV_ERROR_INVALID_PARAMS. - - @def PVR_LOG_GOTO_IF_INVALID_PARAM - @brief Prints error message if expression is false and jumps to label. - - @def PVR_RETURN_IF_ERROR - @brief Returns passed error code if it's different than PVRSRV_OK; - - @def PVR_RETURN_IF_FALSE - @brief Returns passed error code if expression is false. - - @def PVR_RETURN_IF_INVALID_PARAM - @brief Returns PVRSRV_ERROR_INVALID_PARAMS if expression is false. - - @def PVR_RETURN_IF_NOMEM - @brief Returns PVRSRV_ERROR_OUT_OF_MEMORY if expression is NULL. - - @def PVR_GOTO_IF_NOMEM - @brief Goes to a label if expression is NULL. - - @def PVR_GOTO_IF_INVALID_PARAM - @brief Goes to a label if expression is false. - - @def PVR_GOTO_IF_FALSE - @brief Goes to a label if expression is false. - - @def PVR_GOTO_IF_ERROR - @brief Goes to a label if the error code is different than PVRSRV_OK; - - @def PVR_GOTO_WITH_ERROR - @brief Goes to a label and sets the error code. - - @def PVR_LOG - @brief Prints message to a log unconditionally. - - This macro will print messages only if PVRSRV_NEED_PVR_LOG macro is defined. - @def PVR_LOG_MSG - @brief Prints message to a log with the given log-level. - - @def PVR_LOG_VA - @brief Prints message with var-args to a log with the given log-level. - - @def PVR_LOG_IF_ERROR_VA - @brief Prints message with var-args to a log if the error code is different than PVRSRV_OK. - - @def PVR_LOG_IF_FALSE_VA - @brief Prints message with var-args if expression is false. - - @def PVR_LOG_RETURN_IF_ERROR_VA - @brief Prints message with var-args to a log and returns the error code. - - @def PVR_LOG_GOTO_IF_ERROR_VA - @brief Prints message with var-args to a log and goes to a label if the error code is different than PVRSRV_OK. - - @def PVR_LOG_RETURN_IF_FALSE_VA - @brief Logs the error message with var-args if the expression is false and returns the error code. - - @def PVR_LOG_GOTO_IF_FALSE_VA - @brief Logs the error message with var-args and goes to a label if the expression is false. - - @def PVR_TRACE_EMPTY_LINE - @brief Prints empty line to a log (PVRSRV_NEED_PVR_LOG must be defined). - - @def TRUNCATE_64BITS_TO_32BITS - @brief Truncates 64 bit value to 32 bit value (with possible precision loss). - - @def TRUNCATE_64BITS_TO_SIZE_T - @brief Truncates 64 bit value to size_t value (with possible precision loss). - - @def TRUNCATE_SIZE_T_TO_32BITS - @brief Truncates size_t value to 32 bit value (with possible precision loss). - */ - -#endif /* PVR_DEBUG_H */ - -/****************************************************************************** - End of file (pvr_debug.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.c b/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.c deleted file mode 100644 index 140d5e7c29810..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.c +++ /dev/null @@ -1,624 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title DebugFS implementation of Debug Info interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements osdi_impl.h API to provide access to driver's - debug data via DebugFS. - - Note about locking in DebugFS module. - - Access to DebugFS is protected against the race where any - file could be removed while being accessed or accessed while - being removed. Any calls to debugfs_remove() will block - until all operations are finished. - - See implementation of proxy file operations (FULL_PROXY_FUNC) - and implementation of debugfs_file_[get|put]() in - fs/debugfs/file.c in Linux kernel sources for more details. - - Not about locking for sequential files. - - The seq_file objects have a mutex that protects access - to all of the file operations hence all of the sequential - *read* operations are protected. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvr_debugfs.h" -#include "osfunc.h" -#include "allocmem.h" -#include "pvr_bridge_k.h" -#include "pvr_uaccess.h" -#include "osdi_impl.h" - -#define _DRIVER_THREAD_ENTER() \ - do { \ - PVRSRV_ERROR eLocalError = PVRSRVDriverThreadEnter(); \ - if (eLocalError != PVRSRV_OK) \ - { \ - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRVDriverThreadEnter failed: %s", \ - __func__, PVRSRVGetErrorString(eLocalError))); \ - return OSPVRSRVToNativeError(eLocalError); \ - } \ - } while (0) - -#define _DRIVER_THREAD_EXIT() \ - PVRSRVDriverThreadExit() - -#define PVR_DEBUGFS_PVR_DPF_LEVEL PVR_DBG_ERROR - -typedef struct DFS_DIR -{ - struct dentry *psDirEntry; - struct DFS_DIR *psParentDir; -} DFS_DIR; - -typedef struct DFS_ENTRY -{ - OSDI_IMPL_ENTRY sImplEntry; - DI_ITERATOR_CB sIterCb; -} DFS_ENTRY; - -typedef struct DFS_FILE -{ - struct dentry *psFileEntry; - struct DFS_DIR *psParentDir; - const struct seq_operations *psSeqOps; - struct DFS_ENTRY sEntry; - DI_ENTRY_TYPE eType; -} DFS_FILE; - -/* ----- native callbacks interface ----------------------------------------- */ - -static void _WriteData(void *pvNativeHandle, const void *pvData, - IMG_UINT32 uiSize) -{ - seq_write(pvNativeHandle, pvData, uiSize); -} - -__printf(2, 0) -static void _VPrintf(void *pvNativeHandle, const IMG_CHAR *pszFmt, - va_list pArgs) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) - seq_vprintf(pvNativeHandle, pszFmt, pArgs); -#else - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; - - vsnprintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, pszFmt, pArgs); - seq_printf(pvNativeHandle, "%s", szBuffer); -#endif -} - -static void _Puts(void *pvNativeHandle, const IMG_CHAR *pszStr) -{ - seq_puts(pvNativeHandle, pszStr); -} - -static IMG_BOOL _HasOverflowed(void *pvNativeHandle) -{ - struct seq_file *psSeqFile = pvNativeHandle; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) - return seq_has_overflowed(psSeqFile); -#else - return psSeqFile->count == psSeqFile->size; -#endif -} - -static OSDI_IMPL_ENTRY_CB _g_sEntryCallbacks = { - .pfnWrite = _WriteData, - .pfnVPrintf = _VPrintf, - .pfnPuts = _Puts, - .pfnHasOverflowed = _HasOverflowed, -}; - -/* ----- sequential file operations ----------------------------------------- */ - -static void *_Start(struct seq_file *psSeqFile, loff_t *puiPos) -{ - DFS_ENTRY *psEntry = psSeqFile->private; - - void *pvRet = psEntry->sIterCb.pfnStart(&psEntry->sImplEntry, puiPos); - - if (pvRet == DI_START_TOKEN) - { - return SEQ_START_TOKEN; - } - - return pvRet; -} - -static void _Stop(struct seq_file *psSeqFile, void *pvPriv) -{ - DFS_ENTRY *psEntry = psSeqFile->private; - - psEntry->sIterCb.pfnStop(&psEntry->sImplEntry, pvPriv); -} - -static void *_Next(struct seq_file *psSeqFile, void *pvPriv, loff_t *puiPos) -{ - DFS_ENTRY *psEntry = psSeqFile->private; - - return psEntry->sIterCb.pfnNext(&psEntry->sImplEntry, pvPriv, puiPos); -} - -static int _Show(struct seq_file *psSeqFile, void *pvPriv) -{ - DFS_ENTRY *psEntry = psSeqFile->private; - - if (pvPriv == SEQ_START_TOKEN) - { - pvPriv = DI_START_TOKEN; - } - - return psEntry->sIterCb.pfnShow(&psEntry->sImplEntry, pvPriv); -} - -static struct seq_operations _g_sSeqOps = { - .start = _Start, - .stop = _Stop, - .next = _Next, - .show = _Show -}; - -/* ----- file operations ---------------------------------------------------- */ - -static int _Open(struct inode *psINode, struct file *psFile) -{ - DFS_FILE *psDFSFile; - int iRes; - - PVR_LOG_RETURN_IF_FALSE(psINode != NULL && psINode->i_private != NULL, - "psDFSFile is NULL", -EIO); - - _DRIVER_THREAD_ENTER(); - - psDFSFile = psINode->i_private; - - if (psDFSFile->sEntry.sIterCb.pfnStart != NULL) - { - iRes = seq_open(psFile, psDFSFile->psSeqOps); - } - else - { - /* private data is NULL as it's going to be set below */ - iRes = single_open(psFile, _Show, NULL); - } - - if (iRes == 0) - { - struct seq_file *psSeqFile = psFile->private_data; - - DFS_ENTRY *psEntry = OSAllocMem(sizeof(*psEntry)); - if (psEntry == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem() failed", __func__)); - iRes = -ENOMEM; - goto return_; - } - - *psEntry = psDFSFile->sEntry; - psSeqFile->private = psEntry; - psEntry->sImplEntry.pvNative = psSeqFile; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to seq_open psFile, returning %d", - __func__, iRes)); - } - -return_: - _DRIVER_THREAD_EXIT(); - - return iRes; -} - -static int _Close(struct inode *psINode, struct file *psFile) -{ - DFS_FILE *psDFSFile = psINode->i_private; - DFS_ENTRY *psEntry; - int iRes; - - PVR_LOG_RETURN_IF_FALSE(psDFSFile != NULL, "psDFSFile is NULL", - -EIO); - - _DRIVER_THREAD_ENTER(); - - /* save pointer to DFS_ENTRY */ - psEntry = ((struct seq_file *) psFile->private_data)->private; - - if (psDFSFile->sEntry.sIterCb.pfnStart != NULL) - { - iRes = seq_release(psINode, psFile); - } - else - { - iRes = single_release(psINode, psFile); - } - - /* free DFS_ENTRY allocated in _Open */ - OSFreeMem(psEntry); - - /* Validation check as seq_release (and single_release which calls it) - * never fail */ - if (iRes != 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to release psFile, returning %d", - __func__, iRes)); - } - - _DRIVER_THREAD_EXIT(); - - return iRes; -} - -static ssize_t _Read(struct file *psFile, char __user *pcBuffer, - size_t uiCount, loff_t *puiPos) -{ - DFS_FILE *psDFSFile = psFile->f_path.dentry->d_inode->i_private; - ssize_t iRes = -1; - - _DRIVER_THREAD_ENTER(); - - if (psDFSFile->eType == DI_ENTRY_TYPE_GENERIC) - { - iRes = seq_read(psFile, pcBuffer, uiCount, puiPos); - if (iRes < 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to read from file, pfnRead() " - "returned %zd", __func__, iRes)); - goto return_; - } - } - else if (psDFSFile->eType == DI_ENTRY_TYPE_RANDOM_ACCESS) - { - DFS_ENTRY *psEntry = &psDFSFile->sEntry; - IMG_UINT64 ui64Count = uiCount; - - IMG_CHAR *pcLocalBuffer = OSAllocMem(uiCount); - PVR_GOTO_IF_FALSE(pcLocalBuffer != NULL, return_); - - iRes = psEntry->sIterCb.pfnRead(pcLocalBuffer, ui64Count, puiPos, - psEntry->sImplEntry.pvPrivData); - if (iRes < 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to read from file, pfnRead() " - "returned %zd", __func__, iRes)); - OSFreeMem(pcLocalBuffer); - goto return_; - } - - if (pvr_copy_to_user(pcBuffer, pcLocalBuffer, iRes) != 0) - { - iRes = -1; - } - - OSFreeMem(pcLocalBuffer); - } - -return_: - _DRIVER_THREAD_EXIT(); - - return iRes; -} - -static loff_t _LSeek(struct file *psFile, loff_t iOffset, int iOrigin) -{ - DFS_FILE *psDFSFile = psFile->f_path.dentry->d_inode->i_private; - loff_t iRes = -1; - - _DRIVER_THREAD_ENTER(); - - if (psDFSFile->eType == DI_ENTRY_TYPE_GENERIC) - { - iRes = seq_lseek(psFile, iOffset, iOrigin); - if (iRes < 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to set file position in psFile<%p> to offset " - "%lld, iOrigin %d, seq_lseek() returned %lld (dentry='%s')", __func__, - psFile, iOffset, iOrigin, iRes, psFile->f_path.dentry->d_name.name)); - goto return_; - } - } - else if (psDFSFile->eType == DI_ENTRY_TYPE_RANDOM_ACCESS) - { - DFS_ENTRY *psEntry = &psDFSFile->sEntry; - IMG_UINT64 ui64Pos; - - switch (iOrigin) - { - case SEEK_SET: - ui64Pos = psFile->f_pos + iOffset; - break; - case SEEK_CUR: - ui64Pos = iOffset; - break; - case SEEK_END: - /* not supported as we don't know the file size here */ - /* fall through */ - default: - return -1; - } - - /* only pass the absolute position to the callback, it's up to the - * implementer to determine if the position is valid */ - - iRes = psEntry->sIterCb.pfnSeek(ui64Pos, - psEntry->sImplEntry.pvPrivData); - if (iRes < 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to set file position to offset " - "%lld, pfnSeek() returned %lld", __func__, - iOffset, iRes)); - goto return_; - } - - psFile->f_pos = ui64Pos; - } - -return_: - _DRIVER_THREAD_EXIT(); - - return iRes; -} - -static ssize_t _Write(struct file *psFile, const char __user *pszBuffer, - size_t uiCount, loff_t *puiPos) -{ - struct inode *psINode = psFile->f_path.dentry->d_inode; - DFS_FILE *psDFSFile = psINode->i_private; - DI_ITERATOR_CB *psIter = &psDFSFile->sEntry.sIterCb; - IMG_CHAR *pcLocalBuffer; - IMG_UINT64 ui64Count; - IMG_INT64 i64Res = -EIO; - IMG_UINT64 ui64Pos = *puiPos; - - PVR_LOG_RETURN_IF_FALSE(psDFSFile != NULL, "psDFSFile is NULL", - -EIO); - PVR_LOG_RETURN_IF_FALSE(psIter->pfnWrite != NULL, "pfnWrite is NULL", - -EIO); - - - /* Make sure we allocate the smallest amount of needed memory*/ - ui64Count = psIter->ui32WriteLenMax; - PVR_LOG_GOTO_IF_FALSE(uiCount <= ui64Count, "uiCount too long", return_); - ui64Count = MIN(uiCount + 1, ui64Count); - - _DRIVER_THREAD_ENTER(); - - /* allocate buffer with one additional byte for NUL character */ - pcLocalBuffer = OSAllocMem(ui64Count); - PVR_LOG_GOTO_IF_FALSE(pcLocalBuffer != NULL, "OSAllocMem() failed", - return_); - - i64Res = pvr_copy_from_user(pcLocalBuffer, pszBuffer, ui64Count); - PVR_LOG_GOTO_IF_FALSE(i64Res == 0, "pvr_copy_from_user() failed", - free_local_buffer_); - - /* ensure that the framework user gets a NUL terminated buffer */ - pcLocalBuffer[ui64Count - 1] = '\0'; - - i64Res = psIter->pfnWrite(pcLocalBuffer, ui64Count, &ui64Pos, - psDFSFile->sEntry.sImplEntry.pvPrivData); - PVR_LOG_GOTO_IF_FALSE(i64Res >= 0, "pfnWrite failed", free_local_buffer_); - - *puiPos = ui64Pos; - -free_local_buffer_: - OSFreeMem(pcLocalBuffer); - -return_: - _DRIVER_THREAD_EXIT(); - - return i64Res; -} - -static const struct file_operations _g_psFileOpsGen = { - .owner = THIS_MODULE, - .open = _Open, - .release = _Close, - .read = _Read, - .llseek = _LSeek, - .write = _Write, -}; - -static const struct file_operations _g_psFileOpsRndAcc = { - .owner = THIS_MODULE, - .read = _Read, - .llseek = _LSeek, - .write = _Write, -}; - -/* ----- DI implementation interface ---------------------------------------- */ - -static PVRSRV_ERROR _Init(void) -{ - return PVRSRV_OK; -} - -static void _DeInit(void) -{ -} - -static PVRSRV_ERROR _CreateFile(const IMG_CHAR *pszName, - DI_ENTRY_TYPE eType, - const DI_ITERATOR_CB *psIterCb, - void *pvPrivData, - void *pvParentDir, - void **pvFile) -{ - DFS_DIR *psParentDir = pvParentDir; - DFS_FILE *psFile; - umode_t uiMode = S_IFREG; - struct dentry *psEntry; - const struct file_operations *psFileOps = NULL; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pvFile != NULL, "pvFile"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pvParentDir != NULL, "pvParentDir"); - - switch (eType) - { - case DI_ENTRY_TYPE_GENERIC: - psFileOps = &_g_psFileOpsGen; - break; - case DI_ENTRY_TYPE_RANDOM_ACCESS: - psFileOps = &_g_psFileOpsRndAcc; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "eType invalid in %s()", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto return_; - } - - psFile = OSAllocMem(sizeof(*psFile)); - PVR_LOG_GOTO_IF_NOMEM(psFile, eError, return_); - - uiMode |= psIterCb->pfnShow != NULL || psIterCb->pfnRead != NULL ? - S_IRUGO : 0; - uiMode |= psIterCb->pfnWrite != NULL ? S_IWUSR : 0; - - psEntry = debugfs_create_file(pszName, uiMode, psParentDir->psDirEntry, - psFile, psFileOps); - if (IS_ERR_OR_NULL(psEntry)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Cannot create debugfs '%s' file", - __func__, pszName)); - - eError = psEntry == NULL ? - PVRSRV_ERROR_OUT_OF_MEMORY : PVRSRV_ERROR_INVALID_DEVICE; - goto free_file_; - } - - psFile->eType = eType; - psFile->psSeqOps = &_g_sSeqOps; - psFile->sEntry.sIterCb = *psIterCb; - psFile->sEntry.sImplEntry.pvPrivData = pvPrivData; - psFile->sEntry.sImplEntry.pvNative = NULL; - psFile->sEntry.sImplEntry.psCb = &_g_sEntryCallbacks; - psFile->psParentDir = psParentDir; - psFile->psFileEntry = psEntry; - - *pvFile = psFile; - - return PVRSRV_OK; - -free_file_: - OSFreeMem(psFile); - -return_: - return eError; -} - -static void _DestroyFile(void *pvFile) -{ - DFS_FILE *psFile = pvFile; - - PVR_ASSERT(psFile != NULL); - - psFile->psFileEntry->d_inode->i_private = NULL; - - debugfs_remove(psFile->psFileEntry); - OSFreeMem(psFile); -} - -static PVRSRV_ERROR _CreateDir(const IMG_CHAR *pszName, - void *pvParentDir, - void **ppvDir) -{ - DFS_DIR *psNewDir; - struct dentry *psDirEntry, *psParentDir = NULL; - - PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName"); - PVR_LOG_RETURN_IF_INVALID_PARAM(ppvDir != NULL, "ppvDir"); - - psNewDir = OSAllocMem(sizeof(*psNewDir)); - PVR_LOG_RETURN_IF_NOMEM(psNewDir, "OSAllocMem"); - - psNewDir->psParentDir = pvParentDir; - - if (pvParentDir != NULL) - { - psParentDir = psNewDir->psParentDir->psDirEntry; - } - - psDirEntry = debugfs_create_dir(pszName, psParentDir); - if (IS_ERR_OR_NULL(psDirEntry)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Cannot create '%s' debugfs directory", - __func__, pszName)); - OSFreeMem(psNewDir); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psNewDir->psDirEntry = psDirEntry; - *ppvDir = psNewDir; - - return PVRSRV_OK; -} - -static void _DestroyDir(void *pvDir) -{ - DFS_DIR *psDir = pvDir; - - PVR_ASSERT(psDir != NULL); - - debugfs_remove(psDir->psDirEntry); - OSFreeMem(psDir); -} - -PVRSRV_ERROR PVRDebugFsRegister(void) -{ - OSDI_IMPL_CB sImplCb = { - .pfnInit = _Init, - .pfnDeInit = _DeInit, - .pfnCreateEntry = _CreateFile, - .pfnDestroyEntry = _DestroyFile, - .pfnCreateGroup = _CreateDir, - .pfnDestroyGroup = _DestroyDir - }; - - return DIRegisterImplementation("debugfs", &sImplCb); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.h b/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.h deleted file mode 100644 index 23ae55b120695..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_debugfs.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title DebugFS implementation of Debug Info interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_DEBUGFS_H -#define PVR_DEBUGFS_H - -#include "pvrsrv_error.h" - -PVRSRV_ERROR PVRDebugFsRegister(void); - -#endif /* PVR_DEBUGFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_dicommon.h b/drivers/gpu/drm/img-rogue/1.17/pvr_dicommon.h deleted file mode 100644 index c729dde2fab6e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_dicommon.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Debug Information (DI) common types and definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Debug Information (DI) common types and definitions included - in both user mode and kernel mode source. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_DICOMMON_H -#define PVR_DICOMMON_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! Maximum DI entry path length including the null byte. */ -#define DI_IMPL_BRG_PATH_LEN 64 - -#if defined(__cplusplus) -} -#endif - -#endif /* PVR_DICOMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_dma_resv.h b/drivers/gpu/drm/img-rogue/1.17/pvr_dma_resv.h deleted file mode 100644 index a51c9de84adad..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_dma_resv.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************/ /*! -@Title Kernel reservation object compatibility header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Per-version macros to allow code to seamlessly use older kernel -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 __PVR_DMA_RESV_H__ -#define __PVR_DMA_RESV_H__ - -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -#include -#else -#include - -/* Reservation object types */ -#define dma_resv reservation_object -#define dma_resv_list reservation_object_list - -/* Reservation object functions */ -#define dma_resv_add_excl_fence reservation_object_add_excl_fence -#define dma_resv_add_shared_fence reservation_object_add_shared_fence -#define dma_resv_fini reservation_object_fini -#define dma_resv_get_excl reservation_object_get_excl -#define dma_resv_get_list reservation_object_get_list -#define dma_resv_held reservation_object_held -#define dma_resv_init reservation_object_init -#define dma_resv_reserve_shared reservation_object_reserve_shared -#define dma_resv_test_signaled_rcu reservation_object_test_signaled_rcu -#define dma_resv_wait_timeout_rcu reservation_object_wait_timeout_rcu -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) - -#define dma_resv_shared_list dma_resv_get_list -#define dma_resv_excl_fence dma_resv_get_excl -#define dma_resv_wait_timeout dma_resv_wait_timeout_rcu -#define dma_resv_test_signaled dma_resv_test_signaled_rcu -#define dma_resv_get_fences dma_resv_get_fences_rcu - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) */ - -#endif /* __PVR_DMA_RESV_H__ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_drm.c b/drivers/gpu/drm/img-rogue/1.17/pvr_drm.c deleted file mode 100644 index 65a8e511e730c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_drm.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * @File - * @Title PowerVR DRM driver - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#include -#include -#include -#include -#else -#include /* include before drm_crtc.h for kernels older than 3.9 */ -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "module_common.h" -#include "pvr_drm.h" -#include "pvr_drv.h" -#include "pvrversion.h" -#include "services_kernel_client.h" -#include "pvr_sync_ioctl_drm.h" - -#include "kernel_compatibility.h" - -#define PVR_DRM_DRIVER_NAME PVR_DRM_NAME -#define PVR_DRM_DRIVER_DESC "Imagination Technologies PVR DRM" -#define PVR_DRM_DRIVER_DATE "20170530" - -/* - * Protects global PVRSRV_DATA on a multi device system. i.e. this is used to - * protect the PVRSRVCommonDeviceXXXX() APIs in the Server common layer which - * are not re-entrant for device creation and initialisation. - */ -static DEFINE_MUTEX(g_device_mutex); - -static int pvr_pm_suspend(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - - DRM_DEBUG_DRIVER("device %p\n", dev); - - return PVRSRVDeviceSuspend(priv->dev_node); -} - -static int pvr_pm_resume(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - - DRM_DEBUG_DRIVER("device %p\n", dev); - - return PVRSRVDeviceResume(priv->dev_node); -} - -const struct dev_pm_ops pvr_pm_ops = { - .suspend = pvr_pm_suspend, - .resume = pvr_pm_resume, -}; - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) -static -#endif -int pvr_drm_load(struct drm_device *ddev, unsigned long flags) -{ - struct pvr_drm_private *priv; - enum PVRSRV_ERROR_TAG srv_err; - int err, deviceId; - - DRM_DEBUG_DRIVER("device %p\n", ddev->dev); - - dev_set_drvdata(ddev->dev, ddev); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) - /* - * Older kernels do not have render drm_minor member in drm_device, - * so we fallback to primary node for device identification - */ - deviceId = ddev->primary->index; -#else - if (ddev->render) - deviceId = ddev->render->index; - else /* when render node is NULL, fallback to primary node */ - deviceId = ddev->primary->index; -#endif - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - err = -ENOMEM; - goto err_exit; - } - ddev->dev_private = priv; - - if (!ddev->dev->dma_parms) - ddev->dev->dma_parms = &priv->dma_parms; - dma_set_max_seg_size(ddev->dev, DMA_BIT_MASK(32)); - - mutex_lock(&g_device_mutex); - - srv_err = PVRSRVCommonDeviceCreate(ddev->dev, deviceId, &priv->dev_node); - if (srv_err != PVRSRV_OK) { - DRM_ERROR("failed to create device node for device %p (%s)\n", - ddev->dev, PVRSRVGetErrorString(srv_err)); - if (srv_err == PVRSRV_ERROR_PROBE_DEFER) - err = -EPROBE_DEFER; - else - err = -ENODEV; - goto err_unset_dma_parms; - } - - err = PVRSRVDeviceInit(priv->dev_node); - if (err) { - DRM_ERROR("device %p initialisation failed (err=%d)\n", - ddev->dev, err); - goto err_device_destroy; - } - - drm_mode_config_init(ddev); - -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_PROBE) - srv_err = PVRSRVCommonDeviceInitialise(priv->dev_node); - if (srv_err != PVRSRV_OK) { - err = -ENODEV; - DRM_ERROR("device %p initialisation failed (err=%d)\n", - ddev->dev, err); - goto err_device_deinit; - } -#endif - - mutex_unlock(&g_device_mutex); - - return 0; - -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_PROBE) -err_device_deinit: - drm_mode_config_cleanup(ddev); - PVRSRVDeviceDeinit(priv->dev_node); -#endif -err_device_destroy: - PVRSRVCommonDeviceDestroy(priv->dev_node); -err_unset_dma_parms: - mutex_unlock(&g_device_mutex); - if (ddev->dev->dma_parms == &priv->dma_parms) - ddev->dev->dma_parms = NULL; - kfree(priv); -err_exit: - return err; -} - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) -static -#endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) -int pvr_drm_unload(struct drm_device *ddev) -#else -void pvr_drm_unload(struct drm_device *ddev) -#endif -{ - struct pvr_drm_private *priv = ddev->dev_private; - - DRM_DEBUG_DRIVER("device %p\n", ddev->dev); - - drm_mode_config_cleanup(ddev); - - PVRSRVDeviceDeinit(priv->dev_node); - - mutex_lock(&g_device_mutex); - PVRSRVCommonDeviceDestroy(priv->dev_node); - mutex_unlock(&g_device_mutex); - - if (ddev->dev->dma_parms == &priv->dma_parms) - ddev->dev->dma_parms = NULL; - - kfree(priv); - ddev->dev_private = NULL; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - return 0; -#endif -} - -static int pvr_drm_open(struct drm_device *ddev, struct drm_file *dfile) -{ -#if (PVRSRV_DEVICE_INIT_MODE != PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - struct pvr_drm_private *priv = ddev->dev_private; - int err; -#endif - - if (!try_module_get(THIS_MODULE)) { - DRM_ERROR("failed to get module reference\n"); - return -ENOENT; - } - -#if (PVRSRV_DEVICE_INIT_MODE != PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - err = PVRSRVDeviceServicesOpen(priv->dev_node, dfile); - if (err) - module_put(THIS_MODULE); - - return err; -#else - return 0; -#endif -} - -static void pvr_drm_release(struct drm_device *ddev, struct drm_file *dfile) -{ - struct pvr_drm_private *priv = ddev->dev_private; - - PVRSRVDeviceRelease(priv->dev_node, dfile); - - module_put(THIS_MODULE); -} - -/* - * The DRM global lock is taken for ioctls unless the DRM_UNLOCKED flag is set. - */ -static struct drm_ioctl_desc pvr_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(PVR_SRVKM_CMD, PVRSRV_BridgeDispatchKM, - DRM_RENDER_ALLOW | DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(PVR_SRVKM_INIT, drm_pvr_srvkm_init, - DRM_RENDER_ALLOW | DRM_UNLOCKED), -#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE) - DRM_IOCTL_DEF_DRV(PVR_SYNC_RENAME_CMD, pvr_sync_rename_ioctl, - DRM_RENDER_ALLOW | DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(PVR_SYNC_FORCE_SW_ONLY_CMD, pvr_sync_force_sw_only_ioctl, - DRM_RENDER_ALLOW | DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(PVR_SW_SYNC_CREATE_FENCE_CMD, pvr_sw_sync_create_fence_ioctl, - DRM_RENDER_ALLOW | DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(PVR_SW_SYNC_INC_CMD, pvr_sw_sync_inc_ioctl, - DRM_RENDER_ALLOW | DRM_UNLOCKED), -#endif -}; - -#if defined(CONFIG_COMPAT) -static long pvr_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(file, cmd, arg); - - return drm_ioctl(file, cmd, arg); -} -#endif /* defined(CONFIG_COMPAT) */ - -const struct file_operations pvr_drm_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, -#if defined(CONFIG_COMPAT) - .compat_ioctl = pvr_compat_ioctl, -#endif - .mmap = PVRSRV_MMap, - .poll = drm_poll, - .read = drm_read, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) - .fasync = drm_fasync, -#endif -}; - -const struct drm_driver pvr_drm_generic_driver = { - .driver_features = DRIVER_MODESET | DRIVER_RENDER, - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) - .load = NULL, - .unload = NULL, -#else - .load = pvr_drm_load, - .unload = pvr_drm_unload, -#endif - .open = pvr_drm_open, - .postclose = pvr_drm_release, - - .ioctls = pvr_drm_ioctls, - .num_ioctls = ARRAY_SIZE(pvr_drm_ioctls), - .fops = &pvr_drm_fops, - - .name = PVR_DRM_DRIVER_NAME, - .desc = PVR_DRM_DRIVER_DESC, - .date = PVR_DRM_DRIVER_DATE, - .major = PVRVERSION_MAJ, - .minor = PVRVERSION_MIN, - .patchlevel = PVRVERSION_BUILD, -}; diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_drm.h b/drivers/gpu/drm/img-rogue/1.17/pvr_drm.h deleted file mode 100644 index c0d00c98d8c01..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_drm.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * @File - * @Title PVR DRM definitions shared between kernel and user space. - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ - -#if !defined(__PVR_DRM_H__) -#define __PVR_DRM_H__ - -#include - -#if defined(__KERNEL__) -#include -#else -#include -#endif - -/* - * IMPORTANT: - * All structures below are designed to be the same size when compiled for 32 - * and/or 64 bit architectures, i.e. there should be no compiler inserted - * padding. This is achieved by sticking to the following rules: - * 1) only use fixed width types - * 2) always naturally align fields by arranging them appropriately and by using - * padding fields when necessary - * - * These rules should _always_ be followed when modifying or adding new - * structures to this file. - */ - -struct drm_pvr_srvkm_cmd { - __u32 bridge_id; - __u32 bridge_func_id; - __u64 in_data_ptr; - __u64 out_data_ptr; - __u32 in_data_size; - __u32 out_data_size; -}; - -struct pvr_sync_rename_ioctl_data { - char szName[32]; -}; - -struct pvr_sw_sync_create_fence_data { - char name[32]; - __s32 fence; - __u32 pad; - __u64 sync_pt_idx; -}; - -struct pvr_sw_timeline_advance_data { - __u64 sync_pt_idx; -}; - -#define PVR_SRVKM_SERVICES_INIT 1 -#define PVR_SRVKM_SYNC_INIT 2 -struct drm_pvr_srvkm_init_data { - __u32 init_module; -}; - -/* Values used to configure the PVRSRV_DEVICE_INIT_MODE tunable (Linux-only) */ -#define PVRSRV_LINUX_DEV_INIT_ON_PROBE 1 -#define PVRSRV_LINUX_DEV_INIT_ON_OPEN 2 -#define PVRSRV_LINUX_DEV_INIT_ON_CONNECT 3 - -/* - * DRM command numbers, relative to DRM_COMMAND_BASE. - * These defines must be prefixed with "DRM_". - */ - -/* PVR Services command */ -#define DRM_PVR_SRVKM_CMD 0 - -/* PVR Sync commands */ -#define DRM_PVR_SYNC_RENAME_CMD 1 -#define DRM_PVR_SYNC_FORCE_SW_ONLY_CMD 2 - -/* PVR Software Sync commands */ -#define DRM_PVR_SW_SYNC_CREATE_FENCE_CMD 3 -#define DRM_PVR_SW_SYNC_INC_CMD 4 - -/* PVR Services Render Device Init command */ -#define DRM_PVR_SRVKM_INIT 5 - -/* These defines must be prefixed with "DRM_IOCTL_". */ -#define DRM_IOCTL_PVR_SRVKM_CMD \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_SRVKM_CMD, \ - struct drm_pvr_srvkm_cmd) - -#define DRM_IOCTL_PVR_SYNC_RENAME_CMD \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PVR_SYNC_RENAME_CMD, \ - struct pvr_sync_rename_ioctl_data) - -#define DRM_IOCTL_PVR_SYNC_FORCE_SW_ONLY_CMD \ - DRM_IO(DRM_COMMAND_BASE + DRM_PVR_SYNC_FORCE_SW_ONLY_CMD) - -#define DRM_IOCTL_PVR_SW_SYNC_CREATE_FENCE_CMD \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_SW_SYNC_CREATE_FENCE_CMD, \ - struct pvr_sw_sync_create_fence_data) - -#define DRM_IOCTL_PVR_SW_SYNC_INC_CMD \ - DRM_IOR(DRM_COMMAND_BASE + DRM_PVR_SW_SYNC_INC_CMD, \ - struct pvr_sw_timeline_advance_data) - -#define DRM_IOCTL_PVR_SRVKM_INIT \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PVR_SRVKM_INIT, \ - struct drm_pvr_srvkm_init_data) - -#endif /* defined(__PVR_DRM_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_drv.h b/drivers/gpu/drm/img-rogue/1.17/pvr_drv.h deleted file mode 100644 index 15887da30f0fd..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_drv.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * @File - * @Title PowerVR DRM driver - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ - -#if !defined(__PVR_DRV_H__) -#define __PVR_DRV_H__ - -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#include -#include -#include -#else -#include -#endif - -#include - -struct file; -struct _PVRSRV_DEVICE_NODE_; -struct workqueue_struct; -struct vm_area_struct; - -/* This structure is used to store Linux specific per-device information. */ -struct pvr_drm_private { - struct _PVRSRV_DEVICE_NODE_ *dev_node; - - /* - * This is needed for devices that don't already have their own dma - * parameters structure, e.g. platform devices, and, if necessary, will - * be assigned to the 'struct device' during device initialisation. It - * should therefore never be accessed directly via this structure as - * this may not be the version of dma parameters in use. - */ - struct device_dma_parameters dma_parms; - - /* PVR Sync debug notify handle */ - void *sync_debug_notify_handle; - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) - /* Only used in fence sync as sync_debug_notify_handle is used - * to print a header only. Content is registered separately. - * Used to print foreign sync debug - */ - void *sync_foreign_debug_notify_handle; -#endif -}; - -extern const struct dev_pm_ops pvr_pm_ops; -extern const struct drm_driver pvr_drm_generic_driver; -extern const struct file_operations pvr_drm_fops; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) -int pvr_drm_load(struct drm_device *ddev, unsigned long flags); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) -int pvr_drm_unload(struct drm_device *ddev); -#else -void pvr_drm_unload(struct drm_device *ddev); -#endif -#endif - -int PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg, - struct drm_file *file); -int PVRSRV_MMap(struct file *file, struct vm_area_struct *ps_vma); - -#endif /* !defined(__PVR_DRV_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs.h b/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs.h deleted file mode 100644 index b99b8f5217aa2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************/ /*! -@File pvr_dvfs.h -@Title System level interface for DVFS -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_DVFS_H -#define PVR_DVFS_H - -#include - -#if defined(SUPPORT_LINUX_DVFS) - #include - #include - - #if defined(CONFIG_DEVFREQ_THERMAL) - #include - #endif - - #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - #include - #else - #include - #endif -#endif - -#include "img_types.h" - -typedef void (*PFN_SYS_DEV_DVFS_SET_FREQUENCY)(IMG_UINT32 ui32Freq); -typedef void (*PFN_SYS_DEV_DVFS_SET_VOLTAGE)(IMG_UINT32 ui32Volt); - -typedef struct _IMG_OPP_ -{ - IMG_UINT32 ui32Volt; - /* - * Unit of frequency in Hz. - */ - IMG_UINT32 ui32Freq; -} IMG_OPP; - -typedef struct _IMG_DVFS_DEVICE_CFG_ -{ - const IMG_OPP *pasOPPTable; - IMG_UINT32 ui32OPPTableSize; -#if defined(SUPPORT_LINUX_DVFS) - IMG_UINT32 ui32PollMs; -#endif - IMG_BOOL bIdleReq; - PFN_SYS_DEV_DVFS_SET_FREQUENCY pfnSetFrequency; - PFN_SYS_DEV_DVFS_SET_VOLTAGE pfnSetVoltage; - -#if defined(CONFIG_DEVFREQ_THERMAL) && defined(SUPPORT_LINUX_DVFS) - struct devfreq_cooling_power *psPowerOps; -#endif -} IMG_DVFS_DEVICE_CFG; - -#if defined(SUPPORT_LINUX_DVFS) -typedef struct _IMG_DVFS_GOVERNOR_ -{ - IMG_BOOL bEnabled; -} IMG_DVFS_GOVERNOR; - -typedef struct _IMG_DVFS_GOVERNOR_CFG_ -{ - IMG_UINT32 ui32UpThreshold; - IMG_UINT32 ui32DownDifferential; -} IMG_DVFS_GOVERNOR_CFG; -#endif - -#if defined(__linux__) -#if defined(SUPPORT_LINUX_DVFS) -typedef struct _IMG_DVFS_DEVICE_ -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - struct opp *psOPP; -#else - struct dev_pm_opp *psOPP; -#endif - struct devfreq *psDevFreq; - IMG_BOOL bInitPending; - IMG_BOOL bReady; - IMG_BOOL bEnabled; - IMG_HANDLE hGpuUtilUserDVFS; - struct devfreq_simple_ondemand_data data; -#if defined(CONFIG_DEVFREQ_THERMAL) - struct thermal_cooling_device *psDevfreqCoolingDevice; -#endif -} IMG_DVFS_DEVICE; -#endif - -typedef struct _IMG_DVFS_ -{ -#if defined(SUPPORT_LINUX_DVFS) - IMG_DVFS_DEVICE sDVFSDevice; - IMG_DVFS_GOVERNOR sDVFSGovernor; - IMG_DVFS_GOVERNOR_CFG sDVFSGovernorCfg; -#endif - IMG_DVFS_DEVICE_CFG sDVFSDeviceCfg; -} PVRSRV_DVFS; -#endif/* (__linux__) */ - -#endif /* PVR_DVFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.c b/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.c deleted file mode 100644 index e65a4ab8c6a5b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.c +++ /dev/null @@ -1,810 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PowerVR devfreq device implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Linux module setup -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(NO_HARDWARE) - -#include -#if defined(CONFIG_DEVFREQ_THERMAL) -#include -#endif -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#include -#include -#else -#include -#endif - -#include "power.h" -#include "pvrsrv.h" -#include "pvrsrv_device.h" - -#include "rgxdevice.h" -#include "rgxinit.h" -#include "sofunc_rgx.h" - -#include "syscommon.h" - -#include "pvr_dvfs_device.h" - -#include "kernel_compatibility.h" - -static int _device_get_devid(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - int deviceId; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) - /* - * Older kernels do not have render drm_minor member in drm_device, - * so we fallback to primary node for device identification - */ - deviceId = ddev->primary->index; -#else - if (ddev->render) - deviceId = ddev->render->index; - else /* when render node is NULL, fallback to primary node */ - deviceId = ddev->primary->index; -#endif - - return deviceId; -} - -static IMG_INT32 devfreq_target(struct device *dev, unsigned long *requested_freq, IMG_UINT32 flags) -{ - int deviceId = _device_get_devid(dev); - PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId); - RGX_DATA *psRGXData = NULL; - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL; - RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL; - IMG_UINT32 ui32Freq, ui32CurFreq, ui32Volt; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - struct opp *opp; -#else - struct dev_pm_opp *opp; -#endif - - /* Check the device is registered */ - if (!psDeviceNode) - { - return -ENODEV; - } - - psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - - /* Check the RGX device is initialised */ - if (!psRGXData) - { - return -ENODATA; - } - - psRGXTimingInfo = psRGXData->psRGXTimingInfo; - if (!psDVFSDevice->bEnabled) - { - *requested_freq = psRGXTimingInfo->ui32CoreClockSpeed; - return 0; - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - rcu_read_lock(); -#endif - - opp = devfreq_recommended_opp(dev, requested_freq, flags); - if (IS_ERR(opp)) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - rcu_read_unlock(); -#endif - PVR_DPF((PVR_DBG_ERROR, "Invalid OPP")); - return PTR_ERR(opp); - } - - ui32Freq = dev_pm_opp_get_freq(opp); - ui32Volt = dev_pm_opp_get_voltage(opp); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - rcu_read_unlock(); -#else - dev_pm_opp_put(opp); -#endif - - ui32CurFreq = psRGXTimingInfo->ui32CoreClockSpeed; - - if (ui32CurFreq == ui32Freq) - { - return 0; - } - - if (PVRSRV_OK != PVRSRVDevicePreClockSpeedChange(psDeviceNode, - psDVFSDeviceCfg->bIdleReq, - NULL)) - { - dev_err(dev, "PVRSRVDevicePreClockSpeedChange failed\n"); - return -EPERM; - } - - /* Increasing frequency, change voltage first */ - if (ui32Freq > ui32CurFreq) - { - psDVFSDeviceCfg->pfnSetVoltage(ui32Volt); - } - - psDVFSDeviceCfg->pfnSetFrequency(ui32Freq); - - /* Decreasing frequency, change frequency first */ - if (ui32Freq < ui32CurFreq) - { - psDVFSDeviceCfg->pfnSetVoltage(ui32Volt); - } - - psRGXTimingInfo->ui32CoreClockSpeed = ui32Freq; - - PVRSRVDevicePostClockSpeedChange(psDeviceNode, psDVFSDeviceCfg->bIdleReq, - NULL); - - return 0; -} - -static int devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) -{ - int deviceId = _device_get_devid(dev); - PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId); - PVRSRV_RGXDEV_INFO *psDevInfo = NULL; - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - RGX_DATA *psRGXData = NULL; - RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL; - RGXFWIF_GPU_UTIL_STATS sGpuUtilStats; - PVRSRV_ERROR eError; - - /* Check the device is registered */ - if (!psDeviceNode) - { - return -ENODEV; - } - - psDevInfo = psDeviceNode->pvDevice; - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - - /* Check the RGX device is initialised */ - if (!psDevInfo || !psRGXData) - { - return -ENODATA; - } - - psRGXTimingInfo = psRGXData->psRGXTimingInfo; - stat->current_frequency = psRGXTimingInfo->ui32CoreClockSpeed; - - if (psDevInfo->pfnGetGpuUtilStats == NULL) - { - /* Not yet ready. So set times to something sensible. */ - stat->busy_time = 0; - stat->total_time = 0; - return 0; - } - - eError = psDevInfo->pfnGetGpuUtilStats(psDeviceNode, - psDVFSDevice->hGpuUtilUserDVFS, - &sGpuUtilStats); - - if (eError != PVRSRV_OK) - { - return -EAGAIN; - } - - stat->busy_time = sGpuUtilStats.ui64GpuStatActive; - stat->total_time = sGpuUtilStats.ui64GpuStatCumulative; - - return 0; -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -static IMG_INT32 devfreq_cur_freq(struct device *dev, unsigned long *freq) -{ - int deviceId = _device_get_devid(dev); - PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId); - RGX_DATA *psRGXData = NULL; - - /* Check the device is registered */ - if (!psDeviceNode) - { - return -ENODEV; - } - - psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - - /* Check the RGX device is initialised */ - if (!psRGXData) - { - return -ENODATA; - } - - *freq = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed; - - return 0; -} -#endif - -static struct devfreq_dev_profile img_devfreq_dev_profile = -{ - .target = devfreq_target, - .get_dev_status = devfreq_get_dev_status, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) - .get_cur_freq = devfreq_cur_freq, -#endif -}; - -static int FillOPPTable(struct device *dev, PVRSRV_DEVICE_NODE *psDeviceNode) -{ - const IMG_OPP *iopp; - int i, err = 0; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL; - - /* Check the device exists */ - if (!dev || !psDeviceNode) - { - return -ENODEV; - } - - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - - for (i = 0, iopp = psDVFSDeviceCfg->pasOPPTable; - i < psDVFSDeviceCfg->ui32OPPTableSize; - i++, iopp++) - { - err = dev_pm_opp_add(dev, iopp->ui32Freq, iopp->ui32Volt); - if (err) { - dev_err(dev, "Could not add OPP entry, %d\n", err); - return err; - } - } - - return 0; -} - -static void ClearOPPTable(struct device *dev, PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if (defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) - const IMG_OPP *iopp; - int i; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL; - - /* Check the device exists */ - if (!dev || !psDeviceNode) - { - return; - } - - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - - for (i = 0, iopp = psDVFSDeviceCfg->pasOPPTable; - i < psDVFSDeviceCfg->ui32OPPTableSize; - i++, iopp++) - { - dev_pm_opp_remove(dev, iopp->ui32Freq); - } -#endif -} - -static int GetOPPValues(struct device *dev, - unsigned long *min_freq, - unsigned long *min_volt, - unsigned long *max_freq) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - struct opp *opp; -#else - struct dev_pm_opp *opp; -#endif - int count, i, err = 0; - unsigned long freq; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) && \ - (!defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))) - unsigned int *freq_table; -#else - unsigned long *freq_table; -#endif - - count = dev_pm_opp_get_opp_count(dev); - if (count < 0) - { - dev_err(dev, "Could not fetch OPP count, %d\n", count); - return count; - } - - dev_info(dev, "Found %d OPP points.\n", count); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) - freq_table = devm_kcalloc(dev, count, sizeof(*freq_table), GFP_ATOMIC); -#else - freq_table = kcalloc(count, sizeof(*freq_table), GFP_ATOMIC); -#endif - if (! freq_table) - { - return -ENOMEM; - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - /* Start RCU read-side critical section to map frequency to OPP */ - rcu_read_lock(); -#endif - - /* Iterate over OPP table; Iteration 0 finds "opp w/ freq >= 0 Hz". */ - freq = 0; - opp = dev_pm_opp_find_freq_ceil(dev, &freq); - if (IS_ERR(opp)) - { - err = PTR_ERR(opp); - dev_err(dev, "Couldn't find lowest frequency, %d\n", err); - goto exit; - } - - *min_volt = dev_pm_opp_get_voltage(opp); - *max_freq = *min_freq = freq_table[0] = freq; - dev_info(dev, "opp[%d/%d]: (%lu Hz, %lu uV)\n", 1, count, freq, *min_volt); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) - dev_pm_opp_put(opp); -#endif - - /* Iteration i > 0 finds "opp w/ freq >= (opp[i-1].freq + 1)". */ - for (i = 1; i < count; i++) - { - freq++; - opp = dev_pm_opp_find_freq_ceil(dev, &freq); - if (IS_ERR(opp)) - { - err = PTR_ERR(opp); - dev_err(dev, "Couldn't find %dth frequency, %d\n", i, err); - goto exit; - } - - freq_table[i] = freq; - *max_freq = freq; - dev_info(dev, - "opp[%d/%d]: (%lu Hz, %lu uV)\n", - i + 1, - count, - freq, - dev_pm_opp_get_voltage(opp)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) - dev_pm_opp_put(opp); -#endif - } - -exit: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - rcu_read_unlock(); -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) - if (!err) - { - img_devfreq_dev_profile.freq_table = freq_table; - img_devfreq_dev_profile.max_state = count; - } - else -#endif - { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) - devm_kfree(dev, freq_table); -#else - kfree(freq_table); -#endif - } - - return err; -} - -#if defined(CONFIG_DEVFREQ_THERMAL) -static int RegisterCoolingDevice(struct device *dev, - IMG_DVFS_DEVICE *psDVFSDevice, - struct devfreq_cooling_power *powerOps) -{ - struct device_node *of_node; - int err = 0; - PVRSRV_VZ_RET_IF_MODE(GUEST, err); - - if (!psDVFSDevice) - { - return -EINVAL; - } - - if (!powerOps) - { - dev_info(dev, "Cooling: power ops not registered, not enabling cooling"); - return 0; - } - - of_node = of_node_get(dev->of_node); - - psDVFSDevice->psDevfreqCoolingDevice = of_devfreq_cooling_register_power( - of_node, psDVFSDevice->psDevFreq, powerOps); - - if (IS_ERR(psDVFSDevice->psDevfreqCoolingDevice)) - { - err = PTR_ERR(psDVFSDevice->psDevfreqCoolingDevice); - dev_err(dev, "Failed to register as devfreq cooling device %d", err); - } - - of_node_put(of_node); - - return err; -} -#endif - -#define TO_IMG_ERR(err) ((err == -EPROBE_DEFER) ? PVRSRV_ERROR_PROBE_DEFER : PVRSRV_ERROR_INIT_FAILURE) - -PVRSRV_ERROR InitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL; - struct device *psDev; - PVRSRV_ERROR eError; - int err; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - -#if !defined(CONFIG_PM_OPP) - return PVRSRV_ERROR_NOT_SUPPORTED; -#endif - - if (!psDeviceNode) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending) - { - PVR_DPF((PVR_DBG_ERROR, - "DVFS initialise pending for device node %p", - psDeviceNode)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - psDev = psDeviceNode->psDevConfig->pvOSDevice; - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending = IMG_TRUE; - -#if defined(SUPPORT_SOC_TIMER) - if (! psDeviceNode->psDevConfig->pfnSoCTimerRead) - { - PVR_DPF((PVR_DBG_ERROR, "System layer SoC timer callback not implemented")); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } -#endif - - eError = SORgxGpuUtilStatsRegister(&psDVFSDevice->hGpuUtilUserDVFS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to register to the GPU utilisation stats, %d", eError)); - return eError; - } - -#if defined(CONFIG_OF) - err = dev_pm_opp_of_add_table(psDev); - if (err) - { - /* - * If there are no device tree or system layer provided operating points - * then return an error - */ - if (err != -ENODEV || !psDVFSDeviceCfg->pasOPPTable) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to init opp table from devicetree, %d", err)); - eError = TO_IMG_ERR(err); - goto err_exit; - } - } -#endif - - if (psDVFSDeviceCfg->pasOPPTable) - { - err = FillOPPTable(psDev, psDeviceNode); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to fill OPP table with data, %d", err)); - eError = TO_IMG_ERR(err); - goto err_exit; - } - } - - PVR_TRACE(("PVR DVFS init pending: dev = %p, PVR device = %p", - psDev, psDeviceNode)); - - return PVRSRV_OK; - -err_exit: - DeinitDVFS(psDeviceNode); - return eError; -} - -PVRSRV_ERROR RegisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL; - IMG_DVFS_GOVERNOR_CFG *psDVFSGovernorCfg = NULL; - RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL; - struct device *psDev; - unsigned long min_freq = 0, max_freq = 0, min_volt = 0; - PVRSRV_ERROR eError; - int err; - - if (!psDeviceNode) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (!psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending) - { - PVR_DPF((PVR_DBG_ERROR, - "DVFS initialise not yet pending for device node %p", - psDeviceNode)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - psDev = psDeviceNode->psDevConfig->pvOSDevice; - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - psDVFSGovernorCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSGovernorCfg; - psRGXTimingInfo = ((RGX_DATA *)psDeviceNode->psDevConfig->hDevData)->psRGXTimingInfo; - psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending = IMG_FALSE; - psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bReady = IMG_TRUE; - - err = GetOPPValues(psDev, &min_freq, &min_volt, &max_freq); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to read OPP points, %d", err)); - eError = TO_IMG_ERR(err); - goto err_exit; - } - - img_devfreq_dev_profile.initial_freq = min_freq; - img_devfreq_dev_profile.polling_ms = psDVFSDeviceCfg->ui32PollMs; - - psRGXTimingInfo->ui32CoreClockSpeed = min_freq; - - psDVFSDeviceCfg->pfnSetFrequency(min_freq); - psDVFSDeviceCfg->pfnSetVoltage(min_volt); - - psDVFSDevice->data.upthreshold = psDVFSGovernorCfg->ui32UpThreshold; - psDVFSDevice->data.downdifferential = psDVFSGovernorCfg->ui32DownDifferential; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) - psDVFSDevice->psDevFreq = devm_devfreq_add_device(psDev, - &img_devfreq_dev_profile, - "simple_ondemand", - &psDVFSDevice->data); -#else - psDVFSDevice->psDevFreq = devfreq_add_device(psDev, - &img_devfreq_dev_profile, - "simple_ondemand", - &psDVFSDevice->data); -#endif - - if (IS_ERR(psDVFSDevice->psDevFreq)) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to add as devfreq device %p, %ld", - psDVFSDevice->psDevFreq, - PTR_ERR(psDVFSDevice->psDevFreq))); - eError = TO_IMG_ERR(PTR_ERR(psDVFSDevice->psDevFreq)); - goto err_exit; - } - - eError = SuspendDVFS(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVInit: Failed to suspend DVFS")); - goto err_exit; - } - -#if defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) - psDVFSDevice->psDevFreq->policy.user.min_freq = min_freq; - psDVFSDevice->psDevFreq->policy.user.max_freq = max_freq; -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) - psDVFSDevice->psDevFreq->scaling_min_freq = min_freq; - psDVFSDevice->psDevFreq->scaling_max_freq = max_freq; -#else - psDVFSDevice->psDevFreq->min_freq = min_freq; - psDVFSDevice->psDevFreq->max_freq = max_freq; -#endif - - err = devfreq_register_opp_notifier(psDev, psDVFSDevice->psDevFreq); - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to register opp notifier, %d", err)); - eError = TO_IMG_ERR(err); - goto err_exit; - } - -#if defined(CONFIG_DEVFREQ_THERMAL) - err = RegisterCoolingDevice(psDev, psDVFSDevice, psDVFSDeviceCfg->psPowerOps); - if (err) - { - eError = TO_IMG_ERR(err); - goto err_exit; - } -#endif - - PVR_TRACE(("PVR DVFS activated: %lu-%lu Hz, Period: %ums", - min_freq, - max_freq, - psDVFSDeviceCfg->ui32PollMs)); - - return PVRSRV_OK; - -err_exit: - UnregisterDVFSDevice(psDeviceNode); - return eError; -} - -void UnregisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - struct device *psDev = NULL; - IMG_INT32 i32Error; - - /* Check the device exists */ - if (!psDeviceNode) - { - return; - } - - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDev = psDeviceNode->psDevConfig->pvOSDevice; - - if (! psDVFSDevice) - { - return; - } - -#if defined(CONFIG_DEVFREQ_THERMAL) - if (!IS_ERR_OR_NULL(psDVFSDevice->psDevfreqCoolingDevice)) - { - devfreq_cooling_unregister(psDVFSDevice->psDevfreqCoolingDevice); - psDVFSDevice->psDevfreqCoolingDevice = NULL; - } -#endif - - if (psDVFSDevice->psDevFreq) - { - i32Error = devfreq_unregister_opp_notifier(psDev, psDVFSDevice->psDevFreq); - if (i32Error < 0) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to unregister OPP notifier")); - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) - devfreq_remove_device(psDVFSDevice->psDevFreq); -#else - devm_devfreq_remove_device(psDev, psDVFSDevice->psDevFreq); -#endif - - psDVFSDevice->psDevFreq = NULL; - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) && \ - LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) - kfree(img_devfreq_dev_profile.freq_table); -#endif - - psDVFSDevice->bInitPending = IMG_FALSE; - psDVFSDevice->bReady = IMG_FALSE; -} - -void DeinitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - struct device *psDev = NULL; - - /* Check the device exists */ - if (!psDeviceNode) - { - return; - } - - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDev = psDeviceNode->psDevConfig->pvOSDevice; - - /* Remove OPP entries for this device */ - ClearOPPTable(psDev, psDeviceNode); - -#if defined(CONFIG_OF) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) || \ - (defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))) - dev_pm_opp_of_remove_table(psDev); -#endif -#endif - - SORgxGpuUtilStatsUnregister(psDVFSDevice->hGpuUtilUserDVFS); - psDVFSDevice->hGpuUtilUserDVFS = NULL; - psDVFSDevice->bInitPending = IMG_FALSE; - psDVFSDevice->bReady = IMG_FALSE; -} - -PVRSRV_ERROR SuspendDVFS(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - - /* Check the device is registered */ - if (!psDeviceNode) - { - return PVRSRV_ERROR_INVALID_DEVICE; - } - - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - psDVFSDevice->bEnabled = IMG_FALSE; - - return PVRSRV_OK; -} - -PVRSRV_ERROR ResumeDVFS(PPVRSRV_DEVICE_NODE psDeviceNode) -{ - IMG_DVFS_DEVICE *psDVFSDevice = NULL; - - /* Check the device is registered */ - if (!psDeviceNode) - { - return PVRSRV_ERROR_INVALID_DEVICE; - } - - psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice; - - /* Not supported in GuestOS drivers */ - psDVFSDevice->bEnabled = !PVRSRV_VZ_MODE_IS(GUEST); - - return PVRSRV_OK; -} - -#endif /* !NO_HARDWARE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.h b/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.h deleted file mode 100644 index a246b240d9eec..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_dvfs_device.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ /*! -@File pvr_dvfs.c -@Title System level interface for DVFS -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_DVFS_DEVICE_H -#define PVR_DVFS_DEVICE_H - -#include "opaque_types.h" -#include "pvrsrv_error.h" - - -PVRSRV_ERROR InitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode); - -void DeinitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode); - -PVRSRV_ERROR RegisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode); - -void UnregisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode); - -PVRSRV_ERROR SuspendDVFS(PPVRSRV_DEVICE_NODE psDeviceNode); - -PVRSRV_ERROR ResumeDVFS(PPVRSRV_DEVICE_NODE psDeviceNode); - -#endif /* PVR_DVFS_DEVICE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_fd_sync_kernel.h b/drivers/gpu/drm/img-rogue/1.17/pvr_fd_sync_kernel.h deleted file mode 100644 index 3645e29079b15..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_fd_sync_kernel.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ /*! -@File pvr_fd_sync_kernel.h -@Title Kernel/userspace interface definitions to use the kernel sync - driver -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVR_FD_SYNC_KERNEL_H_ -#define _PVR_FD_SYNC_KERNEL_H_ - -#include -#include - -#include "pvr_drm.h" - -#define PVR_SYNC_MAX_QUERY_FENCE_POINTS 14 - -struct pvr_sync_pt_info { - /* Output */ - __u32 id; - __u32 ui32FWAddr; - __u32 ui32CurrOp; - __u32 ui32NextOp; - __u32 ui32TlTaken; -} __attribute__((packed, aligned(8))); - -#endif /* _PVR_FD_SYNC_KERNEL_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_fence.c b/drivers/gpu/drm/img-rogue/1.17/pvr_fence.c deleted file mode 100644 index 340bcd8db7746..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_fence.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * @File - * @Title PowerVR Linux fence interface - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_fence.h" -#include "services_kernel_client.h" -#include "sync_checkpoint_external.h" - -#define CREATE_TRACE_POINTS -#include "pvr_fence_trace.h" - -/* This header must always be included last */ -#include "kernel_compatibility.h" - -/* Global kmem_cache for pvr_fence object allocations */ -static struct kmem_cache *pvr_fence_cache; -static DEFINE_MUTEX(pvr_fence_cache_mutex); -static u32 pvr_fence_cache_refcount; - -#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, fmt, ...) \ - do { \ - if (pfnDumpDebugPrintf) \ - pfnDumpDebugPrintf(pvDumpDebugFile, fmt, \ - ## __VA_ARGS__); \ - else \ - pr_err(fmt "\n", ## __VA_ARGS__); \ - } while (0) - -static inline void -pvr_fence_sync_signal(struct pvr_fence *pvr_fence, u32 fence_sync_flags) -{ - SyncCheckpointSignal(pvr_fence->sync_checkpoint, fence_sync_flags); -} - -static inline bool -pvr_fence_sync_is_signaled(struct pvr_fence *pvr_fence, u32 fence_sync_flags) -{ - return SyncCheckpointIsSignalled(pvr_fence->sync_checkpoint, - fence_sync_flags); -} - -static inline u32 -pvr_fence_sync_value(struct pvr_fence *pvr_fence) -{ - if (SyncCheckpointIsErrored(pvr_fence->sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - return PVRSRV_SYNC_CHECKPOINT_ERRORED; - else if (SyncCheckpointIsSignalled(pvr_fence->sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - return PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - else - return PVRSRV_SYNC_CHECKPOINT_ACTIVE; -} - -static void -pvr_fence_context_check_status(struct work_struct *data) -{ - PVRSRVCheckStatus(NULL); -} - -void -pvr_context_value_str(struct pvr_fence_context *fctx, char *str, int size) -{ - snprintf(str, size, - "%u ctx=%llu refs=%u", - atomic_read(&fctx->fence_seqno), - fctx->fence_context, - refcount_read(&fctx->kref.refcount)); -} - -static void -pvr_fence_context_fences_dump(struct pvr_fence_context *fctx, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - struct pvr_fence *pvr_fence; - unsigned long flags; - char value[128]; - - spin_lock_irqsave(&fctx->list_lock, flags); - pvr_context_value_str(fctx, value, sizeof(value)); - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "%s: @%s", fctx->name, value); - list_for_each_entry(pvr_fence, &fctx->fence_list, fence_head) { - struct dma_fence *fence = pvr_fence->fence; - const char *timeline_value_str = "unknown timeline value"; - - pvr_fence->base.ops->fence_value_str(&pvr_fence->base, value, - sizeof(value)); - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " @%s", value); - - if (is_pvr_fence(fence)) - continue; - - if (fence->ops->timeline_value_str) { - fence->ops->timeline_value_str(fence, value, - sizeof(value)); - timeline_value_str = value; - } - - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " | %s: %s (driver: %s)", - fence->ops->get_timeline_name(fence), - timeline_value_str, - fence->ops->get_driver_name(fence)); - - if (fence->ops->fence_value_str) { - fence->ops->fence_value_str(fence, value, - sizeof(value)); - } - - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " | @%s (foreign)", value); - } - spin_unlock_irqrestore(&fctx->list_lock, flags); -} - -static inline unsigned int -pvr_fence_context_seqno_next(struct pvr_fence_context *fctx) -{ - return atomic_inc_return(&fctx->fence_seqno) - 1; -} - -/* This function prepends seqno to fence name */ -static inline void -pvr_fence_prepare_name(char *fence_name, size_t fence_name_size, - const char *name, unsigned int seqno) -{ - unsigned int len; - - len = OSStringUINT32ToStr(fence_name, fence_name_size, seqno); - if (likely((len > 0) && (fence_name_size >= (len + 1)))) { - fence_name[len] = '-'; - fence_name[len + 1] = '\0'; - } - strlcat(fence_name, name, fence_name_size); -} - -static void -pvr_fence_sched_free(struct rcu_head *rcu) -{ - struct pvr_fence *pvr_fence = container_of(rcu, struct pvr_fence, rcu); - - kmem_cache_free(pvr_fence_cache, pvr_fence); -} - -static inline void -pvr_fence_context_free_deferred(struct pvr_fence_context *fctx) -{ - struct pvr_fence *pvr_fence, *tmp; - LIST_HEAD(deferred_free_list); - unsigned long flags; - - spin_lock_irqsave(&fctx->list_lock, flags); - list_for_each_entry_safe(pvr_fence, tmp, - &fctx->deferred_free_list, - fence_head) - list_move(&pvr_fence->fence_head, &deferred_free_list); - spin_unlock_irqrestore(&fctx->list_lock, flags); - - list_for_each_entry_safe(pvr_fence, tmp, - &deferred_free_list, - fence_head) { - list_del(&pvr_fence->fence_head); - SyncCheckpointFree(pvr_fence->sync_checkpoint); - call_rcu(&pvr_fence->rcu, pvr_fence_sched_free); - module_put(THIS_MODULE); - } -} - -void -pvr_fence_context_free_deferred_callback(void *data) -{ - struct pvr_fence_context *fctx = (struct pvr_fence_context *)data; - - /* - * Free up any fence objects we have deferred freeing. - */ - pvr_fence_context_free_deferred(fctx); -} - -static void -pvr_fence_context_signal_fences(void *data) -{ - struct pvr_fence_context *fctx = (struct pvr_fence_context *)data; - struct pvr_fence *pvr_fence, *tmp; - unsigned long flags1; - - LIST_HEAD(signal_list); - - /* - * We can't call fence_signal while holding the lock as we can end up - * in a situation whereby pvr_fence_foreign_signal_sync, which also - * takes the list lock, ends up being called as a result of the - * fence_signal below, i.e. fence_signal(fence) -> fence->callback() - * -> fence_signal(foreign_fence) -> foreign_fence->callback() where - * the foreign_fence callback is pvr_fence_foreign_signal_sync. - * - * So extract the items we intend to signal and add them to their own - * queue. - */ - spin_lock_irqsave(&fctx->list_lock, flags1); - list_for_each_entry_safe(pvr_fence, tmp, &fctx->signal_list, signal_head) { - if (pvr_fence_sync_is_signaled(pvr_fence, PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - list_move_tail(&pvr_fence->signal_head, &signal_list); - } - spin_unlock_irqrestore(&fctx->list_lock, flags1); - - list_for_each_entry_safe(pvr_fence, tmp, &signal_list, signal_head) { - - PVR_FENCE_TRACE(&pvr_fence->base, "signalled fence (%s)\n", - pvr_fence->name); - trace_pvr_fence_signal_fence(pvr_fence); - spin_lock_irqsave(&pvr_fence->fctx->list_lock, flags1); - list_del(&pvr_fence->signal_head); - spin_unlock_irqrestore(&pvr_fence->fctx->list_lock, flags1); - dma_fence_signal(pvr_fence->fence); - dma_fence_put(pvr_fence->fence); - } - - /* - * Take this opportunity to free up any fence objects we - * have deferred freeing. - */ - pvr_fence_context_free_deferred(fctx); -} - -void -pvr_fence_context_signal_fences_nohw(void *data) -{ - pvr_fence_context_signal_fences(data); -} - -static void -pvr_fence_context_destroy_internal(struct pvr_fence_context *fctx) -{ - pvr_fence_context_free_deferred(fctx); - - if (WARN_ON(!list_empty_careful(&fctx->fence_list))) - pvr_fence_context_fences_dump(fctx, NULL, NULL); - - PVRSRVUnregisterCmdCompleteNotify(fctx->cmd_complete_handle); - - // wait for all fences to be freed before kmem_cache_destroy() is called - rcu_barrier(); - - /* Destroy pvr_fence object cache, if no one is using it */ - WARN_ON(pvr_fence_cache == NULL); - mutex_lock(&pvr_fence_cache_mutex); - if (--pvr_fence_cache_refcount == 0) - kmem_cache_destroy(pvr_fence_cache); - mutex_unlock(&pvr_fence_cache_mutex); - - kfree(fctx); -} - -static void -pvr_fence_context_unregister_dbg(void *dbg_request_handle) -{ - PVRSRVUnregisterDeviceDbgRequestNotify(dbg_request_handle); -} - -static void -pvr_fence_foreign_context_destroy_work(struct work_struct *data) -{ - struct pvr_fence_context *fctx = - container_of(data, struct pvr_fence_context, destroy_work); - - pvr_fence_context_destroy_internal(fctx); -} - -static void -pvr_fence_context_destroy_work(struct work_struct *data) -{ - struct pvr_fence_context *fctx = - container_of(data, struct pvr_fence_context, destroy_work); - - pvr_fence_context_unregister_dbg(fctx->dbg_request_handle); - pvr_fence_context_destroy_internal(fctx); -} - -static void -pvr_fence_context_debug_request(void *data, u32 verbosity, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - struct pvr_fence_context *fctx = (struct pvr_fence_context *)data; - - if (DD_VERB_LVL_ENABLED(verbosity, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - pvr_fence_context_fences_dump(fctx, pfnDumpDebugPrintf, - pvDumpDebugFile); -} - -static struct pvr_fence_context * -pvr_fence_context_create_internal(struct workqueue_struct *fence_status_wq, - const char *name, - work_func_t destroy_callback) -{ - struct pvr_fence_context *fctx; - PVRSRV_ERROR srv_err; - - fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); - if (!fctx) - return NULL; - - spin_lock_init(&fctx->lock); - atomic_set(&fctx->fence_seqno, 0); - INIT_WORK(&fctx->check_status_work, pvr_fence_context_check_status); - INIT_WORK(&fctx->destroy_work, destroy_callback); - spin_lock_init(&fctx->list_lock); - INIT_LIST_HEAD(&fctx->signal_list); - INIT_LIST_HEAD(&fctx->fence_list); - INIT_LIST_HEAD(&fctx->deferred_free_list); - - fctx->fence_wq = fence_status_wq; - - fctx->fence_context = dma_fence_context_alloc(1); - strlcpy(fctx->name, name, sizeof(fctx->name)); - - srv_err = PVRSRVRegisterCmdCompleteNotify(&fctx->cmd_complete_handle, - pvr_fence_context_signal_fences, - fctx); - if (srv_err != PVRSRV_OK) { - pr_err("%s: failed to register command complete callback (%s)\n", - __func__, PVRSRVGetErrorString(srv_err)); - goto err_free_fctx; - } - - /* Create pvr_fence object cache, if not already created */ - mutex_lock(&pvr_fence_cache_mutex); - if (pvr_fence_cache_refcount == 0) { - pvr_fence_cache = KMEM_CACHE(pvr_fence, 0); - if (!pvr_fence_cache) { - pr_err("%s: failed to allocate pvr_fence cache\n", - __func__); - mutex_unlock(&pvr_fence_cache_mutex); - goto err_unregister_cmd_complete_notify; - } - } - pvr_fence_cache_refcount++; - mutex_unlock(&pvr_fence_cache_mutex); - - kref_init(&fctx->kref); - - PVR_FENCE_CTX_TRACE(fctx, "created fence context (%s)\n", name); - trace_pvr_fence_context_create(fctx); - - return fctx; - -err_unregister_cmd_complete_notify: - PVRSRVUnregisterCmdCompleteNotify(fctx->cmd_complete_handle); -err_free_fctx: - kfree(fctx); - return NULL; -} - -/* - * pvr_fence_context_register_dbg - registers the debug handler for a - * fence context - * - * @dbg_request_handle: handle used to keep a reference for deregister - * @dev: device to attach the debug notifier. - * @pvr_fence_context: context used as data to the callback for debug - * - * Registers a debug notifier for a given context for a given device. - * - * Returns PVRSRV_OK if successful. - */ -PVRSRV_ERROR pvr_fence_context_register_dbg(void *dbg_request_handle, - void *dev, - struct pvr_fence_context *fctx) -{ - PVRSRV_ERROR srv_err; - - srv_err = PVRSRVRegisterDeviceDbgRequestNotify(dbg_request_handle, - dev, - pvr_fence_context_debug_request, - DEBUG_REQUEST_LINUXFENCE, - fctx); - if (srv_err != PVRSRV_OK) { - pr_err("%s: failed to register debug request callback (%s)\n", - __func__, PVRSRVGetErrorString(srv_err)); - } - - return srv_err; -} - -/* - * pvr_fence_foreign_context_create - creates a PVR fence context - * @fence_status_wq: linux workqueue used to signal foreign fences - * @name: context name (used for debugging) - * - * Creates a PVR foreign fence context that can be used to create PVR fences - * or to create PVR fences from an existing fence. - * - * pvr_fence_context_destroy should be called to clean up the fence context. - * - * Returns NULL if a context cannot be created. - */ -struct pvr_fence_context * -pvr_fence_foreign_context_create(struct workqueue_struct *fence_status_wq, - const char *name) -{ - return pvr_fence_context_create_internal(fence_status_wq, name, - pvr_fence_foreign_context_destroy_work); -} - -/* - * pvr_fence_context_create - creates a PVR fence context - * @dev_cookie: services device cookie - * @fence_status_wq: Status workqueue to queue fence update CBs. - * @name: context name (used for debugging) - * - * Creates a PVR fence context that can be used to create PVR fences or to - * create PVR fences from an existing fence. - * - * pvr_fence_context_destroy should be called to clean up the fence context. - * - * Returns NULL if a context cannot be created. - */ -struct pvr_fence_context * -pvr_fence_context_create(void *dev_cookie, - struct workqueue_struct *fence_status_wq, - const char *name) -{ - struct pvr_fence_context *fctx; - PVRSRV_ERROR eError; - - fctx = pvr_fence_context_create_internal(fence_status_wq, name, - pvr_fence_context_destroy_work); - if (fctx == NULL) { - pr_err("%s: failed to create fence context", __func__); - goto err_out; - } - - eError = pvr_fence_context_register_dbg(&fctx->dbg_request_handle, - dev_cookie, - fctx); - if (eError != PVRSRV_OK) { - pr_err("%s: failed to register fence context debug (%s)\n", - __func__, PVRSRVGetErrorString(eError)); - goto err_destroy_ctx; - } - - return fctx; - -err_destroy_ctx: - pvr_fence_context_destroy(fctx); -err_out: - return NULL; -} - -static void pvr_fence_context_destroy_kref(struct kref *kref) -{ - struct pvr_fence_context *fctx = - container_of(kref, struct pvr_fence_context, kref); - - PVR_FENCE_CTX_TRACE(fctx, "destroyed fence context (%s)\n", fctx->name); - - trace_pvr_fence_context_destroy_kref(fctx); - - schedule_work(&fctx->destroy_work); -} - -/* - * pvr_fence_context_destroy - destroys a context - * @fctx: PVR fence context to destroy - * - * Destroys a PVR fence context with the expectation that all fences have been - * destroyed. - */ -void -pvr_fence_context_destroy(struct pvr_fence_context *fctx) -{ - trace_pvr_fence_context_destroy(fctx); - - kref_put(&fctx->kref, pvr_fence_context_destroy_kref); -} - -static const char * -pvr_fence_get_driver_name(struct dma_fence *fence) -{ - return PVR_LDM_DRIVER_REGISTRATION_NAME; -} - -static const char * -pvr_fence_get_timeline_name(struct dma_fence *fence) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - - if (pvr_fence) - return pvr_fence->fctx->name; - return NULL; -} - -static -void pvr_fence_fence_value_str(struct dma_fence *fence, char *str, int size) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - - if (!pvr_fence) - return; - - snprintf(str, size, - "%llu: (%s%s) refs=%u fwaddr=%#08x enqueue=%u status=%-9s %s%s", - (u64) pvr_fence->fence->seqno, - test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &pvr_fence->fence->flags) ? "+" : "-", - test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &pvr_fence->fence->flags) ? "+" : "-", - refcount_read(&pvr_fence->fence->refcount.refcount), - SyncCheckpointGetFirmwareAddr( - pvr_fence->sync_checkpoint), - SyncCheckpointGetEnqueuedCount(pvr_fence->sync_checkpoint), - SyncCheckpointGetStateString(pvr_fence->sync_checkpoint), - pvr_fence->name, - (&pvr_fence->base != pvr_fence->fence) ? - "(foreign)" : ""); -} - -static -void pvr_fence_timeline_value_str(struct dma_fence *fence, char *str, int size) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - - if (pvr_fence) - pvr_context_value_str(pvr_fence->fctx, str, size); -} - -static bool -pvr_fence_enable_signaling(struct dma_fence *fence) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - unsigned long flags; - - if (!pvr_fence) - return false; - - WARN_ON_SMP(!spin_is_locked(&pvr_fence->fctx->lock)); - - if (pvr_fence_sync_is_signaled(pvr_fence, PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - return false; - - dma_fence_get(&pvr_fence->base); - - spin_lock_irqsave(&pvr_fence->fctx->list_lock, flags); - list_add_tail(&pvr_fence->signal_head, &pvr_fence->fctx->signal_list); - spin_unlock_irqrestore(&pvr_fence->fctx->list_lock, flags); - - PVR_FENCE_TRACE(&pvr_fence->base, "signalling enabled (%s)\n", - pvr_fence->name); - trace_pvr_fence_enable_signaling(pvr_fence); - - return true; -} - -static bool -pvr_fence_is_signaled(struct dma_fence *fence) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - - if (pvr_fence) - return pvr_fence_sync_is_signaled(pvr_fence, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT); - return false; -} - -static void -pvr_fence_release(struct dma_fence *fence) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - unsigned long flags; - - if (pvr_fence) { - struct pvr_fence_context *fctx = pvr_fence->fctx; - - PVR_FENCE_TRACE(&pvr_fence->base, "released fence (%s)\n", - pvr_fence->name); - trace_pvr_fence_release(pvr_fence); - - spin_lock_irqsave(&fctx->list_lock, flags); - list_move(&pvr_fence->fence_head, - &fctx->deferred_free_list); - spin_unlock_irqrestore(&fctx->list_lock, flags); - - kref_put(&fctx->kref, pvr_fence_context_destroy_kref); - } -} - -const struct dma_fence_ops pvr_fence_ops = { - .get_driver_name = pvr_fence_get_driver_name, - .get_timeline_name = pvr_fence_get_timeline_name, - .fence_value_str = pvr_fence_fence_value_str, - .timeline_value_str = pvr_fence_timeline_value_str, - .enable_signaling = pvr_fence_enable_signaling, - .signaled = pvr_fence_is_signaled, - .wait = dma_fence_default_wait, - .release = pvr_fence_release, -}; - -/* - * pvr_fence_create - creates a PVR fence - * @fctx: PVR fence context on which the PVR fence should be created - * @sync_checkpoint_ctx: context in which to create sync checkpoints - * @timeline_fd: timeline on which the PVR fence should be created - * @name: PVR fence name (used for debugging) - * - * Creates a PVR fence. - * - * Once the fence is finished with, pvr_fence_destroy should be called. - * - * Returns NULL if a PVR fence cannot be created. - */ -struct pvr_fence * -pvr_fence_create(struct pvr_fence_context *fctx, - struct SYNC_CHECKPOINT_CONTEXT_TAG *sync_checkpoint_ctx, - int timeline_fd, const char *name) -{ - struct pvr_fence *pvr_fence; - unsigned int seqno; - unsigned long flags; - PVRSRV_ERROR srv_err; - - if (!try_module_get(THIS_MODULE)) - goto err_exit; - - /* Note: As kmem_cache is used to allocate pvr_fence objects, - * make sure that all members of pvr_fence struct are initialized - * here - */ - pvr_fence = kmem_cache_alloc(pvr_fence_cache, GFP_KERNEL); - if (unlikely(!pvr_fence)) - goto err_module_put; - - srv_err = SyncCheckpointAlloc(sync_checkpoint_ctx, - (PVRSRV_TIMELINE) timeline_fd, PVRSRV_NO_FENCE, - name, &pvr_fence->sync_checkpoint); - if (unlikely(srv_err != PVRSRV_OK)) - goto err_free_fence; - - INIT_LIST_HEAD(&pvr_fence->fence_head); - INIT_LIST_HEAD(&pvr_fence->signal_head); - pvr_fence->fctx = fctx; - seqno = pvr_fence_context_seqno_next(fctx); - /* Add the seqno to the fence name for easier debugging */ - pvr_fence_prepare_name(pvr_fence->name, sizeof(pvr_fence->name), - name, seqno); - - /* Reset cb to zero */ - memset(&pvr_fence->cb, 0, sizeof(pvr_fence->cb)); - pvr_fence->fence = &pvr_fence->base; - - dma_fence_init(&pvr_fence->base, &pvr_fence_ops, &fctx->lock, - fctx->fence_context, seqno); - - spin_lock_irqsave(&fctx->list_lock, flags); - list_add_tail(&pvr_fence->fence_head, &fctx->fence_list); - spin_unlock_irqrestore(&fctx->list_lock, flags); - - kref_get(&fctx->kref); - - PVR_FENCE_TRACE(&pvr_fence->base, "created fence (%s)\n", name); - trace_pvr_fence_create(pvr_fence); - - return pvr_fence; - -err_free_fence: - kmem_cache_free(pvr_fence_cache, pvr_fence); -err_module_put: - module_put(THIS_MODULE); -err_exit: - return NULL; -} - -static const char * -pvr_fence_foreign_get_driver_name(struct dma_fence *fence) -{ - return PVR_LDM_DRIVER_REGISTRATION_NAME; -} - -static const char * -pvr_fence_foreign_get_timeline_name(struct dma_fence *fence) -{ - return "foreign"; -} - -static -void pvr_fence_foreign_fence_value_str(struct dma_fence *fence, char *str, - int size) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - u32 sync_addr = 0; - u32 sync_value_next; - - if (WARN_ON(!pvr_fence)) - return; - - sync_addr = SyncCheckpointGetFirmwareAddr(pvr_fence->sync_checkpoint); - sync_value_next = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - - /* - * Include the fence flag bits from the foreign fence instead of our - * shadow copy. This is done as the shadow fence flag bits aren't used. - */ - snprintf(str, size, - "%llu: (%s%s) refs=%u fwaddr=%#08x cur=%#08x nxt=%#08x %s", - (u64) fence->seqno, - test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &pvr_fence->fence->flags) ? "+" : "-", - test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &pvr_fence->fence->flags) ? "+" : "-", - refcount_read(&fence->refcount.refcount), - sync_addr, - pvr_fence_sync_value(pvr_fence), - sync_value_next, - pvr_fence->name); -} - -static -void pvr_fence_foreign_timeline_value_str(struct dma_fence *fence, char *str, - int size) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - - if (pvr_fence) - pvr_context_value_str(pvr_fence->fctx, str, size); -} - -static bool -pvr_fence_foreign_enable_signaling(struct dma_fence *fence) -{ - WARN_ON("cannot enable signalling on foreign fence"); - return false; -} - -static signed long -pvr_fence_foreign_wait(struct dma_fence *fence, bool intr, signed long timeout) -{ - WARN_ON("cannot wait on foreign fence"); - return 0; -} - -static void -pvr_fence_foreign_release(struct dma_fence *fence) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - unsigned long flags; - - if (pvr_fence) { - struct pvr_fence_context *fctx = pvr_fence->fctx; - struct dma_fence *foreign_fence = pvr_fence->fence; - - PVR_FENCE_TRACE(&pvr_fence->base, - "released fence for foreign fence %llu#%d (%s)\n", - (u64) pvr_fence->fence->context, - pvr_fence->fence->seqno, pvr_fence->name); - trace_pvr_fence_foreign_release(pvr_fence); - - spin_lock_irqsave(&fctx->list_lock, flags); - list_move(&pvr_fence->fence_head, - &fctx->deferred_free_list); - spin_unlock_irqrestore(&fctx->list_lock, flags); - - dma_fence_put(foreign_fence); - - kref_put(&fctx->kref, - pvr_fence_context_destroy_kref); - } -} - -const struct dma_fence_ops pvr_fence_foreign_ops = { - .get_driver_name = pvr_fence_foreign_get_driver_name, - .get_timeline_name = pvr_fence_foreign_get_timeline_name, - .fence_value_str = pvr_fence_foreign_fence_value_str, - .timeline_value_str = pvr_fence_foreign_timeline_value_str, - .enable_signaling = pvr_fence_foreign_enable_signaling, - .wait = pvr_fence_foreign_wait, - .release = pvr_fence_foreign_release, -}; - -static void -pvr_fence_foreign_signal_sync(struct dma_fence *fence, struct dma_fence_cb *cb) -{ - struct pvr_fence *pvr_fence = container_of(cb, struct pvr_fence, cb); - struct pvr_fence_context *fctx = pvr_fence->fctx; - - WARN_ON_ONCE(is_pvr_fence(fence)); - - /* Callback registered by dma_fence_add_callback can be called from an atomic ctx */ - pvr_fence_sync_signal(pvr_fence, PVRSRV_FENCE_FLAG_CTX_ATOMIC); - - trace_pvr_fence_foreign_signal(pvr_fence); - - queue_work(fctx->fence_wq, &fctx->check_status_work); - - PVR_FENCE_TRACE(&pvr_fence->base, - "foreign fence %llu#%d signalled (%s)\n", - (u64) pvr_fence->fence->context, - pvr_fence->fence->seqno, pvr_fence->name); - - /* Drop the reference on the base fence */ - dma_fence_put(&pvr_fence->base); -} - -/* - * pvr_fence_create_from_fence - creates a PVR fence from a fence - * @fctx: PVR fence context on which the PVR fence should be created - * @sync_checkpoint_ctx: context in which to create sync checkpoints - * @fence: fence from which the PVR fence should be created - * @fence_fd: fd for the sync file to which the fence belongs. If it doesn't - * belong to a sync file then PVRSRV_NO_FENCE should be given - * instead. - * @name: PVR fence name (used for debugging) - * - * Creates a PVR fence from an existing fence. If the fence is a foreign fence, - * i.e. one that doesn't originate from a PVR fence context, then a new PVR - * fence will be created using the specified sync_checkpoint_context. - * Otherwise, a reference will be taken on the underlying fence and the PVR - * fence will be returned. - * - * Once the fence is finished with, pvr_fence_destroy should be called. - * - * Returns NULL if a PVR fence cannot be created. - */ - -struct pvr_fence * -pvr_fence_create_from_fence(struct pvr_fence_context *fctx, - struct SYNC_CHECKPOINT_CONTEXT_TAG *sync_checkpoint_ctx, - struct dma_fence *fence, - PVRSRV_FENCE fence_fd, - const char *name) -{ - struct pvr_fence *pvr_fence = to_pvr_fence(fence); - unsigned int seqno; - unsigned long flags; - PVRSRV_ERROR srv_err; - int err; - - if (pvr_fence) { - if (WARN_ON(fence->ops == &pvr_fence_foreign_ops)) - return NULL; - dma_fence_get(fence); - - PVR_FENCE_TRACE(fence, "created fence from PVR fence (%s)\n", - name); - return pvr_fence; - } - - if (!try_module_get(THIS_MODULE)) - goto err_exit; - - /* Note: As kmem_cache is used to allocate pvr_fence objects, - * make sure that all members of pvr_fence struct are initialized - * here - */ - pvr_fence = kmem_cache_alloc(pvr_fence_cache, GFP_KERNEL); - if (!pvr_fence) - goto err_module_put; - - srv_err = SyncCheckpointAlloc(sync_checkpoint_ctx, - SYNC_CHECKPOINT_FOREIGN_CHECKPOINT, - fence_fd, - name, &pvr_fence->sync_checkpoint); - if (srv_err != PVRSRV_OK) - goto err_free_pvr_fence; - - INIT_LIST_HEAD(&pvr_fence->fence_head); - INIT_LIST_HEAD(&pvr_fence->signal_head); - pvr_fence->fctx = fctx; - pvr_fence->fence = dma_fence_get(fence); - seqno = pvr_fence_context_seqno_next(fctx); - /* Add the seqno to the fence name for easier debugging */ - pvr_fence_prepare_name(pvr_fence->name, sizeof(pvr_fence->name), - name, seqno); - - /* - * We use the base fence to refcount the PVR fence and to do the - * necessary clean up once the refcount drops to 0. - */ - dma_fence_init(&pvr_fence->base, &pvr_fence_foreign_ops, &fctx->lock, - fctx->fence_context, seqno); - - /* - * Take an extra reference on the base fence that gets dropped when the - * foreign fence is signalled. - */ - dma_fence_get(&pvr_fence->base); - - spin_lock_irqsave(&fctx->list_lock, flags); - list_add_tail(&pvr_fence->fence_head, &fctx->fence_list); - spin_unlock_irqrestore(&fctx->list_lock, flags); - kref_get(&fctx->kref); - - PVR_FENCE_TRACE(&pvr_fence->base, - "created fence from foreign fence %llu#%d (%s)\n", - (u64) pvr_fence->fence->context, - pvr_fence->fence->seqno, name); - - err = dma_fence_add_callback(fence, &pvr_fence->cb, - pvr_fence_foreign_signal_sync); - if (err) { - if (err != -ENOENT) { - pr_err("%s: failed to add fence callback (err=%d)", - __func__, err); - goto err_put_ref; - } - - /* - * The fence has already signalled so set the sync as signalled. - * The "signalled" hwperf packet should be emitted because the - * callback won't be called for already signalled fence hence, - * PVRSRV_FENCE_FLAG_NONE flag. - */ - pvr_fence_sync_signal(pvr_fence, PVRSRV_FENCE_FLAG_NONE); - PVR_FENCE_TRACE(&pvr_fence->base, - "foreign fence %llu#%d already signaled (%s)\n", - (u64) pvr_fence->fence->context, - pvr_fence->fence->seqno, - name); - dma_fence_put(&pvr_fence->base); - } - - trace_pvr_fence_foreign_create(pvr_fence); - - return pvr_fence; - -err_put_ref: - kref_put(&fctx->kref, pvr_fence_context_destroy_kref); - spin_lock_irqsave(&fctx->list_lock, flags); - list_del(&pvr_fence->fence_head); - spin_unlock_irqrestore(&fctx->list_lock, flags); - SyncCheckpointFree(pvr_fence->sync_checkpoint); -err_free_pvr_fence: - kmem_cache_free(pvr_fence_cache, pvr_fence); -err_module_put: - module_put(THIS_MODULE); -err_exit: - return NULL; -} - -/* - * pvr_fence_destroy - destroys a PVR fence - * @pvr_fence: PVR fence to destroy - * - * Destroys a PVR fence. Upon return, the PVR fence may still exist if something - * else still references the underlying fence, e.g. a reservation object, or if - * software signalling has been enabled and the fence hasn't yet been signalled. - */ -void -pvr_fence_destroy(struct pvr_fence *pvr_fence) -{ - PVR_FENCE_TRACE(&pvr_fence->base, "destroyed fence (%s)\n", - pvr_fence->name); - - dma_fence_put(&pvr_fence->base); -} - -/* - * pvr_fence_sw_signal - signals a PVR fence sync - * @pvr_fence: PVR fence to signal - * - * Sets the PVR fence sync value to signalled. - * - * Returns -EINVAL if the PVR fence represents a foreign fence. - */ -int -pvr_fence_sw_signal(struct pvr_fence *pvr_fence) -{ - if (!is_our_fence(pvr_fence->fctx, &pvr_fence->base)) - return -EINVAL; - - pvr_fence_sync_signal(pvr_fence, PVRSRV_FENCE_FLAG_NONE); - - queue_work(pvr_fence->fctx->fence_wq, - &pvr_fence->fctx->check_status_work); - - PVR_FENCE_TRACE(&pvr_fence->base, "sw set fence sync signalled (%s)\n", - pvr_fence->name); - - return 0; -} - -/* - * pvr_fence_sw_error - errors the sync checkpoint backing a PVR fence - * @pvr_fence: PVR fence to error - * - * Sets the PVR fence sync checkpoint value to errored. - * - * Returns -EINVAL if the PVR fence represents a foreign fence. - */ -int -pvr_fence_sw_error(struct pvr_fence *pvr_fence) -{ - if (!is_our_fence(pvr_fence->fctx, &pvr_fence->base)) - return -EINVAL; - - SyncCheckpointError(pvr_fence->sync_checkpoint, PVRSRV_FENCE_FLAG_NONE); - PVR_FENCE_TRACE(&pvr_fence->base, "sw set fence sync errored (%s)\n", - pvr_fence->name); - - return 0; -} - -int -pvr_fence_get_checkpoints(struct pvr_fence **pvr_fences, u32 nr_fences, - struct SYNC_CHECKPOINT_TAG **fence_checkpoints) -{ - struct SYNC_CHECKPOINT_TAG **next_fence_checkpoint = fence_checkpoints; - struct pvr_fence **next_pvr_fence = pvr_fences; - int fence_checkpoint_idx; - - if (nr_fences > 0) { - - for (fence_checkpoint_idx = 0; fence_checkpoint_idx < nr_fences; - fence_checkpoint_idx++) { - struct pvr_fence *next_fence = *next_pvr_fence++; - *next_fence_checkpoint++ = next_fence->sync_checkpoint; - /* Take reference on sync checkpoint (will be dropped - * later by kick code) - */ - SyncCheckpointTakeRef(next_fence->sync_checkpoint); - } - } - - return 0; -} - -struct SYNC_CHECKPOINT_TAG * -pvr_fence_get_checkpoint(struct pvr_fence *update_fence) -{ - return update_fence->sync_checkpoint; -} - -/* - * pvr_fence_dump_info_on_stalled_ufos - displays debug - * information on a native fence associated with any of - * the ufos provided. This function will be called from - * pvr_sync_file.c if the driver determines any GPU work - * is stuck waiting for a sync checkpoint representing a - * foreign sync to be signalled. - * @nr_ufos: number of ufos in vaddrs - * @vaddrs: array of FW addresses of UFOs which the - * driver is waiting on. - * - * Output debug information to kernel log on linux fences - * which would be responsible for signalling the sync - * checkpoints indicated by the ufo vaddresses. - * - * Returns the number of ufos in the array which were found - * to be associated with foreign syncs. - */ -u32 pvr_fence_dump_info_on_stalled_ufos(struct pvr_fence_context *fctx, - u32 nr_ufos, u32 *vaddrs) -{ - int our_ufo_ct = 0; - struct pvr_fence *pvr_fence; - unsigned long flags; - - spin_lock_irqsave(&fctx->list_lock, flags); - /* dump info on any ufos in our active list */ - list_for_each_entry(pvr_fence, &fctx->fence_list, fence_head) { - u32 *this_ufo_vaddr = vaddrs; - int ufo_num; - DUMPDEBUG_PRINTF_FUNC *pfnDummy = NULL; - - for (ufo_num = 0; ufo_num < nr_ufos; ufo_num++) { - struct SYNC_CHECKPOINT_TAG *checkpoint = - pvr_fence->sync_checkpoint; - const u32 fence_ufo_addr = - SyncCheckpointGetFirmwareAddr(checkpoint); - - if (fence_ufo_addr != this_ufo_vaddr[ufo_num]) - continue; - - /* Dump sync info */ - PVR_DUMPDEBUG_LOG(pfnDummy, NULL, - "\tSyncID = %d, FWAddr = 0x%08x: TLID = %d (Foreign Fence - [%p] %s)", - SyncCheckpointGetId(checkpoint), - fence_ufo_addr, - SyncCheckpointGetTimeline(checkpoint), - pvr_fence->fence, - pvr_fence->name); - our_ufo_ct++; - } - } - spin_unlock_irqrestore(&fctx->list_lock, flags); - return our_ufo_ct; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_fence.h b/drivers/gpu/drm/img-rogue/1.17/pvr_fence.h deleted file mode 100644 index 39b8388b70529..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_fence.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * @File - * @Title PowerVR Linux fence interface - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ - -#if !defined(__PVR_FENCE_H__) -#define __PVR_FENCE_H__ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) -static inline void pvr_fence_cleanup(void) -{ -} -#else -#include "services_kernel_client.h" -#include "pvr_linux_fence.h" -#include -#include -#include - -struct SYNC_CHECKPOINT_CONTEXT_TAG; -struct SYNC_CHECKPOINT_TAG; - -/* - * pvr_fence_context - PVR fence context used to create and manage PVR fences - * @lock: protects the context and fences created on the context - * @name: fence context name (used for debugging) - * @dbg_request_handle: handle for callback used to dump debug data - * @fence_context: fence context with which to associate fences - * @fence_seqno: sequence number to use for the next fence - * @fence_wq: work queue for signalled fence work - * @check_status_work: work item used to inform services when a foreign fence - * has signalled - * @cmd_complete_handle: handle for callback used to signal fences when fence - * syncs are met - * @list_lock: protects the active and active foreign lists - * @signal_list: list of fences waiting to be signalled - * @fence_list: list of fences (used for debugging) - * @deferred_free_list: list of fences that we will free when we are no longer - * holding spinlocks. The frees get implemented when an update fence is - * signalled or the context is freed. - */ -struct pvr_fence_context { - spinlock_t lock; - char name[32]; - void *dbg_request_handle; - u64 fence_context; - atomic_t fence_seqno; - - struct workqueue_struct *fence_wq; - struct work_struct check_status_work; - - void *cmd_complete_handle; - - spinlock_t list_lock; - struct list_head signal_list; - struct list_head fence_list; - struct list_head deferred_free_list; - - struct kref kref; - struct work_struct destroy_work; -}; - -/* - * pvr_fence - PVR fence that represents both native and foreign fences - * @base: fence structure - * @fctx: fence context on which this fence was created - * @name: fence name (used for debugging) - * @fence: pointer to base fence structure or foreign fence - * @sync_checkpoint: services sync checkpoint used by hardware - * @fence_head: entry on the context fence and deferred free list - * @signal_head: entry on the context signal list - * @cb: foreign fence callback to set the sync to signalled - */ -struct pvr_fence { - struct dma_fence base; - struct pvr_fence_context *fctx; - char name[32]; - - struct dma_fence *fence; - struct SYNC_CHECKPOINT_TAG *sync_checkpoint; - - struct list_head fence_head; - struct list_head signal_head; - struct dma_fence_cb cb; - struct rcu_head rcu; -}; - -extern const struct dma_fence_ops pvr_fence_ops; -extern const struct dma_fence_ops pvr_fence_foreign_ops; - -static inline bool is_our_fence(struct pvr_fence_context *fctx, - struct dma_fence *fence) -{ - return (fence->context == fctx->fence_context); -} - -static inline bool is_pvr_fence(struct dma_fence *fence) -{ - return ((fence->ops == &pvr_fence_ops) || - (fence->ops == &pvr_fence_foreign_ops)); -} - -static inline struct pvr_fence *to_pvr_fence(struct dma_fence *fence) -{ - if (is_pvr_fence(fence)) - return container_of(fence, struct pvr_fence, base); - - return NULL; -} - -PVRSRV_ERROR pvr_fence_context_register_dbg(void *dbg_request_handle, - void *dev, - struct pvr_fence_context *fctx); -struct pvr_fence_context * -pvr_fence_foreign_context_create(struct workqueue_struct *fence_status_wq, - const char *name); -struct pvr_fence_context * -pvr_fence_context_create(void *dev_cookie, - struct workqueue_struct *fence_status_wq, - const char *name); -void pvr_fence_context_destroy(struct pvr_fence_context *fctx); -void pvr_context_value_str(struct pvr_fence_context *fctx, char *str, int size); - -struct pvr_fence * -pvr_fence_create(struct pvr_fence_context *fctx, - struct SYNC_CHECKPOINT_CONTEXT_TAG *sync_checkpoint_ctx, - int timeline_fd, const char *name); -struct pvr_fence * -pvr_fence_create_from_fence(struct pvr_fence_context *fctx, - struct SYNC_CHECKPOINT_CONTEXT_TAG *sync_checkpoint_ctx, - struct dma_fence *fence, - PVRSRV_FENCE fence_fd, - const char *name); -void pvr_fence_destroy(struct pvr_fence *pvr_fence); -int pvr_fence_sw_signal(struct pvr_fence *pvr_fence); -int pvr_fence_sw_error(struct pvr_fence *pvr_fence); - -int pvr_fence_get_checkpoints(struct pvr_fence **pvr_fences, u32 nr_fences, - struct SYNC_CHECKPOINT_TAG **fence_checkpoints); -struct SYNC_CHECKPOINT_TAG * -pvr_fence_get_checkpoint(struct pvr_fence *update_fence); - -void pvr_fence_context_signal_fences_nohw(void *data); - -void pvr_fence_context_free_deferred_callback(void *data); - -u32 pvr_fence_dump_info_on_stalled_ufos(struct pvr_fence_context *fctx, - u32 nr_ufos, - u32 *vaddrs); - -static inline void pvr_fence_cleanup(void) -{ - /* - * Ensure all PVR fence contexts have been destroyed, by flushing - * the global workqueue. - */ - __flush_workqueue(system_wq); -} - -#if defined(PVR_FENCE_DEBUG) -#define PVR_FENCE_CTX_TRACE(c, fmt, ...) \ - do { \ - struct pvr_fence_context *__fctx = (c); \ - pr_err("c %llu: (PVR) " fmt, (u64) __fctx->fence_context, \ - ## __VA_ARGS__); \ - } while (0) -#else -#define PVR_FENCE_CTX_TRACE(c, fmt, ...) -#endif - -#define PVR_FENCE_CTX_WARN(c, fmt, ...) \ - do { \ - struct pvr_fence_context *__fctx = (c); \ - pr_warn("c %llu: (PVR) " fmt, (u64) __fctx->fence_context, \ - ## __VA_ARGS__); \ - } while (0) - -#define PVR_FENCE_CTX_ERR(c, fmt, ...) \ - do { \ - struct pvr_fence_context *__fctx = (c); \ - pr_err("c %llu: (PVR) " fmt, (u64) __fctx->fence_context, \ - ## __VA_ARGS__); \ - } while (0) - -#if defined(PVR_FENCE_DEBUG) -#define PVR_FENCE_TRACE(f, fmt, ...) \ - DMA_FENCE_ERR(f, "(PVR) " fmt, ## __VA_ARGS__) -#else -#define PVR_FENCE_TRACE(f, fmt, ...) -#endif - -#define PVR_FENCE_WARN(f, fmt, ...) \ - DMA_FENCE_WARN(f, "(PVR) " fmt, ## __VA_ARGS__) - -#define PVR_FENCE_ERR(f, fmt, ...) \ - DMA_FENCE_ERR(f, "(PVR) " fmt, ## __VA_ARGS__) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */ -#endif /* !defined(__PVR_FENCE_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_fence_trace.h b/drivers/gpu/drm/img-rogue/1.17/pvr_fence_trace.h deleted file mode 100644 index 2bbcec49fbc71..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_fence_trace.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM pvr_fence_1_17 - -#if !defined(_TRACE_PVR_FENCE_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_PVR_FENCE_H - -#include - -struct pvr_fence; -struct pvr_fence_context; - -DECLARE_EVENT_CLASS(pvr_fence_context, - - TP_PROTO(struct pvr_fence_context *fctx), - TP_ARGS(fctx), - - TP_STRUCT__entry( - __string(name, fctx->name) - __array(char, val, 128) - ), - - TP_fast_assign( - __assign_str(name, fctx->name) - pvr_context_value_str(fctx, __entry->val, - sizeof(__entry->val)); - ), - - TP_printk("name=%s val=%s", - __get_str(name), - __entry->val - ) -); - -DEFINE_EVENT(pvr_fence_context, pvr_fence_context_create, - TP_PROTO(struct pvr_fence_context *fctx), - TP_ARGS(fctx) -); - -DEFINE_EVENT(pvr_fence_context, pvr_fence_context_destroy, - TP_PROTO(struct pvr_fence_context *fctx), - TP_ARGS(fctx) -); - -DEFINE_EVENT(pvr_fence_context, pvr_fence_context_destroy_kref, - TP_PROTO(struct pvr_fence_context *fctx), - TP_ARGS(fctx) -); - -DEFINE_EVENT(pvr_fence_context, pvr_fence_context_signal_fences, - TP_PROTO(struct pvr_fence_context *fctx), - TP_ARGS(fctx) -); - -DECLARE_EVENT_CLASS(pvr_fence, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence), - - TP_STRUCT__entry( - __string(driver, - fence->base.ops->get_driver_name(&fence->base)) - __string(timeline, - fence->base.ops->get_timeline_name(&fence->base)) - __array(char, val, 128) - __field(u64, context) - ), - - TP_fast_assign( - __assign_str(driver, - fence->base.ops->get_driver_name(&fence->base)) - __assign_str(timeline, - fence->base.ops->get_timeline_name(&fence->base)) - fence->base.ops->fence_value_str(&fence->base, - __entry->val, sizeof(__entry->val)); - __entry->context = fence->base.context; - ), - - TP_printk("driver=%s timeline=%s ctx=%llu val=%s", - __get_str(driver), __get_str(timeline), - __entry->context, __entry->val - ) -); - -DEFINE_EVENT(pvr_fence, pvr_fence_create, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DEFINE_EVENT(pvr_fence, pvr_fence_release, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DEFINE_EVENT(pvr_fence, pvr_fence_enable_signaling, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DEFINE_EVENT(pvr_fence, pvr_fence_signal_fence, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DECLARE_EVENT_CLASS(pvr_fence_foreign, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence), - - TP_STRUCT__entry( - __string(driver, - fence->base.ops->get_driver_name(&fence->base)) - __string(timeline, - fence->base.ops->get_timeline_name(&fence->base)) - __array(char, val, 128) - __field(u64, context) - __string(foreign_driver, - fence->fence->ops->get_driver_name ? - fence->fence->ops->get_driver_name(fence->fence) : - "unknown") - __string(foreign_timeline, - fence->fence->ops->get_timeline_name ? - fence->fence->ops->get_timeline_name(fence->fence) : - "unknown") - __array(char, foreign_val, 128) - __field(u64, foreign_context) - ), - - TP_fast_assign( - __assign_str(driver, - fence->base.ops->get_driver_name(&fence->base)) - __assign_str(timeline, - fence->base.ops->get_timeline_name(&fence->base)) - fence->base.ops->fence_value_str(&fence->base, __entry->val, - sizeof(__entry->val)); - __entry->context = fence->base.context; - __assign_str(foreign_driver, - fence->fence->ops->get_driver_name ? - fence->fence->ops->get_driver_name(fence->fence) : - "unknown") - __assign_str(foreign_timeline, - fence->fence->ops->get_timeline_name ? - fence->fence->ops->get_timeline_name(fence->fence) : - "unknown") - fence->fence->ops->fence_value_str ? - fence->fence->ops->fence_value_str( - fence->fence, __entry->foreign_val, - sizeof(__entry->foreign_val)) : - (void) strlcpy(__entry->foreign_val, - "unknown", sizeof(__entry->foreign_val)); - __entry->foreign_context = fence->fence->context; - ), - - TP_printk("driver=%s timeline=%s ctx=%llu val=%s foreign: driver=%s timeline=%s ctx=%llu val=%s", - __get_str(driver), __get_str(timeline), __entry->context, - __entry->val, __get_str(foreign_driver), - __get_str(foreign_timeline), __entry->foreign_context, - __entry->foreign_val - ) -); - -DEFINE_EVENT(pvr_fence_foreign, pvr_fence_foreign_create, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DEFINE_EVENT(pvr_fence_foreign, pvr_fence_foreign_release, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -DEFINE_EVENT(pvr_fence_foreign, pvr_fence_foreign_signal, - TP_PROTO(struct pvr_fence *fence), - TP_ARGS(fence) -); - -#endif /* _TRACE_PVR_FENCE_H */ - -#undef TRACE_INCLUDE_PATH -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_PATH . - -/* This is needed because the name of this file doesn't match TRACE_SYSTEM. */ -#define TRACE_INCLUDE_FILE pvr_fence_trace - -/* This part must be outside protection */ -#include diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_gputrace.c b/drivers/gpu/drm/img-rogue/1.17/pvr_gputrace.c deleted file mode 100644 index 3e65aa3de4a7f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_gputrace.c +++ /dev/null @@ -1,1281 +0,0 @@ -/*************************************************************************/ /*! -@File pvr_gputrace.c -@Title PVR GPU Trace module Linux implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) -#include -#else -#include -#endif - -#include "pvrsrv_error.h" -#include "pvrsrv_apphint.h" -#include "pvr_debug.h" -#include "ospvr_gputrace.h" -#include "rgxhwperf.h" -#include "rgxtimecorr.h" -#include "device.h" -#include "trace_events.h" -#include "pvrsrv.h" -#include "pvrsrv_tlstreams.h" -#include "tlclient.h" -#include "pvr_debug.h" -#define CREATE_TRACE_POINTS -#include "rogue_trace_events.h" - -/****************************************************************************** - Module internal implementation -******************************************************************************/ - -typedef enum { - PVR_GPUTRACE_SWITCH_TYPE_UNDEF = 0, - - PVR_GPUTRACE_SWITCH_TYPE_BEGIN = 1, - PVR_GPUTRACE_SWITCH_TYPE_END = 2, - PVR_GPUTRACE_SWITCH_TYPE_SINGLE = 3 -} PVR_GPUTRACE_SWITCH_TYPE; - -typedef struct RGX_HWPERF_FTRACE_DATA { - /* This lock ensures the HWPerf TL stream reading resources are not destroyed - * by one thread disabling it while another is reading from it. Keeps the - * state and resource create/destroy atomic and consistent. */ - POS_LOCK hFTraceResourceLock; - - IMG_HANDLE hGPUTraceCmdCompleteHandle; - IMG_HANDLE hGPUTraceTLStream; - IMG_UINT64 ui64LastSampledTimeCorrOSTimeStamp; - IMG_UINT32 ui32FTraceLastOrdinal; -} RGX_HWPERF_FTRACE_DATA; - -/* This lock ensures state change of GPU_TRACING on/off is done atomically */ -static POS_LOCK ghGPUTraceStateLock; -static IMG_BOOL gbFTraceGPUEventsEnabled = PVRSRV_APPHINT_ENABLEFTRACEGPU; - -/* This lock ensures that the reference counting operation on the FTrace UFO - * events and enable/disable operation on firmware event are performed as - * one atomic operation. This should ensure that there are no race conditions - * between reference counting and firmware event state change. - * See below comment for guiUfoEventRef. - */ -static POS_LOCK ghLockFTraceEventLock; - -/* Multiple FTrace UFO events are reflected in the firmware as only one event. When - * we enable FTrace UFO event we want to also at the same time enable it in - * the firmware. Since there is a multiple-to-one relation between those events - * we count how many FTrace UFO events is enabled. If at least one event is - * enabled we enabled the firmware event. When all FTrace UFO events are disabled - * we disable firmware event. */ -static IMG_UINT guiUfoEventRef; - -/****************************************************************************** - Module In-bound API -******************************************************************************/ - -static PVRSRV_ERROR _GpuTraceDisable( - PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_BOOL bDeInit); - -static void _GpuTraceCmdCompleteNotify(PVRSRV_CMDCOMP_HANDLE); - -PVRSRV_ERROR PVRGpuTraceSupportInit(void) -{ - PVRSRV_ERROR eError; - - if (ghLockFTraceEventLock != NULL) - { - PVR_DPF((PVR_DBG_ERROR, "FTrace Support is already initialized")); - return PVRSRV_OK; - } - - /* common module params initialization */ - eError = OSLockCreate(&ghLockFTraceEventLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate"); - - eError = OSLockCreate(&ghGPUTraceStateLock); - PVR_LOG_RETURN_IF_ERROR (eError, "OSLockCreate"); - - return PVRSRV_OK; -} - -void PVRGpuTraceSupportDeInit(void) -{ - if (ghGPUTraceStateLock) - { - OSLockDestroy(ghGPUTraceStateLock); - } - - if (ghLockFTraceEventLock) - { - OSLockDestroy(ghLockFTraceEventLock); - ghLockFTraceEventLock = NULL; - } -} - -PVRSRV_ERROR PVRGpuTraceInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - RGX_HWPERF_FTRACE_DATA *psData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - psData = OSAllocZMem(sizeof(RGX_HWPERF_FTRACE_DATA)); - psDevInfo->pvGpuFtraceData = psData; - PVR_LOG_GOTO_IF_NOMEM(psData, eError, e0); - - /* We initialise it only once because we want to track if any - * packets were dropped. */ - psData->ui32FTraceLastOrdinal = IMG_UINT32_MAX - 1; - - eError = OSLockCreate(&psData->hFTraceResourceLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0); - - return PVRSRV_OK; - -e0: - PVRGpuTraceDeInitDevice(psDeviceNode); - return eError; -} - -void PVRGpuTraceDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_HWPERF_FTRACE_DATA *psData = psDevInfo->pvGpuFtraceData; - - PVRSRV_VZ_RETN_IF_MODE(GUEST); - if (psData) - { - /* first disable the tracing, to free up TL resources */ - if (psData->hFTraceResourceLock) - { - OSLockAcquire(psData->hFTraceResourceLock); - _GpuTraceDisable(psDeviceNode->pvDevice, IMG_TRUE); - OSLockRelease(psData->hFTraceResourceLock); - - /* now free all the FTrace resources */ - OSLockDestroy(psData->hFTraceResourceLock); - } - OSFreeMem(psData); - psDevInfo->pvGpuFtraceData = NULL; - } -} - -IMG_BOOL PVRGpuTraceIsEnabled(void) -{ - return gbFTraceGPUEventsEnabled; -} - -void PVRGpuTraceInitIfEnabled(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (PVRGpuTraceIsEnabled()) - { - PVRSRV_ERROR eError = PVRGpuTraceSetEnabled(psDeviceNode, IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to initialise GPU event tracing" - " (%s)", PVRSRVGetErrorString(eError))); - } - - /* below functions will enable FTrace events which in turn will - * execute HWPerf callbacks that set appropriate filter values - * note: unfortunately the functions don't allow to pass private - * data so they enable events for all of the devices - * at once, which means that this can happen more than once - * if there is more than one device */ - - /* single events can be enabled by calling trace_set_clr_event() - * with the event name, e.g.: - * trace_set_clr_event("rogue", "rogue_ufo_update", 1) */ -#if defined(CONFIG_EVENT_TRACING) /* this is a kernel config option */ -#if defined(ANDROID) || defined(CHROMIUMOS_KERNEL) - if (trace_set_clr_event("gpu", NULL, 1)) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to enable \"gpu\" event" - " group")); - } - else - { - PVR_LOG(("FTrace events from \"gpu\" group enabled")); - } -#endif /* defined(ANDROID) || defined(CHROMIUMOS_KERNEL) */ - if (trace_set_clr_event("rogue", NULL, 1)) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to enable \"rogue\" event" - " group")); - } - else - { - PVR_LOG(("FTrace events from \"rogue\" group enabled")); - } -#endif /* defined(CONFIG_EVENT_TRACING) */ - } -} - -/* Caller must now hold hFTraceResourceLock before calling this method. - */ -static PVRSRV_ERROR _GpuTraceEnable(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_HWPERF_FTRACE_DATA *psFtraceData; - PVRSRV_DEVICE_NODE *psRgxDevNode = psRgxDevInfo->psDeviceNode; - IMG_CHAR pszHWPerfStreamName[sizeof(PVRSRV_TL_HWPERF_RGX_FW_STREAM) + 5]; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psRgxDevInfo); - - psFtraceData = psRgxDevInfo->pvGpuFtraceData; - - PVR_ASSERT(OSLockIsLocked(psFtraceData->hFTraceResourceLock)); - - /* return if already enabled */ - if (psFtraceData->hGPUTraceTLStream) - { - return PVRSRV_OK; - } - -#if defined(SUPPORT_RGX) - /* Signal FW to enable event generation */ - if (psRgxDevInfo->bFirmwareInitialised) - { - IMG_UINT64 ui64UFOFilter = psRgxDevInfo->ui64HWPerfFilter & - (RGX_HWPERF_EVENT_MASK_FW_SED | RGX_HWPERF_EVENT_MASK_FW_UFO); - - /* Do not call into PVRSRVRGXCtrlHWPerfKM if we're in GUEST mode. */ - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = PVRSRV_OK; - } - else - { - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psRgxDevNode, - RGX_HWPERF_STREAM_ID0_FW, IMG_FALSE, - RGX_HWPERF_EVENT_MASK_HW_KICKFINISH | - ui64UFOFilter); - } - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM", err_out); - } - else -#endif - { - /* only set filter and exit */ - psRgxDevInfo->ui64HWPerfFilter = RGX_HWPERF_EVENT_MASK_HW_KICKFINISH | - ((RGX_HWPERF_EVENT_MASK_FW_SED | RGX_HWPERF_EVENT_MASK_FW_UFO) & - psRgxDevInfo->ui64HWPerfFilter); - - PVR_DPF((PVR_DBG_WARNING, - "HWPerfFW mask has been SET to (%" IMG_UINT64_FMTSPECx ")", - psRgxDevInfo->ui64HWPerfFilter)); - - return PVRSRV_OK; - } - - /* form the HWPerf stream name, corresponding to this DevNode; which can make sense in the UM */ - if (OSSNPrintf(pszHWPerfStreamName, sizeof(pszHWPerfStreamName), "%s%d", - PVRSRV_TL_HWPERF_RGX_FW_STREAM, psRgxDevNode->sDevId.i32OsDeviceID) < 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf stream name for device %d", - __func__, - psRgxDevNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Open the TL Stream for HWPerf data consumption */ - eError = TLClientOpenStream(DIRECT_BRIDGE_HANDLE, - pszHWPerfStreamName, - PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING, - &psFtraceData->hGPUTraceTLStream); - PVR_LOG_GOTO_IF_ERROR(eError, "TLClientOpenStream", err_out); - -#if defined(SUPPORT_RGX) - if (RGXTimeCorrGetClockSource(psRgxDevNode) != RGXTIMECORR_CLOCK_SCHED) - { - /* Set clock source for timer correlation data to sched_clock */ - psRgxDevInfo->ui32LastClockSource = RGXTimeCorrGetClockSource(psRgxDevNode); - RGXTimeCorrSetClockSource(psRgxDevNode, RGXTIMECORR_CLOCK_SCHED); - } -#endif - - /* Reset the OS timestamp coming from the timer correlation data - * associated with the latest HWPerf event we processed. - */ - psFtraceData->ui64LastSampledTimeCorrOSTimeStamp = 0; - - /* Register a notifier to collect HWPerf data whenever the HW completes - * an operation. - */ - eError = PVRSRVRegisterCmdCompleteNotify( - &psFtraceData->hGPUTraceCmdCompleteHandle, - &_GpuTraceCmdCompleteNotify, - psRgxDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVRegisterCmdCompleteNotify", err_close_stream); - -err_out: - PVR_DPF_RETURN_RC(eError); - -err_close_stream: - TLClientCloseStream(DIRECT_BRIDGE_HANDLE, - psFtraceData->hGPUTraceTLStream); - psFtraceData->hGPUTraceTLStream = NULL; - goto err_out; -} - -/* Caller must now hold hFTraceResourceLock before calling this method. - */ -static PVRSRV_ERROR _GpuTraceDisable(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_BOOL bDeInit) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_HWPERF_FTRACE_DATA *psFtraceData; -#if defined(SUPPORT_RGX) - PVRSRV_DEVICE_NODE *psRgxDevNode = psRgxDevInfo->psDeviceNode; -#endif - - PVR_DPF_ENTERED; - - PVR_ASSERT(psRgxDevInfo); - - psFtraceData = psRgxDevInfo->pvGpuFtraceData; - - PVR_ASSERT(OSLockIsLocked(psFtraceData->hFTraceResourceLock)); - - /* if FW is not yet initialised, just set filter and exit */ - if (!psRgxDevInfo->bFirmwareInitialised) - { - psRgxDevInfo->ui64HWPerfFilter = RGX_HWPERF_EVENT_MASK_NONE; -#if !defined(NO_HARDWARE) - PVR_DPF((PVR_DBG_WARNING, - "HWPerfFW mask has been SET to (%" IMG_UINT64_FMTSPECx ")", - psRgxDevInfo->ui64HWPerfFilter)); -#endif - return PVRSRV_OK; - } - - if (NULL == psFtraceData->hGPUTraceTLStream) - { - /* Tracing already disabled, just return */ - return PVRSRV_OK; - } - -#if defined(SUPPORT_RGX) - if (!bDeInit) - { - /* Do not call into PVRSRVRGXCtrlHWPerfKM if we are in GUEST mode. */ - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = PVRSRV_OK; - } - else - { - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psRgxDevNode, - RGX_HWPERF_STREAM_ID0_FW, IMG_FALSE, - (RGX_HWPERF_EVENT_MASK_NONE)); - } - PVR_LOG_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM"); - } -#endif - - if (psFtraceData->hGPUTraceCmdCompleteHandle) - { - /* Tracing is being turned off. Unregister the notifier. */ - eError = PVRSRVUnregisterCmdCompleteNotify( - psFtraceData->hGPUTraceCmdCompleteHandle); - PVR_LOG_IF_ERROR(eError, "PVRSRVUnregisterCmdCompleteNotify"); - psFtraceData->hGPUTraceCmdCompleteHandle = NULL; - } - - if (psFtraceData->hGPUTraceTLStream) - { - IMG_PBYTE pbTmp = NULL; - IMG_UINT32 ui32Tmp = 0; - - /* We have to flush both the L1 (FW) and L2 (Host) buffers in case there - * are some events left unprocessed in this FTrace/systrace "session" - * (note that even if we have just disabled HWPerf on the FW some packets - * could have been generated and already copied to L2 by the MISR handler). - * - * With the following calls we will both copy new data to the Host buffer - * (done by the producer callback in TLClientAcquireData) and advance - * the read offset in the buffer to catch up with the latest events. - */ - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - psFtraceData->hGPUTraceTLStream, - &pbTmp, &ui32Tmp); - PVR_LOG_IF_ERROR(eError, "TLClientCloseStream"); - - /* Let close stream perform the release data on the outstanding acquired data */ - eError = TLClientCloseStream(DIRECT_BRIDGE_HANDLE, - psFtraceData->hGPUTraceTLStream); - PVR_LOG_IF_ERROR(eError, "TLClientCloseStream"); - - psFtraceData->hGPUTraceTLStream = NULL; - } - -#if defined(SUPPORT_RGX) - if (psRgxDevInfo->ui32LastClockSource != RGXTIMECORR_CLOCK_SCHED) - { - RGXTimeCorrSetClockSource(psRgxDevNode, psRgxDevInfo->ui32LastClockSource); - } -#endif - - PVR_DPF_RETURN_RC(eError); -} - -static PVRSRV_ERROR _GpuTraceSetEnabled(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_BOOL bNewValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_HWPERF_FTRACE_DATA *psFtraceData; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - PVR_DPF_ENTERED; - - PVR_ASSERT(psRgxDevInfo); - psFtraceData = psRgxDevInfo->pvGpuFtraceData; - - /* About to create/destroy FTrace resources, lock critical section - * to avoid HWPerf MISR thread contention. - */ - OSLockAcquire(psFtraceData->hFTraceResourceLock); - - eError = (bNewValue ? _GpuTraceEnable(psRgxDevInfo) - : _GpuTraceDisable(psRgxDevInfo, IMG_FALSE)); - - OSLockRelease(psFtraceData->hFTraceResourceLock); - - PVR_DPF_RETURN_RC(eError); -} - -static PVRSRV_ERROR _GpuTraceSetEnabledForAllDevices(IMG_BOOL bNewValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - - /* enable/disable GPU trace on all devices */ - while (psDeviceNode) - { - eError = _GpuTraceSetEnabled(psDeviceNode->pvDevice, bNewValue); - if (eError != PVRSRV_OK) - { - break; - } - psDeviceNode = psDeviceNode->psNext; - } - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - PVR_DPF_RETURN_RC(eError); -} - -PVRSRV_ERROR PVRGpuTraceSetEnabled(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bNewValue) -{ - return _GpuTraceSetEnabled(psDeviceNode->pvDevice, bNewValue); -} - -/* ----- HWPerf to FTrace packet processing and events injection ------------ */ - -static const IMG_CHAR *_HWPerfKickTypeToStr(RGX_HWPERF_KICK_TYPE eKickType) -{ - static const IMG_CHAR *aszKickType[RGX_HWPERF_KICK_TYPE_LAST+1] = { -#if defined(RGX_FEATURE_HWPERF_VOLCANIC) - "TA3D", "CDM", "RS", "SHG", "TQTDM", "SYNC", "TA", "3D", "LAST" -#else - "TA3D", "TQ2D", "TQ3D", "CDM", "RS", "VRDM", "TQTDM", "SYNC", "TA", "3D", "LAST" -#endif - }; - - /* cast in case of negative value */ - if (((IMG_UINT32) eKickType) >= RGX_HWPERF_KICK_TYPE_LAST) - { - return ""; - } - - return aszKickType[eKickType]; -} - -void PVRGpuTraceEnqueueEvent( - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32FirmwareCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - RGX_HWPERF_KICK_TYPE eKickType) -{ - const IMG_CHAR *pszKickType = _HWPerfKickTypeToStr(eKickType); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRGpuTraceEnqueueEvent(%s): contextId %u, " - "jobId %u", pszKickType, ui32FirmwareCtx, ui32IntJobRef)); - - if (PVRGpuTraceIsEnabled()) - { - trace_rogue_job_enqueue(ui32FirmwareCtx, ui32IntJobRef, ui32ExtJobRef, - pszKickType); - } -} - -static void _GpuTraceWorkSwitch( - IMG_UINT64 ui64HWTimestampInOSTime, - IMG_UINT32 ui32CtxId, - IMG_UINT32 ui32CtxPriority, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - const IMG_CHAR* pszWorkType, - PVR_GPUTRACE_SWITCH_TYPE eSwType) -{ - PVR_ASSERT(pszWorkType); - trace_rogue_sched_switch(pszWorkType, eSwType, ui64HWTimestampInOSTime, - ui32CtxId, 2-ui32CtxPriority, ui32IntJobRef, ui32ExtJobRef); -} - -static void _GpuTraceUfo( - IMG_UINT64 ui64OSTimestamp, - const RGX_HWPERF_UFO_EV eEvType, - const IMG_UINT32 ui32CtxId, - const IMG_UINT32 ui32ExtJobRef, - const IMG_UINT32 ui32IntJobRef, - const IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ - switch (eEvType) { - case RGX_HWPERF_UFO_EV_UPDATE: - trace_rogue_ufo_updates(ui64OSTimestamp, ui32CtxId, - ui32ExtJobRef, ui32IntJobRef, ui32UFOCount, puData); - break; - case RGX_HWPERF_UFO_EV_CHECK_SUCCESS: - trace_rogue_ufo_checks_success(ui64OSTimestamp, ui32CtxId, - ui32ExtJobRef, ui32IntJobRef, IMG_FALSE, ui32UFOCount, - puData); - break; - case RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS: - trace_rogue_ufo_checks_success(ui64OSTimestamp, ui32CtxId, - ui32ExtJobRef, ui32IntJobRef, IMG_TRUE, ui32UFOCount, - puData); - break; - case RGX_HWPERF_UFO_EV_CHECK_FAIL: - trace_rogue_ufo_checks_fail(ui64OSTimestamp, ui32CtxId, - ui32ExtJobRef, ui32IntJobRef, IMG_FALSE, ui32UFOCount, - puData); - break; - case RGX_HWPERF_UFO_EV_PRCHECK_FAIL: - trace_rogue_ufo_checks_fail(ui64OSTimestamp, ui32CtxId, - ui32ExtJobRef, ui32IntJobRef, IMG_TRUE, ui32UFOCount, - puData); - break; - default: - break; - } -} - -static void _GpuTraceFirmware( - IMG_UINT64 ui64HWTimestampInOSTime, - const IMG_CHAR* pszWorkType, - PVR_GPUTRACE_SWITCH_TYPE eSwType) -{ - trace_rogue_firmware_activity(ui64HWTimestampInOSTime, pszWorkType, eSwType); -} - -static void _GpuTraceEventsLost( - const RGX_HWPERF_STREAM_ID eStreamId, - const IMG_UINT32 ui32LastOrdinal, - const IMG_UINT32 ui32CurrOrdinal) -{ - trace_rogue_events_lost(eStreamId, ui32LastOrdinal, ui32CurrOrdinal); -} - -/* Calculate the OS timestamp given an RGX timestamp in the HWPerf event. */ -static uint64_t CalculateEventTimestamp( - PVRSRV_RGXDEV_INFO *psDevInfo, - uint32_t ui32TimeCorrIndex, - uint64_t ui64EventTimestamp) -{ - RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb; - RGX_HWPERF_FTRACE_DATA *psFtraceData = psDevInfo->pvGpuFtraceData; - RGXFWIF_TIME_CORR *psTimeCorr = &psGpuUtilFWCB->sTimeCorr[ui32TimeCorrIndex]; - uint64_t ui64CRTimeStamp = psTimeCorr->ui64CRTimeStamp; - uint64_t ui64OSTimeStamp = psTimeCorr->ui64OSTimeStamp; - uint64_t ui64CRDeltaToOSDeltaKNs = psTimeCorr->ui64CRDeltaToOSDeltaKNs; - uint64_t ui64EventOSTimestamp, deltaRgxTimer, delta_ns; - - if (psFtraceData->ui64LastSampledTimeCorrOSTimeStamp > ui64OSTimeStamp) - { - /* The previous packet had a time reference (time correlation data) more - * recent than the one in the current packet, it means the timer - * correlation array wrapped too quickly (buffer too small) and in the - * previous call to _GpuTraceUfoEvent we read one of the - * newest timer correlations rather than one of the oldest ones. - */ - PVR_DPF((PVR_DBG_ERROR, "%s: The timestamps computed so far could be " - "wrong! The time correlation array size should be increased " - "to avoid this.", __func__)); - } - - psFtraceData->ui64LastSampledTimeCorrOSTimeStamp = ui64OSTimeStamp; - - /* RGX CR timer ticks delta */ - deltaRgxTimer = ui64EventTimestamp - ui64CRTimeStamp; - /* RGX time delta in nanoseconds */ - delta_ns = RGXFWIF_GET_DELTA_OSTIME_NS(deltaRgxTimer, ui64CRDeltaToOSDeltaKNs); - /* Calculate OS time of HWPerf event */ - ui64EventOSTimestamp = ui64OSTimeStamp + delta_ns; - - PVR_DPF((PVR_DBG_VERBOSE, "%s: psCurrentDvfs RGX %llu, OS %llu, DVFSCLK %u", - __func__, ui64CRTimeStamp, ui64OSTimeStamp, - psTimeCorr->ui32CoreClockSpeed)); - - return ui64EventOSTimestamp; -} - -static void _GpuTraceSwitchEvent(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt, const IMG_CHAR* pszWorkName, - PVR_GPUTRACE_SWITCH_TYPE eSwType) -{ - IMG_UINT64 ui64Timestamp; - RGX_HWPERF_HW_DATA* psHWPerfPktData; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psHWPerfPkt); - PVR_ASSERT(pszWorkName); - - psHWPerfPktData = RGX_HWPERF_GET_PACKET_DATA_BYTES(psHWPerfPkt); - - ui64Timestamp = CalculateEventTimestamp(psDevInfo, psHWPerfPktData->ui32TimeCorrIndex, - psHWPerfPkt->ui64Timestamp); - - PVR_DPF((PVR_DBG_VERBOSE, "_GpuTraceSwitchEvent: %s ui32ExtJobRef=%d, ui32IntJobRef=%d, eSwType=%d", - pszWorkName, psHWPerfPktData->ui32DMContext, psHWPerfPktData->ui32IntJobRef, eSwType)); - - _GpuTraceWorkSwitch(ui64Timestamp, - psHWPerfPktData->ui32DMContext, - psHWPerfPktData->ui32CtxPriority, - psHWPerfPktData->ui32ExtJobRef, - psHWPerfPktData->ui32IntJobRef, - pszWorkName, - eSwType); - - PVR_DPF_RETURN; -} - -static void _GpuTraceUfoEvent(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt) -{ - IMG_UINT64 ui64Timestamp; - RGX_HWPERF_UFO_DATA *psHWPerfPktData; - IMG_UINT32 ui32UFOCount; - RGX_HWPERF_UFO_DATA_ELEMENT *puData; - - psHWPerfPktData = RGX_HWPERF_GET_PACKET_DATA_BYTES(psHWPerfPkt); - - ui32UFOCount = RGX_HWPERF_GET_UFO_STREAMSIZE(psHWPerfPktData->ui32StreamInfo); - puData = (RGX_HWPERF_UFO_DATA_ELEMENT *) IMG_OFFSET_ADDR(psHWPerfPktData, RGX_HWPERF_GET_UFO_STREAMOFFSET(psHWPerfPktData->ui32StreamInfo)); - - ui64Timestamp = CalculateEventTimestamp(psDevInfo, psHWPerfPktData->ui32TimeCorrIndex, - psHWPerfPkt->ui64Timestamp); - - PVR_DPF((PVR_DBG_VERBOSE, "_GpuTraceUfoEvent: ui32ExtJobRef=%d, " - "ui32IntJobRef=%d", psHWPerfPktData->ui32ExtJobRef, - psHWPerfPktData->ui32IntJobRef)); - - _GpuTraceUfo(ui64Timestamp, psHWPerfPktData->eEvType, - psHWPerfPktData->ui32DMContext, psHWPerfPktData->ui32ExtJobRef, - psHWPerfPktData->ui32IntJobRef, ui32UFOCount, puData); -} - -static void _GpuTraceFirmwareEvent(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt, const IMG_CHAR* pszWorkName, - PVR_GPUTRACE_SWITCH_TYPE eSwType) - -{ - uint64_t ui64Timestamp; - RGX_HWPERF_FW_DATA *psHWPerfPktData = RGX_HWPERF_GET_PACKET_DATA_BYTES(psHWPerfPkt); - - ui64Timestamp = CalculateEventTimestamp(psDevInfo, psHWPerfPktData->ui32TimeCorrIndex, - psHWPerfPkt->ui64Timestamp); - - _GpuTraceFirmware(ui64Timestamp, pszWorkName, eSwType); -} - -static IMG_BOOL ValidAndEmitFTraceEvent(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt) -{ - RGX_HWPERF_EVENT_TYPE eType; - RGX_HWPERF_FTRACE_DATA *psFtraceData = psDevInfo->pvGpuFtraceData; - IMG_UINT32 ui32HwEventTypeIndex; - static const struct { - IMG_CHAR* pszName; - PVR_GPUTRACE_SWITCH_TYPE eSwType; - } aszHwEventTypeMap[] = { -#define _T(T) PVR_GPUTRACE_SWITCH_TYPE_##T - { "BG", _T(BEGIN) }, /* RGX_HWPERF_FW_BGSTART */ - { "BG", _T(END) }, /* RGX_HWPERF_FW_BGEND */ - { "IRQ", _T(BEGIN) }, /* RGX_HWPERF_FW_IRQSTART */ - { "IRQ", _T(END) }, /* RGX_HWPERF_FW_IRQEND */ - { "DBG", _T(BEGIN) }, /* RGX_HWPERF_FW_DBGSTART */ - { "DBG", _T(END) }, /* RGX_HWPERF_FW_DBGEND */ - { "PMOOM_TAPAUSE", _T(END) }, /* RGX_HWPERF_HW_PMOOM_TAPAUSE */ - { "TA", _T(BEGIN) }, /* RGX_HWPERF_HW_TAKICK */ - { "TA", _T(END) }, /* RGX_HWPERF_HW_TAFINISHED */ - { "TQ3D", _T(BEGIN) }, /* RGX_HWPERF_HW_3DTQKICK */ - { "3D", _T(BEGIN) }, /* RGX_HWPERF_HW_3DKICK */ - { "3D", _T(END) }, /* RGX_HWPERF_HW_3DFINISHED */ - { "CDM", _T(BEGIN) }, /* RGX_HWPERF_HW_CDMKICK */ - { "CDM", _T(END) }, /* RGX_HWPERF_HW_CDMFINISHED */ - { "TQ2D", _T(BEGIN) }, /* RGX_HWPERF_HW_TLAKICK */ - { "TQ2D", _T(END) }, /* RGX_HWPERF_HW_TLAFINISHED */ - { "3DSPM", _T(BEGIN) }, /* RGX_HWPERF_HW_3DSPMKICK */ - { NULL, 0 }, /* RGX_HWPERF_HW_PERIODIC (unsupported) */ - { "RTU", _T(BEGIN) }, /* RGX_HWPERF_HW_RTUKICK */ - { "RTU", _T(END) }, /* RGX_HWPERF_HW_RTUFINISHED */ - { "SHG", _T(BEGIN) }, /* RGX_HWPERF_HW_SHGKICK */ - { "SHG", _T(END) }, /* RGX_HWPERF_HW_SHGFINISHED */ - { "TQ3D", _T(END) }, /* RGX_HWPERF_HW_3DTQFINISHED */ - { "3DSPM", _T(END) }, /* RGX_HWPERF_HW_3DSPMFINISHED */ - { "PMOOM_TARESUME", _T(BEGIN) }, /* RGX_HWPERF_HW_PMOOM_TARESUME */ - { "TDM", _T(BEGIN) }, /* RGX_HWPERF_HW_TDMKICK */ - { "TDM", _T(END) }, /* RGX_HWPERF_HW_TDMFINISHED */ - { "NULL", _T(SINGLE) }, /* RGX_HWPERF_HW_NULLKICK */ -#undef _T - }; - static_assert(RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE == RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE + 1, - "FW and HW events are not contiguous in RGX_HWPERF_EVENT_TYPE"); - - PVR_ASSERT(psHWPerfPkt); - eType = RGX_HWPERF_GET_TYPE(psHWPerfPkt); - - if (psFtraceData->ui32FTraceLastOrdinal != psHWPerfPkt->ui32Ordinal - 1) - { - RGX_HWPERF_STREAM_ID eStreamId = RGX_HWPERF_GET_STREAM_ID(psHWPerfPkt); - _GpuTraceEventsLost(eStreamId, - psFtraceData->ui32FTraceLastOrdinal, - psHWPerfPkt->ui32Ordinal); - PVR_DPF((PVR_DBG_ERROR, "FTrace events lost (stream_id = %u, ordinal: last = %u, current = %u)", - eStreamId, psFtraceData->ui32FTraceLastOrdinal, psHWPerfPkt->ui32Ordinal)); - } - - psFtraceData->ui32FTraceLastOrdinal = psHWPerfPkt->ui32Ordinal; - - /* Process UFO packets */ - if (eType == RGX_HWPERF_UFO) - { - _GpuTraceUfoEvent(psDevInfo, psHWPerfPkt); - return IMG_TRUE; - } - - if (eType <= RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE) - { - /* this ID belongs to range 0, so index directly in range 0 */ - ui32HwEventTypeIndex = eType - RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE; - } - else - { - /* this ID belongs to range 1, so first index in range 1 and skip number of slots used up for range 0 */ - ui32HwEventTypeIndex = (eType - RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE) + - (RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE - RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE + 1); - } - - if (ui32HwEventTypeIndex >= ARRAY_SIZE(aszHwEventTypeMap)) - goto err_unsupported; - - if (aszHwEventTypeMap[ui32HwEventTypeIndex].pszName == NULL) - { - /* Not supported map entry, ignore event */ - goto err_unsupported; - } - - if (HWPERF_PACKET_IS_HW_TYPE(eType)) - { - if (aszHwEventTypeMap[ui32HwEventTypeIndex].eSwType == PVR_GPUTRACE_SWITCH_TYPE_SINGLE) - { - _GpuTraceSwitchEvent(psDevInfo, psHWPerfPkt, - aszHwEventTypeMap[ui32HwEventTypeIndex].pszName, - PVR_GPUTRACE_SWITCH_TYPE_BEGIN); - _GpuTraceSwitchEvent(psDevInfo, psHWPerfPkt, - aszHwEventTypeMap[ui32HwEventTypeIndex].pszName, - PVR_GPUTRACE_SWITCH_TYPE_END); - } - else - { - _GpuTraceSwitchEvent(psDevInfo, psHWPerfPkt, - aszHwEventTypeMap[ui32HwEventTypeIndex].pszName, - aszHwEventTypeMap[ui32HwEventTypeIndex].eSwType); - } - } - else if (HWPERF_PACKET_IS_FW_TYPE(eType)) - { - _GpuTraceFirmwareEvent(psDevInfo, psHWPerfPkt, - aszHwEventTypeMap[ui32HwEventTypeIndex].pszName, - aszHwEventTypeMap[ui32HwEventTypeIndex].eSwType); - } - else - { - goto err_unsupported; - } - - return IMG_TRUE; - -err_unsupported: - PVR_DPF((PVR_DBG_VERBOSE, "%s: Unsupported event type %d", __func__, eType)); - return IMG_FALSE; -} - - -static void _GpuTraceProcessPackets(PVRSRV_RGXDEV_INFO *psDevInfo, - void *pBuffer, IMG_UINT32 ui32ReadLen) -{ - IMG_UINT32 ui32TlPackets = 0; - IMG_UINT32 ui32HWPerfPackets = 0; - IMG_UINT32 ui32HWPerfPacketsSent = 0; - void *pBufferEnd; - PVRSRVTL_PPACKETHDR psHDRptr; - PVRSRVTL_PACKETTYPE ui16TlType; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psDevInfo); - PVR_ASSERT(pBuffer); - PVR_ASSERT(ui32ReadLen); - - /* Process the TL Packets - */ - pBufferEnd = IMG_OFFSET_ADDR(pBuffer, ui32ReadLen); - psHDRptr = GET_PACKET_HDR(pBuffer); - while ( psHDRptr < (PVRSRVTL_PPACKETHDR)pBufferEnd ) - { - ui16TlType = GET_PACKET_TYPE(psHDRptr); - if (ui16TlType == PVRSRVTL_PACKETTYPE_DATA) - { - IMG_UINT16 ui16DataLen = GET_PACKET_DATA_LEN(psHDRptr); - if (0 == ui16DataLen) - { - PVR_DPF((PVR_DBG_ERROR, "_GpuTraceProcessPackets: ZERO Data in TL data packet: %p", psHDRptr)); - } - else - { - RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt; - RGX_HWPERF_V2_PACKET_HDR* psHWPerfEnd; - - /* Check for lost hwperf data packets */ - psHWPerfEnd = RGX_HWPERF_GET_PACKET(GET_PACKET_DATA_PTR(psHDRptr)+ui16DataLen); - psHWPerfPkt = RGX_HWPERF_GET_PACKET(GET_PACKET_DATA_PTR(psHDRptr)); - do - { - if (ValidAndEmitFTraceEvent(psDevInfo, psHWPerfPkt)) - { - ui32HWPerfPacketsSent++; - } - ui32HWPerfPackets++; - psHWPerfPkt = RGX_HWPERF_GET_NEXT_PACKET(psHWPerfPkt); - } - while (psHWPerfPkt < psHWPerfEnd); - } - } - else if (ui16TlType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED) - { - PVR_DPF((PVR_DBG_MESSAGE, "_GpuTraceProcessPackets: Indication that the transport buffer was full")); - } - else - { - /* else Ignore padding packet type and others */ - PVR_DPF((PVR_DBG_MESSAGE, "_GpuTraceProcessPackets: Ignoring TL packet, type %d", ui16TlType )); - } - - psHDRptr = GET_NEXT_PACKET_ADDR(psHDRptr); - ui32TlPackets++; - } - - PVR_DPF((PVR_DBG_VERBOSE, "_GpuTraceProcessPackets: TL " - "Packets processed %03d, HWPerf packets %03d, sent %03d", - ui32TlPackets, ui32HWPerfPackets, ui32HWPerfPacketsSent)); - - PVR_DPF_RETURN; -} - - -static void _GpuTraceCmdCompleteNotify(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle) -{ - PVRSRV_RGXDEV_INFO* psDeviceInfo = hCmdCompHandle; - RGX_HWPERF_FTRACE_DATA* psFtraceData; - PVRSRV_ERROR eError; - IMG_PBYTE pBuffer; - IMG_UINT32 ui32ReadLen; - IMG_BOOL bFTraceLockAcquired = IMG_FALSE; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psDeviceInfo != NULL); - - psFtraceData = psDeviceInfo->pvGpuFtraceData; - - /* Command-complete notifiers can run concurrently. If this is - * happening, just bail out and let the previous call finish. - * This is ok because we can process the queued packets on the next call. - */ - bFTraceLockAcquired = OSTryLockAcquire(psFtraceData->hFTraceResourceLock); - if (IMG_FALSE == bFTraceLockAcquired) - { - PVR_DPF_RETURN; - } - - /* If this notifier is called, it means the TL resources will be valid at-least - * until the end of this call, since the DeInit function will wait on the hFTraceResourceLock - * to clean-up the TL resources and un-register the notifier, so just assert here. - */ - PVR_ASSERT(psFtraceData->hGPUTraceTLStream); - - /* If we have a valid stream attempt to acquire some data */ - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, psFtraceData->hGPUTraceTLStream, &pBuffer, &ui32ReadLen); - if (eError == PVRSRV_OK) - { - /* Process the HWPerf packets and release the data */ - if (ui32ReadLen > 0) - { - PVR_DPF((PVR_DBG_VERBOSE, "_GpuTraceCmdCompleteNotify: DATA AVAILABLE offset=%p, length=%d", pBuffer, ui32ReadLen)); - - /* Process the transport layer data for HWPerf packets... */ - _GpuTraceProcessPackets(psDeviceInfo, pBuffer, ui32ReadLen); - - eError = TLClientReleaseData(DIRECT_BRIDGE_HANDLE, psFtraceData->hGPUTraceTLStream); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "TLClientReleaseData"); - - /* Serious error, disable FTrace GPU events */ - - /* Release TraceLock so we always have the locking - * order BridgeLock->TraceLock to prevent AB-BA deadlocks*/ - OSLockRelease(psFtraceData->hFTraceResourceLock); - OSLockAcquire(psFtraceData->hFTraceResourceLock); - _GpuTraceDisable(psDeviceInfo, IMG_FALSE); - OSLockRelease(psFtraceData->hFTraceResourceLock); - goto out; - - } - } /* else no data, ignore */ - } - else if (eError != PVRSRV_ERROR_TIMEOUT) - { - PVR_LOG_ERROR(eError, "TLClientAcquireData"); - } - if (bFTraceLockAcquired) - { - OSLockRelease(psFtraceData->hFTraceResourceLock); - } -out: - PVR_DPF_RETURN; -} - -/* ----- AppHint interface -------------------------------------------------- */ - -static PVRSRV_ERROR _GpuTraceIsEnabledCallback( - const PVRSRV_DEVICE_NODE *device, - const void *private_data, - IMG_BOOL *value) -{ - PVR_UNREFERENCED_PARAMETER(device); - PVR_UNREFERENCED_PARAMETER(private_data); - - *value = gbFTraceGPUEventsEnabled; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _GpuTraceSetEnabledCallback( - const PVRSRV_DEVICE_NODE *device, - const void *private_data, - IMG_BOOL value) -{ - PVR_UNREFERENCED_PARAMETER(device); - - /* Lock down the state to avoid concurrent writes */ - OSLockAcquire(ghGPUTraceStateLock); - - if (value != gbFTraceGPUEventsEnabled) - { - PVRSRV_ERROR eError; - if ((eError = _GpuTraceSetEnabledForAllDevices(value)) == PVRSRV_OK) - { - PVR_TRACE(("%s GPU FTrace", value ? "ENABLED" : "DISABLED")); - gbFTraceGPUEventsEnabled = value; - } - else - { - PVR_TRACE(("FAILED to %s GPU FTrace", value ? "enable" : "disable")); - /* On failure, partial enable/disable might have resulted. - * Try best to restore to previous state. Ignore error */ - _GpuTraceSetEnabledForAllDevices(gbFTraceGPUEventsEnabled); - - OSLockRelease(ghGPUTraceStateLock); - return eError; - } - } - else - { - PVR_TRACE(("GPU FTrace already %s!", value ? "enabled" : "disabled")); - } - - OSLockRelease(ghGPUTraceStateLock); - - return PVRSRV_OK; -} - -void PVRGpuTraceInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_EnableFTraceGPU, - _GpuTraceIsEnabledCallback, - _GpuTraceSetEnabledCallback, - psDeviceNode, NULL); -} - -/* ----- FTrace event callbacks -------------------------------------------- */ - -void PVRGpuTraceEnableUfoCallback(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psRgxDevInfo; - PVRSRV_ERROR eError; -#endif - - /* Lock down events state, for consistent value of guiUfoEventRef */ - OSLockAcquire(ghLockFTraceEventLock); - if (guiUfoEventRef++ == 0) - { - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - - /* make sure UFO events are enabled on all rogue devices */ - while (psDeviceNode) - { -#if defined(SUPPORT_RGX) - IMG_UINT64 ui64Filter; - - psRgxDevInfo = psDeviceNode->pvDevice; - ui64Filter = RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_UFO) | - psRgxDevInfo->ui64HWPerfFilter; - /* Small chance exists that ui64HWPerfFilter can be changed here and - * the newest filter value will be changed to the old one + UFO event. - * This is not a critical problem. */ - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psDeviceNode, RGX_HWPERF_STREAM_ID0_FW, - IMG_FALSE, ui64Filter); - if (eError == PVRSRV_ERROR_NOT_INITIALISED) - { - /* If we land here that means that the FW is not initialised yet. - * We stored the filter and it will be passed to the firmware - * during its initialisation phase. So ignore. */ - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Could not enable UFO HWPerf events on device %d", psDeviceNode->sDevId.i32OsDeviceID)); - } -#endif - psDeviceNode = psDeviceNode->psNext; - } - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - } - OSLockRelease(ghLockFTraceEventLock); -} - -void PVRGpuTraceDisableUfoCallback(void) -{ -#if defined(SUPPORT_RGX) - PVRSRV_ERROR eError; -#endif - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; - - /* We have to check if lock is valid because on driver unload - * PVRGpuTraceSupportDeInit is called before kernel disables the ftrace - * events. This means that the lock will be destroyed before this callback - * is called. - * We can safely return if that situation happens because driver will be - * unloaded so we don't care about HWPerf state anymore. */ - if (ghLockFTraceEventLock == NULL) - return; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - - /* Lock down events state, for consistent value of guiUfoEventRef */ - OSLockAcquire(ghLockFTraceEventLock); - if (--guiUfoEventRef == 0) - { - /* make sure UFO events are disabled on all rogue devices */ - while (psDeviceNode) - { -#if defined(SUPPORT_RGX) - IMG_UINT64 ui64Filter; - PVRSRV_RGXDEV_INFO *psRgxDevInfo = psDeviceNode->pvDevice; - - ui64Filter = ~(RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_UFO)) & - psRgxDevInfo->ui64HWPerfFilter; - /* Small chance exists that ui64HWPerfFilter can be changed here and - * the newest filter value will be changed to the old one + UFO event. - * This is not a critical problem. */ - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psDeviceNode, RGX_HWPERF_STREAM_ID0_FW, - IMG_FALSE, ui64Filter); - if (eError == PVRSRV_ERROR_NOT_INITIALISED) - { - /* If we land here that means that the FW is not initialised yet. - * We stored the filter and it will be passed to the firmware - * during its initialisation phase. So ignore. */ - } - else if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Could not disable UFO HWPerf events on device %d", - psDeviceNode->sDevId.i32OsDeviceID)); - } -#endif - - psDeviceNode = psDeviceNode->psNext; - } - } - OSLockRelease(ghLockFTraceEventLock); - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); -} - -void PVRGpuTraceEnableFirmwareActivityCallback(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psRgxDevInfo; - uint64_t ui64Filter, ui64FWEventsFilter = 0; - int i; - - for (i = RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE; - i <= RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE; i++) - { - ui64FWEventsFilter |= RGX_HWPERF_EVENT_MASK_VALUE(i); - } -#endif - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - - OSLockAcquire(ghLockFTraceEventLock); - /* Enable all FW events on all the devices */ - while (psDeviceNode) - { -#if defined(SUPPORT_RGX) - PVRSRV_ERROR eError; - psRgxDevInfo = psDeviceNode->pvDevice; - ui64Filter = psRgxDevInfo->ui64HWPerfFilter | ui64FWEventsFilter; - - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psDeviceNode, RGX_HWPERF_STREAM_ID0_FW, - IMG_FALSE, ui64Filter); - if ((eError != PVRSRV_OK) && !PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_ERROR, "Could not enable HWPerf event for firmware" - " task timings (%s).", PVRSRVGetErrorString(eError))); - } -#endif - psDeviceNode = psDeviceNode->psNext; - } - OSLockRelease(ghLockFTraceEventLock); - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); -} - -void PVRGpuTraceDisableFirmwareActivityCallback(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; -#if defined(SUPPORT_RGX) - IMG_UINT64 ui64FWEventsFilter = ~0; - int i; -#endif - - /* We have to check if lock is valid because on driver unload - * PVRGpuTraceSupportDeInit is called before kernel disables the ftrace - * events. This means that the lock will be destroyed before this callback - * is called. - * We can safely return if that situation happens because driver will be - * unloaded so we don't care about HWPerf state anymore. */ - if (ghLockFTraceEventLock == NULL) - return; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - -#if defined(SUPPORT_RGX) - for (i = RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE; - i <= RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE; i++) - { - ui64FWEventsFilter &= ~RGX_HWPERF_EVENT_MASK_VALUE(i); - } -#endif - - OSLockAcquire(ghLockFTraceEventLock); - - /* Disable all FW events on all the devices */ - while (psDeviceNode) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psRgxDevInfo = psDeviceNode->pvDevice; - IMG_UINT64 ui64Filter = psRgxDevInfo->ui64HWPerfFilter & ui64FWEventsFilter; - - if ((PVRSRVRGXCtrlHWPerfKM(NULL, psDeviceNode, RGX_HWPERF_STREAM_ID0_FW, - IMG_FALSE, ui64Filter) != PVRSRV_OK) && - !PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_ERROR, "Could not disable HWPerf event for firmware task timings.")); - } -#endif - psDeviceNode = psDeviceNode->psNext; - } - - OSLockRelease(ghLockFTraceEventLock); - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); -} - -/****************************************************************************** - End of file (pvr_gputrace.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_intrinsics.h b/drivers/gpu/drm/img-rogue/1.17/pvr_intrinsics.h deleted file mode 100644 index 410a2f5a50b57..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_intrinsics.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Intrinsics definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_INTRINSICS_H -#define PVR_INTRINSICS_H - -/* PVR_CTZLL: - * Count the number of trailing zeroes in a long long integer - */ - -#if defined(__GNUC__) -#if defined(__x86_64__) - - #define PVR_CTZLL __builtin_ctzll -#endif -#endif - -/* PVR_CLZLL: - * Count the number of leading zeroes in a long long integer - */ - -#if defined(__GNUC__) -#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \ - defined(__arm__) || defined(__mips) - -#define PVR_CLZLL __builtin_clzll - -#endif -#endif - -#endif /* PVR_INTRINSICS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_ion_stats.h b/drivers/gpu/drm/img-rogue/1.17/pvr_ion_stats.h deleted file mode 100644 index c341807854530..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_ion_stats.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Functions for recording ION memory stats. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_ION_STATS_H -#define PVR_ION_STATS_H - -#include "pvrsrv_error.h" -#include "img_defs.h" - -struct dma_buf; - -#if defined(PVRSRV_ENABLE_PVR_ION_STATS) -PVRSRV_ERROR PVRSRVIonStatsInitialise(void); - -void PVRSRVIonStatsDestroy(void); - -void PVRSRVIonAddMemAllocRecord(struct dma_buf *psDmaBuf); - -void PVRSRVIonRemoveMemAllocRecord(struct dma_buf *psDmaBuf); -#else -static INLINE PVRSRV_ERROR PVRSRVIonStatsInitialise(void) -{ - return PVRSRV_OK; -} - -static INLINE void PVRSRVIonStatsDestroy(void) -{ -} - -static INLINE void PVRSRVIonAddMemAllocRecord(struct dma_buf *psDmaBuf) -{ - PVR_UNREFERENCED_PARAMETER(psDmaBuf); -} - -static INLINE void PVRSRVIonRemoveMemAllocRecord(struct dma_buf *psDmaBuf) -{ - PVR_UNREFERENCED_PARAMETER(psDmaBuf); -} -#endif /* defined(PVRSRV_ENABLE_PVR_ION_STATS) */ - -#endif /* PVR_ION_STATS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_linux_fence.h b/drivers/gpu/drm/img-rogue/1.17/pvr_linux_fence.h deleted file mode 100644 index b9c542a26a656..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_linux_fence.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * @File - * @Title PowerVR Linux fence compatibility header - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ - -#if !defined(__PVR_LINUX_FENCE_H__) -#define __PVR_LINUX_FENCE_H__ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) && \ - !defined(CHROMIUMOS_KERNEL_HAS_DMA_FENCE) -#include -#else -#include -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) && \ - !defined(CHROMIUMOS_KERNEL_HAS_DMA_FENCE) -/* Structures */ -#define dma_fence fence -#define dma_fence_array fence_array -#define dma_fence_cb fence_cb -#define dma_fence_ops fence_ops - -/* Defines and Enums */ -#define DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT FENCE_FLAG_ENABLE_SIGNAL_BIT -#define DMA_FENCE_FLAG_SIGNALED_BIT FENCE_FLAG_SIGNALED_BIT -#define DMA_FENCE_FLAG_USER_BITS FENCE_FLAG_USER_BITS - -#define DMA_FENCE_ERR FENCE_ERR -#define DMA_FENCE_TRACE FENCE_TRACE -#define DMA_FENCE_WARN FENCE_WARN - -/* Functions */ -#define dma_fence_add_callback fence_add_callback -#define dma_fence_context_alloc fence_context_alloc -#define dma_fence_default_wait fence_default_wait -#define dma_fence_is_signaled fence_is_signaled -#define dma_fence_enable_sw_signaling fence_enable_sw_signaling -#define dma_fence_free fence_free -#define dma_fence_get fence_get -#define dma_fence_get_rcu fence_get_rcu -#define dma_fence_init fence_init -#define dma_fence_is_array fence_is_array -#define dma_fence_put fence_put -#define dma_fence_signal fence_signal -#define dma_fence_wait fence_wait -#define to_dma_fence_array to_fence_array - -static inline signed long -dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout) -{ - signed long lret; - - lret = fence_wait_timeout(fence, intr, timeout); - if (lret || timeout) - return lret; - - return test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) ? 1 : 0; -} - -#endif - -#endif /* !defined(__PVR_LINUX_FENCE_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.c b/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.c deleted file mode 100644 index 583d4c517d2ca..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.c +++ /dev/null @@ -1,647 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PowerVR notifier interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "allocmem.h" -#include "dllist.h" - -#include "device.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "pvrversion.h" -#include "connection_server.h" - -#include "osfunc.h" -#include "sofunc_pvr.h" - -#define PVR_DUMP_DRIVER_INFO(x, y) \ - PVR_DUMPDEBUG_LOG("%s info: %d.%d @ %8d (%s) build options: 0x%08x", \ - (x), \ - PVRVERSION_UNPACK_MAJ((y).ui32BuildVersion), \ - PVRVERSION_UNPACK_MIN((y).ui32BuildVersion), \ - (y).ui32BuildRevision, \ - (BUILD_TYPE_DEBUG == (y).ui32BuildType) ? "debug":"release", \ - (y).ui32BuildOptions); - -#if !defined(WINDOW_SYSTEM) -#define WINDOW_SYSTEM "Unknown" -#endif - -#define IS_DECLARED(x) (x[0] != '\0') - -/*************************************************************************/ /*! -Command Complete Notifier Interface -*/ /**************************************************************************/ - -typedef struct PVRSRV_CMDCOMP_NOTIFY_TAG -{ - PVRSRV_CMDCOMP_HANDLE hCmdCompHandle; - PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify; - DLLIST_NODE sListNode; -} PVRSRV_CMDCOMP_NOTIFY; - -/* Head of the list of callbacks called when command complete happens */ -static DLLIST_NODE g_sCmdCompNotifyHead; -static POSWR_LOCK g_hCmdCompNotifyLock; - -PVRSRV_ERROR -PVRSRVCmdCompleteInit(void) -{ - PVRSRV_ERROR eError; - - eError = OSWRLockCreate(&g_hCmdCompNotifyLock); - PVR_RETURN_IF_ERROR(eError); - - dllist_init(&g_sCmdCompNotifyHead); - - return PVRSRV_OK; -} - -void -PVRSRVCmdCompleteDeinit(void) -{ - /* Check that all notify function have been unregistered */ - if (!dllist_is_empty(&g_sCmdCompNotifyHead)) - { - PDLLIST_NODE psNode; - - PVR_DPF((PVR_DBG_ERROR, - "%s: Command complete notify list is not empty!", __func__)); - - /* Clean up any stragglers */ - psNode = dllist_get_next_node(&g_sCmdCompNotifyHead); - while (psNode) - { - PVRSRV_CMDCOMP_NOTIFY *psNotify; - - dllist_remove_node(psNode); - - psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode); - OSFreeMem(psNotify); - - psNode = dllist_get_next_node(&g_sCmdCompNotifyHead); - } - } - - if (g_hCmdCompNotifyLock) - { - OSWRLockDestroy(g_hCmdCompNotifyLock); - } -} - -PVRSRV_ERROR -PVRSRVRegisterCmdCompleteNotify(IMG_HANDLE *phNotify, - PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, - PVRSRV_CMDCOMP_HANDLE hCmdCompHandle) -{ - PVRSRV_CMDCOMP_NOTIFY *psNotify; - - PVR_LOG_RETURN_IF_INVALID_PARAM(phNotify, "phNotify"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pfnCmdCompleteNotify, "pfnCmdCompleteNotify"); - PVR_LOG_RETURN_IF_INVALID_PARAM(hCmdCompHandle, "hCmdCompHandle"); - - psNotify = OSAllocMem(sizeof(*psNotify)); - PVR_LOG_RETURN_IF_NOMEM(psNotify, "psNotify"); - - /* Set-up the notify data */ - psNotify->hCmdCompHandle = hCmdCompHandle; - psNotify->pfnCmdCompleteNotify = pfnCmdCompleteNotify; - - /* Add it to the list of Notify functions */ - OSWRLockAcquireWrite(g_hCmdCompNotifyLock); - dllist_add_to_tail(&g_sCmdCompNotifyHead, &psNotify->sListNode); - OSWRLockReleaseWrite(g_hCmdCompNotifyLock); - - *phNotify = psNotify; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVUnregisterCmdCompleteNotify(IMG_HANDLE hNotify) -{ - PVRSRV_CMDCOMP_NOTIFY *psNotify; - - psNotify = (PVRSRV_CMDCOMP_NOTIFY *) hNotify; - PVR_LOG_RETURN_IF_INVALID_PARAM(psNotify, "hNotify"); - - OSWRLockAcquireWrite(g_hCmdCompNotifyLock); - dllist_remove_node(&psNotify->sListNode); - OSWRLockReleaseWrite(g_hCmdCompNotifyLock); - - OSFreeMem(psNotify); - - return PVRSRV_OK; -} - -void -PVRSRVNotifyCommandCompletion(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle) -{ -#if !defined(NO_HARDWARE) - DLLIST_NODE *psNode, *psNext; - - /* Call notify callbacks to check if blocked work items can now proceed */ - OSWRLockAcquireRead(g_hCmdCompNotifyLock); - dllist_foreach_node(&g_sCmdCompNotifyHead, psNode, psNext) - { - PVRSRV_CMDCOMP_NOTIFY *psNotify = - IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode); - - if (hCmdCompCallerHandle != psNotify->hCmdCompHandle) - { - psNotify->pfnCmdCompleteNotify(psNotify->hCmdCompHandle); - } - } - OSWRLockReleaseRead(g_hCmdCompNotifyLock); -#endif -} - -inline void -PVRSRVSignalGlobalEO(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - if (psPVRSRVData->hGlobalEventObject) - { - OSEventObjectSignal(psPVRSRVData->hGlobalEventObject); - } -} - -inline void -PVRSRVCheckStatus(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle) -{ - PVRSRVNotifyCommandCompletion(hCmdCompCallerHandle); - PVRSRVSignalGlobalEO(); -} - -/*************************************************************************/ /*! -Debug Notifier Interface -*/ /**************************************************************************/ - -/* Lockdep sees both locks as the same class due to same struct used thus warns - * about a possible deadlock (false positive), - * using nested api we can supply separate Class' - * */ -#define DN_LOCKCLASS_DRIVER 0 -#define DN_LOCKCLASS_DEVICE 1 - -typedef struct DEBUG_REQUEST_ENTRY_TAG -{ - IMG_UINT32 ui32RequesterID; - DLLIST_NODE sListHead; -} DEBUG_REQUEST_ENTRY; - -typedef struct DEBUG_REQUEST_TABLE_TAG -{ - POSWR_LOCK hLock; - DEBUG_REQUEST_ENTRY asEntry[1]; -} DEBUG_REQUEST_TABLE; - -typedef struct DEBUG_REQUEST_NOTIFY_TAG -{ - IMG_HANDLE hDebugTable; - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle; - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify; - IMG_UINT32 ui32RequesterID; - DLLIST_NODE sListNode; -} DEBUG_REQUEST_NOTIFY; - -static DEBUG_REQUEST_TABLE *g_psDriverDebugTable; - -static const IMG_UINT32 g_aui32DebugOrderTable[] = { - DEBUG_REQUEST_SRV, - DEBUG_REQUEST_RGX, - DEBUG_REQUEST_SYS, - DEBUG_REQUEST_APPHINT, - DEBUG_REQUEST_HTB, - DEBUG_REQUEST_DC, - DEBUG_REQUEST_SYNCCHECKPOINT, - DEBUG_REQUEST_SYNCTRACKING, - DEBUG_REQUEST_ANDROIDSYNC, - DEBUG_REQUEST_FALLBACKSYNC, - DEBUG_REQUEST_LINUXFENCE -}; -static const IMG_UINT32 g_ui32DebugOrderTableReqCount = ARRAY_SIZE(g_aui32DebugOrderTable); - -static PVRSRV_ERROR -_RegisterDebugTableI(DEBUG_REQUEST_TABLE **ppsDebugTable) -{ - DEBUG_REQUEST_TABLE *psDebugTable; - IMG_UINT32 i; - PVRSRV_ERROR eError; - - if (*ppsDebugTable) - { - return PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED; - } - - psDebugTable = OSAllocMem(sizeof(DEBUG_REQUEST_TABLE) + - (sizeof(DEBUG_REQUEST_ENTRY) * (g_ui32DebugOrderTableReqCount-1))); - PVR_RETURN_IF_NOMEM(psDebugTable); - - eError = OSWRLockCreate(&psDebugTable->hLock); - PVR_GOTO_IF_ERROR(eError, ErrorFreeDebugTable); - - /* Init the list heads */ - for (i = 0; i < g_ui32DebugOrderTableReqCount; i++) - { - psDebugTable->asEntry[i].ui32RequesterID = g_aui32DebugOrderTable[i]; - dllist_init(&psDebugTable->asEntry[i].sListHead); - } - - *ppsDebugTable = psDebugTable; - - return PVRSRV_OK; - -ErrorFreeDebugTable: - OSFreeMem(psDebugTable); - - return eError; -} - -PVRSRV_ERROR -PVRSRVRegisterDeviceDbgTable(PVRSRV_DEVICE_NODE *psDevNode) -{ - return _RegisterDebugTableI((DEBUG_REQUEST_TABLE**)&psDevNode->hDebugTable); -} - -PVRSRV_ERROR -PVRSRVRegisterDriverDbgTable(void) -{ - return _RegisterDebugTableI(&g_psDriverDebugTable); -} - -static void _UnregisterDbgTableI(DEBUG_REQUEST_TABLE **ppsDebugTable) -{ - DEBUG_REQUEST_TABLE *psDebugTable; - IMG_UINT32 i; - - PVR_ASSERT(*ppsDebugTable); - psDebugTable = *ppsDebugTable; - *ppsDebugTable = NULL; - - for (i = 0; i < g_ui32DebugOrderTableReqCount; i++) - { - if (!dllist_is_empty(&psDebugTable->asEntry[i].sListHead)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Found registered callback(s) on %d", - __func__, i)); - } - } - - OSWRLockDestroy(psDebugTable->hLock); - psDebugTable->hLock = NULL; - - OSFreeMem(psDebugTable); -} - -void -PVRSRVUnregisterDeviceDbgTable(PVRSRV_DEVICE_NODE *psDevNode) -{ - _UnregisterDbgTableI((DEBUG_REQUEST_TABLE**)&psDevNode->hDebugTable); - PVR_ASSERT(!psDevNode->hDebugTable); -} - -void -PVRSRVUnregisterDriverDbgTable(void) -{ - _UnregisterDbgTableI(&g_psDriverDebugTable); - PVR_ASSERT(!g_psDriverDebugTable); -} - -static PVRSRV_ERROR -_RegisterDbgRequestNotifyI(IMG_HANDLE *phNotify, - DEBUG_REQUEST_TABLE *psDebugTable, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle) -{ - DEBUG_REQUEST_NOTIFY *psNotify; - PDLLIST_NODE psHead = NULL; - IMG_UINT32 i; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_INVALID_PARAM(phNotify, "phNotify"); - PVR_LOG_RETURN_IF_INVALID_PARAM(psDebugTable, "psDebugTable"); - PVR_LOG_RETURN_IF_INVALID_PARAM(pfnDbgRequestNotify, "pfnDbRequestNotify"); - - /* NoStats used since this may be called outside of the register/de-register - * process calls which track memory use. */ - psNotify = OSAllocMemNoStats(sizeof(*psNotify)); - PVR_LOG_RETURN_IF_NOMEM(psNotify, "psNotify"); - - /* Set-up the notify data */ - psNotify->hDebugTable = psDebugTable; - psNotify->hDbgRequestHandle = hDbgRequestHandle; - psNotify->pfnDbgRequestNotify = pfnDbgRequestNotify; - psNotify->ui32RequesterID = ui32RequesterID; - - /* Lock down all the lists */ - OSWRLockAcquireWrite(psDebugTable->hLock); - - /* Find which list to add it to */ - for (i = 0; i < g_ui32DebugOrderTableReqCount; i++) - { - if (psDebugTable->asEntry[i].ui32RequesterID == ui32RequesterID) - { - psHead = &psDebugTable->asEntry[i].sListHead; - } - } - - /* Failed to find debug requester */ - PVR_LOG_GOTO_IF_INVALID_PARAM(psHead, eError, ErrorReleaseLock); - - /* Add it to the list of Notify functions */ - dllist_add_to_tail(psHead, &psNotify->sListNode); - - /* Unlock the lists */ - OSWRLockReleaseWrite(psDebugTable->hLock); - - *phNotify = psNotify; - - return PVRSRV_OK; - -ErrorReleaseLock: - OSWRLockReleaseWrite(psDebugTable->hLock); - OSFreeMem(psNotify); - - return eError; -} - -PVRSRV_ERROR -PVRSRVRegisterDeviceDbgRequestNotify(IMG_HANDLE *phNotify, - PVRSRV_DEVICE_NODE *psDevNode, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle) -{ - PVR_LOG_RETURN_IF_INVALID_PARAM(psDevNode, "psDevNode"); - if (!psDevNode->hDebugTable) - { - PVR_DPF((PVR_DBG_ERROR, "%s: psDevNode->hDebugTable not yet initialised!", - __func__)); - return PVRSRV_ERROR_NOT_INITIALISED; - } - - return _RegisterDbgRequestNotifyI(phNotify, - (DEBUG_REQUEST_TABLE *)psDevNode->hDebugTable, - pfnDbgRequestNotify, - ui32RequesterID, - hDbgRequestHandle); -} - -PVRSRV_ERROR -PVRSRVRegisterDriverDbgRequestNotify(IMG_HANDLE *phNotify, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle) -{ - if (!g_psDriverDebugTable) - { - PVR_DPF((PVR_DBG_ERROR, "%s: g_psDriverDebugTable not yet initialised!", - __func__)); - return PVRSRV_ERROR_NOT_INITIALISED; - } - - return _RegisterDbgRequestNotifyI(phNotify, - g_psDriverDebugTable, - pfnDbgRequestNotify, - ui32RequesterID, - hDbgRequestHandle); -} - -PVRSRV_ERROR -SOPvrDbgRequestNotifyRegister(IMG_HANDLE *phNotify, - PVRSRV_DEVICE_NODE *psDevNode, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle) -{ - return PVRSRVRegisterDeviceDbgRequestNotify(phNotify, - psDevNode, - pfnDbgRequestNotify, - ui32RequesterID, - hDbgRequestHandle); -} - -static PVRSRV_ERROR -_UnregisterDbgRequestNotify(IMG_HANDLE hNotify) -{ - DEBUG_REQUEST_NOTIFY *psNotify = (DEBUG_REQUEST_NOTIFY *) hNotify; - DEBUG_REQUEST_TABLE *psDebugTable; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psNotify, "psNotify"); - - psDebugTable = (DEBUG_REQUEST_TABLE *) psNotify->hDebugTable; - - OSWRLockAcquireWrite(psDebugTable->hLock); - dllist_remove_node(&psNotify->sListNode); - OSWRLockReleaseWrite(psDebugTable->hLock); - - OSFreeMemNoStats(psNotify); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVUnregisterDeviceDbgRequestNotify(IMG_HANDLE hNotify) -{ - return _UnregisterDbgRequestNotify(hNotify); -} - -PVRSRV_ERROR -PVRSRVUnregisterDriverDbgRequestNotify(IMG_HANDLE hNotify) -{ - return _UnregisterDbgRequestNotify(hNotify); -} - -PVRSRV_ERROR -SOPvrDbgRequestNotifyUnregister(IMG_HANDLE hNotify) -{ - return _UnregisterDbgRequestNotify(hNotify); -} - -void -PVRSRVDebugRequest(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - DEBUG_REQUEST_TABLE *psDebugTable = - (DEBUG_REQUEST_TABLE *) psDevNode->hDebugTable; - DEBUG_REQUEST_TABLE *psDriverDebugTable = - (DEBUG_REQUEST_TABLE *) g_psDriverDebugTable; - static const IMG_CHAR *apszVerbosityTable[] = { "Low", "Medium", "High" }; - const IMG_CHAR *szVerbosityLevel; - const IMG_CHAR *Bit32 = "32 Bit", *Bit64 = "64 Bit"; - IMG_UINT32 i; - - static_assert(ARRAY_SIZE(apszVerbosityTable) == DEBUG_REQUEST_VERBOSITY_MAX+1, - "Incorrect number of verbosity levels"); - - PVR_ASSERT(psDebugTable); - PVR_ASSERT(psDriverDebugTable); - - if (ui32VerbLevel < ARRAY_SIZE(apszVerbosityTable)) - { - szVerbosityLevel = apszVerbosityTable[ui32VerbLevel]; - } - else - { - szVerbosityLevel = "unknown"; - PVR_ASSERT(!"Invalid verbosity level received"); - } - - PVR_DUMPDEBUG_LOG("------------[ PVR DBG: START (%s) ]------------", - szVerbosityLevel); - -#if defined(RGX_IRQ_HYPERV_HANDLER) - if (!PVRSRV_VZ_MODE_IS(GUEST)) -#endif - { - OSDumpVersionInfo(pfnDumpDebugPrintf, pvDumpDebugFile); - } - - PVR_DUMPDEBUG_LOG("DDK info: %s (%s) %s", - PVRVERSION_STRING, PVR_BUILD_TYPE, PVR_BUILD_DIR); - - PVR_DUMPDEBUG_LOG("Time now: %" IMG_UINT64_FMTSPEC "us", - OSClockus64()); - - switch (psPVRSRVData->eServicesState) - { - case PVRSRV_SERVICES_STATE_OK: - PVR_DUMPDEBUG_LOG("Services State: OK"); - break; - case PVRSRV_SERVICES_STATE_BAD: - PVR_DUMPDEBUG_LOG("Services State: BAD"); - break; - case PVRSRV_SERVICES_STATE_UNDEFINED: - PVR_DUMPDEBUG_LOG("Services State: UNDEFINED"); - break; - default: - PVR_DUMPDEBUG_LOG("Services State: UNKNOWN (%d)", - psPVRSRVData->eServicesState); - break; - } - - PVR_DUMPDEBUG_LOG("Server Errors: %d", - PVRSRV_KM_ERRORS); - - PVRSRVConnectionDebugNotify(psDevNode, pfnDumpDebugPrintf, pvDumpDebugFile); - - PVR_DUMPDEBUG_LOG("------[ Driver Info ]------"); - - PVR_DUMPDEBUG_LOG("Comparison of UM/KM components: %s", - (psPVRSRVData->sDriverInfo.bIsNoMatch) ? "MISMATCH" : "MATCHING"); - - PVR_DUMPDEBUG_LOG("KM Arch: %s", - (psPVRSRVData->sDriverInfo.ui8KMBitArch & BUILD_ARCH_64BIT) ? Bit64 : Bit32); - - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - PVR_DUMPDEBUG_LOG("Driver Mode: %s", - (PVRSRV_VZ_MODE_IS(HOST)) ? "Host":"Guest"); - } - - if (psPVRSRVData->sDriverInfo.ui8UMSupportedArch) - { - if ((psPVRSRVData->sDriverInfo.ui8UMSupportedArch & BUILD_ARCH_BOTH) == - BUILD_ARCH_BOTH) - { - PVR_DUMPDEBUG_LOG("UM Connected Clients Arch: %s and %s", Bit64, Bit32); - - } - else - { - PVR_DUMPDEBUG_LOG("UM Connected Clients: %s", - (psPVRSRVData->sDriverInfo.ui8UMSupportedArch & BUILD_ARCH_64BIT) ? Bit64 : Bit32); - } - } - - PVR_DUMP_DRIVER_INFO("UM", psPVRSRVData->sDriverInfo.sUMBuildInfo); - PVR_DUMP_DRIVER_INFO("KM", psPVRSRVData->sDriverInfo.sKMBuildInfo); - - PVR_DUMPDEBUG_LOG("Window system: %s", (IS_DECLARED(WINDOW_SYSTEM)) ? (WINDOW_SYSTEM) : "Not declared"); - - /* Driver debug table */ - OSWRLockAcquireReadNested(psDriverDebugTable->hLock, DN_LOCKCLASS_DRIVER); - /* Device debug table*/ - OSWRLockAcquireReadNested(psDebugTable->hLock, DN_LOCKCLASS_DEVICE); - - /* For each requester in Driver and Device table */ - for (i = 0; i < g_ui32DebugOrderTableReqCount; i++) - { - DLLIST_NODE *psNode; - DLLIST_NODE *psNext; - - /* For each notifier on this requestor */ - dllist_foreach_node(&psDriverDebugTable->asEntry[i].sListHead, psNode, psNext) - { - DEBUG_REQUEST_NOTIFY *psNotify = - IMG_CONTAINER_OF(psNode, DEBUG_REQUEST_NOTIFY, sListNode); - psNotify->pfnDbgRequestNotify(psNotify->hDbgRequestHandle, ui32VerbLevel, - pfnDumpDebugPrintf, pvDumpDebugFile); - } - - /* For each notifier on this requestor */ - dllist_foreach_node(&psDebugTable->asEntry[i].sListHead, psNode, psNext) - { - DEBUG_REQUEST_NOTIFY *psNotify = - IMG_CONTAINER_OF(psNode, DEBUG_REQUEST_NOTIFY, sListNode); - psNotify->pfnDbgRequestNotify(psNotify->hDbgRequestHandle, ui32VerbLevel, - pfnDumpDebugPrintf, pvDumpDebugFile); - } - } - - OSWRLockReleaseRead(psDebugTable->hLock); - OSWRLockReleaseRead(psDriverDebugTable->hLock); - - PVR_DUMPDEBUG_LOG("------------[ PVR DBG: END ]------------"); - - if (!pfnDumpDebugPrintf) - { - /* Only notify OS of an issue if the debug dump has gone there */ - OSWarnOn(IMG_TRUE); - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.h b/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.h deleted file mode 100644 index 216e948834e05..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_notifier.h +++ /dev/null @@ -1,326 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PowerVR notifier interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PVR_NOTIFIER_H) -#define PVR_NOTIFIER_H - -#include "img_types.h" -#include "pvr_debug.h" - - -/*************************************************************************/ /*! -Command Complete Notifier Interface -*/ /**************************************************************************/ - -typedef IMG_HANDLE PVRSRV_CMDCOMP_HANDLE; -#ifndef CMDCOMPNOTIFY_PFN -typedef void (*PFN_CMDCOMP_NOTIFY)(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle); -#define CMDCOMPNOTIFY_PFN -#endif - -/*************************************************************************/ /*! -@Function PVRSRVCmdCompleteInit -@Description Performs initialisation of the command complete notifier - interface. -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVCmdCompleteInit(void); - -/*************************************************************************/ /*! -@Function PVRSRVCmdCompleteDeinit -@Description Performs cleanup for the command complete notifier interface. -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -void -PVRSRVCmdCompleteDeinit(void); - -/*************************************************************************/ /*! -@Function PVRSRVRegisterCmdCompleteNotify -@Description Register a callback function that is called when some device - finishes some work, which is signalled via a call to - PVRSRVCheckStatus. -@Output phNotify On success, points to command complete - notifier handle -@Input pfnCmdCompleteNotify Function callback -@Input hPrivData Data to be passed back to the caller via - the callback function -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRegisterCmdCompleteNotify(IMG_HANDLE *phNotify, - PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, - PVRSRV_CMDCOMP_HANDLE hPrivData); - -/*************************************************************************/ /*! -@Function PVRSRVUnregisterCmdCompleteNotify -@Description Unregister a previously registered callback function. -@Input hNotify Command complete notifier handle -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVUnregisterCmdCompleteNotify(IMG_HANDLE hNotify); - -/*************************************************************************/ /*! -@Function PVRSRVCheckStatus -@Description Calls PVRSRVNotifyCommandCompletion() to notify registered - command complete handlers of work completion and then calls - PVRSRVSignalGlobalEO() to signal the global event object. -@Input hCmdCompCallerHandle Used to prevent a handler from being - notified. A NULL value results in all - handlers being notified. -*/ /**************************************************************************/ -void -PVRSRVCheckStatus(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle); - -/*************************************************************************/ /*! -@Function PVRSRVNotifyCommandCompletion -@Description Notify any registered command complete handlers that some work - has been finished (unless hCmdCompCallerHandle matches a - handler's hPrivData). -@Input hCmdCompCallerHandle Used to prevent a handler from being - notified. A NULL value results in all - handlers being notified. -*/ /**************************************************************************/ -void -PVRSRVNotifyCommandCompletion(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle); - -/*************************************************************************/ /*! -@Function PVRSRVSignalGlobalEO -@Description Signals the global event object. -*/ /**************************************************************************/ -void -PVRSRVSignalGlobalEO(void); - - -/*************************************************************************/ /*! -Debug Notifier Interface -*/ /**************************************************************************/ - -#define DEBUG_REQUEST_DC 0 -#define DEBUG_REQUEST_SYNCTRACKING 1 -#define DEBUG_REQUEST_SRV 2 -#define DEBUG_REQUEST_SYS 3 -#define DEBUG_REQUEST_RGX 4 -#define DEBUG_REQUEST_ANDROIDSYNC 5 -#define DEBUG_REQUEST_LINUXFENCE 6 -#define DEBUG_REQUEST_SYNCCHECKPOINT 7 -#define DEBUG_REQUEST_HTB 8 -#define DEBUG_REQUEST_APPHINT 9 -#define DEBUG_REQUEST_FALLBACKSYNC 10 - -#define DEBUG_REQUEST_VERBOSITY_LOW 0 -#define DEBUG_REQUEST_VERBOSITY_MEDIUM 1 -#define DEBUG_REQUEST_VERBOSITY_HIGH 2 -#define DEBUG_REQUEST_VERBOSITY_MAX DEBUG_REQUEST_VERBOSITY_HIGH - -#define DD_VERB_LVL_ENABLED(_verbLvl, _verbLvlChk) ((_verbLvl) >= (_verbLvlChk)) - -/* - * Macro used within debug dump functions to send output either to PVR_LOG or - * a custom function. The custom function should be stored as a function - * pointer in a local variable called 'pfnDumpDebugPrintf'. 'pvDumpDebugFile' - * is also required as a local variable to serve as a file identifier for the - * printf function if required. - */ -#define PVR_DUMPDEBUG_LOG(...) \ - do \ - { \ - if (pfnDumpDebugPrintf) \ - pfnDumpDebugPrintf(pvDumpDebugFile, __VA_ARGS__); \ - else \ - PVR_LOG((__VA_ARGS__)); \ - } while (0) - -struct _PVRSRV_DEVICE_NODE_; - -typedef IMG_HANDLE PVRSRV_DBGREQ_HANDLE; -#ifndef DBGNOTIFY_PFNS -typedef void (DUMPDEBUG_PRINTF_FUNC)(void *pvDumpDebugFile, - const IMG_CHAR *pszFormat, ...) __attribute__ ((format (printf, 2, 3))); -typedef void (*PFN_DBGREQ_NOTIFY)(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); -#define DBGNOTIFY_PFNS -#endif - -/*************************************************************************/ /*! -@Function PVRSRVRegisterDeviceDbgTable -@Description Registers a debug requester table for the given device. The - order in which the debug requester IDs appear in the - table determine the order in which a set of notifier callbacks - will be called. In other words, the requester ID that appears - first will have all of its associated debug notifier callbacks - called first. This will then be followed by all the callbacks - associated with the next requester ID in the table and so on. - The order table is handled internally. -@Input psDevNode Device node to register requester table with -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRegisterDeviceDbgTable(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - -/*************************************************************************/ /*! -@Function PVRSRVRegisterDriverDbgTable -@Description Registers a debug requester table for the driver. The - order in which the debug requester IDs appear in the - table determine the order in which a set of notifier callbacks - will be called. In other words, the requester ID that appears - first will have all of its associated debug notifier callbacks - called first. This will then be followed by all the callbacks - associated with the next requester ID in the table and so on. - The order table is handled internally. -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRegisterDriverDbgTable(void); - -/*************************************************************************/ /*! -@Function PVRSRVUnregisterDeviceDbgTable -@Description Unregisters a debug requester table. -@Input psDevNode Device node for which the requester table should - be unregistered -@Return void -*/ /**************************************************************************/ -void -PVRSRVUnregisterDeviceDbgTable(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - -/*************************************************************************/ /*! -@Function PVRSRVUnregisterDriverDbgTable -@Description Unregisters the driver debug requester table. -@Return void -*/ /**************************************************************************/ -void -PVRSRVUnregisterDriverDbgTable(void); - -/*************************************************************************/ /*! -@Function PVRSRVRegisterDeviceDbgRequestNotify -@Description Register a callback function on a given device that is called - when a debug request is made via a call PVRSRVDebugRequest. - There are a number of verbosity levels ranging from - DEBUG_REQUEST_VERBOSITY_LOW up to - DEBUG_REQUEST_VERBOSITY_MAX. The callback will be called once - for each level up to the highest level specified to - PVRSRVDebugRequest. -@Output phNotify Points to debug notifier handle on success -@Input psDevNode Device node for which the debug callback - should be registered -@Input pfnDbgRequestNotify Function callback -@Input ui32RequesterID Requester ID. This is used to determine - the order in which callbacks are called -@Input hDbgReqeustHandle Data to be passed back to the caller via - the callback function -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRegisterDeviceDbgRequestNotify(IMG_HANDLE *phNotify, - struct _PVRSRV_DEVICE_NODE_ *psDevNode, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgReqeustHandle); - -/*************************************************************************/ /*! -@Function PVRSRVRegisterDriverDbgRequestNotify -@Description Register a callback function that is called when a debug request - is made via a call PVRSRVDebugRequest. There are a number of - verbosity levels ranging from DEBUG_REQUEST_VERBOSITY_LOW up to - DEBUG_REQUEST_VERBOSITY_MAX. The callback will be called once - for each level up to the highest level specified to - PVRSRVDebugRequest. -@Output phNotify Points to debug notifier handle on success -@Input pfnDbgRequestNotify Function callback -@Input ui32RequesterID Requester ID. This is used to determine - the order in which callbacks are called -@Input hDbgReqeustHandle Data to be passed back to the caller via - the callback function -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRegisterDriverDbgRequestNotify(IMG_HANDLE *phNotify, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - IMG_UINT32 ui32RequesterID, - PVRSRV_DBGREQ_HANDLE hDbgRequestHandle); - -/*************************************************************************/ /*! -@Function PVRSRVUnregisterDeviceDbgRequestNotify -@Description Unregister a previously registered (device context) callback - function. -@Input hNotify Debug notifier handle. -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVUnregisterDeviceDbgRequestNotify(IMG_HANDLE hNotify); - -/*************************************************************************/ /*! -@Function PVRSRVUnregisterDriverDbgRequestNotify -@Description Unregister a previously registered (driver context) callback - function. -@Input hNotify Debug notifier handle. -@Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVUnregisterDriverDbgRequestNotify(IMG_HANDLE hNotify); - -/*************************************************************************/ /*! -@Function PVRSRVDebugRequest -@Description Notify any registered debug request handlers that a debug - request has been made and at what level. -@Input psDevNode Device node for which the debug request - has been made -@Input ui32VerbLevel The maximum verbosity level to dump -@Input pfnDumpDebugPrintf Used to specify the print function that - should be used to dump any debug - information. If this argument is NULL then - PVR_LOG() will be used as the default - print function. -@Input pvDumpDebugFile Optional file identifier to be passed to - the print function if required. -@Return void -*/ /**************************************************************************/ -void -PVRSRVDebugRequest(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -#endif /* !defined(PVR_NOTIFIER_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c b/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c deleted file mode 100644 index 9cb2d76cf53ab..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_platform_drv.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * @File - * @Title PowerVR DRM platform driver - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#include -#include - -#include "module_common.h" -#include "pvr_drv.h" -#include "pvrmodule.h" -#include "sysinfo.h" - - -/* This header must always be included last */ -#include "kernel_compatibility.h" - -static struct drm_driver pvr_drm_platform_driver; - -#if defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) -/* - * This is an arbitrary value. If it's changed then the 'num_devices' module - * parameter description should also be updated to match. - */ -#define MAX_DEVICES 16 - -static unsigned int pvr_num_devices = 1; -static struct platform_device **pvr_devices; - -#if defined(NO_HARDWARE) -static int pvr_num_devices_set(const char *val, - const struct kernel_param *param) -{ - int err; - - err = param_set_uint(val, param); - if (err) - return err; - - if (pvr_num_devices == 0 || pvr_num_devices > MAX_DEVICES) - return -EINVAL; - - return 0; -} - -static const struct kernel_param_ops pvr_num_devices_ops = { - .set = pvr_num_devices_set, - .get = param_get_uint, -}; - -module_param_cb(num_devices, &pvr_num_devices_ops, &pvr_num_devices, 0444); -MODULE_PARM_DESC(num_devices, - "Number of platform devices to register (default: 1 - max: 16)"); -#endif /* defined(NO_HARDWARE) */ -#endif /* defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) */ - -static int pvr_devices_register(void) -{ -#if defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) - struct platform_device_info pvr_dev_info = { - .name = SYS_RGX_DEV_NAME, - .id = -2, -#if defined(NO_HARDWARE) - /* Not all cores have 40 bit physical support, but this - * will work unless > 32 bit address is returned on those cores. - * In the future this will be fixed more correctly. - */ - .dma_mask = DMA_BIT_MASK(40), -#else - .dma_mask = DMA_BIT_MASK(32), -#endif - }; - unsigned int i; - - BUG_ON(pvr_num_devices == 0 || pvr_num_devices > MAX_DEVICES); - - pvr_devices = kmalloc_array(pvr_num_devices, sizeof(*pvr_devices), - GFP_KERNEL); - if (!pvr_devices) - return -ENOMEM; - - for (i = 0; i < pvr_num_devices; i++) { - pvr_devices[i] = platform_device_register_full(&pvr_dev_info); - if (IS_ERR(pvr_devices[i])) { - DRM_ERROR("unable to register device %u (err=%ld)\n", - i, PTR_ERR(pvr_devices[i])); - pvr_devices[i] = NULL; - return -ENODEV; - } - } -#endif /* defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) */ - - return 0; -} - -static void pvr_devices_unregister(void) -{ -#if defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) - unsigned int i; - - BUG_ON(!pvr_devices); - - for (i = 0; i < pvr_num_devices && pvr_devices[i]; i++) - platform_device_unregister(pvr_devices[i]); - - kfree(pvr_devices); - pvr_devices = NULL; -#endif /* defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) */ -} - -static int pvr_probe(struct platform_device *pdev) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) - struct drm_device *ddev; - int ret; - - DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - - ddev = drm_dev_alloc(&pvr_drm_platform_driver, &pdev->dev); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) - if (IS_ERR(ddev)) - return PTR_ERR(ddev); -#else - if (!ddev) - return -ENOMEM; -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) - /* Needed by drm_platform_set_busid */ - ddev->platformdev = pdev; -#endif - - /* - * The load callback, called from drm_dev_register, is deprecated, - * because of potential race conditions. Calling the function here, - * before calling drm_dev_register, avoids those potential races. - */ - BUG_ON(pvr_drm_platform_driver.load != NULL); - ret = pvr_drm_load(ddev, 0); - if (ret) - goto err_drm_dev_put; - - ret = drm_dev_register(ddev, 0); - if (ret) - goto err_drm_dev_unload; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - pvr_drm_platform_driver.name, - pvr_drm_platform_driver.major, - pvr_drm_platform_driver.minor, - pvr_drm_platform_driver.patchlevel, - pvr_drm_platform_driver.date, - ddev->primary->index); -#endif - return 0; - -err_drm_dev_unload: - pvr_drm_unload(ddev); -err_drm_dev_put: - drm_dev_put(ddev); - return ret; -#else - DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - - return drm_platform_init(&pvr_drm_platform_driver, pdev); -#endif -} - -static int pvr_remove(struct platform_device *pdev) -{ - struct drm_device *ddev = platform_get_drvdata(pdev); - - DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) - drm_dev_unregister(ddev); - - /* The unload callback, called from drm_dev_unregister, is - * deprecated. Call the unload function directly. - */ - BUG_ON(pvr_drm_platform_driver.unload != NULL); - pvr_drm_unload(ddev); - - drm_dev_put(ddev); -#else - drm_put_dev(ddev); -#endif - return 0; -} - -static void pvr_shutdown(struct platform_device *pdev) -{ - struct drm_device *ddev = platform_get_drvdata(pdev); - struct pvr_drm_private *priv = ddev->dev_private; - - DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - - PVRSRVDeviceShutdown(priv->dev_node); -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) -static const struct of_device_id pvr_of_ids[] = { -#if defined(SYS_RGX_OF_COMPATIBLE) - { .compatible = SYS_RGX_OF_COMPATIBLE, }, -#endif - {}, -}; - -#if !defined(CHROMIUMOS_KERNEL) || !defined(MODULE) -MODULE_DEVICE_TABLE(of, pvr_of_ids); -#endif -#endif - -static struct platform_device_id pvr_platform_ids[] = { -#if defined(SYS_RGX_DEV_NAME) - { SYS_RGX_DEV_NAME, 0 }, -#endif - { } -}; - -#if !defined(CHROMIUMOS_KERNEL) || !defined(MODULE) -MODULE_DEVICE_TABLE(platform, pvr_platform_ids); -#endif - -static struct platform_driver pvr_platform_driver = { - .driver = { - .name = DRVNAME, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) - .of_match_table = of_match_ptr(pvr_of_ids), -#endif - .pm = &pvr_pm_ops, - }, - .id_table = pvr_platform_ids, - .probe = pvr_probe, - .remove = pvr_remove, - .shutdown = pvr_shutdown, -}; - -static int __init pvr_init(void) -{ - int err; - struct device_node *np; - - /* - * CHROMIUM: - * - * This driver seems to do a bunch of stuff before it even detects - * if hardware is available. That's bad. In general drivers are - * supposed to be registering themselves and then actually doing - * something when they see the relevant hardware show up. - * - * Since this driver is downstream and doing an intrusive refactor - * would be disruptive, we'll just apply a large band-aid and early- - * return if we don't find the needed dt-compatible. - */ - np = of_find_compatible_node(NULL, NULL, SYS_RGX_OF_COMPATIBLE); - if (!np) - return -ENODEV; - of_node_put(np); - - DRM_DEBUG_DRIVER("\n"); - - pvr_drm_platform_driver = pvr_drm_generic_driver; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) - pvr_drm_platform_driver.set_busid = drm_platform_set_busid; -#endif - - err = PVRSRVDriverInit(); - if (err) - return err; - - err = platform_driver_register(&pvr_platform_driver); - if (err) - return err; - - return pvr_devices_register(); -} - -static void __exit pvr_exit(void) -{ - DRM_DEBUG_DRIVER("\n"); - - pvr_devices_unregister(); - platform_driver_unregister(&pvr_platform_driver); - PVRSRVDriverDeinit(); - - DRM_DEBUG_DRIVER("done\n"); -} - -late_initcall(pvr_init); -module_exit(pvr_exit); diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_procfs.h b/drivers/gpu/drm/img-rogue/1.17/pvr_procfs.h deleted file mode 100644 index 61a1f0ee28d3c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_procfs.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title ProcFS implementation of Debug Info interface. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_PROCFS_H -#define PVR_PROCFS_H - -#include "pvrsrv_error.h" - -PVRSRV_ERROR PVRProcFsRegister(void); - -#endif /* PVR_PROCFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_ricommon.h b/drivers/gpu/drm/img-rogue/1.17/pvr_ricommon.h deleted file mode 100644 index 0521aa151794b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_ricommon.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Resource Information (RI) common types and definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Resource Information (RI) common types and definitions included - in both user mode and kernel mode source. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_RICOMMON_H -#define PVR_RICOMMON_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" - -/*! Maximum text string length including the null byte */ -#define PRVSRVRI_MAX_TEXT_LENGTH 20U - -/* PID used to hold PMR allocations which are driver-wide (i.e. have a lifetime - * longer than an application process) - */ -#define PVR_SYS_ALLOC_PID 1 - -#if defined(__cplusplus) -} -#endif - -#endif /* PVR_RICOMMON_H */ -/****************************************************************************** - End of file (pvr_ricommon.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.c b/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.c deleted file mode 100644 index b9257be2a741d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * @File - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Strictly Confidential. - */ - -#include -#include -#include -#include -#include -#include - -#include "pvr_sw_fence.h" - -struct pvr_sw_fence_context { - struct kref kref; - unsigned int context; - char context_name[32]; - char driver_name[32]; - atomic_t seqno; - atomic_t fence_count; -}; - -struct pvr_sw_fence { - struct dma_fence base; - struct pvr_sw_fence_context *fence_context; - spinlock_t lock; -}; - -#define to_pvr_sw_fence(fence) container_of(fence, struct pvr_sw_fence, base) - -const char *pvr_sw_fence_context_name(struct pvr_sw_fence_context *fctx) -{ - return fctx->context_name; -} - -void pvr_sw_fence_context_value_str(struct pvr_sw_fence_context *fctx, - char *str, int size) -{ - snprintf(str, size, "%d", atomic_read(&fctx->seqno)); -} - -static inline unsigned -pvr_sw_fence_context_seqno_next(struct pvr_sw_fence_context *fence_context) -{ - return atomic_inc_return(&fence_context->seqno) - 1; -} - -static const char *pvr_sw_fence_get_driver_name(struct dma_fence *fence) -{ - struct pvr_sw_fence *pvr_sw_fence = to_pvr_sw_fence(fence); - - return pvr_sw_fence->fence_context->driver_name; -} - -static const char *pvr_sw_fence_get_timeline_name(struct dma_fence *fence) -{ - struct pvr_sw_fence *pvr_sw_fence = to_pvr_sw_fence(fence); - - return pvr_sw_fence_context_name(pvr_sw_fence->fence_context); -} - -static void pvr_sw_fence_value_str(struct dma_fence *fence, char *str, int size) -{ - snprintf(str, size, "%llu", (u64) fence->seqno); -} - -static void pvr_sw_fence_timeline_value_str(struct dma_fence *fence, - char *str, int size) -{ - struct pvr_sw_fence *pvr_sw_fence = to_pvr_sw_fence(fence); - - pvr_sw_fence_context_value_str(pvr_sw_fence->fence_context, str, size); -} - -static bool pvr_sw_fence_enable_signaling(struct dma_fence *fence) -{ - return true; -} - -static void pvr_sw_fence_context_destroy_kref(struct kref *kref) -{ - struct pvr_sw_fence_context *fence_context = - container_of(kref, struct pvr_sw_fence_context, kref); - unsigned int fence_count; - - fence_count = atomic_read(&fence_context->fence_count); - if (WARN_ON(fence_count)) - pr_debug("%s context has %u fence(s) remaining\n", - fence_context->context_name, fence_count); - - kfree(fence_context); -} - -static void pvr_sw_fence_release(struct dma_fence *fence) -{ - struct pvr_sw_fence *pvr_sw_fence = to_pvr_sw_fence(fence); - - atomic_dec(&pvr_sw_fence->fence_context->fence_count); - kref_put(&pvr_sw_fence->fence_context->kref, - pvr_sw_fence_context_destroy_kref); - kfree(pvr_sw_fence); -} - -static const struct dma_fence_ops pvr_sw_fence_ops = { - .get_driver_name = pvr_sw_fence_get_driver_name, - .get_timeline_name = pvr_sw_fence_get_timeline_name, - .fence_value_str = pvr_sw_fence_value_str, - .timeline_value_str = pvr_sw_fence_timeline_value_str, - .enable_signaling = pvr_sw_fence_enable_signaling, - .wait = dma_fence_default_wait, - .release = pvr_sw_fence_release, -}; - -struct pvr_sw_fence_context * -pvr_sw_fence_context_create(const char *context_name, const char *driver_name) -{ - struct pvr_sw_fence_context *fence_context; - - fence_context = kmalloc(sizeof(*fence_context), GFP_KERNEL); - if (!fence_context) - return NULL; - - fence_context->context = dma_fence_context_alloc(1); - strlcpy(fence_context->context_name, context_name, - sizeof(fence_context->context_name)); - strlcpy(fence_context->driver_name, driver_name, - sizeof(fence_context->driver_name)); - atomic_set(&fence_context->seqno, 0); - atomic_set(&fence_context->fence_count, 0); - kref_init(&fence_context->kref); - - return fence_context; -} - -void pvr_sw_fence_context_destroy(struct pvr_sw_fence_context *fence_context) -{ - kref_put(&fence_context->kref, pvr_sw_fence_context_destroy_kref); -} - -struct dma_fence * -pvr_sw_fence_create(struct pvr_sw_fence_context *fence_context) -{ - struct pvr_sw_fence *pvr_sw_fence; - unsigned int seqno; - - pvr_sw_fence = kmalloc(sizeof(*pvr_sw_fence), GFP_KERNEL); - if (!pvr_sw_fence) - return NULL; - - spin_lock_init(&pvr_sw_fence->lock); - pvr_sw_fence->fence_context = fence_context; - - seqno = pvr_sw_fence_context_seqno_next(fence_context); - dma_fence_init(&pvr_sw_fence->base, &pvr_sw_fence_ops, - &pvr_sw_fence->lock, fence_context->context, seqno); - - atomic_inc(&fence_context->fence_count); - kref_get(&fence_context->kref); - - return &pvr_sw_fence->base; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.h b/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.h deleted file mode 100644 index 40185d2561cb5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sw_fence.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * @File - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Strictly Confidential. - */ - -#if !defined(__PVR_SW_FENCES_H__) -#define __PVR_SW_FENCES_H__ - -#include "pvr_linux_fence.h" - -struct pvr_sw_fence_context; - -struct pvr_sw_fence_context *pvr_sw_fence_context_create(const char *name, - const char *driver_name); -void pvr_sw_fence_context_destroy(struct pvr_sw_fence_context *fence_context); -struct dma_fence *pvr_sw_fence_create(struct pvr_sw_fence_context * - fence_context); - -const char *pvr_sw_fence_context_name(struct pvr_sw_fence_context *fctx); -void pvr_sw_fence_context_value_str(struct pvr_sw_fence_context *fctx, - char *str, int size); - -#endif /* !defined(__PVR_SW_FENCES_H__) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync.h b/drivers/gpu/drm/img-rogue/1.17/pvr_sync.h deleted file mode 100644 index c6d49f34c9674..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * @File pvr_sync.h - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVR_SYNC_H -#define _PVR_SYNC_H - -#include - -#include "pvr_fd_sync_kernel.h" -#include "services_kernel_client.h" - - -/* Services internal interface */ - -/* - * pvr_sync_register_functions() - * - * Return: PVRSRV_OK on success. - */ -enum PVRSRV_ERROR_TAG pvr_sync_register_functions(void); - -/* - * pvr_sync_init - register the pvr_sync misc device - * - * Return: error code, 0 on success. - */ -int pvr_sync_init(void); - -/* - * pvr_sync_deinit - unregister the pvr_sync misc device - */ -void pvr_sync_deinit(void); - -/* - * pvr_sync_device_init() - create an internal sync context - * @dev: Linux device - * - * Return: PVRSRV_OK on success. - */ -enum PVRSRV_ERROR_TAG pvr_sync_device_init(struct device *dev); - -/* - * pvr_sync_device_deinit() - destroy an internal sync context - * - * Drains any work items with outstanding sync fence updates/dependencies. - */ -void pvr_sync_device_deinit(struct device *dev); - -enum PVRSRV_ERROR_TAG pvr_sync_fence_wait(void *fence, u32 timeout_in_ms); - -enum PVRSRV_ERROR_TAG pvr_sync_fence_release(void *fence); - -enum PVRSRV_ERROR_TAG pvr_sync_fence_get(int fence_fd, void **fence_out); - -enum PVRSRV_ERROR_TAG -pvr_sync_sw_timeline_fence_create(struct _PVRSRV_DEVICE_NODE_ *pvrsrv_dev_node, - int timeline_fd, - const char *fence_name, - int *fence_fd_out, - u64 *sync_pt_idx); - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_advance(void *timeline, - u64 *sync_pt_idx); - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_release(void *timeline); - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_get(int timeline_fd, - void **timeline_out); - -enum PVRSRV_ERROR_TAG -sync_dump_fence(void *sw_fence_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file); - -enum PVRSRV_ERROR_TAG -sync_sw_dump_timeline(void *sw_timeline_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file); - -#endif /* _PVR_SYNC_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync2.c b/drivers/gpu/drm/img-rogue/1.17/pvr_sync2.c deleted file mode 100644 index d454de883bcac..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync2.c +++ /dev/null @@ -1,2759 +0,0 @@ -/* - * @File pvr_sync.c - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_drv.h" -#include "pvr_fd_sync_kernel.h" -#include "services_kernel_client.h" -#include "pvr_sync.h" -#include "pvrsrv_sync_km.h" -#include "sync_checkpoint_external.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)) -#include -#include -#else -#include <../drivers/staging/android/sync.h> -#include <../drivers/staging/android/sw_sync.h> -#endif - -#include "linux_sw_sync.h" - -#include "pvr_sync_api.h" - -#include "kernel_compatibility.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) - -static inline int sync_fence_get_status(struct sync_fence *psFence) -{ - return psFence->status; -} - -static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt) -{ - return pt->parent; -} - -static inline int sync_pt_get_status(struct sync_pt *pt) -{ - return pt->status; -} - -static inline ktime_t sync_pt_get_timestamp(struct sync_pt *pt) -{ - return pt->timestamp; -} - -#define for_each_sync_pt(s, f, c) \ - list_for_each_entry((s), &(f)->pt_list_head, pt_list) - -#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */ - -static inline int sync_fence_get_status(struct sync_fence *psFence) -{ - int iStatus = atomic_read(&psFence->status); - - /* - * When Android sync was rebased on top of fences the sync_fence status - * values changed from 0 meaning 'active' to 'signalled' and, likewise, - * values greater than 0 went from meaning 'signalled' to 'active' - * (where the value corresponds to the number of active sync points). - * - * Convert to the old style status values. - */ - return iStatus > 0 ? 0 : iStatus ? iStatus : 1; -} - -static inline int sync_pt_get_status(struct sync_pt *pt) -{ - /* No error state for raw dma-buf fences */ - return fence_is_signaled(&pt->base) ? 1 : 0; -} - -static inline ktime_t sync_pt_get_timestamp(struct sync_pt *pt) -{ - return pt->base.timestamp; -} - -#define for_each_sync_pt(s, f, c) \ - for ((c) = 0, (s) = (f)->num_fences == 0 ? \ - NULL : (struct sync_pt *)(f)->cbs[0].sync_pt; \ - (c) < (f)->num_fences; \ - (c)++, (s) = (c) < (f)->num_fences ? \ - (struct sync_pt *)(f)->cbs[c].sync_pt : NULL) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */ - -/* #define DEBUG_OUTPUT 1 */ - -#ifdef DEBUG_OUTPUT -#define DPF(fmt, ...) pr_err("pvr_sync2: " fmt "\n", __VA_ARGS__) -#else -#define DPF(fmt, ...) do {} while (0) -#endif - -#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, ...) \ - do { \ - if (pfnDumpDebugPrintf) { \ - pfnDumpDebugPrintf(pvDumpDebugFile, __VA_ARGS__); \ - } else { \ - pr_info("pvr_sync2: " __VA_ARGS__); \ - } \ - } while (0) - -#if defined(PDUMP) -#define SYNC_MAX_POOL_SIZE 0 -#else -#define SYNC_MAX_POOL_SIZE 10 -#endif - -enum { - SYNC_TL_TYPE = 0, - SYNC_PT_FENCE_TYPE = 1, - SYNC_PT_CLEANUP_TYPE = 2, - SYNC_PT_FOREIGN_FENCE_TYPE = 3, - SYNC_PT_FOREIGN_CLEANUP_TYPE = 4, -}; - -/* Services client sync prim wrapper. This is used to hold debug information - * and make it possible to cache unused syncs. - */ -struct pvr_sync_native_sync_prim { - /* List for the sync pool support. */ - struct list_head list; - - /* Base services sync prim structure */ - struct PVRSRV_CLIENT_SYNC_PRIM_TAG *client_sync; - - /* The next queued value which should be used */ - u32 next_value; - - /* Every sync data will get some unique id */ - u32 id; - - /* FWAddr used by the client sync */ - u32 vaddr; - - /* The type this sync is used for in our driver. Used in - * pvr_sync_debug_request(). - */ - u8 type; - - /* A debug class name also printed in pvr_sync_debug_request(). */ - char class[32]; -}; - -struct pvr_sync_native_sync_checkpoint { - /* List for the sync pool support. */ - struct list_head list; - - /* Base services sync checkpoint */ - PSYNC_CHECKPOINT client_sync_checkpoint; - - /* Every sync data will get some unique id */ - u32 id; - - /* FWAddr used by the client sync */ - u32 vaddr; - - /* The type this sync is used for in our driver. Used in - * pvr_sync_debug_request(). - */ - u8 type; - - /* A debug class name also printed in pvr_sync_debug_request(). */ - char class[32]; - - /* We store the foreign sync fence (if applicable), for debug purposes. */ - struct sync_fence *foreign_sync_fence; - char foreign_sync_fence_name[32]; -}; - -struct pvr_sw_sync_timeline { - /* sw_sync_timeline must come first to allow casting of a ptr */ - /* to the wrapping struct to a ptr to the sw_sync_timeline */ - struct sw_sync_timeline *sw_sync_timeline; - u64 current_value; - u64 next_value; - /* Reference count for this object */ - struct kref kref; -}; - -/* This is the actual timeline metadata. We might keep this around after the - * base sync driver has destroyed the pvr_sync_timeline_wrapper object. - */ -struct pvr_sync_timeline { - /* Back reference to the sync_timeline. Not always valid */ - struct sync_timeline *obj; - - /* Global timeline list support */ - struct list_head list; - - /* List of sync points alive on this timeline. */ - struct list_head sync_list; - - /* Timeline sync */ - struct pvr_sync_timeline_kernel_pair *kernel; - - /* Reference count for this object */ - struct kref kref; - - /* Used only by pvr_sync_update_all_timelines(). False if the timeline - * has been detected as racing with pvr_sync_destroy_timeline(). - */ - bool valid; -}; - -/* This is the IMG extension of a sync_timeline */ -struct pvr_sync_timeline_wrapper { - /* Original timeline struct. Needs to come first. */ - struct sync_timeline obj; - - /* Pointer to extra timeline data. Separated life-cycle. */ - struct pvr_sync_timeline *timeline; -}; - -struct pvr_sync_timeline_kernel_pair { - /* Binary sync point representing the android native sync in hw. */ - struct pvr_sync_native_sync_prim *fence_sync; - - /* Sync points can go away when there are deferred hardware operations - * still outstanding. We must not free the SERVER_SYNC_PRIMITIVE until - * the hardware is finished, so we add it to a defer list which is - * processed periodically ("defer-free"). - * - * Note that the defer-free list is global, not per-timeline. - */ - struct list_head list; -}; - -struct pvr_sync_kernel_pair { - /* Binary sync point representing the android native sync in hw. */ - struct pvr_sync_native_sync_checkpoint *fence_sync; - - /* Sync points can go away when there are deferred hardware operations - * still outstanding. We must not free the SERVER_SYNC_PRIMITIVE until - * the hardware is finished, so we add it to a defer list which is - * processed periodically ("defer-free"). - * - * Note that the defer-free list is global, not per-timeline. - */ - struct list_head list; -}; - -struct pvr_sync_data { - /* Every sync point has a services sync object. This object is used - * by the hardware to enforce ordering -- it is attached as a source - * dependency to various commands. - */ - struct pvr_sync_kernel_pair *kernel; - - /* The timeline update value for this sync point. */ - u32 timeline_update_value; - - /* This refcount is incremented at create and dup time, and decremented - * at free time. It ensures the object doesn't start the defer-free - * process until it is no longer referenced. - */ - struct kref kref; -}; - -/* This is the IMG extension of a sync_pt */ -struct pvr_sync_pt { - /* Original sync_pt structure. Needs to come first. */ - struct sync_pt pt; - - /* Private shared data */ - struct pvr_sync_data *sync_data; - - /* The timeline on which this pvr_sync_pt was created */ - struct pvr_sync_timeline *timeline; -}; - -/* This is the IMG extension of a sync_fence */ -struct pvr_sync_fence { - /* Original sync_fence structure. Needs to come first. */ - struct sync_fence *fence; - - /* To ensure callbacks are always received for fences / sync_pts, even - * after the fence has been 'put' (freed), we must take a reference to - * the fence. We still need to 'put' the fence ourselves, but this might - * happen in irq context, where fput() is not allowed (in kernels <3.6). - * We must add the fence to a list which is processed in WQ context. - */ - struct list_head list; -}; - -/* Any sync point from a foreign (non-PVR) timeline needs to have a "shadow" - * sync prim. This is modelled as a software operation. The foreign driver - * completes the operation by calling a callback we registered with it. - */ -struct pvr_sync_fence_waiter { - /* Base sync driver waiter structure */ - struct sync_fence_waiter waiter; - - /* "Shadow" sync prim backing the foreign driver's sync_pt */ - struct pvr_sync_kernel_pair *kernel; - - /* Optimizes lookup of fence for defer-put operation */ - struct pvr_sync_fence *sync_fence; -}; - -/* Global data for the sync driver */ -static struct { - /* Complete notify handle */ - void *command_complete_handle; - - /* Defer-free workqueue. Syncs may still be in use by the HW when freed, - * so we have to keep them around until the HW is done with them at - * some later time. This workqueue iterates over the list of free'd - * syncs, checks if they are in use, and frees the sync device memory - * when done with. - */ - struct workqueue_struct *defer_free_wq; - struct work_struct defer_free_work; - - struct work_struct check_status_work; - - /* Context used to create client sync prims. */ - struct SYNC_PRIM_CONTEXT_TAG *sync_prim_context; - - /* Unique id counter for the sync prims */ - atomic_t sync_id; - - /* The global event object (used to wait between checks for - * deferred-free sync status). - */ - void *event_object_handle; - - /* struct used to register with sync_checkpoint.c */ - PFN_SYNC_CHECKPOINT_STRUCT sync_checkpoint_ops; -} pvr_sync_data; - -/* List of timelines created by this driver */ -static LIST_HEAD(timeline_list); -static DEFINE_SPINLOCK(timeline_list_lock); - -/* Sync pool support */ -static LIST_HEAD(sync_pool_free_list); -static LIST_HEAD(sync_pool_active_list); -static DEFINE_MUTEX(sync_pool_mutex); -static s32 sync_pool_size;// = 0; -static u32 sync_pool_created;// = 0; -static u32 sync_pool_reused;// = 0; - -/* pvr_sync_pt_active_list is used for debug - when a - * pvr sync_native_sync_checkpoint is created it is added - * to this list (which contains all existing points for - * all pvr timelines). - */ -static LIST_HEAD(pvr_sync_pt_active_list); -static DEFINE_SPINLOCK(pvr_sync_pt_active_list_spinlock); -/* pvr_sw_sync_pt_active_list is used for debug - when a - * pvr sw_sync_native_sync_checkpoint is created it is added - * to this list (which contains all existing points for - * all pvr sw timelines). - */ -static LIST_HEAD(pvr_sw_sync_pt_active_list); -static DEFINE_MUTEX(pvr_sw_sync_pt_active_list_mutex); - -/* The "defer-free" sync_checkpoint list. Driver global. */ -static LIST_HEAD(sync_checkpoint_free_list); -static DEFINE_SPINLOCK(sync_checkpoint_free_list_spinlock); - -/* The "defer-free-timeline" object list. Driver global. */ -static LIST_HEAD(timeline_free_list); -static DEFINE_SPINLOCK(timeline_free_list_spinlock); - -/* The "defer-put" object list. Driver global. */ -static LIST_HEAD(sync_fence_put_list); -static DEFINE_SPINLOCK(sync_fence_put_list_spinlock); - -static void pvr_sync_update_all_timelines(void *command_complete_handle); -static void pvr_sync_free_checkpoint_list_mem(void *mem_ptr); - -static void _dump_fence(struct sync_fence *fence, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0)) - struct sync_pt *sync_point; - char time_str[16] = { '\0' }; - char pt_value_str[64] = { '\0' }; - char timeline_value_str[64] = { '\0' }; - char value_str[132] = { '\0' }; - int status = sync_fence_get_status(fence); - int i; - - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "[%p] %s: %s ref=%u Sync Points:\n", - fence, - fence->name, - (status > 0 ? - "Signalled" : status ? - "Error" : "Active"), - atomic_read(&fence->kref.refcount)); - - for_each_sync_pt(sync_point, fence, i) { - - struct sync_timeline *timeline = sync_pt_parent(sync_point); - ktime_t timestamp = sync_pt_get_timestamp(sync_point); - struct timeval tv = ktime_to_timeval(timestamp); - int i_pt_status = sync_pt_get_status(sync_point); - - char time_pt[16] = { '\0' }; - const struct fence_ops *fence_ops = sync_point->base.ops; - - snprintf(time_str, - sizeof(time_str), - "@%ld.%06ld", - tv.tv_sec, - tv.tv_usec); - - if (timeline->ops->pt_value_str && - timeline->ops->timeline_value_str) { - timeline->ops->pt_value_str(sync_point, pt_value_str, sizeof(pt_value_str)); - timeline->ops->timeline_value_str(timeline, - timeline_value_str, - sizeof(timeline_value_str)); - snprintf(value_str, sizeof(value_str), "%s / %s", - timeline_value_str, pt_value_str); - } - fence_ops->timeline_value_str(&sync_point->base, time_pt, sizeof(time_pt)); - - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "\t@%u Ref=%u TS=%s State=%s %s TLN=%s\n", - sync_point->base.seqno, - atomic_read(&sync_point->base.refcount.refcount), - time_pt, - (i_pt_status > 0 ? "signalled" : i_pt_status ? - "error" : "active"), - value_str, - fence_ops->get_timeline_name(&sync_point->base)); - } -#else - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "Fence stats not available on this platform!"); -#endif -} - -/* Sync prim helpers */ -static inline void set_sync_prim_value(struct pvr_sync_native_sync_prim *sync, - u32 value) -{ - *(sync->client_sync->pui32LinAddr) = value; -} - -static inline u32 get_sync_prim_value(struct pvr_sync_native_sync_prim *sync) -{ - return *(sync->client_sync->pui32LinAddr); -} - -static inline void complete_sync_prim(struct pvr_sync_native_sync_prim *sync) -{ - *(sync->client_sync->pui32LinAddr) = sync->next_value; -} - -static inline int is_sync_prim_met(struct pvr_sync_native_sync_prim *sync) -{ - return *(sync->client_sync->pui32LinAddr) == sync->next_value; -} - -/* Checkpoint helpers */ -static inline u32 get_sync_checkpoint_value(struct pvr_sync_native_sync_checkpoint *sync) -{ - PVRSRV_SYNC_CHECKPOINT_STATE checkpoint_state = PVRSRV_SYNC_CHECKPOINT_ACTIVE; - - if (SyncCheckpointIsSignalled(sync->client_sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - checkpoint_state = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - else if (SyncCheckpointIsErrored(sync->client_sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - checkpoint_state = PVRSRV_SYNC_CHECKPOINT_ERRORED; - - return (u32)checkpoint_state; -} - -static inline char get_sync_checkpoint_char(struct pvr_sync_native_sync_checkpoint *sync) -{ - char cState = 'A'; - - if (SyncCheckpointIsSignalled(sync->client_sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - cState = 'S'; - else if (SyncCheckpointIsErrored(sync->client_sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - cState = 'E'; - - return cState; -} - -static inline void error_sync_checkpoint(struct pvr_sync_native_sync_checkpoint *sync, - u32 fence_sync_flags) -{ - SyncCheckpointError(sync->client_sync_checkpoint, fence_sync_flags); -} - -static inline void complete_sync_checkpoint(struct pvr_sync_native_sync_checkpoint *sync, - u32 fence_sync_flags) -{ - SyncCheckpointSignal(sync->client_sync_checkpoint, fence_sync_flags); -} - -static inline int is_sync_checkpoint_met(struct pvr_sync_native_sync_checkpoint *sync, - u32 fence_sync_flags) -{ - return (int)SyncCheckpointIsSignalled(sync->client_sync_checkpoint, fence_sync_flags); -} - -static inline int is_sync_checkpoint_errored(struct pvr_sync_native_sync_checkpoint *sync, - u32 fence_sync_flags) -{ - return (int)SyncCheckpointIsErrored(sync->client_sync_checkpoint, fence_sync_flags); -} - -/* Timeline helpers */ -static inline struct pvr_sync_timeline *get_timeline(struct sync_timeline *obj) -{ - return ((struct pvr_sync_timeline_wrapper *)obj)->timeline; -} - -static inline struct pvr_sync_timeline *get_timeline_pt(struct sync_pt *pt) -{ - return get_timeline(sync_pt_parent(pt)); -} - -static inline int -pvr_sync_has_kernel_signaled(struct pvr_sync_kernel_pair *kernel, u32 fence_sync_flags) -{ - /* Idle syncs are always signaled */ - if (!kernel) - return 1; - - return is_sync_checkpoint_met(kernel->fence_sync, fence_sync_flags); -} - -#ifdef DEBUG_OUTPUT - -static char *debug_info_timeline(struct pvr_sync_timeline *timeline) -{ - static char info[256]; - - if (timeline->kernel->fence_sync) { - snprintf(info, sizeof(info), - "n='%s' id=%u fw=0x%x tl_curr=%u tl_next=%u", - timeline->obj ? timeline->obj->name : "?", - timeline->kernel->fence_sync->id, - timeline->kernel->fence_sync->vaddr, - get_sync_prim_value(timeline->kernel->fence_sync), - timeline->kernel->fence_sync->next_value); - } else { - snprintf(info, sizeof(info), - "n='%s' id=n/a fw=n/a tl_curr=n/a tl_next=n/a", - timeline->obj ? timeline->obj->name : "?"); - } - - return info; -} - -static char *debug_info_sync_pt(struct sync_pt *pt) -{ - //struct pvr_sync_timeline *timeline = get_timeline_pt(pt); - //struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)pt; - //struct pvr_sync_kernel_pair *kernel = pvr_pt->sync_data->kernel; - static char info[256], info1[256]; - -#if 1 - info[0] = '\0'; - info1[0] = '\0'; -#else - if (kernel) { - if (timeline->kernel->fence_sync) { - snprintf(info, sizeof(info), - "status=%d tl_taken=%u ref=%d # sync: id=%u fw=0x%x curr=%u next=%u%s # tl: %s", - pvr_sync_has_kernel_signaled(kernel, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT), - pvr_pt->sync_data->timeline_update_value, - atomic_read(&pvr_pt->sync_data->kref.refcount), - kernel->fence_sync->id, - kernel->fence_sync->vaddr, - get_sync_prim_value(timeline->kernel->fence_sync), - kernel->fence_sync->next_value, - info1, debug_info_timeline(timeline)); - } - } else { - snprintf(info, sizeof(info), - "status=%d tl_taken=%u ref=%d # sync: idle # tl: %s", - pvr_sync_has_kernel_signaled(kernel, PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT), - pvr_pt->sync_data->timeline_update_value, - atomic_read(&pvr_pt->sync_data->kref.refcount), - debug_info_timeline(timeline)); - } -#endif - return info; -} - -#endif /* DEBUG_OUTPUT */ - -static u32 sync_pool_get_callers; -static enum PVRSRV_ERROR_TAG -sync_pool_get(struct pvr_sync_native_sync_prim **_sync, - const char *class_name, u8 type) -{ - struct pvr_sync_native_sync_prim *sync; - enum PVRSRV_ERROR_TAG error = PVRSRV_OK; - u32 sync_addr; - - mutex_lock(&sync_pool_mutex); - sync_pool_get_callers++; - - if (list_empty(&sync_pool_free_list)) { - /* If there is nothing in the pool, create a new sync prim. */ - sync = kmalloc(sizeof(*sync), - GFP_KERNEL); - if (!sync) { - pr_err("pvr_sync2: %s: Failed to allocate sync data\n", - __func__); - error = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_unlock; - } - - error = SyncPrimAlloc(pvr_sync_data.sync_prim_context, - &sync->client_sync, class_name); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to allocate sync prim (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_free; - } - - error = SyncPrimGetFirmwareAddr(sync->client_sync, &sync_addr); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to get FW address (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_sync_prim_free; - } - sync->vaddr = sync_addr; - - list_add_tail(&sync->list, &sync_pool_active_list); - ++sync_pool_created; - } else { - sync = list_first_entry(&sync_pool_free_list, - struct pvr_sync_native_sync_prim, list); - list_move_tail(&sync->list, &sync_pool_active_list); - --sync_pool_size; - ++sync_pool_reused; - } - - sync->id = atomic_inc_return(&pvr_sync_data.sync_id); - sync->type = type; - - strlcpy(sync->class, class_name, sizeof(sync->class)); - /* It's crucial to reset the sync to zero */ - set_sync_prim_value(sync, 0); - sync->next_value = 0; - - *_sync = sync; - -err_unlock: - sync_pool_get_callers--; - mutex_unlock(&sync_pool_mutex); - return error; - -err_sync_prim_free: - SyncPrimFree(sync->client_sync); - -err_free: - kfree(sync); - goto err_unlock; -} - -static u32 sync_pool_put_callers; - -static void sync_pool_put(struct pvr_sync_native_sync_prim *sync) -{ - mutex_lock(&sync_pool_mutex); - sync_pool_put_callers++; - - if (sync_pool_size < SYNC_MAX_POOL_SIZE) { - /* Mark it as unused */ - set_sync_prim_value(sync, 0xffffffff); - - list_move(&sync->list, &sync_pool_free_list); - ++sync_pool_size; - } else { - /* Mark it as invalid */ - set_sync_prim_value(sync, 0xdeadbeef); - - list_del(&sync->list); - SyncPrimFree(sync->client_sync); - kfree(sync); - } - - sync_pool_put_callers--; - mutex_unlock(&sync_pool_mutex); -} - -static void sync_pool_clear(void) -{ - struct pvr_sync_native_sync_prim *sync, *n; - - mutex_lock(&sync_pool_mutex); - - list_for_each_entry_safe(sync, n, &sync_pool_free_list, list) { - /* Mark it as invalid */ - set_sync_prim_value(sync, 0xdeadbeef); - - list_del(&sync->list); - SyncPrimFree(sync->client_sync); - kfree(sync); - --sync_pool_size; - } - - mutex_unlock(&sync_pool_mutex); -} - -static void pvr_sync_debug_request(void *hDebugRequestHandle, - u32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - struct pvr_sync_timeline *tl; - struct pvr_sync_native_sync_checkpoint *sync; - unsigned long flags; - - static const char *const type_names[] = { - "Timeline", "Fence", "Cleanup", - "Foreign Fence", "Foreign Cleanup" - }; - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_MEDIUM)) { - /* if timeline_list_lock and pvr_sync_pt_active_list_spinlock - * are acquired together timeline_list_lock must be always acquired first - */ - spin_lock_irqsave(&timeline_list_lock, flags); - spin_lock(&pvr_sync_pt_active_list_spinlock); - - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "------[ Native Fence Sync: timelines ]------"); - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "foreign timeline:\n"); - - list_for_each_entry(sync, &pvr_sync_pt_active_list, list) { - BUG_ON(sync->type >= ARRAY_SIZE(type_names)); - - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " @%u: fwaddr=%#08x enqu=%u ref=%u state=%s %s (%s)\n", - sync->id, - sync->vaddr, - SyncCheckpointGetEnqueuedCount(sync->client_sync_checkpoint), - SyncCheckpointGetReferenceCount(sync->client_sync_checkpoint), - SyncCheckpointGetStateString(sync->client_sync_checkpoint), - sync->class, - type_names[sync->type]); - } - - list_for_each_entry(tl, &timeline_list, list) { - if (tl->kernel->fence_sync) { - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "%s: @%u/%u refs=%u fwaddr=%#08x\n", - tl->obj->name, - get_sync_prim_value(tl->kernel->fence_sync), - tl->kernel->fence_sync->next_value, - refcount_read(&tl->kref.refcount), - tl->kernel->fence_sync->vaddr); - } else { - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "%s: refs=%u\n", - tl->obj->name, - refcount_read(&tl->kref.refcount)); - } - - list_for_each_entry(sync, &tl->sync_list, list) { - BUG_ON(sync->type >= ARRAY_SIZE(type_names)); - - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - " @%u: fwaddr=%#08x enq=%u ref=%u state=%s %s (%s)\n", - sync->id, - sync->vaddr, - SyncCheckpointGetEnqueuedCount(sync->client_sync_checkpoint), - SyncCheckpointGetReferenceCount(sync->client_sync_checkpoint), - SyncCheckpointGetStateString(sync->client_sync_checkpoint), - sync->class, - type_names[sync->type]); - } - } - - spin_unlock(&pvr_sync_pt_active_list_spinlock); - spin_unlock_irqrestore(&timeline_list_lock, flags); - } -} - -static struct sync_pt *pvr_sync_dup(struct sync_pt *sync_pt) -{ - struct pvr_sync_pt *pvr_pt_a = (struct pvr_sync_pt *)sync_pt; - struct pvr_sync_pt *pvr_pt_b = NULL; - - DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt)); - - pvr_pt_b = (struct pvr_sync_pt *) - sync_pt_create(sync_pt_parent(sync_pt), - sizeof(*pvr_pt_b)); - if (!pvr_pt_b) { - pr_err("pvr_sync2: %s: Failed to dup sync pt\n", __func__); - goto err_out; - } - - kref_get(&pvr_pt_a->sync_data->kref); - - pvr_pt_b->sync_data = pvr_pt_a->sync_data; - -err_out: - return (struct sync_pt *)pvr_pt_b; -} - -static int pvr_sync_has_signaled(struct sync_pt *sync_pt) -{ - struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; - - DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt)); - - return pvr_sync_has_kernel_signaled(pvr_pt->sync_data->kernel, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT); -} - -static int pvr_sync_compare(struct sync_pt *a, struct sync_pt *b) -{ - u32 a1 = ((struct pvr_sync_pt *)a)->sync_data->timeline_update_value; - u32 b1 = ((struct pvr_sync_pt *)b)->sync_data->timeline_update_value; - - DPF("%s: a # %s", __func__, debug_info_sync_pt(a)); - DPF("%s: b # %s", __func__, debug_info_sync_pt(b)); - - if (a1 == b1) - return 0; - - /* Take integer wrapping into account */ - return ((s32)a1 - (s32)b1) < 0 ? -1 : 1; -} - -static void check_for_sync_prim(struct pvr_sync_native_sync_prim *sync) -{ -#ifndef NO_HARDWARE - void *event_object; - enum PVRSRV_ERROR_TAG error = PVRSRV_OK; - - if (!sync || is_sync_prim_met(sync)) - return; - - error = OSEventObjectOpen( - pvr_sync_data.event_object_handle, - &event_object); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Error opening event object (%s)\n", - __func__, - PVRSRVGetErrorString(error)); - return; - } - - if (!is_sync_prim_met(sync)) { - /* This debug will indicate if pvr_sync is stuck waiting for a sync prim */ - pr_err("pvr_sync2: %s: sync prim<%p> %s (%d != %d)\n", - __func__, sync->client_sync, sync->class, - *(sync->client_sync->pui32LinAddr), sync->next_value); - } - - OSEventObjectClose(event_object); -#endif /* NO_HARDWARE */ -} - -static void pvr_sync_defer_free_checkpoints(struct pvr_sync_kernel_pair *kernel) -{ - unsigned long flags; - - spin_lock_irqsave(&sync_checkpoint_free_list_spinlock, flags); - list_add_tail(&kernel->list, &sync_checkpoint_free_list); - spin_unlock_irqrestore(&sync_checkpoint_free_list_spinlock, flags); - - queue_work(pvr_sync_data.defer_free_wq, &pvr_sync_data.defer_free_work); -} - -static void pvr_sync_timeline_defer_free(struct pvr_sync_timeline_kernel_pair *kernel) -{ - unsigned long flags; - - spin_lock_irqsave(&timeline_free_list_spinlock, flags); - list_add_tail(&kernel->list, &timeline_free_list); - spin_unlock_irqrestore(&timeline_free_list_spinlock, flags); - - queue_work(pvr_sync_data.defer_free_wq, &pvr_sync_data.defer_free_work); -} - -/* This function assumes the timeline_list_lock is held while it runs */ - -static void pvr_sync_destroy_timeline_locked(struct kref *kref) -{ - unsigned long flags; - struct pvr_sync_timeline *timeline = (struct pvr_sync_timeline *) - container_of(kref, struct pvr_sync_timeline, kref); - - pvr_sync_timeline_defer_free(timeline->kernel); - /* timeline_list_lock is already locked so it's safe to acquire this here */ - spin_lock_irqsave(&pvr_sync_pt_active_list_spinlock, flags); - list_del(&timeline->sync_list); - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - list_del(&timeline->list); - kfree(timeline); -} - -static void pvr_sw_sync_destroy_timeline(struct kref *kref) -{ - struct pvr_sw_sync_timeline *pvr_sw_timeline = (struct pvr_sw_sync_timeline *) - container_of(kref, struct pvr_sw_sync_timeline, kref); - struct sync_timeline *obj = (void *)pvr_sw_timeline->sw_sync_timeline; - u32 unsignalled_points = 0; - - /* signal any unsignalled points on the sw timeline */ - while (pvr_sw_timeline->current_value < pvr_sw_timeline->next_value-1) { - pvr_sync_sw_timeline_advance(pvr_sw_timeline, NULL); - unsignalled_points++; - } - - if (unsignalled_points > 0) { - pr_err("pvr_sync2: %s: signalled %d sw sync pts for timeline <%p> %s\n", - __func__, unsignalled_points, pvr_sw_timeline, obj->name); - } - - sync_timeline_destroy(obj); - kfree(pvr_sw_timeline); -} - -static void pvr_sync_release_timeline(struct sync_timeline *obj) -{ - struct pvr_sync_timeline *timeline = get_timeline(obj); - unsigned long flags; - - /* If pvr_sync_open failed after calling sync_timeline_create, this - * can be called with a timeline that has not got a timeline sync - * or been added to our timeline list. Use a NULL timeline to - * detect and handle this condition - */ - if (!timeline) - return; - - DPF("%s: # %s", __func__, debug_info_timeline(timeline)); - - if (timeline->kernel->fence_sync) - check_for_sync_prim(timeline->kernel->fence_sync); - - /* Take timeline_list_lock before clearing timeline->obj, to - * avoid the chance of doing so while the list is being iterated - * by pvr_sync_update_all_timelines(). - */ - spin_lock_irqsave(&timeline_list_lock, flags); - - /* Whether or not we're the last reference, obj is going away - * after this function returns, so remove our back reference - * to it. - */ - timeline->obj = NULL; - - /* This might be the last reference to the timeline object. - * If so, we'll go ahead and delete it now. - */ - kref_put(&timeline->kref, pvr_sync_destroy_timeline_locked); - - spin_unlock_irqrestore(&timeline_list_lock, flags); -} - -/* The print_obj() and print_pt() functions have been removed, so we're forced - * to use the timeline_value_str() and pt_value_str() functions. These are - * worse because we're limited to 64 characters, and the strings for sync - * pts have to be formatted like: - * - * pt active: pt_info / tl_info - * - * For us, the tl_info is complicated and doesn't need to be repeated over - * and over. So try to detect the way sync_print_pt() calls the two value_str - * functions and change what pvr_sync_timeline_value_str() returns dynamically. - */ -static struct sync_timeline *last_pt_timeline; - -static void pvr_sync_timeline_value_str(struct sync_timeline *sync_timeline, - char *str, int size) -{ - struct pvr_sync_timeline *timeline = get_timeline(sync_timeline); - - if (timeline->kernel->fence_sync) { - if (sync_timeline != last_pt_timeline) { - snprintf(str, size, "%u 0x%x %u/%u", - timeline->kernel->fence_sync->id, - timeline->kernel->fence_sync->vaddr, - get_sync_prim_value(timeline->kernel->fence_sync), - timeline->kernel->fence_sync->next_value); - } else { - snprintf(str, size, "%u", - get_sync_prim_value(timeline->kernel->fence_sync)); - } - } else { - snprintf(str, size, "n/a"); - } -} - -static void pvr_sync_pt_value_str(struct sync_pt *sync_pt, char *str, int size) -{ - struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; - struct pvr_sync_kernel_pair *kernel; - - if (!pvr_pt->sync_data) - return; - - kernel = pvr_pt->sync_data->kernel; - - /* Messages must be at most 64 bytes (including the null terminator): - * - * 123456789012345678901234567890123456789012345678901234567890123 - * - * ID FW ADDR C/N # REF TAKEN - * 123456 0xdeadbeef 0/1 # r=2 123456 - * - * ID FW ADDR C/N # ID FW ADDR C/N # REF TAKEN - * 123456 0xdeadbeef 0/1 # 123456 0xdeadbeef 0/1 # r=2 123456 - */ - if (kernel && kernel->fence_sync) { - snprintf(str, size, - "%u 0x%x %c e=%d r=%d %u", - kernel->fence_sync->id, - kernel->fence_sync->vaddr, - get_sync_checkpoint_char(kernel->fence_sync), - SyncCheckpointGetEnqueuedCount(kernel->fence_sync->client_sync_checkpoint), - atomic_read(&pvr_pt->sync_data->kref.refcount), - pvr_pt->sync_data->timeline_update_value); - } else { - snprintf(str, size, "idle # r=%d %u", - atomic_read(&pvr_pt->sync_data->kref.refcount), - pvr_pt->sync_data->timeline_update_value); - } - - last_pt_timeline = sync_pt_parent(sync_pt); -} - -/* pvr_sync_create_sync_data() should be called with the bridge lock held */ -static struct pvr_sync_data * -pvr_sync_create_sync_data(struct pvr_sync_timeline *timeline, - const s32 timeline_fd, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - const char *pt_name) -{ - struct pvr_sync_data *sync_data = NULL; - enum PVRSRV_ERROR_TAG error; - unsigned long flags; - - sync_data = kzalloc(sizeof(*sync_data), GFP_KERNEL); - if (!sync_data) - goto err_out; - - kref_init(&sync_data->kref); - - sync_data->kernel = - kzalloc(sizeof(*sync_data->kernel), - GFP_KERNEL); - - if (!sync_data->kernel) - goto err_free_data; - - INIT_LIST_HEAD(&sync_data->kernel->list); - - sync_data->kernel->fence_sync = - kzalloc(sizeof(struct pvr_sync_native_sync_checkpoint), GFP_KERNEL); - if (!sync_data->kernel->fence_sync) - goto err_free_kernel; - INIT_LIST_HEAD(&sync_data->kernel->fence_sync->list); - - error = SyncCheckpointAlloc(psSyncCheckpointContext, - (PVRSRV_TIMELINE)timeline_fd, - PVRSRV_NO_FENCE, - pt_name, - &sync_data->kernel->fence_sync->client_sync_checkpoint); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to allocate sync checkpoint (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_free_fence; - } - - sync_data->kernel->fence_sync->foreign_sync_fence = NULL; - sync_data->kernel->fence_sync->foreign_sync_fence_name[0] = '\0'; - - sync_data->kernel->fence_sync->vaddr = - SyncCheckpointGetFirmwareAddr(sync_data->kernel->fence_sync->client_sync_checkpoint); - sync_data->kernel->fence_sync->id = - SyncCheckpointGetId(sync_data->kernel->fence_sync->client_sync_checkpoint); - sync_data->kernel->fence_sync->type = SYNC_PT_FENCE_TYPE; - strlcpy(sync_data->kernel->fence_sync->class, pt_name, - sizeof(sync_data->kernel->fence_sync->class)); - - /* Update list (for debug ) */ - spin_lock_irqsave(&pvr_sync_pt_active_list_spinlock, flags); - list_add_tail(&sync_data->kernel->fence_sync->list, &timeline->sync_list); - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - -err_out: - return sync_data; - -err_free_fence: - kfree(sync_data->kernel->fence_sync); -err_free_kernel: - kfree(sync_data->kernel); -err_free_data: - kfree(sync_data); - sync_data = NULL; - goto err_out; -} - -static void pvr_sync_free_sync_data(struct kref *kref) -{ - struct pvr_sync_data *sync_data = (struct pvr_sync_data *) - container_of(kref, struct pvr_sync_data, kref); - - if (sync_data->kernel) - pvr_sync_defer_free_checkpoints(sync_data->kernel); - - kfree(sync_data); -} - -static void pvr_sync_free_sync(struct sync_pt *sync_pt) -{ - struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; - - DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt)); - - kref_put(&pvr_pt->sync_data->kref, pvr_sync_free_sync_data); -} - -/* this function uses pvr_sync_timeline_ops defined below */ -static int pvr_sync_fill_driver_data(struct sync_pt *, void *, int); - -static struct sync_timeline_ops pvr_sync_timeline_ops = { - .driver_name = PVRSYNC_MODNAME, - .dup = pvr_sync_dup, - .has_signaled = pvr_sync_has_signaled, - .compare = pvr_sync_compare, - .free_pt = pvr_sync_free_sync, - .release_obj = pvr_sync_release_timeline, - .timeline_value_str = pvr_sync_timeline_value_str, - .pt_value_str = pvr_sync_pt_value_str, - .fill_driver_data = pvr_sync_fill_driver_data, -}; - -static inline bool is_pvr_timeline(struct sync_timeline *obj) -{ - return obj->ops == &pvr_sync_timeline_ops; -} - -static inline bool is_pvr_timeline_pt(struct sync_pt *pt) -{ - return is_pvr_timeline(sync_pt_parent(pt)); -} - -static int -pvr_sync_fill_driver_data(struct sync_pt *sync_pt, void *data, int size) -{ - struct pvr_sync_pt_info *info = (struct pvr_sync_pt_info *)data; - struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; - struct pvr_sync_data *sync_data = pvr_pt->sync_data; - struct pvr_sync_kernel_pair *kernel = sync_data->kernel; - - if (size < sizeof(*info)) - return -ENOMEM; - - info->ui32TlTaken = sync_data->timeline_update_value; - - if (kernel && kernel->fence_sync) { - info->id = kernel->fence_sync->id; - info->ui32FWAddr = kernel->fence_sync->vaddr; - info->ui32CurrOp = get_sync_checkpoint_value(kernel->fence_sync); - info->ui32NextOp = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - } else { - info->id = 0; - info->ui32FWAddr = 0; - info->ui32CurrOp = 0; - info->ui32NextOp = 0; - } - - return sizeof(*info); -} - -/* foreign sync handling */ - -static void pvr_sync_foreign_sync_pt_signaled(struct sync_fence *fence, - struct sync_fence_waiter *_waiter) -{ - struct pvr_sync_fence_waiter *waiter = - (struct pvr_sync_fence_waiter *)_waiter; - unsigned long flags; - - /* Complete the SW operation and free the sync if we can. If we can't, - * it will be checked by a later workqueue kick. - */ - if (is_sync_checkpoint_errored(waiter->kernel->fence_sync, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT) || - !is_sync_checkpoint_met(waiter->kernel->fence_sync, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) { - - if (!is_sync_checkpoint_met(waiter->kernel->fence_sync, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - complete_sync_checkpoint(waiter->kernel->fence_sync, - PVRSRV_FENCE_FLAG_CTX_ATOMIC); - - /* We can 'put' the fence now, but this function might be called in - * irq context so we must defer to WQ. - * This WQ is triggered in pvr_sync_defer_free, so adding it to the - * put list before that should guarantee it's cleaned up on the next - * wq run. - */ - spin_lock_irqsave(&sync_fence_put_list_spinlock, flags); - list_add_tail(&waiter->sync_fence->list, &sync_fence_put_list); - spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags); - - pvr_sync_defer_free_checkpoints(waiter->kernel); - - /* The completed sw-sync may allow other tasks to complete, - * so we need to allow them to progress. - */ - queue_work(NativeSyncGetFenceStatusWq(), - &pvr_sync_data.check_status_work); - - kfree(waiter); - } else { - pr_err("pvr_sync2: %s: this sync checkpoint has already been signalled - " - "why are we asked to do this more than once?!\n", __func__); - } -} - -static PSYNC_CHECKPOINT -pvr_sync_create_waiter_for_foreign_sync(int fd, PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext) -{ - struct pvr_sync_kernel_pair *kernel = NULL; - struct pvr_sync_fence_waiter *waiter; - struct pvr_sync_fence *sync_fence; - PSYNC_CHECKPOINT checkpoint = NULL; - struct sync_fence *fence; - enum PVRSRV_ERROR_TAG error; - int err; - unsigned long flags; - - fence = sync_fence_fdget(fd); - if (!fence) { - pr_err("pvr_sync2: %s: Failed to take reference on fence\n", - __func__); - goto err_out; - } - - kernel = kmalloc(sizeof(*kernel), GFP_KERNEL); - if (!kernel) { - pr_err("pvr_sync2: %s: Failed to allocate sync kernel\n", - __func__); - goto err_put_fence; - } - - sync_fence = kmalloc(sizeof(*sync_fence), GFP_KERNEL); - if (!sync_fence) { - pr_err("pvr_sync2: %s: Failed to allocate pvr sync fence\n", - __func__); - goto err_free_kernel; - } - - sync_fence->fence = fence; - - kernel->fence_sync = kzalloc(sizeof(struct pvr_sync_native_sync_checkpoint), GFP_KERNEL); - if (!kernel->fence_sync) - goto err_free_fence; - - INIT_LIST_HEAD(&kernel->fence_sync->list); - - /* Create sync checkpoint for the foreign sync, with an invalid - * timeline (as we do not know it) - */ - error = SyncCheckpointAlloc(psSyncCheckpointContext, - SYNC_CHECKPOINT_FOREIGN_CHECKPOINT, - fd, /* fence_to_resolve */ - fence->name, - &checkpoint); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to allocate sync checkpoint (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_free_fence_sync; - } - kernel->fence_sync->client_sync_checkpoint = checkpoint; - - kernel->fence_sync->foreign_sync_fence = fence; - strlcpy(kernel->fence_sync->foreign_sync_fence_name, - fence->name, - sizeof(kernel->fence_sync->foreign_sync_fence_name)); - - kernel->fence_sync->vaddr = - SyncCheckpointGetFirmwareAddr(kernel->fence_sync->client_sync_checkpoint); - kernel->fence_sync->id = - SyncCheckpointGetId(kernel->fence_sync->client_sync_checkpoint); - kernel->fence_sync->type = SYNC_PT_FOREIGN_FENCE_TYPE; - strlcpy(kernel->fence_sync->class, fence->name, sizeof(kernel->fence_sync->class)); - - /* The custom waiter structure is freed in the waiter callback */ - waiter = kmalloc(sizeof(*waiter), GFP_KERNEL); - if (!waiter) { - pr_err("pvr_sync2: %s: Failed to allocate waiter\n", __func__); - goto err_free_cleanup_sync; - } - - waiter->kernel = kernel; - waiter->sync_fence = sync_fence; - - /* Take an extra ref on the checkpoint for the reference handed over to - * the firmware. - * This must be done before the waiter_init, as the waiter can be called - * and it's reference dropped at _any time_ - */ - SyncCheckpointTakeRef(checkpoint); - - sync_fence_waiter_init(&waiter->waiter, - pvr_sync_foreign_sync_pt_signaled); - - spin_lock_irqsave(&pvr_sync_pt_active_list_spinlock, flags); - err = sync_fence_wait_async(fence, &waiter->waiter); - if (err) { - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - /* -1 means the fence was broken, 1 means the fence already - * signalled. In either case, roll back what we've done and - * skip using this sync_pt for synchronisation. - */ - goto err_put_checkpoint_ref; - } - - /* Update list (for debug ) */ - list_add_tail(&kernel->fence_sync->list, &pvr_sync_pt_active_list); - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - -err_out: - return checkpoint; -err_put_checkpoint_ref: - SyncCheckpointDropRef(checkpoint); - kfree(waiter); -err_free_cleanup_sync: - SyncCheckpointFree(checkpoint); - checkpoint = NULL; -err_free_fence_sync: - kfree(kernel->fence_sync); - kernel->fence_sync = NULL; -err_free_fence: - kfree(sync_fence); - sync_fence = NULL; -err_free_kernel: - kfree(kernel); - kernel = NULL; -err_put_fence: - sync_fence_put(fence); - goto err_out; -} - -static -struct pvr_sync_pt *pvr_sync_create_pt(struct pvr_sync_timeline *timeline, - const s32 timeline_fd, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - const char *pt_name) -{ - struct pvr_sync_data *sync_data; - struct pvr_sync_pt *pvr_pt = NULL; - - sync_data = pvr_sync_create_sync_data(timeline, timeline_fd, - psSyncCheckpointContext, pt_name); - if (!sync_data) { - pr_err("pvr_sync2: %s: Failed to create sync data\n", __func__); - goto err_out; - } - - pvr_pt = (struct pvr_sync_pt *) - sync_pt_create(timeline->obj, sizeof(struct pvr_sync_pt)); - if (!pvr_pt) { - pr_err("pvr_sync2: %s: Failed to create sync pt\n", __func__); - goto err_rollback_fence; - } - - pvr_pt->sync_data = sync_data; - - pvr_pt->timeline = timeline; - - /* Increment the timeline next value */ - pvr_pt->sync_data->timeline_update_value = - timeline->kernel->fence_sync->next_value++; - - return pvr_pt; - -err_rollback_fence: - /* Error the sync checkpoint (so the deferred free considers it 'met') */ - error_sync_checkpoint(sync_data->kernel->fence_sync, PVRSRV_FENCE_FLAG_NONE); - kref_put(&sync_data->kref, pvr_sync_free_sync_data); -err_out: - return NULL; -} - -int pvr_sync_api_init(void *file_handle, void **api_priv) -{ - struct pvr_sync_timeline_wrapper *timeline_wrapper; - struct pvr_sync_timeline *timeline; - char task_comm[TASK_COMM_LEN]; - unsigned long flags; - - get_task_comm(task_comm, current); - - timeline_wrapper = (struct pvr_sync_timeline_wrapper *) - sync_timeline_create(&pvr_sync_timeline_ops, - sizeof(*timeline_wrapper), task_comm); - if (!timeline_wrapper) { - pr_err("pvr_sync2: %s: sync_timeline_create failed\n", __func__); - goto err_out; - } - - timeline = kmalloc(sizeof(*timeline), GFP_KERNEL); - if (!timeline) { - pr_err("pvr_sync2: %s: Out of memory\n", __func__); - goto err_free_timeline_wrapper; - } - - timeline->kernel = kzalloc(sizeof(*timeline->kernel), - GFP_KERNEL); - if (!timeline->kernel) { - pr_err("pvr_sync2: %s: Out of memory\n", __func__); - goto err_free_timeline; - } - - timeline_wrapper->timeline = timeline; - - timeline->obj = &timeline_wrapper->obj; - kref_init(&timeline->kref); - INIT_LIST_HEAD(&timeline->sync_list); - - spin_lock_irqsave(&timeline_list_lock, flags); - list_add_tail(&timeline->list, &timeline_list); - spin_unlock_irqrestore(&timeline_list_lock, flags); - - DPF("%s: # %s", __func__, debug_info_timeline(timeline)); - - *api_priv = (void *)timeline_wrapper; - - return 0; - -err_free_timeline: - kfree(timeline); - - /* Use a NULL timeline to detect this partially-setup timeline in the - * timeline release function (called by sync_timeline_destroy) and - * handle it appropriately. - */ - timeline_wrapper->timeline = NULL; -err_free_timeline_wrapper: - sync_timeline_destroy(&timeline_wrapper->obj); -err_out: - return -ENOMEM; -} - -int pvr_sync_api_deinit(void *api_priv, bool is_sw) -{ - if (!api_priv) - return 0; - - if (!is_sw) { - struct sync_timeline *obj = api_priv; - - DPF("%s: # %s", __func__, - debug_info_timeline(get_timeline(obj))); - - sync_timeline_destroy(obj); - } else { - struct pvr_sw_sync_timeline *pvr_sw_sync_timeline = api_priv; - - /* SW timeline */ - kref_put(&pvr_sw_sync_timeline->kref, pvr_sw_sync_destroy_timeline); - } - return 0; -} - -/* - * This is the function that kick code will call in order to 'finalise' a - * created output fence just prior to returning from the kick function. - * The OS native sync code needs to implement a function meeting this - * specification - the implementation may be a nop if the OS does not need - * to perform any actions at this point. - * - * Input: fence_fd The PVRSRV_FENCE to be 'finalised'. This value - * will have been returned by an earlier call to - * pvr_sync_create_fence(). - * Input: finalise_data The finalise data returned by an earlier call - * to pvr_sync_create_fence(). - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_finalise_fence(PVRSRV_FENCE fence_fd, void *finalise_data) -{ - struct sync_fence *native_fence = (struct sync_fence *)finalise_data; - - if (!native_fence || (fence_fd < 0)) - return PVRSRV_ERROR_INVALID_PARAMS; - - sync_fence_install(native_fence, fence_fd); - return PVRSRV_OK; -} - -/* - * This is the function that kick code will call in order to obtain a new - * PVRSRV_FENCE from the OS native sync code and the PSYNC_CHECKPOINT used - * in that fence. The OS native sync code needs to implement a function - * meeting this specification. - * - * Input: device Not currently used. - * Input: fence_name A string to annotate the fence with (for - * debug). - * Input: timeline The timeline on which the new fence is to be - * created. - * Output: new_fence The new PVRSRV_FENCE to be returned by the - * kick call. - * Output: fence_uid Unique ID of the update fence. - * Output: fence_finalise_data Pointer to data needed to finalise the fence. - * Output: new_checkpoint_handle The PSYNC_CHECKPOINT used by the new fence. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_create_fence(struct _PVRSRV_DEVICE_NODE_ *device, - const char *fence_name, - PVRSRV_TIMELINE new_fence_timeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *new_fence, - u64 *fence_uid, - void **fence_finalise_data, - PSYNC_CHECKPOINT *new_checkpoint_handle, - void **timeline_update_sync, - __u32 *timeline_update_value) -{ - PVRSRV_ERROR err; - PVRSRV_FENCE new_fence_fd = -1; - struct file *timeline_file; - struct sync_timeline *obj; - struct pvr_sync_timeline *timeline; - struct pvr_sync_pt *native_sync_point = NULL; - struct sync_fence *native_fence = NULL; - struct pvr_sync_kernel_pair *sync_kernel; - - if (new_fence_timeline < 0 || !new_fence || - !new_checkpoint_handle || !fence_finalise_data) { - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - /* We reserve the new fence FD before taking any operations - * as we do not want to fail (e.g. run out of FDs) - */ - new_fence_fd = get_unused_fd_flags(O_CLOEXEC); - if (new_fence_fd < 0) { - err = PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - goto err_out; - } - - timeline_file = fget(new_fence_timeline); - if (!timeline_file) { - pr_err("pvr_sync2: %s: Failed to open supplied timeline fd (%d)\n", - __func__, new_fence_timeline); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_fd; - } - - obj = pvr_sync_get_api_priv(timeline_file); - if (!obj) { - pr_err("pvr_sync2: %s: Supplied timeline not pvr_sync timeline\n", - __func__); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_timeline; - } - - timeline = get_timeline(obj); - if (!timeline) { - pr_err("pvr_sync2: %s: Supplied timeline has no private data\n", - __func__); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_timeline; - } - - /* Check if this timeline already has a sync prim, if not create it now */ - if (!timeline->kernel->fence_sync) { - err = sync_pool_get(&timeline->kernel->fence_sync, - timeline->obj->name, - SYNC_TL_TYPE); - - if (err != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to allocate timeline sync prim (%s)\n", - __func__, PVRSRVGetErrorString(err)); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_timeline; - } - } - - native_sync_point = pvr_sync_create_pt(timeline, new_fence_timeline, - psSyncCheckpointContext, fence_name); - if (!native_sync_point) { - pr_err("pvr_sync2: %s: Failed to create sync point\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_timeline; - } - - native_fence = sync_fence_create(fence_name, &native_sync_point->pt); - if (!native_fence) { - struct pvr_sync_native_sync_prim *timeline_prim = - timeline->kernel->fence_sync; - - pr_err("pvr_sync2: %s: Failed to create sync fence\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - - /* If the point was created but the fence failed to be - * created, the point must be manually freed as a - * fence has not yet taken ownership. - */ - timeline_prim->next_value--; - /* Error the new fence's sync checkpoint - * (so the deferred free considers it 'met') - */ - error_sync_checkpoint(native_sync_point->sync_data->kernel->fence_sync, - PVRSRV_FENCE_FLAG_NONE); - pvr_sync_free_sync(&native_sync_point->pt); - goto err_put_timeline; - } - - sync_kernel = native_sync_point->sync_data->kernel; - - /* For Linux, we do not return the fence fd here, but via - * pvr_sync_finalise_fence() - this is because once we - * associate the fd with the fence, it can only be closed - * from client code so it should only be done once we - * know we will definitely require it. - */ - *new_fence = new_fence_fd; - *fence_finalise_data = (void *)native_fence; - *new_checkpoint_handle = sync_kernel->fence_sync->client_sync_checkpoint; - - if (timeline_update_sync && timeline_update_value) { - *timeline_update_sync = (void *)timeline->kernel->fence_sync->client_sync; - *timeline_update_value = timeline->kernel->fence_sync->next_value; - } - - *fence_uid = OSGetCurrentClientProcessIDKM(); - *fence_uid = (*fence_uid << 32) | (new_fence_fd & U32_MAX); - - fput(timeline_file); - - return PVRSRV_OK; - -err_put_timeline: - fput(timeline_file); -err_put_fd: - pr_err("pvr_sync2: %s: putting fd %d back to unused\n", __func__, new_fence_fd); - put_unused_fd(new_fence_fd); - *fence_uid = PVRSRV_NO_FENCE; -err_out: - return err; -} - -/* - * This is the function that kick code will call in order to 'rollback' a - * created output fence should an error occur when submitting the kick. - * The OS native sync code needs to implement a function meeting this - * specification. - * - * Input: fence_to_rollback The PVRSRV_FENCE to be 'rolled back'. The fence - * should be destroyed and any actions taken due to - * its creation that need to be undone should be - * reverted. - * Input: finalise_data The finalise data for the fence to be 'rolled back'. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_rollback_fence_data(PVRSRV_FENCE fence_to_rollback, - void *fence_data_to_rollback) -{ - PVRSRV_ERROR err = PVRSRV_OK; - struct sync_fence *sync_fence = (struct sync_fence *)fence_data_to_rollback; - struct sync_pt *sync_pt; - struct pvr_sync_pt *pvr_pt = NULL; - int j = 0; - - if (!sync_fence) { - pr_err("pvr_sync2: %s: Failed to recognise fence_to_rollback(%d)\n", - __func__, fence_to_rollback); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - (void)j; - for_each_sync_pt(sync_pt, sync_fence, j) { - if (!is_pvr_timeline_pt(sync_pt)) { - pr_err("pvr_sync2: %s: Fence(%d) contains non-pvr timeline sync_pt\n", - __func__, fence_to_rollback); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out2; - } - - pvr_pt = (struct pvr_sync_pt *)sync_pt; - - SyncCheckpointError(pvr_pt->sync_data->kernel->fence_sync->client_sync_checkpoint, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT); - - /* rollback timeline next_value */ - pvr_pt->timeline->kernel->fence_sync->next_value--; - } - - /* close the fence */ - sync_fence_put(sync_fence); - -err_out2: - put_unused_fd(fence_to_rollback); - -err_out: - return err; -} - -/* - * This is the function that kick code will call in order to obtain a list of - * the PSYNC_CHECKPOINTs for a given PVRSRV_FENCE passed to a kick function. - * The OS native sync code will allocate the memory to hold the returned list - * of PSYNC_CHECKPOINT ptrs. The caller will free this memory once it has - * finished referencing it. - * - * Input: fence The input (check) fence - * Output: nr_checkpoints The number of PVRSRV_SYNC_CHECKPOINT ptrs - * returned in the checkpoint_handles - * parameter. - * Output: fence_uid Unique ID of the check fence - * Input/Output: checkpoint_handles The returned list of PVRSRV_SYNC_CHECKPOINTs. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_resolve_fence(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE fence_to_resolve, u32 *nr_checkpoints, - PSYNC_CHECKPOINT **checkpoint_handles, u64 *fence_uid) -{ - PVRSRV_ERROR err = PVRSRV_OK; - - if (!nr_checkpoints || !checkpoint_handles) { - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - if (fence_to_resolve < 0) { - /* Null fence passed, so return 0 checkpoints */ - *nr_checkpoints = 0; - *checkpoint_handles = NULL; - *fence_uid = 0; - } else { - struct sync_fence *sync_fence = sync_fence_fdget(fence_to_resolve); - struct sync_pt *sync_pt; - struct pvr_sync_kernel_pair *sync_kernel; - u32 points_on_fence = 0; - PSYNC_CHECKPOINT foreign_checkpoint = NULL; - PSYNC_CHECKPOINT *next_checkpoint; - bool add_foreign_sync = true; - int j = 0; - - if (!sync_fence) { - pr_err("pvr_sync2: %s: Failed to read sync private data for fd %d\n", - __func__, fence_to_resolve); - err = PVRSRV_ERROR_HANDLE_NOT_FOUND; - goto err_out; - } - - /* Alloc memory to hold list of PSYNC_CHECKPOINTs */ - /* (Alloc memory for MAX_SYNC_CHECKPOINTS_PER_FENCE sync checkpoint handles) */ - *checkpoint_handles = - kmalloc_array(MAX_SYNC_CHECKPOINTS_PER_FENCE, - sizeof(PSYNC_CHECKPOINT), GFP_KERNEL); - if (!(*checkpoint_handles)) { - pr_err("pvr_sync2: %s: Failed to alloc memory for returned list of sync checkpoints\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_out2; - } - - next_checkpoint = *checkpoint_handles; - - (void)j; - for_each_sync_pt(sync_pt, sync_fence, j) { - struct pvr_sync_pt *pvr_pt = NULL; - - /* Make sure that we do not overrun the memory we allocated */ - if (points_on_fence >= MAX_SYNC_CHECKPOINTS_PER_FENCE) { - pr_err("pvr_sync2: Maximum number of sync checkpoints in a fence exceeded (greater than %d)", - MAX_SYNC_CHECKPOINTS_PER_FENCE); - err = PVRSRV_ERROR_INVALID_PARAMS; - - for (j = 0; j < points_on_fence; j++) - SyncCheckpointDropRef((*checkpoint_handles)[j]); - - kfree(*checkpoint_handles); - goto err_out2; - } - - if (is_pvr_timeline_pt(sync_pt)) { - pvr_pt = (struct pvr_sync_pt *)sync_pt; - sync_kernel = pvr_pt->sync_data->kernel; - - if (!sync_kernel || - is_sync_checkpoint_met(sync_kernel->fence_sync, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) { - continue; - } - - /* Take ref on sync_checkpoint - this will be dropped by the - * caller (Kick code) once it has incremented the checkpoint's - * CCB enqueued count. We only really need to do this for - * foreign sync checkpoints, to prevent the sync_checkpoint - * from being destroyed if it gets signalled while being processed - * by the Kick code, but the Kick code has no knowledge of whether a - * sync_checkpoint is foreign, so we take a ref on all checkpoints. - */ - SyncCheckpointTakeRef(sync_kernel->fence_sync->client_sync_checkpoint); - - *next_checkpoint = sync_kernel->fence_sync->client_sync_checkpoint; - next_checkpoint++; - points_on_fence++; - } else if (add_foreign_sync) { - foreign_checkpoint = pvr_sync_create_waiter_for_foreign_sync(fence_to_resolve, psSyncCheckpointContext); - - if (foreign_checkpoint) { - /* Take ref on sync_checkpoint - this will be dropped - * by the caller (see comment for the other call to - * SyncCheckpointTakeRef, above). - */ - /* For foreign points, an extra - * checkpoint reference was taken at - * creation time to ensure it wasn't - * completed and free'd before we got - * here, so ownership of that reference - * is effectively passed to the firmware - */ - *next_checkpoint = foreign_checkpoint; - next_checkpoint++; - points_on_fence++; - add_foreign_sync = false; - } - } - } - - if (0) { - int ii; - - pr_err("pvr_sync2: %s: returning nr_checkpoints=%d\n", - __func__, points_on_fence); - for (ii = 0; ii < points_on_fence; ii++) { - PSYNC_CHECKPOINT *psTmp = *(checkpoint_handles + ii); - - pr_err("pvr_sync2: %s: pt %d: sync checkpoint <%p>,\n", - __func__, ii, psTmp); - pr_err("pvr_sync2: %s: ID=%d\n", - __func__, SyncCheckpointGetId(*psTmp)); - } - } - *nr_checkpoints = points_on_fence; - *fence_uid = OSGetCurrentClientProcessIDKM(); - *fence_uid = (*fence_uid << 32) | (fence_to_resolve & U32_MAX); - -err_out2: - sync_fence_put(sync_fence); - } - -err_out: - return err; -} - -#if defined(PDUMP) -static enum PVRSRV_ERROR_TAG -pvr_sync_fence_get_checkpoints(PVRSRV_FENCE fence_to_pdump, u32 *nr_checkpoints, - struct SYNC_CHECKPOINT_TAG ***checkpoint_handles) -{ - enum PVRSRV_ERROR_TAG err; - struct sync_fence *sync_fence; - struct sync_pt *sync_pt; - struct pvr_sync_kernel_pair *sync_kernel; - u32 points_on_fence = 0; - struct SYNC_CHECKPOINT_TAG **next_checkpoint; - struct SYNC_CHECKPOINT_TAG **checkpoints = NULL; - int j = 0; - - if (!nr_checkpoints || !checkpoint_handles) { - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - if (fence_to_pdump < 0) { - /* Null fence passed, so return 0 checkpoints */ - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - sync_fence = sync_fence_fdget(fence_to_pdump); - if (!sync_fence) { - pr_err("pvr_sync2: %s: Failed to read sync private data for fd %d\n", - __func__, fence_to_pdump); - err = PVRSRV_ERROR_HANDLE_NOT_FOUND; - goto err_out; - } - - /* Alloc memory to hold list of PSYNC_CHECKPOINTs */ - checkpoints = kmalloc_array(MAX_SYNC_CHECKPOINTS_PER_FENCE, - sizeof(*checkpoints), GFP_KERNEL); - if (!checkpoints) { - pr_err("pvr_sync2: %s: Failed to alloc memory for returned list of sync checkpoints\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_fence; - } - - next_checkpoint = checkpoints; - - (void)j; - for_each_sync_pt(sync_pt, sync_fence, j) { - struct pvr_sync_pt *pvr_pt = NULL; - - /* Make sure that we do not overrun the memory we allocated */ - if (points_on_fence >= MAX_SYNC_CHECKPOINTS_PER_FENCE) { - pr_err("pvr_sync2: Maximum number of sync checkpoints in a fence exceeded (greater than %d)", - MAX_SYNC_CHECKPOINTS_PER_FENCE); - err = PVRSRV_ERROR_INVALID_PARAMS; - kfree(*checkpoint_handles); - goto err_put_fence; - } - - if (is_pvr_timeline_pt(sync_pt)) { - pvr_pt = (struct pvr_sync_pt *)sync_pt; - sync_kernel = pvr_pt->sync_data->kernel; - if (!sync_kernel) - continue; - *next_checkpoint = sync_kernel->fence_sync->client_sync_checkpoint; - next_checkpoint++; - points_on_fence++; - } - } - - *checkpoint_handles = checkpoints; - *nr_checkpoints = points_on_fence; - err = PVRSRV_OK; -err_put_fence: - sync_fence_put(sync_fence); -err_out: - return err; - -} -#endif - -static u32 -pvr_sync_dump_info_on_stalled_ufos(u32 nr_ufos, u32 *vaddrs) -{ - u32 our_ufo_ct = 0; - struct pvr_sync_native_sync_checkpoint *sync; - unsigned long flags; - - spin_lock_irqsave(&pvr_sync_pt_active_list_spinlock, flags); - /* dump info on any ufos in our active list */ - list_for_each_entry(sync, &pvr_sync_pt_active_list, list) { - u32 *this_ufo_vaddr = vaddrs; - u32 ufo_num; - DUMPDEBUG_PRINTF_FUNC *pfnDummy = NULL; - - for (ufo_num = 0; ufo_num < nr_ufos; ufo_num++, this_ufo_vaddr++) { - if (sync->vaddr == *this_ufo_vaddr) { - static const char *const type_names[] = { - "Timeline", "Fence", "Cleanup", - "Foreign Fence", "Foreign Cleanup" - }; - - /* Dump sync info */ - PVR_DUMPDEBUG_LOG(pfnDummy, NULL, - "\tSyncID = %d, FWAddr = 0x%08x: %s (%s - [%p] %s)", - sync->id, sync->vaddr, - sync->class, - type_names[sync->type], - sync->foreign_sync_fence, - sync->foreign_sync_fence_name); - our_ufo_ct++; - } - } - } - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - return our_ufo_ct; -} - -int pvr_sync_api_rename(void *api_priv, void *user_data) -{ - struct sync_timeline *obj = api_priv; - struct pvr_sync_timeline *timeline = get_timeline(obj); - struct pvr_sync_rename_ioctl_data *data = user_data; - - data->szName[sizeof(data->szName) - 1] = '\0'; - strlcpy(timeline->obj->name, data->szName, sizeof(timeline->obj->name)); - - return 0; -} - -int pvr_sync_api_force_sw_only(void *api_priv, void **api_priv_new) -{ - struct sync_timeline *obj = api_priv; - struct pvr_sync_timeline *timeline = get_timeline(obj); - struct pvr_sw_sync_timeline *pvr_sw_sync_timeline; - - /* We can only convert an empty GPU timeline */ - if (timeline->kernel->fence_sync && - timeline->kernel->fence_sync->next_value) { - pr_err("pvr_sync2: %s ERROR! timeline->kernel->fence_sync=<%p>, timeline->kernel->fence_sync->next_value=%d\n", - __func__, timeline->kernel->fence_sync, - timeline->kernel->fence_sync->next_value); - return -EFAULT; - } - - /* Create a pvr_sw_sync timeline */ - pvr_sw_sync_timeline = kmalloc(sizeof(*pvr_sw_sync_timeline), GFP_KERNEL); - if (!pvr_sw_sync_timeline) { - pr_err("pvr_sync2: %s ERROR! no memory to allocate pvr_sw_sync_timeline struct\n", - __func__); - return -ENOMEM; - } - - pvr_sw_sync_timeline->current_value = 0; - pvr_sw_sync_timeline->next_value = 1; - kref_init(&pvr_sw_sync_timeline->kref); - - /* Create a sw_sync timeline with the old GPU timeline's name */ - pvr_sw_sync_timeline->sw_sync_timeline = sw_sync_timeline_create(timeline->obj->name); - if (!pvr_sw_sync_timeline->sw_sync_timeline) { - pr_err("pvr_sync2: %s ERROR! error returned from sw_sync_timeline_create() for timeline->obj->name '%s'\n", - __func__, timeline->obj->name); - kfree(pvr_sw_sync_timeline); - return -ENOMEM; - } - - /* Destroy the old GPU timeline and update the struct file */ - DPF("%s: # %s", __func__, debug_info_timeline(timeline)); - - sync_timeline_destroy(timeline->obj); - DPF("%s pvr_sw_sync_timeline<%p>, sw_sync_timeline<%p> curr=%llu,next=%llu", - pvr_sw_sync_timeline, - pvr_sw_sync_timeline->sw_sync_timeline, - pvr_sw_sync_timeline->current_value, - pvr_sw_sync_timeline->next_value); - - *api_priv_new = (void *)pvr_sw_sync_timeline; - - return 0; -} - -int pvr_sync_api_sw_create_fence(void *api_priv, void *user_data) -{ - struct pvr_sw_sync_timeline *pvr_sw_timeline = api_priv; - struct pvr_sw_sync_create_fence_data *data = user_data; - struct sync_fence *fence; - int fd = get_unused_fd_flags(O_CLOEXEC); - struct sync_pt *sync_pt; - struct sw_sync_timeline *timeline; - int err; - - if (fd < 0) { - pr_err("pvr_sync2: %s: Failed to find unused fd (%d)\n", - __func__, fd); - err = -EMFILE; - goto err_out; - } - - timeline = pvr_sw_timeline->sw_sync_timeline; - - sync_pt = sw_sync_pt_create(timeline, pvr_sw_timeline->next_value); - if (!sync_pt) { - pr_err("pvr_sync2: %s: Failed to create a sync point (%d)\n", - __func__, fd); - err = -ENOMEM; - goto err_put_fd; - } - - data->name[sizeof(data->name) - 1] = '\0'; - fence = sync_fence_create(data->name, sync_pt); - if (!fence) { - pr_err("pvr_sync2: %s: Failed to create a fence (%d)\n", - __func__, fd); - sync_pt_free(sync_pt); - err = -ENOMEM; - goto err_put_fd; - } - - data->fence = fd; - data->sync_pt_idx = pvr_sw_timeline->next_value; - - sync_fence_install(fence, fd); - pvr_sw_timeline->next_value++; - - return 0; - -err_put_fd: - pr_err("pvr_sync2: %s: putting fd %d back to unused\n", __func__, fd); - put_unused_fd(fd); -err_out: - return err; -} - -int pvr_sync_api_sw_inc(void *api_priv, void *user_data) -{ - struct pvr_sw_sync_timeline *pvr_timeline = api_priv; - struct sw_sync_timeline *timeline; - struct pvr_sw_timeline_advance_data *data = user_data; - - timeline = pvr_timeline->sw_sync_timeline; - - /* Don't allow sw timeline to be advanced beyond the last defined point */ - if (pvr_timeline->current_value == (pvr_timeline->next_value-1)) { - pr_err("pvr_sync2: attempt to advance SW timeline beyond last defined point\n"); - return -EPERM; - } - - sw_sync_timeline_inc(timeline, 1); - pvr_timeline->current_value++; - data->sync_pt_idx = pvr_timeline->current_value; - - return 0; -} - -static void -pvr_sync_check_status_work_queue_function(struct work_struct *data) -{ - /* A completed SW operation may un-block the GPU */ - PVRSRVCheckStatus(NULL); -} - -/* Returns true if the freelist still has entries, else false if empty */ -static bool -pvr_sync_clean_freelist(void) -{ - struct pvr_sync_kernel_pair *kernel, *k; - struct pvr_sync_timeline_kernel_pair *tl_kernel, *tl_k; - struct pvr_sync_fence *sync_fence, *f; - LIST_HEAD(unlocked_free_checkpoint_list); - LIST_HEAD(unlocked_free_timeline_list); - LIST_HEAD(unlocked_free_list); - unsigned long flags; - bool freelist_empty; - - /* We can't free the sync directly in this loop because - * that will take the mmap mutex. We can't take mutexes while we have - * this list locked with a spinlock. So move all the items we want to - * free to another, local list (no locking required) and process it - * in a second loop. - */ - - spin_lock_irqsave(&sync_checkpoint_free_list_spinlock, flags); - list_for_each_entry_safe(kernel, k, &sync_checkpoint_free_list, list) { - /* Check if this sync is not used anymore. */ - if ((kernel->fence_sync) && - !is_sync_checkpoint_met(kernel->fence_sync, - PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) { - continue; - } - - /* Remove the entry from the free list. */ - list_move_tail(&kernel->list, &unlocked_free_checkpoint_list); - } - - /* Wait and loop if there are still syncs on the free list (IE - * are still in use by the HW). - */ - freelist_empty = list_empty(&sync_checkpoint_free_list); - - spin_unlock_irqrestore(&sync_checkpoint_free_list_spinlock, flags); - - spin_lock_irqsave(&timeline_free_list_spinlock, flags); - list_for_each_entry_safe(tl_kernel, tl_k, &timeline_free_list, list) { - /* Check if this sync is not used anymore. */ - if (tl_kernel->fence_sync && !is_sync_prim_met(tl_kernel->fence_sync)) - continue; - - /* Remove the entry from the free list. */ - list_move_tail(&tl_kernel->list, &unlocked_free_timeline_list); - } - - /* Wait and loop if there are still syncs on the free list (IE - * are still in use by the HW). - */ - freelist_empty &= list_empty(&timeline_free_list); - - spin_unlock_irqrestore(&timeline_free_list_spinlock, flags); - - - list_for_each_entry_safe(kernel, k, &unlocked_free_checkpoint_list, list) { - list_del(&kernel->list); - - if (kernel->fence_sync && kernel->fence_sync->client_sync_checkpoint) { - spin_lock_irqsave(&pvr_sync_pt_active_list_spinlock, flags); - if (!list_empty(&kernel->fence_sync->list)) - list_del_init(&kernel->fence_sync->list); - - spin_unlock_irqrestore(&pvr_sync_pt_active_list_spinlock, flags); - SyncCheckpointFree(kernel->fence_sync->client_sync_checkpoint); - kernel->fence_sync->client_sync_checkpoint = NULL; - } - kfree(kernel->fence_sync); - kfree(kernel); - } - - list_for_each_entry_safe(tl_kernel, tl_k, &unlocked_free_timeline_list, list) { - list_del(&tl_kernel->list); - - if (tl_kernel->fence_sync) - sync_pool_put(tl_kernel->fence_sync); - kfree(tl_kernel); - } - - /* sync_fence_put() must be called from process/WQ context - * because it uses fput(), which is not allowed to be called - * from interrupt context in kernels <3.6. - */ - INIT_LIST_HEAD(&unlocked_free_list); - - spin_lock_irqsave(&sync_fence_put_list_spinlock, flags); - list_for_each_entry_safe(sync_fence, f, &sync_fence_put_list, list) - list_move_tail(&sync_fence->list, &unlocked_free_list); - - spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags); - - list_for_each_entry_safe(sync_fence, f, &unlocked_free_list, list) { - list_del(&sync_fence->list); - sync_fence_put(sync_fence->fence); - kfree(sync_fence); - } - - return !freelist_empty; -} - -static void -pvr_sync_defer_free_work_queue_function(struct work_struct *data) -{ - enum PVRSRV_ERROR_TAG error = PVRSRV_OK; - void *event_object; - - error = OSEventObjectOpen(pvr_sync_data.event_object_handle, - &event_object); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Error opening event object (%s)\n", - __func__, PVRSRVGetErrorString(error)); - return; - - } - - while (pvr_sync_clean_freelist()) { - - error = OSEventObjectWait(event_object); - - switch (error) { - - case PVRSRV_OK: - case PVRSRV_ERROR_TIMEOUT: - /* Timeout is normal behaviour */ - continue; - default: - pr_err("pvr_sync2: %s: Error waiting for event object (%s)\n", - __func__, PVRSRVGetErrorString(error)); - break; - } - } - error = OSEventObjectClose(event_object); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Error closing event object (%s)\n", - __func__, PVRSRVGetErrorString(error)); - } -} - -static -void pvr_sync_free_checkpoint_list_mem(void *mem_ptr) -{ - kfree(mem_ptr); -} - -static -void pvr_sync_update_all_timelines(void *command_complete_handle) -{ - struct pvr_sync_timeline *timeline, *n; - u32 num_signalled = 0; - unsigned long flags; - - spin_lock_irqsave(&timeline_list_lock, flags); - - list_for_each_entry(timeline, &timeline_list, list) { - /* If a timeline is destroyed via pvr_sync_release_timeline() - * in parallel with a call to pvr_sync_update_all_timelines(), - * the timeline_list_lock will block destruction of the - * 'timeline' pointer. Use kref_get_unless_zero() to detect - * and handle this race. Skip the timeline if it's being - * destroyed, blocked only on the timeline_list_lock. - */ - timeline->valid = - kref_get_unless_zero(&timeline->kref) ? true : false; - } - - list_for_each_entry_safe(timeline, n, &timeline_list, list) { - /* We know timeline is valid at this point because we're - * holding the list lock (so pvr_sync_destroy_timeline() has - * to wait). - */ - void *obj = timeline->obj; - - /* If we're racing with pvr_sync_release_timeline(), ignore */ - if (!timeline->valid) - continue; - - /* If syncs have signaled on the GPU, echo this in pvr_sync. - * - * At this point we know the timeline is valid, but obj might - * have raced and been set to NULL. It's only important that - * we use NULL / non-NULL consistently with the if() and call - * to sync_timeline_signal() -- the timeline->obj can't be - * freed (pvr_sync_release_timeline() will be stuck waiting - * for the timeline_list_lock) but it might have been made - * invalid by the base sync driver, in which case this call - * will bounce harmlessly. - */ - if (obj) { - sync_timeline_signal(obj); - num_signalled++; - } - - /* We're already holding the timeline_list_lock */ - kref_put(&timeline->kref, pvr_sync_destroy_timeline_locked); - } - - spin_unlock_irqrestore(&timeline_list_lock, flags); -} - -enum PVRSRV_ERROR_TAG pvr_sync_register_functions(void) -{ - /* Initialise struct and register with sync_checkpoint.c */ - pvr_sync_data.sync_checkpoint_ops.pfnFenceResolve = pvr_sync_resolve_fence; - pvr_sync_data.sync_checkpoint_ops.pfnFenceCreate = pvr_sync_create_fence; - pvr_sync_data.sync_checkpoint_ops.pfnFenceDataRollback = pvr_sync_rollback_fence_data; - pvr_sync_data.sync_checkpoint_ops.pfnFenceFinalise = pvr_sync_finalise_fence; - pvr_sync_data.sync_checkpoint_ops.pfnNoHWUpdateTimelines = pvr_sync_update_all_timelines; - pvr_sync_data.sync_checkpoint_ops.pfnFreeCheckpointListMem = - pvr_sync_free_checkpoint_list_mem; - pvr_sync_data.sync_checkpoint_ops.pfnDumpInfoOnStalledUFOs = - pvr_sync_dump_info_on_stalled_ufos; - strlcpy(pvr_sync_data.sync_checkpoint_ops.pszImplName, - "pvr_sync2", SYNC_CHECKPOINT_IMPL_MAX_STRLEN); -#if defined(PDUMP) - pvr_sync_data.sync_checkpoint_ops.pfnSyncFenceGetCheckpoints = - pvr_sync_fence_get_checkpoints; -#endif - - return SyncCheckpointRegisterFunctions(&pvr_sync_data.sync_checkpoint_ops); -} - -int pvr_sync_init(void) -{ - return pvr_sync_ioctl_init(); -} - -void pvr_sync_deinit(void) -{ - pvr_sync_ioctl_deinit(); -} - -enum PVRSRV_ERROR_TAG pvr_sync_device_init(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - enum PVRSRV_ERROR_TAG error; - - /* Multi-Device not supported for sync2, if we attempt to init - * another device then print a big warning to kernel log - */ - if (WARN_ON(pvr_sync_data.defer_free_wq)) { - pr_err("pvr_sync2: Multi-Device not supported\n"); - return PVRSRV_ERROR_ALREADY_EXISTS; - } - - DPF("%s", __func__); - - atomic_set(&pvr_sync_data.sync_id, 0); - - error = PVRSRVAcquireGlobalEventObjectKM( - &pvr_sync_data.event_object_handle); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to acquire global event object (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_out; - } - - error = SyncPrimContextCreate(priv->dev_node, - &pvr_sync_data.sync_prim_context); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to create sync prim context (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_release_event_object; - } - - pvr_sync_data.defer_free_wq = - create_freezable_workqueue("pvr_sync_defer_free_workqueue"); - if (!pvr_sync_data.defer_free_wq) { - pr_err("pvr_sync2: %s: Failed to create pvr_sync defer_free workqueue\n", - __func__); - goto err_free_sync_context; - } - - INIT_WORK(&pvr_sync_data.defer_free_work, - pvr_sync_defer_free_work_queue_function); - - INIT_WORK(&pvr_sync_data.check_status_work, - pvr_sync_check_status_work_queue_function); - error = PVRSRVRegisterCmdCompleteNotify( - &pvr_sync_data.command_complete_handle, - &pvr_sync_update_all_timelines, - &priv->dev_node); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to register MISR notification (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_destroy_defer_free_wq; - } - - error = PVRSRVRegisterDeviceDbgRequestNotify( - &priv->sync_debug_notify_handle, - priv->dev_node, - pvr_sync_debug_request, - DEBUG_REQUEST_ANDROIDSYNC, - NULL); - if (error != PVRSRV_OK) { - pr_err("pvr_sync2: %s: Failed to register debug notifier (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_unregister_cmd_complete; - } - - error = PVRSRV_OK; - return error; - -err_unregister_cmd_complete: - PVRSRVUnregisterCmdCompleteNotify( - pvr_sync_data.command_complete_handle); -err_destroy_defer_free_wq: - destroy_workqueue(pvr_sync_data.defer_free_wq); -err_free_sync_context: - SyncPrimContextDestroy(pvr_sync_data.sync_prim_context); -err_release_event_object: - PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle); -err_out: - - return error; -} - -void pvr_sync_device_deinit(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - - DPF("%s", __func__); - - PVRSRVUnregisterDeviceDbgRequestNotify(priv->sync_debug_notify_handle); - - PVRSRVUnregisterCmdCompleteNotify( - pvr_sync_data.command_complete_handle); - - /* This will drain the workqueue, so we guarantee that all deferred - * syncs are free'd before returning. - */ - destroy_workqueue(pvr_sync_data.defer_free_wq); - - sync_pool_clear(); - - SyncPrimContextDestroy(pvr_sync_data.sync_prim_context); - - - PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle); -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_wait(void *fence, u32 timeout_in_ms) -{ - int err; - - DPF("fence<%p>, to=%d", fence, timeout_in_ms); - - err = sync_fence_wait(fence, timeout_in_ms); - /* -ETIME means active. In this case we will retry later again. If the - * return value is an error or zero we will close this fence and - * proceed. This makes sure that we are not getting stuck here when a - * fence changes into an error state for whatever reason. - */ - if (err == -ETIME) { - DPF("timeout", __func__); -#ifdef DEBUG_OUTPUT - _dump_fence(fence, NULL, NULL); -#endif - return PVRSRV_ERROR_TIMEOUT; - } else if (err != 0) { - pr_err("%s: failed dependencies\n", __func__); - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_release(void *fence) -{ - sync_fence_put(fence); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_get(int fence_fd, void **pfence) -{ - struct file *file; - - file = fget(fence_fd); - if (file == NULL || file->private_data == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - *pfence = file->private_data; - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG -pvr_sync_sw_timeline_fence_create(struct _PVRSRV_DEVICE_NODE_ *pvrsrv_dev_node, - int timeline_fd, - const char *fence_name, - int *fence_fd_out, - u64 *sync_pt_idx) -{ - enum PVRSRV_ERROR_TAG srv_err; - struct file *file; - struct pvr_sw_sync_timeline *pvr_sw_timeline; - struct sync_fence *fence = NULL; - struct sync_pt *sync_point; - int fd; - - (void)(pvrsrv_dev_node); - - fd = get_unused_fd_flags(O_CLOEXEC); - if (fd < 0) { - pr_err("%s: invalid fd\n", __func__); - - return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - } - - file = fget(timeline_fd); - pvr_sw_timeline = pvr_sync_get_api_priv(file); - if (!pvr_sw_timeline) { - /* unrecognised timeline */ - pr_err("%s: unrecognised timeline\n", __func__); - - srv_err = PVRSRV_ERROR_INVALID_PARAMS; - if (file) - goto err_put_file; - else - goto err_put_fd; - } - - DPF("pvr_sw_timeline<%p>", pvr_sw_timeline); - DPF("psSWTimeline<%p>", pvr_sw_timeline->sw_sync_timeline); - - sync_point = sw_sync_pt_create(pvr_sw_timeline->sw_sync_timeline, - pvr_sw_timeline->next_value); - if (!sync_point) { - srv_err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_file; - } - - fence = sync_fence_create(fence_name, sync_point); - if (!fence) { - srv_err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_free_pt; - } - - sync_fence_install(fence, fd); - - if (sync_pt_idx) - *sync_pt_idx = pvr_sw_timeline->next_value; - pvr_sw_timeline->next_value++; - - fput(file); - - *fence_fd_out = fd; - - DPF("returned fence fd %d <%p> '%s'", *fence_fd_out, fence, fence_name); - - return PVRSRV_OK; - -err_free_pt: - sync_pt_free(sync_point); -err_put_file: - fput(file); -err_put_fd: - put_unused_fd(fd); - return srv_err; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_advance(void *timeline, u64 *sync_pt_idx) -{ - struct sw_sync_timeline *sw_timeline; - struct pvr_sw_sync_timeline *pvr_sw_timeline; - - if (timeline == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - pvr_sw_timeline = (struct pvr_sw_sync_timeline *)timeline; - sw_timeline = (struct sw_sync_timeline *)pvr_sw_timeline->sw_sync_timeline; - - if (pvr_sw_timeline->current_value == (pvr_sw_timeline->next_value - 1)) { - pr_err("%s: attempt to advance SW timeline beyond last defined point\n", - __func__); - return PVRSRV_ERROR_SW_TIMELINE_AT_LATEST_POINT; - } - - sw_sync_timeline_inc(sw_timeline, 1); - pvr_sw_timeline->current_value++; - - if (sync_pt_idx) - *sync_pt_idx = pvr_sw_timeline->current_value; - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_release(void *timeline) -{ - struct pvr_sw_sync_timeline *pvr_sw_timeline; - - if (timeline == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - pvr_sw_timeline = (struct pvr_sw_sync_timeline *)timeline; - kref_put(&pvr_sw_timeline->kref, pvr_sw_sync_destroy_timeline); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_get(int timeline_fd, - void **timeline_out) -{ - enum PVRSRV_ERROR_TAG srv_err; - struct file *file; - struct pvr_sw_sync_timeline *pvr_sw_timeline; - int ret; - - file = fget(timeline_fd); - pvr_sw_timeline = pvr_sync_get_api_priv(file); - if (!pvr_sw_timeline) { - pr_err("%s: invalid params\n", __func__); - srv_err = PVRSRV_ERROR_INVALID_PARAMS; - if (file) - goto err_put_file; - else - goto err_out; - } - - *timeline_out = (void *)pvr_sw_timeline; - - /* Take ref on pvr_sw_timeline */ - ret = kref_get_unless_zero(&pvr_sw_timeline->kref); - if (ret) - srv_err = PVRSRV_OK; - else - srv_err = PVRSRV_ERROR_INVALID_PARAMS; - - DPF("pvr_sw_timeline=<%p>, pvr_sw_timeline->c=%llu, n=%llu", - pvr_sw_timeline->sw_sync_timeline, pvr_sw_timeline->current_value, - pvr_sw_timeline->next_value); - DPF("&pvr_sw_timeline->current_value=<%p>", - &pvr_sw_timeline->current_value); - DPF("returned, *timeline_out=<%p>", *timeline_out); - -err_put_file: - fput(file); -err_out: - return srv_err; -} - -enum PVRSRV_ERROR_TAG sync_dump_fence(void *sw_fence_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - struct sync_fence *fence = (struct sync_fence *) sw_fence_obj; - - _dump_fence(fence, dump_debug_printf, dump_debug_file); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG sync_sw_dump_timeline(void *sw_timeline_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0)) - struct pvr_sw_sync_timeline *timeline = - (struct pvr_sw_sync_timeline *) sw_timeline_obj; - - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "TL:%s SeqNum: %llu/%llu", - timeline->sw_sync_timeline->obj.name, - timeline->current_value, - timeline->next_value); -#else - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "Timeline Stats not available on this kernel!"); -#endif - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_api.h b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_api.h deleted file mode 100644 index 1ee24c262ea41..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_api.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * @File pvr_sync_api.h - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVR_SYNC_API_H -#define _PVR_SYNC_API_H - -#include - -int pvr_sync_api_init(void *file_handle, void **api_priv); -int pvr_sync_api_deinit(void *api_priv, bool is_sw); -int pvr_sync_api_rename(void *api_priv, void *user_data); -int pvr_sync_api_force_sw_only(void *api_priv, void **api_priv_new); -int pvr_sync_api_sw_create_fence(void *api_priv, void *user_data); -int pvr_sync_api_sw_inc(void *api_priv, void *user_data); - -struct file; - -int pvr_sync_ioctl_init(void); -void pvr_sync_ioctl_deinit(void); -void *pvr_sync_get_api_priv(struct file *file); -struct file *pvr_sync_get_file_struct(void *file_handle); - -#endif /* _PVR_SYNC_API_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_file.c b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_file.c deleted file mode 100644 index 4c6932c0864b0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_file.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * @File pvr_sync_file.c - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Strictly Confidential. - */ - -#include "services_kernel_client.h" -#include "pvr_drv.h" -#include "pvr_sync.h" -#include "pvr_fence.h" -#include "pvr_counting_timeline.h" - -#include "linux_sw_sync.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "pvr_sync_api.h" - -/* This header must always be included last */ -#include "kernel_compatibility.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) && !defined(CHROMIUMOS_KERNEL) -#define sync_file_user_name(s) ((s)->name) -#else -#define sync_file_user_name(s) ((s)->user_name) -#endif - -#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, fmt, ...) \ - do { \ - if (pfnDumpDebugPrintf) \ - pfnDumpDebugPrintf(pvDumpDebugFile, fmt, \ - ## __VA_ARGS__); \ - else \ - pr_err(fmt "\n", ## __VA_ARGS__); \ - } while (0) - -#define FILE_NAME "pvr_sync_file" - -struct sw_sync_create_fence_data { - __u32 value; - char name[32]; - __s32 fence; -}; -#define SW_SYNC_IOC_MAGIC 'W' -#define SW_SYNC_IOC_CREATE_FENCE \ - (_IOWR(SW_SYNC_IOC_MAGIC, 0, struct sw_sync_create_fence_data)) -#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) - -/* Global data for the sync driver */ -static struct { - struct pvr_fence_context *foreign_fence_context; - PFN_SYNC_CHECKPOINT_STRUCT sync_checkpoint_ops; -} pvr_sync_data; - -#if defined(NO_HARDWARE) -static DEFINE_MUTEX(pvr_timeline_active_list_lock); -static struct list_head pvr_timeline_active_list; -#endif - -/* This is the actual timeline metadata. We might keep this around after the - * base sync driver has destroyed the pvr_sync_timeline_wrapper object. - */ -struct pvr_sync_timeline { - char name[32]; - void *file_handle; - bool is_sw; - /* Fence context used for hw fences */ - struct pvr_fence_context *hw_fence_context; - /* Timeline and context for sw fences */ - struct pvr_counting_fence_timeline *sw_fence_timeline; -#if defined(NO_HARDWARE) - /* List of all timelines (used to advance all timelines in nohw builds) */ - struct list_head list; -#endif -}; - -static -void pvr_sync_free_checkpoint_list_mem(void *mem_ptr) -{ - kfree(mem_ptr); -} - -#if defined(NO_HARDWARE) -/* function used to signal pvr fence in nohw builds */ -static -void pvr_sync_nohw_signal_fence(void *fence_data_to_signal) -{ - struct pvr_sync_timeline *this_timeline; - - mutex_lock(&pvr_timeline_active_list_lock); - list_for_each_entry(this_timeline, &pvr_timeline_active_list, list) { - pvr_fence_context_signal_fences_nohw(this_timeline->hw_fence_context); - } - mutex_unlock(&pvr_timeline_active_list_lock); -} -#endif - -static struct pvr_sync_timeline *pvr_sync_timeline_fget(int fd) -{ - struct file *file = fget(fd); - struct pvr_sync_timeline *timeline; - - if (!file) - return NULL; - - timeline = pvr_sync_get_api_priv(file); - if (!timeline) - fput(file); - - return timeline; -} - -static void pvr_sync_timeline_fput(struct pvr_sync_timeline *timeline) -{ - struct file *file = pvr_sync_get_file_struct(timeline->file_handle); - - if (file) - fput(file); - else - pr_err(FILE_NAME ": %s: Timeline incomplete\n", __func__); -} - -/* ioctl and fops handling */ - -int pvr_sync_api_init(void *file_handle, void **api_priv) -{ - struct pvr_sync_timeline *timeline; - char task_comm[TASK_COMM_LEN]; - - get_task_comm(task_comm, current); - - timeline = kzalloc(sizeof(*timeline), GFP_KERNEL); - if (!timeline) - return -ENOMEM; - - strlcpy(timeline->name, task_comm, sizeof(timeline->name)); - timeline->file_handle = file_handle; - timeline->is_sw = false; - - *api_priv = (void *)timeline; - - return 0; -} - -int pvr_sync_api_deinit(void *api_priv, bool is_sw) -{ - struct pvr_sync_timeline *timeline = api_priv; - - if (!timeline) - return 0; - - if (timeline->sw_fence_timeline) { - /* This makes sure any outstanding SW syncs are marked as - * complete at timeline close time. Otherwise it'll leak the - * timeline (as outstanding fences hold a ref) and possibly - * wedge the system if something is waiting on one of those - * fences - */ - pvr_counting_fence_timeline_force_complete( - timeline->sw_fence_timeline); - pvr_counting_fence_timeline_put(timeline->sw_fence_timeline); - } - - if (timeline->hw_fence_context) { -#if defined(NO_HARDWARE) - mutex_lock(&pvr_timeline_active_list_lock); - list_del(&timeline->list); - mutex_unlock(&pvr_timeline_active_list_lock); -#endif - pvr_fence_context_destroy(timeline->hw_fence_context); - } - - kfree(timeline); - - return 0; -} - -/* - * This is the function that kick code will call in order to 'finalise' a - * created output fence just prior to returning from the kick function. - * The OS native sync code needs to implement a function meeting this - * specification - the implementation may be a nop if the OS does not need - * to perform any actions at this point. - * - * Input: fence_fd The PVRSRV_FENCE to be 'finalised'. This value - * will have been returned by an earlier call to - * pvr_sync_create_fence(). - * Input: finalise_data The finalise data returned by an earlier call - * to pvr_sync_create_fence(). - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_finalise_fence(PVRSRV_FENCE fence_fd, void *finalise_data) -{ - struct sync_file *sync_file = finalise_data; - struct pvr_fence *pvr_fence; - - if (!sync_file || (fence_fd < 0)) { - pr_err(FILE_NAME ": %s: Invalid input fence\n", __func__); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - pvr_fence = to_pvr_fence(sync_file->fence); - - if (!pvr_fence) { - pr_err(FILE_NAME ": %s: Fence not a pvr fence\n", __func__); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* pvr fences can be signalled any time after creation */ - dma_fence_enable_sw_signaling(&pvr_fence->base); - - fd_install(fence_fd, sync_file->file); - - return PVRSRV_OK; -} - -/* - * This is the function that kick code will call in order to obtain a new - * PVRSRV_FENCE from the OS native sync code and the PSYNC_CHECKPOINT used - * in that fence. The OS native sync code needs to implement a function - * meeting this specification. - * - * Input: device Device node to use in creating a hw_fence_ctx - * Input: fence_name A string to annotate the fence with (for - * debug). - * Input: timeline The timeline on which the new fence is to be - * created. - * Output: new_fence The new PVRSRV_FENCE to be returned by the - * kick call. - * Output: fence_uid Unique ID of the update fence. - * Output: fence_finalise_data Pointer to data needed to finalise the fence. - * Output: new_checkpoint_handle The PSYNC_CHECKPOINT used by the new fence. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_create_fence( - struct _PVRSRV_DEVICE_NODE_ *device, - const char *fence_name, - PVRSRV_TIMELINE new_fence_timeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *new_fence, u64 *fence_uid, - void **fence_finalise_data, - PSYNC_CHECKPOINT *new_checkpoint_handle, - void **timeline_update_sync, - __u32 *timeline_update_value) -{ - PVRSRV_ERROR err = PVRSRV_OK; - PVRSRV_FENCE new_fence_fd = -1; - struct pvr_sync_timeline *timeline; - struct pvr_fence *pvr_fence; - PSYNC_CHECKPOINT checkpoint; - struct sync_file *sync_file; - - if (new_fence_timeline < 0 || !new_fence || !new_checkpoint_handle - || !fence_finalise_data) { - pr_err(FILE_NAME ": %s: Invalid input params\n", __func__); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - /* We reserve the new fence FD before taking any operations - * as we do not want to fail (e.g. run out of FDs) - */ - new_fence_fd = get_unused_fd_flags(O_CLOEXEC); - if (new_fence_fd < 0) { - pr_err(FILE_NAME ": %s: Failed to get fd\n", __func__); - err = PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - goto err_out; - } - - timeline = pvr_sync_timeline_fget(new_fence_timeline); - if (!timeline) { - pr_err(FILE_NAME ": %s: Failed to open supplied timeline fd (%d)\n", - __func__, new_fence_timeline); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_fd; - } - - if (timeline->is_sw) { - /* This should never happen! */ - pr_err(FILE_NAME ": %s: Request to create a pvr fence on sw timeline (%d)\n", - __func__, new_fence_timeline); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_timeline; - } - - if (!timeline->hw_fence_context) { - /* First time we use this timeline, so create a context. */ - timeline->hw_fence_context = - pvr_fence_context_create( - device, - NativeSyncGetFenceStatusWq(), - timeline->name); - if (!timeline->hw_fence_context) { - pr_err(FILE_NAME ": %s: Failed to create fence context (%d)\n", - __func__, new_fence_timeline); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_timeline; - } -#if defined(NO_HARDWARE) - /* Add timeline to active list */ - INIT_LIST_HEAD(&timeline->list); - mutex_lock(&pvr_timeline_active_list_lock); - list_add_tail(&timeline->list, &pvr_timeline_active_list); - mutex_unlock(&pvr_timeline_active_list_lock); -#endif - } - - pvr_fence = pvr_fence_create(timeline->hw_fence_context, - psSyncCheckpointContext, - new_fence_timeline, - fence_name); - if (!pvr_fence) { - pr_err(FILE_NAME ": %s: Failed to create new pvr_fence\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_timeline; - } - - checkpoint = pvr_fence_get_checkpoint(pvr_fence); - if (!checkpoint) { - pr_err(FILE_NAME ": %s: Failed to get fence checkpoint\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_destroy_fence; - } - - sync_file = sync_file_create(&pvr_fence->base); - if (!sync_file) { - pr_err(FILE_NAME ": %s: Failed to create sync_file\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_destroy_fence; - } - strlcpy(sync_file_user_name(sync_file), - pvr_fence->name, - sizeof(sync_file_user_name(sync_file))); - dma_fence_put(&pvr_fence->base); - - *new_fence = new_fence_fd; - *fence_finalise_data = sync_file; - *new_checkpoint_handle = checkpoint; - *fence_uid = OSGetCurrentClientProcessIDKM(); - *fence_uid = (*fence_uid << 32) | (new_fence_fd & U32_MAX); - /* not used but don't want to return dangling pointers */ - *timeline_update_sync = NULL; - *timeline_update_value = 0; - - pvr_sync_timeline_fput(timeline); -err_out: - return err; - -err_destroy_fence: - pvr_fence_destroy(pvr_fence); -err_put_timeline: - pvr_sync_timeline_fput(timeline); -err_put_fd: - put_unused_fd(new_fence_fd); - *fence_uid = PVRSRV_NO_FENCE; - goto err_out; -} - -/* - * This is the function that kick code will call in order to 'rollback' a - * created output fence should an error occur when submitting the kick. - * The OS native sync code needs to implement a function meeting this - * specification. - * - * Input: fence_to_rollback The PVRSRV_FENCE to be 'rolled back'. The fence - * should be destroyed and any actions taken due to - * its creation that need to be undone should be - * reverted. - * Input: finalise_data The finalise data for the fence to be 'rolled back'. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_rollback_fence_data(PVRSRV_FENCE fence_to_rollback, - void *fence_data_to_rollback) -{ - struct sync_file *sync_file = fence_data_to_rollback; - struct pvr_fence *pvr_fence; - - if (!sync_file || fence_to_rollback < 0) { - pr_err(FILE_NAME ": %s: Invalid fence (%d)\n", __func__, - fence_to_rollback); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - pvr_fence = to_pvr_fence(sync_file->fence); - if (!pvr_fence) { - pr_err(FILE_NAME - ": %s: Non-PVR fence (%p)\n", - __func__, sync_file->fence); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - fput(sync_file->file); - - put_unused_fd(fence_to_rollback); - - return PVRSRV_OK; -} - -/* - * This is the function that kick code will call in order to obtain a list of - * the PSYNC_CHECKPOINTs for a given PVRSRV_FENCE passed to a kick function. - * The OS native sync code will allocate the memory to hold the returned list - * of PSYNC_CHECKPOINT ptrs. The caller will free this memory once it has - * finished referencing it. - * - * Input: fence The input (check) fence - * Output: nr_checkpoints The number of PVRSRV_SYNC_CHECKPOINT ptrs - * returned in the checkpoint_handles - * parameter. - * Output: fence_uid Unique ID of the check fence - * Input/Output: checkpoint_handles The returned list of PVRSRV_SYNC_CHECKPOINTs. - */ -static enum PVRSRV_ERROR_TAG -pvr_sync_resolve_fence(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE fence_to_resolve, u32 *nr_checkpoints, - PSYNC_CHECKPOINT **checkpoint_handles, u64 *fence_uid) -{ - PSYNC_CHECKPOINT *checkpoints = NULL; - unsigned int i, num_fences = 0, num_used_fences = 0; - struct dma_fence **fences = NULL; - struct dma_fence *fence; - PVRSRV_ERROR err = PVRSRV_OK; - - if (!nr_checkpoints || !checkpoint_handles || !fence_uid) { - pr_err(FILE_NAME ": %s: Invalid input checkpoint pointer\n", - __func__); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - *nr_checkpoints = 0; - *checkpoint_handles = NULL; - *fence_uid = 0; - - if (fence_to_resolve < 0) - goto err_out; - - fence = sync_file_get_fence(fence_to_resolve); - if (!fence) { - pr_err(FILE_NAME ": %s: Failed to read sync private data for fd %d\n", - __func__, fence_to_resolve); - err = PVRSRV_ERROR_HANDLE_NOT_FOUND; - goto err_out; - } - - if (dma_fence_is_array(fence)) { - struct dma_fence_array *array = to_dma_fence_array(fence); - - if (array) { - fences = array->fences; - num_fences = array->num_fences; - } - } else { - fences = &fence; - num_fences = 1; - } - - checkpoints = kmalloc_array(num_fences, sizeof(PSYNC_CHECKPOINT), - GFP_KERNEL); - if (!checkpoints) { - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_fence; - } - for (i = 0; i < num_fences; i++) { - /* - * Only return the checkpoint if the fence is still active. - * Don't checked for signalled on PDUMP drivers as we need - * to make sure that all fences make it to the pdump. - */ -#if !defined(PDUMP) - if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &fences[i]->flags)) -#endif - { - struct pvr_fence *pvr_fence = - pvr_fence_create_from_fence( - pvr_sync_data.foreign_fence_context, - psSyncCheckpointContext, - fences[i], - fence_to_resolve, - "foreign"); - if (!pvr_fence) { - pr_err(FILE_NAME ": %s: Failed to create fence\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_free_checkpoints; - } - checkpoints[num_used_fences] = - pvr_fence_get_checkpoint(pvr_fence); - SyncCheckpointTakeRef(checkpoints[num_used_fences]); - ++num_used_fences; - dma_fence_put(&pvr_fence->base); - } - } - /* If we don't return any checkpoints, delete the array because - * the caller will not. - */ - if (num_used_fences == 0) { - kfree(checkpoints); - checkpoints = NULL; - } - - *checkpoint_handles = checkpoints; - *nr_checkpoints = num_used_fences; - *fence_uid = OSGetCurrentClientProcessIDKM(); - *fence_uid = (*fence_uid << 32) | (fence_to_resolve & U32_MAX); - -err_put_fence: - dma_fence_put(fence); -err_out: - return err; - -err_free_checkpoints: - for (i = 0; i < num_used_fences; i++) { - if (checkpoints[i]) - SyncCheckpointDropRef(checkpoints[i]); - } - kfree(checkpoints); - goto err_put_fence; -} - -/* - * This is the function that driver code will call in order to request the - * sync implementation to output debug information relating to any sync - * checkpoints it may have created which appear in the provided array of - * FW addresses of Unified Fence Objects (UFOs). - * - * Input: nr_ufos The number of FW addresses provided in the - * vaddrs parameter. - * Input: vaddrs The array of FW addresses of UFOs. The sync - * implementation should check each of these to - * see if any relate to sync checkpoints it has - * created and where they do output debug information - * pertaining to the native/fallback sync with - * which it is associated. - */ -static u32 -pvr_sync_dump_info_on_stalled_ufos(u32 nr_ufos, u32 *vaddrs) -{ - return pvr_fence_dump_info_on_stalled_ufos(pvr_sync_data.foreign_fence_context, - nr_ufos, - vaddrs); -} - -#if defined(PDUMP) -static enum PVRSRV_ERROR_TAG -pvr_sync_fence_get_checkpoints(PVRSRV_FENCE fence_to_pdump, u32 *nr_checkpoints, - struct SYNC_CHECKPOINT_TAG ***checkpoint_handles) -{ - struct dma_fence **fences = NULL; - struct dma_fence *fence; - struct pvr_fence *pvr_fence; - struct SYNC_CHECKPOINT_TAG **checkpoints = NULL; - unsigned int i, num_fences, num_used_fences = 0; - enum PVRSRV_ERROR_TAG err; - - if (fence_to_pdump < 0) { - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - if (!nr_checkpoints || !checkpoint_handles) { - pr_err(FILE_NAME ": %s: Invalid input checkpoint pointer\n", - __func__); - err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_out; - } - - fence = sync_file_get_fence(fence_to_pdump); - if (!fence) { - pr_err(FILE_NAME ": %s: Failed to read sync private data for fd %d\n", - __func__, fence_to_pdump); - err = PVRSRV_ERROR_HANDLE_NOT_FOUND; - goto err_out; - } - - if (dma_fence_is_array(fence)) { - struct dma_fence_array *array = to_dma_fence_array(fence); - - fences = array->fences; - num_fences = array->num_fences; - } else { - fences = &fence; - num_fences = 1; - } - - checkpoints = kmalloc_array(num_fences, sizeof(*checkpoints), - GFP_KERNEL); - if (!checkpoints) { - pr_err("pvr_sync_file: %s: Failed to alloc memory for returned list of sync checkpoints\n", - __func__); - err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_fence; - } - - for (i = 0; i < num_fences; i++) { - pvr_fence = to_pvr_fence(fences[i]); - if (!pvr_fence) - continue; - checkpoints[num_used_fences] = pvr_fence_get_checkpoint(pvr_fence); - ++num_used_fences; - } - - *checkpoint_handles = checkpoints; - *nr_checkpoints = num_used_fences; - err = PVRSRV_OK; - -err_put_fence: - dma_fence_put(fence); -err_out: - return err; -} -#endif - -int pvr_sync_api_rename(void *api_priv, void *user_data) -{ - struct pvr_sync_timeline *timeline = api_priv; - struct pvr_sync_rename_ioctl_data *data = user_data; - - data->szName[sizeof(data->szName) - 1] = '\0'; - strlcpy(timeline->name, data->szName, sizeof(timeline->name)); - if (timeline->hw_fence_context) - strlcpy(timeline->hw_fence_context->name, data->szName, - sizeof(timeline->hw_fence_context->name)); - - return 0; -} - -int pvr_sync_api_force_sw_only(void *api_priv, void **api_priv_new) -{ - struct pvr_sync_timeline *timeline = api_priv; - - /* Already in SW mode? */ - if (timeline->sw_fence_timeline) - return 0; - - /* Create a sw_sync timeline with the old GPU timeline's name */ - timeline->sw_fence_timeline = pvr_counting_fence_timeline_create( - timeline->name); - if (!timeline->sw_fence_timeline) - return -ENOMEM; - - timeline->is_sw = true; - - return 0; -} - -int pvr_sync_api_sw_create_fence(void *api_priv, void *user_data) -{ - struct pvr_sync_timeline *timeline = api_priv; - struct pvr_sw_sync_create_fence_data *data = user_data; - struct sync_file *sync_file; - int fd = get_unused_fd_flags(O_CLOEXEC); - struct dma_fence *fence; - int err; - - if (fd < 0) { - pr_err(FILE_NAME ": %s: Failed to find unused fd (%d)\n", - __func__, fd); - err = -EMFILE; - goto err_out; - } - - fence = pvr_counting_fence_create(timeline->sw_fence_timeline, &data->sync_pt_idx); - if (!fence) { - pr_err(FILE_NAME ": %s: Failed to create a sync point (%d)\n", - __func__, fd); - err = -ENOMEM; - goto err_put_fd; - } - - sync_file = sync_file_create(fence); - dma_fence_put(fence); - if (!sync_file) { - pr_err(FILE_NAME ": %s: Failed to create a sync point (%d)\n", - __func__, fd); - err = -ENOMEM; - goto err_put_fd; - } - - data->fence = fd; - - fd_install(fd, sync_file->file); - - return 0; - -err_put_fd: - put_unused_fd(fd); -err_out: - return err; -} - -int pvr_sync_api_sw_inc(void *api_priv, void *user_data) -{ - struct pvr_sync_timeline *timeline = api_priv; - struct pvr_sw_timeline_advance_data *data = user_data; - bool res; - - res = pvr_counting_fence_timeline_inc(timeline->sw_fence_timeline, &data->sync_pt_idx); - - /* pvr_counting_fence_timeline_inc won't allow sw timeline to be - * advanced beyond the last defined point - */ - if (!res) { - pr_err("pvr_sync_file: attempt to advance SW timeline beyond last defined point\n"); - return -EPERM; - } - - return 0; -} - -static void -pvr_sync_debug_request_heading(void *data, u32 verbosity, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - if (DD_VERB_LVL_ENABLED(verbosity, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, - "------[ Native Fence Sync: timelines ]------"); -} - -enum PVRSRV_ERROR_TAG pvr_sync_register_functions(void) -{ - /* Register the resolve fence and create fence functions with - * sync_checkpoint.c - * The pvr_fence context registers its own EventObject callback to - * update sync status - */ - /* Initialise struct and register with sync_checkpoint.c */ - pvr_sync_data.sync_checkpoint_ops.pfnFenceResolve = pvr_sync_resolve_fence; - pvr_sync_data.sync_checkpoint_ops.pfnFenceCreate = pvr_sync_create_fence; - pvr_sync_data.sync_checkpoint_ops.pfnFenceDataRollback = pvr_sync_rollback_fence_data; - pvr_sync_data.sync_checkpoint_ops.pfnFenceFinalise = pvr_sync_finalise_fence; -#if defined(NO_HARDWARE) - pvr_sync_data.sync_checkpoint_ops.pfnNoHWUpdateTimelines = pvr_sync_nohw_signal_fence; -#else - pvr_sync_data.sync_checkpoint_ops.pfnNoHWUpdateTimelines = NULL; -#endif - pvr_sync_data.sync_checkpoint_ops.pfnFreeCheckpointListMem = - pvr_sync_free_checkpoint_list_mem; - pvr_sync_data.sync_checkpoint_ops.pfnDumpInfoOnStalledUFOs = - pvr_sync_dump_info_on_stalled_ufos; - strlcpy(pvr_sync_data.sync_checkpoint_ops.pszImplName, "pvr_sync_file", - SYNC_CHECKPOINT_IMPL_MAX_STRLEN); -#if defined(PDUMP) - pvr_sync_data.sync_checkpoint_ops.pfnSyncFenceGetCheckpoints = - pvr_sync_fence_get_checkpoints; -#endif - - return SyncCheckpointRegisterFunctions(&pvr_sync_data.sync_checkpoint_ops); -} - -int pvr_sync_init(void) -{ - int err; - - pvr_sync_data.foreign_fence_context = - pvr_fence_foreign_context_create( - NativeSyncGetFenceStatusWq(), - "foreign_sync"); - if (!pvr_sync_data.foreign_fence_context) { - pr_err(FILE_NAME ": %s: Failed to create foreign sync context\n", - __func__); - err = -ENOMEM; - goto err_out; - } - -#if defined(NO_HARDWARE) - INIT_LIST_HEAD(&pvr_timeline_active_list); -#endif - - err = pvr_sync_ioctl_init(); - if (err) { - pr_err(FILE_NAME ": %s: Failed to register pvr_sync device (%d)\n", - __func__, err); - goto err_ioctl_init; - } - - return 0; - -err_ioctl_init: - pvr_fence_context_destroy(pvr_sync_data.foreign_fence_context); - pvr_fence_cleanup(); -err_out: - return err; -} - -void pvr_sync_deinit(void) -{ - pvr_sync_ioctl_deinit(); - pvr_fence_context_destroy(pvr_sync_data.foreign_fence_context); - pvr_fence_cleanup(); -} - -enum PVRSRV_ERROR_TAG pvr_sync_device_init(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - enum PVRSRV_ERROR_TAG error; - - error = PVRSRVRegisterDeviceDbgRequestNotify( - &priv->sync_debug_notify_handle, - priv->dev_node, - pvr_sync_debug_request_heading, - DEBUG_REQUEST_LINUXFENCE, - NULL); - if (error != PVRSRV_OK) { - pr_err("%s: failed to register debug request callback (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_out; - } - - /* Register the foreign sync context debug notifier on each device */ - error = pvr_fence_context_register_dbg( - &priv->sync_foreign_debug_notify_handle, - priv->dev_node, - pvr_sync_data.foreign_fence_context); - if (error != PVRSRV_OK) { - pr_err("%s: failed to register fence debug request callback (%s)\n", - __func__, PVRSRVGetErrorString(error)); - goto err_context_regdbg; - } - -#if defined(NO_HARDWARE) - INIT_LIST_HEAD(&pvr_timeline_active_list); -#endif - - return PVRSRV_OK; - -err_context_regdbg: - PVRSRVUnregisterDeviceDbgRequestNotify(priv->sync_debug_notify_handle); -err_out: - return error; -} - -void pvr_sync_device_deinit(struct device *dev) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct pvr_drm_private *priv = ddev->dev_private; - - PVRSRVUnregisterDeviceDbgRequestNotify(priv->sync_foreign_debug_notify_handle); - PVRSRVUnregisterDeviceDbgRequestNotify(priv->sync_debug_notify_handle); -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_wait(void *fence, u32 timeout_in_ms) -{ - long timeout = msecs_to_jiffies(timeout_in_ms); - int err; - - err = dma_fence_wait_timeout(fence, true, timeout); - /* - * dma_fence_wait_timeout returns: - * - the remaining timeout on success - * - 0 on timeout - * - -ERESTARTSYS if interrupted - */ - if (err > 0) - return PVRSRV_OK; - else if (err == 0) - return PVRSRV_ERROR_TIMEOUT; - - return PVRSRV_ERROR_FAILED_DEPENDENCIES; -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_release(void *fence) -{ - dma_fence_put(fence); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_fence_get(int fence_fd, void **fence_out) -{ - struct dma_fence *fence; - - fence = sync_file_get_fence(fence_fd); - if (fence == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - *fence_out = fence; - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG -pvr_sync_sw_timeline_fence_create(struct _PVRSRV_DEVICE_NODE_ *pvrsrv_dev_node, - int timeline_fd, - const char *fence_name, - int *fence_fd_out, - u64 *sync_pt_idx) -{ - enum PVRSRV_ERROR_TAG srv_err; - struct pvr_sync_timeline *timeline; - struct dma_fence *fence = NULL; - struct sync_file *sync_file = NULL; - int fd; - - (void)(pvrsrv_dev_node); - - fd = get_unused_fd_flags(O_CLOEXEC); - if (fd < 0) - return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - - timeline = pvr_sync_timeline_fget(timeline_fd); - if (!timeline) { - /* unrecognised timeline */ - srv_err = PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - goto err_put_fd; - } - if (!timeline->is_sw) { - pvr_sync_timeline_fput(timeline); - srv_err = PVRSRV_ERROR_INVALID_PARAMS; - goto err_put_fd; - } - - fence = pvr_counting_fence_create(timeline->sw_fence_timeline, sync_pt_idx); - pvr_sync_timeline_fput(timeline); - if (!fence) { - srv_err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_fd; - } - - sync_file = sync_file_create(fence); - dma_fence_put(fence); - if (!sync_file) { - srv_err = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_put_fd; - } - - fd_install(fd, sync_file->file); - - *fence_fd_out = fd; - - return PVRSRV_OK; - -err_put_fd: - put_unused_fd(fd); - return srv_err; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_advance(void *timeline, u64 *sync_pt_idx) -{ - if (timeline == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - pvr_counting_fence_timeline_inc(timeline, sync_pt_idx); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_release(void *timeline) -{ - if (timeline == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - pvr_counting_fence_timeline_put(timeline); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG pvr_sync_sw_timeline_get(int timeline_fd, - void **timeline_out) -{ - struct pvr_counting_fence_timeline *sw_timeline; - struct pvr_sync_timeline *timeline; - - timeline = pvr_sync_timeline_fget(timeline_fd); - if (!timeline) - return PVRSRV_ERROR_INVALID_PARAMS; - - sw_timeline = - pvr_counting_fence_timeline_get(timeline->sw_fence_timeline); - pvr_sync_timeline_fput(timeline); - if (!sw_timeline) - return PVRSRV_ERROR_INVALID_PARAMS; - - *timeline_out = sw_timeline; - - return PVRSRV_OK; -} -static void _dump_sync_point(struct dma_fence *fence, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - const struct dma_fence_ops *fence_ops = fence->ops; - bool signaled = dma_fence_is_signaled(fence); - char time[16] = { '\0' }; - - fence_ops->timeline_value_str(fence, time, sizeof(time)); - - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "<%p> Seq#=%llu TS=%s State=%s TLN=%s", - fence, - (u64) fence->seqno, - time, - (signaled) ? "Signalled" : "Active", - fence_ops->get_timeline_name(fence)); -} - -static void _dump_fence(struct dma_fence *fence, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - if (dma_fence_is_array(fence)) { - struct dma_fence_array *fence_array = to_dma_fence_array(fence); - int i; - - if (fence_array) { - PVR_DUMPDEBUG_LOG(dump_debug_printf, - dump_debug_file, - "Fence: [%p] Sync Points:\n", - fence_array); - - for (i = 0; i < fence_array->num_fences; i++) - _dump_sync_point(fence_array->fences[i], - dump_debug_printf, - dump_debug_file); - } - - } else { - _dump_sync_point(fence, dump_debug_printf, dump_debug_file); - } -} - -enum PVRSRV_ERROR_TAG -sync_dump_fence(void *sw_fence_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - struct dma_fence *fence = (struct dma_fence *) sw_fence_obj; - - _dump_fence(fence, dump_debug_printf, dump_debug_file); - - return PVRSRV_OK; -} - -enum PVRSRV_ERROR_TAG -sync_sw_dump_timeline(void *sw_timeline_obj, - DUMPDEBUG_PRINTF_FUNC *dump_debug_printf, - void *dump_debug_file) -{ - pvr_counting_fence_timeline_dump_timeline(sw_timeline_obj, - dump_debug_printf, - dump_debug_file); - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.c b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.c deleted file mode 100644 index 60ba3555e7792..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * @File pvr_sync_ioctl_common.c - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_drm.h" -#include "pvr_sync_api.h" -#include "pvr_sync_ioctl_common.h" - -/* - * The PVR Sync API is unusual in that some operations configure the - * timeline for use, and are no longer allowed once the timeline is - * in use. A locking mechanism, such as a read/write semaphore, would - * be one method of helping to ensure the API rules are followed, but - * this would add unnecessary overhead once the timeline has been - * configured, as read locks would continue to have to be taken after - * the timeline is in use. To avoid locks, two atomic variables are used, - * together with memory barriers. The in_setup variable indicates a "rename" - * or "force software only" ioctl is in progress. At most one of these two - * configuration ioctls can be in progress at any one time, and they can't - * overlap with any other Sync ioctl. The in_use variable indicates one - * of the other Sync ioctls has started. Once set, in_use stays set, and - * prevents any further configuration ioctls. Non-configuration ioctls - * are allowed to overlap. - * It is possible for a configuration and non-configuration ioctl to race, - * but at most one will be allowed to proceed, and perhaps neither. - * Given the intended usage of the API in user space, where the timeline - * is fully configured before being used, the race behaviour won't be - * an issue. - */ - -struct pvr_sync_file_data { - atomic_t in_setup; - atomic_t in_use; - void *api_private; - bool is_sw; -}; - -static bool pvr_sync_set_in_use(struct pvr_sync_file_data *fdata) -{ - if (atomic_read(&fdata->in_use) < 2) { - atomic_set(&fdata->in_use, 1); - /* Ensure in_use change is visible before in_setup is read */ - smp_mb(); - if (atomic_read(&fdata->in_setup) != 0) - return false; - - atomic_set(&fdata->in_use, 2); - } else { - /* Ensure stale private data isn't read */ - smp_rmb(); - } - - return true; -} - -static bool pvr_sync_set_in_setup(struct pvr_sync_file_data *fdata) -{ - int in_setup; - - in_setup = atomic_inc_return(&fdata->in_setup); - if (in_setup > 1 || atomic_read(&fdata->in_use) != 0) { - atomic_dec(&fdata->in_setup); - return false; - } - - return true; -} - -static inline void pvr_sync_reset_in_setup(struct pvr_sync_file_data *fdata) -{ - /* - * Ensure setup changes are visible before allowing other - * operations to proceed. - */ - smp_mb__before_atomic(); - atomic_dec(&fdata->in_setup); -} - -void *pvr_sync_get_api_priv_common(struct file *file) -{ - if (file != NULL && pvr_sync_is_timeline(file)) { - struct pvr_sync_file_data *fdata = pvr_sync_get_private_data(file); - - if (fdata != NULL && pvr_sync_set_in_use(fdata)) - return fdata->api_private; - } - - return NULL; -} - -int pvr_sync_open_common(void *connection_data, void *file_handle) -{ - void *data = NULL; - struct pvr_sync_file_data *fdata; - int err; - - fdata = kzalloc(sizeof(*fdata), GFP_KERNEL); - if (!fdata) - return -ENOMEM; - - atomic_set(&fdata->in_setup, 0); - atomic_set(&fdata->in_use, 0); - - if (!pvr_sync_set_private_data(connection_data, fdata)) { - kfree(fdata); - return -EINVAL; - } - - err = pvr_sync_api_init(file_handle, &data); - if (err) - kfree(fdata); - else - fdata->api_private = data; - - return err; -} - -int pvr_sync_close_common(void *connection_data) -{ - struct pvr_sync_file_data *fdata; - - fdata = pvr_sync_connection_private_data(connection_data); - if (fdata) { - int err; - - err = pvr_sync_api_deinit(fdata->api_private, fdata->is_sw); - - kfree(fdata); - - return err; - } - - return 0; -} - -static inline int pvr_sync_ioctl_rename(void *api_priv, void *arg) -{ - struct pvr_sync_rename_ioctl_data *data = arg; - - return pvr_sync_api_rename(api_priv, data); -} - -static inline int pvr_sync_ioctl_force_sw_only(struct pvr_sync_file_data *fdata) -{ - void *data = fdata->api_private; - int err; - - err = pvr_sync_api_force_sw_only(fdata->api_private, &data); - if (!err) { - if (data != fdata->api_private) - fdata->api_private = data; - - fdata->is_sw = true; - } - - return err; -} - -static inline int pvr_sync_ioctl_sw_create_fence(void *api_priv, void *arg) -{ - struct pvr_sw_sync_create_fence_data *data = arg; - - return pvr_sync_api_sw_create_fence(api_priv, data); -} - -static inline int pvr_sync_ioctl_sw_inc(void *api_priv, void *arg) -{ - struct pvr_sw_timeline_advance_data *data = arg; - - return pvr_sync_api_sw_inc(api_priv, data); -} - -int pvr_sync_ioctl_common(struct file *file, unsigned int cmd, void *arg) -{ - int err = -ENOTTY; - struct pvr_sync_file_data *fdata; - bool in_setup; - - fdata = pvr_sync_get_private_data(file); - if (!fdata) - return -EINVAL; - - switch (cmd) { - case DRM_PVR_SYNC_RENAME_CMD: - case DRM_PVR_SYNC_FORCE_SW_ONLY_CMD: - if (!pvr_sync_set_in_setup(fdata)) - return -EBUSY; - - in_setup = true; - break; - default: - if (!pvr_sync_set_in_use(fdata)) - return -EBUSY; - - in_setup = false; - break; - } - - if (in_setup) { - if (fdata->is_sw) - err = -ENOTTY; - else - switch (cmd) { - case DRM_PVR_SYNC_RENAME_CMD: - err = pvr_sync_ioctl_rename(fdata->api_private, - arg); - break; - case DRM_PVR_SYNC_FORCE_SW_ONLY_CMD: - err = pvr_sync_ioctl_force_sw_only(fdata); - break; - default: - break; - } - } else { - if (!fdata->is_sw) - err = -ENOTTY; - else - switch (cmd) { - case DRM_PVR_SW_SYNC_CREATE_FENCE_CMD: - err = pvr_sync_ioctl_sw_create_fence(fdata->api_private, - arg); - break; - case DRM_PVR_SW_SYNC_INC_CMD: - err = pvr_sync_ioctl_sw_inc(fdata->api_private, - arg); - break; - default: - break; - } - } - - if (in_setup) - pvr_sync_reset_in_setup(fdata); - - return err; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.h b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.h deleted file mode 100644 index ef12dc298368f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_common.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * @File pvr_sync_ioctl_common.h - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVR_SYNC_IOCTL_COMMON_H -#define _PVR_SYNC_IOCTL_COMMON_H - -struct file; - -/* Functions provided by pvr_sync_ioctl_common */ - -int pvr_sync_open_common(void *connection_data, void *file_handle); -int pvr_sync_close_common(void *connection_data); -int pvr_sync_ioctl_common(struct file *file, unsigned int cmd, void *arg); -void *pvr_sync_get_api_priv_common(struct file *file); - -struct pvr_sync_file_data; - -/* Functions required by pvr_sync_ioctl_common */ - -bool pvr_sync_set_private_data(void *connection_data, - struct pvr_sync_file_data *fdata); - -struct pvr_sync_file_data * -pvr_sync_connection_private_data(void *connection_data); - -struct pvr_sync_file_data * -pvr_sync_get_private_data(struct file *file); - -bool pvr_sync_is_timeline(struct file *file); - -#endif /* _PVR_SYNC_IOCTL_COMMON_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.c b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.c deleted file mode 100644 index 423c8d3a75eff..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * @File pvr_sync_ioctl_drm.c - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_drv.h" -#include "pvr_drm.h" -#include "private_data.h" -#include "env_connection.h" -#include "pvr_sync_api.h" -#include "pvr_sync_ioctl_common.h" -#include "pvr_sync_ioctl_drm.h" - -bool pvr_sync_set_private_data(void *connection_data, - struct pvr_sync_file_data *fdata) -{ - if (connection_data) { - ENV_CONNECTION_DATA *env_data; - - env_data = PVRSRVConnectionPrivateData(connection_data); - if (env_data) { - env_data->pvPvrSyncPrivateData = fdata; - - return true; - } - } - - return false; -} - -struct pvr_sync_file_data * -pvr_sync_connection_private_data(void *connection_data) -{ - if (connection_data) { - ENV_CONNECTION_DATA *env_data; - - env_data = PVRSRVConnectionPrivateData(connection_data); - - if (env_data) - return env_data->pvPvrSyncPrivateData; - } - - return NULL; -} - -struct pvr_sync_file_data * -pvr_sync_get_private_data(struct file *file) -{ - CONNECTION_DATA *connection_data = LinuxSyncConnectionFromFile(file); - - return pvr_sync_connection_private_data(connection_data); -} - -bool pvr_sync_is_timeline(struct file *file) -{ - return file->f_op == &pvr_drm_fops; -} - -void *pvr_sync_get_api_priv(struct file *file) -{ - return pvr_sync_get_api_priv_common(file); -} - -struct file *pvr_sync_get_file_struct(void *file_handle) -{ - if (file_handle) { - struct drm_file *file = file_handle; - - return file->filp; - } - - return NULL; -} - -int pvr_sync_open(void *connection_data, struct drm_file *file) -{ - /* - * The file structure pointer (file->filp) may not have been - * initialised at this point, so pass down a pointer to the - * drm_file structure instead. - */ - return pvr_sync_open_common(connection_data, file); -} - -void pvr_sync_close(void *connection_data) -{ - int iErr = pvr_sync_close_common(connection_data); - - if (iErr < 0) - pr_err("%s: ERROR (%d) returned by pvr_sync_close_common()\n", - __func__, iErr); -} - - -int pvr_sync_rename_ioctl(struct drm_device __maybe_unused *dev, - void *arg, struct drm_file *file) -{ - return pvr_sync_ioctl_common(file->filp, - DRM_PVR_SYNC_RENAME_CMD, arg); -} - -int pvr_sync_force_sw_only_ioctl(struct drm_device __maybe_unused *dev, - void *arg, struct drm_file *file) -{ - return pvr_sync_ioctl_common(file->filp, - DRM_PVR_SYNC_FORCE_SW_ONLY_CMD, arg); -} - -int pvr_sw_sync_create_fence_ioctl(struct drm_device __maybe_unused *dev, - void *arg, struct drm_file *file) -{ - return pvr_sync_ioctl_common(file->filp, - DRM_PVR_SW_SYNC_CREATE_FENCE_CMD, arg); -} - -int pvr_sw_sync_inc_ioctl(struct drm_device __maybe_unused *dev, - void *arg, struct drm_file *file) -{ - return pvr_sync_ioctl_common(file->filp, - DRM_PVR_SW_SYNC_INC_CMD, arg); -} - -int pvr_sync_ioctl_init(void) -{ - return 0; -} - -void pvr_sync_ioctl_deinit(void) -{ -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.h b/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.h deleted file mode 100644 index 756ce4bf71e63..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_sync_ioctl_drm.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * @File pvr_sync_ioctl_drm.h - * @Title Kernel driver for Android's sync mechanism - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVR_SYNC_IOCTL_DRM_H -#define _PVR_SYNC_IOCTL_DRM_H - -struct drm_device; -struct drm_file; - -int pvr_sync_open(void *connection_data, struct drm_file *file); -void pvr_sync_close(void *connection_data); - -int pvr_sync_rename_ioctl(struct drm_device *dev, void *arg, - struct drm_file *file); -int pvr_sync_force_sw_only_ioctl(struct drm_device *dev, void *arg, - struct drm_file *file); -int pvr_sw_sync_create_fence_ioctl(struct drm_device *dev, void *arg, - struct drm_file *file); -int pvr_sw_sync_inc_ioctl(struct drm_device *dev, void *arg, - struct drm_file *file); - -#endif /* _PVR_SYNC_IOCTL_DRM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_uaccess.h b/drivers/gpu/drm/img-rogue/1.17/pvr_uaccess.h deleted file mode 100644 index 13864eab4c7a6..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_uaccess.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Utility functions for user space access -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_UACCESS_H -#define PVR_UACCESS_H - -#include -#include - -static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) - if (access_ok(VERIFY_WRITE, pvTo, ulBytes)) -#else - if (access_ok(pvTo, ulBytes)) -#endif - { - return __copy_to_user(pvTo, pvFrom, ulBytes); - } - - return ulBytes; -} - - -#if defined(__KLOCWORK__) - /* this part is only to tell Klocwork not to report false positive because - it doesn't understand that pvr_copy_from_user will initialise the memory - pointed to by pvTo */ -#include /* get the memset prototype */ -static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes) -{ - if (pvTo != NULL) - { - memset(pvTo, 0xAA, ulBytes); - return 0; - } - return 1; -} - -#else /* real implementation */ - -static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes) -{ - /* - * The compile time correctness checking introduced for copy_from_user in - * Linux 2.6.33 isn't fully compatible with our usage of the function. - */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) - if (access_ok(VERIFY_READ, pvFrom, ulBytes)) -#else - if (access_ok(pvFrom, ulBytes)) -#endif - { - return __copy_from_user(pvTo, pvFrom, ulBytes); - } - - return ulBytes; -} -#endif /* klocworks */ - -#endif /* PVR_UACCESS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvr_vmap.h b/drivers/gpu/drm/img-rogue/1.17/pvr_vmap.h deleted file mode 100644 index 19fe8b8f190bb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvr_vmap.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * @File pvr_vmap.h - * @Title Utility functions for virtual memory mapping - * @Codingstyle LinuxKernel - * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved - * @License Dual MIT/GPLv2 - * - * The contents of this file are subject to the MIT license as set out below. - * - * 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. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 ("GPL") in which case the provisions - * of GPL are applicable instead of those above. - * - * If you wish to allow use of your version of this file only under the terms of - * GPL, and not to allow others to use your version of this file under the terms - * of the MIT license, indicate your decision by deleting the provisions above - * and replace them with the notice and other provisions required by GPL as set - * out in the file called "GPL-COPYING" included in this distribution. If you do - * not delete the provisions above, a recipient may use your version of this file - * under the terms of either the MIT license or GPL. - * - * This License is also included in this distribution in the file called - * "MIT-COPYING". - * - * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_VMAP_H -#define PVR_VMAP_H - -#include -#include - -static inline void *pvr_vmap(struct page **pages, - unsigned int count, - __maybe_unused unsigned long flags, - pgprot_t prot) -{ -#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS) - return vmap(pages, count, flags, prot); -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - return vm_map_ram(pages, count, -1, prot); -#else - if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) - return vm_map_ram(pages, count, -1); - else - return vmap(pages, count, flags, prot); -#endif /* !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS) */ -} - -static inline void pvr_vunmap(void *pages, - __maybe_unused unsigned int count, - __maybe_unused pgprot_t prot) -{ -#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS) - vunmap(pages); -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - vm_unmap_ram(pages, count); -#else - if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) - vm_unmap_ram(pages, count); - else - vunmap(pages); -#endif /* !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS) */ -} - -#endif /* PVR_VMAP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrmodule.h b/drivers/gpu/drm/img-rogue/1.17/pvrmodule.h deleted file mode 100644 index 267c7b6874872..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrmodule.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ /*! -@Title Module Author and License. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 _PVRMODULE_H_ -#define _PVRMODULE_H_ - -MODULE_AUTHOR("Imagination Technologies Ltd. "); -MODULE_LICENSE("Dual MIT/GPL"); - -#endif /* _PVRMODULE_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv.c b/drivers/gpu/drm/img-rogue/1.17/pvrsrv.c deleted file mode 100644 index bd564e33ceb90..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv.c +++ /dev/null @@ -1,3003 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title core services functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main APIs for core services functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgxdebug.h" -#include "handle.h" -#include "connection_server.h" -#include "osconnection_server.h" -#include "pdump_km.h" -#include "ra.h" -#include "allocmem.h" -#include "pmr.h" -#include "pvrsrv.h" -#include "srvcore.h" -#include "services_km.h" -#include "pvrsrv_device.h" -#include "pvr_debug.h" -#include "debug_common.h" -#include "pvr_notifier.h" -#include "sync.h" -#include "sync_server.h" -#include "sync_checkpoint.h" -#include "sync_fallback_server.h" -#include "sync_checkpoint_init.h" -#include "devicemem.h" -#include "cache_km.h" -#include "info_page.h" -#include "info_page_defs.h" -#include "pvrsrv_bridge_init.h" -#include "devicemem_server.h" -#include "km_apphint_defs.h" -#include "di_server.h" -#include "di_impl_brg.h" -#include "htb_debug.h" -#include "dma_km.h" - -#include "log2.h" - -#include "lists.h" -#include "dllist.h" -#include "syscommon.h" -#include "sysvalidation.h" - -#include "physmem_lma.h" -#include "physmem_osmem.h" -#include "physmem_hostmem.h" - -#include "tlintern.h" -#include "htbserver.h" - -//#define MULTI_DEVICE_BRINGUP - -#if defined(MULTI_DEVICE_BRINGUP) -#define MULTI_DEVICE_BRINGUP_DPF(msg, ...) PVR_DPF((PVR_DBG_MESSAGE, msg, __VA_ARGS__)) -#else -#define MULTI_DEVICE_BRINGUP_DPF(msg, ...) -#endif - -#if defined(SUPPORT_RGX) -#include "rgxinit.h" -#include "rgxhwperf.h" -#include "rgxfwutils.h" -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -#include "ri_server.h" -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif - -#include "vz_vmm_pvz.h" - -#include "devicemem_history_server.h" - -#if defined(SUPPORT_LINUX_DVFS) -#include "pvr_dvfs_device.h" -#endif - -#if defined(SUPPORT_DISPLAY_CLASS) -#include "dc_server.h" -#endif - -#include "rgx_options.h" -#include "srvinit.h" -#include "rgxutils.h" - -#include "oskm_apphint.h" -#include "pvrsrv_apphint.h" - -#include "pvrsrv_tlstreams.h" -#include "tlstream.h" - -#if defined(SUPPORT_PHYSMEM_TEST) && !defined(INTEGRITY_OS) && !defined(__QNXNTO__) -#include "physmem_test.h" -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -#if defined(__linux__) -#include "km_apphint.h" -#endif /* defined(__linux__) */ - -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) -#define INFINITE_SLEEP_TIMEOUT 0ULL -#endif - -/*! Wait 100ms before retrying deferred clean-up again */ -#define CLEANUP_THREAD_WAIT_RETRY_TIMEOUT 100000ULL - -/*! Wait 8hrs when no deferred clean-up required. Allows a poll several times - * a day to check for any missed clean-up. */ -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) -#define CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT INFINITE_SLEEP_TIMEOUT -#else -#define CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT 28800000000ULL -#endif - -/*! When unloading try a few times to free everything remaining on the list */ -#define CLEANUP_THREAD_UNLOAD_RETRY 4 - -#define PVRSRV_TL_CTLR_STREAM_SIZE 4096 - -static PVRSRV_DATA *gpsPVRSRVData; -static IMG_UINT32 g_ui32InitFlags; - -/* mark which parts of Services were initialised */ -#define INIT_DATA_ENABLE_PDUMPINIT 0x1U - -/* Callback to dump info of cleanup thread in debug_dump */ -static void CleanupThreadDumpInfo(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DATA *psPVRSRVData; - psPVRSRVData = PVRSRVGetPVRSRVData(); - - PVR_DUMPDEBUG_LOG(" Number of deferred cleanup items Queued : %u", - OSAtomicRead(&psPVRSRVData->i32NumCleanupItemsQueued)); - PVR_DUMPDEBUG_LOG(" Number of deferred cleanup items dropped after " - "retry limit reached : %u", - OSAtomicRead(&psPVRSRVData->i32NumCleanupItemsNotCompleted)); -} - -/* Add work to the cleanup thread work list. - * The work item will be executed by the cleanup thread - */ -void PVRSRVCleanupThreadAddWork(PVRSRV_CLEANUP_THREAD_WORK *psData) -{ - PVRSRV_DATA *psPVRSRVData; - PVRSRV_ERROR eError; - - psPVRSRVData = PVRSRVGetPVRSRVData(); - - PVR_ASSERT(psData != NULL); -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK || psPVRSRVData->bUnload) -#else - if (psPVRSRVData->bUnload) -#endif - { - CLEANUP_THREAD_FN pfnFree = psData->pfnFree; - - PVR_DPF((PVR_DBG_MESSAGE, "Cleanup thread has already quit: doing work immediately")); - - eError = pfnFree(psData->pvData); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to free resource " - "(callback " IMG_PFN_FMTSPEC "). " - "Immediate free will not be retried.", - pfnFree)); - } - } - else - { - OS_SPINLOCK_FLAGS uiFlags; - - /* add this work item to the list */ - OSSpinLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - dllist_add_to_tail(&psPVRSRVData->sCleanupThreadWorkList, &psData->sNode); - OSSpinLockRelease(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - - OSAtomicIncrement(&psPVRSRVData->i32NumCleanupItemsQueued); - - /* signal the cleanup thread to ensure this item gets processed */ - eError = OSEventObjectSignal(psPVRSRVData->hCleanupEventObject); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } -} - -/* Pop an item from the head of the cleanup thread work list */ -static INLINE DLLIST_NODE *_CleanupThreadWorkListPop(PVRSRV_DATA *psPVRSRVData) -{ - DLLIST_NODE *psNode; - OS_SPINLOCK_FLAGS uiFlags; - - OSSpinLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - psNode = dllist_get_next_node(&psPVRSRVData->sCleanupThreadWorkList); - if (psNode != NULL) - { - dllist_remove_node(psNode); - } - OSSpinLockRelease(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - - return psNode; -} - -/* Process the cleanup thread work list */ -static IMG_BOOL _CleanupThreadProcessWorkList(PVRSRV_DATA *psPVRSRVData, - IMG_BOOL *pbUseGlobalEO) -{ - DLLIST_NODE *psNodeIter, *psNodeLast; - PVRSRV_ERROR eError; - IMG_BOOL bNeedRetry = IMG_FALSE; - OS_SPINLOCK_FLAGS uiFlags; - - /* any callback functions which return error will be - * moved to the back of the list, and additional items can be added - * to the list at any time so we ensure we only iterate from the - * head of the list to the current tail (since the tail may always - * be changing) - */ - - OSSpinLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - psNodeLast = dllist_get_prev_node(&psPVRSRVData->sCleanupThreadWorkList); - OSSpinLockRelease(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - - if (psNodeLast == NULL) - { - /* no elements to clean up */ - return IMG_FALSE; - } - - do - { - psNodeIter = _CleanupThreadWorkListPop(psPVRSRVData); - - if (psNodeIter != NULL) - { - PVRSRV_CLEANUP_THREAD_WORK *psData = IMG_CONTAINER_OF(psNodeIter, PVRSRV_CLEANUP_THREAD_WORK, sNode); - CLEANUP_THREAD_FN pfnFree; - - /* get the function pointer address here so we have access to it - * in order to report the error in case of failure, without having - * to depend on psData not having been freed - */ - pfnFree = psData->pfnFree; - - *pbUseGlobalEO = psData->bDependsOnHW; - eError = pfnFree(psData->pvData); - - if (eError != PVRSRV_OK) - { - /* move to back of the list, if this item's - * retry count hasn't hit zero. - */ - if (CLEANUP_THREAD_IS_RETRY_TIMEOUT(psData)) - { - if (CLEANUP_THREAD_RETRY_TIMEOUT_REACHED(psData)) - { - bNeedRetry = IMG_TRUE; - } - } - else - { - if (psData->ui32RetryCount-- > 0) - { - bNeedRetry = IMG_TRUE; - } - } - - if (bNeedRetry) - { - OSSpinLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - dllist_add_to_tail(&psPVRSRVData->sCleanupThreadWorkList, psNodeIter); - OSSpinLockRelease(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "Failed to free resource " - "(callback " IMG_PFN_FMTSPEC "). " - "Retry limit reached", - pfnFree)); - OSAtomicDecrement(&psPVRSRVData->i32NumCleanupItemsQueued); - OSAtomicIncrement(&psPVRSRVData->i32NumCleanupItemsNotCompleted); - - } - } - else - { - OSAtomicDecrement(&psPVRSRVData->i32NumCleanupItemsQueued); - } - } - } while ((psNodeIter != NULL) && (psNodeIter != psNodeLast)); - - return bNeedRetry; -} - -// #define CLEANUP_DPFL PVR_DBG_WARNING -#define CLEANUP_DPFL PVR_DBG_MESSAGE - -/* Create/initialise data required by the cleanup thread, - * before the cleanup thread is started - */ -static PVRSRV_ERROR _CleanupThreadPrepare(PVRSRV_DATA *psPVRSRVData) -{ - PVRSRV_ERROR eError; - - /* Create the clean up event object */ - - eError = OSEventObjectCreate("PVRSRV_CLEANUP_EVENTOBJECT", &gpsPVRSRVData->hCleanupEventObject); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", Exit); - - /* initialise the mutex and linked list required for the cleanup thread work list */ - - eError = OSSpinLockCreate(&psPVRSRVData->hCleanupThreadWorkListLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", Exit); - - dllist_init(&psPVRSRVData->sCleanupThreadWorkList); - -Exit: - return eError; -} - -static void CleanupThread(void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = pvData; - IMG_BOOL bRetryWorkList = IMG_FALSE; - IMG_HANDLE hGlobalEvent; - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eRc; - IMG_BOOL bUseGlobalEO = IMG_FALSE; - IMG_UINT32 uiUnloadRetry = 0; - - /* Store the process id (pid) of the clean-up thread */ - psPVRSRVData->cleanupThreadPid = OSGetCurrentProcessID(); - psPVRSRVData->cleanupThreadTid = OSGetCurrentThreadID(); - OSAtomicWrite(&psPVRSRVData->i32NumCleanupItemsQueued, 0); - OSAtomicWrite(&psPVRSRVData->i32NumCleanupItemsNotCompleted, 0); - - PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread starting... ")); - - /* Open an event on the clean up event object so we can listen on it, - * abort the clean up thread and driver if this fails. - */ - eRc = OSEventObjectOpen(psPVRSRVData->hCleanupEventObject, &hOSEvent); - PVR_ASSERT(eRc == PVRSRV_OK); - - eRc = OSEventObjectOpen(psPVRSRVData->hGlobalEventObject, &hGlobalEvent); - PVR_ASSERT(eRc == PVRSRV_OK); - - /* While the driver is in a good state and is not being unloaded - * try to free any deferred items when signalled - */ - while (psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) - { - IMG_HANDLE hEvent; - - if (psPVRSRVData->bUnload) - { - if (dllist_is_empty(&psPVRSRVData->sCleanupThreadWorkList) || - uiUnloadRetry > CLEANUP_THREAD_UNLOAD_RETRY) - { - break; - } - uiUnloadRetry++; - } - - /* Wait until signalled for deferred clean up OR wait for a - * short period if the previous deferred clean up was not able - * to release all the resources before trying again. - * Bridge lock re-acquired on our behalf before the wait call returns. - */ - - if (bRetryWorkList && bUseGlobalEO) - { - hEvent = hGlobalEvent; - } - else - { - hEvent = hOSEvent; - } - - eRc = OSEventObjectWaitKernel(hEvent, - bRetryWorkList ? - CLEANUP_THREAD_WAIT_RETRY_TIMEOUT : - CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT); - if (eRc == PVRSRV_ERROR_TIMEOUT) - { - PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait timeout")); - } - else if (eRc == PVRSRV_OK) - { - PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait OK, signal received")); - } - else - { - PVR_LOG_ERROR(eRc, "OSEventObjectWaitKernel"); - } - - bRetryWorkList = _CleanupThreadProcessWorkList(psPVRSRVData, &bUseGlobalEO); - } - - OSSpinLockDestroy(psPVRSRVData->hCleanupThreadWorkListLock); - - eRc = OSEventObjectClose(hOSEvent); - PVR_LOG_IF_ERROR(eRc, "OSEventObjectClose"); - - eRc = OSEventObjectClose(hGlobalEvent); - PVR_LOG_IF_ERROR(eRc, "OSEventObjectClose"); - - PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread ending... ")); -} - -IMG_PID PVRSRVCleanupThreadGetPid(void) -{ - return gpsPVRSRVData->cleanupThreadPid; -} - -uintptr_t PVRSRVCleanupThreadGetTid(void) -{ - return gpsPVRSRVData->cleanupThreadTid; -} - -static void DevicesWatchdogThread_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, - va_list va) -{ -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice; -#endif - PVRSRV_DEVICE_HEALTH_STATUS *pePreviousHealthStatus, eHealthStatus; - PVRSRV_ERROR eError; - PVRSRV_DEVICE_DEBUG_DUMP_STATUS eDebugDumpState; - IMG_BOOL bCheckAfterTimePassed; - - pePreviousHealthStatus = va_arg(va, PVRSRV_DEVICE_HEALTH_STATUS *); - bCheckAfterTimePassed = va_arg(va, IMG_BOOL); - - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - return; - } - - if (psDeviceNode->pfnUpdateHealthStatus != NULL) - { - eError = psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, bCheckAfterTimePassed); - PVR_WARN_IF_ERROR(eError, "pfnUpdateHealthStatus"); - } - eHealthStatus = OSAtomicRead(&psDeviceNode->eHealthStatus); - - if (eHealthStatus != PVRSRV_DEVICE_HEALTH_STATUS_OK) - { - if (eHealthStatus != *pePreviousHealthStatus) - { -#if defined(SUPPORT_RGX) - if (!(psDevInfo->ui32DeviceFlags & - RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN)) -#else - /* In this case we don't have an RGX device */ - if (eHealthStatus != PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED) -#endif - { - PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: " - "Device status not OK!!!")); - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, - NULL, NULL); - } - } - } - - *pePreviousHealthStatus = eHealthStatus; - - /* Have we received request from FW to capture debug dump(could be due to HWR) */ - eDebugDumpState = (PVRSRV_DEVICE_DEBUG_DUMP_STATUS)OSAtomicCompareExchange( - &psDeviceNode->eDebugDumpRequested, - PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE, - PVRSRV_DEVICE_DEBUG_DUMP_NONE); - if (PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE == eDebugDumpState) - { - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - } - -} - -#if defined(SUPPORT_RGX) -static void HWPerfPeriodicHostEventsThread(void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = pvData; - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eError; - - eError = OSEventObjectOpen(psPVRSRVData->hHWPerfHostPeriodicEvObj, &hOSEvent); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectOpen"); - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && - !psPVRSRVData->bUnload && !psPVRSRVData->bHWPerfHostThreadStop) -#else - while (!psPVRSRVData->bUnload && !psPVRSRVData->bHWPerfHostThreadStop) -#endif - { - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_BOOL bInfiniteSleep = IMG_TRUE; - - eError = OSEventObjectWaitKernel(hOSEvent, (IMG_UINT64)psPVRSRVData->ui32HWPerfHostThreadTimeout * 1000); - if (eError == PVRSRV_OK && (psPVRSRVData->bUnload || psPVRSRVData->bHWPerfHostThreadStop)) - { - PVR_DPF((PVR_DBG_MESSAGE, "HWPerfPeriodicHostEventsThread: Shutdown event received.")); - break; - } - - for (psDeviceNode = psPVRSRVData->psDeviceNodeList; - psDeviceNode != NULL; - psDeviceNode = psDeviceNode->psNext) - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* If the psDevInfo or hHWPerfHostStream are NULL it most - * likely means that this device or stream has not been - * initialised yet, so just skip */ - if (psDevInfo == NULL || psDevInfo->hHWPerfHostStream == NULL) - { - continue; - } - - /* Check if the HWPerf host stream is open for reading before writing - * a packet, this covers cases where the event filter is not zeroed - * before a reader disconnects. */ - if (TLStreamIsOpenForReading(psDevInfo->hHWPerfHostStream)) - { - /* As long as any of the streams is opened don't go into - * indefinite sleep. */ - bInfiniteSleep = IMG_FALSE; -#if defined(SUPPORT_RGX) - RGXSRV_HWPERF_HOST_INFO(psDevInfo, RGX_HWPERF_INFO_EV_MEM_USAGE); -#endif - } - } - - if (bInfiniteSleep) - { -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - psPVRSRVData->ui32HWPerfHostThreadTimeout = INFINITE_SLEEP_TIMEOUT; -#else - /* Use an 8 hour timeout if indefinite sleep is not supported. */ - psPVRSRVData->ui32HWPerfHostThreadTimeout = 60 * 60 * 8 * 1000; -#endif - } - } - - eError = OSEventObjectClose(hOSEvent); - PVR_LOG_IF_ERROR(eError, "OSEventObjectClose"); -} -#endif - -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - -typedef enum -{ - DWT_ST_INIT, - DWT_ST_SLEEP_POWERON, - DWT_ST_SLEEP_POWEROFF, - DWT_ST_SLEEP_DEFERRED, - DWT_ST_FINAL -} DWT_STATE; - -typedef enum -{ - DWT_SIG_POWERON, - DWT_SIG_POWEROFF, - DWT_SIG_TIMEOUT, - DWT_SIG_UNLOAD, - DWT_SIG_ERROR -} DWT_SIGNAL; - -static inline IMG_BOOL _DwtIsPowerOn(PVRSRV_DATA *psPVRSRVData) -{ - return List_PVRSRV_DEVICE_NODE_IMG_BOOL_Any(psPVRSRVData->psDeviceNodeList, - PVRSRVIsDevicePowered); -} - -static inline void _DwtCheckHealthStatus(PVRSRV_DATA *psPVRSRVData, - PVRSRV_DEVICE_HEALTH_STATUS *peStatus, - IMG_BOOL bTimeOut) -{ - List_PVRSRV_DEVICE_NODE_ForEach_va(psPVRSRVData->psDeviceNodeList, - DevicesWatchdogThread_ForEachVaCb, - peStatus, - bTimeOut); -} - -static DWT_SIGNAL _DwtWait(PVRSRV_DATA *psPVRSRVData, IMG_HANDLE hOSEvent, - IMG_UINT32 ui32Timeout) -{ - PVRSRV_ERROR eError; - - eError = OSEventObjectWaitKernel(hOSEvent, (IMG_UINT64) ui32Timeout * 1000); - -#ifdef PVR_TESTING_UTILS - psPVRSRVData->ui32DevicesWdWakeupCounter++; -#endif - - if (eError == PVRSRV_OK) - { - if (psPVRSRVData->bUnload) - { - PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Shutdown event" - " received.")); - return DWT_SIG_UNLOAD; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power state " - "change event received.")); - - if (_DwtIsPowerOn(psPVRSRVData)) - { - return DWT_SIG_POWERON; - } - else - { - return DWT_SIG_POWEROFF; - } - } - } - else if (eError == PVRSRV_ERROR_TIMEOUT) - { - return DWT_SIG_TIMEOUT; - } - - PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: Error (%d) when" - " waiting for event!", eError)); - return DWT_SIG_ERROR; -} - -#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - -static void DevicesWatchdogThread(void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = pvData; - PVRSRV_DEVICE_HEALTH_STATUS ePreviousHealthStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK; - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eError; -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - DWT_STATE eState = DWT_ST_INIT; - const IMG_UINT32 ui32OnTimeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT; - const IMG_UINT32 ui32OffTimeout = INFINITE_SLEEP_TIMEOUT; -#else - IMG_UINT32 ui32Timeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT; - /* Flag used to defer the sleep timeout change by 1 loop iteration. - * This helps to ensure at least two health checks are performed before a long sleep. - */ - IMG_BOOL bDoDeferredTimeoutChange = IMG_FALSE; -#endif - - PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power off sleep time: %d.", - DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT)); - - /* Open an event on the devices watchdog event object so we can listen on it - and abort the devices watchdog thread. */ - eError = OSEventObjectOpen(psPVRSRVData->hDevicesWatchdogEvObj, &hOSEvent); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectOpen"); - - /* Loop continuously checking the device status every few seconds. */ -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && - !psPVRSRVData->bUnload) -#else - while (!psPVRSRVData->bUnload) -#endif - { -#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - - switch (eState) - { - case DWT_ST_INIT: - { - if (_DwtIsPowerOn(psPVRSRVData)) - { - eState = DWT_ST_SLEEP_POWERON; - } - else - { - eState = DWT_ST_SLEEP_POWEROFF; - } - - break; - } - case DWT_ST_SLEEP_POWERON: - { - DWT_SIGNAL eSignal = _DwtWait(psPVRSRVData, hOSEvent, - ui32OnTimeout); - - switch (eSignal) { - case DWT_SIG_POWERON: - /* self-transition, nothing to do */ - break; - case DWT_SIG_POWEROFF: - eState = DWT_ST_SLEEP_DEFERRED; - break; - case DWT_SIG_TIMEOUT: - _DwtCheckHealthStatus(psPVRSRVData, - &ePreviousHealthStatus, - IMG_TRUE); - /* self-transition */ - break; - case DWT_SIG_UNLOAD: - eState = DWT_ST_FINAL; - break; - case DWT_SIG_ERROR: - /* deliberately ignored */ - break; - } - - break; - } - case DWT_ST_SLEEP_POWEROFF: - { - DWT_SIGNAL eSignal = _DwtWait(psPVRSRVData, hOSEvent, - ui32OffTimeout); - - switch (eSignal) { - case DWT_SIG_POWERON: - eState = DWT_ST_SLEEP_POWERON; - _DwtCheckHealthStatus(psPVRSRVData, - &ePreviousHealthStatus, - IMG_FALSE); - break; - case DWT_SIG_POWEROFF: - /* self-transition, nothing to do */ - break; - case DWT_SIG_TIMEOUT: - /* self-transition */ - _DwtCheckHealthStatus(psPVRSRVData, - &ePreviousHealthStatus, - IMG_TRUE); - break; - case DWT_SIG_UNLOAD: - eState = DWT_ST_FINAL; - break; - case DWT_SIG_ERROR: - /* deliberately ignored */ - break; - } - - break; - } - case DWT_ST_SLEEP_DEFERRED: - { - DWT_SIGNAL eSignal =_DwtWait(psPVRSRVData, hOSEvent, - ui32OnTimeout); - - switch (eSignal) { - case DWT_SIG_POWERON: - eState = DWT_ST_SLEEP_POWERON; - _DwtCheckHealthStatus(psPVRSRVData, - &ePreviousHealthStatus, - IMG_FALSE); - break; - case DWT_SIG_POWEROFF: - /* self-transition, nothing to do */ - break; - case DWT_SIG_TIMEOUT: - eState = DWT_ST_SLEEP_POWEROFF; - _DwtCheckHealthStatus(psPVRSRVData, - &ePreviousHealthStatus, - IMG_FALSE); - break; - case DWT_SIG_UNLOAD: - eState = DWT_ST_FINAL; - break; - case DWT_SIG_ERROR: - /* deliberately ignored */ - break; - } - - break; - } - case DWT_ST_FINAL: - /* the loop should terminate on next spin if this state is - * reached so nothing to do here. */ - break; - } - -#else /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - IMG_BOOL bPwrIsOn = IMG_FALSE; - IMG_BOOL bTimeOut = IMG_FALSE; - - /* Wait time between polls (done at the start of the loop to allow devices - to initialise) or for the event signal (shutdown or power on). */ - eError = OSEventObjectWaitKernel(hOSEvent, (IMG_UINT64)ui32Timeout * 1000); - -#ifdef PVR_TESTING_UTILS - psPVRSRVData->ui32DevicesWdWakeupCounter++; -#endif - if (eError == PVRSRV_OK) - { - if (psPVRSRVData->bUnload) - { - PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Shutdown event received.")); - break; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power state change event received.")); - } - } - else if (eError != PVRSRV_ERROR_TIMEOUT) - { - /* If timeout do nothing otherwise print warning message. */ - PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: " - "Error (%d) when waiting for event!", eError)); - } - else - { - bTimeOut = IMG_TRUE; - } - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - List_PVRSRV_DEVICE_NODE_ForEach_va(psPVRSRVData->psDeviceNodeList, - DevicesWatchdogThread_ForEachVaCb, - &ePreviousHealthStatus, - bTimeOut); - bPwrIsOn = List_PVRSRV_DEVICE_NODE_IMG_BOOL_Any(psPVRSRVData->psDeviceNodeList, - PVRSRVIsDevicePowered); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - if (bPwrIsOn || psPVRSRVData->ui32DevicesWatchdogPwrTrans) - { - psPVRSRVData->ui32DevicesWatchdogPwrTrans = 0; - ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT; - bDoDeferredTimeoutChange = IMG_FALSE; - } - else - { - /* First, check if the previous loop iteration signalled a need to change the timeout period */ - if (bDoDeferredTimeoutChange) - { - ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT; - bDoDeferredTimeoutChange = IMG_FALSE; - } - else - { - /* Signal that we need to change the sleep timeout in the next loop iteration - * to allow the device health check code a further iteration at the current - * sleep timeout in order to determine bad health (e.g. stalled cCCB) by - * comparing past and current state snapshots */ - bDoDeferredTimeoutChange = IMG_TRUE; - } - } - -#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */ - } - - eError = OSEventObjectClose(hOSEvent); - PVR_LOG_IF_ERROR(eError, "OSEventObjectClose"); -} - -#if defined(SUPPORT_AUTOVZ) -static void AutoVzWatchdogThread_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - return; - } - else if (psDeviceNode->pfnUpdateAutoVzWatchdog != NULL) - { - psDeviceNode->pfnUpdateAutoVzWatchdog(psDeviceNode); - } -} - -static void AutoVzWatchdogThread(void *pvData) -{ - PVRSRV_DATA *psPVRSRVData = pvData; - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eError; - IMG_UINT32 ui32Timeout = PVR_AUTOVZ_WDG_PERIOD_MS / 3; - - /* Open an event on the devices watchdog event object so we can listen on it - and abort the devices watchdog thread. */ - eError = OSEventObjectOpen(psPVRSRVData->hAutoVzWatchdogEvObj, &hOSEvent); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectOpen"); - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && - !psPVRSRVData->bUnload) -#else - while (!psPVRSRVData->bUnload) -#endif - { - /* Wait time between polls (done at the start of the loop to allow devices - to initialise) or for the event signal (shutdown or power on). */ - eError = OSEventObjectWaitKernel(hOSEvent, (IMG_UINT64)ui32Timeout * 1000); - - List_PVRSRV_DEVICE_NODE_ForEach(psPVRSRVData->psDeviceNodeList, - AutoVzWatchdogThread_ForEachCb); - } - - eError = OSEventObjectClose(hOSEvent); - PVR_LOG_IF_ERROR(eError, "OSEventObjectClose"); -} -#endif /* SUPPORT_AUTOVZ */ - -PVRSRV_DATA *PVRSRVGetPVRSRVData(void) -{ - return gpsPVRSRVData; -} - -static PVRSRV_ERROR InitialiseInfoPageTimeouts(PVRSRV_DATA *psPVRSRVData) -{ - if (NULL == psPVRSRVData) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_VALUE_RETRIES] = WAIT_TRY_COUNT; - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_VALUE_TIMEOUT_MS] = - ((MAX_HW_TIME_US / 10000) + 1000); - /* TIMEOUT_INFO_VALUE_TIMEOUT_MS resolves to... - vp : 2000 + 1000 - emu : 2000 + 1000 - rgx_nohw : 50 + 1000 - plato : 30000 + 1000 (VIRTUAL_PLATFORM or EMULATOR) - 50 + 1000 (otherwise) - */ - - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_CONDITION_RETRIES] = 5; - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_CONDITION_TIMEOUT_MS] = - ((MAX_HW_TIME_US / 10000) + 100); - /* TIMEOUT_INFO_CONDITION_TIMEOUT_MS resolves to... - vp : 2000 + 100 - emu : 2000 + 100 - rgx_nohw : 50 + 100 - plato : 30000 + 100 (VIRTUAL_PLATFORM or EMULATOR) - 50 + 100 (otherwise) - */ - - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_RETRIES] = 10; -#if defined(VIRTUAL_PLATFORM) - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS] = 1200000U; -#else -#if defined(EMULATOR) - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS] = 20000U; -#else - psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS] = 1000U; -#endif /* EMULATOR */ -#endif - - return PVRSRV_OK; -} - -static PVRSRV_ERROR PopulateInfoPageBridges(PVRSRV_DATA *psPVRSRVData) -{ - PVR_RETURN_IF_INVALID_PARAM(psPVRSRVData); - - psPVRSRVData->pui32InfoPage[BRIDGE_INFO_PVR_BRIDGES] = gui32PVRBridges; - -#if defined(SUPPORT_RGX) - psPVRSRVData->pui32InfoPage[BRIDGE_INFO_RGX_BRIDGES] = gui32RGXBridges; -#else - psPVRSRVData->pui32InfoPage[BRIDGE_INFO_RGX_BRIDGES] = 0; -#endif - - return PVRSRV_OK; -} - -static void _ThreadsDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDbgRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVR_UNREFERENCED_PARAMETER(hDbgRequestHandle); - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH)) - { - PVR_DUMPDEBUG_LOG("------[ Server Thread Summary ]------"); - OSThreadDumpInfo(pfnDumpDebugPrintf, pvDumpDebugFile); - } -} - -PVRSRV_ERROR -PVRSRVCommonDriverInit(void) -{ - PVRSRV_ERROR eError; - - PVRSRV_DATA *psPVRSRVData = NULL; - - IMG_UINT32 ui32AppHintCleanupThreadPriority; - IMG_UINT32 ui32AppHintWatchdogThreadPriority; - IMG_BOOL bEnablePageFaultDebug; - IMG_BOOL bEnableFullSyncTracking; - - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault; - - /* - * As this function performs one time driver initialisation, use the - * Services global device-independent data to determine whether or not - * this function has already been called. - */ - if (gpsPVRSRVData) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Driver already initialised", __func__)); - return PVRSRV_ERROR_ALREADY_EXISTS; - } - - /* - * Allocate the device-independent data - */ - psPVRSRVData = OSAllocZMem(sizeof(*gpsPVRSRVData)); - PVR_GOTO_IF_NOMEM(psPVRSRVData, eError, Error); - - /* Now it is set up, point gpsPVRSRVData to the actual data */ - gpsPVRSRVData = psPVRSRVData; - - eError = OSWRLockCreate(&gpsPVRSRVData->hDeviceNodeListLock); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Register the driver context debug table */ - eError = PVRSRVRegisterDriverDbgTable(); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Register the Server Thread Debug notifier */ - eError = PVRSRVRegisterDriverDbgRequestNotify(&gpsPVRSRVData->hThreadsDbgReqNotify, - _ThreadsDebugRequestNotify, - DEBUG_REQUEST_SRV, - NULL); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = DIInit(); - PVR_GOTO_IF_ERROR(eError, Error); - -#if defined(SUPPORT_DI_BRG_IMPL) - eError = PVRDIImplBrgRegister(); - PVR_GOTO_IF_ERROR(eError, Error); -#endif - -#ifdef PVRSRV_ENABLE_PROCESS_STATS - eError = PVRSRVStatsInitialise(); - PVR_GOTO_IF_ERROR(eError, Error); -#endif /* PVRSRV_ENABLE_PROCESS_STATS */ - - eError = HTB_CreateDIEntry(); - PVR_GOTO_IF_ERROR(eError, Error); - - /* - * Initialise the server bridges - */ - eError = ServerBridgeInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = PhysHeapInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = DevmemIntInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = DebugCommonInitDriver(); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = BridgeDispatcherInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Init any OS specific's */ - eError = OSInitEnvData(); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Early init. server cache maintenance */ - eError = CacheOpInit(); - PVR_GOTO_IF_ERROR(eError, Error); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - RIInitKM(); -#endif - - ui32AppHintDefault = PVRSRV_APPHINT_ENABLEPAGEFAULTDEBUG; - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintBOOL(APPHINT_NO_DEVICE, pvAppHintState, EnablePageFaultDebug, - &ui32AppHintDefault, &bEnablePageFaultDebug); - OSFreeKMAppHintState(pvAppHintState); - - if (bEnablePageFaultDebug) - { - eError = DevicememHistoryInitKM(); - PVR_LOG_GOTO_IF_ERROR(eError, "DevicememHistoryInitKM", Error); - } - - eError = PMRInit(); - PVR_GOTO_IF_ERROR(eError, Error); - -#if defined(SUPPORT_DISPLAY_CLASS) - eError = DCInit(); - PVR_GOTO_IF_ERROR(eError, Error); -#endif - - /* Initialise overall system state */ - gpsPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_OK; - - /* Create an event object */ - eError = OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", &gpsPVRSRVData->hGlobalEventObject); - PVR_GOTO_IF_ERROR(eError, Error); - gpsPVRSRVData->ui32GEOConsecutiveTimeouts = 0; - - eError = PVRSRVCmdCompleteInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = PVRSRVHandleInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - OSCreateKMAppHintState(&pvAppHintState); - ui32AppHintDefault = PVRSRV_APPHINT_CLEANUPTHREADPRIORITY; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, CleanupThreadPriority, - &ui32AppHintDefault, &ui32AppHintCleanupThreadPriority); - - ui32AppHintDefault = PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, WatchdogThreadPriority, - &ui32AppHintDefault, &ui32AppHintWatchdogThreadPriority); - - ui32AppHintDefault = PVRSRV_APPHINT_ENABLEFULLSYNCTRACKING; - OSGetKMAppHintBOOL(APPHINT_NO_DEVICE, pvAppHintState, EnableFullSyncTracking, - &ui32AppHintDefault, &bEnableFullSyncTracking); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - eError = _CleanupThreadPrepare(gpsPVRSRVData); - PVR_LOG_GOTO_IF_ERROR(eError, "_CleanupThreadPrepare", Error); - - /* Create a thread which is used to do the deferred cleanup */ - eError = OSThreadCreatePriority(&gpsPVRSRVData->hCleanupThread, - "pvr_defer_free", - CleanupThread, - CleanupThreadDumpInfo, - IMG_TRUE, - gpsPVRSRVData, - ui32AppHintCleanupThreadPriority); - PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreatePriority:1", Error); - - /* Create the devices watchdog event object */ - eError = OSEventObjectCreate("PVRSRV_DEVICESWATCHDOG_EVENTOBJECT", &gpsPVRSRVData->hDevicesWatchdogEvObj); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", Error); - - /* Create a thread which is used to detect fatal errors */ - eError = OSThreadCreatePriority(&gpsPVRSRVData->hDevicesWatchdogThread, - "pvr_device_wdg", - DevicesWatchdogThread, - NULL, - IMG_TRUE, - gpsPVRSRVData, - ui32AppHintWatchdogThreadPriority); - PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreatePriority:2", Error); - -#if defined(SUPPORT_AUTOVZ) - /* Create the devices watchdog event object */ - eError = OSEventObjectCreate("PVRSRV_AUTOVZ_WATCHDOG_EVENTOBJECT", &gpsPVRSRVData->hAutoVzWatchdogEvObj); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", Error); - - /* Create a thread that maintains the FW-KM connection by regularly updating the virtualization watchdog */ - eError = OSThreadCreatePriority(&gpsPVRSRVData->hAutoVzWatchdogThread, - "pvr_autovz_wdg", - AutoVzWatchdogThread, - NULL, - IMG_TRUE, - gpsPVRSRVData, - OS_THREAD_HIGHEST_PRIORITY); - PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreatePriority:3", Error); -#endif /* SUPPORT_AUTOVZ */ - -#if defined(SUPPORT_RGX) - eError = OSLockCreate(&gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", Error); -#endif - - eError = HostMemDeviceCreate(&gpsPVRSRVData->psHostMemDeviceNode); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Initialise the Transport Layer */ - eError = TLInit(); - PVR_GOTO_IF_ERROR(eError, Error); - - /* Initialise pdump */ - eError = PDUMPINIT(); - PVR_GOTO_IF_ERROR(eError, Error); - - g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT; - - /* Initialise TL control stream */ - eError = TLStreamCreate(&psPVRSRVData->hTLCtrlStream, - PVRSRV_TL_CTLR_STREAM, PVRSRV_TL_CTLR_STREAM_SIZE, - TL_OPMODE_DROP_OLDEST, NULL, NULL, NULL, - NULL); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "TLStreamCreate"); - psPVRSRVData->hTLCtrlStream = NULL; - } - - eError = InfoPageCreate(psPVRSRVData); - PVR_LOG_GOTO_IF_ERROR(eError, "InfoPageCreate", Error); - - - /* Initialise the Timeout Info */ - eError = InitialiseInfoPageTimeouts(psPVRSRVData); - PVR_GOTO_IF_ERROR(eError, Error); - - eError = PopulateInfoPageBridges(psPVRSRVData); - - PVR_GOTO_IF_ERROR(eError, Error); - - if (bEnableFullSyncTracking) - { - psPVRSRVData->pui32InfoPage[DEBUG_FEATURE_FLAGS] |= DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED; - } - if (bEnablePageFaultDebug) - { - psPVRSRVData->pui32InfoPage[DEBUG_FEATURE_FLAGS] |= DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED; - } - - /* Initialise the Host Trace Buffer */ - eError = HTBInit(); - PVR_GOTO_IF_ERROR(eError, Error); - -#if defined(SUPPORT_RGX) - RGXHWPerfClientInitAppHintCallbacks(); -#endif - - /* Late init. client cache maintenance via info. page */ - eError = CacheOpInit2(); - PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpInit2", Error); - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - eError = SyncFbRegisterSyncFunctions(); - PVR_LOG_GOTO_IF_ERROR(eError, "SyncFbRegisterSyncFunctions", Error); -#endif - -#if defined(PDUMP) -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - /* If initialising the device on first connection, we will - * bind PDump capture to the first device we connect to later. - */ - psPVRSRVData->ui32PDumpBoundDevice = PVRSRV_MAX_DEVICES; -#else - /* If not initialising the device on first connection, bind PDump - * capture to device 0. This is because we need to capture PDump - * during device initialisation but only want to capture PDump for - * a single device (by default, device 0). - */ - psPVRSRVData->ui32PDumpBoundDevice = 0; -#endif -#endif - - return 0; - -Error: - PVRSRVCommonDriverDeInit(); - return eError; -} - -void -PVRSRVCommonDriverDeInit(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BOOL bEnablePageFaultDebug = IMG_FALSE; - - if (gpsPVRSRVData == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: missing device-independent data", - __func__)); - return; - } - - if (gpsPVRSRVData->pui32InfoPage != NULL) - { - bEnablePageFaultDebug = GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED; - } - - gpsPVRSRVData->bUnload = IMG_TRUE; - -#if defined(SUPPORT_RGX) - PVRSRVDestroyHWPerfHostThread(); - if (gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock) - { - OSLockDestroy(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock = NULL; - } -#endif - - if (gpsPVRSRVData->hGlobalEventObject) - { - OSEventObjectSignal(gpsPVRSRVData->hGlobalEventObject); - } - -#if defined(SUPPORT_AUTOVZ) - /* Stop and cleanup the devices watchdog thread */ - if (gpsPVRSRVData->hAutoVzWatchdogThread) - { - LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US) - { - if (gpsPVRSRVData->hAutoVzWatchdogEvObj) - { - eError = OSEventObjectSignal(gpsPVRSRVData->hAutoVzWatchdogEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - - eError = OSThreadDestroy(gpsPVRSRVData->hAutoVzWatchdogThread); - if (PVRSRV_OK == eError) - { - gpsPVRSRVData->hAutoVzWatchdogThread = NULL; - break; - } - OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - PVR_LOG_IF_ERROR(eError, "OSThreadDestroy"); - } - - if (gpsPVRSRVData->hAutoVzWatchdogEvObj) - { - eError = OSEventObjectDestroy(gpsPVRSRVData->hAutoVzWatchdogEvObj); - gpsPVRSRVData->hAutoVzWatchdogEvObj = NULL; - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - } -#endif /* SUPPORT_AUTOVZ */ - - /* Stop and cleanup the devices watchdog thread */ - if (gpsPVRSRVData->hDevicesWatchdogThread) - { - LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US) - { - if (gpsPVRSRVData->hDevicesWatchdogEvObj) - { - eError = OSEventObjectSignal(gpsPVRSRVData->hDevicesWatchdogEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - - eError = OSThreadDestroy(gpsPVRSRVData->hDevicesWatchdogThread); - if (PVRSRV_OK == eError) - { - gpsPVRSRVData->hDevicesWatchdogThread = NULL; - break; - } - OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - PVR_LOG_IF_ERROR(eError, "OSThreadDestroy"); - } - - if (gpsPVRSRVData->hDevicesWatchdogEvObj) - { - eError = OSEventObjectDestroy(gpsPVRSRVData->hDevicesWatchdogEvObj); - gpsPVRSRVData->hDevicesWatchdogEvObj = NULL; - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - } - - /* Stop and cleanup the deferred clean up thread, event object and - * deferred context list. - */ - if (gpsPVRSRVData->hCleanupThread) - { - LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US) - { - if (gpsPVRSRVData->hCleanupEventObject) - { - eError = OSEventObjectSignal(gpsPVRSRVData->hCleanupEventObject); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - - eError = OSThreadDestroy(gpsPVRSRVData->hCleanupThread); - if (PVRSRV_OK == eError) - { - gpsPVRSRVData->hCleanupThread = NULL; - break; - } - OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - PVR_LOG_IF_ERROR(eError, "OSThreadDestroy"); - } - - if (gpsPVRSRVData->hCleanupEventObject) - { - eError = OSEventObjectDestroy(gpsPVRSRVData->hCleanupEventObject); - gpsPVRSRVData->hCleanupEventObject = NULL; - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - } - - /* Tear down the HTB before PVRSRVHandleDeInit() removes its TL handle */ - /* HTB De-init happens in device de-registration currently */ - eError = HTBDeInit(); - PVR_LOG_IF_ERROR(eError, "HTBDeInit"); - - /* Tear down CacheOp framework information page first */ - CacheOpDeInit2(); - - /* Clean up information page */ - InfoPageDestroy(gpsPVRSRVData); - - /* Close the TL control plane stream. */ - if (gpsPVRSRVData->hTLCtrlStream != NULL) - { - TLStreamClose(gpsPVRSRVData->hTLCtrlStream); - } - - /* deinitialise pdump */ - if ((g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0) - { - PDUMPDEINIT(); - } - - /* Clean up Transport Layer resources that remain */ - TLDeInit(); - - HostMemDeviceDestroy(gpsPVRSRVData->psHostMemDeviceNode); - gpsPVRSRVData->psHostMemDeviceNode = NULL; - - eError = PVRSRVHandleDeInit(); - PVR_LOG_IF_ERROR(eError, "PVRSRVHandleDeInit"); - - /* destroy event object */ - if (gpsPVRSRVData->hGlobalEventObject) - { - OSEventObjectDestroy(gpsPVRSRVData->hGlobalEventObject); - gpsPVRSRVData->hGlobalEventObject = NULL; - } - - PVRSRVCmdCompleteDeinit(); - -#if defined(SUPPORT_DISPLAY_CLASS) - eError = DCDeInit(); - PVR_LOG_IF_ERROR(eError, "DCDeInit"); -#endif - - eError = PMRDeInit(); - PVR_LOG_IF_ERROR(eError, "PMRDeInit"); - - BridgeDispatcherDeinit(); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - RIDeInitKM(); -#endif - - if (bEnablePageFaultDebug) - { - DevicememHistoryDeInitKM(); - } - - CacheOpDeInit(); - - OSDeInitEnvData(); - - (void) DevmemIntDeInit(); - - ServerBridgeDeInit(); - - PhysHeapDeinit(); - - HTB_DestroyDIEntry(); - -#ifdef PVRSRV_ENABLE_PROCESS_STATS - PVRSRVStatsDestroy(); -#endif /* PVRSRV_ENABLE_PROCESS_STATS */ - - DebugCommonDeInitDriver(); - - DIDeInit(); - - if (gpsPVRSRVData->hThreadsDbgReqNotify) - { - PVRSRVUnregisterDriverDbgRequestNotify(gpsPVRSRVData->hThreadsDbgReqNotify); - } - - PVRSRVUnregisterDriverDbgTable(); - - OSWRLockDestroy(gpsPVRSRVData->hDeviceNodeListLock); - - OSFreeMem(gpsPVRSRVData); - gpsPVRSRVData = NULL; -} - -static void _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - /* Only dump info once */ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*) hDebugRequestHandle; - - PVR_DUMPDEBUG_LOG("------[ System Summary Device ID:%d ]------", psDeviceNode->sDevId.ui32InternalID); - - switch (psDeviceNode->eCurrentSysPowerState) - { - case PVRSRV_SYS_POWER_STATE_OFF: - PVR_DUMPDEBUG_LOG("Device System Power State: OFF"); - break; - case PVRSRV_SYS_POWER_STATE_ON: - PVR_DUMPDEBUG_LOG("Device System Power State: ON"); - break; - default: - PVR_DUMPDEBUG_LOG("Device System Power State: UNKNOWN (%d)", - psDeviceNode->eCurrentSysPowerState); - break; - } - - PVR_DUMPDEBUG_LOG("MaxHWTOut: %dus, WtTryCt: %d, WDGTOut(on,off): (%dms,%dms)", - MAX_HW_TIME_US, WAIT_TRY_COUNT, DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT, DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT); - - SysDebugInfo(psDeviceNode->psDevConfig, pfnDumpDebugPrintf, pvDumpDebugFile); -} - -#define PVRSRV_MIN_DEFAULT_LMA_PHYS_HEAP_SIZE (0x100000ULL * 32ULL) /* 32MB */ - -static PVRSRV_ERROR PVRSRVValidatePhysHeapConfig(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - IMG_UINT32 ui32FlagsAccumulate = 0; - IMG_UINT32 i; - - PVR_LOG_RETURN_IF_FALSE(psDevConfig->ui32PhysHeapCount > 0, - "Device config must specify at least one phys heap config.", - PVRSRV_ERROR_PHYSHEAP_CONFIG); - - for (i = 0; i < psDevConfig->ui32PhysHeapCount; i++) - { - PHYS_HEAP_CONFIG *psHeapConf = &psDevConfig->pasPhysHeaps[i]; - - PVR_LOG_RETURN_IF_FALSE_VA(psHeapConf->ui32UsageFlags != 0, - PVRSRV_ERROR_PHYSHEAP_CONFIG, - "Phys heap config %d: must specify usage flags.", i); - - PVR_LOG_RETURN_IF_FALSE_VA((ui32FlagsAccumulate & psHeapConf->ui32UsageFlags) == 0, - PVRSRV_ERROR_PHYSHEAP_CONFIG, - "Phys heap config %d: duplicate usage flags.", i); - - ui32FlagsAccumulate |= psHeapConf->ui32UsageFlags; - - /* Output message if default heap is LMA and smaller than recommended minimum */ - if ((i == psDevConfig->eDefaultHeap) && -#if defined(__KERNEL__) - ((psHeapConf->eType == PHYS_HEAP_TYPE_LMA) || - (psHeapConf->eType == PHYS_HEAP_TYPE_DMA)) && -#else - (psHeapConf->eType == PHYS_HEAP_TYPE_LMA) && -#endif - (psHeapConf->uiSize < PVRSRV_MIN_DEFAULT_LMA_PHYS_HEAP_SIZE)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Size of default heap is 0x%" IMG_UINT64_FMTSPECX - " (recommended minimum heap size is 0x%llx)", - __func__, psHeapConf->uiSize, - PVRSRV_MIN_DEFAULT_LMA_PHYS_HEAP_SIZE)); - } - } - - if (psDevConfig->eDefaultHeap == PVRSRV_PHYS_HEAP_GPU_LOCAL) - { - PVR_LOG_RETURN_IF_FALSE(((ui32FlagsAccumulate & PHYS_HEAP_USAGE_GPU_LOCAL) != 0) , - "Device config must specify GPU local phys heap config.", - PVRSRV_ERROR_PHYSHEAP_CONFIG); - } - else if (psDevConfig->eDefaultHeap == PVRSRV_PHYS_HEAP_CPU_LOCAL) - { - PVR_LOG_RETURN_IF_FALSE(((ui32FlagsAccumulate & PHYS_HEAP_USAGE_CPU_LOCAL) != 0) , - "Device config must specify CPU local phys heap config.", - PVRSRV_ERROR_PHYSHEAP_CONFIG); - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVPhysMemHeapsInit(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_ERROR eError; - PVRSRV_PHYS_HEAP ePhysHeap; - - eError = PVRSRVValidatePhysHeapConfig(psDevConfig); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVValidatePhysHeapConfig"); - - eError = PhysHeapCreateDeviceHeapsFromConfigs(psDeviceNode, - psDevConfig->pasPhysHeaps, - psDevConfig->ui32PhysHeapCount); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapCreateDeviceHeapsFromConfigs", ErrorDeinit); - - for (ePhysHeap = PVRSRV_PHYS_HEAP_DEFAULT+1; ePhysHeap < PVRSRV_PHYS_HEAP_LAST; ePhysHeap++) - { - if (PhysHeapPVRLayerAcquire(ePhysHeap)) - { - eError = PhysHeapAcquireByDevPhysHeap(ePhysHeap, psDeviceNode, &psDeviceNode->apsPhysHeap[ePhysHeap]); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquireByDevPhysHeap", ErrorDeinit); - } - - /* Calculate the total number of user accessible physical heaps */ - if (psDeviceNode->apsPhysHeap[ePhysHeap] && PhysHeapUserModeAlloc(ePhysHeap)) - { - psDeviceNode->ui32UserAllocHeapCount++; - } - } - - if (PhysHeapValidateDefaultHeapExists(psDeviceNode)) - { - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVPhysHeapCheckUsageFlags", ErrorDeinit); - } - - eError = PhysHeapMMUPxSetup(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapMMUPxSetup", ErrorDeinit); - - return PVRSRV_OK; - -ErrorDeinit: - PVR_ASSERT(IMG_FALSE); - PVRSRVPhysMemHeapsDeinit(psDeviceNode); - - return eError; -} - -void PVRSRVPhysMemHeapsDeinit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_PHYS_HEAP ePhysHeapIdx; - IMG_UINT32 i; - -#if defined(SUPPORT_AUTOVZ) - if (psDeviceNode->psFwMMUReservedPhysHeap) - { - PhysHeapDestroy(psDeviceNode->psFwMMUReservedPhysHeap); - psDeviceNode->psFwMMUReservedPhysHeap = NULL; - } -#endif - - PhysHeapMMUPxDeInit(psDeviceNode); - - /* Release heaps */ - for (ePhysHeapIdx = 0; - ePhysHeapIdx < ARRAY_SIZE(psDeviceNode->apsPhysHeap); - ePhysHeapIdx++) - { - if (psDeviceNode->apsPhysHeap[ePhysHeapIdx]) - { - PhysHeapRelease(psDeviceNode->apsPhysHeap[ePhysHeapIdx]); - } - } - - if (psDeviceNode->psFWMainPhysHeap) - { - PhysHeapDestroy(psDeviceNode->psFWMainPhysHeap); - psDeviceNode->psFWMainPhysHeap = NULL; - } - - if (psDeviceNode->psFWCfgPhysHeap) - { - PhysHeapDestroy(psDeviceNode->psFWCfgPhysHeap); - psDeviceNode->psFWCfgPhysHeap = NULL; - } - - for (i = 0; i < RGX_NUM_OS_SUPPORTED; i++) - { - if (psDeviceNode->apsFWPremapPhysHeap[i]) - { - PhysHeapDestroy(psDeviceNode->apsFWPremapPhysHeap[i]); - psDeviceNode->apsFWPremapPhysHeap[i] = NULL; - } - } - - PhysHeapDestroyDeviceHeaps(psDeviceNode); -} - -PHYS_HEAP_CONFIG* FindPhysHeapConfig(PVRSRV_DEVICE_CONFIG *psDevConfig, - PHYS_HEAP_USAGE_FLAGS ui32Flags) -{ - IMG_UINT32 i; - - for (i = 0; i < psDevConfig->ui32PhysHeapCount; i++) - { - if (psDevConfig->pasPhysHeaps[i].ui32UsageFlags == ui32Flags) - { - return &psDevConfig->pasPhysHeaps[i]; - } - } - - return NULL; -} - -PVRSRV_ERROR PVRSRVCommonDeviceCreate(void *pvOSDevice, - IMG_INT32 i32OsDeviceID, - PVRSRV_DEVICE_NODE **ppsDeviceNode) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_ERROR eError; - PVRSRV_DEVICE_CONFIG *psDevConfig; - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_UINT32 ui32AppHintDefault; - IMG_UINT32 ui32AppHintDriverMode; -#if defined(SUPPORT_PHYSMEM_TEST) && !defined(INTEGRITY_OS) && !defined(__QNXNTO__) - IMG_UINT32 ui32AppHintPhysMemTestPasses; -#endif - void *pvAppHintState = NULL; -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - IMG_HANDLE hProcessStats; -#endif - - MULTI_DEVICE_BRINGUP_DPF("PVRSRVCommonDeviceCreate: DevId %d", i32OsDeviceID); - - /* Read driver mode (i.e. native, host or guest) AppHint early as it is - required by SysDevInit */ - ui32AppHintDefault = PVRSRV_APPHINT_DRIVERMODE; - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, DriverMode, - &ui32AppHintDefault, &ui32AppHintDriverMode); - psPVRSRVData->eDriverMode = PVRSRV_VZ_APPHINT_MODE(ui32AppHintDriverMode); - psPVRSRVData->bForceApphintDriverMode = PVRSRV_VZ_APPHINT_MODE_IS_OVERRIDE(ui32AppHintDriverMode); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - psDeviceNode = OSAllocZMemNoStats(sizeof(*psDeviceNode)); - PVR_LOG_RETURN_IF_NOMEM(psDeviceNode, "psDeviceNode"); - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* Allocate process statistics */ - eError = PVRSRVStatsRegisterProcess(&hProcessStats); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVStatsRegisterProcess", ErrorFreeDeviceNode); -#endif - - psDeviceNode->sDevId.i32OsDeviceID = i32OsDeviceID; - psDeviceNode->sDevId.ui32InternalID = psPVRSRVData->ui32RegisteredDevices; - - eError = SysDevInit(pvOSDevice, &psDevConfig); - PVR_LOG_GOTO_IF_ERROR(eError, "SysDevInit", ErrorDeregisterStats); - - PVR_ASSERT(psDevConfig); - PVR_ASSERT(psDevConfig->pvOSDevice == pvOSDevice); - PVR_ASSERT(!psDevConfig->psDevNode); - - if ((psDevConfig->eDefaultHeap != PVRSRV_PHYS_HEAP_GPU_LOCAL) && - (psDevConfig->eDefaultHeap != PVRSRV_PHYS_HEAP_CPU_LOCAL)) - { - PVR_LOG_MSG(PVR_DBG_ERROR, "DEFAULT Heap is invalid, " - "it must be GPU_LOCAL or CPU_LOCAL"); - PVR_LOG_GOTO_IF_ERROR(eError, "SysDevInit", ErrorDeregisterStats); - } - - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_INIT; - - if (psDevConfig->pfnGpuDomainPower) - { - psDeviceNode->eCurrentSysPowerState = psDevConfig->pfnGpuDomainPower(psDeviceNode); - } - else - { - /* If the System Layer doesn't provide a function to query the power state - * of the system hardware, use a default implementation that keeps track of - * the power state locally and assumes the system starting state */ - psDevConfig->pfnGpuDomainPower = PVRSRVDefaultDomainPower; - -#if defined(SUPPORT_AUTOVZ) - psDeviceNode->eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_ON; -#else - psDeviceNode->eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_OFF; -#endif - } - - psDeviceNode->psDevConfig = psDevConfig; - psDevConfig->psDevNode = psDeviceNode; - -#if defined(SUPPORT_PHYSMEM_TEST) && !defined(INTEGRITY_OS) && !defined(__QNXNTO__) - if (PVRSRV_VZ_MODE_IS(NATIVE)) - { - /* Read AppHint - Configurable memory test pass count */ - ui32AppHintDefault = 0; - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, PhysMemTestPasses, - &ui32AppHintDefault, &ui32AppHintPhysMemTestPasses); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - if (ui32AppHintPhysMemTestPasses > 0) - { - eError = PhysMemTest(psDevConfig, ui32AppHintPhysMemTestPasses); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysMemTest", ErrorSysDevDeInit); - } - } -#endif - - /* Initialise the paravirtualised connection */ - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - /* If a device already exists */ - if (psPVRSRVData->psDeviceNodeList != NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Virtualization is currently supported only on single device systems.", - __func__)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - goto ErrorSysDevDeInit; - } - - PvzConnectionInit(psDevConfig); - PVR_GOTO_IF_ERROR(eError, ErrorSysDevDeInit); - } - - eError = PVRSRVRegisterDeviceDbgTable(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorPvzConnectionDeInit); - - eError = PVRSRVPowerLockInit(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorUnregisterDbgTable); - - eError = PVRSRVPhysMemHeapsInit(psDeviceNode, psDevConfig); - PVR_GOTO_IF_ERROR(eError, ErrorPowerLockDeInit); - -#if defined(SUPPORT_RGX) - /* Requirements: - * registered GPU and FW local heaps */ - /* debug table */ - eError = RGXRegisterDevice(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "RGXRegisterDevice"); - eError = PVRSRV_ERROR_DEVICE_REGISTER_FAILED; - goto ErrorPhysMemHeapsDeinit; - } -#endif - - if (psDeviceNode->pfnPhysMemDeviceHeapsInit != NULL) - { - eError = psDeviceNode->pfnPhysMemDeviceHeapsInit(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorPhysMemHeapsDeinit); - } - - if (psDeviceNode->pfnFwMMUInit != NULL) - { - eError = psDeviceNode->pfnFwMMUInit(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorFwMMUDeinit); - } - - eError = SyncServerInit(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorDeInitRgx); - - eError = SyncCheckpointInit(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "SyncCheckpointInit", ErrorSyncCheckpointInit); - - /* - * This is registered before doing device specific initialisation to ensure - * generic device information is dumped first during a debug request. - */ - eError = PVRSRVRegisterDeviceDbgRequestNotify(&psDeviceNode->hDbgReqNotify, - psDeviceNode, - _SysDebugRequestNotify, - DEBUG_REQUEST_SYS, - psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVRegisterDeviceDbgRequestNotify", ErrorRegDbgReqNotify); - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) - eError = InitDVFS(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "InitDVFS", ErrorDVFSInitFail); -#endif - - OSAtomicWrite(&psDeviceNode->iNumClockSpeedChanges, 0); - -#if defined(PVR_TESTING_UTILS) - TUtilsInit(psDeviceNode); -#endif - - OSWRLockCreate(&psDeviceNode->hMemoryContextPageFaultNotifyListLock); - if (psDeviceNode->hMemoryContextPageFaultNotifyListLock == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock for PF notify list", - __func__)); - goto ErrorPageFaultLockFailCreate; - } - - dllist_init(&psDeviceNode->sMemoryContextPageFaultNotifyListHead); - - PVR_DPF((PVR_DBG_MESSAGE, "Registered device %p", psDeviceNode)); - PVR_DPF((PVR_DBG_MESSAGE, "Register bank address = 0x%08lx", - (unsigned long)psDevConfig->sRegsCpuPBase.uiAddr)); - PVR_DPF((PVR_DBG_MESSAGE, "IRQ = %d", psDevConfig->ui32IRQ)); - -/* SUPPORT_ALT_REGBASE is defined for rogue cores only */ -#if defined(SUPPORT_RGX) && defined(SUPPORT_ALT_REGBASE) - { - IMG_DEV_PHYADDR sRegsGpuPBase; - - PhysHeapCpuPAddrToDevPAddr(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_GPU_LOCAL], - 1, - &sRegsGpuPBase, - &(psDeviceNode->psDevConfig->sRegsCpuPBase)); - - PVR_LOG(("%s: Using alternate Register bank GPU address: 0x%08lx (orig: 0x%08lx)", __func__, - (unsigned long)psDevConfig->sAltRegsGpuPBase.uiAddr, - (unsigned long)sRegsGpuPBase.uiAddr)); - } -#endif - -#if defined(__linux__) - /* register the AppHint device control before device initialisation - * so individual AppHints can be configured during the init phase - */ - { - int iError = pvr_apphint_device_register(psDeviceNode); - PVR_LOG_IF_FALSE(iError == 0, "pvr_apphint_device_register() failed"); - } -#endif /* defined(__linux__) */ - -#if defined(SUPPORT_RGX) - RGXHWPerfInitAppHintCallbacks(psDeviceNode); -#endif - - eError = DebugCommonInitDevice(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "DebugCommonInitDevice", - ErrorDestroyMemoryContextPageFaultNotifyListLock); - - /* Finally insert the device into the dev-list and set it as active */ - OSWRLockAcquireWrite(psPVRSRVData->hDeviceNodeListLock); - List_PVRSRV_DEVICE_NODE_InsertTail(&psPVRSRVData->psDeviceNodeList, - psDeviceNode); - psPVRSRVData->ui32RegisteredDevices++; - OSWRLockReleaseWrite(psPVRSRVData->hDeviceNodeListLock); - - *ppsDeviceNode = psDeviceNode; - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) - /* Register the DVFS device now the device node is present in the dev-list */ - eError = RegisterDVFSDevice(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "RegisterDVFSDevice", ErrorRegisterDVFSDeviceFail); -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* Close the process statistics */ - PVRSRVStatsDeregisterProcess(hProcessStats); -#endif - -#if defined(SUPPORT_VALIDATION) - OSLockCreateNoStats(&psDeviceNode->hValidationLock); -#endif - - return PVRSRV_OK; - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) -ErrorRegisterDVFSDeviceFail: - /* Remove the device from the list */ - OSWRLockAcquireWrite(psPVRSRVData->hDeviceNodeListLock); - List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); - psPVRSRVData->ui32RegisteredDevices--; - OSWRLockReleaseWrite(psPVRSRVData->hDeviceNodeListLock); -#endif - -ErrorDestroyMemoryContextPageFaultNotifyListLock: - OSWRLockDestroy(psDeviceNode->hMemoryContextPageFaultNotifyListLock); - psDeviceNode->hMemoryContextPageFaultNotifyListLock = NULL; - -ErrorPageFaultLockFailCreate: -#if defined(PVR_TESTING_UTILS) - TUtilsDeinit(psDeviceNode); -#endif - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) -ErrorDVFSInitFail: -#endif - - if (psDeviceNode->hDbgReqNotify) - { - PVRSRVUnregisterDeviceDbgRequestNotify(psDeviceNode->hDbgReqNotify); - } - -ErrorRegDbgReqNotify: - SyncCheckpointDeinit(psDeviceNode); - -ErrorSyncCheckpointInit: - SyncServerDeinit(psDeviceNode); - -ErrorDeInitRgx: -#if defined(SUPPORT_RGX) - DevDeInitRGX(psDeviceNode); -#endif -ErrorFwMMUDeinit: -ErrorPhysMemHeapsDeinit: - PVRSRVPhysMemHeapsDeinit(psDeviceNode); -ErrorPowerLockDeInit: - PVRSRVPowerLockDeInit(psDeviceNode); -ErrorUnregisterDbgTable: - PVRSRVUnregisterDeviceDbgTable(psDeviceNode); -ErrorPvzConnectionDeInit: - psDevConfig->psDevNode = NULL; - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - PvzConnectionDeInit(); - } -ErrorSysDevDeInit: - SysDevDeInit(psDevConfig); -ErrorDeregisterStats: -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* Close the process statistics */ - PVRSRVStatsDeregisterProcess(hProcessStats); -ErrorFreeDeviceNode: -#endif - OSFreeMemNoStats(psDeviceNode); - - return eError; -} - -#if defined(SUPPORT_RGX) -static PVRSRV_ERROR _SetDeviceFlag(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivate, IMG_BOOL bValue) -{ - PVRSRV_ERROR eResult = PVRSRV_OK; - IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate); - - PVR_RETURN_IF_INVALID_PARAM(ui32Flag); - PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE, - PVRSRV_ERROR_INVALID_PARAMS); - - eResult = RGXSetDeviceFlags((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice, - ui32Flag, bValue); - - return eResult; -} - -static PVRSRV_ERROR _ReadDeviceFlag(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivate, IMG_BOOL *pbValue) -{ - PVRSRV_ERROR eResult = PVRSRV_OK; - IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate); - IMG_UINT32 ui32State; - - PVR_RETURN_IF_INVALID_PARAM(ui32Flag); - PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE, - PVRSRV_ERROR_INVALID_PARAMS); - - eResult = RGXGetDeviceFlags((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice, - &ui32State); - - if (PVRSRV_OK == eResult) - { - *pbValue = (ui32State & ui32Flag)? IMG_TRUE: IMG_FALSE; - } - - return eResult; -} -static PVRSRV_ERROR _SetStateFlag(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivate, IMG_BOOL bValue) -{ - PVRSRV_ERROR eResult = PVRSRV_OK; - IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate); - - PVR_RETURN_IF_INVALID_PARAM(ui32Flag); - PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE, - PVRSRV_ERROR_INVALID_PARAMS); - - eResult = RGXStateFlagCtrl((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice, - ui32Flag, NULL, bValue); - - return eResult; -} - -static PVRSRV_ERROR _ReadStateFlag(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivate, IMG_BOOL *pbValue) -{ - IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate); - IMG_UINT32 ui32State; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_RETURN_IF_INVALID_PARAM(ui32Flag); - PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE, - PVRSRV_ERROR_INVALID_PARAMS); - - psDevInfo = (PVRSRV_RGXDEV_INFO *)psDevice->pvDevice; - ui32State = psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags; - - if (pbValue) - { - *pbValue = (ui32State & ui32Flag)? IMG_TRUE: IMG_FALSE; - } - - return PVRSRV_OK; -} -#endif - -PVRSRV_ERROR PVRSRVCommonDeviceInitialise(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_BOOL bInitSuccesful = IMG_FALSE; -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - IMG_HANDLE hProcessStats; -#endif - PVRSRV_ERROR eError; - - MULTI_DEVICE_BRINGUP_DPF("PVRSRVCommonDeviceInitialise: DevId %d", psDeviceNode->sDevId.i32OsDeviceID); - - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_INIT) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Device already initialised", __func__)); - return PVRSRV_ERROR_INIT_FAILURE; - } - -#if defined(PDUMP) -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT) - { - PVRSRV_DATA *psSRVData = PVRSRVGetPVRSRVData(); - - /* If first connection, bind this and future PDump clients to use this device */ - if (psSRVData->ui32PDumpBoundDevice == PVRSRV_MAX_DEVICES) - { - psSRVData->ui32PDumpBoundDevice = psDeviceNode->sDevId.ui32InternalID; - } - } -#endif -#endif - - /* Initialise Connection_Data access mechanism */ - dllist_init(&psDeviceNode->sConnections); - eError = OSLockCreate(&psDeviceNode->hConnectionsLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate"); - - /* Allocate process statistics */ -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - eError = PVRSRVStatsRegisterProcess(&hProcessStats); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVStatsRegisterProcess"); -#endif - -#if defined(SUPPORT_RGX) - eError = RGXInit(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXInit", Exit); -#endif - -#if defined(SUPPORT_DMA_TRANSFER) - PVRSRVInitialiseDMA(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVInitialiseDMA", Exit); -#endif - - bInitSuccesful = IMG_TRUE; - -#if defined(SUPPORT_RGX) -Exit: -#endif - eError = PVRSRVDeviceFinalise(psDeviceNode, bInitSuccesful); - PVR_LOG_IF_ERROR(eError, "PVRSRVDeviceFinalise"); - -#if defined(SUPPORT_RGX) - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableClockGating, - _ReadStateFlag, _SetStateFlag, - APPHINT_OF_DRIVER_NO_DEVICE, - (void*)((uintptr_t)RGXFWIF_INICFG_DISABLE_CLKGATING_EN)); - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableDMOverlap, - _ReadStateFlag, _SetStateFlag, - APPHINT_OF_DRIVER_NO_DEVICE, - (void*)((uintptr_t)RGXFWIF_INICFG_DISABLE_DM_OVERLAP)); - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_AssertOnHWRTrigger, - _ReadStateFlag, _SetStateFlag, - psDeviceNode, - (void*)((uintptr_t)RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER)); - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_AssertOutOfMemory, - _ReadStateFlag, _SetStateFlag, - psDeviceNode, - (void*)((uintptr_t)RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY)); - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_CheckMList, - _ReadStateFlag, _SetStateFlag, - psDeviceNode, - (void*)((uintptr_t)RGXFWIF_INICFG_CHECK_MLIST_EN)); - } - - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableFEDLogging, - _ReadDeviceFlag, _SetDeviceFlag, - psDeviceNode, - (void*)((uintptr_t)RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN)); - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_ZeroFreelist, - _ReadDeviceFlag, _SetDeviceFlag, - psDeviceNode, - (void*)((uintptr_t)RGXKM_DEVICE_STATE_ZERO_FREELIST)); -#if defined(SUPPORT_VALIDATION) - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_GPUUnitsPowerChange, - _ReadDeviceFlag, _SetDeviceFlag, - psDeviceNode, - (void*)((uintptr_t)RGXKM_DEVICE_STATE_GPU_UNITS_POWER_CHANGE_EN)); -#endif - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisablePDumpPanic, - RGXQueryPdumpPanicDisable, RGXSetPdumpPanicDisable, - psDeviceNode, - NULL); -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) - /* Close the process statistics */ - PVRSRVStatsDeregisterProcess(hProcessStats); -#endif - - return eError; -} - -PVRSRV_ERROR PVRSRVCommonDeviceDestroy(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_ERROR eError; -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - IMG_BOOL bForceUnload = IMG_FALSE; - - if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - bForceUnload = IMG_TRUE; - } -#endif - - MULTI_DEVICE_BRINGUP_DPF("PVRSRVCommonDeviceDestroy: DevId %d", psDeviceNode->sDevId.i32OsDeviceID); - - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_DEINIT; - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) - UnregisterDVFSDevice(psDeviceNode); -#endif - - OSWRLockAcquireWrite(psPVRSRVData->hDeviceNodeListLock); - List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); - psPVRSRVData->ui32RegisteredDevices--; - OSWRLockReleaseWrite(psPVRSRVData->hDeviceNodeListLock); - -#if defined(__linux__) - pvr_apphint_device_unregister(psDeviceNode); -#endif /* defined(__linux__) */ - - DebugCommonDeInitDevice(psDeviceNode); - - if (psDeviceNode->hMemoryContextPageFaultNotifyListLock != NULL) - { - OSWRLockDestroy(psDeviceNode->hMemoryContextPageFaultNotifyListLock); - } - -#if defined(SUPPORT_VALIDATION) - OSLockDestroyNoStats(psDeviceNode->hValidationLock); - psDeviceNode->hValidationLock = NULL; -#endif - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - SyncFbDeregisterDevice(psDeviceNode); -#endif - /* Counter part to what gets done in PVRSRVDeviceFinalise */ - if (psDeviceNode->hSyncCheckpointContext) - { - SyncCheckpointContextDestroy(psDeviceNode->hSyncCheckpointContext); - psDeviceNode->hSyncCheckpointContext = NULL; - } - if (psDeviceNode->hSyncPrimContext) - { - if (psDeviceNode->psMMUCacheSyncPrim) - { - PVRSRV_CLIENT_SYNC_PRIM *psSync = psDeviceNode->psMMUCacheSyncPrim; - - /* Ensure there are no pending MMU Cache Ops in progress before freeing this sync. */ - eError = PVRSRVPollForValueKM(psDeviceNode, - psSync->pui32LinAddr, - psDeviceNode->ui32NextMMUInvalidateUpdate-1, - 0xFFFFFFFF, - POLL_FLAG_LOG_ERROR); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVPollForValueKM"); - - /* Important to set the device node pointer to NULL - * before we free the sync-prim to make sure we don't - * defer the freeing of the sync-prim's page tables itself. - * The sync is used to defer the MMU page table - * freeing. */ - psDeviceNode->psMMUCacheSyncPrim = NULL; - - /* Free general purpose sync primitive */ - SyncPrimFree(psSync); - } - - SyncPrimContextDestroy(psDeviceNode->hSyncPrimContext); - psDeviceNode->hSyncPrimContext = NULL; - } - - eError = PVRSRVPowerLock(psDeviceNode); - if (eError == PVRSRV_OK) - { -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - /* - * Firmware probably not responding if bForceUnload is set, but we still want to unload the - * driver. - */ - if (!bForceUnload) -#endif - { - /* Force idle device */ - eError = PVRSRVDeviceIdleRequestKM(psDeviceNode, NULL, IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "PVRSRVDeviceIdleRequestKM"); - if (eError != PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED) - { - PVRSRVPowerUnlock(psDeviceNode); - } - return eError; - } - } - - /* Power down the device if necessary */ - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_OFF, - PVRSRV_POWER_FLAGS_FORCED); - PVRSRVPowerUnlock(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "PVRSRVSetDevicePowerStateKM"); - - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - - /* - * If the driver is okay then return the error, otherwise we can ignore - * this error. - */ - if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK) - { - return eError; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Will continue to unregister as driver status is not OK", - __func__)); - } - } - } - -#if defined(PVR_TESTING_UTILS) - TUtilsDeinit(psDeviceNode); -#endif - -#if defined(SUPPORT_LINUX_DVFS) && !defined(NO_HARDWARE) - DeinitDVFS(psDeviceNode); -#endif - - if (psDeviceNode->hDbgReqNotify) - { - PVRSRVUnregisterDeviceDbgRequestNotify(psDeviceNode->hDbgReqNotify); - } - - SyncCheckpointDeinit(psDeviceNode); - - SyncServerDeinit(psDeviceNode); - -#if defined(SUPPORT_RGX) - DevDeInitRGX(psDeviceNode); -#endif - - PVRSRVPhysMemHeapsDeinit(psDeviceNode); - PVRSRVPowerLockDeInit(psDeviceNode); - - PVRSRVUnregisterDeviceDbgTable(psDeviceNode); - - /* Release the Connection-Data lock as late as possible. */ - if (psDeviceNode->hConnectionsLock) - { - OSLockDestroy(psDeviceNode->hConnectionsLock); - } - - psDeviceNode->psDevConfig->psDevNode = NULL; - - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - PvzConnectionDeInit(); - } - SysDevDeInit(psDeviceNode->psDevConfig); - - OSFreeMemNoStats(psDeviceNode); - - return PVRSRV_OK; -} - -/**************************************************************************/ /*! -@Function PVRSRVDeviceFinalise -@Description Performs the final parts of device initialisation. -@Input psDeviceNode Device node of the device to finish - initialising -@Input bInitSuccessful Whether or not device specific - initialisation was successful -@Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR PVRSRVDeviceFinalise(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bInitSuccessful) -{ - PVRSRV_ERROR eError; - __maybe_unused PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)(psDeviceNode->pvDevice); - - if (bInitSuccessful) - { - eError = SyncCheckpointContextCreate(psDeviceNode, - &psDeviceNode->hSyncCheckpointContext); - PVR_LOG_GOTO_IF_ERROR(eError, "SyncCheckpointContextCreate", ErrorExit); -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - eError = SyncFbRegisterDevice(psDeviceNode); - PVR_GOTO_IF_ERROR(eError, ErrorExit); -#endif - eError = SyncPrimContextCreate(psDeviceNode, - &psDeviceNode->hSyncPrimContext); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "SyncPrimContextCreate"); - SyncCheckpointContextDestroy(psDeviceNode->hSyncCheckpointContext); - goto ErrorExit; - } - - /* Allocate MMU cache invalidate sync */ - eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, - &psDeviceNode->psMMUCacheSyncPrim, - "pvrsrv dev MMU cache"); - PVR_LOG_GOTO_IF_ERROR(eError, "SyncPrimAlloc", ErrorExit); - - /* Set the sync prim value to a much higher value near the - * wrapping range. This is so any wrapping bugs would be - * seen early in the driver start-up. - */ - SyncPrimSet(psDeviceNode->psMMUCacheSyncPrim, 0xFFFFFFF6UL); - - /* Next update value will be 0xFFFFFFF7 since sync prim starts with 0xFFFFFFF6 */ - psDeviceNode->ui32NextMMUInvalidateUpdate = 0xFFFFFFF7UL; - - eError = PVRSRVPowerLock(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVPowerLock", ErrorExit); - - /* - * Always ensure a single power on command appears in the pdump. This - * should be the only power related call outside of PDUMPPOWCMDSTART - * and PDUMPPOWCMDEND. - */ - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_FORCED); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to set device %p power state to 'on' (%s)", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - PVRSRVPowerUnlock(psDeviceNode); - goto ErrorExit; - } - -#if defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) - eError = ValidateFWOnLoad(psDeviceNode->pvDevice); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "ValidateFWOnLoad"); - PVRSRVPowerUnlock(psDeviceNode); - return eError; - } -#endif - - eError = PVRSRVDevInitCompatCheck(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed compatibility check for device %p (%s)", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - PVRSRVPowerUnlock(psDeviceNode); - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - goto ErrorExit; - } - - PDUMPPOWCMDSTART(psDeviceNode); - - /* Force the device to idle if its default power state is off */ - eError = PVRSRVDeviceIdleRequestKM(psDeviceNode, - &PVRSRVDeviceIsDefaultStateOFF, - IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "PVRSRVDeviceIdleRequestKM"); - if (eError != PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED) - { - PVRSRVPowerUnlock(psDeviceNode); - } - goto ErrorExit; - } - - /* Place device into its default power state. */ - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_DEFAULT, - PVRSRV_POWER_FLAGS_FORCED); - PDUMPPOWCMDEND(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to set device %p into its default power state (%s)", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - - PVRSRVPowerUnlock(psDeviceNode); - goto ErrorExit; - } - - PVRSRVPowerUnlock(psDeviceNode); - - /* - * If PDUMP is enabled and RGX device is supported, then initialise the - * performance counters that can be further modified in PDUMP. Then, - * before ending the init phase of the pdump, drain the commands put in - * the kCCB during the init phase. - */ -#if defined(SUPPORT_RGX) -#if defined(PDUMP) - { - eError = RGXInitHWPerfCounters(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXInitHWPerfCounters", ErrorExit); - - eError = RGXPdumpDrainKCCB(psDevInfo, - psDevInfo->psKernelCCBCtl->ui32WriteOffset); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXPdumpDrainKCCB", ErrorExit); - } -#endif -#endif /* defined(SUPPORT_RGX) */ - /* Now that the device(s) are fully initialised set them as active */ - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_ACTIVE; - eError = PVRSRV_OK; - } - else - { - /* Initialisation failed so set the device(s) into a bad state */ - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_BAD; - eError = PVRSRV_ERROR_NOT_INITIALISED; - } - - /* Give PDump control a chance to end the init phase, depends on OS */ - PDUMPENDINITPHASE(psDeviceNode); - return eError; - -ErrorExit: - /* Initialisation failed so set the device(s) into a bad state */ - psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_BAD; - - return eError; -} - -PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* Only check devices which specify a compatibility check callback */ - if (psDeviceNode->pfnInitDeviceCompatCheck) - return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode); - else - return PVRSRV_OK; -} - -/* - PollForValueKM -*/ -static -PVRSRV_ERROR PollForValueKM (volatile IMG_UINT32 __iomem * pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Timeoutus, - IMG_UINT32 ui32PollPeriodus, - POLL_FLAGS ePollFlags) -{ -#if defined(NO_HARDWARE) - PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(ui32Timeoutus); - PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus); - PVR_UNREFERENCED_PARAMETER(ePollFlags); - return PVRSRV_OK; -#else - IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */ - - LOOP_UNTIL_TIMEOUT(ui32Timeoutus) - { - ui32ActualValue = OSReadHWReg32((void __iomem *)pui32LinMemAddr, 0) & ui32Mask; - - if (ui32ActualValue == ui32Value) - { - return PVRSRV_OK; - } - - if (gpsPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - OSWaitus(ui32PollPeriodus); - } END_LOOP_UNTIL_TIMEOUT(); - - if (BITMASK_HAS(ePollFlags, POLL_FLAG_LOG_ERROR)) - { - PVR_DPF((PVR_DBG_ERROR, - "PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).", - ui32Value, ui32ActualValue, ui32Mask)); - } - - return PVRSRV_ERROR_TIMEOUT; -#endif /* NO_HARDWARE */ -} - - -/* - PVRSRVPollForValueKM -*/ -PVRSRV_ERROR PVRSRVPollForValueKM (PVRSRV_DEVICE_NODE *psDevNode, - volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - POLL_FLAGS ePollFlags) -{ - PVRSRV_ERROR eError; - - eError = PollForValueKM(pui32LinMemAddr, ui32Value, ui32Mask, - MAX_HW_TIME_US, - MAX_HW_TIME_US/WAIT_TRY_COUNT, - ePollFlags); - if (eError != PVRSRV_OK && BITMASK_HAS(ePollFlags, POLL_FLAG_DEBUG_DUMP)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed! Error(%s) CPU linear address(%p) Expected value(%u)", - __func__, PVRSRVGetErrorString(eError), - pui32LinMemAddr, ui32Value)); - PVRSRVDebugRequest(psDevNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - } - - return eError; -} - -PVRSRV_ERROR -PVRSRVWaitForValueKM(volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask) -{ -#if defined(NO_HARDWARE) - PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - return PVRSRV_OK; -#else - - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - IMG_HANDLE hOSEvent; - PVRSRV_ERROR eError; - PVRSRV_ERROR eErrorWait; - IMG_UINT32 ui32ActualValue; - - eError = OSEventObjectOpen(psPVRSRVData->hGlobalEventObject, &hOSEvent); - PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectOpen", EventObjectOpenError); - - eError = PVRSRV_ERROR_TIMEOUT; /* Initialiser for following loop */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - ui32ActualValue = (OSReadDeviceMem32(pui32LinMemAddr) & ui32Mask); - - if (ui32ActualValue == ui32Value) - { - /* Expected value has been found */ - eError = PVRSRV_OK; - break; - } - else if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - /* Services in bad state, don't wait any more */ - eError = PVRSRV_ERROR_NOT_READY; - break; - } - else - { - /* wait for event and retry */ - eErrorWait = OSEventObjectWait(hOSEvent); - if (eErrorWait != PVRSRV_OK && eErrorWait != PVRSRV_ERROR_TIMEOUT) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Failed with error %d. Found value 0x%x but was expected " - "to be 0x%x (Mask 0x%08x). Retrying", - __func__, - eErrorWait, - ui32ActualValue, - ui32Value, - ui32Mask)); - } - } - } END_LOOP_UNTIL_TIMEOUT(); - - OSEventObjectClose(hOSEvent); - - /* One last check in case the object wait ended after the loop timeout... */ - if (eError != PVRSRV_OK && - (OSReadDeviceMem32(pui32LinMemAddr) & ui32Mask) == ui32Value) - { - eError = PVRSRV_OK; - } - - /* Provide event timeout information to aid the Device Watchdog Thread... */ - if (eError == PVRSRV_OK) - { - psPVRSRVData->ui32GEOConsecutiveTimeouts = 0; - } - else if (eError == PVRSRV_ERROR_TIMEOUT) - { - psPVRSRVData->ui32GEOConsecutiveTimeouts++; - } - -EventObjectOpenError: - - return eError; - -#endif /* NO_HARDWARE */ -} - -int PVRSRVGetDriverStatus(void) -{ - return PVRSRVGetPVRSRVData()->eServicesState; -} - -/* - PVRSRVSystemHasCacheSnooping -*/ -IMG_BOOL PVRSRVSystemHasCacheSnooping(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - if ((psDevConfig->eCacheSnoopingMode != PVRSRV_DEVICE_SNOOP_NONE) && - (psDevConfig->eCacheSnoopingMode != PVRSRV_DEVICE_SNOOP_EMULATED)) - { - return IMG_TRUE; - } - return IMG_FALSE; -} - -IMG_BOOL PVRSRVSystemSnoopingIsEmulated(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - if (psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_EMULATED) - { - return IMG_TRUE; - } - return IMG_FALSE; -} - -IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - if ((psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_CPU_ONLY) || - (psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_CROSS)) - { - return IMG_TRUE; - } - return IMG_FALSE; -} - -IMG_BOOL PVRSRVSystemSnoopingOfDeviceCache(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - if ((psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_DEVICE_ONLY) || - (psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_CROSS)) - { - return IMG_TRUE; - } - return IMG_FALSE; -} - -IMG_BOOL PVRSRVSystemHasNonMappableLocalMemory(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - return psDevConfig->bHasNonMappableLocalMemory; -} - -/* - PVRSRVSystemWaitCycles -*/ -void PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT32 ui32Cycles) -{ - /* Delay in us */ - IMG_UINT32 ui32Delayus = 1; - - /* obtain the device freq */ - if (psDevConfig->pfnClockFreqGet != NULL) - { - IMG_UINT32 ui32DeviceFreq; - - ui32DeviceFreq = psDevConfig->pfnClockFreqGet(psDevConfig->hSysData); - - ui32Delayus = (ui32Cycles*1000000)/ui32DeviceFreq; - - if (ui32Delayus == 0) - { - ui32Delayus = 1; - } - } - - OSWaitus(ui32Delayus); -} - -static void * -PVRSRVSystemInstallDeviceLISR_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, - va_list va) -{ - void *pvOSDevice = va_arg(va, void *); - - if (psDeviceNode->psDevConfig->pvOSDevice == pvOSDevice) - { - return psDeviceNode; - } - - return NULL; -} - -PVRSRV_ERROR PVRSRVSystemInstallDeviceLISR(void *pvOSDevice, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszName, - PFN_LISR pfnLISR, - void *pvData, - IMG_HANDLE *phLISRData) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = - List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList, - &PVRSRVSystemInstallDeviceLISR_Match_AnyVaCb, - pvOSDevice); - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - if (!psDeviceNode) - { - /* Device can't be found in the list so it isn't in the system */ - PVR_DPF((PVR_DBG_ERROR, "%s: device %p with irq %d is not present", - __func__, pvOSDevice, ui32IRQ)); - return PVRSRV_ERROR_INVALID_DEVICE; - } - - return SysInstallDeviceLISR(psDeviceNode->psDevConfig->hSysData, ui32IRQ, - pszName, pfnLISR, pvData, phLISRData); -} - -PVRSRV_ERROR PVRSRVSystemUninstallDeviceLISR(IMG_HANDLE hLISRData) -{ - return SysUninstallDeviceLISR(hLISRData); -} - -#if defined(SUPPORT_GPUVIRT_VALIDATION) && defined(EMULATOR) -/* functions only used on rogue, but header defining them is common */ -void SetAxiProtOSid(IMG_UINT32 ui32OSid, IMG_BOOL bState) -{ - SysSetAxiProtOSid(ui32OSid, bState); -} - -void SetTrustedDeviceAceEnabled(void) -{ - SysSetTrustedDeviceAceEnabled(); -} -#endif - -#if defined(SUPPORT_RGX) -PVRSRV_ERROR PVRSRVCreateHWPerfHostThread(IMG_UINT32 ui32Timeout) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (!ui32Timeout) - return PVRSRV_ERROR_INVALID_PARAMS; - - OSLockAcquire(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - - /* Create only once */ - if (gpsPVRSRVData->hHWPerfHostPeriodicThread == NULL) - { - /* Create the HWPerf event object */ - eError = OSEventObjectCreate("PVRSRV_HWPERFHOSTPERIODIC_EVENTOBJECT", &gpsPVRSRVData->hHWPerfHostPeriodicEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectCreate"); - - if (eError == PVRSRV_OK) - { - gpsPVRSRVData->bHWPerfHostThreadStop = IMG_FALSE; - gpsPVRSRVData->ui32HWPerfHostThreadTimeout = ui32Timeout; - /* Create a thread which is used to periodically emit host stream packets */ - eError = OSThreadCreate(&gpsPVRSRVData->hHWPerfHostPeriodicThread, - "pvr_hwperf_host", - HWPerfPeriodicHostEventsThread, - NULL, IMG_TRUE, gpsPVRSRVData); - PVR_LOG_IF_ERROR(eError, "OSThreadCreate"); - } - } - /* If the thread has already been created then just update the timeout and wake up thread */ - else - { - gpsPVRSRVData->ui32HWPerfHostThreadTimeout = ui32Timeout; - eError = OSEventObjectSignal(gpsPVRSRVData->hHWPerfHostPeriodicEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - - OSLockRelease(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - return eError; -} - -PVRSRV_ERROR PVRSRVDestroyHWPerfHostThread(void) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - OSLockAcquire(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - - /* Stop and cleanup the HWPerf periodic thread */ - if (gpsPVRSRVData->hHWPerfHostPeriodicThread) - { - if (gpsPVRSRVData->hHWPerfHostPeriodicEvObj) - { - gpsPVRSRVData->bHWPerfHostThreadStop = IMG_TRUE; - eError = OSEventObjectSignal(gpsPVRSRVData->hHWPerfHostPeriodicEvObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal"); - } - LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US) - { - eError = OSThreadDestroy(gpsPVRSRVData->hHWPerfHostPeriodicThread); - if (PVRSRV_OK == eError) - { - gpsPVRSRVData->hHWPerfHostPeriodicThread = NULL; - break; - } - OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - PVR_LOG_IF_ERROR(eError, "OSThreadDestroy"); - - if (gpsPVRSRVData->hHWPerfHostPeriodicEvObj) - { - eError = OSEventObjectDestroy(gpsPVRSRVData->hHWPerfHostPeriodicEvObj); - gpsPVRSRVData->hHWPerfHostPeriodicEvObj = NULL; - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - } - } - - OSLockRelease(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock); - return eError; -} -#endif - -/* - * Scan the list of known devices until we find the specific instance or - * exhaust the list - */ -PVRSRV_DEVICE_NODE *PVRSRVGetDeviceInstance(IMG_UINT32 uiInstance) -{ - PVRSRV_DEVICE_NODE *psDevNode; - - if (uiInstance >= gpsPVRSRVData->ui32RegisteredDevices) - { - return NULL; - } - OSWRLockAcquireRead(gpsPVRSRVData->hDeviceNodeListLock); - for (psDevNode = gpsPVRSRVData->psDeviceNodeList; - psDevNode != NULL; psDevNode = psDevNode->psNext) - { - if (uiInstance == psDevNode->sDevId.ui32InternalID) - { - break; - } - } - OSWRLockReleaseRead(gpsPVRSRVData->hDeviceNodeListLock); - - return psDevNode; -} - -PVRSRV_DEVICE_NODE *PVRSRVGetDeviceInstanceByOSId(IMG_INT32 i32OSInstance) -{ - PVRSRV_DEVICE_NODE *psDevNode; - - OSWRLockAcquireRead(gpsPVRSRVData->hDeviceNodeListLock); - for (psDevNode = gpsPVRSRVData->psDeviceNodeList; - psDevNode != NULL; psDevNode = psDevNode->psNext) - { - if (i32OSInstance == psDevNode->sDevId.i32OsDeviceID) - { - break; - } - } - OSWRLockReleaseRead(gpsPVRSRVData->hDeviceNodeListLock); - - return psDevNode; -} - -/* Default function for querying the power state of the system */ -PVRSRV_SYS_POWER_STATE PVRSRVDefaultDomainPower(PVRSRV_DEVICE_NODE *psDevNode) -{ - return psDevNode->eCurrentSysPowerState; -} -/***************************************************************************** - End of file (pvrsrv.c) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv.h deleted file mode 100644 index 5292bcff04512..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv.h +++ /dev/null @@ -1,542 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PowerVR services server header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_H -#define PVRSRV_H - -#include "connection_server.h" -#include "pvrsrv_pool.h" -#include "device.h" -#include "power.h" -#include "syscommon.h" -#include "sysinfo.h" -#include "physheap.h" -#include "cache_ops.h" -#include "pvr_notifier.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -#include "dma_support.h" -#include "vz_vmm_pvz.h" - -/*! - * For OSThreadDestroy(), which may require a retry - * Try for 100 ms to destroy an OS thread before failing - */ -#define OS_THREAD_DESTROY_TIMEOUT_US 100000ULL -#define OS_THREAD_DESTROY_RETRY_COUNT 10 - -typedef enum _POLL_FLAGS_ -{ - POLL_FLAG_NONE = 0, /* No message or dump is printed on poll timeout */ - POLL_FLAG_LOG_ERROR = 1, /* Log error on poll timeout */ - POLL_FLAG_DEBUG_DUMP = 2 /* Print debug dump on poll timeout */ -} POLL_FLAGS; - -typedef struct _BUILD_INFO_ -{ - IMG_UINT32 ui32BuildOptions; - IMG_UINT32 ui32BuildVersion; - IMG_UINT32 ui32BuildRevision; - IMG_UINT32 ui32BuildType; -#define BUILD_TYPE_DEBUG 0 -#define BUILD_TYPE_RELEASE 1 - /* The above fields are self explanatory */ - /* B.V.N.C can be added later if required */ -} BUILD_INFO; - -typedef struct _DRIVER_INFO_ -{ - BUILD_INFO sUMBuildInfo; - BUILD_INFO sKMBuildInfo; - IMG_UINT8 ui8UMSupportedArch; - IMG_UINT8 ui8KMBitArch; - -#define BUILD_ARCH_64BIT (1 << 0) -#define BUILD_ARCH_32BIT (1 << 1) -#define BUILD_ARCH_BOTH (BUILD_ARCH_32BIT | BUILD_ARCH_64BIT) - IMG_BOOL bIsNoMatch; -}DRIVER_INFO; - -#if defined(SUPPORT_VALIDATION) && defined(__linux__) -typedef struct MEM_LEAK_INTERVALS_TAG -{ - IMG_UINT32 ui32OSAlloc; - IMG_UINT32 ui32GPU; - IMG_UINT32 ui32MMU; -} MEM_LEAK_INTERVALS; -#endif - -typedef struct PVRSRV_DATA_TAG -{ - PVRSRV_DRIVER_MODE eDriverMode; /*!< Driver mode (i.e. native, host or guest) */ - IMG_BOOL bForceApphintDriverMode; /*!< Indicate if driver mode is forced via apphint */ - DRIVER_INFO sDriverInfo; - IMG_UINT32 ui32DPFErrorCount; /*!< Number of Fatal/Error DPFs */ - - POSWR_LOCK hDeviceNodeListLock; /*!< Read-Write lock to protect the list of devices */ - PVRSRV_DEVICE_NODE *psDeviceNodeList; /*!< List head of device nodes */ - IMG_UINT32 ui32RegisteredDevices; - PVRSRV_DEVICE_NODE *psHostMemDeviceNode; /*!< DeviceNode to be used for device independent - host based memory allocations where the DevMem - framework is to be used e.g. TL */ - PVRSRV_SERVICES_STATE eServicesState; /*!< global driver state */ - - IMG_HANDLE hGlobalEventObject; /*!< OS Global Event Object */ - IMG_UINT32 ui32GEOConsecutiveTimeouts; /*!< OS Global Event Object Timeouts */ - - IMG_HANDLE hCleanupThread; /*!< Cleanup thread */ - IMG_HANDLE hCleanupEventObject; /*!< Event object to drive cleanup thread */ - POS_SPINLOCK hCleanupThreadWorkListLock; /*!< Lock protecting the cleanup thread work list */ - DLLIST_NODE sCleanupThreadWorkList; /*!< List of work for the cleanup thread */ - IMG_PID cleanupThreadPid; /*!< Cleanup thread process id */ - uintptr_t cleanupThreadTid; /*!< Cleanup thread id */ - ATOMIC_T i32NumCleanupItemsQueued; /*!< Number of items in cleanup thread work list */ - ATOMIC_T i32NumCleanupItemsNotCompleted; /*!< Number of items dropped from cleanup thread work list - after retry limit reached */ - - IMG_HANDLE hDevicesWatchdogThread; /*!< Devices watchdog thread */ - IMG_HANDLE hDevicesWatchdogEvObj; /*! Event object to drive devices watchdog thread */ - volatile IMG_UINT32 ui32DevicesWatchdogPwrTrans; /*! Number of off -> on power state transitions */ -#if !defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) - volatile IMG_UINT32 ui32DevicesWatchdogTimeout; /*! Timeout for the Devices watchdog Thread */ -#endif -#ifdef PVR_TESTING_UTILS - volatile IMG_UINT32 ui32DevicesWdWakeupCounter; /* Need this for the unit tests. */ -#endif - -#if defined(SUPPORT_AUTOVZ) - IMG_HANDLE hAutoVzWatchdogThread; /*!< Devices watchdog thread */ - IMG_HANDLE hAutoVzWatchdogEvObj; /*! Event object to drive devices watchdog thread */ -#endif - - POS_LOCK hHWPerfHostPeriodicThread_Lock; /*!< Lock for the HWPerf Host periodic thread */ - IMG_HANDLE hHWPerfHostPeriodicThread; /*!< HWPerf Host periodic thread */ - IMG_HANDLE hHWPerfHostPeriodicEvObj; /*! Event object to drive HWPerf thread */ - volatile IMG_BOOL bHWPerfHostThreadStop; - IMG_UINT32 ui32HWPerfHostThreadTimeout; - - IMG_HANDLE hPvzConnection; /*!< PVZ connection used for cross-VM hyper-calls */ - POS_LOCK hPvzConnectionLock; /*!< Lock protecting PVZ connection */ - IMG_BOOL abVmOnline[RGX_NUM_OS_SUPPORTED]; - - IMG_BOOL bUnload; /*!< Driver unload is in progress */ - - IMG_HANDLE hTLCtrlStream; /*! Control plane for TL streams */ - - IMG_HANDLE hDriverThreadEventObject; /*! Event object relating to multi-threading in the Server */ - IMG_BOOL bDriverSuspended; /*! if TRUE, the driver is suspended and new threads should not enter */ - ATOMIC_T iNumActiveDriverThreads; /*! Number of threads active in the Server */ - - PMR *psInfoPagePMR; /*! Handle to exportable PMR of the information page. */ - IMG_UINT32 *pui32InfoPage; /*! CPU memory mapping for information page. */ - DEVMEM_MEMDESC *psInfoPageMemDesc; /*! Memory descriptor of the information page. */ - POS_LOCK hInfoPageLock; /*! Lock guarding access to information page. */ - -#if defined(SUPPORT_VALIDATION) && defined(__linux__) - MEM_LEAK_INTERVALS sMemLeakIntervals; /*!< How often certain memory leak types will trigger */ -#endif - IMG_HANDLE hThreadsDbgReqNotify; - - IMG_UINT32 ui32PDumpBoundDevice; /*!< PDump is bound to the device first connected to */ -} PVRSRV_DATA; - - -/*! -****************************************************************************** - @Function PVRSRVGetPVRSRVData - - @Description Get a pointer to the global data - - @Return PVRSRV_DATA * -******************************************************************************/ -PVRSRV_DATA *PVRSRVGetPVRSRVData(void); - -#define PVRSRV_KM_ERRORS (PVRSRVGetPVRSRVData()->ui32DPFErrorCount) -#define PVRSRV_ERROR_LIMIT_REACHED (PVRSRV_KM_ERRORS == IMG_UINT32_MAX) -#define PVRSRV_REPORT_ERROR() do { if (!(PVRSRV_ERROR_LIMIT_REACHED)) { PVRSRVGetPVRSRVData()->ui32DPFErrorCount++; } } while (0) - -#define PVRSRV_VZ_MODE_IS(_expr) (DRIVER_MODE_##_expr == PVRSRVGetPVRSRVData()->eDriverMode) -#define PVRSRV_VZ_RETN_IF_MODE(_expr) do { if ( PVRSRV_VZ_MODE_IS(_expr)) { return; } } while (0) -#define PVRSRV_VZ_RETN_IF_NOT_MODE(_expr) do { if (! PVRSRV_VZ_MODE_IS(_expr)) { return; } } while (0) -#define PVRSRV_VZ_RET_IF_MODE(_expr, _rc) do { if ( PVRSRV_VZ_MODE_IS(_expr)) { return (_rc); } } while (0) -#define PVRSRV_VZ_RET_IF_NOT_MODE(_expr, _rc) do { if (! PVRSRV_VZ_MODE_IS(_expr)) { return (_rc); } } while (0) - -/*! -****************************************************************************** -@Note The driver execution mode AppHint (i.e. PVRSRV_APPHINT_DRIVERMODE) - can be an override or non-override 32-bit value. An override value - has the MSB bit set & a non-override value has this MSB bit cleared. - Excluding this MSB bit & interpreting the remaining 31-bit as a - signed 31-bit integer, the mode values are: - [-1 native : 0 host : +1 guest ]. -******************************************************************************/ -#define PVRSRV_VZ_APPHINT_MODE_IS_OVERRIDE(_expr) ((IMG_UINT32)(_expr)&(IMG_UINT32)(1<<31)) -#define PVRSRV_VZ_APPHINT_MODE(_expr) \ - ((((IMG_UINT32)(_expr)&(IMG_UINT32)0x7FFFFFFF) == (IMG_UINT32)0x7FFFFFFF) ? DRIVER_MODE_NATIVE : \ - !((IMG_UINT32)(_expr)&(IMG_UINT32)0x7FFFFFFF) ? DRIVER_MODE_HOST : \ - ((IMG_UINT32)((IMG_UINT32)(_expr)&(IMG_UINT)0x7FFFFFFF)==(IMG_UINT32)0x1) ? DRIVER_MODE_GUEST : \ - ((IMG_UINT32)(_expr)&(IMG_UINT32)0x7FFFFFFF)) - -typedef struct _PHYS_HEAP_ITERATOR_ PHYS_HEAP_ITERATOR; - -/*! -****************************************************************************** - @Function LMA_HeapIteratorCreate - - @Description - Creates iterator for traversing physical heap requested by ui32Flags. The - iterator will go through all of the segments (a segment is physically - contiguous) of the physical heap and return their CPU physical address and - size. - - @Input psDevNode: Pointer to device node struct. - @Input ui32Flags: Find heap that matches flags. - @Output ppsIter: Pointer to the iterator object. - - @Return PVRSRV_OK upon success and PVRSRV_ERROR otherwise. -******************************************************************************/ -PVRSRV_ERROR LMA_HeapIteratorCreate(PVRSRV_DEVICE_NODE *psDevNode, - PHYS_HEAP_USAGE_FLAGS ui32Flags, - PHYS_HEAP_ITERATOR **ppsIter); - -/*! -****************************************************************************** - @Function LMA_HeapIteratorDestroy - - @Description - Frees the iterator object created with LMA_HeapIteratorCreate. - - @Input psIter: Pointer to the iterator object. -******************************************************************************/ -void LMA_HeapIteratorDestroy(PHYS_HEAP_ITERATOR *psIter); - -/*! -****************************************************************************** - @Function LMA_HeapIteratorReset - - @Description - Resets the iterator the first segment of the physical heap. - - @Input psIter: Pointer to the iterator object. -******************************************************************************/ -PVRSRV_ERROR LMA_HeapIteratorReset(PHYS_HEAP_ITERATOR *psIter); - -/*! -****************************************************************************** - @Function LMA_HeapIteratorNext - - @Description - Retrieves current segment's physical device address and size and moves the - iterator to the next element (if exists). If the iterator reached an end of - the heap and no segment was retrieved, this function returns IMG_FALSE. - - @Input psIter: Pointer to the iterator object. - @Output psDevPAddr: Device physical address of the current segment. - @Output puiSize: Size of the current segment. - - @Return IMG TRUE if a segment was found and retrieved, IMG_FALSE otherwise. -******************************************************************************/ -IMG_BOOL LMA_HeapIteratorNext(PHYS_HEAP_ITERATOR *psIter, - IMG_DEV_PHYADDR *psDevPAddr, - IMG_UINT64 *puiSize); - -/*! -****************************************************************************** - @Function LMA_HeapIteratorGetHeapStats - - @Description - Retrieves phys heap's usage statistics. - - @Input psPhysHeap: Pointer to the physical heap object. - @Output puiTotalSize: Total size of the physical heap. - @Output puiInUseSize: Used space in the physical heap. - - @Return PVRSRV_OK upon success and PVRSRV_otherwise. -******************************************************************************/ -PVRSRV_ERROR LMA_HeapIteratorGetHeapStats(PHYS_HEAP_ITERATOR *psIter, - IMG_UINT64 *puiTotalSize, - IMG_UINT64 *puiInUseSize); - -/*! -****************************************************************************** - @Function PVRSRVPollForValueKM - - @Description - Polls for a value to match a masked read - - @Input psDevNode : Pointer to device node struct - @Input pui32LinMemAddr : CPU linear address to poll - @Input ui32Value : required value - @Input ui32Mask : Mask - @Input bDebugDumpOnFailure : Whether poll failure should result into a debug - dump. CAUTION: When calling this function from code paths which are - also used by debug-dumping code, this argument MUST be IMG_FALSE - otherwise, we might end up requesting debug-dump in recursion and - eventually blow-up call stack. - - @Return PVRSRV_ERROR : -******************************************************************************/ -PVRSRV_ERROR PVRSRVPollForValueKM(PVRSRV_DEVICE_NODE *psDevNode, - volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - POLL_FLAGS ePollFlags); - -/*! -****************************************************************************** - @Function PVRSRVWaitForValueKM - - @Description - Waits (using EventObjects) for a value to match a masked read - - @Input pui32LinMemAddr : CPU linear address to poll - @Input ui32Value : Required value - @Input ui32Mask : Mask to be applied before checking against - ui32Value - @Return PVRSRV_ERROR : -******************************************************************************/ -PVRSRV_ERROR -PVRSRVWaitForValueKM(volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask); - -/*! -****************************************************************************** - @Function : PVRSRVSystemHasCacheSnooping - - @Description : Returns whether the system has cache snooping - - @Return : IMG_TRUE if the system has cache snooping -******************************************************************************/ -IMG_BOOL PVRSRVSystemHasCacheSnooping(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVSystemSnoopingIsEmulated - - @Description : Returns whether system cache snooping support is emulated - - @Return : IMG_TRUE if the system cache snooping is emulated in software -******************************************************************************/ -IMG_BOOL PVRSRVSystemSnoopingIsEmulated(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVSystemSnoopingOfCPUCache - - @Description : Returns whether the system supports snooping of the CPU cache - - @Return : IMG_TRUE if the system has CPU cache snooping -******************************************************************************/ -IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVSystemSnoopingOfDeviceCache - - @Description : Returns whether the system supports snooping of the device cache - - @Return : IMG_TRUE if the system has device cache snooping -******************************************************************************/ -IMG_BOOL PVRSRVSystemSnoopingOfDeviceCache(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVSystemHasNonMappableLocalMemory - - @Description : Returns whether the device has non-mappable part of local memory - - @Return : IMG_TRUE if the device has non-mappable part of local memory -******************************************************************************/ -IMG_BOOL PVRSRVSystemHasNonMappableLocalMemory(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVSystemWaitCycles - - @Description : Waits for at least ui32Cycles of the Device clk. -******************************************************************************/ -void PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT32 ui32Cycles); - -PVRSRV_ERROR PVRSRVSystemInstallDeviceLISR(void *pvOSDevice, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszName, - PFN_LISR pfnLISR, - void *pvData, - IMG_HANDLE *phLISRData); - -PVRSRV_ERROR PVRSRVSystemUninstallDeviceLISR(IMG_HANDLE hLISRData); - -int PVRSRVGetDriverStatus(void); - -/*! -****************************************************************************** - @Function : PVRSRVIsBridgeEnabled - - @Description : Returns whether the given bridge group is enabled - - @Return : IMG_TRUE if the given bridge group is enabled -******************************************************************************/ -static inline IMG_BOOL PVRSRVIsBridgeEnabled(IMG_HANDLE hServices, IMG_UINT32 ui32BridgeGroup) -{ - IMG_UINT32 ui32Bridges; - IMG_UINT32 ui32Offset; - - PVR_UNREFERENCED_PARAMETER(hServices); - -#if defined(SUPPORT_RGX) - if (ui32BridgeGroup >= PVRSRV_BRIDGE_RGX_FIRST) - { - ui32Bridges = gui32RGXBridges; - ui32Offset = PVRSRV_BRIDGE_RGX_FIRST; - } - else -#endif /* SUPPORT_RGX */ - { - ui32Bridges = gui32PVRBridges; - ui32Offset = PVRSRV_BRIDGE_FIRST; - } - - return (IMG_BOOL)(((1U << (ui32BridgeGroup - ui32Offset)) & ui32Bridges) != 0); -} - - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#if defined(EMULATOR) - void SetAxiProtOSid(IMG_UINT32 ui32OSid, IMG_BOOL bState); - void SetTrustedDeviceAceEnabled(void); -#endif -#endif - -/*! -****************************************************************************** - @Function : PVRSRVCreateHWPerfHostThread - - @Description : Creates HWPerf event object and thread unless already created - - @Input ui32Timeout : Initial timeout (ms) between updates on the HWPerf thread - - @Return : PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -******************************************************************************/ -PVRSRV_ERROR PVRSRVCreateHWPerfHostThread(IMG_UINT32 ui32Timeout); - -/*! -****************************************************************************** - @Function : PVRSRVDestroyHWPerfHostThread - - @Description : Destroys HWPerf event object and thread if created - - @Return : PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -******************************************************************************/ -PVRSRV_ERROR PVRSRVDestroyHWPerfHostThread(void); - -/*! -****************************************************************************** - @Function : PVRSRVPhysMemHeapsInit - - @Description : Registers and acquires physical memory heaps - - @Return : PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -******************************************************************************/ -PVRSRV_ERROR PVRSRVPhysMemHeapsInit(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -****************************************************************************** - @Function : PVRSRVPhysMemHeapsDeinit - - @Description : Releases and unregisters physical memory heaps - - @Return : PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_ - error code -******************************************************************************/ -void PVRSRVPhysMemHeapsDeinit(PVRSRV_DEVICE_NODE *psDeviceNode); - -/*************************************************************************/ /*! -@Function FindPhysHeapConfig -@Description Find Phys Heap Config from Device Config. -@Input psDevConfig Pointer to device config. -@Input ui32Flags Find heap that matches flags. -@Return PHYS_HEAP_CONFIG* Return a config, or NULL if not found. -*/ /**************************************************************************/ -PHYS_HEAP_CONFIG* FindPhysHeapConfig(PVRSRV_DEVICE_CONFIG *psDevConfig, - PHYS_HEAP_USAGE_FLAGS ui32Flags); - -/*************************************************************************/ /*! -@Function PVRSRVGetDeviceInstance -@Description Return the specified device instance from Device node list. -@Input ui32Instance Device instance to find -@Return PVRSRV_DEVICE_NODE* Return a device node, or NULL if not found. -*/ /**************************************************************************/ -PVRSRV_DEVICE_NODE* PVRSRVGetDeviceInstance(IMG_UINT32 ui32Instance); - -/*************************************************************************/ /*! -@Function PVRSRVGetDeviceInstanceByOSId -@Description Return the specified device instance by OS Id. -@Input i32OSInstance OS device Id to find -@Return PVRSRV_DEVICE_NODE* Return a device node, or NULL if not found. -*/ /**************************************************************************/ -PVRSRV_DEVICE_NODE *PVRSRVGetDeviceInstanceByOSId(IMG_INT32 i32OSInstance); - -/*************************************************************************/ /*! -@Function PVRSRVDefaultDomainPower -@Description Returns psDevNode->eCurrentSysPowerState -@Input PVRSRV_DEVICE_NODE* Device node -@Return PVRSRV_SYS_POWER_STATE System power state tracked internally -*/ /**************************************************************************/ -PVRSRV_SYS_POWER_STATE PVRSRVDefaultDomainPower(PVRSRV_DEVICE_NODE *psDevNode); - -#endif /* PVRSRV_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_apphint.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_apphint.h deleted file mode 100644 index e354266807954..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_apphint.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title PowerVR AppHint generic interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(PVRSRV_APPHINT_H) -#define PVRSRV_APPHINT_H - -/* Supplied to PVRSRVAppHintRegisterHandlers*() functions when the apphint - * is a global driver apphint, i.e. apphints not present in - * APPHINT_DEBUGFS_DEVICE_ID, i.e. not per device. - */ -#define APPHINT_OF_DRIVER_NO_DEVICE ((void*)-1U) - -#if defined(__linux__) - -#include "km_apphint.h" -#define PVRSRVAppHintDumpState(d) pvr_apphint_dump_state(d) -#define PVRSRVAppHintRegisterHandlersUINT64(i,q,s,d,p) pvr_apphint_register_handlers_uint64(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersUINT32(i,q,s,d,p) pvr_apphint_register_handlers_uint32(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersBOOL(i,q,s,d,p) pvr_apphint_register_handlers_bool(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersSTRING(i,q,s,d,p) pvr_apphint_register_handlers_string(i,q,s,d,p) - -#else - -#define PVRSRVAppHintDumpState(d) -#define PVRSRVAppHintRegisterHandlersUINT64(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersUINT32(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersBOOL(i,q,s,d,p) -#define PVRSRVAppHintRegisterHandlersSTRING(i,q,s,d,p) - -#endif - -#endif /* PVRSRV_APPHINT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.c b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.c deleted file mode 100644 index 2ce4ae0a858ae..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.c +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR Common Bridge Init/Deinit Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements common PVR Bridge init/deinit code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv_bridge_init.h" -#include "srvcore.h" - -/* These will go when full bridge gen comes in */ -#if defined(PDUMP) -PVRSRV_ERROR InitPDUMPCTRLBridge(void); -void DeinitPDUMPCTRLBridge(void); -PVRSRV_ERROR InitPDUMPBridge(void); -void DeinitPDUMPBridge(void); -PVRSRV_ERROR InitRGXPDUMPBridge(void); -void DeinitRGXPDUMPBridge(void); -#endif -#if defined(SUPPORT_DISPLAY_CLASS) -PVRSRV_ERROR InitDCBridge(void); -void DeinitDCBridge(void); -#endif -PVRSRV_ERROR InitMMBridge(void); -void DeinitMMBridge(void); -#if !defined(EXCLUDE_CMM_BRIDGE) -PVRSRV_ERROR InitCMMBridge(void); -void DeinitCMMBridge(void); -#endif -PVRSRV_ERROR InitPDUMPMMBridge(void); -void DeinitPDUMPMMBridge(void); -PVRSRV_ERROR InitSRVCOREBridge(void); -void DeinitSRVCOREBridge(void); -PVRSRV_ERROR InitSYNCBridge(void); -void DeinitSYNCBridge(void); -#if defined(SUPPORT_DMA_TRANSFER) -PVRSRV_ERROR InitDMABridge(void); -void DeinitDMABridge(void); -#endif - -#if defined(SUPPORT_RGX) -PVRSRV_ERROR InitRGXTA3DBridge(void); -void DeinitRGXTA3DBridge(void); -#if defined(SUPPORT_RGXTQ_BRIDGE) -PVRSRV_ERROR InitRGXTQBridge(void); -void DeinitRGXTQBridge(void); -#endif /* defined(SUPPORT_RGXTQ_BRIDGE) */ - -#if defined(SUPPORT_USC_BREAKPOINT) -PVRSRV_ERROR InitRGXBREAKPOINTBridge(void); -void DeinitRGXBREAKPOINTBridge(void); -#endif -PVRSRV_ERROR InitRGXFWDBGBridge(void); -void DeinitRGXFWDBGBridge(void); -PVRSRV_ERROR InitRGXHWPERFBridge(void); -void DeinitRGXHWPERFBridge(void); -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) -PVRSRV_ERROR InitRGXREGCONFIGBridge(void); -void DeinitRGXREGCONFIGBridge(void); -#endif -PVRSRV_ERROR InitRGXKICKSYNCBridge(void); -void DeinitRGXKICKSYNCBridge(void); -#endif /* SUPPORT_RGX */ -PVRSRV_ERROR InitCACHEBridge(void); -void DeinitCACHEBridge(void); -#if defined(SUPPORT_SECURE_EXPORT) -PVRSRV_ERROR InitSMMBridge(void); -void DeinitSMMBridge(void); -#endif -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) -PVRSRV_ERROR InitHTBUFFERBridge(void); -void DeinitHTBUFFERBridge(void); -#endif -PVRSRV_ERROR InitPVRTLBridge(void); -void DeinitPVRTLBridge(void); -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) -PVRSRV_ERROR InitRIBridge(void); -void DeinitRIBridge(void); -#endif -PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void); -void DeinitDEVICEMEMHISTORYBridge(void); -#if defined(SUPPORT_VALIDATION_BRIDGE) -PVRSRV_ERROR InitVALIDATIONBridge(void); -void DeinitVALIDATIONBridge(void); -#endif -#if defined(PVR_TESTING_UTILS) -PVRSRV_ERROR InitTUTILSBridge(void); -void DeinitTUTILSBridge(void); -#endif -PVRSRV_ERROR InitSYNCTRACKINGBridge(void); -void DeinitSYNCTRACKINGBridge(void); -#if defined(SUPPORT_WRAP_EXTMEM) -PVRSRV_ERROR InitMMEXTMEMBridge(void); -void DeinitMMEXTMEMBridge(void); -#endif -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) -PVRSRV_ERROR InitSYNCFALLBACKBridge(void); -void DeinitSYNCFALLBACKBridge(void); -#endif -PVRSRV_ERROR InitRGXTIMERQUERYBridge(void); -void DeinitRGXTIMERQUERYBridge(void); -#if defined(SUPPORT_DI_BRG_IMPL) -PVRSRV_ERROR InitDIBridge(void); -void DeinitDIBridge(void); -#endif - -PVRSRV_ERROR -ServerBridgeInit(void) -{ - PVRSRV_ERROR eError; - - BridgeDispatchTableStartOffsetsInit(); - - eError = InitSRVCOREBridge(); - PVR_LOG_IF_ERROR(eError, "InitSRVCOREBridge"); - - eError = InitSYNCBridge(); - PVR_LOG_IF_ERROR(eError, "InitSYNCBridge"); - -#if defined(PDUMP) - eError = InitPDUMPCTRLBridge(); - PVR_LOG_IF_ERROR(eError, "InitPDUMPCTRLBridge"); -#endif - - eError = InitMMBridge(); - PVR_LOG_IF_ERROR(eError, "InitMMBridge"); - -#if !defined(EXCLUDE_CMM_BRIDGE) - eError = InitCMMBridge(); - PVR_LOG_IF_ERROR(eError, "InitCMMBridge"); -#endif - -#if defined(PDUMP) - eError = InitPDUMPMMBridge(); - PVR_LOG_IF_ERROR(eError, "InitPDUMPMMBridge"); - - eError = InitPDUMPBridge(); - PVR_LOG_IF_ERROR(eError, "InitPDUMPBridge"); -#endif - -#if defined(SUPPORT_DISPLAY_CLASS) - eError = InitDCBridge(); - PVR_LOG_IF_ERROR(eError, "InitDCBridge"); -#endif - - eError = InitCACHEBridge(); - PVR_LOG_IF_ERROR(eError, "InitCACHEBridge"); - -#if defined(SUPPORT_SECURE_EXPORT) - eError = InitSMMBridge(); - PVR_LOG_IF_ERROR(eError, "InitSMMBridge"); -#endif - -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) - eError = InitHTBUFFERBridge(); - PVR_LOG_IF_ERROR(eError, "InitHTBUFFERBridge"); -#endif - - eError = InitPVRTLBridge(); - PVR_LOG_IF_ERROR(eError, "InitPVRTLBridge"); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - eError = InitRIBridge(); - PVR_LOG_IF_ERROR(eError, "InitRIBridge"); -#endif - -#if defined(SUPPORT_VALIDATION_BRIDGE) - eError = InitVALIDATIONBridge(); - PVR_LOG_IF_ERROR(eError, "InitVALIDATIONBridge"); -#endif - -#if defined(PVR_TESTING_UTILS) - eError = InitTUTILSBridge(); - PVR_LOG_IF_ERROR(eError, "InitTUTILSBridge"); -#endif - - eError = InitDEVICEMEMHISTORYBridge(); - PVR_LOG_IF_ERROR(eError, "InitDEVICEMEMHISTORYBridge"); - - eError = InitSYNCTRACKINGBridge(); - PVR_LOG_IF_ERROR(eError, "InitSYNCTRACKINGBridge"); - -#if defined(SUPPORT_DMA_TRANSFER) - eError = InitDMABridge(); - PVR_LOG_IF_ERROR(eError, "InitDMABridge"); -#endif - -#if defined(SUPPORT_RGX) - -#if defined(SUPPORT_RGXTQ_BRIDGE) - eError = InitRGXTQBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXTQBridge"); -#endif /* defined(SUPPORT_RGXTQ_BRIDGE) */ - - eError = InitRGXTA3DBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXTA3DBridge"); - - #if defined(SUPPORT_USC_BREAKPOINT) - eError = InitRGXBREAKPOINTBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXBREAKPOINTBridge"); -#endif - - eError = InitRGXFWDBGBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXFWDBGBridge"); - -#if defined(PDUMP) - eError = InitRGXPDUMPBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXPDUMPBridge"); -#endif - - eError = InitRGXHWPERFBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXHWPERFBridge"); - -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) - eError = InitRGXREGCONFIGBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXREGCONFIGBridge"); -#endif - - eError = InitRGXKICKSYNCBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXKICKSYNCBridge"); - - eError = InitRGXTIMERQUERYBridge(); - PVR_LOG_IF_ERROR(eError, "InitRGXTIMERQUERYBridge"); - -#endif /* SUPPORT_RGX */ - -#if defined(SUPPORT_WRAP_EXTMEM) - eError = InitMMEXTMEMBridge(); - PVR_LOG_IF_ERROR(eError, "InitMMEXTMEMBridge"); -#endif - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - eError = InitSYNCFALLBACKBridge(); - PVR_LOG_IF_ERROR(eError, "InitSYNCFALLBACKBridge"); -#endif - -#if defined(SUPPORT_DI_BRG_IMPL) - eError = InitDIBridge(); - PVR_LOG_IF_ERROR(eError, "InitDIBridge"); -#endif - - eError = OSPlatformBridgeInit(); - PVR_LOG_IF_ERROR(eError, "OSPlatformBridgeInit"); - - return eError; -} - -void ServerBridgeDeInit(void) -{ - OSPlatformBridgeDeInit(); - -#if defined(SUPPORT_DI_BRG_IMPL) - DeinitDIBridge(); -#endif - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - DeinitSYNCFALLBACKBridge(); -#endif - -#if defined(SUPPORT_WRAP_EXTMEM) - DeinitMMEXTMEMBridge(); -#endif - - DeinitSRVCOREBridge(); - - DeinitSYNCBridge(); - -#if defined(PDUMP) - DeinitPDUMPCTRLBridge(); -#endif - - DeinitMMBridge(); - -#if !defined(EXCLUDE_CMM_BRIDGE) - DeinitCMMBridge(); -#endif - -#if defined(PDUMP) - DeinitPDUMPMMBridge(); - - DeinitPDUMPBridge(); -#endif - -#if defined(PVR_TESTING_UTILS) - DeinitTUTILSBridge(); -#endif - -#if defined(SUPPORT_DISPLAY_CLASS) - DeinitDCBridge(); -#endif - - DeinitCACHEBridge(); - -#if defined(SUPPORT_SECURE_EXPORT) - DeinitSMMBridge(); -#endif - -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) - DeinitHTBUFFERBridge(); -#endif - - DeinitPVRTLBridge(); - -#if defined(SUPPORT_VALIDATION_BRIDGE) - DeinitVALIDATIONBridge(); -#endif - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - DeinitRIBridge(); -#endif - - DeinitDEVICEMEMHISTORYBridge(); - - DeinitSYNCTRACKINGBridge(); - -#if defined(SUPPORT_DMA_TRANSFER) - DeinitDMABridge(); -#endif - -#if defined(SUPPORT_RGX) - -#if defined(SUPPORT_RGXTQ_BRIDGE) - DeinitRGXTQBridge(); -#endif /* defined(SUPPORT_RGXTQ_BRIDGE) */ - - DeinitRGXTA3DBridge(); - -#if defined(SUPPORT_USC_BREAKPOINT) - DeinitRGXBREAKPOINTBridge(); -#endif - - DeinitRGXFWDBGBridge(); - -#if defined(PDUMP) - DeinitRGXPDUMPBridge(); -#endif - - DeinitRGXHWPERFBridge(); - -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) - DeinitRGXREGCONFIGBridge(); -#endif - - DeinitRGXKICKSYNCBridge(); - - DeinitRGXTIMERQUERYBridge(); - -#endif /* SUPPORT_RGX */ -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.h deleted file mode 100644 index 750c9816c8ac4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_bridge_init.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title PVR Common Bridge Init/Deinit Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the common PVR Bridge init/deinit code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_BRIDGE_INIT_H -#define PVRSRV_BRIDGE_INIT_H - -#include "img_types.h" -#include "pvrsrv_error.h" - -PVRSRV_ERROR ServerBridgeInit(void); -void ServerBridgeDeInit(void); - -#endif /* PVRSRV_BRIDGE_INIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_cleanup.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_cleanup.h deleted file mode 100644 index 9eb454f5e1d12..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_cleanup.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title PowerVR SrvKM cleanup thread deferred work interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_CLEANUP_H -#define PVRSRV_CLEANUP_H - -#include "dllist.h" - -/**************************************************************************/ /*! -@Brief CLEANUP_THREAD_FN - -@Description This is the function prototype for the pfnFree member found in - the structure PVRSRV_CLEANUP_THREAD_WORK. The function is - responsible for carrying out the clean up work and if successful - freeing the memory originally supplied to the call - PVRSRVCleanupThreadAddWork(). - -@Input pvParam This is private data originally supplied by the caller - to PVRSRVCleanupThreadAddWork() when registering the - clean up work item, psDAta->pvData. Itr can be cast - to a relevant type within the using module. - -@Return PVRSRV_OK if the cleanup operation was successful and the - callback has freed the PVRSRV_CLEANUP_THREAD_WORK* work item - memory original supplied to PVRSRVCleanupThreadAddWork() - Any other error code will lead to the work item - being re-queued and hence the original - PVRSRV_CLEANUP_THREAD_WORK* must not be freed. -*/ /***************************************************************************/ - -typedef PVRSRV_ERROR (*CLEANUP_THREAD_FN)(void *pvParam); - - -/* Typical number of times a caller should want the work to be retried in case - * of the callback function (pfnFree) returning an error. - * Callers to PVRSRVCleanupThreadAddWork should provide this value as the retry - * count (ui32RetryCount) unless there are special requirements. - * A value of 200 corresponds to around ~20s (200 * 100ms). If it is not - * successful by then give up as an unrecoverable problem has occurred. - */ -#define CLEANUP_THREAD_RETRY_COUNT_DEFAULT 200u -/* Like for CLEANUP_THREAD_RETRY_COUNT_DEFAULT but call will wait for - * a specified amount of time rather than number of retries. - */ -#define CLEANUP_THREAD_RETRY_TIMEOUT_MS_DEFAULT 20000u /* 20s */ - -/* Use to set retry count on a cleanup item. - * _item - pointer to the PVRSRV_CLEANUP_THREAD_WORK - * _count - retry count - */ -#define CLEANUP_THREAD_SET_RETRY_COUNT(_item,_count) \ - do { \ - (_item)->ui32RetryCount = (_count); \ - (_item)->ui32TimeStart = 0; \ - (_item)->ui32TimeEnd = 0; \ - } while (0) - -/* Use to set timeout deadline on a cleanup item. - * _item - pointer to the PVRSRV_CLEANUP_THREAD_WORK - * _timeout - timeout in milliseconds, if 0 - * CLEANUP_THREAD_RETRY_TIMEOUT_MS_DEFAULT is used - */ -#define CLEANUP_THREAD_SET_RETRY_TIMEOUT(_item,_timeout) \ - do { \ - (_item)->ui32RetryCount = 0; \ - (_item)->ui32TimeStart = OSClockms(); \ - (_item)->ui32TimeEnd = (_item)->ui32TimeStart + ((_timeout) > 0 ? \ - (_timeout) : CLEANUP_THREAD_RETRY_TIMEOUT_MS_DEFAULT); \ - } while (0) - -/* Indicates if the timeout on a given item has been reached. - * _item - pointer to the PVRSRV_CLEANUP_THREAD_WORK - */ -#define CLEANUP_THREAD_RETRY_TIMEOUT_REACHED(_item) \ - ((_item)->ui32TimeEnd - (_item)->ui32TimeStart >= \ - OSClockms() - (_item)->ui32TimeStart) - -/* Indicates if the current item is waiting on timeout or retry count. - * _item - pointer to the PVRSRV_CLEANUP_THREAD_WORK - * */ -#define CLEANUP_THREAD_IS_RETRY_TIMEOUT(_item) \ - ((_item)->ui32TimeStart != (_item->ui32TimeEnd)) - -/* Clean up work item specifics so that the task can be managed by the - * pvr_defer_free cleanup thread in the Server. - */ -typedef struct _PVRSRV_CLEANUP_THREAD_WORK_ -{ - DLLIST_NODE sNode; /*!< List node used internally by the cleanup - thread */ - CLEANUP_THREAD_FN pfnFree; /*!< Pointer to the function to be called to - carry out the deferred cleanup */ - void *pvData; /*!< private data for pfnFree, usually a way back - to the original PVRSRV_CLEANUP_THREAD_WORK* - pointer supplied in the call to - PVRSRVCleanupThreadAddWork(). */ - IMG_UINT32 ui32TimeStart; /*!< Timestamp in ms of the moment when - cleanup item has been created. */ - IMG_UINT32 ui32TimeEnd; /*!< Time in ms after which no further retry - attempts will be made, item discard and - error logged when this is reached. */ - IMG_UINT32 ui32RetryCount; /*!< Number of times the callback should be - re-tried when it returns error. */ - IMG_BOOL bDependsOnHW; /*!< Retry again after the RGX interrupt signals - the global event object */ -} PVRSRV_CLEANUP_THREAD_WORK; - - -/**************************************************************************/ /*! -@Function PVRSRVCleanupThreadAddWork - -@Description Add a work item to be called from the cleanup thread - -@Input psData : The function pointer and private data for the callback - -@Return None -*/ /***************************************************************************/ -void PVRSRVCleanupThreadAddWork(PVRSRV_CLEANUP_THREAD_WORK *psData); - -/**************************************************************************/ /*! -@Function PVRSRVCleanupThreadGetPid - -@Description Returns Cleanup Thread's PID. - -@Return PID of the Cleanup Thread -*/ /***************************************************************************/ -IMG_PID PVRSRVCleanupThreadGetPid(void); - -/**************************************************************************/ /*! -@Function PVRSRVCleanupThreadGetTid - -@Description Returns Cleanup Thread's TID. - -@Return TID of the Cleanup Thread -*/ /***************************************************************************/ -uintptr_t PVRSRVCleanupThreadGetTid(void); - -#endif /* PVRSRV_CLEANUP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device.h deleted file mode 100644 index b97e015cb7002..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device.h +++ /dev/null @@ -1,401 +0,0 @@ -/**************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_DEVICE_H -#define PVRSRV_DEVICE_H - -#include "img_types.h" -#include "physheap.h" -#include "pvrsrv_error.h" -#include "pvrsrv_memalloc_physheap.h" -#include "pvrsrv_firmware_boot.h" -#include "rgx_fwif_km.h" -#include "servicesext.h" -#include "cache_ops.h" - -#if defined(SUPPORT_LINUX_DVFS) || defined(SUPPORT_PDVFS) -#include "pvr_dvfs.h" -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -typedef struct _PVRSRV_DEVICE_CONFIG_ PVRSRV_DEVICE_CONFIG; -typedef enum _DRIVER_MODE_ -{ -/* Do not use these enumerations directly, to query the - current driver mode, use the PVRSRV_VZ_MODE_IS() - macro */ - DRIVER_MODE_NATIVE = -1, - DRIVER_MODE_HOST = 0, - DRIVER_MODE_GUEST -} PVRSRV_DRIVER_MODE; - -typedef enum -{ - PVRSRV_DEVICE_LOCAL_MEMORY_ARENA_MAPPABLE = 0, - PVRSRV_DEVICE_LOCAL_MEMORY_ARENA_NON_MAPPABLE = 1, - PVRSRV_DEVICE_LOCAL_MEMORY_ARENA_LAST -} PVRSRV_DEVICE_LOCAL_MEMORY_ARENA; - -typedef enum _PVRSRV_DEVICE_SNOOP_MODE_ -{ - PVRSRV_DEVICE_SNOOP_NONE = 0, - PVRSRV_DEVICE_SNOOP_CPU_ONLY, - PVRSRV_DEVICE_SNOOP_DEVICE_ONLY, - PVRSRV_DEVICE_SNOOP_CROSS, - PVRSRV_DEVICE_SNOOP_EMULATED, -} PVRSRV_DEVICE_SNOOP_MODE; - -#if defined(SUPPORT_SOC_TIMER) -typedef IMG_UINT64 -(*PFN_SYS_DEV_SOC_TIMER_READ)(IMG_HANDLE hSysData); -#endif - -typedef enum _PVRSRV_DEVICE_FABRIC_TYPE_ -{ - PVRSRV_DEVICE_FABRIC_NONE = 0, - PVRSRV_DEVICE_FABRIC_ACELITE, - PVRSRV_DEVICE_FABRIC_FULLACE, -} PVRSRV_DEVICE_FABRIC_TYPE; - -typedef IMG_UINT32 -(*PFN_SYS_DEV_CLK_FREQ_GET)(IMG_HANDLE hSysData); - -typedef PVRSRV_ERROR -(*PFN_SYS_PRE_POWER)(IMG_HANDLE hSysData, - PVRSRV_SYS_POWER_STATE eNewPowerState, - PVRSRV_SYS_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -typedef PVRSRV_ERROR -(*PFN_SYS_POST_POWER)(IMG_HANDLE hSysData, - PVRSRV_SYS_POWER_STATE eNewPowerState, - PVRSRV_SYS_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*************************************************************************/ /*! -@Brief Callback function type PFN_SYS_GET_POWER - -@Description This function queries the SoC power registers to determine - if the power domain on which the GPU resides is powered on. - - Implementation of this callback is optional - where it is not provided, - the driver will assume the domain power state depending on driver type: - regular drivers assume it is unpowered at startup, while drivers with - AutoVz support expect the GPU domain to be powered on initially. The power - state will be then tracked internally according to the pfnPrePowerState - and pfnPostPowerState calls using a fallback function. - -@Input psDevNode Pointer to node struct of the - device being initialised - -@Return PVRSRV_SYS_POWER_STATE_ON if the respective device's hardware - domain is powered on - PVRSRV_SYS_POWER_STATE_OFF if the domain is powered off -*/ /**************************************************************************/ -typedef PVRSRV_SYS_POWER_STATE -(*PFN_SYS_GET_POWER)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - -typedef void -(*PFN_SYS_DEV_INTERRUPT_HANDLED)(PVRSRV_DEVICE_CONFIG *psDevConfig); - -typedef PVRSRV_ERROR -(*PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE)(IMG_HANDLE hSysData, - IMG_UINT64 ui64MemSize); - -typedef void (*PFN_SYS_DEV_FEAT_DEP_INIT)(PVRSRV_DEVICE_CONFIG *, IMG_UINT64); - -typedef void -(*PFN_SYS_DEV_HOST_CACHE_MAINTENANCE)(IMG_HANDLE hSysData, - PVRSRV_CACHE_OP eRequestType, - void *pvVirtStart, - void *pvVirtEnd, - IMG_CPU_PHYADDR sCPUPhysStart, - IMG_CPU_PHYADDR sCPUPhysEnd); - -typedef void* -(*PFN_SLAVE_DMA_CHAN)(PVRSRV_DEVICE_CONFIG*, char*); - -typedef void -(*PFN_SLAVE_DMA_FREE)(PVRSRV_DEVICE_CONFIG*, - void*); - -typedef void -(*PFN_DEV_PHY_ADDR_2_DMA_ADDR)(PVRSRV_DEVICE_CONFIG *, - IMG_DMA_ADDR *, - IMG_DEV_PHYADDR *, - IMG_BOOL *, - IMG_UINT32, - IMG_BOOL); - - -#if defined(SUPPORT_TRUSTED_DEVICE) - -typedef struct _PVRSRV_TD_FW_PARAMS_ -{ - const void *pvFirmware; - IMG_UINT32 ui32FirmwareSize; - PVRSRV_FW_BOOT_PARAMS uFWP; -} PVRSRV_TD_FW_PARAMS; - -typedef PVRSRV_ERROR -(*PFN_TD_SEND_FW_IMAGE)(IMG_HANDLE hSysData, - PVRSRV_TD_FW_PARAMS *psTDFWParams); - -typedef struct _PVRSRV_TD_POWER_PARAMS_ -{ - IMG_DEV_PHYADDR sPCAddr; - - /* MIPS-only fields */ - IMG_DEV_PHYADDR sGPURegAddr; - IMG_DEV_PHYADDR sBootRemapAddr; - IMG_DEV_PHYADDR sCodeRemapAddr; - IMG_DEV_PHYADDR sDataRemapAddr; -} PVRSRV_TD_POWER_PARAMS; - -typedef PVRSRV_ERROR -(*PFN_TD_SET_POWER_PARAMS)(IMG_HANDLE hSysData, - PVRSRV_TD_POWER_PARAMS *psTDPowerParams); - -typedef PVRSRV_ERROR -(*PFN_TD_RGXSTART)(IMG_HANDLE hSysData); - -typedef PVRSRV_ERROR -(*PFN_TD_RGXSTOP)(IMG_HANDLE hSysData); - -#endif /* defined(SUPPORT_TRUSTED_DEVICE) */ - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -typedef void (*PFN_SYS_DEV_VIRT_INIT)(IMG_UINT64[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS], IMG_UINT64[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS]); -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - -typedef struct _PVRSRV_ROBUSTNESS_ERR_DATA_HOST_WDG_ -{ - IMG_UINT32 ui32Status; /*!< FW status */ - IMG_UINT32 ui32Reason; /*!< Reason for FW status */ -} PVRSRV_ROBUSTNESS_ERR_DATA_HOST_WDG; - -typedef struct _PVRSRV_ROBUSTNESS_ERR_DATA_FW_PF_ -{ - IMG_DEV_VIRTADDR sFWFaultAddr; /*!< FW page fault address */ -} PVRSRV_ROBUSTNESS_ERR_DATA_FW_PF; - -typedef struct _PVRSRV_ROBUSTNESS_ERR_DATA_CHECKSUM_ -{ - IMG_UINT32 ui32ExtJobRef; /*!< External Job Reference of any affected GPU work */ - RGXFWIF_DM eDM; /*!< Data Master which was running any affected GPU work */ -} PVRSRV_ROBUSTNESS_ERR_DATA_CHECKSUM; - -typedef struct _PVRSRV_ROBUSTNESS_NOTIFY_DATA_ -{ - RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reason for error/reset */ - IMG_PID pid; /*!< Pid of process which created the errored context */ - union - { - PVRSRV_ROBUSTNESS_ERR_DATA_CHECKSUM sChecksumErrData; /*!< Data returned for checksum errors */ - PVRSRV_ROBUSTNESS_ERR_DATA_FW_PF sFwPFErrData; /*!< Data returned for FW page faults */ - PVRSRV_ROBUSTNESS_ERR_DATA_HOST_WDG sHostWdgData; /*!< Data returned for Host Wdg FW faults */ - } uErrData; -} PVRSRV_ROBUSTNESS_NOTIFY_DATA; - -typedef void -(*PFN_SYS_DEV_ERROR_NOTIFY)(IMG_HANDLE hSysData, - PVRSRV_ROBUSTNESS_NOTIFY_DATA *psRobustnessErrorData); - -struct _PVRSRV_DEVICE_CONFIG_ -{ - /*! OS device passed to SysDevInit (linux: 'struct device') */ - void *pvOSDevice; - - /*! - *! Service representation of pvOSDevice. Should be set to NULL when the - *! config is created in SysDevInit. Set by Services once a device node has - *! been created for this config and unset before SysDevDeInit is called. - */ - struct _PVRSRV_DEVICE_NODE_ *psDevNode; - - /*! Name of the device */ - IMG_CHAR *pszName; - - /*! Version of the device (optional) */ - IMG_CHAR *pszVersion; - - /*! Register bank address */ - IMG_CPU_PHYADDR sRegsCpuPBase; - /*! Register bank size */ - IMG_UINT32 ui32RegsSize; - /*! Device interrupt number */ - IMG_UINT32 ui32IRQ; - - PVRSRV_DEVICE_SNOOP_MODE eCacheSnoopingMode; - - /*! Device specific data handle */ - IMG_HANDLE hDevData; - - /*! System specific data that gets passed into system callback functions. */ - IMG_HANDLE hSysData; - - IMG_BOOL bHasNonMappableLocalMemory; - - /*! Indicates if system supports FBCDC v3.1 */ - IMG_BOOL bHasFBCDCVersion31; - - /*! Physical Heap definitions for this device. - * eDefaultHeap must be set to GPU_LOCAL or CPU_LOCAL. Specifying any other value - * (e.g. DEFAULT) will lead to an error at device discovery. - * pasPhysHeap array must contain at least one PhysHeap, the declared default heap. - */ - PVRSRV_PHYS_HEAP eDefaultHeap; - PHYS_HEAP_CONFIG *pasPhysHeaps; - IMG_UINT32 ui32PhysHeapCount; - - /*! - *! Callbacks to change system device power state at the beginning and end - *! of a power state change (optional). - */ - PFN_SYS_PRE_POWER pfnPrePowerState; - PFN_SYS_POST_POWER pfnPostPowerState; - PFN_SYS_GET_POWER pfnGpuDomainPower; - - /*! Callback to obtain the clock frequency from the device (optional). */ - PFN_SYS_DEV_CLK_FREQ_GET pfnClockFreqGet; - -#if defined(SUPPORT_SOC_TIMER) - /*! Callback to read SoC timer register value (mandatory). */ - PFN_SYS_DEV_SOC_TIMER_READ pfnSoCTimerRead; -#endif - - /*! - *! Callback to handle memory budgeting. Can be used to reject allocations - *! over a certain size (optional). - */ - PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE pfnCheckMemAllocSize; - - /*! - *! Callback to perform host CPU cache maintenance. Might be needed for - *! architectures which allow extensions such as RISC-V (optional). - */ - PFN_SYS_DEV_HOST_CACHE_MAINTENANCE pfnHostCacheMaintenance; - IMG_BOOL bHasPhysicalCacheMaintenance; - -#if defined(SUPPORT_TRUSTED_DEVICE) - /*! - *! Callback to send FW image and FW boot time parameters to the trusted - *! device. - */ - PFN_TD_SEND_FW_IMAGE pfnTDSendFWImage; - - /*! - *! Callback to send parameters needed in a power transition to the trusted - *! device. - */ - PFN_TD_SET_POWER_PARAMS pfnTDSetPowerParams; - - /*! Callbacks to ping the trusted device to securely run RGXStart/Stop() */ - PFN_TD_RGXSTART pfnTDRGXStart; - PFN_TD_RGXSTOP pfnTDRGXStop; -#endif /* defined(SUPPORT_TRUSTED_DEVICE) */ - - /*! Function that does device feature specific system layer initialisation */ - PFN_SYS_DEV_FEAT_DEP_INIT pfnSysDevFeatureDepInit; - -#if defined(SUPPORT_LINUX_DVFS) || defined(SUPPORT_PDVFS) - PVRSRV_DVFS sDVFS; -#endif - -#if defined(SUPPORT_ALT_REGBASE) - IMG_DEV_PHYADDR sAltRegsGpuPBase; -#endif - - /*! - *! Indicates if device physical address 0x0 might be used as GPU memory - *! (e.g. LMA system or UMA system with CPU PA 0x0 reserved by the OS, - *! but CPU PA != device PA and device PA 0x0 available for the GPU) - */ - IMG_BOOL bDevicePA0IsValid; - - /*! - *! Function to initialize System-specific virtualization. If not supported - *! this should be a NULL reference. Only present if - *! SUPPORT_GPUVIRT_VALIDATION is defined. - */ -#if defined(SUPPORT_GPUVIRT_VALIDATION) - PFN_SYS_DEV_VIRT_INIT pfnSysDevVirtInit; -#endif - - /*! - *! Callback to notify system layer of device errors. - *! NB. implementers should ensure that the minimal amount of work is - *! done in the callback function, as it will be executed in the main - *! RGX MISR. (e.g. any blocking or lengthy work should be performed by - *! a worker queue/thread instead.) - */ - PFN_SYS_DEV_ERROR_NOTIFY pfnSysDevErrorNotify; - - /*! - *! Slave DMA channel request callbacks - */ - PFN_SLAVE_DMA_CHAN pfnSlaveDMAGetChan; - PFN_SLAVE_DMA_FREE pfnSlaveDMAFreeChan; - /*! - *! Conversion of device memory to DMA addresses - */ - PFN_DEV_PHY_ADDR_2_DMA_ADDR pfnDevPhysAddr2DmaAddr; - /*! - *! DMA channel names - */ - IMG_CHAR *pszDmaTxChanName; - IMG_CHAR *pszDmaRxChanName; - /*! - *! DMA device transfer restrictions - */ - IMG_UINT32 ui32DmaAlignment; - IMG_UINT32 ui32DmaTransferUnit; - /*! - *! System-wide presence of DMA capabilities - */ - IMG_BOOL bHasDma; - -}; - -#endif /* PVRSRV_DEVICE_H*/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device_types.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device_types.h deleted file mode 100644 index 662e3bc171635..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_device_types.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PowerVR device type definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PVRSRV_DEVICE_TYPES_H) -#define PVRSRV_DEVICE_TYPES_H - -#include "img_types.h" - -#define PVRSRV_MAX_DEVICES 16U /*!< Largest supported number of devices on the system */ - -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - -#endif /* PVRSRV_DEVICE_TYPES_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_devvar.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_devvar.h deleted file mode 100644 index a8c64e309fdaf..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_devvar.h +++ /dev/null @@ -1,291 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Device Variable interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the client side interface for device variables -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_DEVVAR_H -#define PVRSRV_DEVVAR_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -#define DEVVAR_MAX_NAME_LEN 32 - -typedef struct SYNC_PRIM_CONTEXT_TAG *PDEVVARCTX; -typedef struct PVRSRV_CLIENT_SYNC_PRIM_TAG *PDEVVAR; - -typedef struct PVRSRV_DEV_VAR_UPDATE_TAG -{ - PDEVVAR psDevVar; /*!< Pointer to the dev var */ - IMG_UINT32 ui32UpdateValue; /*!< the update value */ -} PVRSRV_DEV_VAR_UPDATE; - -/*************************************************************************/ /*! -@Function PVRSRVDevVarContextCreate - -@Description Create a new device variable context - -@Input psDevConnection Device to create the device - variable context on - -@Output phDevVarContext Handle to the created device - variable context - -@Return PVRSRV_OK if the device variable context was successfully - created -*/ -/*****************************************************************************/ -IMG_EXPORT PVRSRV_ERROR -PVRSRVDevVarContextCreate(const PVRSRV_DEV_CONNECTION *psDevConnection, - PDEVVARCTX *phDevVarContext); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarContextDestroy - -@Description Destroy a device variable context - -@Input hDevVarContext Handle to the device variable - context to destroy - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarContextDestroy(PDEVVARCTX hDevVarContext); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarAlloc - -@Description Allocate a new device variable on the specified device - variable context. The device variable's value is initialised - with the value passed in ui32InitialValue. - -@Input hDevVarContext Handle to the device variable - context -@Input ui32InitialValue Value to initially assign to the - new variable -@Input pszDevVarName Name assigned to the device variable - (for debug purposes) - -@Output ppsDevVar Created device variable - -@Return PVRSRV_OK if the device variable was successfully created -*/ -/*****************************************************************************/ -IMG_EXPORT PVRSRV_ERROR -PVRSRVDevVarAllocI(PDEVVARCTX hDevVarContext, - PDEVVAR *ppsDevVar, - IMG_UINT32 ui32InitialValue, - const IMG_CHAR *pszDevVarName - PVR_DBG_FILELINE_PARAM); -#define PVRSRVDevVarAlloc(hDevVarContext, ppsDevVar, ui32InitialValue, pszDevVarName) \ - PVRSRVDevVarAllocI( (hDevVarContext), (ppsDevVar), (ui32InitialValue), (pszDevVarName) \ - PVR_DBG_FILELINE ) - -/*************************************************************************/ /*! -@Function PVRSRVDevVarFree - -@Description Free a device variable - -@Input psDevVar The device variable to free - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarFree(PDEVVAR psDevVar); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarSet - -@Description Set the device variable to a value - -@Input psDevVar The device variable to set - -@Input ui32Value Value to set it to - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarSet(PDEVVAR psDevVar, - IMG_UINT32 ui32Value); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarGet - -@Description Get the current value of the device variable - -@Input psDevVar The device variable to get the - value of - -@Return Value of the variable -*/ -/*****************************************************************************/ -IMG_EXPORT IMG_UINT32 -PVRSRVDevVarGet(PDEVVAR psDevVar); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarGetFirmwareAddr - -@Description Returns the address of the associated firmware value for a - specified device integer (not exposed to client) - -@Input psDevVar The device variable to resolve - -@Return The firmware address of the device variable -*/ -/*****************************************************************************/ -IMG_EXPORT IMG_UINT32 -PVRSRVDevVarGetFirmwareAddr(PDEVVAR psDevVar); - -#if defined(PDUMP) -/*************************************************************************/ /*! -@Function PVRSRVDevVarPDump - -@Description PDump the current value of the device variable - -@Input psDevVar The device variable to PDump - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarPDump(PDEVVAR psDevVar); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarPDumpPol - -@Description Do a PDump poll of the device variable - -@Input psDevVar The device variable to PDump - -@Input ui32Value Value to Poll for - -@Input ui32Mask PDump mask operator - -@Input ui32PDumpFlags PDump flags - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarPDumpPol(PDEVVAR psDevVar, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function PVRSRVDevVarPDumpCBP - -@Description Do a PDump CB poll using the device variable - -@Input psDevVar The device variable to PDump - -@Input uiWriteOffset Current write offset of buffer - -@Input uiPacketSize Size of the packet to write into CB - -@Input uiBufferSize Size of the CB - -@Return None -*/ -/*****************************************************************************/ -IMG_EXPORT void -PVRSRVDevVarPDumpCBP(PDEVVAR psDevVar, - IMG_UINT64 uiWriteOffset, - IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize); -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVDevVarPDump) -#endif -static INLINE void -PVRSRVDevVarPDump(PDEVVAR psDevVar) -{ - PVR_UNREFERENCED_PARAMETER(psDevVar); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVDevVarPDumpPol) -#endif -static INLINE void -PVRSRVDevVarPDumpPol(PDEVVAR psDevVar, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDevVar); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVDevVarPDumpCBP) -#endif -static INLINE void -PVRSRVDevVarPDumpCBP(PDEVVAR psDevVar, - IMG_UINT64 uiWriteOffset, - IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize) -{ - PVR_UNREFERENCED_PARAMETER(psDevVar); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); -} -#endif /* PDUMP */ - -#if defined(__cplusplus) -} -#endif -#endif /* PVRSRV_DEVVAR_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.c b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.c deleted file mode 100644 index 5cd02a28d5a15..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.c +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services error support -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "pvr_debug.h" - -IMG_EXPORT -const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError) -{ - switch (eError) - { - case PVRSRV_OK: - return "PVRSRV_OK"; -#define PVRE(x) \ - case x: \ - return #x; -#include "pvrsrv_errors.h" -#undef PVRE - default: - return "Unknown PVRSRV error number"; - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.h deleted file mode 100644 index 0bbf8431bedcb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_error.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File pvrsrv_error.h -@Title services error enumerant -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines error codes used by any/all services modules -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(PVRSRV_ERROR_H) -#define PVRSRV_ERROR_H - -/*! - ***************************************************************************** - * Error values - *****************************************************************************/ -typedef enum PVRSRV_ERROR_TAG -{ - PVRSRV_OK, -#define PVRE(x) x, -#include "pvrsrv_errors.h" -#undef PVRE - PVRSRV_ERROR_FORCE_I32 = 0x7fffffff - -} PVRSRV_ERROR; - -#endif /* !defined(PVRSRV_ERROR_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_errors.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_errors.h deleted file mode 100644 index 0ce0a61a7ede7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_errors.h +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************/ /*! -@File pvrsrv_errors.h -@Title services error codes -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines error codes used by any/all services modules -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* Don't add include guards to this file! */ - -PVRE(PVRSRV_ERROR_OUT_OF_MEMORY) -PVRE(PVRSRV_ERROR_TOO_FEW_BUFFERS) -PVRE(PVRSRV_ERROR_INVALID_PARAMS) -PVRE(PVRSRV_ERROR_INIT_FAILURE) -PVRE(PVRSRV_ERROR_CANT_REGISTER_CALLBACK) -PVRE(PVRSRV_ERROR_INVALID_DEVICE) -PVRE(PVRSRV_ERROR_NOT_OWNER) -PVRE(PVRSRV_ERROR_BAD_MAPPING) -PVRE(PVRSRV_ERROR_TIMEOUT) -PVRE(PVRSRV_ERROR_NOT_IMPLEMENTED) -PVRE(PVRSRV_ERROR_FLIP_CHAIN_EXISTS) -PVRE(PVRSRV_ERROR_INVALID_SWAPINTERVAL) -PVRE(PVRSRV_ERROR_SCENE_INVALID) -PVRE(PVRSRV_ERROR_STREAM_ERROR) -PVRE(PVRSRV_ERROR_FAILED_DEPENDENCIES) -PVRE(PVRSRV_ERROR_CMD_NOT_PROCESSED) -PVRE(PVRSRV_ERROR_CMD_TOO_BIG) -PVRE(PVRSRV_ERROR_DEVICE_REGISTER_FAILED) -PVRE(PVRSRV_ERROR_TOOMANYBUFFERS) -PVRE(PVRSRV_ERROR_NOT_SUPPORTED) -PVRE(PVRSRV_ERROR_PROCESSING_BLOCKED) -PVRE(PVRSRV_ERROR_CANNOT_FLUSH_QUEUE) -PVRE(PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) -PVRE(PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS) -PVRE(PVRSRV_ERROR_RETRY) -PVRE(PVRSRV_ERROR_DDK_VERSION_MISMATCH) -PVRE(PVRSRV_ERROR_DDK_BUILD_MISMATCH) -PVRE(PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH) -PVRE(PVRSRV_ERROR_BVNC_MISMATCH) -PVRE(PVRSRV_ERROR_FWPROCESSOR_MISMATCH) -PVRE(PVRSRV_ERROR_UPLOAD_TOO_BIG) -PVRE(PVRSRV_ERROR_INVALID_FLAGS) -PVRE(PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS) -PVRE(PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY) -PVRE(PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR) -PVRE(PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED) -PVRE(PVRSRV_ERROR_BRIDGE_CALL_FAILED) -PVRE(PVRSRV_ERROR_IOCTL_CALL_FAILED) -PVRE(PVRSRV_ERROR_MMU_API_PROTOCOL_ERROR) -PVRE(PVRSRV_ERROR_MMU_CONFIG_IS_WRONG) -PVRE(PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND) -PVRE(PVRSRV_ERROR_MMU_FAILED_TO_ALLOCATE_PAGETABLES) -PVRE(PVRSRV_ERROR_MMU_FAILED_TO_CREATE_HEAP) -PVRE(PVRSRV_ERROR_MMU_FAILED_TO_MAP_PAGE_TABLE) -PVRE(PVRSRV_ERROR_MMU_FAILED_TO_UNMAP_PAGE_TABLE) -PVRE(PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE) -PVRE(PVRSRV_ERROR_MMU_LIVE_ALLOCATIONS_IN_HEAP) -PVRE(PVRSRV_ERROR_MMU_RESERVATION_NOT_INSIDE_HEAP) -PVRE(PVRSRV_ERROR_PMR_NEW_MEMORY) -PVRE(PVRSRV_ERROR_PMR_STILL_REFERENCED) -PVRE(PVRSRV_ERROR_PMR_CLIENT_NOT_TRUSTED) -PVRE(PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES) -PVRE(PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY) -PVRE(PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES) -PVRE(PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE) -PVRE(PVRSRV_ERROR_PMR_NOT_PERMITTED) -PVRE(PVRSRV_ERROR_PMR_ALREADY_OCCUPIED) -PVRE(PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR) -PVRE(PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR) -PVRE(PVRSRV_ERROR_PMR_WRONG_PMR_TYPE) -PVRE(PVRSRV_ERROR_PMR_MAPPING_ALREADY_EXISTS) -PVRE(PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE) -PVRE(PVRSRV_ERROR_PMR_BAD_CHUNK_SIZE) -PVRE(PVRSRV_ERROR_PMR_MAPPINGTABLE_MISMATCH) -PVRE(PVRSRV_ERROR_PMR_INVALID_CHUNK) -PVRE(PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING) -PVRE(PVRSRV_ERROR_PMR_EMPTY) -PVRE(PVRSRV_ERROR_PMR_NO_CPU_MAP_FOUND) -PVRE(PVRSRV_ERROR_PMR_CPU_PAGE_UNMAP_FAILED) -PVRE(PVRSRV_ERROR_PMR_CPU_PAGE_MAP_FAILED) -PVRE(PVRSRV_ERROR_PMR_PAGE_POISONING_FAILED) -PVRE(PVRSRV_ERROR_PMR_INVALID_MAP_INDEX_ARRAY) -PVRE(PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP) -PVRE(PVRSRV_ERROR_DEVICEMEM_BAD_IMPORT_SIZE) -PVRE(PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION) -PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX) -PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX) -PVRE(PVRSRV_ERROR_DEVICEMEM_MAP_FAILED) -PVRE(PVRSRV_ERROR_DEVICEMEM_NON_ZERO_USAGE_COUNT) -PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE) -PVRE(PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED) -PVRE(PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA) -PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM) -PVRE(PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED) -PVRE(PVRSRV_ERROR_DEVICEMEM_NO_MAPPING) -PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS) -PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_LMA_HEAP) -PVRE(PVRSRV_ERROR_INVALID_MMU_TYPE) -PVRE(PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND) -PVRE(PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT) -PVRE(PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND) -PVRE(PVRSRV_ERROR_PCI_CALL_FAILED) -PVRE(PVRSRV_ERROR_PCI_REGION_TOO_SMALL) -PVRE(PVRSRV_ERROR_PCI_REGION_UNAVAILABLE) -PVRE(PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH) -PVRE(PVRSRV_ERROR_REGISTER_BASE_NOT_SET) -PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM) -PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY) -PVRE(PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC) -PVRE(PVRSRV_ERROR_FAILED_TO_MAP_KERNELVIRTUAL) -PVRE(PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR) -PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY) -PVRE(PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY) -PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES) -PVRE(PVRSRV_ERROR_FAILED_TO_FREE_PAGES) -PVRE(PVRSRV_ERROR_FAILED_TO_COPY_PAGES) -PVRE(PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES) -PVRE(PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES) -PVRE(PVRSRV_ERROR_STILL_MAPPED) -PVRE(PVRSRV_ERROR_MAPPING_NOT_FOUND) -PVRE(PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT) -PVRE(PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE) -PVRE(PVRSRV_ERROR_INVALID_SEGMENT_BLOCK) -PVRE(PVRSRV_ERROR_INVALID_GFXDEVDEVDATA) -PVRE(PVRSRV_ERROR_INVALID_DEVINFO) -PVRE(PVRSRV_ERROR_INVALID_MEMINFO) -PVRE(PVRSRV_ERROR_INVALID_MISCINFO) -PVRE(PVRSRV_ERROR_UNKNOWN_IOCTL) -PVRE(PVRSRV_ERROR_INVALID_CONTEXT) -PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT) -PVRE(PVRSRV_ERROR_INVALID_HEAP) -PVRE(PVRSRV_ERROR_INVALID_KERNELINFO) -PVRE(PVRSRV_ERROR_UNKNOWN_POWER_STATE) -PVRE(PVRSRV_ERROR_INVALID_HANDLE_TYPE) -PVRE(PVRSRV_ERROR_INVALID_WRAP_TYPE) -PVRE(PVRSRV_ERROR_INVALID_PHYS_ADDR) -PVRE(PVRSRV_ERROR_INVALID_CPU_ADDR) -PVRE(PVRSRV_ERROR_INVALID_HEAPINFO) -PVRE(PVRSRV_ERROR_INVALID_PERPROC) -PVRE(PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO) -PVRE(PVRSRV_ERROR_INVALID_MAP_REQUEST) -PVRE(PVRSRV_ERROR_INVALID_UNMAP_REQUEST) -PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP) -PVRE(PVRSRV_ERROR_MAPPING_STILL_IN_USE) -PVRE(PVRSRV_ERROR_EXCEEDED_HW_LIMITS) -PVRE(PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED) -PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA) -PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT) -PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT) -PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT) -PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT) -PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD) -PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD) -PVRE(PVRSRV_ERROR_THREAD_READ_ERROR) -PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER) -PVRE(PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR) -PVRE(PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR) -PVRE(PVRSRV_ERROR_ISR_ALREADY_INSTALLED) -PVRE(PVRSRV_ERROR_ISR_NOT_INSTALLED) -PVRE(PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT) -PVRE(PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO) -PVRE(PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT) -PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES) -PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT) -PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE) -PVRE(PVRSRV_ERROR_INVALID_CCB_COMMAND) -PVRE(PVRSRV_ERROR_KERNEL_CCB_FULL) -PVRE(PVRSRV_ERROR_FLIP_FAILED) -PVRE(PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED) -PVRE(PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE) -PVRE(PVRSRV_ERROR_TIMEOUT_WAITING_FOR_CLIENT_CCB) -PVRE(PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED) -PVRE(PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG) -PVRE(PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG) -PVRE(PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG) -PVRE(PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID) -PVRE(PVRSRV_ERROR_BLIT_SETUP_FAILED) -PVRE(PVRSRV_ERROR_SUBMIT_NEEDED) -PVRE(PVRSRV_ERROR_PDUMP_NOT_AVAILABLE) -PVRE(PVRSRV_ERROR_PDUMP_BUFFER_FULL) -PVRE(PVRSRV_ERROR_PDUMP_BUF_OVERFLOW) -PVRE(PVRSRV_ERROR_PDUMP_NOT_ACTIVE) -PVRE(PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES) -PVRE(PVRSRV_ERROR_MUTEX_DESTROY_FAILED) -PVRE(PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR) -PVRE(PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND) -PVRE(PVRSRV_ERROR_PROCESS_NOT_INITIALISED) -PVRE(PVRSRV_ERROR_PROCESS_NOT_FOUND) -PVRE(PVRSRV_ERROR_SRV_CONNECT_FAILED) -PVRE(PVRSRV_ERROR_SRV_DISCONNECT_FAILED) -PVRE(PVRSRV_ERROR_DEINT_PHASE_FAILED) -PVRE(PVRSRV_ERROR_INIT2_PHASE_FAILED) -PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE) -PVRE(PVRSRV_ERROR_NO_DC_DEVICES_FOUND) -PVRE(PVRSRV_ERROR_DC_DEVICE_INACCESSIBLE) -PVRE(PVRSRV_ERROR_DC_INVALID_MAXDEPTH) -PVRE(PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE) -PVRE(PVRSRV_ERROR_UNABLE_TO_UNREGISTER_DEVICE) -PVRE(PVRSRV_ERROR_NO_DEVICEDATA_FOUND) -PVRE(PVRSRV_ERROR_NO_DEVICENODE_FOUND) -PVRE(PVRSRV_ERROR_NO_CLIENTNODE_FOUND) -PVRE(PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE) -PVRE(PVRSRV_ERROR_UNABLE_TO_INIT_TASK) -PVRE(PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK) -PVRE(PVRSRV_ERROR_UNABLE_TO_KILL_TASK) -PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER) -PVRE(PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER) -PVRE(PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER) -PVRE(PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT) -PVRE(PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE) -PVRE(PVRSRV_ERROR_HANDLE_NOT_ALLOCATED) -PVRE(PVRSRV_ERROR_HANDLE_TYPE_MISMATCH) -PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE) -PVRE(PVRSRV_ERROR_HANDLE_NOT_SHAREABLE) -PVRE(PVRSRV_ERROR_HANDLE_NOT_FOUND) -PVRE(PVRSRV_ERROR_INVALID_SUBHANDLE) -PVRE(PVRSRV_ERROR_HANDLE_BATCH_IN_USE) -PVRE(PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE) -PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE) -PVRE(PVRSRV_ERROR_UNABLE_TO_RETRIEVE_HASH_VALUE) -PVRE(PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE) -PVRE(PVRSRV_ERROR_UNABLE_TO_INSERT_HASH_VALUE) -PVRE(PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED) -PVRE(PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE) -PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP) -PVRE(PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE) -PVRE(PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVAILABLE) -PVRE(PVRSRV_ERROR_INVALID_DEVICEID) -PVRE(PVRSRV_ERROR_DEVICEID_NOT_FOUND) -PVRE(PVRSRV_ERROR_MEMORY_TEST_FAILED) -PVRE(PVRSRV_ERROR_CPUPADDR_TEST_FAILED) -PVRE(PVRSRV_ERROR_COPY_TEST_FAILED) -PVRE(PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED) -PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK) -PVRE(PVRSRV_ERROR_CLOCK_REQUEST_FAILED) -PVRE(PVRSRV_ERROR_DISABLE_CLOCK_FAILURE) -PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE) -PVRE(PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE) -PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK) -PVRE(PVRSRV_ERROR_UNABLE_TO_GET_CLOCK) -PVRE(PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK) -PVRE(PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK) -PVRE(PVRSRV_ERROR_UNKNOWN_SGL_ERROR) -PVRE(PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE) -PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE) -PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED) -PVRE(PVRSRV_ERROR_BAD_SYNC_STATE) -PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE) -PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_MMUCONTEXT_ID) -PVRE(PVRSRV_ERROR_PARAMETER_BUFFER_INVALID_ALIGNMENT) -PVRE(PVRSRV_ERROR_UNABLE_TO_ACQUIRE_CONNECTION) -PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CONNECTION) -PVRE(PVRSRV_ERROR_PHYSHEAP_ID_IN_USE) -PVRE(PVRSRV_ERROR_PHYSHEAP_ID_INVALID) -PVRE(PVRSRV_ERROR_PHYSHEAP_CONFIG) -PVRE(PVRSRV_ERROR_HP_REQUEST_TOO_LONG) -PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM) -PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM_OP) -PVRE(PVRSRV_ERROR_INVALID_SYNC_CONTEXT) -PVRE(PVRSRV_ERROR_BP_NOT_SET) -PVRE(PVRSRV_ERROR_BP_ALREADY_SET) -PVRE(PVRSRV_ERROR_FEATURE_DISABLED) -PVRE(PVRSRV_ERROR_REG_CONFIG_ENABLED) -PVRE(PVRSRV_ERROR_REG_CONFIG_FULL) -PVRE(PVRSRV_ERROR_REG_CONFIG_INVALID_TYPE) -PVRE(PVRSRV_ERROR_MEMORY_ACCESS) -PVRE(PVRSRV_ERROR_NO_SYSTEM_BUFFER) -PVRE(PVRSRV_ERROR_DC_INVALID_CONFIG) -PVRE(PVRSRV_ERROR_DC_INVALID_CROP_RECT) -PVRE(PVRSRV_ERROR_DC_INVALID_DISPLAY_RECT) -PVRE(PVRSRV_ERROR_DC_INVALID_BUFFER_DIMS) -PVRE(PVRSRV_ERROR_DC_INVALID_TRANSFORM) -PVRE(PVRSRV_ERROR_DC_INVALID_SCALE) -PVRE(PVRSRV_ERROR_DC_INVALID_CUSTOM) -PVRE(PVRSRV_ERROR_DC_TOO_MANY_PIPES) -PVRE(PVRSRV_ERROR_DC_INVALID_PLANE_ALPHA) -PVRE(PVRSRV_ERROR_NOT_READY) -PVRE(PVRSRV_ERROR_RESOURCE_UNAVAILABLE) -PVRE(PVRSRV_ERROR_UNSUPPORTED_PIXEL_FORMAT) -PVRE(PVRSRV_ERROR_UNSUPPORTED_MEMORY_LAYOUT) -PVRE(PVRSRV_ERROR_UNSUPPORTED_FB_COMPRESSION_MODE) -PVRE(PVRSRV_ERROR_UNSUPPORTED_DIMS) -PVRE(PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE) -PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_TIMER) -PVRE(PVRSRV_ERROR_NOT_FOUND) -PVRE(PVRSRV_ERROR_ALREADY_OPEN) -PVRE(PVRSRV_ERROR_STREAM_MISUSE) -PVRE(PVRSRV_ERROR_STREAM_FULL) -PVRE(PVRSRV_ERROR_STREAM_READLIMIT_REACHED) -PVRE(PVRSRV_ERROR_STREAM_NOT_ENOUGH_SPACE) -PVRE(PVRSRV_ERROR_PHYSMEM_NOT_ALLOCATED) -PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MAX) -PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MIN) -PVRE(PVRSRV_ERROR_INVALID_PB_CONFIG) -PVRE(PVRSRV_ERROR_META_THREAD0_NOT_ENABLED) -PVRE(PVRSRV_ERROR_NOT_AUTHENTICATED) -PVRE(PVRSRV_ERROR_REQUEST_TDFWMEM_PAGES_FAIL) -PVRE(PVRSRV_ERROR_INIT_TDFWMEM_PAGES_FAIL) -PVRE(PVRSRV_ERROR_REQUEST_TDSECUREBUF_PAGES_FAIL) -PVRE(PVRSRV_ERROR_INIT_TDSECUREBUF_PAGES_FAIL) -PVRE(PVRSRV_ERROR_MUTEX_ALREADY_CREATED) -PVRE(PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED) -PVRE(PVRSRV_ERROR_ALREADY_EXISTS) -PVRE(PVRSRV_ERROR_UNABLE_TO_SEND_PULSE) -PVRE(PVRSRV_ERROR_TASK_FAILED) -PVRE(PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED) -PVRE(PVRSRV_ERROR_INVALID_GPU_ADDR) -PVRE(PVRSRV_ERROR_INVALID_OFFSET) -PVRE(PVRSRV_ERROR_CCCB_STALLED) -PVRE(PVRSRV_ERROR_MIPS_STATUS_UNAVAILABLE) -PVRE(PVRSRV_ERROR_NOT_ENABLED) -PVRE(PVRSRV_ERROR_SYSTEM_LOCAL_MEMORY_INIT_FAIL) -PVRE(PVRSRV_ERROR_FW_IMAGE_MISMATCH) -PVRE(PVRSRV_ERROR_PDUMP_NOT_ALLOWED) -PVRE(PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL) -PVRE(PVRSRV_ERROR_RPM_PBSIZE_ALREADY_MAX) -PVRE(PVRSRV_ERROR_NONZERO_REFCOUNT) -PVRE(PVRSRV_ERROR_SETAFFINITY_FAILED) -PVRE(PVRSRV_ERROR_UNABLE_TO_COMPILE_PDS) -PVRE(PVRSRV_ERROR_INTERNAL_ERROR) -PVRE(PVRSRV_ERROR_BRIDGE_EFAULT) -PVRE(PVRSRV_ERROR_BRIDGE_EINVAL) -PVRE(PVRSRV_ERROR_BRIDGE_ENOMEM) -PVRE(PVRSRV_ERROR_BRIDGE_ERANGE) -PVRE(PVRSRV_ERROR_BRIDGE_EPERM) -PVRE(PVRSRV_ERROR_BRIDGE_ENOTTY) -PVRE(PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED) -PVRE(PVRSRV_ERROR_PROBE_DEFER) -PVRE(PVRSRV_ERROR_INVALID_ALIGNMENT) -PVRE(PVRSRV_ERROR_CLOSE_FAILED) -PVRE(PVRSRV_ERROR_NOT_INITIALISED) -PVRE(PVRSRV_ERROR_CONVERSION_FAILED) -PVRE(PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL) -PVRE(PVRSRV_ERROR_RA_REQUEST_VIRT_ADDR_FAIL) -PVRE(PVRSRV_ERROR_RA_INSERT_RESOURCE_SPAN_FAILED) -PVRE(PVRSRV_ERROR_RA_ATTEMPT_ALLOC_ALIGNED_FAILED) -PVRE(PVRSRV_ERROR_OBJECT_STILL_REFERENCED) -PVRE(PVRSRV_ERROR_BVNC_UNSUPPORTED) -PVRE(PVRSRV_ERROR_INVALID_BVNC_PARAMS) -PVRE(PVRSRV_ERROR_ALIGNMENT_ARRAY_NOT_AVAILABLE) -PVRE(PVRSRV_ERROR_DEVICEMEM_ADDITIONAL_HEAPS_IN_CONTEXT) -PVRE(PVRSRV_ERROR_PID_ALREADY_REGISTERED) -PVRE(PVRSRV_ERROR_PID_NOT_REGISTERED) -PVRE(PVRSRV_ERROR_SIGNAL_FAILED) -PVRE(PVRSRV_ERROR_INVALID_NOTIF_STREAM) -PVRE(PVRSRV_ERROR_INVALID_SPU_MASK) -PVRE(PVRSRV_ERROR_FREELIST_RECONSTRUCTION_FAILED) -PVRE(PVRSRV_ERROR_INVALID_PVZ_CONFIG) -PVRE(PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED) -PVRE(PVRSRV_ERROR_NOT_SW_TIMELINE) -PVRE(PVRSRV_ERROR_SW_TIMELINE_AT_LATEST_POINT) -PVRE(PVRSRV_ERROR_INVALID_PVZ_OSID) -PVRE(PVRSRV_ERROR_PVZ_OSID_IS_OFFLINE) -PVRE(PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG) -PVRE(PVRSRV_ERROR_INTERRUPTED) -PVRE(PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED) -PVRE(PVRSRV_ERROR_PDUMP_INVALID_BLOCKLEN) -PVRE(PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF) -PVRE(PVRSRV_ERROR_MULTIPLE_SECURITY_PDUMPS) -PVRE(PVRSRV_ERROR_BAD_PARAM_SIZE) -PVRE(PVRSRV_ERROR_INVALID_REQUEST) -PVRE(PVRSRV_ERROR_FAILED_TO_ACQUIRE_PAGES) -PVRE(PVRSRV_ERROR_TEST_FAILED) -PVRE(PVRSRV_ERROR_SYNC_PRIM_OP_NOT_SUPPORTED) -PVRE(PVRSRV_ERROR_FAILED_TO_GET_VIRT_ADDR) -PVRE(PVRSRV_ERROR_UNABLE_TO_FREE_RESOURCE) -PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_SEMAPHORE) -PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_SEMAPHORE) -PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_SEMAPHORE) -PVRE(PVRSRV_ERROR_TOO_MANY_SYNCS) -PVRE(PVRSRV_ERROR_ION_NO_CLIENT) -PVRE(PVRSRV_ERROR_ION_FAILED_TO_ALLOC) -PVRE(PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE) -PVRE(PVRSRV_ERROR_REFCOUNT_OVERFLOW) -PVRE(PVRSRV_ERROR_OUT_OF_RANGE) -PVRE(PVRSRV_ERROR_PMR_TOO_LARGE) diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_firmware_boot.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_firmware_boot.h deleted file mode 100644 index 14a196d2767cb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_firmware_boot.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_FIRMWARE_BOOT_H -#define PVRSRV_FIRMWARE_BOOT_H - -#include "img_types.h" -#include "rgx_fwif_shared.h" - -#define TD_MAX_NUM_MIPS_PAGETABLE_PAGES (4U) - -typedef union _PVRSRV_FW_BOOT_PARAMS_ -{ - struct - { - IMG_DEV_VIRTADDR sFWCodeDevVAddr; - IMG_DEV_VIRTADDR sFWDataDevVAddr; - IMG_DEV_VIRTADDR sFWCorememCodeDevVAddr; - RGXFWIF_DEV_VIRTADDR sFWCorememCodeFWAddr; - IMG_DEVMEM_SIZE_T uiFWCorememCodeSize; - IMG_DEV_VIRTADDR sFWCorememDataDevVAddr; - RGXFWIF_DEV_VIRTADDR sFWCorememDataFWAddr; - IMG_UINT32 ui32NumThreads; - } sMeta; - - struct - { - IMG_DEV_PHYADDR sGPURegAddr; - IMG_DEV_PHYADDR asFWPageTableAddr[TD_MAX_NUM_MIPS_PAGETABLE_PAGES]; - IMG_DEV_PHYADDR sFWStackAddr; - IMG_UINT32 ui32FWPageTableLog2PageSize; - IMG_UINT32 ui32FWPageTableNumPages; - } sMips; - - struct - { - IMG_DEV_VIRTADDR sFWCorememCodeDevVAddr; - RGXFWIF_DEV_VIRTADDR sFWCorememCodeFWAddr; - IMG_DEVMEM_SIZE_T uiFWCorememCodeSize; - - IMG_DEV_VIRTADDR sFWCorememDataDevVAddr; - RGXFWIF_DEV_VIRTADDR sFWCorememDataFWAddr; - IMG_DEVMEM_SIZE_T uiFWCorememDataSize; - } sRISCV; - -} PVRSRV_FW_BOOT_PARAMS; - - -#endif /* PVRSRV_FIRMWARE_BOOT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memalloc_physheap.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memalloc_physheap.h deleted file mode 100644 index 1072ba857c9aa..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memalloc_physheap.h +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************/ /*! -@File pvrsrv_memalloc_physheap.h -@Title Services Phys Heap types -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Used in creating and allocating from Physical Heaps. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_MEMALLOC_PHYSHEAP_H -#define PVRSRV_MEMALLOC_PHYSHEAP_H - -#include "img_defs.h" - -/* - * These IDs are replicated in the Device Memory allocation flags to allow - * allocations to be made in terms of their locality/use to ensure the correct - * physical heap is accessed for the given system/platform configuration. - * A system Phys Heap Config is linked to one or more Phys Heaps. When a heap - * is not present in the system configuration the allocation will fallback to - * the default GPU_LOCAL physical heap which all systems must define. - * See PVRSRV_MEMALLOCFLAGS_*_MAPPABLE_MASK. - * - * NOTE: Enum order important, table in physheap.c must change if order changed. - */ -typedef IMG_UINT32 PVRSRV_PHYS_HEAP; -/* Services client accessible heaps */ -#define PVRSRV_PHYS_HEAP_DEFAULT 0U /* default phys heap for device memory allocations */ -#define PVRSRV_PHYS_HEAP_GPU_LOCAL 1U /* used for buffers with more GPU access than CPU */ -#define PVRSRV_PHYS_HEAP_CPU_LOCAL 2U /* used for buffers with more CPU access than GPU */ -#define PVRSRV_PHYS_HEAP_GPU_PRIVATE 3U /* used for buffers that only required GPU read/write access, not visible to the CPU. */ - -#define HEAPSTR(x) #x -static inline const IMG_CHAR *PVRSRVGetClientPhysHeapName(PVRSRV_PHYS_HEAP ePhysHeapID) -{ - switch (ePhysHeapID) - { - case PVRSRV_PHYS_HEAP_DEFAULT: - return HEAPSTR(PVRSRV_PHYS_HEAP_DEFAULT); - case PVRSRV_PHYS_HEAP_GPU_LOCAL: - return HEAPSTR(PVRSRV_PHYS_HEAP_GPU_LOCAL); - case PVRSRV_PHYS_HEAP_CPU_LOCAL: - return HEAPSTR(PVRSRV_PHYS_HEAP_CPU_LOCAL); - case PVRSRV_PHYS_HEAP_GPU_PRIVATE: - return HEAPSTR(PVRSRV_PHYS_HEAP_GPU_PRIVATE); - default: - return "Unknown Heap"; - } -} - -/* Services internal heaps */ -#define PVRSRV_PHYS_HEAP_FW_MAIN 4U /* runtime data, e.g. CCBs, sync objects */ -#define PVRSRV_PHYS_HEAP_EXTERNAL 5U /* used by some PMR import/export factories where the physical memory heap is not managed by the pvrsrv driver */ -#define PVRSRV_PHYS_HEAP_GPU_COHERENT 6U /* used for a cache coherent region */ -#define PVRSRV_PHYS_HEAP_GPU_SECURE 7U /* used by security validation */ -#define PVRSRV_PHYS_HEAP_FW_CONFIG 8U /* subheap of FW_MAIN, configuration data for FW init */ -#define PVRSRV_PHYS_HEAP_FW_CODE 9U /* used by security validation or dedicated fw */ -#define PVRSRV_PHYS_HEAP_FW_PRIV_DATA 10U /* internal FW data (like the stack, FW control data structures, etc.) */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP0 11U /* Host OS premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP1 12U /* Guest OS 1 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP2 13U /* Guest OS 2 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP3 14U /* Guest OS 3 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP4 15U /* Guest OS 4 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP5 16U /* Guest OS 5 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP6 17U /* Guest OS 6 premap fw heap */ -#define PVRSRV_PHYS_HEAP_FW_PREMAP7 18U /* Guest OS 7 premap fw heap */ -#define PVRSRV_PHYS_HEAP_LAST 19U - - -static_assert(PVRSRV_PHYS_HEAP_LAST <= (0x1FU + 1U), "Ensure enum fits in memalloc flags bitfield."); - -/*! Type conveys the class of physical heap to instantiate within Services - * for the physical pool of memory. */ -typedef enum _PHYS_HEAP_TYPE_ -{ - PHYS_HEAP_TYPE_UNKNOWN = 0, /*!< Not a valid value for any config */ - PHYS_HEAP_TYPE_UMA, /*!< Heap represents OS managed physical memory heap - i.e. system RAM. Unified Memory Architecture - physmem_osmem PMR factory */ - PHYS_HEAP_TYPE_LMA, /*!< Heap represents physical memory pool managed by - Services i.e. carve out from system RAM or local - card memory. Local Memory Architecture - physmem_lma PMR factory */ -#if defined(__KERNEL__) - PHYS_HEAP_TYPE_DMA, /*!< Heap represents a physical memory pool managed by - Services, alias of LMA and is only used on - VZ non-native system configurations for - a heap used for PHYS_HEAP_USAGE_FW_MAIN tagged - buffers */ -#if defined(SUPPORT_WRAP_EXTMEMOBJECT) - PHYS_HEAP_TYPE_WRAP, /*!< Heap used to group UM buffers given - to Services. Integrity OS port only. */ -#endif -#endif -} PHYS_HEAP_TYPE; - -/* Defines used when interpreting the ui32PhysHeapFlags in PHYS_HEAP_MEM_STATS - 0x000000000000dttt - d = is this the default heap? (1=yes, 0=no) - ttt = heap type (000 = PHYS_HEAP_TYPE_UNKNOWN, - 001 = PHYS_HEAP_TYPE_UMA, - 010 = PHYS_HEAP_TYPE_LMA, - 011 = PHYS_HEAP_TYPE_DMA) -*/ -#define PVRSRV_PHYS_HEAP_FLAGS_TYPE_MASK (0x7U << 0) -#define PVRSRV_PHYS_HEAP_FLAGS_IS_DEFAULT (0x1U << 7) - -typedef struct PHYS_HEAP_MEM_STATS_TAG -{ - IMG_UINT64 ui64TotalSize; - IMG_UINT64 ui64FreeSize; - IMG_UINT32 ui32PhysHeapFlags; -}PHYS_HEAP_MEM_STATS, *PHYS_HEAP_MEM_STATS_PTR; - -typedef struct PHYS_HEAP_MEM_STATS_PKD_TAG -{ - IMG_UINT64 ui64TotalSize; - IMG_UINT64 ui64FreeSize; - IMG_UINT32 ui32PhysHeapFlags; - IMG_UINT32 ui32Dummy; -}PHYS_HEAP_MEM_STATS_PKD, *PHYS_HEAP_MEM_STATS_PKD_PTR; - -static inline const IMG_CHAR *PVRSRVGetClientPhysHeapTypeName(PHYS_HEAP_TYPE ePhysHeapType) -{ - switch (ePhysHeapType) - { - case PHYS_HEAP_TYPE_UMA: - return HEAPSTR(PHYS_HEAP_TYPE_UMA); - case PHYS_HEAP_TYPE_LMA: - return HEAPSTR(PHYS_HEAP_TYPE_LMA); - default: - return "Unknown Heap Type"; - } -} -#undef HEAPSTR - -#endif /* PVRSRV_MEMALLOC_PHYSHEAP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags.h deleted file mode 100644 index 3b87dbf498d5e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags.h +++ /dev/null @@ -1,969 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This file defines flags used on memory allocations and mappings - These flags are relevant throughout the memory management - software stack and are specified by users of services and - understood by all levels of the memory management in both - client and server. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_MEMALLOCFLAGS_H -#define PVRSRV_MEMALLOCFLAGS_H - -#include "img_types.h" -#include "pvrsrv_memalloc_physheap.h" - -/*! - Type for specifying memory allocation flags. - */ - -typedef IMG_UINT64 PVRSRV_MEMALLOCFLAGS_T; -#define PVRSRV_MEMALLOCFLAGS_FMTSPEC IMG_UINT64_FMTSPECx - -#if defined(__KERNEL__) -#include "pvrsrv_memallocflags_internal.h" -#endif /* __KERNEL__ */ - -/* - * --- MAPPING FLAGS 0..14 (15-bits) --- - * | 0-3 | 4-7 | 8-10 | 11-13 | 14 | - * | GPU-RW | CPU-RW | GPU-Caching | CPU-Caching | KM-Mappable | - * - * --- MISC FLAGS 15..23 (9-bits) --- - * | 15 | 17 | 18 | 19 | 20 | - * | Defer | SVM | Sparse-Dummy-Page | CPU-Cache-Clean | Sparse-Zero-Page | - * - * --- DEV CONTROL FLAGS 26..27 (2-bits) --- - * | 26-27 | - * | Device-Flags | - * - * --- MISC FLAGS 28..31 (4-bits) --- - * | 28 | 29 | 30 | 31 | - * | No-Cache-Align | Poison-On-Free | P.-On-Alloc | Zero-On-Alloc | - * - * --- VALIDATION FLAGS --- - * | 35 | - * | Shared-buffer | - * - * --- PHYS HEAP HINTS --- - * | 59-63 | - * | PhysHeap Hints | - * - */ - -/* - * ********************************************************** - * * * - * * MAPPING FLAGS * - * * * - * ********************************************************** - */ - -/*! - * This flag affects the device MMU protection flags, and specifies - * that the memory may be read by the GPU. - * - * Typically all device memory allocations would specify this flag. - * - * At the moment, memory allocations without this flag are not supported - * - * This flag will live with the PMR, thus subsequent mappings would - * honour this flag. - * - * This is a dual purpose flag. It specifies that memory is permitted - * to be read by the GPU, and also requests that the allocation is - * mapped into the GPU as a readable mapping - * - * To be clear: - * - When used as an argument on PMR creation; it specifies - * that GPU readable mappings will be _permitted_ - * - When used as an argument to a "map" function: it specifies - * that a GPU readable mapping is _desired_ - * - When used as an argument to "AllocDeviceMem": it specifies - * that the PMR will be created with permission to be mapped - * with a GPU readable mapping, _and_ that this PMR will be - * mapped with a GPU readable mapping. - * This distinction becomes important when (a) we export allocations; - * and (b) when we separate the creation of the PMR from the mapping. - */ -#define PVRSRV_MEMALLOCFLAG_GPU_READABLE (1ULL<<0) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_READABLE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_READABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_READABLE) != 0U) - -/*! - * This flag affects the device MMU protection flags, and specifies - * that the memory may be written by the GPU - * - * Using this flag on an allocation signifies that the allocation is - * intended to be written by the GPU. - * - * Omitting this flag causes a read-only mapping. - * - * This flag will live with the PMR, thus subsequent mappings would - * honour this flag. - * - * This is a dual purpose flag. It specifies that memory is permitted - * to be written by the GPU, and also requests that the allocation is - * mapped into the GPU as a writable mapping (see note above about - * permission vs. mapping mode, and why this flag causes permissions - * to be inferred from mapping mode on first allocation) - * - * N.B. This flag has no relevance to the CPU's MMU mapping, if any, - * and would therefore not enforce read-only mapping on CPU. - */ -#define PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE (1ULL<<1) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_WRITEABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE) != 0U) - -/*! - The flag indicates whether an allocation can be mapped as GPU readable in another GPU memory context. - */ -#define PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED (1ULL<<2) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_READ_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED) != 0U) - -/*! - The flag indicates whether an allocation can be mapped as GPU writable in another GPU memory context. - */ -#define PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED (1ULL<<3) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_WRITE_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED) != 0U) - -/*! - The flag indicates that an allocation is mapped as readable to the CPU. - */ -#define PVRSRV_MEMALLOCFLAG_CPU_READABLE (1ULL<<4) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_READABLE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_READABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_READABLE) != 0U) - -/*! - The flag indicates that an allocation is mapped as writable to the CPU. - */ -#define PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE (1ULL<<5) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_WRITEABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) != 0U) - -/*! - The flag indicates whether an allocation can be mapped as CPU readable in another CPU memory context. - */ -#define PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED (1ULL<<6) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_READ_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED) != 0U) - -/*! - The flag indicates whether an allocation can be mapped as CPU writable in another CPU memory context. - */ -#define PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED (1ULL<<7) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_WRITE_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED) != 0U) - - -/* - * ********************************************************** - * * * - * * CACHE CONTROL FLAGS * - * * * - * ********************************************************** - */ - -/* - GPU domain - ========== - - The following defines are used to control the GPU cache bit field. - The defines are mutually exclusive. - - A helper macro, PVRSRV_GPU_CACHE_MODE, is provided to obtain just the GPU - cache bit field from the flags. This should be used whenever the GPU cache - mode needs to be determined. -*/ - -/*! - GPU domain. Flag indicating uncached memory. This means that any writes to memory - allocated with this flag are written straight to memory and thus are - coherent for any device in the system. -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_UNCACHED (1ULL<<8) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_UNCACHED mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_UNCACHED(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_UNCACHED) - -/*! - GPU domain. Use write combiner (if supported) to combine sequential writes - together to reduce memory access by doing burst writes. -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC (0ULL<<8) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_WRITE_COMBINE(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC) - -/*! - GPU domain. This flag affects the GPU MMU protection flags. - The allocation will be cached. - Services will try to set the coherent bit in the GPU MMU tables so the - GPU cache is snooping the CPU cache. If coherency is not supported the - caller is responsible to ensure the caches are up to date. -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT (2ULL<<8) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) - -/*! - GPU domain. Request cached memory, but not coherent (i.e. no cache - snooping). Services will flush the GPU internal caches after every GPU - task so no cache maintenance requests from the users are necessary. - - Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future - expansion. -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT (3ULL<<8) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT) - -/*! - GPU domain. This flag is for internal use only and is used to indicate - that the underlying allocation should be cached on the GPU after all - the snooping and coherent checks have been done -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_CACHED (7ULL<<8) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHED mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_GPU_CACHED(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHED) - -/*! - GPU domain. GPU cache mode mask. -*/ -#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK (7ULL<<8) - -/*! - @Description A helper macro to obtain just the GPU cache bit field from the flags. - This should be used whenever the GPU cache mode needs to be determined. - @Input uiFlags Allocation flags. - @Return Value of the GPU cache bit field. - */ -#define PVRSRV_GPU_CACHE_MODE(uiFlags) ((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK) - - -/* - CPU domain - ========== - - The following defines are used to control the CPU cache bit field. - The defines are mutually exclusive. - - A helper macro, PVRSRV_CPU_CACHE_MODE, is provided to obtain just the CPU - cache bit field from the flags. This should be used whenever the CPU cache - mode needs to be determined. -*/ - -/*! - CPU domain. Use write combiner (if supported) to combine sequential writes - together to reduce memory access by doing burst writes. -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC (0ULL<<11) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC) - -/*! - CPU domain. This flag affects the CPU MMU protection flags. - The allocation will be cached. - Services will try to set the coherent bit in the CPU MMU tables so the - CPU cache is snooping the GPU cache. If coherency is not supported the - caller is responsible to ensure the caches are up to date. -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT (2ULL<<11) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) - -/*! - CPU domain. Request cached memory, but not coherent (i.e. no cache - snooping). This means that if the allocation needs to transition from - one device to another services has to be informed so it can - flush/invalidate the appropriate caches. - - Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future - expansion. -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT (3ULL<<11) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT) - -/*! - CPU domain. This flag is for internal use only and is used to indicate - that the underlying allocation should be cached on the CPU - after all the snooping and coherent checks have been done -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_CACHED (7ULL<<11) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHED mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_CACHED(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED) - -/*! - CPU domain. CPU cache mode mask -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK (7ULL<<11) - -/*! - @Description A helper macro to obtain just the CPU cache bit field from the flags. - This should be used whenever the CPU cache mode needs to be determined. - @Input uiFlags Allocation flags. - @Return Value of the CPU cache bit field. - */ -#define PVRSRV_CPU_CACHE_MODE(uiFlags) ((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK) - -/* Helper flags for usual cases */ - -/*! - * Memory will be write-combined on CPU and GPU - */ -#define PVRSRV_MEMALLOCFLAG_UNCACHED_WC (PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_UNCACHED_WC mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_WRITE_COMBINE(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_UNCACHED_WC) - -/*! - * Memory will be cached. - * Services will try to set the correct flags in the MMU tables. - * In case there is no coherency support the caller has to ensure caches are up to date */ -#define PVRSRV_MEMALLOCFLAG_CACHE_COHERENT (PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CACHE_COHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CACHE_COHERENT(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CACHE_COHERENT) - -/*! - * Memory will be cache-incoherent on CPU and GPU - */ -#define PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT (PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CACHE_INCOHERENT(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT) - -/*! - Cache mode mask -*/ -#define PVRSRV_CACHE_MODE(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) | PVRSRV_CPU_CACHE_MODE(uiFlags)) - - -/*! - CPU MMU Flags mask -- intended for use internal to services only - */ -#define PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK (PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK) - -/*! - MMU Flags mask -- intended for use internal to services only - used for - partitioning the flags bits and determining which flags to pass down to - mmu_common.c - */ -#define PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK (PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK) - -/*! - Indicates that the PMR created due to this allocation will support - in-kernel CPU mappings. Only privileged processes may use this flag as - it may cause wastage of precious kernel virtual memory on some platforms. - */ -#define PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE (1ULL<<14) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_KERNEL_CPU_MAPPABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE) != 0U) - - - -/* - * - * ********************************************************** - * * * - * * ALLOC MEMORY FLAGS * - * * * - * ********************************************************** - * - * (Bits 15) - * - */ -#define PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC (1ULL<<15) -#define PVRSRV_CHECK_ON_DEMAND(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) != 0U) - -/*! - Indicates that the allocation will be accessed by the CPU and GPU using - the same virtual address, i.e. for all SVM allocs, - IMG_CPU_VIRTADDR == IMG_DEV_VIRTADDR - */ -#define PVRSRV_MEMALLOCFLAG_SVM_ALLOC (1ULL<<17) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_SVM_ALLOC flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_SVM_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_SVM_ALLOC) != 0U) - -/*! - Indicates the particular memory that's being allocated is sparse and the - sparse regions should not be backed by dummy page - */ -#define PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING (1ULL << 18) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING) == 0U) - -/*! - Used to force Services to carry out at least one CPU cache invalidate on a - CPU cached buffer during allocation of the memory. Applicable to incoherent - systems, it must be used for buffers which are CPU cached and which will not - be 100% written to by the CPU before the GPU accesses it. For performance - reasons, avoid usage if the whole buffer that is allocated is written to by - the CPU anyway before the next GPU kick, or if the system is coherent. - */ -#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN (1ULL<<19) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN) != 0U) - -/*! PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING - - Indicates the particular memory that's being allocated is sparse and the - sparse regions should be backed by zero page. This is different with - zero on alloc flag such that only physically unbacked pages are backed - by zero page at the time of mapping. - The zero backed page is always with read only attribute irrespective of its - original attributes. - */ -#define PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING (1ULL << 20) -#define PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiFlags) (((uiFlags) & \ - PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING) == PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING) - -/*! - @Description Macro extracting the OS id from a variable containing memalloc flags - @Input uiFlags Allocation flags - @Return returns the value of the FW_ALLOC_OSID bitfield - */ -#define PVRSRV_FW_RAW_ALLOC_OSID(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_MASK) \ - >> PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_SHIFT) - -/*! - @Description Macro converting an OS id value into a memalloc bitfield - @Input uiFlags OS id - @Return returns a shifted bitfield with the OS id value - */ -#define PVRSRV_MEMALLOCFLAG_FW_RAW_ALLOC_OSID(osid) (((osid) << PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_SHIFT) \ - & PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_MASK) \ - -/* - * - * ********************************************************** - * * * - * * MEMORY ZEROING AND POISONING FLAGS * - * * * - * ********************************************************** - * - * Zero / Poison, on alloc/free - * - * We think the following usecases are required: - * - * don't poison or zero on alloc or free - * (normal operation, also most efficient) - * poison on alloc - * (for helping to highlight bugs) - * poison on alloc and free - * (for helping to highlight bugs) - * zero on alloc - * (avoid highlighting security issues in other uses of memory) - * zero on alloc and poison on free - * (avoid highlighting security issues in other uses of memory, while - * helping to highlight a subset of bugs e.g. memory freed prematurely) - * - * Since there are more than 4, we can't encode this in just two bits, - * so we might as well have a separate flag for each of the three - * actions. - */ - -/*! - Ensures that the memory allocated is initialised with zeroes. - */ -#define PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC (1ULL<<31) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) != 0U) - -/*! - Scribbles over the allocated memory with a poison value - - Not compatible with ZERO_ON_ALLOC - - Poisoning is very deliberately _not_ reflected in PDump as we want - a simulation to cry loudly if the initialised data propagates to a - result. - */ -#define PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC (1ULL<<30) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC) != 0U) - -#if defined(DEBUG) || defined(SERVICES_SC) -/*! - Causes memory to be trashed when freed, used when debugging only, not to be used - as a security measure. - */ -#define PVRSRV_MEMALLOCFLAG_POISON_ON_FREE (1ULL<<29) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_POISON_ON_FREE flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_POISON_ON_FREE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE) != 0U) -#endif /* DEBUG */ - -/*! - Avoid address alignment to a CPU or GPU cache line size. - */ -#define PVRSRV_MEMALLOCFLAG_NO_CACHE_LINE_ALIGN (1ULL<<28) - -/*! - @Description Macro checking whether the PVRSRV_CHECK_NO_CACHE_LINE_ALIGN flag is set. - @Input uiFlags Allocation flags. - @Return True if the flag is set, false otherwise - */ -#define PVRSRV_CHECK_NO_CACHE_LINE_ALIGN(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_NO_CACHE_LINE_ALIGN) != 0U) - - -/* - * - * ********************************************************** - * * * - * * Device specific MMU flags * - * * * - * ********************************************************** - * - * (Bits 26 to 27) - * - * Some services controlled devices have device specific control bits in - * their page table entries, we need to allow these flags to be passed down - * the memory management layers so the user can control these bits. - * For example, RGX device has the file rgx_memallocflags.h - */ - -/*! - * Offset of device specific MMU flags. - */ -#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET 26 - -/*! - * Mask for retrieving device specific MMU flags. - */ -#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK (0x3ULL << PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET) - -/*! - @Description Helper macro for setting device specific MMU flags. - @Input n Flag index. - @Return Flag vector with the specified bit set. - */ -#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(n) \ - (((PVRSRV_MEMALLOCFLAGS_T)(n) << PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET) & \ - PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK) - -/* - * - * ********************************************************** - * * * - * * Secure validation flags * - * * * - * ********************************************************** - * - * (Bit 35) - * - */ - -/*! - PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER - */ - -#define PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER (1ULL<<35) -#define PVRSRV_CHECK_SHARED_BUFFER(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER) != 0U) - -/* - * - * ********************************************************** - * * * - * * Phys Heap Hints * - * * * - * ********************************************************** - * - * (Bits 59 to 63) - * - */ - -/*! - * Value of enum PVRSRV_PHYS_HEAP stored in memalloc flags. If not set - * i.e. PVRSRV_PHYS_HEAP_DEFAULT (value 0) used, the system layer defined default physical heap is used. - */ -#define PVRSRV_PHYS_HEAP_HINT_SHIFT (59) -#define PVRSRV_PHYS_HEAP_HINT_MASK (0x1FULL << PVRSRV_PHYS_HEAP_HINT_SHIFT) - - -/*! - @Description Macro extracting the Phys Heap hint from memalloc flag value. - @Input uiFlags Allocation flags - @Return returns the value of the PHYS_HEAP_HINT bitfield - */ -#define PVRSRV_GET_PHYS_HEAP_HINT(uiFlags) (((uiFlags) & PVRSRV_PHYS_HEAP_HINT_MASK) \ - >> PVRSRV_PHYS_HEAP_HINT_SHIFT) - -/*! - @Description Macro converting a Phys Heap value into a memalloc bitfield - @Input uiFlags Device Phys Heap - @Return returns a shifted bitfield with the Device Phys Heap value - */ -#define PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(PhysHeap) ((((PVRSRV_MEMALLOCFLAGS_T)PVRSRV_PHYS_HEAP_ ## PhysHeap) << \ - PVRSRV_PHYS_HEAP_HINT_SHIFT) \ - & PVRSRV_PHYS_HEAP_HINT_MASK) -/*! - @Description Macro to replace an existing phys heap hint value in flags. - @Input PhysHeap Phys Heap Macro - @Input uiFlags Allocation flags - @Return N/A - */ -#define PVRSRV_SET_PHYS_HEAP_HINT(PhysHeap, uiFlags) (uiFlags) = ((uiFlags) & ~PVRSRV_PHYS_HEAP_HINT_MASK) | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(PhysHeap) - -/*! - @Description Macro to replace an existing phys heap hint value using Phys Heap value. - @Input PhysHeap Phys Heap Value - @Input uiFlags Allocation flags - @Return N/A - */ -#define PVRSRV_CHANGE_PHYS_HEAP_HINT(Physheap, uiFlags) (uiFlags) = ((uiFlags) & ~PVRSRV_PHYS_HEAP_HINT_MASK) | \ - (((PVRSRV_MEMALLOCFLAGS_T)(Physheap) << \ - PVRSRV_PHYS_HEAP_HINT_SHIFT) \ - & PVRSRV_PHYS_HEAP_HINT_MASK) - -/*! - @Description Macros checking if a Phys Heap hint is set. - @Input uiFlags Allocation flags. - @Return True if the hint is set, false otherwise - */ -#define PVRSRV_CHECK_PHYS_HEAP(PhysHeap, uiFlags) (PVRSRV_PHYS_HEAP_ ## PhysHeap == PVRSRV_GET_PHYS_HEAP_HINT(uiFlags)) - -#define PVRSRV_CHECK_FW_MAIN(uiFlags) (PVRSRV_CHECK_PHYS_HEAP(FW_MAIN, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_CONFIG, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_CODE, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PRIV_DATA, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP0, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP1, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP2, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP3, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP4, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP5, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP6, uiFlags) || \ - PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP7, uiFlags)) - -/*! - * Secure buffer mask -- Flags in the mask are allowed for secure buffers - * because they are not related to CPU mappings. - */ -#define PVRSRV_MEMALLOCFLAGS_SECBUFMASK ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \ - PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \ - PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED) - -/*! - * Trusted device mask -- Flags in the mask are allowed for trusted device - * because the driver cannot access the memory - */ -#if defined(DEBUG) || defined(SERVICES_SC) -#define PVRSRV_MEMALLOCFLAGS_TDFWMASK ~(PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \ - PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING) -#else -#define PVRSRV_MEMALLOCFLAGS_TDFWMASK ~(PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING) -#endif - -/*! - PMR flags mask -- for internal services use only. This is the set of flags - that will be passed down and stored with the PMR, this also includes the - MMU flags which the PMR has to pass down to mm_common.c at PMRMap time. -*/ -#if defined(DEBUG) || defined(SERVICES_SC) -#define PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \ - PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING | \ - PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING | \ - PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER | \ - PVRSRV_PHYS_HEAP_HINT_MASK) -#else -#define PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING | \ - PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING | \ - PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER | \ - PVRSRV_PHYS_HEAP_HINT_MASK) -#endif - -/*! - * CPU mappable mask -- Any flag set in the mask requires memory to be CPU mappable - */ -#define PVRSRV_MEMALLOCFLAGS_CPU_MAPPABLE_MASK (PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE) -/*! - RA differentiation mask - - for use internal to services - - this is the set of flags bits that are able to determine whether a pair of - allocations are permitted to live in the same page table. Allocations - whose flags differ in any of these places would be allocated from separate - RA Imports and therefore would never coexist in the same page. - Special cases are zeroing and poisoning of memory. The caller is responsible - to set the sub-allocations to the value he wants it to be. To differentiate - between zeroed and poisoned RA Imports does not make sense because the - memory might be reused. - -*/ -#if defined(DEBUG) || defined(SERVICES_SC) -#define PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK (PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK \ - & \ - ~(PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_FREE)) -#else -#define PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK (PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK \ - & \ - ~(PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)) -#endif -/*! - Flags that affect _allocation_ -*/ -#define PVRSRV_MEMALLOCFLAGS_PERALLOCFLAGSMASK (0xFFFFFFFFU) - -/*! - Flags that affect _mapping_ -*/ -#define PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \ - PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \ - PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING | \ - PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING) - -#if ((~(PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK) & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK) != 0U) -#error PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK is not a subset of PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK -#endif - - -/*! - Flags that affect _physical allocations_ in the DevMemX API - */ -#if defined(DEBUG) || defined(SERVICES_SC) -#define PVRSRV_MEMALLOCFLAGS_DEVMEMX_PHYSICAL_MASK (PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK | \ - PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \ - PVRSRV_PHYS_HEAP_HINT_MASK) -#else -#define PVRSRV_MEMALLOCFLAGS_DEVMEMX_PHYSICAL_MASK (PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK | \ - PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \ - PVRSRV_PHYS_HEAP_HINT_MASK) -#endif - -/*! - Flags that affect _virtual allocations_ in the DevMemX API - */ -#define PVRSRV_MEMALLOCFLAGS_DEVMEMX_VIRTUAL_MASK (PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \ - PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED) - -#endif /* PVRSRV_MEMALLOCFLAGS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags_internal.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags_internal.h deleted file mode 100644 index 4fee3d49b9278..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_memallocflags_internal.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device Memory Management allocation flags for internal Services - use only -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This file defines flags used on memory allocations and mappings - These flags are relevant throughout the memory management - software stack and are specified by users of services and - understood by all levels of the memory management in the server - and in special cases in the client. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_MEMALLOCFLAGS_INTERNAL_H -#define PVRSRV_MEMALLOCFLAGS_INTERNAL_H - -/*! - CPU domain. Request uncached memory. This means that any writes to memory - allocated with this flag are written straight to memory and thus are - coherent for any device in the system. -*/ -#define PVRSRV_MEMALLOCFLAG_CPU_UNCACHED (1ULL<<11) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_UNCACHED mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_CPU_UNCACHED(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED) - -/*! - * Memory will be uncached on CPU and GPU - */ -#define PVRSRV_MEMALLOCFLAG_UNCACHED (PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED) - -/*! - @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_UNCACHED mode is set. - @Input uiFlags Allocation flags. - @Return True if the mode is set, false otherwise - */ -#define PVRSRV_CHECK_UNCACHED(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_UNCACHED) - -#endif /* PVRSRV_MEMALLOCFLAGS_INTERNAL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.c b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.c deleted file mode 100644 index d62a062a944c0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.c +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Services pool implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides a generic pool implementation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv.h" -#include "lock.h" -#include "dllist.h" -#include "allocmem.h" - -struct _PVRSRV_POOL_ -{ - POS_LOCK hLock; - /* total max number of permitted entries in the pool */ - IMG_UINT uiMaxEntries; - /* currently number of pool entries created. these may be in the pool - * or in-use - */ - IMG_UINT uiNumBusy; - /* number of not-in-use entries currently free in the pool */ - IMG_UINT uiNumFree; - - DLLIST_NODE sFreeList; - - const IMG_CHAR *pszName; - - PVRSRV_POOL_ALLOC_FUNC *pfnAlloc; - PVRSRV_POOL_FREE_FUNC *pfnFree; - void *pvPrivData; -}; - -typedef struct _PVRSRV_POOL_ENTRY_ -{ - DLLIST_NODE sNode; - void *pvData; -} PVRSRV_POOL_ENTRY; - -PVRSRV_ERROR PVRSRVPoolCreate(PVRSRV_POOL_ALLOC_FUNC *pfnAlloc, - PVRSRV_POOL_FREE_FUNC *pfnFree, - IMG_UINT32 ui32MaxEntries, - const IMG_CHAR *pszName, - void *pvPrivData, - PVRSRV_POOL **ppsPool) -{ - PVRSRV_POOL *psPool; - PVRSRV_ERROR eError; - - psPool = OSAllocMem(sizeof(PVRSRV_POOL)); - PVR_GOTO_IF_NOMEM(psPool, eError, err_alloc); - - eError = OSLockCreate(&psPool->hLock); - - PVR_GOTO_IF_ERROR(eError, err_lock_create); - - psPool->uiMaxEntries = ui32MaxEntries; - psPool->uiNumBusy = 0; - psPool->uiNumFree = 0; - psPool->pfnAlloc = pfnAlloc; - psPool->pfnFree = pfnFree; - psPool->pvPrivData = pvPrivData; - psPool->pszName = pszName; - - dllist_init(&psPool->sFreeList); - - *ppsPool = psPool; - - return PVRSRV_OK; - -err_lock_create: - OSFreeMem(psPool); -err_alloc: - return eError; -} - -static PVRSRV_ERROR _DestroyPoolEntry(PVRSRV_POOL *psPool, - PVRSRV_POOL_ENTRY *psEntry) -{ - psPool->pfnFree(psPool->pvPrivData, psEntry->pvData); - OSFreeMem(psEntry); - - return PVRSRV_OK; -} - -void PVRSRVPoolDestroy(PVRSRV_POOL *psPool) -{ - if (psPool->uiNumBusy != 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to destroy pool %s " - "with %u entries still in use", - __func__, - psPool->pszName, - psPool->uiNumBusy)); - return; - } - - OSLockDestroy(psPool->hLock); - - if (psPool->uiNumFree) - { - PVRSRV_POOL_ENTRY *psEntry; - DLLIST_NODE *psChosenNode; - - psChosenNode = dllist_get_next_node(&psPool->sFreeList); - - while (psChosenNode) - { - dllist_remove_node(psChosenNode); - - psEntry = IMG_CONTAINER_OF(psChosenNode, PVRSRV_POOL_ENTRY, sNode); - _DestroyPoolEntry(psPool, psEntry); - - psPool->uiNumFree--; - - psChosenNode = dllist_get_next_node(&psPool->sFreeList); - } - - PVR_ASSERT(psPool->uiNumFree == 0); - } - - OSFreeMem(psPool); -} - -static PVRSRV_ERROR _CreateNewPoolEntry(PVRSRV_POOL *psPool, - PVRSRV_POOL_ENTRY **ppsEntry) -{ - PVRSRV_POOL_ENTRY *psNewEntry; - PVRSRV_ERROR eError; - - psNewEntry = OSAllocMem(sizeof(PVRSRV_POOL_ENTRY)); - PVR_GOTO_IF_NOMEM(psNewEntry, eError, err_allocmem); - - dllist_init(&psNewEntry->sNode); - - eError = psPool->pfnAlloc(psPool->pvPrivData, &psNewEntry->pvData); - - PVR_GOTO_IF_ERROR(eError, err_pfn_alloc); - - *ppsEntry = psNewEntry; - - return PVRSRV_OK; - -err_pfn_alloc: - OSFreeMem(psNewEntry); -err_allocmem: - return eError; -} - -PVRSRV_ERROR PVRSRVPoolGet(PVRSRV_POOL *psPool, - PVRSRV_POOL_TOKEN *hToken, - void **ppvDataOut) -{ - PVRSRV_POOL_ENTRY *psEntry; - PVRSRV_ERROR eError = PVRSRV_OK; - DLLIST_NODE *psChosenNode; - - OSLockAcquire(psPool->hLock); - - psChosenNode = dllist_get_next_node(&psPool->sFreeList); - if (unlikely(psChosenNode == NULL)) - { - /* no available elements in the pool. try to create one */ - - eError = _CreateNewPoolEntry(psPool, &psEntry); - - PVR_GOTO_IF_ERROR(eError, out_unlock); - } - else - { - dllist_remove_node(psChosenNode); - - psEntry = IMG_CONTAINER_OF(psChosenNode, PVRSRV_POOL_ENTRY, sNode); - - psPool->uiNumFree--; - } - -#if defined(DEBUG) || defined(SUPPORT_VALIDATION) - /* Don't poison the IN buffer as that is copied from client and would be - * waste of cycles. - */ - OSCachedMemSet(((IMG_PBYTE)psEntry->pvData)+PVRSRV_MAX_BRIDGE_IN_SIZE, - PVRSRV_POISON_ON_ALLOC_VALUE, PVRSRV_MAX_BRIDGE_OUT_SIZE); -#endif - - psPool->uiNumBusy++; - *hToken = psEntry; - *ppvDataOut = psEntry->pvData; - -out_unlock: - OSLockRelease(psPool->hLock); - return eError; -} - -PVRSRV_ERROR PVRSRVPoolPut(PVRSRV_POOL *psPool, PVRSRV_POOL_TOKEN hToken) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_POOL_ENTRY *psEntry = hToken; - - PVR_ASSERT(psPool->uiNumBusy > 0); - - OSLockAcquire(psPool->hLock); - - /* put this entry in the pool if the pool has space, - * otherwise free it - */ - if (psPool->uiNumFree < psPool->uiMaxEntries) - { - dllist_add_to_tail(&psPool->sFreeList, &psEntry->sNode); - psPool->uiNumFree++; - } - else - { - eError = _DestroyPoolEntry(psPool, psEntry); - } - - psPool->uiNumBusy--; - - OSLockRelease(psPool->hLock); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.h deleted file mode 100644 index 2272fc50ce6e3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_pool.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Services pool implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides a generic pool implementation. - The pool allows to dynamically retrieve and return entries from - it using functions pair PVRSRVPoolGet/PVRSRVPoolPut. The entries - are created in lazy manner which means not until first usage. - The pool API allows to pass and allocation/free functions - pair that will allocate entry's private data and return it - to the caller on every entry 'Get'. - The pool will keep up to ui32MaxEntries entries allocated. - Every entry that exceeds this number and is 'Put' back to the - pool will be freed on the spot instead being returned to the - pool. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(PVRSRVPOOL_H) -#define PVRSRVPOOL_H - -/**************************************************************************/ /*! - @Description Callback function called during creation of the new element. This - function allocates an object that will be stored in the pool. - The object can be retrieved from the pool by calling - PVRSRVPoolGet. - @Input pvPrivData Private data passed to the alloc function. - @Output pvOut Allocated object. - @Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /***************************************************************************/ -typedef PVRSRV_ERROR (PVRSRV_POOL_ALLOC_FUNC)(void *pvPrivData, void **pvOut); - -/**************************************************************************/ /*! - @Description Callback function called to free the object allocated by - the counterpart alloc function. - @Input pvPrivData Private data passed to the free function. - @Output pvFreeData Object allocated by PVRSRV_POOL_ALLOC_FUNC. -*/ /***************************************************************************/ -typedef void (PVRSRV_POOL_FREE_FUNC)(void *pvPrivData, void *pvFreeData); - -typedef IMG_HANDLE PVRSRV_POOL_TOKEN; - -typedef struct _PVRSRV_POOL_ PVRSRV_POOL; - -/**************************************************************************/ /*! - @Function PVRSRVPoolCreate - @Description Creates new buffer pool. - @Input pfnAlloc Allocation function pointer. Function is used - to allocate new pool entries' data. - @Input pfnFree Free function pointer. Function is used to - free memory allocated by pfnAlloc function. - @Input ui32MaxEntries Total maximum number of entries in the pool. - @Input pszName Name of the pool. String has to be NULL - terminated. - @Input pvPrivData Private data that will be passed to pfnAlloc and - pfnFree functions. - @Output ppsPool New buffer pool object. - @Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR PVRSRVPoolCreate(PVRSRV_POOL_ALLOC_FUNC *pfnAlloc, - PVRSRV_POOL_FREE_FUNC *pfnFree, - IMG_UINT32 ui32MaxEntries, - const IMG_CHAR *pszName, - void *pvPrivData, - PVRSRV_POOL **ppsPool); - -/**************************************************************************/ /*! - @Function PVRSRVPoolDestroy - @Description Destroys pool created by PVRSRVPoolCreate. - @Input psPool Buffer pool object meant to be destroyed. -*/ /***************************************************************************/ -void PVRSRVPoolDestroy(PVRSRV_POOL *psPool); - -/**************************************************************************/ /*! - @Function PVRSRVPoolGet - @Description Retrieves an entry from a pool. If no free elements are - available new entry will be allocated. - @Input psPool Pointer to the pool. - @Output hToken Pointer to the entry handle. - @Output ppvDataOut Pointer to data stored in the entry (the data - allocated by the pfnAlloc function). - @Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR PVRSRVPoolGet(PVRSRV_POOL *psPool, - PVRSRV_POOL_TOKEN *hToken, - void **ppvDataOut); - -/**************************************************************************/ /*! - @Function PVRSRVPoolPut - @Description Returns entry to the pool. If number of entries is greater - than ui32MaxEntries set during pool creation the entry will - be freed instead. - @Input psPool Pointer to the pool. - @Input hToken Entry handle. - @Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR PVRSRVPoolPut(PVRSRV_POOL *psPool, - PVRSRV_POOL_TOKEN hToken); - -#endif /* PVRSRVPOOL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_km.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_km.h deleted file mode 100644 index 04611f9f7ceeb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_km.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR synchronisation interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Types for server side code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_SYNC_KM_H -#define PVRSRV_SYNC_KM_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -#define SYNC_FB_FILE_STRING_MAX 256 -#define SYNC_FB_MODULE_STRING_LEN_MAX (32) -#define SYNC_FB_DESC_STRING_LEN_MAX (32) - -/* By default, fence-sync module emits into HWPerf (of course, if enabled) and - * considers a process (sleepable) context */ -#define PVRSRV_FENCE_FLAG_NONE (0U) -#define PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT (1U << 0) -#define PVRSRV_FENCE_FLAG_CTX_ATOMIC (1U << 1) - -#if defined(__cplusplus) -} -#endif -#endif /* PVRSRV_SYNC_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_server.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_server.h deleted file mode 100644 index 5d1a10cd0a9c4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_sync_server.h +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Fence sync server interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_SYNC_SERVER_H -#define PVRSRV_SYNC_SERVER_H - -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) -#include "sync_fallback_server.h" -#include "pvr_notifier.h" -#include "img_types.h" -#include "pvrsrv_sync_km.h" -#elif defined(SUPPORT_NATIVE_FENCE_SYNC) -#include "pvr_sync.h" -#endif - -#include "rgxhwperf.h" - -#define SYNC_SW_TIMELINE_MAX_LENGTH PVRSRV_SYNC_NAME_LENGTH -#define SYNC_SW_FENCE_MAX_LENGTH PVRSRV_SYNC_NAME_LENGTH - -typedef struct _SYNC_TIMELINE_OBJ_ -{ - void *pvTlObj; /* Implementation specific timeline object */ - - PVRSRV_TIMELINE hTimeline; /* Reference to implementation-independent timeline object */ -} SYNC_TIMELINE_OBJ; - -typedef struct _SYNC_FENCE_OBJ_ -{ - void *pvFenceObj; /* Implementation specific fence object */ - - PVRSRV_FENCE hFence; /* Reference to implementation-independent fence object */ -} SYNC_FENCE_OBJ; - -static inline void SyncClearTimelineObj(SYNC_TIMELINE_OBJ *psSTO) -{ - psSTO->pvTlObj = NULL; - psSTO->hTimeline = PVRSRV_NO_TIMELINE; -} - -static inline IMG_BOOL SyncIsTimelineObjValid(const SYNC_TIMELINE_OBJ *psSTO) -{ - return (IMG_BOOL)(psSTO->pvTlObj != NULL); -} - -static inline void SyncClearFenceObj(SYNC_FENCE_OBJ *psSFO) -{ - psSFO->pvFenceObj = NULL; - psSFO->hFence = PVRSRV_NO_FENCE; -} - -static inline IMG_BOOL SyncIsFenceObjValid(const SYNC_FENCE_OBJ *psSFO) -{ - return (IMG_BOOL)(psSFO->pvFenceObj != NULL); -} - - -/* Mapping of each required function to its appropriate sync-implementation function */ -#if defined(SUPPORT_FALLBACK_FENCE_SYNC) - #define SyncFenceWaitKM_ SyncFbFenceWait - #define SyncGetFenceObj_ SyncFbGetFenceObj - #define SyncFenceReleaseKM_ SyncFbFenceReleaseKM - #define SyncSWTimelineFenceCreateKM_ SyncFbSWTimelineFenceCreateKM - #define SyncSWTimelineAdvanceKM_ SyncFbSWTimelineAdvanceKM - #define SyncSWGetTimelineObj_ SyncFbSWGetTimelineObj - #define SyncSWTimelineReleaseKM_ SyncFbTimelineRelease - #define SyncDumpFence_ SyncFbDumpFenceKM - #define SyncSWDumpTimeline_ SyncFbSWDumpTimelineKM -#elif defined(SUPPORT_NATIVE_FENCE_SYNC) - #define SyncFenceWaitKM_ pvr_sync_fence_wait - #define SyncGetFenceObj_ pvr_sync_fence_get - #define SyncFenceReleaseKM_ pvr_sync_fence_release - #define SyncSWTimelineFenceCreateKM_ pvr_sync_sw_timeline_fence_create - #define SyncSWTimelineAdvanceKM_ pvr_sync_sw_timeline_advance - #define SyncSWGetTimelineObj_ pvr_sync_sw_timeline_get - #define SyncSWTimelineReleaseKM_ pvr_sync_sw_timeline_release - #define SyncDumpFence_ sync_dump_fence - #define SyncSWDumpTimeline_ sync_sw_dump_timeline -#endif - -/*************************************************************************/ /*! -@Function SyncFenceWaitKM - -@Description Wait for all the sync points in the fence to be signalled. - -@Input psFenceObj Fence to wait on - -@Input ui32TimeoutInMs Maximum time to wait (in milliseconds) - -@Return PVRSRV_OK once the fence has been passed (all - containing check points have either - signalled or errored) - PVRSRV_ERROR_TIMEOUT if the poll has exceeded the timeout - PVRSRV_ERROR_FAILED_DEPENDENCIES Other sync-impl specific error -*/ /**************************************************************************/ -static inline PVRSRV_ERROR -SyncFenceWaitKM(PVRSRV_DEVICE_NODE *psDevNode, - const SYNC_FENCE_OBJ *psFenceObj, - IMG_UINT32 ui32TimeoutInMs) -{ - PVRSRV_ERROR eError; - - RGXSRV_HWPERF_SYNC_FENCE_WAIT(psDevNode->pvDevice, - BEGIN, - OSGetCurrentProcessID(), - psFenceObj->hFence, - ui32TimeoutInMs); - - eError = SyncFenceWaitKM_(psFenceObj->pvFenceObj, ui32TimeoutInMs); - - RGXSRV_HWPERF_SYNC_FENCE_WAIT(psDevNode->pvDevice, - END, - OSGetCurrentProcessID(), - psFenceObj->hFence, - ((eError == PVRSRV_OK) ? - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_PASSED : - ((eError == PVRSRV_ERROR_TIMEOUT) ? - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_TIMEOUT : - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_ERROR))); - return eError; -} - -/*************************************************************************/ /*! -@Function SyncGetFenceObj - -@Description Get the implementation specific server fence object from - opaque implementation independent PVRSRV_FENCE type. - When successful, this function gets a reference on the base - fence, which needs to be dropped using SyncFenceReleaseKM, - when fence object is no longer in use. - -@Input iFence Input opaque fence object - -@Output psFenceObj Pointer to implementation specific fence object - -@Return PVRSRV_ERROR PVRSRV_OK, on success -*/ /**************************************************************************/ -static inline PVRSRV_ERROR -SyncGetFenceObj(PVRSRV_FENCE iFence, - SYNC_FENCE_OBJ *psFenceObj) -{ - psFenceObj->hFence = iFence; - return SyncGetFenceObj_(iFence, &psFenceObj->pvFenceObj); -} - -/*************************************************************************/ /*! -@Function SyncFenceReleaseKM - -@Description Release reference on this fence. - -@Input psFenceObj Fence to be released - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static inline -PVRSRV_ERROR SyncFenceReleaseKM(const SYNC_FENCE_OBJ *psFenceObj) -{ - return SyncFenceReleaseKM_(psFenceObj->pvFenceObj); -} - -/*****************************************************************************/ -/* */ -/* SW TIMELINE SPECIFIC FUNCTIONS */ -/* */ -/*****************************************************************************/ - -static inline PVRSRV_ERROR -SyncSWTimelineFenceCreateKM(PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE hSWTimeline, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE *phOutFence) -{ - IMG_UINT64 ui64SyncPtIdx; - PVRSRV_ERROR eError; - eError = SyncSWTimelineFenceCreateKM_(psDevNode, - hSWTimeline, - pszFenceName, - phOutFence, - &ui64SyncPtIdx); - if (eError == PVRSRV_OK) - { - RGXSRV_HWPERF_ALLOC_SW_FENCE(psDevNode, OSGetCurrentProcessID(), - *phOutFence, hSWTimeline, ui64SyncPtIdx, - pszFenceName, OSStringLength(pszFenceName)); - } - return eError; -} - -static inline PVRSRV_ERROR -SyncSWTimelineAdvanceKM(PVRSRV_DEVICE_NODE *psDevNode, - const SYNC_TIMELINE_OBJ *psSWTimelineObj) -{ - IMG_UINT64 ui64SyncPtIdx; - PVRSRV_ERROR eError; - eError = SyncSWTimelineAdvanceKM_(psSWTimelineObj->pvTlObj, - &ui64SyncPtIdx); - - if (eError == PVRSRV_OK) - { - RGXSRV_HWPERF_SYNC_SW_TL_ADV(psDevNode->pvDevice, - OSGetCurrentProcessID(), - psSWTimelineObj->hTimeline, - ui64SyncPtIdx); - } - return eError; -} - -static inline PVRSRV_ERROR -SyncSWGetTimelineObj(PVRSRV_TIMELINE hSWTimeline, - SYNC_TIMELINE_OBJ *psSWTimelineObj) -{ - psSWTimelineObj->hTimeline = hSWTimeline; - return SyncSWGetTimelineObj_(hSWTimeline, &psSWTimelineObj->pvTlObj); -} - -static inline PVRSRV_ERROR -SyncSWTimelineReleaseKM(const SYNC_TIMELINE_OBJ *psSWTimelineObj) -{ - return SyncSWTimelineReleaseKM_(psSWTimelineObj->pvTlObj); -} - -static inline PVRSRV_ERROR -SyncDumpFence(const SYNC_FENCE_OBJ *psFenceObj, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - return SyncDumpFence_(psFenceObj->pvFenceObj, pfnDumpDebugPrintf, pvDumpDebugFile); -} - -static inline PVRSRV_ERROR -SyncSWDumpTimeline(const SYNC_TIMELINE_OBJ *psSWTimelineObj, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - return SyncSWDumpTimeline_(psSWTimelineObj->pvTlObj, pfnDumpDebugPrintf, pvDumpDebugFile); -} - - -#endif /* PVRSRV_SYNC_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlcommon.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlcommon.h deleted file mode 100644 index 28999e5d21b7a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlcommon.h +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Transport Layer common types and definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport layer common types and definitions included into - both user mode and kernel mode source. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVR_TLCOMMON_H -#define PVR_TLCOMMON_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" - - -/*! Handle type for stream descriptor objects as created by this API */ -typedef IMG_HANDLE PVRSRVTL_SD; - -/*! Maximum stream name length including the null byte */ -#define PRVSRVTL_MAX_STREAM_NAME_SIZE 40U - -/*! Maximum number of streams expected to exist */ -#define PVRSRVTL_MAX_DISCOVERABLE_STREAMS_BUFFER (32*PRVSRVTL_MAX_STREAM_NAME_SIZE) - -/*! Packet lengths are always rounded up to a multiple of 8 bytes */ -#define PVRSRVTL_PACKET_ALIGNMENT 8U -#define PVRSRVTL_ALIGN(x) (((x)+PVRSRVTL_PACKET_ALIGNMENT-1U) & ~(PVRSRVTL_PACKET_ALIGNMENT-1U)) - - -/*! A packet is made up of a header structure followed by the data bytes. - * There are 3 types of packet: normal (has data), data lost and padding, - * see packet flags. Header kept small to reduce data overhead. - * - * if the ORDER of the structure members is changed, please UPDATE the - * PVRSRVTL_PACKET_FLAG_OFFSET macro. - * - * Layout of uiTypeSize member is : - * - * |<---------------------------32-bits------------------------------>| - * |<----8---->|<-----1----->|<----7--->|<------------16------------->| - * | Type | Drop-Oldest | UNUSED | Size | - * - */ -typedef struct -{ - IMG_UINT32 uiTypeSize; /*!< Type, Drop-Oldest flag & number of bytes following header */ - IMG_UINT32 uiReserved; /*!< Reserve, packets and data must be 8 byte aligned */ - - /* First bytes of TL packet data follow header ... */ -} PVRSRVTL_PACKETHDR, *PVRSRVTL_PPACKETHDR; - -/* Structure must always be a size multiple of 8 as stream buffer - * still an array of IMG_UINT32s. - */ -static_assert((sizeof(PVRSRVTL_PACKETHDR) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(PVRSRVTL_PACKETHDR) must be a multiple of 8"); - -/*! Packet header reserved word fingerprint "TLP1" */ -#define PVRSRVTL_PACKETHDR_RESERVED 0x31504C54U - -/*! Packet header mask used to extract the size from the uiTypeSize member. - * Do not use directly, see GET macros. - */ -#define PVRSRVTL_PACKETHDR_SIZE_MASK 0x0000FFFFU -#define PVRSRVTL_MAX_PACKET_SIZE (PVRSRVTL_PACKETHDR_SIZE_MASK & ~0xFU) - - -/*! Packet header mask used to extract the type from the uiTypeSize member. - * Do not use directly, see GET macros. - */ -#define PVRSRVTL_PACKETHDR_TYPE_MASK 0xFF000000U -#define PVRSRVTL_PACKETHDR_TYPE_OFFSET 24U - -/*! Packet header mask used to check if packets before this one were dropped - * or not. Do not use directly, see GET macros. - */ -#define PVRSRVTL_PACKETHDR_OLDEST_DROPPED_MASK 0x00800000U -#define PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET 23U - -/*! Packet type enumeration. - */ -typedef IMG_UINT32 PVRSRVTL_PACKETTYPE; - -/*! Undefined packet */ -#define PVRSRVTL_PACKETTYPE_UNDEF 0U - -/*! Normal packet type. Indicates data follows the header. - */ -#define PVRSRVTL_PACKETTYPE_DATA 1U - -/*! When seen this packet type indicates that at this moment in the stream - * packet(s) were not able to be accepted due to space constraints and - * that recent data may be lost - depends on how the producer handles the - * error. Such packets have no data, data length is 0. - */ -#define PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED 2U - -/*! Packets with this type set are padding packets that contain undefined - * data and must be ignored/skipped by the client. They are used when the - * circular stream buffer wraps around and there is not enough space for - * the data at the end of the buffer. Such packets have a length of 0 or - * more. - */ -#define PVRSRVTL_PACKETTYPE_PADDING 3U - -/*! This packet type conveys to the stream consumer that the stream - * producer has reached the end of data for that data sequence. The - * TLDaemon has several options for processing these packets that can - * be selected on a per stream basis. - */ -#define PVRSRVTL_PACKETTYPE_MARKER_EOS 4U - -/*! This is same as PVRSRVTL_PACKETTYPE_MARKER_EOS but additionally removes - * old data record output file before opening new/next one - */ -#define PVRSRVTL_PACKETTYPE_MARKER_EOS_REMOVEOLD 5U - -/*! Packet emitted on first stream opened by writer. Packet carries a name - * of the opened stream in a form of null-terminated string. - */ -#define PVRSRVTL_PACKETTYPE_STREAM_OPEN_FOR_WRITE 6U - -/*! Packet emitted on last stream closed by writer. Packet carries a name - * of the closed stream in a form of null-terminated string. - */ -#define PVRSRVTL_PACKETTYPE_STREAM_CLOSE_FOR_WRITE 7U - -#define PVRSRVTL_PACKETTYPE_LAST 8U - -/* The SET_PACKET_* macros rely on the order the PVRSRVTL_PACKETHDR members are declared: - * uiFlags is the upper half of a structure consisting of 2 uint16 quantities. - */ -#define PVRSRVTL_SET_PACKET_DATA(len) (len) | (PVRSRVTL_PACKETTYPE_DATA << PVRSRVTL_PACKETHDR_TYPE_OFFSET) -#define PVRSRVTL_SET_PACKET_PADDING(len) (len) | (PVRSRVTL_PACKETTYPE_PADDING << PVRSRVTL_PACKETHDR_TYPE_OFFSET) -#define PVRSRVTL_SET_PACKET_WRITE_FAILED (0U) | (PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED << PVRSRVTL_PACKETHDR_TYPE_OFFSET) -#define PVRSRVTL_SET_PACKET_HDR(len, type) (len) | ((type) << PVRSRVTL_PACKETHDR_TYPE_OFFSET) - -/*! Returns the number of bytes of data in the packet. - * p may be any address type. - */ -#define GET_PACKET_DATA_LEN(p) \ - ((IMG_UINT32) ((PVRSRVTL_PPACKETHDR) (void *) (p))->uiTypeSize & PVRSRVTL_PACKETHDR_SIZE_MASK) - - -/*! Returns a IMG_BYTE* pointer to the first byte of data in the packet */ -#define GET_PACKET_DATA_PTR(p) \ - (((IMG_UINT8 *) (void *) (p)) + sizeof(PVRSRVTL_PACKETHDR)) - -/*! Turns the packet address p into a PVRSRVTL_PPACKETHDR pointer type. - */ -#define GET_PACKET_HDR(p) ((PVRSRVTL_PPACKETHDR) ((void *) (p))) - -/*! Given a PVRSRVTL_PPACKETHDR address, return the address of the next pack - * It is up to the caller to determine if the new address is within the - * packet buffer. - */ -#define GET_NEXT_PACKET_ADDR(p) \ - GET_PACKET_HDR( \ - GET_PACKET_DATA_PTR(p) + \ - ( \ - (GET_PACKET_DATA_LEN(p) + (PVRSRVTL_PACKET_ALIGNMENT-1U)) & \ - (~(PVRSRVTL_PACKET_ALIGNMENT-1U)) \ - ) \ - ) - -/*! Get the type of the packet. p is of type PVRSRVTL_PPACKETHDR. - */ -#define GET_PACKET_TYPE(p) (((p)->uiTypeSize & PVRSRVTL_PACKETHDR_TYPE_MASK)>>PVRSRVTL_PACKETHDR_TYPE_OFFSET) - -/*! Set PACKETS_DROPPED flag in packet header as a part of uiTypeSize. - * p is of type PVRSRVTL_PPACKETHDR. - */ -#define SET_PACKETS_DROPPED(p) (((p)->uiTypeSize) | (1UL << PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET)) - -/*! Check if packets were dropped before this packet. - * p is of type PVRSRVTL_PPACKETHDR. - */ -#define CHECK_PACKETS_DROPPED(p) (((p)->uiTypeSize & PVRSRVTL_PACKETHDR_OLDEST_DROPPED_MASK)>>PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET) - -/*! Flags for use with PVRSRVTLOpenStream - * 0x01 - Do not block in PVRSRVTLAcquireData() when no bytes are available - * 0x02 - When the stream does not exist wait for a bit (2s) in - * PVRSRVTLOpenStream() and then exit with a timeout error if it still - * does not exist. - * 0x04 - Open stream for write only operations. - * If flag is not used stream is opened as read-only. This flag is - * required if one wants to call reserve/commit/write function on the - * stream descriptor. Read from on the stream descriptor opened - * with this flag will fail. - * 0x08 - Disable Producer Callback. - * If this flag is set and the stream becomes empty, do not call any - * associated producer callback to generate more data from the reader - * context. - * 0x10 - Reset stream on open. - * When this flag is used the stream will drop all of the stored data. - * 0x20 - Limit read position to the write position at time the stream - * was opened. Hence this flag will freeze the content read to that - * produced before the stream was opened for reading. - * 0x40 - Ignore Open Callback. - * When this flag is set ignore any OnReaderOpenCallback setting for - * the stream. This allows access to the stream to be made without - * generating any extra packets into the stream. - */ - -#define PVRSRV_STREAM_FLAG_NONE (0U) -#define PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING (1U<<0) -#define PVRSRV_STREAM_FLAG_OPEN_WAIT (1U<<1) -#define PVRSRV_STREAM_FLAG_OPEN_WO (1U<<2) -#define PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK (1U<<3) -#define PVRSRV_STREAM_FLAG_RESET_ON_OPEN (1U<<4) -#define PVRSRV_STREAM_FLAG_READ_LIMIT (1U<<5) -#define PVRSRV_STREAM_FLAG_IGNORE_OPEN_CALLBACK (1U<<6) - - -#if defined(__cplusplus) -} -#endif - -#endif /* PVR_TLCOMMON_H */ -/****************************************************************************** - End of file (pvrsrv_tlcommon.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlstreams.h b/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlstreams.h deleted file mode 100644 index 9064075ad5c0c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrv_tlstreams.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Transport Layer stream names -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport layer common types and definitions included into - both user mode and kernel mode source. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRSRV_TLSTREAMS_H -#define PVRSRV_TLSTREAMS_H - -#define PVRSRV_TL_CTLR_STREAM "tlctrl" - -#define PVRSRV_TL_HWPERF_RGX_FW_STREAM "hwperf_fw_" -#define PVRSRV_TL_HWPERF_HOST_SERVER_STREAM "hwperf_host_" - -/* Host HWPerf client stream names are of the form 'hwperf_client_' */ -#define PVRSRV_TL_HWPERF_HOST_CLIENT_STREAM "hwperf_client_" -#define PVRSRV_TL_HWPERF_HOST_CLIENT_STREAM_FMTSPEC "hwperf_client_%u_%u" - -#endif /* PVRSRV_TLSTREAMS_H */ - -/****************************************************************************** - End of file (pvrsrv_tlstreams.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrsrvkm.mk b/drivers/gpu/drm/img-rogue/1.17/pvrsrvkm.mk deleted file mode 100644 index 41e38a26f7e36..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrsrvkm.mk +++ /dev/null @@ -1,165 +0,0 @@ -pvrsrvkm_1_17-y += \ - client_cache_direct_bridge.o \ - server_cache_bridge.o \ - server_cmm_bridge.o \ - client_devicememhistory_direct_bridge.o \ - server_devicememhistory_bridge.o \ - server_di_bridge.o \ - server_dmabuf_bridge.o \ - client_htbuffer_direct_bridge.o \ - server_htbuffer_bridge.o \ - client_mm_direct_bridge.o \ - server_mm_bridge.o \ - client_pvrtl_direct_bridge.o \ - server_pvrtl_bridge.o \ - server_rgxbreakpoint_bridge.o \ - server_rgxcmp_bridge.o \ - server_rgxfwdbg_bridge.o \ - server_rgxhwperf_bridge.o \ - server_rgxkicksync_bridge.o \ - server_rgxregconfig_bridge.o \ - server_rgxta3d_bridge.o \ - server_rgxtimerquery_bridge.o \ - server_rgxtq2_bridge.o \ - server_rgxtq_bridge.o \ - server_srvcore_bridge.o \ - client_sync_direct_bridge.o \ - server_sync_bridge.o \ - client_synctracking_direct_bridge.o \ - server_synctracking_bridge.o \ - cache_km.o \ - connection_server.o \ - debug_common.o \ - devicemem_heapcfg.o \ - devicemem_history_server.o \ - devicemem_server.o \ - di_impl_brg.o \ - di_server.o \ - handle.o \ - htb_debug.o \ - htbserver.o \ - info_page_km.o \ - lists.o \ - mmu_common.o \ - physheap.o \ - physmem.o \ - physmem_hostmem.o \ - physmem_lma.o \ - pmr.o \ - power.o \ - process_stats.o \ - pvr_notifier.o \ - pvrsrv.o \ - pvrsrv_bridge_init.o \ - pvrsrv_pool.o \ - srvcore.o \ - sync_checkpoint.o \ - sync_server.o \ - tlintern.o \ - tlserver.o \ - tlstream.o \ - vmm_pvz_client.o \ - vmm_pvz_server.o \ - vz_vmm_pvz.o \ - vz_vmm_vm.o \ - rgx_bridge_init.o \ - rgxbreakpoint.o \ - rgxbvnc.o \ - rgxccb.o \ - rgxfwdbg.o \ - rgxfwimageutils.o \ - rgxfwtrace_strings.o \ - rgxhwperf_common.o \ - rgxkicksync.o \ - rgxmem.o \ - rgxregconfig.o \ - rgxshader.o \ - rgxsyncutils.o \ - rgxtimecorr.o \ - rgxtimerquery.o \ - rgxutils.o \ - rgxcompute.o \ - rgxdebug.o \ - rgxfwutils.o \ - rgxhwperf.o \ - rgxinit.o \ - rgxlayer_impl.o \ - rgxmipsmmuinit.o \ - rgxmmuinit.o \ - rgxmulticore.o \ - rgxpower.o \ - rgxsrvinit.o \ - rgxstartstop.o \ - rgxta3d.o \ - rgxtdmtransfer.o \ - rgxtransfer.o \ - allocmem.o \ - event.o \ - fwload.o \ - handle_idr.o \ - km_apphint.o \ - module_common.o \ - osconnection_server.o \ - osfunc.o \ - osmmap_stub.o \ - physmem_dmabuf.o \ - physmem_osmem_linux.o \ - pmr_os.o \ - pvr_bridge_k.o \ - pvr_buffer_sync.o \ - pvr_debug.o \ - pvr_debugfs.o \ - pvr_drm.o \ - pvr_dvfs_device.o \ - pvr_fence.o \ - pvr_gputrace.o \ - pvr_platform_drv.o \ - pvr_counting_timeline.o \ - pvr_counting_timeline.o \ - pvr_sw_fence.o \ - pvr_sw_fence.o \ - pvr_sync_file.o \ - pvr_sync_ioctl_common.o \ - pvr_sync_ioctl_drm.o \ - devicemem.o \ - devicemem_utils.o \ - hash.o \ - htbuffer.o \ - mem_utils.o \ - pvrsrv_error.o \ - ra.o \ - sync.o \ - tlclient.o \ - uniq_key_splay_tree.o \ - rgx_hwperf_table.o \ - interrupt_support.o \ - dma_support.o \ - vmm_type_stub.o -pvrsrvkm_1_17-$(CONFIG_DRM_POWERVR_ROGUE_DEBUG) += \ - client_ri_direct_bridge.o \ - server_ri_bridge.o \ - ri_server.o -pvrsrvkm_1_17-$(CONFIG_DRM_POWERVR_ROGUE_PDUMP) += \ - client_pdump_direct_bridge.o \ - server_pdump_bridge.o \ - client_pdumpctrl_direct_bridge.o \ - server_pdumpctrl_bridge.o \ - client_pdumpmm_direct_bridge.o \ - server_pdumpmm_bridge.o \ - client_rgxpdump_direct_bridge.o \ - server_rgxpdump_bridge.o \ - pdump_mmu.o \ - pdump_physmem.o \ - pdump_server.o \ - rgxpdump.o \ - devicemem_pdump.o \ - devicememx_pdump.o -ifneq ($(CONFIG_DRM_POWERVR_ROGUE_PDUMP),y) -pvrsrvkm_1_17-y += \ - physmem_test.o -endif -pvrsrvkm_1_17-$(CONFIG_ARM) += osfunc_arm.o -pvrsrvkm_1_17-$(CONFIG_ARM64) += osfunc_arm64.o -pvrsrvkm_1_17-$(CONFIG_EVENT_TRACING) += trace_events.o -pvrsrvkm_1_17-$(CONFIG_RISCV) += osfunc_riscv.c -pvrsrvkm_1_17-$(CONFIG_X86) += osfunc_x86.o diff --git a/drivers/gpu/drm/img-rogue/1.17/pvrversion.h b/drivers/gpu/drm/img-rogue/1.17/pvrversion.h deleted file mode 100644 index fb31d18785bb9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/pvrversion.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ /*! -@File pvrversion.h -@Title PowerVR version numbers and strings. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Version numbers and strings for PowerVR components. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 PVRVERSION_H -#define PVRVERSION_H - -#define PVRVERSION_MAJ 1U -#define PVRVERSION_MIN 17U - -#define PVRVERSION_FAMILY "rogueddk" -#define PVRVERSION_BRANCHNAME "1.17" -#define PVRVERSION_BUILD 6210866 -#define PVRVERSION_BSCONTROL "Rogue_DDK_ChromiumOS" - -#define PVRVERSION_STRING "Rogue_DDK_ChromiumOS rogueddk 1.17@6210866" -#define PVRVERSION_STRING_SHORT "1.17@6210866" - -#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved." - -#define PVRVERSION_BUILD_HI 621 -#define PVRVERSION_BUILD_LO 866 -#define PVRVERSION_STRING_NUMERIC "1.17.621.866" - -#define PVRVERSION_PACK(MAJOR,MINOR) (((IMG_UINT32)((IMG_UINT32)(MAJOR) & 0xFFFFU) << 16U) | (((MINOR) & 0xFFFFU) << 0U)) -#define PVRVERSION_UNPACK_MAJ(VERSION) (((VERSION) >> 16U) & 0xFFFFU) -#define PVRVERSION_UNPACK_MIN(VERSION) (((VERSION) >> 0U) & 0xFFFFU) - -#endif /* PVRVERSION_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/ra.c b/drivers/gpu/drm/img-rogue/1.17/ra.c deleted file mode 100644 index 4c2981e575635..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ra.c +++ /dev/null @@ -1,2166 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Resource Allocator -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - -@Description - Implements generic resource allocation. The resource allocator was originally - intended to manage address spaces. In practice the resource allocator is - generic and can manage arbitrary sets of integers. - - Resources are allocated from arenas. Arenas can be created with an initial - span of resources. Further resources spans can be added to arenas. A - callback mechanism allows an arena to request further resource spans on - demand. - - Each arena maintains an ordered list of resource segments each described by a - boundary tag. Each boundary tag describes a segment of resources which are - either 'free', available for allocation, or 'busy' currently allocated. - Adjacent 'free' segments are always coalesced to avoid fragmentation. - - For allocation, all 'free' segments are kept on lists of 'free' segments in - a table index by pvr_log2(segment size) i.e., each table index n holds 'free' - segments in the size range 2^n -> 2^(n+1) - 1. - - Allocation policy is based on an *almost* good fit strategy. - - Allocated segments are inserted into a self-scaling hash table which maps - the base resource of the span to the relevant boundary tag. This allows the - code to get back to the boundary tag without exporting explicit boundary tag - references through the API. - - Each arena has an associated quantum size, all allocations from the arena are - made in multiples of the basic quantum. - - On resource exhaustion in an arena, a callback if provided will be used to - request further resources. Resource spans allocated by the callback mechanism - will be returned when freed (through one of the two callbacks). -*/ /**************************************************************************/ - -/* Issues: - * - flags, flags are passed into the resource allocator but are not currently used. - * - determination, of import size, is currently braindead. - * - debug code should be moved out to own module and #ifdef'd - */ - -#include "img_types.h" -#include "img_defs.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "uniq_key_splay_tree.h" - -#include "hash.h" -#include "ra.h" -#include "pvrsrv_memallocflags.h" - -#include "osfunc.h" -#include "allocmem.h" -#include "lock.h" -#include "pvr_intrinsics.h" - -/* The initial, and minimum size of the live address -> boundary tag structure - * hash table. The value 64 is a fairly arbitrary choice. The hash table - * resizes on demand so the value chosen is not critical. - */ -#define MINIMUM_HASH_SIZE (64) - - -/* #define RA_VALIDATE */ - -#if defined(__KLOCWORK__) - /* Make sure Klocwork analyses all the code (including the debug one) */ - #if !defined(RA_VALIDATE) - #define RA_VALIDATE - #endif -#endif - -#if !defined(PVRSRV_NEED_PVR_ASSERT) || !defined(RA_VALIDATE) -/* Disable the asserts unless explicitly told otherwise. - * They slow the driver too much for other people - */ - -#undef PVR_ASSERT -/* Use a macro that really do not do anything when compiling in release - * mode! - */ -#define PVR_ASSERT(x) -#endif - -/* boundary tags, used to describe a resource segment */ -struct _BT_ -{ - enum bt_type - { - btt_free, /* free resource segment */ - btt_live /* allocated resource segment */ - } type; - - unsigned int is_leftmost; - unsigned int is_rightmost; - unsigned int free_import; - - /* The base resource and extent of this segment */ - RA_BASE_T base; - RA_LENGTH_T uSize; - - /* doubly linked ordered list of all segments within the arena */ - struct _BT_ *pNextSegment; - struct _BT_ *pPrevSegment; - - /* doubly linked un-ordered list of free segments with the same flags. */ - struct _BT_ *next_free; - struct _BT_ *prev_free; - - /* A user reference associated with this span, user references are - * currently only provided in the callback mechanism - */ - IMG_HANDLE hPriv; - - /* Flags to match on this span */ - RA_FLAGS_T uFlags; - -}; -typedef struct _BT_ BT; - - -/* resource allocation arena */ -struct _RA_ARENA_ -{ - /* arena name for diagnostics output */ - IMG_CHAR name[RA_MAX_NAME_LENGTH]; - - /* allocations within this arena are quantum sized */ - RA_LENGTH_T uQuantum; - - /* import interface, if provided */ - PFN_RA_ALLOC pImportAlloc; - - PFN_RA_FREE pImportFree; - - /* Arbitrary handle provided by arena owner to be passed into the - * import alloc and free hooks - */ - void *pImportHandle; - - IMG_PSPLAY_TREE per_flags_buckets; - - /* resource segment list */ - BT *pHeadSegment; - - /* segment address to boundary tag hash table */ - HASH_TABLE *pSegmentHash; - - /* Lock for this arena */ - POS_LOCK hLock; - - /* Policies that govern the resource area */ - IMG_UINT32 ui32PolicyFlags; - - /* LockClass of this arena. This is used within lockdep to decide if a - * recursive call sequence with the same lock class is allowed or not. - */ - IMG_UINT32 ui32LockClass; - - /* Total Size of the Arena */ - IMG_UINT64 ui64TotalArenaSize; - - /* Size available for allocation in the arena */ - IMG_UINT64 ui64FreeArenaSize; - -}; - -struct _RA_ARENA_ITERATOR_ -{ - RA_ARENA *pArena; - BT *pCurrent; - IMG_BOOL bIncludeFreeSegments; -}; - -/*************************************************************************/ /*! -@Function _RequestAllocFail -@Description Default callback allocator used if no callback is specified, - always fails to allocate further resources to the arena. -@Input _h - callback handle -@Input _uSize - requested allocation size -@Input _uflags - allocation flags -@Input _pBase - receives allocated base -@Output _pActualSize - actual allocation size -@Input _pRef - user reference -@Return PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL, this function always fails - to allocate. -*/ /**************************************************************************/ -static PVRSRV_ERROR -_RequestAllocFail(RA_PERARENA_HANDLE _h, - RA_LENGTH_T _uSize, - RA_FLAGS_T _uFlags, - const IMG_CHAR *_pszAnnotation, - RA_BASE_T *_pBase, - RA_LENGTH_T *_pActualSize, - RA_PERISPAN_HANDLE *_phPriv) -{ - PVR_UNREFERENCED_PARAMETER(_h); - PVR_UNREFERENCED_PARAMETER(_uSize); - PVR_UNREFERENCED_PARAMETER(_pActualSize); - PVR_UNREFERENCED_PARAMETER(_phPriv); - PVR_UNREFERENCED_PARAMETER(_uFlags); - PVR_UNREFERENCED_PARAMETER(_pBase); - PVR_UNREFERENCED_PARAMETER(_pszAnnotation); - - return PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL; -} - - -#if defined(PVR_CTZLL) - /* Make sure to trigger an error if someone change the buckets or the bHasEltsMapping size - the bHasEltsMapping is used to quickly determine the smallest bucket containing elements. - therefore it must have at least as many bits has the buckets array have buckets. The RA - implementation actually uses one more bit. */ - static_assert(ARRAY_SIZE(((IMG_PSPLAY_TREE)0)->buckets) - < 8 * sizeof(((IMG_PSPLAY_TREE) 0)->bHasEltsMapping), - "Too many buckets for bHasEltsMapping bitmap"); -#endif - - -/*************************************************************************/ /*! -@Function pvr_log2 -@Description Computes the floor of the log base 2 of a unsigned integer -@Input n Unsigned integer -@Return Floor(Log2(n)) -*/ /**************************************************************************/ -#if defined(PVR_CLZLL) -/* make sure to trigger a problem if someone changes the RA_LENGTH_T type - indeed the __builtin_clzll is for unsigned long long variables. - - if someone changes RA_LENGTH to unsigned long, then use __builtin_clzl - if it changes to unsigned int, use __builtin_clz - - if it changes for something bigger than unsigned long long, - then revert the pvr_log2 to the classic implementation */ -static_assert(sizeof(RA_LENGTH_T) == sizeof(unsigned long long), - "RA log routines not tuned for sizeof(RA_LENGTH_T)"); - -static inline IMG_UINT32 pvr_log2(RA_LENGTH_T n) -{ - PVR_ASSERT(n != 0); /* Log2 is not defined on 0 */ - - return (8 * sizeof(RA_LENGTH_T)) - 1 - PVR_CLZLL(n); -} -#else -static IMG_UINT32 -pvr_log2(RA_LENGTH_T n) -{ - IMG_UINT32 l = 0; - - PVR_ASSERT(n != 0); /* Log2 is not defined on 0 */ - - n >>= 1; - while (n > 0) - { - n >>= 1; - l++; - } - return l; -} -#endif - - -#if defined(RA_VALIDATE) -/*************************************************************************/ /*! -@Function _IsInSegmentList -@Description Tests if a BT is in the segment list. -@Input pArena The arena. -@Input pBT The boundary tag to look for. -@Return IMG_FALSE BT was not in the arena's segment list. - IMG_TRUE BT was in the arena's segment list. -*/ /**************************************************************************/ -static IMG_BOOL -_IsInSegmentList(RA_ARENA *pArena, BT *pBT) -{ - BT* pBTScan; - - PVR_ASSERT(pArena != NULL); - PVR_ASSERT(pBT != NULL); - - /* Walk the segment list until we see the BT pointer... */ - pBTScan = pArena->pHeadSegment; - while (pBTScan != NULL && pBTScan != pBT) - { - pBTScan = pBTScan->pNextSegment; - } - - /* Test if we found it and then return */ - return (pBTScan == pBT); -} - -/*************************************************************************/ /*! -@Function _IsInFreeList -@Description Tests if a BT is in the free list. -@Input pArena The arena. -@Input pBT The boundary tag to look for. -@Return IMG_FALSE BT was not in the arena's free list. - IMG_TRUE BT was in the arena's free list. -*/ /**************************************************************************/ -static IMG_BOOL -_IsInFreeList(RA_ARENA *pArena, BT *pBT) -{ - BT* pBTScan; - IMG_UINT32 uIndex; - - PVR_ASSERT(pArena != NULL); - PVR_ASSERT(pBT != NULL); - - /* Look for the free list that holds BTs of this size... */ - uIndex = pvr_log2(pBT->uSize); - PVR_ASSERT(uIndex < FREE_TABLE_LIMIT); - - pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets); - if ((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->flags != pBT->uFlags)) - { - return 0; - } - else - { - pBTScan = pArena->per_flags_buckets->buckets[uIndex]; - while (pBTScan != NULL && pBTScan != pBT) - { - pBTScan = pBTScan->next_free; - } - - /* Test if we found it and then return */ - return (pBTScan == pBT); - } -} - -/* is_arena_valid should only be used in debug mode. - * It checks that some properties an arena must have are verified - */ -static int is_arena_valid(struct _RA_ARENA_ *arena) -{ - struct _BT_ *chunk; -#if defined(PVR_CTZLL) - unsigned int i; -#endif - - for (chunk = arena->pHeadSegment; chunk != NULL; chunk = chunk->pNextSegment) - { - /* if next segment is NULL, then it must be a rightmost */ - PVR_ASSERT((chunk->pNextSegment != NULL) || (chunk->is_rightmost)); - /* if prev segment is NULL, then it must be a leftmost */ - PVR_ASSERT((chunk->pPrevSegment != NULL) || (chunk->is_leftmost)); - - if (chunk->type == btt_free) - { - /* checks the correctness of the type field */ - PVR_ASSERT(_IsInFreeList(arena, chunk)); - - /* check that there can't be two consecutive free chunks. - Indeed, instead of having two consecutive free chunks, - there should be only one that span the size of the two. */ - PVR_ASSERT((chunk->is_leftmost) || (chunk->pPrevSegment->type != btt_free)); - PVR_ASSERT((chunk->is_rightmost) || (chunk->pNextSegment->type != btt_free)); - } - else - { - /* checks the correctness of the type field */ - PVR_ASSERT(!_IsInFreeList(arena, chunk)); - } - - PVR_ASSERT((chunk->is_leftmost) || (chunk->pPrevSegment->base + chunk->pPrevSegment->uSize == chunk->base)); - PVR_ASSERT((chunk->is_rightmost) || (chunk->base + chunk->uSize == chunk->pNextSegment->base)); - - /* all segments of the same imports must have the same flags ... */ - PVR_ASSERT((chunk->is_rightmost) || (chunk->uFlags == chunk->pNextSegment->uFlags)); - /* ... and the same import handle */ - PVR_ASSERT((chunk->is_rightmost) || (chunk->hPriv == chunk->pNextSegment->hPriv)); - - - /* if a free chunk spans a whole import, then it must be an 'not to free import'. - Otherwise it should have been freed. */ - PVR_ASSERT((!chunk->is_leftmost) || (!chunk->is_rightmost) || (chunk->type == btt_live) || (!chunk->free_import)); - } - -#if defined(PVR_CTZLL) - if (arena->per_flags_buckets != NULL) - { - for (i = 0; i < FREE_TABLE_LIMIT; ++i) - { - /* verify that the bHasEltsMapping is correct for this flags bucket */ - PVR_ASSERT( - ((arena->per_flags_buckets->buckets[i] == NULL) && - (((arena->per_flags_buckets->bHasEltsMapping & ((IMG_ELTS_MAPPINGS) 1 << i)) == 0))) - || - ((arena->per_flags_buckets->buckets[i] != NULL) && - (((arena->per_flags_buckets->bHasEltsMapping & ((IMG_ELTS_MAPPINGS) 1 << i)) != 0))) - ); - } - } -#endif - - /* if arena was not valid, an earlier assert should have triggered */ - return 1; -} -#endif - -/*************************************************************************/ /*! -@Function _SegmentListInsertAfter -@Description Insert a boundary tag into an arena segment list after a - specified boundary tag. -@Input pInsertionPoint The insertion point. -@Input pBT The boundary tag to insert. -*/ /**************************************************************************/ -static INLINE void -_SegmentListInsertAfter(BT *pInsertionPoint, - BT *pBT) -{ - PVR_ASSERT(pBT != NULL); - PVR_ASSERT(pInsertionPoint != NULL); - - pBT->pNextSegment = pInsertionPoint->pNextSegment; - pBT->pPrevSegment = pInsertionPoint; - if (pInsertionPoint->pNextSegment != NULL) - { - pInsertionPoint->pNextSegment->pPrevSegment = pBT; - } - pInsertionPoint->pNextSegment = pBT; -} - -/*************************************************************************/ /*! -@Function _SegmentListInsert -@Description Insert a boundary tag into an arena segment list -@Input pArena The arena. -@Input pBT The boundary tag to insert. -*/ /**************************************************************************/ -static INLINE void -_SegmentListInsert(RA_ARENA *pArena, BT *pBT) -{ - PVR_ASSERT(!_IsInSegmentList(pArena, pBT)); - - /* insert into the segment chain */ - pBT->pNextSegment = pArena->pHeadSegment; - pArena->pHeadSegment = pBT; - if (pBT->pNextSegment != NULL) - { - pBT->pNextSegment->pPrevSegment = pBT; - } - - pBT->pPrevSegment = NULL; -} - -/*************************************************************************/ /*! -@Function _SegmentListRemove -@Description Remove a boundary tag from an arena segment list. -@Input pArena The arena. -@Input pBT The boundary tag to remove. -*/ /**************************************************************************/ -static void -_SegmentListRemove(RA_ARENA *pArena, BT *pBT) -{ - PVR_ASSERT(_IsInSegmentList(pArena, pBT)); - - if (pBT->pPrevSegment == NULL) - pArena->pHeadSegment = pBT->pNextSegment; - else - pBT->pPrevSegment->pNextSegment = pBT->pNextSegment; - - if (pBT->pNextSegment != NULL) - pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment; -} - - -/*************************************************************************/ /*! -@Function _BuildBT -@Description Construct a boundary tag for a free segment. -@Input base The base of the resource segment. -@Input uSize The extent of the resource segment. -@Input uFlags The flags to give to the boundary tag -@Return Boundary tag or NULL -*/ /**************************************************************************/ -static BT * -_BuildBT(RA_BASE_T base, RA_LENGTH_T uSize, RA_FLAGS_T uFlags) -{ - BT *pBT; - - pBT = OSAllocZMem(sizeof(BT)); - if (pBT == NULL) - { - return NULL; - } - - pBT->is_leftmost = 1; - pBT->is_rightmost = 1; - /* pBT->free_import = 0; */ - pBT->type = btt_live; - pBT->base = base; - pBT->uSize = uSize; - pBT->uFlags = uFlags; - - return pBT; -} - - -/*************************************************************************/ /*! -@Function _SegmentSplit -@Description Split a segment into two, maintain the arena segment list. The - boundary tag should not be in the free table. Neither the - original or the new neighbour boundary tag will be in the free - table. -@Input pBT The boundary tag to split. -@Input uSize The required segment size of boundary tag after - splitting. -@Return New neighbour boundary tag or NULL. -*/ /**************************************************************************/ -static BT * -_SegmentSplit(BT *pBT, RA_LENGTH_T uSize) -{ - BT *pNeighbour; - - pNeighbour = _BuildBT(pBT->base + uSize, pBT->uSize - uSize, pBT->uFlags); - if (pNeighbour == NULL) - { - return NULL; - } - - _SegmentListInsertAfter(pBT, pNeighbour); - - pNeighbour->is_leftmost = 0; - pNeighbour->is_rightmost = pBT->is_rightmost; - pNeighbour->free_import = pBT->free_import; - pBT->is_rightmost = 0; - pNeighbour->hPriv = pBT->hPriv; - pBT->uSize = uSize; - pNeighbour->uFlags = pBT->uFlags; - - return pNeighbour; -} - -/*************************************************************************/ /*! -@Function _FreeListInsert -@Description Insert a boundary tag into an arena free table. -@Input pArena The arena. -@Input pBT The boundary tag. -*/ /**************************************************************************/ -static void -_FreeListInsert(RA_ARENA *pArena, BT *pBT) -{ - IMG_UINT32 uIndex; - BT *pBTTemp = NULL; - uIndex = pvr_log2(pBT->uSize); - - PVR_ASSERT(uIndex < FREE_TABLE_LIMIT); - PVR_ASSERT(!_IsInFreeList(pArena, pBT)); - - pBT->type = btt_free; - - pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets); - /* the flags item in the splay tree must have been created before-hand by - _InsertResource */ - PVR_ASSERT(pArena->per_flags_buckets != NULL); - PVR_ASSERT(pArena->per_flags_buckets->buckets != NULL); - - /* Handle NULL values for RELEASE builds and/or disabled ASSERT DEBUG builds */ - if (unlikely((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->buckets == NULL))) - { - return; - } - - /* Get the first node in the bucket */ - pBTTemp = pArena->per_flags_buckets->buckets[uIndex]; - - if (unlikely((pArena->ui32PolicyFlags & RA_POLICY_ALLOC_NODE_SELECT_MASK) == RA_POLICY_ALLOC_OPTIMAL)) - { - /* Add the node to the start if the bucket is empty */ - if (NULL == pBTTemp) - { - pArena->per_flags_buckets->buckets[uIndex] = pBT; - pBT->next_free = NULL; - pBT->prev_free = NULL; - - } - else - { - BT *pBTPrev = NULL; - /* Traverse the list and identify the appropriate - * place based on the size of the Boundary being inserted */ - while (pBTTemp && (pBTTemp->uSize < pBT->uSize)) - { - pBTPrev = pBTTemp; - pBTTemp = pBTTemp->next_free; - } - /* point the new node to the first higher size element */ - pBT->next_free = pBTTemp; - pBT->prev_free = pBTPrev; - - if (pBTPrev) - { - /* Set the lower size element in the - * chain to point new node */ - pBTPrev->next_free = pBT; - } - else - { - /* Assign the new node to the start of the bucket - * if the bucket is empty */ - pArena->per_flags_buckets->buckets[uIndex] = pBT; - } - /* Make sure the higher size element in the chain points back - * to the new node to be introduced */ - if (pBTTemp) - { - pBTTemp->prev_free = pBT; - } - } - } - else - { - pBT->next_free = pBTTemp; - if (pBT->next_free != NULL) - { - pBT->next_free->prev_free = pBT; - } - pBT->prev_free = NULL; - pArena->per_flags_buckets->buckets[uIndex] = pBT; - } - -#if defined(PVR_CTZLL) - /* tells that bucket[index] now contains elements */ - pArena->per_flags_buckets->bHasEltsMapping |= ((IMG_ELTS_MAPPINGS) 1 << uIndex); -#endif - -} - -/*************************************************************************/ /*! -@Function _FreeListRemove -@Description Remove a boundary tag from an arena free table. -@Input pArena The arena. -@Input pBT The boundary tag. -*/ /**************************************************************************/ -static void -_FreeListRemove(RA_ARENA *pArena, BT *pBT) -{ - IMG_UINT32 uIndex; - uIndex = pvr_log2(pBT->uSize); - - PVR_ASSERT(uIndex < FREE_TABLE_LIMIT); - PVR_ASSERT(_IsInFreeList(pArena, pBT)); - - if (pBT->next_free != NULL) - { - pBT->next_free->prev_free = pBT->prev_free; - } - - if (pBT->prev_free != NULL) - { - pBT->prev_free->next_free = pBT->next_free; - } - else - { - pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets); - /* the flags item in the splay tree must have already been created - (otherwise how could there be a segment with these flags */ - PVR_ASSERT(pArena->per_flags_buckets != NULL); - PVR_ASSERT(pArena->per_flags_buckets->buckets != NULL); - - /* Handle unlikely NULL values for RELEASE or ASSERT-disabled builds */ - if (unlikely((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->buckets == NULL))) - { - pBT->type = btt_live; - return; - } - - pArena->per_flags_buckets->buckets[uIndex] = pBT->next_free; -#if defined(PVR_CTZLL) - if (pArena->per_flags_buckets->buckets[uIndex] == NULL) - { - /* there is no more elements in this bucket. Update the mapping. */ - pArena->per_flags_buckets->bHasEltsMapping &= ~((IMG_ELTS_MAPPINGS) 1 << uIndex); - } -#endif - } - - PVR_ASSERT(!_IsInFreeList(pArena, pBT)); - pBT->type = btt_live; -} - - -/*************************************************************************/ /*! -@Function _InsertResource -@Description Add a free resource segment to an arena. -@Input pArena The arena. -@Input base The base of the resource segment. -@Input uSize The extent of the resource segment. -@Input uFlags The flags of the new resources. -@Return New bucket pointer - NULL on failure -*/ /**************************************************************************/ -static BT * -_InsertResource(RA_ARENA *pArena, RA_BASE_T base, RA_LENGTH_T uSize, - RA_FLAGS_T uFlags) -{ - BT *pBT; - PVR_ASSERT(pArena!=NULL); - - pBT = _BuildBT(base, uSize, uFlags); - - if (pBT != NULL) - { - IMG_PSPLAY_TREE tmp = PVRSRVInsert(pBT->uFlags, pArena->per_flags_buckets); - if (tmp == NULL) - { - OSFreeMem(pBT); - return NULL; - } - - pArena->per_flags_buckets = tmp; - _SegmentListInsert(pArena, pBT); - _FreeListInsert(pArena, pBT); - } - return pBT; -} - -/*************************************************************************/ /*! -@Function _InsertResourceSpan -@Description Add a free resource span to an arena, marked for free_import. -@Input pArena The arena. -@Input base The base of the resource segment. -@Input uSize The extent of the resource segment. -@Return The boundary tag representing the free resource segment, - or NULL on failure. -*/ /**************************************************************************/ -static INLINE BT * -_InsertResourceSpan(RA_ARENA *pArena, - RA_BASE_T base, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags) -{ - BT *pBT = _InsertResource(pArena, base, uSize, uFlags); - if (pBT != NULL) - { - pBT->free_import = 1; - } - return pBT; -} - - -/*************************************************************************/ /*! -@Function _RemoveResourceSpan -@Description Frees a resource span from an arena, returning the imported - span via the callback. -@Input pArena The arena. -@Input pBT The boundary tag to free. -@Return IMG_FALSE failure - span was still in use - IMG_TRUE success - span was removed and returned -*/ /**************************************************************************/ -static INLINE IMG_BOOL -_RemoveResourceSpan(RA_ARENA *pArena, BT *pBT) -{ - PVR_ASSERT(pArena!=NULL); - PVR_ASSERT(pBT!=NULL); - - if (pBT->free_import && - pBT->is_leftmost && - pBT->is_rightmost) - { - _SegmentListRemove(pArena, pBT); - pArena->pImportFree(pArena->pImportHandle, pBT->base, pBT->hPriv); - OSFreeMem(pBT); - - return IMG_TRUE; - } - - return IMG_FALSE; -} - -/*************************************************************************/ /*! -@Function _FreeBT -@Description Free a boundary tag taking care of the segment list and the - boundary tag free table. -@Input pArena The arena. -@Input pBT The boundary tag to free. -*/ /**************************************************************************/ -static void -_FreeBT(RA_ARENA *pArena, BT *pBT) -{ - BT *pNeighbour; - - PVR_ASSERT(pArena!=NULL); - PVR_ASSERT(pBT!=NULL); - PVR_ASSERT(!_IsInFreeList(pArena, pBT)); - - /* try and coalesce with left neighbour */ - pNeighbour = pBT->pPrevSegment; - if ((!pBT->is_leftmost) && (pNeighbour->type == btt_free)) - { - /* Verify list correctness */ - PVR_ASSERT(pNeighbour->base + pNeighbour->uSize == pBT->base); - - _FreeListRemove(pArena, pNeighbour); - _SegmentListRemove(pArena, pNeighbour); - pBT->base = pNeighbour->base; - - pBT->uSize += pNeighbour->uSize; - pBT->is_leftmost = pNeighbour->is_leftmost; - OSFreeMem(pNeighbour); - } - - /* try to coalesce with right neighbour */ - pNeighbour = pBT->pNextSegment; - if ((!pBT->is_rightmost) && (pNeighbour->type == btt_free)) - { - /* Verify list correctness */ - PVR_ASSERT(pBT->base + pBT->uSize == pNeighbour->base); - - _FreeListRemove(pArena, pNeighbour); - _SegmentListRemove(pArena, pNeighbour); - pBT->uSize += pNeighbour->uSize; - pBT->is_rightmost = pNeighbour->is_rightmost; - OSFreeMem(pNeighbour); - } - - if (_RemoveResourceSpan(pArena, pBT) == IMG_FALSE) - { - _FreeListInsert(pArena, pBT); - PVR_ASSERT((!pBT->is_rightmost) || (!pBT->is_leftmost) || (!pBT->free_import)); - } - - PVR_ASSERT(is_arena_valid(pArena)); -} - - -/* - This function returns the first element in a bucket that can be split - in a way that one of the sub-segments can meet the size and alignment - criteria. - - The first_elt is the bucket to look into. Remember that a bucket is - implemented as a pointer to the first element of the linked list. - - nb_max_try is used to limit the number of elements considered. - This is used to only consider the first nb_max_try elements in the - free-list. The special value ~0 is used to say unlimited i.e. consider - all elements in the free list - */ -static INLINE -struct _BT_ *find_chunk_in_bucket(struct _BT_ * first_elt, - RA_LENGTH_T uSize, - RA_LENGTH_T uAlignment, - unsigned int nb_max_try) -{ - struct _BT_ *walker; - - for (walker = first_elt; (walker != NULL) && (nb_max_try != 0); walker = walker->next_free) - { - const RA_BASE_T aligned_base = (uAlignment > 1) ? - (walker->base + uAlignment - 1) & ~(uAlignment - 1) - : walker->base; - - if (walker->base + walker->uSize >= aligned_base + uSize) - { - return walker; - } - - /* 0xFFFF...FFFF is used has nb_max_try = infinity. */ - if (nb_max_try != (unsigned int) ~0) - { - nb_max_try--; - } - } - - return NULL; -} - -/*************************************************************************/ /*! -@Function _AllocAlignSplit -@Description Given a valid BT, trim the start and end of the BT according - to alignment and size requirements. Also add the resulting - BT to the live hash table. -@Input pArena The arena. -@Input pBT The BT to trim and add to live hash table -@Input uSize The requested allocation size. -@Input uAlignment The alignment requirements of the allocation - Required uAlignment, or 0. - Must be a power of 2 if not 0 -@Output pBase Allocated, corrected, resource base - (non-optional, must not be NULL) -@Output phPriv The user references associated with - the imported segment. (optional) -@Return IMG_FALSE failure - IMG_TRUE success -*/ /**************************************************************************/ -static IMG_BOOL -_AllocAlignSplit(RA_ARENA *pArena, - BT *pBT, - RA_LENGTH_T uSize, - RA_LENGTH_T uAlignment, - RA_BASE_T *pBase, - RA_PERISPAN_HANDLE *phPriv) -{ - RA_BASE_T aligned_base; - - aligned_base = (uAlignment > 1) ? (pBT->base + uAlignment - 1) & ~(uAlignment - 1) : pBT->base; - - _FreeListRemove(pArena, pBT); - - if ((pArena->ui32PolicyFlags & RA_POLICY_NO_SPLIT_MASK) == RA_POLICY_NO_SPLIT) - { - goto nosplit; - } - - /* with uAlignment we might need to discard the front of this segment */ - if (aligned_base > pBT->base) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit(pBT, (RA_LENGTH_T)(aligned_base - pBT->base)); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Front split failed", __func__)); - /* Put pBT back in the list */ - _FreeListInsert(pArena, pBT); - return IMG_FALSE; - } - - _FreeListInsert(pArena, pBT); - pBT = pNeighbour; - } - - /* the segment might be too big, if so, discard the back of the segment */ - if (pBT->uSize > uSize) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit(pBT, uSize); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Back split failed", __func__)); - /* Put pBT back in the list */ - _FreeListInsert(pArena, pBT); - return IMG_FALSE; - } - - _FreeListInsert(pArena, pNeighbour); - } -nosplit: - pBT->type = btt_live; - - if (!HASH_Insert_Extended(pArena->pSegmentHash, &aligned_base, (uintptr_t)pBT)) - { - _FreeBT(pArena, pBT); - return IMG_FALSE; - } - - if (phPriv != NULL) - *phPriv = pBT->hPriv; - - *pBase = aligned_base; - - return IMG_TRUE; -} - -/*************************************************************************/ /*! -@Function _AttemptAllocAligned -@Description Attempt an allocation from an arena. -@Input pArena The arena. -@Input uSize The requested allocation size. -@Input uFlags Allocation flags -@Output phPriv The user references associated with - the imported segment. (optional) -@Input uAlignment Required uAlignment, or 0. - Must be a power of 2 if not 0 -@Output base Allocated resource base (non-optional, must not - be NULL) -@Return IMG_FALSE failure - IMG_TRUE success -*/ /**************************************************************************/ -static IMG_BOOL -_AttemptAllocAligned(RA_ARENA *pArena, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags, - RA_LENGTH_T uAlignment, - RA_BASE_T *base, - RA_PERISPAN_HANDLE *phPriv) /* this is the "per-import" private data */ -{ - - IMG_UINT32 index_low; - IMG_UINT32 index_high; - IMG_UINT32 i; - struct _BT_ *pBT = NULL; - - PVR_ASSERT(pArena!=NULL); - PVR_ASSERT(base != NULL); - - pArena->per_flags_buckets = PVRSRVSplay(uFlags, pArena->per_flags_buckets); - if ((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->uiFlags != uFlags)) - { - /* no chunks with these flags. */ - return IMG_FALSE; - } - - index_low = pvr_log2(uSize); - if (uAlignment) - { - index_high = pvr_log2(uSize + uAlignment - 1); - } - else - { - index_high = index_low; - } - - PVR_ASSERT(index_low < FREE_TABLE_LIMIT); - PVR_ASSERT(index_high < FREE_TABLE_LIMIT); - PVR_ASSERT(index_low <= index_high); - - if (unlikely((pArena->ui32PolicyFlags & RA_POLICY_BUCKET_MASK) == RA_POLICY_BUCKET_BEST_FIT)) - { - /* This policy ensures the selection of the first lowest size bucket that - * satisfies the request size is selected */ -#if defined(PVR_CTZLL) - i = PVR_CTZLL((~(((IMG_ELTS_MAPPINGS)1 << (index_low )) - 1)) & pArena->per_flags_buckets->bHasEltsMapping); -#else - i = index_low; -#endif - for ( ; (i < FREE_TABLE_LIMIT) && (pBT == NULL); ++i) - { - if (pArena->per_flags_buckets->buckets[i]) - { - pBT = find_chunk_in_bucket(pArena->per_flags_buckets->buckets[i], uSize, uAlignment, (unsigned int) ~0); - } - } - } - else - { -#if defined(PVR_CTZLL) - i = PVR_CTZLL((~(((IMG_ELTS_MAPPINGS)1 << (index_high + 1)) - 1)) & pArena->per_flags_buckets->bHasEltsMapping); -#else - for (i = index_high + 1; (i < FREE_TABLE_LIMIT) && (pArena->per_flags_buckets->buckets[i] == NULL); ++i) - { - } -#endif - PVR_ASSERT(i <= FREE_TABLE_LIMIT); - - if (i != FREE_TABLE_LIMIT) - { - /* since we start at index_high + 1, we are guaranteed to exit */ - pBT = find_chunk_in_bucket(pArena->per_flags_buckets->buckets[i], uSize, uAlignment, 1); - } - else - { - for (i = index_high; (i != index_low - 1) && (pBT == NULL); --i) - { - pBT = find_chunk_in_bucket(pArena->per_flags_buckets->buckets[i], uSize, uAlignment, (unsigned int) ~0); - } - } - } - - if (pBT == NULL) - { - return IMG_FALSE; - } - - return _AllocAlignSplit(pArena, pBT, uSize, uAlignment, base, phPriv); -} - -/*************************************************************************/ /*! -@Function _AttemptImportSpanAlloc -@Description Attempt to Import more memory and create a new span. - Function attempts to import more memory from the callback - provided at RA creation time, if successful the memory - will form a new span in the RA. -@Input pArena The arena. -@Input uRequestSize The requested allocation size. -@Input uImportMultiplier Import x-times more for future requests if - we have to import new memory. -@Input uImportFlags Flags influencing allocation policy. -@Input uAlignment The alignment requirements of the allocation - Required uAlignment, or 0. - Must be a power of 2 if not 0 -@Input pszAnnotation String to describe the allocation -@Output pImportBase Allocated import base - (non-optional, must not be NULL) -@Output pImportSize Allocated import size -@Output pImportBT Allocated import BT -@Return PVRSRV_OK - success -*/ /**************************************************************************/ -static PVRSRV_ERROR -_AttemptImportSpanAlloc(RA_ARENA *pArena, - RA_LENGTH_T uRequestSize, - IMG_UINT8 uImportMultiplier, - RA_FLAGS_T uImportFlags, - RA_LENGTH_T uAlignment, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *pImportBase, - RA_LENGTH_T *pImportSize, - BT **pImportBT) -{ - IMG_HANDLE hPriv; - RA_FLAGS_T uFlags = (uImportFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK); - BT *pBT; - PVRSRV_ERROR eError; - - *pImportSize = uRequestSize; - /* - Ensure that we allocate sufficient space to meet the uAlignment - constraint - */ - if (uAlignment > pArena->uQuantum) - { - *pImportSize += (uAlignment - pArena->uQuantum); - } - - /* apply over-allocation multiplier after all alignment adjustments */ - *pImportSize *= uImportMultiplier; - - /* ensure that we import according to the quanta of this arena */ - *pImportSize = (*pImportSize + pArena->uQuantum - 1) & ~(pArena->uQuantum - 1); - - eError = pArena->pImportAlloc(pArena->pImportHandle, - *pImportSize, uImportFlags, - pszAnnotation, - pImportBase, pImportSize, - &hPriv); - if (PVRSRV_OK != eError) - { - return eError; - } - - /* If we successfully import more resource, create a span to - * represent it else free the resource we imported. - */ - pBT = _InsertResourceSpan(pArena, *pImportBase, *pImportSize, uFlags); - if (pBT == NULL) - { - /* insufficient resources to insert the newly acquired span, - so free it back again */ - pArena->pImportFree(pArena->pImportHandle, *pImportBase, hPriv); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: name='%s', " - "size=0x%llx failed!", __func__, pArena->name, - (unsigned long long)uRequestSize)); - /* RA_Dump (arena); */ - - return PVRSRV_ERROR_RA_INSERT_RESOURCE_SPAN_FAILED; - } - - pBT->hPriv = hPriv; - *pImportBT = pBT; - - return eError; -} - -IMG_INTERNAL RA_ARENA * -RA_Create(IMG_CHAR *name, - RA_LOG2QUANTUM_T uLog2Quantum, - IMG_UINT32 ui32LockClass, - PFN_RA_ALLOC imp_alloc, - PFN_RA_FREE imp_free, - RA_PERARENA_HANDLE arena_handle, - IMG_UINT32 ui32PolicyFlags) -{ - RA_ARENA *pArena; - PVRSRV_ERROR eError; - - if (name == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter 'name' (NULL not accepted)", __func__)); - return NULL; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: name='%s'", __func__, name)); - - pArena = OSAllocMem(sizeof(*pArena)); - if (pArena == NULL) - { - goto arena_fail; - } - - eError = OSLockCreate(&pArena->hLock); - if (eError != PVRSRV_OK) - { - goto lock_fail; - } - - pArena->pSegmentHash = HASH_Create_Extended(MINIMUM_HASH_SIZE, sizeof(RA_BASE_T), HASH_Func_Default, HASH_Key_Comp_Default); - - if (pArena->pSegmentHash==NULL) - { - goto hash_fail; - } - - OSStringLCopy(pArena->name, name, RA_MAX_NAME_LENGTH); - pArena->pImportAlloc = (imp_alloc!=NULL) ? imp_alloc : &_RequestAllocFail; - pArena->pImportFree = imp_free; - pArena->pImportHandle = arena_handle; - pArena->pHeadSegment = NULL; - pArena->uQuantum = 1ULL << uLog2Quantum; - pArena->per_flags_buckets = NULL; - pArena->ui32LockClass = ui32LockClass; - pArena->ui32PolicyFlags = ui32PolicyFlags; - pArena->ui64TotalArenaSize = 0; - pArena->ui64FreeArenaSize = 0; - - PVR_ASSERT(is_arena_valid(pArena)); - return pArena; - -hash_fail: - OSLockDestroy(pArena->hLock); -lock_fail: - OSFreeMem(pArena); - /* not nulling pointer, out of scope */ -arena_fail: - return NULL; -} - -static void _LogRegionCreation(const char *pszMemType, - IMG_UINT64 ui64CpuPA, - IMG_UINT64 ui64DevPA, - IMG_UINT64 ui64Size) -{ -#if !defined(DEBUG) - PVR_UNREFERENCED_PARAMETER(pszMemType); - PVR_UNREFERENCED_PARAMETER(ui64CpuPA); - PVR_UNREFERENCED_PARAMETER(ui64DevPA); - PVR_UNREFERENCED_PARAMETER(ui64Size); -#else - if ((ui64CpuPA != 0) && (ui64DevPA != 0) && (ui64CpuPA != ui64DevPA)) - { - PVR_DPF((PVR_DBG_MESSAGE, - "Creating RA for \"%s\" memory" - " - Cpu PA 0x%016" IMG_UINT64_FMTSPECx "-0x%016" IMG_UINT64_FMTSPECx - " - Dev PA 0x%016" IMG_UINT64_FMTSPECx "-0x%016" IMG_UINT64_FMTSPECx, - pszMemType, - ui64CpuPA, ui64CpuPA + ui64Size, - ui64DevPA, ui64DevPA + ui64Size)); - } - else - { - __maybe_unused IMG_UINT64 ui64PA = - ui64CpuPA != 0 ? ui64CpuPA : ui64DevPA; - __maybe_unused const IMG_CHAR *pszAddrType = - ui64CpuPA == ui64DevPA ? "Cpu/Dev" : (ui64CpuPA != 0 ? "Cpu" : "Dev"); - - PVR_DPF((PVR_DBG_MESSAGE, - "Creating RA for \"%s\" memory - %s PA 0x%016" - IMG_UINT64_FMTSPECx "-0x%016" IMG_UINT64_FMTSPECx, - pszMemType, pszAddrType, - ui64PA, ui64PA + ui64Size)); - } -#endif -} - -IMG_INTERNAL RA_ARENA * -RA_Create_With_Span(IMG_CHAR *name, - RA_LOG2QUANTUM_T uLog2Quantum, - IMG_UINT64 ui64CpuBase, - IMG_UINT64 ui64SpanDevBase, - IMG_UINT64 ui64SpanSize) -{ - RA_ARENA *psRA; - IMG_BOOL bSuccess; - - psRA = RA_Create(name, - uLog2Quantum, /* Use OS page size, keeps things simple */ - RA_LOCKCLASS_0, /* This arena doesn't use any other arenas. */ - NULL, /* No Import */ - NULL, /* No free import */ - NULL, /* No import handle */ - RA_POLICY_DEFAULT); /* No restriction on import splitting */ - PVR_LOG_GOTO_IF_FALSE(psRA != NULL, "RA_Create() failed", return_); - - bSuccess = RA_Add(psRA, (RA_BASE_T) ui64SpanDevBase, (RA_LENGTH_T) ui64SpanSize, 0, NULL); - PVR_LOG_GOTO_IF_FALSE(bSuccess, "RA_Add() failed", cleanup_); - - _LogRegionCreation(name, ui64CpuBase, ui64SpanDevBase, ui64SpanSize); - - return psRA; - -cleanup_: - RA_Delete(psRA); -return_: - return NULL; -} - -IMG_INTERNAL void -RA_Delete(RA_ARENA *pArena) -{ - IMG_UINT32 uIndex; - IMG_BOOL bWarn = IMG_TRUE; - - PVR_ASSERT(pArena != NULL); - - if (pArena == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter - pArena", __func__)); - return; - } - - PVR_ASSERT(is_arena_valid(pArena)); - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: name='%s'", __func__, pArena->name)); - - while (pArena->pHeadSegment != NULL) - { - BT *pBT = pArena->pHeadSegment; - - if (pBT->type != btt_free) - { - if (bWarn) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Allocations still exist in the arena that is being destroyed", __func__)); - PVR_DPF((PVR_DBG_ERROR, "%s: Likely Cause: client drivers not freeing allocations before destroying devmem context", __func__)); - PVR_DPF((PVR_DBG_ERROR, "%s: base = 0x%llx size=0x%llx", __func__, - (unsigned long long)pBT->base, (unsigned long long)pBT->uSize)); - PVR_DPF((PVR_DBG_ERROR, "%s: This warning will be issued only once for the first allocation found!", __func__)); - bWarn = IMG_FALSE; - } - } - else - { - _FreeListRemove(pArena, pBT); - } - - _SegmentListRemove(pArena, pBT); - OSFreeMem(pBT); - /* not nulling original pointer, it has changed */ - } - - while (pArena->per_flags_buckets != NULL) - { - for (uIndex=0; uIndexper_flags_buckets->buckets[uIndex] == NULL); - } - - pArena->per_flags_buckets = PVRSRVDelete(pArena->per_flags_buckets->uiFlags, pArena->per_flags_buckets); - } - - HASH_Delete(pArena->pSegmentHash); - OSLockDestroy(pArena->hLock); - OSFreeMem(pArena); - /* not nulling pointer, copy on stack */ -} - -IMG_INTERNAL IMG_BOOL -RA_Add(RA_ARENA *pArena, - RA_BASE_T base, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags, - RA_PERISPAN_HANDLE hPriv) -{ - struct _BT_* bt; - PVR_ASSERT(pArena != NULL); - PVR_ASSERT(uSize != 0); - - if (pArena == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter - pArena", __func__)); - return IMG_FALSE; - } - - if (uSize == 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid size 0 added to arena %s", __func__, pArena->name)); - return IMG_FALSE; - } - - OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass); - PVR_ASSERT(is_arena_valid(pArena)); - PVR_DPF((PVR_DBG_MESSAGE, "%s: name='%s', " - "base=0x%llx, size=0x%llx", __func__, pArena->name, - (unsigned long long)base, (unsigned long long)uSize)); - - uSize = (uSize + pArena->uQuantum - 1) & ~(pArena->uQuantum - 1); - bt = _InsertResource(pArena, base, uSize, uFlags); - if (bt != NULL) - { - bt->hPriv = hPriv; - } - - PVR_ASSERT(is_arena_valid(pArena)); - - pArena->ui64TotalArenaSize += uSize; - pArena->ui64FreeArenaSize += uSize; - OSLockRelease(pArena->hLock); - - return bt != NULL; -} - -IMG_INTERNAL PVRSRV_ERROR -RA_Alloc(RA_ARENA *pArena, - RA_LENGTH_T uRequestSize, - IMG_UINT8 uImportMultiplier, - RA_FLAGS_T uImportFlags, - RA_LENGTH_T uAlignment, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *base, - RA_LENGTH_T *pActualSize, - RA_PERISPAN_HANDLE *phPriv) -{ - PVRSRV_ERROR eError; - IMG_BOOL bResult; - RA_LENGTH_T uSize = uRequestSize; - RA_FLAGS_T uFlags = (uImportFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK); - - if (pArena == NULL || uImportMultiplier == 0 || uSize == 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: One of the necessary parameters is 0", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass); - PVR_ASSERT(is_arena_valid(pArena)); - - if (pActualSize != NULL) - { - *pActualSize = uSize; - } - - /* Must be a power of 2 or 0 */ - PVR_ASSERT((uAlignment == 0) || (uAlignment & (uAlignment - 1)) == 0); - - PVR_DPF((PVR_DBG_MESSAGE, - "%s: arena='%s', size=0x%llx(0x%llx), " - "alignment=0x%llx", __func__, pArena->name, - (unsigned long long)uSize, (unsigned long long)uRequestSize, - (unsigned long long)uAlignment)); - - /* if allocation failed then we might have an import source which - can provide more resource, else we will have to fail the - allocation to the caller. */ - bResult = _AttemptAllocAligned(pArena, uSize, uFlags, uAlignment, base, phPriv); - if (!bResult) - { - RA_BASE_T uImportBase; - RA_LENGTH_T uImportSize; - BT *pBT = NULL; - - eError = _AttemptImportSpanAlloc(pArena, - uSize, - uImportMultiplier, - uFlags, - uAlignment, - pszAnnotation, - &uImportBase, - &uImportSize, - &pBT); - if (eError != PVRSRV_OK) - { - OSLockRelease(pArena->hLock); - return eError; - } - - bResult = _AttemptAllocAligned(pArena, uSize, uFlags, uAlignment, base, phPriv); - if (!bResult) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: name='%s' second alloc failed!", - __func__, pArena->name)); - - /* - On failure of _AttemptAllocAligned() depending on the exact point - of failure, the imported segment may have been used and freed, or - left untouched. If the later, we need to return it. - */ - _FreeBT(pArena, pBT); - - OSLockRelease(pArena->hLock); - return PVRSRV_ERROR_RA_ATTEMPT_ALLOC_ALIGNED_FAILED; - } - else - { - /* Check if the new allocation was in the span we just added... */ - if (*base < uImportBase || *base > (uImportBase + uImportSize)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: name='%s' alloc did not occur in the imported span!", - __func__, pArena->name)); - - /* - Remove the imported span which should not be in use (if it is then - that is okay, but essentially no span should exist that is not used). - */ - _FreeBT(pArena, pBT); - } - else - { - pArena->ui64FreeArenaSize += uImportSize; - pArena->ui64TotalArenaSize += uImportSize; - } - } - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: name='%s', size=0x%llx, " - "*base=0x%llx = %d", __func__, pArena->name, (unsigned long long)uSize, - (unsigned long long)*base, bResult)); - - PVR_ASSERT(is_arena_valid(pArena)); - - pArena->ui64FreeArenaSize -= uSize; - - OSLockRelease(pArena->hLock); - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function RA_Find_BT_VARange -@Description To find the boundary tag associated with the given device - virtual address. -@Input pArena The arena -@input base Allocated base resource -@Input uRequestSize The size of resource segment requested. -@Input uImportFlags Flags influencing allocation policy. -@Return Boundary Tag - success, NULL on failure -*/ /**************************************************************************/ -static BT *RA_Find_BT_VARange(RA_ARENA *pArena, - RA_BASE_T base, - RA_LENGTH_T uRequestSize, - RA_FLAGS_T uImportFlags) -{ - IMG_PSPLAY_TREE psSplaynode; - BT *pBT = pArena->pHeadSegment; - IMG_UINT32 uIndex; - - uIndex = pvr_log2 (uRequestSize); - - /* Find the splay node associated with these import flags */ - psSplaynode = PVRSRVFindNode(uImportFlags, pArena->per_flags_buckets); - - if (psSplaynode == NULL) - { - return NULL; - } - - /* Find the free Boundary Tag from the bucket that holds the requested range */ - while (uIndex < FREE_TABLE_LIMIT) - { - pBT = psSplaynode->buckets[uIndex]; - - while (pBT) - { - if ((pBT->base <= base) && ((pBT->base + pBT->uSize) >= (base + uRequestSize))) - { - if (pBT->type == btt_free) - { - return pBT; - } - else - { - PVR_ASSERT(pBT->type == btt_free); - } - } - else{ - pBT = pBT->next_free; - } - } - -#if defined(PVR_CTZLL) - /* This could further be optimised to get the next valid bucket */ - while (!(psSplaynode->bHasEltsMapping & (1ULL << ++uIndex))); -#else - uIndex++; -#endif - } - - return NULL; -} - -IMG_INTERNAL PVRSRV_ERROR -RA_Alloc_Range(RA_ARENA *pArena, - RA_LENGTH_T uRequestSize, - RA_FLAGS_T uImportFlags, - RA_LENGTH_T uAlignment, - RA_BASE_T base, - RA_LENGTH_T *pActualSize) -{ - RA_LENGTH_T uSize = uRequestSize; - BT *pBT = NULL; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (pArena == NULL || uSize == 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: One of the necessary parameters is 0", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass); - PVR_ASSERT(is_arena_valid(pArena)); - - /* Align the requested size to the Arena Quantum */ - uSize = ((uSize + pArena->uQuantum - 1) & ~(pArena->uQuantum - 1)); - - /* Must be a power of 2 or 0 */ - PVR_ASSERT((uAlignment == 0) || (uAlignment & (uAlignment - 1)) == 0); - - if (uAlignment > 1) - { - if (base != ((base + uAlignment - 1) & ~(uAlignment - 1))) - { - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, unlock_); - } - } - - /* Find if the segment in the range exists and is free - * Check if the segment can be split - * Find the bucket that points to this segment - * Find the free segment is in the free list - * remove the free segment - * split the segment into three segments one prior free, alloc range, - * free segment after the range. - * remove the allocated range segment from the free list - * hook up the prior and after segments back to free list - * For each free, find the bucket the segment should go to - */ - - pBT = RA_Find_BT_VARange(pArena, base, uSize, uImportFlags); - - if (pBT == NULL) - { - PVR_GOTO_WITH_ERROR(eError, - PVRSRV_ERROR_RA_REQUEST_VIRT_ADDR_FAIL, - unlock_); - } - - /* Remove the boundary tag from the free list */ - _FreeListRemove (pArena, pBT); - - /* if requested VA start in the middle of the BT, split the BT accordingly */ - if (base > pBT->base) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit (pBT, (RA_LENGTH_T)(base - pBT->base)); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour == NULL) - { - /* Put pBT back in the list */ - _FreeListInsert (pArena, pBT); - PVR_LOG_GOTO_WITH_ERROR("_SegmentSplit (1)", eError, - PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL, - unlock_); - } - - /* Insert back the free BT to the free list */ - _FreeListInsert(pArena, pBT); - pBT = pNeighbour; - } - - /* the segment might be too big, if so, discard the back of the segment */ - if (pBT->uSize > uSize) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit(pBT, uSize); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour == NULL) - { - /* Put pBT back in the list */ - _FreeListInsert (pArena, pBT); - PVR_LOG_GOTO_WITH_ERROR("_SegmentSplit (2)", eError, - PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL, - unlock_); - } - - /* Insert back the free BT to the free list */ - _FreeListInsert (pArena, pNeighbour); - } - - pBT->type = btt_live; - - if (!HASH_Insert_Extended (pArena->pSegmentHash, &base, (uintptr_t)pBT)) - { - _FreeBT (pArena, pBT); - PVR_GOTO_WITH_ERROR(eError, - PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED, - unlock_); - } - - if (pActualSize != NULL) - { - *pActualSize = uSize; - } - - pArena->ui64FreeArenaSize -= uSize; - -unlock_: - OSLockRelease(pArena->hLock); - - return eError; -} - -IMG_INTERNAL void -RA_Free(RA_ARENA *pArena, RA_BASE_T base) -{ - BT *pBT; - - PVR_ASSERT(pArena != NULL); - - if (pArena == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter - pArena", __func__)); - return; - } - - OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass); - PVR_ASSERT(is_arena_valid(pArena)); - - PVR_DPF((PVR_DBG_MESSAGE, "%s: name='%s', base=0x%llx", __func__, pArena->name, - (unsigned long long)base)); - - pBT = (BT *) HASH_Remove_Extended(pArena->pSegmentHash, &base); - PVR_ASSERT(pBT != NULL); - - if (pBT) - { - pArena->ui64FreeArenaSize += pBT->uSize; - - PVR_ASSERT(pBT->base == base); - _FreeBT(pArena, pBT); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: no resource span found for given base (0x%llX) in arena %s", - __func__, (unsigned long long) base, pArena->name)); - } - - PVR_ASSERT(is_arena_valid(pArena)); - OSLockRelease(pArena->hLock); -} - -IMG_INTERNAL void -RA_Get_Usage_Stats(RA_ARENA *pArena, PRA_USAGE_STATS psRAStats) -{ - psRAStats->ui64TotalArenaSize = pArena->ui64TotalArenaSize; - psRAStats->ui64FreeArenaSize = pArena->ui64FreeArenaSize; -} - -/* #define _DBG(...) PVR_LOG((__VA_ARGS__)) */ -#define _DBG(...) - -IMG_INTERNAL RA_ARENA_ITERATOR * -RA_IteratorAcquire(RA_ARENA *pArena, IMG_BOOL bIncludeFreeSegments) -{ - RA_ARENA_ITERATOR *pIter = OSAllocMem(sizeof(*pIter)); - PVR_LOG_RETURN_IF_FALSE(pIter != NULL, "OSAllocMem", NULL); - - OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass); - - pIter->pArena = pArena; - pIter->bIncludeFreeSegments = bIncludeFreeSegments; - - RA_IteratorReset(pIter); - - return pIter; -} - -IMG_INTERNAL void -RA_IteratorRelease(RA_ARENA_ITERATOR *pIter) -{ - PVR_ASSERT(pIter != NULL); - - if (pIter == NULL) - { - return; - } - - OSLockRelease(pIter->pArena->hLock); - - OSFreeMem(pIter); -} - -IMG_INTERNAL void -RA_IteratorReset(RA_ARENA_ITERATOR *pIter) -{ - BT *pNext; - - PVR_ASSERT(pIter != NULL); - - pNext = pIter->pArena->pHeadSegment; - - /* find next element if we're not including the free ones */ - if (!pIter->bIncludeFreeSegments) - { - while (pNext != NULL && pNext->type != btt_live) - { - _DBG("(%s()) skipping segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, (void *) pNext->base, pNext->uSize, - pNext->type); - pNext = pNext->pNextSegment; - } - } - - _DBG("(%s()) current segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, - pNext != NULL ? (void *) pNext->base : NULL, - pNext != NULL ? pNext->uSize : 0, - pNext != NULL ? pNext->type : 0); - - /* if bIncludeFreeSegments then pNext here is either a valid pointer to - * "live" segment or NULL and if !bIncludeFreeSegments then it's either - * a valid pointer to any next segment or NULL */ - pIter->pCurrent = pNext; -} - -IMG_INTERNAL IMG_BOOL -RA_IteratorNext(RA_ARENA_ITERATOR *pIter, RA_ITERATOR_DATA *pData) -{ - BT *pNext; - - PVR_ASSERT(pIter != NULL); - - if (pIter == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "pIter in %s() is NULL", __func__)); - return IMG_FALSE; - } - - if (pIter->pCurrent == NULL) - { - return IMG_FALSE; - } - - pNext = pIter->pCurrent; - - _DBG("(%s()) current segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, (void *) pNext->base, pNext->uSize, - pNext->type); - - pData->uiAddr = pIter->pCurrent->base; - pData->uiSize = pIter->pCurrent->uSize; - pData->bFree = pIter->pCurrent->type == btt_free; - - /* combine contiguous segments */ - while ((pNext = pNext->pNextSegment) != NULL && - pNext->type == btt_live && - pNext->base == pData->uiAddr + pData->uiSize) - { - _DBG("(%s()) combining segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, (void *) pNext->base, pNext->uSize, - pNext->type); - pData->uiSize += pNext->uSize; - } - - /* advance to next */ - if (!pIter->bIncludeFreeSegments) - { - while (pNext != NULL && pNext->type != btt_live) - { - _DBG("(%s()) skipping segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, (void *) pNext->base, pNext->uSize, - pNext->type); - pNext = pNext->pNextSegment; - } - } - - _DBG("(%s()) next segment=%px, size=0x%" IMG_UINT64_FMTSPECx ", " - "type=%u", __func__, - pNext != NULL ? (void *) pNext->base : NULL, - pNext != NULL ? pNext->uSize : 0, - pNext != NULL ? pNext->type : 0); - - /* if bIncludeFreeSegments then pNext here is either a valid pointer to - * "live" segment or NULL and if !bIncludeFreeSegments then it's either - * a valid pointer to any next segment or NULL */ - pIter->pCurrent = pNext; - - return IMG_TRUE; -} - -IMG_INTERNAL PVRSRV_ERROR -RA_BlockDump(RA_ARENA *pArena, void (*pfnLogDump)(void*, IMG_CHAR*, ...), void *pPrivData) -{ - RA_ARENA_ITERATOR *pIter = NULL; - RA_ITERATOR_DATA sIterData; - const IMG_UINT32 uiLineWidth = 64; - - IMG_UINT32 **papRegionArray = NULL; - IMG_UINT32 uiRegionCount = 0; - - const IMG_UINT32 uiChunkSize = 32; /* 32-bit chunks */ - const IMG_UINT32 uiChunkCount = (uiLineWidth / uiChunkSize) * 2; /* This should equal 2 or a multiple of 2 */ - const IMG_UINT32 uiRegionSize = uiChunkSize * uiChunkCount; - - IMG_UINT32 uiRecognisedQuantum = 0; - - IMG_UINT32 uiLastBase = 0; - IMG_UINT32 uiLastSize = 0; - - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* -- papRegionArray Structure -- - * papRegionArray Indexes - * | Chunk 0 Chunk 1 Chunk 2 Chunk 3 - * v |------------|------------|------------|------------| - * [0] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | -- | - * [1] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | | - * [2] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | | - * [3] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | | Regions - * [4] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | | - * [5] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | | - * [6] -> | 0000000000 | 0000000000 | 0000000000 | 0000000000 | -- | - * ... - */ - - if (pArena == NULL || pfnLogDump == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - pIter = RA_IteratorAcquire(pArena, IMG_FALSE); - PVR_LOG_RETURN_IF_NOMEM(pIter, "RA_IteratorAcquire"); - - uiRecognisedQuantum = pArena->uQuantum > 0 ? pArena->uQuantum : 4096; - - while (RA_IteratorNext(pIter, &sIterData)) - { - if (sIterData.uiAddr >= uiLastBase) - { - uiLastBase = sIterData.uiAddr; - uiLastSize = sIterData.uiSize; - } - } - - uiRegionCount = ((uiLastBase + uiLastSize) / uiRecognisedQuantum) / uiRegionSize; - if (((uiLastBase + uiLastSize) / uiRecognisedQuantum) % uiRegionSize != 0 - || uiRegionCount == 0) - { - uiRegionCount += 1; - } - - papRegionArray = OSAllocZMem(sizeof(IMG_UINT32*) * uiRegionCount); - PVR_LOG_GOTO_IF_NOMEM(papRegionArray, eError, cleanup_array); - - RA_IteratorReset(pIter); - - while (RA_IteratorNext(pIter, &sIterData)) - { - IMG_UINT32 uiAddrRegionIdx = 0; - IMG_UINT32 uiAddrRegionOffset = 0; - IMG_UINT32 uiAddrChunkIdx = 0; - IMG_UINT32 uiAddrChunkOffset = 0; - IMG_UINT32 uiAddrChunkShift; /* The bit-shift needed to fill the chunk */ - - IMG_UINT32 uiQuantisedSize; - IMG_UINT32 uiQuantisedSizeMod; - IMG_UINT32 uiAllocLastRegionIdx = 0; /* The last region that this alloc appears in */ - IMG_UINT32 uiAllocChunkSize = 0; /* The number of chunks this alloc spans */ - - IMG_INT32 iBitSetCount = 0; - IMG_INT32 iOverflowCheck = 0; - IMG_INT32 iOverflow = 0; - IMG_UINT32 uiRegionIdx = 0; - IMG_UINT32 uiChunkIdx = 0; - -#if defined(__KERNEL__) && defined(__linux__) - IMG_UINT64 uiDataDivRecQuant = sIterData.uiSize; - uiQuantisedSizeMod = do_div(uiDataDivRecQuant, uiRecognisedQuantum); - uiQuantisedSize = (IMG_UINT32)uiDataDivRecQuant; - - uiDataDivRecQuant = sIterData.uiAddr; - do_div(uiDataDivRecQuant, uiRecognisedQuantum); - uiAddrRegionOffset = do_div(uiDataDivRecQuant, uiRegionSize); - uiAddrRegionIdx = (IMG_UINT32)uiDataDivRecQuant; - - uiDataDivRecQuant = sIterData.uiAddr; - do_div(uiDataDivRecQuant, uiRecognisedQuantum); -#else - IMG_UINT64 uiDataDivRecQuant = sIterData.uiAddr / uiRecognisedQuantum; - uiAddrRegionIdx = uiDataDivRecQuant / uiRegionSize; - uiAddrRegionOffset = uiDataDivRecQuant % uiRegionSize; - - uiQuantisedSize = sIterData.uiSize / uiRecognisedQuantum; - uiQuantisedSizeMod = sIterData.uiSize % uiRecognisedQuantum; -#endif - uiAddrChunkIdx = uiAddrRegionOffset / uiChunkSize; - uiAddrChunkOffset = uiAddrRegionOffset % uiChunkSize; - uiAddrChunkShift = uiChunkSize - uiAddrChunkOffset; - uiRegionIdx = uiAddrRegionIdx; - uiChunkIdx = uiAddrChunkIdx; - - if ((uiQuantisedSize == 0) || (uiQuantisedSizeMod != 0)) - { - uiQuantisedSize += 1; - } - -#if defined(__KERNEL__) && defined(__linux__) - uiDataDivRecQuant += uiQuantisedSize - 1; - do_div(uiDataDivRecQuant, uiRegionSize); - uiAllocLastRegionIdx = (IMG_UINT32)uiDataDivRecQuant; -#else - uiAllocLastRegionIdx = - (uiDataDivRecQuant + uiQuantisedSize - 1) / uiRegionSize; -#endif - uiAllocChunkSize = (uiAddrChunkOffset + uiQuantisedSize) / uiChunkSize; - - if ((uiAddrChunkOffset + uiQuantisedSize) % uiChunkSize > 0) - { - uiAllocChunkSize += 1; - } - - iBitSetCount = uiQuantisedSize; - iOverflowCheck = uiQuantisedSize - uiAddrChunkShift; - - if (iOverflowCheck > 0) - { - iOverflow = iOverflowCheck; - iBitSetCount = uiQuantisedSize - iOverflow; - } - - /** - * Allocate memory to represent the chunks for each region the allocation - * spans. If one was already allocated before don't do it again. - */ - for (i = 0; uiAddrRegionIdx + i <= uiAllocLastRegionIdx; i++) - { - if (papRegionArray[uiAddrRegionIdx + i] == NULL) - { - papRegionArray[uiAddrRegionIdx + i] = OSAllocZMem(sizeof(IMG_UINT32) * uiChunkCount); - PVR_LOG_GOTO_IF_NOMEM(papRegionArray[uiAddrRegionIdx + i], eError, cleanup_regions); - } - } - - for (i = 0; i < uiAllocChunkSize; i++) - { - if (uiChunkIdx >= uiChunkCount) - { - uiRegionIdx++; - uiChunkIdx = 0; - } - - if ((IMG_UINT32)iBitSetCount != uiChunkSize) - { - IMG_UINT32 uiBitMask = 0; - - uiBitMask = (1U << iBitSetCount) - 1; - uiBitMask <<= (uiAddrChunkShift - iBitSetCount); - - papRegionArray[uiRegionIdx][uiChunkIdx] |= uiBitMask; - } - else - { - papRegionArray[uiRegionIdx][uiChunkIdx] |= 0xFFFFFFFF; - } - - uiChunkIdx++; - iOverflow -= uiChunkSize; - iBitSetCount = iOverflow >= 0 ? uiChunkSize : uiChunkSize + iOverflow; - if (iOverflow < 0) - { - uiAddrChunkShift = 32; - } - } - } - - RA_IteratorRelease(pIter); - - pfnLogDump(pPrivData, "~~~ '%s' Resource Arena Block Dump", pArena->name); - pfnLogDump(pPrivData, " Block Size: %uB", uiRecognisedQuantum); - pfnLogDump(pPrivData, - " Span Memory Usage: %"IMG_UINT64_FMTSPEC"B" - " Free Span Memory: %"IMG_UINT64_FMTSPEC"B", - pArena->ui64TotalArenaSize, - pArena->ui64FreeArenaSize); - pfnLogDump(pPrivData, - "==============================================================================="); - - for (i = 0; i < uiRegionCount; i++) - { - static IMG_BOOL bEmptyRegion = IMG_FALSE; - if (papRegionArray[i] != NULL) - { - IMG_CHAR pszLine[65]; - IMG_UINT32 j; - - bEmptyRegion = IMG_FALSE; - pszLine[64] = '\0'; - - for (j = 0; j < uiChunkCount; j+=2) - { - IMG_UINT8 uiBit = 0; - IMG_UINT32 k; - IMG_UINT64 uiLineAddress = - (i * uiRegionSize + (j >> 1) * uiLineWidth) * uiRecognisedQuantum; - - /** - * Move through each of the 32 bits in the chunk and check their - * value. If it is 1 we set the corresponding character to '#', - * otherwise it is set to '.' representing empty space - */ - for (k = 1 << 31; k != 0; k >>= 1) - { - pszLine[uiBit] = papRegionArray[i][j] & k ? '#' : '.'; - pszLine[32 + uiBit] = papRegionArray[i][j+1] & k ? '#' : '.'; - uiBit++; - } - - pfnLogDump(pPrivData, - "| 0x%08"IMG_UINT64_FMTSPECx" | %s", - uiLineAddress, - pszLine); - } - OSFreeMem(papRegionArray[i]); - } - else - { - /* We only print this once per gap of n regions */ - if (!bEmptyRegion) - { - pfnLogDump(pPrivData, " ...."); - bEmptyRegion = IMG_TRUE; - } - } - } - OSFreeMem(papRegionArray); - return eError; - -cleanup_regions: - for (i = 0; i < uiRegionCount; i++) - { - if (papRegionArray[i] != NULL) - { - OSFreeMem(papRegionArray[i]); - } - } - -cleanup_array: - OSFreeMem(papRegionArray); - RA_IteratorRelease(pIter); - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/ra.h b/drivers/gpu/drm/img-rogue/1.17/ra.h deleted file mode 100644 index 0d96bdf175d85..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ra.h +++ /dev/null @@ -1,386 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Resource Allocator API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RA_H -#define RA_H - -#include "img_types.h" -#include "pvrsrv_error.h" - -#define RA_MAX_NAME_LENGTH 20 - -/* Resource arena. - * struct _RA_ARENA_ deliberately opaque - */ -typedef struct _RA_ARENA_ RA_ARENA; //PRQA S 3313 - -/* Resource arena's iterator. - * struct _RA_ARENA_ITERATOR_ deliberately opaque - */ -typedef struct _RA_ARENA_ITERATOR_ RA_ARENA_ITERATOR; - -typedef struct _RA_ITERATOR_DATA_ { - IMG_UINT64 uiAddr; - IMG_UINT64 uiSize; - IMG_BOOL bFree; -} RA_ITERATOR_DATA; - -/* Resource arena usage statistics. - * struct _RA_USAGE_STATS - */ -typedef struct _RA_USAGE_STATS { - IMG_UINT64 ui64TotalArenaSize; - IMG_UINT64 ui64FreeArenaSize; -}RA_USAGE_STATS, *PRA_USAGE_STATS; - -/* - * Per-Arena handle - this is private data for the caller of the RA. - * The RA knows nothing about this data. It is given it in RA_Create, and - * promises to pass it to calls to the ImportAlloc and ImportFree callbacks - */ -typedef IMG_HANDLE RA_PERARENA_HANDLE; -/* - * Per-Import handle - this is private data for the caller of the RA. - * The RA knows nothing about this data. It is given it on a per-import basis, - * basis, either the "initial" import at RA_Create time, or further imports - * via the ImportAlloc callback. It sends it back via the ImportFree callback, - * and also provides it in answer to any RA_Alloc request to signify from - * which "import" the allocation came. - */ -typedef IMG_HANDLE RA_PERISPAN_HANDLE; - -typedef IMG_UINT64 RA_BASE_T; -typedef IMG_UINT32 RA_LOG2QUANTUM_T; -typedef IMG_UINT64 RA_LENGTH_T; - -/* Lock classes: describes the level of nesting between different arenas. */ -#define RA_LOCKCLASS_0 0 -#define RA_LOCKCLASS_1 1 -#define RA_LOCKCLASS_2 2 - -#define RA_NO_IMPORT_MULTIPLIER 1 - -/* - * Allocation Policies that govern the resource areas. - * */ - -/* --- Resource allocation policy definitions --- -* | 31.........4|......3....|........2.............|1...................0| -* | Reserved | No split | Area bucket selection| Alloc node selection| -*/ - -/* - * Fast allocation policy allows to pick the first node - * that satisfies the request. - * It is the default policy for all arenas. - * */ -#define RA_POLICY_ALLOC_FAST (0U) -/* - * Optimal allocation policy allows to pick the lowest size node - * that satisfies the request. This picking policy helps in reducing the fragmentation. - * This minimises the necessity to split the nodes more often as the optimal - * ones are picked. - * As a result any future higher size allocation requests are likely to succeed - */ -#define RA_POLICY_ALLOC_OPTIMAL (1U) -#define RA_POLICY_ALLOC_NODE_SELECT_MASK (3U) - -/* - * Bucket selection policies - * */ -/* Assured bucket policy makes sure the selected bucket is guaranteed - * to satisfy the given request. Generally Nodes picked up from such a - * bucket need to be further split. However picking node that belongs to this - * bucket is likely to succeed and thus promises better response times */ -#define RA_POLICY_BUCKET_ASSURED_FIT (0U) -/* - * Best fit bucket policy selects a bucket with free nodes that are likely - * to satisfy the request and nodes that are close to the requested size. - * Nodes picked up from this bucket may likely to satisfy the request but not - * guaranteed. Failing to satisfy the request from this bucket mean further - * higher size buckets are selected in the later iterations till the request - * is satisfied. - * - * Hence response times may vary depending on availability of free nodes - * that satisfy the request. - * */ -#define RA_POLICY_BUCKET_BEST_FIT (4U) -#define RA_POLICY_BUCKET_MASK (4U) - -/* This flag ensures the imports will not be split up and Allocations will always get - * their own import - */ -#define RA_POLICY_NO_SPLIT (8U) -#define RA_POLICY_NO_SPLIT_MASK (8U) - -/* - * Default Arena Policy - * */ -#define RA_POLICY_DEFAULT (RA_POLICY_ALLOC_FAST | RA_POLICY_BUCKET_ASSURED_FIT) - -/* - * Flags in an "import" must match the flags for an allocation - */ -typedef IMG_UINT64 RA_FLAGS_T; - -/*************************************************************************/ /*! -@Function Callback function PFN_RA_ALLOC -@Description RA import allocate function -@Input RA_PERARENA_HANDLE RA handle -@Input RA_LENGTH_T Request size -@Input RA_FLAGS_T RA flags -@Input IMG_CHAR Annotation -@Input RA_BASE_T Allocation base -@Input RA_LENGTH_T Actual size -@Input RA_PERISPAN_HANDLE Per import private data -@Return PVRSRV_ERROR PVRSRV_OK or error code -*/ /**************************************************************************/ -typedef PVRSRV_ERROR (*PFN_RA_ALLOC)(RA_PERARENA_HANDLE, - RA_LENGTH_T, - RA_FLAGS_T, - const IMG_CHAR*, - RA_BASE_T*, - RA_LENGTH_T*, - RA_PERISPAN_HANDLE*); - -/*************************************************************************/ /*! -@Function Callback function PFN_RA_FREE -@Description RA free imported allocation -@Input RA_PERARENA_HANDLE RA handle -@Input RA_BASE_T Allocation base -@Output RA_PERISPAN_HANDLE Per import private data -*/ /**************************************************************************/ -typedef void (*PFN_RA_FREE)(RA_PERARENA_HANDLE, - RA_BASE_T, - RA_PERISPAN_HANDLE); - -/* - * @Function RA_Create - * - * @Description To create a resource arena. - * - * @Input name - the name of the arena for diagnostic purposes. - * @Input uLog2Quantum - the arena allocation quantum. - * @Input ui32LockClass - the lock class level this arena uses. - * @Input imp_alloc - a resource allocation callback or 0. - * @Input imp_free - a resource de-allocation callback or 0. - * @Input per_arena_handle - private handle passed to alloc and free or 0. - * @Input ui32PlicyFlags - Policies that govern the arena. - * @Return pointer to arena, or NULL. - */ -RA_ARENA * -RA_Create(IMG_CHAR *name, - /* subsequent imports: */ - RA_LOG2QUANTUM_T uLog2Quantum, - IMG_UINT32 ui32LockClass, - PFN_RA_ALLOC imp_alloc, - PFN_RA_FREE imp_free, - RA_PERARENA_HANDLE per_arena_handle, - IMG_UINT32 ui32PolicyFlags); - -/* - * @Function RA_Create_With_Span - * - * @Description - * - * Create a resource arena and initialises it, with a given resource span. - * - * @Input name - String briefly describing the RA's purpose. - * @Input uLog2Quantum - the arena allocation quantum. - * @Input ui64CpuBase - CPU Physical Base Address of the RA. - * @Input ui64SpanDevBase - Device Physical Base Address of the RA. - * @Input ui64SpanSize - Size of the span to add to the created RA. - * @Return pointer to arena, or NULL. -*/ -RA_ARENA * -RA_Create_With_Span(IMG_CHAR *name, - RA_LOG2QUANTUM_T uLog2Quantum, - IMG_UINT64 ui64CpuBase, - IMG_UINT64 ui64SpanDevBase, - IMG_UINT64 ui64SpanSize); - -/* - * @Function RA_Delete - * - * @Description - * - * To delete a resource arena. All resources allocated from the arena - * must be freed before deleting the arena. - * - * @Input pArena - the arena to delete. - * @Return None - */ -void -RA_Delete(RA_ARENA *pArena); - -/* - * @Function RA_Add - * - * @Description - * - * To add a resource span to an arena. The span must not overlap with - * any span previously added to the arena. - * - * @Input pArena - the arena to add a span into. - * @Input base - the base of the span. - * @Input uSize - the extent of the span. - * @Input hPriv - handle associated to the span (reserved for user uses) - * @Return IMG_TRUE - success, IMG_FALSE - failure - */ -IMG_BOOL -RA_Add(RA_ARENA *pArena, - RA_BASE_T base, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags, - RA_PERISPAN_HANDLE hPriv); - -/* - * @Function RA_Alloc - * - * @Description To allocate resource from an arena. - * - * @Input pArena - the arena - * @Input uRequestSize - the size of resource segment requested. - * @Input uImportMultiplier - Import x-times of the uRequestSize - * for future RA_Alloc calls. - * Use RA_NO_IMPORT_MULTIPLIER to import the exact size. - * @Input uImportFlags - flags influencing allocation policy. - * @Input uAlignment - the alignment constraint required for the - * allocated segment, use 0 if alignment not required. - * @Input pszAnnotation - a string to describe the allocation - * @Output base - allocated base resource - * @Output pActualSize - the actual_size of resource segment allocated, - * typically rounded up by quantum. - * @Output phPriv - the user reference associated with allocated - * resource span. - * @Return PVRSRV_OK - success - */ -PVRSRV_ERROR -RA_Alloc(RA_ARENA *pArena, - RA_LENGTH_T uRequestSize, - IMG_UINT8 uImportMultiplier, - RA_FLAGS_T uImportFlags, - RA_LENGTH_T uAlignment, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *base, - RA_LENGTH_T *pActualSize, - RA_PERISPAN_HANDLE *phPriv); - -/* - * @Function RA_Alloc_Range - * - * @Description - * - * To allocate a resource at a specified base from an arena. - * - * @Input pArena - the arena - * @Input uRequestSize - the size of resource segment requested. - * @Input uImportFlags - flags influencing allocation policy. - * @Input uAlignment - the alignment constraint required for the - * allocated segment, use 0 if alignment not required. - * @Input base - allocated base resource - * @Output pActualSize - the actual_size of resource segment allocated, - * typically rounded up by quantum. - * @Return PVRSRV_OK - success - */ -PVRSRV_ERROR -RA_Alloc_Range(RA_ARENA *pArena, - RA_LENGTH_T uRequestSize, - RA_FLAGS_T uImportFlags, - RA_LENGTH_T uAlignment, - RA_BASE_T base, - RA_LENGTH_T *pActualSize); - -/* - * @Function RA_Free - * - * @Description To free a resource segment. - * - * @Input pArena - the arena the segment was originally allocated from. - * @Input base - the base of the resource span to free. - * - * @Return None - */ -void -RA_Free(RA_ARENA *pArena, RA_BASE_T base); - -/* - * @Function RA_Get_Usage_Stats - * - * @Description To collect the arena usage statistics. - * - * @Input pArena - the arena to acquire usage statistics from. - * @Input psRAStats - the buffer to hold the usage statistics of the arena. - * - * @Return None - */ -IMG_INTERNAL void -RA_Get_Usage_Stats(RA_ARENA *pArena, PRA_USAGE_STATS psRAStats); - -IMG_INTERNAL RA_ARENA_ITERATOR * -RA_IteratorAcquire(RA_ARENA *pArena, IMG_BOOL bIncludeFreeSegments); - -IMG_INTERNAL void -RA_IteratorReset(RA_ARENA_ITERATOR *pIter); - -IMG_INTERNAL void -RA_IteratorRelease(RA_ARENA_ITERATOR *pIter); - -IMG_INTERNAL IMG_BOOL -RA_IteratorNext(RA_ARENA_ITERATOR *pIter, RA_ITERATOR_DATA *pData); - -/*************************************************************************/ /*! -@Function RA_BlockDump -@Description Debug dump of all memory allocations within the RA and the space - between. A '#' represents a block of memory (the arena's quantum - in size) that has been allocated whereas a '.' represents a free - block. -@Input pArena The arena to dump. -@Input pfnLogDump The dumping method. -@Input pPrivData Data to be passed into the pfnLogDump method. -*/ /**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR -RA_BlockDump(RA_ARENA *pArena, - __printf(2, 3) void (*pfnLogDump)(void*, IMG_CHAR*, ...), - void *pPrivData); - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge.h b/drivers/gpu/drm/img-rogue/1.17/rgx_bridge.h deleted file mode 100644 index cb9230f6cdd43..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge.h +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Bridge Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the Rogue Bridge code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_BRIDGE_H -#define RGX_BRIDGE_H - -#include "pvr_bridge.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "rgx_fwif_km.h" - -#define RGXFWINITPARAMS_VERSION 1 -#define RGXFWINITPARAMS_EXTENSION 128 - -#include "common_rgxta3d_bridge.h" -#include "common_rgxcmp_bridge.h" -#if defined(SUPPORT_FASTRENDER_DM) -#include "common_rgxtq2_bridge.h" -#endif -#if defined(SUPPORT_RGXTQ_BRIDGE) -#include "common_rgxtq_bridge.h" -#endif -#if defined(SUPPORT_USC_BREAKPOINT) -#include "common_rgxbreakpoint_bridge.h" -#endif -#include "common_rgxfwdbg_bridge.h" -#if defined(PDUMP) -#include "common_rgxpdump_bridge.h" -#endif -#include "common_rgxhwperf_bridge.h" -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) -#include "common_rgxregconfig_bridge.h" -#endif -#include "common_rgxkicksync_bridge.h" -#include "common_rgxtimerquery_bridge.h" -#if defined(SUPPORT_RGXRAY_BRIDGE) -#include "common_rgxray_bridge.h" -#endif -/* - * Bridge Cmd Ids - */ - -/* *REMEMBER* to update PVRSRV_BRIDGE_RGX_LAST if you add/remove a bridge - * group! - * Also you need to ensure all PVRSRV_BRIDGE_RGX_xxx_DISPATCH_FIRST offsets - * follow on from the previous bridge group's commands! - * - * If a bridge group is optional, ensure you *ALWAYS* define its index - * (e.g. PVRSRV_BRIDGE_RGXCMP is always 151, even is the feature is not - * defined). If an optional bridge group is not defined you must still - * define PVRSRV_BRIDGE_RGX_xxx_DISPATCH_FIRST for it with an assigned - * value of 0. - */ - -/* The RGX bridge groups start at 128 (PVRSRV_BRIDGE_RGX_FIRST) rather than - * follow-on from the other non-device bridge groups (meaning that they then - * won't be displaced if other non-device bridge groups are added). - */ - -#define PVRSRV_BRIDGE_RGX_FIRST 128UL - -/* 128: RGX TQ interface functions */ -#define PVRSRV_BRIDGE_RGXTQ 128UL -/* The RGXTQ bridge is conditional since the definitions in this header file - * support both the rogue and volcanic servers, but the RGXTQ bridge is not - * required at all on the Volcanic architecture. - */ -#if defined(SUPPORT_RGXTQ_BRIDGE) -#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST (PVRSRV_BRIDGE_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTQ_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST (PVRSRV_BRIDGE_DISPATCH_LAST) -#endif - -/* 129: RGX Compute interface functions */ -#define PVRSRV_BRIDGE_RGXCMP 129UL -#define PVRSRV_BRIDGE_RGXCMP_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST (PVRSRV_BRIDGE_RGXCMP_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXCMP_CMD_LAST) - -/* 130: RGX TA/3D interface functions */ -#define PVRSRV_BRIDGE_RGXTA3D 130UL -#define PVRSRV_BRIDGE_RGXTA3D_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTA3D_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTA3D_CMD_LAST) - -/* 131: RGX Breakpoint interface functions */ -#define PVRSRV_BRIDGE_RGXBREAKPOINT 131UL -#if defined(SUPPORT_USC_BREAKPOINT) -#define PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_LAST (PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST) -#endif - -/* 132: RGX Debug/Misc interface functions */ -#define PVRSRV_BRIDGE_RGXFWDBG 132UL -#define PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_LAST (PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXFWDBG_CMD_LAST) - -/* 133: RGX PDump interface functions */ -#define PVRSRV_BRIDGE_RGXPDUMP 133UL -#if defined(PDUMP) -#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST (PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXPDUMP_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST (PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_LAST) -#endif - -/* 134: RGX HWPerf interface functions */ -#define PVRSRV_BRIDGE_RGXHWPERF 134UL -#define PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXHWPERF_CMD_LAST) - -/* 135: RGX Register Configuration interface functions */ -#define PVRSRV_BRIDGE_RGXREGCONFIG 135UL -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) -#define PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_LAST (PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXREGCONFIG_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_LAST (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST) -#endif - -/* 136: RGX kicksync interface */ -#define PVRSRV_BRIDGE_RGXKICKSYNC 136UL -#define PVRSRV_BRIDGE_RGXKICKSYNC_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXKICKSYNC_DISPATCH_LAST (PVRSRV_BRIDGE_RGXKICKSYNC_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXKICKSYNC_CMD_LAST) - -/* 137: RGX TQ2 interface */ -#define PVRSRV_BRIDGE_RGXTQ2 137UL -#if defined(SUPPORT_FASTRENDER_DM) -#define PVRSRV_BRIDGE_RGXTQ2_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXKICKSYNC_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXTQ2_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTQ2_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTQ2_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXTQ2_DISPATCH_FIRST (0) -#define PVRSRV_BRIDGE_RGXTQ2_DISPATCH_LAST (PVRSRV_BRIDGE_RGXKICKSYNC_DISPATCH_LAST) -#endif - -/* 138: RGX timer query interface */ -#define PVRSRV_BRIDGE_RGXTIMERQUERY 138UL -#define PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXTQ2_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_LAST) - -/* 139: RGX Ray tracing interface */ -#define PVRSRV_BRIDGE_RGXRAY 139UL -#if defined(SUPPORT_RGXRAY_BRIDGE) -#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST (PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_LAST + 1) -#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST (PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXRAY_CMD_LAST) -#else -#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST 0 -#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST (PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_LAST) -#endif - -#define PVRSRV_BRIDGE_RGX_LAST (PVRSRV_BRIDGE_RGXRAY) -#define PVRSRV_BRIDGE_RGX_DISPATCH_LAST (PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST) - -/* bit mask representing the enabled RGX bridges */ - -static const IMG_UINT32 __maybe_unused gui32RGXBridges = - (1U << (PVRSRV_BRIDGE_RGXTQ - PVRSRV_BRIDGE_RGX_FIRST)) -#if defined(RGX_FEATURE_COMPUTE) || defined(__KERNEL__) - | (1U << (PVRSRV_BRIDGE_RGXCMP - PVRSRV_BRIDGE_RGX_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_RGXTA3D - PVRSRV_BRIDGE_RGX_FIRST)) -#if defined(SUPPORT_BREAKPOINT) - | (1U << (PVRSRV_BRIDGE_BREAKPOINT - PVRSRV_BRIDGE_RGX_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_RGXFWDBG - PVRSRV_BRIDGE_RGX_FIRST)) -#if defined(PDUMP) - | (1U << (PVRSRV_BRIDGE_RGXPDUMP - PVRSRV_BRIDGE_RGX_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_RGXHWPERF - PVRSRV_BRIDGE_RGX_FIRST)) -#if defined(SUPPORT_REGCONFIG) - | (1U << (PVRSRV_BRIDGE_RGXREGCONFIG - PVRSRV_BRIDGE_RGX_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_RGXKICKSYNC - PVRSRV_BRIDGE_RGX_FIRST)) -#if defined(SUPPORT_FASTRENDER_DM) || defined(__KERNEL__) - | (1U << (PVRSRV_BRIDGE_RGXTQ2 - PVRSRV_BRIDGE_RGX_FIRST)) -#endif -#if defined(SUPPORT_TIMERQUERY) - | (1U << (PVRSRV_BRIDGE_RGXTIMERQUERY - PVRSRV_BRIDGE_RGX_FIRST)) -#endif - | (1U << (PVRSRV_BRIDGE_RGXRAY - PVRSRV_BRIDGE_RGX_FIRST)) - ; -/* bit field representing which RGX bridge groups may optionally not - * be present in the server - */ - -#define RGX_BRIDGES_OPTIONAL \ - ( \ - 0 /* no RGX bridges are currently optional */ \ - ) - -#if defined(__cplusplus) -} -#endif - -#endif /* RGX_BRIDGE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.c b/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.c deleted file mode 100644 index 1b1f81d788bcc..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.c +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR device dependent bridge Init/Deinit Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements device dependent PVR Bridge init/deinit code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "rgx_bridge_init.h" -#include "rgxdevice.h" - -#if defined(RGX_FEATURE_FASTRENDER_DM_BIT_MASK) -PVRSRV_ERROR InitRGXTQ2Bridge(void); -void DeinitRGXTQ2Bridge(void); -#endif -PVRSRV_ERROR InitRGXCMPBridge(void); -void DeinitRGXCMPBridge(void); -#if defined(SUPPORT_RGXRAY_BRIDGE) -PVRSRV_ERROR InitRGXRAYBridge(void); -void DeinitRGXRAYBridge(void); -#endif - -PVRSRV_ERROR DeviceDepBridgeInit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PVRSRV_ERROR eError; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE)) - { - eError = InitRGXCMPBridge(); - PVR_LOG_RETURN_IF_ERROR(eError, "InitRGXCMPBridge"); - } - -#if defined(RGX_FEATURE_FASTRENDER_DM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - eError = InitRGXTQ2Bridge(); - PVR_LOG_RETURN_IF_ERROR(eError, "InitRGXTQ2Bridge"); - } -#endif - -#if defined(SUPPORT_RGXRAY_BRIDGE) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, RAY_TRACING_ARCH) && - RGX_GET_FEATURE_VALUE(psDevInfo, RAY_TRACING_ARCH) > 0) - { - eError = InitRGXRAYBridge(); - PVR_LOG_RETURN_IF_ERROR(eError, "InitRGXRAYBridge"); - } -#endif - - return PVRSRV_OK; -} - -void DeviceDepBridgeDeInit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE)) - { - DeinitRGXCMPBridge(); - } - -#if defined(RGX_FEATURE_FASTRENDER_DM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - DeinitRGXTQ2Bridge(); - } -#endif - -#if defined(SUPPORT_RGXRAY_BRIDGE) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, RAY_TRACING_ARCH) && - RGX_GET_FEATURE_VALUE(psDevInfo, RAY_TRACING_ARCH) > 0) - { - DeinitRGXRAYBridge(); - } -#endif -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.h b/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.h deleted file mode 100644 index 10e8e72ca0957..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_bridge_init.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title PVR device dependent bridge Init/Deinit Module (kernel side) -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements device dependent PVR Bridge init/deinit code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_BRIDGE_INIT_H) -#define RGX_BRIDGE_INIT_H - -#include "img_types.h" -#include "img_defs.h" -#include "device.h" -#include "rgxdevice.h" - -PVRSRV_ERROR DeviceDepBridgeInit(PVRSRV_RGXDEV_INFO *psDevInfo); -void DeviceDepBridgeDeInit(PVRSRV_RGXDEV_INFO *psDevInfo); - -#endif /* RGX_BRIDGE_INIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_common.h b/drivers/gpu/drm/img-rogue/1.17/rgx_common.h deleted file mode 100644 index b6ae1500acc3c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_common.h +++ /dev/null @@ -1,235 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Common Types and Defines Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Common types and definitions for RGX software -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_COMMON_H -#define RGX_COMMON_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" - -/* Included to get the BVNC_KM_N defined and other feature defs */ -#include "km/rgxdefs_km.h" - -#include "rgx_common_asserts.h" - - -/* Virtualisation validation builds are meant to test the VZ-related hardware without a fully virtualised platform. - * As such a driver can support either the vz-validation code or real virtualisation. - * Note: PVRSRV_VZ_NUM_OSID is the external build option, while RGX_NUM_OS_SUPPORTED is the internal symbol used in the DDK */ -#if defined(SUPPORT_GPUVIRT_VALIDATION) && (defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1)) -#error "Invalid build configuration: Virtualisation support (PVRSRV_VZ_NUM_OSID > 1) and virtualisation validation code (SUPPORT_GPUVIRT_VALIDATION) are mutually exclusive." -#endif - -/* The RGXFWIF_DM defines assume only one of RGX_FEATURE_TLA or - * RGX_FEATURE_FASTRENDER_DM is present. Ensure this with a compile-time check. - */ -#if defined(RGX_FEATURE_TLA) && defined(RGX_FEATURE_FASTRENDER_DM) -#error "Both RGX_FEATURE_TLA and RGX_FEATURE_FASTRENDER_DM defined. Fix code to handle this!" -#endif - -/*! The master definition for data masters known to the firmware of RGX. - * When a new DM is added to this list, relevant entry should be added to - * RGX_HWPERF_DM enum list. - * The DM in a V1 HWPerf packet uses this definition. */ - -typedef IMG_UINT32 RGXFWIF_DM; - -#define RGXFWIF_DM_GP IMG_UINT32_C(0) -/* Either TDM or 2D DM is present. The above build time error is present to verify this */ -#define RGXFWIF_DM_2D IMG_UINT32_C(1) /* when RGX_FEATURE_TLA defined */ -#define RGXFWIF_DM_TDM IMG_UINT32_C(1) /* when RGX_FEATURE_FASTRENDER_DM defined */ - -#define RGXFWIF_DM_GEOM IMG_UINT32_C(2) -#define RGXFWIF_DM_3D IMG_UINT32_C(3) -#define RGXFWIF_DM_CDM IMG_UINT32_C(4) -#define RGXFWIF_DM_RAY IMG_UINT32_C(5) -#define RGXFWIF_DM_GEOM2 IMG_UINT32_C(6) -#define RGXFWIF_DM_GEOM3 IMG_UINT32_C(7) -#define RGXFWIF_DM_GEOM4 IMG_UINT32_C(8) - -#define RGXFWIF_DM_LAST RGXFWIF_DM_GEOM4 - -typedef IMG_UINT32 RGX_KICK_TYPE_DM; -#define RGX_KICK_TYPE_DM_GP IMG_UINT32_C(0x001) -#define RGX_KICK_TYPE_DM_TDM_2D IMG_UINT32_C(0x002) -#define RGX_KICK_TYPE_DM_TA IMG_UINT32_C(0x004) -#define RGX_KICK_TYPE_DM_3D IMG_UINT32_C(0x008) -#define RGX_KICK_TYPE_DM_CDM IMG_UINT32_C(0x010) -#define RGX_KICK_TYPE_DM_RTU IMG_UINT32_C(0x020) -#define RGX_KICK_TYPE_DM_SHG IMG_UINT32_C(0x040) -#define RGX_KICK_TYPE_DM_TQ2D IMG_UINT32_C(0x080) -#define RGX_KICK_TYPE_DM_TQ3D IMG_UINT32_C(0x100) -#define RGX_KICK_TYPE_DM_RAY IMG_UINT32_C(0x200) -#define RGX_KICK_TYPE_DM_LAST IMG_UINT32_C(0x400) - -/* Maximum number of DM in use: GP, 2D/TDM, GEOM, 3D, CDM, RDM, GEOM2, GEOM3, GEOM4 */ -#define RGXFWIF_DM_MAX (RGXFWIF_DM_LAST + 1U) - -/* - * Data Master Tags to be appended to resources created on behalf of each RGX - * Context. - */ -#define RGX_RI_DM_TAG_KS 'K' -#define RGX_RI_DM_TAG_CDM 'C' -#define RGX_RI_DM_TAG_RC 'R' /* To be removed once TA/3D Timelines are split */ -#define RGX_RI_DM_TAG_TA 'V' -#define RGX_RI_DM_TAG_GEOM 'V' -#define RGX_RI_DM_TAG_3D 'P' -#define RGX_RI_DM_TAG_TDM 'T' -#define RGX_RI_DM_TAG_TQ2D '2' -#define RGX_RI_DM_TAG_TQ3D 'Q' -#define RGX_RI_DM_TAG_RAY 'r' - -/* - * Client API Tags to be appended to resources created on behalf of each - * Client API. - */ -#define RGX_RI_CLIENT_API_GLES1 '1' -#define RGX_RI_CLIENT_API_GLES3 '3' -#define RGX_RI_CLIENT_API_VULKAN 'V' -#define RGX_RI_CLIENT_API_EGL 'E' -#define RGX_RI_CLIENT_API_OPENCL 'C' -#define RGX_RI_CLIENT_API_OPENGL 'G' -#define RGX_RI_CLIENT_API_SERVICES 'S' -#define RGX_RI_CLIENT_API_WSEGL 'W' -#define RGX_RI_CLIENT_API_ANDROID 'A' -#define RGX_RI_CLIENT_API_LWS 'L' - -/* - * Format a RI annotation for a given RGX Data Master context - */ -#define RGX_RI_FORMAT_DM_ANNOTATION(annotation, dmTag, clientAPI) do \ - { \ - (annotation)[0] = (dmTag); \ - (annotation)[1] = (clientAPI); \ - (annotation)[2] = '\0'; \ - } while (false) - -/*! - ****************************************************************************** - * RGXFW Compiler alignment definitions - *****************************************************************************/ -#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES) || defined(INTEGRITY_OS) -#define RGXFW_ALIGN __attribute__ ((aligned (8))) -#define RGXFW_ALIGN_DCACHEL __attribute__((aligned (64))) -#elif defined(_MSC_VER) -#define RGXFW_ALIGN __declspec(align(8)) -#define RGXFW_ALIGN_DCACHEL __declspec(align(64)) -#pragma warning (disable : 4324) -#else -#error "Align MACROS need to be defined for this compiler" -#endif - -/*! - ****************************************************************************** - * Force 8-byte alignment for structures allocated uncached. - *****************************************************************************/ -#define UNCACHED_ALIGN RGXFW_ALIGN - - -/*! - ****************************************************************************** - * GPU Utilisation states - *****************************************************************************/ -#define RGXFWIF_GPU_UTIL_STATE_IDLE (0U) -#define RGXFWIF_GPU_UTIL_STATE_ACTIVE (1U) -#define RGXFWIF_GPU_UTIL_STATE_BLOCKED (2U) -#define RGXFWIF_GPU_UTIL_STATE_NUM (3U) -#define RGXFWIF_GPU_UTIL_STATE_MASK IMG_UINT64_C(0x0000000000000003) - - -/* - * Maximum amount of register writes that can be done by the register - * programmer (FW or META DMA). This is not a HW limitation, it is only - * a protection against malformed inputs to the register programmer. - */ -#define RGX_MAX_NUM_REGISTER_PROGRAMMER_WRITES (128U) - -/* FW common context priority. */ -/*! - * @AddToGroup WorkloadContexts - * @{ - */ -#define RGX_CTX_PRIORITY_REALTIME (INT32_MAX) -#define RGX_CTX_PRIORITY_HIGH (2U) /*!< HIGH priority */ -#define RGX_CTX_PRIORITY_MEDIUM (1U) /*!< MEDIUM priority */ -#define RGX_CTX_PRIORITY_LOW (0) /*!< LOW priority */ -/*! - * @} End of AddToGroup WorkloadContexts - */ - - -/* - * Use of the 32-bit context property flags mask - * ( X = taken/in use, - = available/unused ) - * - * 0 - * | - * -------------------------------x - */ -/* - * Context creation flags - * (specify a context's properties at creation time) - */ -#define RGX_CONTEXT_FLAG_DISABLESLR (1UL << 0) /*!< Disable SLR */ - -/* Bitmask of context flags allowed to be modified after context create. */ -#define RGX_CONTEXT_FLAGS_WRITEABLE_MASK (RGX_CONTEXT_FLAG_DISABLESLR) - -/* List of attributes that may be set for a context */ -typedef enum _RGX_CONTEXT_PROPERTY_ -{ - RGX_CONTEXT_PROPERTY_FLAGS = 0, /*!< Context flags */ -} RGX_CONTEXT_PROPERTY; - -#if defined(__cplusplus) -} -#endif - -#endif /* RGX_COMMON_H */ - -/****************************************************************************** - End of file -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_common_asserts.h b/drivers/gpu/drm/img-rogue/1.17/rgx_common_asserts.h deleted file mode 100644 index c571cc6f008ef..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_common_asserts.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Common Types and Defines Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Common types and definitions for RGX software -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_COMMON_ASSERTS_H -#define RGX_COMMON_ASSERTS_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! This macro represents a mask of LSBs that must be zero on data structure - * sizes and offsets to ensure they are 8-byte granular on types shared between - * the FW and host driver */ -#define RGX_FW_ALIGNMENT_LSB (7U) - -/*! Macro to test structure size alignment */ -#define RGX_FW_STRUCT_SIZE_ASSERT(_a) \ - static_assert((sizeof(_a) & RGX_FW_ALIGNMENT_LSB) == 0U, \ - "Size of " #_a " is not properly aligned") - -/*! Macro to test structure member alignment */ -#define RGX_FW_STRUCT_OFFSET_ASSERT(_a, _b) \ - static_assert((offsetof(_a, _b) & RGX_FW_ALIGNMENT_LSB) == 0U, \ - "Offset of " #_a "." #_b " is not properly aligned") - -#if defined(__cplusplus) -} -#endif - -#endif /* RGX_COMMON_ASSERTS_H */ - -/****************************************************************************** - End of file -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_compat_bvnc.h b/drivers/gpu/drm/img-rogue/1.17/rgx_compat_bvnc.h deleted file mode 100644 index c3e1333cdb0fa..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_compat_bvnc.h +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_compat_bvnc.h -@Title BVNC compatibility check utilities -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Utility functions used for packing BNC and V. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_COMPAT_BVNC_H) -#define RGX_COMPAT_BVNC_H - -#include "img_types.h" - -#if defined(RGX_FIRMWARE) /* Services firmware */ -# include "rgxfw_utils.h" -# define PVR_COMPAT_ASSERT RGXFW_ASSERT -#elif !defined(RGX_BUILD_BINARY) /* Services host driver code */ -# include "pvr_debug.h" -# define PVR_COMPAT_ASSERT PVR_ASSERT -#else /* FW user-mode tools */ -# include -# define PVR_COMPAT_ASSERT assert -#endif - -/* 64bit endian conversion macros */ -#if defined(__BIG_ENDIAN__) -#define RGX_INT64_TO_BE(N) (N) -#define RGX_INT64_FROM_BE(N) (N) -#define RGX_INT32_TO_BE(N) (N) -#define RGX_INT32_FROM_BE(N) (N) -#else -#define RGX_INT64_TO_BE(N) \ - ((((N) >> 56) & 0xff) \ - | (((N) >> 40) & 0xff00) \ - | (((N) >> 24) & 0xff0000) \ - | (((N) >> 8) & 0xff000000U) \ - | ((N) << 56) \ - | (((N) & 0xff00) << 40) \ - | (((N) & 0xff0000) << 24) \ - | (((N) & 0xff000000U) << 8)) -#define RGX_INT64_FROM_BE(N) RGX_INT64_TO_BE(N) - -#define RGX_INT32_TO_BE(N) \ - ((((N) >> 24) & 0xff) \ - | (((N) >> 8) & 0xff00) \ - | ((N) << 24) \ - | ((((N) & 0xff00) << 8))) -#define RGX_INT32_FROM_BE(N) RGX_INT32_TO_BE(N) -#endif - -/****************************************************************************** - * RGX Version packed into 64-bit (BVNC) to be used by Compatibility Check - *****************************************************************************/ - -#define RGX_BVNC_PACK_SHIFT_B 48 -#define RGX_BVNC_PACK_SHIFT_V 32 -#define RGX_BVNC_PACK_SHIFT_N 16 -#define RGX_BVNC_PACK_SHIFT_C 0 - -#define RGX_BVNC_PACK_MASK_B (IMG_UINT64_C(0xFFFF000000000000)) -#define RGX_BVNC_PACK_MASK_V (IMG_UINT64_C(0x0000FFFF00000000)) -#define RGX_BVNC_PACK_MASK_N (IMG_UINT64_C(0x00000000FFFF0000)) -#define RGX_BVNC_PACK_MASK_C (IMG_UINT64_C(0x000000000000FFFF)) - -#define RGX_BVNC_PACKED_EXTR_B(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_B) >> RGX_BVNC_PACK_SHIFT_B)) -#define RGX_BVNC_PACKED_EXTR_V(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_V) >> RGX_BVNC_PACK_SHIFT_V)) -#define RGX_BVNC_PACKED_EXTR_N(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_N) >> RGX_BVNC_PACK_SHIFT_N)) -#define RGX_BVNC_PACKED_EXTR_C(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_C) >> RGX_BVNC_PACK_SHIFT_C)) - -#define RGX_BVNC_EQUAL(L,R,all,version,bvnc) do { \ - (bvnc) = IMG_FALSE; \ - (version) = ((L).ui32LayoutVersion == (R).ui32LayoutVersion); \ - if (version) \ - { \ - (bvnc) = ((L).ui64BVNC == (R).ui64BVNC); \ - } \ - (all) = (version) && (bvnc); \ - } while (false) - - -/**************************************************************************//** - * Utility function for packing BVNC - *****************************************************************************/ -static inline IMG_UINT64 rgx_bvnc_pack(IMG_UINT32 ui32B, IMG_UINT32 ui32V, IMG_UINT32 ui32N, IMG_UINT32 ui32C) -{ - /* - * Test for input B, V, N and C exceeding max bit width. - */ - PVR_COMPAT_ASSERT((ui32B & (~(RGX_BVNC_PACK_MASK_B >> RGX_BVNC_PACK_SHIFT_B))) == 0U); - PVR_COMPAT_ASSERT((ui32V & (~(RGX_BVNC_PACK_MASK_V >> RGX_BVNC_PACK_SHIFT_V))) == 0U); - PVR_COMPAT_ASSERT((ui32N & (~(RGX_BVNC_PACK_MASK_N >> RGX_BVNC_PACK_SHIFT_N))) == 0U); - PVR_COMPAT_ASSERT((ui32C & (~(RGX_BVNC_PACK_MASK_C >> RGX_BVNC_PACK_SHIFT_C))) == 0U); - - return (((IMG_UINT64)ui32B << RGX_BVNC_PACK_SHIFT_B) | - ((IMG_UINT64)ui32V << RGX_BVNC_PACK_SHIFT_V) | - ((IMG_UINT64)ui32N << RGX_BVNC_PACK_SHIFT_N) | - ((IMG_UINT64)ui32C << RGX_BVNC_PACK_SHIFT_C)); -} - - -#endif /* RGX_COMPAT_BVNC_H */ - -/****************************************************************************** - End of file (rgx_compat_bvnc.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fw_info.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fw_info.h deleted file mode 100644 index 909ec8216e1da..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fw_info.h +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title FW image information - -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Utility functions used internally for HWPerf data retrieval -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_FW_INFO_H) -#define RGX_FW_INFO_H - -#include "img_types.h" -#include "rgx_common.h" - -/* - * Firmware binary block unit in bytes. - * Raw data stored in FW binary will be aligned to this size. - */ -#define FW_BLOCK_SIZE 4096L - -typedef enum -{ - META_CODE = 0, - META_PRIVATE_DATA, - META_COREMEM_CODE, - META_COREMEM_DATA, - MIPS_CODE, - MIPS_EXCEPTIONS_CODE, - MIPS_BOOT_CODE, - MIPS_PRIVATE_DATA, - MIPS_BOOT_DATA, - MIPS_STACK, - RISCV_UNCACHED_CODE, - RISCV_CACHED_CODE, - RISCV_PRIVATE_DATA, - RISCV_COREMEM_CODE, - RISCV_COREMEM_DATA, -} RGX_FW_SECTION_ID; - -typedef enum -{ - NONE = 0, - FW_CODE, - FW_DATA, - FW_COREMEM_CODE, - FW_COREMEM_DATA -} RGX_FW_SECTION_TYPE; - - -/* - * FW binary format with FW info attached: - * - * Contents Offset - * +-----------------+ - * | | 0 - * | | - * | Original binary | - * | file | - * | (.ldr/.elf) | - * | | - * | | - * +-----------------+ - * | FW info header | FILE_SIZE - 4K - * +-----------------+ - * | | - * | FW layout table | - * | | - * +-----------------+ - * FILE_SIZE - */ - -#define FW_INFO_VERSION (2) - -typedef struct -{ - /* FW_INFO_VERSION 1 */ - IMG_UINT32 ui32InfoVersion; /* FW info version */ - IMG_UINT32 ui32HeaderLen; /* Header length */ - IMG_UINT32 ui32LayoutEntryNum; /* Number of entries in the layout table */ - IMG_UINT32 ui32LayoutEntrySize; /* Size of an entry in the layout table */ - IMG_UINT64 RGXFW_ALIGN ui64BVNC; /* BVNC */ - IMG_UINT32 ui32FwPageSize; /* Page size of processor on which firmware executes */ - IMG_UINT32 ui32Flags; /* Compatibility flags */ - - /* FW_INFO_VERSION 2 */ - IMG_UINT16 ui16PVRVersionMajor; /* DDK major version number */ - IMG_UINT16 ui16PVRVersionMinor; /* DDK minor version number */ - IMG_UINT32 ui32PVRVersionBuild; /* DDK build number */ -} RGX_FW_INFO_HEADER; - -typedef struct -{ - RGX_FW_SECTION_ID eId; - RGX_FW_SECTION_TYPE eType; - IMG_UINT32 ui32BaseAddr; - IMG_UINT32 ui32MaxSize; - IMG_UINT32 ui32AllocSize; - IMG_UINT32 ui32AllocOffset; -} RGX_FW_LAYOUT_ENTRY; - -#endif /* RGX_FW_INFO_H */ - -/****************************************************************************** - End of file (rgx_fw_info.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_alignchecks.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_alignchecks.h deleted file mode 100644 index 4f82b23743be2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_alignchecks.h +++ /dev/null @@ -1,192 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX fw interface alignment checks -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Checks to avoid disalignment in RGX fw data structures - shared with the host -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_FWIF_ALIGNCHECKS_H) -#define RGX_FWIF_ALIGNCHECKS_H - -/* for the offsetof macro */ -#if defined(__KERNEL__) && defined(__linux__) -#include -#else -#include -#endif - -/*! - ****************************************************************************** - * Alignment UM/FW checks array - *****************************************************************************/ - -#define RGXFW_ALIGN_CHECKS_UM_MAX 128U - -#define RGXFW_ALIGN_CHECKS_INIT0 \ - sizeof(RGXFWIF_TRACEBUF), \ - offsetof(RGXFWIF_TRACEBUF, ui32LogType), \ - offsetof(RGXFWIF_TRACEBUF, sTraceBuf), \ - offsetof(RGXFWIF_TRACEBUF, ui32TraceBufSizeInDWords), \ - offsetof(RGXFWIF_TRACEBUF, ui32TracebufFlags), \ - \ - sizeof(RGXFWIF_SYSDATA), \ - offsetof(RGXFWIF_SYSDATA, ePowState), \ - offsetof(RGXFWIF_SYSDATA, ui32HWPerfDropCount), \ - offsetof(RGXFWIF_SYSDATA, ui32LastDropOrdinal), \ - offsetof(RGXFWIF_SYSDATA, ui32FWFaults), \ - offsetof(RGXFWIF_SYSDATA, ui32HWRStateFlags), \ - \ - sizeof(RGXFWIF_OSDATA), \ - offsetof(RGXFWIF_OSDATA, ui32HostSyncCheckMark), \ - offsetof(RGXFWIF_OSDATA, ui32KCCBCmdsExecuted), \ - \ - sizeof(RGXFWIF_HWRINFOBUF), \ - offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmLockedUpCount), \ - offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmOverranCount), \ - offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmRecoveredCount), \ - offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmFalseDetectCount), \ - \ - /* RGXFWIF_CMDTA checks */ \ - sizeof(RGXFWIF_CMDTA), \ - offsetof(RGXFWIF_CMDTA, sGeomRegs), \ - \ - /* RGXFWIF_CMD3D checks */ \ - sizeof(RGXFWIF_CMD3D), \ - offsetof(RGXFWIF_CMD3D, s3DRegs), \ - \ - /* RGXFWIF_CMDTRANSFER checks */ \ - sizeof(RGXFWIF_CMDTRANSFER), \ - offsetof(RGXFWIF_CMDTRANSFER, sTransRegs), \ - \ - \ - /* RGXFWIF_CMD_COMPUTE checks */ \ - sizeof(RGXFWIF_CMD_COMPUTE), \ - offsetof(RGXFWIF_CMD_COMPUTE, sCDMRegs), \ - \ - /* RGXFWIF_FREELIST checks */ \ - sizeof(RGXFWIF_FREELIST), \ - offsetof(RGXFWIF_FREELIST, psFreeListDevVAddr), \ - offsetof(RGXFWIF_FREELIST, ui32MaxPages), \ - offsetof(RGXFWIF_FREELIST, ui32CurrentPages), \ - \ - /* RGXFWIF_HWRTDATA checks */ \ - sizeof(RGXFWIF_HWRTDATA), \ - offsetof(RGXFWIF_HWRTDATA, psVHeapTableDevVAddr), \ - offsetof(RGXFWIF_HWRTDATA, psPMMListDevVAddr), \ - offsetof(RGXFWIF_HWRTDATA, apsFreeLists), \ - offsetof(RGXFWIF_HWRTDATA, ui64VCECatBase), \ - offsetof(RGXFWIF_HWRTDATA, eState), \ - \ - /* RGXFWIF_HWRTDATA_COMMON checks */ \ - sizeof(RGXFWIF_HWRTDATA_COMMON), \ - offsetof(RGXFWIF_HWRTDATA_COMMON, bTACachesNeedZeroing),\ - \ - /* RGXFWIF_HWPERF_CTL_BLK checks */ \ - sizeof(RGXFWIF_HWPERF_CTL_BLK), \ - offsetof(RGXFWIF_HWPERF_CTL_BLK, aui64CounterCfg), \ - \ - /* RGXFWIF_HWPERF_CTL checks */ \ - sizeof(RGXFWIF_HWPERF_CTL), \ - offsetof(RGXFWIF_HWPERF_CTL, SelCntr) - -#if defined(RGX_FEATURE_TLA) -#define RGXFW_ALIGN_CHECKS_INIT1 \ - RGXFW_ALIGN_CHECKS_INIT0, \ - /* RGXFWIF_CMD2D checks */ \ - sizeof(RGXFWIF_CMD2D), \ - offsetof(RGXFWIF_CMD2D, s2DRegs) -#else -#define RGXFW_ALIGN_CHECKS_INIT1 RGXFW_ALIGN_CHECKS_INIT0 -#endif /* RGX_FEATURE_TLA */ - - -#if defined(RGX_FEATURE_FASTRENDER_DM) -#define RGXFW_ALIGN_CHECKS_INIT \ - RGXFW_ALIGN_CHECKS_INIT1, \ - /* RGXFWIF_CMDTDM checks */ \ - sizeof(RGXFWIF_CMDTDM), \ - offsetof(RGXFWIF_CMDTDM, sTDMRegs) -#else -#define RGXFW_ALIGN_CHECKS_INIT RGXFW_ALIGN_CHECKS_INIT1 -#endif /* ! RGX_FEATURE_FASTRENDER_DM */ - - - -/*! - ****************************************************************************** - * Alignment KM checks array - *****************************************************************************/ - -#define RGXFW_ALIGN_CHECKS_INIT_KM \ - sizeof(RGXFWIF_SYSINIT), \ - offsetof(RGXFWIF_SYSINIT, sFaultPhysAddr), \ - offsetof(RGXFWIF_SYSINIT, sPDSExecBase), \ - offsetof(RGXFWIF_SYSINIT, sUSCExecBase), \ - offsetof(RGXFWIF_SYSINIT, asSigBufCtl), \ - offsetof(RGXFWIF_SYSINIT, sTraceBufCtl), \ - offsetof(RGXFWIF_SYSINIT, sFwSysData), \ - sizeof(RGXFWIF_OSINIT), \ - offsetof(RGXFWIF_OSINIT, psKernelCCBCtl), \ - offsetof(RGXFWIF_OSINIT, psKernelCCB), \ - offsetof(RGXFWIF_OSINIT, psFirmwareCCBCtl), \ - offsetof(RGXFWIF_OSINIT, psFirmwareCCB), \ - offsetof(RGXFWIF_OSINIT, sFwOsData), \ - offsetof(RGXFWIF_OSINIT, sRGXCompChecks), \ - \ - /* RGXFWIF_FWRENDERCONTEXT checks */ \ - sizeof(RGXFWIF_FWRENDERCONTEXT), \ - offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext), \ - offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext), \ - \ - sizeof(RGXFWIF_FWCOMMONCONTEXT), \ - offsetof(RGXFWIF_FWCOMMONCONTEXT, psFWMemContext), \ - offsetof(RGXFWIF_FWCOMMONCONTEXT, sRunNode), \ - offsetof(RGXFWIF_FWCOMMONCONTEXT, psCCB), \ - \ - sizeof(RGXFWIF_MMUCACHEDATA), \ - offsetof(RGXFWIF_MMUCACHEDATA, ui32CacheFlags), \ - offsetof(RGXFWIF_MMUCACHEDATA, sMMUCacheSync), \ - offsetof(RGXFWIF_MMUCACHEDATA, ui32MMUCacheSyncUpdateValue) - -#endif /* RGX_FWIF_ALIGNCHECKS_H */ - -/****************************************************************************** - End of file (rgx_fwif_alignchecks.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_hwperf.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_hwperf.h deleted file mode 100644 index 7001092c72210..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_hwperf.h +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_fwif_hwperf.h -@Title RGX HWPerf support -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shared header between RGX firmware and Init process -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_FWIF_HWPERF_H -#define RGX_FWIF_HWPERF_H - -#include "rgx_fwif_shared.h" -#include "rgx_hwperf.h" -#include "rgxdefs_km.h" - - -/*****************************************************************************/ - -/* Structure to hold a block's parameters for passing between the BG context - * and the IRQ context when applying a configuration request. */ -typedef struct -{ - IMG_BOOL bValid; - IMG_BOOL bEnabled; - IMG_UINT32 eBlockID; - IMG_UINT32 uiCounterMask; - IMG_UINT64 RGXFW_ALIGN aui64CounterCfg[RGX_CNTBLK_MUX_COUNTERS_MAX]; -} RGXFWIF_HWPERF_CTL_BLK; - -/* Structure used to hold the configuration of the non-mux counters blocks */ -typedef struct -{ - IMG_UINT32 ui32NumSelectedCounters; - IMG_UINT32 aui32SelectedCountersIDs[RGX_HWPERF_MAX_CUSTOM_CNTRS]; -} RGXFW_HWPERF_SELECT; - -/* Structure used to hold a Direct-Addressable block's parameters for passing - * between the BG context and the IRQ context when applying a configuration - * request. RGX_FEATURE_HWPERF_OCEANIC use only. - */ -typedef struct -{ - IMG_UINT32 uiEnabled; - IMG_UINT32 uiNumCounters; - IMG_UINT32 eBlockID; - RGXFWIF_DEV_VIRTADDR psModel; - IMG_UINT32 aui32Counters[RGX_CNTBLK_COUNTERS_MAX]; -} RGXFWIF_HWPERF_DA_BLK; - - -/* Structure to hold the whole configuration request details for all blocks - * The block masks and counts are used to optimise reading of this data. */ -typedef struct -{ - IMG_UINT32 ui32HWPerfCtlFlags; - - IMG_UINT32 ui32SelectedCountersBlockMask; - RGXFW_HWPERF_SELECT RGXFW_ALIGN SelCntr[RGX_HWPERF_MAX_CUSTOM_BLKS]; - - IMG_UINT32 ui32EnabledMUXBlksCount; - RGXFWIF_HWPERF_CTL_BLK RGXFW_ALIGN sBlkCfg[RGX_HWPERF_MAX_MUX_BLKS]; -} UNCACHED_ALIGN RGXFWIF_HWPERF_CTL; - -/* NOTE: The switch statement in this function must be kept in alignment with - * the enumeration RGX_HWPERF_CNTBLK_ID defined in rgx_hwperf.h. ASSERTs may - * result if not. - * The function provides a hash lookup to get a handle on the global store for - * a block's configuration store from it's block ID. - */ -#ifdef INLINE_IS_PRAGMA -#pragma inline(rgxfw_hwperf_get_block_ctl) -#endif -static INLINE RGXFWIF_HWPERF_CTL_BLK *rgxfw_hwperf_get_block_ctl( - RGX_HWPERF_CNTBLK_ID eBlockID, RGXFWIF_HWPERF_CTL *psHWPerfInitData) -{ - IMG_UINT32 ui32Idx; - - /* Hash the block ID into a control configuration array index */ - switch (eBlockID) - { - case RGX_CNTBLK_ID_TA: - case RGX_CNTBLK_ID_RASTER: - case RGX_CNTBLK_ID_HUB: - case RGX_CNTBLK_ID_TORNADO: - case RGX_CNTBLK_ID_JONES: - { - ui32Idx = eBlockID; - break; - } - case RGX_CNTBLK_ID_TPU_MCU0: - case RGX_CNTBLK_ID_TPU_MCU1: - case RGX_CNTBLK_ID_TPU_MCU2: - case RGX_CNTBLK_ID_TPU_MCU3: - case RGX_CNTBLK_ID_TPU_MCU4: - case RGX_CNTBLK_ID_TPU_MCU5: - case RGX_CNTBLK_ID_TPU_MCU6: - case RGX_CNTBLK_ID_TPU_MCU7: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - case RGX_CNTBLK_ID_USC0: - case RGX_CNTBLK_ID_USC1: - case RGX_CNTBLK_ID_USC2: - case RGX_CNTBLK_ID_USC3: - case RGX_CNTBLK_ID_USC4: - case RGX_CNTBLK_ID_USC5: - case RGX_CNTBLK_ID_USC6: - case RGX_CNTBLK_ID_USC7: - case RGX_CNTBLK_ID_USC8: - case RGX_CNTBLK_ID_USC9: - case RGX_CNTBLK_ID_USC10: - case RGX_CNTBLK_ID_USC11: - case RGX_CNTBLK_ID_USC12: - case RGX_CNTBLK_ID_USC13: - case RGX_CNTBLK_ID_USC14: - case RGX_CNTBLK_ID_USC15: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - case RGX_CNTBLK_ID_TEXAS0: - case RGX_CNTBLK_ID_TEXAS1: - case RGX_CNTBLK_ID_TEXAS2: - case RGX_CNTBLK_ID_TEXAS3: - case RGX_CNTBLK_ID_TEXAS4: - case RGX_CNTBLK_ID_TEXAS5: - case RGX_CNTBLK_ID_TEXAS6: - case RGX_CNTBLK_ID_TEXAS7: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) + - RGX_CNTBLK_INDIRECT_COUNT(USC, 15) + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - case RGX_CNTBLK_ID_RASTER0: - case RGX_CNTBLK_ID_RASTER1: - case RGX_CNTBLK_ID_RASTER2: - case RGX_CNTBLK_ID_RASTER3: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) + - RGX_CNTBLK_INDIRECT_COUNT(USC, 15) + - RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - case RGX_CNTBLK_ID_BLACKPEARL0: - case RGX_CNTBLK_ID_BLACKPEARL1: - case RGX_CNTBLK_ID_BLACKPEARL2: - case RGX_CNTBLK_ID_BLACKPEARL3: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) + - RGX_CNTBLK_INDIRECT_COUNT(USC, 15) + - RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) + - RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3) + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - case RGX_CNTBLK_ID_PBE0: - case RGX_CNTBLK_ID_PBE1: - case RGX_CNTBLK_ID_PBE2: - case RGX_CNTBLK_ID_PBE3: - case RGX_CNTBLK_ID_PBE4: - case RGX_CNTBLK_ID_PBE5: - case RGX_CNTBLK_ID_PBE6: - case RGX_CNTBLK_ID_PBE7: - case RGX_CNTBLK_ID_PBE8: - case RGX_CNTBLK_ID_PBE9: - case RGX_CNTBLK_ID_PBE10: - case RGX_CNTBLK_ID_PBE11: - case RGX_CNTBLK_ID_PBE12: - case RGX_CNTBLK_ID_PBE13: - case RGX_CNTBLK_ID_PBE14: - case RGX_CNTBLK_ID_PBE15: - { - ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST + - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) + - RGX_CNTBLK_INDIRECT_COUNT(USC, 15) + - RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) + - RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3) + - RGX_CNTBLK_INDIRECT_COUNT(BLACKPEARL, 3) + - (eBlockID & RGX_CNTBLK_ID_UNIT_MASK); - break; - } - default: - { - ui32Idx = RGX_HWPERF_MAX_DEFINED_BLKS; - break; - } - } - if (ui32Idx >= RGX_HWPERF_MAX_DEFINED_BLKS) - { - return NULL; - } - return &psHWPerfInitData->sBlkCfg[ui32Idx]; -} - -/* Stub routine for rgxfw_hwperf_get_da_block_ctl() for non - * RGX_FEATURE_HWPERF_OCEANIC systems. Just return a NULL. - */ -#ifdef INLINE_IS_PRAGMA -#pragma inline(rgxfw_hwperf_get_da_block_ctl) -#endif -static INLINE RGXFWIF_HWPERF_DA_BLK* rgxfw_hwperf_get_da_block_ctl( - RGX_HWPERF_CNTBLK_ID eBlockID, RGXFWIF_HWPERF_CTL *psHWPerfInitData) -{ - PVR_UNREFERENCED_PARAMETER(eBlockID); - PVR_UNREFERENCED_PARAMETER(psHWPerfInitData); - - return NULL; -} -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_km.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_km.h deleted file mode 100644 index 2943eee5bfc2d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_km.h +++ /dev/null @@ -1,2341 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX firmware interface structures used by pvrsrvkm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX firmware interface structures used by pvrsrvkm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_FWIF_KM_H) -#define RGX_FWIF_KM_H - -#include "img_types.h" -#include "rgx_fwif_shared.h" -#include "rgxdefs_km.h" -#include "dllist.h" -#include "rgx_hwperf.h" -#include "rgxheapconfig.h" - -/*************************************************************************/ /*! - Logging type -*/ /**************************************************************************/ -#define RGXFWIF_LOG_TYPE_NONE 0x00000000U -#define RGXFWIF_LOG_TYPE_TRACE 0x00000001U -#define RGXFWIF_LOG_TYPE_GROUP_MAIN 0x00000002U -#define RGXFWIF_LOG_TYPE_GROUP_MTS 0x00000004U -#define RGXFWIF_LOG_TYPE_GROUP_CLEANUP 0x00000008U -#define RGXFWIF_LOG_TYPE_GROUP_CSW 0x00000010U -#define RGXFWIF_LOG_TYPE_GROUP_BIF 0x00000020U -#define RGXFWIF_LOG_TYPE_GROUP_PM 0x00000040U -#define RGXFWIF_LOG_TYPE_GROUP_RTD 0x00000080U -#define RGXFWIF_LOG_TYPE_GROUP_SPM 0x00000100U -#define RGXFWIF_LOG_TYPE_GROUP_POW 0x00000200U -#define RGXFWIF_LOG_TYPE_GROUP_HWR 0x00000400U -#define RGXFWIF_LOG_TYPE_GROUP_HWP 0x00000800U -#define RGXFWIF_LOG_TYPE_GROUP_RPM 0x00001000U -#define RGXFWIF_LOG_TYPE_GROUP_DMA 0x00002000U -#define RGXFWIF_LOG_TYPE_GROUP_MISC 0x00004000U -#define RGXFWIF_LOG_TYPE_GROUP_DEBUG 0x80000000U -#define RGXFWIF_LOG_TYPE_GROUP_MASK 0x80007FFEU -#define RGXFWIF_LOG_TYPE_MASK 0x80007FFFU - -/* String used in pvrdebug -h output */ -#define RGXFWIF_LOG_GROUPS_STRING_LIST "main,mts,cleanup,csw,bif,pm,rtd,spm,pow,hwr,hwp,rpm,dma,misc,debug" - -/* Table entry to map log group strings to log type value */ -typedef struct { - const IMG_CHAR* pszLogGroupName; - IMG_UINT32 ui32LogGroupType; -} RGXFWIF_LOG_GROUP_MAP_ENTRY; - -/* - Macro for use with the RGXFWIF_LOG_GROUP_MAP_ENTRY type to create a lookup - table where needed. Keep log group names short, no more than 20 chars. -*/ -#define RGXFWIF_LOG_GROUP_NAME_VALUE_MAP { "none", RGXFWIF_LOG_TYPE_NONE }, \ - { "main", RGXFWIF_LOG_TYPE_GROUP_MAIN }, \ - { "mts", RGXFWIF_LOG_TYPE_GROUP_MTS }, \ - { "cleanup", RGXFWIF_LOG_TYPE_GROUP_CLEANUP }, \ - { "csw", RGXFWIF_LOG_TYPE_GROUP_CSW }, \ - { "bif", RGXFWIF_LOG_TYPE_GROUP_BIF }, \ - { "pm", RGXFWIF_LOG_TYPE_GROUP_PM }, \ - { "rtd", RGXFWIF_LOG_TYPE_GROUP_RTD }, \ - { "spm", RGXFWIF_LOG_TYPE_GROUP_SPM }, \ - { "pow", RGXFWIF_LOG_TYPE_GROUP_POW }, \ - { "hwr", RGXFWIF_LOG_TYPE_GROUP_HWR }, \ - { "hwp", RGXFWIF_LOG_TYPE_GROUP_HWP }, \ - { "rpm", RGXFWIF_LOG_TYPE_GROUP_RPM }, \ - { "dma", RGXFWIF_LOG_TYPE_GROUP_DMA }, \ - { "misc", RGXFWIF_LOG_TYPE_GROUP_MISC }, \ - { "debug", RGXFWIF_LOG_TYPE_GROUP_DEBUG } - - -/* Used in print statements to display log group state, one %s per group defined */ -#define RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" - -/* Used in a print statement to display log group state, one per group */ -#define RGXFWIF_LOG_ENABLED_GROUPS_LIST(types) ((((types) & RGXFWIF_LOG_TYPE_GROUP_MAIN) != 0U) ?("main ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_MTS) != 0U) ?("mts ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_CLEANUP) != 0U) ?("cleanup ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_CSW) != 0U) ?("csw ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_BIF) != 0U) ?("bif ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_PM) != 0U) ?("pm ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_RTD) != 0U) ?("rtd ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_SPM) != 0U) ?("spm ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_POW) != 0U) ?("pow ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_HWR) != 0U) ?("hwr ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_HWP) != 0U) ?("hwp ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_RPM) != 0U) ?("rpm ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_DMA) != 0U) ?("dma ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_MISC) != 0U) ?("misc ") :("")), \ - ((((types) & RGXFWIF_LOG_TYPE_GROUP_DEBUG) != 0U) ?("debug ") :("")) - - -/************************************************************************ -* RGX FW signature checks -************************************************************************/ -#define RGXFW_SIG_BUFFER_SIZE_MIN (8192) - -#define RGXFWIF_TIMEDIFF_ID ((0x1UL << 28) | RGX_CR_TIMER) - -/*! - ****************************************************************************** - * Trace Buffer - *****************************************************************************/ - -/*! Default size of RGXFWIF_TRACEBUF_SPACE in DWords */ -#define RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS 12000U -#define RGXFW_TRACE_BUFFER_ASSERT_SIZE 200U -#if defined(RGXFW_META_SUPPORT_2ND_THREAD) -#define RGXFW_THREAD_NUM 2U -#else -#define RGXFW_THREAD_NUM 1U -#endif - -#define RGXFW_POLL_TYPE_SET 0x80000000U - -typedef struct -{ - IMG_CHAR szPath[RGXFW_TRACE_BUFFER_ASSERT_SIZE]; - IMG_CHAR szInfo[RGXFW_TRACE_BUFFER_ASSERT_SIZE]; - IMG_UINT32 ui32LineNum; -} UNCACHED_ALIGN RGXFWIF_FILE_INFO_BUF; - -/*! - * @Defgroup SRVAndFWTracing Services and Firmware Tracing data interface - * @Brief The document groups/lists the data structures and the interfaces related to Services and Firmware Tracing - * @{ - */ - -/*! - * @Brief Firmware trace buffer details - */ -typedef struct -{ - IMG_UINT32 ui32TracePointer; /*!< Trace pointer (write index into Trace Buffer)*/ - -#if defined(RGX_FIRMWARE) - IMG_UINT32 *pui32RGXFWIfTraceBuffer; /*!< Trace buffer address (FW address), to be used by firmware for writing into trace buffer */ -#else - RGXFWIF_DEV_VIRTADDR pui32RGXFWIfTraceBuffer; /*!< Trace buffer address (FW address)*/ -#endif - IMG_PUINT32 pui32TraceBuffer; /*!< Trace buffer address (Host address), to be used by host when reading from trace buffer */ - - RGXFWIF_FILE_INFO_BUF sAssertBuf; -} UNCACHED_ALIGN RGXFWIF_TRACEBUF_SPACE; - -/*! @} End of Defgroup SRVAndFWTracing */ - -#define RGXFWIF_FWFAULTINFO_MAX (8U) /* Total number of FW fault logs stored */ - -typedef struct -{ - IMG_UINT64 RGXFW_ALIGN ui64CRTimer; - IMG_UINT64 RGXFW_ALIGN ui64OSTimer; - IMG_UINT32 RGXFW_ALIGN ui32Data; - IMG_UINT32 ui32Reserved; - RGXFWIF_FILE_INFO_BUF sFaultBuf; -} UNCACHED_ALIGN RGX_FWFAULTINFO; - - -#define RGXFWIF_POW_STATES \ - X(RGXFWIF_POW_OFF) /* idle and handshaked with the host (ready to full power down) */ \ - X(RGXFWIF_POW_ON) /* running HW commands */ \ - X(RGXFWIF_POW_FORCED_IDLE) /* forced idle */ \ - X(RGXFWIF_POW_IDLE) /* idle waiting for host handshake */ - -typedef enum -{ -#define X(NAME) NAME, - RGXFWIF_POW_STATES -#undef X -} RGXFWIF_POW_STATE; - -/* Firmware HWR states */ -#define RGXFWIF_HWR_HARDWARE_OK (IMG_UINT32_C(0x1) << 0U) /*!< The HW state is ok or locked up */ -#define RGXFWIF_HWR_RESET_IN_PROGRESS (IMG_UINT32_C(0x1) << 1U) /*!< Tells if a HWR reset is in progress */ -#define RGXFWIF_HWR_GENERAL_LOCKUP (IMG_UINT32_C(0x1) << 3U) /*!< A DM unrelated lockup has been detected */ -#define RGXFWIF_HWR_DM_RUNNING_OK (IMG_UINT32_C(0x1) << 4U) /*!< At least one DM is running without being close to a lockup */ -#define RGXFWIF_HWR_DM_STALLING (IMG_UINT32_C(0x1) << 5U) /*!< At least one DM is close to lockup */ -#define RGXFWIF_HWR_FW_FAULT (IMG_UINT32_C(0x1) << 6U) /*!< The FW has faulted and needs to restart */ -#define RGXFWIF_HWR_RESTART_REQUESTED (IMG_UINT32_C(0x1) << 7U) /*!< The FW has requested the host to restart it */ - -#define RGXFWIF_PHR_STATE_SHIFT (8U) -#define RGXFWIF_PHR_RESTART_REQUESTED (IMG_UINT32_C(1) << RGXFWIF_PHR_STATE_SHIFT) /*!< The FW has requested the host to restart it, per PHR configuration */ -#define RGXFWIF_PHR_RESTART_FINISHED (IMG_UINT32_C(2) << RGXFWIF_PHR_STATE_SHIFT) /*!< A PHR triggered GPU reset has just finished */ -#define RGXFWIF_PHR_RESTART_MASK (RGXFWIF_PHR_RESTART_REQUESTED | RGXFWIF_PHR_RESTART_FINISHED) - -#define RGXFWIF_PHR_MODE_OFF (0UL) -#define RGXFWIF_PHR_MODE_RD_RESET (1UL) -#define RGXFWIF_PHR_MODE_FULL_RESET (2UL) - -typedef IMG_UINT32 RGXFWIF_HWR_STATEFLAGS; - -/* Firmware per-DM HWR states */ -#define RGXFWIF_DM_STATE_WORKING (0x00U) /*!< DM is working if all flags are cleared */ -#define RGXFWIF_DM_STATE_READY_FOR_HWR (IMG_UINT32_C(0x1) << 0) /*!< DM is idle and ready for HWR */ -#define RGXFWIF_DM_STATE_NEEDS_SKIP (IMG_UINT32_C(0x1) << 2) /*!< DM need to skip to next cmd before resuming processing */ -#define RGXFWIF_DM_STATE_NEEDS_PR_CLEANUP (IMG_UINT32_C(0x1) << 3) /*!< DM need partial render cleanup before resuming processing */ -#define RGXFWIF_DM_STATE_NEEDS_TRACE_CLEAR (IMG_UINT32_C(0x1) << 4) /*!< DM need to increment Recovery Count once fully recovered */ -#define RGXFWIF_DM_STATE_GUILTY_LOCKUP (IMG_UINT32_C(0x1) << 5) /*!< DM was identified as locking up and causing HWR */ -#define RGXFWIF_DM_STATE_INNOCENT_LOCKUP (IMG_UINT32_C(0x1) << 6) /*!< DM was innocently affected by another lockup which caused HWR */ -#define RGXFWIF_DM_STATE_GUILTY_OVERRUNING (IMG_UINT32_C(0x1) << 7) /*!< DM was identified as over-running and causing HWR */ -#define RGXFWIF_DM_STATE_INNOCENT_OVERRUNING (IMG_UINT32_C(0x1) << 8) /*!< DM was innocently affected by another DM over-running which caused HWR */ -#define RGXFWIF_DM_STATE_HARD_CONTEXT_SWITCH (IMG_UINT32_C(0x1) << 9) /*!< DM was forced into HWR as it delayed more important workloads */ -#define RGXFWIF_DM_STATE_GPU_ECC_HWR (IMG_UINT32_C(0x1) << 10) /*!< DM was forced into HWR due to an uncorrected GPU ECC error */ - -/* Firmware's connection state */ -typedef IMG_UINT32 RGXFWIF_CONNECTION_FW_STATE; -#define RGXFW_CONNECTION_FW_OFFLINE 0U /*!< Firmware is offline */ -#define RGXFW_CONNECTION_FW_READY 1U /*!< Firmware is initialised */ -#define RGXFW_CONNECTION_FW_ACTIVE 2U /*!< Firmware connection is fully established */ -#define RGXFW_CONNECTION_FW_OFFLOADING 3U /*!< Firmware is clearing up connection data */ -#define RGXFW_CONNECTION_FW_STATE_COUNT 4U - -/* OS' connection state */ -typedef enum -{ - RGXFW_CONNECTION_OS_OFFLINE = 0, /*!< OS is offline */ - RGXFW_CONNECTION_OS_READY, /*!< OS's KM driver is setup and waiting */ - RGXFW_CONNECTION_OS_ACTIVE, /*!< OS connection is fully established */ - RGXFW_CONNECTION_OS_STATE_COUNT -} RGXFWIF_CONNECTION_OS_STATE; - -typedef struct -{ - IMG_UINT bfOsState : 3; - IMG_UINT bfFLOk : 1; - IMG_UINT bfFLGrowPending : 1; - IMG_UINT bfIsolatedOS : 1; - IMG_UINT bfReserved : 26; -} RGXFWIF_OS_RUNTIME_FLAGS; - -typedef IMG_UINT32 RGXFWIF_HWR_RECOVERYFLAGS; - -#if defined(PVRSRV_STALLED_CCB_ACTION) -#define PVR_SLR_LOG_ENTRIES 10U -#define PVR_SLR_LOG_STRLEN 30 /*!< MAX_CLIENT_CCB_NAME not visible to this header */ - -typedef struct -{ - IMG_UINT64 RGXFW_ALIGN ui64Timestamp; - IMG_UINT32 ui32FWCtxAddr; - IMG_UINT32 ui32NumUFOs; - IMG_CHAR aszCCBName[PVR_SLR_LOG_STRLEN]; -} UNCACHED_ALIGN RGXFWIF_SLR_ENTRY; -#endif - -/*! - * @InGroup SRVAndFWTracing - * @Brief Firmware trace control data - */ -typedef struct -{ - IMG_UINT32 ui32LogType; /*!< FW trace log group configuration */ - RGXFWIF_TRACEBUF_SPACE sTraceBuf[RGXFW_THREAD_NUM]; /*!< FW Trace buffer */ - IMG_UINT32 ui32TraceBufSizeInDWords; /*!< FW Trace buffer size in dwords, Member initialised only when sTraceBuf is actually allocated - (in RGXTraceBufferInitOnDemandResources) */ - IMG_UINT32 ui32TracebufFlags; /*!< Compatibility and other flags */ -} UNCACHED_ALIGN RGXFWIF_TRACEBUF; - -/*! @Brief Firmware system data shared with the Host driver */ -typedef struct -{ - IMG_UINT32 ui32ConfigFlags; /*!< Configuration flags from host */ - IMG_UINT32 ui32ConfigFlagsExt; /*!< Extended configuration flags from host */ - volatile RGXFWIF_POW_STATE ePowState; - volatile IMG_UINT32 ui32HWPerfRIdx; - volatile IMG_UINT32 ui32HWPerfWIdx; - volatile IMG_UINT32 ui32HWPerfWrapCount; - IMG_UINT32 ui32HWPerfSize; /*!< Constant after setup, needed in FW */ - IMG_UINT32 ui32HWPerfDropCount; /*!< The number of times the FW drops a packet due to buffer full */ - - /* ui32HWPerfUt, ui32FirstDropOrdinal, ui32LastDropOrdinal only valid when FW is built with - * RGX_HWPERF_UTILIZATION & RGX_HWPERF_DROP_TRACKING defined in rgxfw_hwperf.c */ - IMG_UINT32 ui32HWPerfUt; /*!< Buffer utilisation, high watermark of bytes in use */ - IMG_UINT32 ui32FirstDropOrdinal; /*!< The ordinal of the first packet the FW dropped */ - IMG_UINT32 ui32LastDropOrdinal; /*!< The ordinal of the last packet the FW dropped */ - RGXFWIF_OS_RUNTIME_FLAGS asOsRuntimeFlagsMirror[RGXFW_MAX_NUM_OS];/*!< State flags for each Operating System mirrored from Fw coremem */ - RGX_FWFAULTINFO sFaultInfo[RGXFWIF_FWFAULTINFO_MAX]; /*!< Firmware fault info */ - IMG_UINT32 ui32FWFaults; /*!< Firmware faults count */ - IMG_UINT32 aui32CrPollAddr[RGXFW_THREAD_NUM]; /*!< Failed poll address */ - IMG_UINT32 aui32CrPollMask[RGXFW_THREAD_NUM]; /*!< Failed poll mask */ - IMG_UINT32 aui32CrPollCount[RGXFW_THREAD_NUM]; /*!< Failed poll count */ - IMG_UINT64 RGXFW_ALIGN ui64StartIdleTime; -#if defined(SUPPORT_POWMON_COMPONENT) -#if defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS) - RGXFWIF_TRACEBUF_SPACE sPowerMonBuf; - IMG_UINT32 ui32PowerMonBufSizeInDWords; -#endif -#endif - -#if defined(SUPPORT_RGXFW_STATS_FRAMEWORK) -#define RGXFWIF_STATS_FRAMEWORK_LINESIZE (8) -#define RGXFWIF_STATS_FRAMEWORK_MAX (2048*RGXFWIF_STATS_FRAMEWORK_LINESIZE) - IMG_UINT32 RGXFW_ALIGN aui32FWStatsBuf[RGXFWIF_STATS_FRAMEWORK_MAX]; -#endif - RGXFWIF_HWR_STATEFLAGS ui32HWRStateFlags; /*!< Firmware's Current HWR state */ - RGXFWIF_HWR_RECOVERYFLAGS aui32HWRRecoveryFlags[RGXFWIF_DM_MAX]; /*!< Each DM's HWR state */ - IMG_UINT32 ui32FwSysDataFlags; /*!< Compatibility and other flags */ - IMG_UINT32 ui32McConfig; /*!< Identify whether MC config is P-P or P-S */ -} UNCACHED_ALIGN RGXFWIF_SYSDATA; - -/*! - * @InGroup ContextSwitching - * @Brief Firmware per-os data and configuration - */ -typedef struct -{ - IMG_UINT32 ui32FwOsConfigFlags; /*!< Configuration flags from an OS */ - IMG_UINT32 ui32FWSyncCheckMark; /*!< Markers to signal that the host should perform a full sync check */ - IMG_UINT32 ui32HostSyncCheckMark; /*!< Markers to signal that the Firmware should perform a full sync check */ -#if defined(PVRSRV_STALLED_CCB_ACTION) - IMG_UINT32 ui32ForcedUpdatesRequested; - IMG_UINT8 ui8SLRLogWp; - RGXFWIF_SLR_ENTRY sSLRLogFirst; - RGXFWIF_SLR_ENTRY sSLRLog[PVR_SLR_LOG_ENTRIES]; - IMG_UINT64 RGXFW_ALIGN ui64LastForcedUpdateTime; -#endif - volatile IMG_UINT32 aui32InterruptCount[RGXFW_THREAD_NUM]; /*!< Interrupt count from Threads > */ - IMG_UINT32 ui32KCCBCmdsExecuted; /*!< Executed Kernel CCB command count */ - RGXFWIF_DEV_VIRTADDR sPowerSync; /*!< Sync prim used to signal the host the power off state */ - IMG_UINT32 ui32FwOsDataFlags; /*!< Compatibility and other flags */ -} UNCACHED_ALIGN RGXFWIF_OSDATA; - -/* Firmware trace time-stamp field breakup */ - -/* RGX_CR_TIMER register read (48 bits) value*/ -#define RGXFWT_TIMESTAMP_TIME_SHIFT (0U) -#define RGXFWT_TIMESTAMP_TIME_CLRMSK (IMG_UINT64_C(0xFFFF000000000000)) - -/* Extra debug-info (16 bits) */ -#define RGXFWT_TIMESTAMP_DEBUG_INFO_SHIFT (48U) -#define RGXFWT_TIMESTAMP_DEBUG_INFO_CLRMSK ~RGXFWT_TIMESTAMP_TIME_CLRMSK - - -/* Debug-info sub-fields */ -/* Bit 0: RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT bit from RGX_CR_EVENT_STATUS register */ -#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT (0U) -#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET (1U << RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT) - -/* Bit 1: RGX_CR_BIF_MMU_ENTRY_PENDING bit from RGX_CR_BIF_MMU_ENTRY register */ -#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT (1U) -#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET (1U << RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT) - -/* Bit 2: RGX_CR_SLAVE_EVENT register is non-zero */ -#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT (2U) -#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET (1U << RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT) - -/* Bit 3-15: Unused bits */ - -#define RGXFWT_DEBUG_INFO_STR_MAXLEN 64 -#define RGXFWT_DEBUG_INFO_STR_PREPEND " (debug info: " -#define RGXFWT_DEBUG_INFO_STR_APPEND ")" - -/* Table of debug info sub-field's masks and corresponding message strings - * to be appended to firmware trace - * - * Mask : 16 bit mask to be applied to debug-info field - * String : debug info message string - */ - -#define RGXFWT_DEBUG_INFO_MSKSTRLIST \ -/*Mask, String*/ \ -X(RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET, "mmu pf") \ -X(RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET, "mmu pending") \ -X(RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET, "slave events") - -/*! - ****************************************************************************** - * HWR Data - *****************************************************************************/ -/*! - * @Defgroup HWRInfo FW HWR shared data interface - * @Brief Types grouping data structures and defines used in realising the HWR record. - * @{ - */ -/*! @Brief HWR Lockup types */ -typedef enum -{ - RGX_HWRTYPE_UNKNOWNFAILURE = 0, /*!< Unknown failure */ - RGX_HWRTYPE_OVERRUN = 1, /*!< DM overrun */ - RGX_HWRTYPE_POLLFAILURE = 2, /*!< Poll failure */ - RGX_HWRTYPE_BIF0FAULT = 3, /*!< BIF0 fault */ - RGX_HWRTYPE_BIF1FAULT = 4, /*!< BIF1 fault */ - RGX_HWRTYPE_TEXASBIF0FAULT = 5, /*!< TEXASBIF0 fault */ - RGX_HWRTYPE_MMUFAULT = 6, /*!< MMU fault */ - RGX_HWRTYPE_MMUMETAFAULT = 7, /*!< MMU META fault */ - RGX_HWRTYPE_MIPSTLBFAULT = 8, /*!< MIPS TLB fault */ - RGX_HWRTYPE_ECCFAULT = 9, /*!< ECC fault */ - RGX_HWRTYPE_MMURISCVFAULT = 10, /*!< MMU RISCV fault */ -} RGX_HWRTYPE; - -#define RGXFWIF_HWRTYPE_BIF_BANK_GET(eHWRType) (((eHWRType) == RGX_HWRTYPE_BIF0FAULT) ? 0 : 1) - -#define RGXFWIF_HWRTYPE_PAGE_FAULT_GET(eHWRType) ((((eHWRType) == RGX_HWRTYPE_BIF0FAULT) || \ - ((eHWRType) == RGX_HWRTYPE_BIF1FAULT) || \ - ((eHWRType) == RGX_HWRTYPE_TEXASBIF0FAULT) || \ - ((eHWRType) == RGX_HWRTYPE_MMUFAULT) || \ - ((eHWRType) == RGX_HWRTYPE_MMUMETAFAULT) || \ - ((eHWRType) == RGX_HWRTYPE_MIPSTLBFAULT) || \ - ((eHWRType) == RGX_HWRTYPE_MMURISCVFAULT)) ? true : false) - -typedef struct -{ - IMG_UINT64 RGXFW_ALIGN ui64BIFReqStatus; /*!< BIF request status */ - IMG_UINT64 RGXFW_ALIGN ui64BIFMMUStatus; /*!< MMU status */ - IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */ - IMG_UINT64 RGXFW_ALIGN ui64Reserved; -} RGX_BIFINFO; - -typedef struct -{ - IMG_UINT32 ui32FaultGPU; /*!< ECC fault in GPU */ -} RGX_ECCINFO; - -typedef struct -{ - IMG_UINT64 RGXFW_ALIGN aui64MMUStatus[2]; /*!< MMU status */ - IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */ - IMG_UINT64 RGXFW_ALIGN ui64Reserved; -} RGX_MMUINFO; - -typedef struct -{ - IMG_UINT32 ui32ThreadNum; /*!< Thread ID performing poll operation */ - IMG_UINT32 ui32CrPollAddr; /*!< CR Poll Address */ - IMG_UINT32 ui32CrPollMask; /*!< CR Poll mask */ - IMG_UINT32 ui32CrPollLastValue; /*!< CR Poll last value */ - IMG_UINT64 RGXFW_ALIGN ui64Reserved; -} UNCACHED_ALIGN RGX_POLLINFO; - -typedef struct -{ - IMG_UINT32 ui32BadVAddr; /*!< VA address */ - IMG_UINT32 ui32EntryLo; -} RGX_TLBINFO; - -/*! @Brief Structure to keep information specific to a lockup e.g. DM, timer, lockup type etc. */ -typedef struct -{ - union - { - RGX_BIFINFO sBIFInfo; /*!< BIF failure details */ - RGX_MMUINFO sMMUInfo; /*!< MMU failure details */ - RGX_POLLINFO sPollInfo; /*!< Poll failure details */ - RGX_TLBINFO sTLBInfo; /*!< TLB failure details */ - RGX_ECCINFO sECCInfo; /*!< ECC failure details */ - } uHWRData; - - IMG_UINT64 RGXFW_ALIGN ui64CRTimer; /*!< Timer value at the time of lockup */ - IMG_UINT64 RGXFW_ALIGN ui64OSTimer; /*!< OS timer value at the time of lockup */ - IMG_UINT32 ui32FrameNum; /*!< Frame number of the workload */ - IMG_UINT32 ui32PID; /*!< PID belonging to the workload */ - IMG_UINT32 ui32ActiveHWRTData; /*!< HWRT data of the workload */ - IMG_UINT32 ui32HWRNumber; /*!< HWR number */ - IMG_UINT32 ui32EventStatus; /*!< Core specific event status register at the time of lockup */ - IMG_UINT32 ui32HWRRecoveryFlags; /*!< DM state flags */ - RGX_HWRTYPE eHWRType; /*!< Type of lockup */ - RGXFWIF_DM eDM; /*!< Recovery triggered for the DM */ - IMG_UINT32 ui32CoreID; /*!< Core ID of the GPU */ - IMG_UINT64 RGXFW_ALIGN ui64CRTimeOfKick; /*!< Workload kick time */ - IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetStart; /*!< HW reset start time */ - IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetFinish; /*!< HW reset stop time */ - IMG_UINT64 RGXFW_ALIGN ui64CRTimeFreelistReady; /*!< freelist ready time on the last HWR */ - IMG_UINT64 RGXFW_ALIGN ui64Reserved[2]; -} UNCACHED_ALIGN RGX_HWRINFO; - -#define RGXFWIF_HWINFO_MAX_FIRST 8U /* Number of first HWR logs recorded (never overwritten by newer logs) */ -#define RGXFWIF_HWINFO_MAX_LAST 8U /* Number of latest HWR logs (older logs are overwritten by newer logs) */ -#define RGXFWIF_HWINFO_MAX (RGXFWIF_HWINFO_MAX_FIRST + RGXFWIF_HWINFO_MAX_LAST) /* Total number of HWR logs stored in a buffer */ -#define RGXFWIF_HWINFO_LAST_INDEX (RGXFWIF_HWINFO_MAX - 1U) /* Index of the last log in the HWR log buffer */ - -/*! @Brief Firmware HWR information structure allocated by the Services and used by the Firmware to update recovery information. */ -typedef struct -{ - RGX_HWRINFO sHWRInfo[RGXFWIF_HWINFO_MAX]; /*!< Max number of recovery record */ - IMG_UINT32 ui32HwrCounter; /*!< HWR counter used in FL reconstruction */ - IMG_UINT32 ui32WriteIndex; /*!< Index for updating recovery information in sHWRInfo */ - IMG_UINT32 ui32DDReqCount; /*!< Count of DebugDump requested to the host after recovery */ - IMG_UINT32 ui32HWRInfoBufFlags; /* Compatibility and other flags */ - IMG_UINT32 aui32HwrDmLockedUpCount[RGXFWIF_DM_MAX]; /*!< Lockup count for each DM */ - IMG_UINT32 aui32HwrDmOverranCount[RGXFWIF_DM_MAX]; /*!< Overrun count for each DM */ - IMG_UINT32 aui32HwrDmRecoveredCount[RGXFWIF_DM_MAX]; /*!< Lockup + Overrun count for each DM */ - IMG_UINT32 aui32HwrDmFalseDetectCount[RGXFWIF_DM_MAX]; /*!< False lockup detection count for each DM */ -} UNCACHED_ALIGN RGXFWIF_HWRINFOBUF; - -/*! @} End of HWRInfo */ - -#define RGXFWIF_CTXSWITCH_PROFILE_FAST_EN (IMG_UINT32_C(0x1)) -#define RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN (IMG_UINT32_C(0x2)) -#define RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN (IMG_UINT32_C(0x3)) -#define RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN (IMG_UINT32_C(0x4)) - -#define RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN (IMG_UINT32_C(0x1)) -#define RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN (IMG_UINT32_C(0x2)) - -#define RGXFWIF_ISP_SCHEDMODE_VER1_IPP (IMG_UINT32_C(0x1)) -#define RGXFWIF_ISP_SCHEDMODE_VER2_ISP (IMG_UINT32_C(0x2)) -/*! - ****************************************************************************** - * RGX firmware Init Config Data - *****************************************************************************/ - -/* Flag definitions affecting the firmware globally */ -#define RGXFWIF_INICFG_CTXSWITCH_MODE_RAND (IMG_UINT32_C(0x1) << 0) -#define RGXFWIF_INICFG_CTXSWITCH_SRESET_EN (IMG_UINT32_C(0x1) << 1) -#define RGXFWIF_INICFG_HWPERF_EN (IMG_UINT32_C(0x1) << 2) -#define RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN (IMG_UINT32_C(0x1) << 3) -#define RGXFWIF_INICFG_POW_RASCALDUST (IMG_UINT32_C(0x1) << 4) -/* 5 unused */ -#define RGXFWIF_INICFG_FBCDC_V3_1_EN (IMG_UINT32_C(0x1) << 6) -#define RGXFWIF_INICFG_CHECK_MLIST_EN (IMG_UINT32_C(0x1) << 7) -#define RGXFWIF_INICFG_DISABLE_CLKGATING_EN (IMG_UINT32_C(0x1) << 8) -/* 9 unused */ -/* 10 unused */ -/* 11 unused */ -#define RGXFWIF_INICFG_REGCONFIG_EN (IMG_UINT32_C(0x1) << 12) -#define RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY (IMG_UINT32_C(0x1) << 13) -#define RGXFWIF_INICFG_HWP_DISABLE_FILTER (IMG_UINT32_C(0x1) << 14) -/* 15 unused */ -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT (16) -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_FAST (RGXFWIF_CTXSWITCH_PROFILE_FAST_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MEDIUM (RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SLOW (RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_NODELAY (RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) -#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK (IMG_UINT32_C(0x7) << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) -#define RGXFWIF_INICFG_DISABLE_DM_OVERLAP (IMG_UINT32_C(0x1) << 19) -#define RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER (IMG_UINT32_C(0x1) << 20) -#define RGXFWIF_INICFG_FABRIC_COHERENCY_ENABLED (IMG_UINT32_C(0x1) << 21) -#define RGXFWIF_INICFG_VALIDATE_IRQ (IMG_UINT32_C(0x1) << 22) -#define RGXFWIF_INICFG_DISABLE_PDP_EN (IMG_UINT32_C(0x1) << 23) -#define RGXFWIF_INICFG_SPU_POWER_STATE_MASK_CHANGE_EN (IMG_UINT32_C(0x1) << 24) -#define RGXFWIF_INICFG_WORKEST (IMG_UINT32_C(0x1) << 25) -#define RGXFWIF_INICFG_PDVFS (IMG_UINT32_C(0x1) << 26) -#define RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT (27) -#define RGXFWIF_INICFG_CDM_ARBITRATION_TASK_DEMAND (RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT) -#define RGXFWIF_INICFG_CDM_ARBITRATION_ROUND_ROBIN (RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT) -#define RGXFWIF_INICFG_CDM_ARBITRATION_MASK (IMG_UINT32_C(0x3) << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT) -#define RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT (29) -#define RGXFWIF_INICFG_ISPSCHEDMODE_NONE (0) -#define RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP (RGXFWIF_ISP_SCHEDMODE_VER1_IPP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT) -#define RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP (RGXFWIF_ISP_SCHEDMODE_VER2_ISP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT) -#define RGXFWIF_INICFG_ISPSCHEDMODE_MASK (RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP |\ - RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP) -#define RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER (IMG_UINT32_C(0x1) << 31) - -#define RGXFWIF_INICFG_ALL (0xFFFFFFFFU) - -/* Extended Flag definitions affecting the firmware globally */ -#define RGXFWIF_INICFG_EXT_TFBC_CONTROL_SHIFT (0) -/* [7] YUV10 override - * [6:4] Quality - * [3] Quality enable - * [2:1] Compression scheme - * [0] Lossy group */ -#define RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK (IMG_UINT32_C(0xFF)) /* RGX_CR_TFBC_COMPRESSION_CONTROL_MASKFULL */ -#define RGXFWIF_INICFG_EXT_ALL (RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK) - -#define RGXFWIF_INICFG_SYS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_CTXSWITCH_MODE_RAND | \ - RGXFWIF_INICFG_CTXSWITCH_SRESET_EN) - -/* Flag definitions affecting only workloads submitted by a particular OS */ - -/*! - * @AddToGroup ContextSwitching - * @{ - * @Name Per-OS DM context switch configuration flags - * @{ - */ -#define RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN (IMG_UINT32_C(0x1) << 0) /*!< Enables TDM context switch */ -#define RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN (IMG_UINT32_C(0x1) << 1) /*!< Enables GEOM DM context switch */ -#define RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN (IMG_UINT32_C(0x1) << 2) /*!< Enables FRAG DM context switch */ -#define RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN (IMG_UINT32_C(0x1) << 3) /*!< Enables CDM context switch */ - -#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_TDM (IMG_UINT32_C(0x1) << 4) -#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_GEOM (IMG_UINT32_C(0x1) << 5) -#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_3D (IMG_UINT32_C(0x1) << 6) -#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_CDM (IMG_UINT32_C(0x1) << 7) - -#define RGXFWIF_INICFG_OS_ALL (0xFFU) - -#define RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL (RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN | \ - RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN | \ - RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN | \ - RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN) - -#define RGXFWIF_INICFG_OS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL) - -/*! - * @} End of Per-OS Context switch configuration flags - * @} End of AddToGroup ContextSwitching - */ - -#define RGXFWIF_FILTCFG_TRUNCATE_HALF (IMG_UINT32_C(0x1) << 3) -#define RGXFWIF_FILTCFG_TRUNCATE_INT (IMG_UINT32_C(0x1) << 2) -#define RGXFWIF_FILTCFG_NEW_FILTER_MODE (IMG_UINT32_C(0x1) << 1) - -typedef IMG_UINT32 RGX_ACTIVEPM_CONF; -#define RGX_ACTIVEPM_FORCE_OFF 0U -#define RGX_ACTIVEPM_FORCE_ON 1U -#define RGX_ACTIVEPM_DEFAULT 2U - -typedef enum -{ - RGX_RD_POWER_ISLAND_FORCE_OFF = 0, - RGX_RD_POWER_ISLAND_FORCE_ON = 1, - RGX_RD_POWER_ISLAND_DEFAULT = 2 -} RGX_RD_POWER_ISLAND_CONF; - -#if defined(RGX_FW_IRQ_OS_COUNTERS) -/* Unused registers re-purposed for storing counters of the Firmware's - * interrupts for each OS - */ -#define IRQ_COUNTER_STORAGE_REGS \ - 0x2028U, /* RGX_CR_PM_TA_MMU_FSTACK */ \ - 0x2050U, /* RGX_CR_PM_3D_MMU_FSTACK */ \ - 0x2030U, /* RGX_CR_PM_START_OF_MMU_TACONTEXT*/ \ - 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \ - 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \ - 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \ - 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \ - 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ -#endif - -typedef struct -{ - IMG_UINT16 ui16RegNum; /*!< Register number */ - IMG_UINT16 ui16IndirectRegNum; /*!< Indirect register number (or 0 if not used) */ - IMG_UINT16 ui16IndirectStartVal; /*!< Start value for indirect register */ - IMG_UINT16 ui16IndirectEndVal; /*!< End value for indirect register */ -} RGXFW_REGISTER_LIST; - -#if defined(RGX_FIRMWARE) -typedef DLLIST_NODE RGXFWIF_DLLIST_NODE; -#else -typedef struct {RGXFWIF_DEV_VIRTADDR p; - RGXFWIF_DEV_VIRTADDR n;} RGXFWIF_DLLIST_NODE; -#endif - -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SIGBUFFER; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TRACEBUF; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SYSDATA; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_OSDATA; -#if defined(SUPPORT_TBI_INTERFACE) -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TBIBUF; -#endif -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERFBUF; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRINFOBUF; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RUNTIME_CFG; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_GPU_UTIL_FWCB; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_REG_CFG; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERF_CTL; -typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_CONFIG_MUX_CNTBLK; -typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_CONFIG_CNTBLK; -typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_SELECT_CUSTOM_CNTRS; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_CTL; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_RTN_SLOTS; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWMEMCONTEXT; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWCOMMONCONTEXT; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_ZSBUFFER; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_COMMONCTX_STATE; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CORE_CLK_RATE; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_COUNTERBUFFER; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FIRMWAREGCOVBUFFER; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB_CTL; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FREELIST; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRTDATA; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TIMESTAMP_ADDR; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RF_CMD; - -/*! - * This number is used to represent an invalid page catalogue physical address - */ -#define RGXFWIF_INVALID_PC_PHYADDR 0xFFFFFFFFFFFFFFFFLLU - -/*! - * This number is used to represent unallocated page catalog base register - */ -#define RGXFW_BIF_INVALID_PCSET 0xFFFFFFFFU - -/*! - Firmware memory context. -*/ -typedef struct -{ - IMG_DEV_PHYADDR RGXFW_ALIGN sPCDevPAddr; /*!< device physical address of context's page catalogue */ - IMG_UINT32 uiPageCatBaseRegSet; /*!< associated page catalog base register (RGXFW_BIF_INVALID_PCSET == unallocated) */ - IMG_UINT32 uiBreakpointAddr; /*!< breakpoint address */ - IMG_UINT32 uiBPHandlerAddr; /*!< breakpoint handler address */ - IMG_UINT32 uiBreakpointCtl; /*!< DM and enable control for BP */ - IMG_UINT32 ui32FwMemCtxFlags; /*!< Compatibility and other flags */ - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - IMG_UINT32 ui32OSid; - IMG_BOOL bOSidAxiProt; -#endif - -} UNCACHED_ALIGN RGXFWIF_FWMEMCONTEXT; - -/*! - * FW context state flags - */ -#define RGXFWIF_CONTEXT_FLAGS_NEED_RESUME (0x00000001U) -#define RGXFWIF_CONTEXT_FLAGS_MC_NEED_RESUME_MASKFULL (0x000000FFU) -#define RGXFWIF_CONTEXT_FLAGS_TDM_HEADER_STALE (0x00000100U) -#define RGXFWIF_CONTEXT_FLAGS_LAST_KICK_SECURE (0x00000200U) - -/*! - * @InGroup ContextSwitching - * @Brief Firmware GEOM/TA context suspend state - */ -typedef struct -{ - /* FW-accessible TA state which must be written out to memory on context store */ - IMG_UINT64 RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER; /*!< VDM control stream stack pointer, to store in mid-TA */ - IMG_UINT64 RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER_Init; /*!< Initial value of VDM control stream stack pointer (in case is 'lost' due to a lock-up) */ - IMG_UINT32 uTAReg_VBS_SO_PRIM[4]; - IMG_UINT16 ui16TACurrentIdx; -} UNCACHED_ALIGN RGXFWIF_TACTX_STATE_PER_GEOM; - -typedef struct -{ - /* FW-accessible TA state which must be written out to memory on context store */ - RGXFWIF_TACTX_STATE_PER_GEOM asGeomCore[RGX_NUM_GEOM_CORES]; -} UNCACHED_ALIGN RGXFWIF_TACTX_STATE; - -/*! - * @InGroup ContextSwitching - * @Brief Firmware FRAG/3D context suspend state - */ -typedef struct -{ - /* FW-accessible ISP state which must be written out to memory on context store */ - IMG_UINT32 u3DReg_PM_DEALLOCATED_MASK_STATUS; /*!< PM deallocation status */ - IMG_UINT32 u3DReg_PM_PDS_MTILEFREE_STATUS; /*!< Macro-tiles (MTs) finished status */ - IMG_UINT32 ui32CtxStateFlags; /*!< Compatibility and other flags */ - /* au3DReg_ISP_STORE should be the last element of the structure - * as this is an array whose size is determined at runtime - * after detecting the RGX core */ - IMG_UINT32 au3DReg_ISP_STORE[]; /*!< ISP state (per-pipe) */ -} UNCACHED_ALIGN RGXFWIF_3DCTX_STATE; - -static_assert(sizeof(RGXFWIF_3DCTX_STATE) <= 16U, - "Size of structure RGXFWIF_3DCTX_STATE exceeds maximum expected size."); - -#define RGXFWIF_CTX_USING_BUFFER_A (0) -#define RGXFWIF_CTX_USING_BUFFER_B (1U) - -typedef struct -{ - IMG_UINT32 ui32CtxStateFlags; /*!< Target buffer and other flags */ -} RGXFWIF_COMPUTECTX_STATE; - -/*! - * @InGroup WorkloadContexts - * @Brief Firmware Common Context (or FWCC) - */ -typedef struct RGXFWIF_FWCOMMONCONTEXT_ -{ - /* CCB details for this firmware context */ - PRGXFWIF_CCCB_CTL psCCBCtl; /*!< CCB control */ - PRGXFWIF_CCCB psCCB; /*!< CCB base */ - RGXFWIF_DMA_ADDR sCCBMetaDMAAddr; - - /* Context suspend state */ - PRGXFWIF_COMMONCTX_STATE RGXFW_ALIGN psContextState; /*!< TA/3D context suspend state, read/written by FW */ - - /* Flags e.g. for context switching */ - IMG_UINT32 ui32FWComCtxFlags; - IMG_INT32 i32Priority; /*!< Priority level */ - IMG_UINT32 ui32PrioritySeqNum; - - /* Framework state */ - PRGXFWIF_RF_CMD RGXFW_ALIGN psRFCmd; /*!< Register updates for Framework */ - - /* Statistic updates waiting to be passed back to the host... */ - IMG_BOOL bStatsPending; /*!< True when some stats are pending */ - IMG_INT32 i32StatsNumStores; /*!< Number of stores on this context since last update */ - IMG_INT32 i32StatsNumOutOfMemory; /*!< Number of OOMs on this context since last update */ - IMG_INT32 i32StatsNumPartialRenders; /*!< Number of PRs on this context since last update */ - RGXFWIF_DM eDM; /*!< Data Master type */ - IMG_UINT64 RGXFW_ALIGN ui64WaitSignalAddress; /*!< Device Virtual Address of the signal the context is waiting on */ - RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitSignalNode; /*!< List entry for the wait-signal list */ - RGXFWIF_DLLIST_NODE RGXFW_ALIGN sBufStalledNode; /*!< List entry for the buffer stalled list */ - IMG_UINT64 RGXFW_ALIGN ui64CBufQueueCtrlAddr; /*!< Address of the circular buffer queue pointers */ - - IMG_UINT64 RGXFW_ALIGN ui64RobustnessAddress; - IMG_UINT32 ui32MaxDeadlineMS; /*!< Max HWR deadline limit in ms */ - bool bReadOffsetNeedsReset; /*!< Following HWR circular buffer read-offset needs resetting */ - - RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitingNode; /*!< List entry for the waiting list */ - RGXFWIF_DLLIST_NODE RGXFW_ALIGN sRunNode; /*!< List entry for the run list */ - RGXFWIF_UFO sLastFailedUFO; /*!< UFO that last failed (or NULL) */ - - PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */ - - /* References to the host side originators */ - IMG_UINT32 ui32ServerCommonContextID; /*!< the Server Common Context */ - IMG_UINT32 ui32PID; /*!< associated process ID */ - - IMG_BOOL bGeomOOMDisabled; /*!< True when Geom DM OOM is not allowed */ - -} UNCACHED_ALIGN RGXFWIF_FWCOMMONCONTEXT; - -static_assert(sizeof(RGXFWIF_FWCOMMONCONTEXT) <= 256U, - "Size of structure RGXFWIF_FWCOMMONCONTEXT exceeds maximum expected size."); - -typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_TQ[RGX_TRP_MAX_NUM_CORES][1]; -typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_2D[RGX_TRP_MAX_NUM_CORES][2]; -typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_3D[RGX_TRP_MAX_NUM_CORES][4]; -typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_GEOM[RGX_TRP_MAX_NUM_CORES][2]; - -/*! - * @InGroup WorkloadContexts - * @Brief Firmware render context. - */ -typedef struct -{ - RGXFWIF_FWCOMMONCONTEXT sTAContext; /*!< Firmware context for the TA */ - RGXFWIF_FWCOMMONCONTEXT s3DContext; /*!< Firmware context for the 3D */ - - RGXFWIF_STATIC_RENDERCONTEXT_STATE sStaticRenderContextState; - - IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */ - - IMG_UINT32 ui32FwRenderCtxFlags; /*!< Compatibility and other flags */ - -#if defined(SUPPORT_TRP) - RGXFWIF_TRP_CHECKSUM_3D aui64TRPChecksums3D; - RGXFWIF_TRP_CHECKSUM_GEOM aui64TRPChecksumsGeom; -#endif -} UNCACHED_ALIGN RGXFWIF_FWRENDERCONTEXT; - -/*! - Firmware compute context. -*/ -typedef struct -{ - RGXFWIF_FWCOMMONCONTEXT sCDMContext; /*!< Firmware context for the CDM */ - - RGXFWIF_STATIC_COMPUTECONTEXT_STATE sStaticComputeContextState; - - IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */ - - IMG_UINT32 ui32ComputeCtxFlags; /*!< Compatibility and other flags */ - - IMG_UINT32 ui32WGPState; - IMG_UINT32 ui32WGPChecksum; - IMG_UINT32 ui32CoreMaskA; - IMG_UINT32 ui32CoreMaskB; -} UNCACHED_ALIGN RGXFWIF_FWCOMPUTECONTEXT; - -/*! - Firmware TDM context. -*/ -typedef struct -{ - RGXFWIF_FWCOMMONCONTEXT sTDMContext; /*!< Firmware context for the TDM */ - - IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */ - -} UNCACHED_ALIGN RGXFWIF_FWTDMCONTEXT; - -/*! - * @InGroup WorkloadContexts - * @Brief Firmware transfer context. - */ -typedef struct -{ - RGXFWIF_FWCOMMONCONTEXT sTQContext; /*!< Firmware context for TQ3D */ - -#if defined(SUPPORT_TRP) - IMG_UINT32 ui32TRPState; - RGXFWIF_TRP_CHECKSUM_TQ aui64TRPChecksumsTQ; -#endif -} UNCACHED_ALIGN RGXFWIF_FWTRANSFERCONTEXT; - -/*! - ****************************************************************************** - * Defines for CMD_TYPE corruption detection and forward compatibility check - *****************************************************************************/ - -/* CMD_TYPE 32bit contains: - * 31:16 Reserved for magic value to detect corruption (16 bits) - * 15 Reserved for RGX_CCB_TYPE_TASK (1 bit) - * 14:0 Bits available for CMD_TYPEs (15 bits) */ - - -/* Magic value to detect corruption */ -#define RGX_CMD_MAGIC_DWORD IMG_UINT32_C(0x2ABC) -#define RGX_CMD_MAGIC_DWORD_MASK (0xFFFF0000U) -#define RGX_CMD_MAGIC_DWORD_SHIFT (16U) -#define RGX_CMD_MAGIC_DWORD_SHIFTED (RGX_CMD_MAGIC_DWORD << RGX_CMD_MAGIC_DWORD_SHIFT) - -/*! - * @InGroup KCCBTypes ClientCCBTypes - * @Brief Generic CCB control structure - */ -typedef struct -{ - volatile IMG_UINT32 ui32WriteOffset; /*!< write offset into array of commands (MUST be aligned to 16 bytes!) */ - volatile IMG_UINT32 ui32ReadOffset; /*!< read offset into array of commands */ - IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask (Total capacity of the CCB - 1) */ - IMG_UINT32 ui32CmdSize; /*!< size of each command in bytes */ -} UNCACHED_ALIGN RGXFWIF_CCB_CTL; - -/*! - * @Defgroup KCCBTypes Kernel CCB data interface - * @Brief Types grouping data structures and defines used in realising the KCCB functionality - * @{ - */ - -#define RGXFWIF_MMUCACHEDATA_FLAGS_PT (0x1U) /* MMU_CTRL_INVAL_PT_EN */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_PD (0x2U) /* MMU_CTRL_INVAL_PD_EN */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_PC (0x4U) /* MMU_CTRL_INVAL_PC_EN */ - -#if !defined(__KERNEL) - -#if !defined(RGX_FEATURE_SLC_VIVT) -#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x10U) /* can't use PM_TLB0 bit from BIFPM_CTRL reg because it collides with PT bit from BIF_CTRL reg */ -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE < 2) -#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB | 0x8U) /* BIF_CTRL_INVAL_TLB1_EN */ -#else -#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB) -#endif -#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x0U) /* not used */ - -#else /* RGX_FEATURE_SLC_VIVT */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x0) /* not used */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (0x0) /* not used */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */ -#endif - -#else -#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x10) /* can't use PM_TLB0 bit from BIFPM_CTRL reg because it collides with PT bit from BIF_CTRL reg */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB | 0x8) /* BIF_CTRL_INVAL_TLB1_EN */ -#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */ -#endif - -#define RGXFWIF_MMUCACHEDATA_FLAGS_INTERRUPT (0x4000000U) /* indicates FW should interrupt the host */ - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_MMUCACHE type command - */ -typedef struct -{ - IMG_UINT32 ui32CacheFlags; - RGXFWIF_DEV_VIRTADDR sMMUCacheSync; - IMG_UINT32 ui32MMUCacheSyncUpdateValue; -} RGXFWIF_MMUCACHEDATA; - -#define RGXFWIF_BPDATA_FLAGS_ENABLE (1U << 0) -#define RGXFWIF_BPDATA_FLAGS_WRITE (1U << 1) -#define RGXFWIF_BPDATA_FLAGS_CTL (1U << 2) -#define RGXFWIF_BPDATA_FLAGS_REGS (1U << 3) - -typedef struct -{ - PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */ - IMG_UINT32 ui32BPAddr; /*!< Breakpoint address */ - IMG_UINT32 ui32HandlerAddr; /*!< Breakpoint handler */ - IMG_UINT32 ui32BPDM; /*!< Breakpoint control */ - IMG_UINT32 ui32BPDataFlags; - IMG_UINT32 ui32TempRegs; /*!< Number of temporary registers to overallocate */ - IMG_UINT32 ui32SharedRegs; /*!< Number of shared registers to overallocate */ - RGXFWIF_DM eDM; /*!< DM associated with the breakpoint */ -} RGXFWIF_BPDATA; - -#define RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS (RGXFWIF_PRBUFFER_MAXSUPPORTED + 1U) /* +1 is RTDATASET cleanup */ - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_KICK type command - */ -typedef struct -{ - PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */ - IMG_UINT32 ui32CWoffUpdate; /*!< Client CCB woff update */ - IMG_UINT32 ui32CWrapMaskUpdate; /*!< Client CCB wrap mask update after CCCB growth */ - IMG_UINT32 ui32NumCleanupCtl; /*!< number of CleanupCtl pointers attached */ - PRGXFWIF_CLEANUP_CTL apsCleanupCtl[RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS]; /*!< CleanupCtl structures associated with command */ - IMG_UINT32 ui32WorkEstCmdHeaderOffset; /*!< offset to the CmdHeader which houses the workload estimation kick data. */ -} RGXFWIF_KCCB_CMD_KICK_DATA; - -/*! - * @Brief Command data for @Ref RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK type command - */ -typedef struct -{ - RGXFWIF_KCCB_CMD_KICK_DATA sTACmdKickData; /*!< GEOM DM kick command data */ - RGXFWIF_KCCB_CMD_KICK_DATA s3DCmdKickData; /*!< FRAG DM kick command data */ -} RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FORCE_UPDATE type command - */ -typedef struct -{ - PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */ - IMG_UINT32 ui32CCBFenceOffset; /*!< Client CCB fence offset */ -} RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA; - -/*! - * @Brief Resource types supported by \ref RGXFWIF_KCCB_CMD_CLEANUP type command - */ -typedef enum -{ - RGXFWIF_CLEANUP_FWCOMMONCONTEXT, /*!< FW common context cleanup */ - RGXFWIF_CLEANUP_HWRTDATA, /*!< FW HW RT data cleanup */ - RGXFWIF_CLEANUP_FREELIST, /*!< FW freelist cleanup */ - RGXFWIF_CLEANUP_ZSBUFFER, /*!< FW ZS Buffer cleanup */ -} RGXFWIF_CLEANUP_TYPE; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CLEANUP type command - */ -typedef struct -{ - RGXFWIF_CLEANUP_TYPE eCleanupType; /*!< Cleanup type */ - union { - PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< FW common context to cleanup */ - PRGXFWIF_HWRTDATA psHWRTData; /*!< HW RT to cleanup */ - PRGXFWIF_FREELIST psFreelist; /*!< Freelist to cleanup */ - PRGXFWIF_ZSBUFFER psZSBuffer; /*!< ZS Buffer to cleanup */ - } uCleanupData; -} RGXFWIF_CLEANUP_REQUEST; - -/*! - * @Brief Type of power requests supported in \ref RGXFWIF_KCCB_CMD_POW type command - */ -typedef enum -{ - RGXFWIF_POW_OFF_REQ = 1, /*!< GPU power-off request */ - RGXFWIF_POW_FORCED_IDLE_REQ, /*!< Force-idle related request */ - RGXFWIF_POW_NUM_UNITS_CHANGE, /*!< Request to change default powered scalable units */ - RGXFWIF_POW_APM_LATENCY_CHANGE /*!< Request to change the APM latency period */ -} RGXFWIF_POWER_TYPE; - -/*! - * @Brief Supported force-idle related requests with \ref RGXFWIF_POW_FORCED_IDLE_REQ type request - */ -typedef enum -{ - RGXFWIF_POWER_FORCE_IDLE = 1, /*!< Request to force-idle GPU */ - RGXFWIF_POWER_CANCEL_FORCED_IDLE, /*!< Request to cancel a previously successful force-idle transition */ - RGXFWIF_POWER_HOST_TIMEOUT, /*!< Notification that host timed-out waiting for force-idle state */ -} RGXFWIF_POWER_FORCE_IDLE_TYPE; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_POW type command - */ -typedef struct -{ - RGXFWIF_POWER_TYPE ePowType; /*!< Type of power request */ - union - { - IMG_UINT32 ui32NumOfDusts; /*!< Number of active Dusts */ - IMG_BOOL bForced; /*!< If the operation is mandatory */ - RGXFWIF_POWER_FORCE_IDLE_TYPE ePowRequestType; /*!< Type of Request. Consolidating Force Idle, Cancel Forced Idle, Host Timeout */ - } uPowerReqData; -} RGXFWIF_POWER_REQUEST; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_SLCFLUSHINVAL type command - */ -typedef struct -{ - PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to fence on (only useful when bDMContext == TRUE) */ - IMG_BOOL bInval; /*!< Invalidate the cache as well as flushing */ - IMG_BOOL bDMContext; /*!< The data to flush/invalidate belongs to a specific DM context */ - IMG_UINT64 RGXFW_ALIGN ui64Address; /*!< Optional address of range (only useful when bDMContext == FALSE) */ - IMG_UINT64 RGXFW_ALIGN ui64Size; /*!< Optional size of range (only useful when bDMContext == FALSE) */ -} RGXFWIF_SLCFLUSHINVALDATA; - -typedef enum -{ - RGXFWIF_HWPERF_CTRL_TOGGLE = 0, - RGXFWIF_HWPERF_CTRL_SET = 1, - RGXFWIF_HWPERF_CTRL_EMIT_FEATURES_EV = 2 -} RGXFWIF_HWPERF_UPDATE_CONFIG; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG type command - */ -typedef struct -{ - RGXFWIF_HWPERF_UPDATE_CONFIG eOpCode; /*!< Control operation code */ - IMG_UINT64 RGXFW_ALIGN ui64Mask; /*!< Mask of events to toggle */ -} RGXFWIF_HWPERF_CTRL; - -typedef struct -{ - IMG_UINT32 ui32NumBlocks; /*!< Number of RGX_HWPERF_CONFIG_MUX_CNTBLK in the array */ - PRGX_HWPERF_CONFIG_MUX_CNTBLK sBlockConfigs; /*!< Address of the RGX_HWPERF_CONFIG_MUX_CNTBLK array */ -} RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS; - -typedef struct -{ - IMG_UINT32 ui32NumBlocks; /*!< Number of RGX_HWPERF_CONFIG_CNTBLK in the array */ - PRGX_HWPERF_CONFIG_CNTBLK sBlockConfigs; /*!< Address of the RGX_HWPERF_CONFIG_CNTBLK array */ -} RGXFWIF_HWPERF_CONFIG_DA_BLKS; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE type command - */ -typedef struct -{ - IMG_UINT32 ui32NewClockSpeed; /*!< New clock speed */ -} RGXFWIF_CORECLKSPEEDCHANGE_DATA; - -#define RGXFWIF_HWPERF_CTRL_BLKS_MAX 16U - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS type command - */ -typedef struct -{ - bool bEnable; - IMG_UINT32 ui32NumBlocks; /*!< Number of block IDs in the array */ - IMG_UINT16 aeBlockIDs[RGXFWIF_HWPERF_CTRL_BLKS_MAX]; /*!< Array of RGX_HWPERF_CNTBLK_ID values */ -} RGXFWIF_HWPERF_CTRL_BLKS; - - -typedef struct -{ - IMG_UINT16 ui16CustomBlock; - IMG_UINT16 ui16NumCounters; - PRGX_HWPERF_SELECT_CUSTOM_CNTRS sCustomCounterIDs; -} RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE & \ref RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE type commands - */ -typedef struct -{ - RGXFWIF_DEV_VIRTADDR sZSBufferFWDevVAddr; /*!< ZS-Buffer FW address */ - IMG_BOOL bDone; /*!< action backing/unbacking succeeded */ -} RGXFWIF_ZSBUFFER_BACKING_DATA; - -#if defined(SUPPORT_VALIDATION) -typedef struct -{ - IMG_UINT32 ui32RegWidth; - IMG_BOOL bWriteOp; - IMG_UINT32 ui32RegAddr; - IMG_UINT64 RGXFW_ALIGN ui64RegVal; -} RGXFWIF_RGXREG_DATA; - -typedef struct -{ - IMG_UINT64 ui64BaseAddress; - PRGXFWIF_FWCOMMONCONTEXT psContext; - IMG_UINT32 ui32Size; -} RGXFWIF_GPUMAP_DATA; -#endif - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE type command - */ -typedef struct -{ - RGXFWIF_DEV_VIRTADDR sFreeListFWDevVAddr; /*!< Freelist FW address */ - IMG_UINT32 ui32DeltaPages; /*!< Amount of the Freelist change */ - IMG_UINT32 ui32NewPages; /*!< New amount of pages on the freelist (including ready pages) */ - IMG_UINT32 ui32ReadyPages; /*!< Number of ready pages to be held in reserve until OOM */ -} RGXFWIF_FREELIST_GS_DATA; - -#define RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT (MAX_HW_TA3DCONTEXTS * RGXFW_MAX_FREELISTS * 2U) -#define RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG 0x80000000U - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE type command - */ -typedef struct -{ - IMG_UINT32 ui32FreelistsCount; - IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT]; -} RGXFWIF_FREELISTS_RECONSTRUCTION_DATA; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE type command - */ -typedef struct -{ - PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to that may need to be resumed following write offset update */ -} UNCACHED_ALIGN RGXFWIF_WRITE_OFFSET_UPDATE_DATA; - -/*! - ****************************************************************************** - * Proactive DVFS Structures - *****************************************************************************/ -#define NUM_OPP_VALUES 16 - -typedef struct -{ - IMG_UINT32 ui32Volt; /* V */ - IMG_UINT32 ui32Freq; /* Hz */ -} UNCACHED_ALIGN PDVFS_OPP; - -typedef struct -{ - PDVFS_OPP asOPPValues[NUM_OPP_VALUES]; -#if defined(DEBUG) - IMG_UINT32 ui32MinOPPPoint; -#endif - IMG_UINT32 ui32MaxOPPPoint; -} UNCACHED_ALIGN RGXFWIF_PDVFS_OPP; - -typedef struct -{ - IMG_UINT32 ui32MaxOPPPoint; -} UNCACHED_ALIGN RGXFWIF_PDVFS_MAX_FREQ_DATA; - -typedef struct -{ - IMG_UINT32 ui32MinOPPPoint; -} UNCACHED_ALIGN RGXFWIF_PDVFS_MIN_FREQ_DATA; - -/*! - ****************************************************************************** - * Register configuration structures - *****************************************************************************/ - -#define RGXFWIF_REG_CFG_MAX_SIZE 512 - -typedef enum -{ - RGXFWIF_REGCFG_CMD_ADD = 101, - RGXFWIF_REGCFG_CMD_CLEAR = 102, - RGXFWIF_REGCFG_CMD_ENABLE = 103, - RGXFWIF_REGCFG_CMD_DISABLE = 104 -} RGXFWIF_REGDATA_CMD_TYPE; - -typedef enum -{ - RGXFWIF_REG_CFG_TYPE_PWR_ON=0, /* Sidekick power event */ - RGXFWIF_REG_CFG_TYPE_DUST_CHANGE, /* Rascal / dust power event */ - RGXFWIF_REG_CFG_TYPE_TA, /* TA kick */ - RGXFWIF_REG_CFG_TYPE_3D, /* 3D kick */ - RGXFWIF_REG_CFG_TYPE_CDM, /* Compute kick */ - RGXFWIF_REG_CFG_TYPE_TLA, /* TLA kick */ - RGXFWIF_REG_CFG_TYPE_TDM, /* TDM kick */ - RGXFWIF_REG_CFG_TYPE_ALL /* Applies to all types. Keep as last element */ -} RGXFWIF_REG_CFG_TYPE; - -typedef struct -{ - IMG_UINT64 ui64Addr; - IMG_UINT64 ui64Mask; - IMG_UINT64 ui64Value; -} RGXFWIF_REG_CFG_REC; - -typedef struct -{ - RGXFWIF_REGDATA_CMD_TYPE eCmdType; - RGXFWIF_REG_CFG_TYPE eRegConfigType; - RGXFWIF_REG_CFG_REC RGXFW_ALIGN sRegConfig; - -} RGXFWIF_REGCONFIG_DATA; - -typedef struct -{ - /** - * PDump WRW command write granularity is 32 bits. - * Add padding to ensure array size is 32 bit granular. - */ - IMG_UINT8 RGXFW_ALIGN aui8NumRegsType[PVR_ALIGN((IMG_UINT32)RGXFWIF_REG_CFG_TYPE_ALL,sizeof(IMG_UINT32))]; - RGXFWIF_REG_CFG_REC RGXFW_ALIGN asRegConfigs[RGXFWIF_REG_CFG_MAX_SIZE]; -} UNCACHED_ALIGN RGXFWIF_REG_CFG; - -typedef enum -{ - RGXFWIF_OS_ONLINE = 1, - RGXFWIF_OS_OFFLINE -} RGXFWIF_OS_STATE_CHANGE; - -/*! - * @Brief Command data for \ref RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE type command - */ -typedef struct -{ - IMG_UINT32 ui32OSid; - RGXFWIF_OS_STATE_CHANGE eNewOSState; -} UNCACHED_ALIGN RGXFWIF_OS_STATE_CHANGE_DATA; - -typedef enum -{ - RGXFWIF_PWR_COUNTER_DUMP_START = 1, - RGXFWIF_PWR_COUNTER_DUMP_STOP, - RGXFWIF_PWR_COUNTER_DUMP_SAMPLE, -} RGXFWIF_COUNTER_DUMP_REQUEST; - -typedef struct -{ - RGXFWIF_COUNTER_DUMP_REQUEST eCounterDumpRequest; -} RGXFW_ALIGN RGXFWIF_COUNTER_DUMP_DATA; - -/*! - * @Brief List of command types supported by the Kernel CCB - */ -typedef enum -{ - /* Common commands */ - RGXFWIF_KCCB_CMD_KICK = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< DM workload kick command */ - RGXFWIF_KCCB_CMD_MMUCACHE = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< MMU cache invalidation request */ - RGXFWIF_KCCB_CMD_BP = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED, - RGXFWIF_KCCB_CMD_SLCFLUSHINVAL = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< SLC flush and invalidation request */ - RGXFWIF_KCCB_CMD_CLEANUP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests cleanup of a FW resource (type specified in the command data) */ - RGXFWIF_KCCB_CMD_POW = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Power request */ - RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Backing for on-demand ZS-Buffer done */ - RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Unbacking for on-demand ZS-Buffer done */ - RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelist Grow done */ - RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelists Reconstruction done */ - /* RGXFWIF_KCCB_CMD_NOTIFY_SIGNAL_UPDATE */ - RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE = 114U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the firmware that the host has added more data to a CDM2 Circular Buffer */ - RGXFWIF_KCCB_CMD_HEALTH_CHECK = 115U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Health check request */ - RGXFWIF_KCCB_CMD_FORCE_UPDATE = 116U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Forcing signalling of all unmet UFOs for a given CCB offset */ - - RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK = 117U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< There is a TA and a 3D command in this single kick */ - RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE = 118U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the FW that a Guest OS has come online / offline. */ - - /* Commands only permitted to the native or host OS */ - RGXFWIF_KCCB_CMD_REGCONFIG = 200U | RGX_CMD_MAGIC_DWORD_SHIFTED, - RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG = 201U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure HWPerf events (to be generated) and HWPerf buffer address (if required) */ - /* RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS */ - RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS = 203U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Enable or disable multiple HWPerf blocks (reusing existing configuration) */ - RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE = 204U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Core clock speed change event */ - /* RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS_DIRECT*/ - RGXFWIF_KCCB_CMD_LOGTYPE_UPDATE = 206U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Ask the firmware to update its cached ui32LogType value from the (shared) tracebuf control structure */ - RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MAX_FREQ = 207U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set a maximum frequency/OPP point */ - RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE = 208U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Changes the relative scheduling priority for a particular OSid. It can only be serviced for the Host DDK */ - RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL = 209U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set or clear firmware state flags */ - /* RGXFWIF_KCCB_CMD_HCS_SET_DEADLINE */ - /*RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE */ - RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MIN_FREQ = 212U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set a minimum frequency/OPP point */ - RGXFWIF_KCCB_CMD_PHR_CFG = 213U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Periodic Hardware Reset behaviour */ -#if defined(SUPPORT_VALIDATION) - RGXFWIF_KCCB_CMD_RGXREG = 214U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Read RGX Register from FW */ -#endif - RGXFWIF_KCCB_CMD_WDG_CFG = 215U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Safety Firmware Watchdog */ - RGXFWIF_KCCB_CMD_COUNTER_DUMP = 216U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Controls counter dumping in the FW */ - RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS = 217U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure, clear and enable multiple HWPerf blocks */ - RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS = 218U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure the custom counters for HWPerf */ -#if defined(SUPPORT_VALIDATION) - RGXFWIF_KCCB_CMD_GPUMAP = 219U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Request a FW GPU mapping which is written into by the FW with a pattern */ -#endif - RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS = 220U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure directly addressable counters for HWPerf */ -} RGXFWIF_KCCB_CMD_TYPE; - -#define RGXFWIF_LAST_ALLOWED_GUEST_KCCB_CMD (RGXFWIF_KCCB_CMD_REGCONFIG - 1) - -/*! @Brief Kernel CCB command packet */ -typedef struct -{ - RGXFWIF_KCCB_CMD_TYPE eCmdType; /*!< Command type */ - IMG_UINT32 ui32KCCBFlags; /*!< Compatibility and other flags */ - - /* NOTE: Make sure that uCmdData is the last member of this struct - * This is to calculate actual command size for device mem copy. - * (Refer RGXGetCmdMemCopySize()) - * */ - union - { - RGXFWIF_KCCB_CMD_KICK_DATA sCmdKickData; /*!< Data for Kick command */ - RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA sCombinedTA3DCmdKickData; /*!< Data for combined TA/3D Kick command */ - RGXFWIF_MMUCACHEDATA sMMUCacheData; /*!< Data for MMU cache command */ - RGXFWIF_BPDATA sBPData; /*!< Data for Breakpoint Commands */ - RGXFWIF_SLCFLUSHINVALDATA sSLCFlushInvalData; /*!< Data for SLC Flush/Inval commands */ - RGXFWIF_CLEANUP_REQUEST sCleanupData; /*!< Data for cleanup commands */ - RGXFWIF_POWER_REQUEST sPowData; /*!< Data for power request commands */ - RGXFWIF_HWPERF_CTRL sHWPerfCtrl; /*!< Data for HWPerf control command */ - RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS sHWPerfCfgEnableBlks; /*!< Data for HWPerf configure, clear and enable performance counter block command */ - RGXFWIF_HWPERF_CTRL_BLKS sHWPerfCtrlBlks; /*!< Data for HWPerf enable or disable performance counter block commands */ - RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS sHWPerfSelectCstmCntrs; /*!< Data for HWPerf configure the custom counters to read */ - RGXFWIF_HWPERF_CONFIG_DA_BLKS sHWPerfCfgDABlks; /*!< Data for HWPerf configure Directly Addressable blocks */ - RGXFWIF_CORECLKSPEEDCHANGE_DATA sCoreClkSpeedChangeData;/*!< Data for core clock speed change */ - RGXFWIF_ZSBUFFER_BACKING_DATA sZSBufferBackingData; /*!< Feedback for Z/S Buffer backing/unbacking */ - RGXFWIF_FREELIST_GS_DATA sFreeListGSData; /*!< Feedback for Freelist grow/shrink */ - RGXFWIF_FREELISTS_RECONSTRUCTION_DATA sFreeListsReconstructionData; /*!< Feedback for Freelists reconstruction */ - RGXFWIF_REGCONFIG_DATA sRegConfigData; /*!< Data for custom register configuration */ - RGXFWIF_WRITE_OFFSET_UPDATE_DATA sWriteOffsetUpdateData; /*!< Data for informing the FW about the write offset update */ - RGXFWIF_PDVFS_MAX_FREQ_DATA sPDVFSMaxFreqData; /*!< Data for setting the max frequency/OPP */ - RGXFWIF_PDVFS_MIN_FREQ_DATA sPDVFSMinFreqData; /*!< Data for setting the min frequency/OPP */ - RGXFWIF_OS_STATE_CHANGE_DATA sCmdOSOnlineStateData; /*!< Data for updating the Guest Online states */ - RGXFWIF_DEV_VIRTADDR sTBIBuffer; /*!< Dev address for TBI buffer allocated on demand */ - RGXFWIF_COUNTER_DUMP_DATA sCounterDumpConfigData; /*!< Data for dumping of register ranges */ - RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA sForceUpdateData; /*!< Data for signalling all unmet fences for a given CCB */ -#if defined(SUPPORT_VALIDATION) - RGXFWIF_RGXREG_DATA sFwRgxData; /*!< Data for reading off an RGX register */ - RGXFWIF_GPUMAP_DATA sGPUMapData; /*!< Data for requesting a FW GPU mapping which is written into by the FW with a pattern */ -#endif - } UNCACHED_ALIGN uCmdData; -} UNCACHED_ALIGN RGXFWIF_KCCB_CMD; - -RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_KCCB_CMD); - -/*! @} End of KCCBTypes */ - -/*! - * @Defgroup FWCCBTypes Firmware CCB data interface - * @Brief Types grouping data structures and defines used in realising the Firmware CCB functionality - * @{ - */ - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING and the - * \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING Firmware CCB commands - *****************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32ZSBufferID; /*!< ZS buffer ID */ -} RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA; - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELIST_GROW Firmware CCB - * command - *****************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32FreelistID; /*!< Freelist ID */ -} RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA; - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION - * Firmware CCB command - *****************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32FreelistsCount; /*!< Freelists count */ - IMG_UINT32 ui32HwrCounter; /*!< HWR counter */ - IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT]; /*!< Array of freelist IDs to reconstruct */ -} RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA; - -#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_PF (1U<<0) /*!< 1 if a page fault happened */ -#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS (1U<<1) /*!< 1 if applicable to all contexts */ - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION - * Firmware CCB command - *****************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32ServerCommonContextID; /*!< Context affected by the reset */ - RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reason for reset */ - RGXFWIF_DM eDM; /*!< Data Master affected by the reset */ - IMG_UINT32 ui32ResetJobRef; /*!< Job ref running at the time of reset */ - IMG_UINT32 ui32Flags; /*!< RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG bitfield */ - IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< At what page catalog address */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sFaultAddress; /*!< Page fault address (only when applicable) */ -} RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA; - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION - * Firmware CCB command - *****************************************************************************/ -typedef struct -{ - IMG_DEV_VIRTADDR sFWFaultAddr; /*!< Page fault address */ -} RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA; - -/*! - ****************************************************************************** - * List of command types supported by the Firmware CCB - *****************************************************************************/ -typedef enum -{ - RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be backed with physical pages - \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */ - RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be unbacked - \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */ - RGXFWIF_FWCCB_CMD_FREELIST_GROW = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand freelist grow - \n Command data: RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA */ - RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION = 104U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests freelists reconstruction - \n Command data: RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA */ - RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a HWR event on a context - \n Command data: RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA */ - RGXFWIF_FWCCB_CMD_DEBUG_DUMP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand debug dump - \n Command data: None */ - RGXFWIF_FWCCB_CMD_UPDATE_STATS = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand update on process stats - \n Command data: RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA */ - - RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED, - RGXFWIF_FWCCB_CMD_REQUEST_GPU_RESTART = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests GPU restart - \n Command data: None */ -#if defined(SUPPORT_VALIDATION) - RGXFWIF_FWCCB_CMD_REG_READ = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED, -#if defined(SUPPORT_SOC_TIMER) - RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS = 111U | RGX_CMD_MAGIC_DWORD_SHIFTED, -#endif -#endif - RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a FW pagefault - \n Command data: RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA */ -} RGXFWIF_FWCCB_CMD_TYPE; - -/*! - ****************************************************************************** - * List of the various stats of the process to update/increment - *****************************************************************************/ -typedef enum -{ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS=1, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumPartialRenders stat */ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumOutOfMemory stat */ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTAStores stat */ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32Num3DStores stat */ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumCDMStores stat */ - RGXFWIF_FWCCB_CMD_UPDATE_NUM_TDM_STORES /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTDMStores stat */ -} RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE; - -/*! - ****************************************************************************** - * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_UPDATE_STATS Firmware CCB - * command - *****************************************************************************/ -typedef struct -{ - RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE eElementToUpdate; /*!< Element to update */ - IMG_PID pidOwner; /*!< The pid of the process whose stats are being updated */ - IMG_INT32 i32AdjustmentValue; /*!< Adjustment to be made to the statistic */ -} RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA; - -typedef struct -{ - IMG_UINT32 ui32CoreClkRate; -} UNCACHED_ALIGN RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA; - -#if defined(SUPPORT_VALIDATION) -typedef struct -{ - IMG_UINT64 ui64RegValue; -} RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA; - -#if defined(SUPPORT_SOC_TIMER) -typedef struct -{ - IMG_UINT64 ui64timerGray; - IMG_UINT64 ui64timerBinary; - IMG_UINT64 aui64uscTimers[RGX_FEATURE_NUM_CLUSTERS]; -} RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA; -#endif -#endif - -/*! - ****************************************************************************** - * @Brief Firmware CCB command structure - *****************************************************************************/ -typedef struct -{ - RGXFWIF_FWCCB_CMD_TYPE eCmdType; /*!< Command type */ - IMG_UINT32 ui32FWCCBFlags; /*!< Compatibility and other flags */ - - union - { - RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA sCmdZSBufferBacking; /*!< Data for Z/S-Buffer on-demand (un)backing*/ - RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA sCmdFreeListGS; /*!< Data for on-demand freelist grow/shrink */ - RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA sCmdFreeListsReconstruction; /*!< Data for freelists reconstruction */ - RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA sCmdContextResetNotification; /*!< Data for context reset notification */ - RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA sCmdUpdateStatsData; /*!< Data for updating process stats */ - RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA sCmdCoreClkRateChange; - RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA sCmdFWPagefault; /*!< Data for context reset notification */ -#if defined(SUPPORT_VALIDATION) - RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA sCmdRgxRegReadData; -#if defined(SUPPORT_SOC_TIMER) - RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA sCmdTimers; -#endif -#endif - } RGXFW_ALIGN uCmdData; -} RGXFW_ALIGN RGXFWIF_FWCCB_CMD; - -RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_FWCCB_CMD); - -/*! @} End of FWCCBTypes */ - -/*! - ****************************************************************************** - * Workload estimation Firmware CCB command structure for RGX - *****************************************************************************/ -typedef struct -{ - IMG_UINT16 ui16ReturnDataIndex; /*!< Index for return data array */ - IMG_UINT32 ui32CyclesTaken; /*!< The cycles the workload took on the hardware */ -} RGXFWIF_WORKEST_FWCCB_CMD; - -/*! - * @Defgroup ClientCCBTypes Client CCB data interface - * @Brief Types grouping data structures and defines used in realising Client CCB commands/functionality - * @{ - */ - -/* Required memory alignment for 64-bit variables accessible by Meta - (The gcc meta aligns 64-bit variables to 64-bit; therefore, memory shared - between the host and meta that contains 64-bit variables has to maintain - this alignment) */ -#define RGXFWIF_FWALLOC_ALIGN sizeof(IMG_UINT64) - -#define RGX_CCB_TYPE_TASK (IMG_UINT32_C(1) << 15) -#define RGX_CCB_FWALLOC_ALIGN(size) (((size) + (RGXFWIF_FWALLOC_ALIGN-1U)) & ~(RGXFWIF_FWALLOC_ALIGN - 1U)) - -typedef IMG_UINT32 RGXFWIF_CCB_CMD_TYPE; - -/*! - * @Name Client CCB command types - * @{ - */ -#define RGXFWIF_CCB_CMD_TYPE_GEOM (201U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TA DM command */ -#define RGXFWIF_CCB_CMD_TYPE_TQ_3D (202U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for TQ operation */ -#define RGXFWIF_CCB_CMD_TYPE_3D (203U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command */ -#define RGXFWIF_CCB_CMD_TYPE_3D_PR (204U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for Partial render */ -#define RGXFWIF_CCB_CMD_TYPE_CDM (205U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< Compute DM command */ -#define RGXFWIF_CCB_CMD_TYPE_TQ_TDM (206U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TDM command */ -#define RGXFWIF_CCB_CMD_TYPE_FBSC_INVALIDATE (207U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) -#define RGXFWIF_CCB_CMD_TYPE_TQ_2D (208U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 2D DM command for TQ operation */ -#define RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP (209U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) -#define RGXFWIF_CCB_CMD_TYPE_NULL (210U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) -#define RGXFWIF_CCB_CMD_TYPE_ABORT (211U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) - -/* Leave a gap between CCB specific commands and generic commands */ -#define RGXFWIF_CCB_CMD_TYPE_FENCE (212U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a command */ -#define RGXFWIF_CCB_CMD_TYPE_UPDATE (213U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates of a command */ -#define RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE (214U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates related to workload resources */ -#define RGXFWIF_CCB_CMD_TYPE_FENCE_PR (215U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a PR command */ -#define RGXFWIF_CCB_CMD_TYPE_PRIORITY (216U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Context priority update command */ -/* Pre and Post timestamp commands are supposed to sandwich the DM cmd. The - padding code with the CCB wrap upsets the FW if we don't have the task type - bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types. -*/ -#define RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP (217U | RGX_CMD_MAGIC_DWORD_SHIFTED) -#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE (218U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates of a command */ -#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE (219U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates related to workload resources */ - -#if defined(SUPPORT_VALIDATION) -#define RGXFWIF_CCB_CMD_TYPE_REG_READ (220U | RGX_CMD_MAGIC_DWORD_SHIFTED) -#endif - -#define RGXFWIF_CCB_CMD_TYPE_PADDING (221U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Skip without action type command */ -/*! @} End of Client CCB command types */ - -typedef struct -{ - /* Index for the KM Workload estimation return data array */ - IMG_UINT16 RGXFW_ALIGN ui16ReturnDataIndex; - /* Predicted time taken to do the work in cycles */ - IMG_UINT32 RGXFW_ALIGN ui32CyclesPrediction; - /* Deadline for the workload (in usecs) */ - IMG_UINT64 RGXFW_ALIGN ui64Deadline; -} RGXFWIF_WORKEST_KICK_DATA; - -/*! @Brief Command header of a command in the client CCB buffer. - * - * Followed by this header is the command-data specific to the - * command-type as specified in the header. - */ -typedef struct -{ - RGXFWIF_CCB_CMD_TYPE eCmdType; /*!< Command data type following this command header */ - IMG_UINT32 ui32CmdSize; /*!< Size of the command following this header */ - IMG_UINT32 ui32ExtJobRef; /*!< external job reference - provided by client and used in debug for tracking submitted work */ - IMG_UINT32 ui32IntJobRef; /*!< internal job reference - generated by services and used in debug for tracking submitted work */ - RGXFWIF_WORKEST_KICK_DATA RGXFW_ALIGN sWorkEstKickData; /*!< Workload Estimation - Workload Estimation Data */ -} RGXFWIF_CCB_CMD_HEADER; - -/* - ****************************************************************************** - * Client CCB commands which are only required by the kernel - *****************************************************************************/ - -/*! @Brief Command data for \ref RGXFWIF_CCB_CMD_TYPE_PRIORITY type client CCB command */ -typedef struct -{ - IMG_INT32 i32Priority; /*!< Priority level */ -} RGXFWIF_CMD_PRIORITY; - -/*! @} End of ClientCCBTypes */ - -/*! - ****************************************************************************** - * Signature and Checksums Buffer - *****************************************************************************/ -typedef struct -{ - PRGXFWIF_SIGBUFFER sBuffer; /*!< Ptr to Signature Buffer memory */ - IMG_UINT32 ui32LeftSizeInRegs; /*!< Amount of space left for storing regs in the buffer */ -} UNCACHED_ALIGN RGXFWIF_SIGBUF_CTL; - -typedef struct -{ - PRGXFWIF_COUNTERBUFFER sBuffer; /*!< Ptr to counter dump buffer */ - IMG_UINT32 ui32SizeInDwords; /*!< Amount of space for storing in the buffer */ -} UNCACHED_ALIGN RGXFWIF_COUNTER_DUMP_CTL; - -typedef struct -{ - PRGXFWIF_FIRMWAREGCOVBUFFER sBuffer; /*!< Ptr to firmware gcov buffer */ - IMG_UINT32 ui32Size; /*!< Amount of space for storing in the buffer */ -} UNCACHED_ALIGN RGXFWIF_FIRMWARE_GCOV_CTL; - -/*! - ***************************************************************************** - * RGX Compatibility checks - *****************************************************************************/ - -/* WARNING: Whenever the layout of RGXFWIF_COMPCHECKS_BVNC changes, the - following define should be increased by 1 to indicate to the - compatibility logic that layout has changed. */ -#define RGXFWIF_COMPCHECKS_LAYOUT_VERSION 3 - -typedef struct -{ - IMG_UINT32 ui32LayoutVersion; /* WARNING: This field must be defined as first one in this structure */ - IMG_UINT64 RGXFW_ALIGN ui64BVNC; -} UNCACHED_ALIGN RGXFWIF_COMPCHECKS_BVNC; - -typedef struct -{ - IMG_UINT8 ui8OsCountSupport; -} UNCACHED_ALIGN RGXFWIF_INIT_OPTIONS; - -#define RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(name) \ - RGXFWIF_COMPCHECKS_BVNC (name) = { \ - RGXFWIF_COMPCHECKS_LAYOUT_VERSION, \ - 0, \ - } -#define RGXFWIF_COMPCHECKS_BVNC_INIT(name) \ - do { \ - (name).ui32LayoutVersion = RGXFWIF_COMPCHECKS_LAYOUT_VERSION; \ - (name).ui64BVNC = 0; \ - } while (false) - -typedef struct -{ - RGXFWIF_COMPCHECKS_BVNC sHWBVNC; /*!< hardware BVNC (from the RGX registers) */ - RGXFWIF_COMPCHECKS_BVNC sFWBVNC; /*!< firmware BVNC */ - IMG_UINT32 ui32FWProcessorVersion; /*!< identifier of the FW processor version */ - IMG_UINT32 ui32DDKVersion; /*!< software DDK version */ - IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */ - IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */ - RGXFWIF_INIT_OPTIONS sInitOptions; /*!< initialisation options bit-field */ - IMG_BOOL bUpdated; /*!< Information is valid */ -} UNCACHED_ALIGN RGXFWIF_COMPCHECKS; - -/*! - ****************************************************************************** - * Updated configuration post FW data init. - *****************************************************************************/ -typedef struct -{ - IMG_UINT32 ui32ActivePMLatencyms; /* APM latency in ms before signalling IDLE to the host */ - IMG_UINT32 ui32RuntimeCfgFlags; /* Compatibility and other flags */ - IMG_BOOL bActivePMLatencyPersistant; /* If set, APM latency does not reset to system default each GPU power transition */ - IMG_UINT32 ui32CoreClockSpeed; /* Core clock speed, currently only used to calculate timer ticks */ - IMG_UINT32 ui32DefaultDustsNumInit; /* Last number of dusts change requested by the host */ - IMG_UINT32 ui32PHRMode; /* Periodic Hardware Reset configuration values */ - IMG_UINT32 ui32HCSDeadlineMS; /* New number of milliseconds C/S is allowed to last */ - IMG_UINT32 ui32WdgPeriodUs; /* The watchdog period in microseconds */ - IMG_UINT32 aui32OSidPriority[RGXFW_MAX_NUM_OS]; /*!< Array of priorities per OS */ - PRGXFWIF_HWPERFBUF sHWPerfBuf; /* On-demand allocated HWPerf buffer address, to be passed to the FW */ -} RGXFWIF_RUNTIME_CFG; - -/*! - ***************************************************************************** - * Control data for RGX - *****************************************************************************/ - -#define RGXFWIF_HWR_DEBUG_DUMP_ALL (99999U) - -#if defined(PDUMP) - -#define RGXFWIF_PID_FILTER_MAX_NUM_PIDS 32U - -typedef enum -{ - RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT, - RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT -} RGXFWIF_PID_FILTER_MODE; - -typedef struct -{ - IMG_PID uiPID; - IMG_UINT32 ui32OSID; -} RGXFW_ALIGN RGXFWIF_PID_FILTER_ITEM; - -typedef struct -{ - RGXFWIF_PID_FILTER_MODE eMode; - /* each process in the filter list is specified by a PID and OS ID pair. - * each PID and OS pair is an item in the items array (asItems). - * if the array contains less than RGXFWIF_PID_FILTER_MAX_NUM_PIDS entries - * then it must be terminated by an item with pid of zero. - */ - RGXFWIF_PID_FILTER_ITEM asItems[RGXFWIF_PID_FILTER_MAX_NUM_PIDS]; -} RGXFW_ALIGN RGXFWIF_PID_FILTER; -#endif - -#if defined(SUPPORT_SECURITY_VALIDATION) -#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_DATA (0x1U << 0) -#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_CODE (0x1U << 1) -#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_NONSECURE (0x1U << 2) -#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_SECURE (0x1U << 3) -#endif - -typedef enum -{ - RGXFWIF_TPU_DM_PDM = 0, - RGXFWIF_TPU_DM_VDM = 1, - RGXFWIF_TPU_DM_CDM = 2, - RGXFWIF_TPU_DM_TDM = 3, - RGXFWIF_TPU_DM_LAST -} RGXFWIF_TPU_DM; - -typedef enum -{ - RGXFWIF_GPIO_VAL_OFF = 0, /*!< No GPIO validation */ - RGXFWIF_GPIO_VAL_GENERAL = 1, /*!< Simple test case that - initiates by sending data via the - GPIO and then sends back any data - received over the GPIO */ - RGXFWIF_GPIO_VAL_AP = 2, /*!< More complex test case that writes - and reads data across the entire - GPIO AP address range.*/ -#if defined(SUPPORT_STRIP_RENDERING) - RGXFWIF_GPIO_VAL_SR_BASIC = 3, /*!< Strip Rendering AP based basic test.*/ - RGXFWIF_GPIO_VAL_SR_COMPLEX = 4, /*!< Strip Rendering AP based complex test.*/ -#endif - RGXFWIF_GPIO_VAL_TESTBENCH = 5, /*!< Validates the GPIO Testbench. */ - RGXFWIF_GPIO_VAL_LOOPBACK = 6, /*!< Send and then receive each byte - in the range 0-255. */ - RGXFWIF_GPIO_VAL_LOOPBACK_LITE = 7, /*!< Send and then receive each power-of-2 - byte in the range 0-255. */ - RGXFWIF_GPIO_VAL_LAST -} RGXFWIF_GPIO_VAL_MODE; - -typedef enum -{ - FW_PERF_CONF_NONE = 0, - FW_PERF_CONF_ICACHE = 1, - FW_PERF_CONF_DCACHE = 2, - FW_PERF_CONF_JTLB_INSTR = 5, - FW_PERF_CONF_INSTRUCTIONS = 6 -} FW_PERF_CONF; - -typedef enum -{ - FW_BOOT_STAGE_TLB_INIT_FAILURE = -2, - FW_BOOT_STAGE_NOT_AVAILABLE = -1, - FW_BOOT_NOT_STARTED = 0, - FW_BOOT_BLDR_STARTED = 1, - FW_BOOT_CACHE_DONE, - FW_BOOT_TLB_DONE, - FW_BOOT_MAIN_STARTED, - FW_BOOT_ALIGNCHECKS_DONE, - FW_BOOT_INIT_DONE, -} FW_BOOT_STAGE; - -/*! - * @AddToGroup KCCBTypes - * @{ - * @Name Kernel CCB return slot responses - * @{ - * Usage of bit-fields instead of bare integers - * allows FW to possibly pack-in several responses for each single kCCB command. - */ - -#define RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED (1U << 0) /*!< Command executed (return status from FW) */ -#define RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY (1U << 1) /*!< A cleanup was requested but resource busy */ -#define RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE (1U << 2) /*!< Poll failed in FW for a HW operation to complete */ - -#define RGXFWIF_KCCB_RTN_SLOT_NO_RESPONSE 0x0U /*!< Reset value of a kCCB return slot (set by host) */ -/*! - * @} End of Name Kernel CCB return slot responses - * @} End of AddToGroup KCCBTypes - */ - -typedef struct -{ - /* Fw-Os connection states */ - volatile RGXFWIF_CONNECTION_FW_STATE eConnectionFwState; - volatile RGXFWIF_CONNECTION_OS_STATE eConnectionOsState; - volatile IMG_UINT32 ui32AliveFwToken; - volatile IMG_UINT32 ui32AliveOsToken; -} UNCACHED_ALIGN RGXFWIF_CONNECTION_CTL; - -/*! @Brief Firmware OS Initialization data \ref RGXFWIF_OSINIT - * allocated by services and used by the Firmware on boot - **/ -typedef struct -{ - /* Kernel CCB */ - PRGXFWIF_CCB_CTL psKernelCCBCtl; /*!< Kernel CCB Control */ - PRGXFWIF_CCB psKernelCCB; /*!< Kernel CCB */ - PRGXFWIF_CCB_RTN_SLOTS psKernelCCBRtnSlots; /*!< Kernel CCB return slots */ - - /* Firmware CCB */ - PRGXFWIF_CCB_CTL psFirmwareCCBCtl; /*!< Firmware CCB control */ - PRGXFWIF_CCB psFirmwareCCB; /*!< Firmware CCB */ - - /* Workload Estimation Firmware CCB */ - PRGXFWIF_CCB_CTL psWorkEstFirmwareCCBCtl; /*!< Workload estimation control */ - PRGXFWIF_CCB psWorkEstFirmwareCCB; /*!< Workload estimation buffer */ - - PRGXFWIF_HWRINFOBUF sRGXFWIfHWRInfoBufCtl; /*!< HWRecoveryInfo control */ - - IMG_UINT32 ui32HWRDebugDumpLimit; /*!< Firmware debug dump maximum limit */ - - PRGXFWIF_OSDATA sFwOsData; /*!< Firmware per-os shared data */ - - RGXFWIF_COMPCHECKS sRGXCompChecks; /*!< Compatibility checks to be populated by the Firmware */ - -} UNCACHED_ALIGN RGXFWIF_OSINIT; - -/*! @Brief Firmware System Initialization data \ref RGXFWIF_SYSINIT - * allocated by services and used by the Firmware on boot - **/ -typedef struct -{ - IMG_DEV_PHYADDR RGXFW_ALIGN sFaultPhysAddr; /*!< Fault read address */ - - IMG_DEV_VIRTADDR RGXFW_ALIGN sPDSExecBase; /*!< PDS execution base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sUSCExecBase; /*!< USC execution base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sFBCDCStateTableBase; /*!< FBCDC bindless texture state table base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sFBCDCLargeStateTableBase; - IMG_DEV_VIRTADDR RGXFW_ALIGN sTextureHeapBase; /*!< Texture state base */ - - IMG_UINT64 RGXFW_ALIGN ui64HWPerfFilter; /*! Event filter for Firmware events */ - - IMG_DEV_VIRTADDR RGXFW_ALIGN sSLC3FenceDevVAddr; - - IMG_UINT32 RGXFW_ALIGN aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_LAST]; - - RGXFWIF_SIGBUF_CTL asSigBufCtl[RGXFWIF_DM_MAX]; /*!< Signature and Checksum Buffers for DMs */ - - RGXFWIF_PDVFS_OPP sPDVFSOPPInfo; - - RGXFWIF_DMA_ADDR sCorememDataStore; /*!< Firmware coremem data */ - - RGXFWIF_COUNTER_DUMP_CTL sCounterDumpCtl; - -#if defined(SUPPORT_FIRMWARE_GCOV) - RGXFWIF_FIRMWARE_GCOV_CTL sFirmwareGcovCtl; /*!< Firmware gcov buffer control */ -#endif - - IMG_UINT32 ui32FilterFlags; - - PRGXFWIF_RUNTIME_CFG sRuntimeCfg; /*!< Firmware Runtime configuration */ - - PRGXFWIF_TRACEBUF sTraceBufCtl; /*!< Firmware Trace buffer control */ - PRGXFWIF_SYSDATA sFwSysData; /*!< Firmware System shared data */ -#if defined(SUPPORT_TBI_INTERFACE) - PRGXFWIF_TBIBUF sTBIBuf; /*!< Tbi log buffer */ -#endif - - PRGXFWIF_GPU_UTIL_FWCB sGpuUtilFWCbCtl; /*!< GPU utilization buffer */ - PRGXFWIF_REG_CFG sRegCfg; /*!< Firmware register user configuration */ - PRGXFWIF_HWPERF_CTL sHWPerfCtl; /*!< HWPerf counter block configuration.*/ - - RGXFWIF_DEV_VIRTADDR sAlignChecks; /*!< Array holding Server structures alignment data */ - - IMG_UINT32 ui32InitialCoreClockSpeed; /*!< Core clock speed at FW boot time */ - - IMG_UINT32 ui32InitialActivePMLatencyms; /*!< APM latency in ms before signalling IDLE to the host */ - - IMG_BOOL bFirmwareStarted; /*!< Flag to be set by the Firmware after successful start */ - - IMG_UINT32 ui32MarkerVal; /*!< Host/FW Trace synchronisation Partition Marker */ - - IMG_UINT32 ui32FirmwareStartedTimeStamp; /*!< Firmware initialization complete time */ - - IMG_UINT32 ui32JonesDisableMask; - - FW_PERF_CONF eFirmwarePerf; /*!< Firmware performance counter config */ - - /** - * FW Pointer to memory containing core clock rate in Hz. - * Firmware (PDVFS) updates the memory when running on non primary FW thread - * to communicate to host driver. - */ - PRGXFWIF_CORE_CLK_RATE sCoreClockRate; - -#if defined(PDUMP) - RGXFWIF_PID_FILTER sPIDFilter; -#endif - - RGXFWIF_GPIO_VAL_MODE eGPIOValidationMode; - - RGX_HWPERF_BVNC sBvncKmFeatureFlags; /*!< Used in HWPerf for decoding BVNC Features*/ - -#if defined(SUPPORT_SECURITY_VALIDATION) - IMG_UINT32 ui32SecurityTestFlags; - RGXFWIF_DEV_VIRTADDR pbSecureBuffer; - RGXFWIF_DEV_VIRTADDR pbNonSecureBuffer; -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* - * Used when validation is enabled to allow the host to check - * that MTS sent the correct sideband in response to a kick - * from a given OSes schedule register. - * Testing is enabled if RGXFWIF_KICK_TEST_ENABLED_BIT is set - * - * Set by the host to: - * (osid << RGXFWIF_KICK_TEST_OSID_SHIFT) | RGXFWIF_KICK_TEST_ENABLED_BIT - * reset to 0 by FW when kicked by the given OSid - */ - IMG_UINT32 ui32OSKickTest; -#endif - - /* Value to write into RGX_CR_TFBC_COMPRESSION_CONTROL */ - IMG_UINT32 ui32TFBCCompressionControl; - -#if defined(SUPPORT_AUTOVZ) - IMG_UINT32 ui32VzWdgPeriod; -#endif - -} UNCACHED_ALIGN RGXFWIF_SYSINIT; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#define RGXFWIF_KICK_TEST_ENABLED_BIT 0x1 -#define RGXFWIF_KICK_TEST_OSID_SHIFT 0x1 -#endif - -/*! - ***************************************************************************** - * Timer correlation shared data and defines - *****************************************************************************/ - -typedef struct -{ - IMG_UINT64 RGXFW_ALIGN ui64OSTimeStamp; - IMG_UINT64 RGXFW_ALIGN ui64OSMonoTimeStamp; - IMG_UINT64 RGXFW_ALIGN ui64CRTimeStamp; - - /* Utility variable used to convert CR timer deltas to OS timer deltas (nS), - * where the deltas are relative to the timestamps above: - * deltaOS = (deltaCR * K) >> decimal_shift, see full explanation below */ - IMG_UINT64 RGXFW_ALIGN ui64CRDeltaToOSDeltaKNs; - - IMG_UINT32 ui32CoreClockSpeed; - IMG_UINT32 ui32Reserved; -} UNCACHED_ALIGN RGXFWIF_TIME_CORR; - - -/* The following macros are used to help converting FW timestamps to the Host - * time domain. On the FW the RGX_CR_TIMER counter is used to keep track of - * time; it increments by 1 every 256 GPU clock ticks, so the general - * formula to perform the conversion is: - * - * [ GPU clock speed in Hz, if (scale == 10^9) then deltaOS is in nS, - * otherwise if (scale == 10^6) then deltaOS is in uS ] - * - * deltaCR * 256 256 * scale - * deltaOS = --------------- * scale = deltaCR * K [ K = --------------- ] - * GPUclockspeed GPUclockspeed - * - * The actual K is multiplied by 2^20 (and deltaCR * K is divided by 2^20) - * to get some better accuracy and to avoid returning 0 in the integer - * division 256000000/GPUfreq if GPUfreq is greater than 256MHz. - * This is the same as keeping K as a decimal number. - * - * The maximum deltaOS is slightly more than 5hrs for all GPU frequencies - * (deltaCR * K is more or less a constant), and it's relative to the base - * OS timestamp sampled as a part of the timer correlation data. - * This base is refreshed on GPU power-on, DVFS transition and periodic - * frequency calibration (executed every few seconds if the FW is doing - * some work), so as long as the GPU is doing something and one of these - * events is triggered then deltaCR * K will not overflow and deltaOS will be - * correct. - */ - -#define RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT (20) - -#define RGXFWIF_GET_DELTA_OSTIME_NS(deltaCR, K) \ - (((deltaCR) * (K)) >> RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT) - - -/*! - ****************************************************************************** - * GPU Utilisation - *****************************************************************************/ - -/* See rgx_common.h for a list of GPU states */ -#define RGXFWIF_GPU_UTIL_TIME_MASK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF) & ~RGXFWIF_GPU_UTIL_STATE_MASK) - -#define RGXFWIF_GPU_UTIL_GET_TIME(word) ((word) & RGXFWIF_GPU_UTIL_TIME_MASK) -#define RGXFWIF_GPU_UTIL_GET_STATE(word) ((word) & RGXFWIF_GPU_UTIL_STATE_MASK) - -/* The OS timestamps computed by the FW are approximations of the real time, - * which means they could be slightly behind or ahead the real timer on the Host. - * In some cases we can perform subtractions between FW approximated - * timestamps and real OS timestamps, so we need a form of protection against - * negative results if for instance the FW one is a bit ahead of time. - */ -#define RGXFWIF_GPU_UTIL_GET_PERIOD(newtime,oldtime) \ - (((newtime) > (oldtime)) ? ((newtime) - (oldtime)) : 0U) - -#define RGXFWIF_GPU_UTIL_MAKE_WORD(time,state) \ - (RGXFWIF_GPU_UTIL_GET_TIME(time) | RGXFWIF_GPU_UTIL_GET_STATE(state)) - - -/* The timer correlation array must be big enough to ensure old entries won't be - * overwritten before all the HWPerf events linked to those entries are processed - * by the MISR. The update frequency of this array depends on how fast the system - * can change state (basically how small the APM latency is) and perform DVFS transitions. - * - * The minimum size is 2 (not 1) to avoid race conditions between the FW reading - * an entry while the Host is updating it. With 2 entries in the worst case the FW - * will read old data, which is still quite ok if the Host is updating the timer - * correlation at that time. - */ -#define RGXFWIF_TIME_CORR_ARRAY_SIZE 256U -#define RGXFWIF_TIME_CORR_CURR_INDEX(seqcount) ((seqcount) % RGXFWIF_TIME_CORR_ARRAY_SIZE) - -/* Make sure the timer correlation array size is a power of 2 */ -static_assert((RGXFWIF_TIME_CORR_ARRAY_SIZE & (RGXFWIF_TIME_CORR_ARRAY_SIZE - 1U)) == 0U, - "RGXFWIF_TIME_CORR_ARRAY_SIZE must be a power of two"); - -typedef struct -{ - RGXFWIF_TIME_CORR sTimeCorr[RGXFWIF_TIME_CORR_ARRAY_SIZE]; - IMG_UINT32 ui32TimeCorrSeqCount; - - /* Compatibility and other flags */ - IMG_UINT32 ui32GpuUtilFlags; - - /* Last GPU state + OS time of the last state update */ - IMG_UINT64 RGXFW_ALIGN ui64LastWord; - - /* Counters for the amount of time the GPU was active/idle/blocked */ - IMG_UINT64 RGXFW_ALIGN aui64StatsCounters[RGXFWIF_GPU_UTIL_STATE_NUM]; -} UNCACHED_ALIGN RGXFWIF_GPU_UTIL_FWCB; - -typedef struct -{ - IMG_UINT32 ui32RenderTargetIndex; //Render number - IMG_UINT32 ui32CurrentRenderTarget; //index in RTA - IMG_UINT32 ui32ActiveRenderTargets; //total active RTs - IMG_UINT32 ui32CumulActiveRenderTargets; //total active RTs from the first TA kick, for OOM - RGXFWIF_DEV_VIRTADDR sValidRenderTargets; //Array of valid RT indices - RGXFWIF_DEV_VIRTADDR sRTANumPartialRenders; //Array of number of occurred partial renders per render target - IMG_UINT32 ui32MaxRTs; //Number of render targets in the array - IMG_UINT32 ui32RTACtlFlags; /* Compatibility and other flags */ -} UNCACHED_ALIGN RGXFWIF_RTA_CTL; - -/*! - * @InGroup RenderTarget - * @Brief Firmware Freelist holding usage state of the Parameter Buffers - */ -typedef struct -{ - IMG_DEV_VIRTADDR RGXFW_ALIGN psFreeListDevVAddr; /*!< Freelist page table base */ - IMG_UINT64 RGXFW_ALIGN ui64CurrentDevVAddr;/*!< Freelist page table entry for current free page */ - IMG_UINT32 ui32CurrentStackTop; /*!< Freelist current free page */ - IMG_UINT32 ui32MaxPages; /*!< Max no. of pages can be added to the freelist */ - IMG_UINT32 ui32GrowPages; /*!< No pages to add in each freelist grow */ - IMG_UINT32 ui32CurrentPages; /*!< Total no. of pages made available to the PM HW */ - IMG_UINT32 ui32AllocatedPageCount; /*!< No. of pages allocated by PM HW */ - IMG_UINT32 ui32AllocatedMMUPageCount; /*!< No. of pages allocated for GPU MMU for PM*/ -#if defined(SUPPORT_SHADOW_FREELISTS) - IMG_UINT32 ui32HWRCounter; - PRGXFWIF_FWMEMCONTEXT psFWMemContext; -#endif - IMG_UINT32 ui32FreeListID; /*!< Unique Freelist ID */ - IMG_BOOL bGrowPending; /*!< Freelist grow is pending */ - IMG_UINT32 ui32ReadyPages; /*!< Reserved pages to be used only on PM OOM event */ - IMG_UINT32 ui32FreelistFlags; /*!< Compatibility and other flags */ -#if defined(SUPPORT_AGP) - IMG_UINT32 ui32PmGlobalPb; /*!< PM Global PB on which Freelist is loaded */ -#endif -} UNCACHED_ALIGN RGXFWIF_FREELIST; - -/*! - ****************************************************************************** - * HWRTData - *****************************************************************************/ - -/* HWRTData flags */ -/* Deprecated flags 1:0 */ -#define HWRTDATA_HAS_LAST_TA (1UL << 2) -#define HWRTDATA_PARTIAL_RENDERED (1UL << 3) -#define HWRTDATA_DISABLE_TILE_REORDERING (1UL << 4) -#define HWRTDATA_NEED_BRN65101_BLIT (1UL << 5) -#define HWRTDATA_FIRST_BRN65101_STRIP (1UL << 6) -#define HWRTDATA_NEED_BRN67182_2ND_RENDER (1UL << 7) -#if defined(SUPPORT_AGP) -#define HWRTDATA_GLOBAL_PB_NUMBER_BIT0 (1UL << 8) -#if defined(SUPPORT_AGP4) -#define HWRTDATA_GLOBAL_PB_NUMBER_BIT1 (1UL << 9) -#endif -#define HWRTDATA_GEOM_NEEDS_RESUME (1UL << 10) -#endif - -typedef enum -{ - RGXFWIF_RTDATA_STATE_NONE = 0, - RGXFWIF_RTDATA_STATE_KICKTA, - RGXFWIF_RTDATA_STATE_KICKTAFIRST, - RGXFWIF_RTDATA_STATE_TAFINISHED, - RGXFWIF_RTDATA_STATE_KICK3D, - RGXFWIF_RTDATA_STATE_3DFINISHED, - RGXFWIF_RTDATA_STATE_3DCONTEXTSTORED, - RGXFWIF_RTDATA_STATE_TAOUTOFMEM, - RGXFWIF_RTDATA_STATE_PARTIALRENDERFINISHED, - /* In case of HWR, we can't set the RTDATA state to NONE, - * as this will cause any TA to become a first TA. - * To ensure all related TA's are skipped, we use the HWR state */ - RGXFWIF_RTDATA_STATE_HWR, - RGXFWIF_RTDATA_STATE_UNKNOWN = 0x7FFFFFFFU -} RGXFWIF_RTDATA_STATE; - -typedef struct -{ - IMG_BOOL bTACachesNeedZeroing; - - IMG_UINT32 ui32ScreenPixelMax; - IMG_UINT64 RGXFW_ALIGN ui64MultiSampleCtl; - IMG_UINT64 ui64FlippedMultiSampleCtl; - IMG_UINT32 ui32TPCStride; - IMG_UINT32 ui32TPCSize; - IMG_UINT32 ui32TEScreen; - IMG_UINT32 ui32MTileStride; - IMG_UINT32 ui32TEAA; - IMG_UINT32 ui32TEMTILE1; - IMG_UINT32 ui32TEMTILE2; - IMG_UINT32 ui32ISPMergeLowerX; - IMG_UINT32 ui32ISPMergeLowerY; - IMG_UINT32 ui32ISPMergeUpperX; - IMG_UINT32 ui32ISPMergeUpperY; - IMG_UINT32 ui32ISPMergeScaleX; - IMG_UINT32 ui32ISPMergeScaleY; - IMG_UINT32 uiRgnHeaderSize; - IMG_UINT32 ui32ISPMtileSize; -} UNCACHED_ALIGN RGXFWIF_HWRTDATA_COMMON; - -/*! - * @InGroup RenderTarget - * @Brief Firmware Render Target data i.e. HWRTDATA used to hold the PM context - */ -typedef struct -{ - IMG_DEV_VIRTADDR RGXFW_ALIGN psPMMListDevVAddr; /*!< MList Data Store */ - - IMG_UINT64 RGXFW_ALIGN ui64VCECatBase[4]; /*!< VCE Page Catalogue base */ - IMG_UINT64 RGXFW_ALIGN ui64VCELastCatBase[4]; - IMG_UINT64 RGXFW_ALIGN ui64TECatBase[4]; /*!< TE Page Catalogue base */ - IMG_UINT64 RGXFW_ALIGN ui64TELastCatBase[4]; - IMG_UINT64 RGXFW_ALIGN ui64AlistCatBase; /*!< Alist Page Catalogue base */ - IMG_UINT64 RGXFW_ALIGN ui64AlistLastCatBase; - - IMG_UINT64 RGXFW_ALIGN ui64PMAListStackPointer; /*!< Freelist page table entry for current Mlist page */ - IMG_UINT32 ui32PMMListStackPointer; /*!< Current Mlist page */ - - RGXFWIF_DEV_VIRTADDR sHWRTDataCommonFwAddr; /*!< Render target dimension dependent data */ - - IMG_UINT32 ui32HWRTDataFlags; - RGXFWIF_RTDATA_STATE eState; /*!< Current workload processing state of HWRTDATA */ - - PRGXFWIF_FREELIST RGXFW_ALIGN apsFreeLists[RGXFW_MAX_FREELISTS]; /*!< Freelist to use */ - IMG_UINT32 aui32FreeListHWRSnapshot[RGXFW_MAX_FREELISTS]; - - IMG_DEV_VIRTADDR RGXFW_ALIGN psVHeapTableDevVAddr; /*!< VHeap table base */ - - RGXFWIF_CLEANUP_CTL sCleanupState; /*!< Render target clean up state */ - - RGXFWIF_RTA_CTL sRTACtl; /*!< Render target array data */ - - IMG_DEV_VIRTADDR RGXFW_ALIGN sTailPtrsDevVAddr; /*!< Tail pointers base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sMacrotileArrayDevVAddr; /*!< Macrotiling array base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sRgnHeaderDevVAddr; /*!< Region headers base */ - IMG_DEV_VIRTADDR RGXFW_ALIGN sRTCDevVAddr; /*!< Render target cache base */ -#if defined(RGX_FIRMWARE) - struct RGXFWIF_FWCOMMONCONTEXT_* RGXFW_ALIGN psOwnerGeom; -#else - RGXFWIF_DEV_VIRTADDR RGXFW_ALIGN pui32OwnerGeomNotUsedByHost; -#endif -#if defined(SUPPORT_TRP) - IMG_UINT32 ui32KickFlagsCopy; - IMG_UINT32 ui32TRPState; - IMG_UINT32 ui32TEPageCopy; - IMG_UINT32 ui32VCEPageCopy; -#endif -#if defined(SUPPORT_AGP) - IMG_BOOL bTACachesNeedZeroing; -#endif -} UNCACHED_ALIGN RGXFWIF_HWRTDATA; - -/* Sync_checkpoint firmware object. - * This is the FW-addressable structure use to hold the sync checkpoint's - * state and other information which needs to be accessed by the firmware. - */ -typedef struct -{ - IMG_UINT32 ui32State; /*!< Holds the current state of the sync checkpoint */ - IMG_UINT32 ui32FwRefCount; /*!< Holds the FW reference count (num of fences/updates processed) */ -} SYNC_CHECKPOINT_FW_OBJ; - -/* Bit mask Firmware can use to test if a checkpoint has signalled or errored */ -#define SYNC_CHECKPOINT_SIGNALLED_MASK (0x1 << 0) - -#endif /* RGX_FWIF_KM_H */ - -/****************************************************************************** - End of file (rgx_fwif_km.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_resetframework.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_resetframework.h deleted file mode 100644 index e60bafd845365..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_resetframework.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_fwif_resetframework.h -@Title Post-reset work-around framework FW interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_FWIF_RESETFRAMEWORK_H) -#define RGX_FWIF_RESETFRAMEWORK_H - -#include "img_types.h" -#include "rgx_fwif_shared.h" - -typedef struct -{ - union - { - IMG_UINT64 uCDMReg_CDM_CB_BASE; // defined(RGX_FEATURE_CDM_USER_MODE_QUEUE) - IMG_UINT64 uCDMReg_CDM_CTRL_STREAM_BASE; // !defined(RGX_FEATURE_CDM_USER_MODE_QUEUE) - }; - IMG_UINT64 uCDMReg_CDM_CB_QUEUE; // !defined(RGX_FEATURE_CDM_USER_MODE_QUEUE) - IMG_UINT64 uCDMReg_CDM_CB; // !defined(RGX_FEATURE_CDM_USER_MODE_QUEUE) -} RGXFWIF_RF_REGISTERS; - -typedef struct -{ - /* THIS MUST BE THE LAST MEMBER OF THE CONTAINING STRUCTURE */ - RGXFWIF_RF_REGISTERS RGXFW_ALIGN sFWRegisters; - -} RGXFWIF_RF_CMD; - -/* to opaquely allocate and copy in the kernel */ -#define RGXFWIF_RF_CMD_SIZE sizeof(RGXFWIF_RF_CMD) - -#endif /* RGX_FWIF_RESETFRAMEWORK_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_sf.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_sf.h deleted file mode 100644 index a1094d7ab72de..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_sf.h +++ /dev/null @@ -1,932 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_fwif_sf.h -@Title RGX firmware interface string format specifiers -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the rgx firmware logging messages. The following - list are the messages the firmware prints. Changing anything - but the first column or spelling mistakes in the strings will - break compatibility with log files created with older/newer - firmware versions. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_FWIF_SF_H -#define RGX_FWIF_SF_H - -/****************************************************************************** - * *DO*NOT* rearrange or delete lines in SFIDLIST or SFGROUPLIST or you - * WILL BREAK fw tracing message compatibility with previous - * fw versions. Only add new ones, if so required. - *****************************************************************************/ -/* Available log groups */ -#define RGXFW_LOG_SFGROUPLIST \ - X(RGXFW_GROUP_NULL,NULL) \ - X(RGXFW_GROUP_MAIN,MAIN) \ - X(RGXFW_GROUP_CLEANUP,CLEANUP) \ - X(RGXFW_GROUP_CSW,CSW) \ - X(RGXFW_GROUP_PM, PM) \ - X(RGXFW_GROUP_RTD,RTD) \ - X(RGXFW_GROUP_SPM,SPM) \ - X(RGXFW_GROUP_MTS,MTS) \ - X(RGXFW_GROUP_BIF,BIF) \ - X(RGXFW_GROUP_MISC,MISC) \ - X(RGXFW_GROUP_POW,POW) \ - X(RGXFW_GROUP_HWR,HWR) \ - X(RGXFW_GROUP_HWP,HWP) \ - X(RGXFW_GROUP_RPM,RPM) \ - X(RGXFW_GROUP_DMA,DMA) \ - X(RGXFW_GROUP_DBG,DBG) - -/*! - * @InGroup SRVAndFWTracing - * @Brief FW Trace log groups(GID) list - */ -enum RGXFW_LOG_SFGROUPS { -#define X(A,B) A, - RGXFW_LOG_SFGROUPLIST -#undef X -}; - -#define IMG_SF_STRING_MAX_SIZE 256U - -typedef struct { - IMG_UINT32 ui32Id; - IMG_CHAR sName[IMG_SF_STRING_MAX_SIZE]; -} RGXFW_STID_FMT; /* pair of string format id and string formats */ - -typedef struct { - IMG_UINT32 ui32Id; - const IMG_CHAR *psName; -} RGXKM_STID_FMT; /* pair of string format id and string formats */ - -/* Table of String Format specifiers, the group they belong and the number of - * arguments each expects. Xmacro styled macros are used to generate what is - * needed without requiring hand editing. - * - * id : id within a group - * gid : group id - * Sym name : name of enumerations used to identify message strings - * String : Actual string - * #args : number of arguments the string format requires - */ -#define RGXFW_LOG_SFIDLIST \ -/*id, gid, id name, string, # arguments */ \ -X( 0, RGXFW_GROUP_NULL, RGXFW_SF_FIRST, "You should not use this string", 0) \ -\ -X( 1, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3D_DEPRECATED, "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x. Partial render:%d, CSW resume:%d, prio:%d", 6) \ -X( 2, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_FINISHED, "3D finished, HWRTData0State=%x, HWRTData1State=%x", 2) \ -X( 3, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK3D_TQ_DEPRECATED, "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d, prio: %d", 4) \ -X( 4, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_TQ_FINISHED, "3D Transfer finished", 0) \ -X( 5, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_COMPUTE_DEPRECATED, "Kick Compute: FWCtx 0x%08.8x @ %d, prio: %d", 3) \ -X( 6, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_FINISHED, "Compute finished", 0) \ -X( 7, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TA_DEPRECATED, "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x. First kick:%d, Last kick:%d, CSW resume:%d, prio:%d", 7) \ -X( 8, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_FINISHED, "TA finished", 0) \ -X( 9, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_RESTART_AFTER_PRENDER, "Restart TA after partial render", 0) \ -X( 10, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_RESUME_WOUT_PRENDER, "Resume TA without partial render", 0) \ -X( 11, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OOM, "Out of memory! Context 0x%08x, HWRTData 0x%x", 2) \ -X( 12, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TLA_DEPRECATED, "Kick TLA: FWCtx 0x%08.8x @ %d, prio:%d", 3) \ -X( 13, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TLA_FINISHED, "TLA finished", 0) \ -X( 14, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CCCB_WOFF_UPDATE, "cCCB Woff update = %d, DM = %d, FWCtx = 0x%08.8x", 3) \ -X( 16, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_START, "UFO Checks for FWCtx 0x%08.8x @ %d", 2) \ -X( 17, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK, "UFO Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \ -X( 18, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_SUCCEEDED, "UFO Checks succeeded", 0) \ -X( 19, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_PR_CHECK, "UFO PR-Check: [0x%08.8x] is 0x%08.8x requires >= 0x%08.8x", 3) \ -X( 20, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK_START, "UFO SPM PR-Checks for FWCtx 0x%08.8x", 1) \ -X( 21, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK_DEPRECATED, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires >= ????????, [0x%08.8x] is ???????? requires 0x%08.8x", 4) \ -X( 22, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_UPDATE_START, "UFO Updates for FWCtx 0x%08.8x @ %d", 2) \ -X( 23, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_UPDATE, "UFO Update: [0x%08.8x] = 0x%08.8x", 2) \ -X( 24, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ASSERT_FAILED, "ASSERT Failed: line %d of:", 1) \ -X( 25, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_LOCKUP_DEPRECATED, "HWR: Lockup detected on DM%d, FWCtx: 0x%08.8x", 2) \ -X( 26, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_RESET_FW_DEPRECATED, "HWR: Reset fw state for DM%d, FWCtx: 0x%08.8x, MemCtx: 0x%08.8x", 3) \ -X( 27, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_RESET_HW_DEPRECATED, "HWR: Reset HW", 0) \ -X( 28, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_TERMINATED_DEPRECATED, "HWR: Lockup recovered.", 0) \ -X( 29, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_FALSE_LOCKUP_DEPRECATED, "HWR: False lockup detected for DM%u", 1) \ -X( 30, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ALIGN_FAILED, "Alignment check %d failed: host = 0x%x, fw = 0x%x", 3) \ -X( 31, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GP_USC_TRIGGERED, "GP USC triggered", 0) \ -X( 32, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_OVERALLOC_REGS, "Overallocating %u temporary registers and %u shared registers for breakpoint handler", 2) \ -X( 33, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET_DEPRECATED, "Setting breakpoint: Addr 0x%08.8x", 1) \ -X( 34, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_STORE, "Store breakpoint state", 0) \ -X( 35, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_UNSET, "Unsetting BP Registers", 0) \ -X( 36, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NONZERO_RT, "Active RTs expected to be zero, actually %u", 1) \ -X( 37, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTC_PRESENT, "RTC present, %u active render targets", 1) \ -X( 38, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_EST_POWER_DEPRECATED, "Estimated Power 0x%x", 1) \ -X( 39, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTA_TARGET, "RTA render target %u", 1) \ -X( 40, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTA_KICK_RENDER, "Kick RTA render %u of %u", 2) \ -X( 41, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_SIZES_CHECK_DEPRECATED, "HWR sizes check %d failed: addresses = %d, sizes = %d", 3) \ -X( 42, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_ENABLE_DEPRECATED, "Pow: DUSTS_ENABLE = 0x%x", 1) \ -X( 43, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_HWREQ_DEPRECATED, "Pow: On(1)/Off(0): %d, Units: 0x%08.8x", 2) \ -X( 44, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_CHANGE_DEPRECATED, "Pow: Changing number of dusts from %d to %d", 2) \ -X( 45, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_SIDEKICK_IDLE_DEPRECATED, "Pow: Sidekick ready to be powered down", 0) \ -X( 46, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_CHANGE_REQ_DEPRECATED, "Pow: Request to change num of dusts to %d (bPowRascalDust=%d)", 2) \ -X( 47, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PARTIALRENDER_WITHOUT_ZSBUFFER_STORE, "No ZS Buffer used for partial render (store)", 0) \ -X( 48, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PARTIALRENDER_WITHOUT_ZSBUFFER_LOAD, "No Depth/Stencil Buffer used for partial render (load)", 0) \ -X( 49, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_SET_LOCKUP_DEPRECATED, "HWR: Lock-up DM%d FWCtx: 0x%08.8x", 2) \ -X( 50, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_REG_VALUE_DEPRECATED, "MLIST%d checker: CatBase TE=0x%08x (%d Pages), VCE=0x%08x (%d Pages), ALIST=0x%08x, IsTA=%d", 7) \ -X( 51, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_MLIST_VALUE, "MLIST%d checker: MList[%d] = 0x%08x", 3) \ -X( 52, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_OK, "MLIST%d OK", 1) \ -X( 53, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_EMPTY, "MLIST%d is empty", 1) \ -X( 54, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_REG_VALUE, "MLIST%d checker: CatBase TE=0x%08x%08x, VCE=0x%08x%08x, ALIST=0x%08x%08x, IsTA=%d", 8) \ -X( 55, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_40480KICK, "3D OQ flush kick", 0) \ -X( 56, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWP_UNSUPPORTED_BLOCK, "HWPerf block ID (0x%x) unsupported by device", 1) \ -X( 57, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET_DEPRECATED2, "Setting breakpoint: Addr 0x%08.8x DM%u", 2) \ -X( 58, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED, "Kick RTU: FWCtx 0x%08.8x @ %d, prio: %d", 3) \ -X( 59, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTU_FINISHED_DEPRECATED, "RDM finished on context %u", 1) \ -X( 60, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_SHG_DEPRECATED, "Kick SHG: FWCtx 0x%08.8x @ %d, prio: %d", 3) \ -X( 61, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SHG_FINISHED_DEPRECATED, "SHG finished", 0) \ -X( 62, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FBA_FINISHED_DEPRECATED, "FBA finished on context %u", 1) \ -X( 63, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_FAILED, "UFO Checks failed", 0) \ -X( 64, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_START, "Kill DM%d start", 1) \ -X( 65, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_COMPLETE, "Kill DM%d complete", 1) \ -X( 66, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FC_CCB_UPDATE_DEPRECATED, "FC%u cCCB Woff update = %u", 2) \ -X( 67, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED2, "Kick RTU: FWCtx 0x%08.8x @ %d, prio: %d, Frame Context: %d", 4) \ -X( 68, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_INIT, "GPU init", 0) \ -X( 69, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNITS_INIT, "GPU Units init (# mask: 0x%x)", 1) \ -X( 70, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGTIMES, "Register access cycles: read: %d cycles, write: %d cycles, iterations: %d", 3) \ -X( 71, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGCONFIG_ADD, "Register configuration added. Address: 0x%x Value: 0x%x%x", 3) \ -X( 72, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGCONFIG_SET, "Register configuration applied to type %d. (0:pow on, 1:Rascal/dust init, 2-5: TA,3D,CDM,TLA, 6:All)", 1) \ -X( 73, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TPC_FLUSH, "Perform TPC flush.", 0) \ -X( 74, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP_DEPRECATED, "GPU has locked up (see HWR logs for more info)", 0) \ -X( 75, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_OUTOFTIME, "HWR has been triggered - GPU has overrun its deadline (see HWR logs)", 0) \ -X( 76, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_POLLFAILURE, "HWR has been triggered - GPU has failed a poll (see HWR logs)", 0) \ -X( 77, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DOPPLER_OOM_DEPRECATED, "Doppler out of memory event for FC %u", 1) \ -X( 78, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK1, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires >= 0x%08.8x", 3) \ -X( 79, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK2, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \ -X( 80, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TIMESTAMP, "TIMESTAMP -> [0x%08.8x]", 1) \ -X( 81, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_RMW_UPDATE_START, "UFO RMW Updates for FWCtx 0x%08.8x @ %d", 2) \ -X( 82, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_RMW_UPDATE, "UFO Update: [0x%08.8x] = 0x%08.8x", 2) \ -X( 83, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NULLCMD, "Kick Null cmd: FWCtx 0x%08.8x @ %d", 2) \ -X( 84, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RPM_OOM_DEPRECATED, "RPM Out of memory! Context 0x%08x, SH requestor %d", 2) \ -X( 85, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTU_ABORT_DISCARD_DEPRECATED, "Discard RTU due to RPM abort: FWCtx 0x%08.8x @ %d, prio: %d, Frame Context: %d", 4) \ -X( 86, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED, "Deferring DM%u from running context 0x%08x @ %d (deferred DMs = 0x%08x)", 4) \ -X( 87, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED_WAITING_TURN_DEPRECATED, "Deferring DM%u from running context 0x%08x @ %d to let other deferred DMs run (deferred DMs = 0x%08x)", 4) \ -X( 88, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED_NO_LONGER, "No longer deferring DM%u from running context = 0x%08x @ %d (deferred DMs = 0x%08x)", 4) \ -X( 89, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_FWCCB_DEPRECATED, "FWCCB for DM%u is full, we will have to wait for space! (Roff = %u, Woff = %u)", 3) \ -X( 90, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_FWCCB, "FWCCB for OSid %u is full, we will have to wait for space! (Roff = %u, Woff = %u)", 3) \ -X( 91, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SYNC_PART, "Host Sync Partition marker: %d", 1) \ -X( 92, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SYNC_PART_RPT, "Host Sync Partition repeat: %d", 1) \ -X( 93, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CLOCK_SPEED_CHANGE, "Core clock set to %d Hz", 1) \ -X( 94, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_OFFSETS, "Compute Queue: FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 7) \ -X( 95, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_DEPRECATED, "Signal check failed, Required Data: 0x%x, Address: 0x%08x%08x", 3) \ -X( 96, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE_DEPRECATED, "Signal update, Snoop Filter: %u, MMU Ctx: %u, Signal Id: %u, Signals Base: 0x%08x%08x", 5) \ -X( 97, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWCONTEXT_SIGNALED, "Signalled the previously waiting FWCtx: 0x%08.8x, OSId: %u, Signal Address: 0x%08x%08x", 4) \ -X( 98, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_STALLED_DEPRECATED, "Compute stalled", 0) \ -X( 99, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_STALLED, "Compute stalled (Roff = %u, Woff = %u, Size = %u)", 3) \ -X(100, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_RESUMED_FROM_STALL, "Compute resumed (Roff = %u, Woff = %u, Size = %u)", 3) \ -X(101, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NOTIFY_SIGNAL_UPDATE, "Signal update notification from the host, PC Physical Address: 0x%08x%08x, Signal Virtual Address: 0x%08x%08x", 4) \ -X(102, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE_OSID_DM_DEPRECATED, "Signal update from DM: %u, OSId: %u, PC Physical Address: 0x%08x%08x", 4) \ -X(103, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_DM_DEPRECATED, "DM: %u signal check failed", 1) \ -X(104, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM_DEPRECATED, "Kick TDM: FWCtx 0x%08.8x @ %d, prio:%d", 3) \ -X(105, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_FINISHED, "TDM finished", 0) \ -X(106, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TE_PIPE_STATUS_DEPRECATED, "MMU_PM_CAT_BASE_TE[%d]_PIPE[%d]: 0x%08x 0x%08x)", 4) \ -X(107, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_HIT_DEPRECATED, "BRN 54141 HIT", 0) \ -X(108, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_APPLYING_DUMMY_TA_DEPRECATED, "BRN 54141 Dummy TA kicked", 0) \ -X(109, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_RESUME_TA_DEPRECATED, "BRN 54141 resume TA", 0) \ -X(110, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_DOUBLE_HIT_DEPRECATED, "BRN 54141 double hit after applying WA", 0) \ -X(111, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_DUMMY_TA_VDM_BASE_DEPRECATED, "BRN 54141 Dummy TA VDM base address: 0x%08x%08x", 2) \ -X(112, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_WITH_CURRENT, "Signal check failed, Required Data: 0x%x, Current Data: 0x%x, Address: 0x%08x%08x", 4) \ -X(113, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BUFFER_STALL_DEPRECATED, "TDM stalled (Roff = %u, Woff = %u)", 2) \ -X(114, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NOTIFY_WRITE_OFFSET_UPDATE, "Write Offset update notification for stalled FWCtx 0x%08.8x", 1) \ -X(115, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_PRIORITY_CHANGE_DEPRECATED, "Changing OSid %d's priority from %u to %u", 3) \ -X(116, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_RESUMED, "Compute resumed", 0) \ -X(117, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TLA, "Kick TLA: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \ -X(118, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM, "Kick TDM: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \ -X(119, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TA, "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x, First kick:%d, Last kick:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 11) \ -X(120, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3D, "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x, Partial render:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 10) \ -X(121, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3DTQ, "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8) \ -X(122, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_COMPUTE, "Kick Compute: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, ext:0x%08x, int:0x%08x)", 6) \ -X(123, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED3, "Kick RTU: FWCtx 0x%08.8x @ %d, Frame Context:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8) \ -X(124, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_SHG_DEPRECATED2, "Kick SHG: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \ -X(125, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CSRM_RECONFIG, "Reconfigure CSRM: special coeff support enable %d.", 1) \ -X(127, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_REQ_MAX_COEFFS, "TA requires max coeff mode, deferring: %d.", 1) \ -X(128, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_REQ_MAX_COEFFS, "3D requires max coeff mode, deferring: %d.", 1) \ -X(129, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_FAILED, "Kill DM%d failed", 1) \ -X(130, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_QUEUE, "Thread Queue is full, we will have to wait for space! (Roff = %u, Woff = %u)", 2) \ -X(131, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_QUEUE_FENCE, "Thread Queue is fencing, we are waiting for Roff = %d (Roff = %u, Woff = %u)", 3) \ -X(132, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SET_HCS_TRIGGERED, "DM %d failed to Context Switch on time. Triggered HCS (see HWR logs).", 1) \ -X(133, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HCS_SET_DEPRECATED, "HCS changed to %d ms", 1) \ -X(134, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UPDATE_TILES_IN_FLIGHT_DEPRECATED, "Updating Tiles In Flight (Dusts=%d, PartitionMask=0x%08x, ISPCtl=0x%08x%08x)", 4) \ -X(135, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SET_TILES_IN_FLIGHT, " Phantom %d: USCTiles=%d", 2) \ -X(136, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ISOLATION_CONF_OFF_DEPRECATED, "Isolation grouping is disabled", 0) \ -X(137, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ISOLATION_CONF_DEPRECATED, "Isolation group configured with a priority threshold of %d", 1) \ -X(138, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_ONLINE_DEPRECATED, "OS %d has come online", 1) \ -X(139, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_OFFLINE_DEPRECATED, "OS %d has gone offline", 1) \ -X(140, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWCONTEXT_SIGNAL_REKICK, "Signalled the previously stalled FWCtx: 0x%08.8x, OSId: %u, Signal Address: 0x%08x%08x", 4) \ -X(141, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSETS_DEPRECATED, "TDM Queue: FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 7) \ -X(142, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSET_READ_RESET, "Reset TDM Queue Read Offset: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u becomes 0, Woff = %u, Size = %u)", 6) \ -X(143, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UMQ_MISMATCHED_READ_OFFSET, "User Mode Queue mismatched stream start: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u, StreamStartOffset = %u)", 5) \ -X(144, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_DEINIT, "GPU deinit", 0) \ -X(145, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNITS_DEINIT, "GPU units deinit", 0) \ -X(146, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CONFIG, "Initialised OS %d with config flags 0x%08x", 2) \ -X(147, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_LIMIT, "UFO limit exceeded %d/%d", 2) \ -X(148, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_62850KICK, "3D Dummy stencil store", 0) \ -X(149, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CONFIG_DEPRECATED, "Initialised OS %d with config flags 0x%08x and extended config flags 0x%08x", 3) \ -X(150, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_COMMAND_DEPRECATED, "Unknown Command (eCmdType=0x%08x)", 1) \ -X(151, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_FORCED_UPDATE, "UFO forced update: FWCtx 0x%08.8x @ %d [0x%08.8x] = 0x%08.8x", 4) \ -X(152, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_FORCED_UPDATE_NOP, "UFO forced update NOP: FWCtx 0x%08.8x @ %d [0x%08.8x] = 0x%08.8x, reason %d", 5) \ -X(153, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN66075_CHECK, "TDM context switch check: Roff %u points to 0x%08x, Match=%u", 3) \ -X(154, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CCBS, "OSid %d CCB init status: %d (1-ok 0-fail): kCCBCtl@0x%x kCCB@0x%x fwCCBCtl@0x%x fwCCB@0x%x", 6) \ -X(155, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWIRQ, "FW IRQ # %u @ %u", 2) \ -X(156, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET, "Setting breakpoint: Addr 0x%08.8x DM%u usc_breakpoint_ctrl_dm = %u", 3) \ -X(157, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KERNEL_CCB_DEPRECATED, "Invalid KCCB setup for OSid %u: KCCB 0x%08x, KCCB Ctrl 0x%08x", 3) \ -X(158, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KERNEL_CCB_CMD, "Invalid KCCB cmd (%u) for OSid %u @ KCCB 0x%08x", 3) \ -X(159, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FW_FAULT, "FW FAULT: At line %d in file 0x%08x%08x, additional data=0x%08x", 4) \ -X(160, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_INVALID, "Invalid breakpoint: MemCtx 0x%08x Addr 0x%08.8x DM%u usc_breakpoint_ctrl_dm = %u", 4) \ -X(161, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FLUSHINVAL_CMD_INVALID_DEPRECATED, "Discarding invalid SLC flushinval command for OSid %u: DM %u, FWCtx 0x%08x", 3) \ -X(162, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_NOTIFY_WRITE_OFFSET_UPDATE_DEPRECATED, "Invalid Write Offset update notification from OSid %u to DM %u: FWCtx 0x%08x, MemCtx 0x%08x", 4) \ -X(163, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KCCB_KICK_CMD_DEPRECATED, "Null FWCtx in KCCB kick cmd for OSid %u: KCCB 0x%08x, ROff %u, WOff %u", 4) \ -X(164, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FULL_CHPTCCB, "Checkpoint CCB for OSid %u is full, signalling host for full check state (Roff = %u, Woff = %u)", 3) \ -X(165, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CCBS_DEPRECATED, "OSid %d CCB init status: %d (1-ok 0-fail): kCCBCtl@0x%x kCCB@0x%x fwCCBCtl@0x%x fwCCB@0x%x chptCCBCtl@0x%x chptCCB@0x%x", 8) \ -X(166, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_STATE_CHANGE, "OSid %d fw state transition request: from %d to %d (0-offline 1-ready 2-active 3-offloading). Status %d (1-ok 0-fail)", 4) \ -X(167, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_STALE_KCCB_CMDS, "OSid %u has %u stale commands in its KCCB", 2) \ -X(168, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_VCE_PAUSE, "Applying VCE pause", 0) \ -X(169, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KCCB_UPDATE_RTN_SLOT_DEPRECATED, "OSid %u KCCB slot %u value updated to %u", 3) \ -X(170, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_KCCB_COMMAND, "Unknown KCCB Command: KCCBCtl=0x%08x, KCCB=0x%08x, Roff=%u, Woff=%u, Wrap=%u, Cmd=0x%08x, CmdType=0x%08x", 7) \ -X(171, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_CCB_COMMAND1, "Unknown Client CCB Command processing fences: FWCtx=0x%08x, CCBCtl=0x%08x, CCB=0x%08x, Roff=%u, Doff=%u, Woff=%u, Wrap=%u, CmdHdr=0x%08x, CmdType=0x%08x, CmdSize=%u", 10) \ -X(172, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_CCB_COMMAND2, "Unknown Client CCB Command executing kick: FWCtx=0x%08x, CCBCtl=0x%08x, CCB=0x%08x, Roff=%u, Doff=%u, Woff=%u, Wrap=%u, CmdHdr=0x%08x, CmdType=0x%08x, CmdSize=%u", 10) \ -X(173, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KCCB_KICK_CMD, "Null FWCtx in KCCB kick cmd for OSid %u with WOff %u", 2) \ -X(174, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FLUSHINVAL_CMD_INVALID, "Discarding invalid SLC flushinval command for OSid %u, FWCtx 0x%08x", 2) \ -X(175, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_NOTIFY_WRITE_OFFSET_UPDATE, "Invalid Write Offset update notification from OSid %u: FWCtx 0x%08x, MemCtx 0x%08x", 3) \ -X(176, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FW_INIT_CONFIG, "Initialised Firmware with config flags 0x%08x and extended config flags 0x%08x", 2) \ -X(177, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_CONFIG, "Set Periodic Hardware Reset Mode: %d", 1) \ -X(179, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_TRIG, "PHR mode %d, FW state: 0x%08x, HWR flags: 0x%08x", 3) \ -X(180, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_RESET_DEPRECATED, "PHR mode %d triggered a reset", 1) \ -X(181, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE, "Signal update, Snoop Filter: %u, Signal Id: %u", 2) \ -X(182, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEV_SERIES8_DEPRECATED, "WARNING: Skipping FW KCCB Cmd type %d which is not yet supported on Series8.", 1) \ -X(183, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INCONSISTENT_MMU_FLAGS, "MMU context cache data NULL, but cache flags=0x%x (sync counter=%u, update value=%u) OSId=%u", 4) \ -X(184, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SLC_FLUSH, "SLC range based flush: Context=%u VAddr=0x%02x%08x, Size=0x%08x, Invalidate=%d", 5) \ -X(185, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FBSC_INVAL, "FBSC invalidate for Context Set [0x%08x]: Entry mask 0x%08x%08x.", 3) \ -X(186, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN66284_UPDATE, "TDM context switch check: Roff %u was not valid for kick starting at %u, moving back to %u", 3) \ -X(187, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SPFILTER_UPDATES, "Signal updates: FIFO: %u, Signals: 0x%08x", 2) \ -X(188, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_FBSC_CMD, "Invalid FBSC cmd: FWCtx 0x%08x, MemCtx 0x%08x", 2) \ -X(189, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN68497_BLIT, "Insert BRN68497 WA blit after TDM Context store.", 0) \ -X(190, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PENDING_UFO_UPDATE_START, "UFO Updates for previously finished FWCtx 0x%08.8x", 1) \ -X(191, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTC_RTA_PRESENT, "RTC with RTA present, %u active render targets", 1) \ -X(192, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NULL_RTAS, "Invalid RTA Set-up. The ValidRenderTargets array in RTACtl is Null!", 0) \ -X(193, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_COUNTER, "Block 0x%x / Counter 0x%x INVALID and ignored", 2) \ -X(194, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ECC_FAULT_DEPRECATED, "ECC fault GPU=0x%08x FW=0x%08x", 2) \ -X(195, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PROCESS_XPU_EVENT, "Processing XPU event on DM = %d", 1) \ -X(196, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_VZ_WDG_TRIGGER, "OSid %u failed to respond to the virtualisation watchdog in time. Timestamp of its last input = %u", 2) \ -X(197, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP, "GPU-%u has locked up (see HWR logs for more info)", 1) \ -X(198, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UPDATE_TILES_IN_FLIGHT, "Updating Tiles In Flight (Dusts=%d, PartitionMask=0x%08x, ISPCtl=0x%08x)", 3) \ -X(199, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP_DM, "GPU has locked up (see HWR logs for more info)", 0) \ -X(200, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REPROCESS_XPU_EVENTS, "Reprocessing outstanding XPU events from cores 0x%02x", 1) \ -X(201, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SECONDARY_XPU_EVENT, "Secondary XPU event on DM=%d, CoreMask=0x%02x, Raised=0x%02x", 3) \ -X(202, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSETS, "TDM Queue: Core %u, FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 8) \ -X(203, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BUFFER_STALL, "TDM stalled Core %u (Roff = %u, Woff = %u)", 3) \ -X(204, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_OFFSETS, "Compute Queue: Core %u, FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 8) \ -X(205, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_STALLED, "Compute stalled core %u (Roff = %u, Woff = %u, Size = %u)", 4) \ -X(206, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UMQ_MISMATCHED_CORE_READ_OFFSET, "User Mode Queue mismatched stream start: Core %u, FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u, StreamStartOffset = %u)", 6) \ -X(207, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_RESUMED_FROM_STALL, "TDM resumed core %u (Roff = %u, Woff = %u)", 3) \ -X(208, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_RESUMED_FROM_STALL, "Compute resumed core %u (Roff = %u, Woff = %u, Size = %u)", 4) \ -X(209, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_MTS_PERMISSION_CHANGED, " Updated permission for OSid %u to perform MTS kicks: %u (1 = allowed, 0 = not allowed)", 2) \ -X(210, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TEST1, "Mask = 0x%X, mask2 = 0x%X", 2) \ -X(211, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TEST2, " core %u, reg = %u, mask = 0x%X)", 3) \ -X(212, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ECC_FAULT_SAFETY_BUS, "ECC fault received from safety bus: 0x%08x", 1) \ -X(213, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SAFETY_WDG_CONFIG, "Safety Watchdog threshold period set to 0x%x clock cycles", 1) \ -X(214, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SAFETY_WDG_TRIGGER, "MTS Safety Event trigged by the safety watchdog.", 0) \ -X(215, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_USC_TASKS_RANGE, "DM%d USC tasks range limit 0 - %d, stride %d", 3) \ -X(216, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_ECC_FAULT, "ECC fault GPU=0x%08x", 1) \ -X(217, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_SAFETY_RESET, "GPU Hardware units reset to prevent transient faults.", 0) \ -X(218, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ABORTCMD, "Kick Abort cmd: FWCtx 0x%08.8x @ %d", 2) \ -X(219, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RAY_DEPRECATED, "Kick Ray: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7)\ -X(220, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RAY_FINISHED_DEPRECATED, "Ray finished", 0) \ -X(221, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWDATA_INIT_STATUS, "State of firmware's private data at boot time: %d (0 = uninitialised, 1 = initialised); Fw State Flags = 0x%08X", 2) \ -X(222, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CFI_TIMEOUT, "CFI Timeout detected (%d increasing to %d)", 2) \ -X(223, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CFI_TIMEOUT_FBM, "CFI Timeout detected for FBM (%d increasing to %d)", 2) \ -X(224, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GEOM_OOM_DISALLOWED, "Geom OOM event not allowed", 0) \ -X(225, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_PRIORITY_CHANGE, "Changing OSid %d's priority from %u to %u; Isolation = %u (0 = off; 1 = on)", 4) \ -X(226, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SKIP_ALREADY_RUN_GEOM, "Skipping already executed TA FWCtx 0x%08.8x @ %d", 2) \ -X(227, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ATTEMPT_TO_RUN_AHEAD_GEOM, "Attempt to execute TA FWCtx 0x%08.8x @ %d ahead of time on other GEOM", 2) \ -X(228, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM_DEPRECATED2, "Kick TDM: Kick ID %u FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8) \ -X(229, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TA_PIPELINE, "Kick TA: Kick ID %u FWCtx 0x%08.8x @ %d, RTD 0x%08x, First kick:%d, Last kick:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 12) \ -X(230, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3D_PIPELINE, "Kick 3D: Kick ID %u FWCtx 0x%08.8x @ %d, RTD 0x%08x, Partial render:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 11) \ -X(231, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_COMPUTE_PIPELINE, "Kick Compute: Kick ID %u FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, ext:0x%08x, int:0x%08x)", 7) \ -X(232, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_FINISHED_PIPELINE, "TDM finished: Kick ID %u ", 1) \ -X(233, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_FINISHED_PIPELINE, "TA finished: Kick ID %u ", 1) \ -X(234, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_FINISHED_PIPELINE, "3D finished: Kick ID %u , HWRTData0State=%x, HWRTData1State=%x", 3) \ -X(235, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_FINISHED_PIPELINE, "Compute finished: Kick ID %u ", 1) \ -X(236, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM_PIPELINE, "Kick TDM: Kick ID %u FWCtx 0x%08.8x @ %d, Base 0x%08x%08x. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 10) \ -X(237, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RAY_PIPELINE, "Kick Ray: Kick ID %u FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8)\ -X(238, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RAY_FINISHED_PIPELINE, "Ray finished: Kick ID %u ", 1) \ -X(288, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ZERO_LM, "Zeroing local memory after context storing FWCtx = 0x%08.8x", 1) \ -\ -X( 1, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK_DEPRECATED, "Bg Task DM = %u, counted = %d", 2) \ -X( 2, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_COMPLETE_DEPRECATED, "Bg Task complete DM = %u", 1) \ -X( 3, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_KICK_DEPRECATED, "Irq Task DM = %u, Breq = %d, SBIrq = 0x%x", 3) \ -X( 4, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_COMPLETE_DEPRECATED, "Irq Task complete DM = %u", 1) \ -X( 5, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KICK_MTS_BG_ALL_DEPRECATED, "Kick MTS Bg task DM=All", 0) \ -X( 6, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KICK_MTS_IRQ, "Kick MTS Irq task DM=%d", 1) \ -X( 7, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYCELLTYPE_DEPRECATED, "Ready queue debug DM = %u, celltype = %d", 2) \ -X( 8, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYTORUN_DEPRECATED, "Ready-to-run debug DM = %u, item = 0x%x", 2) \ -X( 9, RGXFW_GROUP_MTS, RGXFW_SF_MTS_CMDHEADER, "Client command header DM = %u, client CCB = 0x%x, cmd = 0x%x", 3) \ -X( 10, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYTORUN, "Ready-to-run debug OSid = %u, DM = %u, item = 0x%x", 3) \ -X( 11, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYCELLTYPE_DEPRECATED2, "Ready queue debug DM = %u, celltype = %d, OSid = %u", 3) \ -X( 12, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK_DEPRECATED2, "Bg Task DM = %u, counted = %d, OSid = %u", 3) \ -X( 13, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_COMPLETE, "Bg Task complete DM Bitfield: %u", 1) \ -X( 14, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_COMPLETE, "Irq Task complete.", 0) \ -X( 15, RGXFW_GROUP_MTS, RGXFW_SF_MTS_CMD_DISCARD, "Discarded Command Type: %d OS ID = %d PID = %d context = 0x%08x cccb ROff = 0x%x, due to USC breakpoint hit by OS ID = %d PID = %d.", 7) \ -X( 16, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_EXEC_DEPRECATED, "KCCB Slot %u: DM=%u, Cmd=0x%08x, OSid=%u", 4) \ -X( 17, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_RTN_VALUE, "KCCB Slot %u: Return value %u", 2) \ -X( 18, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK, "Bg Task OSid = %u", 1) \ -X( 19, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_EXEC, "KCCB Slot %u: Cmd=0x%08x, OSid=%u", 3) \ -X( 20, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_KICK, "Irq Task (EVENT_STATUS=0x%08x)", 1) \ -X( 21, RGXFW_GROUP_MTS, RGXFW_SF_MTS_VZ_SIDEBAND, "VZ sideband test, kicked with OSid=%u from MTS, OSid for test=%u", 2) \ -\ -X( 1, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FWCTX_CLEANUP, "FwCommonContext [0x%08x] cleaned", 1) \ -X( 2, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FWCTX_BUSY, "FwCommonContext [0x%08x] is busy: ReadOffset = %d, WriteOffset = %d", 3) \ -X( 3, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANUP_DEPRECATED, "HWRTData [0x%08x] for DM=%d, received cleanup request", 2) \ -X( 4, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED_FOR_DM_DEPRECATED, "HWRTData [0x%08x] HW Context cleaned for DM%u, executed commands = %d", 3) \ -X( 5, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY_DEPRECATED, "HWRTData [0x%08x] HW Context for DM%u is busy", 2) \ -X( 6, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED_DEPRECATED, "HWRTData [0x%08x] HW Context %u cleaned", 2) \ -X( 7, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FL_CLEANED, "Freelist [0x%08x] cleaned", 1) \ -X( 8, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_ZSBUFFER_CLEANED, "ZSBuffer [0x%08x] cleaned", 1) \ -X( 9, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_ZSBUFFER_BUSY, "ZSBuffer [0x%08x] is busy: submitted = %d, executed = %d", 3) \ -X( 10, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY_DEPRECATED2, "HWRTData [0x%08x] HW Context for DM%u is busy: submitted = %d, executed = %d", 4) \ -X( 11, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANUP_DEPRECATED, "HW Ray Frame data [0x%08x] for DM=%d, received cleanup request", 2) \ -X( 12, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANED_FOR_DM_DEPRECATED, "HW Ray Frame Data [0x%08x] cleaned for DM%u, executed commands = %d", 3) \ -X( 13, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_BUSY_DEPRECATED, "HW Ray Frame Data [0x%08x] for DM%u is busy: submitted = %d, executed = %d", 4) \ -X( 14, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANED_DEPRECATED, "HW Ray Frame Data [0x%08x] HW Context %u cleaned", 2) \ -X( 15, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_INVALID_REQUEST, "Discarding invalid cleanup request of type 0x%x", 1) \ -X( 16, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANUP, "Received cleanup request for HWRTData [0x%08x]", 1) \ -X( 17, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY, "HWRTData [0x%08x] HW Context is busy: submitted = %d, executed = %d", 3) \ -X( 18, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED, "HWRTData [0x%08x] HW Context %u cleaned, executed commands = %d", 3) \ -\ -X( 1, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_NEEDS_RESUME, "CDM FWCtx 0x%08.8x needs resume", 1) \ -X( 2, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_RESUME_DEPRECATED, "*** CDM FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \ -X( 3, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_SHARED, "CDM FWCtx shared alloc size load 0x%x", 1) \ -X( 4, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_COMPLETE, "*** CDM FWCtx store complete", 0) \ -X( 5, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_START, "*** CDM FWCtx store start", 0) \ -X( 6, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_SOFT_RESET, "CDM Soft Reset", 0) \ -X( 7, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_NEEDS_RESUME, "3D FWCtx 0x%08.8x needs resume", 1) \ -X( 8, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME, "*** 3D FWCtx 0x%08.8x resume", 1) \ -X( 9, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_COMPLETE, "*** 3D context store complete", 0) \ -X( 10, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_DEPRECATED, "3D context store pipe state: 0x%08.8x 0x%08.8x 0x%08.8x", 3) \ -X( 11, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_START, "*** 3D context store start", 0) \ -X( 12, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_TQ_RESUME, "*** 3D TQ FWCtx 0x%08.8x resume", 1) \ -X( 13, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_NEEDS_RESUME, "TA FWCtx 0x%08.8x needs resume", 1) \ -X( 14, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_RESUME, "*** TA FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \ -X( 15, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_SHARED, "TA context shared alloc size store 0x%x, load 0x%x", 2) \ -X( 16, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_COMPLETE, "*** TA context store complete", 0) \ -X( 17, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_START, "*** TA context store start", 0) \ -X( 18, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED_DEPRECATED, "Higher priority context scheduled for DM %u, old prio:%d, new prio:%d", 3) \ -X( 19, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SET_CONTEXT_PRIORITY, "Set FWCtx 0x%x priority to %u", 2) \ -X( 20, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_DEPRECATED2, "3D context store pipe%d state: 0x%08.8x", 2) \ -X( 21, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE_DEPRECATED, "3D context resume pipe%d state: 0x%08.8x", 2) \ -X( 22, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_NEEDS_RESUME_DEPRECATED, "SHG FWCtx 0x%08.8x needs resume", 1) \ -X( 23, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_RESUME_DEPRECATED, "*** SHG FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \ -X( 24, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_SHARED_DEPRECATED, "SHG context shared alloc size store 0x%x, load 0x%x", 2) \ -X( 25, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_STORE_COMPLETE_DEPRECATED, "*** SHG context store complete", 0) \ -X( 26, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_STORE_START_DEPRECATED, "*** SHG context store start", 0) \ -X( 27, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_PIPE_INDIRECT, "Performing TA indirection, last used pipe %d", 1) \ -X( 28, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_CTRL_STREAM_TERMINATE, "CDM context store hit ctrl stream terminate. Skip resume.", 0) \ -X( 29, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_RESUME_AB_BUFFER, "*** CDM FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x, shader state %u", 4) \ -X( 30, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STATE_BUFFER_FLIP, "TA PDS/USC state buffer flip (%d->%d)", 2) \ -X( 31, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_52563_HIT_DEPRECATED, "TA context store hit BRN 52563: vertex store tasks outstanding", 0) \ -X( 32, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_USC_POLL_FAILED, "TA USC poll failed (USC vertex task count: %d)", 1) \ -X( 33, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_DEFERRED_DEPRECATED, "TA context store deferred due to BRN 54141.", 0) \ -X( 34, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED_DEPRECATED2, "Higher priority context scheduled for DM %u. Prios (OSid, OSid Prio, Context Prio): Current: %u, %u, %u New: %u, %u, %u", 7) \ -X( 35, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_START, "*** TDM context store start", 0) \ -X( 36, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_COMPLETE, "*** TDM context store complete", 0) \ -X( 37, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_NEEDS_RESUME_DEPRECATED, "TDM context needs resume, header [0x%08.8x, 0x%08.8x]", 2) \ -X( 38, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED, "Higher priority context scheduled for DM %u. Prios (OSid, OSid Prio, Context Prio): Current: %u, %u, %u New: %u, %u, %u. Hard Context Switching: %u", 8) \ -X( 39, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE, "3D context store pipe %2d (%2d) state: 0x%08.8x", 3) \ -X( 40, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE, "3D context resume pipe %2d (%2d) state: 0x%08.8x", 3) \ -X( 41, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_START_VOLCANIC, "*** 3D context store start version %d (1=IPP_TILE, 2=ISP_TILE)", 1) \ -X( 42, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_VOLCANIC, "3D context store pipe%d state: 0x%08.8x%08x", 3) \ -X( 43, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE_VOLCANIC, "3D context resume pipe%d state: 0x%08.8x%08x", 3) \ -X( 44, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_IPP_STATE, "3D context resume IPP state: 0x%08.8x%08x", 2) \ -X( 45, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_PIPES_EMPTY, "All 3D pipes empty after ISP tile mode store! IPP_status: 0x%08x", 1) \ -X( 46, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_RESUME_PIPE_STATE_DEPRECATED, "TDM context resume pipe%d state: 0x%08.8x%08x", 3) \ -X( 47, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_LEVEL4_STORE_START, "*** 3D context store start version 4", 0) \ -X( 48, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RESUME_MULTICORE, "Multicore context resume on DM%d active core mask 0x%04.4x", 2) \ -X( 49, RGXFW_GROUP_CSW, RGXFW_SF_CSW_STORE_MULTICORE, "Multicore context store on DM%d active core mask 0x%04.4x", 2) \ -X( 50, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_RESUME_PIPE_STATE, "TDM context resume Core %d, pipe%d state: 0x%08.8x%08x%08x", 5) \ -X( 51, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_STORE_COMPLETE, "*** RDM FWCtx store complete", 0) \ -X( 52, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_STORE_START, "*** RDM FWCtx store start", 0) \ -X( 53, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_NEEDS_RESUME, "RDM FWCtx 0x%08.8x needs resume", 1) \ -X( 54, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_RESUME, "RDM FWCtx 0x%08.8x resume", 1) \ -\ -X( 1, RGXFW_GROUP_BIF, RGXFW_SF_BIF_ACTIVATE_BIFREQ_DEPRECATED, "Activate MemCtx=0x%08x BIFreq=%d secure=%d", 3) \ -X( 2, RGXFW_GROUP_BIF, RGXFW_SF_BIF_DEACTIVATE, "Deactivate MemCtx=0x%08x", 1) \ -X( 3, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCREG_ALLOC_DEPRECATED, "Alloc PC reg %d", 1) \ -X( 4, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCSET_GRAB, "Grab reg set %d refcount now %d", 2) \ -X( 5, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCSET_UNGRAB, "Ungrab reg set %d refcount now %d", 2) \ -X( 6, RGXFW_GROUP_BIF, RGXFW_SF_BIF_SETUP_REG_BIFREQ_DEPRECATED, "Setup reg=%d BIFreq=%d, expect=0x%08x%08x, actual=0x%08x%08x", 6) \ -X( 7, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TRUST_DEPRECATED, "Trust enabled:%d, for BIFreq=%d", 2) \ -X( 8, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TILECFG_DEPRECATED, "BIF Tiling Cfg %d base 0x%08x%08x len 0x%08x%08x enable %d stride %d --> 0x%08x%08x", 9) \ -X( 9, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSID0, "Wrote the Value %d to OSID0, Cat Base %d, Register's contents are now 0x%08x 0x%08x", 4) \ -X( 10, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSID1, "Wrote the Value %d to OSID1, Context %d, Register's contents are now 0x%04x", 3) \ -X( 11, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSIDx, "ui32OSid = %u, Catbase = %u, Reg Address = 0x%x, Reg index = %u, Bitshift index = %u, Val = 0x%08x%08x", 7) \ -X( 12, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY_BIFREQ_DEPRECATED, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u, BIFREQ %u", 5) \ -X( 13, RGXFW_GROUP_BIF, RGXFW_SF_BIF_UNMAP_GPU_MEMORY, "Unmap GPU memory (event status 0x%x)", 1) \ -X( 14, RGXFW_GROUP_BIF, RGXFW_SF_BIF_ACTIVATE_DM, "Activate MemCtx=0x%08x DM=%d secure=%d", 3) \ -X( 15, RGXFW_GROUP_BIF, RGXFW_SF_BIF_SETUP_REG_DM_DEPRECATED, "Setup reg=%d DM=%d, expect=0x%08x%08x, actual=0x%08x%08x", 6) \ -X( 16, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u", 4) \ -X( 17, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TRUST_DM, "Trust enabled:%d, for DM=%d", 2) \ -X( 18, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY_DM, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u, DM %u", 5) \ -X( 19, RGXFW_GROUP_BIF, RGXFW_SF_BIF_SETUP_REG_DM, "Setup register set=%d DM=%d, PC address=0x%08x%08x, OSid=%u, NewPCRegRequired=%d", 6) \ -X( 20, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCSET_ALLOC, "Alloc PC set %d as register range [%u - %u]", 3) \ -\ -X( 1, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_WRITE, "GPIO write 0x%02x", 1) \ -X( 2, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_READ, "GPIO read 0x%02x", 1) \ -X( 3, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_ENABLED, "GPIO enabled", 0) \ -X( 4, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_DISABLED, "GPIO disabled", 0) \ -X( 5, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_STATUS, "GPIO status=%d (0=OK, 1=Disabled)", 1) \ -X( 6, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_READ, "GPIO_AP: Read address=0x%02x (%d byte(s))", 2) \ -X( 7, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_WRITE, "GPIO_AP: Write address=0x%02x (%d byte(s))", 2) \ -X( 8, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_TIMEOUT, "GPIO_AP timeout!", 0) \ -X( 9, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_ERROR, "GPIO_AP error. GPIO status=%d (0=OK, 1=Disabled)", 1) \ -X( 10, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_ALREADY_READ, "GPIO already read 0x%02x", 1) \ -X( 11, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_CHECK_BUFFER_AVAILABLE, "SR: Check buffer %d available returned %d", 2) \ -X( 12, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_WAITING_BUFFER_AVAILABLE, "SR: Waiting for buffer %d", 1) \ -X( 13, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_WAIT_BUFFER_TIMEOUT, "SR: Timeout waiting for buffer %d (after %d ticks)", 2) \ -X( 14, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_FRAME_CHECK, "SR: Skip frame check for strip %d returned %d (0=No skip, 1=Skip frame)", 2) \ -X( 15, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_REMAINING_STRIPS, "SR: Skip remaining strip %d in frame", 1) \ -X( 16, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_FRAME_SKIP_NEW_FRAME, "SR: Inform HW that strip %d is a new frame", 1) \ -X( 17, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_FRAME_TIMEOUT, "SR: Timeout waiting for INTERRUPT_FRAME_SKIP (after %d ticks)", 1) \ -X( 18, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_STRIP_MODE, "SR: Strip mode is %d", 1) \ -X( 19, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_STRIP_INDEX, "SR: Strip Render start (strip %d)", 1) \ -X( 20, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_BUFFER_RENDERED, "SR: Strip Render complete (buffer %d)", 1) \ -X( 21, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_BUFFER_FAULT, "SR: Strip Render fault (buffer %d)", 1) \ -X( 22, RGXFW_GROUP_MISC, RGXFW_SF_MISC_TRP_STATE, "TRP state: %d", 1) \ -X( 23, RGXFW_GROUP_MISC, RGXFW_SF_MISC_TRP_FAILURE, "TRP failure: %d", 1) \ -X( 24, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SW_TRP_STATE, "SW TRP State: %d", 1) \ -X( 25, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SW_TRP_FAILURE, "SW TRP failure: %d", 1) \ -X( 26, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HW_KICK, "HW kick event (%u)", 1) \ -X( 27, RGXFW_GROUP_MISC, RGXFW_SF_MISC_WGP_CHECKSUMS, "GPU core (%u/%u): checksum 0x%08x vs. 0x%08x", 4) \ -X( 28, RGXFW_GROUP_MISC, RGXFW_SF_MISC_WGP_UNIT_CHECKSUMS, "GPU core (%u/%u), unit (%u,%u): checksum 0x%08x vs. 0x%08x", 6) \ -X( 29, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_CHECK_REG, "HWR: Core%u, Register=0x%08x, OldValue=0x%08x%08x, CurrValue=0x%08x%08x", 6) \ -X( 30, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_USC_SLOTS_CHECK, "HWR: USC Core%u, ui32TotalSlotsUsedByDM=0x%08x, psDMHWCtl->ui32USCSlotsUsedByDM=0x%08x, bHWRNeeded=%u", 4) \ -X( 31, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_USC_REG_CHECK, "HWR: USC Core%u, Register=0x%08x, OldValue=0x%08x%08x, CurrValue=0x%08x%08x", 6) \ -\ -X( 1, RGXFW_GROUP_PM, RGXFW_SF_PM_AMLIST, "ALIST%d SP = %u, MLIST%d SP = %u (VCE 0x%08x%08x, TE 0x%08x%08x, ALIST 0x%08x%08x)", 10) \ -X( 2, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED_DEPRECATED, "Is TA: %d, finished: %d on HW %u (HWRTData = 0x%08x, MemCtx = 0x%08x). FL different between TA/3D: global:%d, local:%d, mmu:%d", 8) \ -X( 3, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE_DEPRECATED, "UFL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), MFL-3D-Base: 0x%08x%08x (SP = %u, 4PT = %u)", 14) \ -X( 4, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE_DEPRECATED, "UFL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), MFL-TA-Base: 0x%08x%08x (SP = %u, 4PT = %u)", 14) \ -X( 5, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_GROW_COMPLETE_DEPRECATED, "Freelist grow completed [0x%08x]: added pages 0x%08x, total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 5) \ -X( 6, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_GROW_DENIED_DEPRECATED, "Grow for freelist ID=0x%08x denied by host", 1) \ -X( 7, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_COMPLETE, "Freelist update completed [0x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 5) \ -X( 8, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_RECONSTRUCTION_FAILED_DEPRECATED, "Reconstruction of freelist ID=0x%08x failed", 1) \ -X( 9, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_WARNING, "Ignored attempt to pause or unpause the DM while there is no relevant operation in progress (0-TA,1-3D): %d, operation(0-unpause, 1-pause): %d", 2) \ -X( 10, RGXFW_GROUP_PM, RGXFW_SF_PM_3D_TIMEOUT_STATUS, "Force free 3D Context memory, FWCtx: 0x%08x, status(1:success, 0:fail): %d", 2)\ -X( 11, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_ALLOC, "PM pause TA ALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \ -X( 12, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_UNPAUSE_ALLOC, "PM unpause TA ALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \ -X( 13, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_DALLOC, "PM pause 3D DALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \ -X( 14, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_UNPAUSE_DALLOC, "PM unpause 3D DALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \ -X( 15, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_FAILED, "PM ALLOC/DALLOC change was not actioned: PM_PAGE_MANAGEOP_STATUS=0x%x", 1) \ -X( 16, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED, "Is TA: %d, finished: %d on HW %u (HWRTData = 0x%08x, MemCtx = 0x%08x). FL different between TA/3D: global:%d, local:%d", 7) \ -X( 17, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE, "UFL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \ -X( 18, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE, "UFL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \ -X( 19, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_COMPLETE_VOLCANIC, "Freelist update completed [0x%08x / FL State 0x%08x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 7) \ -X( 20, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_FAILED, "Freelist update failed [0x%08x / FL State 0x%08x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 7) \ -X( 21, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE_VOLCANIC, "UFL-3D-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \ -X( 22, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE_VOLCANIC, "UFL-TA-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \ -X( 23, RGXFW_GROUP_PM, RGXFW_SF_PM_CHECK_FL_BASEADDR, "Freelist 0x%08x base address from HW: 0x%02x%08x (expected value: 0x%02x%08x)", 5) \ -X( 24, RGXFW_GROUP_PM, RGXFW_SF_PM_ANALYSE_FL_GROW, "Analysis of FL grow: Pause=(%u,%u) Paused+Valid(%u,%u) PMStateBuffer=0x%x", 5) \ -X( 25, RGXFW_GROUP_PM, RGXFW_SF_PM_ATTEMPT_FL_GROW, "Attempt FL grow for FL: 0x%08x, new dev address: 0x%02x%08x, new page count: %u, new ready count: %u", 5) \ -X( 26, RGXFW_GROUP_PM, RGXFW_SF_PM_DEFER_FL_GROW, "Deferring FL grow for non-loaded FL: 0x%08x, new dev address: 0x%02x%08x, new page count: %u, new ready count: %u", 5) \ -X( 27, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED_ALBIORIX, "Is GEOM: %d, finished: %d (HWRTData = 0x%08x, MemCtx = 0x%08x)", 4) \ -X( 28, RGXFW_GROUP_PM, RGXFW_SF_PM_3D_TIMEOUT, "3D Timeout Now for FWCtx 0x%08.8x", 1) \ -X( 29, RGXFW_GROUP_PM, RGXFW_SF_PM_RECYCLE, "GEOM PM Recycle for FWCtx 0x%08.8x", 1) \ -X( 30, RGXFW_GROUP_PM, RGXFW_SF_PM_PRIMARY_CONFIG, "PM running primary config (Core %d)", 1) \ -X( 31, RGXFW_GROUP_PM, RGXFW_SF_PM_SECONDARY_CONFIG, "PM running secondary config (Core %d)", 1) \ -X( 32, RGXFW_GROUP_PM, RGXFW_SF_PM_TERTIARY_CONFIG, "PM running tertiary config (Core %d)", 1) \ -X( 33, RGXFW_GROUP_PM, RGXFW_SF_PM_QUATERNARY_CONFIG, "PM running quaternary config (Core %d)", 1) \ -\ -X( 1, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GLL_DYNAMIC_STATUS_DEPRECATED, "Global link list dynamic page count: vertex 0x%x, varying 0x%x, node 0x%x", 3) \ -X( 2, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GLL_STATIC_STATUS_DEPRECATED, "Global link list static page count: vertex 0x%x, varying 0x%x, node 0x%x", 3) \ -X( 3, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_WAIT_FOR_GROW_DEPRECATED, "RPM request failed. Waiting for freelist grow.", 0) \ -X( 4, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_ABORT_DEPRECATED, "RPM request failed. Aborting the current frame.", 0) \ -X( 5, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_WAIT_FOR_PENDING_GROW_DEPRECATED, "RPM waiting for pending grow on freelist 0x%08x", 1) \ -X( 6, RGXFW_GROUP_RPM, RGXFW_SF_RPM_REQUEST_HOST_GROW_DEPRECATED, "Request freelist grow [0x%08x] current pages %d, grow size %d", 3) \ -X( 7, RGXFW_GROUP_RPM, RGXFW_SF_RPM_FREELIST_LOAD_DEPRECATED, "Freelist load: SHF = 0x%08x, SHG = 0x%08x", 2) \ -X( 8, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_DEPRECATED, "SHF FPL register: 0x%08x.0x%08x", 2) \ -X( 9, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_DEPRECATED, "SHG FPL register: 0x%08x.0x%08x", 2) \ -X( 10, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_FREELIST_DEPRECATED, "Kernel requested RPM grow on freelist (type %d) at 0x%08x from current size %d to new size %d, RPM restart: %d (1=Yes)", 5) \ -X( 11, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_RESTART_DEPRECATED, "Restarting SHG", 0) \ -X( 12, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_ABORTED_DEPRECATED, "Grow failed, aborting the current frame.", 0) \ -X( 13, RGXFW_GROUP_RPM, RGXFW_SF_RPM_ABORT_COMPLETE_DEPRECATED, "RPM abort complete on HWFrameData [0x%08x].", 1) \ -X( 14, RGXFW_GROUP_RPM, RGXFW_SF_RPM_CLEANUP_NEEDS_ABORT_DEPRECATED, "RPM freelist cleanup [0x%08x] requires abort to proceed.", 1) \ -X( 15, RGXFW_GROUP_RPM, RGXFW_SF_RPM_RPM_PT_DEPRECATED, "RPM page table base register: 0x%08x.0x%08x", 2) \ -X( 16, RGXFW_GROUP_RPM, RGXFW_SF_RPM_OOM_ABORT_DEPRECATED, "Issuing RPM abort.", 0) \ -X( 17, RGXFW_GROUP_RPM, RGXFW_SF_RPM_OOM_TOGGLE_CHECK_FULL_DEPRECATED, "RPM OOM received but toggle bits indicate free pages available", 0) \ -X( 18, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_HW_TIMEOUT_DEPRECATED, "RPM hardware timeout. Unable to process OOM event.", 0) \ -X( 19, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_LOAD_DEPRECATED_DEPRECATED, "SHF FL (0x%08x) load, FPL: 0x%08x.0x%08x, roff: 0x%08x, woff: 0x%08x", 5) \ -X( 20, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_LOAD_DEPRECATED, "SHG FL (0x%08x) load, FPL: 0x%08x.0x%08x, roff: 0x%08x, woff: 0x%08x", 5) \ -X( 21, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_STORE_DEPRECATED, "SHF FL (0x%08x) store, roff: 0x%08x, woff: 0x%08x", 3) \ -X( 22, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_STORE_DEPRECATED, "SHG FL (0x%08x) store, roff: 0x%08x, woff: 0x%08x", 3) \ -\ -X( 1, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_FINISHED, "3D RTData 0x%08x finished on HW context %u", 2) \ -X( 2, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_READY, "3D RTData 0x%08x ready on HW context %u", 2) \ -X( 3, RGXFW_GROUP_RTD, RGXFW_SF_RTD_PB_SET_TO_DEPRECATED, "CONTEXT_PB_BASE set to 0x%x, FL different between TA/3D: local: %d, global: %d, mmu: %d", 4) \ -X( 4, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOADVFP_3D_DEPRECATED, "Loading VFP table 0x%08x%08x for 3D", 2) \ -X( 5, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOADVFP_TA_DEPRECATED, "Loading VFP table 0x%08x%08x for TA", 2) \ -X( 6, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_DEPRECATED, "Load Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: TotalPMPages = %d, FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 10) \ -X( 7, RGXFW_GROUP_RTD, RGXFW_SF_RTD_VHEAP_STORE, "Perform VHEAP table store", 0) \ -X( 8, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_MATCH_FOUND, "RTData 0x%08x: found match in Context=%d: Load=No, Store=No", 2) \ -X( 9, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_NULL_FOUND, "RTData 0x%08x: found NULL in Context=%d: Load=Yes, Store=No", 2) \ -X( 10, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_3D_FINISHED, "RTData 0x%08x: found state 3D finished (0x%08x) in Context=%d: Load=Yes, Store=Yes", 3) \ -X( 11, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_TA_FINISHED, "RTData 0x%08x: found state TA finished (0x%08x) in Context=%d: Load=Yes, Store=Yes", 3) \ -X( 12, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_STACK_POINTERS, "Loading stack-pointers for %d (0:MidTA,1:3D) on context %d, MLIST = 0x%08x, ALIST = 0x%08x%08x", 5) \ -X( 13, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_PB_DEPRECATED, "Store Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: TotalPMPages = %d, FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 10) \ -X( 14, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_FINISHED, "TA RTData 0x%08x finished on HW context %u", 2) \ -X( 15, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_LOADED, "TA RTData 0x%08x loaded on HW context %u", 2) \ -X( 16, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_PB_DEPRECATED2, "Store Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \ -X( 17, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_DEPRECATED2, "Load Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \ -X( 18, RGXFW_GROUP_RTD, RGXFW_SF_RTD_DEBUG_DEPRECATED, "Freelist 0x%x RESET!!!!!!!!", 1) \ -X( 19, RGXFW_GROUP_RTD, RGXFW_SF_RTD_DEBUG2_DEPRECATED, "Freelist 0x%x stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 5) \ -X( 20, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_DEPRECATED, "Request reconstruction of Freelist 0x%x type: %d (0:local,1:global,2:mmu) on HW context %u", 3) \ -X( 21, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_ACK_DEPRECATED, "Freelist reconstruction ACK from host (HWR state :%u)", 1) \ -X( 22, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_ACK_DEPRECATED2, "Freelist reconstruction completed", 0) \ -X( 23, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_LOADED_DEPRECATED, "TA RTData 0x%08x loaded on HW context %u HWRTDataNeedsLoading=%d", 3) \ -X( 24, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TE_RGNHDR_INFO, "TE Region headers base 0x%08x%08x (RGNHDR Init: %d)", 3) \ -X( 25, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_BUFFER_ADDRS_DEPRECATED, "TA Buffers: FWCtx 0x%08x, RT 0x%08x, RTData 0x%08x, VHeap 0x%08x%08x, TPC 0x%08x%08x (MemCtx 0x%08x)", 8) \ -X( 26, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_LOADED_DEPRECATED, "3D RTData 0x%08x loaded on HW context %u", 2) \ -X( 27, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS_DEPRECATED, "3D Buffers: FWCtx 0x%08x, RT 0x%08x, RTData 0x%08x (MemCtx 0x%08x)", 4) \ -X( 28, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RESTART_AFTER_PR_EXECUTED, "Restarting TA after partial render, HWRTData0State=0x%x, HWRTData1State=0x%x", 2) \ -X( 29, RGXFW_GROUP_RTD, RGXFW_SF_RTD_PB_SET_TO, "CONTEXT_PB_BASE set to 0x%x, FL different between TA/3D: local: %d, global: %d", 3) \ -X( 30, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_FL, "Store Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \ -X( 31, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL, "Load Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \ -X( 32, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS_DEPRECATED2, "3D Buffers: FWCtx 0x%08x, parent RT 0x%08x, RTData 0x%08x on ctx %d, (MemCtx 0x%08x)", 5) \ -X( 33, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_BUFFER_ADDRS, "TA Buffers: FWCtx 0x%08x, RTData 0x%08x, VHeap 0x%08x%08x, TPC 0x%08x%08x (MemCtx 0x%08x)", 7) \ -X( 34, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS, "3D Buffers: FWCtx 0x%08x, RTData 0x%08x on ctx %d, (MemCtx 0x%08x)", 4) \ -X( 35, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_V2, "Load Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u)", 6) \ -X( 36, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILLED_TA, "TA RTData 0x%08x marked as killed.", 1) \ -X( 37, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILLED_3D, "3D RTData 0x%08x marked as killed.", 1) \ -X( 38, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILL_TA_AFTER_RESTART, "RTData 0x%08x will be killed after TA restart.", 1) \ -X( 39, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RENDERSTATE_RESET, "RTData 0x%08x Render State Buffer 0x%02x%08x will be reset.", 3) \ -X( 40, RGXFW_GROUP_RTD, RGXFW_SF_RTD_GEOM_RENDERSTATE, "GEOM RTData 0x%08x using Render State Buffer 0x%02x%08x.", 3) \ -X( 41, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FRAG_RENDERSTATE, "FRAG RTData 0x%08x using Render State Buffer 0x%02x%08x.", 3) \ -\ -X( 1, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZLOAD_DEPRECATED, "Force Z-Load for partial render", 0) \ -X( 2, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSTORE_DEPRECATED, "Force Z-Store for partial render", 0) \ -X( 3, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_LOCAL_DEPRECATED, "3D MemFree: Local FL 0x%08x", 1) \ -X( 4, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_MMU_DEPRECATED, "3D MemFree: MMU FL 0x%08x", 1) \ -X( 5, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_GLOBAL_DEPRECATED, "3D MemFree: Global FL 0x%08x", 1) \ -X( 6, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_DEPRECATED, "OOM TA/3D PR Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x, HardwareSync Fence [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 6) \ -X( 7, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_UN_FL, "OOM TA_cmd=0x%08x, U-FL 0x%08x, N-FL 0x%08x", 3) \ -X( 8, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_UN_MMU_FL_DEPRECATED, "OOM TA_cmd=0x%08x, OOM MMU:%d, U-FL 0x%08x, N-FL 0x%08x, MMU-FL 0x%08x", 5) \ -X( 9, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_AVOIDED_DEPRECATED, "Partial render avoided", 0) \ -X( 10, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_DISCARDED_DEPRECATED, "Partial render discarded", 0) \ -X( 11, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_FINISHED, "Partial Render finished", 0) \ -X( 12, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_3DBG_DEPRECATED, "SPM Owner = 3D-BG", 0) \ -X( 13, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_3DIRQ_DEPRECATED, "SPM Owner = 3D-IRQ", 0) \ -X( 14, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_NONE_DEPRECATED, "SPM Owner = NONE", 0) \ -X( 15, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_TABG_DEPRECATED, "SPM Owner = TA-BG", 0) \ -X( 16, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_TAIRQ_DEPRECATED, "SPM Owner = TA-IRQ", 0) \ -X( 17, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSTORE_ADDRESS, "ZStore address 0x%08x%08x", 2) \ -X( 18, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SSTORE_ADDRESS, "SStore address 0x%08x%08x", 2) \ -X( 19, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZLOAD_ADDRESS, "ZLoad address 0x%08x%08x", 2) \ -X( 20, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SLOAD_ADDRESS, "SLoad address 0x%08x%08x", 2) \ -X( 21, RGXFW_GROUP_SPM, RGXFW_SF_SPM_NO_DEFERRED_ZSBUFFER_DEPRECATED, "No deferred ZS Buffer provided", 0) \ -X( 22, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_POPULATED, "ZS Buffer successfully populated (ID=0x%08x)", 1) \ -X( 23, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_POP_UNNEEDED_DEPRECATED, "No need to populate ZS Buffer (ID=0x%08x)", 1) \ -X( 24, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNPOPULATED, "ZS Buffer successfully unpopulated (ID=0x%08x)", 1) \ -X( 25, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNPOP_UNNEEDED_DEPRECATED, "No need to unpopulate ZS Buffer (ID=0x%08x)", 1) \ -X( 26, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_DEPRECATED, "Send ZS-Buffer backing request to host (ID=0x%08x)", 1) \ -X( 27, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNBACKING_REQUEST_DEPRECATED, "Send ZS-Buffer unbacking request to host (ID=0x%08x)", 1) \ -X( 28, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_PENDING_DEPRECATED, "Don't send ZS-Buffer backing request. Previous request still pending (ID=0x%08x)", 1) \ -X( 29, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNBACKING_REQUEST_PENDING_DEPRECATED, "Don't send ZS-Buffer unbacking request. Previous request still pending (ID=0x%08x)", 1) \ -X( 30, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZBUFFER_NOT_READY_DEPRECATED, "Partial Render waiting for ZBuffer to be backed (ID=0x%08x)", 1) \ -X( 31, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SBUFFER_NOT_READY_DEPRECATED, "Partial Render waiting for SBuffer to be backed (ID=0x%08x)", 1) \ -X( 32, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_NONE, "SPM State = none", 0) \ -X( 33, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_BLOCKED, "SPM State = PR blocked", 0) \ -X( 34, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_GROW, "SPM State = wait for grow", 0) \ -X( 35, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_HW, "SPM State = wait for HW", 0) \ -X( 36, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_RUNNING, "SPM State = PR running", 0) \ -X( 37, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_AVOIDED, "SPM State = PR avoided", 0) \ -X( 38, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_EXECUTED, "SPM State = PR executed", 0) \ -X( 39, RGXFW_GROUP_SPM, RGXFW_SF_SPM_FREELIST_MATCH, "3DMemFree matches freelist 0x%08x (FL type = %u)", 2) \ -X( 40, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_FLAG_SET, "Raise the 3DMemFreeDedected flag", 0) \ -X( 41, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_PENDING_GROW, "Wait for pending grow on Freelist 0x%08x", 1) \ -X( 42, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_FAILED, "ZS Buffer failed to be populated (ID=0x%08x)", 1) \ -X( 43, RGXFW_GROUP_SPM, RGXFW_SF_SPM_FL_GROW_DEBUG, "Grow update inconsistency: FL addr: 0x%02x%08x, curr pages: %u, ready: %u, new: %u", 5) \ -X( 44, RGXFW_GROUP_SPM, RGXFW_SF_SPM_RESUMED_TA_WITH_SP, "OOM: Resumed TA with ready pages, FL addr: 0x%02x%08x, current pages: %u, SP : %u", 4) \ -X( 45, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ACK_GROW_UPDATE_DEPRECATED, "Received grow update, FL addr: 0x%02x%08x, current pages: %u, ready pages: %u, threshold: %u", 5) \ -X( 46, RGXFW_GROUP_SPM, RGXFW_SF_SPM_NO_DEFERRED_PRBUFFER, "No deferred partial render FW (Type=%d) Buffer provided", 1) \ -X( 47, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_POP_UNNEEDED, "No need to populate PR Buffer (ID=0x%08x)", 1) \ -X( 48, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNPOP_UNNEEDED, "No need to unpopulate PR Buffer (ID=0x%08x)", 1) \ -X( 49, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_BACKING_REQUEST, "Send PR Buffer backing request to host (ID=0x%08x)", 1) \ -X( 50, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNBACKING_REQUEST, "Send PR Buffer unbacking request to host (ID=0x%08x)", 1) \ -X( 51, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_BACKING_REQUEST_PENDING, "Don't send PR Buffer backing request. Previous request still pending (ID=0x%08x)", 1) \ -X( 52, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNBACKING_REQUEST_PENDING, "Don't send PR Buffer unbacking request. Previous request still pending (ID=0x%08x)", 1) \ -X( 53, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_NOT_READY, "Partial Render waiting for Buffer %d type to be backed (ID=0x%08x)", 2) \ -X( 54, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ACK_GROW_UPDATE, "Received grow update, FL addr: 0x%02x%08x, new pages: %u, ready pages: %u", 4) \ -X( 66, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD, "OOM TA/3D PR Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \ -X( 67, RGXFW_GROUP_SPM, RGXFW_SF_SPM_RESUMED_TA, "OOM: Resumed TA with ready pages, FL addr: 0x%02x%08x, current pages: %u", 3) \ -X( 68, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PR_DEADLOCK_UNBLOCKED, "OOM TA/3D PR deadlock unblocked reordering DM%d runlist head from Context 0x%08x to 0x%08x", 3) \ -X( 69, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_FORCEFREE, "SPM State = PR force free", 0) \ -\ -X( 1, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK_DEPRECATED, "Check Pow state DM%d int: 0x%x, ext: 0x%x, pow flags: 0x%x", 4) \ -X( 2, RGXFW_GROUP_POW, RGXFW_SF_POW_GPU_IDLE, "GPU idle (might be powered down). Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \ -X( 3, RGXFW_GROUP_POW, RGXFW_SF_POW_OSREQ_DEPRECATED, "OS requested pow off (forced = %d), DM%d, pow flags: 0x%x", 3) \ -X( 4, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_DEPRECATED, "Initiate powoff query. Inactive DMs: %d %d %d %d", 4) \ -X( 5, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECKOFF_DEPRECATED, "Any RD-DM pending? %d, Any RD-DM Active? %d", 2) \ -X( 6, RGXFW_GROUP_POW, RGXFW_SF_POW_GPU_OFF, "GPU ready to be powered down. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \ -X( 7, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ, "HW Request On(1)/Off(0): %d, Units: 0x%08.8x", 2) \ -X( 8, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE_REQ, "Request to change num of dusts to %d (Power flags=%d)", 2) \ -X( 9, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE, "Changing number of dusts from %d to %d", 2) \ -X( 11, RGXFW_GROUP_POW, RGXFW_SF_POW_SIDEKICK_INIT_DEPRECATED, "Sidekick init", 0) \ -X( 12, RGXFW_GROUP_POW, RGXFW_SF_POW_RD_INIT_DEPRECATED, "Rascal+Dusts init (# dusts mask: 0x%x)", 1) \ -X( 13, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_RD, "Initiate powoff query for RD-DMs.", 0) \ -X( 14, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_TLA, "Initiate powoff query for TLA-DM.", 0) \ -X( 15, RGXFW_GROUP_POW, RGXFW_SF_POW_REQUESTEDOFF_RD, "Any RD-DM pending? %d, Any RD-DM Active? %d", 2) \ -X( 16, RGXFW_GROUP_POW, RGXFW_SF_POW_REQUESTEDOFF_TLA, "TLA-DM pending? %d, TLA-DM Active? %d", 2) \ -X( 17, RGXFW_GROUP_POW, RGXFW_SF_POW_BRN37270_DEPRECATED, "Request power up due to BRN37270. Pow stat int: 0x%x", 1) \ -X( 18, RGXFW_GROUP_POW, RGXFW_SF_POW_REQ_CANCEL, "Cancel power off request int: 0x%x, ext: 0x%x, pow flags: 0x%x", 3) \ -X( 19, RGXFW_GROUP_POW, RGXFW_SF_POW_FORCED_IDLE, "OS requested forced IDLE, pow flags: 0x%x", 1) \ -X( 20, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_FORCED_IDLE, "OS cancelled forced IDLE, pow flags: 0x%x", 1) \ -X( 21, RGXFW_GROUP_POW, RGXFW_SF_POW_IDLE_TIMER, "Idle timer start. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \ -X( 22, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_IDLE_TIMER, "Cancel idle timer. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \ -X( 23, RGXFW_GROUP_POW, RGXFW_SF_POW_APM_LATENCY_CHANGE, "Active PM latency set to %dms. Core clock: %d Hz", 2) \ -X( 24, RGXFW_GROUP_POW, RGXFW_SF_POW_CDM_CLUSTERS, "Compute cluster mask change to 0x%x, %d dusts powered.", 2) \ -X( 25, RGXFW_GROUP_POW, RGXFW_SF_POW_NULL_CMD_INIOFF_RD, "Null command executed, repeating initiate powoff query for RD-DMs.", 0) \ -X( 26, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_ENERGY, "Power monitor: Estimate of dynamic energy %u", 1) \ -X( 27, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK_DEPRECATED2, "Check Pow state: Int: 0x%x, Ext: 0x%x, Pow flags: 0x%x", 3) \ -X( 28, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_NEW_DEADLINE, "Proactive DVFS: New deadline, time = 0x%08x%08x", 2) \ -X( 29, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_NEW_WORKLOAD, "Proactive DVFS: New workload, cycles = 0x%08x%08x", 2) \ -X( 30, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_CALCULATE, "Proactive DVFS: Proactive frequency calculated = %u", 1) \ -X( 31, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UTILISATION, "Proactive DVFS: Reactive utilisation = %u percent", 1) \ -X( 32, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_REACT, "Proactive DVFS: Reactive frequency calculated = %u.%u", 2) \ -X( 33, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_SEND_DEPRECATED, "Proactive DVFS: OPP Point Sent = 0x%x", 1) \ -X( 34, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_DEADLINE_REMOVED, "Proactive DVFS: Deadline removed = 0x%08x%08x", 2) \ -X( 35, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_WORKLOAD_REMOVED, "Proactive DVFS: Workload removed = 0x%08x%08x", 2) \ -X( 36, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_THROTTLE, "Proactive DVFS: Throttle to a maximum = 0x%x", 1) \ -X( 37, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_FAILURE, "Proactive DVFS: Failed to pass OPP point via GPIO.", 0) \ -X( 38, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_INVALID_NODE_DEPRECATED, "Proactive DVFS: Invalid node passed to function.", 0) \ -X( 39, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GUEST_BAD_ACCESS_DEPRECATED, "Proactive DVFS: Guest OS attempted to do a privileged action. OSid = %u", 1) \ -X( 40, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UNPROFILED_STARTED, "Proactive DVFS: Unprofiled work started. Total unprofiled work present: %u", 1) \ -X( 41, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UNPROFILED_FINISHED, "Proactive DVFS: Unprofiled work finished. Total unprofiled work present: %u", 1) \ -X( 42, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_DISABLED, "Proactive DVFS: Disabled: Not enabled by host.", 0) \ -X( 43, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ_RESULT, "HW Request Completed(1)/Aborted(0): %d, Ticks: %d", 2) \ -X( 44, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE_FIX_59042_DEPRECATED, "Allowed number of dusts is %d due to BRN59042.", 1) \ -X( 45, RGXFW_GROUP_POW, RGXFW_SF_POW_HOST_TIMEOUT_NOTIFICATION, "Host timed out while waiting for a forced idle state. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \ -X( 46, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK, "Check Pow state: Int: 0x%x, Ext: 0x%x, Pow flags: 0x%x, Fence Counters: Check: %u - Update: %u", 5) \ -X( 47, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_SEND, "Proactive DVFS: OPP Point Sent = 0x%x, Success = 0x%x", 2) \ -X( 48, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_TO_IDLE, "Proactive DVFS: GPU transitioned to idle", 0) \ -X( 49, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_TO_ACTIVE, "Proactive DVFS: GPU transitioned to active", 0) \ -X( 50, RGXFW_GROUP_POW, RGXFW_SF_POW_POWDUMP_BUFFER_SIZE, "Power counter dumping: Data truncated writing register %u. Buffer too small.", 1) \ -X( 51, RGXFW_GROUP_POW, RGXFW_SF_POW_POWCTRL_ABORT, "Power controller returned ABORT for last request so retrying.", 0) \ -X( 52, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_POWER_REQUEST_DEPRECATED, "Discarding invalid power request: type 0x%x, DM %u", 2) \ -X( 53, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_FORCED_IDLE_NOT_IDLE, "Detected attempt to cancel forced idle while not forced idle (pow state 0x%x, pow flags 0x%x)", 2) \ -X( 54, RGXFW_GROUP_POW, RGXFW_SF_POW_FORCED_POW_OFF_NOT_IDLE, "Detected attempt to force power off while not forced idle (pow state 0x%x, pow flags 0x%x)", 2) \ -X( 55, RGXFW_GROUP_POW, RGXFW_SF_POW_NUMDUST_CHANGE_NOT_IDLE, "Detected attempt to change dust count while not forced idle (pow state 0x%x)", 1) \ -X( 56, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_RESULT, "Power monitor: Type = %d (0 = power, 1 = energy), Estimate result = 0x%08x%08x", 3) \ -X( 57, RGXFW_GROUP_POW, RGXFW_SF_POW_MINMAX_CONFLICT, "Conflicting clock frequency range: OPP min = %u, max = %u", 2) \ -X( 58, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_FLOOR, "Proactive DVFS: Set floor to a minimum = 0x%x", 1) \ -X( 59, RGXFW_GROUP_POW, RGXFW_SF_POW_OSREQ, "OS requested pow off (forced = %d), pow flags: 0x%x", 2) \ -X( 60, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_POWER_REQUEST, "Discarding invalid power request: type 0x%x", 1) \ -X( 61, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_STATE_CHANGE_REQ, "Request to change SPU power state mask from 0x%x to 0x%x. Pow flags: 0x%x", 3) \ -X( 62, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_STATE_CHANGE, "Changing SPU power state mask from 0x%x to 0x%x", 2) \ -X( 63, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_CHANGE_NOT_IDLE, "Detected attempt to change SPU power state mask while not forced idle (pow state 0x%x)", 1) \ -X( 64, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_SPU_POWER_MASK, "Invalid SPU power mask 0x%x! Changing to 1", 1) \ -X( 65, RGXFW_GROUP_POW, RGXFW_SF_POW_CLKDIV_UPDATE, "Proactive DVFS: Send OPP %u with clock divider value %u", 2) \ -X( 66, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_PERF_MODE, "PPA block started in perf validation mode.", 0) \ -X( 67, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_RESET, "Reset PPA block state %u (1=reset, 0=recalculate).", 1) \ -X( 68, RGXFW_GROUP_POW, RGXFW_SF_POW_POWCTRL_ABORT_WITH_CORE, "Power controller returned ABORT for Core-%d last request so retrying.", 1) \ -X( 69, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ64BIT, "HW Request On(1)/Off(0): %d, Units: 0x%08x%08x", 3) \ -X( 70, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_RAC_POW_STATE_CHANGE_REQ, "Request to change SPU power state mask from 0x%x to 0x%x and RAC from 0x%x to 0x%x. Pow flags: 0x%x", 5) \ -X( 71, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_RAC_POW_STATE_CHANGE, "Changing SPU power state mask from 0x%x to 0x%x and RAC from 0x%x to 0x%x", 4) \ -X( 72, RGXFW_GROUP_POW, RGXFW_SF_POW_REQUESTEDOFF_RAC, "RAC pending? %d, RAC Active? %d", 2) \ -X( 73, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_RAC, "Initiate powoff query for RAC.", 0) \ -\ -X( 1, RGXFW_GROUP_HWR, RGXFW_SF_HWR_LOCKUP_DEPRECATED, "Lockup detected on DM%d, FWCtx: 0x%08.8x", 2) \ -X( 2, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_FW_DEPRECATED, "Reset fw state for DM%d, FWCtx: 0x%08.8x, MemCtx: 0x%08.8x", 3) \ -X( 3, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED, "Reset HW", 0) \ -X( 4, RGXFW_GROUP_HWR, RGXFW_SF_HWR_TERMINATED_DEPRECATED, "Lockup recovered.", 0) \ -X( 5, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DEPRECATED, "Lock-up DM%d FWCtx: 0x%08.8x", 2) \ -X( 6, RGXFW_GROUP_HWR, RGXFW_SF_HWR_LOCKUP_DETECTED_DEPRECATED, "Lockup detected: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \ -X( 7, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EARLY_FAULT_DETECTION_DEPRECATED, "Early fault detection: GLB(%d->%d), PER-DM(0x%08x)", 3) \ -X( 8, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_LOCKUP_DEPRECATED, "Hold scheduling due lockup: GLB(%d), PER-DM(0x%08x->0x%08x)", 3) \ -X( 9, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FALSE_LOCKUP_DEPRECATED, "False lockup detected: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \ -X( 10, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BRN37729_DEPRECATED, "BRN37729: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \ -X( 11, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FREELISTS_RECONSTRUCTED_DEPRECATED, "Freelists reconstructed: GLB(%d->%d), PER-DM(0x%08x)", 3) \ -X( 12, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RECONSTRUCTING_FREELISTS_DEPRECATED, "Reconstructing freelists: %u (0-No, 1-Yes): GLB(%d->%d), PER-DM(0x%08x)", 4) \ -X( 13, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FAILED_HW_POLL, "HW poll %u (0-Unset 1-Set) failed (reg:0x%08x val:0x%08x)", 3) \ -X( 14, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_DISCARDED_DEPRECATED, "Discarded cmd on DM%u FWCtx=0x%08x", 2) \ -X( 15, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_DISCARDED, "Discarded cmd on DM%u (reason=%u) HWRTData=0x%08x (st: %d), FWCtx 0x%08x @ %d", 6) \ -X( 16, RGXFW_GROUP_HWR, RGXFW_SF_HWR_PM_FENCE_DEPRECATED, "PM fence WA could not be applied, Valid TA Setup: %d, RD powered off: %d", 2) \ -X( 17, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_SNAPSHOT, "FL snapshot RTD 0x%08.8x - local (0x%08.8x): %d, global (0x%08.8x): %d", 5) \ -X( 18, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_CHECK, "FL check RTD 0x%08.8x, discard: %d - local (0x%08.8x): s%d?=c%d, global (0x%08.8x): s%d?=c%d", 8) \ -X( 19, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_DEPRECATED, "FL reconstruction 0x%08.8x c%d", 2) \ -X( 20, RGXFW_GROUP_HWR, RGXFW_SF_HWR_3D_CHECK, "3D check: missing TA FWCtx 0x%08.8x @ %d, RTD 0x%08x.", 3) \ -X( 21, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED2, "Reset HW (mmu:%d, extmem: %d)", 2) \ -X( 22, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ZERO_TA_CACHES, "Zero TA caches for FWCtx: 0x%08.8x (TPC addr: 0x%08x%08x, size: %d bytes)", 4) \ -X( 23, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FREELISTS_RECONSTRUCTED_DEPRECATED2, "Recovery DM%u: Freelists reconstructed. New R-Flags=0x%08x", 2) \ -X( 24, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SKIPPED_CMD, "Recovery DM%u: FWCtx 0x%08x skipped to command @ %u. PR=%u. New R-Flags=0x%08x", 5) \ -X( 25, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_RECOVERED, "Recovery DM%u: DM fully recovered", 1) \ -X( 26, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_LOCKUP, "DM%u: Hold scheduling due to R-Flag = 0x%08x", 2) \ -X( 27, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_RECONSTRUCTION, "Analysis: Need freelist reconstruction", 0) \ -X( 28, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_SKIP, "Analysis DM%u: Lockup FWCtx: 0x%08.8x. Need to skip to next command", 2) \ -X( 29, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_SKIP_OOM_TA, "Analysis DM%u: Lockup while TA is OOM FWCtx: 0x%08.8x. Need to skip to next command", 2) \ -X( 30, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_PR_CLEANUP, "Analysis DM%u: Lockup while partial render FWCtx: 0x%08.8x. Need PR cleanup", 2) \ -X( 31, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DEPRECATED2, "GPU has locked up", 0) \ -X( 32, RGXFW_GROUP_HWR, RGXFW_SF_HWR_READY, "DM%u ready for HWR", 1) \ -X( 33, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_UPDATE_RECOVERY, "Recovery DM%u: Updated Recovery counter. New R-Flags=0x%08x", 2) \ -X( 34, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BRN37729_DEPRECATED2, "Analysis: BRN37729 detected, reset TA and re-kicked 0x%08x)", 1) \ -X( 35, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_TIMED_OUT, "DM%u timed out", 1) \ -X( 36, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EVENT_STATUS_REG, "RGX_CR_EVENT_STATUS=0x%08x", 1) \ -X( 37, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_FALSE_LOCKUP, "DM%u lockup falsely detected, R-Flags=0x%08x", 2) \ -X( 38, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_OUTOFTIME, "GPU has overrun its deadline", 0) \ -X( 39, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_POLLFAILURE, "GPU has failed a poll", 0) \ -X( 40, RGXFW_GROUP_HWR, RGXFW_SF_HWR_PERF_PHASE_REG, "RGX DM%u phase count=0x%08x", 2) \ -X( 41, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED3, "Reset HW (loop:%d, poll failures: 0x%08x)", 2) \ -X( 42, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_FAULT_EVENT, "MMU fault event: 0x%08x", 1) \ -X( 43, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BIF1_FAULT, "BIF1 page fault detected (Bank1 MMU Status: 0x%08x)", 1) \ -X( 44, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK_TRUE_DEPRECATED, "Fast CRC Failed. Proceeding to full register checking (DM: %u).", 1) \ -X( 45, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_META_FAULT, "Meta MMU page fault detected (Meta MMU Status: 0x%08x%08x)", 2) \ -X( 46, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK_DEPRECATED, "Fast CRC Check result for DM%u is HWRNeeded=%u", 2) \ -X( 47, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FULL_CHECK_DEPRECATED, "Full Signature Check result for DM%u is HWRNeeded=%u", 2) \ -X( 48, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FINAL_RESULT, "Final result for DM%u is HWRNeeded=%u with HWRChecksToGo=%u", 3) \ -X( 49, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_CHECK_DEPRECATED, "USC Slots result for DM%u is HWRNeeded=%u USCSlotsUsedByDM=%d", 3) \ -X( 50, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DEADLINE_CHECK_DEPRECATED, "Deadline counter for DM%u is HWRDeadline=%u", 2) \ -X( 51, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_FREELIST_DEPRECATED, "Holding Scheduling on OSid %u due to pending freelist reconstruction", 1) \ -X( 52, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_REQUEST, "Requesting reconstruction for freelist 0x%x (ID=%d)", 2) \ -X( 53, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_PASSED, "Reconstruction of freelist ID=%d complete", 1) \ -X( 54, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global,2:mmu) on HW context %u", 4) \ -X( 55, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_FAILED, "Reconstruction of freelist ID=%d failed", 1) \ -X( 56, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESTRICTING_PDS_TASKS, "Restricting PDS Tasks to help other stalling DMs (RunningMask=0x%02x, StallingMask=0x%02x, PDS_CTRL=0x%08x%08x)", 4) \ -X( 57, RGXFW_GROUP_HWR, RGXFW_SF_HWR_UNRESTRICTING_PDS_TASKS, "Unrestricting PDS Tasks again (RunningMask=0x%02x, StallingMask=0x%02x, PDS_CTRL=0x%08x%08x)", 4) \ -X( 58, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_USED, "USC slots: %u used by DM%u", 2) \ -X( 59, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_EMPTY, "USC slots: %u empty", 1) \ -X( 60, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HCS_FIRE, "HCS DM%d's Context Switch failed to meet deadline. Current time: 0x%08x%08x, deadline: 0x%08x%08x", 5) \ -X( 61, RGXFW_GROUP_HWR, RGXFW_SF_HWR_START_HW_RESET, "Begin hardware reset (HWR Counter=%d)", 1) \ -X( 62, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FINISH_HW_RESET, "Finished hardware reset (HWR Counter=%d)", 1) \ -X( 63, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_FREELIST, "Holding Scheduling on DM %u for OSid %u due to pending freelist reconstruction", 2) \ -X( 64, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_UMQ_READ_OFFSET, "User Mode Queue ROff reset: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u becomes StreamStartOffset = %u)", 5) \ -X( 65, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED2, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global) on HW context %u", 4) \ -X( 66, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MIPS_FAULT, "Mips page fault detected (BadVAddr: 0x%08x, EntryLo0: 0x%08x, EntryLo1: 0x%08x)", 3) \ -X( 67, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ANOTHER_CHANCE, "At least one other DM is running okay so DM%u will get another chance", 1) \ -X( 68, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_FW, "Reconstructing in FW, FL: 0x%x (ID=%d)", 2) \ -X( 69, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ZERO_RTC, "Zero RTC for FWCtx: 0x%08.8x (RTC addr: 0x%08x%08x, size: %d bytes)", 4) \ -X( 70, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED3, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global) phase: %d (0:TA, 1:3D) on HW context %u", 5) \ -X( 71, RGXFW_GROUP_HWR, RGXFW_SF_HWR_START_LONG_HW_POLL, "Start long HW poll %u (0-Unset 1-Set) for (reg:0x%08x val:0x%08x)", 3) \ -X( 72, RGXFW_GROUP_HWR, RGXFW_SF_HWR_END_LONG_HW_POLL, "End long HW poll (result=%d)", 1) \ -X( 73, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DEADLINE_CHECK, "DM%u has taken %d ticks and deadline is %d ticks", 3) \ -X( 74, RGXFW_GROUP_HWR, RGXFW_SF_HWR_WATCHDOG_CHECK_DEPRECATED, "USC Watchdog result for DM%u is HWRNeeded=%u Status=%u USCs={0x%x} with HWRChecksToGo=%u", 5) \ -X( 75, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED, "Reconstruction needed for freelist 0x%x (ID=%d) OSid: %d type: %d (0:local,1:global) phase: %d (0:TA, 1:3D) on HW context %u", 6) \ -X( 76, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP, "GPU-%u has locked up", 1) \ -X( 77, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DM, "DM%u has locked up", 1) \ -X( 78, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_EVENT_STATUS_REG, "Core %d RGX_CR_EVENT_STATUS=0x%08x", 2) \ -X( 79, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MULTICORE_EVENT_STATUS_REG, "RGX_CR_MULTICORE_EVENT_STATUS%u=0x%08x", 2) \ -X( 80, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_BIF0_FAULT, "BIF0 page fault detected (Core %d MMU Status: 0x%08x%08x Req Status: 0x%08x%08x)", 5) \ -X( 81, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_MMU_FAULT_S7, "MMU page fault detected (Core %d MMU Status: 0x%08x%08x)", 3) \ -X( 82, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_MMU_FAULT, "MMU page fault detected (Core %d MMU Status: 0x%08x%08x 0x%08x)", 4) \ -X( 83, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW, "Reset HW (core:%d of %d, loop:%d, poll failures: 0x%08x)", 4) \ -X( 84, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK, "Fast CRC Check result for Core%u, DM%u is HWRNeeded=%u", 3) \ -X( 85, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FULL_CHECK, "Full Signature Check result for Core%u, DM%u is HWRNeeded=%u", 3) \ -X( 86, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_CHECK, "USC Slots result for Core%u, DM%u is HWRNeeded=%u USCSlotsUsedByDM=%d", 4) \ -X( 87, RGXFW_GROUP_HWR, RGXFW_SF_HWR_WATCHDOG_CHECK, "USC Watchdog result for Core%u DM%u is HWRNeeded=%u Status=%u USCs={0x%x} with HWRChecksToGo=%u", 6) \ -X( 88, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_RISCV_FAULT, "RISC-V MMU page fault detected (FWCORE MMU Status 0x%08x Req Status 0x%08x%08x)", 3) \ -X( 89, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_TEXAS1_PFS_DEPRECATED, "TEXAS1_PFS poll failed on core %d with value 0x%08x", 2) \ -X( 90, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_PFS, "BIF_PFS poll failed on core %d with value 0x%08x", 2) \ -X( 91, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SET_ABORT_PM_STATUS, "MMU_ABORT_PM_STATUS set poll failed on core %d with value 0x%08x", 2) \ -X( 92, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_UNSET_ABORT_PM_STATUS, "MMU_ABORT_PM_STATUS unset poll failed on core %d with value 0x%08x", 2) \ -X( 93, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SLC_INVAL, "MMU_CTRL_INVAL poll (all but fw) failed on core %d with value 0x%08x", 2) \ -X( 94, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SLCMMU_INVAL, "MMU_CTRL_INVAL poll (all) failed on core %d with value 0x%08x", 2) \ -X( 95, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_TEXAS_PFS, "TEXAS%d_PFS poll failed on core %d with value 0x%08x", 3) \ -X( 96, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EXTRA_CHECK, "Extra Registers Check result for Core%u, DM%u is HWRNeeded=%u", 3) \ -X( 97, RGXFW_GROUP_HWR, RGXFW_SF_HWR_WRITE_TO_GPU_READONLY_ADDR, "FW attempted to write to read-only GPU address 0x%08x", 1) \ -\ -X( 1, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CFGBLK, "Block 0x%x mapped to Config Idx %u", 2) \ -X( 2, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_OMTBLK, "Block 0x%x omitted from event - not enabled in HW", 1) \ -X( 3, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INCBLK, "Block 0x%x included in event - enabled in HW", 1) \ -X( 4, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_SELREG, "Select register state hi_0x%x lo_0x%x", 2) \ -X( 5, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CSBHDR, "Counter stream block header word 0x%x", 1) \ -X( 6, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTROFF, "Counter register offset 0x%x", 1) \ -X( 7, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CFGSKP, "Block 0x%x config unset, skipping", 1) \ -X( 8, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INDBLK, "Accessing Indirect block 0x%x", 1) \ -X( 9, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DIRBLK, "Accessing Direct block 0x%x", 1) \ -X( 10, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CNTPRG, "Programmed counter select register at offset 0x%x", 1) \ -X( 11, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKPRG, "Block register offset 0x%x and value 0x%x", 2) \ -X( 12, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKCG, "Reading config block from driver 0x%x", 1) \ -X( 13, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKRG, "Reading block range 0x%x to 0x%x", 2) \ -X( 14, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKREC, "Recording block 0x%x config from driver", 1) \ -X( 15, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKED, "Finished reading config block from driver", 0) \ -X( 16, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CUSTOM_COUNTER, "Custom Counter offset: 0x%x value: 0x%x", 2) \ -X( 17, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_SELECT_CNTR, "Select counter n:%u ID:0x%x", 2) \ -X( 18, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_SELECT_PACK, "The counter ID 0x%x is not allowed. The package [b:%u, n:%u] will be discarded", 3) \ -X( 19, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHANGE_FILTER_STATUS_CUSTOM, "Custom Counters filter status %d", 1) \ -X( 20, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_WRONG_BLOCK, "The Custom block %d is not allowed. Use only blocks lower than %d. The package will be discarded", 2) \ -X( 21, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_TOO_MANY_ID, "The package will be discarded because it contains %d counters IDs while the upper limit is %d", 2) \ -X( 22, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHECK_FILTER, "Check Filter 0x%x is 0x%x ?", 2) \ -X( 23, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_RESET_CUSTOM_BLOCK, "The custom block %u is reset", 1) \ -X( 24, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INVALID_CMD_DEPRECATED, "Encountered an invalid command (%d)", 1) \ -X( 25, RGXFW_GROUP_HWP, RGXFW_SF_HWP_WAITING_FOR_QUEUE_DEPRECATED, "HWPerf Queue is full, we will have to wait for space! (Roff = %u, Woff = %u)", 2) \ -X( 26, RGXFW_GROUP_HWP, RGXFW_SF_HWP_WAITING_FOR_QUEUE_FENCE_DEPRECATED, "HWPerf Queue is fencing, we are waiting for Roff = %d (Roff = %u, Woff = %u)", 3) \ -X( 27, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CUSTOM_BLOCK, "Custom Counter block: %d", 1) \ -X( 28, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKENA, "Block 0x%x ENABLED", 1) \ -X( 29, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKDIS, "Block 0x%x DISABLED", 1) \ -X( 30, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INDBLK_INSTANCE, "Accessing Indirect block 0x%x, instance %u", 2) \ -X( 31, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTRVAL, "Counter register 0x%x, Value 0x%x", 2) \ -X( 32, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHANGE_FILTER_STATUS, "Counters filter status %d", 1) \ -X( 33, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTLBLK, "Block 0x%x mapped to Ctl Idx %u", 2) \ -X( 34, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_WORKEST_EN, "Block(s) in use for workload estimation.", 0) \ -X( 35, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CYCCTR, "GPU %u Cycle counter 0x%x, Value 0x%x", 3) \ -X( 36, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CYCMAX, "GPU Mask 0x%x Cycle counter 0x%x, Value 0x%x", 3) \ -X( 37, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_IGNORE_BLOCKS, "Blocks IGNORED for GPU %u", 1) \ -\ -X( 1, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_REQUEST_DEPRECATED, "Transfer 0x%02x request: 0x%02x%08x -> 0x%08x, size %u", 5) \ -X( 2, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_COMPLETE, "Transfer of type 0x%02x expected on channel %u, 0x%02x found, status %u", 4) \ -X( 3, RGXFW_GROUP_DMA, RGXFW_SF_DMA_INT_REG, "DMA Interrupt register 0x%08x", 1) \ -X( 4, RGXFW_GROUP_DMA, RGXFW_SF_DMA_WAIT, "Waiting for transfer of type 0x%02x completion...", 1) \ -X( 5, RGXFW_GROUP_DMA, RGXFW_SF_DMA_CCB_LOADING_FAILED, "Loading of cCCB data from FW common context 0x%08x (offset: %u, size: %u) failed", 3) \ -X( 6, RGXFW_GROUP_DMA, RGXFW_SF_DMA_CCB_LOAD_INVALID, "Invalid load of cCCB data from FW common context 0x%08x (offset: %u, size: %u)", 3) \ -X( 7, RGXFW_GROUP_DMA, RGXFW_SF_DMA_POLL_FAILED, "Transfer 0x%02x request poll failure", 1) \ -X( 8, RGXFW_GROUP_DMA, RGXFW_SF_DMA_BOOT_TRANSFER_FAILED, "Boot transfer(s) failed (code? %u, data? %u), used slower memcpy instead", 2) \ -X( 9, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_REQUEST, "Transfer 0x%02x request on ch. %u: system 0x%02x%08x, coremem 0x%08x, flags 0x%x, size %u", 7) \ -\ -X( 1, RGXFW_GROUP_DBG, RGXFW_SF_DBG_INTPAIR, "0x%08x 0x%08x", 2) \ -X( 2, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1HEX, "0x%08x", 1) \ -X( 3, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2HEX, "0x%08x 0x%08x", 2) \ -X( 4, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3HEX, "0x%08x 0x%08x 0x%08x", 3) \ -X( 5, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4HEX, "0x%08x 0x%08x 0x%08x 0x%08x", 4) \ -X( 6, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 5) \ -X( 7, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 6) \ -X( 8, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 7) \ -X( 9, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 8) \ -X( 10, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1SIGNED, "%d", 1) \ -X( 11, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2SIGNED, "%d %d", 2) \ -X( 12, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3SIGNED, "%d %d %d", 3) \ -X( 13, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4SIGNED, "%d %d %d %d", 4) \ -X( 14, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5SIGNED, "%d %d %d %d %d", 5) \ -X( 15, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6SIGNED, "%d %d %d %d %d %d", 6) \ -X( 16, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7SIGNED, "%d %d %d %d %d %d %d", 7) \ -X( 17, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8SIGNED, "%d %d %d %d %d %d %d %d", 8) \ -X( 18, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1UNSIGNED, "%u", 1) \ -X( 19, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2UNSIGNED, "%u %u", 2) \ -X( 20, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3UNSIGNED, "%u %u %u", 3) \ -X( 21, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4UNSIGNED, "%u %u %u %u", 4) \ -X( 22, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5UNSIGNED, "%u %u %u %u %u", 5) \ -X( 23, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6UNSIGNED, "%u %u %u %u %u %u", 6) \ -X( 24, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7UNSIGNED, "%u %u %u %u %u %u %u", 7) \ -X( 25, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8UNSIGNED, "%u %u %u %u %u %u %u %u", 8) \ -\ -X(65535, RGXFW_GROUP_NULL, RGXFW_SF_LAST, "You should not use this string", 15) - - -/* The symbolic names found in the table above are assigned an ui32 value of - * the following format: - * 31 30 28 27 20 19 16 15 12 11 0 bits - * - --- ---- ---- ---- ---- ---- ---- ---- - * 0-11: id number - * 12-15: group id number - * 16-19: number of parameters - * 20-27: unused - * 28-30: active: identify SF packet, otherwise regular int32 - * 31: reserved for signed/unsigned compatibility - * - * The following macro assigns those values to the enum generated SF ids list. - */ -#define RGXFW_LOG_IDMARKER (0x70000000U) -#define RGXFW_LOG_CREATESFID(a,b,e) ((IMG_UINT32)(a) | ((IMG_UINT32)(b)<<12U) | ((IMG_UINT32)(e)<<16U)) | RGXFW_LOG_IDMARKER - -#define RGXFW_LOG_IDMASK (0xFFF00000U) -#define RGXFW_LOG_VALIDID(I) (((I) & RGXFW_LOG_IDMASK) == RGXFW_LOG_IDMARKER) - -typedef enum { -#define X(a, b, c, d, e) c = RGXFW_LOG_CREATESFID(a,b,e), - RGXFW_LOG_SFIDLIST -#undef X -} RGXFW_LOG_SFids; - -/* Return the group id that the given (enum generated) id belongs to */ -#define RGXFW_SF_GID(x) (((IMG_UINT32)(x)>>12) & 0xfU) -/* Returns how many arguments the SF(string format) for the given (enum generated) id requires */ -#define RGXFW_SF_PARAMNUM(x) (((IMG_UINT32)(x)>>16) & 0xfU) - -#endif /* RGX_FWIF_SF_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_shared.h b/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_shared.h deleted file mode 100644 index 13844ad4e801e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_fwif_shared.h +++ /dev/null @@ -1,335 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX firmware interface structures -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX firmware interface structures shared by both host client - and host server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_FWIF_SHARED_H) -#define RGX_FWIF_SHARED_H - -#include "img_types.h" -#include "img_defs.h" -#include "rgx_common.h" -#include "powervr/mem_types.h" - -/* Indicates the number of RTDATAs per RTDATASET */ -#if defined(SUPPORT_AGP) -#define RGXMKIF_NUM_RTDATAS 4U -#define RGXMKIF_NUM_GEOMDATAS 4U -#define RGXMKIF_NUM_RTDATA_FREELISTS 12U /* RGXMKIF_NUM_RTDATAS * RGXFW_MAX_FREELISTS */ -#define RGX_NUM_GEOM_CORES (2U) -#else -#define RGXMKIF_NUM_RTDATAS 2U -#define RGXMKIF_NUM_GEOMDATAS 1U -#define RGXMKIF_NUM_RTDATA_FREELISTS 2U /* RGXMKIF_NUM_RTDATAS * RGXFW_MAX_FREELISTS */ -#define RGX_NUM_GEOM_CORES (1U) -#endif - -/* Maximum number of UFOs in a CCB command. - * The number is based on having 32 sync prims (as originally), plus 32 sync - * checkpoints. - * Once the use of sync prims is no longer supported, we will retain - * the same total (64) as the number of sync checkpoints which may be - * supporting a fence is not visible to the client driver and has to - * allow for the number of different timelines involved in fence merges. - */ -#define RGXFWIF_CCB_CMD_MAX_UFOS (32U+32U) - -/* - * This is a generic limit imposed on any DM (TA,3D,CDM,TDM,2D,TRANSFER) - * command passed through the bridge. - * Just across the bridge in the server, any incoming kick command size is - * checked against this maximum limit. - * In case the incoming command size is larger than the specified limit, - * the bridge call is retired with error. - */ -#define RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE (1024U) - -typedef struct RGXFWIF_DEV_VIRTADDR_ -{ - IMG_UINT32 ui32Addr; -} RGXFWIF_DEV_VIRTADDR; - -typedef struct -{ - IMG_DEV_VIRTADDR RGXFW_ALIGN psDevVirtAddr; - RGXFWIF_DEV_VIRTADDR pbyFWAddr; -} UNCACHED_ALIGN RGXFWIF_DMA_ADDR; - -typedef IMG_UINT8 RGXFWIF_CCCB; - -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_UFO_ADDR; -typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CLEANUP_CTL; - - -/*! - * @InGroup ClientCCBTypes - * @Brief Command data for fence & update types Client CCB commands. - */ -typedef struct -{ - PRGXFWIF_UFO_ADDR puiAddrUFO; /*!< Address to be checked/updated */ - IMG_UINT32 ui32Value; /*!< Value to check-against/update-to */ -} RGXFWIF_UFO; - -typedef struct -{ - IMG_UINT32 ui32SubmittedCommands; /*!< Number of commands received by the FW */ - IMG_UINT32 ui32ExecutedCommands; /*!< Number of commands executed by the FW */ -} UNCACHED_ALIGN RGXFWIF_CLEANUP_CTL; - -#define RGXFWIF_PRBUFFER_START IMG_UINT32_C(0) -#define RGXFWIF_PRBUFFER_ZSBUFFER IMG_UINT32_C(0) -#define RGXFWIF_PRBUFFER_MSAABUFFER IMG_UINT32_C(1) -#define RGXFWIF_PRBUFFER_MAXSUPPORTED IMG_UINT32_C(2) - -typedef IMG_UINT32 RGXFWIF_PRBUFFER_TYPE; - -typedef enum -{ - RGXFWIF_PRBUFFER_UNBACKED = 0, - RGXFWIF_PRBUFFER_BACKED, - RGXFWIF_PRBUFFER_BACKING_PENDING, - RGXFWIF_PRBUFFER_UNBACKING_PENDING, -}RGXFWIF_PRBUFFER_STATE; - -/*! - * @InGroup RenderTarget - * @Brief OnDemand Z/S/MSAA Buffers - */ -typedef struct -{ - IMG_UINT32 ui32BufferID; /*!< Buffer ID*/ - IMG_BOOL bOnDemand; /*!< Needs On-demand Z/S/MSAA Buffer allocation */ - RGXFWIF_PRBUFFER_STATE eState; /*!< Z/S/MSAA -Buffer state */ - RGXFWIF_CLEANUP_CTL sCleanupState; /*!< Cleanup state */ - IMG_UINT32 ui32PRBufferFlags; /*!< Compatibility and other flags */ -} UNCACHED_ALIGN RGXFWIF_PRBUFFER; - -/* - * Used to share frame numbers across UM-KM-FW, - * frame number is set in UM, - * frame number is required in both KM for HTB and FW for FW trace. - * - * May be used to house Kick flags in the future. - */ -typedef struct -{ - IMG_UINT32 ui32FrameNum; /*!< associated frame number */ -} CMD_COMMON; - -/* - * TA and 3D commands require set of firmware addresses that are stored in the - * Kernel. Client has handle(s) to Kernel containers storing these addresses, - * instead of raw addresses. We have to patch/write these addresses in KM to - * prevent UM from controlling FW addresses directly. - * Typedefs for TA and 3D commands are shared between Client and Firmware (both - * single-BVNC). Kernel is implemented in a multi-BVNC manner, so it can't use - * TA|3D CMD type definitions directly. Therefore we have a SHARED block that - * is shared between UM-KM-FW across all BVNC configurations. - */ -typedef struct -{ - CMD_COMMON sCmn; /*!< Common command attributes */ - RGXFWIF_DEV_VIRTADDR sHWRTData; /* RTData associated with this command, - this is used for context selection and for storing out HW-context, - when TA is switched out for continuing later */ - - RGXFWIF_DEV_VIRTADDR asPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /* Supported PR Buffers like Z/S/MSAA Scratch */ - -} CMDTA3D_SHARED; - -/*! - * Client Circular Command Buffer (CCCB) control structure. - * This is shared between the Server and the Firmware and holds byte offsets - * into the CCCB as well as the wrapping mask to aid wrap around. A given - * snapshot of this queue with Cmd 1 running on the GPU might be: - * - * Roff Doff Woff - * [..........|-1----------|=2===|=3===|=4===|~5~~~~|~6~~~~|~7~~~~|..........] - * < runnable commands >< !ready to run > - * - * Cmd 1 : Currently executing on the GPU data master. - * Cmd 2,3,4: Fence dependencies met, commands runnable. - * Cmd 5... : Fence dependency not met yet. - */ -typedef struct -{ - IMG_UINT32 ui32WriteOffset; /*!< Host write offset into CCB. This - * must be aligned to 16 bytes. */ - IMG_UINT32 ui32ReadOffset; /*!< Firmware read offset into CCB. - Points to the command that is - * runnable on GPU, if R!=W */ - IMG_UINT32 ui32DepOffset; /*!< Firmware fence dependency offset. - * Points to commands not ready, i.e. - * fence dependencies are not met. */ - IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask, total capacity - in bytes of the CCB-1 */ -#if defined(SUPPORT_AGP) - IMG_UINT32 ui32ReadOffset2; -#if defined(SUPPORT_AGP4) - IMG_UINT32 ui32ReadOffset3; - IMG_UINT32 ui32ReadOffset4; -#endif -#endif - -} UNCACHED_ALIGN RGXFWIF_CCCB_CTL; - - -typedef IMG_UINT32 RGXFW_FREELIST_TYPE; - -#define RGXFW_LOCAL_FREELIST IMG_UINT32_C(0) -#define RGXFW_GLOBAL_FREELIST IMG_UINT32_C(1) -#if defined(SUPPORT_AGP) -#define RGXFW_GLOBAL2_FREELIST IMG_UINT32_C(2) -#define RGXFW_MAX_FREELISTS (RGXFW_GLOBAL2_FREELIST + 1U) -#else -#define RGXFW_MAX_FREELISTS (RGXFW_GLOBAL_FREELIST + 1U) -#endif -#define RGXFW_MAX_HWFREELISTS (2U) - -/*! - * @Defgroup ContextSwitching Context switching data interface - * @Brief Types grouping data structures and defines used in realising the Context Switching (CSW) functionality - * @{ - */ - -/*! - * @Brief GEOM DM or TA register controls for context switch - */ -typedef struct -{ - IMG_UINT64 uTAReg_VDM_CONTEXT_STATE_BASE_ADDR; /*!< The base address of the VDM's context state buffer */ - IMG_UINT64 uTAReg_VDM_CONTEXT_STATE_RESUME_ADDR; - IMG_UINT64 uTAReg_TA_CONTEXT_STATE_BASE_ADDR; /*!< The base address of the TA's context state buffer */ - - struct - { - IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK0; /*!< VDM context store task 0 */ - IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK1; /*!< VDM context store task 1 */ - IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK2; /*!< VDM context store task 2 */ - - /* VDM resume state update controls */ - IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK0; /*!< VDM context resume task 0 */ - IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK1; /*!< VDM context resume task 1 */ - IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK2; /*!< VDM context resume task 2 */ - - IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK3; - IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK4; - - IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK3; - IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK4; - } asTAState[2]; - -} RGXFWIF_TAREGISTERS_CSWITCH; -/*! @} End of Defgroup ContextSwitching */ - -#define RGXFWIF_TAREGISTERS_CSWITCH_SIZE sizeof(RGXFWIF_TAREGISTERS_CSWITCH) - -typedef struct -{ - IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0; - IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS1; - IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS; - IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS1; - - /* CDM resume controls */ - IMG_UINT64 uCDMReg_CDM_RESUME_PDS0; - IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0_B; - IMG_UINT64 uCDMReg_CDM_RESUME_PDS0_B; - -} RGXFWIF_CDM_REGISTERS_CSWITCH; - -/*! - * @InGroup ContextSwitching - * @Brief Render context static register controls for context switch - */ -typedef struct -{ - RGXFWIF_TAREGISTERS_CSWITCH RGXFW_ALIGN asCtxSwitch_GeomRegs[RGX_NUM_GEOM_CORES]; /*!< Geom registers for ctx switch */ -} RGXFWIF_STATIC_RENDERCONTEXT_STATE; - -#define RGXFWIF_STATIC_RENDERCONTEXT_SIZE sizeof(RGXFWIF_STATIC_RENDERCONTEXT_STATE) - -typedef struct -{ - RGXFWIF_CDM_REGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_Regs; /*!< CDM registers for ctx switch */ -} RGXFWIF_STATIC_COMPUTECONTEXT_STATE; - -#define RGXFWIF_STATIC_COMPUTECONTEXT_SIZE sizeof(RGXFWIF_STATIC_COMPUTECONTEXT_STATE) - -/*! - @Brief Context reset reason. Last reset reason for a reset context. -*/ -typedef enum -{ - RGX_CONTEXT_RESET_REASON_NONE = 0, /*!< No reset reason recorded */ - RGX_CONTEXT_RESET_REASON_GUILTY_LOCKUP = 1, /*!< Caused a reset due to locking up */ - RGX_CONTEXT_RESET_REASON_INNOCENT_LOCKUP = 2, /*!< Affected by another context locking up */ - RGX_CONTEXT_RESET_REASON_GUILTY_OVERRUNING = 3, /*!< Overran the global deadline */ - RGX_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING = 4, /*!< Affected by another context overrunning */ - RGX_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH = 5, /*!< Forced reset to ensure scheduling requirements */ - RGX_CONTEXT_RESET_REASON_WGP_CHECKSUM = 6, /*!< CDM Mission/safety checksum mismatch */ - RGX_CONTEXT_RESET_REASON_TRP_CHECKSUM = 7, /*!< TRP checksum mismatch */ - RGX_CONTEXT_RESET_REASON_GPU_ECC_OK = 8, /*!< GPU ECC error (corrected, OK) */ - RGX_CONTEXT_RESET_REASON_GPU_ECC_HWR = 9, /*!< GPU ECC error (uncorrected, HWR) */ - RGX_CONTEXT_RESET_REASON_FW_ECC_OK = 10, /*!< FW ECC error (corrected, OK) */ - RGX_CONTEXT_RESET_REASON_FW_ECC_ERR = 11, /*!< FW ECC error (uncorrected, ERR) */ - RGX_CONTEXT_RESET_REASON_FW_WATCHDOG = 12, /*!< FW Safety watchdog triggered */ - RGX_CONTEXT_RESET_REASON_FW_PAGEFAULT = 13, /*!< FW page fault (no HWR) */ - RGX_CONTEXT_RESET_REASON_FW_EXEC_ERR = 14, /*!< FW execution error (GPU reset requested) */ - RGX_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR = 15, /*!< Host watchdog detected FW error */ - RGX_CONTEXT_GEOM_OOM_DISABLED = 16, /*!< Geometry DM OOM event is not allowed */ -} RGX_CONTEXT_RESET_REASON; - -/*! - @Brief Context reset data shared with the host -*/ -typedef struct -{ - RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reset reason */ - IMG_UINT32 ui32ResetExtJobRef; /*!< External Job ID */ -} RGX_CONTEXT_RESET_REASON_DATA; -#endif /* RGX_FWIF_SHARED_H */ - -/****************************************************************************** - End of file (rgx_fwif_shared.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_heap_firmware.h b/drivers/gpu/drm/img-rogue/1.17/rgx_heap_firmware.h deleted file mode 100644 index db2b90b9f2a77..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_heap_firmware.h +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX FW heap definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_HEAP_FIRMWARE_H) -#define RGX_HEAP_FIRMWARE_H - -/* Start at 903GiB. Size of 32MB per OSID (see rgxheapconfig.h) - * NOTE: - * The firmware heaps bases and sizes are defined here to - * simplify #include dependencies, see rgxheapconfig.h - * for the full RGX virtual address space layout. - */ - -/* - * The Config heap holds initialisation data shared between the - * the driver and firmware (e.g. pointers to the KCCB and FWCCB). - * The Main Firmware heap size is adjusted accordingly but most - * of the map / unmap functions must take into consideration - * the entire range (i.e. main and config heap). - */ -#define RGX_FIRMWARE_NUMBER_OF_FW_HEAPS (IMG_UINT32_C(2)) -#define RGX_FIRMWARE_HEAP_SHIFT RGX_FW_HEAP_SHIFT -#define RGX_FIRMWARE_RAW_HEAP_BASE (0xE1C0000000ULL) -#define RGX_FIRMWARE_RAW_HEAP_SIZE (IMG_UINT32_C(1) << RGX_FIRMWARE_HEAP_SHIFT) - -/* To enable the firmware to compute the exact address of structures allocated by the KM - * in the Fw Config subheap, regardless of the KM's page size (and PMR granularity), - * objects allocated consecutively but from different PMRs (due to differing memalloc flags) - * are allocated with a 64kb offset. This way, all structures will be located at the same base - * addresses when the KM is running with a page size of 4k, 16k or 64k. */ -#define RGX_FIRMWARE_CONFIG_HEAP_ALLOC_GRANULARITY (IMG_UINT32_C(0x10000)) - -/* Ensure the heap can hold 3 PMRs of maximum supported granularity (192KB): - * 1st PMR: RGXFWIF_CONNECTION_CTL - * 2nd PMR: RGXFWIF_OSINIT - * 3rd PMR: RGXFWIF_SYSINIT */ -#define RGX_FIRMWARE_CONFIG_HEAP_SIZE (IMG_UINT32_C(3)*RGX_FIRMWARE_CONFIG_HEAP_ALLOC_GRANULARITY) - -#define RGX_FIRMWARE_DEFAULT_MAIN_HEAP_SIZE (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE) -/* - * MIPS FW needs space in the Main heap to map GPU memory. - * This space is taken from the MAIN heap, to avoid creating a new heap. - */ -#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL (IMG_UINT32_C(0x100000)) /* 1MB */ -#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101 (IMG_UINT32_C(0x400000)) /* 4MB */ - -#define RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_NORMAL (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE - \ - RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL) - -#define RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_BRN65101 (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE - \ - RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101) - -#if !defined(__KERNEL__) -#if defined(FIX_HW_BRN_65101) -#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101 -#define RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_BRN65101 - -#include "img_defs.h" -static_assert((RGX_FIRMWARE_RAW_HEAP_SIZE) >= IMG_UINT32_C(0x800000), "MIPS GPU map size cannot be increased due to BRN65101 with a small FW heap"); - -#else -#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL -#define RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_NORMAL -#endif -#endif /* !defined(__KERNEL__) */ - -#define RGX_FIRMWARE_MAIN_HEAP_BASE RGX_FIRMWARE_RAW_HEAP_BASE -#define RGX_FIRMWARE_CONFIG_HEAP_BASE (RGX_FIRMWARE_MAIN_HEAP_BASE + \ - RGX_FIRMWARE_RAW_HEAP_SIZE - \ - RGX_FIRMWARE_CONFIG_HEAP_SIZE) - -/* - * The maximum configurable size via RGX_FW_HEAP_SHIFT is 32MiB (1<<25) and - * the minimum is 4MiB (1<<22); the default firmware heap size is set to - * maximum 32MiB. - */ -#if defined(RGX_FW_HEAP_SHIFT) && (RGX_FW_HEAP_SHIFT < 22 || RGX_FW_HEAP_SHIFT > 25) -#error "RGX_FW_HEAP_SHIFT is outside valid range [22, 25]" -#endif - -#endif /* RGX_HEAP_FIRMWARE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_heaps.h b/drivers/gpu/drm/img-rogue/1.17/rgx_heaps.h deleted file mode 100644 index e41e4002b2c4d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_heaps.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX heap definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_HEAPS_H) -#define RGX_HEAPS_H - -/* - Identify heaps by their names -*/ -#define RGX_GENERAL_SVM_HEAP_IDENT "General SVM" /*!< RGX General SVM (shared virtual memory) Heap Identifier */ -#define RGX_GENERAL_HEAP_IDENT "General" /*!< RGX General Heap Identifier */ -#define RGX_GENERAL_NON4K_HEAP_IDENT "General NON-4K" /*!< RGX General non-4K Heap Identifier */ -#define RGX_PDSCODEDATA_HEAP_IDENT "PDS Code and Data" /*!< RGX PDS Code/Data Heap Identifier */ -#define RGX_USCCODE_HEAP_IDENT "USC Code" /*!< RGX USC Code Heap Identifier */ -#define RGX_VK_CAPT_REPLAY_HEAP_IDENT "Vulkan Capture Replay" /*!< RGX Vulkan capture replay buffer Heap Identifier */ -#define RGX_SIGNALS_HEAP_IDENT "Signals" /*!< Signals Heap Identifier */ -#define RGX_FBCDC_HEAP_IDENT "FBCDC" /*!< RGX FBCDC State Table Heap Identifier */ -#define RGX_FBCDC_LARGE_HEAP_IDENT "Large FBCDC" /*!< RGX Large FBCDC State Table Heap Identifier */ -#define RGX_CMP_MISSION_RMW_HEAP_IDENT "Compute Mission RMW" /*!< Compute Mission RMW Heap Identifier */ -#define RGX_CMP_SAFETY_RMW_HEAP_IDENT "Compute Safety RMW" /*!< Compute Safety RMW Heap Identifier */ -#define RGX_TEXTURE_STATE_HEAP_IDENT "Texture State" /*!< Texture State Heap Identifier */ -#define RGX_VISIBILITY_TEST_HEAP_IDENT "Visibility Test" /*!< Visibility Test Heap Identifier */ - -/* Services client internal heap identification */ -#define RGX_RGNHDR_BRN_63142_HEAP_IDENT "RgnHdr BRN63142" /*!< RGX RgnHdr BRN63142 Heap Identifier */ -#define RGX_TQ3DPARAMETERS_HEAP_IDENT "TQ3DParameters" /*!< RGX TQ 3D Parameters Heap Identifier */ -#define RGX_MMU_INIA_BRN_65273_HEAP_IDENT "MMU INIA BRN65273" /*!< MMU BRN65273 Heap A Identifier */ -#define RGX_MMU_INIB_BRN_65273_HEAP_IDENT "MMU INIB BRN65273" /*!< MMU BRN65273 Heap B Identifier */ -#endif /* RGX_HEAPS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf.h b/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf.h deleted file mode 100644 index fa711b0b6df20..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf.h +++ /dev/null @@ -1,1607 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HWPerf and Debug Types and Defines Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Common data types definitions for hardware performance API -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_HWPERF_H_ -#define RGX_HWPERF_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* These structures are used on both GPU and CPU and must be a size that is a - * multiple of 64 bits, 8 bytes to allow the FW to write 8 byte quantities at - * 8 byte aligned addresses. RGX_FW_STRUCT_*_ASSERT() is used to check this. - */ - -/****************************************************************************** - * Includes and Defines - *****************************************************************************/ - -#include "img_types.h" -#include "img_defs.h" - -#include "rgx_common.h" -#include "rgx_hwperf_common.h" -#include "pvrsrv_tlcommon.h" -#include "pvrsrv_sync_km.h" - - -#if !defined(__KERNEL__) -/* User-mode and Firmware definitions only */ - -#if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER) - -/* HWPerf interface assumption checks */ -static_assert(RGX_FEATURE_NUM_CLUSTERS <= 16U, "Cluster count too large for HWPerf protocol definition"); - -/*! The number of indirectly addressable TPU_MSC blocks in the GPU */ -# define RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST MAX(((IMG_UINT32)RGX_FEATURE_NUM_CLUSTERS >> 1), 1U) - -/*! The number of indirectly addressable USC blocks in the GPU */ -# define RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER (RGX_FEATURE_NUM_CLUSTERS) - -# if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - - /*! Defines the number of performance counter blocks that are directly - * addressable in the RGX register map for S. */ -# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 1 /* JONES */ -# define RGX_HWPERF_INDIRECT_BY_PHANTOM (RGX_NUM_PHANTOMS) -# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 1 /* BLACKPEARL */ -# define RGX_HWPERF_PHANTOM_DUST_BLKS 2 /* TPU, TEXAS */ -# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 2 /* USC, PBE */ - -# elif defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) - - /*! Defines the number of performance counter blocks that are directly - * addressable in the RGX register map. */ -# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 2 /* TORNADO, TA */ - -# define RGX_HWPERF_INDIRECT_BY_PHANTOM (RGX_NUM_PHANTOMS) -# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 2 /* RASTER, TEXAS */ -# define RGX_HWPERF_PHANTOM_DUST_BLKS 1 /* TPU */ -# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 1 /* USC */ - -# else /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && !defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) i.e. S6 */ - - /*! Defines the number of performance counter blocks that are - * addressable in the RGX register map for Series 6. */ -# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 3 /* TA, RASTER, HUB */ -# define RGX_HWPERF_INDIRECT_BY_PHANTOM 0 /* PHANTOM is not there in Rogue1. Just using it to keep naming same as later series (RogueXT n Rogue XT+) */ -# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 0 -# define RGX_HWPERF_PHANTOM_DUST_BLKS 1 /* TPU */ -# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 1 /* USC */ - -# endif - -/*! The number of performance counters in each layout block defined for UM/FW code */ -#if defined(RGX_FEATURE_CLUSTER_GROUPING) - #define RGX_HWPERF_CNTRS_IN_BLK 6 - #else - #define RGX_HWPERF_CNTRS_IN_BLK 4 -#endif - -#endif /* #if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER) */ -#else /* defined(__KERNEL__) */ -/* Kernel/server definitions - not used, hence invalid definitions */ - -# define RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC 0xFF - -# define RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -# define RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC - -# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -# define RGX_HWPERF_INDIRECT_BY_PHANTOM RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -# define RGX_HWPERF_PHANTOM_NONDUST_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -# define RGX_HWPERF_PHANTOM_DUST_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC - -#endif - -/*! The number of custom non-mux counter blocks supported */ -#define RGX_HWPERF_MAX_CUSTOM_BLKS 5U - -/*! The number of counters supported in each non-mux counter block */ -#define RGX_HWPERF_MAX_CUSTOM_CNTRS 8U - -/*! The number of directly-addressable counters allowed in non-mux counter blocks */ -#define RGX_CNTBLK_COUNTERS_MAX ((IMG_UINT32)PVRSRV_HWPERF_COUNTERS_PERBLK + 0U) - - -/****************************************************************************** - * Data Stream Common Types - *****************************************************************************/ - -/*! All the Data Masters HWPerf is aware of. When a new DM is added to this - * list, it should be appended at the end to maintain backward compatibility - * of HWPerf data. - */ -typedef enum { - - RGX_HWPERF_DM_GP, - RGX_HWPERF_DM_2D, - RGX_HWPERF_DM_TA, - RGX_HWPERF_DM_3D, - RGX_HWPERF_DM_CDM, - RGX_HWPERF_DM_RTU, - RGX_HWPERF_DM_SHG, - RGX_HWPERF_DM_TDM, - - RGX_HWPERF_DM_LAST, - - RGX_HWPERF_DM_INVALID = 0x1FFFFFFF -} RGX_HWPERF_DM; - -/*! Define containing bit position for 32bit feature flags used in hwperf and api */ -typedef IMG_UINT32 RGX_HWPERF_FEATURE_FLAGS; -#define RGX_HWPERF_FEATURE_PERFBUS_FLAG 0x0001U -#define RGX_HWPERF_FEATURE_S7_TOP_INFRASTRUCTURE_FLAG 0x0002U -#define RGX_HWPERF_FEATURE_XT_TOP_INFRASTRUCTURE_FLAG 0x0004U -#define RGX_HWPERF_FEATURE_PERF_COUNTER_BATCH_FLAG 0x0008U -#define RGX_HWPERF_FEATURE_ROGUEXE_FLAG 0x0010U -#define RGX_HWPERF_FEATURE_DUST_POWER_ISLAND_S7_FLAG 0x0020U -#define RGX_HWPERF_FEATURE_PBE2_IN_XE_FLAG 0x0040U -#define RGX_HWPERF_FEATURE_WORKLOAD_ESTIMATION 0x0080U -#define RGX_HWPERF_FEATURE_MULTICORE_FLAG 0x0100U -#define RGX_HWPERF_FEATURE_VOLCANIC_FLAG 0x0800U -#define RGX_HWPERF_FEATURE_ROGUE_FLAG 0x1000U -#define RGX_HWPERF_FEATURE_OCEANIC_FLAG 0x2000U - -/*! This structure holds the data of a firmware packet. */ -typedef struct -{ - RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */ - IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */ - IMG_UINT32 ui32FWPerfCount0; /*!< Meta/MIPS PERF_COUNT0 register */ - IMG_UINT32 ui32FWPerfCount1; /*!< Meta/MIPS PERF_COUNT1 register */ - IMG_UINT32 ui32TimeCorrIndex; /*!< Internal field */ - IMG_UINT32 ui32Padding; /*!< Reserved */ -} RGX_HWPERF_FW_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FW_DATA); - -/*! This structure holds the data of a hardware packet, including counters. */ -typedef struct -{ - IMG_UINT32 ui32DMCyc; /*!< DataMaster cycle count register, 0 if none */ - IMG_UINT32 ui32FrameNum; /*!< Frame number, undefined on some DataMasters */ - IMG_UINT32 ui32PID; /*!< Process identifier */ - IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */ - IMG_UINT32 ui32WorkTarget; /*!< RenderTarget for a TA,3D; Frame context for RTU, 0x0 otherwise */ - IMG_UINT32 ui32ExtJobRef; /*!< Client driver context job reference used for tracking/debugging */ - IMG_UINT32 ui32IntJobRef; /*!< RGX Data master context job reference used for tracking/debugging */ - IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the time correlation at the time the packet was generated */ - IMG_UINT32 ui32BlkInfo; /*!< <31..16> NumBlocks <15..0> Counter block stream offset */ - IMG_UINT32 ui32WorkCtx; /*!< Work context: Render Context for TA/3D; RayTracing Context for RTU/SHG; 0x0 otherwise */ - IMG_UINT32 ui32CtxPriority; /*!< Context priority */ - IMG_UINT32 ui32GPUIdMask; /*!< GPU IDs active within this event */ - IMG_UINT32 ui32KickInfo; /*!< <31..8> Reserved <7..0> GPU Pipeline DM kick ID, 0 if not using Pipeline DMs */ - IMG_UINT32 ui32Padding; /*!< Reserved. To ensure correct alignment */ - IMG_UINT32 aui32CountBlksStream[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS]; /*!< Optional variable length Counter data */ - IMG_UINT32 ui32Padding2; /*!< Reserved. To ensure correct alignment (not written in the packet) */ -} RGX_HWPERF_HW_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA); -RGX_FW_STRUCT_OFFSET_ASSERT(RGX_HWPERF_HW_DATA, aui32CountBlksStream); - -typedef struct -{ - IMG_UINT32 ui32DMCyc; /*!< DataMaster cycle count register, 0 if none */ - IMG_UINT32 ui32FrameNum; /*!< Frame number, undefined on some DataMasters */ - IMG_UINT32 ui32PID; /*!< Process identifier */ - IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */ - IMG_UINT32 ui32WorkTarget[4]; /*!< RenderTarget for a TA,3D; Frame context for RTU, 0x0 otherwise */ - /*!< V2A Block count / Client driver context job reference used for tracking/debugging */ - /*!< RGX Data master context job reference used for tracking/debugging */ - /*!< V2 Block count / Index to the time correlation at the time the packet was generated */ -} RGX_HWPERF_HW_DATA_V2; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA_V2); - -/*! Mask for use with the aui32CountBlksStream field when decoding the - * counter block ID and mask word. */ -#define RGX_HWPERF_CNTBLK_ID_MASK 0xFFFF0000U -#define RGX_HWPERF_CNTBLK_ID_SHIFT 16U - -/*! Obtains the counter block ID word from an aui32CountBlksStream field. - * The word combines Control bits (15-12), GPU-Id (11-8), Group (7-4), Unit - * within group (3-0) */ -#define RGX_HWPERF_GET_CNTBLK_IDW(_word) ((IMG_UINT16)(((_word)&RGX_HWPERF_CNTBLK_ID_MASK)>>RGX_HWPERF_CNTBLK_ID_SHIFT)) - -/*! Obtains the counter block ID from the supplied RGX_HWPERF_HW_DATA address - * and stream index. May be used in decoding the counter block stream words of - * a RGX_HWPERF_HW_DATA structure. */ -#define RGX_HWPERF_GET_CNTBLK_ID(_data_addr, _idx) RGX_HWPERF_GET_CNTBLK_IDW((_data_addr)->aui32CountBlksStream[(_idx)]) - -/*! Obtains the GPU ID from the supplied RGX_HWPERF_HW_DATA CNTBLK_IDW */ -#define RGX_HWPERF_GET_CNTBLK_GPUW(_word) ((IMG_UINT16)(((_word)&RGX_CNTBLK_ID_MC_GPU_MASK)>>RGX_CNTBLK_ID_MC_GPU_SHIFT)) - -#define RGX_HWPERF_GET_CNT_MASKW(_word) ((IMG_UINT16)((_word)&(~RGX_HWPERF_CNTBLK_ID_MASK))) - -/*! Obtains the counter mask from the supplied RGX_HWPERF_HW_DATA address - * and stream index. May be used in decoding the counter block stream words - * of a RGX_HWPERF_HW_DATA structure. */ -#define RGX_HWPERF_GET_CNT_MASK(_data_addr, _idx) RGX_HWPERF_GET_CNT_MASKW((_data_addr)->aui32CountBlksStream[(_idx)]) - -/*! Context switch packet event */ -typedef struct -{ - RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */ - IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */ - IMG_UINT32 ui32FrameNum; /*!< Client Frame number (TA, 3D only) */ - IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */ - IMG_UINT32 ui32PerfCycle; /*!< Cycle count. Used to measure HW context store latency */ - IMG_UINT32 ui32PerfPhase; /*!< Phase. Used to determine geometry content */ - IMG_UINT32 ui32Padding[2]; /*!< Padding to 8 DWords */ -} RGX_HWPERF_CSW_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CSW_DATA); - -/*! Enumeration of clocks supporting this event */ -typedef enum -{ - RGX_HWPERF_CLKS_CHG_INVALID = 0, - - RGX_HWPERF_CLKS_CHG_NAME_CORE = 1, - - RGX_HWPERF_CLKS_CHG_LAST, -} RGX_HWPERF_CLKS_CHG_NAME; - -/*! This structure holds the data of a clocks change packet. */ -typedef struct -{ - IMG_UINT64 ui64NewClockSpeed; /*!< New Clock Speed (in Hz) */ - RGX_HWPERF_CLKS_CHG_NAME eClockName; /*!< Clock name */ - IMG_UINT32 ui32CalibratedClockSpeed; /*!< Calibrated new GPU clock speed (in Hz) */ - IMG_UINT64 ui64OSTimeStamp; /*!< OSTimeStamp sampled by the host */ - IMG_UINT64 ui64CRTimeStamp; /*!< CRTimeStamp sampled by the host and - correlated to OSTimeStamp */ -} RGX_HWPERF_CLKS_CHG_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CLKS_CHG_DATA); - -/*! Enumeration of GPU utilisation states supported by this event */ -typedef IMG_UINT32 RGX_HWPERF_GPU_STATE; - -/*! This structure holds the data of a GPU utilisation state change packet. */ -typedef struct -{ - RGX_HWPERF_GPU_STATE eState; /*!< New GPU utilisation state */ - IMG_UINT32 uiUnused1; /*!< Padding */ - IMG_UINT32 uiUnused2; /*!< Padding */ - IMG_UINT32 uiUnused3; /*!< Padding */ -} RGX_HWPERF_GPU_STATE_CHG_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_GPU_STATE_CHG_DATA); - - -/*! Signature pattern 'HPE1' found in the first word of a PWR_EST packet data */ -#define HWPERF_PWR_EST_V1_SIG 0x48504531 - -/*! Macros to obtain a component field from a counter ID word */ -#define RGX_HWPERF_GET_PWR_EST_HIGH_FLAG(_word) (((_word)&0x80000000)>>31) -#define RGX_HWPERF_GET_PWR_EST_GPUID(_word) (((_word)&0x70000000)>>28) -/*!< Obtains the GPU ID from a counter ID word */ -#define RGX_HWPERF_GET_PWR_EST_UNIT(_word) (((_word)&0x0F000000)>>24) -#define RGX_HWPERF_GET_PWR_EST_NUMBER(_word) ((_word)&0x0000FFFF) - -#define RGX_HWPERF_PWR_EST_HIGH_OFFSET (31) -#define RGX_HWPERF_PWR_EST_GPUID_OFFSET (28) -#define RGX_HWPERF_PWR_EST_GPUID_MASK (0x7U) -#define RGX_HWPERF_PWR_EST_UNIT_OFFSET (24) -#define RGX_HWPERF_PWR_EST_UNIT_MASK (0xFU) -#define RGX_HWPERF_PWR_EST_VALUE_MASK (0xFFFFU) - -/*! This macro constructs a counter ID for a power estimate data stream from - * the component parts of: high word flag, unit id, GPU id, counter number */ -#define RGX_HWPERF_MAKE_PWR_EST_COUNTERID(_high, _unit, _core, _number) \ - ((IMG_UINT32)(((IMG_UINT32)((IMG_UINT32)(_high)&0x1U)<= RGX_BVNC_STR_SIZE_MAX), - "Space inside HWPerf packet data for BVNC string insufficient"); - -#define RGX_HWPERF_MAX_BVNC_BLOCK_LEN (16U) - -/*! BVNC Features */ -typedef struct -{ - /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */ - IMG_UINT16 ui16BlockID; - - /*! Number of counters in this block type */ - IMG_UINT16 ui16NumCounters; - - /*! Number of blocks of this type */ - IMG_UINT16 ui16NumBlocks; - - /*! Reserved for future use */ - IMG_UINT16 ui16Reserved; -} RGX_HWPERF_BVNC_BLOCK; - -/*! BVNC Features */ -typedef struct -{ - IMG_CHAR aszBvncString[RGX_HWPERF_MAX_BVNC_LEN]; /*!< BVNC string */ - IMG_UINT32 ui32BvncKmFeatureFlags; /*!< See RGX_HWPERF_FEATURE_FLAGS */ - IMG_UINT16 ui16BvncBlocks; /*!< Number of blocks described in aBvncBlocks */ - IMG_UINT16 ui16BvncGPUCores; /*!< Number of GPU cores present */ - RGX_HWPERF_BVNC_BLOCK aBvncBlocks[RGX_HWPERF_MAX_BVNC_BLOCK_LEN]; /*!< Supported Performance Blocks for BVNC. See RGX_HWPERF_BVNC_BLOCK */ -} RGX_HWPERF_BVNC; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_BVNC); - -/*! Performance Counter Configuration data element. */ -typedef struct -{ - IMG_UINT32 ui32BlockID; /*!< Counter Block ID. See RGX_HWPERF_CNTBLK_ID */ - IMG_UINT32 ui32NumCounters; /*!< Number of counters configured */ - IMG_UINT32 ui32CounterVals[RGX_CNTBLK_COUNTERS_MAX]; /*!< Counters configured (ui32NumCounters worth of entries) */ -} RGX_HWPERF_COUNTER_CFG_DATA_EL; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_COUNTER_CFG_DATA_EL); - -/*! Performance Counter Configuration data. */ -typedef struct -{ - IMG_UINT32 ui32EnabledBlocks; /*!< Number of Enabled Blocks. */ - RGX_HWPERF_COUNTER_CFG_DATA_EL uData; /*!< Start of variable length data. See RGX_HWPERF_COUNTER_CFG_DATA_EL */ - IMG_UINT32 ui32Padding; /*!< reserved */ -} RGX_HWPERF_COUNTER_CFG; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_COUNTER_CFG); - -/*! Sub-event's data. */ -typedef union -{ - struct - { - RGX_HWPERF_DM eDM; /*!< Data Master ID. */ - RGX_HWPERF_HWR_REASON eReason; /*!< Reason of the HWR. */ - IMG_UINT32 ui32DMContext; /*!< FW render context */ - } sHWR; /*!< HWR sub-event data. */ - - RGX_HWPERF_BVNC sBVNC; /*!< BVNC Features. See RGX_HWPERF_BVNC */ - struct - { - IMG_UINT32 ui32EvMaskLo; /*!< Low order 32 bits of Filter Mask */ - IMG_UINT32 ui32EvMaskHi; /*!< High order 32 bits of Filter Mask */ - } sEvMsk; /*!< HW Filter Mask */ - RGX_HWPERF_COUNTER_CFG sPCC; /*!< Performance Counter Config. See RGX_HWPERF_COUNTER_CFG */ -} RGX_HWPERF_FWACT_DETAIL; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DETAIL); - -/*! This structure holds the data of a FW activity event packet */ -typedef struct -{ - RGX_HWPERF_FWACT_EV eEvType; /*!< Event type. */ - RGX_HWPERF_FWACT_DETAIL uFwActDetail; /*!< Data of the sub-event. */ - IMG_UINT32 ui32Padding; /*!< Reserved. */ -} RGX_HWPERF_FWACT_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DATA); - - -typedef enum { - RGX_HWPERF_UFO_EV_UPDATE, /*!< Update on the UFO objects. */ - RGX_HWPERF_UFO_EV_CHECK_SUCCESS, /*!< Successful check on UFO objects. */ - RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS, /*!< Successful partial render check on UFO objects. */ - RGX_HWPERF_UFO_EV_CHECK_FAIL, /*!< Unsuccessful check on UFO objects. */ - RGX_HWPERF_UFO_EV_PRCHECK_FAIL, /*!< Unsuccessful partial render check on UFO objects. */ - RGX_HWPERF_UFO_EV_FORCE_UPDATE, /*!< Forced erroring of the UFO objects. */ - - RGX_HWPERF_UFO_EV_LAST /*!< Reserved. Do not use. */ -} RGX_HWPERF_UFO_EV; - -/*! Data stream tuple. */ -typedef union -{ - struct - { - IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */ - IMG_UINT32 ui32Value; /*!< Value of the UFO object */ - } sCheckSuccess; - struct - { - IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */ - IMG_UINT32 ui32Value; /*!< Value of the UFO object */ - IMG_UINT32 ui32Required; /*!< Value of the UFO object required by the fence */ - } sCheckFail; - struct - { - IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */ - IMG_UINT32 ui32OldValue; /*!< Value of UFO object before update */ - IMG_UINT32 ui32NewValue; /*!< Value of UFO object after update */ - } sUpdate; -} RGX_HWPERF_UFO_DATA_ELEMENT; - -/*! This structure holds the packet payload data for UFO event. */ -typedef struct -{ - RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event. See RGX_HWPERF_UFO_EV */ - IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the timer correlation data - at the time the packet was generated. - Used to approximate Host timestamps for - these events. */ - IMG_UINT32 ui32PID; /*!< Client process identifier */ - IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX - API to track submitted work (for - debugging/trace purposes) */ - IMG_UINT32 ui32IntJobRef; /*!< Internal reference used to track - submitted work (for debugging / trace - purposes) */ - IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context. - RenderContext for TA and 3D, Common - Context for other DMs */ - IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the - stream and stream data offset in the - payload */ - RGX_HWPERF_DM eDM; /*!< Data Master number, see RGX_HWPERF_DM */ - IMG_UINT32 ui32Padding; /*!< Unused, reserved */ - IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; /*!< Series of tuples holding UFO objects data */ -} RGX_HWPERF_UFO_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_UFO_DATA); - - -/*! - * RGX_HWPERF_KICK_TYPE describes the type of kick for events received / sent - * between KICK_START / KICK_END inclusively for all event types. - */ -typedef enum -{ - RGX_HWPERF_KICK_TYPE_TA3D, /*!< Replaced by separate TA and 3D types */ - RGX_HWPERF_KICK_TYPE_TQ2D, /*!< 2D TQ Kick */ - RGX_HWPERF_KICK_TYPE_TQ3D, /*!< 3D TQ Kick */ - RGX_HWPERF_KICK_TYPE_CDM, /*!< Compute Kick */ - RGX_HWPERF_KICK_TYPE_RS, /*!< Ray Store Kick */ - RGX_HWPERF_KICK_TYPE_VRDM, /*!< Vertex Ray Data Master Kick */ - RGX_HWPERF_KICK_TYPE_TQTDM,/*!< 2D Data Master TQ Kick */ - RGX_HWPERF_KICK_TYPE_SYNC, /*!< Sync Kick */ - RGX_HWPERF_KICK_TYPE_TA, /*!< TA Kick */ - RGX_HWPERF_KICK_TYPE_3D, /*!< 3D Kick */ - RGX_HWPERF_KICK_TYPE_LAST, - - RGX_HWPERF_KICK_TYPE_FORCE_32BIT = 0x7fffffff -} RGX_HWPERF_KICK_TYPE; - -typedef struct -{ - RGX_HWPERF_KICK_TYPE ui32EnqType; /*!< Workload type sent to FW for - scheduling on GPU hardware. - See RGX_HWPERF_KICK_TYPE */ - IMG_UINT32 ui32PID; /*!< Client process identifier */ - IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX API - to track submitted work (for debugging / - trace purposes) */ - IMG_UINT32 ui32IntJobRef; /*!< internal reference used to track submitted - work (for debugging / trace purposes) */ - IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */ - IMG_UINT32 ui32Padding; /*!< Unused, reserved */ - IMG_UINT64 ui64CheckFence_UID; /*!< ID of fence gating work execution on GPU */ - IMG_UINT64 ui64UpdateFence_UID; /*!< ID of fence triggered after work completes on GPU */ - IMG_UINT64 ui64DeadlineInus; /*!< Workload deadline in system monotonic time */ - IMG_UINT32 ui32CycleEstimate; /*!< Estimated cycle time for the workload */ - PVRSRV_FENCE hCheckFence; /*!< Fence this enqueue task waits for, before starting */ - PVRSRV_FENCE hUpdateFence; /*!< Fence this enqueue task signals, on completion */ - PVRSRV_TIMELINE hUpdateTimeline; /*!< Timeline on which the above hUpdateFence is created */ - - /* Align structure size to 8 bytes */ -} RGX_HWPERF_HOST_ENQ_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_ENQ_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_ENQ_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef struct -{ - RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event */ - IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the stream and - stream data offset in the payload */ -#ifdef __CHECKER__ - /* Since we're not conforming to the C99 standard by not using a flexible - * array member need to add a special case for Smatch static code analyser. */ - IMG_UINT32 aui32StreamData[]; -#else - IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; - /*!< Series of tuples holding UFO objects data */ - - IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */ -#endif -} RGX_HWPERF_HOST_UFO_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_UFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_UFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -/*! - * RGX_HWPERF_HOST_RESOURCE_TYPE describes the type of resource which has been - * Allocated, Freed or Modified. The values are used to determine which event - * data structure to use to decode the data from the event stream - */ -typedef enum -{ - RGX_HWPERF_HOST_RESOURCE_TYPE_INVALID, /*!< Invalid */ - RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC, /*!< SyncPrim */ - RGX_HWPERF_HOST_RESOURCE_TYPE_TIMELINE_DEPRECATED, - /*!< Timeline resource packets are - now emitted in client hwperf buffer */ - RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR, /*!< Fence for use on GPU (SYNC_CP backed) */ - RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP, /*!< Sync Checkpoint */ - RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW, /*!< Fence created on SW timeline */ - - RGX_HWPERF_HOST_RESOURCE_TYPE_LAST /*!< End of enumeration */ -} RGX_HWPERF_HOST_RESOURCE_TYPE; - -typedef union -{ - /*! Data for TYPE_TIMELINE (*Deprecated*). This sub-event is no longer - * generated in the HOST stream. Timeline data is now provided in the - * CLIENT stream instead. - */ - struct - { - IMG_UINT32 uiPid; /*!< Identifier of owning process */ - IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for timeline resource */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */ - } sTimelineAlloc; - - /*! Data for TYPE_FENCE_PVR */ - struct - { - IMG_PID uiPID; /*!< Identifier of owning process */ - PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */ - IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier of the check point - backing this fence on the GPU */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - } sFenceAlloc; - - /*! Data for TYPE_SYNC_CP */ - struct - { - IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */ - PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */ - IMG_PID uiPID; /*!< Identifier of owning process */ - PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - } sSyncCheckPointAlloc; - - /*! Data for TYPE_FENCE_SW */ - struct - { - IMG_PID uiPID; /*!< Identifier of owning process */ - PVRSRV_FENCE hSWFence; /*!< Unique identifier for the SWFence resource */ - PVRSRV_TIMELINE hSWTimeline; /*!< Unique identifier for the timeline resource */ - IMG_UINT64 ui64SyncPtIndex; /*!< Sync-pt index where this SW timeline has reached */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - } sSWFenceAlloc; - - /*! Data for TYPE_SYNC */ - struct - { - IMG_UINT32 ui32FWAddr; /*!< Identifier of sync resource */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - } sSyncAlloc; -} RGX_HWPERF_HOST_ALLOC_DETAIL; - -typedef struct -{ - RGX_HWPERF_HOST_RESOURCE_TYPE ui32AllocType; - /*!< This describes the type of the resource - allocated in the driver. See - RGX_HWPERF_HOST_RESOURCE_TYPE */ - RGX_HWPERF_HOST_ALLOC_DETAIL RGXFW_ALIGN uAllocDetail; - /*!< Union of structures providing further - data regarding the resource allocated. - Size of data varies with union member that - is present, check ``ui32AllocType`` value - to decode */ -} RGX_HWPERF_HOST_ALLOC_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_ALLOC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_ALLOC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef union -{ - /*! Data for TYPE_TIMELINE (*Deprecated*) */ - struct - { - IMG_UINT32 uiPid; /*!< Identifier of owning process */ - IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for the timeline resource */ - IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */ - } sTimelineDestroy; - - /*! Data for TYPE_FENCE_PVR */ - struct - { - IMG_UINT64 ui64Fence_UID; /*!< Unique identifier for the fence resource */ - IMG_UINT32 ui32Padding; /*!< Reserved. */ - } sFenceDestroy; - - /*! Data for TYPE_SYNC_CP */ - struct - { - IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */ - } sSyncCheckPointFree; - - /*! Data for TYPE_SYNC */ - struct - { - IMG_UINT32 ui32FWAddr; /*!< Unique identifier for the sync resource */ - } sSyncFree; -} RGX_HWPERF_HOST_FREE_DETAIL; - -typedef struct -{ - RGX_HWPERF_HOST_RESOURCE_TYPE ui32FreeType; - /*!< This describes the type of the resource - freed or released by the driver. See - RGX_HWPERF_HOST_RESOURCE_TYPE */ - RGX_HWPERF_HOST_FREE_DETAIL uFreeDetail; - /*!< Union of structures providing further data - regarding the resource freed. Size of data - varies with union member that is present, - check ``ui32FreeType`` value to decode */ - IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */ -} RGX_HWPERF_HOST_FREE_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_FREE_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_FREE_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef struct -{ - IMG_UINT64 ui64CRTimestamp; /*!< CR timer value from the latest entry of - the time domains correlation table */ - IMG_UINT64 ui64OSTimestamp; /*!< OS timestamp from the latest entry of the - time domains correlation table */ - IMG_UINT32 ui32ClockSpeed; /*!< GPU clock speed from the latest entry of - the time domains correlation table */ - IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */ -} RGX_HWPERF_HOST_CLK_SYNC_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef union -{ - /*! Data for TYPE_FENCE_PVR */ - struct - { - IMG_UINT64 ui64NewFence_UID; /*!< Unique identifier for the new merged fence - resource that has been created */ - IMG_UINT64 ui64InFence1_UID; /*!< Unique identifier for the fence resource */ - IMG_UINT64 ui64InFence2_UID; /*!< Unique identifier of the check point backing - the fence on the GPU */ - IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH]; - /*!< Label or name given to the sync resource */ - IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */ - } sFenceMerge; -} RGX_HWPERF_HOST_MODIFY_DETAIL; - -typedef struct -{ - RGX_HWPERF_HOST_RESOURCE_TYPE ui32ModifyType; - /*!< Describes the type of the resource - modified by the driver. See - RGX_HWPERF_HOST_RESOURCE_TYPE */ - - RGX_HWPERF_HOST_MODIFY_DETAIL uModifyDetail; - /*!< Union of structures providing further - data regarding the resource modified. - Size of data varies with union member that - is present. - Check ``uiModifyType`` value to decode */ -} RGX_HWPERF_HOST_MODIFY_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_MODIFY_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_MODIFY_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef enum -{ - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_UNDEFINED = 0, /*!< Invalid */ - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_OK, /*!< Device OK */ - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_RESPONDING, /*!< Device responding to requests */ - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_DEAD, /*!< Device not responding */ - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_FAULT, /*!< Device has faulted */ - - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_LAST -} RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS; - -typedef enum -{ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_UNDEFINED = 0, /*!< Invalid */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_NONE, /*!< No underlying health reason. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_ASSERTED, /*!< Device has asserted. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_POLL_FAILING, /*!< Device poll has failed. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_TIMEOUTS, /*!< Device timeout has fired. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_CORRUPT, /*!< Queue has become corrupt. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_STALLED, /*!< Queue has stalled. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_IDLING, /*!< Device is idling. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_RESTARTING, /*!< Device restarting. */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS,/*!< Interrupts have been discarded. */ - - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_LAST -} RGX_HWPERF_HOST_DEVICE_HEALTH_REASON; - -/*! RGX_HWPERF_DEV_INFO_EV values */ -typedef enum -{ - RGX_HWPERF_DEV_INFO_EV_HEALTH, /*!< Health sub-event */ - - RGX_HWPERF_DEV_INFO_EV_LAST /*!< Last enumeration value */ -} RGX_HWPERF_DEV_INFO_EV; - -/*! RGX_HWPERF_HOST_DEV_INFO_DETAIL is a union of structures providing - * further data regarding the device's status - */ -typedef union -{ - /*! Data for device status event */ - struct - { - RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS eDeviceHealthStatus; - /*!< Device's health status */ - RGX_HWPERF_HOST_DEVICE_HEALTH_REASON eDeviceHealthReason; - /*!< Reason for device's health status */ - } sDeviceStatus; -} RGX_HWPERF_HOST_DEV_INFO_DETAIL; - -/*! RGX_HWPERF_HOST_DEV_INFO_DATA contains device health status information */ -typedef struct -{ - IMG_UINT32 ui32Padding; - /*!< Reserved. Align structure size to 8 bytes */ - RGX_HWPERF_DEV_INFO_EV eEvType; - /*!< Type of the sub-event. See - RGX_HWPERF_DEV_INFO_EV */ - RGX_HWPERF_HOST_DEV_INFO_DETAIL uDevInfoDetail; - /*!< Union of structures providing further data - regarding the device's status. Size of data - varies with union member that is present, - check ``eEvType`` value to decode */ -} RGX_HWPERF_HOST_DEV_INFO_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -/*! RGX_HWPERF_INFO_EV event subtype for RGX_HWPERF_HOST_INFO_DATA events */ -typedef enum -{ - RGX_HWPERF_INFO_EV_MEM_USAGE, /*!< Memory usage event */ - RGX_HWPERF_INFO_EV_LAST /*!< End of enumeration */ -} RGX_HWPERF_INFO_EV; - -/*! RGX_HWPERF_HOST_INFO_DETAIL contains the data payload for the - * RGX_HWPERF_HOST_INFO_DATA event. - */ -typedef union -{ - /*! Host Memory usage statistics */ - struct - { - IMG_UINT32 ui32TotalMemoryUsage; /*!< Total memory usage */ - /*! Detailed memory usage */ - struct - { - IMG_UINT32 ui32Pid; /*!< Process ID */ - IMG_UINT32 ui32KernelMemUsage; /*!< Kernel memory usage */ - IMG_UINT32 ui32GraphicsMemUsage; /*!< GPU memory usage */ - } sPerProcessUsage[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS]; - } sMemUsageStats; -} RGX_HWPERF_HOST_INFO_DETAIL; - -/*! RGX_HWPERF_HOST_INFO_DATA. Host Info data event payload contains device - * memory usage information. - */ -typedef struct -{ - IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */ - RGX_HWPERF_INFO_EV eEvType; /*!< Type of subevent. See RGX_HWPERF_INFO_EV */ - RGX_HWPERF_HOST_INFO_DETAIL uInfoDetail; - /*!< Union of structures providing further data - regarding memory usage. Size varies with union - member that is present, check ``eEvType`` - value to decode */ -} RGX_HWPERF_HOST_INFO_DATA; - -/* Payload size must be multiple of 8 bytes to align start of next packet. */ -static_assert((sizeof(RGX_HWPERF_HOST_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -/*! FENCE_WAIT_TYPE definitions */ -typedef enum -{ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_BEGIN = 0, /*!< Begin */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_END, /*!< End */ - - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_LAST, /*!< Do not use */ -} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE; - -/*! FENCE_WAIT_RESULT definitions */ -typedef enum -{ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_INVALID = 0, /*!< Invalid */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_TIMEOUT, /*!< Timed Out */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_PASSED, /*!< Passed */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_ERROR, /*!< Errored */ - - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_LAST, /*!< Do not use */ -} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT; - -/*! FENCE_WAIT_DETAIL Event Payload */ -typedef union -{ -/*! Data for SYNC_FENCE_WAIT_TYPE_BEGIN */ - struct - { - IMG_UINT32 ui32TimeoutInMs; /*!< Wait timeout (ms) */ - } sBegin; - - /*! Data for SYNC_FENCE_WAIT_TYPE_END */ - struct - { - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT eResult; /*!< Wait result */ - } sEnd; -} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL; - -/*! RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA Event Payload. This data structure - * is received whenever the host driver handles a wait for sync event request. - */ -typedef struct -{ - IMG_PID uiPID; /*!< Identifier of the owning process */ - PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eType; - /*!< Type of the subevent, see - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL uDetail; - /*!< Union of structures providing further data - regarding device's status. Size of data varies with - union member that is present, check ``eType`` value - to decode */ - -} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA; - -static_assert((sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -/*! RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA. - * Software Timeline Advanced Event Payload. This data structure is received - * whenever the host driver processes a Software Timeline Advanced event. - */ -typedef struct -{ - IMG_PID uiPID; /*!< Identifier of the owning process */ - PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */ - IMG_UINT64 ui64SyncPtIndex; /*!< Index of the sync point to which the - timeline has advanced */ - -} RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA; - -static_assert((sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef enum -{ - RGX_HWPERF_HOST_CLIENT_INFO_TYPE_INVALID = 0, /*!< Invalid */ - RGX_HWPERF_HOST_CLIENT_INFO_TYPE_PROCESS_NAME, /*!< Process Name */ - - RGX_HWPERF_HOST_CLIENT_INFO_TYPE_LAST, /*!< Do not use */ -} RGX_HWPERF_HOST_CLIENT_INFO_TYPE; - -typedef struct -{ - IMG_PID uiClientPID; /*!< Client process identifier */ - IMG_UINT32 ui32Length; /*!< Number of bytes present in ``acName`` */ - IMG_CHAR acName[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; /*!< Process name string, null terminated */ -} RGX_HWPERF_HOST_CLIENT_PROC_NAME; - -#define RGX_HWPERF_HOST_CLIENT_PROC_NAME_SIZE(ui32NameLen) \ - ((IMG_UINT32)(offsetof(RGX_HWPERF_HOST_CLIENT_PROC_NAME, acName) + (ui32NameLen))) - -typedef union -{ - struct - { - IMG_UINT32 ui32Count; /*!< Number of elements in ``asProcNames`` */ - RGX_HWPERF_HOST_CLIENT_PROC_NAME asProcNames[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; - } sProcName; -} RGX_HWPERF_HOST_CLIENT_INFO_DETAIL; - -typedef struct -{ - IMG_UINT32 uiReserved1; /*!< Reserved. Align structure size to 8 bytes */ - RGX_HWPERF_HOST_CLIENT_INFO_TYPE eType; - /*!< Type of the subevent, see - RGX_HWPERF_HOST_CLIENT_INFO_TYPE */ - RGX_HWPERF_HOST_CLIENT_INFO_DETAIL uDetail; - /*!< Union of structures. Size of data - varies with union member that is present, - check ``eType`` value to decode */ - -} RGX_HWPERF_HOST_CLIENT_INFO_DATA; - -static_assert((sizeof(RGX_HWPERF_HOST_CLIENT_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U, - "sizeof(RGX_HWPERF_HOST_CLIENT_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT"); - -typedef enum -{ - RGX_HWPERF_RESOURCE_CAPTURE_TYPE_NONE, - RGX_HWPERF_RESOURCE_CAPTURE_TYPE_DEFAULT_FRAMEBUFFER, - RGX_HWPERF_RESOURCE_CAPTURE_TYPE_OFFSCREEN_FB_ATTACHMENTS, - RGX_HWPERF_RESOURCE_CAPTURE_TYPE_TILE_LIFETIME_DATA, - - RGX_HWPERF_RESOURCE_TYPE_COUNT -} RGX_HWPERF_RESOURCE_CAPTURE_TYPE; - -typedef struct -{ - IMG_UINT32 ui32Height; - IMG_UINT32 ui32Width; - IMG_UINT32 ui32BPP; - IMG_UINT32 ui32PixFormat; -} RGX_RESOURCE_PER_SURFACE_INFO, *PRGX_RESOURCE_PER_SURFACE_INFO; - -typedef struct -{ - IMG_INT32 i32XOffset; /*!< render surface X shift */ - IMG_INT32 i32YOffset; /*!< render surface Y shift */ - IMG_UINT32 ui32WidthInTiles; /*!< number of TLT data points in X */ - IMG_UINT32 ui32HeightInTiles; /*!< number of TLT data points in Y */ -} RGX_RESOURCE_PER_TLT_BUFFER_INFO, *PRGX_RESOURCE_PER_TLT_BUFFER_INFO; - -typedef union -{ - struct RGX_RESOURCE_CAPTURE_RENDER_SURFACES - { - IMG_UINT32 ui32RenderSurfaceCount; - RGX_RESOURCE_PER_SURFACE_INFO sSurface[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; - } sRenderSurfaces; - - struct RGX_RESOURCE_CAPTURE_TILE_LIFETIME_BUFFERS - { - RGX_RESOURCE_PER_TLT_BUFFER_INFO sTLTBufInfo[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; - } sTLTBuffers; -} RGX_RESOURCE_CAPTURE_DETAIL; - -typedef struct -{ - RGX_HWPERF_RESOURCE_CAPTURE_TYPE eType; - IMG_PID uPID; - IMG_UINT32 ui32ContextID; - IMG_UINT32 ui32FrameNum; - IMG_UINT32 ui32CapturedTaskJobRef; /* The job ref of the HW task that emitted the data */ - IMG_INT32 eClientModule; /* RGX_HWPERF_CLIENT_API - ID that the capture is originating from. */ - RGX_RESOURCE_CAPTURE_DETAIL uDetail; /* eType determines the value of the union */ -} RGX_RESOURCE_CAPTURE_INFO, *PRGX_RESOURCE_CAPTURE_INFO; - -#define RGX_RESOURCE_CAPTURE_INFO_BASE_SIZE() offsetof(RGX_RESOURCE_CAPTURE_INFO, uDetail) - -/*! Tile Lifetime Tracking header size. Only available if - * RGX_FEATURE_ISP_TILE_LIFETIME_TRACKING is present and enabled via - * SUPPORT_TLT_PERF - */ -#define RGX_TLT_HARDWARE_HDR_SIZE (16U) - -/* PVRSRVGetHWPerfResourceCaptureResult */ -typedef enum -{ - RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NONE = 0, - RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK, /* We got data ok, expect more packets for this request. */ - RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NOT_READY, /* Signals a timeout on the connection - no data available yet. */ - RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_SUCCESS, /* The request completed successfully, signals the end of packets for the request. */ - RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_FAILURE /* The request failed, signals the end of packets for the request. */ -} RGX_HWPERF_RESOURCE_CAPTURE_RESULT_STATUS; - -typedef struct -{ - IMG_PID uPID; /* In case of a failed request pass the caller the PID and context ID. */ - IMG_UINT32 ui32CtxID; - RGX_RESOURCE_CAPTURE_INFO *psInfo; /* Various meta-data regarding the captured resource which aid the requester when, - unpacking the resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */ - IMG_BYTE *pbData; /* Buffer containing the captured resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */ -} RGX_RESOURCE_CAPTURE_RESULT; - -/*! This type is a union of packet payload data structures associated with - * various FW and Host events */ -typedef union -{ - RGX_HWPERF_FW_DATA sFW; /*!< Firmware event packet data, - events ``0x01-0x06`` */ - RGX_HWPERF_HW_DATA sHW; /*!< Hardware event packet data, - events ``0x07-0x19``, ``0x28-0x29`` */ - RGX_HWPERF_CLKS_CHG_DATA sCLKSCHG; /*!< Clock change event packet - data, events ``0x1A`` */ - RGX_HWPERF_GPU_STATE_CHG_DATA sGPUSTATECHG; /*!< GPU utilisation state - change event packet data, - events ``0x1B`` */ - RGX_HWPERF_PWR_EST_DATA sPWREST; /*!< Power estimate event - packet data, - events ``0x20-0x22`` */ - RGX_HWPERF_PWR_CHG_DATA sPWR; /*!< Power event packet data, - events ``0x23`` */ - RGX_HWPERF_CSW_DATA sCSW; /*!< Context switch packet data, - events ``0x30-0x31`` */ - RGX_HWPERF_DVFS_DATA sDVFS; /*!< DVFS activity data, - events ``0x32`` */ - RGX_HWPERF_UFO_DATA sUFO; /*!< UFO data, events ``0x38`` */ - RGX_HWPERF_FWACT_DATA sFWACT; /*!< Firmware activity event - packet data, - events ``0x39`` */ - /* */ - RGX_HWPERF_HOST_ENQ_DATA sENQ; /*!< Host ENQ data, - events ``0x01`` (Host) */ - RGX_HWPERF_HOST_UFO_DATA sHUFO; /*!< Host UFO data, - events ``0x02`` (Host) */ - RGX_HWPERF_HOST_ALLOC_DATA sHALLOC; /*!< Host Alloc data, - events ``0x03`` (Host) */ - RGX_HWPERF_HOST_CLK_SYNC_DATA sHCLKSYNC; /*!< Host CLK_SYNC data, - events ``0x04`` (Host) */ - RGX_HWPERF_HOST_FREE_DATA sHFREE; /*!< Host Free data, - events ``0x05`` (Host) */ - RGX_HWPERF_HOST_MODIFY_DATA sHMOD; /*!< Host Modify data, - events ``0x06`` (Host) */ - RGX_HWPERF_HOST_DEV_INFO_DATA sHDEVINFO; /*!< Host device info data, - events ``0x07`` (Host) */ - RGX_HWPERF_HOST_INFO_DATA sHINFO; /*!< Host info data, - events ``0x08`` (Host) */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA sWAIT; /*!< Host fence-wait data, - events ``0x09`` (Host) */ - RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA sSWTLADV; /*!< Host SW-timeline advance - data, events ``0x0A`` (Host) */ - RGX_HWPERF_HOST_CLIENT_INFO_DATA sHClientInfo; /*!< Host client info, - events ``0x0B`` (Host) */ - -} RGX_HWPERF_V2_PACKET_DATA, *RGX_PHWPERF_V2_PACKET_DATA; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_DATA); - -#define RGX_HWPERF_GET_PACKET_DATA(_packet_addr) ((RGX_PHWPERF_V2_PACKET_DATA) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR)))) - -#define RGX_HWPERF_GET_DVFS_EVENT_TYPE_PTR(_packet_addr) \ - ((RGX_HWPERF_DVFS_EV*) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR) + offsetof(RGX_HWPERF_DVFS_DATA,eEventType)))) - -/****************************************************************************** - * API Types - *****************************************************************************/ - -/*! Counter block IDs for all the hardware blocks with counters. - * Directly addressable blocks must have a value between 0..15 [0..0xF]. - * Indirect groups have following encoding: - * First hex digit (LSB) represents a unit number within the group - * and the second hex digit represents the group number. - * Group 0 is the direct group, all others are indirect groups. - */ -typedef IMG_UINT32 RGX_HWPERF_CNTBLK_ID; - -/*! Directly addressable counter blocks */ -#if defined(DOXYGEN) -/*! _RGX_HWPERF_CNTBLK_ID */ -#endif -#define RGX_CNTBLK_ID_TA 0x0000U -#define RGX_CNTBLK_ID_RASTER 0x0001U /*!< Non-cluster grouping cores */ -#define RGX_CNTBLK_ID_HUB 0x0002U /*!< Non-cluster grouping cores */ -#define RGX_CNTBLK_ID_TORNADO 0x0003U /*!< XT cores */ -#define RGX_CNTBLK_ID_JONES 0x0004U /*!< S7 cores */ -#if defined(RGX_FEATURE_HWPERF_OCEANIC) -#define RGX_CNTBLK_ID_DIRECT_LAST 0x0003U /*!< Indirect blocks start from here */ -#else -#define RGX_CNTBLK_ID_DIRECT_LAST 0x0005U /*!< Indirect blocks start from here */ -#endif /* defined(RGX_FEATURE_HWPERF_OCEANIC) */ - -#define RGX_CNTBLK_ID_BF_DEPRECATED 0x0005U /*!< Doppler unit (DEPRECATED) */ -#define RGX_CNTBLK_ID_BT_DEPRECATED 0x0006U /*!< Doppler unit (DEPRECATED) */ -#define RGX_CNTBLK_ID_RT_DEPRECATED 0x0007U /*!< Doppler unit (DEPRECATED) */ -#define RGX_CNTBLK_ID_SH_DEPRECATED 0x0008U /*!< Ray tracing unit (DEPRECATED) */ - - -/*! Indirectly addressable counter blocks. DA blocks indicate counter blocks - * where the counter registers are directly accessible - */ -#define RGX_CNTBLK_ID_TPU_MCU0 0x0010U /*!< Addressable by Dust */ -#define RGX_CNTBLK_ID_TPU_MCU0_DA 0x8010U -#define RGX_CNTBLK_ID_TPU_MCU1 0x0011U -#define RGX_CNTBLK_ID_TPU_MCU1_DA 0x8011U -#define RGX_CNTBLK_ID_TPU_MCU2 0x0012U -#define RGX_CNTBLK_ID_TPU_MCU2_DA 0x8012U -#define RGX_CNTBLK_ID_TPU_MCU3 0x0013U -#define RGX_CNTBLK_ID_TPU_MCU3_DA 0x8013U -#define RGX_CNTBLK_ID_TPU_MCU4 0x0014U -#define RGX_CNTBLK_ID_TPU_MCU4_DA 0x8014U -#define RGX_CNTBLK_ID_TPU_MCU5 0x0015U -#define RGX_CNTBLK_ID_TPU_MCU5_DA 0x8015U -#define RGX_CNTBLK_ID_TPU_MCU6 0x0016U -#define RGX_CNTBLK_ID_TPU_MCU6_DA 0x8016U -#define RGX_CNTBLK_ID_TPU_MCU7 0x0017U -#define RGX_CNTBLK_ID_TPU_MCU7_DA 0x8017U -#define RGX_CNTBLK_ID_TPU_MCU_ALL 0x4010U -#define RGX_CNTBLK_ID_TPU_MCU_ALL_DA 0xC010U - -#define RGX_CNTBLK_ID_USC0 0x0020U /*!< Addressable by Cluster */ -#define RGX_CNTBLK_ID_USC0_DA 0x8020U -#define RGX_CNTBLK_ID_USC1 0x0021U -#define RGX_CNTBLK_ID_USC1_DA 0x8021U -#define RGX_CNTBLK_ID_USC2 0x0022U -#define RGX_CNTBLK_ID_USC2_DA 0x8022U -#define RGX_CNTBLK_ID_USC3 0x0023U -#define RGX_CNTBLK_ID_USC3_DA 0x8023U -#define RGX_CNTBLK_ID_USC4 0x0024U -#define RGX_CNTBLK_ID_USC4_DA 0x8024U -#define RGX_CNTBLK_ID_USC5 0x0025U -#define RGX_CNTBLK_ID_USC5_DA 0x8025U -#define RGX_CNTBLK_ID_USC6 0x0026U -#define RGX_CNTBLK_ID_USC6_DA 0x8026U -#define RGX_CNTBLK_ID_USC7 0x0027U -#define RGX_CNTBLK_ID_USC7_DA 0x8027U -#define RGX_CNTBLK_ID_USC8 0x0028U -#define RGX_CNTBLK_ID_USC8_DA 0x8028U -#define RGX_CNTBLK_ID_USC9 0x0029U -#define RGX_CNTBLK_ID_USC9_DA 0x8029U -#define RGX_CNTBLK_ID_USC10 0x002AU -#define RGX_CNTBLK_ID_USC10_DA 0x802AU -#define RGX_CNTBLK_ID_USC11 0x002BU -#define RGX_CNTBLK_ID_USC11_DA 0x802BU -#define RGX_CNTBLK_ID_USC12 0x002CU -#define RGX_CNTBLK_ID_USC12_DA 0x802CU -#define RGX_CNTBLK_ID_USC13 0x002DU -#define RGX_CNTBLK_ID_USC13_DA 0x802DU -#define RGX_CNTBLK_ID_USC14 0x002EU -#define RGX_CNTBLK_ID_USC14_DA 0x802EU -#define RGX_CNTBLK_ID_USC15 0x002FU -#define RGX_CNTBLK_ID_USC15_DA 0x802FU -#define RGX_CNTBLK_ID_USC_ALL 0x4020U -#define RGX_CNTBLK_ID_USC_ALL_DA 0xC020U - -#define RGX_CNTBLK_ID_TEXAS0 0x0030U /*!< Addressable by Phantom in XT, Dust in S7 */ -#define RGX_CNTBLK_ID_TEXAS1 0x0031U -#define RGX_CNTBLK_ID_TEXAS2 0x0032U -#define RGX_CNTBLK_ID_TEXAS3 0x0033U -#define RGX_CNTBLK_ID_TEXAS4 0x0034U -#define RGX_CNTBLK_ID_TEXAS5 0x0035U -#define RGX_CNTBLK_ID_TEXAS6 0x0036U -#define RGX_CNTBLK_ID_TEXAS7 0x0037U -#define RGX_CNTBLK_ID_TEXAS_ALL 0x4030U - -#define RGX_CNTBLK_ID_RASTER0 0x0040U /*!< Addressable by Phantom, XT only */ -#define RGX_CNTBLK_ID_RASTER1 0x0041U -#define RGX_CNTBLK_ID_RASTER2 0x0042U -#define RGX_CNTBLK_ID_RASTER3 0x0043U -#define RGX_CNTBLK_ID_RASTER_ALL 0x4040U - -#define RGX_CNTBLK_ID_BLACKPEARL0 0x0050U /*!< Addressable by Phantom, S7, only */ -#define RGX_CNTBLK_ID_BLACKPEARL1 0x0051U -#define RGX_CNTBLK_ID_BLACKPEARL2 0x0052U -#define RGX_CNTBLK_ID_BLACKPEARL3 0x0053U -#define RGX_CNTBLK_ID_BLACKPEARL_ALL 0x4050U - -#define RGX_CNTBLK_ID_PBE0 0x0060U /*!< Addressable by Cluster in S7 and PBE2_IN_XE */ -#define RGX_CNTBLK_ID_PBE1 0x0061U -#define RGX_CNTBLK_ID_PBE2 0x0062U -#define RGX_CNTBLK_ID_PBE3 0x0063U -#define RGX_CNTBLK_ID_PBE4 0x0064U -#define RGX_CNTBLK_ID_PBE5 0x0065U -#define RGX_CNTBLK_ID_PBE6 0x0066U -#define RGX_CNTBLK_ID_PBE7 0x0067U -#define RGX_CNTBLK_ID_PBE8 0x0068U -#define RGX_CNTBLK_ID_PBE9 0x0069U -#define RGX_CNTBLK_ID_PBE10 0x006AU -#define RGX_CNTBLK_ID_PBE11 0x006BU -#define RGX_CNTBLK_ID_PBE12 0x006CU -#define RGX_CNTBLK_ID_PBE13 0x006DU -#define RGX_CNTBLK_ID_PBE14 0x006EU -#define RGX_CNTBLK_ID_PBE15 0x006FU -#define RGX_CNTBLK_ID_PBE_ALL 0x4060U - -#define RGX_CNTBLK_ID_LAST 0x0070U /*!< End of PBE block */ - -#define RGX_CNTBLK_ID_BX_TU0_DEPRECATED 0x0070U /*!< Doppler unit, DEPRECATED */ -#define RGX_CNTBLK_ID_BX_TU1_DEPRECATED 0x0071U -#define RGX_CNTBLK_ID_BX_TU2_DEPRECATED 0x0072U -#define RGX_CNTBLK_ID_BX_TU3_DEPRECATED 0x0073U -#define RGX_CNTBLK_ID_BX_TU_ALL_DEPRECATED 0x4070U - -#define RGX_CNTBLK_ID_CUSTOM0 0x70F0U -#define RGX_CNTBLK_ID_CUSTOM1 0x70F1U -#define RGX_CNTBLK_ID_CUSTOM2 0x70F2U -#define RGX_CNTBLK_ID_CUSTOM3 0x70F3U -#define RGX_CNTBLK_ID_CUSTOM4_FW 0x70F4U /*!< Custom block used for getting statistics held in the FW */ -#define RGX_CNTBLK_ID_CUSTOM_MASK 0x70FFU - - -/* Masks for the counter block ID*/ -#define RGX_CNTBLK_ID_UNIT_MASK (0x000FU) -#define RGX_CNTBLK_ID_GROUP_MASK (0x00F0U) -#define RGX_CNTBLK_ID_GROUP_SHIFT (4U) -#define RGX_CNTBLK_ID_MC_GPU_MASK (0x0F00U) -#define RGX_CNTBLK_ID_MC_GPU_SHIFT (8U) -#define RGX_CNTBLK_ID_UNIT_ALL_MASK (0x4000U) -#define RGX_CNTBLK_ID_DA_MASK (0x8000U) /*!< Block with directly accessible counter registers */ - -#define RGX_CNTBLK_INDIRECT_COUNT(_class, _n) ((IMG_UINT32)(RGX_CNTBLK_ID_ ## _class ## _n) - (IMG_UINT32)(RGX_CNTBLK_ID_ ## _class ## 0) + 1u) - -/*! The number of layout blocks defined with configurable multiplexed - * performance counters, hence excludes custom counter blocks. - */ -#if defined(RGX_FEATURE_HWPERF_OCEANIC) -#define RGX_HWPERF_MAX_MUX_BLKS (\ - (IMG_UINT32)RGX_CNTBLK_ID_DIRECT_LAST +\ - RGX_CNTBLK_INDIRECT_COUNT(PBE, 0) ) - -#define RGX_HWPERF_MAX_DA_BLKS (\ - (IMG_UINT32)RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 0)+\ - RGX_CNTBLK_INDIRECT_COUNT(USC, 0) ) - -#define RGX_HWPERF_MAX_DEFINED_BLKS (\ - (IMG_UINT32)RGX_HWPERF_MAX_MUX_BLKS +\ - RGX_HWPERF_MAX_DA_BLKS ) -#else -#define RGX_HWPERF_MAX_DEFINED_BLKS (\ - (IMG_UINT32)RGX_CNTBLK_ID_DIRECT_LAST +\ - RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7)+\ - RGX_CNTBLK_INDIRECT_COUNT(USC, 15)+\ - RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7)+\ - RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3)+\ - RGX_CNTBLK_INDIRECT_COUNT(BLACKPEARL, 3)+\ - RGX_CNTBLK_INDIRECT_COUNT(PBE, 15) ) -#define RGX_HWPERF_MAX_MUX_BLKS (\ - RGX_HWPERF_MAX_DEFINED_BLKS ) -#endif - -static_assert( - ((RGX_CNTBLK_ID_DIRECT_LAST + ((RGX_CNTBLK_ID_LAST & RGX_CNTBLK_ID_GROUP_MASK) >> RGX_CNTBLK_ID_GROUP_SHIFT)) <= RGX_HWPERF_MAX_BVNC_BLOCK_LEN), - "RGX_HWPERF_MAX_BVNC_BLOCK_LEN insufficient"); - -#define RGX_HWPERF_EVENT_MASK_VALUE(e) (IMG_UINT64_C(1) << (IMG_UINT32)(e)) - -#define RGX_CUSTOM_FW_CNTRS \ - X(TA_LOCAL_FL_SIZE, 0x0, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \ - \ - X(TA_GLOBAL_FL_SIZE, 0x1, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \ - \ - X(3D_LOCAL_FL_SIZE, 0x2, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \ - \ - X(3D_GLOBAL_FL_SIZE, 0x3, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \ - \ - X(ISP_TILES_IN_FLIGHT, 0x4, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DSPMKICK)) - -/*! Counter IDs for the firmware held statistics */ -typedef enum -{ -#define X(ctr, id, allow_mask) RGX_CUSTOM_FW_CNTR_##ctr = id, - RGX_CUSTOM_FW_CNTRS -#undef X - - /* always the last entry in the list */ - RGX_CUSTOM_FW_CNTR_LAST -} RGX_HWPERF_CUSTOM_FW_CNTR_ID; - -/*! Identifier for each counter in a performance counting module */ -typedef IMG_UINT32 RGX_HWPERF_CNTBLK_COUNTER_ID; - -#define RGX_CNTBLK_COUNTER0_ID 0U -#define RGX_CNTBLK_COUNTER1_ID 1U -#define RGX_CNTBLK_COUNTER2_ID 2U -#define RGX_CNTBLK_COUNTER3_ID 3U -#define RGX_CNTBLK_COUNTER4_ID 4U -#define RGX_CNTBLK_COUNTER5_ID 5U - /* MAX value used in server handling of counter config arrays */ -#define RGX_CNTBLK_MUX_COUNTERS_MAX 6U - - -/* sets all the bits from bit _b1 to _b2, in a IMG_UINT64 type */ -#define MASK_RANGE_IMPL(b1, b2) ((IMG_UINT64)((IMG_UINT64_C(1) << ((IMG_UINT32)(b2)-(IMG_UINT32)(b1) + 1U)) - 1U) << (IMG_UINT32)(b1)) -#define MASK_RANGE(R) MASK_RANGE_IMPL(R##_FIRST_TYPE, R##_LAST_TYPE) -#define RGX_HWPERF_HOST_EVENT_MASK_VALUE(e) (IMG_UINT32_C(1) << (e)) - -/*! Mask macros for use with RGXCtrlHWPerf() API. - */ -#define RGX_HWPERF_EVENT_MASK_NONE (IMG_UINT64_C(0x0000000000000000)) -#define RGX_HWPERF_EVENT_MASK_DEFAULT RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_FWACT) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG) | \ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG) -#define RGX_HWPERF_EVENT_MASK_ALL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF)) - -/*! HWPerf Firmware event masks - * @par - * All FW Start/End/Debug (SED) events. */ -#define RGX_HWPERF_EVENT_MASK_FW_SED (MASK_RANGE(RGX_HWPERF_FW_EVENT_RANGE)) - -#define RGX_HWPERF_EVENT_MASK_FW_UFO (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_UFO)) -#define RGX_HWPERF_EVENT_MASK_FW_CSW (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_START) |\ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_FINISHED)) -/*! All FW events. */ -#define RGX_HWPERF_EVENT_MASK_ALL_FW (RGX_HWPERF_EVENT_MASK_FW_SED |\ - RGX_HWPERF_EVENT_MASK_FW_UFO |\ - RGX_HWPERF_EVENT_MASK_FW_CSW) - -/*! HW Periodic events (1ms interval). */ -#define RGX_HWPERF_EVENT_MASK_HW_PERIODIC (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PERIODIC)) -/*! All HW Kick/Finish events. */ -#define RGX_HWPERF_EVENT_MASK_HW_KICKFINISH ((MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE0) |\ - MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE1)) &\ - ~(RGX_HWPERF_EVENT_MASK_HW_PERIODIC)) - -#define RGX_HWPERF_EVENT_MASK_ALL_HW (RGX_HWPERF_EVENT_MASK_HW_KICKFINISH |\ - RGX_HWPERF_EVENT_MASK_HW_PERIODIC) - -#define RGX_HWPERF_EVENT_MASK_ALL_PWR_EST (MASK_RANGE(RGX_HWPERF_PWR_EST_RANGE)) - -#define RGX_HWPERF_EVENT_MASK_ALL_PWR (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG) |\ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_GPU_STATE_CHG) |\ - RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG)) - -/*! HWPerf Host event masks - */ -#define RGX_HWPERF_EVENT_MASK_HOST_WORK_ENQ (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_ENQ)) -#define RGX_HWPERF_EVENT_MASK_HOST_ALL_UFO (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_UFO)) -#define RGX_HWPERF_EVENT_MASK_HOST_ALL_PWR (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_CLK_SYNC)) - - -/*! Type used in the RGX API RGXConfigMuxHWPerfCounters() */ -typedef struct -{ - /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */ - IMG_UINT16 ui16BlockID; - - /*! 4 or 6 LSBs used to select counters to configure in this block. */ - IMG_UINT8 ui8CounterSelect; - - /*! 4 or 6 LSBs used as MODE bits for the counters in the group. */ - IMG_UINT8 ui8Mode; - - /*! 5 or 6 LSBs used as the GROUP_SELECT value for the counter. */ - IMG_UINT8 aui8GroupSelect[RGX_CNTBLK_MUX_COUNTERS_MAX]; - - /*! 16 LSBs used as the BIT_SELECT value for the counter. */ - IMG_UINT16 aui16BitSelect[RGX_CNTBLK_MUX_COUNTERS_MAX]; - - /*! 14 LSBs used as the BATCH_MAX value for the counter. */ - IMG_UINT32 aui32BatchMax[RGX_CNTBLK_MUX_COUNTERS_MAX]; - - /*! 14 LSBs used as the BATCH_MIN value for the counter. */ - IMG_UINT32 aui32BatchMin[RGX_CNTBLK_MUX_COUNTERS_MAX]; -} UNCACHED_ALIGN RGX_HWPERF_CONFIG_MUX_CNTBLK; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_MUX_CNTBLK); - -/*! Type used in the RGX API RGXConfigHWPerfCounters() */ -typedef struct -{ - /*! Reserved for future use */ - IMG_UINT32 ui32Reserved; - - /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */ - IMG_UINT16 ui16BlockID; - - /*! Number of configured counters within this block */ - IMG_UINT16 ui16NumCounters; - - /*! Counter register values */ - IMG_UINT16 ui16Counters[RGX_CNTBLK_COUNTERS_MAX]; -} UNCACHED_ALIGN RGX_HWPERF_CONFIG_CNTBLK; - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_CNTBLK); - -#if defined(__cplusplus) -} -#endif - -#endif /* RGX_HWPERF_H_ */ - -/****************************************************************************** - End of file -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_common.h b/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_common.h deleted file mode 100644 index 0635a51578a89..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_common.h +++ /dev/null @@ -1,482 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HWPerf and Debug Types and Defines Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Common data types definitions for hardware performance API -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_HWPERF_COMMON_H_ -#define RGX_HWPERF_COMMON_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* These structures are used on both GPU and CPU and must be a size that is a - * multiple of 64 bits, 8 bytes to allow the FW to write 8 byte quantities at - * 8 byte aligned addresses. RGX_FW_STRUCT_*_ASSERT() is used to check this. - */ - -/****************************************************************************** - * Includes and Defines - *****************************************************************************/ - -#include "img_types.h" -#include "img_defs.h" - -#include "rgx_common_asserts.h" -#include "pvrsrv_tlcommon.h" - - -/****************************************************************************** - * Packet Event Type Enumerations - *****************************************************************************/ - -/*! Type used to encode the event that generated the packet. - * NOTE: When this type is updated the corresponding hwperfbin2json tool - * source needs to be updated as well. The RGX_HWPERF_EVENT_MASK_* macros will - * also need updating when adding new types. - * - * @par - * The event type values are incrementing integers for use as a shift ordinal - * in the event filtering process at the point events are generated. - * This scheme thus implies a limit of 63 event types. - */ - -typedef IMG_UINT32 RGX_HWPERF_EVENT_TYPE; - -#define RGX_HWPERF_INVALID 0x00U /*!< Invalid. Reserved value. */ - -/*! FW types 0x01..0x06 */ -#define RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE 0x01U - -#define RGX_HWPERF_FW_BGSTART 0x01U /*!< Background task processing start */ -#define RGX_HWPERF_FW_BGEND 0x02U /*!< Background task end */ -#define RGX_HWPERF_FW_IRQSTART 0x03U /*!< IRQ task processing start */ - -#define RGX_HWPERF_FW_IRQEND 0x04U /*!< IRQ task end */ -#define RGX_HWPERF_FW_DBGSTART 0x05U /*!< Debug event start */ -#define RGX_HWPERF_FW_DBGEND 0x06U /*!< Debug event end */ - -#define RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE 0x06U - -/*! HW types 0x07..0x19 */ -#define RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE 0x07U - -#define RGX_HWPERF_HW_PMOOM_TAPAUSE 0x07U /*!< TA Pause at PM Out of Memory */ - -#define RGX_HWPERF_HW_TAKICK 0x08U /*!< TA task started */ -#define RGX_HWPERF_HW_TAFINISHED 0x09U /*!< TA task finished */ -#define RGX_HWPERF_HW_3DTQKICK 0x0AU /*!< 3D TQ started */ -#define RGX_HWPERF_HW_3DKICK 0x0BU /*!< 3D task started */ -#define RGX_HWPERF_HW_3DFINISHED 0x0CU /*!< 3D task finished */ -#define RGX_HWPERF_HW_CDMKICK 0x0DU /*!< CDM task started */ -#define RGX_HWPERF_HW_CDMFINISHED 0x0EU /*!< CDM task finished */ -#define RGX_HWPERF_HW_TLAKICK 0x0FU /*!< TLA task started */ -#define RGX_HWPERF_HW_TLAFINISHED 0x10U /*!< TLS task finished */ -#define RGX_HWPERF_HW_3DSPMKICK 0x11U /*!< 3D SPM task started */ -#define RGX_HWPERF_HW_PERIODIC 0x12U /*!< Periodic event with updated HW counters */ -#define RGX_HWPERF_HW_RTUKICK 0x13U /*!< Reserved, future use */ -#define RGX_HWPERF_HW_RTUFINISHED 0x14U /*!< Reserved, future use */ -#define RGX_HWPERF_HW_SHGKICK 0x15U /*!< Reserved, future use */ -#define RGX_HWPERF_HW_SHGFINISHED 0x16U /*!< Reserved, future use */ -#define RGX_HWPERF_HW_3DTQFINISHED 0x17U /*!< 3D TQ finished */ -#define RGX_HWPERF_HW_3DSPMFINISHED 0x18U /*!< 3D SPM task finished */ - -#define RGX_HWPERF_HW_PMOOM_TARESUME 0x19U /*!< TA Resume after PM Out of Memory */ - -/*! HW_EVENT_RANGE0 used up. Use next empty range below to add new hardware events */ -#define RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE 0x19U - -/*! other types 0x1A..0x1F */ -#define RGX_HWPERF_CLKS_CHG 0x1AU /*!< Clock speed change in GPU */ -#define RGX_HWPERF_GPU_STATE_CHG 0x1BU /*!< GPU work state change */ - -/*! power types 0x20..0x27 */ -#define RGX_HWPERF_PWR_EST_RANGE_FIRST_TYPE 0x20U -#define RGX_HWPERF_PWR_EST_REQUEST 0x20U /*!< Power estimate requested (via GPIO) */ -#define RGX_HWPERF_PWR_EST_READY 0x21U /*!< Power estimate inputs ready */ -#define RGX_HWPERF_PWR_EST_RESULT 0x22U /*!< Power estimate result calculated */ -#define RGX_HWPERF_PWR_EST_RANGE_LAST_TYPE 0x22U - -#define RGX_HWPERF_PWR_CHG 0x23U /*!< Power state change */ - -/*! HW_EVENT_RANGE1 0x28..0x2F, for accommodating new hardware events */ -#define RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE 0x28U - -#define RGX_HWPERF_HW_TDMKICK 0x28U /*!< TDM task started */ -#define RGX_HWPERF_HW_TDMFINISHED 0x29U /*!< TDM task finished */ -#define RGX_HWPERF_HW_NULLKICK 0x2AU /*!< NULL event */ - -#define RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE 0x2AU - -/*! context switch types 0x30..0x31 */ -#define RGX_HWPERF_CSW_START 0x30U /*!< HW context store started */ -#define RGX_HWPERF_CSW_FINISHED 0x31U /*!< HW context store finished */ - -/*! DVFS events */ -#define RGX_HWPERF_DVFS 0x32U /*!< Dynamic voltage/frequency scaling events */ - -/*! firmware misc 0x38..0x39 */ -#define RGX_HWPERF_UFO 0x38U /*!< FW UFO Check / Update */ -#define RGX_HWPERF_FWACT 0x39U /*!< FW Activity notification */ - -/*! last */ -#define RGX_HWPERF_LAST_TYPE 0x3BU - -/*! This enumeration must have a value that is a power of two as it is - * used in masks and a filter bit field (currently 64 bits long). - */ -#define RGX_HWPERF_MAX_TYPE 0x40U - -static_assert(RGX_HWPERF_LAST_TYPE < RGX_HWPERF_MAX_TYPE, "Too many HWPerf event types"); - -/*! Macro used to check if an event type ID is present in the known set of hardware type events */ -#define HWPERF_PACKET_IS_HW_TYPE(_etype) (((_etype) >= RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE) || \ - ((_etype) >= RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE)) - -/*! Macro used to check if an event type ID is present in the known set of firmware type events */ -#define HWPERF_PACKET_IS_FW_TYPE(_etype) \ - ((_etype) >= RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE && \ - (_etype) <= RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE) - - -typedef enum { - RGX_HWPERF_HOST_INVALID = 0x00, /*!< Invalid, do not use. */ - RGX_HWPERF_HOST_ENQ = 0x01, /*!< ``0x01`` Kernel driver has queued GPU work. - See RGX_HWPERF_HOST_ENQ_DATA */ - RGX_HWPERF_HOST_UFO = 0x02, /*!< ``0x02`` UFO updated by the driver. - See RGX_HWPERF_HOST_UFO_DATA */ - RGX_HWPERF_HOST_ALLOC = 0x03, /*!< ``0x03`` Resource allocated. - See RGX_HWPERF_HOST_ALLOC_DATA */ - RGX_HWPERF_HOST_CLK_SYNC = 0x04, /*!< ``0x04`` GPU / Host clocks correlation data. - See RGX_HWPERF_HOST_CLK_SYNC_DATA */ - RGX_HWPERF_HOST_FREE = 0x05, /*!< ``0x05`` Resource freed, - See RGX_HWPERF_HOST_FREE_DATA */ - RGX_HWPERF_HOST_MODIFY = 0x06, /*!< ``0x06`` Resource modified / updated. - See RGX_HWPERF_HOST_MODIFY_DATA */ - RGX_HWPERF_HOST_DEV_INFO = 0x07, /*!< ``0x07`` Device Health status. - See RGX_HWPERF_HOST_DEV_INFO_DATA */ - RGX_HWPERF_HOST_INFO = 0x08, /*!< ``0x08`` Device memory usage information. - See RGX_HWPERF_HOST_INFO_DATA */ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT = 0x09, /*!< ``0x09`` Wait for sync event. - See RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA */ - RGX_HWPERF_HOST_SYNC_SW_TL_ADVANCE = 0x0A, /*!< ``0x0A`` Software timeline advanced. - See RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA */ - RGX_HWPERF_HOST_CLIENT_INFO = 0x0B, /*!< ``0x0B`` Additional client info. - See RGX_HWPERF_HOST_CLIENT_INFO_DATA */ - - /*! last */ - RGX_HWPERF_HOST_LAST_TYPE, - - /*! This enumeration must have a value that is a power of two as it is - * used in masks and a filter bit field (currently 32 bits long). - */ - RGX_HWPERF_HOST_MAX_TYPE = 0x20 -} RGX_HWPERF_HOST_EVENT_TYPE; - -/*!< The event type values are incrementing integers for use as a shift ordinal - * in the event filtering process at the point events are generated. - * This scheme thus implies a limit of 31 event types. - */ -static_assert(RGX_HWPERF_HOST_LAST_TYPE < RGX_HWPERF_HOST_MAX_TYPE, "Too many HWPerf host event types"); - - -/****************************************************************************** - * Packet Header Format Version 2 Types - *****************************************************************************/ - -/*! Major version number of the protocol in operation - */ -#define RGX_HWPERF_V2_FORMAT 2 - -/*! Signature ASCII pattern 'HWP2' found in the first word of a HWPerfV2 packet - */ -#define HWPERF_PACKET_V2_SIG 0x48575032 - -/*! Signature ASCII pattern 'HWPA' found in the first word of a HWPerfV2a packet - */ -#define HWPERF_PACKET_V2A_SIG 0x48575041 - -/*! Signature ASCII pattern 'HWPB' found in the first word of a HWPerfV2b packet - */ -#define HWPERF_PACKET_V2B_SIG 0x48575042 - -/*! Signature ASCII pattern 'HWPC' found in the first word of a HWPerfV2c packet - */ -#define HWPERF_PACKET_V2C_SIG 0x48575043 - -#define HWPERF_PACKET_ISVALID(_val) (((_val) == HWPERF_PACKET_V2_SIG) || ((_val) == HWPERF_PACKET_V2A_SIG) || ((_val) == HWPERF_PACKET_V2B_SIG) || ((_val) == HWPERF_PACKET_V2C_SIG)) -/*!< Checks that the packet signature is one of the supported versions */ - -/*! Type defines the HWPerf packet header common to all events. */ -typedef struct -{ - IMG_UINT32 ui32Sig; /*!< Always the value HWPERF_PACKET_SIG */ - IMG_UINT32 ui32Size; /*!< Overall packet size in bytes */ - IMG_UINT32 eTypeId; /*!< Event type information field */ - IMG_UINT32 ui32Ordinal; /*!< Sequential number of the packet */ - IMG_UINT64 ui64Timestamp; /*!< Event timestamp */ -} RGX_HWPERF_V2_PACKET_HDR, *RGX_PHWPERF_V2_PACKET_HDR; - -RGX_FW_STRUCT_OFFSET_ASSERT(RGX_HWPERF_V2_PACKET_HDR, ui64Timestamp); - -RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_HDR); - - -/*! Mask for use with the IMG_UINT32 ui32Size header field */ -#define RGX_HWPERF_SIZE_MASK 0xFFFFU - -/*! This macro defines an upper limit to which the size of the largest variable - * length HWPerf packet must fall within, currently 3KB. This constant may be - * used to allocate a buffer to hold one packet. - * This upper limit is policed by packet producing code. - */ -#define RGX_HWPERF_MAX_PACKET_SIZE 0xC00U - -/*! Defines an upper limit to the size of a variable length packet payload. - */ -#define RGX_HWPERF_MAX_PAYLOAD_SIZE ((IMG_UINT32)(RGX_HWPERF_MAX_PACKET_SIZE-\ - sizeof(RGX_HWPERF_V2_PACKET_HDR))) - -/*! Macro which takes a structure name and provides the packet size for - * a fixed size payload packet, rounded up to 8 bytes to align packets - * for 64 bit architectures. */ -#define RGX_HWPERF_MAKE_SIZE_FIXED(_struct) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN(sizeof(_struct), PVRSRVTL_PACKET_ALIGNMENT)))) - -/*! Macro which takes the number of bytes written in the data payload of a - * packet for a variable size payload packet, rounded up to 8 bytes to - * align packets for 64 bit architectures. */ -#define RGX_HWPERF_MAKE_SIZE_VARIABLE(_size) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&((IMG_UINT32)sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN((_size), PVRSRVTL_PACKET_ALIGNMENT)))) - -/*! Macro to obtain the size of the packet */ -#define RGX_HWPERF_GET_SIZE(_packet_addr) ((IMG_UINT16)(((_packet_addr)->ui32Size) & RGX_HWPERF_SIZE_MASK)) - -/*! Macro to obtain the size of the packet data */ -#define RGX_HWPERF_GET_DATA_SIZE(_packet_addr) (RGX_HWPERF_GET_SIZE(_packet_addr) - sizeof(RGX_HWPERF_V2_PACKET_HDR)) - -/*! Masks for use with the IMG_UINT32 eTypeId header field */ -#define RGX_HWPERF_TYPEID_MASK 0x0007FFFFU -#define RGX_HWPERF_TYPEID_EVENT_MASK 0x00007FFFU -#define RGX_HWPERF_TYPEID_THREAD_MASK 0x00008000U -#define RGX_HWPERF_TYPEID_STREAM_MASK 0x00070000U -#define RGX_HWPERF_TYPEID_META_DMA_MASK 0x00080000U -#define RGX_HWPERF_TYPEID_M_CORE_MASK 0x00100000U -#define RGX_HWPERF_TYPEID_OSID_MASK 0x07000000U - -/*! Meta thread macros for encoding the ID into the type field of a packet */ -#define RGX_HWPERF_META_THREAD_SHIFT 15U -#define RGX_HWPERF_META_THREAD_ID0 0x0U /*!< Meta Thread 0 ID */ -#define RGX_HWPERF_META_THREAD_ID1 0x1U /*!< Meta Thread 1 ID */ -/*! Obsolete, kept for source compatibility */ -#define RGX_HWPERF_META_THREAD_MASK 0x1U -/*! Stream ID macros for encoding the ID into the type field of a packet */ -#define RGX_HWPERF_STREAM_SHIFT 16U -/*! Meta DMA macro for encoding how the packet was generated into the type field of a packet */ -#define RGX_HWPERF_META_DMA_SHIFT 19U -/*! Bit-shift macro used for encoding multi-core data into the type field of a packet */ -#define RGX_HWPERF_M_CORE_SHIFT 20U -/*! OSID bit-shift macro used for encoding OSID into type field of a packet */ -#define RGX_HWPERF_OSID_SHIFT 24U -typedef enum { - RGX_HWPERF_STREAM_ID0_FW, /*!< Events from the Firmware/GPU */ - RGX_HWPERF_STREAM_ID1_HOST, /*!< Events from the Server host driver component */ - RGX_HWPERF_STREAM_ID2_CLIENT, /*!< Events from the Client host driver component */ - RGX_HWPERF_STREAM_ID_LAST, -} RGX_HWPERF_STREAM_ID; - -/* Checks if all stream IDs can fit under RGX_HWPERF_TYPEID_STREAM_MASK. */ -static_assert(((IMG_UINT32)RGX_HWPERF_STREAM_ID_LAST - 1U) < (RGX_HWPERF_TYPEID_STREAM_MASK >> RGX_HWPERF_STREAM_SHIFT), - "Too many HWPerf stream IDs."); - -/*! Compile-time value used to seed the Multi-Core (MC) bit in the typeID field. - * Only set by RGX_FIRMWARE builds. - */ -#if defined(RGX_FIRMWARE) -# if defined(RGX_FEATURE_GPU_MULTICORE_SUPPORT) -#define RGX_HWPERF_M_CORE_VALUE 1U /*!< 1 => Multi-core supported */ -# else -#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */ -# endif -#else -#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */ -#endif - -/*! Macros used to set the packet type and encode meta thread ID (0|1), - * HWPerf stream ID, multi-core capability and OSID within the typeID */ -#define RGX_HWPERF_MAKE_TYPEID(_stream, _type, _thread, _metadma, _osid)\ - ((IMG_UINT32) ((RGX_HWPERF_TYPEID_STREAM_MASK&((IMG_UINT32)(_stream) << RGX_HWPERF_STREAM_SHIFT)) | \ - (RGX_HWPERF_TYPEID_THREAD_MASK & ((IMG_UINT32)(_thread) << RGX_HWPERF_META_THREAD_SHIFT)) | \ - (RGX_HWPERF_TYPEID_EVENT_MASK & (IMG_UINT32)(_type)) | \ - (RGX_HWPERF_TYPEID_META_DMA_MASK & ((IMG_UINT32)(_metadma) << RGX_HWPERF_META_DMA_SHIFT)) | \ - (RGX_HWPERF_TYPEID_OSID_MASK & ((IMG_UINT32)(_osid) << RGX_HWPERF_OSID_SHIFT)) | \ - (RGX_HWPERF_TYPEID_M_CORE_MASK & ((IMG_UINT32)(RGX_HWPERF_M_CORE_VALUE) << RGX_HWPERF_M_CORE_SHIFT)))) - -/*! Obtains the event type that generated the packet */ -#define RGX_HWPERF_GET_TYPE(_packet_addr) (((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_EVENT_MASK) - -/*! Obtains the META Thread number that generated the packet */ -#define RGX_HWPERF_GET_THREAD_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_THREAD_MASK) >> RGX_HWPERF_META_THREAD_SHIFT)) - -/*! Determines if the packet generated contains multi-core data */ -#define RGX_HWPERF_GET_M_CORE(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_M_CORE_MASK) >> RGX_HWPERF_M_CORE_SHIFT) - -/*! Obtains the guest OSID which resulted in packet generation */ -#define RGX_HWPERF_GET_OSID(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_OSID_MASK) >> RGX_HWPERF_OSID_SHIFT) - -/*! Obtain stream id */ -#define RGX_HWPERF_GET_STREAM_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_STREAM_MASK) >> RGX_HWPERF_STREAM_SHIFT)) - -/*! Obtain information about how the packet was generated, which might affect payload total size */ -#define RGX_HWPERF_GET_META_DMA_INFO(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_META_DMA_MASK) >> RGX_HWPERF_META_DMA_SHIFT)) - -/*! Obtains a typed pointer to a packet given a buffer address */ -#define RGX_HWPERF_GET_PACKET(_buffer_addr) ((RGX_HWPERF_V2_PACKET_HDR *)(void *) (_buffer_addr)) -/*! Obtains a typed pointer to a data structure given a packet address */ -#define RGX_HWPERF_GET_PACKET_DATA_BYTES(_packet_addr) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR))) -/*! Obtains a typed pointer to the next packet given a packet address */ -#define RGX_HWPERF_GET_NEXT_PACKET(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), RGX_HWPERF_SIZE_MASK&((_packet_addr)->ui32Size)))) - -/*! Obtains a typed pointer to a packet header given the packet data address */ -#define RGX_HWPERF_GET_PACKET_HEADER(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), -(IMG_INT32)sizeof(RGX_HWPERF_V2_PACKET_HDR)))) - - -/****************************************************************************** - * Other Common Defines - *****************************************************************************/ - -/*! This macro is not a real array size, but indicates the array has a variable - * length only known at run-time but always contains at least 1 element. The - * final size of the array is deduced from the size field of a packet header. - */ -#define RGX_HWPERF_ONE_OR_MORE_ELEMENTS 1U - -/*! This macro is not a real array size, but indicates the array is optional - * and if present has a variable length only known at run-time. The final - * size of the array is deduced from the size field of a packet header. */ -#define RGX_HWPERF_ZERO_OR_MORE_ELEMENTS 1U - - -/*! Masks for use with the IMG_UINT32 ui32BlkInfo field */ -#define RGX_HWPERF_BLKINFO_BLKCOUNT_MASK 0xFFFF0000U -#define RGX_HWPERF_BLKINFO_BLKOFFSET_MASK 0x0000FFFFU - -/*! Shift for the NumBlocks and counter block offset field in ui32BlkInfo */ -#define RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT 16U -#define RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT 0U - -/*! Macro used to set the block info word as a combination of two 16-bit integers */ -#define RGX_HWPERF_MAKE_BLKINFO(_numblks, _blkoffset) ((IMG_UINT32) ((RGX_HWPERF_BLKINFO_BLKCOUNT_MASK&((_numblks) << RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)) | (RGX_HWPERF_BLKINFO_BLKOFFSET_MASK&((_blkoffset) << RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT)))) - -/*! Macro used to obtain the number of counter blocks present in the packet */ -#define RGX_HWPERF_GET_BLKCOUNT(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKCOUNT_MASK) >> RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT) - -/*! Obtains the offset of the counter block stream in the packet */ -#define RGX_HWPERF_GET_BLKOFFSET(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKOFFSET_MASK) >> RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT) - -/*! This macro gets the number of blocks depending on the packet version */ -#define RGX_HWPERF_GET_NUMBLKS(_sig, _packet_data, _numblocks) \ - do { \ - if (HWPERF_PACKET_V2B_SIG == (_sig) || HWPERF_PACKET_V2C_SIG == (_sig)) \ - { \ - (_numblocks) = RGX_HWPERF_GET_BLKCOUNT((_packet_data)->ui32BlkInfo);\ - } \ - else \ - { \ - IMG_UINT32 ui32VersionOffset = (((_sig) == HWPERF_PACKET_V2_SIG) ? 1 : 3);\ - (_numblocks) = *(IMG_UINT16 *)(IMG_OFFSET_ADDR(&(_packet_data)->ui32WorkTarget, ui32VersionOffset)); \ - } \ - } while (0) - -/*! This macro gets the counter stream pointer depending on the packet version */ -#define RGX_HWPERF_GET_CNTSTRM(_sig, _hw_packet_data, _cntstream_ptr) \ -{ \ - if (HWPERF_PACKET_V2B_SIG == (_sig) || HWPERF_PACKET_V2C_SIG == (_sig)) \ - { \ - (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR((_hw_packet_data), RGX_HWPERF_GET_BLKOFFSET((_hw_packet_data)->ui32BlkInfo))); \ - } \ - else \ - { \ - IMG_UINT32 ui32BlkStreamOffsetInWords = (((_sig) == HWPERF_PACKET_V2_SIG) ? 6 : 8); \ - (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR_DW((_hw_packet_data), ui32BlkStreamOffsetInWords)); \ - } \ -} - -/*! Masks for use with the IMG_UINT32 ui32KickInfo field */ -#define RGX_HWPERF_KICKINFO_KICKID_MASK 0x000000FFU - -/*! Shift for the Kick ID field in ui32KickInfo */ -#define RGX_HWPERF_KICKINFO_KICKID_SHIFT 0U - -/*! Macro used to set the kick info field. */ -#define RGX_HWPERF_MAKE_KICKINFO(_kickid) ((IMG_UINT32) (RGX_HWPERF_KICKINFO_KICKID_MASK&((_kickid) << RGX_HWPERF_KICKINFO_KICKID_SHIFT))) - -/*! Macro used to obtain the Kick ID if present in the packet */ -#define RGX_HWPERF_GET_KICKID(_kickinfo) (((_kickinfo) & RGX_HWPERF_KICKINFO_KICKID_MASK) >> RGX_HWPERF_KICKINFO_KICKID_SHIFT) - -/*! Masks for use with the RGX_HWPERF_UFO_EV eEvType field */ -#define RGX_HWPERF_UFO_STREAMSIZE_MASK 0xFFFF0000U -#define RGX_HWPERF_UFO_STREAMOFFSET_MASK 0x0000FFFFU - -/*! Shift for the UFO count and data stream fields */ -#define RGX_HWPERF_UFO_STREAMSIZE_SHIFT 16U -#define RGX_HWPERF_UFO_STREAMOFFSET_SHIFT 0U - -/*! Macro used to set UFO stream info word as a combination of two 16-bit integers */ -#define RGX_HWPERF_MAKE_UFOPKTINFO(_ssize, _soff) \ - ((IMG_UINT32) ((RGX_HWPERF_UFO_STREAMSIZE_MASK&((_ssize) << RGX_HWPERF_UFO_STREAMSIZE_SHIFT)) | \ - (RGX_HWPERF_UFO_STREAMOFFSET_MASK&((_soff) << RGX_HWPERF_UFO_STREAMOFFSET_SHIFT)))) - -/*! Macro used to obtain UFO count*/ -#define RGX_HWPERF_GET_UFO_STREAMSIZE(_streaminfo) \ - (((_streaminfo) & RGX_HWPERF_UFO_STREAMSIZE_MASK) >> RGX_HWPERF_UFO_STREAMSIZE_SHIFT) - -/*! Obtains the offset of the UFO stream in the packet */ -#define RGX_HWPERF_GET_UFO_STREAMOFFSET(_streaminfo) \ - (((_streaminfo) & RGX_HWPERF_UFO_STREAMOFFSET_MASK) >> RGX_HWPERF_UFO_STREAMOFFSET_SHIFT) - - -#if defined(__cplusplus) -} -#endif - -#endif /* RGX_HWPERF_COMMON_H_ */ - -/****************************************************************************** - End of file -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.c b/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.c deleted file mode 100644 index 268ba65207ae3..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.c +++ /dev/null @@ -1,635 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HW Performance counter table -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX HW Performance counters table -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgx_fwif_hwperf.h" -#if defined(__KERNEL__) -#include "rgxdefs_km.h" -#else -#include "rgxdefs.h" -#endif -#include "rgx_hwperf_table.h" - -/* Includes needed for PVRSRVKM (Server) context */ -# include "rgx_bvnc_defs_km.h" -# if defined(__KERNEL__) -# include "rgxdevice.h" -# endif - -/* Shared compile-time context ASSERT macro */ -#if defined(RGX_FIRMWARE) -# include "rgxfw_utils.h" -/* firmware context */ -# define DBG_ASSERT(_c) RGXFW_ASSERT((_c)) -#else -# include "pvr_debug.h" -/* host client/server context */ -# define DBG_ASSERT(_c) PVR_ASSERT((_c)) -#endif - -/***************************************************************************** - RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPowered() - - Referenced in gasCntBlkTypeModel[] table below and only called from - RGX_FIRMWARE run-time context. Therefore compile time configuration is used. - *****************************************************************************/ - -#if defined(RGX_FIRMWARE) && defined(RGX_FEATURE_PERFBUS) -# include "rgxfw_pow.h" -# include "rgxfw_utils.h" - -static bool rgxfw_hwperf_pow_st_direct(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId) -{ - PVR_UNREFERENCED_PARAMETER(eBlkType); - PVR_UNREFERENCED_PARAMETER(ui8UnitId); - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - /* S7XT: JONES */ - return (eBlkType == RGX_CNTBLK_ID_JONES); -#elif defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) - /* S6XT: TA, TORNADO */ - return true; -#else - /* S6 : TA, HUB, RASTER (RASCAL) */ - return (gsPowCtl.eUnitsPowState & RGXFW_POW_ST_RD_ON) != 0U; -#endif -} - -/* Only use conditional compilation when counter blocks appear in different - * islands for different Rogue families. - */ -static bool rgxfw_hwperf_pow_st_indirect(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId) -{ - IMG_UINT32 ui32NumDustsEnabled = rgxfw_pow_get_enabled_units(); - - if (((gsPowCtl.eUnitsPowState & RGXFW_POW_ST_RD_ON) != 0U) && - (ui32NumDustsEnabled > 0U)) - { -#if defined(RGX_FEATURE_DYNAMIC_DUST_POWER) - IMG_UINT32 ui32NumUscEnabled = ui32NumDustsEnabled*2U; - - switch (eBlkType) - { - case RGX_CNTBLK_ID_TPU_MCU0: /* S6 and S6XT */ -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - case RGX_CNTBLK_ID_TEXAS0: /* S7 */ -#endif - if (ui8UnitId >= ui32NumDustsEnabled) - { - return false; - } - break; - case RGX_CNTBLK_ID_USC0: /* S6, S6XT, S7 */ - case RGX_CNTBLK_ID_PBE0: /* S7, PBE2_IN_XE */ - /* Handle single cluster cores */ - if (ui8UnitId >= ((ui32NumUscEnabled > RGX_FEATURE_NUM_CLUSTERS) ? RGX_FEATURE_NUM_CLUSTERS : ui32NumUscEnabled)) - { - return false; - } - break; - case RGX_CNTBLK_ID_BLACKPEARL0: /* S7 */ - case RGX_CNTBLK_ID_RASTER0: /* S6XT */ -#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) - case RGX_CNTBLK_ID_TEXAS0: /* S6XT */ -#endif - if (ui8UnitId >= (RGX_REQ_NUM_PHANTOMS(ui32NumUscEnabled))) - { - return false; - } - break; - default: - RGXFW_ASSERT(false); /* should never get here, table error */ - break; - } -#else - /* Always true, no fused DUSTs, all powered so do not check unit */ - PVR_UNREFERENCED_PARAMETER(eBlkType); - PVR_UNREFERENCED_PARAMETER(ui8UnitId); -#endif - } - else - { - return false; - } - return true; -} - -#else /* !defined(RGX_FIRMWARE) || !defined(RGX_FEATURE_PERFBUS) */ - -# define rgxfw_hwperf_pow_st_direct ((void*)NULL) -# define rgxfw_hwperf_pow_st_indirect ((void*)NULL) - -#endif /* !defined(RGX_FIRMWARE) || !defined(RGX_FEATURE_PERFBUS) */ - -/***************************************************************************** - RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPowered() end - *****************************************************************************/ - -/***************************************************************************** - RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPresent() start - - Referenced in gasCntBlkTypeModel[] table below and called from all build - contexts: - RGX_FIRMWARE, PVRSRVCTL (UM) and PVRSRVKM (Server). - - Therefore each function has two implementations, one for compile time and one - run time configuration depending on the context. The functions will inform the - caller whether this block is valid for this particular RGX device. Other - run-time dependent data is returned in psRtInfo for the caller to use. - *****************************************************************************/ - -/* Used for block types: USC */ -static IMG_BOOL rgx_hwperf_blk_present_perfbus(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - DBG_ASSERT(psBlkTypeDesc != NULL); - DBG_ASSERT(psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_USC0); - -#if defined(__KERNEL__) /* Server context */ - PVR_ASSERT(pvDev_km != NULL); - PVR_ASSERT(pvRtInfo != NULL); - { - RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo = (RGX_HWPERF_CNTBLK_RT_INFO *) pvRtInfo; - const PVRSRV_RGXDEV_INFO *psDevInfo = (const PVRSRV_RGXDEV_INFO *)pvDev_km; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PERFBUS)) - { - psRtInfo->ui32NumUnits = RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) ? RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS) : 0; - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - } -#else /* FW context */ - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); -# if defined(RGX_FEATURE_PERFBUS) - return IMG_TRUE; -# endif -#endif - return IMG_FALSE; -} - -/* Used for block types: Direct RASTERISATION, HUB */ -static IMG_BOOL rgx_hwperf_blk_present_not_clustergrouping(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - DBG_ASSERT(psBlkTypeDesc != NULL); - DBG_ASSERT((psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_RASTER) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_HUB)); - -#if defined(__KERNEL__) /* Server context */ - PVR_ASSERT(pvDev_km != NULL); - PVR_ASSERT(pvRtInfo != NULL); - { - RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo = (RGX_HWPERF_CNTBLK_RT_INFO *) pvRtInfo; - const PVRSRV_RGXDEV_INFO *psDevInfo = (const PVRSRV_RGXDEV_INFO *)pvDev_km; - if ((!RGX_IS_FEATURE_SUPPORTED(psDevInfo, CLUSTER_GROUPING)) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PERFBUS))) - { - psRtInfo->ui32NumUnits = 1; - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - } -#else /* FW context */ - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); -# if !defined(RGX_FEATURE_CLUSTER_GROUPING) && defined(RGX_FEATURE_PERFBUS) - return IMG_TRUE; -# endif -#endif - return IMG_FALSE; -} - -#if defined(__KERNEL__) /* Server context */ -static IMG_UINT32 rgx_units_indirect_by_phantom(const PVRSRV_DEVICE_FEATURE_CONFIG *psFeatCfg) -{ - /* Run-time math for RGX_HWPERF_INDIRECT_BY_PHANTOM */ - return ((psFeatCfg->ui64Features & RGX_FEATURE_CLUSTER_GROUPING_BIT_MASK) == 0) ? 1 - : (psFeatCfg->ui32FeaturesValues[RGX_FEATURE_NUM_CLUSTERS_IDX]+3)/4; -} - -static IMG_UINT32 rgx_units_phantom_indirect_by_dust(const PVRSRV_DEVICE_FEATURE_CONFIG *psFeatCfg) -{ - /* Run-time math for RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST */ - return MAX((psFeatCfg->ui32FeaturesValues[RGX_FEATURE_NUM_CLUSTERS_IDX]>>1),1); -} - -static IMG_UINT32 rgx_units_phantom_indirect_by_cluster(const PVRSRV_DEVICE_FEATURE_CONFIG *psFeatCfg) -{ - /* Run-time math for RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER */ - return psFeatCfg->ui32FeaturesValues[RGX_FEATURE_NUM_CLUSTERS_IDX]; -} -#endif /* defined(__KERNEL__) */ - -/* Used for block types: TORNADO, TEXAS, Indirect RASTERISATION */ -static IMG_BOOL rgx_hwperf_blk_present_xttop(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - DBG_ASSERT(psBlkTypeDesc != NULL); - DBG_ASSERT((psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TORNADO) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TEXAS0) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_RASTER0)); - -#if defined(__KERNEL__) /* Server context */ - PVR_ASSERT(pvDev_km != NULL); - PVR_ASSERT(pvRtInfo != NULL); - { - RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo = (RGX_HWPERF_CNTBLK_RT_INFO *) pvRtInfo; - const PVRSRV_RGXDEV_INFO *psDevInfo = (const PVRSRV_RGXDEV_INFO *)pvDev_km; - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XT_TOP_INFRASTRUCTURE)) - { - if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TORNADO) - { - psRtInfo->ui32NumUnits = 1; - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TEXAS0) - { - psRtInfo->ui32NumUnits = rgx_units_indirect_by_phantom(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = RGX_CR_TEXAS_PERF_INDIRECT; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_RASTER0) - { - psRtInfo->ui32NumUnits = rgx_units_indirect_by_phantom(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - } - } -#else /* FW context */ - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); -# if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) && defined(RGX_FEATURE_PERFBUS) - return IMG_TRUE; -# endif -#endif - return IMG_FALSE; -} - -/* Used for block types: JONES, TPU_MCU, TEXAS, BLACKPERL, PBE */ -static IMG_BOOL rgx_hwperf_blk_present_s7top(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - DBG_ASSERT(psBlkTypeDesc != NULL); - DBG_ASSERT((psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_JONES) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TPU_MCU0) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TEXAS0) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_BLACKPEARL0) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_PBE0)); - -#if defined(__KERNEL__) /* Server context */ - PVR_ASSERT(pvDev_km != NULL); - PVR_ASSERT(pvRtInfo != NULL); - { - RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo = (RGX_HWPERF_CNTBLK_RT_INFO *) pvRtInfo; - const PVRSRV_RGXDEV_INFO *psDevInfo = (const PVRSRV_RGXDEV_INFO *)pvDev_km; - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TPU_MCU0) - { - psRtInfo->ui32NumUnits = rgx_units_phantom_indirect_by_dust(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = RGX_CR_TPU_PERF_INDIRECT; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TEXAS0) - { - psRtInfo->ui32NumUnits = rgx_units_phantom_indirect_by_dust(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = RGX_CR_TEXAS3_PERF_INDIRECT; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_BLACKPEARL0) - { - psRtInfo->ui32NumUnits = rgx_units_indirect_by_phantom(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_PBE0) - { - psRtInfo->ui32NumUnits = rgx_units_phantom_indirect_by_cluster(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_JONES) - { - psRtInfo->ui32NumUnits = 1; - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - } - } -#else /* FW context */ - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); -# if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - return IMG_TRUE; -# else -# endif -#endif - return IMG_FALSE; -} - -/* Used for block types: TA, TPU_MCU. Also PBE when PBE2_IN_XE is present */ -static IMG_BOOL rgx_hwperf_blk_present_not_s7top(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - DBG_ASSERT(psBlkTypeDesc != NULL); - DBG_ASSERT((psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TA) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TPU_MCU0) || - (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_PBE0)); - -#if defined(__KERNEL__) /* Server context */ - PVR_ASSERT(pvDev_km != NULL); - PVR_ASSERT(pvRtInfo != NULL); - { - RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo = (RGX_HWPERF_CNTBLK_RT_INFO *) pvRtInfo; - const PVRSRV_RGXDEV_INFO *psDevInfo = (const PVRSRV_RGXDEV_INFO *)pvDev_km; - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE) && - RGX_IS_FEATURE_SUPPORTED(psDevInfo, PERFBUS)) - { - if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TA) - { - psRtInfo->ui32NumUnits = 1; - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_PBE0) - { - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, PBE2_IN_XE)) - { - /* PBE counters are not present on this config */ - return IMG_FALSE; - } - psRtInfo->ui32NumUnits = rgx_units_phantom_indirect_by_cluster(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = psBlkTypeDesc->ui32IndirectReg; - return IMG_TRUE; - } - else if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_TPU_MCU0) - { - psRtInfo->ui32NumUnits = rgx_units_phantom_indirect_by_dust(&psDevInfo->sDevFeatureCfg); - psRtInfo->ui32IndirectReg = RGX_CR_TPU_MCU_L0_PERF_INDIRECT; - return IMG_TRUE; - } - } - } -#else /* FW context */ - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); -# if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && defined(RGX_FEATURE_PERFBUS) -# if !defined(RGX_FEATURE_PBE2_IN_XE) - if (psBlkTypeDesc->ui32CntBlkIdBase == RGX_CNTBLK_ID_PBE0) - { - /* No support for PBE counters without PBE2_IN_XE */ - return IMG_FALSE; - } -# endif - return IMG_TRUE; -# endif -#endif - return IMG_FALSE; -} - -static IMG_BOOL rgx_hwperf_blk_present_check_s7top_or_not(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ -#if defined(__KERNEL__) - return (rgx_hwperf_blk_present_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo) - || rgx_hwperf_blk_present_not_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo)); - -#elif defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - return rgx_hwperf_blk_present_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo); - -#elif defined(RGX_FEATURE_PBE2_IN_XE) || defined(RGX_FEATURE_PERFBUS) - return rgx_hwperf_blk_present_not_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo); -#else - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); - return IMG_FALSE; -#endif -} - -static IMG_BOOL rgx_hwperf_blk_present_check_s7top_or_xttop(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ -#if defined(__KERNEL__) - return (rgx_hwperf_blk_present_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo) - || rgx_hwperf_blk_present_xttop(psBlkTypeDesc, pvDev_km, pvRtInfo)); - -#elif defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - return rgx_hwperf_blk_present_s7top(psBlkTypeDesc, pvDev_km, pvRtInfo); - -#elif defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) - return rgx_hwperf_blk_present_xttop(psBlkTypeDesc, pvDev_km, pvRtInfo); -#else - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); - return IMG_FALSE; -#endif -} - -#if !defined(__KERNEL__) /* Firmware or User-mode context */ -static IMG_BOOL rgx_hwperf_blk_present_false(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, void *pvRtInfo) -{ - PVR_UNREFERENCED_PARAMETER(psBlkTypeDesc); - PVR_UNREFERENCED_PARAMETER(pvDev_km); - PVR_UNREFERENCED_PARAMETER(pvRtInfo); - - /* Some functions not used on some BVNCs, silence compiler warnings */ - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_perfbus); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_not_clustergrouping); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_xttop); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_s7top); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_not_s7top); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_check_s7top_or_not); - PVR_UNREFERENCED_PARAMETER(rgx_hwperf_blk_present_check_s7top_or_xttop); - - return IMG_FALSE; -} - -/* Used to instantiate a null row in the block type model table below where the - * block is not supported for a given build BVNC in firmware/user mode context. - * This is needed as the blockid to block type lookup uses the table as well - * and clients may try to access blocks not in the hardware. */ -#define RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(_blkid) {_blkid, 0, 0, 0, 0, 0, 0, 0, 0, #_blkid, NULL, rgx_hwperf_blk_present_false} - -#endif - - -/***************************************************************************** - RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPresent() end - *****************************************************************************/ - -#if defined(__KERNEL__) /* Values will be calculated at run-time */ -#define RGX_HWPERF_NUM_BLOCK_UNITS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC -#define RGX_INDIRECT_REG_TEXAS 0xFFFFFFFF -#define RGX_INDIRECT_REG_TPU 0xFFFFFFFF - -#elif defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) -#define RGX_HWPERF_NUM_BLOCK_UNITS RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST -#define RGX_INDIRECT_REG_TEXAS RGX_CR_TEXAS3_PERF_INDIRECT -#define RGX_INDIRECT_REG_TPU RGX_CR_TPU_PERF_INDIRECT - -#else - -#if defined(RGX_FEATURE_PERFBUS) -#define RGX_INDIRECT_REG_TPU RGX_CR_TPU_MCU_L0_PERF_INDIRECT -#endif - -#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) -#define RGX_HWPERF_NUM_BLOCK_UNITS RGX_HWPERF_INDIRECT_BY_PHANTOM -#define RGX_INDIRECT_REG_TEXAS RGX_CR_TEXAS_PERF_INDIRECT -#endif - -#endif - - -/***************************************************************************** - RGXFW_HWPERF_CNTBLK_TYPE_MODEL gasCntBlkTypeModel[] table - - This table holds the entries for the performance counter block type model. - Where the block is not present on an RGX device in question the - pfnIsBlkPresent() returns false, if valid and present it returns true. - Columns in the table with a ** indicate the value is a default and the - value returned in RGX_HWPERF_CNTBLK_RT_INFO when calling pfnIsBlkPresent() - should be used at runtime by the caller. These columns are only valid for - compile time BVNC configured contexts. - - Order of table rows must match order of counter block IDs in the enumeration - RGX_HWPERF_CNTBLK_ID. - *****************************************************************************/ - -static const RGXFW_HWPERF_CNTBLK_TYPE_MODEL gasCntBlkTypeModel[] = -{ - /* ui32CntBlkIdBase, ui32IndirectReg, ui32PerfReg, ui32Select0BaseReg, ui32Counter0BaseReg ui8NumCounters, ui32NumUnits**, ui8SelectRegModeShift, ui8SelectRegOffsetShift, pfnIsBlkPowered pfnIsBlkPresent - * pszBlockNameComment, */ - /*RGX_CNTBLK_ID_TA*/ -#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && defined(RGX_FEATURE_PERFBUS) || defined(__KERNEL__) - {RGX_CNTBLK_ID_TA, 0, /* direct */ RGX_CR_TA_PERF, RGX_CR_TA_PERF_SELECT0, RGX_CR_TA_PERF_COUNTER_0, 4, 1, 21, 3, "RGX_CR_TA_PERF", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present_not_s7top }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_TA), -#endif - - /*RGX_CNTBLK_ID_RASTER*/ -#if !defined(RGX_FEATURE_CLUSTER_GROUPING) && defined(RGX_FEATURE_PERFBUS) || defined(__KERNEL__) - {RGX_CNTBLK_ID_RASTER, 0, /* direct */ RGX_CR_RASTERISATION_PERF, RGX_CR_RASTERISATION_PERF_SELECT0, RGX_CR_RASTERISATION_PERF_COUNTER_0, 4, 1, 21, 3, "RGX_CR_RASTERISATION_PERF", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present_not_clustergrouping }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_RASTER), -#endif - - /*RGX_CNTBLK_ID_HUB*/ -#if !defined(RGX_FEATURE_CLUSTER_GROUPING) && defined(RGX_FEATURE_PERFBUS) || defined(__KERNEL__) - {RGX_CNTBLK_ID_HUB, 0, /* direct */ RGX_CR_HUB_BIFPMCACHE_PERF, RGX_CR_HUB_BIFPMCACHE_PERF_SELECT0, RGX_CR_HUB_BIFPMCACHE_PERF_COUNTER_0, 4, 1, 21, 3, "RGX_CR_HUB_BIFPMCACHE_PERF", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present_not_clustergrouping }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_HUB), -#endif - - /*RGX_CNTBLK_ID_TORNADO*/ -#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) || defined(__KERNEL__) - {RGX_CNTBLK_ID_TORNADO, 0, /* direct */ RGX_CR_TORNADO_PERF, RGX_CR_TORNADO_PERF_SELECT0, RGX_CR_TORNADO_PERF_COUNTER_0, 4, 1, 21, 4, "RGX_CR_TORNADO_PERF", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present_xttop }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_TORNADO), -#endif - - /*RGX_CNTBLK_ID_JONES*/ -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) || defined(__KERNEL__) - {RGX_CNTBLK_ID_JONES, 0, /* direct */ RGX_CR_JONES_PERF, RGX_CR_JONES_PERF_SELECT0, RGX_CR_JONES_PERF_COUNTER_0, 4, 1, 21, 3, "RGX_CR_JONES_PERF", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present_s7top }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_JONES), -#endif - - /*RGX_CNTBLK_ID_TPU_MCU0*/ -#if defined(__KERNEL__) || (defined(RGX_FEATURE_PERFBUS) && !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)) || defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) - {RGX_CNTBLK_ID_TPU_MCU0, RGX_INDIRECT_REG_TPU, RGX_CR_TPU_MCU_L0_PERF, RGX_CR_TPU_MCU_L0_PERF_SELECT0, RGX_CR_TPU_MCU_L0_PERF_COUNTER_0, 4, RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST, 21, 3, "RGX_CR_TPU_MCU_L0_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_check_s7top_or_not }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_TPU_MCU0), -#endif - - /*RGX_CNTBLK_ID_USC0*/ -#if defined(RGX_FEATURE_PERFBUS) || defined(__KERNEL__) - {RGX_CNTBLK_ID_USC0, RGX_CR_USC_PERF_INDIRECT, RGX_CR_USC_PERF, RGX_CR_USC_PERF_SELECT0, RGX_CR_USC_PERF_COUNTER_0, 4, RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER, 21, 3, "RGX_CR_USC_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_perfbus }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_USC0), -#endif - - /*RGX_CNTBLK_ID_TEXAS0*/ -#if defined(__KERNEL__) || defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) || defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) - {RGX_CNTBLK_ID_TEXAS0, RGX_INDIRECT_REG_TEXAS, RGX_CR_TEXAS_PERF, RGX_CR_TEXAS_PERF_SELECT0, RGX_CR_TEXAS_PERF_COUNTER_0, 6, RGX_HWPERF_NUM_BLOCK_UNITS, 31, 3, "RGX_CR_TEXAS_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_check_s7top_or_xttop }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_TEXAS0), -#endif - - /*RGX_CNTBLK_ID_RASTER0*/ -#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) || defined(__KERNEL__) - {RGX_CNTBLK_ID_RASTER0, RGX_CR_RASTERISATION_PERF_INDIRECT, RGX_CR_RASTERISATION_PERF, RGX_CR_RASTERISATION_PERF_SELECT0, RGX_CR_RASTERISATION_PERF_COUNTER_0, 4, RGX_HWPERF_INDIRECT_BY_PHANTOM, 21, 3, "RGX_CR_RASTERISATION_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_xttop }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_RASTER0), -#endif - - /*RGX_CNTBLK_ID_BLACKPEARL0*/ -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) || defined(__KERNEL__) - {RGX_CNTBLK_ID_BLACKPEARL0, RGX_CR_BLACKPEARL_PERF_INDIRECT, RGX_CR_BLACKPEARL_PERF, RGX_CR_BLACKPEARL_PERF_SELECT0, RGX_CR_BLACKPEARL_PERF_COUNTER_0, 6, RGX_HWPERF_INDIRECT_BY_PHANTOM, 21, 3, "RGX_CR_BLACKPEARL_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_s7top }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_BLACKPEARL0), -#endif - - /*RGX_CNTBLK_ID_PBE0*/ -#if defined(__KERNEL__) || defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) || defined(RGX_FEATURE_PBE2_IN_XE) - {RGX_CNTBLK_ID_PBE0, RGX_CR_PBE_PERF_INDIRECT, RGX_CR_PBE_PERF, RGX_CR_PBE_PERF_SELECT0, RGX_CR_PBE_PERF_COUNTER_0, 4, RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER, 21, 3, "RGX_CR_PBE_PERF", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present_check_s7top_or_not }, -#else - RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(RGX_CNTBLK_ID_PBE0), -#endif -}; - - -IMG_INTERNAL IMG_UINT32 -RGXGetHWPerfBlockConfig(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL **ppsModel) -{ - *ppsModel = gasCntBlkTypeModel; - return ARRAY_SIZE(gasCntBlkTypeModel); -} - -/****************************************************************************** - End of file (rgx_hwperf_table.c) - ******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.h b/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.h deleted file mode 100644 index 449885cdcb64c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_hwperf_table.h +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title HWPerf counter table header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Utility functions used internally for HWPerf data retrieval -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_HWPERF_TABLE_H -#define RGX_HWPERF_TABLE_H - -#include "img_types.h" -#include "img_defs.h" -#include "rgx_fwif_hwperf.h" -#if defined(__KERNEL__) -#include "rgxdevice.h" -#endif -/*****************************************************************************/ - -/* Forward declaration */ -typedef struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_ RGXFW_HWPERF_CNTBLK_TYPE_MODEL; - -/* Function pointer type for functions to check dynamic power state of - * counter block instance. Used only in firmware. */ -typedef bool (*PFN_RGXFW_HWPERF_CNTBLK_POWERED)( - RGX_HWPERF_CNTBLK_ID eBlkType, - IMG_UINT8 ui8UnitId); - -#if defined(__KERNEL__) -/* Counter block run-time info */ -typedef struct -{ - IMG_UINT32 ui32IndirectReg; /* 0 if direct type otherwise the indirect control register to select indirect unit */ - IMG_UINT32 ui32NumUnits; /* Number of instances of this block type in the core */ -} RGX_HWPERF_CNTBLK_RT_INFO; -#endif - -/* Function pointer type for functions to check block is valid and present - * on that RGX Device at runtime. It may have compile logic or run-time - * logic depending on where the code executes: server, srvinit or firmware. - * Values in the psRtInfo output parameter are only valid if true returned. - */ -typedef IMG_BOOL (*PFN_RGXFW_HWPERF_CNTBLK_PRESENT)( - const struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_* psBlkTypeDesc, - const void *pvDev_km, - void *pvRtInfo); - -/* This structure encodes properties of a type of performance counter block. - * The structure is sometimes referred to as a block type descriptor. These - * properties contained in this structure represent the columns in the block - * type model table variable below. These values vary depending on the build - * BVNC and core type. - * Each direct block has a unique type descriptor and each indirect group has - * a type descriptor. - */ -struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_ -{ - /* Could use RGXFW_ALIGN_DCACHEL here but then we would waste 40% of the cache line? */ - IMG_UINT32 ui32CntBlkIdBase; /* The starting block id for this block type */ - IMG_UINT32 ui32IndirectReg; /* 0 if direct type otherwise the indirect control register to select indirect unit */ - IMG_UINT32 ui32PerfReg; /* RGX_CR_*_PERF register for this block type */ - IMG_UINT32 ui32Select0BaseReg; /* RGX_CR_*_PERF_SELECT0 register for this block type */ - IMG_UINT32 ui32Counter0BaseReg; /* RGX_CR_*_PERF_COUNTER_0 register for this block type */ - IMG_UINT8 ui8NumCounters; /* Number of counters in this block type */ - IMG_UINT8 ui8NumUnits; /* Number of instances of this block type in the core */ - IMG_UINT8 ui8SelectRegModeShift; /* Mode field shift value of select registers */ - IMG_UINT8 ui8SelectRegOffsetShift; /* Interval between select registers, either 8 bytes or 16, hence << 3 or << 4 */ - const IMG_CHAR *pszBlockNameComment; /* Name of the PERF register. Used while dumping the perf counters to pdumps */ - PFN_RGXFW_HWPERF_CNTBLK_POWERED pfnIsBlkPowered; /* A function to determine dynamic power state for the block type */ - PFN_RGXFW_HWPERF_CNTBLK_PRESENT pfnIsBlkPresent; /* A function to determine presence on RGX Device at run-time */ -}; - -/*****************************************************************************/ - -IMG_INTERNAL IMG_UINT32 RGXGetHWPerfBlockConfig(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL **ppsModel); - -#endif /* RGX_HWPERF_TABLE_H */ - -/****************************************************************************** - End of file (rgx_hwperf_table.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_memallocflags.h b/drivers/gpu/drm/img-rogue/1.17/rgx_memallocflags.h deleted file mode 100644 index e26f42c4f935a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_memallocflags.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title RGX device specific memory allocation flags -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_MEMALLOCFLAGS_H -#define RGX_MEMALLOCFLAGS_H - - -/* Include pvrsrv layer header as the flags below are used in the device - * field defined in this header inside Services code. - * See PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK */ -#include "pvrsrv_memallocflags.h" - - -/* Device specific MMU flags */ -#define PMMETA_PROTECT (1U << 0) /*!< Memory that only the PM and Meta can access */ -#define FIRMWARE_CACHED (1U << 1) /*!< Memory that is cached in META/MIPS */ - - -#endif /* RGX_MEMALLOCFLAGS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_meta.h b/drivers/gpu/drm/img-rogue/1.17/rgx_meta.h deleted file mode 100644 index bdff11ffbdc1e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_meta.h +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX META definitions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX META helper definitions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_META_H) -#define RGX_META_H - - -/***** The META HW register definitions in the file are updated manually *****/ - - -#include "img_defs.h" -#include "km/rgxdefs_km.h" - - -/****************************************************************************** -* META registers and MACROS -******************************************************************************/ -#define META_CR_CTRLREG_BASE(T) (0x04800000U + (0x1000U*(T))) - -#define META_CR_TXPRIVEXT (0x048000E8) -#define META_CR_TXPRIVEXT_MINIM_EN (IMG_UINT32_C(0x1) << 7) - -#define META_CR_SYSC_JTAG_THREAD (0x04830030) -#define META_CR_SYSC_JTAG_THREAD_PRIV_EN (0x00000004) - -#define META_CR_PERF_COUNT0 (0x0480FFE0) -#define META_CR_PERF_COUNT1 (0x0480FFE8) -#define META_CR_PERF_COUNT_CTRL_SHIFT (28) -#define META_CR_PERF_COUNT_CTRL_MASK (0xF0000000) -#define META_CR_PERF_COUNT_CTRL_DCACHEHITS (IMG_UINT32_C(0x8) << META_CR_PERF_COUNT_CTRL_SHIFT) -#define META_CR_PERF_COUNT_CTRL_ICACHEHITS (IMG_UINT32_C(0x9) << META_CR_PERF_COUNT_CTRL_SHIFT) -#define META_CR_PERF_COUNT_CTRL_ICACHEMISS (IMG_UINT32_C(0xA) << META_CR_PERF_COUNT_CTRL_SHIFT) -#define META_CR_PERF_COUNT_CTRL_ICORE (IMG_UINT32_C(0xD) << META_CR_PERF_COUNT_CTRL_SHIFT) -#define META_CR_PERF_COUNT_THR_SHIFT (24) -#define META_CR_PERF_COUNT_THR_MASK (0x0F000000) -#define META_CR_PERF_COUNT_THR_0 (IMG_UINT32_C(0x1) << META_CR_PERF_COUNT_THR_SHIFT) -#define META_CR_PERF_COUNT_THR_1 (IMG_UINT32_C(0x2) << META_CR_PERF_COUNT_THR_SHIFT) - -#define META_CR_TxVECINT_BHALT (0x04820500) -#define META_CR_PERF_ICORE0 (0x0480FFD0) -#define META_CR_PERF_ICORE1 (0x0480FFD8) -#define META_CR_PERF_ICORE_DCACHEMISS (0x8) - -#define META_CR_PERF_COUNT(CTRL, THR) ((META_CR_PERF_COUNT_CTRL_##CTRL << META_CR_PERF_COUNT_CTRL_SHIFT) | \ - (THR << META_CR_PERF_COUNT_THR_SHIFT)) - -#define META_CR_TXUXXRXDT_OFFSET (META_CR_CTRLREG_BASE(0U) + 0x0000FFF0U) -#define META_CR_TXUXXRXRQ_OFFSET (META_CR_CTRLREG_BASE(0U) + 0x0000FFF8U) - -#define META_CR_TXUXXRXRQ_DREADY_BIT (0x80000000U) /* Poll for done */ -#define META_CR_TXUXXRXRQ_RDnWR_BIT (0x00010000U) /* Set for read */ -#define META_CR_TXUXXRXRQ_TX_S (12) -#define META_CR_TXUXXRXRQ_RX_S (4) -#define META_CR_TXUXXRXRQ_UXX_S (0) - -#define META_CR_TXUIN_ID (0x0) /* Internal ctrl regs */ -#define META_CR_TXUD0_ID (0x1) /* Data unit regs */ -#define META_CR_TXUD1_ID (0x2) /* Data unit regs */ -#define META_CR_TXUA0_ID (0x3) /* Address unit regs */ -#define META_CR_TXUA1_ID (0x4) /* Address unit regs */ -#define META_CR_TXUPC_ID (0x5) /* PC registers */ - -/* Macros to calculate register access values */ -#define META_CR_CORE_REG(Thr, RegNum, Unit) (((IMG_UINT32)(Thr) << META_CR_TXUXXRXRQ_TX_S) | \ - ((IMG_UINT32)(RegNum) << META_CR_TXUXXRXRQ_RX_S) | \ - ((IMG_UINT32)(Unit) << META_CR_TXUXXRXRQ_UXX_S)) - -#define META_CR_THR0_PC META_CR_CORE_REG(0, 0, META_CR_TXUPC_ID) -#define META_CR_THR0_PCX META_CR_CORE_REG(0, 1, META_CR_TXUPC_ID) -#define META_CR_THR0_SP META_CR_CORE_REG(0, 0, META_CR_TXUA0_ID) - -#define META_CR_THR1_PC META_CR_CORE_REG(1, 0, META_CR_TXUPC_ID) -#define META_CR_THR1_PCX META_CR_CORE_REG(1, 1, META_CR_TXUPC_ID) -#define META_CR_THR1_SP META_CR_CORE_REG(1, 0, META_CR_TXUA0_ID) - -#define SP_ACCESS(Thread) META_CR_CORE_REG(Thread, 0, META_CR_TXUA0_ID) -#define PC_ACCESS(Thread) META_CR_CORE_REG(Thread, 0, META_CR_TXUPC_ID) - -#define META_CR_COREREG_ENABLE (0x0000000U) -#define META_CR_COREREG_STATUS (0x0000010U) -#define META_CR_COREREG_DEFR (0x00000A0U) -#define META_CR_COREREG_PRIVEXT (0x00000E8U) - -#define META_CR_T0ENABLE_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_ENABLE) -#define META_CR_T0STATUS_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_STATUS) -#define META_CR_T0DEFR_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_DEFR) -#define META_CR_T0PRIVEXT_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_PRIVEXT) - -#define META_CR_T1ENABLE_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_ENABLE) -#define META_CR_T1STATUS_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_STATUS) -#define META_CR_T1DEFR_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_DEFR) -#define META_CR_T1PRIVEXT_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_PRIVEXT) - -#define META_CR_TXENABLE_ENABLE_BIT (0x00000001U) /* Set if running */ -#define META_CR_TXSTATUS_PRIV (0x00020000U) -#define META_CR_TXPRIVEXT_MINIM (0x00000080U) - -#define META_MEM_GLOBAL_RANGE_BIT (0x80000000U) - -#define META_CR_TXCLKCTRL (0x048000B0) -#define META_CR_TXCLKCTRL_ALL_ON (0x55111111) -#define META_CR_TXCLKCTRL_ALL_AUTO (0xAA222222) - - -/****************************************************************************** -* META LDR Format -******************************************************************************/ -/* Block header structure */ -typedef struct -{ - IMG_UINT32 ui32DevID; - IMG_UINT32 ui32SLCode; - IMG_UINT32 ui32SLData; - IMG_UINT16 ui16PLCtrl; - IMG_UINT16 ui16CRC; - -} RGX_META_LDR_BLOCK_HDR; - -/* High level data stream block structure */ -typedef struct -{ - IMG_UINT16 ui16Cmd; - IMG_UINT16 ui16Length; - IMG_UINT32 ui32Next; - IMG_UINT32 aui32CmdData[4]; - -} RGX_META_LDR_L1_DATA_BLK; - -/* High level data stream block structure */ -typedef struct -{ - IMG_UINT16 ui16Tag; - IMG_UINT16 ui16Length; - IMG_UINT32 aui32BlockData[4]; - -} RGX_META_LDR_L2_DATA_BLK; - -/* Config command structure */ -typedef struct -{ - IMG_UINT32 ui32Type; - IMG_UINT32 aui32BlockData[4]; - -} RGX_META_LDR_CFG_BLK; - -/* Block type definitions */ -#define RGX_META_LDR_COMMENT_TYPE_MASK (0x0010U) -#define RGX_META_LDR_BLK_IS_COMMENT(X) ((X & RGX_META_LDR_COMMENT_TYPE_MASK) != 0U) - -/* Command definitions - * Value Name Description - * 0 LoadMem Load memory with binary data. - * 1 LoadCore Load a set of core registers. - * 2 LoadMMReg Load a set of memory mapped registers. - * 3 StartThreads Set each thread PC and SP, then enable threads. - * 4 ZeroMem Zeros a memory region. - * 5 Config Perform a configuration command. - */ -#define RGX_META_LDR_CMD_MASK (0x000FU) - -#define RGX_META_LDR_CMD_LOADMEM (0x0000U) -#define RGX_META_LDR_CMD_LOADCORE (0x0001U) -#define RGX_META_LDR_CMD_LOADMMREG (0x0002U) -#define RGX_META_LDR_CMD_START_THREADS (0x0003U) -#define RGX_META_LDR_CMD_ZEROMEM (0x0004U) -#define RGX_META_LDR_CMD_CONFIG (0x0005U) - -/* Config Command definitions - * Value Name Description - * 0 Pause Pause for x times 100 instructions - * 1 Read Read a value from register - No value return needed. - * Utilises effects of issuing reads to certain registers - * 2 Write Write to mem location - * 3 MemSet Set mem to value - * 4 MemCheck check mem for specific value. - */ -#define RGX_META_LDR_CFG_PAUSE (0x0000) -#define RGX_META_LDR_CFG_READ (0x0001) -#define RGX_META_LDR_CFG_WRITE (0x0002) -#define RGX_META_LDR_CFG_MEMSET (0x0003) -#define RGX_META_LDR_CFG_MEMCHECK (0x0004) - - -/****************************************************************************** -* RGX FW segmented MMU definitions -******************************************************************************/ -/* All threads can access the segment */ -#define RGXFW_SEGMMU_ALLTHRS (IMG_UINT32_C(0xf) << 8U) -/* Writable */ -#define RGXFW_SEGMMU_WRITEABLE (0x1U << 1U) -/* All threads can access and writable */ -#define RGXFW_SEGMMU_ALLTHRS_WRITEABLE (RGXFW_SEGMMU_ALLTHRS | RGXFW_SEGMMU_WRITEABLE) - -/* Direct map region 10 used for mapping GPU memory - max 8MB */ -#define RGXFW_SEGMMU_DMAP_GPU_ID (10U) -#define RGXFW_SEGMMU_DMAP_GPU_ADDR_START (0x07000000U) -#define RGXFW_SEGMMU_DMAP_GPU_MAX_SIZE (0x00800000U) - -/* Segment IDs */ -#define RGXFW_SEGMMU_DATA_ID (1U) -#define RGXFW_SEGMMU_BOOTLDR_ID (2U) -#define RGXFW_SEGMMU_TEXT_ID (RGXFW_SEGMMU_BOOTLDR_ID) - -/* - * SLC caching strategy in S7 and volcanic is emitted through the segment MMU. - * All the segments configured through the macro RGXFW_SEGMMU_OUTADDR_TOP are - * CACHED in the SLC. - * The interface has been kept the same to simplify the code changes. - * The bifdm argument is ignored (no longer relevant) in S7 and volcanic. - */ -#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(pers, slc_policy, mmu_ctx) ((((IMG_UINT64) ((pers) & 0x3U)) << 52) | \ - (((IMG_UINT64) ((mmu_ctx) & 0xFFU)) << 44) | \ - (((IMG_UINT64) ((slc_policy) & 0x1U)) << 40)) -#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED(mmu_ctx) RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(0x3U, 0x0U, mmu_ctx) -#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_UNCACHED(mmu_ctx) RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(0x0U, 0x1U, mmu_ctx) - -/* To configure the Page Catalog and BIF-DM fed into the BIF for Garten - * accesses through this segment - */ -#define RGXFW_SEGMMU_OUTADDR_TOP_SLC(pc, bifdm) (((IMG_UINT64)((IMG_UINT64)(pc) & 0xFU) << 44U) | \ - ((IMG_UINT64)((IMG_UINT64)(bifdm) & 0xFU) << 40U)) - -#define RGXFW_SEGMMU_META_BIFDM_ID (0x7U) -#if !defined(__KERNEL__) && defined(RGX_FEATURE_META) -#if defined(RGX_FEATURE_SLC_VIVT) -#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED -#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_UNCACHED RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_UNCACHED -#define RGXFW_SEGMMU_OUTADDR_TOP_META RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED -#else -#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED RGXFW_SEGMMU_OUTADDR_TOP_SLC -#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_UNCACHED RGXFW_SEGMMU_OUTADDR_TOP_SLC -#define RGXFW_SEGMMU_OUTADDR_TOP_META(pc) RGXFW_SEGMMU_OUTADDR_TOP_SLC(pc, RGXFW_SEGMMU_META_BIFDM_ID) -#endif -#endif - -/* META segments have 4kB minimum size */ -#define RGXFW_SEGMMU_ALIGN (0x1000U) - -/* Segmented MMU registers (n = segment id) */ -#define META_CR_MMCU_SEGMENTn_BASE(n) (0x04850000U + ((n)*0x10U)) -#define META_CR_MMCU_SEGMENTn_LIMIT(n) (0x04850004U + ((n)*0x10U)) -#define META_CR_MMCU_SEGMENTn_OUTA0(n) (0x04850008U + ((n)*0x10U)) -#define META_CR_MMCU_SEGMENTn_OUTA1(n) (0x0485000CU + ((n)*0x10U)) - -/* The following defines must be recalculated if the Meta MMU segments used - * to access Host-FW data are changed - * Current combinations are: - * - SLC uncached, META cached, FW base address 0x70000000 - * - SLC uncached, META uncached, FW base address 0xF0000000 - * - SLC cached, META cached, FW base address 0x10000000 - * - SLC cached, META uncached, FW base address 0x90000000 - */ -#define RGXFW_SEGMMU_DATA_BASE_ADDRESS (0x10000000U) -#define RGXFW_SEGMMU_DATA_META_CACHED (0x0U) -#define RGXFW_SEGMMU_DATA_META_UNCACHED (META_MEM_GLOBAL_RANGE_BIT) // 0x80000000 -#define RGXFW_SEGMMU_DATA_META_CACHE_MASK (META_MEM_GLOBAL_RANGE_BIT) -/* For non-VIVT SLCs the cacheability of the FW data in the SLC is selected in - * the PTEs for the FW data, not in the Meta Segment MMU, which means these - * defines have no real effect in those cases - */ -#define RGXFW_SEGMMU_DATA_VIVT_SLC_CACHED (0x0U) -#define RGXFW_SEGMMU_DATA_VIVT_SLC_UNCACHED (0x60000000U) -#define RGXFW_SEGMMU_DATA_VIVT_SLC_CACHE_MASK (0x60000000U) - - -#if defined(SECURE_FW_CODE_OSID) && defined(RGX_FEATURE_META) -#error "SECURE_FW_CODE_OSID is not supported on META cores" -#endif - - -/****************************************************************************** -* RGX FW Bootloader defaults -******************************************************************************/ -#define RGXFW_BOOTLDR_META_ADDR (0x40000000U) -#define RGXFW_BOOTLDR_DEVV_ADDR_0 (0xC0000000U) -#define RGXFW_BOOTLDR_DEVV_ADDR_1 (0x000000E1) -#define RGXFW_BOOTLDR_DEVV_ADDR ((((IMG_UINT64) RGXFW_BOOTLDR_DEVV_ADDR_1) << 32) | RGXFW_BOOTLDR_DEVV_ADDR_0) -#define RGXFW_BOOTLDR_LIMIT (0x1FFFF000) -#define RGXFW_MAX_BOOTLDR_OFFSET (0x1000) - -/* Bootloader configuration offset is in dwords (512 bytes) */ -#define RGXFW_BOOTLDR_CONF_OFFSET (0x80) - - -/****************************************************************************** -* RGX META Stack -******************************************************************************/ -#define RGX_META_STACK_SIZE (0x1000U) - -/****************************************************************************** - RGX META Core memory -******************************************************************************/ -/* code and data both map to the same physical memory */ -#define RGX_META_COREMEM_CODE_ADDR (0x80000000U) -#define RGX_META_COREMEM_DATA_ADDR (0x82000000U) -#define RGX_META_COREMEM_OFFSET_MASK (0x01ffffffU) - -#if defined(__KERNEL__) -#define RGX_META_IS_COREMEM_CODE(A, B) (((A) >= RGX_META_COREMEM_CODE_ADDR) && ((A) < (RGX_META_COREMEM_CODE_ADDR + (B)))) -#define RGX_META_IS_COREMEM_DATA(A, B) (((A) >= RGX_META_COREMEM_DATA_ADDR) && ((A) < (RGX_META_COREMEM_DATA_ADDR + (B)))) -#endif - -/****************************************************************************** -* 2nd thread -******************************************************************************/ -#define RGXFW_THR1_PC (0x18930000) -#define RGXFW_THR1_SP (0x78890000) - -/****************************************************************************** -* META compatibility -******************************************************************************/ - -#define META_CR_CORE_ID (0x04831000) -#define META_CR_CORE_ID_VER_SHIFT (16U) -#define META_CR_CORE_ID_VER_CLRMSK (0XFF00FFFFU) - -#if !defined(__KERNEL__) && defined(RGX_FEATURE_META) - - #if (RGX_FEATURE_META == MTP218) - #define RGX_CR_META_CORE_ID_VALUE 0x19 - #elif (RGX_FEATURE_META == MTP219) - #define RGX_CR_META_CORE_ID_VALUE 0x1E - #elif (RGX_FEATURE_META == LTP218) - #define RGX_CR_META_CORE_ID_VALUE 0x1C - #elif (RGX_FEATURE_META == LTP217) - #define RGX_CR_META_CORE_ID_VALUE 0x1F - #else - #error "Unknown META ID" - #endif -#else - - #define RGX_CR_META_MTP218_CORE_ID_VALUE 0x19 - #define RGX_CR_META_MTP219_CORE_ID_VALUE 0x1E - #define RGX_CR_META_LTP218_CORE_ID_VALUE 0x1C - #define RGX_CR_META_LTP217_CORE_ID_VALUE 0x1F - -#endif -#define RGXFW_PROCESSOR_META "META" - - -#endif /* RGX_META_H */ - -/****************************************************************************** - End of file (rgx_meta.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_mips.h b/drivers/gpu/drm/img-rogue/1.17/rgx_mips.h deleted file mode 100644 index c2f381882f749..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_mips.h +++ /dev/null @@ -1,374 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_mips.h -@Title -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Platform RGX -@Description RGX MIPS definitions, kernel/user space -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_MIPS_H) -#define RGX_MIPS_H - -/* - * Utility defines for memory management - */ -#define RGXMIPSFW_LOG2_PAGE_SIZE_4K (12) -#define RGXMIPSFW_PAGE_SIZE_4K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4K) -#define RGXMIPSFW_PAGE_MASK_4K (RGXMIPSFW_PAGE_SIZE_4K - 1) -#define RGXMIPSFW_LOG2_PAGE_SIZE_64K (16) -#define RGXMIPSFW_PAGE_SIZE_64K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_64K) -#define RGXMIPSFW_PAGE_MASK_64K (RGXMIPSFW_PAGE_SIZE_64K - 1) -#define RGXMIPSFW_LOG2_PAGE_SIZE_256K (18) -#define RGXMIPSFW_PAGE_SIZE_256K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_256K) -#define RGXMIPSFW_PAGE_MASK_256K (RGXMIPSFW_PAGE_SIZE_256K - 1) -#define RGXMIPSFW_LOG2_PAGE_SIZE_1MB (20) -#define RGXMIPSFW_PAGE_SIZE_1MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_1MB) -#define RGXMIPSFW_PAGE_MASK_1MB (RGXMIPSFW_PAGE_SIZE_1MB - 1) -#define RGXMIPSFW_LOG2_PAGE_SIZE_4MB (22) -#define RGXMIPSFW_PAGE_SIZE_4MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4MB) -#define RGXMIPSFW_PAGE_MASK_4MB (RGXMIPSFW_PAGE_SIZE_4MB - 1) -#define RGXMIPSFW_LOG2_PTE_ENTRY_SIZE (2) -/* log2 page table sizes dependent on FW heap size and page size (for each OS) */ -#define RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_4K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE) -#define RGXMIPSFW_LOG2_PAGETABLE_SIZE_64K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_64K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE) -/* Maximum number of page table pages (both Host and MIPS pages) */ -#define RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES (4) -/* Total number of TLB entries */ -#define RGXMIPSFW_NUMBER_OF_TLB_ENTRIES (16) -/* "Uncached" caching policy */ -#define RGXMIPSFW_UNCACHED_CACHE_POLICY (0X00000002U) -/* "Write-back write-allocate" caching policy */ -#define RGXMIPSFW_WRITEBACK_CACHE_POLICY (0X00000003) -/* "Write-through no write-allocate" caching policy */ -#define RGXMIPSFW_WRITETHROUGH_CACHE_POLICY (0X00000001) -/* Cached policy used by MIPS in case of physical bus on 32 bit */ -#define RGXMIPSFW_CACHED_POLICY (RGXMIPSFW_WRITEBACK_CACHE_POLICY) -/* Cached policy used by MIPS in case of physical bus on more than 32 bit */ -#define RGXMIPSFW_CACHED_POLICY_ABOVE_32BIT (RGXMIPSFW_WRITETHROUGH_CACHE_POLICY) -/* Total number of Remap entries */ -#define RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES (2 * RGXMIPSFW_NUMBER_OF_TLB_ENTRIES) - - -/* - * MIPS EntryLo/PTE format - */ - -#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_SHIFT (31U) -#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_CLRMSK (0X7FFFFFFF) -#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN (0X80000000U) - -#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_SHIFT (30U) -#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_CLRMSK (0XBFFFFFFF) -#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_EN (0X40000000U) - -/* Page Frame Number */ -#define RGXMIPSFW_ENTRYLO_PFN_SHIFT (6) -#define RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT (12) -/* Mask used for the MIPS Page Table in case of physical bus on 32 bit */ -#define RGXMIPSFW_ENTRYLO_PFN_MASK (0x03FFFFC0) -#define RGXMIPSFW_ENTRYLO_PFN_SIZE (20) -/* Mask used for the MIPS Page Table in case of physical bus on more than 32 bit */ -#define RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT (0x3FFFFFC0U) -#define RGXMIPSFW_ENTRYLO_PFN_SIZE_ABOVE_32BIT (24) -#define RGXMIPSFW_ADDR_TO_ENTRYLO_PFN_RSHIFT (RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT - \ - RGXMIPSFW_ENTRYLO_PFN_SHIFT) - -#define RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT (3U) -#define RGXMIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK (0XFFFFFFC7U) - -#define RGXMIPSFW_ENTRYLO_DIRTY_SHIFT (2U) -#define RGXMIPSFW_ENTRYLO_DIRTY_CLRMSK (0XFFFFFFFB) -#define RGXMIPSFW_ENTRYLO_DIRTY_EN (0X00000004U) - -#define RGXMIPSFW_ENTRYLO_VALID_SHIFT (1U) -#define RGXMIPSFW_ENTRYLO_VALID_CLRMSK (0XFFFFFFFD) -#define RGXMIPSFW_ENTRYLO_VALID_EN (0X00000002U) - -#define RGXMIPSFW_ENTRYLO_GLOBAL_SHIFT (0U) -#define RGXMIPSFW_ENTRYLO_GLOBAL_CLRMSK (0XFFFFFFFE) -#define RGXMIPSFW_ENTRYLO_GLOBAL_EN (0X00000001U) - -#define RGXMIPSFW_ENTRYLO_DVG (RGXMIPSFW_ENTRYLO_DIRTY_EN | \ - RGXMIPSFW_ENTRYLO_VALID_EN | \ - RGXMIPSFW_ENTRYLO_GLOBAL_EN) -#define RGXMIPSFW_ENTRYLO_UNCACHED (RGXMIPSFW_UNCACHED_CACHE_POLICY << \ - RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT) -#define RGXMIPSFW_ENTRYLO_DVG_UNCACHED (RGXMIPSFW_ENTRYLO_DVG | RGXMIPSFW_ENTRYLO_UNCACHED) - - -/* Remap Range Config Addr Out */ -/* These defines refer to the upper half of the Remap Range Config register */ -#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_MASK (0x0FFFFFF0) -#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT (4) /* wrt upper half of the register */ -#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT (12) -#define RGXMIPSFW_ADDR_TO_RR_ADDR_OUT_RSHIFT (RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT - \ - RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT) - -#if defined(SECURE_FW_CODE_OSID) && (SECURE_FW_CODE_OSID + 1 > 2) -#define MIPS_FW_CODE_OSID (SECURE_FW_CODE_OSID) -#elif defined(SECURE_FW_CODE_OSID) -#define MIPS_FW_CODE_OSID (1U) -#endif - - -/* - * Pages to trampoline problematic physical addresses: - * - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN : 0x1FC0_0000 - * - RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN : 0x1FC0_1000 - * - RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN : 0x1FC0_2000 - * - (benign trampoline) : 0x1FC0_3000 - * that would otherwise be erroneously remapped by the MIPS wrapper - * (see "Firmware virtual layout and remap configuration" section below) - */ - -#define RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES (2) -#define RGXMIPSFW_TRAMPOLINE_NUMPAGES (1U << RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES) -#define RGXMIPSFW_TRAMPOLINE_SIZE (RGXMIPSFW_TRAMPOLINE_NUMPAGES << RGXMIPSFW_LOG2_PAGE_SIZE_4K) -#define RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE (RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES + RGXMIPSFW_LOG2_PAGE_SIZE_4K) - -#define RGXMIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN) -#define RGXMIPSFW_TRAMPOLINE_OFFSET(a) (a - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN) - -#define RGXMIPSFW_SENSITIVE_ADDR(a) (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN == (~((1UL << RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE)-1U) & a)) - -/* - * Firmware virtual layout and remap configuration - */ -/* - * For each remap region we define: - * - the virtual base used by the Firmware to access code/data through that region - * - the microAptivAP physical address correspondent to the virtual base address, - * used as input address and remapped to the actual physical address - * - log2 of size of the region remapped by the MIPS wrapper, i.e. number of bits from - * the bottom of the base input address that survive onto the output address - * (this defines both the alignment and the maximum size of the remapped region) - * - one or more code/data segments within the remapped region - */ - -/* Boot remap setup */ -#define RGXMIPSFW_BOOT_REMAP_VIRTUAL_BASE (0xBFC00000) -#define RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN (0x1FC00000U) -#define RGXMIPSFW_BOOT_REMAP_LOG2_SEGMENT_SIZE (12) -#define RGXMIPSFW_BOOT_NMI_CODE_VIRTUAL_BASE (RGXMIPSFW_BOOT_REMAP_VIRTUAL_BASE) - -/* Data remap setup */ -#define RGXMIPSFW_DATA_REMAP_VIRTUAL_BASE (0xBFC01000) -#define RGXMIPSFW_DATA_CACHED_REMAP_VIRTUAL_BASE (0x9FC01000) -#define RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN (0x1FC01000U) -#define RGXMIPSFW_DATA_REMAP_LOG2_SEGMENT_SIZE (12) -#define RGXMIPSFW_BOOT_NMI_DATA_VIRTUAL_BASE (RGXMIPSFW_DATA_REMAP_VIRTUAL_BASE) - -/* Code remap setup */ -#define RGXMIPSFW_CODE_REMAP_VIRTUAL_BASE (0x9FC02000) -#define RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN (0x1FC02000U) -#define RGXMIPSFW_CODE_REMAP_LOG2_SEGMENT_SIZE (12) -#define RGXMIPSFW_EXCEPTIONS_VIRTUAL_BASE (RGXMIPSFW_CODE_REMAP_VIRTUAL_BASE) - -/* Permanent mappings setup */ -#define RGXMIPSFW_PT_VIRTUAL_BASE (0xCF000000) -#define RGXMIPSFW_REGISTERS_VIRTUAL_BASE (0xCF800000) -#define RGXMIPSFW_STACK_VIRTUAL_BASE (0xCF600000) - - -/* - * Bootloader configuration data - */ -/* Bootloader configuration offset (where RGXMIPSFW_BOOT_DATA lives) - * within the bootloader/NMI data page */ -#define RGXMIPSFW_BOOTLDR_CONF_OFFSET (0x0U) - - -/* - * NMI shared data - */ -/* Base address of the shared data within the bootloader/NMI data page */ -#define RGXMIPSFW_NMI_SHARED_DATA_BASE (0x100) -/* Size used by Debug dump data */ -#define RGXMIPSFW_NMI_SHARED_SIZE (0x2B0) -/* Offsets in the NMI shared area in 32-bit words */ -#define RGXMIPSFW_NMI_SYNC_FLAG_OFFSET (0x0) -#define RGXMIPSFW_NMI_STATE_OFFSET (0x1) -#define RGXMIPSFW_NMI_ERROR_STATE_SET (0x1) - -/* - * MIPS boot stage - */ -#define RGXMIPSFW_BOOT_STAGE_OFFSET (0x400) - -/* - * MIPS private data in the bootloader data page. - * Memory below this offset is used by the FW only, no interface data allowed. - */ -#define RGXMIPSFW_PRIVATE_DATA_OFFSET (0x800) - - -/* The things that follow are excluded when compiling assembly sources */ -#if !defined(RGXMIPSFW_ASSEMBLY_CODE) -#include "img_types.h" -#include "km/rgxdefs_km.h" - -typedef struct -{ - IMG_UINT64 ui64StackPhyAddr; - IMG_UINT64 ui64RegBase; - IMG_UINT64 aui64PTPhyAddr[RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES]; - IMG_UINT32 ui32PTLog2PageSize; - IMG_UINT32 ui32PTNumPages; - IMG_UINT32 ui32Reserved1; - IMG_UINT32 ui32Reserved2; -} RGXMIPSFW_BOOT_DATA; - -#define RGXMIPSFW_GET_OFFSET_IN_DWORDS(offset) (offset / sizeof(IMG_UINT32)) -#define RGXMIPSFW_GET_OFFSET_IN_QWORDS(offset) (offset / sizeof(IMG_UINT64)) - -/* Used for compatibility checks */ -#define RGXMIPSFW_ARCHTYPE_VER_CLRMSK (0xFFFFE3FFU) -#define RGXMIPSFW_ARCHTYPE_VER_SHIFT (10U) -#define RGXMIPSFW_CORE_ID_VALUE (0x001U) -#define RGXFW_PROCESSOR_MIPS "MIPS" - -/* microAptivAP cache line size */ -#define RGXMIPSFW_MICROAPTIVEAP_CACHELINE_SIZE (16U) - -/* The SOCIF transactions are identified with the top 16 bits of the physical address emitted by the MIPS */ -#define RGXMIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN (16U) - -/* Values to put in the MIPS selectors for performance counters */ -#define RGXMIPSFW_PERF_COUNT_CTRL_ICACHE_ACCESSES_C0 (9U) /* Icache accesses in COUNTER0 */ -#define RGXMIPSFW_PERF_COUNT_CTRL_ICACHE_MISSES_C1 (9U) /* Icache misses in COUNTER1 */ - -#define RGXMIPSFW_PERF_COUNT_CTRL_DCACHE_ACCESSES_C0 (10U) /* Dcache accesses in COUNTER0 */ -#define RGXMIPSFW_PERF_COUNT_CTRL_DCACHE_MISSES_C1 (11U) /* Dcache misses in COUNTER1 */ - -#define RGXMIPSFW_PERF_COUNT_CTRL_ITLB_INSTR_ACCESSES_C0 (5U) /* ITLB instruction accesses in COUNTER0 */ -#define RGXMIPSFW_PERF_COUNT_CTRL_JTLB_INSTR_MISSES_C1 (7U) /* JTLB instruction accesses misses in COUNTER1 */ - -#define RGXMIPSFW_PERF_COUNT_CTRL_INSTR_COMPLETED_C0 (1U) /* Instructions completed in COUNTER0 */ -#define RGXMIPSFW_PERF_COUNT_CTRL_JTLB_DATA_MISSES_C1 (8U) /* JTLB data misses in COUNTER1 */ - -#define RGXMIPSFW_PERF_COUNT_CTRL_EVENT_SHIFT (5U) /* Shift for the Event field in the MIPS perf ctrl registers */ -/* Additional flags for performance counters. See MIPS manual for further reference */ -#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_USER_MODE (8U) -#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_KERNEL_MODE (2U) -#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_EXL (1U) - - -#define RGXMIPSFW_C0_NBHWIRQ 8 - -/* Macros to decode C0_Cause register */ -#define RGXMIPSFW_C0_CAUSE_EXCCODE(CAUSE) (((CAUSE) & 0x7cU) >> 2U) -#define RGXMIPSFW_C0_CAUSE_EXCCODE_FWERROR 9 -/* Use only when Coprocessor Unusable exception */ -#define RGXMIPSFW_C0_CAUSE_UNUSABLE_UNIT(CAUSE) (((CAUSE) >> 28U) & 0x3U) -#define RGXMIPSFW_C0_CAUSE_PENDING_HWIRQ(CAUSE) (((CAUSE) & 0x3fc00) >> 10) -#define RGXMIPSFW_C0_CAUSE_FDCIPENDING (1UL << 21) -#define RGXMIPSFW_C0_CAUSE_IV (1UL << 23) -#define RGXMIPSFW_C0_CAUSE_IC (1UL << 25) -#define RGXMIPSFW_C0_CAUSE_PCIPENDING (1UL << 26) -#define RGXMIPSFW_C0_CAUSE_TIPENDING (1UL << 30) -#define RGXMIPSFW_C0_CAUSE_BRANCH_DELAY (1UL << 31) - -/* Macros to decode C0_Debug register */ -#define RGXMIPSFW_C0_DEBUG_EXCCODE(DEBUG) (((DEBUG) >> 10U) & 0x1fU) -#define RGXMIPSFW_C0_DEBUG_DSS (1UL << 0) -#define RGXMIPSFW_C0_DEBUG_DBP (1UL << 1) -#define RGXMIPSFW_C0_DEBUG_DDBL (1UL << 2) -#define RGXMIPSFW_C0_DEBUG_DDBS (1UL << 3) -#define RGXMIPSFW_C0_DEBUG_DIB (1UL << 4) -#define RGXMIPSFW_C0_DEBUG_DINT (1UL << 5) -#define RGXMIPSFW_C0_DEBUG_DIBIMPR (1UL << 6) -#define RGXMIPSFW_C0_DEBUG_DDBLIMPR (1UL << 18) -#define RGXMIPSFW_C0_DEBUG_DDBSIMPR (1UL << 19) -#define RGXMIPSFW_C0_DEBUG_IEXI (1UL << 20) -#define RGXMIPSFW_C0_DEBUG_DBUSEP (1UL << 21) -#define RGXMIPSFW_C0_DEBUG_CACHEEP (1UL << 22) -#define RGXMIPSFW_C0_DEBUG_MCHECKP (1UL << 23) -#define RGXMIPSFW_C0_DEBUG_IBUSEP (1UL << 24) -#define RGXMIPSFW_C0_DEBUG_DM (1UL << 30) -#define RGXMIPSFW_C0_DEBUG_DBD (1UL << 31) - -/* Macros to decode TLB entries */ -#define RGXMIPSFW_TLB_GET_MASK(PAGE_MASK) (((PAGE_MASK) >> 13) & 0XFFFFU) -#define RGXMIPSFW_TLB_GET_PAGE_SIZE(PAGE_MASK) ((((PAGE_MASK) | 0x1FFFU) + 1U) >> 11U) /* page size in KB */ -#define RGXMIPSFW_TLB_GET_PAGE_MASK(PAGE_SIZE) ((((PAGE_SIZE) << 11) - 1) & ~0x7FF) /* page size in KB */ -#define RGXMIPSFW_TLB_GET_VPN2(ENTRY_HI) ((ENTRY_HI) >> 13) -#define RGXMIPSFW_TLB_GET_COHERENCY(ENTRY_LO) (((ENTRY_LO) >> 3) & 0x7U) -#define RGXMIPSFW_TLB_GET_PFN(ENTRY_LO) (((ENTRY_LO) >> 6) & 0XFFFFFU) -/* GET_PA uses a non-standard PFN mask for 36 bit addresses */ -#define RGXMIPSFW_TLB_GET_PA(ENTRY_LO) (((IMG_UINT64)(ENTRY_LO) & RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT) << 6) -#define RGXMIPSFW_TLB_GET_INHIBIT(ENTRY_LO) (((ENTRY_LO) >> 30) & 0x3U) -#define RGXMIPSFW_TLB_GET_DGV(ENTRY_LO) ((ENTRY_LO) & 0x7U) -#define RGXMIPSFW_TLB_GLOBAL (1U) -#define RGXMIPSFW_TLB_VALID (1U << 1) -#define RGXMIPSFW_TLB_DIRTY (1U << 2) -#define RGXMIPSFW_TLB_XI (1U << 30) -#define RGXMIPSFW_TLB_RI (1U << 31) - -typedef struct { - IMG_UINT32 ui32TLBPageMask; - IMG_UINT32 ui32TLBHi; - IMG_UINT32 ui32TLBLo0; - IMG_UINT32 ui32TLBLo1; -} RGX_MIPS_TLB_ENTRY; - -typedef struct { - IMG_UINT32 ui32RemapAddrIn; /* always 4k aligned */ - IMG_UINT32 ui32RemapAddrOut; /* always 4k aligned */ - IMG_UINT32 ui32RemapRegionSize; -} RGX_MIPS_REMAP_ENTRY; - -typedef struct { - IMG_UINT32 ui32ErrorState; /* This must come first in the structure */ - IMG_UINT32 ui32ErrorEPC; - IMG_UINT32 ui32StatusRegister; - IMG_UINT32 ui32CauseRegister; - IMG_UINT32 ui32BadRegister; - IMG_UINT32 ui32EPC; - IMG_UINT32 ui32SP; - IMG_UINT32 ui32Debug; - IMG_UINT32 ui32DEPC; - IMG_UINT32 ui32BadInstr; - IMG_UINT32 ui32UnmappedAddress; - RGX_MIPS_TLB_ENTRY asTLB[RGXMIPSFW_NUMBER_OF_TLB_ENTRIES]; - RGX_MIPS_REMAP_ENTRY asRemap[RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES]; -} RGX_MIPS_STATE; - -#endif /* RGXMIPSFW_ASSEMBLY_CODE */ - -#endif /* RGX_MIPS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_options.h b/drivers/gpu/drm/img-rogue/1.17/rgx_options.h deleted file mode 100644 index 91fc6522d7ee5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_options.h +++ /dev/null @@ -1,304 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX build options -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* Each build option listed here is packed into a dword which provides up to - * log2(RGX_BUILD_OPTIONS_MASK_KM + 1) flags for KM and - * (32 - log2(RGX_BUILD_OPTIONS_MASK_KM + 1)) flags for UM. - * The corresponding bit is set if the build option was enabled at compile - * time. - * - * In order to extract the enabled build flags the INTERNAL_TEST switch should - * be enabled in a client program which includes this header. Then the client - * can test specific build flags by reading the bit value at - * ##OPTIONNAME##_SET_OFFSET - * in RGX_BUILD_OPTIONS_KM or RGX_BUILD_OPTIONS. - * - * IMPORTANT: add new options to unused bits or define a new dword - * (e.g. RGX_BUILD_OPTIONS_KM2 or RGX_BUILD_OPTIONS2) so that the bitfield - * remains backwards compatible. - */ - -#ifndef RGX_OPTIONS_H -#define RGX_OPTIONS_H - -#define RGX_BUILD_OPTIONS_MASK_KM 0x0000FFFFUL - -#define NO_HARDWARE_OPTION "NO_HARDWARE " -#if defined(NO_HARDWARE) || defined(INTERNAL_TEST) - #define NO_HARDWARE_SET_OFFSET OPTIONS_BIT0 - #define OPTIONS_BIT0 (0x1UL << 0) - #if OPTIONS_BIT0 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT0 0x0UL -#endif /* NO_HARDWARE */ - -#define PDUMP_OPTION "PDUMP " -#if defined(PDUMP) || defined(INTERNAL_TEST) - #define PDUMP_SET_OFFSET OPTIONS_BIT1 - #define OPTIONS_BIT1 (0x1UL << 1) - #if OPTIONS_BIT1 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT1 0x0UL -#endif /* PDUMP */ - -/* No longer used */ -#define INTERNAL_TEST_OPTION "INTERNAL_TEST " -#if defined(INTERNAL_TEST) - #define UNUSED_SET_OFFSET OPTIONS_BIT2 - #define OPTIONS_BIT2 (0x1UL << 2) - #if OPTIONS_BIT2 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT2 0x0UL -#endif - -/* No longer used */ -#define UNUSED_OPTION " " -#if defined(INTERNAL_TEST) - #define OPTIONS_BIT3 (0x1UL << 3) - #define INTERNAL_TEST_OPTION "INTERNAL_TEST " - #if OPTIONS_BIT3 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT3 0x0UL -#endif - -#define SUPPORT_RGX_OPTION " " -#if defined(SUPPORT_RGX) || defined(INTERNAL_TEST) - #define SUPPORT_RGX_SET_OFFSET OPTIONS_BIT4 - #define OPTIONS_BIT4 (0x1UL << 4) - #if OPTIONS_BIT4 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT4 0x0UL -#endif /* SUPPORT_RGX */ - -#define SUPPORT_SECURE_EXPORT_OPTION "SECURE_EXPORTS " -#if defined(SUPPORT_SECURE_EXPORT) || defined(INTERNAL_TEST) - #define SUPPORT_SECURE_EXPORT_SET_OFFSET OPTIONS_BIT5 - #define OPTIONS_BIT5 (0x1UL << 5) - #if OPTIONS_BIT5 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT5 0x0UL -#endif /* SUPPORT_SECURE_EXPORT */ - -#define SUPPORT_INSECURE_EXPORT_OPTION "INSECURE_EXPORTS " -#if defined(SUPPORT_INSECURE_EXPORT) || defined(INTERNAL_TEST) - #define SUPPORT_INSECURE_EXPORT_SET_OFFSET OPTIONS_BIT6 - #define OPTIONS_BIT6 (0x1UL << 6) - #if OPTIONS_BIT6 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT6 0x0UL -#endif /* SUPPORT_INSECURE_EXPORT */ - -#define SUPPORT_VFP_OPTION "VFP " -#if defined(SUPPORT_VFP) || defined(INTERNAL_TEST) - #define SUPPORT_VFP_SET_OFFSET OPTIONS_BIT7 - #define OPTIONS_BIT7 (0x1UL << 7) - #if OPTIONS_BIT7 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT7 0x0UL -#endif /* SUPPORT_VFP */ - -#define SUPPORT_WORKLOAD_ESTIMATION_OPTION "WORKLOAD_ESTIMATION " -#if defined(SUPPORT_WORKLOAD_ESTIMATION) || defined(INTERNAL_TEST) - #define SUPPORT_WORKLOAD_ESTIMATION_OFFSET OPTIONS_BIT8 - #define OPTIONS_BIT8 (0x1UL << 8) - #if OPTIONS_BIT8 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT8 0x0UL -#endif /* SUPPORT_WORKLOAD_ESTIMATION */ -#define OPTIONS_WORKLOAD_ESTIMATION_MASK (0x1UL << 8) - -#define SUPPORT_PDVFS_OPTION "PDVFS " -#if defined(SUPPORT_PDVFS) || defined(INTERNAL_TEST) - #define SUPPORT_PDVFS_OFFSET OPTIONS_BIT9 - #define OPTIONS_BIT9 (0x1UL << 9) - #if OPTIONS_BIT9 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT9 0x0UL -#endif /* SUPPORT_PDVFS */ -#define OPTIONS_PDVFS_MASK (0x1UL << 9) - -#define DEBUG_OPTION "DEBUG " -#if defined(DEBUG) || defined(INTERNAL_TEST) - #define DEBUG_SET_OFFSET OPTIONS_BIT10 - #define OPTIONS_BIT10 (0x1UL << 10) - #if OPTIONS_BIT10 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT10 0x0UL -#endif /* DEBUG */ -/* The bit position of this should be the same as DEBUG_SET_OFFSET option - * when defined. - */ -#define OPTIONS_DEBUG_MASK (0x1UL << 10) - -#define SUPPORT_BUFFER_SYNC_OPTION "BUFFER_SYNC " -#if defined(SUPPORT_BUFFER_SYNC) || defined(INTERNAL_TEST) - #define SUPPORT_BUFFER_SYNC_SET_OFFSET OPTIONS_BIT11 - #define OPTIONS_BIT11 (0x1UL << 11) - #if OPTIONS_BIT11 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT11 0x0UL -#endif /* SUPPORT_BUFFER_SYNC */ - -#define SUPPORT_AUTOVZ_OPTION "AUTOVZ " -#if defined(SUPPORT_AUTOVZ) - #define SUPPORT_AUTOVZ_OFFSET OPTIONS_BIT12 - #define OPTIONS_BIT12 (0x1UL << 12) - #if OPTIONS_BIT12 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT12 0x0UL -#endif /* SUPPORT_AUTOVZ */ - -#define SUPPORT_AUTOVZ_HW_REGS_OPTION "AUTOVZ_HW_REGS " -#if defined(SUPPORT_AUTOVZ_HW_REGS) - #define SUPPORT_AUTOVZ_HW_REGS_OFFSET OPTIONS_BIT13 - #define OPTIONS_BIT13 (0x1UL << 13) - #if OPTIONS_BIT13 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT13 0x0UL -#endif /* SUPPORT_AUTOVZ_HW_REGS */ - -#define RGX_FW_IRQ_OS_COUNTERS_OPTION "FW_IRQ_OS_COUNTERS " -#if defined(RGX_FW_IRQ_OS_COUNTERS) || defined(INTERNAL_TEST) - #define SUPPORT_FW_IRQ_REG_COUNTERS OPTIONS_BIT14 - #define OPTIONS_BIT14 (0x1UL << 14) - #if OPTIONS_BIT14 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT14 0x0UL -#endif /* RGX_FW_IRQ_OS_COUNTERS */ - -#define VALIDATION_EN_MASK (0x1UL << 15) -#define SUPPORT_VALIDATION_OPTION "VALIDATION " -#if defined(SUPPORT_VALIDATION) - #define SUPPORT_VALIDATION_OFFSET OPTIONS_BIT15 - #define OPTIONS_BIT15 (0x1UL << 15) - #if OPTIONS_BIT15 > RGX_BUILD_OPTIONS_MASK_KM - #error "Bit exceeds reserved range" - #endif -#else - #define OPTIONS_BIT15 0x0UL -#endif /* SUPPORT_VALIDATION */ - -#define RGX_BUILD_OPTIONS_KM \ - (OPTIONS_BIT0 |\ - OPTIONS_BIT1 |\ - OPTIONS_BIT2 |\ - OPTIONS_BIT3 |\ - OPTIONS_BIT4 |\ - OPTIONS_BIT6 |\ - OPTIONS_BIT7 |\ - OPTIONS_BIT8 |\ - OPTIONS_BIT9 |\ - OPTIONS_BIT10 |\ - OPTIONS_BIT11 |\ - OPTIONS_BIT12 |\ - OPTIONS_BIT13 |\ - OPTIONS_BIT14 |\ - OPTIONS_BIT15) - -#define RGX_BUILD_OPTIONS_LIST \ - { \ - NO_HARDWARE_OPTION, \ - PDUMP_OPTION, \ - INTERNAL_TEST_OPTION, \ - UNUSED_OPTION, \ - SUPPORT_RGX_OPTION, \ - SUPPORT_SECURE_EXPORT_OPTION, \ - SUPPORT_INSECURE_EXPORT_OPTION, \ - SUPPORT_VFP_OPTION, \ - SUPPORT_WORKLOAD_ESTIMATION_OPTION, \ - SUPPORT_PDVFS_OPTION, \ - DEBUG_OPTION, \ - SUPPORT_BUFFER_SYNC_OPTION, \ - SUPPORT_AUTOVZ_OPTION, \ - SUPPORT_AUTOVZ_HW_REGS_OPTION, \ - RGX_FW_IRQ_OS_COUNTERS_OPTION, \ - SUPPORT_VALIDATION_OPTION \ - } - -#define RGX_BUILD_OPTIONS_MASK_FW \ - (RGX_BUILD_OPTIONS_MASK_KM & \ - ~OPTIONS_BIT11) - -#define OPTIONS_BIT31 (0x1UL << 31) -#if OPTIONS_BIT31 <= RGX_BUILD_OPTIONS_MASK_KM -#error "Bit exceeds reserved range" -#endif -#define SUPPORT_PERCONTEXT_FREELIST_SET_OFFSET OPTIONS_BIT31 - -#define RGX_BUILD_OPTIONS (RGX_BUILD_OPTIONS_KM | OPTIONS_BIT31) - -#define OPTIONS_STRICT (RGX_BUILD_OPTIONS & \ - ~(OPTIONS_DEBUG_MASK | \ - OPTIONS_WORKLOAD_ESTIMATION_MASK | \ - OPTIONS_PDVFS_MASK)) - -#endif /* RGX_OPTIONS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_pdump_panics.h b/drivers/gpu/drm/img-rogue/1.17/rgx_pdump_panics.h deleted file mode 100644 index fce2b3efab695..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_pdump_panics.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX PDump panic definitions header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX PDump panic definitions header -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_PDUMP_PANICS_H_) -#define RGX_PDUMP_PANICS_H_ - -/*! Unique device specific IMG_UINT16 panic IDs to identify the cause of an - * RGX PDump panic in a PDump script. */ -typedef enum -{ - RGX_PDUMP_PANIC_UNDEFINED = 0, - - /* These panics occur when test parameters and driver configuration - * enable features that require the firmware and host driver to - * communicate. Such features are not supported with off-line playback. - */ - RGX_PDUMP_PANIC_ZSBUFFER_BACKING = 101, /*!< Requests ZSBuffer to be backed with physical pages */ - RGX_PDUMP_PANIC_ZSBUFFER_UNBACKING = 102, /*!< Requests ZSBuffer to be unbacked */ - RGX_PDUMP_PANIC_FREELIST_GROW = 103, /*!< Requests an on-demand freelist grow/shrink */ - RGX_PDUMP_PANIC_FREELISTS_RECONSTRUCTION = 104, /*!< Requests freelists reconstruction */ - RGX_PDUMP_PANIC_SPARSEMEM_SWAP = 105, /*!< Requests sparse remap memory swap feature */ -} RGX_PDUMP_PANIC; - -#endif /* RGX_PDUMP_PANICS_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_riscv.h b/drivers/gpu/drm/img-rogue/1.17/rgx_riscv.h deleted file mode 100644 index e5be2a562f34c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_riscv.h +++ /dev/null @@ -1,250 +0,0 @@ -/*************************************************************************/ /*! -@File rgx_riscv.h -@Title -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Platform RGX -@Description RGX RISCV definitions, kernel/user space -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_RISCV_H) -#define RGX_RISCV_H - -#include "km/rgxdefs_km.h" - - -/* Utility defines to convert regions to virtual addresses and remaps */ -#define RGXRISCVFW_GET_REGION_BASE(r) IMG_UINT32_C((r) << 28) -#define RGXRISCVFW_GET_REGION(a) IMG_UINT32_C((a) >> 28) -#define RGXRISCVFW_MAX_REGION_SIZE IMG_UINT32_C(1 << 28) -#define RGXRISCVFW_GET_REMAP(r) (RGX_CR_FWCORE_ADDR_REMAP_CONFIG0 + ((r) * 8U)) - -/* RISCV remap output is aligned to 4K */ -#define RGXRISCVFW_REMAP_CONFIG_DEVVADDR_ALIGN (0x1000U) - -/* - * FW bootloader defines - */ -#define RGXRISCVFW_BOOTLDR_CODE_REGION IMG_UINT32_C(0xC) -#define RGXRISCVFW_BOOTLDR_DATA_REGION IMG_UINT32_C(0x5) -#define RGXRISCVFW_BOOTLDR_CODE_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_BOOTLDR_CODE_REGION)) -#define RGXRISCVFW_BOOTLDR_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_BOOTLDR_DATA_REGION)) -#define RGXRISCVFW_BOOTLDR_CODE_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_BOOTLDR_CODE_REGION)) -#define RGXRISCVFW_BOOTLDR_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_BOOTLDR_DATA_REGION)) - -/* Bootloader data offset in dwords from the beginning of the FW data allocation */ -#define RGXRISCVFW_BOOTLDR_CONF_OFFSET (0x0) - -/* - * FW coremem region defines - */ -#define RGXRISCVFW_COREMEM_REGION IMG_UINT32_C(0x8) -#define RGXRISCVFW_COREMEM_MAX_SIZE IMG_UINT32_C(0x10000000) /* 256 MB */ -#define RGXRISCVFW_COREMEM_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_COREMEM_REGION)) -#define RGXRISCVFW_COREMEM_END (RGXRISCVFW_COREMEM_BASE + RGXRISCVFW_COREMEM_MAX_SIZE - 1U) - - -/* - * Host-FW shared data defines - */ -#define RGXRISCVFW_SHARED_CACHED_DATA_REGION (0x6UL) -#define RGXRISCVFW_SHARED_UNCACHED_DATA_REGION (0xDUL) -#define RGXRISCVFW_SHARED_CACHED_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SHARED_CACHED_DATA_REGION)) -#define RGXRISCVFW_SHARED_UNCACHED_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SHARED_UNCACHED_DATA_REGION)) -#define RGXRISCVFW_SHARED_CACHED_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_SHARED_CACHED_DATA_REGION)) -#define RGXRISCVFW_SHARED_UNCACHED_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_SHARED_UNCACHED_DATA_REGION)) - - -/* - * GPU SOCIF access defines - */ -#define RGXRISCVFW_SOCIF_REGION (0x2U) -#define RGXRISCVFW_SOCIF_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SOCIF_REGION)) - - -/* The things that follow are excluded when compiling assembly sources */ -#if !defined(RGXRISCVFW_ASSEMBLY_CODE) -#include "img_types.h" - -#define RGXFW_PROCESSOR_RISCV "RISCV" -#define RGXRISCVFW_CORE_ID_VALUE (0x00450B02U) -#define RGXRISCVFW_MISA_ADDR (0x301U) -#define RGXRISCVFW_MISA_VALUE (0x40001104U) -#define RGXRISCVFW_MSCRATCH_ADDR (0x340U) - -typedef struct -{ - IMG_UINT64 ui64CorememCodeDevVAddr; - IMG_UINT64 ui64CorememDataDevVAddr; - IMG_UINT32 ui32CorememCodeFWAddr; - IMG_UINT32 ui32CorememDataFWAddr; - IMG_UINT32 ui32CorememCodeSize; - IMG_UINT32 ui32CorememDataSize; - IMG_UINT32 ui32Flags; - IMG_UINT32 ui32Reserved; -} RGXRISCVFW_BOOT_DATA; - -/* - * List of registers to be printed in debug dump. - * First column: register names (general purpose or control/status registers) - * Second column: register number to be used in abstract access register command - * (see RISC-V debug spec v0.13) - */ -#define RGXRISCVFW_DEBUG_DUMP_REGISTERS \ - X(pc, 0x7b1) /* dpc */ \ - X(ra, 0x1001) \ - X(sp, 0x1002) \ - X(mepc, 0x341) \ - X(mcause, 0x342) \ - X(mdseac, 0xfc0) \ - X(mstatus, 0x300) \ - X(mie, 0x304) \ - X(mip, 0x344) \ - X(mscratch, 0x340) \ - X(mbvnc0, 0xffe) \ - X(mbvnc1, 0xfff) \ - X(micect, 0x7f0) \ - X(mdcect, 0x7f3) \ - X(mdcrfct, 0x7f4) \ - -typedef struct -{ -#define X(name, address) \ - IMG_UINT32 name; - - RGXRISCVFW_DEBUG_DUMP_REGISTERS -#undef X -} RGXRISCVFW_STATE; - - -#define RGXRISCVFW_MCAUSE_INTERRUPT (1U << 31) - -#define RGXRISCVFW_MCAUSE_TABLE \ - X(0x00000000U, IMG_FALSE, "NMI pin assertion") /* Also reset value */ \ - X(0x00000001U, IMG_TRUE, "Instruction access fault") \ - X(0x00000002U, IMG_TRUE, "Illegal instruction") \ - X(0x00000003U, IMG_TRUE, "Breakpoint") \ - X(0x00000004U, IMG_TRUE, "Load address misaligned") \ - X(0x00000005U, IMG_TRUE, "Load access fault") \ - X(0x00000006U, IMG_TRUE, "Store/AMO address misaligned") \ - X(0x00000007U, IMG_TRUE, "Store/AMO access fault") \ - X(0x0000000BU, IMG_TRUE, "Environment call from M-mode (FW assert)") \ - X(0x80000007U, IMG_FALSE, "Machine timer interrupt") \ - X(0x8000000BU, IMG_FALSE, "Machine external interrupt") \ - X(0x8000001EU, IMG_FALSE, "Machine correctable error local interrupt") \ - X(0xF0000000U, IMG_TRUE, "Machine D-bus store error NMI") \ - X(0xF0000001U, IMG_TRUE, "Machine D-bus non-blocking load error NMI") \ - X(0xF0000002U, IMG_TRUE, "dCache unrecoverable NMI") - - -/* Debug module HW defines */ -#define RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER (0U) -#define RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY (2U) -#define RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT (2UL << 20) -#define RGXRISCVFW_DMI_COMMAND_WRITE (1UL << 16) -#define RGXRISCVFW_DMI_COMMAND_READ (0UL << 16) -#define RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT (2U) - -/* Abstract command error codes (descriptions from RISC-V debug spec v0.13) */ -typedef enum -{ - /* No error. */ - RISCV_ABSTRACT_CMD_NO_ERROR = 0, - - /* - * An abstract command was executing while command, abstractcs, or abstractauto - * was written, or when one of the data or progbuf registers was read or - * written. This status is only written if cmderr contains 0. - */ - RISCV_ABSTRACT_CMD_BUSY = 1, - - /* - * The requested command is not supported, regardless of whether - * the hart is running or not. - */ - RISCV_ABSTRACT_CMD_NOT_SUPPORTED = 2, - - /* - * An exception occurred while executing the command - * (e.g. while executing the Program Buffer). - */ - RISCV_ABSTRACT_CMD_EXCEPTION = 3, - - /* - * The abstract command couldn't execute because the hart wasn't in the required - * state (running/halted), or unavailable. - */ - RISCV_ABSTRACT_CMD_HALT_RESUME = 4, - - /* - * The abstract command failed due to a bus error - * (e.g. alignment, access size, or timeout). - */ - RISCV_ABSTRACT_CMD_BUS_ERROR = 5, - - /* The command failed for another reason. */ - RISCV_ABSTRACT_CMD_OTHER_ERROR = 7 - -} RGXRISCVFW_ABSTRACT_CMD_ERR; - -/* System Bus error codes (descriptions from RISC-V debug spec v0.13) */ -typedef enum -{ - /* There was no bus error. */ - RISCV_SYSBUS_NO_ERROR = 0, - - /* There was a timeout. */ - RISCV_SYSBUS_TIMEOUT = 1, - - /* A bad address was accessed. */ - RISCV_SYSBUS_BAD_ADDRESS = 2, - - /* There was an alignment error. */ - RISCV_SYSBUS_BAD_ALIGNMENT = 3, - - /* An access of unsupported size was requested. */ - RISCV_SYSBUS_UNSUPPORTED_SIZE = 4, - - /* Other. */ - RISCV_SYSBUS_OTHER_ERROR = 7 - -} RGXRISCVFW_SYSBUS_ERR; - -#endif /* RGXRISCVFW_ASSEMBLY_CODE */ - -#endif /* RGX_RISCV_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgx_tq_shared.h b/drivers/gpu/drm/img-rogue/1.17/rgx_tq_shared.h deleted file mode 100644 index dc10b6eecc91b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgx_tq_shared.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX transfer queue shared -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shared definitions between client and server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGX_TQ_SHARED_H -#define RGX_TQ_SHARED_H - -#define TQ_MAX_PREPARES_PER_SUBMIT 16U - -#define TQ_PREP_FLAGS_COMMAND_3D 0x0U -#define TQ_PREP_FLAGS_COMMAND_2D 0x1U -#define TQ_PREP_FLAGS_COMMAND_MASK (0xfU) -#define TQ_PREP_FLAGS_COMMAND_SHIFT 0 -#define TQ_PREP_FLAGS_PDUMPCONTINUOUS (1U << 4) -#define TQ_PREP_FLAGS_START (1U << 5) -#define TQ_PREP_FLAGS_END (1U << 6) - -#define TQ_PREP_FLAGS_COMMAND_SET(m) \ - ((TQ_PREP_FLAGS_COMMAND_##m << TQ_PREP_FLAGS_COMMAND_SHIFT) & TQ_PREP_FLAGS_COMMAND_MASK) - -#define TQ_PREP_FLAGS_COMMAND_IS(m,n) \ - (((m & TQ_PREP_FLAGS_COMMAND_MASK) >> TQ_PREP_FLAGS_COMMAND_SHIFT) == TQ_PREP_FLAGS_COMMAND_##n) - -#endif /* RGX_TQ_SHARED_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxapi_km.h b/drivers/gpu/drm/img-rogue/1.17/rgxapi_km.h deleted file mode 100644 index 65ba85d20b4ba..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxapi_km.h +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX API Header kernel mode -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exported RGX API details -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXAPI_KM_H -#define RGXAPI_KM_H - -#if defined(SUPPORT_SHARED_SLC) -/*************************************************************************/ /*! -@Function RGXInitSLC -@Description Init the SLC after a power up. It is required to call this - function if using SUPPORT_SHARED_SLC. Otherwise, it shouldn't - be called. - -@Input hDevHandle RGX Device Node -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXInitSLC(IMG_HANDLE hDevHandle); -#endif - -#include "rgx_hwperf.h" - - -/****************************************************************************** - * RGX HW Performance Profiling Control API(s) - *****************************************************************************/ - -/*! HWPerf device identification structure */ -typedef struct _RGX_HWPERF_DEVICE_ -{ - IMG_CHAR pszName[20]; /*!< Helps identify this device uniquely */ - IMG_HANDLE hDevData; /*!< Handle for the server */ - - struct _RGX_HWPERF_DEVICE_ *psNext; /*!< Next device if any */ -} RGX_HWPERF_DEVICE; - -/*! HWPerf connection structure */ -typedef struct -{ - RGX_HWPERF_DEVICE *psHWPerfDevList; /*!< Pointer to list of devices */ -} RGX_HWPERF_CONNECTION; - -/*************************************************************************/ /*! -@Function RGXHWPerfLazyConnect -@Description Obtain a HWPerf connection object to the RGX device(s). The - connections to devices are not actually opened until - HWPerfOpen() is called. - -@Output ppsHWPerfConnection Address of a HWPerf connection object -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfLazyConnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfOpen -@Description Opens connection(s) to the RGX device(s). Valid handle to the - connection object has to be provided which means the this - function needs to be preceded by the call to - RGXHWPerfLazyConnect() function. - -@Input psHWPerfConnection HWPerf connection object -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfOpen(RGX_HWPERF_CONNECTION* psHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfConnect -@Description Obtain a connection object to the RGX HWPerf module. Allocated - connection object(s) reference opened connection(s). Calling - this function is an equivalent of calling RGXHWPerfLazyConnect - and RGXHWPerfOpen. This connect should be used when the caller - will be retrieving event data. - -@Output ppsHWPerfConnection Address of HWPerf connection object -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfConnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfFreeConnection -@Description Frees the HWPerf connection object - -@Input psHWPerfConnection Pointer to connection object as returned - from RGXHWPerfLazyConnect() -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfFreeConnection(RGX_HWPERF_CONNECTION** psHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfClose -@Description Closes all the opened connection(s) to RGX device(s) - -@Input psHWPerfConnection Pointer to HWPerf connection object as - returned from RGXHWPerfConnect() or - RGXHWPerfOpen() -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfClose(RGX_HWPERF_CONNECTION *psHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfDisconnect -@Description Disconnect from the RGX device - -@Input ppsHWPerfConnection Pointer to HWPerf connection object as - returned from RGXHWPerfConnect() or - RGXHWPerfOpen(). Calling this function is - an equivalent of calling RGXHWPerfClose() - and RGXHWPerfFreeConnection(). -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfDisconnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection); - - -/*************************************************************************/ /*! -@Function RGXHWPerfControl -@Description Enable or disable the generation of RGX HWPerf event packets. - See RGXCtrlHWPerf(). - -@Input psHWPerfConnection Pointer to HWPerf connection object -@Input eStreamId ID of the HWPerf stream -@Input bToggle Switch to toggle or apply mask. -@Input ui64Mask Mask of events to control. -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfControl( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_BOOL bToggle, - IMG_UINT64 ui64Mask); - - -/*************************************************************************/ /*! -@Function RGXHWPerfGetFilter -@Description Reads HWPerf stream filter where stream is identified by the - given stream ID. - -@Input hDevData Handle to connection/device object -@Input eStreamId ID of the HWPerf stream -@Output ui64Filter HWPerf filter value -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfGetFilter( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_UINT64 *ui64Filter -); - - -/*************************************************************************/ /*! -@Function RGXHWPerfConfigMuxCounters -@Description Enable and configure the performance counter block for one or - more device layout modules. - See RGXHWPerfConfigureAndEnableCustomCounters(). - -@Input psHWPerfConnection Pointer to HWPerf connection object -@Input ui32NumBlocks Number of elements in the array -@Input asBlockConfigs Address of the array of configuration blocks -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfConfigMuxCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - RGX_HWPERF_CONFIG_MUX_CNTBLK *asBlockConfigs); - -/*************************************************************************/ /*! -@Function RGXHWPerfConfigureAndEnableCustomCounters -@Description Enable and configure custom performance counters - -@Input psHWPerfConnection Pointer to HWPerf connection object -@Input ui16CustomBlockID ID of the custom block to configure -@Input ui16NumCustomCounters Number of custom counters -@Input pui32CustomCounterIDs Pointer to array containing custom - counter IDs -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfConfigureAndEnableCustomCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT16 ui16CustomBlockID, - IMG_UINT16 ui16NumCustomCounters, - IMG_UINT32 *pui32CustomCounterIDs); - -/*************************************************************************/ /*! -@Function RGXHWPerfDisableCounters -@Description Disable the performance counter block for one or more device - layout modules. - -@Input psHWPerfConnection Pointer to HWPerf connection object -@Input ui32NumBlocks Number of elements in the array -@Input aeBlockIDs An array of words with values taken from - the RGX_HWPERF_CNTBLK_ID - enumeration. -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfDisableCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs); - -/*************************************************************************/ /*! -@Function RGXHWPerfEnableCounters -@Description Enable the performance counter block for one or more device - layout modules. - -@Input psHWPerfConnection Pointer to HWPerf connection object -@Input ui32NumBlocks Number of elements in the array -@Input aeBlockIDs An array of words with values taken from the - RGX_HWPERF_CNTBLK_ID enumeration. -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfEnableCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs); - -/****************************************************************************** - * RGX HW Performance Profiling Retrieval API(s) - * - * The client must ensure their use of this acquire/release API for a single - * connection/stream must not be shared with multiple execution contexts e.g. - * between a kernel thread and an ISR handler. It is the client's - * responsibility to ensure this API is not interrupted by a high priority - * thread/ISR - *****************************************************************************/ - -/*************************************************************************/ /*! -@Function RGXHWPerfAcquireEvents -@Description When there is data available to read this call returns with OK - and the address and length of the data buffer the client can - safely read. This buffer may contain one or more event packets. - When there is no data to read, this call returns with OK and - sets *puiBufLen to 0 on exit. - Clients must pair this call with a RGXHWPerfReleaseEvents() - call. - Data returned in ppBuf will be in the form of a sequence of - HWPerf packets which should be traversed using the pointers, - structures and macros provided by rgx_hwperf.h. - -@Input hDevData Handle to connection/device object -@Input eStreamId ID of the HWPerf stream -@Output ppBuf Address of a pointer to a byte buffer. On exit it - contains the address of buffer to read from -@Output pui32BufLen Pointer to an integer. On exit it is the size of - the data to read from the buffer -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfAcquireEvents( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_PBYTE* ppBuf, - IMG_UINT32* pui32BufLen); - - -/*************************************************************************/ /*! -@Function RGXHWPerfReleaseEvents -@Description Called after client has read the event data out of the buffer - retrieved from the Acquire Events call to release resources. - -@Input hDevData Handle to connection/device object -@Input eStreamId ID of the HWPerf stream -@Return PVRSRV_ERROR System error code -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR RGXHWPerfReleaseEvents( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId); - - -/*************************************************************************/ /*! -@Function RGXHWPerfConvertCRTimeStamp -@Description Converts the timestamp given by FW events to the common OS - timestamp. The first three inputs are obtained via a CLK_SYNC - event, ui64CRTimeStamp is the CR timestamp from the FW event - to be converted. - -@Input ui32ClkSpeed Clock speed given by sync event -@Input ui64CorrCRTimeStamp CR Timestamp given by sync event -@Input ui64CorrOSTimeStamp Correlating OS Timestamp given by sync - event -@Input ui64CRTimeStamp CR Timestamp to convert -@Return IMG_UINT64 Calculated OS Timestamp -*/ /**************************************************************************/ -IMG_UINT64 RGXHWPerfConvertCRTimeStamp( - IMG_UINT32 ui32ClkSpeed, - IMG_UINT64 ui64CorrCRTimeStamp, - IMG_UINT64 ui64CorrOSTimeStamp, - IMG_UINT64 ui64CRTimeStamp); - -#endif /* RGXAPI_KM_H */ - -/****************************************************************************** - End of file (rgxapi_km.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.c b/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.c deleted file mode 100644 index bd147dc62e1a2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.c +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Breakpoint routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Breakpoint routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxbreakpoint.h" -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgxmem.h" -#include "device.h" -#include "sync_internal.h" -#include "pdump_km.h" -#include "pvrsrv.h" - -PVRSRV_ERROR PVRSRVRGXSetBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - RGXFWIF_DM eFWDataMaster, - IMG_UINT32 ui32BPAddr, - IMG_UINT32 ui32HandlerAddr, - IMG_UINT32 ui32DataMaster) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sBPCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - OSLockAcquire(psDevInfo->hBPLock); - - if (psDevInfo->bBPSet) - { - eError = PVRSRV_ERROR_BP_ALREADY_SET; - goto unlock; - } - - sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP; - sBPCmd.uCmdData.sBPData.ui32BPAddr = ui32BPAddr; - sBPCmd.uCmdData.sBPData.ui32HandlerAddr = ui32HandlerAddr; - sBPCmd.uCmdData.sBPData.ui32BPDM = ui32DataMaster; - sBPCmd.uCmdData.sBPData.ui32BPDataFlags = RGXFWIF_BPDATA_FLAGS_WRITE | RGXFWIF_BPDATA_FLAGS_ENABLE; - sBPCmd.uCmdData.sBPData.eDM = eFWDataMaster; - - eError = RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, - psFWMemContextMemDesc, - 0 , - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", unlock); - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - eFWDataMaster, - &sBPCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", unlock); - - /* Wait for FW to complete command execution */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", unlock); - - psDevInfo->eBPDM = eFWDataMaster; - psDevInfo->bBPSet = IMG_TRUE; - -unlock: - OSLockRelease(psDevInfo->hBPLock); - - return eError; -} - -PVRSRV_ERROR PVRSRVRGXClearBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sBPCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP; - sBPCmd.uCmdData.sBPData.ui32BPAddr = 0; - sBPCmd.uCmdData.sBPData.ui32HandlerAddr = 0; - sBPCmd.uCmdData.sBPData.ui32BPDataFlags = RGXFWIF_BPDATA_FLAGS_WRITE | RGXFWIF_BPDATA_FLAGS_CTL; - sBPCmd.uCmdData.sBPData.eDM = psDevInfo->eBPDM; - - OSLockAcquire(psDevInfo->hBPLock); - - eError = RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, - psFWMemContextMemDesc, - 0 , - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", unlock); - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - psDevInfo->eBPDM, - &sBPCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", unlock); - - /* Wait for FW to complete command execution */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", unlock); - - psDevInfo->bBPSet = IMG_FALSE; - -unlock: - OSLockRelease(psDevInfo->hBPLock); - - return eError; -} - -PVRSRV_ERROR PVRSRVRGXEnableBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sBPCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - OSLockAcquire(psDevInfo->hBPLock); - - if (psDevInfo->bBPSet == IMG_FALSE) - { - eError = PVRSRV_ERROR_BP_NOT_SET; - goto unlock; - } - - sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP; - sBPCmd.uCmdData.sBPData.ui32BPDataFlags = RGXFWIF_BPDATA_FLAGS_CTL | RGXFWIF_BPDATA_FLAGS_ENABLE; - sBPCmd.uCmdData.sBPData.eDM = psDevInfo->eBPDM; - - eError = RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, - psFWMemContextMemDesc, - 0 , - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", unlock); - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - psDevInfo->eBPDM, - &sBPCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", unlock); - - /* Wait for FW to complete command execution */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", unlock); - -unlock: - OSLockRelease(psDevInfo->hBPLock); - - return eError; -} - -PVRSRV_ERROR PVRSRVRGXDisableBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sBPCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - OSLockAcquire(psDevInfo->hBPLock); - - if (psDevInfo->bBPSet == IMG_FALSE) - { - eError = PVRSRV_ERROR_BP_NOT_SET; - goto unlock; - } - - sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP; - sBPCmd.uCmdData.sBPData.ui32BPDataFlags = RGXFWIF_BPDATA_FLAGS_CTL; - sBPCmd.uCmdData.sBPData.eDM = psDevInfo->eBPDM; - - eError = RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, - psFWMemContextMemDesc, - 0 , - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", unlock); - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - psDevInfo->eBPDM, - &sBPCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", unlock); - - /* Wait for FW to complete command execution */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", unlock); - -unlock: - OSLockRelease(psDevInfo->hBPLock); - - return eError; -} - -PVRSRV_ERROR PVRSRVRGXOverallocateBPRegistersKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32TempRegs, - IMG_UINT32 ui32SharedRegs) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sBPCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP; - sBPCmd.uCmdData.sBPData.ui32BPDataFlags = RGXFWIF_BPDATA_FLAGS_REGS; - sBPCmd.uCmdData.sBPData.ui32TempRegs = ui32TempRegs; - sBPCmd.uCmdData.sBPData.ui32SharedRegs = ui32SharedRegs; - sBPCmd.uCmdData.sBPData.psFWMemContext.ui32Addr = 0U; - sBPCmd.uCmdData.sBPData.eDM = RGXFWIF_DM_GP; - - OSLockAcquire(psDevInfo->hBPLock); - - eError = RGXScheduleCommandAndGetKCCBSlot(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sBPCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", unlock); - - /* Wait for FW to complete command execution */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", unlock); - -unlock: - OSLockRelease(psDevInfo->hBPLock); - - return eError; -} - -/****************************************************************************** - End of file (rgxbreakpoint.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.h b/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.h deleted file mode 100644 index 1a0b87b4252b1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxbreakpoint.h +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX breakpoint functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX breakpoint functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXBREAKPOINT_H) -#define RGXBREAKPOINT_H - -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgx_fwif_km.h" - -/*! -******************************************************************************* - @Function PVRSRVRGXSetBreakpointKM - - @Description - Server-side implementation of RGXSetBreakpoint - - @Input psDeviceNode - RGX Device node - @Input eDataMaster - Data Master to schedule command for - @Input hMemCtxPrivData - memory context private data - @Input ui32BPAddr - Address of breakpoint - @Input ui32HandlerAddr - Address of breakpoint handler - @Input ui32BPCtl - Breakpoint controls - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXSetBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - RGXFWIF_DM eFWDataMaster, - IMG_UINT32 ui32BPAddr, - IMG_UINT32 ui32HandlerAddr, - IMG_UINT32 ui32DataMaster); - -/*! -******************************************************************************* - @Function PVRSRVRGXClearBreakpointKM - - @Description - Server-side implementation of RGXClearBreakpoint - - @Input psDeviceNode - RGX Device node - @Input hMemCtxPrivData - memory context private data - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXClearBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData); - -/*! -******************************************************************************* - @Function PVRSRVRGXEnableBreakpointKM - - @Description - Server-side implementation of RGXEnableBreakpoint - - @Input psDeviceNode - RGX Device node - @Input hMemCtxPrivData - memory context private data - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXEnableBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData); - -/*! -******************************************************************************* - @Function PVRSRVRGXDisableBreakpointKM - - @Description - Server-side implementation of RGXDisableBreakpoint - - @Input psDeviceNode - RGX Device node - @Input hMemCtxPrivData - memory context private data - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXDisableBreakpointKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData); - -/*! -******************************************************************************* - @Function PVRSRVRGXOverallocateBPRegistersKM - - @Description - Server-side implementation of RGXOverallocateBPRegisters - - @Input psDeviceNode - RGX Device node - @Input ui32TempRegs - Number of temporary registers to overallocate - @Input ui32SharedRegs - Number of shared registers to overallocate - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXOverallocateBPRegistersKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32TempRegs, - IMG_UINT32 ui32SharedRegs); -#endif /* RGXBREAKPOINT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.c b/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.c deleted file mode 100644 index 6c29beef22b50..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.c +++ /dev/null @@ -1,852 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title BVNC handling specific routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Functions used for BNVC related work -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgxbvnc.h" -#define RGXBVNC_C -#include "rgx_bvnc_table_km.h" -#undef RGXBVNC_C -#include "oskm_apphint.h" -#include "pvrsrv.h" -#include "pdump_km.h" -#include "rgx_compat_bvnc.h" - -#define RGXBVNC_BUFFER_SIZE (((PVRSRV_MAX_DEVICES)*(RGX_BVNC_STR_SIZE_MAX))+1) - -/* This function searches the given array for a given search value */ -static IMG_UINT64* _RGXSearchBVNCTable( IMG_UINT64 *pui64Array, - IMG_UINT uiEnd, - IMG_UINT64 ui64SearchValue, - IMG_UINT uiColCount) -{ - IMG_UINT uiStart = 0, index; - IMG_UINT64 value, *pui64Ptr = NULL; - - while (uiStart < uiEnd) - { - index = (uiStart + uiEnd)/2; - pui64Ptr = pui64Array + (index * uiColCount); - value = *(pui64Ptr); - - if (value == ui64SearchValue) - { - return pui64Ptr; - } - - if (value > ui64SearchValue) - { - uiEnd = index; - }else - { - uiStart = index + 1; - } - } - return NULL; -} -#define RGX_SEARCH_BVNC_TABLE(t, b) (_RGXSearchBVNCTable((IMG_UINT64*)(t), \ - ARRAY_SIZE(t), (b), \ - sizeof((t)[0])/sizeof(IMG_UINT64)) ) - - -#if defined(DEBUG) - -#define PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, szShortName, Feature) \ - if ( psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_##Feature##_IDX] != RGX_FEATURE_VALUE_DISABLED ) \ - { PVR_LOG(("%s %d", szShortName, psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_##Feature##_IDX])); } \ - else \ - { PVR_LOG(("%s N/A", szShortName)); } - -static void _RGXBvncDumpParsedConfig(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - IMG_UINT64 ui64Mask = 0, ui32IdOrNameIdx = 1; - - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "NC: ", NUM_CLUSTERS); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "CSF: ", CDM_CONTROL_STREAM_FORMAT); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "FBCDCA: ", FBCDC_ARCHITECTURE); -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "META: ", META); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "MCMB: ", META_COREMEM_BANKS); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "MCMS: ", META_COREMEM_SIZE); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "MDMACnt: ", META_DMA_CHANNEL_COUNT); -#endif - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "NIIP: ", NUM_ISP_IPP_PIPES); -#if defined(RGX_FEATURE_NUM_ISP_PER_SPU_MAX_VALUE_IDX) - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "NIPS: ", NUM_ISP_PER_SPU); -#endif -#if defined(RGX_FEATURE_PBE_PER_SPU_MAX_VALUE_IDX) - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "PPS: ", PBE_PER_SPU); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "NSPU: ", NUM_SPU); -#endif - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "PBW: ", PHYS_BUS_WIDTH); -#if defined(RGX_FEATURE_SCALABLE_TE_ARCH_MAX_VALUE_IDX) - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "STEArch: ", SCALABLE_TE_ARCH); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "SVCEA: ", SCALABLE_VCE); -#endif - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "SLCBanks: ", SLC_BANKS); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "SLCCLS: ", SLC_CACHE_LINE_SIZE_BITS); - PVR_LOG(("SLCSize: %d", psDevInfo->sDevFeatureCfg.ui32SLCSizeInBytes)); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "VASB: ", VIRTUAL_ADDRESS_SPACE_BITS); - PVR_LOG_DUMP_FEATURE_VALUE(psDevInfo, "NOSIDS: ", NUM_OSIDS); - -#if defined(FEATURE_NO_VALUES_NAMES_MAX_IDX) - /* Dump the features with no values */ - ui64Mask = psDevInfo->sDevFeatureCfg.ui64Features; - while (ui64Mask) - { - if (ui64Mask & 0x01) - { - if (ui32IdOrNameIdx <= FEATURE_NO_VALUES_NAMES_MAX_IDX) - { - PVR_LOG(("%s", gaszFeaturesNoValuesNames[ui32IdOrNameIdx - 1])); - } - else - { - PVR_DPF((PVR_DBG_WARNING, - "Feature with Mask doesn't exist: 0x%016" IMG_UINT64_FMTSPECx, - ((IMG_UINT64)1 << (ui32IdOrNameIdx - 1)))); - } - } - ui64Mask >>= 1; - ui32IdOrNameIdx++; - } -#endif - -#if defined(ERNSBRNS_IDS_MAX_IDX) - /* Dump the ERN and BRN flags for this core */ - ui64Mask = psDevInfo->sDevFeatureCfg.ui64ErnsBrns; - ui32IdOrNameIdx = 1; - - while (ui64Mask) - { - if (ui64Mask & 0x1) - { - if (ui32IdOrNameIdx <= ERNSBRNS_IDS_MAX_IDX) - { - PVR_LOG(("ERN/BRN : %d", gaui64ErnsBrnsIDs[ui32IdOrNameIdx - 1])); - } - else - { - PVR_LOG(("Unknown ErnBrn bit: 0x%0" IMG_UINT64_FMTSPECx, ((IMG_UINT64)1 << (ui32IdOrNameIdx - 1)))); - } - } - ui64Mask >>= 1; - ui32IdOrNameIdx++; - } -#endif - -} -#endif - -static void _RGXBvncParseFeatureValues(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT64 *pui64Cfg) -{ - IMG_UINT32 ui32Index; - - /* Read the feature values for the runtime BVNC */ - for (ui32Index = 0; ui32Index < RGX_FEATURE_WITH_VALUES_MAX_IDX; ui32Index++) - { - IMG_UINT16 bitPosition = aui16FeaturesWithValuesBitPositions[ui32Index]; - IMG_UINT64 ui64PackedValues = pui64Cfg[2 + bitPosition / 64]; - IMG_UINT16 ui16ValueIndex = (ui64PackedValues & aui64FeaturesWithValuesBitMasks[ui32Index]) >> (bitPosition % 64); - - if (ui16ValueIndex < gaFeaturesValuesMaxIndexes[ui32Index]) - { - if (gaFeaturesValues[ui32Index][ui16ValueIndex] == (IMG_UINT16)RGX_FEATURE_VALUE_DISABLED) - { - psDevInfo->sDevFeatureCfg.ui32FeaturesValues[ui32Index] = RGX_FEATURE_VALUE_DISABLED; - } - else - { - psDevInfo->sDevFeatureCfg.ui32FeaturesValues[ui32Index] = gaFeaturesValues[ui32Index][ui16ValueIndex]; - } - } - else - { - /* This case should never be reached */ - psDevInfo->sDevFeatureCfg.ui32FeaturesValues[ui32Index] = RGX_FEATURE_VALUE_INVALID; - PVR_DPF((PVR_DBG_ERROR, "%s: Feature with index (%d) decoded wrong value index (%d)", __func__, ui32Index, ui16ValueIndex)); - PVR_ASSERT(ui16ValueIndex < gaFeaturesValuesMaxIndexes[ui32Index]); - } - } - -#if defined(RGX_FEATURE_POWER_ISLAND_VERSION_MAX_VALUE_IDX) - /* Code path for Volcanic */ - - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = RGXFWIF_DM_CDM+1; - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, RAY_TRACING_ARCH) && - RGX_GET_FEATURE_VALUE(psDevInfo, RAY_TRACING_ARCH) > 1) - { - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = MAX(psDevInfo->sDevFeatureCfg.ui32MAXDMCount, RGXFWIF_DM_RAY+1); - } -#if defined(SUPPORT_AGP) - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = MAX(psDevInfo->sDevFeatureCfg.ui32MAXDMCount, RGXFWIF_DM_GEOM2+1); -#if defined(SUPPORT_AGP4) - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = MAX(psDevInfo->sDevFeatureCfg.ui32MAXDMCount, RGXFWIF_DM_GEOM4+1); -#endif -#endif - - /* Get the max number of dusts in the core */ - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS)) - { - RGX_LAYER_PARAMS sParams = {.psDevInfo = psDevInfo}; - - if (RGX_DEVICE_GET_FEATURE_VALUE(&sParams, POWER_ISLAND_VERSION) == 1) - { - /* per SPU power island */ - psDevInfo->sDevFeatureCfg.ui32MAXPowUnitCount = MAX(1, (RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS) / 2)); - } - else if (RGX_DEVICE_GET_FEATURE_VALUE(&sParams, POWER_ISLAND_VERSION) >= 2) - { - /* per Cluster power island */ - psDevInfo->sDevFeatureCfg.ui32MAXPowUnitCount = RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS); - } - else - { - /* All volcanic cores support power islanding */ - psDevInfo->sDevFeatureCfg.ui32MAXPowUnitCount = RGX_FEATURE_VALUE_INVALID; - PVR_DPF((PVR_DBG_ERROR, "%s: Power island feature version not found!", __func__)); - PVR_ASSERT(0); - } - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, RAY_TRACING_ARCH) && - RGX_GET_FEATURE_VALUE(psDevInfo, RAY_TRACING_ARCH) > 1) - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RT_RAC_PER_SPU)) - { - psDevInfo->sDevFeatureCfg.ui32MAXRACCount = RGX_GET_FEATURE_VALUE(psDevInfo, NUM_SPU); - } - else - { - psDevInfo->sDevFeatureCfg.ui32MAXRACCount = 1; - } - } - } - else - { - /* This case should never be reached as all cores have clusters */ - psDevInfo->sDevFeatureCfg.ui32MAXPowUnitCount = RGX_FEATURE_VALUE_INVALID; - PVR_DPF((PVR_DBG_ERROR, "%s: Number of clusters feature value missing!", __func__)); - PVR_ASSERT(0); - } -#else /* defined(RGX_FEATURE_POWER_ISLAND_VERSION_MAX_VALUE_IDX) */ - /* Code path for Rogue and Oceanic */ - - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = RGXFWIF_DM_CDM+1; -#if defined(SUPPORT_AGP) - psDevInfo->sDevFeatureCfg.ui32MAXDMCount = MAX(psDevInfo->sDevFeatureCfg.ui32MAXDMCount, RGXFWIF_DM_GEOM2+1); -#endif - - /* Meta feature not present in oceanic */ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_META_IDX] = RGX_FEATURE_VALUE_DISABLED; - } -#endif - - /* Get the max number of dusts in the core */ - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS)) - { - psDevInfo->sDevFeatureCfg.ui32MAXDustCount = MAX(1, (RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS) / 2)); - } - else - { - /* This case should never be reached as all cores have clusters */ - psDevInfo->sDevFeatureCfg.ui32MAXDustCount = RGX_FEATURE_VALUE_INVALID; - PVR_DPF((PVR_DBG_ERROR, "%s: Number of clusters feature value missing!", __func__)); - PVR_ASSERT(0); - } -#endif /* defined(RGX_FEATURE_POWER_ISLAND_VERSION_MAX_VALUE_IDX) */ - - /* Meta feature not present in oceanic */ -#if defined(RGX_FEATURE_META_COREMEM_SIZE_MAX_VALUE_IDX) - /* Transform the META coremem size info in bytes */ - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META_COREMEM_SIZE)) - { - psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_META_COREMEM_SIZE_IDX] *= 1024; - } -#endif -} - -static void _RGXBvncAcquireAppHint(IMG_CHAR *pszBVNC, const IMG_UINT32 ui32RGXDevCount) -{ - const IMG_CHAR *pszAppHintDefault = PVRSRV_APPHINT_RGXBVNC; - void *pvAppHintState = NULL; - IMG_UINT32 ui32BVNCCount = 0; - IMG_BOOL bRet; - IMG_CHAR szBVNCAppHint[RGXBVNC_BUFFER_SIZE]; - IMG_CHAR *pszCurrentBVNC = szBVNCAppHint; - szBVNCAppHint[0] = '\0'; - - OSCreateKMAppHintState(&pvAppHintState); - - bRet = (IMG_BOOL)OSGetKMAppHintSTRING(APPHINT_NO_DEVICE, - pvAppHintState, - RGXBVNC, - pszAppHintDefault, - szBVNCAppHint, - sizeof(szBVNCAppHint)); - - OSFreeKMAppHintState(pvAppHintState); - - if (!bRet || (szBVNCAppHint[0] == '\0')) - { - return; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: BVNC module param list: %s",__func__, szBVNCAppHint)); - - while (*pszCurrentBVNC != '\0') - { - IMG_CHAR *pszNext = pszCurrentBVNC; - - if (ui32BVNCCount >= PVRSRV_MAX_DEVICES) - { - break; - } - - while (1) - { - if (*pszNext == ',') - { - pszNext[0] = '\0'; - pszNext++; - break; - } else if (*pszNext == '\0') - { - break; - } - pszNext++; - } - - if (ui32BVNCCount == ui32RGXDevCount) - { - OSStringLCopy(pszBVNC, pszCurrentBVNC, RGX_BVNC_STR_SIZE_MAX); - return; - } - - ui32BVNCCount++; - pszCurrentBVNC = pszNext; - } - - PVR_DPF((PVR_DBG_ERROR, "%s: Given module parameters list is shorter than " - "number of actual devices", __func__)); - - /* If only one BVNC parameter is specified, the same is applied for all RGX - * devices detected */ - if (1 == ui32BVNCCount) - { - OSStringLCopy(pszBVNC, szBVNCAppHint, RGX_BVNC_STR_SIZE_MAX); - } -} - -/* Function that parses the BVNC List passed as module parameter */ -static PVRSRV_ERROR _RGXBvncParseList(IMG_UINT32 *pB, - IMG_UINT32 *pV, - IMG_UINT32 *pN, - IMG_UINT32 *pC, - const IMG_UINT32 ui32RGXDevCount) -{ - unsigned int ui32ScanCount = 0; - IMG_CHAR aszBVNCString[RGX_BVNC_STR_SIZE_MAX]; - - aszBVNCString[0] = '\0'; - - /* 4 components of a BVNC string is B, V, N & C */ -#define RGX_BVNC_INFO_PARAMS (4) - - _RGXBvncAcquireAppHint(aszBVNCString, ui32RGXDevCount); - - if ('\0' == aszBVNCString[0]) - { - return PVRSRV_ERROR_INVALID_BVNC_PARAMS; - } - - /* Parse the given RGX_BVNC string */ - ui32ScanCount = OSVSScanf(aszBVNCString, RGX_BVNC_STR_FMTSPEC, pB, pV, pN, pC); - if (RGX_BVNC_INFO_PARAMS != ui32ScanCount) - { - ui32ScanCount = OSVSScanf(aszBVNCString, RGX_BVNC_STRP_FMTSPEC, pB, pV, pN, pC); - } - if (RGX_BVNC_INFO_PARAMS != ui32ScanCount) - { - return PVRSRV_ERROR_INVALID_BVNC_PARAMS; - } - PVR_LOG(("BVNC module parameter honoured: %s", aszBVNCString)); - - return PVRSRV_OK; -} - -#if !defined(NO_HARDWARE) -/* - * This function obtains the SLCSize from the physical device for GPUs which provide - * this information. If the GPU does not provide support we return a value of 0 which will - * result in the BVNC supplied definition being used to provide the SLCSize. - * Must only be called from driver-live with hardware powered-on. - */ -static IMG_UINT32 _RGXBvncReadSLCSize(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT64 ui64SLCSize = 0ULL; - -#if defined(RGX_CR_SLC_SIZE_IN_KB) - /* Rogue and Oceanic hardware */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_SIZE_CONFIGURABLE)) - { - ui64SLCSize = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SLC_SIZE_IN_KB); - if (ui64SLCSize == 0ULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Unexpected 0 SLC size. Using default", __func__)); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: RGX_CR_SIZE_IN_KB = %u", __func__, - (IMG_UINT32) ui64SLCSize)); - } - } -#else - /* Volcanic hardware */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_SIZE_ADJUSTMENT)) - { - ui64SLCSize = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SLC_STATUS2); - ui64SLCSize &= ~RGX_CR_SLC_STATUS2_SLC_SIZE_IN_KB_CLRMSK; - ui64SLCSize >>= RGX_CR_SLC_STATUS2_SLC_SIZE_IN_KB_SHIFT; - - if (ui64SLCSize == 0ULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Unexpected 0 SLC size. Using default", __func__)); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: SLC_SIZE_IN_KILOBYTES = %u", __func__, - (IMG_UINT32) ui64SLCSize)); - } - } -#endif - - return (IMG_UINT32)ui64SLCSize * 1024U; -} -#endif /* !defined(NO_HARDWARE) */ - -/* This function detects the Rogue variant and configures the essential - * config info associated with such a device. - * The config info includes features, errata, etc - */ -PVRSRV_ERROR RGXBvncInitialiseConfiguration(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - static IMG_UINT32 ui32RGXDevCnt = 0; - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT64 ui64BVNC=0; - IMG_UINT32 B=0, V=0, N=0, C=0; - IMG_UINT64 *pui64Cfg = NULL; - IMG_UINT32 ui32Cores = 1U; - IMG_UINT32 ui32SLCSize = 0; - - /* Check for load time RGX BVNC parameter */ - eError = _RGXBvncParseList(&B,&V,&N,&C, ui32RGXDevCnt); - if (PVRSRV_OK == eError) - { - PVR_LOG(("Read BVNC " RGX_BVNC_STR_FMTSPEC - " from driver load parameter", B, V, N, C)); - - /* Extract the BVNC config from the Features table */ - ui64BVNC = BVNC_PACK(B,0,N,C); - pui64Cfg = RGX_SEARCH_BVNC_TABLE(gaFeatures, ui64BVNC); - PVR_LOG_IF_FALSE((pui64Cfg != NULL), "Driver parameter BVNC configuration not found!"); - } - - { - void *pvAppHintState = NULL; - const IMG_BOOL bAppHintDefault = PVRSRV_APPHINT_IGNOREHWREPORTEDBVNC; - - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintBOOL(APPHINT_NO_DEVICE, - pvAppHintState, - IgnoreHWReportedBVNC, - &bAppHintDefault, - &psDevInfo->bIgnoreHWReportedBVNC); - OSFreeKMAppHintState(pvAppHintState); - } - -#if !defined(NO_HARDWARE) - - /* Try to detect the RGX BVNC from the HW device */ - if ((NULL == pui64Cfg) && !psDevInfo->bIgnoreHWReportedBVNC) - { - IMG_UINT64 ui32ID; - IMG_BOOL bPowerDown = (psDeviceNode->eCurrentSysPowerState == PVRSRV_SYS_POWER_STATE_OFF); - - /* Power-up the device as required to read the registers */ - if (bPowerDown) - { - eError = PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_ON); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVSetSystemPowerState ON"); - } - -#if defined(RGX_CR_CORE_ID__PBVNC) - /* Core ID reading code for Rogue */ - - /* Read the BVNC, in to new way first, if B not set, use old scheme */ - ui32ID = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_ID__PBVNC); - - if (GET_B(ui32ID)) - { - B = (ui32ID & ~RGX_CR_CORE_ID__PBVNC__BRANCH_ID_CLRMSK) >> - RGX_CR_CORE_ID__PBVNC__BRANCH_ID_SHIFT; - V = (ui32ID & ~RGX_CR_CORE_ID__PBVNC__VERSION_ID_CLRMSK) >> - RGX_CR_CORE_ID__PBVNC__VERSION_ID_SHIFT; - N = (ui32ID & ~RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_CLRMSK) >> - RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_SHIFT; - C = (ui32ID & ~RGX_CR_CORE_ID__PBVNC__CONFIG_ID_CLRMSK) >> - RGX_CR_CORE_ID__PBVNC__CONFIG_ID_SHIFT; - - } - else - { - IMG_UINT64 ui32CoreID, ui32CoreRev; - ui32CoreRev = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_REVISION); - ui32CoreID = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_ID); - B = (ui32CoreRev & ~RGX_CR_CORE_REVISION_MAJOR_CLRMSK) >> - RGX_CR_CORE_REVISION_MAJOR_SHIFT; - V = (ui32CoreRev & ~RGX_CR_CORE_REVISION_MINOR_CLRMSK) >> - RGX_CR_CORE_REVISION_MINOR_SHIFT; - N = (ui32CoreID & ~RGX_CR_CORE_ID_CONFIG_N_CLRMSK) >> - RGX_CR_CORE_ID_CONFIG_N_SHIFT; - C = (ui32CoreID & ~RGX_CR_CORE_ID_CONFIG_C_CLRMSK) >> - RGX_CR_CORE_ID_CONFIG_C_SHIFT; - } -#else - /* Core ID reading code for Volcanic */ - - ui32ID = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_ID); - - B = (ui32ID & ~RGX_CR_CORE_ID_BRANCH_ID_CLRMSK) >> - RGX_CR_CORE_ID_BRANCH_ID_SHIFT; - V = (ui32ID & ~RGX_CR_CORE_ID_VERSION_ID_CLRMSK) >> - RGX_CR_CORE_ID_VERSION_ID_SHIFT; - N = (ui32ID & ~RGX_CR_CORE_ID_NUMBER_OF_SCALABLE_UNITS_CLRMSK) >> - RGX_CR_CORE_ID_NUMBER_OF_SCALABLE_UNITS_SHIFT; - C = (ui32ID & ~RGX_CR_CORE_ID_CONFIG_ID_CLRMSK) >> - RGX_CR_CORE_ID_CONFIG_ID_SHIFT; -#endif - - PVR_LOG(("Read BVNC " RGX_BVNC_STR_FMTSPEC - " from HW device registers", B, V, N, C)); - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - /* Read the number of cores in the system for newer BVNC (Branch ID > 20) */ - if (B > 20) - { - ui32Cores = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MULTICORE_SYSTEM); - } - } - - /* Obtain the SLC size from the device */ - ui32SLCSize = _RGXBvncReadSLCSize(psDeviceNode); - PVR_DPF((PVR_DBG_MESSAGE, "%s: SLC Size reported as %u", __func__, ui32SLCSize)); - - if (bPowerDown) - { - eError = PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_OFF); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVSetSystemPowerState OFF"); - } - - /* Extract the BVNC config from the Features table */ - ui64BVNC = BVNC_PACK(B,0,N,C); - if (ui64BVNC != 0) - { - pui64Cfg = RGX_SEARCH_BVNC_TABLE(gaFeatures, ui64BVNC); - PVR_LOG_IF_FALSE((pui64Cfg != NULL), "HW device BVNC configuration not found!"); - } - else if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - /* - * On host OS we should not get here as CORE_ID should not be zero, so flag an error. - * On older cores, guest OS only has CORE_ID if defined(RGX_FEATURE_COREID_PER_OS) - */ - PVR_LOG_ERROR(PVRSRV_ERROR_DEVICE_REGISTER_FAILED, "CORE_ID register returns zero. Unknown BVNC"); - } - } -#endif - -#if defined(RGX_BVNC_KM_B) && defined(RGX_BVNC_KM_N) && defined(RGX_BVNC_KM_C) - if (NULL == pui64Cfg) - { - /* We reach here if the HW is not present, - * or we are running in a guest OS with no COREID_PER_OS feature, - * or HW is unstable during register read giving invalid values, - * or runtime detection has been disabled - fall back to compile time BVNC - */ - B = RGX_BVNC_KM_B; - N = RGX_BVNC_KM_N; - C = RGX_BVNC_KM_C; - { - IMG_UINT32 ui32ScanCount = 0; - ui32ScanCount = OSVSScanf(RGX_BVNC_KM_V_ST, "%u", &V); - if (1 != ui32ScanCount) - { - ui32ScanCount = OSVSScanf(RGX_BVNC_KM_V_ST, "%up", &V); - if (1 != ui32ScanCount) - { - V = 0; - } - } - } - PVR_LOG(("Reverting to compile time BVNC %s", RGX_BVNC_KM)); - - /* Extract the BVNC config from the Features table */ - ui64BVNC = BVNC_PACK(B,0,N,C); - pui64Cfg = RGX_SEARCH_BVNC_TABLE(gaFeatures, ui64BVNC); - PVR_LOG_IF_FALSE((pui64Cfg != NULL), "Compile time BVNC configuration not found!"); - } -#endif /* defined(RGX_BVNC) */ - - /* Have we failed to identify the BVNC to use? */ - if (NULL == pui64Cfg) - { - PVR_DPF((PVR_DBG_ERROR, "%s: BVNC Detection and feature lookup failed. " - "Unsupported BVNC: 0x%016" IMG_UINT64_FMTSPECx, __func__, ui64BVNC)); - return PVRSRV_ERROR_BVNC_UNSUPPORTED; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: BVNC Feature found config: 0x%016" - IMG_UINT64_FMTSPECx " 0x%016" IMG_UINT64_FMTSPECx " 0x%016" - IMG_UINT64_FMTSPECx " 0x%016" IMG_UINT64_FMTSPECx "\n", __func__, - pui64Cfg[0], pui64Cfg[1], pui64Cfg[2], pui64Cfg[3])); - - /* Parsing feature config depends on available features on the core - * hence this parsing should always follow the above feature assignment */ - psDevInfo->sDevFeatureCfg.ui64Features = pui64Cfg[1]; - _RGXBvncParseFeatureValues(psDevInfo, pui64Cfg); - - /* Add 'V' to the packed BVNC value to get the BVNC ERN and BRN config. */ - ui64BVNC = BVNC_PACK(B,V,N,C); - pui64Cfg = RGX_SEARCH_BVNC_TABLE(gaErnsBrns, ui64BVNC); - if (NULL == pui64Cfg) - { - PVR_DPF((PVR_DBG_ERROR, "%s: BVNC ERN/BRN lookup failed. " - "Unsupported BVNC: 0x%016" IMG_UINT64_FMTSPECx, __func__, ui64BVNC)); - psDevInfo->sDevFeatureCfg.ui64ErnsBrns = 0; - return PVRSRV_ERROR_BVNC_UNSUPPORTED; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: BVNC ERN/BRN Cfg: 0x%016" IMG_UINT64_FMTSPECx - " 0x%016" IMG_UINT64_FMTSPECx, __func__, *pui64Cfg, pui64Cfg[1])); - psDevInfo->sDevFeatureCfg.ui64ErnsBrns = pui64Cfg[1]; - - psDevInfo->sDevFeatureCfg.ui32B = B; - psDevInfo->sDevFeatureCfg.ui32V = V; - psDevInfo->sDevFeatureCfg.ui32N = N; - psDevInfo->sDevFeatureCfg.ui32C = C; - - - /* - * Store the SLCSize in the device info field. If 0 it means the device uses the BVNC - * values so grab them here as we've already populated the internal structures. - */ - if (ui32SLCSize == 0U) - { - ui32SLCSize = RGX_GET_FEATURE_VALUE(psDevInfo, SLC_SIZE_IN_KILOBYTES) * 1024U; - - /* Verify that we have a valid value returned from the BVNC */ - PVR_ASSERT(ui32SLCSize != 0U); - } - psDevInfo->sDevFeatureCfg.ui32SLCSizeInBytes = ui32SLCSize; - - /* Message to confirm configuration look up was a success */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { -#if defined(NO_HARDWARE) - { - PVR_UNREFERENCED_PARAMETER(ui32Cores); - PVR_LOG(("RGX Device registered with BVNC " RGX_BVNC_STR_FMTSPEC, - B, V, N, C)); - } -#else - { - PVR_LOG(("RGX Device registered BVNC " RGX_BVNC_STR_FMTSPEC - " with %u %s in the system", B ,V ,N ,C, ui32Cores , - ((ui32Cores == 1U)?"core":"cores"))); - } -#endif - } - else - { - PVR_LOG(("RGX Device registered with BVNC " RGX_BVNC_STR_FMTSPEC, - B, V, N, C)); - } - - ui32RGXDevCnt++; - -#if defined(DEBUG) - _RGXBvncDumpParsedConfig(psDeviceNode); -#endif - return PVRSRV_OK; -} - -/* - * This function checks if a particular feature is available on the given rgx device */ -IMG_BOOL RGXBvncCheckFeatureSupported(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64 ui64FeatureMask) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (psDevInfo->sDevFeatureCfg.ui64Features & ui64FeatureMask) - { - return IMG_TRUE; - } - return IMG_FALSE; -} - -/* - * This function returns the value of a feature on the given rgx device */ -IMG_INT32 RGXBvncGetSupportedFeatureValue(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_FEATURE_WITH_VALUE_INDEX eFeatureIndex) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (eFeatureIndex >= RGX_FEATURE_WITH_VALUES_MAX_IDX) - { - return -1; - } - - if (psDevInfo->sDevFeatureCfg.ui32FeaturesValues[eFeatureIndex] == RGX_FEATURE_VALUE_DISABLED) - { - return -1; - } - - return psDevInfo->sDevFeatureCfg.ui32FeaturesValues[eFeatureIndex]; -} - -/**************************************************************************/ /*! -@Function RGXVerifyBVNC -@Description Checks that the device's BVNC registers have the correct values. -@Input psDeviceNode Device node -@Return PVRSRV_ERROR -*/ /***************************************************************************/ -#define NUM_RGX_CORE_IDS 8 -PVRSRV_ERROR RGXVerifyBVNC(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64 ui64GivenBVNC, IMG_UINT64 ui64CoreIdMask) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT64 ui64MatchBVNC; - IMG_UINT32 i; - - PVR_ASSERT(psDeviceNode != NULL); - PVR_ASSERT(psDeviceNode->pvDevice != NULL); - - /* The device info */ - psDevInfo = psDeviceNode->pvDevice; - - PDUMPCOMMENT(psDeviceNode, "PDUMP VERIFY CORE_ID registers for all OSIDs\n"); - - /* construct the value to match against */ - if ((ui64GivenBVNC | ui64CoreIdMask) == 0) /* both zero means use configured DDK value */ - { - ui64MatchBVNC = rgx_bvnc_pack(psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); - } - else - { - /* use the value in CORE_ID for any zero elements in the BVNC */ - ui64MatchBVNC = (ui64GivenBVNC & ~ui64CoreIdMask) | (OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_ID) & ui64CoreIdMask); - } - PVR_LOG(("matchBVNC %d.%d.%d.%d", - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_B) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_V) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_N) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_C) & 0xffff))); - - /* read in all the CORE_ID registers */ - for (i = 0; i < NUM_RGX_CORE_IDS; ++i) - { -#if !defined(NO_HARDWARE) - IMG_UINT64 ui64BVNC = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CORE_ID + (i << 16)); - - PVR_LOG(("CORE_ID%d returned %d.%d.%d.%d", i, - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_B) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_V) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_N) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_C) & 0xffff))); - - if (ui64BVNC != ui64MatchBVNC) - { - eError = PVRSRV_ERROR_BVNC_MISMATCH; - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid CORE_ID%d %d.%d.%d.%d, Expected %d.%d.%d.%d", __func__, i, - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_B) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_V) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_N) & 0xffff), - (int) ((ui64BVNC >> RGX_BVNC_PACK_SHIFT_C) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_B) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_V) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_N) & 0xffff), - (int) ((ui64MatchBVNC >> RGX_BVNC_PACK_SHIFT_C) & 0xffff))); - break; - } -#endif - -#if defined(SUPPORT_VALIDATION) && defined(NO_HARDWARE) && defined(PDUMP) - /* check upper DWORD */ - eError = PDUMPREGPOL(psDeviceNode, RGX_PDUMPREG_NAME, - (RGX_CR_CORE_ID + 4) + (i << 16), - (IMG_UINT32)(ui64MatchBVNC >> 32), - 0xFFFFFFFF, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - if (eError == PVRSRV_OK) - { - /* check lower DWORD */ - eError = PDUMPREGPOL(psDeviceNode, RGX_PDUMPREG_NAME, - RGX_CR_CORE_ID + (i << 16), - (IMG_UINT32)(ui64MatchBVNC & 0xFFFFFFFF), - 0xFFFFFFFF, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - } -#endif - } - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.h b/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.h deleted file mode 100644 index 64c418bc4edb1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxbvnc.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title BVNC handling specific header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the BVNC related work - (see hwdefs/km/rgx_bvnc_table_km.h and - hwdefs/km/rgx_bvnc_defs_km.h -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXBVNC_H) -#define RGXBVNC_H - -#include "pvrsrv_error.h" -#include "img_types.h" -#include "rgxdevice.h" - -/*************************************************************************/ /*! -@brief This function detects the Rogue variant and configures the - essential config info associated with such a device. - The config info includes features, errata, etc -@param psDeviceNode - Device Node pointer -@return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXBvncInitialiseConfiguration(PVRSRV_DEVICE_NODE *psDeviceNode); - -/*************************************************************************/ /*! -@brief This function checks if a particular feature is available on - the given rgx device -@param psDeviceNode - Device Node pointer -@param ui64FeatureMask - feature to be checked -@return true if feature is supported, false otherwise -*/ /**************************************************************************/ -IMG_BOOL RGXBvncCheckFeatureSupported(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64 ui64FeatureMask); - -/*************************************************************************/ /*! -@brief This function returns the value of a feature on the given - rgx device -@param psDeviceNode - Device Node pointer -@param ui64FeatureMask - feature for which to return the value -@return the value for the specified feature -*/ /**************************************************************************/ -IMG_INT32 RGXBvncGetSupportedFeatureValue(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_FEATURE_WITH_VALUE_INDEX eFeatureIndex); - -/*************************************************************************/ /*! -@brief This function validates that the BVNC values in CORE_ID regs are - consistent and correct. -@param psDeviceNode - Device Node pointer -@param GivenBVNC - BVNC to be verified against as supplied by caller -@param CoreIdMask - mask of components to pull from CORE_ID register -@return success or fail -*/ /**************************************************************************/ -PVRSRV_ERROR RGXVerifyBVNC(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64 ui64GivenBVNC, IMG_UINT64 ui64CoreIdMask); - -#endif /* RGXBVNC_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxccb.c b/drivers/gpu/drm/img-rogue/1.17/rgxccb.c deleted file mode 100644 index 053ea0330c49d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxccb.c +++ /dev/null @@ -1,2800 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX CCB routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX CCB routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_debug.h" -#include "rgxdevice.h" -#include "pdump_km.h" -#include "allocmem.h" -#include "devicemem.h" -#include "rgxfwutils.h" -#include "osfunc.h" -#include "rgxccb.h" -#include "rgx_memallocflags.h" -#include "devicemem_pdump.h" -#include "dllist.h" -#if defined(__linux__) -#include "trace_events.h" -#endif -#include "sync_checkpoint_external.h" -#include "sync_checkpoint.h" -#include "rgxutils.h" -#include "info_page.h" -#include "rgxtimerquery.h" - -#if defined(PVRSRV_FORCE_FLUSH_CCCB_ON_KICK) -#include "cache_km.h" -#endif - -/* - * Uncomment PVRSRV_ENABLE_CCCB_UTILISATION_INFO define for verbose - * info and statistics regarding CCB usage. - */ -//#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO - -/* Default threshold (as a percentage) for the PVRSRV_ENABLE_CCCB_UTILISATION_INFO feature. */ -#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO_THRESHOLD (90) - -/* - * Defines the number of fence updates to record so that future fences in the - * CCB. Can be checked to see if they are already known to be satisfied. - */ -#define RGX_CCCB_FENCE_UPDATE_LIST_SIZE (32) - -#define RGX_UFO_PTR_ADDR(ufoptr) \ - (((ufoptr)->puiAddrUFO.ui32Addr) & 0xFFFFFFFC) - -#define GET_CCB_SPACE(WOff, ROff, CCBSize) \ - ((((ROff) - (WOff)) + ((CCBSize) - 1)) & ((CCBSize) - 1)) - -#define UPDATE_CCB_OFFSET(Off, PacketSize, CCBSize) \ - (Off) = (((Off) + (PacketSize)) & ((CCBSize) - 1)) - -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - -#define PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_THRESHOLD 0x1 -#define PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_ACQUIRE_FAILED 0x2 -#define PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_FULL_CCB 0x4 - -typedef struct _RGX_CLIENT_CCB_UTILISATION_ -{ - /* the threshold in bytes. - * when the CCB utilisation hits the threshold then we will print - * a warning message. - */ - IMG_UINT32 ui32ThresholdBytes; - /* Maximum cCCB usage at some point in time */ - IMG_UINT32 ui32HighWaterMark; - /* keep track of the warnings already printed. - * bit mask of PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_xyz - */ - IMG_UINT32 ui32Warnings; - /* Keep track how many times CCB was full. - * Counters are reset after every grow. - */ - IMG_UINT32 ui32CCBFull; - IMG_UINT32 ui32CCBAcquired; -} RGX_CLIENT_CCB_UTILISATION; - -#endif /* PVRSRV_ENABLE_CCCB_UTILISATION_INFO */ - -struct _RGX_CLIENT_CCB_ { - volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl; /*!< CPU mapping of the CCB control structure used by the fw */ - void *pvClientCCB; /*!< CPU mapping of the CCB */ - DEVMEM_MEMDESC *psClientCCBMemDesc; /*!< MemDesc for the CCB */ - DEVMEM_MEMDESC *psClientCCBCtrlMemDesc; /*!< MemDesc for the CCB control */ - IMG_UINT32 ui32HostWriteOffset; /*!< CCB write offset from the driver side */ - IMG_UINT32 ui32LastPDumpWriteOffset; /*!< CCB write offset from the last time we submitted a command in capture range */ - IMG_UINT32 ui32FinishedPDumpWriteOffset; /*!< Trails LastPDumpWriteOffset for last finished command, used for HW CB driven DMs */ - IMG_UINT32 ui32LastROff; /*!< Last CCB Read offset to help detect any CCB wedge */ - IMG_UINT32 ui32LastWOff; /*!< Last CCB Write offset to help detect any CCB wedge */ - IMG_UINT32 ui32ByteCount; /*!< Count of the number of bytes written to CCCB */ - IMG_UINT32 ui32LastByteCount; /*!< Last value of ui32ByteCount to help detect any CCB wedge */ - IMG_UINT32 ui32Size; /*!< Size of the CCB */ -#if defined(PVRSRV_ENABLE_CCCB_GROW) - POS_LOCK hCCBGrowLock; /*!< Prevents CCB Grow while DumpCCB() is called and vice versa */ - IMG_UINT32 ui32VirtualAllocSize; /*!< Virtual size of the CCB */ - IMG_UINT32 ui32ChunkSize; /*!< CCB Sparse allocation chunk size */ - IMG_PUINT32 pui32MappingTable; /*!< Mapping table for sparse allocation of the CCB */ -#endif - DLLIST_NODE sNode; /*!< Node used to store this CCB on the per connection list */ - PDUMP_CONNECTION_DATA *psPDumpConnectionData; /*!< Pointer to the per connection data in which we reside */ - void *hTransition; /*!< Handle for Transition callback */ - IMG_CHAR szName[MAX_CLIENT_CCB_NAME]; /*!< Name of this client CCB */ - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; /*!< Parent server common context that this CCB belongs to */ -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - RGX_CCB_REQUESTOR_TYPE eRGXCCBRequestor; - RGX_CLIENT_CCB_UTILISATION sUtilisation; /*!< CCB utilisation data */ -#endif -#if defined(DEBUG) - IMG_UINT32 ui32UpdateEntries; /*!< Number of Fence Updates in asFenceUpdateList */ - RGXFWIF_UFO asFenceUpdateList[RGX_CCCB_FENCE_UPDATE_LIST_SIZE]; /*!< List of recent updates written in this CCB */ -#endif - IMG_UINT32 ui32CCBFlags; /*!< Bitmask for various flags relating to CCB. Bit defines in rgxccb.h */ -}; - -/* Forms a table, with array of strings for each requestor type (listed in RGX_CCB_REQUESTORS X macro), to be used for - DevMemAllocation comments and PDump comments. Each tuple in the table consists of 3 strings: - { "FwClientCCB:" , "FwClientCCBControl:" , }, - The first string being used as comment when allocating ClientCCB for the given requestor, the second for CCBControl - structure, and the 3rd one for use in PDUMP comments. The number of tuples in the table must adhere to the following - build assert. */ -const IMG_CHAR *const aszCCBRequestors[][3] = -{ -#define REQUESTOR_STRING(prefix,req) #prefix ":" #req -#define FORM_REQUESTOR_TUPLE(req) { REQUESTOR_STRING(FwClientCCB,req), REQUESTOR_STRING(FwClientCCBControl,req), #req }, - RGX_CCB_REQUESTORS(FORM_REQUESTOR_TUPLE) -#undef FORM_REQUESTOR_TUPLE -}; - -PVRSRV_ERROR RGXCCBPDumpDrainCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32PDumpFlags) -{ - - IMG_UINT32 ui32PollOffset; -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psClientCCB->psServerCommonContext); -#endif - - if (BIT_ISSET(psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN)) - { - /* Draining CCB on a command that hasn't finished, and FW isn't expected - * to have updated Roff up to Woff. Only drain to the first - * finished command prior to this. The Roff for this - * is stored in ui32FinishedPDumpWriteOffset. - */ - ui32PollOffset = psClientCCB->ui32FinishedPDumpWriteOffset; - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - ui32PDumpFlags, - "cCCB(%s@%p): Draining open CCB rgxfw_roff < woff (%d)", - psClientCCB->szName, - psClientCCB, - ui32PollOffset); - } - else - { - /* Command to a finished CCB stream and FW is drained to empty - * out remaining commands until R==W. - */ - ui32PollOffset = psClientCCB->ui32LastPDumpWriteOffset; - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - ui32PDumpFlags, - "cCCB(%s@%p): Draining CCB rgxfw_roff == woff (%d)", - psClientCCB->szName, - psClientCCB, - ui32PollOffset); - } - - return DevmemPDumpDevmemPol32(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - ui32PollOffset, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); -} - -/****************************************************************************** - FUNCTION : RGXCCBPDumpSyncCCB - - PURPOSE : Synchronise Client CCBs from both live and playback contexts. - Waits for live-FW to empty live-CCB. - Waits for sim-FW to empty sim-CCB by adding POL - - PARAMETERS : psClientCCB - The client CCB - ui32PDumpFlags - PDump flags - - RETURNS : PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXCCBPDumpSyncCCB(RGX_CLIENT_CCB *psClientCCB, IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - /* Wait for the live FW to catch up/empty CCB. This is done by returning - * retry which will get pushed back out to Services client where it - * waits on the event object and then resubmits the command. - */ - if (psClientCCB->psClientCCBCtrl->ui32ReadOffset != psClientCCB->ui32HostWriteOffset) - { - return PVRSRV_ERROR_RETRY; - } - - /* Wait for the sim FW to catch up/empty sim CCB. - * We drain whenever capture range is entered, even if no commands - * have been issued on this CCB when out of capture range. We have to - * wait for commands that might have been issued in the last capture - * range to finish so the connection's sync block snapshot dumped after - * all the PDumpTransition callbacks have been execute doesn't clobber - * syncs which the sim FW is currently working on. - * - * Although this is sub-optimal for play-back - while out of capture - * range for every continuous operation we synchronise the sim - * play-back processing the script and the sim FW, there is no easy - * solution. Not all modules that work with syncs register a - * PDumpTransition callback and thus we have no way of knowing if we - * can skip this sim CCB drain and sync block dump or not. - */ - - eError = RGXCCBPDumpDrainCCB(psClientCCB, ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "RGXCCBPDumpDrainCCB"); - PVR_ASSERT(eError == PVRSRV_OK); - - /* Live CCB and simulation CCB now empty, FW idle on CCB in both - * contexts. - */ - return PVRSRV_OK; -} - -/****************************************************************************** - FUNCTION : RGXCCBPDumpFastForwardCCB - - PURPOSE : Fast-forward sim-CCB and live-CCB offsets to live app-thread - values. - This helps to skip any commands submitted when out of capture - range and start with first command in capture range in both - live and playback contexts. In case of Block mode, this helps - to playback any intermediate PDump block directly after first - block. - - - PARAMETERS : psClientCCB - The client CCB - ui32PDumpFlags - PDump flags - - RETURNS : void -******************************************************************************/ -static void RGXCCBPDumpFastForwardCCB(RGX_CLIENT_CCB *psClientCCB, IMG_UINT32 ui32PDumpFlags) -{ - volatile RGXFWIF_CCCB_CTL *psCCBCtl = psClientCCB->psClientCCBCtrl; -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psClientCCB->psServerCommonContext); -#endif - - /* Make sure that we have synced live-FW and live-App threads */ - PVR_ASSERT(psCCBCtl->ui32ReadOffset == psClientCCB->ui32HostWriteOffset); - - psCCBCtl->ui32ReadOffset = psClientCCB->ui32HostWriteOffset; - psCCBCtl->ui32DepOffset = psClientCCB->ui32HostWriteOffset; - psCCBCtl->ui32WriteOffset = psClientCCB->ui32HostWriteOffset; -#if defined(SUPPORT_AGP) - psCCBCtl->ui32ReadOffset2 = psClientCCB->ui32HostWriteOffset; -#if defined(SUPPORT_AGP4) - psCCBCtl->ui32ReadOffset3 = psClientCCB->ui32HostWriteOffset; - psCCBCtl->ui32ReadOffset4 = psClientCCB->ui32HostWriteOffset; -#endif -#endif - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - ui32PDumpFlags, - "cCCB(%s@%p): Fast-forward from %d to %d", - psClientCCB->szName, - psClientCCB, - psClientCCB->ui32LastPDumpWriteOffset, - psClientCCB->ui32HostWriteOffset); - - DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc, - 0, - sizeof(RGXFWIF_CCCB_CTL), - ui32PDumpFlags); - - /* Although we've entered capture range for this process connection - * we might not do any work on this CCB so update the - * ui32LastPDumpWriteOffset to reflect where we got to for next - * time so we start the drain from where we got to last time. - */ - psClientCCB->ui32LastPDumpWriteOffset = psClientCCB->ui32HostWriteOffset; - -} - -static PVRSRV_ERROR _RGXCCBPDumpTransition(void *pvData, void *pvDevice, PDUMP_TRANSITION_EVENT eEvent, IMG_UINT32 ui32PDumpFlags) -{ - RGX_CLIENT_CCB *psClientCCB = (RGX_CLIENT_CCB *) pvData; -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) pvDevice; -#endif - PVRSRV_ERROR eError; - - /* Block mode: - * Here is block structure at transition (ui32BlockLength=N frames): - * - * ... - * ... - * PDUMP_BLOCK_START_0x0000000x{ - * - * - * ... - * ... - * ... (N frames data) - * ... - * ... - * <(1) Drain sim-KCCB> ''| - * <(2) Sync live and sim CCCB> | - * }PDUMP_BLOCK_END_0x0000000x | <- BlockTransition Steps - * <(3) Split MAIN and BLOCK stream script> | - * PDUMP_BLOCK_START_0x0000000y{ | - * <(4) Fast-forward sim-CCCB> | - * <(5) Re-dump SyncBlocks> ,,| - * ... - * ... - * ... (N frames data) - * ... - * ... - * - * - * }PDUMP_BLOCK_END_0x0000000y - * ... - * ... - * - * Steps (3) and (5) are done in pdump_server.c - * */ - switch (eEvent) - { - case PDUMP_TRANSITION_EVENT_RANGE_ENTERED: - { - /* We're about to transition into capture range and we've submitted - * new commands since the last time we entered capture range so drain - * the live CCB and simulation (sim) CCB as required, i.e. leave CCB - * idle in both live and sim contexts. - * This requires the host driver to ensure the live FW & the sim FW - * have both emptied out the remaining commands until R==W (CCB empty). - */ - - eError = RGXCCBPDumpSyncCCB(psClientCCB, ui32PDumpFlags); - PVR_RETURN_IF_ERROR(eError); - - if (psClientCCB->ui32LastPDumpWriteOffset != psClientCCB->ui32HostWriteOffset) - { - /* If new commands have been written when out of capture range in - * the live CCB then we need to fast forward the sim CCBCtl - * offsets past uncaptured commands. This is done by PDUMPing - * the CCBCtl memory to align sim values with the live CCBCtl - * values. Both live and sim FWs can start with the 1st command - * which is in the new capture range. - */ - RGXCCBPDumpFastForwardCCB(psClientCCB, ui32PDumpFlags); - } - break; - } - case PDUMP_TRANSITION_EVENT_RANGE_EXITED: - { - /* Nothing to do */ - break; - } - case PDUMP_TRANSITION_EVENT_BLOCK_FINISHED: - { - /* (1) Drain KCCB from current block before starting new: - * - * At playback, this will ensure that sim-FW drains all commands in KCCB - * belongs to current block before 'jumping' to any future commands (from - * next block). This will synchronise script-thread and sim-FW thread KCCBs - * at end of each pdump block. - * - * This will additionally force redump of KCCBCtl structure at start of next/new block. - * */ - -#if defined(PDUMP) - eError = RGXPdumpDrainKCCB(psDevInfo, psDevInfo->psKernelCCBCtl->ui32WriteOffset); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXPdumpDrainKCCB"); -#endif - - /* (2) Synchronise Client CCBs from live and playback contexts before starting new block: - * - * This operation will, - * a. Force synchronisation between app-thread and live-FW thread (i.e. Wait - * for live-FW to empty live Client CCB). - * - * b. Next, it will dump poll command to drain Client CCB at end of every - * pdump block. At playback time this will synchronise sim-FW and - * script-thread Client CCBs at end of each block. - * - * This is to ensure that all commands in CCB from current block are processed - * before moving on to future commands. - * */ - - eError = RGXCCBPDumpSyncCCB(psClientCCB, ui32PDumpFlags); - PVR_RETURN_IF_ERROR(eError); - break; - } - case PDUMP_TRANSITION_EVENT_BLOCK_STARTED: - { - /* (4) Fast-forward CCB write offsets to current live values: - * - * We have already synchronised live-FW and app-thread above at end of each - * block (in Step 2a above), now fast-forward Client CCBCtl write offsets to that of - * current app-thread values at start of every block. This will allow us to - * skip any intermediate pdump blocks and start with last (or any next) block - * immediately after first pdump block. - * */ - - RGXCCBPDumpFastForwardCCB(psClientCCB, ui32PDumpFlags); - break; - } - case PDUMP_TRANSITION_EVENT_NONE: - /* Invalid event for transition */ - default: - { - /* Unknown Transition event */ - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - return PVRSRV_OK; -} - -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - -static INLINE void _RGXInitCCBUtilisation(RGX_CLIENT_CCB *psClientCCB) -{ - psClientCCB->sUtilisation.ui32HighWaterMark = 0; /* initialize ui32HighWaterMark level to zero */ - psClientCCB->sUtilisation.ui32ThresholdBytes = (psClientCCB->ui32Size * - PVRSRV_ENABLE_CCCB_UTILISATION_INFO_THRESHOLD) / 100; - psClientCCB->sUtilisation.ui32Warnings = 0; - psClientCCB->sUtilisation.ui32CCBAcquired = 0; - psClientCCB->sUtilisation.ui32CCBFull = 0; -} - -static INLINE void _RGXCCBUtilisationEvent(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32WarningType, - IMG_UINT32 ui32CmdSize) -{ - /* in VERBOSE mode we will print a message for each different - * event type as they happen. - */ -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - if (!(psClientCCB->sUtilisation.ui32Warnings & ui32WarningType)) - { - if (ui32WarningType == PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_ACQUIRE_FAILED) - { - PVR_LOG(("Failed to acquire CCB space for %u byte command:", ui32CmdSize)); - } - - PVR_LOG(("%s: Client CCB (%s) watermark (%u) hit %d%% of its allocation size (%u)", - __func__, - psClientCCB->szName, - psClientCCB->sUtilisation.ui32HighWaterMark, - psClientCCB->sUtilisation.ui32HighWaterMark * 100 / psClientCCB->ui32Size, - psClientCCB->ui32Size)); - - /* record that we have issued a warning of this type */ - psClientCCB->sUtilisation.ui32Warnings |= ui32WarningType; - } -#else - PVR_UNREFERENCED_PARAMETER(psClientCCB); - PVR_UNREFERENCED_PARAMETER(ui32WarningType); - PVR_UNREFERENCED_PARAMETER(ui32CmdSize); -#endif -} - -/* Check the current CCB utilisation. Print a one-time warning message if it is above the - * specified threshold - */ -static INLINE void _RGXCheckCCBUtilisation(RGX_CLIENT_CCB *psClientCCB) -{ - /* Print a warning message if the cCCB watermark is above the threshold value */ - if (psClientCCB->sUtilisation.ui32HighWaterMark >= psClientCCB->sUtilisation.ui32ThresholdBytes) - { - _RGXCCBUtilisationEvent(psClientCCB, - PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_THRESHOLD, - 0); - } -} - -/* Update the cCCB high watermark level if necessary */ -static void _RGXUpdateCCBUtilisation(RGX_CLIENT_CCB *psClientCCB) -{ - IMG_UINT32 ui32FreeSpace, ui32MemCurrentUsage; - - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - ui32MemCurrentUsage = psClientCCB->ui32Size - ui32FreeSpace; - - if (ui32MemCurrentUsage > psClientCCB->sUtilisation.ui32HighWaterMark) - { - psClientCCB->sUtilisation.ui32HighWaterMark = ui32MemCurrentUsage; - - /* The high water mark has increased. Check if it is above the - * threshold so we can print a warning if necessary. - */ - _RGXCheckCCBUtilisation(psClientCCB); - } -} - -#endif /* PVRSRV_ENABLE_CCCB_UTILISATION_INFO */ - -PVRSRV_ERROR RGXCreateCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32CCBSizeLog2, - IMG_UINT32 ui32CCBMaxSizeLog2, - IMG_UINT32 ui32ContextFlags, - CONNECTION_DATA *psConnectionData, - RGX_CCB_REQUESTOR_TYPE eRGXCCBRequestor, - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - RGX_CLIENT_CCB **ppsClientCCB, - DEVMEM_MEMDESC **ppsClientCCBMemDesc, - DEVMEM_MEMDESC **ppsClientCCBCtrlMemDesc) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_MEMALLOCFLAGS_T uiClientCCBMemAllocFlags, uiClientCCBCtlMemAllocFlags; - IMG_UINT32 ui32FWMainLog2PageSize = DevmemGetHeapLog2PageSize(psDevInfo->psFirmwareMainHeap); - IMG_UINT32 ui32ChunkSize = (1U << ui32FWMainLog2PageSize); - IMG_UINT32 ui32AllocSize = MAX((1U << ui32CCBSizeLog2), ui32ChunkSize); - IMG_UINT32 ui32MinAllocSize = MAX((1U << MIN_SAFE_CCB_SIZE_LOG2), ui32ChunkSize); - RGX_CLIENT_CCB *psClientCCB; -#if defined(PVRSRV_ENABLE_CCCB_GROW) - IMG_UINT32 ui32NumChunks = ui32AllocSize / ui32ChunkSize; - IMG_UINT32 ui32VirtualAllocSize = (1U << ui32CCBMaxSizeLog2); - IMG_UINT32 ui32NumVirtChunks = ui32VirtualAllocSize / ui32ChunkSize; - IMG_UINT32 i; - - /* For the allocation request to be valid, at least one page is required. - * This is relevant on systems where the page size is greater than the client CCB size. */ - ui32NumVirtChunks = MAX(1, ui32NumVirtChunks); - PVR_ASSERT((ui32ChunkSize >= (1U << PAGE_SHIFT))); -#else - PVR_UNREFERENCED_PARAMETER(ui32CCBMaxSizeLog2); -#endif /* defined(PVRSRV_ENABLE_CCCB_GROW) */ - - /* All client CCBs should be at-least of the "minimum" size and not to exceed "maximum" */ - if ((ui32CCBSizeLog2 < MIN_SAFE_CCB_SIZE_LOG2) || - (ui32CCBSizeLog2 > MAX_SAFE_CCB_SIZE_LOG2)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s CCB size is invalid (%d). Should be from %d to %d", - __func__, - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - ui32CCBSizeLog2, MIN_SAFE_CCB_SIZE_LOG2, MAX_SAFE_CCB_SIZE_LOG2)); - return PVRSRV_ERROR_INVALID_PARAMS; - } -#if defined(PVRSRV_ENABLE_CCCB_GROW) - if ((ui32CCBMaxSizeLog2 < ui32CCBSizeLog2) || - (ui32CCBMaxSizeLog2 > MAX_SAFE_CCB_SIZE_LOG2)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s CCB maximum size is invalid (%d). Should be from %d to %d", - __func__, - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - ui32CCBMaxSizeLog2, ui32CCBSizeLog2, MAX_SAFE_CCB_SIZE_LOG2)); - return PVRSRV_ERROR_INVALID_PARAMS; - } -#endif - - psClientCCB = OSAllocMem(sizeof(*psClientCCB)); - if (psClientCCB == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc; - } - psClientCCB->psServerCommonContext = psServerCommonContext; - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - psClientCCB->ui32VirtualAllocSize = 0; - psClientCCB->pui32MappingTable = NULL; - psClientCCB->ui32ChunkSize = ui32ChunkSize; -#endif - - uiClientCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN); - - uiClientCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN); - - /* If connection data indicates Sync Lockup Recovery (SLR) should be disabled, - * or if the caller has set ui32ContextFlags to disable SLR for this context, - * indicate this in psClientCCB->ui32CCBFlags. - */ - if ((psConnectionData->ui32ClientFlags & SRV_FLAGS_CLIENT_SLR_DISABLED) || - (ui32ContextFlags & RGX_CONTEXT_FLAG_DISABLESLR)) - { - BIT_SET(psClientCCB->ui32CCBFlags, CCB_FLAGS_SLR_DISABLED); - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Allocate RGXFW cCCB"); -#if defined(PVRSRV_ENABLE_CCCB_GROW) - if (BITMASK_HAS(psDevInfo->ui32DeviceFlags, RGXKM_DEVICE_STATE_CCB_GROW_EN)) - { - PHYS_HEAP *psPhysHeap = psDevInfo->psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]; - PHYS_HEAP_TYPE eHeapType = PhysHeapGetType(psPhysHeap); - - psClientCCB->ui32VirtualAllocSize = ui32VirtualAllocSize; - - /* - * Growing CCB is doubling the size. Last grow would require only ui32NumVirtChunks/2 new chunks - * because another ui32NumVirtChunks/2 is already allocated. - * Sometimes initial chunk count would be higher (when CCB size is equal to CCB maximum size) so MAX is needed. - */ - psClientCCB->pui32MappingTable = OSAllocMem(MAX(ui32NumChunks, ui32NumVirtChunks/2) * sizeof(IMG_UINT32)); - if (psClientCCB->pui32MappingTable == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc_mtable; - } - for (i = 0; i < ui32NumChunks; i++) - { - psClientCCB->pui32MappingTable[i] = i; - } - - if (eHeapType == PHYS_HEAP_TYPE_LMA || - eHeapType == PHYS_HEAP_TYPE_DMA) - { - /* - * On LMA sparse memory can't be mapped to kernel. - * To work around this whole ccb memory is allocated at once as contiguous. - */ - eError = DevmemFwAllocate(psDevInfo, - ui32VirtualAllocSize, - uiClientCCBMemAllocFlags, - aszCCBRequestors[eRGXCCBRequestor][REQ_RGX_FW_CLIENT_CCB_STRING], - &psClientCCB->psClientCCBMemDesc); - } - else - { - eError = DevmemFwAllocateSparse(psDevInfo, - ui32VirtualAllocSize, - ui32ChunkSize, - ui32NumChunks, - ui32NumVirtChunks, - psClientCCB->pui32MappingTable, - uiClientCCBMemAllocFlags, - aszCCBRequestors[eRGXCCBRequestor][REQ_RGX_FW_CLIENT_CCB_STRING], - &psClientCCB->psClientCCBMemDesc); - } - } - - if (eError != PVRSRV_OK) - { - OSFreeMem(psClientCCB->pui32MappingTable); - psClientCCB->pui32MappingTable = NULL; - psClientCCB->ui32VirtualAllocSize = 0; - } - - if (!BITMASK_HAS(psDevInfo->ui32DeviceFlags, RGXKM_DEVICE_STATE_CCB_GROW_EN) || - (eError != PVRSRV_OK)) -#endif /* defined(PVRSRV_ENABLE_CCCB_GROW) */ - { - /* Allocate ui32AllocSize, or the next best POT allocation */ - do - { - eError = DevmemFwAllocate(psDevInfo, - ui32AllocSize, - uiClientCCBMemAllocFlags, - aszCCBRequestors[eRGXCCBRequestor][REQ_RGX_FW_CLIENT_CCB_STRING], - &psClientCCB->psClientCCBMemDesc); - if (eError != PVRSRV_OK) - { - /* Failed to allocate - ensure CCB grow is disabled from - * now on for this device. - */ - BITMASK_UNSET(psDevInfo->ui32DeviceFlags, RGXKM_DEVICE_STATE_CCB_GROW_EN); - - /* Failed to allocate, try next POT down */ - ui32AllocSize >>= 1; - } - } while ((eError != PVRSRV_OK) && (ui32AllocSize > ui32MinAllocSize)); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate RGX client CCB (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_alloc_ccb; - } - - OSSNPrintf(psClientCCB->szName, MAX_CLIENT_CCB_NAME, "%s-P%lu-T%lu-%s", - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - (unsigned long) OSGetCurrentClientProcessIDKM(), - (unsigned long) OSGetCurrentClientThreadIDKM(), - OSGetCurrentClientProcessNameKM()); - - if (ui32AllocSize < (1U << ui32CCBSizeLog2)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Unable to allocate %d bytes for RGX client CCB (%s) but allocated %d bytes", - __func__, - (1U << ui32CCBSizeLog2), - psClientCCB->szName, - ui32AllocSize)); - } - - eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBMemDesc, - &psClientCCB->pvClientCCB); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map RGX client CCB (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_map_ccb; - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Allocate RGXFW cCCB control"); - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_CCCB_CTL), - uiClientCCBCtlMemAllocFlags, - aszCCBRequestors[eRGXCCBRequestor][REQ_RGX_FW_CLIENT_CCB_CONTROL_STRING], - &psClientCCB->psClientCCBCtrlMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate RGX client CCB control (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_alloc_ccbctrl; - } - - - eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc, - (void **) &psClientCCB->psClientCCBCtrl); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map RGX client CCB control (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_map_ccbctrl; - } - - /* psClientCCBCtrlMemDesc was zero alloc'd so no need to initialise offsets. */ - psClientCCB->psClientCCBCtrl->ui32WrapMask = ui32AllocSize - 1; - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "cCCB control"); - DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc, - 0, - sizeof(RGXFWIF_CCCB_CTL), - PDUMP_FLAGS_CONTINUOUS); - PVR_ASSERT(eError == PVRSRV_OK); - - psClientCCB->ui32HostWriteOffset = 0; - psClientCCB->ui32LastPDumpWriteOffset = 0; - psClientCCB->ui32FinishedPDumpWriteOffset = 0; - psClientCCB->ui32Size = ui32AllocSize; - psClientCCB->ui32LastROff = ui32AllocSize - 1; - psClientCCB->ui32ByteCount = 0; - psClientCCB->ui32LastByteCount = 0; - BIT_UNSET(psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN); - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - eError = OSLockCreate(&psClientCCB->hCCBGrowLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to create hCCBGrowLock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_create_ccbgrow_lock; - } -#endif -#if defined(DEBUG) - psClientCCB->ui32UpdateEntries = 0; -#endif - -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - _RGXInitCCBUtilisation(psClientCCB); - psClientCCB->eRGXCCBRequestor = eRGXCCBRequestor; -#endif - eError = PDumpRegisterTransitionCallback(psConnectionData->psPDumpConnectionData, - _RGXCCBPDumpTransition, - psClientCCB, - psDevInfo, - &psClientCCB->hTransition); - if (eError != PVRSRV_OK) - { - goto fail_pdumpreg; - } - - /* - * Note: - * Save the PDump specific structure, which is ref counted unlike - * the connection data, to ensure it's not freed too early - */ - psClientCCB->psPDumpConnectionData = psConnectionData->psPDumpConnectionData; - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "New RGXFW cCCB(%s@%p) created", - psClientCCB->szName, - psClientCCB); - - *ppsClientCCB = psClientCCB; - *ppsClientCCBMemDesc = psClientCCB->psClientCCBMemDesc; - *ppsClientCCBCtrlMemDesc = psClientCCB->psClientCCBCtrlMemDesc; - return PVRSRV_OK; - -fail_pdumpreg: -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockDestroy(psClientCCB->hCCBGrowLock); -fail_create_ccbgrow_lock: -#endif - DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc); -fail_map_ccbctrl: - DevmemFwUnmapAndFree(psDevInfo, psClientCCB->psClientCCBCtrlMemDesc); -fail_alloc_ccbctrl: - DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc); -fail_map_ccb: - DevmemFwUnmapAndFree(psDevInfo, psClientCCB->psClientCCBMemDesc); -#if defined(PVRSRV_ENABLE_CCCB_GROW) -fail_alloc_ccb: - if ( psClientCCB->ui32VirtualAllocSize > 0) - { - OSFreeMem(psClientCCB->pui32MappingTable); - } -fail_alloc_mtable: -#else -fail_alloc_ccb: -#endif - OSFreeMem(psClientCCB); -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -void RGXDestroyCCB(PVRSRV_RGXDEV_INFO *psDevInfo, RGX_CLIENT_CCB *psClientCCB) -{ -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - if (psClientCCB->sUtilisation.ui32CCBFull) - { - PVR_LOG(("CCBUtilisationInfo: GPU %s command buffer was full %d times out of %d. " - "This is not an error but the application may not run optimally.", - aszCCBRequestors[psClientCCB->eRGXCCBRequestor][REQ_PDUMP_COMMENT], - psClientCCB->sUtilisation.ui32CCBFull, - psClientCCB->sUtilisation.ui32CCBAcquired)); - } -#endif -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockDestroy(psClientCCB->hCCBGrowLock); -#endif - PDumpUnregisterTransitionCallback(psClientCCB->hTransition); - DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psClientCCB->psClientCCBCtrlMemDesc); - DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psClientCCB->psClientCCBMemDesc); -#if defined(PVRSRV_ENABLE_CCCB_GROW) - if (psClientCCB->pui32MappingTable) - { - OSFreeMem(psClientCCB->pui32MappingTable); - } -#endif - OSFreeMem(psClientCCB); -} - -#if defined(PVRSRV_ENABLE_CCCB_GROW) -static PVRSRV_ERROR _RGXCCBMemChangeSparse(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32AllocPageCount) -{ - PVRSRV_ERROR eError; - IMG_UINT32 i; - -#ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE - DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc); -#endif - - for (i = 0; i < ui32AllocPageCount; i++) - { - psClientCCB->pui32MappingTable[i] = ui32AllocPageCount + i; - } - - /* Double the CCB size (CCB must be POT) by adding ui32AllocPageCount new pages */ - eError = DeviceMemChangeSparse(psClientCCB->psClientCCBMemDesc, - ui32AllocPageCount, - psClientCCB->pui32MappingTable, - 0, - NULL, -#if !defined(PVRSRV_UNMAP_ON_SPARSE_CHANGE) - SPARSE_MAP_CPU_ADDR | -#endif - SPARSE_RESIZE_ALLOC); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXAcquireCCB: Failed to grow RGX client CCB (%s)", - PVRSRVGetErrorString(eError))); - -#ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE - if (DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBMemDesc, - &psClientCCB->pvClientCCB) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXAcquireCCB: Failed to reacquire CCB mapping")); - psClientCCB->pvClientCCB = NULL; - } -#endif - - return eError; - } - -#ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE - eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBMemDesc, - &psClientCCB->pvClientCCB); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXAcquireCCB: Failed to map RGX client CCB (%s)", - PVRSRVGetErrorString(eError))); - return eError; - } -#endif - - return PVRSRV_OK; -} -#endif /* defined(PVRSRV_ENABLE_CCCB_GROW) */ - -PVRSRV_ERROR RGXCheckSpaceCCB(RGX_CLIENT_CCB *psClientCCB, IMG_UINT32 ui32CmdSize) -{ - IMG_UINT32 ui32FreeSpace; - - /* Check that the CCB can hold this command + padding */ - if ((ui32CmdSize + PADDING_COMMAND_SIZE + 1) > psClientCCB->ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "Command size (%d bytes) too big for CCB" - " (%d bytes)", ui32CmdSize, psClientCCB->ui32Size)); - return PVRSRV_ERROR_CMD_TOO_BIG; - } - - /* - Check we don't overflow the end of the buffer and make sure we have - enough space for the padding command. If we don't have enough space - (including the minimum amount for the padding command) we need to make - sure we insert a padding command now and wrap before adding the main - command. - */ - if ((psClientCCB->ui32HostWriteOffset + ui32CmdSize + PADDING_COMMAND_SIZE) <= psClientCCB->ui32Size) - { - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - - /* Don't allow all the space to be used */ - if (ui32FreeSpace > ui32CmdSize) - { - return PVRSRV_OK; - } - - goto e_retry; - } - else - { - IMG_UINT32 ui32Remain = psClientCCB->ui32Size - psClientCCB->ui32HostWriteOffset; - - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - - /* Check there is space for both the command and the padding command */ - if (ui32FreeSpace > ui32Remain + ui32CmdSize) - { - return PVRSRV_OK; - } - - goto e_retry; - } - -e_retry: -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - _RGXCCBUtilisationEvent(psClientCCB, - PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_FULL_CCB, - ui32CmdSize); -#endif /* PVRSRV_ENABLE_CCCB_UTILISATION_INFO */ - - return PVRSRV_ERROR_RETRY; -} - -/****************************************************************************** - FUNCTION : RGXAcquireCCB - - PURPOSE : Obtains access to write some commands to a CCB - - PARAMETERS : psClientCCB - The client CCB - ui32CmdSize - How much space is required - ppvBufferSpace - Pointer to space in the buffer - ui32PDumpFlags - Should this be PDump continuous? - - RETURNS : PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXAcquireCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32CmdSize, - void **ppvBufferSpace, - IMG_UINT32 ui32PDumpFlags) -{ -#if defined(PVRSRV_ENABLE_CCCB_GROW) - IMG_UINT32 ui32RetryCount = 2; -#endif - -#if defined(PDUMP) - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psClientCCB->psServerCommonContext); - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - IMG_BOOL bPDumpEnabled = PDumpCheckFlagsWrite(psDeviceNode, ui32PDumpFlags); - IMG_BOOL bPDumpFlagsContinuous = PDUMP_IS_CONTINUOUS(ui32PDumpFlags); - - /* - PDumpSetFrame will detect as we Transition into capture range for - frame based data but if we are PDumping continuous data then we - need to inform the PDump layer ourselves - - First check is to confirm we are in continuous mode - Second check is to confirm the pdump client is connected and ready. - Third check is to confirm we are not in capture range. - */ - if (bPDumpFlagsContinuous && - bPDumpEnabled && - !PDumpCheckFlagsWrite(psDeviceNode, PDUMP_FLAGS_NONE)) - { - eError = PDumpTransition(psDeviceNode, - psClientCCB->psPDumpConnectionData, - PDUMP_TRANSITION_EVENT_RANGE_ENTERED, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - return eError; - } - } -#endif - - /* Check that the CCB can hold this command + padding */ - if ((ui32CmdSize + PADDING_COMMAND_SIZE + 1) > psClientCCB->ui32Size) - { - PVR_DPF((PVR_DBG_ERROR, "Command size (%d bytes) too big for CCB (%d bytes)", - ui32CmdSize, psClientCCB->ui32Size)); - return PVRSRV_ERROR_CMD_TOO_BIG; - } - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - while (ui32RetryCount--) -#endif - { -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - psClientCCB->sUtilisation.ui32CCBAcquired++; -#endif - - /* - Check we don't overflow the end of the buffer and make sure we have - enough space for the padding command. We don't have enough space (including the - minimum amount for the padding command) we will need to make sure we insert a - padding command now and wrap before adding the main command. - */ - if ((psClientCCB->ui32HostWriteOffset + ui32CmdSize + PADDING_COMMAND_SIZE) <= psClientCCB->ui32Size) - { - /* The command can fit without wrapping... */ - IMG_UINT32 ui32FreeSpace; - -#if defined(PDUMP) - /* Wait for sufficient CCB space to become available */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, 0, - "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s", - ui32CmdSize, psClientCCB->ui32HostWriteOffset, - psClientCCB->szName); - DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - psClientCCB->ui32HostWriteOffset, - ui32CmdSize, - psClientCCB->ui32Size); -#endif - - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - - /* Can command fit? */ - if (ui32FreeSpace > ui32CmdSize) - { - *ppvBufferSpace = IMG_OFFSET_ADDR(psClientCCB->pvClientCCB, psClientCCB->ui32HostWriteOffset); - return PVRSRV_OK; - } - /* There is not enough free space in CCB. */ - goto e_retry; - } - else - { - /* - We're at the end of the buffer without enough contiguous space. - The command cannot fit without wrapping, we need to insert a - padding command and wrap. We need to do this in one go otherwise - we would be leaving unflushed commands and forcing the client to - deal with flushing the padding command but not the command they - wanted to write. Therefore we either do all or nothing. - */ - RGXFWIF_CCB_CMD_HEADER *psHeader; - IMG_UINT32 ui32FreeSpace; - IMG_UINT32 ui32Remain = psClientCCB->ui32Size - psClientCCB->ui32HostWriteOffset; - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - /* Check this is a growable CCB */ - if (psClientCCB->ui32VirtualAllocSize > 0) - { - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psClientCCB->psServerCommonContext); - - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - /* - * Check if CCB should grow or be wrapped. - * Wrap CCB if there is no need for grow (CCB is half empty) or CCB can't grow, - * and when is free space for command and padding. - */ - if (((ui32FreeSpace > psClientCCB->ui32Size/2) || (psClientCCB->ui32Size == psClientCCB->ui32VirtualAllocSize)) && - (ui32FreeSpace > ui32Remain + ui32CmdSize)) - { - /* Wrap CCB */ - psHeader = IMG_OFFSET_ADDR(psClientCCB->pvClientCCB, psClientCCB->ui32HostWriteOffset); - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PADDING; - psHeader->ui32CmdSize = ui32Remain - sizeof(RGXFWIF_CCB_CMD_HEADER); - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, ui32PDumpFlags, - "cCCB(%p): Padding cmd %d", psClientCCB, psHeader->ui32CmdSize); - if (bPDumpEnabled) - { - DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc, - psClientCCB->ui32HostWriteOffset, - ui32Remain, - ui32PDumpFlags); - } -#endif - - *ppvBufferSpace = psClientCCB->pvClientCCB; - return PVRSRV_OK; - } - else if ((psClientCCB->ui32Size < psClientCCB->ui32VirtualAllocSize) && - (psClientCCB->ui32HostWriteOffset >= psClientCCB->psClientCCBCtrl->ui32ReadOffset)) - { - /* Grow CCB */ - PHYS_HEAP *psPhysHeap = psDevInfo->psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]; - PHYS_HEAP_TYPE eHeapType = PhysHeapGetType(psPhysHeap); - PVRSRV_ERROR eErr = PVRSRV_OK; - - /* Something went wrong if we are here a second time */ - PVR_ASSERT(ui32RetryCount != 0); - OSLockAcquire(psClientCCB->hCCBGrowLock); - - /* - * On LMA sparse memory can't be mapped to kernel. - * To work around this whole ccb memory was allocated at once as contiguous. - * In such case below sparse change is not needed because memory is already allocated. - */ - if (eHeapType != PHYS_HEAP_TYPE_LMA && - eHeapType != PHYS_HEAP_TYPE_DMA) - { - IMG_UINT32 ui32AllocChunkCount = psClientCCB->ui32Size / psClientCCB->ui32ChunkSize; - - eErr = _RGXCCBMemChangeSparse(psClientCCB, ui32AllocChunkCount); - } - - /* Setup new CCB size */ - if (eErr == PVRSRV_OK) - { - psClientCCB->ui32Size += psClientCCB->ui32Size; - } - else - { - PVR_LOG(("%s: Client CCB (%s) grow failed (%s)", __func__, psClientCCB->szName, PVRSRVGetErrorString(eErr))); - OSLockRelease(psClientCCB->hCCBGrowLock); - goto e_retry; - } - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, ui32PDumpFlags, "cCCB update for grow"); - if (bPDumpEnabled) - { - DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32WrapMask), - sizeof(psClientCCB->psClientCCBCtrl->ui32WrapMask), - ui32PDumpFlags); - DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc, - offsetof(RGX_CLIENT_CCB, ui32Size), - sizeof(psClientCCB->ui32Size), - ui32PDumpFlags); - } -#endif /* defined(PVRSRV_ENABLE_CCCB_GROW) */ - -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - PVR_LOG(("%s: Client CCB (%s) grew to %u", __func__, psClientCCB->szName, psClientCCB->ui32Size)); - /* Reset counters */ - _RGXInitCCBUtilisation(psClientCCB); -#endif - - /* CCB doubled the size so retry now. */ - OSLockRelease(psClientCCB->hCCBGrowLock); - } - else - { - /* CCB can't grow anymore and can't be wrapped */ -#if defined(PDUMP) - /* Wait for sufficient CCB space to become available */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, 0, - "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s", - ui32Remain, psClientCCB->ui32HostWriteOffset, - psClientCCB->szName); - DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - psClientCCB->ui32HostWriteOffset, - ui32Remain, - psClientCCB->ui32Size); - PDUMPCOMMENTWITHFLAGS(psDeviceNode, 0, - "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s", - ui32CmdSize, 0 /*ui32HostWriteOffset after wrap */, - psClientCCB->szName); - DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - 0 /*ui32HostWriteOffset after wrap */, - ui32CmdSize, - psClientCCB->ui32Size); - /* CCB has now space for our command so try wrapping again. Retry now. */ -#else /* defined(PDUMP) */ - goto e_retry; -#endif /* defined(PDUMP) */ - } - } - else -#endif /* defined(PVRSRV_ENABLE_CCCB_GROW) */ - { -#if defined(PDUMP) - /* Wait for sufficient CCB space to become available */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, 0, - "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s", - ui32Remain, psClientCCB->ui32HostWriteOffset, - psClientCCB->szName); - DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - psClientCCB->ui32HostWriteOffset, - ui32Remain, - psClientCCB->ui32Size); - PDUMPCOMMENTWITHFLAGS(psDeviceNode, 0, - "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s", - ui32CmdSize, 0 /*ui32HostWriteOffset after wrap */, - psClientCCB->szName); - DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc, - offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset), - 0 /*ui32HostWriteOffset after wrap */, - ui32CmdSize, - psClientCCB->ui32Size); -#endif - ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset, - psClientCCB->psClientCCBCtrl->ui32ReadOffset, - psClientCCB->ui32Size); - - if (ui32FreeSpace > ui32Remain + ui32CmdSize) - { - psHeader = IMG_OFFSET_ADDR(psClientCCB->pvClientCCB, psClientCCB->ui32HostWriteOffset); - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PADDING; - psHeader->ui32CmdSize = ui32Remain - sizeof(RGXFWIF_CCB_CMD_HEADER); -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, ui32PDumpFlags, "cCCB(%p): Padding cmd %d", psClientCCB, psHeader->ui32CmdSize); - if (bPDumpEnabled) - { - DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc, - psClientCCB->ui32HostWriteOffset, - ui32Remain, - ui32PDumpFlags); - } -#endif - - *ppvBufferSpace = psClientCCB->pvClientCCB; - return PVRSRV_OK; - } - - goto e_retry; - } - } - } -e_retry: -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - psClientCCB->sUtilisation.ui32CCBFull++; - _RGXCCBUtilisationEvent(psClientCCB, - PVRSRV_CLIENT_CCCB_UTILISATION_WARNING_ACQUIRE_FAILED, - ui32CmdSize); -#endif /* PVRSRV_ENABLE_CCCB_UTILISATION_INFO */ - return PVRSRV_ERROR_RETRY; -} - -/****************************************************************************** - FUNCTION : RGXReleaseCCB - - PURPOSE : Release a CCB that we have been writing to. - - PARAMETERS : psDevData - device data - psCCB - the CCB - - RETURNS : None -******************************************************************************/ -void RGXReleaseCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32CmdSize, - IMG_UINT32 ui32PDumpFlags) -{ -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psClientCCB->psServerCommonContext); - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - IMG_BOOL bPDumpEnabled = PDumpCheckFlagsWrite(psDeviceNode, ui32PDumpFlags); - IMG_BOOL bPDumpFlagsContinuous = PDUMP_IS_CONTINUOUS(ui32PDumpFlags); -#endif - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockAcquire(psClientCCB->hCCBGrowLock); -#endif - /* - * If a padding command was needed then we should now move ui32HostWriteOffset - * forward. The command has already be dumped (if bPDumpEnabled). - */ - if ((psClientCCB->ui32HostWriteOffset + ui32CmdSize + PADDING_COMMAND_SIZE) > psClientCCB->ui32Size) - { - IMG_UINT32 ui32Remain = psClientCCB->ui32Size - psClientCCB->ui32HostWriteOffset; - - UPDATE_CCB_OFFSET(psClientCCB->ui32HostWriteOffset, - ui32Remain, - psClientCCB->ui32Size); - psClientCCB->ui32ByteCount += ui32Remain; - } - -#if defined(PDUMP) - /* Dump the CCB data */ - if (bPDumpEnabled) - { - DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc, - psClientCCB->ui32HostWriteOffset, - ui32CmdSize, - ui32PDumpFlags); - } -#endif - - /* - * Check if there any fences being written that will already be - * satisfied by the last written update command in this CCB. At the - * same time we can ASSERT that all sync addresses are not NULL. - */ -#if defined(DEBUG) - { - void *pvBufferStart = IMG_OFFSET_ADDR(psClientCCB->pvClientCCB, psClientCCB->ui32HostWriteOffset); - void *pvBufferEnd = IMG_OFFSET_ADDR(psClientCCB->pvClientCCB, psClientCCB->ui32HostWriteOffset + ui32CmdSize); - IMG_BOOL bMessagePrinted = IMG_FALSE; - - /* Walk through the commands in this section of CCB being released... */ - while (pvBufferStart < pvBufferEnd) - { - RGXFWIF_CCB_CMD_HEADER *psCmdHeader = pvBufferStart; - - if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_UPDATE) - { - /* If an UPDATE then record the values incase an adjacent fence uses it. */ - IMG_UINT32 ui32NumUFOs = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO); - RGXFWIF_UFO *psUFOPtr = IMG_OFFSET_ADDR(pvBufferStart, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - psClientCCB->ui32UpdateEntries = 0; - while (ui32NumUFOs-- > 0) - { - PVR_ASSERT(psUFOPtr->puiAddrUFO.ui32Addr != 0); - if (psClientCCB->ui32UpdateEntries < RGX_CCCB_FENCE_UPDATE_LIST_SIZE) - { - psClientCCB->asFenceUpdateList[psClientCCB->ui32UpdateEntries++] = *psUFOPtr++; - } - } - } - else if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE) - { - /* If a FENCE then check the values against the last UPDATE issued. */ - IMG_UINT32 ui32NumUFOs = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO); - RGXFWIF_UFO *psUFOPtr = IMG_OFFSET_ADDR(pvBufferStart, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - while (ui32NumUFOs-- > 0) - { - PVR_ASSERT(psUFOPtr->puiAddrUFO.ui32Addr != 0); - - if (bMessagePrinted == IMG_FALSE) - { - RGXFWIF_UFO *psUpdatePtr = psClientCCB->asFenceUpdateList; - IMG_UINT32 ui32UpdateIndex; - - for (ui32UpdateIndex = 0; ui32UpdateIndex < psClientCCB->ui32UpdateEntries; ui32UpdateIndex++) - { - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT(psUFOPtr)) - { - if (RGX_UFO_PTR_ADDR(psUFOPtr) == RGX_UFO_PTR_ADDR(psUpdatePtr)) - { - PVR_DPF((PVR_DBG_MESSAGE, "Redundant sync checkpoint check found in cCCB(%p) - 0x%x -> 0x%x", - psClientCCB, RGX_UFO_PTR_ADDR(psUFOPtr), psUFOPtr->ui32Value)); - bMessagePrinted = IMG_TRUE; - break; - } - } - else - { - if (psUFOPtr->puiAddrUFO.ui32Addr == psUpdatePtr->puiAddrUFO.ui32Addr && - psUFOPtr->ui32Value == psUpdatePtr->ui32Value) - { - PVR_DPF((PVR_DBG_MESSAGE, "Redundant fence check found in cCCB(%p) - 0x%x -> 0x%x", - psClientCCB, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value)); - bMessagePrinted = IMG_TRUE; - break; - } - } - psUpdatePtr++; - } - } - - psUFOPtr++; - } - } - else if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR || - psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE) - { - /* For all other UFO ops check the UFO address is not NULL. */ - IMG_UINT32 ui32NumUFOs = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO); - RGXFWIF_UFO *psUFOPtr = IMG_OFFSET_ADDR(pvBufferStart, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - while (ui32NumUFOs-- > 0) - { - PVR_ASSERT(psUFOPtr->puiAddrUFO.ui32Addr != 0); - psUFOPtr++; - } - } - - /* Move to the next command in this section of CCB being released... */ - pvBufferStart = IMG_OFFSET_ADDR(pvBufferStart, sizeof(RGXFWIF_CCB_CMD_HEADER) + psCmdHeader->ui32CmdSize); - } - } -#endif /* REDUNDANT_SYNCS_DEBUG */ - - -#if defined(PVRSRV_FORCE_FLUSH_CCCB_ON_KICK) - { - DEVMEM_MEMDESC* psClientCCBMemDesc = psClientCCB->psClientCCBMemDesc; - void *pvClientCCBAddr = psClientCCB->pvClientCCB; - PMR *psClientCCBMemDescPMR = NULL; - IMG_DEVMEM_OFFSET_T uiPMROffset; - - DevmemGetPMRData(psClientCCBMemDesc, - (IMG_HANDLE*)&psClientCCBMemDescPMR, - &uiPMROffset); - - CacheOpValExec(psClientCCBMemDescPMR, - (IMG_UINT64)(uintptr_t) pvClientCCBAddr, - uiPMROffset, - psClientCCBMemDesc->uiAllocSize, - PVRSRV_CACHE_OP_FLUSH); - - } -#endif - /* - * Update the CCB write offset. - */ - UPDATE_CCB_OFFSET(psClientCCB->ui32HostWriteOffset, - ui32CmdSize, - psClientCCB->ui32Size); - psClientCCB->ui32ByteCount += ui32CmdSize; - -#if defined(PVRSRV_ENABLE_CCCB_UTILISATION_INFO) - _RGXUpdateCCBUtilisation(psClientCCB); -#endif - /* - PDumpSetFrame will detect as we Transition out of capture range for - frame based data but if we are PDumping continuous data then we - need to inform the PDump layer ourselves - - First check is to confirm we are in continuous mode - Second check is to confirm the pdump client is connected and ready. - Third check is to confirm we are not in capture range. - */ -#if defined(PDUMP) - if (bPDumpFlagsContinuous && - bPDumpEnabled && - !PDumpCheckFlagsWrite(psDeviceNode, PDUMP_FLAGS_NONE)) - { - PVRSRV_ERROR eError; - - /* Only Transitioning into capture range can cause an error */ - eError = PDumpTransition(psDeviceNode, - psClientCCB->psPDumpConnectionData, - PDUMP_TRANSITION_EVENT_RANGE_EXITED, - ui32PDumpFlags); - PVR_ASSERT(eError == PVRSRV_OK); - } - - if (bPDumpEnabled) - { - if (!BIT_ISSET(psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN)) - { - /* Store offset to last finished CCB command. This offset can - * be needed when appending commands to a non finished CCB. - */ - psClientCCB->ui32FinishedPDumpWriteOffset = psClientCCB->ui32LastPDumpWriteOffset; - } - - /* Update the PDump write offset to show we PDumped this command */ - psClientCCB->ui32LastPDumpWriteOffset = psClientCCB->ui32HostWriteOffset; - } -#endif - -#if defined(NO_HARDWARE) - /* - The firmware is not running, it cannot update these; we do here instead. - */ - psClientCCB->psClientCCBCtrl->ui32ReadOffset = psClientCCB->ui32HostWriteOffset; - psClientCCB->psClientCCBCtrl->ui32DepOffset = psClientCCB->ui32HostWriteOffset; -#if defined(SUPPORT_AGP) - psClientCCB->psClientCCBCtrl->ui32ReadOffset2 = psClientCCB->ui32HostWriteOffset; -#endif -#endif - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockRelease(psClientCCB->hCCBGrowLock); -#endif -} - -IMG_UINT32 RGXGetHostWriteOffsetCCB(RGX_CLIENT_CCB *psClientCCB) -{ - return psClientCCB->ui32HostWriteOffset; -} - -IMG_UINT32 RGXGetWrapMaskCCB(RGX_CLIENT_CCB *psClientCCB) -{ - return psClientCCB->ui32Size-1; -} - -PVRSRV_ERROR RGXSetCCBFlags(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32Flags) -{ - if ((ui32Flags & RGX_CONTEXT_FLAG_DISABLESLR)) - { - BIT_SET(psClientCCB->ui32CCBFlags, CCB_FLAGS_SLR_DISABLED); - } - else - { - BIT_UNSET(psClientCCB->ui32CCBFlags, CCB_FLAGS_SLR_DISABLED); - } - return PVRSRV_OK; -} - -void RGXCmdHelperInitCmdCCB_CommandSize(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 ui64FBSCEntryMask, - IMG_UINT32 ui32ClientFenceCount, - IMG_UINT32 ui32ClientUpdateCount, - IMG_UINT32 ui32CmdSize, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - IMG_BOOL bCacheInval = IMG_TRUE; - /* Init the generated data members */ - psCmdHelperData->ui32FBSCInvalCmdSize = 0; - psCmdHelperData->ui64FBSCEntryMask = 0; - psCmdHelperData->ui32FenceCmdSize = 0; - psCmdHelperData->ui32UpdateCmdSize = 0; - psCmdHelperData->ui32PreTimeStampCmdSize = 0; - psCmdHelperData->ui32PostTimeStampCmdSize = 0; - psCmdHelperData->ui32RMWUFOCmdSize = 0; - - /* Only compile if RGX_FEATURE_PDS_INSTRUCTION_CACHE_AUTO_INVALIDATE is defined to avoid - * compilation errors on rogue cores. - */ -#if defined(RGX_FEATURE_PDS_INSTRUCTION_CACHE_AUTO_INVALIDATE) - bCacheInval = !(PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, PDS_INSTRUCTION_CACHE_AUTO_INVALIDATE) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, USC_INSTRUCTION_CACHE_AUTO_INVALIDATE) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, TDM_SLC_MMU_AUTO_CACHE_OPS) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, GEOM_SLC_MMU_AUTO_CACHE_OPS) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, FRAG_SLC_MMU_AUTO_CACHE_OPS) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, COMPUTE_SLC_MMU_AUTO_CACHE_OPS)) || - RGX_IS_BRN_SUPPORTED(psDevInfo, 71960) || - RGX_IS_BRN_SUPPORTED(psDevInfo, 72143); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif - - /* Total FBSC invalidate command size (header plus command data) */ - if (bCacheInval) - { - if (ui64FBSCEntryMask != 0) - { - psCmdHelperData->ui32FBSCInvalCmdSize = - RGX_CCB_FWALLOC_ALIGN(sizeof(psCmdHelperData->ui64FBSCEntryMask) + - sizeof(RGXFWIF_CCB_CMD_HEADER)); - psCmdHelperData->ui64FBSCEntryMask = ui64FBSCEntryMask; - } - } - - /* total DM command size (header plus command data) */ - - psCmdHelperData->ui32DMCmdSize = - RGX_CCB_FWALLOC_ALIGN(ui32CmdSize + sizeof(RGXFWIF_CCB_CMD_HEADER)); - - if (ui32ClientFenceCount != 0) - { - psCmdHelperData->ui32FenceCmdSize = - RGX_CCB_FWALLOC_ALIGN(ui32ClientFenceCount * sizeof(RGXFWIF_UFO) + - sizeof(RGXFWIF_CCB_CMD_HEADER)); - } - - if (ui32ClientUpdateCount != 0) - { - psCmdHelperData->ui32UpdateCmdSize = - RGX_CCB_FWALLOC_ALIGN(ui32ClientUpdateCount * sizeof(RGXFWIF_UFO) + - sizeof(RGXFWIF_CCB_CMD_HEADER)); - } - - if (ppPreAddr && (ppPreAddr->ui32Addr != 0)) - { - psCmdHelperData->ui32PreTimeStampCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER) - + ((sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN - 1)); - } - - if (ppPostAddr && (ppPostAddr->ui32Addr != 0)) - { - psCmdHelperData->ui32PostTimeStampCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER) - + ((sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN - 1)); - } - - if (ppRMWUFOAddr && (ppRMWUFOAddr->ui32Addr != 0)) - { - psCmdHelperData->ui32RMWUFOCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER) + sizeof(RGXFWIF_UFO); - } -} - -/* - Work out how much space this command will require -*/ -void RGXCmdHelperInitCmdCCB_OtherData(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiFenceUFOAddress, - IMG_UINT32 *paui32FenceValue, - IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiUpdateUFOAddress, - IMG_UINT32 *paui32UpdateValue, - IMG_UINT32 ui32CmdSize, - IMG_PBYTE pui8DMCmd, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGXFWIF_CCB_CMD_TYPE eType, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32PDumpFlags, - RGXFWIF_WORKEST_KICK_DATA *psWorkEstKickData, - IMG_CHAR *pszCommandName, - IMG_BOOL bCCBStateOpen, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = NULL; - - /* Job reference values */ - psCmdHelperData->ui32ExtJobRef = ui32ExtJobRef; - psCmdHelperData->ui32IntJobRef = ui32IntJobRef; - - /* Save the data we require in the submit call */ - psCmdHelperData->psClientCCB = psClientCCB; -#if defined(PDUMP) - psCmdHelperData->ui32PDumpFlags = ui32PDumpFlags; - psDevInfo = FWCommonContextGetRGXDevInfo(psCmdHelperData->psClientCCB->psServerCommonContext); -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); -#endif - psCmdHelperData->pszCommandName = pszCommandName; - if (bCCBStateOpen) - { - BIT_SET(psCmdHelperData->psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN); - } - else - { - BIT_UNSET(psCmdHelperData->psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN); - } - - /* Client sync data */ - psCmdHelperData->ui32ClientFenceCount = ui32ClientFenceCount; - psCmdHelperData->pauiFenceUFOAddress = pauiFenceUFOAddress; - psCmdHelperData->paui32FenceValue = paui32FenceValue; - psCmdHelperData->ui32ClientUpdateCount = ui32ClientUpdateCount; - psCmdHelperData->pauiUpdateUFOAddress = pauiUpdateUFOAddress; - psCmdHelperData->paui32UpdateValue = paui32UpdateValue; - - /* Command data */ - psCmdHelperData->ui32CmdSize = ui32CmdSize; - psCmdHelperData->pui8DMCmd = pui8DMCmd; - psCmdHelperData->eType = eType; - - if (ppPreAddr) - { - psCmdHelperData->pPreTimestampAddr = *ppPreAddr; - } - - if (ppPostAddr) - { - psCmdHelperData->pPostTimestampAddr = *ppPostAddr; - } - - if (ppRMWUFOAddr) - { - psCmdHelperData->pRMWUFOAddr = *ppRMWUFOAddr; - } - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "%s Command Server Init on FWCtx %08x", pszCommandName, - FWCommonContextGetFWAddress(psClientCCB->psServerCommonContext).ui32Addr); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Workload Data added */ - psCmdHelperData->psWorkEstKickData = psWorkEstKickData; -#endif -} - -/* - Work out how much space this command will require -*/ -void RGXCmdHelperInitCmdCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_CLIENT_CCB *psClientCCB, - IMG_UINT64 ui64FBSCEntryMask, - IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiFenceUFOAddress, - IMG_UINT32 *paui32FenceValue, - IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiUpdateUFOAddress, - IMG_UINT32 *paui32UpdateValue, - IMG_UINT32 ui32CmdSize, - IMG_PBYTE pui8DMCmd, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGXFWIF_CCB_CMD_TYPE eType, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32PDumpFlags, - RGXFWIF_WORKEST_KICK_DATA *psWorkEstKickData, - IMG_CHAR *pszCommandName, - IMG_BOOL bCCBStateOpen, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData) -{ - RGXCmdHelperInitCmdCCB_CommandSize(psDevInfo, - ui64FBSCEntryMask, - ui32ClientFenceCount, - ui32ClientUpdateCount, - ui32CmdSize, - ppPreAddr, - ppPostAddr, - ppRMWUFOAddr, - psCmdHelperData); - - RGXCmdHelperInitCmdCCB_OtherData(psClientCCB, - ui32ClientFenceCount, - pauiFenceUFOAddress, - paui32FenceValue, - ui32ClientUpdateCount, - pauiUpdateUFOAddress, - paui32UpdateValue, - ui32CmdSize, - pui8DMCmd, - ppPreAddr, - ppPostAddr, - ppRMWUFOAddr, - eType, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, - psWorkEstKickData, - pszCommandName, - bCCBStateOpen, - psCmdHelperData); -} - -/* - Reserve space in the CCB and fill in the command and client sync data -*/ -PVRSRV_ERROR RGXCmdHelperAcquireCmdCCB(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData) -{ - const IMG_UINT32 ui32MaxUFOCmdSize = RGX_CCB_FWALLOC_ALIGN((RGXFWIF_CCB_CMD_MAX_UFOS * sizeof(RGXFWIF_UFO)) + - sizeof(RGXFWIF_CCB_CMD_HEADER)); - IMG_UINT32 ui32AllocSize = 0; - IMG_UINT32 i; - void *pvStartPtr; - PVRSRV_ERROR eError; -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(asCmdHelperData->psClientCCB->psServerCommonContext); -#endif - - /* - Check the number of fences & updates are valid. - */ - for (i = 0; i < ui32CmdCount; i++) - { - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = &asCmdHelperData[i]; - - if (psCmdHelperData->ui32FenceCmdSize > ui32MaxUFOCmdSize || - psCmdHelperData->ui32UpdateCmdSize > ui32MaxUFOCmdSize) - { - return PVRSRV_ERROR_TOO_MANY_SYNCS; - } - } - - /* - Work out how much space we need for all the command(s) - */ - ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData); - -#if defined(PDUMP) - for (i = 0; i < ui32CmdCount; i++) - { - if ((asCmdHelperData[0].ui32PDumpFlags ^ asCmdHelperData[i].ui32PDumpFlags) & PDUMP_FLAGS_CONTINUOUS) - { - PVR_DPF((PVR_DBG_ERROR, "%s: PDump continuous is not consistent (%s != %s) for command %d", - __func__, - PDUMP_IS_CONTINUOUS(asCmdHelperData[0].ui32PDumpFlags)?"IMG_TRUE":"IMG_FALSE", - PDUMP_IS_CONTINUOUS(asCmdHelperData[i].ui32PDumpFlags)?"IMG_TRUE":"IMG_FALSE", - ui32CmdCount)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - } -#endif - - /* - Acquire space in the CCB for all the command(s). - */ - eError = RGXAcquireCCB(asCmdHelperData[0].psClientCCB, - ui32AllocSize, - &pvStartPtr, - asCmdHelperData[0].ui32PDumpFlags); - if (unlikely(eError != PVRSRV_OK)) - { - return eError; - } - - /* - For each command fill in the fence, DM, and update command - - */ - for (i = 0; i < ui32CmdCount; i++) - { - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = & asCmdHelperData[i]; - void *pvCmdPtr; -#if defined(PDUMP) - IMG_UINT32 ui32CtxAddr = FWCommonContextGetFWAddress(asCmdHelperData->psClientCCB->psServerCommonContext).ui32Addr; - IMG_UINT32 ui32CcbWoff = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(asCmdHelperData->psClientCCB->psServerCommonContext)); -#endif - - if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0) - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Start of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", - psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); - } - - pvCmdPtr = pvStartPtr; - - /* - Create the fence command. - */ - if (psCmdHelperData->ui32FenceCmdSize) - { - RGXFWIF_CCB_CMD_HEADER *psHeader; - IMG_UINT k, uiNextValueIndex; - - psHeader = pvCmdPtr; - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_FENCE; - - psHeader->ui32CmdSize = psCmdHelperData->ui32FenceCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); - psHeader->ui32ExtJobRef = psCmdHelperData->ui32ExtJobRef; - psHeader->ui32IntJobRef = psCmdHelperData->ui32IntJobRef; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - psHeader->sWorkEstKickData.ui16ReturnDataIndex = 0; - psHeader->sWorkEstKickData.ui64Deadline = 0; - psHeader->sWorkEstKickData.ui32CyclesPrediction = 0; -#endif - - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - /* Fill in the client fences */ - uiNextValueIndex = 0; - for (k = 0; k < psCmdHelperData->ui32ClientFenceCount; k++) - { - RGXFWIF_UFO *psUFOPtr = pvCmdPtr; - - psUFOPtr->puiAddrUFO = psCmdHelperData->pauiFenceUFOAddress[k]; - - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT(psUFOPtr)) - { - psUFOPtr->ui32Value = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - } - else - { - /* Only increment uiNextValueIndex for non sync checkpoints - * (as paui32FenceValue only contains values for sync prims) - */ - psUFOPtr->ui32Value = psCmdHelperData->paui32FenceValue[uiNextValueIndex++]; - } - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_UFO)); - -#if defined(SYNC_COMMAND_DEBUG) - PVR_DPF((PVR_DBG_ERROR, "%s client sync fence - 0x%x -> 0x%x", - psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value)); -#endif - PDUMPCOMMENT(psDevInfo->psDeviceNode, - ".. %s client sync fence - 0x%x -> 0x%x", - psCmdHelperData->psClientCCB->szName, - psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value); - - - } - } - - /* - Create the FBSC invalidate command. - */ - if (psCmdHelperData->ui32FBSCInvalCmdSize) - { - RGXFWIF_CCB_CMD_HEADER *psHeader; - IMG_UINT64 *pui64FBSCInvalCmdData; - - /* pui8CmdPtr */ - - psHeader = pvCmdPtr; - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_FBSC_INVALIDATE; - - psHeader->ui32CmdSize = psCmdHelperData->ui32FBSCInvalCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); - psHeader->ui32ExtJobRef = psCmdHelperData->ui32ExtJobRef; - psHeader->ui32IntJobRef = psCmdHelperData->ui32IntJobRef; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - psHeader->sWorkEstKickData.ui16ReturnDataIndex = 0; - psHeader->sWorkEstKickData.ui64Deadline = 0; - psHeader->sWorkEstKickData.ui32CyclesPrediction = 0; -#endif - pui64FBSCInvalCmdData = IMG_OFFSET_ADDR(psHeader, sizeof(RGXFWIF_CCB_CMD_HEADER)); - *pui64FBSCInvalCmdData = psCmdHelperData->ui64FBSCEntryMask; - /* leap over the FBSC invalidate command */ - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, psCmdHelperData->ui32FBSCInvalCmdSize); - - } - - /* - Create the pre DM timestamp commands. Pre and Post timestamp commands are supposed to - sandwich the DM cmd. The padding code with the CCB wrap upsets the FW if we don't have - the task type bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types. - */ - if (psCmdHelperData->ui32PreTimeStampCmdSize != 0) - { - RGXWriteTimestampCommand(&pvCmdPtr, - RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP, - psCmdHelperData->pPreTimestampAddr); - } - - /* - Create the DM command - */ - if (psCmdHelperData->ui32DMCmdSize) - { - RGXFWIF_CCB_CMD_HEADER *psHeader; - - psHeader = pvCmdPtr; - psHeader->eCmdType = psCmdHelperData->eType; - - psHeader->ui32CmdSize = psCmdHelperData->ui32DMCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); - psHeader->ui32ExtJobRef = psCmdHelperData->ui32ExtJobRef; - psHeader->ui32IntJobRef = psCmdHelperData->ui32IntJobRef; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (psCmdHelperData->psWorkEstKickData != NULL && - psCmdHelperData->eType != RGXFWIF_CCB_CMD_TYPE_NULL) - { - PVR_ASSERT(psCmdHelperData->eType == RGXFWIF_CCB_CMD_TYPE_GEOM || - psCmdHelperData->eType == RGXFWIF_CCB_CMD_TYPE_3D || - psCmdHelperData->eType == RGXFWIF_CCB_CMD_TYPE_CDM || - psCmdHelperData->eType == RGXFWIF_CCB_CMD_TYPE_TQ_TDM); - psHeader->sWorkEstKickData = *psCmdHelperData->psWorkEstKickData; - } - else - { - psHeader->sWorkEstKickData.ui16ReturnDataIndex = 0; - psHeader->sWorkEstKickData.ui64Deadline = 0; - psHeader->sWorkEstKickData.ui32CyclesPrediction = 0; - } -#endif - - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - /* The buffer is write-combine, so no special device memory treatment required. */ - OSCachedMemCopy(pvCmdPtr, psCmdHelperData->pui8DMCmd, psCmdHelperData->ui32CmdSize); - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, psCmdHelperData->ui32CmdSize); - } - - - if (psCmdHelperData->ui32PostTimeStampCmdSize != 0) - { - RGXWriteTimestampCommand(&pvCmdPtr, - RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP, - psCmdHelperData->pPostTimestampAddr); - } - - - if (psCmdHelperData->ui32RMWUFOCmdSize != 0) - { - RGXFWIF_CCB_CMD_HEADER * psHeader; - RGXFWIF_UFO * psUFO; - - psHeader = (RGXFWIF_CCB_CMD_HEADER *) pvCmdPtr; - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE; - psHeader->ui32CmdSize = psCmdHelperData->ui32RMWUFOCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); - psHeader->ui32ExtJobRef = psCmdHelperData->ui32ExtJobRef; - psHeader->ui32IntJobRef = psCmdHelperData->ui32IntJobRef; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - psHeader->sWorkEstKickData.ui16ReturnDataIndex = 0; - psHeader->sWorkEstKickData.ui64Deadline = 0; - psHeader->sWorkEstKickData.ui32CyclesPrediction = 0; -#endif - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - psUFO = (RGXFWIF_UFO *) pvCmdPtr; - psUFO->puiAddrUFO = psCmdHelperData->pRMWUFOAddr; - - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_UFO)); - } - - /* - Create the update command. - */ - if (psCmdHelperData->ui32UpdateCmdSize) - { - RGXFWIF_CCB_CMD_HEADER *psHeader; - IMG_UINT k, uiNextValueIndex; - - psHeader = pvCmdPtr; - psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_UPDATE; - psHeader->ui32CmdSize = psCmdHelperData->ui32UpdateCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); - psHeader->ui32ExtJobRef = psCmdHelperData->ui32ExtJobRef; - psHeader->ui32IntJobRef = psCmdHelperData->ui32IntJobRef; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - psHeader->sWorkEstKickData.ui16ReturnDataIndex = 0; - psHeader->sWorkEstKickData.ui64Deadline = 0; - psHeader->sWorkEstKickData.ui32CyclesPrediction = 0; -#endif - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - /* Fill in the client updates */ - uiNextValueIndex = 0; - for (k = 0; k < psCmdHelperData->ui32ClientUpdateCount; k++) - { - RGXFWIF_UFO *psUFOPtr = pvCmdPtr; - - psUFOPtr->puiAddrUFO = psCmdHelperData->pauiUpdateUFOAddress[k]; - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT(psUFOPtr)) - { - psUFOPtr->ui32Value = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - } - else - { - /* Only increment uiNextValueIndex for non sync checkpoints - * (as paui32UpdateValue only contains values for sync prims) - */ - psUFOPtr->ui32Value = psCmdHelperData->paui32UpdateValue[uiNextValueIndex++]; - } - pvCmdPtr = IMG_OFFSET_ADDR(pvCmdPtr, sizeof(RGXFWIF_UFO)); - -#if defined(SYNC_COMMAND_DEBUG) - PVR_DPF((PVR_DBG_ERROR, "%s client sync update - 0x%x -> 0x%x", - psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value)); -#endif - PDUMPCOMMENT(psDevInfo->psDeviceNode, - ".. %s client sync update - 0x%x -> 0x%x", - psCmdHelperData->psClientCCB->szName, - psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value); - - } - } - - /* Set the start pointer for the next iteration around the loop */ - pvStartPtr = IMG_OFFSET_ADDR(pvStartPtr, - psCmdHelperData->ui32FenceCmdSize + - psCmdHelperData->ui32FBSCInvalCmdSize + - psCmdHelperData->ui32PreTimeStampCmdSize + - psCmdHelperData->ui32DMCmdSize + - psCmdHelperData->ui32PostTimeStampCmdSize + - psCmdHelperData->ui32RMWUFOCmdSize + - psCmdHelperData->ui32UpdateCmdSize ); - - if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0) - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "End of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", - psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); - } - else - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "No %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", - psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); - } - } - - return PVRSRV_OK; -} - -/* - Fill in the server syncs data and release the CCB space -*/ -void RGXCmdHelperReleaseCmdCCB(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, - const IMG_CHAR *pcszDMName, - IMG_UINT32 ui32CtxAddr) -{ - IMG_UINT32 ui32AllocSize = 0; - IMG_UINT32 i; -#if defined(__linux__) - IMG_BOOL bTraceChecks = trace_rogue_are_fence_checks_traced(); - IMG_BOOL bTraceUpdates = trace_rogue_are_fence_updates_traced(); -#endif - - /* - Work out how much space we need for all the command(s) - */ - ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData); - /* - For each command fill in the server sync info - */ - for (i=0;ipsClientCCB->psServerCommonContext); -#endif - -#if (!defined(__linux__) || !defined(SUPPORT_RGX)) && !defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(psCmdHelperData); -#endif - -#if defined(__linux__) && defined(SUPPORT_RGX) - if (bTraceChecks) - { - trace_rogue_fence_checks(psCmdHelperData->pszCommandName, - pcszDMName, - ui32CtxAddr, - psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, - psCmdHelperData->ui32ClientFenceCount, - psCmdHelperData->pauiFenceUFOAddress, - psCmdHelperData->paui32FenceValue); - } - if (bTraceUpdates) - { - trace_rogue_fence_updates(psCmdHelperData->pszCommandName, - pcszDMName, - ui32CtxAddr, - psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize, - psCmdHelperData->ui32ClientUpdateCount, - psCmdHelperData->pauiUpdateUFOAddress, - psCmdHelperData->paui32UpdateValue); - } -#endif - - /* - All the commands have been filled in so release the CCB space. - The FW still won't run this command until we kick it - */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - psCmdHelperData->ui32PDumpFlags, - "%s Command Server Release on FWCtx %08x", - psCmdHelperData->pszCommandName, ui32CtxAddr); - } - - RGXReleaseCCB(asCmdHelperData[0].psClientCCB, - ui32AllocSize, - asCmdHelperData[0].ui32PDumpFlags); - - BIT_UNSET(asCmdHelperData[0].psClientCCB->ui32CCBFlags, CCB_FLAGS_CCB_STATE_OPEN); -} - -IMG_UINT32 RGXCmdHelperGetCommandSize(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData) -{ - IMG_UINT32 ui32AllocSize = 0; - IMG_UINT32 i; - - /* - Work out how much space we need for all the command(s) - */ - for (i = 0; i < ui32CmdCount; i++) - { - ui32AllocSize += - asCmdHelperData[i].ui32FenceCmdSize + - asCmdHelperData[i].ui32FBSCInvalCmdSize + - asCmdHelperData[i].ui32DMCmdSize + - asCmdHelperData[i].ui32UpdateCmdSize + - asCmdHelperData[i].ui32PreTimeStampCmdSize + - asCmdHelperData[i].ui32PostTimeStampCmdSize + - asCmdHelperData[i].ui32RMWUFOCmdSize; - } - - return ui32AllocSize; -} - -/* Work out how much of an offset there is to a specific command. */ -IMG_UINT32 RGXCmdHelperGetCommandOffset(RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, - IMG_UINT32 ui32Cmdindex) -{ - IMG_UINT32 ui32Offset = 0; - IMG_UINT32 i; - - for (i = 0; i < ui32Cmdindex; i++) - { - ui32Offset += - asCmdHelperData[i].ui32FenceCmdSize + - asCmdHelperData[i].ui32FBSCInvalCmdSize + - asCmdHelperData[i].ui32DMCmdSize + - asCmdHelperData[i].ui32UpdateCmdSize + - asCmdHelperData[i].ui32PreTimeStampCmdSize + - asCmdHelperData[i].ui32PostTimeStampCmdSize + - asCmdHelperData[i].ui32RMWUFOCmdSize; - } - - return ui32Offset; -} - -/* Returns the offset of the data master command from a write offset */ -IMG_UINT32 RGXCmdHelperGetDMCommandHeaderOffset(RGX_CCB_CMD_HELPER_DATA *psCmdHelperData) -{ - return psCmdHelperData->ui32FenceCmdSize + - psCmdHelperData->ui32PreTimeStampCmdSize + - psCmdHelperData->ui32FBSCInvalCmdSize; -} - -static const char *_CCBCmdTypename(RGXFWIF_CCB_CMD_TYPE cmdType) -{ - switch (cmdType) - { - case RGXFWIF_CCB_CMD_TYPE_GEOM: return "TA"; - case RGXFWIF_CCB_CMD_TYPE_3D: return "3D"; - case RGXFWIF_CCB_CMD_TYPE_3D_PR: return "3D_PR"; - case RGXFWIF_CCB_CMD_TYPE_CDM: return "CDM"; - case RGXFWIF_CCB_CMD_TYPE_TQ_3D: return "TQ_3D"; - case RGXFWIF_CCB_CMD_TYPE_TQ_2D: return "TQ_2D"; - case RGXFWIF_CCB_CMD_TYPE_TQ_TDM: return "TQ_TDM"; - case RGXFWIF_CCB_CMD_TYPE_FBSC_INVALIDATE: return "FBSC_INVALIDATE"; - case RGXFWIF_CCB_CMD_TYPE_NULL: return "NULL"; - case RGXFWIF_CCB_CMD_TYPE_FENCE: return "FENCE"; - case RGXFWIF_CCB_CMD_TYPE_UPDATE: return "UPDATE"; - case RGXFWIF_CCB_CMD_TYPE_FENCE_PR: return "FENCE_PR"; - case RGXFWIF_CCB_CMD_TYPE_PRIORITY: return "PRIORITY"; - case RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE: return "UNFENCED_UPDATE"; - case RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP: return "PRE_TIMESTAMP"; - case RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE: return "RMW_UPDATE"; - case RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP: return "POST_TIMESTAMP"; - case RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE: return "UNFENCED_RMW_UPDATE"; - case RGXFWIF_CCB_CMD_TYPE_PADDING: return "PADDING"; - - default: - PVR_ASSERT(IMG_FALSE); - break; - } - - return "INVALID"; -} - -PVRSRV_ERROR CheckForStalledCCB(PVRSRV_DEVICE_NODE *psDevNode, RGX_CLIENT_CCB *psCurrentClientCCB, RGX_KICK_TYPE_DM eKickTypeDM) -{ - volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl; - IMG_UINT32 ui32SampledRdOff, ui32SampledDpOff, ui32SampledWrOff, ui32WrapMask; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psCurrentClientCCB == NULL) - { - PVR_DPF((PVR_DBG_WARNING, "CheckForStalledCCB: CCCB is NULL")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - /* If CCB grow is enabled, take the lock while sampling offsets - * (to guard against a grow happening mid-sample) - */ - OSLockAcquire(psCurrentClientCCB->hCCBGrowLock); -#endif - /* NB. use psCurrentClientCCB->ui32Size as basis for wrap mask (rather than psClientCCBCtrl->ui32WrapMask) - * as if CCB grow happens, psCurrentClientCCB->ui32Size will have been updated but - * psClientCCBCtrl->ui32WrapMask is only updated once the firmware sees the CCB has grown. - * If we use the wrong value, we might incorrectly determine that the offsets are invalid. - */ - ui32WrapMask = RGXGetWrapMaskCCB(psCurrentClientCCB); - psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl; - ui32SampledRdOff = psClientCCBCtrl->ui32ReadOffset; - ui32SampledDpOff = psClientCCBCtrl->ui32DepOffset; - ui32SampledWrOff = psCurrentClientCCB->ui32HostWriteOffset; -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockRelease(psCurrentClientCCB->hCCBGrowLock); -#endif - - if (ui32SampledRdOff > ui32WrapMask || - ui32SampledDpOff > ui32WrapMask || - ui32SampledWrOff > ui32WrapMask) - { - PVR_DPF((PVR_DBG_WARNING, "CheckForStalledCCB: CCCB has invalid offset (ROFF=%d DOFF=%d WOFF=%d)", - ui32SampledRdOff, ui32SampledDpOff, ui32SampledWrOff)); - return PVRSRV_ERROR_INVALID_OFFSET; - } - - if (ui32SampledRdOff != ui32SampledWrOff && - psCurrentClientCCB->ui32LastROff != psCurrentClientCCB->ui32LastWOff && - ui32SampledRdOff == psCurrentClientCCB->ui32LastROff && - (psCurrentClientCCB->ui32ByteCount - psCurrentClientCCB->ui32LastByteCount) < psCurrentClientCCB->ui32Size) - { - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*)psDevNode->pvDevice; - - /* Only log a stalled CCB if GPU is idle (any state other than POW_ON is considered idle). - * Guest drivers do not initialize psRGXFWIfFwSysData, so they assume FW internal state is ON. */ - if (((psDevInfo->psRGXFWIfFwSysData == NULL) || (psDevInfo->psRGXFWIfFwSysData->ePowState != RGXFWIF_POW_ON)) && - (psDevInfo->ui32SLRHoldoffCounter == 0)) - { - static __maybe_unused const char *pszStalledAction = -#if defined(PVRSRV_STALLED_CCB_ACTION) - "force"; -#else - "warn"; -#endif - /* Don't log this by default unless debugging since a higher up - * function will log the stalled condition. Helps avoid double - * messages in the log. - */ - PVR_DPF((PVR_DBG_ERROR, "%s (%s): CCCB has not progressed (ROFF=%d DOFF=%d WOFF=%d) for \"%s\"", - __func__, pszStalledAction, ui32SampledRdOff, - ui32SampledDpOff, ui32SampledWrOff, - psCurrentClientCCB->szName)); - eError = PVRSRV_ERROR_CCCB_STALLED; - - { - void *pvClientCCBBuff = psCurrentClientCCB->pvClientCCB; - RGXFWIF_CCB_CMD_HEADER *psCommandHeader = IMG_OFFSET_ADDR(pvClientCCBBuff, ui32SampledRdOff); - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psCurrentClientCCB->psServerCommonContext); - - /* Special case - if readOffset is on a PADDING packet, CCB has wrapped. - * In this case, skip over the PADDING packet. - */ - if (psCommandHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_PADDING) - { - psCommandHeader = IMG_OFFSET_ADDR(pvClientCCBBuff, - ((ui32SampledRdOff + - psCommandHeader->ui32CmdSize + - sizeof(RGXFWIF_CCB_CMD_HEADER)) - & psCurrentClientCCB->psClientCCBCtrl->ui32WrapMask)); - } - - /* Only try to recover a 'stalled' context (ie one waiting on a fence), as some work (eg compute) could - * take a long time to complete, during which time the CCB ptrs would not advance. - */ - if (((psCommandHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE) || - (psCommandHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR)) && - (psCommandHeader != IMG_OFFSET_ADDR(pvClientCCBBuff, ui32SampledWrOff))) - { - /* Acquire the cCCB recovery lock */ - OSLockAcquire(psDevInfo->hCCBRecoveryLock); - - if (!psDevInfo->pvEarliestStalledClientCCB) - { - psDevInfo->pvEarliestStalledClientCCB = (void*)psCurrentClientCCB; - psDevInfo->ui32OldestSubmissionOrdinal = psCommandHeader->ui32IntJobRef; - } - else - { - /* Check if this fence cmd header has an older submission stamp than the one we are currently considering unblocking - * (account for submission stamp wrap by checking diff is less than 0x80000000) - if it is older, then this becomes - * our preferred fence to be unblocked/ - */ - if ((psCommandHeader->ui32IntJobRef < psDevInfo->ui32OldestSubmissionOrdinal) && - ((psDevInfo->ui32OldestSubmissionOrdinal - psCommandHeader->ui32IntJobRef) < 0x8000000)) - { - psDevInfo->pvEarliestStalledClientCCB = (void*)psCurrentClientCCB; - psDevInfo->ui32OldestSubmissionOrdinal = psCommandHeader->ui32IntJobRef; - } - } - - /* Release the cCCB recovery lock */ - OSLockRelease(psDevInfo->hCCBRecoveryLock); - } - } - } - } - - psCurrentClientCCB->ui32LastROff = ui32SampledRdOff; - psCurrentClientCCB->ui32LastWOff = ui32SampledWrOff; - psCurrentClientCCB->ui32LastByteCount = psCurrentClientCCB->ui32ByteCount; - - return eError; -} - -void DumpCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, - RGX_CLIENT_CCB *psCurrentClientCCB, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl; - void *pvClientCCBBuff; - IMG_UINT32 ui32Offset; - IMG_UINT32 ui32DepOffset; - IMG_UINT32 ui32EndOffset; - IMG_UINT32 ui32WrapMask; - IMG_CHAR * pszState = "Ready"; - - /* Ensure hCCBGrowLock is acquired before reading - * psCurrentClientCCB->pvClientCCB as a CCB grow - * could remap the virtual addresses. - */ -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockAcquire(psCurrentClientCCB->hCCBGrowLock); -#endif - psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl; - pvClientCCBBuff = psCurrentClientCCB->pvClientCCB; - ui32EndOffset = psCurrentClientCCB->ui32HostWriteOffset; - OSMemoryBarrier(NULL); - ui32Offset = psClientCCBCtrl->ui32ReadOffset; - ui32DepOffset = psClientCCBCtrl->ui32DepOffset; - /* NB. Use psCurrentClientCCB->ui32Size as basis for wrap mask (rather - * than psClientCCBCtrl->ui32WrapMask) as if CCB grow happened, - * psCurrentClientCCB->ui32Size will have been updated but - * psClientCCBCtrl->ui32WrapMask is only updated once the firmware - * sees the CCB has grown. If we use the wrong value, ui32NextOffset - * can end up being wrapped prematurely and pointing to garbage. - */ - ui32WrapMask = RGXGetWrapMaskCCB(psCurrentClientCCB); - - PVR_DUMPDEBUG_LOG("FWCtx 0x%08X (%s)", sFWCommonContext.ui32Addr, psCurrentClientCCB->szName); - if (ui32Offset == ui32EndOffset) - { - PVR_DUMPDEBUG_LOG(" `--"); - } - - while (ui32Offset != ui32EndOffset) - { - RGXFWIF_CCB_CMD_HEADER *psCmdHeader = IMG_OFFSET_ADDR(pvClientCCBBuff, ui32Offset); - IMG_UINT32 ui32NextOffset = (ui32Offset + psCmdHeader->ui32CmdSize + sizeof(RGXFWIF_CCB_CMD_HEADER)) & ui32WrapMask; - IMG_BOOL bLastCommand = (ui32NextOffset == ui32EndOffset)? IMG_TRUE: IMG_FALSE; - IMG_BOOL bLastUFO; - #define CCB_SYNC_INFO_LEN 80 - IMG_CHAR pszSyncInfo[CCB_SYNC_INFO_LEN]; - IMG_UINT32 ui32NoOfUpdates, i; - RGXFWIF_UFO *psUFOPtr; - - ui32NoOfUpdates = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO); - psUFOPtr = IMG_OFFSET_ADDR(pvClientCCBBuff, ui32Offset + sizeof(RGXFWIF_CCB_CMD_HEADER)); - pszSyncInfo[0] = '\0'; - - if (ui32Offset == ui32DepOffset) - { - pszState = "Waiting"; - } - - PVR_DUMPDEBUG_LOG(" %s--%s %s @ %u Int=%u Ext=%u", - bLastCommand? "`": "|", - pszState, _CCBCmdTypename(psCmdHeader->eCmdType), - ui32Offset, psCmdHeader->ui32IntJobRef, psCmdHeader->ui32ExtJobRef - ); - - /* switch on type and write checks and updates */ - switch (psCmdHeader->eCmdType) - { - case RGXFWIF_CCB_CMD_TYPE_UPDATE: - case RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE: - case RGXFWIF_CCB_CMD_TYPE_FENCE: - case RGXFWIF_CCB_CMD_TYPE_FENCE_PR: - { - for (i = 0; i < ui32NoOfUpdates; i++, psUFOPtr++) - { - bLastUFO = (ui32NoOfUpdates-1 == i)? IMG_TRUE: IMG_FALSE; - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT(psUFOPtr)) - { - SyncCheckpointRecordLookup(psDeviceNode, psUFOPtr->puiAddrUFO.ui32Addr, - pszSyncInfo, CCB_SYNC_INFO_LEN); - } - else - { - SyncRecordLookup(psDeviceNode, psUFOPtr->puiAddrUFO.ui32Addr, - pszSyncInfo, CCB_SYNC_INFO_LEN); - } - } - - PVR_DUMPDEBUG_LOG(" %s %s--Addr:0x%08x Val=0x%08x %s", - bLastCommand? " ": "|", - bLastUFO? "`": "|", - psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value, - pszSyncInfo - ); - } - break; - } - case RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE: - case RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE: - { - for (i = 0; i < ui32NoOfUpdates; i++, psUFOPtr++) - { - bLastUFO = (ui32NoOfUpdates-1 == i)? IMG_TRUE: IMG_FALSE; - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT(psUFOPtr)) - { - SyncCheckpointRecordLookup(psDeviceNode, psUFOPtr->puiAddrUFO.ui32Addr, - pszSyncInfo, CCB_SYNC_INFO_LEN); - } - else - { - SyncRecordLookup(psDeviceNode, psUFOPtr->puiAddrUFO.ui32Addr, - pszSyncInfo, CCB_SYNC_INFO_LEN); - } - } - - PVR_DUMPDEBUG_LOG(" %s %s--Addr:0x%08x Val++ %s", - bLastCommand? " ": "|", - bLastUFO? "`": "|", - psUFOPtr->puiAddrUFO.ui32Addr, - pszSyncInfo - ); - } - break; - } - default: - break; - } - ui32Offset = ui32NextOffset; - } - -#if defined(PVRSRV_ENABLE_CCCB_GROW) - OSLockRelease(psCurrentClientCCB->hCCBGrowLock); -#endif -} - -void DumpStalledCCBCommand(PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, - RGX_CLIENT_CCB *psCurrentClientCCB, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl; - void *pvClientCCBBuff = psCurrentClientCCB->pvClientCCB; - IMG_UINT32 ui32SampledRdOff = psClientCCBCtrl->ui32ReadOffset; - IMG_UINT32 ui32SampledDepOff = psClientCCBCtrl->ui32DepOffset; - IMG_UINT32 ui32SampledWrOff = psCurrentClientCCB->ui32HostWriteOffset; - - if ((ui32SampledRdOff == ui32SampledDepOff) && - (ui32SampledRdOff != ui32SampledWrOff)) - { - volatile RGXFWIF_CCB_CMD_HEADER *psCommandHeader = IMG_OFFSET_ADDR(pvClientCCBBuff, ui32SampledRdOff); - RGXFWIF_CCB_CMD_TYPE eCommandType = psCommandHeader->eCmdType; - volatile void *pvPtr = psCommandHeader; - - /* CCB is stalled on a fence... */ - if ((eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE) || (eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR)) - { -#if defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psCurrentClientCCB->psServerCommonContext); - IMG_UINT32 ui32Val; -#endif - RGXFWIF_UFO *psUFOPtr = IMG_OFFSET_ADDR(pvPtr, sizeof(*psCommandHeader)); - IMG_UINT32 jj; - - /* Display details of the fence object on which the context is pending */ - PVR_DUMPDEBUG_LOG("FWCtx 0x%08X @ %d (%s) pending on %s:", - sFWCommonContext.ui32Addr, - ui32SampledRdOff, - psCurrentClientCCB->szName, - _CCBCmdTypename(eCommandType)); - for (jj=0; jjui32CmdSize/sizeof(RGXFWIF_UFO); jj++) - { -#if !defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) - PVR_DUMPDEBUG_LOG(" Addr:0x%08x Value=0x%08x",psUFOPtr[jj].puiAddrUFO.ui32Addr, psUFOPtr[jj].ui32Value); -#else - ui32Val = 0; - RGXReadFWModuleAddr(psDevInfo, psUFOPtr[jj].puiAddrUFO.ui32Addr, &ui32Val); - PVR_DUMPDEBUG_LOG(" Addr:0x%08x Value(Host)=0x%08x Value(FW)=0x%08x", - psUFOPtr[jj].puiAddrUFO.ui32Addr, - psUFOPtr[jj].ui32Value, ui32Val); -#endif - } - - /* Advance psCommandHeader past the FENCE to the next command header (this will be the TA/3D command that is fenced) */ - pvPtr = IMG_OFFSET_ADDR(psUFOPtr, psCommandHeader->ui32CmdSize); - psCommandHeader = pvPtr; - if (psCommandHeader != IMG_OFFSET_ADDR(pvClientCCBBuff, ui32SampledWrOff)) - { - PVR_DUMPDEBUG_LOG(" FWCtx 0x%08X fenced command is of type %s",sFWCommonContext.ui32Addr, _CCBCmdTypename(psCommandHeader->eCmdType)); - /* Advance psCommandHeader past the TA/3D to the next command header (this will possibly be an UPDATE) */ - pvPtr = IMG_OFFSET_ADDR(pvPtr, sizeof(*psCommandHeader) + psCommandHeader->ui32CmdSize); - psCommandHeader = pvPtr; - /* If the next command is an update, display details of that so we can see what would then become unblocked */ - if (psCommandHeader != IMG_OFFSET_ADDR(pvClientCCBBuff, ui32SampledWrOff)) - { - eCommandType = psCommandHeader->eCmdType; - - if (eCommandType == RGXFWIF_CCB_CMD_TYPE_UPDATE) - { - psUFOPtr = IMG_OFFSET_ADDR(psCommandHeader, sizeof(*psCommandHeader)); - PVR_DUMPDEBUG_LOG(" preventing %s:",_CCBCmdTypename(eCommandType)); - for (jj=0; jjui32CmdSize/sizeof(RGXFWIF_UFO); jj++) - { -#if !defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) - PVR_DUMPDEBUG_LOG(" Addr:0x%08x Value=0x%08x",psUFOPtr[jj].puiAddrUFO.ui32Addr, psUFOPtr[jj].ui32Value); -#else - ui32Val = 0; - RGXReadFWModuleAddr(psDevInfo, psUFOPtr[jj].puiAddrUFO.ui32Addr, &ui32Val); - PVR_DUMPDEBUG_LOG(" Addr:0x%08x Value(Host)=0x%08x Value(FW)=0x%08x", - psUFOPtr[jj].puiAddrUFO.ui32Addr, - psUFOPtr[jj].ui32Value, - ui32Val); -#endif - } - } - } - else - { - PVR_DUMPDEBUG_LOG(" FWCtx 0x%08X has no further commands",sFWCommonContext.ui32Addr); - } - } - else - { - PVR_DUMPDEBUG_LOG(" FWCtx 0x%08X has no further commands",sFWCommonContext.ui32Addr); - } - } - } -} - -void DumpStalledContextInfo(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGX_CLIENT_CCB *psStalledClientCCB; - - PVR_ASSERT(psDevInfo); - - psStalledClientCCB = (RGX_CLIENT_CCB *)psDevInfo->pvEarliestStalledClientCCB; - - if (psStalledClientCCB) - { - volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl = psStalledClientCCB->psClientCCBCtrl; - IMG_UINT32 ui32SampledDepOffset = psClientCCBCtrl->ui32DepOffset; - void *pvPtr = IMG_OFFSET_ADDR(psStalledClientCCB->pvClientCCB, ui32SampledDepOffset); - RGXFWIF_CCB_CMD_HEADER *psCommandHeader = pvPtr; - RGXFWIF_CCB_CMD_TYPE eCommandType = psCommandHeader->eCmdType; - - if ((eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE) || (eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR)) - { - RGXFWIF_UFO *psUFOPtr = IMG_OFFSET_ADDR(pvPtr, sizeof(*psCommandHeader)); - IMG_UINT32 jj; - IMG_UINT32 ui32NumUnsignalledUFOs = 0; - IMG_UINT32 ui32UnsignalledUFOVaddrs[PVRSRV_MAX_SYNCS]; - -#if defined(PVRSRV_STALLED_CCB_ACTION) - if (!psDevInfo->psRGXFWIfFwOsData->sSLRLogFirst.aszCCBName[0]) - { - OSClockMonotonicns64(&psDevInfo->psRGXFWIfFwOsData->sSLRLogFirst.ui64Timestamp); - psDevInfo->psRGXFWIfFwOsData->sSLRLogFirst.ui32NumUFOs = (IMG_UINT32)(psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO)); - psDevInfo->psRGXFWIfFwOsData->sSLRLogFirst.ui32FWCtxAddr = FWCommonContextGetFWAddress(psStalledClientCCB->psServerCommonContext).ui32Addr; - OSStringLCopy(psDevInfo->psRGXFWIfFwOsData->sSLRLogFirst.aszCCBName, - psStalledClientCCB->szName, - MAX_CLIENT_CCB_NAME); - } - else - { - OSClockMonotonicns64(&psDevInfo->psRGXFWIfFwOsData->sSLRLog[psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp].ui64Timestamp); - psDevInfo->psRGXFWIfFwOsData->sSLRLog[psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp].ui32NumUFOs = (IMG_UINT32)(psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO)); - psDevInfo->psRGXFWIfFwOsData->sSLRLog[psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp].ui32FWCtxAddr = FWCommonContextGetFWAddress(psStalledClientCCB->psServerCommonContext).ui32Addr; - OSStringLCopy(psDevInfo->psRGXFWIfFwOsData->sSLRLog[psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp].aszCCBName, - psStalledClientCCB->szName, - MAX_CLIENT_CCB_NAME); - psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp = (psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp + 1) % PVR_SLR_LOG_ENTRIES; - } - psDevInfo->psRGXFWIfFwOsData->ui32ForcedUpdatesRequested++; - /* flush write buffers for psRGXFWIfFwOsData */ - OSWriteMemoryBarrier(&psDevInfo->psRGXFWIfFwOsData->sSLRLog[psDevInfo->psRGXFWIfFwOsData->ui8SLRLogWp]); -#endif - PVR_LOG(("Fence found on context 0x%x '%s' @ %d has %d UFOs", - FWCommonContextGetFWAddress(psStalledClientCCB->psServerCommonContext).ui32Addr, - psStalledClientCCB->szName, ui32SampledDepOffset, - (IMG_UINT32)(psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO)))); - - for (jj=0; jjui32CmdSize/sizeof(RGXFWIF_UFO); jj++) - { - if (PVRSRV_UFO_IS_SYNC_CHECKPOINT((RGXFWIF_UFO *)&psUFOPtr[jj])) - { - IMG_UINT32 ui32ReadValue = SyncCheckpointStateFromUFO(psDevInfo->psDeviceNode, - psUFOPtr[jj].puiAddrUFO.ui32Addr); - PVR_LOG((" %d/%d FWAddr 0x%x requires 0x%x (currently 0x%x)", jj+1, - (IMG_UINT32)(psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO)), - psUFOPtr[jj].puiAddrUFO.ui32Addr, - psUFOPtr[jj].ui32Value, - ui32ReadValue)); - /* If fence is unmet, dump debug info on it */ - if (ui32ReadValue != psUFOPtr[jj].ui32Value) - { - /* Add to our list to pass to pvr_sync */ - ui32UnsignalledUFOVaddrs[ui32NumUnsignalledUFOs] = psUFOPtr[jj].puiAddrUFO.ui32Addr; - ui32NumUnsignalledUFOs++; - } - } - else - { - PVR_LOG((" %d/%d FWAddr 0x%x requires 0x%x", jj+1, - (IMG_UINT32)(psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO)), - psUFOPtr[jj].puiAddrUFO.ui32Addr, - psUFOPtr[jj].ui32Value)); - } - } -#if defined(SUPPORT_NATIVE_FENCE_SYNC) || defined(SUPPORT_FALLBACK_FENCE_SYNC) - if (ui32NumUnsignalledUFOs > 0) - { - IMG_UINT32 ui32NumSyncsOwned; - PVRSRV_ERROR eErr = SyncCheckpointDumpInfoOnStalledUFOs(ui32NumUnsignalledUFOs, &ui32UnsignalledUFOVaddrs[0], &ui32NumSyncsOwned); - - PVR_LOG_IF_ERROR(eErr, "SyncCheckpointDumpInfoOnStalledUFOs() call failed."); - } -#endif -#if defined(PVRSRV_STALLED_CCB_ACTION) - if (BIT_ISSET(psStalledClientCCB->ui32CCBFlags, CCB_FLAGS_SLR_DISABLED)) - { - PRGXFWIF_FWCOMMONCONTEXT psContext = FWCommonContextGetFWAddress(psStalledClientCCB->psServerCommonContext); - - PVR_LOG(("SLR disabled for FWCtx 0x%08X", psContext.ui32Addr)); - } - else - { - if (ui32NumUnsignalledUFOs > 0) - { - RGXFWIF_KCCB_CMD sSignalFencesCmd; - - sSignalFencesCmd.eCmdType = RGXFWIF_KCCB_CMD_FORCE_UPDATE; - sSignalFencesCmd.ui32KCCBFlags = 0; - sSignalFencesCmd.uCmdData.sForceUpdateData.psContext = FWCommonContextGetFWAddress(psStalledClientCCB->psServerCommonContext); - sSignalFencesCmd.uCmdData.sForceUpdateData.ui32CCBFenceOffset = ui32SampledDepOffset; - - PVR_LOG(("Forced update command issued for FWCtx 0x%08X", sSignalFencesCmd.uCmdData.sForceUpdateData.psContext.ui32Addr)); - - RGXScheduleCommand(FWCommonContextGetRGXDevInfo(psStalledClientCCB->psServerCommonContext), - RGXFWIF_DM_GP, - &sSignalFencesCmd, - PDUMP_FLAGS_CONTINUOUS); - } - } -#endif - } - psDevInfo->pvEarliestStalledClientCCB = NULL; - } -} - -/****************************************************************************** - End of file (rgxccb.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxccb.h b/drivers/gpu/drm/img-rogue/1.17/rgxccb.h deleted file mode 100644 index 0dddee171a7e5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxccb.h +++ /dev/null @@ -1,356 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Circular Command Buffer functionality. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX Circular Command Buffer functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXCCB_H) -#define RGXCCB_H - -#include "devicemem.h" -#include "device.h" -#include "rgxdevice.h" -#include "sync_server.h" -#include "connection_server.h" -#include "rgxdebug.h" -#include "rgxdefs_km.h" -#include "pvr_notifier.h" - -#define MAX_CLIENT_CCB_NAME 30 -#define SYNC_FLAG_MASK_ALL IMG_UINT32_MAX - -/* - * This size is to be used when a client CCB is found to consume very - * negligible space (e.g. a few hundred bytes to few KBs - less than a page). - * In such a case, instead of allocating CCB of size of only a few KBs, we - * allocate at-least this much to be future risk-free. - */ -#define MIN_SAFE_CCB_SIZE_LOG2 13 /* 8K (2 Pages) */ -#define MAX_SAFE_CCB_SIZE_LOG2 18 /* 256K (64 Pages) */ - -#define RGX_TQ3D_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ3D -static_assert(RGX_TQ3D_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_TQ3D_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TQ3D CCB size is invalid"); -#define RGX_TQ3D_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ3D -static_assert(RGX_TQ3D_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ3D - && RGX_TQ3D_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TQ3D max CCB size is invalid"); - -#define RGX_TQ2D_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ2D -static_assert(RGX_TQ2D_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_TQ2D_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TQ2D CCB size is invalid"); -#define RGX_TQ2D_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ2D -static_assert(RGX_TQ2D_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ2D && - RGX_TQ2D_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TQ2D max CCB size is invalid"); - -#define RGX_CDM_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_CDM -static_assert(RGX_CDM_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_CDM_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "CDM CCB size is invalid"); -#define RGX_CDM_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_CDM -static_assert(RGX_CDM_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_CDM && - RGX_CDM_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "CDM max CCB size is invalid"); - -#define RGX_TA_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TA -static_assert(RGX_TA_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_TA_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TA CCB size is invalid"); -#define RGX_TA_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TA -static_assert(RGX_TA_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TA && - RGX_TA_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TA max CCB size is invalid"); - -#define RGX_3D_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_3D -static_assert(RGX_3D_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_3D_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "3D CCB size is invalid"); -#define RGX_3D_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_3D -static_assert(RGX_3D_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_3D && - RGX_3D_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "3D max CCB size is invalid"); - -#define RGX_KICKSYNC_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_KICKSYNC -static_assert(RGX_KICKSYNC_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_KICKSYNC_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "KickSync CCB size is invalid"); -#define RGX_KICKSYNC_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_KICKSYNC -static_assert(RGX_KICKSYNC_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_KICKSYNC && - RGX_KICKSYNC_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "KickSync max CCB size is invalid"); - -#define RGX_TDM_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TDM -static_assert(RGX_TDM_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_TDM_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TDM CCB size is invalid"); -#define RGX_TDM_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TDM -static_assert(RGX_TDM_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TDM && - RGX_TDM_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "TDM max CCB size is invalid"); - -#define RGX_RDM_CCB_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_RDM -static_assert(RGX_RDM_CCB_SIZE_LOG2 >= MIN_SAFE_CCB_SIZE_LOG2 && - RGX_RDM_CCB_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "RDM CCB size is invalid"); -#define RGX_RDM_CCB_MAX_SIZE_LOG2 PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_RDM -static_assert(RGX_RDM_CCB_MAX_SIZE_LOG2 >= PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_RDM && - RGX_RDM_CCB_MAX_SIZE_LOG2 <= MAX_SAFE_CCB_SIZE_LOG2, "RDM max CCB size is invalid"); - -typedef struct _RGX_CLIENT_CCB_ RGX_CLIENT_CCB; - -/* - This structure is declared here as it's allocated on the heap by - the callers -*/ - -typedef struct _RGX_CCB_CMD_HELPER_DATA_ { - /* Data setup at command init time */ - RGX_CLIENT_CCB *psClientCCB; - IMG_CHAR *pszCommandName; - IMG_UINT32 ui32PDumpFlags; - - IMG_UINT32 ui32ClientFenceCount; - PRGXFWIF_UFO_ADDR *pauiFenceUFOAddress; - IMG_UINT32 *paui32FenceValue; - IMG_UINT32 ui32ClientUpdateCount; - PRGXFWIF_UFO_ADDR *pauiUpdateUFOAddress; - IMG_UINT32 *paui32UpdateValue; - RGXFWIF_CCB_CMD_TYPE eType; - IMG_UINT32 ui32CmdSize; - IMG_UINT8 *pui8DMCmd; - IMG_UINT32 ui32FenceCmdSize; - IMG_UINT32 ui32FBSCInvalCmdSize; - IMG_UINT32 ui32DMCmdSize; - IMG_UINT32 ui32UpdateCmdSize; - - /* data for FBSC invalidate command */ - IMG_UINT64 ui64FBSCEntryMask; - - /* timestamp commands */ - PRGXFWIF_TIMESTAMP_ADDR pPreTimestampAddr; - IMG_UINT32 ui32PreTimeStampCmdSize; - PRGXFWIF_TIMESTAMP_ADDR pPostTimestampAddr; - IMG_UINT32 ui32PostTimeStampCmdSize; - PRGXFWIF_UFO_ADDR pRMWUFOAddr; - IMG_UINT32 ui32RMWUFOCmdSize; - - /* Job reference fields */ - IMG_UINT32 ui32ExtJobRef; - IMG_UINT32 ui32IntJobRef; - - /* FW Memdesc for Workload information */ - RGXFWIF_WORKEST_KICK_DATA *psWorkEstKickData; - -} RGX_CCB_CMD_HELPER_DATA; - -#define PADDING_COMMAND_SIZE (sizeof(RGXFWIF_CCB_CMD_HEADER)) - - -#define RGX_CCB_REQUESTORS(TYPE) \ - /* for debugging purposes */ TYPE(UNDEF) \ - TYPE(TA) \ - TYPE(3D) \ - TYPE(CDM) \ - TYPE(SH) \ - TYPE(RS) \ - TYPE(TQ_3D) \ - TYPE(TQ_2D) \ - TYPE(TQ_TDM) \ - TYPE(KICKSYNC) \ - TYPE(RAY) \ - -/* Forms an enum constant for each type present in RGX_CCB_REQUESTORS list. The enum is mainly used as - an index to the aszCCBRequestors table defined in rgxccb.c. The total number of enums must adhere - to the following build assert. -*/ -typedef enum _RGX_CCB_REQUESTOR_TYPE_ -{ -#define CONSTRUCT_ENUM(req) REQ_TYPE_##req, - RGX_CCB_REQUESTORS (CONSTRUCT_ENUM) -#undef CONSTRUCT_ENUM - - /* should always be at the end */ - REQ_TYPE_TOTAL_COUNT, -} RGX_CCB_REQUESTOR_TYPE; - -/* Tuple describing the columns of the following table */ -typedef enum _RGX_CCB_REQUESTOR_TUPLE_ -{ - REQ_RGX_FW_CLIENT_CCB_STRING, /* Index to comment to be dumped in DevMemAllocs when allocating FirmwareClientCCB for this requestor */ - REQ_RGX_FW_CLIENT_CCB_CONTROL_STRING, /* Index to comment to be dumped in DevMemAllocs when allocating FirmwareClientCCBControl for this requestor */ - REQ_PDUMP_COMMENT, /* Index to comment to be dumped in PDUMPs */ - - /* should always be at the end */ - REQ_TUPLE_CARDINALITY, -} RGX_CCB_REQUESTOR_TUPLE; - -/* Unpack U8 values from U32. */ -#define U32toU8_Unpack1(U32Packed) (U32Packed & 0xFF) -#define U32toU8_Unpack2(U32Packed) ((U32Packed>>8) & 0xFF) -#define U32toU8_Unpack3(U32Packed) ((U32Packed>>16) & 0xFF) -#define U32toU8_Unpack4(U32Packed) ((U32Packed>>24) & 0xFF) - -/* Defines for bit meanings within the ui32CCBFlags member of struct _RGX_CLIENT_CCB_ - * - * ( X = taken/in use, - = available/unused ) - * - * 31 10 - * | || - * ------------------------------XX - * Bit Meaning - * 0 = If set, CCB is still open and commands will be appended to it - * 1 = If set, do not perform Sync Lockup Recovery (SLR) for this CCB - */ -#define CCB_FLAGS_CCB_STATE_OPEN (0) /*!< This bit is set to indicate CCB is in the 'Open' state. */ -#define CCB_FLAGS_SLR_DISABLED (1) /*!< This bit is set to disable Sync Lockup Recovery (SLR) for this CCB. */ - - -/* Table containing an array of strings for each requestor type in the list of RGX_CCB_REQUESTORS. In addition to its use in - this module (rgxccb.c), this table is also used to access string to be dumped in PDUMP comments, hence, marking it extern for - use in other modules. -*/ -extern const IMG_CHAR *const aszCCBRequestors[][REQ_TUPLE_CARDINALITY]; - -PVRSRV_ERROR RGXCCBPDumpDrainCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR RGXCreateCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32CCBSizeLog2, - IMG_UINT32 ui32CCBMaxSizeLog2, - IMG_UINT32 ui32ContextFlags, - CONNECTION_DATA *psConnectionData, - RGX_CCB_REQUESTOR_TYPE eCCBRequestor, - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - RGX_CLIENT_CCB **ppsClientCCB, - DEVMEM_MEMDESC **ppsClientCCBMemDesc, - DEVMEM_MEMDESC **ppsClientCCBCtlMemDesc); - -void RGXDestroyCCB(PVRSRV_RGXDEV_INFO *psDevInfo, RGX_CLIENT_CCB *psClientCCB); - -PVRSRV_ERROR RGXCheckSpaceCCB(RGX_CLIENT_CCB *psClientCCB, IMG_UINT32 ui32CmdSize); - -PVRSRV_ERROR RGXAcquireCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32CmdSize, - void **ppvBufferSpace, - IMG_UINT32 ui32PDumpFlags); - -void RGXReleaseCCB(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32CmdSize, - IMG_UINT32 ui32PDumpFlags); - -IMG_UINT32 RGXGetHostWriteOffsetCCB(RGX_CLIENT_CCB *psClientCCB); -IMG_UINT32 RGXGetWrapMaskCCB(RGX_CLIENT_CCB *psClientCCB); - -PVRSRV_ERROR RGXSetCCBFlags(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32Flags); - -void RGXCmdHelperInitCmdCCB_CommandSize(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 ui64FBSCEntryMask, - IMG_UINT32 ui32ClientFenceCount, - IMG_UINT32 ui32ClientUpdateCount, - IMG_UINT32 ui32CmdSize, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData); - -void RGXCmdHelperInitCmdCCB_OtherData(RGX_CLIENT_CCB *psClientCCB, - IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiFenceUFOAddress, - IMG_UINT32 *paui32FenceValue, - IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiUpdateUFOAddress, - IMG_UINT32 *paui32UpdateValue, - IMG_UINT32 ui32CmdSize, - IMG_PBYTE pui8DMCmd, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGXFWIF_CCB_CMD_TYPE eType, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32PDumpFlags, - RGXFWIF_WORKEST_KICK_DATA *psWorkEstKickData, - IMG_CHAR *pszCommandName, - IMG_BOOL bCCBStateOpen, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData); - -void RGXCmdHelperInitCmdCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_CLIENT_CCB *psClientCCB, - IMG_UINT64 ui64FBSCEntryMask, - IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiFenceUFOAddress, - IMG_UINT32 *paui32FenceValue, - IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiUpdateUFOAddress, - IMG_UINT32 *paui32UpdateValue, - IMG_UINT32 ui32CmdSize, - IMG_UINT8 *pui8DMCmd, - PRGXFWIF_TIMESTAMP_ADDR *ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR *ppPostAddr, - PRGXFWIF_UFO_ADDR *ppRMWUFOAddr, - RGXFWIF_CCB_CMD_TYPE eType, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32PDumpFlags, - RGXFWIF_WORKEST_KICK_DATA *psWorkEstKickData, - IMG_CHAR *pszCommandName, - IMG_BOOL bCCBStateOpen, - RGX_CCB_CMD_HELPER_DATA *psCmdHelperData); - -PVRSRV_ERROR RGXCmdHelperAcquireCmdCCB(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData); - -void RGXCmdHelperReleaseCmdCCB(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, - const IMG_CHAR *pcszDMName, - IMG_UINT32 ui32CtxAddr); - -IMG_UINT32 RGXCmdHelperGetCommandSize(IMG_UINT32 ui32CmdCount, - RGX_CCB_CMD_HELPER_DATA *asCmdHelperData); - -IMG_UINT32 RGXCmdHelperGetCommandOffset(RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, - IMG_UINT32 ui32Cmdindex); - -IMG_UINT32 RGXCmdHelperGetDMCommandHeaderOffset(RGX_CCB_CMD_HELPER_DATA *psCmdHelperData); - -void DumpStalledCCBCommand(PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, - RGX_CLIENT_CCB *psCurrentClientCCB, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -void DumpCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, - RGX_CLIENT_CCB *psCurrentClientCCB, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -PVRSRV_ERROR CheckForStalledCCB(PVRSRV_DEVICE_NODE *psDevNode, RGX_CLIENT_CCB *psCurrentClientCCB, RGX_KICK_TYPE_DM eKickTypeDM); - -void DumpStalledContextInfo(PVRSRV_RGXDEV_INFO *psDevInfo); -#endif /* RGXCCB_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxcompute.c b/drivers/gpu/drm/img-rogue/1.17/rgxcompute.c deleted file mode 100644 index 952940f6f67e0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxcompute.c +++ /dev/null @@ -1,1324 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Compute routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Compute routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "srvkm.h" -#include "pdump_km.h" -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgxcompute.h" -#include "rgx_bvnc_defs_km.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "osfunc.h" -#include "rgxccb.h" -#include "rgxhwperf.h" -#include "ospvr_gputrace.h" -#include "htbuffer.h" - -#include "sync_server.h" -#include "sync_internal.h" -#include "sync.h" -#include "rgx_memallocflags.h" - -#if defined(SUPPORT_BUFFER_SYNC) -#include "pvr_buffer_sync.h" -#endif - -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" - -#include "rgxtimerquery.h" - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "rgxworkest.h" - -#define HASH_CLEAN_LIMIT 6 -#endif - -/* Enable this to dump the compiled list of UFOs prior to kick call */ -#define ENABLE_CMP_UFO_DUMP 0 - -//#define CMP_CHECKPOINT_DEBUG 1 - -#if defined(CMP_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -#else -#define CHKPT_DBG(X) -#endif - -struct _RGX_SERVER_COMPUTE_CONTEXT_ { - PVRSRV_DEVICE_NODE *psDeviceNode; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - DEVMEM_MEMDESC *psFWComputeContextMemDesc; - DEVMEM_MEMDESC *psFWFrameworkMemDesc; - DEVMEM_MEMDESC *psFWComputeContextStateMemDesc; - DLLIST_NODE sListNode; - SYNC_ADDR_LIST sSyncAddrListFence; - SYNC_ADDR_LIST sSyncAddrListUpdate; - POS_LOCK hLock; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WORKEST_HOST_DATA sWorkEstData; -#endif -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif -}; - -PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pbyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32StaticComputecontextStateSize, - IMG_PBYTE pStaticComputecontextState, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - IMG_UINT32 ui32MaxDeadlineMS, - RGX_SERVER_COMPUTE_CONTEXT **ppsComputeContext) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - RGX_SERVER_COMPUTE_CONTEXT *psComputeContext; - RGX_COMMON_CONTEXT_INFO sInfo = {NULL}; - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_FWCOMPUTECONTEXT *psFWComputeContext; - IMG_UINT32 ui32CCBAllocSizeLog2, ui32CCBMaxAllocSizeLog2; - - /* Prepare cleanup struct */ - *ppsComputeContext = NULL; - - psComputeContext = OSAllocZMem(sizeof(*psComputeContext)); - if (psComputeContext == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* - Create the FW compute context, this has the CDM common - context embedded within it - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_FWCOMPUTECONTEXT), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwComputeContext", - &psComputeContext->psFWComputeContextMemDesc); - if (eError != PVRSRV_OK) - { - goto fail_fwcomputecontext; - } - - eError = OSLockCreate(&psComputeContext->hLock); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to create lock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_createlock; - } - - psComputeContext->psDeviceNode = psDeviceNode; - - /* - Allocate device memory for the firmware GPU context suspend state. - Note: the FW reads/writes the state to memory by accessing the GPU register interface. - */ - PDUMPCOMMENT(psDeviceNode, "Allocate RGX firmware compute context suspend state"); - - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_COMPUTECTX_STATE), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwComputeContextState", - &psComputeContext->psFWComputeContextStateMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU context suspend state (%d)", - __func__, - eError)); - goto fail_contextsuspendalloc; - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WorkEstInitCompute(psDevInfo, &psComputeContext->sWorkEstData); -#endif - - if (ui32FrameworkCommandSize) - { - /* - * Create the FW framework buffer - */ - eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, - &psComputeContext->psFWFrameworkMemDesc, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU framework state (%d)", - __func__, - eError)); - goto fail_frameworkcreate; - } - - /* Copy the Framework client data into the framework buffer */ - eError = PVRSRVRGXFrameworkCopyCommand(psDeviceNode, - psComputeContext->psFWFrameworkMemDesc, - pbyFrameworkCommand, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to populate the framework buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcopy; - } - - sInfo.psFWFrameworkMemDesc = psComputeContext->psFWFrameworkMemDesc; - } - - ui32CCBAllocSizeLog2 = U32toU8_Unpack1(ui32PackedCCBSizeU88); - ui32CCBMaxAllocSizeLog2 = U32toU8_Unpack2(ui32PackedCCBSizeU88); - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_CDM, - RGXFWIF_DM_CDM, - NULL, - psComputeContext->psFWComputeContextMemDesc, - offsetof(RGXFWIF_FWCOMPUTECONTEXT, sCDMContext), - psFWMemContextMemDesc, - psComputeContext->psFWComputeContextStateMemDesc, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_CDM_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_CDM_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - ui32MaxDeadlineMS, - ui64RobustnessAddress, - &sInfo, - &psComputeContext->psServerCommonContext); - if (eError != PVRSRV_OK) - { - goto fail_contextalloc; - } - - eError = DevmemAcquireCpuVirtAddr(psComputeContext->psFWComputeContextMemDesc, - (void **)&psFWComputeContext); - if (eError != PVRSRV_OK) - { - goto fail_acquire_cpu_mapping; - } - - OSDeviceMemCopy(&psFWComputeContext->sStaticComputeContextState, pStaticComputecontextState, ui32StaticComputecontextStateSize); - DevmemPDumpLoadMem(psComputeContext->psFWComputeContextMemDesc, 0, sizeof(RGXFWIF_FWCOMPUTECONTEXT), PDUMP_FLAGS_CONTINUOUS); - DevmemReleaseCpuVirtAddr(psComputeContext->psFWComputeContextMemDesc); - -#if defined(SUPPORT_BUFFER_SYNC) - psComputeContext->psBufferSyncContext = - pvr_buffer_sync_context_create(psDeviceNode->psDevConfig->pvOSDevice, - "rogue-cdm"); - if (IS_ERR(psComputeContext->psBufferSyncContext)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create buffer_sync context (err=%ld)", - __func__, PTR_ERR(psComputeContext->psBufferSyncContext))); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_buffer_sync_context_create; - } -#endif - - SyncAddrListInit(&psComputeContext->sSyncAddrListFence); - SyncAddrListInit(&psComputeContext->sSyncAddrListUpdate); - - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSWRLockAcquireWrite(psDevInfo->hComputeCtxListLock); - dllist_add_to_tail(&(psDevInfo->sComputeCtxtListHead), &(psComputeContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hComputeCtxListLock); - } - - *ppsComputeContext = psComputeContext; - return PVRSRV_OK; - -#if defined(SUPPORT_BUFFER_SYNC) -fail_buffer_sync_context_create: -#endif -fail_acquire_cpu_mapping: - FWCommonContextFree(psComputeContext->psServerCommonContext); -fail_contextalloc: -fail_frameworkcopy: - if (psComputeContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWFrameworkMemDesc); - } -fail_frameworkcreate: - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWComputeContextStateMemDesc); -fail_contextsuspendalloc: - OSLockDestroy(psComputeContext->hLock); -fail_createlock: - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWComputeContextMemDesc); -fail_fwcomputecontext: - OSFreeMem(psComputeContext); - return eError; -} - -PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO *psDevInfo = psComputeContext->psDeviceNode->pvDevice; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_FWCOMPUTECONTEXT *psFWComputeContext; - IMG_UINT32 ui32WorkEstCCBSubmitted; -#endif - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psComputeContext->psDeviceNode, - psComputeContext->psServerCommonContext, - RGXFWIF_DM_CDM, - PDUMP_FLAGS_NONE); - - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - -#if defined(SUPPORT_BUFFER_SYNC) - /* remove after RGXFWRequestCommonContextCleanUp() because we might return - * RETRY and don't want to be calling this twice */ - if (psComputeContext->psBufferSyncContext != NULL) - { - pvr_buffer_sync_context_destroy(psComputeContext->psBufferSyncContext); - psComputeContext->psBufferSyncContext = NULL; - } -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - eError = DevmemAcquireCpuVirtAddr(psComputeContext->psFWComputeContextMemDesc, - (void **)&psFWComputeContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware compute context (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - ui32WorkEstCCBSubmitted = psFWComputeContext->ui32WorkEstCCBSubmitted; - - DevmemReleaseCpuVirtAddr(psComputeContext->psFWComputeContextMemDesc); - - /* Check if all of the workload estimation CCB commands for this workload are read */ - if (ui32WorkEstCCBSubmitted != psComputeContext->sWorkEstData.ui32WorkEstCCBReceived) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: WorkEst # cmds submitted (%u) and received (%u) mismatch", - __func__, ui32WorkEstCCBSubmitted, - psComputeContext->sWorkEstData.ui32WorkEstCCBReceived)); - - return PVRSRV_ERROR_RETRY; - } -#endif - - /* ... it has so we can free its resources */ - - OSWRLockAcquireWrite(psDevInfo->hComputeCtxListLock); - dllist_remove_node(&(psComputeContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hComputeCtxListLock); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WorkEstDeInitCompute(psDevInfo, &psComputeContext->sWorkEstData); -#endif - - FWCommonContextFree(psComputeContext->psServerCommonContext); - if (psComputeContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWFrameworkMemDesc); - } - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWComputeContextStateMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psComputeContext->psFWComputeContextMemDesc); - - OSLockDestroy(psComputeContext->hLock); - OSFreeMem(psComputeContext); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFODevVarBlock, - IMG_UINT32 *paui32ClientUpdateSyncOffset, - IMG_UINT32 *paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE *piUpdateFence, - IMG_CHAR pszUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32CmdSize, - IMG_PBYTE pui8DMCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs, - IMG_UINT32 ui32NumWorkgroups, - IMG_UINT32 ui32NumWorkitems, - IMG_UINT64 ui64DeadlineInus) -{ - RGXFWIF_KCCB_CMD sCmpKCCBCmd; - RGX_CCB_CMD_HELPER_DATA asCmdHelperData[1]; - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - IMG_UINT32 ui32CDMCmdOffset = 0; - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psComputeContext->psServerCommonContext); - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psComputeContext->psServerCommonContext); - IMG_UINT32 ui32IntJobRef = OSAtomicIncrement(&psDevInfo->iCCBSubmissionOrdinal); - IMG_UINT32 ui32FWCtx; - IMG_BOOL bCCBStateOpen = IMG_FALSE; - - PRGXFWIF_TIMESTAMP_ADDR pPreAddr; - PRGXFWIF_TIMESTAMP_ADDR pPostAddr; - PRGXFWIF_UFO_ADDR pRMWUFOAddr; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_WORKEST_KICK_DATA sWorkloadKickDataCompute = {0}; - IMG_UINT32 ui32CDMWorkloadDataRO = 0; - IMG_UINT32 ui32CDMCmdHeaderOffset = 0; - IMG_UINT32 ui32CDMCmdOffsetWrapCheck = 0; - RGX_WORKLOAD sWorkloadCharacteristics = {0}; -#endif - - IMG_UINT32 ui32IntClientFenceCount = 0; - PRGXFWIF_UFO_ADDR *pauiIntFenceUFOAddress = NULL; - IMG_UINT32 ui32IntClientUpdateCount = 0; - PRGXFWIF_UFO_ADDR *pauiIntUpdateUFOAddress = NULL; - IMG_UINT32 *paui32IntUpdateValue = NULL; - PVRSRV_FENCE iUpdateFence = PVRSRV_NO_FENCE; - IMG_UINT64 uiCheckFenceUID = 0; - IMG_UINT64 uiUpdateFenceUID = 0; - PSYNC_CHECKPOINT psUpdateSyncCheckpoint = NULL; - PSYNC_CHECKPOINT *apsFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32FenceSyncCheckpointCount = 0; - IMG_UINT32 *pui32IntAllocatedUpdateValues = NULL; - PVRSRV_CLIENT_SYNC_PRIM *psFenceTimelineUpdateSync = NULL; - IMG_UINT32 ui32FenceTimelineUpdateValue = 0; - void *pvUpdateFenceFinaliseData = NULL; - -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_append_data *psBufferSyncData = NULL; - PSYNC_CHECKPOINT *apsBufferFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32BufferFenceSyncCheckpointCount = 0; - PSYNC_CHECKPOINT psBufferUpdateSyncCheckpoint = NULL; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - CMD_COMMON *psComputeCmdCmn = IMG_OFFSET_ADDR(pui8DMCmd, 0); - - if (iUpdateTimeline >= 0 && !piUpdateFence) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Ensure we haven't been given a null ptr to - * update values if we have been told we - * have updates - */ - if (ui32ClientUpdateCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32ClientUpdateValue != NULL, - "paui32ClientUpdateValue NULL but " - "ui32ClientUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Ensure the string is null-terminated (Required for safety) */ - pszUpdateFenceName[31] = '\0'; - - OSLockAcquire(psComputeContext->hLock); - - eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListFence, - 0, - NULL, - NULL); - if (eError != PVRSRV_OK) - { - goto err_populate_sync_addr_list; - } - - ui32IntClientUpdateCount = ui32ClientUpdateCount; - - eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListUpdate, - ui32ClientUpdateCount, - pauiClientUpdateUFODevVarBlock, - paui32ClientUpdateSyncOffset); - if (eError != PVRSRV_OK) - { - goto err_populate_sync_addr_list; - } - if (ui32IntClientUpdateCount && !pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psComputeContext->sSyncAddrListUpdate.pasFWAddrs; - } - paui32IntUpdateValue = paui32ClientUpdateValue; - - if (ui32SyncPMRCount != 0) - { -#if defined(SUPPORT_BUFFER_SYNC) - int err; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: Calling " - "pvr_buffer_sync_resolve_and_create_fences", __func__)); - - err = pvr_buffer_sync_resolve_and_create_fences( - psComputeContext->psBufferSyncContext, - psComputeContext->psDeviceNode->hSyncCheckpointContext, - ui32SyncPMRCount, - ppsSyncPMRs, - paui32SyncPMRFlags, - &ui32BufferFenceSyncCheckpointCount, - &apsBufferFenceSyncCheckpoints, - &psBufferUpdateSyncCheckpoint, - &psBufferSyncData - ); - - if (unlikely(err)) - { - switch (err) - { - case -EINTR: - eError = PVRSRV_ERROR_RETRY; - break; - case -ENOMEM: - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - break; - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: " - "pvr_buffer_sync_resolve_and_create_fences failed (%d)", - __func__, eError)); - } - - goto fail_resolve_input_fence; - } - - /* Append buffer sync fences */ - if (ui32BufferFenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d buffer sync checkpoints " - "to CDM Fence (&psTransferContext->sSyncAddrListFence=<%p>, " - "pauiIntFenceUFOAddress=<%p>)...", __func__, - ui32BufferFenceSyncCheckpointCount, - (void *) &psComputeContext->sSyncAddrListFence , - (void *) pauiIntFenceUFOAddress)); - - SyncAddrListAppendAndDeRefCheckpoints(&psComputeContext->sSyncAddrListFence, - ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); - if (pauiIntFenceUFOAddress == NULL) - { - pauiIntFenceUFOAddress = psComputeContext->sSyncAddrListFence.pasFWAddrs; - } - ui32IntClientFenceCount += ui32BufferFenceSyncCheckpointCount; - } - - /* Append the update (from output fence) */ - if (psBufferUpdateSyncCheckpoint) - { - SyncAddrListAppendCheckpoints(&psComputeContext->sSyncAddrListUpdate, - 1, &psBufferUpdateSyncCheckpoint); - if (pauiIntUpdateUFOAddress == NULL) - { - pauiIntUpdateUFOAddress = psComputeContext->sSyncAddrListUpdate.pasFWAddrs; - } - ui32IntClientUpdateCount++; - } -#else /* defined(SUPPORT_BUFFER_SYNC) */ - PVR_DPF((PVR_DBG_ERROR, "%s: Buffer sync not supported but got %u buffers", - __func__, ui32SyncPMRCount)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto err_populate_sync_addr_list; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointResolveFence (iCheckFence=%d), psComputeContext->psDeviceNode->hSyncCheckpointContext=<%p>...", __func__, iCheckFence, (void*)psComputeContext->psDeviceNode->hSyncCheckpointContext)); - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence(psComputeContext->psDeviceNode->hSyncCheckpointContext, - iCheckFence, - &ui32FenceSyncCheckpointCount, - &apsFenceSyncCheckpoints, - &uiCheckFenceUID, ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, returned ERROR (eError=%d)", __func__, eError)); - goto fail_free_buffer_sync_data; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, fence %d contained %d checkpoints (apsFenceSyncCheckpoints=<%p>)", __func__, iCheckFence, ui32FenceSyncCheckpointCount, (void*)apsFenceSyncCheckpoints)); -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32FenceSyncCheckpointCount > 0) - { - IMG_UINT32 ii; - for (ii=0; ii", __func__, ii, (void*)psNextCheckpoint)); - } - } -#endif - /* Create the output fence (if required) */ - if (iUpdateTimeline != PVRSRV_NO_TIMELINE) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointCreateFence (iUpdateFence=%d, iUpdateTimeline=%d, psComputeContext->psDeviceNode->hSyncCheckpointContext=<%p>)...", __func__, iUpdateFence, iUpdateTimeline, (void*)psComputeContext->psDeviceNode->hSyncCheckpointContext)); - eError = SyncCheckpointCreateFence(psComputeContext->psDeviceNode, - pszUpdateFenceName, - iUpdateTimeline, - psComputeContext->psDeviceNode->hSyncCheckpointContext, - &iUpdateFence, - &uiUpdateFenceUID, - &pvUpdateFenceFinaliseData, - &psUpdateSyncCheckpoint, - (void*)&psFenceTimelineUpdateSync, - &ui32FenceTimelineUpdateValue, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...returned error (%d)", __func__, eError)); - goto fail_create_output_fence; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...returned from SyncCheckpointCreateFence (iUpdateFence=%d, psFenceTimelineUpdateSync=<%p>, ui32FenceTimelineUpdateValue=%u)", __func__, iUpdateFence, psFenceTimelineUpdateSync, ui32FenceTimelineUpdateValue)); - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ui32IntClientUpdateCount=%u, psFenceTimelineUpdateSync=<%p>", __func__, ui32IntClientUpdateCount, (void*)psFenceTimelineUpdateSync)); - /* Append the sync prim update for the timeline (if required) */ - if (psFenceTimelineUpdateSync) - { - IMG_UINT32 *pui32TimelineUpdateWp = NULL; - - /* Allocate memory to hold the list of update values (including our timeline update) */ - pui32IntAllocatedUpdateValues = OSAllocMem(sizeof(*pui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); - if (!pui32IntAllocatedUpdateValues) - { - /* Failed to allocate memory */ - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc_update_values_mem; - } - OSCachedMemSet(pui32IntAllocatedUpdateValues, 0xbb, sizeof(*pui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); - /* Copy the update values into the new memory, then append our timeline update value */ - if (paui32IntUpdateValue) - { - OSCachedMemCopy(pui32IntAllocatedUpdateValues, paui32IntUpdateValue, sizeof(*pui32IntAllocatedUpdateValues) * ui32IntClientUpdateCount); - } -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ui32IntClientUpdateCount=%u:", __func__, ui32IntClientUpdateCount)); - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Now set the additional update value */ - pui32TimelineUpdateWp = pui32IntAllocatedUpdateValues + ui32IntClientUpdateCount; - *pui32TimelineUpdateWp = ui32FenceTimelineUpdateValue; - ui32IntClientUpdateCount++; - /* Now make sure paui32ClientUpdateValue points to pui32IntAllocatedUpdateValues */ - paui32ClientUpdateValue = pui32IntAllocatedUpdateValues; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: append the timeline sync prim addr <%p> to the compute context update list", __func__, (void*)psFenceTimelineUpdateSync)); - /* Now append the timeline sync prim addr to the compute context update list */ - SyncAddrListAppendSyncPrim(&psComputeContext->sSyncAddrListUpdate, - psFenceTimelineUpdateSync); -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ui32IntClientUpdateCount=%u:", __func__, ui32IntClientUpdateCount)); - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Ensure paui32IntUpdateValue is now pointing to our new array of update values */ - paui32IntUpdateValue = pui32IntAllocatedUpdateValues; - } - } - - /* Append the checks (from input fence) */ - if (ui32FenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d sync checkpoints to Compute CDM Fence (&psComputeContext->sSyncAddrListFence=<%p>)...", __func__, ui32FenceSyncCheckpointCount, (void*)&psComputeContext->sSyncAddrListFence)); -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiIntFenceUFOAddress; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - SyncAddrListAppendCheckpoints(&psComputeContext->sSyncAddrListFence, - ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - if (!pauiIntFenceUFOAddress) - { - pauiIntFenceUFOAddress = psComputeContext->sSyncAddrListFence.pasFWAddrs; - } - ui32IntClientFenceCount += ui32FenceSyncCheckpointCount; - } -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)paui32IntUpdateValue; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: Dumping %d update values (paui32IntUpdateValue=<%p>)...", __func__, ui32IntClientUpdateCount, (void*)paui32IntUpdateValue)); - for (iii=0; iii", __func__, iii, (void*)pui32Tmp)); - CHKPT_DBG((PVR_DBG_ERROR, "%s: *paui32IntUpdateValue[%d] = 0x%x", __func__, iii, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - - if (psUpdateSyncCheckpoint) - { - /* Append the update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append 1 sync checkpoint to Compute CDM Update (&psComputeContext->sSyncAddrListUpdate=<%p>, psUpdateSyncCheckpoint=<%p>)...", __func__, (void*)&psComputeContext->sSyncAddrListUpdate , (void*)psUpdateSyncCheckpoint)); - SyncAddrListAppendCheckpoints(&psComputeContext->sSyncAddrListUpdate, - 1, - &psUpdateSyncCheckpoint); - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psComputeContext->sSyncAddrListUpdate.pasFWAddrs; - } - ui32IntClientUpdateCount++; -#if defined(CMP_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiIntUpdateUFOAddress; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: pauiIntUpdateUFOAddress=<%p>, pui32Tmp=<%p>, ui32IntClientUpdateCount=%u", __func__, (void*)pauiIntUpdateUFOAddress, (void*)pui32Tmp, ui32IntClientUpdateCount)); - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: (after pvr_sync) ui32IntClientFenceCount=%d, ui32IntClientUpdateCount=%d", __func__, ui32IntClientFenceCount, ui32IntClientUpdateCount)); - -#if (ENABLE_CMP_UFO_DUMP == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: dumping Compute (CDM) fence/updates syncs...", __func__)); - { - IMG_UINT32 ii; - PRGXFWIF_UFO_ADDR *psTmpIntFenceUFOAddress = pauiIntFenceUFOAddress; - PRGXFWIF_UFO_ADDR *psTmpIntUpdateUFOAddress = pauiIntUpdateUFOAddress; - IMG_UINT32 *pui32TmpIntUpdateValue = paui32IntUpdateValue; - - /* Dump Fence syncs and Update syncs */ - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d Compute (CDM) fence syncs (&psComputeContext->sSyncAddrListFence=<%p>, pauiIntFenceUFOAddress=<%p>):", __func__, ui32IntClientFenceCount, (void*)&psComputeContext->sSyncAddrListFence, (void*)pauiIntFenceUFOAddress)); - for (ii=0; ii. FWAddr=0x%x, CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientFenceCount, (void*)psTmpIntFenceUFOAddress, psTmpIntFenceUFOAddress->ui32Addr)); - psTmpIntFenceUFOAddress++; - } - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d Compute (CDM) update syncs (&psComputeContext->sSyncAddrListUpdate=<%p>, pauiIntUpdateUFOAddress=<%p>):", __func__, ui32IntClientUpdateCount, (void*)&psComputeContext->sSyncAddrListUpdate, (void*)pauiIntUpdateUFOAddress)); - for (ii=0; iiui32Addr & 0x1) - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr, *pui32TmpIntUpdateValue)); - pui32TmpIntUpdateValue++; - } - psTmpIntUpdateUFOAddress++; - } - } -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - sWorkloadCharacteristics.sCompute.ui32NumberOfWorkgroups = ui32NumWorkgroups; - sWorkloadCharacteristics.sCompute.ui32NumberOfWorkitems = ui32NumWorkitems; - - /* Prepare workload estimation */ - WorkEstPrepare(psComputeContext->psDeviceNode->pvDevice, - &psComputeContext->sWorkEstData, - &psComputeContext->sWorkEstData.uWorkloadMatchingData.sCompute.sDataCDM, - RGXFWIF_CCB_CMD_TYPE_CDM, - &sWorkloadCharacteristics, - ui64DeadlineInus, - &sWorkloadKickDataCompute); -#endif - - RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psComputeContext->psDeviceNode->pvDevice, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr); - - RGXCmdHelperInitCmdCCB(psDevInfo, - psClientCCB, - 0, - ui32IntClientFenceCount, - pauiIntFenceUFOAddress, - NULL, - ui32IntClientUpdateCount, - pauiIntUpdateUFOAddress, - paui32IntUpdateValue, - ui32CmdSize, - pui8DMCmd, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr, - RGXFWIF_CCB_CMD_TYPE_CDM, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - &sWorkloadKickDataCompute, -#else - NULL, -#endif - "Compute", - bCCBStateOpen, - asCmdHelperData); - - eError = RGXCmdHelperAcquireCmdCCB(ARRAY_SIZE(asCmdHelperData), asCmdHelperData); - if (eError != PVRSRV_OK) - { - goto fail_cmdaquire; - } - - - /* - We should reserve space in the kernel CCB here and fill in the command - directly. - This is so if there isn't space in the kernel CCB we can return with - retry back to services client before we take any operations - */ - - /* - We might only be kicking for flush out a padding packet so only submit - the command if the create was successful - */ - if (eError == PVRSRV_OK) - { - /* - All the required resources are ready at this point, we can't fail so - take the required server sync operations and commit all the resources - */ - - ui32CDMCmdOffset = RGXGetHostWriteOffsetCCB(psClientCCB); - RGXCmdHelperReleaseCmdCCB(1, asCmdHelperData, "CDM", FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext).ui32Addr); - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* The following is used to determine the offset of the command header containing - the workload estimation data so that can be accessed when the KCCB is read */ - ui32CDMCmdHeaderOffset = RGXCmdHelperGetDMCommandHeaderOffset(asCmdHelperData); - - ui32CDMCmdOffsetWrapCheck = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psComputeContext->psServerCommonContext)); - - /* This checks if the command would wrap around at the end of the CCB and - * therefore would start at an offset of 0 rather than the current command - * offset */ - if (ui32CDMCmdOffset < ui32CDMCmdOffsetWrapCheck) - { - ui32CDMWorkloadDataRO = ui32CDMCmdOffset; - } - else - { - ui32CDMWorkloadDataRO = 0; - } -#endif - - /* Construct the kernel compute CCB command. */ - sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - sCmpKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext); - sCmpKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - sCmpKCCBCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - sCmpKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - - /* Add the Workload data into the KCCB kick */ -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Store the offset to the CCCB command header so that it can be referenced - * when the KCCB command reaches the FW */ - sCmpKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = ui32CDMWorkloadDataRO + ui32CDMCmdHeaderOffset; -#else - sCmpKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0; -#endif - - ui32FWCtx = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext).ui32Addr; - - if (psComputeCmdCmn) - { - HTBLOGK(HTB_SF_MAIN_KICK_CDM, - sCmpKCCBCmd.uCmdData.sCmdKickData.psContext, - ui32CDMCmdOffset, - psComputeCmdCmn->ui32FrameNum, - ui32ExtJobRef, - ui32IntJobRef); - } - - RGXSRV_HWPERF_ENQ(psComputeContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_CDM, - iCheckFence, - iUpdateFence, - iUpdateTimeline, - uiCheckFenceUID, - uiUpdateFenceUID, - NO_DEADLINE, - NO_CYCEST); - - /* - * Submit the compute command to the firmware. - */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psComputeContext->psDeviceNode->pvDevice, - RGXFWIF_DM_CDM, - &sCmpKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s failed to schedule kernel CCB command (%s)", - __func__, - PVRSRVGetErrorString(eError2))); - } - else - { - PVRGpuTraceEnqueueEvent(psComputeContext->psDeviceNode->pvDevice, - ui32FWCtx, ui32ExtJobRef, ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_CDM); - } - /* - * Now check eError (which may have returned an error from our earlier call - * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first - * so we check it now... - */ - if (eError != PVRSRV_OK ) - { - goto fail_cmdaquire; - } - -#if defined(NO_HARDWARE) - /* If NO_HARDWARE, signal the output fence's sync checkpoint and sync prim */ - if (psUpdateSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Signalling NOHW sync checkpoint<%p>, ID:%d, FwAddr=0x%x", __func__, (void*)psUpdateSyncCheckpoint, SyncCheckpointGetId(psUpdateSyncCheckpoint), SyncCheckpointGetFirmwareAddr(psUpdateSyncCheckpoint))); - SyncCheckpointSignalNoHW(psUpdateSyncCheckpoint); - } - if (psFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Updating NOHW sync prim<%p> to %d", __func__, (void*)psFenceTimelineUpdateSync, ui32FenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(psFenceTimelineUpdateSync, ui32FenceTimelineUpdateValue); - } - SyncCheckpointNoHWUpdateTimelines(NULL); -#endif /* defined(NO_HARDWARE) */ - -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_succeeded(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - *piUpdateFence = iUpdateFence; - - if (pvUpdateFenceFinaliseData && (iUpdateFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psComputeContext->psDeviceNode, iUpdateFence, - pvUpdateFenceFinaliseData, - psUpdateSyncCheckpoint, pszUpdateFenceName); - } - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - /* Free memory allocated to hold the internal list of update values */ - if (pui32IntAllocatedUpdateValues) - { - OSFreeMem(pui32IntAllocatedUpdateValues); - pui32IntAllocatedUpdateValues = NULL; - } - - OSLockRelease(psComputeContext->hLock); - - return PVRSRV_OK; - -fail_cmdaquire: - SyncAddrListRollbackCheckpoints(psComputeContext->psDeviceNode, &psComputeContext->sSyncAddrListFence); - SyncAddrListRollbackCheckpoints(psComputeContext->psDeviceNode, &psComputeContext->sSyncAddrListUpdate); -fail_alloc_update_values_mem: - if (iUpdateFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(iUpdateFence, pvUpdateFenceFinaliseData); - } -fail_create_output_fence: - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - -fail_free_buffer_sync_data: -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_failed(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } - -fail_resolve_input_fence: -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - -err_populate_sync_addr_list: - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - /* Free memory allocated to hold the internal list of update values */ - if (pui32IntAllocatedUpdateValues) - { - OSFreeMem(pui32IntAllocatedUpdateValues); - pui32IntAllocatedUpdateValues = NULL; - } - OSLockRelease(psComputeContext->hLock); - return eError; -} - -PVRSRV_ERROR PVRSRVRGXFlushComputeDataKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext) -{ - RGXFWIF_KCCB_CMD sFlushCmd; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_RGXDEV_INFO *psDevInfo = psComputeContext->psDeviceNode->pvDevice; - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psComputeContext->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS, "Submit Compute flush"); -#endif - sFlushCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL; - sFlushCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_FALSE; - sFlushCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_TRUE; - sFlushCmd.uCmdData.sSLCFlushInvalData.psContext = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext); - - OSLockAcquire(psComputeContext->hLock); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - RGXFWIF_DM_CDM, - &sFlushCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - /* Iterate if we hit a PVRSRV_ERROR_KERNEL_CCB_FULL error */ - if ((eError != PVRSRV_ERROR_RETRY) && - (eError != PVRSRV_ERROR_KERNEL_CCB_FULL)) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError != PVRSRV_OK) - { - /* If we hit a temporary KCCB exhaustion, return a RETRY to caller */ - if (eError == PVRSRV_ERROR_KERNEL_CCB_FULL) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Returning RETRY to caller", __func__)); - eError = PVRSRV_ERROR_RETRY; - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule SLC flush command (%s)", - __func__, - PVRSRVGetErrorString(eError))); - } - } - else - { - /* Wait for the SLC flush to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Compute flush aborted (%s)", - __func__, - PVRSRVGetErrorString(eError))); - } - else if (unlikely(psDevInfo->pui32KernelCCBRtnSlots[ui32kCCBCommandSlot] & - RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: FW poll on a HW operation failed", __func__)); - } - } - - OSLockRelease(psComputeContext->hLock); - return eError; -} - - -PVRSRV_ERROR PVRSRVRGXNotifyComputeWriteOffsetUpdateKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psComputeContext->psDeviceNode->pvDevice; - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, CDM_CONTROL_STREAM_FORMAT) && - 2 == RGX_GET_FEATURE_VALUE(psDevInfo, CDM_CONTROL_STREAM_FORMAT)) - { - - RGXFWIF_KCCB_CMD sKCCBCmd; - PVRSRV_ERROR eError; - - OSLockAcquire(psComputeContext->hLock); - - /* Schedule the firmware command */ - sKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE; - sKCCBCmd.uCmdData.sWriteOffsetUpdateData.psContext = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psComputeContext->psDeviceNode->pvDevice, - RGXFWIF_DM_CDM, - &sKCCBCmd, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule the FW command %d (%s)", - __func__, - eError, - PVRSRVGETERRORSTRING(eError))); - } - - OSLockRelease(psComputeContext->hLock); - return eError; - }else - { - return PVRSRV_ERROR_NOT_SUPPORTED; - } -} - - -PVRSRV_ERROR PVRSRVRGXSetComputeContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - IMG_UINT32 ui32Priority) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - - OSLockAcquire(psComputeContext->hLock); - - eError = ContextSetPriority(psComputeContext->psServerCommonContext, - psConnection, - psComputeContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_CDM); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the compute context (%s)", __func__, PVRSRVGetErrorString(eError))); - } - - OSLockRelease(psComputeContext->hLock); - return eError; -} - -/* - * PVRSRVRGXSetComputeContextPropertyKM - */ -PVRSRV_ERROR PVRSRVRGXSetComputeContextPropertyKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (eContextProperty) - { - case RGX_CONTEXT_PROPERTY_FLAGS: - { - IMG_UINT32 ui32ContextFlags = (IMG_UINT32)ui64Input; - - OSLockAcquire(psComputeContext->hLock); - eError = FWCommonContextSetFlags(psComputeContext->psServerCommonContext, - ui32ContextFlags); - OSLockRelease(psComputeContext->hLock); - break; - } - - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_ERROR_NOT_SUPPORTED - asked to set unknown property (%d)", __func__, eContextProperty)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - } - - return eError; -} - -void DumpComputeCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - DLLIST_NODE *psNode, *psNext; - OSWRLockAcquireRead(psDevInfo->hComputeCtxListLock); - dllist_foreach_node(&psDevInfo->sComputeCtxtListHead, psNode, psNext) - { - RGX_SERVER_COMPUTE_CONTEXT *psCurrentServerComputeCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_COMPUTE_CONTEXT, sListNode); - DumpFWCommonContextInfo(psCurrentServerComputeCtx->psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - OSWRLockReleaseRead(psDevInfo->hComputeCtxListLock); -} - -IMG_UINT32 CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32ContextBitMask = 0; - DLLIST_NODE *psNode, *psNext; - OSWRLockAcquireRead(psDevInfo->hComputeCtxListLock); - dllist_foreach_node(&psDevInfo->sComputeCtxtListHead, psNode, psNext) - { - RGX_SERVER_COMPUTE_CONTEXT *psCurrentServerComputeCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_COMPUTE_CONTEXT, sListNode); - - if (CheckStalledClientCommonContext(psCurrentServerComputeCtx->psServerCommonContext, RGX_KICK_TYPE_DM_CDM) - == PVRSRV_ERROR_CCCB_STALLED) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_CDM; - } - } - OSWRLockReleaseRead(psDevInfo->hComputeCtxListLock); - return ui32ContextBitMask; -} - -/* - * PVRSRVRGXGetLastDeviceErrorKM - */ -PVRSRV_ERROR PVRSRVRGXGetLastDeviceErrorKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *ui32Error) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - - *ui32Error = psDevInfo->eLastDeviceError; - psDevInfo->eLastDeviceError = RGX_CONTEXT_RESET_REASON_NONE; - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (rgxcompute.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxcompute.h b/drivers/gpu/drm/img-rogue/1.17/rgxcompute.h deleted file mode 100644 index 0ac6e4a3491e0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxcompute.h +++ /dev/null @@ -1,173 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX compute functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX compute functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXCOMPUTE_H) -#define RGXCOMPUTE_H - -#include "devicemem.h" -#include "device.h" -#include "rgxfwutils.h" -#include "rgx_fwif_resetframework.h" -#include "rgxdebug.h" -#include "pvr_notifier.h" - -#include "sync_server.h" -#include "sync_internal.h" -#include "connection_server.h" - - -typedef struct _RGX_SERVER_COMPUTE_CONTEXT_ RGX_SERVER_COMPUTE_CONTEXT; - -/*! -******************************************************************************* - @Function PVRSRVRGXCreateComputeContextKM - - @Description - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkRegisterSize, - IMG_PBYTE pbyFrameworkRegisters, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32StaticComputecontextStateSize, - IMG_PBYTE pStaticComputecontextState, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - IMG_UINT32 ui32MaxDeadlineMS, - RGX_SERVER_COMPUTE_CONTEXT **ppsComputeContext); - -/*! -******************************************************************************* - @Function PVRSRVRGXDestroyComputeContextKM - - @Description - Server-side implementation of RGXDestroyComputeContext - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext); - - -/*! -******************************************************************************* - @Function PVRSRVRGXKickCDMKM - - @Description - Server-side implementation of RGXKickCDM - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFODevVarBlock, - IMG_UINT32 *paui32ClientUpdateSyncOffset, - IMG_UINT32 *paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE *piUpdateFence, - IMG_CHAR pcszUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32CmdSize, - IMG_PBYTE pui8DMCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs, - IMG_UINT32 ui32NumWorkgroups, - IMG_UINT32 ui32NumWorkitems, - IMG_UINT64 ui64DeadlineInus); - -/*! -******************************************************************************* - @Function PVRSRVRGXFlushComputeDataKM - - @Description - Server-side implementation of RGXFlushComputeData - - @Input psComputeContext - Compute context to flush - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXFlushComputeDataKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext); - -/*! -******************************************************************************* - - @Function PVRSRVRGXNotifyComputeWriteOffsetUpdateKM - @Description Server-side implementation of RGXNotifyComputeWriteOffsetUpdate - - @Input psComputeContext - Compute context to flush - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXNotifyComputeWriteOffsetUpdateKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext); - -PVRSRV_ERROR PVRSRVRGXSetComputeContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - IMG_UINT32 ui32Priority); - -PVRSRV_ERROR PVRSRVRGXSetComputeContextPropertyKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output); - -PVRSRV_ERROR PVRSRVRGXGetLastDeviceErrorKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *ui32Error); - -/* Debug - Dump debug info of compute contexts on this device */ -void DumpComputeCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/* Debug/Watchdog - check if client compute contexts are stalled */ -IMG_UINT32 CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); - -#endif /* RGXCOMPUTE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxdebug.c b/drivers/gpu/drm/img-rogue/1.17/rgxdebug.c deleted file mode 100644 index 6bf607ecf8a5e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxdebug.c +++ /dev/null @@ -1,5785 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Rgx debug information -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX debugging functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -//#define PVR_DPF_FUNCTION_TRACE_ON 1 -#undef PVR_DPF_FUNCTION_TRACE_ON - -#include "img_defs.h" -#include "rgxdefs_km.h" -#include "rgxdevice.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "cache_km.h" -#include "osfunc.h" - -#include "rgxdebug.h" -#include "pvrversion.h" -#include "pvr_debug.h" -#include "srvkm.h" -#include "rgxutils.h" -#include "tlstream.h" -#include "rgxfwutils.h" -#include "pvrsrv.h" -#include "services_km.h" - -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "devicemem_utils.h" -#include "rgx_fwif_km.h" -#include "rgx_fwif_sf.h" -#include "rgxfw_log_helper.h" -#include "fwtrace_string.h" -#include "rgxfwimageutils.h" -#include "fwload.h" - -#include "rgxta3d.h" -#include "rgxkicksync.h" -#include "rgxcompute.h" -#include "rgxtransfer.h" -#include "rgxtdmtransfer.h" -#include "rgxtimecorr.h" -#include "rgx_options.h" -#include "rgxinit.h" -#include "devicemem_history_server.h" -#include "info_page.h" -#include "rgx_bvnc_defs_km.h" - -#define PVR_DUMP_FIRMWARE_INFO(x) \ - PVR_DUMPDEBUG_LOG("FW info: %d.%d @ %8d (%s) build options: 0x%08x", \ - PVRVERSION_UNPACK_MAJ((x).ui32DDKVersion), \ - PVRVERSION_UNPACK_MIN((x).ui32DDKVersion), \ - (x).ui32DDKBuild, \ - ((x).ui32BuildOptions & OPTIONS_DEBUG_MASK) ? "debug":"release",\ - (x).ui32BuildOptions); - -#define DD_SUMMARY_INDENT "" -#define DD_NORMAL_INDENT " " - -#define RGX_DEBUG_STR_SIZE (150U) -#define MAX_FW_DESCRIPTION_LENGTH (500U) - -#define RGX_CR_BIF_CAT_BASE0 (0x1200U) -#define RGX_CR_BIF_CAT_BASE1 (0x1208U) - -#define RGX_CR_BIF_CAT_BASEN(n) \ - RGX_CR_BIF_CAT_BASE0 + \ - ((RGX_CR_BIF_CAT_BASE1 - RGX_CR_BIF_CAT_BASE0) * n) - - -#define RGXDBG_BIF_IDS \ - X(BIF0)\ - X(BIF1)\ - X(TEXAS_BIF)\ - X(DPX_BIF) \ - X(FWCORE) - -#define RGXDBG_SIDEBAND_TYPES \ - X(META)\ - X(TLA)\ - X(DMA)\ - X(VDMM)\ - X(CDM)\ - X(IPP)\ - X(PM)\ - X(TILING)\ - X(MCU)\ - X(PDS)\ - X(PBE)\ - X(VDMS)\ - X(IPF)\ - X(ISP)\ - X(TPF)\ - X(USCS)\ - X(PPP)\ - X(VCE)\ - X(TPF_CPF)\ - X(IPF_CPF)\ - X(FBCDC) - -typedef enum -{ -#define X(NAME) RGXDBG_##NAME, - RGXDBG_BIF_IDS -#undef X -} RGXDBG_BIF_ID; - -typedef enum -{ -#define X(NAME) RGXDBG_##NAME, - RGXDBG_SIDEBAND_TYPES -#undef X -} RGXDBG_SIDEBAND_TYPE; - -static const IMG_CHAR *const pszPowStateName[] = -{ -#define X(NAME) #NAME, - RGXFWIF_POW_STATES -#undef X -}; - -static const IMG_CHAR *const pszBIFNames[] = -{ -#define X(NAME) #NAME, - RGXDBG_BIF_IDS -#undef X -}; - -typedef struct _IMG_FLAGS2DESC_ -{ - IMG_UINT32 uiFlag; - const IMG_CHAR *pszLabel; -} IMG_FLAGS2DESC; - -static const IMG_FLAGS2DESC asCswOpts2Description[] = -{ - {RGXFWIF_INICFG_CTXSWITCH_PROFILE_FAST, " Fast CSW profile;"}, - {RGXFWIF_INICFG_CTXSWITCH_PROFILE_MEDIUM, " Medium CSW profile;"}, - {RGXFWIF_INICFG_CTXSWITCH_PROFILE_SLOW, " Slow CSW profile;"}, - {RGXFWIF_INICFG_CTXSWITCH_PROFILE_NODELAY, " No Delay CSW profile;"}, - {RGXFWIF_INICFG_CTXSWITCH_MODE_RAND, " Random Csw enabled;"}, - {RGXFWIF_INICFG_CTXSWITCH_SRESET_EN, " SoftReset;"}, -}; - -static const IMG_FLAGS2DESC asMisc2Description[] = -{ - {RGXFWIF_INICFG_POW_RASCALDUST, " Power Rascal/Dust;"}, - {RGXFWIF_INICFG_HWPERF_EN, " HwPerf EN;"}, - {RGXFWIF_INICFG_FBCDC_V3_1_EN, " FBCDCv3.1;"}, - {RGXFWIF_INICFG_CHECK_MLIST_EN, " Check MList;"}, - {RGXFWIF_INICFG_DISABLE_CLKGATING_EN, " ClockGating Off;"}, - {RGXFWIF_INICFG_REGCONFIG_EN, " Register Config;"}, - {RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY, " Assert on OOM;"}, - {RGXFWIF_INICFG_HWP_DISABLE_FILTER, " HWP Filter Off;"}, - {RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN, " CDM Random kill;"}, - {RGXFWIF_INICFG_DISABLE_DM_OVERLAP, " DM Overlap Off;"}, - {RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER, " Assert on HWR;"}, - {RGXFWIF_INICFG_FABRIC_COHERENCY_ENABLED, " Coherent fabric on;"}, - {RGXFWIF_INICFG_VALIDATE_IRQ, " Validate IRQ;"}, - {RGXFWIF_INICFG_DISABLE_PDP_EN, " PDUMP Panic off;"}, - {RGXFWIF_INICFG_SPU_POWER_STATE_MASK_CHANGE_EN, " SPU Pow mask change on;"}, - {RGXFWIF_INICFG_WORKEST, " Workload Estim;"}, - {RGXFWIF_INICFG_PDVFS, " PDVFS;"}, - {RGXFWIF_INICFG_CDM_ARBITRATION_TASK_DEMAND, " CDM task demand arbitration;"}, - {RGXFWIF_INICFG_CDM_ARBITRATION_ROUND_ROBIN, " CDM round-robin arbitration;"}, - {RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP, " ISP v1 scheduling;"}, - {RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP, " ISP v2 scheduling;"}, - {RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER, " Validate SOC&USC timers;"}, -}; - -static const IMG_FLAGS2DESC asFwOsCfg2Description[] = -{ - {RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN, " TDM;"}, - {RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN, " TA;"}, - {RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN, " 3D;"}, - {RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN, " CDM;"}, - {RGXFWIF_INICFG_OS_LOW_PRIO_CS_TDM, " LowPrio TDM;"}, - {RGXFWIF_INICFG_OS_LOW_PRIO_CS_GEOM, " LowPrio TA;"}, - {RGXFWIF_INICFG_OS_LOW_PRIO_CS_3D, " LowPrio 3D;"}, - {RGXFWIF_INICFG_OS_LOW_PRIO_CS_CDM, " LowPrio CDM;"}, -}; - -static const IMG_FLAGS2DESC asHwrState2Description[] = -{ - {RGXFWIF_HWR_HARDWARE_OK, " HWR OK;"}, - {RGXFWIF_HWR_GENERAL_LOCKUP, " General lockup;"}, - {RGXFWIF_HWR_DM_RUNNING_OK, " DM running ok;"}, - {RGXFWIF_HWR_DM_STALLING, " DM stalling;"}, - {RGXFWIF_HWR_FW_FAULT, " FW fault;"}, - {RGXFWIF_HWR_RESTART_REQUESTED, " Restarting;"}, -}; - -static const IMG_FLAGS2DESC asDmState2Description[] = -{ - {RGXFWIF_DM_STATE_READY_FOR_HWR, " ready for hwr;"}, - {RGXFWIF_DM_STATE_NEEDS_SKIP, " needs skip;"}, - {RGXFWIF_DM_STATE_NEEDS_PR_CLEANUP, " needs PR cleanup;"}, - {RGXFWIF_DM_STATE_NEEDS_TRACE_CLEAR, " needs trace clear;"}, - {RGXFWIF_DM_STATE_GUILTY_LOCKUP, " guilty lockup;"}, - {RGXFWIF_DM_STATE_INNOCENT_LOCKUP, " innocent lockup;"}, - {RGXFWIF_DM_STATE_GUILTY_OVERRUNING, " guilty overrunning;"}, - {RGXFWIF_DM_STATE_INNOCENT_OVERRUNING, " innocent overrunning;"}, - {RGXFWIF_DM_STATE_HARD_CONTEXT_SWITCH, " hard context switching;"}, - {RGXFWIF_DM_STATE_GPU_ECC_HWR, " GPU ECC hwr;"}, -}; - -const IMG_CHAR * const gapszMipsPermissionPTFlags[4] = -{ - " ", - "XI ", - "RI ", - "RIXI" -}; - -const IMG_CHAR * const gapszMipsCoherencyPTFlags[8] = -{ - "C", - "C", - " ", - "C", - "C", - "C", - "C", - " " -}; - -const IMG_CHAR * const gapszMipsDirtyGlobalValidPTFlags[8] = -{ - " ", - " G", - " V ", - " VG", - "D ", - "D G", - "DV ", - "DVG" -}; - -#if !defined(SUPPORT_TRUSTED_DEVICE) -#if !defined(NO_HARDWARE) -/* Translation of MIPS exception encoding */ -typedef struct _MIPS_EXCEPTION_ENCODING_ -{ - const IMG_CHAR *const pszStr; /* Error type */ - const IMG_BOOL bIsFatal; /* Error is fatal or non-fatal */ -} MIPS_EXCEPTION_ENCODING; - -static const MIPS_EXCEPTION_ENCODING apsMIPSExcCodes[] = -{ - {"Interrupt", IMG_FALSE}, - {"TLB modified exception", IMG_FALSE}, - {"TLB exception (load/instruction fetch)", IMG_FALSE}, - {"TLB exception (store)", IMG_FALSE}, - {"Address error exception (load/instruction fetch)", IMG_TRUE}, - {"Address error exception (store)", IMG_TRUE}, - {"Bus error exception (instruction fetch)", IMG_TRUE}, - {"Bus error exception (load/store)", IMG_TRUE}, - {"Syscall exception", IMG_FALSE}, - {"Breakpoint exception (FW assert)", IMG_FALSE}, - {"Reserved instruction exception", IMG_TRUE}, - {"Coprocessor Unusable exception", IMG_FALSE}, - {"Arithmetic Overflow exception", IMG_FALSE}, - {"Trap exception", IMG_FALSE}, - {NULL, IMG_FALSE}, - {NULL, IMG_FALSE}, - {"Implementation-Specific Exception 1 (COP2)", IMG_FALSE}, - {"CorExtend Unusable", IMG_FALSE}, - {"Coprocessor 2 exceptions", IMG_FALSE}, - {"TLB Read-Inhibit", IMG_TRUE}, - {"TLB Execute-Inhibit", IMG_TRUE}, - {NULL, IMG_FALSE}, - {NULL, IMG_FALSE}, - {"Reference to WatchHi/WatchLo address", IMG_FALSE}, - {"Machine check", IMG_FALSE}, - {NULL, IMG_FALSE}, - {"DSP Module State Disabled exception", IMG_FALSE}, - {NULL, IMG_FALSE}, - {NULL, IMG_FALSE}, - {NULL, IMG_FALSE}, - /* Can only happen in MIPS debug mode */ - {"Parity error", IMG_FALSE}, - {NULL, IMG_FALSE} -}; - -static IMG_CHAR const *_GetMIPSExcString(IMG_UINT32 ui32ExcCode) -{ - if (ui32ExcCode >= sizeof(apsMIPSExcCodes)/sizeof(MIPS_EXCEPTION_ENCODING)) - { - PVR_DPF((PVR_DBG_WARNING, - "Only %lu exceptions available in MIPS, %u is not a valid exception code", - (unsigned long)sizeof(apsMIPSExcCodes)/sizeof(MIPS_EXCEPTION_ENCODING), ui32ExcCode)); - return NULL; - } - - return apsMIPSExcCodes[ui32ExcCode].pszStr; -} -#endif -#endif /* !defined(SUPPORT_TRUSTED_DEVICE) */ - -typedef struct _RGXMIPSFW_C0_DEBUG_TBL_ENTRY_ -{ - IMG_UINT32 ui32Mask; - const IMG_CHAR * pszExplanation; -} RGXMIPSFW_C0_DEBUG_TBL_ENTRY; - -#if !defined(SUPPORT_TRUSTED_DEVICE) -#if !defined(NO_HARDWARE) -static const RGXMIPSFW_C0_DEBUG_TBL_ENTRY sMIPS_C0_DebugTable[] = -{ - { RGXMIPSFW_C0_DEBUG_DSS, "Debug single-step exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DBP, "Debug software breakpoint exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DDBL, "Debug data break exception occurred on a load" }, - { RGXMIPSFW_C0_DEBUG_DDBS, "Debug data break exception occurred on a store" }, - { RGXMIPSFW_C0_DEBUG_DIB, "Debug instruction break exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DINT, "Debug interrupt exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DIBIMPR, "Imprecise debug instruction break exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DDBLIMPR, "Imprecise debug data break load exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DDBSIMPR, "Imprecise debug data break store exception occurred" }, - { RGXMIPSFW_C0_DEBUG_IEXI, "Imprecise error exception inhibit controls exception occurred" }, - { RGXMIPSFW_C0_DEBUG_DBUSEP, "Data access Bus Error exception pending" }, - { RGXMIPSFW_C0_DEBUG_CACHEEP, "Imprecise Cache Error pending" }, - { RGXMIPSFW_C0_DEBUG_MCHECKP, "Imprecise Machine Check exception pending" }, - { RGXMIPSFW_C0_DEBUG_IBUSEP, "Instruction fetch Bus Error exception pending" }, - { (IMG_UINT32)RGXMIPSFW_C0_DEBUG_DBD, "Debug exception occurred in branch delay slot" } -}; -#endif -#endif /* !defined(SUPPORT_TRUSTED_DEVICE) */ - -static const IMG_CHAR * const apszFwOsStateName[RGXFW_CONNECTION_FW_STATE_COUNT] = -{ - "offline", - "ready", - "active", - "offloading" -}; - -#if defined(PVR_ENABLE_PHR) -static const IMG_FLAGS2DESC asPHRConfig2Description[] = -{ - {BIT_ULL(RGXFWIF_PHR_MODE_OFF), "off"}, - {BIT_ULL(RGXFWIF_PHR_MODE_RD_RESET), "reset RD hardware"}, - {BIT_ULL(RGXFWIF_PHR_MODE_FULL_RESET), "full gpu reset "}, -}; -#endif - -static PVRSRV_ERROR -RGXPollMetaRegThroughSP(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32PollValue, IMG_UINT32 ui32Mask) -{ - IMG_UINT32 ui32RegValue, ui32NumPolls = 0; - PVRSRV_ERROR eError; - - do - { - eError = RGXReadFWModuleAddr(psDevInfo, ui32RegOffset, &ui32RegValue); - if (eError != PVRSRV_OK) - { - return eError; - } - } while (((ui32RegValue & ui32Mask) != ui32PollValue) && (ui32NumPolls++ < 1000)); - - return ((ui32RegValue & ui32Mask) == ui32PollValue) ? PVRSRV_OK : PVRSRV_ERROR_RETRY; -} - -static PVRSRV_ERROR -RGXReadMetaCoreReg(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32RegAddr, IMG_UINT32 *pui32RegVal) -{ - PVRSRV_ERROR eError; - - /* Core Read Ready? */ - eError = RGXPollMetaRegThroughSP(psDevInfo, - META_CR_TXUXXRXRQ_OFFSET, - META_CR_TXUXXRXRQ_DREADY_BIT, - META_CR_TXUXXRXRQ_DREADY_BIT); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXPollMetaRegThroughSP"); - - /* Set the reg we are interested in reading */ - eError = RGXWriteFWModuleAddr(psDevInfo, META_CR_TXUXXRXRQ_OFFSET, - ui32RegAddr | META_CR_TXUXXRXRQ_RDnWR_BIT); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXWriteFWModuleAddr"); - - /* Core Read Done? */ - eError = RGXPollMetaRegThroughSP(psDevInfo, - META_CR_TXUXXRXRQ_OFFSET, - META_CR_TXUXXRXRQ_DREADY_BIT, - META_CR_TXUXXRXRQ_DREADY_BIT); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXPollMetaRegThroughSP"); - - /* Read the value */ - return RGXReadFWModuleAddr(psDevInfo, META_CR_TXUXXRXDT_OFFSET, pui32RegVal); -} - -#if !defined(NO_HARDWARE) && !defined(SUPPORT_TRUSTED_DEVICE) -static PVRSRV_ERROR _ValidateWithFWModule(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DEV_VIRTADDR *psFWAddr, - void *pvHostCodeAddr, - IMG_UINT32 ui32MaxLen, - const IMG_CHAR *pszDesc, - IMG_UINT32 ui32StartOffset) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32Value = 0; - IMG_UINT32 ui32FWCodeDevVAAddr = psFWAddr->ui32Addr + ui32StartOffset; - IMG_UINT32 *pui32FWCode = (IMG_PUINT32) ((IMG_PBYTE)pvHostCodeAddr + ui32StartOffset); - IMG_UINT32 i; - -#if defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - return PVRSRV_OK; - } -#endif - - ui32MaxLen -= ui32StartOffset; - ui32MaxLen /= sizeof(IMG_UINT32); /* Byte -> 32 bit words */ - - for (i = 0; i < ui32MaxLen; i++) - { - eError = RGXReadFWModuleAddr(psDevInfo, ui32FWCodeDevVAAddr, &ui32Value); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: %s", __func__, PVRSRVGetErrorString(eError))); - return eError; - } - -#if defined(EMULATOR) - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) -#endif - { - PVR_DPF((PVR_DBG_VERBOSE, "0x%x: CPU 0x%08x, FW 0x%08x", i * 4, pui32FWCode[i], ui32Value)); - - if (pui32FWCode[i] != ui32Value) - { - PVR_DUMPDEBUG_LOG("%s: Mismatch while validating %s at offset 0x%x: CPU 0x%08x (%p), FW 0x%08x (%x)", - __func__, pszDesc, - (i * 4) + ui32StartOffset, pui32FWCode[i], pui32FWCode, ui32Value, ui32FWCodeDevVAAddr); - return PVRSRV_ERROR_FW_IMAGE_MISMATCH; - } - } - - ui32FWCodeDevVAAddr += 4; - } - - PVR_DUMPDEBUG_LOG("Match between Host and Firmware view of the %s", pszDesc); - return PVRSRV_OK; -} -#endif - -static PVRSRV_ERROR _ValidateFWImage(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if !defined(NO_HARDWARE) && !defined(SUPPORT_TRUSTED_DEVICE) - PVRSRV_ERROR eError; - IMG_UINT32 *pui32HostFWCode = NULL, *pui32HostFWCoremem = NULL; - OS_FW_IMAGE *psRGXFW = NULL; - const IMG_BYTE *pbRGXFirmware = NULL; - IMG_UINT32 *pui32CodeMemoryPointer; - RGXFWIF_DEV_VIRTADDR sFWAddr; - IMG_UINT32 ui32StartOffset = 0; - RGX_LAYER_PARAMS sLayerParams; - sLayerParams.psDevInfo = psDevInfo; - -#if defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - PVR_DUMPDEBUG_LOG("Validation of RISC-V FW code is disabled on emulator"); - return PVRSRV_OK; - } -#endif - - if (psDevInfo->pvRegsBaseKM == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: RGX registers not mapped yet!", __func__)); - return PVRSRV_ERROR_BAD_MAPPING; - } - - /* Load FW from system for code verification */ - pui32HostFWCode = OSAllocZMem(psDevInfo->ui32FWCodeSizeInBytes); - if (pui32HostFWCode == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed in allocating memory for FW code. " - "So skipping FW code verification", - __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - if (psDevInfo->ui32FWCorememCodeSizeInBytes) - { - pui32HostFWCoremem = OSAllocZMem(psDevInfo->ui32FWCorememCodeSizeInBytes); - if (pui32HostFWCoremem == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed in allocating memory for FW core code. " - "So skipping FW code verification", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto freeHostFWCode; - } - } - - /* Load FW image */ - eError = RGXLoadAndGetFWData(psDevInfo->psDeviceNode, &psRGXFW, &pbRGXFirmware); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to load FW image file (%s).", - __func__, PVRSRVGetErrorString(eError))); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto cleanup_initfw; - } - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - eError = ProcessLDRCommandStream(&sLayerParams, pbRGXFirmware, - (void*) pui32HostFWCode, NULL, - (void*) pui32HostFWCoremem, NULL, NULL); - } - else if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - eError = ProcessELFCommandStream(&sLayerParams, pbRGXFirmware, - pui32HostFWCode, NULL, - NULL, NULL); - } - else if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - eError = ProcessELFCommandStream(&sLayerParams, pbRGXFirmware, - pui32HostFWCode, NULL, - pui32HostFWCoremem, NULL); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed in parsing FW image file.", __func__)); - goto cleanup_initfw; - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc, (void **)&pui32CodeMemoryPointer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error in acquiring MIPS FW code memory area (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto cleanup_initfw; - } - - if (OSMemCmp(pui32HostFWCode, pui32CodeMemoryPointer, psDevInfo->ui32FWCodeSizeInBytes) == 0) - { - PVR_DUMPDEBUG_LOG("Match between Host and MIPS views of the FW code" ); - } - else - { - IMG_UINT32 ui32Count = 10; /* Show only the first 10 mismatches */ - IMG_UINT32 ui32Offset; - - PVR_DUMPDEBUG_LOG("Mismatch between Host and MIPS views of the FW code"); - for (ui32Offset = 0; (ui32Offset*4 < psDevInfo->ui32FWCodeSizeInBytes) || (ui32Count == 0); ui32Offset++) - { - if (pui32HostFWCode[ui32Offset] != pui32CodeMemoryPointer[ui32Offset]) - { - PVR_DUMPDEBUG_LOG("At %d bytes, code should be 0x%x but it is instead 0x%x", - ui32Offset*4, pui32HostFWCode[ui32Offset], pui32CodeMemoryPointer[ui32Offset]); - ui32Count--; - } - } - } - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc); - } - else - { - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - /* starting checking after BOOT LOADER config */ - sFWAddr.ui32Addr = RGXFW_BOOTLDR_META_ADDR; - - ui32StartOffset = RGXFW_MAX_BOOTLDR_OFFSET; - } - else - { - /* Use bootloader code remap which is always configured before the FW is started */ - sFWAddr.ui32Addr = RGXRISCVFW_BOOTLDR_CODE_BASE; - } - - eError = _ValidateWithFWModule(pfnDumpDebugPrintf, pvDumpDebugFile, - psDevInfo, &sFWAddr, - pui32HostFWCode, psDevInfo->ui32FWCodeSizeInBytes, - "FW code", ui32StartOffset); - if (eError != PVRSRV_OK) - { - goto cleanup_initfw; - } - - if (psDevInfo->ui32FWCorememCodeSizeInBytes) - { - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - sFWAddr.ui32Addr = RGXGetFWImageSectionAddress(NULL, META_COREMEM_CODE); - } - else - { - sFWAddr.ui32Addr = RGXGetFWImageSectionAddress(NULL, RISCV_COREMEM_CODE); - - /* Core must be halted while issuing abstract commands */ - eError = RGXRiscvHalt(psDevInfo); - PVR_GOTO_IF_ERROR(eError, cleanup_initfw); - } - - eError = _ValidateWithFWModule(pfnDumpDebugPrintf, pvDumpDebugFile, - psDevInfo, &sFWAddr, - pui32HostFWCoremem, psDevInfo->ui32FWCorememCodeSizeInBytes, - "FW coremem code", 0); - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - eError = RGXRiscvResume(psDevInfo); - PVR_GOTO_IF_ERROR(eError, cleanup_initfw); - } - } - } - -cleanup_initfw: - if (psRGXFW) - { - OSUnloadFirmware(psRGXFW); - } - - if (pui32HostFWCoremem) - { - OSFreeMem(pui32HostFWCoremem); - } -freeHostFWCode: - if (pui32HostFWCode) - { - OSFreeMem(pui32HostFWCode); - } - return eError; -#else - PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf); - PVR_UNREFERENCED_PARAMETER(pvDumpDebugFile); - PVR_UNREFERENCED_PARAMETER(psDevInfo); - return PVRSRV_OK; -#endif -} - -#if defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) -PVRSRV_ERROR ValidateFWOnLoad(PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if !defined(NO_HARDWARE) && !defined(SUPPORT_TRUSTED_DEVICE) - IMG_PBYTE pbCodeMemoryPointer; - PVRSRV_ERROR eError; - RGXFWIF_DEV_VIRTADDR sFWAddr; - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc, (void **)&pbCodeMemoryPointer); - if (eError != PVRSRV_OK) - { - return eError; - } - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - sFWAddr.ui32Addr = RGXFW_BOOTLDR_META_ADDR; - } - else - { - PVR_ASSERT(RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)); - sFWAddr.ui32Addr = RGXRISCVFW_BOOTLDR_CODE_BASE; - }; - - eError = _ValidateWithFWModule(NULL, NULL, psDevInfo, &sFWAddr, pbCodeMemoryPointer, psDevInfo->ui32FWCodeSizeInBytes, "FW code", 0); - if (eError != PVRSRV_OK) - { - goto releaseFWCodeMapping; - } - - if (psDevInfo->ui32FWCorememCodeSizeInBytes) - { - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc, (void **)&pbCodeMemoryPointer); - if (eError != PVRSRV_OK) - { - goto releaseFWCoreCodeMapping; - } - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - sFWAddr.ui32Addr = RGXGetFWImageSectionAddress(NULL, META_COREMEM_CODE); - } - else - { - PVR_ASSERT(RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)); - sFWAddr.ui32Addr = RGXGetFWImageSectionAddress(NULL, RISCV_COREMEM_CODE); - } - - eError = _ValidateWithFWModule(NULL, NULL, psDevInfo, &sFWAddr, pbCodeMemoryPointer, - psDevInfo->ui32FWCorememCodeSizeInBytes, "FW coremem code", 0); - } - -releaseFWCoreCodeMapping: - if (psDevInfo->ui32FWCorememCodeSizeInBytes) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc); - } -releaseFWCodeMapping: - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); - return PVRSRV_OK; -#endif -} -#endif - -/*! -******************************************************************************* - - @Function _RGXDecodePMPC - - @Description - - Return the name for the PM managed Page Catalogues - - @Input ui32PC - Page Catalogue number - - @Return void - -******************************************************************************/ -static const IMG_CHAR* _RGXDecodePMPC(IMG_UINT32 ui32PC) -{ - const IMG_CHAR* pszPMPC = " (-)"; - - switch (ui32PC) - { - case 0x8: pszPMPC = " (PM-VCE0)"; break; - case 0x9: pszPMPC = " (PM-TE0)"; break; - case 0xA: pszPMPC = " (PM-ZLS0)"; break; - case 0xB: pszPMPC = " (PM-ALIST0)"; break; - case 0xC: pszPMPC = " (PM-VCE1)"; break; - case 0xD: pszPMPC = " (PM-TE1)"; break; - case 0xE: pszPMPC = " (PM-ZLS1)"; break; - case 0xF: pszPMPC = " (PM-ALIST1)"; break; - } - - return pszPMPC; -} - -/*! -******************************************************************************* - - @Function _RGXDecodeBIFReqTags - - @Description - - Decode the BIF Tag ID and sideband data fields from BIF_FAULT_BANK_REQ_STATUS regs - - @Input eBankID - BIF identifier - @Input ui32TagID - Tag ID value - @Input ui32TagSB - Tag Sideband data - @Output ppszTagID - Decoded string from the Tag ID - @Output ppszTagSB - Decoded string from the Tag SB - @Output pszScratchBuf - Buffer provided to the function to generate the debug strings - @Input ui32ScratchBufSize - Size of the provided buffer - - @Return void - -******************************************************************************/ -#include "rgxmhdefs_km.h" - -static void _RGXDecodeBIFReqTagsXE(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32TagID, - IMG_UINT32 ui32TagSB, - IMG_CHAR **ppszTagID, - IMG_CHAR **ppszTagSB, - IMG_CHAR *pszScratchBuf, - IMG_UINT32 ui32ScratchBufSize) -{ - /* default to unknown */ - IMG_CHAR *pszTagID = "-"; - IMG_CHAR *pszTagSB = "-"; - IMG_BOOL bNewTagEncoding = IMG_FALSE; - - PVR_ASSERT(ppszTagID != NULL); - PVR_ASSERT(ppszTagSB != NULL); - - /* tags updated for all cores (auto & consumer) with branch > 36 or only auto cores with branch = 36 */ - if ((psDevInfo->sDevFeatureCfg.ui32B > 36) || - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TILE_REGION_PROTECTION) && (psDevInfo->sDevFeatureCfg.ui32B == 36))) - { - bNewTagEncoding = IMG_TRUE; - } - - switch (ui32TagID) - { - /* MMU tags */ - case RGX_MH_TAG_ENCODING_MH_TAG_MMU: - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_MMU: - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_IFU: - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_LSU: - { - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_MMU: pszTagID = "MMU"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_MMU: pszTagID = "CPU MMU"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_IFU: pszTagID = "CPU IFU"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_LSU: pszTagID = "CPU LSU"; break; - } - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PT_REQUEST: pszTagSB = "PT"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PD_REQUEST: pszTagSB = "PD"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PC_REQUEST: pszTagSB = "PC"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PT_REQUEST: pszTagSB = "PM PT"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PD_REQUEST: pszTagSB = "PM PD"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PC_REQUEST: pszTagSB = "PM PC"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PD_WREQUEST: pszTagSB = "PM PD W"; break; - case RGX_MH_TAG_SB_MMU_ENCODING_MMU_TAG_PM_PC_WREQUEST: pszTagSB = "PM PC W"; break; - } - break; - } - - /* MIPS */ - case RGX_MH_TAG_ENCODING_MH_TAG_MIPS: - { - pszTagID = "MIPS"; - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_MIPS_ENCODING_MIPS_TAG_OPCODE_FETCH: pszTagSB = "Opcode"; break; - case RGX_MH_TAG_SB_MIPS_ENCODING_MIPS_TAG_DATA_ACCESS: pszTagSB = "Data"; break; - } - break; - } - - /* CDM tags */ - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG0: - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG1: - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG2: - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG3: - { - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG0: pszTagID = "CDM Stage 0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG1: pszTagID = "CDM Stage 1"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG2: pszTagID = "CDM Stage 2"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CDM_STG3: pszTagID = "CDM Stage 3"; break; - } - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_CONTROL_STREAM: pszTagSB = "Control"; break; - case RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_INDIRECT_DATA: pszTagSB = "Indirect"; break; - case RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_EVENT_DATA: pszTagSB = "Event"; break; - case RGX_MH_TAG_SB_CDM_ENCODING_CDM_TAG_CONTEXT_STATE: pszTagSB = "Context"; break; - } - break; - } - - /* VDM tags */ - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG0: - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG1: - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG2: - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG3: - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG4: - { - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG0: pszTagID = "VDM Stage 0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG1: pszTagID = "VDM Stage 1"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG2: pszTagID = "VDM Stage 2"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG3: pszTagID = "VDM Stage 3"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG4: pszTagID = "VDM Stage 4"; break; - } - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_CONTROL: pszTagSB = "Control"; break; - case RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_STATE: pszTagSB = "State"; break; - case RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_INDEX: pszTagSB = "Index"; break; - case RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_STACK: pszTagSB = "Stack"; break; - case RGX_MH_TAG_SB_VDM_ENCODING_VDM_TAG_CONTEXT: pszTagSB = "Context"; break; - } - break; - } - - /* PDS */ - case RGX_MH_TAG_ENCODING_MH_TAG_PDS_0: - pszTagID = "PDS req 0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_PDS_1: - pszTagID = "PDS req 1"; break; - - /* MCU */ - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCA: - pszTagID = "MCU USCA"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCB: - pszTagID = "MCU USCB"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCC: - pszTagID = "MCU USCC"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_USCD: - pszTagID = "MCU USCD"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCA: - pszTagID = "MCU PDS USCA"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCB: - pszTagID = "MCU PDS USCB"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCC: - pszTagID = "MCU PDS USCC"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDS_USCD: - pszTagID = "MCU PDSUSCD"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_MCU_PDSRW: - pszTagID = "MCU PDS PDSRW"; break; - - /* TCU */ - case RGX_MH_TAG_ENCODING_MH_TAG_TCU_0: - pszTagID = "TCU req 0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TCU_1: - pszTagID = "TCU req 1"; break; - - /* FBCDC */ - case RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_0: - pszTagID = bNewTagEncoding ? "TFBDC_TCU0" : "FBCDC0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_1: - pszTagID = bNewTagEncoding ? "TFBDC_ZLS0" : "FBCDC1"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_2: - pszTagID = bNewTagEncoding ? "TFBDC_TCU1" : "FBCDC2"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_FBCDC_3: - pszTagID = bNewTagEncoding ? "TFBDC_ZLS1" : "FBCDC3"; break; - - /* USC Shared */ - case RGX_MH_TAG_ENCODING_MH_TAG_USC: - pszTagID = "USCS"; break; - - /* ISP */ - case RGX_MH_TAG_ENCODING_MH_TAG_ISP_ZLS: - pszTagID = "ISP0 ZLS"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_ISP_DS: - pszTagID = "ISP0 DS"; break; - - /* TPF */ - case RGX_MH_TAG_ENCODING_MH_TAG_TPF: - case RGX_MH_TAG_ENCODING_MH_TAG_TPF_PBCDBIAS: - case RGX_MH_TAG_ENCODING_MH_TAG_TPF_SPF: - { - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_TPF: pszTagID = "TPF0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TPF_PBCDBIAS: pszTagID = "TPF0 DBIAS"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TPF_SPF: pszTagID = "TPF0 SPF"; break; - } - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_PDS_STATE: pszTagSB = "PDS state"; break; - case RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_DEPTH_BIAS: pszTagSB = "Depth bias"; break; - case RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_FLOOR_OFFSET_DATA: pszTagSB = "Floor offset"; break; - case RGX_MH_TAG_SB_TPF_ENCODING_TPF_TAG_DELTA_DATA: pszTagSB = "Delta"; break; - } - break; - } - - /* IPF */ - case RGX_MH_TAG_ENCODING_MH_TAG_IPF_CREQ: - case RGX_MH_TAG_ENCODING_MH_TAG_IPF_OTHERS: - { - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_IPF_CREQ: pszTagID = "IPF0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_IPF_OTHERS: pszTagID = "IPF0"; break; - } - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_ISP_IPP_PIPES)) - { - if (ui32TagID < RGX_GET_FEATURE_VALUE(psDevInfo, NUM_ISP_IPP_PIPES)) - { - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, "CReq%d", ui32TagID); - pszTagSB = pszScratchBuf; - } - else if (ui32TagID < 2 * RGX_GET_FEATURE_VALUE(psDevInfo, NUM_ISP_IPP_PIPES)) - { - ui32TagID -= RGX_GET_FEATURE_VALUE(psDevInfo, NUM_ISP_IPP_PIPES); - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, "PReq%d", ui32TagID); - pszTagSB = pszScratchBuf; - } - else - { - switch (ui32TagSB - 2 * RGX_GET_FEATURE_VALUE(psDevInfo, NUM_ISP_IPP_PIPES)) - { - case 0: pszTagSB = "RReq"; break; - case 1: pszTagSB = "DBSC"; break; - case 2: pszTagSB = "CPF"; break; - case 3: pszTagSB = "Delta"; break; - } - } - } - break; - } - - /* VDM Stage 5 (temporary) */ - case RGX_MH_TAG_ENCODING_MH_TAG_VDM_STG5: - pszTagID = "VDM Stage 5"; break; - - /* TA */ - case RGX_MH_TAG_ENCODING_MH_TAG_TA_PPP: - pszTagID = "PPP"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_TPWRTC: - pszTagID = "TPW RTC"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_TEACRTC: - pszTagID = "TEAC RTC"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGRTC: - pszTagID = "PSG RTC"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGREGION: - pszTagID = "PSG Region"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_PSGSTREAM: - pszTagID = "PSG Stream"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_TPW: - pszTagID = "TPW"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_TA_TPC: - pszTagID = "TPC"; break; - - /* PM */ - case RGX_MH_TAG_ENCODING_MH_TAG_PM_ALLOC: - { - pszTagID = "PMA"; - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAFSTACK: pszTagSB = "TA Fstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAMLIST: pszTagSB = "TA MList"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DFSTACK: pszTagSB = "3D Fstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DMLIST: pszTagSB = "3D MList"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_PMCTX0: pszTagSB = "Context0"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_PMCTX1: pszTagSB = "Context1"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_MAVP: pszTagSB = "MAVP"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_UFSTACK: pszTagSB = "UFstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAMMUSTACK: pszTagSB = "TA MMUstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DMMUSTACK: pszTagSB = "3D MMUstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAUFSTACK: pszTagSB = "TA UFstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_3DUFSTACK: pszTagSB = "3D UFstack"; break; - case RGX_MH_TAG_SB_PMA_ENCODING_PM_TAG_PMA_TAVFP: pszTagSB = "TA VFP"; break; - } - break; - } - case RGX_MH_TAG_ENCODING_MH_TAG_PM_DEALLOC: - { - pszTagID = "PMD"; - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAFSTACK: pszTagSB = "TA Fstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAMLIST: pszTagSB = "TA MList"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DFSTACK: pszTagSB = "3D Fstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DMLIST: pszTagSB = "3D MList"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_PMCTX0: pszTagSB = "Context0"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_PMCTX1: pszTagSB = "Context1"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_UFSTACK: pszTagSB = "UFstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAMMUSTACK: pszTagSB = "TA MMUstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DMMUSTACK: pszTagSB = "3D MMUstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAUFSTACK: pszTagSB = "TA UFstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DUFSTACK: pszTagSB = "3D UFstack"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_TAVFP: pszTagSB = "TA VFP"; break; - case RGX_MH_TAG_SB_PMD_ENCODING_PM_TAG_PMD_3DVFP: pszTagSB = "3D VFP"; break; - } - break; - } - - /* TDM */ - case RGX_MH_TAG_ENCODING_MH_TAG_TDM_DMA: - { - pszTagID = "TDM DMA"; - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_CTL_STREAM: pszTagSB = "Ctl stream"; break; - case RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_CTX_BUFFER: pszTagSB = "Ctx buffer"; break; - case RGX_MH_TAG_SB_TDM_DMA_ENCODING_TDM_DMA_TAG_QUEUE_CTL: pszTagSB = "Queue ctl"; break; - } - break; - } - case RGX_MH_TAG_ENCODING_MH_TAG_TDM_CTL: - { - pszTagID = "TDM CTL"; - switch (ui32TagSB) - { - case RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_FENCE: pszTagSB = "Fence"; break; - case RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_CONTEXT: pszTagSB = "Context"; break; - case RGX_MH_TAG_SB_TDM_CTL_ENCODING_TDM_CTL_TAG_QUEUE: pszTagSB = "Queue"; break; - } - break; - } - - /* PBE */ - case RGX_MH_TAG_ENCODING_MH_TAG_PBE0: - pszTagID = "PBE0"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_PBE1: - pszTagID = "PBE1"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_PBE2: - pszTagID = "PBE2"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_PBE3: - pszTagID = "PBE3"; break; - } - - *ppszTagID = pszTagID; - *ppszTagSB = pszTagSB; -} - -/* RISC-V pf tags */ -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_MMU (0x00000001U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_IFU (0x00000002U) -#define RGX_MH_TAG_ENCODING_MH_TAG_CPU_LSU (0x00000003U) - -static void _RGXDecodeBIFReqTagsFwcore(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32TagID, - IMG_UINT32 ui32TagSB, - IMG_CHAR **ppszTagID, - IMG_CHAR **ppszTagSB) -{ - /* default to unknown */ - IMG_CHAR *pszTagID = "-"; - IMG_CHAR *pszTagSB = "-"; - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - pszTagSB = "RISC-V"; - - switch (ui32TagID) - { - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_MMU: pszTagID = "RISC-V MMU"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_IFU: pszTagID = "RISC-V Instruction Fetch Unit"; break; - case RGX_MH_TAG_ENCODING_MH_TAG_CPU_LSU: pszTagID = "RISC-V Load/Store Unit"; break; /* Or Debug Module System Bus */ - } - } - - *ppszTagID = pszTagID; - *ppszTagSB = pszTagSB; -} - -static void _RGXDecodeBIFReqTags(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXDBG_BIF_ID eBankID, - IMG_UINT32 ui32TagID, - IMG_UINT32 ui32TagSB, - IMG_CHAR **ppszTagID, - IMG_CHAR **ppszTagSB, - IMG_CHAR *pszScratchBuf, - IMG_UINT32 ui32ScratchBufSize) -{ - /* default to unknown */ - IMG_CHAR *pszTagID = "-"; - IMG_CHAR *pszTagSB = "-"; - - PVR_ASSERT(ppszTagID != NULL); - PVR_ASSERT(ppszTagSB != NULL); - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XE_MEMORY_HIERARCHY)) - { - if (eBankID == RGXDBG_FWCORE) - { - _RGXDecodeBIFReqTagsFwcore(psDevInfo, ui32TagID, ui32TagSB, ppszTagID, ppszTagSB); - } - else - { - _RGXDecodeBIFReqTagsXE(psDevInfo, ui32TagID, ui32TagSB, ppszTagID, ppszTagSB, pszScratchBuf, ui32ScratchBufSize); - } - return; - } - - switch (ui32TagID) - { - case 0x0: - { - pszTagID = "MMU"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Table"; break; - case 0x1: pszTagSB = "Directory"; break; - case 0x2: pszTagSB = "Catalogue"; break; - } - break; - } - case 0x1: - { - pszTagID = "TLA"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Pixel data"; break; - case 0x1: pszTagSB = "Command stream data"; break; - case 0x2: pszTagSB = "Fence or flush"; break; - } - break; - } - case 0x2: - { - pszTagID = "HOST"; - break; - } - case 0x3: - { - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - pszTagID = "META"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "DCache - Thread 0"; break; - case 0x1: pszTagSB = "ICache - Thread 0"; break; - case 0x2: pszTagSB = "JTag - Thread 0"; break; - case 0x3: pszTagSB = "Slave bus - Thread 0"; break; - case 0x4: pszTagSB = "DCache - Thread "; break; - case 0x5: pszTagSB = "ICache - Thread 1"; break; - case 0x6: pszTagSB = "JTag - Thread 1"; break; - case 0x7: pszTagSB = "Slave bus - Thread 1"; break; - } - } - else if (RGX_IS_ERN_SUPPORTED(psDevInfo, 57596)) - { - pszTagID="TCU"; - } - else - { - /* Unreachable code */ - PVR_ASSERT(IMG_FALSE); - } - break; - } - case 0x4: - { - pszTagID = "USC"; - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, - "Cache line %d", (ui32TagSB & 0x3f)); - pszTagSB = pszScratchBuf; - break; - } - case 0x5: - { - pszTagID = "PBE"; - break; - } - case 0x6: - { - pszTagID = "ISP"; - switch (ui32TagSB) - { - case 0x00: pszTagSB = "ZLS"; break; - case 0x20: pszTagSB = "Occlusion Query"; break; - } - break; - } - case 0x7: - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, CLUSTER_GROUPING)) - { - if (eBankID == RGXDBG_TEXAS_BIF) - { - pszTagID = "IPF"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "CPF"; break; - case 0x1: pszTagSB = "DBSC"; break; - case 0x2: - case 0x4: - case 0x6: - case 0x8: pszTagSB = "Control Stream"; break; - case 0x3: - case 0x5: - case 0x7: - case 0x9: pszTagSB = "Primitive Block"; break; - } - } - else - { - pszTagID = "IPP"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Macrotile Header"; break; - case 0x1: pszTagSB = "Region Header"; break; - } - } - } - else if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SIMPLE_INTERNAL_PARAMETER_FORMAT)) - { - pszTagID = "IPF"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Region Header"; break; - case 0x1: pszTagSB = "DBSC"; break; - case 0x2: pszTagSB = "CPF"; break; - case 0x3: pszTagSB = "Control Stream"; break; - case 0x4: pszTagSB = "Primitive Block"; break; - } - } - else - { - pszTagID = "IPF"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Macrotile Header"; break; - case 0x1: pszTagSB = "Region Header"; break; - case 0x2: pszTagSB = "DBSC"; break; - case 0x3: pszTagSB = "CPF"; break; - case 0x4: - case 0x6: - case 0x8: pszTagSB = "Control Stream"; break; - case 0x5: - case 0x7: - case 0x9: pszTagSB = "Primitive Block"; break; - } - } - break; - } - case 0x8: - { - pszTagID = "CDM"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Control Stream"; break; - case 0x1: pszTagSB = "Indirect Data"; break; - case 0x2: pszTagSB = "Event Write"; break; - case 0x3: pszTagSB = "Context State"; break; - } - break; - } - case 0x9: - { - pszTagID = "VDM"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Control Stream"; break; - case 0x1: pszTagSB = "PPP State"; break; - case 0x2: pszTagSB = "Index Data"; break; - case 0x4: pszTagSB = "Call Stack"; break; - case 0x8: pszTagSB = "Context State"; break; - } - break; - } - case 0xA: - { - pszTagID = "PM"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "PMA_TAFSTACK"; break; - case 0x1: pszTagSB = "PMA_TAMLIST"; break; - case 0x2: pszTagSB = "PMA_3DFSTACK"; break; - case 0x3: pszTagSB = "PMA_3DMLIST"; break; - case 0x4: pszTagSB = "PMA_PMCTX0"; break; - case 0x5: pszTagSB = "PMA_PMCTX1"; break; - case 0x6: pszTagSB = "PMA_MAVP"; break; - case 0x7: pszTagSB = "PMA_UFSTACK"; break; - case 0x8: pszTagSB = "PMD_TAFSTACK"; break; - case 0x9: pszTagSB = "PMD_TAMLIST"; break; - case 0xA: pszTagSB = "PMD_3DFSTACK"; break; - case 0xB: pszTagSB = "PMD_3DMLIST"; break; - case 0xC: pszTagSB = "PMD_PMCTX0"; break; - case 0xD: pszTagSB = "PMD_PMCTX1"; break; - case 0xF: pszTagSB = "PMD_UFSTACK"; break; - case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break; - case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break; - case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break; - case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break; - case 0x14: pszTagSB = "PMA_TAUFSTACK"; break; - case 0x15: pszTagSB = "PMA_3DUFSTACK"; break; - case 0x16: pszTagSB = "PMD_TAUFSTACK"; break; - case 0x17: pszTagSB = "PMD_3DUFSTACK"; break; - case 0x18: pszTagSB = "PMA_TAVFP"; break; - case 0x19: pszTagSB = "PMD_3DVFP"; break; - case 0x1A: pszTagSB = "PMD_TAVFP"; break; - } - break; - } - case 0xB: - { - pszTagID = "TA"; - switch (ui32TagSB) - { - case 0x1: pszTagSB = "VCE"; break; - case 0x2: pszTagSB = "TPC"; break; - case 0x3: pszTagSB = "TE Control Stream"; break; - case 0x4: pszTagSB = "TE Region Header"; break; - case 0x5: pszTagSB = "TE Render Target Cache"; break; - case 0x6: pszTagSB = "TEAC Render Target Cache"; break; - case 0x7: pszTagSB = "VCE Render Target Cache"; break; - case 0x8: pszTagSB = "PPP Context State"; break; - } - break; - } - case 0xC: - { - pszTagID = "TPF"; - switch (ui32TagSB) - { - case 0x0: pszTagSB = "TPF0: Primitive Block"; break; - case 0x1: pszTagSB = "TPF0: Depth Bias"; break; - case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break; - case 0x3: pszTagSB = "CPF - Tables"; break; - case 0x4: pszTagSB = "TPF1: Primitive Block"; break; - case 0x5: pszTagSB = "TPF1: Depth Bias"; break; - case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break; - case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break; - case 0x8: pszTagSB = "TPF2: Primitive Block"; break; - case 0x9: pszTagSB = "TPF2: Depth Bias"; break; - case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break; - case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break; - case 0xC: pszTagSB = "TPF3: Primitive Block"; break; - case 0xD: pszTagSB = "TPF3: Depth Bias"; break; - case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break; - case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break; - } - break; - } - case 0xD: - { - pszTagID = "PDS"; - break; - } - case 0xE: - { - pszTagID = "MCU"; - { - IMG_UINT32 ui32Burst = (ui32TagSB >> 5) & 0x7; - IMG_UINT32 ui32GroupEnc = (ui32TagSB >> 2) & 0x7; - IMG_UINT32 ui32Group = ui32TagSB & 0x3; - - IMG_CHAR* pszBurst = ""; - IMG_CHAR* pszGroupEnc = ""; - IMG_CHAR* pszGroup = ""; - - switch (ui32Burst) - { - case 0x0: - case 0x1: pszBurst = "128bit word within the Lower 256bits"; break; - case 0x2: - case 0x3: pszBurst = "128bit word within the Upper 256bits"; break; - case 0x4: pszBurst = "Lower 256bits"; break; - case 0x5: pszBurst = "Upper 256bits"; break; - case 0x6: pszBurst = "512 bits"; break; - } - switch (ui32GroupEnc) - { - case 0x0: pszGroupEnc = "TPUA_USC"; break; - case 0x1: pszGroupEnc = "TPUB_USC"; break; - case 0x2: pszGroupEnc = "USCA_USC"; break; - case 0x3: pszGroupEnc = "USCB_USC"; break; - case 0x4: pszGroupEnc = "PDS_USC"; break; - case 0x5: - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) && - 6 > RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS)) - { - pszGroupEnc = "PDSRW"; - } else if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) && - 6 == RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS)) - { - pszGroupEnc = "UPUC_USC"; - } - break; - case 0x6: - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) && - 6 == RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS)) - { - pszGroupEnc = "TPUC_USC"; - } - break; - case 0x7: - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) && - 6 == RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS)) - { - pszGroupEnc = "PDSRW"; - } - break; - } - switch (ui32Group) - { - case 0x0: pszGroup = "Banks 0-3"; break; - case 0x1: pszGroup = "Banks 4-7"; break; - case 0x2: pszGroup = "Banks 8-11"; break; - case 0x3: pszGroup = "Banks 12-15"; break; - } - - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, - "%s, %s, %s", pszBurst, pszGroupEnc, pszGroup); - pszTagSB = pszScratchBuf; - } - break; - } - case 0xF: - { - pszTagID = "FB_CDC"; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XT_TOP_INFRASTRUCTURE)) - { - IMG_UINT32 ui32Req = (ui32TagSB >> 0) & 0xf; - IMG_UINT32 ui32MCUSB = (ui32TagSB >> 4) & 0x3; - IMG_CHAR* pszReqOrig = ""; - - switch (ui32Req) - { - case 0x0: pszReqOrig = "FBC Request, originator ZLS"; break; - case 0x1: pszReqOrig = "FBC Request, originator PBE"; break; - case 0x2: pszReqOrig = "FBC Request, originator Host"; break; - case 0x3: pszReqOrig = "FBC Request, originator TLA"; break; - case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break; - case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break; - case 0x6: pszReqOrig = "FBDC Request, originator Host"; break; - case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break; - case 0x8: pszReqOrig = "FBC Request, originator ZLS Requester Fence"; break; - case 0x9: pszReqOrig = "FBC Request, originator PBE Requester Fence"; break; - case 0xa: pszReqOrig = "FBC Request, originator Host Requester Fence"; break; - case 0xb: pszReqOrig = "FBC Request, originator TLA Requester Fence"; break; - case 0xc: pszReqOrig = "Reserved"; break; - case 0xd: pszReqOrig = "Reserved"; break; - case 0xe: pszReqOrig = "FBDC Request, originator FBCDC(Host) Memory Fence"; break; - case 0xf: pszReqOrig = "FBDC Request, originator FBCDC(TLA) Memory Fence"; break; - } - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, - "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB); - pszTagSB = pszScratchBuf; - } - else - { - IMG_UINT32 ui32Req = (ui32TagSB >> 2) & 0x7; - IMG_UINT32 ui32MCUSB = (ui32TagSB >> 0) & 0x3; - IMG_CHAR* pszReqOrig = ""; - - switch (ui32Req) - { - case 0x0: pszReqOrig = "FBC Request, originator ZLS"; break; - case 0x1: pszReqOrig = "FBC Request, originator PBE"; break; - case 0x2: pszReqOrig = "FBC Request, originator Host"; break; - case 0x3: pszReqOrig = "FBC Request, originator TLA"; break; - case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break; - case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break; - case 0x6: pszReqOrig = "FBDC Request, originator Host"; break; - case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break; - } - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, - "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB); - pszTagSB = pszScratchBuf; - } - break; - } - } /* switch (TagID) */ - - *ppszTagID = pszTagID; - *ppszTagSB = pszTagSB; -} - - - -/*! -******************************************************************************* - - @Function _RGXDecodeMMULevel - - @Description - - Return the name for the MMU level that faulted. - - @Input ui32MMULevel - MMU level - - @Return IMG_CHAR* to the sting describing the MMU level that faulted. - -******************************************************************************/ -static const IMG_CHAR* _RGXDecodeMMULevel(IMG_UINT32 ui32MMULevel) -{ - const IMG_CHAR* pszMMULevel = ""; - - switch (ui32MMULevel) - { - case 0x0: pszMMULevel = " (Page Table)"; break; - case 0x1: pszMMULevel = " (Page Directory)"; break; - case 0x2: pszMMULevel = " (Page Catalog)"; break; - case 0x3: pszMMULevel = " (Cat Base Reg)"; break; - } - - return pszMMULevel; -} - - -/*! -******************************************************************************* - - @Function _RGXDecodeMMUReqTags - - @Description - - Decodes the MMU Tag ID and Sideband data fields from RGX_CR_MMU_FAULT_META_STATUS and - RGX_CR_MMU_FAULT_STATUS regs. - - @Input ui32TagID - Tag ID value - @Input ui32TagSB - Tag Sideband data - @Input bRead - Read flag - @Output ppszTagID - Decoded string from the Tag ID - @Output ppszTagSB - Decoded string from the Tag SB - @Output pszScratchBuf - Buffer provided to the function to generate the debug strings - @Input ui32ScratchBufSize - Size of the provided buffer - - @Return void - -******************************************************************************/ -static void _RGXDecodeMMUReqTags(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32TagID, - IMG_UINT32 ui32TagSB, - IMG_BOOL bRead, - IMG_CHAR **ppszTagID, - IMG_CHAR **ppszTagSB, - IMG_CHAR *pszScratchBuf, - IMG_UINT32 ui32ScratchBufSize) -{ - IMG_INT32 i32SideBandType = -1; - IMG_CHAR *pszTagID = "-"; - IMG_CHAR *pszTagSB = "-"; - - PVR_ASSERT(ppszTagID != NULL); - PVR_ASSERT(ppszTagSB != NULL); - - - switch (ui32TagID) - { - case 0: pszTagID = "META (Jones)"; i32SideBandType = RGXDBG_META; break; - case 1: pszTagID = "TLA (Jones)"; i32SideBandType = RGXDBG_TLA; break; - case 2: pszTagID = "DMA (Jones)"; i32SideBandType = RGXDBG_DMA; break; - case 3: pszTagID = "VDMM (Jones)"; i32SideBandType = RGXDBG_VDMM; break; - case 4: pszTagID = "CDM (Jones)"; i32SideBandType = RGXDBG_CDM; break; - case 5: pszTagID = "IPP (Jones)"; i32SideBandType = RGXDBG_IPP; break; - case 6: pszTagID = "PM (Jones)"; i32SideBandType = RGXDBG_PM; break; - case 7: pszTagID = "Tiling (Jones)"; i32SideBandType = RGXDBG_TILING; break; - case 8: pszTagID = "MCU (Texas 0)"; i32SideBandType = RGXDBG_MCU; break; - case 12: pszTagID = "VDMS (Black Pearl 0)"; i32SideBandType = RGXDBG_VDMS; break; - case 13: pszTagID = "IPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF; break; - case 14: pszTagID = "ISP (Black Pearl 0)"; i32SideBandType = RGXDBG_ISP; break; - case 15: pszTagID = "TPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF; break; - case 16: pszTagID = "USCS (Black Pearl 0)"; i32SideBandType = RGXDBG_USCS; break; - case 17: pszTagID = "PPP (Black Pearl 0)"; i32SideBandType = RGXDBG_PPP; break; - case 20: pszTagID = "MCU (Texas 1)"; i32SideBandType = RGXDBG_MCU; break; - case 24: pszTagID = "MCU (Texas 2)"; i32SideBandType = RGXDBG_MCU; break; - case 28: pszTagID = "VDMS (Black Pearl 1)"; i32SideBandType = RGXDBG_VDMS; break; - case 29: pszTagID = "IPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF; break; - case 30: pszTagID = "ISP (Black Pearl 1)"; i32SideBandType = RGXDBG_ISP; break; - case 31: pszTagID = "TPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF; break; - case 32: pszTagID = "USCS (Black Pearl 1)"; i32SideBandType = RGXDBG_USCS; break; - case 33: pszTagID = "PPP (Black Pearl 1)"; i32SideBandType = RGXDBG_PPP; break; - case 36: pszTagID = "MCU (Texas 3)"; i32SideBandType = RGXDBG_MCU; break; - case 40: pszTagID = "MCU (Texas 4)"; i32SideBandType = RGXDBG_MCU; break; - case 44: pszTagID = "VDMS (Black Pearl 2)"; i32SideBandType = RGXDBG_VDMS; break; - case 45: pszTagID = "IPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF; break; - case 46: pszTagID = "ISP (Black Pearl 2)"; i32SideBandType = RGXDBG_ISP; break; - case 47: pszTagID = "TPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF; break; - case 48: pszTagID = "USCS (Black Pearl 2)"; i32SideBandType = RGXDBG_USCS; break; - case 49: pszTagID = "PPP (Black Pearl 2)"; i32SideBandType = RGXDBG_PPP; break; - case 52: pszTagID = "MCU (Texas 5)"; i32SideBandType = RGXDBG_MCU; break; - case 56: pszTagID = "MCU (Texas 6)"; i32SideBandType = RGXDBG_MCU; break; - case 60: pszTagID = "VDMS (Black Pearl 3)"; i32SideBandType = RGXDBG_VDMS; break; - case 61: pszTagID = "IPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF; break; - case 62: pszTagID = "ISP (Black Pearl 3)"; i32SideBandType = RGXDBG_ISP; break; - case 63: pszTagID = "TPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF; break; - case 64: pszTagID = "USCS (Black Pearl 3)"; i32SideBandType = RGXDBG_USCS; break; - case 65: pszTagID = "PPP (Black Pearl 3)"; i32SideBandType = RGXDBG_PPP; break; - case 68: pszTagID = "MCU (Texas 7)"; i32SideBandType = RGXDBG_MCU; break; - } - if (('-' == pszTagID[0]) && '\n' == pszTagID[1]) - { - - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 50539) || - (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, FBCDC_ARCHITECTURE) && RGX_GET_FEATURE_VALUE(psDevInfo, FBCDC_ARCHITECTURE) >= 3)) - { - switch (ui32TagID) - { - case 18: pszTagID = "TPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF_CPF; break; - case 19: pszTagID = "IPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF_CPF; break; - case 34: pszTagID = "TPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF_CPF; break; - case 35: pszTagID = "IPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF_CPF; break; - case 50: pszTagID = "TPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF_CPF; break; - case 51: pszTagID = "IPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF_CPF; break; - case 66: pszTagID = "TPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF_CPF; break; - case 67: pszTagID = "IPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF_CPF; break; - } - - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 50539)) - { - switch (ui32TagID) - { - case 9: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE; break; - case 10: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break; - case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break; - case 21: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE; break; - case 22: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break; - case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break; - case 25: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE; break; - case 26: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break; - case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break; - case 37: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE; break; - case 38: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break; - case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break; - case 41: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE; break; - case 42: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break; - case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break; - case 53: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE; break; - case 54: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break; - case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break; - case 57: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE; break; - case 58: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break; - case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break; - case 69: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE; break; - case 70: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break; - case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break; - } - }else - { - switch (ui32TagID) - { - case 9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break; - case 10: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE; break; - case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break; - case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break; - case 22: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE; break; - case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break; - case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break; - case 26: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE; break; - case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break; - case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break; - case 38: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE; break; - case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break; - case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break; - case 42: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE; break; - case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break; - case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break; - case 54: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE; break; - case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break; - case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break; - case 58: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE; break; - case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break; - case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break; - case 70: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE; break; - case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break; - } - } - }else - { - switch (ui32TagID) - { - case 9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break; - case 10: pszTagID = "PBE0 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break; - case 11: pszTagID = "PBE1 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break; - case 18: pszTagID = "VCE (Black Pearl 0)"; i32SideBandType = RGXDBG_VCE; break; - case 19: pszTagID = "FBCDC (Black Pearl 0)"; i32SideBandType = RGXDBG_FBCDC; break; - case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break; - case 22: pszTagID = "PBE0 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break; - case 23: pszTagID = "PBE1 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break; - case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break; - case 26: pszTagID = "PBE0 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break; - case 27: pszTagID = "PBE1 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break; - case 34: pszTagID = "VCE (Black Pearl 1)"; i32SideBandType = RGXDBG_VCE; break; - case 35: pszTagID = "FBCDC (Black Pearl 1)"; i32SideBandType = RGXDBG_FBCDC; break; - case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break; - case 38: pszTagID = "PBE0 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break; - case 39: pszTagID = "PBE1 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break; - case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break; - case 42: pszTagID = "PBE0 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break; - case 43: pszTagID = "PBE1 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break; - case 50: pszTagID = "VCE (Black Pearl 2)"; i32SideBandType = RGXDBG_VCE; break; - case 51: pszTagID = "FBCDC (Black Pearl 2)"; i32SideBandType = RGXDBG_FBCDC; break; - case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break; - case 54: pszTagID = "PBE0 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break; - case 55: pszTagID = "PBE1 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break; - case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break; - case 58: pszTagID = "PBE0 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break; - case 59: pszTagID = "PBE1 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break; - case 66: pszTagID = "VCE (Black Pearl 3)"; i32SideBandType = RGXDBG_VCE; break; - case 67: pszTagID = "FBCDC (Black Pearl 3)"; i32SideBandType = RGXDBG_FBCDC; break; - case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break; - case 70: pszTagID = "PBE0 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break; - case 71: pszTagID = "PBE1 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break; - } - } - - } - - switch (i32SideBandType) - { - case RGXDBG_META: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "DCache - Thread 0"; break; - case 0x1: pszTagSB = "ICache - Thread 0"; break; - case 0x2: pszTagSB = "JTag - Thread 0"; break; - case 0x3: pszTagSB = "Slave bus - Thread 0"; break; - case 0x4: pszTagSB = "DCache - Thread 1"; break; - case 0x5: pszTagSB = "ICache - Thread 1"; break; - case 0x6: pszTagSB = "JTag - Thread 1"; break; - case 0x7: pszTagSB = "Slave bus - Thread 1"; break; - } - break; - } - - case RGXDBG_TLA: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Pixel data"; break; - case 0x1: pszTagSB = "Command stream data"; break; - case 0x2: pszTagSB = "Fence or flush"; break; - } - break; - } - - case RGXDBG_VDMM: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Control Stream - Read Only"; break; - case 0x1: pszTagSB = "PPP State - Read Only"; break; - case 0x2: pszTagSB = "Indices - Read Only"; break; - case 0x4: pszTagSB = "Call Stack - Read/Write"; break; - case 0x6: pszTagSB = "DrawIndirect - Read Only"; break; - case 0xA: pszTagSB = "Context State - Write Only"; break; - } - break; - } - - case RGXDBG_CDM: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Control Stream"; break; - case 0x1: pszTagSB = "Indirect Data"; break; - case 0x2: pszTagSB = "Event Write"; break; - case 0x3: pszTagSB = "Context State"; break; - } - break; - } - - case RGXDBG_IPP: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Macrotile Header"; break; - case 0x1: pszTagSB = "Region Header"; break; - } - break; - } - - case RGXDBG_PM: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "PMA_TAFSTACK"; break; - case 0x1: pszTagSB = "PMA_TAMLIST"; break; - case 0x2: pszTagSB = "PMA_3DFSTACK"; break; - case 0x3: pszTagSB = "PMA_3DMLIST"; break; - case 0x4: pszTagSB = "PMA_PMCTX0"; break; - case 0x5: pszTagSB = "PMA_PMCTX1"; break; - case 0x6: pszTagSB = "PMA_MAVP"; break; - case 0x7: pszTagSB = "PMA_UFSTACK"; break; - case 0x8: pszTagSB = "PMD_TAFSTACK"; break; - case 0x9: pszTagSB = "PMD_TAMLIST"; break; - case 0xA: pszTagSB = "PMD_3DFSTACK"; break; - case 0xB: pszTagSB = "PMD_3DMLIST"; break; - case 0xC: pszTagSB = "PMD_PMCTX0"; break; - case 0xD: pszTagSB = "PMD_PMCTX1"; break; - case 0xF: pszTagSB = "PMD_UFSTACK"; break; - case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break; - case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break; - case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break; - case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break; - case 0x14: pszTagSB = "PMA_TAUFSTACK"; break; - case 0x15: pszTagSB = "PMA_3DUFSTACK"; break; - case 0x16: pszTagSB = "PMD_TAUFSTACK"; break; - case 0x17: pszTagSB = "PMD_3DUFSTACK"; break; - case 0x18: pszTagSB = "PMA_TAVFP"; break; - case 0x19: pszTagSB = "PMD_3DVFP"; break; - case 0x1A: pszTagSB = "PMD_TAVFP"; break; - } - break; - } - - case RGXDBG_TILING: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "PSG Control Stream TP0"; break; - case 0x1: pszTagSB = "TPC TP0"; break; - case 0x2: pszTagSB = "VCE0"; break; - case 0x3: pszTagSB = "VCE1"; break; - case 0x4: pszTagSB = "PSG Control Stream TP1"; break; - case 0x5: pszTagSB = "TPC TP1"; break; - case 0x8: pszTagSB = "PSG Region Header TP0"; break; - case 0xC: pszTagSB = "PSG Region Header TP1"; break; - } - break; - } - - case RGXDBG_VDMS: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "Context State - Write Only"; break; - } - break; - } - - case RGXDBG_IPF: - { - switch (ui32TagSB) - { - case 0x00: - case 0x20: pszTagSB = "CPF"; break; - case 0x01: pszTagSB = "DBSC"; break; - case 0x02: - case 0x04: - case 0x06: - case 0x08: - case 0x0A: - case 0x0C: - case 0x0E: - case 0x10: pszTagSB = "Control Stream"; break; - case 0x03: - case 0x05: - case 0x07: - case 0x09: - case 0x0B: - case 0x0D: - case 0x0F: - case 0x11: pszTagSB = "Primitive Block"; break; - } - break; - } - - case RGXDBG_ISP: - { - switch (ui32TagSB) - { - case 0x00: pszTagSB = "ZLS read/write"; break; - case 0x20: pszTagSB = "Occlusion query read/write"; break; - } - break; - } - - case RGXDBG_TPF: - { - switch (ui32TagSB) - { - case 0x0: pszTagSB = "TPF0: Primitive Block"; break; - case 0x1: pszTagSB = "TPF0: Depth Bias"; break; - case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break; - case 0x3: pszTagSB = "CPF - Tables"; break; - case 0x4: pszTagSB = "TPF1: Primitive Block"; break; - case 0x5: pszTagSB = "TPF1: Depth Bias"; break; - case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break; - case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break; - case 0x8: pszTagSB = "TPF2: Primitive Block"; break; - case 0x9: pszTagSB = "TPF2: Depth Bias"; break; - case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break; - case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break; - case 0xC: pszTagSB = "TPF3: Primitive Block"; break; - case 0xD: pszTagSB = "TPF3: Depth Bias"; break; - case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break; - case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break; - } - break; - } - - case RGXDBG_FBCDC: - { - /* - * FBC faults on a 4-cluster phantom does not always set SB - * bit 5, but since FBC is write-only and FBDC is read-only, - * we can set bit 5 if this is a write fault, before decoding. - */ - if (bRead == IMG_FALSE) - { - ui32TagSB |= 0x20; - } - - switch (ui32TagSB) - { - case 0x00: pszTagSB = "FBDC Request, originator ZLS"; break; - case 0x02: pszTagSB = "FBDC Request, originator MCU Dust 0"; break; - case 0x03: pszTagSB = "FBDC Request, originator MCU Dust 1"; break; - case 0x20: pszTagSB = "FBC Request, originator ZLS"; break; - case 0x22: pszTagSB = "FBC Request, originator PBE Dust 0, Cluster 0"; break; - case 0x23: pszTagSB = "FBC Request, originator PBE Dust 0, Cluster 1"; break; - case 0x24: pszTagSB = "FBC Request, originator PBE Dust 1, Cluster 0"; break; - case 0x25: pszTagSB = "FBC Request, originator PBE Dust 1, Cluster 1"; break; - case 0x28: pszTagSB = "FBC Request, originator ZLS Fence"; break; - case 0x2a: pszTagSB = "FBC Request, originator PBE Dust 0, Cluster 0, Fence"; break; - case 0x2b: pszTagSB = "FBC Request, originator PBE Dust 0, Cluster 1, Fence"; break; - case 0x2c: pszTagSB = "FBC Request, originator PBE Dust 1, Cluster 0, Fence"; break; - case 0x2d: pszTagSB = "FBC Request, originator PBE Dust 1, Cluster 1, Fence"; break; - } - break; - } - - case RGXDBG_MCU: - { - IMG_UINT32 ui32SetNumber = (ui32TagSB >> 5) & 0x7; - IMG_UINT32 ui32WayNumber = (ui32TagSB >> 2) & 0x7; - IMG_UINT32 ui32Group = ui32TagSB & 0x3; - - IMG_CHAR* pszGroup = ""; - - switch (ui32Group) - { - case 0x0: pszGroup = "Banks 0-1"; break; - case 0x1: pszGroup = "Banks 2-3"; break; - case 0x2: pszGroup = "Banks 4-5"; break; - case 0x3: pszGroup = "Banks 6-7"; break; - } - - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, - "Set=%d, Way=%d, %s", ui32SetNumber, ui32WayNumber, pszGroup); - pszTagSB = pszScratchBuf; - break; - } - - default: - { - OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, "SB=0x%02x", ui32TagSB); - pszTagSB = pszScratchBuf; - break; - } - } - - *ppszTagID = pszTagID; - *ppszTagSB = pszTagSB; -} - - -static void ConvertOSTimestampToSAndNS(IMG_UINT64 ui64OSTimer, - IMG_UINT64 *pui64Seconds, - IMG_UINT64 *pui64Nanoseconds) -{ - IMG_UINT32 ui32Remainder; - - *pui64Seconds = OSDivide64r64(ui64OSTimer, 1000000000, &ui32Remainder); - *pui64Nanoseconds = ui64OSTimer - (*pui64Seconds * 1000000000ULL); -} - - -typedef enum _DEVICEMEM_HISTORY_QUERY_INDEX_ -{ - DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING, - DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED, - DEVICEMEM_HISTORY_QUERY_INDEX_NEXT, - DEVICEMEM_HISTORY_QUERY_INDEX_COUNT, -} DEVICEMEM_HISTORY_QUERY_INDEX; - - -/*! -******************************************************************************* - - @Function _PrintDevicememHistoryQueryResult - - @Description - - Print details of a single result from a DevicememHistory query - - @Input pfnDumpDebugPrintf - Debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psFaultProcessInfo - The process info derived from the page fault - @Input psResult - The DevicememHistory result to be printed - @Input ui32Index - The index of the result - - @Return void - -******************************************************************************/ -static void _PrintDevicememHistoryQueryResult(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - RGXMEM_PROCESS_INFO *psFaultProcessInfo, - DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult, - IMG_UINT32 ui32Index, - const IMG_CHAR* pszIndent) -{ - IMG_UINT32 ui32Remainder; - IMG_UINT64 ui64Seconds, ui64Nanoseconds; - - ConvertOSTimestampToSAndNS(psResult->ui64When, - &ui64Seconds, - &ui64Nanoseconds); - - if (psFaultProcessInfo->uiPID != RGXMEM_SERVER_PID_FIRMWARE) - { - PVR_DUMPDEBUG_LOG("%s [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC - " Size: " IMG_DEVMEM_SIZE_FMTSPEC - " Operation: %s Modified: %" IMG_UINT64_FMTSPEC - " us ago (OS time %" IMG_UINT64_FMTSPEC - ".%09" IMG_UINT64_FMTSPEC " s)", - pszIndent, - ui32Index, - psResult->szString, - psResult->sBaseDevVAddr.uiAddr, - psResult->uiSize, - psResult->bMap ? "Map": "Unmap", - OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder), - ui64Seconds, - ui64Nanoseconds); - } - else - { - PVR_DUMPDEBUG_LOG("%s [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC - " Size: " IMG_DEVMEM_SIZE_FMTSPEC - " Operation: %s Modified: %" IMG_UINT64_FMTSPEC - " us ago (OS time %" IMG_UINT64_FMTSPEC - ".%09" IMG_UINT64_FMTSPEC - ") PID: %u (%s)", - pszIndent, - ui32Index, - psResult->szString, - psResult->sBaseDevVAddr.uiAddr, - psResult->uiSize, - psResult->bMap ? "Map": "Unmap", - OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder), - ui64Seconds, - ui64Nanoseconds, - psResult->sProcessInfo.uiPID, - psResult->sProcessInfo.szProcessName); - } - - if (!psResult->bRange) - { - PVR_DUMPDEBUG_LOG("%s Whole allocation was %s", pszIndent, psResult->bMap ? "mapped": "unmapped"); - } - else - { - PVR_DUMPDEBUG_LOG("%s Pages %u to %u (" IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC ") %s%s", - pszIndent, - psResult->ui32StartPage, - psResult->ui32StartPage + psResult->ui32PageCount - 1, - psResult->sMapStartAddr.uiAddr, - psResult->sMapEndAddr.uiAddr, - psResult->bAll ? "(whole allocation) " : "", - psResult->bMap ? "mapped": "unmapped"); - } -} - -/*! -******************************************************************************* - - @Function _PrintDevicememHistoryQueryOut - - @Description - - Print details of all the results from a DevicememHistory query - - @Input pfnDumpDebugPrintf - Debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psFaultProcessInfo - The process info derived from the page fault - @Input psQueryOut - Storage for the query results - - @Return void - -******************************************************************************/ -static void _PrintDevicememHistoryQueryOut(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - RGXMEM_PROCESS_INFO *psFaultProcessInfo, - DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut, - const IMG_CHAR* pszIndent) -{ - IMG_UINT32 i; - - if (psQueryOut->ui32NumResults == 0) - { - PVR_DUMPDEBUG_LOG("%s No results", pszIndent); - } - else - { - for (i = 0; i < psQueryOut->ui32NumResults; i++) - { - _PrintDevicememHistoryQueryResult(pfnDumpDebugPrintf, pvDumpDebugFile, - psFaultProcessInfo, - &psQueryOut->sResults[i], - i, - pszIndent); - } - } -} - -/* table of HW page size values and the equivalent */ -static const unsigned int aui32HWPageSizeTable[][2] = -{ - { 0, PVRSRV_4K_PAGE_SIZE }, - { 1, PVRSRV_16K_PAGE_SIZE }, - { 2, PVRSRV_64K_PAGE_SIZE }, - { 3, PVRSRV_256K_PAGE_SIZE }, - { 4, PVRSRV_1M_PAGE_SIZE }, - { 5, PVRSRV_2M_PAGE_SIZE } -}; - -/*! -******************************************************************************* - - @Function _PageSizeHWToBytes - - @Description - - Convert a HW page size value to its size in bytes - - @Input ui32PageSizeHW - The HW page size value - - @Return IMG_UINT32 The page size in bytes - -******************************************************************************/ -static IMG_UINT32 _PageSizeHWToBytes(IMG_UINT32 ui32PageSizeHW) -{ - if (ui32PageSizeHW > 5) - { - /* This is invalid, so return a default value as we cannot ASSERT in this code! */ - return PVRSRV_4K_PAGE_SIZE; - } - - return aui32HWPageSizeTable[ui32PageSizeHW][1]; -} - -/*! -******************************************************************************* - - @Function _GetDevicememHistoryData - - @Description - - Get the DevicememHistory results for the given PID and faulting device virtual address. - The function will query DevicememHistory for information about the faulting page, as well - as the page before and after. - - @Input uiPID - The process ID to search for allocations belonging to - @Input sFaultDevVAddr - The device address to search for allocations at/before/after - @Input asQueryOut - Storage for the query results - @Input ui32PageSizeBytes - Faulted page size in bytes - - @Return IMG_BOOL - IMG_TRUE if any results were found for this page fault - -******************************************************************************/ -static IMG_BOOL _GetDevicememHistoryData(IMG_PID uiPID, IMG_DEV_VIRTADDR sFaultDevVAddr, - DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT], - IMG_UINT32 ui32PageSizeBytes) -{ - DEVICEMEM_HISTORY_QUERY_IN sQueryIn; - IMG_BOOL bAnyHits = IMG_FALSE; - - /* if the page fault originated in the firmware then the allocation may - * appear to belong to any PID, because FW allocations are attributed - * to the client process creating the allocation, so instruct the - * devicemem_history query to search all available PIDs - */ - if (uiPID == RGXMEM_SERVER_PID_FIRMWARE) - { - sQueryIn.uiPID = DEVICEMEM_HISTORY_PID_ANY; - } - else - { - sQueryIn.uiPID = uiPID; - } - - /* Query the DevicememHistory for all allocations in the previous page... */ - sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) - ui32PageSizeBytes; - if (DevicememHistoryQuery(&sQueryIn, &asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING], - ui32PageSizeBytes, IMG_TRUE)) - { - bAnyHits = IMG_TRUE; - } - - /* Query the DevicememHistory for any record at the exact address... */ - sQueryIn.sDevVAddr = sFaultDevVAddr; - if (DevicememHistoryQuery(&sQueryIn, &asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED], - ui32PageSizeBytes, IMG_FALSE)) - { - bAnyHits = IMG_TRUE; - } - else - { - /* If not matched then try matching any record in the faulting page... */ - if (DevicememHistoryQuery(&sQueryIn, &asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED], - ui32PageSizeBytes, IMG_TRUE)) - { - bAnyHits = IMG_TRUE; - } - } - - /* Query the DevicememHistory for all allocations in the next page... */ - sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) + ui32PageSizeBytes; - if (DevicememHistoryQuery(&sQueryIn, &asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_NEXT], - ui32PageSizeBytes, IMG_TRUE)) - { - bAnyHits = IMG_TRUE; - } - - return bAnyHits; -} - -/* stored data about one page fault */ -typedef struct _FAULT_INFO_ -{ - /* the process info of the memory context that page faulted */ - RGXMEM_PROCESS_INFO sProcessInfo; - IMG_DEV_VIRTADDR sFaultDevVAddr; - MMU_FAULT_DATA sMMUFaultData; - DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT]; - /* the CR timer value at the time of the fault, recorded by the FW. - * used to differentiate different page faults - */ - IMG_UINT64 ui64CRTimer; - /* time when this FAULT_INFO entry was added. used for timing - * reference against the map/unmap information - */ - IMG_UINT64 ui64When; - IMG_UINT32 ui32FaultInfoFlags; -} FAULT_INFO; - -/* history list of page faults. - * Keeps the first `n` page faults and the last `n` page faults, like the FW - * HWR log - */ -typedef struct _FAULT_INFO_LOG_ -{ - IMG_UINT32 ui32Head; - /* the number of faults in this log need not correspond exactly to - * the HWINFO number of the FW, as the FW HWINFO log may contain - * non-page fault HWRs - */ - FAULT_INFO asFaults[RGXFWIF_HWINFO_MAX]; -} FAULT_INFO_LOG; - -#define FAULT_INFO_PROC_INFO (0x1U) -#define FAULT_INFO_DEVMEM_HIST (0x2U) - -static FAULT_INFO_LOG gsFaultInfoLog = { 0 }; - -static void _FillAppForFWFaults(PVRSRV_RGXDEV_INFO *psDevInfo, - FAULT_INFO *psInfo, - RGXMEM_PROCESS_INFO *psProcInfo) -{ - IMG_UINT32 i, j; - - for (i = 0; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++) - { - for (j = 0; j < DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS; j++) - { - IMG_BOOL bFound; - - RGXMEM_PROCESS_INFO *psProcInfo = &psInfo->asQueryOut[i].sResults[j].sProcessInfo; - bFound = RGXPCPIDToProcessInfo(psDevInfo, - psProcInfo->uiPID, - psProcInfo); - if (!bFound) - { - OSStringLCopy(psProcInfo->szProcessName, - "(unknown)", - sizeof(psProcInfo->szProcessName)); - } - } - } -} - -/*! -******************************************************************************* - - @Function _PrintFaultInfo - - @Description - - Print all the details of a page fault from a FAULT_INFO structure - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psInfo - The page fault occurrence to print - - @Return void - -******************************************************************************/ -static void _PrintFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - FAULT_INFO *psInfo, - const IMG_CHAR* pszIndent) -{ - IMG_UINT32 i; - IMG_UINT64 ui64Seconds, ui64Nanoseconds; - - ConvertOSTimestampToSAndNS(psInfo->ui64When, &ui64Seconds, &ui64Nanoseconds); - - if (BITMASK_HAS(psInfo->ui32FaultInfoFlags, FAULT_INFO_PROC_INFO)) - { - IMG_PID uiPID = (psInfo->sProcessInfo.uiPID == RGXMEM_SERVER_PID_FIRMWARE || psInfo->sProcessInfo.uiPID == RGXMEM_SERVER_PID_PM) ? - 0 : psInfo->sProcessInfo.uiPID; - - PVR_DUMPDEBUG_LOG("%sDevice memory history for page fault address " IMG_DEV_VIRTADDR_FMTSPEC - ", PID: %u " - "(%s, unregistered: %u) OS time: " - "%" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC, - pszIndent, - psInfo->sFaultDevVAddr.uiAddr, - uiPID, - psInfo->sProcessInfo.szProcessName, - psInfo->sProcessInfo.bUnregistered, - ui64Seconds, - ui64Nanoseconds); - } - else - { - PVR_DUMPDEBUG_LOG("%sCould not find PID for device memory history on PC of the fault", pszIndent); - } - - if (BITMASK_HAS(psInfo->ui32FaultInfoFlags, FAULT_INFO_DEVMEM_HIST)) - { - for (i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++) - { - const IMG_CHAR *pszWhich = NULL; - - switch (i) - { - case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING: - pszWhich = "Preceding page"; - break; - case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED: - pszWhich = "Faulted page"; - break; - case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT: - pszWhich = "Next page"; - break; - } - - PVR_DUMPDEBUG_LOG("%s %s:", pszIndent, pszWhich); - _PrintDevicememHistoryQueryOut(pfnDumpDebugPrintf, pvDumpDebugFile, - &psInfo->sProcessInfo, - &psInfo->asQueryOut[i], - pszIndent); - } - } - else - { - PVR_DUMPDEBUG_LOG("%s No matching Devmem History for fault address", pszIndent); - } -} - -static void _RecordFaultInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - FAULT_INFO *psInfo, - IMG_DEV_VIRTADDR sFaultDevVAddr, - IMG_DEV_PHYADDR sPCDevPAddr, - IMG_UINT64 ui64CRTimer, - IMG_UINT32 ui32PageSizeBytes) -{ - IMG_BOOL bFound = IMG_FALSE, bIsPMFault = IMG_FALSE; - RGXMEM_PROCESS_INFO sProcessInfo; - - psInfo->ui32FaultInfoFlags = 0; - psInfo->sFaultDevVAddr = sFaultDevVAddr; - psInfo->ui64CRTimer = ui64CRTimer; - psInfo->ui64When = OSClockns64(); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - /* Check if this is PM fault */ - if (psInfo->sMMUFaultData.eType == MMU_FAULT_TYPE_PM) - { - bIsPMFault = IMG_TRUE; - bFound = IMG_TRUE; - sProcessInfo.uiPID = RGXMEM_SERVER_PID_PM; - OSStringLCopy(sProcessInfo.szProcessName, "PM", sizeof(sProcessInfo.szProcessName)); - sProcessInfo.szProcessName[sizeof(sProcessInfo.szProcessName) - 1] = '\0'; - sProcessInfo.bUnregistered = IMG_FALSE; - } - else - { - /* look up the process details for the faulting page catalogue */ - bFound = RGXPCAddrToProcessInfo(psDevInfo, sPCDevPAddr, &sProcessInfo); - } - - if (bFound) - { - IMG_BOOL bHits; - - psInfo->ui32FaultInfoFlags = FAULT_INFO_PROC_INFO; - psInfo->sProcessInfo = sProcessInfo; - - if (bIsPMFault) - { - bHits = IMG_TRUE; - } - else - { - /* get any DevicememHistory data for the faulting address */ - bHits = _GetDevicememHistoryData(sProcessInfo.uiPID, - sFaultDevVAddr, - psInfo->asQueryOut, - ui32PageSizeBytes); - - if (bHits) - { - psInfo->ui32FaultInfoFlags |= FAULT_INFO_DEVMEM_HIST; - - /* if the page fault was caused by the firmware then get information about - * which client application created the related allocations. - * - * Fill in the process info data for each query result. - */ - - if (sProcessInfo.uiPID == RGXMEM_SERVER_PID_FIRMWARE) - { - _FillAppForFWFaults(psDevInfo, psInfo, &sProcessInfo); - } - } - } - } - } -} - -/*! -******************************************************************************* - - @Function _DumpFaultAddressHostView - - @Description - - Dump FW HWR fault status in human readable form. - - @Input ui32Index - Index of global Fault info - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Return void - -******************************************************************************/ -static void _DumpFaultAddressHostView(MMU_FAULT_DATA *psFaultData, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const IMG_CHAR* pszIndent) -{ - MMU_LEVEL eTopLevel; - const IMG_CHAR szPageLevel[][4] = {"", "PTE", "PDE", "PCE" }; - const IMG_CHAR szPageError[][3] = {"", "PT", "PD", "PC" }; - - eTopLevel = psFaultData->eTopLevel; - - if (psFaultData->eType == MMU_FAULT_TYPE_UNKNOWN) - { - PVR_DUMPDEBUG_LOG("%sNo live host MMU data available", pszIndent); - return; - } - else if (psFaultData->eType == MMU_FAULT_TYPE_PM) - { - PVR_DUMPDEBUG_LOG("%sPM faulted at PC address = 0x%016" IMG_UINT64_FMTSPECx, pszIndent, psFaultData->sLevelData[MMU_LEVEL_0].ui64Address); - } - else - { - MMU_LEVEL eCurrLevel; - PVR_ASSERT(eTopLevel < MMU_LEVEL_LAST); - - for (eCurrLevel = eTopLevel; eCurrLevel > MMU_LEVEL_0; eCurrLevel--) - { - MMU_LEVEL_DATA *psMMULevelData = &psFaultData->sLevelData[eCurrLevel]; - if (psMMULevelData->ui64Address) - { - if (psMMULevelData->uiBytesPerEntry == 4) - { - PVR_DUMPDEBUG_LOG("%s%s for index %d = 0x%08x and is %s", - pszIndent, - szPageLevel[eCurrLevel], - psMMULevelData->ui32Index, - (IMG_UINT) psMMULevelData->ui64Address, - psMMULevelData->psDebugStr); - } - else - { - PVR_DUMPDEBUG_LOG("%s%s for index %d = 0x%016" IMG_UINT64_FMTSPECx " and is %s", - pszIndent, - szPageLevel[eCurrLevel], - psMMULevelData->ui32Index, - psMMULevelData->ui64Address, - psMMULevelData->psDebugStr); - } - } - else - { - PVR_DUMPDEBUG_LOG("%s%s index (%d) out of bounds (%d)", - pszIndent, - szPageError[eCurrLevel], - psMMULevelData->ui32Index, - psMMULevelData->ui32NumOfEntries); - break; - } - } - } - -} - -/*! -******************************************************************************* - - @Function _RGXDumpRGXBIFBank - - @Description - - Dump BIF Bank state in human readable form. - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - @Input eBankID - BIF identifier - @Input ui64MMUStatus - MMU Status register value - @Input ui64ReqStatus - BIF request Status register value - @Return void - -******************************************************************************/ -static void _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - RGXDBG_BIF_ID eBankID, - IMG_UINT64 ui64MMUStatus, - IMG_UINT64 ui64ReqStatus, - const IMG_CHAR *pszIndent) -{ - if (ui64MMUStatus == 0x0) - { - PVR_DUMPDEBUG_LOG("%s - OK", pszBIFNames[eBankID]); - } - else - { - IMG_UINT32 ui32PageSize; - IMG_UINT32 ui32PC = - (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT; - - /* Bank 0 & 1 share the same fields */ - PVR_DUMPDEBUG_LOG("%s%s - FAULT:", - pszIndent, - pszBIFNames[eBankID]); - - /* MMU Status */ - { - IMG_UINT32 ui32MMUDataType = - (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT; - - IMG_BOOL bROFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN) != 0; - IMG_BOOL bProtFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN) != 0; - - ui32PageSize = (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT; - - PVR_DUMPDEBUG_LOG("%s * MMU status (0x%016" IMG_UINT64_FMTSPECx "): PC = %d%s, Page Size = %d%s%s%s.", - pszIndent, - ui64MMUStatus, - ui32PC, - (ui32PC < 0x8)?"":_RGXDecodePMPC(ui32PC), - ui32PageSize, - (bROFault)?", Read Only fault":"", - (bProtFault)?", PM/META protection fault":"", - _RGXDecodeMMULevel(ui32MMUDataType)); - } - - /* Req Status */ - { - IMG_CHAR *pszTagID; - IMG_CHAR *pszTagSB; - IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE]; - IMG_BOOL bRead; - IMG_UINT32 ui32TagSB, ui32TagID; - IMG_UINT64 ui64Addr; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XE_MEMORY_HIERARCHY)) - { - bRead = (ui64ReqStatus & RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__RNW_EN) != 0; - ui32TagSB = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_SHIFT; - ui32TagID = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_SHIFT; - } - else - { - bRead = (ui64ReqStatus & RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN) != 0; - ui32TagSB = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT; - ui32TagID = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT; - } - ui64Addr = ((ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT) << - RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT; - - _RGXDecodeBIFReqTags(psDevInfo, eBankID, ui32TagID, ui32TagSB, &pszTagID, &pszTagSB, &aszScratch[0], RGX_DEBUG_STR_SIZE); - - PVR_DUMPDEBUG_LOG("%s * Request (0x%016" IMG_UINT64_FMTSPECx - "): %s (%s), %s " IMG_DEV_VIRTADDR_FMTSPEC ".", - pszIndent, - ui64ReqStatus, - pszTagID, - pszTagSB, - (bRead)?"Reading from":"Writing to", - ui64Addr); - } - } -} -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__RNW_EN == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_RNW_EN), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_RNW_EN mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_CLRMSK == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_CLRMSK), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_CLRMSK mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_SB_SHIFT == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_SHIFT), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_SB_SHIFT mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_CLRMSK == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_CLRMSK), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_CLRMSK mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS__XE_MEM__TAG_ID_SHIFT == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_SHIFT), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_TAG_ID_SHIFT mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_CLRMSK), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_CLRMSK mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_SHIFT), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_SHIFT mismatch!"); -static_assert((RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT == RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_ALIGNSHIFT), - "RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_ALIGNSHIFT mismatch!"); - -/*! -******************************************************************************* - - @Function _RGXDumpRGXMMUFaultStatus - - @Description - - Dump MMU Fault status in human readable form. - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - @Input ui64MMUStatus - MMU Status register value - @Input pszMetaOrCore - string representing call is for META or MMU core - @Return void - -******************************************************************************/ -static void _RGXDumpRGXMMUFaultStatus(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 ui64MMUStatus, - const IMG_PCHAR pszMetaOrCore, - const IMG_CHAR *pszIndent) -{ - if (ui64MMUStatus == 0x0) - { - PVR_DUMPDEBUG_LOG("%sMMU (%s) - OK", pszIndent, pszMetaOrCore); - } - else - { - IMG_UINT32 ui32PC = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT; - IMG_UINT64 ui64Addr = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT) << 4; /* align shift */ - IMG_UINT32 ui32Requester = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT; - IMG_UINT32 ui32SideBand = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT; - IMG_UINT32 ui32MMULevel = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT; - IMG_BOOL bRead = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_RNW_EN) != 0; - IMG_BOOL bFault = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_FAULT_EN) != 0; - IMG_BOOL bROFault = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x2; - IMG_BOOL bProtFault = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x3; - IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE]; - IMG_CHAR *pszTagID; - IMG_CHAR *pszTagSB; - - _RGXDecodeMMUReqTags(psDevInfo, ui32Requester, ui32SideBand, bRead, &pszTagID, &pszTagSB, aszScratch, RGX_DEBUG_STR_SIZE); - - PVR_DUMPDEBUG_LOG("%sMMU (%s) - FAULT:", pszIndent, pszMetaOrCore); - PVR_DUMPDEBUG_LOG("%s * MMU status (0x%016" IMG_UINT64_FMTSPECx "): PC = %d, %s 0x%010" IMG_UINT64_FMTSPECx ", %s (%s)%s%s%s%s.", - pszIndent, - ui64MMUStatus, - ui32PC, - (bRead)?"Reading from":"Writing to", - ui64Addr, - pszTagID, - pszTagSB, - (bFault)?", Fault":"", - (bROFault)?", Read Only fault":"", - (bProtFault)?", PM/META protection fault":"", - _RGXDecodeMMULevel(ui32MMULevel)); - - } -} -static_assert((RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_LEVEL_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_LEVEL_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_RNW_EN == RGX_CR_MMU_FAULT_STATUS_META_RNW_EN), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_FAULT_EN == RGX_CR_MMU_FAULT_STATUS_META_FAULT_EN), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK == RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); -static_assert((RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT == RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT), - "RGX_CR_MMU_FAULT_STATUS_META mismatch!"); - - - -#if !defined(SUPPORT_TRUSTED_DEVICE) -#if !defined(NO_HARDWARE) -static PVRSRV_ERROR _RGXMipsExtraDebug(PVRSRV_RGXDEV_INFO *psDevInfo, RGX_MIPS_STATE *psMIPSState) -{ - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - IMG_UINT32 ui32RegRead; - IMG_UINT32 eError = PVRSRV_OK; - IMG_UINT32 *pui32NMIMemoryPointer; - IMG_UINT32 volatile *pui32SyncFlag; - IMG_DEVMEM_OFFSET_T uiNMIMemoryBootOffset; - - /* Map the FW data area to the kernel */ - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc, - (void **)&pui32NMIMemoryPointer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire NMI shared memory area (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto map_error_fail; - } - - /* Calculate offset to the boot/NMI data page */ - uiNMIMemoryBootOffset = RGXMIPSFW_GET_OFFSET_IN_DWORDS(RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA)); - - /* Jump to the NMI shared data area within the page above */ - pui32NMIMemoryPointer += uiNMIMemoryBootOffset + RGXMIPSFW_GET_OFFSET_IN_DWORDS(RGXMIPSFW_NMI_SHARED_DATA_BASE); - - /* Acquire the NMI operations lock */ - OSLockAcquire(psDevInfo->hNMILock); - - /* Make sure the synchronisation flag is set to 0 */ - pui32SyncFlag = &pui32NMIMemoryPointer[RGXMIPSFW_NMI_SYNC_FLAG_OFFSET]; - *pui32SyncFlag = 0; - - /* Readback performed as a part of memory barrier */ - OSWriteMemoryBarrier(pui32SyncFlag); - - /* Enable NMI issuing in the MIPS wrapper */ - OSWriteHWReg64(pvRegsBaseKM, - RGX_CR_MIPS_WRAPPER_NMI_ENABLE, - RGX_CR_MIPS_WRAPPER_NMI_ENABLE_EVENT_EN); - (void) OSReadHWReg64(pvRegsBaseKM, RGX_CR_MIPS_WRAPPER_NMI_ENABLE); - - /* Check the MIPS is not in error state already (e.g. it is booting or an NMI has already been requested) */ - ui32RegRead = OSReadHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_EXCEPTION_STATUS); - if ((ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_EN) || (ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_EN)) - { - - eError = PVRSRV_ERROR_MIPS_STATUS_UNAVAILABLE; - goto fail; - } - ui32RegRead = 0; - - /* Issue NMI */ - OSWriteHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_WRAPPER_NMI_EVENT, - RGX_CR_MIPS_WRAPPER_NMI_EVENT_TRIGGER_EN); - (void) OSReadHWReg64(pvRegsBaseKM, RGX_CR_MIPS_WRAPPER_NMI_EVENT); - - - /* Wait for NMI Taken to be asserted */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - ui32RegRead = OSReadHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_EXCEPTION_STATUS); - if (ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_EN) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if ((ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_NMI_TAKEN_EN) == 0) - { - eError = PVRSRV_ERROR_MIPS_STATUS_UNAVAILABLE; - goto fail; - } - ui32RegRead = 0; - - /* Allow the firmware to proceed */ - *pui32SyncFlag = 1; - - /* Readback performed as a part of memory barrier */ - OSWriteMemoryBarrier(pui32SyncFlag); - - /* Wait for the FW to have finished the NMI routine */ - ui32RegRead = OSReadHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_EXCEPTION_STATUS); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - ui32RegRead = OSReadHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_EXCEPTION_STATUS); - if (!(ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_EN)) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - if (ui32RegRead & RGX_CR_MIPS_EXCEPTION_STATUS_SI_ERL_EN) - { - eError = PVRSRV_ERROR_MIPS_STATUS_UNAVAILABLE; - goto fail; - } - ui32RegRead = 0; - - /* Copy state */ - OSDeviceMemCopy(psMIPSState, pui32NMIMemoryPointer + RGXMIPSFW_NMI_STATE_OFFSET, sizeof(*psMIPSState)); - - --(psMIPSState->ui32ErrorEPC); - --(psMIPSState->ui32EPC); - - /* Disable NMI issuing in the MIPS wrapper */ - OSWriteHWReg32(pvRegsBaseKM, - RGX_CR_MIPS_WRAPPER_NMI_ENABLE, - 0); - (void) OSReadHWReg64(pvRegsBaseKM, RGX_CR_MIPS_WRAPPER_NMI_ENABLE); - -fail: - /* Release the NMI operations lock */ - OSLockRelease(psDevInfo->hNMILock); - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc); -map_error_fail: - return eError; -} - -/* Print decoded information from cause register */ -static void _RGXMipsDumpCauseDecode(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32Cause, - IMG_UINT32 ui32ErrorState) -{ -#define INDENT " " - const IMG_UINT32 ui32ExcCode = RGXMIPSFW_C0_CAUSE_EXCCODE(ui32Cause); - const IMG_CHAR * const pszException = _GetMIPSExcString(ui32ExcCode); - - if (ui32ErrorState == RGXMIPSFW_NMI_ERROR_STATE_SET && - pszException != NULL) - { - PVR_DUMPDEBUG_LOG(INDENT "Cause exception: %s", pszException); - } - - if (ui32Cause & RGXMIPSFW_C0_CAUSE_FDCIPENDING) - { - PVR_DUMPDEBUG_LOG(INDENT "FDC interrupt pending"); - } - - if (!(ui32Cause & RGXMIPSFW_C0_CAUSE_IV)) - { - PVR_DUMPDEBUG_LOG(INDENT "Interrupt uses general interrupt vector"); - } - - if (ui32Cause & RGXMIPSFW_C0_CAUSE_PCIPENDING) - { - PVR_DUMPDEBUG_LOG(INDENT "Performance Counter Interrupt pending"); - } - - /* Unusable Coproc exception */ - if (ui32ExcCode == 11) - { - PVR_DUMPDEBUG_LOG(INDENT "Unusable Coprocessor: %d", RGXMIPSFW_C0_CAUSE_UNUSABLE_UNIT(ui32Cause)); - } - -#undef INDENT -} - -static IMG_BOOL _IsFWCodeException(IMG_UINT32 ui32ExcCode) -{ - if (ui32ExcCode >= sizeof(apsMIPSExcCodes)/sizeof(MIPS_EXCEPTION_ENCODING)) - { - PVR_DPF((PVR_DBG_WARNING, - "Only %lu exceptions available in MIPS, %u is not a valid exception code", - (unsigned long)sizeof(apsMIPSExcCodes)/sizeof(MIPS_EXCEPTION_ENCODING), ui32ExcCode)); - return IMG_FALSE; - } - - return apsMIPSExcCodes[ui32ExcCode].bIsFatal; -} - -static void _RGXMipsDumpDebugDecode(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32Debug, - IMG_UINT32 ui32DEPC) -{ - const IMG_CHAR *pszDException = NULL; - IMG_UINT32 i; -#define INDENT " " - - if (!(ui32Debug & RGXMIPSFW_C0_DEBUG_DM)) - { - return; - } - - PVR_DUMPDEBUG_LOG("DEBUG :"); - - pszDException = _GetMIPSExcString(RGXMIPSFW_C0_DEBUG_EXCCODE(ui32Debug)); - - if (pszDException != NULL) - { - PVR_DUMPDEBUG_LOG(INDENT "Debug exception: %s", pszDException); - } - - for (i = 0; i < ARRAY_SIZE(sMIPS_C0_DebugTable); ++i) - { - const RGXMIPSFW_C0_DEBUG_TBL_ENTRY * const psDebugEntry = &sMIPS_C0_DebugTable[i]; - - if (ui32Debug & psDebugEntry->ui32Mask) - { - PVR_DUMPDEBUG_LOG(INDENT "%s", psDebugEntry->pszExplanation); - } - } -#undef INDENT - PVR_DUMPDEBUG_LOG("DEPC :0x%08X", ui32DEPC); -} - -static inline void _GetMipsTLBPARanges(const RGX_MIPS_TLB_ENTRY *psTLBEntry, - const RGX_MIPS_REMAP_ENTRY *psRemapEntry0, - const RGX_MIPS_REMAP_ENTRY *psRemapEntry1, - IMG_UINT64 *pui64PA0Start, - IMG_UINT64 *pui64PA0End, - IMG_UINT64 *pui64PA1Start, - IMG_UINT64 *pui64PA1End) -{ - IMG_BOOL bUseRemapOutput = (psRemapEntry0 != NULL && psRemapEntry1 != NULL) ? IMG_TRUE : IMG_FALSE; - IMG_UINT64 ui64PageSize = RGXMIPSFW_TLB_GET_PAGE_SIZE(psTLBEntry->ui32TLBPageMask); - - if ((psTLBEntry->ui32TLBLo0 & RGXMIPSFW_TLB_VALID) == 0) - { - /* Dummy values to fail the range checks later */ - *pui64PA0Start = -1ULL; - *pui64PA0End = -1ULL; - } - else if (bUseRemapOutput) - { - *pui64PA0Start = (IMG_UINT64)psRemapEntry0->ui32RemapAddrOut << 12; - *pui64PA0End = *pui64PA0Start + ui64PageSize - 1; - } - else - { - *pui64PA0Start = RGXMIPSFW_TLB_GET_PA(psTLBEntry->ui32TLBLo0); - *pui64PA0End = *pui64PA0Start + ui64PageSize - 1; - } - - if ((psTLBEntry->ui32TLBLo1 & RGXMIPSFW_TLB_VALID) == 0) - { - /* Dummy values to fail the range checks later */ - *pui64PA1Start = -1ULL; - *pui64PA1End = -1ULL; - } - else if (bUseRemapOutput) - { - *pui64PA1Start = (IMG_UINT64)psRemapEntry1->ui32RemapAddrOut << 12; - *pui64PA1End = *pui64PA1Start + ui64PageSize - 1; - } - else - { - *pui64PA1Start = RGXMIPSFW_TLB_GET_PA(psTLBEntry->ui32TLBLo1); - *pui64PA1End = *pui64PA1Start + ui64PageSize - 1; - } -} - -static void _CheckMipsTLBDuplicatePAs(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGX_MIPS_TLB_ENTRY *psTLB, - const RGX_MIPS_REMAP_ENTRY *psRemap) -{ - IMG_UINT64 ui64PA0StartI, ui64PA1StartI, ui64PA0StartJ, ui64PA1StartJ; - IMG_UINT64 ui64PA0EndI, ui64PA1EndI, ui64PA0EndJ, ui64PA1EndJ; - IMG_UINT32 i, j; - -#define RANGES_OVERLAP(start0,end0,start1,end1) ((start0) < (end1) && (start1) < (end0)) - - for (i = 0; i < RGXMIPSFW_NUMBER_OF_TLB_ENTRIES; i++) - { - _GetMipsTLBPARanges(&psTLB[i], - psRemap ? &psRemap[i] : NULL, - psRemap ? &psRemap[i + RGXMIPSFW_NUMBER_OF_TLB_ENTRIES] : NULL, - &ui64PA0StartI, &ui64PA0EndI, - &ui64PA1StartI, &ui64PA1EndI); - - for (j = i + 1; j < RGXMIPSFW_NUMBER_OF_TLB_ENTRIES; j++) - { - _GetMipsTLBPARanges(&psTLB[j], - psRemap ? &psRemap[j] : NULL, - psRemap ? &psRemap[j + RGXMIPSFW_NUMBER_OF_TLB_ENTRIES] : NULL, - &ui64PA0StartJ, &ui64PA0EndJ, - &ui64PA1StartJ, &ui64PA1EndJ); - - if (RANGES_OVERLAP(ui64PA0StartI, ui64PA0EndI, ui64PA0StartJ, ui64PA0EndJ) || - RANGES_OVERLAP(ui64PA0StartI, ui64PA0EndI, ui64PA1StartJ, ui64PA1EndJ) || - RANGES_OVERLAP(ui64PA1StartI, ui64PA1EndI, ui64PA0StartJ, ui64PA0EndJ) || - RANGES_OVERLAP(ui64PA1StartI, ui64PA1EndI, ui64PA1StartJ, ui64PA1EndJ) ) - { - PVR_DUMPDEBUG_LOG("Overlap between TLB entry %u and %u", i , j); - } - } - } -} - -static inline IMG_UINT32 _GetMIPSRemapRegionSize(IMG_UINT32 ui32RegionSizeEncoding) -{ - return 1U << ((ui32RegionSizeEncoding + 1U) << 1U); -} - -static inline void _RGXMipsDumpTLBEntry(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGX_MIPS_TLB_ENTRY *psTLBEntry, - const RGX_MIPS_REMAP_ENTRY *psRemapEntry0, - const RGX_MIPS_REMAP_ENTRY *psRemapEntry1, - IMG_UINT32 ui32Index) -{ - IMG_BOOL bDumpRemapEntries = (psRemapEntry0 != NULL && psRemapEntry1 != NULL) ? IMG_TRUE : IMG_FALSE; - IMG_UINT64 ui64PA0 = RGXMIPSFW_TLB_GET_PA(psTLBEntry->ui32TLBLo0); - IMG_UINT64 ui64PA1 = RGXMIPSFW_TLB_GET_PA(psTLBEntry->ui32TLBLo1); - IMG_UINT64 ui64Remap0AddrOut = 0, ui64Remap1AddrOut = 0; - IMG_UINT32 ui32Remap0AddrIn = 0, ui32Remap1AddrIn = 0; - - if (bDumpRemapEntries) - { - /* RemapAddrIn is always 4k aligned and on 32 bit */ - ui32Remap0AddrIn = psRemapEntry0->ui32RemapAddrIn << 12; - ui32Remap1AddrIn = psRemapEntry1->ui32RemapAddrIn << 12; - - /* RemapAddrOut is always 4k aligned and on 32 or 36 bit */ - ui64Remap0AddrOut = (IMG_UINT64)psRemapEntry0->ui32RemapAddrOut << 12; - ui64Remap1AddrOut = (IMG_UINT64)psRemapEntry1->ui32RemapAddrOut << 12; - - /* If TLB and remap entries match, then merge them else, print them separately */ - if ((IMG_UINT32)ui64PA0 == ui32Remap0AddrIn && - (IMG_UINT32)ui64PA1 == ui32Remap1AddrIn) - { - ui64PA0 = ui64Remap0AddrOut; - ui64PA1 = ui64Remap1AddrOut; - bDumpRemapEntries = IMG_FALSE; - } - } - - PVR_DUMPDEBUG_LOG("%2u) VA 0x%08X (%3uk) -> PA0 0x%08" IMG_UINT64_FMTSPECx " %s%s%s, " - "PA1 0x%08" IMG_UINT64_FMTSPECx " %s%s%s", - ui32Index, - psTLBEntry->ui32TLBHi, - RGXMIPSFW_TLB_GET_PAGE_SIZE(psTLBEntry->ui32TLBPageMask), - ui64PA0, - gapszMipsPermissionPTFlags[RGXMIPSFW_TLB_GET_INHIBIT(psTLBEntry->ui32TLBLo0)], - gapszMipsDirtyGlobalValidPTFlags[RGXMIPSFW_TLB_GET_DGV(psTLBEntry->ui32TLBLo0)], - gapszMipsCoherencyPTFlags[RGXMIPSFW_TLB_GET_COHERENCY(psTLBEntry->ui32TLBLo0)], - ui64PA1, - gapszMipsPermissionPTFlags[RGXMIPSFW_TLB_GET_INHIBIT(psTLBEntry->ui32TLBLo1)], - gapszMipsDirtyGlobalValidPTFlags[RGXMIPSFW_TLB_GET_DGV(psTLBEntry->ui32TLBLo1)], - gapszMipsCoherencyPTFlags[RGXMIPSFW_TLB_GET_COHERENCY(psTLBEntry->ui32TLBLo1)]); - - if (bDumpRemapEntries) - { - PVR_DUMPDEBUG_LOG(" Remap %2u : IN 0x%08X (%3uk) => OUT 0x%08" IMG_UINT64_FMTSPECx, - ui32Index, - ui32Remap0AddrIn, - _GetMIPSRemapRegionSize(psRemapEntry0->ui32RemapRegionSize), - ui64Remap0AddrOut); - - PVR_DUMPDEBUG_LOG(" Remap %2u : IN 0x%08X (%3uk) => OUT 0x%08" IMG_UINT64_FMTSPECx, - ui32Index + RGXMIPSFW_NUMBER_OF_TLB_ENTRIES, - ui32Remap1AddrIn, - _GetMIPSRemapRegionSize(psRemapEntry1->ui32RemapRegionSize), - ui64Remap1AddrOut); - } -} - -#endif /* !defined(NO_HARDWARE) */ -#endif /* !defined(SUPPORT_TRUSTED_DEVICE) */ - -static inline IMG_CHAR const *_GetRISCVException(IMG_UINT32 ui32Mcause) -{ - switch (ui32Mcause) - { -#define X(value, fatal, description) \ - case value: \ - if (fatal) \ - return description; \ - return NULL; - - RGXRISCVFW_MCAUSE_TABLE -#undef X - - default: - PVR_DPF((PVR_DBG_WARNING, "Invalid RISC-V FW mcause value 0x%08x", ui32Mcause)); - return NULL; - } -} - -/* - Appends flags strings to a null-terminated string buffer - each flag - description string starts with a space. -*/ -static void _Flags2Description(IMG_CHAR *psDesc, - IMG_UINT32 ui32DescSize, - const IMG_FLAGS2DESC *psConvTable, - IMG_UINT32 ui32TableSize, - IMG_UINT32 ui32Flags) -{ - IMG_UINT32 ui32Idx; - - for (ui32Idx = 0; ui32Idx < ui32TableSize; ui32Idx++) - { - if ((ui32Flags & psConvTable[ui32Idx].uiFlag) == psConvTable[ui32Idx].uiFlag) - { - OSStringLCat(psDesc, psConvTable[ui32Idx].pszLabel, ui32DescSize); - } - } -} - -/* - Writes flags strings to an uninitialised buffer. -*/ -static void _GetFwSysFlagsDescription(IMG_CHAR *psDesc, IMG_UINT32 ui32DescSize, IMG_UINT32 ui32RawFlags) -{ - const IMG_CHAR szCswLabel[] = "Ctx switch options:"; - size_t uLabelLen = sizeof(szCswLabel) - 1; - const size_t uiBytesPerDesc = (ui32DescSize - uLabelLen) / 2U - 1U; - - OSStringLCopy(psDesc, szCswLabel, ui32DescSize); - - _Flags2Description(psDesc, uiBytesPerDesc + uLabelLen, asCswOpts2Description, ARRAY_SIZE(asCswOpts2Description), ui32RawFlags); - _Flags2Description(psDesc, ui32DescSize, asMisc2Description, ARRAY_SIZE(asMisc2Description), ui32RawFlags); -} - -static void _GetFwOsFlagsDescription(IMG_CHAR *psDesc, IMG_UINT32 ui32DescSize, IMG_UINT32 ui32RawFlags) -{ - const IMG_CHAR szCswLabel[] = "Ctx switch:"; - size_t uLabelLen = sizeof(szCswLabel) - 1; - const size_t uiBytesPerDesc = (ui32DescSize - uLabelLen) / 2U - 1U; - - OSStringLCopy(psDesc, szCswLabel, ui32DescSize); - - _Flags2Description(psDesc, uiBytesPerDesc + uLabelLen, asFwOsCfg2Description, ARRAY_SIZE(asFwOsCfg2Description), ui32RawFlags); -} - - -/*! -******************************************************************************* - - @Function _RGXDumpFWAssert - - @Description - - Dump FW assert strings when a thread asserts. - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psRGXFWIfTraceBufCtl - RGX FW trace buffer - - @Return void - -******************************************************************************/ -static void _RGXDumpFWAssert(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl) -{ - const IMG_CHAR *pszTraceAssertPath; - const IMG_CHAR *pszTraceAssertInfo; - IMG_INT32 ui32TraceAssertLine; - IMG_UINT32 i; - - for (i = 0; i < RGXFW_THREAD_NUM; i++) - { - pszTraceAssertPath = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szPath; - pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szInfo; - ui32TraceAssertLine = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.ui32LineNum; - - /* print non-null assert strings */ - if (*pszTraceAssertInfo) - { - PVR_DUMPDEBUG_LOG("FW-T%d Assert: %s (%s:%d)", - i, pszTraceAssertInfo, pszTraceAssertPath, ui32TraceAssertLine); - } - } -} - -/*! -******************************************************************************* - - @Function _RGXDumpFWFaults - - @Description - - Dump FW assert strings when a thread asserts. - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psFwSysData - RGX FW shared system data - - @Return void - -******************************************************************************/ -static void _RGXDumpFWFaults(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGXFWIF_SYSDATA *psFwSysData) -{ - if (psFwSysData->ui32FWFaults > 0) - { - IMG_UINT32 ui32StartFault = psFwSysData->ui32FWFaults - RGXFWIF_FWFAULTINFO_MAX; - IMG_UINT32 ui32EndFault = psFwSysData->ui32FWFaults - 1; - IMG_UINT32 ui32Index; - - if (psFwSysData->ui32FWFaults < RGXFWIF_FWFAULTINFO_MAX) - { - ui32StartFault = 0; - } - - for (ui32Index = ui32StartFault; ui32Index <= ui32EndFault; ui32Index++) - { - const RGX_FWFAULTINFO *psFaultInfo = &psFwSysData->sFaultInfo[ui32Index % RGXFWIF_FWFAULTINFO_MAX]; - IMG_UINT64 ui64Seconds, ui64Nanoseconds; - - /* Split OS timestamp in seconds and nanoseconds */ - ConvertOSTimestampToSAndNS(psFaultInfo->ui64OSTimer, &ui64Seconds, &ui64Nanoseconds); - - PVR_DUMPDEBUG_LOG("FW Fault %d: %s (%s:%d)", - ui32Index+1, psFaultInfo->sFaultBuf.szInfo, - psFaultInfo->sFaultBuf.szPath, - psFaultInfo->sFaultBuf.ui32LineNum); - PVR_DUMPDEBUG_LOG(" Data = 0x%08x, CRTimer = 0x%012"IMG_UINT64_FMTSPECx", OSTimer = %" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC, - psFaultInfo->ui32Data, - psFaultInfo->ui64CRTimer, - ui64Seconds, ui64Nanoseconds); - } - } -} - -static void _RGXDumpFWPoll(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGXFWIF_SYSDATA *psFwSysData) -{ - IMG_UINT32 i; - for (i = 0; i < RGXFW_THREAD_NUM; i++) - { - if (psFwSysData->aui32CrPollAddr[i]) - { - PVR_DUMPDEBUG_LOG("T%u polling %s (reg:0x%08X mask:0x%08X)", - i, - ((psFwSysData->aui32CrPollAddr[i] & RGXFW_POLL_TYPE_SET)?("set"):("unset")), - psFwSysData->aui32CrPollAddr[i] & ~RGXFW_POLL_TYPE_SET, - psFwSysData->aui32CrPollMask[i]); - } - } - -} - -static void _RGXDumpFWHWRInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - const RGXFWIF_SYSDATA *psFwSysData, - const RGXFWIF_HWRINFOBUF *psHWRInfoBuf, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_BOOL bAnyLocked = IMG_FALSE; - IMG_UINT32 dm, i; - IMG_UINT32 ui32LineSize; - IMG_CHAR *pszLine, *pszTemp; - const IMG_CHAR *apszDmNames[RGXFWIF_DM_MAX] = {"GP", "TDM", "TA", "3D", "CDM", "RAY", "TA2", "TA3", "TA4"}; - const IMG_CHAR szMsgHeader[] = "Number of HWR: "; - const IMG_CHAR szMsgFalse[] = "FALSE("; - IMG_CHAR *pszLockupType = ""; - const IMG_UINT32 ui32MsgHeaderCharCount = ARRAY_SIZE(szMsgHeader) - 1; /* size includes the null */ - const IMG_UINT32 ui32MsgFalseCharCount = ARRAY_SIZE(szMsgFalse) - 1; - IMG_UINT32 ui32HWRRecoveryFlags; - IMG_UINT32 ui32ReadIndex; - - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM))) - { - apszDmNames[RGXFWIF_DM_TDM] = "2D"; - } - - for (dm = 0; dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount; dm++) - { - if (psHWRInfoBuf->aui32HwrDmLockedUpCount[dm] || - psHWRInfoBuf->aui32HwrDmOverranCount[dm]) - { - bAnyLocked = IMG_TRUE; - break; - } - } - - if (!PVRSRV_VZ_MODE_IS(GUEST) && !bAnyLocked && (psFwSysData->ui32HWRStateFlags & RGXFWIF_HWR_HARDWARE_OK)) - { - /* No HWR situation, print nothing */ - return; - } - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - IMG_BOOL bAnyHWROccured = IMG_FALSE; - - for (dm = 0; dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount; dm++) - { - if (psHWRInfoBuf->aui32HwrDmRecoveredCount[dm] != 0 || - psHWRInfoBuf->aui32HwrDmLockedUpCount[dm] != 0 || - psHWRInfoBuf->aui32HwrDmOverranCount[dm] !=0) - { - bAnyHWROccured = IMG_TRUE; - break; - } - } - - if (!bAnyHWROccured) - { - return; - } - } - - ui32LineSize = sizeof(IMG_CHAR) * ( - ui32MsgHeaderCharCount + - (psDevInfo->sDevFeatureCfg.ui32MAXDMCount*( 4/*DM name + left parenthesis*/ + - 10/*UINT32 max num of digits*/ + - 1/*slash*/ + - 10/*UINT32 max num of digits*/ + - 3/*right parenthesis + comma + space*/)) + - ui32MsgFalseCharCount + 1 + (psDevInfo->sDevFeatureCfg.ui32MAXDMCount*6) + 1 - /* 'FALSE(' + ')' + (UINT16 max num + comma) per DM + \0 */ - ); - - pszLine = OSAllocMem(ui32LineSize); - if (pszLine == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Out of mem allocating line string (size: %d)", - __func__, - ui32LineSize)); - return; - } - - OSStringLCopy(pszLine, szMsgHeader, ui32LineSize); - pszTemp = pszLine + ui32MsgHeaderCharCount; - - for (dm = 0; dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount; dm++) - { - pszTemp += OSSNPrintf(pszTemp, - 4 + 10 + 1 + 10 + 1 + 10 + 1 + 1 + 1 + 1 - /* (name + left parenthesis) + UINT32 + slash + UINT32 + plus + UINT32 + right parenthesis + comma + space + \0 */, - "%s(%u/%u+%u), ", - apszDmNames[dm], - psHWRInfoBuf->aui32HwrDmRecoveredCount[dm], - psHWRInfoBuf->aui32HwrDmLockedUpCount[dm], - psHWRInfoBuf->aui32HwrDmOverranCount[dm]); - } - - OSStringLCat(pszLine, szMsgFalse, ui32LineSize); - pszTemp += ui32MsgFalseCharCount; - - for (dm = 0; dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount; dm++) - { - pszTemp += OSSNPrintf(pszTemp, - 10 + 1 + 1 /* UINT32 max num + comma + \0 */, - (dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount-1 ? "%u," : "%u)"), - psHWRInfoBuf->aui32HwrDmFalseDetectCount[dm]); - } - - PVR_DUMPDEBUG_LOG("%s", pszLine); - - OSFreeMem(pszLine); - - /* Print out per HWR info */ - for (dm = 0; dm < psDevInfo->sDevFeatureCfg.ui32MAXDMCount; dm++) - { - if (dm == RGXFWIF_DM_GP) - { - PVR_DUMPDEBUG_LOG("DM %d (GP)", dm); - } - else - { - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - IMG_UINT32 ui32HWRRecoveryFlags = psFwSysData->aui32HWRRecoveryFlags[dm]; - IMG_CHAR sPerDmHwrDescription[RGX_DEBUG_STR_SIZE]; - sPerDmHwrDescription[0] = '\0'; - - if (ui32HWRRecoveryFlags == RGXFWIF_DM_STATE_WORKING) - { - OSStringLCopy(sPerDmHwrDescription, " working;", RGX_DEBUG_STR_SIZE); - } - else - { - _Flags2Description(sPerDmHwrDescription, RGX_DEBUG_STR_SIZE, - asDmState2Description, ARRAY_SIZE(asDmState2Description), - ui32HWRRecoveryFlags); - } - PVR_DUMPDEBUG_LOG("DM %d (HWRflags 0x%08x:%s)", dm, ui32HWRRecoveryFlags, sPerDmHwrDescription); - } - else - { - PVR_DUMPDEBUG_LOG("DM %d", dm); - } - } - - ui32ReadIndex = 0; - for (i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++) - { - IMG_BOOL bPMFault = IMG_FALSE; - IMG_UINT32 ui32PC; - IMG_UINT32 ui32PageSize = 0; - IMG_DEV_PHYADDR sPCDevPAddr = { 0 }; - const RGX_HWRINFO *psHWRInfo = &psHWRInfoBuf->sHWRInfo[ui32ReadIndex]; - - if ((psHWRInfo->eDM == dm) && (psHWRInfo->ui32HWRNumber != 0)) - { - IMG_CHAR aui8RecoveryNum[10+10+1]; - IMG_UINT64 ui64Seconds, ui64Nanoseconds; - IMG_BOOL bPageFault = IMG_FALSE; - IMG_DEV_VIRTADDR sFaultDevVAddr; - - /* Split OS timestamp in seconds and nanoseconds */ - ConvertOSTimestampToSAndNS(psHWRInfo->ui64OSTimer, &ui64Seconds, &ui64Nanoseconds); - - ui32HWRRecoveryFlags = psHWRInfo->ui32HWRRecoveryFlags; - if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_LOCKUP) { pszLockupType = ", Guilty Lockup"; } - else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_INNOCENT_LOCKUP) { pszLockupType = ", Innocent Lockup"; } - else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_OVERRUNING) { pszLockupType = ", Guilty Overrun"; } - else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_INNOCENT_OVERRUNING) { pszLockupType = ", Innocent Overrun"; } - else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_HARD_CONTEXT_SWITCH) { pszLockupType = ", Hard Context Switch"; } - else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GPU_ECC_HWR) { pszLockupType = ", GPU ECC HWR"; } - - OSSNPrintf(aui8RecoveryNum, sizeof(aui8RecoveryNum), "Recovery %d:", psHWRInfo->ui32HWRNumber); - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { - PVR_DUMPDEBUG_LOG(" %s Core = %u, PID = %u, frame = %d, HWRTData = 0x%08X, EventStatus = 0x%08X%s", - aui8RecoveryNum, - psHWRInfo->ui32CoreID, - psHWRInfo->ui32PID, - psHWRInfo->ui32FrameNum, - psHWRInfo->ui32ActiveHWRTData, - psHWRInfo->ui32EventStatus, - pszLockupType); - } - else - { - PVR_DUMPDEBUG_LOG(" %s PID = %u, frame = %d, HWRTData = 0x%08X, EventStatus = 0x%08X%s", - aui8RecoveryNum, - psHWRInfo->ui32PID, - psHWRInfo->ui32FrameNum, - psHWRInfo->ui32ActiveHWRTData, - psHWRInfo->ui32EventStatus, - pszLockupType); - } - pszTemp = &aui8RecoveryNum[0]; - while (*pszTemp != '\0') - { - *pszTemp++ = ' '; - } - - /* There's currently no time correlation for the Guest OSes on the Firmware so there's no point printing OS Timestamps on Guests */ - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DUMPDEBUG_LOG(" %s CRTimer = 0x%012"IMG_UINT64_FMTSPECX", OSTimer = %" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC ", CyclesElapsed = %" IMG_INT64_FMTSPECd, - aui8RecoveryNum, - psHWRInfo->ui64CRTimer, - ui64Seconds, - ui64Nanoseconds, - (psHWRInfo->ui64CRTimer-psHWRInfo->ui64CRTimeOfKick)*256); - } - else - { - PVR_DUMPDEBUG_LOG(" %s CRTimer = 0x%012"IMG_UINT64_FMTSPECX", CyclesElapsed = %" IMG_INT64_FMTSPECd, - aui8RecoveryNum, - psHWRInfo->ui64CRTimer, - (psHWRInfo->ui64CRTimer-psHWRInfo->ui64CRTimeOfKick)*256); - } - - if (psHWRInfo->ui64CRTimeHWResetFinish != 0) - { - if (psHWRInfo->ui64CRTimeFreelistReady != 0) - { - /* If ui64CRTimeFreelistReady is less than ui64CRTimeHWResetFinish it means APM kicked in and the time is not valid. */ - if (psHWRInfo->ui64CRTimeHWResetFinish < psHWRInfo->ui64CRTimeFreelistReady) - { - PVR_DUMPDEBUG_LOG(" %s PreResetTimeInCycles = %" IMG_INT64_FMTSPECd ", HWResetTimeInCycles = %" IMG_INT64_FMTSPECd ", FreelistReconTimeInCycles = %" IMG_INT64_FMTSPECd ", TotalRecoveryTimeInCycles = %" IMG_INT64_FMTSPECd, - aui8RecoveryNum, - (psHWRInfo->ui64CRTimeHWResetStart-psHWRInfo->ui64CRTimer)*256, - (psHWRInfo->ui64CRTimeHWResetFinish-psHWRInfo->ui64CRTimeHWResetStart)*256, - (psHWRInfo->ui64CRTimeFreelistReady-psHWRInfo->ui64CRTimeHWResetFinish)*256, - (psHWRInfo->ui64CRTimeFreelistReady-psHWRInfo->ui64CRTimer)*256); - } - else - { - PVR_DUMPDEBUG_LOG(" %s PreResetTimeInCycles = %" IMG_INT64_FMTSPECd ", HWResetTimeInCycles = %" IMG_INT64_FMTSPECd ", FreelistReconTimeInCycles = , TotalResetTimeInCycles = %" IMG_INT64_FMTSPECd, - aui8RecoveryNum, - (psHWRInfo->ui64CRTimeHWResetStart-psHWRInfo->ui64CRTimer)*256, - (psHWRInfo->ui64CRTimeHWResetFinish-psHWRInfo->ui64CRTimeHWResetStart)*256, - (psHWRInfo->ui64CRTimeHWResetFinish-psHWRInfo->ui64CRTimer)*256); - } - } - else - { - PVR_DUMPDEBUG_LOG(" %s PreResetTimeInCycles = %" IMG_INT64_FMTSPECd ", HWResetTimeInCycles = %" IMG_INT64_FMTSPECd ", TotalResetTimeInCycles = %" IMG_INT64_FMTSPECd, - aui8RecoveryNum, - (psHWRInfo->ui64CRTimeHWResetStart-psHWRInfo->ui64CRTimer)*256, - (psHWRInfo->ui64CRTimeHWResetFinish-psHWRInfo->ui64CRTimeHWResetStart)*256, - (psHWRInfo->ui64CRTimeHWResetFinish-psHWRInfo->ui64CRTimer)*256); - } - } - - switch (psHWRInfo->eHWRType) - { - case RGX_HWRTYPE_BIF0FAULT: - case RGX_HWRTYPE_BIF1FAULT: - { - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE))) - { - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXFWIF_HWRTYPE_BIF_BANK_GET(psHWRInfo->eHWRType), - psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus, - psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus, - DD_NORMAL_INDENT); - - bPageFault = IMG_TRUE; - sFaultDevVAddr.uiAddr = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK); - ui32PC = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT; - bPMFault = (ui32PC >= 8); - ui32PageSize = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT; - sPCDevPAddr.uiAddr = psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress; - } - } - break; - case RGX_HWRTYPE_TEXASBIF0FAULT: - { - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE))) - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, CLUSTER_GROUPING)) - { - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_TEXAS_BIF, - psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus, - psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus, - DD_NORMAL_INDENT); - - bPageFault = IMG_TRUE; - sFaultDevVAddr.uiAddr = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK); - ui32PC = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT; - bPMFault = (ui32PC >= 8); - ui32PageSize = (psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK) >> - RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT; - sPCDevPAddr.uiAddr = psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress; - } - } - } - break; - - case RGX_HWRTYPE_ECCFAULT: - { - PVR_DUMPDEBUG_LOG(" ECC fault GPU=0x%08x", psHWRInfo->uHWRData.sECCInfo.ui32FaultGPU); - } - break; - - case RGX_HWRTYPE_MMUFAULT: - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, - psHWRInfo->uHWRData.sMMUInfo.aui64MMUStatus[0], - "Core", - DD_NORMAL_INDENT); - - bPageFault = IMG_TRUE; - sFaultDevVAddr.uiAddr = psHWRInfo->uHWRData.sMMUInfo.aui64MMUStatus[0]; - sFaultDevVAddr.uiAddr &= ~RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK; - sFaultDevVAddr.uiAddr >>= RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT; - sFaultDevVAddr.uiAddr <<= 4; /* align shift */ - ui32PC = (psHWRInfo->uHWRData.sMMUInfo.aui64MMUStatus[0] & ~RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK) >> - RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT; -#if defined(SUPPORT_TRUSTED_DEVICE) - ui32PC = ui32PC - 1; -#endif - bPMFault = (ui32PC <= 8); - sPCDevPAddr.uiAddr = psHWRInfo->uHWRData.sMMUInfo.ui64PCAddress; - } - } - break; - - case RGX_HWRTYPE_MMUMETAFAULT: - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, - psHWRInfo->uHWRData.sMMUInfo.aui64MMUStatus[0], - "Meta", - DD_NORMAL_INDENT); - - bPageFault = IMG_TRUE; - sFaultDevVAddr.uiAddr = psHWRInfo->uHWRData.sMMUInfo.aui64MMUStatus[0]; - sFaultDevVAddr.uiAddr &= ~RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK; - sFaultDevVAddr.uiAddr >>= RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT; - sFaultDevVAddr.uiAddr <<= 4; /* align shift */ - sPCDevPAddr.uiAddr = psHWRInfo->uHWRData.sMMUInfo.ui64PCAddress; - } - } - break; - - case RGX_HWRTYPE_POLLFAILURE: - { - PVR_DUMPDEBUG_LOG(" T%u polling %s (reg:0x%08X mask:0x%08X last:0x%08X)", - psHWRInfo->uHWRData.sPollInfo.ui32ThreadNum, - ((psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & RGXFW_POLL_TYPE_SET)?("set"):("unset")), - psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & ~RGXFW_POLL_TYPE_SET, - psHWRInfo->uHWRData.sPollInfo.ui32CrPollMask, - psHWRInfo->uHWRData.sPollInfo.ui32CrPollLastValue); - } - break; - - case RGX_HWRTYPE_MIPSTLBFAULT: - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - IMG_UINT32 ui32EntryLo = psHWRInfo->uHWRData.sTLBInfo.ui32EntryLo; - - /* This is not exactly what the MMU code does, but the result should be the same */ - const IMG_UINT32 ui32UnmappedEntry = - ((IMG_UINT32)(MMU_BAD_PHYS_ADDR & 0xffffffff) & RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT) | RGXMIPSFW_ENTRYLO_UNCACHED; - - PVR_DUMPDEBUG_LOG(" MIPS TLB fault: BadVA = 0x%08X, EntryLo = 0x%08X" - " (page PA 0x%" IMG_UINT64_FMTSPECx", V %u)", - psHWRInfo->uHWRData.sTLBInfo.ui32BadVAddr, - ui32EntryLo, - RGXMIPSFW_TLB_GET_PA(ui32EntryLo), - ui32EntryLo & RGXMIPSFW_TLB_VALID ? 1 : 0); - - if (ui32EntryLo == ui32UnmappedEntry) - { - PVR_DUMPDEBUG_LOG(" Potential use-after-free detected"); - } - } - } - break; - - case RGX_HWRTYPE_MMURISCVFAULT: - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_FWCORE, - psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus, - psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus, - DD_NORMAL_INDENT); - - bPageFault = IMG_TRUE; - bPMFault = IMG_FALSE; - sFaultDevVAddr.uiAddr = - (psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus & - ~RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS_ADDRESS_CLRMSK); - ui32PageSize = - (psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus & - ~RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_PAGE_SIZE_CLRMSK) >> - RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS_PAGE_SIZE_SHIFT; - sPCDevPAddr.uiAddr = psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress; - } - } - break; - - case RGX_HWRTYPE_OVERRUN: - case RGX_HWRTYPE_UNKNOWNFAILURE: - { - /* Nothing to dump */ - } - break; - - default: - { - PVR_DUMPDEBUG_LOG(" Unknown HWR Info type: 0x%x", psHWRInfo->eHWRType); - } - break; - } - - if (bPageFault) - { - - FAULT_INFO *psInfo; - - OSLockAcquire(psDevInfo->hDebugFaultInfoLock); - - /* Find the matching Fault Info for this HWRInfo */ - psInfo = &gsFaultInfoLog.asFaults[ui32ReadIndex]; - - /* if they do not match, we need to update the psInfo */ - if ((psInfo->ui64CRTimer != psHWRInfo->ui64CRTimer) || - (psInfo->sFaultDevVAddr.uiAddr != sFaultDevVAddr.uiAddr)) - { - MMU_FAULT_DATA *psFaultData = &psInfo->sMMUFaultData; - - psFaultData->eType = MMU_FAULT_TYPE_UNKNOWN; - - if (bPMFault) - { - /* PM fault and we dump PC details only */ - psFaultData->eTopLevel = MMU_LEVEL_0; - psFaultData->eType = MMU_FAULT_TYPE_PM; - psFaultData->sLevelData[MMU_LEVEL_0].ui64Address = sPCDevPAddr.uiAddr; - } - else - { - RGXCheckFaultAddress(psDevInfo, &sFaultDevVAddr, &sPCDevPAddr, psFaultData); - } - - _RecordFaultInfo(psDevInfo, psInfo, - sFaultDevVAddr, sPCDevPAddr, psHWRInfo->ui64CRTimer, - _PageSizeHWToBytes(ui32PageSize)); - - } - - _DumpFaultAddressHostView(&psInfo->sMMUFaultData, pfnDumpDebugPrintf, pvDumpDebugFile, DD_NORMAL_INDENT); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - _PrintFaultInfo(pfnDumpDebugPrintf, pvDumpDebugFile, psInfo, DD_NORMAL_INDENT); - } - - OSLockRelease(psDevInfo->hDebugFaultInfoLock); - } - - } - - if (ui32ReadIndex == RGXFWIF_HWINFO_MAX_FIRST - 1) - ui32ReadIndex = psHWRInfoBuf->ui32WriteIndex; - else - ui32ReadIndex = (ui32ReadIndex + 1) - (ui32ReadIndex / RGXFWIF_HWINFO_LAST_INDEX) * RGXFWIF_HWINFO_MAX_LAST; - } - } -} - -#if !defined(NO_HARDWARE) - -/*! -******************************************************************************* - - @Function _CheckForPendingPage - - @Description - - Check if the MMU indicates it is blocked on a pending page - - @Input psDevInfo - RGX device info - - @Return IMG_BOOL - IMG_TRUE if there is a pending page - -******************************************************************************/ -static INLINE IMG_BOOL _CheckForPendingPage(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32BIFMMUEntry; - - ui32BIFMMUEntry = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY); - - if (ui32BIFMMUEntry & RGX_CR_BIF_MMU_ENTRY_PENDING_EN) - { - return IMG_TRUE; - } - else - { - return IMG_FALSE; - } -} - -/*! -******************************************************************************* - - @Function _GetPendingPageInfo - - @Description - - Get information about the pending page from the MMU status registers - - @Input psDevInfo - RGX device info - @Output psDevVAddr - The device virtual address of the pending MMU address translation - @Output pui32CatBase - The page catalog base - @Output pui32DataType - The MMU entry data type - - @Return void - -******************************************************************************/ -static void _GetPendingPageInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *psDevVAddr, - IMG_UINT32 *pui32CatBase, - IMG_UINT32 *pui32DataType) -{ - IMG_UINT64 ui64BIFMMUEntryStatus; - - ui64BIFMMUEntryStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY_STATUS); - - psDevVAddr->uiAddr = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_CLRMSK); - - *pui32CatBase = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_CLRMSK) >> - RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_SHIFT; - - *pui32DataType = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_CLRMSK) >> - RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_SHIFT; -} - -#endif - -void RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_BOOL bRGXPoweredON) -{ - IMG_CHAR *pszState, *pszReason; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - const RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - IMG_UINT32 ui32OSid; - const RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg; - /* space for the current clock speed and 3 previous */ - RGXFWIF_TIME_CORR asTimeCorrs[4]; - IMG_UINT32 ui32NumClockSpeedChanges; - -#if defined(NO_HARDWARE) - PVR_UNREFERENCED_PARAMETER(bRGXPoweredON); -#else - if ((bRGXPoweredON) && !PVRSRV_VZ_MODE_IS(GUEST)) - { - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - - IMG_UINT64 ui64RegValMMUStatus; - - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS); - _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, ui64RegValMMUStatus, "Core", DD_SUMMARY_INDENT); - - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS_META); - _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, ui64RegValMMUStatus, "Meta", DD_SUMMARY_INDENT); - } - else - { - IMG_UINT64 ui64RegValMMUStatus, ui64RegValREQStatus; - - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_MMU_STATUS); - ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_REQ_STATUS); - - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_BIF0, ui64RegValMMUStatus, ui64RegValREQStatus, DD_SUMMARY_INDENT); - - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, SINGLE_BIF))) - { - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_MMU_STATUS); - ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_BIF1, ui64RegValMMUStatus, ui64RegValREQStatus, DD_SUMMARY_INDENT); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_MEM_FAULT_MMU_STATUS); - ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_MEM_FAULT_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_FWCORE, ui64RegValMMUStatus, ui64RegValREQStatus, DD_SUMMARY_INDENT); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, CLUSTER_GROUPING)) - { - IMG_UINT32 ui32PhantomCnt = RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, NUM_CLUSTERS) ? RGX_REQ_NUM_PHANTOMS(RGX_GET_FEATURE_VALUE(psDevInfo, NUM_CLUSTERS)) : 0; - - if (ui32PhantomCnt > 1) - { - IMG_UINT32 ui32Phantom; - for (ui32Phantom = 0; ui32Phantom < ui32PhantomCnt; ui32Phantom++) - { - /* This can't be done as it may interfere with the FW... */ - /*OSWriteHWReg64(RGX_CR_TEXAS_INDIRECT, ui32Phantom);*/ - - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS); - ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS); - - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, DD_SUMMARY_INDENT); - } - }else - { - ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS); - ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS); - - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, DD_SUMMARY_INDENT); - } - } - } - - if (_CheckForPendingPage(psDevInfo)) - { - IMG_UINT32 ui32CatBase; - IMG_UINT32 ui32DataType; - IMG_DEV_VIRTADDR sDevVAddr; - - PVR_DUMPDEBUG_LOG("MMU Pending page: Yes"); - - _GetPendingPageInfo(psDevInfo, &sDevVAddr, &ui32CatBase, &ui32DataType); - - if (ui32CatBase >= 8) - { - PVR_DUMPDEBUG_LOG("Cannot check address on PM cat base %u", ui32CatBase); - } - else - { - IMG_DEV_PHYADDR sPCDevPAddr; - MMU_FAULT_DATA sFaultData; - - sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32CatBase)); - - PVR_DUMPDEBUG_LOG("Checking device virtual address " IMG_DEV_VIRTADDR_FMTSPEC - " on cat base %u. PC Addr = 0x%" IMG_UINT64_FMTSPECx, - sDevVAddr.uiAddr, - ui32CatBase, - sPCDevPAddr.uiAddr); - RGXCheckFaultAddress(psDevInfo, &sDevVAddr, &sPCDevPAddr, &sFaultData); - _DumpFaultAddressHostView(&sFaultData, pfnDumpDebugPrintf, pvDumpDebugFile, DD_SUMMARY_INDENT); - } - } - } -#endif /* NO_HARDWARE */ - - /* Firmware state */ - switch (OSAtomicRead(&psDevInfo->psDeviceNode->eHealthStatus)) - { - case PVRSRV_DEVICE_HEALTH_STATUS_OK: pszState = "OK"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING: pszState = "NOT RESPONDING"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_DEAD: pszState = "DEAD"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_FAULT: pszState = "FAULT"; break; - case PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED: pszState = "UNDEFINED"; break; - default: pszState = "UNKNOWN"; break; - } - - switch (OSAtomicRead(&psDevInfo->psDeviceNode->eHealthReason)) - { - case PVRSRV_DEVICE_HEALTH_REASON_NONE: pszReason = ""; break; - case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED: pszReason = " - Asserted"; break; - case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING: pszReason = " - Poll failing"; break; - case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS: pszReason = " - Global Event Object timeouts rising"; break; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT: pszReason = " - KCCB offset invalid"; break; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED: pszReason = " - KCCB stalled"; break; - case PVRSRV_DEVICE_HEALTH_REASON_IDLING: pszReason = " - Idling"; break; - case PVRSRV_DEVICE_HEALTH_REASON_RESTARTING: pszReason = " - Restarting"; break; - case PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS: pszReason = " - Missing interrupts"; break; - default: pszReason = " - Unknown reason"; break; - } - -#if !defined(NO_HARDWARE) - /* Determine the type virtualisation support used */ -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) -#if defined(SUPPORT_AUTOVZ) -#if defined(SUPPORT_AUTOVZ_HW_REGS) - PVR_DUMPDEBUG_LOG("RGX Virtualisation type: AutoVz with HW register support"); -#else - PVR_DUMPDEBUG_LOG("RGX Virtualisation type: AutoVz with shared memory"); -#endif /* defined(SUPPORT_AUTOVZ_HW_REGS) */ -#else - PVR_DUMPDEBUG_LOG("RGX Virtualisation type: Hypervisor-assisted with static Fw heap allocation"); -#endif /* defined(SUPPORT_AUTOVZ) */ -#else - PVR_DUMPDEBUG_LOG("RGX Virtualisation type: Hypervisor-assisted with dynamic Fw heap allocation"); -#endif /* defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) */ - } -#endif /* (RGX_NUM_OS_SUPPORTED > 1) */ - -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) || (defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1)) - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - RGXFWIF_CONNECTION_FW_STATE eFwState = KM_GET_FW_CONNECTION(psDevInfo); - RGXFWIF_CONNECTION_OS_STATE eOsState = KM_GET_OS_CONNECTION(psDevInfo); - - PVR_DUMPDEBUG_LOG("RGX Virtualisation firmware connection state: %s (Fw=%s; OS=%s)", - ((eFwState == RGXFW_CONNECTION_FW_ACTIVE) && (eOsState == RGXFW_CONNECTION_OS_ACTIVE)) ? ("UP") : ("DOWN"), - (eFwState < RGXFW_CONNECTION_FW_STATE_COUNT) ? (apszFwOsStateName[eFwState]) : ("invalid"), - (eOsState < RGXFW_CONNECTION_OS_STATE_COUNT) ? (apszFwOsStateName[eOsState]) : ("invalid")); - - } -#endif - -#if defined(SUPPORT_AUTOVZ) && defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) - if (!PVRSRV_VZ_MODE_IS(NATIVE)) - { - IMG_UINT32 ui32FwAliveTS = KM_GET_FW_ALIVE_TOKEN(psDevInfo); - IMG_UINT32 ui32OsAliveTS = KM_GET_OS_ALIVE_TOKEN(psDevInfo); - - PVR_DUMPDEBUG_LOG("RGX Virtualisation watchdog timestamps (in GPU timer ticks): Fw=%u; OS=%u; diff(FW, OS) = %u", - ui32FwAliveTS, ui32OsAliveTS, ui32FwAliveTS - ui32OsAliveTS); - } -#endif -#endif /* !defined(NO_HARDWARE) */ - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - IMG_CHAR sHwrStateDescription[RGX_DEBUG_STR_SIZE]; - IMG_BOOL bOsIsolationEnabled = IMG_FALSE; - - if (psFwSysData == NULL) - { - /* can't dump any more information */ - PVR_DUMPDEBUG_LOG("RGX FW State: %s%s", pszState, pszReason); - return; - } - - sHwrStateDescription[0] = '\0'; - - _Flags2Description(sHwrStateDescription, RGX_DEBUG_STR_SIZE, - asHwrState2Description, ARRAY_SIZE(asHwrState2Description), - psFwSysData->ui32HWRStateFlags); - PVR_DUMPDEBUG_LOG("RGX FW State: %s%s (HWRState 0x%08x:%s)", pszState, pszReason, psFwSysData->ui32HWRStateFlags, sHwrStateDescription); - PVR_DUMPDEBUG_LOG("RGX FW Power State: %s (APM %s: %d ok, %d denied, %d non-idle, %d retry, %d other, %d total. Latency: %u ms)", - pszPowStateName[psFwSysData->ePowState], - (psDevInfo->pvAPMISRData)?"enabled":"disabled", - psDevInfo->ui32ActivePMReqOk - psDevInfo->ui32ActivePMReqNonIdle, - psDevInfo->ui32ActivePMReqDenied, - psDevInfo->ui32ActivePMReqNonIdle, - psDevInfo->ui32ActivePMReqRetry, - psDevInfo->ui32ActivePMReqTotal - - psDevInfo->ui32ActivePMReqOk - - psDevInfo->ui32ActivePMReqDenied - - psDevInfo->ui32ActivePMReqRetry - - psDevInfo->ui32ActivePMReqNonIdle, - psDevInfo->ui32ActivePMReqTotal, - psRuntimeCfg->ui32ActivePMLatencyms); - - ui32NumClockSpeedChanges = (IMG_UINT32) OSAtomicRead(&psDevInfo->psDeviceNode->iNumClockSpeedChanges); - RGXGetTimeCorrData(psDevInfo->psDeviceNode, asTimeCorrs, ARRAY_SIZE(asTimeCorrs)); - - PVR_DUMPDEBUG_LOG("RGX DVFS: %u frequency changes. " - "Current frequency: %u.%03u MHz (sampled at %" IMG_UINT64_FMTSPEC " ns). " - "FW frequency: %u.%03u MHz.", - ui32NumClockSpeedChanges, - asTimeCorrs[0].ui32CoreClockSpeed / 1000000, - (asTimeCorrs[0].ui32CoreClockSpeed / 1000) % 1000, - asTimeCorrs[0].ui64OSTimeStamp, - psRuntimeCfg->ui32CoreClockSpeed / 1000000, - (psRuntimeCfg->ui32CoreClockSpeed / 1000) % 1000); - if (ui32NumClockSpeedChanges > 0) - { - PVR_DUMPDEBUG_LOG(" Previous frequencies: %u.%03u, %u.%03u, %u.%03u MHz (Sampled at " - "%" IMG_UINT64_FMTSPEC ", %" IMG_UINT64_FMTSPEC ", %" IMG_UINT64_FMTSPEC ")", - asTimeCorrs[1].ui32CoreClockSpeed / 1000000, - (asTimeCorrs[1].ui32CoreClockSpeed / 1000) % 1000, - asTimeCorrs[2].ui32CoreClockSpeed / 1000000, - (asTimeCorrs[2].ui32CoreClockSpeed / 1000) % 1000, - asTimeCorrs[3].ui32CoreClockSpeed / 1000000, - (asTimeCorrs[3].ui32CoreClockSpeed / 1000) % 1000, - asTimeCorrs[1].ui64OSTimeStamp, - asTimeCorrs[2].ui64OSTimeStamp, - asTimeCorrs[3].ui64OSTimeStamp); - } - - for (ui32OSid = 0; ui32OSid < RGX_NUM_OS_SUPPORTED; ui32OSid++) - { - RGXFWIF_OS_RUNTIME_FLAGS sFwRunFlags = psFwSysData->asOsRuntimeFlagsMirror[ui32OSid]; - - IMG_BOOL bMTSEnabled = (RGX_IS_BRN_SUPPORTED(psDevInfo, 64502) || !RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_VIRTUALISATION)) ? - IMG_TRUE : ((OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_SCHEDULE_ENABLE) & BIT(ui32OSid)) != 0); - - PVR_DUMPDEBUG_LOG("RGX FW OS %u - State: %s; Freelists: %s%s; Priority: %d;%s %s", ui32OSid, - apszFwOsStateName[sFwRunFlags.bfOsState], - (sFwRunFlags.bfFLOk) ? "Ok" : "Not Ok", - (sFwRunFlags.bfFLGrowPending) ? "; Grow Request Pending" : "", - psDevInfo->psRGXFWIfRuntimeCfg->aui32OSidPriority[ui32OSid], - (sFwRunFlags.bfIsolatedOS) ? " Isolated;" : "", - (bMTSEnabled) ? "MTS on;" : "MTS off;" - ); - - bOsIsolationEnabled |= sFwRunFlags.bfIsolatedOS; - } - -#if defined(PVR_ENABLE_PHR) - { - IMG_CHAR sPHRConfigDescription[RGX_DEBUG_STR_SIZE]; - - sPHRConfigDescription[0] = '\0'; - _Flags2Description(sPHRConfigDescription, RGX_DEBUG_STR_SIZE, - asPHRConfig2Description, ARRAY_SIZE(asPHRConfig2Description), - BIT_ULL(psDevInfo->psRGXFWIfRuntimeCfg->ui32PHRMode)); - - PVR_DUMPDEBUG_LOG("RGX PHR configuration: (%d) %s", psDevInfo->psRGXFWIfRuntimeCfg->ui32PHRMode, sPHRConfigDescription); - } -#endif - - if (bRGXPoweredON && RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { - if (OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MULTICORE_SYSTEM) > 1U) - { - PVR_DUMPDEBUG_LOG("RGX MC Configuration: 0x%X (1:primary, 0:secondary)", psFwSysData->ui32McConfig); - } - } - - if (bOsIsolationEnabled) - { - PVR_DUMPDEBUG_LOG("RGX Hard Context Switch deadline: %u ms", psDevInfo->psRGXFWIfRuntimeCfg->ui32HCSDeadlineMS); - } - - _RGXDumpFWAssert(pfnDumpDebugPrintf, pvDumpDebugFile, psRGXFWIfTraceBufCtl); - _RGXDumpFWFaults(pfnDumpDebugPrintf, pvDumpDebugFile, psFwSysData); - _RGXDumpFWPoll(pfnDumpDebugPrintf, pvDumpDebugFile, psFwSysData); - } - else - { - PVR_DUMPDEBUG_LOG("RGX FW State: Unavailable under Guest Mode of operation"); - PVR_DUMPDEBUG_LOG("RGX FW Power State: Unavailable under Guest Mode of operation"); - } - - _RGXDumpFWHWRInfo(pfnDumpDebugPrintf, pvDumpDebugFile, psFwSysData, psDevInfo->psRGXFWIfHWRInfoBufCtl, psDevInfo); - -#if defined(SUPPORT_RGXFW_STATS_FRAMEWORK) - /* Dump all non-zero values in lines of 8... */ - { - IMG_CHAR pszLine[(9*RGXFWIF_STATS_FRAMEWORK_LINESIZE)+1]; - const IMG_UINT32 *pui32FWStatsBuf = psFwSysData->aui32FWStatsBuf; - IMG_UINT32 ui32Index1, ui32Index2; - - PVR_DUMPDEBUG_LOG("STATS[START]: RGXFWIF_STATS_FRAMEWORK_MAX=%d", RGXFWIF_STATS_FRAMEWORK_MAX); - for (ui32Index1 = 0; ui32Index1 < RGXFWIF_STATS_FRAMEWORK_MAX; ui32Index1 += RGXFWIF_STATS_FRAMEWORK_LINESIZE) - { - IMG_UINT32 ui32OrOfValues = 0; - IMG_CHAR *pszBuf = pszLine; - - /* Print all values in this line and skip if all zero... */ - for (ui32Index2 = 0; ui32Index2 < RGXFWIF_STATS_FRAMEWORK_LINESIZE; ui32Index2++) - { - ui32OrOfValues |= pui32FWStatsBuf[ui32Index1+ui32Index2]; - OSSNPrintf(pszBuf, 9 + 1, " %08x", pui32FWStatsBuf[ui32Index1+ui32Index2]); - pszBuf += 9; /* write over the '\0' */ - } - - if (ui32OrOfValues != 0) - { - PVR_DUMPDEBUG_LOG("STATS[%08x]:%s", ui32Index1, pszLine); - } - } - PVR_DUMPDEBUG_LOG("STATS[END]"); - } -#endif -} - -static void _RGXDumpMetaSPExtraDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ -/* List of extra META Slave Port debug registers */ -#define RGX_META_SP_EXTRA_DEBUG \ - X(RGX_CR_META_SP_MSLVCTRL0) \ - X(RGX_CR_META_SP_MSLVCTRL1) \ - X(RGX_CR_META_SP_MSLVDATAX) \ - X(RGX_CR_META_SP_MSLVIRQSTATUS) \ - X(RGX_CR_META_SP_MSLVIRQENABLE) \ - X(RGX_CR_META_SP_MSLVIRQLEVEL) - - IMG_UINT32 ui32Idx, ui32RegIdx; - IMG_UINT32 ui32RegVal; - IMG_UINT32 ui32RegAddr; - - const IMG_UINT32 aui32DebugRegAddr[] = { -#define X(A) A, - RGX_META_SP_EXTRA_DEBUG -#undef X - }; - - const IMG_CHAR* apszDebugRegName[] = { -#define X(A) #A, - RGX_META_SP_EXTRA_DEBUG -#undef X - }; - - const IMG_UINT32 aui32Debug2RegAddr[] = {0xA28, 0x0A30, 0x0A38}; - - PVR_DUMPDEBUG_LOG("META Slave Port extra debug:"); - - /* dump first set of Slave Port debug registers */ - for (ui32Idx = 0; ui32Idx < sizeof(aui32DebugRegAddr)/sizeof(IMG_UINT32); ui32Idx++) - { - const IMG_CHAR* pszRegName = apszDebugRegName[ui32Idx]; - - ui32RegAddr = aui32DebugRegAddr[ui32Idx]; - ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr); - PVR_DUMPDEBUG_LOG(" * %s: 0x%8.8X", pszRegName, ui32RegVal); - } - - /* dump second set of Slave Port debug registers */ - for (ui32Idx = 0; ui32Idx < 4; ui32Idx++) - { - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, 0xA20, ui32Idx); - ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, 0xA20); - PVR_DUMPDEBUG_LOG(" * 0xA20[%d]: 0x%8.8X", ui32Idx, ui32RegVal); - - } - - for (ui32RegIdx = 0; ui32RegIdx < sizeof(aui32Debug2RegAddr)/sizeof(IMG_UINT32); ui32RegIdx++) - { - ui32RegAddr = aui32Debug2RegAddr[ui32RegIdx]; - for (ui32Idx = 0; ui32Idx < 2; ui32Idx++) - { - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr, ui32Idx); - ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr); - PVR_DUMPDEBUG_LOG(" * 0x%X[%d]: 0x%8.8X", ui32RegAddr, ui32Idx, ui32RegVal); - } - } - -} - -/* - * Array of all the Firmware Trace log IDs used to convert the trace data. - */ -typedef struct _TRACEBUF_LOG_ { - RGXFW_LOG_SFids eSFId; - const IMG_CHAR *pszName; - const IMG_CHAR *pszFmt; - IMG_UINT32 ui32ArgNum; -} TRACEBUF_LOG; - -static const TRACEBUF_LOG aLogDefinitions[] = -{ -#define X(a, b, c, d, e) {RGXFW_LOG_CREATESFID(a,b,e), #c, d, e}, - RGXFW_LOG_SFIDLIST -#undef X -}; - -#define NARGS_MASK ~(0xF<<16) -static IMG_BOOL _FirmwareTraceIntegrityCheck(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - const TRACEBUF_LOG *psLogDef = &aLogDefinitions[0]; - IMG_BOOL bIntegrityOk = IMG_TRUE; - - /* - * For every log ID, check the format string and number of arguments is valid. - */ - while (psLogDef->eSFId != RGXFW_SF_LAST) - { - const TRACEBUF_LOG *psLogDef2; - const IMG_CHAR *pszString; - IMG_UINT32 ui32Count; - - /* - * Check the number of arguments matches the number of '%' in the string and - * check that no string uses %s which is not supported as it requires a - * pointer to memory that is not going to be valid. - */ - pszString = psLogDef->pszFmt; - ui32Count = 0; - - while (*pszString != '\0') - { - if (*pszString++ == '%') - { - ui32Count++; - if (*pszString == 's') - { - bIntegrityOk = IMG_FALSE; - PVR_DUMPDEBUG_LOG("Integrity Check FAIL: %s has an unsupported type not recognized (fmt: %%%c). Please fix.", - psLogDef->pszName, *pszString); - } - else if (*pszString == '%') - { - /* Double % is a printable % sign and not a format string... */ - ui32Count--; - } - } - } - - if (ui32Count != psLogDef->ui32ArgNum) - { - bIntegrityOk = IMG_FALSE; - PVR_DUMPDEBUG_LOG("Integrity Check FAIL: %s has %d arguments but only %d are specified. Please fix.", - psLogDef->pszName, ui32Count, psLogDef->ui32ArgNum); - } - - /* RGXDumpFirmwareTrace() has a hardcoded limit of supporting up to 20 arguments... */ - if (ui32Count > 20) - { - bIntegrityOk = IMG_FALSE; - PVR_DUMPDEBUG_LOG("Integrity Check FAIL: %s has %d arguments but a maximum of 20 are supported. Please fix.", - psLogDef->pszName, ui32Count); - } - - /* Check the id number is unique (don't take into account the number of arguments) */ - ui32Count = 0; - psLogDef2 = &aLogDefinitions[0]; - - while (psLogDef2->eSFId != RGXFW_SF_LAST) - { - if ((psLogDef->eSFId & NARGS_MASK) == (psLogDef2->eSFId & NARGS_MASK)) - { - ui32Count++; - } - psLogDef2++; - } - - if (ui32Count != 1) - { - bIntegrityOk = IMG_FALSE; - PVR_DUMPDEBUG_LOG("Integrity Check FAIL: %s id %x is not unique, there are %d more. Please fix.", - psLogDef->pszName, psLogDef->eSFId, ui32Count - 1); - } - - /* Move to the next log ID... */ - psLogDef++; - } - - return bIntegrityOk; -} - -typedef struct { - IMG_UINT16 ui16Mask; - const IMG_CHAR *pszStr; -} RGXFWT_DEBUG_INFO_MSKSTR; /* pair of bit mask and debug info message string */ - - -/*! -******************************************************************************* - - @Function RGXPrepareExtraDebugInfo - - @Description - - Prepares debug info string by decoding ui16DebugInfo value passed - - @Input pszBuffer - pointer to debug info string buffer - - @Return void - -******************************************************************************/ -static void RGXPrepareExtraDebugInfo(IMG_CHAR *pszBuffer, IMG_UINT32 ui32BufferSize, IMG_UINT16 ui16DebugInfo) -{ - const RGXFWT_DEBUG_INFO_MSKSTR aDebugInfoMskStr[] = - { -#define X(a, b) {a, b}, - RGXFWT_DEBUG_INFO_MSKSTRLIST -#undef X - }; - - IMG_UINT32 ui32NumFields = sizeof(aDebugInfoMskStr)/sizeof(RGXFWT_DEBUG_INFO_MSKSTR); - IMG_UINT32 i; - IMG_BOOL bHasExtraDebugInfo = IMG_FALSE; - - /* Add prepend string */ - OSStringLCopy(pszBuffer, RGXFWT_DEBUG_INFO_STR_PREPEND, ui32BufferSize); - - /* Add debug info strings */ - for (i = 0; i < ui32NumFields; i++) - { - if (ui16DebugInfo & aDebugInfoMskStr[i].ui16Mask) - { - if (bHasExtraDebugInfo) - { - OSStringLCat(pszBuffer, ", ", ui32BufferSize); /* Add comma separator */ - } - OSStringLCat(pszBuffer, aDebugInfoMskStr[i].pszStr, ui32BufferSize); - bHasExtraDebugInfo = IMG_TRUE; - } - } - - /* Add append string */ - OSStringLCat(pszBuffer, RGXFWT_DEBUG_INFO_STR_APPEND, ui32BufferSize); -} - -void RGXDumpFirmwareTrace(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - static IMG_BOOL bIntegrityCheckPassed = IMG_FALSE; - - /* Check that the firmware trace is correctly defined... */ - if (!bIntegrityCheckPassed) - { - bIntegrityCheckPassed = _FirmwareTraceIntegrityCheck(pfnDumpDebugPrintf, pvDumpDebugFile); - if (!bIntegrityCheckPassed) - { - return; - } - } - - /* Dump FW trace information... */ - if (psRGXFWIfTraceBufCtl != NULL) - { - IMG_UINT32 tid; - IMG_UINT32 ui32TraceBufSizeInDWords = psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords; - - PVR_DUMPDEBUG_LOG("Device ID: %u", psDevInfo->psDeviceNode->sDevId.ui32InternalID); - - /* Print the log type settings... */ - if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK) - { - PVR_DUMPDEBUG_LOG("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")", - ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")), - RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType) - ); - } - else - { - PVR_DUMPDEBUG_LOG("Debug log type: none"); - } - - /* Print the decoded log for each thread... */ - for (tid = 0; tid < RGXFW_THREAD_NUM; tid++) - { - volatile IMG_UINT32 *pui32FWWrapCount = &(psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.ui32LineNum); - volatile IMG_UINT32 *pui32FWTracePtr = &(psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer); - IMG_UINT32 *pui32TraceBuf = psRGXFWIfTraceBufCtl->sTraceBuf[tid].pui32TraceBuffer; - IMG_UINT32 ui32HostWrapCount = *pui32FWWrapCount; - IMG_UINT32 ui32HostTracePtr = *pui32FWTracePtr; - IMG_UINT32 ui32Count = 0; - - if (pui32TraceBuf == NULL) - { - /* trace buffer not yet allocated */ - continue; - } - - while (ui32Count < ui32TraceBufSizeInDWords) - { - IMG_UINT32 ui32Data, ui32DataToId; - - /* Find the first valid log ID, skipping whitespace... */ - do - { - ui32Data = pui32TraceBuf[ui32HostTracePtr]; - ui32DataToId = idToStringID(ui32Data, SFs); - - /* If an unrecognized id is found it may be inconsistent data or a firmware trace error. */ - if (ui32DataToId == RGXFW_SF_LAST && RGXFW_LOG_VALIDID(ui32Data)) - { - PVR_DUMPDEBUG_LOG("WARNING: Unrecognized id (%x). From here on the trace might be wrong!", ui32Data); - } - - /* Update the trace pointer... */ - ui32HostTracePtr++; - if (ui32HostTracePtr >= ui32TraceBufSizeInDWords) - { - ui32HostTracePtr = 0; - ui32HostWrapCount++; - } - ui32Count++; - } while ((RGXFW_SF_LAST == ui32DataToId) && - ui32Count < ui32TraceBufSizeInDWords); - - if (ui32Count < ui32TraceBufSizeInDWords) - { - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN] = "%" IMG_UINT64_FMTSPEC ":T%u-%s> "; - IMG_CHAR szDebugInfoBuffer[RGXFWT_DEBUG_INFO_STR_MAXLEN] = ""; - IMG_UINT64 ui64Timestamp; - IMG_UINT16 ui16DebugInfo; - - /* If we hit the ASSERT message then this is the end of the log... */ - if (ui32Data == RGXFW_SF_MAIN_ASSERT_FAILED) - { - PVR_DUMPDEBUG_LOG("ASSERTION %s failed at %s:%u", - psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szInfo, - psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szPath, - psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.ui32LineNum); - break; - } - - ui64Timestamp = (IMG_UINT64)(pui32TraceBuf[(ui32HostTracePtr + 0) % ui32TraceBufSizeInDWords]) << 32 | - (IMG_UINT64)(pui32TraceBuf[(ui32HostTracePtr + 1) % ui32TraceBufSizeInDWords]); - - ui16DebugInfo = (IMG_UINT16) ((ui64Timestamp & ~RGXFWT_TIMESTAMP_DEBUG_INFO_CLRMSK) >> RGXFWT_TIMESTAMP_DEBUG_INFO_SHIFT); - ui64Timestamp = (ui64Timestamp & ~RGXFWT_TIMESTAMP_TIME_CLRMSK) >> RGXFWT_TIMESTAMP_TIME_SHIFT; - - /* - * Print the trace string and provide up to 20 arguments which - * printf function will be able to use. We have already checked - * that no string uses more than this. - */ - OSStringLCat(szBuffer, SFs[ui32DataToId].psName, PVR_MAX_DEBUG_MESSAGE_LEN); - - /* Check and append any extra debug info available */ - if (ui16DebugInfo) - { - /* Prepare debug info string */ - RGXPrepareExtraDebugInfo(szDebugInfoBuffer, RGXFWT_DEBUG_INFO_STR_MAXLEN, ui16DebugInfo); - - /* Append debug info string */ - OSStringLCat(szBuffer, szDebugInfoBuffer, PVR_MAX_DEBUG_MESSAGE_LEN); - } - - PVR_DUMPDEBUG_LOG(szBuffer, ui64Timestamp, tid, groups[RGXFW_SF_GID(ui32Data)], - pui32TraceBuf[(ui32HostTracePtr + 2) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 3) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 4) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 5) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 6) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 7) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 8) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 9) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 10) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 11) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 12) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 13) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 14) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 15) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 16) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 17) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 18) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 19) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 20) % ui32TraceBufSizeInDWords], - pui32TraceBuf[(ui32HostTracePtr + 21) % ui32TraceBufSizeInDWords]); - - /* Update the trace pointer... */ - ui32HostTracePtr = ui32HostTracePtr + 2 + RGXFW_SF_PARAMNUM(ui32Data); - if (ui32HostTracePtr >= ui32TraceBufSizeInDWords) - { - ui32HostTracePtr = ui32HostTracePtr % ui32TraceBufSizeInDWords; - ui32HostWrapCount++; - } - ui32Count = (ui32Count + 2 + RGXFW_SF_PARAMNUM(ui32Data)); - - /* Has the FW trace buffer overtaken the host pointer during the last line printed??? */ - if ((*pui32FWWrapCount > ui32HostWrapCount) || - ((*pui32FWWrapCount == ui32HostWrapCount) && (*pui32FWTracePtr > ui32HostTracePtr))) - { - /* Move forward to the oldest entry again... */ - PVR_DUMPDEBUG_LOG(". . ."); - ui32HostWrapCount = *pui32FWWrapCount; - ui32HostTracePtr = *pui32FWTracePtr; - } - } - } - } - } -} - -#if defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS) -void RGXDumpPowerMonitoring(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - - /* Print the power monitoring counters... */ - if (psFwSysData != NULL) - { - const IMG_UINT32 *pui32TraceBuf = psFwSysData->sPowerMonBuf.pui32TraceBuffer; - IMG_UINT32 ui32TracePtr = 0; //psFwSysData->sPowerMonBuf.ui32TracePointer; - IMG_UINT32 ui32PowerMonBufSizeInDWords = psFwSysData->ui32PowerMonBufSizeInDWords; - IMG_UINT32 ui32Count = 0; - IMG_UINT64 ui64Timestamp; - - if (pui32TraceBuf == NULL) - { - /* power monitoring buffer not yet allocated */ - return; - } - - if (pui32TraceBuf[ui32TracePtr] != RGX_CR_TIMER) - { - PVR_DPF((PVR_DBG_WARNING, "Power monitoring data not available.")); - return; - } - ui64Timestamp = (IMG_UINT64)(pui32TraceBuf[(ui32TracePtr + 1) % ui32PowerMonBufSizeInDWords]) << 32 | - (IMG_UINT64)(pui32TraceBuf[(ui32TracePtr + 2) % ui32PowerMonBufSizeInDWords]); - - /* Update the trace pointer... */ - ui32TracePtr = (ui32TracePtr + 3) % ui32PowerMonBufSizeInDWords; - ui32Count = (ui32Count + 3); - - PVR_DPF((PVR_DBG_WARNING, "Dumping power monitoring buffer: CPUVAddr = %p, pointer = 0x%x, size = 0x%x", - pui32TraceBuf, - ui32TracePtr, - ui32PowerMonBufSizeInDWords)); - - while (ui32Count < ui32PowerMonBufSizeInDWords) - { - /* power monitoring data is (register, value) dword pairs */ - PVR_DUMPDEBUG_LOG("%" IMG_UINT64_FMTSPEC ":POWMON 0x%08x 0x%08x 0x%08x 0x%08x", - ui64Timestamp, - pui32TraceBuf[(ui32TracePtr + 0) % ui32PowerMonBufSizeInDWords], - pui32TraceBuf[(ui32TracePtr + 1) % ui32PowerMonBufSizeInDWords], - pui32TraceBuf[(ui32TracePtr + 2) % ui32PowerMonBufSizeInDWords], - pui32TraceBuf[(ui32TracePtr + 3) % ui32PowerMonBufSizeInDWords]); - - if (pui32TraceBuf[(ui32TracePtr + 0) % ui32PowerMonBufSizeInDWords] == RGXFWIF_TIMEDIFF_ID || - pui32TraceBuf[(ui32TracePtr + 2) % ui32PowerMonBufSizeInDWords] == RGXFWIF_TIMEDIFF_ID) - { - /* end of buffer */ - break; - } - - /* Update the trace pointer... */ - ui32TracePtr = (ui32TracePtr + 4) % ui32PowerMonBufSizeInDWords; - ui32Count = (ui32Count + 4); - } - } -} -#endif - -static const IMG_CHAR *_RGXGetDebugDevStateString(PVRSRV_DEVICE_STATE eDevState) -{ - switch (eDevState) - { - case PVRSRV_DEVICE_STATE_INIT: - return "Initialising"; - case PVRSRV_DEVICE_STATE_ACTIVE: - return "Active"; - case PVRSRV_DEVICE_STATE_DEINIT: - return "De-initialising"; - case PVRSRV_DEVICE_STATE_BAD: - return "Bad"; - case PVRSRV_DEVICE_STATE_UNDEFINED: - PVR_ASSERT(!"Device has undefined state"); - fallthrough; - default: - return "Unknown"; - } -} - -static const IMG_CHAR* _RGXGetDebugDevPowerStateString(PVRSRV_DEV_POWER_STATE ePowerState) -{ - switch (ePowerState) - { - case PVRSRV_DEV_POWER_STATE_DEFAULT: return "DEFAULT"; - case PVRSRV_DEV_POWER_STATE_OFF: return "OFF"; - case PVRSRV_DEV_POWER_STATE_ON: return "ON"; - default: return "UNKNOWN"; - } -} - -/* Helper macros to emit data */ -#define REG32_FMTSPEC "%-30s: 0x%08X" -#define REG64_FMTSPEC "%-30s: 0x%016" IMG_UINT64_FMTSPECx -#define DDLOG32(R) PVR_DUMPDEBUG_LOG(REG32_FMTSPEC, #R, OSReadHWReg32(pvRegsBaseKM, RGX_CR_##R)); -#define DDLOG64(R) PVR_DUMPDEBUG_LOG(REG64_FMTSPEC, #R, OSReadHWReg64(pvRegsBaseKM, RGX_CR_##R)); -#define DDLOG32_DPX(R) PVR_DUMPDEBUG_LOG(REG32_FMTSPEC, #R, OSReadHWReg32(pvRegsBaseKM, DPX_CR_##R)); -#define DDLOG64_DPX(R) PVR_DUMPDEBUG_LOG(REG64_FMTSPEC, #R, OSReadHWReg64(pvRegsBaseKM, DPX_CR_##R)); -#define DDLOGVAL32(S,V) PVR_DUMPDEBUG_LOG(REG32_FMTSPEC, S, V); - -#if !defined(SUPPORT_TRUSTED_DEVICE) -#if !defined(NO_HARDWARE) -static void RGXDumpMIPSState(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - RGX_MIPS_STATE sMIPSState = {0}; - PVRSRV_ERROR eError; - - eError = _RGXMipsExtraDebug(psDevInfo, &sMIPSState); - PVR_DUMPDEBUG_LOG("---- [ MIPS internal state ] ----"); - if (eError != PVRSRV_OK) - { - PVR_DUMPDEBUG_LOG("MIPS extra debug not available"); - } - else - { - DDLOGVAL32("PC", sMIPSState.ui32ErrorEPC); - DDLOGVAL32("STATUS_REGISTER", sMIPSState.ui32StatusRegister); - DDLOGVAL32("CAUSE_REGISTER", sMIPSState.ui32CauseRegister); - _RGXMipsDumpCauseDecode(pfnDumpDebugPrintf, pvDumpDebugFile, - sMIPSState.ui32CauseRegister, sMIPSState.ui32ErrorState); - DDLOGVAL32("BAD_REGISTER", sMIPSState.ui32BadRegister); - DDLOGVAL32("EPC", sMIPSState.ui32EPC); - DDLOGVAL32("SP", sMIPSState.ui32SP); - DDLOGVAL32("BAD_INSTRUCTION", sMIPSState.ui32BadInstr); - _RGXMipsDumpDebugDecode(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, - sMIPSState.ui32Debug, sMIPSState.ui32DEPC); - - { - IMG_UINT32 ui32Idx; - - IMG_BOOL bCheckBRN63553WA = - RGX_IS_BRN_SUPPORTED(psDevInfo, 63553) && - (OSReadHWReg32(pvRegsBaseKM, RGX_CR_MIPS_ADDR_REMAP5_CONFIG1) == (0x0 | RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_EN)); - - IMG_BOOL bUseRemapRanges = RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) > 32; - - PVR_DUMPDEBUG_LOG("TLB :"); - - for (ui32Idx = 0; ui32Idx < ARRAY_SIZE(sMIPSState.asTLB); ui32Idx++) - { - RGX_MIPS_REMAP_ENTRY *psRemapEntry0 = NULL; - RGX_MIPS_REMAP_ENTRY *psRemapEntry1 = NULL; - - if (bUseRemapRanges) - { - psRemapEntry0 = &sMIPSState.asRemap[ui32Idx]; - psRemapEntry1 = &sMIPSState.asRemap[ui32Idx+16]; - } - - _RGXMipsDumpTLBEntry(pfnDumpDebugPrintf, - pvDumpDebugFile, - &sMIPSState.asTLB[ui32Idx], - psRemapEntry0, - psRemapEntry1, - ui32Idx); - - if (bCheckBRN63553WA) - { - const RGX_MIPS_TLB_ENTRY *psTLBEntry = &sMIPSState.asTLB[ui32Idx]; - - #define BRN63553_TLB_IS_NUL(X) (((X) & RGXMIPSFW_TLB_VALID) && (RGXMIPSFW_TLB_GET_PA(X) == 0x0)) - - if (BRN63553_TLB_IS_NUL(psTLBEntry->ui32TLBLo0) || BRN63553_TLB_IS_NUL(psTLBEntry->ui32TLBLo1)) - { - PVR_DUMPDEBUG_LOG("BRN63553 WA present with a valid TLB entry mapping address 0x0."); - } - } - } - - /* This implicitly also checks for overlaps between memory and regbank addresses */ - _CheckMipsTLBDuplicatePAs(pfnDumpDebugPrintf, - pvDumpDebugFile, - sMIPSState.asTLB, - bUseRemapRanges ? sMIPSState.asRemap : NULL); - - if (bUseRemapRanges) - { - /* Dump unmapped address if it was dumped in FW, otherwise it will be 0 */ - if (sMIPSState.ui32UnmappedAddress) - { - PVR_DUMPDEBUG_LOG("Remap unmapped address => 0x%08X", - sMIPSState.ui32UnmappedAddress); - } - } - } - - /* Check FW code corruption in case of known errors */ - if (_IsFWCodeException(RGXMIPSFW_C0_CAUSE_EXCCODE(sMIPSState.ui32CauseRegister))) - { - eError = _ValidateFWImage(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DUMPDEBUG_LOG("Failed to validate any FW code corruption"); - } - } - } - PVR_DUMPDEBUG_LOG("--------------------------------"); -} -#endif -#endif /* !defined(SUPPORT_TRUSTED_DEVICE) */ - -static PVRSRV_ERROR RGXDumpRISCVState(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - RGXRISCVFW_STATE sRiscvState; - const IMG_CHAR *pszException; - PVRSRV_ERROR eError; - - DDLOG64(FWCORE_MEM_CAT_BASE0); - DDLOG64(FWCORE_MEM_CAT_BASE1); - DDLOG64(FWCORE_MEM_CAT_BASE2); - DDLOG64(FWCORE_MEM_CAT_BASE3); - DDLOG64(FWCORE_MEM_CAT_BASE4); - DDLOG64(FWCORE_MEM_CAT_BASE5); - DDLOG64(FWCORE_MEM_CAT_BASE6); - DDLOG64(FWCORE_MEM_CAT_BASE7); - - /* Limit dump to what is currently being used */ - DDLOG64(FWCORE_ADDR_REMAP_CONFIG4); - DDLOG64(FWCORE_ADDR_REMAP_CONFIG5); - DDLOG64(FWCORE_ADDR_REMAP_CONFIG6); - DDLOG64(FWCORE_ADDR_REMAP_CONFIG12); - DDLOG64(FWCORE_ADDR_REMAP_CONFIG13); - DDLOG64(FWCORE_ADDR_REMAP_CONFIG14); - - DDLOG32(FWCORE_MEM_FAULT_MMU_STATUS); - DDLOG64(FWCORE_MEM_FAULT_REQ_STATUS); - DDLOG32(FWCORE_MEM_MMU_STATUS); - DDLOG32(FWCORE_MEM_READS_EXT_STATUS); - DDLOG32(FWCORE_MEM_READS_INT_STATUS); - - PVR_DUMPDEBUG_LOG("---- [ RISC-V internal state ] ----"); - -#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB) - if (RGXRiscvIsHalted(psDevInfo)) - { - /* Avoid resuming the RISC-V FW as most operations - * on the debug module require a halted core */ - PVR_DUMPDEBUG_LOG("(skipping as RISC-V found halted)"); - return PVRSRV_OK; - } -#endif - - eError = RGXRiscvHalt(psDevInfo); - PVR_GOTO_IF_ERROR(eError, _RISCVDMError); - -#define X(name, address) \ - eError = RGXRiscvReadReg(psDevInfo, address, &sRiscvState.name); \ - PVR_LOG_GOTO_IF_ERROR(eError, "RGXRiscvReadReg", _RISCVDMError); \ - DDLOGVAL32(#name, sRiscvState.name); - - RGXRISCVFW_DEBUG_DUMP_REGISTERS -#undef X - - eError = RGXRiscvResume(psDevInfo); - PVR_GOTO_IF_ERROR(eError, _RISCVDMError); - - pszException = _GetRISCVException(sRiscvState.mcause); - if (pszException != NULL) - { - PVR_DUMPDEBUG_LOG("RISC-V FW hit an exception: %s", pszException); - - eError = _ValidateFWImage(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DUMPDEBUG_LOG("Failed to validate any FW code corruption"); - } - } - - return PVRSRV_OK; - -_RISCVDMError: - PVR_DPF((PVR_DBG_ERROR, "Failed to communicate with the Debug Module")); - - return eError; -} - -PVRSRV_ERROR RGXDumpRGXRegisters(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32Meta = (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) ? RGX_GET_FEATURE_VALUE(psDevInfo, META) : 0; - IMG_UINT32 ui32TACycles, ui323DCycles, ui32TAOr3DCycles, ui32TAAnd3DCycles; - IMG_UINT32 ui32RegVal; - IMG_BOOL bFirmwarePerf; - IMG_BOOL bS7Infra = RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE); - IMG_BOOL bMulticore = RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT); - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - PVRSRV_ERROR eError; - - PVR_DUMPDEBUG_LOG("------[ RGX registers ]------"); - PVR_DUMPDEBUG_LOG("RGX Register Base Address (Linear): 0x%p", psDevInfo->pvRegsBaseKM); - PVR_DUMPDEBUG_LOG("RGX Register Base Address (Physical): 0x%08lX", (unsigned long)psDevInfo->sRegsPhysBase.uiAddr); - - /* Check if firmware perf was set at Init time */ - bFirmwarePerf = (psDevInfo->psRGXFWIfSysInit->eFirmwarePerf != FW_PERF_CONF_NONE); - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PBVNC_COREID_REG)) - { - DDLOG64(CORE_ID); - } - else - { - DDLOG32(CORE_ID); - } - DDLOG32(CORE_REVISION); - DDLOG32(DESIGNER_REV_FIELD1); - DDLOG32(DESIGNER_REV_FIELD2); - DDLOG64(CHANGESET_NUMBER); - if (ui32Meta) - { - DDLOG32(META_SP_MSLVIRQSTATUS); - } - - if (bMulticore) - { - DDLOG32(MULTICORE_SYSTEM); - DDLOG32(MULTICORE_GPU); - } - - DDLOG64(CLK_CTRL); - DDLOG64(CLK_STATUS); - DDLOG64(CLK_CTRL2); - DDLOG64(CLK_STATUS2); - - if (bS7Infra) - { - DDLOG64(CLK_XTPLUS_CTRL); - DDLOG64(CLK_XTPLUS_STATUS); - } - DDLOG32(EVENT_STATUS); - DDLOG64(TIMER); - if (bS7Infra) - { - DDLOG64(MMU_FAULT_STATUS); - DDLOG64(MMU_FAULT_STATUS_META); - } - else - { - DDLOG32(BIF_FAULT_BANK0_MMU_STATUS); - DDLOG64(BIF_FAULT_BANK0_REQ_STATUS); - DDLOG32(BIF_FAULT_BANK1_MMU_STATUS); - DDLOG64(BIF_FAULT_BANK1_REQ_STATUS); - } - DDLOG32(BIF_MMU_STATUS); - DDLOG32(BIF_MMU_ENTRY); - DDLOG64(BIF_MMU_ENTRY_STATUS); - - if (bS7Infra) - { - DDLOG32(BIF_JONES_OUTSTANDING_READ); - DDLOG32(BIF_BLACKPEARL_OUTSTANDING_READ); - DDLOG32(BIF_DUST_OUTSTANDING_READ); - } - else - { - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, XT_TOP_INFRASTRUCTURE))) - { - DDLOG32(BIF_STATUS_MMU); - DDLOG32(BIF_READS_EXT_STATUS); - DDLOG32(BIF_READS_INT_STATUS); - } - DDLOG32(BIFPM_STATUS_MMU); - DDLOG32(BIFPM_READS_EXT_STATUS); - DDLOG32(BIFPM_READS_INT_STATUS); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_VIVT)) - { - DDLOG64(CONTEXT_MAPPING0); - DDLOG64(CONTEXT_MAPPING1); - DDLOG64(CONTEXT_MAPPING2); - DDLOG64(CONTEXT_MAPPING3); - DDLOG64(CONTEXT_MAPPING4); - } - else - { - DDLOG64(BIF_CAT_BASE_INDEX); - DDLOG64(BIF_CAT_BASE0); - DDLOG64(BIF_CAT_BASE1); - DDLOG64(BIF_CAT_BASE2); - DDLOG64(BIF_CAT_BASE3); - DDLOG64(BIF_CAT_BASE4); - DDLOG64(BIF_CAT_BASE5); - DDLOG64(BIF_CAT_BASE6); - DDLOG64(BIF_CAT_BASE7); - } - - DDLOG32(BIF_CTRL_INVAL); - DDLOG32(BIF_CTRL); - - DDLOG64(BIF_PM_CAT_BASE_VCE0); - DDLOG64(BIF_PM_CAT_BASE_TE0); - DDLOG64(BIF_PM_CAT_BASE_ALIST0); - DDLOG64(BIF_PM_CAT_BASE_VCE1); - DDLOG64(BIF_PM_CAT_BASE_TE1); - DDLOG64(BIF_PM_CAT_BASE_ALIST1); - - if (bMulticore) - { - DDLOG32(MULTICORE_GEOMETRY_CTRL_COMMON); - DDLOG32(MULTICORE_FRAGMENT_CTRL_COMMON); - DDLOG32(MULTICORE_COMPUTE_CTRL_COMMON); - } - - DDLOG32(PERF_TA_PHASE); - DDLOG32(PERF_TA_CYCLE); - DDLOG32(PERF_3D_PHASE); - DDLOG32(PERF_3D_CYCLE); - - ui32TACycles = OSReadHWReg32(pvRegsBaseKM, RGX_CR_PERF_TA_CYCLE); - ui323DCycles = OSReadHWReg32(pvRegsBaseKM, RGX_CR_PERF_3D_CYCLE); - ui32TAOr3DCycles = OSReadHWReg32(pvRegsBaseKM, RGX_CR_PERF_TA_OR_3D_CYCLE); - ui32TAAnd3DCycles = ((ui32TACycles + ui323DCycles) > ui32TAOr3DCycles) ? (ui32TACycles + ui323DCycles - ui32TAOr3DCycles) : 0; - DDLOGVAL32("PERF_TA_OR_3D_CYCLE", ui32TAOr3DCycles); - DDLOGVAL32("PERF_TA_AND_3D_CYCLE", ui32TAAnd3DCycles); - - DDLOG32(PERF_COMPUTE_PHASE); - DDLOG32(PERF_COMPUTE_CYCLE); - - DDLOG32(PM_PARTIAL_RENDER_ENABLE); - - DDLOG32(ISP_RENDER); - DDLOG64(TLA_STATUS); - DDLOG64(MCU_FENCE); - - DDLOG32(VDM_CONTEXT_STORE_STATUS); - DDLOG64(VDM_CONTEXT_STORE_TASK0); - DDLOG64(VDM_CONTEXT_STORE_TASK1); - DDLOG64(VDM_CONTEXT_STORE_TASK2); - DDLOG64(VDM_CONTEXT_RESUME_TASK0); - DDLOG64(VDM_CONTEXT_RESUME_TASK1); - DDLOG64(VDM_CONTEXT_RESUME_TASK2); - - DDLOG32(ISP_CTL); - DDLOG32(ISP_STATUS); - DDLOG32(MTS_INTCTX); - DDLOG32(MTS_BGCTX); - DDLOG32(MTS_BGCTX_COUNTED_SCHEDULE); - DDLOG32(MTS_SCHEDULE); - DDLOG32(MTS_GPU_INT_STATUS); - - DDLOG32(CDM_CONTEXT_STORE_STATUS); - DDLOG64(CDM_CONTEXT_PDS0); - DDLOG64(CDM_CONTEXT_PDS1); - DDLOG64(CDM_TERMINATE_PDS); - DDLOG64(CDM_TERMINATE_PDS1); - - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 47025)) - { - DDLOG64(CDM_CONTEXT_LOAD_PDS0); - DDLOG64(CDM_CONTEXT_LOAD_PDS1); - } - - if (bS7Infra) - { - DDLOG32(JONES_IDLE); - } - - DDLOG32(SIDEKICK_IDLE); - - if (!bS7Infra) - { - DDLOG32(SLC_IDLE); - DDLOG32(SLC_STATUS0); - DDLOG64(SLC_STATUS1); - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, SLC_BANKS) && RGX_GET_FEATURE_VALUE(psDevInfo, SLC_BANKS)) - { - DDLOG64(SLC_STATUS2); - } - - DDLOG32(SLC_CTRL_BYPASS); - DDLOG64(SLC_CTRL_MISC); - } - else - { - DDLOG32(SLC3_IDLE); - DDLOG64(SLC3_STATUS); - DDLOG32(SLC3_FAULT_STOP_STATUS); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, ROGUEXE) && - RGX_IS_FEATURE_SUPPORTED(psDevInfo, WATCHDOG_TIMER)) - { - DDLOG32(SAFETY_EVENT_STATUS__ROGUEXE); - DDLOG32(MTS_SAFETY_EVENT_ENABLE__ROGUEXE); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, WATCHDOG_TIMER)) - { - DDLOG32(FWCORE_WDT_CTRL); - } - - if (PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0) - { - DDLOG32(SCRATCH0); - DDLOG32(SCRATCH1); - DDLOG32(SCRATCH2); - DDLOG32(SCRATCH3); - DDLOG32(SCRATCH4); - DDLOG32(SCRATCH5); - DDLOG32(SCRATCH6); - DDLOG32(SCRATCH7); - DDLOG32(SCRATCH8); - DDLOG32(SCRATCH9); - DDLOG32(SCRATCH10); - DDLOG32(SCRATCH11); - DDLOG32(SCRATCH12); - DDLOG32(SCRATCH13); - DDLOG32(SCRATCH14); - DDLOG32(SCRATCH15); - } - - if (ui32Meta) - { - IMG_BOOL bIsT0Enabled = IMG_FALSE, bIsFWFaulted = IMG_FALSE; - - /* Forcing bit 6 of MslvCtrl1 to 0 to avoid internal reg read going through the core */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x0); - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T0ENABLE_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T0 TXENABLE", ui32RegVal); - if (ui32RegVal & META_CR_TXENABLE_ENABLE_BIT) - { - bIsT0Enabled = IMG_TRUE; - } - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T0STATUS_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T0 TXSTATUS", ui32RegVal); - - /* check for FW fault */ - if (((ui32RegVal >> 20) & 0x3) == 0x2) - { - bIsFWFaulted = IMG_TRUE; - } - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T0DEFR_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T0 TXDEFR", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR0_PC, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T0 PC", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR0_PCX, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T0 PCX", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR0_SP, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T0 SP", ui32RegVal); - - if ((ui32Meta == MTP218) || (ui32Meta == MTP219)) - { - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T1ENABLE_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T1 TXENABLE", ui32RegVal); - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T1STATUS_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T1 TXSTATUS", ui32RegVal); - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T1DEFR_OFFSET, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("T1 TXDEFR", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR1_PC, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T1 PC", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR1_PCX, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T1 PCX", ui32RegVal); - - eError = RGXReadMetaCoreReg(psDevInfo, META_CR_THR1_SP, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadMetaCoreReg", _METASPError); - DDLOGVAL32("T1 SP", ui32RegVal); - } - - if (bFirmwarePerf) - { - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_PERF_COUNT0, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("PERF_COUNT0", ui32RegVal); - - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_PERF_COUNT1, &ui32RegVal); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXReadFWModuleAddr", _METASPError); - DDLOGVAL32("PERF_COUNT1", ui32RegVal); - } - - if (bIsT0Enabled & bIsFWFaulted) - { - eError = _ValidateFWImage(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DUMPDEBUG_LOG("Failed to validate any FW code corruption"); - } - } - else if (bIsFWFaulted) - { - PVR_DUMPDEBUG_LOG("Skipping FW code memory corruption checking as META is disabled"); - } - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - DDLOG32(MIPS_ADDR_REMAP1_CONFIG1); - DDLOG64(MIPS_ADDR_REMAP1_CONFIG2); - DDLOG32(MIPS_ADDR_REMAP2_CONFIG1); - DDLOG64(MIPS_ADDR_REMAP2_CONFIG2); - DDLOG32(MIPS_ADDR_REMAP3_CONFIG1); - DDLOG64(MIPS_ADDR_REMAP3_CONFIG2); - DDLOG32(MIPS_ADDR_REMAP4_CONFIG1); - DDLOG64(MIPS_ADDR_REMAP4_CONFIG2); - DDLOG32(MIPS_ADDR_REMAP5_CONFIG1); - DDLOG64(MIPS_ADDR_REMAP5_CONFIG2); - DDLOG64(MIPS_WRAPPER_CONFIG); - DDLOG32(MIPS_EXCEPTION_STATUS); - -#if defined(SUPPORT_TRUSTED_DEVICE) - PVR_DUMPDEBUG_LOG("MIPS extra debug not available with SUPPORT_TRUSTED_DEVICE."); -#elif !defined(NO_HARDWARE) - RGXDumpMIPSState(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); -#endif - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - eError = RGXDumpRISCVState(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - PVR_RETURN_IF_ERROR(eError); - } - - return PVRSRV_OK; - -_METASPError: - PVR_DUMPDEBUG_LOG("Dump Slave Port debug information"); - _RGXDumpMetaSPExtraDebugInfo(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - - return eError; -} - -#undef REG32_FMTSPEC -#undef REG64_FMTSPEC -#undef DDLOG32 -#undef DDLOG64 -#undef DDLOG32_DPX -#undef DDLOG64_DPX -#undef DDLOGVAL32 - -/*! -******************************************************************************* - - @Function RGXDebugRequestProcess - - @Description - - This function will print out the debug for the specified level of verbosity - - @Input pfnDumpDebugPrintf - Optional replacement print function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - @Input ui32VerbLevel - Verbosity level - - @Return void - -******************************************************************************/ -static -void RGXDebugRequestProcess(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32VerbLevel) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - PVRSRV_DEV_POWER_STATE ePowerState; - IMG_BOOL bRGXPoweredON; - IMG_UINT8 ui8FwOsCount; - RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - const RGXFWIF_OSDATA *psFwOsData = psDevInfo->psRGXFWIfFwOsData; - IMG_BOOL bPwrLockAlreadyHeld; - - bPwrLockAlreadyHeld = PVRSRVPwrLockIsLockedByMe(psDeviceNode); - if (!bPwrLockAlreadyHeld) - { - /* Only acquire the power-lock if not already held by the calling context */ - eError = PVRSRVPowerLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to acquire lock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return; - } - } - - ui8FwOsCount = psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.sInitOptions.ui8OsCountSupport; - - eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error retrieving RGX power state. No debug info dumped.", - __func__)); - goto Exit; - } - - if ((PVRSRV_VZ_MODE_IS(NATIVE) && (ui8FwOsCount > 1)) || - (PVRSRV_VZ_MODE_IS(HOST) && (ui8FwOsCount != RGX_NUM_OS_SUPPORTED))) - { - PVR_DUMPDEBUG_LOG("Mismatch between the number of Operating Systems supported by KM driver (%d) and FW (%d)", - (PVRSRV_VZ_MODE_IS(NATIVE)) ? (1) : (RGX_NUM_OS_SUPPORTED), ui8FwOsCount); - } - - PVR_DUMPDEBUG_LOG("------[ RGX Device ID:%d Start ]------", psDevInfo->psDeviceNode->sDevId.ui32InternalID); - - bRGXPoweredON = (ePowerState == PVRSRV_DEV_POWER_STATE_ON); - - PVR_DUMPDEBUG_LOG("------[ RGX Info ]------"); - PVR_DUMPDEBUG_LOG("Device Node (Info): %p (%p)", psDevInfo->psDeviceNode, psDevInfo); - PVR_DUMPDEBUG_LOG("RGX BVNC: %d.%d.%d.%d (%s)", psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C, - PVR_ARCH_NAME); - PVR_DUMPDEBUG_LOG("RGX Device State: %s", _RGXGetDebugDevStateString(psDeviceNode->eDevState)); - PVR_DUMPDEBUG_LOG("RGX Power State: %s", _RGXGetDebugDevPowerStateString(ePowerState)); - if (psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated) - { - PVR_DUMP_FIRMWARE_INFO(psDevInfo->psRGXFWIfOsInit->sRGXCompChecks); - } - else - { - PVR_DUMPDEBUG_LOG("FW info: UNINITIALIZED"); - } - - RGXDumpRGXDebugSummary(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, bRGXPoweredON); - - /* Dump out the kernel CCB. */ - { - const RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl; - - if (psKCCBCtl != NULL) - { - PVR_DUMPDEBUG_LOG("RGX Kernel CCB WO:0x%X RO:0x%X", - psKCCBCtl->ui32WriteOffset, - psKCCBCtl->ui32ReadOffset); - } - } - - /* Dump out the firmware CCB. */ - { - const RGXFWIF_CCB_CTL *psFCCBCtl = psDevInfo->psFirmwareCCBCtl; - - if (psFCCBCtl != NULL) - { - PVR_DUMPDEBUG_LOG("RGX Firmware CCB WO:0x%X RO:0x%X", - psFCCBCtl->ui32WriteOffset, - psFCCBCtl->ui32ReadOffset); - } - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Dump out the Workload estimation CCB. */ - { - const RGXFWIF_CCB_CTL *psWorkEstCCBCtl = psDevInfo->psWorkEstFirmwareCCBCtl; - - if (psWorkEstCCBCtl != NULL) - { - PVR_DUMPDEBUG_LOG("RGX WorkEst CCB WO:0x%X RO:0x%X", - psWorkEstCCBCtl->ui32WriteOffset, - psWorkEstCCBCtl->ui32ReadOffset); - } - } -#endif - - - if (psFwOsData != NULL) - { - /* Dump the KCCB commands executed */ - PVR_DUMPDEBUG_LOG("RGX Kernel CCB commands executed = %d", - psFwOsData->ui32KCCBCmdsExecuted); - -#if defined(PVRSRV_STALLED_CCB_ACTION) - /* Dump the number of times we have performed a forced UFO update, - * and (if non-zero) the timestamp of the most recent occurrence/ - */ - PVR_DUMPDEBUG_LOG("RGX SLR: Forced UFO updates requested = %d", - psFwOsData->ui32ForcedUpdatesRequested); - if (psFwOsData->ui32ForcedUpdatesRequested > 0) - { - IMG_UINT8 ui8Idx; - IMG_UINT64 ui64Seconds, ui64Nanoseconds; - - if (psFwOsData->ui64LastForcedUpdateTime > 0ULL) - { - ConvertOSTimestampToSAndNS(psFwOsData->ui64LastForcedUpdateTime, &ui64Seconds, &ui64Nanoseconds); - PVR_DUMPDEBUG_LOG("RGX SLR: (most recent forced update was around %" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC ")", - ui64Seconds, ui64Nanoseconds); - } - else - { - PVR_DUMPDEBUG_LOG("RGX SLR: (unable to force update as fence contained no sync checkpoints)"); - } - /* Dump SLR log */ - if (psFwOsData->sSLRLogFirst.aszCCBName[0]) - { - ConvertOSTimestampToSAndNS(psFwOsData->sSLRLogFirst.ui64Timestamp, &ui64Seconds, &ui64Nanoseconds); - PVR_DUMPDEBUG_LOG("RGX SLR:{%" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC - "} Fence found on context 0x%x '%s' has %d UFOs", - ui64Seconds, ui64Nanoseconds, - psFwOsData->sSLRLogFirst.ui32FWCtxAddr, - psFwOsData->sSLRLogFirst.aszCCBName, - psFwOsData->sSLRLogFirst.ui32NumUFOs); - } - for (ui8Idx=0; ui8IdxsSLRLog[ui8Idx].aszCCBName[0]) - { - ConvertOSTimestampToSAndNS(psFwOsData->sSLRLog[ui8Idx].ui64Timestamp, &ui64Seconds, &ui64Nanoseconds); - PVR_DUMPDEBUG_LOG("RGX SLR:[%" IMG_UINT64_FMTSPEC ".%09" IMG_UINT64_FMTSPEC - "] Fence found on context 0x%x '%s' has %d UFOs", - ui64Seconds, ui64Nanoseconds, - psFwOsData->sSLRLog[ui8Idx].ui32FWCtxAddr, - psFwOsData->sSLRLog[ui8Idx].aszCCBName, - psFwOsData->sSLRLog[ui8Idx].ui32NumUFOs); - } - } - } -#else - PVR_DUMPDEBUG_LOG("RGX SLR: Disabled"); -#endif - - /* Dump the error counts */ - PVR_DUMPDEBUG_LOG("RGX Errors: WGP:%d, TRP:%d", - psDevInfo->sErrorCounts.ui32WGPErrorCount, - psDevInfo->sErrorCounts.ui32TRPErrorCount); - - /* Dump the IRQ info for threads or OS IDs */ -#if defined(RGX_FW_IRQ_OS_COUNTERS) - /* only Host has access to registers containing IRQ counters */ - if (!PVRSRV_VZ_MODE_IS(GUEST)) -#endif - { - IMG_UINT32 ui32idx; - - for_each_irq_cnt(ui32idx) - { - IMG_UINT32 ui32IrqCnt; - - get_irq_cnt_val(ui32IrqCnt, ui32idx, psDevInfo); - if (ui32IrqCnt) - { - PVR_DUMPDEBUG_LOG(MSG_IRQ_CNT_TYPE "%u: FW IRQ count = %u", ui32idx, ui32IrqCnt); -#if defined(RGX_FW_IRQ_OS_COUNTERS) - if (ui32idx == RGXFW_HOST_OS) -#endif - { - PVR_DUMPDEBUG_LOG("Last sampled IRQ count in LISR = %u", psDevInfo->aui32SampleIRQCount[ui32idx]); - } - } - } - } - } - - /* Dump the FW Sys config flags on the Host */ - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - IMG_CHAR sFwSysFlagsDescription[MAX_FW_DESCRIPTION_LENGTH]; - - if (!psFwSysData) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Fw Sys Data is not mapped into CPU space", __func__)); - goto Exit; - } - - _GetFwSysFlagsDescription(sFwSysFlagsDescription, MAX_FW_DESCRIPTION_LENGTH, psFwSysData->ui32ConfigFlags); - PVR_DUMPDEBUG_LOG("FW System config flags = 0x%08X (%s)", psFwSysData->ui32ConfigFlags, sFwSysFlagsDescription); - } - - /* Dump the FW OS config flags */ - { - IMG_CHAR sFwOsFlagsDescription[MAX_FW_DESCRIPTION_LENGTH]; - - if (!psFwOsData) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Fw Os Data is not mapped into CPU space", __func__)); - goto Exit; - } - - _GetFwOsFlagsDescription(sFwOsFlagsDescription, MAX_FW_DESCRIPTION_LENGTH, psFwOsData->ui32FwOsConfigFlags); - PVR_DUMPDEBUG_LOG("FW OS config flags = 0x%08X (%s)", psFwOsData->ui32FwOsConfigFlags, sFwOsFlagsDescription); - } - - if ((bRGXPoweredON) && !PVRSRV_VZ_MODE_IS(GUEST)) - { - - eError = RGXDumpRGXRegisters(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXDumpRGXRegisters failed (%s)", - __func__, - PVRSRVGetErrorString(eError))); - } - } - else - { - PVR_DUMPDEBUG_LOG(" (!) %s. No registers dumped", PVRSRV_VZ_MODE_IS(GUEST) ? "Guest Mode of operation" : "RGX power is down"); - } - - PVR_DUMPDEBUG_LOG("------[ RGX FW Trace Info ]------"); - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - { - IMG_INT tid; - /* Dump FW trace information */ - if (psRGXFWIfTraceBufCtl != NULL) - { - for (tid = 0 ; tid < RGXFW_THREAD_NUM ; tid++) - { - IMG_UINT32 i; - IMG_BOOL bPrevLineWasZero = IMG_FALSE; - IMG_BOOL bLineIsAllZeros = IMG_FALSE; - IMG_UINT32 ui32CountLines = 0; - IMG_UINT32 *pui32TraceBuffer; - IMG_CHAR *pszLine; - - if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK) - { - PVR_DUMPDEBUG_LOG("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")", - ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")), - RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType) - ); - } - else - { - PVR_DUMPDEBUG_LOG("Debug log type: none"); - } - - pui32TraceBuffer = psRGXFWIfTraceBufCtl->sTraceBuf[tid].pui32TraceBuffer; - - /* Skip if trace buffer is not allocated */ - if (pui32TraceBuffer == NULL) - { - PVR_DUMPDEBUG_LOG("RGX FW thread %d: Trace buffer not yet allocated",tid); - continue; - } - -/* Max number of DWords to be printed per line, in debug dump output */ -#define PVR_DD_FW_TRACEBUF_LINESIZE 30U - /* each element in the line is 8 characters plus a space. The '+ 1' is because of the final trailing '\0'. */ - pszLine = OSAllocMem(9 * PVR_DD_FW_TRACEBUF_LINESIZE + 1); - if (pszLine == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Out of mem allocating line string (size: %d)", - __func__, - 9 * PVR_DD_FW_TRACEBUF_LINESIZE + 1)); - goto Exit; - } - - PVR_DUMPDEBUG_LOG("------[ RGX FW thread %d trace START ]------", tid); - PVR_DUMPDEBUG_LOG("FWT[traceptr]: %X", psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer); - PVR_DUMPDEBUG_LOG("FWT[tracebufsize]: %X", psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords); - - for (i = 0; i < psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords; i += PVR_DD_FW_TRACEBUF_LINESIZE) - { - IMG_UINT32 k = 0; - IMG_UINT32 ui32Line = 0x0; - IMG_UINT32 ui32LineOffset = i*sizeof(IMG_UINT32); - IMG_CHAR *pszBuf = pszLine; - - for (k = 0; k < PVR_DD_FW_TRACEBUF_LINESIZE; k++) - { - if ((i + k) >= psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords) - { - /* Stop reading when the index goes beyond trace buffer size. This condition is - * hit during printing the last line in DD when ui32TraceBufSizeInDWords is not - * a multiple of PVR_DD_FW_TRACEBUF_LINESIZE */ - break; - } - - ui32Line |= pui32TraceBuffer[i + k]; - - /* prepare the line to print it. The '+1' is because of the trailing '\0' added */ - OSSNPrintf(pszBuf, 9 + 1, " %08x", pui32TraceBuffer[i + k]); - pszBuf += 9; /* write over the '\0' */ - } - - bLineIsAllZeros = (ui32Line == 0x0); - - if (bLineIsAllZeros) - { - if (bPrevLineWasZero) - { - ui32CountLines++; - } - else - { - bPrevLineWasZero = IMG_TRUE; - ui32CountLines = 1; - PVR_DUMPDEBUG_LOG("FWT[%08x]: 00000000 ... 00000000", ui32LineOffset); - } - } - else - { - if (bPrevLineWasZero && ui32CountLines > 1) - { - PVR_DUMPDEBUG_LOG("FWT[...]: %d lines were all zero", ui32CountLines); - } - bPrevLineWasZero = IMG_FALSE; - - PVR_DUMPDEBUG_LOG("FWT[%08x]:%s", ui32LineOffset, pszLine); - } - - } - if (bPrevLineWasZero) - { - PVR_DUMPDEBUG_LOG("FWT[END]: %d lines were all zero", ui32CountLines); - } - - PVR_DUMPDEBUG_LOG("------[ RGX FW thread %d trace END ]------", tid); - - OSFreeMem(pszLine); - } - } - - { - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH)) - { - PVR_DUMPDEBUG_LOG("------[ Full CCB Status ]------"); - } - else - { - PVR_DUMPDEBUG_LOG("------[ Stalled FWCtxs ]------"); - } - - DumpTransferCtxtsInfo(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - - DumpRenderCtxtsInfo(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - - DumpKickSyncCtxtsInfo(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE)) - { - DumpComputeCtxtsInfo(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - DumpTDMTransferCtxtsInfo(psDevInfo, pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - } - } - - PVR_DUMPDEBUG_LOG("------[ RGX Device ID:%d End ]------", psDevInfo->psDeviceNode->sDevId.ui32InternalID); - -Exit: - if (!bPwrLockAlreadyHeld) - { - PVRSRVPowerUnlock(psDeviceNode); - } -} - -/*! - ****************************************************************************** - - @Function RGXDebugRequestNotify - - @Description Dump the debug data for RGX - - ******************************************************************************/ -static void RGXDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDbgRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = hDbgRequestHandle; - - /* Only action the request if we've fully init'ed */ - if (psDevInfo->bDevInit2Done) - { - RGXDebugRequestProcess(pfnDumpDebugPrintf, pvDumpDebugFile, psDevInfo, ui32VerbLevel); - } -} - -PVRSRV_ERROR RGXDebugInit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - return PVRSRVRegisterDeviceDbgRequestNotify(&psDevInfo->hDbgReqNotify, - psDevInfo->psDeviceNode, - RGXDebugRequestNotify, - DEBUG_REQUEST_RGX, - psDevInfo); -} - -PVRSRV_ERROR RGXDebugDeinit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - if (psDevInfo->hDbgReqNotify) - { - return PVRSRVUnregisterDeviceDbgRequestNotify(psDevInfo->hDbgReqNotify); - } - - /* No notifier registered */ - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (rgxdebug.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxdebug.h b/drivers/gpu/drm/img-rogue/1.17/rgxdebug.h deleted file mode 100644 index 279718bc254b8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxdebug.h +++ /dev/null @@ -1,229 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX debug header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX debugging functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXDEBUG_H) -#define RGXDEBUG_H - -#include "pvrsrv_error.h" -#include "img_types.h" -#include "device.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "rgxdevice.h" - -/* - * Debug utility macro for printing FW IRQ count and Last sampled IRQ count in - * LISR for each RGX FW thread. - * Macro takes pointer to PVRSRV_RGXDEV_INFO as input. - */ - -#if defined(RGX_FW_IRQ_OS_COUNTERS) -#define for_each_irq_cnt(ui32idx) \ - for (ui32idx = 0; ui32idx < RGX_NUM_OS_SUPPORTED; ui32idx++) - -#define get_irq_cnt_val(ui32Dest, ui32idx, psRgxDevInfo) \ - do { \ - extern const IMG_UINT32 gaui32FwOsIrqCntRegAddr[RGXFW_MAX_NUM_OS]; \ - ui32Dest = PVRSRV_VZ_MODE_IS(GUEST) ? 0 : OSReadHWReg32((psRgxDevInfo)->pvRegsBaseKM, gaui32FwOsIrqCntRegAddr[ui32idx]); \ - } while (false) - -#define MSG_IRQ_CNT_TYPE "OS" - -#else - -#define for_each_irq_cnt(ui32idx) \ - for (ui32idx = 0; ui32idx < RGXFW_THREAD_NUM; ui32idx++) - -#define get_irq_cnt_val(ui32Dest, ui32idx, psRgxDevInfo) \ - ui32Dest = (psRgxDevInfo)->psRGXFWIfFwOsData->aui32InterruptCount[ui32idx] - -#define MSG_IRQ_CNT_TYPE "Thread" -#endif /* RGX_FW_IRQ_OS_COUNTERS */ - -static inline void RGXDEBUG_PRINT_IRQ_COUNT(PVRSRV_RGXDEV_INFO* psRgxDevInfo) -{ -#if defined(PVRSRV_NEED_PVR_DPF) && defined(DEBUG) - IMG_UINT32 ui32idx; - - for_each_irq_cnt(ui32idx) - { - IMG_UINT32 ui32IrqCnt; - - get_irq_cnt_val(ui32IrqCnt, ui32idx, psRgxDevInfo); - - PVR_DPF((DBGPRIV_VERBOSE, MSG_IRQ_CNT_TYPE - " %u FW IRQ count = %u", ui32idx, ui32IrqCnt)); - -#if defined(RGX_FW_IRQ_OS_COUNTERS) - if (ui32idx == RGXFW_HOST_OS) -#endif - { - PVR_DPF((DBGPRIV_VERBOSE, "Last sampled IRQ count in LISR = %u", - (psRgxDevInfo)->aui32SampleIRQCount[ui32idx])); - } - } -#endif /* PVRSRV_NEED_PVR_DPF */ -} - -extern const IMG_CHAR * const gapszMipsPermissionPTFlags[4]; -extern const IMG_CHAR * const gapszMipsCoherencyPTFlags[8]; -extern const IMG_CHAR * const gapszMipsDirtyGlobalValidPTFlags[8]; -/*! -******************************************************************************* - - @Function RGXDumpRGXRegisters - - @Description - - Dumps an extensive list of RGX registers required for debugging - - @Input pfnDumpDebugPrintf - Optional replacement print function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - - @Return PVRSRV_ERROR PVRSRV_OK on success, error code otherwise - -******************************************************************************/ -PVRSRV_ERROR RGXDumpRGXRegisters(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* - - @Function RGXDumpFirmwareTrace - - @Description Dumps the decoded version of the firmware trace buffer. - - Dump useful debugging info - - @Input pfnDumpDebugPrintf - Optional replacement print function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - - @Return void - -******************************************************************************/ -void RGXDumpFirmwareTrace(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo); - -#if defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS) -void RGXDumpPowerMonitoring(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo); -#endif - -#if defined(SUPPORT_FW_VIEW_EXTRA_DEBUG) -/*! -******************************************************************************* - - @Function ValidateFWOnLoad - - @Description Compare the Firmware image as seen from the CPU point of view - against the same memory area as seen from the firmware point - of view after first power up. - - @Input psDevInfo - Device Info - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR ValidateFWOnLoad(PVRSRV_RGXDEV_INFO *psDevInfo); -#endif - -/*! -******************************************************************************* - - @Function RGXDumpRGXDebugSummary - - @Description - - Dump a summary in human readable form with the RGX state - - @Input pfnDumpDebugPrintf - The debug printf function - @Input pvDumpDebugFile - Optional file identifier to be passed to the - 'printf' function if required - @Input psDevInfo - RGX device info - @Input bRGXPoweredON - IMG_TRUE if RGX device is on - - @Return void - -******************************************************************************/ -void RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_BOOL bRGXPoweredON); - -/*! -******************************************************************************* - - @Function RGXDebugInit - - @Description - - Setup debug requests, calls into PVRSRVRegisterDeviceDbgRequestNotify - - @Input psDevInfo RGX device info - @Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error - -******************************************************************************/ -PVRSRV_ERROR RGXDebugInit(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* - - @Function RGXDebugDeinit - - @Description - - Remove debug requests, calls into PVRSRVUnregisterDeviceDbgRequestNotify - - @Output phNotify Points to debug notifier handle - @Return PVRSRV_ERROR PVRSRV_OK on success otherwise an error - -******************************************************************************/ -PVRSRV_ERROR RGXDebugDeinit(PVRSRV_RGXDEV_INFO *psDevInfo); - -#endif /* RGXDEBUG_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxdevice.h b/drivers/gpu/drm/img-rogue/1.17/rgxdevice.h deleted file mode 100644 index 4ebbd29159db1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxdevice.h +++ /dev/null @@ -1,828 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX device node header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX device node -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXDEVICE_H) -#define RGXDEVICE_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_device_types.h" -#include "mmu_common.h" -#include "rgx_fwif_km.h" -#include "cache_ops.h" -#include "device.h" -#include "osfunc.h" -#include "rgxlayer_impl.h" -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "hash.h" -#endif -typedef struct _RGX_SERVER_COMMON_CONTEXT_ RGX_SERVER_COMMON_CONTEXT; - -typedef struct { - DEVMEM_MEMDESC *psFWFrameworkMemDesc; -} RGX_COMMON_CONTEXT_INFO; - - -/*! - ****************************************************************************** - * Device state flags - *****************************************************************************/ -#define RGXKM_DEVICE_STATE_ZERO_FREELIST (0x1) /*!< Zeroing the physical pages of reconstructed free lists */ -#define RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN (0x2) /*!< Used to disable the Devices Watchdog logging */ -#define RGXKM_DEVICE_STATE_GPU_UNITS_POWER_CHANGE_EN (0x4) /*!< Used for validation to inject dust requests every TA/3D kick */ -#define RGXKM_DEVICE_STATE_CCB_GROW_EN (0x8) /*!< Used to indicate CCB grow is permitted */ -#define RGXKM_DEVICE_STATE_ENABLE_SPU_UNITS_POWER_MASK_CHANGE_EN (0x10) /*!< Used for validation to enable SPU power state mask change */ -#define RGXKM_DEVICE_STATE_MASK (0x1F) - -/*! - ****************************************************************************** - * ECC RAM Fault Validation - *****************************************************************************/ -#define RGXKM_ECC_ERR_INJ_DISABLE 0 -#define RGXKM_ECC_ERR_INJ_SLC 1 -#define RGXKM_ECC_ERR_INJ_USC 2 -#define RGXKM_ECC_ERR_INJ_TPU 3 -#define RGXKM_ECC_ERR_INJ_RASCAL 4 -#define RGXKM_ECC_ERR_INJ_MARS 5 - -#define RGXKM_ECC_ERR_INJ_INTERVAL 10U - -/*! - ****************************************************************************** - * GPU DVFS Table - *****************************************************************************/ - -#define RGX_GPU_DVFS_TABLE_SIZE 32 -#define RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US 25000 /* Time required to calibrate a clock frequency the first time */ -#define RGX_GPU_DVFS_TRANSITION_CALIBRATION_TIME_US 150000 /* Time required for a recalibration after a DVFS transition */ -#define RGX_GPU_DVFS_PERIODIC_CALIBRATION_TIME_US 10000000 /* Time before the next periodic calibration and correlation */ - -/*! - ****************************************************************************** - * Global flags for driver validation - *****************************************************************************/ -#define RGX_VAL_KZ_SIG_CHECK_NOERR_EN (0x10U) /*!< Enable KZ signature check. Signatures must match */ -#define RGX_VAL_KZ_SIG_CHECK_ERR_EN (0x20U) /*!< Enable KZ signature check. Signatures must not match */ -#define RGX_VAL_SIG_CHECK_ERR_EN (0U) /*!< Not supported on Rogue cores */ - -typedef struct _GPU_FREQ_TRACKING_DATA_ -{ - /* Core clock speed estimated by the driver */ - IMG_UINT32 ui32EstCoreClockSpeed; - - /* Amount of successful calculations of the estimated core clock speed */ - IMG_UINT32 ui32CalibrationCount; -} GPU_FREQ_TRACKING_DATA; - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) -#define RGX_GPU_FREQ_TRACKING_SIZE 16 - -typedef struct -{ - IMG_UINT64 ui64BeginCRTimestamp; - IMG_UINT64 ui64BeginOSTimestamp; - - IMG_UINT64 ui64EndCRTimestamp; - IMG_UINT64 ui64EndOSTimestamp; - - IMG_UINT32 ui32EstCoreClockSpeed; - IMG_UINT32 ui32CoreClockSpeed; -} GPU_FREQ_TRACKING_HISTORY; -#endif - -typedef struct _RGX_GPU_DVFS_TABLE_ -{ - /* Beginning of current calibration period (in us) */ - IMG_UINT64 ui64CalibrationCRTimestamp; - IMG_UINT64 ui64CalibrationOSTimestamp; - - /* Calculated calibration period (in us) */ - IMG_UINT64 ui64CalibrationCRTimediff; - IMG_UINT64 ui64CalibrationOSTimediff; - - /* Current calibration period (in us) */ - IMG_UINT32 ui32CalibrationPeriod; - - /* System layer frequency table and frequency tracking data */ - IMG_UINT32 ui32FreqIndex; - IMG_UINT32 aui32GPUFrequency[RGX_GPU_DVFS_TABLE_SIZE]; - GPU_FREQ_TRACKING_DATA asTrackingData[RGX_GPU_DVFS_TABLE_SIZE]; - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) - IMG_UINT32 ui32HistoryIndex; - GPU_FREQ_TRACKING_HISTORY asTrackingHistory[RGX_GPU_FREQ_TRACKING_SIZE]; -#endif -} RGX_GPU_DVFS_TABLE; - - -/*! - ****************************************************************************** - * GPU utilisation statistics - *****************************************************************************/ - -typedef struct _RGXFWIF_GPU_UTIL_STATS_ -{ - IMG_BOOL bValid; /* If TRUE, statistics are valid. - FALSE if the driver couldn't get reliable stats. */ - IMG_UINT64 ui64GpuStatActive; /* GPU active statistic */ - IMG_UINT64 ui64GpuStatBlocked; /* GPU blocked statistic */ - IMG_UINT64 ui64GpuStatIdle; /* GPU idle statistic */ - IMG_UINT64 ui64GpuStatCumulative; /* Sum of active/blocked/idle stats */ - IMG_UINT64 ui64TimeStamp; /* Timestamp of the most recent sample of the GPU stats */ -} RGXFWIF_GPU_UTIL_STATS; - - -typedef struct _RGX_REG_CONFIG_ -{ - IMG_BOOL bEnabled; - RGXFWIF_REG_CFG_TYPE eRegCfgTypeToPush; - IMG_UINT32 ui32NumRegRecords; - POS_LOCK hLock; -} RGX_REG_CONFIG; - -typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC; - -typedef struct -{ - IMG_UINT32 ui32DustCount1; - IMG_UINT32 ui32DustCount2; - IMG_BOOL bToggle; -} RGX_DUST_STATE; - -typedef struct _PVRSRV_DEVICE_FEATURE_CONFIG_ -{ - IMG_UINT64 ui64ErnsBrns; - IMG_UINT64 ui64Features; - IMG_UINT32 ui32B; - IMG_UINT32 ui32V; - IMG_UINT32 ui32N; - IMG_UINT32 ui32C; - IMG_UINT32 ui32FeaturesValues[RGX_FEATURE_WITH_VALUES_MAX_IDX]; - IMG_UINT32 ui32MAXDMCount; - IMG_UINT32 ui32MAXDustCount; - IMG_UINT32 ui32SLCSizeInBytes; - IMG_PCHAR pszBVNCString; -}PVRSRV_DEVICE_FEATURE_CONFIG; - -/* This is used to get the value of a specific feature. - * Note that it will assert if the feature is disabled or value is invalid. */ -#define RGX_GET_FEATURE_VALUE(psDevInfo, Feature) \ - ( psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_##Feature##_IDX] ) - -/* This is used to check if the feature value (e.g. with an integer value) is available for the currently running BVNC or not */ -#define RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, Feature) \ - ( psDevInfo->sDevFeatureCfg.ui32FeaturesValues[RGX_FEATURE_##Feature##_IDX] < RGX_FEATURE_VALUE_DISABLED ) - -/* This is used to check if the Boolean feature (e.g. WITHOUT an integer value) is available for the currently running BVNC or not */ -#define RGX_IS_FEATURE_SUPPORTED(psDevInfo, Feature) \ - BITMASK_HAS(psDevInfo->sDevFeatureCfg.ui64Features, RGX_FEATURE_##Feature##_BIT_MASK) - -/* This is used to check if the ERN is available for the currently running BVNC or not */ -#define RGX_IS_ERN_SUPPORTED(psDevInfo, ERN) \ - BITMASK_HAS(psDevInfo->sDevFeatureCfg.ui64ErnsBrns, HW_ERN_##ERN##_BIT_MASK) - -/* This is used to check if the BRN is available for the currently running BVNC or not */ -#define RGX_IS_BRN_SUPPORTED(psDevInfo, BRN) \ - BITMASK_HAS(psDevInfo->sDevFeatureCfg.ui64ErnsBrns, FIX_HW_BRN_##BRN##_BIT_MASK) - -/* there is a corresponding define in rgxapi.h */ -#define RGX_MAX_TIMER_QUERIES 16U - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -/*! - * The host maintains a 512-deep cache of submitted workloads per device, - * i.e. a global look-up table for TA, 3D and compute (depending on the RGX - * hardware support present) - */ - -/* - * For the workload estimation return data array, the max amount of commands the - * MTS can have is 255, therefore 512 (LOG2 = 9) is large enough to account for - * all corner cases - */ -#define RETURN_DATA_ARRAY_SIZE_LOG2 (9) -#define RETURN_DATA_ARRAY_SIZE ((1U) << RETURN_DATA_ARRAY_SIZE_LOG2) -#define RETURN_DATA_ARRAY_WRAP_MASK (RETURN_DATA_ARRAY_SIZE - 1) - -#define WORKLOAD_HASH_SIZE_LOG2 6 -#define WORKLOAD_HASH_SIZE ((1U) << WORKLOAD_HASH_SIZE_LOG2) -#define WORKLOAD_HASH_WRAP_MASK (WORKLOAD_HASH_SIZE - 1) - -/*! - * Workload characteristics for supported data masters. - * All characteristics must match for the workload estimate to be used/updated. - */ -typedef union _RGX_WORKLOAD_ -{ - struct - { - IMG_UINT32 ui32RenderTargetSize; - IMG_UINT32 ui32NumberOfDrawCalls; - IMG_UINT32 ui32NumberOfIndices; - IMG_UINT32 ui32NumberOfMRTs; - } sTA3D; - - struct - { - IMG_UINT32 ui32NumberOfWorkgroups; - IMG_UINT32 ui32NumberOfWorkitems; - } sCompute; - - struct - { - IMG_UINT32 ui32Characteristic1; - IMG_UINT32 ui32Characteristic2; - } sTransfer; -} RGX_WORKLOAD; - -/*! - * Host data used to match the return data (actual cycles count) to the - * submitted command packet. - * The hash table is a per-DM circular buffer containing a key based on the - * workload characteristics. On job completion, the oldest workload data - * is evicted if the CB is full and the driver matches the characteristics - * to the matching data. - * - * o If the driver finds a match the existing cycle estimate is averaged with - * the actual cycles used. - * o Otherwise a new hash entry is created with the actual cycles for this - * workload. - * - * Subsequently if a match is found during command submission, the estimate - * is passed to the scheduler, e.g. adjust the GPU frequency if PDVFS is enabled. - */ -typedef struct _WORKLOAD_MATCHING_DATA_ -{ - POS_LOCK psHashLock; - HASH_TABLE *psHashTable; /*! existing workload cycle estimates for this DM */ - RGX_WORKLOAD asHashKeys[WORKLOAD_HASH_SIZE]; - IMG_UINT64 aui64HashData[WORKLOAD_HASH_SIZE]; - IMG_UINT32 ui32HashArrayWO; /*! track the most recent workload estimates */ -} WORKLOAD_MATCHING_DATA; - -/*! - * A generic container for the workload matching data for GPU contexts: - * rendering (TA, 3D), compute, etc. - */ -typedef struct _WORKEST_HOST_DATA_ -{ - union - { - struct - { - WORKLOAD_MATCHING_DATA sDataTA; /*!< matching data for TA commands */ - WORKLOAD_MATCHING_DATA sData3D; /*!< matching data for 3D commands */ - } sTA3D; - - struct - { - WORKLOAD_MATCHING_DATA sDataCDM; /*!< matching data for CDM commands */ - } sCompute; - - struct - { - WORKLOAD_MATCHING_DATA sDataTDM; /*!< matching data for TDM-TQ commands */ - } sTransfer; - } uWorkloadMatchingData; - - /* - * This is a per-context property, hence the TA and 3D share the same - * per render context counter. - */ - IMG_UINT32 ui32WorkEstCCBReceived; /*!< Used to ensure all submitted work - estimation commands are received - by the host before clean up. */ -} WORKEST_HOST_DATA; - -/*! - * Entries in the list of submitted workloads, used when the completed command - * returns data to the host. - * - * - the matching data is needed as it holds the hash data - * - the host data is needed for completion updates, ensuring memory is not - * freed while workload estimates are in-flight. - * - the workload characteristic is used in the hash table look-up. - */ -typedef struct _WORKEST_RETURN_DATA_ -{ - WORKEST_HOST_DATA *psWorkEstHostData; - WORKLOAD_MATCHING_DATA *psWorkloadMatchingData; - RGX_WORKLOAD sWorkloadCharacteristics; -} WORKEST_RETURN_DATA; -#endif - - -typedef struct -{ -#if defined(PDUMP) - IMG_HANDLE hPdumpPages; -#endif - PG_HANDLE sPages; - IMG_DEV_PHYADDR sPhysAddr; -} RGX_MIPS_ADDRESS_TRAMPOLINE; - - -/*! - ****************************************************************************** - * RGX Device error counts - *****************************************************************************/ -typedef struct _PVRSRV_RGXDEV_ERROR_COUNTS_ -{ - IMG_UINT32 ui32WGPErrorCount; /*!< count of the number of WGP checksum errors */ - IMG_UINT32 ui32TRPErrorCount; /*!< count of the number of TRP checksum errors */ -} PVRSRV_RGXDEV_ERROR_COUNTS; - -/*! - ****************************************************************************** - * RGX Device info - *****************************************************************************/ -typedef struct _PVRSRV_RGXDEV_INFO_ -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - - PVRSRV_DEVICE_FEATURE_CONFIG sDevFeatureCfg; - - IMG_BOOL bDevInit2Done; - - IMG_BOOL bFirmwareInitialised; - IMG_BOOL bPDPEnabled; - - IMG_HANDLE hDbgReqNotify; - - /* Kernel mode linear address of device registers */ - void __iomem *pvRegsBaseKM; - - IMG_HANDLE hRegMapping; - - /* System physical address of device registers */ - IMG_CPU_PHYADDR sRegsPhysBase; - /* Register region size in bytes */ - IMG_UINT32 ui32RegSize; - - PVRSRV_STUB_PBDESC *psStubPBDescListKM; - - /* Firmware memory context info */ - DEVMEM_CONTEXT *psKernelDevmemCtx; - DEVMEM_HEAP *psFirmwareMainHeap; - DEVMEM_HEAP *psFirmwareConfigHeap; - MMU_CONTEXT *psKernelMMUCtx; - - void *pvDeviceMemoryHeap; - - /* Kernel CCB */ - DEVMEM_MEMDESC *psKernelCCBCtlMemDesc; /*!< memdesc for Kernel CCB control */ - RGXFWIF_CCB_CTL *psKernelCCBCtl; /*!< kernel mapping for Kernel CCB control */ - DEVMEM_MEMDESC *psKernelCCBMemDesc; /*!< memdesc for Kernel CCB */ - IMG_UINT8 *psKernelCCB; /*!< kernel mapping for Kernel CCB */ - DEVMEM_MEMDESC *psKernelCCBRtnSlotsMemDesc; /*!< Return slot array for Kernel CCB commands */ - IMG_UINT32 *pui32KernelCCBRtnSlots; /*!< kernel mapping for return slot array */ - - /* Firmware CCB */ - DEVMEM_MEMDESC *psFirmwareCCBCtlMemDesc; /*!< memdesc for Firmware CCB control */ - RGXFWIF_CCB_CTL *psFirmwareCCBCtl; /*!< kernel mapping for Firmware CCB control */ - DEVMEM_MEMDESC *psFirmwareCCBMemDesc; /*!< memdesc for Firmware CCB */ - IMG_UINT8 *psFirmwareCCB; /*!< kernel mapping for Firmware CCB */ - - /* Workload Estimation Firmware CCB */ - DEVMEM_MEMDESC *psWorkEstFirmwareCCBCtlMemDesc; /*!< memdesc for Workload Estimation Firmware CCB control */ - RGXFWIF_CCB_CTL *psWorkEstFirmwareCCBCtl; /*!< kernel mapping for Workload Estimation Firmware CCB control */ - DEVMEM_MEMDESC *psWorkEstFirmwareCCBMemDesc; /*!< memdesc for Workload Estimation Firmware CCB */ - IMG_UINT8 *psWorkEstFirmwareCCB; /*!< kernel mapping for Workload Estimation Firmware CCB */ - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) - /* Counter dumping */ - DEVMEM_MEMDESC *psCounterBufferMemDesc; /*!< mem desc for counter dumping buffer */ - POS_LOCK hCounterDumpingLock; /*!< Lock for guarding access to counter dumping buffer */ -#endif - - PVRSRV_MEMALLOCFLAGS_T uiFWPoisonOnFreeFlag; /*!< Flag for poisoning FW allocations when freed */ - - IMG_BOOL bIgnoreHWReportedBVNC; /*!< Ignore BVNC reported by HW */ - - /* - if we don't preallocate the pagetables we must - insert newly allocated page tables dynamically - */ - void *pvMMUContextList; - - IMG_UINT32 ui32ClkGateStatusReg; - IMG_UINT32 ui32ClkGateStatusMask; - - DEVMEM_MEMDESC *psRGXFWCodeMemDesc; - IMG_DEV_VIRTADDR sFWCodeDevVAddrBase; - IMG_UINT32 ui32FWCodeSizeInBytes; - DEVMEM_MEMDESC *psRGXFWDataMemDesc; - IMG_DEV_VIRTADDR sFWDataDevVAddrBase; - RGX_MIPS_ADDRESS_TRAMPOLINE *psTrampoline; - - DEVMEM_MEMDESC *psRGXFWCorememCodeMemDesc; - IMG_DEV_VIRTADDR sFWCorememCodeDevVAddrBase; - RGXFWIF_DEV_VIRTADDR sFWCorememCodeFWAddr; - IMG_UINT32 ui32FWCorememCodeSizeInBytes; - - DEVMEM_MEMDESC *psRGXFWIfCorememDataStoreMemDesc; - IMG_DEV_VIRTADDR sFWCorememDataStoreDevVAddrBase; - RGXFWIF_DEV_VIRTADDR sFWCorememDataStoreFWAddr; - - DEVMEM_MEMDESC *psRGXFWAlignChecksMemDesc; - -#if defined(PDUMP) - DEVMEM_MEMDESC *psRGXFWSigTAChecksMemDesc; - IMG_UINT32 ui32SigTAChecksSize; - - DEVMEM_MEMDESC *psRGXFWSig3DChecksMemDesc; - IMG_UINT32 ui32Sig3DChecksSize; - - DEVMEM_MEMDESC *psRGXFWSigTDM2DChecksMemDesc; - IMG_UINT32 ui32SigTDM2DChecksSize; - - IMG_BOOL bDumpedKCCBCtlAlready; - - POS_SPINLOCK hSyncCheckpointSignalSpinLock; /*!< Guards data shared between an atomic & sleepable-context */ -#endif - - POS_LOCK hRGXFWIfBufInitLock; /*!< trace buffer lock for initialisation phase */ - - DEVMEM_MEMDESC *psRGXFWIfTraceBufCtlMemDesc; /*!< memdesc of trace buffer control structure */ - DEVMEM_MEMDESC *psRGXFWIfTraceBufferMemDesc[RGXFW_THREAD_NUM]; /*!< memdesc of actual FW trace (log) buffer(s) */ - RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl; /*!< structure containing trace control data and actual trace buffer */ - - DEVMEM_MEMDESC *psRGXFWIfFwSysDataMemDesc; /*!< memdesc of the firmware-shared system data structure */ - RGXFWIF_SYSDATA *psRGXFWIfFwSysData; /*!< structure containing trace control data and actual trace buffer */ - - DEVMEM_MEMDESC *psRGXFWIfFwOsDataMemDesc; /*!< memdesc of the firmware-shared os structure */ - RGXFWIF_OSDATA *psRGXFWIfFwOsData; /*!< structure containing trace control data and actual trace buffer */ - -#if defined(SUPPORT_TBI_INTERFACE) - DEVMEM_MEMDESC *psRGXFWIfTBIBufferMemDesc; /*!< memdesc of actual FW TBI buffer */ - RGXFWIF_DEV_VIRTADDR sRGXFWIfTBIBuffer; /*!< TBI buffer data */ - IMG_UINT32 ui32FWIfTBIBufferSize; -#endif - - DEVMEM_MEMDESC *psRGXFWIfHWRInfoBufCtlMemDesc; - RGXFWIF_HWRINFOBUF *psRGXFWIfHWRInfoBufCtl; - IMG_UINT32 ui32ClockSource; - IMG_UINT32 ui32LastClockSource; - - DEVMEM_MEMDESC *psRGXFWIfGpuUtilFWCbCtlMemDesc; - RGXFWIF_GPU_UTIL_FWCB *psRGXFWIfGpuUtilFWCb; - - DEVMEM_MEMDESC *psRGXFWIfHWPerfBufMemDesc; - IMG_BYTE *psRGXFWIfHWPerfBuf; - IMG_UINT32 ui32RGXFWIfHWPerfBufSize; /* in bytes */ - - DEVMEM_MEMDESC *psRGXFWIfRegCfgMemDesc; - - DEVMEM_MEMDESC *psRGXFWIfHWPerfCountersMemDesc; - - DEVMEM_MEMDESC *psRGXFWIfConnectionCtlMemDesc; - RGXFWIF_CONNECTION_CTL *psRGXFWIfConnectionCtl; - - DEVMEM_MEMDESC *psRGXFWHeapGuardPageReserveMemDesc; - DEVMEM_MEMDESC *psRGXFWIfSysInitMemDesc; - RGXFWIF_SYSINIT *psRGXFWIfSysInit; - - DEVMEM_MEMDESC *psRGXFWIfOsInitMemDesc; - RGXFWIF_OSINIT *psRGXFWIfOsInit; - - DEVMEM_MEMDESC *psRGXFWIfRuntimeCfgMemDesc; - RGXFWIF_RUNTIME_CFG *psRGXFWIfRuntimeCfg; - - /* Additional guest firmware memory context info */ - DEVMEM_HEAP *psGuestFirmwareRawHeap[RGX_NUM_OS_SUPPORTED]; - DEVMEM_MEMDESC *psGuestFirmwareRawMemDesc[RGX_NUM_OS_SUPPORTED]; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Array to store data needed for workload estimation when a workload - has finished and its cycle time is returned to the host. */ - WORKEST_RETURN_DATA asReturnData[RETURN_DATA_ARRAY_SIZE]; - IMG_UINT32 ui32ReturnDataWO; - POS_LOCK hWorkEstLock; -#endif - -#if defined(SUPPORT_PDVFS) - /** - * Host memdesc and pointer to memory containing core clock rate in Hz. - * Firmware updates the memory on changing the core clock rate over GPIO. - * Note: Shared memory needs atomic access from Host driver and firmware, - * hence size should not be greater than memory transaction granularity. - * Currently it is chosen to be 32 bits. - */ - DEVMEM_MEMDESC *psRGXFWIFCoreClkRateMemDesc; - volatile IMG_UINT32 *pui32RGXFWIFCoreClkRate; - /** - * Last sampled core clk rate. - */ - volatile IMG_UINT32 ui32CoreClkRateSnapshot; -#endif - - /* - HWPerf data for the RGX device - */ - - POS_LOCK hHWPerfLock; /*! Critical section lock that protects HWPerf code - * from multiple thread duplicate init/deinit - * and loss/freeing of FW & Host resources while in - * use in another thread e.g. MSIR. */ - - IMG_UINT64 ui64HWPerfFilter; /*! Event filter for FW events (settable by AppHint) */ - IMG_HANDLE hHWPerfStream; /*! TL Stream buffer (L2) for firmware event stream */ - IMG_UINT32 ui32L2BufMaxPacketSize;/*!< Max allowed packet size in FW HWPerf TL (L2) buffer */ - IMG_BOOL bSuspendHWPerfL2DataCopy; /*! Flag to indicate if copying HWPerf data is suspended */ - - IMG_UINT32 ui32HWPerfHostFilter; /*! Event filter for HWPerfHost stream (settable by AppHint) */ - POS_LOCK hLockHWPerfHostStream; /*! Lock guarding access to HWPerfHost stream from multiple threads */ - IMG_HANDLE hHWPerfHostStream; /*! TL Stream buffer for host only event stream */ - IMG_UINT32 ui32HWPerfHostBufSize; /*! Host side buffer size in bytes */ - IMG_UINT32 ui32HWPerfHostLastOrdinal; /*! Ordinal of the last packet emitted in HWPerfHost TL stream. - * Guarded by hLockHWPerfHostStream */ - IMG_UINT32 ui32HWPerfHostNextOrdinal; /*! Ordinal number for HWPerfHost events. Guarded by hHWPerfHostSpinLock */ - IMG_UINT8 *pui8DeferredEvents; /*! List of HWPerfHost events yet to be emitted in the TL stream. - * Events generated from atomic context are deferred "emitted" - * as the "emission" code can sleep */ - IMG_UINT16 ui16DEReadIdx; /*! Read index in the above deferred events buffer */ - IMG_UINT16 ui16DEWriteIdx; /*! Write index in the above deferred events buffer */ - void *pvHostHWPerfMISR; /*! MISR to emit pending/deferred events in HWPerfHost TL stream */ - POS_SPINLOCK hHWPerfHostSpinLock; /*! Guards data shared between an atomic & sleepable-context */ -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - IMG_UINT32 ui32DEHighWatermark; /*! High watermark of deferred events buffer usage. Protected by - *! hHWPerfHostSpinLock */ - /* Max number of times DeferredEmission waited for an atomic-context to "finish" packet write */ - IMG_UINT32 ui32WaitForAtomicCtxPktHighWatermark; /*! Protected by hLockHWPerfHostStream */ - /* Whether warning has been logged about an atomic-context packet loss (due to too long wait for "write" finish) */ - IMG_BOOL bWarnedAtomicCtxPktLost; - /* Max number of times DeferredEmission scheduled-out to give a chance to the right-ordinal packet to be emitted */ - IMG_UINT32 ui32WaitForRightOrdPktHighWatermark; /*! Protected by hLockHWPerfHostStream */ - /* Whether warning has been logged about an packet loss (due to too long wait for right ordinal to emit) */ - IMG_BOOL bWarnedPktOrdinalBroke; -#endif - - void *pvGpuFtraceData; - - /* Poll data for detecting firmware fatal errors */ - IMG_UINT32 aui32CrLastPollCount[RGXFW_THREAD_NUM]; - IMG_UINT32 ui32KCCBCmdsExecutedLastTime; - IMG_BOOL bKCCBCmdsWaitingLastTime; - IMG_UINT32 ui32GEOTimeoutsLastTime; - IMG_UINT32 ui32InterruptCountLastTime; - IMG_UINT32 ui32MissingInterruptsLastTime; - - /* Client stall detection */ - IMG_UINT32 ui32StalledClientMask; - - IMG_BOOL bWorkEstEnabled; - IMG_BOOL bPDVFSEnabled; - - void *pvLISRData; - void *pvMISRData; - void *pvAPMISRData; - RGX_ACTIVEPM_CONF eActivePMConf; - - volatile IMG_UINT32 aui32SampleIRQCount[RGXFW_THREAD_NUM]; - - DEVMEM_MEMDESC *psRGXFaultAddressMemDesc; - - DEVMEM_MEMDESC *psSLC3FenceMemDesc; - - /* If we do 10 deferred memory allocations per second, then the ID would wrap around after 13 years */ - IMG_UINT32 ui32ZSBufferCurrID; /*!< ID assigned to the next deferred devmem allocation */ - IMG_UINT32 ui32FreelistCurrID; /*!< ID assigned to the next freelist */ - - POS_LOCK hLockZSBuffer; /*!< Lock to protect simultaneous access to ZSBuffers */ - DLLIST_NODE sZSBufferHead; /*!< List of on-demand ZSBuffers */ - POS_LOCK hLockFreeList; /*!< Lock to protect simultaneous access to Freelists */ - DLLIST_NODE sFreeListHead; /*!< List of growable Freelists */ - PSYNC_PRIM_CONTEXT hSyncPrimContext; - PVRSRV_CLIENT_SYNC_PRIM *psPowSyncPrim; - - IMG_UINT32 ui32ActivePMReqOk; - IMG_UINT32 ui32ActivePMReqDenied; - IMG_UINT32 ui32ActivePMReqNonIdle; - IMG_UINT32 ui32ActivePMReqRetry; - IMG_UINT32 ui32ActivePMReqTotal; - - IMG_HANDLE hProcessQueuesMISR; - - IMG_UINT32 ui32DeviceFlags; /*!< Flags to track general device state */ - - /* GPU DVFS Table */ - RGX_GPU_DVFS_TABLE *psGpuDVFSTable; - - /* Pointer to function returning the GPU utilisation statistics since the last - * time the function was called. Supports different users at the same time. - * - * psReturnStats [out]: GPU utilisation statistics (active high/active low/idle/blocked) - * in microseconds since the last time the function was called - * by a specific user (identified by hGpuUtilUser) - * - * Returns PVRSRV_OK in case the call completed without errors, - * some other value otherwise. - */ - PVRSRV_ERROR (*pfnGetGpuUtilStats) (PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hGpuUtilUser, - RGXFWIF_GPU_UTIL_STATS *psReturnStats); - - /* Pointer to function that checks if the physical GPU IRQ - * line has been asserted and clears it if so */ - IMG_BOOL (*pfnRGXAckIrq) (struct _PVRSRV_RGXDEV_INFO_ *psDevInfo); - - POS_LOCK hGPUUtilLock; - - /* Register configuration */ - RGX_REG_CONFIG sRegCongfig; - - IMG_BOOL bRGXPowered; - DLLIST_NODE sMemoryContextList; - - POSWR_LOCK hRenderCtxListLock; - POSWR_LOCK hComputeCtxListLock; - POSWR_LOCK hTransferCtxListLock; - POSWR_LOCK hTDMCtxListLock; - POSWR_LOCK hMemoryCtxListLock; - POSWR_LOCK hKickSyncCtxListLock; - - /* Linked list of deferred KCCB commands due to a full KCCB. - * Access to members sKCCBDeferredCommandsListHead and ui32KCCBDeferredCommandsCount - * are protected by the hLockKCCBDeferredCommandsList spin lock. */ - POS_SPINLOCK hLockKCCBDeferredCommandsList; /*!< Protects deferred KCCB commands list */ - DLLIST_NODE sKCCBDeferredCommandsListHead; - IMG_UINT32 ui32KCCBDeferredCommandsCount; /*!< No of commands in the deferred list */ - - /* Linked lists of contexts on this device */ - DLLIST_NODE sRenderCtxtListHead; - DLLIST_NODE sComputeCtxtListHead; - DLLIST_NODE sTransferCtxtListHead; - DLLIST_NODE sTDMCtxtListHead; - DLLIST_NODE sKickSyncCtxtListHead; - - DLLIST_NODE sCommonCtxtListHead; - POSWR_LOCK hCommonCtxtListLock; - IMG_UINT32 ui32CommonCtxtCurrentID; /*!< ID assigned to the next common context */ - - POS_LOCK hDebugFaultInfoLock; /*!< Lock to protect the debug fault info list */ - POS_LOCK hMMUCtxUnregLock; /*!< Lock to protect list of unregistered MMU contexts */ - - POS_LOCK hNMILock; /*!< Lock to protect NMI operations */ - -#if defined(SUPPORT_VALIDATION) - IMG_UINT32 ui32ValidationFlags; /*!< Validation flags for host driver */ -#endif - RGX_DUST_STATE sDustReqState; - - RGX_LAYER_PARAMS sLayerParams; - - RGXFWIF_DM eBPDM; /*!< Current breakpoint data master */ - IMG_BOOL bBPSet; /*!< A Breakpoint has been set */ - POS_LOCK hBPLock; /*!< Lock for break point operations */ - - IMG_UINT32 ui32CoherencyTestsDone; - - ATOMIC_T iCCBSubmissionOrdinal; /* Rolling count used to indicate CCB submission order (all CCBs) */ - POS_LOCK hCCBRecoveryLock; /* Lock to protect pvEarliestStalledClientCCB and ui32OldestSubmissionOrdinal variables */ - void *pvEarliestStalledClientCCB; /* Will point to cCCB command to unblock in the event of a stall */ - IMG_UINT32 ui32OldestSubmissionOrdinal; /* Earliest submission ordinal of CCB entry found so far */ - IMG_UINT32 ui32SLRHoldoffCounter; /* Decremented each time health check is called until zero. SLR only happen when zero. */ - - POS_LOCK hCCBStallCheckLock; /* Lock used to guard against multiple threads simultaneously checking for stalled CCBs */ - -#if defined(SUPPORT_FIRMWARE_GCOV) - /* Firmware gcov buffer */ - DEVMEM_MEMDESC *psFirmwareGcovBufferMemDesc; /*!< mem desc for Firmware gcov dumping buffer */ - IMG_UINT32 ui32FirmwareGcovSize; -#endif - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) - struct - { - IMG_UINT64 ui64timerGray; - IMG_UINT64 ui64timerBinary; - IMG_UINT64 *pui64uscTimers; - } sRGXTimerValues; -#endif - -#if defined(SUPPORT_VALIDATION) - struct - { - IMG_UINT64 ui64RegVal; - struct completion sRegComp; - } sFwRegs; -#endif - - IMG_HANDLE hTQCLISharedMem; /*!< TQ Client Shared Mem PMR */ - IMG_HANDLE hTQUSCSharedMem; /*!< TQ USC Shared Mem PMR */ - -#if defined(SUPPORT_VALIDATION) - IMG_UINT32 ui32TestSLRInterval; /* Don't enqueue an update sync checkpoint every nth kick */ - IMG_UINT32 ui32TestSLRCount; /* (used to test SLR operation) */ - IMG_UINT32 ui32SLRSkipFWAddr; -#endif - -#if defined(SUPPORT_SECURITY_VALIDATION) - DEVMEM_MEMDESC *psRGXFWIfSecureBufMemDesc; - DEVMEM_MEMDESC *psRGXFWIfNonSecureBufMemDesc; -#endif - - /* Timer Queries */ - IMG_UINT32 ui32ActiveQueryId; /*!< id of the active line */ - IMG_BOOL bSaveStart; /*!< save the start time of the next kick on the device*/ - IMG_BOOL bSaveEnd; /*!< save the end time of the next kick on the device*/ - - DEVMEM_MEMDESC *psStartTimeMemDesc; /*!< memdesc for Start Times */ - IMG_UINT64 *pui64StartTimeById; /*!< CPU mapping of the above */ - - DEVMEM_MEMDESC *psEndTimeMemDesc; /*!< memdesc for End Timer */ - IMG_UINT64 *pui64EndTimeById; /*!< CPU mapping of the above */ - - IMG_UINT32 aui32ScheduledOnId[RGX_MAX_TIMER_QUERIES]; /*!< kicks Scheduled on QueryId */ - DEVMEM_MEMDESC *psCompletedMemDesc; /*!< kicks Completed on QueryId */ - IMG_UINT32 *pui32CompletedById; /*!< CPU mapping of the above */ - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - POS_LOCK hTimerQueryLock; /*!< lock to protect simultaneous access to timer query members */ -#endif - - PVRSRV_RGXDEV_ERROR_COUNTS sErrorCounts; /*!< struct containing device error counts */ - - IMG_UINT32 ui32HostSafetyEventMask;/*!< mask of the safety events handled by the driver */ - - RGX_CONTEXT_RESET_REASON eLastDeviceError; /*!< device error reported to client */ -#if defined(SUPPORT_VALIDATION) - IMG_UINT32 ui32ECCRAMErrInjModule; - IMG_UINT32 ui32ECCRAMErrInjInterval; -#endif - - IMG_UINT32 ui32Log2Non4KPgSize; /* Page size of Non4k heap in log2 form */ -} PVRSRV_RGXDEV_INFO; - - - -typedef struct _RGX_TIMING_INFORMATION_ -{ - /*! GPU default core clock speed in Hz */ - IMG_UINT32 ui32CoreClockSpeed; - - /*! Active Power Management: GPU actively requests the host driver to be powered off */ - IMG_BOOL bEnableActivePM; - - /*! Enable the GPU to power off internal Power Islands independently from the host driver */ - IMG_BOOL bEnableRDPowIsland; - - /*! Active Power Management: Delay between the GPU idle and the request to the host */ - IMG_UINT32 ui32ActivePMLatencyms; - -} RGX_TIMING_INFORMATION; - -typedef struct _RGX_DATA_ -{ - /*! Timing information */ - RGX_TIMING_INFORMATION *psRGXTimingInfo; -} RGX_DATA; - - -/* - RGX PDUMP register bank name (prefix) -*/ -#define RGX_PDUMPREG_NAME "RGXREG" -#define RGX_TB_PDUMPREG_NAME "EMUREG" - -#endif /* RGXDEVICE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfw_log_helper.h b/drivers/gpu/drm/img-rogue/1.17/rgxfw_log_helper.h deleted file mode 100644 index 275b63aca46bf..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfw_log_helper.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************/ /*! -@File rgxfw_log_helper.h -@Title Firmware TBI logging helper function -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Platform Generic -@Description This file contains some helper code to make TBI logging possible - Specifically, it uses the SFIDLIST xmacro to trace ids back to - the original strings. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXFW_LOG_HELPER_H -#define RGXFW_LOG_HELPER_H - -#include "rgx_fwif_sf.h" - -static const IMG_CHAR *const groups[]= { -#define X(A,B) #B, - RGXFW_LOG_SFGROUPLIST -#undef X -}; - -/* idToStringID : Search SFs tuples {id,string} for a matching id. - * return index to array if found or RGXFW_SF_LAST if none found. - * bsearch could be used as ids are in increasing order. */ -#if defined(RGX_FIRMWARE) -static IMG_UINT32 idToStringID(IMG_UINT32 ui32CheckData, const RGXFW_STID_FMT *const psSFs) -#else -static IMG_UINT32 idToStringID(IMG_UINT32 ui32CheckData, const RGXKM_STID_FMT *const psSFs) -#endif -{ - IMG_UINT32 i = 0, ui32Id = (IMG_UINT32)RGXFW_SF_LAST; - - for ( i = 0 ; psSFs[i].ui32Id != (IMG_UINT32)RGXFW_SF_LAST ; i++) - { - if ( ui32CheckData == psSFs[i].ui32Id ) - { - ui32Id = i; - break; - } - } - return ui32Id; -} - -#endif /* RGXFW_LOG_HELPER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.c b/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.c deleted file mode 100644 index 1e7a51f5fc834..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.c +++ /dev/null @@ -1,282 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Debugging and miscellaneous functions server implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Kernel services functions for debugging and other - miscellaneous functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv.h" -#include "pvr_debug.h" -#include "rgxfwdbg.h" -#include "rgxfwutils.h" -#include "rgxta3d.h" -#include "pdump_km.h" -#include "mmu_common.h" -#include "devicemem_server.h" -#include "osfunc.h" - -PVRSRV_ERROR -PVRSRVRGXFWDebugQueryFWLogKM( - const CONNECTION_DATA *psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *pui32RGXFWLogType) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - if (!psDeviceNode || !pui32RGXFWLogType) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevInfo = psDeviceNode->pvDevice; - - if (!psDevInfo || !psDevInfo->psRGXFWIfTraceBufCtl) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *pui32RGXFWLogType = psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType; - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetFWLogKM( - const CONNECTION_DATA * psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32RGXFWLogType) -{ - RGXFWIF_KCCB_CMD sLogTypeUpdateCmd; - PVRSRV_DEV_POWER_STATE ePowerState; - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 ui32OldRGXFWLogTpe; - IMG_UINT32 ui32kCCBCommandSlot; - IMG_BOOL bWaitForFwUpdate = IMG_FALSE; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - ui32OldRGXFWLogTpe = psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType; - - /* check log type is valid */ - if (ui32RGXFWLogType & ~RGXFWIF_LOG_TYPE_MASK) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - OSLockAcquire(psDevInfo->hRGXFWIfBufInitLock); - - /* set the new log type and ensure the new log type is written to memory - * before requesting the FW to read it - */ - psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType = ui32RGXFWLogType; - OSMemoryBarrier(&psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType); - - /* Allocate firmware trace buffer resource(s) if not already done */ - if (RGXTraceBufferIsInitRequired(psDevInfo)) - { - eError = RGXTraceBufferInitOnDemandResources(psDevInfo, RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS); - } -#if defined(SUPPORT_TBI_INTERFACE) - /* Check if LogType is TBI then allocate resource on demand and copy - * SFs to it - */ - else if (RGXTBIBufferIsInitRequired(psDevInfo)) - { - eError = RGXTBIBufferInitOnDemandResources(psDevInfo); - } - - /* TBI buffer address will be 0 if not initialised */ - sLogTypeUpdateCmd.uCmdData.sTBIBuffer = psDevInfo->sRGXFWIfTBIBuffer; -#else - sLogTypeUpdateCmd.uCmdData.sTBIBuffer.ui32Addr = 0; -#endif - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate resource on-demand. Reverting to old value", - __func__)); - psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType = ui32OldRGXFWLogTpe; - OSMemoryBarrier(&psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType); - - OSLockRelease(psDevInfo->hRGXFWIfBufInitLock); - - return eError; - } - - OSLockRelease(psDevInfo->hRGXFWIfBufInitLock); - - eError = PVRSRVPowerLock((PPVRSRV_DEVICE_NODE) psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire power lock (%u)", - __func__, - eError)); - return eError; - } - - eError = PVRSRVGetDevicePowerState((PPVRSRV_DEVICE_NODE) psDeviceNode, &ePowerState); - - if ((eError == PVRSRV_OK) && (ePowerState != PVRSRV_DEV_POWER_STATE_OFF)) - { - /* Ask the FW to update its cached version of logType value */ - sLogTypeUpdateCmd.eCmdType = RGXFWIF_KCCB_CMD_LOGTYPE_UPDATE; - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sLogTypeUpdateCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSendCommandAndGetKCCBSlot", unlock); - bWaitForFwUpdate = IMG_TRUE; - } - -unlock: - PVRSRVPowerUnlock( (PPVRSRV_DEVICE_NODE) psDeviceNode); - if (bWaitForFwUpdate) - { - /* Wait for the LogType value to be updated in FW */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); - } - return eError; -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetHCSDeadlineKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HCSDeadlineMS) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - - return RGXFWSetHCSDeadline(psDevInfo, ui32HCSDeadlineMS); -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetOSidPriorityKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32OSidPriority) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - - return RGXFWChangeOSidPriority(psDevInfo, ui32OSid, ui32OSidPriority); -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetOSNewOnlineStateKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32OSNewState) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_OS_STATE_CHANGE eState; - PVR_UNREFERENCED_PARAMETER(psConnection); - - eState = (ui32OSNewState) ? (RGXFWIF_OS_ONLINE) : (RGXFWIF_OS_OFFLINE); - return RGXFWSetFwOsState(psDevInfo, ui32OSid, eState); -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugPHRConfigureKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PHRMode) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - - return RGXFWConfigPHR(psDevInfo, - ui32PHRMode); -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugWdgConfigureKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32WdgPeriodUs) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - - return RGXFWConfigWdg(psDevInfo, - ui32WdgPeriodUs); -} - -PVRSRV_ERROR -PVRSRVRGXFWDebugDumpFreelistPageListKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice; - DLLIST_NODE *psNode, *psNext; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (dllist_is_empty(&psDevInfo->sFreeListHead)) - { - return PVRSRV_OK; - } - - PVR_LOG(("---------------[ Begin Freelist Page List Dump ]------------------")); - - OSLockAcquire(psDevInfo->hLockFreeList); - dllist_foreach_node(&psDevInfo->sFreeListHead, psNode, psNext) - { - RGX_FREELIST *psFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode); - RGXDumpFreeListPageList(psFreeList); - } - OSLockRelease(psDevInfo->hLockFreeList); - - PVR_LOG(("----------------[ End Freelist Page List Dump ]-------------------")); - - return PVRSRV_OK; - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.h b/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.h deleted file mode 100644 index 38d487edbcae5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwdbg.h +++ /dev/null @@ -1,113 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Debugging and miscellaneous functions server interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Kernel services functions for debugging and other - miscellaneous functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXFWDBG_H) -#define RGXFWDBG_H - -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "device.h" -#include "pmr.h" - -#include "connection_server.h" - - -PVRSRV_ERROR -PVRSRVRGXFWDebugInitFWImageKM( - PMR *psFWImgDestPMR, - PMR *psFWImgSrcPMR, - IMG_UINT64 ui64FWImgLen, - PMR *psFWImgSigPMR, - IMG_UINT64 ui64FWSigLen); - -PVRSRV_ERROR -PVRSRVRGXFWDebugQueryFWLogKM( - const CONNECTION_DATA *psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *pui32RGXFWLogType); - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetFWLogKM( - const CONNECTION_DATA *psConnection, - const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32RGXFWLogType); - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetHCSDeadlineKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HCSDeadlineMS); - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetOSidPriorityKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32OSidPriority); - -PVRSRV_ERROR -PVRSRVRGXFWDebugSetOSNewOnlineStateKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32OSNewState); - -PVRSRV_ERROR -PVRSRVRGXFWDebugPHRConfigureKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PHRMode); - -PVRSRV_ERROR -PVRSRVRGXFWDebugWdgConfigureKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32WdgPeriodUs); - -PVRSRV_ERROR -PVRSRVRGXFWDebugDumpFreelistPageListKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.c b/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.c deleted file mode 100644 index dc863a96ba7a6..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.c +++ /dev/null @@ -1,1155 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services Firmware image utilities used at init time -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Services Firmware image utilities used at init time -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* The routines implemented here are built on top of an abstraction layer to - * hide DDK/OS-specific details in case they are used outside of the DDK - * (e.g. when trusted device is enabled). - * Any new dependency should be added to rgxlayer.h. - * Any new code should be built on top of the existing abstraction layer, - * which should be extended when necessary. */ -#include "rgxfwimageutils.h" -#include "pvrsrv.h" -#include "pvrversion.h" - - -/************************************************************************ -* FW layout information -************************************************************************/ -#define MAX_NUM_ENTRIES (8) -static RGX_FW_LAYOUT_ENTRY asRGXFWLayoutTable[MAX_NUM_ENTRIES]; -static IMG_UINT32 ui32LayoutEntryNum; - - -static RGX_FW_LAYOUT_ENTRY* GetTableEntry(const void *hPrivate, RGX_FW_SECTION_ID eId) -{ - IMG_UINT32 i; - - for (i = 0; i < ui32LayoutEntryNum; i++) - { - if (asRGXFWLayoutTable[i].eId == eId) - { - return &asRGXFWLayoutTable[i]; - } - } - - RGXErrorLog(hPrivate, "%s: id %u not found, returning entry 0\n", - __func__, eId); - - return &asRGXFWLayoutTable[0]; -} - -/*! -******************************************************************************* - - @Function FindMMUSegment - - @Description Given a 32 bit FW address attempt to find the corresponding - pointer to FW allocation - - @Input ui32OffsetIn : 32 bit FW address - @Input pvHostFWCodeAddr : Pointer to FW code - @Input pvHostFWDataAddr : Pointer to FW data - @Input pvHostFWCorememCodeAddr : Pointer to FW coremem code - @Input pvHostFWCorememDataAddr : Pointer to FW coremem code - @Input uiHostAddrOut : CPU pointer equivalent to ui32OffsetIn - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR FindMMUSegment(IMG_UINT32 ui32OffsetIn, - void *pvHostFWCodeAddr, - void *pvHostFWDataAddr, - void *pvHostFWCorememCodeAddr, - void *pvHostFWCorememDataAddr, - void **uiHostAddrOut) -{ - IMG_UINT32 i; - - for (i = 0; i < ui32LayoutEntryNum; i++) - { - if ((ui32OffsetIn >= asRGXFWLayoutTable[i].ui32BaseAddr) && - (ui32OffsetIn < (asRGXFWLayoutTable[i].ui32BaseAddr + asRGXFWLayoutTable[i].ui32AllocSize))) - { - switch (asRGXFWLayoutTable[i].eType) - { - case FW_CODE: - *uiHostAddrOut = pvHostFWCodeAddr; - break; - - case FW_DATA: - *uiHostAddrOut = pvHostFWDataAddr; - break; - - case FW_COREMEM_CODE: - *uiHostAddrOut = pvHostFWCorememCodeAddr; - break; - - case FW_COREMEM_DATA: - *uiHostAddrOut = pvHostFWCorememDataAddr; - break; - - default: - return PVRSRV_ERROR_INIT_FAILURE; - } - - goto found; - } - } - - return PVRSRV_ERROR_INIT_FAILURE; - -found: - if (*uiHostAddrOut == NULL) - { - return PVRSRV_OK; - } - - /* Direct Mem write to mapped memory */ - ui32OffsetIn -= asRGXFWLayoutTable[i].ui32BaseAddr; - ui32OffsetIn += asRGXFWLayoutTable[i].ui32AllocOffset; - - /* Add offset to pointer to FW allocation only if - * that allocation is available - */ - if (*uiHostAddrOut) - { - *(IMG_UINT8 **)uiHostAddrOut += ui32OffsetIn; - } - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RGXFWConfigureSegID - - @Description Configures a single segment of the Segment MMU - (base, limit and out_addr) - - @Input hPrivate : Implementation specific data - @Input ui64SegOutAddr : Segment output base address (40 bit devVaddr) - @Input ui32SegBase : Segment input base address (32 bit FW address) - @Input ui32SegLimit : Segment size - @Input ui32SegID : Segment ID - @Input pszName : Segment name - @Input ppui32BootConf : Pointer to bootloader data - - @Return void - -******************************************************************************/ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static void RGXFWConfigureSegID(const void *hPrivate, - IMG_UINT64 ui64SegOutAddr, - IMG_UINT32 ui32SegBase, - IMG_UINT32 ui32SegLimit, - IMG_UINT32 ui32SegID, - IMG_UINT32 **ppui32BootConf) -{ - IMG_UINT32 *pui32BootConf = *ppui32BootConf; - IMG_UINT32 ui32SegOutAddr0 = ui64SegOutAddr & 0x00000000FFFFFFFFUL; - IMG_UINT32 ui32SegOutAddr1 = (ui64SegOutAddr >> 32) & 0x00000000FFFFFFFFUL; - - /* META segments have a minimum size */ - IMG_UINT32 ui32LimitOff = (ui32SegLimit < RGXFW_SEGMMU_ALIGN) ? - RGXFW_SEGMMU_ALIGN : ui32SegLimit; - /* the limit is an offset, therefore off = size - 1 */ - ui32LimitOff -= 1; - - RGXCommentLog(hPrivate, - "* Seg%d: meta_addr = 0x%08x, devv_addr = 0x%" IMG_UINT64_FMTSPECx ", limit = 0x%x", - ui32SegID, - ui32SegBase, - ui64SegOutAddr, - ui32LimitOff); - - ui32SegBase |= RGXFW_SEGMMU_ALLTHRS_WRITEABLE; - - *pui32BootConf++ = META_CR_MMCU_SEGMENTn_BASE(ui32SegID); - *pui32BootConf++ = ui32SegBase; - - *pui32BootConf++ = META_CR_MMCU_SEGMENTn_LIMIT(ui32SegID); - *pui32BootConf++ = ui32LimitOff; - - *pui32BootConf++ = META_CR_MMCU_SEGMENTn_OUTA0(ui32SegID); - *pui32BootConf++ = ui32SegOutAddr0; - - *pui32BootConf++ = META_CR_MMCU_SEGMENTn_OUTA1(ui32SegID); - *pui32BootConf++ = ui32SegOutAddr1; - - *ppui32BootConf = pui32BootConf; -} -#endif - -/*! -******************************************************************************* - - @Function RGXFWConfigureSegMMU - - @Description Configures META's Segment MMU - - @Input hPrivate : Implementation specific data - @Input psFWCodeDevVAddrBase : FW code base device virtual address - @Input psFWDataDevVAddrBase : FW data base device virtual address - @Input ppui32BootConf : Pointer to bootloader data - - @Return void - -******************************************************************************/ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static void RGXFWConfigureSegMMU(const void *hPrivate, - IMG_DEV_VIRTADDR *psFWCodeDevVAddrBase, - IMG_DEV_VIRTADDR *psFWDataDevVAddrBase, - IMG_UINT32 **ppui32BootConf) -{ - IMG_UINT64 ui64SegOutAddrTop; - IMG_UINT32 i; - - PVR_UNREFERENCED_PARAMETER(psFWCodeDevVAddrBase); - - /* Configure Segment MMU */ - RGXCommentLog(hPrivate, "********** FW configure Segment MMU **********"); - - if (RGX_DEVICE_HAS_FEATURE(hPrivate, SLC_VIVT)) - { - ui64SegOutAddrTop = RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED(MMU_CONTEXT_MAPPING_FWPRIV); - } - else - { - ui64SegOutAddrTop = RGXFW_SEGMMU_OUTADDR_TOP_SLC(MMU_CONTEXT_MAPPING_FWPRIV, RGXFW_SEGMMU_META_BIFDM_ID); - } - - for (i = 0; i < ui32LayoutEntryNum; i++) - { - /* - * FW code is using the bootloader segment which is already configured on boot. - * FW coremem code and data don't use the segment MMU. - * Only the FW data segment needs to be configured. - */ - - if (asRGXFWLayoutTable[i].eType == FW_DATA) - { - IMG_UINT64 ui64SegOutAddr; - IMG_UINT32 ui32SegId = RGXFW_SEGMMU_DATA_ID; - - ui64SegOutAddr = (psFWDataDevVAddrBase->uiAddr | ui64SegOutAddrTop) + - asRGXFWLayoutTable[i].ui32AllocOffset; - - RGXFWConfigureSegID(hPrivate, - ui64SegOutAddr, - asRGXFWLayoutTable[i].ui32BaseAddr, - asRGXFWLayoutTable[i].ui32AllocSize, - ui32SegId, - ppui32BootConf); /*write the sequence to the bootldr */ - - break; - } - } -} -#endif - -/*! -******************************************************************************* - - @Function RGXFWConfigureMetaCaches - - @Description Configure and enable the Meta instruction and data caches - - @Input hPrivate : Implementation specific data - @Input ui32NumThreads : Number of FW threads in use - @Input ppui32BootConf : Pointer to bootloader data - - @Return void - -******************************************************************************/ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static void RGXFWConfigureMetaCaches(const void *hPrivate, - IMG_UINT32 ui32NumThreads, - IMG_UINT32 **ppui32BootConf) -{ - IMG_UINT32 *pui32BootConf = *ppui32BootConf; - IMG_UINT32 ui32DCacheT0, ui32ICacheT0; - IMG_UINT32 ui32DCacheT1, ui32ICacheT1; - IMG_UINT32 ui32DCacheT2, ui32ICacheT2; - IMG_UINT32 ui32DCacheT3, ui32ICacheT3; - -#define META_CR_MMCU_LOCAL_EBCTRL (0x04830600) -#define META_CR_MMCU_LOCAL_EBCTRL_ICWIN (0x3 << 14) -#define META_CR_MMCU_LOCAL_EBCTRL_DCWIN (0x3 << 6) -#define META_CR_SYSC_DCPART(n) (0x04830200 + (n)*0x8) -#define META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE (0x1 << 31) -#define META_CR_SYSC_ICPART(n) (0x04830220 + (n)*0x8) -#define META_CR_SYSC_XCPARTX_LOCAL_ADDR_OFFSET_TOP_HALF (0x8 << 16) -#define META_CR_SYSC_XCPARTX_LOCAL_ADDR_FULL_CACHE (0xF) -#define META_CR_SYSC_XCPARTX_LOCAL_ADDR_HALF_CACHE (0x7) -#define META_CR_MMCU_DCACHE_CTRL (0x04830018) -#define META_CR_MMCU_ICACHE_CTRL (0x04830020) -#define META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN (0x1) - - RGXCommentLog(hPrivate, "********** Meta caches configuration *********"); - - /* Initialise I/Dcache settings */ - ui32DCacheT0 = ui32DCacheT1 = (IMG_UINT32)META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; - ui32DCacheT2 = ui32DCacheT3 = (IMG_UINT32)META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; - ui32ICacheT0 = ui32ICacheT1 = ui32ICacheT2 = ui32ICacheT3 = 0; - - if (ui32NumThreads == 1) - { - ui32DCacheT0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_FULL_CACHE; - ui32ICacheT0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_FULL_CACHE; - } - else - { - ui32DCacheT0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_HALF_CACHE; - ui32ICacheT0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_HALF_CACHE; - - ui32DCacheT1 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_HALF_CACHE | - META_CR_SYSC_XCPARTX_LOCAL_ADDR_OFFSET_TOP_HALF; - ui32ICacheT1 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_HALF_CACHE | - META_CR_SYSC_XCPARTX_LOCAL_ADDR_OFFSET_TOP_HALF; - } - - /* Local region MMU enhanced bypass: WIN-3 mode for code and data caches */ - *pui32BootConf++ = META_CR_MMCU_LOCAL_EBCTRL; - *pui32BootConf++ = META_CR_MMCU_LOCAL_EBCTRL_ICWIN | - META_CR_MMCU_LOCAL_EBCTRL_DCWIN; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_MMCU_LOCAL_EBCTRL, - META_CR_MMCU_LOCAL_EBCTRL_ICWIN | META_CR_MMCU_LOCAL_EBCTRL_DCWIN); - - /* Data cache partitioning thread 0 to 3 */ - *pui32BootConf++ = META_CR_SYSC_DCPART(0); - *pui32BootConf++ = ui32DCacheT0; - *pui32BootConf++ = META_CR_SYSC_DCPART(1); - *pui32BootConf++ = ui32DCacheT1; - *pui32BootConf++ = META_CR_SYSC_DCPART(2); - *pui32BootConf++ = ui32DCacheT2; - *pui32BootConf++ = META_CR_SYSC_DCPART(3); - *pui32BootConf++ = ui32DCacheT3; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_DCPART(0), ui32DCacheT0); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_DCPART(1), ui32DCacheT1); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_DCPART(2), ui32DCacheT2); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_DCPART(3), ui32DCacheT3); - - /* Enable data cache hits */ - *pui32BootConf++ = META_CR_MMCU_DCACHE_CTRL; - *pui32BootConf++ = META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_MMCU_DCACHE_CTRL, - META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN); - - /* Instruction cache partitioning thread 0 to 3 */ - *pui32BootConf++ = META_CR_SYSC_ICPART(0); - *pui32BootConf++ = ui32ICacheT0; - *pui32BootConf++ = META_CR_SYSC_ICPART(1); - *pui32BootConf++ = ui32ICacheT1; - *pui32BootConf++ = META_CR_SYSC_ICPART(2); - *pui32BootConf++ = ui32ICacheT2; - *pui32BootConf++ = META_CR_SYSC_ICPART(3); - *pui32BootConf++ = ui32ICacheT3; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_ICPART(0), ui32ICacheT0); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_ICPART(1), ui32ICacheT1); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_ICPART(2), ui32ICacheT2); - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_SYSC_ICPART(3), ui32ICacheT3); - - /* Enable instruction cache hits */ - *pui32BootConf++ = META_CR_MMCU_ICACHE_CTRL; - *pui32BootConf++ = META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - META_CR_MMCU_ICACHE_CTRL, - META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN); - - *pui32BootConf++ = 0x040000C0; - *pui32BootConf++ = 0; - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", 0x040000C0, 0); - - *ppui32BootConf = pui32BootConf; -} -#endif - -/*! -******************************************************************************* - - @Function ProcessLDRCommandStream - - @Description Process the output of the Meta toolchain in the .LDR format - copying code and data sections into their final location and - passing some information to the Meta bootloader - - @Input hPrivate : Implementation specific data - @Input pbLDR : Pointer to FW blob - @Input pvHostFWCodeAddr : Pointer to FW code - @Input pvHostFWDataAddr : Pointer to FW data - @Input pvHostFWCorememCodeAddr : Pointer to FW coremem code - @Input pvHostFWCorememDataAddr : Pointer to FW coremem data - @Input ppui32BootConf : Pointer to bootloader data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR ProcessLDRCommandStream(const void *hPrivate, - const IMG_BYTE* pbLDR, - void* pvHostFWCodeAddr, - void* pvHostFWDataAddr, - void* pvHostFWCorememCodeAddr, - void* pvHostFWCorememDataAddr, - IMG_UINT32 **ppui32BootConf) -{ - RGX_META_LDR_BLOCK_HDR *psHeader = (RGX_META_LDR_BLOCK_HDR *) pbLDR; - RGX_META_LDR_L1_DATA_BLK *psL1Data = - (RGX_META_LDR_L1_DATA_BLK*) ((IMG_UINT8 *) pbLDR + psHeader->ui32SLData); - - IMG_UINT32 *pui32BootConf = ppui32BootConf ? *ppui32BootConf : NULL; - IMG_UINT32 ui32CorememSize = RGXGetFWCorememSize(hPrivate); - - RGXCommentLog(hPrivate, "**********************************************"); - RGXCommentLog(hPrivate, "************** Begin LDR Parsing *************"); - RGXCommentLog(hPrivate, "**********************************************"); - - while (psL1Data != NULL) - { - if (RGX_META_LDR_BLK_IS_COMMENT(psL1Data->ui16Cmd)) - { - /* Don't process comment blocks */ - goto NextBlock; - } - - switch (psL1Data->ui16Cmd & RGX_META_LDR_CMD_MASK) - { - case RGX_META_LDR_CMD_LOADMEM: - { - RGX_META_LDR_L2_DATA_BLK *psL2Block = - (RGX_META_LDR_L2_DATA_BLK*) (((IMG_UINT8 *) pbLDR) + psL1Data->aui32CmdData[1]); - IMG_UINT32 ui32Offset = psL1Data->aui32CmdData[0]; - IMG_UINT32 ui32DataSize = psL2Block->ui16Length - 6 /* L2 Tag length and checksum */; - void *pvWriteAddr; - PVRSRV_ERROR eError; - - if (!RGX_META_IS_COREMEM_CODE(ui32Offset, ui32CorememSize) && - !RGX_META_IS_COREMEM_DATA(ui32Offset, ui32CorememSize)) - { - /* Global range is aliased to local range */ - ui32Offset &= ~META_MEM_GLOBAL_RANGE_BIT; - } - - eError = FindMMUSegment(ui32Offset, - pvHostFWCodeAddr, - pvHostFWDataAddr, - pvHostFWCorememCodeAddr, - pvHostFWCorememDataAddr, - &pvWriteAddr); - - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, - "ProcessLDRCommandStream: Addr 0x%x (size: %d) not found in any segment", - ui32Offset, ui32DataSize); - return eError; - } - - /* Write to FW allocation only if available */ - if (pvWriteAddr) - { - RGXMemCopy(hPrivate, - pvWriteAddr, - psL2Block->aui32BlockData, - ui32DataSize); - } - - break; - } - case RGX_META_LDR_CMD_LOADCORE: - case RGX_META_LDR_CMD_LOADMMREG: - { - return PVRSRV_ERROR_INIT_FAILURE; - } - case RGX_META_LDR_CMD_START_THREADS: - { - /* Don't process this block */ - break; - } - case RGX_META_LDR_CMD_ZEROMEM: - { - IMG_UINT32 ui32Offset = psL1Data->aui32CmdData[0]; - IMG_UINT32 ui32ByteCount = psL1Data->aui32CmdData[1]; - void *pvWriteAddr; - PVRSRV_ERROR eError; - - if (RGX_META_IS_COREMEM_DATA(ui32Offset, ui32CorememSize)) - { - /* cannot zero coremem directly */ - break; - } - - /* Global range is aliased to local range */ - ui32Offset &= ~META_MEM_GLOBAL_RANGE_BIT; - - eError = FindMMUSegment(ui32Offset, - pvHostFWCodeAddr, - pvHostFWDataAddr, - pvHostFWCorememCodeAddr, - pvHostFWCorememDataAddr, - &pvWriteAddr); - - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, - "ProcessLDRCommandStream: Addr 0x%x (size: %d) not found in any segment", - ui32Offset, ui32ByteCount); - return eError; - } - - /* Write to FW allocation only if available */ - if (pvWriteAddr) - { - RGXMemSet(hPrivate, pvWriteAddr, 0, ui32ByteCount); - } - - break; - } - case RGX_META_LDR_CMD_CONFIG: - { - RGX_META_LDR_L2_DATA_BLK *psL2Block = - (RGX_META_LDR_L2_DATA_BLK*) (((IMG_UINT8 *) pbLDR) + psL1Data->aui32CmdData[0]); - RGX_META_LDR_CFG_BLK *psConfigCommand = (RGX_META_LDR_CFG_BLK*) psL2Block->aui32BlockData; - IMG_UINT32 ui32L2BlockSize = psL2Block->ui16Length - 6 /* L2 Tag length and checksum */; - IMG_UINT32 ui32CurrBlockSize = 0; - - while (ui32L2BlockSize) - { - switch (psConfigCommand->ui32Type) - { - case RGX_META_LDR_CFG_PAUSE: - case RGX_META_LDR_CFG_READ: - { - ui32CurrBlockSize = 8; - return PVRSRV_ERROR_INIT_FAILURE; - } - case RGX_META_LDR_CFG_WRITE: - { - IMG_UINT32 ui32RegisterOffset = psConfigCommand->aui32BlockData[0]; - IMG_UINT32 ui32RegisterValue = psConfigCommand->aui32BlockData[1]; - - /* Only write to bootloader if we got a valid - * pointer to the FW code allocation - */ - if (pui32BootConf) - { - /* Do register write */ - *pui32BootConf++ = ui32RegisterOffset; - *pui32BootConf++ = ui32RegisterValue; - } - - RGXCommentLog(hPrivate, "Meta SP: [0x%08x] = 0x%08x", - ui32RegisterOffset, ui32RegisterValue); - - ui32CurrBlockSize = 12; - break; - } - case RGX_META_LDR_CFG_MEMSET: - case RGX_META_LDR_CFG_MEMCHECK: - { - ui32CurrBlockSize = 20; - return PVRSRV_ERROR_INIT_FAILURE; - } - default: - { - return PVRSRV_ERROR_INIT_FAILURE; - } - } - ui32L2BlockSize -= ui32CurrBlockSize; - psConfigCommand = (RGX_META_LDR_CFG_BLK*) (((IMG_UINT8*) psConfigCommand) + ui32CurrBlockSize); - } - - break; - } - default: - { - return PVRSRV_ERROR_INIT_FAILURE; - } - } - -NextBlock: - - if (psL1Data->ui32Next == 0xFFFFFFFF) - { - psL1Data = NULL; - } - else - { - psL1Data = (RGX_META_LDR_L1_DATA_BLK*) (((IMG_UINT8 *) pbLDR) + psL1Data->ui32Next); - } - } - - if (pui32BootConf) - { - *ppui32BootConf = pui32BootConf; - } - - RGXCommentLog(hPrivate, "**********************************************"); - RGXCommentLog(hPrivate, "************** End Loader Parsing ************"); - RGXCommentLog(hPrivate, "**********************************************"); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function ProcessELFCommandStream - - @Description Process a file in .ELF format copying code and data sections - into their final location - - @Input hPrivate : Implementation specific data - @Input pbELF : Pointer to FW blob - @Input pvHostFWCodeAddr : Pointer to FW code - @Input pvHostFWDataAddr : Pointer to FW data - @Input pvHostFWCorememCodeAddr : Pointer to FW coremem code - @Input pvHostFWCorememDataAddr : Pointer to FW coremem data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR ProcessELFCommandStream(const void *hPrivate, - const IMG_BYTE *pbELF, - void *pvHostFWCodeAddr, - void *pvHostFWDataAddr, - void* pvHostFWCorememCodeAddr, - void* pvHostFWCorememDataAddr) -{ - IMG_UINT32 ui32Entry; - IMG_ELF_HDR *psHeader = (IMG_ELF_HDR *)pbELF; - IMG_ELF_PROGRAM_HDR *psProgramHeader = - (IMG_ELF_PROGRAM_HDR *)(pbELF + psHeader->ui32Ephoff); - PVRSRV_ERROR eError; - - for (ui32Entry = 0; ui32Entry < psHeader->ui32Ephnum; ui32Entry++, psProgramHeader++) - { - void *pvWriteAddr; - - /* Only consider loadable entries in the ELF segment table */ - if (psProgramHeader->ui32Ptype != ELF_PT_LOAD) continue; - - eError = FindMMUSegment(psProgramHeader->ui32Pvaddr, - pvHostFWCodeAddr, - pvHostFWDataAddr, - pvHostFWCorememCodeAddr, - pvHostFWCorememDataAddr, - &pvWriteAddr); - - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, - "%s: Addr 0x%x (size: %d) not found in any segment",__func__, - psProgramHeader->ui32Pvaddr, - psProgramHeader->ui32Pfilesz); - return eError; - } - - /* Write to FW allocation only if available */ - if (pvWriteAddr) - { - RGXMemCopy(hPrivate, - pvWriteAddr, - (IMG_PBYTE)(pbELF + psProgramHeader->ui32Poffset), - psProgramHeader->ui32Pfilesz); - - RGXMemSet(hPrivate, - (IMG_PBYTE)pvWriteAddr + psProgramHeader->ui32Pfilesz, - 0, - psProgramHeader->ui32Pmemsz - psProgramHeader->ui32Pfilesz); - } - } - - return PVRSRV_OK; -} - -IMG_UINT32 RGXGetFWImageSectionOffset(const void *hPrivate, RGX_FW_SECTION_ID eId) -{ - RGX_FW_LAYOUT_ENTRY *psEntry = GetTableEntry(hPrivate, eId); - - return psEntry->ui32AllocOffset; -} - -IMG_UINT32 RGXGetFWImageSectionMaxSize(const void *hPrivate, RGX_FW_SECTION_ID eId) -{ - RGX_FW_LAYOUT_ENTRY *psEntry = GetTableEntry(hPrivate, eId); - - return psEntry->ui32MaxSize; -} - -IMG_UINT32 RGXGetFWImageSectionAllocSize(const void *hPrivate, RGX_FW_SECTION_ID eId) -{ - RGX_FW_LAYOUT_ENTRY *psEntry = GetTableEntry(hPrivate, eId); - - return psEntry->ui32AllocSize; -} - -IMG_UINT32 RGXGetFWImageSectionAddress(const void *hPrivate, RGX_FW_SECTION_ID eId) -{ - RGX_FW_LAYOUT_ENTRY *psEntry = GetTableEntry(hPrivate, eId); - - return psEntry->ui32BaseAddr; -} - -static inline -PVRSRV_ERROR RGXValidateFWHeaderVersion1(const void *hPrivate, - const RGX_FW_INFO_HEADER *psInfoHeader) -{ - /* Applicable to any FW_INFO_VERSION */ - if (psInfoHeader->ui32LayoutEntrySize != sizeof(RGX_FW_LAYOUT_ENTRY)) - { - RGXErrorLog(hPrivate, "%s: FW layout entry sizes mismatch (expected: %u, found: %u)", - __func__, - (IMG_UINT32) sizeof(RGX_FW_LAYOUT_ENTRY), - psInfoHeader->ui32LayoutEntrySize); - } - - /* Applicable to any FW_INFO_VERSION */ - if (psInfoHeader->ui32LayoutEntryNum > MAX_NUM_ENTRIES) - { - RGXErrorLog(hPrivate, "%s: Not enough storage for the FW layout table (max: %u entries, found: %u)", - __func__, - MAX_NUM_ENTRIES, - psInfoHeader->ui32LayoutEntryNum); - } - -#if defined(RGX_FEATURE_MIPS_BIT_MASK) - /* Applicable to any FW_INFO_VERSION */ - if (RGX_DEVICE_HAS_FEATURE(hPrivate, MIPS)) - { - if (psInfoHeader->ui32FwPageSize != RGXGetOSPageSize(hPrivate)) - { - RGXErrorLog(hPrivate, "%s: FW page size mismatch (expected: %u, found: %u)", - __func__, - (IMG_UINT32) RGXGetOSPageSize(hPrivate), - psInfoHeader->ui32FwPageSize); - return PVRSRV_ERROR_INVALID_PARAMS; - } - } -#endif - - if (psInfoHeader->ui32InfoVersion != FW_INFO_VERSION) - { - /* Not an error because RGX_FW_INFO_HEADER is now versioned. It can grow - * incrementally and it must be backwards compatible. - */ - RGXCommentLog(hPrivate, "%s: FW info version mismatch (expected: %u, found: %u)", - __func__, - (IMG_UINT32) FW_INFO_VERSION, - psInfoHeader->ui32InfoVersion); - goto exit_version1_validation; - } - - if (psInfoHeader->ui32HeaderLen != sizeof(RGX_FW_INFO_HEADER)) - { - RGXErrorLog(hPrivate, "%s: FW info header sizes mismatch (expected: %u, found: %u)", - __func__, - (IMG_UINT32) sizeof(RGX_FW_INFO_HEADER), - psInfoHeader->ui32HeaderLen); - } - -exit_version1_validation: - return PVRSRV_OK; -} - -static inline -PVRSRV_ERROR RGXValidateFWHeaderVersion2(const void *hPrivate, - const RGX_FW_INFO_HEADER *psInfoHeader) -{ - if (psInfoHeader->ui16PVRVersionMajor != PVRVERSION_MAJ || - psInfoHeader->ui16PVRVersionMinor != PVRVERSION_MIN) - { - RGXErrorLog(hPrivate, "%s: KM and FW version mismatch (expected: %u.%u, found: %u.%u)", - __func__, - PVRVERSION_MAJ, - PVRVERSION_MIN, - psInfoHeader->ui16PVRVersionMajor, - psInfoHeader->ui16PVRVersionMinor); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - -static inline -PVRSRV_ERROR RGXValidateFWHeaderVersion(const void *hPrivate, - const RGX_FW_INFO_HEADER *psInfoHeader) -{ - PVRSRV_ERROR eError; - - switch (psInfoHeader->ui32InfoVersion) - { - default: - fallthrough; - case 2: - eError = RGXValidateFWHeaderVersion2(hPrivate, psInfoHeader); - if (eError != PVRSRV_OK) - { - return eError; - } - - fallthrough; - case 1: - eError = RGXValidateFWHeaderVersion1(hPrivate, psInfoHeader); - if (eError != PVRSRV_OK) - { - return eError; - } - - break; - case 0: - RGXErrorLog(hPrivate, "%s: invalid FW_INFO_VERSION", __func__); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXGetFWImageAllocSize(const void *hPrivate, - const IMG_BYTE *pbRGXFirmware, - const IMG_UINT32 ui32RGXFirmwareSize, - IMG_DEVMEM_SIZE_T *puiFWCodeAllocSize, - IMG_DEVMEM_SIZE_T *puiFWDataAllocSize, - IMG_DEVMEM_SIZE_T *puiFWCorememCodeAllocSize, - IMG_DEVMEM_SIZE_T *puiFWCorememDataAllocSize) -{ - RGX_FW_INFO_HEADER *psInfoHeader; - const IMG_BYTE *pbRGXFirmwareInfo; - const IMG_BYTE *pbRGXFirmwareLayout; - PVRSRV_ERROR eError; - IMG_UINT32 i; - - if (pbRGXFirmware == NULL || ui32RGXFirmwareSize == 0 || ui32RGXFirmwareSize <= FW_BLOCK_SIZE) - { - RGXErrorLog(hPrivate, "%s: Invalid FW binary at %p, size %u", - __func__, pbRGXFirmware, ui32RGXFirmwareSize); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* - * Acquire pointer to the FW info header within the FW image. - * The format of the header in the FW image might not be the one expected - * by the driver, but the driver should still be able to correctly read - * the information below, as long as new/incompatible elements are added - * at the end of the header (they will be ignored by the driver). - */ - - pbRGXFirmwareInfo = pbRGXFirmware + ui32RGXFirmwareSize - FW_BLOCK_SIZE; - psInfoHeader = (RGX_FW_INFO_HEADER*)pbRGXFirmwareInfo; - - eError = RGXValidateFWHeaderVersion(hPrivate, psInfoHeader); - if (eError != PVRSRV_OK) - { - return eError; - } - - ui32LayoutEntryNum = psInfoHeader->ui32LayoutEntryNum; - - - /* - * Copy FW layout table from FW image to local array. - * One entry is copied at a time and the copy is limited to what the driver - * expects to find in it. Assuming that new/incompatible elements - * are added at the end of each entry, the loop below adapts the table - * in the FW image into the format expected by the driver. - */ - - pbRGXFirmwareLayout = pbRGXFirmwareInfo + psInfoHeader->ui32HeaderLen; - - for (i = 0; i < ui32LayoutEntryNum; i++) - { - RGX_FW_LAYOUT_ENTRY *psOutEntry = &asRGXFWLayoutTable[i]; - - RGX_FW_LAYOUT_ENTRY *psInEntry = (RGX_FW_LAYOUT_ENTRY*) - (pbRGXFirmwareLayout + i * psInfoHeader->ui32LayoutEntrySize); - - RGXMemCopy(hPrivate, - (void*)psOutEntry, - (void*)psInEntry, - sizeof(RGX_FW_LAYOUT_ENTRY)); - } - - - /* Calculate how much memory the FW needs for its code and data segments */ - - *puiFWCodeAllocSize = 0; - *puiFWDataAllocSize = 0; - *puiFWCorememCodeAllocSize = 0; - *puiFWCorememDataAllocSize = 0; - - for (i = 0; i < ui32LayoutEntryNum; i++) - { - switch (asRGXFWLayoutTable[i].eType) - { - case FW_CODE: - *puiFWCodeAllocSize += asRGXFWLayoutTable[i].ui32AllocSize; - break; - - case FW_DATA: - *puiFWDataAllocSize += asRGXFWLayoutTable[i].ui32AllocSize; - break; - - case FW_COREMEM_CODE: - *puiFWCorememCodeAllocSize += asRGXFWLayoutTable[i].ui32AllocSize; - break; - - case FW_COREMEM_DATA: - *puiFWCorememDataAllocSize += asRGXFWLayoutTable[i].ui32AllocSize; - break; - - default: - RGXErrorLog(hPrivate, "%s: Unknown FW section type %u\n", - __func__, asRGXFWLayoutTable[i].eType); - break; - } - } - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXProcessFWImage(const void *hPrivate, - const IMG_BYTE *pbRGXFirmware, - void *pvFWCode, - void *pvFWData, - void *pvFWCorememCode, - void *pvFWCorememData, - PVRSRV_FW_BOOT_PARAMS *puFWParams) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BOOL bMIPS = IMG_FALSE; -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - IMG_BOOL bRISCV = RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR); -#endif - IMG_BOOL bMETA; - -#if defined(RGX_FEATURE_MIPS_BIT_MASK) - bMIPS = (IMG_BOOL)RGX_DEVICE_HAS_FEATURE(hPrivate, MIPS); -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - bMETA = (IMG_BOOL)(!bMIPS && !bRISCV); -#else - bMETA = !bMIPS; -#endif - - if (bMETA) - { -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - IMG_UINT32 *pui32BootConf = NULL; - /* Skip bootloader configuration if a pointer to the FW code - * allocation is not available - */ - if (pvFWCode) - { - /* This variable points to the bootloader code which is mostly - * a sequence of pairs - */ - pui32BootConf = ((IMG_UINT32*) pvFWCode) + RGXFW_BOOTLDR_CONF_OFFSET; - - /* Slave port and JTAG accesses are privileged */ - *pui32BootConf++ = META_CR_SYSC_JTAG_THREAD; - *pui32BootConf++ = META_CR_SYSC_JTAG_THREAD_PRIV_EN; - - RGXFWConfigureSegMMU(hPrivate, - &puFWParams->sMeta.sFWCodeDevVAddr, - &puFWParams->sMeta.sFWDataDevVAddr, - &pui32BootConf); - } - - /* Process FW image data stream */ - eError = ProcessLDRCommandStream(hPrivate, - pbRGXFirmware, - pvFWCode, - pvFWData, - pvFWCorememCode, - pvFWCorememData, - &pui32BootConf); - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, "RGXProcessFWImage: Processing FW image failed (%d)", eError); - return eError; - } - - /* Skip bootloader configuration if a pointer to the FW code - * allocation is not available - */ - if (pvFWCode) - { - IMG_UINT32 ui32NumThreads = puFWParams->sMeta.ui32NumThreads; - - if ((ui32NumThreads == 0) || (ui32NumThreads > 2)) - { - RGXErrorLog(hPrivate, - "ProcessFWImage: Wrong Meta threads configuration, using one thread only"); - - ui32NumThreads = 1; - } - - RGXFWConfigureMetaCaches(hPrivate, - ui32NumThreads, - &pui32BootConf); - - /* Signal the end of the conf sequence */ - *pui32BootConf++ = 0x0; - *pui32BootConf++ = 0x0; - - if (puFWParams->sMeta.uiFWCorememCodeSize && (puFWParams->sMeta.sFWCorememCodeFWAddr.ui32Addr != 0)) - { - *pui32BootConf++ = puFWParams->sMeta.sFWCorememCodeFWAddr.ui32Addr; - *pui32BootConf++ = puFWParams->sMeta.uiFWCorememCodeSize; - } - else - { - *pui32BootConf++ = 0; - *pui32BootConf++ = 0; - } - -#if defined(RGX_FEATURE_META_DMA_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, META_DMA)) - { - *pui32BootConf++ = (IMG_UINT32) (puFWParams->sMeta.sFWCorememCodeDevVAddr.uiAddr >> 32); - *pui32BootConf++ = (IMG_UINT32) puFWParams->sMeta.sFWCorememCodeDevVAddr.uiAddr; - } - else -#endif - { - *pui32BootConf++ = 0; - *pui32BootConf++ = 0; - } - } -#endif /* defined(RGX_FEATURE_META_MAX_VALUE_IDX) */ - } -#if defined(RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES) - else if (bMIPS) - { - /* Process FW image data stream */ - eError = ProcessELFCommandStream(hPrivate, - pbRGXFirmware, - pvFWCode, - pvFWData, - NULL, - NULL); - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, "RGXProcessFWImage: Processing FW image failed (%d)", eError); - return eError; - } - - if (pvFWData) - { - RGXMIPSFW_BOOT_DATA *psBootData = (RGXMIPSFW_BOOT_DATA*) - /* To get a pointer to the bootloader configuration data start from a pointer to the FW image... */ - IMG_OFFSET_ADDR(pvFWData, - /* ... jump to the boot/NMI data page... */ - (RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA) - /* ... and then jump to the bootloader data offset within the page */ - + RGXMIPSFW_BOOTLDR_CONF_OFFSET)); - - /* Rogue Registers physical address */ - psBootData->ui64RegBase = puFWParams->sMips.sGPURegAddr.uiAddr; - - /* MIPS Page Table physical address */ - psBootData->ui32PTLog2PageSize = puFWParams->sMips.ui32FWPageTableLog2PageSize; - psBootData->ui32PTNumPages = puFWParams->sMips.ui32FWPageTableNumPages; - psBootData->aui64PTPhyAddr[0U] = puFWParams->sMips.asFWPageTableAddr[0U].uiAddr; - psBootData->aui64PTPhyAddr[1U] = puFWParams->sMips.asFWPageTableAddr[1U].uiAddr; - psBootData->aui64PTPhyAddr[2U] = puFWParams->sMips.asFWPageTableAddr[2U].uiAddr; - psBootData->aui64PTPhyAddr[3U] = puFWParams->sMips.asFWPageTableAddr[3U].uiAddr; - - /* MIPS Stack Pointer Physical Address */ - psBootData->ui64StackPhyAddr = puFWParams->sMips.sFWStackAddr.uiAddr; - - /* Reserved for future use */ - psBootData->ui32Reserved1 = 0; - psBootData->ui32Reserved2 = 0; - } - } -#endif /* #if defined(RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES) */ - else - { - /* Process FW image data stream */ - eError = ProcessELFCommandStream(hPrivate, - pbRGXFirmware, - pvFWCode, - pvFWData, - pvFWCorememCode, - pvFWCorememData); - if (eError != PVRSRV_OK) - { - RGXErrorLog(hPrivate, "RGXProcessFWImage: Processing FW image failed (%d)", eError); - return eError; - } - - if (pvFWData) - { - RGXRISCVFW_BOOT_DATA *psBootData = (RGXRISCVFW_BOOT_DATA*) - IMG_OFFSET_ADDR(pvFWData, RGXRISCVFW_BOOTLDR_CONF_OFFSET); - - psBootData->ui64CorememCodeDevVAddr = puFWParams->sRISCV.sFWCorememCodeDevVAddr.uiAddr; - psBootData->ui32CorememCodeFWAddr = puFWParams->sRISCV.sFWCorememCodeFWAddr.ui32Addr; - psBootData->ui32CorememCodeSize = puFWParams->sRISCV.uiFWCorememCodeSize; - - psBootData->ui64CorememDataDevVAddr = puFWParams->sRISCV.sFWCorememDataDevVAddr.uiAddr; - psBootData->ui32CorememDataFWAddr = puFWParams->sRISCV.sFWCorememDataFWAddr.ui32Addr; - psBootData->ui32CorememDataSize = puFWParams->sRISCV.uiFWCorememDataSize; - } - } - - return eError; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.h b/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.h deleted file mode 100644 index e5f9a2afea77f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwimageutils.h +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Header for Services Firmware image utilities used at init time -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for Services Firmware image utilities used at init time -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXFWIMAGEUTILS_H -#define RGXFWIMAGEUTILS_H - -/* The routines declared here are built on top of an abstraction layer to - * hide DDK/OS-specific details in case they are used outside of the DDK - * (e.g. when DRM security is enabled). - * Any new dependency should be added to rgxlayer.h. - * Any new code should be built on top of the existing abstraction layer, - * which should be extended when necessary. - */ -#include "rgxlayer.h" - -/*! -******************************************************************************* - - @Function RGXGetFWImageSectionOffset - - @Input hPrivate : Implementation specific data - @Input eId : Section id - - @Description Return offset of a Firmware section, relative to the beginning - of the code or data allocation (depending on the section id) - -******************************************************************************/ -IMG_UINT32 RGXGetFWImageSectionOffset(const void *hPrivate, - RGX_FW_SECTION_ID eId); - -/*! -******************************************************************************* - - @Function RGXGetFWImageSectionMaxSize - - @Input hPrivate : Implementation specific data - @Input eId : Section id - - @Description Return maximum size (not allocation size) of a Firmware section - -******************************************************************************/ -IMG_UINT32 RGXGetFWImageSectionMaxSize(const void *hPrivate, - RGX_FW_SECTION_ID eId); - -/*! -******************************************************************************* - - @Function RGXGetFWImageSectionAllocSize - - @Input hPrivate : Implementation specific data - @Input eId : Section id - - @Description Return allocation size of a Firmware section - -******************************************************************************/ -IMG_UINT32 RGXGetFWImageSectionAllocSize(const void *hPrivate, - RGX_FW_SECTION_ID eId); - -/*! -******************************************************************************* - - @Function RGXGetFWImageSectionAddress - - @Input hPrivate : Implementation specific data - @Input eId : Section id - - @Description Return base address of a Firmware section - -******************************************************************************/ -IMG_UINT32 RGXGetFWImageSectionAddress(const void *hPrivate, - RGX_FW_SECTION_ID eId); - -/*! -******************************************************************************* - - @Function RGXGetFWImageAllocSize - - @Description Return size of Firmware code/data/coremem code allocations - - @Input hPrivate : Implementation specific data - @Input pbRGXFirmware : Pointer to FW binary - @Input ui32RGXFirmwareSize : FW binary size - @Output puiFWCodeAllocSize : Code size - @Output puiFWDataAllocSize : Data size - @Output puiFWCorememCodeAllocSize : Coremem code size (0 if N/A) - @Output puiFWCorememDataAllocSize : Coremem data size (0 if N/A) - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXGetFWImageAllocSize(const void *hPrivate, - const IMG_BYTE *pbRGXFirmware, - const IMG_UINT32 ui32RGXFirmwareSize, - IMG_DEVMEM_SIZE_T *puiFWCodeAllocSize, - IMG_DEVMEM_SIZE_T *puiFWDataAllocSize, - IMG_DEVMEM_SIZE_T *puiFWCorememCodeAllocSize, - IMG_DEVMEM_SIZE_T *puiFWCorememDataAllocSize); - -/*! -******************************************************************************* - - @Function ProcessLDRCommandStream - - @Description Process the output of the Meta toolchain in the .LDR format - copying code and data sections into their final location and - passing some information to the Meta bootloader - - @Input hPrivate : Implementation specific data - @Input pbLDR : Pointer to FW blob - @Input pvHostFWCodeAddr : Pointer to FW code - @Input pvHostFWDataAddr : Pointer to FW data - @Input pvHostFWCorememCodeAddr : Pointer to FW coremem code - @Input pvHostFWCorememDataAddr : Pointer to FW coremem data - @Input ppui32BootConf : Pointer to bootloader data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR ProcessLDRCommandStream(const void *hPrivate, - const IMG_BYTE* pbLDR, - void* pvHostFWCodeAddr, - void* pvHostFWDataAddr, - void* pvHostFWCorememCodeAddr, - void* pvHostFWCorememDataAddr, - IMG_UINT32 **ppui32BootConf); - -/*! -******************************************************************************* - - @Function ProcessELFCommandStream - - @Description Process a file in .ELF format copying code and data sections - into their final location - - @Input hPrivate : Implementation specific data - @Input pbELF : Pointer to FW blob - @Input pvHostFWCodeAddr : Pointer to FW code - @Input pvHostFWDataAddr : Pointer to FW data - @Input pvHostFWCorememCodeAddr : Pointer to FW coremem code - @Input pvHostFWCorememDataAddr : Pointer to FW coremem data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR ProcessELFCommandStream(const void *hPrivate, - const IMG_BYTE *pbELF, - void *pvHostFWCodeAddr, - void *pvHostFWDataAddr, - void* pvHostFWCorememCodeAddr, - void* pvHostFWCorememDataAddr); - -/*! -******************************************************************************* - - @Function RGXProcessFWImage - - @Description Process the Firmware binary blob copying code and data - sections into their final location and passing some - information to the Firmware bootloader. - If a pointer to the final memory location for FW code or data - is not valid (NULL) then the relative section will not be - processed. - - @Input hPrivate : Implementation specific data - @Input pbRGXFirmware : Pointer to FW blob - @Input pvFWCode : Pointer to FW code - @Input pvFWData : Pointer to FW data - @Input pvFWCorememCode : Pointer to FW coremem code - @Input pvFWCorememData : Pointer to FW coremem data - @Input puFWParams : Parameters used by the FW at boot time - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXProcessFWImage(const void *hPrivate, - const IMG_BYTE *pbRGXFirmware, - void *pvFWCode, - void *pvFWData, - void *pvFWCorememCode, - void *pvFWCorememData, - PVRSRV_FW_BOOT_PARAMS *puFWParams); - -#endif /* RGXFWIMAGEUTILS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwtrace_strings.c b/drivers/gpu/drm/img-rogue/1.17/rgxfwtrace_strings.c deleted file mode 100644 index d950508719949..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwtrace_strings.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ /*! -@File rgxfwtrace_strings.c -@Title RGX Firmware trace strings -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgx_fwif_sf.h" -#include "fwtrace_string.h" - -/* The tuple pairs that will be generated using XMacros will be stored here. - * This macro definition must match the definition of SFids in rgx_fwif_sf.h - */ -const RGXKM_STID_FMT SFs[]= { -#define X(a, b, c, d, e) { RGXFW_LOG_CREATESFID(a,b,e), d }, - RGXFW_LOG_SFIDLIST -#undef X -}; - -const IMG_UINT32 g_ui32SFsCount = ARRAY_SIZE(SFs); diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.c b/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.c deleted file mode 100644 index 2e98cd2055db7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.c +++ /dev/null @@ -1,7825 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Rogue firmware utility routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Rogue firmware utility routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(__linux__) -#include -#else -#include -#endif - -#include "img_defs.h" - -#include "rgxdefs_km.h" -#include "rgx_fwif_km.h" -#include "pdump_km.h" -#include "osfunc.h" -#include "oskm_apphint.h" -#include "cache_km.h" -#include "allocmem.h" -#include "physheap.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "devicemem_server.h" - -#include "pvr_debug.h" -#include "pvr_notifier.h" -#include "rgxfwutils.h" -#include "rgx_options.h" -#include "rgx_fwif_alignchecks.h" -#include "rgx_fwif_resetframework.h" -#include "rgx_pdump_panics.h" -#include "fwtrace_string.h" -#include "rgxheapconfig.h" -#include "pvrsrv.h" -#include "rgxdebug.h" -#include "rgxhwperf.h" -#include "rgxccb.h" -#include "rgxcompute.h" -#include "rgxtransfer.h" -#include "rgxpower.h" -#include "rgxtdmtransfer.h" -#if defined(SUPPORT_DISPLAY_CLASS) -#include "dc_server.h" -#endif -#include "rgxmem.h" -#include "rgxmmudefs_km.h" -#include "rgxmipsmmuinit.h" -#include "rgxta3d.h" -#include "rgxkicksync.h" -#include "rgxutils.h" -#include "rgxtimecorr.h" -#include "sync_internal.h" -#include "sync.h" -#include "sync_checkpoint.h" -#include "sync_checkpoint_external.h" -#include "tlstream.h" -#include "devicemem_server_utils.h" -#include "htbuffer.h" -#include "rgx_bvnc_defs_km.h" -#include "info_page.h" - -#include "physmem_lma.h" -#include "physmem_osmem.h" - -#ifdef __linux__ -#include /* sprintf */ -#include "rogue_trace_events.h" -#else -#include -#include -#endif -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "rgxworkest.h" -#endif - -#if defined(SUPPORT_PDVFS) -#include "rgxpdvfs.h" -#endif - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) -#include "rgxsoctimer.h" -#endif - -#include "vz_vmm_pvz.h" -#include "rgx_heaps.h" - -/*! - ****************************************************************************** - * HWPERF - *****************************************************************************/ -/* Size of the Firmware L1 HWPERF buffer in bytes (2MB). Accessed by the - * Firmware and host driver. */ -#define RGXFW_HWPERF_L1_SIZE_MIN (16U) -#define RGXFW_HWPERF_L1_SIZE_DEFAULT PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB -#define RGXFW_HWPERF_L1_SIZE_MAX (12288U) - -/* Firmware CCB length */ -#if defined(NO_HARDWARE) && defined(PDUMP) -#define RGXFWIF_FWCCB_NUMCMDS_LOG2 (10) -#elif defined(SUPPORT_PDVFS) -#define RGXFWIF_FWCCB_NUMCMDS_LOG2 (8) -#else -#define RGXFWIF_FWCCB_NUMCMDS_LOG2 (5) -#endif - -#if defined(RGX_FW_IRQ_OS_COUNTERS) -const IMG_UINT32 gaui32FwOsIrqCntRegAddr[RGXFW_MAX_NUM_OS] = {IRQ_COUNTER_STORAGE_REGS}; -#endif - -/* - * Maximum length of time a DM can run for before the DM will be marked - * as out-of-time. CDM has an increased value due to longer running kernels. - * - * These deadlines are increased on FPGA, EMU and VP due to the slower - * execution time of these platforms. PDUMPS are also included since they - * are often run on EMU, FPGA or in CSim. - */ -#if defined(FPGA) || defined(EMULATOR) || defined(VIRTUAL_PLATFORM) || defined(PDUMP) -#define RGXFWIF_MAX_WORKLOAD_DEADLINE_MS (480000) -#define RGXFWIF_MAX_CDM_WORKLOAD_DEADLINE_MS (1000000) -#else -#define RGXFWIF_MAX_WORKLOAD_DEADLINE_MS (40000) -#define RGXFWIF_MAX_CDM_WORKLOAD_DEADLINE_MS (90000) -#endif - -/* Workload Estimation Firmware CCB length */ -#define RGXFWIF_WORKEST_FWCCB_NUMCMDS_LOG2 (7) - -/* Size of memory buffer for firmware gcov data - * The actual data size is several hundred kilobytes. The buffer is an order of magnitude larger. */ -#define RGXFWIF_FIRMWARE_GCOV_BUFFER_SIZE (4*1024*1024) - -typedef struct -{ - RGXFWIF_KCCB_CMD sKCCBcmd; - DLLIST_NODE sListNode; - PDUMP_FLAGS_T uiPDumpFlags; - PVRSRV_RGXDEV_INFO *psDevInfo; -} RGX_DEFERRED_KCCB_CMD; - -#if defined(PDUMP) -/* ensure PIDs are 32-bit because a 32-bit PDump load is generated for the - * PID filter example entries - */ -static_assert(sizeof(IMG_PID) == sizeof(IMG_UINT32), - "FW PID filtering assumes the IMG_PID type is 32-bits wide as it " - "generates WRW commands for loading the PID values"); -#endif - -static void RGXFreeFwOsData(PVRSRV_RGXDEV_INFO *psDevInfo); -static void RGXFreeFwSysData(PVRSRV_RGXDEV_INFO *psDevInfo); - -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) -static PVRSRV_ERROR _AllocateSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo, RGXFWIF_SYSINIT* psFwSysInit) -{ - PVRSRV_ERROR eError; - DEVMEM_MEMDESC** ppsSLC3FenceMemDesc = &psDevInfo->psSLC3FenceMemDesc; - IMG_UINT32 ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE( - RGX_GET_FEATURE_VALUE(psDevInfo, SLC_CACHE_LINE_SIZE_BITS)); - - PVR_DPF_ENTERED; - - eError = DevmemAllocate(psDevInfo->psFirmwareMainHeap, - 1, - ui32CacheLineSize, - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwSLC3FenceWA", - ppsSLC3FenceMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF_RETURN_RC(eError); - } - - /* We need to map it so the heap for this allocation is set */ - eError = DevmemMapToDevice(*ppsSLC3FenceMemDesc, - psDevInfo->psFirmwareMainHeap, - &psFwSysInit->sSLC3FenceDevVAddr); - if (eError != PVRSRV_OK) - { - DevmemFree(*ppsSLC3FenceMemDesc); - *ppsSLC3FenceMemDesc = NULL; - } - - PVR_DPF_RETURN_RC1(eError, *ppsSLC3FenceMemDesc); -} - -static void _FreeSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo) -{ - DEVMEM_MEMDESC* psSLC3FenceMemDesc = psDevInfo->psSLC3FenceMemDesc; - - if (psSLC3FenceMemDesc) - { - DevmemReleaseDevVirtAddr(psSLC3FenceMemDesc); - DevmemFree(psSLC3FenceMemDesc); - } -} -#endif - -static void __MTSScheduleWrite(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Value) -{ - /* ensure memory is flushed before kicking MTS */ - OSWriteMemoryBarrier(NULL); - - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_SCHEDULE, ui32Value); - - /* ensure the MTS kick goes through before continuing */ -#if !defined(NO_HARDWARE) && !defined(INTEGRITY_OS) - OSWriteMemoryBarrier((IMG_BYTE*) psDevInfo->pvRegsBaseKM + RGX_CR_MTS_SCHEDULE); -#else - OSWriteMemoryBarrier(NULL); -#endif -} - -/*************************************************************************/ /*! -@Function RGXSetupFwAllocation - -@Description Sets a pointer in a firmware data structure. - -@Input psDevInfo Device Info struct -@Input uiAllocFlags Flags determining type of memory allocation -@Input ui32Size Size of memory allocation -@Input pszName Allocation label -@Input ppsMemDesc pointer to the allocation's memory descriptor -@Input psFwPtr Address of the firmware pointer to set -@Input ppvCpuPtr Address of the cpu pointer to set -@Input ui32DevVAFlags Any combination of RFW_FWADDR_*_FLAG - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXSetupFwAllocation(PVRSRV_RGXDEV_INFO* psDevInfo, - PVRSRV_MEMALLOCFLAGS_T uiAllocFlags, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszName, - DEVMEM_MEMDESC **ppsMemDesc, - RGXFWIF_DEV_VIRTADDR *psFwPtr, - void **ppvCpuPtr, - IMG_UINT32 ui32DevVAFlags) -{ - PVRSRV_ERROR eError; -#if defined(SUPPORT_AUTOVZ) - IMG_BOOL bClearByMemset; - if (PVRSRV_CHECK_ZERO_ON_ALLOC(uiAllocFlags)) - { - /* Under AutoVz the ZERO_ON_ALLOC flag is avoided as it causes the memory to - * be allocated from a different PMR than an allocation without the flag. - * When the content of an allocation needs to be recovered from physical memory - * on a later driver reboot, the memory then cannot be zeroed but the allocation - * addresses must still match. - * If the memory requires clearing, perform a memset after the allocation. */ - uiAllocFlags &= ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC; - bClearByMemset = IMG_TRUE; - } - else - { - bClearByMemset = IMG_FALSE; - } -#endif - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Allocate %s", pszName); - eError = DevmemFwAllocate(psDevInfo, - ui32Size, - uiAllocFlags, - pszName, - ppsMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate %u bytes for %s (%u)", - __func__, - ui32Size, - pszName, - eError)); - goto fail_alloc; - } - - if (psFwPtr) - { - eError = RGXSetFirmwareAddress(psFwPtr, *ppsMemDesc, 0, ui32DevVAFlags); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire firmware virtual address for %s (%u)", - __func__, - pszName, - eError)); - goto fail_fwaddr; - } - } - -#if defined(SUPPORT_AUTOVZ) - if ((bClearByMemset) || (ppvCpuPtr)) -#else - if (ppvCpuPtr) -#endif - { - void *pvTempCpuPtr; - - eError = DevmemAcquireCpuVirtAddr(*ppsMemDesc, &pvTempCpuPtr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire CPU virtual address for %s (%u)", - __func__, - pszName, - eError)); - goto fail_cpuva; - } - -#if defined(SUPPORT_AUTOVZ) - if (bClearByMemset) - { - if (PVRSRV_CHECK_CPU_WRITE_COMBINE(uiAllocFlags)) - { - OSCachedMemSetWMB(pvTempCpuPtr, 0, ui32Size); - } - else - { - OSDeviceMemSet(pvTempCpuPtr, 0, ui32Size); - } - } - if (ppvCpuPtr) -#endif - { - *ppvCpuPtr = pvTempCpuPtr; - } -#if defined(SUPPORT_AUTOVZ) - else - { - DevmemReleaseCpuVirtAddr(*ppsMemDesc); - pvTempCpuPtr = NULL; - } -#endif - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: %s set up at Fw VA 0x%x and CPU VA 0x%p with alloc flags 0x%" IMG_UINT64_FMTSPECX, - __func__, pszName, - (psFwPtr) ? (psFwPtr->ui32Addr) : (0), - (ppvCpuPtr) ? (*ppvCpuPtr) : (NULL), - uiAllocFlags)); - - return eError; - -fail_cpuva: - if (psFwPtr) - { - RGXUnsetFirmwareAddress(*ppsMemDesc); - } -fail_fwaddr: - DevmemFree(*ppsMemDesc); -fail_alloc: - return eError; -} - -/*************************************************************************/ /*! -@Function GetHwPerfBufferSize - -@Description Computes the effective size of the HW Perf Buffer -@Input ui32HWPerfFWBufSizeKB Device Info struct -@Return HwPerfBufferSize -*/ /**************************************************************************/ -static IMG_UINT32 GetHwPerfBufferSize(IMG_UINT32 ui32HWPerfFWBufSizeKB) -{ - IMG_UINT32 HwPerfBufferSize; - - /* HWPerf: Determine the size of the FW buffer */ - if (ui32HWPerfFWBufSizeKB == 0 || - ui32HWPerfFWBufSizeKB == RGXFW_HWPERF_L1_SIZE_DEFAULT) - { - /* Under pvrsrvctl 0 size implies AppHint not set or is set to zero, - * use default size from driver constant. Set it to the default - * size, no logging. - */ - HwPerfBufferSize = RGXFW_HWPERF_L1_SIZE_DEFAULT<<10; - } - else if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MAX)) - { - /* Size specified as a AppHint but it is too big */ - PVR_DPF((PVR_DBG_WARNING, - "%s: HWPerfFWBufSizeInKB value (%u) too big, using maximum (%u)", - __func__, - ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MAX)); - HwPerfBufferSize = RGXFW_HWPERF_L1_SIZE_MAX<<10; - } - else if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MIN)) - { - /* Size specified as in AppHint HWPerfFWBufSizeInKB */ - PVR_DPF((PVR_DBG_WARNING, - "%s: Using HWPerf FW buffer size of %u KB", - __func__, - ui32HWPerfFWBufSizeKB)); - HwPerfBufferSize = ui32HWPerfFWBufSizeKB<<10; - } - else - { - /* Size specified as a AppHint but it is too small */ - PVR_DPF((PVR_DBG_WARNING, - "%s: HWPerfFWBufSizeInKB value (%u) too small, using minimum (%u)", - __func__, - ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MIN)); - HwPerfBufferSize = RGXFW_HWPERF_L1_SIZE_MIN<<10; - } - - return HwPerfBufferSize; -} - -#if defined(PDUMP) -/*! -******************************************************************************* - @Function RGXFWSetupSignatureChecks - @Description - @Input psDevInfo - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXFWSetupSignatureChecks(PVRSRV_RGXDEV_INFO* psDevInfo, - DEVMEM_MEMDESC** ppsSigChecksMemDesc, - IMG_UINT32 ui32SigChecksBufSize, - RGXFWIF_SIGBUF_CTL* psSigBufCtl) -{ - PVRSRV_ERROR eError; - - /* Allocate memory for the checks */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS, - ui32SigChecksBufSize, - "FwSignatureChecks", - ppsSigChecksMemDesc, - &psSigBufCtl->sBuffer, - NULL, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - DevmemPDumpLoadMem( *ppsSigChecksMemDesc, - 0, - ui32SigChecksBufSize, - PDUMP_FLAGS_CONTINUOUS); - - psSigBufCtl->ui32LeftSizeInRegs = ui32SigChecksBufSize / sizeof(IMG_UINT32); -fail: - return eError; -} -#endif - - -#if defined(SUPPORT_FIRMWARE_GCOV) -/*! -******************************************************************************* - @Function RGXFWSetupFirmwareGcovBuffer - @Description - @Input psDevInfo - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXFWSetupFirmwareGcovBuffer(PVRSRV_RGXDEV_INFO* psDevInfo, - DEVMEM_MEMDESC** ppsBufferMemDesc, - IMG_UINT32 ui32FirmwareGcovBufferSize, - RGXFWIF_FIRMWARE_GCOV_CTL* psFirmwareGcovCtl, - const IMG_CHAR* pszBufferName) -{ - PVRSRV_ERROR eError; - - /* Allocate memory for gcov */ - eError = RGXSetupFwAllocation(psDevInfo, - (RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)), - ui32FirmwareGcovBufferSize, - pszBufferName, - ppsBufferMemDesc, - &psFirmwareGcovCtl->sBuffer, - NULL, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXSetupFwAllocation"); - - psFirmwareGcovCtl->ui32Size = ui32FirmwareGcovBufferSize; - - return PVRSRV_OK; -} -#endif - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) -/*! - ****************************************************************************** - @Function RGXFWSetupCounterBuffer - @Description - @Input psDevInfo - - @Return PVRSRV_ERROR - *****************************************************************************/ -static PVRSRV_ERROR RGXFWSetupCounterBuffer(PVRSRV_RGXDEV_INFO* psDevInfo, - DEVMEM_MEMDESC** ppsBufferMemDesc, - IMG_UINT32 ui32CounterDataBufferSize, - RGXFWIF_COUNTER_DUMP_CTL* psCounterDumpCtl, - const IMG_CHAR* pszBufferName) -{ - PVRSRV_ERROR eError; - - eError = RGXSetupFwAllocation(psDevInfo, - (RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)), - ui32CounterDataBufferSize, - "FwCounterBuffer", - ppsBufferMemDesc, - &psCounterDumpCtl->sBuffer, - NULL, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXSetupFwAllocation"); - - psCounterDumpCtl->ui32SizeInDwords = ui32CounterDataBufferSize >> 2; - - return PVRSRV_OK; -} -#endif - -/*! - ****************************************************************************** - @Function RGXFWSetupAlignChecks - @Description This functions allocates and fills memory needed for the - aligns checks of the UM and KM structures shared with the - firmware. The format of the data in the memory is as follows: - - - - - The UM array is passed from the user side. Now the firmware is - is responsible for filling this part of the memory. If that - happens the check of the UM structures will be performed - by the host driver on client's connect. - If the macro is not defined the client driver fills the memory - and the firmware checks for the alignment of all structures. - @Input psDeviceNode - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXFWSetupAlignChecks(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXFWIF_DEV_VIRTADDR *psAlignChecksDevFW) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 aui32RGXFWAlignChecksKM[] = { RGXFW_ALIGN_CHECKS_INIT_KM }; - IMG_UINT32 ui32RGXFWAlignChecksTotal; - IMG_UINT32* paui32AlignChecks; - PVRSRV_ERROR eError; - - /* In this case we don't know the number of elements in UM array. - * We have to assume something so we assume RGXFW_ALIGN_CHECKS_UM_MAX. - */ - ui32RGXFWAlignChecksTotal = sizeof(aui32RGXFWAlignChecksKM) - + RGXFW_ALIGN_CHECKS_UM_MAX * sizeof(IMG_UINT32) - + 2 * sizeof(IMG_UINT32); - - /* Allocate memory for the checks */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - ui32RGXFWAlignChecksTotal, - "FwAlignmentChecks", - &psDevInfo->psRGXFWAlignChecksMemDesc, - psAlignChecksDevFW, - (void**) &paui32AlignChecks, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - if (!psDeviceNode->bAutoVzFwIsUp) - { - /* Copy the values */ - *paui32AlignChecks++ = ARRAY_SIZE(aui32RGXFWAlignChecksKM); - OSCachedMemCopy(paui32AlignChecks, &aui32RGXFWAlignChecksKM[0], - sizeof(aui32RGXFWAlignChecksKM)); - paui32AlignChecks += ARRAY_SIZE(aui32RGXFWAlignChecksKM); - - *paui32AlignChecks = 0; - } - - OSWriteMemoryBarrier(paui32AlignChecks); - - DevmemPDumpLoadMem(psDevInfo->psRGXFWAlignChecksMemDesc, - 0, - ui32RGXFWAlignChecksTotal, - PDUMP_FLAGS_CONTINUOUS); - - return PVRSRV_OK; - -fail: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void RGXFWFreeAlignChecks(PVRSRV_RGXDEV_INFO* psDevInfo) -{ - if (psDevInfo->psRGXFWAlignChecksMemDesc != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWAlignChecksMemDesc); - psDevInfo->psRGXFWAlignChecksMemDesc = NULL; - } -} - -PVRSRV_ERROR RGXSetFirmwareAddress(RGXFWIF_DEV_VIRTADDR *ppDest, - DEVMEM_MEMDESC *psSrc, - IMG_UINT32 uiExtraOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR psDevVirtAddr; - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDeviceNode = (PVRSRV_DEVICE_NODE *) DevmemGetConnection(psSrc); - psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - IMG_UINT32 ui32Offset; - IMG_BOOL bCachedInMETA; - PVRSRV_MEMALLOCFLAGS_T uiDevFlags; - IMG_UINT32 uiGPUCacheMode; - - eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireDevVirtAddr", failDevVAAcquire); - - /* Convert to an address in META memmap */ - ui32Offset = psDevVirtAddr.uiAddr + uiExtraOffset - RGX_FIRMWARE_RAW_HEAP_BASE; - - /* Check in the devmem flags whether this memory is cached/uncached */ - DevmemGetFlags(psSrc, &uiDevFlags); - - /* Honour the META cache flags */ - bCachedInMETA = (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) & uiDevFlags) != 0; - - /* Honour the SLC cache flags */ - eError = DevmemDeviceCacheMode(psDeviceNode, uiDevFlags, &uiGPUCacheMode); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemDeviceCacheMode", failDevCacheMode); - - ui32Offset += RGXFW_SEGMMU_DATA_BASE_ADDRESS; - - if (bCachedInMETA) - { - ui32Offset |= RGXFW_SEGMMU_DATA_META_CACHED; - } - else - { - ui32Offset |= RGXFW_SEGMMU_DATA_META_UNCACHED; - } - - if (PVRSRV_CHECK_GPU_CACHED(uiGPUCacheMode)) - { - ui32Offset |= RGXFW_SEGMMU_DATA_VIVT_SLC_CACHED; - } - else - { - ui32Offset |= RGXFW_SEGMMU_DATA_VIVT_SLC_UNCACHED; - } - ppDest->ui32Addr = ui32Offset; - } - else -#endif - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr); - PVR_GOTO_IF_ERROR(eError, failDevVAAcquire); - - ppDest->ui32Addr = (IMG_UINT32)((psDevVirtAddr.uiAddr + uiExtraOffset) & 0xFFFFFFFF); - } - else - { - IMG_UINT32 ui32Offset; - IMG_BOOL bCachedInRISCV; - PVRSRV_MEMALLOCFLAGS_T uiDevFlags; - - eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireDevVirtAddr", failDevVAAcquire); - - /* Convert to an address in RISCV memmap */ - ui32Offset = psDevVirtAddr.uiAddr + uiExtraOffset - RGX_FIRMWARE_RAW_HEAP_BASE; - - /* Check in the devmem flags whether this memory is cached/uncached */ - DevmemGetFlags(psSrc, &uiDevFlags); - - /* Honour the RISCV cache flags */ - bCachedInRISCV = (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) & uiDevFlags) != 0; - - if (bCachedInRISCV) - { - ui32Offset |= RGXRISCVFW_SHARED_CACHED_DATA_BASE; - } - else - { - ui32Offset |= RGXRISCVFW_SHARED_UNCACHED_DATA_BASE; - } - - ppDest->ui32Addr = ui32Offset; - } - - if ((ppDest->ui32Addr & 0x3U) != 0) - { - IMG_CHAR *pszAnnotation; - /* It is expected that the annotation returned by DevmemGetAnnotation() is always valid */ - DevmemGetAnnotation(psSrc, &pszAnnotation); - - PVR_DPF((PVR_DBG_ERROR, "%s: %s @ 0x%x is not aligned to 32 bit", - __func__, pszAnnotation, ppDest->ui32Addr)); - - return PVRSRV_ERROR_INVALID_ALIGNMENT; - } - - if (ui32Flags & RFW_FWADDR_NOREF_FLAG) - { - DevmemReleaseDevVirtAddr(psSrc); - } - - return PVRSRV_OK; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -failDevCacheMode: - DevmemReleaseDevVirtAddr(psSrc); -#endif -failDevVAAcquire: - return eError; -} - -void RGXSetMetaDMAAddress(RGXFWIF_DMA_ADDR *psDest, - DEVMEM_MEMDESC *psSrcMemDesc, - RGXFWIF_DEV_VIRTADDR *psSrcFWDevVAddr, - IMG_UINT32 uiOffset) -{ - PVRSRV_ERROR eError; - IMG_DEV_VIRTADDR sDevVirtAddr; - - eError = DevmemAcquireDevVirtAddr(psSrcMemDesc, &sDevVirtAddr); - PVR_ASSERT(eError == PVRSRV_OK); - - psDest->psDevVirtAddr.uiAddr = sDevVirtAddr.uiAddr; - psDest->psDevVirtAddr.uiAddr += uiOffset; - psDest->pbyFWAddr.ui32Addr = psSrcFWDevVAddr->ui32Addr; - - DevmemReleaseDevVirtAddr(psSrcMemDesc); -} - - -void RGXUnsetFirmwareAddress(DEVMEM_MEMDESC *psSrc) -{ - DevmemReleaseDevVirtAddr(psSrc); -} - -struct _RGX_SERVER_COMMON_CONTEXT_ { - PVRSRV_RGXDEV_INFO *psDevInfo; - DEVMEM_MEMDESC *psFWCommonContextMemDesc; - PRGXFWIF_FWCOMMONCONTEXT sFWCommonContextFWAddr; - SERVER_MMU_CONTEXT *psServerMMUContext; - DEVMEM_MEMDESC *psFWMemContextMemDesc; - DEVMEM_MEMDESC *psFWFrameworkMemDesc; - DEVMEM_MEMDESC *psContextStateMemDesc; - RGX_CLIENT_CCB *psClientCCB; - DEVMEM_MEMDESC *psClientCCBMemDesc; - DEVMEM_MEMDESC *psClientCCBCtrlMemDesc; - IMG_BOOL bCommonContextMemProvided; - IMG_UINT32 ui32ContextID; - DLLIST_NODE sListNode; - RGX_CONTEXT_RESET_REASON eLastResetReason; - IMG_UINT32 ui32LastResetJobRef; - IMG_INT32 i32Priority; - RGX_CCB_REQUESTOR_TYPE eRequestor; -}; - -/*************************************************************************/ /*! -@Function _CheckPriority -@Description Check if priority is allowed for requestor type -@Input psDevInfo pointer to DevInfo struct -@Input i32Priority Requested priority -@Input eRequestor Requestor type specifying data master -@Return PVRSRV_ERROR PVRSRV_OK on success -*/ /**************************************************************************/ -static PVRSRV_ERROR _CheckPriority(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_INT32 i32Priority, - RGX_CCB_REQUESTOR_TYPE eRequestor) -{ - /* Only one context allowed with real time priority (highest priority) */ - if (i32Priority == RGX_CTX_PRIORITY_REALTIME) - { - DLLIST_NODE *psNode, *psNext; - - dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, psNode, psNext) - { - RGX_SERVER_COMMON_CONTEXT *psThisContext = - IMG_CONTAINER_OF(psNode, RGX_SERVER_COMMON_CONTEXT, sListNode); - - if (psThisContext->i32Priority == RGX_CTX_PRIORITY_REALTIME && - psThisContext->eRequestor == eRequestor) - { - PVR_LOG(("Only one context with real time priority allowed")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR FWCommonContextAllocate(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_CCB_REQUESTOR_TYPE eRGXCCBRequestor, - RGXFWIF_DM eDM, - SERVER_MMU_CONTEXT *psServerMMUContext, - DEVMEM_MEMDESC *psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - DEVMEM_MEMDESC *psContextStateMemDesc, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32MaxDeadlineMS, - IMG_UINT64 ui64RobustnessAddress, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_COMMON_CONTEXT **ppsServerCommonContext) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - RGXFWIF_FWCOMMONCONTEXT *psFWCommonContext; - IMG_UINT32 ui32FWCommonContextOffset; - IMG_UINT8 *pui8Ptr; - IMG_INT32 i32Priority = (IMG_INT32)ui32Priority; - PVRSRV_ERROR eError; - - /* - * Allocate all the resources that are required - */ - psServerCommonContext = OSAllocMem(sizeof(*psServerCommonContext)); - if (psServerCommonContext == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc; - } - - psServerCommonContext->psDevInfo = psDevInfo; - psServerCommonContext->psServerMMUContext = psServerMMUContext; - - if (psAllocatedMemDesc) - { - PDUMPCOMMENT(psDeviceNode, - "Using existing MemDesc for Rogue firmware %s context (offset = %d)", - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - ui32AllocatedOffset); - ui32FWCommonContextOffset = ui32AllocatedOffset; - psServerCommonContext->psFWCommonContextMemDesc = psAllocatedMemDesc; - psServerCommonContext->bCommonContextMemProvided = IMG_TRUE; - } - else - { - /* Allocate device memory for the firmware context */ - PDUMPCOMMENT(psDeviceNode, - "Allocate Rogue firmware %s context", aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT]); - eError = DevmemFwAllocate(psDevInfo, - sizeof(*psFWCommonContext), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwContext", - &psServerCommonContext->psFWCommonContextMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware %s context (%s)", - __func__, - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - PVRSRVGetErrorString(eError))); - goto fail_contextalloc; - } - ui32FWCommonContextOffset = 0; - psServerCommonContext->bCommonContextMemProvided = IMG_FALSE; - } - - /* Record this context so we can refer to it if the FW needs to tell us it was reset. */ - psServerCommonContext->eLastResetReason = RGX_CONTEXT_RESET_REASON_NONE; - psServerCommonContext->ui32LastResetJobRef = 0; - psServerCommonContext->ui32ContextID = psDevInfo->ui32CommonCtxtCurrentID++; - - /* - * Temporarily map the firmware context to the kernel and initialise it - */ - eError = DevmemAcquireCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc, - (void **)&pui8Ptr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware %s context to CPU (%s)", - __func__, - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - PVRSRVGetErrorString(eError))); - goto fail_cpuvirtacquire; - } - - /* Allocate the client CCB */ - eError = RGXCreateCCB(psDevInfo, - ui32CCBAllocSizeLog2, - ui32CCBMaxAllocSizeLog2, - ui32ContextFlags, - psConnection, - eRGXCCBRequestor, - psServerCommonContext, - &psServerCommonContext->psClientCCB, - &psServerCommonContext->psClientCCBMemDesc, - &psServerCommonContext->psClientCCBCtrlMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create CCB for %s context (%s)", - __func__, - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - PVRSRVGetErrorString(eError))); - goto fail_allocateccb; - } - - psFWCommonContext = (RGXFWIF_FWCOMMONCONTEXT *) (pui8Ptr + ui32FWCommonContextOffset); - psFWCommonContext->eDM = eDM; - - /* Set the firmware CCB device addresses in the firmware common context */ - eError = RGXSetFirmwareAddress(&psFWCommonContext->psCCB, - psServerCommonContext->psClientCCBMemDesc, - 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:1", fail_cccbfwaddr); - - eError = RGXSetFirmwareAddress(&psFWCommonContext->psCCBCtl, - psServerCommonContext->psClientCCBCtrlMemDesc, - 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:2", fail_cccbctrlfwaddr); - -#if defined(RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, META_DMA)) - { - RGXSetMetaDMAAddress(&psFWCommonContext->sCCBMetaDMAAddr, - psServerCommonContext->psClientCCBMemDesc, - &psFWCommonContext->psCCB, - 0); - } -#endif - - /* Set the memory context device address */ - psServerCommonContext->psFWMemContextMemDesc = psFWMemContextMemDesc; - eError = RGXSetFirmwareAddress(&psFWCommonContext->psFWMemContext, - psFWMemContextMemDesc, - 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:3", fail_fwmemctxfwaddr); - - /* Set the framework register updates address */ - psServerCommonContext->psFWFrameworkMemDesc = psInfo->psFWFrameworkMemDesc; - if (psInfo->psFWFrameworkMemDesc != NULL) - { - eError = RGXSetFirmwareAddress(&psFWCommonContext->psRFCmd, - psInfo->psFWFrameworkMemDesc, - 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:4", fail_fwframeworkfwaddr); - } - else - { - /* This should never be touched in this contexts without a framework - * memdesc, but ensure it is zero so we see crashes if it is. - */ - psFWCommonContext->psRFCmd.ui32Addr = 0; - } - - eError = _CheckPriority(psDevInfo, i32Priority, eRGXCCBRequestor); - PVR_LOG_GOTO_IF_ERROR(eError, "_CheckPriority", fail_checkpriority); - - psServerCommonContext->i32Priority = i32Priority; - psServerCommonContext->eRequestor = eRGXCCBRequestor; - - psFWCommonContext->i32Priority = i32Priority; - psFWCommonContext->ui32PrioritySeqNum = 0; - psFWCommonContext->ui32MaxDeadlineMS = MIN(ui32MaxDeadlineMS, - (eDM == RGXFWIF_DM_CDM ? - RGXFWIF_MAX_CDM_WORKLOAD_DEADLINE_MS : - RGXFWIF_MAX_WORKLOAD_DEADLINE_MS)); - psFWCommonContext->ui64RobustnessAddress = ui64RobustnessAddress; - - /* Store a references to Server Common Context and PID for notifications back from the FW. */ - psFWCommonContext->ui32ServerCommonContextID = psServerCommonContext->ui32ContextID; - psFWCommonContext->ui32PID = OSGetCurrentClientProcessIDKM(); - - /* Set the firmware GPU context state buffer */ - psServerCommonContext->psContextStateMemDesc = psContextStateMemDesc; - if (psContextStateMemDesc) - { - eError = RGXSetFirmwareAddress(&psFWCommonContext->psContextState, - psContextStateMemDesc, - 0, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:5", fail_ctxstatefwaddr); - } - - /* - * Dump the created context - */ - PDUMPCOMMENT(psDeviceNode, - "Dump %s context", aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT]); - DevmemPDumpLoadMem(psServerCommonContext->psFWCommonContextMemDesc, - ui32FWCommonContextOffset, - sizeof(*psFWCommonContext), - PDUMP_FLAGS_CONTINUOUS); - - /* We've finished the setup so release the CPU mapping */ - DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc); - - /* Map this allocation into the FW */ - eError = RGXSetFirmwareAddress(&psServerCommonContext->sFWCommonContextFWAddr, - psServerCommonContext->psFWCommonContextMemDesc, - ui32FWCommonContextOffset, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:6", fail_fwcommonctxfwaddr); - -#if defined(__linux__) - { - IMG_UINT32 ui32FWAddr; - switch (eDM) { - case RGXFWIF_DM_GEOM: - ui32FWAddr = (IMG_UINT32) ((uintptr_t) IMG_CONTAINER_OF((void *) ((uintptr_t) - psServerCommonContext->sFWCommonContextFWAddr.ui32Addr), RGXFWIF_FWRENDERCONTEXT, sTAContext)); - break; - case RGXFWIF_DM_3D: - ui32FWAddr = (IMG_UINT32) ((uintptr_t) IMG_CONTAINER_OF((void *) ((uintptr_t) - psServerCommonContext->sFWCommonContextFWAddr.ui32Addr), RGXFWIF_FWRENDERCONTEXT, s3DContext)); - break; - default: - ui32FWAddr = psServerCommonContext->sFWCommonContextFWAddr.ui32Addr; - break; - } - - trace_rogue_create_fw_context(OSGetCurrentClientProcessNameKM(), - aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT], - ui32FWAddr); - } -#endif - /*Add the node to the list when finalised */ - OSWRLockAcquireWrite(psDevInfo->hCommonCtxtListLock); - dllist_add_to_tail(&(psDevInfo->sCommonCtxtListHead), &(psServerCommonContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hCommonCtxtListLock); - - *ppsServerCommonContext = psServerCommonContext; - return PVRSRV_OK; - -fail_fwcommonctxfwaddr: - if (psContextStateMemDesc) - { - RGXUnsetFirmwareAddress(psContextStateMemDesc); - } -fail_ctxstatefwaddr: -fail_checkpriority: - if (psInfo->psFWFrameworkMemDesc != NULL) - { - RGXUnsetFirmwareAddress(psInfo->psFWFrameworkMemDesc); - } -fail_fwframeworkfwaddr: - RGXUnsetFirmwareAddress(psFWMemContextMemDesc); -fail_fwmemctxfwaddr: - RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBCtrlMemDesc); -fail_cccbctrlfwaddr: - RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBMemDesc); -fail_cccbfwaddr: - RGXDestroyCCB(psDevInfo, psServerCommonContext->psClientCCB); -fail_allocateccb: - DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc); -fail_cpuvirtacquire: - if (!psServerCommonContext->bCommonContextMemProvided) - { - DevmemFwUnmapAndFree(psDevInfo, psServerCommonContext->psFWCommonContextMemDesc); - psServerCommonContext->psFWCommonContextMemDesc = NULL; - } -fail_contextalloc: - OSFreeMem(psServerCommonContext); -fail_alloc: - return eError; -} - -void FWCommonContextFree(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext) -{ - - OSWRLockAcquireWrite(psServerCommonContext->psDevInfo->hCommonCtxtListLock); - /* Remove the context from the list of all contexts. */ - dllist_remove_node(&psServerCommonContext->sListNode); - OSWRLockReleaseWrite(psServerCommonContext->psDevInfo->hCommonCtxtListLock); - - /* - Unmap the context itself and then all its resources - */ - - /* Unmap the FW common context */ - RGXUnsetFirmwareAddress(psServerCommonContext->psFWCommonContextMemDesc); - /* Umap context state buffer (if there was one) */ - if (psServerCommonContext->psContextStateMemDesc) - { - RGXUnsetFirmwareAddress(psServerCommonContext->psContextStateMemDesc); - } - /* Unmap the framework buffer */ - if (psServerCommonContext->psFWFrameworkMemDesc) - { - RGXUnsetFirmwareAddress(psServerCommonContext->psFWFrameworkMemDesc); - } - /* Unmap client CCB and CCB control */ - RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBCtrlMemDesc); - RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBMemDesc); - /* Unmap the memory context */ - RGXUnsetFirmwareAddress(psServerCommonContext->psFWMemContextMemDesc); - - /* Destroy the client CCB */ - RGXDestroyCCB(psServerCommonContext->psDevInfo, psServerCommonContext->psClientCCB); - - - /* Free the FW common context (if there was one) */ - if (!psServerCommonContext->bCommonContextMemProvided) - { - DevmemFwUnmapAndFree(psServerCommonContext->psDevInfo, - psServerCommonContext->psFWCommonContextMemDesc); - psServerCommonContext->psFWCommonContextMemDesc = NULL; - } - /* Free the hosts representation of the common context */ - OSFreeMem(psServerCommonContext); -} - -PRGXFWIF_FWCOMMONCONTEXT FWCommonContextGetFWAddress(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext) -{ - return psServerCommonContext->sFWCommonContextFWAddr; -} - -RGX_CLIENT_CCB *FWCommonContextGetClientCCB(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext) -{ - return psServerCommonContext->psClientCCB; -} - -RGX_CONTEXT_RESET_REASON FWCommonContextGetLastResetReason(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - IMG_UINT32 *pui32LastResetJobRef) -{ - RGX_CONTEXT_RESET_REASON eLastResetReason; - - PVR_ASSERT(psServerCommonContext != NULL); - PVR_ASSERT(pui32LastResetJobRef != NULL); - - /* Take the most recent reason & job ref and reset for next time... */ - eLastResetReason = psServerCommonContext->eLastResetReason; - *pui32LastResetJobRef = psServerCommonContext->ui32LastResetJobRef; - psServerCommonContext->eLastResetReason = RGX_CONTEXT_RESET_REASON_NONE; - psServerCommonContext->ui32LastResetJobRef = 0; - - if (eLastResetReason == RGX_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH) - { - PVR_DPF((PVR_DBG_WARNING, - "A Hard Context Switch was triggered on the GPU to ensure Quality of Service.")); - } - - return eLastResetReason; -} - -PVRSRV_RGXDEV_INFO* FWCommonContextGetRGXDevInfo(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext) -{ - return psServerCommonContext->psDevInfo; -} - -PVRSRV_ERROR RGXGetFWCommonContextAddrFromServerMMUCtx(PVRSRV_RGXDEV_INFO *psDevInfo, - SERVER_MMU_CONTEXT *psServerMMUContext, - PRGXFWIF_FWCOMMONCONTEXT *psFWCommonContextFWAddr) -{ - DLLIST_NODE *psNode, *psNext; - dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, psNode, psNext) - { - RGX_SERVER_COMMON_CONTEXT *psThisContext = - IMG_CONTAINER_OF(psNode, RGX_SERVER_COMMON_CONTEXT, sListNode); - - if (psThisContext->psServerMMUContext == psServerMMUContext) - { - psFWCommonContextFWAddr->ui32Addr = psThisContext->sFWCommonContextFWAddr.ui32Addr; - return PVRSRV_OK; - } - } - return PVRSRV_ERROR_INVALID_PARAMS; -} - -PVRSRV_ERROR FWCommonContextSetFlags(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - IMG_UINT32 ui32ContextFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (BITMASK_ANY(ui32ContextFlags, ~RGX_CONTEXT_FLAGS_WRITEABLE_MASK)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Context flag(s) invalid or not writeable (%d)", - __func__, ui32ContextFlags)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - else - { - RGXSetCCBFlags(psServerCommonContext->psClientCCB, - ui32ContextFlags); - } - - return eError; -} - -/*! -******************************************************************************* - @Function RGXFreeCCB - @Description Free the kernel or firmware CCB - @Input psDevInfo - @Input ppsCCBCtl - @Input ppsCCBCtlMemDesc - @Input ppsCCBMemDesc - @Input psCCBCtlFWAddr -******************************************************************************/ -static void RGXFreeCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_CCB_CTL **ppsCCBCtl, - DEVMEM_MEMDESC **ppsCCBCtlMemDesc, - IMG_UINT8 **ppui8CCB, - DEVMEM_MEMDESC **ppsCCBMemDesc) -{ - if (*ppsCCBMemDesc != NULL) - { - if (*ppui8CCB != NULL) - { - DevmemReleaseCpuVirtAddr(*ppsCCBMemDesc); - *ppui8CCB = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, *ppsCCBMemDesc); - *ppsCCBMemDesc = NULL; - } - if (*ppsCCBCtlMemDesc != NULL) - { - if (*ppsCCBCtl != NULL) - { - DevmemReleaseCpuVirtAddr(*ppsCCBCtlMemDesc); - *ppsCCBCtl = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, *ppsCCBCtlMemDesc); - *ppsCCBCtlMemDesc = NULL; - } -} - -/*! -******************************************************************************* - @Function RGXFreeCCBReturnSlots - @Description Free the kernel CCB's return slot array and associated mappings - @Input psDevInfo Device Info struct - @Input ppui32CCBRtnSlots CPU mapping of slot array - @Input ppsCCBRtnSlotsMemDesc Slot array's device memdesc -******************************************************************************/ -static void RGXFreeCCBReturnSlots(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 **ppui32CCBRtnSlots, - DEVMEM_MEMDESC **ppsCCBRtnSlotsMemDesc) -{ - /* Free the return slot array if allocated */ - if (*ppsCCBRtnSlotsMemDesc != NULL) - { - /* Before freeing, ensure the CPU mapping as well is released */ - if (*ppui32CCBRtnSlots != NULL) - { - DevmemReleaseCpuVirtAddr(*ppsCCBRtnSlotsMemDesc); - *ppui32CCBRtnSlots = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, *ppsCCBRtnSlotsMemDesc); - *ppsCCBRtnSlotsMemDesc = NULL; - } -} - -/*! -******************************************************************************* - @Function RGXSetupCCB - @Description Allocate and initialise a circular command buffer - @Input psDevInfo - @Input ppsCCBCtl - @Input ppsCCBCtlMemDesc - @Input ppui8CCB - @Input ppsCCBMemDesc - @Input psCCBCtlFWAddr - @Input ui32NumCmdsLog2 - @Input ui32CmdSize - @Input uiCCBMemAllocFlags - @Input pszName - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXSetupCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_CCB_CTL **ppsCCBCtl, - DEVMEM_MEMDESC **ppsCCBCtlMemDesc, - IMG_UINT8 **ppui8CCB, - DEVMEM_MEMDESC **ppsCCBMemDesc, - PRGXFWIF_CCB_CTL *psCCBCtlFWAddr, - PRGXFWIF_CCB *psCCBFWAddr, - IMG_UINT32 ui32NumCmdsLog2, - IMG_UINT32 ui32CmdSize, - PVRSRV_MEMALLOCFLAGS_T uiCCBMemAllocFlags, - const IMG_CHAR *pszName) -{ - PVRSRV_ERROR eError; - RGXFWIF_CCB_CTL *psCCBCtl; - IMG_UINT32 ui32CCBSize = (1U << ui32NumCmdsLog2); - IMG_CHAR szCCBCtlName[DEVMEM_ANNOTATION_MAX_LEN]; - IMG_INT32 iStrLen; - - /* Append "Control" to the name for the control struct. */ - iStrLen = OSSNPrintf(szCCBCtlName, sizeof(szCCBCtlName), "%sControl", pszName); - PVR_ASSERT(iStrLen < sizeof(szCCBCtlName)); - - if (unlikely(iStrLen < 0)) - { - OSStringLCopy(szCCBCtlName, "FwCCBControl", DEVMEM_ANNOTATION_MAX_LEN); - } - - /* Allocate memory for the CCB control.*/ - eError = RGXSetupFwAllocation(psDevInfo, - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - sizeof(RGXFWIF_CCB_CTL), - szCCBCtlName, - ppsCCBCtlMemDesc, - psCCBCtlFWAddr, - (void**) ppsCCBCtl, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - /* - * Allocate memory for the CCB. - * (this will reference further command data in non-shared CCBs) - */ - eError = RGXSetupFwAllocation(psDevInfo, - uiCCBMemAllocFlags, - ui32CCBSize * ui32CmdSize, - pszName, - ppsCCBMemDesc, - psCCBFWAddr, - (void**) ppui8CCB, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - /* - * Initialise the CCB control. - */ - psCCBCtl = *ppsCCBCtl; - psCCBCtl->ui32WriteOffset = 0; - psCCBCtl->ui32ReadOffset = 0; - psCCBCtl->ui32WrapMask = ui32CCBSize - 1; - psCCBCtl->ui32CmdSize = ui32CmdSize; - - /* Pdump the CCB control */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Initialise %s", szCCBCtlName); - DevmemPDumpLoadMem(*ppsCCBCtlMemDesc, - 0, - sizeof(RGXFWIF_CCB_CTL), - 0); - - return PVRSRV_OK; - -fail: - RGXFreeCCB(psDevInfo, - ppsCCBCtl, - ppsCCBCtlMemDesc, - ppui8CCB, - ppsCCBMemDesc); - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -static void RGXSetupFaultReadRegisterRollback(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PMR *psPMR; - - if (psDevInfo->psRGXFaultAddressMemDesc) - { - if (DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc, (void **)&psPMR) == PVRSRV_OK) - { - PMRUnlockSysPhysAddresses(psPMR); - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFaultAddressMemDesc); - psDevInfo->psRGXFaultAddressMemDesc = NULL; - } -} - -static PVRSRV_ERROR RGXSetupFaultReadRegister(PVRSRV_DEVICE_NODE *psDeviceNode, RGXFWIF_SYSINIT *psFwSysInit) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 *pui32MemoryVirtAddr; - IMG_UINT32 i; - size_t ui32PageSize = OSGetPageSize(); - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PMR *psPMR; - - /* Allocate page of memory to use for page faults on non-blocking memory transactions. - * Doesn't need to be cleared as it is initialised with the 0xDEADBEE0 pattern below. */ - psDevInfo->psRGXFaultAddressMemDesc = NULL; - eError = DevmemFwAllocateExportable(psDeviceNode, - ui32PageSize, - ui32PageSize, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC, - "FwExFaultAddress", - &psDevInfo->psRGXFaultAddressMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate mem for fault address (%u)", - __func__, eError)); - goto failFaultAddressDescAlloc; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc, - (void **)&pui32MemoryVirtAddr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire mem for fault address (%u)", - __func__, eError)); - goto failFaultAddressDescAqCpuVirt; - } - - if (!psDeviceNode->bAutoVzFwIsUp) - { - /* fill the page with a known pattern when booting the firmware */ - for (i = 0; i < ui32PageSize/sizeof(IMG_UINT32); i++) - { - *(pui32MemoryVirtAddr + i) = 0xDEADBEE0; - } - } - - OSWriteMemoryBarrier(pui32MemoryVirtAddr); - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc); - - eError = DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc, (void **)&psPMR); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error getting PMR for fault address (%u)", - __func__, eError)); - - goto failFaultAddressDescGetPMR; - } - else - { - IMG_BOOL bValid; - IMG_UINT32 ui32Log2PageSize = OSGetPageShift(); - - eError = PMRLockSysPhysAddresses(psPMR); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error locking physical address for fault address MemDesc (%u)", - __func__, eError)); - - goto failFaultAddressDescLockPhys; - } - - eError = PMR_DevPhysAddr(psPMR,ui32Log2PageSize, 1, 0, &(psFwSysInit->sFaultPhysAddr), &bValid); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error getting physical address for fault address MemDesc (%u)", - __func__, eError)); - - goto failFaultAddressDescGetPhys; - } - - if (!bValid) - { - psFwSysInit->sFaultPhysAddr.uiAddr = 0; - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed getting physical address for fault address MemDesc - invalid page (0x%" IMG_UINT64_FMTSPECX ")", - __func__, psFwSysInit->sFaultPhysAddr.uiAddr)); - - goto failFaultAddressDescGetPhys; - } - } - - return PVRSRV_OK; - -failFaultAddressDescGetPhys: - PMRUnlockSysPhysAddresses(psPMR); - -failFaultAddressDescLockPhys: -failFaultAddressDescGetPMR: -failFaultAddressDescAqCpuVirt: - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFaultAddressMemDesc); - psDevInfo->psRGXFaultAddressMemDesc = NULL; - -failFaultAddressDescAlloc: - - return eError; -} - -#if defined(PDUMP) -/* Replace the DevPhy address with the one Pdump allocates at pdump_player run time */ -static PVRSRV_ERROR RGXPDumpFaultReadRegister(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PVRSRV_ERROR eError; - PMR *psFWInitPMR, *psFaultAddrPMR; - IMG_UINT32 ui32Dstoffset; - - psFWInitPMR = (PMR *)(psDevInfo->psRGXFWIfSysInitMemDesc->psImport->hPMR); - ui32Dstoffset = psDevInfo->psRGXFWIfSysInitMemDesc->uiOffset + offsetof(RGXFWIF_SYSINIT, sFaultPhysAddr.uiAddr); - - psFaultAddrPMR = (PMR *)(psDevInfo->psRGXFaultAddressMemDesc->psImport->hPMR); - - eError = PDumpMemLabelToMem64(psFaultAddrPMR, - psFWInitPMR, - 0, - ui32Dstoffset, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Dump of Fault Page Phys address failed(%u)", __func__, eError)); - } - return eError; -} -#endif - -#if defined(SUPPORT_TBI_INTERFACE) -/*************************************************************************/ /*! -@Function RGXTBIBufferIsInitRequired - -@Description Returns true if the firmware tbi buffer is not allocated and - might be required by the firmware soon. TBI buffer allocated - on-demand to reduce RAM footprint on systems not needing - tbi. - -@Input psDevInfo RGX device info - -@Return IMG_BOOL Whether on-demand allocation(s) is/are needed - or not -*/ /**************************************************************************/ -INLINE IMG_BOOL RGXTBIBufferIsInitRequired(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - - /* The firmware expects a tbi buffer only when: - * - Logtype is "tbi" - */ - if ((psDevInfo->psRGXFWIfTBIBufferMemDesc == NULL) - && (psTraceBufCtl->ui32LogType & ~RGXFWIF_LOG_TYPE_TRACE) - && (psTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK)) - { - return IMG_TRUE; - } - - return IMG_FALSE; -} - -/*************************************************************************/ /*! -@Function RGXTBIBufferDeinit - -@Description Deinitialises all the allocations and references that are made - for the FW tbi buffer - -@Input ppsDevInfo RGX device info -@Return void -*/ /**************************************************************************/ -static void RGXTBIBufferDeinit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfTBIBufferMemDesc); - psDevInfo->psRGXFWIfTBIBufferMemDesc = NULL; - psDevInfo->ui32RGXFWIfHWPerfBufSize = 0; -} - -/*************************************************************************/ /*! -@Function RGXTBIBufferInitOnDemandResources - -@Description Allocates the firmware TBI buffer required for reading SFs - strings and initialize it with SFs. - -@Input psDevInfo RGX device info - -@Return PVRSRV_OK If all went good, PVRSRV_ERROR otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR RGXTBIBufferInitOnDemandResources(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 i, ui32Len; - const IMG_UINT32 ui32FWTBIBufsize = g_ui32SFsCount * sizeof(RGXFW_STID_FMT); - RGXFW_STID_FMT *psFW_SFs = NULL; - - /* Firmware address should not be already set */ - if (psDevInfo->sRGXFWIfTBIBuffer.ui32Addr) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: FW address for FWTBI is already set. Resetting it with newly allocated one", - __func__)); - } - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_GPU_RO_ALLOCFLAGS, - ui32FWTBIBufsize, - "FwTBIBuffer", - &psDevInfo->psRGXFWIfTBIBufferMemDesc, - &psDevInfo->sRGXFWIfTBIBuffer, - (void**)&psFW_SFs, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - /* Copy SFs entries to FW buffer */ - for (i = 0; i < g_ui32SFsCount; i++) - { - OSCachedMemCopy(&psFW_SFs[i].ui32Id, &SFs[i].ui32Id, sizeof(SFs[i].ui32Id)); - ui32Len = OSStringLength(SFs[i].psName); - OSCachedMemCopy(psFW_SFs[i].sName, SFs[i].psName, MIN(ui32Len, IMG_SF_STRING_MAX_SIZE - 1)); - } - - /* flush write buffers for psFW_SFs */ - OSWriteMemoryBarrier(psFW_SFs); - - /* Set size of TBI buffer */ - psDevInfo->ui32FWIfTBIBufferSize = ui32FWTBIBufsize; - - /* release CPU mapping */ - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTBIBufferMemDesc); - - return PVRSRV_OK; -fail: - RGXTBIBufferDeinit(psDevInfo); - return eError; -} -#endif - -/*************************************************************************/ /*! -@Function RGXTraceBufferIsInitRequired - -@Description Returns true if the firmware trace buffer is not allocated and - might be required by the firmware soon. Trace buffer allocated - on-demand to reduce RAM footprint on systems not needing - firmware trace. - -@Input psDevInfo RGX device info - -@Return IMG_BOOL Whether on-demand allocation(s) is/are needed - or not -*/ /**************************************************************************/ -INLINE IMG_BOOL RGXTraceBufferIsInitRequired(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - - /* The firmware expects a trace buffer only when: - * - Logtype is "trace" AND - * - at least one LogGroup is configured - * - the Driver Mode is not Guest - */ - if ((psDevInfo->psRGXFWIfTraceBufferMemDesc[0] == NULL) - && (psTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE) - && (psTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK) - && !PVRSRV_VZ_MODE_IS(GUEST)) - { - return IMG_TRUE; - } - - return IMG_FALSE; -} - -/*************************************************************************/ /*! -@Function RGXTraceBufferDeinit - -@Description Deinitialises all the allocations and references that are made - for the FW trace buffer(s) - -@Input ppsDevInfo RGX device info -@Return void -*/ /**************************************************************************/ -static void RGXTraceBufferDeinit(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - IMG_UINT32 i; - - for (i = 0; i < RGXFW_THREAD_NUM; i++) - { - if (psDevInfo->psRGXFWIfTraceBufferMemDesc[i]) - { - if (psTraceBufCtl->sTraceBuf[i].pui32TraceBuffer != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufferMemDesc[i]); - psTraceBufCtl->sTraceBuf[i].pui32TraceBuffer = NULL; - } - - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfTraceBufferMemDesc[i]); - psDevInfo->psRGXFWIfTraceBufferMemDesc[i] = NULL; - } - } -} - -/*************************************************************************/ /*! -@Function RGXTraceBufferInitOnDemandResources - -@Description Allocates the firmware trace buffer required for dumping trace - info from the firmware. - -@Input psDevInfo RGX device info - -@Return PVRSRV_OK If all went good, PVRSRV_ERROR otherwise. -*/ /**************************************************************************/ -PVRSRV_ERROR RGXTraceBufferInitOnDemandResources(PVRSRV_RGXDEV_INFO* psDevInfo, - PVRSRV_MEMALLOCFLAGS_T uiAllocFlags) -{ - RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32FwThreadNum; - IMG_UINT32 ui32DefaultTraceBufSize; - IMG_DEVMEM_SIZE_T uiTraceBufSizeInBytes; - void *pvAppHintState = NULL; - IMG_CHAR pszBufferName[] = "FwTraceBuffer_Thread0"; - - /* Check AppHint value for module-param FWTraceBufSizeInDWords */ - OSCreateKMAppHintState(&pvAppHintState); - ui32DefaultTraceBufSize = RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, - pvAppHintState, - FWTraceBufSizeInDWords, - &ui32DefaultTraceBufSize, - &psTraceBufCtl->ui32TraceBufSizeInDWords); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - uiTraceBufSizeInBytes = psTraceBufCtl->ui32TraceBufSizeInDWords * sizeof(IMG_UINT32); - - for (ui32FwThreadNum = 0; ui32FwThreadNum < RGXFW_THREAD_NUM; ui32FwThreadNum++) - { -#if !defined(SUPPORT_AUTOVZ) - /* Ensure allocation API is only called when not already allocated */ - PVR_ASSERT(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum] == NULL); - /* Firmware address should not be already set */ - PVR_ASSERT(psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32RGXFWIfTraceBuffer.ui32Addr == 0x0); -#endif - - /* update the firmware thread number in the Trace Buffer's name */ - pszBufferName[sizeof(pszBufferName) - 2] += ui32FwThreadNum; - - eError = RGXSetupFwAllocation(psDevInfo, - uiAllocFlags, - uiTraceBufSizeInBytes, - pszBufferName, - &psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum], - &psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32RGXFWIfTraceBuffer, - (void**)&psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32TraceBuffer, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - } - - return PVRSRV_OK; - -fail: - RGXTraceBufferDeinit(psDevInfo); - return eError; -} - -#if defined(PDUMP) -/*************************************************************************/ /*! -@Function RGXPDumpLoadFWInitData - -@Description Allocates the firmware trace buffer required for dumping trace - info from the firmware. - -@Input psDevInfo RGX device info - */ /*************************************************************************/ -static void RGXPDumpLoadFWInitData(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_BOOL bEnableSignatureChecks) -{ - IMG_UINT32 ui32ConfigFlags = psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags; - IMG_UINT32 ui32FwOsCfgFlags = psDevInfo->psRGXFWIfFwOsData->ui32FwOsConfigFlags; - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Dump RGXFW Init data"); - if (!bEnableSignatureChecks) - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(to enable rgxfw signatures place the following line after the RTCONF line)"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, asSigBufCtl), - sizeof(RGXFWIF_SIGBUF_CTL)*(RGXFWIF_DM_MAX), - PDUMP_FLAGS_CONTINUOUS); - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump initial state of FW runtime configuration"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - 0, - sizeof(RGXFWIF_RUNTIME_CFG), - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgxfw hwperfctl structure"); - DevmemPDumpLoadZeroMem(psDevInfo->psRGXFWIfHWPerfCountersMemDesc, - 0, - ui32HWPerfCountersDataSize, - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgxfw trace control structure"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - 0, - sizeof(RGXFWIF_TRACEBUF), - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump firmware system data structure"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfFwSysDataMemDesc, - 0, - sizeof(RGXFWIF_SYSDATA), - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump firmware OS data structure"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfFwOsDataMemDesc, - 0, - sizeof(RGXFWIF_OSDATA), - PDUMP_FLAGS_CONTINUOUS); - -#if defined(SUPPORT_TBI_INTERFACE) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgx TBI buffer"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfTBIBufferMemDesc, - 0, - psDevInfo->ui32FWIfTBIBufferSize, - PDUMP_FLAGS_CONTINUOUS); -#endif /* defined(SUPPORT_TBI_INTERFACE) */ - -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgxfw register configuration buffer"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfRegCfgMemDesc, - 0, - sizeof(RGXFWIF_REG_CFG), - PDUMP_FLAGS_CONTINUOUS); -#endif /* defined(SUPPORT_USER_REGISTER_CONFIGURATION) */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgxfw system init structure"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfSysInitMemDesc, - 0, - sizeof(RGXFWIF_SYSINIT), - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Dump rgxfw os init structure"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfOsInitMemDesc, - 0, - sizeof(RGXFWIF_OSINIT), - PDUMP_FLAGS_CONTINUOUS); - - /* RGXFW Init structure needs to be loaded before we overwrite FaultPhysAddr, else this address patching won't have any effect */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Overwrite FaultPhysAddr of FwSysInit in pdump with actual physical address"); - RGXPDumpFaultReadRegister(psDevInfo); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "RTCONF: run-time configuration"); - - - /* Dump the config options so they can be edited. - * - */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(Set the FW system config options here)"); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch Rand mode: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_MODE_RAND); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch Soft Reset Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_SRESET_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable HWPerf: 0x%08x)", RGXFWIF_INICFG_HWPERF_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable generic DM Killing Rand mode: 0x%08x)", RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Rascal+Dust Power Island: 0x%08x)", RGXFWIF_INICFG_POW_RASCALDUST); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( FBCDC Version 3.1 Enable: 0x%08x)", RGXFWIF_INICFG_FBCDC_V3_1_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Check MList: 0x%08x)", RGXFWIF_INICFG_CHECK_MLIST_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Disable Auto Clock Gating: 0x%08x)", RGXFWIF_INICFG_DISABLE_CLKGATING_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable register configuration: 0x%08x)", RGXFWIF_INICFG_REGCONFIG_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Assert on TA Out-of-Memory: 0x%08x)", RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Disable HWPerf custom counter filter: 0x%08x)", RGXFWIF_INICFG_HWP_DISABLE_FILTER); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable Ctx Switch profile mode: 0x%08x (none=b'000, fast=b'001, medium=b'010, slow=b'011, nodelay=b'100))", RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Disable DM overlap (except TA during SPM): 0x%08x)", RGXFWIF_INICFG_DISABLE_DM_OVERLAP); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Assert on HWR trigger (page fault, lockup, overrun or poll failure): 0x%08x)", RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable coherent memory accesses: 0x%08x)", RGXFWIF_INICFG_FABRIC_COHERENCY_ENABLED); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable IRQ validation: 0x%08x)", RGXFWIF_INICFG_VALIDATE_IRQ); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( SPU power state mask change Enable: 0x%08x)", RGXFWIF_INICFG_SPU_POWER_STATE_MASK_CHANGE_EN); -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable Workload Estimation: 0x%08x)", RGXFWIF_INICFG_WORKEST); -#if defined(SUPPORT_PDVFS) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Enable Proactive DVFS: 0x%08x)", RGXFWIF_INICFG_PDVFS); -#endif /* defined(SUPPORT_PDVFS) */ -#endif /* defined(SUPPORT_WORKLOAD_ESTIMATION) */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( CDM Arbitration Mode (task demand=b'01, round robin=b'10): 0x%08x)", RGXFWIF_INICFG_CDM_ARBITRATION_MASK); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( ISP Scheduling Mode (v1=b'01, v2=b'10): 0x%08x)", RGXFWIF_INICFG_ISPSCHEDMODE_MASK); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Validate SOC & USC timers: 0x%08x)", RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER); - - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfFwSysDataMemDesc, - offsetof(RGXFWIF_SYSDATA, ui32ConfigFlags), - ui32ConfigFlags, - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Extended FW system config options not used.)"); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(Set the FW OS config options here)"); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch TDM Enable: 0x%08x)", RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch TA Enable: 0x%08x)", RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch 3D Enable: 0x%08x)", RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Ctx Switch CDM Enable: 0x%08x)", RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Lower Priority Ctx Switch 2D Enable: 0x%08x)", RGXFWIF_INICFG_OS_LOW_PRIO_CS_TDM); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Lower Priority Ctx Switch TA Enable: 0x%08x)", RGXFWIF_INICFG_OS_LOW_PRIO_CS_GEOM); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Lower Priority Ctx Switch 3D Enable: 0x%08x)", RGXFWIF_INICFG_OS_LOW_PRIO_CS_3D); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Lower Priority Ctx Switch CDM Enable: 0x%08x)", RGXFWIF_INICFG_OS_LOW_PRIO_CS_CDM); - - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfFwOsDataMemDesc, - offsetof(RGXFWIF_OSDATA, ui32FwOsConfigFlags), - ui32FwOsCfgFlags, - PDUMP_FLAGS_CONTINUOUS); - - -#if defined(SUPPORT_SECURITY_VALIDATION) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(Select one or more security tests here)"); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Read/write FW private data from non-FW contexts: 0x%08x)", RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_DATA); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Read/write FW code from non-FW contexts: 0x%08x)", RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_CODE); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Execute FW code from non-secure memory: 0x%08x)", RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_NONSECURE); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Execute FW code from secure (non-FW) memory: 0x%08x)", RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_SECURE); - - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, ui32SecurityTestFlags), - psDevInfo->psRGXFWIfSysInit->ui32SecurityTestFlags, - PDUMP_FLAGS_CONTINUOUS); -#endif - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( PID filter type: %X=INCLUDE_ALL_EXCEPT, %X=EXCLUDE_ALL_EXCEPT)", - RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT, - RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT); - - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, sPIDFilter.eMode), - psDevInfo->psRGXFWIfSysInit->sPIDFilter.eMode, - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( PID filter PID/OSID list (Up to %u entries. Terminate with a zero PID))", - RGXFWIF_PID_FILTER_MAX_NUM_PIDS); - { - IMG_UINT32 i; - - /* generate a few WRWs in the pdump stream as an example */ - for (i = 0; i < MIN(RGXFWIF_PID_FILTER_MAX_NUM_PIDS, 8); i++) - { - /* - * Some compilers cannot cope with the uses of offsetof() below - the specific problem being the use of - * a non-const variable in the expression, which it needs to be const. Typical compiler output is - * "expression must have a constant value". - */ - const IMG_DEVMEM_OFFSET_T uiPIDOff - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_SYSINIT *)0)->sPIDFilter.asItems[i].uiPID); - - const IMG_DEVMEM_OFFSET_T uiOSIDOff - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_SYSINIT *)0)->sPIDFilter.asItems[i].ui32OSID); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(PID and OSID pair %u)", i); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "(PID)"); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfSysInitMemDesc, - uiPIDOff, - 0, - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "(OSID)"); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfSysInitMemDesc, - uiOSIDOff, - 0, - PDUMP_FLAGS_CONTINUOUS); - } - } - - /* - * Dump the log config so it can be edited. - */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(Set the log config here)"); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( Log Type: set bit 0 for TRACE, reset for TBI)"); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( MAIN Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MAIN); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( MTS Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MTS); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( CLEANUP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CLEANUP); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( CSW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CSW); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( BIF Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_BIF); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( PM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_PM); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( RTD Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_RTD); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( SPM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_SPM); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( POW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_POW); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( HWR Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWR); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( HWP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWP); - -#if defined(RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, META_DMA)) - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( DMA Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DMA); - } -#endif - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( MISC Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MISC); - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "( DEBUG Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DEBUG); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - offsetof(RGXFWIF_TRACEBUF, ui32LogType), - psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType, - PDUMP_FLAGS_CONTINUOUS); - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Set the HWPerf Filter config here, see \"hwperfbin2jsont -h\""); - DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, ui64HWPerfFilter), - psDevInfo->psRGXFWIfSysInit->ui64HWPerfFilter, - PDUMP_FLAGS_CONTINUOUS); - -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "(Number of registers configurations for types(byte index): pow on(%d), dust change(%d), ta(%d), 3d(%d), cdm(%d), tla(%d), TDM(%d))", - RGXFWIF_REG_CFG_TYPE_PWR_ON, - RGXFWIF_REG_CFG_TYPE_DUST_CHANGE, - RGXFWIF_REG_CFG_TYPE_TA, - RGXFWIF_REG_CFG_TYPE_3D, - RGXFWIF_REG_CFG_TYPE_CDM, - RGXFWIF_REG_CFG_TYPE_TLA, - RGXFWIF_REG_CFG_TYPE_TDM); - - { - IMG_UINT32 i; - - /* Write 32 bits in each iteration as required by PDUMP WRW command */ - for (i = 0; i < RGXFWIF_REG_CFG_TYPE_ALL; i += sizeof(IMG_UINT32)) - { - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc, - offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[i]), - 0, - PDUMP_FLAGS_CONTINUOUS); - } - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "(Set registers here: address, mask, value)"); - DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc, - offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Addr), - 0, - PDUMP_FLAGS_CONTINUOUS); - DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc, - offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Mask), - 0, - PDUMP_FLAGS_CONTINUOUS); - DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc, - offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Value), - 0, - PDUMP_FLAGS_CONTINUOUS); -#endif /* SUPPORT_USER_REGISTER_CONFIGURATION */ -} -#endif /* defined(PDUMP) */ - -/*! -******************************************************************************* - @Function RGXSetupFwGuardPage - - @Description Allocate a Guard Page at the start of a Guest's Main Heap - - @Input psDevceNode - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXSetupFwGuardPage(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PVRSRV_ERROR eError; - - eError = RGXSetupFwAllocation(psDevInfo, - (RGX_FWSHAREDMEM_GPU_ONLY_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN)), - OSGetPageSize(), - "FwGuardPage", - &psDevInfo->psRGXFWHeapGuardPageReserveMemDesc, - NULL, - NULL, - RFW_FWADDR_FLAG_NONE); - - return eError; -} - -/*! -******************************************************************************* - @Function RGXSetupFwSysData - - @Description Sets up all system-wide firmware related data - - @Input psDevInfo - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXSetupFwSysData(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bEnableSignatureChecks, - IMG_UINT32 ui32SignatureChecksBufSize, - IMG_UINT32 ui32HWPerfFWBufSizeKB, - IMG_UINT64 ui64HWPerfFilter, - IMG_UINT32 ui32ConfigFlags, - IMG_UINT32 ui32ConfigFlagsExt, - IMG_UINT32 ui32LogType, - IMG_UINT32 ui32FilterFlags, - IMG_UINT32 ui32JonesDisableMask, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_UINT32 *pui32TPUTrilinearFracMask, - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf, - FW_PERF_CONF eFirmwarePerf) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_SYSINIT *psFwSysInitScratch = NULL; - - psFwSysInitScratch = OSAllocZMem(sizeof(*psFwSysInitScratch)); - PVR_LOG_GOTO_IF_NOMEM(psFwSysInitScratch, eError, fail); - - /* Sys Fw init data */ - eError = RGXSetupFwAllocation(psDevInfo, - (RGX_FWSHAREDMEM_CONFIG_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)) & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_SYSINIT), - "FwSysInitStructure", - &psDevInfo->psRGXFWIfSysInitMemDesc, - NULL, - (void**) &psDevInfo->psRGXFWIfSysInit, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware Sys Init structure allocation", fail); - - /* Setup Fault read register */ - eError = RGXSetupFaultReadRegister(psDeviceNode, psFwSysInitScratch); - PVR_LOG_GOTO_IF_ERROR(eError, "Fault read register setup", fail); - -#if defined(SUPPORT_AUTOVZ) - psFwSysInitScratch->ui32VzWdgPeriod = PVR_AUTOVZ_WDG_PERIOD_MS; -#endif - - /* RD Power Island */ - { - RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - IMG_BOOL bSysEnableRDPowIsland = psRGXData->psRGXTimingInfo->bEnableRDPowIsland; - IMG_BOOL bEnableRDPowIsland = ((eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_DEFAULT) && bSysEnableRDPowIsland) || - (eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_FORCE_ON); - - ui32ConfigFlags |= bEnableRDPowIsland? RGXFWIF_INICFG_POW_RASCALDUST : 0; - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - ui32ConfigFlags |= RGXFWIF_INICFG_WORKEST; -#if defined(SUPPORT_PDVFS) - { - RGXFWIF_PDVFS_OPP *psPDVFSOPPInfo; - IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg; - - /* Pro-active DVFS depends on Workload Estimation */ - psPDVFSOPPInfo = &psFwSysInitScratch->sPDVFSOPPInfo; - psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg; - PVR_LOG_IF_FALSE(psDVFSDeviceCfg->pasOPPTable, "RGXSetupFwSysData: Missing OPP Table"); - - if (psDVFSDeviceCfg->pasOPPTable != NULL) - { - if (psDVFSDeviceCfg->ui32OPPTableSize > ARRAY_SIZE(psPDVFSOPPInfo->asOPPValues)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OPP Table too large: Size = %u, Maximum size = %lu", - __func__, - psDVFSDeviceCfg->ui32OPPTableSize, - (unsigned long)(ARRAY_SIZE(psPDVFSOPPInfo->asOPPValues)))); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail; - } - - OSDeviceMemCopy(psPDVFSOPPInfo->asOPPValues, - psDVFSDeviceCfg->pasOPPTable, - sizeof(psPDVFSOPPInfo->asOPPValues)); - - psPDVFSOPPInfo->ui32MaxOPPPoint = psDVFSDeviceCfg->ui32OPPTableSize - 1; - - ui32ConfigFlags |= RGXFWIF_INICFG_PDVFS; - } - } -#endif /* defined(SUPPORT_PDVFS) */ -#endif /* defined(SUPPORT_WORKLOAD_ESTIMATION) */ - - /* FW trace control structure */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_TRACEBUF), - "FwTraceCtlStruct", - &psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - &psFwSysInitScratch->sTraceBufCtl, - (void**) &psDevInfo->psRGXFWIfTraceBufCtl, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - if (!psDeviceNode->bAutoVzFwIsUp) - { - /* Set initial firmware log type/group(s) */ - if (ui32LogType & ~RGXFWIF_LOG_TYPE_MASK) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid initial log type (0x%X)", - __func__, ui32LogType)); - goto fail; - } - psDevInfo->psRGXFWIfTraceBufCtl->ui32LogType = ui32LogType; - } - - /* When PDUMP is enabled, ALWAYS allocate on-demand trace buffer resource - * (irrespective of loggroup(s) enabled), given that logtype/loggroups can - * be set during PDump playback in logconfig, at any point of time, - * Otherwise, allocate only if required. */ -#if !defined(PDUMP) -#if defined(SUPPORT_AUTOVZ) - /* always allocate trace buffer for AutoVz Host drivers to allow - * deterministic addresses of all SysData structures */ - if ((PVRSRV_VZ_MODE_IS(HOST)) || (RGXTraceBufferIsInitRequired(psDevInfo))) -#else - if (RGXTraceBufferIsInitRequired(psDevInfo)) -#endif -#endif - { - eError = RGXTraceBufferInitOnDemandResources(psDevInfo, - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp)); - } - PVR_LOG_GOTO_IF_ERROR(eError, "RGXTraceBufferInitOnDemandResources", fail); - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_SYSDATA), - "FwSysData", - &psDevInfo->psRGXFWIfFwSysDataMemDesc, - &psFwSysInitScratch->sFwSysData, - (void**) &psDevInfo->psRGXFWIfFwSysData, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - /* GPIO validation setup */ - psFwSysInitScratch->eGPIOValidationMode = RGXFWIF_GPIO_VAL_OFF; -#if defined(SUPPORT_VALIDATION) - { - IMG_INT32 ui32AppHintDefault; - IMG_INT32 ui32GPIOValidationMode; - void *pvAppHintState = NULL; - - /* Check AppHint for GPIO validation mode */ - OSCreateKMAppHintState(&pvAppHintState); - ui32AppHintDefault = PVRSRV_APPHINT_GPIOVALIDATIONMODE; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, - pvAppHintState, - GPIOValidationMode, - &ui32AppHintDefault, - &ui32GPIOValidationMode); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - if (ui32GPIOValidationMode >= RGXFWIF_GPIO_VAL_LAST) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid GPIO validation mode: %d, only valid if smaller than %d. Disabling GPIO validation.", - __func__, - ui32GPIOValidationMode, - RGXFWIF_GPIO_VAL_LAST)); - } - else - { - psFwSysInitScratch->eGPIOValidationMode = (RGXFWIF_GPIO_VAL_MODE) ui32GPIOValidationMode; - } - - psFwSysInitScratch->eGPIOValidationMode = ui32GPIOValidationMode; - } -#endif - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) - eError = RGXFWSetupCounterBuffer(psDevInfo, - &psDevInfo->psCounterBufferMemDesc, - PAGE_SIZE, - &psFwSysInitScratch->sCounterDumpCtl, - "CounterBuffer"); - PVR_LOG_GOTO_IF_ERROR(eError, "Counter Buffer allocation", fail); -#endif /* defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) */ - -#if defined(SUPPORT_VALIDATION) - { - IMG_UINT32 ui32EnablePollOnChecksumErrorStatus; - IMG_UINT32 ui32ApphintDefault = 0; - void *pvAppHintState = NULL; - - /* Check AppHint for polling on GPU Checksum status */ - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, - pvAppHintState, - EnablePollOnChecksumErrorStatus, - &ui32ApphintDefault, - &ui32EnablePollOnChecksumErrorStatus); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - switch (ui32EnablePollOnChecksumErrorStatus) - { - case 0: /* no checking */ break; - case 3: psDevInfo->ui32ValidationFlags |= RGX_VAL_KZ_SIG_CHECK_NOERR_EN; break; - case 4: psDevInfo->ui32ValidationFlags |= RGX_VAL_KZ_SIG_CHECK_ERR_EN; break; - default: - PVR_DPF((PVR_DBG_WARNING, "Unsupported value in EnablePollOnChecksumErrorStatus (%d)", ui32EnablePollOnChecksumErrorStatus)); - break; - } - } -#endif /* defined(SUPPORT_VALIDATION) */ - -#if defined(SUPPORT_FIRMWARE_GCOV) - eError = RGXFWSetupFirmwareGcovBuffer(psDevInfo, - &psDevInfo->psFirmwareGcovBufferMemDesc, - RGXFWIF_FIRMWARE_GCOV_BUFFER_SIZE, - &psFwSysInitScratch->sFirmwareGcovCtl, - "FirmwareGcovBuffer"); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware GCOV buffer allocation", fail); - psDevInfo->ui32FirmwareGcovSize = RGXFWIF_FIRMWARE_GCOV_BUFFER_SIZE; -#endif /* defined(SUPPORT_FIRMWARE_GCOV) */ - -#if defined(PDUMP) - /* Require a minimum amount of memory for the signature buffers */ - if (ui32SignatureChecksBufSize < RGXFW_SIG_BUFFER_SIZE_MIN) - { - ui32SignatureChecksBufSize = RGXFW_SIG_BUFFER_SIZE_MIN; - } - - /* Setup Signature and Checksum Buffers for TDM, GEOM and 3D */ - eError = RGXFWSetupSignatureChecks(psDevInfo, - &psDevInfo->psRGXFWSigTAChecksMemDesc, - ui32SignatureChecksBufSize, - &psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_GEOM]); - PVR_LOG_GOTO_IF_ERROR(eError, "TA Signature check setup", fail); - psDevInfo->ui32SigTAChecksSize = ui32SignatureChecksBufSize; - - eError = RGXFWSetupSignatureChecks(psDevInfo, - &psDevInfo->psRGXFWSig3DChecksMemDesc, - ui32SignatureChecksBufSize, - &psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_3D]); - PVR_LOG_GOTO_IF_ERROR(eError, "3D Signature check setup", fail); - psDevInfo->ui32Sig3DChecksSize = ui32SignatureChecksBufSize; - - psDevInfo->psRGXFWSigTDM2DChecksMemDesc = NULL; - psDevInfo->ui32SigTDM2DChecksSize = 0; - -#if defined(RGX_FEATURE_TDM_PDS_CHECKSUM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TDM_PDS_CHECKSUM)) - { - /* Buffer allocated only when feature present because, all known TDM - * signature registers are dependent on this feature being present */ - eError = RGXFWSetupSignatureChecks(psDevInfo, - &psDevInfo->psRGXFWSigTDM2DChecksMemDesc, - ui32SignatureChecksBufSize, - &psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_TDM]); - PVR_LOG_GOTO_IF_ERROR(eError, "TDM Signature check setup", fail); - psDevInfo->ui32SigTDM2DChecksSize = ui32SignatureChecksBufSize; - } -#endif - - if (!bEnableSignatureChecks) - { - psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_TDM].sBuffer.ui32Addr = 0x0; - psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_GEOM].sBuffer.ui32Addr = 0x0; - psFwSysInitScratch->asSigBufCtl[RGXFWIF_DM_3D].sBuffer.ui32Addr = 0x0; - } -#endif /* defined(PDUMP) */ - - eError = RGXFWSetupAlignChecks(psDeviceNode, - &psFwSysInitScratch->sAlignChecks); - PVR_LOG_GOTO_IF_ERROR(eError, "Alignment checks setup", fail); - - psFwSysInitScratch->ui32FilterFlags = ui32FilterFlags; - - /* Fill the remaining bits of fw the init data */ - psFwSysInitScratch->sPDSExecBase.uiAddr = RGX_PDSCODEDATA_HEAP_BASE; - psFwSysInitScratch->sUSCExecBase.uiAddr = RGX_USCCODE_HEAP_BASE; - psFwSysInitScratch->sFBCDCStateTableBase.uiAddr = RGX_FBCDC_HEAP_BASE; - psFwSysInitScratch->sFBCDCLargeStateTableBase.uiAddr = RGX_FBCDC_LARGE_HEAP_BASE; - psFwSysInitScratch->sTextureHeapBase.uiAddr = RGX_TEXTURE_STATE_HEAP_BASE; - -#if defined(FIX_HW_BRN_65273_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 65273)) - { - /* Fill the remaining bits of fw the init data */ - psFwSysInitScratch->sPDSExecBase.uiAddr = RGX_PDSCODEDATA_BRN_65273_HEAP_BASE; - psFwSysInitScratch->sUSCExecBase.uiAddr = RGX_USCCODE_BRN_65273_HEAP_BASE; - } -#endif - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - psFwSysInitScratch->ui32JonesDisableMask = ui32JonesDisableMask; - } -#endif -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_VIVT)) - { - eError = _AllocateSLC3Fence(psDevInfo, psFwSysInitScratch); - PVR_LOG_GOTO_IF_ERROR(eError, "SLC3Fence memory allocation", fail); - } -#endif -#if defined(SUPPORT_PDVFS) - /* Core clock rate */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(IMG_UINT32), - "FwPDVFSCoreClkRate", - &psDevInfo->psRGXFWIFCoreClkRateMemDesc, - &psFwSysInitScratch->sCoreClockRate, - (void**) &psDevInfo->pui32RGXFWIFCoreClkRate, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "PDVFS core clock rate memory setup", fail); -#endif - { - /* Timestamps */ - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags = - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | /* XXX ?? */ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC; - - /* - the timer query arrays - */ - PDUMPCOMMENT(psDeviceNode, "Allocate timer query arrays (FW)"); - eError = DevmemFwAllocate(psDevInfo, - sizeof(IMG_UINT64) * RGX_MAX_TIMER_QUERIES, - uiMemAllocFlags | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE, - "FwStartTimesArray", - &psDevInfo->psStartTimeMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map start times array", - __func__)); - goto fail; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psStartTimeMemDesc, - (void **)& psDevInfo->pui64StartTimeById); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map start times array", - __func__)); - goto fail; - } - - eError = DevmemFwAllocate(psDevInfo, - sizeof(IMG_UINT64) * RGX_MAX_TIMER_QUERIES, - uiMemAllocFlags | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE, - "FwEndTimesArray", - & psDevInfo->psEndTimeMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map end times array", - __func__)); - goto fail; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psEndTimeMemDesc, - (void **)& psDevInfo->pui64EndTimeById); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map end times array", - __func__)); - goto fail; - } - - eError = DevmemFwAllocate(psDevInfo, - sizeof(IMG_UINT32) * RGX_MAX_TIMER_QUERIES, - uiMemAllocFlags, - "FwCompletedOpsArray", - & psDevInfo->psCompletedMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to completed ops array", - __func__)); - goto fail; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psCompletedMemDesc, - (void **)& psDevInfo->pui32CompletedById); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map completed ops array", - __func__)); - goto fail; - } - } -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - eError = OSLockCreate(&psDevInfo->hTimerQueryLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate log for timer query", - __func__)); - goto fail; - } -#endif -#if defined(SUPPORT_TBI_INTERFACE) -#if !defined(PDUMP) - /* allocate only if required */ - if (RGXTBIBufferIsInitRequired(psDevInfo)) -#endif /* !defined(PDUMP) */ - { - /* When PDUMP is enabled, ALWAYS allocate on-demand TBI buffer resource - * (irrespective of loggroup(s) enabled), given that logtype/loggroups - * can be set during PDump playback in logconfig, at any point of time - */ - eError = RGXTBIBufferInitOnDemandResources(psDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXTBIBufferInitOnDemandResources", fail); - } - - psFwSysInitScratch->sTBIBuf = psDevInfo->sRGXFWIfTBIBuffer; -#endif /* defined(SUPPORT_TBI_INTERFACE) */ - - /* Allocate shared buffer for GPU utilisation */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_GPU_UTIL_FWCB), - "FwGPUUtilisationBuffer", - &psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc, - &psFwSysInitScratch->sGpuUtilFWCbCtl, - (void**) &psDevInfo->psRGXFWIfGpuUtilFWCb, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "GPU Utilisation Buffer ctl allocation", fail); - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_GPU_RO_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_RUNTIME_CFG), - "FwRuntimeCfg", - &psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - &psFwSysInitScratch->sRuntimeCfg, - (void**) &psDevInfo->psRGXFWIfRuntimeCfg, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware runtime configuration memory allocation", fail); - -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - sizeof(RGXFWIF_REG_CFG), - "FwRegisterConfigStructure", - &psDevInfo->psRGXFWIfRegCfgMemDesc, - &psFwSysInitScratch->sRegCfg, - NULL, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware register user configuration structure allocation", fail); -#endif - - psDevInfo->ui32RGXFWIfHWPerfBufSize = GetHwPerfBufferSize(ui32HWPerfFWBufSizeKB); - /* Second stage initialisation or HWPerf, hHWPerfLock created in first - * stage. See RGXRegisterDevice() call to RGXHWPerfInit(). */ - if (psDevInfo->ui64HWPerfFilter == 0) - { - psDevInfo->ui64HWPerfFilter = ui64HWPerfFilter; - psFwSysInitScratch->ui64HWPerfFilter = ui64HWPerfFilter; - } - else - { - /* The filter has already been modified. This can happen if - * pvr/apphint/EnableFTraceGPU was enabled. */ - psFwSysInitScratch->ui64HWPerfFilter = psDevInfo->ui64HWPerfFilter; - } - -#if !defined(PDUMP) - /* Allocate if HWPerf filter has already been set. This is possible either - * by setting a proper AppHint or enabling GPU ftrace events. */ - if (psDevInfo->ui64HWPerfFilter != 0) -#endif - { - /* When PDUMP is enabled, ALWAYS allocate on-demand HWPerf resources - * (irrespective of HWPerf enabled or not), given that HWPerf can be - * enabled during PDump playback via RTCONF at any point of time. */ - eError = RGXHWPerfInitOnDemandResources(psDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXHWPerfInitOnDemandResources", fail); - } - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp), - ui32HWPerfCountersDataSize, - "FwHWPerfControlStructure", - &psDevInfo->psRGXFWIfHWPerfCountersMemDesc, - &psFwSysInitScratch->sHWPerfCtl, - NULL, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware HW Perf control struct allocation", fail); - - psDevInfo->bPDPEnabled = (ui32ConfigFlags & RGXFWIF_INICFG_DISABLE_PDP_EN) - ? IMG_FALSE : IMG_TRUE; - - psFwSysInitScratch->eFirmwarePerf = eFirmwarePerf; - -#if defined(PDUMP) - /* default: no filter */ - psFwSysInitScratch->sPIDFilter.eMode = RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT; - psFwSysInitScratch->sPIDFilter.asItems[0].uiPID = 0; -#endif - -#if defined(SUPPORT_VALIDATION) - { - IMG_UINT32 dm; - - /* TPU trilinear rounding mask override */ - for (dm = 0; dm < RGXFWIF_TPU_DM_LAST; dm++) - { - psFwSysInitScratch->aui32TPUTrilinearFracMask[dm] = pui32TPUTrilinearFracMask[dm]; - } - } -#endif - -#if defined(SUPPORT_SECURITY_VALIDATION) - { - PVRSRV_MEMALLOCFLAGS_T uiFlags = RGX_FWSHAREDMEM_GPU_ONLY_ALLOCFLAGS; - PVRSRV_SET_PHYS_HEAP_HINT(GPU_SECURE, uiFlags); - - PDUMPCOMMENT(psDeviceNode, "Allocate non-secure buffer for security validation test"); - eError = DevmemFwAllocateExportable(psDeviceNode, - OSGetPageSize(), - OSGetPageSize(), - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS, - "FwExNonSecureBuffer", - &psDevInfo->psRGXFWIfNonSecureBufMemDesc); - PVR_LOG_GOTO_IF_ERROR(eError, "Non-secure buffer allocation", fail); - - eError = RGXSetFirmwareAddress(&psFwSysInitScratch->pbNonSecureBuffer, - psDevInfo->psRGXFWIfNonSecureBufMemDesc, - 0, RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:1", fail); - - PDUMPCOMMENT(psDeviceNode, "Allocate secure buffer for security validation test"); - eError = DevmemFwAllocateExportable(psDeviceNode, - OSGetPageSize(), - OSGetPageSize(), - uiFlags, - "FwExSecureBuffer", - &psDevInfo->psRGXFWIfSecureBufMemDesc); - PVR_LOG_GOTO_IF_ERROR(eError, "Secure buffer allocation", fail); - - eError = RGXSetFirmwareAddress(&psFwSysInitScratch->pbSecureBuffer, - psDevInfo->psRGXFWIfSecureBufMemDesc, - 0, RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:2", fail); - } -#endif /* SUPPORT_SECURITY_VALIDATION */ - -#if defined(RGX_FEATURE_TFBC_LOSSY_37_PERCENT_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_LOSSY_37_PERCENT) || RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_DELTA_CORRELATION)) - { - psFwSysInitScratch->ui32TFBCCompressionControl = - (ui32ConfigFlagsExt & RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK) >> RGXFWIF_INICFG_EXT_TFBC_CONTROL_SHIFT; - } -#endif - - /* Initialize FW started flag */ - psFwSysInitScratch->bFirmwareStarted = IMG_FALSE; - psFwSysInitScratch->ui32MarkerVal = 1; - - if (!psDeviceNode->bAutoVzFwIsUp) - { - IMG_UINT32 ui32OSIndex; - - RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg; - - /* Required info by FW to calculate the ActivePM idle timer latency */ - psFwSysInitScratch->ui32InitialCoreClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed; - psFwSysInitScratch->ui32InitialActivePMLatencyms = psRGXData->psRGXTimingInfo->ui32ActivePMLatencyms; - - /* Initialise variable runtime configuration to the system defaults */ - psRuntimeCfg->ui32CoreClockSpeed = psFwSysInitScratch->ui32InitialCoreClockSpeed; - psRuntimeCfg->ui32ActivePMLatencyms = psFwSysInitScratch->ui32InitialActivePMLatencyms; - psRuntimeCfg->bActivePMLatencyPersistant = IMG_TRUE; - psRuntimeCfg->ui32WdgPeriodUs = RGXFW_SAFETY_WATCHDOG_PERIOD_IN_US; - psRuntimeCfg->ui32HCSDeadlineMS = RGX_HCS_DEFAULT_DEADLINE_MS; - - if (PVRSRV_VZ_MODE_IS(NATIVE)) - { - psRuntimeCfg->aui32OSidPriority[RGXFW_HOST_OS] = 0; - } - else - { - for (ui32OSIndex = 0; ui32OSIndex < RGX_NUM_OS_SUPPORTED; ui32OSIndex++) - { - const IMG_INT32 ai32DefaultOsPriority[RGXFW_MAX_NUM_OS] = - {RGX_OSID_0_DEFAULT_PRIORITY, RGX_OSID_1_DEFAULT_PRIORITY, RGX_OSID_2_DEFAULT_PRIORITY, RGX_OSID_3_DEFAULT_PRIORITY, - RGX_OSID_4_DEFAULT_PRIORITY, RGX_OSID_5_DEFAULT_PRIORITY, RGX_OSID_6_DEFAULT_PRIORITY, RGX_OSID_7_DEFAULT_PRIORITY}; - - /* Set up initial priorities between different OSes */ - psRuntimeCfg->aui32OSidPriority[ui32OSIndex] = (IMG_UINT32)ai32DefaultOsPriority[ui32OSIndex]; - } - } - -#if defined(PVR_ENABLE_PHR) && defined(PDUMP) - psRuntimeCfg->ui32PHRMode = RGXFWIF_PHR_MODE_RD_RESET; -#else - psRuntimeCfg->ui32PHRMode = 0; -#endif - - /* Initialize the DefaultDustsNumInit Field to Max Dusts */ - psRuntimeCfg->ui32DefaultDustsNumInit = psDevInfo->sDevFeatureCfg.ui32MAXDustCount; - - /* flush write buffers for psDevInfo->psRGXFWIfRuntimeCfg */ - OSWriteMemoryBarrier(psDevInfo->psRGXFWIfRuntimeCfg); - - /* Setup FW coremem data */ - if (psDevInfo->psRGXFWIfCorememDataStoreMemDesc) - { - psFwSysInitScratch->sCorememDataStore.pbyFWAddr = psDevInfo->sFWCorememDataStoreFWAddr; - -#if defined(RGX_FEATURE_META_DMA_CHANNEL_COUNT_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, META_DMA)) - { - RGXSetMetaDMAAddress(&psFwSysInitScratch->sCorememDataStore, - psDevInfo->psRGXFWIfCorememDataStoreMemDesc, - &psFwSysInitScratch->sCorememDataStore.pbyFWAddr, - 0); - } -#endif - } - - psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags = ui32ConfigFlags & RGXFWIF_INICFG_ALL; - psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlagsExt = ui32ConfigFlagsExt & RGXFWIF_INICFG_EXT_ALL; - - /* Initialise GPU utilisation buffer */ - psDevInfo->psRGXFWIfGpuUtilFWCb->ui64LastWord = - RGXFWIF_GPU_UTIL_MAKE_WORD(OSClockns64(),RGXFWIF_GPU_UTIL_STATE_IDLE); - - /* init HWPERF data */ - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfRIdx = 0; - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfWIdx = 0; - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfWrapCount = 0; - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfSize = psDevInfo->ui32RGXFWIfHWPerfBufSize; - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfUt = 0; - psDevInfo->psRGXFWIfFwSysData->ui32HWPerfDropCount = 0; - psDevInfo->psRGXFWIfFwSysData->ui32FirstDropOrdinal = 0; - psDevInfo->psRGXFWIfFwSysData->ui32LastDropOrdinal = 0; - - /*Send through the BVNC Feature Flags*/ - eError = RGXServerFeatureFlagsToHWPerfFlags(psDevInfo, &psFwSysInitScratch->sBvncKmFeatureFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXServerFeatureFlagsToHWPerfFlags", fail); - - /* populate the real FwOsInit structure with the values stored in the scratch copy */ - OSCachedMemCopyWMB(psDevInfo->psRGXFWIfSysInit, psFwSysInitScratch, sizeof(RGXFWIF_SYSINIT)); - } - - OSFreeMem(psFwSysInitScratch); - - return PVRSRV_OK; - -fail: - if (psFwSysInitScratch) - { - OSFreeMem(psFwSysInitScratch); - } - - RGXFreeFwSysData(psDevInfo); - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/*! -******************************************************************************* - @Function RGXSetupFwOsData - - @Description Sets up all os-specific firmware related data - - @Input psDevInfo - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXSetupFwOsData(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32KCCBSizeLog2, - IMG_UINT32 ui32HWRDebugDumpLimit, - IMG_UINT32 ui32FwOsCfgFlags) -{ - PVRSRV_ERROR eError; - RGXFWIF_OSINIT sFwOsInitScratch; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSCachedMemSet(&sFwOsInitScratch, 0, sizeof(RGXFWIF_OSINIT)); - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = RGXSetupFwGuardPage(psDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "Setting up firmware heap guard pages", fail); - } - - /* Memory tracking the connection state should be non-volatile and - * is not cleared on allocation to prevent loss of pre-reset information */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_CONFIG_ALLOCFLAGS & - ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC, - sizeof(RGXFWIF_CONNECTION_CTL), - "FwConnectionCtl", - &psDevInfo->psRGXFWIfConnectionCtlMemDesc, - NULL, - (void**) &psDevInfo->psRGXFWIfConnectionCtl, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware Connection Control structure allocation", fail); - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_CONFIG_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED), - sizeof(RGXFWIF_OSINIT), - "FwOsInitStructure", - &psDevInfo->psRGXFWIfOsInitMemDesc, - NULL, - (void**) &psDevInfo->psRGXFWIfOsInit, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware Os Init structure allocation", fail); - - /* init HWR frame info */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS, - sizeof(RGXFWIF_HWRINFOBUF), - "FwHWRInfoBuffer", - &psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc, - &sFwOsInitScratch.sRGXFWIfHWRInfoBufCtl, - (void**) &psDevInfo->psRGXFWIfHWRInfoBufCtl, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "HWR Info Buffer allocation", fail); - - /* Might be uncached. Be conservative and use a DeviceMemSet */ - OSDeviceMemSet(psDevInfo->psRGXFWIfHWRInfoBufCtl, 0, sizeof(RGXFWIF_HWRINFOBUF)); - - /* Allocate a sync for power management */ - eError = SyncPrimContextCreate(psDevInfo->psDeviceNode, - &psDevInfo->hSyncPrimContext); - PVR_LOG_GOTO_IF_ERROR(eError, "Sync primitive context allocation", fail); - - eError = SyncPrimAlloc(psDevInfo->hSyncPrimContext, &psDevInfo->psPowSyncPrim, "fw power ack"); - PVR_LOG_GOTO_IF_ERROR(eError, "Sync primitive allocation", fail); - - /* Set up kernel CCB */ - eError = RGXSetupCCB(psDevInfo, - &psDevInfo->psKernelCCBCtl, - &psDevInfo->psKernelCCBCtlMemDesc, - &psDevInfo->psKernelCCB, - &psDevInfo->psKernelCCBMemDesc, - &sFwOsInitScratch.psKernelCCBCtl, - &sFwOsInitScratch.psKernelCCB, - ui32KCCBSizeLog2, - sizeof(RGXFWIF_KCCB_CMD), - (RGX_FWSHAREDMEM_GPU_RO_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)), - "FwKernelCCB"); - PVR_LOG_GOTO_IF_ERROR(eError, "Kernel CCB allocation", fail); - - /* KCCB additionally uses a return slot array for FW to be able to send back - * return codes for each required command - */ - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS, - (1U << ui32KCCBSizeLog2) * sizeof(IMG_UINT32), - "FwKernelCCBRtnSlots", - &psDevInfo->psKernelCCBRtnSlotsMemDesc, - &sFwOsInitScratch.psKernelCCBRtnSlots, - (void**) &psDevInfo->pui32KernelCCBRtnSlots, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "Kernel CCB return slot array allocation", fail); - - /* Set up firmware CCB */ - eError = RGXSetupCCB(psDevInfo, - &psDevInfo->psFirmwareCCBCtl, - &psDevInfo->psFirmwareCCBCtlMemDesc, - &psDevInfo->psFirmwareCCB, - &psDevInfo->psFirmwareCCBMemDesc, - &sFwOsInitScratch.psFirmwareCCBCtl, - &sFwOsInitScratch.psFirmwareCCB, - RGXFWIF_FWCCB_NUMCMDS_LOG2, - sizeof(RGXFWIF_FWCCB_CMD), - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS, - "FwCCB"); - PVR_LOG_GOTO_IF_ERROR(eError, "Firmware CCB allocation", fail); - - eError = RGXSetupFwAllocation(psDevInfo, - RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS, - sizeof(RGXFWIF_OSDATA), - "FwOsData", - &psDevInfo->psRGXFWIfFwOsDataMemDesc, - &sFwOsInitScratch.sFwOsData, - (void**) &psDevInfo->psRGXFWIfFwOsData, - RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", fail); - - psDevInfo->psRGXFWIfFwOsData->ui32FwOsConfigFlags = ui32FwOsCfgFlags & RGXFWIF_INICFG_OS_ALL; - - eError = SyncPrimGetFirmwareAddr(psDevInfo->psPowSyncPrim, &psDevInfo->psRGXFWIfFwOsData->sPowerSync.ui32Addr); - PVR_LOG_GOTO_IF_ERROR(eError, "Get Sync Prim FW address", fail); - - /* flush write buffers for psRGXFWIfFwOsData */ - OSWriteMemoryBarrier(psDevInfo->psRGXFWIfFwOsData); - - sFwOsInitScratch.ui32HWRDebugDumpLimit = ui32HWRDebugDumpLimit; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Set up Workload Estimation firmware CCB */ - eError = RGXSetupCCB(psDevInfo, - &psDevInfo->psWorkEstFirmwareCCBCtl, - &psDevInfo->psWorkEstFirmwareCCBCtlMemDesc, - &psDevInfo->psWorkEstFirmwareCCB, - &psDevInfo->psWorkEstFirmwareCCBMemDesc, - &sFwOsInitScratch.psWorkEstFirmwareCCBCtl, - &sFwOsInitScratch.psWorkEstFirmwareCCB, - RGXFWIF_WORKEST_FWCCB_NUMCMDS_LOG2, - sizeof(RGXFWIF_WORKEST_FWCCB_CMD), - RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS, - "FwWEstCCB"); - PVR_LOG_GOTO_IF_ERROR(eError, "Workload Estimation Firmware CCB allocation", fail); -#endif /* defined(SUPPORT_WORKLOAD_ESTIMATION) */ - - /* Initialise the compatibility check data */ - RGXFWIF_COMPCHECKS_BVNC_INIT(sFwOsInitScratch.sRGXCompChecks.sFWBVNC); - RGXFWIF_COMPCHECKS_BVNC_INIT(sFwOsInitScratch.sRGXCompChecks.sHWBVNC); - - /* populate the real FwOsInit structure with the values stored in the scratch copy */ - OSCachedMemCopyWMB(psDevInfo->psRGXFWIfOsInit, &sFwOsInitScratch, sizeof(RGXFWIF_OSINIT)); - - return PVRSRV_OK; - -fail: - RGXFreeFwOsData(psDevInfo); - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/*! -******************************************************************************* - @Function RGXSetupFirmware - - @Description Sets up all firmware related data - - @Input psDevInfo - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXSetupFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bEnableSignatureChecks, - IMG_UINT32 ui32SignatureChecksBufSize, - IMG_UINT32 ui32HWPerfFWBufSizeKB, - IMG_UINT64 ui64HWPerfFilter, - IMG_UINT32 ui32ConfigFlags, - IMG_UINT32 ui32ConfigFlagsExt, - IMG_UINT32 ui32FwOsCfgFlags, - IMG_UINT32 ui32LogType, - IMG_UINT32 ui32FilterFlags, - IMG_UINT32 ui32JonesDisableMask, - IMG_UINT32 ui32HWRDebugDumpLimit, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_UINT32 *pui32TPUTrilinearFracMask, - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf, - FW_PERF_CONF eFirmwarePerf, - IMG_UINT32 ui32KCCBSizeLog2) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - eError = RGXSetupFwOsData(psDeviceNode, - ui32KCCBSizeLog2, - ui32HWRDebugDumpLimit, - ui32FwOsCfgFlags); - PVR_LOG_GOTO_IF_ERROR(eError, "Setting up firmware os data", fail); - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - /* Guest drivers do not configure system-wide firmware data */ - psDevInfo->psRGXFWIfSysInit = NULL; - } - else - { - /* Native and Host drivers must initialise the firmware's system data */ - eError = RGXSetupFwSysData(psDeviceNode, - bEnableSignatureChecks, - ui32SignatureChecksBufSize, - ui32HWPerfFWBufSizeKB, - ui64HWPerfFilter, - ui32ConfigFlags, - ui32ConfigFlagsExt, - ui32LogType, - ui32FilterFlags, - ui32JonesDisableMask, - ui32HWPerfCountersDataSize, - pui32TPUTrilinearFracMask, - eRGXRDPowerIslandConf, - eFirmwarePerf); - PVR_LOG_GOTO_IF_ERROR(eError, "Setting up firmware system data", fail); - } - - psDevInfo->bFirmwareInitialised = IMG_TRUE; - -#if defined(PDUMP) - RGXPDumpLoadFWInitData(psDevInfo, - ui32HWPerfCountersDataSize, - bEnableSignatureChecks); -#endif /* PDUMP */ - -fail: - return eError; -} - -/*! -******************************************************************************* - @Function RGXFreeFwSysData - - @Description Frees all system-wide firmware related data - - @Input psDevInfo -******************************************************************************/ -static void RGXFreeFwSysData(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - psDevInfo->bFirmwareInitialised = IMG_FALSE; - - if (psDevInfo->psRGXFWAlignChecksMemDesc) - { - RGXFWFreeAlignChecks(psDevInfo); - } - -#if defined(PDUMP) -#if defined(RGX_FEATURE_TDM_PDS_CHECKSUM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TDM_PDS_CHECKSUM) && - psDevInfo->psRGXFWSigTDM2DChecksMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWSigTDM2DChecksMemDesc); - psDevInfo->psRGXFWSigTDM2DChecksMemDesc = NULL; - } -#endif - - if (psDevInfo->psRGXFWSigTAChecksMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWSigTAChecksMemDesc); - psDevInfo->psRGXFWSigTAChecksMemDesc = NULL; - } - - if (psDevInfo->psRGXFWSig3DChecksMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWSig3DChecksMemDesc); - psDevInfo->psRGXFWSig3DChecksMemDesc = NULL; - } -#endif - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) - if (psDevInfo->psCounterBufferMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psCounterBufferMemDesc); - psDevInfo->psCounterBufferMemDesc = NULL; - } -#endif - -#if defined(SUPPORT_FIRMWARE_GCOV) - if (psDevInfo->psFirmwareGcovBufferMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psFirmwareGcovBufferMemDesc); - psDevInfo->psFirmwareGcovBufferMemDesc = NULL; - } -#endif - - RGXSetupFaultReadRegisterRollback(psDevInfo); - - if (psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc) - { - if (psDevInfo->psRGXFWIfGpuUtilFWCb != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc); - psDevInfo->psRGXFWIfGpuUtilFWCb = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc); - psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfRuntimeCfgMemDesc) - { - if (psDevInfo->psRGXFWIfRuntimeCfg != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfRuntimeCfgMemDesc); - psDevInfo->psRGXFWIfRuntimeCfg = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfRuntimeCfgMemDesc); - psDevInfo->psRGXFWIfRuntimeCfgMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfCorememDataStoreMemDesc) - { - psDevInfo->psRGXFWIfCorememDataStoreMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfTraceBufCtlMemDesc) - { - if (psDevInfo->psRGXFWIfTraceBufCtl != NULL) - { - /* first deinit/free the tracebuffer allocation */ - RGXTraceBufferDeinit(psDevInfo); - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufCtlMemDesc); - psDevInfo->psRGXFWIfTraceBufCtl = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfTraceBufCtlMemDesc); - psDevInfo->psRGXFWIfTraceBufCtlMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfFwSysDataMemDesc) - { - if (psDevInfo->psRGXFWIfFwSysData != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfFwSysDataMemDesc); - psDevInfo->psRGXFWIfFwSysData = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfFwSysDataMemDesc); - psDevInfo->psRGXFWIfFwSysDataMemDesc = NULL; - } - -#if defined(SUPPORT_TBI_INTERFACE) - if (psDevInfo->psRGXFWIfTBIBufferMemDesc) - { - RGXTBIBufferDeinit(psDevInfo); - } -#endif - -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - if (psDevInfo->psRGXFWIfRegCfgMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfRegCfgMemDesc); - psDevInfo->psRGXFWIfRegCfgMemDesc = NULL; - } -#endif - if (psDevInfo->psRGXFWIfHWPerfCountersMemDesc) - { - RGXUnsetFirmwareAddress(psDevInfo->psRGXFWIfHWPerfCountersMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfHWPerfCountersMemDesc); - psDevInfo->psRGXFWIfHWPerfCountersMemDesc = NULL; - } - -#if defined(SUPPORT_SECURITY_VALIDATION) - if (psDevInfo->psRGXFWIfNonSecureBufMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfNonSecureBufMemDesc); - psDevInfo->psRGXFWIfNonSecureBufMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfSecureBufMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfSecureBufMemDesc); - psDevInfo->psRGXFWIfSecureBufMemDesc = NULL; - } -#endif - -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_VIVT)) - { - _FreeSLC3Fence(psDevInfo); - } -#endif -#if defined(SUPPORT_PDVFS) - if (psDevInfo->psRGXFWIFCoreClkRateMemDesc) - { - if (psDevInfo->pui32RGXFWIFCoreClkRate != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIFCoreClkRateMemDesc); - psDevInfo->pui32RGXFWIFCoreClkRate = NULL; - } - - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIFCoreClkRateMemDesc); - psDevInfo->psRGXFWIFCoreClkRateMemDesc = NULL; - } -#endif -} - -/*! -******************************************************************************* - @Function RGXFreeFwOsData - - @Description Frees all os-specific firmware related data - - @Input psDevInfo -******************************************************************************/ -static void RGXFreeFwOsData(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFreeCCBReturnSlots(psDevInfo, - &psDevInfo->pui32KernelCCBRtnSlots, - &psDevInfo->psKernelCCBRtnSlotsMemDesc); - RGXFreeCCB(psDevInfo, - &psDevInfo->psKernelCCBCtl, - &psDevInfo->psKernelCCBCtlMemDesc, - &psDevInfo->psKernelCCB, - &psDevInfo->psKernelCCBMemDesc); - - RGXFreeCCB(psDevInfo, - &psDevInfo->psFirmwareCCBCtl, - &psDevInfo->psFirmwareCCBCtlMemDesc, - &psDevInfo->psFirmwareCCB, - &psDevInfo->psFirmwareCCBMemDesc); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFreeCCB(psDevInfo, - &psDevInfo->psWorkEstFirmwareCCBCtl, - &psDevInfo->psWorkEstFirmwareCCBCtlMemDesc, - &psDevInfo->psWorkEstFirmwareCCB, - &psDevInfo->psWorkEstFirmwareCCBMemDesc); -#endif - - if (psDevInfo->psPowSyncPrim != NULL) - { - SyncPrimFree(psDevInfo->psPowSyncPrim); - psDevInfo->psPowSyncPrim = NULL; - } - - if (psDevInfo->hSyncPrimContext != (IMG_HANDLE) NULL) - { - SyncPrimContextDestroy(psDevInfo->hSyncPrimContext); - psDevInfo->hSyncPrimContext = (IMG_HANDLE) NULL; - } - - if (psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc) - { - if (psDevInfo->psRGXFWIfHWRInfoBufCtl != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc); - psDevInfo->psRGXFWIfHWRInfoBufCtl = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc); - psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfFwOsDataMemDesc) - { - if (psDevInfo->psRGXFWIfFwOsData != NULL) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfFwOsDataMemDesc); - psDevInfo->psRGXFWIfFwOsData = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfFwOsDataMemDesc); - psDevInfo->psRGXFWIfFwOsDataMemDesc = NULL; - } - - if (psDevInfo->psCompletedMemDesc) - { - if (psDevInfo->pui32CompletedById) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psCompletedMemDesc); - psDevInfo->pui32CompletedById = NULL; - } - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psCompletedMemDesc); - psDevInfo->psCompletedMemDesc = NULL; - } - if (psDevInfo->psEndTimeMemDesc) - { - if (psDevInfo->pui64EndTimeById) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psEndTimeMemDesc); - psDevInfo->pui64EndTimeById = NULL; - } - - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psEndTimeMemDesc); - psDevInfo->psEndTimeMemDesc = NULL; - } - if (psDevInfo->psStartTimeMemDesc) - { - if (psDevInfo->pui64StartTimeById) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psStartTimeMemDesc); - psDevInfo->pui64StartTimeById = NULL; - } - - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psStartTimeMemDesc); - psDevInfo->psStartTimeMemDesc = NULL; - } -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - if (psDevInfo->hTimerQueryLock) - { - OSLockDestroy(psDevInfo->hTimerQueryLock); - psDevInfo->hTimerQueryLock = NULL; - } -#endif - - if (psDevInfo->psRGXFWHeapGuardPageReserveMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWHeapGuardPageReserveMemDesc); - } -} - -/*! -******************************************************************************* - @Function RGXFreeFirmware - - @Description Frees all the firmware-related allocations - - @Input psDevInfo -******************************************************************************/ -void RGXFreeFirmware(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFreeFwOsData(psDevInfo); - - if (psDevInfo->psRGXFWIfConnectionCtl) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfConnectionCtlMemDesc); - psDevInfo->psRGXFWIfConnectionCtl = NULL; - } - - if (psDevInfo->psRGXFWIfConnectionCtlMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfConnectionCtlMemDesc); - psDevInfo->psRGXFWIfConnectionCtlMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfOsInit) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfOsInitMemDesc); - psDevInfo->psRGXFWIfOsInit = NULL; - } - - if (psDevInfo->psRGXFWIfOsInitMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfOsInitMemDesc); - psDevInfo->psRGXFWIfOsInitMemDesc = NULL; - } - - RGXFreeFwSysData(psDevInfo); - if (psDevInfo->psRGXFWIfSysInit) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfSysInitMemDesc); - psDevInfo->psRGXFWIfSysInit = NULL; - } - - if (psDevInfo->psRGXFWIfSysInitMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfSysInitMemDesc); - psDevInfo->psRGXFWIfSysInitMemDesc = NULL; - } -} - -/****************************************************************************** - FUNCTION : RGXAcquireKernelCCBSlot - - PURPOSE : Attempts to obtain a slot in the Kernel CCB - - PARAMETERS : psCCB - the CCB - : Address of space if available, NULL otherwise - - RETURNS : PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXAcquireKernelCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - const RGXFWIF_CCB_CTL *psKCCBCtl, - IMG_UINT32 *pui32Offset) -{ - IMG_UINT32 ui32OldWriteOffset, ui32NextWriteOffset; -#if defined(PDUMP) - const DEVMEM_MEMDESC *psKCCBCtrlMemDesc = psDevInfo->psKernelCCBCtlMemDesc; -#endif - - ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset; - ui32NextWriteOffset = (ui32OldWriteOffset + 1) & psKCCBCtl->ui32WrapMask; - -#if defined(PDUMP) - /* Wait for sufficient CCB space to become available */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, 0, - "Wait for kCCB woff=%u", ui32NextWriteOffset); - DevmemPDumpCBP(psKCCBCtrlMemDesc, - offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset), - ui32NextWriteOffset, - 1, - (psKCCBCtl->ui32WrapMask + 1)); -#endif - - if (ui32NextWriteOffset == psKCCBCtl->ui32ReadOffset) - { - return PVRSRV_ERROR_KERNEL_CCB_FULL; - } - *pui32Offset = ui32NextWriteOffset; - return PVRSRV_OK; -} - -/****************************************************************************** - FUNCTION : RGXPollKernelCCBSlot - - PURPOSE : Poll for space in Kernel CCB - - PARAMETERS : psCCB - the CCB - : Address of space if available, NULL otherwise - - RETURNS : PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXPollKernelCCBSlot(const DEVMEM_MEMDESC *psKCCBCtrlMemDesc, - const RGXFWIF_CCB_CTL *psKCCBCtl) -{ - IMG_UINT32 ui32OldWriteOffset, ui32NextWriteOffset; - - ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset; - ui32NextWriteOffset = (ui32OldWriteOffset + 1) & psKCCBCtl->ui32WrapMask; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - - if (ui32NextWriteOffset != psKCCBCtl->ui32ReadOffset) - { - return PVRSRV_OK; - } - - /* - * The following check doesn't impact performance, since the - * CPU has to wait for the GPU anyway (full kernel CCB). - */ - if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - return PVRSRV_ERROR_KERNEL_CCB_FULL; - } - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - return PVRSRV_ERROR_KERNEL_CCB_FULL; -} - -/****************************************************************************** - FUNCTION : RGXGetCmdMemCopySize - - PURPOSE : Calculates actual size of KCCB command getting used - - PARAMETERS : eCmdType Type of KCCB command - - RETURNS : Returns actual size of KCCB command on success else zero -******************************************************************************/ -static IMG_UINT32 RGXGetCmdMemCopySize(RGXFWIF_KCCB_CMD_TYPE eCmdType) -{ - /* First get offset of uCmdData inside the struct RGXFWIF_KCCB_CMD - * This will account alignment requirement of uCmdData union - * - * Then add command-data size depending on command type to calculate actual - * command size required to do mem copy - * - * NOTE: Make sure that uCmdData is the last member of RGXFWIF_KCCB_CMD struct. - */ - switch (eCmdType) - { - case RGXFWIF_KCCB_CMD_KICK: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_KCCB_CMD_KICK_DATA); - } - case RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA); - } - case RGXFWIF_KCCB_CMD_MMUCACHE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_MMUCACHEDATA); - } -#if defined(SUPPORT_USC_BREAKPOINT) - case RGXFWIF_KCCB_CMD_BP: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_BPDATA); - } -#endif - case RGXFWIF_KCCB_CMD_SLCFLUSHINVAL: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_SLCFLUSHINVALDATA); - } - case RGXFWIF_KCCB_CMD_CLEANUP: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_CLEANUP_REQUEST); - } - case RGXFWIF_KCCB_CMD_POW: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_POWER_REQUEST); - } - case RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE: - case RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_ZSBUFFER_BACKING_DATA); - } - case RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_FREELIST_GS_DATA); - } - case RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_FREELISTS_RECONSTRUCTION_DATA); - } - case RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_WRITE_OFFSET_UPDATE_DATA); - } - case RGXFWIF_KCCB_CMD_FORCE_UPDATE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA); - } -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - case RGXFWIF_KCCB_CMD_REGCONFIG: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_REGCONFIG_DATA); - } -#endif - case RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS); - } -#if defined(SUPPORT_PDVFS) - case RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MAX_FREQ: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_PDVFS_MAX_FREQ_DATA); - } -#endif - case RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_OS_STATE_CHANGE_DATA); - } - case RGXFWIF_KCCB_CMD_COUNTER_DUMP: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_COUNTER_DUMP_DATA); - } - case RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_HWPERF_CTRL); - } - case RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS); - } - case RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_HWPERF_CONFIG_DA_BLKS); - } - case RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_HWPERF_CTRL_BLKS); - } - case RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_CORECLKSPEEDCHANGE_DATA); - } - case RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE: - case RGXFWIF_KCCB_CMD_WDG_CFG: - case RGXFWIF_KCCB_CMD_PHR_CFG: - case RGXFWIF_KCCB_CMD_HEALTH_CHECK: - case RGXFWIF_KCCB_CMD_LOGTYPE_UPDATE: - case RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL: - { - /* No command specific data */ - return offsetof(RGXFWIF_KCCB_CMD, uCmdData); - } -#if defined(SUPPORT_VALIDATION) - case RGXFWIF_KCCB_CMD_RGXREG: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_RGXREG_DATA); - } - case RGXFWIF_KCCB_CMD_GPUMAP: - { - return offsetof(RGXFWIF_KCCB_CMD, uCmdData) + sizeof(RGXFWIF_GPUMAP_DATA); - } -#endif - default: - { - /* Invalid (OR) Unused (OR) Newly added command type */ - return 0; /* Error */ - } - } -} - -PVRSRV_ERROR RGXWaitForKCCBSlotUpdate(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32SlotNum, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - eError = PVRSRVWaitForValueKM( - (IMG_UINT32 __iomem *)&psDevInfo->pui32KernelCCBRtnSlots[ui32SlotNum], - RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED, - RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVWaitForValueKM"); - -#if defined(PDUMP) - /* PDumping conditions same as RGXSendCommandRaw for the actual command and poll command to go in harmony */ - if (PDumpCheckFlagsWrite(psDevInfo->psDeviceNode, ui32PDumpFlags)) - { - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Poll on KCCB slot %u for value %u (mask: 0x%x)", ui32SlotNum, - RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED, RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED); - - eError = DevmemPDumpDevmemPol32(psDevInfo->psKernelCCBRtnSlotsMemDesc, - ui32SlotNum * sizeof(IMG_UINT32), - RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED, - RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "DevmemPDumpDevmemPol32"); - } -#else - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); -#endif - - return eError; -} - -static PVRSRV_ERROR RGXSendCommandRaw(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 uiPDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl; - IMG_UINT8 *pui8KCCB = psDevInfo->psKernelCCB; - IMG_UINT32 ui32NewWriteOffset; - IMG_UINT32 ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset; - IMG_UINT32 ui32CmdMemCopySize; - -#if !defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(uiPDumpFlags); -#else - IMG_BOOL bContCaptureOn = PDumpCheckFlagsWrite(psDeviceNode, PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER); /* client connected or in pdump init phase */ - IMG_BOOL bPDumpEnabled = PDumpCheckFlagsWrite(psDeviceNode, uiPDumpFlags); /* Are we in capture range or continuous and not in a power transition */ - - if (bContCaptureOn) - { - /* in capture range */ - if (bPDumpEnabled) - { - if (!psDevInfo->bDumpedKCCBCtlAlready) - { - /* entering capture range */ - psDevInfo->bDumpedKCCBCtlAlready = IMG_TRUE; - - /* Wait for the live FW to catch up */ - PVR_DPF((PVR_DBG_MESSAGE, "%s: waiting on fw to catch-up, roff: %d, woff: %d", - __func__, - psKCCBCtl->ui32ReadOffset, ui32OldWriteOffset)); - PVRSRVPollForValueKM(psDeviceNode, - (IMG_UINT32 __iomem *)&psKCCBCtl->ui32ReadOffset, - ui32OldWriteOffset, 0xFFFFFFFF, - POLL_FLAG_LOG_ERROR | POLL_FLAG_DEBUG_DUMP); - - /* Dump Init state of Kernel CCB control (read and write offset) */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, uiPDumpFlags, - "Initial state of kernel CCB Control, roff: %d, woff: %d", - psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset); - - DevmemPDumpLoadMem(psDevInfo->psKernelCCBCtlMemDesc, - 0, - sizeof(RGXFWIF_CCB_CTL), - uiPDumpFlags); - } - } - } -#endif - -#if defined(SUPPORT_AUTOVZ) - if (!((KM_FW_CONNECTION_IS(READY, psDevInfo) && KM_OS_CONNECTION_IS(READY, psDevInfo)) || - (KM_FW_CONNECTION_IS(ACTIVE, psDevInfo) && KM_OS_CONNECTION_IS(ACTIVE, psDevInfo))) && - !PVRSRV_VZ_MODE_IS(NATIVE)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: The firmware-driver connection is invalid:" - "driver state = %u / firmware state = %u;" - "expected READY (%u/%u) or ACTIVE (%u/%u);", - __func__, KM_GET_OS_CONNECTION(psDevInfo), KM_GET_FW_CONNECTION(psDevInfo), - RGXFW_CONNECTION_OS_READY, RGXFW_CONNECTION_FW_READY, - RGXFW_CONNECTION_OS_ACTIVE, RGXFW_CONNECTION_FW_ACTIVE)); - eError = PVRSRV_ERROR_PVZ_OSID_IS_OFFLINE; - goto _RGXSendCommandRaw_Exit; - } -#endif - - PVR_ASSERT(sizeof(RGXFWIF_KCCB_CMD) == psKCCBCtl->ui32CmdSize); - if (!OSLockIsLocked(psDeviceNode->hPowerLock)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s called without power lock held!", - __func__)); - PVR_ASSERT(OSLockIsLocked(psDeviceNode->hPowerLock)); - } - - /* Acquire a slot in the CCB */ - eError = RGXAcquireKernelCCBSlot(psDevInfo, psKCCBCtl, &ui32NewWriteOffset); - if (eError != PVRSRV_OK) - { - goto _RGXSendCommandRaw_Exit; - } - - /* Calculate actual size of command to optimize device mem copy */ - ui32CmdMemCopySize = RGXGetCmdMemCopySize(psKCCBCmd->eCmdType); - PVR_LOG_RETURN_IF_FALSE(ui32CmdMemCopySize !=0, "RGXGetCmdMemCopySize failed", PVRSRV_ERROR_INVALID_CCB_COMMAND); - - /* Copy the command into the CCB */ - OSCachedMemCopyWMB(&pui8KCCB[ui32OldWriteOffset * psKCCBCtl->ui32CmdSize], - psKCCBCmd, ui32CmdMemCopySize); - - /* If non-NULL pui32CmdKCCBSlot passed-in, return the kCCB slot in which the command was enqueued */ - if (pui32CmdKCCBSlot) - { - *pui32CmdKCCBSlot = ui32OldWriteOffset; - - /* Each such command enqueue needs to reset the slot value first. This is so that a caller - * doesn't get to see stale/false value in allotted slot */ - OSWriteDeviceMem32WithWMB(&psDevInfo->pui32KernelCCBRtnSlots[ui32OldWriteOffset], - RGXFWIF_KCCB_RTN_SLOT_NO_RESPONSE); -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, uiPDumpFlags, - "Reset kCCB slot number %u", ui32OldWriteOffset); - DevmemPDumpLoadMem(psDevInfo->psKernelCCBRtnSlotsMemDesc, - ui32OldWriteOffset * sizeof(IMG_UINT32), - sizeof(IMG_UINT32), - uiPDumpFlags); -#endif - PVR_DPF((PVR_DBG_MESSAGE, "%s: Device (%p) KCCB slot %u reset with value %u for command type %x", - __func__, psDevInfo, ui32OldWriteOffset, RGXFWIF_KCCB_RTN_SLOT_NO_RESPONSE, psKCCBCmd->eCmdType)); - } - - /* Move past the current command */ - psKCCBCtl->ui32WriteOffset = ui32NewWriteOffset; - - OSWriteMemoryBarrier(&psKCCBCtl->ui32WriteOffset); - -#if defined(PDUMP) - if (bContCaptureOn) - { - /* in capture range */ - if (bPDumpEnabled) - { - /* Dump new Kernel CCB content */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, - uiPDumpFlags, "Dump kCCB cmd woff = %d", - ui32OldWriteOffset); - DevmemPDumpLoadMem(psDevInfo->psKernelCCBMemDesc, - ui32OldWriteOffset * psKCCBCtl->ui32CmdSize, - ui32CmdMemCopySize, - uiPDumpFlags); - - /* Dump new kernel CCB write offset */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, - uiPDumpFlags, "Dump kCCBCtl woff: %d", - ui32NewWriteOffset); - DevmemPDumpLoadMem(psDevInfo->psKernelCCBCtlMemDesc, - offsetof(RGXFWIF_CCB_CTL, ui32WriteOffset), - sizeof(IMG_UINT32), - uiPDumpFlags); - - /* mimic the read-back of the write from above */ - DevmemPDumpDevmemPol32(psDevInfo->psKernelCCBCtlMemDesc, - offsetof(RGXFWIF_CCB_CTL, ui32WriteOffset), - ui32NewWriteOffset, - 0xFFFFFFFF, - PDUMP_POLL_OPERATOR_EQUAL, - uiPDumpFlags); - } - /* out of capture range */ - else - { - eError = RGXPdumpDrainKCCB(psDevInfo, ui32OldWriteOffset); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXPdumpDrainKCCB", _RGXSendCommandRaw_Exit); - } - } -#endif - - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, uiPDumpFlags, "MTS kick for kernel CCB"); - /* - * Kick the MTS to schedule the firmware. - */ - __MTSScheduleWrite(psDevInfo, RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK); - - PDUMPREG32(psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_MTS_SCHEDULE, - RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK, uiPDumpFlags); - -#if defined(SUPPORT_AUTOVZ) - RGXUpdateAutoVzWdgToken(psDevInfo); -#endif - -#if defined(NO_HARDWARE) - /* keep the roff updated because fw isn't there to update it */ - psKCCBCtl->ui32ReadOffset = psKCCBCtl->ui32WriteOffset; -#endif - -_RGXSendCommandRaw_Exit: - return eError; -} - -/****************************************************************************** - FUNCTION : _AllocDeferredCommand - - PURPOSE : Allocate a KCCB command and add it to KCCB deferred list - - PARAMETERS : psDevInfo RGX device info - : eKCCBType Firmware Command type - : psKCCBCmd Firmware Command - : uiPDumpFlags Pdump flags - - RETURNS : PVRSRV_OK If all went good, PVRSRV_ERROR_RETRY otherwise. -******************************************************************************/ -static PVRSRV_ERROR _AllocDeferredCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 uiPDumpFlags) -{ - RGX_DEFERRED_KCCB_CMD *psDeferredCommand; - OS_SPINLOCK_FLAGS uiFlags; - - psDeferredCommand = OSAllocMem(sizeof(*psDeferredCommand)); - - if (!psDeferredCommand) - { - PVR_DPF((PVR_DBG_ERROR, - "Deferring a KCCB command failed: allocation failure: requesting retry")); - return PVRSRV_ERROR_RETRY; - } - - psDeferredCommand->sKCCBcmd = *psKCCBCmd; - psDeferredCommand->uiPDumpFlags = uiPDumpFlags; - psDeferredCommand->psDevInfo = psDevInfo; - - OSSpinLockAcquire(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - dllist_add_to_tail(&(psDevInfo->sKCCBDeferredCommandsListHead), &(psDeferredCommand->sListNode)); - psDevInfo->ui32KCCBDeferredCommandsCount++; - OSSpinLockRelease(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - - return PVRSRV_OK; -} - -/****************************************************************************** - FUNCTION : _FreeDeferredCommand - - PURPOSE : Remove from the deferred list the sent deferred KCCB command - - PARAMETERS : psNode Node in deferred list - : psDeferredKCCBCmd KCCB Command to free - - RETURNS : None -******************************************************************************/ -static void _FreeDeferredCommand(DLLIST_NODE *psNode, RGX_DEFERRED_KCCB_CMD *psDeferredKCCBCmd) -{ - dllist_remove_node(psNode); - psDeferredKCCBCmd->psDevInfo->ui32KCCBDeferredCommandsCount--; - OSFreeMem(psDeferredKCCBCmd); -} - -/****************************************************************************** - FUNCTION : RGXSendCommandsFromDeferredList - - PURPOSE : Try send KCCB commands in deferred list to KCCB - Should be called by holding PowerLock - - PARAMETERS : psDevInfo RGX device info - : bPoll Poll for space in KCCB - - RETURNS : PVRSRV_OK If all commands in deferred list are sent to KCCB, - PVRSRV_ERROR_KERNEL_CCB_FULL otherwise. -******************************************************************************/ -PVRSRV_ERROR RGXSendCommandsFromDeferredList(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bPoll) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - DLLIST_NODE *psNode, *psNext; - RGX_DEFERRED_KCCB_CMD *psTempDeferredKCCBCmd; - DLLIST_NODE sCommandList; - OS_SPINLOCK_FLAGS uiFlags; - - PVR_ASSERT(PVRSRVPwrLockIsLockedByMe(psDevInfo->psDeviceNode)); - - /* !!! Important !!! - * - * The idea of moving the whole list hLockKCCBDeferredCommandsList below - * to the temporary list is only valid under the principle that all of the - * operations are also protected by the power lock. It must be held - * so that the order of the commands doesn't get messed up while we're - * performing the operations on the local list. - * - * The necessity of releasing the hLockKCCBDeferredCommandsList comes from - * the fact that _FreeDeferredCommand() is allocating memory and it can't - * be done in atomic context (inside section protected by a spin lock). - * - * We're using spin lock here instead of mutex to quickly perform a check - * if the list is empty in MISR without a risk that the MISR is going - * to sleep due to a lock. - */ - - /* move the whole list to a local list so it can be processed without lock */ - OSSpinLockAcquire(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - dllist_replace_head(&psDevInfo->sKCCBDeferredCommandsListHead, &sCommandList); - OSSpinLockRelease(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if (dllist_is_empty(&sCommandList)) - { - return PVRSRV_OK; - } - - /* For every deferred KCCB command, try to send it*/ - dllist_foreach_node(&sCommandList, psNode, psNext) - { - psTempDeferredKCCBCmd = IMG_CONTAINER_OF(psNode, RGX_DEFERRED_KCCB_CMD, sListNode); - eError = RGXSendCommandRaw(psTempDeferredKCCBCmd->psDevInfo, - &psTempDeferredKCCBCmd->sKCCBcmd, - psTempDeferredKCCBCmd->uiPDumpFlags, - NULL /* We surely aren't interested in kCCB slot number of deferred command */); - if (eError != PVRSRV_OK) - { - if (!bPoll) - { - eError = PVRSRV_ERROR_KERNEL_CCB_FULL; - goto cleanup_; - } - break; - } - - _FreeDeferredCommand(psNode, psTempDeferredKCCBCmd); - } - - if (bPoll) - { - PVRSRV_ERROR eErrPollForKCCBSlot; - - /* Don't overwrite eError because if RGXPollKernelCCBSlot returns OK and the - * outer loop times-out, we'll still want to return KCCB_FULL to caller - */ - eErrPollForKCCBSlot = RGXPollKernelCCBSlot(psDevInfo->psKernelCCBCtlMemDesc, - psDevInfo->psKernelCCBCtl); - if (eErrPollForKCCBSlot == PVRSRV_ERROR_KERNEL_CCB_FULL) - { - eError = PVRSRV_ERROR_KERNEL_CCB_FULL; - goto cleanup_; - } - } - } END_LOOP_UNTIL_TIMEOUT(); - -cleanup_: - /* if the local list is not empty put it back to the deferred list head - * so that the old order of commands is retained */ - OSSpinLockAcquire(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - dllist_insert_list_at_head(&psDevInfo->sKCCBDeferredCommandsListHead, &sCommandList); - OSSpinLockRelease(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - - return eError; -} - -PVRSRV_ERROR RGXSendCommandAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 uiPDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot) -{ - IMG_BOOL bPoll = (pui32CmdKCCBSlot != NULL); - PVRSRV_ERROR eError; - - /* - * First try to Flush all the cmds in deferred list. - * - * We cannot defer an incoming command if the caller is interested in - * knowing the command's kCCB slot: it plans to poll/wait for a - * response from the FW just after the command is enqueued, so we must - * poll for space to be available. - */ - eError = RGXSendCommandsFromDeferredList(psDevInfo, bPoll); - if (eError == PVRSRV_OK) - { - eError = RGXSendCommandRaw(psDevInfo, - psKCCBCmd, - uiPDumpFlags, - pui32CmdKCCBSlot); - } - - /* - * If we don't manage to enqueue one of the deferred commands or the command - * passed as argument because the KCCB is full, insert the latter into the deferred commands list. - * The deferred commands will also be flushed eventually by: - * - one more KCCB command sent for any DM - * - RGX_MISRHandler_CheckFWActivePowerState - */ - if (eError == PVRSRV_ERROR_KERNEL_CCB_FULL) - { - if (pui32CmdKCCBSlot == NULL) - { - eError = _AllocDeferredCommand(psDevInfo, psKCCBCmd, uiPDumpFlags); - } - else - { - /* Let the caller retry. Otherwise if we deferred the command and returned OK, - * the caller can end up looking in a stale CCB slot. - */ - PVR_DPF((PVR_DBG_WARNING, "%s: Couldn't flush the deferred queue for a command (Type:%d) " - "- will be retried", __func__, psKCCBCmd->eCmdType)); - } - } - - return eError; -} - -PVRSRV_ERROR RGXSendCommandWithPowLockAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - - /* Ensure Rogue is powered up before kicking MTS */ - eError = PVRSRVPowerLock(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: failed to acquire powerlock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - - goto _PVRSRVPowerLock_Exit; - } - - PDUMPPOWCMDSTART(psDeviceNode); - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_NONE); - PDUMPPOWCMDEND(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to transition Rogue to ON (%s)", - __func__, - PVRSRVGetErrorString(eError))); - - goto _PVRSRVSetDevicePowerStateKM_Exit; - } - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - psKCCBCmd, - ui32PDumpFlags, - pui32CmdKCCBSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to schedule command (%s)", - __func__, - PVRSRVGetErrorString(eError))); -#if defined(DEBUG) - /* PVRSRVDebugRequest must be called without powerlock */ - PVRSRVPowerUnlock(psDeviceNode); - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - goto _PVRSRVPowerLock_Exit; -#endif - } - -_PVRSRVSetDevicePowerStateKM_Exit: - PVRSRVPowerUnlock(psDeviceNode); - -_PVRSRVPowerLock_Exit: - return eError; -} - -void RGXScheduleProcessQueuesKM(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*) hCmdCompHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSScheduleMISR(psDevInfo->hProcessQueuesMISR); -} - -#if defined(SUPPORT_VALIDATION) -PVRSRV_ERROR RGXScheduleRgxRegCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 ui64RegVal, - IMG_UINT64 ui64Size, - IMG_UINT32 ui32Offset, - IMG_BOOL bWriteOp) -{ - RGXFWIF_KCCB_CMD sRgxRegsCmd = {0}; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_ERROR eError; - - sRgxRegsCmd.eCmdType = RGXFWIF_KCCB_CMD_RGXREG; - sRgxRegsCmd.uCmdData.sFwRgxData.ui64RegVal = ui64RegVal; - sRgxRegsCmd.uCmdData.sFwRgxData.ui32RegWidth = ui64Size; - sRgxRegsCmd.uCmdData.sFwRgxData.ui32RegAddr = ui32Offset; - sRgxRegsCmd.uCmdData.sFwRgxData.bWriteOp = bWriteOp; - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - RGXFWIF_DM_GP, - &sRgxRegsCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot"); - - if (bWriteOp) - { - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, - ui32kCCBCommandSlot, - PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); - } - - return eError; -} -#endif - -/*! -******************************************************************************* - - @Function RGX_MISRHandler_ScheduleProcessQueues - - @Description - Sends uncounted kick to all the DMs (the FW will process all - the queue for all the DMs) -******************************************************************************/ -static void RGX_MISRHandler_ScheduleProcessQueues(void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = pvData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - PVRSRV_DEV_POWER_STATE ePowerState; - - eError = PVRSRVPowerLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to acquire powerlock (%s)", - __func__, PVRSRVGetErrorString(eError))); - return; - } - - /* Check whether it's worth waking up the GPU */ - eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - - if (!PVRSRV_VZ_MODE_IS(GUEST) && - (eError == PVRSRV_OK) && (ePowerState == PVRSRV_DEV_POWER_STATE_OFF)) - { - /* For now, guest drivers will always wake-up the GPU */ - RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb; - IMG_BOOL bGPUHasWorkWaiting; - - bGPUHasWorkWaiting = - (RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord) == RGXFWIF_GPU_UTIL_STATE_BLOCKED); - - if (!bGPUHasWorkWaiting) - { - /* all queues are empty, don't wake up the GPU */ - PVRSRVPowerUnlock(psDeviceNode); - return; - } - } - - PDUMPPOWCMDSTART(psDeviceNode); - /* wake up the GPU */ - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_NONE); - PDUMPPOWCMDEND(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to transition Rogue to ON (%s)", - __func__, PVRSRVGetErrorString(eError))); - - PVRSRVPowerUnlock(psDeviceNode); - return; - } - - /* uncounted kick to the FW */ - HTBLOGK(HTB_SF_MAIN_KICK_UNCOUNTED); - __MTSScheduleWrite(psDevInfo, (RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED); - - PVRSRVPowerUnlock(psDeviceNode); -} - -PVRSRV_ERROR RGXInstallProcessQueuesMISR(IMG_HANDLE *phMISR, PVRSRV_DEVICE_NODE *psDeviceNode) -{ - return OSInstallMISR(phMISR, - RGX_MISRHandler_ScheduleProcessQueues, - psDeviceNode, - "RGX_ScheduleProcessQueues"); -} - -PVRSRV_ERROR RGXScheduleCommandAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DM eKCCBType, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot) -{ - PVRSRV_ERROR eError; - IMG_UINT32 uiMMUSyncUpdate; - - /* Don't send the command/power up request if the device is de-initialising. - * The de-init thread could destroy the device whilst the power up - * sequence below is accessing the HW registers. - */ - if (unlikely((psDevInfo == NULL) || - (psDevInfo->psDeviceNode == NULL) || - (psDevInfo->psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_DEINIT))) - { - return PVRSRV_ERROR_INVALID_DEVICE; - } - -#if defined(SUPPORT_VALIDATION) - /* For validation, force the core to different dust count states with each kick */ - if ((eKCCBType == RGXFWIF_DM_GEOM) || (eKCCBType == RGXFWIF_DM_CDM)) - { - if (psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_GPU_UNITS_POWER_CHANGE_EN) - { - IMG_UINT32 ui32NumDusts = RGXGetNextDustCount(&psDevInfo->sDustReqState, psDevInfo->sDevFeatureCfg.ui32MAXDustCount); - PVRSRVDeviceGPUUnitsPowerChange(psDevInfo->psDeviceNode, ui32NumDusts); - } - } - - if (psDevInfo->ui32ECCRAMErrInjModule != RGXKM_ECC_ERR_INJ_DISABLE) - { - if (psDevInfo->ui32ECCRAMErrInjInterval > 0U) - { - --psDevInfo->ui32ECCRAMErrInjInterval; - } - else - { - IMG_UINT64 ui64ECCRegVal = 0U; - - psDevInfo->ui32ECCRAMErrInjInterval = RGXKM_ECC_ERR_INJ_INTERVAL; - - if (psDevInfo->ui32ECCRAMErrInjModule == RGXKM_ECC_ERR_INJ_SLC) - { - PVR_LOG(("ECC RAM Error Inject SLC")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_EN; - } - else if (psDevInfo->ui32ECCRAMErrInjModule == RGXKM_ECC_ERR_INJ_USC) - { - PVR_LOG(("ECC RAM Error Inject USC")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_USC_EN; - } - else if (psDevInfo->ui32ECCRAMErrInjModule == RGXKM_ECC_ERR_INJ_TPU) - { -#if defined(RGX_FEATURE_MAX_TPU_PER_SPU) - PVR_LOG(("ECC RAM Error Inject Swift TPU")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_SWIFT_EN; -#else - PVR_LOG(("ECC RAM Error Inject TPU MCU L0")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_EN; -#endif - } - else if (psDevInfo->ui32ECCRAMErrInjModule == RGXKM_ECC_ERR_INJ_RASCAL) - { -#if defined(RGX_CR_ECC_RAM_ERR_INJ_RASCAL_EN) - PVR_LOG(("ECC RAM Error Inject RASCAL")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_RASCAL_EN; -#else - PVR_LOG(("ECC RAM Error Inject USC")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_USC_EN; -#endif - } - else if (psDevInfo->ui32ECCRAMErrInjModule == RGXKM_ECC_ERR_INJ_MARS) - { - PVR_LOG(("ECC RAM Error Inject MARS")); - ui64ECCRegVal = RGX_CR_ECC_RAM_ERR_INJ_MARS_EN; - } - else - { - } - - OSWriteMemoryBarrier(NULL); - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_ECC_RAM_ERR_INJ, ui64ECCRegVal); - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Write reg ECC_RAM_ERR_INJ"); - PDUMPREG64(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_ECC_RAM_ERR_INJ, ui64ECCRegVal, PDUMP_FLAGS_CONTINUOUS); - OSWriteMemoryBarrier(NULL); - } - } -#endif - - /* PVRSRVPowerLock guarantees atomicity between commands. This is helpful - in a scenario with several applications allocating resources. */ - eError = PVRSRVPowerLock(psDevInfo->psDeviceNode); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to acquire powerlock (%s)", - __func__, PVRSRVGetErrorString(eError))); - - /* If system is found powered OFF, Retry scheduling the command */ - if (likely(eError == PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF)) - { - eError = PVRSRV_ERROR_RETRY; - } - - goto RGXScheduleCommand_exit; - } - - if (unlikely(psDevInfo->psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_DEINIT)) - { - /* If we have the power lock the device is valid but the deinit - * thread could be waiting for the lock. */ - PVRSRVPowerUnlock(psDevInfo->psDeviceNode); - return PVRSRV_ERROR_INVALID_DEVICE; - } - - /* Ensure device is powered up before sending any commands */ - PDUMPPOWCMDSTART(psDevInfo->psDeviceNode); - eError = PVRSRVSetDevicePowerStateKM(psDevInfo->psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_NONE); - PDUMPPOWCMDEND(psDevInfo->psDeviceNode); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to transition RGX to ON (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto _PVRSRVSetDevicePowerStateKM_Exit; - } - - eError = RGXPreKickCacheCommand(psDevInfo, eKCCBType, &uiMMUSyncUpdate); - if (unlikely(eError != PVRSRV_OK)) goto _PVRSRVSetDevicePowerStateKM_Exit; - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, psKCCBCmd, ui32PDumpFlags, pui32CmdKCCBSlot); - if (unlikely(eError != PVRSRV_OK)) goto _PVRSRVSetDevicePowerStateKM_Exit; - -_PVRSRVSetDevicePowerStateKM_Exit: - PVRSRVPowerUnlock(psDevInfo->psDeviceNode); - -RGXScheduleCommand_exit: - return eError; -} - -/* - * RGXCheckFirmwareCCB - */ -void RGXCheckFirmwareCCB(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_CCB_CTL *psFWCCBCtl = psDevInfo->psFirmwareCCBCtl; - IMG_UINT8 *psFWCCB = psDevInfo->psFirmwareCCB; - -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) - PVR_LOG_RETURN_VOID_IF_FALSE(PVRSRV_VZ_MODE_IS(NATIVE) || - (KM_FW_CONNECTION_IS(ACTIVE, psDevInfo) && - KM_OS_CONNECTION_IS(ACTIVE, psDevInfo)), - "FW-KM connection is down"); -#endif - - while (psFWCCBCtl->ui32ReadOffset != psFWCCBCtl->ui32WriteOffset) - { - /* Point to the next command */ - const RGXFWIF_FWCCB_CMD *psFwCCBCmd = ((RGXFWIF_FWCCB_CMD *)psFWCCB) + psFWCCBCtl->ui32ReadOffset; - - HTBLOGK(HTB_SF_MAIN_FWCCB_CMD, psFwCCBCmd->eCmdType); - switch (psFwCCBCmd->eCmdType) - { - case RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING: - { - if (psDevInfo->bPDPEnabled) - { - PDUMP_PANIC(psDevInfo->psDeviceNode, ZSBUFFER_BACKING, - "Request to add backing to ZSBuffer"); - } - RGXProcessRequestZSBufferBacking(psDevInfo, - psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID); - break; - } - - case RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING: - { - if (psDevInfo->bPDPEnabled) - { - PDUMP_PANIC(psDevInfo->psDeviceNode, ZSBUFFER_UNBACKING, - "Request to remove backing from ZSBuffer"); - } - RGXProcessRequestZSBufferUnbacking(psDevInfo, - psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID); - break; - } - - case RGXFWIF_FWCCB_CMD_FREELIST_GROW: - { - if (psDevInfo->bPDPEnabled) - { - PDUMP_PANIC(psDevInfo->psDeviceNode, FREELIST_GROW, - "Request to grow the free list"); - } - RGXProcessRequestGrow(psDevInfo, - psFwCCBCmd->uCmdData.sCmdFreeListGS.ui32FreelistID); - break; - } - - case RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION: - { - if (psDevInfo->bPDPEnabled) - { - PDUMP_PANIC(psDevInfo->psDeviceNode, FREELISTS_RECONSTRUCTION, - "Request to reconstruct free lists"); - } - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Freelist reconstruction request (%d) for %d freelists", - __func__, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32HwrCounter+1, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount)); - } - else - { - PVR_ASSERT(psDevInfo->psRGXFWIfHWRInfoBufCtl); - PVR_DPF((PVR_DBG_MESSAGE, "%s: Freelist reconstruction request (%d/%d) for %d freelists", - __func__, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32HwrCounter+1, - psDevInfo->psRGXFWIfHWRInfoBufCtl->ui32HwrCounter+1, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount)); - } - - RGXProcessRequestFreelistsReconstruction(psDevInfo, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount, - psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.aui32FreelistIDs); - break; - } - - case RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION: - { - /* Notify client drivers */ - /* Client notification of device error will be achieved by - * clients calling UM function RGXGetLastDeviceError() */ - psDevInfo->eLastDeviceError = RGX_CONTEXT_RESET_REASON_FW_PAGEFAULT; - - /* Notify system layer */ - { - PVRSRV_DEVICE_NODE *psDevNode = psDevInfo->psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - const RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA *psCmdFwPagefault = - &psFwCCBCmd->uCmdData.sCmdFWPagefault; - - if (psDevConfig->pfnSysDevErrorNotify) - { - PVRSRV_ROBUSTNESS_NOTIFY_DATA sErrorData = {0}; - - sErrorData.eResetReason = RGX_CONTEXT_RESET_REASON_FW_PAGEFAULT; - sErrorData.uErrData.sFwPFErrData.sFWFaultAddr.uiAddr = psCmdFwPagefault->sFWFaultAddr.uiAddr; - - psDevConfig->pfnSysDevErrorNotify(psDevConfig, - &sErrorData); - } - } - break; - } - - case RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION: - { - DLLIST_NODE *psNode, *psNext; - const RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA *psCmdContextResetNotification = - &psFwCCBCmd->uCmdData.sCmdContextResetNotification; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext = NULL; - IMG_UINT32 ui32ErrorPid = 0; - - OSWRLockAcquireRead(psDevInfo->hCommonCtxtListLock); - - dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, psNode, psNext) - { - RGX_SERVER_COMMON_CONTEXT *psThisContext = - IMG_CONTAINER_OF(psNode, RGX_SERVER_COMMON_CONTEXT, sListNode); - - /* If the notification applies to all contexts update reset info - * for all contexts, otherwise only do so for the appropriate ID. - */ - if (psCmdContextResetNotification->ui32Flags & RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS) - { - /* Notification applies to all contexts */ - psThisContext->eLastResetReason = psCmdContextResetNotification->eResetReason; - psThisContext->ui32LastResetJobRef = psCmdContextResetNotification->ui32ResetJobRef; - } - else - { - /* Notification applies to one context only */ - if (psThisContext->ui32ContextID == psCmdContextResetNotification->ui32ServerCommonContextID) - { - psServerCommonContext = psThisContext; - psServerCommonContext->eLastResetReason = psCmdContextResetNotification->eResetReason; - psServerCommonContext->ui32LastResetJobRef = psCmdContextResetNotification->ui32ResetJobRef; - ui32ErrorPid = RGXGetPIDFromServerMMUContext(psServerCommonContext->psServerMMUContext); - break; - } - } - } - - if (psCmdContextResetNotification->ui32Flags & RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: All contexts reset (Reason=%d, JobRef=0x%08x)", - __func__, - (IMG_UINT32)(psCmdContextResetNotification->eResetReason), - psCmdContextResetNotification->ui32ResetJobRef)); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Context 0x%p reset (ID=0x%08x, Reason=%d, JobRef=0x%08x)", - __func__, - psServerCommonContext, - psCmdContextResetNotification->ui32ServerCommonContextID, - (IMG_UINT32)(psCmdContextResetNotification->eResetReason), - psCmdContextResetNotification->ui32ResetJobRef)); - } - - /* Increment error counter (if appropriate) */ - if (psCmdContextResetNotification->eResetReason == RGX_CONTEXT_RESET_REASON_WGP_CHECKSUM) - { - /* Avoid wrapping the error count (which would then - * make it appear we had far fewer errors), by limiting - * it to IMG_UINT32_MAX. - */ - if (psDevInfo->sErrorCounts.ui32WGPErrorCount < IMG_UINT32_MAX) - { - psDevInfo->sErrorCounts.ui32WGPErrorCount++; - } - } - else if (psCmdContextResetNotification->eResetReason == RGX_CONTEXT_RESET_REASON_TRP_CHECKSUM) - { - /* Avoid wrapping the error count (which would then - * make it appear we had far fewer errors), by limiting - * it to IMG_UINT32_MAX. - */ - if (psDevInfo->sErrorCounts.ui32TRPErrorCount < IMG_UINT32_MAX) - { - psDevInfo->sErrorCounts.ui32TRPErrorCount++; - } - } - OSWRLockReleaseRead(psDevInfo->hCommonCtxtListLock); - - /* Notify system layer */ - { - PVRSRV_DEVICE_NODE *psDevNode = psDevInfo->psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - - if (psDevConfig->pfnSysDevErrorNotify) - { - PVRSRV_ROBUSTNESS_NOTIFY_DATA sErrorData = {0}; - - sErrorData.eResetReason = psCmdContextResetNotification->eResetReason; - sErrorData.pid = ui32ErrorPid; - - /* Populate error data according to reset reason */ - switch (psCmdContextResetNotification->eResetReason) - { - case RGX_CONTEXT_RESET_REASON_WGP_CHECKSUM: - case RGX_CONTEXT_RESET_REASON_TRP_CHECKSUM: - { - sErrorData.uErrData.sChecksumErrData.ui32ExtJobRef = psCmdContextResetNotification->ui32ResetJobRef; - sErrorData.uErrData.sChecksumErrData.eDM = psCmdContextResetNotification->eDM; - break; - } - default: - { - break; - } - } - - psDevConfig->pfnSysDevErrorNotify(psDevConfig, - &sErrorData); - } - } - - /* Notify if a page fault */ - if (psCmdContextResetNotification->ui32Flags & RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_PF) - { - DevmemIntPFNotify(psDevInfo->psDeviceNode, - psCmdContextResetNotification->ui64PCAddress, - psCmdContextResetNotification->sFaultAddress); - } - break; - } - - case RGXFWIF_FWCCB_CMD_DEBUG_DUMP: - { - PVRSRV_ERROR eError; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - OSAtomicWrite(&psDevInfo->psDeviceNode->eDebugDumpRequested, PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE); - eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to signal FW Cmd debug dump event, dumping now instead", __func__)); - PVRSRVDebugRequest(psDevInfo->psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - } - break; - } - - case RGXFWIF_FWCCB_CMD_UPDATE_STATS: - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - IMG_PID pidTmp = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.pidOwner; - IMG_INT32 i32AdjustmentValue = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.i32AdjustmentValue; - - switch (psFwCCBCmd->uCmdData.sCmdUpdateStatsData.eElementToUpdate) - { - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS: - { - PVRSRVStatsUpdateRenderContextStats(i32AdjustmentValue,0,0,0,0,0,pidTmp); - break; - } - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY: - { - PVRSRVStatsUpdateRenderContextStats(0,i32AdjustmentValue,0,0,0,0,pidTmp); - break; - } - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES: - { - PVRSRVStatsUpdateRenderContextStats(0,0,i32AdjustmentValue,0,0,0,pidTmp); - break; - } - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES: - { - PVRSRVStatsUpdateRenderContextStats(0,0,0,i32AdjustmentValue,0,0,pidTmp); - break; - } - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES: - { - PVRSRVStatsUpdateRenderContextStats(0,0,0,0,i32AdjustmentValue,0,pidTmp); - break; - } - case RGXFWIF_FWCCB_CMD_UPDATE_NUM_TDM_STORES: - { - PVRSRVStatsUpdateRenderContextStats(0,0,0,0,0,i32AdjustmentValue,pidTmp); - break; - } - } -#endif - break; - } - case RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE: - { -#if defined(SUPPORT_PDVFS) - PDVFS_PROCESS_CORE_CLK_RATE_CHANGE(psDevInfo, - psFwCCBCmd->uCmdData.sCmdCoreClkRateChange.ui32CoreClkRate); -#endif - break; - } - - case RGXFWIF_FWCCB_CMD_REQUEST_GPU_RESTART: - { - if (psDevInfo->psRGXFWIfFwSysData != NULL && - psDevInfo->psRGXFWIfFwSysData->ePowState != RGXFWIF_POW_OFF) - { - PVRSRV_ERROR eError; - - /* Power down... */ - eError = PVRSRVSetDeviceSystemPowerState(psDevInfo->psDeviceNode, - PVRSRV_SYS_POWER_STATE_OFF, PVRSRV_POWER_FLAGS_NONE); - if (eError == PVRSRV_OK) - { - /* Clear the FW faulted flags... */ - psDevInfo->psRGXFWIfFwSysData->ui32HWRStateFlags &= ~(RGXFWIF_HWR_FW_FAULT|RGXFWIF_HWR_RESTART_REQUESTED); - - /* Power back up again... */ - eError = PVRSRVSetDeviceSystemPowerState(psDevInfo->psDeviceNode, - PVRSRV_SYS_POWER_STATE_ON, PVRSRV_POWER_FLAGS_NONE); - - /* Send a dummy KCCB command to ensure the FW wakes up and checks the queues... */ - if (eError == PVRSRV_OK) - { - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXFWHealthCheckCmd(psDevInfo); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - } - } - - /* Notify client drivers and system layer of FW fault */ - { - PVRSRV_DEVICE_NODE *psDevNode = psDevInfo->psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - - /* Client notification of device error will be achieved by - * clients calling UM function RGXGetLastDeviceError() */ - psDevInfo->eLastDeviceError = RGX_CONTEXT_RESET_REASON_FW_EXEC_ERR; - - /* Notify system layer */ - if (psDevConfig->pfnSysDevErrorNotify) - { - PVRSRV_ROBUSTNESS_NOTIFY_DATA sErrorData = {0}; - - sErrorData.eResetReason = RGX_CONTEXT_RESET_REASON_FW_EXEC_ERR; - psDevConfig->pfnSysDevErrorNotify(psDevConfig, - &sErrorData); - } - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed firmware restart (%s)", - __func__, PVRSRVGetErrorString(eError))); - } - } - break; - } -#if defined(SUPPORT_VALIDATION) - case RGXFWIF_FWCCB_CMD_REG_READ: - { - psDevInfo->sFwRegs.ui64RegVal = psFwCCBCmd->uCmdData.sCmdRgxRegReadData.ui64RegValue; - complete(&psDevInfo->sFwRegs.sRegComp); - break; - } -#if defined(SUPPORT_SOC_TIMER) - case RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS: - { - if (psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags & RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER) - { - PVRSRV_ERROR eSOCtimerErr = RGXValidateSOCUSCTimer(psDevInfo, - PDUMP_NONE, - psFwCCBCmd->uCmdData.sCmdTimers.ui64timerGray, - psFwCCBCmd->uCmdData.sCmdTimers.ui64timerBinary, - psFwCCBCmd->uCmdData.sCmdTimers.aui64uscTimers); - if (PVRSRV_OK == eSOCtimerErr) - { - PVR_DPF((PVR_DBG_WARNING, "SoC or USC Timers have increased over time")); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "SoC or USC Timers have NOT increased over time")); - } - } - break; - } -#endif -#endif - default: - { - /* unknown command */ - PVR_DPF((PVR_DBG_WARNING, "%s: Unknown Command (eCmdType=0x%08x)", - __func__, psFwCCBCmd->eCmdType)); - /* Assert on magic value corruption */ - PVR_ASSERT((((IMG_UINT32)psFwCCBCmd->eCmdType & RGX_CMD_MAGIC_DWORD_MASK) >> RGX_CMD_MAGIC_DWORD_SHIFT) == RGX_CMD_MAGIC_DWORD); - } - } - - /* Update read offset */ - psFWCCBCtl->ui32ReadOffset = (psFWCCBCtl->ui32ReadOffset + 1) & psFWCCBCtl->ui32WrapMask; - } -} - -/* - * PVRSRVRGXFrameworkCopyCommand -*/ -PVRSRV_ERROR PVRSRVRGXFrameworkCopyCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psFWFrameworkMemDesc, - IMG_PBYTE pbyGPUFRegisterList, - IMG_UINT32 ui32FrameworkRegisterSize) -{ - PVRSRV_ERROR eError; - RGXFWIF_RF_REGISTERS *psRFReg; - - eError = DevmemAcquireCpuVirtAddr(psFWFrameworkMemDesc, - (void **)&psRFReg); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware render context state (%u)", - __func__, eError)); - return eError; - } - - OSDeviceMemCopy(psRFReg, pbyGPUFRegisterList, ui32FrameworkRegisterSize); - - /* Release the CPU mapping */ - DevmemReleaseCpuVirtAddr(psFWFrameworkMemDesc); - - /* - * Dump the FW framework buffer - */ -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump FWFramework buffer"); - DevmemPDumpLoadMem(psFWFrameworkMemDesc, 0, ui32FrameworkRegisterSize, PDUMP_FLAGS_CONTINUOUS); -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); -#endif - - return PVRSRV_OK; -} - -/* - * PVRSRVRGXFrameworkCreateKM -*/ -PVRSRV_ERROR PVRSRVRGXFrameworkCreateKM(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC **ppsFWFrameworkMemDesc, - IMG_UINT32 ui32FrameworkCommandSize) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* - Allocate device memory for the firmware GPU framework state. - Sufficient info to kick one or more DMs should be contained in this buffer - */ - PDUMPCOMMENT(psDeviceNode, "Allocate Rogue firmware framework state"); - - eError = DevmemFwAllocate(psDevInfo, - ui32FrameworkCommandSize, - RGX_FWCOMCTX_ALLOCFLAGS, - "FwGPUFrameworkState", - ppsFWFrameworkMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware framework state (%u)", - __func__, eError)); - return eError; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXPollForGPCommandCompletion(PVRSRV_DEVICE_NODE *psDevNode, - volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32CurrentQueueLength, ui32MaxRetries; - PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice; - const RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl; - - ui32CurrentQueueLength = (psKCCBCtl->ui32WrapMask+1 + - psKCCBCtl->ui32WriteOffset - - psKCCBCtl->ui32ReadOffset) & psKCCBCtl->ui32WrapMask; - ui32CurrentQueueLength += psDevInfo->ui32KCCBDeferredCommandsCount; - - for (ui32MaxRetries = ui32CurrentQueueLength + 1; - ui32MaxRetries > 0; - ui32MaxRetries--) - { - - /* - * PVRSRVPollForValueKM flags are set to POLL_FLAG_NONE in this case so that the function - * does not generate an error message. In this case, the PollForValueKM is expected to - * timeout as there is work ongoing on the GPU which may take longer than the timeout period. - */ - eError = PVRSRVPollForValueKM(psDevNode, pui32LinMemAddr, ui32Value, ui32Mask, POLL_FLAG_NONE); - if (eError != PVRSRV_ERROR_TIMEOUT) - { - break; - } - - RGXSendCommandsFromDeferredList(psDevInfo, IMG_FALSE); - } - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed! Error(%s) CPU linear address(%p) Expected value(%u)", - __func__, PVRSRVGetErrorString(eError), - pui32LinMemAddr, ui32Value)); - } - - return eError; -} - -PVRSRV_ERROR RGXStateFlagCtrl(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Config, - IMG_UINT32 *pui32ConfigState, - IMG_BOOL bSetNotClear) -{ - PVRSRV_ERROR eError; - PVRSRV_DEV_POWER_STATE ePowerState; - RGXFWIF_KCCB_CMD sStateFlagCmd = { 0 }; - PVRSRV_DEVICE_NODE *psDeviceNode; - RGXFWIF_SYSDATA *psSysData; - IMG_UINT32 ui32kCCBCommandSlot; - IMG_BOOL bWaitForFwUpdate = IMG_FALSE; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - if (!psDevInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - psDeviceNode = psDevInfo->psDeviceNode; - psSysData = psDevInfo->psRGXFWIfFwSysData; - - if (NULL == psSysData) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Fw Sys Config is not mapped into CPU space", __func__)); - return PVRSRV_ERROR_INVALID_CPU_ADDR; - } - - /* apply change and ensure the new data is written to memory - * before requesting the FW to read it - */ - ui32Config = ui32Config & RGXFWIF_INICFG_ALL; - if (bSetNotClear) - { - psSysData->ui32ConfigFlags |= ui32Config; - } - else - { - psSysData->ui32ConfigFlags &= ~ui32Config; - } - - /* return current/new value to caller */ - if (pui32ConfigState) - { - *pui32ConfigState = psSysData->ui32ConfigFlags; - } - - OSMemoryBarrier(&psSysData->ui32ConfigFlags); - - eError = PVRSRVPowerLock(psDeviceNode); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVPowerLock"); - - /* notify FW to update setting */ - eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - - if ((eError == PVRSRV_OK) && (ePowerState != PVRSRV_DEV_POWER_STATE_OFF)) - { - /* Ask the FW to update its cached version of the value */ - sStateFlagCmd.eCmdType = RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL; - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sStateFlagCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSendCommandAndGetKCCBSlot", unlock); - bWaitForFwUpdate = IMG_TRUE; - } - -unlock: - PVRSRVPowerUnlock(psDeviceNode); - if (bWaitForFwUpdate) - { - /* Wait for the value to be updated as the FW validates - * the parameters and modifies the ui32ConfigFlags - * accordingly - * (for completeness as registered callbacks should also - * not permit invalid transitions) - */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); - } - return eError; -} - -static -PVRSRV_ERROR RGXScheduleCleanupCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DM eDM, - RGXFWIF_KCCB_CMD *psKCCBCmd, - RGXFWIF_CLEANUP_TYPE eCleanupType, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32kCCBCommandSlot; - - /* Clean-up commands sent during frame capture intervals must be dumped even when not in capture range... */ - ui32PDumpFlags |= PDUMP_FLAGS_INTERVAL; - - psKCCBCmd->eCmdType = RGXFWIF_KCCB_CMD_CLEANUP; - psKCCBCmd->uCmdData.sCleanupData.eCleanupType = eCleanupType; - - /* - Send the cleanup request to the firmware. If the resource is still busy - the firmware will tell us and we'll drop out with a retry. - */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - eDM, - psKCCBCmd, - ui32PDumpFlags, - &ui32kCCBCommandSlot); - if (eError != PVRSRV_OK) - { - /* If caller may retry, fail with no error message */ - if ((eError != PVRSRV_ERROR_RETRY) && - (eError != PVRSRV_ERROR_KERNEL_CCB_FULL)) - { - PVR_DPF((PVR_DBG_ERROR ,"RGXScheduleCommandAndGetKCCBSlot() failed (%s) in %s()", - PVRSRVGETERRORSTRING(eError), __func__)); - } - goto fail_command; - } - - /* Wait for command kCCB slot to be updated by FW */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Wait for the firmware to reply to the cleanup command"); - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, - ui32PDumpFlags); - /* - If the firmware hasn't got back to us in a timely manner - then bail and let the caller retry the command. - */ - if (eError == PVRSRV_ERROR_TIMEOUT) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: RGXWaitForKCCBSlotUpdate timed out. Dump debug information.", - __func__)); - - eError = PVRSRV_ERROR_RETRY; -#if defined(DEBUG) - PVRSRVDebugRequest(psDevInfo->psDeviceNode, - DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); -#endif - goto fail_poll; - } - else if (eError != PVRSRV_OK) - { - goto fail_poll; - } - -#if defined(PDUMP) - /* - * The cleanup request to the firmware will tell us if a given resource is busy or not. - * If the RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY flag is set, this means that the resource is - * still in use. In this case we return a PVRSRV_ERROR_RETRY error to the client drivers - * and they will re-issue the cleanup request until it succeed. - * - * Since this retry mechanism doesn't work for pdumps, client drivers should ensure - * that cleanup requests are only submitted if the resource is unused. - * If this is not the case, the following poll will block infinitely, making sure - * the issue doesn't go unnoticed. - */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Cleanup: If this poll fails, the following resource is still in use (DM=%u, type=%u, address=0x%08x), which is incorrect in pdumps", - eDM, - psKCCBCmd->uCmdData.sCleanupData.eCleanupType, - psKCCBCmd->uCmdData.sCleanupData.uCleanupData.psContext.ui32Addr); - eError = DevmemPDumpDevmemPol32(psDevInfo->psKernelCCBRtnSlotsMemDesc, - ui32kCCBCommandSlot * sizeof(IMG_UINT32), - 0, - RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "DevmemPDumpDevmemPol32"); -#endif - - /* - If the command has was run but a resource was busy, then the request - will need to be retried. - */ - if (unlikely(psDevInfo->pui32KernelCCBRtnSlots[ui32kCCBCommandSlot] & RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY)) - { - if (psDevInfo->pui32KernelCCBRtnSlots[ui32kCCBCommandSlot] & RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE) - { - PVR_DPF((PVR_DBG_WARNING, "%s: FW poll on a HW operation failed", __func__)); - } - eError = PVRSRV_ERROR_RETRY; - goto fail_requestbusy; - } - - return PVRSRV_OK; - -fail_requestbusy: -fail_poll: -fail_command: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -/* - RGXRequestCommonContextCleanUp -*/ -PVRSRV_ERROR RGXFWRequestCommonContextCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - RGXFWIF_DM eDM, - IMG_UINT32 ui32PDumpFlags) -{ - RGXFWIF_KCCB_CMD sRCCleanUpCmd = {0}; - PVRSRV_ERROR eError; - PRGXFWIF_FWCOMMONCONTEXT psFWCommonContextFWAddr; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*)psDeviceNode->pvDevice; - - /* Force retry if this context's CCB is currently being dumped - * as part of the stalled CCB debug */ - if (psDevInfo->pvEarliestStalledClientCCB == (void*)psServerCommonContext->psClientCCB) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Forcing retry as psDevInfo->pvEarliestStalledClientCCB = psServerCommonContext->psClientCCB <%p>", - __func__, - (void*)psServerCommonContext->psClientCCB)); - return PVRSRV_ERROR_RETRY; - } - - psFWCommonContextFWAddr = FWCommonContextGetFWAddress(psServerCommonContext); -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Common ctx cleanup Request DM%d [context = 0x%08x]", - eDM, psFWCommonContextFWAddr.ui32Addr); - PDUMPCOMMENT(psDeviceNode, "Wait for CCB to be empty before common ctx cleanup"); - - RGXCCBPDumpDrainCCB(FWCommonContextGetClientCCB(psServerCommonContext), ui32PDumpFlags); -#endif - - /* Setup our command data, the cleanup call will fill in the rest */ - sRCCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psContext = psFWCommonContextFWAddr; - - /* Request cleanup of the firmware resource */ - eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice, - eDM, - &sRCCleanUpCmd, - RGXFWIF_CLEANUP_FWCOMMONCONTEXT, - ui32PDumpFlags); - - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule a memory context cleanup with error (%u)", - __func__, eError)); - } - - return eError; -} - -/* - * RGXFWRequestHWRTDataCleanUp - */ - -PVRSRV_ERROR RGXFWRequestHWRTDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode, - PRGXFWIF_HWRTDATA psHWRTData) -{ - RGXFWIF_KCCB_CMD sHWRTDataCleanUpCmd = {0}; - PVRSRV_ERROR eError; - - PDUMPCOMMENT(psDeviceNode, "HW RTData cleanup Request [HWRTData = 0x%08x]", psHWRTData.ui32Addr); - - sHWRTDataCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psHWRTData = psHWRTData; - - eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sHWRTDataCleanUpCmd, - RGXFWIF_CLEANUP_HWRTDATA, - PDUMP_FLAGS_NONE); - - if (eError != PVRSRV_OK) - { - /* If caller may retry, fail with no error message */ - if ((eError != PVRSRV_ERROR_RETRY) && - (eError != PVRSRV_ERROR_KERNEL_CCB_FULL)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule a HWRTData cleanup with error (%u)", - __func__, eError)); - } - } - - return eError; -} - -/* - RGXFWRequestFreeListCleanUp -*/ -PVRSRV_ERROR RGXFWRequestFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo, - PRGXFWIF_FREELIST psFWFreeList) -{ - RGXFWIF_KCCB_CMD sFLCleanUpCmd = {0}; - PVRSRV_ERROR eError; - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Free list cleanup Request [FreeList = 0x%08x]", psFWFreeList.ui32Addr); - - /* Setup our command data, the cleanup call will fill in the rest */ - sFLCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psFreelist = psFWFreeList; - - /* Request cleanup of the firmware resource */ - eError = RGXScheduleCleanupCommand(psDevInfo, - RGXFWIF_DM_GP, - &sFLCleanUpCmd, - RGXFWIF_CLEANUP_FREELIST, - PDUMP_FLAGS_NONE); - - if (eError != PVRSRV_OK) - { - /* If caller may retry, fail with no error message */ - if ((eError != PVRSRV_ERROR_RETRY) && - (eError != PVRSRV_ERROR_KERNEL_CCB_FULL)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule a memory context cleanup with error (%u)", - __func__, eError)); - } - } - - return eError; -} - -/* - RGXFWRequestZSBufferCleanUp -*/ -PVRSRV_ERROR RGXFWRequestZSBufferCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo, - PRGXFWIF_ZSBUFFER psFWZSBuffer) -{ - RGXFWIF_KCCB_CMD sZSBufferCleanUpCmd = {0}; - PVRSRV_ERROR eError; - - PDUMPCOMMENT(psDevInfo->psDeviceNode, "ZS Buffer cleanup Request [ZS Buffer = 0x%08x]", psFWZSBuffer.ui32Addr); - - /* Setup our command data, the cleanup call will fill in the rest */ - sZSBufferCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psZSBuffer = psFWZSBuffer; - - /* Request cleanup of the firmware resource */ - eError = RGXScheduleCleanupCommand(psDevInfo, - RGXFWIF_DM_3D, - &sZSBufferCleanUpCmd, - RGXFWIF_CLEANUP_ZSBUFFER, - PDUMP_FLAGS_NONE); - - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule a memory context cleanup with error (%u)", - __func__, eError)); - } - - return eError; -} - -PVRSRV_ERROR RGXFWSetHCSDeadline(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32HCSDeadlineMs) -{ - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - psDevInfo->psRGXFWIfRuntimeCfg->ui32HCSDeadlineMS = ui32HCSDeadlineMs; - OSWriteMemoryBarrier(&psDevInfo->psRGXFWIfRuntimeCfg->ui32HCSDeadlineMS); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Updating the Hard Context Switching deadline inside RGXFWIfRuntimeCfg"); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - offsetof(RGXFWIF_RUNTIME_CFG, ui32HCSDeadlineMS), - ui32HCSDeadlineMs, - PDUMP_FLAGS_CONTINUOUS); -#endif - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXFWHealthCheckCmd(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_KCCB_CMD sCmpKCCBCmd = { 0 }; - - sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_HEALTH_CHECK; - - return RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GP, - &sCmpKCCBCmd, - PDUMP_FLAGS_CONTINUOUS); -} - -PVRSRV_ERROR RGXFWSetFwOsState(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32OSid, - RGXFWIF_OS_STATE_CHANGE eOSOnlineState) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sOSOnlineStateCmd = { 0 }; - RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - - sOSOnlineStateCmd.eCmdType = RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE; - sOSOnlineStateCmd.uCmdData.sCmdOSOnlineStateData.ui32OSid = ui32OSid; - sOSOnlineStateCmd.uCmdData.sCmdOSOnlineStateData.eNewOSState = eOSOnlineState; - -#if defined(SUPPORT_AUTOVZ) - { - IMG_BOOL bConnectionDown = IMG_FALSE; - - PVR_UNREFERENCED_PARAMETER(psFwSysData); - sOSOnlineStateCmd.uCmdData.sCmdOSOnlineStateData.eNewOSState = RGXFWIF_OS_OFFLINE; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - /* Send the offline command regardless if power lock is held or not. - * Under AutoVz this is done during regular driver deinit, store-to-ram suspend - * or (optionally) from a kernel panic callback. Deinit and suspend operations - * take the lock in the rgx pre/post power functions as expected. - * The kernel panic callback is a last resort way of letting the firmware know that - * the VM is unrecoverable and the vz connection must be disabled. It cannot wait - * on other kernel threads to finish and release the lock. */ - eError = RGXSendCommand(psDevInfo, - &sOSOnlineStateCmd, - PDUMP_FLAGS_CONTINUOUS); - - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Guests and Host going offline should wait for confirmation - * from the Firmware of the state change. If this fails, break - * the connection on the OS Driver's end as backup. */ - if (PVRSRV_VZ_MODE_IS(GUEST) || (ui32OSid == RGXFW_HOST_OS)) - { - LOOP_UNTIL_TIMEOUT(SECONDS_TO_MICROSECONDS/2) - { - if (KM_FW_CONNECTION_IS(READY, psDevInfo)) - { - bConnectionDown = IMG_TRUE; - break; - } - } END_LOOP_UNTIL_TIMEOUT(); - - if (!bConnectionDown) - { - KM_SET_OS_CONNECTION(OFFLINE, psDevInfo); - } - } - } -#else - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - /* no reason for Guests to update their state or any other VM's. - * This is the Hypervisor and Host driver's responsibility. */ - return PVRSRV_OK; - } - else if (eOSOnlineState == RGXFWIF_OS_ONLINE) - { - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GP, - &sOSOnlineStateCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_ERROR_RETRY) break; - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - } - else if (psFwSysData) - { - const volatile RGXFWIF_OS_RUNTIME_FLAGS *psFwRunFlags = - (const volatile RGXFWIF_OS_RUNTIME_FLAGS*) &psFwSysData->asOsRuntimeFlagsMirror[ui32OSid]; - - /* Attempt several times until the FW manages to offload the OS */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - IMG_UINT32 ui32kCCBCommandSlot; - - /* Send request */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevInfo, - RGXFWIF_DM_GP, - &sOSOnlineStateCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - if (unlikely(eError == PVRSRV_ERROR_RETRY)) continue; - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommand", return_); - - /* Wait for FW to process the cmd */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", return_); - - /* read the OS state */ - OSMemoryBarrier(NULL); - /* check if FW finished offloading the OSID and is stopped */ - if (psFwRunFlags->bfOsState == RGXFW_CONNECTION_FW_OFFLINE) - { - eError = PVRSRV_OK; - break; - } - else - { - eError = PVRSRV_ERROR_TIMEOUT; - } - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - } - else - { - eError = PVRSRV_ERROR_NOT_INITIALISED; - } - -return_ : -#endif - return eError; -} - -PVRSRV_ERROR RGXFWChangeOSidPriority(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32Priority) -{ - PVRSRV_ERROR eError; - RGXFWIF_KCCB_CMD sOSidPriorityCmd = { 0 }; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - sOSidPriorityCmd.eCmdType = RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE; - psDevInfo->psRGXFWIfRuntimeCfg->aui32OSidPriority[ui32OSid] = ui32Priority; - OSWriteMemoryBarrier(&psDevInfo->psRGXFWIfRuntimeCfg->aui32OSidPriority[ui32OSid]); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Updating the priority of OSID%u inside RGXFWIfRuntimeCfg", ui32OSid); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - offsetof(RGXFWIF_RUNTIME_CFG, aui32OSidPriority) + (ui32OSid * sizeof(ui32Priority)), - ui32Priority , - PDUMP_FLAGS_CONTINUOUS); -#endif - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GP, - &sOSidPriorityCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - return eError; -} - -PVRSRV_ERROR ContextSetPriority(RGX_SERVER_COMMON_CONTEXT *psContext, - CONNECTION_DATA *psConnection, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Priority, - RGXFWIF_DM eDM) -{ - IMG_UINT32 ui32CmdSize; - IMG_UINT8 *pui8CmdPtr; - RGXFWIF_KCCB_CMD sPriorityCmd = { 0 }; - RGXFWIF_CCB_CMD_HEADER *psCmdHeader; - RGXFWIF_CMD_PRIORITY *psCmd; - PVRSRV_ERROR eError; - IMG_INT32 i32Priority = (IMG_INT32)ui32Priority; - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psContext); - - eError = _CheckPriority(psDevInfo, i32Priority, psContext->eRequestor); - PVR_LOG_GOTO_IF_ERROR(eError, "_CheckPriority", fail_checkpriority); - - /* - Get space for command - */ - ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CCB_CMD_HEADER) + sizeof(RGXFWIF_CMD_PRIORITY)); - - eError = RGXAcquireCCB(psClientCCB, - ui32CmdSize, - (void **) &pui8CmdPtr, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire space for client CCB", __func__)); - } - goto fail_ccbacquire; - } - - /* - Write the command header and command - */ - psCmdHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr; - psCmdHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PRIORITY; - psCmdHeader->ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CMD_PRIORITY)); - pui8CmdPtr += sizeof(*psCmdHeader); - - psCmd = (RGXFWIF_CMD_PRIORITY *) pui8CmdPtr; - psCmd->i32Priority = i32Priority; - pui8CmdPtr += sizeof(*psCmd); - - /* - We should reserve space in the kernel CCB here and fill in the command - directly. - This is so if there isn't space in the kernel CCB we can return with - retry back to services client before we take any operations - */ - - /* - Submit the command - */ - RGXReleaseCCB(psClientCCB, - ui32CmdSize, - PDUMP_FLAGS_CONTINUOUS); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to release space in client CCB", __func__)); - return eError; - } - - /* Construct the priority command. */ - sPriorityCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - sPriorityCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psContext); - sPriorityCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - sPriorityCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - sPriorityCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - sPriorityCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - eDM, - &sPriorityCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to submit set priority command with error (%u)", - __func__, - eError)); - goto fail_cmdacquire; - } - - psContext->i32Priority = i32Priority; - - return PVRSRV_OK; - -fail_ccbacquire: -fail_checkpriority: -fail_cmdacquire: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR RGXFWConfigPHR(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32PHRMode) -{ - PVRSRV_ERROR eError; - RGXFWIF_KCCB_CMD sCfgPHRCmd = { 0 }; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - sCfgPHRCmd.eCmdType = RGXFWIF_KCCB_CMD_PHR_CFG; - psDevInfo->psRGXFWIfRuntimeCfg->ui32PHRMode = ui32PHRMode; - OSWriteMemoryBarrier(&psDevInfo->psRGXFWIfRuntimeCfg->ui32PHRMode); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Updating the Periodic Hardware Reset Mode inside RGXFWIfRuntimeCfg"); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - offsetof(RGXFWIF_RUNTIME_CFG, ui32PHRMode), - ui32PHRMode, - PDUMP_FLAGS_CONTINUOUS); -#endif - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GP, - &sCfgPHRCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - return eError; -} - -PVRSRV_ERROR RGXFWConfigWdg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32WdgPeriodUs) -{ - PVRSRV_ERROR eError; - RGXFWIF_KCCB_CMD sCfgWdgCmd = { 0 }; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - sCfgWdgCmd.eCmdType = RGXFWIF_KCCB_CMD_WDG_CFG; - psDevInfo->psRGXFWIfRuntimeCfg->ui32WdgPeriodUs = ui32WdgPeriodUs; - OSWriteMemoryBarrier(&psDevInfo->psRGXFWIfRuntimeCfg->ui32WdgPeriodUs); - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Updating the firmware watchdog period inside RGXFWIfRuntimeCfg"); - DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRuntimeCfgMemDesc, - offsetof(RGXFWIF_RUNTIME_CFG, ui32WdgPeriodUs), - ui32WdgPeriodUs, - PDUMP_FLAGS_CONTINUOUS); -#endif - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GP, - &sCfgWdgCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - return eError; -} - - - -void RGXCheckForStalledClientContexts(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bIgnorePrevious) -{ - /* Attempt to detect and deal with any stalled client contexts. - * bIgnorePrevious may be set by the caller if they know a context to be - * stalled, as otherwise this function will only identify stalled - * contexts which have not been previously reported. - */ - - IMG_UINT32 ui32StalledClientMask = 0; - - if (!(OSTryLockAcquire(psDevInfo->hCCBStallCheckLock))) - { - PVR_LOG(("RGXCheckForStalledClientContexts: Failed to acquire hCCBStallCheckLock, returning...")); - return; - } - - ui32StalledClientMask |= CheckForStalledClientTransferCtxt(psDevInfo); - - ui32StalledClientMask |= CheckForStalledClientRenderCtxt(psDevInfo); - - ui32StalledClientMask |= CheckForStalledClientKickSyncCtxt(psDevInfo); - - if (psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_COMPUTE_BIT_MASK) - { - ui32StalledClientMask |= CheckForStalledClientComputeCtxt(psDevInfo); - } - - /* If at least one DM stalled bit is different than before */ - if (bIgnorePrevious || (psDevInfo->ui32StalledClientMask != ui32StalledClientMask))//(psDevInfo->ui32StalledClientMask ^ ui32StalledClientMask)) - { - if (ui32StalledClientMask > 0) - { - static __maybe_unused const char *pszStalledAction = -#if defined(PVRSRV_STALLED_CCB_ACTION) - "force"; -#else - "warn"; -#endif - /* Print all the stalled DMs */ - PVR_LOG(("Possible stalled client RGX contexts detected: %s%s%s%s%s%s%s%s%s", - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_GP), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TDM_2D), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TA), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_3D), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_CDM), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_RTU), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_SHG), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TQ2D), - RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TQ3D))); - - PVR_LOG(("Trying to identify stalled context...(%s) [%d]", - pszStalledAction, bIgnorePrevious)); - - DumpStalledContextInfo(psDevInfo); - } - else - { - if (psDevInfo->ui32StalledClientMask> 0) - { - /* Indicate there are no stalled DMs */ - PVR_LOG(("No further stalled client contexts exist")); - } - } - psDevInfo->ui32StalledClientMask = ui32StalledClientMask; - psDevInfo->pvEarliestStalledClientCCB = NULL; - } - OSLockRelease(psDevInfo->hCCBStallCheckLock); -} - -/* - RGXUpdateHealthStatus -*/ -PVRSRV_ERROR RGXUpdateHealthStatus(PVRSRV_DEVICE_NODE* psDevNode, - IMG_BOOL bCheckAfterTimePassed) -{ - const PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_HEALTH_STATUS eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK; - PVRSRV_DEVICE_HEALTH_REASON eNewReason = PVRSRV_DEVICE_HEALTH_REASON_NONE; - PVRSRV_RGXDEV_INFO* psDevInfo; - const RGXFWIF_TRACEBUF* psRGXFWIfTraceBufCtl; - const RGXFWIF_SYSDATA* psFwSysData; - const RGXFWIF_OSDATA* psFwOsData; - const RGXFWIF_CCB_CTL* psKCCBCtl; - IMG_UINT32 ui32ThreadCount; - IMG_BOOL bKCCBCmdsWaiting; - - PVR_ASSERT(psDevNode != NULL); - psDevInfo = psDevNode->pvDevice; - - /* If the firmware is not yet initialised or has already deinitialised, stop here */ - if (psDevInfo == NULL || !psDevInfo->bFirmwareInitialised || psDevInfo->pvRegsBaseKM == NULL || - psDevInfo->psDeviceNode == NULL || psDevInfo->psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_DEINIT) - { - return PVRSRV_OK; - } - - psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBufCtl; - psFwSysData = psDevInfo->psRGXFWIfFwSysData; - psFwOsData = psDevInfo->psRGXFWIfFwOsData; - - /* If this is a quick update, then include the last current value... */ - if (!bCheckAfterTimePassed) - { - eNewStatus = OSAtomicRead(&psDevNode->eHealthStatus); - eNewReason = OSAtomicRead(&psDevNode->eHealthReason); - } - - /* Decrement the SLR holdoff counter (if non-zero) */ - if (psDevInfo->ui32SLRHoldoffCounter > 0) - { - psDevInfo->ui32SLRHoldoffCounter--; - } - - /* If Rogue is not powered on, just skip ahead and check for stalled client CCBs */ - if (PVRSRVIsDevicePowered(psDevNode)) - { - if (psRGXFWIfTraceBufCtl != NULL) - { - /* - Firmware thread checks... - */ - for (ui32ThreadCount = 0; ui32ThreadCount < RGXFW_THREAD_NUM; ui32ThreadCount++) - { - const IMG_CHAR* pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szInfo; - - /* - Check if the FW has hit an assert... - */ - if (*pszTraceAssertInfo != '\0') - { - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware thread %d has asserted: %s (%s:%d)", - __func__, ui32ThreadCount, pszTraceAssertInfo, - psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szPath, - psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.ui32LineNum)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_ASSERTED; - goto _RGXUpdateHealthStatus_Exit; - } - - /* - Check the threads to see if they are in the same poll locations as last time... - */ - if (bCheckAfterTimePassed) - { - if (psFwSysData->aui32CrPollAddr[ui32ThreadCount] != 0 && - psFwSysData->aui32CrPollCount[ui32ThreadCount] == psDevInfo->aui32CrLastPollCount[ui32ThreadCount]) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware stuck on CR poll: T%u polling %s (reg:0x%08X mask:0x%08X)", - __func__, ui32ThreadCount, - ((psFwSysData->aui32CrPollAddr[ui32ThreadCount] & RGXFW_POLL_TYPE_SET)?("set"):("unset")), - psFwSysData->aui32CrPollAddr[ui32ThreadCount] & ~RGXFW_POLL_TYPE_SET, - psFwSysData->aui32CrPollMask[ui32ThreadCount])); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING; - goto _RGXUpdateHealthStatus_Exit; - } - psDevInfo->aui32CrLastPollCount[ui32ThreadCount] = psFwSysData->aui32CrPollCount[ui32ThreadCount]; - } - } - - /* - Check if the FW has faulted... - */ - if (psFwSysData->ui32HWRStateFlags & RGXFWIF_HWR_FW_FAULT) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Firmware has faulted and needs to restart", - __func__)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_FAULT; - if (psFwSysData->ui32HWRStateFlags & RGXFWIF_HWR_RESTART_REQUESTED) - { - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_RESTARTING; - } - else - { - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_IDLING; - } - goto _RGXUpdateHealthStatus_Exit; - } - } - - /* - Event Object Timeouts check... - */ - if (!bCheckAfterTimePassed) - { - if (psDevInfo->ui32GEOTimeoutsLastTime > 1 && psPVRSRVData->ui32GEOConsecutiveTimeouts > psDevInfo->ui32GEOTimeoutsLastTime) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Global Event Object Timeouts have risen (from %d to %d)", - __func__, - psDevInfo->ui32GEOTimeoutsLastTime, psPVRSRVData->ui32GEOConsecutiveTimeouts)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS; - } - psDevInfo->ui32GEOTimeoutsLastTime = psPVRSRVData->ui32GEOConsecutiveTimeouts; - } - - /* - Check the Kernel CCB pointer is valid. If any commands were waiting last time, then check - that some have executed since then. - */ - bKCCBCmdsWaiting = IMG_FALSE; - psKCCBCtl = psDevInfo->psKernelCCBCtl; - - if (psKCCBCtl != NULL) - { - if (psKCCBCtl->ui32ReadOffset > psKCCBCtl->ui32WrapMask || - psKCCBCtl->ui32WriteOffset > psKCCBCtl->ui32WrapMask) - { - PVR_DPF((PVR_DBG_WARNING, "%s: KCCB has invalid offset (ROFF=%d WOFF=%d)", - __func__, psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT; - } - - if (psKCCBCtl->ui32ReadOffset != psKCCBCtl->ui32WriteOffset) - { - bKCCBCmdsWaiting = IMG_TRUE; - } - } - - if (bCheckAfterTimePassed && psFwOsData != NULL) - { - IMG_UINT32 ui32KCCBCmdsExecuted = psFwOsData->ui32KCCBCmdsExecuted; - - if (psDevInfo->ui32KCCBCmdsExecutedLastTime == ui32KCCBCmdsExecuted) - { - /* - If something was waiting last time then the Firmware has stopped processing commands. - */ - if (psDevInfo->bKCCBCmdsWaitingLastTime) - { - PVR_DPF((PVR_DBG_WARNING, "%s: No KCCB commands executed since check!", - __func__)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED; - } - - /* - If no commands are currently pending and nothing happened since the last poll, then - schedule a dummy command to ping the firmware so we know it is alive and processing. - */ - if (!bKCCBCmdsWaiting) - { - /* Protect the PDumpLoadMem. RGXScheduleCommand() cannot take the - * PMR lock itself, because some bridge functions will take the PMR lock - * before calling RGXScheduleCommand - */ - PVRSRV_ERROR eError = RGXFWHealthCheckCmd(psDevNode->pvDevice); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Cannot schedule Health Check command! (0x%x)", - __func__, eError)); - } - else - { - bKCCBCmdsWaiting = IMG_TRUE; - } - } - } - - psDevInfo->bKCCBCmdsWaitingLastTime = bKCCBCmdsWaiting; - psDevInfo->ui32KCCBCmdsExecutedLastTime = ui32KCCBCmdsExecuted; - } - } - - /* - Interrupt counts check... - */ - if (bCheckAfterTimePassed && psFwOsData != NULL) - { - IMG_UINT32 ui32LISRCount = 0; - IMG_UINT32 ui32FWCount = 0; - IMG_UINT32 ui32MissingInts = 0; - - /* Add up the total number of interrupts issued, sampled/received and missed... */ -#if defined(RGX_FW_IRQ_OS_COUNTERS) - /* Only the Host OS has a sample count, so only one counter to check. */ - ui32LISRCount += psDevInfo->aui32SampleIRQCount[RGXFW_HOST_OS]; - ui32FWCount += OSReadHWReg32(psDevInfo->pvRegsBaseKM, gaui32FwOsIrqCntRegAddr[RGXFW_HOST_OS]); -#else - IMG_UINT32 ui32Index; - - for (ui32Index = 0; ui32Index < RGXFW_THREAD_NUM; ui32Index++) - { - ui32LISRCount += psDevInfo->aui32SampleIRQCount[ui32Index]; - ui32FWCount += psFwOsData->aui32InterruptCount[ui32Index]; - } -#endif /* RGX_FW_IRQ_OS_COUNTERS */ - - if (ui32LISRCount < ui32FWCount) - { - ui32MissingInts = (ui32FWCount-ui32LISRCount); - } - - if (ui32LISRCount == psDevInfo->ui32InterruptCountLastTime && - ui32MissingInts >= psDevInfo->ui32MissingInterruptsLastTime && - psDevInfo->ui32MissingInterruptsLastTime > 1) - { - PVR_DPF((PVR_DBG_ERROR, "%s: LISR has not received the last %d interrupts", - __func__, ui32MissingInts)); - eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING; - eNewReason = PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS; - - /* Schedule the MISRs to help mitigate the problems of missing interrupts. */ - OSScheduleMISR(psDevInfo->pvMISRData); - if (psDevInfo->pvAPMISRData != NULL) - { - OSScheduleMISR(psDevInfo->pvAPMISRData); - } - } - psDevInfo->ui32InterruptCountLastTime = ui32LISRCount; - psDevInfo->ui32MissingInterruptsLastTime = ui32MissingInts; - } - - /* - Stalled CCB check... - */ - if (bCheckAfterTimePassed && (PVRSRV_DEVICE_HEALTH_STATUS_OK==eNewStatus)) - { - RGXCheckForStalledClientContexts(psDevInfo, IMG_FALSE); - } - - /* Notify client driver and system layer of any eNewStatus errors */ - if (eNewStatus > PVRSRV_DEVICE_HEALTH_STATUS_OK) - { - /* Client notification of device error will be achieved by - * clients calling UM function RGXGetLastDeviceError() */ - psDevInfo->eLastDeviceError = RGX_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR; - - /* Notify system layer */ - { - PVRSRV_DEVICE_NODE *psDevNode = psDevInfo->psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - - if (psDevConfig->pfnSysDevErrorNotify) - { - PVRSRV_ROBUSTNESS_NOTIFY_DATA sErrorData = {0}; - - sErrorData.eResetReason = RGX_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR; - sErrorData.uErrData.sHostWdgData.ui32Status = (IMG_UINT32)eNewStatus; - sErrorData.uErrData.sHostWdgData.ui32Reason = (IMG_UINT32)eNewReason; - - psDevConfig->pfnSysDevErrorNotify(psDevConfig, - &sErrorData); - } - } - } - - /* - Finished, save the new status... - */ -_RGXUpdateHealthStatus_Exit: - OSAtomicWrite(&psDevNode->eHealthStatus, eNewStatus); - OSAtomicWrite(&psDevNode->eHealthReason, eNewReason); - RGXSRV_HWPERF_DEVICE_INFO(psDevInfo, RGX_HWPERF_DEV_INFO_EV_HEALTH, eNewStatus, eNewReason); - - /* - * Attempt to service the HWPerf buffer to regularly transport idle/periodic - * packets to host buffer. - */ - if (psDevNode->pfnServiceHWPerf != NULL) - { - PVRSRV_ERROR eError = psDevNode->pfnServiceHWPerf(psDevNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: " - "Error occurred when servicing HWPerf buffer (%d)", - __func__, eError)); - } - } - - /* Attempt to refresh timer correlation data */ - RGXTimeCorrRestartPeriodic(psDevNode); - - return PVRSRV_OK; -} /* RGXUpdateHealthStatus */ - -#if defined(SUPPORT_AUTOVZ) -void RGXUpdateAutoVzWdgToken(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - if (likely(KM_FW_CONNECTION_IS(ACTIVE, psDevInfo) && KM_OS_CONNECTION_IS(ACTIVE, psDevInfo))) - { - /* read and write back the alive token value to confirm to the - * virtualisation watchdog that this connection is healthy */ - KM_SET_OS_ALIVE_TOKEN(KM_GET_FW_ALIVE_TOKEN(psDevInfo), psDevInfo); - } -} - -/* - RGXUpdateAutoVzWatchdog -*/ -void RGXUpdateAutoVzWatchdog(PVRSRV_DEVICE_NODE* psDevNode) -{ - if (likely(psDevNode != NULL)) - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice; - - if (unlikely((psDevInfo == NULL || !psDevInfo->bFirmwareInitialised || !psDevInfo->bRGXPowered || - psDevInfo->pvRegsBaseKM == NULL || psDevNode->eDevState == PVRSRV_DEVICE_STATE_DEINIT))) - { - /* If the firmware is not initialised, stop here */ - return; - } - else - { - PVRSRV_ERROR eError = PVRSRVPowerLock(psDevNode); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "PVRSRVPowerLock"); - - RGXUpdateAutoVzWdgToken(psDevInfo); - PVRSRVPowerUnlock(psDevNode); - } - } -} -#endif /* SUPPORT_AUTOVZ */ - -PVRSRV_ERROR CheckStalledClientCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext, RGX_KICK_TYPE_DM eKickTypeDM) -{ - if (psCurrentServerCommonContext == NULL) - { - /* the context has already been freed so there is nothing to do here */ - return PVRSRV_OK; - } - - return CheckForStalledCCB(psCurrentServerCommonContext->psDevInfo->psDeviceNode, - psCurrentServerCommonContext->psClientCCB, - eKickTypeDM); -} - -void DumpFWCommonContextInfo(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - if (psCurrentServerCommonContext == NULL) - { - /* the context has already been freed so there is nothing to do here */ - return; - } - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH)) - { - /* If high verbosity requested, dump whole CCB */ - DumpCCB(psCurrentServerCommonContext->psDevInfo, - psCurrentServerCommonContext->sFWCommonContextFWAddr, - psCurrentServerCommonContext->psClientCCB, - pfnDumpDebugPrintf, - pvDumpDebugFile); - } - else - { - /* Otherwise, only dump first stalled command in the CCB */ - DumpStalledCCBCommand(psCurrentServerCommonContext->sFWCommonContextFWAddr, - psCurrentServerCommonContext->psClientCCB, - pfnDumpDebugPrintf, - pvDumpDebugFile); - } -} - -PVRSRV_ERROR AttachKickResourcesCleanupCtls(PRGXFWIF_CLEANUP_CTL *apsCleanupCtl, - IMG_UINT32 *pui32NumCleanupCtl, - RGXFWIF_DM eDM, - IMG_BOOL bKick, - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet, - RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_ZSBUFFER_DATA *psMSAAScratchBuffer) -{ - PVRSRV_ERROR eError; - PRGXFWIF_CLEANUP_CTL *psCleanupCtlWrite = apsCleanupCtl; - - PVR_ASSERT((eDM == RGXFWIF_DM_GEOM) || (eDM == RGXFWIF_DM_3D)); - PVR_RETURN_IF_INVALID_PARAM((eDM == RGXFWIF_DM_GEOM) || (eDM == RGXFWIF_DM_3D)); - - if (bKick) - { - if (psKMHWRTDataSet) - { - PRGXFWIF_CLEANUP_CTL psCleanupCtl; - - eError = RGXSetFirmwareAddress(&psCleanupCtl, psKMHWRTDataSet->psHWRTDataFwMemDesc, - offsetof(RGXFWIF_HWRTDATA, sCleanupState), - RFW_FWADDR_NOREF_FLAG); - PVR_RETURN_IF_ERROR(eError); - - *(psCleanupCtlWrite++) = psCleanupCtl; - } - - if (eDM == RGXFWIF_DM_3D) - { - RGXFWIF_PRBUFFER_TYPE eBufferType; - RGX_ZSBUFFER_DATA *psBuffer = NULL; - - for (eBufferType = RGXFWIF_PRBUFFER_START; eBufferType < RGXFWIF_PRBUFFER_MAXSUPPORTED; eBufferType++) - { - switch (eBufferType) - { - case RGXFWIF_PRBUFFER_ZSBUFFER: - psBuffer = psZSBuffer; - break; - case RGXFWIF_PRBUFFER_MSAABUFFER: - psBuffer = psMSAAScratchBuffer; - break; - case RGXFWIF_PRBUFFER_MAXSUPPORTED: - psBuffer = NULL; - break; - } - if (psBuffer) - { - (psCleanupCtlWrite++)->ui32Addr = psBuffer->sZSBufferFWDevVAddr.ui32Addr + - offsetof(RGXFWIF_PRBUFFER, sCleanupState); - psBuffer = NULL; - } - } - } - } - - *pui32NumCleanupCtl = psCleanupCtlWrite - apsCleanupCtl; - PVR_ASSERT(*pui32NumCleanupCtl <= RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS); - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXResetHWRLogs(PVRSRV_DEVICE_NODE *psDevNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - RGXFWIF_HWRINFOBUF *psHWRInfoBuf; - IMG_UINT32 i; - - if (psDevNode->pvDevice == NULL) - { - return PVRSRV_ERROR_INVALID_DEVINFO; - } - psDevInfo = psDevNode->pvDevice; - - psHWRInfoBuf = psDevInfo->psRGXFWIfHWRInfoBufCtl; - - for (i = 0 ; i < RGXFWIF_DM_MAX ; i++) - { - /* Reset the HWR numbers */ - psHWRInfoBuf->aui32HwrDmLockedUpCount[i] = 0; - psHWRInfoBuf->aui32HwrDmFalseDetectCount[i] = 0; - psHWRInfoBuf->aui32HwrDmRecoveredCount[i] = 0; - psHWRInfoBuf->aui32HwrDmOverranCount[i] = 0; - } - - for (i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++) - { - psHWRInfoBuf->sHWRInfo[i].ui32HWRNumber = 0; - } - - psHWRInfoBuf->ui32WriteIndex = 0; - psHWRInfoBuf->ui32DDReqCount = 0; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXGetPhyAddr(PMR *psPMR, - IMG_DEV_PHYADDR *psPhyAddr, - IMG_UINT32 ui32LogicalOffset, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_BOOL *bValid) -{ - - PVRSRV_ERROR eError; - - eError = PMRLockSysPhysAddresses(psPMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: PMRLockSysPhysAddresses failed (%u)", - __func__, - eError)); - return eError; - } - - eError = PMR_DevPhysAddr(psPMR, - ui32Log2PageSize, - ui32NumOfPages, - ui32LogicalOffset, - psPhyAddr, - bValid); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: PMR_DevPhysAddr failed (%u)", - __func__, - eError)); - return eError; - } - - - eError = PMRUnlockSysPhysAddresses(psPMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: PMRUnLockSysPhysAddresses failed (%u)", - __func__, - eError)); - return eError; - } - - return eError; -} - -#if defined(PDUMP) -PVRSRV_ERROR RGXPdumpDrainKCCB(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32WriteOffset) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psDevInfo->bDumpedKCCBCtlAlready) - { - /* exiting capture range or pdump block */ - psDevInfo->bDumpedKCCBCtlAlready = IMG_FALSE; - - /* make sure previous cmd is drained in pdump in case we will 'jump' over some future cmds */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER, - "kCCB(%p): Draining rgxfw_roff (0x%x) == woff (0x%x)", - psDevInfo->psKernelCCBCtl, - ui32WriteOffset, - ui32WriteOffset); - eError = DevmemPDumpDevmemPol32(psDevInfo->psKernelCCBCtlMemDesc, - offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset), - ui32WriteOffset, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: problem pdumping POL for kCCBCtl (%d)", __func__, eError)); - } - } - - return eError; - -} -#endif - -/*! -******************************************************************************* - - @Function RGXClientConnectCompatCheck_ClientAgainstFW - - @Description - - Check compatibility of client and firmware (build options) - at the connection time. - - @Input psDeviceNode - device node - @Input ui32ClientBuildOptions - build options for the client - - @Return PVRSRV_ERROR - depending on mismatch found - -******************************************************************************/ -PVRSRV_ERROR RGXClientConnectCompatCheck_ClientAgainstFW(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32ClientBuildOptions) -{ -#if !defined(NO_HARDWARE) || defined(PDUMP) -#if !defined(NO_HARDWARE) - IMG_UINT32 ui32BuildOptionsMismatch; - IMG_UINT32 ui32BuildOptionsFW; -#endif - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -#endif - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - -#if !defined(NO_HARDWARE) - if (psDevInfo == NULL || psDevInfo->psRGXFWIfOsInitMemDesc == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Cannot acquire kernel fw compatibility check info, RGXFWIF_OSINIT structure not allocated.", - __func__)); - return PVRSRV_ERROR_NOT_INITIALISED; - } - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if (*((volatile IMG_BOOL *) &psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated)) - { - /* No need to wait if the FW has already updated the values */ - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); -#endif - -#if defined(PDUMP) - { - PVRSRV_ERROR eError; - - PDUMPCOMMENT(psDeviceNode, "Compatibility check: client and FW build options"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, ui32BuildOptions), - ui32ClientBuildOptions, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", - __func__, - eError)); - return eError; - } - } -#endif - -#if !defined(NO_HARDWARE) - ui32BuildOptionsFW = psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.ui32BuildOptions; - ui32BuildOptionsMismatch = ui32ClientBuildOptions ^ ui32BuildOptionsFW; - - if (ui32BuildOptionsMismatch != 0) - { - if ((ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; " - "extra options present in client: (0x%x). Please check rgx_options.h", - ui32ClientBuildOptions & ui32BuildOptionsMismatch )); - } - - if ((ui32BuildOptionsFW & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; " - "extra options present in Firmware: (0x%x). Please check rgx_options.h", - ui32BuildOptionsFW & ui32BuildOptionsMismatch )); - } - - return PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware and client build options match. [ OK ]", __func__)); - } -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RGXFwRawHeapAllocMap - - @Description Register firmware heap for the specified guest OSID - - @Input psDeviceNode - device node - @Input ui32OSID - Guest OSID - @Input sDevPAddr - Heap address - @Input ui64DevPSize - Heap size - - @Return PVRSRV_ERROR - PVRSRV_OK if heap setup was successful. - -******************************************************************************/ -PVRSRV_ERROR RGXFwRawHeapAllocMap(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSID, - IMG_DEV_PHYADDR sDevPAddr, - IMG_UINT64 ui64DevPSize) -{ - PVRSRV_ERROR eError; - IMG_CHAR szRegionRAName[RA_MAX_NAME_LENGTH]; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_MEMALLOCFLAGS_T uiRawFwHeapAllocFlags = (RGX_FWSHAREDMEM_GPU_ONLY_ALLOCFLAGS | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_PREMAP0 + ui32OSID)); - PHYS_HEAP_CONFIG *psFwMainConfig = FindPhysHeapConfig(psDeviceNode->psDevConfig, - PHYS_HEAP_USAGE_FW_MAIN); - PHYS_HEAP_CONFIG sFwHeapConfig; - - PVRSRV_VZ_RET_IF_NOT_MODE(HOST, PVRSRV_OK); - - if (psFwMainConfig == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "FW_MAIN heap config not found.")); - return PVRSRV_ERROR_NOT_SUPPORTED; - } - - OSSNPrintf(szRegionRAName, sizeof(szRegionRAName), RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT, ui32OSID); - - if (!ui64DevPSize || - !sDevPAddr.uiAddr || - ui32OSID >= RGX_NUM_OS_SUPPORTED || - ui64DevPSize != RGX_FIRMWARE_RAW_HEAP_SIZE) - { - PVR_DPF((PVR_DBG_ERROR, "Invalid parameters for %s", szRegionRAName)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - sFwHeapConfig = *psFwMainConfig; - sFwHeapConfig.sStartAddr.uiAddr = 0; - sFwHeapConfig.sCardBase.uiAddr = sDevPAddr.uiAddr; - sFwHeapConfig.uiSize = RGX_FIRMWARE_RAW_HEAP_SIZE; - sFwHeapConfig.eType = PHYS_HEAP_TYPE_LMA; - - eError = PhysmemCreateHeapLMA(psDeviceNode, &sFwHeapConfig, szRegionRAName, &psDeviceNode->apsFWPremapPhysHeap[ui32OSID]); - PVR_LOG_RETURN_IF_ERROR_VA(eError, "PhysmemCreateHeapLMA:PREMAP [%d]", ui32OSID); - - eError = PhysHeapAcquire(psDeviceNode->apsFWPremapPhysHeap[ui32OSID]); - PVR_LOG_RETURN_IF_ERROR_VA(eError, "PhysHeapAcquire:PREMAP [%d]", ui32OSID); - - psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_PREMAP0 + ui32OSID] = psDeviceNode->apsFWPremapPhysHeap[ui32OSID]; - - PDUMPCOMMENT(psDeviceNode, "Allocate and map raw firmware heap for OSID: [%d]", ui32OSID); - -#if (RGX_NUM_OS_SUPPORTED > 1) - /* don't clear the heap of other guests on allocation */ - uiRawFwHeapAllocFlags &= (ui32OSID > RGXFW_HOST_OS) ? (~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) : (~0ULL); -#endif - - /* if the firmware is already powered up, consider the firmware heaps are pre-mapped. */ - if (psDeviceNode->bAutoVzFwIsUp) - { - uiRawFwHeapAllocFlags &= RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp); - DevmemHeapSetPremapStatus(psDevInfo->psGuestFirmwareRawHeap[ui32OSID], IMG_TRUE); - } - - eError = DevmemFwAllocate(psDevInfo, - RGX_FIRMWARE_RAW_HEAP_SIZE, - uiRawFwHeapAllocFlags, - psDevInfo->psGuestFirmwareRawHeap[ui32OSID]->pszName, - &psDevInfo->psGuestFirmwareRawMemDesc[ui32OSID]); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemFwAllocate"); - - /* Mark this devmem heap as premapped so allocations will not require device mapping. */ - DevmemHeapSetPremapStatus(psDevInfo->psGuestFirmwareRawHeap[ui32OSID], IMG_TRUE); - - if (ui32OSID == RGXFW_HOST_OS) - { - /* if the Host's raw fw heap is premapped, mark its main & config sub-heaps accordingly - * No memory allocated from these sub-heaps will be individually mapped into the device's - * address space so they can remain marked permanently as premapped. */ - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareMainHeap, IMG_TRUE); - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareConfigHeap, IMG_TRUE); - } - - return eError; -} - -/*! -******************************************************************************* - - @Function RGXFwRawHeapUnmapFree - - @Description Unregister firmware heap for the specified guest OSID - - @Input psDeviceNode - device node - @Input ui32OSID - Guest OSID - -******************************************************************************/ -void RGXFwRawHeapUnmapFree(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSID) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* remove the premap status, so the heap can be unmapped and freed */ - if (psDevInfo->psGuestFirmwareRawHeap[ui32OSID]) - { - DevmemHeapSetPremapStatus(psDevInfo->psGuestFirmwareRawHeap[ui32OSID], IMG_FALSE); - } - - if (psDevInfo->psGuestFirmwareRawMemDesc[ui32OSID]) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psGuestFirmwareRawMemDesc[ui32OSID]); - psDevInfo->psGuestFirmwareRawMemDesc[ui32OSID] = NULL; - } -} - -/*! -******************************************************************************* -@Function RGXRiscvHalt - -@Description Halt the RISC-V FW core (required for certain operations - done through Debug Module) - -@Input psDevInfo Pointer to device info - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvHalt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS, "Halt RISC-V FW"); - - /* Send halt request (no need to select one or more harts on this RISC-V core) */ - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_HALTREQ_EN | - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until hart is halted */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_DMSTATUS, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - /* Clear halt request */ - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN, - PDUMP_FLAGS_CONTINUOUS); -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Send halt request (no need to select one or more harts on this RISC-V core) */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_HALTREQ_EN | - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN); - - /* Wait until hart is halted */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_DMSTATUS/sizeof(IMG_UINT32), - RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Hart not halted (0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMSTATUS))); - return PVRSRV_ERROR_TIMEOUT; - } - - /* Clear halt request */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN); -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* -@Function RGXRiscvIsHalted - -@Description Check if the RISC-V FW is halted - -@Input psDevInfo Pointer to device info - -@Return IMG_BOOL -******************************************************************************/ -IMG_BOOL RGXRiscvIsHalted(PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if defined(NO_HARDWARE) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - /* Assume the core is always halted in nohw */ - return IMG_TRUE; -#else - - return (OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMSTATUS) & - RGX_CR_FWCORE_DMI_DMSTATUS_ALLHALTED_EN) != 0U; -#endif -} - -/*! -******************************************************************************* -@Function RGXRiscvResume - -@Description Resume the RISC-V FW core - -@Input psDevInfo Pointer to device info - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvResume(PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS, "Resume RISC-V FW"); - - /* Send resume request (no need to select one or more harts on this RISC-V core) */ - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_RESUMEREQ_EN | - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until hart is resumed */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_DMSTATUS, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_EN, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - /* Clear resume request */ - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN, - PDUMP_FLAGS_CONTINUOUS); -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Send resume request (no need to select one or more harts on this RISC-V core) */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_RESUMEREQ_EN | - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN); - - /* Wait until hart is resumed */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_DMSTATUS/sizeof(IMG_UINT32), - RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_EN, - RGX_CR_FWCORE_DMI_DMSTATUS_ALLRESUMEACK_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Hart not resumed (0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMSTATUS))); - return PVRSRV_ERROR_TIMEOUT; - } - - /* Clear resume request */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DMCONTROL, - RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN); -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* -@Function RGXRiscvCheckAbstractCmdError - -@Description Check for RISC-V abstract command errors and clear them - -@Input psDevInfo Pointer to GPU device info - -@Return RGXRISCVFW_ABSTRACT_CMD_ERR -******************************************************************************/ -static RGXRISCVFW_ABSTRACT_CMD_ERR RGXRiscvCheckAbstractCmdError(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXRISCVFW_ABSTRACT_CMD_ERR eCmdErr; - -#if defined(NO_HARDWARE) && defined(PDUMP) - eCmdErr = RISCV_ABSTRACT_CMD_NO_ERROR; - - /* Check error status */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_ABSTRACTCS, - RISCV_ABSTRACT_CMD_NO_ERROR << RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_SHIFT, - ~RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_CLRMSK, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); -#else - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - - /* Check error status */ - eCmdErr = (OSReadHWReg32(pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS) - & ~RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_CLRMSK) - >> RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_SHIFT; - - if (eCmdErr != RISCV_ABSTRACT_CMD_NO_ERROR) - { - PVR_DPF((PVR_DBG_WARNING, "RISC-V FW abstract command error %u", eCmdErr)); - - /* Clear the error (note CMDERR field is write-1-to-clear) */ - OSWriteHWReg32(pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS, - ~RGX_CR_FWCORE_DMI_ABSTRACTCS_CMDERR_CLRMSK); - } -#endif - - return eCmdErr; -} - -/*! -******************************************************************************* -@Function RGXRiscvReadReg - -@Description Read a value from the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvReadReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 *pui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32RegAddr); - PVR_UNREFERENCED_PARAMETER(pui32Value); - - /* Reading HW registers is not supported in nohw/pdump */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Send abstract register read command */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_READ | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT | - ui32RegAddr); - - /* Wait until abstract command is completed */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_ABSTRACTCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Abstract command did not complete in time (abstractcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS))); - return PVRSRV_ERROR_TIMEOUT; - } - - if (RGXRiscvCheckAbstractCmdError(psDevInfo) == RISCV_ABSTRACT_CMD_NO_ERROR) - { - /* Read register value */ - *pui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA0); - } - else - { - *pui32Value = 0U; - } - - return PVRSRV_OK; -#endif -} - -/*! -******************************************************************************* -@Function RGXRiscvPollReg - -@Description Poll for a value from the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvPollReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Poll RISC-V register 0x%x (expected 0x%08x)", - ui32RegAddr, ui32Value); - - /* Send abstract register read command */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_READ | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT | - ui32RegAddr, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until abstract command is completed */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_ABSTRACTCS, - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - RGXRiscvCheckAbstractCmdError(psDevInfo); - - /* Check read value */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_DATA0, - ui32Value, - 0xFFFFFFFF, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - return PVRSRV_OK; -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32RegAddr); - PVR_UNREFERENCED_PARAMETER(ui32Value); - - /* Polling HW registers is currently not required driverlive */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#endif -} - -/*! -******************************************************************************* -@Function RGXRiscvWriteReg - -@Description Write a value to the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvWriteReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Write RISC-V register 0x%x (value 0x%08x)", - ui32RegAddr, ui32Value); - - /* Prepare data to be written to register */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DATA0, - ui32Value, PDUMP_FLAGS_CONTINUOUS); - - /* Send abstract register write command */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_WRITE | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT | - ui32RegAddr, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until abstract command is completed */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_ABSTRACTCS, - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Prepare data to be written to register */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA0, ui32Value); - - /* Send abstract register write command */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_WRITE | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT | - ui32RegAddr); - - /* Wait until abstract command is completed */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_ABSTRACTCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Abstract command did not complete in time (abstractcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS))); - return PVRSRV_ERROR_TIMEOUT; - } -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* -@Function RGXRiscvCheckSysBusError - -@Description Check for RISC-V system bus errors and clear them - -@Input psDevInfo Pointer to GPU device info - -@Return RGXRISCVFW_SYSBUS_ERR -******************************************************************************/ -static __maybe_unused RGXRISCVFW_SYSBUS_ERR RGXRiscvCheckSysBusError(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXRISCVFW_SYSBUS_ERR eSBError; - -#if defined(NO_HARDWARE) && defined(PDUMP) - eSBError = RISCV_SYSBUS_NO_ERROR; - - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_SBCS, - RISCV_SYSBUS_NO_ERROR << RGX_CR_FWCORE_DMI_SBCS_SBERROR_SHIFT, - ~RGX_CR_FWCORE_DMI_SBCS_SBERROR_CLRMSK, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); -#else - void __iomem *pvRegsBaseKM = psDevInfo->pvRegsBaseKM; - - eSBError = (OSReadHWReg32(pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBCS) - & ~RGX_CR_FWCORE_DMI_SBCS_SBERROR_CLRMSK) - >> RGX_CR_FWCORE_DMI_SBCS_SBERROR_SHIFT; - - if (eSBError != RISCV_SYSBUS_NO_ERROR) - { - PVR_DPF((PVR_DBG_WARNING, "RISC-V FW system bus error %u", eSBError)); - - /* Clear the error (note SBERROR field is write-1-to-clear) */ - OSWriteHWReg32(pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBCS, - ~RGX_CR_FWCORE_DMI_SBCS_SBERROR_CLRMSK); - } -#endif - - return eSBError; -} - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) -/*! -******************************************************************************* -@Function RGXRiscvReadAbstractMem - -@Description Read a value at the given address in RISC-V memory space - using RISC-V abstract memory commands - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvReadAbstractMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 *pui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32Addr); - PVR_UNREFERENCED_PARAMETER(pui32Value); - - /* Reading memory is not supported in nohw/pdump */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Prepare read address */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA1, ui32Addr); - - /* Send abstract memory read command */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_READ | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT); - - /* Wait until abstract command is completed */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_ABSTRACTCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Abstract command did not complete in time (abstractcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS))); - return PVRSRV_ERROR_TIMEOUT; - } - - if (RGXRiscvCheckAbstractCmdError(psDevInfo) == RISCV_ABSTRACT_CMD_NO_ERROR) - { - /* Read memory value */ - *pui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA0); - } - else - { - *pui32Value = 0U; - } - - return PVRSRV_OK; -#endif -} -#endif /* !defined(EMULATOR) */ - -/*! -******************************************************************************* -@Function RGXRiscvPollAbstractMem - -@Description Poll for a value at the given address in RISC-V memory space - using RISC-V abstract memory commands - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvPollAbstractMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Poll RISC-V address 0x%x (expected 0x%08x)", - ui32Addr, ui32Value); - - /* Prepare read address */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DATA1, - ui32Addr, PDUMP_FLAGS_CONTINUOUS); - - /* Send abstract memory read command */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_READ | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until abstract command is completed */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_ABSTRACTCS, - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - RGXRiscvCheckAbstractCmdError(psDevInfo); - - /* Check read value */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_DATA0, - ui32Value, - 0xFFFFFFFF, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - return PVRSRV_OK; -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32Addr); - PVR_UNREFERENCED_PARAMETER(ui32Value); - - /* Polling memory is currently not required driverlive */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#endif -} - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) -/*! -******************************************************************************* -@Function RGXRiscvReadSysBusMem - -@Description Read a value at the given address in RISC-V memory space - using the RISC-V system bus - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvReadSysBusMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 *pui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32Addr); - PVR_UNREFERENCED_PARAMETER(pui32Value); - - /* Reading memory is not supported in nohw/pdump */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Configure system bus to read 32 bit every time a new address is provided */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_SBCS, - (RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT << RGX_CR_FWCORE_DMI_SBCS_SBACCESS_SHIFT) | - RGX_CR_FWCORE_DMI_SBCS_SBREADONADDR_EN); - - /* Perform read */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBADDRESS0, ui32Addr); - - /* Wait until system bus is idle */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_SBCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_SBCS_SBBUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: System Bus did not go idle in time (sbcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBCS))); - return PVRSRV_ERROR_TIMEOUT; - } - - if (RGXRiscvCheckSysBusError(psDevInfo) == RISCV_SYSBUS_NO_ERROR) - { - /* Read value from debug system bus */ - *pui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBDATA0); - } - else - { - *pui32Value = 0U; - } - - return PVRSRV_OK; -#endif -} -#endif /* !defined(EMULATOR) */ - -/*! -******************************************************************************* -@Function RGXRiscvPollSysBusMem - -@Description Poll for a value at the given address in RISC-V memory space - using the RISC-V system bus - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvPollSysBusMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Poll RISC-V address 0x%x (expected 0x%08x)", - ui32Addr, ui32Value); - - /* Configure system bus to read 32 bit every time a new address is provided */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_SBCS, - (RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT << RGX_CR_FWCORE_DMI_SBCS_SBACCESS_SHIFT) | - RGX_CR_FWCORE_DMI_SBCS_SBREADONADDR_EN, - PDUMP_FLAGS_CONTINUOUS); - - /* Perform read */ - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_SBADDRESS0, - ui32Addr, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until system bus is idle */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_SBCS, - 0U, - RGX_CR_FWCORE_DMI_SBCS_SBBUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - RGXRiscvCheckSysBusError(psDevInfo); - - /* Check read value */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_SBDATA0, - ui32Value, - 0xFFFFFFFF, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); - - return PVRSRV_OK; -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(ui32Addr); - PVR_UNREFERENCED_PARAMETER(ui32Value); - - /* Polling memory is currently not required driverlive */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#endif -} - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) -/*! -******************************************************************************* -@Function RGXRiscvReadMem - -@Description Read a value at the given address in RISC-V memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXRiscvReadMem(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Addr, - IMG_UINT32 *pui32Value) -{ - if (ui32Addr >= RGXRISCVFW_COREMEM_BASE && ui32Addr <= RGXRISCVFW_COREMEM_END) - { - return RGXRiscvReadAbstractMem(psDevInfo, ui32Addr, pui32Value); - } - - return RGXRiscvReadSysBusMem(psDevInfo, ui32Addr, pui32Value); -} -#endif /* !defined(EMULATOR) */ - -/*! -******************************************************************************* -@Function RGXRiscvPollMem - -@Description Poll a value at the given address in RISC-V memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvPollMem(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Addr, - IMG_UINT32 ui32Value) -{ - if (ui32Addr >= RGXRISCVFW_COREMEM_BASE && ui32Addr <= RGXRISCVFW_COREMEM_END) - { - return RGXRiscvPollAbstractMem(psDevInfo, ui32Addr, ui32Value); - } - - return RGXRiscvPollSysBusMem(psDevInfo, ui32Addr, ui32Value); -} - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) -/*! -******************************************************************************* -@Function RGXRiscvWriteAbstractMem - -@Description Write a value at the given address in RISC-V memory space - using RISC-V abstract memory commands - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvWriteAbstractMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Write RISC-V address 0x%x (value 0x%08x)", - ui32Addr, ui32Value); - - /* Prepare write address */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DATA1, - ui32Addr, PDUMP_FLAGS_CONTINUOUS); - - /* Prepare write data */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_DATA0, - ui32Value, PDUMP_FLAGS_CONTINUOUS); - - /* Send abstract register write command */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_WRITE | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT, - PDUMP_FLAGS_CONTINUOUS); - - /* Wait until abstract command is completed */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_ABSTRACTCS, - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Prepare write address */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA1, ui32Addr); - - /* Prepare write data */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_DATA0, ui32Value); - - /* Send abstract memory write command */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_COMMAND, - (RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY << RGX_CR_FWCORE_DMI_COMMAND_CMDTYPE_SHIFT) | - RGXRISCVFW_DMI_COMMAND_WRITE | - RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT); - - /* Wait until abstract command is completed */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_ABSTRACTCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_ABSTRACTCS_BUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Abstract command did not complete in time (abstractcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_ABSTRACTCS))); - return PVRSRV_ERROR_TIMEOUT; - } -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* -@Function RGXRiscvWriteSysBusMem - -@Description Write a value at the given address in RISC-V memory space - using the RISC-V system bus - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -RGXRiscvWriteSysBusMem(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Addr, IMG_UINT32 ui32Value) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Write RISC-V address 0x%x (value 0x%08x)", - ui32Addr, ui32Value); - - /* Configure system bus to read 32 bit every time a new address is provided */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_SBCS, - RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT << RGX_CR_FWCORE_DMI_SBCS_SBACCESS_SHIFT, - PDUMP_FLAGS_CONTINUOUS); - - /* Prepare write address */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_SBADDRESS0, - ui32Addr, PDUMP_FLAGS_CONTINUOUS); - - /* Prepare write data and initiate write */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_FWCORE_DMI_SBDATA0, - ui32Value, PDUMP_FLAGS_CONTINUOUS); - - /* Wait until system bus is idle */ - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_FWCORE_DMI_SBCS, - 0U, - RGX_CR_FWCORE_DMI_SBCS_SBBUSY_EN, - PDUMP_FLAGS_CONTINUOUS, - PDUMP_POLL_OPERATOR_EQUAL); -#else - IMG_UINT32 __iomem *pui32RegsBase = psDevInfo->pvRegsBaseKM; - - /* Configure system bus for 32 bit accesses */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - RGX_CR_FWCORE_DMI_SBCS, - RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT << RGX_CR_FWCORE_DMI_SBCS_SBACCESS_SHIFT); - - /* Prepare write address */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBADDRESS0, ui32Addr); - - /* Prepare write data and initiate write */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBDATA0, ui32Value); - - /* Wait until system bus is idle */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - pui32RegsBase + RGX_CR_FWCORE_DMI_SBCS/sizeof(IMG_UINT32), - 0U, - RGX_CR_FWCORE_DMI_SBCS_SBBUSY_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: System Bus did not go idle in time (sbcs = 0x%x)", - __func__, OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FWCORE_DMI_SBCS))); - return PVRSRV_ERROR_TIMEOUT; - } -#endif - - return PVRSRV_OK; -} - -/*! -******************************************************************************* -@Function RGXRiscvWriteMem - -@Description Write a value to the given address in RISC-V memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXRiscvWriteMem(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Addr, - IMG_UINT32 ui32Value) -{ - if (ui32Addr >= RGXRISCVFW_COREMEM_BASE && ui32Addr <= RGXRISCVFW_COREMEM_END) - { - return RGXRiscvWriteAbstractMem(psDevInfo, ui32Addr, ui32Value); - } - - return RGXRiscvWriteSysBusMem(psDevInfo, ui32Addr, ui32Value); -} -#endif /* !defined(EMULATOR) */ - -/*! -******************************************************************************* -@Function RGXRiscvDmiOp - -@Description Acquire the powerlock and perform an operation on the RISC-V - Debug Module Interface, but only if the GPU is powered on. - -@Input psDevInfo Pointer to device info -@InOut pui64DMI Encoding of a request for the RISC-V Debug - Module with same format as the 'dmi' register - from the RISC-V debug specification (v0.13+). - On return, this is updated with the result of - the request, encoded the same way. - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvDmiOp(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 *pui64DMI) -{ -#if defined(NO_HARDWARE) && defined(PDUMP) - PVR_UNREFERENCED_PARAMETER(psDevInfo); - PVR_UNREFERENCED_PARAMETER(pui64DMI); - - /* Accessing DM registers is not supported in nohw/pdump */ - return PVRSRV_ERROR_NOT_SUPPORTED; -#else -#define DMI_BASE RGX_CR_FWCORE_DMI_RESERVED00 -#define DMI_STRIDE (RGX_CR_FWCORE_DMI_RESERVED01 - RGX_CR_FWCORE_DMI_RESERVED00) -#define DMI_REG(r) ((DMI_BASE) + (DMI_STRIDE) * (r)) - -#define DMI_OP_SHIFT 0U -#define DMI_OP_MASK 0x3ULL -#define DMI_DATA_SHIFT 2U -#define DMI_DATA_MASK 0x3FFFFFFFCULL -#define DMI_ADDRESS_SHIFT 34U -#define DMI_ADDRESS_MASK 0xFC00000000ULL - -#define DMI_OP_NOP 0U -#define DMI_OP_READ 1U -#define DMI_OP_WRITE 2U -#define DMI_OP_RESERVED 3U - -#define DMI_OP_STATUS_SUCCESS 0U -#define DMI_OP_STATUS_RESERVED 1U -#define DMI_OP_STATUS_FAILED 2U -#define DMI_OP_STATUS_BUSY 3U - - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - PVRSRV_DEV_POWER_STATE ePowerState; - PVRSRV_ERROR eError; - IMG_UINT64 ui64Op, ui64Address, ui64Data; - - ui64Op = (*pui64DMI & DMI_OP_MASK) >> DMI_OP_SHIFT; - ui64Address = (*pui64DMI & DMI_ADDRESS_MASK) >> DMI_ADDRESS_SHIFT; - ui64Data = (*pui64DMI & DMI_DATA_MASK) >> DMI_DATA_SHIFT; - - eError = PVRSRVPowerLock(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to acquire powerlock (%s)", - __func__, PVRSRVGetErrorString(eError))); - ui64Op = DMI_OP_STATUS_FAILED; - goto dmiop_update; - } - - eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to retrieve RGX power state (%s)", - __func__, PVRSRVGetErrorString(eError))); - ui64Op = DMI_OP_STATUS_FAILED; - goto dmiop_release_lock; - } - - if (ePowerState == PVRSRV_DEV_POWER_STATE_ON) - { - switch (ui64Op) - { - case DMI_OP_NOP: - ui64Op = DMI_OP_STATUS_SUCCESS; - break; - case DMI_OP_WRITE: - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, - DMI_REG(ui64Address), - (IMG_UINT32)ui64Data); - ui64Op = DMI_OP_STATUS_SUCCESS; - break; - case DMI_OP_READ: - ui64Data = (IMG_UINT64)OSReadHWReg32(psDevInfo->pvRegsBaseKM, - DMI_REG(ui64Address)); - ui64Op = DMI_OP_STATUS_SUCCESS; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: unknown op %u", __func__, (IMG_UINT32)ui64Op)); - ui64Op = DMI_OP_STATUS_FAILED; - break; - } - } - else - { - PVR_DPF((PVR_DBG_WARNING, "%s: Accessing RISC-V Debug Module is not " - "possible while the GPU is powered off", __func__)); - - ui64Op = DMI_OP_STATUS_FAILED; - } - -dmiop_release_lock: - PVRSRVPowerUnlock(psDeviceNode); - -dmiop_update: - *pui64DMI = (ui64Op << DMI_OP_SHIFT) | - (ui64Address << DMI_ADDRESS_SHIFT) | - (ui64Data << DMI_DATA_SHIFT); - - return eError; -#endif -} - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -/* - RGXReadMETAAddr -*/ -static PVRSRV_ERROR RGXReadMETAAddr(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32METAAddr, IMG_UINT32 *pui32Value) -{ - IMG_UINT8 __iomem *pui8RegBase = psDevInfo->pvRegsBaseKM; - IMG_UINT32 ui32Value; - - /* Wait for Slave Port to be Ready */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1), - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - /* Issue the Read */ - OSWriteHWReg32( - psDevInfo->pvRegsBaseKM, - RGX_CR_META_SP_MSLVCTRL0, - ui32METAAddr | RGX_CR_META_SP_MSLVCTRL0_RD_EN); - (void) OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL0); - - /* Wait for Slave Port to be Ready: read complete */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1), - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - /* Read the value */ - ui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVDATAX); - - *pui32Value = ui32Value; - - return PVRSRV_OK; -} - -/* - RGXWriteMETAAddr -*/ -static PVRSRV_ERROR RGXWriteMETAAddr(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32METAAddr, IMG_UINT32 ui32Value) -{ - IMG_UINT8 __iomem *pui8RegBase = psDevInfo->pvRegsBaseKM; - - /* Wait for Slave Port to be Ready */ - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *)(pui8RegBase + RGX_CR_META_SP_MSLVCTRL1), - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - return PVRSRV_ERROR_TIMEOUT; - } - - /* Issue the Write */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL0, ui32METAAddr); - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVDATAT, ui32Value); - - return PVRSRV_OK; -} -#endif - -PVRSRV_ERROR RGXReadFWModuleAddr(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32FWAddr, IMG_UINT32 *pui32Value) -{ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - return RGXReadMETAAddr(psDevInfo, ui32FWAddr, pui32Value); - } -#endif - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - return RGXRiscvReadMem(psDevInfo, ui32FWAddr, pui32Value); - } -#endif - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR RGXWriteFWModuleAddr(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32FWAddr, IMG_UINT32 ui32Value) -{ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - return RGXWriteMETAAddr(psDevInfo, ui32FWAddr, ui32Value); - } -#endif - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - return RGXRiscvWriteMem(psDevInfo, ui32FWAddr, ui32Value); - } -#endif - - return PVRSRV_ERROR_NOT_SUPPORTED; -} - -PVRSRV_ERROR RGXGetFwMapping(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FwVA, - IMG_CPU_PHYADDR *psCpuPA, - IMG_DEV_PHYADDR *psDevPA, - IMG_UINT64 *pui64RawPTE) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_CPU_PHYADDR sCpuPA = {0U}; - IMG_DEV_PHYADDR sDevPA = {0U}; - IMG_UINT64 ui64RawPTE = 0U; - MMU_FAULT_DATA sFaultData = {0U}; - MMU_CONTEXT *psFwMMUCtx = psDevInfo->psKernelMMUCtx; - IMG_UINT32 ui32FwHeapBase = (IMG_UINT32) (RGX_FIRMWARE_RAW_HEAP_BASE & UINT_MAX); - IMG_UINT32 ui32FwHeapEnd = ui32FwHeapBase + (RGX_NUM_OS_SUPPORTED * RGX_FIRMWARE_RAW_HEAP_SIZE); - IMG_UINT32 ui32OSID = (ui32FwVA - ui32FwHeapBase) / RGX_FIRMWARE_RAW_HEAP_SIZE; - IMG_UINT32 ui32HeapId; - PHYS_HEAP *psPhysHeap; - - /* MIPS uses the same page size as the OS, while others default to 4K pages */ - IMG_UINT32 ui32FwPageSize = RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) ? - OSGetPageSize() : BIT(RGX_MMUCTRL_PAGE_4KB_RANGE_SHIFT); - IMG_UINT32 ui32PageOffset = (ui32FwVA & (ui32FwPageSize - 1)); - - PVR_LOG_GOTO_IF_INVALID_PARAM((ui32OSID < RGX_NUM_OS_SUPPORTED), - eError, ErrorExit); - - PVR_LOG_GOTO_IF_INVALID_PARAM(((psCpuPA != NULL) || - (psDevPA != NULL) || - (pui64RawPTE != NULL)), - eError, ErrorExit); - - PVR_LOG_GOTO_IF_INVALID_PARAM(((ui32FwVA >= ui32FwHeapBase) && - (ui32FwVA < ui32FwHeapEnd)), - eError, ErrorExit); - - ui32HeapId = (ui32OSID == RGXFW_HOST_OS) ? - PVRSRV_PHYS_HEAP_FW_MAIN : (PVRSRV_PHYS_HEAP_FW_PREMAP0 + ui32OSID); - psPhysHeap = psDevInfo->psDeviceNode->apsPhysHeap[ui32HeapId]; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - /* MIPS is equipped with a dedicated MMU */ - RGXMipsCheckFaultAddress(psFwMMUCtx, ui32FwVA, &sFaultData); - } - else - { - IMG_UINT64 ui64FwDataBaseMask; - IMG_DEV_VIRTADDR sDevVAddr; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - ui64FwDataBaseMask = ~(RGXFW_SEGMMU_DATA_META_CACHE_MASK | - RGXFW_SEGMMU_DATA_VIVT_SLC_CACHE_MASK | - RGXFW_SEGMMU_DATA_BASE_ADDRESS); - } - else -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) && !defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - ui64FwDataBaseMask = ~(RGXRISCVFW_GET_REGION_BASE(0xF)); - } - else -#endif - { - PVR_LOG_GOTO_WITH_ERROR("RGXGetFwMapping", eError, PVRSRV_ERROR_NOT_IMPLEMENTED, ErrorExit); - } - - sDevVAddr.uiAddr = (ui32FwVA & ui64FwDataBaseMask) | RGX_FIRMWARE_RAW_HEAP_BASE; - - /* Fw CPU shares a subset of the GPU's VA space */ - MMU_CheckFaultAddress(psFwMMUCtx, &sDevVAddr, &sFaultData); - } - - ui64RawPTE = sFaultData.sLevelData[MMU_LEVEL_1].ui64Address; - - if (eError == PVRSRV_OK) - { - IMG_BOOL bValidPage = (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) ? - BITMASK_HAS(ui64RawPTE, RGXMIPSFW_TLB_VALID) : - BITMASK_HAS(ui64RawPTE, RGX_MMUCTRL_PT_DATA_VALID_EN); - if (!bValidPage) - { - /* don't report invalid pages */ - eError = PVRSRV_ERROR_DEVICEMEM_NO_MAPPING; - } - else - { - sDevPA.uiAddr = ui32PageOffset + ((RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) ? - RGXMIPSFW_TLB_GET_PA(ui64RawPTE) : - (ui64RawPTE & ~RGX_MMUCTRL_PT_DATA_PAGE_CLRMSK)); - - /* Only the Host's Firmware heap is present in the Host's CPU IPA space */ - if (ui32OSID == RGXFW_HOST_OS) - { - PhysHeapDevPAddrToCpuPAddr(psPhysHeap, 1, &sCpuPA, &sDevPA); - } - else - { - sCpuPA.uiAddr = 0U; - } - } - } - - if (psCpuPA != NULL) - { - *psCpuPA = sCpuPA; - } - - if (psDevPA != NULL) - { - *psDevPA = sDevPA; - } - - if (pui64RawPTE != NULL) - { - *pui64RawPTE = ui64RawPTE; - } - -ErrorExit: - return eError; -} - -/****************************************************************************** - End of file (rgxfwutils.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.h b/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.h deleted file mode 100644 index d69f92f8ae9cb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxfwutils.h +++ /dev/null @@ -1,1362 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX firmware utility routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX firmware utility routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXFWUTILS_H -#define RGXFWUTILS_H - -#include "rgx_memallocflags.h" -#include "log2.h" -#include "rgxdevice.h" -#include "rgxccb.h" -#include "devicemem.h" -#include "device.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "connection_server.h" -#include "rgxta3d.h" -#include "devicemem_utils.h" -#include "rgxmem.h" - -#define RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT "FwRawOSID%d" /*!< RGX Raw Firmware Heap identifier */ - -static INLINE PVRSRV_ERROR _SelectDevMemHeap(PVRSRV_RGXDEV_INFO *psDevInfo, - PVRSRV_MEMALLOCFLAGS_T *puiFlags, - DEVMEM_HEAP **ppsFwHeap) -{ - PVRSRV_PHYS_HEAP ePhysHeap = (PVRSRV_PHYS_HEAP)PVRSRV_GET_PHYS_HEAP_HINT(*puiFlags); - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (ePhysHeap) - { -#if defined(SUPPORT_SECURITY_VALIDATION) - /* call with GPU_SECURE from RGXSetupFwSysData */ - case PVRSRV_PHYS_HEAP_GPU_SECURE: -#endif - case PVRSRV_PHYS_HEAP_FW_CODE: - case PVRSRV_PHYS_HEAP_FW_PRIV_DATA: - case PVRSRV_PHYS_HEAP_FW_MAIN: - { - *ppsFwHeap = psDevInfo->psFirmwareMainHeap; - break; - } - case PVRSRV_PHYS_HEAP_FW_CONFIG: - { - *ppsFwHeap = psDevInfo->psFirmwareConfigHeap; - break; - } - case PVRSRV_PHYS_HEAP_FW_PREMAP0: - case PVRSRV_PHYS_HEAP_FW_PREMAP1: - case PVRSRV_PHYS_HEAP_FW_PREMAP2: - case PVRSRV_PHYS_HEAP_FW_PREMAP3: - case PVRSRV_PHYS_HEAP_FW_PREMAP4: - case PVRSRV_PHYS_HEAP_FW_PREMAP5: - case PVRSRV_PHYS_HEAP_FW_PREMAP6: - case PVRSRV_PHYS_HEAP_FW_PREMAP7: - { - IMG_UINT32 ui32OSID = ePhysHeap - PVRSRV_PHYS_HEAP_FW_PREMAP0; - - PVR_LOG_RETURN_IF_INVALID_PARAM(ui32OSID < RGX_NUM_OS_SUPPORTED, "ui32OSID"); - *ppsFwHeap = psDevInfo->psGuestFirmwareRawHeap[ui32OSID]; - break; - } - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: invalid phys heap", __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - } - - return eError; -} - -/* - * Firmware-only allocation (which are initialised by the host) must be aligned to the SLC cache line size. - * This is because firmware-only allocations are GPU_CACHE_INCOHERENT and this causes problems - * if two allocations share the same cache line; e.g. the initialisation of the second allocation won't - * make it into the SLC cache because it has been already loaded when accessing the content of the first allocation. - */ -static INLINE PVRSRV_ERROR DevmemFwAllocate(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_DEVMEM_SIZE_T uiSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - IMG_DEV_VIRTADDR sTmpDevVAddr; - PVRSRV_ERROR eError; - DEVMEM_HEAP *psFwHeap; - IMG_DEVMEM_ALIGN_T uiAlign; - - PVR_DPF_ENTERED; - - /* Enforce the standard pre-fix naming scheme callers must follow */ - PVR_ASSERT((pszText != NULL) && (pszText[0] == 'F') && (pszText[1] == 'w')); - - /* Imported from AppHint , flag to poison allocations when freed */ - uiFlags |= psDevInfo->uiFWPoisonOnFreeFlag; - - eError = _SelectDevMemHeap(psDevInfo, &uiFlags, &psFwHeap); - if (eError != PVRSRV_OK) - { - PVR_DPF_RETURN_RC(eError); - } - -#define MIPS_CACHE_LINE_SIZE_IN_BYTES 16 - uiAlign = (psFwHeap == psDevInfo->psFirmwareConfigHeap) ? - (RGX_FIRMWARE_CONFIG_HEAP_ALLOC_GRANULARITY) : -/* - * Aligning fw based allocations for MIPS based rogue cores at cache line boundary(16 bytes) instead of SLC(64 bytes) - * to have more compact memory with less wastage and hopefully save some tlb misses. - */ - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) ? MIPS_CACHE_LINE_SIZE_IN_BYTES - : GET_ROGUE_CACHE_LINE_SIZE(RGX_GET_FEATURE_VALUE(psDevInfo, SLC_CACHE_LINE_SIZE_BITS))); - - eError = DevmemAllocateAndMap(psFwHeap, - uiSize, - uiAlign, - uiFlags, - pszText, - ppsMemDescPtr, - &sTmpDevVAddr); - - PVR_DPF_RETURN_RC(eError); -} - -static INLINE PVRSRV_ERROR DevmemFwAllocateExportable(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_ALIGN_T uiAlign, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice; - IMG_DEV_VIRTADDR sTmpDevVAddr; - PVRSRV_ERROR eError; - DEVMEM_HEAP *psFwHeap; - - PVR_DPF_ENTERED; - - /* Enforce the standard pre-fix naming scheme callers must follow */ - PVR_ASSERT((pszText != NULL) && - (pszText[0] == 'F') && (pszText[1] == 'w') && - (pszText[2] == 'E') && (pszText[3] == 'x')); - - /* Imported from AppHint , flag to poison allocations when freed */ - uiFlags |= psDevInfo->uiFWPoisonOnFreeFlag; - - eError = _SelectDevMemHeap(psDevInfo, &uiFlags, &psFwHeap); - if (eError != PVRSRV_OK) - { - PVR_DPF_RETURN_RC(eError); - } - - eError = DevmemAllocateExportable(psDeviceNode, - uiSize, - uiAlign, - RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) ? - ExactLog2(uiAlign) : - DevmemGetHeapLog2PageSize(psFwHeap), - uiFlags, - pszText, - ppsMemDescPtr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FW DevmemAllocateExportable failed (%u)", eError)); - PVR_DPF_RETURN_RC(eError); - } - - /* - We need to map it so the heap for this allocation - is set - */ - eError = DevmemMapToDevice(*ppsMemDescPtr, - psDevInfo->psFirmwareMainHeap, - &sTmpDevVAddr); - if (eError != PVRSRV_OK) - { - DevmemFree(*ppsMemDescPtr); - PVR_DPF((PVR_DBG_ERROR, "FW DevmemMapToDevice failed (%u)", eError)); - } - - PVR_DPF_RETURN_RC1(eError, *ppsMemDescPtr); -} - -static INLINE PVRSRV_ERROR DevmemFwAllocateSparse(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - IMG_DEV_VIRTADDR sTmpDevVAddr; - PVRSRV_ERROR eError; - DEVMEM_HEAP *psFwHeap; - IMG_UINT32 ui32Align; - - PVR_DPF_ENTERED; - - /* Enforce the standard pre-fix naming scheme callers must follow */ - PVR_ASSERT((pszText != NULL) && (pszText[0] == 'F') && (pszText[1] == 'w')); - ui32Align = GET_ROGUE_CACHE_LINE_SIZE(RGX_GET_FEATURE_VALUE(psDevInfo, SLC_CACHE_LINE_SIZE_BITS)); - - /* Imported from AppHint , flag to poison allocations when freed */ - uiFlags |= psDevInfo->uiFWPoisonOnFreeFlag; - - eError = _SelectDevMemHeap(psDevInfo, &uiFlags, &psFwHeap); - if (eError != PVRSRV_OK) - { - PVR_DPF_RETURN_RC(eError); - } - - eError = DevmemAllocateSparse(psDevInfo->psDeviceNode, - uiSize, - uiChunkSize, - ui32NumPhysChunks, - ui32NumVirtChunks, - pui32MappingTable, - ui32Align, - DevmemGetHeapLog2PageSize(psFwHeap), - uiFlags | PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING, - pszText, - ppsMemDescPtr); - if (eError != PVRSRV_OK) - { - PVR_DPF_RETURN_RC(eError); - } - /* - We need to map it so the heap for this allocation - is set - */ - eError = DevmemMapToDevice(*ppsMemDescPtr, - psFwHeap, - &sTmpDevVAddr); - if (eError != PVRSRV_OK) - { - DevmemFree(*ppsMemDescPtr); - PVR_DPF_RETURN_RC(eError); - } - - PVR_DPF_RETURN_RC(eError); -} - - -static INLINE void DevmemFwUnmapAndFree(PVRSRV_RGXDEV_INFO *psDevInfo, - DEVMEM_MEMDESC *psMemDesc) -{ - PVR_DPF_ENTERED1(psMemDesc); - - DevmemReleaseDevVirtAddr(psMemDesc); - DevmemFree(psMemDesc); - - PVR_DPF_RETURN; -} - -/* - * This function returns the value of the hardware register RGX_CR_TIMER - * which is a timer counting in ticks. - */ - -static INLINE IMG_UINT64 RGXReadHWTimerReg(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT64 ui64Time = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TIMER); - - /* - * In order to avoid having to issue three 32-bit reads to detect the - * lower 32-bits wrapping, the MSB of the low 32-bit word is duplicated - * in the MSB of the high 32-bit word. If the wrap happens, we just read - * the register again (it will not wrap again so soon). - */ - if ((ui64Time ^ (ui64Time << 32)) & ~RGX_CR_TIMER_BIT31_CLRMSK) - { - ui64Time = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TIMER); - } - - return (ui64Time & ~RGX_CR_TIMER_VALUE_CLRMSK) >> RGX_CR_TIMER_VALUE_SHIFT; -} - -/* - * This FW Common Context is only mapped into kernel for initialisation and cleanup purposes. - * Otherwise this allocation is only used by the FW. - * Therefore the GPU cache doesn't need coherency, and write-combine will - * suffice on the CPU side (WC buffer will be flushed at the first kick) - */ -#define RGX_FWCOMCTX_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED)| \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN)) - -#define RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN)) - -#define RGX_FWSHAREDMEM_CONFIG_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_CONFIG)) - -#define RGX_FWSHAREDMEM_GPU_RO_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN)) - -/* Firmware memory that is not accessible by the CPU. */ -#define RGX_FWSHAREDMEM_GPU_ONLY_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) - -/* Firmware shared memory that is supposed to be read-only to the CPU. - * In reality it isn't due to ZERO_ON_ALLOC which enforces CPU_WRITEABLE - * flag on the allocations. */ -#define RGX_FWSHAREDMEM_CPU_RO_ALLOCFLAGS (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \ - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN) | \ - PVRSRV_MEMALLOCFLAG_GPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \ - PVRSRV_MEMALLOCFLAG_CPU_READABLE | \ - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \ - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | \ - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | \ - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) - -/* data content being kept from previous boot cycles from physical memory must not be cleared during allocation */ -#define RGX_AUTOVZ_KEEP_FW_DATA_MASK(bKeepMem) ((bKeepMem) ? (~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) : (~0ULL)) - -/****************************************************************************** - * RGXSetFirmwareAddress Flags - *****************************************************************************/ -#define RFW_FWADDR_FLAG_NONE (0) /*!< Void flag */ -#define RFW_FWADDR_NOREF_FLAG (1U << 0) /*!< It is safe to immediately release the reference to the pointer, - otherwise RGXUnsetFirmwareAddress() must be call when finished. */ - -IMG_BOOL RGXTraceBufferIsInitRequired(PVRSRV_RGXDEV_INFO *psDevInfo); -PVRSRV_ERROR RGXTraceBufferInitOnDemandResources(PVRSRV_RGXDEV_INFO* psDevInfo, PVRSRV_MEMALLOCFLAGS_T uiAllocFlags); - -#if defined(SUPPORT_TBI_INTERFACE) -IMG_BOOL RGXTBIBufferIsInitRequired(PVRSRV_RGXDEV_INFO *psDevInfo); -PVRSRV_ERROR RGXTBIBufferInitOnDemandResources(PVRSRV_RGXDEV_INFO *psDevInfo); -#endif - -PVRSRV_ERROR RGXSetupFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bEnableSignatureChecks, - IMG_UINT32 ui32SignatureChecksBufSize, - IMG_UINT32 ui32HWPerfFWBufSizeKB, - IMG_UINT64 ui64HWPerfFilter, - IMG_UINT32 ui32ConfigFlags, - IMG_UINT32 ui32ConfigFlagsExt, - IMG_UINT32 ui32FwOsCfgFlags, - IMG_UINT32 ui32LogType, - IMG_UINT32 ui32FilterFlags, - IMG_UINT32 ui32JonesDisableMask, - IMG_UINT32 ui32HWRDebugDumpLimit, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_UINT32 *pui32TPUTrilinearFracMask, - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf, - FW_PERF_CONF eFirmwarePerf, - IMG_UINT32 ui32KCCBSizeLog2); - - - -void RGXFreeFirmware(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*************************************************************************/ /*! -@Function RGXSetupFwAllocation - -@Description Sets a pointer in a firmware data structure. - -@Input psDevInfo Device Info struct -@Input uiAllocFlags Flags determining type of memory allocation -@Input ui32Size Size of memory allocation -@Input pszName Allocation label -@Input psFwPtr Address of the firmware pointer to set -@Input ppvCpuPtr Address of the cpu pointer to set -@Input ui32DevVAFlags Any combination of RFW_FWADDR_*_FLAG - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXSetupFwAllocation(PVRSRV_RGXDEV_INFO *psDevInfo, - PVRSRV_MEMALLOCFLAGS_T uiAllocFlags, - IMG_UINT32 ui32Size, - const IMG_CHAR *pszName, - DEVMEM_MEMDESC **ppsMemDesc, - RGXFWIF_DEV_VIRTADDR *psFwPtr, - void **ppvCpuPtr, - IMG_UINT32 ui32DevVAFlags); - -/*************************************************************************/ /*! -@Function RGXSetFirmwareAddress - -@Description Sets a pointer in a firmware data structure. - -@Input ppDest Address of the pointer to set -@Input psSrc MemDesc describing the pointer -@Input ui32Flags Any combination of RFW_FWADDR_*_FLAG - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXSetFirmwareAddress(RGXFWIF_DEV_VIRTADDR *ppDest, - DEVMEM_MEMDESC *psSrc, - IMG_UINT32 uiOffset, - IMG_UINT32 ui32Flags); - - -/*************************************************************************/ /*! -@Function RGXSetMetaDMAAddress - -@Description Fills a Firmware structure used to setup the Meta DMA with two - pointers to the same data, one on 40 bit and one on 32 bit - (pointer in the FW memory space). - -@Input ppDest Address of the structure to set -@Input psSrcMemDesc MemDesc describing the pointer -@Input psSrcFWDevVAddr Firmware memory space pointer - -@Return void -*/ /**************************************************************************/ -void RGXSetMetaDMAAddress(RGXFWIF_DMA_ADDR *psDest, - DEVMEM_MEMDESC *psSrcMemDesc, - RGXFWIF_DEV_VIRTADDR *psSrcFWDevVAddr, - IMG_UINT32 uiOffset); - - -/*************************************************************************/ /*! -@Function RGXUnsetFirmwareAddress - -@Description Unsets a pointer in a firmware data structure - -@Input psSrc MemDesc describing the pointer - -@Return void -*/ /**************************************************************************/ -void RGXUnsetFirmwareAddress(DEVMEM_MEMDESC *psSrc); - -/*************************************************************************/ /*! -@Function FWCommonContextAllocate - -@Description Allocate a FW common context. This allocates the HW memory - for the context, the CCB and wires it all together. - -@Input psConnection Connection this context is being created on -@Input psDeviceNode Device node to create the FW context on - (must be RGX device node) -@Input eRGXCCBRequestor RGX_CCB_REQUESTOR_TYPE enum constant which - which represents the requestor of this FWCC -@Input eDM Data Master type -@Input psServerMMUContext Server MMU memory context. -@Input psAllocatedMemDesc Pointer to pre-allocated MemDesc to use - as the FW context or NULL if this function - should allocate it -@Input ui32AllocatedOffset Offset into pre-allocate MemDesc to use - as the FW context. If psAllocatedMemDesc - is NULL then this parameter is ignored -@Input psFWMemContextMemDesc MemDesc of the FW memory context this - common context resides on -@Input psContextStateMemDesc FW context state (context switch) MemDesc -@Input ui32CCBAllocSizeLog2 Size of the CCB for this context -@Input ui32CCBMaxAllocSizeLog2 Maximum size to which CCB can grow for this context -@Input ui32ContextFlags Flags which specify properties of the context -@Input ui32Priority Priority of the context -@Input ui32MaxDeadlineMS Max deadline limit in MS that the workload can run -@Input ui64RobustnessAddress Address for FW to signal a context reset -@Input psInfo Structure that contains extra info - required for the creation of the context - (elements might change from core to core) -@Return PVRSRV_OK if the context was successfully created -*/ /**************************************************************************/ -PVRSRV_ERROR FWCommonContextAllocate(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_CCB_REQUESTOR_TYPE eRGXCCBRequestor, - RGXFWIF_DM eDM, - SERVER_MMU_CONTEXT *psServerMMUContext, - DEVMEM_MEMDESC *psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - DEVMEM_MEMDESC *psContextStateMemDesc, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32MaxDeadlineMS, - IMG_UINT64 ui64RobustnessAddress, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_COMMON_CONTEXT **ppsServerCommonContext); - -void FWCommonContextFree(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext); - -PRGXFWIF_FWCOMMONCONTEXT FWCommonContextGetFWAddress(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext); - -RGX_CLIENT_CCB *FWCommonContextGetClientCCB(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext); - -RGX_CONTEXT_RESET_REASON FWCommonContextGetLastResetReason(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - IMG_UINT32 *pui32LastResetJobRef); - -PVRSRV_RGXDEV_INFO* FWCommonContextGetRGXDevInfo(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext); - -PVRSRV_ERROR RGXGetFWCommonContextAddrFromServerMMUCtx(PVRSRV_RGXDEV_INFO *psDevInfo, - SERVER_MMU_CONTEXT *psServerMMUContext, - PRGXFWIF_FWCOMMONCONTEXT *psFWCommonContextFWAddr); - -PVRSRV_ERROR FWCommonContextSetFlags(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - IMG_UINT32 ui32ContextFlags); -/*! -******************************************************************************* -@Function RGXScheduleProcessQueuesKM - -@Description Software command complete handler - (sends uncounted kicks for all the DMs through the MISR) - -@Input hCmdCompHandle RGX device node - -@Return None -******************************************************************************/ -void RGXScheduleProcessQueuesKM(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle); - -#if defined(SUPPORT_VALIDATION) -/*! -******************************************************************************* -@Function RGXScheduleRgxRegCommand - -@Input psDevInfo Device Info struct -@Input ui64RegVal Value to write into FW register -@Input ui64Size Register size -@Input ui32Offset Register Offset -@Input bWriteOp Register Write or Read toggle - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXScheduleRgxRegCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 ui64RegVal, - IMG_UINT64 ui64Size, - IMG_UINT32 ui32Offset, - IMG_BOOL bWriteOp); - -#endif - -/*! -******************************************************************************* - -@Function RGXInstallProcessQueuesMISR - -@Description Installs the MISR to handle Process Queues operations - -@Input phMISR Pointer to the MISR handler -@Input psDeviceNode RGX Device node - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXInstallProcessQueuesMISR(IMG_HANDLE *phMISR, PVRSRV_DEVICE_NODE *psDeviceNode); - -PVRSRV_ERROR RGXSendCommandsFromDeferredList(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bPoll); - -/*************************************************************************/ /*! -@Function RGXSendCommandWithPowLockAndGetKCCBSlot - -@Description Sends a command to a particular DM without honouring - pending cache operations but taking the power lock. - -@Input psDevInfo Device Info -@Input psKCCBCmd The cmd to send. -@Input ui32PDumpFlags Pdump flags -@Output pui32CmdKCCBSlot When non-NULL: - - Pointer on return contains the kCCB slot - number in which the command was enqueued. - - Resets the value of the allotted slot to - RGXFWIF_KCCB_RTN_SLOT_RST -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXSendCommandWithPowLockAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot); - -#define RGXSendCommandWithPowLock(psDevInfo, psKCCBCmd, ui32PDumpFlags) \ - RGXSendCommandWithPowLockAndGetKCCBSlot(psDevInfo, psKCCBCmd, ui32PDumpFlags, NULL) - -/*************************************************************************/ /*! -@Function RGXSendCommandAndGetKCCBSlot - -@Description Sends a command to a particular DM without honouring - pending cache operations or the power lock. - The function flushes any deferred KCCB commands first. - -@Input psDevInfo Device Info -@Input psKCCBCmd The cmd to send. -@Input uiPdumpFlags PDump flags. -@Output pui32CmdKCCBSlot When non-NULL: - - Pointer on return contains the kCCB slot - number in which the command was enqueued. - - Resets the value of the allotted slot to - RGXFWIF_KCCB_RTN_SLOT_RST -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXSendCommandAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_KCCB_CMD *psKCCBCmd, - PDUMP_FLAGS_T uiPdumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot); - -#define RGXSendCommand(psDevInfo, psKCCBCmd, ui32PDumpFlags) \ - RGXSendCommandAndGetKCCBSlot(psDevInfo, psKCCBCmd, ui32PDumpFlags, NULL) - -/*************************************************************************/ /*! -@Function RGXScheduleCommand - -@Description Sends a command to a particular DM and kicks the firmware but - first schedules any commands which have to happen before - handle - -@Input psDevInfo Device Info -@Input eDM To which DM the cmd is sent. -@Input psKCCBCmd The cmd to send. -@Input ui32PDumpFlags PDump flags -@Output pui32CmdKCCBSlot When non-NULL: - - Pointer on return contains the kCCB slot - number in which the command was enqueued. - - Resets the value of the allotted slot to - RGXFWIF_KCCB_RTN_SLOT_RST -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXScheduleCommandAndGetKCCBSlot(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DM eKCCBType, - RGXFWIF_KCCB_CMD *psKCCBCmd, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 *pui32CmdKCCBSlot); -#define RGXScheduleCommand(psDevInfo, eKCCBType, psKCCBCmd, ui32PDumpFlags) \ - RGXScheduleCommandAndGetKCCBSlot(psDevInfo, eKCCBType, psKCCBCmd, ui32PDumpFlags, NULL) - -/*************************************************************************/ /*! -@Function RGXWaitForKCCBSlotUpdate - -@Description Waits until the required kCCB slot value is updated by the FW - (signifies command completion). Additionally, dumps a relevant - PDump poll command. - -@Input psDevInfo Device Info -@Input ui32SlotNum The kCCB slot number to wait for an update on -@Input ui32PDumpFlags - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXWaitForKCCBSlotUpdate(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32SlotNum, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR RGXFirmwareUnittests(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*************************************************************************/ /*! -@Function PVRSRVRGXFrameworkCopyCommand - -@Description Copy framework command into FW addressable buffer - -@param psDeviceNode -@param psFWFrameworkMemDesc -@param pbyGPUFRegisterList -@param ui32FrameworkRegisterSize - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVRGXFrameworkCopyCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psFWFrameworkMemDesc, - IMG_PBYTE pbyGPUFRegisterList, - IMG_UINT32 ui32FrameworkRegisterSize); - - -/*************************************************************************/ /*! -@Function PVRSRVRGXFrameworkCreateKM - -@Description Create FW addressable buffer for framework - -@param psDeviceNode -@param ppsFWFrameworkMemDesc -@param ui32FrameworkRegisterSize - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVRGXFrameworkCreateKM(PVRSRV_DEVICE_NODE * psDeviceNode, - DEVMEM_MEMDESC ** ppsFWFrameworkMemDesc, - IMG_UINT32 ui32FrameworkRegisterSize); - -/*************************************************************************/ /*! -@Function RGXPollForGPCommandCompletion - -@Description Polls for completion of a submitted GP command. Poll is done - on a value matching a masked read from the address. - -@Input psDevNode Pointer to device node struct -@Input pui32LinMemAddr CPU linear address to poll -@Input ui32Value Required value -@Input ui32Mask Mask - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXPollForGPCommandCompletion(PVRSRV_DEVICE_NODE *psDevNode, - volatile IMG_UINT32 __iomem *pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask); - -/*************************************************************************/ /*! -@Function RGXStateFlagCtrl - -@Description Set and return FW internal state flags. - -@Input psDevInfo Device Info -@Input ui32Config AppHint config flags -@Output pui32State Current AppHint state flag configuration -@Input bSetNotClear Set or clear the provided config flags - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXStateFlagCtrl(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Config, - IMG_UINT32 *pui32State, - IMG_BOOL bSetNotClear); - -/*! -******************************************************************************* -@Function RGXFWRequestCommonContextCleanUp - -@Description Schedules a FW common context cleanup. The firmware doesn't - block waiting for the resource to become idle but rather - notifies the host that the resources is busy. - -@Input psDeviceNode pointer to device node -@Input psServerCommonContext context to be cleaned up -@Input eDM Data master, to which the cleanup command should - be sent -@Input ui32PDumpFlags PDump continuous flag - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWRequestCommonContextCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, - RGXFWIF_DM eDM, - IMG_UINT32 ui32PDumpFlags); - -/*! -******************************************************************************* -@Function RGXFWRequestHWRTDataCleanUp - -@Description Schedules a FW HWRTData memory cleanup. The firmware doesn't - block waiting for the resource to become idle but rather - notifies the host that the resources is busy. - -@Input psDeviceNode pointer to device node -@Input psHWRTData firmware address of the HWRTData for clean-up - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWRequestHWRTDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode, - PRGXFWIF_HWRTDATA psHWRTData); - -/*! -******************************************************************************* -@Function RGXFWRequestFreeListCleanUp - -@Description Schedules a FW FreeList cleanup. The firmware doesn't block - waiting for the resource to become idle but rather notifies the - host that the resources is busy. - -@Input psDeviceNode pointer to device node -@Input psFWFreeList firmware address of the FreeList for clean-up - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWRequestFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDeviceNode, - PRGXFWIF_FREELIST psFWFreeList); - -/*! -******************************************************************************* -@Function RGXFWRequestZSBufferCleanUp - -@Description Schedules a FW ZS Buffer cleanup. The firmware doesn't block - waiting for the resource to become idle but rather notifies the - host that the resources is busy. - -@Input psDevInfo pointer to device node -@Input psFWZSBuffer firmware address of the ZS Buffer for clean-up - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWRequestZSBufferCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo, - PRGXFWIF_ZSBUFFER psFWZSBuffer); - -PVRSRV_ERROR ContextSetPriority(RGX_SERVER_COMMON_CONTEXT *psContext, - CONNECTION_DATA *psConnection, - PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Priority, - RGXFWIF_DM eDM); - -/*! -******************************************************************************* -@Function RGXFWSetHCSDeadline - -@Description Requests the Firmware to set a new Hard Context Switch timeout - deadline. Context switches that surpass that deadline cause the - system to kill the currently running workloads. - -@Input psDeviceNode pointer to device node -@Input ui32HCSDeadlineMs The deadline in milliseconds. - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWSetHCSDeadline(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32HCSDeadlineMs); - -/*! -******************************************************************************* -@Function RGXFWChangeOSidPriority - -@Description Requests the Firmware to change the priority of an operating - system. Higher priority number equals higher priority on the - scheduling system. - -@Input psDevInfo pointer to device info -@Input ui32OSid The OSid whose priority is to be altered -@Input ui32Priority The new priority number for the specified OSid - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWChangeOSidPriority(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32OSid, - IMG_UINT32 ui32Priority); - -/*! -******************************************************************************* -@Function RGXFWHealthCheckCmd - -@Description Ping the firmware to check if it is responsive. - -@Input psDevInfo pointer to device info - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWHealthCheckCmd(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* -@Function RGXFWSetFwOsState - -@Description Requests the Firmware to change the guest OS Online states. - This should be initiated by the VMM when a guest VM comes - online or goes offline. If offline, the FW offloads any current - resource from that OSID. The request is repeated until the FW - has had time to free all the resources or has waited for - workloads to finish. - -@Input psDevInfo pointer to device info -@Input ui32OSid The Guest OSid whose state is being altered -@Input eOSOnlineState The new state (Online or Offline) - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWSetFwOsState(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32OSid, - RGXFWIF_OS_STATE_CHANGE eOSOnlineState); - -#if defined(SUPPORT_AUTOVZ) -/*! -******************************************************************************* -@Function RGXUpdateAutoVzWdgToken - -@Description If the driver-firmware connection is active, read the - firmware's watchdog token and copy its value back into the OS - token. This indicates to the firmware that this driver is alive - and responsive. - -@Input psDevInfo pointer to device info -******************************************************************************/ -void RGXUpdateAutoVzWdgToken(PVRSRV_RGXDEV_INFO *psDevInfo); -#endif - -/*! -******************************************************************************* -@Function RGXFWConfigPHR - -@Description Configure the Periodic Hardware Reset functionality - -@Input psDevInfo pointer to device info -@Input ui32PHRMode desired PHR mode - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWConfigPHR(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32PHRMode); - -/*! -******************************************************************************* -@Function RGXFWConfigWdg - -@Description Configure the Safety watchdog trigger period - -@Input psDevInfo pointer to device info -@Input ui32WdgPeriodUs requested period in microseconds - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXFWConfigWdg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32WdgPeriod); - -/*! -******************************************************************************* -@Function RGXCheckFirmwareCCB - -@Description Processes all commands that are found in the Firmware CCB. - -@Input psDevInfo pointer to device - -@Return None -******************************************************************************/ -void RGXCheckFirmwareCCB(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* -@Function RGXCheckForStalledClientContexts - -@Description Checks all client contexts, for the device with device info - provided, to see if any are waiting for a fence to signal and - optionally force signalling of the fence for the context which - has been waiting the longest. - This function is called by RGXUpdateHealthStatus() and also - may be invoked from other trigger points. - -@Input psDevInfo pointer to device info -@Input bIgnorePrevious If IMG_TRUE, any stalled contexts will be - indicated immediately, rather than only - checking against any previous stalled contexts - -@Return None -******************************************************************************/ -void RGXCheckForStalledClientContexts(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bIgnorePrevious); - -/*! -******************************************************************************* -@Function RGXUpdateHealthStatus - -@Description Tests a number of conditions which might indicate a fatal error - has occurred in the firmware. The result is stored in the - device node eHealthStatus. - -@Input psDevNode Pointer to device node structure. -@Input bCheckAfterTimePassed When TRUE, the function will also test - for firmware queues and polls not changing - since the previous test. - - Note: if not enough time has passed since the - last call, false positives may occur. - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXUpdateHealthStatus(PVRSRV_DEVICE_NODE* psDevNode, - IMG_BOOL bCheckAfterTimePassed); - - -PVRSRV_ERROR CheckStalledClientCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext, RGX_KICK_TYPE_DM eKickTypeDM); - -#if defined(SUPPORT_AUTOVZ) -/*! -******************************************************************************* -@Function RGXUpdateAutoVzWatchdog - -@Description Updates AutoVz watchdog that maintains the fw-driver connection - -@Input psDevNode Pointer to device node structure. -******************************************************************************/ -void RGXUpdateAutoVzWatchdog(PVRSRV_DEVICE_NODE* psDevNode); -#endif /* SUPPORT_AUTOVZ */ - -void DumpFWCommonContextInfo(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/*! -******************************************************************************* -@Function AttachKickResourcesCleanupCtls - -@Description Attaches the cleanup structures to a kick command so that - submission reference counting can be performed when the - firmware processes the command - -@Output apsCleanupCtl Array of CleanupCtl structure pointers to populate. -@Output pui32NumCleanupCtl Number of CleanupCtl structure pointers written out. -@Input eDM Which data master is the subject of the command. -@Input bKick TRUE if the client originally wanted to kick this DM. -@Input psRTDataCleanup Optional RTData cleanup associated with the command. -@Input psZBuffer Optional ZSBuffer associated with the command. - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR AttachKickResourcesCleanupCtls(PRGXFWIF_CLEANUP_CTL *apsCleanupCtl, - IMG_UINT32 *pui32NumCleanupCtl, - RGXFWIF_DM eDM, - IMG_BOOL bKick, - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet, - RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_ZSBUFFER_DATA *psMSAAScratchBuffer); - -/*! -******************************************************************************* -@Function RGXResetHWRLogs - -@Description Resets the HWR Logs buffer - (the hardware recovery count is not reset) - -@Input psDevNode Pointer to the device - -@Return PVRSRV_ERROR PVRSRV_OK on success. - Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR RGXResetHWRLogs(PVRSRV_DEVICE_NODE *psDevNode); - -/*! -******************************************************************************* -@Function RGXGetPhyAddr - -@Description Get the physical address of a PMR at an offset within it - -@Input psPMR PMR of the allocation -@Input ui32LogicalOffset Logical offset - -@Output psPhyAddr Physical address of the allocation - -@Return PVRSRV_ERROR PVRSRV_OK on success. - Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR RGXGetPhyAddr(PMR *psPMR, - IMG_DEV_PHYADDR *psPhyAddr, - IMG_UINT32 ui32LogicalOffset, - IMG_UINT32 ui32Log2PageSize, - IMG_UINT32 ui32NumOfPages, - IMG_BOOL *bValid); - -#if defined(PDUMP) -/*! -******************************************************************************* -@Function RGXPdumpDrainKCCB - -@Description Wait for the firmware to execute all the commands in the kCCB - -@Input psDevInfo Pointer to the device -@Input ui32WriteOffset Woff we have to POL for the Roff to be equal to - -@Return PVRSRV_ERROR PVRSRV_OK on success. - Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR RGXPdumpDrainKCCB(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32WriteOffset); -#endif /* PDUMP */ - -/*! -******************************************************************************* -@Function RGXFwRawHeapAllocMap - -@Description Register and maps to device, a raw firmware physheap - -@Return PVRSRV_ERROR PVRSRV_OK on success. - Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR RGXFwRawHeapAllocMap(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSID, - IMG_DEV_PHYADDR sDevPAddr, - IMG_UINT64 ui64DevPSize); - -/*! -******************************************************************************* -@Function RGXFwRawHeapUnmapFree - -@Description Unregister and unmap from device, a raw firmware physheap -******************************************************************************/ -void RGXFwRawHeapUnmapFree(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32OSID); - -/*! -******************************************************************************* -@Function RGXRiscvHalt - -@Description Halt the RISC-V FW core (required for certain operations - done through Debug Module) - -@Input psDevInfo Pointer to device info - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvHalt(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* -@Function RGXRiscvIsHalted - -@Description Check if the RISC-V FW is halted - -@Input psDevInfo Pointer to device info - -@Return IMG_BOOL -******************************************************************************/ -IMG_BOOL RGXRiscvIsHalted(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* -@Function RGXRiscvResume - -@Description Resume the RISC-V FW core - -@Input psDevInfo Pointer to device info - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvResume(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* -@Function RGXRiscvReadReg - -@Description Read a value from the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvReadReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 *pui32Value); - -/*! -******************************************************************************* -@Function RGXRiscvPollReg - -@Description Poll for a value from the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvPollReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32Value); - -/*! -******************************************************************************* -@Function RGXRiscvWriteReg - -@Description Write a value to the given RISC-V register (GPR or CSR) - -@Input psDevInfo Pointer to device info -@Input ui32RegAddr RISC-V register address -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvWriteReg(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32Value); - -/*! -******************************************************************************* -@Function RGXRiscvPollMem - -@Description Poll for a value at the given address in RISC-V memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Expected value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvPollMem(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Addr, - IMG_UINT32 ui32Value); - -/*! -******************************************************************************* -@Function RGXRiscvDmiOp - -@Description Acquire the powerlock and perform an operation on the RISC-V - Debug Module Interface, but only if the GPU is powered on. - -@Input psDevInfo Pointer to device info -@InOut pui64DMI Encoding of a request for the RISC-V Debug - Module with same format as the 'dmi' register - from the RISC-V debug specification (v0.13+). - On return, this is updated with the result of - the request, encoded the same way. - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXRiscvDmiOp(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT64 *pui64DMI); - -/*! -******************************************************************************* -@Function RGXReadFWModuleAddr - -@Description Read a value at the given address in META or RISCV memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in META or RISCV memory space - -@Output pui32Value Read value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXReadFWModuleAddr(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Addr, - IMG_UINT32 *pui32Value); - -/*! -******************************************************************************* -@Function RGXWriteFWModuleAddr - -@Description Write a value to the given address in META or RISC memory space - -@Input psDevInfo Pointer to device info -@Input ui32Addr Address in RISC-V memory space -@Input ui32Value Write value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXWriteFWModuleAddr(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32MemAddr, - IMG_UINT32 ui32Value); - -/*! -******************************************************************************* -@Function RGXGetFwMapping - -@Description Retrieve any of the CPU Physical Address, Device Physical - Address or the raw value of the page table entry associated - with the firmware virtual address given. - -@Input psDevInfo Pointer to device info -@Input ui32FwVA The Fw VA that needs decoding -@Output psCpuPA Pointer to the resulting CPU PA -@Output psDevPA Pointer to the resulting Dev PA -@Output pui64RawPTE Pointer to the raw Page Table Entry value - -@Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RGXGetFwMapping(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FwVA, - IMG_CPU_PHYADDR *psCpuPA, - IMG_DEV_PHYADDR *psDevPA, - IMG_UINT64 *pui64RawPTE); - -#if defined(SUPPORT_AUTOVZ_HW_REGS) && !defined(SUPPORT_AUTOVZ) -#error "VZ build configuration error: use of OS scratch registers supported only in AutoVz drivers." -#endif - -#if defined(SUPPORT_AUTOVZ_HW_REGS) -/* AutoVz with hw support */ -#define KM_GET_FW_CONNECTION(psDevInfo) OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH3) -#define KM_GET_OS_CONNECTION(psDevInfo) OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH2) -#define KM_SET_OS_CONNECTION(val, psDevInfo) OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH2, RGXFW_CONNECTION_OS_##val) - -#define KM_GET_FW_ALIVE_TOKEN(psDevInfo) OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH1) -#define KM_GET_OS_ALIVE_TOKEN(psDevInfo) OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH0) -#define KM_SET_OS_ALIVE_TOKEN(val, psDevInfo) OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OS0_SCRATCH0, val) - -#else - -#if defined(SUPPORT_AUTOVZ) -#define KM_GET_FW_ALIVE_TOKEN(psDevInfo) (psDevInfo->psRGXFWIfConnectionCtl->ui32AliveFwToken) -#define KM_GET_OS_ALIVE_TOKEN(psDevInfo) (psDevInfo->psRGXFWIfConnectionCtl->ui32AliveOsToken) -#define KM_SET_OS_ALIVE_TOKEN(val, psDevInfo) OSWriteDeviceMem32WithWMB((volatile IMG_UINT32 *) &psDevInfo->psRGXFWIfConnectionCtl->ui32AliveOsToken, val) -#endif /* defined(SUPPORT_AUTOVZ) */ - -#if !defined(NO_HARDWARE) && (defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) || (defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED == 1))) -/* native, static-vz and AutoVz using shared memory */ -#define KM_GET_FW_CONNECTION(psDevInfo) (psDevInfo->psRGXFWIfConnectionCtl->eConnectionFwState) -#define KM_GET_OS_CONNECTION(psDevInfo) (psDevInfo->psRGXFWIfConnectionCtl->eConnectionOsState) -#define KM_SET_OS_CONNECTION(val, psDevInfo) OSWriteDeviceMem32WithWMB((void*)&psDevInfo->psRGXFWIfConnectionCtl->eConnectionOsState, RGXFW_CONNECTION_OS_##val) -#else -/* dynamic-vz & nohw */ -#define KM_GET_FW_CONNECTION(psDevInfo) (RGXFW_CONNECTION_FW_ACTIVE) -#define KM_GET_OS_CONNECTION(psDevInfo) (RGXFW_CONNECTION_OS_ACTIVE) -#define KM_SET_OS_CONNECTION(val, psDevInfo) -#endif /* defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) || (RGX_NUM_OS_SUPPORTED == 1) */ -#endif /* defined(SUPPORT_AUTOVZ_HW_REGS) */ - -#if defined(SUPPORT_AUTOVZ) -#define RGX_FIRST_RAW_HEAP_OSID RGXFW_HOST_OS -#else -#define RGX_FIRST_RAW_HEAP_OSID RGXFW_GUEST_OSID_START -#endif - -#define KM_OS_CONNECTION_IS(val, psDevInfo) (KM_GET_OS_CONNECTION(psDevInfo) == RGXFW_CONNECTION_OS_##val) -#define KM_FW_CONNECTION_IS(val, psDevInfo) (KM_GET_FW_CONNECTION(psDevInfo) == RGXFW_CONNECTION_FW_##val) - -#endif /* RGXFWUTILS_H */ -/****************************************************************************** - End of file (rgxfwutils.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig.h b/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig.h deleted file mode 100644 index abb63084acefc..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig.h +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Device virtual memory map -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Memory heaps device specific configuration -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXHEAPCONFIG_H -#define RGXHEAPCONFIG_H - -#include "rgxdefs_km.h" - - -#define RGX_HEAP_SIZE_4KiB IMG_UINT64_C(0x0000001000) -#define RGX_HEAP_SIZE_64KiB IMG_UINT64_C(0x0000010000) -#define RGX_HEAP_SIZE_256KiB IMG_UINT64_C(0x0000040000) - -#define RGX_HEAP_SIZE_1MiB IMG_UINT64_C(0x0000100000) -#define RGX_HEAP_SIZE_2MiB IMG_UINT64_C(0x0000200000) -#define RGX_HEAP_SIZE_4MiB IMG_UINT64_C(0x0000400000) -#define RGX_HEAP_SIZE_16MiB IMG_UINT64_C(0x0001000000) -#define RGX_HEAP_SIZE_256MiB IMG_UINT64_C(0x0010000000) - -#define RGX_HEAP_SIZE_1GiB IMG_UINT64_C(0x0040000000) -#define RGX_HEAP_SIZE_2GiB IMG_UINT64_C(0x0080000000) -#define RGX_HEAP_SIZE_4GiB IMG_UINT64_C(0x0100000000) -#define RGX_HEAP_SIZE_16GiB IMG_UINT64_C(0x0400000000) -#define RGX_HEAP_SIZE_32GiB IMG_UINT64_C(0x0800000000) -#define RGX_HEAP_SIZE_64GiB IMG_UINT64_C(0x1000000000) -#define RGX_HEAP_SIZE_128GiB IMG_UINT64_C(0x2000000000) -#define RGX_HEAP_SIZE_256GiB IMG_UINT64_C(0x4000000000) -#define RGX_HEAP_SIZE_512GiB IMG_UINT64_C(0x8000000000) - -/* - RGX Device Virtual Address Space Definitions - - This file defines the RGX virtual address heaps that are used in - application memory contexts. It also shows where the Firmware memory heap - fits into this, but the firmware heap is only ever created in the - Services KM/server component. - - RGX_PDSCODEDATA_HEAP_BASE and RGX_USCCODE_HEAP_BASE will be programmed, - on a global basis, into RGX_CR_PDS_EXEC_BASE and RGX_CR_USC_CODE_BASE_* - respectively. Therefore if clients use multiple configs they must still - be consistent with their definitions for these heaps. - - Shared virtual memory (GENERAL_SVM) support requires half of the address - space (512 GiB) be reserved for SVM allocations to mirror application CPU - addresses. However, if BRN_65273 WA is active in which case the SVM heap - is disabled. This is reflected in the device connection capability bits - returned to user space. - - The GENERAL non-SVM region is 512 GiB to 768 GiB and is shared between the - general (4KiB) heap and the general non-4K heap. The first 128 GiB is used - for the GENERAL_HEAP (4KiB) and the last 32 GiB is used for the - GENERAL_NON4K_HEAP. This heap has a default page-size of 16K. - AppHint PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE can be used to forced it - to these values: 4K,64K,256K,1M,2M. - - The heaps defined for BRN_65273 _replace_ the non-BRN equivalents below - when this BRN WA is active on affected cores. This is different to most - other BRNs and hence has been given its own header file for clarity, - see below. This is a special case, other BRNs that need 1 or 2 additional - heaps should be added to this file, like BRN_63142 below. - NOTE: All regular heaps below greater than 1GB require a BRN_65273 WA heap. - - Base addresses have to be a multiple of 4MiB - Heaps must not start at 0x0000000000, as this is reserved for internal - use within device memory layer. - Range comments, those starting in column 0 below are a section heading of - sorts and are above the heaps in that range. Often this is the reserved - size of the heap within the range. -*/ - -/* This BRN requires a different virtual memory map from the standard one - * defined in this file below. Hence the alternative heap definitions for this - * BRN are provided in a separate file for clarity. */ -#include "rgxheapconfig_65273.h" - - -/* 0x00_0000_0000 ************************************************************/ - -/* 0x00_0000_0000 - 0x00_0040_0000 **/ - /* 0 MiB to 4 MiB, size of 4 MiB : RESERVED **/ - - /* BRN_65273 TQ3DPARAMETERS base 0x0000010000 */ - /* BRN_65273 GENERAL base 0x65C0000000 */ - /* BRN_65273 GENERAL_NON4K base 0x73C0000000 */ - -/* 0x00_0040_0000 - 0x7F_FFC0_0000 **/ - /* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : GENERAL_SVM_HEAP **/ - #define RGX_GENERAL_SVM_HEAP_BASE IMG_UINT64_C(0x0000400000) - #define RGX_GENERAL_SVM_HEAP_SIZE (RGX_HEAP_SIZE_512GiB - RGX_HEAP_SIZE_4MiB) - - -/* 0x80_0000_0000 ************************************************************/ - -/* 0x80_0000_0000 - 0x9F_FFFF_FFFF **/ - /* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/ - #define RGX_GENERAL_HEAP_BASE IMG_UINT64_C(0x8000000000) - #define RGX_GENERAL_HEAP_SIZE RGX_HEAP_SIZE_128GiB - - /* BRN_65273 PDSCODEDATA base 0xA800000000 */ - -/* 0xA0_0000_0000 - 0xAF_FFFF_FFFF **/ - /* 640 GiB to 704 GiB, size of 64 GiB : FREE **/ - -/* B0_0000_0000 - 0xB7_FFFF_FFFF **/ - /* 704 GiB to 736 GiB, size of 32 GiB : FREE **/ - - /* BRN_65273 USCCODE base 0xBA00000000 */ - -/* 0xB8_0000_0000 - 0xBF_FFFF_FFFF **/ - /* 736 GiB to 768 GiB, size of 32 GiB : GENERAL_NON4K_HEAP **/ - #define RGX_GENERAL_NON4K_HEAP_BASE IMG_UINT64_C(0xB800000000) - #define RGX_GENERAL_NON4K_HEAP_SIZE RGX_HEAP_SIZE_32GiB - - -/* 0xC0_0000_0000 ************************************************************/ - -/* 0xC0_0000_0000 - 0xD9_FFFF_FFFF **/ - /* 768 GiB to 872 GiB, size of 104 GiB : FREE **/ - -/* 0xDA_0000_0000 - 0xDA_FFFF_FFFF **/ - /* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP **/ - #define RGX_PDSCODEDATA_HEAP_BASE IMG_UINT64_C(0xDA00000000) - #define RGX_PDSCODEDATA_HEAP_SIZE RGX_HEAP_SIZE_4GiB - -/* 0xDB_0000_0000 - 0xDB_FFFF_FFFF **/ - /* 876 GiB to 880 GiB, size of 256 MiB (reserved 4GiB) : BRN **/ - /* HWBRN63142 workaround requires Region Header memory to be at the top - of a 16GiB aligned range. This is so when masked with 0x03FFFFFFFF the - address will avoid aliasing PB addresses. Start at 879.75GiB. Size of 256MiB. */ - #define RGX_RGNHDR_BRN_63142_HEAP_BASE IMG_UINT64_C(0xDBF0000000) - #define RGX_RGNHDR_BRN_63142_HEAP_SIZE RGX_HEAP_SIZE_256MiB - -/* 0xDC_0000_0000 - 0xDF_FFFF_FFFF **/ - /* 880 GiB to 896 GiB, size of 16 GiB : FREE **/ - -/* 0xE0_0000_0000 - 0xE0_FFFF_FFFF **/ - /* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP **/ - #define RGX_USCCODE_HEAP_BASE IMG_UINT64_C(0xE000000000) - #define RGX_USCCODE_HEAP_SIZE RGX_HEAP_SIZE_4GiB - -/* 0xE1_0000_0000 - 0xE1_BFFF_FFFF **/ - /* 900 GiB to 903 GiB, size of 3 GiB : RESERVED **/ - -/* 0xE1_C000_000 - 0xE1_FFFF_FFFF **/ - /* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP **/ - - /* Firmware heaps defined in rgx_heap_firmware.h as they are not present in - application memory contexts, see: - RGX_FIRMWARE_RAW_HEAP_BASE - RGX_FIRMWARE_RAW_HEAP_SIZE - See header for other sub-heaps details - */ - -/* 0xE2_0000_0000 - 0xE3_FFFF_FFFF **/ - /* 904 GiB to 912 GiB, size of 8 GiB : FREE **/ - - /* BRN_65273 VISIBILITY_TEST base 0xE400000000 */ - -/* 0xE4_0000_0000 - 0xE7_FFFF_FFFF **/ - /* 912 GiB to 928 GiB, size 16 GiB : TQ3DPARAMETERS_HEAP **/ - /* Aligned to match RGX_CR_ISP_PIXEL_BASE at 16 GiB */ - #define RGX_TQ3DPARAMETERS_HEAP_BASE IMG_UINT64_C(0xE400000000) - #define RGX_TQ3DPARAMETERS_HEAP_SIZE RGX_HEAP_SIZE_16GiB - -/* 0xE8_0000_0000 - 0xE8_FFFF_FFFF **/ - /* 928 GiB to 932 GiB, size of 4 GiB : FREE **/ - -/* 0xE9_0000_0000 - 0xE9_3FFF_FFFF **/ - /* 932 GiB to 933 GiB, size of 1 GiB : VK_CAPT_REPLAY_HEAP **/ - #define RGX_VK_CAPT_REPLAY_HEAP_BASE IMG_UINT64_C(0xE900000000) - #define RGX_VK_CAPT_REPLAY_HEAP_SIZE RGX_HEAP_SIZE_1GiB - -/* 0xE9_4000_0000 - 0xE9_FFFF_FFFF **/ - /* 933 GiB to 936 GiB, size of 3 GiB : FREE **/ - -/* 0xEA_0000_0000 - 0xEA_0000_0FFF **/ - /* 936 GiB to 937 GiB, size of min heap size : SIGNALS_HEAP **/ - /* CDM Signals heap (31 signals less one reserved for Services). - * Size 960B rounded up to minimum heap size */ - #define RGX_SIGNALS_HEAP_BASE IMG_UINT64_C(0xEA00000000) - #define RGX_SIGNALS_HEAP_SIZE DEVMEM_HEAP_MINIMUM_SIZE - -/* 0xEA_4000_0000 - 0xEA_FFFF_FFFF **/ - /* 937 GiB to 940 GiB, size of 3 GiB : FREE **/ - -/* 0xEB_0000_0000 - 0xEB_FFFF_FFFF **/ - /* 940 GiB to 944 GiB, size of 4 GiB : RESERVED VOLCANIC **/ - -/* 0xEC_0000_0000 - 0xEC_001F_FFFF **/ - /* 944 GiB to 945 GiB, size 2 MiB : FBCDC_HEAP **/ - #define RGX_FBCDC_HEAP_BASE IMG_UINT64_C(0xEC00000000) - #define RGX_FBCDC_HEAP_SIZE RGX_HEAP_SIZE_2MiB - -/* 0xEC_4000_0000 - 0xEC_401F_FFFF **/ - /* 945 GiB to 946 GiB, size 2 MiB : FBCDC_LARGE_HEAP **/ - #define RGX_FBCDC_LARGE_HEAP_BASE IMG_UINT64_C(0xEC40000000) - #define RGX_FBCDC_LARGE_HEAP_SIZE RGX_HEAP_SIZE_2MiB - -/* 0xEC_8000_0000 - 0xED_FFFF_FFFF **/ - /* 946 GiB to 952 GiB, size of 6 GiB : RESERVED VOLCANIC **/ - -/* 0xEE_0000_0000 - 0xEE_3FFF_FFFF **/ - /* 952 GiB to 953 GiB, size of 1 GiB : CMP_MISSION_RMW_HEAP **/ - #define RGX_CMP_MISSION_RMW_HEAP_BASE IMG_UINT64_C(0xEE00000000) - #define RGX_CMP_MISSION_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB - -/* 0xEE_4000_0000 - 0xEE_FFFF_FFFF **/ - /* 953 GiB to 956 GiB, size of 3 GiB : RESERVED **/ - -/* 0xEF_0000_0000 - 0xEF_3FFF_FFFF **/ - /* 956 GiB to 957 GiB, size of 1 GiB : CMP_SAFETY_RMW_HEAP **/ - #define RGX_CMP_SAFETY_RMW_HEAP_BASE IMG_UINT64_C(0xEF00000000) - #define RGX_CMP_SAFETY_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB - -/* 0xEF_4000_0000 - 0xEF_FFFF_FFFF **/ - /* 957 GiB to 960 GiB, size of 3 GiB : RESERVED **/ - -/* 0xF0_0000_0000 - 0xF0_FFFF_FFFF **/ - /* 960 GiB to 964 GiB, size of 4 GiB : TEXTURE_STATE_HEAP (36-bit aligned) */ - #define RGX_TEXTURE_STATE_HEAP_BASE IMG_UINT64_C(0xF000000000) - #define RGX_TEXTURE_STATE_HEAP_SIZE RGX_HEAP_SIZE_4GiB - -/* 0xF1_0000_0000 - 0xF1_FFFF_FFFF **/ - /* 964 GiB to 968 GiB, size of 4 GiB : FREE **/ - -/* 0xF2_0000_0000 - 0xF2_001F_FFFF **/ - /* 968 GiB to 969 GiB, size of 2 MiB : VISIBILITY_TEST_HEAP **/ - #define RGX_VISIBILITY_TEST_HEAP_BASE IMG_UINT64_C(0xF200000000) - #define RGX_VISIBILITY_TEST_HEAP_SIZE RGX_HEAP_SIZE_2MiB - -/* 0xF2_4000_0000 - 0xF2_FFFF_FFFF **/ - /* 969 GiB to 972 GiB, size of 3 GiB : FREE **/ - - /* BRN_65273 MMU_INIA base 0xF800000000 */ - /* BRN_65273 MMU_INIB base 0xF900000000 */ - -/* 0xF3_0000_0000 - 0xFF_FFFF_FFFF **/ - /* 972 GiB to 1024 GiB, size of 52 GiB : FREE **/ - - - -/* 0xFF_FFFF_FFFF ************************************************************/ - -/* End of RGX Device Virtual Address Space definitions */ - -#endif /* RGXHEAPCONFIG_H */ - -/****************************************************************************** - End of file (rgxheapconfig.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig_65273.h b/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig_65273.h deleted file mode 100644 index 31f90fee9d420..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxheapconfig_65273.h +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Device virtual memory map for BRN_65273. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Memory heaps device specific configuration -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXHEAPCONFIG_65273_H -#define RGXHEAPCONFIG_65273_H - -/* - RGX Device Virtual Address Space Definitions - - This file defines the RGX virtual address replacement heaps that are used in - in application memory contexts for BRN_65273. - - The heaps defined for BRN_65273 _replace_ the non-BRN equivalents when this - BRN WA is active on affected cores. This is different to most other BRNs - and hence has been given its own header file for clarity. The SVM_HEAP is - also disabled and unavailable when the WA is active. This is reflected - in the device connection capability bits returned to user space. - NOTE: All regular heaps in rgxheapconfig.h greater than 1GB require - a BRN_65273 WA heap. - - Base addresses must have to be a multiple of 4MiB - Heaps must not start at 0x0000000000, as this is reserved for internal - use within device memory layer. - Range comments, those starting in column 0 below are a section heading of - sorts and are above the heaps in that range. -*/ - - -/* 0x00_0000_0000 ************************************************************/ - -/* 0x00_0001_0000 - 0x00_3FFF_FFFF **/ - /* HWBRN65273 workaround requires TQ memory to start at 64 KiB and use a - * unique single 0.99GiB PCE entry. */ - #define RGX_TQ3DPARAMETERS_BRN_65273_HEAP_BASE IMG_UINT64_C(0x0000010000) - #define RGX_TQ3DPARAMETERS_BRN_65273_HEAP_SIZE (RGX_HEAP_SIZE_1GiB - RGX_HEAP_SIZE_64KiB) - -/* 0x65_C000_0000 - 0x66_3FFF_FFFF **/ - /* HWBRN65273 workaround requires General Heap to use a unique PCE entry for each GiB in range */ - #define RGX_GENERAL_BRN_65273_HEAP_BASE IMG_UINT64_C(0x65C0000000) - #define RGX_GENERAL_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2GiB - -/* 0x73_C000_0000 - 0x74_3FFF_FFFF **/ - /* HWBRN65273 workaround requires Non4K memory to use a unique PCE entry for each GiB in range */ - #define RGX_GENERAL_NON4K_BRN_65273_HEAP_BASE IMG_UINT64_C(0x73C0000000) - #define RGX_GENERAL_NON4K_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2GiB - - -/* 0x80_0000_0000 ************************************************************/ - -/* 0xA8_0000_0000 - 0xA8_3FFF_FFFF **/ - /* HWBRN65273 workaround requires PDS memory to use a unique single 1GiB PCE entry. */ - #define RGX_PDSCODEDATA_BRN_65273_HEAP_BASE IMG_UINT64_C(0xA800000000) - #define RGX_PDSCODEDATA_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB - -/* 0xBA_0000_0000 - 0xBA_3FFF_FFFF **/ - /* HWBRN65273 workaround requires USC memory to use a unique single 1GiB PCE entry. */ - #define RGX_USCCODE_BRN_65273_HEAP_BASE IMG_UINT64_C(0xBA00000000) - #define RGX_USCCODE_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB - - -/* 0xC0_0000_0000 ************************************************************/ - -/* 0xE4_0000_0000 - 0xE4_001F_FFFF **/ - /* HWBRN65273 workaround requires USC memory to use a unique single 1GiB PCE entry. */ - #define RGX_VISIBILITY_TEST_BRN_65273_HEAP_BASE IMG_UINT64_C(0xE400000000) - #define RGX_VISIBILITY_TEST_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2MiB - -/* 0xF8_0000_0000 - 0xF9_FFFF_FFFF **/ - /* HWBRN65273 workaround requires two Region Header buffers 4GiB apart. */ - #define RGX_MMU_INIA_BRN_65273_HEAP_BASE IMG_UINT64_C(0xF800000000) - #define RGX_MMU_INIA_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB - #define RGX_MMU_INIB_BRN_65273_HEAP_BASE IMG_UINT64_C(0xF900000000) - #define RGX_MMU_INIB_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB - - -/* 0xFF_FFFF_FFFF ************************************************************/ - -/* End of RGX Device Virtual Address Space definitions */ - -#endif /* RGXHEAPCONFIG_65273_H */ - -/****************************************************************************** - End of file (rgxheapconfig_65273.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.c b/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.c deleted file mode 100644 index a6e2dd420eaf6..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.c +++ /dev/null @@ -1,694 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HW Performance implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX HW Performance implementation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ /**************************************************************************/ - -//#define PVR_DPF_FUNCTION_TRACE_ON 1 -#undef PVR_DPF_FUNCTION_TRACE_ON - -#include "img_defs.h" -#include "pvr_debug.h" -#include "rgxdevice.h" -#include "pvrsrv_error.h" -#include "pvr_notifier.h" -#include "osfunc.h" -#include "allocmem.h" - -#include "pvrsrv.h" -#include "pvrsrv_tlstreams.h" -#include "pvrsrv_tlcommon.h" -#include "tlclient.h" -#include "tlstream.h" - -#include "rgxhwperf.h" -#include "rgxapi_km.h" -#include "rgxfwutils.h" -#include "rgxtimecorr.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "pdump_km.h" -#include "pvrsrv_apphint.h" -#include "process_stats.h" -#include "rgx_hwperf_table.h" -#include "rgxinit.h" - -#include "info_page_defs.h" - -/* This is defined by default to enable producer callbacks. - * Clients of the TL interface can disable the use of the callback - * with PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK. */ -#define SUPPORT_TL_PRODUCER_CALLBACK 1 - -/* Maximum enum value to prevent access to RGX_HWPERF_STREAM_ID2_CLIENT stream */ -#define RGX_HWPERF_MAX_STREAM_ID (RGX_HWPERF_STREAM_ID2_CLIENT) - -/* Defines size of buffers returned from acquire/release calls */ -#define FW_STREAM_BUFFER_SIZE (0x80000) -#define HOST_STREAM_BUFFER_SIZE (0x20000) - -/* Must be at least as large as two tl packets of maximum size */ -static_assert(HOST_STREAM_BUFFER_SIZE >= (PVRSRVTL_MAX_PACKET_SIZE<<1), - "HOST_STREAM_BUFFER_SIZE is less than (PVRSRVTL_MAX_PACKET_SIZE<<1)"); -static_assert(FW_STREAM_BUFFER_SIZE >= (PVRSRVTL_MAX_PACKET_SIZE<<1), - "FW_STREAM_BUFFER_SIZE is less than (PVRSRVTL_MAX_PACKET_SIZE<<1)"); - -static inline IMG_UINT32 -RGXHWPerfGetPackets(IMG_UINT32 ui32BytesExp, - IMG_UINT32 ui32AllowedSize, - RGX_PHWPERF_V2_PACKET_HDR psCurPkt ) -{ - IMG_UINT32 sizeSum = 0; - - /* Traverse the array to find how many packets will fit in the available space. */ - while ( sizeSum < ui32BytesExp && - sizeSum + RGX_HWPERF_GET_SIZE(psCurPkt) < ui32AllowedSize ) - { - sizeSum += RGX_HWPERF_GET_SIZE(psCurPkt); - psCurPkt = RGX_HWPERF_GET_NEXT_PACKET(psCurPkt); - } - - return sizeSum; -} - -static inline void -RGXSuspendHWPerfL2DataCopy(PVRSRV_RGXDEV_INFO* psDeviceInfo, - IMG_BOOL bIsReaderConnected) -{ - if (!bIsReaderConnected) - { - PVR_DPF((PVR_DBG_WARNING, "%s : HWPerf FW events enabled but host buffer for FW events is full " - "and no reader is currently connected, suspending event collection. " - "Connect a reader or restart driver to avoid event loss.", __func__)); - psDeviceInfo->bSuspendHWPerfL2DataCopy = IMG_TRUE; - } -} - -/****************************************************************************** - * RGX HW Performance Profiling Server API(s) - *****************************************************************************/ - -static IMG_BOOL RGXServerFeatureFlagsToHWPerfFlagsAddBlock( - RGX_HWPERF_BVNC_BLOCK * const psBlocks, - IMG_UINT16 * const pui16Count, - const IMG_UINT16 ui16BlockID, /* see RGX_HWPERF_CNTBLK_ID */ - const IMG_UINT16 ui16NumCounters, - const IMG_UINT16 ui16NumBlocks) -{ - const IMG_UINT16 ui16Count = *pui16Count; - - if (ui16Count < RGX_HWPERF_MAX_BVNC_BLOCK_LEN) - { - RGX_HWPERF_BVNC_BLOCK * const psBlock = &psBlocks[ui16Count]; - - /* If the GROUP is non-zero, convert from e.g. RGX_CNTBLK_ID_USC0 to RGX_CNTBLK_ID_USC_ALL. The table stores the former (plus the - number of blocks and counters) but PVRScopeServices expects the latter (plus the number of blocks and counters). The conversion - could always be moved to PVRScopeServices, but it's less code this way. */ - psBlock->ui16BlockID = (ui16BlockID & RGX_CNTBLK_ID_GROUP_MASK) ? (ui16BlockID | RGX_CNTBLK_ID_UNIT_ALL_MASK) : ui16BlockID; - if ((ui16BlockID & RGX_CNTBLK_ID_DA_MASK) == RGX_CNTBLK_ID_DA_MASK) - { - psBlock->ui16NumCounters = RGX_CNTBLK_COUNTERS_MAX; - } - else - { - psBlock->ui16NumCounters = ui16NumCounters; - } - psBlock->ui16NumBlocks = ui16NumBlocks; - - *pui16Count = ui16Count + 1; - return IMG_TRUE; - } - return IMG_FALSE; -} - -PVRSRV_ERROR RGXServerFeatureFlagsToHWPerfFlags(PVRSRV_RGXDEV_INFO *psDevInfo, RGX_HWPERF_BVNC *psBVNC) -{ - IMG_PCHAR pszBVNC; - PVR_LOG_RETURN_IF_FALSE((NULL != psDevInfo), "psDevInfo invalid", PVRSRV_ERROR_INVALID_PARAMS); - - if ((pszBVNC = RGXDevBVNCString(psDevInfo))) - { - size_t uiStringLength = OSStringNLength(pszBVNC, RGX_HWPERF_MAX_BVNC_LEN - 1); - OSStringLCopy(psBVNC->aszBvncString, pszBVNC, uiStringLength + 1); - memset(&psBVNC->aszBvncString[uiStringLength], 0, RGX_HWPERF_MAX_BVNC_LEN - uiStringLength); - } - else - { - *psBVNC->aszBvncString = 0; - } - - psBVNC->ui32BvncKmFeatureFlags = 0x0; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PERFBUS)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_PERFBUS_FLAG; - } -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_S7_TOP_INFRASTRUCTURE_FLAG; - } -#endif -#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XT_TOP_INFRASTRUCTURE)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_XT_TOP_INFRASTRUCTURE_FLAG; - } -#endif -#if defined(RGX_FEATURE_PERF_COUNTER_BATCH_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PERF_COUNTER_BATCH)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_PERF_COUNTER_BATCH_FLAG; - } -#endif - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, ROGUEXE)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_ROGUEXE_FLAG; - } -#if defined(RGX_FEATURE_DUST_POWER_ISLAND_S7_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, DUST_POWER_ISLAND_S7)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_DUST_POWER_ISLAND_S7_FLAG; - } -#endif - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PBE2_IN_XE)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_PBE2_IN_XE_FLAG; - } - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_MULTICORE_FLAG; - } - -#ifdef SUPPORT_WORKLOAD_ESTIMATION - /* Not a part of BVNC feature line and so doesn't need the feature supported check */ - psBVNC->ui32BvncKmFeatureFlags |= RGX_HWPERF_FEATURE_WORKLOAD_ESTIMATION; -#endif - - /* Define the HW counter block counts. */ - { - RGX_HWPERF_BVNC_BLOCK * const psBlocks = psBVNC->aBvncBlocks; - IMG_UINT16 * const pui16Count = &psBVNC->ui16BvncBlocks; - const RGXFW_HWPERF_CNTBLK_TYPE_MODEL *asCntBlkTypeModel; - const IMG_UINT32 ui32CntBlkModelLen = RGXGetHWPerfBlockConfig(&asCntBlkTypeModel); - IMG_UINT32 ui32BlkCfgIdx; - size_t uiCount; - IMG_BOOL bOk = IMG_TRUE; - - // Initialise to zero blocks - *pui16Count = 0; - - // Add all the blocks - for (ui32BlkCfgIdx = 0; ui32BlkCfgIdx < ui32CntBlkModelLen; ui32BlkCfgIdx++) - { - const RGXFW_HWPERF_CNTBLK_TYPE_MODEL * const psCntBlkInfo = &asCntBlkTypeModel[ui32BlkCfgIdx]; - RGX_HWPERF_CNTBLK_RT_INFO sCntBlkRtInfo; - /* psCntBlkInfo->ui8NumUnits gives compile-time info. For BVNC agnosticism, we use this: */ - if (psCntBlkInfo->pfnIsBlkPresent(psCntBlkInfo, psDevInfo, &sCntBlkRtInfo)) - { - bOk &= RGXServerFeatureFlagsToHWPerfFlagsAddBlock(psBlocks, pui16Count, psCntBlkInfo->ui32CntBlkIdBase, psCntBlkInfo->ui8NumCounters, sCntBlkRtInfo.ui32NumUnits); - } - } - - /* If this fails, consider why the static_assert didn't fail, and consider increasing RGX_HWPERF_MAX_BVNC_BLOCK_LEN */ - PVR_ASSERT(bOk); - - // Zero the remaining entries - uiCount = *pui16Count; - OSDeviceMemSet(&psBlocks[uiCount], 0, (RGX_HWPERF_MAX_BVNC_BLOCK_LEN - uiCount) * sizeof(*psBlocks)); - } - - return PVRSRV_OK; -} - -/* - PVRSRVRGXConfigMuxHWPerfCountersKM - */ -PVRSRV_ERROR PVRSRVRGXConfigMuxHWPerfCountersKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32ArrayLen, - RGX_HWPERF_CONFIG_MUX_CNTBLK *psBlockConfigs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sKccbCmd; - DEVMEM_MEMDESC* psFwBlkConfigsMemDesc; - RGX_HWPERF_CONFIG_MUX_CNTBLK* psFwArray; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_RGXDEV_INFO *psDevice; - - PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", - PVRSRV_ERROR_INVALID_PARAMS); - psDevice = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - PVR_LOG_RETURN_IF_FALSE(ui32ArrayLen > 0, "ui32ArrayLen is 0", - PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE(psBlockConfigs != NULL, "psBlockConfigs is NULL", - PVRSRV_ERROR_INVALID_PARAMS); - - PVR_DPF_ENTERED; - - /* Fill in the command structure with the parameters needed - */ - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS; - sKccbCmd.uCmdData.sHWPerfCfgEnableBlks.ui32NumBlocks = ui32ArrayLen; - - /* used for passing counters config to the Firmware, write-only for the CPU */ - eError = DevmemFwAllocate(psDevice, - sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK)*ui32ArrayLen, - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwHWPerfCountersConfigBlock", - &psFwBlkConfigsMemDesc); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemFwAllocate"); - - eError = RGXSetFirmwareAddress(&sKccbCmd.uCmdData.sHWPerfCfgEnableBlks.sBlockConfigs, - psFwBlkConfigsMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", fail1); - - eError = DevmemAcquireCpuVirtAddr(psFwBlkConfigsMemDesc, (void **)&psFwArray); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", fail2); - - OSCachedMemCopyWMB(psFwArray, psBlockConfigs, sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK)*ui32ArrayLen); - DevmemPDumpLoadMem(psFwBlkConfigsMemDesc, - 0, - sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK)*ui32ArrayLen, - PDUMP_FLAGS_CONTINUOUS); - - /*PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigMuxHWPerfCountersKM parameters set, calling FW"));*/ - - /* Ask the FW to carry out the HWPerf configuration command - */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", fail2); - - /*PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigMuxHWPerfCountersKM command scheduled for FW"));*/ - - /* Wait for FW to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevice, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", fail3); - - /* Release temporary memory used for block configuration - */ - RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc); - DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc); - DevmemFwUnmapAndFree(psDevice, psFwBlkConfigsMemDesc); - - /*PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigMuxHWPerfCountersKM firmware completed"));*/ - - PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks configured and ENABLED", ui32ArrayLen)); - - PVR_DPF_RETURN_OK; - -fail3: - DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc); -fail2: - RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc); -fail1: - DevmemFwUnmapAndFree(psDevice, psFwBlkConfigsMemDesc); - - PVR_DPF_RETURN_RC(eError); -} - - -/* - PVRSRVRGXConfigCustomCountersReadingHWPerfKM - */ -PVRSRV_ERROR PVRSRVRGXConfigCustomCountersKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT16 ui16CustomBlockID, - IMG_UINT16 ui16NumCustomCounters, - IMG_UINT32 * pui32CustomCounterIDs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sKccbCmd; - DEVMEM_MEMDESC* psFwSelectCntrsMemDesc = NULL; - IMG_UINT32* psFwArray; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_RGXDEV_INFO *psDevice = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - PVR_DPF_ENTERED; - - PVR_ASSERT(psDeviceNode); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVRGXSelectCustomCountersKM: configure block %u to read %u counters", ui16CustomBlockID, ui16NumCustomCounters)); - - /* Fill in the command structure with the parameters needed */ - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS; - sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.ui16NumCounters = ui16NumCustomCounters; - sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.ui16CustomBlock = ui16CustomBlockID; - - if (ui16NumCustomCounters > 0) - { - PVR_ASSERT(pui32CustomCounterIDs); - - /* used for passing counters config to the Firmware, write-only for the CPU */ - eError = DevmemFwAllocate(psDevice, - sizeof(IMG_UINT32) * ui16NumCustomCounters, - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwHWPerfConfigCustomCounters", - &psFwSelectCntrsMemDesc); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemFwAllocate"); - - eError = RGXSetFirmwareAddress(&sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.sCustomCounterIDs, - psFwSelectCntrsMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", fail1); - - eError = DevmemAcquireCpuVirtAddr(psFwSelectCntrsMemDesc, (void **)&psFwArray); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", fail2); - - OSCachedMemCopyWMB(psFwArray, pui32CustomCounterIDs, sizeof(IMG_UINT32) * ui16NumCustomCounters); - DevmemPDumpLoadMem(psFwSelectCntrsMemDesc, - 0, - sizeof(IMG_UINT32) * ui16NumCustomCounters, - PDUMP_FLAGS_CONTINUOUS); - } - - /* Push in the KCCB the command to configure the custom counters block */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", fail3); - - PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXSelectCustomCountersKM: Command scheduled")); - - /* Wait for FW to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevice, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", fail3); - - PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXSelectCustomCountersKM: FW operation completed")); - - if (ui16NumCustomCounters > 0) - { - /* Release temporary memory used for block configuration */ - RGXUnsetFirmwareAddress(psFwSelectCntrsMemDesc); - DevmemReleaseCpuVirtAddr(psFwSelectCntrsMemDesc); - DevmemFwUnmapAndFree(psDevice, psFwSelectCntrsMemDesc); - } - - PVR_DPF((PVR_DBG_MESSAGE, "HWPerf custom counters %u reading will be sent with the next HW events", ui16NumCustomCounters)); - - PVR_DPF_RETURN_OK; - -fail3: - if (psFwSelectCntrsMemDesc) - { - DevmemReleaseCpuVirtAddr(psFwSelectCntrsMemDesc); - } -fail2: - if (psFwSelectCntrsMemDesc) - { - RGXUnsetFirmwareAddress(psFwSelectCntrsMemDesc); - } -fail1: - if (psFwSelectCntrsMemDesc) - { - DevmemFwUnmapAndFree(psDevice, psFwSelectCntrsMemDesc); - } - - PVR_DPF_RETURN_RC(eError); -} - -/* - PVRSRVRGXConfigureHWPerfBlocksKM - */ -PVRSRV_ERROR PVRSRVRGXConfigureHWPerfBlocksKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32CtrlWord, - IMG_UINT32 ui32ArrayLen, - RGX_HWPERF_CONFIG_CNTBLK * psBlockConfigs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sKccbCmd; - DEVMEM_MEMDESC *psFwBlkConfigsMemDesc; - RGX_HWPERF_CONFIG_CNTBLK *psFwArray; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_RGXDEV_INFO *psDevice; - - PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", - PVRSRV_ERROR_INVALID_PARAMS); - - psDevice = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(ui32CtrlWord); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - PVR_LOG_RETURN_IF_FALSE(ui32ArrayLen > 0, "ui32ArrayLen is 0", - PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE(psBlockConfigs != NULL, "psBlockConfigs is NULL", - PVRSRV_ERROR_INVALID_PARAMS); - - PVR_DPF_ENTERED; - - /* Fill in the command structure with the parameters needed */ - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS; - sKccbCmd.uCmdData.sHWPerfCfgDABlks.ui32NumBlocks = ui32ArrayLen; - - /* used for passing counters config to the Firmware, write-only for the CPU */ - eError = DevmemFwAllocate(psDevice, - sizeof(RGX_HWPERF_CONFIG_CNTBLK) * ui32ArrayLen, - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwHWPerfCountersDAConfigBlock", - &psFwBlkConfigsMemDesc); - PVR_LOG_RETURN_IF_ERROR(eError, "DevmemFwAllocate"); - - eError = RGXSetFirmwareAddress(&sKccbCmd.uCmdData.sHWPerfCfgDABlks.sBlockConfigs, - psFwBlkConfigsMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", fail1); - - eError = DevmemAcquireCpuVirtAddr(psFwBlkConfigsMemDesc, (void **)&psFwArray); - PVR_LOG_GOTO_IF_ERROR(eError, "DevMemAcquireCpuVirtAddr", fail2); - - OSCachedMemCopyWMB(psFwArray, psBlockConfigs, sizeof(RGX_HWPERF_CONFIG_CNTBLK)*ui32ArrayLen); - DevmemPDumpLoadMem(psFwBlkConfigsMemDesc, - 0, - sizeof(RGX_HWPERF_CONFIG_CNTBLK)*ui32ArrayLen, - PDUMP_FLAGS_CONTINUOUS); - - /* Ask the FW to carry out the HWPerf configuration command. */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - - PVR_LOG_GOTO_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot", fail2); - - /* Wait for FW to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevice, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", fail3); - - /* Release temporary memory used for block configuration. */ - RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc); - DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc); - DevmemFwUnmapAndFree(psDevice, psFwBlkConfigsMemDesc); - - PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks configured and ENABLED", - ui32ArrayLen)); - - PVR_DPF_RETURN_OK; - -fail3: - DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc); - -fail2: - RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc); - -fail1: - DevmemFwUnmapAndFree(psDevice, psFwBlkConfigsMemDesc); - - PVR_DPF_RETURN_RC (eError); -} - -/****************************************************************************** - * Currently only implemented on Linux. Feature can be enabled to provide - * an interface to 3rd-party kernel modules that wish to access the - * HWPerf data. The API is documented in the rgxapi_km.h header and - * the rgx_hwperf* headers. - *****************************************************************************/ - -/* Internal HWPerf kernel connection/device data object to track the state - * of a client session. - */ -typedef struct -{ - PVRSRV_DEVICE_NODE* psRgxDevNode; - PVRSRV_RGXDEV_INFO* psRgxDevInfo; - - /* TL Open/close state */ - IMG_HANDLE hSD[RGX_HWPERF_MAX_STREAM_ID]; - - /* TL Acquire/release state */ - IMG_PBYTE pHwpBuf[RGX_HWPERF_MAX_STREAM_ID]; /*!< buffer returned to user in acquire call */ - IMG_PBYTE pHwpBufEnd[RGX_HWPERF_MAX_STREAM_ID]; /*!< pointer to end of HwpBuf */ - IMG_PBYTE pTlBuf[RGX_HWPERF_MAX_STREAM_ID]; /*!< buffer obtained via TlAcquireData */ - IMG_PBYTE pTlBufPos[RGX_HWPERF_MAX_STREAM_ID]; /*!< initial position in TlBuf to acquire packets */ - IMG_PBYTE pTlBufRead[RGX_HWPERF_MAX_STREAM_ID]; /*!< pointer to the last packet read */ - IMG_UINT32 ui32AcqDataLen[RGX_HWPERF_MAX_STREAM_ID]; /*!< length of acquired TlBuf */ - IMG_BOOL bRelease[RGX_HWPERF_MAX_STREAM_ID]; /*!< used to determine whether or not to release currently held TlBuf */ - - -} RGX_KM_HWPERF_DEVDATA; - -PVRSRV_ERROR RGXHWPerfConfigMuxCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - RGX_HWPERF_CONFIG_MUX_CNTBLK *asBlockConfigs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_KM_HWPERF_DEVDATA* psDevData; - RGX_HWPERF_DEVICE *psHWPerfDev; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Validate input argument values supplied by the caller */ - if (!psHWPerfConnection || ui32NumBlocks==0 || !asBlockConfigs) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32NumBlocks > RGXFWIF_HWPERF_CTRL_BLKS_MAX) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - - while (psHWPerfDev) - { - psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - - /* Call the internal server API */ - eError = PVRSRVRGXConfigMuxHWPerfCountersKM(NULL, - psDevData->psRgxDevNode, - ui32NumBlocks, - asBlockConfigs); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM"); - - psHWPerfDev = psHWPerfDev->psNext; - } - - return eError; -} - - -PVRSRV_ERROR RGXHWPerfConfigureAndEnableCustomCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT16 ui16CustomBlockID, - IMG_UINT16 ui16NumCustomCounters, - IMG_UINT32 *pui32CustomCounterIDs) -{ - PVRSRV_ERROR eError; - RGX_HWPERF_DEVICE *psHWPerfDev; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Validate input arguments supplied by the caller */ - PVR_LOG_RETURN_IF_FALSE((NULL != psHWPerfConnection), "psHWPerfConnection invalid", - PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE((0 != ui16NumCustomCounters), "uiNumBlocks invalid", - PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE((NULL != pui32CustomCounterIDs),"asBlockConfigs invalid", - PVRSRV_ERROR_INVALID_PARAMS); - - /* Check # of blocks */ - PVR_LOG_RETURN_IF_FALSE((!(ui16CustomBlockID > RGX_HWPERF_MAX_CUSTOM_BLKS)),"ui16CustomBlockID invalid", - PVRSRV_ERROR_INVALID_PARAMS); - - /* Check # of counters */ - PVR_LOG_RETURN_IF_FALSE((!(ui16NumCustomCounters > RGX_HWPERF_MAX_CUSTOM_CNTRS)),"ui16NumCustomCounters invalid", - PVRSRV_ERROR_INVALID_PARAMS); - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - - while (psHWPerfDev) - { - RGX_KM_HWPERF_DEVDATA *psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - - eError = PVRSRVRGXConfigCustomCountersKM(NULL, - psDevData->psRgxDevNode, - ui16CustomBlockID, ui16NumCustomCounters, pui32CustomCounterIDs); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVRGXCtrlCustHWPerfKM"); - - psHWPerfDev = psHWPerfDev->psNext; - } - - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (rgxhwperf.c) - ******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.h b/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.h deleted file mode 100644 index 8819fe4f26827..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HW Performance header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX HWPerf functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXHWPERF_H_ -#define RGXHWPERF_H_ - -#include "rgxhwperf_common.h" - -/****************************************************************************** - * RGX HW Performance Profiling API(s) Rogue specific - *****************************************************************************/ - -PVRSRV_ERROR PVRSRVRGXConfigMuxHWPerfCountersKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32ArrayLen, - RGX_HWPERF_CONFIG_MUX_CNTBLK *psBlockConfigs); - - -PVRSRV_ERROR PVRSRVRGXConfigCustomCountersKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT16 ui16CustomBlockID, - IMG_UINT16 ui16NumCustomCounters, - IMG_UINT32 * pui32CustomCounterIDs); - -PVRSRV_ERROR PVRSRVRGXConfigureHWPerfBlocksKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32CtrlWord, - IMG_UINT32 ui32ArrayLen, - RGX_HWPERF_CONFIG_CNTBLK * psBlockConfigs); - -#endif /* RGXHWPERF_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.c b/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.c deleted file mode 100644 index efa43c613272f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.c +++ /dev/null @@ -1,3712 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HW Performance implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX HW Performance implementation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. - */ /**************************************************************************/ - -//#define PVR_DPF_FUNCTION_TRACE_ON 1 -#undef PVR_DPF_FUNCTION_TRACE_ON - -#include "img_defs.h" -#include "pvr_debug.h" -#include "rgxdevice.h" -#include "pvrsrv_error.h" -#include "pvr_notifier.h" -#include "osfunc.h" -#include "allocmem.h" - -#include "pvrsrv.h" -#include "pvrsrv_tlstreams.h" -#include "pvrsrv_tlcommon.h" -#include "tlclient.h" -#include "tlstream.h" - -#include "rgxhwperf.h" -#include "rgxapi_km.h" -#include "rgxfwutils.h" -#include "rgxtimecorr.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "pdump_km.h" -#include "pvrsrv_apphint.h" -#include "process_stats.h" -#include "rgx_hwperf_table.h" -#include "rgxinit.h" - -#include "info_page_defs.h" - -/* This is defined by default to enable producer callbacks. - * Clients of the TL interface can disable the use of the callback - * with PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK. */ -#define SUPPORT_TL_PRODUCER_CALLBACK 1 - -/* Maximum enum value to prevent access to RGX_HWPERF_STREAM_ID2_CLIENT stream */ -#define RGX_HWPERF_MAX_STREAM_ID (RGX_HWPERF_STREAM_ID2_CLIENT) - -/* Defines size of buffers returned from acquire/release calls */ -#define FW_STREAM_BUFFER_SIZE (0x80000) -#define HOST_STREAM_BUFFER_SIZE (0x20000) - -/* Must be at least as large as two tl packets of maximum size */ -static_assert(HOST_STREAM_BUFFER_SIZE >= (PVRSRVTL_MAX_PACKET_SIZE<<1), - "HOST_STREAM_BUFFER_SIZE is less than (PVRSRVTL_MAX_PACKET_SIZE<<1)"); -static_assert(FW_STREAM_BUFFER_SIZE >= (PVRSRVTL_MAX_PACKET_SIZE<<1), - "FW_STREAM_BUFFER_SIZE is less than (PVRSRVTL_MAX_PACKET_SIZE<<1)"); - -IMG_INTERNAL /*static inline*/ IMG_UINT32 RGXGetHWPerfBlockConfig(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL **); - -static inline IMG_UINT32 -RGXHWPerfGetPackets(IMG_UINT32 ui32BytesExp, - IMG_UINT32 ui32AllowedSize, - RGX_PHWPERF_V2_PACKET_HDR psCurPkt ) -{ - IMG_UINT32 sizeSum = 0; - - /* Traverse the array to find how many packets will fit in the available space. */ - while ( sizeSum < ui32BytesExp && - sizeSum + RGX_HWPERF_GET_SIZE(psCurPkt) < ui32AllowedSize ) - { - sizeSum += RGX_HWPERF_GET_SIZE(psCurPkt); - psCurPkt = RGX_HWPERF_GET_NEXT_PACKET(psCurPkt); - } - - return sizeSum; -} - -static inline void -RGXSuspendHWPerfL2DataCopy(PVRSRV_RGXDEV_INFO* psDeviceInfo, - IMG_BOOL bIsReaderConnected) -{ - if (!bIsReaderConnected) - { - PVR_DPF((PVR_DBG_WARNING, "%s : HWPerf FW events enabled but host buffer for FW events is full " - "and no reader is currently connected, suspending event collection. " - "Connect a reader or restart driver to avoid event loss.", __func__)); - psDeviceInfo->bSuspendHWPerfL2DataCopy = IMG_TRUE; - } -} - -/* - RGXHWPerfCopyDataL1toL2 - */ -static IMG_UINT32 RGXHWPerfCopyDataL1toL2(PVRSRV_RGXDEV_INFO* psDeviceInfo, - IMG_BYTE *pbFwBuffer, - IMG_UINT32 ui32BytesExp) -{ - IMG_HANDLE hHWPerfStream = psDeviceInfo->hHWPerfStream; - IMG_BYTE * pbL2Buffer; - IMG_UINT32 ui32L2BufFree; - IMG_UINT32 ui32BytesCopied = 0; - IMG_UINT32 ui32BytesExpMin = RGX_HWPERF_GET_SIZE(RGX_HWPERF_GET_PACKET(pbFwBuffer)); - PVRSRV_ERROR eError; - IMG_BOOL bIsReaderConnected; - - /* HWPERF_MISR_FUNC_DEBUG enables debug code for investigating HWPerf issues */ -#ifdef HWPERF_MISR_FUNC_DEBUG - static IMG_UINT32 gui32Ordinal = IMG_UINT32_MAX; -#endif - - PVR_DPF_ENTERED; - -#ifdef HWPERF_MISR_FUNC_DEBUG - PVR_DPF((PVR_DBG_VERBOSE, "EVENTS to copy from 0x%p length:%05d", - pbFwBuffer, ui32BytesExp)); -#endif - -#ifdef HWPERF_MISR_FUNC_DEBUG - { - /* Check the incoming buffer of data has not lost any packets */ - IMG_BYTE *pbFwBufferIter = pbFwBuffer; - IMG_BYTE *pbFwBufferEnd = pbFwBuffer+ui32BytesExp; - do - { - RGX_HWPERF_V2_PACKET_HDR *asCurPos = RGX_HWPERF_GET_PACKET(pbFwBufferIter); - IMG_UINT32 ui32CurOrdinal = asCurPos->ui32Ordinal; - if (gui32Ordinal != IMG_UINT32_MAX) - { - if ((gui32Ordinal+1) != ui32CurOrdinal) - { - if (gui32Ordinal < ui32CurOrdinal) - { - PVR_DPF((PVR_DBG_WARNING, - "HWPerf [%p] packets lost (%u packets) between ordinal %u...%u", - pbFwBufferIter, - ui32CurOrdinal - gui32Ordinal - 1, - gui32Ordinal, - ui32CurOrdinal)); - } - else - { - PVR_DPF((PVR_DBG_WARNING, - "HWPerf [%p] packet ordinal out of sequence last: %u, current: %u", - pbFwBufferIter, - gui32Ordinal, - ui32CurOrdinal)); - } - } - } - gui32Ordinal = asCurPos->ui32Ordinal; - pbFwBufferIter += RGX_HWPERF_GET_SIZE(asCurPos); - } while (pbFwBufferIter < pbFwBufferEnd); - } -#endif - - if (ui32BytesExp > psDeviceInfo->ui32L2BufMaxPacketSize) - { - IMG_UINT32 sizeSum = RGXHWPerfGetPackets(ui32BytesExp, - psDeviceInfo->ui32L2BufMaxPacketSize, - RGX_HWPERF_GET_PACKET(pbFwBuffer)); - - if (0 != sizeSum) - { - ui32BytesExp = sizeSum; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "Failed to write data into host buffer as " - "packet is too big and hence it breaches TL " - "packet size limit (TLBufferSize / 2.5)")); - goto e0; - } - } - - /* Try submitting all data in one TL packet. */ - eError = TLStreamReserve2(hHWPerfStream, - &pbL2Buffer, - (size_t)ui32BytesExp, ui32BytesExpMin, - &ui32L2BufFree, &bIsReaderConnected); - if ( eError == PVRSRV_OK ) - { - OSDeviceMemCopy( pbL2Buffer, pbFwBuffer, (size_t)ui32BytesExp ); - eError = TLStreamCommit(hHWPerfStream, (size_t)ui32BytesExp); - if ( eError != PVRSRV_OK ) - { - PVR_DPF((PVR_DBG_ERROR, - "TLStreamCommit() failed (%d) in %s(), unable to copy packet from L1 to L2 buffer", - eError, __func__)); - goto e0; - } - /* Data were successfully written */ - ui32BytesCopied = ui32BytesExp; - } - else if (eError == PVRSRV_ERROR_STREAM_FULL) - { - /* There was not enough space for all data, copy as much as possible */ - IMG_UINT32 sizeSum = RGXHWPerfGetPackets(ui32BytesExp, ui32L2BufFree, RGX_HWPERF_GET_PACKET(pbFwBuffer)); - - PVR_DPF((PVR_DBG_MESSAGE, "Unable to reserve space (%d) in host buffer on first attempt, remaining free space: %d", ui32BytesExp, ui32L2BufFree)); - - if ( 0 != sizeSum ) - { - eError = TLStreamReserve( hHWPerfStream, &pbL2Buffer, (size_t)sizeSum); - - if ( eError == PVRSRV_OK ) - { - OSDeviceMemCopy( pbL2Buffer, pbFwBuffer, (size_t)sizeSum ); - eError = TLStreamCommit(hHWPerfStream, (size_t)sizeSum); - if ( eError != PVRSRV_OK ) - { - PVR_DPF((PVR_DBG_ERROR, - "TLStreamCommit() failed (%d) in %s(), unable to copy packet from L1 to L2 buffer", - eError, __func__)); - goto e0; - } - /* sizeSum bytes of hwperf packets have been successfully written */ - ui32BytesCopied = sizeSum; - } - else if ( PVRSRV_ERROR_STREAM_FULL == eError ) - { - PVR_DPF((PVR_DBG_WARNING, "Cannot write HWPerf packet into host buffer, check data in case of packet loss, remaining free space: %d", ui32L2BufFree)); - RGXSuspendHWPerfL2DataCopy(psDeviceInfo, bIsReaderConnected); - } - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "Cannot find space in host buffer, check data in case of packet loss, remaining free space: %d", ui32L2BufFree)); - RGXSuspendHWPerfL2DataCopy(psDeviceInfo, bIsReaderConnected); - } - } - if ( PVRSRV_OK != eError && /* Some other error occurred */ - PVRSRV_ERROR_STREAM_FULL != eError ) /* Full error handled by caller, we returning the copied bytes count to caller */ - { - PVR_DPF((PVR_DBG_ERROR, - "HWPerf enabled: Unexpected Error ( %d ) while copying FW buffer to TL buffer.", - eError)); - } - -e0: - /* Return the remaining packets left to be transported. */ - PVR_DPF_RETURN_VAL(ui32BytesCopied); -} - - -static INLINE IMG_UINT32 RGXHWPerfAdvanceRIdx( - const IMG_UINT32 ui32BufSize, - const IMG_UINT32 ui32Pos, - const IMG_UINT32 ui32Size) -{ - return ( ui32Pos + ui32Size < ui32BufSize ? ui32Pos + ui32Size : 0 ); -} - - -/* - RGXHWPerfDataStore - */ -static IMG_UINT32 RGXHWPerfDataStore(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - IMG_BYTE* psHwPerfInfo = psDevInfo->psRGXFWIfHWPerfBuf; - IMG_UINT32 ui32SrcRIdx, ui32SrcWIdx, ui32SrcWrapCount; - IMG_UINT32 ui32BytesExp = 0, ui32BytesCopied = 0, ui32BytesCopiedSum = 0; -#ifdef HWPERF_MISR_FUNC_DEBUG - IMG_UINT32 ui32BytesExpSum = 0; -#endif - - PVR_DPF_ENTERED; - - /* Caller should check this member is valid before calling */ - PVR_ASSERT(psDevInfo->hHWPerfStream); - - if (psDevInfo->bSuspendHWPerfL2DataCopy) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s : Copying data to host buffer for FW events is " - "suspended. Start HWPerf consumer or restart driver if " - "HWPerf FW events are needed", __func__)); - - PVR_DPF_RETURN_VAL(ui32BytesCopiedSum); - } - - /* Get a copy of the current - * read (first packet to read) - * write (empty location for the next write to be inserted) - * WrapCount (size in bytes of the buffer at or past end) - * indexes of the FW buffer */ - ui32SrcRIdx = psFwSysData->ui32HWPerfRIdx; - ui32SrcWIdx = psFwSysData->ui32HWPerfWIdx; - OSMemoryBarrier(NULL); - ui32SrcWrapCount = psFwSysData->ui32HWPerfWrapCount; - -#if defined(HWPERF_MISR_FUNC_DEBUG) || defined(EMULATOR) - { - IMG_UINT32 ui32SrcBufSize = psDevInfo->ui32RGXFWIfHWPerfBufSize; - - if (ui32SrcRIdx >= ui32SrcBufSize || ui32SrcWIdx >= ui32SrcBufSize) - { - PVR_DPF((PVR_DBG_ERROR, "%s : Invalid read/write offsets found! srcRIdx:%u srcWIdx:%u srcBufSize:%u", - __func__, ui32SrcRIdx, ui32SrcWIdx, ui32SrcBufSize)); - - PVR_DPF_RETURN_VAL(ui32BytesCopiedSum); - } - } -#endif - - /* Is there any data in the buffer not yet retrieved? */ - if ( ui32SrcRIdx != ui32SrcWIdx ) - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfDataStore EVENTS found srcRIdx:%d srcWIdx: %d", ui32SrcRIdx, ui32SrcWIdx)); - - /* Is the write position higher than the read position? */ - if ( ui32SrcWIdx > ui32SrcRIdx ) - { - /* Yes, buffer has not wrapped */ - ui32BytesExp = ui32SrcWIdx - ui32SrcRIdx; -#ifdef HWPERF_MISR_FUNC_DEBUG - ui32BytesExpSum += ui32BytesExp; -#endif - ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo, - psHwPerfInfo + ui32SrcRIdx, - ui32BytesExp); - - /* Advance the read index and the free bytes counter by the number - * of bytes transported. Items will be left in buffer if not all data - * could be transported. Exit to allow buffer to drain. */ - OSWriteDeviceMem32WithWMB(&psFwSysData->ui32HWPerfRIdx, - RGXHWPerfAdvanceRIdx(psDevInfo->ui32RGXFWIfHWPerfBufSize, - ui32SrcRIdx, - ui32BytesCopied)); - - ui32BytesCopiedSum += ui32BytesCopied; - } - /* No, buffer has wrapped and write position is behind read position */ - else - { - /* Byte count equal to - * number of bytes from read position to the end of the buffer, - * + data in the extra space in the end of the buffer. */ - ui32BytesExp = ui32SrcWrapCount - ui32SrcRIdx; - -#ifdef HWPERF_MISR_FUNC_DEBUG - ui32BytesExpSum += ui32BytesExp; -#endif - /* Attempt to transfer the packets to the TL stream buffer */ - ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo, - psHwPerfInfo + ui32SrcRIdx, - ui32BytesExp); - - /* Advance read index as before and Update the local copy of the - * read index as it might be used in the last if branch*/ - ui32SrcRIdx = RGXHWPerfAdvanceRIdx( - psDevInfo->ui32RGXFWIfHWPerfBufSize, ui32SrcRIdx, - ui32BytesCopied); - - /* Update Wrap Count */ - if ( ui32SrcRIdx == 0) - { - OSWriteDeviceMem32WithWMB(&psFwSysData->ui32HWPerfWrapCount, - psDevInfo->ui32RGXFWIfHWPerfBufSize); - } - OSWriteDeviceMem32WithWMB(&psFwSysData->ui32HWPerfRIdx, ui32SrcRIdx); - - ui32BytesCopiedSum += ui32BytesCopied; - - /* If all the data in the end of the array was copied, try copying - * wrapped data in the beginning of the array, assuming there is - * any and the RIdx was wrapped. */ - if ( (ui32BytesCopied == ui32BytesExp) - && (ui32SrcWIdx > 0) - && (ui32SrcRIdx == 0) ) - { - ui32BytesExp = ui32SrcWIdx; -#ifdef HWPERF_MISR_FUNC_DEBUG - ui32BytesExpSum += ui32BytesExp; -#endif - ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo, - psHwPerfInfo, - ui32BytesExp); - /* Advance the FW buffer read position. */ - psFwSysData->ui32HWPerfRIdx = RGXHWPerfAdvanceRIdx( - psDevInfo->ui32RGXFWIfHWPerfBufSize, ui32SrcRIdx, - ui32BytesCopied); - - ui32BytesCopiedSum += ui32BytesCopied; - } - } -#ifdef HWPERF_MISR_FUNC_DEBUG - if (ui32BytesCopiedSum != ui32BytesExpSum) - { - PVR_DPF((PVR_DBG_WARNING, "RGXHWPerfDataStore: FW L1 RIdx:%u. Not all bytes copied to L2: %u bytes out of %u expected", psFwSysData->ui32HWPerfRIdx, ui32BytesCopiedSum, ui32BytesExpSum)); - } -#endif - - } - else - { - PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfDataStore NO EVENTS to transport")); - } - - PVR_DPF_RETURN_VAL(ui32BytesCopiedSum); -} - - -PVRSRV_ERROR RGXHWPerfDataStoreCB(PVRSRV_DEVICE_NODE *psDevInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psRgxDevInfo; - IMG_UINT32 ui32BytesCopied; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - PVR_DPF_ENTERED; - - PVR_ASSERT(psDevInfo); - psRgxDevInfo = psDevInfo->pvDevice; - - /* Store FW event data if the destination buffer exists.*/ - if (psRgxDevInfo->hHWPerfStream != (IMG_HANDLE) NULL) - { - OSLockAcquire(psRgxDevInfo->hHWPerfLock); - ui32BytesCopied = RGXHWPerfDataStore(psRgxDevInfo); - if ( ui32BytesCopied ) - { /* Signal consumers that packets may be available to read when - * running from a HW kick, not when called by client APP thread - * via the transport layer CB as this can lead to stream - * corruption.*/ - eError = TLStreamSync(psRgxDevInfo->hHWPerfStream); - PVR_ASSERT(eError == PVRSRV_OK); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfDataStoreCB: Zero bytes copied")); - RGXDEBUG_PRINT_IRQ_COUNT(psRgxDevInfo); - } - OSLockRelease(psRgxDevInfo->hHWPerfLock); - } - - - PVR_DPF_RETURN_OK; -} - - -/* Currently supported by default */ -#if defined(SUPPORT_TL_PRODUCER_CALLBACK) -static PVRSRV_ERROR RGXHWPerfTLCB(IMG_HANDLE hStream, - IMG_UINT32 ui32ReqOp, IMG_UINT32* ui32Resp, void* pvUser) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psRgxDevInfo = (PVRSRV_RGXDEV_INFO*)pvUser; - - PVR_UNREFERENCED_PARAMETER(hStream); - PVR_UNREFERENCED_PARAMETER(ui32Resp); - - PVR_ASSERT(psRgxDevInfo); - - switch (ui32ReqOp) - { - case TL_SOURCECB_OP_CLIENT_EOS: - /* Keep HWPerf resource init check and use of - * resources atomic, they may not be freed during use - */ - - /* This solution is for avoiding a deadlock situation where - - * in DoTLStreamReserve(), writer has acquired HWPerfLock and - * ReadLock and is waiting on ReadPending (which will be reset - * by reader), And - * the reader after setting ReadPending in TLStreamAcquireReadPos(), - * is waiting for HWPerfLock in RGXHWPerfTLCB(). - * So here in RGXHWPerfTLCB(), if HWPerfLock is already acquired we - * will return to the reader without waiting to acquire HWPerfLock. - */ - if (!OSTryLockAcquire(psRgxDevInfo->hHWPerfLock)) - { - PVR_DPF((PVR_DBG_MESSAGE, "hHWPerfLock is already acquired, a write " - "operation might already be in process")); - return PVRSRV_OK; - } - - if (psRgxDevInfo->hHWPerfStream != (IMG_HANDLE) NULL) - { - (void) RGXHWPerfDataStore(psRgxDevInfo); - } - OSLockRelease(psRgxDevInfo->hHWPerfLock); - break; - - default: - break; - } - - return eError; -} -#endif - - -static void RGXHWPerfL1BufferDeinit(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - if (psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc) - { - if (psRgxDevInfo->psRGXFWIfHWPerfBuf != NULL) - { - DevmemReleaseCpuVirtAddr(psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc); - psRgxDevInfo->psRGXFWIfHWPerfBuf = NULL; - } - DevmemFwUnmapAndFree(psRgxDevInfo, psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc); - psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc = NULL; - } -} - -/*************************************************************************/ /*! -@Function RGXHWPerfInit - -@Description Called during driver init for initialization of HWPerf module - in the Rogue device driver. This function keeps allocated - only the minimal necessary resources, which are required for - functioning of HWPerf server module. - -@Input psRgxDevInfo RGX Device Info - -@Return PVRSRV_ERROR - */ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - PVRSRV_ERROR eError; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - PVR_DPF_ENTERED; - - /* expecting a valid device info */ - PVR_RETURN_IF_INVALID_PARAM(psRgxDevInfo != NULL); - - /* Create a lock for HWPerf server module used for serializing, L1 to L2 - * copy calls (e.g. in case of TL producer callback) and L1, L2 resource - * allocation */ - eError = OSLockCreate(&psRgxDevInfo->hHWPerfLock); - PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate"); - - /* avoid uninitialised data */ - psRgxDevInfo->hHWPerfStream = (IMG_HANDLE) NULL; - psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc = NULL; - - PVR_DPF_RETURN_OK; -} - -/*************************************************************************/ /*! -@Function RGXHWPerfIsInitRequired - -@Description Returns true if the HWperf firmware buffer (L1 buffer) and host - driver TL buffer (L2 buffer) are not already allocated. Caller - must possess hHWPerfLock lock before calling this - function so the state tested is not inconsistent. - -@Input psRgxDevInfo RGX Device Info, on which init requirement is - checked. - -@Return IMG_BOOL Whether initialization (allocation) is required - */ /**************************************************************************/ -static INLINE IMG_BOOL RGXHWPerfIsInitRequired(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - PVR_ASSERT(OSLockIsLocked(psRgxDevInfo->hHWPerfLock)); - -#if !defined(NO_HARDWARE) - /* Both L1 and L2 buffers are required (for HWPerf functioning) on driver - * built for actual hardware (TC, EMU, etc.) - */ - if (psRgxDevInfo->hHWPerfStream == (IMG_HANDLE) NULL) - { - /* The allocation API (RGXHWPerfInitOnDemandResources) allocates - * device memory for both L1 and L2 without any checks. Hence, - * either both should be allocated or both be NULL. - * - * In-case this changes in future (for e.g. a situation where one - * of the 2 buffers is already allocated and other is required), - * add required checks before allocation calls to avoid memory leaks. - */ - PVR_ASSERT(psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc == NULL); - return IMG_TRUE; - } - PVR_ASSERT(psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc != NULL); -#else - /* On a NO-HW driver L2 is not allocated. So, no point in checking its - * allocation */ - if (psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc == NULL) - { - return IMG_TRUE; - } -#endif - return IMG_FALSE; -} -#if !defined(NO_HARDWARE) -static void _HWPerfFWOnReaderOpenCB(void *pvArg) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psRgxDevInfo = (PVRSRV_RGXDEV_INFO*) pvArg; - PVRSRV_DEVICE_NODE* psDevNode = (PVRSRV_DEVICE_NODE*) psRgxDevInfo->psDeviceNode; - RGXFWIF_KCCB_CMD sKccbCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - /* Clear any previously suspended state for bSuspendHWPerfL2DataCopy as we - * now have a reader attached so the data will be delivered upstream. */ - if (psRgxDevInfo->bSuspendHWPerfL2DataCopy) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Resuming HWPerf FW event collection.", - __func__)); - psRgxDevInfo->bSuspendHWPerfL2DataCopy = IMG_FALSE; - } - - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG; - sKccbCmd.uCmdData.sHWPerfCtrl.eOpCode = RGXFWIF_HWPERF_CTRL_EMIT_FEATURES_EV; - sKccbCmd.uCmdData.sHWPerfCtrl.ui64Mask = 0; - - eError = RGXScheduleCommandAndGetKCCBSlot(psDevNode->pvDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to generate feature packet in " - "firmware (error = %d)", __func__, eError)); - return; - } - - eError = RGXWaitForKCCBSlotUpdate(psRgxDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); -} -#endif -/*************************************************************************/ /*! -@Function RGXHWPerfInitOnDemandResources - -@Description This function allocates the HWperf firmware buffer (L1 buffer) - and host driver TL buffer (L2 buffer) if HWPerf is enabled at - driver load time. Otherwise, these buffers are allocated - on-demand as and when required. Caller - must possess hHWPerfLock lock before calling this - function so the state tested is not inconsistent if called - outside of driver initialisation. - -@Input psRgxDevInfo RGX Device Info, on which init is done - -@Return PVRSRV_ERROR - */ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfInitOnDemandResources(PVRSRV_RGXDEV_INFO* psRgxDevInfo) -{ - IMG_HANDLE hStream = NULL; /* Init required for noHW */ - PVRSRV_ERROR eError; - IMG_UINT32 ui32L2BufferSize = 0; - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags; - IMG_CHAR pszHWPerfStreamName[sizeof(PVRSRV_TL_HWPERF_RGX_FW_STREAM) + 5]; /* 5 seems reasonable as it can hold - names up to "hwperf_9999", which is enough */ - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - PVR_DPF_ENTERED; - - /* Create the L1 HWPerf buffer on demand, read-only for the CPU - * (except for the zero/poison operations) */ - uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) - | PVRSRV_MEMALLOCFLAG_GPU_READABLE - | PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE - | PVRSRV_MEMALLOCFLAG_GPU_UNCACHED - | PVRSRV_MEMALLOCFLAG_CPU_READABLE - | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC - | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE -#if defined(PDUMP) /* Helps show where the packet data ends */ - | PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC -#else /* Helps show corruption issues in driver-live */ - | PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC -#endif - | PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN); - - /* Allocate HWPerf FW L1 buffer */ - eError = DevmemFwAllocate(psRgxDevInfo, - /* Pad it enough to hold the biggest variable sized packet. */ - psRgxDevInfo->ui32RGXFWIfHWPerfBufSize+RGX_HWPERF_MAX_PACKET_SIZE, - uiMemAllocFlags, - "FwHWPerfBuffer", - &psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate kernel fw hwperf buffer (%u)", - __func__, eError)); - goto e0; - } - - /* Expecting the RuntimeCfg structure is mapped into CPU virtual memory. - * Also, make sure the FW address is not already set */ - PVR_ASSERT(psRgxDevInfo->psRGXFWIfRuntimeCfg && psRgxDevInfo->psRGXFWIfRuntimeCfg->sHWPerfBuf.ui32Addr == 0x0); - - /* Meta cached flag removed from this allocation as it was found - * FW performance was better without it. */ - eError = RGXSetFirmwareAddress(&psRgxDevInfo->psRGXFWIfRuntimeCfg->sHWPerfBuf, - psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc, - 0, RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", e0); - -#if defined(RGX_FEATURE_HWPERF_VOLCANIC) - RGXSetMetaDMAAddress(&psRgxDevInfo->psRGXFWIfRuntimeCfg->sHWPerfDMABuf, - psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc, - &psRgxDevInfo->psRGXFWIfRuntimeCfg->sHWPerfBuf, - 0); -#endif - - /* flush write buffers for psRgxDevInfo->psRGXFWIfRuntimeCfg */ - OSWriteMemoryBarrier(&psRgxDevInfo->psRGXFWIfRuntimeCfg->sHWPerfBuf.ui32Addr); - - eError = DevmemAcquireCpuVirtAddr(psRgxDevInfo->psRGXFWIfHWPerfBufMemDesc, - (void**)&psRgxDevInfo->psRGXFWIfHWPerfBuf); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire kernel hwperf buffer (%u)", - __func__, eError)); - goto e0; - } - - /* On NO-HW driver, there is no MISR installed to copy data from L1 to L2. Hence, - * L2 buffer is not allocated */ -#if !defined(NO_HARDWARE) - /* Host L2 HWPERF buffer size in bytes must be bigger than the L1 buffer - * accessed by the FW. The MISR may try to write one packet the size of the L1 - * buffer in some scenarios. When logging is enabled in the MISR, it can be seen - * if the L2 buffer hits a full condition. The closer in size the L2 and L1 buffers - * are the more chance of this happening. - * Size chosen to allow MISR to write an L1 sized packet and for the client - * application/daemon to drain a L1 sized packet e.g. ~ 1.5*L1. - */ - ui32L2BufferSize = psRgxDevInfo->ui32RGXFWIfHWPerfBufSize + - (psRgxDevInfo->ui32RGXFWIfHWPerfBufSize>>1); - - /* form the HWPerf stream name, corresponding to this DevNode; which can make sense in the UM */ - if (OSSNPrintf(pszHWPerfStreamName, sizeof(pszHWPerfStreamName), "%s%d", - PVRSRV_TL_HWPERF_RGX_FW_STREAM, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID) < 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf stream name for device %d", - __func__, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = TLStreamCreate(&hStream, - pszHWPerfStreamName, - ui32L2BufferSize, - TL_OPMODE_DROP_NEWER | TL_FLAG_NO_SIGNAL_ON_COMMIT, - _HWPerfFWOnReaderOpenCB, psRgxDevInfo, -#if !defined(SUPPORT_TL_PRODUCER_CALLBACK) - NULL, NULL -#else - /* Not enabled by default */ - RGXHWPerfTLCB, psRgxDevInfo -#endif - ); - PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCreate", e1); - - eError = TLStreamSetNotifStream(hStream, - PVRSRVGetPVRSRVData()->hTLCtrlStream); - /* we can still discover host stream so leave it as is and just log error */ - PVR_LOG_IF_ERROR(eError, "TLStreamSetNotifStream"); - - /* send the event here because host stream is implicitly opened for write - * in TLStreamCreate and TLStreamOpen is never called (so the event is - * never emitted) */ - TLStreamMarkStreamOpen(hStream); - - { - TL_STREAM_INFO sTLStreamInfo; - - TLStreamInfo(hStream, &sTLStreamInfo); - psRgxDevInfo->ui32L2BufMaxPacketSize = sTLStreamInfo.maxTLpacketSize; - - psRgxDevInfo->bSuspendHWPerfL2DataCopy = IMG_FALSE; - } - - PVR_DPF((PVR_DBG_MESSAGE, "HWPerf buffer size in bytes: L1: %d L2: %d", - psRgxDevInfo->ui32RGXFWIfHWPerfBufSize, ui32L2BufferSize)); - -#else /* defined(NO_HARDWARE) */ - PVR_UNREFERENCED_PARAMETER(ui32L2BufferSize); - PVR_UNREFERENCED_PARAMETER(RGXHWPerfTLCB); - PVR_UNREFERENCED_PARAMETER(pszHWPerfStreamName); - ui32L2BufferSize = 0; -#endif - - psRgxDevInfo->hHWPerfStream = hStream; - PVR_DPF_RETURN_OK; - -#if !defined(NO_HARDWARE) -e1: /* L2 buffer initialisation failures */ - psRgxDevInfo->hHWPerfStream = NULL; -#endif -e0: /* L1 buffer initialisation failures */ - RGXHWPerfL1BufferDeinit(psRgxDevInfo); - - PVR_DPF_RETURN_RC(eError); -} - - -void RGXHWPerfDeinit(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - IMG_HANDLE hStream = psRgxDevInfo->hHWPerfStream; - - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - PVR_DPF_ENTERED; - - PVR_ASSERT(psRgxDevInfo); - psRgxDevInfo->hHWPerfStream = NULL; - - /* Clean up the L2 buffer stream object if allocated */ - if (hStream) - { - /* send the event here because host stream is implicitly opened for - * write in TLStreamCreate and TLStreamClose is never called (so the - * event is never emitted) */ - TLStreamMarkStreamClose(hStream); - TLStreamClose(hStream); - } - - /* Cleanup L1 buffer resources */ - RGXHWPerfL1BufferDeinit(psRgxDevInfo); - - /* Cleanup the HWPerf server module lock resource */ - if (psRgxDevInfo->hHWPerfLock) - { - OSLockDestroy(psRgxDevInfo->hHWPerfLock); - psRgxDevInfo->hHWPerfLock = NULL; - } - - PVR_DPF_RETURN; -} - - -/****************************************************************************** - * RGX HW Performance Profiling Server API(s) - *****************************************************************************/ - -static PVRSRV_ERROR RGXHWPerfCtrlFwBuffer(const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bToggle, - IMG_UINT64 ui64Mask) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psDevice = psDeviceNode->pvDevice; - RGXFWIF_KCCB_CMD sKccbCmd; - IMG_UINT32 ui32kCCBCommandSlot; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - /* If this method is being used whether to enable or disable - * then the hwperf buffers (host and FW) are likely to be needed - * eventually so create them, also helps unit testing. Buffers - * allocated on demand to reduce RAM foot print on systems not - * needing HWPerf resources. - * Obtain lock first, test and init if required. */ - OSLockAcquire(psDevice->hHWPerfLock); - - if (!psDevice->bFirmwareInitialised) - { - psDevice->ui64HWPerfFilter = ui64Mask; // at least set filter - eError = PVRSRV_ERROR_NOT_INITIALISED; - - PVR_DPF((PVR_DBG_ERROR, - "HWPerf has NOT been initialised yet. Mask has been SET to " - "(%" IMG_UINT64_FMTSPECx ")", - ui64Mask)); - - goto unlock_and_return; - } - - if (RGXHWPerfIsInitRequired(psDevice)) - { - eError = RGXHWPerfInitOnDemandResources(psDevice); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation of on-demand HWPerfFW " - "resources failed", __func__)); - goto unlock_and_return; - } - } - -#if defined(RGX_FEATURE_HWPERF_VOLCANIC) && defined(SUPPORT_POWMON_COMPONENT) && defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS) - if (RGXPowmonBufferIsInitRequired(psDeviceNode->pvDevice)) - { - /* Allocate power monitoring log buffer if enabled */ - eError = RGXPowmonBufferInitOnDemandResources(psDeviceNode->pvDevice); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation of on-demand power monitoring " - "resources failed", __func__)); - goto unlock_and_return; - } - } -#endif - - /* Unlock here as no further HWPerf resources are used below that would be - * affected if freed by another thread */ - OSLockRelease(psDevice->hHWPerfLock); - - /* Return if the filter is the same */ - if (!bToggle && psDevice->ui64HWPerfFilter == ui64Mask) - goto return_; - - /* Prepare command parameters ... */ - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG; - sKccbCmd.uCmdData.sHWPerfCtrl.eOpCode = bToggle ? RGXFWIF_HWPERF_CTRL_TOGGLE : RGXFWIF_HWPERF_CTRL_SET; - sKccbCmd.uCmdData.sHWPerfCtrl.ui64Mask = ui64Mask; - - /* Ask the FW to carry out the HWPerf configuration command */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - IMG_TRUE, - &ui32kCCBCommandSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set new HWPerfFW filter in " - "firmware (error = %d)", __func__, eError)); - goto return_; - } - - psDevice->ui64HWPerfFilter = bToggle ? - psDevice->ui64HWPerfFilter ^ ui64Mask : ui64Mask; - - /* Wait for FW to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevice, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate", return_); - -#if defined(DEBUG) - if (bToggle) - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfFW events (%" IMG_UINT64_FMTSPECx ") have been TOGGLED", - ui64Mask)); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfFW mask has been SET to (%" IMG_UINT64_FMTSPECx ")", - ui64Mask)); - } -#endif - - return PVRSRV_OK; - -unlock_and_return: - OSLockRelease(psDevice->hHWPerfLock); - -return_: - return eError; -} - -#define HWPERF_HOST_MAX_DEFERRED_PACKETS 800 - -static PVRSRV_ERROR RGXHWPerfCtrlHostBuffer(const PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bToggle, - IMG_UINT32 ui32Mask) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO* psDevice = psDeviceNode->pvDevice; -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - IMG_UINT32 ui32OldFilter = psDevice->ui32HWPerfHostFilter; -#endif - - OSLockAcquire(psDevice->hLockHWPerfHostStream); - if (psDevice->hHWPerfHostStream == NULL) - { - eError = RGXHWPerfHostInitOnDemandResources(psDevice); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Initialisation of on-demand HWPerfHost resources failed", - __func__)); - OSLockRelease(psDevice->hLockHWPerfHostStream); - return eError; - } - } - - psDevice->ui32HWPerfHostFilter = bToggle ? - psDevice->ui32HWPerfHostFilter ^ ui32Mask : ui32Mask; - - // Deferred creation of host periodic events thread - if (psDevice->ui32HWPerfHostFilter & RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HOST_INFO)) - { - eError = PVRSRVCreateHWPerfHostThread(PVRSRV_APPHINT_HWPERFHOSTTHREADTIMEOUTINMS); - PVR_LOG_IF_ERROR(eError, "PVRSRVCreateHWPerfHostThread"); - } - else if (!(psDevice->ui32HWPerfHostFilter & RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HOST_INFO))) - { - eError = PVRSRVDestroyHWPerfHostThread(); - PVR_LOG_IF_ERROR(eError, "PVRSRVDestroyHWPerfHostThread"); - } - -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - // Log deferred events stats if filter changed from non-zero to zero - if ((ui32OldFilter != 0) && (psDevice->ui32HWPerfHostFilter == 0)) - { - PVR_LOG(("HWPerfHost deferred events buffer high-watermark / size: (%u / %u)", - psDevice->ui32DEHighWatermark, HWPERF_HOST_MAX_DEFERRED_PACKETS)); - - PVR_LOG(("HWPerfHost deferred event retries: WaitForAtomicCtxPktHighWatermark(%u) " - "WaitForRightOrdPktHighWatermark(%u)", - psDevice->ui32WaitForAtomicCtxPktHighWatermark, - psDevice->ui32WaitForRightOrdPktHighWatermark)); - } -#endif - - OSLockRelease(psDevice->hLockHWPerfHostStream); - -#if defined(DEBUG) - if (bToggle) - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfHost events (%x) have been TOGGLED", - ui32Mask)); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfHost mask has been SET to (%x)", - ui32Mask)); - } -#endif - - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXHWPerfCtrlClientBuffer(IMG_BOOL bToggle, - IMG_UINT32 ui32InfoPageIdx, - IMG_UINT32 ui32Mask) -{ - PVRSRV_DATA *psData = PVRSRVGetPVRSRVData(); - - PVR_LOG_RETURN_IF_FALSE(ui32InfoPageIdx >= HWPERF_INFO_IDX_START && - ui32InfoPageIdx < HWPERF_INFO_IDX_END, "invalid info" - " page index", PVRSRV_ERROR_INVALID_PARAMS); - - OSLockAcquire(psData->hInfoPageLock); - psData->pui32InfoPage[ui32InfoPageIdx] = bToggle ? - psData->pui32InfoPage[ui32InfoPageIdx] ^ ui32Mask : ui32Mask; - OSLockRelease(psData->hInfoPageLock); - -#if defined(DEBUG) - if (bToggle) - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfClient (%u) events (%x) have been TOGGLED", - ui32InfoPageIdx, ui32Mask)); - } - else - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfClient (%u) mask has been SET to (%x)", - ui32InfoPageIdx, ui32Mask)); - } -#endif - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVRGXGetHWPerfBvncFeatureFlagsKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_HWPERF_BVNC *psBVNC) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_FALSE((NULL != psDeviceNode), "psDeviceNode invalid", PVRSRV_ERROR_INVALID_PARAMS); - - psDevInfo = psDeviceNode->pvDevice; - eError = RGXServerFeatureFlagsToHWPerfFlags(psDevInfo, psBVNC); - - return eError; -} - -/* - AppHint interfaces - */ -static -PVRSRV_ERROR RGXHWPerfSetFwFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT64 ui64Value) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode != NULL); - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode->pvDevice != NULL); - - eError = RGXHWPerfCtrlFwBuffer(psDeviceNode, IMG_FALSE, ui64Value); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to set HWPerf firmware filter for device (%u)", - psDeviceNode->sDevId.ui32InternalID)); - return eError; - } - - return PVRSRV_OK; -} - -static -PVRSRV_ERROR RGXHWPerfReadFwFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT64 *pui64Value) -{ - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode != NULL); - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode->pvDevice != NULL); - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - *pui64Value = - ((PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice)->ui64HWPerfFilter; - - return PVRSRV_OK; -} - -static -PVRSRV_ERROR RGXHWPerfSetHostFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eError; - - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode != NULL); - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode->pvDevice != NULL); - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - eError = RGXHWPerfCtrlHostBuffer(psDeviceNode, IMG_FALSE, ui32Value); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to set HWPerf firmware filter for device (%u)", - psDeviceNode->sDevId.ui32InternalID)); - return eError; - } - - return PVRSRV_OK; -} - -static -PVRSRV_ERROR RGXHWPerfReadHostFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode != NULL); - PVR_RETURN_IF_INVALID_PARAM(psDeviceNode->pvDevice != NULL); - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - *pui32Value = - ((PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice)->ui32HWPerfHostFilter; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _ReadClientFilter(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivData, - IMG_UINT32 *pui32Value) -{ - PVRSRV_DATA *psData = PVRSRVGetPVRSRVData(); - IMG_UINT32 ui32Idx = (IMG_UINT32) (uintptr_t) psPrivData; - PVR_UNREFERENCED_PARAMETER(psDevice); - - OSLockAcquire(psData->hInfoPageLock); - *pui32Value = psData->pui32InfoPage[ui32Idx]; - OSLockRelease(psData->hInfoPageLock); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _WriteClientFilter(const PVRSRV_DEVICE_NODE *psDevice, - const void *psPrivData, - IMG_UINT32 ui32Value) -{ - IMG_UINT32 ui32Idx = (IMG_UINT32) (uintptr_t) psPrivData; - PVR_UNREFERENCED_PARAMETER(psDevice); - - return RGXHWPerfCtrlClientBuffer(IMG_FALSE, ui32Idx, ui32Value); -} - -void RGXHWPerfInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRVAppHintRegisterHandlersUINT64(APPHINT_ID_HWPerfFWFilter, - RGXHWPerfReadFwFilter, - RGXHWPerfSetFwFilter, - psDeviceNode, - NULL); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfHostFilter, - RGXHWPerfReadHostFilter, - RGXHWPerfSetHostFilter, - psDeviceNode, - NULL); -} - -void RGXHWPerfClientInitAppHintCallbacks(void) -{ - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_Services, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_SERVICES_IDX); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_EGL, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_EGL_IDX); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_OpenGLES, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_OPENGLES_IDX); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_OpenCL, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_OPENCL_IDX); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_Vulkan, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_VULKAN_IDX); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HWPerfClientFilter_OpenGL, - _ReadClientFilter, - _WriteClientFilter, - APPHINT_OF_DRIVER_NO_DEVICE, - (void *) HWPERF_FILTER_OPENGL_IDX); -} - -static INLINE IMG_UINT32 _RGXHWPerfFixBufferSize(IMG_UINT32 ui32BufSizeKB) -{ - if (ui32BufSizeKB > HWPERF_HOST_TL_STREAM_SIZE_MAX) - { - /* Size specified as a AppHint but it is too big */ - PVR_DPF((PVR_DBG_WARNING, - "RGXHWPerfHostInit: HWPerf Host buffer size " - "value (%u) too big, using maximum (%u)", - ui32BufSizeKB, HWPERF_HOST_TL_STREAM_SIZE_MAX)); - return HWPERF_HOST_TL_STREAM_SIZE_MAX<<10; - } - else if (ui32BufSizeKB >= HWPERF_HOST_TL_STREAM_SIZE_MIN) - { - return ui32BufSizeKB<<10; - } - else if (ui32BufSizeKB > 0) - { - /* Size specified as a AppHint but it is too small */ - PVR_DPF((PVR_DBG_WARNING, - "RGXHWPerfHostInit: HWPerf Host buffer size " - "value (%u) too small, using minimum (%u)", - ui32BufSizeKB, HWPERF_HOST_TL_STREAM_SIZE_MIN)); - return HWPERF_HOST_TL_STREAM_SIZE_MIN<<10; - } - else - { - /* 0 size implies AppHint not set or is set to zero, - * use default size from driver constant. */ - return HWPERF_HOST_TL_STREAM_SIZE_DEFAULT<<10; - } -} - -/****************************************************************************** - * RGX HW Performance Host Stream API - *****************************************************************************/ - -/*************************************************************************/ /*! -@Function RGXHWPerfHostInit - -@Description Called during driver init for initialisation of HWPerfHost - stream in the Rogue device driver. This function keeps allocated - only the minimal necessary resources, which are required for - functioning of HWPerf server module. - -@Return PVRSRV_ERROR - */ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfHostInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT32 ui32BufSizeKB) -{ - PVRSRV_ERROR eError; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - PVR_RETURN_IF_INVALID_PARAM(psRgxDevInfo != NULL); - - eError = OSLockCreate(&psRgxDevInfo->hLockHWPerfHostStream); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", error); - - psRgxDevInfo->hHWPerfHostStream = NULL; - psRgxDevInfo->ui32HWPerfHostFilter = 0; /* disable all events */ - psRgxDevInfo->ui32HWPerfHostNextOrdinal = 1; - psRgxDevInfo->ui32HWPerfHostBufSize = _RGXHWPerfFixBufferSize(ui32BufSizeKB); - psRgxDevInfo->pvHostHWPerfMISR = NULL; - psRgxDevInfo->pui8DeferredEvents = NULL; - /* First packet has ordinal=1, so LastOrdinal=0 will ensure ordering logic - * is maintained */ - psRgxDevInfo->ui32HWPerfHostLastOrdinal = 0; - psRgxDevInfo->hHWPerfHostSpinLock = NULL; - -error: - return eError; -} - -#define RGX_HWPERF_HOST_CLIENT_INFO_PROC_NAME_BASE_SIZE \ - ((IMG_UINT32)(offsetof(RGX_HWPERF_HOST_CLIENT_INFO_DATA, uDetail) + \ - sizeof(((RGX_HWPERF_HOST_CLIENT_INFO_DETAIL*)0)->sProcName.ui32Count))) - -static void _HWPerfHostOnConnectCB(void *pvArg) -{ - PVRSRV_RGXDEV_INFO* psDevice; - PVRSRV_ERROR eError; - - RGXSRV_HWPERF_CLK_SYNC(pvArg); - - psDevice = (PVRSRV_RGXDEV_INFO*) pvArg; - - /* Handle the case where the RGX_HWPERF_HOST_INFO bit is set in the event filter - * before the host stream is opened for reading by a HWPerf client. - * Which can result in the host periodic thread sleeping for a long duration as TLStreamIsOpenForReading may return false. */ - if (psDevice->ui32HWPerfHostFilter & RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HOST_INFO)) - { - eError = PVRSRVCreateHWPerfHostThread(PVRSRV_APPHINT_HWPERFHOSTTHREADTIMEOUTINMS); - PVR_LOG_IF_ERROR(eError, "PVRSRVCreateHWPerfHostThread"); - } - - if (RGXHWPerfHostIsEventEnabled(psDevice, RGX_HWPERF_HOST_CLIENT_INFO)) - { - // GCC throws -Werror=frame-larger-than error if the frame size is > 1024 bytes, - // so use a heap allocation - is there an alternate solution? - IMG_BYTE *pbPktPayload = (IMG_BYTE*)OSAllocMem(RGX_HWPERF_MAX_PAYLOAD_SIZE); - - if (pbPktPayload) - { - RGX_HWPERF_HOST_CLIENT_INFO_DATA *psHostClientInfo; - RGX_HWPERF_HOST_CLIENT_PROC_NAME *psProcName; - IMG_UINT32 ui32TotalPayloadSize, ui32NameLen, ui32ProcNamePktSize; - DLLIST_NODE *pNode, *pNext; - - psHostClientInfo = IMG_OFFSET_ADDR(pbPktPayload,0); - psHostClientInfo->eType = RGX_HWPERF_HOST_CLIENT_INFO_TYPE_PROCESS_NAME; - psHostClientInfo->uDetail.sProcName.ui32Count = 0U; - psProcName = psHostClientInfo->uDetail.sProcName.asProcNames; - ui32TotalPayloadSize = RGX_HWPERF_HOST_CLIENT_INFO_PROC_NAME_BASE_SIZE; - - OSLockAcquire(psDevice->psDeviceNode->hConnectionsLock); - - // Announce current client connections to the reader - dllist_foreach_node(&psDevice->psDeviceNode->sConnections, pNode, pNext) - { - CONNECTION_DATA *psData = IMG_CONTAINER_OF(pNode, CONNECTION_DATA, sConnectionListNode); - - ui32NameLen = OSStringLength(psData->pszProcName) + 1U; - ui32ProcNamePktSize = RGX_HWPERF_HOST_CLIENT_PROC_NAME_SIZE(ui32NameLen); - - // Unlikely case where we have too much data to fit into a single hwperf packet - if (ui32ProcNamePktSize + ui32TotalPayloadSize > RGX_HWPERF_MAX_PAYLOAD_SIZE) - { - RGXHWPerfHostPostRaw(psDevice, RGX_HWPERF_HOST_CLIENT_INFO, pbPktPayload, ui32TotalPayloadSize); - - psHostClientInfo->uDetail.sProcName.ui32Count = 0U; - psProcName = psHostClientInfo->uDetail.sProcName.asProcNames; - ui32TotalPayloadSize = RGX_HWPERF_HOST_CLIENT_INFO_PROC_NAME_BASE_SIZE; - } - - // Setup packet data - psHostClientInfo->uDetail.sProcName.ui32Count++; - psProcName->uiClientPID = psData->pid; - psProcName->ui32Length = ui32NameLen; - (void)OSStringLCopy(psProcName->acName, psData->pszProcName, ui32NameLen); - - psProcName = (RGX_HWPERF_HOST_CLIENT_PROC_NAME*)IMG_OFFSET_ADDR(psProcName, ui32ProcNamePktSize); - ui32TotalPayloadSize += ui32ProcNamePktSize; - } - - OSLockRelease(psDevice->psDeviceNode->hConnectionsLock); - RGXHWPerfHostPostRaw(psDevice, RGX_HWPERF_HOST_CLIENT_INFO, pbPktPayload, ui32TotalPayloadSize); - OSFreeMem(pbPktPayload); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: OUT OF MEMORY. Could not allocate memory for RGX_HWPERF_HOST_CLIENT_INFO_DATA packet.", __func__)); - } - } -} - -/* Avoiding a holder struct using fields below, as a struct gets along padding, - * packing, and other compiler dependencies, and we want a continuous stream of - * bytes for (header+data) for use in TLStreamWrite. See - * _HWPerfHostDeferredEventsEmitter(). - * - * A deferred (UFO) packet is represented in memory as: - * - IMG_BOOL --> Indicates whether a packet write is - * "complete" by atomic context or not. - * - RGX_HWPERF_V2_PACKET_HDR --. - * |--> Fed together to TLStreamWrite for - * | deferred packet to be written to - * | HWPerfHost buffer - * - RGX_HWPERF_HOST_UFO_DATA---` - * - * PS: Currently only UFO events are supported in deferred list */ -#define HWPERF_HOST_DEFERRED_UFO_PACKET_SIZE (sizeof(IMG_BOOL) +\ - sizeof(RGX_HWPERF_V2_PACKET_HDR) +\ - sizeof(RGX_HWPERF_HOST_UFO_DATA)) - -static void RGX_MISRHandler_HWPerfPostDeferredHostEvents(void *pvData); -static void _HWPerfHostDeferredEventsEmitter(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 ui32MaxOrdinal); - -/*************************************************************************/ /*! -@Function RGXHWPerfHostInitOnDemandResources - -@Description This function allocates the HWPerfHost buffer if HWPerf is - enabled at driver load time. Otherwise, these buffers are - allocated on-demand as and when required. - -@Return PVRSRV_ERROR - */ /**************************************************************************/ -PVRSRV_ERROR RGXHWPerfHostInitOnDemandResources(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - PVRSRV_ERROR eError; - /* 5 makes space up to "hwperf_host_9999" streams */ - IMG_CHAR pszHWPerfHostStreamName[sizeof(PVRSRV_TL_HWPERF_HOST_SERVER_STREAM) + 5]; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - if (psRgxDevInfo->hHWPerfHostStream != NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "HWPerf host stream already initialised")); - return PVRSRV_OK; - } - - /* form the HWPerf host stream name, corresponding to this DevNode; which can make sense in the UM */ - if (OSSNPrintf(pszHWPerfHostStreamName, sizeof(pszHWPerfHostStreamName), "%s%d", - PVRSRV_TL_HWPERF_HOST_SERVER_STREAM, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID) < 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf host stream name for device %d", - __func__, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = TLStreamCreate(&psRgxDevInfo->hHWPerfHostStream, - pszHWPerfHostStreamName, psRgxDevInfo->ui32HWPerfHostBufSize, - TL_OPMODE_DROP_NEWER, - _HWPerfHostOnConnectCB, psRgxDevInfo, - NULL, NULL); - PVR_LOG_RETURN_IF_ERROR(eError, "TLStreamCreate"); - - eError = TLStreamSetNotifStream(psRgxDevInfo->hHWPerfHostStream, - PVRSRVGetPVRSRVData()->hTLCtrlStream); - /* we can still discover host stream so leave it as is and just log error */ - PVR_LOG_IF_ERROR(eError, "TLStreamSetNotifStream"); - - /* send the event here because host stream is implicitly opened for write - * in TLStreamCreate and TLStreamOpen is never called (so the event is - * never emitted) */ - eError = TLStreamMarkStreamOpen(psRgxDevInfo->hHWPerfHostStream); - PVR_LOG_IF_ERROR(eError, "TLStreamMarkStreamOpen"); - - /* HWPerfHost deferred events specific initialization */ - eError = OSInstallMISR(&psRgxDevInfo->pvHostHWPerfMISR, - RGX_MISRHandler_HWPerfPostDeferredHostEvents, - psRgxDevInfo, - "RGX_HWPerfDeferredEventPoster"); - PVR_LOG_GOTO_IF_ERROR(eError, "OSInstallMISR", err_install_misr); - - eError = OSSpinLockCreate(&psRgxDevInfo->hHWPerfHostSpinLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSSpinLockCreate", err_spinlock_create); - - psRgxDevInfo->pui8DeferredEvents = OSAllocMem(HWPERF_HOST_MAX_DEFERRED_PACKETS - * HWPERF_HOST_DEFERRED_UFO_PACKET_SIZE); - if (NULL == psRgxDevInfo->pui8DeferredEvents) - { - PVR_DPF((PVR_DBG_ERROR, "%s: OUT OF MEMORY. Could not allocate memory for " - "HWPerfHost deferred events array", __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_alloc_deferred_events; - } - psRgxDevInfo->ui16DEReadIdx = 0; - psRgxDevInfo->ui16DEWriteIdx = 0; -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - psRgxDevInfo->ui32DEHighWatermark = 0; - psRgxDevInfo->ui32WaitForRightOrdPktHighWatermark = 0; - psRgxDevInfo->ui32WaitForAtomicCtxPktHighWatermark = 0; -#endif - - PVR_DPF((DBGPRIV_MESSAGE, "HWPerf Host buffer size is %uKB", - psRgxDevInfo->ui32HWPerfHostBufSize)); - - return PVRSRV_OK; - -err_alloc_deferred_events: - OSSpinLockDestroy(psRgxDevInfo->hHWPerfHostSpinLock); - psRgxDevInfo->hHWPerfHostSpinLock = NULL; - -err_spinlock_create: - (void) OSUninstallMISR(psRgxDevInfo->pvHostHWPerfMISR); - psRgxDevInfo->pvHostHWPerfMISR = NULL; - -err_install_misr: - TLStreamMarkStreamClose(psRgxDevInfo->hHWPerfHostStream); - TLStreamClose(psRgxDevInfo->hHWPerfHostStream); - psRgxDevInfo->hHWPerfHostStream = NULL; - - return eError; -} - -void RGXHWPerfHostDeInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - PVR_ASSERT (psRgxDevInfo); - - if (psRgxDevInfo->pui8DeferredEvents) - { - OSFreeMem(psRgxDevInfo->pui8DeferredEvents); - psRgxDevInfo->pui8DeferredEvents = NULL; - } - - if (psRgxDevInfo->hHWPerfHostSpinLock) - { - OSSpinLockDestroy(psRgxDevInfo->hHWPerfHostSpinLock); - psRgxDevInfo->hHWPerfHostSpinLock = NULL; - } - - if (psRgxDevInfo->pvHostHWPerfMISR) - { - (void) OSUninstallMISR(psRgxDevInfo->pvHostHWPerfMISR); - psRgxDevInfo->pvHostHWPerfMISR = NULL; - } - - if (psRgxDevInfo->hHWPerfHostStream) - { - /* send the event here because host stream is implicitly opened for - * write in TLStreamCreate and TLStreamClose is never called (so the - * event is never emitted) */ - TLStreamMarkStreamClose(psRgxDevInfo->hHWPerfHostStream); - TLStreamClose(psRgxDevInfo->hHWPerfHostStream); - psRgxDevInfo->hHWPerfHostStream = NULL; - } - - if (psRgxDevInfo->hLockHWPerfHostStream) - { - OSLockDestroy(psRgxDevInfo->hLockHWPerfHostStream); - psRgxDevInfo->hLockHWPerfHostStream = NULL; - } -} - -inline void RGXHWPerfHostSetEventFilter(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT32 ui32Filter) -{ - PVRSRV_VZ_RETN_IF_MODE(GUEST); - psRgxDevInfo->ui32HWPerfHostFilter = ui32Filter; -} - -inline IMG_BOOL RGXHWPerfHostIsEventEnabled(PVRSRV_RGXDEV_INFO *psRgxDevInfo, RGX_HWPERF_HOST_EVENT_TYPE eEvent) -{ - PVR_ASSERT(psRgxDevInfo); - return (psRgxDevInfo->ui32HWPerfHostFilter & RGX_HWPERF_EVENT_MASK_VALUE(eEvent)) ? IMG_TRUE : IMG_FALSE; -} - -#define MAX_RETRY_COUNT 80 -static inline void _PostFunctionPrologue(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 ui32CurrentOrdinal) -{ - IMG_UINT32 ui32Retry = MAX_RETRY_COUNT; - - PVR_ASSERT(psRgxDevInfo->hLockHWPerfHostStream != NULL); - PVR_ASSERT(psRgxDevInfo->hHWPerfHostStream != NULL); - - OSLockAcquire(psRgxDevInfo->hLockHWPerfHostStream); - - /* First, flush pending events (if any) */ - _HWPerfHostDeferredEventsEmitter(psRgxDevInfo, ui32CurrentOrdinal); - - while ((ui32CurrentOrdinal != psRgxDevInfo->ui32HWPerfHostLastOrdinal + 1) - && (--ui32Retry != 0)) - { - /* Release lock and give a chance to a waiting context to emit the - * expected packet */ - OSLockRelease (psRgxDevInfo->hLockHWPerfHostStream); - OSSleepms(100); - OSLockAcquire(psRgxDevInfo->hLockHWPerfHostStream); - } - -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - if ((ui32Retry == 0) && !(psRgxDevInfo->bWarnedPktOrdinalBroke)) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Will warn only once! Potential packet(s) lost after ordinal" - " %u (Current ordinal = %u)", - __func__, - psRgxDevInfo->ui32HWPerfHostLastOrdinal, ui32CurrentOrdinal)); - psRgxDevInfo->bWarnedPktOrdinalBroke = IMG_TRUE; - } - - if (psRgxDevInfo->ui32WaitForRightOrdPktHighWatermark < (MAX_RETRY_COUNT - ui32Retry)) - { - psRgxDevInfo->ui32WaitForRightOrdPktHighWatermark = MAX_RETRY_COUNT - ui32Retry; - } -#endif -} - -static inline void _PostFunctionEpilogue(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 ui32CurrentOrdinal) -{ - /* update last ordinal emitted */ - psRgxDevInfo->ui32HWPerfHostLastOrdinal = ui32CurrentOrdinal; - - PVR_ASSERT(OSLockIsLocked(psRgxDevInfo->hLockHWPerfHostStream)); - OSLockRelease(psRgxDevInfo->hLockHWPerfHostStream); -} - -static inline IMG_UINT8 *_ReserveHWPerfStream(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT32 ui32Size) -{ - IMG_UINT8 *pui8Dest; - - PVRSRV_ERROR eError = TLStreamReserve(psRgxDevInfo->hHWPerfHostStream, - &pui8Dest, ui32Size); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Could not reserve space in %s buffer" - " (%d). Dropping packet.", - __func__, PVRSRV_TL_HWPERF_HOST_SERVER_STREAM, eError)); - return NULL; - } - PVR_ASSERT(pui8Dest != NULL); - - return pui8Dest; -} - -static inline void _CommitHWPerfStream(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT32 ui32Size) -{ - PVRSRV_ERROR eError = TLStreamCommit(psRgxDevInfo->hHWPerfHostStream, - ui32Size); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Could not commit data to %s" - " (%d)", __func__, PVRSRV_TL_HWPERF_HOST_SERVER_STREAM, eError)); - } -} - -/* Returns IMG_TRUE if packet write passes, IMG_FALSE otherwise */ -static inline IMG_BOOL _WriteHWPerfStream(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_V2_PACKET_HDR *psHeader) -{ - PVRSRV_ERROR eError = TLStreamWrite(psRgxDevInfo->hHWPerfHostStream, - IMG_OFFSET_ADDR(psHeader, 0), psHeader->ui32Size); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Could not write packet in %s buffer" - " (%d). Dropping packet.", - __func__, PVRSRV_TL_HWPERF_HOST_SERVER_STREAM, eError)); - } - - /* Regardless of whether write passed/failed, we consider it "written" */ - psRgxDevInfo->ui32HWPerfHostLastOrdinal = psHeader->ui32Ordinal; - - return (eError == PVRSRV_OK); -} - -/* Helper macros for deferred events operations */ -#define GET_DE_NEXT_IDX(_curridx) ((_curridx + 1) % HWPERF_HOST_MAX_DEFERRED_PACKETS) -#define GET_DE_EVENT_BASE(_idx) (IMG_OFFSET_ADDR(psRgxDevInfo->pui8DeferredEvents, \ - (_idx) * HWPERF_HOST_DEFERRED_UFO_PACKET_SIZE)) - -#define GET_DE_EVENT_WRITE_STATUS(_base) ((IMG_BOOL*)((void *)(_base))) -#define GET_DE_EVENT_DATA(_base) (IMG_OFFSET_ADDR((_base), sizeof(IMG_BOOL))) - -/* Emits HWPerfHost event packets present in the deferred list stopping when one - * of the following cases is hit: - * case 1: Packet ordering breaks i.e. a packet found doesn't meet ordering - * criteria (ordinal == last_ordinal + 1) - * - * case 2: A packet with ordinal > ui32MaxOrdinal is found - * - * case 3: Deferred list's (read == write) i.e. no more deferred packets. - * - * NOTE: Caller must possess the hLockHWPerfHostStream lock before calling - * this function.*/ -static void _HWPerfHostDeferredEventsEmitter(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 ui32MaxOrdinal) -{ - RGX_HWPERF_V2_PACKET_HDR *psHeader; - IMG_UINT32 ui32Retry; - IMG_UINT8 *pui8DeferredEvent; - IMG_BOOL *pbPacketWritten; - IMG_BOOL bWritePassed; - - PVR_ASSERT(OSLockIsLocked(psRgxDevInfo->hLockHWPerfHostStream)); - - while (psRgxDevInfo->ui16DEReadIdx != psRgxDevInfo->ui16DEWriteIdx) - { - pui8DeferredEvent = GET_DE_EVENT_BASE(psRgxDevInfo->ui16DEReadIdx); - pbPacketWritten = GET_DE_EVENT_WRITE_STATUS(pui8DeferredEvent); - psHeader = (RGX_HWPERF_V2_PACKET_HDR*) GET_DE_EVENT_DATA(pui8DeferredEvent); - - for (ui32Retry = MAX_RETRY_COUNT; !(*pbPacketWritten) && (ui32Retry != 0); ui32Retry--) - { - /* Packet not yet written, re-check after a while. Wait for a short period as - * atomic contexts are generally expected to finish fast */ - OSWaitus(10); - } - -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - if ((ui32Retry == 0) && !(psRgxDevInfo->bWarnedAtomicCtxPktLost)) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Will warn only once. Dropping a deferred packet as atomic context" - " took too long to write it", - __func__)); - psRgxDevInfo->bWarnedAtomicCtxPktLost = IMG_TRUE; - } - - if (psRgxDevInfo->ui32WaitForAtomicCtxPktHighWatermark < (MAX_RETRY_COUNT - ui32Retry)) - { - psRgxDevInfo->ui32WaitForAtomicCtxPktHighWatermark = MAX_RETRY_COUNT - ui32Retry; - } -#endif - - if (*pbPacketWritten) - { - if ((psHeader->ui32Ordinal > ui32MaxOrdinal) || - (psHeader->ui32Ordinal != (psRgxDevInfo->ui32HWPerfHostLastOrdinal + 1))) - { - /* Leave remaining events to be emitted by next call to this function */ - break; - } - bWritePassed = _WriteHWPerfStream(psRgxDevInfo, psHeader); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Atomic context packet lost!", __func__)); - bWritePassed = IMG_FALSE; - } - - /* Move on to next packet */ - psRgxDevInfo->ui16DEReadIdx = GET_DE_NEXT_IDX(psRgxDevInfo->ui16DEReadIdx); - - if (!bWritePassed // if write failed - && ui32MaxOrdinal == IMG_UINT32_MAX // and we are from MISR - && psRgxDevInfo->ui16DEReadIdx != psRgxDevInfo->ui16DEWriteIdx) // and there are more events - { - /* Stop emitting here and re-schedule MISR */ - OSScheduleMISR(psRgxDevInfo->pvHostHWPerfMISR); - break; - } - } -} - -static void RGX_MISRHandler_HWPerfPostDeferredHostEvents(void *pvData) -{ - PVRSRV_RGXDEV_INFO *psRgxDevInfo = pvData; - - OSLockAcquire(psRgxDevInfo->hLockHWPerfHostStream); - - /* Since we're called from MISR, there is no upper cap of ordinal to be emitted. - * Send IMG_UINT32_MAX to signify all possible packets. */ - _HWPerfHostDeferredEventsEmitter(psRgxDevInfo, IMG_UINT32_MAX); - - OSLockRelease(psRgxDevInfo->hLockHWPerfHostStream); -} - -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) -static inline void _UpdateDEBufferHighWatermark(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - IMG_UINT32 ui32DEWatermark; - IMG_UINT16 ui16LRead = psRgxDevInfo->ui16DEReadIdx; - IMG_UINT16 ui16LWrite = psRgxDevInfo->ui16DEWriteIdx; - - if (ui16LWrite >= ui16LRead) - { - ui32DEWatermark = ui16LWrite - ui16LRead; - } - else - { - ui32DEWatermark = (HWPERF_HOST_MAX_DEFERRED_PACKETS - ui16LRead) + (ui16LWrite); - } - - if (ui32DEWatermark > psRgxDevInfo->ui32DEHighWatermark) - { - psRgxDevInfo->ui32DEHighWatermark = ui32DEWatermark; - } -} -#endif - -/* @Description Gets the data/members that concerns the accuracy of a packet in HWPerfHost - buffer. Since the data returned by this function is required in both, an - atomic as well as a process/sleepable context, it is protected under spinlock - - @Output pui32Ordinal Pointer to ordinal number assigned to this packet - @Output pui64Timestamp Timestamp value for this packet - @Output ppui8Dest If the current context cannot sleep, pointer to a place in - deferred events buffer where the packet data should be written. - Don't care, otherwise. - */ -static void _GetHWPerfHostPacketSpecifics(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 *pui32Ordinal, - IMG_UINT64 *pui64Timestamp, - IMG_UINT8 **ppui8Dest, - IMG_BOOL bSleepAllowed) -{ - OS_SPINLOCK_FLAGS uiFlags; - - /* Spin lock is required to avoid getting scheduled out by a higher priority - * context while we're getting header specific details and packet place in - * HWPerf buffer (when in atomic context) for ourselves */ - OSSpinLockAcquire(psRgxDevInfo->hHWPerfHostSpinLock, uiFlags); - - *pui32Ordinal = psRgxDevInfo->ui32HWPerfHostNextOrdinal++; - *pui64Timestamp = RGXTimeCorrGetClockus64(psRgxDevInfo->psDeviceNode); - - if (!bSleepAllowed) - { - /* We're in an atomic context. So return the next position available in - * deferred events buffer */ - IMG_UINT16 ui16NewWriteIdx; - IMG_BOOL *pbPacketWritten; - - PVR_ASSERT(ppui8Dest != NULL); - - ui16NewWriteIdx = GET_DE_NEXT_IDX(psRgxDevInfo->ui16DEWriteIdx); - if (ui16NewWriteIdx == psRgxDevInfo->ui16DEReadIdx) - { - /* This shouldn't happen. HWPERF_HOST_MAX_DEFERRED_PACKETS should be - * big enough to avoid any such scenario */ -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - /* PVR_LOG/printk isn't recommended in atomic context. Perhaps we'll do - * this debug output here when trace_printk support is added to DDK */ -// PVR_LOG(("%s: No more space in deferred events buffer (%u/%u) W=%u,R=%u", -// __func__, psRgxDevInfo->ui32DEHighWatermark, -// HWPERF_HOST_MAX_DEFERRED_PACKETS, psRgxDevInfo->ui16DEWriteIdx, -// psRgxDevInfo->ui16DEReadIdx)); -#endif - *ppui8Dest = NULL; - } - else - { - /* Return the position where deferred event would be written */ - *ppui8Dest = GET_DE_EVENT_BASE(psRgxDevInfo->ui16DEWriteIdx); - - /* Make sure packet write "state" is "write-pending" _before_ moving write - * pointer forward */ - pbPacketWritten = GET_DE_EVENT_WRITE_STATUS(*ppui8Dest); - *pbPacketWritten = IMG_FALSE; - - psRgxDevInfo->ui16DEWriteIdx = ui16NewWriteIdx; - -#if defined(PVRSRV_HWPERF_HOST_DEBUG_DEFERRED_EVENTS) - _UpdateDEBufferHighWatermark(psRgxDevInfo); -#endif - } - } - - OSSpinLockRelease(psRgxDevInfo->hHWPerfHostSpinLock, uiFlags); -} - -static inline void _SetupHostPacketHeader(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT8 *pui8Dest, - RGX_HWPERF_HOST_EVENT_TYPE eEvType, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32Ordinal, - IMG_UINT64 ui64Timestamp) -{ - RGX_HWPERF_V2_PACKET_HDR *psHeader = (RGX_HWPERF_V2_PACKET_HDR *) ((void *)pui8Dest); - - PVR_ASSERT(ui32Size<=RGX_HWPERF_MAX_PACKET_SIZE); - - psHeader->ui32Ordinal = ui32Ordinal; - psHeader->ui64Timestamp = ui64Timestamp; - psHeader->ui32Sig = HWPERF_PACKET_V2B_SIG; - psHeader->eTypeId = RGX_HWPERF_MAKE_TYPEID(RGX_HWPERF_STREAM_ID1_HOST, - eEvType, 0, 0, 0); - psHeader->ui32Size = ui32Size; -} - -static inline void _SetupHostEnqPacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_KICK_TYPE eEnqType, - IMG_UINT32 ui32Pid, - IMG_UINT32 ui32FWDMContext, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - PVRSRV_FENCE hCheckFence, - PVRSRV_FENCE hUpdateFence, - PVRSRV_TIMELINE hUpdateTimeline, - IMG_UINT64 ui64CheckFenceUID, - IMG_UINT64 ui64UpdateFenceUID, - IMG_UINT64 ui64DeadlineInus, - IMG_UINT32 ui32CycleEstimate) -{ - RGX_HWPERF_HOST_ENQ_DATA *psData = (RGX_HWPERF_HOST_ENQ_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - psData->ui32EnqType = eEnqType; - psData->ui32PID = ui32Pid; - psData->ui32ExtJobRef = ui32ExtJobRef; - psData->ui32IntJobRef = ui32IntJobRef; - psData->ui32DMContext = ui32FWDMContext; - psData->hCheckFence = hCheckFence; - psData->hUpdateFence = hUpdateFence; - psData->hUpdateTimeline = hUpdateTimeline; - psData->ui64CheckFence_UID = ui64CheckFenceUID; - psData->ui64UpdateFence_UID = ui64UpdateFenceUID; - psData->ui64DeadlineInus = ui64DeadlineInus; - psData->ui32CycleEstimate = ui32CycleEstimate; -} - -void RGXHWPerfHostPostRaw(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_EVENT_TYPE eEvType, - IMG_BYTE *pbPayload, - IMG_UINT32 ui32PayloadSize) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32PktSize; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - PVR_ASSERT(ui32PayloadSize <= RGX_HWPERF_MAX_PAYLOAD_SIZE); - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - ui32PktSize = RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32PayloadSize); - pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32PktSize); - - if (pui8Dest == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, eEvType, ui32PktSize, ui32Ordinal, ui64Timestamp); - OSDeviceMemCopy((IMG_UINT8*)IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)), pbPayload, ui32PayloadSize); - _CommitHWPerfStream(psRgxDevInfo, ui32PktSize); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -void RGXHWPerfHostPostEnqEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_KICK_TYPE eEnqType, - IMG_UINT32 ui32Pid, - IMG_UINT32 ui32FWDMContext, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - PVRSRV_FENCE hCheckFence, - PVRSRV_FENCE hUpdateFence, - PVRSRV_TIMELINE hUpdateTimeline, - IMG_UINT64 ui64CheckFenceUID, - IMG_UINT64 ui64UpdateFenceUID, - IMG_UINT64 ui64DeadlineInus, - IMG_UINT32 ui32CycleEstimate ) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size = RGX_HWPERF_MAKE_SIZE_FIXED(RGX_HWPERF_HOST_ENQ_DATA); - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_ENQ, ui32Size, - ui32Ordinal, ui64Timestamp); - _SetupHostEnqPacketData(pui8Dest, - eEnqType, - ui32Pid, - ui32FWDMContext, - ui32ExtJobRef, - ui32IntJobRef, - hCheckFence, - hUpdateFence, - hUpdateTimeline, - ui64CheckFenceUID, - ui64UpdateFenceUID, - ui64DeadlineInus, - ui32CycleEstimate); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline IMG_UINT32 _CalculateHostUfoPacketSize(RGX_HWPERF_UFO_EV eUfoType) -{ - IMG_UINT32 ui32Size = - (IMG_UINT32) offsetof(RGX_HWPERF_HOST_UFO_DATA, aui32StreamData); - RGX_HWPERF_UFO_DATA_ELEMENT *puData; - - switch (eUfoType) - { - case RGX_HWPERF_UFO_EV_CHECK_SUCCESS: - case RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS: - ui32Size += sizeof(puData->sCheckSuccess); - break; - case RGX_HWPERF_UFO_EV_CHECK_FAIL: - case RGX_HWPERF_UFO_EV_PRCHECK_FAIL: - ui32Size += sizeof(puData->sCheckFail); - break; - case RGX_HWPERF_UFO_EV_UPDATE: - ui32Size += sizeof(puData->sUpdate); - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostUfoEvent: Invalid UFO" - " event type")); - PVR_ASSERT(IMG_FALSE); - break; - } - - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -static inline void _SetupHostUfoPacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_UFO_EV eUfoType, - RGX_HWPERF_UFO_DATA_ELEMENT *psUFOData) -{ - RGX_HWPERF_HOST_UFO_DATA *psData = (RGX_HWPERF_HOST_UFO_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - RGX_HWPERF_UFO_DATA_ELEMENT *puData = (RGX_HWPERF_UFO_DATA_ELEMENT *) - psData->aui32StreamData; - - psData->eEvType = eUfoType; - /* HWPerfHost always emits 1 UFO at a time, since each UFO has 1-to-1 mapping - * with an underlying DevNode, and each DevNode has a dedicated HWPerf buffer */ - psData->ui32StreamInfo = RGX_HWPERF_MAKE_UFOPKTINFO(1, - offsetof(RGX_HWPERF_HOST_UFO_DATA, aui32StreamData)); - - switch (eUfoType) - { - case RGX_HWPERF_UFO_EV_CHECK_SUCCESS: - case RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS: - puData->sCheckSuccess.ui32FWAddr = - psUFOData->sCheckSuccess.ui32FWAddr; - puData->sCheckSuccess.ui32Value = - psUFOData->sCheckSuccess.ui32Value; - break; - case RGX_HWPERF_UFO_EV_CHECK_FAIL: - case RGX_HWPERF_UFO_EV_PRCHECK_FAIL: - puData->sCheckFail.ui32FWAddr = - psUFOData->sCheckFail.ui32FWAddr; - puData->sCheckFail.ui32Value = - psUFOData->sCheckFail.ui32Value; - puData->sCheckFail.ui32Required = - psUFOData->sCheckFail.ui32Required; - break; - case RGX_HWPERF_UFO_EV_UPDATE: - puData->sUpdate.ui32FWAddr = - psUFOData->sUpdate.ui32FWAddr; - puData->sUpdate.ui32OldValue = - psUFOData->sUpdate.ui32OldValue; - puData->sUpdate.ui32NewValue = - psUFOData->sUpdate.ui32NewValue; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostUfoEvent: Invalid UFO" - " event type")); - PVR_ASSERT(IMG_FALSE); - break; - } -} - -void RGXHWPerfHostPostUfoEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_UFO_EV eUfoType, - RGX_HWPERF_UFO_DATA_ELEMENT *psUFOData, - const IMG_BOOL bSleepAllowed) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size = _CalculateHostUfoPacketSize(eUfoType); - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - IMG_BOOL *pbPacketWritten = NULL; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - &pui8Dest, bSleepAllowed); - - if (bSleepAllowed) - { - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - } - else - { - if (pui8Dest == NULL) - { - // Give-up if we couldn't get a place in deferred events buffer - goto cleanup; - } - pbPacketWritten = GET_DE_EVENT_WRITE_STATUS(pui8Dest); - pui8Dest = GET_DE_EVENT_DATA(pui8Dest); - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_UFO, ui32Size, - ui32Ordinal, ui64Timestamp); - _SetupHostUfoPacketData(pui8Dest, eUfoType, psUFOData); - - if (bSleepAllowed) - { - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - } - else - { - *pbPacketWritten = IMG_TRUE; - OSScheduleMISR(psRgxDevInfo->pvHostHWPerfMISR); - } - -cleanup: - if (bSleepAllowed) - { - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); - } -} - -#define UNKNOWN_SYNC_NAME "UnknownSync" - -static_assert(PVRSRV_SYNC_NAME_LENGTH==PVRSRV_SYNC_NAME_LENGTH, "Sync class name max does not match Fence Sync name max"); - -static inline IMG_UINT32 _FixNameAndCalculateHostAllocPacketSize( - RGX_HWPERF_HOST_RESOURCE_TYPE eAllocType, - const IMG_CHAR **ppsName, - IMG_UINT32 *ui32NameSize) -{ - RGX_HWPERF_HOST_ALLOC_DATA *psData; - IMG_UINT32 ui32Size = offsetof(RGX_HWPERF_HOST_ALLOC_DATA, uAllocDetail); - - if (*ppsName != NULL && *ui32NameSize > 0) - { - /* if string longer than maximum cut it (leave space for '\0') */ - if (*ui32NameSize >= PVRSRV_SYNC_NAME_LENGTH) - *ui32NameSize = PVRSRV_SYNC_NAME_LENGTH; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "RGXHWPerfHostPostAllocEvent: Invalid" - " resource name given.")); - *ppsName = UNKNOWN_SYNC_NAME; - *ui32NameSize = sizeof(UNKNOWN_SYNC_NAME); - } - - switch (eAllocType) - { - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC: - ui32Size += sizeof(psData->uAllocDetail.sSyncAlloc) - PVRSRV_SYNC_NAME_LENGTH + - *ui32NameSize; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR: - ui32Size += sizeof(psData->uAllocDetail.sFenceAlloc) - PVRSRV_SYNC_NAME_LENGTH + - *ui32NameSize; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW: - ui32Size += sizeof(psData->uAllocDetail.sSWFenceAlloc) - PVRSRV_SYNC_NAME_LENGTH + - *ui32NameSize; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP: - ui32Size += sizeof(psData->uAllocDetail.sSyncCheckPointAlloc) - PVRSRV_SYNC_NAME_LENGTH + - *ui32NameSize; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "RGXHWPerfHostPostAllocEvent: Invalid alloc event type")); - PVR_ASSERT(IMG_FALSE); - break; - } - - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -static inline void _SetupHostAllocPacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_HOST_RESOURCE_TYPE eAllocType, - RGX_HWPERF_HOST_ALLOC_DETAIL *puAllocDetail, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize) -{ - RGX_HWPERF_HOST_ALLOC_DATA *psData = (RGX_HWPERF_HOST_ALLOC_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - - IMG_CHAR *acName = NULL; - - psData->ui32AllocType = eAllocType; - - switch (eAllocType) - { - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC: - psData->uAllocDetail.sSyncAlloc = puAllocDetail->sSyncAlloc; - acName = psData->uAllocDetail.sSyncAlloc.acName; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR: - psData->uAllocDetail.sFenceAlloc = puAllocDetail->sFenceAlloc; - acName = psData->uAllocDetail.sFenceAlloc.acName; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW: - psData->uAllocDetail.sSWFenceAlloc = puAllocDetail->sSWFenceAlloc; - acName = psData->uAllocDetail.sSWFenceAlloc.acName; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP: - psData->uAllocDetail.sSyncCheckPointAlloc = puAllocDetail->sSyncCheckPointAlloc; - acName = psData->uAllocDetail.sSyncCheckPointAlloc.acName; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "RGXHWPerfHostPostAllocEvent: Invalid alloc event type")); - PVR_ASSERT(IMG_FALSE); - } - - - if (acName != NULL) - { - if (ui32NameSize) - { - OSStringLCopy(acName, psName, ui32NameSize); - } - else - { - /* In case no name was given make sure we don't access random - * memory */ - acName[0] = '\0'; - } - } -} - -void RGXHWPerfHostPostAllocEvent(PVRSRV_RGXDEV_INFO* psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eAllocType, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize, - RGX_HWPERF_HOST_ALLOC_DETAIL *puAllocDetail) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT64 ui64Timestamp; - IMG_UINT32 ui32Ordinal; - IMG_UINT32 ui32Size = _FixNameAndCalculateHostAllocPacketSize(eAllocType, - &psName, - &ui32NameSize); - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_ALLOC, ui32Size, - ui32Ordinal, ui64Timestamp); - - _SetupHostAllocPacketData(pui8Dest, - eAllocType, - puAllocDetail, - psName, - ui32NameSize); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline void _SetupHostFreePacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_HOST_RESOURCE_TYPE eFreeType, - IMG_UINT64 ui64UID, - IMG_UINT32 ui32PID, - IMG_UINT32 ui32FWAddr) -{ - RGX_HWPERF_HOST_FREE_DATA *psData = (RGX_HWPERF_HOST_FREE_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - - psData->ui32FreeType = eFreeType; - - switch (eFreeType) - { - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC: - psData->uFreeDetail.sSyncFree.ui32FWAddr = ui32FWAddr; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR: - psData->uFreeDetail.sFenceDestroy.ui64Fence_UID = ui64UID; - break; - case RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP: - psData->uFreeDetail.sSyncCheckPointFree.ui32CheckPt_FWAddr = ui32FWAddr; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "RGXHWPerfHostPostFreeEvent: Invalid free event type")); - PVR_ASSERT(IMG_FALSE); - } -} - -void RGXHWPerfHostPostFreeEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eFreeType, - IMG_UINT64 ui64UID, - IMG_UINT32 ui32PID, - IMG_UINT32 ui32FWAddr) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size = RGX_HWPERF_MAKE_SIZE_FIXED(RGX_HWPERF_HOST_FREE_DATA); - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_FREE, ui32Size, - ui32Ordinal, ui64Timestamp); - _SetupHostFreePacketData(pui8Dest, - eFreeType, - ui64UID, - ui32PID, - ui32FWAddr); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline IMG_UINT32 _FixNameAndCalculateHostModifyPacketSize( - RGX_HWPERF_HOST_RESOURCE_TYPE eModifyType, - const IMG_CHAR **ppsName, - IMG_UINT32 *ui32NameSize) -{ - RGX_HWPERF_HOST_MODIFY_DATA *psData; - RGX_HWPERF_HOST_MODIFY_DETAIL *puData; - IMG_UINT32 ui32Size = sizeof(psData->ui32ModifyType); - - if (*ppsName != NULL && *ui32NameSize > 0) - { - /* first strip the terminator */ - if ((*ppsName)[*ui32NameSize - 1] == '\0') - *ui32NameSize -= 1; - /* if string longer than maximum cut it (leave space for '\0') */ - if (*ui32NameSize >= PVRSRV_SYNC_NAME_LENGTH) - *ui32NameSize = PVRSRV_SYNC_NAME_LENGTH - 1; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "RGXHWPerfHostPostModifyEvent: Invalid" - " resource name given.")); - *ppsName = UNKNOWN_SYNC_NAME; - *ui32NameSize = sizeof(UNKNOWN_SYNC_NAME) - 1; - } - - switch (eModifyType) - { - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR: - ui32Size += sizeof(puData->sFenceMerge) - PVRSRV_SYNC_NAME_LENGTH + - *ui32NameSize + 1; /* +1 for '\0' */ - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "RGXHWPerfHostPostModifyEvent: Invalid modify event type")); - PVR_ASSERT(IMG_FALSE); - break; - } - - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -static inline void _SetupHostModifyPacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_HOST_RESOURCE_TYPE eModifyType, - IMG_UINT64 ui64NewUID, - IMG_UINT64 ui64UID1, - IMG_UINT64 ui64UID2, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize) -{ - RGX_HWPERF_HOST_MODIFY_DATA *psData = (RGX_HWPERF_HOST_MODIFY_DATA *)IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - - IMG_CHAR *acName = NULL; - - psData->ui32ModifyType = eModifyType; - - switch (eModifyType) - { - case RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR: - psData->uModifyDetail.sFenceMerge.ui64NewFence_UID = ui64NewUID; - psData->uModifyDetail.sFenceMerge.ui64InFence1_UID = ui64UID1; - psData->uModifyDetail.sFenceMerge.ui64InFence2_UID = ui64UID2; - acName = psData->uModifyDetail.sFenceMerge.acName; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "RGXHWPerfHostPostModifyEvent: Invalid modify event type")); - PVR_ASSERT(IMG_FALSE); - } - - if (acName != NULL) - { - if (ui32NameSize) - { - OSStringLCopy(acName, psName, ui32NameSize); - } - else - { - /* In case no name was given make sure we don't access random - * memory */ - acName[0] = '\0'; - } - } -} - -void RGXHWPerfHostPostModifyEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eModifyType, - IMG_UINT64 ui64NewUID, - IMG_UINT64 ui64UID1, - IMG_UINT64 ui64UID2, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT64 ui64Timestamp; - IMG_UINT32 ui32Ordinal; - IMG_UINT32 ui32Size = _FixNameAndCalculateHostModifyPacketSize(eModifyType, - &psName, - &ui32NameSize); - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_MODIFY, ui32Size, - ui32Ordinal, ui64Timestamp); - _SetupHostModifyPacketData(pui8Dest, - eModifyType, - ui64NewUID, - ui64UID1, - ui64UID2, - psName, - ui32NameSize); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline void _SetupHostClkSyncPacketData(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT8 *pui8Dest) -{ - RGX_HWPERF_HOST_CLK_SYNC_DATA *psData = (RGX_HWPERF_HOST_CLK_SYNC_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psRgxDevInfo->psRGXFWIfGpuUtilFWCb; - IMG_UINT32 ui32CurrIdx = - RGXFWIF_TIME_CORR_CURR_INDEX(psGpuUtilFWCB->ui32TimeCorrSeqCount); - RGXFWIF_TIME_CORR *psTimeCorr = &psGpuUtilFWCB->sTimeCorr[ui32CurrIdx]; - - psData->ui64CRTimestamp = psTimeCorr->ui64CRTimeStamp; - psData->ui64OSTimestamp = psTimeCorr->ui64OSTimeStamp; - psData->ui32ClockSpeed = psTimeCorr->ui32CoreClockSpeed; -} - -void RGXHWPerfHostPostClkSyncEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size = - RGX_HWPERF_MAKE_SIZE_FIXED(RGX_HWPERF_HOST_CLK_SYNC_DATA); - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - /* if the buffer for time correlation data is not yet available (possibly - * device not initialised yet) skip this event */ - if (psRgxDevInfo->psRGXFWIfGpuUtilFWCb == NULL) - { - return; - } - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_CLK_SYNC, ui32Size, - ui32Ordinal, ui64Timestamp); - _SetupHostClkSyncPacketData(psRgxDevInfo, pui8Dest); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS _ConvDeviceHealthStatus(PVRSRV_DEVICE_HEALTH_STATUS eDeviceHealthStatus) -{ - switch (eDeviceHealthStatus) - { - case PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_UNDEFINED; - case PVRSRV_DEVICE_HEALTH_STATUS_OK: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_OK; - case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_RESPONDING; - case PVRSRV_DEVICE_HEALTH_STATUS_DEAD: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_DEAD; - case PVRSRV_DEVICE_HEALTH_STATUS_FAULT: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_FAULT; - default: return RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_UNDEFINED; - } -} - -static inline RGX_HWPERF_HOST_DEVICE_HEALTH_REASON _ConvDeviceHealthReason(PVRSRV_DEVICE_HEALTH_REASON eDeviceHealthReason) -{ - switch (eDeviceHealthReason) - { - case PVRSRV_DEVICE_HEALTH_REASON_NONE: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_NONE; - case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_ASSERTED; - case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_POLL_FAILING; - case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_TIMEOUTS; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_CORRUPT; - case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_STALLED; - case PVRSRV_DEVICE_HEALTH_REASON_IDLING: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_IDLING; - case PVRSRV_DEVICE_HEALTH_REASON_RESTARTING: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_RESTARTING; - case PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS:return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS; - default: return RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_UNDEFINED; - } -} - -static inline void _SetupHostDeviceInfoPacketData(RGX_HWPERF_DEV_INFO_EV eEvType, - PVRSRV_DEVICE_HEALTH_STATUS eDeviceHealthStatus, - PVRSRV_DEVICE_HEALTH_REASON eDeviceHealthReason, - IMG_UINT8 *pui8Dest) -{ - RGX_HWPERF_HOST_DEV_INFO_DATA *psData = (RGX_HWPERF_HOST_DEV_INFO_DATA *)IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - psData->eEvType = eEvType; - - switch (eEvType) - { - case RGX_HWPERF_DEV_INFO_EV_HEALTH: - psData->uDevInfoDetail.sDeviceStatus.eDeviceHealthStatus = _ConvDeviceHealthStatus(eDeviceHealthStatus); - psData->uDevInfoDetail.sDeviceStatus.eDeviceHealthReason = _ConvDeviceHealthReason(eDeviceHealthReason); - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostDeviceInfo: Invalid event type")); - PVR_ASSERT(IMG_FALSE); - break; - } -} - -static inline IMG_UINT32 _CalculateHostDeviceInfoPacketSize(RGX_HWPERF_DEV_INFO_EV eEvType) -{ - IMG_UINT32 ui32Size = offsetof(RGX_HWPERF_HOST_DEV_INFO_DATA, uDevInfoDetail); - - switch (eEvType) - { - case RGX_HWPERF_DEV_INFO_EV_HEALTH: - ui32Size += sizeof(((RGX_HWPERF_HOST_DEV_INFO_DATA*)0)->uDevInfoDetail.sDeviceStatus); - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostDeviceInfo: Invalid event type")); - PVR_ASSERT(IMG_FALSE); - break; - } - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -void RGXHWPerfHostPostDeviceInfo(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_DEV_INFO_EV eEvType, - PVRSRV_DEVICE_HEALTH_STATUS eDeviceHealthStatus, - PVRSRV_DEVICE_HEALTH_REASON eDeviceHealthReason) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - IMG_UINT32 ui32Size; - - OSLockAcquire(psRgxDevInfo->hHWPerfLock); - - if (psRgxDevInfo->hHWPerfHostStream != (IMG_HANDLE) NULL) - { - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - ui32Size = _CalculateHostDeviceInfoPacketSize(eEvType); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) != NULL) - { - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_DEV_INFO, ui32Size, ui32Ordinal, ui64Timestamp); - _SetupHostDeviceInfoPacketData(eEvType, eDeviceHealthStatus, eDeviceHealthReason, pui8Dest); - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - } - - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); - } - - OSLockRelease(psRgxDevInfo->hHWPerfLock); -} - -static inline void _SetupHostInfoPacketData(RGX_HWPERF_INFO_EV eEvType, - IMG_UINT32 ui32TotalMemoryUsage, - IMG_UINT32 ui32LivePids, - PVRSRV_PER_PROCESS_MEM_USAGE *psPerProcessMemUsage, - IMG_UINT8 *pui8Dest) -{ - IMG_INT i; - RGX_HWPERF_HOST_INFO_DATA *psData = (RGX_HWPERF_HOST_INFO_DATA *)IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - psData->eEvType = eEvType; - - switch (eEvType) - { - case RGX_HWPERF_INFO_EV_MEM_USAGE: - psData->uInfoDetail.sMemUsageStats.ui32TotalMemoryUsage = ui32TotalMemoryUsage; - - if (psPerProcessMemUsage) - { - for (i = 0; i < ui32LivePids; ++i) - { - psData->uInfoDetail.sMemUsageStats.sPerProcessUsage[i].ui32Pid = psPerProcessMemUsage[i].ui32Pid; - psData->uInfoDetail.sMemUsageStats.sPerProcessUsage[i].ui32KernelMemUsage = psPerProcessMemUsage[i].ui32KernelMemUsage; - psData->uInfoDetail.sMemUsageStats.sPerProcessUsage[i].ui32GraphicsMemUsage = psPerProcessMemUsage[i].ui32GraphicsMemUsage; - } - } - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostInfo: Invalid event type")); - PVR_ASSERT(IMG_FALSE); - break; - } -} - -static inline IMG_UINT32 _CalculateHostInfoPacketSize(RGX_HWPERF_INFO_EV eEvType, - IMG_UINT32 *pui32TotalMemoryUsage, - IMG_UINT32 *pui32LivePids, - PVRSRV_PER_PROCESS_MEM_USAGE **ppsPerProcessMemUsage) -{ - IMG_UINT32 ui32Size = offsetof(RGX_HWPERF_HOST_INFO_DATA, uInfoDetail); - - switch (eEvType) - { - case RGX_HWPERF_INFO_EV_MEM_USAGE: -#if !defined(__QNXNTO__) - if (PVRSRVGetProcessMemUsage(pui32TotalMemoryUsage, pui32LivePids, ppsPerProcessMemUsage) == PVRSRV_OK) - { - ui32Size += ((offsetof(RGX_HWPERF_HOST_INFO_DATA, uInfoDetail.sMemUsageStats.ui32TotalMemoryUsage) - ui32Size) - + ((*pui32LivePids) * sizeof(((RGX_HWPERF_HOST_INFO_DATA*)0)->uInfoDetail.sMemUsageStats.sPerProcessUsage))); - } -#else - PVR_DPF((PVR_DBG_ERROR, "This functionality is not yet implemented for this platform")); -#endif - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfHostPostInfo: Invalid event type")); - PVR_ASSERT(IMG_FALSE); - break; - } - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -void RGXHWPerfHostPostInfo(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_INFO_EV eEvType) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - IMG_UINT32 ui32TotalMemoryUsage = 0; - PVRSRV_PER_PROCESS_MEM_USAGE *psPerProcessMemUsage = NULL; - IMG_UINT32 ui32LivePids = 0; - - OSLockAcquire(psRgxDevInfo->hHWPerfLock); - - if (psRgxDevInfo->hHWPerfHostStream != (IMG_HANDLE) NULL) - { - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - ui32Size = _CalculateHostInfoPacketSize(eEvType, &ui32TotalMemoryUsage, &ui32LivePids, &psPerProcessMemUsage); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) != NULL) - { - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_INFO, ui32Size, ui32Ordinal, ui64Timestamp); - _SetupHostInfoPacketData(eEvType, ui32TotalMemoryUsage, ui32LivePids, psPerProcessMemUsage, pui8Dest); - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - } - - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); - - if (psPerProcessMemUsage) - OSFreeMemNoStats(psPerProcessMemUsage); // psPerProcessMemUsage was allocated with OSAllocZMemNoStats - } - - OSLockRelease(psRgxDevInfo->hHWPerfLock); -} - -static inline IMG_UINT32 -_CalculateHostFenceWaitPacketSize(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eWaitType) -{ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA *psSizeCalculator; - IMG_UINT32 ui32Size = offsetof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA, uDetail); - - switch (eWaitType) - { - case RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_BEGIN: - ui32Size += sizeof(psSizeCalculator->uDetail.sBegin); - break; - case RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_END: - ui32Size += sizeof(psSizeCalculator->uDetail.sEnd); - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid wait event type (%u)", __func__, - eWaitType)); - PVR_ASSERT(IMG_FALSE); - break; - } - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -static inline void -_SetupHostFenceWaitPacketData(IMG_UINT8 *pui8Dest, - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eWaitType, - IMG_PID uiPID, - PVRSRV_FENCE hFence, - IMG_UINT32 ui32Data) -{ - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA *psData = (RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - - psData->eType = eWaitType; - psData->uiPID = uiPID; - psData->hFence = hFence; - - switch (eWaitType) - { - case RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_BEGIN: - psData->uDetail.sBegin.ui32TimeoutInMs = ui32Data; - break; - case RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_END: - psData->uDetail.sEnd.eResult = - (RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT) ui32Data; - break; - default: - // unknown type - this should never happen - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid fence-wait event type", __func__)); - PVR_ASSERT(IMG_FALSE); - } -} - -void RGXHWPerfHostPostFenceWait(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eType, - IMG_PID uiPID, - PVRSRV_FENCE hFence, - IMG_UINT32 ui32Data) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - ui32Size = _CalculateHostFenceWaitPacketSize(eType); - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_SYNC_FENCE_WAIT, - ui32Size, ui32Ordinal, ui64Timestamp); - _SetupHostFenceWaitPacketData(pui8Dest, eType, uiPID, hFence, ui32Data); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -static inline IMG_UINT32 _CalculateHostSWTimelineAdvPacketSize(void) -{ - IMG_UINT32 ui32Size = sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA); - return RGX_HWPERF_MAKE_SIZE_VARIABLE(ui32Size); -} - -static inline void -_SetupHostSWTimelineAdvPacketData(IMG_UINT8 *pui8Dest, - IMG_PID uiPID, - PVRSRV_TIMELINE hSWTimeline, - IMG_UINT64 ui64SyncPtIndex) - -{ - RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA *psData = (RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA *) - IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - - psData->uiPID = uiPID; - psData->hTimeline = hSWTimeline; - psData->ui64SyncPtIndex = ui64SyncPtIndex; -} - -void RGXHWPerfHostPostSWTimelineAdv(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_PID uiPID, - PVRSRV_TIMELINE hSWTimeline, - IMG_UINT64 ui64SyncPtIndex) -{ - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, - NULL, IMG_TRUE); - - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - ui32Size = _CalculateHostSWTimelineAdvPacketSize(); - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_SYNC_SW_TL_ADVANCE, - ui32Size, ui32Ordinal, ui64Timestamp); - _SetupHostSWTimelineAdvPacketData(pui8Dest, uiPID, hSWTimeline, ui64SyncPtIndex); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); - -} - -void RGXHWPerfHostPostClientInfoProcName(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_PID uiPID, - const IMG_CHAR *psName) -{ - RGX_HWPERF_HOST_CLIENT_INFO_DATA* psPkt; - IMG_UINT8 *pui8Dest; - IMG_UINT32 ui32Size; - IMG_UINT32 ui32NameLen; - IMG_UINT32 ui32Ordinal; - IMG_UINT64 ui64Timestamp; - - _GetHWPerfHostPacketSpecifics(psRgxDevInfo, &ui32Ordinal, &ui64Timestamp, NULL, IMG_TRUE); - _PostFunctionPrologue(psRgxDevInfo, ui32Ordinal); - - ui32NameLen = OSStringLength(psName) + 1U; - ui32Size = RGX_HWPERF_MAKE_SIZE_VARIABLE(RGX_HWPERF_HOST_CLIENT_INFO_PROC_NAME_BASE_SIZE - + RGX_HWPERF_HOST_CLIENT_PROC_NAME_SIZE(ui32NameLen)); - - if ((pui8Dest = _ReserveHWPerfStream(psRgxDevInfo, ui32Size)) == NULL) - { - goto cleanup; - } - - _SetupHostPacketHeader(psRgxDevInfo, pui8Dest, RGX_HWPERF_HOST_CLIENT_INFO, - ui32Size, ui32Ordinal, ui64Timestamp); - - psPkt = (RGX_HWPERF_HOST_CLIENT_INFO_DATA*)IMG_OFFSET_ADDR(pui8Dest, sizeof(RGX_HWPERF_V2_PACKET_HDR)); - psPkt->eType = RGX_HWPERF_HOST_CLIENT_INFO_TYPE_PROCESS_NAME; - psPkt->uDetail.sProcName.ui32Count = 1U; - psPkt->uDetail.sProcName.asProcNames[0].uiClientPID = uiPID; - psPkt->uDetail.sProcName.asProcNames[0].ui32Length = ui32NameLen; - (void)OSStringLCopy(psPkt->uDetail.sProcName.asProcNames[0].acName, psName, ui32NameLen); - - _CommitHWPerfStream(psRgxDevInfo, ui32Size); - -cleanup: - _PostFunctionEpilogue(psRgxDevInfo, ui32Ordinal); -} - -/****************************************************************************** - * Currently only implemented on Linux. Feature can be enabled to provide - * an interface to 3rd-party kernel modules that wish to access the - * HWPerf data. The API is documented in the rgxapi_km.h header and - * the rgx_hwperf* headers. - *****************************************************************************/ - -/* Internal HWPerf kernel connection/device data object to track the state - * of a client session. - */ -typedef struct -{ - PVRSRV_DEVICE_NODE* psRgxDevNode; - PVRSRV_RGXDEV_INFO* psRgxDevInfo; - - /* TL Open/close state */ - IMG_HANDLE hSD[RGX_HWPERF_MAX_STREAM_ID]; - - /* TL Acquire/release state */ - IMG_PBYTE pHwpBuf[RGX_HWPERF_MAX_STREAM_ID]; /*!< buffer returned to user in acquire call */ - IMG_PBYTE pHwpBufEnd[RGX_HWPERF_MAX_STREAM_ID]; /*!< pointer to end of HwpBuf */ - IMG_PBYTE pTlBuf[RGX_HWPERF_MAX_STREAM_ID]; /*!< buffer obtained via TlAcquireData */ - IMG_PBYTE pTlBufPos[RGX_HWPERF_MAX_STREAM_ID]; /*!< initial position in TlBuf to acquire packets */ - IMG_PBYTE pTlBufRead[RGX_HWPERF_MAX_STREAM_ID]; /*!< pointer to the last packet read */ - IMG_UINT32 ui32AcqDataLen[RGX_HWPERF_MAX_STREAM_ID]; /*!< length of acquired TlBuf */ - IMG_BOOL bRelease[RGX_HWPERF_MAX_STREAM_ID]; /*!< used to determine whether or not to release currently held TlBuf */ - - -} RGX_KM_HWPERF_DEVDATA; - -PVRSRV_ERROR RGXHWPerfLazyConnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; - RGX_KM_HWPERF_DEVDATA *psDevData; - RGX_HWPERF_DEVICE *psNewHWPerfDevice; - RGX_HWPERF_CONNECTION* psHWPerfConnection; - IMG_BOOL bFWActive = IMG_FALSE; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* avoid uninitialised data */ - PVR_ASSERT(*ppsHWPerfConnection == NULL); - PVR_ASSERT(psPVRSRVData); - - /* Allocate connection object */ - psHWPerfConnection = OSAllocZMem(sizeof(*psHWPerfConnection)); - if (!psHWPerfConnection) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - /* early save the return pointer to aid clean-up if failure occurs */ - *ppsHWPerfConnection = psHWPerfConnection; - - OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock); - psDeviceNode = psPVRSRVData->psDeviceNodeList; - - while (psDeviceNode) - { - if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: HWPerf: Device not currently active. ID:%u", - __func__, - psDeviceNode->sDevId.i32OsDeviceID)); - psDeviceNode = psDeviceNode->psNext; - continue; - } - /* Create a list node to be attached to connection object's list */ - psNewHWPerfDevice = OSAllocMem(sizeof(*psNewHWPerfDevice)); - if (!psNewHWPerfDevice) - { - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - /* Insert node at head of the list */ - psNewHWPerfDevice->psNext = psHWPerfConnection->psHWPerfDevList; - psHWPerfConnection->psHWPerfDevList = psNewHWPerfDevice; - - /* create a device data object for kernel server */ - psDevData = OSAllocZMem(sizeof(*psDevData)); - psNewHWPerfDevice->hDevData = (IMG_HANDLE)psDevData; - if (!psDevData) - { - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - if (OSSNPrintf(psNewHWPerfDevice->pszName, sizeof(psNewHWPerfDevice->pszName), - "hwperf_device_%d", psDeviceNode->sDevId.i32OsDeviceID) < 0) - { - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf device name for device %d", - __func__, - psDeviceNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevData->psRgxDevNode = psDeviceNode; - psDevData->psRgxDevInfo = psDeviceNode->pvDevice; - - psDeviceNode = psDeviceNode->psNext; - - /* At least one device is active */ - bFWActive = IMG_TRUE; - } - - OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock); - - if (!bFWActive) - { - return PVRSRV_ERROR_NOT_READY; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXHWPerfOpen(RGX_HWPERF_CONNECTION *psHWPerfConnection) -{ - RGX_KM_HWPERF_DEVDATA *psDevData; - RGX_HWPERF_DEVICE *psHWPerfDev; - PVRSRV_RGXDEV_INFO *psRgxDevInfo; - PVRSRV_ERROR eError; - IMG_CHAR pszHWPerfFwStreamName[sizeof(PVRSRV_TL_HWPERF_RGX_FW_STREAM) + 5]; - IMG_CHAR pszHWPerfHostStreamName[sizeof(PVRSRV_TL_HWPERF_HOST_SERVER_STREAM) + 5]; - IMG_UINT32 ui32BufSize; - - /* Disable producer callback by default for the Kernel API. */ - IMG_UINT32 ui32StreamFlags = PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING | - PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Validate input argument values supplied by the caller */ - if (!psHWPerfConnection) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - while (psHWPerfDev) - { - psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - psRgxDevInfo = psDevData->psRgxDevInfo; - - /* In the case where the AppHint has not been set we need to - * initialise the HWPerf resources here. Allocated on-demand - * to reduce RAM foot print on systems not needing HWPerf. - */ - OSLockAcquire(psRgxDevInfo->hHWPerfLock); - if (RGXHWPerfIsInitRequired(psRgxDevInfo)) - { - eError = RGXHWPerfInitOnDemandResources(psRgxDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Initialisation of on-demand HWPerfFW resources failed", - __func__)); - OSLockRelease(psRgxDevInfo->hHWPerfLock); - return eError; - } - } - OSLockRelease(psRgxDevInfo->hHWPerfLock); - - OSLockAcquire(psRgxDevInfo->hLockHWPerfHostStream); - if (psRgxDevInfo->hHWPerfHostStream == NULL) - { - eError = RGXHWPerfHostInitOnDemandResources(psRgxDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Initialisation of on-demand HWPerfHost resources failed", - __func__)); - OSLockRelease(psRgxDevInfo->hLockHWPerfHostStream); - return eError; - } - } - OSLockRelease(psRgxDevInfo->hLockHWPerfHostStream); - - /* form the HWPerf stream name, corresponding to this DevNode; which can make sense in the UM */ - if (OSSNPrintf(pszHWPerfFwStreamName, sizeof(pszHWPerfFwStreamName), "%s%d", - PVRSRV_TL_HWPERF_RGX_FW_STREAM, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID) < 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf stream name for device %d", - __func__, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - /* Open the RGX TL stream for reading in this session */ - eError = TLClientOpenStream(DIRECT_BRIDGE_HANDLE, - pszHWPerfFwStreamName, - ui32StreamFlags, - &psDevData->hSD[RGX_HWPERF_STREAM_ID0_FW]); - PVR_LOG_RETURN_IF_ERROR(eError, "TLClientOpenStream(RGX_HWPerf)"); - - /* form the HWPerf host stream name, corresponding to this DevNode; which can make sense in the UM */ - if (OSSNPrintf(pszHWPerfHostStreamName, sizeof(pszHWPerfHostStreamName), "%s%d", - PVRSRV_TL_HWPERF_HOST_SERVER_STREAM, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID) < 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to form HWPerf host stream name for device %d", - __func__, - psRgxDevInfo->psDeviceNode->sDevId.i32OsDeviceID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Open the host TL stream for reading in this session */ - eError = TLClientOpenStream(DIRECT_BRIDGE_HANDLE, - pszHWPerfHostStreamName, - PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING, - &psDevData->hSD[RGX_HWPERF_STREAM_ID1_HOST]); - PVR_LOG_RETURN_IF_ERROR(eError, "TLClientOpenStream(Host_HWPerf)"); - - /* Allocate a large enough buffer for use during the entire session to - * avoid the need to resize in the Acquire call as this might be in an ISR - * Choose size that can contain at least one packet. - */ - /* Allocate buffer for FW Stream */ - ui32BufSize = FW_STREAM_BUFFER_SIZE; - psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID0_FW] = OSAllocMem(ui32BufSize); - if (psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID0_FW] == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - psDevData->pHwpBufEnd[RGX_HWPERF_STREAM_ID0_FW] = psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID0_FW]+ui32BufSize; - - /* Allocate buffer for Host Stream */ - ui32BufSize = HOST_STREAM_BUFFER_SIZE; - psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID1_HOST] = OSAllocMem(ui32BufSize); - if (psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID1_HOST] == NULL) - { - OSFreeMem(psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID0_FW]); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - psDevData->pHwpBufEnd[RGX_HWPERF_STREAM_ID1_HOST] = psDevData->pHwpBuf[RGX_HWPERF_STREAM_ID1_HOST]+ui32BufSize; - - psHWPerfDev = psHWPerfDev->psNext; - } - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXHWPerfConnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection) -{ - PVRSRV_ERROR eError; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - eError = RGXHWPerfLazyConnect(ppsHWPerfConnection); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXHWPerfLazyConnect", e0); - - eError = RGXHWPerfOpen(*ppsHWPerfConnection); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXHWPerfOpen", e1); - - return PVRSRV_OK; - -e1: /* HWPerfOpen might have opened some, and then failed */ - RGXHWPerfClose(*ppsHWPerfConnection); -e0: /* LazyConnect might have allocated some resources and then failed, - * make sure they are cleaned up */ - RGXHWPerfFreeConnection(ppsHWPerfConnection); - return eError; -} - -/* - PVRSRVRGXControlHWPerfBlocksKM - */ -PVRSRV_ERROR PVRSRVRGXControlHWPerfBlocksKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_BOOL bEnable, - IMG_UINT32 ui32ArrayLen, - IMG_UINT16 * psBlockIDs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sKccbCmd; - IMG_UINT32 ui32kCCBCommandSlot; - PVRSRV_RGXDEV_INFO *psDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - PVR_DPF_ENTERED; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psBlockIDs != NULL, "psBlockIDs"); - PVR_LOG_RETURN_IF_INVALID_PARAM((ui32ArrayLen>0) && (ui32ArrayLen <= RGXFWIF_HWPERF_CTRL_BLKS_MAX), "ui32ArrayLen"); - - PVR_ASSERT(psDeviceNode); - psDevice = psDeviceNode->pvDevice; - - /* Fill in the command structure with the parameters needed - */ - sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS; - sKccbCmd.uCmdData.sHWPerfCtrlBlks.bEnable = bEnable; - sKccbCmd.uCmdData.sHWPerfCtrlBlks.ui32NumBlocks = ui32ArrayLen; - - OSDeviceMemCopy(sKccbCmd.uCmdData.sHWPerfCtrlBlks.aeBlockIDs, psBlockIDs, sizeof(IMG_UINT16) * ui32ArrayLen); - - - /* Ask the FW to carry out the HWPerf configuration command - */ - eError = RGXScheduleCommandAndGetKCCBSlot(psDevice, - RGXFWIF_DM_GP, - &sKccbCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot"); - - /* Wait for FW to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevice, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXWaitForKCCBSlotUpdate"); - - -#if defined(DEBUG) - if (bEnable) - PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks have been ENABLED", ui32ArrayLen)); - else - PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks have been DISABLED", ui32ArrayLen)); -#endif - - PVR_DPF_RETURN_OK; -} - -/* - PVRSRVRGXCtrlHWPerfKM - */ -PVRSRV_ERROR PVRSRVRGXCtrlHWPerfKM( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_BOOL bToggle, - IMG_UINT64 ui64Mask) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - PVR_DPF_ENTERED; - PVR_ASSERT(psDeviceNode); - - if (eStreamId == RGX_HWPERF_STREAM_ID0_FW) - { - return RGXHWPerfCtrlFwBuffer(psDeviceNode, bToggle, ui64Mask); - } - else if (eStreamId == RGX_HWPERF_STREAM_ID1_HOST) - { - return RGXHWPerfCtrlHostBuffer(psDeviceNode, bToggle, (IMG_UINT32) ui64Mask); - } - else if (eStreamId == RGX_HWPERF_STREAM_ID2_CLIENT) - { - IMG_UINT32 ui32Index = (IMG_UINT32) (ui64Mask >> 32); - IMG_UINT32 ui32Mask = (IMG_UINT32) ui64Mask; - - return RGXHWPerfCtrlClientBuffer(bToggle, ui32Index, ui32Mask); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXCtrlHWPerfKM: Unknown stream id.")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_DPF_RETURN_OK; -} - -PVRSRV_ERROR RGXHWPerfControl( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_BOOL bToggle, - IMG_UINT64 ui64Mask) -{ - PVRSRV_ERROR eError; - RGX_KM_HWPERF_DEVDATA* psDevData; - RGX_HWPERF_DEVICE* psHWPerfDev; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Validate input argument values supplied by the caller */ - if (!psHWPerfConnection) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - - while (psHWPerfDev) - { - psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - - /* Call the internal server API */ - eError = PVRSRVRGXCtrlHWPerfKM(NULL, psDevData->psRgxDevNode, eStreamId, bToggle, ui64Mask); - PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM"); - - psHWPerfDev = psHWPerfDev->psNext; - } - - return PVRSRV_OK; -} - - -IMG_INTERNAL PVRSRV_ERROR RGXHWPerfToggleCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs, - IMG_BOOL bToggle, - const char* szFunctionString); - -IMG_INTERNAL PVRSRV_ERROR RGXHWPerfToggleCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs, - IMG_BOOL bToggle, - const char* szFunctionString) -{ - PVRSRV_ERROR eError; - RGX_KM_HWPERF_DEVDATA* psDevData; - RGX_HWPERF_DEVICE* psHWPerfDev; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - if (!psHWPerfConnection || ui32NumBlocks==0 || !aeBlockIDs) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32NumBlocks > RGXFWIF_HWPERF_CTRL_BLKS_MAX) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - - while (psHWPerfDev) - { - psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - - /* Call the internal server API */ - eError = PVRSRVRGXControlHWPerfBlocksKM(NULL, - psDevData->psRgxDevNode, - bToggle, - ui32NumBlocks, - aeBlockIDs); - - PVR_LOG_RETURN_IF_ERROR(eError, szFunctionString); - - psHWPerfDev = psHWPerfDev->psNext; - } - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXHWPerfDisableCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs) -{ - return RGXHWPerfToggleCounters(psHWPerfConnection, - ui32NumBlocks, - aeBlockIDs, - IMG_FALSE, - __func__); -} - - -PVRSRV_ERROR RGXHWPerfEnableCounters( - RGX_HWPERF_CONNECTION *psHWPerfConnection, - IMG_UINT32 ui32NumBlocks, - IMG_UINT16* aeBlockIDs) -{ - return RGXHWPerfToggleCounters(psHWPerfConnection, - ui32NumBlocks, - aeBlockIDs, - IMG_TRUE, - __func__); -} - - -PVRSRV_ERROR RGXHWPerfAcquireEvents( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_PBYTE* ppBuf, - IMG_UINT32* pui32BufLen) -{ - PVRSRV_ERROR eError; - RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData; - IMG_PBYTE pDataDest; - IMG_UINT32 ui32TlPackets = 0; - IMG_PBYTE pBufferEnd; - PVRSRVTL_PPACKETHDR psHDRptr; - PVRSRVTL_PACKETTYPE ui16TlType; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Reset the output arguments in case we discover an error */ - *ppBuf = NULL; - *pui32BufLen = 0; - - /* Valid input argument values supplied by the caller */ - if (!psDevData || eStreamId >= RGX_HWPERF_MAX_STREAM_ID) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (psDevData->pTlBuf[eStreamId] == NULL) - { - /* Acquire some data to read from the HWPerf TL stream */ - eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE, - psDevData->hSD[eStreamId], - &psDevData->pTlBuf[eStreamId], - &psDevData->ui32AcqDataLen[eStreamId]); - PVR_LOG_RETURN_IF_ERROR(eError, "TLClientAcquireData"); - - psDevData->pTlBufPos[eStreamId] = psDevData->pTlBuf[eStreamId]; - } - - /* TL indicates no data exists so return OK and zero. */ - if ((psDevData->pTlBufPos[eStreamId] == NULL) || (psDevData->ui32AcqDataLen[eStreamId] == 0)) - { - return PVRSRV_OK; - } - - /* Process each TL packet in the data buffer we have acquired */ - pBufferEnd = psDevData->pTlBuf[eStreamId]+psDevData->ui32AcqDataLen[eStreamId]; - pDataDest = psDevData->pHwpBuf[eStreamId]; - psHDRptr = GET_PACKET_HDR(psDevData->pTlBufPos[eStreamId]); - psDevData->pTlBufRead[eStreamId] = psDevData->pTlBufPos[eStreamId]; - while (psHDRptr < (PVRSRVTL_PPACKETHDR)((void *)pBufferEnd)) - { - ui16TlType = GET_PACKET_TYPE(psHDRptr); - if (ui16TlType == PVRSRVTL_PACKETTYPE_DATA) - { - IMG_UINT16 ui16DataLen = GET_PACKET_DATA_LEN(psHDRptr); - if (0 == ui16DataLen) - { - PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfAcquireEvents: ZERO Data in TL data packet: %p", psHDRptr)); - } - else - { - /* Check next packet does not fill buffer */ - if (pDataDest + ui16DataLen > psDevData->pHwpBufEnd[eStreamId]) - { - break; - } - - /* For valid data copy it into the client buffer and move - * the write position on */ - OSDeviceMemCopy(pDataDest, GET_PACKET_DATA_PTR(psHDRptr), ui16DataLen); - pDataDest += ui16DataLen; - } - } - else if (ui16TlType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED) - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfAcquireEvents: Indication that the transport buffer was full")); - } - else - { - /* else Ignore padding packet type and others */ - PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfAcquireEvents: Ignoring TL packet, type %d", ui16TlType )); - } - - /* Update loop variable to the next packet and increment counts */ - psHDRptr = GET_NEXT_PACKET_ADDR(psHDRptr); - /* Updated to keep track of the next packet to be read. */ - psDevData->pTlBufRead[eStreamId] = (IMG_PBYTE) ((void *)psHDRptr); - ui32TlPackets++; - } - - PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfAcquireEvents: TL Packets processed %03d", ui32TlPackets)); - - psDevData->bRelease[eStreamId] = IMG_FALSE; - if (psHDRptr >= (PVRSRVTL_PPACKETHDR)((void *)pBufferEnd)) - { - psDevData->bRelease[eStreamId] = IMG_TRUE; - } - - /* Update output arguments with client buffer details and true length */ - *ppBuf = psDevData->pHwpBuf[eStreamId]; - *pui32BufLen = pDataDest - psDevData->pHwpBuf[eStreamId]; - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXHWPerfReleaseEvents( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Valid input argument values supplied by the caller */ - if (!psDevData || eStreamId >= RGX_HWPERF_MAX_STREAM_ID) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (psDevData->bRelease[eStreamId]) - { - /* Inform the TL that we are done with reading the data. */ - eError = TLClientReleaseData(DIRECT_BRIDGE_HANDLE, psDevData->hSD[eStreamId]); - psDevData->ui32AcqDataLen[eStreamId] = 0; - psDevData->pTlBuf[eStreamId] = NULL; - } - else - { - psDevData->pTlBufPos[eStreamId] = psDevData->pTlBufRead[eStreamId]; - } - return eError; -} - - -PVRSRV_ERROR RGXHWPerfGetFilter( - IMG_HANDLE hDevData, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_UINT64 *ui64Filter) -{ - PVRSRV_RGXDEV_INFO* psRgxDevInfo = - hDevData ? ((RGX_KM_HWPERF_DEVDATA*) hDevData)->psRgxDevInfo : NULL; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - /* Valid input argument values supplied by the caller */ - if (!psRgxDevInfo) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pointer to the RGX device", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* No need to take hHWPerfLock here since we are only reading data - * from always existing integers to return to debugfs which is an - * atomic operation. - */ - switch (eStreamId) { - case RGX_HWPERF_STREAM_ID0_FW: - *ui64Filter = psRgxDevInfo->ui64HWPerfFilter; - break; - case RGX_HWPERF_STREAM_ID1_HOST: - *ui64Filter = psRgxDevInfo->ui32HWPerfHostFilter; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid stream ID", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXHWPerfFreeConnection(RGX_HWPERF_CONNECTION** ppsHWPerfConnection) -{ - RGX_HWPERF_DEVICE *psHWPerfDev, *psHWPerfNextDev; - RGX_HWPERF_CONNECTION *psHWPerfConnection = *ppsHWPerfConnection; - - /* if connection object itself is NULL, nothing to free */ - if (psHWPerfConnection == NULL) - { - return PVRSRV_OK; - } - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - psHWPerfNextDev = psHWPerfConnection->psHWPerfDevList; - while (psHWPerfNextDev) - { - psHWPerfDev = psHWPerfNextDev; - psHWPerfNextDev = psHWPerfNextDev->psNext; - - /* Free the session memory */ - if (psHWPerfDev->hDevData) - OSFreeMem(psHWPerfDev->hDevData); - OSFreeMem(psHWPerfDev); - } - OSFreeMem(psHWPerfConnection); - *ppsHWPerfConnection = NULL; - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXHWPerfClose(RGX_HWPERF_CONNECTION *psHWPerfConnection) -{ - RGX_HWPERF_DEVICE *psHWPerfDev; - RGX_KM_HWPERF_DEVDATA* psDevData; - IMG_UINT uiStreamId; - PVRSRV_ERROR eError; - - /* Check session connection is not zero */ - if (!psHWPerfConnection) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - psHWPerfDev = psHWPerfConnection->psHWPerfDevList; - while (psHWPerfDev) - { - psDevData = (RGX_KM_HWPERF_DEVDATA *) psHWPerfDev->hDevData; - for (uiStreamId = 0; uiStreamId < RGX_HWPERF_MAX_STREAM_ID; uiStreamId++) - { - /* If the TL buffer exists they have not called ReleaseData - * before disconnecting so clean it up */ - if (psDevData->pTlBuf[uiStreamId]) - { - /* TLClientReleaseData call and null out the buffer fields - * and length */ - eError = TLClientReleaseData(DIRECT_BRIDGE_HANDLE, psDevData->hSD[uiStreamId]); - psDevData->ui32AcqDataLen[uiStreamId] = 0; - psDevData->pTlBuf[uiStreamId] = NULL; - PVR_LOG_IF_ERROR(eError, "TLClientReleaseData"); - /* Packets may be lost if release was not required */ - if (!psDevData->bRelease[uiStreamId]) - { - PVR_DPF((PVR_DBG_WARNING, "RGXHWPerfClose: Events in buffer waiting to be read, remaining events may be lost.")); - } - } - - /* Close the TL stream, ignore the error if it occurs as we - * are disconnecting */ - if (psDevData->hSD[uiStreamId]) - { - eError = TLClientCloseStream(DIRECT_BRIDGE_HANDLE, - psDevData->hSD[uiStreamId]); - PVR_LOG_IF_ERROR(eError, "TLClientCloseStream"); - psDevData->hSD[uiStreamId] = NULL; - } - - /* Free the client buffer used in session */ - if (psDevData->pHwpBuf[uiStreamId]) - { - OSFreeMem(psDevData->pHwpBuf[uiStreamId]); - psDevData->pHwpBuf[uiStreamId] = NULL; - } - } - psHWPerfDev = psHWPerfDev->psNext; - } - - return PVRSRV_OK; -} - - -PVRSRV_ERROR RGXHWPerfDisconnect(RGX_HWPERF_CONNECTION** ppsHWPerfConnection) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_IMPLEMENTED); - - eError = RGXHWPerfClose(*ppsHWPerfConnection); - PVR_LOG_IF_ERROR(eError, "RGXHWPerfClose"); - - eError = RGXHWPerfFreeConnection(ppsHWPerfConnection); - PVR_LOG_IF_ERROR(eError, "RGXHWPerfFreeConnection"); - - return eError; -} - -IMG_UINT64 RGXHWPerfConvertCRTimeStamp( - IMG_UINT32 ui32ClkSpeed, - IMG_UINT64 ui64CorrCRTimeStamp, - IMG_UINT64 ui64CorrOSTimeStamp, - IMG_UINT64 ui64CRTimeStamp) -{ - IMG_UINT64 ui64CRDeltaToOSDeltaKNs; - IMG_UINT64 ui64EventOSTimestamp, deltaRgxTimer, delta_ns; - - if (!(ui64CRTimeStamp) || !(ui32ClkSpeed) || !(ui64CorrCRTimeStamp) || !(ui64CorrOSTimeStamp)) - { - return 0; - } - - ui64CRDeltaToOSDeltaKNs = RGXTimeCorrGetConversionFactor(ui32ClkSpeed); - - /* RGX CR timer ticks delta */ - deltaRgxTimer = ui64CRTimeStamp - ui64CorrCRTimeStamp; - /* RGX time delta in nanoseconds */ - delta_ns = RGXFWIF_GET_DELTA_OSTIME_NS(deltaRgxTimer, ui64CRDeltaToOSDeltaKNs); - /* Calculate OS time of HWPerf event */ - ui64EventOSTimestamp = ui64CorrOSTimeStamp + delta_ns; - - return ui64EventOSTimestamp; -} - -/****************************************************************************** - End of file (rgxhwperf_common.c) - ******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.h b/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.h deleted file mode 100644 index 50e3ce2f532e8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxhwperf_common.h +++ /dev/null @@ -1,512 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX HW Performance header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX HWPerf functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXHWPERF_COMMON_H_ -#define RGXHWPERF_COMMON_H_ - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" - -#include "device.h" -#include "connection_server.h" -#include "rgxdevice.h" -#include "rgx_hwperf.h" - -/* HWPerf host buffer size constraints in KBs */ -#define HWPERF_HOST_TL_STREAM_SIZE_DEFAULT PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB -#define HWPERF_HOST_TL_STREAM_SIZE_MIN (32U) -#define HWPERF_HOST_TL_STREAM_SIZE_MAX (3072U) - -/****************************************************************************** - * RGX HW Performance decode Bvnc Features for HWPerf - *****************************************************************************/ -PVRSRV_ERROR RGXServerFeatureFlagsToHWPerfFlags(PVRSRV_RGXDEV_INFO *psDevInfo, - RGX_HWPERF_BVNC *psBVNC); - -PVRSRV_ERROR PVRSRVRGXGetHWPerfBvncFeatureFlagsKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_HWPERF_BVNC *psBVNC); - -/****************************************************************************** - * RGX HW Performance Data Transport Routines - *****************************************************************************/ - -PVRSRV_ERROR RGXHWPerfDataStoreCB(PVRSRV_DEVICE_NODE* psDevInfo); - -PVRSRV_ERROR RGXHWPerfInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo); -PVRSRV_ERROR RGXHWPerfInitOnDemandResources(PVRSRV_RGXDEV_INFO* psRgxDevInfo); -void RGXHWPerfDeinit(PVRSRV_RGXDEV_INFO *psRgxDevInfo); -void RGXHWPerfInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode); -void RGXHWPerfClientInitAppHintCallbacks(void); - -/****************************************************************************** - * RGX HW Performance Profiling API(s) - *****************************************************************************/ - -PVRSRV_ERROR PVRSRVRGXCtrlHWPerfKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - RGX_HWPERF_STREAM_ID eStreamId, - IMG_BOOL bToggle, - IMG_UINT64 ui64Mask); - -PVRSRV_ERROR PVRSRVRGXControlHWPerfBlocksKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_BOOL bEnable, - IMG_UINT32 ui32ArrayLen, - IMG_UINT16 * psBlockIDs); - -/****************************************************************************** - * RGX HW Performance Host Stream API - *****************************************************************************/ - -PVRSRV_ERROR RGXHWPerfHostInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo, IMG_UINT32 ui32BufSizeKB); -PVRSRV_ERROR RGXHWPerfHostInitOnDemandResources(PVRSRV_RGXDEV_INFO* psRgxDevInfo); -void RGXHWPerfHostDeInit(PVRSRV_RGXDEV_INFO *psRgxDevInfo); - -void RGXHWPerfHostSetEventFilter(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_UINT32 ui32Filter); - -void RGXHWPerfHostPostRaw(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_EVENT_TYPE eEvType, - IMG_BYTE *pbPayload, - IMG_UINT32 ui32PayloadSize); - -void RGXHWPerfHostPostEnqEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_KICK_TYPE eEnqType, - IMG_UINT32 ui32Pid, - IMG_UINT32 ui32FWDMContext, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - PVRSRV_FENCE hCheckFence, - PVRSRV_FENCE hUpdateFence, - PVRSRV_TIMELINE hUpdateTimeline, - IMG_UINT64 ui64CheckFenceUID, - IMG_UINT64 ui64UpdateFenceUID, - IMG_UINT64 ui64DeadlineInus, - IMG_UINT32 ui32CycleEstimate); - -void RGXHWPerfHostPostAllocEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eAllocType, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize, - RGX_HWPERF_HOST_ALLOC_DETAIL *puAllocDetail); - -void RGXHWPerfHostPostFreeEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eFreeType, - IMG_UINT64 ui64UID, - IMG_UINT32 ui32PID, - IMG_UINT32 ui32FWAddr); - -void RGXHWPerfHostPostModifyEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_RESOURCE_TYPE eModifyType, - IMG_UINT64 ui64NewUID, - IMG_UINT64 ui64UID1, - IMG_UINT64 ui64UID2, - const IMG_CHAR *psName, - IMG_UINT32 ui32NameSize); - -void RGXHWPerfHostPostUfoEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_UFO_EV eUfoType, - RGX_HWPERF_UFO_DATA_ELEMENT *psUFOData, - const IMG_BOOL bSleepAllowed); - -void RGXHWPerfHostPostClkSyncEvent(PVRSRV_RGXDEV_INFO *psRgxDevInfo); - -void RGXHWPerfHostPostDeviceInfo(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_DEV_INFO_EV eEvType, - PVRSRV_DEVICE_HEALTH_STATUS eDeviceHealthStatus, - PVRSRV_DEVICE_HEALTH_REASON eDeviceHeathReason); - -void RGXHWPerfHostPostInfo(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_INFO_EV eEvType); - -void RGXHWPerfHostPostFenceWait(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eType, - IMG_PID uiPID, - PVRSRV_FENCE hFence, - IMG_UINT32 ui32Data); - -void RGXHWPerfHostPostSWTimelineAdv(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_PID uiPID, - PVRSRV_TIMELINE hSWTimeline, - IMG_UINT64 ui64SyncPtIndex); - -void RGXHWPerfHostPostClientInfoProcName(PVRSRV_RGXDEV_INFO *psRgxDevInfo, - IMG_PID uiPID, - const IMG_CHAR *psName); - -IMG_BOOL RGXHWPerfHostIsEventEnabled(PVRSRV_RGXDEV_INFO *psRgxDevInfo, RGX_HWPERF_HOST_EVENT_TYPE eEvent); - -#define _RGX_HWPERF_HOST_FILTER(CTX, EV) \ - (((PVRSRV_RGXDEV_INFO *)CTX->psDeviceNode->pvDevice)->ui32HWPerfHostFilter \ - & RGX_HWPERF_EVENT_MASK_VALUE(EV)) - -#define _RGX_DEVICE_INFO_FROM_CTX(CTX) \ - ((PVRSRV_RGXDEV_INFO *)CTX->psDeviceNode->pvDevice) - -#define _RGX_DEVICE_INFO_FROM_NODE(DEVNODE) \ - ((PVRSRV_RGXDEV_INFO *)DEVNODE->pvDevice) - -/* Deadline and cycle estimate is not supported for all ENQ events */ -#define NO_DEADLINE 0 -#define NO_CYCEST 0 - - -#if defined(SUPPORT_RGX) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param C Kick context - * @param P Pid of kicking process - * @param X Related FW context - * @param E External job reference - * @param I Job ID - * @param K Kick type - * @param CF Check fence handle - * @param UF Update fence handle - * @param UT Update timeline (on which above UF was created) handle - * @param CHKUID Check fence UID - * @param UPDUID Update fence UID - * @param D Deadline - * @param CE Cycle estimate - */ -#define RGXSRV_HWPERF_ENQ(C, P, X, E, I, K, CF, UF, UT, CHKUID, UPDUID, D, CE) \ - do { \ - if (_RGX_HWPERF_HOST_FILTER(C, RGX_HWPERF_HOST_ENQ)) \ - { \ - RGXHWPerfHostPostEnqEvent(_RGX_DEVICE_INFO_FROM_CTX(C), \ - (K), (P), (X), (E), (I), \ - (CF), (UF), (UT), \ - (CHKUID), (UPDUID), (D), (CE)); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param I Device Info pointer - * @param T Host UFO event type - * @param D Pointer to UFO data - * @param S Is sleeping allowed? - */ -#define RGXSRV_HWPERF_UFO(I, T, D, S) \ - do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_UFO)) \ - { \ - RGXHWPerfHostPostUfoEvent((I), (T), (D), (S)); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param D Device node pointer - * @param T Host ALLOC event type - * @param FWADDR sync firmware address - * @param N string containing sync name - * @param Z string size including null terminating character - */ -#define RGXSRV_HWPERF_ALLOC(D, T, FWADDR, N, Z) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_ALLOC)) \ - { \ - RGX_HWPERF_HOST_ALLOC_DETAIL uAllocDetail; \ - uAllocDetail.sSyncAlloc.ui32FWAddr = (FWADDR); \ - RGXHWPerfHostPostAllocEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_##T, \ - (N), (Z), &uAllocDetail); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param D Device Node pointer - * @param PID ID of allocating process - * @param FENCE PVRSRV_FENCE object - * @param FWADDR sync firmware address - * @param N string containing sync name - * @param Z string size including null terminating character - */ -#define RGXSRV_HWPERF_ALLOC_FENCE(D, PID, FENCE, FWADDR, N, Z) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_ALLOC)) \ - { \ - RGX_HWPERF_HOST_ALLOC_DETAIL uAllocDetail; \ - uAllocDetail.sFenceAlloc.uiPID = (PID); \ - uAllocDetail.sFenceAlloc.hFence = (FENCE); \ - uAllocDetail.sFenceAlloc.ui32CheckPt_FWAddr = (FWADDR); \ - RGXHWPerfHostPostAllocEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR, \ - N, Z, &uAllocDetail); \ - } \ - } while (0) - -/* - * @param D Device Node pointer - * @param TL PVRSRV_TIMELINE on which CP is allocated - * @param PID Allocating process ID of this TL/FENCE - * @param FENCE PVRSRV_FENCE as passed to SyncCheckpointResolveFence OR PVRSRV_NO_FENCE - * @param FWADDR sync firmware address - * @param N string containing sync name - * @param Z string size including null terminating character - */ -#define RGXSRV_HWPERF_ALLOC_SYNC_CP(D, TL, PID, FENCE, FWADDR, N, Z) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_ALLOC)) \ - { \ - RGX_HWPERF_HOST_ALLOC_DETAIL uAllocDetail; \ - uAllocDetail.sSyncCheckPointAlloc.ui32CheckPt_FWAddr = (FWADDR); \ - uAllocDetail.sSyncCheckPointAlloc.hTimeline = (TL); \ - uAllocDetail.sSyncCheckPointAlloc.uiPID = (PID); \ - uAllocDetail.sSyncCheckPointAlloc.hFence = (FENCE); \ - RGXHWPerfHostPostAllocEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP, \ - N, Z, &uAllocDetail); \ - } \ - } while (0) - -/* - * @param D Device Node pointer - * @param PID ID of allocating process - * @param SW_FENCE PVRSRV_FENCE object - * @param SW_TL PVRSRV_TIMELINE on which SW_FENCE is allocated - * @param SPI Sync point index on the SW_TL on which this SW_FENCE is allocated - * @param N string containing sync name - * @param Z string size including null terminating character - */ -#define RGXSRV_HWPERF_ALLOC_SW_FENCE(D, PID, SW_FENCE, SW_TL, SPI, N, Z) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_ALLOC)) \ - { \ - RGX_HWPERF_HOST_ALLOC_DETAIL uAllocDetail; \ - uAllocDetail.sSWFenceAlloc.uiPID = (PID); \ - uAllocDetail.sSWFenceAlloc.hSWFence = (SW_FENCE); \ - uAllocDetail.sSWFenceAlloc.hSWTimeline = (SW_TL); \ - uAllocDetail.sSWFenceAlloc.ui64SyncPtIndex = (SPI); \ - RGXHWPerfHostPostAllocEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW, \ - N, Z, &uAllocDetail); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param D Device Node pointer - * @param T Host ALLOC event type - * @param FWADDR sync firmware address - */ -#define RGXSRV_HWPERF_FREE(D, T, FWADDR) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_FREE)) \ - { \ - RGXHWPerfHostPostFreeEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_##T, \ - (0), (0), (FWADDR)); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param D Device Node pointer - * @param T Host ALLOC event type - * @param UID ID of input object - * @param PID ID of allocating process - * @param FWADDR sync firmware address - */ -#define RGXSRV_HWPERF_FREE_FENCE_SYNC(D, T, UID, PID, FWADDR) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_FREE)) \ - { \ - RGXHWPerfHostPostFreeEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_##T, \ - (UID), (PID), (FWADDR)); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param D Device Node pointer - * @param T Host ALLOC event type - * @param NEWUID ID of output object - * @param UID1 ID of first input object - * @param UID2 ID of second input object - * @param N string containing new object's name - * @param Z string size including null terminating character - */ -#define RGXSRV_HWPERF_MODIFY_FENCE_SYNC(D, T, NEWUID, UID1, UID2, N, Z) \ - do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_MODIFY)) \ - { \ - RGXHWPerfHostPostModifyEvent(_RGX_DEVICE_INFO_FROM_NODE(D), \ - RGX_HWPERF_HOST_RESOURCE_TYPE_##T, \ - (NEWUID), (UID1), (UID2), N, Z); \ - } \ - } while (0) - - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param I Device info pointer - */ -#define RGXSRV_HWPERF_CLK_SYNC(I) \ - do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_CLK_SYNC)) \ - { \ - RGXHWPerfHostPostClkSyncEvent((I)); \ - } \ - } while (0) - - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts a device info event to the HWPerfHost stream. - * - * @param I Device info pointer - * @param T Event type - * @param H Health status enum - * @param R Health reason enum - */ -#define RGXSRV_HWPERF_DEVICE_INFO(I, T, H, R) \ - do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_DEV_INFO)) \ - { \ - RGXHWPerfHostPostDeviceInfo((I), (T), (H), (R)); \ - } \ - } while (0) - -/* - * This macro checks if HWPerfHost and the event are enabled and if they are - * it posts event to the HWPerfHost stream. - * - * @param I Device info pointer - * @param T Event type - */ -#define RGXSRV_HWPERF_HOST_INFO(I, T) \ -do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_INFO)) \ - { \ - RGXHWPerfHostPostInfo((I), (T)); \ - } \ -} while (0) - -/* - * @param I Device info pointer - * @param T Wait Event type - * @param PID Process ID that the following fence belongs to - * @param F Fence handle - * @param D Data for this wait event type - */ -#define RGXSRV_HWPERF_SYNC_FENCE_WAIT(I, T, PID, F, D) \ -do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_SYNC_FENCE_WAIT)) \ - { \ - RGXHWPerfHostPostFenceWait(I, RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_##T, \ - (PID), (F), (D)); \ - } \ -} while (0) - -/* - * @param I Device info pointer - * @param PID Process ID that the following timeline belongs to - * @param F SW-timeline handle - * @param SPI Sync-pt index where this SW-timeline has reached - */ -#define RGXSRV_HWPERF_SYNC_SW_TL_ADV(I, PID, SW_TL, SPI)\ -do { \ - if (RGXHWPerfHostIsEventEnabled((I), RGX_HWPERF_HOST_SYNC_SW_TL_ADVANCE)) \ - { \ - RGXHWPerfHostPostSWTimelineAdv((I), (PID), (SW_TL), (SPI)); \ - } \ -} while (0) - -/* - * @param D Device Node pointer - * @param PID Process ID that the following timeline belongs to - * @param N Null terminated string containing the process name - */ -#define RGXSRV_HWPERF_HOST_CLIENT_INFO_PROCESS_NAME(D, PID, N) \ -do { \ - if (RGXHWPerfHostIsEventEnabled(_RGX_DEVICE_INFO_FROM_NODE(D), RGX_HWPERF_HOST_CLIENT_INFO)) \ - { \ - RGXHWPerfHostPostClientInfoProcName(_RGX_DEVICE_INFO_FROM_NODE(D), (PID), (N)); \ - } \ -} while (0) - -#else - -#define RGXSRV_HWPERF_ENQ(C, P, X, E, I, K, CF, UF, UT, CHKUID, UPDUID, D, CE) -#define RGXSRV_HWPERF_UFO(I, T, D, S) -#define RGXSRV_HWPERF_ALLOC(D, T, FWADDR, N, Z) -#define RGXSRV_HWPERF_ALLOC_FENCE(D, PID, FENCE, FWADDR, N, Z) -#define RGXSRV_HWPERF_ALLOC_SYNC_CP(D, TL, PID, FENCE, FWADDR, N, Z) -#define RGXSRV_HWPERF_ALLOC_SW_FENCE(D, PID, SW_FENCE, SW_TL, SPI, N, Z) -#define RGXSRV_HWPERF_FREE(D, T, FWADDR) -#define RGXSRV_HWPERF_FREE_FENCE_SYNC(D, T, UID, PID, FWADDR) -#define RGXSRV_HWPERF_MODIFY_FENCE_SYNC(D, T, NEWUID, UID1, UID2, N, Z) -#define RGXSRV_HWPERF_CLK_SYNC(I) -#define RGXSRV_HWPERF_DEVICE_INFO(I, T, H, R) -#define RGXSRV_HWPERF_HOST_INFO(I, T) -#define RGXSRV_HWPERF_SYNC_FENCE_WAIT(I, T, PID, F, D) -#define RGXSRV_HWPERF_SYNC_SW_TL_ADV(I, PID, SW_TL, SPI) -#define RGXSRV_HWPERF_HOST_CLIENT_INFO_PROCESS_NAME(D, PID, N) - -#endif - -#endif /* RGXHWPERF_COMMON_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxinit.c b/drivers/gpu/drm/img-rogue/1.17/rgxinit.c deleted file mode 100644 index dd572a5c67a01..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxinit.c +++ /dev/null @@ -1,5127 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(__linux__) -#include -#else -#include -#endif - -#include "img_defs.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "pvrsrv_bridge_init.h" -#include "rgx_bridge_init.h" -#include "syscommon.h" -#include "rgx_heaps.h" -#include "rgxheapconfig.h" -#include "rgxpower.h" -#include "tlstream.h" -#include "pvrsrv_tlstreams.h" - -#include "rgxinit.h" -#include "rgxbvnc.h" -#include "rgxmulticore.h" - -#include "pdump_km.h" -#include "handle.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "rgxmem.h" -#include "sync_internal.h" -#include "pvrsrv_apphint.h" -#include "oskm_apphint.h" -#include "rgxfwdbg.h" -#include "info_page.h" - -#include "rgxfwimageutils.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgx_fwif_km.h" - -#include "rgxmmuinit.h" -#include "rgxmipsmmuinit.h" -#include "physmem.h" -#include "devicemem_utils.h" -#include "devicemem_server.h" -#include "physmem_osmem.h" -#include "physmem_lma.h" - -#include "rgxdebug.h" -#include "rgxhwperf.h" -#include "htbserver.h" - -#include "rgx_options.h" -#include "pvrversion.h" - -#include "rgx_compat_bvnc.h" - -#include "rgx_heaps.h" - -#include "rgxta3d.h" -#include "rgxtimecorr.h" -#include "rgxshader.h" - -#include "rgx_bvnc_defs_km.h" -#if defined(PDUMP) -#include "rgxstartstop.h" -#endif - -#include "rgx_fwif_alignchecks.h" -#include "vmm_pvz_client.h" - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "rgxworkest.h" -#endif - -#if defined(SUPPORT_PDVFS) -#include "rgxpdvfs.h" -#endif - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) -#include "rgxsoctimer.h" -#endif - -#if defined(PDUMP) && defined(SUPPORT_SECURITY_VALIDATION) -#include "pdump_physmem.h" -#endif - -static PVRSRV_ERROR RGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); -static PVRSRV_ERROR RGXDevVersionString(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_CHAR **ppszVersionString); -static PVRSRV_ERROR RGXDevClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_PUINT32 pui32RGXClockSpeed); -static PVRSRV_ERROR RGXSoftReset(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64 ui64ResetValue1, IMG_UINT64 ui64ResetValue2); -static PVRSRV_ERROR RGXPhysMemDeviceHeapsInit(PVRSRV_DEVICE_NODE *psDeviceNode); -static void DevPart2DeInitRGX(PVRSRV_DEVICE_NODE *psDeviceNode); - -#if (RGX_NUM_OS_SUPPORTED > 1) -static PVRSRV_ERROR RGXInitFwRawHeap(DEVMEM_HEAP_BLUEPRINT *psDevMemHeap, IMG_UINT32 ui32OSid); -static void RGXDeInitFwRawHeap(DEVMEM_HEAP_BLUEPRINT *psDevMemHeap); -#endif - -/* Services internal heap identification used in this file only */ -#define RGX_FIRMWARE_MAIN_HEAP_IDENT "FwMain" /*!< RGX Main Firmware Heap identifier */ -#define RGX_FIRMWARE_CONFIG_HEAP_IDENT "FwConfig" /*!< RGX Config firmware Heap identifier */ - -#define RGX_MMU_PAGE_SIZE_4KB ( 4 * 1024) -#define RGX_MMU_PAGE_SIZE_16KB ( 16 * 1024) -#define RGX_MMU_PAGE_SIZE_64KB ( 64 * 1024) -#define RGX_MMU_PAGE_SIZE_256KB ( 256 * 1024) -#define RGX_MMU_PAGE_SIZE_1MB (1024 * 1024) -#define RGX_MMU_PAGE_SIZE_2MB (2048 * 1024) -#define RGX_MMU_PAGE_SIZE_MIN RGX_MMU_PAGE_SIZE_4KB -#define RGX_MMU_PAGE_SIZE_MAX RGX_MMU_PAGE_SIZE_2MB - -#define VAR(x) #x - -static void RGXDeInitHeaps(DEVICE_MEMORY_INFO *psDevMemoryInfo); - -#if !defined(NO_HARDWARE) -/*************************************************************************/ /*! -@Function SampleIRQCount -@Description Utility function taking snapshots of RGX FW interrupt count. -@Input psDevInfo Device Info structure - -@Return IMG_BOOL Returns IMG_TRUE if RGX FW IRQ is not equal to - sampled RGX FW IRQ count for any RGX FW thread. - */ /**************************************************************************/ -static INLINE IMG_BOOL SampleIRQCount(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_BOOL bReturnVal = IMG_FALSE; - volatile IMG_UINT32 *aui32SampleIrqCount = psDevInfo->aui32SampleIRQCount; - IMG_UINT32 ui32IrqCnt; - -#if defined(RGX_FW_IRQ_OS_COUNTERS) - if PVRSRV_VZ_MODE_IS(GUEST) - { - bReturnVal = IMG_TRUE; - } - else - { - get_irq_cnt_val(ui32IrqCnt, RGXFW_HOST_OS, psDevInfo); - - if (ui32IrqCnt != aui32SampleIrqCount[RGXFW_THREAD_0]) - { - aui32SampleIrqCount[RGXFW_THREAD_0] = ui32IrqCnt; - bReturnVal = IMG_TRUE; - } - } -#else - IMG_UINT32 ui32TID; - - for_each_irq_cnt(ui32TID) - { - get_irq_cnt_val(ui32IrqCnt, ui32TID, psDevInfo); - - /* treat unhandled interrupts here to align host count with fw count */ - if (aui32SampleIrqCount[ui32TID] != ui32IrqCnt) - { - aui32SampleIrqCount[ui32TID] = ui32IrqCnt; - bReturnVal = IMG_TRUE; - } - } -#endif - - return bReturnVal; -} - -/*************************************************************************/ /*! -@Function RGXHostSafetyEvents -@Description Returns the event status masked to keep only the safety - events handled by the Host -@Input psDevInfo Device Info structure -@Return IMG_UINT32 Status of Host-handled safety events - */ /**************************************************************************/ -static INLINE IMG_UINT32 RGXHostSafetyEvents(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - if (PVRSRV_VZ_MODE_IS(GUEST) || (psDevInfo->ui32HostSafetyEventMask == 0)) - { - return 0; - } - else - { - IMG_UINT32 ui32SafetyEventStatus = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE); - return (ui32SafetyEventStatus & psDevInfo->ui32HostSafetyEventMask); - } -} - -/*************************************************************************/ /*! -@Function RGXSafetyEventCheck -@Description Clears the Event Status register and checks if any of the - safety events need Host handling -@Input psDevInfo Device Info structure -@Return IMG_BOOL Are there any safety events for Host to handle ? - */ /**************************************************************************/ -static INLINE IMG_BOOL RGXSafetyEventCheck(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_BOOL bSafetyEvent = IMG_FALSE; - - if (psDevInfo->ui32HostSafetyEventMask != 0) - { - IMG_UINT32 ui32EventStatus = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_EVENT_STATUS); - - if (BIT_ISSET(ui32EventStatus, RGX_CR_EVENT_STATUS_SAFETY_SHIFT)) - { - /* clear the safety event */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_EVENT_CLEAR, RGX_CR_EVENT_CLEAR_SAFETY_EN); - - /* report if there is anything for the Host to handle */ - bSafetyEvent = (RGXHostSafetyEvents(psDevInfo) != 0); - } - } - - return bSafetyEvent; -} - -/*************************************************************************/ /*! -@Function RGXSafetyEventHandler -@Description Handles the Safety Events that the Host is responsible for -@Input psDevInfo Device Info structure - */ /**************************************************************************/ -static void RGXSafetyEventHandler(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32HostSafetyStatus = RGXHostSafetyEvents(psDevInfo); - RGX_CONTEXT_RESET_REASON eResetReason = RGX_CONTEXT_RESET_REASON_NONE; - - if (ui32HostSafetyStatus != 0) - { - /* clear the safety bus events handled by the Host */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SAFETY_EVENT_CLEAR__ROGUEXE, ui32HostSafetyStatus); - - if (BIT_ISSET(ui32HostSafetyStatus, RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_SHIFT)) - { - IMG_UINT32 ui32FaultFlag; - IMG_UINT32 ui32FaultFW = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FAULT_FW_STATUS); - IMG_UINT32 ui32CorrectedBitOffset = RGX_CR_FAULT_FW_STATUS_CPU_CORRECT_SHIFT - - RGX_CR_FAULT_FW_STATUS_CPU_DETECT_SHIFT; - - PVR_DPF((PVR_DBG_ERROR, "%s: Firmware safety fault status: 0x%X", __func__, ui32FaultFW)); - - for (ui32FaultFlag = 0; ui32FaultFlag < ui32CorrectedBitOffset; ui32FaultFlag++) - { - if (BIT_ISSET(ui32FaultFW, ui32FaultFlag)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Firmware safety hardware fault detected (0x%lX).", - __func__, BIT(ui32FaultFlag))); - eResetReason = RGX_CONTEXT_RESET_REASON_FW_ECC_ERR; - } - else if BIT_ISSET(ui32FaultFW, ui32FaultFlag + ui32CorrectedBitOffset) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware safety hardware fault corrected.(0x%lX).", - __func__, BIT(ui32FaultFlag))); - - /* Only report this if we haven't detected a more serious error */ - if (eResetReason != RGX_CONTEXT_RESET_REASON_FW_ECC_ERR) - { - eResetReason = RGX_CONTEXT_RESET_REASON_FW_ECC_OK; - } - } - } - - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_FAULT_FW_CLEAR, ui32FaultFW); - } - - if (BIT_ISSET(ui32HostSafetyStatus, RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_SHIFT)) - { - volatile RGXFWIF_POW_STATE ePowState = psDevInfo->psRGXFWIfFwSysData->ePowState; - - if (ePowState == RGXFWIF_POW_ON) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Safety Watchdog Trigger !", __func__)); - - /* Only report this if we haven't detected a more serious error */ - if (eResetReason != RGX_CONTEXT_RESET_REASON_FW_ECC_ERR) - { - eResetReason = RGX_CONTEXT_RESET_REASON_FW_WATCHDOG; - } - } - } - - /* Notify client and system layer of any error */ - if (eResetReason != RGX_CONTEXT_RESET_REASON_NONE) - { - PVRSRV_DEVICE_NODE *psDevNode = psDevInfo->psDeviceNode; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig; - - /* Client notification of device error will be achieved by - * clients calling UM function RGXGetLastDeviceError() */ - psDevInfo->eLastDeviceError = eResetReason; - - /* Notify system layer of any error */ - if (psDevConfig->pfnSysDevErrorNotify) - { - PVRSRV_ROBUSTNESS_NOTIFY_DATA sErrorData = {0}; - - sErrorData.eResetReason = eResetReason; - - psDevConfig->pfnSysDevErrorNotify(psDevConfig, - &sErrorData); - } - } - } -} - -static IMG_BOOL _WaitForInterruptsTimeoutCheck(PVRSRV_RGXDEV_INFO *psDevInfo) -{ -#if defined(PVRSRV_DEBUG_LISR_EXECUTION) - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - IMG_UINT32 ui32idx; -#endif - - RGXDEBUG_PRINT_IRQ_COUNT(psDevInfo); - -#if defined(PVRSRV_DEBUG_LISR_EXECUTION) - PVR_DPF((PVR_DBG_ERROR, - "Last RGX_LISRHandler State (DevID %u): 0x%08X Clock: %llu", - psDeviceNode->sDevId.ui32InternalID, - psDeviceNode->sLISRExecutionInfo.ui32Status, - psDeviceNode->sLISRExecutionInfo.ui64Clockns)); - - for_each_irq_cnt(ui32idx) - { - PVR_DPF((PVR_DBG_ERROR, - MSG_IRQ_CNT_TYPE " %u: InterruptCountSnapshot: 0x%X", - ui32idx, psDeviceNode->sLISRExecutionInfo.aui32InterruptCountSnapshot[ui32idx])); - } -#else - PVR_DPF((PVR_DBG_ERROR, "No further information available. Please enable PVRSRV_DEBUG_LISR_EXECUTION")); -#endif - - return SampleIRQCount(psDevInfo); -} - -void RGX_WaitForInterruptsTimeout(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_BOOL bScheduleMISR; - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - bScheduleMISR = IMG_TRUE; - } - else - { - bScheduleMISR = _WaitForInterruptsTimeoutCheck(psDevInfo); - } - - if (bScheduleMISR) - { - OSScheduleMISR(psDevInfo->pvMISRData); - - if (psDevInfo->pvAPMISRData != NULL) - { - OSScheduleMISR(psDevInfo->pvAPMISRData); - } - } -} - -static inline IMG_BOOL RGXAckHwIrq(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32IRQStatusReg, - IMG_UINT32 ui32IRQStatusEventMsk, - IMG_UINT32 ui32IRQClearReg, - IMG_UINT32 ui32IRQClearMask) -{ - IMG_UINT32 ui32IRQStatus = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32IRQStatusReg); - - if (ui32IRQStatus & ui32IRQStatusEventMsk) - { - /* acknowledge and clear the interrupt */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32IRQClearReg, ui32IRQClearMask); - return IMG_TRUE; - } - else - { - /* spurious interrupt */ - return IMG_FALSE; - } -} - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static IMG_BOOL RGXAckIrqMETA(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - return RGXAckHwIrq(psDevInfo, - RGX_CR_META_SP_MSLVIRQSTATUS, - RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN, - RGX_CR_META_SP_MSLVIRQSTATUS, - RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK); -} -#endif - -static IMG_BOOL RGXAckIrqMIPS(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - return RGXAckHwIrq(psDevInfo, - RGX_CR_MIPS_WRAPPER_IRQ_STATUS, - RGX_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN, - RGX_CR_MIPS_WRAPPER_IRQ_CLEAR, - RGX_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN); -} - -static IMG_BOOL RGXAckIrqDedicated(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - /* status & clearing registers are available on both Host and Guests - * and are agnostic of the Fw CPU type. Due to the remappings done by - * the 2nd stage device MMU, all drivers assume they are accessing - * register bank 0 */ - return RGXAckHwIrq(psDevInfo, - RGX_CR_IRQ_OS0_EVENT_STATUS, - RGX_CR_IRQ_OS0_EVENT_STATUS_SOURCE_EN, - RGX_CR_IRQ_OS0_EVENT_CLEAR, - RGX_CR_IRQ_OS0_EVENT_CLEAR_SOURCE_EN); -} - -static IMG_BOOL RGX_LISRHandler(void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = pvData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_BOOL bIrqAcknowledged = IMG_FALSE; - -#if defined(PVRSRV_DEBUG_LISR_EXECUTION) - IMG_UINT32 ui32idx, ui32IrqCnt; - - for_each_irq_cnt(ui32idx) - { - get_irq_cnt_val(ui32IrqCnt, ui32idx, psDevInfo); - UPDATE_LISR_DBG_SNAPSHOT(ui32idx, ui32IrqCnt); - } - UPDATE_LISR_DBG_STATUS(RGX_LISR_INIT); - UPDATE_LISR_DBG_TIMESTAMP(); -#endif - - UPDATE_LISR_DBG_COUNTER(); - - if (psDevInfo->bRGXPowered) - { - IMG_BOOL bSafetyEvent = RGXSafetyEventCheck(psDevInfo); - - if ((psDevInfo->pfnRGXAckIrq == NULL) || psDevInfo->pfnRGXAckIrq(psDevInfo) || bSafetyEvent) - { - bIrqAcknowledged = IMG_TRUE; - - if (SampleIRQCount(psDevInfo) || bSafetyEvent) - { - UPDATE_LISR_DBG_STATUS(RGX_LISR_PROCESSED); - UPDATE_MISR_DBG_COUNTER(); - - OSScheduleMISR(psDevInfo->pvMISRData); - -#if defined(SUPPORT_AUTOVZ) - RGXUpdateAutoVzWdgToken(psDevInfo); -#endif - if (psDevInfo->pvAPMISRData != NULL) - { - OSScheduleMISR(psDevInfo->pvAPMISRData); - } - } - else - { - UPDATE_LISR_DBG_STATUS(RGX_LISR_FW_IRQ_COUNTER_NOT_UPDATED); - } - } - else - { - UPDATE_LISR_DBG_STATUS(RGX_LISR_NOT_TRIGGERED_BY_HW); - } - } - else - { - /* AutoVz drivers rebooting while the firmware is active must acknowledge - * and clear the hw IRQ line before the RGXInit() has finished. */ - if (!(psDevInfo->psDeviceNode->bAutoVzFwIsUp && - (psDevInfo->pfnRGXAckIrq != NULL) && - psDevInfo->pfnRGXAckIrq(psDevInfo))) - { - UPDATE_LISR_DBG_STATUS(RGX_LISR_DEVICE_NOT_POWERED); - } - } - - return bIrqAcknowledged; -} - -static void RGX_MISR_ProcessKCCBDeferredList(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - OS_SPINLOCK_FLAGS uiFlags; - - /* First check whether there are pending commands in Deferred KCCB List */ - OSSpinLockAcquire(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - if (dllist_is_empty(&psDevInfo->sKCCBDeferredCommandsListHead)) - { - OSSpinLockRelease(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - return; - } - OSSpinLockRelease(psDevInfo->hLockKCCBDeferredCommandsList, uiFlags); - - /* Powerlock to avoid further Power transition requests - while KCCB deferred list is being processed */ - eError = PVRSRVPowerLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire PowerLock (device: %p, error: %s)", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - return; - } - - /* Try to send deferred KCCB commands Do not Poll from here*/ - eError = RGXSendCommandsFromDeferredList(psDevInfo, IMG_FALSE); - - PVRSRVPowerUnlock(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s could not flush Deferred KCCB list, KCCB is full.", - __func__)); - } -} - -static void RGX_MISRHandler_CheckFWActivePowerState(void *psDevice) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psDevice; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psFwSysData->ePowState == RGXFWIF_POW_ON || psFwSysData->ePowState == RGXFWIF_POW_IDLE) - { - RGX_MISR_ProcessKCCBDeferredList(psDeviceNode); - } - - if (psFwSysData->ePowState == RGXFWIF_POW_IDLE) - { - /* The FW is IDLE and therefore could be shut down */ - eError = RGXActivePowerRequest(psDeviceNode); - - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)) - { - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Failed RGXActivePowerRequest call (device: %p) with %s", - __func__, psDeviceNode, PVRSRVGetErrorString(eError))); - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - } - else - { - /* Re-schedule the power down request as it was deferred. */ - OSScheduleMISR(psDevInfo->pvAPMISRData); - } - } - } - -} - -/* Shorter defines to keep the code a bit shorter */ -#define GPU_IDLE RGXFWIF_GPU_UTIL_STATE_IDLE -#define GPU_ACTIVE RGXFWIF_GPU_UTIL_STATE_ACTIVE -#define GPU_BLOCKED RGXFWIF_GPU_UTIL_STATE_BLOCKED -#define MAX_ITERATIONS 64 - -static PVRSRV_ERROR RGXGetGpuUtilStats(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hGpuUtilUser, - RGXFWIF_GPU_UTIL_STATS *psReturnStats) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - volatile RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb; - RGXFWIF_GPU_UTIL_STATS *psAggregateStats; - IMG_UINT64 ui64TimeNow; - IMG_UINT32 ui32Attempts; - IMG_UINT32 ui32Remainder; - - - /***** (1) Initialise return stats *****/ - - psReturnStats->bValid = IMG_FALSE; - psReturnStats->ui64GpuStatIdle = 0; - psReturnStats->ui64GpuStatActive = 0; - psReturnStats->ui64GpuStatBlocked = 0; - psReturnStats->ui64GpuStatCumulative = 0; - - if (hGpuUtilUser == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - psAggregateStats = hGpuUtilUser; - - - /* Try to acquire GPU utilisation counters and repeat if the FW is in the middle of an update */ - for (ui32Attempts = 0; ui32Attempts < 4; ui32Attempts++) - { - IMG_UINT64 aui64TmpCounters[RGXFWIF_GPU_UTIL_STATE_NUM] = {0}; - IMG_UINT64 ui64LastPeriod = 0, ui64LastWord = 0, ui64LastState = 0, ui64LastTime = 0; - IMG_UINT32 i = 0; - - - /***** (2) Get latest data from shared area *****/ - - OSLockAcquire(psDevInfo->hGPUUtilLock); - - /* - * First attempt at detecting if the FW is in the middle of an update. - * This should also help if the FW is in the middle of a 64 bit variable update. - */ - while (((ui64LastWord != psUtilFWCb->ui64LastWord) || - (aui64TmpCounters[ui64LastState] != - psUtilFWCb->aui64StatsCounters[ui64LastState])) && - (i < MAX_ITERATIONS)) - { - ui64LastWord = psUtilFWCb->ui64LastWord; - ui64LastState = RGXFWIF_GPU_UTIL_GET_STATE(ui64LastWord); - aui64TmpCounters[GPU_IDLE] = psUtilFWCb->aui64StatsCounters[GPU_IDLE]; - aui64TmpCounters[GPU_ACTIVE] = psUtilFWCb->aui64StatsCounters[GPU_ACTIVE]; - aui64TmpCounters[GPU_BLOCKED] = psUtilFWCb->aui64StatsCounters[GPU_BLOCKED]; - i++; - } - - OSLockRelease(psDevInfo->hGPUUtilLock); - - if (i == MAX_ITERATIONS) - { - PVR_DPF((PVR_DBG_WARNING, - "RGXGetGpuUtilStats could not get reliable data after trying %u times", i)); - return PVRSRV_ERROR_TIMEOUT; - } - - - /***** (3) Compute return stats *****/ - - /* Update temp counters to account for the time since the last update to the shared ones */ - OSMemoryBarrier(NULL); /* Ensure the current time is read after the loop above */ - ui64TimeNow = RGXFWIF_GPU_UTIL_GET_TIME(RGXTimeCorrGetClockns64(psDeviceNode)); - ui64LastTime = RGXFWIF_GPU_UTIL_GET_TIME(ui64LastWord); - ui64LastPeriod = RGXFWIF_GPU_UTIL_GET_PERIOD(ui64TimeNow, ui64LastTime); - aui64TmpCounters[ui64LastState] += ui64LastPeriod; - - /* Get statistics for a user since its last request */ - psReturnStats->ui64GpuStatIdle = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_IDLE], - psAggregateStats->ui64GpuStatIdle); - psReturnStats->ui64GpuStatActive = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_ACTIVE], - psAggregateStats->ui64GpuStatActive); - psReturnStats->ui64GpuStatBlocked = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_BLOCKED], - psAggregateStats->ui64GpuStatBlocked); - psReturnStats->ui64GpuStatCumulative = psReturnStats->ui64GpuStatIdle + - psReturnStats->ui64GpuStatActive + - psReturnStats->ui64GpuStatBlocked; - - if (psAggregateStats->ui64TimeStamp != 0) - { - IMG_UINT64 ui64TimeSinceLastCall = ui64TimeNow - psAggregateStats->ui64TimeStamp; - /* We expect to return at least 75% of the time since the last call in GPU stats */ - IMG_UINT64 ui64MinReturnedStats = ui64TimeSinceLastCall - (ui64TimeSinceLastCall / 4); - - /* - * If the returned stats are substantially lower than the time since - * the last call, then the Host might have read a partial update from the FW. - * If this happens, try sampling the shared counters again. - */ - if (psReturnStats->ui64GpuStatCumulative < ui64MinReturnedStats) - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Return stats (%" IMG_UINT64_FMTSPEC ") too low " - "(call period %" IMG_UINT64_FMTSPEC ")", - __func__, psReturnStats->ui64GpuStatCumulative, ui64TimeSinceLastCall)); - PVR_DPF((PVR_DBG_MESSAGE, "%s: Attempt #%u has failed, trying again", - __func__, ui32Attempts)); - continue; - } - } - - break; - } - - - /***** (4) Update aggregate stats for the current user *****/ - - psAggregateStats->ui64GpuStatIdle += psReturnStats->ui64GpuStatIdle; - psAggregateStats->ui64GpuStatActive += psReturnStats->ui64GpuStatActive; - psAggregateStats->ui64GpuStatBlocked += psReturnStats->ui64GpuStatBlocked; - psAggregateStats->ui64TimeStamp = ui64TimeNow; - - - /***** (5) Convert return stats to microseconds *****/ - - psReturnStats->ui64GpuStatIdle = OSDivide64(psReturnStats->ui64GpuStatIdle, 1000, &ui32Remainder); - psReturnStats->ui64GpuStatActive = OSDivide64(psReturnStats->ui64GpuStatActive, 1000, &ui32Remainder); - psReturnStats->ui64GpuStatBlocked = OSDivide64(psReturnStats->ui64GpuStatBlocked, 1000, &ui32Remainder); - psReturnStats->ui64GpuStatCumulative = OSDivide64(psReturnStats->ui64GpuStatCumulative, 1000, &ui32Remainder); - - /* Check that the return stats make sense */ - if (psReturnStats->ui64GpuStatCumulative == 0) - { - /* We can enter here only if all the RGXFWIF_GPU_UTIL_GET_PERIOD - * returned 0. This could happen if the GPU frequency value - * is not well calibrated and the FW is updating the GPU state - * while the Host is reading it. - * When such an event happens frequently, timers or the aggregate - * stats might not be accurate... - */ - PVR_DPF((PVR_DBG_WARNING, "RGXGetGpuUtilStats could not get reliable data.")); - return PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - - psReturnStats->bValid = IMG_TRUE; - - return PVRSRV_OK; -} - -PVRSRV_ERROR SORgxGpuUtilStatsRegister(IMG_HANDLE *phGpuUtilUser) -{ - RGXFWIF_GPU_UTIL_STATS *psAggregateStats; - - /* NoStats used since this may be called outside of the register/de-register - * process calls which track memory use. */ - psAggregateStats = OSAllocMemNoStats(sizeof(RGXFWIF_GPU_UTIL_STATS)); - if (psAggregateStats == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psAggregateStats->ui64GpuStatIdle = 0; - psAggregateStats->ui64GpuStatActive = 0; - psAggregateStats->ui64GpuStatBlocked = 0; - psAggregateStats->ui64TimeStamp = 0; - - /* Not used */ - psAggregateStats->bValid = IMG_FALSE; - psAggregateStats->ui64GpuStatCumulative = 0; - - *phGpuUtilUser = psAggregateStats; - - return PVRSRV_OK; -} - -PVRSRV_ERROR SORgxGpuUtilStatsUnregister(IMG_HANDLE hGpuUtilUser) -{ - RGXFWIF_GPU_UTIL_STATS *psAggregateStats; - - if (hGpuUtilUser == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psAggregateStats = hGpuUtilUser; - OSFreeMemNoStats(psAggregateStats); - - return PVRSRV_OK; -} - -/* - RGX MISR Handler -*/ -static void RGX_MISRHandler_Main (void *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = pvData; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* Give the HWPerf service a chance to transfer some data from the FW - * buffer to the host driver transport layer buffer. - */ - RGXHWPerfDataStoreCB(psDeviceNode); - - /* Inform other services devices that we have finished an operation */ - PVRSRVNotifyCommandCompletion(psDeviceNode); - -#if defined(SUPPORT_PDVFS) && defined(RGXFW_META_SUPPORT_2ND_THREAD) - /* Normally, firmware CCB only exists for the primary FW thread unless PDVFS - is running on the second[ary] FW thread, here we process said CCB */ - RGXPDVFSCheckCoreClkRateChange(psDeviceNode->pvDevice); -#endif - - /* Handle Safety events if necessary */ - RGXSafetyEventHandler(psDeviceNode->pvDevice); - - /* Signal the global event object */ - PVRSRVSignalGlobalEO(); - - /* Process the Firmware CCB for pending commands */ - RGXCheckFirmwareCCB(psDeviceNode->pvDevice); - - /* Calibrate the GPU frequency and recorrelate Host and GPU timers (done every few seconds) */ - RGXTimeCorrRestartPeriodic(psDeviceNode); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Process Workload Estimation Specific commands from the FW */ - WorkEstCheckFirmwareCCB(psDeviceNode->pvDevice); -#endif - - if (psDevInfo->pvAPMISRData == NULL) - { - RGX_MISR_ProcessKCCBDeferredList(psDeviceNode); - } -} -#endif /* !defined(NO_HARDWARE) */ - - -#if defined(PDUMP) -static PVRSRV_ERROR RGXPDumpBootldrData(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - PMR *psFWDataPMR; - RGXMIPSFW_BOOT_DATA *psBootData; - IMG_DEV_PHYADDR sTmpAddr; - IMG_UINT32 ui32BootConfOffset, ui32ParamOffset, i; - PVRSRV_ERROR eError; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - psFWDataPMR = (PMR *)(psDevInfo->psRGXFWDataMemDesc->psImport->hPMR); - ui32BootConfOffset = RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA); - ui32BootConfOffset += RGXMIPSFW_BOOTLDR_CONF_OFFSET; - - /* The physical addresses used by a pdump player will be different - * than the ones we have put in the MIPS bootloader configuration data. - * We have to tell the pdump player to replace the original values with the real ones. - */ - PDUMPCOMMENT(psDeviceNode, "Pass new boot parameters to the FW"); - - /* Rogue Registers physical address */ - ui32ParamOffset = ui32BootConfOffset + offsetof(RGXMIPSFW_BOOT_DATA, ui64RegBase); - - eError = PDumpRegLabelToMem64(RGX_PDUMPREG_NAME, - 0x0, - psFWDataPMR, - ui32ParamOffset, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPDumpBootldrData: Dump of Rogue registers phy address failed (%u)", eError)); - return eError; - } - - /* Page Table physical Address */ - eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sTmpAddr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXBootldrDataInit: MMU_AcquireBaseAddr failed (%u)", - eError)); - return eError; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc, - (void **)&psBootData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire pointer to FW data (%s)", - __func__, PVRSRVGetErrorString(eError))); - return eError; - } - - psBootData = IMG_OFFSET_ADDR(psBootData, ui32BootConfOffset); - - for (i = 0; i < psBootData->ui32PTNumPages; i++) - { - ui32ParamOffset = ui32BootConfOffset + - offsetof(RGXMIPSFW_BOOT_DATA, aui64PTPhyAddr[0]) - + i * sizeof(psBootData->aui64PTPhyAddr[0]); - - eError = PDumpPTBaseObjectToMem64(psDeviceNode->psFirmwareMMUDevAttrs->pszMMUPxPDumpMemSpaceName, - psFWDataPMR, - 0, - ui32ParamOffset, - PDUMP_FLAGS_CONTINUOUS, - MMU_LEVEL_1, - sTmpAddr.uiAddr, - i << psBootData->ui32PTLog2PageSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPDumpBootldrData: Dump of page tables phy address failed (%u)", eError)); - return eError; - } - } - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc); - - /* Stack physical address */ - ui32ParamOffset = ui32BootConfOffset + offsetof(RGXMIPSFW_BOOT_DATA, ui64StackPhyAddr); - - eError = PDumpMemLabelToMem64(psFWDataPMR, - psFWDataPMR, - RGXGetFWImageSectionOffset(NULL, MIPS_STACK), - ui32ParamOffset, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPDumpBootldrData: Dump of stack phy address failed (%u)", eError)); - return eError; - } - - return eError; -} -#endif /* PDUMP */ - -static PVRSRV_ERROR RGXSetPowerParams(PVRSRV_RGXDEV_INFO *psDevInfo, - PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - /* Save information used on power transitions for later - * (when RGXStart and RGXStop are executed) - */ - psDevInfo->sLayerParams.psDevInfo = psDevInfo; - psDevInfo->sLayerParams.psDevConfig = psDevConfig; -#if defined(PDUMP) - psDevInfo->sLayerParams.ui32PdumpFlags = PDUMP_FLAGS_CONTINUOUS; -#endif -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) || defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META) || - RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - IMG_DEV_PHYADDR sKernelMMUCtxPCAddr; - - if (psDevInfo->psDeviceNode->bAutoVzFwIsUp) - { - /* If AutoVz firmware is up at this stage, the driver initialised it - * during a previous life-cycle. The firmware's memory is already pre-mapped - * and the MMU page tables reside in the predetermined memory carveout. - * The Kernel MMU Context created in this life-cycle is a dummy structure - * that is not used for mapping. - * To program the Device's BIF with the correct PC address, use the base - * address of the carveout reserved for MMU mappings as Kernel MMU PC Address */ -#if defined(PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR) - sKernelMMUCtxPCAddr.uiAddr = PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR; -#else - PHYS_HEAP_CONFIG *psFwHeapCfg = FindPhysHeapConfig(psDevConfig, - PHYS_HEAP_USAGE_FW_MAIN); - eError = (psFwHeapCfg != NULL) ? PVRSRV_OK : PVRSRV_ERROR_PHYSHEAP_CONFIG; - PVR_LOG_RETURN_IF_ERROR(eError, "FindPhysHeapConfig(PHYS_HEAP_USAGE_FW_MAIN)"); - - sKernelMMUCtxPCAddr.uiAddr = psFwHeapCfg->sCardBase.uiAddr + - (RGX_FIRMWARE_RAW_HEAP_SIZE * RGX_NUM_OS_SUPPORTED); -#endif /* PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR */ - } - else - { - eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, - &sKernelMMUCtxPCAddr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: Failed to acquire Kernel MMU Ctx page catalog")); - return eError; - } - } - - psDevInfo->sLayerParams.sPCAddr = sKernelMMUCtxPCAddr; - } - else -#endif - { - PMR *psFWCodePMR = (PMR *)(psDevInfo->psRGXFWCodeMemDesc->psImport->hPMR); - PMR *psFWDataPMR = (PMR *)(psDevInfo->psRGXFWDataMemDesc->psImport->hPMR); - IMG_DEV_PHYADDR sPhyAddr; - IMG_BOOL bValid; - -#if defined(SUPPORT_ALT_REGBASE) - psDevInfo->sLayerParams.sGPURegAddr = psDevConfig->sAltRegsGpuPBase; -#else - /* The physical address of the GPU registers needs to be translated - * in case we are in a LMA scenario - */ - PhysHeapCpuPAddrToDevPAddr(psDevInfo->psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_GPU_LOCAL], - 1, - &sPhyAddr, - &(psDevConfig->sRegsCpuPBase)); - - psDevInfo->sLayerParams.sGPURegAddr = sPhyAddr; -#endif - - /* Register bank must be aligned to 512KB (as per the core integration) to - * prevent the FW accessing incorrect registers */ - if ((psDevInfo->sLayerParams.sGPURegAddr.uiAddr & 0x7FFFFU) != 0U) - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: Register bank must be aligned to 512KB, but current address (0x%016"IMG_UINT64_FMTSPECX") is not", - psDevInfo->sLayerParams.sGPURegAddr.uiAddr)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - eError = RGXGetPhyAddr(psFWCodePMR, - &sPhyAddr, - RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_CODE), - OSGetPageShift(), /* FW will be using the same page size as the OS */ - 1, - &bValid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: Failed to acquire FW boot/NMI code address")); - return eError; - } - - psDevInfo->sLayerParams.sBootRemapAddr = sPhyAddr; - - eError = RGXGetPhyAddr(psFWDataPMR, - &sPhyAddr, - RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA), - OSGetPageShift(), - 1, - &bValid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: Failed to acquire FW boot/NMI data address")); - return eError; - } - - psDevInfo->sLayerParams.sDataRemapAddr = sPhyAddr; - - eError = RGXGetPhyAddr(psFWCodePMR, - &sPhyAddr, - RGXGetFWImageSectionOffset(NULL, MIPS_EXCEPTIONS_CODE), - OSGetPageShift(), - 1, - &bValid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: Failed to acquire FW exceptions address")); - return eError; - } - - psDevInfo->sLayerParams.sCodeRemapAddr = sPhyAddr; - - psDevInfo->sLayerParams.sTrampolineRemapAddr.uiAddr = psDevInfo->psTrampoline->sPhysAddr.uiAddr; - - psDevInfo->sLayerParams.bDevicePA0IsValid = psDevConfig->bDevicePA0IsValid; - } - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - /* Send information used on power transitions to the trusted device as - * in this setup the driver cannot start/stop the GPU and perform resets - */ - if (psDevConfig->pfnTDSetPowerParams) - { - PVRSRV_TD_POWER_PARAMS sTDPowerParams; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - sTDPowerParams.sPCAddr = psDevInfo->sLayerParams.sPCAddr; - } -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - sTDPowerParams.sPCAddr = psDevInfo->sLayerParams.sPCAddr; - } -#endif - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - sTDPowerParams.sGPURegAddr = psDevInfo->sLayerParams.sGPURegAddr; - sTDPowerParams.sBootRemapAddr = psDevInfo->sLayerParams.sBootRemapAddr; - sTDPowerParams.sCodeRemapAddr = psDevInfo->sLayerParams.sCodeRemapAddr; - sTDPowerParams.sDataRemapAddr = psDevInfo->sLayerParams.sDataRemapAddr; - } - - eError = psDevConfig->pfnTDSetPowerParams(psDevConfig->hSysData, - &sTDPowerParams); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "RGXSetPowerParams: TDSetPowerParams not implemented!")); - eError = PVRSRV_ERROR_NOT_IMPLEMENTED; - } -#endif - - return eError; -} - -/* - RGXSystemHasFBCDCVersion31 -*/ -static IMG_BOOL RGXSystemHasFBCDCVersion31(PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_VALIDATION) - IMG_UINT32 ui32FBCDCVersionOverride = 0; -#endif - -#if defined(FIX_HW_ERN_66622_BIT_MASK) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 66622)) - { -#if defined(SUPPORT_VALIDATION) - void *pvAppHintState = NULL; - - IMG_UINT32 ui32AppHintDefault; - - OSCreateKMAppHintState(&pvAppHintState); - ui32AppHintDefault = PVRSRV_APPHINT_FBCDCVERSIONOVERRIDE; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, FBCDCVersionOverride, - &ui32AppHintDefault, &ui32FBCDCVersionOverride); - OSFreeKMAppHintState(pvAppHintState); - - if (ui32FBCDCVersionOverride > 0) - { - if (ui32FBCDCVersionOverride == 2) - { - return IMG_TRUE; - } - } - else -#endif - { - if (psDeviceNode->psDevConfig->bHasFBCDCVersion31) - { - return IMG_TRUE; - } - } - } - else -#endif - { - -#if defined(SUPPORT_VALIDATION) - if (ui32FBCDCVersionOverride == 2) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: FBCDCVersionOverride forces FBC3.1 but this core doesn't support it!", - __func__)); - } -#endif - -#if !defined(NO_HARDWARE) - if (psDeviceNode->psDevConfig->bHasFBCDCVersion31) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: System uses FBCDC3.1 but GPU doesn't support it!", - __func__)); - } -#endif - } - - return IMG_FALSE; -} - -/* - RGXDevMMUAttributes -*/ -static MMU_DEVICEATTRIBS *RGXDevMMUAttributes(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bKernelMemoryCtx) -{ - MMU_DEVICEATTRIBS *psMMUDevAttrs; - - if ((psDeviceNode->pfnCheckDeviceFeature) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, MIPS)) - { - psMMUDevAttrs = bKernelMemoryCtx ? - psDeviceNode->psFirmwareMMUDevAttrs : - psDeviceNode->psMMUDevAttrs; - } - else - { - psMMUDevAttrs = psDeviceNode->psMMUDevAttrs; - } - - return psMMUDevAttrs; -} - -/* - * RGXInitDevPart2 - */ -PVRSRV_ERROR RGXInitDevPart2(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32DeviceFlags, - IMG_UINT32 ui32HWPerfHostFilter, - RGX_ACTIVEPM_CONF eActivePMConf) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_DEV_POWER_STATE eDefaultPowerState = PVRSRV_DEV_POWER_STATE_ON; - PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig; - - /* Assume system layer has turned power on by this point, required before powering device */ - psDeviceNode->eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_ON; - - PDUMPCOMMENT(psDeviceNode, "RGX Initialisation Part 2"); - -#if defined(PDUMP) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - RGXPDumpBootldrData(psDeviceNode, psDevInfo); - } -#endif -#if defined(TIMING) || defined(DEBUG) - OSUserModeAccessToPerfCountersEn(); -#endif - - /* Initialise Device Flags */ - psDevInfo->ui32DeviceFlags = 0; - RGXSetDeviceFlags(psDevInfo, ui32DeviceFlags, IMG_TRUE); - - /* Allocate DVFS Table (needs to be allocated before GPU trace events - * component is initialised because there is a dependency between them) */ - psDevInfo->psGpuDVFSTable = OSAllocZMem(sizeof(*(psDevInfo->psGpuDVFSTable))); - PVR_LOG_GOTO_IF_NOMEM(psDevInfo->psGpuDVFSTable, eError, ErrorExit); - - if (psDevInfo->ui32HWPerfHostFilter == 0) - { - RGXHWPerfHostSetEventFilter(psDevInfo, ui32HWPerfHostFilter); - } - - /* If HWPerf enabled allocate all resources for the host side buffer. */ - if (psDevInfo->ui32HWPerfHostFilter != 0) - { - if (RGXHWPerfHostInitOnDemandResources(psDevInfo) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "HWPerfHost buffer on demand" - " initialisation failed.")); - } - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Initialise work estimation lock */ - eError = OSLockCreate(&psDevInfo->hWorkEstLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(WorkEstLock)", ErrorExit); -#endif - - /* Initialise lists of ZSBuffers */ - eError = OSLockCreate(&psDevInfo->hLockZSBuffer); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(LockZSBuffer)", ErrorExit); - dllist_init(&psDevInfo->sZSBufferHead); - psDevInfo->ui32ZSBufferCurrID = 1; - - /* Initialise lists of growable Freelists */ - eError = OSLockCreate(&psDevInfo->hLockFreeList); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(LockFreeList)", ErrorExit); - dllist_init(&psDevInfo->sFreeListHead); - psDevInfo->ui32FreelistCurrID = 1; - - eError = OSLockCreate(&psDevInfo->hDebugFaultInfoLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(DebugFaultInfoLock)", ErrorExit); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - eError = OSLockCreate(&psDevInfo->hMMUCtxUnregLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(MMUCtxUnregLock)", ErrorExit); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - eError = OSLockCreate(&psDevInfo->hNMILock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(NMILock)", ErrorExit); - } - - /* Setup GPU utilisation stats update callback */ - eError = OSLockCreate(&psDevInfo->hGPUUtilLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate(GPUUtilLock)", ErrorExit); -#if !defined(NO_HARDWARE) - psDevInfo->pfnGetGpuUtilStats = RGXGetGpuUtilStats; -#endif - - eDefaultPowerState = PVRSRV_DEV_POWER_STATE_ON; - psDevInfo->eActivePMConf = eActivePMConf; - - /* set-up the Active Power Mgmt callback */ -#if !defined(NO_HARDWARE) - { - RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - IMG_BOOL bSysEnableAPM = psRGXData->psRGXTimingInfo->bEnableActivePM; - IMG_BOOL bEnableAPM = ((eActivePMConf == RGX_ACTIVEPM_DEFAULT) && bSysEnableAPM) || - (eActivePMConf == RGX_ACTIVEPM_FORCE_ON); - - if (bEnableAPM && (!PVRSRV_VZ_MODE_IS(NATIVE))) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Active Power Management disabled in virtualization mode", __func__)); - bEnableAPM = IMG_FALSE; - } - -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) && defined(SUPPORT_AUTOVZ) - /* The AutoVz driver enable a virtualisation watchdog not compatible with APM */ - PVR_ASSERT(bEnableAPM == IMG_FALSE); -#endif - - if (bEnableAPM) - { - eError = OSInstallMISR(&psDevInfo->pvAPMISRData, - RGX_MISRHandler_CheckFWActivePowerState, - psDeviceNode, - "RGX_CheckFWActivePower"); - PVR_LOG_GOTO_IF_ERROR(eError, "OSInstallMISR(APMISR)", ErrorExit); - - /* Prevent the device being woken up before there is something to do. */ - eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF; - } - } -#endif - - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_EnableAPM, - RGXQueryAPMState, - RGXSetAPMState, - psDeviceNode, - NULL); - - RGXTimeCorrInitAppHintCallbacks(psDeviceNode); - - /* Register the device with the power manager */ - eError = PVRSRVRegisterPowerDevice(psDeviceNode, - (PVRSRV_VZ_MODE_IS(NATIVE)) ? &RGXPrePowerState : &RGXVzPrePowerState, - (PVRSRV_VZ_MODE_IS(NATIVE)) ? &RGXPostPowerState : &RGXVzPostPowerState, - psDevConfig->pfnPrePowerState, psDevConfig->pfnPostPowerState, - &RGXPreClockSpeedChange, &RGXPostClockSpeedChange, - &RGXForcedIdleRequest, &RGXCancelForcedIdleRequest, - &RGXDustCountChange, - (IMG_HANDLE)psDeviceNode, - PVRSRV_DEV_POWER_STATE_OFF, - eDefaultPowerState); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVRegisterPowerDevice", ErrorExit); - - eError = RGXSetPowerParams(psDevInfo, psDevConfig); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetPowerParams", ErrorExit); - -#if defined(SUPPORT_VALIDATION) - { - void *pvAppHintState = NULL; - - IMG_UINT32 ui32AppHintDefault; - - OSCreateKMAppHintState(&pvAppHintState); - ui32AppHintDefault = PVRSRV_APPHINT_TESTSLRINTERVAL; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, TestSLRInterval, - &ui32AppHintDefault, &psDevInfo->ui32TestSLRInterval); - PVR_LOG(("OSGetKMAppHintUINT32(TestSLRInterval) ui32AppHintDefault=%d, psDevInfo->ui32TestSLRInterval=%d", - ui32AppHintDefault, psDevInfo->ui32TestSLRInterval)); - OSFreeKMAppHintState(pvAppHintState); - psDevInfo->ui32TestSLRCount = psDevInfo->ui32TestSLRInterval; - psDevInfo->ui32SLRSkipFWAddr = 0; - - ui32AppHintDefault = 0; - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, ECCRAMErrInj, &ui32AppHintDefault, &psDevInfo->ui32ECCRAMErrInjModule); - psDevInfo->ui32ECCRAMErrInjInterval = RGXKM_ECC_ERR_INJ_INTERVAL; - -#if defined(PDUMP) && defined(SUPPORT_VALIDATION) - /* POL on ECC RAM GPU fault events, MARS is FW fault */ - if (psDevInfo->ui32ECCRAMErrInjModule != RGXKM_ECC_ERR_INJ_DISABLE && - psDevInfo->ui32ECCRAMErrInjModule != RGXKM_ECC_ERR_INJ_MARS) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_DEINIT, "Verify ECC fault event"); - eError = PDUMPREGPOL(psDeviceNode, RGX_PDUMPREG_NAME, - RGX_CR_SCRATCH11, - 1U, - 0xFFFFFFFF, - PDUMP_FLAGS_DEINIT, - PDUMP_POLL_OPERATOR_EQUAL); - } -#endif - } -#endif - -#if defined(PDUMP) -#if defined(NO_HARDWARE) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_DEINIT, "Wait for the FW to signal idle"); - - /* Kick the FW once, in case it still needs to detect and set the idle state */ - PDUMPREG32(psDeviceNode, RGX_PDUMPREG_NAME, - RGX_CR_MTS_SCHEDULE, - RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK, - PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_DEINIT); - - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfFwSysDataMemDesc, - offsetof(RGXFWIF_SYSDATA, ePowState), - RGXFWIF_POW_IDLE, - 0xFFFFFFFFU, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_DEINIT); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemPDumpDevmemPol32", ErrorExit); -#endif - - /* Run RGXStop with the correct PDump flags to feed the last-frame deinit buffer */ - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_DEINIT, - "RGX deinitialisation commands"); - - psDevInfo->sLayerParams.ui32PdumpFlags |= PDUMP_FLAGS_DEINIT | PDUMP_FLAGS_NOHW; - - if (! PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = RGXStop(&psDevInfo->sLayerParams); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXStop", ErrorExit); - } - - psDevInfo->sLayerParams.ui32PdumpFlags &= ~(PDUMP_FLAGS_DEINIT | PDUMP_FLAGS_NOHW); -#endif - -#if !defined(NO_HARDWARE) - eError = RGXInstallProcessQueuesMISR(&psDevInfo->hProcessQueuesMISR, psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXInstallProcessQueuesMISR", ErrorExit); - - /* Register RGX to receive notifies when other devices complete some work */ - PVRSRVRegisterCmdCompleteNotify(&psDeviceNode->hCmdCompNotify, &RGXScheduleProcessQueuesKM, psDeviceNode); - - /* Register the interrupt handlers */ - eError = OSInstallMISR(&psDevInfo->pvMISRData, - RGX_MISRHandler_Main, - psDeviceNode, - "RGX_Main"); - PVR_LOG_GOTO_IF_ERROR(eError, "OSInstallMISR(MISR)", ErrorExit); - - /* Register appropriate mechanism for clearing hw interrupts */ - if ((RGX_IS_FEATURE_SUPPORTED(psDevInfo, IRQ_PER_OS)) && (!PVRSRV_VZ_MODE_IS(NATIVE))) - { - psDevInfo->pfnRGXAckIrq = RGXAckIrqDedicated; - } - else if (PVRSRV_VZ_MODE_IS(GUEST)) - { - psDevInfo->pfnRGXAckIrq = NULL; - } - else - { - /* native and host drivers must clear the unique GPU physical interrupt */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - psDevInfo->pfnRGXAckIrq = RGXAckIrqMIPS; - } -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - else if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - psDevInfo->pfnRGXAckIrq = RGXAckIrqMETA; - } -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - else if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - psDevInfo->pfnRGXAckIrq = RGXAckIrqDedicated; - } -#endif - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: GPU IRQ clearing mechanism not implemented " - "for the this architecture.", __func__)); - PVR_LOG_GOTO_WITH_ERROR("pfnRGXAckIrq", eError, PVRSRV_ERROR_NOT_IMPLEMENTED, ErrorExit); - } - } - -#if defined(RGX_IRQ_HYPERV_HANDLER) - /* The hypervisor receives and acknowledges the GPU irq, then it injects an - * irq only in the recipient OS. The KM driver doesn't handle the GPU irq line */ - psDevInfo->pfnRGXAckIrq = NULL; -#endif - - eError = SysInstallDeviceLISR(psDevConfig->hSysData, - psDevConfig->ui32IRQ, - PVRSRV_MODNAME, - RGX_LISRHandler, - psDeviceNode, - &psDevInfo->pvLISRData); - PVR_LOG_GOTO_IF_ERROR(eError, "SysInstallDeviceLISR", ErrorExit); -#endif /* !defined(NO_HARDWARE) */ - -#if defined(PDUMP) -/* We need to wrap the check for S7_CACHE_HIERARCHY being supported inside - * #if defined(RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK)...#endif, as the - * RGX_IS_FEATURE_SUPPORTED macro references a bitmask define derived from its - * last parameter which will not exist on architectures which do not have this - * feature. - * Note we check for RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK rather than for - * RGX_FEATURE_S7_CACHE_HIERARCHY (which might seem a better choice) as this - * means we can build the kernel driver without having to worry about the BVNC - * (the BIT_MASK is defined in rgx_bvnc_defs_km.h for all BVNCs for a given - * architecture, whereas the FEATURE is only defined for those BVNCs that - * support it). - */ -#if defined(RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK) - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_CACHE_HIERARCHY))) -#endif - { - if (!PVRSRVSystemSnoopingOfCPUCache(psDevConfig) && - !PVRSRVSystemSnoopingOfDeviceCache(psDevConfig)) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "System has NO cache snooping"); - } - else - { - if (PVRSRVSystemSnoopingOfCPUCache(psDevConfig)) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "System has CPU cache snooping"); - } - if (PVRSRVSystemSnoopingOfDeviceCache(psDevConfig)) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "System has DEVICE cache snooping"); - } - } - } -#endif - -#if defined(RGX_FEATURE_COMPUTE_ONLY_BIT_MASK) - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE_ONLY)) -#endif - { - eError = PVRSRVTQLoadShaders(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVTQLoadShaders", ErrorExit); - } - - psDevInfo->bDevInit2Done = IMG_TRUE; - - return PVRSRV_OK; - -ErrorExit: - DevPart2DeInitRGX(psDeviceNode); - - return eError; -} - -#define VZ_RGX_FW_FILENAME_SUFFIX ".vz" -#define RGX_64K_FW_FILENAME_SUFFIX ".64k" -#define RGX_FW_FILENAME_MAX_SIZE ((sizeof(RGX_FW_FILENAME)+ \ - RGX_BVNC_STR_SIZE_MAX+sizeof(VZ_RGX_FW_FILENAME_SUFFIX) + sizeof(RGX_64K_FW_FILENAME_SUFFIX))) - -static void _GetFWFileName(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszFWFilenameStr, - IMG_CHAR *pszFWpFilenameStr) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const IMG_CHAR * const pszFWFilenameSuffix = - PVRSRV_VZ_MODE_IS(NATIVE) ? "" : VZ_RGX_FW_FILENAME_SUFFIX; - - const IMG_CHAR * const pszFWFilenameSuffix2 = - ((OSGetPageSize() == RGX_MMU_PAGE_SIZE_64KB) && - RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - ? RGX_64K_FW_FILENAME_SUFFIX : ""; - - OSSNPrintf(pszFWFilenameStr, RGX_FW_FILENAME_MAX_SIZE, - "%s." RGX_BVNC_STR_FMTSPEC "%s%s", - RGX_FW_FILENAME, - psDevInfo->sDevFeatureCfg.ui32B, psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, psDevInfo->sDevFeatureCfg.ui32C, - pszFWFilenameSuffix, pszFWFilenameSuffix2); - - OSSNPrintf(pszFWpFilenameStr, RGX_FW_FILENAME_MAX_SIZE, - "%s." RGX_BVNC_STRP_FMTSPEC "%s%s", - RGX_FW_FILENAME, - psDevInfo->sDevFeatureCfg.ui32B, psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, psDevInfo->sDevFeatureCfg.ui32C, - pszFWFilenameSuffix, pszFWFilenameSuffix2); -} - -PVRSRV_ERROR RGXLoadAndGetFWData(PVRSRV_DEVICE_NODE *psDeviceNode, - OS_FW_IMAGE **ppsRGXFW, - const IMG_BYTE **ppbFWData) -{ - IMG_CHAR aszFWFilenameStr[RGX_FW_FILENAME_MAX_SIZE]; - IMG_CHAR aszFWpFilenameStr[RGX_FW_FILENAME_MAX_SIZE]; - IMG_CHAR *pszLoadedFwStr; - PVRSRV_ERROR eErr; - - /* Prepare the image filenames to use in the following code */ - _GetFWFileName(psDeviceNode, aszFWFilenameStr, aszFWpFilenameStr); - - /* Get pointer to Firmware image */ - pszLoadedFwStr = aszFWFilenameStr; - eErr = OSLoadFirmware(psDeviceNode, pszLoadedFwStr, OS_FW_VERIFY_FUNCTION, ppsRGXFW); - if (eErr == PVRSRV_ERROR_NOT_FOUND) - { - pszLoadedFwStr = aszFWpFilenameStr; - eErr = OSLoadFirmware(psDeviceNode, pszLoadedFwStr, OS_FW_VERIFY_FUNCTION, ppsRGXFW); - if (eErr == PVRSRV_ERROR_NOT_FOUND) - { - pszLoadedFwStr = RGX_FW_FILENAME; - eErr = OSLoadFirmware(psDeviceNode, pszLoadedFwStr, OS_FW_VERIFY_FUNCTION, ppsRGXFW); - if (eErr == PVRSRV_ERROR_NOT_FOUND) - { - PVR_DPF((PVR_DBG_FATAL, "All RGX Firmware image loads failed for '%s' (%s)", - aszFWFilenameStr, PVRSRVGetErrorString(eErr))); - } - } - } - - if (eErr == PVRSRV_OK) - { - PVR_LOG(("RGX Firmware image '%s' loaded", pszLoadedFwStr)); - *ppbFWData = (const IMG_BYTE*)OSFirmwareData(*ppsRGXFW); - } - else - { - *ppbFWData = NULL; - } - - return eErr; - -} - -#if defined(PDUMP) -PVRSRV_ERROR RGXInitHWPerfCounters(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - return PVRSRV_OK; -} -#endif - -PVRSRV_ERROR RGXInitCreateFWKernelMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* set up fw memory contexts */ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - -#if defined(SUPPORT_AUTOVZ) - PHYS_HEAP *psDefaultPhysHeap = psDeviceNode->psMMUPhysHeap; - - if (PVRSRV_VZ_MODE_IS(HOST) && (!psDeviceNode->bAutoVzFwIsUp)) - { - /* Temporarily swap the MMU and default GPU physheap to allow the page - * tables of all memory mapped by the FwKernel context to be placed - * in a dedicated memory carveout. This should allow the firmware mappings to - * persist after a Host kernel crash or driver reset. */ - - psDeviceNode->psMMUPhysHeap = psDeviceNode->psFwMMUReservedPhysHeap; - } -#endif - - /* Register callbacks for creation of device memory contexts */ - psDeviceNode->pfnRegisterMemoryContext = RGXRegisterMemoryContext; - psDeviceNode->pfnUnregisterMemoryContext = RGXUnregisterMemoryContext; - - /* Create the memory context for the firmware. */ - eError = DevmemCreateContext(psDeviceNode, DEVMEM_HEAPCFG_META, - &psDevInfo->psKernelDevmemCtx); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed DevmemCreateContext (%u)", - __func__, - eError)); - goto failed_to_create_ctx; - } - - eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx, RGX_FIRMWARE_MAIN_HEAP_IDENT, - &psDevInfo->psFirmwareMainHeap); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed DevmemFindHeapByName (%u)", - __func__, - eError)); - goto failed_to_find_heap; - } - - eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx, RGX_FIRMWARE_CONFIG_HEAP_IDENT, - &psDevInfo->psFirmwareConfigHeap); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed DevmemFindHeapByName (%u)", - __func__, - eError)); - goto failed_to_find_heap; - } - -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - IMG_UINT32 ui32OSID; - for (ui32OSID = RGX_FIRST_RAW_HEAP_OSID; ui32OSID < RGX_NUM_OS_SUPPORTED; ui32OSID++) - { - IMG_CHAR szHeapName[RA_MAX_NAME_LENGTH]; - - OSSNPrintf(szHeapName, sizeof(szHeapName), RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT, ui32OSID); - eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx, szHeapName, - &psDevInfo->psGuestFirmwareRawHeap[ui32OSID]); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemFindHeapByName", failed_to_find_heap); - } - } -#endif - -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - IMG_DEV_PHYADDR sPhysHeapBase; - IMG_UINT32 ui32OSID; - - eError = PhysHeapGetDevPAddr(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN], &sPhysHeapBase); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapGetDevPAddr", failed_to_find_heap); - - for (ui32OSID = RGX_FIRST_RAW_HEAP_OSID; ui32OSID < RGX_NUM_OS_SUPPORTED; ui32OSID++) - { - IMG_DEV_PHYADDR sRawFwHeapBase = {sPhysHeapBase.uiAddr + (ui32OSID * RGX_FIRMWARE_RAW_HEAP_SIZE)}; - - eError = RGXFwRawHeapAllocMap(psDeviceNode, - ui32OSID, - sRawFwHeapBase, - RGX_FIRMWARE_RAW_HEAP_SIZE); - if (eError != PVRSRV_OK) - { - for (; ui32OSID > RGX_FIRST_RAW_HEAP_OSID; ui32OSID--) - { - RGXFwRawHeapUnmapFree(psDeviceNode, ui32OSID); - } - PVR_LOG_GOTO_IF_ERROR(eError, "RGXFwRawHeapAllocMap", failed_to_find_heap); - } - } - -#if defined(SUPPORT_AUTOVZ) - /* restore default Px setup */ - psDeviceNode->psMMUPhysHeap = psDefaultPhysHeap; -#endif - } -#else - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = PvzClientMapDevPhysHeap(psDeviceNode->psDevConfig); - PVR_LOG_GOTO_IF_ERROR(eError, "PvzClientMapDevPhysHeap", failed_to_find_heap); - } -#endif /* defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) */ - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareMainHeap, IMG_TRUE); - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareConfigHeap, IMG_TRUE); - } - - return eError; - -failed_to_find_heap: - /* - * Clear the mem context create callbacks before destroying the RGX firmware - * context to avoid a spurious callback. - */ - psDeviceNode->pfnRegisterMemoryContext = NULL; - psDeviceNode->pfnUnregisterMemoryContext = NULL; - DevmemDestroyContext(psDevInfo->psKernelDevmemCtx); - psDevInfo->psKernelDevmemCtx = NULL; -failed_to_create_ctx: - return eError; -} - -void RGXDeInitDestroyFWKernelMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - if (PVRSRV_VZ_MODE_IS(HOST)) - { -#if defined(SUPPORT_AUTOVZ) - PHYS_HEAP *psDefaultPhysHeap = psDeviceNode->psMMUPhysHeap; - - psDeviceNode->psMMUPhysHeap = psDeviceNode->psFwMMUReservedPhysHeap; - - if (!psDeviceNode->bAutoVzFwIsUp) -#endif - { - IMG_UINT32 ui32OSID; - - for (ui32OSID = RGX_FIRST_RAW_HEAP_OSID; ui32OSID < RGX_NUM_OS_SUPPORTED; ui32OSID++) - { - RGXFwRawHeapUnmapFree(psDeviceNode, ui32OSID); - } - } -#if defined(SUPPORT_AUTOVZ) - psDeviceNode->psMMUPhysHeap = psDefaultPhysHeap; -#endif - } -#else - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - (void) PvzClientUnmapDevPhysHeap(psDeviceNode->psDevConfig); - - if (psDevInfo->psFirmwareMainHeap) - { - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareMainHeap, IMG_FALSE); - } - if (psDevInfo->psFirmwareConfigHeap) - { - DevmemHeapSetPremapStatus(psDevInfo->psFirmwareConfigHeap, IMG_FALSE); - } - } -#endif - - /* - * Clear the mem context create callbacks before destroying the RGX firmware - * context to avoid a spurious callback. - */ - psDeviceNode->pfnRegisterMemoryContext = NULL; - psDeviceNode->pfnUnregisterMemoryContext = NULL; - - if (psDevInfo->psKernelDevmemCtx) - { - eError = DevmemDestroyContext(psDevInfo->psKernelDevmemCtx); - PVR_ASSERT(eError == PVRSRV_OK); - } -} - -static PVRSRV_ERROR RGXAlignmentCheck(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32AlignChecksSizeUM, - IMG_UINT32 aui32AlignChecksUM[]) -{ - static const IMG_UINT32 aui32AlignChecksKM[] = {RGXFW_ALIGN_CHECKS_INIT_KM}; - IMG_UINT32 ui32UMChecksOffset = ARRAY_SIZE(aui32AlignChecksKM) + 1; - PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice; - IMG_UINT32 i, *paui32FWAlignChecks; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Skip the alignment check if the driver is guest - since there is no firmware to check against */ - PVRSRV_VZ_RET_IF_MODE(GUEST, eError); - - if (psDevInfo->psRGXFWAlignChecksMemDesc == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: FW Alignment Check Mem Descriptor is NULL", - __func__)); - return PVRSRV_ERROR_ALIGNMENT_ARRAY_NOT_AVAILABLE; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc, - (void **) &paui32FWAlignChecks); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire kernel address for alignment checks (%u)", - __func__, - eError)); - return eError; - } - - paui32FWAlignChecks += ui32UMChecksOffset; - if (*paui32FWAlignChecks++ != ui32AlignChecksSizeUM) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Mismatching sizes of RGXFW_ALIGN_CHECKS_INIT" - " array between UM(%d) and FW(%d)", - __func__, - ui32AlignChecksSizeUM, - *paui32FWAlignChecks)); - eError = PVRSRV_ERROR_INVALID_ALIGNMENT; - goto return_; - } - - for (i = 0; i < ui32AlignChecksSizeUM; i++) - { - if (aui32AlignChecksUM[i] != paui32FWAlignChecks[i]) - { - PVR_DPF((PVR_DBG_ERROR, "%s: size/offset mismatch in RGXFW_ALIGN_CHECKS_INIT[%d]" - " between UM(%d) and FW(%d)", - __func__, i, aui32AlignChecksUM[i], paui32FWAlignChecks[i])); - eError = PVRSRV_ERROR_INVALID_ALIGNMENT; - } - } - - if (eError == PVRSRV_ERROR_INVALID_ALIGNMENT) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Check for FW/KM structure" - " alignment failed.", __func__)); - } - -return_: - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc); - - return eError; -} - -static -PVRSRV_ERROR RGXAllocateFWMemoryRegion(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEVMEM_SIZE_T ui32Size, - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags, - const IMG_PCHAR pszText, - DEVMEM_MEMDESC **ppsMemDescPtr) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_DEVMEM_LOG2ALIGN_T uiLog2Align = OSGetPageShift(); -#if defined(SUPPORT_MIPS_CONTIGUOUS_FW_MEMORY) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -#endif - -#if defined(SUPPORT_MIPS_CONTIGUOUS_FW_MEMORY) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - uiLog2Align = RGXMIPSFW_LOG2_PAGE_SIZE_64K; - } -#endif - - uiMemAllocFlags = (uiMemAllocFlags | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) & - RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp); - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(SUPPORT_SECURITY_VALIDATION) - uiMemAllocFlags &= PVRSRV_MEMALLOCFLAGS_TDFWMASK; -#endif - - PDUMPCOMMENT(psDeviceNode, "Allocate FW %s memory", pszText); - - eError = DevmemFwAllocateExportable(psDeviceNode, - ui32Size, - 1ULL << uiLog2Align, - uiMemAllocFlags, - pszText, - ppsMemDescPtr); - - return eError; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver - - @Description - - Validate the FW build options against KM driver build options (KM build options only) - - Following check is redundant, because next check checks the same bits. - Redundancy occurs because if client-server are build-compatible and client-firmware are - build-compatible then server-firmware are build-compatible as well. - - This check is left for clarity in error messages if any incompatibility occurs. - - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver(RGXFWIF_OSINIT *psFwOsInit) -{ -#if !defined(NO_HARDWARE) - IMG_UINT32 ui32BuildOptions, ui32BuildOptionsFWKMPart, ui32BuildOptionsMismatch; - - if (psFwOsInit == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - ui32BuildOptions = (RGX_BUILD_OPTIONS_KM & RGX_BUILD_OPTIONS_MASK_FW); - - ui32BuildOptionsFWKMPart = psFwOsInit->sRGXCompChecks.ui32BuildOptions & RGX_BUILD_OPTIONS_MASK_FW; - - /* Check if the FW is missing support for any features required by the driver */ - if (~ui32BuildOptionsFWKMPart & ui32BuildOptions) - { - ui32BuildOptionsMismatch = ui32BuildOptions ^ ui32BuildOptionsFWKMPart; -#if !defined(PVRSRV_STRICT_COMPAT_CHECK) - /*Mask the debug flag option out as we do support combinations of debug vs release in um & km*/ - ui32BuildOptionsMismatch &= OPTIONS_STRICT; -#endif - if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and KM driver build options; " - "extra options present in the KM driver: (0x%x). Please check rgx_options.h", - ui32BuildOptions & ui32BuildOptionsMismatch )); - return PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH; - } - - if ( (ui32BuildOptionsFWKMPart & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware-side and KM driver build options; " - "extra options present in Firmware: (0x%x). Please check rgx_options.h", - ui32BuildOptionsFWKMPart & ui32BuildOptionsMismatch )); - return PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH; - } - PVR_DPF((PVR_DBG_WARNING, "RGXDevInitCompatCheck: Firmware and KM driver build options differ.")); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware and KM driver build options match. [ OK ]")); - } -#endif - - return PVRSRV_OK; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver - - @Description - - Validate FW DDK version against driver DDK version - - @Input psDevInfo - device info - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_OSINIT *psFwOsInit) -{ -#if defined(PDUMP)||(!defined(NO_HARDWARE)) - IMG_UINT32 ui32DDKVersion; - PVRSRV_ERROR eError; - - ui32DDKVersion = PVRVERSION_PACK(PVRVERSION_MAJ, PVRVERSION_MIN); -#endif - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Compatibility check: KM driver and FW DDK version"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, ui32DDKVersion), - ui32DDKVersion, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } -#endif - -#if !defined(NO_HARDWARE) - if (psFwOsInit == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - if (psFwOsInit->sRGXCompChecks.ui32DDKVersion != ui32DDKVersion) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible driver DDK version (%u.%u) / Firmware DDK version (%u.%u).", - PVRVERSION_MAJ, PVRVERSION_MIN, - PVRVERSION_UNPACK_MAJ(psFwOsInit->sRGXCompChecks.ui32DDKVersion), - PVRVERSION_UNPACK_MIN(psFwOsInit->sRGXCompChecks.ui32DDKVersion))); - eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; - PVR_DBG_BREAK; - return eError; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: driver DDK version (%u.%u) and Firmware DDK version (%u.%u) match. [ OK ]", - PVRVERSION_MAJ, PVRVERSION_MIN, - PVRVERSION_MAJ, PVRVERSION_MIN)); - } -#endif - - return PVRSRV_OK; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver - - @Description - - Validate FW DDK build against driver DDK build - - @Input psDevInfo - device info - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_OSINIT *psFwOsInit) -{ - PVRSRV_ERROR eError=PVRSRV_OK; -#if defined(PDUMP)||(!defined(NO_HARDWARE)) - IMG_UINT32 ui32DDKBuild; - - ui32DDKBuild = PVRVERSION_BUILD; -#endif - -#if defined(PDUMP) && defined(PVRSRV_STRICT_COMPAT_CHECK) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Compatibility check: KM driver and FW DDK build"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, ui32DDKBuild), - ui32DDKBuild, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } -#endif - -#if !defined(NO_HARDWARE) - if (psFwOsInit == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - if (psFwOsInit->sRGXCompChecks.ui32DDKBuild != ui32DDKBuild) - { - PVR_LOG(("(WARN) RGXDevInitCompatCheck: Different driver DDK build version (%d) / Firmware DDK build version (%d).", - ui32DDKBuild, psFwOsInit->sRGXCompChecks.ui32DDKBuild)); -#if defined(PVRSRV_STRICT_COMPAT_CHECK) - eError = PVRSRV_ERROR_DDK_BUILD_MISMATCH; - PVR_DBG_BREAK; - return eError; -#endif - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: driver DDK build version (%d) and Firmware DDK build version (%d) match. [ OK ]", - ui32DDKBuild, psFwOsInit->sRGXCompChecks.ui32DDKBuild)); - } -#endif - return eError; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_BVNC_FWAgainstDriver - - @Description - - Validate FW BVNC against driver BVNC - - @Input psDevInfo - device info - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_BVNC_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_OSINIT *psFwOsInit) -{ -#if !defined(NO_HARDWARE) - IMG_BOOL bCompatibleAll, bCompatibleVersion, bCompatibleBVNC; -#endif -#if defined(PDUMP)||(!defined(NO_HARDWARE)) - RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sBVNC); - PVRSRV_ERROR eError; - - sBVNC.ui64BVNC = rgx_bvnc_pack(psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); -#endif - -#if defined(PDUMP) - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Compatibility check: KM driver and FW BVNC (struct version)"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32LayoutVersion), - sBVNC.ui32LayoutVersion, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Compatibility check: KM driver and FW BVNC (BVNC part - Lower 32 bits)"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui64BVNC), - (IMG_UINT32)sBVNC.ui64BVNC, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - } - - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Compatibility check: KM driver and FW BVNC (BVNC part - Higher 32 bits)"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui64BVNC) + - sizeof(IMG_UINT32), - (IMG_UINT32)(sBVNC.ui64BVNC >> 32), - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - } -#endif - -#if !defined(NO_HARDWARE) - if (psFwOsInit == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - RGX_BVNC_EQUAL(sBVNC, psFwOsInit->sRGXCompChecks.sFWBVNC, bCompatibleAll, bCompatibleVersion, bCompatibleBVNC); - - if (!bCompatibleAll) - { - if (!bCompatibleVersion) - { - PVR_LOG(("(FAIL) %s: Incompatible compatibility struct version of driver (%u) and firmware (%u).", - __func__, - sBVNC.ui32LayoutVersion, - psFwOsInit->sRGXCompChecks.sFWBVNC.ui32LayoutVersion)); - eError = PVRSRV_ERROR_BVNC_MISMATCH; - return eError; - } - - if (!bCompatibleBVNC) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in KM driver BVNC (%u.%u.%u.%u) and Firmware BVNC (%u.%u.%u.%u)", - RGX_BVNC_PACKED_EXTR_B(sBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(sBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(sBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(sBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_B(psFwOsInit->sRGXCompChecks.sFWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(psFwOsInit->sRGXCompChecks.sFWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(psFwOsInit->sRGXCompChecks.sFWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(psFwOsInit->sRGXCompChecks.sFWBVNC.ui64BVNC))); - eError = PVRSRV_ERROR_BVNC_MISMATCH; - return eError; - } - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware BVNC and KM driver BNVC match. [ OK ]")); - } -#endif - return PVRSRV_OK; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_BVNC_HWAgainstDriver - - @Description - - Validate HW BVNC against driver BVNC - - @Input psDevInfo - device info - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_BVNC_HWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_OSINIT *psFwOsInit) -{ -#if defined(PDUMP) || !defined(NO_HARDWARE) - IMG_UINT64 ui64MaskBVNC = RGX_BVNC_PACK_MASK_B | - RGX_BVNC_PACK_MASK_V | - RGX_BVNC_PACK_MASK_N | - RGX_BVNC_PACK_MASK_C; - - PVRSRV_ERROR eError; - RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sSWBVNC); -#endif - -#if defined(PDUMP) - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; -#endif - -#if !defined(NO_HARDWARE) - RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sHWBVNC); - IMG_BOOL bCompatibleAll, bCompatibleVersion, bCompatibleBVNC; -#endif - - if (psDevInfo->bIgnoreHWReportedBVNC) - { - PVR_LOG(("BVNC compatibility checks between driver and HW are disabled (AppHint override)")); - return PVRSRV_OK; - } - -#if defined(PDUMP) || !defined(NO_HARDWARE) -#if defined(COMPAT_BVNC_MASK_V) - ui64MaskBVNC &= ~RGX_BVNC_PACK_MASK_V; -#endif -#if defined(COMPAT_BVNC_MASK_N) - ui64MaskBVNC &= ~RGX_BVNC_PACK_MASK_N; -#endif -#if defined(COMPAT_BVNC_MASK_C) - ui64MaskBVNC &= ~RGX_BVNC_PACK_MASK_C; -#endif - - sSWBVNC.ui64BVNC = rgx_bvnc_pack(psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); - -#if defined(FIX_HW_BRN_38344_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 38344) && (psDevInfo->sDevFeatureCfg.ui32C >= 10)) - { - ui64MaskBVNC &= ~RGX_BVNC_PACK_MASK_C; - } -#endif - if (ui64MaskBVNC != (RGX_BVNC_PACK_MASK_B | RGX_BVNC_PACK_MASK_V | RGX_BVNC_PACK_MASK_N | RGX_BVNC_PACK_MASK_C)) - { - PVR_LOG(("Compatibility checks: Ignoring fields: '%s%s%s%s' of HW BVNC.", - ((!(ui64MaskBVNC & RGX_BVNC_PACK_MASK_B))?("B"):("")), - ((!(ui64MaskBVNC & RGX_BVNC_PACK_MASK_V))?("V"):("")), - ((!(ui64MaskBVNC & RGX_BVNC_PACK_MASK_N))?("N"):("")), - ((!(ui64MaskBVNC & RGX_BVNC_PACK_MASK_C))?("C"):("")))); - } -#endif - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Compatibility check: Layout version of compchecks struct"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32LayoutVersion), - sSWBVNC.ui32LayoutVersion, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } - - PDUMPCOM(psDevInfo->psDeviceNode, ui32PDumpFlags, "BVNC compatibility check started"); - if (ui64MaskBVNC & (RGX_BVNC_PACK_MASK_B | RGX_BVNC_PACK_MASK_N | RGX_BVNC_PACK_MASK_C)) - { - PDUMPIF(psDevInfo->psDeviceNode, "DISABLE_HWBNC_CHECK", ui32PDumpFlags); - PDUMPELSE(psDevInfo->psDeviceNode, "DISABLE_HWBNC_CHECK", ui32PDumpFlags); - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Compatibility check: HW BNC and FW BNC (Lower 32 bits)"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui64BVNC), - (IMG_UINT32)sSWBVNC.ui64BVNC , - (IMG_UINT32)(ui64MaskBVNC & ~RGX_BVNC_PACK_MASK_V), - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Compatibility check: HW BNC and FW BNC (Higher 32 bits)"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui64BVNC) + - sizeof(IMG_UINT32), - (IMG_UINT32)(sSWBVNC.ui64BVNC >> 32), - (IMG_UINT32)((ui64MaskBVNC & ~RGX_BVNC_PACK_MASK_V) >> 32), - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } - - PDUMPFI(psDevInfo->psDeviceNode, "DISABLE_HWBNC_CHECK", ui32PDumpFlags); - } - if (ui64MaskBVNC & RGX_BVNC_PACK_MASK_V) - { - PDUMPIF(psDevInfo->psDeviceNode, "DISABLE_HWV_CHECK", ui32PDumpFlags); - PDUMPELSE(psDevInfo->psDeviceNode, "DISABLE_HWV_CHECK", ui32PDumpFlags); - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Compatibility check: HW V and FW V"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) + - offsetof(RGXFWIF_COMPCHECKS_BVNC, ui64BVNC) + - ((RGX_BVNC_PACK_SHIFT_V >= 32) ? sizeof(IMG_UINT32) : 0), - (IMG_UINT32)(sSWBVNC.ui64BVNC >> ((RGX_BVNC_PACK_SHIFT_V >= 32) ? 32 : 0)), - RGX_BVNC_PACK_MASK_V >> ((RGX_BVNC_PACK_SHIFT_V >= 32) ? 32 : 0), - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } - PDUMPFI(psDevInfo->psDeviceNode, "DISABLE_HWV_CHECK", ui32PDumpFlags); - } - PDUMPCOM(psDevInfo->psDeviceNode, ui32PDumpFlags, "BVNC compatibility check finished"); -#endif - -#if !defined(NO_HARDWARE) - if (psFwOsInit == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - sHWBVNC = psFwOsInit->sRGXCompChecks.sHWBVNC; - - sHWBVNC.ui64BVNC &= ui64MaskBVNC; - sSWBVNC.ui64BVNC &= ui64MaskBVNC; - - RGX_BVNC_EQUAL(sSWBVNC, sHWBVNC, bCompatibleAll, bCompatibleVersion, bCompatibleBVNC); - - if (!bCompatibleAll) - { - if (!bCompatibleVersion) - { - PVR_LOG(("(FAIL) %s: Incompatible compatibility struct version of HW (%d) and FW (%d).", - __func__, - sHWBVNC.ui32LayoutVersion, - sSWBVNC.ui32LayoutVersion)); - eError = PVRSRV_ERROR_BVNC_MISMATCH; - return eError; - } - - if (!bCompatibleBVNC) - { - PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible HW BVNC (%d.%d.%d.%d) and FW BVNC (%d.%d.%d.%d).", - RGX_BVNC_PACKED_EXTR_B(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_B(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(sSWBVNC.ui64BVNC))); - eError = PVRSRV_ERROR_BVNC_MISMATCH; - return eError; - } - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: HW BVNC (%d.%d.%d.%d) and FW BVNC (%d.%d.%d.%d) match. [ OK ]", - RGX_BVNC_PACKED_EXTR_B(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(sHWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_B(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_V(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_N(sSWBVNC.ui64BVNC), - RGX_BVNC_PACKED_EXTR_C(sSWBVNC.ui64BVNC))); - } -#endif - - return PVRSRV_OK; -} - -/*! - ******************************************************************************* - - @Function RGXDevInitCompatCheck_METACoreVersion_AgainstDriver - - @Description - - Validate HW META version against driver META version - - @Input psDevInfo - device info - @Input psFwOsInit - FW init data - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck_FWProcessorVersion_AgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_OSINIT *psFwOsInit) -{ -#if defined(PDUMP)||(!defined(NO_HARDWARE)) - PVRSRV_ERROR eError; -#endif -#if defined(PDUMP) - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; -#endif - IMG_UINT32 ui32FWCoreIDValue = 0; - IMG_CHAR *pcRGXFW_PROCESSOR = NULL; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - ui32FWCoreIDValue = RGXMIPSFW_CORE_ID_VALUE; - pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_MIPS; - } - else -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - switch (RGX_GET_FEATURE_VALUE(psDevInfo, META)) - { - case MTP218: ui32FWCoreIDValue = RGX_CR_META_MTP218_CORE_ID_VALUE; break; - case MTP219: ui32FWCoreIDValue = RGX_CR_META_MTP219_CORE_ID_VALUE; break; - case LTP218: ui32FWCoreIDValue = RGX_CR_META_LTP218_CORE_ID_VALUE; break; - case LTP217: ui32FWCoreIDValue = RGX_CR_META_LTP217_CORE_ID_VALUE; break; - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Undefined FW_CORE_ID_VALUE", __func__)); - PVR_ASSERT(0); - } - pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_META; - } - else -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - ui32FWCoreIDValue = RGXRISCVFW_CORE_ID_VALUE; - pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_RISCV; - } - else -#endif - { - PVR_DPF((PVR_DBG_ERROR, "%s: Undefined FW_CORE_ID_VALUE", __func__)); - PVR_ASSERT(0); - } - -#if defined(PDUMP) - PDUMPIF(psDevInfo->psDeviceNode, "DISABLE_HWMETA_CHECK", ui32PDumpFlags); - PDUMPELSE(psDevInfo->psDeviceNode, "DISABLE_HWMETA_CHECK", ui32PDumpFlags); - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Compatibility check: KM driver and HW FW Processor version"); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfOsInitMemDesc, - offsetof(RGXFWIF_OSINIT, sRGXCompChecks) + - offsetof(RGXFWIF_COMPCHECKS, ui32FWProcessorVersion), - ui32FWCoreIDValue, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfOsInitMemDesc (%d)", eError)); - return eError; - } - PDUMPFI(psDevInfo->psDeviceNode, "DISABLE_HWMETA_CHECK", ui32PDumpFlags); -#endif - -#if !defined(NO_HARDWARE) - if (psFwOsInit == NULL) - return PVRSRV_ERROR_INVALID_PARAMS; - - if (psFwOsInit->sRGXCompChecks.ui32FWProcessorVersion != ui32FWCoreIDValue) - { - PVR_LOG(("RGXDevInitCompatCheck: Incompatible driver %s version (%d) / HW %s version (%d).", - pcRGXFW_PROCESSOR, - ui32FWCoreIDValue, - pcRGXFW_PROCESSOR, - psFwOsInit->sRGXCompChecks.ui32FWProcessorVersion)); - eError = PVRSRV_ERROR_FWPROCESSOR_MISMATCH; - PVR_DBG_BREAK; - return eError; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Compatible driver %s version (%d) / HW %s version (%d) [OK].", - pcRGXFW_PROCESSOR, - ui32FWCoreIDValue, - pcRGXFW_PROCESSOR, - psFwOsInit->sRGXCompChecks.ui32FWProcessorVersion)); - } -#endif - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RGXDevInitCompatCheck - - @Description - - Check compatibility of host driver and firmware (DDK and build options) - for RGX devices at services/device initialisation - - @Input psDeviceNode - device node - - @Return PVRSRV_ERROR - depending on mismatch found - - ******************************************************************************/ -static PVRSRV_ERROR RGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -#if !defined(NO_HARDWARE) - IMG_UINT32 ui32RegValue; - IMG_UINT8 ui8FwOsCount; - IMG_UINT32 ui32FwTimeout = MAX_HW_TIME_US; - - LOOP_UNTIL_TIMEOUT(ui32FwTimeout) - { - if (*((volatile IMG_BOOL *)&psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated)) - { - /* No need to wait if the FW has already updated the values */ - break; - } - OSWaitus(ui32FwTimeout/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - ui32RegValue = 0; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if ((!PVRSRV_VZ_MODE_IS(GUEST)) && - RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - eError = RGXReadFWModuleAddr(psDevInfo, META_CR_T0ENABLE_OFFSET, &ui32RegValue); - - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Reading RGX META register failed. Is the GPU correctly powered up? (%u)", - __func__, eError)); - goto chk_exit; - } - - if (!(ui32RegValue & META_CR_TXENABLE_ENABLE_BIT)) - { - eError = PVRSRV_ERROR_META_THREAD0_NOT_ENABLED; - PVR_DPF((PVR_DBG_ERROR, - "%s: RGX META is not running. Is the GPU correctly powered up? %d (%u)", - __func__, psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated, eError)); - goto chk_exit; - } - } -#endif - - if (!*((volatile IMG_BOOL *)&psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated)) - { - eError = PVRSRV_ERROR_TIMEOUT; - PVR_DPF((PVR_DBG_ERROR, "%s: GPU Firmware not responding: failed to supply compatibility info (%u)", - __func__, eError)); - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Potential causes: firmware not initialised or the current Guest driver's " - "OsConfig initialisation data was not accepted by the firmware", __func__)); - } - goto chk_exit; - } - - ui8FwOsCount = psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.sInitOptions.ui8OsCountSupport; - if ((PVRSRV_VZ_MODE_IS(NATIVE) && (ui8FwOsCount > 1)) || - (PVRSRV_VZ_MODE_IS(HOST) && (ui8FwOsCount != RGX_NUM_OS_SUPPORTED))) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Mismatch between the number of Operating Systems supported by KM driver (%d) and FW (%d)", - __func__, (PVRSRV_VZ_MODE_IS(NATIVE)) ? (1) : (RGX_NUM_OS_SUPPORTED), ui8FwOsCount)); - } -#endif /* defined(NO_HARDWARE) */ - - eError = RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver(psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - - eError = RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver(psDevInfo, psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - - eError = RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver(psDevInfo, psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = RGXDevInitCompatCheck_BVNC_FWAgainstDriver(psDevInfo, psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - - eError = RGXDevInitCompatCheck_BVNC_HWAgainstDriver(psDevInfo, psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - } - - eError = RGXDevInitCompatCheck_FWProcessorVersion_AgainstDriver(psDevInfo, psDevInfo->psRGXFWIfOsInit); - if (eError != PVRSRV_OK) - { - goto chk_exit; - } - - eError = PVRSRV_OK; -chk_exit: - - return eError; -} - -/**************************************************************************/ /*! -@Function RGXSoftReset -@Description Resets some modules of the RGX device -@Input psDeviceNode Device node -@Input ui64ResetValue1 A mask for which each bit set corresponds - to a module to reset (via the SOFT_RESET - register). -@Input ui64ResetValue2 A mask for which each bit set corresponds - to a module to reset (via the SOFT_RESET2 - register). -@Return PVRSRV_ERROR - */ /***************************************************************************/ -static PVRSRV_ERROR RGXSoftReset(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT64 ui64ResetValue1, - IMG_UINT64 ui64ResetValue2) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_BOOL bSoftReset = IMG_FALSE; - IMG_UINT64 ui64SoftResetMask = 0; - - PVR_ASSERT(psDeviceNode != NULL); - PVR_ASSERT(psDeviceNode->pvDevice != NULL); - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - /* the device info */ - psDevInfo = psDeviceNode->pvDevice; -#if defined(RGX_CR_SOFT_RESET__PBE2_XE__MASKFULL) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, PBE2_IN_XE)) - { - ui64SoftResetMask = RGX_CR_SOFT_RESET__PBE2_XE__MASKFULL; - }else -#endif - { - ui64SoftResetMask = RGX_CR_SOFT_RESET_MASKFULL; - } - -#if defined(RGX_CR_SOFT_RESET2_MASKFULL) - if ((RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) && - ((ui64ResetValue2 & RGX_CR_SOFT_RESET2_MASKFULL) != ui64ResetValue2)) - { - bSoftReset = IMG_TRUE; - } -#endif - - if (((ui64ResetValue1 & ui64SoftResetMask) != ui64ResetValue1) || bSoftReset) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Set in soft-reset */ - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, ui64ResetValue1); - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, ui64ResetValue2); - } -#endif - - /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */ - (void) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET); -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - (void) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2); - } -#endif - - /* Take the modules out of reset... */ - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, 0); -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, 0); - } -#endif - - /* ...and fence again */ - (void) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET); -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - (void) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2); - } -#endif - - return PVRSRV_OK; -} - -static const RGX_MIPS_ADDRESS_TRAMPOLINE sNullTrampoline; - -static void RGXFreeTrampoline(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - DevPhysMemFree(psDeviceNode, -#if defined(PDUMP) - psDevInfo->psTrampoline->hPdumpPages, -#endif - &psDevInfo->psTrampoline->sPages); - - if (psDevInfo->psTrampoline != &sNullTrampoline) - { - OSFreeMem(psDevInfo->psTrampoline); - } - psDevInfo->psTrampoline = (RGX_MIPS_ADDRESS_TRAMPOLINE *)&sNullTrampoline; -} - -#define RANGES_OVERLAP(x,y,size) (x < (y+size) && y < (x+size)) -#define TRAMPOLINE_ALLOC_MAX_RETRIES (3) - -static PVRSRV_ERROR RGXAllocTrampoline(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - IMG_INT32 i, j; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_MIPS_ADDRESS_TRAMPOLINE *pasTrampoline[TRAMPOLINE_ALLOC_MAX_RETRIES]; - - PDUMPCOMMENT(psDeviceNode, "Allocate pages for trampoline"); - - /* Retry the allocation of the trampoline block (16KB), retaining any - * previous allocations overlapping with the target range until we get an - * allocation that doesn't overlap with the target range. - * Any allocation like this will require a maximum of 3 tries as we are - * allocating a physical contiguous block of memory, not individual pages. - * Free the unused allocations at the end only after the desired range - * is obtained to prevent the alloc function from returning the same bad - * range repeatedly. - */ - for (i = 0; i < TRAMPOLINE_ALLOC_MAX_RETRIES; i++) - { - pasTrampoline[i] = OSAllocMem(sizeof(RGX_MIPS_ADDRESS_TRAMPOLINE)); - eError = DevPhysMemAlloc(psDeviceNode, - RGXMIPSFW_TRAMPOLINE_SIZE, - RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE, - 0, // (init) u8Value - IMG_FALSE, // bInitPage, -#if defined(PDUMP) - psDeviceNode->psFirmwareMMUDevAttrs->pszMMUPxPDumpMemSpaceName, - "TrampolineRegion", - &pasTrampoline[i]->hPdumpPages, -#endif - &pasTrampoline[i]->sPages, - &pasTrampoline[i]->sPhysAddr); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, - "%s failed (%u)", - __func__, - eError)); - goto fail; - } - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - /* Set the persistent uiOSid value so that we free from the correct - * base arena when unloading the driver and freeing the trampoline. - */ - pasTrampoline[i]->sPages.uiOSid = 0; /* Firmware global arena */ -#endif - - if (!RANGES_OVERLAP(pasTrampoline[i]->sPhysAddr.uiAddr, - RGXMIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR, - RGXMIPSFW_TRAMPOLINE_SIZE)) - { - break; - } - } - if (TRAMPOLINE_ALLOC_MAX_RETRIES == i) - { - /* Failed to find a physical allocation after 3 attempts */ - eError = PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; - PVR_DPF((PVR_DBG_ERROR, - "%s failed to allocate non-overlapping pages (%u)", - __func__, eError)); - /* Fall through, clean up and return error. */ - } - else - { - /* Remember the last physical block allocated, it will not be freed */ - psDevInfo->psTrampoline = pasTrampoline[i]; - } - -fail: - /* free all unused allocations */ - for (j = 0; j < i; j++) - { - DevPhysMemFree(psDeviceNode, -#if defined(PDUMP) - pasTrampoline[j]->hPdumpPages, -#endif - &pasTrampoline[j]->sPages); - OSFreeMem(pasTrampoline[j]); - } - - return eError; -} - -#undef RANGES_OVERLAP - - -PVRSRV_ERROR RGXInitAllocFWImgMem(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEVMEM_SIZE_T uiFWCodeLen, - IMG_DEVMEM_SIZE_T uiFWDataLen, - IMG_DEVMEM_SIZE_T uiFWCorememCodeLen, - IMG_DEVMEM_SIZE_T uiFWCorememDataLen) -{ - PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - IMG_DEVMEM_SIZE_T uiDummyLen; - DEVMEM_MEMDESC *psDummyMemDesc = NULL; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && - (RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) == 32)) - { - eError = RGXAllocTrampoline(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate trampoline region (%u)", - eError)); - goto failTrampolineMemDescAlloc; - } - } - - /* - * Set up Allocation for FW code section - */ - uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_CODE); - - eError = RGXAllocateFWMemoryRegion(psDeviceNode, - uiFWCodeLen, - uiMemAllocFlags, - "FwExCodeRegion", - &psDevInfo->psRGXFWCodeMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate fw code mem (%u)", - eError)); - goto failFWCodeMemDescAlloc; - } - - eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWCodeMemDesc, - &psDevInfo->sFWCodeDevVAddrBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to acquire devVAddr for fw code mem (%u)", - eError)); - goto failFWCodeMemDescAqDevVirt; - } - - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) || (PVRSRV_VZ_MODE_IS(GUEST)))) - { - /* - * The FW code must be the first allocation in the firmware heap, otherwise - * the bootloader will not work (the FW will not be able to find the bootloader). - */ - PVR_ASSERT(psDevInfo->sFWCodeDevVAddrBase.uiAddr == RGX_FIRMWARE_RAW_HEAP_BASE); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - /* - * Allocate Dummy Pages so that Data segment allocation gets the same - * device virtual address as specified in MIPS firmware linker script - */ - uiDummyLen = RGXGetFWImageSectionMaxSize(NULL, MIPS_CODE) + - RGXGetFWImageSectionMaxSize(NULL, MIPS_EXCEPTIONS_CODE) + - RGXGetFWImageSectionMaxSize(NULL, MIPS_BOOT_CODE) - - uiFWCodeLen; /* code actual size */ - - if (uiDummyLen > 0) - { - eError = DevmemFwAllocateExportable(psDeviceNode, - uiDummyLen, - OSGetPageSize(), - uiMemAllocFlags, - "FwExDummyPages", - &psDummyMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate fw dummy mem (%u)", - eError)); - goto failDummyMemDescAlloc; - } - } - } - - /* - * Set up Allocation for FW data section - */ - uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_PRIV_DATA); - - eError = RGXAllocateFWMemoryRegion(psDeviceNode, - uiFWDataLen, - uiMemAllocFlags, - "FwExDataRegion", - &psDevInfo->psRGXFWDataMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate fw data mem (%u)", - eError)); - goto failFWDataMemDescAlloc; - } - - eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWDataMemDesc, - &psDevInfo->sFWDataDevVAddrBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to acquire devVAddr for fw data mem (%u)", - eError)); - goto failFWDataMemDescAqDevVirt; - } - - if (uiFWCorememCodeLen != 0) - { - /* - * Set up Allocation for FW coremem code section - */ - uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_CODE); - - eError = RGXAllocateFWMemoryRegion(psDeviceNode, - uiFWCorememCodeLen, - uiMemAllocFlags, - "FwExCorememCodeRegion", - &psDevInfo->psRGXFWCorememCodeMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate fw coremem code mem, size: %" IMG_INT64_FMTSPECd ", flags: %" PVRSRV_MEMALLOCFLAGS_FMTSPEC " (%u)", - uiFWCorememCodeLen, uiMemAllocFlags, eError)); - goto failFWCorememCodeMemDescAlloc; - } - - eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc, - &psDevInfo->sFWCorememCodeDevVAddrBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to acquire devVAddr for fw coremem mem code (%u)", - eError)); - goto failFWCorememCodeMemDescAqDevVirt; - } - - eError = RGXSetFirmwareAddress(&psDevInfo->sFWCorememCodeFWAddr, - psDevInfo->psRGXFWCorememCodeMemDesc, - 0, RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:1", failFWCorememCodeMemDescFwAddr); - } - else - { - psDevInfo->sFWCorememCodeDevVAddrBase.uiAddr = 0; - psDevInfo->sFWCorememCodeFWAddr.ui32Addr = 0; - } - - if (uiFWCorememDataLen != 0) - { - /* - * Set up Allocation for FW coremem data section - */ - uiMemAllocFlags = (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_PRIV_DATA)) - & RGX_AUTOVZ_KEEP_FW_DATA_MASK(psDeviceNode->bAutoVzFwIsUp); - - eError = RGXAllocateFWMemoryRegion(psDeviceNode, - uiFWCorememDataLen, - uiMemAllocFlags, - "FwExCorememDataRegion", - &psDevInfo->psRGXFWIfCorememDataStoreMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to allocate fw coremem data mem, " - "size: %" IMG_INT64_FMTSPECd ", flags: %" PVRSRV_MEMALLOCFLAGS_FMTSPEC " (%u)", - uiFWCorememDataLen, - uiMemAllocFlags, - eError)); - goto failFWCorememDataMemDescAlloc; - } - - eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWIfCorememDataStoreMemDesc, - &psDevInfo->sFWCorememDataStoreDevVAddrBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Failed to acquire devVAddr for fw coremem mem data (%u)", - eError)); - goto failFWCorememDataMemDescAqDevVirt; - } - - eError = RGXSetFirmwareAddress(&psDevInfo->sFWCorememDataStoreFWAddr, - psDevInfo->psRGXFWIfCorememDataStoreMemDesc, - 0, RFW_FWADDR_NOREF_FLAG); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:2", failFWCorememDataMemDescFwAddr); - } - else - { - psDevInfo->sFWCorememDataStoreDevVAddrBase.uiAddr = 0; - psDevInfo->sFWCorememDataStoreFWAddr.ui32Addr = 0; - } - - /* Free Dummy Pages */ - if (psDummyMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDummyMemDesc); - } - - return PVRSRV_OK; - -failFWCorememDataMemDescFwAddr: -failFWCorememDataMemDescAqDevVirt: - if (uiFWCorememDataLen != 0) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfCorememDataStoreMemDesc); - psDevInfo->psRGXFWIfCorememDataStoreMemDesc = NULL; - } -failFWCorememDataMemDescAlloc: -failFWCorememCodeMemDescFwAddr: -failFWCorememCodeMemDescAqDevVirt: - if (uiFWCorememCodeLen != 0) - { - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWCorememCodeMemDesc); - psDevInfo->psRGXFWCorememCodeMemDesc = NULL; - } -failFWCorememCodeMemDescAlloc: -failFWDataMemDescAqDevVirt: - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWDataMemDesc); - psDevInfo->psRGXFWDataMemDesc = NULL; -failFWDataMemDescAlloc: - if (psDummyMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psDummyMemDesc); - } -failDummyMemDescAlloc: -failFWCodeMemDescAqDevVirt: - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWCodeMemDesc); - psDevInfo->psRGXFWCodeMemDesc = NULL; -failFWCodeMemDescAlloc: - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && - (RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) == 32)) - { - RGXFreeTrampoline(psDeviceNode); - } -failTrampolineMemDescAlloc: - return eError; -} - -/* - AppHint parameter interface - */ -static -PVRSRV_ERROR RGXFWTraceQueryFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVRSRV_ERROR eResult; - - eResult = PVRSRVRGXFWDebugQueryFWLogKM(NULL, psDeviceNode, pui32Value); - *pui32Value &= RGXFWIF_LOG_TYPE_GROUP_MASK; - return eResult; -} - -static -PVRSRV_ERROR RGXFWTraceQueryLogType(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVRSRV_ERROR eResult; - - eResult = PVRSRVRGXFWDebugQueryFWLogKM(NULL, psDeviceNode, pui32Value); - if (PVRSRV_OK == eResult) - { - if (*pui32Value & RGXFWIF_LOG_TYPE_TRACE) - { - *pui32Value = 0; /* Trace */ - } - else - { - *pui32Value = 1; /* TBI */ - } - } - return eResult; -} - -static -PVRSRV_ERROR RGXFWTraceSetFilter(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eResult; - IMG_UINT32 ui32RGXFWLogType; - - eResult = RGXFWTraceQueryLogType(psDeviceNode, NULL, &ui32RGXFWLogType); - if (PVRSRV_OK == eResult) - { - if (0 == ui32RGXFWLogType) - { - BITMASK_SET(ui32Value, RGXFWIF_LOG_TYPE_TRACE); - } - eResult = PVRSRVRGXFWDebugSetFWLogKM(NULL, psDeviceNode, ui32Value); - } - return eResult; -} - -static -PVRSRV_ERROR RGXFWTraceSetLogType(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eResult; - IMG_UINT32 ui32RGXFWLogType = ui32Value; - - eResult = RGXFWTraceQueryFilter(psDeviceNode, NULL, &ui32RGXFWLogType); - if (PVRSRV_OK != eResult) - { - return eResult; - } - - /* 0 - trace, 1 - tbi */ - if (0 == ui32Value) - { - BITMASK_SET(ui32RGXFWLogType, RGXFWIF_LOG_TYPE_TRACE); - } -#if defined(SUPPORT_TBI_INTERFACE) - else if (1 == ui32Value) - { - BITMASK_UNSET(ui32RGXFWLogType, RGXFWIF_LOG_TYPE_TRACE); - } -#endif - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid parameter %u specified to set FW log type AppHint.", - __func__, ui32Value)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eResult = PVRSRVRGXFWDebugSetFWLogKM(NULL, psDeviceNode, ui32RGXFWLogType); - return eResult; -} - -#if defined(DEBUG) -static -PVRSRV_ERROR RGXQueryFWPoisonOnFree(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_BOOL *pbValue) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice; - - *pbValue = (PVRSRV_MEMALLOCFLAG_POISON_ON_FREE == psDevInfo->uiFWPoisonOnFreeFlag) - ? IMG_TRUE - : IMG_FALSE; - return PVRSRV_OK; -} - -static -PVRSRV_ERROR RGXSetFWPoisonOnFree(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_BOOL bValue) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice; - psDevInfo->uiFWPoisonOnFreeFlag = bValue - ? PVRSRV_MEMALLOCFLAG_POISON_ON_FREE - : 0ULL; - - return PVRSRV_OK; -} -#endif - -/* - * RGXInitFirmware - */ -PVRSRV_ERROR -RGXInitFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bEnableSignatureChecks, - IMG_UINT32 ui32SignatureChecksBufSize, - IMG_UINT32 ui32HWPerfFWBufSizeKB, - IMG_UINT64 ui64HWPerfFilter, - IMG_UINT32 ui32ConfigFlags, - IMG_UINT32 ui32LogType, - IMG_UINT32 ui32FilterFlags, - IMG_UINT32 ui32JonesDisableMask, - IMG_UINT32 ui32HWRDebugDumpLimit, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_UINT32 *pui32TPUTrilinearFracMask, - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandingConf, - FW_PERF_CONF eFirmwarePerf, - IMG_UINT32 ui32KCCBSizeLog2, - IMG_UINT32 ui32ConfigFlagsExt, - IMG_UINT32 ui32FwOsCfgFlags) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; -#if defined(DEBUG) - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault; - IMG_BOOL bEnableFWPoisonOnFree = IMG_FALSE; -#endif - - eError = RGXSetupFirmware(psDeviceNode, - bEnableSignatureChecks, - ui32SignatureChecksBufSize, - ui32HWPerfFWBufSizeKB, - ui64HWPerfFilter, - ui32ConfigFlags, - ui32ConfigFlagsExt, - ui32FwOsCfgFlags, - ui32LogType, - ui32FilterFlags, - ui32JonesDisableMask, - ui32HWRDebugDumpLimit, - ui32HWPerfCountersDataSize, - pui32TPUTrilinearFracMask, - eRGXRDPowerIslandingConf, - eFirmwarePerf, - ui32KCCBSizeLog2); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRGXInitFirmwareKM: RGXSetupFirmware failed (%u)", - eError)); - goto failed_init_firmware; - } - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_EnableLogGroup, - RGXFWTraceQueryFilter, - RGXFWTraceSetFilter, - psDeviceNode, - NULL); - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_FirmwareLogType, - RGXFWTraceQueryLogType, - RGXFWTraceSetLogType, - psDeviceNode, - NULL); - } - -#if defined(DEBUG) - OSCreateKMAppHintState(&pvAppHintState); - - ui32AppHintDefault = PVRSRV_APPHINT_ENABLEFWPOISONONFREE; - OSGetKMAppHintBOOL(psDeviceNode, - pvAppHintState, - EnableFWPoisonOnFree, - &ui32AppHintDefault, - &bEnableFWPoisonOnFree); - - OSFreeKMAppHintState(pvAppHintState); - - PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_EnableFWPoisonOnFree, - RGXQueryFWPoisonOnFree, - RGXSetFWPoisonOnFree, - psDeviceNode, - NULL); - - psDevInfo->uiFWPoisonOnFreeFlag = bEnableFWPoisonOnFree - ? PVRSRV_MEMALLOCFLAG_POISON_ON_FREE - : 0ULL; -#else - psDevInfo->uiFWPoisonOnFreeFlag = 0ULL; -#endif - - psDevInfo->ui32ClockSource = PVRSRV_APPHINT_TIMECORRCLOCK; - psDevInfo->ui32LastClockSource = PVRSRV_APPHINT_TIMECORRCLOCK; - - return PVRSRV_OK; - -failed_init_firmware: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/* See device.h for function declaration */ -static PVRSRV_ERROR RGXAllocUFOBlock(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC **psMemDesc, - IMG_UINT32 *puiSyncPrimVAddr, - IMG_UINT32 *puiSyncPrimBlockSize) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PVRSRV_ERROR eError; - RGXFWIF_DEV_VIRTADDR pFirmwareAddr; - IMG_DEVMEM_SIZE_T uiUFOBlockSize = sizeof(IMG_UINT32); - IMG_DEVMEM_ALIGN_T ui32UFOBlockAlign = sizeof(IMG_UINT32); - IMG_UINT32 ui32CoherencyFlag = 0; - - psDevInfo = psDeviceNode->pvDevice; - - /* Size and align are 'expanded' because we request an Exportalign allocation */ - eError = DevmemExportalignAdjustSizeAndAlign(DevmemGetHeapLog2PageSize(psDevInfo->psFirmwareMainHeap), - &uiUFOBlockSize, - &ui32UFOBlockAlign); - if (eError != PVRSRV_OK) - { - goto e0; - } - - if (PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig) && - PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig)) - { - ui32CoherencyFlag = PVRSRV_MEMALLOCFLAG_CACHE_COHERENT; - } - else - { - ui32CoherencyFlag = PVRSRV_MEMALLOCFLAG_UNCACHED; - } - - eError = DevmemFwAllocateExportable(psDeviceNode, - uiUFOBlockSize, - ui32UFOBlockAlign, - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - ui32CoherencyFlag, - "FwExUFOBlock", - psMemDesc); - if (eError != PVRSRV_OK) - { - goto e0; - } - - eError = RGXSetFirmwareAddress(&pFirmwareAddr, *psMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_GOTO_IF_ERROR(eError, e1); - - *puiSyncPrimVAddr = pFirmwareAddr.ui32Addr; - *puiSyncPrimBlockSize = TRUNCATE_64BITS_TO_32BITS(uiUFOBlockSize); - - return PVRSRV_OK; - -e1: - DevmemFwUnmapAndFree(psDevInfo, *psMemDesc); -e0: - return eError; -} - -/* See device.h for function declaration */ -static void RGXFreeUFOBlock(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psMemDesc) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* - If the system has snooping of the device cache then the UFO block - might be in the cache so we need to flush it out before freeing - the memory - - When the device is being shutdown/destroyed we don't care anymore. - Several necessary data structures to issue a flush were destroyed - already. - */ - if (PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig) && - psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_DEINIT) - { - RGXFWIF_KCCB_CMD sFlushInvalCmd; - PVRSRV_ERROR eError; - IMG_UINT32 ui32kCCBCommandSlot; - - /* Schedule the SLC flush command ... */ -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Submit SLC flush and invalidate"); -#endif - sFlushInvalCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_TRUE; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_FALSE; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.psContext.ui32Addr = 0; - - eError = RGXSendCommandWithPowLockAndGetKCCBSlot(psDevInfo, - &sFlushInvalCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule SLC flush command with error (%u)", - __func__, - eError)); - } - else - { - /* Wait for the SLC flush to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: SLC flush and invalidate aborted with error (%u)", - __func__, - eError)); - } - else if (unlikely(psDevInfo->pui32KernelCCBRtnSlots[ui32kCCBCommandSlot] & - RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: FW poll on a HW operation failed", __func__)); - } - } - } - - RGXUnsetFirmwareAddress(psMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psMemDesc); -} - -static void DevPart2DeInitRGX(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*)psDeviceNode->pvDevice; - - psDevInfo->bDevInit2Done = IMG_FALSE; - -#if defined(RGX_FEATURE_COMPUTE_ONLY_BIT_MASK) - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE_ONLY)) -#endif - { - if ((psDevInfo->hTQUSCSharedMem != NULL) && - (psDevInfo->hTQCLISharedMem != NULL)) - { - PVRSRVTQUnloadShaders(psDeviceNode); - } - } - -#if !defined(NO_HARDWARE) - if (psDevInfo->pvLISRData != NULL) - { - (void) SysUninstallDeviceLISR(psDevInfo->pvLISRData); - } - if (psDevInfo->pvMISRData != NULL) - { - (void) OSUninstallMISR(psDevInfo->pvMISRData); - } - if (psDevInfo->hProcessQueuesMISR != NULL) - { - (void) OSUninstallMISR(psDevInfo->hProcessQueuesMISR); - } - if (psDevInfo->pvAPMISRData != NULL) - { - (void) OSUninstallMISR(psDevInfo->pvAPMISRData); - } - if (psDeviceNode->hCmdCompNotify != NULL) - { - /* Cancel notifications to this device */ - PVRSRVUnregisterCmdCompleteNotify(psDeviceNode->hCmdCompNotify); - psDeviceNode->hCmdCompNotify = NULL; - } -#endif /* !NO_HARDWARE */ - - /* Remove the device from the power manager */ - PVRSRVRemovePowerDevice(psDeviceNode); - - psDevInfo->pfnGetGpuUtilStats = NULL; - if (psDevInfo->hGPUUtilLock != NULL) - { - OSLockDestroy(psDevInfo->hGPUUtilLock); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && - (psDevInfo->hNMILock != NULL)) - { - OSLockDestroy(psDevInfo->hNMILock); - } - - if ((GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) && - (psDevInfo->hMMUCtxUnregLock != NULL)) - { - OSLockDestroy(psDevInfo->hMMUCtxUnregLock); - } - - if (psDevInfo->hDebugFaultInfoLock != NULL) - { - OSLockDestroy(psDevInfo->hDebugFaultInfoLock); - } - - /* De-init Freelists/ZBuffers... */ - if (psDevInfo->hLockFreeList != NULL) - { - OSLockDestroy(psDevInfo->hLockFreeList); - } - - if (psDevInfo->hLockZSBuffer != NULL) - { - OSLockDestroy(psDevInfo->hLockZSBuffer); - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* De-init work estimation lock */ - if (psDevInfo->hWorkEstLock != NULL) - { - OSLockDestroy(psDevInfo->hWorkEstLock); - } -#endif - - /* Free DVFS Table */ - if (psDevInfo->psGpuDVFSTable != NULL) - { - OSFreeMem(psDevInfo->psGpuDVFSTable); - psDevInfo->psGpuDVFSTable = NULL; - } -} - -/* - DevDeInitRGX - */ -PVRSRV_ERROR DevDeInitRGX(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*)psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - IMG_UINT32 ui32Temp=0; - - if (!psDevInfo) - { - /* Can happen if DevInitRGX failed */ - PVR_DPF((PVR_DBG_ERROR, "DevDeInitRGX: Null DevInfo")); - return PVRSRV_OK; - } - - if (psDevInfo->psRGXFWIfOsInit) - { - KM_SET_OS_CONNECTION(OFFLINE, psDevInfo); - } - - DeviceDepBridgeDeInit(psDevInfo); - -#if defined(PDUMP) - DevmemIntFreeDefBackingPage(psDeviceNode, - &psDeviceNode->sDummyPage, - DUMMY_PAGE); - DevmemIntFreeDefBackingPage(psDeviceNode, - &psDeviceNode->sDevZeroPage, - DEV_ZERO_PAGE); -#endif - -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) - if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - OSAtomicWrite(&psDeviceNode->sDummyPage.atRefCounter, 0); - PVR_UNREFERENCED_PARAMETER(ui32Temp); - } - else -#else - { - /*Delete the Dummy page related info */ - ui32Temp = (IMG_UINT32)OSAtomicRead(&psDeviceNode->sDummyPage.atRefCounter); - if (0 != ui32Temp) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Dummy page reference counter is non zero (%u)", - __func__, - ui32Temp)); - PVR_ASSERT(0); - } - } -#endif - - /*Delete the Dummy page related info */ - ui32Temp = (IMG_UINT32)OSAtomicRead(&psDeviceNode->sDevZeroPage.atRefCounter); - if (0 != ui32Temp) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Zero page reference counter is non zero (%u)", - __func__, - ui32Temp)); - } - -#if defined(PDUMP) - if (NULL != psDeviceNode->sDummyPage.hPdumpPg) - { - PDUMPCOMMENT(psDeviceNode, "Error dummy page handle is still active"); - } - - if (NULL != psDeviceNode->sDevZeroPage.hPdumpPg) - { - PDUMPCOMMENT(psDeviceNode, "Error Zero page handle is still active"); - } -#endif - - /*The lock type need to be dispatch type here because it can be acquired from MISR (Z-buffer) path */ - OSLockDestroy(psDeviceNode->sDummyPage.psPgLock); - - /* Destroy the zero page lock */ - OSLockDestroy(psDeviceNode->sDevZeroPage.psPgLock); - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) - OSLockDestroy(psDevInfo->hCounterDumpingLock); -#endif - - RGXDeInitMultiCoreInfo(psDeviceNode); - - /* Unregister debug request notifiers first as they could depend on anything. */ - - RGXDebugDeinit(psDevInfo); - - /* De-initialise in reverse order, so stage 2 init is undone first. */ - if (psDevInfo->bDevInit2Done) - { - DevPart2DeInitRGX(psDeviceNode); - } - - /* Unregister MMU related stuff */ - eError = RGXMMUInit_Unregister(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevDeInitRGX: Failed RGXMMUInit_Unregister (0x%x)", - eError)); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - /* Unregister MMU related stuff */ - eError = RGXMipsMMUInit_Unregister(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevDeInitRGX: Failed RGXMipsMMUInit_Unregister (0x%x)", - eError)); - } - } - - /* UnMap Regs */ - if (psDevInfo->pvRegsBaseKM != NULL) - { -#if !defined(NO_HARDWARE) - OSUnMapPhysToLin((void __force *) psDevInfo->pvRegsBaseKM, - psDevInfo->ui32RegSize); -#endif /* !NO_HARDWARE */ - psDevInfo->pvRegsBaseKM = NULL; - } - -#if 0 /* not required at this time */ - if (psDevInfo->hTimer) - { - eError = OSRemoveTimer(psDevInfo->hTimer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevDeInitRGX: Failed to remove timer")); - return eError; - } - psDevInfo->hTimer = NULL; - } -#endif - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - - RGXDeInitHeaps(psDevMemoryInfo); - - if (psDevInfo->psRGXFWCodeMemDesc) - { - /* Free fw code */ - PDUMPCOMMENT(psDeviceNode, "Freeing FW code memory"); - DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWCodeMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWCodeMemDesc); - psDevInfo->psRGXFWCodeMemDesc = NULL; - } - else if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_WARNING, "No firmware code memory to free")); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && - (RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) == 32)) - { - if (psDevInfo->psTrampoline->sPages.u.pvHandle) - { - /* Free trampoline region */ - PDUMPCOMMENT(psDeviceNode, "Freeing trampoline memory"); - RGXFreeTrampoline(psDeviceNode); - } - } - - if (psDevInfo->psRGXFWDataMemDesc) - { - /* Free fw data */ - PDUMPCOMMENT(psDeviceNode, "Freeing FW data memory"); - DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWDataMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWDataMemDesc); - psDevInfo->psRGXFWDataMemDesc = NULL; - } - else if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_DPF((PVR_DBG_WARNING, "No firmware data memory to free")); - } - - if (psDevInfo->psRGXFWCorememCodeMemDesc) - { - /* Free fw core mem code */ - PDUMPCOMMENT(psDeviceNode, "Freeing FW coremem code memory"); - DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWCorememCodeMemDesc); - psDevInfo->psRGXFWCorememCodeMemDesc = NULL; - } - - if (psDevInfo->psRGXFWIfCorememDataStoreMemDesc) - { - /* Free fw core mem data */ - PDUMPCOMMENT(psDeviceNode, "Freeing FW coremem data store memory"); - DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWIfCorememDataStoreMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psDevInfo->psRGXFWIfCorememDataStoreMemDesc); - psDevInfo->psRGXFWIfCorememDataStoreMemDesc = NULL; - } - - /* - Free the firmware allocations. - */ - RGXFreeFirmware(psDevInfo); - - /* De-initialise non-device specific (TL) users of RGX device memory */ - RGXHWPerfDeinit(psDevInfo); - RGXHWPerfHostDeInit(psDevInfo); - eError = HTBDeInit(); - PVR_LOG_IF_ERROR(eError, "HTBDeInit"); - - RGXDeInitDestroyFWKernelMemoryContext(psDeviceNode); - - /* destroy the stalled CCB locks */ - OSLockDestroy(psDevInfo->hCCBRecoveryLock); - OSLockDestroy(psDevInfo->hCCBStallCheckLock); - - /* destroy the context list locks */ - OSLockDestroy(psDevInfo->sRegCongfig.hLock); - OSLockDestroy(psDevInfo->hBPLock); - OSLockDestroy(psDevInfo->hRGXFWIfBufInitLock); - OSWRLockDestroy(psDevInfo->hRenderCtxListLock); - OSWRLockDestroy(psDevInfo->hComputeCtxListLock); - OSWRLockDestroy(psDevInfo->hTransferCtxListLock); - OSWRLockDestroy(psDevInfo->hTDMCtxListLock); - OSWRLockDestroy(psDevInfo->hKickSyncCtxListLock); - OSWRLockDestroy(psDevInfo->hMemoryCtxListLock); - OSSpinLockDestroy(psDevInfo->hLockKCCBDeferredCommandsList); - OSWRLockDestroy(psDevInfo->hCommonCtxtListLock); - - /* Free device BVNC string */ - if (NULL != psDevInfo->sDevFeatureCfg.pszBVNCString) - { - OSFreeMem(psDevInfo->sDevFeatureCfg.pszBVNCString); - } - - /* DeAllocate devinfo */ - OSFreeMem(psDevInfo); - - psDeviceNode->pvDevice = NULL; - - return PVRSRV_OK; -} - -#if defined(PDUMP) -static -PVRSRV_ERROR RGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)(psDeviceNode->pvDevice); - - psDevInfo->bDumpedKCCBCtlAlready = IMG_FALSE; - - return PVRSRV_OK; -} -#endif /* PDUMP */ - -/* Takes a log2 page size parameter and calculates a suitable page size - * for the RGX heaps. Returns 0 if parameter is wrong.*/ -static INLINE IMG_UINT32 RGXHeapDerivePageSize(IMG_UINT32 uiLog2PageSize) -{ - IMG_BOOL bFound = IMG_FALSE; - - /* OS page shift must be at least RGX_HEAP_4KB_PAGE_SHIFT, - * max RGX_HEAP_2MB_PAGE_SHIFT, non-zero and a power of two*/ - if (uiLog2PageSize == 0U || - (uiLog2PageSize < RGX_HEAP_4KB_PAGE_SHIFT) || - (uiLog2PageSize > RGX_HEAP_2MB_PAGE_SHIFT)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Provided incompatible log2 page size %u", - __func__, - uiLog2PageSize)); - PVR_ASSERT(0); - return 0; - } - - do - { - switch (uiLog2PageSize) - { - case RGX_HEAP_4KB_PAGE_SHIFT: - case RGX_HEAP_16KB_PAGE_SHIFT: - case RGX_HEAP_64KB_PAGE_SHIFT: - case RGX_HEAP_256KB_PAGE_SHIFT: - case RGX_HEAP_1MB_PAGE_SHIFT: - case RGX_HEAP_2MB_PAGE_SHIFT: - /* All good, RGX page size equals given page size - * => use it as default for heaps */ - bFound = IMG_TRUE; - break; - default: - /* We have to fall back to a smaller device - * page size than given page size because there - * is no exact match for any supported size. */ - uiLog2PageSize -= 1U; - break; - } - } while (!bFound); - - return uiLog2PageSize; -} - -/* First 16-bits define possible types */ -#define HEAP_INST_VALUE_MASK (0xFFFF) -#define HEAP_INST_DEFAULT_VALUE (1U) /* Used to show either the heap is always instantiated by default (pfn = NULL) - OR - that this is the default configuration of the heap with an Alternative BRN */ -#define HEAP_INST_BRN_DEP_VALUE (2U) /* The inclusion of this heap is dependent on the brn being present */ -#define HEAP_INST_FEAT_DEP_VALUE (3U) /* The inclusion of this heap is dependent on the feature being present */ -#define HEAP_INST_BRN_ALT_VALUE (4U) /* This entry is a possible alternative to the default determined by a BRN */ -#define HEAP_INST_FEAT_ALT_VALUE (5U) /* The entry is a possible alternative to the default determined by a Feature define */ - -/* Latter 16-bits define other flags we may need */ -#define HEAP_INST_NON4K_FLAG (1 << 16U) /* This is a possible NON4K Entry and we should use the device - NON4K size when instantiating */ - -typedef struct RGX_HEAP_INFO_TAG RGX_HEAP_INFO; // Forward declaration -typedef IMG_BOOL (*PFN_IS_PRESENT)(PVRSRV_RGXDEV_INFO*, const RGX_HEAP_INFO*); - -struct RGX_HEAP_INFO_TAG -{ - IMG_CHAR *pszName; - IMG_UINT64 ui64HeapBase; - IMG_DEVMEM_SIZE_T uiHeapLength; - IMG_DEVMEM_SIZE_T uiHeapReservedRegionLength; - IMG_UINT32 ui32Log2ImportAlignment; - PFN_IS_PRESENT pfnIsHeapPresent; - IMG_UINT32 ui32HeapInstanceFlags; -}; - -/* Feature Present function prototypes */ - -static IMG_BOOL BRN65273IsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ -#if defined(FIX_HW_BRN_65273_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 65273)) - { - return (((pksHeapInfo->ui32HeapInstanceFlags & HEAP_INST_VALUE_MASK) == HEAP_INST_BRN_ALT_VALUE) || - ((pksHeapInfo->ui32HeapInstanceFlags & HEAP_INST_VALUE_MASK) == HEAP_INST_BRN_DEP_VALUE)) ? - IMG_TRUE : IMG_FALSE; - } - else -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); -#endif - { - return ((pksHeapInfo->ui32HeapInstanceFlags & HEAP_INST_VALUE_MASK) == HEAP_INST_DEFAULT_VALUE) ? IMG_TRUE : IMG_FALSE; - } -} - -static IMG_BOOL BRN63142IsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - PVR_UNREFERENCED_PARAMETER(pksHeapInfo); - -#if defined(FIX_HW_BRN_63142_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 63142)) - { - PVR_ASSERT((pksHeapInfo->ui64HeapBase & IMG_UINT64_C(0x3FFFFFFFF)) + - pksHeapInfo->uiHeapLength == IMG_UINT64_C(0x400000000)); - - return IMG_TRUE; - } -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); -#endif - - return IMG_FALSE; -} - -static IMG_BOOL FBCDescriptorIsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - PVR_UNREFERENCED_PARAMETER(pksHeapInfo); - - if (RGX_GET_FEATURE_VALUE(psDevInfo, FBC_MAX_DEFAULT_DESCRIPTORS)) - { - return IMG_TRUE; - } - - return IMG_FALSE; -} - -static IMG_BOOL FBCLargeDescriptorIsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - PVR_UNREFERENCED_PARAMETER(pksHeapInfo); - - if (RGX_GET_FEATURE_VALUE(psDevInfo, FBC_MAX_LARGE_DESCRIPTORS)) - { - return IMG_TRUE; - } - - return IMG_FALSE; -} - -static IMG_BOOL TextureStateIsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - PVR_UNREFERENCED_PARAMETER(pksHeapInfo); -#if defined(RGX_FEATURE_BINDLESS_IMAGE_AND_TEXTURE_STATE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, BINDLESS_IMAGE_AND_TEXTURE_STATE)) - { - return IMG_TRUE; - } -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); -#endif - return IMG_FALSE; -} - -static IMG_BOOL SignalSnoopingIsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - PVR_UNREFERENCED_PARAMETER(pksHeapInfo); - -#if defined(RGX_FEATURE_SIGNAL_SNOOPING_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SIGNAL_SNOOPING)) - { - return IMG_TRUE; - } -#else - PVR_UNREFERENCED_PARAMETER(psDevInfo); -#endif - - return IMG_FALSE; -} - -static IMG_BOOL FWBRN65101IsPresent(PVRSRV_RGXDEV_INFO *psDevInfo, const RGX_HEAP_INFO *pksHeapInfo) -{ - /* Used to determine the correct table row to instantiate as a heap by checking - * the Heap size and base at run time VS the current table instance - */ - IMG_UINT64 ui64MainSubHeapSize; - - /* MIPS Firmware must reserve some space in its Host/Native heap for GPU memory mappings */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && (!PVRSRV_VZ_MODE_IS(GUEST))) - { -#if defined(FIX_HW_BRN_65101_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 65101)) - { - ui64MainSubHeapSize = RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_BRN65101; - } - else -#endif - { - ui64MainSubHeapSize = RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_NORMAL; - } - } - else - { - ui64MainSubHeapSize = RGX_FIRMWARE_DEFAULT_MAIN_HEAP_SIZE; - } - - /* Determine if we should include this entry based upon previous checks */ - return (pksHeapInfo->uiHeapLength == ui64MainSubHeapSize && - pksHeapInfo->ui64HeapBase == RGX_FIRMWARE_MAIN_HEAP_BASE) ? - IMG_TRUE : IMG_FALSE; -} - -static IMG_BOOL FWVZConfigPresent(PVRSRV_RGXDEV_INFO* psDevInfo, const RGX_HEAP_INFO* pksHeapInfo) -{ - /* Used to determine the correct table row to instantiate as a heap by checking - * the Heap base at run time VS the current table instance - */ - - /* Determine if we should include this entry based upon previous checks */ - return (pksHeapInfo->ui64HeapBase == RGX_FIRMWARE_CONFIG_HEAP_BASE) ? IMG_TRUE : IMG_FALSE; -} - -/* Blueprint array. note: not all heaps are available to clients*/ - -static const RGX_HEAP_INFO gasRGXHeapLayoutApp[] = -{ - /* Name HeapBase HeapLength HeapReservedRegionLength Log2ImportAlignment pfnPresent HeapInstanceFlags */ - {RGX_GENERAL_SVM_HEAP_IDENT, RGX_GENERAL_SVM_HEAP_BASE, RGX_GENERAL_SVM_HEAP_SIZE, 0, 0, NULL, HEAP_INST_DEFAULT_VALUE }, - {RGX_GENERAL_HEAP_IDENT, RGX_GENERAL_HEAP_BASE, RGX_GENERAL_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE }, - {RGX_GENERAL_HEAP_IDENT, RGX_GENERAL_BRN_65273_HEAP_BASE, RGX_GENERAL_BRN_65273_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE }, - {RGX_GENERAL_NON4K_HEAP_IDENT, RGX_GENERAL_NON4K_HEAP_BASE, RGX_GENERAL_NON4K_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE | HEAP_INST_NON4K_FLAG }, - {RGX_GENERAL_NON4K_HEAP_IDENT, RGX_GENERAL_NON4K_BRN_65273_HEAP_BASE, RGX_GENERAL_NON4K_BRN_65273_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE | HEAP_INST_NON4K_FLAG }, - {RGX_PDSCODEDATA_HEAP_IDENT, RGX_PDSCODEDATA_HEAP_BASE, RGX_PDSCODEDATA_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE }, - {RGX_PDSCODEDATA_HEAP_IDENT, RGX_PDSCODEDATA_BRN_65273_HEAP_BASE, RGX_PDSCODEDATA_BRN_65273_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE }, - {RGX_RGNHDR_BRN_63142_HEAP_IDENT, RGX_RGNHDR_BRN_63142_HEAP_BASE, RGX_RGNHDR_BRN_63142_HEAP_SIZE, 0, 0, BRN63142IsPresent, HEAP_INST_BRN_DEP_VALUE }, - {RGX_USCCODE_HEAP_IDENT, RGX_USCCODE_HEAP_BASE, RGX_USCCODE_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE }, - {RGX_USCCODE_HEAP_IDENT, RGX_USCCODE_BRN_65273_HEAP_BASE, RGX_USCCODE_BRN_65273_HEAP_SIZE, (1 * DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY), 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE }, - {RGX_TQ3DPARAMETERS_HEAP_IDENT, RGX_TQ3DPARAMETERS_HEAP_BASE, RGX_TQ3DPARAMETERS_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE }, - {RGX_TQ3DPARAMETERS_HEAP_IDENT, RGX_TQ3DPARAMETERS_BRN_65273_HEAP_BASE, RGX_TQ3DPARAMETERS_BRN_65273_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE }, - {RGX_VK_CAPT_REPLAY_HEAP_IDENT, RGX_VK_CAPT_REPLAY_HEAP_BASE, RGX_VK_CAPT_REPLAY_HEAP_SIZE, 0, 0, NULL, HEAP_INST_DEFAULT_VALUE }, - {RGX_SIGNALS_HEAP_IDENT, RGX_SIGNALS_HEAP_BASE, RGX_SIGNALS_HEAP_SIZE, 0, 0, SignalSnoopingIsPresent, HEAP_INST_FEAT_DEP_VALUE}, - {RGX_FBCDC_HEAP_IDENT, RGX_FBCDC_HEAP_BASE, RGX_FBCDC_HEAP_SIZE, 0, 0, FBCDescriptorIsPresent, HEAP_INST_FEAT_DEP_VALUE}, - {RGX_FBCDC_LARGE_HEAP_IDENT, RGX_FBCDC_LARGE_HEAP_BASE, RGX_FBCDC_LARGE_HEAP_SIZE, 0, 0, FBCLargeDescriptorIsPresent, HEAP_INST_FEAT_DEP_VALUE}, - {RGX_CMP_MISSION_RMW_HEAP_IDENT, RGX_CMP_MISSION_RMW_HEAP_BASE, RGX_CMP_MISSION_RMW_HEAP_SIZE, 0, 0, NULL, HEAP_INST_DEFAULT_VALUE }, - {RGX_CMP_SAFETY_RMW_HEAP_IDENT, RGX_CMP_SAFETY_RMW_HEAP_BASE, RGX_CMP_SAFETY_RMW_HEAP_SIZE, 0, 0, NULL, HEAP_INST_DEFAULT_VALUE }, - {RGX_TEXTURE_STATE_HEAP_IDENT, RGX_TEXTURE_STATE_HEAP_BASE, RGX_TEXTURE_STATE_HEAP_SIZE, 0, 0, TextureStateIsPresent, HEAP_INST_FEAT_DEP_VALUE}, - {RGX_VISIBILITY_TEST_HEAP_IDENT, RGX_VISIBILITY_TEST_HEAP_BASE, RGX_VISIBILITY_TEST_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_DEFAULT_VALUE }, - {RGX_VISIBILITY_TEST_HEAP_IDENT, RGX_VISIBILITY_TEST_BRN_65273_HEAP_BASE, RGX_VISIBILITY_TEST_BRN_65273_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_BRN_ALT_VALUE }, - {RGX_MMU_INIA_BRN_65273_HEAP_IDENT, RGX_MMU_INIA_BRN_65273_HEAP_BASE, RGX_MMU_INIA_BRN_65273_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_BRN_DEP_VALUE }, - {RGX_MMU_INIB_BRN_65273_HEAP_IDENT, RGX_MMU_INIB_BRN_65273_HEAP_BASE, RGX_MMU_INIB_BRN_65273_HEAP_SIZE, 0, 0, BRN65273IsPresent, HEAP_INST_BRN_DEP_VALUE } -}; - -static const RGX_HEAP_INFO gasRGXHeapLayoutFW[] = -{ - /* Name HeapBase HeapLength HeapReservedRegionLength Log2ImportAlignment pfnIsHeapPresent HeapInstanceFlags*/ - {RGX_FIRMWARE_MAIN_HEAP_IDENT, RGX_FIRMWARE_MAIN_HEAP_BASE, RGX_FIRMWARE_DEFAULT_MAIN_HEAP_SIZE, 0, 0, FWBRN65101IsPresent, HEAP_INST_DEFAULT_VALUE}, - {RGX_FIRMWARE_MAIN_HEAP_IDENT, RGX_FIRMWARE_MAIN_HEAP_BASE, RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_NORMAL, 0, 0, FWBRN65101IsPresent, HEAP_INST_DEFAULT_VALUE}, - {RGX_FIRMWARE_MAIN_HEAP_IDENT, RGX_FIRMWARE_MAIN_HEAP_BASE, RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_BRN65101, 0, 0, FWBRN65101IsPresent, HEAP_INST_BRN_ALT_VALUE}, - {RGX_FIRMWARE_CONFIG_HEAP_IDENT, RGX_FIRMWARE_CONFIG_HEAP_BASE, RGX_FIRMWARE_CONFIG_HEAP_SIZE, 0, 0, FWVZConfigPresent, HEAP_INST_DEFAULT_VALUE}, -}; - -/* Generic counting method. */ -static void _CountRequiredHeaps(PVRSRV_RGXDEV_INFO *psDevInfo, - const RGX_HEAP_INFO pksHeapInfo[], - IMG_UINT32 ui32HeapListSize, - IMG_UINT32* ui32HeapCount) -{ - IMG_UINT32 i; - - /* Loop over rows in the heap data array using callback to decide if we - * should include the heap - */ - for (i = 0; i < ui32HeapListSize; i++) - { - const RGX_HEAP_INFO *psHeapInfo = &pksHeapInfo[i]; - - if (psHeapInfo->pfnIsHeapPresent) - { - if (!psHeapInfo->pfnIsHeapPresent(psDevInfo, psHeapInfo)) - { - /* We don't need to create this heap */ - continue; - } - } - - (*ui32HeapCount)++; - } -} -/* Generic heap instantiator */ -static void _InstantiateRequiredHeaps(PVRSRV_RGXDEV_INFO *psDevInfo, - const RGX_HEAP_INFO pksHeapInfo[], - IMG_UINT32 ui32HeapListSize, - DEVMEM_HEAP_BLUEPRINT **psDeviceMemoryHeapCursor) -{ - IMG_UINT32 i; - /* We now have a list of the heaps to include and so we should loop over this - * list and instantiate. - */ - for (i = 0; i < ui32HeapListSize; i++) - { - IMG_UINT32 ui32Log2RgxDefaultPageShift = RGXHeapDerivePageSize(OSGetPageShift()); - IMG_UINT32 ui32Log2DataPageSize = 0; - - const RGX_HEAP_INFO *psHeapInfo = &pksHeapInfo[i]; - - if (psHeapInfo->pfnIsHeapPresent) - { - if (!psHeapInfo->pfnIsHeapPresent(psDevInfo, psHeapInfo)) - { - /* We don't need to create this heap */ - continue; - } - } - - if (psHeapInfo->ui32HeapInstanceFlags & HEAP_INST_NON4K_FLAG) - { - ui32Log2DataPageSize = psDevInfo->ui32Log2Non4KPgSize; - } - else - { - ui32Log2DataPageSize = ui32Log2RgxDefaultPageShift; - } - - HeapCfgBlueprintInit(psHeapInfo->pszName, - psHeapInfo->ui64HeapBase, - psHeapInfo->uiHeapLength, - psHeapInfo->uiHeapReservedRegionLength, - ui32Log2DataPageSize, - psHeapInfo->ui32Log2ImportAlignment, - *psDeviceMemoryHeapCursor); - - (*psDeviceMemoryHeapCursor)++; - } -} - -static PVRSRV_ERROR RGXInitHeaps(PVRSRV_RGXDEV_INFO *psDevInfo, - DEVICE_MEMORY_INFO *psNewMemoryInfo) -{ - PVRSRV_ERROR eError; - DEVMEM_HEAP_BLUEPRINT *psDeviceMemoryHeapCursor; - - IMG_UINT32 ui32HeapListSize = ARRAY_SIZE(gasRGXHeapLayoutApp); - IMG_UINT32 ui32FWHeapListSize = ARRAY_SIZE(gasRGXHeapLayoutFW); - IMG_UINT32 ui32CountedHeapSize; - - IMG_UINT32 ui32HeapCount = 0; - IMG_UINT32 ui32FWHeapCount = 0; - - /* Count heaps required for the app heaps */ - _CountRequiredHeaps(psDevInfo, - gasRGXHeapLayoutApp, - ui32HeapListSize, - &ui32HeapCount); - - /* Count heaps required for the FW heaps */ - _CountRequiredHeaps(psDevInfo, - gasRGXHeapLayoutFW, - ui32FWHeapListSize, - &ui32FWHeapCount); - - ui32CountedHeapSize = (ui32HeapCount + ui32FWHeapCount + RGX_NUM_OS_SUPPORTED); - - psNewMemoryInfo->psDeviceMemoryHeap = OSAllocMem(sizeof(DEVMEM_HEAP_BLUEPRINT) * ui32CountedHeapSize); - PVR_LOG_GOTO_IF_NOMEM(psNewMemoryInfo->psDeviceMemoryHeap, eError, e0); - - /* Initialise the heaps */ - psDeviceMemoryHeapCursor = psNewMemoryInfo->psDeviceMemoryHeap; - - /* Instantiate App Heaps */ - _InstantiateRequiredHeaps(psDevInfo, - gasRGXHeapLayoutApp, - ui32HeapListSize, - &psDeviceMemoryHeapCursor); - - /* Instantiate FW Heaps */ - _InstantiateRequiredHeaps(psDevInfo, - gasRGXHeapLayoutFW, - ui32FWHeapListSize, - &psDeviceMemoryHeapCursor); - - /* set the heap count */ - psNewMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeapCursor - psNewMemoryInfo->psDeviceMemoryHeap); - - /* Check we have allocated the correct # of heaps, minus any VZ heaps as these - * have not been created at this point - */ - PVR_ASSERT(psNewMemoryInfo->ui32HeapCount == (ui32CountedHeapSize - RGX_NUM_OS_SUPPORTED)); - - /* - In the new heap setup, we initialise 2 configurations: - 1 - One will be for the firmware only (index 1 in array) - a. This primarily has the firmware heap in it. - b. It also has additional guest OSID firmware heap(s) - - Only if the number of support firmware OSID > 1 - 2 - Others shall be for clients only (index 0 in array) - a. This has all the other client heaps in it. - */ - psNewMemoryInfo->uiNumHeapConfigs = 2; - psNewMemoryInfo->psDeviceMemoryHeapConfigArray = OSAllocMem(sizeof(DEVMEM_HEAP_CONFIG) * psNewMemoryInfo->uiNumHeapConfigs); - PVR_LOG_GOTO_IF_NOMEM(psNewMemoryInfo->psDeviceMemoryHeapConfigArray, eError, e1); - - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].pszName = "Default Heap Configuration"; - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].uiNumHeaps = psNewMemoryInfo->ui32HeapCount - RGX_FIRMWARE_NUMBER_OF_FW_HEAPS; - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].psHeapBlueprintArray = psNewMemoryInfo->psDeviceMemoryHeap; - - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].pszName = "Firmware Heap Configuration"; - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].uiNumHeaps = RGX_FIRMWARE_NUMBER_OF_FW_HEAPS; - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].psHeapBlueprintArray = psDeviceMemoryHeapCursor - RGX_FIRMWARE_NUMBER_OF_FW_HEAPS; - -#if (RGX_NUM_OS_SUPPORTED > 1) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - IMG_UINT32 ui32OSid; - - /* Create additional raw firmware heaps */ - for (ui32OSid = RGX_FIRST_RAW_HEAP_OSID; ui32OSid < RGX_NUM_OS_SUPPORTED; ui32OSid++) - { - if (RGXInitFwRawHeap(psDeviceMemoryHeapCursor, ui32OSid) != PVRSRV_OK) - { - /* if any allocation fails, free previously allocated heaps and abandon initialisation */ - for (; ui32OSid > RGX_FIRST_RAW_HEAP_OSID; ui32OSid--) - { - RGXDeInitFwRawHeap(psDeviceMemoryHeapCursor); - psDeviceMemoryHeapCursor--; - } - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e1; - } - - /* Append additional firmware heaps to host driver firmware context heap configuration */ - psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].uiNumHeaps += 1; - - /* advance to the next heap */ - psDeviceMemoryHeapCursor++; - } - } -#endif /* (RGX_NUM_OS_SUPPORTED > 1) */ - - return PVRSRV_OK; -e1: - OSFreeMem(psNewMemoryInfo->psDeviceMemoryHeap); -e0: - return eError; -} - -static void RGXDeInitHeaps(DEVICE_MEMORY_INFO *psDevMemoryInfo) -{ -#if (RGX_NUM_OS_SUPPORTED > 1) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - IMG_UINT32 ui32OSid; - DEVMEM_HEAP_BLUEPRINT *psDeviceMemoryHeapCursor = psDevMemoryInfo->psDeviceMemoryHeap; - - /* Delete all guest firmware heaps */ - for (ui32OSid = RGX_FIRST_RAW_HEAP_OSID; ui32OSid < RGX_NUM_OS_SUPPORTED; ui32OSid++) - { - RGXDeInitFwRawHeap(psDeviceMemoryHeapCursor); - psDeviceMemoryHeapCursor++; - } - } -#endif /* (RGX_NUM_OS_SUPPORTED > 1) */ - - OSFreeMem(psDevMemoryInfo->psDeviceMemoryHeapConfigArray); - OSFreeMem(psDevMemoryInfo->psDeviceMemoryHeap); -} - -static PVRSRV_ERROR RGXPhysMemDeviceHeapsInit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - PHYS_HEAP_CONFIG *psFwMainConfig = FindPhysHeapConfig(psDeviceNode->psDevConfig, - PHYS_HEAP_USAGE_FW_MAIN); - -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1) - /* VZ heap validation */ - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - PVR_LOG_RETURN_IF_FALSE(psFwMainConfig != NULL, - "FW Main heap is required for VZ Guest.", - PVRSRV_ERROR_PHYSHEAP_CONFIG); - } -#endif - - if (psFwMainConfig != NULL) - { - /* Check FW_MAIN for multiple usage flags. Because FW_MAIN is divided - into subheaps, shared usage with other heaps is not allowed. */ - PVR_LOG_RETURN_IF_FALSE(psFwMainConfig->ui32UsageFlags == PHYS_HEAP_USAGE_FW_MAIN, - "FW Main phys heap config specified with more than one usage. FW Main must be FW Main only.", - PVRSRV_ERROR_PHYSHEAP_CONFIG); - } - - if (psFwMainConfig == NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware physical heap not set", __func__)); - } - else if (psFwMainConfig->eType == PHYS_HEAP_TYPE_UMA) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware physical heap uses OS System memory (UMA)", __func__)); - } - else /* PHYS_HEAP_TYPE_LMA or PHYS_HEAP_TYPE_DMA */ - { - IMG_UINT64 uFwMainSubHeapSize; - PHYS_HEAP_CONFIG sFwHeapConfig; - - /* MIPS Firmware must reserve some space in its Host/Native heap for GPU memory mappings */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && (!PVRSRV_VZ_MODE_IS(GUEST))) - { -#if defined(FIX_HW_BRN_65101_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 65101)) - { - uFwMainSubHeapSize = RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_BRN65101; - } - else -#endif - { - uFwMainSubHeapSize = RGX_FIRMWARE_HOST_MIPS_MAIN_HEAP_SIZE_NORMAL; - } - } - else - { - uFwMainSubHeapSize = RGX_FIRMWARE_DEFAULT_MAIN_HEAP_SIZE; - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware physical heap uses local memory managed by the driver (LMA)", __func__)); - - PVR_LOG_GOTO_IF_FALSE(psFwMainConfig->uiSize >= RGX_FIRMWARE_RAW_HEAP_SIZE, - "Invalid firmware physical heap size.", ErrorDeinit); - - /* Now we construct RAs to manage the FW heaps */ - -#if defined(SUPPORT_AUTOVZ) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - /* 1 Mb can hold the maximum amount of page tables for the memory shared between the firmware and all KM drivers: - * MAX(RAW_HEAP_SIZE) = 32 Mb; MAX(NUMBER_OS) = 8; Total shared memory = 256 Mb; - * MMU objects required: 65536 PTEs; 16 PDEs; 1 PCE; */ - IMG_UINT64 uMaxFwMmuPageTableSize = 1 * 1024 * 1024; - - sFwHeapConfig = *psFwMainConfig; - - /* By default the firmware MMU's page tables are allocated from the same carveout memory as the firmware heap. - * If a different base address is specified for this reserved range, use the overriding define instead. */ -#if defined(PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR) - sFwHeapConfig.sStartAddr.uiAddr = PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR; - sFwHeapConfig.sCardBase.uiAddr = PVR_AUTOVZ_OVERRIDE_FW_MMU_CARVEOUT_BASE_ADDR; -#else - sFwHeapConfig.sStartAddr.uiAddr += RGX_FIRMWARE_RAW_HEAP_SIZE * RGX_NUM_OS_SUPPORTED; - sFwHeapConfig.sCardBase.uiAddr += RGX_FIRMWARE_RAW_HEAP_SIZE * RGX_NUM_OS_SUPPORTED; -#endif - - sFwHeapConfig.uiSize = uMaxFwMmuPageTableSize; - sFwHeapConfig.ui32UsageFlags = 0; - - eError = PhysmemCreateHeapLMA(psDeviceNode, &sFwHeapConfig, "Fw MMU subheap", - &psDeviceNode->psFwMMUReservedPhysHeap); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysmemCreateHeapLMA:MMU", ErrorDeinit); - } -#endif - - /* Subheap layout: Main + (optional MIPS reserved range) + Config */ - sFwHeapConfig = *psFwMainConfig; - sFwHeapConfig.uiSize = uFwMainSubHeapSize; - sFwHeapConfig.ui32UsageFlags = PHYS_HEAP_USAGE_FW_MAIN; - - eError = PhysmemCreateHeapLMA(psDeviceNode, &sFwHeapConfig, "Fw Main subheap", &psDeviceNode->psFWMainPhysHeap); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysmemCreateHeapLMA:MAIN", ErrorDeinit); - - sFwHeapConfig = *psFwMainConfig; - sFwHeapConfig.sStartAddr.uiAddr += RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE; - sFwHeapConfig.sCardBase.uiAddr += RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE; - sFwHeapConfig.uiSize = RGX_FIRMWARE_CONFIG_HEAP_SIZE; - sFwHeapConfig.ui32UsageFlags = PHYS_HEAP_USAGE_FW_CONFIG; - - eError = PhysmemCreateHeapLMA(psDeviceNode, &sFwHeapConfig, "Fw Cfg subheap", &psDeviceNode->psFWCfgPhysHeap); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysmemCreateHeapLMA:CFG", ErrorDeinit); - } - - /* Acquire FW heaps */ - eError = PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP_FW_MAIN, psDeviceNode, - &psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquire:FW_MAIN", ErrorDeinit); - - eError = PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP_FW_CONFIG, psDeviceNode, - &psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_CONFIG]); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquire:FW_CONFIG", ErrorDeinit); - - eError = PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP_FW_CODE, psDeviceNode, - &psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_CODE]); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquire:FW_CODE", ErrorDeinit); - - eError = PhysHeapAcquireByDevPhysHeap(PVRSRV_PHYS_HEAP_FW_PRIV_DATA, psDeviceNode, - &psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_PRIV_DATA]); - PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapAcquire:FW_DATA", ErrorDeinit); - - return eError; - -ErrorDeinit: - PVR_ASSERT(IMG_FALSE); - PVRSRVPhysMemHeapsDeinit(psDeviceNode); - - return eError; -} - -static void _ReadNon4KHeapPageSize(IMG_UINT32 *pui32Log2Non4KPgSize) -{ - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault = PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE; - IMG_UINT32 ui32GeneralNon4KHeapPageSize; - - /* Get the page size for the dummy page from the NON4K heap apphint */ - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, - GeneralNon4KHeapPageSize, &ui32AppHintDefault, - &ui32GeneralNon4KHeapPageSize); - *pui32Log2Non4KPgSize = ExactLog2(ui32GeneralNon4KHeapPageSize); - OSFreeKMAppHintState(pvAppHintState); -} - -/* RGXRegisterDevice - * - * NOTE: No PDUMP statements are allowed in until Part 2 of the device initialisation - * is reached. - */ -PVRSRV_ERROR RGXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - PVRSRV_RGXDEV_INFO *psDevInfo; - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault = HWPERF_HOST_TL_STREAM_SIZE_DEFAULT, ui32HWPerfHostBufSizeKB; - - ui32AppHintDefault = PVRSRV_APPHINT_DRIVERMODE; - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, HWPerfHostBufSizeInKB, - &ui32AppHintDefault, &ui32HWPerfHostBufSizeKB); - OSFreeKMAppHintState(pvAppHintState); - pvAppHintState = NULL; - - /********************* - * Device node setup * - *********************/ - /* Setup static data and callbacks on the device agnostic device node */ -#if defined(PDUMP) - psDeviceNode->sDevId.pszPDumpRegName = RGX_PDUMPREG_NAME; - psDeviceNode->sDevId.pszPDumpDevName = PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_GPU_LOCAL]); - psDeviceNode->pfnPDumpInitDevice = &RGXResetPDump; -#endif /* PDUMP */ - - OSAtomicWrite(&psDeviceNode->eHealthStatus, PVRSRV_DEVICE_HEALTH_STATUS_OK); - OSAtomicWrite(&psDeviceNode->eHealthReason, PVRSRV_DEVICE_HEALTH_REASON_NONE); - - /* Configure MMU specific stuff */ - RGXMMUInit_Register(psDeviceNode); - - psDeviceNode->pfnDevSLCFlushRange = NULL; - psDeviceNode->pfnInvalFBSCTable = NULL; - - psDeviceNode->pfnValidateOrTweakPhysAddrs = NULL; - - psDeviceNode->pfnMMUCacheInvalidate = RGXMMUCacheInvalidate; - - psDeviceNode->pfnMMUCacheInvalidateKick = RGXMMUCacheInvalidateKick; - - psDeviceNode->pfnInitDeviceCompatCheck = &RGXDevInitCompatCheck; - - /* Register callbacks for creation of device memory contexts */ - psDeviceNode->pfnRegisterMemoryContext = RGXRegisterMemoryContext; - psDeviceNode->pfnUnregisterMemoryContext = RGXUnregisterMemoryContext; - - /* Register callbacks for Unified Fence Objects */ - psDeviceNode->pfnAllocUFOBlock = RGXAllocUFOBlock; - psDeviceNode->pfnFreeUFOBlock = RGXFreeUFOBlock; - - /* Register callback for checking the device's health */ - psDeviceNode->pfnUpdateHealthStatus = PVRSRV_VZ_MODE_IS(GUEST) ? NULL : RGXUpdateHealthStatus; - -#if defined(SUPPORT_AUTOVZ) - /* Register callback for updating the virtualization watchdog */ - psDeviceNode->pfnUpdateAutoVzWatchdog = RGXUpdateAutoVzWatchdog; -#endif - - /* Register method to service the FW HWPerf buffer */ - psDeviceNode->pfnServiceHWPerf = RGXHWPerfDataStoreCB; - - /* Register callback for getting the device version information string */ - psDeviceNode->pfnDeviceVersionString = RGXDevVersionString; - - /* Register callback for getting the device clock speed */ - psDeviceNode->pfnDeviceClockSpeed = RGXDevClockSpeed; - - /* Register callback for soft resetting some device modules */ - psDeviceNode->pfnSoftReset = RGXSoftReset; - - /* Register callback for resetting the HWR logs */ - psDeviceNode->pfnResetHWRLogs = RGXResetHWRLogs; - - /* Register callback for resetting the HWR logs */ - psDeviceNode->pfnVerifyBVNC = RGXVerifyBVNC; - - /* Register callback for checking alignment of UM structures */ - psDeviceNode->pfnAlignmentCheck = RGXAlignmentCheck; - - /*Register callback for checking the supported features and getting the - * corresponding values */ - psDeviceNode->pfnCheckDeviceFeature = RGXBvncCheckFeatureSupported; - psDeviceNode->pfnGetDeviceFeatureValue = RGXBvncGetSupportedFeatureValue; - - /* Callback for checking if system layer supports FBC 3.1 */ - psDeviceNode->pfnHasFBCDCVersion31 = RGXSystemHasFBCDCVersion31; - - /* Callback for getting the MMU device attributes */ - psDeviceNode->pfnGetMMUDeviceAttributes = RGXDevMMUAttributes; - - /* Register callback for initialising device-specific physical memory heaps */ - psDeviceNode->pfnPhysMemDeviceHeapsInit = RGXPhysMemDeviceHeapsInit; - - /* Set up required support for dummy page */ - OSAtomicWrite(&(psDeviceNode->sDummyPage.atRefCounter), 0); - OSAtomicWrite(&(psDeviceNode->sDevZeroPage.atRefCounter), 0); - - /* Set the order to 0 */ - psDeviceNode->sDummyPage.sPageHandle.uiOrder = 0; - psDeviceNode->sDevZeroPage.sPageHandle.uiOrder = 0; - - /* Set the size of the Dummy page to zero */ - psDeviceNode->sDummyPage.ui32Log2PgSize = 0; - - /* Set the size of the Zero page to zero */ - psDeviceNode->sDevZeroPage.ui32Log2PgSize = 0; - - /* Set the Dummy page phys addr */ - psDeviceNode->sDummyPage.ui64PgPhysAddr = MMU_BAD_PHYS_ADDR; - - /* Set the Zero page phys addr */ - psDeviceNode->sDevZeroPage.ui64PgPhysAddr = MMU_BAD_PHYS_ADDR; - - /* The lock can be acquired from MISR (Z-buffer) path */ - eError = OSLockCreate(&psDeviceNode->sDummyPage.psPgLock); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create dummy page lock", __func__)); - return eError; - } - - /* Create the lock for zero page */ - eError = OSLockCreate(&psDeviceNode->sDevZeroPage.psPgLock); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create Zero page lock", __func__)); - goto free_dummy_page; - } -#if defined(PDUMP) - psDeviceNode->sDummyPage.hPdumpPg = NULL; - psDeviceNode->sDevZeroPage.hPdumpPg = NULL; -#endif - - /********************* - * Device info setup * - *********************/ - /* Allocate device control block */ - psDevInfo = OSAllocZMem(sizeof(*psDevInfo)); - if (psDevInfo == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "DevInitRGXPart1 : Failed to alloc memory for DevInfo")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - /* Default psTrampoline to point to null struct */ - psDevInfo->psTrampoline = (RGX_MIPS_ADDRESS_TRAMPOLINE *)&sNullTrampoline; - - /* create locks for the context lists stored in the DevInfo structure. - * these lists are modified on context create/destroy and read by the - * watchdog thread - */ - - eError = OSWRLockCreate(&(psDevInfo->hRenderCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create render context list lock", __func__)); - goto e0; - } - - eError = OSWRLockCreate(&(psDevInfo->hComputeCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create compute context list lock", __func__)); - goto e1; - } - - eError = OSWRLockCreate(&(psDevInfo->hTransferCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create transfer context list lock", __func__)); - goto e2; - } - - eError = OSWRLockCreate(&(psDevInfo->hTDMCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create TDM context list lock", __func__)); - goto e3; - } - - eError = OSWRLockCreate(&(psDevInfo->hKickSyncCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create kick sync context list lock", __func__)); - goto e4; - } - - eError = OSWRLockCreate(&(psDevInfo->hMemoryCtxListLock)); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create memory context list lock", __func__)); - goto e5; - } - - eError = OSSpinLockCreate(&psDevInfo->hLockKCCBDeferredCommandsList); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to KCCB deferred commands list lock", __func__)); - goto e6; - } - dllist_init(&(psDevInfo->sKCCBDeferredCommandsListHead)); - - dllist_init(&(psDevInfo->sRenderCtxtListHead)); - dllist_init(&(psDevInfo->sComputeCtxtListHead)); - dllist_init(&(psDevInfo->sTransferCtxtListHead)); - dllist_init(&(psDevInfo->sTDMCtxtListHead)); - dllist_init(&(psDevInfo->sKickSyncCtxtListHead)); - - dllist_init(&(psDevInfo->sCommonCtxtListHead)); - psDevInfo->ui32CommonCtxtCurrentID = 1; - - - eError = OSWRLockCreate(&psDevInfo->hCommonCtxtListLock); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create common context list lock", __func__)); - goto e7; - } - - eError = OSLockCreate(&psDevInfo->sRegCongfig.hLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create register configuration lock", __func__)); - goto e8; - } - - eError = OSLockCreate(&psDevInfo->hBPLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock for break points", __func__)); - goto e9; - } - - eError = OSLockCreate(&psDevInfo->hRGXFWIfBufInitLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock for trace buffers", __func__)); - goto e10; - } - - eError = OSLockCreate(&psDevInfo->hCCBStallCheckLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create stalled CCB checking lock", __func__)); - goto e11; - } - eError = OSLockCreate(&psDevInfo->hCCBRecoveryLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create stalled CCB recovery lock", __func__)); - goto e12; - } - - dllist_init(&psDevInfo->sMemoryContextList); - - /* initialise ui32SLRHoldoffCounter */ - if (RGX_INITIAL_SLR_HOLDOFF_PERIOD_MS > DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT) - { - psDevInfo->ui32SLRHoldoffCounter = RGX_INITIAL_SLR_HOLDOFF_PERIOD_MS / DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT; - } - else - { - psDevInfo->ui32SLRHoldoffCounter = 0; - } - - /* Setup static data and callbacks on the device specific device info */ - psDevInfo->psDeviceNode = psDeviceNode; - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psDevInfo->pvDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; - - /* - * Map RGX Registers - */ - psDevInfo->ui32RegSize = psDeviceNode->psDevConfig->ui32RegsSize; - psDevInfo->sRegsPhysBase = psDeviceNode->psDevConfig->sRegsCpuPBase; - -#if !defined(NO_HARDWARE) - psDevInfo->pvRegsBaseKM = (void __iomem *) OSMapPhysToLin(psDeviceNode->psDevConfig->sRegsCpuPBase, - psDeviceNode->psDevConfig->ui32RegsSize, - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED); - - if (psDevInfo->pvRegsBaseKM == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to create RGX register mapping", - __func__)); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto e13; - } -#endif - - psDeviceNode->pvDevice = psDevInfo; - - eError = RGXBvncInitialiseConfiguration(psDeviceNode); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Unsupported HW device detected by driver", - __func__)); - goto e14; - } - - _ReadNon4KHeapPageSize(&psDevInfo->ui32Log2Non4KPgSize); - - /*Set the zero & dummy page sizes as needed for the heap with largest page size */ - psDeviceNode->sDevZeroPage.ui32Log2PgSize = psDevInfo->ui32Log2Non4KPgSize; - psDeviceNode->sDummyPage.ui32Log2PgSize = psDevInfo->ui32Log2Non4KPgSize; - - eError = RGXInitHeaps(psDevInfo, psDevMemoryInfo); - if (eError != PVRSRV_OK) - { - goto e14; - } - - eError = RGXHWPerfInit(psDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXHWPerfInit", e14); - - eError = RGXHWPerfHostInit(psDeviceNode->pvDevice, ui32HWPerfHostBufSizeKB); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXHWPerfHostInit", ErrorDeInitHWPerfFw); - -#if defined(SUPPORT_VALIDATION) - /* This completion will be signaled by the ISR when processing - * the answer CCB command carrying an RGX Register read value */ - init_completion(&psDevInfo->sFwRegs.sRegComp); - psDevInfo->sFwRegs.ui64RegVal = 0; - -#if defined(SUPPORT_SOC_TIMER) - { - IMG_BOOL ui32AppHintDefault = IMG_FALSE; - IMG_BOOL bInitSocTimer; - void *pvAppHintState = NULL; - - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintBOOL(APPHINT_NO_DEVICE, pvAppHintState, ValidateSOCUSCTimer, &ui32AppHintDefault, &bInitSocTimer); - OSFreeKMAppHintState(pvAppHintState); - - if (bInitSocTimer) - { - eError = RGXInitSOCUSCTimer(psDeviceNode); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXInitSOCUSCTimer", ErrorDeInitHWPerfHost); - } - } -#endif -#endif - - /* Register callback for dumping debug info */ - eError = RGXDebugInit(psDevInfo); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXDebugInit", ErrorDeInitHWPerfHost); - - /* Register callback for fw mmu init */ - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - psDeviceNode->pfnFwMMUInit = RGXMipsMMUInit_Register; - } - - /* The device shared-virtual-memory heap address-space size is stored here for faster - look-up without having to walk the device heap configuration structures during - client device connection (i.e. this size is relative to a zero-based offset) */ -#if defined(FIX_HW_BRN_65273_BIT_MASK) - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 65273)) - { - psDeviceNode->ui64GeneralSVMHeapTopVA = 0; - }else -#endif - { - psDeviceNode->ui64GeneralSVMHeapTopVA = RGX_GENERAL_SVM_HEAP_BASE + RGX_GENERAL_SVM_HEAP_SIZE; - } - - if (NULL != psDeviceNode->psDevConfig->pfnSysDevFeatureDepInit) - { - psDeviceNode->psDevConfig->pfnSysDevFeatureDepInit(psDeviceNode->psDevConfig, - psDevInfo->sDevFeatureCfg.ui64Features); - } - - psDeviceNode->bHasSystemDMA = psDeviceNode->psDevConfig->bHasDma; - - /* Initialise the device dependent bridges */ - eError = DeviceDepBridgeInit(psDevInfo); - PVR_LOG_IF_ERROR(eError, "DeviceDepBridgeInit"); - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) - eError = OSLockCreate(&psDevInfo->hCounterDumpingLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock for counter sampling.", __func__)); - goto ErrorDeInitDeviceDepBridge; - } -#endif - - /* Initialise error counters */ - memset(&psDevInfo->sErrorCounts, 0, sizeof(PVRSRV_RGXDEV_ERROR_COUNTS)); - - return PVRSRV_OK; - -#if defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) -ErrorDeInitDeviceDepBridge: - DeviceDepBridgeDeInit(psDevInfo); -#endif - -ErrorDeInitHWPerfHost: - RGXHWPerfHostDeInit(psDevInfo); - -ErrorDeInitHWPerfFw: - RGXHWPerfDeinit(psDevInfo); - -e14: -#if !defined(NO_HARDWARE) - OSUnMapPhysToLin((void __force *) psDevInfo->pvRegsBaseKM, - psDevInfo->ui32RegSize); - -e13: -#endif /* !NO_HARDWARE */ - OSLockDestroy(psDevInfo->hCCBRecoveryLock); -e12: - OSLockDestroy(psDevInfo->hCCBStallCheckLock); -e11: - OSLockDestroy(psDevInfo->hRGXFWIfBufInitLock); -e10: - OSLockDestroy(psDevInfo->hBPLock); -e9: - OSLockDestroy(psDevInfo->sRegCongfig.hLock); -e8: - OSWRLockDestroy(psDevInfo->hCommonCtxtListLock); -e7: - OSSpinLockDestroy(psDevInfo->hLockKCCBDeferredCommandsList); -e6: - OSWRLockDestroy(psDevInfo->hMemoryCtxListLock); -e5: - OSWRLockDestroy(psDevInfo->hKickSyncCtxListLock); -e4: - OSWRLockDestroy(psDevInfo->hTDMCtxListLock); -e3: - OSWRLockDestroy(psDevInfo->hTransferCtxListLock); -e2: - OSWRLockDestroy(psDevInfo->hComputeCtxListLock); -e1: - OSWRLockDestroy(psDevInfo->hRenderCtxListLock); -e0: - OSFreeMem(psDevInfo); - - /* Destroy the zero page lock created above */ - OSLockDestroy(psDeviceNode->sDevZeroPage.psPgLock); - -free_dummy_page: - /* Destroy the dummy page lock created above */ - OSLockDestroy(psDeviceNode->sDummyPage.psPgLock); - - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -IMG_PCHAR RGXDevBVNCString(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_PCHAR psz = psDevInfo->sDevFeatureCfg.pszBVNCString; - if (NULL == psz) - { - IMG_CHAR pszBVNCInfo[RGX_HWPERF_MAX_BVNC_LEN]; - size_t uiBVNCStringSize; - size_t uiStringLength; - - uiStringLength = OSSNPrintf(pszBVNCInfo, RGX_HWPERF_MAX_BVNC_LEN, "%d.%d.%d.%d", - psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); - PVR_ASSERT(uiStringLength < RGX_HWPERF_MAX_BVNC_LEN); - - uiBVNCStringSize = (uiStringLength + 1) * sizeof(IMG_CHAR); - psz = OSAllocMem(uiBVNCStringSize); - if (NULL != psz) - { - OSCachedMemCopy(psz, pszBVNCInfo, uiBVNCStringSize); - psDevInfo->sDevFeatureCfg.pszBVNCString = psz; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Allocating memory for BVNC Info string failed", - __func__)); - } - } - - return psz; -} - -/*************************************************************************/ /*! -@Function RGXDevVersionString -@Description Gets the version string for the given device node and returns - a pointer to it in ppszVersionString. It is then the - responsibility of the caller to free this memory. -@Input psDeviceNode Device node from which to obtain the - version string -@Output ppszVersionString Contains the version string upon return -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static PVRSRV_ERROR RGXDevVersionString(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR **ppszVersionString) -{ -#if defined(NO_HARDWARE) || defined(EMULATOR) - const IMG_CHAR szFormatString[] = "GPU variant BVNC: %s (SW)"; -#else - const IMG_CHAR szFormatString[] = "GPU variant BVNC: %s (HW)"; -#endif - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_PCHAR pszBVNC; - size_t uiStringLength; - - if (psDeviceNode == NULL || ppszVersionString == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - pszBVNC = RGXDevBVNCString(psDevInfo); - - if (NULL == pszBVNC) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - uiStringLength = OSStringLength(pszBVNC); - uiStringLength += (sizeof(szFormatString) - 2); /* sizeof includes the null, -2 for "%s" */ - *ppszVersionString = OSAllocMem(uiStringLength * sizeof(IMG_CHAR)); - if (*ppszVersionString == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - OSSNPrintf(*ppszVersionString, uiStringLength, szFormatString, - pszBVNC); - - return PVRSRV_OK; -} - -/**************************************************************************/ /*! -@Function RGXDevClockSpeed -@Description Gets the clock speed for the given device node and returns - it in pui32RGXClockSpeed. -@Input psDeviceNode Device node -@Output pui32RGXClockSpeed Variable for storing the clock speed -@Return PVRSRV_ERROR - */ /***************************************************************************/ -static PVRSRV_ERROR RGXDevClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_PUINT32 pui32RGXClockSpeed) -{ - RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData; - - /* get clock speed */ - *pui32RGXClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed; - - return PVRSRV_OK; -} - -#if (RGX_NUM_OS_SUPPORTED > 1) -/*! - ******************************************************************************* - - @Function RGXInitFwRawHeap - - @Description Called to perform additional initialisation - ******************************************************************************/ -static PVRSRV_ERROR RGXInitFwRawHeap(DEVMEM_HEAP_BLUEPRINT *psDevMemHeap, IMG_UINT32 ui32OSid) -{ - IMG_UINT32 uiStringLength; - IMG_UINT32 uiStringLengthMax = 32; - - IMG_UINT32 ui32Log2RgxDefaultPageShift = RGXHeapDerivePageSize(OSGetPageShift()); - - uiStringLength = MIN(sizeof(RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT), uiStringLengthMax + 1); - - /* Start by allocating memory for this OSID heap identification string */ - psDevMemHeap->pszName = OSAllocMem(uiStringLength * sizeof(IMG_CHAR)); - if (psDevMemHeap->pszName == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* Append the OSID number to the RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT string */ - OSSNPrintf((IMG_CHAR *)psDevMemHeap->pszName, uiStringLength, RGX_FIRMWARE_GUEST_RAW_HEAP_IDENT, ui32OSid); - - /* Use the common blueprint template support function to initialise the heap */ - HeapCfgBlueprintInit(psDevMemHeap->pszName, - RGX_FIRMWARE_RAW_HEAP_BASE + (ui32OSid * RGX_FIRMWARE_RAW_HEAP_SIZE), - RGX_FIRMWARE_RAW_HEAP_SIZE, - 0, - ui32Log2RgxDefaultPageShift, - 0, - psDevMemHeap); - - return PVRSRV_OK; -} - -/*! - ******************************************************************************* - - @Function RGXDeInitFwRawHeap - - @Description Called to perform additional deinitialisation - ******************************************************************************/ -static void RGXDeInitFwRawHeap(DEVMEM_HEAP_BLUEPRINT *psDevMemHeap) -{ - IMG_UINT64 uiBase = RGX_FIRMWARE_RAW_HEAP_BASE + RGX_FIRMWARE_RAW_HEAP_SIZE; - IMG_UINT64 uiSpan = uiBase + ((RGX_NUM_OS_SUPPORTED - 1) * RGX_FIRMWARE_RAW_HEAP_SIZE); - - /* Safe to do as the guest firmware heaps are last in the list */ - if (psDevMemHeap->sHeapBaseAddr.uiAddr >= uiBase && - psDevMemHeap->sHeapBaseAddr.uiAddr < uiSpan) - { - void *pszName = (void*)psDevMemHeap->pszName; - OSFreeMem(pszName); - } -} -#endif /* (RGX_NUM_OS_SUPPORTED > 1) */ - -/****************************************************************************** - End of file (rgxinit.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxinit.h b/drivers/gpu/drm/img-rogue/1.17/rgxinit.h deleted file mode 100644 index 6cc8c8b1c256c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxinit.h +++ /dev/null @@ -1,281 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX initialisation header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX initialisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXINIT_H) -#define RGXINIT_H - -#include "connection_server.h" -#include "pvrsrv_error.h" -#include "img_types.h" -#include "device.h" -#include "rgxdevice.h" -#include "rgx_bridge.h" -#include "fwload.h" - -#if defined(__linux__) -#define OS_FW_VERIFY_FUNCTION OSVerifyFirmware -#else -#define OS_FW_VERIFY_FUNCTION NULL -#endif - -/*! -******************************************************************************* - - @Function RGXInitDevPart2 - - @Description - - Second part of server-side RGX initialisation - - @Input psDeviceNode - device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXInitDevPart2 (PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32DeviceFlags, - IMG_UINT32 ui32HWPerfHostFilter, - RGX_ACTIVEPM_CONF eActivePMConf); - -PVRSRV_ERROR RGXInitAllocFWImgMem(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEVMEM_SIZE_T ui32FWCodeLen, - IMG_DEVMEM_SIZE_T ui32FWDataLen, - IMG_DEVMEM_SIZE_T uiFWCorememCodeLen, - IMG_DEVMEM_SIZE_T uiFWCorememDataLen); - - -/*! -******************************************************************************* - - @Function RGXInitFirmware - - @Description - - Server-side RGX firmware initialisation - - @Input psDeviceNode - device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR -RGXInitFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_BOOL bEnableSignatureChecks, - IMG_UINT32 ui32SignatureChecksBufSize, - IMG_UINT32 ui32HWPerfFWBufSizeKB, - IMG_UINT64 ui64HWPerfFilter, - IMG_UINT32 ui32ConfigFlags, - IMG_UINT32 ui32LogType, - IMG_UINT32 ui32FilterFlags, - IMG_UINT32 ui32JonesDisableMask, - IMG_UINT32 ui32HWRDebugDumpLimit, - IMG_UINT32 ui32HWPerfCountersDataSize, - IMG_UINT32 *pui32TPUTrilinearFracMask, - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandingConf, - FW_PERF_CONF eFirmwarePerf, - IMG_UINT32 ui32KCCBSizeLog2, - IMG_UINT32 ui32ConfigFlagsExt, - IMG_UINT32 ui32FwOsCfgFlags); - - -/*! -******************************************************************************* - - @Function RGXLoadAndGetFWData - - @Description - - Load FW and return pointer to FW data. - - @Input psDeviceNode - device node - - @Input ppsRGXFW - fw pointer - - @Output ppbFWData - pointer to FW data (NULL if an error occurred) - - @Return PVRSRV_ERROR - PVRSRV_OK on success - PVRSRV_ERROR_NOT_READY if filesystem is not ready - PVRSRV_ERROR_NOT_FOUND if no suitable FW image found - PVRSRV_ERROR_OUT_OF_MEMORY if unable to alloc memory for FW image - PVRSRV_ERROR_NOT_AUTHENTICATED if FW image failed verification - -******************************************************************************/ -PVRSRV_ERROR RGXLoadAndGetFWData(PVRSRV_DEVICE_NODE *psDeviceNode, - OS_FW_IMAGE **ppsRGXFW, - const IMG_BYTE **ppbFWData); - -#if defined(PDUMP) -/*! -******************************************************************************* - - @Function RGXInitHWPerfCounters - - @Description - - Initialisation of the performance counters - - @Input psDeviceNode - device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXInitHWPerfCounters(PVRSRV_DEVICE_NODE *psDeviceNode); -#endif - -/*! -******************************************************************************* - - @Function RGXRegisterDevice - - @Description - - Registers the device with the system - - @Input: psDeviceNode - device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -******************************************************************************* - - @Function RGXDevBVNCString - - @Description - - Returns the Device BVNC string. It will allocate and fill it first, if necessary. - - @Input: psDevInfo - device info (must not be null) - - @Return IMG_PCHAR - pointer to BVNC string - -******************************************************************************/ -IMG_PCHAR RGXDevBVNCString(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* - - @Function DevDeInitRGX - - @Description - - Reset and deinitialise Chip - - @Input psDeviceNode - device info. structure - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR DevDeInitRGX(PVRSRV_DEVICE_NODE *psDeviceNode); - - -#if !defined(NO_HARDWARE) - -void RGX_WaitForInterruptsTimeout(PVRSRV_RGXDEV_INFO *psDevInfo); - -/*! -******************************************************************************* - - @Function SORgxGpuUtilStatsRegister - - @Description SO Interface function called from the OS layer implementation. - Initialise data used to compute GPU utilisation statistics - for a particular user (identified by the handle passed as - argument). This function must be called only once for each - different user/handle. - - @Input phGpuUtilUser - Pointer to handle used to identify a user of - RGXGetGpuUtilStats - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR SORgxGpuUtilStatsRegister(IMG_HANDLE *phGpuUtilUser); - - -/*! -******************************************************************************* - - @Function SORgxGpuUtilStatsUnregister - - @Description SO Interface function called from the OS layer implementation. - Free data previously used to compute GPU utilisation statistics - for a particular user (identified by the handle passed as - argument). - - @Input hGpuUtilUser - Handle used to identify a user of - RGXGetGpuUtilStats - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR SORgxGpuUtilStatsUnregister(IMG_HANDLE hGpuUtilUser); -#endif /* !defined(NO_HARDWARE) */ - -/*! - ******************************************************************************* - - @Function RGXInitCreateFWKernelMemoryContext - - @Description Called to perform initialisation during firmware kernel context - creation. - - @Input psDeviceNode device node - ******************************************************************************/ -PVRSRV_ERROR RGXInitCreateFWKernelMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! - ******************************************************************************* - - @Function RGXDeInitDestroyFWKernelMemoryContext - - @Description Called to perform deinitialisation during firmware kernel - context destruction. - - @Input psDeviceNode device node - ******************************************************************************/ -void RGXDeInitDestroyFWKernelMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* RGXINIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.c b/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.c deleted file mode 100644 index 73f1b783f4d27..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.c +++ /dev/null @@ -1,794 +0,0 @@ -/*************************************************************************/ /*! -@File rgxkicksync.c -@Title Server side of the sync only kick API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgxkicksync.h" - -#include "rgxdevice.h" -#include "rgxmem.h" -#include "rgxfwutils.h" -#include "allocmem.h" -#include "sync.h" -#include "rgxhwperf.h" -#include "ospvr_gputrace.h" - -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" - -/* Enable this to dump the compiled list of UFOs prior to kick call */ -#define ENABLE_KICKSYNC_UFO_DUMP 0 - -//#define KICKSYNC_CHECKPOINT_DEBUG 1 - -#if defined(KICKSYNC_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -#else -#define CHKPT_DBG(X) -#endif - -struct _RGX_SERVER_KICKSYNC_CONTEXT_ -{ - PVRSRV_DEVICE_NODE * psDeviceNode; - RGX_SERVER_COMMON_CONTEXT * psServerCommonContext; - DLLIST_NODE sListNode; - SYNC_ADDR_LIST sSyncAddrListFence; - SYNC_ADDR_LIST sSyncAddrListUpdate; - POS_LOCK hLock; -}; - - -PVRSRV_ERROR PVRSRVRGXCreateKickSyncContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - RGX_SERVER_KICKSYNC_CONTEXT **ppsKickSyncContext) -{ - PVRSRV_RGXDEV_INFO * psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC * psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - RGX_SERVER_KICKSYNC_CONTEXT * psKickSyncContext; - RGX_COMMON_CONTEXT_INFO sInfo; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CCBAllocSizeLog2, ui32CCBMaxAllocSizeLog2; - - memset(&sInfo, 0, sizeof(sInfo)); - - /* Prepare cleanup struct */ - * ppsKickSyncContext = NULL; - psKickSyncContext = OSAllocZMem(sizeof(*psKickSyncContext)); - if (psKickSyncContext == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eError = OSLockCreate(&psKickSyncContext->hLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto err_lockcreate; - } - - psKickSyncContext->psDeviceNode = psDeviceNode; - - ui32CCBAllocSizeLog2 = U32toU8_Unpack1(ui32PackedCCBSizeU88); - ui32CCBMaxAllocSizeLog2 = U32toU8_Unpack2(ui32PackedCCBSizeU88); - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_KICKSYNC, - RGXFWIF_DM_GP, - hMemCtxPrivData, - NULL, - 0, - psFWMemContextMemDesc, - NULL, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_KICKSYNC_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_KICKSYNC_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - 0, /* priority */ - 0, /* max deadline MS */ - 0, /* robustness address */ - & sInfo, - & psKickSyncContext->psServerCommonContext); - if (eError != PVRSRV_OK) - { - goto fail_contextalloc; - } - - OSWRLockAcquireWrite(psDevInfo->hKickSyncCtxListLock); - dllist_add_to_tail(&(psDevInfo->sKickSyncCtxtListHead), &(psKickSyncContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hKickSyncCtxListLock); - - SyncAddrListInit(&psKickSyncContext->sSyncAddrListFence); - SyncAddrListInit(&psKickSyncContext->sSyncAddrListUpdate); - - * ppsKickSyncContext = psKickSyncContext; - return PVRSRV_OK; - -fail_contextalloc: - OSLockDestroy(psKickSyncContext->hLock); -err_lockcreate: - OSFreeMem(psKickSyncContext); - return eError; -} - - -PVRSRV_ERROR PVRSRVRGXDestroyKickSyncContextKM(RGX_SERVER_KICKSYNC_CONTEXT * psKickSyncContext) -{ - PVRSRV_RGXDEV_INFO * psDevInfo = psKickSyncContext->psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psKickSyncContext->psDeviceNode, - psKickSyncContext->psServerCommonContext, - RGXFWIF_DM_GP, - PDUMP_FLAGS_NONE); - - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free its resources */ - - OSWRLockAcquireWrite(psDevInfo->hKickSyncCtxListLock); - dllist_remove_node(&(psKickSyncContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hKickSyncCtxListLock); - - FWCommonContextFree(psKickSyncContext->psServerCommonContext); - - SyncAddrListDeinit(&psKickSyncContext->sSyncAddrListFence); - SyncAddrListDeinit(&psKickSyncContext->sSyncAddrListUpdate); - - OSLockDestroy(psKickSyncContext->hLock); - - OSFreeMem(psKickSyncContext); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVRGXSetKickSyncContextPropertyKM(RGX_SERVER_KICKSYNC_CONTEXT *psKickSyncContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (eContextProperty) - { - case RGX_CONTEXT_PROPERTY_FLAGS: - { - IMG_UINT32 ui32ContextFlags = (IMG_UINT32)ui64Input; - - OSLockAcquire(psKickSyncContext->hLock); - eError = FWCommonContextSetFlags(psKickSyncContext->psServerCommonContext, - ui32ContextFlags); - - OSLockRelease(psKickSyncContext->hLock); - break; - } - - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_ERROR_NOT_SUPPORTED - asked to set unknown property (%d)", __func__, eContextProperty)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - } - - return eError; -} - -void DumpKickSyncCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - DLLIST_NODE *psNode, *psNext; - OSWRLockAcquireRead(psDevInfo->hKickSyncCtxListLock); - dllist_foreach_node(&psDevInfo->sKickSyncCtxtListHead, psNode, psNext) - { - RGX_SERVER_KICKSYNC_CONTEXT *psCurrentServerKickSyncCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_KICKSYNC_CONTEXT, sListNode); - - if (NULL != psCurrentServerKickSyncCtx->psServerCommonContext) - { - DumpFWCommonContextInfo(psCurrentServerKickSyncCtx->psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - } - OSWRLockReleaseRead(psDevInfo->hKickSyncCtxListLock); -} - -IMG_UINT32 CheckForStalledClientKickSyncCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - DLLIST_NODE *psNode, *psNext; - IMG_UINT32 ui32ContextBitMask = 0; - - OSWRLockAcquireRead(psDevInfo->hKickSyncCtxListLock); - - dllist_foreach_node(&psDevInfo->sKickSyncCtxtListHead, psNode, psNext) - { - RGX_SERVER_KICKSYNC_CONTEXT *psCurrentServerKickSyncCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_KICKSYNC_CONTEXT, sListNode); - - if (NULL != psCurrentServerKickSyncCtx->psServerCommonContext) - { - if (CheckStalledClientCommonContext(psCurrentServerKickSyncCtx->psServerCommonContext, RGX_KICK_TYPE_DM_GP) == PVRSRV_ERROR_CCCB_STALLED) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_GP; - } - } - } - - OSWRLockReleaseRead(psDevInfo->hKickSyncCtxListLock); - return ui32ContextBitMask; -} - -PVRSRV_ERROR PVRSRVRGXKickSyncKM(RGX_SERVER_KICKSYNC_CONTEXT * psKickSyncContext, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ** pauiClientUpdateUFODevVarBlock, - IMG_UINT32 * paui32ClientUpdateOffset, - IMG_UINT32 * paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE * piUpdateFence, - IMG_CHAR szUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32ExtJobRef) -{ - RGXFWIF_KCCB_CMD sKickSyncKCCBCmd; - RGX_CCB_CMD_HELPER_DATA asCmdHelperData[1]; - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - IMG_BOOL bCCBStateOpen = IMG_FALSE; - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress = NULL; - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress = NULL; - IMG_UINT32 ui32ClientFenceCount = 0; - IMG_UINT32 *paui32ClientFenceValue = NULL; - PVRSRV_FENCE iUpdateFence = PVRSRV_NO_FENCE; - IMG_UINT32 ui32FWCtx = FWCommonContextGetFWAddress(psKickSyncContext->psServerCommonContext).ui32Addr; - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psKickSyncContext->psServerCommonContext); - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psKickSyncContext->psServerCommonContext); - IMG_UINT32 ui32IntJobRef = OSAtomicIncrement(&psDevInfo->iCCBSubmissionOrdinal); - IMG_UINT64 uiCheckFenceUID = 0; - IMG_UINT64 uiUpdateFenceUID = 0; - PSYNC_CHECKPOINT psUpdateSyncCheckpoint = NULL; - PSYNC_CHECKPOINT *apsFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32FenceSyncCheckpointCount = 0; - IMG_UINT32 ui32FenceTimelineUpdateValue = 0; - IMG_UINT32 *pui32IntAllocatedUpdateValues = NULL; - PVRSRV_CLIENT_SYNC_PRIM *psFenceTimelineUpdateSync = NULL; - void *pvUpdateFenceFinaliseData = NULL; - - /* Ensure we haven't been given a null ptr to - * update values if we have been told we - * have dev var updates - */ - if (ui32ClientUpdateCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32ClientUpdateValue != NULL, - "paui32ClientUpdateValue NULL but ui32ClientUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - - OSLockAcquire(psKickSyncContext->hLock); - eError = SyncAddrListPopulate(&psKickSyncContext->sSyncAddrListUpdate, - ui32ClientUpdateCount, - pauiClientUpdateUFODevVarBlock, - paui32ClientUpdateOffset); - - if (eError != PVRSRV_OK) - { - goto fail_syncaddrlist; - } - - if (ui32ClientUpdateCount > 0) - { - pauiClientUpdateUFOAddress = psKickSyncContext->sSyncAddrListUpdate.pasFWAddrs; - } - /* Ensure the string is null-terminated (Required for safety) */ - szUpdateFenceName[31] = '\0'; - - /* This will never be true if called from the bridge since piUpdateFence will always be valid */ - if (iUpdateTimeline >= 0 && !piUpdateFence) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto out_unlock; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling SyncCheckpointResolveFence (iCheckFence=%d), " - "psKickSyncContext->psDeviceNode->hSyncCheckpointContext=<%p>...", - __func__, iCheckFence, - (void*)psKickSyncContext->psDeviceNode->hSyncCheckpointContext)); - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence(psKickSyncContext->psDeviceNode->hSyncCheckpointContext, - iCheckFence, - &ui32FenceSyncCheckpointCount, - &apsFenceSyncCheckpoints, - &uiCheckFenceUID, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_OK) - { - goto fail_resolve_fence; - } - - /* Create the output fence (if required) */ - if (iUpdateTimeline != PVRSRV_NO_TIMELINE) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling SyncCheckpointCreateFence (iUpdateTimeline=%d)...", - __func__, iUpdateTimeline)); - eError = SyncCheckpointCreateFence(psKickSyncContext->psDeviceNode, - szUpdateFenceName, - iUpdateTimeline, - psKickSyncContext->psDeviceNode->hSyncCheckpointContext, - &iUpdateFence, - &uiUpdateFenceUID, - &pvUpdateFenceFinaliseData, - &psUpdateSyncCheckpoint, - (void*)&psFenceTimelineUpdateSync, - &ui32FenceTimelineUpdateValue, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_OK) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...returned error (%d)", - __func__, eError)); - goto fail_create_output_fence; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: ...returned from SyncCheckpointCreateFence " - "(iUpdateFence=%d, psFenceTimelineUpdateSync=<%p>, " - "ui32FenceTimelineUpdateValue=%u)", - __func__, iUpdateFence, psFenceTimelineUpdateSync, - ui32FenceTimelineUpdateValue)); - - /* Append the sync prim update for the timeline (if required) */ - if (psFenceTimelineUpdateSync) - { - IMG_UINT32 *pui32TimelineUpdateWp = NULL; - - /* Allocate memory to hold the list of update values (including our timeline update) */ - pui32IntAllocatedUpdateValues = OSAllocMem(sizeof(*paui32ClientUpdateValue) * (ui32ClientUpdateCount+1)); - if (!pui32IntAllocatedUpdateValues) - { - /* Failed to allocate memory */ - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc_update_values_mem; - } - OSCachedMemSet(pui32IntAllocatedUpdateValues, 0xbb, sizeof(*pui32IntAllocatedUpdateValues) * (ui32ClientUpdateCount+1)); - /* Copy the update values into the new memory, then append our timeline update value */ - OSCachedMemCopy(pui32IntAllocatedUpdateValues, paui32ClientUpdateValue, sizeof(*pui32IntAllocatedUpdateValues) * ui32ClientUpdateCount); - /* Now set the additional update value */ - pui32TimelineUpdateWp = pui32IntAllocatedUpdateValues + ui32ClientUpdateCount; - *pui32TimelineUpdateWp = ui32FenceTimelineUpdateValue; - ui32ClientUpdateCount++; - /* Now make sure paui32ClientUpdateValue points to pui32IntAllocatedUpdateValues */ - paui32ClientUpdateValue = pui32IntAllocatedUpdateValues; -#if defined(KICKSYNC_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", - __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Now append the timeline sync prim addr to the kicksync context update list */ - SyncAddrListAppendSyncPrim(&psKickSyncContext->sSyncAddrListUpdate, - psFenceTimelineUpdateSync); - } - } - - /* Reset number of fence syncs in kicksync context fence list to 0 */ - SyncAddrListPopulate(&psKickSyncContext->sSyncAddrListFence, - 0, NULL, NULL); - - if (ui32FenceSyncCheckpointCount > 0) - { - /* Append the checks (from input fence) */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append %d sync checkpoints to KickSync Fence " - "(&psKickSyncContext->sSyncAddrListFence=<%p>)...", - __func__, ui32FenceSyncCheckpointCount, - (void*)&psKickSyncContext->sSyncAddrListFence)); - SyncAddrListAppendCheckpoints(&psKickSyncContext->sSyncAddrListFence, - ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - if (!pauiClientFenceUFOAddress) - { - pauiClientFenceUFOAddress = psKickSyncContext->sSyncAddrListFence.pasFWAddrs; - } - ui32ClientFenceCount += ui32FenceSyncCheckpointCount; -#if defined(KICKSYNC_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiClientFenceUFOAddress; - - for (iii=0; iii) = 0x%x", - __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - - if (psUpdateSyncCheckpoint) - { - PVRSRV_ERROR eErr; - - /* Append the update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 sync checkpoint to KickSync Update " - "(&psKickSyncContext->sSyncAddrListUpdate=<%p>)...", - __func__, (void*)&psKickSyncContext->sSyncAddrListUpdate)); - eErr = SyncAddrListAppendCheckpoints(&psKickSyncContext->sSyncAddrListUpdate, - 1, - &psUpdateSyncCheckpoint); - if (eErr != PVRSRV_OK) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: ...done. SyncAddrListAppendCheckpoints() returned error (%d)", - __func__, eErr)); - } - else - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done.", __func__)); - } - if (!pauiClientUpdateUFOAddress) - { - pauiClientUpdateUFOAddress = psKickSyncContext->sSyncAddrListUpdate.pasFWAddrs; - } - ui32ClientUpdateCount++; -#if defined(KICKSYNC_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiClientUpdateUFOAddress; - - for (iii=0; iii) = 0x%x", - __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - -#if (ENABLE_KICKSYNC_UFO_DUMP == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: dumping KICKSYNC fence/updates syncs...", - __func__)); - { - IMG_UINT32 ii; - PRGXFWIF_UFO_ADDR *psTmpIntFenceUFOAddress = pauiClientFenceUFOAddress; - IMG_UINT32 *pui32TmpIntFenceValue = paui32ClientFenceValue; - PRGXFWIF_UFO_ADDR *psTmpIntUpdateUFOAddress = pauiClientUpdateUFOAddress; - IMG_UINT32 *pui32TmpIntUpdateValue = paui32ClientUpdateValue; - - /* Dump Fence syncs and Update syncs */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Prepared %d KickSync fence syncs " - "(&psKickSyncContext->sSyncAddrListFence=<%p>, " - "pauiClientFenceUFOAddress=<%p>):", - __func__, ui32ClientFenceCount, - (void*)&psKickSyncContext->sSyncAddrListFence, - (void*)pauiClientFenceUFOAddress)); - for (ii=0; iiui32Addr & 0x1) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, " - "CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, ii + 1, ui32ClientFenceCount, - (void*)psTmpIntFenceUFOAddress, - psTmpIntFenceUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, CheckValue=%d(0x%x)", - __func__, ii + 1, ui32ClientFenceCount, - (void*)psTmpIntFenceUFOAddress, - psTmpIntFenceUFOAddress->ui32Addr, - *pui32TmpIntFenceValue, - *pui32TmpIntFenceValue)); - pui32TmpIntFenceValue++; - } - psTmpIntFenceUFOAddress++; - } - PVR_DPF((PVR_DBG_ERROR, - "%s: Prepared %d KickSync update syncs " - "(&psKickSyncContext->sSyncAddrListUpdate=<%p>, " - "pauiClientUpdateUFOAddress=<%p>):", - __func__, ui32ClientUpdateCount, - (void*)&psKickSyncContext->sSyncAddrListUpdate, - (void*)pauiClientUpdateUFOAddress)); - for (ii=0; ii", - __func__, __LINE__, - (void*)psTmpIntUpdateUFOAddress)); - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Line %d, pui32TmpIntUpdateValue=<%p>", - __func__, __LINE__, - (void*)pui32TmpIntUpdateValue)); - if (psTmpIntUpdateUFOAddress->ui32Addr & 0x1) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, " - "UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, ii + 1, ui32ClientUpdateCount, - (void*)psTmpIntUpdateUFOAddress, - psTmpIntUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d", - __func__, ii + 1, ui32ClientUpdateCount, - (void*)psTmpIntUpdateUFOAddress, - psTmpIntUpdateUFOAddress->ui32Addr, - *pui32TmpIntUpdateValue)); - pui32TmpIntUpdateValue++; - } - psTmpIntUpdateUFOAddress++; - } - } -#endif - - RGXCmdHelperInitCmdCCB(psDevInfo, - psClientCCB, - 0, /* empty ui64FBSCEntryMask */ - ui32ClientFenceCount, - pauiClientFenceUFOAddress, - paui32ClientFenceValue, - ui32ClientUpdateCount, - pauiClientUpdateUFOAddress, - paui32ClientUpdateValue, - 0, - NULL, - NULL, - NULL, - NULL, - RGXFWIF_CCB_CMD_TYPE_NULL, - ui32ExtJobRef, - ui32IntJobRef, - PDUMP_FLAGS_NONE, - NULL, - "KickSync", - bCCBStateOpen, - asCmdHelperData); - - eError = RGXCmdHelperAcquireCmdCCB(ARRAY_SIZE(asCmdHelperData), asCmdHelperData); - if (eError != PVRSRV_OK) - { - goto fail_cmdaquire; - } - - /* - * We should reserve space in the kernel CCB here and fill in the command - * directly. - * This is so if there isn't space in the kernel CCB we can return with - * retry back to services client before we take any operations - */ - - /* - * We might only be kicking for flush out a padding packet so only submit - * the command if the create was successful - */ - if (eError == PVRSRV_OK) - { - /* - * All the required resources are ready at this point, we can't fail so - * take the required server sync operations and commit all the resources - */ - RGXCmdHelperReleaseCmdCCB(1, - asCmdHelperData, - "KickSync", - FWCommonContextGetFWAddress(psKickSyncContext->psServerCommonContext).ui32Addr); - } - - /* Construct the kernel kicksync CCB command. */ - sKickSyncKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - sKickSyncKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psKickSyncContext->psServerCommonContext); - sKickSyncKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - sKickSyncKCCBCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - - sKickSyncKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - sKickSyncKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0; - - /* - * Submit the kicksync command to the firmware. - */ - RGXSRV_HWPERF_ENQ(psKickSyncContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_SYNC, - iCheckFence, - iUpdateFence, - iUpdateTimeline, - uiCheckFenceUID, - uiUpdateFenceUID, - NO_DEADLINE, - NO_CYCEST); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psKickSyncContext->psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - & sKickSyncKCCBCmd, - PDUMP_FLAGS_NONE); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - PVRGpuTraceEnqueueEvent(psKickSyncContext->psDeviceNode->pvDevice, - ui32FWCtx, ui32ExtJobRef, ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_SYNC); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRGXKickSync failed to schedule kernel CCB command. (0x%x)", - eError)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - } - - /* - * Now check eError (which may have returned an error from our earlier call - * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first - * so we check it now... - */ - if (eError != PVRSRV_OK ) - { - goto fail_cmdaquire; - } - -#if defined(NO_HARDWARE) - /* If NO_HARDWARE, signal the output fence's sync checkpoint and sync prim */ - if (psUpdateSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Signalling NOHW sync checkpoint<%p>, ID:%d, FwAddr=0x%x", - __func__, (void*)psUpdateSyncCheckpoint, - SyncCheckpointGetId(psUpdateSyncCheckpoint), - SyncCheckpointGetFirmwareAddr(psUpdateSyncCheckpoint))); - SyncCheckpointSignalNoHW(psUpdateSyncCheckpoint); - } - if (psFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Updating NOHW sync prim<%p> to %d", - __func__, (void*)psFenceTimelineUpdateSync, - ui32FenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(psFenceTimelineUpdateSync, ui32FenceTimelineUpdateValue); - } - SyncCheckpointNoHWUpdateTimelines(NULL); -#endif - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - /* Free memory allocated to hold the internal list of update values */ - if (pui32IntAllocatedUpdateValues) - { - OSFreeMem(pui32IntAllocatedUpdateValues); - pui32IntAllocatedUpdateValues = NULL; - } - - *piUpdateFence = iUpdateFence; - if (pvUpdateFenceFinaliseData && (iUpdateFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psKickSyncContext->psDeviceNode, iUpdateFence, - pvUpdateFenceFinaliseData, - psUpdateSyncCheckpoint, szUpdateFenceName); - } - - OSLockRelease(psKickSyncContext->hLock); - return PVRSRV_OK; - -fail_cmdaquire: - SyncAddrListRollbackCheckpoints(psKickSyncContext->psDeviceNode, &psKickSyncContext->sSyncAddrListFence); - SyncAddrListRollbackCheckpoints(psKickSyncContext->psDeviceNode, &psKickSyncContext->sSyncAddrListUpdate); - if (iUpdateFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(iUpdateFence, pvUpdateFenceFinaliseData); - } - - /* Free memory allocated to hold update values */ - if (pui32IntAllocatedUpdateValues) - { - OSFreeMem(pui32IntAllocatedUpdateValues); - } -fail_alloc_update_values_mem: -fail_create_output_fence: - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free memory allocated to hold the resolved fence's checkpoints */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } -fail_resolve_fence: -fail_syncaddrlist: -out_unlock: - OSLockRelease(psKickSyncContext->hLock); - return eError; -} - -/**************************************************************************//** - End of file (rgxkicksync.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.h b/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.h deleted file mode 100644 index 57b49a03da5c4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxkicksync.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************/ /*! -@File rgxkicksync.h -@Title Server side of the sync only kick API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXKICKSYNC_H) -#define RGXKICKSYNC_H - -#include "pvrsrv_error.h" -#include "connection_server.h" -#include "sync_server.h" -#include "rgxdevice.h" - - -typedef struct _RGX_SERVER_KICKSYNC_CONTEXT_ RGX_SERVER_KICKSYNC_CONTEXT; - -/**************************************************************************/ /*! -@Function DumpKickSyncCtxtsInfo -@Description Function that dumps debug info of kick sync ctxs on this device -@Return none -*/ /**************************************************************************/ -void -DumpKickSyncCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/**************************************************************************/ /*! -@Function CheckForStalledClientKickSyncCtxt -@Description Function that checks if a kick sync client is stalled -@Return RGX_KICK_TYPE_DM_GP on stalled context. Otherwise, 0 -*/ /**************************************************************************/ -IMG_UINT32 CheckForStalledClientKickSyncCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); - -/**************************************************************************/ /*! -@Function PVRSRVRGXCreateKickSyncContextKM -@Description Server-side implementation of RGXCreateKicksyncContext -@Return PVRSRV_OK on success. Otherwise, a PVRSRV_ error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXCreateKickSyncContextKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - RGX_SERVER_KICKSYNC_CONTEXT ** ppsKicksyncContext); - - - -/**************************************************************************/ /*! -@Function PVRSRVRGXDestroyKickSyncContextKM -@Description Server-side implementation of RGXDestroyKicksyncContext -@Return PVRSRV_OK on success. Otherwise, a PVRSRV_ error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXDestroyKickSyncContextKM(RGX_SERVER_KICKSYNC_CONTEXT * psKicksyncContext); - -/**************************************************************************/ /*! -@Function PVRSRVRGXSetKickSyncContextPropertyKM -@Description Server-side implementation of RGXSetKickSyncContextProperty -@Return PVRSRV_OK on success. Otherwise, a PVRSRV_ error code - */ /**************************************************************************/ -PVRSRV_ERROR PVRSRVRGXSetKickSyncContextPropertyKM(RGX_SERVER_KICKSYNC_CONTEXT *psKickSyncContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output); - -/**************************************************************************/ /*! -@Function PVRSRVRGXKickSyncKM -@Description Kicks a sync only command -@Return PVRSRV_OK on success. Otherwise, a PVRSRV_ error code -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXKickSyncKM(RGX_SERVER_KICKSYNC_CONTEXT * psKicksyncContext, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ** pauiClientUpdateUFODevVarBlock, - IMG_UINT32 * paui32ClientUpdateDevVarOffset, - IMG_UINT32 * paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE * piUpdateFence, - IMG_CHAR szUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - - IMG_UINT32 ui32ExtJobRef); - -#endif /* RGXKICKSYNC_H */ - -/**************************************************************************//** - End of file (rgxkicksync.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxlayer.h b/drivers/gpu/drm/img-rogue/1.17/rgxlayer.h deleted file mode 100644 index 431a7b6896a62..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxlayer.h +++ /dev/null @@ -1,812 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Header for Services abstraction layer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Declaration of an interface layer used to abstract code that - can be compiled outside of the DDK, potentially in a - completely different OS. - All the headers included by this file must also be copied to - the alternative source tree. - All the functions declared here must have a DDK implementation - inside the DDK source tree (e.g. rgxlayer_impl.h/.c) and - another different implementation in case they are used outside - of the DDK. - All of the functions accept as a first parameter a - "const void *hPrivate" argument. It should be used to pass - around any implementation specific data required. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXLAYER_H) -#define RGXLAYER_H - -#if defined(__cplusplus) -extern "C" { -#endif - - -#include "img_defs.h" -#include "img_types.h" -#include "img_elf.h" -#include "pvrsrv_error.h" /* includes pvrsrv_errors.h */ -#include "pvrsrv_firmware_boot.h" -#include "rgx_bvnc_defs_km.h" -#include "rgx_fw_info.h" -#include "rgx_fwif_shared.h" /* includes rgx_common.h and mem_types.h */ -#include "rgx_meta.h" -#include "rgx_mips.h" -#include "rgx_riscv.h" - -#include "rgxdefs_km.h" -/* includes: - * rgx_cr_defs_km.h, - * RGX_BVNC_CORE_KM_HEADER (rgxcore_km_B.V.N.C.h), - * RGX_BNC_CONFIG_KM_HEADER (rgxconfig_km_B.V.N.C.h) - */ - - -/*! -******************************************************************************* - - @Function RGXMemCopy - - @Description MemCopy implementation - - @Input hPrivate : Implementation specific data - @Input pvDst : Pointer to the destination - @Input pvSrc : Pointer to the source location - @Input uiSize : The amount of memory to copy in bytes - - @Return void - -******************************************************************************/ -void RGXMemCopy(const void *hPrivate, - void *pvDst, - void *pvSrc, - size_t uiSize); - -/*! -******************************************************************************* - - @Function RGXMemSet - - @Description MemSet implementation - - @Input hPrivate : Implementation specific data - @Input pvDst : Pointer to the start of the memory region - @Input ui8Value : The value to be written - @Input uiSize : The number of bytes to be set to ui8Value - - @Return void - -******************************************************************************/ -void RGXMemSet(const void *hPrivate, - void *pvDst, - IMG_UINT8 ui8Value, - size_t uiSize); - -/*! -******************************************************************************* - - @Function RGXCommentLog - - @Description Generic log function used for debugging or other purposes - - @Input hPrivate : Implementation specific data - @Input pszString : Message to be printed - @Input ... : Variadic arguments - - @Return void - -******************************************************************************/ -__printf(2, 3) -void RGXCommentLog(const void *hPrivate, - const IMG_CHAR *pszString, - ...); - -/*! -******************************************************************************* - - @Function RGXErrorLog - - @Description Generic error log function used for debugging or other purposes - - @Input hPrivate : Implementation specific data - @Input pszString : Message to be printed - @Input ... : Variadic arguments - - @Return void - -******************************************************************************/ -__printf(2, 3) -void RGXErrorLog(const void *hPrivate, - const IMG_CHAR *pszString, - ...); - -/*! -******************************************************************************* - - @Function RGXGetOSPageSize - - @Description Return Page size used on OS - - @Input hPrivate : Implementation specific data - - @Return IMG_UINT32 - -******************************************************************************/ - -IMG_UINT32 RGXGetOSPageSize(const void *hPrivate); - -/* This is used to get the value of a specific feature from hprivate. - * Should be used instead of calling RGXDeviceHasFeature. */ -#define RGX_DEVICE_HAS_FEATURE(hPrivate, Feature) \ - RGXDeviceHasFeature(hPrivate, RGX_FEATURE_##Feature##_BIT_MASK) - -/* This is used to check if a specific feature with value is enabled. - * Should be used instead of calling RGXDeviceGetFeatureValue. */ -#define RGX_DEVICE_HAS_FEATURE_VALUE(hPrivate, Feature) \ - (RGXDeviceGetFeatureValue(hPrivate, RGX_FEATURE_##Feature##_IDX) >= 0) - -/* This is used to get the value of a specific feature from hPrivate. - * Should be used instead of calling RGXDeviceGetFeatureValue. */ -#define RGX_DEVICE_GET_FEATURE_VALUE(hPrivate, Feature) \ - RGXDeviceGetFeatureValue(hPrivate, RGX_FEATURE_##Feature##_IDX) - -/*! -******************************************************************************* - - @Function RGXDeviceGetFeatureValue - - @Description Checks if a device has a particular feature with values - - @Input hPrivate : Implementation specific data - @Input ui64Feature : Feature with values to check - - @Return Value >= 0 if the given feature is available, -1 otherwise - -******************************************************************************/ -IMG_INT32 RGXDeviceGetFeatureValue(const void *hPrivate, IMG_UINT64 ui64Feature); - -/*! -******************************************************************************* - - @Function RGXDeviceHasFeature - - @Description Checks if a device has a particular feature - - @Input hPrivate : Implementation specific data - @Input ui64Feature : Feature to check - - @Return IMG_TRUE if the given feature is available, IMG_FALSE otherwise - -******************************************************************************/ -IMG_BOOL RGXDeviceHasFeature(const void *hPrivate, IMG_UINT64 ui64Feature); - -/*! -******************************************************************************* - - @Function RGXGetFWCorememSize - - @Description Get the FW coremem size - - @Input hPrivate : Implementation specific data - - @Return FW coremem size - -******************************************************************************/ -IMG_UINT32 RGXGetFWCorememSize(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXWriteReg32/64 - - @Description Write a value to a 32/64 bit RGX register - - @Input hPrivate : Implementation specific data - @Input ui32RegAddr : Register offset inside the register bank - @Input ui32/64RegValue : New register value - - @Return void - -******************************************************************************/ -void RGXWriteReg32(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue); - -void RGXWriteReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue); - -/*! -******************************************************************************* - - @Function RGXReadReg32/64 - - @Description Read a 32/64 bit RGX register - - @Input hPrivate : Implementation specific data - @Input ui32RegAddr : Register offset inside the register bank - - @Return Register value - -******************************************************************************/ -IMG_UINT32 RGXReadReg32(const void *hPrivate, - IMG_UINT32 ui32RegAddr); - -IMG_UINT64 RGXReadReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr); - -/*! -******************************************************************************* - - @Function RGXReadModifyWriteReg32 - - @Description Read-modify-write a 32 bit RGX register - - @Input hPrivate : Implementation specific data. - @Input ui32RegAddr : Register offset inside the register bank. - @Input ui32RegValue : New register value. - @Input ui32RegMask : Keep the bits set in the mask. - - @Return Always returns PVRSRV_OK - -******************************************************************************/ -IMG_UINT32 RGXReadModifyWriteReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT64 ui64RegKeepMask); - -/*! -******************************************************************************* - - @Function RGXPollReg32/64 - - @Description Poll on a 32/64 bit RGX register until some bits are set/unset - - @Input hPrivate : Implementation specific data - @Input ui32RegAddr : Register offset inside the register bank - @Input ui32/64RegValue : Value expected from the register - @Input ui32/64RegMask : Only the bits set in this mask will be - checked against uiRegValue - - @Return PVRSRV_OK if the poll succeeds, - PVRSRV_ERROR_TIMEOUT if the poll takes too long - -******************************************************************************/ -PVRSRV_ERROR RGXPollReg32(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32RegMask); - -PVRSRV_ERROR RGXPollReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT64 ui64RegMask); - -/*! -******************************************************************************* - - @Function RGXWaitCycles - - @Description Wait for a number of GPU cycles and/or microseconds - - @Input hPrivate : Implementation specific data - @Input ui32Cycles : Number of GPU cycles to wait for in pdumps, - it can also be used when running driver-live - if desired (ignoring the next parameter) - @Input ui32WaitUs : Number of microseconds to wait for when running - driver-live - - @Return void - -******************************************************************************/ -void RGXWaitCycles(const void *hPrivate, - IMG_UINT32 ui32Cycles, - IMG_UINT32 ui32WaitUs); - -/*! -******************************************************************************* - - @Function RGXAcquireKernelMMUPC - - @Description Acquire the Kernel MMU Page Catalogue device physical address - - @Input hPrivate : Implementation specific data - @Input psPCAddr : Returned page catalog address - - @Return void - -******************************************************************************/ -void RGXAcquireKernelMMUPC(const void *hPrivate, IMG_DEV_PHYADDR *psPCAddr); - -/*! -******************************************************************************* - - @Function RGXWriteKernelMMUPC32/64 - - @Description Write the Kernel MMU Page Catalogue to the 32/64 bit - RGX register passed as argument. - In a driver-live scenario without PDump these functions - are the same as RGXWriteReg32/64 and they don't need - to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32PCReg : Register offset inside the register bank - @Input ui32AlignShift : PC register alignshift - @Input ui32Shift : PC register shift - @Input ui32/64PCVal : Page catalog value (aligned and shifted) - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXWriteKernelMMUPC64(const void *hPrivate, - IMG_UINT32 ui32PCReg, - IMG_UINT32 ui32PCRegAlignShift, - IMG_UINT32 ui32PCRegShift, - IMG_UINT64 ui64PCVal); - -void RGXWriteKernelMMUPC32(const void *hPrivate, - IMG_UINT32 ui32PCReg, - IMG_UINT32 ui32PCRegAlignShift, - IMG_UINT32 ui32PCRegShift, - IMG_UINT32 ui32PCVal); -#else /* defined(PDUMP) */ - -#define RGXWriteKernelMMUPC64(priv, pcreg, alignshift, shift, pcval) \ - RGXWriteReg64(priv, pcreg, pcval) - -#define RGXWriteKernelMMUPC32(priv, pcreg, alignshift, shift, pcval) \ - RGXWriteReg32(priv, pcreg, pcval) - -#endif /* defined(PDUMP) */ - - - -/*! -******************************************************************************* - - @Function RGXAcquireGPURegsAddr - - @Description Acquire the GPU registers base device physical address - - @Input hPrivate : Implementation specific data - @Input psGPURegsAddr : Returned GPU registers base address - - @Return void - -******************************************************************************/ -void RGXAcquireGPURegsAddr(const void *hPrivate, IMG_DEV_PHYADDR *psGPURegsAddr); - -/*! -******************************************************************************* - - @Function RGXMIPSWrapperConfig - - @Description Write GPU register bank transaction ID and MIPS boot mode - to the MIPS wrapper config register (passed as argument). - In a driver-live scenario without PDump this is the same as - RGXWriteReg64 and it doesn't need to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32RegAddr : Register offset inside the register bank - @Input ui64GPURegsAddr : GPU registers base address - @Input ui32GPURegsAlign : Register bank transactions alignment - @Input ui32BootMode : Mips BOOT ISA mode - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXMIPSWrapperConfig(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64GPURegsAddr, - IMG_UINT32 ui32GPURegsAlign, - IMG_UINT32 ui32BootMode); -#else -#define RGXMIPSWrapperConfig(priv, regaddr, gpuregsaddr, gpuregsalign, bootmode) \ - RGXWriteReg64(priv, regaddr, ((gpuregsaddr) >> (gpuregsalign)) | (bootmode)) -#endif - -/*! -******************************************************************************* - - @Function RGXAcquireBootRemapAddr - - @Description Acquire the device physical address of the MIPS bootloader - accessed through remap region - - @Input hPrivate : Implementation specific data - @Output psBootRemapAddr : Base address of the remapped bootloader - - @Return void - -******************************************************************************/ -void RGXAcquireBootRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psBootRemapAddr); - -/*! -******************************************************************************* - - @Function RGXBootRemapConfig - - @Description Configure the bootloader remap registers passed as arguments. - In a driver-live scenario without PDump this is the same as - two RGXWriteReg64 and it doesn't need to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32Config1RegAddr : Remap config1 register offset - @Input ui64Config1RegValue : Remap config1 register value - @Input ui32Config2RegAddr : Remap config2 register offset - @Input ui64Config2PhyAddr : Output remapped aligned physical address - @Input ui64Config2PhyMask : Mask for the output physical address - @Input ui64Config2Settings : Extra settings for this remap region - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXBootRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings); -#else -#define RGXBootRemapConfig(priv, c1reg, c1val, c2reg, c2phyaddr, c2phymask, c2settings) do { \ - RGXWriteReg64(priv, c1reg, (c1val)); \ - RGXWriteReg64(priv, c2reg, ((c2phyaddr) & (c2phymask)) | (c2settings)); \ - } while (0) -#endif - -/*! -******************************************************************************* - - @Function RGXAcquireCodeRemapAddr - - @Description Acquire the device physical address of the MIPS code - accessed through remap region - - @Input hPrivate : Implementation specific data - @Output psCodeRemapAddr : Base address of the remapped code - - @Return void - -******************************************************************************/ -void RGXAcquireCodeRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psCodeRemapAddr); - -/*! -******************************************************************************* - - @Function RGXCodeRemapConfig - - @Description Configure the code remap registers passed as arguments. - In a driver-live scenario without PDump this is the same as - two RGXWriteReg64 and it doesn't need to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32Config1RegAddr : Remap config1 register offset - @Input ui64Config1RegValue : Remap config1 register value - @Input ui32Config2RegAddr : Remap config2 register offset - @Input ui64Config2PhyAddr : Output remapped aligned physical address - @Input ui64Config2PhyMask : Mask for the output physical address - @Input ui64Config2Settings : Extra settings for this remap region - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXCodeRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings); -#else -#define RGXCodeRemapConfig(priv, c1reg, c1val, c2reg, c2phyaddr, c2phymask, c2settings) do { \ - RGXWriteReg64(priv, c1reg, (c1val)); \ - RGXWriteReg64(priv, c2reg, ((c2phyaddr) & (c2phymask)) | (c2settings)); \ - } while (0) -#endif - -/*! -******************************************************************************* - - @Function RGXAcquireDataRemapAddr - - @Description Acquire the device physical address of the MIPS data - accessed through remap region - - @Input hPrivate : Implementation specific data - @Output psDataRemapAddr : Base address of the remapped data - - @Return void - -******************************************************************************/ -void RGXAcquireDataRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psDataRemapAddr); - -/*! -******************************************************************************* - - @Function RGXDataRemapConfig - - @Description Configure the data remap registers passed as arguments. - In a driver-live scenario without PDump this is the same as - two RGXWriteReg64 and it doesn't need to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32Config1RegAddr : Remap config1 register offset - @Input ui64Config1RegValue : Remap config1 register value - @Input ui32Config2RegAddr : Remap config2 register offset - @Input ui64Config2PhyAddr : Output remapped aligned physical address - @Input ui64Config2PhyMask : Mask for the output physical address - @Input ui64Config2Settings : Extra settings for this remap region - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXDataRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings); -#else -#define RGXDataRemapConfig(priv, c1reg, c1val, c2reg, c2phyaddr, c2phymask, c2settings) do { \ - RGXWriteReg64(priv, c1reg, (c1val)); \ - RGXWriteReg64(priv, c2reg, ((c2phyaddr) & (c2phymask)) | (c2settings)); \ - } while (0) -#endif - -/*! -******************************************************************************* - - @Function RGXAcquireTrampolineRemapAddr - - @Description Acquire the device physical address of the MIPS data - accessed through remap region - - @Input hPrivate : Implementation specific data - @Output psTrampolineRemapAddr: Base address of the remapped data - - @Return void - -******************************************************************************/ -void RGXAcquireTrampolineRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psTrampolineRemapAddr); - -/*! -******************************************************************************* - - @Function RGXTrampolineRemapConfig - - @Description Configure the trampoline remap registers passed as arguments. - In a driver-live scenario without PDump this is the same as - two RGXWriteReg64 and it doesn't need to be reimplemented. - - @Input hPrivate : Implementation specific data - @Input ui32Config1RegAddr : Remap config1 register offset - @Input ui64Config1RegValue : Remap config1 register value - @Input ui32Config2RegAddr : Remap config2 register offset - @Input ui64Config2PhyAddr : Output remapped aligned physical address - @Input ui64Config2PhyMask : Mask for the output physical address - @Input ui64Config2Settings : Extra settings for this remap region - - @Return void - -******************************************************************************/ -#if defined(PDUMP) -void RGXTrampolineRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings); -#else -#define RGXTrampolineRemapConfig(priv, c1reg, c1val, c2reg, c2phyaddr, c2phymask, c2settings) do { \ - RGXWriteReg64(priv, c1reg, (c1val)); \ - RGXWriteReg64(priv, c2reg, ((c2phyaddr) & (c2phymask)) | (c2settings)); \ - } while (0) -#endif - -/*! -******************************************************************************* - - @Function RGXDoFWSlaveBoot - - @Description Returns whether or not a FW Slave Boot is required - while powering on - - @Input hPrivate : Implementation specific data - - @Return IMG_BOOL - -******************************************************************************/ -IMG_BOOL RGXDoFWSlaveBoot(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXFabricCoherencyTest - - @Description Performs a coherency test - - @Input hPrivate : Implementation specific data - - @Return PVRSRV_OK if the test succeeds, - PVRSRV_ERROR_INIT_FAILURE if the test fails at some point - -******************************************************************************/ -PVRSRV_ERROR RGXFabricCoherencyTest(const void *hPrivate); - -/* This is used to check if a specific ERN/BRN is enabled from hprivate. - * Should be used instead of calling RGXDeviceHasErnBrn. */ -#define RGX_DEVICE_HAS_ERN(hPrivate, ERN) \ - RGXDeviceHasErnBrn(hPrivate, HW_ERN_##ERN##_BIT_MASK) - -#define RGX_DEVICE_HAS_BRN(hPrivate, BRN) \ - RGXDeviceHasErnBrn(hPrivate, FIX_HW_BRN_##BRN##_BIT_MASK) - -/*! -******************************************************************************* - - @Function RGXDeviceHasErnBrn - - @Description Checks if a device has a particular errata - - @Input hPrivate : Implementation specific data - @Input ui64ErnsBrns : Flags to check - - @Return IMG_TRUE if the given errata is available, IMG_FALSE otherwise - -******************************************************************************/ -IMG_BOOL RGXDeviceHasErnBrn(const void *hPrivate, IMG_UINT64 ui64ErnsBrns); - -/*! -******************************************************************************* - - @Function RGXGetDeviceSLCBanks - - @Description Returns the number of SLC banks used by the device - - @Input hPrivate : Implementation specific data - - @Return Number of SLC banks - -******************************************************************************/ -IMG_UINT32 RGXGetDeviceSLCBanks(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXGetDeviceCacheLineSize - - @Description Returns the device cache line size - - @Input hPrivate : Implementation specific data - - @Return Cache line size - -******************************************************************************/ -IMG_UINT32 RGXGetDeviceCacheLineSize(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXGetDevicePhysBusWidth - - @Description Returns the device physical bus width - - @Input hPrivate : Implementation specific data - - @Return Physical bus width - -******************************************************************************/ -IMG_UINT32 RGXGetDevicePhysBusWidth(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXDevicePA0IsValid - - @Description Returns true if the device physical address 0x0 is a valid - address and can be accessed by the GPU. - - @Input hPrivate : Implementation specific data - - @Return IMG_TRUE if device physical address 0x0 is a valid address, - IMG_FALSE otherwise - -******************************************************************************/ -IMG_BOOL RGXDevicePA0IsValid(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXAcquireBootCodeAddr - - @Description Acquire the device virtual address of the RISCV boot code - - @Input hPrivate : Implementation specific data - @Output psBootCodeAddr : Boot code base address - - @Return void - -******************************************************************************/ -void RGXAcquireBootCodeAddr(const void *hPrivate, IMG_DEV_VIRTADDR *psBootCodeAddr); - -/*! -******************************************************************************* - - @Function RGXAcquireBootDataAddr - - @Description Acquire the device virtual address of the RISCV boot data - - @Input hPrivate : Implementation specific data - @Output psBootDataAddr : Boot data base address - - @Return void - -******************************************************************************/ -void RGXAcquireBootDataAddr(const void *hPrivate, IMG_DEV_VIRTADDR *psBootDataAddr); - -/*! -******************************************************************************* - - @Function RGXDeviceAckIrq - - @Description Checks the implementation specific IRQ status register, - clearing it if necessary and returning the IRQ status. - - @Input hPrivate : Implementation specific data - - @Return: IRQ status - -******************************************************************************/ -IMG_BOOL RGXDeviceAckIrq(const void *hPrivate); - -#if defined(__cplusplus) -} -#endif - -#endif /* RGXLAYER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.c b/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.c deleted file mode 100644 index ed0c4b1a1e3c1..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.c +++ /dev/null @@ -1,1318 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title DDK implementation of the Services abstraction layer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description DDK implementation of the Services abstraction layer -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxlayer_impl.h" -#include "osfunc.h" -#include "pdump_km.h" -#include "rgxfwutils.h" -#include "rgxfwimageutils.h" -#include "devicemem.h" -#include "cache_km.h" -#include "pmr.h" - -#if defined(PDUMP) -#include -#endif - -void RGXMemCopy(const void *hPrivate, - void *pvDst, - void *pvSrc, - size_t uiSize) -{ - PVR_UNREFERENCED_PARAMETER(hPrivate); - OSDeviceMemCopy(pvDst, pvSrc, uiSize); -} - -void RGXMemSet(const void *hPrivate, - void *pvDst, - IMG_UINT8 ui8Value, - size_t uiSize) -{ - PVR_UNREFERENCED_PARAMETER(hPrivate); - OSDeviceMemSet(pvDst, ui8Value, uiSize); -} - -void RGXCommentLog(const void *hPrivate, - const IMG_CHAR *pszString, - ...) -{ -#if defined(PDUMP) - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - va_list argList; - va_start(argList, pszString); - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - PDumpCommentWithFlagsVA(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, pszString, argList); - va_end(argList); -#else - PVR_UNREFERENCED_PARAMETER(hPrivate); - PVR_UNREFERENCED_PARAMETER(pszString); -#endif -} - -void RGXErrorLog(const void *hPrivate, - const IMG_CHAR *pszString, - ...) -{ - IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; - va_list argList; - - PVR_UNREFERENCED_PARAMETER(hPrivate); - - va_start(argList, pszString); - vsnprintf(szBuffer, sizeof(szBuffer), pszString, argList); - va_end(argList); - - PVR_DPF((PVR_DBG_ERROR, "%s", szBuffer)); -} - -IMG_UINT32 RGXGetOSPageSize(const void *hPrivate) -{ - PVR_UNREFERENCED_PARAMETER(hPrivate); - return OSGetPageSize(); -} - -IMG_UINT32 RGXGetFWCorememSize(const void *hPrivate) -{ -#if defined(RGX_FEATURE_META_COREMEM_SIZE_MAX_VALUE_IDX) - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32CorememSize = 0; - - PVR_ASSERT(hPrivate != NULL); - - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META_COREMEM_SIZE)) - { - ui32CorememSize = RGX_GET_FEATURE_VALUE(psDevInfo, META_COREMEM_SIZE); - } - - return ui32CorememSize; -#else - PVR_UNREFERENCED_PARAMETER(hPrivate); - - return 0U; -#endif -} - -void RGXWriteReg32(const void *hPrivate, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (!(psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW)) -#endif - { - OSWriteHWReg32(pvRegsBase, ui32RegAddr, ui32RegValue); - } - - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, ui32RegValue, psParams->ui32PdumpFlags); -} - -void RGXWriteReg64(const void *hPrivate, IMG_UINT32 ui32RegAddr, IMG_UINT64 ui64RegValue) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (!(psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW)) -#endif - { - OSWriteHWReg64(pvRegsBase, ui32RegAddr, ui64RegValue); - } - - PDUMPREG64(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, ui64RegValue, psParams->ui32PdumpFlags); -} - -IMG_UINT32 RGXReadReg32(const void *hPrivate, IMG_UINT32 ui32RegAddr) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - IMG_UINT32 ui32RegValue; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW) - { - ui32RegValue = IMG_UINT32_MAX; - } - else -#endif - { - ui32RegValue = OSReadHWReg32(pvRegsBase, ui32RegAddr); - } - - PDUMPREGREAD32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, psParams->ui32PdumpFlags); - - return ui32RegValue; -} - -IMG_UINT64 RGXReadReg64(const void *hPrivate, IMG_UINT32 ui32RegAddr) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - IMG_UINT64 ui64RegValue; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW) - { - ui64RegValue = IMG_UINT64_MAX; - } - else -#endif - { - ui64RegValue = OSReadHWReg64(pvRegsBase, ui32RegAddr); - } - - PDUMPREGREAD64(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, PDUMP_FLAGS_CONTINUOUS); - - return ui64RegValue; -} - -IMG_UINT32 RGXReadModifyWriteReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 uiRegValueNew, - IMG_UINT64 uiRegKeepMask) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; -#if defined(PDUMP) - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; -#endif - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - - /* only use the new values for bits we update according to the keep mask */ - uiRegValueNew &= ~uiRegKeepMask; - -#if defined(PDUMP) - - PDUMP_BLKSTART(ui32PDumpFlags); - - /* Store register offset to temp PDump variable */ - PDumpRegRead64ToInternalVar(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ":SYSMEM:$1", ui32RegAddr, ui32PDumpFlags); - - /* Keep the bits set in the mask */ - PDumpWriteVarANDValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - uiRegKeepMask, ui32PDumpFlags); - - /* OR the new values */ - PDumpWriteVarORValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - uiRegValueNew, ui32PDumpFlags); - - /* Do the actual register write */ - PDumpInternalVarToReg64(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, ":SYSMEM:$1", ui32PDumpFlags); - - PDUMP_BLKEND(ui32PDumpFlags); - - if (!(psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW)) -#endif - - { - IMG_UINT64 uiRegValue = OSReadHWReg64(pvRegsBase, ui32RegAddr); - uiRegValue &= uiRegKeepMask; - OSWriteHWReg64(pvRegsBase, ui32RegAddr, uiRegValue | uiRegValueNew); - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXPollReg32(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32RegMask) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (!(psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW)) -#endif - { - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *)((IMG_UINT8 __iomem *)pvRegsBase + ui32RegAddr), - ui32RegValue, - ui32RegMask, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPollReg32: Poll for Reg (0x%x) failed", ui32RegAddr)); - return PVRSRV_ERROR_TIMEOUT; - } - } - - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - ui32RegAddr, - ui32RegValue, - ui32RegMask, - psParams->ui32PdumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXPollReg64(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT64 ui64RegMask) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - void __iomem *pvRegsBase; - - /* Split lower and upper words */ - IMG_UINT32 ui32UpperValue = (IMG_UINT32) (ui64RegValue >> 32); - IMG_UINT32 ui32LowerValue = (IMG_UINT32) (ui64RegValue); - IMG_UINT32 ui32UpperMask = (IMG_UINT32) (ui64RegMask >> 32); - IMG_UINT32 ui32LowerMask = (IMG_UINT32) (ui64RegMask); - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - pvRegsBase = psDevInfo->pvRegsBaseKM; - -#if defined(PDUMP) - if (!(psParams->ui32PdumpFlags & PDUMP_FLAGS_NOHW)) -#endif - { - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *)((IMG_UINT8 __iomem *)pvRegsBase + ui32RegAddr + 4), - ui32UpperValue, - ui32UpperMask, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPollReg64: Poll for upper part of Reg (0x%x) failed", ui32RegAddr)); - return PVRSRV_ERROR_TIMEOUT; - } - - if (PVRSRVPollForValueKM(psDevInfo->psDeviceNode, - (IMG_UINT32 __iomem *)((IMG_UINT8 __iomem *)pvRegsBase + ui32RegAddr), - ui32LowerValue, - ui32LowerMask, - POLL_FLAG_LOG_ERROR) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPollReg64: Poll for lower part of Reg (0x%x) failed", ui32RegAddr)); - return PVRSRV_ERROR_TIMEOUT; - } - } - - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - ui32RegAddr + 4, - ui32UpperValue, - ui32UpperMask, - psParams->ui32PdumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - - - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - ui32RegAddr, - ui32LowerValue, - ui32LowerMask, - psParams->ui32PdumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - - return PVRSRV_OK; -} - -void RGXWaitCycles(const void *hPrivate, IMG_UINT32 ui32Cycles, IMG_UINT32 ui32TimeUs) -{ - PVRSRV_RGXDEV_INFO __maybe_unused *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - OSWaitus(ui32TimeUs); - PDUMPIDLWITHFLAGS(psDevInfo->psDeviceNode, ui32Cycles, PDUMP_FLAGS_CONTINUOUS); -} - -void RGXAcquireKernelMMUPC(const void *hPrivate, IMG_DEV_PHYADDR *psPCAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psPCAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sPCAddr; -} - -#if defined(PDUMP) -void RGXWriteKernelMMUPC64(const void *hPrivate, - IMG_UINT32 ui32PCReg, - IMG_UINT32 ui32PCRegAlignShift, - IMG_UINT32 ui32PCRegShift, - IMG_UINT64 ui64PCVal) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* Write the cat-base address */ - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, ui32PCReg, ui64PCVal); - - /* Pdump catbase address */ - MMU_PDumpWritePageCatBase(psDevInfo->psKernelMMUCtx, - RGX_PDUMPREG_NAME, - ui32PCReg, - 8, - ui32PCRegAlignShift, - ui32PCRegShift, - PDUMP_FLAGS_CONTINUOUS); -} - -void RGXWriteKernelMMUPC32(const void *hPrivate, - IMG_UINT32 ui32PCReg, - IMG_UINT32 ui32PCRegAlignShift, - IMG_UINT32 ui32PCRegShift, - IMG_UINT32 ui32PCVal) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* Write the cat-base address */ - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32PCReg, ui32PCVal); - - /* Pdump catbase address */ - MMU_PDumpWritePageCatBase(psDevInfo->psKernelMMUCtx, - RGX_PDUMPREG_NAME, - ui32PCReg, - 4, - ui32PCRegAlignShift, - ui32PCRegShift, - PDUMP_FLAGS_CONTINUOUS); -} -#endif /* defined(PDUMP) */ - -void RGXAcquireGPURegsAddr(const void *hPrivate, IMG_DEV_PHYADDR *psGPURegsAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psGPURegsAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sGPURegAddr; -} - -#if defined(PDUMP) -void RGXMIPSWrapperConfig(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64GPURegsAddr, - IMG_UINT32 ui32GPURegsAlign, - IMG_UINT32 ui32BootMode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, - ui32RegAddr, - (ui64GPURegsAddr >> ui32GPURegsAlign) | ui32BootMode); - - PDUMP_BLKSTART(ui32PDumpFlags); - - /* Store register offset to temp PDump variable */ - PDumpRegLabelToInternalVar(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, ":SYSMEM:$1", ui32PDumpFlags); - - /* Align register transactions identifier */ - PDumpWriteVarSHRValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - ui32GPURegsAlign, ui32PDumpFlags); - - /* Enable micromips instruction encoding */ - PDumpWriteVarORValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - ui32BootMode, ui32PDumpFlags); - - /* Do the actual register write */ - PDumpInternalVarToReg64(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - ui32RegAddr, ":SYSMEM:$1", ui32PDumpFlags); - - PDUMP_BLKEND(ui32PDumpFlags); -} -#endif - -void RGXAcquireBootRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psBootRemapAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psBootRemapAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sBootRemapAddr; -} - -void RGXAcquireCodeRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psCodeRemapAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psCodeRemapAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sCodeRemapAddr; -} - -void RGXAcquireDataRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psDataRemapAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psDataRemapAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sDataRemapAddr; -} - -void RGXAcquireTrampolineRemapAddr(const void *hPrivate, IMG_DEV_PHYADDR *psTrampolineRemapAddr) -{ - PVR_ASSERT(hPrivate != NULL); - *psTrampolineRemapAddr = ((RGX_LAYER_PARAMS*)hPrivate)->sTrampolineRemapAddr; -} - -#if defined(PDUMP) -static inline -void RGXWriteRemapConfig2Reg(void __iomem *pvRegs, - PMR *psPMR, - IMG_DEVMEM_OFFSET_T uiLogicalOffset, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64PhyAddr, - IMG_UINT64 ui64PhyMask, - IMG_UINT64 ui64Settings) -{ - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; - PVRSRV_DEVICE_NODE *psDevNode; - - PVR_ASSERT(psPMR != NULL); - psDevNode = PMR_DeviceNode(psPMR); - - OSWriteHWReg64(pvRegs, ui32RegAddr, (ui64PhyAddr & ui64PhyMask) | ui64Settings); - - PDUMP_BLKSTART(ui32PDumpFlags); - - /* Store memory offset to temp PDump variable */ - PDumpMemLabelToInternalVar64(":SYSMEM:$1", psPMR, - uiLogicalOffset, ui32PDumpFlags); - - /* Keep only the relevant bits of the output physical address */ - PDumpWriteVarANDValueOp(psDevNode, ":SYSMEM:$1", ui64PhyMask, ui32PDumpFlags); - - /* Extra settings for this remapped region */ - PDumpWriteVarORValueOp(psDevNode, ":SYSMEM:$1", ui64Settings, ui32PDumpFlags); - - /* Do the actual register write */ - PDumpInternalVarToReg64(psDevNode, RGX_PDUMPREG_NAME, ui32RegAddr, - ":SYSMEM:$1", ui32PDumpFlags); - - PDUMP_BLKEND(ui32PDumpFlags); -} - -void RGXBootRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32BootRemapMemOffset = RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_CODE); - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* Write remap config1 register */ - RGXWriteReg64(hPrivate, - ui32Config1RegAddr, - ui64Config1RegValue); - - /* Write remap config2 register */ - RGXWriteRemapConfig2Reg(psDevInfo->pvRegsBaseKM, - psDevInfo->psRGXFWCodeMemDesc->psImport->hPMR, - psDevInfo->psRGXFWCodeMemDesc->uiOffset + ui32BootRemapMemOffset, - ui32Config2RegAddr, - ui64Config2PhyAddr, - ui64Config2PhyMask, - ui64Config2Settings); -} - -void RGXCodeRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32CodeRemapMemOffset = RGXGetFWImageSectionOffset(NULL, MIPS_EXCEPTIONS_CODE); - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* Write remap config1 register */ - RGXWriteReg64(hPrivate, - ui32Config1RegAddr, - ui64Config1RegValue); - - /* Write remap config2 register */ - RGXWriteRemapConfig2Reg(psDevInfo->pvRegsBaseKM, - psDevInfo->psRGXFWCodeMemDesc->psImport->hPMR, - psDevInfo->psRGXFWCodeMemDesc->uiOffset + ui32CodeRemapMemOffset, - ui32Config2RegAddr, - ui64Config2PhyAddr, - ui64Config2PhyMask, - ui64Config2Settings); -} - -void RGXDataRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32DataRemapMemOffset = RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA); - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* Write remap config1 register */ - RGXWriteReg64(hPrivate, - ui32Config1RegAddr, - ui64Config1RegValue); - - /* Write remap config2 register */ - RGXWriteRemapConfig2Reg(psDevInfo->pvRegsBaseKM, - psDevInfo->psRGXFWDataMemDesc->psImport->hPMR, - psDevInfo->psRGXFWDataMemDesc->uiOffset + ui32DataRemapMemOffset, - ui32Config2RegAddr, - ui64Config2PhyAddr, - ui64Config2PhyMask, - ui64Config2Settings); -} - -void RGXTrampolineRemapConfig(const void *hPrivate, - IMG_UINT32 ui32Config1RegAddr, - IMG_UINT64 ui64Config1RegValue, - IMG_UINT32 ui32Config2RegAddr, - IMG_UINT64 ui64Config2PhyAddr, - IMG_UINT64 ui64Config2PhyMask, - IMG_UINT64 ui64Config2Settings) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - /* write the register for real, without PDump */ - OSWriteHWReg64(psDevInfo->pvRegsBaseKM, - ui32Config1RegAddr, - ui64Config1RegValue); - - PDUMP_BLKSTART(ui32PDumpFlags); - - /* Store the memory address in a PDump variable */ - PDumpPhysHandleToInternalVar64(psDevInfo->psDeviceNode, ":SYSMEM:$1", - psDevInfo->psTrampoline->hPdumpPages, - ui32PDumpFlags); - - /* Keep only the relevant bits of the input physical address */ - PDumpWriteVarANDValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - ~RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_BASE_ADDR_IN_CLRMSK, - ui32PDumpFlags); - - /* Enable bit */ - PDumpWriteVarORValueOp(psDevInfo->psDeviceNode, ":SYSMEM:$1", - RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_EN, - ui32PDumpFlags); - - /* Do the PDump register write */ - PDumpInternalVarToReg64(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - ui32Config1RegAddr, - ":SYSMEM:$1", - ui32PDumpFlags); - - PDUMP_BLKEND(ui32PDumpFlags); - - /* this can be written directly */ - RGXWriteReg64(hPrivate, - ui32Config2RegAddr, - (ui64Config2PhyAddr & ui64Config2PhyMask) | ui64Config2Settings); -} -#endif - -#define MAX_NUM_COHERENCY_TESTS (10) -IMG_BOOL RGXDoFWSlaveBoot(const void *hPrivate) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - PVRSRV_DEVICE_CONFIG *psDevConfig; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - if (psDevInfo->ui32CoherencyTestsDone >= MAX_NUM_COHERENCY_TESTS) - { - return IMG_FALSE; - } - - psDevConfig = ((RGX_LAYER_PARAMS*)hPrivate)->psDevConfig; - - return PVRSRVSystemSnoopingOfCPUCache(psDevConfig); -} - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static PVRSRV_ERROR RGXWriteMetaRegThroughSP(const void *hPrivate, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Wait for Slave Port to be Ready */ - eError = RGXPollReg32(hPrivate, - RGX_CR_META_SP_MSLVCTRL1, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN); - if (eError != PVRSRV_OK) return eError; - - /* Issue a Write */ - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVCTRL0, ui32RegAddr); - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVDATAT, ui32RegValue); - - return eError; -} -#endif - -/* - * The fabric coherency test is performed when platform supports fabric coherency - * either in the form of ACE-lite or Full-ACE. This test is done quite early - * with the firmware processor quiescent and makes exclusive use of the slave - * port interface for reading/writing through the device memory hierarchy. The - * rationale for the test is to ensure that what the CPU writes to its dcache - * is visible to the GPU via coherency snoop miss/hit and vice-versa without - * any intervening cache maintenance by the writing agent. - */ -PVRSRV_ERROR RGXFabricCoherencyTest(const void *hPrivate) -{ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 *pui32FabricCohTestBufferCpuVA; - DEVMEM_MEMDESC *psFabricCohTestBufferMemDesc; - RGXFWIF_DEV_VIRTADDR sFabricCohTestBufferDevVA; - IMG_DEVMEM_SIZE_T uiFabricCohTestBlockSize = sizeof(IMG_UINT64); - IMG_DEVMEM_ALIGN_T uiFabricCohTestBlockAlign = sizeof(IMG_UINT64); - IMG_UINT32 ui32SLCCTRL = 0; - IMG_UINT32 ui32OddEven; -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - IMG_BOOL bFeatureS7 = RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE); -#endif - IMG_UINT32 ui32TestType; - IMG_UINT32 ui32OddEvenSeed = 1; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_BOOL bFullTestPassed = IMG_TRUE; - IMG_BOOL bExit = IMG_FALSE; -#if defined(DEBUG) - IMG_BOOL bSubTestPassed = IMG_FALSE; -#endif - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - PVR_LOG(("Starting fabric coherency test .....")); - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (bFeatureS7) - { - IMG_UINT64 ui64SegOutAddrTopUncached = RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_UNCACHED(MMU_CONTEXT_MAPPING_FWIF); - - /* Configure META to use SLC force-linefill for the bootloader segment */ - RGXWriteMetaRegThroughSP(hPrivate, META_CR_MMCU_SEGMENTn_OUTA1(6), - (ui64SegOutAddrTopUncached | RGXFW_BOOTLDR_DEVV_ADDR) >> 32); - } - else -#endif - { - /* Bypass the SLC when IO coherency is enabled */ - ui32SLCCTRL = RGXReadReg32(hPrivate, RGX_CR_SLC_CTRL_BYPASS); - RGXWriteReg32(hPrivate, - RGX_CR_SLC_CTRL_BYPASS, - ui32SLCCTRL | RGX_CR_SLC_CTRL_BYPASS_BYP_CC_EN); - } - - /* Size and align are 'expanded' because we request an export align allocation */ - eError = DevmemExportalignAdjustSizeAndAlign(DevmemGetHeapLog2PageSize(psDevInfo->psFirmwareMainHeap), - &uiFabricCohTestBlockSize, - &uiFabricCohTestBlockAlign); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevmemExportalignAdjustSizeAndAlign() error: %s, exiting", - PVRSRVGetErrorString(eError))); - goto e0; - } - - /* Allocate, acquire cpu address and set firmware address */ - eError = DevmemFwAllocateExportable(psDevInfo->psDeviceNode, - uiFabricCohTestBlockSize, - uiFabricCohTestBlockAlign, - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT | - PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwExFabricCoherencyTestBuffer", - &psFabricCohTestBufferMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevmemFwAllocateExportable() error: %s, exiting", - PVRSRVGetErrorString(eError))); - goto e0; - } - - eError = DevmemAcquireCpuVirtAddr(psFabricCohTestBufferMemDesc, (void **) &pui32FabricCohTestBufferCpuVA); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "DevmemAcquireCpuVirtAddr() error: %s, exiting", - PVRSRVGetErrorString(eError))); - goto e1; - } - - /* Create a FW address which is uncached in the Meta DCache and in the SLC - * using the Meta bootloader segment. - * This segment is the only one configured correctly out of reset - * (when this test is meant to be executed). - */ - eError = RGXSetFirmwareAddress(&sFabricCohTestBufferDevVA, - psFabricCohTestBufferMemDesc, - 0, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", e2); - - /* Undo most of the FW mappings done by RGXSetFirmwareAddress */ - sFabricCohTestBufferDevVA.ui32Addr &= ~RGXFW_SEGMMU_DATA_META_CACHE_MASK; - sFabricCohTestBufferDevVA.ui32Addr &= ~RGXFW_SEGMMU_DATA_VIVT_SLC_CACHE_MASK; - sFabricCohTestBufferDevVA.ui32Addr -= RGXFW_SEGMMU_DATA_BASE_ADDRESS; - - /* Map the buffer in the bootloader segment as uncached */ - sFabricCohTestBufferDevVA.ui32Addr |= RGXFW_BOOTLDR_META_ADDR; - sFabricCohTestBufferDevVA.ui32Addr |= RGXFW_SEGMMU_DATA_META_UNCACHED; - - for (ui32TestType = 0; ui32TestType < 4 && bExit == IMG_FALSE; ui32TestType++) - { - IMG_CPU_PHYADDR sCpuPhyAddr; - IMG_BOOL bValid; - PMR *psPMR; - - /* Acquire underlying PMR CpuPA in preparation for cache maintenance */ - (void) DevmemLocalGetImportHandle(psFabricCohTestBufferMemDesc, (void**)&psPMR); - eError = PMR_CpuPhysAddr(psPMR, OSGetPageShift(), 1, 0, &sCpuPhyAddr, &bValid); - if (eError != PVRSRV_OK || bValid == IMG_FALSE) - { - PVR_DPF((PVR_DBG_ERROR, - "PMR_CpuPhysAddr error: %s, exiting", - PVRSRVGetErrorString(eError))); - bExit = IMG_TRUE; - continue; - } - - /* Here we do two passes [runs] mostly to account for the effects of using - the different seed (i.e. ui32OddEvenSeed) value to read and write */ - for (ui32OddEven = 1; ui32OddEven < 3 && bExit == IMG_FALSE; ui32OddEven++) - { - IMG_UINT32 i; - -#if defined(DEBUG) - switch (ui32TestType) - { - case 0: - PVR_LOG(("CPU:Write/GPU:Read Snoop Miss Test: starting [run #%u]", ui32OddEven)); - break; - case 1: - PVR_LOG(("GPU:Write/CPU:Read Snoop Miss Test: starting [run #%u]", ui32OddEven)); - break; - case 2: - PVR_LOG(("CPU:Write/GPU:Read Snoop Hit Test: starting [run #%u]", ui32OddEven)); - break; - case 3: - PVR_LOG(("GPU:Write/CPU:Read Snoop Hit Test: starting [run #%u]", ui32OddEven)); - break; - default: - PVR_LOG(("Internal error, exiting test")); - eError = PVRSRV_ERROR_INIT_FAILURE; - bExit = IMG_TRUE; - continue; - } -#endif - - for (i = 0; i < 2 && bExit == IMG_FALSE; i++) - { - IMG_UINT32 ui32FWAddr; - IMG_UINT32 ui32FWValue; - IMG_UINT32 ui32FWValue2; - IMG_CPU_PHYADDR sCpuPhyAddrStart; - IMG_CPU_PHYADDR sCpuPhyAddrEnd; - IMG_UINT32 ui32LastFWValue = ~0; - IMG_UINT32 ui32Offset = i * sizeof(IMG_UINT32); - - /* Calculate next address and seed value to write/read from slave-port */ - ui32FWAddr = sFabricCohTestBufferDevVA.ui32Addr + ui32Offset; - sCpuPhyAddrStart.uiAddr = sCpuPhyAddr.uiAddr + ui32Offset; - sCpuPhyAddrEnd.uiAddr = sCpuPhyAddrStart.uiAddr; - ui32OddEvenSeed += 1; - - if (ui32TestType & 0x1) - { - ui32FWValue = i + ui32OddEvenSeed; - - switch (ui32TestType) - { - case 1: - case 3: - /* Clean dcache to ensure there is no stale data in dcache that might over-write - what we are about to write via slave-port here because if it drains from the CPU - dcache before we read it, it would corrupt what we are going to read back via - the CPU */ - sCpuPhyAddrEnd.uiAddr += sizeof(IMG_UINT32); - CacheOpExec(psDevInfo->psDeviceNode, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset + sizeof(IMG_UINT32), - sCpuPhyAddrStart, - sCpuPhyAddrEnd, - PVRSRV_CACHE_OP_CLEAN); - break; - } - - /* Write the value using the RGX slave-port interface */ - eError = RGXWriteFWModuleAddr(psDevInfo, ui32FWAddr, ui32FWValue); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXWriteFWModuleAddr error: %s, exiting", - PVRSRVGetErrorString(eError))); - bExit = IMG_TRUE; - continue; - } - - /* Read back value using RGX slave-port interface, this is used - as a sort of memory barrier for the above write */ - eError = RGXReadFWModuleAddr(psDevInfo, ui32FWAddr, &ui32FWValue2); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXReadFWModuleAddr error: %s, exiting", - PVRSRVGetErrorString(eError))); - bExit = IMG_TRUE; - continue; - } - else if (ui32FWValue != ui32FWValue2) - { - /* Fatal error, we should abort */ - PVR_DPF((PVR_DBG_ERROR, - "At Offset: %d, RAW via SlavePort failed: expected: %x, got: %x", - i, - ui32FWValue, - ui32FWValue2)); - eError = PVRSRV_ERROR_INIT_FAILURE; - bExit = IMG_TRUE; - continue; - } - - if (! PVRSRVSystemSnoopingOfDeviceCache(psDevInfo->psDeviceNode->psDevConfig)) - { - /* Invalidate dcache to ensure that any prefetched data by the CPU from this memory - region is discarded before we read (i.e. next read must trigger a cache miss). - If there is snooping of device cache, then any prefetching done by the CPU - will reflect the most up to date datum writing by GPU into said location, - that is to say prefetching must be coherent so CPU d-flush is not needed */ - sCpuPhyAddrEnd.uiAddr += sizeof(IMG_UINT32); - CacheOpExec(psDevInfo->psDeviceNode, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset + sizeof(IMG_UINT32), - sCpuPhyAddrStart, - sCpuPhyAddrEnd, - PVRSRV_CACHE_OP_INVALIDATE); - } - } - else - { - IMG_UINT32 ui32RAWCpuValue; - - /* Ensures line is in dcache */ - ui32FWValue = IMG_UINT32_MAX; - - /* Dirty allocation in dcache */ - ui32RAWCpuValue = i + ui32OddEvenSeed; - pui32FabricCohTestBufferCpuVA[i] = i + ui32OddEvenSeed; - - /* Flush possible cpu store-buffer(ing) on LMA */ - OSWriteMemoryBarrier(&pui32FabricCohTestBufferCpuVA[i]); - - switch (ui32TestType) - { - case 0: - /* Flush dcache to force subsequent incoming CPU-bound snoop to miss so - memory is coherent before the SlavePort reads */ - sCpuPhyAddrEnd.uiAddr += sizeof(IMG_UINT32); - CacheOpExec(psDevInfo->psDeviceNode, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset + sizeof(IMG_UINT32), - sCpuPhyAddrStart, - sCpuPhyAddrEnd, - PVRSRV_CACHE_OP_FLUSH); - break; - } - - /* Read back value using RGX slave-port interface */ - eError = RGXReadFWModuleAddr(psDevInfo, ui32FWAddr, &ui32FWValue); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXReadFWModuleAddr error: %s, exiting", - PVRSRVGetErrorString(eError))); - bExit = IMG_TRUE; - continue; - } - - /* We are being mostly paranoid here, just to account for CPU RAW operations */ - sCpuPhyAddrEnd.uiAddr += sizeof(IMG_UINT32); - CacheOpExec(psDevInfo->psDeviceNode, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset, - (IMG_CHAR *)pui32FabricCohTestBufferCpuVA + ui32Offset + sizeof(IMG_UINT32), - sCpuPhyAddrStart, - sCpuPhyAddrEnd, - PVRSRV_CACHE_OP_FLUSH); - if (pui32FabricCohTestBufferCpuVA[i] != ui32RAWCpuValue) - { - /* Fatal error, we should abort */ - PVR_DPF((PVR_DBG_ERROR, - "At Offset: %d, RAW by CPU failed: expected: %x, got: %x", - i, - ui32RAWCpuValue, - pui32FabricCohTestBufferCpuVA[i])); - eError = PVRSRV_ERROR_INIT_FAILURE; - bExit = IMG_TRUE; - continue; - } - } - - /* Compare to see if sub-test passed */ - if (pui32FabricCohTestBufferCpuVA[i] == ui32FWValue) - { -#if defined(DEBUG) - bSubTestPassed = IMG_TRUE; -#endif - } - else - { - bFullTestPassed = IMG_FALSE; - eError = PVRSRV_ERROR_INIT_FAILURE; -#if defined(DEBUG) - bSubTestPassed = IMG_FALSE; -#endif - if (ui32LastFWValue != ui32FWValue) - { -#if defined(DEBUG) - PVR_LOG(("At Offset: %d, Expected: %x, Got: %x", - i, - (ui32TestType & 0x1) ? ui32FWValue : pui32FabricCohTestBufferCpuVA[i], - (ui32TestType & 0x1) ? pui32FabricCohTestBufferCpuVA[i] : ui32FWValue)); -#endif - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "test encountered unexpected error, exiting")); - eError = PVRSRV_ERROR_INIT_FAILURE; - bExit = IMG_TRUE; - continue; - } - } - - ui32LastFWValue = (ui32TestType & 0x1) ? ui32FWValue : pui32FabricCohTestBufferCpuVA[i]; - } - -#if defined(DEBUG) - if (bExit) - { - continue; - } - - switch (ui32TestType) - { - case 0: - PVR_LOG(("CPU:Write/GPU:Read Snoop Miss Test: completed [run #%u]: %s", ui32OddEven, bSubTestPassed ? "PASSED" : "FAILED")); - break; - case 1: - PVR_LOG(("GPU:Write/CPU:Read Snoop Miss Test: completed [run #%u]: %s", ui32OddEven, bSubTestPassed ? "PASSED" : "FAILED")); - break; - case 2: - PVR_LOG(("CPU:Write/GPU:Read Snoop Hit Test: completed [run #%u]: %s", ui32OddEven, bSubTestPassed ? "PASSED" : "FAILED")); - break; - case 3: - PVR_LOG(("GPU:Write/CPU:Read Snoop Hit Test: completed [run #%u]: %s", ui32OddEven, bSubTestPassed ? "PASSED" : "FAILED")); - break; - default: - PVR_LOG(("Internal error, exiting test")); - bExit = IMG_TRUE; - continue; - } -#endif - } - } - - RGXUnsetFirmwareAddress(psFabricCohTestBufferMemDesc); -e2: - DevmemReleaseCpuVirtAddr(psFabricCohTestBufferMemDesc); -e1: - DevmemFwUnmapAndFree(psDevInfo, psFabricCohTestBufferMemDesc); - -e0: -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (bFeatureS7) - { - /* Restore bootloader segment settings */ - IMG_UINT64 ui64SegOutAddrTopCached = RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED(MMU_CONTEXT_MAPPING_FWIF); - RGXWriteMetaRegThroughSP(hPrivate, META_CR_MMCU_SEGMENTn_OUTA1(6), - (ui64SegOutAddrTopCached | RGXFW_BOOTLDR_DEVV_ADDR) >> 32); - } - else -#endif - { - /* Restore SLC bypass settings */ - RGXWriteReg32(hPrivate, RGX_CR_SLC_CTRL_BYPASS, ui32SLCCTRL); - } - - bFullTestPassed = bExit ? IMG_FALSE: bFullTestPassed; - if (bFullTestPassed) - { - PVR_LOG(("fabric coherency test: PASSED")); - psDevInfo->ui32CoherencyTestsDone = MAX_NUM_COHERENCY_TESTS + 1; - } - else - { - PVR_LOG(("fabric coherency test: FAILED")); - psDevInfo->ui32CoherencyTestsDone++; - } - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(hPrivate); - - return PVRSRV_OK; -#endif -} - -IMG_INT32 RGXDeviceGetFeatureValue(const void *hPrivate, IMG_UINT64 ui64Feature) -{ - IMG_INT32 i32Ret = -1; - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PVR_ASSERT(hPrivate != NULL); - - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - psDeviceNode = psDevInfo->psDeviceNode; - - if ((psDeviceNode->pfnGetDeviceFeatureValue)) - { - i32Ret = psDeviceNode->pfnGetDeviceFeatureValue(psDeviceNode, ui64Feature); - } - - return i32Ret; -} - -IMG_BOOL RGXDeviceHasFeature(const void *hPrivate, IMG_UINT64 ui64Feature) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - return (psDevInfo->sDevFeatureCfg.ui64Features & ui64Feature) != 0; -} - -IMG_BOOL RGXDeviceHasErnBrn(const void *hPrivate, IMG_UINT64 ui64ErnsBrns) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - return (psDevInfo->sDevFeatureCfg.ui64ErnsBrns & ui64ErnsBrns) != 0; -} - -IMG_UINT32 RGXGetDeviceSLCBanks(const void *hPrivate) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - if (!RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, SLC_BANKS)) - { - return 0; - } - return RGX_GET_FEATURE_VALUE(psDevInfo, SLC_BANKS); -} - -IMG_UINT32 RGXGetDeviceCacheLineSize(const void *hPrivate) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - if (!RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, SLC_CACHE_LINE_SIZE_BITS)) - { - return 0; - } - return RGX_GET_FEATURE_VALUE(psDevInfo, SLC_CACHE_LINE_SIZE_BITS); -} - -IMG_UINT32 RGXGetDevicePhysBusWidth(const void *hPrivate) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - if (!RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, PHYS_BUS_WIDTH)) - { - return 0; - } - return RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH); -} - -IMG_BOOL RGXDevicePA0IsValid(const void *hPrivate) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - return psDevInfo->sLayerParams.bDevicePA0IsValid; -} - -void RGXAcquireBootCodeAddr(const void *hPrivate, IMG_DEV_VIRTADDR *psBootCodeAddr) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - *psBootCodeAddr = psDevInfo->sFWCodeDevVAddrBase; -} - -void RGXAcquireBootDataAddr(const void *hPrivate, IMG_DEV_VIRTADDR *psBootDataAddr) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psDevInfo = ((RGX_LAYER_PARAMS*)hPrivate)->psDevInfo; - - *psBootDataAddr = psDevInfo->sFWDataDevVAddrBase; -} - -IMG_BOOL RGXDeviceAckIrq(const void *hPrivate) -{ - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - return (psDevInfo->pfnRGXAckIrq != NULL) ? - psDevInfo->pfnRGXAckIrq(psDevInfo) : IMG_TRUE; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.h b/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.h deleted file mode 100644 index 4d7c0f0c77986..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxlayer_impl.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Header for DDK implementation of the Services abstraction layer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for DDK implementation of the Services abstraction layer -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXLAYER_IMPL_H) -#define RGXLAYER_IMPL_H - -#include "rgxlayer.h" -#include "device_connection.h" - -typedef struct _RGX_LAYER_PARAMS_ -{ - void *psDevInfo; - void *psDevConfig; -#if defined(PDUMP) - IMG_UINT32 ui32PdumpFlags; -#endif - - IMG_DEV_PHYADDR sPCAddr; - IMG_DEV_PHYADDR sGPURegAddr; - IMG_DEV_PHYADDR sBootRemapAddr; - IMG_DEV_PHYADDR sCodeRemapAddr; - IMG_DEV_PHYADDR sDataRemapAddr; - IMG_DEV_PHYADDR sTrampolineRemapAddr; - IMG_BOOL bDevicePA0IsValid; -} RGX_LAYER_PARAMS; - -#endif /* RGXLAYER_IMPL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmem.c b/drivers/gpu/drm/img-rogue/1.17/rgxmem.c deleted file mode 100644 index de38b1cec33f4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmem.c +++ /dev/null @@ -1,947 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX memory context management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX memory context management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvr_debug.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_server_utils.h" -#include "devicemem_pdump.h" -#include "rgxdevice.h" -#include "rgx_fwif_km.h" -#include "rgxfwutils.h" -#include "pdump_km.h" -#include "pdump_physmem.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" -#include "sync_internal.h" -#include "rgx_memallocflags.h" -#include "rgx_bvnc_defs_km.h" -#include "info_page.h" - -#if defined(PDUMP) -#include "sync.h" -#endif - -struct SERVER_MMU_CONTEXT_TAG -{ - DEVMEM_MEMDESC *psFWMemContextMemDesc; - PRGXFWIF_FWMEMCONTEXT sFWMemContextDevVirtAddr; - MMU_CONTEXT *psMMUContext; - IMG_PID uiPID; - IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; - IMG_UINT64 ui64FBSCEntryMask; - DLLIST_NODE sNode; - PVRSRV_RGXDEV_INFO *psDevInfo; -}; /* SERVER_MMU_CONTEXT is typedef-ed in rgxmem.h */ - -PVRSRV_ERROR RGXSLCFlushRange(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiSize, - IMG_BOOL bInvalidate) -{ - PVRSRV_ERROR eError; - DLLIST_NODE *psNode, *psNext; - RGXFWIF_KCCB_CMD sFlushInvalCmd; - SERVER_MMU_CONTEXT *psServerMMUContext = NULL; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 ui32kCCBCommandSlot; - - OSWRLockAcquireRead(psDevInfo->hMemoryCtxListLock); - - dllist_foreach_node(&psDevInfo->sMemoryContextList, psNode, psNext) - { - SERVER_MMU_CONTEXT *psIter = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); - if (psIter->psMMUContext == psMMUContext) - { - psServerMMUContext = psIter; - } - } - - OSWRLockReleaseRead(psDevInfo->hMemoryCtxListLock); - - if (! psServerMMUContext) - { - return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; - } - - /* Schedule the SLC flush command */ -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Submit SLC flush and invalidate"); -#endif - sFlushInvalCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bInval = bInvalidate; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_FALSE; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.ui64Size = uiSize; - sFlushInvalCmd.uCmdData.sSLCFlushInvalData.ui64Address = sDevVAddr.uiAddr; - eError = RGXGetFWCommonContextAddrFromServerMMUCtx(psDevInfo, - psServerMMUContext, - &sFlushInvalCmd.uCmdData.sSLCFlushInvalData.psContext); - if (eError != PVRSRV_OK) - { - return eError; - } - - eError = RGXSendCommandWithPowLockAndGetKCCBSlot(psDevInfo, - &sFlushInvalCmd, - PDUMP_FLAGS_CONTINUOUS, - &ui32kCCBCommandSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXSLCFlush: Failed to schedule SLC flush command with error (%u)", - eError)); - } - else - { - /* Wait for the SLC flush to complete */ - eError = RGXWaitForKCCBSlotUpdate(psDevInfo, ui32kCCBCommandSlot, PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXSLCFlush: SLC flush and invalidate aborted with error (%u)", - eError)); - } - } - - return eError; -} - -PVRSRV_ERROR RGXInvalidateFBSCTable(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_CONTEXT *psMMUContext, - IMG_UINT64 ui64FBSCEntryMask) -{ - DLLIST_NODE *psNode, *psNext; - SERVER_MMU_CONTEXT *psServerMMUContext = NULL; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSWRLockAcquireRead(psDevInfo->hMemoryCtxListLock); - - dllist_foreach_node(&psDevInfo->sMemoryContextList, psNode, psNext) - { - SERVER_MMU_CONTEXT *psIter = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); - if (psIter->psMMUContext == psMMUContext) - { - psServerMMUContext = psIter; - } - } - - OSWRLockReleaseRead(psDevInfo->hMemoryCtxListLock); - - if (! psServerMMUContext) - { - return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; - } - - /* Accumulate the FBSC invalidate request */ - psServerMMUContext->ui64FBSCEntryMask |= ui64FBSCEntryMask; - - return PVRSRV_OK; -} - -/* - * RGXExtractFBSCEntryMaskFromMMUContext - * - */ -PVRSRV_ERROR RGXExtractFBSCEntryMaskFromMMUContext(PVRSRV_DEVICE_NODE *psDeviceNode, - SERVER_MMU_CONTEXT *psServerMMUContext, - IMG_UINT64 *pui64FBSCEntryMask) -{ - if (!psServerMMUContext) - { - return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; - } - - *pui64FBSCEntryMask = psServerMMUContext->ui64FBSCEntryMask; - psServerMMUContext->ui64FBSCEntryMask = 0; - - return PVRSRV_OK; -} - -void RGXMMUCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_CONTEXT *psMMUContext, - MMU_LEVEL eMMULevel, - IMG_BOOL bUnmap) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - IMG_UINT32 ui32NewCacheFlags; - - PVR_UNREFERENCED_PARAMETER(bUnmap); - - switch (eMMULevel) - { - case MMU_LEVEL_3: - ui32NewCacheFlags = RGXFWIF_MMUCACHEDATA_FLAGS_PC; - - break; - case MMU_LEVEL_2: - ui32NewCacheFlags = RGXFWIF_MMUCACHEDATA_FLAGS_PD; - - break; - case MMU_LEVEL_1: - ui32NewCacheFlags = RGXFWIF_MMUCACHEDATA_FLAGS_PT; - -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_VIVT))) -#endif - { - ui32NewCacheFlags |= RGXFWIF_MMUCACHEDATA_FLAGS_TLB; - } - - break; - default: - ui32NewCacheFlags = 0; - PVR_ASSERT(0); - - break; - } - -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, SLC_VIVT)) - { - MMU_AppendCacheFlags(psMMUContext, ui32NewCacheFlags); - } - else -#endif - { - MMU_AppendCacheFlags(psDevInfo->psKernelMMUCtx, ui32NewCacheFlags); - } -} - -static inline void _GetAndResetCacheOpsPending(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 *pui32FWCacheFlags) -{ - /* - * Atomically exchange flags and 0 to ensure we never accidentally read - * state inconsistently or overwrite valid cache flags with 0. - */ - *pui32FWCacheFlags = MMU_ExchangeCacheFlags(psDevInfo->psKernelMMUCtx, 0); -} - -static -PVRSRV_ERROR _PrepareAndSubmitCacheCommand(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXFWIF_DM eDM, - IMG_UINT32 ui32CacheFlags, - IMG_BOOL bInterrupt, - IMG_UINT32 *pui32MMUInvalidateUpdate) -{ - PVRSRV_ERROR eError; - RGXFWIF_KCCB_CMD sFlushCmd; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - - *pui32MMUInvalidateUpdate = psDeviceNode->ui32NextMMUInvalidateUpdate++; - - /* Setup cmd and add the device nodes sync object */ - sFlushCmd.eCmdType = RGXFWIF_KCCB_CMD_MMUCACHE; - sFlushCmd.uCmdData.sMMUCacheData.ui32MMUCacheSyncUpdateValue = *pui32MMUInvalidateUpdate; - SyncPrimGetFirmwareAddr(psDeviceNode->psMMUCacheSyncPrim, - &sFlushCmd.uCmdData.sMMUCacheData.sMMUCacheSync.ui32Addr); - - /* Indicate the firmware should signal command completion to the host */ - if (bInterrupt) - { - ui32CacheFlags |= RGXFWIF_MMUCACHEDATA_FLAGS_INTERRUPT; - } - - sFlushCmd.uCmdData.sMMUCacheData.ui32CacheFlags = ui32CacheFlags; - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Submit MMU flush and invalidate (flags = 0x%08x)", - ui32CacheFlags); -#endif - - /* Schedule MMU cache command */ - eError = RGXSendCommand(psDevInfo, - &sFlushCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule MMU cache command to " - "DM=%d with error (%u)", - __func__, eDM, eError)); - psDeviceNode->ui32NextMMUInvalidateUpdate--; - } - - return eError; -} - -PVRSRV_ERROR RGXMMUCacheInvalidateKick(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *pui32MMUInvalidateUpdate) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32FWCacheFlags; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - eError = PVRSRVPowerLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to acquire powerlock (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto RGXMMUCacheInvalidateKick_exit; - } - - _GetAndResetCacheOpsPending(psDeviceNode->pvDevice, &ui32FWCacheFlags); - if (ui32FWCacheFlags == 0) - { - /* Nothing to do if no cache ops pending */ - eError = PVRSRV_OK; - goto _PowerUnlockAndReturnErr; - } - - /* Ensure device is powered up before sending cache command */ - PDUMPPOWCMDSTART(psDeviceNode); - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON, - PVRSRV_POWER_FLAGS_NONE); - PDUMPPOWCMDEND(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "%s: failed to transition RGX to ON (%s)", - __func__, PVRSRVGetErrorString(eError))); - MMU_AppendCacheFlags(psDevInfo->psKernelMMUCtx, ui32FWCacheFlags); - goto _PowerUnlockAndReturnErr; - } - - eError = _PrepareAndSubmitCacheCommand(psDeviceNode, RGXFWIF_DM_GP, ui32FWCacheFlags, - IMG_TRUE, pui32MMUInvalidateUpdate); - if (eError != PVRSRV_OK) - { - /* failed to submit cache operations, return failure */ - PVR_DPF((PVR_DBG_WARNING, "%s: failed to submit cache command (%s)", - __func__, PVRSRVGetErrorString(eError))); - MMU_AppendCacheFlags(psDevInfo->psKernelMMUCtx, ui32FWCacheFlags); - goto _PowerUnlockAndReturnErr; - } - -_PowerUnlockAndReturnErr: - PVRSRVPowerUnlock(psDeviceNode); - -RGXMMUCacheInvalidateKick_exit: - return eError; -} - -PVRSRV_ERROR RGXPreKickCacheCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DM eDM, - IMG_UINT32 *pui32MMUInvalidateUpdate) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode; - IMG_UINT32 ui32FWCacheFlags; - - /* Caller should ensure that power lock is held before calling this function */ - PVR_ASSERT(OSLockIsLocked(psDeviceNode->hPowerLock)); - - _GetAndResetCacheOpsPending(psDeviceNode->pvDevice, &ui32FWCacheFlags); - if (ui32FWCacheFlags == 0) - { - /* Nothing to do if no cache ops pending */ - return PVRSRV_OK; - } - - return _PrepareAndSubmitCacheCommand(psDeviceNode, eDM, ui32FWCacheFlags, - IMG_FALSE, pui32MMUInvalidateUpdate); -} - -/* page fault debug is the only current use case for needing to find process info - * after that process device memory context has been destroyed - */ - -typedef struct _UNREGISTERED_MEMORY_CONTEXT_ -{ - IMG_PID uiPID; - IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; - IMG_DEV_PHYADDR sPCDevPAddr; -} UNREGISTERED_MEMORY_CONTEXT; - -/* must be a power of two */ -#define UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE (1 << 3) - -static UNREGISTERED_MEMORY_CONTEXT gasUnregisteredMemCtxs[UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE]; -static IMG_UINT32 gui32UnregisteredMemCtxsHead; - -/* record a device memory context being unregistered. - * the list of unregistered contexts can be used to find the PID and process name - * belonging to a memory context which has been destroyed - */ -static void _RecordUnregisteredMemoryContext(PVRSRV_RGXDEV_INFO *psDevInfo, SERVER_MMU_CONTEXT *psServerMMUContext) -{ - UNREGISTERED_MEMORY_CONTEXT *psRecord; - - OSLockAcquire(psDevInfo->hMMUCtxUnregLock); - - psRecord = &gasUnregisteredMemCtxs[gui32UnregisteredMemCtxsHead]; - - gui32UnregisteredMemCtxsHead = (gui32UnregisteredMemCtxsHead + 1) - & (UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1); - - OSLockRelease(psDevInfo->hMMUCtxUnregLock); - - psRecord->uiPID = psServerMMUContext->uiPID; - if (MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &psRecord->sPCDevPAddr) != PVRSRV_OK) - { - PVR_LOG(("_RecordUnregisteredMemoryContext: Failed to get PC address for memory context")); - } - OSStringLCopy(psRecord->szProcessName, psServerMMUContext->szProcessName, sizeof(psRecord->szProcessName)); -} - - -void RGXUnregisterMemoryContext(IMG_HANDLE hPrivData) -{ - SERVER_MMU_CONTEXT *psServerMMUContext = hPrivData; - PVRSRV_RGXDEV_INFO *psDevInfo = psServerMMUContext->psDevInfo; - -#if defined(PDUMP) - { - RGXFWIF_DEV_VIRTADDR sFWAddr; - - RGXSetFirmwareAddress(&sFWAddr, - psServerMMUContext->psFWMemContextMemDesc, - 0, - RFW_FWADDR_NOREF_FLAG); - - /* - * MMU cache commands (always dumped) might have a pointer to this FW - * memory context, wait until the FW has caught-up to the latest command. - */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, - "Ensure FW has executed all MMU invalidations on FW memory " - "context 0x%x before freeing it", sFWAddr.ui32Addr); - SyncPrimPDumpPol(psDevInfo->psDeviceNode->psMMUCacheSyncPrim, - psDevInfo->psDeviceNode->ui32NextMMUInvalidateUpdate - 1, - 0xFFFFFFFF, - PDUMP_POLL_OPERATOR_GREATEREQUAL, - PDUMP_FLAGS_CONTINUOUS); - } -#endif - - OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock); - dllist_remove_node(&psServerMMUContext->sNode); - OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) - { - _RecordUnregisteredMemoryContext(psDevInfo, psServerMMUContext); - } - - /* - * Release the page catalogue address acquired in RGXRegisterMemoryContext(). - */ - MMU_ReleaseBaseAddr(NULL); - - /* - * Free the firmware memory context. - */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Free FW memory context"); - DevmemFwUnmapAndFree(psDevInfo, psServerMMUContext->psFWMemContextMemDesc); - - OSFreeMem(psServerMMUContext); -} - -/* - * RGXRegisterMemoryContext - */ -PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_CONTEXT *psMMUContext, - IMG_HANDLE *hPrivData) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_MEMALLOCFLAGS_T uiFWMemContextMemAllocFlags; - RGXFWIF_FWMEMCONTEXT *psFWMemContext; - DEVMEM_MEMDESC *psFWMemContextMemDesc; - SERVER_MMU_CONTEXT *psServerMMUContext; - - if (psDevInfo->psKernelMMUCtx == NULL) - { - /* - * This must be the creation of the Kernel memory context. Take a copy - * of the MMU context for use when programming the BIF. - */ - psDevInfo->psKernelMMUCtx = psMMUContext; - -#if defined(RGX_BRN71422_TARGET_HARDWARE_PHYSICAL_ADDR) - /* Setup the BRN71422 mapping in the FW memory context. */ - if (RGX_IS_BRN_SUPPORTED(psDevInfo, 71422)) - { - RGXMapBRN71422TargetPhysicalAddress(psMMUContext); - } -#endif - } - else - { - psServerMMUContext = OSAllocMem(sizeof(*psServerMMUContext)); - if (psServerMMUContext == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc_server_ctx; - } - - psServerMMUContext->psDevInfo = psDevInfo; - psServerMMUContext->ui64FBSCEntryMask = 0; - psServerMMUContext->sFWMemContextDevVirtAddr.ui32Addr = 0; - - /* - * This FW MemContext is only mapped into kernel for initialisation purposes. - * Otherwise this allocation is only used by the FW. - * Therefore the GPU cache doesn't need coherency, and write-combine - * will suffice on the CPU side (WC buffer will be flushed at any kick) - */ - uiFWMemContextMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN); - - /* - Allocate device memory for the firmware memory context for the new - application. - */ - PDUMPCOMMENT(psDevInfo->psDeviceNode, "Allocate RGX firmware memory context"); - eError = DevmemFwAllocate(psDevInfo, - sizeof(*psFWMemContext), - uiFWMemContextMemAllocFlags | PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC, - "FwMemoryContext", - &psFWMemContextMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware memory context (%u)", - __func__, - eError)); - goto fail_alloc_fw_ctx; - } - - /* - Temporarily map the firmware memory context to the kernel. - */ - eError = DevmemAcquireCpuVirtAddr(psFWMemContextMemDesc, - (void **)&psFWMemContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware memory context (%u)", - __func__, - eError)); - goto fail_acquire_cpu_addr; - } - - /* - * Write the new memory context's page catalogue into the firmware memory - * context for the client. - */ - eError = MMU_AcquireBaseAddr(psMMUContext, &psFWMemContext->sPCDevPAddr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire Page Catalogue address (%u)", - __func__, - eError)); - DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); - goto fail_acquire_base_addr; - } - - /* - * Set default values for the rest of the structure. - */ - psFWMemContext->uiPageCatBaseRegSet = RGXFW_BIF_INVALID_PCSET; - psFWMemContext->uiBreakpointAddr = 0; - psFWMemContext->uiBPHandlerAddr = 0; - psFWMemContext->uiBreakpointCtl = 0; - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -{ - IMG_UINT32 ui32OSid = 0, ui32OSidReg = 0; - IMG_BOOL bOSidAxiProt; - - MMU_GetOSids(psMMUContext, &ui32OSid, &ui32OSidReg, &bOSidAxiProt); - - psFWMemContext->ui32OSid = ui32OSidReg; - psFWMemContext->bOSidAxiProt = bOSidAxiProt; -} -#endif - -#if defined(PDUMP) - { - IMG_CHAR aszName[PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH]; - IMG_DEVMEM_OFFSET_T uiOffset = 0; - - /* - * Dump the Mem context allocation - */ - DevmemPDumpLoadMem(psFWMemContextMemDesc, 0, sizeof(*psFWMemContext), PDUMP_FLAGS_CONTINUOUS); - - - /* - * Obtain a symbolic addr of the mem context structure - */ - eError = DevmemPDumpPageCatBaseToSAddr(psFWMemContextMemDesc, - &uiOffset, - aszName, - PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to generate a Dump Page Catalogue address (%u)", - __func__, - eError)); - DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); - goto fail_pdump_cat_base_addr; - } - - /* - * Dump the Page Cat tag in the mem context (symbolic address) - */ - eError = MMU_PDumpWritePageCatBase(psMMUContext, - aszName, - uiOffset, - 8, /* 64-bit register write */ - 0, - 0, - 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire Page Catalogue address (%u)", - __func__, - eError)); - DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); - goto fail_pdump_cat_base; - } - } -#endif - - /* - * Release kernel address acquired above. - */ - DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); - - /* - * Store the process information for this device memory context - * for use with the host page-fault analysis. - */ - psServerMMUContext->uiPID = OSGetCurrentClientProcessIDKM(); - psServerMMUContext->psMMUContext = psMMUContext; - psServerMMUContext->psFWMemContextMemDesc = psFWMemContextMemDesc; - OSStringLCopy(psServerMMUContext->szProcessName, - OSGetCurrentClientProcessNameKM(), - sizeof(psServerMMUContext->szProcessName)); - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "New memory context: Process Name: %s PID: %u (0x%08X)", - psServerMMUContext->szProcessName, - psServerMMUContext->uiPID, - psServerMMUContext->uiPID); - - OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock); - dllist_add_to_tail(&psDevInfo->sMemoryContextList, &psServerMMUContext->sNode); - OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock); - - *hPrivData = psServerMMUContext; - } - - return PVRSRV_OK; - -#if defined(PDUMP) -fail_pdump_cat_base: -fail_pdump_cat_base_addr: - MMU_ReleaseBaseAddr(NULL); -#endif -fail_acquire_base_addr: - /* Done before jumping to the fail point as the release is done before exit */ -fail_acquire_cpu_addr: - DevmemFwUnmapAndFree(psDevInfo, psServerMMUContext->psFWMemContextMemDesc); -fail_alloc_fw_ctx: - OSFreeMem(psServerMMUContext); -fail_alloc_server_ctx: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -DEVMEM_MEMDESC *RGXGetFWMemDescFromMemoryContextHandle(IMG_HANDLE hPriv) -{ - SERVER_MMU_CONTEXT *psMMUContext = (SERVER_MMU_CONTEXT *) hPriv; - - return psMMUContext->psFWMemContextMemDesc; -} - -void RGXSetFWMemContextDevVirtAddr(SERVER_MMU_CONTEXT *psServerMMUContext, - RGXFWIF_DEV_VIRTADDR sFWMemContextAddr) -{ - psServerMMUContext->sFWMemContextDevVirtAddr.ui32Addr = sFWMemContextAddr.ui32Addr; -} - -void RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_DEV_VIRTADDR *psDevVAddr, - IMG_DEV_PHYADDR *psDevPAddr, - MMU_FAULT_DATA *psOutFaultData) -{ - IMG_DEV_PHYADDR sPCDevPAddr; - DLLIST_NODE *psNode, *psNext; - - OSWRLockAcquireRead(psDevInfo->hMemoryCtxListLock); - - dllist_foreach_node(&psDevInfo->sMemoryContextList, psNode, psNext) - { - SERVER_MMU_CONTEXT *psServerMMUContext = - IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); - - if (MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &sPCDevPAddr) != PVRSRV_OK) - { - PVR_LOG(("Failed to get PC address for memory context")); - continue; - } - - if (psDevPAddr->uiAddr == sPCDevPAddr.uiAddr) - { - MMU_CheckFaultAddress(psServerMMUContext->psMMUContext, psDevVAddr, psOutFaultData); - goto out_unlock; - } - } - - /* Lastly check for fault in the kernel allocated memory */ - if (MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sPCDevPAddr) != PVRSRV_OK) - { - PVR_LOG(("Failed to get PC address for kernel memory context")); - } - - if (psDevPAddr->uiAddr == sPCDevPAddr.uiAddr) - { - MMU_CheckFaultAddress(psDevInfo->psKernelMMUCtx, psDevVAddr, psOutFaultData); - } - -out_unlock: - OSWRLockReleaseRead(psDevInfo->hMemoryCtxListLock); -} - -/* given the physical address of a page catalogue, searches for a corresponding - * MMU context and if found, provides the caller details of the process. - * Returns IMG_TRUE if a process is found. - */ -IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress, - RGXMEM_PROCESS_INFO *psInfo) -{ - IMG_BOOL bRet = IMG_FALSE; - DLLIST_NODE *psNode, *psNext; - SERVER_MMU_CONTEXT *psServerMMUContext = NULL; - - /* check if the input PC addr corresponds to an active memory context */ - dllist_foreach_node(&psDevInfo->sMemoryContextList, psNode, psNext) - { - SERVER_MMU_CONTEXT *psThisMMUContext = - IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); - IMG_DEV_PHYADDR sPCDevPAddr; - - if (MMU_AcquireBaseAddr(psThisMMUContext->psMMUContext, &sPCDevPAddr) != PVRSRV_OK) - { - PVR_LOG(("Failed to get PC address for memory context")); - continue; - } - - if (sPCAddress.uiAddr == sPCDevPAddr.uiAddr) - { - psServerMMUContext = psThisMMUContext; - break; - } - } - - if (psServerMMUContext != NULL) - { - psInfo->uiPID = psServerMMUContext->uiPID; - OSStringLCopy(psInfo->szProcessName, psServerMMUContext->szProcessName, sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_FALSE; - bRet = IMG_TRUE; - } - /* else check if the input PC addr corresponds to the firmware */ - else - { - IMG_DEV_PHYADDR sKernelPCDevPAddr; - PVRSRV_ERROR eError; - - eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sKernelPCDevPAddr); - - if (eError != PVRSRV_OK) - { - PVR_LOG(("Failed to get PC address for kernel memory context")); - } - else - { - if (sPCAddress.uiAddr == sKernelPCDevPAddr.uiAddr) - { - psInfo->uiPID = RGXMEM_SERVER_PID_FIRMWARE; - OSStringLCopy(psInfo->szProcessName, "Firmware", sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_FALSE; - bRet = IMG_TRUE; - } - } - } - - if ((GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) && - (bRet == IMG_FALSE)) - { - /* no active memory context found with the given PC address. - * Check the list of most recently freed memory contexts. - */ - IMG_UINT32 i; - - OSLockAcquire(psDevInfo->hMMUCtxUnregLock); - - /* iterate through the list of unregistered memory contexts - * from newest (one before the head) to the oldest (the current head) - */ - i = gui32UnregisteredMemCtxsHead; - - do - { - UNREGISTERED_MEMORY_CONTEXT *psRecord; - - i ? i-- : (i = (UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1)); - - psRecord = &gasUnregisteredMemCtxs[i]; - - if (psRecord->sPCDevPAddr.uiAddr == sPCAddress.uiAddr) - { - psInfo->uiPID = psRecord->uiPID; - OSStringLCopy(psInfo->szProcessName, psRecord->szProcessName, sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_TRUE; - bRet = IMG_TRUE; - break; - } - } while (i != gui32UnregisteredMemCtxsHead); - - OSLockRelease(psDevInfo->hMMUCtxUnregLock); - - } - - return bRet; -} - -IMG_BOOL RGXPCPIDToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_PID uiPID, - RGXMEM_PROCESS_INFO *psInfo) -{ - IMG_BOOL bRet = IMG_FALSE; - DLLIST_NODE *psNode, *psNext; - SERVER_MMU_CONTEXT *psServerMMUContext = NULL; - - /* check if the input PID corresponds to an active memory context */ - dllist_foreach_node(&psDevInfo->sMemoryContextList, psNode, psNext) - { - SERVER_MMU_CONTEXT *psThisMMUContext = - IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); - - if (psThisMMUContext->uiPID == uiPID) - { - psServerMMUContext = psThisMMUContext; - break; - } - } - - if (psServerMMUContext != NULL) - { - psInfo->uiPID = psServerMMUContext->uiPID; - OSStringLCopy(psInfo->szProcessName, psServerMMUContext->szProcessName, sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_FALSE; - bRet = IMG_TRUE; - } - /* else check if the input PID corresponds to the firmware */ - else if (uiPID == RGXMEM_SERVER_PID_FIRMWARE) - { - psInfo->uiPID = RGXMEM_SERVER_PID_FIRMWARE; - OSStringLCopy(psInfo->szProcessName, "Firmware", sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_FALSE; - bRet = IMG_TRUE; - } - - if ((GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED) && - (bRet == IMG_FALSE)) - { - /* if the PID didn't correspond to an active context or the - * FW address then see if it matches a recently unregistered context - */ - const IMG_UINT32 ui32Mask = UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1; - IMG_UINT32 i, j; - - OSLockAcquire(psDevInfo->hMMUCtxUnregLock); - - for (i = (gui32UnregisteredMemCtxsHead - 1) & ui32Mask, j = 0; - j < UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE; - i = (gui32UnregisteredMemCtxsHead - 1) & ui32Mask, j++) - { - UNREGISTERED_MEMORY_CONTEXT *psRecord = &gasUnregisteredMemCtxs[i]; - - if (psRecord->uiPID == uiPID) - { - psInfo->uiPID = psRecord->uiPID; - OSStringLCopy(psInfo->szProcessName, psRecord->szProcessName, sizeof(psInfo->szProcessName)); - psInfo->bUnregistered = IMG_TRUE; - bRet = IMG_TRUE; - break; - } - } - - OSLockRelease(psDevInfo->hMMUCtxUnregLock); - } - - return bRet; -} - -IMG_PID RGXGetPIDFromServerMMUContext(SERVER_MMU_CONTEXT *psServerMMUContext) -{ - if (psServerMMUContext) - { - return psServerMMUContext->uiPID; - } - return 0; -} - -/****************************************************************************** - End of file (rgxmem.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmem.h b/drivers/gpu/drm/img-rogue/1.17/rgxmem.h deleted file mode 100644 index cbcbed77f9213..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmem.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX memory context management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for RGX memory context management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXMEM_H) -#define RGXMEM_H - -#include "pvrsrv_error.h" -#include "device.h" -#include "mmu_common.h" -#include "rgxdevice.h" - -#define RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME 16 - -/* this PID denotes the firmware */ -#define RGXMEM_SERVER_PID_FIRMWARE 0xFFFFFFFF - -/* this PID denotes the PM */ -#define RGXMEM_SERVER_PID_PM 0xEFFFFFFF - -typedef struct _RGXMEM_PROCESS_INFO_ -{ - IMG_PID uiPID; - IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; - IMG_BOOL bUnregistered; -} RGXMEM_PROCESS_INFO; - -typedef struct SERVER_MMU_CONTEXT_TAG SERVER_MMU_CONTEXT; - -IMG_DEV_PHYADDR GetPC(MMU_CONTEXT * psContext); - -void RGXSetFWMemContextDevVirtAddr(SERVER_MMU_CONTEXT *psServerMMUContext, - RGXFWIF_DEV_VIRTADDR sFWMemContextAddr); - -void RGXMMUSyncPrimAlloc(PVRSRV_DEVICE_NODE *psDevNode); -void RGXMMUSyncPrimFree(void); - -PVRSRV_ERROR RGXSLCFlushRange(PVRSRV_DEVICE_NODE *psDevNode, - MMU_CONTEXT *psMMUContext, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_DEVMEM_SIZE_T uiLength, - IMG_BOOL bInvalidate); - -PVRSRV_ERROR RGXInvalidateFBSCTable(PVRSRV_DEVICE_NODE *psDeviceNode, - MMU_CONTEXT *psMMUContext, - IMG_UINT64 ui64FBSCEntryMask); - -PVRSRV_ERROR RGXExtractFBSCEntryMaskFromMMUContext(PVRSRV_DEVICE_NODE *psDeviceNode, - SERVER_MMU_CONTEXT *psServerMMUContext, - IMG_UINT64 *pui64FBSCEntryMask); - -void RGXMMUCacheInvalidate(PVRSRV_DEVICE_NODE *psDevNode, - MMU_CONTEXT *psMMUContext, - MMU_LEVEL eMMULevel, - IMG_BOOL bUnmap); - -/*************************************************************************/ /*! -@Function RGXMMUCacheInvalidateKick - -@Description Sends a flush command to a particular DM but first takes - the power lock. - -@Input psDevNode Device Node pointer -@Input pui32NextMMUInvalidateUpdate - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXMMUCacheInvalidateKick(PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 *pui32NextMMUInvalidateUpdate); - -/*************************************************************************/ /*! -@Function RGXPreKickCacheCommand - -@Description Sends a cache flush command to a particular DM without - honouring the power lock. It's the caller's responsibility - to ensure power lock is held before calling this function. - -@Input psDevInfo Device Info -@Input eDM To which DM the cmd is sent. -@Input pui32MMUInvalidateUpdate - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -PVRSRV_ERROR RGXPreKickCacheCommand(PVRSRV_RGXDEV_INFO *psDevInfo, - RGXFWIF_DM eDM, - IMG_UINT32 *pui32MMUInvalidateUpdate); - -void RGXUnregisterMemoryContext(IMG_HANDLE hPrivData); -PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE *psDevNode, - MMU_CONTEXT *psMMUContext, - IMG_HANDLE *hPrivData); - -DEVMEM_MEMDESC *RGXGetFWMemDescFromMemoryContextHandle(IMG_HANDLE hPriv); - -void RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_DEV_VIRTADDR *psDevVAddr, - IMG_DEV_PHYADDR *psDevPAddr, - MMU_FAULT_DATA *psOutFaultData); - -IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress, - RGXMEM_PROCESS_INFO *psInfo); - -IMG_BOOL RGXPCPIDToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_PID uiPID, - RGXMEM_PROCESS_INFO *psInfo); - -IMG_PID RGXGetPIDFromServerMMUContext(SERVER_MMU_CONTEXT *psServerMMUContext); - -#endif /* RGXMEM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.c b/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.c deleted file mode 100644 index 0e6c0ab05a463..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.c +++ /dev/null @@ -1,1045 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific MMU initialisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxmipsmmuinit.h" - -#include "device.h" -#include "img_types.h" -#include "img_defs.h" -#include "mmu_common.h" -#include "pdump_mmu.h" -#include "rgxheapconfig.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "rgx_memallocflags.h" -#include "pdump_km.h" -#include "rgxdevice.h" -#include "log2.h" - -/* - * Bits of PT, PD and PC not involving addresses - */ - -/* Currently there is no page directory for MIPS MMU */ -#define RGX_MIPS_MMUCTRL_PDE_PROTMASK 0 -/* Currently there is no page catalog for MIPS MMU */ -#define RGX_MIPS_MMUCTRL_PCE_PROTMASK 0 - - -static MMU_PxE_CONFIG sRGXMMUPCEConfig; -static MMU_DEVVADDR_CONFIG sRGXMMUTopLevelDevVAddrConfig; - - -/* - * - * Configuration for heaps with 4kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_4KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_4KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_4KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig4KB; - - -/* - * - * Configuration for heaps with 16kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_16KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_16KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_16KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig16KB; - - -/* - * - * Configuration for heaps with 64kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_64KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_64KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_64KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig64KB; - - -/* - * - * Configuration for heaps with 256kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_256KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_256KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig256KB; - - -/* - * - * Configuration for heaps with 1MB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_1MBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_1MBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_1MBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig1MB; - - -/* - * - * Configuration for heaps with 2MB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_2MBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_2MBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_2MBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig2MB; - - -/* Forward declaration of protection bits derivation functions, for - the following structure */ -static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags); -static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags); -static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags); - -static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize, - const MMU_PxE_CONFIG **ppsMMUPDEConfig, - const MMU_PxE_CONFIG **ppsMMUPTEConfig, - const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv); - -static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv); - -static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize); -static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize); - -static MMU_DEVICEATTRIBS sRGXMMUDeviceAttributes; - -/* Cached policy */ -static IMG_UINT32 gui32CachedPolicy; - -static PVRSRV_ERROR RGXCheckTrampolineAddrs(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_DEVICEATTRIBS *psDevAttrs, - IMG_UINT64 *pui64Addr); - -PVRSRV_ERROR RGXMipsMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_BOOL bPhysBusAbove32Bit = 0; - - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, PHYS_BUS_WIDTH)) - { - bPhysBusAbove32Bit = RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) > 32; - } - - sRGXMMUDeviceAttributes.pszMMUPxPDumpMemSpaceName = - PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]); - - /* - * Setup sRGXMMUPCEConfig, no PC in MIPS MMU currently - */ - sRGXMMUPCEConfig.uiBytesPerEntry = 0; /* 32 bit entries */ - sRGXMMUPCEConfig.uiAddrMask = 0; /* Mask to get significant address bits of PC entry */ - - sRGXMMUPCEConfig.uiAddrShift = 0; /* Shift this many bits to get PD address in PC entry */ - sRGXMMUPCEConfig.uiAddrLog2Align = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_4K; /* Alignment of PD AND PC */ - - sRGXMMUPCEConfig.uiProtMask = RGX_MIPS_MMUCTRL_PCE_PROTMASK; /* Mask to get the status bits of the PC */ - sRGXMMUPCEConfig.uiProtShift = 0; /* Shift this many bits to have status bits starting with bit 0 */ - - sRGXMMUPCEConfig.uiValidEnMask = RGX_MIPS_MMUCTRL_PC_DATA_VALID_EN; /* Mask to get entry valid bit of the PC */ - sRGXMMUPCEConfig.uiValidEnShift = RGX_MIPS_MMUCTRL_PC_DATA_VALID_SHIFT; /* Shift this many bits to have entry valid bit starting with bit 0 */ - - /* - * Setup sRGXMMUTopLevelDevVAddrConfig - */ - sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask = 0; /* Get the PC address bits from a 40 bit virt. address (in a 64bit UINT) */ - sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift = 0; - sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPC = 0; - - sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask = 0; /* Get the PD address bits from a 40 bit virt. address (in a 64bit UINT) */ - sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift = 0; - sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPD = 0; - - sRGXMMUTopLevelDevVAddrConfig.uiPTIndexMask = IMG_UINT64_C(0xfffffff000); /* Get the PT address bits from a 40 bit virt. address (in a 64bit UINT) */ - sRGXMMUTopLevelDevVAddrConfig.uiPTIndexShift = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_4K; - sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPT = (RGX_NUM_OS_SUPPORTED << RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K) >> RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - -/* - * - * Configuration for heaps with 4kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_4KBDP. No PD in MIPS MMU currently - */ - sRGXMMUPDEConfig_4KBDP.uiBytesPerEntry = 0; - - /* No PD used for MIPS */ - sRGXMMUPDEConfig_4KBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_4KBDP.uiAddrShift = 0; - sRGXMMUPDEConfig_4KBDP.uiAddrLog2Align = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_4K; - - sRGXMMUPDEConfig_4KBDP.uiVarCtrlMask = IMG_UINT64_C(0x0); - sRGXMMUPDEConfig_4KBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_4KBDP.uiProtMask = RGX_MIPS_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_4KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_4KBDP.uiValidEnMask = RGX_MIPS_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_4KBDP.uiValidEnShift = RGX_MIPS_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_4KBDP. - */ - sRGXMMUPTEConfig_4KBDP.uiBytesPerEntry = 1 << RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - - - if (bPhysBusAbove32Bit) - { - sRGXMMUPTEConfig_4KBDP.uiAddrMask = RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT; - gui32CachedPolicy = RGXMIPSFW_CACHED_POLICY_ABOVE_32BIT; - } - else - { - sRGXMMUPTEConfig_4KBDP.uiAddrMask = RGXMIPSFW_ENTRYLO_PFN_MASK; - gui32CachedPolicy = RGXMIPSFW_CACHED_POLICY; - } - - sRGXMMUPTEConfig_4KBDP.uiAddrShift = RGXMIPSFW_ENTRYLO_PFN_SHIFT; - sRGXMMUPTEConfig_4KBDP.uiAddrLog2Align = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_4K; - - sRGXMMUPTEConfig_4KBDP.uiProtMask = RGXMIPSFW_ENTRYLO_DVG | ~RGXMIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK | - RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN | RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_EN; - sRGXMMUPTEConfig_4KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_4KBDP.uiValidEnMask = RGXMIPSFW_ENTRYLO_VALID_EN; - sRGXMMUPTEConfig_4KBDP.uiValidEnShift = RGXMIPSFW_ENTRYLO_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_4KBDP - */ - sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPC = 0; - - - sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask = ~RGX_MIPS_MMUCTRL_VADDR_PT_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift = RGX_MIPS_MMUCTRL_VADDR_PT_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPT = (RGX_NUM_OS_SUPPORTED << RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K) >> RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - - - sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000000fff); - sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiOffsetInBytes = RGX_FIRMWARE_RAW_HEAP_BASE & IMG_UINT64_C(0x00ffffffff); - - /* - * Setup gsPageSizeConfig4KB - */ - gsPageSizeConfig4KB.psPDEConfig = &sRGXMMUPDEConfig_4KBDP; - gsPageSizeConfig4KB.psPTEConfig = &sRGXMMUPTEConfig_4KBDP; - gsPageSizeConfig4KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_4KBDP; - gsPageSizeConfig4KB.uiRefCount = 0; - gsPageSizeConfig4KB.uiMaxRefCount = 0; - - -/* - * - * Configuration for heaps with 16kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_16KBDP - */ - sRGXMMUPDEConfig_16KBDP.uiBytesPerEntry = 0; - - sRGXMMUPDEConfig_16KBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_16KBDP.uiAddrShift = 0; /* These are for a page directory ENTRY, meaning the address of a PT cropped to suit the PD */ - sRGXMMUPDEConfig_16KBDP.uiAddrLog2Align = 0; /* Alignment of the page tables NOT directories */ - - sRGXMMUPDEConfig_16KBDP.uiVarCtrlMask = 0; - sRGXMMUPDEConfig_16KBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_16KBDP.uiProtMask = 0; - sRGXMMUPDEConfig_16KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_16KBDP.uiValidEnMask = 0; - sRGXMMUPDEConfig_16KBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUPTEConfig_16KBDP. Not supported yet - */ - sRGXMMUPTEConfig_16KBDP.uiBytesPerEntry = 0; - - sRGXMMUPTEConfig_16KBDP.uiAddrMask = 0; - sRGXMMUPTEConfig_16KBDP.uiAddrShift = 0; /* These are for a page table ENTRY, meaning the address of a PAGE cropped to suit the PD */ - sRGXMMUPTEConfig_16KBDP.uiAddrLog2Align = 0; /* Alignment of the pages NOT tables */ - - sRGXMMUPTEConfig_16KBDP.uiProtMask = 0; - sRGXMMUPTEConfig_16KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_16KBDP.uiValidEnMask = 0; - sRGXMMUPTEConfig_16KBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUDevVAddrConfig_16KBDP - */ - sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPC = 0; - - sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPT = 0; - - sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetMask = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig16KB - */ - gsPageSizeConfig16KB.psPDEConfig = &sRGXMMUPDEConfig_16KBDP; - gsPageSizeConfig16KB.psPTEConfig = &sRGXMMUPTEConfig_16KBDP; - gsPageSizeConfig16KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_16KBDP; - gsPageSizeConfig16KB.uiRefCount = 0; - gsPageSizeConfig16KB.uiMaxRefCount = 0; - - -/* - * - * Configuration for heaps with 64kB Data-Page size. Not supported yet - * - */ - - /* - * Setup sRGXMMUPDEConfig_64KBDP - */ - sRGXMMUPDEConfig_64KBDP.uiBytesPerEntry = 0; - - sRGXMMUPDEConfig_64KBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_64KBDP.uiAddrShift = 0; - sRGXMMUPDEConfig_64KBDP.uiAddrLog2Align = 0; - - sRGXMMUPDEConfig_64KBDP.uiVarCtrlMask = 0; - sRGXMMUPDEConfig_64KBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_64KBDP.uiProtMask = 0; - sRGXMMUPDEConfig_64KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_64KBDP.uiValidEnMask = 0; - sRGXMMUPDEConfig_64KBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUPTEConfig_64KBDP. - * - */ - sRGXMMUPTEConfig_64KBDP.uiBytesPerEntry = 1 << RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - - if (bPhysBusAbove32Bit) - { - sRGXMMUPTEConfig_64KBDP.uiAddrMask = RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT; - gui32CachedPolicy = RGXMIPSFW_CACHED_POLICY_ABOVE_32BIT; - } - else - { - sRGXMMUPTEConfig_64KBDP.uiAddrMask = RGXMIPSFW_ENTRYLO_PFN_MASK; - gui32CachedPolicy = RGXMIPSFW_CACHED_POLICY; - } - - /* Even while using 64K pages, MIPS still aligns addresses to 4K */ - sRGXMMUPTEConfig_64KBDP.uiAddrShift = RGXMIPSFW_ENTRYLO_PFN_SHIFT; - sRGXMMUPTEConfig_64KBDP.uiAddrLog2Align = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_4K; - - sRGXMMUPTEConfig_64KBDP.uiProtMask = RGXMIPSFW_ENTRYLO_DVG | ~RGXMIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK | - RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN | RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_EN; - sRGXMMUPTEConfig_64KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_64KBDP.uiValidEnMask = RGXMIPSFW_ENTRYLO_VALID_EN; - sRGXMMUPTEConfig_64KBDP.uiValidEnShift = RGXMIPSFW_ENTRYLO_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_64KBDP. - */ - sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPC = 0; - - sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask = IMG_UINT64_C(0x00ffff0000); - sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift = (IMG_UINT32)RGXMIPSFW_LOG2_PAGE_SIZE_64K; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPT = (RGX_NUM_OS_SUPPORTED << RGXMIPSFW_LOG2_PAGETABLE_SIZE_64K) >> RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - - sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000000ffff); - sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiOffsetInBytes = RGX_FIRMWARE_RAW_HEAP_BASE & IMG_UINT64_C(0x00ffffffff); - - /* - * Setup gsPageSizeConfig64KB. - */ - gsPageSizeConfig64KB.psPDEConfig = &sRGXMMUPDEConfig_64KBDP; - gsPageSizeConfig64KB.psPTEConfig = &sRGXMMUPTEConfig_64KBDP; - gsPageSizeConfig64KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_64KBDP; - gsPageSizeConfig64KB.uiRefCount = 0; - gsPageSizeConfig64KB.uiMaxRefCount = 0; - - -/* - * - * Configuration for heaps with 256kB Data-Page size. Not supported yet - * - */ - - /* - * Setup sRGXMMUPDEConfig_256KBDP - */ - sRGXMMUPDEConfig_256KBDP.uiBytesPerEntry = 0; - - sRGXMMUPDEConfig_256KBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_256KBDP.uiAddrShift = 0; - sRGXMMUPDEConfig_256KBDP.uiAddrLog2Align = 0; - - sRGXMMUPDEConfig_256KBDP.uiVarCtrlMask = 0; - sRGXMMUPDEConfig_256KBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_256KBDP.uiProtMask = 0; - sRGXMMUPDEConfig_256KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_256KBDP.uiValidEnMask = 0; - sRGXMMUPDEConfig_256KBDP.uiValidEnShift = 0; - - /* - * Setup MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP - */ - sRGXMMUPTEConfig_256KBDP.uiBytesPerEntry = 0; - - sRGXMMUPTEConfig_256KBDP.uiAddrMask = 0; - sRGXMMUPTEConfig_256KBDP.uiAddrShift = 0; - sRGXMMUPTEConfig_256KBDP.uiAddrLog2Align = 0; - - sRGXMMUPTEConfig_256KBDP.uiProtMask = 0; - sRGXMMUPTEConfig_256KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_256KBDP.uiValidEnMask = 0; - sRGXMMUPTEConfig_256KBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUDevVAddrConfig_256KBDP - */ - sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPC = 0; - - sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPT = 0; - - sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetMask = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig256KB - */ - gsPageSizeConfig256KB.psPDEConfig = &sRGXMMUPDEConfig_256KBDP; - gsPageSizeConfig256KB.psPTEConfig = &sRGXMMUPTEConfig_256KBDP; - gsPageSizeConfig256KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_256KBDP; - gsPageSizeConfig256KB.uiRefCount = 0; - gsPageSizeConfig256KB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUPDEConfig_1MBDP. Not supported yet - */ - sRGXMMUPDEConfig_1MBDP.uiBytesPerEntry = 0; - - sRGXMMUPDEConfig_1MBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_1MBDP.uiAddrShift = 0; - sRGXMMUPDEConfig_1MBDP.uiAddrLog2Align = 0; - - sRGXMMUPDEConfig_1MBDP.uiVarCtrlMask = 0; - sRGXMMUPDEConfig_1MBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_1MBDP.uiProtMask = 0; - sRGXMMUPDEConfig_1MBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_1MBDP.uiValidEnMask = 0; - sRGXMMUPDEConfig_1MBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUPTEConfig_1MBDP - */ - sRGXMMUPTEConfig_1MBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_1MBDP.uiAddrMask = 0; - sRGXMMUPTEConfig_1MBDP.uiAddrShift = 0; - sRGXMMUPTEConfig_1MBDP.uiAddrLog2Align = 0; - - sRGXMMUPTEConfig_1MBDP.uiProtMask = 0; - sRGXMMUPTEConfig_1MBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_1MBDP.uiValidEnMask = 0; - sRGXMMUPTEConfig_1MBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUDevVAddrConfig_1MBDP - */ - sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPC = 0; - - sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPT = 0; - - sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetMask = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig1MB - */ - gsPageSizeConfig1MB.psPDEConfig = &sRGXMMUPDEConfig_1MBDP; - gsPageSizeConfig1MB.psPTEConfig = &sRGXMMUPTEConfig_1MBDP; - gsPageSizeConfig1MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_1MBDP; - gsPageSizeConfig1MB.uiRefCount = 0; - gsPageSizeConfig1MB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUPDEConfig_2MBDP. Not supported yet - */ - sRGXMMUPDEConfig_2MBDP.uiBytesPerEntry = 0; - - sRGXMMUPDEConfig_2MBDP.uiAddrMask = 0; - sRGXMMUPDEConfig_2MBDP.uiAddrShift = 0; - sRGXMMUPDEConfig_2MBDP.uiAddrLog2Align = 0; - - sRGXMMUPDEConfig_2MBDP.uiVarCtrlMask = 0; - sRGXMMUPDEConfig_2MBDP.uiVarCtrlShift = 0; - - sRGXMMUPDEConfig_2MBDP.uiProtMask = 0; - sRGXMMUPDEConfig_2MBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_2MBDP.uiValidEnMask = 0; - sRGXMMUPDEConfig_2MBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUPTEConfig_2MBDP - */ - sRGXMMUPTEConfig_2MBDP.uiBytesPerEntry = 0; - - sRGXMMUPTEConfig_2MBDP.uiAddrMask = 0; - sRGXMMUPTEConfig_2MBDP.uiAddrShift = 0; - sRGXMMUPTEConfig_2MBDP.uiAddrLog2Align = 0; - - sRGXMMUPTEConfig_2MBDP.uiProtMask = 0; - sRGXMMUPTEConfig_2MBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_2MBDP.uiValidEnMask = 0; - sRGXMMUPTEConfig_2MBDP.uiValidEnShift = 0; - - /* - * Setup sRGXMMUDevVAddrConfig_2MBDP - */ - sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPC = 0; - - sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPD = 0; - - sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPT = 0; - - sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetMask = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig2MB - */ - gsPageSizeConfig2MB.psPDEConfig = &sRGXMMUPDEConfig_2MBDP; - gsPageSizeConfig2MB.psPTEConfig = &sRGXMMUPTEConfig_2MBDP; - gsPageSizeConfig2MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_2MBDP; - gsPageSizeConfig2MB.uiRefCount = 0; - gsPageSizeConfig2MB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUDeviceAttributes - */ - sRGXMMUDeviceAttributes.eMMUType = PDUMP_MMU_TYPE_MIPS_MICROAPTIV; - sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_1; - - /* - * The page table fits in one or more big physically adjacent pages, - * at most as big as the page table itself. - * To calculate its alignment/page size, calculate the log2 size of the page - * table taking into account all OSes, then round that down to a valid MIPS - * log2 page size (12, 14, 16 for a 4K, 16K, 64K page size). - */ - sRGXMMUDeviceAttributes.ui32BaseAlign = - (CeilLog2(RGX_NUM_OS_SUPPORTED) + RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K) & ~1U; - - /* 256K alignment might be too hard to achieve, fall back to 64K */ - sRGXMMUDeviceAttributes.ui32BaseAlign = - MIN(sRGXMMUDeviceAttributes.ui32BaseAlign, RGXMIPSFW_LOG2_PAGE_SIZE_64K); - - - - /* The base configuration is set to 4kB pages*/ - sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPTEConfig_4KBDP; - sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig; - - /* Functions for deriving page table/dir/cat protection bits */ - sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8; - sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4; - sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8; - sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4; - sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8; - sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4; - - /* Functions for establishing configurations for PDE/PTE/DEVVADDR - on per-heap basis */ - sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB; - sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB; - - sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE4 = RGXGetPageSizeFromPDE4; - sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE8 = RGXGetPageSizeFromPDE8; - - psDeviceNode->psFirmwareMMUDevAttrs = &sRGXMMUDeviceAttributes; - - psDeviceNode->pfnValidateOrTweakPhysAddrs = RGXCheckTrampolineAddrs; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXCheckTrampolineAddrs(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - MMU_DEVICEATTRIBS *psDevAttrs, - IMG_UINT64 *pui64Addr) -{ - if (PVRSRV_IS_FEATURE_SUPPORTED(psDevNode, MIPS)) - { - /* - * If mapping for the MIPS FW context, check for sensitive PAs - */ - if (psDevAttrs == psDevNode->psFirmwareMMUDevAttrs) - { - PVRSRV_RGXDEV_INFO *psDevice = (PVRSRV_RGXDEV_INFO *)psDevNode->pvDevice; - - if ((RGX_GET_FEATURE_VALUE(psDevice, PHYS_BUS_WIDTH) == 32) && - RGXMIPSFW_SENSITIVE_ADDR(*pui64Addr)) - { - *pui64Addr = psDevice->psTrampoline->sPhysAddr.uiAddr + RGXMIPSFW_TRAMPOLINE_OFFSET(*pui64Addr); - } - /* FIX_HW_BRN_63553 is mainlined for all MIPS cores */ - else if (*pui64Addr == 0x0 && !psDevice->sLayerParams.bDevicePA0IsValid) - { - PVR_DPF((PVR_DBG_ERROR, "%s attempt to map addr 0x0 in the FW but 0x0 is not considered valid.", __func__)); - return PVRSRV_ERROR_MMU_FAILED_TO_MAP_PAGE_TABLE; - } - } - } - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXMipsMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - eError = PVRSRV_OK; - -#if defined(PDUMP) - psDeviceNode->pfnMMUGetContextID = NULL; -#endif - - psDeviceNode->psFirmwareMMUDevAttrs = NULL; - -#if defined(DEBUG) - PVR_DPF((PVR_DBG_MESSAGE, "Variable Page Size Heap Stats:")); - PVR_DPF((PVR_DBG_MESSAGE, "Max 4K page heaps: %d", - gsPageSizeConfig4KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 4K page heaps (should be 0): %d", - gsPageSizeConfig4KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 16K page heaps: %d", - gsPageSizeConfig16KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 16K page heaps (should be 0): %d", - gsPageSizeConfig16KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 64K page heaps: %d", - gsPageSizeConfig64KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 64K page heaps (should be 0): %d", - gsPageSizeConfig64KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 256K page heaps: %d", - gsPageSizeConfig256KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 256K page heaps (should be 0): %d", - gsPageSizeConfig256KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 1M page heaps: %d", - gsPageSizeConfig1MB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 1M page heaps (should be 0): %d", - gsPageSizeConfig1MB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 2M page heaps: %d", - gsPageSizeConfig2MB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 2M page heaps (should be 0): %d", - gsPageSizeConfig2MB.uiRefCount)); -#endif - if (gsPageSizeConfig4KB.uiRefCount > 0 || - gsPageSizeConfig16KB.uiRefCount > 0 || - gsPageSizeConfig64KB.uiRefCount > 0 || - gsPageSizeConfig256KB.uiRefCount > 0 || - gsPageSizeConfig1MB.uiRefCount > 0 || - gsPageSizeConfig2MB.uiRefCount > 0 - ) - { - PVR_DPF((PVR_DBG_ERROR, "RGXMMUInit_Unregister: Unbalanced MMU API Usage (Internal error)")); - } - - return eError; -} - -/*************************************************************************/ /*! -@Function RGXDerivePCEProt4 -@Description calculate the PCE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags) -{ - PVR_DPF((PVR_DBG_ERROR, "Page Catalog not supported on MIPS MMU")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePCEProt8 -@Description calculate the PCE protection flags based on an 8 byte entry -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize); - - PVR_DPF((PVR_DBG_ERROR, "Page Catalog not supported on MIPS MMU")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePDEProt4 -@Description derive the PDE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_DPF((PVR_DBG_ERROR, "Page Directory not supported on MIPS MMU")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePDEProt8 -@Description derive the PDE protection flags based on an 8 byte entry - -@Input uiLog2DataPageSize The log2 of the required page size. - E.g, for 4KiB pages, this parameter must be 12. - For 2MiB pages, it must be set to 21. - -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_DPF((PVR_DBG_ERROR, "Page Directory not supported on MIPS MMU")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePTEProt4 -@Description calculate the PTE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags) -{ - IMG_UINT32 ui32MMUFlags = 0; - - if (((MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE) & uiProtFlags) == (MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE)) - { - /* read/write */ - ui32MMUFlags |= RGXMIPSFW_ENTRYLO_DIRTY_EN; - } - else if (MMU_PROTFLAGS_READABLE & uiProtFlags) - { - /* read only */ - } - else if (MMU_PROTFLAGS_WRITEABLE & uiProtFlags) - { - /* write only */ - ui32MMUFlags |= RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN; - } - else if ((MMU_PROTFLAGS_INVALID & uiProtFlags) == 0) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt4: neither read nor write specified...")); - } - - /* cache coherency */ - if (MMU_PROTFLAGS_CACHE_COHERENT & uiProtFlags) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt4: cache coherency not supported for MIPS caches")); - } - - /* cache setup */ - if ((MMU_PROTFLAGS_CACHED & uiProtFlags) == 0) - { - ui32MMUFlags |= RGXMIPSFW_ENTRYLO_UNCACHED; - } - else - { - ui32MMUFlags |= gui32CachedPolicy << - RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT; - } - - if ((uiProtFlags & MMU_PROTFLAGS_INVALID) == 0) - { - ui32MMUFlags |= RGXMIPSFW_ENTRYLO_VALID_EN; - ui32MMUFlags |= RGXMIPSFW_ENTRYLO_GLOBAL_EN; - } - - if (MMU_PROTFLAGS_DEVICE(PMMETA_PROTECT) & uiProtFlags) - { - /* PVR_DPF((PVR_DBG_WARNING, "RGXDerivePTEProt4: PMMETA Protect not existent for MIPS, option discarded")); */ - } - - return ui32MMUFlags; -} - -/*************************************************************************/ /*! -@Function RGXDerivePTEProt8 -@Description calculate the PTE protection flags based on an 8 byte entry -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize); - - PVR_DPF((PVR_DBG_ERROR, "8-byte PTE not supported on this device")); - - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXGetPageSizeConfig -@Description Set up configuration for variable sized data pages. - RGXPutPageSizeConfigCB has to be called to ensure correct - refcounting. -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize, - const MMU_PxE_CONFIG **ppsMMUPDEConfig, - const MMU_PxE_CONFIG **ppsMMUPTEConfig, - const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv) -{ - MMU_PAGESIZECONFIG *psPageSizeConfig; - - switch (uiLog2DataPageSize) - { - case RGXMIPSFW_LOG2_PAGE_SIZE_64K: - psPageSizeConfig = &gsPageSizeConfig64KB; - break; - case RGXMIPSFW_LOG2_PAGE_SIZE_4K: - psPageSizeConfig = &gsPageSizeConfig4KB; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "RGXGetPageSizeConfigCB: Invalid Data Page Size 1<<0x%x", - uiLog2DataPageSize)); - *phPriv = NULL; - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; - } - - /* Refer caller's pointers to the data */ - *ppsMMUPDEConfig = psPageSizeConfig->psPDEConfig; - *ppsMMUPTEConfig = psPageSizeConfig->psPTEConfig; - *ppsMMUDevVAddrConfig = psPageSizeConfig->psDevVAddrConfig; - -#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT) - /* Increment ref-count - not that we're allocating anything here - (I'm using static structs), but one day we might, so we want - the Get/Put code to be balanced properly */ - psPageSizeConfig->uiRefCount++; - - /* This is purely for debug statistics */ - psPageSizeConfig->uiMaxRefCount = MAX(psPageSizeConfig->uiMaxRefCount, - psPageSizeConfig->uiRefCount); -#endif - - *phPriv = (IMG_HANDLE)(uintptr_t)uiLog2DataPageSize; - PVR_ASSERT (uiLog2DataPageSize == (IMG_UINT32)(uintptr_t)*phPriv); - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function RGXPutPageSizeConfig -@Description Tells this code that the mmu module is done with the - configurations set in RGXGetPageSizeConfig. This can - be a no-op. - Called after RGXGetPageSizeConfigCB. -@Return PVRSRV_ERROR -*/ /**************************************************************************/ -static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv) -{ -#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT) - MMU_PAGESIZECONFIG *psPageSizeConfig; - IMG_UINT32 uiLog2DataPageSize; - - uiLog2DataPageSize = (IMG_UINT32)(uintptr_t) hPriv; - - switch (uiLog2DataPageSize) - { - case RGXMIPSFW_LOG2_PAGE_SIZE_64K: - psPageSizeConfig = &gsPageSizeConfig64KB; - break; - case RGXMIPSFW_LOG2_PAGE_SIZE_4K: - psPageSizeConfig = &gsPageSizeConfig4KB; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "RGXPutPageSizeConfigCB: Invalid Data Page Size 1<<0x%x", - uiLog2DataPageSize)); - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; - } - - /* Ref-count here is not especially useful, but it's an extra - check that the API is being used correctly */ - psPageSizeConfig->uiRefCount--; -#else - PVR_UNREFERENCED_PARAMETER(hPriv); -#endif - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize) -{ - PVR_UNREFERENCED_PARAMETER(ui32PDE); - PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize); - PVR_DPF((PVR_DBG_ERROR, "PDE not supported on MIPS")); - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; -} - -static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize) -{ - PVR_UNREFERENCED_PARAMETER(ui64PDE); - PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize); - PVR_DPF((PVR_DBG_ERROR, "PDE not supported on MIPS")); - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; -} - -void RGXMipsCheckFaultAddress(MMU_CONTEXT *psFwMMUCtx, - IMG_UINT32 ui32FwVA, - MMU_FAULT_DATA *psOutFaultData) -{ - IMG_UINT32 *pui32PageTable = NULL; - PVRSRV_ERROR eError = MMU_AcquireCPUBaseAddr(psFwMMUCtx, (void**) &pui32PageTable); - MMU_LEVEL_DATA *psMMULevelData; - IMG_UINT32 ui32FwHeapBase = (IMG_UINT32) (RGX_FIRMWARE_RAW_HEAP_BASE & UINT_MAX); - IMG_UINT32 ui32PageSize = OSGetPageSize(); - - /* MIPS Firmware CPU must use the same page size as the Host */ - IMG_UINT32 ui32PTEIndex = ((ui32FwVA & ~(ui32PageSize - 1)) - ui32FwHeapBase) / ui32PageSize; - - psOutFaultData->eTopLevel = MMU_LEVEL_1; - psOutFaultData->eType = MMU_FAULT_TYPE_NON_PM; - - psMMULevelData = &psOutFaultData->sLevelData[MMU_LEVEL_1]; - psMMULevelData->uiBytesPerEntry = 1 << RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - psMMULevelData->ui32Index = ui32PTEIndex; - psMMULevelData->ui32NumOfEntries = RGX_FIRMWARE_RAW_HEAP_SIZE / ui32PageSize; - - if ((eError == PVRSRV_OK) && (pui32PageTable != NULL)) - { - psMMULevelData->ui64Address = pui32PageTable[ui32PTEIndex]; - } - else - { - psMMULevelData->ui64Address = 0U; - } - - psMMULevelData->psDebugStr = BITMASK_HAS(psMMULevelData->ui64Address, - RGXMIPSFW_TLB_VALID) ? - ("valid") : ("not valid"); -} - - diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.h b/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.h deleted file mode 100644 index b2b39402cafed..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmipsmmuinit.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific MMU initialisation for the MIPS firmware -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* NB: this file is not to be included arbitrarily. It exists solely - for the linkage between rgxinit.c and rgxmmuinit.c, the former - being otherwise cluttered by the contents of the latter */ - -#ifndef SRVKM_RGXMIPSMMUINIT_H -#define SRVKM_RGXMIPSMMUINIT_H - -#include "device.h" -#include "img_types.h" -#include "mmu_common.h" -#include "img_defs.h" -#include "rgx_mips.h" - -/* - - Labelling of fields within virtual address. No PD and PC are used currently for - the MIPS MMU -*/ -/* -Page Table entry # -*/ -#define RGX_MIPS_MMUCTRL_VADDR_PT_INDEX_SHIFT (12U) -#define RGX_MIPS_MMUCTRL_VADDR_PT_INDEX_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000FFF)) - - -/* PC entries related definitions */ -/* No PC is currently used for MIPS MMU */ -#define RGX_MIPS_MMUCTRL_PC_DATA_VALID_EN (0U) -#define RGX_MIPS_MMUCTRL_PC_DATA_VALID_SHIFT (0U) -#define RGX_MIPS_MMUCTRL_PC_DATA_VALID_CLRMSK (0U) - -#define RGX_MIPS_MMUCTRL_PC_DATA_READ_ONLY_SHIFT (0U) -#define RGX_MIPS_MMUCTRL_PC_DATA_READ_ONLY_CLRMSK (0U) -#define RGX_MIPS_MMUCTRL_PC_DATA_READ_ONLY_EN (0U) - -/* PD entries related definitions */ -/* No PD is currently used for MIPS MMU */ -#define RGX_MIPS_MMUCTRL_PD_DATA_VALID_EN (0U) -#define RGX_MIPS_MMUCTRL_PD_DATA_VALID_SHIFT (0U) -#define RGX_MIPS_MMUCTRL_PD_DATA_VALID_CLRMSK (0U) - -#define RGX_MIPS_MMUCTRL_PD_DATA_READ_ONLY_SHIFT (0U) -#define RGX_MIPS_MMUCTRL_PD_DATA_READ_ONLY_CLRMSK (0U) -#define RGX_MIPS_MMUCTRL_PD_DATA_READ_ONLY_EN (0U) - - -PVRSRV_ERROR RGXMipsMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode); -PVRSRV_ERROR RGXMipsMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode); - -void RGXMipsCheckFaultAddress(MMU_CONTEXT *psFwMMUCtx, - IMG_UINT32 ui32FwVA, - MMU_FAULT_DATA *psOutFaultData); - -#endif /* #ifndef SRVKM_RGXMIPSMMUINIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.c b/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.c deleted file mode 100644 index 629e7abdc370f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.c +++ /dev/null @@ -1,1079 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific MMU initialisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxmmuinit.h" -#include "rgxmmudefs_km.h" - -#include "device.h" -#include "img_types.h" -#include "img_defs.h" -#include "mmu_common.h" -#include "pdump_mmu.h" - -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "rgx_memallocflags.h" -#include "rgx_heaps.h" -#include "pdump_km.h" - - -/* useful macros */ -/* units represented in a bitfield */ -#define UNITS_IN_BITFIELD(Mask, Shift) ((Mask >> Shift) + 1) - - -/* - * Bits of PT, PD and PC not involving addresses - */ - -#define RGX_MMUCTRL_PTE_PROTMASK (RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN | \ - RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN | \ - RGX_MMUCTRL_PT_DATA_PM_SRC_EN | \ - RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN | \ - RGX_MMUCTRL_PT_DATA_CC_EN | \ - RGX_MMUCTRL_PT_DATA_READ_ONLY_EN | \ - RGX_MMUCTRL_PT_DATA_VALID_EN) - -#define RGX_MMUCTRL_PDE_PROTMASK (RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN | \ - ~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK | \ - RGX_MMUCTRL_PD_DATA_VALID_EN) - -#define RGX_MMUCTRL_PCE_PROTMASK (RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN | \ - RGX_MMUCTRL_PC_DATA_VALID_EN) - - - -static MMU_PxE_CONFIG sRGXMMUPCEConfig; -static MMU_DEVVADDR_CONFIG sRGXMMUTopLevelDevVAddrConfig; - - -/* - * - * Configuration for heaps with 4kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_4KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_4KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_4KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig4KB; - - -/* - * - * Configuration for heaps with 16kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_16KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_16KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_16KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig16KB; - - -/* - * - * Configuration for heaps with 64kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_64KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_64KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_64KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig64KB; - - -/* - * - * Configuration for heaps with 256kB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_256KBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_256KBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig256KB; - - -/* - * - * Configuration for heaps with 1MB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_1MBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_1MBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_1MBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig1MB; - - -/* - * - * Configuration for heaps with 2MB Data-Page size - * - */ - -static MMU_PxE_CONFIG sRGXMMUPDEConfig_2MBDP; -static MMU_PxE_CONFIG sRGXMMUPTEConfig_2MBDP; -static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_2MBDP; -static MMU_PAGESIZECONFIG gsPageSizeConfig2MB; - - -/* Forward declaration of protection bits derivation functions, for - the following structure */ -static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags); -static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags); -static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize); -static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags); - -static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize, - const MMU_PxE_CONFIG **ppsMMUPDEConfig, - const MMU_PxE_CONFIG **ppsMMUPTEConfig, - const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv); - -static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv); - -static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize); -static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize); - -static MMU_DEVICEATTRIBS sRGXMMUDeviceAttributes; - -PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* Setup of Px Entries: - * - * - * PAGE TABLE (8 Byte): - * - * | 62 | 61...40 | 39...12 (varies) | 11...6 | 5 | 4 | 3 | 2 | 1 | 0 | - * | PM/Meta protect | VP Page (39:18) | Physical Page | VP Page (17:12) | Entry Pending | PM src | SLC Bypass Ctrl | Cache Coherency | Read Only | Valid | - * - * - * PAGE DIRECTORY (8 Byte): - * - * | 40 | 39...5 (varies) | 4 | 3...1 | 0 | - * | Entry Pending | Page Table base address | (reserved) | Page Size | Valid | - * - * - * PAGE CATALOGUE (4 Byte): - * - * | 31...4 | 3...2 | 1 | 0 | - * | Page Directory base address | (reserved) | Entry Pending | Valid | - * - */ - - - /* Example how to get the PD address from a PC entry. - * The procedure is the same for PD and PT entries to retrieve PT and Page addresses: - * - * 1) sRGXMMUPCEConfig.uiAddrMask applied to PC entry with '&': - * | 31...4 | 3...2 | 1 | 0 | - * | PD Addr | 0 | 0 | 0 | - * - * 2) sRGXMMUPCEConfig.uiAddrShift applied with '>>': - * | 27...0 | - * | PD Addr | - * - * 3) sRGXMMUPCEConfig.uiAddrLog2Align applied with '<<': - * | 39...0 | - * | PD Addr | - * - */ - - - sRGXMMUDeviceAttributes.pszMMUPxPDumpMemSpaceName = - PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_GPU_LOCAL]); - - /* - * Setup sRGXMMUPCEConfig - */ - sRGXMMUPCEConfig.uiBytesPerEntry = 4; /* 32 bit entries */ - sRGXMMUPCEConfig.uiAddrMask = 0xfffffff0; /* Mask to get significant address bits of PC entry i.e. the address of the PD */ - - sRGXMMUPCEConfig.uiAddrShift = 4; /* Shift this many bits to get PD address */ - sRGXMMUPCEConfig.uiAddrLog2Align = 12; /* Alignment of PD physical addresses. */ - - sRGXMMUPCEConfig.uiProtMask = RGX_MMUCTRL_PCE_PROTMASK; /* Mask to get the status bits (pending | valid)*/ - sRGXMMUPCEConfig.uiProtShift = 0; /* Shift this many bits to get the status bits */ - - sRGXMMUPCEConfig.uiValidEnMask = RGX_MMUCTRL_PC_DATA_VALID_EN; /* Mask to get entry valid bit of the PC */ - sRGXMMUPCEConfig.uiValidEnShift = RGX_MMUCTRL_PC_DATA_VALID_SHIFT; /* Shift this many bits to get entry valid bit */ - - /* - * Setup sRGXMMUTopLevelDevVAddrConfig - */ - sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; /* Mask to get PC index applied to a 40 bit virt. device address */ - sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; /* Shift a 40 bit virt. device address by this amount to get the PC index */ - sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask, - sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift)); - - sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; /* Mask to get PD index applied to a 40 bit virt. device address */ - sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; /* Shift a 40 bit virt. device address by this amount to get the PD index */ - sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask, - sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift)); - - /* - * - * Configuration for heaps with 4kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_4KBDP - */ - sRGXMMUPDEConfig_4KBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - sRGXMMUPDEConfig_4KBDP.uiAddrShift = 12; - sRGXMMUPDEConfig_4KBDP.uiAddrLog2Align = 12; - - sRGXMMUPDEConfig_4KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_4KBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_4KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_4KBDP - */ - sRGXMMUPTEConfig_4KBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffff000); - sRGXMMUPTEConfig_4KBDP.uiAddrShift = 12; - sRGXMMUPTEConfig_4KBDP.uiAddrLog2Align = 12; /* Alignment of the physical addresses of the pages NOT PTs */ - - sRGXMMUPTEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_4KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_4KBDP - */ - sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift)); - - sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift)); - - sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask = ~RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift = RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift)); - - sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000000fff); - sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_4KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig4KB - */ - gsPageSizeConfig4KB.psPDEConfig = &sRGXMMUPDEConfig_4KBDP; - gsPageSizeConfig4KB.psPTEConfig = &sRGXMMUPTEConfig_4KBDP; - gsPageSizeConfig4KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_4KBDP; - gsPageSizeConfig4KB.uiRefCount = 0; - gsPageSizeConfig4KB.uiMaxRefCount = 0; - - - /* - * - * Configuration for heaps with 16kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_16KBDP - */ - sRGXMMUPDEConfig_16KBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - sRGXMMUPDEConfig_16KBDP.uiAddrShift = 10; - sRGXMMUPDEConfig_16KBDP.uiAddrLog2Align = 10; - - sRGXMMUPDEConfig_16KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_16KBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_16KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_16KBDP - */ - sRGXMMUPTEConfig_16KBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xffffffc000); - sRGXMMUPTEConfig_16KBDP.uiAddrShift = 14; - sRGXMMUPTEConfig_16KBDP.uiAddrLog2Align = 14; - - sRGXMMUPTEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_16KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_16KBDP - */ - sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift)); - - - sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift)); - - - sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001fc000); - sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift = 14; - sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift)); - - sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000003fff); - sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_16KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig16KB - */ - gsPageSizeConfig16KB.psPDEConfig = &sRGXMMUPDEConfig_16KBDP; - gsPageSizeConfig16KB.psPTEConfig = &sRGXMMUPTEConfig_16KBDP; - gsPageSizeConfig16KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_16KBDP; - gsPageSizeConfig16KB.uiRefCount = 0; - gsPageSizeConfig16KB.uiMaxRefCount = 0; - - - /* - * - * Configuration for heaps with 64kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_64KBDP - */ - sRGXMMUPDEConfig_64KBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - sRGXMMUPDEConfig_64KBDP.uiAddrShift = 8; - sRGXMMUPDEConfig_64KBDP.uiAddrLog2Align = 8; - - sRGXMMUPDEConfig_64KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_64KBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_64KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_64KBDP - */ - sRGXMMUPTEConfig_64KBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xffffff0000); - sRGXMMUPTEConfig_64KBDP.uiAddrShift = 16; - sRGXMMUPTEConfig_64KBDP.uiAddrLog2Align = 16; - - sRGXMMUPTEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_64KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_64KBDP - */ - sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift)); - - - sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift)); - - - sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001f0000); - sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift = 16; - sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift)); - - - sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000000ffff); - sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_64KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig64KB - */ - gsPageSizeConfig64KB.psPDEConfig = &sRGXMMUPDEConfig_64KBDP; - gsPageSizeConfig64KB.psPTEConfig = &sRGXMMUPTEConfig_64KBDP; - gsPageSizeConfig64KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_64KBDP; - gsPageSizeConfig64KB.uiRefCount = 0; - gsPageSizeConfig64KB.uiMaxRefCount = 0; - - - /* - * - * Configuration for heaps with 256kB Data-Page size - * - */ - - /* - * Setup sRGXMMUPDEConfig_256KBDP - */ - sRGXMMUPDEConfig_256KBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - sRGXMMUPDEConfig_256KBDP.uiAddrShift = 6; - sRGXMMUPDEConfig_256KBDP.uiAddrLog2Align = 6; - - sRGXMMUPDEConfig_256KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_256KBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_256KBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP - */ - sRGXMMUPTEConfig_256KBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffc0000); - sRGXMMUPTEConfig_256KBDP.uiAddrShift = 18; - sRGXMMUPTEConfig_256KBDP.uiAddrLog2Align = 18; - - sRGXMMUPTEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_256KBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_256KBDP - */ - sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift)); - - - sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift)); - - - sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001c0000); - sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift = 18; - sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift)); - - - sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000003ffff); - sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_256KBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig256KB - */ - gsPageSizeConfig256KB.psPDEConfig = &sRGXMMUPDEConfig_256KBDP; - gsPageSizeConfig256KB.psPTEConfig = &sRGXMMUPTEConfig_256KBDP; - gsPageSizeConfig256KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_256KBDP; - gsPageSizeConfig256KB.uiRefCount = 0; - gsPageSizeConfig256KB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUPDEConfig_1MBDP - */ - sRGXMMUPDEConfig_1MBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - /* - * The hardware requires that PT tables need be 1<<6 = 64 byte aligned even - * if they contain fewer entries. - */ - sRGXMMUPDEConfig_1MBDP.uiAddrShift = 6; - sRGXMMUPDEConfig_1MBDP.uiAddrLog2Align = 6; - - sRGXMMUPDEConfig_1MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_1MBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_1MBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_1MBDP - */ - sRGXMMUPTEConfig_1MBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffff00000); - sRGXMMUPTEConfig_1MBDP.uiAddrShift = 20; - sRGXMMUPTEConfig_1MBDP.uiAddrLog2Align = 20; - - sRGXMMUPTEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_1MBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_1MBDP - */ - sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift)); - - - sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift)); - - - sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000100000); - sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift = 20; - sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift)); - - - sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00000fffff); - sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_1MBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig1MB - */ - gsPageSizeConfig1MB.psPDEConfig = &sRGXMMUPDEConfig_1MBDP; - gsPageSizeConfig1MB.psPTEConfig = &sRGXMMUPTEConfig_1MBDP; - gsPageSizeConfig1MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_1MBDP; - gsPageSizeConfig1MB.uiRefCount = 0; - gsPageSizeConfig1MB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUPDEConfig_2MBDP - */ - sRGXMMUPDEConfig_2MBDP.uiBytesPerEntry = 8; - - sRGXMMUPDEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0); - /* - * The hardware requires that PT tables need be 1<<6 = 64 byte aligned even - * if they contain fewer entries. - */ - sRGXMMUPDEConfig_2MBDP.uiAddrShift = 6; - sRGXMMUPDEConfig_2MBDP.uiAddrLog2Align = 6; - - sRGXMMUPDEConfig_2MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e); - sRGXMMUPDEConfig_2MBDP.uiVarCtrlShift = 1; - - sRGXMMUPDEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK; - sRGXMMUPDEConfig_2MBDP.uiProtShift = 0; - - sRGXMMUPDEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN; - sRGXMMUPDEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUPTEConfig_2MBDP - */ - sRGXMMUPTEConfig_2MBDP.uiBytesPerEntry = 8; - - sRGXMMUPTEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xffffe00000); - sRGXMMUPTEConfig_2MBDP.uiAddrShift = 21; - sRGXMMUPTEConfig_2MBDP.uiAddrLog2Align = 21; - - sRGXMMUPTEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK; - sRGXMMUPTEConfig_2MBDP.uiProtShift = 0; - - sRGXMMUPTEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN; - sRGXMMUPTEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT; - - /* - * Setup sRGXMMUDevVAddrConfig_2MBDP - */ - sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask, - sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift)); - - - sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; - sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask, - sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift)); - - - sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000000000); - sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift = 21; - sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask, - sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift)); - - - sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00001fffff); - sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetShift = 0; - sRGXMMUDevVAddrConfig_2MBDP.uiOffsetInBytes = 0; - - /* - * Setup gsPageSizeConfig2MB - */ - gsPageSizeConfig2MB.psPDEConfig = &sRGXMMUPDEConfig_2MBDP; - gsPageSizeConfig2MB.psPTEConfig = &sRGXMMUPTEConfig_2MBDP; - gsPageSizeConfig2MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_2MBDP; - gsPageSizeConfig2MB.uiRefCount = 0; - gsPageSizeConfig2MB.uiMaxRefCount = 0; - - /* - * Setup sRGXMMUDeviceAttributes - */ - sRGXMMUDeviceAttributes.eMMUType = PDUMP_MMU_TYPE_VARPAGE_40BIT; - sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3; - sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT; - sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig; - sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig; - - /* Functions for deriving page table/dir/cat protection bits */ - sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8; - sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4; - sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8; - sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4; - sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8; - sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4; - - /* Functions for establishing configurations for PDE/PTE/DEVVADDR - on per-heap basis */ - sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB; - sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB; - - sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE4 = RGXGetPageSizeFromPDE4; - sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE8 = RGXGetPageSizeFromPDE8; - sRGXMMUDeviceAttributes.pfnGetPageSizeFromVirtAddr = NULL; - - psDeviceNode->psMMUDevAttrs = &sRGXMMUDeviceAttributes; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - eError = PVRSRV_OK; - -#if defined(PDUMP) - psDeviceNode->pfnMMUGetContextID = NULL; -#endif - - psDeviceNode->psMMUDevAttrs = NULL; - -#if defined(DEBUG) - PVR_DPF((PVR_DBG_MESSAGE, "Variable Page Size Heap Stats:")); - PVR_DPF((PVR_DBG_MESSAGE, "Max 4K page heaps: %d", - gsPageSizeConfig4KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 4K page heaps (should be 0): %d", - gsPageSizeConfig4KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 16K page heaps: %d", - gsPageSizeConfig16KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 16K page heaps (should be 0): %d", - gsPageSizeConfig16KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 64K page heaps: %d", - gsPageSizeConfig64KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 64K page heaps (should be 0): %d", - gsPageSizeConfig64KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 256K page heaps: %d", - gsPageSizeConfig256KB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 256K page heaps (should be 0): %d", - gsPageSizeConfig256KB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 1M page heaps: %d", - gsPageSizeConfig1MB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 1M page heaps (should be 0): %d", - gsPageSizeConfig1MB.uiRefCount)); - PVR_DPF((PVR_DBG_MESSAGE, "Max 2M page heaps: %d", - gsPageSizeConfig2MB.uiMaxRefCount)); - PVR_DPF((PVR_DBG_VERBOSE, "Current 2M page heaps (should be 0): %d", - gsPageSizeConfig2MB.uiRefCount)); -#endif - if (gsPageSizeConfig4KB.uiRefCount > 0 || - gsPageSizeConfig16KB.uiRefCount > 0 || - gsPageSizeConfig64KB.uiRefCount > 0 || - gsPageSizeConfig256KB.uiRefCount > 0 || - gsPageSizeConfig1MB.uiRefCount > 0 || - gsPageSizeConfig2MB.uiRefCount > 0 - ) - { - PVR_DPF((PVR_DBG_ERROR, "RGXMMUInit_Unregister: Unbalanced MMU API Usage (Internal error)")); - } - - return eError; -} - -/*************************************************************************/ /*! -@Function RGXDerivePCEProt4 -@Description calculate the PCE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags) -{ - return (uiProtFlags & MMU_PROTFLAGS_INVALID)?0:RGX_MMUCTRL_PC_DATA_VALID_EN; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePCEProt8 -@Description calculate the PCE protection flags based on an 8 byte entry -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize); - - PVR_DPF((PVR_DBG_ERROR, "8-byte PCE not supported on this device")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePDEProt4 -@Description derive the PDE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device")); - return 0; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePDEProt8 -@Description derive the PDE protection flags based on an 8 byte entry - -@Input uiLog2DataPageSize The log2 of the required page size. - E.g, for 4KiB pages, this parameter must be 12. - For 2MiB pages, it must be set to 21. - -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - IMG_UINT64 ret_value = 0; /* 0 means invalid */ - - if (!(uiProtFlags & MMU_PROTFLAGS_INVALID)) /* if not invalid */ - { - switch (uiLog2DataPageSize) - { - case RGX_HEAP_4KB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB; - break; - case RGX_HEAP_16KB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB; - break; - case RGX_HEAP_64KB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB; - break; - case RGX_HEAP_256KB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB; - break; - case RGX_HEAP_1MB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB; - break; - case RGX_HEAP_2MB_PAGE_SHIFT: - ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "%s:%d: in function<%s>: Invalid parameter log2_page_size. Expected {12, 14, 16, 18, 20, 21}. Got [%u]", - __FILE__, __LINE__, __func__, uiLog2DataPageSize)); - } - } - return ret_value; -} - - -/*************************************************************************/ /*! -@Function RGXDerivePTEProt4 -@Description calculate the PTE protection flags based on a 4 byte entry -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags) -{ - PVR_UNREFERENCED_PARAMETER(uiProtFlags); - PVR_DPF((PVR_DBG_ERROR, "4-byte PTE not supported on this device")); - - return 0; -} - -/*************************************************************************/ /*! -@Function RGXDerivePTEProt8 -@Description calculate the PTE protection flags based on an 8 byte entry -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize) -{ - IMG_UINT64 ui64MMUFlags=0; - - PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize); - - if (((MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE) & uiProtFlags) == (MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE)) - { - /* read/write */ - } - else if (MMU_PROTFLAGS_READABLE & uiProtFlags) - { - /* read only */ - ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_READ_ONLY_EN; - } - else if (MMU_PROTFLAGS_WRITEABLE & uiProtFlags) - { - /* write only */ - PVR_DPF((PVR_DBG_WARNING, "RGXDerivePTEProt8: write-only is not possible on this device")); - } - else if ((MMU_PROTFLAGS_INVALID & uiProtFlags) == 0) - { - PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: neither read nor write specified...")); - } - - /* cache coherency */ - if (MMU_PROTFLAGS_CACHE_COHERENT & uiProtFlags) - { - ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_CC_EN; - } - - /* cache setup */ - if ((MMU_PROTFLAGS_CACHED & uiProtFlags) == 0) - { - ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN; - } - - if ((uiProtFlags & MMU_PROTFLAGS_INVALID) == 0) - { - ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_VALID_EN; - } - - if (MMU_PROTFLAGS_DEVICE(PMMETA_PROTECT) & uiProtFlags) - { - ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN; - } - - return ui64MMUFlags; -} - - -/*************************************************************************/ /*! -@Function RGXGetPageSizeConfig -@Description Set up configuration for variable sized data pages. - RGXPutPageSizeConfigCB has to be called to ensure correct - refcounting. -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize, - const MMU_PxE_CONFIG **ppsMMUPDEConfig, - const MMU_PxE_CONFIG **ppsMMUPTEConfig, - const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig, - IMG_HANDLE *phPriv) -{ - MMU_PAGESIZECONFIG *psPageSizeConfig; - - switch (uiLog2DataPageSize) - { - case RGX_HEAP_4KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig4KB; - break; - case RGX_HEAP_16KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig16KB; - break; - case RGX_HEAP_64KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig64KB; - break; - case RGX_HEAP_256KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig256KB; - break; - case RGX_HEAP_1MB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig1MB; - break; - case RGX_HEAP_2MB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig2MB; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "RGXGetPageSizeConfigCB: Invalid Data Page Size 1<<0x%x", - uiLog2DataPageSize)); - *phPriv = NULL; - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; - } - - /* Refer caller's pointers to the data */ - *ppsMMUPDEConfig = psPageSizeConfig->psPDEConfig; - *ppsMMUPTEConfig = psPageSizeConfig->psPTEConfig; - *ppsMMUDevVAddrConfig = psPageSizeConfig->psDevVAddrConfig; - -#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT) - /* Increment ref-count - not that we're allocating anything here - (I'm using static structs), but one day we might, so we want - the Get/Put code to be balanced properly */ - psPageSizeConfig->uiRefCount++; - - /* This is purely for debug statistics */ - psPageSizeConfig->uiMaxRefCount = MAX(psPageSizeConfig->uiMaxRefCount, - psPageSizeConfig->uiRefCount); -#endif - - *phPriv = (IMG_HANDLE)(uintptr_t)uiLog2DataPageSize; - PVR_ASSERT (uiLog2DataPageSize == (IMG_UINT32)(uintptr_t)*phPriv); - - return PVRSRV_OK; -} - -/*************************************************************************/ /*! -@Function RGXPutPageSizeConfig -@Description Tells this code that the mmu module is done with the - configurations set in RGXGetPageSizeConfig. This can - be a no-op. - Called after RGXGetPageSizeConfigCB. -@Return PVRSRV_ERROR - */ /**************************************************************************/ -static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv) -{ -#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT) - MMU_PAGESIZECONFIG *psPageSizeConfig; - IMG_UINT32 uiLog2DataPageSize; - - uiLog2DataPageSize = (IMG_UINT32)(uintptr_t) hPriv; - - switch (uiLog2DataPageSize) - { - case RGX_HEAP_4KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig4KB; - break; - case RGX_HEAP_16KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig16KB; - break; - case RGX_HEAP_64KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig64KB; - break; - case RGX_HEAP_256KB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig256KB; - break; - case RGX_HEAP_1MB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig1MB; - break; - case RGX_HEAP_2MB_PAGE_SHIFT: - psPageSizeConfig = &gsPageSizeConfig2MB; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "RGXPutPageSizeConfigCB: Invalid Data Page Size 1<<0x%x", - uiLog2DataPageSize)); - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; - } - - /* Ref-count here is not especially useful, but it's an extra - check that the API is being used correctly */ - psPageSizeConfig->uiRefCount--; -#else - PVR_UNREFERENCED_PARAMETER(hPriv); -#endif - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize) -{ - PVR_UNREFERENCED_PARAMETER(ui32PDE); - PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize); - PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device")); - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; -} - -static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize) -{ - switch (ui64PDE & (~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK)) - { - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB: - *pui32Log2PageSize = RGX_HEAP_4KB_PAGE_SHIFT; - break; - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB: - *pui32Log2PageSize = RGX_HEAP_16KB_PAGE_SHIFT; - break; - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB: - *pui32Log2PageSize = RGX_HEAP_64KB_PAGE_SHIFT; - break; - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB: - *pui32Log2PageSize = RGX_HEAP_256KB_PAGE_SHIFT; - break; - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB: - *pui32Log2PageSize = RGX_HEAP_1MB_PAGE_SHIFT; - break; - case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB: - *pui32Log2PageSize = RGX_HEAP_2MB_PAGE_SHIFT; - break; - default: - return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE; - } - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.h b/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.h deleted file mode 100644 index 0591628d6ad3e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmmuinit.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific MMU initialisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* NB: this file is not to be included arbitrarily. It exists solely - for the linkage between rgxinit.c and rgxmmuinit.c, the former - being otherwise cluttered by the contents of the latter */ - -#ifndef SRVKM_RGXMMUINIT_H -#define SRVKM_RGXMMUINIT_H - -#include "device.h" -#include "img_types.h" -#include "mmu_common.h" -#include "img_defs.h" - -PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode); -PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode); - - -#endif /* #ifndef SRVKM_RGXMMUINIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.c b/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.c deleted file mode 100644 index a888e70015db0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.c +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************/ /*! -@File rgxmulticore.c -@Title Functions related to multicore devices -@Codingstyle IMG -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Kernel mode workload estimation functionality. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxdevice.h" -#include "rgxdefs_km.h" -#include "pdump_km.h" -#include "rgxmulticore.h" -#include "multicore_defs.h" -#include "allocmem.h" -#include "pvr_debug.h" - -/* - * check that register defines match our hardcoded definitions. - * Rogue has these, volcanic does not. - */ -#if ((RGX_MULTICORE_CAPABILITY_FRAGMENT_EN != RGX_CR_MULTICORE_GPU_CAPABILITY_FRAGMENT_EN) || \ - (RGX_MULTICORE_CAPABILITY_GEOMETRY_EN != RGX_CR_MULTICORE_GPU_CAPABILITY_GEOMETRY_EN) || \ - (RGX_MULTICORE_CAPABILITY_COMPUTE_EN != RGX_CR_MULTICORE_GPU_CAPABILITY_COMPUTE_EN) || \ - (RGX_MULTICORE_CAPABILITY_PRIMARY_EN != RGX_CR_MULTICORE_GPU_CAPABILITY_PRIMARY_EN) || \ - (RGX_MULTICORE_ID_CLRMSK != RGX_CR_MULTICORE_GPU_ID_CLRMSK)) -#error "Rogue definitions for RGX_CR_MULTICORE_GPU register have changed" -#endif - - -static PVRSRV_ERROR RGXGetMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CapsSize, - IMG_UINT32 *pui32NumCores, - IMG_UINT64 *pui64Caps); - - -/* - * RGXInitMultiCoreInfo: - * Return multicore information to clients. - * Return not_supported on cores without multicore. - */ -static PVRSRV_ERROR RGXGetMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CapsSize, - IMG_UINT32 *pui32NumCores, - IMG_UINT64 *pui64Caps) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psDeviceNode->ui32MultiCoreNumCores == 0) - { - /* MULTICORE not supported on this device */ - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - else - { - *pui32NumCores = psDeviceNode->ui32MultiCoreNumCores; - if (ui32CapsSize > 0) - { - if (ui32CapsSize < psDeviceNode->ui32MultiCoreNumCores) - { - PVR_DPF((PVR_DBG_ERROR, "Multicore caps buffer too small")); - eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - } - else - { - IMG_UINT32 i; - - for (i = 0; i < psDeviceNode->ui32MultiCoreNumCores; ++i) - { - pui64Caps[i] = psDeviceNode->pui64MultiCoreCapabilities[i]; - } - } - } - } - - return eError; -} - - - -/* - * RGXInitMultiCoreInfo: - * Read multicore HW registers and fill in data structure for clients. - * Return not supported on cores without multicore. - */ -PVRSRV_ERROR RGXInitMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psDeviceNode->pfnGetMultiCoreInfo != NULL) - { - /* we only set this up once */ - return PVRSRV_OK; - } - - /* defaults for non-multicore devices */ - psDeviceNode->ui32MultiCoreNumCores = 0; - psDeviceNode->ui32MultiCorePrimaryId = (IMG_UINT32)(-1); - psDeviceNode->pui64MultiCoreCapabilities = NULL; - psDeviceNode->pfnGetMultiCoreInfo = NULL; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { - IMG_UINT32 ui32MulticoreRegBankOffset = (1 << RGX_GET_FEATURE_VALUE(psDevInfo, XPU_MAX_REGBANKS_ADDR_WIDTH)); - IMG_UINT32 ui32MulticoreGPUReg = RGX_CR_MULTICORE_GPU; - IMG_UINT32 ui32NumCores; - IMG_UINT32 i; - - ui32NumCores = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MULTICORE_SYSTEM); -#if !defined(NO_HARDWARE) - /* check that the number of cores reported is in-bounds */ - if (ui32NumCores > (RGX_CR_MULTICORE_SYSTEM_MASKFULL >> RGX_CR_MULTICORE_SYSTEM_GPU_COUNT_SHIFT)) - { - PVR_DPF((PVR_DBG_ERROR, "invalid return (%u) read from MULTICORE_SYSTEM", ui32NumCores)); - return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; - } -#else - /* for nohw set to max so clients can allocate enough memory for all pdump runs on any config */ - ui32NumCores = RGX_MULTICORE_MAX_NOHW_CORES; -#endif - PVR_DPF((PVR_DBG_MESSAGE, "Multicore system has %u cores", ui32NumCores)); - PDUMPCOMMENT(psDeviceNode, "RGX Multicore has %d cores\n", ui32NumCores); - - /* allocate storage for capabilities */ - psDeviceNode->pui64MultiCoreCapabilities = OSAllocMem(ui32NumCores * sizeof(psDeviceNode->pui64MultiCoreCapabilities[0])); - if (psDeviceNode->pui64MultiCoreCapabilities == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to alloc memory for Multicore info", __func__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psDeviceNode->ui32MultiCoreNumCores = ui32NumCores; - - for (i = 0; i < ui32NumCores; ++i) - { - #if !defined(NO_HARDWARE) - psDeviceNode->pui64MultiCoreCapabilities[i] = - OSReadHWReg64(psDevInfo->pvRegsBaseKM, ui32MulticoreGPUReg) & RGX_CR_MULTICORE_GPU_MASKFULL; - #else - /* emulation for what we think caps are */ - psDeviceNode->pui64MultiCoreCapabilities[i] = - i | ((i == 0) ? (RGX_MULTICORE_CAPABILITY_PRIMARY_EN - | RGX_MULTICORE_CAPABILITY_GEOMETRY_EN) : 0) - | RGX_MULTICORE_CAPABILITY_COMPUTE_EN - | RGX_MULTICORE_CAPABILITY_FRAGMENT_EN; - #endif - PVR_DPF((PVR_DBG_MESSAGE, "Core %d has capabilities value 0x%x", i, (IMG_UINT32)psDeviceNode->pui64MultiCoreCapabilities[i] )); - PDUMPCOMMENT(psDeviceNode, "\tCore %d has caps 0x%08x\n", i, - (IMG_UINT32)psDeviceNode->pui64MultiCoreCapabilities[i]); - - if (psDeviceNode->pui64MultiCoreCapabilities[i] & RGX_CR_MULTICORE_GPU_CAPABILITY_PRIMARY_EN) - { - psDeviceNode->ui32MultiCorePrimaryId = (psDeviceNode->pui64MultiCoreCapabilities[i] - & ~RGX_CR_MULTICORE_GPU_ID_CLRMSK) - >> RGX_CR_MULTICORE_GPU_ID_SHIFT; - } - - ui32MulticoreGPUReg += ui32MulticoreRegBankOffset; - } - - /* Register callback to return info about multicore setup to client bridge */ - psDeviceNode->pfnGetMultiCoreInfo = RGXGetMultiCoreInfo; - } - else - { - /* MULTICORE not supported on this device */ - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - - return eError; -} - - -/* - * RGXDeinitMultiCoreInfo: - * Release resources and clear the MultiCore values in the DeviceNode. - */ -void RGXDeInitMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->pui64MultiCoreCapabilities != NULL) - { - OSFreeMem(psDeviceNode->pui64MultiCoreCapabilities); - psDeviceNode->pui64MultiCoreCapabilities = NULL; - psDeviceNode->ui32MultiCoreNumCores = 0; - psDeviceNode->ui32MultiCorePrimaryId = (IMG_UINT32)(-1); - } - psDeviceNode->pfnGetMultiCoreInfo = NULL; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.h b/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.h deleted file mode 100644 index b45a20ab5e14c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxmulticore.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ /*! -@File rgxmulticore.h -@Title Functions related to multicore devices -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description General purpose memory shared between kernel driver and user - mode. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXMULTICORE_H -#define RGXMULTICORE_H - -#include "pvrsrv_error.h" -#include "pvrsrv.h" - -PVRSRV_ERROR RGXInitMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode); -void RGXDeInitMultiCoreInfo(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* RGXMULTICORE_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxpdump.c b/drivers/gpu/drm/img-rogue/1.17/rgxpdump.c deleted file mode 100644 index 750281d82ebe4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxpdump.c +++ /dev/null @@ -1,708 +0,0 @@ -/*************************************************************************/ /*! -@File rgxpdump.c -@Title Device specific pdump routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific pdump functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(PDUMP) -#include "pvrsrv.h" -#include "devicemem_pdump.h" -#include "rgxpdump.h" -#include "rgx_bvnc_defs_km.h" -#include "pdumpdesc.h" - -/* - * There are two different set of functions one for META/RISCV and one for MIPS - * because the Pdump player does not implement the support for - * the MIPS MMU yet. So for MIPS builds we cannot use DevmemPDumpSaveToFileVirtual, - * we have to use DevmemPDumpSaveToFile instead. - */ -static PVRSRV_ERROR _FWDumpSignatureBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PDUMPIF(psDeviceNode, "DISABLE_SIGNATURE_BUFFER_DUMP", ui32PDumpFlags); - PDUMPELSE(psDeviceNode, "DISABLE_SIGNATURE_BUFFER_DUMP", ui32PDumpFlags); - -#if defined(SUPPORT_FIRMWARE_GCOV) - /* Gcov */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Gcov Buffer"); - DevmemPDumpSaveToFileVirtual(psDevInfo->psFirmwareGcovBufferMemDesc, - 0, - psDevInfo->ui32FirmwareGcovSize, - "firmware_gcov.img", - 0, - ui32PDumpFlags); -#endif - /* TA signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump TA signatures and checksums Buffer"); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSigTAChecksMemDesc, - 0, - psDevInfo->ui32SigTAChecksSize, - "out.tasig", - 0, - ui32PDumpFlags); - - /* 3D signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump 3D signatures and checksums Buffer"); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSig3DChecksMemDesc, - 0, - psDevInfo->ui32Sig3DChecksSize, - "out.3dsig", - 0, - ui32PDumpFlags); - -#if defined(RGX_FEATURE_TDM_PDS_CHECKSUM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TDM_PDS_CHECKSUM)) - { - /* TDM signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump TDM signatures and checksums Buffer"); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSigTDM2DChecksMemDesc, - 0, - psDevInfo->ui32SigTDM2DChecksSize, - "out.tdmsig", - 0, - ui32PDumpFlags); - } -#endif - - PDUMPFI(psDeviceNode, "DISABLE_SIGNATURE_BUFFER_DUMP", ui32PDumpFlags); - - return PVRSRV_OK; -} -static PVRSRV_ERROR _FWDumpTraceBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 ui32ThreadNum, ui32Size, ui32OutFileOffset; - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - /* Dump trace buffers */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump trace buffers"); - for (ui32ThreadNum = 0, ui32OutFileOffset = 0; ui32ThreadNum < RGXFW_THREAD_NUM; ui32ThreadNum++) - { - /* - * Some compilers cannot cope with the use of offsetof() below - the specific problem being the use of - * a non-const variable in the expression, which it needs to be const. Typical compiler error produced is - * "expression must have a constant value". - */ - const IMG_DEVMEM_OFFSET_T uiTraceBufThreadNumOff - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_TRACEBUF *)0)->sTraceBuf[ui32ThreadNum]); - - /* ui32TracePointer tracepointer */ - ui32Size = sizeof(IMG_UINT32); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - uiTraceBufThreadNumOff, - ui32Size, - "out.trace", - ui32OutFileOffset, - ui32PDumpFlags); - ui32OutFileOffset += ui32Size; - - /* next, dump size of trace buffer in DWords */ - ui32Size = sizeof(IMG_UINT32); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - offsetof(RGXFWIF_TRACEBUF, ui32TraceBufSizeInDWords), - ui32Size, - "out.trace", - ui32OutFileOffset, - ui32PDumpFlags); - ui32OutFileOffset += ui32Size; - - /* trace buffer */ - ui32Size = psDevInfo->psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords * sizeof(IMG_UINT32); - PVR_ASSERT(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32ThreadNum]); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32ThreadNum], - 0, /* 0 offset in the trace buffer mem desc */ - ui32Size, - "out.trace", - ui32OutFileOffset, - ui32PDumpFlags); - ui32OutFileOffset += ui32Size; - - /* assert info buffer */ - ui32Size = RGXFW_TRACE_BUFFER_ASSERT_SIZE * sizeof(IMG_CHAR) - + RGXFW_TRACE_BUFFER_ASSERT_SIZE * sizeof(IMG_CHAR) - + sizeof(IMG_UINT32); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - offsetof(RGXFWIF_TRACEBUF, sTraceBuf) /* move to first element of sTraceBuf */ - + ui32ThreadNum * sizeof(RGXFWIF_TRACEBUF_SPACE) /* skip required number of sTraceBuf elements */ - + offsetof(RGXFWIF_TRACEBUF_SPACE, sAssertBuf), /* offset into its sAssertBuf, to be pdumped */ - ui32Size, - "out.trace", - ui32OutFileOffset, - ui32PDumpFlags); - ui32OutFileOffset += ui32Size; - } - - /* FW HWPerf buffer is always allocated when PDUMP is defined, irrespective of HWPerf events being enabled/disabled */ - PVR_ASSERT(psDevInfo->psRGXFWIfHWPerfBufMemDesc); - - /* Dump hwperf buffer */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump HWPerf Buffer"); - DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfHWPerfBufMemDesc, - 0, - psDevInfo->ui32RGXFWIfHWPerfBufSize, - "out.hwperf", - 0, - ui32PDumpFlags); - - return PVRSRV_OK; - -} - - -static PVRSRV_ERROR _MipsDumpSignatureBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* TA signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump TA signatures and checksums Buffer"); - - DevmemPDumpSaveToFile(psDevInfo->psRGXFWSigTAChecksMemDesc, - 0, - psDevInfo->ui32SigTAChecksSize, - "out.tasig", - 0); - - /* 3D signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump 3D signatures and checksums Buffer"); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWSig3DChecksMemDesc, - 0, - psDevInfo->ui32Sig3DChecksSize, - "out.3dsig", - 0); - -#if defined(RGX_FEATURE_TDM_PDS_CHECKSUM_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TDM_PDS_CHECKSUM)) - { - /* TDM signatures */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump TDM signatures and checksums Buffer"); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWSigTDM2DChecksMemDesc, - 0, - psDevInfo->ui32SigTDM2DChecksSize, - "out.tdmsig", - 0); - } -#endif - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _MipsDumpTraceBufferKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - IMG_UINT32 ui32ThreadNum, ui32Size, ui32OutFileOffset; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVR_UNREFERENCED_PARAMETER(psConnection); - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - /* Dump trace buffers */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump trace buffers"); - for (ui32ThreadNum = 0, ui32OutFileOffset = 0; ui32ThreadNum < RGXFW_THREAD_NUM; ui32ThreadNum++) - { - /* - * Some compilers cannot cope with the use of offsetof() below - the specific problem being the use of - * a non-const variable in the expression, which it needs to be const. Typical compiler error produced is - * "expression must have a constant value". - */ - const IMG_DEVMEM_OFFSET_T uiTraceBufOff - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_TRACEBUF *)0)->sTraceBuf[ui32ThreadNum]); - - /* Same again... */ - const IMG_DEVMEM_OFFSET_T uiTraceBufSpaceAssertBufOff - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_TRACEBUF_SPACE *)0)->sAssertBuf); - - /* ui32TracePointer tracepointer */ - ui32Size = sizeof(IMG_UINT32); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - uiTraceBufOff, - ui32Size, - "out.trace", - ui32OutFileOffset); - ui32OutFileOffset += ui32Size; - - /* next, dump size of trace buffer in DWords */ - ui32Size = sizeof(IMG_UINT32); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - offsetof(RGXFWIF_TRACEBUF, ui32TraceBufSizeInDWords), - ui32Size, - "out.trace", - ui32OutFileOffset); - ui32OutFileOffset += ui32Size; - - /* trace buffer */ - ui32Size = psDevInfo->psRGXFWIfTraceBufCtl->ui32TraceBufSizeInDWords * sizeof(IMG_UINT32); - PVR_ASSERT(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32ThreadNum]); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32ThreadNum], - 0, /* 0 offset in the trace buffer mem desc */ - ui32Size, - "out.trace", - ui32OutFileOffset); - ui32OutFileOffset += ui32Size; - - /* assert info buffer */ - ui32Size = RGXFW_TRACE_BUFFER_ASSERT_SIZE * sizeof(IMG_CHAR) - + RGXFW_TRACE_BUFFER_ASSERT_SIZE * sizeof(IMG_CHAR) - + sizeof(IMG_UINT32); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWIfTraceBufCtlMemDesc, - uiTraceBufOff + uiTraceBufSpaceAssertBufOff, - ui32Size, - "out.trace", - ui32OutFileOffset); - ui32OutFileOffset += ui32Size; - } - - /* Dump hwperf buffer */ - PDumpCommentWithFlags(psDeviceNode, ui32PDumpFlags, "** Dump HWPerf Buffer"); - DevmemPDumpSaveToFile(psDevInfo->psRGXFWIfHWPerfBufMemDesc, - 0, - psDevInfo->ui32RGXFWIfHWPerfBufSize, - "out.hwperf", - 0); - - return PVRSRV_OK; - -} - - -/* - * PVRSRVPDumpSignatureBufferKM - */ -PVRSRV_ERROR PVRSRVPDumpSignatureBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - if ((psDeviceNode->pfnCheckDeviceFeature) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, MIPS)) - { - return _MipsDumpSignatureBufferKM(psConnection, - psDeviceNode, - ui32PDumpFlags); - } - else - { - return _FWDumpSignatureBufferKM(psConnection, - psDeviceNode, - ui32PDumpFlags); - } -} - - -#if defined(SUPPORT_VALIDATION) -PVRSRV_ERROR PVRSRVPDumpComputeCRCSignatureCheckKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - - if (!(RGX_IS_FEATURE_SUPPORTED(psDevInfo, COMPUTE))) - { - return PVRSRV_ERROR_NOT_SUPPORTED; - } - - /* - * Add a PDUMP POLL on the KZ signature check status. - */ - if (psDevInfo->ui32ValidationFlags & RGX_VAL_KZ_SIG_CHECK_NOERR_EN) - { - PDUMPCOMMENT(psDeviceNode, "Verify KZ Signature: match required"); - eError = PDUMPREGPOL(psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_SCRATCH11, - 1U, - 0xFFFFFFFF, - ui32PDumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - } - else if (psDevInfo->ui32ValidationFlags & RGX_VAL_KZ_SIG_CHECK_ERR_EN) - { - PDUMPCOMMENT(psDeviceNode, "Verify KZ Signature: mismatch required"); - eError = PDUMPREGPOL(psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_SCRATCH11, - 2U, - 0xFFFFFFFF, - ui32PDumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - } - PVR_UNREFERENCED_PARAMETER(psConnection); - - return PVRSRV_OK; -} -#endif - -PVRSRV_ERROR PVRSRVPDumpCRCSignatureCheckKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - - return PVRSRV_OK; -} - - -/* - * PVRSRVPDumpValCheckPreCommand - */ -PVRSRV_ERROR PVRSRVPDumpValCheckPreCommandKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - PVR_UNREFERENCED_PARAMETER(psConnection); - - return PVRSRV_OK; -} - -/* - * PVRSRVPDumpValCheckPostCommand - */ -PVRSRV_ERROR PVRSRVPDumpValCheckPostCommandKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - PVR_UNREFERENCED_PARAMETER(psConnection); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR PVRSRVPDumpTraceBufferKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - if ((psDeviceNode->pfnCheckDeviceFeature) && - PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, MIPS)) - { - return _MipsDumpTraceBufferKM(psConnection, psDeviceNode, ui32PDumpFlags); - } - else - { - return _FWDumpTraceBufferKM(psConnection, psDeviceNode, ui32PDumpFlags); - } -} - -PVRSRV_ERROR RGXPDumpPrepareOutputImageDescriptorHdr(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_PBYTE pbyPDumpImageHdr) -{ - IMG_PUINT32 pui32Word; - IMG_UINT32 ui32HeaderDataSize; - -#if defined(RGX_FEATURE_TFBC_LOSSY_37_PERCENT_BIT_MASK) || defined(RGX_FEATURE_TFBC_DELTA_CORRELATION_BIT_MASK) || defined(RGX_FEATURE_TFBC_NATIVE_YUV10_BIT_MASK) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_UINT32 ui32TFBCControl = (psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlagsExt & RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK) >> - RGXFWIF_INICFG_EXT_TFBC_CONTROL_SHIFT; -#endif - - /* Validate parameters */ - if (((IMAGE_HEADER_SIZE & ~(HEADER_WORD1_SIZE_CLRMSK >> HEADER_WORD1_SIZE_SHIFT)) != 0) || - ((IMAGE_HEADER_VERSION & ~(HEADER_WORD1_VERSION_CLRMSK >> HEADER_WORD1_VERSION_SHIFT)) != 0)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - memset(pbyPDumpImageHdr, 0, IMAGE_HEADER_SIZE); - - pui32Word = IMG_OFFSET_ADDR(pbyPDumpImageHdr, 0); - pui32Word[0] = (IMAGE_HEADER_TYPE << HEADER_WORD0_TYPE_SHIFT); - pui32Word[1] = (IMAGE_HEADER_SIZE << HEADER_WORD1_SIZE_SHIFT) | - (IMAGE_HEADER_VERSION << HEADER_WORD1_VERSION_SHIFT); - - ui32HeaderDataSize = ui32DataSize; - if (eFBCompression != IMG_FB_COMPRESSION_NONE) - { - ui32HeaderDataSize += ui32HeaderSize; - } - pui32Word[2] = ui32HeaderDataSize << HEADER_WORD2_DATA_SIZE_SHIFT; - - pui32Word[3] = ui32LogicalWidth << IMAGE_HEADER_WORD3_LOGICAL_WIDTH_SHIFT; - pui32Word[4] = ui32LogicalHeight << IMAGE_HEADER_WORD4_LOGICAL_HEIGHT_SHIFT; - - pui32Word[5] = ePixFmt << IMAGE_HEADER_WORD5_FORMAT_SHIFT; - - pui32Word[6] = ui32PhysicalWidth << IMAGE_HEADER_WORD6_PHYSICAL_WIDTH_SHIFT; - pui32Word[7] = ui32PhysicalHeight << IMAGE_HEADER_WORD7_PHYSICAL_HEIGHT_SHIFT; - - pui32Word[8] = IMAGE_HEADER_WORD8_STRIDE_POSITIVE | IMAGE_HEADER_WORD8_BIFTYPE_NONE; - - switch (eMemLayout) - { - case IMG_MEMLAYOUT_STRIDED: - pui32Word[8] |= IMAGE_HEADER_WORD8_TWIDDLING_STRIDED; - break; - case IMG_MEMLAYOUT_TWIDDLED: - pui32Word[8] |= IMAGE_HEADER_WORD8_TWIDDLING_NTWIDDLE; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "Unsupported memory layout - %d", eMemLayout)); - return PVRSRV_ERROR_UNSUPPORTED_MEMORY_LAYOUT; - } - - pui32Word[9] = 0; - if (eFBCompression != IMG_FB_COMPRESSION_NONE) - { - switch (PVRSRV_GET_DEVICE_FEATURE_VALUE(psDeviceNode, FBCDC_ALGORITHM)) - { - case 1: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCCOMPAT_BASE; - break; - case 2: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCCOMPAT_V2; - break; - case 3: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCCOMPAT_V3_0_LAYOUT2; - break; - case 4: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCCOMPAT_V4; - - if (eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) - { - pui32Word[9] |= IMAGE_HEADER_WORD9_LOSSY_ON; - } - - pui32Word[9] |= (eFBCSwizzle << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT) & IMAGE_HEADER_WORD9_SWIZZLE_CLRMSK; - - break; - case 50: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCCOMPAT_TFBC; - - if (eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) - { - pui32Word[9] |= IMAGE_HEADER_WORD9_LOSSY_25; - } - - if (eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) - { - pui32Word[9] |= IMAGE_HEADER_WORD9_LOSSY_37; - } - - if (eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) - { - pui32Word[9] |= IMAGE_HEADER_WORD9_LOSSY_50; - } - - if (eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4 || - eFBCompression == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) - { - pui32Word[9] |= IMAGE_HEADER_WORD9_LOSSY_75; - } - - break; - default: - PVR_DPF((PVR_DBG_ERROR, "Unsupported algorithm - %d", - PVRSRV_GET_DEVICE_FEATURE_VALUE(psDeviceNode, FBCDC_ALGORITHM))); - return PVRSRV_ERROR_NOT_ENABLED; - } - } - - switch (GET_FBCDC_BLOCK_TYPE(eFBCompression)) - { - case IMG_FB_COMPRESSION_NONE: - break; - case IMG_FB_COMPRESSION_DIRECT_8x8: - pui32Word[8] |= IMAGE_HEADER_WORD8_FBCTYPE_8X8; - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCDECOR_ENABLE; - break; - case IMG_FB_COMPRESSION_DIRECT_16x4: - pui32Word[8] |= IMAGE_HEADER_WORD8_FBCTYPE_16x4; - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCDECOR_ENABLE; - break; - case IMG_FB_COMPRESSION_DIRECT_32x2: - pui32Word[9] |= IMAGE_HEADER_WORD9_FBCDECOR_ENABLE; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "Unsupported compression mode - %d", eFBCompression)); - return PVRSRV_ERROR_UNSUPPORTED_FB_COMPRESSION_MODE; - } - - pui32Word[10] = paui32FBCClearColour[0]; - pui32Word[11] = paui32FBCClearColour[1]; - pui32Word[12] = paui32FBCClearColour[2]; - pui32Word[13] = paui32FBCClearColour[3]; - -#if defined(RGX_FEATURE_TFBC_LOSSY_37_PERCENT_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_LOSSY_37_PERCENT)) - { - /* Should match current value of RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP */ - IMG_UINT32 ui32TFBCGroup = (ui32TFBCControl & ~RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_CLRMSK) >> - RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_SHIFT; - switch (ui32TFBCGroup) - { - case RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_GROUP_0: - pui32Word[14] = IMAGE_HEADER_WORD14_TFBC_GROUP_25_50_75; - break; - case RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_GROUP_1: - pui32Word[14] = IMAGE_HEADER_WORD14_TFBC_GROUP_25_37_50; - break; - } - } - else -#endif - { - pui32Word[14] = IMAGE_HEADER_WORD14_TFBC_GROUP_25_50_75; - } - -#if defined(RGX_FEATURE_TFBC_DELTA_CORRELATION_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_DELTA_CORRELATION)) - { - /* Should match current value of RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME */ - IMG_UINT32 ui32TFBCScheme = (ui32TFBCControl & ~RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_CLRMSK) >> - RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_SHIFT; - switch (ui32TFBCScheme) - { - case RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_DEFAULT: - pui32Word[14] |= IMAGE_HEADER_WORD14_COMP_SCHEME_ALL; - break; - case RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_TFBC_DELTA_STANDARD_AND_CORRELATION: - pui32Word[14] |= IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_CORR; - break; - case RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_TFBC_DELTA_STANDARD: - pui32Word[14] |= IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_ONLY; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "Unsupported TFBC compression control scheme - %d", ui32TFBCScheme)); - return PVRSRV_ERROR_UNSUPPORTED_FB_COMPRESSION_MODE; - } - } - else -#endif - { - /* Should always be set to 2 ("TFBC delta standard only") on cores without this feature */ - pui32Word[14] |= IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_ONLY; - } - -#if defined(RGX_FEATURE_TFBC_NATIVE_YUV10_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_NATIVE_YUV10)) - { - IMG_UINT32 ui32TFBCOverrideYUV10 = (ui32TFBCControl & RGX_CR_TFBC_COMPRESSION_CONTROL_YUV10_OVERRIDE_EN); - - if (ui32TFBCOverrideYUV10) - { - pui32Word[14] |= IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_EN; - } - } -#endif - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXPDumpPrepareOutputDataDescriptorHdr(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_PBYTE pbyPDumpDataHdr) -{ - IMG_PUINT32 pui32Word; - - /* Validate parameters */ - if (((DATA_HEADER_SIZE & ~(HEADER_WORD1_SIZE_CLRMSK >> HEADER_WORD1_SIZE_SHIFT)) != 0) || - ((DATA_HEADER_VERSION & ~(HEADER_WORD1_VERSION_CLRMSK >> HEADER_WORD1_VERSION_SHIFT)) != 0)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - pui32Word = IMG_OFFSET_ADDR(pbyPDumpDataHdr, 0); - - if (ui32HeaderType == DATA_HEADER_TYPE) - { - pui32Word[0] = (ui32HeaderType << HEADER_WORD0_TYPE_SHIFT); - pui32Word[1] = (DATA_HEADER_SIZE << HEADER_WORD1_SIZE_SHIFT) | - (DATA_HEADER_VERSION << HEADER_WORD1_VERSION_SHIFT); - pui32Word[2] = ui32DataSize << HEADER_WORD2_DATA_SIZE_SHIFT; - - pui32Word[3] = ui32ElementType << DATA_HEADER_WORD3_ELEMENT_TYPE_SHIFT; - pui32Word[4] = ui32ElementCount << DATA_HEADER_WORD4_ELEMENT_COUNT_SHIFT; - } - - if (ui32HeaderType == IBIN_HEADER_TYPE) - { - pui32Word[0] = (ui32HeaderType << HEADER_WORD0_TYPE_SHIFT); - pui32Word[1] = (IBIN_HEADER_SIZE << HEADER_WORD1_SIZE_SHIFT) | - (IBIN_HEADER_VERSION << HEADER_WORD1_VERSION_SHIFT); - pui32Word[2] = ui32DataSize << HEADER_WORD2_DATA_SIZE_SHIFT; - } - - return PVRSRV_OK; -} -#endif /* PDUMP */ - -/****************************************************************************** - End of file (rgxpdump.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxpdump.h b/drivers/gpu/drm/img-rogue/1.17/rgxpdump.h deleted file mode 100644 index 54443a59e0c53..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxpdump.h +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX pdump Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX pdump functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "pvrsrv_error.h" -#include "rgxdevice.h" -#include "device.h" -#include "devicemem.h" -#include "pdump_km.h" -#include "pvr_debug.h" - -#if defined(PDUMP) -/*! -******************************************************************************* - - @Function PVRSRVPDumpSignatureBufferKM - - @Description - - Dumps TA and 3D signature and checksum buffers - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpSignatureBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags); - -#if defined(SUPPORT_VALIDATION) -/*! -******************************************************************************* - - @Function PVRSRVPDumpComputeCRCSignatureCheckKM - - @Description - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpComputeCRCSignatureCheckKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags); -#endif - -/*! -******************************************************************************* - - @Function PVRSRVPDumpCRCSignatureCheckKM - - @Description - - Poll on FBC/FBDC end-to-end signature status - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpCRCSignatureCheckKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags); - -/*! -******************************************************************************* - - @Function PVRSRVPDumpValCheckPreCommandKM - - @Description - - Poll on various GPU status/signature status for validation, before - sending the GPU command. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpValCheckPreCommandKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags); - -/*! -******************************************************************************* - - @Function PVRSRVPDumpValCheckPostCommandKM - - @Description - - Poll on various GPU status/signature status for validation, after - sending the GPU command. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpValCheckPostCommandKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32PDumpFlags); - -/*! -******************************************************************************* - - @Function PVRSRVPDumpTraceBufferKM - - @Description - - Dumps TA and 3D signature and checksum buffers - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPDumpTraceBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags); - -/*! -******************************************************************************* - - @Function RGXPDumpPrepareOutputImageDescriptorHdr - - @Description - - Dumps the header for an OutputImage command - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXPDumpPrepareOutputImageDescriptorHdr(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HeaderSize, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32LogicalWidth, - IMG_UINT32 ui32LogicalHeight, - IMG_UINT32 ui32PhysicalWidth, - IMG_UINT32 ui32PhysicalHeight, - PDUMP_PIXEL_FORMAT ePixFmt, - IMG_MEMLAYOUT eMemLayout, - IMG_FB_COMPRESSION eFBCompression, - const IMG_UINT32 *paui32FBCClearColour, - PDUMP_FBC_SWIZZLE eFBCSwizzle, - IMG_PBYTE abyPDumpDesc); - -/*! -******************************************************************************* - - @Function RGXPDumpPrepareOutputDataDescriptorHdr - - @Description - - Dumps the header for an OutputData command - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXPDumpPrepareOutputDataDescriptorHdr(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32HeaderType, - IMG_UINT32 ui32DataSize, - IMG_UINT32 ui32ElementType, - IMG_UINT32 ui32ElementCount, - IMG_PBYTE pbyPDumpDataHdr); - -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVPDumpSignatureBufferKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVPDumpSignatureBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVPDumpTraceBufferKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVPDumpTraceBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); - return PVRSRV_OK; -} -#endif /* PDUMP */ -/****************************************************************************** - End of file (rgxpdump.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxpower.c b/drivers/gpu/drm/img-rogue/1.17/rgxpower.c deleted file mode 100644 index 1a2a09ed4984e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxpower.c +++ /dev/null @@ -1,1628 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific power routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(__linux__) -#include -#else -#include -#endif - -#include "rgxpower.h" -#include "rgxinit.h" -#include "rgx_fwif_km.h" -#include "rgxfwutils.h" -#include "pdump_km.h" -#include "pvr_debug.h" -#include "osfunc.h" -#include "rgxdebug.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "rgxtimecorr.h" -#include "devicemem_utils.h" -#include "htbserver.h" -#include "rgxstartstop.h" -#include "rgxfwimageutils.h" -#include "sync.h" -#include "rgxdefs_km.h" - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) -#include "process_stats.h" -#endif -#if defined(SUPPORT_LINUX_DVFS) -#include "pvr_dvfs_device.h" -#endif -#if defined(SUPPORT_VALIDATION) && defined(NO_HARDWARE) && defined(PDUMP) -#include "oskm_apphint.h" -#endif - -static PVRSRV_ERROR RGXFWNotifyHostTimeout(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_KCCB_CMD sCmd; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CmdKCCBSlot; - - /* Send the Timeout notification to the FW */ - sCmd.eCmdType = RGXFWIF_KCCB_CMD_POW; - sCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ; - sCmd.uCmdData.sPowData.uPowerReqData.ePowRequestType = RGXFWIF_POWER_HOST_TIMEOUT; - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sCmd, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - - return eError; -} - -static void _RGXUpdateGPUUtilStats(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb; - IMG_UINT64 *paui64StatsCounters; - IMG_UINT64 ui64LastPeriod; - IMG_UINT64 ui64LastState; - IMG_UINT64 ui64LastTime; - IMG_UINT64 ui64TimeNow; - - psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb; - paui64StatsCounters = &psUtilFWCb->aui64StatsCounters[0]; - - OSLockAcquire(psDevInfo->hGPUUtilLock); - - ui64TimeNow = RGXFWIF_GPU_UTIL_GET_TIME(RGXTimeCorrGetClockns64(psDevInfo->psDeviceNode)); - - /* Update counters to account for the time since the last update */ - ui64LastState = RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord); - ui64LastTime = RGXFWIF_GPU_UTIL_GET_TIME(psUtilFWCb->ui64LastWord); - ui64LastPeriod = RGXFWIF_GPU_UTIL_GET_PERIOD(ui64TimeNow, ui64LastTime); - paui64StatsCounters[ui64LastState] += ui64LastPeriod; - - /* Update state and time of the latest update */ - psUtilFWCb->ui64LastWord = RGXFWIF_GPU_UTIL_MAKE_WORD(ui64TimeNow, ui64LastState); - - OSLockRelease(psDevInfo->hGPUUtilLock); -} - -static INLINE PVRSRV_ERROR RGXDoStop(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - if (psDevConfig->pfnTDRGXStop == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPrePowerState: TDRGXStop not implemented!")); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - eError = psDevConfig->pfnTDRGXStop(psDevConfig->hSysData); -#else - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - eError = RGXStop(&psDevInfo->sLayerParams); -#endif - - return eError; -} - -/* - RGXPrePowerState -*/ -PVRSRV_ERROR RGXPrePowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - - if ((eNewPowerState != eCurrentPowerState) && - (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON)) - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_KCCB_CMD sPowCmd; - IMG_UINT32 ui32CmdKCCBSlot; - - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - - /* Send the Power off request to the FW */ - sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW; - sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_OFF_REQ; - sPowCmd.uCmdData.sPowData.uPowerReqData.bForced = BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED); - - eError = SyncPrimSet(psDevInfo->psPowSyncPrim, 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set Power sync prim", - __func__)); - return eError; - } - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sPowCmd, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to send Power off request", - __func__)); - return eError; - } - - /* Wait for the firmware to complete processing. It cannot use PVRSRVWaitForValueKM as it relies - on the EventObject which is signalled in this MISR */ - eError = RGXPollForGPCommandCompletion(psDeviceNode, - psDevInfo->psPowSyncPrim->pui32LinAddr, - 0x1, 0xFFFFFFFF); - - /* Check the Power state after the answer */ - if (eError == PVRSRV_OK) - { - /* Finally, de-initialise some registers. */ - if (psFwSysData->ePowState == RGXFWIF_POW_OFF) - { -#if !defined(NO_HARDWARE) - IMG_UINT32 ui32idx; - - /* Driver takes the VZ Fw-KM connection down, preventing the - * firmware from submitting further interrupts */ - KM_SET_OS_CONNECTION(OFFLINE, psDevInfo); - -#if defined(RGX_FW_IRQ_OS_COUNTERS) - ui32idx = RGXFW_HOST_OS; -#else - for_each_irq_cnt(ui32idx) -#endif /* RGX_FW_IRQ_OS_COUNTERS */ - { - IMG_UINT32 ui32IrqCnt; - - get_irq_cnt_val(ui32IrqCnt, ui32idx, psDevInfo); - - /* Wait for the pending FW processor to host interrupts to come back. */ - eError = PVRSRVPollForValueKM(psDeviceNode, - (IMG_UINT32 __iomem *)&psDevInfo->aui32SampleIRQCount[ui32idx], - ui32IrqCnt, - 0xffffffff, - POLL_FLAG_LOG_ERROR); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Wait for pending interrupts failed (DevID %u)." MSG_IRQ_CNT_TYPE " %u Host: %u, FW: %u", - __func__, - psDeviceNode->sDevId.ui32InternalID, - ui32idx, - psDevInfo->aui32SampleIRQCount[ui32idx], - ui32IrqCnt)); - - RGX_WaitForInterruptsTimeout(psDevInfo); - } - } -#endif /* NO_HARDWARE */ - - /* Update GPU frequency and timer correlation related data */ - RGXTimeCorrEnd(psDeviceNode, RGXTIMECORR_EVENT_POWER); - - /* Update GPU state counters */ - _RGXUpdateGPUUtilStats(psDevInfo); - -#if defined(SUPPORT_LINUX_DVFS) - eError = SuspendDVFS(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to suspend DVFS", __func__)); - return eError; - } -#endif - - psDevInfo->bRGXPowered = IMG_FALSE; - - eError = RGXDoStop(psDeviceNode); - if (eError != PVRSRV_OK) - { - /* Power down failures are treated as successful since the power was removed but logged. */ - PVR_DPF((PVR_DBG_WARNING, "%s: RGXDoStop failed (%s)", - __func__, PVRSRVGetErrorString(eError))); - psDevInfo->ui32ActivePMReqNonIdle++; - eError = PVRSRV_OK; - } - } - else - { - /* the sync was updated but the pow state isn't off -> the FW denied the transition */ - eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED; - - if (BITMASK_HAS(ePwrFlags, PVRSRV_POWER_FLAGS_FORCED)) - { /* It is an error for a forced request to be denied */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Failure to power off during a forced power off. FW: %d", - __func__, psFwSysData->ePowState)); - } - } - } - else if (eError == PVRSRV_ERROR_TIMEOUT) - { - /* timeout waiting for the FW to ack the request: return timeout */ - PVR_DPF((PVR_DBG_WARNING, - "%s: Timeout waiting for powoff ack from the FW", - __func__)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error waiting for powoff ack from the FW (%s)", - __func__, PVRSRVGetErrorString(eError))); - eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE; - } - } - - return eError; -} - -#if defined(SUPPORT_AUTOVZ) -static PVRSRV_ERROR _RGXWaitForGuestsToDisconnect(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError = PVRSRV_ERROR_TIMEOUT; - IMG_UINT32 ui32FwTimeout = (20 * SECONDS_TO_MICROSECONDS); - - LOOP_UNTIL_TIMEOUT(ui32FwTimeout) - { - IMG_UINT32 ui32OSid; - IMG_BOOL bGuestOnline = IMG_FALSE; - - for (ui32OSid = RGXFW_GUEST_OSID_START; - ui32OSid < RGX_NUM_OS_SUPPORTED; ui32OSid++) - { - RGXFWIF_CONNECTION_FW_STATE eGuestState = (RGXFWIF_CONNECTION_FW_STATE) - psDevInfo->psRGXFWIfFwSysData->asOsRuntimeFlagsMirror[ui32OSid].bfOsState; - - if ((eGuestState == RGXFW_CONNECTION_FW_ACTIVE) || - (eGuestState == RGXFW_CONNECTION_FW_OFFLOADING)) - { - bGuestOnline = IMG_TRUE; - PVR_DPF((PVR_DBG_WARNING, "%s: Guest OS %u still online.", __func__, ui32OSid)); - } - } - - if (!bGuestOnline) - { - /* Allow Guests to finish reading Connection state registers before disconnecting. */ - OSSleepms(100); - - PVR_DPF((PVR_DBG_WARNING, "%s: All Guest connections are down. " - "Host can power down the GPU.", __func__)); - eError = PVRSRV_OK; - break; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "%s: Waiting for Guests to disconnect " - "before powering down GPU.", __func__)); - - if (PVRSRVPwrLockIsLockedByMe(psDeviceNode)) - { - /* Don't wait with the power lock held as this prevents the vz - * watchdog thread from keeping the fw-km connection alive. */ - PVRSRVPowerUnlock(psDeviceNode); - } - } - - OSSleepms(10); - } END_LOOP_UNTIL_TIMEOUT(); - - if (!PVRSRVPwrLockIsLockedByMe(psDeviceNode)) - { - /* Take back power lock after waiting for Guests */ - eError = PVRSRVPowerLock(psDeviceNode); - } - - return eError; -} -#endif /* defined(SUPPORT_AUTOVZ) */ - -/* - RGXVzPrePowerState -*/ -PVRSRV_ERROR RGXVzPrePowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - - PVR_LOG_RETURN_IF_FALSE((eNewPowerState != eCurrentPowerState), "no power change", eError); - - if (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON) - { - /* powering down */ -#if defined(SUPPORT_AUTOVZ) - if (PVRSRV_VZ_MODE_IS(HOST) && (!psDeviceNode->bAutoVzFwIsUp)) - { - /* The Host must ensure all Guest drivers have disconnected from the GPU before powering it down. - * Guest drivers regularly access hardware registers during runtime. If an attempt is made to - * access a GPU register while the GPU is down, the SoC might lock up. */ - eError = _RGXWaitForGuestsToDisconnect(psDeviceNode); - PVR_LOG_RETURN_IF_ERROR(eError, "_RGXWaitForGuestsToDisconnect"); - - /* Temporarily restore all power callbacks used by the driver to fully power down the GPU. - * Under AutoVz, power transitions requests (e.g. on driver deinitialisation and unloading) - * are generally ignored and the GPU power state is unaffected. Special power requests like - * those triggered by Suspend/Resume calls must reinstate the callbacks when needed. */ - PVRSRVSetPowerCallbacks(psDeviceNode, psDeviceNode->psPowerDev, - &RGXVzPrePowerState, &RGXVzPostPowerState, - psDeviceNode->psDevConfig->pfnPrePowerState, - psDeviceNode->psDevConfig->pfnPostPowerState, - &RGXForcedIdleRequest, &RGXCancelForcedIdleRequest); - } - else - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if (KM_FW_CONNECTION_IS(ACTIVE, psDevInfo) && - KM_OS_CONNECTION_IS(ACTIVE, psDevInfo)) - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError = RGXFWSetFwOsState(psDevInfo, 0, RGXFWIF_OS_OFFLINE); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXFWSetFwOsState"); - } - } -#endif - PVR_DPF((PVR_DBG_WARNING, "%s: %s driver powering down: bAutoVzFwIsUp = %s", - __func__, PVRSRV_VZ_MODE_IS(GUEST)? "GUEST" : "HOST", - psDeviceNode->bAutoVzFwIsUp ? "TRUE" : "FALSE")); - } - else if (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON) - { - /* powering up */ - PVR_DPF((PVR_DBG_WARNING, "%s: %s driver powering up: bAutoVzFwIsUp = %s", - __func__, PVRSRV_VZ_MODE_IS(GUEST)? "GUEST" : "HOST", - psDeviceNode->bAutoVzFwIsUp ? "TRUE" : "FALSE")); - - } - - if (!(PVRSRV_VZ_MODE_IS(GUEST) || (psDeviceNode->bAutoVzFwIsUp))) - { - /* call regular device power function */ - eError = RGXPrePowerState(hDevHandle, eNewPowerState, eCurrentPowerState, ePwrFlags); - } - - return eError; -} - -/* - RGXVzPostPowerState -*/ -PVRSRV_ERROR RGXVzPostPowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_LOG_RETURN_IF_FALSE((eNewPowerState != eCurrentPowerState), "no power change", eError); - - if (!(PVRSRV_VZ_MODE_IS(GUEST) || (psDeviceNode->bAutoVzFwIsUp))) - { - /* call regular device power function */ - eError = RGXPostPowerState(hDevHandle, eNewPowerState, eCurrentPowerState, ePwrFlags); - } - - if (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON) - { - /* powering down */ - PVR_LOG_RETURN_IF_FALSE((!psDeviceNode->bAutoVzFwIsUp), "AutoVz Fw active, power not changed", eError); - PVR_DPF((PVR_DBG_WARNING, "%s: %s driver powering down: bAutoVzFwIsUp = %s", - __func__, PVRSRV_VZ_MODE_IS(GUEST)? "GUEST" : "HOST", - psDeviceNode->bAutoVzFwIsUp ? "TRUE" : "FALSE")); - -#if !defined(SUPPORT_AUTOVZ_HW_REGS) - /* The connection states must be reset on a GPU power cycle. If the states are kept - * in hardware scratch registers, they will be cleared on power down. When using shared - * memory the connection data must be explicitly cleared by the driver. */ - OSCachedMemSetWMB(psDevInfo->psRGXFWIfConnectionCtl, 0, sizeof(RGXFWIF_CONNECTION_CTL)); -#endif /* defined(SUPPORT_AUTOVZ) && !defined(SUPPORT_AUTOVZ_HW_REGS) */ - - if (PVRSRV_VZ_MODE_IS(GUEST) || (psDeviceNode->bAutoVzFwIsUp)) - { -#if defined(SUPPORT_AUTOVZ) - /* AutoVz Guests attempting to suspend have updated their connections earlier in RGXVzPrePowerState. - * Skip this redundant register write, as the Host could have powered down the GPU by now. */ - if (psDeviceNode->bAutoVzFwIsUp) -#endif - { - /* Take the VZ connection down to prevent firmware from submitting further interrupts */ - KM_SET_OS_CONNECTION(OFFLINE, psDevInfo); - } - /* Power transition callbacks were not executed, update RGXPowered flag here */ - psDevInfo->bRGXPowered = IMG_FALSE; - } - } - else if (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON) - { - /* powering up */ - IMG_UINT32 ui32FwTimeout = (3 * SECONDS_TO_MICROSECONDS); - volatile IMG_BOOL *pbUpdatedFlag = &psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated; - - PVR_DPF((PVR_DBG_WARNING, "%s: %s driver powering up: bAutoVzFwIsUp = %s", - __func__, PVRSRV_VZ_MODE_IS(GUEST)? "GUEST" : "HOST", - psDeviceNode->bAutoVzFwIsUp ? "TRUE" : "FALSE")); - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - /* Guests don't execute the power transition callbacks, so update their RGXPowered flag here */ - psDevInfo->bRGXPowered = IMG_TRUE; - -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - /* Guest drivers expect the firmware to have set its end of the - * connection to Ready state by now. Poll indefinitely otherwise. */ - if (!KM_FW_CONNECTION_IS(READY, psDevInfo)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Connection is not in Ready state. Waiting for Firmware ...", __func__)); - } - while (!KM_FW_CONNECTION_IS(READY, psDevInfo)) - { - OSSleepms(10); - } - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Connection is Ready. Initialisation proceeding.", __func__)); -#endif /* RGX_VZ_STATIC_CARVEOUT_FW_HEAPS */ - - /* Guests can only access the register holding the connection states, - * after the GPU is confirmed to be powered up */ - KM_SET_OS_CONNECTION(READY, psDevInfo); - - OSWriteDeviceMem32WithWMB(pbUpdatedFlag, IMG_FALSE); - - /* Kick an initial dummy command to make the firmware initialise all - * its internal guest OS data structures and compatibility information. - * Use the lower-level RGXSendCommandAndGetKCCBSlot() for the job, to make - * sure only 1 KCCB command is issued to the firmware. - * The default RGXFWHealthCheckCmd() prefaces each HealthCheck command with - * a pre-kick cache command which can interfere with the FW-KM init handshake. */ - { - RGXFWIF_KCCB_CMD sCmpKCCBCmd; - sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_HEALTH_CHECK; - - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, &sCmpKCCBCmd, PDUMP_FLAGS_CONTINUOUS, NULL); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXSendCommandAndGetKCCBSlot()"); - } - } - else - { - KM_SET_OS_CONNECTION(READY, psDevInfo); - - /* Disable power callbacks that should not be run on virtualised drivers after the GPU - * is fully initialised: system layer pre/post functions and driver idle requests. - * The original device RGX Pre/Post functions are called from this Vz wrapper. */ - PVRSRVSetPowerCallbacks(psDeviceNode, psDeviceNode->psPowerDev, - &RGXVzPrePowerState, &RGXVzPostPowerState, - NULL, NULL, NULL, NULL); - -#if defined(SUPPORT_AUTOVZ) - /* During first-time boot the flag is set here, while subsequent reboots will already - * have set it earlier in RGXInit. Set to true from this point onwards in any case. */ - psDeviceNode->bAutoVzFwIsUp = IMG_TRUE; -#endif - } - - /* Wait for the firmware to accept and enable the connection with this OS by setting its state to Active */ - while (!KM_FW_CONNECTION_IS(ACTIVE, psDevInfo)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Connection is not in Active state. Waiting for Firmware ...", __func__)); - OSSleepms(100); - } - PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Connection is Active. Initialisation proceeding.", __func__)); - - /* poll on the Firmware supplying the compatibility data */ - LOOP_UNTIL_TIMEOUT(ui32FwTimeout) - { - if (*pbUpdatedFlag) - { - break; - } - OSSleepms(10); - } END_LOOP_UNTIL_TIMEOUT(); - - PVR_LOG_RETURN_IF_FALSE(*pbUpdatedFlag, "Firmware does not respond with compatibility data. ", PVRSRV_ERROR_TIMEOUT); - - KM_SET_OS_CONNECTION(ACTIVE, psDevInfo); - } - - return PVRSRV_OK; -} - -#if defined(TRACK_FW_BOOT) -static INLINE void RGXCheckFWBootStage(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - FW_BOOT_STAGE eStage; - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - /* Boot stage temporarily stored to the register below */ - eStage = OSReadHWReg32(psDevInfo->pvRegsBaseKM, - RGX_FW_BOOT_STAGE_REGISTER); - } - else -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR)) - { - eStage = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SCRATCH14); - } - else -#endif - { - IMG_BYTE *pbBootData; - - if (PVRSRV_OK != DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc, - (void**)&pbBootData)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Could not acquire pointer to FW boot stage", __func__)); - eStage = FW_BOOT_STAGE_NOT_AVAILABLE; - } - else - { - pbBootData += RGXGetFWImageSectionOffset(NULL, MIPS_BOOT_DATA); - - eStage = *(FW_BOOT_STAGE*)&pbBootData[RGXMIPSFW_BOOT_STAGE_OFFSET]; - - if (eStage == FW_BOOT_STAGE_TLB_INIT_FAILURE) - { - RGXMIPSFW_BOOT_DATA *psBootData = - (RGXMIPSFW_BOOT_DATA*) (pbBootData + RGXMIPSFW_BOOTLDR_CONF_OFFSET); - - PVR_LOG(("MIPS TLB could not be initialised. Boot data info:" - " num PT pages %u, log2 PT page size %u, PT page addresses" - " %"IMG_UINT64_FMTSPECx " %"IMG_UINT64_FMTSPECx - " %"IMG_UINT64_FMTSPECx " %"IMG_UINT64_FMTSPECx, - psBootData->ui32PTNumPages, - psBootData->ui32PTLog2PageSize, - psBootData->aui64PTPhyAddr[0U], - psBootData->aui64PTPhyAddr[1U], - psBootData->aui64PTPhyAddr[2U], - psBootData->aui64PTPhyAddr[3U])); - } - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc); - } - } - - PVR_LOG(("%s: FW reached boot stage %i/%i.", - __func__, eStage, FW_BOOT_INIT_DONE)); -} -#endif - -static INLINE PVRSRV_ERROR RGXDoStart(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig; - - if (psDevConfig->pfnTDRGXStart == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPostPowerState: TDRGXStart not implemented!")); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - eError = psDevConfig->pfnTDRGXStart(psDevConfig->hSysData); -#else - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - eError = RGXStart(&psDevInfo->sLayerParams); -#endif - - return eError; -} - - -#if defined(NO_HARDWARE) && defined(PDUMP) - -#if 0 -#include "emu_cr_defs.h" -#else -#define EMU_CR_SYSTEM_IRQ_STATUS (0x00E0U) -/* IRQ is officially defined [8 .. 0] but here we split out the old deprecated single irq. */ -#define EMU_CR_SYSTEM_IRQ_STATUS_IRQ_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFE01)) -#define EMU_CR_SYSTEM_IRQ_STATUS_OLD_IRQ_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE)) -#endif - -static PVRSRV_ERROR -_ValidateIrqs(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32OSid; - PDUMP_FLAGS_T ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; - - /* Check if the Validation IRQ flag is set */ - if ((psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags & RGXFWIF_INICFG_VALIDATE_IRQ) == 0) - { - return PVRSRV_OK; - } - - PDUMPIF(psDevInfo->psDeviceNode, "IMG_PVR_TESTBENCH", ui32PDumpFlags); - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Poll for TB irq status to be set (irqs signalled)..."); - PDUMPREGPOL(psDevInfo->psDeviceNode, - RGX_TB_PDUMPREG_NAME, - EMU_CR_SYSTEM_IRQ_STATUS, - ~EMU_CR_SYSTEM_IRQ_STATUS_IRQ_CLRMSK, - ~EMU_CR_SYSTEM_IRQ_STATUS_IRQ_CLRMSK, - ui32PDumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "... and then clear them"); - for (ui32OSid = 0; ui32OSid < RGXFW_MAX_NUM_OS; ui32OSid++) - { - PDUMPREG32(psDevInfo->psDeviceNode, - RGX_PDUMPREG_NAME, - RGX_CR_IRQ_OS0_EVENT_CLEAR + ui32OSid * 0x10000, - RGX_CR_IRQ_OS0_EVENT_CLEAR_MASKFULL, - ui32PDumpFlags); - } - - PDUMPFI(psDevInfo->psDeviceNode, "IMG_PVR_TESTBENCH", ui32PDumpFlags); - - /* Poll on all the interrupt status registers for all OSes */ - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, ui32PDumpFlags, - "Validate Interrupt lines."); - - for (ui32OSid = 0; ui32OSid < RGXFW_MAX_NUM_OS; ui32OSid++) - { - PDUMPREGPOL(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, - RGX_CR_IRQ_OS0_EVENT_STATUS + ui32OSid * 0x10000, - 0x0, - 0xFFFFFFFF, - ui32PDumpFlags, - PDUMP_POLL_OPERATOR_EQUAL); - } - - return PVRSRV_OK; -} -#endif /* defined(NO_HARDWARE) && defined(PDUMP) */ - -#if defined(SUPPORT_GPUVIRT_VALIDATION) && !defined(NO_HARDWARE) -/* - * To validate the MTS unit we do the following: - * - Immediately after firmware loading for each OSID - * - Write the OSid to a memory location shared with FW - * - Kick the register of that OSid - * (Uncounted, DM 0) - * - FW clears the memory location if OSid matches - * - Host checks that memory location is cleared - * - * See firmware/devices/rgx/rgxfw_bg.c - */ -static PVRSRV_ERROR RGXVirtualisationPowerupSidebandTest(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXFWIF_SYSINIT *psFwSysInit, - PVRSRV_RGXDEV_INFO *psDevInfo) -{ - IMG_UINT32 ui32ScheduleRegister; - IMG_UINT32 ui32OSid; - IMG_UINT32 ui32KickType; - IMG_UINT32 ui32OsRegBanksMapped = (psDeviceNode->psDevConfig->ui32RegsSize / RGX_VIRTUALISATION_REG_SIZE_PER_OS); - - /* Nothing to do if the device does not support GPU_VIRTUALISATION */ - if (!PVRSRV_IS_FEATURE_SUPPORTED(psDeviceNode, GPU_VIRTUALISATION)) - { - return PVRSRV_OK; - } - - PVR_DPF((PVR_DBG_MESSAGE, "Testing per-os kick registers:")); - - ui32OsRegBanksMapped = MIN(ui32OsRegBanksMapped, GPUVIRT_VALIDATION_NUM_OS); - - if (ui32OsRegBanksMapped != RGXFW_MAX_NUM_OS) - { - PVR_DPF((PVR_DBG_WARNING, "The register bank mapped into kernel VA does not cover all OS' registers:")); - PVR_DPF((PVR_DBG_WARNING, "Maximum OS count = %d / Per-os register banks mapped = %d", RGXFW_MAX_NUM_OS, ui32OsRegBanksMapped)); - PVR_DPF((PVR_DBG_WARNING, "Only first %d MTS registers will be tested", ui32OsRegBanksMapped)); - } - - ui32KickType = RGX_CR_MTS_SCHEDULE_DM_DM0 | RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED; - - for (ui32OSid = 0; ui32OSid < ui32OsRegBanksMapped; ui32OSid++) - { - /* set Test field */ - psFwSysInit->ui32OSKickTest = (ui32OSid << RGXFWIF_KICK_TEST_OSID_SHIFT) | RGXFWIF_KICK_TEST_ENABLED_BIT; - -#if defined(PDUMP) - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, ui32OSKickTest), - sizeof(psFwSysInit->ui32OSKickTest), - PDUMP_FLAGS_CONTINUOUS); -#endif - - /* Force a read-back to memory to avoid posted writes on certain buses */ - OSWriteMemoryBarrier(&psFwSysInit->ui32OSKickTest); - - /* kick register */ - ui32ScheduleRegister = RGX_CR_MTS_SCHEDULE + (ui32OSid * RGX_VIRTUALISATION_REG_SIZE_PER_OS); - PVR_DPF((PVR_DBG_MESSAGE, " Testing OS: %u, Kick Reg: %X", - ui32OSid, - ui32ScheduleRegister)); - OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32ScheduleRegister, ui32KickType); - OSMemoryBarrier((IMG_BYTE*) psDevInfo->pvRegsBaseKM + ui32ScheduleRegister); - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, "VZ sideband test, kicking MTS register %u", ui32OSid); - - PDUMPREG32(psDeviceNode, RGX_PDUMPREG_NAME, - ui32ScheduleRegister, ui32KickType, PDUMP_FLAGS_CONTINUOUS); - - DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, ui32OSKickTest), - 0, - 0xFFFFFFFF, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); -#endif - - /* Wait test enable bit to be unset */ - if (PVRSRVPollForValueKM(psDeviceNode, - (IMG_UINT32 *)&psFwSysInit->ui32OSKickTest, - 0, - RGXFWIF_KICK_TEST_ENABLED_BIT, - POLL_FLAG_LOG_ERROR | POLL_FLAG_DEBUG_DUMP) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Testing OS %u kick register failed: firmware did not clear test location (contents: 0x%X)", - ui32OSid, - psFwSysInit->ui32OSKickTest)); - - return PVRSRV_ERROR_TIMEOUT; - } - - /* Check that the value is what we expect */ - if (psFwSysInit->ui32OSKickTest != 0) - { - PVR_DPF((PVR_DBG_ERROR, "Testing OS %u kick register failed: firmware wrote 0x%X to test location", - ui32OSid, - psFwSysInit->ui32OSKickTest)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - PVR_DPF((PVR_DBG_MESSAGE, " PASS")); - } - - PVR_LOG(("MTS passed sideband tests")); - return PVRSRV_OK; -} -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) && !defined(NO_HARDWARE) */ - -#if defined(SUPPORT_VALIDATION) && defined(NO_HARDWARE) && defined(PDUMP) -#define SCRATCH_VALUE (0x12345678U) - -static void RGXRiscvDebugModuleTest(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - void *pvAppHintState = NULL; - IMG_UINT32 ui32AppHintDefault = 0; - IMG_BOOL bRunRiscvDmiTest; - - IMG_UINT32 *pui32FWCode = NULL; - PVRSRV_ERROR eError; - - OSCreateKMAppHintState(&pvAppHintState); - OSGetKMAppHintBOOL(APPHINT_NO_DEVICE, pvAppHintState, RiscvDmiTest, - &ui32AppHintDefault, &bRunRiscvDmiTest); - OSFreeKMAppHintState(pvAppHintState); - - if (bRunRiscvDmiTest == IMG_FALSE) - { - return; - } - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc, (void **)&pui32FWCode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error acquiring FW code memory pointer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - } - - PDumpIfKM(psDevInfo->psDeviceNode, "ENABLE_RISCV_DMI_TEST", PDUMP_FLAGS_CONTINUOUS); - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, "DMI_TEST BEGIN"); - - RGXRiscvHalt(psDevInfo); - - /* - * Test RISC-V register reads/writes. - * RGXRiscv[Write/Poll]Reg are used to access internal RISC-V registers - * via debug module. - */ - - /* Write RISC-V mscratch register */ - RGXRiscvWriteReg(psDevInfo, RGXRISCVFW_MSCRATCH_ADDR, SCRATCH_VALUE); - /* Read RISC-V misa register (compare against default standard value) */ - RGXRiscvPollReg(psDevInfo, RGXRISCVFW_MISA_ADDR, RGXRISCVFW_MISA_VALUE); - /* Read RISC-V mscratch register (compare against previously written value) */ - RGXRiscvPollReg(psDevInfo, RGXRISCVFW_MSCRATCH_ADDR, SCRATCH_VALUE); - - /* - * Test RISC-V memory reads/writes. - * RGXRiscv[Write/Poll]Mem are used to access system memory via debug module - * (from RISC-V point of view). - */ - - if (pui32FWCode != NULL) - { - IMG_UINT32 ui32Tmp; - - /* Acquire pointer to FW code (bootloader) */ - pui32FWCode += RGXGetFWImageSectionOffset(NULL, RISCV_UNCACHED_CODE) / sizeof(IMG_UINT32); - /* Save FW code at address (bootloader) */ - ui32Tmp = *pui32FWCode; - - /* Write FW code at address (bootloader) */ - RGXWriteFWModuleAddr(psDevInfo, RGXRISCVFW_BOOTLDR_CODE_BASE, SCRATCH_VALUE); - /* Read FW code at address (bootloader + 4) (compare against value read from Host) */ - RGXRiscvPollMem(psDevInfo, RGXRISCVFW_BOOTLDR_CODE_BASE + 4, *(pui32FWCode + 1)); - /* Read FW code at address (bootloader) (compare against previously written value) */ - RGXRiscvPollMem(psDevInfo, RGXRISCVFW_BOOTLDR_CODE_BASE, SCRATCH_VALUE); - /* Restore FW code at address (bootloader) */ - RGXWriteFWModuleAddr(psDevInfo, RGXRISCVFW_BOOTLDR_CODE_BASE, ui32Tmp); - - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc); - } - - /* - * Test GPU register reads/writes. - * RGXRiscv[Write/Poll]Mem are used to access GPU registers via debug module - * (from RISC-V point of view). - * Note that system memory and GPU register accesses both use the same - * debug module interface, targeting different address ranges. - */ - - /* Write SCRATCH0 from the Host */ - PDUMPREG32(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_SCRATCH0, - SCRATCH_VALUE, PDUMP_FLAGS_CONTINUOUS); - /* Read SCRATCH0 */ - RGXRiscvPollMem(psDevInfo, RGXRISCVFW_SOCIF_BASE | RGX_CR_SCRATCH0, SCRATCH_VALUE); - /* Write SCRATCH0 */ - RGXWriteFWModuleAddr(psDevInfo, RGXRISCVFW_SOCIF_BASE | RGX_CR_SCRATCH0, ~SCRATCH_VALUE); - /* Read SCRATCH0 from the Host */ - PDUMPREGPOL(psDevInfo->psDeviceNode, RGX_PDUMPREG_NAME, RGX_CR_SCRATCH0, - ~SCRATCH_VALUE, 0xFFFFFFFFU, - PDUMP_FLAGS_CONTINUOUS, PDUMP_POLL_OPERATOR_EQUAL); - - RGXRiscvResume(psDevInfo); - - PDUMPCOMMENTWITHFLAGS(psDevInfo->psDeviceNode, PDUMP_FLAGS_CONTINUOUS, "DMI_TEST END"); - PDumpFiKM(psDevInfo->psDeviceNode, "ENABLE_RISCV_DMI_TEST", PDUMP_FLAGS_CONTINUOUS); -} -#endif - -/* - RGXPostPowerState -*/ -PVRSRV_ERROR RGXPostPowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - if ((eNewPowerState != eCurrentPowerState) && - (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON)) - { - PVRSRV_ERROR eError; - - if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) - { - /* Update timer correlation related data */ - RGXTimeCorrBegin(psDeviceNode, RGXTIMECORR_EVENT_POWER); - - /* Update GPU state counters */ - _RGXUpdateGPUUtilStats(psDevInfo); - - eError = RGXDoStart(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPostPowerState: RGXDoStart failed")); - return eError; - } - - OSMemoryBarrier(NULL); - - /* - * Check whether the FW has started by polling on bFirmwareStarted flag - */ - if (PVRSRVPollForValueKM(psDeviceNode, - (IMG_UINT32 __iomem *)&psDevInfo->psRGXFWIfSysInit->bFirmwareStarted, - IMG_TRUE, - 0xFFFFFFFF, - POLL_FLAG_LOG_ERROR | POLL_FLAG_DEBUG_DUMP) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPostPowerState: Polling for 'FW started' flag failed.")); - eError = PVRSRV_ERROR_TIMEOUT; - -#if defined(TRACK_FW_BOOT) - RGXCheckFWBootStage(psDevInfo); -#endif - - /* - * When bFirmwareStarted fails some info may be gained by doing the following - * debug dump but unfortunately it could be potentially dangerous if the reason - * for not booting is the GPU power is not ON. However, if we have reached this - * point the System Layer has returned without errors, we assume the GPU power - * is indeed ON. - */ - RGXDumpRGXDebugSummary(NULL, NULL, psDeviceNode->pvDevice, IMG_TRUE); - RGXDumpRGXRegisters(NULL, NULL, psDeviceNode->pvDevice); - - return eError; - } - -#if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, "Wait for the Firmware to start."); - eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfSysInitMemDesc, - offsetof(RGXFWIF_SYSINIT, bFirmwareStarted), - IMG_TRUE, - 0xFFFFFFFFU, - PDUMP_POLL_OPERATOR_EQUAL, - PDUMP_FLAGS_CONTINUOUS); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "RGXPostPowerState: problem pdumping POL for psRGXFWIfSysInitMemDesc (%d)", - eError)); - return eError; - } - -#if defined(NO_HARDWARE) && defined(PDUMP) - eError = _ValidateIrqs(psDevInfo); - if (eError != PVRSRV_OK) - { - return eError; - } -#endif -#endif - -#if defined(SUPPORT_GPUVIRT_VALIDATION) && !defined(NO_HARDWARE) - eError = RGXVirtualisationPowerupSidebandTest(psDeviceNode, psDevInfo->psRGXFWIfSysInit, psDevInfo); - if (eError != PVRSRV_OK) - { - return eError; - } -#endif - -#if defined(SUPPORT_VALIDATION) && defined(NO_HARDWARE) && defined(PDUMP) - RGXRiscvDebugModuleTest(psDevInfo); -#endif - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - SetFirmwareStartTime(psDevInfo->psRGXFWIfSysInit->ui32FirmwareStartedTimeStamp); -#endif - - HTBSyncPartitionMarker(psDevInfo->psRGXFWIfSysInit->ui32MarkerVal); - - psDevInfo->bRGXPowered = IMG_TRUE; - -#if defined(SUPPORT_LINUX_DVFS) - eError = ResumeDVFS(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXPostPowerState: Failed to resume DVFS")); - return eError; - } -#endif - } - } - - PDUMPCOMMENT(psDeviceNode, - "RGXPostPowerState: Current state: %d, New state: %d", - eCurrentPowerState, eNewPowerState); - - return PVRSRV_OK; -} - -/* - RGXPreClockSpeedChange -*/ -PVRSRV_ERROR RGXPreClockSpeedChange(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eCurrentPowerState) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - const PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const RGX_DATA *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - PVR_UNREFERENCED_PARAMETER(psRGXData); - - PVR_DPF((PVR_DBG_MESSAGE, "RGXPreClockSpeedChange: RGX clock speed was %uHz", - psRGXData->psRGXTimingInfo->ui32CoreClockSpeed)); - - if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF) && - (psFwSysData->ePowState != RGXFWIF_POW_OFF)) - { - /* Update GPU frequency and timer correlation related data */ - RGXTimeCorrEnd(psDeviceNode, RGXTIMECORR_EVENT_DVFS); - } - - return eError; -} - -/* - RGXPostClockSpeedChange -*/ -PVRSRV_ERROR RGXPostClockSpeedChange(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eCurrentPowerState) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const RGX_DATA *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32NewClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed; - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - /* Update runtime configuration with the new value */ - OSWriteDeviceMem32WithWMB(&psDevInfo->psRGXFWIfRuntimeCfg->ui32CoreClockSpeed, - ui32NewClockSpeed); - - if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF) && - (psFwSysData->ePowState != RGXFWIF_POW_OFF)) - { - RGXFWIF_KCCB_CMD sCOREClkSpeedChangeCmd; - IMG_UINT32 ui32CmdKCCBSlot; - - RGXTimeCorrBegin(psDeviceNode, RGXTIMECORR_EVENT_DVFS); - - sCOREClkSpeedChangeCmd.eCmdType = RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE; - sCOREClkSpeedChangeCmd.uCmdData.sCoreClkSpeedChangeData.ui32NewClockSpeed = ui32NewClockSpeed; - - PDUMPCOMMENT(psDeviceNode, "Scheduling CORE clock speed change command"); - - PDUMPPOWCMDSTART(psDeviceNode); - eError = RGXSendCommandAndGetKCCBSlot(psDeviceNode->pvDevice, - &sCOREClkSpeedChangeCmd, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - PDUMPPOWCMDEND(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PDUMPCOMMENT(psDeviceNode, "Scheduling CORE clock speed change command failed"); - PVR_DPF((PVR_DBG_ERROR, "RGXPostClockSpeedChange: Scheduling KCCB command failed. Error:%u", eError)); - return eError; - } - - PVR_DPF((PVR_DBG_MESSAGE, "RGXPostClockSpeedChange: RGX clock speed changed to %uHz", - psRGXData->psRGXTimingInfo->ui32CoreClockSpeed)); - } - - return eError; -} - -/*! - ****************************************************************************** - - @Function RGXDustCountChange - - @Description - - Does change of number of DUSTs - - @Input hDevHandle : RGX Device Node - @Input ui32NumberOfDusts : Number of DUSTs to make transition to - - @Return PVRSRV_ERROR : - - ******************************************************************************/ -PVRSRV_ERROR RGXDustCountChange(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32NumberOfDusts) -{ - - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - RGXFWIF_KCCB_CMD sDustCountChange; - IMG_UINT32 ui32MaxAvailableDusts = psDevInfo->sDevFeatureCfg.ui32MAXDustCount; - IMG_UINT32 ui32CmdKCCBSlot; - RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - if (ui32NumberOfDusts > ui32MaxAvailableDusts) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, - "%s: Invalid number of DUSTs (%u) while expecting value within <0,%u>. Error:%u", - __func__, - ui32NumberOfDusts, - ui32MaxAvailableDusts, - eError)); - return eError; - } - - psRuntimeCfg->ui32DefaultDustsNumInit = ui32NumberOfDusts; - OSWriteMemoryBarrier(&psRuntimeCfg->ui32DefaultDustsNumInit); - -#if !defined(NO_HARDWARE) - { - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - - if (psFwSysData->ePowState == RGXFWIF_POW_OFF) - { - return PVRSRV_OK; - } - - if (psFwSysData->ePowState != RGXFWIF_POW_FORCED_IDLE) - { - eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED; - PVR_DPF((PVR_DBG_ERROR, - "%s: Attempt to change dust count when not IDLE", - __func__)); - return eError; - } - } -#endif - - eError = SyncPrimSet(psDevInfo->psPowSyncPrim, 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set Power sync prim", - __func__)); - return eError; - } - - sDustCountChange.eCmdType = RGXFWIF_KCCB_CMD_POW; - sDustCountChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_NUM_UNITS_CHANGE; - sDustCountChange.uCmdData.sPowData.uPowerReqData.ui32NumOfDusts = ui32NumberOfDusts; - - PDUMPCOMMENT(psDeviceNode, - "Scheduling command to change Dust Count to %u", - ui32NumberOfDusts); - eError = RGXSendCommandAndGetKCCBSlot(psDeviceNode->pvDevice, - &sDustCountChange, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - - if (eError != PVRSRV_OK) - { - PDUMPCOMMENT(psDeviceNode, - "Scheduling command to change Dust Count failed. Error:%u", - eError); - PVR_DPF((PVR_DBG_ERROR, - "%s: Scheduling KCCB to change Dust Count failed. Error:%u", - __func__, eError)); - return eError; - } - - /* Wait for the firmware to answer. */ - eError = RGXPollForGPCommandCompletion(psDeviceNode, - psDevInfo->psPowSyncPrim->pui32LinAddr, - 0x1, 0xFFFFFFFF); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Timeout waiting for idle request", __func__)); - return eError; - } - -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, - "RGXDustCountChange: Poll for Kernel SyncPrim [0x%p] on DM %d", - psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP); - - SyncPrimPDumpPol(psDevInfo->psPowSyncPrim, - 1, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - 0); -#endif - - return PVRSRV_OK; -} - -/* - @Function RGXAPMLatencyChange -*/ -PVRSRV_ERROR RGXAPMLatencyChange(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32ActivePMLatencyms, - IMG_BOOL bActivePMLatencyPersistant) -{ - - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg; - IMG_UINT32 ui32CmdKCCBSlot; - PVRSRV_DEV_POWER_STATE ePowerState; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - eError = PVRSRVPowerLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "RGXAPMLatencyChange: Failed to acquire power lock")); - return eError; - } - - /* Update runtime configuration with the new values and ensure the - * new APM latency is written to memory before requesting the FW to - * read it - */ - psRuntimeCfg->ui32ActivePMLatencyms = ui32ActivePMLatencyms; - psRuntimeCfg->bActivePMLatencyPersistant = bActivePMLatencyPersistant; - OSWriteMemoryBarrier(&psRuntimeCfg->bActivePMLatencyPersistant); - - eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - - if ((eError == PVRSRV_OK) && (ePowerState != PVRSRV_DEV_POWER_STATE_OFF)) - { - RGXFWIF_KCCB_CMD sActivePMLatencyChange; - sActivePMLatencyChange.eCmdType = RGXFWIF_KCCB_CMD_POW; - sActivePMLatencyChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_APM_LATENCY_CHANGE; - - PDUMPCOMMENT(psDeviceNode, - "Scheduling command to change APM latency to %u", - ui32ActivePMLatencyms); - eError = RGXSendCommandAndGetKCCBSlot(psDeviceNode->pvDevice, - &sActivePMLatencyChange, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - - if (eError != PVRSRV_OK) - { - PDUMPCOMMENT(psDeviceNode, - "Scheduling command to change APM latency failed. Error:%u", - eError); - PVR_DPF((PVR_DBG_ERROR, "RGXAPMLatencyChange: Scheduling KCCB to change APM latency failed. Error:%u", eError)); - goto ErrorExit; - } - } - -ErrorExit: - PVRSRVPowerUnlock(psDeviceNode); - - return eError; -} - -/* - RGXActivePowerRequest -*/ -PVRSRV_ERROR RGXActivePowerRequest(IMG_HANDLE hDevHandle) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - - psDevInfo->ui32ActivePMReqTotal++; - - /* Powerlock to avoid further requests from racing with the FW hand-shake - * from now on (previous kicks to this point are detected by the FW) - * PVRSRVPowerLock is replaced with PVRSRVPowerTryLock to avoid - * potential dead lock between PDumpWriteLock and PowerLock - * during 'DriverLive + PDUMP=1 + EnableAPM=1'. - */ - eError = PVRSRVPowerTryLock(psDeviceNode); - if (eError != PVRSRV_OK) - { - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_LOG_ERROR(eError, "PVRSRVPowerTryLock"); - } - else - { - psDevInfo->ui32ActivePMReqRetry++; - } - goto _RGXActivePowerRequest_PowerLock_failed; - } - - /* Check again for IDLE once we have the power lock */ - if (psFwSysData->ePowState == RGXFWIF_POW_IDLE) - { -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - SetFirmwareHandshakeIdleTime(RGXReadHWTimerReg(psDevInfo)-psFwSysData->ui64StartIdleTime); -#endif - - PDUMPPOWCMDSTART(psDeviceNode); - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode, - PVRSRV_DEV_POWER_STATE_OFF, - PVRSRV_POWER_FLAGS_NONE); - PDUMPPOWCMDEND(psDeviceNode); - - if (eError == PVRSRV_OK) - { - psDevInfo->ui32ActivePMReqOk++; - } - else if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED) - { - psDevInfo->ui32ActivePMReqDenied++; - } - } - else - { - psDevInfo->ui32ActivePMReqNonIdle++; - } - - PVRSRVPowerUnlock(psDeviceNode); - -_RGXActivePowerRequest_PowerLock_failed: - - return eError; -} -/* - RGXForcedIdleRequest -*/ - -#define RGX_FORCED_IDLE_RETRY_COUNT 10 - -PVRSRV_ERROR RGXForcedIdleRequest(IMG_HANDLE hDevHandle, IMG_BOOL bDeviceOffPermitted) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_KCCB_CMD sPowCmd; - PVRSRV_ERROR eError; - IMG_UINT32 ui32RetryCount = 0; - IMG_UINT32 ui32CmdKCCBSlot; -#if !defined(NO_HARDWARE) - const RGXFWIF_SYSDATA *psFwSysData; -#endif - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - -#if !defined(NO_HARDWARE) - psFwSysData = psDevInfo->psRGXFWIfFwSysData; - - /* Firmware already forced idle */ - if (psFwSysData->ePowState == RGXFWIF_POW_FORCED_IDLE) - { - return PVRSRV_OK; - } - - /* Firmware is not powered. Sometimes this is permitted, for instance we were forcing idle to power down. */ - if (psFwSysData->ePowState == RGXFWIF_POW_OFF) - { - return (bDeviceOffPermitted) ? PVRSRV_OK : PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED; - } -#endif - - eError = SyncPrimSet(psDevInfo->psPowSyncPrim, 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set Power sync prim", - __func__)); - return eError; - } - sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW; - sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ; - sPowCmd.uCmdData.sPowData.uPowerReqData.ePowRequestType = RGXFWIF_POWER_FORCE_IDLE; - - PDUMPCOMMENT(psDeviceNode, - "RGXForcedIdleRequest: Sending forced idle command"); - - /* Send one forced IDLE command to GP */ - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sPowCmd, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to send idle request", __func__)); - return eError; - } - - /* Wait for GPU to finish current workload */ - do { - eError = RGXPollForGPCommandCompletion(psDeviceNode, - psDevInfo->psPowSyncPrim->pui32LinAddr, - 0x1, 0xFFFFFFFF); - if ((eError == PVRSRV_OK) || (ui32RetryCount == RGX_FORCED_IDLE_RETRY_COUNT)) - { - break; - } - ui32RetryCount++; - PVR_DPF((PVR_DBG_WARNING, - "%s: Request timeout. Retry %d of %d", - __func__, ui32RetryCount, RGX_FORCED_IDLE_RETRY_COUNT)); - } while (IMG_TRUE); - - if (eError != PVRSRV_OK) - { - RGXFWNotifyHostTimeout(psDevInfo); - PVR_DPF((PVR_DBG_ERROR, - "%s: Idle request failed. Firmware potentially left in forced idle state", - __func__)); - return eError; - } - -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, - "RGXForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d", - psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP); - - SyncPrimPDumpPol(psDevInfo->psPowSyncPrim, - 1, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - 0); -#endif - -#if !defined(NO_HARDWARE) - /* Check the firmware state for idleness */ - if (psFwSysData->ePowState != RGXFWIF_POW_FORCED_IDLE) - { - return PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED; - } -#endif - - return PVRSRV_OK; -} - -/* - RGXCancelForcedIdleRequest -*/ -PVRSRV_ERROR RGXCancelForcedIdleRequest(IMG_HANDLE hDevHandle) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_KCCB_CMD sPowCmd; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32CmdKCCBSlot; - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK); - - eError = SyncPrimSet(psDevInfo->psPowSyncPrim, 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set Power sync prim", - __func__)); - goto ErrorExit; - } - - /* Send the IDLE request to the FW */ - sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW; - sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ; - sPowCmd.uCmdData.sPowData.uPowerReqData.ePowRequestType = RGXFWIF_POWER_CANCEL_FORCED_IDLE; - - PDUMPCOMMENT(psDeviceNode, - "RGXForcedIdleRequest: Sending cancel forced idle command"); - - /* Send cancel forced IDLE command to GP */ - eError = RGXSendCommandAndGetKCCBSlot(psDevInfo, - &sPowCmd, - PDUMP_FLAGS_NONE, - &ui32CmdKCCBSlot); - - if (eError != PVRSRV_OK) - { - PDUMPCOMMENT(psDeviceNode, - "RGXCancelForcedIdleRequest: Failed to send cancel IDLE request for DM%d", - RGXFWIF_DM_GP); - goto ErrorExit; - } - - /* Wait for the firmware to answer. */ - eError = RGXPollForGPCommandCompletion(psDeviceNode, - psDevInfo->psPowSyncPrim->pui32LinAddr, - 1, 0xFFFFFFFF); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Timeout waiting for cancel idle request", __func__)); - goto ErrorExit; - } - -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, - "RGXCancelForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d", - psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP); - - SyncPrimPDumpPol(psDevInfo->psPowSyncPrim, - 1, - 0xffffffff, - PDUMP_POLL_OPERATOR_EQUAL, - 0); -#endif - - return eError; - -ErrorExit: - PVR_DPF((PVR_DBG_ERROR, "%s: Firmware potentially left in forced idle state", __func__)); - return eError; -} - -/*! - ****************************************************************************** - - @Function PVRSRVGetNextDustCount - - @Description - - Calculate a sequence of dust counts to achieve full transition coverage. - We increment two counts of dusts and switch up and down between them. - It does contain a few redundant transitions. If two dust exist, the - output transitions should be as follows. - - 0->1, 0<-1, 0->2, 0<-2, (0->1) - 1->1, 1->2, 1<-2, (1->2) - 2->2, (2->0), - 0->0. Repeat. - - Redundant transitions in brackets. - - @Input psDustReqState : Counter state used to calculate next dust count - @Input ui32DustCount : Number of dusts in the core - - @Return PVRSRV_ERROR - - ******************************************************************************/ -IMG_UINT32 RGXGetNextDustCount(RGX_DUST_STATE *psDustReqState, IMG_UINT32 ui32DustCount) -{ - if (psDustReqState->bToggle) - { - psDustReqState->ui32DustCount2++; - } - - if (psDustReqState->ui32DustCount2 > ui32DustCount) - { - psDustReqState->ui32DustCount1++; - psDustReqState->ui32DustCount2 = psDustReqState->ui32DustCount1; - } - - if (psDustReqState->ui32DustCount1 > ui32DustCount) - { - psDustReqState->ui32DustCount1 = 0; - psDustReqState->ui32DustCount2 = 0; - } - - psDustReqState->bToggle = !psDustReqState->bToggle; - - return (psDustReqState->bToggle) ? psDustReqState->ui32DustCount1 : psDustReqState->ui32DustCount2; -} - -/****************************************************************************** - End of file (rgxpower.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxpower.h b/drivers/gpu/drm/img-rogue/1.17/rgxpower.h deleted file mode 100644 index a6cd3f2b2d10b..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxpower.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX power header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX power -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXPOWER_H) -#define RGXPOWER_H - -#include "pvrsrv_error.h" -#include "img_types.h" -#include "servicesext.h" -#include "rgxdevice.h" - - -/*! -****************************************************************************** - - @Function RGXPrePowerState - - @Description - - does necessary preparation before power state transition - - @Input hDevHandle : RGX Device Node - @Input eNewPowerState : New power state - @Input eCurrentPowerState : Current power state - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXPrePowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*! -****************************************************************************** - - @Function RGXPostPowerState - - @Description - - does necessary preparation after power state transition - - @Input hDevHandle : RGX Device Node - @Input eNewPowerState : New power state - @Input eCurrentPowerState : Current power state - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXPostPowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*! -****************************************************************************** - - @Function RGXVzPrePowerState - - @Description - - does necessary preparation before power state transition on a vz driver - - @Input hDevHandle : RGX Device Node - @Input eNewPowerState : New power state - @Input eCurrentPowerState : Current power state - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXVzPrePowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*! -****************************************************************************** - - @Function RGXVzPostPowerState - - @Description - - does necessary preparation after power state transition on a vz driver - - @Input hDevHandle : RGX Device Node - @Input eNewPowerState : New power state - @Input eCurrentPowerState : Current power state - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXVzPostPowerState(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eNewPowerState, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_POWER_FLAGS ePwrFlags); - -/*! -****************************************************************************** - - @Function RGXPreClockSpeedChange - - @Description - - Does processing required before an RGX clock speed change. - - @Input hDevHandle : RGX Device Node - @Input eCurrentPowerState : Power state of the device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXPreClockSpeedChange(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eCurrentPowerState); - -/*! -****************************************************************************** - - @Function RGXPostClockSpeedChange - - @Description - - Does processing required after an RGX clock speed change. - - @Input hDevHandle : RGX Device Node - @Input eCurrentPowerState : Power state of the device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXPostClockSpeedChange(IMG_HANDLE hDevHandle, - PVRSRV_DEV_POWER_STATE eCurrentPowerState); - - -/*! -****************************************************************************** - - @Function RGXDustCountChange - - @Description Change of number of DUSTs - - @Input hDevHandle : RGX Device Node - @Input ui32NumberOfDusts : Number of DUSTs to make transition to - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXDustCountChange(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32NumberOfDusts); - -/*! -****************************************************************************** - - @Function RGXAPMLatencyChange - - @Description - - Changes the wait duration used before firmware indicates IDLE. - Reducing this value will cause the firmware to shut off faster and - more often but may increase bubbles in GPU scheduling due to the added - power management activity. If bPersistent is NOT set, APM latency will - return back to system default on power up. - - @Input hDevHandle : RGX Device Node - @Input ui32ActivePMLatencyms : Number of milliseconds to wait - @Input bActivePMLatencyPersistant : Set to ensure new value is not reset - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXAPMLatencyChange(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32ActivePMLatencyms, - IMG_BOOL bActivePMLatencyPersistant); - -/*! -****************************************************************************** - - @Function RGXActivePowerRequest - - @Description Initiate a handshake with the FW to power off the GPU - - @Input hDevHandle : RGX Device Node - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXActivePowerRequest(IMG_HANDLE hDevHandle); - -/*! -****************************************************************************** - - @Function RGXForcedIdleRequest - - @Description Initiate a handshake with the FW to idle the GPU - - @Input hDevHandle : RGX Device Node - - @Input bDeviceOffPermitted : Set to indicate device state being off is not - erroneous. - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXForcedIdleRequest(IMG_HANDLE hDevHandle, IMG_BOOL bDeviceOffPermitted); - -/*! -****************************************************************************** - - @Function RGXCancelForcedIdleRequest - - @Description Send a request to cancel idle to the firmware. - - @Input hDevHandle : RGX Device Node - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR RGXCancelForcedIdleRequest(IMG_HANDLE hDevHandle); - -/*! -****************************************************************************** - - @Function PVRSRVGetNextDustCount - - @Description - - Calculate a sequence of dust counts to achieve full transition coverage. - We increment two counts of dusts and switch up and down between them. - It does contain a few redundant transitions. If two dust exist, the - output transitions should be as follows. - - 0->1, 0<-1, 0->2, 0<-2, (0->1) - 1->1, 1->2, 1<-2, (1->2) - 2->2, (2->0), - 0->0. Repeat. - - Redundant transitions in brackets. - - @Input psDustReqState : Counter state used to calculate next dust count - @Input ui32DustCount : Number of dusts in the core - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_UINT32 RGXGetNextDustCount(RGX_DUST_STATE *psDustState, IMG_UINT32 ui32DustCount); - -#endif /* RGXPOWER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.c b/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.c deleted file mode 100644 index ef39bea255ebb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.c +++ /dev/null @@ -1,319 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Register configuration -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Regconfig routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxregconfig.h" -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "device.h" -#include "sync_internal.h" -#include "pdump_km.h" -#include "pvrsrv.h" - -PVRSRV_ERROR PVRSRVRGXSetRegConfigTypeKM(CONNECTION_DATA * psDevConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 ui8RegCfgType) -{ -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_REG_CONFIG *psRegCfg = &psDevInfo->sRegCongfig; - RGXFWIF_REG_CFG_TYPE eRegCfgType = (RGXFWIF_REG_CFG_TYPE) ui8RegCfgType; - - PVR_UNREFERENCED_PARAMETER(psDevConnection); - - OSLockAcquire(psRegCfg->hLock); - - if (eRegCfgType < psRegCfg->eRegCfgTypeToPush) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Register configuration requested (%d) is not valid since it has to be at least %d." - " Configurations of different types need to go in order", - __func__, - eRegCfgType, - psRegCfg->eRegCfgTypeToPush)); - OSLockRelease(psRegCfg->hLock); - return PVRSRV_ERROR_REG_CONFIG_INVALID_TYPE; - } - - psRegCfg->eRegCfgTypeToPush = eRegCfgType; - - OSLockRelease(psRegCfg->hLock); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(psDevConnection); - - PVR_DPF((PVR_DBG_ERROR, - "%s: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION", - __func__)); - return PVRSRV_ERROR_FEATURE_DISABLED; -#endif -} - -PVRSRV_ERROR PVRSRVRGXAddRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT64 ui64RegMask) -{ -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sRegCfgCmd; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_REG_CONFIG *psRegCfg = &psDevInfo->sRegCongfig; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - OSLockAcquire(psRegCfg->hLock); - - if (psRegCfg->bEnabled) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Cannot add record whilst register configuration active.", - __func__)); - OSLockRelease(psRegCfg->hLock); - return PVRSRV_ERROR_REG_CONFIG_ENABLED; - } - if (psRegCfg->ui32NumRegRecords == RGXFWIF_REG_CFG_MAX_SIZE) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Register configuration full.", - __func__)); - OSLockRelease(psRegCfg->hLock); - return PVRSRV_ERROR_REG_CONFIG_FULL; - } - - sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG; - sRegCfgCmd.uCmdData.sRegConfigData.sRegConfig.ui64Addr = (IMG_UINT64) ui32RegAddr; - sRegCfgCmd.uCmdData.sRegConfigData.sRegConfig.ui64Value = ui64RegValue; - sRegCfgCmd.uCmdData.sRegConfigData.sRegConfig.ui64Mask = ui64RegMask; - sRegCfgCmd.uCmdData.sRegConfigData.eRegConfigType = psRegCfg->eRegCfgTypeToPush; - sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_ADD; - - eError = RGXScheduleCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sRegCfgCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXScheduleCommand failed. Error:%u", - __func__, - eError)); - OSLockRelease(psRegCfg->hLock); - return eError; - } - - psRegCfg->ui32NumRegRecords++; - - OSLockRelease(psRegCfg->hLock); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVR_DPF((PVR_DBG_ERROR, - "%s: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION", - __func__)); - return PVRSRV_ERROR_FEATURE_DISABLED; -#endif -} - -PVRSRV_ERROR PVRSRVRGXClearRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sRegCfgCmd; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_REG_CONFIG *psRegCfg = &psDevInfo->sRegCongfig; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - OSLockAcquire(psRegCfg->hLock); - - if (psRegCfg->bEnabled) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Attempt to clear register configuration whilst active.", - __func__)); - OSLockRelease(psRegCfg->hLock); - return PVRSRV_ERROR_REG_CONFIG_ENABLED; - } - - sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG; - sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_CLEAR; - - eError = RGXScheduleCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sRegCfgCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXScheduleCommand failed. Error:%u", - __func__, - eError)); - OSLockRelease(psRegCfg->hLock); - return eError; - } - - psRegCfg->ui32NumRegRecords = 0; - psRegCfg->eRegCfgTypeToPush = RGXFWIF_REG_CFG_TYPE_PWR_ON; - - OSLockRelease(psRegCfg->hLock); - - return eError; -#else - PVR_DPF((PVR_DBG_ERROR, - "%s: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION", - __func__)); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - return PVRSRV_ERROR_FEATURE_DISABLED; -#endif -} - -PVRSRV_ERROR PVRSRVRGXEnableRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sRegCfgCmd; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_REG_CONFIG *psRegCfg = &psDevInfo->sRegCongfig; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - OSLockAcquire(psRegCfg->hLock); - - sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG; - sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_ENABLE; - - eError = RGXScheduleCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sRegCfgCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXScheduleCommand failed. Error:%u", - __func__, - eError)); - OSLockRelease(psRegCfg->hLock); - return eError; - } - - psRegCfg->bEnabled = IMG_TRUE; - - OSLockRelease(psRegCfg->hLock); - - return eError; -#else - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVR_DPF((PVR_DBG_ERROR, - "%s: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION", - __func__)); - return PVRSRV_ERROR_FEATURE_DISABLED; -#endif -} - -PVRSRV_ERROR PVRSRVRGXDisableRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(SUPPORT_USER_REGISTER_CONFIGURATION) - PVRSRV_ERROR eError = PVRSRV_OK; - RGXFWIF_KCCB_CMD sRegCfgCmd; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_REG_CONFIG *psRegCfg = &psDevInfo->sRegCongfig; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_ERROR_NOT_SUPPORTED); - - OSLockAcquire(psRegCfg->hLock); - - sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG; - sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_DISABLE; - - eError = RGXScheduleCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_GP, - &sRegCfgCmd, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXScheduleCommand failed. Error:%u", - __func__, - eError)); - OSLockRelease(psRegCfg->hLock); - return eError; - } - - psRegCfg->bEnabled = IMG_FALSE; - - OSLockRelease(psRegCfg->hLock); - - return eError; -#else - PVR_DPF((PVR_DBG_ERROR, - "%s: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION", - __func__)); - PVR_UNREFERENCED_PARAMETER(psConnection); - - return PVRSRV_ERROR_FEATURE_DISABLED; -#endif -} - -/****************************************************************************** - End of file (rgxregconfig.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.h b/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.h deleted file mode 100644 index b0921d98cb14a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxregconfig.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX register configuration functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX register configuration functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXREGCONFIG_H) -#define RGXREGCONFIG_H - -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgx_fwif_km.h" - -/*! -******************************************************************************* - @Function PVRSRVRGXSetRegConfigTypeKM - - @Description - Server-side implementation of RGXSetRegConfig - - @Input psDeviceNode - RGX Device node - @Input ui8RegPowerIsland - Reg configuration - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXSetRegConfigTypeKM(CONNECTION_DATA * psDevConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT8 ui8RegPowerIsland); -/*! -******************************************************************************* - @Function PVRSRVRGXSetRegConfigKM - - @Description - Server-side implementation of RGXSetRegConfig - - @Input psDeviceNode - RGX Device node - @Input ui64RegAddr - Register address - @Input ui64RegValue - Reg value - @Input ui64RegMask - Reg mask - - @Return PVRSRV_ERROR -******************************************************************************/ - -PVRSRV_ERROR PVRSRVRGXAddRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui64RegAddr, - IMG_UINT64 ui64RegValue, - IMG_UINT64 ui64RegMask); - -/*! -******************************************************************************* - @Function PVRSRVRGXClearRegConfigKM - - @Description - Server-side implementation of RGXClearRegConfig - - @Input psDeviceNode - RGX Device node - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXClearRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -******************************************************************************* - @Function PVRSRVRGXEnableRegConfigKM - - @Description - Server-side implementation of RGXEnableRegConfig - - @Input psDeviceNode - RGX Device node - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXEnableRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -******************************************************************************* - @Function PVRSRVRGXDisableRegConfigKM - - @Description - Server-side implementation of RGXDisableRegConfig - - @Input psDeviceNode - RGX Device node - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXDisableRegConfigKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* RGXREGCONFIG_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxshader.c b/drivers/gpu/drm/img-rogue/1.17/rgxshader.c deleted file mode 100644 index 407c0fbd5939c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxshader.c +++ /dev/null @@ -1,302 +0,0 @@ -/*************************************************************************/ /*! -@File rgxshader.c -@Title TQ Shader Load -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shader code and info are shared for all context on the device. - If allocation doesn't already exist, read shader data from file - and allocate PMR memory. PMR memory is not deallocated until - device deinit. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxshader.h" -#include "osfunc_common.h" -#include "rgxdevice.h" -#include "pdump_km.h" -#include "physmem.h" -#include "ri_server.h" -#include "pvr_ricommon.h" - -static void -RGXShaderReadHeader(OS_FW_IMAGE *psShaderFW, RGX_SHADER_HEADER *psHeader) -{ - const void * pvData; - - pvData = OSFirmwareData(psShaderFW); - - OSDeviceMemCopy(psHeader, pvData, sizeof(RGX_SHADER_HEADER)); -} - -static size_t -RGXShaderCLIMemSize(OS_FW_IMAGE *psShaderFW) -{ - RGX_SHADER_HEADER sHeader; - - RGXShaderReadHeader(psShaderFW, &sHeader); - - return sHeader.ui32SizeClientMem; -} - -static size_t -RGXShaderUSCMemSize(OS_FW_IMAGE *psShaderFW) -{ - RGX_SHADER_HEADER sHeader; - - RGXShaderReadHeader(psShaderFW, &sHeader); - - return sHeader.ui32SizeFragment; -} - -static void * -RGXShaderCLIMem(OS_FW_IMAGE *psShaderFW) -{ - return (void*)OSFirmwareData(psShaderFW); -} - -static void * -RGXShaderUSCMem(OS_FW_IMAGE *psShaderFW) -{ - IMG_PBYTE pui8Data; - - pui8Data = (IMG_PBYTE)OSFirmwareData(psShaderFW); - - pui8Data += RGXShaderCLIMemSize(psShaderFW); - - return (void*) pui8Data; -} - -#define RGX_SHADER_FILENAME_MAX_SIZE ((sizeof(RGX_SH_FILENAME)+ \ - RGX_BVNC_STR_SIZE_MAX)) - -static void -_GetShaderFileName(PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_CHAR * pszShaderFilenameStr, - IMG_CHAR * pszShaderpFilenameStr) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSSNPrintf(pszShaderFilenameStr, RGX_SHADER_FILENAME_MAX_SIZE, - "%s." RGX_BVNC_STR_FMTSPEC, - RGX_SH_FILENAME, - psDevInfo->sDevFeatureCfg.ui32B, psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, psDevInfo->sDevFeatureCfg.ui32C); - - OSSNPrintf(pszShaderpFilenameStr, RGX_SHADER_FILENAME_MAX_SIZE, - "%s." RGX_BVNC_STRP_FMTSPEC, - RGX_SH_FILENAME, - psDevInfo->sDevFeatureCfg.ui32B, psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, psDevInfo->sDevFeatureCfg.ui32C); -} - -PVRSRV_ERROR -PVRSRVTQLoadShaders(PVRSRV_DEVICE_NODE * psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - OS_FW_IMAGE *psShaderFW; - RGX_SHADER_HEADER sHeader; - IMG_UINT32 ui32MappingTable = 0; - IMG_UINT32 ui32NumPages; - IMG_CHAR aszShaderFilenameStr[RGX_SHADER_FILENAME_MAX_SIZE]; - IMG_CHAR aszShaderpFilenameStr[RGX_SHADER_FILENAME_MAX_SIZE]; - const IMG_CHAR *pszShaderFilenameStr = aszShaderFilenameStr; - size_t uiNumBytes; - PVRSRV_ERROR eError; - - _GetShaderFileName(psDeviceNode, aszShaderFilenameStr, aszShaderpFilenameStr); - - eError = OSLoadFirmware(psDeviceNode, aszShaderFilenameStr, NULL, &psShaderFW); - - if (eError != PVRSRV_OK) - { - eError = OSLoadFirmware(psDeviceNode, aszShaderpFilenameStr, - NULL, &psShaderFW); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to load shader binary file %s (%s)", - __func__, - aszShaderpFilenameStr, - PVRSRVGetErrorString(eError))); - eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE; - goto failed_init; - } - - pszShaderFilenameStr = aszShaderpFilenameStr; - } - - PVR_LOG(("Shader binary image '%s' loaded", pszShaderFilenameStr)); - - RGXShaderReadHeader(psShaderFW, &sHeader); - - ui32NumPages = (sHeader.ui32SizeFragment / RGX_BIF_PM_PHYSICAL_PAGE_SIZE) + 1; - - PDUMPCOMMENT(psDeviceNode, "Allocate TDM USC PMR Block (Pages %08X)", ui32NumPages); - - eError = PhysmemNewRamBackedPMR(NULL, - psDeviceNode, - (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE, - (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE, - 1, - 1, - &ui32MappingTable, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT, - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE - | PVRSRV_MEMALLOCFLAG_GPU_READABLE - | PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT - | PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER, - sizeof("tquscpmr"), - "tquscpmr", - PVR_SYS_ALLOC_PID, - (PMR**)&psDevInfo->hTQUSCSharedMem, - PDUMP_NONE, - NULL); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from PhysmemNewRamBackedPMR (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_firmware; - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - eError = RIWritePMREntryWithOwnerKM(psDevInfo->hTQUSCSharedMem, PVR_SYS_ALLOC_PID); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RIWritePMREntryWithOwnerKM (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_uscpmr; - } -#endif - - eError = PMR_WriteBytes(psDevInfo->hTQUSCSharedMem, 0, RGXShaderUSCMem(psShaderFW), RGXShaderUSCMemSize(psShaderFW), &uiNumBytes); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from PMR_WriteBytes (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_uscpmr; - } - - ui32NumPages = (sHeader.ui32SizeClientMem / RGX_BIF_PM_PHYSICAL_PAGE_SIZE) + 1; - - PDUMPCOMMENT(psDeviceNode, "Allocate TDM Client PMR Block (Pages %08X)", ui32NumPages); - - eError = PhysmemNewRamBackedPMR(NULL, - psDeviceNode, - (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE, - (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE, - 1, - 1, - &ui32MappingTable, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT, - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE - | PVRSRV_MEMALLOCFLAG_CPU_READABLE - | PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT - | PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER, - sizeof("tqclipmr"), - "tqclipmr", - PVR_SYS_ALLOC_PID, - (PMR**)&psDevInfo->hTQCLISharedMem, - PDUMP_NONE, - NULL); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from PhysmemNewRamBackedPMR (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_uscpmr; - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - eError = RIWritePMREntryWithOwnerKM(psDevInfo->hTQCLISharedMem, PVR_SYS_ALLOC_PID); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RIWritePMREntryWithOwnerKM (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_clipmr; - } -#endif - - eError = PMR_WriteBytes(psDevInfo->hTQCLISharedMem, 0, RGXShaderCLIMem(psShaderFW), RGXShaderCLIMemSize(psShaderFW), &uiNumBytes); - if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from PMR_WriteBytes (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto failed_clipmr; - } - - OSUnloadFirmware(psShaderFW); - - PVR_ASSERT(psDevInfo->hTQUSCSharedMem != NULL); - PVR_ASSERT(psDevInfo->hTQCLISharedMem != NULL); - - return PVRSRV_OK; - -failed_clipmr: - PMRUnrefPMR(psDevInfo->hTQCLISharedMem); -failed_uscpmr: - PMRUnrefPMR(psDevInfo->hTQUSCSharedMem); -failed_firmware: - OSUnloadFirmware(psShaderFW); -failed_init: - return eError; -} - -void -PVRSRVTQAcquireShaders(PVRSRV_DEVICE_NODE * psDeviceNode, - PMR ** ppsCLIPMRMem, - PMR ** ppsUSCPMRMem) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_ASSERT(psDevInfo->hTQUSCSharedMem != NULL); - PVR_ASSERT(psDevInfo->hTQCLISharedMem != NULL); - - *ppsUSCPMRMem = psDevInfo->hTQUSCSharedMem; - *ppsCLIPMRMem = psDevInfo->hTQCLISharedMem; -} - -void PVRSRVTQUnloadShaders(PVRSRV_DEVICE_NODE * psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - (void) PMRUnrefPMR(psDevInfo->hTQUSCSharedMem); - (void) PMRUnrefPMR(psDevInfo->hTQCLISharedMem); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxshader.h b/drivers/gpu/drm/img-rogue/1.17/rgxshader.h deleted file mode 100644 index 7676ede51b7fa..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxshader.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************/ /*! -@File rgxshader.h -@Title TQ Shader Load -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shader code and info are shared for all context on the device. - If allocation doesn't already exist, read shader data from file - and allocate PMR memory. PMR memory is not deallocated until - device deinit. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXSHADER_H) -#define RGXSHADER_H - -#include "fwload.h" -#include "rgxtransfer_shader.h" -#include "connection_server.h" - -/*************************************************************************/ /*! -@Function PVRSRVTQLoadShaders -@Description If PMR is not allocated, reads shader binary data from file - and allocates new PMR memory. -@Input psDeviceNode Device node -@Return PVRSRV_ERROR Returns PVRSRV_OK on success. -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVTQLoadShaders(PVRSRV_DEVICE_NODE *psDeviceNode); - -/*************************************************************************/ /*! -@Function PVRSRVTQAcquireShaders -@Description Get handle to ready allocated shader PMR memory -@Input psDeviceNode Device node -@Output ppsCLIPMRMem Shader data used by CPU client side. -@Output ppsUSCPMRMem Shader usc code used by GPU. -*/ /**************************************************************************/ -void -PVRSRVTQAcquireShaders(PVRSRV_DEVICE_NODE *psDeviceNode, - PMR **ppsCLIPMRMem, - PMR **ppsUSCPMRMem); - -/*************************************************************************/ /*! -@Function PVRSRVTQUnLoadShaders -@Description Unref PMR memory. -@Input psDeviceNode Device node -*/ /**************************************************************************/ -void PVRSRVTQUnloadShaders(PVRSRV_DEVICE_NODE *psDeviceNode); - -#endif /* RGXSHADER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxsrvinit.c b/drivers/gpu/drm/img-rogue/1.17/rgxsrvinit.c deleted file mode 100644 index 7de49eea1378c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxsrvinit.c +++ /dev/null @@ -1,1641 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services initialisation routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "srvinit.h" -#include "pvr_debug.h" -#include "osfunc.h" -#include "km_apphint_defs.h" -#include "htbuffer_types.h" -#include "htbuffer_init.h" - -#include "devicemem.h" -#include "devicemem_pdump.h" - -#include "rgx_fwif_km.h" -#include "pdump_km.h" - -#include "rgxinit.h" -#include "rgxmulticore.h" - -#include "rgx_compat_bvnc.h" - -#include "osfunc.h" - -#include "rgxdefs_km.h" - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -#include "rgx_fwif_hwperf.h" -#include "rgx_hwperf_table.h" - -#include "fwload.h" -#include "rgxlayer_impl.h" -#include "rgxfwimageutils.h" -#include "rgxfwutils.h" - -#include "rgx_hwperf.h" -#include "rgx_bvnc_defs_km.h" - -#include "rgxdevice.h" - -#include "pvrsrv.h" - -#if defined(SUPPORT_TRUSTED_DEVICE) -#include "rgxdevice.h" -#include "pvrsrv_device.h" -#endif - -#define DRIVER_MODE_HOST 0 /* AppHint value for host driver mode */ - -#define HW_PERF_FILTER_DEFAULT 0x00000000 /* Default to no HWPerf */ -#define HW_PERF_FILTER_DEFAULT_ALL_ON 0xFFFFFFFF /* All events */ - -/* Kernel CCB size */ - -#if !defined(PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE) -#define PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE 4 -#endif -#if !defined(PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE) -#define PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE 16 -#endif - -#if PVRSRV_APPHINT_KCCB_SIZE_LOG2 < PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE -#error PVRSRV_APPHINT_KCCB_SIZE_LOG2 is too low. -#elif PVRSRV_APPHINT_KCCB_SIZE_LOG2 > PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE -#error PVRSRV_APPHINT_KCCB_SIZE_LOG2 is too high. -#endif - -#if defined(SUPPORT_VALIDATION) -#include "pvrsrv_apphint.h" -#endif - -#include "os_srvinit_param.h" -#if !defined(__linux__) -/*! -******************************************************************************* - * AppHint mnemonic data type helper tables -******************************************************************************/ -/* apphint map of name vs. enable flag */ -static SRV_INIT_PARAM_UINT32_LOOKUP htb_loggroup_tbl[] = { -#define X(a, b) { #b, HTB_LOG_GROUP_FLAG(a) }, - HTB_LOG_SFGROUPLIST -#undef X -}; -/* apphint map of arg vs. OpMode */ -static SRV_INIT_PARAM_UINT32_LOOKUP htb_opmode_tbl[] = { - { "droplatest", HTB_OPMODE_DROPLATEST}, - { "dropoldest", HTB_OPMODE_DROPOLDEST}, - /* HTB should never be started in HTB_OPMODE_BLOCK - * as this can lead to deadlocks - */ -}; - -static SRV_INIT_PARAM_UINT32_LOOKUP fwt_logtype_tbl[] = { - { "trace", 0}, - { "none", 0} -#if defined(SUPPORT_TBI_INTERFACE) - , { "tbi", 1} -#endif -}; - -static SRV_INIT_PARAM_UINT32_LOOKUP timecorr_clk_tbl[] = { - { "mono", 0 }, - { "mono_raw", 1 }, - { "sched", 2 } -}; - -static SRV_INIT_PARAM_UINT32_LOOKUP fwt_loggroup_tbl[] = { RGXFWIF_LOG_GROUP_NAME_VALUE_MAP }; - -/* - * Services AppHints initialisation - */ -#define X(a, b, c, d, e) SrvInitParamInit ## b(a, d, e) -APPHINT_LIST_ALL -#undef X -#endif /* !defined(__linux__) */ - -/* - * Container for all the apphints used by this module - */ -typedef struct _RGX_SRVINIT_APPHINTS_ -{ - IMG_UINT32 ui32DriverMode; - IMG_BOOL bGPUUnitsPowerChange; - IMG_BOOL bEnableSignatureChecks; - IMG_UINT32 ui32SignatureChecksBufSize; - - IMG_BOOL bAssertOnOutOfMem; -#if defined(SUPPORT_VALIDATION) - IMG_BOOL bValidateIrq; - IMG_BOOL bValidateSOCUSCTimer; -#endif - IMG_BOOL bAssertOnHWRTrigger; -#if defined(SUPPORT_VALIDATION) - IMG_UINT32 aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_LAST]; - IMG_UINT32 ui32FBCDCVersionOverride; - IMG_UINT32 ui32TFBCCompressionControlGroup; - IMG_UINT32 ui32TFBCCompressionControlScheme; - IMG_BOOL bTFBCCompressionControlYUVFormat; -#endif - IMG_BOOL bCheckMlist; - IMG_BOOL bDisableClockGating; - IMG_BOOL bDisableDMOverlap; - IMG_BOOL bDisableFEDLogging; - IMG_BOOL bDisablePDP; - IMG_BOOL bEnableCDMKillRand; - IMG_BOOL bEnableRandomCsw; - IMG_BOOL bEnableSoftResetCsw; - IMG_BOOL bFilteringMode; - IMG_BOOL bHWPerfDisableCustomCounterFilter; - IMG_BOOL bZeroFreelist; - IMG_UINT32 ui32EnableFWContextSwitch; - IMG_UINT32 ui32FWContextSwitchProfile; - - IMG_UINT32 ui32HWPerfFWBufSize; - IMG_UINT32 ui32HWPerfHostBufSize; - IMG_UINT32 ui32HWPerfFilter0; - IMG_UINT32 ui32HWPerfFilter1; - IMG_UINT32 ui32HWPerfHostFilter; - IMG_UINT32 ui32TimeCorrClock; - IMG_UINT32 ui32HWRDebugDumpLimit; - IMG_UINT32 ui32JonesDisableMask; - IMG_UINT32 ui32LogType; - IMG_UINT32 ui32TruncateMode; - IMG_UINT32 ui32KCCBSizeLog2; - FW_PERF_CONF eFirmwarePerf; - RGX_ACTIVEPM_CONF eRGXActivePMConf; - RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf; - - IMG_BOOL bEnableTrustedDeviceAceConfig; - IMG_UINT32 ui32FWContextSwitchCrossDM; -#if defined(SUPPORT_PHYSMEM_TEST) && !defined(INTEGRITY_OS) && !defined(__QNXNTO__) - IMG_UINT32 ui32PhysMemTestPasses; -#endif -} RGX_SRVINIT_APPHINTS; - -/*! -******************************************************************************* - - @Function GetApphints - - @Description Read init time apphints and initialise internal variables - - @Input psHints : Pointer to apphints container - - @Return void - -******************************************************************************/ -static INLINE void GetApphints(PVRSRV_RGXDEV_INFO *psDevInfo, RGX_SRVINIT_APPHINTS *psHints) -{ - void *pvParamState = SrvInitParamOpen(); - IMG_UINT32 ui32ParamTemp; - IMG_BOOL bS7TopInfra = IMG_FALSE, bE42290 = IMG_FALSE, bTPUFiltermodeCtrl = IMG_FALSE; - IMG_BOOL bE42606 = IMG_FALSE; -#if defined(EMULATOR) - IMG_BOOL bAXIACELite = IMG_FALSE; -#endif - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, S7_TOP_INFRASTRUCTURE)) - { - bS7TopInfra = IMG_TRUE; - } -#endif -#if defined(RGX_FEATURE_TPU_FILTERING_MODE_CONTROL_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TPU_FILTERING_MODE_CONTROL)) - { - bTPUFiltermodeCtrl = IMG_TRUE; - } -#endif -#if defined(HW_ERN_42290_BIT_MASK) - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 42290)) - { - bE42290 = IMG_TRUE; - } -#endif -#if defined(HW_ERN_42606_BIT_MASK) - if (RGX_IS_ERN_SUPPORTED(psDevInfo, 42606)) - { - bE42606 = IMG_TRUE; - } -#endif -#if defined(HW_FEATURE_AXI_ACELITE_BIT_MASK) && defined(EMULATOR) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, AXI_ACELITE)) - { - bAXIACELite = IMG_TRUE; - } -#endif - - /* - * NB AppHints initialised to a default value via SrvInitParamInit* macros above - */ - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, DriverMode, psHints->ui32DriverMode); - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, GPUUnitsPowerChange, psHints->bGPUUnitsPowerChange); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, EnableSignatureChecks, psHints->bEnableSignatureChecks); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, SignatureChecksBufSize, psHints->ui32SignatureChecksBufSize); - - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, AssertOutOfMemory, psHints->bAssertOnOutOfMem); - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, AssertOnHWRTrigger, psHints->bAssertOnHWRTrigger); - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, CheckMList, psHints->bCheckMlist); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, DisableClockGating, psHints->bDisableClockGating); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, DisableDMOverlap, psHints->bDisableDMOverlap); - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, DisableFEDLogging, psHints->bDisableFEDLogging); - SrvInitParamGetUINT32(psDevInfo->psDeviceNode, pvParamState, EnableAPM, ui32ParamTemp); - psHints->eRGXActivePMConf = ui32ParamTemp; - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, EnableCDMKillingRandMode, psHints->bEnableCDMKillRand); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, EnableRandomContextSwitch, psHints->bEnableRandomCsw); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, EnableSoftResetContextSwitch, psHints->bEnableSoftResetCsw); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, EnableFWContextSwitch, psHints->ui32EnableFWContextSwitch); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, EnableRDPowerIsland, ui32ParamTemp); - psHints->eRGXRDPowerIslandConf = ui32ParamTemp; - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, FirmwarePerf, ui32ParamTemp); - psHints->eFirmwarePerf = ui32ParamTemp; - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, FWContextSwitchProfile, psHints->ui32FWContextSwitchProfile); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, - HWPerfDisableCustomCounterFilter, psHints->bHWPerfDisableCustomCounterFilter); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, HWPerfHostBufSizeInKB, psHints->ui32HWPerfHostBufSize); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, HWPerfFWBufSizeInKB, psHints->ui32HWPerfFWBufSize); - SrvInitParamGetUINT32(psDevInfo->psDeviceNode, pvParamState, KernelCCBSizeLog2, psHints->ui32KCCBSizeLog2); - - if (psHints->ui32KCCBSizeLog2 < PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE) - { - PVR_DPF((PVR_DBG_WARNING, "KCCB size %u is too low, setting to %u", - psHints->ui32KCCBSizeLog2, PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE)); - psHints->ui32KCCBSizeLog2 = PVRSRV_RGX_LOG2_KERNEL_CCB_MIN_SIZE; - } - else if (psHints->ui32KCCBSizeLog2 > PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE) - { - PVR_DPF((PVR_DBG_WARNING, "KCCB size %u is too high, setting to %u", - psHints->ui32KCCBSizeLog2, PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE)); - psHints->ui32KCCBSizeLog2 = PVRSRV_RGX_LOG2_KERNEL_CCB_MAX_SIZE; - } - -#if defined(SUPPORT_VALIDATION) - if (psHints->ui32KCCBSizeLog2 != PVRSRV_APPHINT_KCCB_SIZE_LOG2) - { - PVR_LOG(("KernelCCBSizeLog2 set to %u", psHints->ui32KCCBSizeLog2)); - } -#endif - -#if defined(__linux__) - /* name changes */ - { - IMG_UINT64 ui64Tmp; - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, DisablePDumpPanic, psHints->bDisablePDP); - SrvInitParamGetUINT64(psDevInfo->psDeviceNode, pvParamState, HWPerfFWFilter, ui64Tmp); - psHints->ui32HWPerfFilter0 = (IMG_UINT32)(ui64Tmp & 0xffffffffllu); - psHints->ui32HWPerfFilter1 = (IMG_UINT32)((ui64Tmp >> 32) & 0xffffffffllu); - } -#else - SrvInitParamUnreferenced(DisablePDumpPanic); - SrvInitParamUnreferenced(HWPerfFWFilter); - SrvInitParamUnreferenced(RGXBVNC); -#endif - SrvInitParamGetUINT32(psDevInfo->psDeviceNode, pvParamState, HWPerfHostFilter, psHints->ui32HWPerfHostFilter); - SrvInitParamGetUINT32List(psDevInfo->psDeviceNode, pvParamState, TimeCorrClock, psHints->ui32TimeCorrClock); - SrvInitParamGetUINT32(psDevInfo->psDeviceNode, pvParamState, HWRDebugDumpLimit, ui32ParamTemp); - psHints->ui32HWRDebugDumpLimit = MIN(ui32ParamTemp, RGXFWIF_HWR_DEBUG_DUMP_ALL); - - if (bS7TopInfra) - { - #define RGX_CR_JONES_FIX_MT_ORDER_ISP_TE_CLRMSK (0XFFFFFFCFU) - #define RGX_CR_JONES_FIX_MT_ORDER_ISP_EN (0X00000020U) - #define RGX_CR_JONES_FIX_MT_ORDER_TE_EN (0X00000010U) - - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, JonesDisableMask, ui32ParamTemp); - if (((ui32ParamTemp & ~RGX_CR_JONES_FIX_MT_ORDER_ISP_TE_CLRMSK) == RGX_CR_JONES_FIX_MT_ORDER_ISP_EN) || - ((ui32ParamTemp & ~RGX_CR_JONES_FIX_MT_ORDER_ISP_TE_CLRMSK) == RGX_CR_JONES_FIX_MT_ORDER_TE_EN)) - { - ui32ParamTemp |= (RGX_CR_JONES_FIX_MT_ORDER_TE_EN | - RGX_CR_JONES_FIX_MT_ORDER_ISP_EN); - PVR_DPF((PVR_DBG_WARNING, "Tile reordering mode requires both TE and ISP enabled. Forcing JonesDisableMask = %d", - ui32ParamTemp)); - } - psHints->ui32JonesDisableMask = ui32ParamTemp; - } - - if ((bE42290) && (bTPUFiltermodeCtrl)) - { - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, NewFilteringMode, psHints->bFilteringMode); - } - - if (bE42606) - { - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TruncateMode, psHints->ui32TruncateMode); - } -#if defined(EMULATOR) - if (bAXIACELite) - { - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, EnableTrustedDeviceAceConfig, psHints->bEnableTrustedDeviceAceConfig); - } -#endif - - SrvInitParamGetBOOL(psDevInfo->psDeviceNode, pvParamState, ZeroFreelist, psHints->bZeroFreelist); - -#if defined(__linux__) - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, FWContextSwitchCrossDM, psHints->ui32FWContextSwitchCrossDM); -#else - SrvInitParamUnreferenced(FWContextSwitchCrossDM); -#endif - -#if defined(SUPPORT_PHYSMEM_TEST) && !defined(INTEGRITY_OS) && !defined(__QNXNTO__) - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, PhysMemTestPasses, psHints->ui32PhysMemTestPasses); -#endif - -#if defined(SUPPORT_VALIDATION) - /* Apphints for TPU trilinear frac masking */ - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TPUTrilinearFracMaskPDM, psHints->aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_PDM]); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TPUTrilinearFracMaskVDM, psHints->aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_VDM]); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TPUTrilinearFracMaskCDM, psHints->aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_CDM]); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TPUTrilinearFracMaskTDM, psHints->aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_TDM]); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, ValidateIrq, psHints->bValidateIrq); - SrvInitParamGetBOOL(INITPARAM_NO_DEVICE, pvParamState, ValidateSOCUSCTimer, psHints->bValidateSOCUSCTimer); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, FBCDCVersionOverride, psHints->ui32FBCDCVersionOverride); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TFBCCompressionControlGroup, psHints->ui32TFBCCompressionControlGroup); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TFBCCompressionControlScheme, psHints->ui32TFBCCompressionControlScheme); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, TFBCCompressionControlYUVFormat, psHints->bTFBCCompressionControlYUVFormat); -#endif - - /* - * FW logs apphints - */ - { - IMG_UINT32 ui32LogGroup, ui32TraceOrTBI; - - SrvInitParamGetUINT32BitField(psDevInfo->psDeviceNode, pvParamState, EnableLogGroup, ui32LogGroup); - SrvInitParamGetUINT32List(psDevInfo->psDeviceNode, pvParamState, FirmwareLogType, ui32TraceOrTBI); - - /* Defaulting to TRACE */ - BITMASK_SET(ui32LogGroup, RGXFWIF_LOG_TYPE_TRACE); - -#if defined(SUPPORT_TBI_INTERFACE) - if (ui32TraceOrTBI == 1 /* TBI */) - { - if ((ui32LogGroup & RGXFWIF_LOG_TYPE_GROUP_MASK) == 0) - { - /* No groups configured - defaulting to MAIN group */ - BITMASK_SET(ui32LogGroup, RGXFWIF_LOG_TYPE_GROUP_MAIN); - } - BITMASK_UNSET(ui32LogGroup, RGXFWIF_LOG_TYPE_TRACE); - } -#endif - psHints->ui32LogType = ui32LogGroup; - } - - SrvInitParamClose(pvParamState); -} - - -/*! -******************************************************************************* - - @Function GetFWConfigFlags - - @Description Initialise and return FW config flags - - @Input psHints : Apphints container - @Input pui32FWConfigFlags : Pointer to config flags - - @Return void - -******************************************************************************/ -static INLINE void GetFWConfigFlags(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_SRVINIT_APPHINTS *psHints, - IMG_UINT32 *pui32FWConfigFlags, - IMG_UINT32 *pui32FWConfigFlagsExt, - IMG_UINT32 *pui32FwOsCfgFlags) -{ -#if defined(SUPPORT_VALIDATION) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -#endif - IMG_UINT32 ui32FWConfigFlags = 0; - IMG_UINT32 ui32FWConfigFlagsExt = 0; - - if (PVRSRV_VZ_MODE_IS(GUEST)) - { - ui32FWConfigFlags = 0; - ui32FWConfigFlagsExt = 0; - } - else - { - ui32FWConfigFlags |= psHints->bAssertOnOutOfMem ? RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY : 0; - ui32FWConfigFlags |= psHints->bAssertOnHWRTrigger ? RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER : 0; - ui32FWConfigFlags |= psHints->bCheckMlist ? RGXFWIF_INICFG_CHECK_MLIST_EN : 0; - ui32FWConfigFlags |= psHints->bDisableClockGating ? RGXFWIF_INICFG_DISABLE_CLKGATING_EN : 0; - ui32FWConfigFlags |= psHints->bDisableDMOverlap ? RGXFWIF_INICFG_DISABLE_DM_OVERLAP : 0; - ui32FWConfigFlags |= psHints->bDisablePDP ? RGXFWIF_INICFG_DISABLE_PDP_EN : 0; - ui32FWConfigFlags |= psHints->bEnableCDMKillRand ? RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN : 0; - ui32FWConfigFlags |= psHints->bEnableRandomCsw ? RGXFWIF_INICFG_CTXSWITCH_MODE_RAND : 0; - ui32FWConfigFlags |= psHints->bEnableSoftResetCsw ? RGXFWIF_INICFG_CTXSWITCH_SRESET_EN : 0; - ui32FWConfigFlags |= (psHints->ui32HWPerfFilter0 != 0 || psHints->ui32HWPerfFilter1 != 0) ? RGXFWIF_INICFG_HWPERF_EN : 0; - ui32FWConfigFlags |= psHints->bHWPerfDisableCustomCounterFilter ? RGXFWIF_INICFG_HWP_DISABLE_FILTER : 0; - ui32FWConfigFlags |= (psHints->ui32FWContextSwitchProfile << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT) & RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK; - -#if defined(SUPPORT_VALIDATION) -#if defined(NO_HARDWARE) && defined(PDUMP) - ui32FWConfigFlags |= psHints->bValidateIrq ? RGXFWIF_INICFG_VALIDATE_IRQ : 0; -#endif - - if (psHints->ui32FBCDCVersionOverride > 0) - { - ui32FWConfigFlags |= (psHints->ui32FBCDCVersionOverride == 2) ? RGXFWIF_INICFG_FBCDC_V3_1_EN : 0; - } - else -#endif /* defined(SUPPORT_VALIDATION) */ - { - ui32FWConfigFlags |= psDeviceNode->pfnHasFBCDCVersion31(psDeviceNode) ? RGXFWIF_INICFG_FBCDC_V3_1_EN : 0; - } - -#if defined(SUPPORT_VALIDATION) - ui32FWConfigFlags |= psHints->bValidateSOCUSCTimer ? RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER : 0; - - if ((ui32FWConfigFlags & RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER) && - ((psHints->eRGXActivePMConf != 0) || (psHints->eRGXRDPowerIslandConf != 0))) - { - psHints->eRGXActivePMConf = 0; - psHints->eRGXRDPowerIslandConf = 0; - PVR_DPF((PVR_DBG_WARNING, "SoC/USC Timer test needs to run with both EnableAPM and EnableRDPowerIsland disabled.\n" - "Overriding current value for both with new value 0.")); - } - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_LOSSY_37_PERCENT) || - RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_DELTA_CORRELATION) || - RGX_IS_FEATURE_SUPPORTED(psDevInfo, TFBC_NATIVE_YUV10)) - { - ui32FWConfigFlagsExt |= - ((((psHints->ui32TFBCCompressionControlGroup << RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_SHIFT) & - ~RGX_CR_TFBC_COMPRESSION_CONTROL_GROUP_CONTROL_CLRMSK) | - ((psHints->ui32TFBCCompressionControlScheme << RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_SHIFT) & - ~RGX_CR_TFBC_COMPRESSION_CONTROL_SCHEME_CLRMSK) | - ((psHints->bTFBCCompressionControlYUVFormat) ? RGX_CR_TFBC_COMPRESSION_CONTROL_YUV10_OVERRIDE_EN : 0)) - << RGXFWIF_INICFG_EXT_TFBC_CONTROL_SHIFT) & RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK; - } -#endif - } - - *pui32FWConfigFlags = ui32FWConfigFlags; - *pui32FWConfigFlagsExt = ui32FWConfigFlagsExt; - *pui32FwOsCfgFlags = psHints->ui32FWContextSwitchCrossDM | - (psHints->ui32EnableFWContextSwitch & ~RGXFWIF_INICFG_OS_CTXSWITCH_CLRMSK); -} - - -/*! -******************************************************************************* - - @Function GetFilterFlags - - @Description Initialise and return filter flags - - @Input psHints : Apphints container - - @Return IMG_UINT32 : Filter flags - -******************************************************************************/ -static INLINE IMG_UINT32 GetFilterFlags(RGX_SRVINIT_APPHINTS *psHints) -{ - IMG_UINT32 ui32FilterFlags = 0; - - ui32FilterFlags |= psHints->bFilteringMode ? RGXFWIF_FILTCFG_NEW_FILTER_MODE : 0; - if (psHints->ui32TruncateMode == 2) - { - ui32FilterFlags |= RGXFWIF_FILTCFG_TRUNCATE_INT; - } - else if (psHints->ui32TruncateMode == 3) - { - ui32FilterFlags |= RGXFWIF_FILTCFG_TRUNCATE_HALF; - } - - return ui32FilterFlags; -} - - -/*! -******************************************************************************* - - @Function InittDeviceFlags - - @Description Initialise and return device flags - - @Input psHints : Apphints container - @Input pui32DeviceFlags : Pointer to device flags - - @Return void - -******************************************************************************/ -static INLINE void InitDeviceFlags(RGX_SRVINIT_APPHINTS *psHints, - IMG_UINT32 *pui32DeviceFlags) -{ - IMG_UINT32 ui32DeviceFlags = 0; - - ui32DeviceFlags |= psHints->bGPUUnitsPowerChange ? RGXKM_DEVICE_STATE_GPU_UNITS_POWER_CHANGE_EN : 0; - ui32DeviceFlags |= psHints->bZeroFreelist ? RGXKM_DEVICE_STATE_ZERO_FREELIST : 0; - ui32DeviceFlags |= psHints->bDisableFEDLogging ? RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN : 0; -#if defined(PVRSRV_ENABLE_CCCB_GROW) - BITMASK_SET(ui32DeviceFlags, RGXKM_DEVICE_STATE_CCB_GROW_EN); -#endif - - *pui32DeviceFlags = ui32DeviceFlags; -} - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) -/*! -******************************************************************************* - - @Function RGXTDProcessFWImage - - @Description Fetch and send data used by the trusted device to complete - the FW image setup - - @Input psDeviceNode : Device node - @Input psRGXFW : Firmware blob - @Input puFWParams : Parameters used by the FW at boot time - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR RGXTDProcessFWImage(PVRSRV_DEVICE_NODE *psDeviceNode, - OS_FW_IMAGE *psRGXFW, - PVRSRV_FW_BOOT_PARAMS *puFWParams) -{ - PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_TD_FW_PARAMS sTDFWParams; - RGX_LAYER_PARAMS sLayerParams; - PVRSRV_ERROR eError; - - if (psDevConfig->pfnTDSendFWImage == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: TDSendFWImage not implemented!", __func__)); - return PVRSRV_ERROR_NOT_IMPLEMENTED; - } - - sLayerParams.psDevInfo = psDevInfo; - - sTDFWParams.pvFirmware = OSFirmwareData(psRGXFW); - sTDFWParams.ui32FirmwareSize = OSFirmwareSize(psRGXFW); - -#if defined(RGX_FEATURE_META_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - sTDFWParams.uFWP.sMeta = puFWParams->sMeta; - } - else -#endif - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - sTDFWParams.uFWP.sMips = puFWParams->sMips; - - if (sTDFWParams.uFWP.sMips.ui32FWPageTableNumPages > TD_MAX_NUM_MIPS_PAGETABLE_PAGES) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Number of page table pages %u greater " - "than what is allowed by the TD interface (%u), FW might " - "not work properly!", __func__, - puFWParams->sMips.ui32FWPageTableNumPages, - TD_MAX_NUM_MIPS_PAGETABLE_PAGES)); - } - } - else - { - sTDFWParams.uFWP.sRISCV = puFWParams->sRISCV; - } - - eError = psDevConfig->pfnTDSendFWImage(psDevConfig->hSysData, &sTDFWParams); - - return eError; -} -#endif - -/*! -******************************************************************************* - - @Function RGXAcquireMipsBootldrData - - @Description Acquire MIPS bootloader data parameters - - @Input psDeviceNode : Device node - @Input puFWParams : FW boot parameters - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR RGXAcquireMipsBootldrData(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_FW_BOOT_PARAMS *puFWParams) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*) psDeviceNode->pvDevice; - MMU_DEVICEATTRIBS *psFWMMUDevAttrs = psDevInfo->psDeviceNode->psFirmwareMMUDevAttrs; - IMG_DEV_PHYADDR sAddr; - IMG_UINT32 ui32PTSize, i; - PVRSRV_ERROR eError; - IMG_BOOL bValid; - - /* Rogue Registers physical address */ -#if defined(SUPPORT_ALT_REGBASE) - puFWParams->sMips.sGPURegAddr = psDeviceNode->psDevConfig->sAltRegsGpuPBase; -#else - PhysHeapCpuPAddrToDevPAddr(psDevInfo->psDeviceNode->apsPhysHeap[PVRSRV_PHYS_HEAP_GPU_LOCAL], - 1, - &puFWParams->sMips.sGPURegAddr, - &(psDeviceNode->psDevConfig->sRegsCpuPBase)); -#endif - - /* MIPS Page Table physical address */ - MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sAddr); - - /* MIPS Page Table allocation is contiguous. Pass one or more addresses - * to the FW depending on the Page Table size and alignment. */ - - ui32PTSize = (psFWMMUDevAttrs->psTopLevelDevVAddrConfig->uiNumEntriesPT) - << RGXMIPSFW_LOG2_PTE_ENTRY_SIZE; - ui32PTSize = PVR_ALIGN(ui32PTSize, 1U << psFWMMUDevAttrs->ui32BaseAlign); - - puFWParams->sMips.ui32FWPageTableLog2PageSize = psFWMMUDevAttrs->ui32BaseAlign; - puFWParams->sMips.ui32FWPageTableNumPages = ui32PTSize >> psFWMMUDevAttrs->ui32BaseAlign; - - if (puFWParams->sMips.ui32FWPageTableNumPages > 4U) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Page table cannot be mapped by the FW " - "(size 0x%x, log2 page size %u, %u pages)", - __func__, ui32PTSize, puFWParams->sMips.ui32FWPageTableLog2PageSize, - puFWParams->sMips.ui32FWPageTableNumPages)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - /* Confirm page alignment fits in 64-bits */ - if (psFWMMUDevAttrs->ui32BaseAlign > 63) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid page alignment " - "(psFWMMUDevAttrs->ui32BaseAlign = %u)", - __func__, psFWMMUDevAttrs->ui32BaseAlign)); - return PVRSRV_ERROR_INIT_FAILURE; - } - - for (i = 0; i < puFWParams->sMips.ui32FWPageTableNumPages; i++) - { - puFWParams->sMips.asFWPageTableAddr[i].uiAddr = - sAddr.uiAddr + i * (1ULL << psFWMMUDevAttrs->ui32BaseAlign); - } - - /* MIPS Stack Pointer Physical Address */ - eError = RGXGetPhyAddr(psDevInfo->psRGXFWDataMemDesc->psImport->hPMR, - &puFWParams->sMips.sFWStackAddr, - RGXGetFWImageSectionOffset(NULL, MIPS_STACK), - OSGetPageShift(), - 1, - &bValid); - - return eError; -} - -/*! -******************************************************************************* - - @Function InitFirmware - - @Description Allocate, initialise and pdump Firmware code and data memory - - @Input psDeviceNode : Device Node - @Input psHints : Apphints - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR InitFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_SRVINIT_APPHINTS *psHints) -{ - OS_FW_IMAGE *psRGXFW = NULL; - const IMG_BYTE *pbRGXFirmware = NULL; - - /* FW code memory */ - IMG_DEVMEM_SIZE_T uiFWCodeAllocSize; - void *pvFWCodeHostAddr; - - /* FW data memory */ - IMG_DEVMEM_SIZE_T uiFWDataAllocSize; - void *pvFWDataHostAddr; - - /* FW coremem code memory */ - IMG_DEVMEM_SIZE_T uiFWCorememCodeAllocSize; - void *pvFWCorememCodeHostAddr = NULL; - - /* FW coremem data memory */ - IMG_DEVMEM_SIZE_T uiFWCorememDataAllocSize; - void *pvFWCorememDataHostAddr = NULL; - - PVRSRV_FW_BOOT_PARAMS uFWParams; - RGX_LAYER_PARAMS sLayerParams; - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - IMG_BOOL bUseSecureFWData = -#if defined(RGX_FEATURE_META_IDX) - RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META) || -#endif -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - RGX_IS_FEATURE_SUPPORTED(psDevInfo, RISCV_FW_PROCESSOR) || -#endif - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS) && - RGX_GET_FEATURE_VALUE(psDevInfo, PHYS_BUS_WIDTH) > 32); -#endif - - /* - * Get pointer to Firmware image - */ - eError = RGXLoadAndGetFWData(psDeviceNode, &psRGXFW, &pbRGXFirmware); - - if (eError != PVRSRV_OK) - { - /* Error or confirmation message generated in RGXLoadAndGetFWData */ - goto fw_load_fail; - } - - sLayerParams.psDevInfo = psDevInfo; - - /* - * Allocate Firmware memory - */ - - eError = RGXGetFWImageAllocSize(&sLayerParams, - pbRGXFirmware, - OSFirmwareSize(psRGXFW), - &uiFWCodeAllocSize, - &uiFWDataAllocSize, - &uiFWCorememCodeAllocSize, - &uiFWCorememDataAllocSize); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXGetFWImageAllocSize failed", - __func__)); - goto cleanup_initfw; - } - - psDevInfo->ui32FWCodeSizeInBytes = uiFWCodeAllocSize; - -#if defined(SUPPORT_TRUSTED_DEVICE) && defined(RGX_FEATURE_META_DMA_BIT_MASK) - /* Disable META core memory allocation unless the META DMA is available */ - if (!RGX_DEVICE_HAS_FEATURE(&sLayerParams, META_DMA)) - { - uiFWCorememCodeAllocSize = 0; - uiFWCorememDataAllocSize = 0; - } -#endif - - psDevInfo->ui32FWCorememCodeSizeInBytes = uiFWCorememCodeAllocSize; - - eError = RGXInitAllocFWImgMem(psDeviceNode, - uiFWCodeAllocSize, - uiFWDataAllocSize, - uiFWCorememCodeAllocSize, - uiFWCorememDataAllocSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXInitAllocFWImgMem failed (%d)", - __func__, - eError)); - goto cleanup_initfw; - } - - /* - * Acquire pointers to Firmware allocations - */ - -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc, &pvFWCodeHostAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", cleanup_initfw); - -#else - /* We can't get a pointer to a secure FW allocation from within the DDK */ - pvFWCodeHostAddr = NULL; -#endif - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (bUseSecureFWData) - { - /* We can't get a pointer to a secure FW allocation from within the DDK */ - pvFWDataHostAddr = NULL; - } - else -#endif - { - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc, &pvFWDataHostAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", release_code); - } - -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - if (uiFWCorememCodeAllocSize) - { - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc, &pvFWCorememCodeHostAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", release_data); - } -#else - /* We can't get a pointer to a secure FW allocation from within the DDK */ - pvFWCorememCodeHostAddr = NULL; -#endif - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (bUseSecureFWData) - { - pvFWCorememDataHostAddr = NULL; - } - else -#endif - if (uiFWCorememDataAllocSize) - { - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfCorememDataStoreMemDesc, &pvFWCorememDataHostAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", release_corememcode); - } - - /* - * Prepare FW boot parameters - */ - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, MIPS)) - { - eError = RGXAcquireMipsBootldrData(psDeviceNode, &uFWParams); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXAcquireMipsBootldrData failed (%d)", - __func__, eError)); - goto release_fw_allocations; - } - } - else -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_IS_FEATURE_VALUE_SUPPORTED(psDevInfo, META)) - { - uFWParams.sMeta.sFWCodeDevVAddr = psDevInfo->sFWCodeDevVAddrBase; - uFWParams.sMeta.sFWDataDevVAddr = psDevInfo->sFWDataDevVAddrBase; - uFWParams.sMeta.sFWCorememCodeDevVAddr = psDevInfo->sFWCorememCodeDevVAddrBase; - uFWParams.sMeta.sFWCorememCodeFWAddr = psDevInfo->sFWCorememCodeFWAddr; - uFWParams.sMeta.uiFWCorememCodeSize = uiFWCorememCodeAllocSize; - uFWParams.sMeta.sFWCorememDataDevVAddr = psDevInfo->sFWCorememDataStoreDevVAddrBase; - uFWParams.sMeta.sFWCorememDataFWAddr = psDevInfo->sFWCorememDataStoreFWAddr; -#if defined(RGXFW_META_SUPPORT_2ND_THREAD) - uFWParams.sMeta.ui32NumThreads = 2; -#else - uFWParams.sMeta.ui32NumThreads = 1; -#endif - } - else -#endif - { - uFWParams.sRISCV.sFWCorememCodeDevVAddr = psDevInfo->sFWCorememCodeDevVAddrBase; - uFWParams.sRISCV.sFWCorememCodeFWAddr = psDevInfo->sFWCorememCodeFWAddr; - uFWParams.sRISCV.uiFWCorememCodeSize = uiFWCorememCodeAllocSize; - - uFWParams.sRISCV.sFWCorememDataDevVAddr = psDevInfo->sFWCorememDataStoreDevVAddrBase; - uFWParams.sRISCV.sFWCorememDataFWAddr = psDevInfo->sFWCorememDataStoreFWAddr; - uFWParams.sRISCV.uiFWCorememDataSize = uiFWCorememDataAllocSize; - } - - - /* - * Process the Firmware image and setup code and data segments. - * - * When the trusted device is enabled and the FW code lives - * in secure memory we will only setup the data segments here, - * while the code segments will be loaded to secure memory - * by the trusted device. - */ - if (!psDeviceNode->bAutoVzFwIsUp) - { - eError = RGXProcessFWImage(&sLayerParams, - pbRGXFirmware, - pvFWCodeHostAddr, - pvFWDataHostAddr, - pvFWCorememCodeHostAddr, - pvFWCorememDataHostAddr, - &uFWParams); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXProcessFWImage failed (%d)", - __func__, eError)); - goto release_fw_allocations; - } - } - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - RGXTDProcessFWImage(psDeviceNode, psRGXFW, &uFWParams); -#endif - - - /* - * PDump Firmware allocations - */ - -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Dump firmware code image"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWCodeMemDesc, - 0, - uiFWCodeAllocSize, - PDUMP_FLAGS_CONTINUOUS); -#endif - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (!bUseSecureFWData) -#endif - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Dump firmware data image"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWDataMemDesc, - 0, - uiFWDataAllocSize, - PDUMP_FLAGS_CONTINUOUS); - } - -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - if (uiFWCorememCodeAllocSize) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Dump firmware coremem code image"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWCorememCodeMemDesc, - 0, - uiFWCorememCodeAllocSize, - PDUMP_FLAGS_CONTINUOUS); - } -#endif - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (!bUseSecureFWData && uiFWCorememDataAllocSize) -#else - if (uiFWCorememDataAllocSize) -#endif - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Dump firmware coremem data store image"); - DevmemPDumpLoadMem(psDevInfo->psRGXFWIfCorememDataStoreMemDesc, - 0, - uiFWCorememDataAllocSize, - PDUMP_FLAGS_CONTINUOUS); - } - - /* - * Release Firmware allocations and clean up - */ - -release_fw_allocations: -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (!bUseSecureFWData && uiFWCorememDataAllocSize) -#else - if (uiFWCorememDataAllocSize) -#endif - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfCorememDataStoreMemDesc); - } -release_corememcode: -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - if (uiFWCorememCodeAllocSize) - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCorememCodeMemDesc); - } -#endif - -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) -release_data: -#endif -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(NO_HARDWARE) && !defined(SUPPORT_SECURITY_VALIDATION) - if (!bUseSecureFWData) -#endif - { - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWDataMemDesc); - } - -release_code: -#if !defined(SUPPORT_TRUSTED_DEVICE) || defined(NO_HARDWARE) || defined(SUPPORT_SECURITY_VALIDATION) - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWCodeMemDesc); -#endif -cleanup_initfw: - OSUnloadFirmware(psRGXFW); -fw_load_fail: - - return eError; -} - - -#if defined(PDUMP) -/*! -******************************************************************************* - - @Function InitialiseHWPerfCounters - - @Description Initialisation of hardware performance counters and dumping - them out to pdump, so that they can be modified at a later - point. - - @Input pvDevice - @Input psHWPerfDataMemDesc - @Input psHWPerfInitDataInt - - @Return void - -******************************************************************************/ - -static void InitialiseHWPerfCounters(PVRSRV_DEVICE_NODE *psDeviceNode, - void *pvDevice, - DEVMEM_MEMDESC *psHWPerfDataMemDesc, - RGXFWIF_HWPERF_CTL *psHWPerfInitDataInt) -{ - RGXFWIF_HWPERF_CTL_BLK *psHWPerfInitBlkData; - RGXFWIF_HWPERF_DA_BLK *psHWPerfInitDABlkData; - IMG_UINT32 ui32CntBlkModelLen; - const RGXFW_HWPERF_CNTBLK_TYPE_MODEL *asCntBlkTypeModel; - const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc; - IMG_UINT32 ui32BlockID, ui32BlkCfgIdx, ui32CounterIdx; - RGX_HWPERF_CNTBLK_RT_INFO sCntBlkRtInfo; - - ui32CntBlkModelLen = RGXGetHWPerfBlockConfig(&asCntBlkTypeModel); - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "HWPerf Counter Config starts here."); - - for (ui32BlkCfgIdx = 0; ui32BlkCfgIdx < ui32CntBlkModelLen; ui32BlkCfgIdx++) - { - IMG_UINT32 uiUnit; - IMG_BOOL bDirect; - - /* Exit early if this core does not have any of these counter blocks - * due to core type/BVNC features.... */ - psBlkTypeDesc = &asCntBlkTypeModel[ui32BlkCfgIdx]; - if (psBlkTypeDesc->pfnIsBlkPresent(psBlkTypeDesc, pvDevice, &sCntBlkRtInfo) == IMG_FALSE) - { - continue; - } - - /* Program all counters in one block so those already on may - * be configured off and vice-a-versa. */ - for (ui32BlockID = psBlkTypeDesc->ui32CntBlkIdBase; - ui32BlockID < psBlkTypeDesc->ui32CntBlkIdBase+sCntBlkRtInfo.ui32NumUnits; - ui32BlockID++) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "Unit %d Block : %s", - ui32BlockID-psBlkTypeDesc->ui32CntBlkIdBase, - psBlkTypeDesc->pszBlockNameComment); - - /* Get the block configure store to update from the global store of - * block configuration. This is used to remember the configuration - * between configurations and core power on in APM. - * For RGX_FEATURE_HWPERF_OCEANIC layout we have a different - * structure type to decode the HWPerf block. This is indicated by - * the RGX_CNTBLK_ID_DA_MASK bit being set in the block-ID value. */ - - bDirect = (psBlkTypeDesc->ui32IndirectReg == 0U); - uiUnit = ui32BlockID - psBlkTypeDesc->ui32CntBlkIdBase; - - if ((ui32BlockID & RGX_CNTBLK_ID_DA_MASK) == RGX_CNTBLK_ID_DA_MASK) - { - psHWPerfInitDABlkData = rgxfw_hwperf_get_da_block_ctl(ui32BlockID, psHWPerfInitDataInt); - - PVR_ASSERT(psHWPerfInitDABlkData); - - psHWPerfInitDABlkData->eBlockID = ui32BlockID; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "eBlockID: The Block ID for the layout block. See RGX_HWPERF_CNTBLK_ID for further information."); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitDABlkData->eBlockID) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitDABlkData->eBlockID, - PDUMP_FLAGS_CONTINUOUS); - - psHWPerfInitDABlkData->uiEnabled = 0U; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "uiEnabled: Set to 0x1 if the block needs to be enabled during playback."); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitDABlkData->uiEnabled) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitDABlkData->uiEnabled, - PDUMP_FLAGS_CONTINUOUS); - - psHWPerfInitDABlkData->uiNumCounters = 0U; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "uiNumCounters (X): Specifies the number of valid counters" - " [0..%d] which follow.", RGX_CNTBLK_COUNTERS_MAX); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitDABlkData->uiNumCounters) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitDABlkData->uiNumCounters, - PDUMP_FLAGS_CONTINUOUS); - - for (ui32CounterIdx = 0; ui32CounterIdx < RGX_CNTBLK_COUNTERS_MAX; ui32CounterIdx++) - { - psHWPerfInitDABlkData->aui32Counters[ui32CounterIdx] = IMG_UINT32_C(0x00000000); - - if (bDirect) - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "%s_COUNTER_%d", - psBlkTypeDesc->pszBlockNameComment, - ui32CounterIdx); - } - else - { - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "%s%d_COUNTER_%d", - psBlkTypeDesc->pszBlockNameComment, - uiUnit, ui32CounterIdx); - } - - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitDABlkData->aui32Counters[ui32CounterIdx]) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitDABlkData->aui32Counters[ui32CounterIdx], - PDUMP_FLAGS_CONTINUOUS); - } - } - else - { - psHWPerfInitBlkData = rgxfw_hwperf_get_block_ctl(ui32BlockID, psHWPerfInitDataInt); - /* Assert to check for HWPerf block mis-configuration */ - PVR_ASSERT(psHWPerfInitBlkData); - - psHWPerfInitBlkData->bValid = IMG_TRUE; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "bValid: This specifies if the layout block is valid for the given BVNC."); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitBlkData->bValid) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitBlkData->bValid, - PDUMP_FLAGS_CONTINUOUS); - - psHWPerfInitBlkData->bEnabled = IMG_FALSE; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "bEnabled: Set to 0x1 if the block needs to be enabled during playback."); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitBlkData->bEnabled) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitBlkData->bEnabled, - PDUMP_FLAGS_CONTINUOUS); - - psHWPerfInitBlkData->eBlockID = ui32BlockID; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "eBlockID: The Block ID for the layout block. See RGX_HWPERF_CNTBLK_ID for further information."); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitBlkData->eBlockID) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitBlkData->eBlockID, - PDUMP_FLAGS_CONTINUOUS); - - psHWPerfInitBlkData->uiCounterMask = 0x00; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "uiCounterMask: Bitmask for selecting the counters that need to be configured. (Bit 0 - counter0, bit 1 - counter1 and so on.)"); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitBlkData->uiCounterMask) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitBlkData->uiCounterMask, - PDUMP_FLAGS_CONTINUOUS); - - for (ui32CounterIdx = RGX_CNTBLK_COUNTER0_ID; ui32CounterIdx < psBlkTypeDesc->ui8NumCounters; ui32CounterIdx++) - { - psHWPerfInitBlkData->aui64CounterCfg[ui32CounterIdx] = IMG_UINT64_C(0x0000000000000000); - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "%s_COUNTER_%d", psBlkTypeDesc->pszBlockNameComment, ui32CounterIdx); - DevmemPDumpLoadMemValue64(psHWPerfDataMemDesc, - (size_t)&(psHWPerfInitBlkData->aui64CounterCfg[ui32CounterIdx]) - (size_t)(psHWPerfInitDataInt), - psHWPerfInitBlkData->aui64CounterCfg[ui32CounterIdx], - PDUMP_FLAGS_CONTINUOUS); - - } - } - } - } -} -/*! -******************************************************************************* - - @Function InitialiseCustomCounters - - @Description Initialisation of custom counters and dumping them out to - pdump, so that they can be modified at a later point. - - @Input psHWPerfDataMemDesc - - @Return void - -******************************************************************************/ - -static void InitialiseCustomCounters(PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psHWPerfDataMemDesc) -{ - IMG_UINT32 ui32CustomBlock, ui32CounterID; - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "ui32SelectedCountersBlockMask - The Bitmask of the custom counters that are to be selected"); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - offsetof(RGXFWIF_HWPERF_CTL, ui32SelectedCountersBlockMask), - 0, - PDUMP_FLAGS_CONTINUOUS); - - for (ui32CustomBlock = 0; ui32CustomBlock < RGX_HWPERF_MAX_CUSTOM_BLKS; ui32CustomBlock++) - { - /* - * Some compilers cannot cope with the use of offsetof() below - the specific problem being the use of - * a non-const variable in the expression, which it needs to be const. Typical compiler error produced is - * "expression must have a constant value". - */ - const IMG_DEVMEM_OFFSET_T uiOffsetOfCustomBlockSelectedCounters - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_HWPERF_CTL *)0)->SelCntr[ui32CustomBlock].ui32NumSelectedCounters); - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "ui32NumSelectedCounters - The Number of counters selected for this Custom Block: %d",ui32CustomBlock ); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - uiOffsetOfCustomBlockSelectedCounters, - 0, - PDUMP_FLAGS_CONTINUOUS); - - for (ui32CounterID = 0; ui32CounterID < RGX_HWPERF_MAX_CUSTOM_CNTRS; ui32CounterID++ ) - { - const IMG_DEVMEM_OFFSET_T uiOffsetOfCustomBlockSelectedCounterIDs - = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_HWPERF_CTL *)0)->SelCntr[ui32CustomBlock].aui32SelectedCountersIDs[ui32CounterID]); - - PDUMPCOMMENTWITHFLAGS(psDeviceNode, PDUMP_FLAGS_CONTINUOUS, - "CUSTOMBLK_%d_COUNTERID_%d",ui32CustomBlock, ui32CounterID); - DevmemPDumpLoadMemValue32(psHWPerfDataMemDesc, - uiOffsetOfCustomBlockSelectedCounterIDs, - 0, - PDUMP_FLAGS_CONTINUOUS); - } - } -} - -/*! -******************************************************************************* - - @Function InitialiseAllCounters - - @Description Initialise HWPerf and custom counters - - @Input psDeviceNode : Device Node - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR InitialiseAllCounters(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - RGXFWIF_HWPERF_CTL *psHWPerfInitData; - PVRSRV_ERROR eError; - - eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfHWPerfCountersMemDesc, (void **)&psHWPerfInitData); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", failHWPerfCountersMemDescAqCpuVirt); - - InitialiseHWPerfCounters(psDeviceNode, psDevInfo, psDevInfo->psRGXFWIfHWPerfCountersMemDesc, psHWPerfInitData); - InitialiseCustomCounters(psDeviceNode, psDevInfo->psRGXFWIfHWPerfCountersMemDesc); - -failHWPerfCountersMemDescAqCpuVirt: - DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfHWPerfCountersMemDesc); - - return eError; -} -#endif /* PDUMP */ - -/* - * _ParseHTBAppHints: - * - * Generate necessary references to the globally visible AppHints which are - * declared in the above #include "km_apphint_defs.h" - * Without these local references some compiler tool-chains will treat - * unreferenced declarations as fatal errors. This function duplicates the - * HTB_specific apphint references which are made in htbserver.c:HTBInit() - * However, it makes absolutely *NO* use of these hints. - */ -static void -_ParseHTBAppHints(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - void *pvParamState = NULL; - IMG_UINT32 ui32LogType; - IMG_UINT32 ui32BufferSize; - IMG_UINT32 ui32OpMode; - - /* Services initialisation parameters */ - pvParamState = SrvInitParamOpen(); - if (pvParamState == NULL) - return; - - SrvInitParamGetUINT32BitField(INITPARAM_NO_DEVICE, pvParamState, EnableHTBLogGroup, ui32LogType); - SrvInitParamGetUINT32List(INITPARAM_NO_DEVICE, pvParamState, HTBOperationMode, ui32OpMode); - SrvInitParamGetUINT32(INITPARAM_NO_DEVICE, pvParamState, HTBufferSizeInKB, ui32BufferSize); - - SrvInitParamClose(pvParamState); -} - -#if defined(SUPPORT_TRUSTED_DEVICE) -static PVRSRV_ERROR RGXValidateTDHeap(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_PHYS_HEAP ePhysHeap, - PHYS_HEAP_USAGE_FLAGS ui32RequiredFlags) -{ - PHYS_HEAP *psHeap = psDeviceNode->apsPhysHeap[ePhysHeap]; - PHYS_HEAP_USAGE_FLAGS ui32HeapFlags = PhysHeapGetFlags(psHeap); - PHYS_HEAP_USAGE_FLAGS ui32InvalidFlags = ~(PHYS_HEAP_USAGE_FW_PRIV_DATA | PHYS_HEAP_USAGE_FW_CODE - | PHYS_HEAP_USAGE_GPU_SECURE); - - PVR_LOG_RETURN_IF_FALSE_VA((ui32HeapFlags & ui32RequiredFlags) != 0, - PVRSRV_ERROR_NOT_SUPPORTED, - "TD heap is missing required flags. flags: 0x%x / required:0x%x", - ui32HeapFlags, - ui32RequiredFlags); - - PVR_LOG_RETURN_IF_FALSE_VA((ui32HeapFlags & ui32InvalidFlags) == 0, - PVRSRV_ERROR_NOT_SUPPORTED, - "TD heap uses invalid flags. flags: 0x%x / invalid:0x%x", - ui32HeapFlags, - ui32InvalidFlags); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXValidateTDHeaps(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - eError = RGXValidateTDHeap(psDeviceNode, PVRSRV_PHYS_HEAP_FW_PRIV_DATA, PHYS_HEAP_USAGE_FW_PRIV_DATA); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXValidateTDHeap:FW_PRIV_DATA"); - - eError = RGXValidateTDHeap(psDeviceNode, PVRSRV_PHYS_HEAP_FW_CODE, PHYS_HEAP_USAGE_FW_CODE); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXValidateTDHeap:FW_CODE"); - - eError = RGXValidateTDHeap(psDeviceNode, PVRSRV_PHYS_HEAP_GPU_SECURE, PHYS_HEAP_USAGE_GPU_SECURE); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXValidateTDHeap:GPU_SECURE"); - - return PVRSRV_OK; -} -#endif - -/*! -******************************************************************************* - - @Function RGXInit - - @Description RGX Initialisation - - @Input psDeviceNode - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXInit(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - /* Services initialisation parameters */ - RGX_SRVINIT_APPHINTS sApphints = {0}; - IMG_UINT32 ui32FWConfigFlags, ui32FWConfigFlagsExt, ui32FwOsCfgFlags; - IMG_UINT32 ui32DeviceFlags; - - PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - RGX_LAYER_PARAMS sLayerParams; - - PDUMPCOMMENT(psDeviceNode, "RGX Initialisation Part 1"); - - PDUMPCOMMENT(psDeviceNode, "Device Name: %s", - psDeviceNode->psDevConfig->pszName); - PDUMPCOMMENT(psDeviceNode, "Device ID: %u (%d)", - psDeviceNode->sDevId.ui32InternalID, - psDeviceNode->sDevId.i32OsDeviceID); - - if (psDeviceNode->psDevConfig->pszVersion) - { - PDUMPCOMMENT(psDeviceNode, "Device Version: %s", - psDeviceNode->psDevConfig->pszVersion); - } - - /* pdump info about the core */ - PDUMPCOMMENT(psDeviceNode, - "RGX Version Information (KM): %d.%d.%d.%d", - psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); - - RGXInitMultiCoreInfo(psDeviceNode); - -#if defined(PDUMP) - eError = DevmemIntAllocDefBackingPage(psDeviceNode, - &psDeviceNode->sDummyPage, - PVR_DUMMY_PAGE_INIT_VALUE, - DUMMY_PAGE, - IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate dummy page.", __func__)); - goto cleanup; - } - - eError = DevmemIntAllocDefBackingPage(psDeviceNode, - &psDeviceNode->sDevZeroPage, - PVR_ZERO_PAGE_INIT_VALUE, - DEV_ZERO_PAGE, - IMG_TRUE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate Zero page.", __func__)); - goto cleanup; - } -#endif /* defined(PDUMP) */ - - sLayerParams.psDevInfo = psDevInfo; -#if defined(SUPPORT_TRUSTED_DEVICE) - eError = RGXValidateTDHeaps(psDeviceNode); - PVR_LOG_RETURN_IF_ERROR(eError, "RGXValidateTDHeaps"); -#endif - -#if defined(SUPPORT_AUTOVZ) - if (PVRSRV_VZ_MODE_IS(HOST)) - { - /* The RGX_CR_MTS_DM0_INTERRUPT_ENABLE register is always set by the firmware during initialisation - * and it provides a good method of determining if the firmware has been booted previously */ - psDeviceNode->bAutoVzFwIsUp = (OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_DM0_INTERRUPT_ENABLE) != 0); - - PVR_LOG(("AutoVz startup check: firmware is %s;", - (psDeviceNode->bAutoVzFwIsUp) ? "already running" : "powered down")); - } - else if (PVRSRV_VZ_MODE_IS(GUEST)) - { - /* Guest assumes the firmware is always available */ - psDeviceNode->bAutoVzFwIsUp = IMG_TRUE; - } - else -#endif - { - /* Firmware does not follow the AutoVz life-cycle */ - psDeviceNode->bAutoVzFwIsUp = IMG_FALSE; - } - - if (PVRSRV_VZ_MODE_IS(GUEST) || (psDeviceNode->bAutoVzFwIsUp)) - { - /* set the device power state here as the regular power - * callbacks will not be executed on this driver */ - psDevInfo->bRGXPowered = IMG_TRUE; - } - - /* Set which HW Safety Events will be handled by the driver */ -#if defined(RGX_FEATURE_WATCHDOG_TIMER_BIT_MASK) - psDevInfo->ui32HostSafetyEventMask |= RGX_IS_FEATURE_SUPPORTED(psDevInfo, WATCHDOG_TIMER) ? - RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN : 0; -#endif -#if defined(RGX_FEATURE_ECC_RAMS_MAX_VALUE_IDX) - psDevInfo->ui32HostSafetyEventMask |= (RGX_DEVICE_HAS_FEATURE_VALUE(&sLayerParams, ECC_RAMS) - && (RGX_DEVICE_GET_FEATURE_VALUE(&sLayerParams, ECC_RAMS) > 0)) ? - RGX_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN : 0; -#endif - - /* Services initialisation parameters */ - _ParseHTBAppHints(psDeviceNode); - GetApphints(psDevInfo, &sApphints); - InitDeviceFlags(&sApphints, &ui32DeviceFlags); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#if defined(EMULATOR) - if ((sApphints.bEnableTrustedDeviceAceConfig) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, AXI_ACELITE))) - { - SetTrustedDeviceAceEnabled(); - } -#endif -#endif - - eError = RGXInitCreateFWKernelMemoryContext(psDeviceNode); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create FW kernel memory context (%u)", - __func__, eError)); - goto cleanup; - } - - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = InitFirmware(psDeviceNode, &sApphints); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: InitFirmware failed (%d)", - __func__, eError)); - goto cleanup; - } - } - - /* - * Setup Firmware initialisation data - */ - - GetFWConfigFlags(psDeviceNode, &sApphints, &ui32FWConfigFlags, &ui32FWConfigFlagsExt, &ui32FwOsCfgFlags); - - eError = RGXInitFirmware(psDeviceNode, - sApphints.bEnableSignatureChecks, - sApphints.ui32SignatureChecksBufSize, - sApphints.ui32HWPerfFWBufSize, - (IMG_UINT64)sApphints.ui32HWPerfFilter0 | - ((IMG_UINT64)sApphints.ui32HWPerfFilter1 << 32), - ui32FWConfigFlags, - sApphints.ui32LogType, - GetFilterFlags(&sApphints), - sApphints.ui32JonesDisableMask, - sApphints.ui32HWRDebugDumpLimit, - sizeof(RGXFWIF_HWPERF_CTL), -#if defined(SUPPORT_VALIDATION) - &sApphints.aui32TPUTrilinearFracMask[0], -#else - NULL, -#endif - sApphints.eRGXRDPowerIslandConf, - sApphints.eFirmwarePerf, - sApphints.ui32KCCBSizeLog2, - ui32FWConfigFlagsExt, - ui32FwOsCfgFlags); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXInitFirmware failed (%d)", - __func__, - eError)); - goto cleanup; - } - -#if defined(PDUMP) - if (!PVRSRV_VZ_MODE_IS(GUEST)) - { - eError = InitialiseAllCounters(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: InitialiseAllCounters failed (%d)", - __func__, eError)); - goto cleanup; - } - } -#endif - - /* - * Perform second stage of RGX initialisation - */ - eError = RGXInitDevPart2(psDeviceNode, - ui32DeviceFlags, - sApphints.ui32HWPerfHostFilter, - sApphints.eRGXActivePMConf); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXInitDevPart2 failed (%d)", - __func__, eError)); - goto cleanup; - } - -#if defined(SUPPORT_VALIDATION) - PVRSRVAppHintDumpState(psDeviceNode); -#endif - - eError = PVRSRV_OK; - -cleanup: - return eError; -} - -/****************************************************************************** - End of file (rgxsrvinit.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.c b/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.c deleted file mode 100644 index 2d213e3540c6c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.c +++ /dev/null @@ -1,1331 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific start/stop routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific start/stop routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* The routines implemented here are built on top of an abstraction layer to - * hide DDK/OS-specific details in case they are used outside of the DDK - * (e.g. when trusted device is enabled). - * Any new dependency should be added to rgxlayer.h. - * Any new code should be built on top of the existing abstraction layer, - * which should be extended when necessary. */ -#include "rgxstartstop.h" - -#if defined(SUPPORT_SHARED_SLC) -#include "rgxapi_km.h" -#endif - -#include "rgxdevice.h" -#include "km/rgxdefs_km.h" - -#define SOC_FEATURE_STRICT_SAME_ADDRESS_WRITE_ORDERING - - -/*! -******************************************************************************* - - @Function RGXEnableClocks - - @Description Enable RGX Clocks - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXEnableClocks(const void *hPrivate) -{ - RGXCommentLog(hPrivate, "RGX clock: use default (automatic clock gating)"); -} - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) -static PVRSRV_ERROR RGXWriteMetaRegThroughSP(const void *hPrivate, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Wait for Slave Port to be Ready */ - eError = RGXPollReg32(hPrivate, - RGX_CR_META_SP_MSLVCTRL1, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN); - if (eError != PVRSRV_OK) return eError; - - /* Issue a Write */ - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVCTRL0, ui32RegAddr); - (void)RGXReadReg32(hPrivate, RGX_CR_META_SP_MSLVCTRL0); /* Fence write */ - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVDATAT, ui32RegValue); - (void)RGXReadReg32(hPrivate, RGX_CR_META_SP_MSLVDATAT); /* Fence write */ - - return eError; -} - -static PVRSRV_ERROR RGXReadMetaRegThroughSP(const void *hPrivate, - IMG_UINT32 ui32RegAddr, - IMG_UINT32* ui32RegValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Wait for Slave Port to be Ready */ - eError = RGXPollReg32(hPrivate, - RGX_CR_META_SP_MSLVCTRL1, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN); - if (eError != PVRSRV_OK) return eError; - - /* Issue a Read */ - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVCTRL0, ui32RegAddr | RGX_CR_META_SP_MSLVCTRL0_RD_EN); - (void)RGXReadReg32(hPrivate, RGX_CR_META_SP_MSLVCTRL0); /* Fence write */ - - /* Wait for Slave Port to be Ready */ - eError = RGXPollReg32(hPrivate, - RGX_CR_META_SP_MSLVCTRL1, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN); - if (eError != PVRSRV_OK) return eError; - -#if !defined(NO_HARDWARE) - *ui32RegValue = RGXReadReg32(hPrivate, RGX_CR_META_SP_MSLVDATAX); -#else - *ui32RegValue = 0xFFFFFFFF; -#endif - - return eError; -} - -static PVRSRV_ERROR RGXWriteMetaCoreRegThoughSP(const void *hPrivate, - IMG_UINT32 ui32CoreReg, - IMG_UINT32 ui32Value) -{ - IMG_UINT32 i = 0; - - RGXWriteMetaRegThroughSP(hPrivate, META_CR_TXUXXRXDT_OFFSET, ui32Value); - RGXWriteMetaRegThroughSP(hPrivate, META_CR_TXUXXRXRQ_OFFSET, ui32CoreReg & ~META_CR_TXUXXRXRQ_RDnWR_BIT); - - do - { - RGXReadMetaRegThroughSP(hPrivate, META_CR_TXUXXRXRQ_OFFSET, &ui32Value); - } while (((ui32Value & META_CR_TXUXXRXRQ_DREADY_BIT) != META_CR_TXUXXRXRQ_DREADY_BIT) && (i++ < 1000)); - - if (i == 1000) - { - RGXCommentLog(hPrivate, "RGXWriteMetaCoreRegThoughSP: Timeout"); - return PVRSRV_ERROR_TIMEOUT; - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR RGXStartFirmware(const void *hPrivate) -{ - PVRSRV_ERROR eError; - - /* Give privilege to debug and slave port */ - RGXWriteMetaRegThroughSP(hPrivate, META_CR_SYSC_JTAG_THREAD, META_CR_SYSC_JTAG_THREAD_PRIV_EN); - - /* Point Meta to the bootloader address, global (uncached) range */ - eError = RGXWriteMetaCoreRegThoughSP(hPrivate, - PC_ACCESS(0), - RGXFW_BOOTLDR_META_ADDR | META_MEM_GLOBAL_RANGE_BIT); - - if (eError != PVRSRV_OK) - { - RGXCommentLog(hPrivate, "RGXStart: RGX Firmware Slave boot Start failed!"); - return eError; - } - - /* Enable minim encoding */ - RGXWriteMetaRegThroughSP(hPrivate, META_CR_TXPRIVEXT, META_CR_TXPRIVEXT_MINIM_EN); - - /* Enable Meta thread */ - RGXWriteMetaRegThroughSP(hPrivate, META_CR_T0ENABLE_OFFSET, META_CR_TXENABLE_ENABLE_BIT); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RGXInitMetaProcWrapper - - @Description Configures the hardware wrapper of the META processor - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXInitMetaProcWrapper(const void *hPrivate) -{ - IMG_UINT64 ui64GartenConfig; - - /* Set Garten IDLE to META idle and Set the Garten Wrapper BIF Fence address */ - - /* Garten IDLE bit controlled by META */ - ui64GartenConfig = RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META; - - /* The fence addr is set at the fw init sequence */ - - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - /* Set PC = 0 for fences */ - ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_CLRMSK; - ui64GartenConfig |= (IMG_UINT64)MMU_CONTEXT_MAPPING_FWPRIV - << RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_SHIFT; - - } - else - { - /* Set PC = 0 for fences */ - ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK; - ui64GartenConfig |= (IMG_UINT64)MMU_CONTEXT_MAPPING_FWPRIV - << RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT; - - /* Set SLC DM=META */ - ui64GartenConfig |= ((IMG_UINT64) RGXFW_SEGMMU_META_BIFDM_ID) << RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT; - } - - RGXCommentLog(hPrivate, "RGXStart: Configure META wrapper"); - RGXWriteReg64(hPrivate, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, ui64GartenConfig); -} -#endif - -/*! -******************************************************************************* - - @Function RGXInitMipsProcWrapper - - @Description Configures the hardware wrapper of the MIPS processor - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXInitMipsProcWrapper(const void *hPrivate) -{ - IMG_DEV_PHYADDR sPhyAddr; - IMG_UINT64 ui64RemapSettings = RGXMIPSFW_BOOT_REMAP_LOG2_SEGMENT_SIZE; /* Same for all remap registers */ - - RGXCommentLog(hPrivate, "RGXStart: Configure MIPS wrapper"); - - /* - * MIPS wrapper (registers transaction ID and ISA mode) setup - */ - - RGXCommentLog(hPrivate, "RGXStart: Write wrapper config register"); - - if (RGXGetDevicePhysBusWidth(hPrivate) > 32) - { - RGXWriteReg32(hPrivate, - RGX_CR_MIPS_WRAPPER_CONFIG, - (RGXMIPSFW_REGISTERS_VIRTUAL_BASE >> - RGXMIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN) | - RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS); - } - else - { - RGXAcquireGPURegsAddr(hPrivate, &sPhyAddr); - - RGXMIPSWrapperConfig(hPrivate, - RGX_CR_MIPS_WRAPPER_CONFIG, - sPhyAddr.uiAddr, - RGXMIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN, - RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS); - } - - /* - * Boot remap setup - */ - - RGXAcquireBootRemapAddr(hPrivate, &sPhyAddr); - -#if defined(SUPPORT_TRUSTED_DEVICE) - /* Do not mark accesses to a FW code remap region as DRM accesses */ - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK; -#endif - -#if defined(MIPS_FW_CODE_OSID) - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK; - ui64RemapSettings |= MIPS_FW_CODE_OSID << RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_SHIFT; -#endif - - RGXCommentLog(hPrivate, "RGXStart: Write boot remap registers"); - RGXBootRemapConfig(hPrivate, - RGX_CR_MIPS_ADDR_REMAP1_CONFIG1, - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN | RGX_CR_MIPS_ADDR_REMAP1_CONFIG1_MODE_ENABLE_EN, - RGX_CR_MIPS_ADDR_REMAP1_CONFIG2, - sPhyAddr.uiAddr, - ~RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_CLRMSK, - ui64RemapSettings); - -#if defined(FIX_HW_BRN_63553_BIT_MASK) - if (RGX_DEVICE_HAS_BRN(hPrivate, 63553)) - { - IMG_BOOL bPhysBusAbove32Bit = RGXGetDevicePhysBusWidth(hPrivate) > 32; - IMG_BOOL bDevicePA0IsValid = RGXDevicePA0IsValid(hPrivate); - - /* WA always required on 36 bit cores, to avoid continuous unmapped memory accesses to address 0x0 */ - if (bPhysBusAbove32Bit || !bDevicePA0IsValid) - { - RGXCodeRemapConfig(hPrivate, - RGX_CR_MIPS_ADDR_REMAP5_CONFIG1, - 0x0 | RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_EN, - RGX_CR_MIPS_ADDR_REMAP5_CONFIG2, - sPhyAddr.uiAddr, - ~RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_CLRMSK, - ui64RemapSettings); - } - } -#endif - - /* - * Data remap setup - */ - - RGXAcquireDataRemapAddr(hPrivate, &sPhyAddr); - -#if defined(SUPPORT_TRUSTED_DEVICE) - if (RGXGetDevicePhysBusWidth(hPrivate) > 32) - { - /* Remapped private data in secure memory */ - ui64RemapSettings |= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_EN; - } - else - { - /* Remapped data in non-secure memory */ - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK; - } -#endif - -#if defined(MIPS_FW_CODE_OSID) - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK; -#endif - - RGXCommentLog(hPrivate, "RGXStart: Write data remap registers"); - RGXDataRemapConfig(hPrivate, - RGX_CR_MIPS_ADDR_REMAP2_CONFIG1, - RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN | RGX_CR_MIPS_ADDR_REMAP2_CONFIG1_MODE_ENABLE_EN, - RGX_CR_MIPS_ADDR_REMAP2_CONFIG2, - sPhyAddr.uiAddr, - ~RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_CLRMSK, - ui64RemapSettings); - - /* - * Code remap setup - */ - - RGXAcquireCodeRemapAddr(hPrivate, &sPhyAddr); - -#if defined(SUPPORT_TRUSTED_DEVICE) - /* Do not mark accesses to a FW code remap region as DRM accesses */ - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK; -#endif - -#if defined(MIPS_FW_CODE_OSID) - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK; - ui64RemapSettings |= MIPS_FW_CODE_OSID << RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_SHIFT; -#endif - - RGXCommentLog(hPrivate, "RGXStart: Write exceptions remap registers"); - RGXCodeRemapConfig(hPrivate, - RGX_CR_MIPS_ADDR_REMAP3_CONFIG1, - RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN | RGX_CR_MIPS_ADDR_REMAP3_CONFIG1_MODE_ENABLE_EN, - RGX_CR_MIPS_ADDR_REMAP3_CONFIG2, - sPhyAddr.uiAddr, - ~RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_CLRMSK, - ui64RemapSettings); - - if (RGXGetDevicePhysBusWidth(hPrivate) == 32) - { - /* - * Trampoline remap setup - */ - - RGXAcquireTrampolineRemapAddr(hPrivate, &sPhyAddr); - ui64RemapSettings = RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE; - -#if defined(SUPPORT_TRUSTED_DEVICE) - /* Remapped data in non-secure memory */ - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK; -#endif - -#if defined(MIPS_FW_CODE_OSID) - ui64RemapSettings &= RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK; -#endif - - RGXCommentLog(hPrivate, "RGXStart: Write trampoline remap registers"); - RGXTrampolineRemapConfig(hPrivate, - RGX_CR_MIPS_ADDR_REMAP4_CONFIG1, - sPhyAddr.uiAddr | RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_EN, - RGX_CR_MIPS_ADDR_REMAP4_CONFIG2, - RGXMIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR, - ~RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_ADDR_OUT_CLRMSK, - ui64RemapSettings); - } - - /* Garten IDLE bit controlled by MIPS */ - RGXCommentLog(hPrivate, "RGXStart: Set GARTEN_IDLE type to MIPS"); - RGXWriteReg64(hPrivate, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META); - - /* Turn on the EJTAG probe (only useful driver live) */ - RGXWriteReg32(hPrivate, RGX_CR_MIPS_DEBUG_CONFIG, 0); -} - - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) -/*! -******************************************************************************* - - @Function RGXInitRiscvProcWrapper - - @Description Configures the hardware wrapper of the RISCV processor - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXInitRiscvProcWrapper(const void *hPrivate) -{ - IMG_DEV_VIRTADDR sTmp; - - RGXCommentLog(hPrivate, "RGXStart: Configure RISCV wrapper"); - - RGXCommentLog(hPrivate, "RGXStart: Write boot code remap"); - RGXAcquireBootCodeAddr(hPrivate, &sTmp); - RGXWriteReg64(hPrivate, - RGXRISCVFW_BOOTLDR_CODE_REMAP, - sTmp.uiAddr | - (IMG_UINT64) (RGX_FIRMWARE_RAW_HEAP_SIZE >> FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT) - << RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT | - (IMG_UINT64) MMU_CONTEXT_MAPPING_FWPRIV << FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT | - RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_EN); - - RGXCommentLog(hPrivate, "RGXStart: Write boot data remap"); - RGXAcquireBootDataAddr(hPrivate, &sTmp); - RGXWriteReg64(hPrivate, - RGXRISCVFW_BOOTLDR_DATA_REMAP, - sTmp.uiAddr | - (IMG_UINT64) (RGX_FIRMWARE_RAW_HEAP_SIZE >> FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT) - << RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT | - (IMG_UINT64) MMU_CONTEXT_MAPPING_FWPRIV << FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT | -#if defined(SUPPORT_TRUSTED_DEVICE) - RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_EN | -#endif - RGX_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_EN); - - /* Garten IDLE bit controlled by RISCV */ - RGXCommentLog(hPrivate, "RGXStart: Set GARTEN_IDLE type to RISCV"); - RGXWriteReg64(hPrivate, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META); -} -#endif - - -/*! -******************************************************************************* - - @Function __RGXInitSLC - - @Description Initialise RGX SLC - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void __RGXInitSLC(const void *hPrivate) -{ -#if defined(RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_CACHE_HIERARCHY)) - { - IMG_UINT32 ui32Reg; - IMG_UINT32 ui32RegVal; - - /* - * SLC control - */ - ui32Reg = RGX_CR_SLC3_CTRL_MISC; - ui32RegVal = RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SCRAMBLE_PVR_HASH | - RGX_CR_SLC3_CTRL_MISC_WRITE_COMBINER_EN; - RGXWriteReg32(hPrivate, ui32Reg, ui32RegVal); - - /* - * SLC scramble bits - */ - { - IMG_UINT32 i; - IMG_UINT32 ui32Count=0; - IMG_UINT32 ui32SLCBanks = RGXGetDeviceSLCBanks(hPrivate); - IMG_UINT64 aui64ScrambleValues[4]; - IMG_UINT32 aui32ScrambleRegs[] = { - RGX_CR_SLC3_SCRAMBLE, - RGX_CR_SLC3_SCRAMBLE2, - RGX_CR_SLC3_SCRAMBLE3, - RGX_CR_SLC3_SCRAMBLE4 - }; - - if (2 == ui32SLCBanks) - { - aui64ScrambleValues[0] = IMG_UINT64_C(0x6965a99a55696a6a); - aui64ScrambleValues[1] = IMG_UINT64_C(0x6aa9aa66959aaa9a); - aui64ScrambleValues[2] = IMG_UINT64_C(0x9a5665965a99a566); - aui64ScrambleValues[3] = IMG_UINT64_C(0x5aa69596aa66669a); - ui32Count = 4; - } - else if (4 == ui32SLCBanks) - { - aui64ScrambleValues[0] = IMG_UINT64_C(0xc6788d722dd29ce4); - aui64ScrambleValues[1] = IMG_UINT64_C(0x7272e4e11b279372); - aui64ScrambleValues[2] = IMG_UINT64_C(0x87d872d26c6c4be1); - aui64ScrambleValues[3] = IMG_UINT64_C(0xe1b4878d4b36e478); - ui32Count = 4; - - } - else if (8 == ui32SLCBanks) - { - aui64ScrambleValues[0] = IMG_UINT64_C(0x859d6569e8fac688); - aui64ScrambleValues[1] = IMG_UINT64_C(0xf285e1eae4299d33); - aui64ScrambleValues[2] = IMG_UINT64_C(0x1e1af2be3c0aa447); - ui32Count = 3; - } - - for (i = 0; i < ui32Count; i++) - { - IMG_UINT32 ui32Reg = aui32ScrambleRegs[i]; - IMG_UINT64 ui64Value = aui64ScrambleValues[i]; - RGXWriteReg64(hPrivate, ui32Reg, ui64Value); - } - } - - { - /* Disable the forced SLC coherency which the hardware enables for compatibility with older pdumps */ - RGXCommentLog(hPrivate, "Disable forced SLC coherency"); - RGXWriteReg64(hPrivate, RGX_CR_GARTEN_SLC, 0); - } - } - else -#endif - { - IMG_UINT32 ui32Reg; - IMG_UINT32 ui32RegVal; - IMG_UINT64 ui64RegVal; - - /* - * SLC Bypass control - */ - ui32Reg = RGX_CR_SLC_CTRL_BYPASS; - ui64RegVal = 0; - -#if defined(RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_EN) - if ((RGX_DEVICE_GET_FEATURE_VALUE(hPrivate, SLC_SIZE_IN_KILOBYTES) == 8) || - RGX_DEVICE_HAS_BRN(hPrivate, 61450)) - { - RGXCommentLog(hPrivate, "Bypass SLC for IPF_OBJ and IPF_CPF"); - ui64RegVal |= (IMG_UINT64) RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_EN | - (IMG_UINT64) RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_EN; - } -#endif - - if (ui64RegVal != 0) - { - RGXReadModifyWriteReg64(hPrivate, ui32Reg, ui64RegVal, ~ui64RegVal); - } - - /* - * SLC Misc control. - * - * Note: This is a 64bit register and we set only the lower 32bits leaving the top - * 32bits (RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS) unchanged from the HW default. - */ - ui32Reg = RGX_CR_SLC_CTRL_MISC; - ui32RegVal = RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1; - -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - ui32RegVal |= RGXReadReg32(hPrivate, ui32Reg) & RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN; -#endif - -#if defined(FIX_HW_BRN_60084_BIT_MASK) - if (RGX_DEVICE_HAS_BRN(hPrivate, 60084)) - { -#if !defined(SOC_FEATURE_STRICT_SAME_ADDRESS_WRITE_ORDERING) - ui32RegVal |= RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN; -#else - if (RGX_DEVICE_HAS_ERN(hPrivate, 61389)) - { - ui32RegVal |= RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN; - } -#endif - } -#endif - -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - /* Bypass burst combiner if SLC line size is smaller than 1024 bits */ - if (RGXGetDeviceCacheLineSize(hPrivate) < 1024) - { - ui32RegVal |= RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN; - } -#endif - - RGXWriteReg32(hPrivate, ui32Reg, ui32RegVal); - } -} - - -/*! -******************************************************************************* - - @Function RGXInitBIF - - @Description Initialise RGX BIF - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXInitBIF(const void *hPrivate) -{ - if (!RGX_DEVICE_HAS_FEATURE(hPrivate, MIPS)) - { - IMG_DEV_PHYADDR sPCAddr; - - /* - * Acquire the address of the Kernel Page Catalogue. - */ - RGXAcquireKernelMMUPC(hPrivate, &sPCAddr); - - /* - * Write the kernel catalogue base. - */ - RGXCommentLog(hPrivate, "RGX firmware MMU Page Catalogue"); - -#if defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (!RGX_DEVICE_HAS_FEATURE(hPrivate, SLC_VIVT)) - { - /* Write the cat-base address */ - RGXWriteKernelMMUPC64(hPrivate, - BIF_CAT_BASEx(MMU_CONTEXT_MAPPING_FWPRIV), - RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT, - RGX_CR_BIF_CAT_BASE0_ADDR_SHIFT, - ((sPCAddr.uiAddr - >> RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT) - << RGX_CR_BIF_CAT_BASE0_ADDR_SHIFT) - & ~RGX_CR_BIF_CAT_BASE0_ADDR_CLRMSK); - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR)) - { - /* Keep catbase registers in sync */ - RGXWriteKernelMMUPC64(hPrivate, - FWCORE_MEM_CAT_BASEx(MMU_CONTEXT_MAPPING_FWPRIV), - RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT, - RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT, - ((sPCAddr.uiAddr - >> RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT) - << RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT) - & ~RGX_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK); - } -#endif - - /* - * Trusted Firmware boot - */ -#if defined(SUPPORT_TRUSTED_DEVICE) - RGXCommentLog(hPrivate, "RGXInitBIF: Trusted Device enabled"); - RGXWriteReg32(hPrivate, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN); -#endif - } - else -#endif /* defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) */ - { -#if defined(RGX_CR_MMU_CBASE_MAPPING) // FIXME_OCEANIC - IMG_UINT32 uiPCAddr; - uiPCAddr = (((sPCAddr.uiAddr >> RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_ALIGNSHIFT) - << RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_SHIFT) - & ~RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_CLRMSK); - - /* Set the mapping context */ - RGXWriteReg32(hPrivate, RGX_CR_MMU_CBASE_MAPPING_CONTEXT, MMU_CONTEXT_MAPPING_FWPRIV); - (void)RGXReadReg32(hPrivate, RGX_CR_MMU_CBASE_MAPPING_CONTEXT); /* Fence write */ - - /* Write the cat-base address */ - RGXWriteKernelMMUPC32(hPrivate, - RGX_CR_MMU_CBASE_MAPPING, - RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_ALIGNSHIFT, - RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_SHIFT, - uiPCAddr); - -#if (MMU_CONTEXT_MAPPING_FWIF != MMU_CONTEXT_MAPPING_FWPRIV) - /* Set-up different MMU ID mapping to the same PC used above */ - RGXWriteReg32(hPrivate, RGX_CR_MMU_CBASE_MAPPING_CONTEXT, MMU_CONTEXT_MAPPING_FWIF); - (void)RGXReadReg32(hPrivate, RGX_CR_MMU_CBASE_MAPPING_CONTEXT); /* Fence write */ - - RGXWriteKernelMMUPC32(hPrivate, - RGX_CR_MMU_CBASE_MAPPING, - RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_ALIGNSHIFT, - RGX_CR_MMU_CBASE_MAPPING_BASE_ADDR_SHIFT, - uiPCAddr); -#endif -#endif - } - } - else - { - /* - * Trusted Firmware boot - */ -#if defined(SUPPORT_TRUSTED_DEVICE) - RGXCommentLog(hPrivate, "RGXInitBIF: Trusted Device enabled"); - RGXWriteReg32(hPrivate, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN); -#endif - } -} - - -/*! -******************************************************************************* - - @Function RGXAXIACELiteInit - - @Description Initialise AXI-ACE Lite interface - - @Input hPrivate : Implementation specific data - - @Return void - -******************************************************************************/ -static void RGXAXIACELiteInit(const void *hPrivate) -{ - IMG_UINT32 ui32RegAddr; - IMG_UINT64 ui64RegVal; - - ui32RegAddr = RGX_CR_AXI_ACE_LITE_CONFIGURATION; - - /* Setup AXI-ACE config. Set everything to outer cache */ - ui64RegVal = (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT) | - (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT) | - (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT); - -#if defined(FIX_HW_BRN_42321_BIT_MASK) - if (RGX_DEVICE_HAS_BRN(hPrivate, 42321)) - { - ui64RegVal |= (((IMG_UINT64) 1) << RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_SHIFT); - } -#endif - -#if defined(FIX_HW_BRN_68186_BIT_MASK) - if (RGX_DEVICE_HAS_BRN(hPrivate, 68186)) - { - /* default value for reg_enable_fence_out is zero. Force to 1 to allow core_clk < mem_clk */ - ui64RegVal |= (IMG_UINT64)1 << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ENABLE_FENCE_OUT_SHIFT; - } -#endif - -#if defined(SUPPORT_TRUSTED_DEVICE) && defined(RGX_FEATURE_SLC_VIVT_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, SLC_VIVT)) - { - RGXCommentLog(hPrivate, "OSID 0 and 1 are trusted"); - ui64RegVal |= IMG_UINT64_C(0xFC) - << RGX_CR_AXI_ACE_LITE_CONFIGURATION_OSID_SECURITY_SHIFT; - } -#endif - - RGXCommentLog(hPrivate, "Init AXI-ACE interface"); - RGXWriteReg64(hPrivate, ui32RegAddr, ui64RegVal); -} - -PVRSRV_ERROR RGXStart(const void *hPrivate) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_CHAR *pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_MIPS; -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - IMG_BOOL bDoFWSlaveBoot = IMG_FALSE; - IMG_BOOL bMetaFW = IMG_FALSE; -#endif - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR)) - { - pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_RISCV; - } - else -#endif -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (RGX_DEVICE_HAS_FEATURE_VALUE(hPrivate, META)) - { - pcRGXFW_PROCESSOR = RGXFW_PROCESSOR_META; - bMetaFW = IMG_TRUE; - bDoFWSlaveBoot = RGXDoFWSlaveBoot(hPrivate); - } -#endif - - if (RGX_DEVICE_HAS_FEATURE(hPrivate, SYS_BUS_SECURE_RESET)) - { - /* Disable the default sys_bus_secure protection to perform minimal setup */ - RGXCommentLog(hPrivate, "RGXStart: Disable sys_bus_secure"); - RGXWriteReg32(hPrivate, RGX_CR_SYS_BUS_SECURE, 0); - (void) RGXReadReg32(hPrivate, RGX_CR_SYS_BUS_SECURE); /* Fence write */ - } - -#if defined(SUPPORT_SHARED_SLC) - /* When the SLC is shared, the SLC reset is performed by the System layer when calling - * RGXInitSLC (before any device uses it), therefore mask out the SLC bit to avoid - * soft_resetting it here. - */ -#define RGX_CR_SOFT_RESET_ALL (RGX_CR_SOFT_RESET_MASKFULL ^ RGX_CR_SOFT_RESET_SLC_EN) - RGXCommentLog(hPrivate, "RGXStart: Shared SLC (don't reset SLC as part of RGX reset)"); -#else -#define RGX_CR_SOFT_RESET_ALL (RGX_CR_SOFT_RESET_MASKFULL) -#endif - -#if defined(RGX_S7_SOFT_RESET_DUSTS) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - /* Set RGX in soft-reset */ - RGXCommentLog(hPrivate, "RGXStart: soft reset assert step 1"); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS); - - /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */ - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET2); - - RGXCommentLog(hPrivate, "RGXStart: soft reset assert step 2"); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_JONES_ALL | RGX_S7_SOFT_RESET_DUSTS); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET2, RGX_S7_SOFT_RESET2); - - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET2); - - /* Take everything out of reset but the FW processor */ - RGXCommentLog(hPrivate, "RGXStart: soft reset de-assert step 1 excluding %s", pcRGXFW_PROCESSOR); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS | RGX_CR_SOFT_RESET_GARTEN_EN); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET2, 0x0); - - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET2); - - RGXCommentLog(hPrivate, "RGXStart: soft reset de-assert step 2 excluding %s", pcRGXFW_PROCESSOR); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN); - - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - } - else -#endif - { - /* Set RGX in soft-reset */ - RGXCommentLog(hPrivate, "RGXStart: soft reset everything"); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL); - - /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */ - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - - /* Take Rascal and Dust out of reset */ - RGXCommentLog(hPrivate, "RGXStart: Rascal and Dust out of reset"); - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL ^ RGX_CR_SOFT_RESET_RASCALDUSTS_EN); - - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - - /* Take everything out of reset but the FW processor */ - RGXCommentLog(hPrivate, "RGXStart: Take everything out of reset but %s", pcRGXFW_PROCESSOR); - -#if defined(RGX_FEATURE_XE_ARCHITECTURE) && (RGX_FEATURE_XE_ARCHITECTURE > 1) - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_CPU_EN); -#else - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN); -#endif - - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - } - - /* Enable clocks */ - RGXEnableClocks(hPrivate); - - /* - * Initialise SLC. - */ -#if !defined(SUPPORT_SHARED_SLC) - __RGXInitSLC(hPrivate); -#endif - - if (RGX_DEVICE_GET_FEATURE_VALUE(hPrivate, ECC_RAMS) > 0) - { - RGXCommentLog(hPrivate, "RGXStart: Enable safety events"); - RGXWriteReg32(hPrivate, RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE, - RGX_CR_SAFETY_EVENT_ENABLE__ROGUEXE__MASKFULL); - } - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (bMetaFW) - { - if (bDoFWSlaveBoot) - { - /* Configure META to Slave boot */ - RGXCommentLog(hPrivate, "RGXStart: META Slave boot"); - RGXWriteReg32(hPrivate, RGX_CR_META_BOOT, 0); - - } - else - { - /* Configure META to Master boot */ - RGXCommentLog(hPrivate, "RGXStart: META Master boot"); - RGXWriteReg32(hPrivate, RGX_CR_META_BOOT, RGX_CR_META_BOOT_MODE_EN); - } - } -#endif - - /* - * Initialise Firmware wrapper - */ -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR)) - { - RGXInitRiscvProcWrapper(hPrivate); - } - else -#endif -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (bMetaFW) - { - RGXInitMetaProcWrapper(hPrivate); - } - else -#endif - { - RGXInitMipsProcWrapper(hPrivate); - } - - if (RGX_DEVICE_HAS_FEATURE(hPrivate, AXI_ACELITE)) - { - /* We must init the AXI-ACE interface before 1st BIF transaction */ - RGXAXIACELiteInit(hPrivate); - } - - /* - * Initialise BIF. - */ - RGXInitBIF(hPrivate); - - RGXCommentLog(hPrivate, "RGXStart: Take %s out of reset", pcRGXFW_PROCESSOR); - - /* Need to wait for at least 16 cycles before taking the FW processor out of reset ... */ - RGXWaitCycles(hPrivate, 32, 3); - - RGXWriteReg64(hPrivate, RGX_CR_SOFT_RESET, 0x0); - (void) RGXReadReg64(hPrivate, RGX_CR_SOFT_RESET); - - /* ... and afterwards */ - RGXWaitCycles(hPrivate, 32, 3); - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (bMetaFW && bDoFWSlaveBoot) - { - eError = RGXFabricCoherencyTest(hPrivate); - if (eError != PVRSRV_OK) return eError; - - RGXCommentLog(hPrivate, "RGXStart: RGX Firmware Slave boot Start"); - eError = RGXStartFirmware(hPrivate); - if (eError != PVRSRV_OK) return eError; - } - else -#endif - { - RGXCommentLog(hPrivate, "RGXStart: RGX Firmware Master boot Start"); - -#if defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR)) - { - /* Bring Debug Module out of reset */ - RGXWriteReg32(hPrivate, RGX_CR_FWCORE_DMI_DMCONTROL, RGX_CR_FWCORE_DMI_DMCONTROL_DMACTIVE_EN); - - /* Boot the FW */ - RGXWriteReg32(hPrivate, RGX_CR_FWCORE_BOOT, 1); - RGXWaitCycles(hPrivate, 32, 3); - } -#endif - } - -#if defined(SUPPORT_TRUSTED_DEVICE) && !defined(SUPPORT_SECURITY_VALIDATION) - RGXCommentLog(hPrivate, "RGXStart: Enable sys_bus_secure"); - RGXWriteReg32(hPrivate, RGX_CR_SYS_BUS_SECURE, RGX_CR_SYS_BUS_SECURE_ENABLE_EN); - (void) RGXReadReg32(hPrivate, RGX_CR_SYS_BUS_SECURE); /* Fence write */ -#endif - - return eError; -} - -PVRSRV_ERROR RGXStop(const void *hPrivate) -{ -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) || defined(RGX_FEATURE_RISCV_FW_PROCESSOR_BIT_MASK) - IMG_BOOL bMipsFW = RGX_DEVICE_HAS_FEATURE(hPrivate, MIPS); - IMG_BOOL bRiscvFW = RGX_DEVICE_HAS_FEATURE(hPrivate, RISCV_FW_PROCESSOR); - IMG_BOOL bMetaFW = !bMipsFW && !bRiscvFW; -#endif - PVRSRV_ERROR eError = PVRSRV_OK; - RGX_LAYER_PARAMS *psParams; - PVRSRV_RGXDEV_INFO *psDevInfo; - PVR_ASSERT(hPrivate != NULL); - psParams = (RGX_LAYER_PARAMS*)hPrivate; - psDevInfo = psParams->psDevInfo; - - RGXDeviceAckIrq(hPrivate); - - /* Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper - * For LAYOUT_MARS = 1, SIDEKICK would have been powered down by FW - */ -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - if (!(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0)) - { -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - eError = RGXPollReg32(hPrivate, - RGX_CR_JONES_IDLE, - RGX_CR_JONES_IDLE_MASKFULL^(RGX_CR_JONES_IDLE_GARTEN_EN|RGX_CR_JONES_IDLE_SOCIF_EN|RGX_CR_JONES_IDLE_HOSTIF_EN), - RGX_CR_JONES_IDLE_MASKFULL^(RGX_CR_JONES_IDLE_GARTEN_EN|RGX_CR_JONES_IDLE_SOCIF_EN|RGX_CR_JONES_IDLE_HOSTIF_EN)); - } - else -#endif - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SIDEKICK_IDLE, - RGX_CR_SIDEKICK_IDLE_MASKFULL^(RGX_CR_SIDEKICK_IDLE_GARTEN_EN|RGX_CR_SIDEKICK_IDLE_SOCIF_EN|RGX_CR_SIDEKICK_IDLE_HOSTIF_EN), - RGX_CR_SIDEKICK_IDLE_MASKFULL^(RGX_CR_SIDEKICK_IDLE_GARTEN_EN|RGX_CR_SIDEKICK_IDLE_SOCIF_EN|RGX_CR_SIDEKICK_IDLE_HOSTIF_EN)); - } - - if (eError != PVRSRV_OK) return eError; - } -#endif - - if (!(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0)) - { -#if !defined(SUPPORT_SHARED_SLC) - /* - * Wait for SLC to signal IDLE - * For LAYOUT_MARS = 1, SLC would have been powered down by FW - */ -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SLC3_IDLE, - RGX_CR_SLC3_IDLE_MASKFULL, - RGX_CR_SLC3_IDLE_MASKFULL); - } - else -#endif - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SLC_IDLE, - RGX_CR_SLC_IDLE_MASKFULL, - RGX_CR_SLC_IDLE_MASKFULL); - } -#endif /* SUPPORT_SHARED_SLC */ - if (eError != PVRSRV_OK) return eError; - } - - /* Unset MTS DM association with threads */ - RGXWriteReg32(hPrivate, - RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC, - RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK - & RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL); - RGXWriteReg32(hPrivate, - RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC, - RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK - & RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL); -#if defined(RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC) // FIXME_OCEANIC - RGXWriteReg32(hPrivate, - RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC, - RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK - & RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL); - RGXWriteReg32(hPrivate, - RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC, - RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK - & RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL); -#endif - -#if defined(PDUMP) && defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (bMetaFW) - { - /* Disabling threads is only required for pdumps to stop the fw gracefully */ - - /* Disable thread 0 */ - eError = RGXWriteMetaRegThroughSP(hPrivate, - META_CR_T0ENABLE_OFFSET, - ~META_CR_TXENABLE_ENABLE_BIT); - if (eError != PVRSRV_OK) return eError; - - /* Disable thread 1 */ - eError = RGXWriteMetaRegThroughSP(hPrivate, - META_CR_T1ENABLE_OFFSET, - ~META_CR_TXENABLE_ENABLE_BIT); - if (eError != PVRSRV_OK) return eError; - - /* Clear down any irq raised by META (done after disabling the FW - * threads to avoid a race condition). - * This is only really needed for PDumps but we do it anyway driver-live. - */ - RGXWriteReg32(hPrivate, RGX_CR_META_SP_MSLVIRQSTATUS, 0x0); - (void)RGXReadReg32(hPrivate, RGX_CR_META_SP_MSLVIRQSTATUS); /* Fence write */ - - /* Wait for the Slave Port to finish all the transactions */ - eError = RGXPollReg32(hPrivate, - RGX_CR_META_SP_MSLVCTRL1, - RGX_CR_META_SP_MSLVCTRL1_READY_EN | RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, - RGX_CR_META_SP_MSLVCTRL1_READY_EN | RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN); - if (eError != PVRSRV_OK) return eError; - } -#endif - -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - /* Extra Idle checks */ - eError = RGXPollReg32(hPrivate, - RGX_CR_BIF_STATUS_MMU, - 0, - RGX_CR_BIF_STATUS_MMU_MASKFULL); - if (eError != PVRSRV_OK) return eError; - - eError = RGXPollReg32(hPrivate, - RGX_CR_BIFPM_STATUS_MMU, - 0, - RGX_CR_BIFPM_STATUS_MMU_MASKFULL); - if (eError != PVRSRV_OK) return eError; -#endif - -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (!RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE) && - !RGX_DEVICE_HAS_FEATURE(hPrivate, XT_TOP_INFRASTRUCTURE)) -#endif - { - eError = RGXPollReg32(hPrivate, - RGX_CR_BIF_READS_EXT_STATUS, - 0, - RGX_CR_BIF_READS_EXT_STATUS_MASKFULL); - if (eError != PVRSRV_OK) return eError; - } - -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - eError = RGXPollReg32(hPrivate, - RGX_CR_BIFPM_READS_EXT_STATUS, - 0, - RGX_CR_BIFPM_READS_EXT_STATUS_MASKFULL); - if (eError != PVRSRV_OK) return eError; -#endif - - { - IMG_UINT64 ui64SLCMask = RGX_CR_SLC_STATUS1_MASKFULL; - eError = RGXPollReg64(hPrivate, - RGX_CR_SLC_STATUS1, - 0, - ui64SLCMask); - if (eError != PVRSRV_OK) return eError; - } - -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - if (4 == RGXGetDeviceSLCBanks(hPrivate)) - { - eError = RGXPollReg64(hPrivate, - RGX_CR_SLC_STATUS2, - 0, - RGX_CR_SLC_STATUS2_MASKFULL); - if (eError != PVRSRV_OK) return eError; - } -#endif - - if (!(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0)) - { -#if !defined(SUPPORT_SHARED_SLC) - /* - * Wait for SLC to signal IDLE - * For LAYOUT_MARS = 1, SLC would have been powered down by FW - */ -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SLC3_IDLE, - RGX_CR_SLC3_IDLE_MASKFULL, - RGX_CR_SLC3_IDLE_MASKFULL); - } - else -#endif - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SLC_IDLE, - RGX_CR_SLC_IDLE_MASKFULL, - RGX_CR_SLC_IDLE_MASKFULL); - } -#endif /* SUPPORT_SHARED_SLC */ - if (eError != PVRSRV_OK) return eError; - } - - /* Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper - * For LAYOUT_MARS = 1, SIDEKICK would have been powered down by FW - */ -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - if (!(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0)) - { -#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK) - if (RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { -#if defined(RGX_FEATURE_FASTRENDER_DM_BIT_MASK) - if (!RGX_DEVICE_HAS_FEATURE(hPrivate, FASTRENDER_DM)) - { - eError = RGXPollReg32(hPrivate, - RGX_CR_JONES_IDLE, - RGX_CR_JONES_IDLE_MASKFULL^(RGX_CR_JONES_IDLE_GARTEN_EN|RGX_CR_JONES_IDLE_SOCIF_EN|RGX_CR_JONES_IDLE_HOSTIF_EN), - RGX_CR_JONES_IDLE_MASKFULL^(RGX_CR_JONES_IDLE_GARTEN_EN|RGX_CR_JONES_IDLE_SOCIF_EN|RGX_CR_JONES_IDLE_HOSTIF_EN)); - } -#endif - } - else -#endif - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SIDEKICK_IDLE, - RGX_CR_SIDEKICK_IDLE_MASKFULL^(RGX_CR_SIDEKICK_IDLE_GARTEN_EN|RGX_CR_SIDEKICK_IDLE_SOCIF_EN|RGX_CR_SIDEKICK_IDLE_HOSTIF_EN), - RGX_CR_SIDEKICK_IDLE_MASKFULL^(RGX_CR_SIDEKICK_IDLE_GARTEN_EN|RGX_CR_SIDEKICK_IDLE_SOCIF_EN|RGX_CR_SIDEKICK_IDLE_HOSTIF_EN)); - } - - if (eError != PVRSRV_OK) return eError; - } -#endif - -#if defined(RGX_FEATURE_META_MAX_VALUE_IDX) - if (bMetaFW) - { - IMG_UINT32 ui32RegValue; - - eError = RGXReadMetaRegThroughSP(hPrivate, - META_CR_TxVECINT_BHALT, - &ui32RegValue); - if (eError != PVRSRV_OK) return eError; - - if ((ui32RegValue & 0xFFFFFFFFU) == 0x0) - { - /* Wait for Sidekick/Jones to signal IDLE including - * the Garten Wrapper if there is no debugger attached - * (TxVECINT_BHALT = 0x0) */ - if (!RGX_DEVICE_HAS_FEATURE(hPrivate, S7_TOP_INFRASTRUCTURE)) - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SIDEKICK_IDLE, - RGX_CR_SIDEKICK_IDLE_GARTEN_EN, - RGX_CR_SIDEKICK_IDLE_GARTEN_EN); - if (eError != PVRSRV_OK) return eError; - } - else - { - eError = RGXPollReg32(hPrivate, - RGX_CR_JONES_IDLE, - RGX_CR_JONES_IDLE_GARTEN_EN, - RGX_CR_JONES_IDLE_GARTEN_EN); - if (eError != PVRSRV_OK) return eError; - } - } - } - else -#endif - { - if (PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevInfo->psDeviceNode, LAYOUT_MARS) > 0) - { - /* As FW core has been moved from SIDEKICK to the new MARS domain, checking - * idle bits for CPU & System Arbiter excluding SOCIF which will never be Idle - * if Host polling on this register - */ - eError = RGXPollReg32(hPrivate, - RGX_CR_MARS_IDLE, - RGX_CR_MARS_IDLE_CPU_EN | RGX_CR_MARS_IDLE_MH_SYSARB0_EN, - RGX_CR_MARS_IDLE_CPU_EN | RGX_CR_MARS_IDLE_MH_SYSARB0_EN); - if (eError != PVRSRV_OK) return eError; - } -#if !defined(RGX_FEATURE_XE_ARCHITECTURE) || (RGX_FEATURE_XE_ARCHITECTURE == 1) - else - { - eError = RGXPollReg32(hPrivate, - RGX_CR_SIDEKICK_IDLE, - RGX_CR_SIDEKICK_IDLE_GARTEN_EN, - RGX_CR_SIDEKICK_IDLE_GARTEN_EN); - if (eError != PVRSRV_OK) return eError; - } -#endif - } - - return eError; -} - - -/* - * RGXInitSLC - */ -#if defined(SUPPORT_SHARED_SLC) -PVRSRV_ERROR RGXInitSLC(IMG_HANDLE hDevHandle) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo; - void *pvPowerParams; - - if (psDeviceNode == NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - psDevInfo = psDeviceNode->pvDevice; - pvPowerParams = &psDevInfo->sLayerParams; - - /* reset the SLC */ - RGXCommentLog(pvPowerParams, "RGXInitSLC: soft reset SLC"); - RGXWriteReg64(pvPowerParams, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_SLC_EN); - - /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */ - (void) RGXReadReg64(pvPowerParams, RGX_CR_SOFT_RESET); - - /* Take everything out of reset */ - RGXWriteReg64(pvPowerParams, RGX_CR_SOFT_RESET, 0x0); - - __RGXInitSLC(pvPowerParams); - - return PVRSRV_OK; -} -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.h b/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.h deleted file mode 100644 index 178afe2849a0c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxstartstop.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX start/stop header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX start/stop functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXSTARTSTOP_H) -#define RGXSTARTSTOP_H - -/* The routines declared here are built on top of an abstraction layer to - * hide DDK/OS-specific details in case they are used outside of the DDK - * (e.g. when DRM security is enabled). - * Any new dependency should be added to rgxlayer.h. - * Any new code should be built on top of the existing abstraction layer, - * which should be extended when necessary. - */ -#include "rgxlayer.h" - -/*! -******************************************************************************* - - @Function RGXStart - - @Description Perform GPU reset and initialisation - - @Input hPrivate : Implementation specific data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXStart(const void *hPrivate); - -/*! -******************************************************************************* - - @Function RGXStop - - @Description Stop Rogue in preparation for power down - - @Input hPrivate : Implementation specific data - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXStop(const void *hPrivate); - -#endif /* RGXSTARTSTOP_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.c b/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.c deleted file mode 100644 index cec0597d0301e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.c +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************/ /*! -@File rgxsyncutils.c -@Title RGX Sync Utilities -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Sync helper functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxsyncutils.h" - -#include "sync_server.h" -#include "sync_internal.h" -#include "sync.h" -#include "allocmem.h" - -#if defined(SUPPORT_BUFFER_SYNC) -#include "pvr_buffer_sync.h" -#endif - -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" - -//#define TA3D_CHECKPOINT_DEBUG - -#if defined(TA3D_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -static -void _DebugSyncValues(IMG_UINT32 *pui32UpdateValues, - IMG_UINT32 ui32Count) -{ - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32UpdateValues; - - for (iii = 0; iii < ui32Count; iii++) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: pui32IntAllocatedUpdateValues[%d](<%p>) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } -} -#else -#define CHKPT_DBG(X) -#endif - - -PVRSRV_ERROR RGXSyncAppendTimelineUpdate(IMG_UINT32 ui32FenceTimelineUpdateValue, - SYNC_ADDR_LIST *psSyncList, - SYNC_ADDR_LIST *psPRSyncList, - PVRSRV_CLIENT_SYNC_PRIM *psFenceTimelineUpdateSync, - RGX_SYNC_DATA *psSyncData, - IMG_BOOL bKick3D) -{ - IMG_UINT32 *pui32TimelineUpdateWOff = NULL; - IMG_UINT32 *pui32IntAllocatedUpdateValues = NULL; - - IMG_UINT32 ui32ClientUpdateValueCount = psSyncData->ui32ClientUpdateValueCount; - - /* Space for original client updates, and the one new update */ - size_t uiUpdateSize = sizeof(*pui32IntAllocatedUpdateValues) * (ui32ClientUpdateValueCount + 1); - - if (!bKick3D) - { - /* Additional space for one PR update, only the newest one */ - uiUpdateSize += sizeof(*pui32IntAllocatedUpdateValues) * 1; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: About to allocate memory to hold updates in pui32IntAllocatedUpdateValues(<%p>)", - __func__, - (void*)pui32IntAllocatedUpdateValues)); - - /* Allocate memory to hold the list of update values (including our timeline update) */ - pui32IntAllocatedUpdateValues = OSAllocMem(uiUpdateSize); - if (!pui32IntAllocatedUpdateValues) - { - /* Failed to allocate memory */ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSCachedMemSet(pui32IntAllocatedUpdateValues, 0xcc, uiUpdateSize); - pui32TimelineUpdateWOff = pui32IntAllocatedUpdateValues; - - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Copying %d %s update values into pui32IntAllocatedUpdateValues(<%p>)", - __func__, - ui32ClientUpdateValueCount, - bKick3D ? "TA/3D" : "TA/PR", - (void*)pui32IntAllocatedUpdateValues)); - /* Copy the update values into the new memory, then append our timeline update value */ - OSCachedMemCopy(pui32TimelineUpdateWOff, psSyncData->paui32ClientUpdateValue, ui32ClientUpdateValueCount * sizeof(*psSyncData->paui32ClientUpdateValue)); - -#if defined(TA3D_CHECKPOINT_DEBUG) - _DebugSyncValues(pui32TimelineUpdateWOff, ui32ClientUpdateValueCount); -#endif - - pui32TimelineUpdateWOff += ui32ClientUpdateValueCount; - } - - /* Now set the additional update value and append the timeline sync prim addr to either the - * render context 3D (or TA) update list - */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Appending the additional update value (0x%x) to psRenderContext->sSyncAddrList%sUpdate...", - __func__, - ui32FenceTimelineUpdateValue, - bKick3D ? "TA/3D" : "TA/PR")); - - /* Append the TA/3D update */ - { - *pui32TimelineUpdateWOff++ = ui32FenceTimelineUpdateValue; - psSyncData->ui32ClientUpdateValueCount++; - psSyncData->ui32ClientUpdateCount++; - SyncAddrListAppendSyncPrim(psSyncList, psFenceTimelineUpdateSync); - - if (!psSyncData->pauiClientUpdateUFOAddress) - { - psSyncData->pauiClientUpdateUFOAddress = psSyncList->pasFWAddrs; - } - /* Update paui32ClientUpdateValue to point to our new list of update values */ - psSyncData->paui32ClientUpdateValue = pui32IntAllocatedUpdateValues; - -#if defined(TA3D_CHECKPOINT_DEBUG) - _DebugSyncValues(pui32IntAllocatedUpdateValues, psSyncData->ui32ClientUpdateValueCount); -#endif - } - - if (!bKick3D) - { - /* Use the sSyncAddrList3DUpdate for PR (as it doesn't have one of its own) */ - *pui32TimelineUpdateWOff++ = ui32FenceTimelineUpdateValue; - psSyncData->ui32ClientPRUpdateValueCount = 1; - psSyncData->ui32ClientPRUpdateCount = 1; - SyncAddrListAppendSyncPrim(psPRSyncList, psFenceTimelineUpdateSync); - - if (!psSyncData->pauiClientPRUpdateUFOAddress) - { - psSyncData->pauiClientPRUpdateUFOAddress = psPRSyncList->pasFWAddrs; - } - /* Update paui32ClientPRUpdateValue to point to our new list of update values */ - psSyncData->paui32ClientPRUpdateValue = &pui32IntAllocatedUpdateValues[psSyncData->ui32ClientUpdateValueCount]; - -#if defined(TA3D_CHECKPOINT_DEBUG) - _DebugSyncValues(psSyncData->paui32ClientPRUpdateValue, psSyncData->ui32ClientPRUpdateValueCount); -#endif - } - - /* Do not free the old psSyncData->ui32ClientUpdateValueCount, - * as it was constant data passed through the bridge down to PVRSRVRGXKickTA3DKM() */ - - return PVRSRV_OK; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.h b/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.h deleted file mode 100644 index 2133da85e78ac..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxsyncutils.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************/ /*! -@File rgxsyncutils.h -@Title RGX Sync Utilities -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Sync helper functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXSYNCUTILS_H -#define RGXSYNCUTILS_H - -#include "rgxdevice.h" -#include "sync_server.h" -#include "rgxdebug.h" -#include "rgx_fwif_km.h" - -typedef struct _RGX_SYNC_DATA_ -{ - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress; - IMG_UINT32 *paui32ClientUpdateValue; - IMG_UINT32 ui32ClientUpdateValueCount; - IMG_UINT32 ui32ClientUpdateCount; - - PRGXFWIF_UFO_ADDR *pauiClientPRUpdateUFOAddress; - IMG_UINT32 *paui32ClientPRUpdateValue; - IMG_UINT32 ui32ClientPRUpdateValueCount; - IMG_UINT32 ui32ClientPRUpdateCount; -} RGX_SYNC_DATA; - -PVRSRV_ERROR RGXSyncAppendTimelineUpdate(IMG_UINT32 ui32FenceTimelineUpdateValue, - SYNC_ADDR_LIST *psSyncList, - SYNC_ADDR_LIST *psPRSyncList, - PVRSRV_CLIENT_SYNC_PRIM *psFenceTimelineUpdateSync, - RGX_SYNC_DATA *psSyncData, - IMG_BOOL bKick3D); - -#endif /* RGXSYNCUTILS_H */ - -/****************************************************************************** - End of file (rgxsyncutils.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxta3d.c b/drivers/gpu/drm/img-rogue/1.17/rgxta3d.c deleted file mode 100644 index ab0709e0fdbfb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxta3d.c +++ /dev/null @@ -1,5549 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX TA/3D routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX TA/3D routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -/* for the offsetof macro */ -#if defined(__linux__) -#include -#else -#include -#endif - -#include "pdump_km.h" -#include "pvr_debug.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgxta3d.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "ri_server.h" -#include "osfunc.h" -#include "pvrsrv.h" -#include "rgx_memallocflags.h" -#include "rgxccb.h" -#include "rgxhwperf.h" -#include "ospvr_gputrace.h" -#include "rgxsyncutils.h" -#include "htbuffer.h" - -#include "rgxdefs_km.h" -#include "rgx_fwif_km.h" -#include "physmem.h" -#include "sync_server.h" -#include "sync_internal.h" -#include "sync.h" -#include "process_stats.h" - -#include "rgxtimerquery.h" - -#if defined(SUPPORT_BUFFER_SYNC) -#include "pvr_buffer_sync.h" -#endif - -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" - -#if defined(SUPPORT_PDVFS) -#include "rgxpdvfs.h" -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "rgxworkest.h" - -#define HASH_CLEAN_LIMIT 6 -#endif - -/* Enable this to dump the compiled list of UFOs prior to kick call */ -#define ENABLE_TA3D_UFO_DUMP 0 - -//#define TA3D_CHECKPOINT_DEBUG - -#if defined(TA3D_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -static INLINE -void _DebugSyncValues(const IMG_CHAR *pszFunction, - const IMG_UINT32 *pui32UpdateValues, - const IMG_UINT32 ui32Count) -{ - IMG_UINT32 i; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32UpdateValues; - - for (i = 0; i < ui32Count; i++) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: pui32IntAllocatedUpdateValues[%d](<%p>) = 0x%x", pszFunction, i, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } -} - -static INLINE -void _DebugSyncCheckpoints(const IMG_CHAR *pszFunction, - const IMG_CHAR *pszDMName, - const PSYNC_CHECKPOINT *apsSyncCheckpoints, - const IMG_UINT32 ui32Count) -{ - IMG_UINT32 i; - - for (i = 0; i < ui32Count; i++) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: apsFence%sSyncCheckpoints[%d]=<%p>", pszFunction, pszDMName, i, *(apsSyncCheckpoints + i))); - } -} - -#else -#define CHKPT_DBG(X) -#endif - -/* define the number of commands required to be set up by the CCB helper */ -/* 1 command for the TA */ -#define CCB_CMD_HELPER_NUM_TA_COMMANDS 1 -/* Up to 3 commands for the 3D (partial render fence, partial render, and render) */ -#define CCB_CMD_HELPER_NUM_3D_COMMANDS 3 - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#define WORKEST_CYCLES_PREDICTION_GET(x) ((x).ui32CyclesPrediction) -#else -#define WORKEST_CYCLES_PREDICTION_GET(x) (NO_CYCEST) -#endif - -typedef struct { - DEVMEM_MEMDESC *psContextStateMemDesc; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - IMG_UINT32 ui32Priority; -} RGX_SERVER_RC_TA_DATA; - -typedef struct { - DEVMEM_MEMDESC *psContextStateMemDesc; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - IMG_UINT32 ui32Priority; -} RGX_SERVER_RC_3D_DATA; - -struct _RGX_SERVER_RENDER_CONTEXT_ { - /* this lock protects usage of the render context. - * it ensures only one kick is being prepared and/or submitted on - * this render context at any time - */ - POS_LOCK hLock; - RGX_CCB_CMD_HELPER_DATA asTACmdHelperData[CCB_CMD_HELPER_NUM_TA_COMMANDS]; - RGX_CCB_CMD_HELPER_DATA as3DCmdHelperData[CCB_CMD_HELPER_NUM_3D_COMMANDS]; - PVRSRV_DEVICE_NODE *psDeviceNode; - DEVMEM_MEMDESC *psFWRenderContextMemDesc; - DEVMEM_MEMDESC *psFWFrameworkMemDesc; - RGX_SERVER_RC_TA_DATA sTAData; - RGX_SERVER_RC_3D_DATA s3DData; - IMG_UINT32 ui32CleanupStatus; -#define RC_CLEANUP_TA_COMPLETE (1 << 0) -#define RC_CLEANUP_3D_COMPLETE (1 << 1) - DLLIST_NODE sListNode; - SYNC_ADDR_LIST sSyncAddrListTAFence; - SYNC_ADDR_LIST sSyncAddrListTAUpdate; - SYNC_ADDR_LIST sSyncAddrList3DFence; - SYNC_ADDR_LIST sSyncAddrList3DUpdate; - ATOMIC_T hIntJobRef; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WORKEST_HOST_DATA sWorkEstData; -#endif -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif -}; - - -/* - Static functions used by render context code -*/ - -static -PVRSRV_ERROR _DestroyTAContext(RGX_SERVER_RC_TA_DATA *psTAData, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psDeviceNode, - psTAData->psServerCommonContext, - RGXFWIF_DM_GEOM, - PDUMP_FLAGS_CONTINUOUS); - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free its resources */ -#if defined(DEBUG) - /* Log the number of TA context stores which occurred */ - { - RGXFWIF_TACTX_STATE *psFWTAState; - - eError = DevmemAcquireCpuVirtAddr(psTAData->psContextStateMemDesc, - (void**)&psFWTAState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware render context state (%s)", - __func__, PVRSRVGetErrorString(eError))); - } - else - { - /* Release the CPU virt addr */ - DevmemReleaseCpuVirtAddr(psTAData->psContextStateMemDesc); - } - } -#endif - FWCommonContextFree(psTAData->psServerCommonContext); - DevmemFwUnmapAndFree(psDeviceNode->pvDevice, psTAData->psContextStateMemDesc); - psTAData->psServerCommonContext = NULL; - return PVRSRV_OK; -} - -static -PVRSRV_ERROR _Destroy3DContext(RGX_SERVER_RC_3D_DATA *ps3DData, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psDeviceNode, - ps3DData->psServerCommonContext, - RGXFWIF_DM_3D, - PDUMP_FLAGS_CONTINUOUS); - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free its resources */ -#if defined(DEBUG) - /* Log the number of 3D context stores which occurred */ - { - RGXFWIF_3DCTX_STATE *psFW3DState; - - eError = DevmemAcquireCpuVirtAddr(ps3DData->psContextStateMemDesc, - (void**)&psFW3DState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware render context state (%s)", - __func__, PVRSRVGetErrorString(eError))); - } - else - { - /* Release the CPU virt addr */ - DevmemReleaseCpuVirtAddr(ps3DData->psContextStateMemDesc); - } - } -#endif - - FWCommonContextFree(ps3DData->psServerCommonContext); - DevmemFwUnmapAndFree(psDeviceNode->pvDevice, ps3DData->psContextStateMemDesc); - ps3DData->psServerCommonContext = NULL; - return PVRSRV_OK; -} - -static void _RGXDumpPMRPageList(DLLIST_NODE *psNode) -{ - RGX_PMR_NODE *psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock); - PVRSRV_ERROR eError; - - eError = PMRDumpPageList(psPMRNode->psPMR, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Error (%s) printing pmr %p", - PVRSRVGetErrorString(eError), - psPMRNode->psPMR)); - } -} - -IMG_BOOL RGXDumpFreeListPageList(RGX_FREELIST *psFreeList) -{ - DLLIST_NODE *psNode, *psNext; - - PVR_LOG(("Freelist FWAddr 0x%08x, ID = %d, CheckSum 0x%016" IMG_UINT64_FMTSPECx, - psFreeList->sFreeListFWDevVAddr.ui32Addr, - psFreeList->ui32FreelistID, - psFreeList->ui64FreelistChecksum)); - - /* Dump Init FreeList page list */ - PVR_LOG((" Initial Memory block")); - dllist_foreach_node(&psFreeList->sMemoryBlockInitHead, psNode, psNext) - { - _RGXDumpPMRPageList(psNode); - } - - /* Dump Grow FreeList page list */ - PVR_LOG((" Grow Memory blocks")); - dllist_foreach_node(&psFreeList->sMemoryBlockHead, psNode, psNext) - { - _RGXDumpPMRPageList(psNode); - } - - return IMG_TRUE; -} - -static void _CheckFreelist(RGX_FREELIST *psFreeList, - IMG_UINT32 ui32NumOfPagesToCheck, - IMG_UINT64 ui64ExpectedCheckSum, - IMG_UINT64 *pui64CalculatedCheckSum) -{ -#if defined(NO_HARDWARE) - /* No checksum needed as we have all information in the pdumps */ - PVR_UNREFERENCED_PARAMETER(psFreeList); - PVR_UNREFERENCED_PARAMETER(ui32NumOfPagesToCheck); - PVR_UNREFERENCED_PARAMETER(ui64ExpectedCheckSum); - *pui64CalculatedCheckSum = 0; -#else - PVRSRV_ERROR eError; - size_t uiNumBytes; - IMG_UINT8* pui8Buffer; - IMG_UINT32* pui32Buffer; - IMG_UINT32 ui32CheckSumAdd = 0; - IMG_UINT32 ui32CheckSumXor = 0; - IMG_UINT32 ui32Entry; - IMG_UINT32 ui32Entry2; - IMG_BOOL bFreelistBad = IMG_FALSE; - - *pui64CalculatedCheckSum = 0; - - PVR_ASSERT(ui32NumOfPagesToCheck <= (psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages)); - - /* Allocate Buffer of the size of the freelist */ - pui8Buffer = OSAllocMem(ui32NumOfPagesToCheck * sizeof(IMG_UINT32)); - if (pui8Buffer == NULL) - { - PVR_LOG(("%s: Failed to allocate buffer to check freelist %p!", - __func__, psFreeList)); - PVR_ASSERT(0); - return; - } - - /* Copy freelist content into Buffer */ - eError = PMR_ReadBytes(psFreeList->psFreeListPMR, - psFreeList->uiFreeListPMROffset + - (((psFreeList->ui32MaxFLPages - - psFreeList->ui32CurrentFLPages - - psFreeList->ui32ReadyFLPages) * sizeof(IMG_UINT32)) & - ~((IMG_UINT64)RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE-1)), - pui8Buffer, - ui32NumOfPagesToCheck * sizeof(IMG_UINT32), - &uiNumBytes); - if (eError != PVRSRV_OK) - { - OSFreeMem(pui8Buffer); - PVR_LOG(("%s: Failed to get freelist data for freelist %p!", - __func__, psFreeList)); - PVR_ASSERT(0); - return; - } - - PVR_ASSERT(uiNumBytes == ui32NumOfPagesToCheck * sizeof(IMG_UINT32)); - - /* Generate checksum (skipping the first page if not allocated) */ - pui32Buffer = (IMG_UINT32 *)pui8Buffer; - ui32Entry = ((psFreeList->ui32GrowFLPages == 0 && psFreeList->ui32CurrentFLPages > 1) ? 1 : 0); - for (/*ui32Entry*/ ; ui32Entry < ui32NumOfPagesToCheck; ui32Entry++) - { - ui32CheckSumAdd += pui32Buffer[ui32Entry]; - ui32CheckSumXor ^= pui32Buffer[ui32Entry]; - - /* Check for double entries */ - for (ui32Entry2 = ui32Entry+1; ui32Entry2 < ui32NumOfPagesToCheck; ui32Entry2++) - { - if (pui32Buffer[ui32Entry] == pui32Buffer[ui32Entry2]) - { - PVR_LOG(("%s: Freelist consistency failure: FW addr: 0x%08X, Double entry found 0x%08x on idx: %d and %d of %d", - __func__, - psFreeList->sFreeListFWDevVAddr.ui32Addr, - pui32Buffer[ui32Entry2], - ui32Entry, - ui32Entry2, - psFreeList->ui32CurrentFLPages)); - bFreelistBad = IMG_TRUE; - break; - } - } - } - - OSFreeMem(pui8Buffer); - - /* Check the calculated checksum against the expected checksum... */ - *pui64CalculatedCheckSum = ((IMG_UINT64)ui32CheckSumXor << 32) | ui32CheckSumAdd; - - if (ui64ExpectedCheckSum != 0 && ui64ExpectedCheckSum != *pui64CalculatedCheckSum) - { - PVR_LOG(("%s: Checksum mismatch for freelist %p! Expected 0x%016" IMG_UINT64_FMTSPECx " calculated 0x%016" IMG_UINT64_FMTSPECx, - __func__, psFreeList, - ui64ExpectedCheckSum, *pui64CalculatedCheckSum)); - bFreelistBad = IMG_TRUE; - } - - if (bFreelistBad) - { - PVR_LOG(("%s: Sleeping for ever!", __func__)); - PVR_ASSERT(!bFreelistBad); - } -#endif -} - - -/* - * Function to work out the number of freelist pages to reserve for growing - * within the FW without having to wait for the host to progress a grow - * request. - * - * The number of pages must be a multiple of 4 to align the PM addresses - * for the initial freelist allocation and also be less than the grow size. - * - * If the threshold or grow size means less than 4 pages, then the feature - * is not used. - */ -static IMG_UINT32 _CalculateFreelistReadyPages(RGX_FREELIST *psFreeList, - IMG_UINT32 ui32FLPages) -{ - IMG_UINT32 ui32ReadyFLPages = ((ui32FLPages * psFreeList->ui32GrowThreshold) / 100) & - ~((RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE/sizeof(IMG_UINT32))-1); - - if (ui32ReadyFLPages > psFreeList->ui32GrowFLPages) - { - ui32ReadyFLPages = psFreeList->ui32GrowFLPages; - } - - return ui32ReadyFLPages; -} - - -PVRSRV_ERROR RGXGrowFreeList(RGX_FREELIST *psFreeList, - IMG_UINT32 ui32NumPages, - PDLLIST_NODE pListHeader) -{ - RGX_PMR_NODE *psPMRNode; - IMG_DEVMEM_SIZE_T uiSize; - IMG_UINT32 ui32MappingTable = 0; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiLength; - IMG_DEVMEM_SIZE_T uistartPage; - PVRSRV_ERROR eError; - static const IMG_CHAR szAllocName[DEVMEM_ANNOTATION_MAX_LEN] = "Free List"; - - /* Are we allowed to grow ? */ - if (psFreeList->ui32MaxFLPages - (psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages) < ui32NumPages) - { - PVR_DPF((PVR_DBG_WARNING, - "Freelist [0x%p]: grow by %u pages denied. " - "Max PB size reached (current pages %u+%u/%u)", - psFreeList, - ui32NumPages, - psFreeList->ui32CurrentFLPages, - psFreeList->ui32ReadyFLPages, - psFreeList->ui32MaxFLPages)); - return PVRSRV_ERROR_PBSIZE_ALREADY_MAX; - } - - /* Allocate kernel memory block structure */ - psPMRNode = OSAllocMem(sizeof(*psPMRNode)); - if (psPMRNode == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to allocate host data structure", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorAllocHost; - } - - /* - * Lock protects simultaneous manipulation of: - * - the memory block list - * - the freelist's ui32CurrentFLPages - */ - OSLockAcquire(psFreeList->psDevInfo->hLockFreeList); - - - /* - * The PM never takes the last page in a freelist, so if this block - * of pages is the first one and there is no ability to grow, then - * we can skip allocating one 4K page for the lowest entry. - */ - if (OSGetPageSize() > RGX_BIF_PM_PHYSICAL_PAGE_SIZE) - { - /* - * Allocation size will be rounded up to the OS page size, - * any attempt to change it a bit now will be invalidated later. - */ - psPMRNode->bFirstPageMissing = IMG_FALSE; - } - else - { - psPMRNode->bFirstPageMissing = (psFreeList->ui32GrowFLPages == 0 && ui32NumPages > 1); - } - - psPMRNode->ui32NumPages = ui32NumPages; - psPMRNode->psFreeList = psFreeList; - - /* Allocate Memory Block */ - PDUMPCOMMENT(psFreeList->psDevInfo->psDeviceNode, "Allocate PB Block (Pages %08X)", ui32NumPages); - uiSize = (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE; - if (psPMRNode->bFirstPageMissing) - { - uiSize -= RGX_BIF_PM_PHYSICAL_PAGE_SIZE; - } - eError = PhysmemNewRamBackedPMR(psFreeList->psConnection, - psFreeList->psDevInfo->psDeviceNode, - uiSize, - uiSize, - 1, - 1, - &ui32MappingTable, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT, - PVRSRV_MEMALLOCFLAG_GPU_READABLE, - sizeof(szAllocName), - szAllocName, - psFreeList->ownerPid, - &psPMRNode->psPMR, - PDUMP_NONE, - NULL); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate PB block of size: 0x%016" IMG_UINT64_FMTSPECX, - __func__, - (IMG_UINT64)uiSize)); - goto ErrorBlockAlloc; - } - - /* Zeroing physical pages pointed by the PMR */ - if (psFreeList->psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_ZERO_FREELIST) - { - eError = PMRZeroingPMR(psPMRNode->psPMR, RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to zero PMR %p of freelist %p (%s)", - __func__, - psPMRNode->psPMR, - psFreeList, - PVRSRVGetErrorString(eError))); - PVR_ASSERT(0); - } - } - - uiLength = psPMRNode->ui32NumPages * sizeof(IMG_UINT32); - uistartPage = (psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages - psPMRNode->ui32NumPages); - uiOffset = psFreeList->uiFreeListPMROffset + ((uistartPage * sizeof(IMG_UINT32)) & ~((IMG_UINT64)RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE-1)); - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - - eError = RIWritePMREntryWithOwnerKM(psPMRNode->psPMR, - psFreeList->ownerPid); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: call to RIWritePMREntryWithOwnerKM failed (%s)", - __func__, - PVRSRVGetErrorString(eError))); - } - - /* Attach RI information */ - eError = RIWriteMEMDESCEntryKM(psPMRNode->psPMR, - OSStringNLength(szAllocName, DEVMEM_ANNOTATION_MAX_LEN), - szAllocName, - 0, - uiSize, - IMG_FALSE, - IMG_FALSE, - &psPMRNode->hRIHandle); - PVR_LOG_IF_ERROR(eError, "RIWriteMEMDESCEntryKM"); - -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - /* write Freelist with Memory Block physical addresses */ - eError = PMRWritePMPageList( - /* Target PMR, offset, and length */ - psFreeList->psFreeListPMR, - (psPMRNode->bFirstPageMissing ? uiOffset + sizeof(IMG_UINT32) : uiOffset), - (psPMRNode->bFirstPageMissing ? uiLength - sizeof(IMG_UINT32) : uiLength), - /* Referenced PMR, and "page" granularity */ - psPMRNode->psPMR, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT, - &psPMRNode->psPageList); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to write pages of Node %p", - __func__, - psPMRNode)); - goto ErrorPopulateFreelist; - } - -#if defined(SUPPORT_SHADOW_FREELISTS) - /* Copy freelist memory to shadow freelist */ - { - const IMG_UINT32 ui32FLMaxSize = psFreeList->ui32MaxFLPages * sizeof(IMG_UINT32); - const IMG_UINT32 ui32MapSize = ui32FLMaxSize * 2; - const IMG_UINT32 ui32CopyOffset = uiOffset - psFreeList->uiFreeListPMROffset; - IMG_BYTE *pFLMapAddr; - size_t uiNumBytes; - PVRSRV_ERROR res; - IMG_HANDLE hMapHandle; - IMG_DEVMEM_SIZE_T uiPMRSize; - - PMR_LogicalSize(psFreeList->psFreeListPMR, &uiPMRSize); - - /* Check for overflow. Validate size and offset. */ - PVR_GOTO_IF_INVALID_PARAM(psFreeList->uiFreeListPMROffset + ui32MapSize > psFreeList->uiFreeListPMROffset, eError, ErrorPopulateFreelist); - PVR_GOTO_IF_INVALID_PARAM(psFreeList->uiFreeListPMROffset + ui32MapSize <= uiPMRSize, eError, ErrorPopulateFreelist); - - /* Map both the FL and the shadow FL */ - res = PMRAcquireKernelMappingData(psFreeList->psFreeListPMR, psFreeList->uiFreeListPMROffset, ui32MapSize, - (void**) &pFLMapAddr, &uiNumBytes, &hMapHandle); - if (res != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map freelist (ID=%d)", - __func__, - psFreeList->ui32FreelistID)); - goto ErrorPopulateFreelist; - } - - /* Copy only the newly added memory */ - OSCachedMemCopy(pFLMapAddr + ui32FLMaxSize + ui32CopyOffset, pFLMapAddr + ui32CopyOffset , uiLength); - OSWriteMemoryBarrier(pFLMapAddr); - -#if defined(PDUMP) - PDUMPCOMMENT(psFreeList->psDevInfo->psDeviceNode, "Initialize shadow freelist"); - - /* Translate memcpy to pdump */ - { - IMG_DEVMEM_OFFSET_T uiCurrOffset; - - for (uiCurrOffset = uiOffset; (uiCurrOffset - uiOffset) < uiLength; uiCurrOffset += sizeof(IMG_UINT32)) - { - PMRPDumpCopyMem32(psFreeList->psFreeListPMR, - uiCurrOffset + ui32FLMaxSize, - psFreeList->psFreeListPMR, - uiCurrOffset, - ":SYSMEM:$1", - PDUMP_FLAGS_CONTINUOUS); - } - } -#endif - - - res = PMRReleaseKernelMappingData(psFreeList->psFreeListPMR, hMapHandle); - - if (res != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to release freelist mapping (ID=%d)", - __func__, - psFreeList->ui32FreelistID)); - goto ErrorPopulateFreelist; - } - } -#endif - - /* We add It must be added to the tail, otherwise the freelist population won't work */ - dllist_add_to_head(pListHeader, &psPMRNode->sMemoryBlock); - - /* Update number of available pages */ - psFreeList->ui32CurrentFLPages += ui32NumPages; - - /* Update statistics (needs to happen before the ReadyFL calculation to also count those pages) */ - if (psFreeList->ui32NumHighPages < psFreeList->ui32CurrentFLPages) - { - psFreeList->ui32NumHighPages = psFreeList->ui32CurrentFLPages; - } - - /* Reserve a number ready pages to allow the FW to process OOM quickly and asynchronously request a grow. */ - psFreeList->ui32ReadyFLPages = _CalculateFreelistReadyPages(psFreeList, psFreeList->ui32CurrentFLPages); - psFreeList->ui32CurrentFLPages -= psFreeList->ui32ReadyFLPages; - - if (psFreeList->bCheckFreelist) - { - /* - * We can only calculate the freelist checksum when the list is full - * (e.g. at initial creation time). At other times the checksum cannot - * be calculated and has to be disabled for this freelist. - */ - if ((psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages) == ui32NumPages) - { - _CheckFreelist(psFreeList, ui32NumPages, 0, &psFreeList->ui64FreelistChecksum); - } - else - { - psFreeList->ui64FreelistChecksum = 0; - } - } - OSLockRelease(psFreeList->psDevInfo->hLockFreeList); - - PVR_DPF((PVR_DBG_MESSAGE, - "Freelist [%p]: %s %u pages (pages=%u+%u/%u checksum=0x%016" IMG_UINT64_FMTSPECx "%s)", - psFreeList, - ((psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages) == ui32NumPages ? "Create initial" : "Grow by"), - ui32NumPages, - psFreeList->ui32CurrentFLPages, - psFreeList->ui32ReadyFLPages, - psFreeList->ui32MaxFLPages, - psFreeList->ui64FreelistChecksum, - (psPMRNode->bFirstPageMissing ? " - lowest page not allocated" : ""))); - - return PVRSRV_OK; - - /* Error handling */ -ErrorPopulateFreelist: - PMRUnrefPMR(psPMRNode->psPMR); - -ErrorBlockAlloc: - OSFreeMem(psPMRNode); - OSLockRelease(psFreeList->psDevInfo->hLockFreeList); - -ErrorAllocHost: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; - -} - -static PVRSRV_ERROR RGXShrinkFreeList(PDLLIST_NODE pListHeader, - RGX_FREELIST *psFreeList) -{ - DLLIST_NODE *psNode; - RGX_PMR_NODE *psPMRNode; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32OldValue; - - /* - * Lock protects simultaneous manipulation of: - * - the memory block list - * - the freelist's ui32CurrentFLPages value - */ - PVR_ASSERT(pListHeader); - PVR_ASSERT(psFreeList); - PVR_ASSERT(psFreeList->psDevInfo); - PVR_ASSERT(psFreeList->psDevInfo->hLockFreeList); - - OSLockAcquire(psFreeList->psDevInfo->hLockFreeList); - - /* Get node from head of list and remove it */ - psNode = dllist_get_next_node(pListHeader); - if (psNode) - { - dllist_remove_node(psNode); - - psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock); - PVR_ASSERT(psPMRNode); - PVR_ASSERT(psPMRNode->psPMR); - PVR_ASSERT(psPMRNode->psFreeList); - - /* remove block from freelist list */ - - /* Unwrite Freelist with Memory Block physical addresses */ - eError = PMRUnwritePMPageList(psPMRNode->psPageList); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to unwrite pages of Node %p", - __func__, - psPMRNode)); - PVR_ASSERT(IMG_FALSE); - } - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - - if (psPMRNode->hRIHandle) - { - PVRSRV_ERROR eError; - - eError = RIDeleteMEMDESCEntryKM(psPMRNode->hRIHandle); - PVR_LOG_IF_ERROR(eError, "RIDeleteMEMDESCEntryKM"); - } - -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ - - /* Free PMR (We should be the only one that holds a ref on the PMR) */ - eError = PMRUnrefPMR(psPMRNode->psPMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to free PB block %p (%s)", - __func__, - psPMRNode->psPMR, - PVRSRVGetErrorString(eError))); - PVR_ASSERT(IMG_FALSE); - } - - /* update available pages in freelist */ - ui32OldValue = psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages; - - /* - * Deallocated pages should first be deducted from ReadyPages bank, once - * there are no more left, start deducting them from CurrentPage bank. - */ - if (psPMRNode->ui32NumPages > psFreeList->ui32ReadyFLPages) - { - psFreeList->ui32CurrentFLPages -= psPMRNode->ui32NumPages - psFreeList->ui32ReadyFLPages; - psFreeList->ui32ReadyFLPages = 0; - } - else - { - psFreeList->ui32ReadyFLPages -= psPMRNode->ui32NumPages; - } - - /* check underflow */ - PVR_ASSERT(ui32OldValue > (psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages)); - - PVR_DPF((PVR_DBG_MESSAGE, "Freelist [%p]: shrink by %u pages (current pages %u/%u)", - psFreeList, - psPMRNode->ui32NumPages, - psFreeList->ui32CurrentFLPages, - psFreeList->ui32MaxFLPages)); - - OSFreeMem(psPMRNode); - } - else - { - PVR_DPF((PVR_DBG_WARNING, - "Freelist [0x%p]: shrink denied. PB already at initial PB size (%u pages)", - psFreeList, - psFreeList->ui32InitFLPages)); - eError = PVRSRV_ERROR_PBSIZE_ALREADY_MIN; - } - - OSLockRelease(psFreeList->psDevInfo->hLockFreeList); - - return eError; -} - -static RGX_FREELIST *FindFreeList(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32FreelistID) -{ - DLLIST_NODE *psNode, *psNext; - RGX_FREELIST *psFreeList = NULL; - - OSLockAcquire(psDevInfo->hLockFreeList); - - dllist_foreach_node(&psDevInfo->sFreeListHead, psNode, psNext) - { - RGX_FREELIST *psThisFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode); - - if (psThisFreeList->ui32FreelistID == ui32FreelistID) - { - psFreeList = psThisFreeList; - break; - } - } - - OSLockRelease(psDevInfo->hLockFreeList); - return psFreeList; -} - -void RGXProcessRequestGrow(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FreelistID) -{ - RGX_FREELIST *psFreeList = NULL; - RGXFWIF_KCCB_CMD s3DCCBCmd; - IMG_UINT32 ui32GrowValue; - PVRSRV_ERROR eError; - - PVR_ASSERT(psDevInfo); - - psFreeList = FindFreeList(psDevInfo, ui32FreelistID); - - if (psFreeList) - { - /* Since the FW made the request, it has already consumed the ready pages, update the host struct */ - psFreeList->ui32CurrentFLPages += psFreeList->ui32ReadyFLPages; - psFreeList->ui32ReadyFLPages = 0; - - /* Try to grow the freelist */ - eError = RGXGrowFreeList(psFreeList, - psFreeList->ui32GrowFLPages, - &psFreeList->sMemoryBlockHead); - - if (eError == PVRSRV_OK) - { - /* Grow successful, return size of grow size */ - ui32GrowValue = psFreeList->ui32GrowFLPages; - - psFreeList->ui32NumGrowReqByFW++; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - /* Update Stats */ - PVRSRVStatsUpdateFreelistStats(0, - 1, /* Add 1 to the appropriate counter (Requests by FW) */ - psFreeList->ui32InitFLPages, - psFreeList->ui32NumHighPages, - psFreeList->ownerPid); - -#endif - - } - else - { - /* Grow failed */ - ui32GrowValue = 0; - PVR_DPF((PVR_DBG_ERROR, - "Grow for FreeList %p failed (%s)", - psFreeList, - PVRSRVGetErrorString(eError))); - } - - /* send feedback */ - s3DCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE; - s3DCCBCmd.uCmdData.sFreeListGSData.sFreeListFWDevVAddr.ui32Addr = psFreeList->sFreeListFWDevVAddr.ui32Addr; - s3DCCBCmd.uCmdData.sFreeListGSData.ui32DeltaPages = ui32GrowValue; - s3DCCBCmd.uCmdData.sFreeListGSData.ui32NewPages = psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages; - s3DCCBCmd.uCmdData.sFreeListGSData.ui32ReadyPages = psFreeList->ui32ReadyFLPages; - - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_3D, - &s3DCCBCmd, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - /* Kernel CCB should never fill up, as the FW is processing them right away */ - - PVR_ASSERT(eError == PVRSRV_OK); - } - else - { - /* Should never happen */ - PVR_DPF((PVR_DBG_ERROR, - "FreeList Lookup for FreeList ID 0x%08x failed (Populate)", - ui32FreelistID)); - PVR_ASSERT(IMG_FALSE); - } -} - -static void _RGXFreeListReconstruction(PDLLIST_NODE psNode) -{ - - PVRSRV_RGXDEV_INFO *psDevInfo; - RGX_FREELIST *psFreeList; - RGX_PMR_NODE *psPMRNode; - PVRSRV_ERROR eError; - IMG_DEVMEM_OFFSET_T uiOffset; - IMG_DEVMEM_SIZE_T uiLength; - IMG_UINT32 ui32StartPage; - - psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock); - psFreeList = psPMRNode->psFreeList; - PVR_ASSERT(psFreeList); - psDevInfo = psFreeList->psDevInfo; - PVR_ASSERT(psDevInfo); - - uiLength = psPMRNode->ui32NumPages * sizeof(IMG_UINT32); - ui32StartPage = (psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages - psPMRNode->ui32NumPages); - uiOffset = psFreeList->uiFreeListPMROffset + ((ui32StartPage * sizeof(IMG_UINT32)) & ~((IMG_UINT64)RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE-1)); - - PMRUnwritePMPageList(psPMRNode->psPageList); - psPMRNode->psPageList = NULL; - eError = PMRWritePMPageList( - /* Target PMR, offset, and length */ - psFreeList->psFreeListPMR, - (psPMRNode->bFirstPageMissing ? uiOffset + sizeof(IMG_UINT32) : uiOffset), - (psPMRNode->bFirstPageMissing ? uiLength - sizeof(IMG_UINT32) : uiLength), - /* Referenced PMR, and "page" granularity */ - psPMRNode->psPMR, - RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT, - &psPMRNode->psPageList); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error (%s) writing FL 0x%08x", - __func__, - PVRSRVGetErrorString(eError), - (IMG_UINT32)psFreeList->ui32FreelistID)); - } - - /* Zeroing physical pages pointed by the reconstructed freelist */ - if (psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_ZERO_FREELIST) - { - eError = PMRZeroingPMR(psPMRNode->psPMR, RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to zero PMR %p of freelist %p (%s)", - __func__, - psPMRNode->psPMR, - psFreeList, - PVRSRVGetErrorString(eError))); - PVR_ASSERT(0); - } - } - - - psFreeList->ui32CurrentFLPages += psPMRNode->ui32NumPages; -} - - -static PVRSRV_ERROR RGXReconstructFreeList(RGX_FREELIST *psFreeList) -{ - IMG_UINT32 ui32OriginalFLPages; - DLLIST_NODE *psNode, *psNext; - RGXFWIF_FREELIST *psFWFreeList; - PVRSRV_ERROR eError; - - //PVR_DPF((PVR_DBG_ERROR, "FreeList RECONSTRUCTION: Reconstructing freelist %p (ID=%u)", psFreeList, psFreeList->ui32FreelistID)); - - /* Do the FreeList Reconstruction */ - ui32OriginalFLPages = psFreeList->ui32CurrentFLPages; - psFreeList->ui32CurrentFLPages = 0; - - /* Reconstructing Init FreeList pages */ - dllist_foreach_node(&psFreeList->sMemoryBlockInitHead, psNode, psNext) - { - _RGXFreeListReconstruction(psNode); - } - - /* Reconstructing Grow FreeList pages */ - dllist_foreach_node(&psFreeList->sMemoryBlockHead, psNode, psNext) - { - _RGXFreeListReconstruction(psNode); - } - - /* Ready pages are allocated but kept hidden until OOM occurs. */ - psFreeList->ui32CurrentFLPages -= psFreeList->ui32ReadyFLPages; - if (psFreeList->ui32CurrentFLPages != ui32OriginalFLPages) - { - PVR_ASSERT(psFreeList->ui32CurrentFLPages == ui32OriginalFLPages); - return PVRSRV_ERROR_FREELIST_RECONSTRUCTION_FAILED; - } - - /* Reset the firmware freelist structure */ - eError = DevmemAcquireCpuVirtAddr(psFreeList->psFWFreelistMemDesc, (void **)&psFWFreeList); - if (eError != PVRSRV_OK) - { - return eError; - } - - psFWFreeList->ui32CurrentStackTop = psFWFreeList->ui32CurrentPages - 1; - psFWFreeList->ui32AllocatedPageCount = 0; - psFWFreeList->ui32AllocatedMMUPageCount = 0; - - DevmemReleaseCpuVirtAddr(psFreeList->psFWFreelistMemDesc); - - /* Check the Freelist checksum if required (as the list is fully populated) */ - if (psFreeList->bCheckFreelist) - { - IMG_UINT64 ui64CheckSum; - - _CheckFreelist(psFreeList, psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages, psFreeList->ui64FreelistChecksum, &ui64CheckSum); - } - - return eError; -} - - -void RGXProcessRequestFreelistsReconstruction(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FreelistsCount, - const IMG_UINT32 *paui32Freelists) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - DLLIST_NODE *psNode, *psNext; - IMG_UINT32 ui32Loop; - RGXFWIF_KCCB_CMD sTACCBCmd; -#if !defined(SUPPORT_SHADOW_FREELISTS) - DLLIST_NODE *psNodeHWRTData, *psNextHWRTData; - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet; - RGXFWIF_HWRTDATA *psHWRTData; -#endif - IMG_UINT32 ui32FinalFreelistsCount = 0; - IMG_UINT32 aui32FinalFreelists[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT * 2]; /* Worst-case is double what we are sent */ - - PVR_ASSERT(psDevInfo != NULL); - PVR_ASSERT(ui32FreelistsCount <= RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT); - if (ui32FreelistsCount > RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT) - { - ui32FreelistsCount = RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT; - } - - //PVR_DPF((PVR_DBG_ERROR, "FreeList RECONSTRUCTION: %u freelist(s) requested for reconstruction", ui32FreelistsCount)); - - /* - * Initialise the response command (in case we don't find a freelist ID). - * Also copy the list to the 'final' freelist array. - */ - sTACCBCmd.eCmdType = RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE; - sTACCBCmd.uCmdData.sFreeListsReconstructionData.ui32FreelistsCount = ui32FreelistsCount; - - for (ui32Loop = 0; ui32Loop < ui32FreelistsCount; ui32Loop++) - { - sTACCBCmd.uCmdData.sFreeListsReconstructionData.aui32FreelistIDs[ui32Loop] = paui32Freelists[ui32Loop] | - RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG; - aui32FinalFreelists[ui32Loop] = paui32Freelists[ui32Loop]; - } - - ui32FinalFreelistsCount = ui32FreelistsCount; - - /* - * The list of freelists we have been given for reconstruction will - * consist of local and global freelists (maybe MMU as well). Any - * local freelists should have their global list specified as well. - * There may be cases where the global freelist is not given (in - * cases of partial setups before a poll failure for example). To - * handle that we must first ensure every local freelist has a global - * freelist specified, otherwise we add that to the 'final' list. - * This final list of freelists is created in a first pass. - * - * Even with the global freelists listed, there may be other local - * freelists not listed, which are going to have their global freelist - * reconstructed. Therefore we have to find those freelists as well - * meaning we will have to iterate the entire list of freelists to - * find which must be reconstructed. This is the second pass. - */ - OSLockAcquire(psDevInfo->hLockFreeList); - dllist_foreach_node(&psDevInfo->sFreeListHead, psNode, psNext) - { - RGX_FREELIST *psFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode); - IMG_BOOL bInList = IMG_FALSE; - IMG_BOOL bGlobalInList = IMG_FALSE; - - /* Check if this local freelist is in the list and ensure its global is too. */ - if (psFreeList->ui32FreelistGlobalID != 0) - { - for (ui32Loop = 0; ui32Loop < ui32FinalFreelistsCount; ui32Loop++) - { - if (aui32FinalFreelists[ui32Loop] == psFreeList->ui32FreelistID) - { - bInList = IMG_TRUE; - } - if (aui32FinalFreelists[ui32Loop] == psFreeList->ui32FreelistGlobalID) - { - bGlobalInList = IMG_TRUE; - } - } - - if (bInList && !bGlobalInList) - { - aui32FinalFreelists[ui32FinalFreelistsCount] = psFreeList->ui32FreelistGlobalID; - ui32FinalFreelistsCount++; - } - } - } - dllist_foreach_node(&psDevInfo->sFreeListHead, psNode, psNext) - { - RGX_FREELIST *psFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode); - IMG_BOOL bReconstruct = IMG_FALSE; - - /* - * Check if this freelist needs to be reconstructed (was it requested - * or is its global freelist going to be reconstructed)... - */ - for (ui32Loop = 0; ui32Loop < ui32FinalFreelistsCount; ui32Loop++) - { - if (aui32FinalFreelists[ui32Loop] == psFreeList->ui32FreelistID || - aui32FinalFreelists[ui32Loop] == psFreeList->ui32FreelistGlobalID) - { - bReconstruct = IMG_TRUE; - break; - } - } - - if (bReconstruct) - { - eError = RGXReconstructFreeList(psFreeList); - if (eError == PVRSRV_OK) - { -#if !defined(SUPPORT_SHADOW_FREELISTS) - /* Mark all HWRTData's of reconstructing local freelists as HWR (applies to TA/3D's not finished yet) */ - dllist_foreach_node(&psFreeList->sNodeHWRTDataHead, psNodeHWRTData, psNextHWRTData) - { - psKMHWRTDataSet = IMG_CONTAINER_OF(psNodeHWRTData, RGX_KM_HW_RT_DATASET, sNodeHWRTData); - eError = DevmemAcquireCpuVirtAddr(psKMHWRTDataSet->psHWRTDataFwMemDesc, (void **)&psHWRTData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Devmem AcquireCpuVirtAddr Failed during Reconstructing of FreeList, FwMemDesc(%p),psHWRTData(%p)", - psKMHWRTDataSet->psHWRTDataFwMemDesc, - psHWRTData)); - continue; - } - - psHWRTData->eState = RGXFWIF_RTDATA_STATE_HWR; - psHWRTData->ui32HWRTDataFlags &= ~HWRTDATA_HAS_LAST_TA; - - DevmemReleaseCpuVirtAddr(psKMHWRTDataSet->psHWRTDataFwMemDesc); - } -#endif - - /* Update the response for this freelist if it was specifically requested for reconstruction. */ - for (ui32Loop = 0; ui32Loop < ui32FreelistsCount; ui32Loop++) - { - if (paui32Freelists[ui32Loop] == psFreeList->ui32FreelistID) - { - /* Reconstruction of this requested freelist was successful... */ - sTACCBCmd.uCmdData.sFreeListsReconstructionData.aui32FreelistIDs[ui32Loop] &= ~RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG; - break; - } - } - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "Reconstructing of FreeList %p failed (%s)", - psFreeList, - PVRSRVGetErrorString(eError))); - } - } - } - OSLockRelease(psDevInfo->hLockFreeList); - - /* Check that all freelists were found and reconstructed... */ - for (ui32Loop = 0; ui32Loop < ui32FreelistsCount; ui32Loop++) - { - PVR_ASSERT((sTACCBCmd.uCmdData.sFreeListsReconstructionData.aui32FreelistIDs[ui32Loop] & - RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG) == 0); - } - - /* send feedback */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GEOM, - &sTACCBCmd, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Kernel CCB should never fill up, as the FW is processing them right away */ - PVR_ASSERT(eError == PVRSRV_OK); -} - -/* Create a single HWRTData instance */ -static PVRSRV_ERROR RGXCreateHWRTData_aux( - CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR psVHeapTableDevVAddr, - IMG_DEV_VIRTADDR psPMMListDevVAddr, /* per-HWRTData */ - RGX_FREELIST *apsFreeLists[RGXFW_MAX_FREELISTS], - IMG_DEV_VIRTADDR sTailPtrsDevVAddr, - IMG_DEV_VIRTADDR sMacrotileArrayDevVAddr, /* per-HWRTData */ - IMG_DEV_VIRTADDR sRgnHeaderDevVAddr, /* per-HWRTData */ - IMG_DEV_VIRTADDR sRTCDevVAddr, - IMG_UINT16 ui16MaxRTs, - RGX_HWRTDATA_COMMON_COOKIE *psHWRTDataCommonCookie, - RGX_KM_HW_RT_DATASET **ppsKMHWRTDataSet) /* per-HWRTData */ -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32Loop; - - /* KM cookie storing all the FW/HW data */ - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet; - - /* local pointers for memory descriptors of FW allocations */ - DEVMEM_MEMDESC *psHWRTDataFwMemDesc = NULL; - DEVMEM_MEMDESC *psRTArrayFwMemDesc = NULL; - DEVMEM_MEMDESC *psRendersAccArrayFwMemDesc = NULL; - - /* local pointer for CPU-mapped [FW]HWRTData */ - RGXFWIF_HWRTDATA *psHWRTData = NULL; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* Prepare the HW RT DataSet struct */ - psKMHWRTDataSet = OSAllocZMem(sizeof(*psKMHWRTDataSet)); - if (psKMHWRTDataSet == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto AllocError; - } - - *ppsKMHWRTDataSet = psKMHWRTDataSet; - psKMHWRTDataSet->psDeviceNode = psDeviceNode; - - psKMHWRTDataSet->psHWRTDataCommonCookie = psHWRTDataCommonCookie; - - psDevInfo = psDeviceNode->pvDevice; - - /* - * This FW RT-Data is only mapped into kernel for initialisation. - * Otherwise this allocation is only used by the FW. - * Therefore the GPU cache doesn't need coherency, and write-combine will - * suffice on the CPU side (WC buffer will be flushed at the first TA-kick) - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_HWRTDATA), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwHWRTData", - &psHWRTDataFwMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: DevmemAllocate for RGX_FWIF_HWRTDATA failed", - __func__)); - goto FWRTDataAllocateError; - } - - psKMHWRTDataSet->psHWRTDataFwMemDesc = psHWRTDataFwMemDesc; - eError = RGXSetFirmwareAddress( &psKMHWRTDataSet->sHWRTDataFwAddr, - psHWRTDataFwMemDesc, - 0, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:1", FWRTDataFwAddrError); - - eError = DevmemAcquireCpuVirtAddr(psHWRTDataFwMemDesc, - (void **)&psHWRTData); - PVR_LOG_GOTO_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", FWRTDataCpuMapError); - - psHWRTData->psVHeapTableDevVAddr = psVHeapTableDevVAddr; - - psHWRTData->sHWRTDataCommonFwAddr = psHWRTDataCommonCookie->sHWRTDataCommonFwAddr; - - psHWRTData->psPMMListDevVAddr = psPMMListDevVAddr; - - psHWRTData->sTailPtrsDevVAddr = sTailPtrsDevVAddr; - psHWRTData->sMacrotileArrayDevVAddr = sMacrotileArrayDevVAddr; - psHWRTData->sRgnHeaderDevVAddr = sRgnHeaderDevVAddr; - psHWRTData->sRTCDevVAddr = sRTCDevVAddr; - - OSLockAcquire(psDevInfo->hLockFreeList); - for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++) - { - psKMHWRTDataSet->apsFreeLists[ui32Loop] = apsFreeLists[ui32Loop]; - psKMHWRTDataSet->apsFreeLists[ui32Loop]->ui32RefCount++; - psHWRTData->apsFreeLists[ui32Loop].ui32Addr = psKMHWRTDataSet->apsFreeLists[ui32Loop]->sFreeListFWDevVAddr.ui32Addr; - /* invalid initial snapshot value, the snapshot is always taken during first kick - * and hence the value get replaced during the first kick anyway. So it's safe to set it 0. - */ - psHWRTData->aui32FreeListHWRSnapshot[ui32Loop] = 0; - } -#if !defined(SUPPORT_SHADOW_FREELISTS) - dllist_add_to_tail(&apsFreeLists[RGXFW_LOCAL_FREELIST]->sNodeHWRTDataHead, &(psKMHWRTDataSet->sNodeHWRTData)); -#endif - OSLockRelease(psDevInfo->hLockFreeList); - - { - RGXFWIF_RTA_CTL *psRTACtl = &psHWRTData->sRTACtl; - - psRTACtl->ui32RenderTargetIndex = 0; - psRTACtl->ui32ActiveRenderTargets = 0; - psRTACtl->sValidRenderTargets.ui32Addr = 0; - psRTACtl->sRTANumPartialRenders.ui32Addr = 0; - psRTACtl->ui32MaxRTs = (IMG_UINT32) ui16MaxRTs; - - if (ui16MaxRTs > 1) - { - PDUMPCOMMENT(psDeviceNode, "Allocate memory for shadow render target cache"); - eError = DevmemFwAllocate(psDevInfo, - ui16MaxRTs * sizeof(IMG_UINT32), - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwShadowRTCache", - &psRTArrayFwMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate %u bytes for render target array (%s)", - __func__, - ui16MaxRTs, PVRSRVGetErrorString(eError))); - goto FWAllocateRTArryError; - } - - psKMHWRTDataSet->psRTArrayFwMemDesc = psRTArrayFwMemDesc; - eError = RGXSetFirmwareAddress(&psRTACtl->sValidRenderTargets, - psRTArrayFwMemDesc, - 0, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:2", FWAllocateRTArryFwAddrError); - - PDUMPCOMMENT(psDeviceNode, "Allocate memory for tracking renders accumulation"); - eError = DevmemFwAllocate(psDevInfo, - ui16MaxRTs * sizeof(IMG_UINT32), - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwRendersAccumulation", - &psRendersAccArrayFwMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate %u bytes for render target array (%s) (renders accumulation)", - __func__, - ui16MaxRTs, PVRSRVGetErrorString(eError))); - goto FWAllocateRTAccArryError; - } - psKMHWRTDataSet->psRendersAccArrayFwMemDesc = psRendersAccArrayFwMemDesc; - eError = RGXSetFirmwareAddress(&psRTACtl->sRTANumPartialRenders, - psRendersAccArrayFwMemDesc, - 0, - RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress:3", FWAllocRTAccArryFwAddrError); - } - } - -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump HWRTData 0x%08X", psKMHWRTDataSet->sHWRTDataFwAddr.ui32Addr); - DevmemPDumpLoadMem(psKMHWRTDataSet->psHWRTDataFwMemDesc, 0, sizeof(*psHWRTData), PDUMP_FLAGS_CONTINUOUS); -#endif - - DevmemReleaseCpuVirtAddr(psKMHWRTDataSet->psHWRTDataFwMemDesc); - return PVRSRV_OK; - -FWAllocRTAccArryFwAddrError: - DevmemFwUnmapAndFree(psDevInfo, psRendersAccArrayFwMemDesc); -FWAllocateRTAccArryError: - RGXUnsetFirmwareAddress(psKMHWRTDataSet->psRTArrayFwMemDesc); -FWAllocateRTArryFwAddrError: - DevmemFwUnmapAndFree(psDevInfo, psKMHWRTDataSet->psRTArrayFwMemDesc); -FWAllocateRTArryError: - OSLockAcquire(psDevInfo->hLockFreeList); - for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++) - { - PVR_ASSERT(psKMHWRTDataSet->apsFreeLists[ui32Loop]->ui32RefCount > 0); - psKMHWRTDataSet->apsFreeLists[ui32Loop]->ui32RefCount--; - } - OSLockRelease(psDevInfo->hLockFreeList); - DevmemReleaseCpuVirtAddr(psKMHWRTDataSet->psHWRTDataFwMemDesc); -FWRTDataCpuMapError: - RGXUnsetFirmwareAddress(psKMHWRTDataSet->psHWRTDataFwMemDesc); -FWRTDataFwAddrError: - DevmemFwUnmapAndFree(psDevInfo, psKMHWRTDataSet->psHWRTDataFwMemDesc); -FWRTDataAllocateError: - *ppsKMHWRTDataSet = NULL; - OSFreeMem(psKMHWRTDataSet); - -AllocError: - return eError; -} - -static void RGXDestroyHWRTData_aux(RGX_KM_HW_RT_DATASET *psKMHWRTDataSet) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - IMG_UINT32 ui32Loop; - - if (psKMHWRTDataSet == NULL) - { - return; - } - - psDevInfo = psKMHWRTDataSet->psDeviceNode->pvDevice; - - if (psKMHWRTDataSet->psRTArrayFwMemDesc) - { - RGXUnsetFirmwareAddress(psKMHWRTDataSet->psRTArrayFwMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psKMHWRTDataSet->psRTArrayFwMemDesc); - } - - if (psKMHWRTDataSet->psRendersAccArrayFwMemDesc) - { - RGXUnsetFirmwareAddress(psKMHWRTDataSet->psRendersAccArrayFwMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psKMHWRTDataSet->psRendersAccArrayFwMemDesc); - } - - /* Decrease freelist refcount */ - OSLockAcquire(psDevInfo->hLockFreeList); - for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++) - { - PVR_ASSERT(psKMHWRTDataSet->apsFreeLists[ui32Loop]->ui32RefCount > 0); - psKMHWRTDataSet->apsFreeLists[ui32Loop]->ui32RefCount--; - } -#if !defined(SUPPORT_SHADOW_FREELISTS) - dllist_remove_node(&psKMHWRTDataSet->sNodeHWRTData); -#endif - OSLockRelease(psDevInfo->hLockFreeList); - - /* Freeing the memory has to happen _after_ removing the HWRTData from the freelist - * otherwise we risk traversing the freelist to find a pointer from a freed data structure */ - RGXUnsetFirmwareAddress(psKMHWRTDataSet->psHWRTDataFwMemDesc); - DevmemFwUnmapAndFree(psDevInfo, psKMHWRTDataSet->psHWRTDataFwMemDesc); - - OSFreeMem(psKMHWRTDataSet); -} - -/* Create set of HWRTData(s) and bind it with a shared FW HWRTDataCommon */ -PVRSRV_ERROR RGXCreateHWRTDataSet(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR asVHeapTableDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_DEV_VIRTADDR asPMMListDevVAddr[RGXMKIF_NUM_RTDATAS], - RGX_FREELIST *apsFreeLists[RGXMKIF_NUM_RTDATA_FREELISTS], - IMG_UINT32 ui32ScreenPixelMax, - IMG_UINT64 ui64MultiSampleCtl, - IMG_UINT64 ui64FlippedMultiSampleCtl, - IMG_UINT32 ui32TPCStride, - IMG_DEV_VIRTADDR asTailPtrsDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_UINT32 ui32TPCSize, - IMG_UINT32 ui32TEScreen, - IMG_UINT32 ui32TEAA, - IMG_UINT32 ui32TEMTILE1, - IMG_UINT32 ui32TEMTILE2, - IMG_UINT32 ui32MTileStride, - IMG_UINT32 ui32ISPMergeLowerX, - IMG_UINT32 ui32ISPMergeLowerY, - IMG_UINT32 ui32ISPMergeUpperX, - IMG_UINT32 ui32ISPMergeUpperY, - IMG_UINT32 ui32ISPMergeScaleX, - IMG_UINT32 ui32ISPMergeScaleY, - IMG_DEV_VIRTADDR asMacrotileArrayDevVAddr[RGXMKIF_NUM_RTDATAS], - IMG_DEV_VIRTADDR asRgnHeaderDevVAddr[RGXMKIF_NUM_RTDATAS], - IMG_DEV_VIRTADDR asRTCDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_UINT32 uiRgnHeaderSize, - IMG_UINT32 ui32ISPMtileSize, - IMG_UINT16 ui16MaxRTs, - RGX_KM_HW_RT_DATASET *pasKMHWRTDataSet[RGXMKIF_NUM_RTDATAS]) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32RTDataID; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - RGX_HWRTDATA_COMMON_COOKIE *psHWRTDataCommonCookie; - RGXFWIF_HWRTDATA_COMMON *psHWRTDataCommon; - DEVMEM_MEMDESC *psHWRTDataCommonFwMemDesc; - RGXFWIF_DEV_VIRTADDR sHWRTDataCommonFwAddr; - - /* Prepare KM cleanup object for HWRTDataCommon FW object */ - psHWRTDataCommonCookie = OSAllocZMem(sizeof(*psHWRTDataCommonCookie)); - if (psHWRTDataCommonCookie == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto err_HWRTDataCommonCookieAlloc; - } - - /* - * This FW common context is only mapped into kernel for initialisation. - * Otherwise this allocation is only used by the FW. - * Therefore the GPU cache doesn't need coherency, and write-combine will - * suffice on the CPU side (WC buffer will be flushed at the first TA-kick) - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_HWRTDATA_COMMON), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwHWRTDataCommon", - &psHWRTDataCommonFwMemDesc); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: DevmemAllocate for FwHWRTDataCommon failed", __func__)); - goto err_HWRTDataCommonAlloc; - } - eError = RGXSetFirmwareAddress(&sHWRTDataCommonFwAddr, psHWRTDataCommonFwMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", err_HWRTDataCommonFwAddr); - - eError = DevmemAcquireCpuVirtAddr(psHWRTDataCommonFwMemDesc, (void **)&psHWRTDataCommon); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", err_HWRTDataCommonVA); - - psHWRTDataCommon->bTACachesNeedZeroing = IMG_FALSE; - psHWRTDataCommon->ui32ScreenPixelMax = ui32ScreenPixelMax; - psHWRTDataCommon->ui64MultiSampleCtl = ui64MultiSampleCtl; - psHWRTDataCommon->ui64FlippedMultiSampleCtl = ui64FlippedMultiSampleCtl; - psHWRTDataCommon->ui32TPCStride = ui32TPCStride; - psHWRTDataCommon->ui32TPCSize = ui32TPCSize; - psHWRTDataCommon->ui32TEScreen = ui32TEScreen; - psHWRTDataCommon->ui32TEAA = ui32TEAA; - psHWRTDataCommon->ui32TEMTILE1 = ui32TEMTILE1; - psHWRTDataCommon->ui32TEMTILE2 = ui32TEMTILE2; - psHWRTDataCommon->ui32MTileStride = ui32MTileStride; - psHWRTDataCommon->ui32ISPMergeLowerX = ui32ISPMergeLowerX; - psHWRTDataCommon->ui32ISPMergeLowerY = ui32ISPMergeLowerY; - psHWRTDataCommon->ui32ISPMergeUpperX = ui32ISPMergeUpperX; - psHWRTDataCommon->ui32ISPMergeUpperY = ui32ISPMergeUpperY; - psHWRTDataCommon->ui32ISPMergeScaleX = ui32ISPMergeScaleX; - psHWRTDataCommon->ui32ISPMergeScaleY = ui32ISPMergeScaleY; - psHWRTDataCommon->uiRgnHeaderSize = uiRgnHeaderSize; - psHWRTDataCommon->ui32ISPMtileSize = ui32ISPMtileSize; -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump HWRTDataCommon"); - DevmemPDumpLoadMem(psHWRTDataCommonFwMemDesc, 0, sizeof(*psHWRTDataCommon), PDUMP_FLAGS_CONTINUOUS); -#endif - DevmemReleaseCpuVirtAddr(psHWRTDataCommonFwMemDesc); - - psHWRTDataCommonCookie->ui32RefCount = 0; - psHWRTDataCommonCookie->psHWRTDataCommonFwMemDesc = psHWRTDataCommonFwMemDesc; - psHWRTDataCommonCookie->sHWRTDataCommonFwAddr = sHWRTDataCommonFwAddr; - - /* Here we are creating a set of HWRTData(s) - the number of elements in the set equals RGXMKIF_NUM_RTDATAS. - */ - - for (ui32RTDataID = 0; ui32RTDataID < RGXMKIF_NUM_RTDATAS; ui32RTDataID++) - { - eError = RGXCreateHWRTData_aux( - psConnection, - psDeviceNode, - asVHeapTableDevVAddr[ui32RTDataID % RGXMKIF_NUM_GEOMDATAS], - asPMMListDevVAddr[ui32RTDataID], - &apsFreeLists[(ui32RTDataID % RGXMKIF_NUM_GEOMDATAS) * RGXFW_MAX_FREELISTS], - asTailPtrsDevVAddr[ui32RTDataID % RGXMKIF_NUM_GEOMDATAS], - asMacrotileArrayDevVAddr[ui32RTDataID], - asRgnHeaderDevVAddr[ui32RTDataID], - asRTCDevVAddr[ui32RTDataID % RGXMKIF_NUM_GEOMDATAS], - ui16MaxRTs, - psHWRTDataCommonCookie, - &pasKMHWRTDataSet[ui32RTDataID]); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to create HWRTData [slot %u] (%s)", - __func__, - ui32RTDataID, - PVRSRVGetErrorString(eError))); - goto err_HWRTDataAlloc; - } - psHWRTDataCommonCookie->ui32RefCount += 1; - } - - return PVRSRV_OK; - -err_HWRTDataAlloc: - PVR_DPF((PVR_DBG_WARNING, "%s: err_HWRTDataAlloc %u", - __func__, psHWRTDataCommonCookie->ui32RefCount)); - if (pasKMHWRTDataSet) - { - for (ui32RTDataID = psHWRTDataCommonCookie->ui32RefCount; ui32RTDataID > 0; ui32RTDataID--) - { - if (pasKMHWRTDataSet[ui32RTDataID-1] != NULL) - { - RGXDestroyHWRTData_aux(pasKMHWRTDataSet[ui32RTDataID-1]); - pasKMHWRTDataSet[ui32RTDataID-1] = NULL; - } - } - } -err_HWRTDataCommonVA: - RGXUnsetFirmwareAddress(psHWRTDataCommonFwMemDesc); -err_HWRTDataCommonFwAddr: - DevmemFwUnmapAndFree(psDevInfo, psHWRTDataCommonFwMemDesc); -err_HWRTDataCommonAlloc: - OSFreeMem(psHWRTDataCommonCookie); -err_HWRTDataCommonCookieAlloc: - - return eError; -} - -/* Destroy a single instance of HWRTData. - Additionally, destroy the HWRTDataCommon{Cookie} objects - when it is the last HWRTData within a corresponding set of HWRTDatas. -*/ -PVRSRV_ERROR RGXDestroyHWRTDataSet(RGX_KM_HW_RT_DATASET *psKMHWRTDataSet) -{ - PVRSRV_DEVICE_NODE *psDevNode; - PVRSRV_ERROR eError; - PRGXFWIF_HWRTDATA psHWRTData; - RGX_HWRTDATA_COMMON_COOKIE *psCommonCookie; - - PVR_ASSERT(psKMHWRTDataSet); - - psDevNode = psKMHWRTDataSet->psDeviceNode; - - eError = RGXSetFirmwareAddress(&psHWRTData, - psKMHWRTDataSet->psHWRTDataFwMemDesc, 0, - RFW_FWADDR_NOREF_FLAG); - PVR_RETURN_IF_ERROR(eError); - - /* Cleanup HWRTData */ - eError = RGXFWRequestHWRTDataCleanUp(psDevNode, psHWRTData); - if (eError != PVRSRV_OK) - { - return eError; - } - - psCommonCookie = psKMHWRTDataSet->psHWRTDataCommonCookie; - - RGXDestroyHWRTData_aux(psKMHWRTDataSet); - - /* We've got past potential PVRSRV_ERROR_RETRY events, so we are sure - that the HWRTDATA instance will be destroyed during this call. - Consequently, we decrease the ref count for HWRTDataCommonCookie. - - NOTE: This ref count does not require locks or atomics. - ------------------------------------------------------- - HWRTDatas bound into one pair are always destroyed sequentially, - within a single loop on the Client side. - The Common/Cookie objects always belong to only one pair of - HWRTDatas, and ref count is used to ensure that the Common/Cookie - objects will be destroyed after destruction of all HWRTDatas - within a single pair. - */ - psCommonCookie->ui32RefCount--; - - /* When ref count for HWRTDataCommonCookie hits ZERO - * we have to destroy the HWRTDataCommon [FW object] and the cookie - * [KM object] afterwards. */ - if (psCommonCookie->ui32RefCount == 0) - { - RGXUnsetFirmwareAddress(psCommonCookie->psHWRTDataCommonFwMemDesc); - - /* We don't need to flush the SLC before freeing. - * FW RequestCleanUp has already done that for HWRTData, so we're fine - * now. */ - - DevmemFwUnmapAndFree(psDevNode->pvDevice, - psCommonCookie->psHWRTDataCommonFwMemDesc); - OSFreeMem(psCommonCookie); - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXCreateFreeList(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32MaxFLPages, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32GrowFLPages, - IMG_UINT32 ui32GrowParamThreshold, - RGX_FREELIST *psGlobalFreeList, - IMG_BOOL bCheckFreelist, - IMG_DEV_VIRTADDR sFreeListDevVAddr, - PMR *psFreeListPMR, - IMG_DEVMEM_OFFSET_T uiFreeListPMROffset, - RGX_FREELIST **ppsFreeList) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(hMemCtxPrivData); - PVR_UNREFERENCED_PARAMETER(ui32MaxFLPages); - PVR_UNREFERENCED_PARAMETER(ui32InitFLPages); - PVR_UNREFERENCED_PARAMETER(ui32GrowFLPages); - PVR_UNREFERENCED_PARAMETER(ui32GrowParamThreshold); - PVR_UNREFERENCED_PARAMETER(psGlobalFreeList); - PVR_UNREFERENCED_PARAMETER(bCheckFreelist); - PVR_UNREFERENCED_PARAMETER(sFreeListDevVAddr); - PVR_UNREFERENCED_PARAMETER(psFreeListPMR); - PVR_UNREFERENCED_PARAMETER(uiFreeListPMROffset); - PVR_UNREFERENCED_PARAMETER(ppsFreeList); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR RGXCreateFreeList2(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32MaxFLPages, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32GrowFLPages, - IMG_UINT32 ui32GrowParamThreshold, - RGX_FREELIST *psGlobalFreeList, - IMG_BOOL bCheckFreelist, - DEVMEMINT_RESERVATION2 *psFreeListReservation, - RGX_FREELIST **ppsFreeList) -{ - PVRSRV_ERROR eError; - RGXFWIF_FREELIST *psFWFreeList; - DEVMEM_MEMDESC *psFWFreelistMemDesc; - RGX_FREELIST *psFreeList; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - IMG_DEV_VIRTADDR sFreeListDevVAddr; - PMR* psFreeListPMR = NULL; - - /* Obtain reference to reservation object */ - if (!DevmemIntReservationAcquire(psFreeListReservation)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire reservation for freelist buffer", - __func__)); - eError = PVRSRV_ERROR_REFCOUNT_OVERFLOW; - goto ErrorReservationAcquire; - } - - eError = DevmemIntGetReservationData(psFreeListReservation, &psFreeListPMR, &sFreeListDevVAddr); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Error from DevmemIntGetReservationData: %s", - __func__, PVRSRVGetErrorString(eError))); - - goto ErrorAllocHost; - } - - /* Check if client properly allocated PMMETA_PROTECT */ - if ((PMR_Flags(psFreeListPMR) & PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT)) == 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Freelist PMR must have PMMETA_PROTECT set", - __func__)); - eError = PVRSRV_ERROR_INVALID_FLAGS; - goto ErrorAllocHost; - } - - if (PMR_IsSparse(psFreeListPMR)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Free list PMR cannot be sparse!", - __func__)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto ErrorAllocHost; - } - - /* Ref the PMR to prevent resource being destroyed before use */ - PMRRefPMR(psFreeListPMR); - - if (OSGetPageShift() > RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT) - { - IMG_UINT32 ui32Size, ui32NewInitFLPages, ui32NewMaxFLPages, ui32NewGrowFLPages; - - /* Round up number of FL pages to the next multiple of the OS page size */ - - ui32Size = ui32InitFLPages << RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - ui32Size = PVR_ALIGN(ui32Size, (IMG_DEVMEM_SIZE_T)OSGetPageSize()); - ui32NewInitFLPages = ui32Size >> RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - - ui32Size = ui32GrowFLPages << RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - ui32Size = PVR_ALIGN(ui32Size, (IMG_DEVMEM_SIZE_T)OSGetPageSize()); - ui32NewGrowFLPages = ui32Size >> RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - - ui32Size = ui32MaxFLPages << RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - ui32Size = PVR_ALIGN(ui32Size, (IMG_DEVMEM_SIZE_T)OSGetPageSize()); - ui32NewMaxFLPages = ui32Size >> RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT; - - PVR_DPF((PVR_DBG_WARNING, "%s: Increased number of PB pages: Init %u -> %u, Grow %u -> %u, Max %u -> %u", - __func__, ui32InitFLPages, ui32NewInitFLPages, ui32GrowFLPages, ui32NewGrowFLPages, ui32MaxFLPages, ui32NewMaxFLPages)); - - ui32InitFLPages = ui32NewInitFLPages; - ui32GrowFLPages = ui32NewGrowFLPages; - ui32MaxFLPages = ui32NewMaxFLPages; - } - - /* Allocate kernel freelist struct */ - psFreeList = OSAllocZMem(sizeof(*psFreeList)); - if (psFreeList == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to allocate host data structure", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorAllocHost; - } - - /* - * This FW FreeList context is only mapped into kernel for initialisation - * and reconstruction (at other times it is not mapped and only used by the - * FW). - * Therefore the GPU cache doesn't need coherency, and write-combine will - * suffice on the CPU side (WC buffer will be flushed at the first TA-kick) - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(*psFWFreeList), - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwFreeList", - &psFWFreelistMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: DevmemAllocate for RGXFWIF_FREELIST failed", - __func__)); - goto FWFreeListAlloc; - } - - /* Initialise host data structures */ - psFreeList->psDevInfo = psDevInfo; - psFreeList->psConnection = psConnection; - - psFreeList->psFreeListPMR = psFreeListPMR; - psFreeList->psFreeListReservation = psFreeListReservation; - - psFreeList->uiFreeListPMROffset = 0U; - - psFreeList->psFWFreelistMemDesc = psFWFreelistMemDesc; - eError = RGXSetFirmwareAddress(&psFreeList->sFreeListFWDevVAddr, psFWFreelistMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", ErrorSetFwAddr); - - /* psFreeList->ui32FreelistID set below with lock... */ - psFreeList->ui32FreelistGlobalID = (psGlobalFreeList ? psGlobalFreeList->ui32FreelistID : 0); - psFreeList->ui32MaxFLPages = ui32MaxFLPages; - psFreeList->ui32InitFLPages = ui32InitFLPages; - psFreeList->ui32GrowFLPages = ui32GrowFLPages; - psFreeList->ui32CurrentFLPages = 0; - psFreeList->ui32ReadyFLPages = 0; - psFreeList->ui32GrowThreshold = ui32GrowParamThreshold; - psFreeList->ui64FreelistChecksum = 0; - psFreeList->ui32RefCount = 0; - psFreeList->bCheckFreelist = bCheckFreelist; - dllist_init(&psFreeList->sMemoryBlockHead); - dllist_init(&psFreeList->sMemoryBlockInitHead); -#if !defined(SUPPORT_SHADOW_FREELISTS) - dllist_init(&psFreeList->sNodeHWRTDataHead); -#endif - psFreeList->ownerPid = OSGetCurrentClientProcessIDKM(); - - - /* Add to list of freelists */ - OSLockAcquire(psDevInfo->hLockFreeList); - psFreeList->ui32FreelistID = psDevInfo->ui32FreelistCurrID++; - dllist_add_to_tail(&psDevInfo->sFreeListHead, &psFreeList->sNode); - OSLockRelease(psDevInfo->hLockFreeList); - - - /* Initialise FW data structure */ - eError = DevmemAcquireCpuVirtAddr(psFreeList->psFWFreelistMemDesc, (void **)&psFWFreeList); - PVR_LOG_GOTO_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", FWFreeListCpuMap); - - { - const IMG_UINT32 ui32ReadyPages = _CalculateFreelistReadyPages(psFreeList, ui32InitFLPages); - - psFWFreeList->ui32MaxPages = ui32MaxFLPages; - psFWFreeList->ui32CurrentPages = ui32InitFLPages - ui32ReadyPages; - psFWFreeList->ui32GrowPages = ui32GrowFLPages; - psFWFreeList->ui32CurrentStackTop = psFWFreeList->ui32CurrentPages - 1; - psFWFreeList->psFreeListDevVAddr = sFreeListDevVAddr; - psFWFreeList->ui64CurrentDevVAddr = (sFreeListDevVAddr.uiAddr + - ((ui32MaxFLPages - psFWFreeList->ui32CurrentPages) * sizeof(IMG_UINT32))) & - ~((IMG_UINT64)RGX_BIF_PM_FREELIST_BASE_ADDR_ALIGNSIZE-1); - psFWFreeList->ui32FreeListID = psFreeList->ui32FreelistID; - psFWFreeList->bGrowPending = IMG_FALSE; - psFWFreeList->ui32ReadyPages = ui32ReadyPages; - -#if defined(SUPPORT_SHADOW_FREELISTS) - /* Get the FW Memory Context address... */ - eError = RGXSetFirmwareAddress(&psFWFreeList->psFWMemContext, - RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData), - 0, RFW_FWADDR_NOREF_FLAG); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: RGXSetFirmwareAddress for RGXFWIF_FWMEMCONTEXT failed", - __func__)); - DevmemReleaseCpuVirtAddr(psFreeList->psFWFreelistMemDesc); - goto FWFreeListCpuMap; - } -#else - PVR_UNREFERENCED_PARAMETER(hMemCtxPrivData); -#endif - } - - PVR_DPF((PVR_DBG_MESSAGE, - "Freelist %p created: Max pages 0x%08x, Init pages 0x%08x, " - "Max FL base address 0x%016" IMG_UINT64_FMTSPECx ", " - "Init FL base address 0x%016" IMG_UINT64_FMTSPECx, - psFreeList, - ui32MaxFLPages, - ui32InitFLPages, - sFreeListDevVAddr.uiAddr, - psFWFreeList->ui64CurrentDevVAddr)); -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump FW FreeList"); - DevmemPDumpLoadMem(psFreeList->psFWFreelistMemDesc, 0, sizeof(*psFWFreeList), PDUMP_FLAGS_CONTINUOUS); - - /* - * Separate dump of the Freelist's number of Pages and stack pointer. - * This allows to easily modify the PB size in the out2.txt files. - */ - PDUMPCOMMENT(psDeviceNode, "FreeList TotalPages"); - DevmemPDumpLoadMemValue32(psFreeList->psFWFreelistMemDesc, - offsetof(RGXFWIF_FREELIST, ui32CurrentPages), - psFWFreeList->ui32CurrentPages, - PDUMP_FLAGS_CONTINUOUS); - PDUMPCOMMENT(psDeviceNode, "FreeList StackPointer"); - DevmemPDumpLoadMemValue32(psFreeList->psFWFreelistMemDesc, - offsetof(RGXFWIF_FREELIST, ui32CurrentStackTop), - psFWFreeList->ui32CurrentStackTop, - PDUMP_FLAGS_CONTINUOUS); -#endif - - DevmemReleaseCpuVirtAddr(psFreeList->psFWFreelistMemDesc); - - - /* Add initial PB block */ - eError = RGXGrowFreeList(psFreeList, - ui32InitFLPages, - &psFreeList->sMemoryBlockInitHead); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to allocate initial memory block for free list 0x%016" IMG_UINT64_FMTSPECx " (%d)", - __func__, - sFreeListDevVAddr.uiAddr, - eError)); - goto FWFreeListCpuMap; - } -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - /* Update Stats */ - PVRSRVStatsUpdateFreelistStats(1, /* Add 1 to the appropriate counter (Requests by App)*/ - 0, - psFreeList->ui32InitFLPages, - psFreeList->ui32NumHighPages, - psFreeList->ownerPid); - -#endif - - /* return values */ - *ppsFreeList = psFreeList; - - return PVRSRV_OK; - - /* Error handling */ - -FWFreeListCpuMap: - /* Remove freelists from list */ - OSLockAcquire(psDevInfo->hLockFreeList); - dllist_remove_node(&psFreeList->sNode); - OSLockRelease(psDevInfo->hLockFreeList); - RGXUnsetFirmwareAddress(psFWFreelistMemDesc); - -ErrorSetFwAddr: - DevmemFwUnmapAndFree(psDevInfo, psFWFreelistMemDesc); - PMRUnrefPMR(psFreeList->psFreeListPMR); - -FWFreeListAlloc: - OSFreeMem(psFreeList); - -ErrorAllocHost: - DevmemIntReservationRelease(psFreeListReservation); - -ErrorReservationAcquire: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -/* - RGXDestroyFreeList - */ -PVRSRV_ERROR RGXDestroyFreeList(RGX_FREELIST *psFreeList) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32RefCount; - - PVR_ASSERT(psFreeList); - - OSLockAcquire(psFreeList->psDevInfo->hLockFreeList); - ui32RefCount = psFreeList->ui32RefCount; - OSLockRelease(psFreeList->psDevInfo->hLockFreeList); - - if (ui32RefCount != 0) - { - /* Freelist still busy */ - return PVRSRV_ERROR_RETRY; - } - - /* Freelist is not in use => start firmware cleanup */ - eError = RGXFWRequestFreeListCleanUp(psFreeList->psDevInfo, - psFreeList->sFreeListFWDevVAddr); - if (eError != PVRSRV_OK) - { - /* Can happen if the firmware took too long to handle the cleanup request, - * or if SLC-flushes didn't went through (due to some GPU lockup) */ - return eError; - } - - /* Remove FreeList from linked list before we destroy it... */ - OSLockAcquire(psFreeList->psDevInfo->hLockFreeList); - dllist_remove_node(&psFreeList->sNode); -#if !defined(SUPPORT_SHADOW_FREELISTS) - /* Confirm all HWRTData nodes are freed before releasing freelist */ - PVR_ASSERT(dllist_is_empty(&psFreeList->sNodeHWRTDataHead)); -#endif - OSLockRelease(psFreeList->psDevInfo->hLockFreeList); - - if (psFreeList->bCheckFreelist) - { - RGXFWIF_FREELIST *psFWFreeList; - IMG_UINT64 ui32CurrentStackTop; - IMG_UINT64 ui64CheckSum; - - /* Get the current stack pointer for this free list */ - DevmemAcquireCpuVirtAddr(psFreeList->psFWFreelistMemDesc, (void **)&psFWFreeList); - ui32CurrentStackTop = psFWFreeList->ui32CurrentStackTop; - DevmemReleaseCpuVirtAddr(psFreeList->psFWFreelistMemDesc); - - if (ui32CurrentStackTop == psFreeList->ui32CurrentFLPages-1) - { - /* Do consistency tests (as the list is fully populated) */ - _CheckFreelist(psFreeList, psFreeList->ui32CurrentFLPages + psFreeList->ui32ReadyFLPages, psFreeList->ui64FreelistChecksum, &ui64CheckSum); - } - else - { - /* Check for duplicate pages, but don't check the checksum as the list is not fully populated */ - _CheckFreelist(psFreeList, ui32CurrentStackTop+1, 0, &ui64CheckSum); - } - } - - /* Destroy FW structures */ - RGXUnsetFirmwareAddress(psFreeList->psFWFreelistMemDesc); - DevmemFwUnmapAndFree(psFreeList->psDevInfo, psFreeList->psFWFreelistMemDesc); - - /* Remove grow shrink blocks */ - while (!dllist_is_empty(&psFreeList->sMemoryBlockHead)) - { - eError = RGXShrinkFreeList(&psFreeList->sMemoryBlockHead, psFreeList); - PVR_ASSERT(eError == PVRSRV_OK); - } - - /* Remove initial PB block */ - eError = RGXShrinkFreeList(&psFreeList->sMemoryBlockInitHead, psFreeList); - PVR_ASSERT(eError == PVRSRV_OK); - - /* consistency checks */ - PVR_ASSERT(dllist_is_empty(&psFreeList->sMemoryBlockInitHead)); - PVR_ASSERT(psFreeList->ui32CurrentFLPages == 0); - - /* Remove reference from the PMR and reservation resources */ - PMRUnrefPMR(psFreeList->psFreeListPMR); - DevmemIntReservationRelease(psFreeList->psFreeListReservation); - - /* free Freelist */ - OSFreeMem(psFreeList); - - return eError; -} - - -/* - RGXCreateZSBuffer - */ -PVRSRV_ERROR RGXCreateZSBufferKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - RGX_ZSBUFFER_DATA **ppsZSBuffer) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psReservation); - PVR_UNREFERENCED_PARAMETER(psPMR); - PVR_UNREFERENCED_PARAMETER(uiMapFlags); - PVR_UNREFERENCED_PARAMETER(ppsZSBuffer); - - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -PVRSRV_ERROR RGXCreateZSBufferKM2(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_RESERVATION2 *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - RGX_ZSBUFFER_DATA **ppsZSBuffer) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_PRBUFFER *psFWZSBuffer; - RGX_ZSBUFFER_DATA *psZSBuffer; - DEVMEM_MEMDESC *psFWZSBufferMemDesc; - IMG_BOOL bOnDemand = PVRSRV_CHECK_ON_DEMAND(uiMapFlags) ? IMG_TRUE : IMG_FALSE; - - /* Allocate host data structure */ - psZSBuffer = OSAllocZMem(sizeof(*psZSBuffer)); - if (psZSBuffer == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate cleanup data structure for ZS-Buffer", - __func__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorAllocCleanup; - } - - /* Populate Host data */ - psZSBuffer->psDevInfo = psDevInfo; - psZSBuffer->psReservation = psReservation; - - /* Obtain reference to reservation object */ - if (!DevmemIntReservationAcquire(psZSBuffer->psReservation)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to acquire reservation for ZS-Buffer", - __func__)); - eError = PVRSRV_ERROR_REFCOUNT_OVERFLOW; - goto ErrorReservationAcquire; - } - - psZSBuffer->psPMR = psPMR; - /* Obtain reference to PMR */ - PMRRefPMR(psZSBuffer->psPMR); - - psZSBuffer->ui32RefCount = 0; - psZSBuffer->bOnDemand = bOnDemand; - if (bOnDemand) - { - /* psZSBuffer->ui32ZSBufferID set below with lock... */ - OSLockAcquire(psDevInfo->hLockZSBuffer); - psZSBuffer->ui32ZSBufferID = psDevInfo->ui32ZSBufferCurrID++; - dllist_add_to_tail(&psDevInfo->sZSBufferHead, &psZSBuffer->sNode); - OSLockRelease(psDevInfo->hLockZSBuffer); - } - - /* Allocate firmware memory for ZS-Buffer. */ - PDUMPCOMMENT(psDeviceNode, "Allocate firmware ZS-Buffer data structure"); - eError = DevmemFwAllocate(psDevInfo, - sizeof(*psFWZSBuffer), - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | - PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) | - PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | - PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(FW_MAIN), - "FwZSBuffer", - &psFWZSBufferMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware ZS-Buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto ErrorAllocFWZSBuffer; - } - psZSBuffer->psFWZSBufferMemDesc = psFWZSBufferMemDesc; - - /* Temporarily map the firmware render context to the kernel. */ - eError = DevmemAcquireCpuVirtAddr(psFWZSBufferMemDesc, - (void **)&psFWZSBuffer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware ZS-Buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto ErrorAcquireFWZSBuffer; - } - - /* Populate FW ZS-Buffer data structure */ - psFWZSBuffer->bOnDemand = bOnDemand; - psFWZSBuffer->eState = (bOnDemand) ? RGXFWIF_PRBUFFER_UNBACKED : RGXFWIF_PRBUFFER_BACKED; - psFWZSBuffer->ui32BufferID = psZSBuffer->ui32ZSBufferID; - - /* Get firmware address of ZS-Buffer. */ - eError = RGXSetFirmwareAddress(&psZSBuffer->sZSBufferFWDevVAddr, psFWZSBufferMemDesc, 0, RFW_FWADDR_FLAG_NONE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetFirmwareAddress", ErrorSetFwAddr); - - /* Dump the ZS-Buffer and the memory content */ -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump firmware ZS-Buffer"); - DevmemPDumpLoadMem(psFWZSBufferMemDesc, 0, sizeof(*psFWZSBuffer), PDUMP_FLAGS_CONTINUOUS); -#endif - - /* Release address acquired above. */ - DevmemReleaseCpuVirtAddr(psFWZSBufferMemDesc); - - - /* define return value */ - *ppsZSBuffer = psZSBuffer; - - PVR_DPF((PVR_DBG_MESSAGE, "ZS-Buffer [%p] created (%s)", - psZSBuffer, - (bOnDemand) ? "On-Demand": "Up-front")); - - psZSBuffer->owner=OSGetCurrentClientProcessIDKM(); - - return PVRSRV_OK; - - /* error handling */ - -ErrorSetFwAddr: - DevmemReleaseCpuVirtAddr(psFWZSBufferMemDesc); -ErrorAcquireFWZSBuffer: - DevmemFwUnmapAndFree(psDevInfo, psFWZSBufferMemDesc); - -ErrorAllocFWZSBuffer: - PMRUnrefPMR(psZSBuffer->psPMR); - DevmemIntReservationRelease(psZSBuffer->psReservation); -ErrorReservationAcquire: - OSFreeMem(psZSBuffer); - -ErrorAllocCleanup: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -/* - RGXDestroyZSBuffer - */ -PVRSRV_ERROR RGXDestroyZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer) -{ - POS_LOCK hLockZSBuffer; - PVRSRV_ERROR eError; - - PVR_ASSERT(psZSBuffer); - hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer; - - if (psZSBuffer->ui32RefCount != 0) - { - PVR_ASSERT(IMG_FALSE); - /* ZS-Buffer is still referenced (by population object) */ - return PVRSRV_ERROR_RETRY; - } - - /* Request ZS Buffer cleanup */ - eError = RGXFWRequestZSBufferCleanUp(psZSBuffer->psDevInfo, - psZSBuffer->sZSBufferFWDevVAddr); - if (eError == PVRSRV_OK) - { - /* Free the firmware render context. */ - RGXUnsetFirmwareAddress(psZSBuffer->psFWZSBufferMemDesc); - DevmemFwUnmapAndFree(psZSBuffer->psDevInfo, psZSBuffer->psFWZSBufferMemDesc); - - /* Remove Deferred Allocation from list */ - if (psZSBuffer->bOnDemand) - { - OSLockAcquire(hLockZSBuffer); - PVR_ASSERT(dllist_node_is_in_list(&psZSBuffer->sNode)); - dllist_remove_node(&psZSBuffer->sNode); - OSLockRelease(hLockZSBuffer); - } - - PVR_DPF((PVR_DBG_MESSAGE, "ZS-Buffer [%p] destroyed", psZSBuffer)); - - /* Release reference to reservation object and the PMR */ - PMRUnrefPMR(psZSBuffer->psPMR); - DevmemIntReservationRelease(psZSBuffer->psReservation); - - /* Free ZS-Buffer host data structure */ - OSFreeMem(psZSBuffer); - - } - - return eError; -} - -PVRSRV_ERROR -RGXBackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer) -{ - POS_LOCK hLockZSBuffer; - PVRSRV_ERROR eError; - - if (!psZSBuffer) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (!psZSBuffer->bOnDemand) - { - /* Only deferred allocations can be populated */ - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_DPF((PVR_DBG_MESSAGE, - "ZS Buffer [%p, ID=0x%08x]: Physical backing requested", - psZSBuffer, - psZSBuffer->ui32ZSBufferID)); - hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer; - - OSLockAcquire(hLockZSBuffer); - - if (psZSBuffer->ui32RefCount == 0) - { - if (psZSBuffer->bOnDemand) - { - IMG_HANDLE hDevmemHeap; - - /* Get Heap */ - eError = DevmemServerGetHeapHandle(psZSBuffer->psReservation, &hDevmemHeap); - if (unlikely(hDevmemHeap == (IMG_HANDLE)NULL)) - { - OSLockRelease(hLockZSBuffer); - return PVRSRV_ERROR_INVALID_HEAP; - } - - eError = DevmemIntMapPMR2(hDevmemHeap, - psZSBuffer->psReservation, - psZSBuffer->psPMR); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Unable populate ZS Buffer [%p, ID=0x%08x] (%s)", - psZSBuffer, - psZSBuffer->ui32ZSBufferID, - PVRSRVGetErrorString(eError))); - OSLockRelease(hLockZSBuffer); - return eError; - - } - PVR_DPF((PVR_DBG_MESSAGE, "ZS Buffer [%p, ID=0x%08x]: Physical backing acquired", - psZSBuffer, - psZSBuffer->ui32ZSBufferID)); - } - } - - /* Increase refcount*/ - psZSBuffer->ui32RefCount++; - - OSLockRelease(hLockZSBuffer); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -RGXPopulateZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_POPULATION **ppsPopulation) -{ - RGX_POPULATION *psPopulation; - PVRSRV_ERROR eError; - - psZSBuffer->ui32NumReqByApp++; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRVStatsUpdateZSBufferStats(1, 0, psZSBuffer->owner); -#endif - - /* Do the backing */ - eError = RGXBackingZSBuffer(psZSBuffer); - if (eError != PVRSRV_OK) - { - goto OnErrorBacking; - } - - /* Create the handle to the backing */ - psPopulation = OSAllocMem(sizeof(*psPopulation)); - if (psPopulation == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto OnErrorAlloc; - } - - psPopulation->psZSBuffer = psZSBuffer; - - /* return value */ - *ppsPopulation = psPopulation; - - return PVRSRV_OK; - -OnErrorAlloc: - RGXUnbackingZSBuffer(psZSBuffer); - -OnErrorBacking: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR -RGXUnbackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer) -{ - POS_LOCK hLockZSBuffer; - PVRSRV_ERROR eError; - - if (!psZSBuffer) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_ASSERT(psZSBuffer->ui32RefCount); - - PVR_DPF((PVR_DBG_MESSAGE, - "ZS Buffer [%p, ID=0x%08x]: Physical backing removal requested", - psZSBuffer, - psZSBuffer->ui32ZSBufferID)); - - hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer; - - OSLockAcquire(hLockZSBuffer); - - if (psZSBuffer->bOnDemand) - { - if (psZSBuffer->ui32RefCount == 1) - { - eError = DevmemIntUnmapPMR2(psZSBuffer->psReservation); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Unable to unpopulate ZS Buffer [%p, ID=0x%08x] (%s)", - psZSBuffer, - psZSBuffer->ui32ZSBufferID, - PVRSRVGetErrorString(eError))); - OSLockRelease(hLockZSBuffer); - return eError; - } - - PVR_DPF((PVR_DBG_MESSAGE, "ZS Buffer [%p, ID=0x%08x]: Physical backing removed", - psZSBuffer, - psZSBuffer->ui32ZSBufferID)); - } - } - - /* Decrease refcount*/ - psZSBuffer->ui32RefCount--; - - OSLockRelease(hLockZSBuffer); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -RGXUnpopulateZSBufferKM(RGX_POPULATION *psPopulation) -{ - PVRSRV_ERROR eError; - - if (!psPopulation) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = RGXUnbackingZSBuffer(psPopulation->psZSBuffer); - if (eError != PVRSRV_OK) - { - return eError; - } - - OSFreeMem(psPopulation); - - return PVRSRV_OK; -} - -static RGX_ZSBUFFER_DATA *FindZSBuffer(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32ZSBufferID) -{ - DLLIST_NODE *psNode, *psNext; - RGX_ZSBUFFER_DATA *psZSBuffer = NULL; - - OSLockAcquire(psDevInfo->hLockZSBuffer); - - dllist_foreach_node(&psDevInfo->sZSBufferHead, psNode, psNext) - { - RGX_ZSBUFFER_DATA *psThisZSBuffer = IMG_CONTAINER_OF(psNode, RGX_ZSBUFFER_DATA, sNode); - - if (psThisZSBuffer->ui32ZSBufferID == ui32ZSBufferID) - { - psZSBuffer = psThisZSBuffer; - break; - } - } - - OSLockRelease(psDevInfo->hLockZSBuffer); - return psZSBuffer; -} - -void RGXProcessRequestZSBufferBacking(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32ZSBufferID) -{ - RGX_ZSBUFFER_DATA *psZSBuffer; - RGXFWIF_KCCB_CMD sTACCBCmd; - PVRSRV_ERROR eError; - - PVR_ASSERT(psDevInfo); - - /* scan all deferred allocations */ - psZSBuffer = FindZSBuffer(psDevInfo, ui32ZSBufferID); - - if (psZSBuffer) - { - IMG_BOOL bBackingDone = IMG_TRUE; - - /* Populate ZLS */ - eError = RGXBackingZSBuffer(psZSBuffer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "Populating ZS-Buffer (ID = 0x%08x) failed (%s)", - ui32ZSBufferID, - PVRSRVGetErrorString(eError))); - bBackingDone = IMG_FALSE; - } - - /* send confirmation */ - sTACCBCmd.eCmdType = RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE; - sTACCBCmd.uCmdData.sZSBufferBackingData.sZSBufferFWDevVAddr.ui32Addr = psZSBuffer->sZSBufferFWDevVAddr.ui32Addr; - sTACCBCmd.uCmdData.sZSBufferBackingData.bDone = bBackingDone; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GEOM, - &sTACCBCmd, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Kernel CCB should never fill up, as the FW is processing them right away */ - PVR_ASSERT(eError == PVRSRV_OK); - - psZSBuffer->ui32NumReqByFW++; - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - PVRSRVStatsUpdateZSBufferStats(0, 1, psZSBuffer->owner); -#endif - - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "ZS Buffer Lookup for ZS Buffer ID 0x%08x failed (Populate)", - ui32ZSBufferID)); - } -} - -void RGXProcessRequestZSBufferUnbacking(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32ZSBufferID) -{ - RGX_ZSBUFFER_DATA *psZSBuffer; - RGXFWIF_KCCB_CMD sTACCBCmd; - PVRSRV_ERROR eError; - - PVR_ASSERT(psDevInfo); - - /* scan all deferred allocations */ - psZSBuffer = FindZSBuffer(psDevInfo, ui32ZSBufferID); - - if (psZSBuffer) - { - /* Unpopulate ZLS */ - eError = RGXUnbackingZSBuffer(psZSBuffer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "UnPopulating ZS-Buffer (ID = 0x%08x) failed (%s)", - ui32ZSBufferID, - PVRSRVGetErrorString(eError))); - PVR_ASSERT(IMG_FALSE); - } - - /* send confirmation */ - sTACCBCmd.eCmdType = RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE; - sTACCBCmd.uCmdData.sZSBufferBackingData.sZSBufferFWDevVAddr.ui32Addr = psZSBuffer->sZSBufferFWDevVAddr.ui32Addr; - sTACCBCmd.uCmdData.sZSBufferBackingData.bDone = IMG_TRUE; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_GEOM, - &sTACCBCmd, - PDUMP_FLAGS_NONE); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - /* Kernel CCB should never fill up, as the FW is processing them right away */ - PVR_ASSERT(eError == PVRSRV_OK); - - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "ZS Buffer Lookup for ZS Buffer ID 0x%08x failed (UnPopulate)", - ui32ZSBufferID)); - } -} - -static -PVRSRV_ERROR _CreateTAContext(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - IMG_DEV_VIRTADDR sVDMCallStackAddr, - IMG_UINT32 ui32CallStackDepth, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32MaxDeadlineMS, - IMG_UINT64 ui64RobustnessAddress, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_RC_TA_DATA *psTAData, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_TACTX_STATE *psContextState; - IMG_UINT32 uiCoreIdx; - PVRSRV_ERROR eError; - /* - Allocate device memory for the firmware GPU context suspend state. - Note: the FW reads/writes the state to memory by accessing the GPU register interface. - */ - PDUMPCOMMENT(psDeviceNode, "Allocate RGX firmware TA context suspend state"); - - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_TACTX_STATE), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwTAContextState", - &psTAData->psContextStateMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU context suspend state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_tacontextsuspendalloc; - } - - eError = DevmemAcquireCpuVirtAddr(psTAData->psContextStateMemDesc, - (void **)&psContextState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware render context state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_suspendcpuvirtacquire; - } - - for (uiCoreIdx = 0; uiCoreIdx < RGX_NUM_GEOM_CORES; uiCoreIdx++) - { - psContextState->asGeomCore[uiCoreIdx].uTAReg_VDM_CALL_STACK_POINTER_Init = - sVDMCallStackAddr.uiAddr + (uiCoreIdx * ui32CallStackDepth * sizeof(IMG_UINT64)); - } - - DevmemReleaseCpuVirtAddr(psTAData->psContextStateMemDesc); - - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_TA, - RGXFWIF_DM_GEOM, - NULL, - psAllocatedMemDesc, - ui32AllocatedOffset, - psFWMemContextMemDesc, - psTAData->psContextStateMemDesc, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_TA_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_TA_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - ui32MaxDeadlineMS, - ui64RobustnessAddress, - psInfo, - &psTAData->psServerCommonContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to init TA fw common context (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_tacommoncontext; - } - - /* - * Dump the FW 3D context suspend state buffer - */ -#if defined(PDUMP) - PDUMPCOMMENT(psDeviceNode, "Dump the TA context suspend state buffer"); - DevmemPDumpLoadMem(psTAData->psContextStateMemDesc, - 0, - sizeof(RGXFWIF_TACTX_STATE), - PDUMP_FLAGS_CONTINUOUS); -#endif - - psTAData->ui32Priority = ui32Priority; - return PVRSRV_OK; - -fail_tacommoncontext: -fail_suspendcpuvirtacquire: - DevmemFwUnmapAndFree(psDevInfo, psTAData->psContextStateMemDesc); -fail_tacontextsuspendalloc: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -static -PVRSRV_ERROR _Create3DContext(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32MaxDeadlineMS, - IMG_UINT64 ui64RobustnessAddress, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_RC_3D_DATA *ps3DData, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - IMG_UINT uiNumISPStoreRegs; - IMG_UINT ui3DRegISPStateStoreSize = 0; - - /* - Allocate device memory for the firmware GPU context suspend state. - Note: the FW reads/writes the state to memory by accessing the GPU register interface. - */ - PDUMPCOMMENT(psDeviceNode, "Allocate RGX firmware 3D context suspend state"); - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, XE_MEMORY_HIERARCHY)) - { - uiNumISPStoreRegs = psDeviceNode->pfnGetDeviceFeatureValue(psDeviceNode, - RGX_FEATURE_NUM_RASTER_PIPES_IDX); - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, GPU_MULTICORE_SUPPORT)) - { - uiNumISPStoreRegs *= (1U + psDeviceNode->pfnGetDeviceFeatureValue(psDeviceNode, - RGX_FEATURE_XPU_MAX_SLAVES_IDX)); - } - } - else - { - uiNumISPStoreRegs = psDeviceNode->pfnGetDeviceFeatureValue(psDeviceNode, - RGX_FEATURE_NUM_ISP_IPP_PIPES_IDX); - } - - /* Size of the CS buffer */ - /* Calculate the size of the 3DCTX ISP state */ - ui3DRegISPStateStoreSize = sizeof(RGXFWIF_3DCTX_STATE) + - uiNumISPStoreRegs * sizeof(((RGXFWIF_3DCTX_STATE *)0)->au3DReg_ISP_STORE[0]); - - eError = DevmemFwAllocate(psDevInfo, - ui3DRegISPStateStoreSize, - RGX_FWCOMCTX_ALLOCFLAGS, - "Fw3DContextState", - &ps3DData->psContextStateMemDesc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU context suspend state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_3dcontextsuspendalloc; - } - - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_3D, - RGXFWIF_DM_3D, - NULL, - psAllocatedMemDesc, - ui32AllocatedOffset, - psFWMemContextMemDesc, - ps3DData->psContextStateMemDesc, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_3D_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_3D_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - ui32MaxDeadlineMS, - ui64RobustnessAddress, - psInfo, - &ps3DData->psServerCommonContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to init 3D fw common context (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_3dcommoncontext; - } - - /* - * Dump the FW 3D context suspend state buffer - */ - PDUMPCOMMENT(psDeviceNode, "Dump the 3D context suspend state buffer"); - DevmemPDumpLoadMem(ps3DData->psContextStateMemDesc, - 0, - sizeof(RGXFWIF_3DCTX_STATE), - PDUMP_FLAGS_CONTINUOUS); - - ps3DData->ui32Priority = ui32Priority; - return PVRSRV_OK; - -fail_3dcommoncontext: - DevmemFwUnmapAndFree(psDevInfo, ps3DData->psContextStateMemDesc); -fail_3dcontextsuspendalloc: - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - - -/* - * PVRSRVRGXCreateRenderContextKM - */ -PVRSRV_ERROR PVRSRVRGXCreateRenderContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_DEV_VIRTADDR sVDMCallStackAddr, - IMG_UINT32 ui32CallStackDepth, - IMG_UINT32 ui32FrameworkRegisterSize, - IMG_PBYTE pabyFrameworkRegisters, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32StaticRenderContextStateSize, - IMG_PBYTE pStaticRenderContextState, - IMG_UINT32 ui32PackedCCBSizeU8888, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - IMG_UINT32 ui32MaxTADeadlineMS, - IMG_UINT32 ui32Max3DDeadlineMS, - RGX_SERVER_RENDER_CONTEXT **ppsRenderContext) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_SERVER_RENDER_CONTEXT *psRenderContext; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - RGX_COMMON_CONTEXT_INFO sInfo = {NULL}; - RGXFWIF_FWRENDERCONTEXT *psFWRenderContext; - - *ppsRenderContext = NULL; - - if (ui32StaticRenderContextStateSize > RGXFWIF_STATIC_RENDERCONTEXT_SIZE) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psRenderContext = OSAllocZMem(sizeof(*psRenderContext)); - if (psRenderContext == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eError = OSLockCreate(&psRenderContext->hLock); - - if (eError != PVRSRV_OK) - { - goto fail_lock; - } - - psRenderContext->psDeviceNode = psDeviceNode; - - /* - Create the FW render context, this has the TA and 3D FW common - contexts embedded within it - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_FWRENDERCONTEXT), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwRenderContext", - &psRenderContext->psFWRenderContextMemDesc); - if (eError != PVRSRV_OK) - { - goto fail_fwrendercontext; - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WorkEstInitTA3D(psDevInfo, &psRenderContext->sWorkEstData); -#endif - - if (ui32FrameworkRegisterSize) - { - /* - * Create the FW framework buffer - */ - eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, - &psRenderContext->psFWFrameworkMemDesc, - ui32FrameworkRegisterSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU framework state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcreate; - } - - /* Copy the Framework client data into the framework buffer */ - eError = PVRSRVRGXFrameworkCopyCommand(psDeviceNode, - psRenderContext->psFWFrameworkMemDesc, - pabyFrameworkRegisters, - ui32FrameworkRegisterSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to populate the framework buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcopy; - } - - sInfo.psFWFrameworkMemDesc = psRenderContext->psFWFrameworkMemDesc; - } - - eError = _Create3DContext(psConnection, - psDeviceNode, - psRenderContext->psFWRenderContextMemDesc, - offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext), - psFWMemContextMemDesc, - ui32Priority, - ui32Max3DDeadlineMS, - ui64RobustnessAddress, - &sInfo, - &psRenderContext->s3DData, - U32toU8_Unpack3(ui32PackedCCBSizeU8888), - U32toU8_Unpack4(ui32PackedCCBSizeU8888), - ui32ContextFlags); - if (eError != PVRSRV_OK) - { - goto fail_3dcontext; - } - - eError = _CreateTAContext(psConnection, - psDeviceNode, - psRenderContext->psFWRenderContextMemDesc, - offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext), - psFWMemContextMemDesc, - sVDMCallStackAddr, - ui32CallStackDepth, - ui32Priority, - ui32MaxTADeadlineMS, - ui64RobustnessAddress, - &sInfo, - &psRenderContext->sTAData, - U32toU8_Unpack1(ui32PackedCCBSizeU8888), - U32toU8_Unpack2(ui32PackedCCBSizeU8888), - ui32ContextFlags); - if (eError != PVRSRV_OK) - { - goto fail_tacontext; - } - - eError = DevmemAcquireCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc, - (void **)&psFWRenderContext); - if (eError != PVRSRV_OK) - { - goto fail_acquire_cpu_mapping; - } - - /* Copy the static render context data */ - OSDeviceMemCopy(&psFWRenderContext->sStaticRenderContextState, pStaticRenderContextState, ui32StaticRenderContextStateSize); - DevmemPDumpLoadMem(psRenderContext->psFWRenderContextMemDesc, 0, sizeof(RGXFWIF_FWRENDERCONTEXT), PDUMP_FLAGS_CONTINUOUS); - DevmemReleaseCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc); - -#if defined(SUPPORT_BUFFER_SYNC) - psRenderContext->psBufferSyncContext = - pvr_buffer_sync_context_create(psDeviceNode->psDevConfig->pvOSDevice, - "rogue-ta3d"); - if (IS_ERR(psRenderContext->psBufferSyncContext)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create buffer_sync context (err=%ld)", - __func__, PTR_ERR(psRenderContext->psBufferSyncContext))); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_buffer_sync_context_create; - } -#endif - - SyncAddrListInit(&psRenderContext->sSyncAddrListTAFence); - SyncAddrListInit(&psRenderContext->sSyncAddrListTAUpdate); - SyncAddrListInit(&psRenderContext->sSyncAddrList3DFence); - SyncAddrListInit(&psRenderContext->sSyncAddrList3DUpdate); - - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock); - dllist_add_to_tail(&(psDevInfo->sRenderCtxtListHead), &(psRenderContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock); - } - - *ppsRenderContext = psRenderContext; - return PVRSRV_OK; - -#if defined(SUPPORT_BUFFER_SYNC) -fail_buffer_sync_context_create: -#endif -fail_acquire_cpu_mapping: - _DestroyTAContext(&psRenderContext->sTAData, - psDeviceNode); -fail_tacontext: - _Destroy3DContext(&psRenderContext->s3DData, - psRenderContext->psDeviceNode); -fail_3dcontext: -fail_frameworkcopy: - if (psRenderContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psRenderContext->psFWFrameworkMemDesc); - } -fail_frameworkcreate: - DevmemFwUnmapAndFree(psDevInfo, psRenderContext->psFWRenderContextMemDesc); -fail_fwrendercontext: - OSLockDestroy(psRenderContext->hLock); -fail_lock: - OSFreeMem(psRenderContext); - PVR_ASSERT(eError != PVRSRV_OK); - - return eError; -} - -/* - * PVRSRVRGXDestroyRenderContextKM - */ -PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psRenderContext->psDeviceNode->pvDevice; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_FWRENDERCONTEXT *psFWRenderContext; - IMG_UINT32 ui32WorkEstCCBSubmitted; -#endif - - /* remove node from list before calling destroy - as destroy, if successful - * will invalidate the node - * must be re-added if destroy fails - */ - OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock); - dllist_remove_node(&(psRenderContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock); - -#if defined(SUPPORT_BUFFER_SYNC) - /* Check psBufferSyncContext has not been destroyed already (by a previous - * call to this function which then later returned PVRSRV_ERROR_RETRY) - */ - if (psRenderContext->psBufferSyncContext != NULL) - { - pvr_buffer_sync_context_destroy(psRenderContext->psBufferSyncContext); - psRenderContext->psBufferSyncContext = NULL; - } -#endif - - /* Cleanup the TA if we haven't already */ - if ((psRenderContext->ui32CleanupStatus & RC_CLEANUP_TA_COMPLETE) == 0) - { - eError = _DestroyTAContext(&psRenderContext->sTAData, - psRenderContext->psDeviceNode); - if (eError == PVRSRV_OK) - { - psRenderContext->ui32CleanupStatus |= RC_CLEANUP_TA_COMPLETE; - } - else - { - goto e0; - } - } - - /* Cleanup the 3D if we haven't already */ - if ((psRenderContext->ui32CleanupStatus & RC_CLEANUP_3D_COMPLETE) == 0) - { - eError = _Destroy3DContext(&psRenderContext->s3DData, - psRenderContext->psDeviceNode); - if (eError == PVRSRV_OK) - { - psRenderContext->ui32CleanupStatus |= RC_CLEANUP_3D_COMPLETE; - } - else - { - goto e0; - } - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - eError = DevmemAcquireCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc, - (void **)&psFWRenderContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware render context (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto e0; - } - - ui32WorkEstCCBSubmitted = psFWRenderContext->ui32WorkEstCCBSubmitted; - - DevmemReleaseCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc); - - /* Check if all of the workload estimation CCB commands for this workload are read */ - if (ui32WorkEstCCBSubmitted != psRenderContext->sWorkEstData.ui32WorkEstCCBReceived) - { - - PVR_DPF((PVR_DBG_WARNING, - "%s: WorkEst # cmds submitted (%u) and received (%u) mismatch", - __func__, ui32WorkEstCCBSubmitted, - psRenderContext->sWorkEstData.ui32WorkEstCCBReceived)); - - eError = PVRSRV_ERROR_RETRY; - goto e0; - } -#endif - - /* - Only if both TA and 3D contexts have been cleaned up can we - free the shared resources - */ - if (psRenderContext->ui32CleanupStatus == (RC_CLEANUP_3D_COMPLETE | RC_CLEANUP_TA_COMPLETE)) - { - if (psRenderContext->psFWFrameworkMemDesc) - { - /* Free the framework buffer */ - DevmemFwUnmapAndFree(psDevInfo, psRenderContext->psFWFrameworkMemDesc); - } - - /* Free the firmware render context */ - DevmemFwUnmapAndFree(psDevInfo, psRenderContext->psFWRenderContextMemDesc); - - SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAFence); - SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAUpdate); - SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DFence); - SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DUpdate); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WorkEstDeInitTA3D(psDevInfo, &psRenderContext->sWorkEstData); -#endif - - OSLockDestroy(psRenderContext->hLock); - - OSFreeMem(psRenderContext); - } - - return PVRSRV_OK; - -e0: - OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock); - dllist_add_to_tail(&(psDevInfo->sRenderCtxtListHead), &(psRenderContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock); - return eError; -} - - - -#if (ENABLE_TA3D_UFO_DUMP == 1) -static void DumpUfoList(IMG_UINT32 ui32ClientTAFenceCount, - IMG_UINT32 ui32ClientTAUpdateCount, - IMG_UINT32 ui32Client3DFenceCount, - IMG_UINT32 ui32Client3DUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientTAFenceUFOAddress, - IMG_UINT32 *paui32ClientTAFenceValue, - PRGXFWIF_UFO_ADDR *pauiClientTAUpdateUFOAddress, - IMG_UINT32 *paui32ClientTAUpdateValue, - PRGXFWIF_UFO_ADDR *pauiClient3DFenceUFOAddress, - IMG_UINT32 *paui32Client3DFenceValue, - PRGXFWIF_UFO_ADDR *pauiClient3DUpdateUFOAddress, - IMG_UINT32 *paui32Client3DUpdateValue) -{ - IMG_UINT32 i; - - PVR_DPF((PVR_DBG_ERROR, "%s: ~~~ After populating sync prims ~~~", - __func__)); - - /* Dump Fence syncs, Update syncs and PR Update syncs */ - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TA fence syncs:", - __func__, ui32ClientTAFenceCount)); - for (i = 0; i < ui32ClientTAFenceCount; i++) - { - if (BITMASK_HAS(pauiClientTAFenceUFOAddress->ui32Addr, 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x," - " CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, i + 1, ui32ClientTAFenceCount, - (void *) pauiClientTAFenceUFOAddress, - pauiClientTAFenceUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, CheckValue=%d(0x%x)", - __func__, i + 1, ui32ClientTAFenceCount, - (void *) pauiClientTAFenceUFOAddress, - pauiClientTAFenceUFOAddress->ui32Addr, - *paui32ClientTAFenceValue, - *paui32ClientTAFenceValue)); - paui32ClientTAFenceValue++; - } - pauiClientTAFenceUFOAddress++; - } - - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TA update syncs:", - __func__, ui32ClientTAUpdateCount)); - for (i = 0; i < ui32ClientTAUpdateCount; i++) - { - if (BITMASK_HAS(pauiClientTAUpdateUFOAddress->ui32Addr, 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x," - " UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, i + 1, ui32ClientTAUpdateCount, - (void *) pauiClientTAUpdateUFOAddress, - pauiClientTAUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d(0x%x)", - __func__, i + 1, ui32ClientTAUpdateCount, - (void *) pauiClientTAUpdateUFOAddress, - pauiClientTAUpdateUFOAddress->ui32Addr, - *paui32ClientTAUpdateValue, - *paui32ClientTAUpdateValue)); - paui32ClientTAUpdateValue++; - } - pauiClientTAUpdateUFOAddress++; - } - - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d 3D fence syncs:", - __func__, ui32Client3DFenceCount)); - for (i = 0; i < ui32Client3DFenceCount; i++) - { - if (BITMASK_HAS(pauiClient3DFenceUFOAddress->ui32Addr, 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x," - " CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, i + 1, ui32Client3DFenceCount, - (void *) pauiClient3DFenceUFOAddress, - pauiClient3DFenceUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, CheckValue=%d(0x%x)", - __func__, i + 1, ui32Client3DFenceCount, - (void *) pauiClient3DFenceUFOAddress, - pauiClient3DFenceUFOAddress->ui32Addr, - *paui32Client3DFenceValue, - *paui32Client3DFenceValue)); - paui32Client3DFenceValue++; - } - pauiClient3DFenceUFOAddress++; - } - - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d 3D update syncs:", - __func__, ui32Client3DUpdateCount)); - for (i = 0; i < ui32Client3DUpdateCount; i++) - { - if (BITMASK_HAS(pauiClient3DUpdateUFOAddress->ui32Addr, 1)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x," - " UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", - __func__, i + 1, ui32Client3DUpdateCount, - (void *) pauiClient3DUpdateUFOAddress, - pauiClient3DUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d(0x%x)", - __func__, i + 1, ui32Client3DUpdateCount, - (void *) pauiClient3DUpdateUFOAddress, - pauiClient3DUpdateUFOAddress->ui32Addr, - *paui32Client3DUpdateValue, - *paui32Client3DUpdateValue)); - paui32Client3DUpdateValue++; - } - pauiClient3DUpdateUFOAddress++; - } -} -#endif /* (ENABLE_TA3D_UFO_DUMP == 1) */ - -/* - * PVRSRVRGXKickTA3DKM - */ -PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, - IMG_UINT32 ui32ClientTAFenceCount, - SYNC_PRIMITIVE_BLOCK **apsClientTAFenceSyncPrimBlock, - IMG_UINT32 *paui32ClientTAFenceSyncOffset, - IMG_UINT32 *paui32ClientTAFenceValue, - IMG_UINT32 ui32ClientTAUpdateCount, - SYNC_PRIMITIVE_BLOCK **apsClientTAUpdateSyncPrimBlock, - IMG_UINT32 *paui32ClientTAUpdateSyncOffset, - IMG_UINT32 *paui32ClientTAUpdateValue, - IMG_UINT32 ui32Client3DUpdateCount, - SYNC_PRIMITIVE_BLOCK **apsClient3DUpdateSyncPrimBlock, - IMG_UINT32 *paui32Client3DUpdateSyncOffset, - IMG_UINT32 *paui32Client3DUpdateValue, - SYNC_PRIMITIVE_BLOCK *psPRFenceSyncPrimBlock, - IMG_UINT32 ui32PRFenceSyncOffset, - IMG_UINT32 ui32PRFenceValue, - PVRSRV_FENCE iCheckTAFence, - PVRSRV_TIMELINE iUpdateTATimeline, - PVRSRV_FENCE *piUpdateTAFence, - IMG_CHAR szFenceNameTA[PVRSRV_SYNC_NAME_LENGTH], - PVRSRV_FENCE iCheck3DFence, - PVRSRV_TIMELINE iUpdate3DTimeline, - PVRSRV_FENCE *piUpdate3DFence, - IMG_CHAR szFenceName3D[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32TACmdSize, - IMG_PBYTE pui8TADMCmd, - IMG_UINT32 ui323DPRCmdSize, - IMG_PBYTE pui83DPRDMCmd, - IMG_UINT32 ui323DCmdSize, - IMG_PBYTE pui83DDMCmd, - IMG_UINT32 ui32ExtJobRef, - IMG_BOOL bKickTA, - IMG_BOOL bKickPR, - IMG_BOOL bKick3D, - IMG_BOOL bAbort, - IMG_UINT32 ui32PDumpFlags, - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet, - RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_ZSBUFFER_DATA *psMSAAScratchBuffer, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs, - IMG_UINT32 ui32RenderTargetSize, - IMG_UINT32 ui32NumberOfDrawCalls, - IMG_UINT32 ui32NumberOfIndices, - IMG_UINT32 ui32NumberOfMRTs, - IMG_UINT64 ui64DeadlineInus) -{ - /* per-context helper structures */ - RGX_CCB_CMD_HELPER_DATA *pasTACmdHelperData = psRenderContext->asTACmdHelperData; - RGX_CCB_CMD_HELPER_DATA *pas3DCmdHelperData = psRenderContext->as3DCmdHelperData; - - IMG_UINT32 ui32TACmdCount=0; - IMG_UINT32 ui323DCmdCount=0; - IMG_UINT32 ui32TACmdOffset=0; - IMG_UINT32 ui323DCmdOffset=0; - RGXFWIF_UFO sPRUFO; - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_ERROR eError2 = PVRSRV_OK; - - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psRenderContext->s3DData.psServerCommonContext); - IMG_UINT32 ui32IntJobRef = OSAtomicIncrement(&psDevInfo->iCCBSubmissionOrdinal); - IMG_BOOL bCCBStateOpen = IMG_FALSE; - - IMG_UINT32 ui32ClientPRUpdateCount = 0; - PRGXFWIF_UFO_ADDR *pauiClientPRUpdateUFOAddress = NULL; - IMG_UINT32 *paui32ClientPRUpdateValue = NULL; - - PRGXFWIF_TIMESTAMP_ADDR pPreAddr; - PRGXFWIF_TIMESTAMP_ADDR pPostAddr; - PRGXFWIF_UFO_ADDR pRMWUFOAddr; - - PRGXFWIF_UFO_ADDR *pauiClientTAFenceUFOAddress = NULL; - PRGXFWIF_UFO_ADDR *pauiClientTAUpdateUFOAddress = NULL; - PRGXFWIF_UFO_ADDR *pauiClient3DFenceUFOAddress = NULL; - PRGXFWIF_UFO_ADDR *pauiClient3DUpdateUFOAddress = NULL; - PRGXFWIF_UFO_ADDR uiPRFenceUFOAddress; - - IMG_UINT64 uiCheckTAFenceUID = 0; - IMG_UINT64 uiCheck3DFenceUID = 0; - IMG_UINT64 uiUpdateTAFenceUID = 0; - IMG_UINT64 uiUpdate3DFenceUID = 0; - - IMG_BOOL bUseCombined3DAnd3DPR = bKickPR && bKick3D && !pui83DPRDMCmd; - - RGXFWIF_KCCB_CMD_KICK_DATA sTACmdKickData; - RGXFWIF_KCCB_CMD_KICK_DATA s3DCmdKickData; - IMG_BOOL bUseSingleFWCommand = bKickTA && (bKickPR || bKick3D); - - IMG_UINT32 ui32TACmdSizeTmp = 0, ui323DCmdSizeTmp = 0; - - IMG_BOOL bTAFenceOnSyncCheckpointsOnly = IMG_FALSE; - - PVRSRV_FENCE iUpdateTAFence = PVRSRV_NO_FENCE; - PVRSRV_FENCE iUpdate3DFence = PVRSRV_NO_FENCE; - - IMG_BOOL b3DFenceOnSyncCheckpointsOnly = IMG_FALSE; - IMG_UINT32 ui32TAFenceTimelineUpdateValue = 0; - IMG_UINT32 ui323DFenceTimelineUpdateValue = 0; - - /* - * Count of the number of TA and 3D update values (may differ from number of - * TA and 3D updates later, as sync checkpoints do not need to specify a value) - */ - IMG_UINT32 ui32ClientPRUpdateValueCount = 0; - IMG_UINT32 ui32ClientTAUpdateValueCount = ui32ClientTAUpdateCount; - IMG_UINT32 ui32Client3DUpdateValueCount = ui32Client3DUpdateCount; - PSYNC_CHECKPOINT *apsFenceTASyncCheckpoints = NULL; /*!< TA fence checkpoints */ - PSYNC_CHECKPOINT *apsFence3DSyncCheckpoints = NULL; /*!< 3D fence checkpoints */ - IMG_UINT32 ui32FenceTASyncCheckpointCount = 0; - IMG_UINT32 ui32Fence3DSyncCheckpointCount = 0; - PSYNC_CHECKPOINT psUpdateTASyncCheckpoint = NULL; /*!< TA update checkpoint (output) */ - PSYNC_CHECKPOINT psUpdate3DSyncCheckpoint = NULL; /*!< 3D update checkpoint (output) */ - PVRSRV_CLIENT_SYNC_PRIM *psTAFenceTimelineUpdateSync = NULL; - PVRSRV_CLIENT_SYNC_PRIM *ps3DFenceTimelineUpdateSync = NULL; - void *pvTAUpdateFenceFinaliseData = NULL; - void *pv3DUpdateFenceFinaliseData = NULL; - - RGX_SYNC_DATA sTASyncData = {NULL}; /*!< Contains internal update syncs for TA */ - RGX_SYNC_DATA s3DSyncData = {NULL}; /*!< Contains internal update syncs for 3D */ - - IMG_BOOL bTestSLRAdd3DCheck = IMG_FALSE; -#if defined(SUPPORT_VALIDATION) - PVRSRV_FENCE hTestSLRTmpFence = PVRSRV_NO_FENCE; - PSYNC_CHECKPOINT psDummySyncCheckpoint = NULL; -#endif - -#if defined(SUPPORT_BUFFER_SYNC) - PSYNC_CHECKPOINT *apsBufferFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32BufferFenceSyncCheckpointCount = 0; - PSYNC_CHECKPOINT psBufferUpdateSyncCheckpoint = NULL; - struct pvr_buffer_sync_append_data *psBufferSyncData = NULL; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_WORKEST_KICK_DATA sWorkloadKickDataTA = {0}; - RGXFWIF_WORKEST_KICK_DATA sWorkloadKickData3D = {0}; - IMG_UINT32 ui32TACommandOffset = 0; - IMG_UINT32 ui323DCommandOffset = 0; - IMG_UINT32 ui32TACmdHeaderOffset = 0; - IMG_UINT32 ui323DCmdHeaderOffset = 0; - IMG_UINT32 ui323DFullRenderCommandOffset = 0; - IMG_UINT32 ui32TACmdOffsetWrapCheck = 0; - IMG_UINT32 ui323DCmdOffsetWrapCheck = 0; - RGX_WORKLOAD sWorkloadCharacteristics = {0}; -#endif - - IMG_UINT32 ui32TAFenceCount, ui323DFenceCount; - IMG_UINT32 ui32TAUpdateCount, ui323DUpdateCount; - IMG_UINT32 ui32PRUpdateCount; - - IMG_PID uiCurrentProcess = OSGetCurrentClientProcessIDKM(); - - IMG_UINT32 ui32Client3DFenceCount = 0; - - /* Ensure we haven't been given a null ptr to - * TA fence values if we have been told we - * have TA sync prim fences - */ - if (ui32ClientTAFenceCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32ClientTAFenceValue != NULL, - "paui32ClientTAFenceValue NULL but " - "ui32ClientTAFenceCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - /* Ensure we haven't been given a null ptr to - * TA update values if we have been told we - * have TA updates - */ - if (ui32ClientTAUpdateCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32ClientTAUpdateValue != NULL, - "paui32ClientTAUpdateValue NULL but " - "ui32ClientTAUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - /* Ensure we haven't been given a null ptr to - * 3D update values if we have been told we - * have 3D updates - */ - if (ui32Client3DUpdateCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32Client3DUpdateValue != NULL, - "paui32Client3DUpdateValue NULL but " - "ui32Client3DUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Write FW addresses into CMD SHARED BLOCKs */ - { - CMDTA3D_SHARED *psGeomCmdShared = (CMDTA3D_SHARED *)pui8TADMCmd; - CMDTA3D_SHARED *ps3DCmdShared = (CMDTA3D_SHARED *)pui83DDMCmd; - CMDTA3D_SHARED *psPR3DCmdShared = (CMDTA3D_SHARED *)pui83DPRDMCmd; - - if (psKMHWRTDataSet == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "KMHWRTDataSet is a null-pointer")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Write FW address for TA CMD - */ - if (psGeomCmdShared != NULL) - { - psGeomCmdShared->sHWRTData = psKMHWRTDataSet->sHWRTDataFwAddr; - - if (psZSBuffer != NULL) - { - psGeomCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_ZSBUFFER] = psZSBuffer->sZSBufferFWDevVAddr; - } - if (psMSAAScratchBuffer != NULL) - { - psGeomCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_MSAABUFFER] = psMSAAScratchBuffer->sZSBufferFWDevVAddr; - } - } - - /* Write FW address for 3D CMD - */ - if (ps3DCmdShared != NULL) - { - ps3DCmdShared->sHWRTData = psKMHWRTDataSet->sHWRTDataFwAddr; - - if (psZSBuffer != NULL) - { - ps3DCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_ZSBUFFER] = psZSBuffer->sZSBufferFWDevVAddr; - } - if (psMSAAScratchBuffer != NULL) - { - ps3DCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_MSAABUFFER] = psMSAAScratchBuffer->sZSBufferFWDevVAddr; - } - } - - /* Write FW address for PR3D CMD - */ - if (psPR3DCmdShared != NULL) - { - psPR3DCmdShared->sHWRTData = psKMHWRTDataSet->sHWRTDataFwAddr; - - if (psZSBuffer != NULL) - { - psPR3DCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_ZSBUFFER] = psZSBuffer->sZSBufferFWDevVAddr; - } - if (psMSAAScratchBuffer != NULL) - { - psPR3DCmdShared->asPRBuffer[RGXFWIF_PRBUFFER_MSAABUFFER] = psMSAAScratchBuffer->sZSBufferFWDevVAddr; - } - } - } - - if (unlikely(iUpdateTATimeline >= 0 && !piUpdateTAFence)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - if (unlikely(iUpdate3DTimeline >= 0 && !piUpdate3DFence)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: ui32ClientTAFenceCount=%d, ui32ClientTAUpdateCount=%d, " - "ui32Client3DFenceCount=%d, ui32Client3DUpdateCount=%d", - __func__, - ui32ClientTAFenceCount, ui32ClientTAUpdateCount, - ui32Client3DFenceCount, ui32Client3DUpdateCount)); - - - RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psRenderContext->psDeviceNode->pvDevice, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr); - - /* Double-check we have a PR kick if there are client fences */ - if (unlikely(!bKickPR && ui32Client3DFenceCount != 0)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: 3D fence passed without a PR kick", - __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Ensure the string is null-terminated (Required for safety) */ - szFenceNameTA[PVRSRV_SYNC_NAME_LENGTH-1] = '\0'; - szFenceName3D[PVRSRV_SYNC_NAME_LENGTH-1] = '\0'; - - OSLockAcquire(psRenderContext->hLock); - - ui32TAFenceCount = ui32ClientTAFenceCount; - ui323DFenceCount = ui32Client3DFenceCount; - ui32TAUpdateCount = ui32ClientTAUpdateCount; - ui323DUpdateCount = ui32Client3DUpdateCount; - ui32PRUpdateCount = ui32ClientPRUpdateCount; - -#if defined(SUPPORT_BUFFER_SYNC) - if (ui32SyncPMRCount) - { - int err; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: Calling" - " pvr_buffer_sync_resolve_and_create_fences", __func__)); - - err = pvr_buffer_sync_resolve_and_create_fences( - psRenderContext->psBufferSyncContext, - psRenderContext->psDeviceNode->hSyncCheckpointContext, - ui32SyncPMRCount, - ppsSyncPMRs, - paui32SyncPMRFlags, - &ui32BufferFenceSyncCheckpointCount, - &apsBufferFenceSyncCheckpoints, - &psBufferUpdateSyncCheckpoint, - &psBufferSyncData - ); - - if (unlikely(err)) - { - switch (err) - { - case -EINTR: - eError = PVRSRV_ERROR_RETRY; - break; - case -ENOMEM: - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - break; - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: " - "pvr_buffer_sync_resolve_and_create_fences failed (%d)", - __func__, eError)); - } - OSLockRelease(psRenderContext->hLock); - - return eError; - } - -#if !defined(SUPPORT_STRIP_RENDERING) - if (bKickTA) - { - ui32TAFenceCount += ui32BufferFenceSyncCheckpointCount; - } - else - { - ui323DFenceCount += ui32BufferFenceSyncCheckpointCount; - } -#else /* !defined(SUPPORT_STRIP_RENDERING) */ - ui323DFenceCount += ui32BufferFenceSyncCheckpointCount; - - PVR_UNREFERENCED_PARAMETER(bTAFenceOnSyncCheckpointsOnly); -#endif /* !defined(SUPPORT_STRIP_RENDERING) */ - - if (psBufferUpdateSyncCheckpoint != NULL) - { - if (bKick3D) - { - ui323DUpdateCount++; - } - else - { - ui32PRUpdateCount++; - } - } - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - -#if !defined(UPDATE_FENCE_CHECKPOINT_COUNT) || UPDATE_FENCE_CHECKPOINT_COUNT != 1 && UPDATE_FENCE_CHECKPOINT_COUNT != 2 -#error "Invalid value for UPDATE_FENCE_CHECKPOINT_COUNT. Must be either 1 or 2." -#endif /* !defined(UPDATE_FENCE_CHECKPOINT_COUNT) || UPDATE_FENCE_CHECKPOINT_COUNT != 1 && UPDATE_FENCE_CHECKPOINT_COUNT != 2 */ - - if (iCheckTAFence != PVRSRV_NO_FENCE) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointResolveFence[TA]" - " (iCheckFence=%d)," - " psRenderContext->psDeviceNode->hSyncCheckpointContext=<%p>...", - __func__, iCheckTAFence, - (void *) psRenderContext->psDeviceNode->hSyncCheckpointContext)); - - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence( - psRenderContext->psDeviceNode->hSyncCheckpointContext, - iCheckTAFence, - &ui32FenceTASyncCheckpointCount, - &apsFenceTASyncCheckpoints, - &uiCheckTAFenceUID, - ui32PDumpFlags); - if (unlikely(eError != PVRSRV_OK)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, returned ERROR (eError=%d)", - __func__, eError)); - goto fail_resolve_input_ta_fence; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, fence %d contained %d " - "checkpoints (apsFenceSyncCheckpoints=<%p>)", - __func__, iCheckTAFence, ui32FenceTASyncCheckpointCount, - (void *) apsFenceTASyncCheckpoints)); - -#if defined(TA3D_CHECKPOINT_DEBUG) - if (apsFenceTASyncCheckpoints) - { - _DebugSyncCheckpoints(__func__, "TA", apsFenceTASyncCheckpoints, - ui32FenceTASyncCheckpointCount); - } -#endif /* defined(TA3D_CHECKPOINT_DEBUG) */ - } - - if (iCheck3DFence != PVRSRV_NO_FENCE) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointResolveFence[3D]" - " (iCheckFence=%d), " - "psRenderContext->psDeviceNode->hSyncCheckpointContext=<%p>...", - __func__, iCheck3DFence, - (void*)psRenderContext->psDeviceNode->hSyncCheckpointContext)); - - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence( - psRenderContext->psDeviceNode->hSyncCheckpointContext, - iCheck3DFence, - &ui32Fence3DSyncCheckpointCount, - &apsFence3DSyncCheckpoints, - &uiCheck3DFenceUID, - ui32PDumpFlags); - if (unlikely(eError != PVRSRV_OK)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, returned ERROR (eError=%d)", - __func__, eError)); - goto fail_resolve_input_3d_fence; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, fence %d contained %d " - "checkpoints (apsFenceSyncCheckpoints=<%p>)", - __func__, iCheck3DFence, ui32Fence3DSyncCheckpointCount, - (void*)apsFence3DSyncCheckpoints)); - -#if defined(TA3D_CHECKPOINT_DEBUG) - if (apsFence3DSyncCheckpoints) - { - _DebugSyncCheckpoints(__func__, "3D", apsFence3DSyncCheckpoints, - ui32Fence3DSyncCheckpointCount); - } -#endif /* defined(TA3D_CHECKPOINT_DEBUG) */ - } - - if (iCheckTAFence >= 0 || iUpdateTATimeline >= 0 || - iCheck3DFence >= 0 || iUpdate3DTimeline >= 0) - { - IMG_UINT32 i; - - if (bKickTA) - { - ui32TAFenceCount += ui32FenceTASyncCheckpointCount; - - for (i = 0; i < ui32Fence3DSyncCheckpointCount; i++) - { - if (SyncCheckpointGetCreator(apsFence3DSyncCheckpoints[i]) != - uiCurrentProcess) - { - ui32TAFenceCount++; - } - } - } - - if (bKick3D) - { - ui323DFenceCount += ui32Fence3DSyncCheckpointCount; - } - - ui32TAUpdateCount += iUpdateTATimeline != PVRSRV_NO_TIMELINE ? - UPDATE_FENCE_CHECKPOINT_COUNT : 0; - ui323DUpdateCount += iUpdate3DTimeline != PVRSRV_NO_TIMELINE ? - UPDATE_FENCE_CHECKPOINT_COUNT : 0; - ui32PRUpdateCount += iUpdate3DTimeline != PVRSRV_NO_TIMELINE && !bKick3D ? - UPDATE_FENCE_CHECKPOINT_COUNT : 0; - } - -#if defined(SUPPORT_VALIDATION) - /* Check if TestingSLR is adding an extra sync checkpoint to the - * 3D fence check (which we won't signal) - */ - if ((psDevInfo->ui32TestSLRInterval > 0) && - (--psDevInfo->ui32TestSLRCount == 0)) - { - bTestSLRAdd3DCheck = IMG_TRUE; - psDevInfo->ui32TestSLRCount = psDevInfo->ui32TestSLRInterval; - } - - if ((bTestSLRAdd3DCheck) && (iUpdate3DTimeline != PVRSRV_NO_TIMELINE)) - { - if (iUpdate3DTimeline == PVRSRV_NO_TIMELINE) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Would append additional SLR checkpoint " - "to 3D fence but no update 3D timeline provided", __func__)); - } - else - { - SyncCheckpointAlloc(psRenderContext->psDeviceNode->hSyncCheckpointContext, - iUpdate3DTimeline, - hTestSLRTmpFence, - "TestSLRCheck", - &psDummySyncCheckpoint); - PVR_DPF((PVR_DBG_WARNING, "%s: Appending additional SLR checkpoint to 3D fence " - "checkpoints (psDummySyncCheckpoint=<%p>)", - __func__, (void*)psDummySyncCheckpoint)); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DFence, - 1, - &psDummySyncCheckpoint); - if (!pauiClient3DFenceUFOAddress) - { - pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; - } - - if (ui32Client3DFenceCount == 0) - { - b3DFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - ui323DFenceCount++; - } - } -#endif /* defined(SUPPORT_VALIDATION) */ - - if (bKickTA) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling RGXCmdHelperInitCmdCCB()," - " ui32ClientTAFenceCount=%d, ui32ClientTAUpdateCount=%d", - __func__, ui32TAFenceCount, ui32TAUpdateCount)); - - RGXCmdHelperInitCmdCCB_CommandSize( - psDevInfo, - 0, - ui32TAFenceCount, - ui32TAUpdateCount, - ui32TACmdSize, - &pPreAddr, - (bKick3D ? NULL : &pPostAddr), - (bKick3D ? NULL : &pRMWUFOAddr), - pasTACmdHelperData - ); - } - - if (bKickPR) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling RGXCmdHelperInitCmdCCB()," - " ui32Client3DFenceCount=%d", __func__, - ui323DFenceCount)); - - RGXCmdHelperInitCmdCCB_CommandSize( - psDevInfo, - 0, - ui323DFenceCount, - 0, - sizeof(sPRUFO), - NULL, - NULL, - NULL, - &pas3DCmdHelperData[ui323DCmdCount++] - ); - } - - if (bKickPR && !bUseCombined3DAnd3DPR) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling RGXCmdHelperInitCmdCCB()," - " ui32PRUpdateCount=%d", __func__, - ui32PRUpdateCount)); - - RGXCmdHelperInitCmdCCB_CommandSize( - psDevInfo, - 0, - 0, - ui32PRUpdateCount, - /* if the client has not provided a 3DPR command, the regular 3D - * command should be used instead */ - pui83DPRDMCmd ? ui323DPRCmdSize : ui323DCmdSize, - NULL, - NULL, - NULL, - &pas3DCmdHelperData[ui323DCmdCount++] - ); - } - - if (bKick3D || bAbort) - { - if (!bKickTA) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling RGXCmdHelperInitCmdCCB()," - " ui32Client3DFenceCount=%d", __func__, - ui323DFenceCount)); - } - - RGXCmdHelperInitCmdCCB_CommandSize( - psDevInfo, - 0, - bKickTA ? 0 : ui323DFenceCount, - ui323DUpdateCount, - ui323DCmdSize, - (bKickTA ? NULL : &pPreAddr), - &pPostAddr, - &pRMWUFOAddr, - &pas3DCmdHelperData[ui323DCmdCount++] - ); - } - - if (bKickTA) - { - ui32TACmdSizeTmp = RGXCmdHelperGetCommandSize(1, pasTACmdHelperData); - - eError = RGXCheckSpaceCCB( - FWCommonContextGetClientCCB(psRenderContext->sTAData.psServerCommonContext), - ui32TACmdSizeTmp - ); - if (eError != PVRSRV_OK) - { - goto err_not_enough_space; - } - } - - if (ui323DCmdCount > 0) - { - ui323DCmdSizeTmp = RGXCmdHelperGetCommandSize(ui323DCmdCount, pas3DCmdHelperData); - - eError = RGXCheckSpaceCCB( - FWCommonContextGetClientCCB(psRenderContext->s3DData.psServerCommonContext), - ui323DCmdSizeTmp - ); - if (eError != PVRSRV_OK) - { - goto err_not_enough_space; - } - } - - /* need to reset the counter here */ - - ui323DCmdCount = 0; - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: SyncAddrListPopulate(psRenderContext->sSyncAddrListTAFence, %d fences)...", - __func__, ui32ClientTAFenceCount)); - eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAFence, - ui32ClientTAFenceCount, - apsClientTAFenceSyncPrimBlock, - paui32ClientTAFenceSyncOffset); - if (unlikely(eError != PVRSRV_OK)) - { - goto err_populate_sync_addr_list_ta_fence; - } - - if (ui32ClientTAFenceCount) - { - pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: pauiClientTAFenceUFOAddress=<%p> ", - __func__, (void*)pauiClientTAFenceUFOAddress)); - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: SyncAddrListPopulate(psRenderContext->sSyncAddrListTAUpdate, %d updates)...", - __func__, ui32ClientTAUpdateCount)); - eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAUpdate, - ui32ClientTAUpdateCount, - apsClientTAUpdateSyncPrimBlock, - paui32ClientTAUpdateSyncOffset); - if (unlikely(eError != PVRSRV_OK)) - { - goto err_populate_sync_addr_list_ta_update; - } - - if (ui32ClientTAUpdateCount) - { - pauiClientTAUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: pauiClientTAUpdateUFOAddress=<%p> ", - __func__, (void*)pauiClientTAUpdateUFOAddress)); - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: SyncAddrListPopulate(psRenderContext->sSyncAddrList3DFence, %d fences)...", - __func__, ui32Client3DFenceCount)); - eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DFence, - ui32Client3DFenceCount, - NULL, - NULL); - if (unlikely(eError != PVRSRV_OK)) - { - goto err_populate_sync_addr_list_3d_fence; - } - - if (ui32Client3DFenceCount) - { - pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: pauiClient3DFenceUFOAddress=<%p> ", - __func__, (void*)pauiClient3DFenceUFOAddress)); - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: SyncAddrListPopulate(psRenderContext->sSyncAddrList3DUpdate, %d updates)...", - __func__, ui32Client3DUpdateCount)); - eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DUpdate, - ui32Client3DUpdateCount, - apsClient3DUpdateSyncPrimBlock, - paui32Client3DUpdateSyncOffset); - if (unlikely(eError != PVRSRV_OK)) - { - goto err_populate_sync_addr_list_3d_update; - } - - if (ui32Client3DUpdateCount || (iUpdate3DTimeline != PVRSRV_NO_TIMELINE && piUpdate3DFence && bKick3D)) - { - pauiClient3DUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: pauiClient3DUpdateUFOAddress=<%p> ", - __func__, (void*)pauiClient3DUpdateUFOAddress)); - - eError = SyncPrimitiveBlockToFWAddr(psPRFenceSyncPrimBlock, ui32PRFenceSyncOffset, &uiPRFenceUFOAddress); - - if (unlikely(eError != PVRSRV_OK)) - { - goto err_pr_fence_address; - } - -#if (ENABLE_TA3D_UFO_DUMP == 1) - DumpUfoList(ui32ClientTAFenceCount, ui32ClientTAUpdateCount, - ui32Client3DFenceCount + (bTestSLRAdd3DCheck ? 1 : 0), - ui32Client3DUpdateCount, - pauiClientTAFenceUFOAddress, paui32ClientTAFenceValue, - pauiClientTAUpdateUFOAddress, paui32ClientTAUpdateValue, - pauiClient3DFenceUFOAddress, NULL, - pauiClient3DUpdateUFOAddress, paui32Client3DUpdateValue); -#endif /* (ENABLE_TA3D_UFO_DUMP == 1) */ - - if (ui32SyncPMRCount) - { -#if defined(SUPPORT_BUFFER_SYNC) -#if !defined(SUPPORT_STRIP_RENDERING) - /* Append buffer sync fences to TA fences */ - if (ui32BufferFenceSyncCheckpointCount > 0 && bKickTA) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append %d buffer sync checkpoints to TA Fence " - "(&psRenderContext->sSyncAddrListTAFence=<%p>, " - "pauiClientTAFenceUFOAddress=<%p>)...", - __func__, - ui32BufferFenceSyncCheckpointCount, - (void*)&psRenderContext->sSyncAddrListTAFence , - (void*)pauiClientTAFenceUFOAddress)); - SyncAddrListAppendAndDeRefCheckpoints(&psRenderContext->sSyncAddrListTAFence, - ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); - if (!pauiClientTAFenceUFOAddress) - { - pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; - } - if (ui32ClientTAFenceCount == 0) - { - bTAFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - ui32ClientTAFenceCount += ui32BufferFenceSyncCheckpointCount; - } - else -#endif - /* Append buffer sync fences to 3D fences */ - if (ui32BufferFenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append %d buffer sync checkpoints to 3D Fence " - "(&psRenderContext->sSyncAddrList3DFence=<%p>, " - "pauiClient3DFenceUFOAddress=<%p>)...", - __func__, - ui32BufferFenceSyncCheckpointCount, - (void*)&psRenderContext->sSyncAddrList3DFence, - (void*)pauiClient3DFenceUFOAddress)); - SyncAddrListAppendAndDeRefCheckpoints(&psRenderContext->sSyncAddrList3DFence, - ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); - if (!pauiClient3DFenceUFOAddress) - { - pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; - } - if (ui32Client3DFenceCount == 0) - { - b3DFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - ui32Client3DFenceCount += ui32BufferFenceSyncCheckpointCount; - } - - if (psBufferUpdateSyncCheckpoint) - { - /* If we have a 3D kick append update to the 3D updates else append to the PR update */ - if (bKick3D) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 buffer sync checkpoint<%p> to 3D Update" - " (&psRenderContext->sSyncAddrList3DUpdate=<%p>," - " pauiClient3DUpdateUFOAddress=<%p>)...", - __func__, - (void*)psBufferUpdateSyncCheckpoint, - (void*)&psRenderContext->sSyncAddrList3DUpdate, - (void*)pauiClient3DUpdateUFOAddress)); - /* Append buffer sync update to 3D updates */ - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DUpdate, - 1, - &psBufferUpdateSyncCheckpoint); - if (!pauiClient3DUpdateUFOAddress) - { - pauiClient3DUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; - } - ui32Client3DUpdateCount++; - } - else - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 buffer sync checkpoint<%p> to PR Update" - " (&psRenderContext->sSyncAddrList3DUpdate=<%p>," - " pauiClientPRUpdateUFOAddress=<%p>)...", - __func__, - (void*)psBufferUpdateSyncCheckpoint, - (void*)&psRenderContext->sSyncAddrList3DUpdate, - (void*)pauiClientPRUpdateUFOAddress)); - /* Attach update to the 3D (used for PR) Updates */ - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DUpdate, - 1, - &psBufferUpdateSyncCheckpoint); - if (!pauiClientPRUpdateUFOAddress) - { - pauiClientPRUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; - } - ui32ClientPRUpdateCount++; - } - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: (after buffer_sync) ui32ClientTAFenceCount=%d, " - "ui32ClientTAUpdateCount=%d, ui32Client3DFenceCount=%d, " - "ui32Client3DUpdateCount=%d, ui32ClientPRUpdateCount=%d,", - __func__, ui32ClientTAFenceCount, ui32ClientTAUpdateCount, - ui32Client3DFenceCount, ui32Client3DUpdateCount, - ui32ClientPRUpdateCount)); - -#else /* defined(SUPPORT_BUFFER_SYNC) */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Buffer sync not supported but got %u buffers", - __func__, ui32SyncPMRCount)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto err_no_buffer_sync_invalid_params; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - } - - /* - * The hardware requires a PR to be submitted if there is a TA (otherwise - * it can wedge if we run out of PB space with no PR to run) - * - * If we only have a TA, attach native checks to the TA and updates to the PR - * If we have a TA and 3D, attach checks to TA, updates to 3D - * If we only have a 3D, attach checks and updates to the 3D - * - * Note that 'updates' includes the cleanup syncs for 'check' fence FDs, in - * addition to the update fence FD (if supplied) - * - * Currently, the client driver never kicks only the 3D, so we only support - * that for the time being. - */ - if (iCheckTAFence >= 0 || iUpdateTATimeline >= 0 || - iCheck3DFence >= 0 || iUpdate3DTimeline >= 0) - { - PRGXFWIF_UFO_ADDR __maybe_unused *pauiClientTAIntUpdateUFOAddress = NULL; - PRGXFWIF_UFO_ADDR __maybe_unused *pauiClient3DIntUpdateUFOAddress = NULL; - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: [TA] iCheckFence = %d, iUpdateTimeline = %d", - __func__, iCheckTAFence, iUpdateTATimeline)); - CHKPT_DBG((PVR_DBG_ERROR, - "%s: [3D] iCheckFence = %d, iUpdateTimeline = %d", - __func__, iCheck3DFence, iUpdate3DTimeline)); - - { - /* Create the output fence for TA (if required) */ - if (iUpdateTATimeline != PVRSRV_NO_TIMELINE) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling SyncCheckpointCreateFence[TA] " - "(iUpdateFence=%d, iUpdateTimeline=%d, " - "psRenderContext->psDeviceNode->hSyncCheckpointContext=<%p>)", - __func__, iUpdateTAFence, iUpdateTATimeline, - (void*)psRenderContext->psDeviceNode->hSyncCheckpointContext)); - eError = SyncCheckpointCreateFence(psRenderContext->psDeviceNode, - szFenceNameTA, - iUpdateTATimeline, - psRenderContext->psDeviceNode->hSyncCheckpointContext, - &iUpdateTAFence, - &uiUpdateTAFenceUID, - &pvTAUpdateFenceFinaliseData, - &psUpdateTASyncCheckpoint, - (void*)&psTAFenceTimelineUpdateSync, - &ui32TAFenceTimelineUpdateValue, - ui32PDumpFlags); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: SyncCheckpointCreateFence[TA] failed (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_create_ta_fence; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: returned from SyncCheckpointCreateFence[TA] " - "(iUpdateFence=%d, psFenceTimelineUpdateSync=<%p>, " - "ui32FenceTimelineUpdateValue=0x%x)", - __func__, iUpdateTAFence, - (void*)psTAFenceTimelineUpdateSync, - ui32TAFenceTimelineUpdateValue)); - - /* Store the FW address of the update sync checkpoint in pauiClientTAIntUpdateUFOAddress */ - pauiClientTAIntUpdateUFOAddress = SyncCheckpointGetRGXFWIFUFOAddr(psUpdateTASyncCheckpoint); - CHKPT_DBG((PVR_DBG_ERROR, - "%s: pauiClientIntUpdateUFOAddress[TA]->ui32Addr=0x%x", - __func__, pauiClientTAIntUpdateUFOAddress->ui32Addr)); - } - - /* Append the sync prim update for the TA timeline (if required) */ - if (psTAFenceTimelineUpdateSync) - { - sTASyncData.ui32ClientUpdateCount = ui32ClientTAUpdateCount; - sTASyncData.ui32ClientUpdateValueCount = ui32ClientTAUpdateValueCount; - sTASyncData.ui32ClientPRUpdateValueCount = (bKick3D) ? 0 : ui32ClientPRUpdateValueCount; - sTASyncData.paui32ClientUpdateValue = paui32ClientTAUpdateValue; - - eError = RGXSyncAppendTimelineUpdate(ui32TAFenceTimelineUpdateValue, - &psRenderContext->sSyncAddrListTAUpdate, - (bKick3D) ? NULL : &psRenderContext->sSyncAddrList3DUpdate, - psTAFenceTimelineUpdateSync, - &sTASyncData, - bKick3D); - if (unlikely(eError != PVRSRV_OK)) - { - goto fail_alloc_update_values_mem_TA; - } - - paui32ClientTAUpdateValue = sTASyncData.paui32ClientUpdateValue; - ui32ClientTAUpdateValueCount = sTASyncData.ui32ClientUpdateValueCount; - pauiClientTAUpdateUFOAddress = sTASyncData.pauiClientUpdateUFOAddress; - ui32ClientTAUpdateCount = sTASyncData.ui32ClientUpdateCount; - } - - /* Create the output fence for 3D (if required) */ - if (iUpdate3DTimeline != PVRSRV_NO_TIMELINE) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling SyncCheckpointCreateFence[3D] " - "(iUpdateFence=%d, iUpdateTimeline=%d, " - "psRenderContext->psDeviceNode->hSyncCheckpointContext=<%p>)", - __func__, iUpdate3DFence, iUpdate3DTimeline, - (void*)psRenderContext->psDeviceNode->hSyncCheckpointContext)); - eError = SyncCheckpointCreateFence(psRenderContext->psDeviceNode, - szFenceName3D, - iUpdate3DTimeline, - psRenderContext->psDeviceNode->hSyncCheckpointContext, - &iUpdate3DFence, - &uiUpdate3DFenceUID, - &pv3DUpdateFenceFinaliseData, - &psUpdate3DSyncCheckpoint, - (void*)&ps3DFenceTimelineUpdateSync, - &ui323DFenceTimelineUpdateValue, - ui32PDumpFlags); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: SyncCheckpointCreateFence[3D] failed (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_create_3d_fence; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: returned from SyncCheckpointCreateFence[3D] " - "(iUpdateFence=%d, psFenceTimelineUpdateSync=<%p>, " - "ui32FenceTimelineUpdateValue=0x%x)", - __func__, iUpdate3DFence, - (void*)ps3DFenceTimelineUpdateSync, - ui323DFenceTimelineUpdateValue)); - - /* Store the FW address of the update sync checkpoint in pauiClient3DIntUpdateUFOAddress */ - pauiClient3DIntUpdateUFOAddress = SyncCheckpointGetRGXFWIFUFOAddr(psUpdate3DSyncCheckpoint); - CHKPT_DBG((PVR_DBG_ERROR, - "%s: pauiClientIntUpdateUFOAddress[3D]->ui32Addr=0x%x", - __func__, pauiClient3DIntUpdateUFOAddress->ui32Addr)); - } - - /* Append the sync prim update for the 3D timeline (if required) */ - if (ps3DFenceTimelineUpdateSync) - { - s3DSyncData.ui32ClientUpdateCount = ui32Client3DUpdateCount; - s3DSyncData.ui32ClientUpdateValueCount = ui32Client3DUpdateValueCount; - s3DSyncData.ui32ClientPRUpdateValueCount = ui32ClientPRUpdateValueCount; - s3DSyncData.paui32ClientUpdateValue = paui32Client3DUpdateValue; - - eError = RGXSyncAppendTimelineUpdate(ui323DFenceTimelineUpdateValue, - &psRenderContext->sSyncAddrList3DUpdate, - &psRenderContext->sSyncAddrList3DUpdate, /*!< PR update: is this required? */ - ps3DFenceTimelineUpdateSync, - &s3DSyncData, - bKick3D); - if (unlikely(eError != PVRSRV_OK)) - { - goto fail_alloc_update_values_mem_3D; - } - - paui32Client3DUpdateValue = s3DSyncData.paui32ClientUpdateValue; - ui32Client3DUpdateValueCount = s3DSyncData.ui32ClientUpdateValueCount; - pauiClient3DUpdateUFOAddress = s3DSyncData.pauiClientUpdateUFOAddress; - ui32Client3DUpdateCount = s3DSyncData.ui32ClientUpdateCount; - - if (!bKick3D) - { - paui32ClientPRUpdateValue = s3DSyncData.paui32ClientPRUpdateValue; - ui32ClientPRUpdateValueCount = s3DSyncData.ui32ClientPRUpdateValueCount; - pauiClientPRUpdateUFOAddress = s3DSyncData.pauiClientPRUpdateUFOAddress; - ui32ClientPRUpdateCount = s3DSyncData.ui32ClientPRUpdateCount; - } - } - - /* - * The hardware requires a PR to be submitted if there is a TA OOM. - * If we only have a TA, attach native checks and updates to the TA - * and 3D updates to the PR. - * If we have a TA and 3D, attach the native TA checks and updates - * to the TA and similarly for the 3D. - * Note that 'updates' includes the cleanup syncs for 'check' fence - * FDs, in addition to the update fence FD (if supplied). - * Currently, the client driver never kicks only the 3D, so we don't - * support that for the time being. - */ - - { - if (bKickTA) - { - /* Attach checks and updates to TA */ - - /* Checks (from input fence) */ - if (ui32FenceTASyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append %d sync checkpoints to TA Fence (apsFenceSyncCheckpoints=<%p>)...", - __func__, - ui32FenceTASyncCheckpointCount, - (void*)apsFenceTASyncCheckpoints)); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrListTAFence, - ui32FenceTASyncCheckpointCount, - apsFenceTASyncCheckpoints); - if (!pauiClientTAFenceUFOAddress) - { - pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: {ui32ClientTAFenceCount was %d, now %d}", - __func__, ui32ClientTAFenceCount, - ui32ClientTAFenceCount + ui32FenceTASyncCheckpointCount)); - if (ui32ClientTAFenceCount == 0) - { - bTAFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - ui32ClientTAFenceCount += ui32FenceTASyncCheckpointCount; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: {ui32ClientTAFenceCount now %d}", - __func__, ui32ClientTAFenceCount)); - - if (psUpdateTASyncCheckpoint) - { - /* Update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 sync checkpoint<%p> (ID=%d) to TA Update...", - __func__, (void*)psUpdateTASyncCheckpoint, - SyncCheckpointGetId(psUpdateTASyncCheckpoint))); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrListTAUpdate, - 1, - &psUpdateTASyncCheckpoint); - if (!pauiClientTAUpdateUFOAddress) - { - pauiClientTAUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs; - } - ui32ClientTAUpdateCount++; - } - - if (!bKick3D && psUpdate3DSyncCheckpoint) - { - /* Attach update to the 3D (used for PR) Updates */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 sync checkpoint<%p> (ID=%d) to 3D(PR) Update...", - __func__, (void*)psUpdate3DSyncCheckpoint, - SyncCheckpointGetId(psUpdate3DSyncCheckpoint))); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DUpdate, - 1, - &psUpdate3DSyncCheckpoint); - if (!pauiClientPRUpdateUFOAddress) - { - pauiClientPRUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; - } - ui32ClientPRUpdateCount++; - } - } - - if (bKick3D) - { - /* Attach checks and updates to the 3D */ - - /* Checks (from input fence) */ - if (ui32Fence3DSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append %d sync checkpoints to 3D Fence...", - __func__, ui32Fence3DSyncCheckpointCount)); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DFence, - ui32Fence3DSyncCheckpointCount, - apsFence3DSyncCheckpoints); - if (!pauiClient3DFenceUFOAddress) - { - pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: {ui32Client3DFenceCount was %d, now %d}", - __func__, ui32Client3DFenceCount, - ui32Client3DFenceCount + ui32Fence3DSyncCheckpointCount)); - if (ui32Client3DFenceCount == 0) - { - b3DFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - ui32Client3DFenceCount += ui32Fence3DSyncCheckpointCount; - } - CHKPT_DBG((PVR_DBG_ERROR, - "%s: {ui32Client3DFenceCount was %d}", - __func__, ui32Client3DFenceCount)); - - if (psUpdate3DSyncCheckpoint) - { - /* Update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Append 1 sync checkpoint<%p> (ID=%d) to 3D Update...", - __func__, (void*)psUpdate3DSyncCheckpoint, - SyncCheckpointGetId(psUpdate3DSyncCheckpoint))); - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrList3DUpdate, - 1, - &psUpdate3DSyncCheckpoint); - if (!pauiClient3DUpdateUFOAddress) - { - pauiClient3DUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; - } - ui32Client3DUpdateCount++; - } - } - - /* - * Relocate sync check points from the 3D fence that are - * external to the current process, to the TA fence. - * This avoids a sync lockup when dependent renders are - * submitted out-of-order and a PR must be scheduled. - */ - if (bKickTA) - { - /* Search for external timeline dependencies */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Checking 3D fence for external sync points (%d)...", - __func__, ui32Fence3DSyncCheckpointCount)); - - for (i=0; i (ID=%d) to TA Fence...", - __func__, (void*)apsFence3DSyncCheckpoints[i], - SyncCheckpointGetId(apsFence3DSyncCheckpoints[i]))); - - SyncAddrListAppendCheckpoints(&psRenderContext->sSyncAddrListTAFence, - 1, - &apsFence3DSyncCheckpoints[i]); - - if (!pauiClientTAFenceUFOAddress) - { - pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: {ui32ClientTAFenceCount was %d, now %d}", - __func__, - ui32ClientTAFenceCount, - ui32ClientTAFenceCount + 1)); - - if (ui32ClientTAFenceCount == 0) - { - bTAFenceOnSyncCheckpointsOnly = IMG_TRUE; - } - - ui32ClientTAFenceCount++; - } - } - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: (after pvr_sync) ui32ClientTAFenceCount=%d, " - "ui32ClientTAUpdateCount=%d, ui32Client3DFenceCount=%d, " - "ui32Client3DUpdateCount=%d, ui32ClientPRUpdateCount=%d,", - __func__, - ui32ClientTAFenceCount, ui32ClientTAUpdateCount, - ui32Client3DFenceCount, ui32Client3DUpdateCount, - ui32ClientPRUpdateCount)); - } - } - - if (ui32ClientTAFenceCount) - { - PVR_ASSERT(pauiClientTAFenceUFOAddress); - if (!bTAFenceOnSyncCheckpointsOnly) - { - PVR_ASSERT(paui32ClientTAFenceValue); - } - } - if (ui32ClientTAUpdateCount) - { - PVR_ASSERT(pauiClientTAUpdateUFOAddress); - if (ui32ClientTAUpdateValueCount>0) - { - PVR_ASSERT(paui32ClientTAUpdateValue); - } - } - if (ui32Client3DFenceCount) - { - PVR_ASSERT(pauiClient3DFenceUFOAddress); - PVR_ASSERT(b3DFenceOnSyncCheckpointsOnly); - } - if (ui32Client3DUpdateCount) - { - PVR_ASSERT(pauiClient3DUpdateUFOAddress); - if (ui32Client3DUpdateValueCount>0) - { - PVR_ASSERT(paui32Client3DUpdateValue); - } - } - if (ui32ClientPRUpdateCount) - { - PVR_ASSERT(pauiClientPRUpdateUFOAddress); - if (ui32ClientPRUpdateValueCount>0) - { - PVR_ASSERT(paui32ClientPRUpdateValue); - } - } - - } - - CHKPT_DBG((PVR_DBG_ERROR, - "%s: ui32ClientTAFenceCount=%d, pauiClientTAFenceUFOAddress=<%p> Line ", - __func__, - ui32ClientTAFenceCount, - (void*)paui32ClientTAFenceValue)); - CHKPT_DBG((PVR_DBG_ERROR, - "%s: ui32ClientTAUpdateCount=%d, pauiClientTAUpdateUFOAddress=<%p> Line ", - __func__, - ui32ClientTAUpdateCount, - (void*)pauiClientTAUpdateUFOAddress)); -#if (ENABLE_TA3D_UFO_DUMP == 1) - DumpUfoList(ui32ClientTAFenceCount, ui32ClientTAUpdateCount, - ui32Client3DFenceCount + (bTestSLRAdd3DCheck ? 1 : 0), - ui32Client3DUpdateCount, - pauiClientTAFenceUFOAddress, paui32ClientTAFenceValue, - pauiClientTAUpdateUFOAddress, paui32ClientTAUpdateValue, - pauiClient3DFenceUFOAddress, NULL, - pauiClient3DUpdateUFOAddress, paui32Client3DUpdateValue); -#endif /* (ENABLE_TA3D_UFO_DUMP == 1) */ - - /* Command size check */ - if (ui32TAFenceCount != ui32ClientTAFenceCount) - { - PVR_DPF((PVR_DBG_ERROR, "TA pre-calculated number of fences" - " is different than the actual number (%u != %u)", - ui32TAFenceCount, ui32ClientTAFenceCount)); - } - if (ui32TAUpdateCount != ui32ClientTAUpdateCount) - { - PVR_DPF((PVR_DBG_ERROR, "TA pre-calculated number of updates" - " is different than the actual number (%u != %u)", - ui32TAUpdateCount, ui32ClientTAUpdateCount)); - } - if (!bTestSLRAdd3DCheck && (ui323DFenceCount != ui32Client3DFenceCount)) - { - PVR_DPF((PVR_DBG_ERROR, "3D pre-calculated number of fences" - " is different than the actual number (%u != %u)", - ui323DFenceCount, ui32Client3DFenceCount)); - } - if (ui323DUpdateCount != ui32Client3DUpdateCount) - { - PVR_DPF((PVR_DBG_ERROR, "3D pre-calculated number of updates" - " is different than the actual number (%u != %u)", - ui323DUpdateCount, ui32Client3DUpdateCount)); - } - if (ui32PRUpdateCount != ui32ClientPRUpdateCount) - { - PVR_DPF((PVR_DBG_ERROR, "PR pre-calculated number of updates" - " is different than the actual number (%u != %u)", - ui32PRUpdateCount, ui32ClientPRUpdateCount)); - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (bKickTA || bKick3D || bAbort) - { - sWorkloadCharacteristics.sTA3D.ui32RenderTargetSize = ui32RenderTargetSize; - sWorkloadCharacteristics.sTA3D.ui32NumberOfDrawCalls = ui32NumberOfDrawCalls; - sWorkloadCharacteristics.sTA3D.ui32NumberOfIndices = ui32NumberOfIndices; - sWorkloadCharacteristics.sTA3D.ui32NumberOfMRTs = ui32NumberOfMRTs; - } -#endif - - /* Init and acquire to TA command if required */ - if (bKickTA) - { - RGX_SERVER_RC_TA_DATA *psTAData = &psRenderContext->sTAData; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Prepare workload estimation */ - WorkEstPrepare(psRenderContext->psDeviceNode->pvDevice, - &psRenderContext->sWorkEstData, - &psRenderContext->sWorkEstData.uWorkloadMatchingData.sTA3D.sDataTA, - RGXFWIF_CCB_CMD_TYPE_GEOM, - &sWorkloadCharacteristics, - ui64DeadlineInus, - &sWorkloadKickDataTA); -#endif - - /* Init the TA command helper */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling RGXCmdHelperInitCmdCCB(), ui32ClientTAFenceCount=%d, ui32ClientTAUpdateCount=%d", - __func__, ui32ClientTAFenceCount, ui32ClientTAUpdateCount)); - RGXCmdHelperInitCmdCCB_OtherData(FWCommonContextGetClientCCB(psTAData->psServerCommonContext), - ui32ClientTAFenceCount, - pauiClientTAFenceUFOAddress, - paui32ClientTAFenceValue, - ui32ClientTAUpdateCount, - pauiClientTAUpdateUFOAddress, - paui32ClientTAUpdateValue, - ui32TACmdSize, - pui8TADMCmd, - &pPreAddr, - (bKick3D ? NULL : &pPostAddr), - (bKick3D ? NULL : &pRMWUFOAddr), - RGXFWIF_CCB_CMD_TYPE_GEOM, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - &sWorkloadKickDataTA, -#else - NULL, -#endif - "TA", - bCCBStateOpen, - pasTACmdHelperData); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* The following is used to determine the offset of the command header containing - the workload estimation data so that can be accessed when the KCCB is read */ - ui32TACmdHeaderOffset = RGXCmdHelperGetDMCommandHeaderOffset(pasTACmdHelperData); -#endif - - eError = RGXCmdHelperAcquireCmdCCB(CCB_CMD_HELPER_NUM_TA_COMMANDS, pasTACmdHelperData); - if (unlikely(eError != PVRSRV_OK)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", - __func__, eError)); - goto fail_taacquirecmd; - } - else - { - ui32TACmdCount++; - } - } - - /* Only kick the 3D if required */ - if (bKickPR) - { - RGX_SERVER_RC_3D_DATA *ps3DData = &psRenderContext->s3DData; - - /* - The command helper doesn't know about the PR fence so create - the command with all the fences against it and later create - the PR command itself which _must_ come after the PR fence. - */ - sPRUFO.puiAddrUFO = uiPRFenceUFOAddress; - sPRUFO.ui32Value = ui32PRFenceValue; - - /* Init the PR fence command helper */ - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling RGXCmdHelperInitCmdCCB(), ui32Client3DFenceCount=%d", - __func__, ui32Client3DFenceCount)); - RGXCmdHelperInitCmdCCB_OtherData(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext), - ui32Client3DFenceCount + (bTestSLRAdd3DCheck ? 1 : 0), - pauiClient3DFenceUFOAddress, - NULL, - 0, - NULL, - NULL, - sizeof(sPRUFO), - (IMG_UINT8*) &sPRUFO, - NULL, - NULL, - NULL, - RGXFWIF_CCB_CMD_TYPE_FENCE_PR, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, - NULL, - "3D-PR-Fence", - bCCBStateOpen, - &pas3DCmdHelperData[ui323DCmdCount++]); - - /* Init the 3D PR command helper */ - /* - Updates for Android (fence sync and Timeline sync prim) are provided in the PR-update - if no 3D is present. This is so the timeline update cannot happen out of order with any - other 3D already in flight for the same timeline (PR-updates are done in the 3D cCCB). - This out of order timeline sync prim update could happen if we attach it to the TA update. - */ - if (ui32ClientPRUpdateCount) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Line %d, ui32ClientPRUpdateCount=%d, " - "pauiClientPRUpdateUFOAddress=0x%x, " - "ui32ClientPRUpdateValueCount=%d, " - "paui32ClientPRUpdateValue=0x%x", - __func__, __LINE__, ui32ClientPRUpdateCount, - pauiClientPRUpdateUFOAddress->ui32Addr, - ui32ClientPRUpdateValueCount, - (ui32ClientPRUpdateValueCount == 0) ? PVRSRV_SYNC_CHECKPOINT_SIGNALLED : *paui32ClientPRUpdateValue)); - } - - if (!bUseCombined3DAnd3DPR) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling RGXCmdHelperInitCmdCCB(), ui32ClientPRUpdateCount=%d", - __func__, ui32ClientPRUpdateCount)); - RGXCmdHelperInitCmdCCB_OtherData(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext), - 0, - NULL, - NULL, - ui32ClientPRUpdateCount, - pauiClientPRUpdateUFOAddress, - paui32ClientPRUpdateValue, - pui83DPRDMCmd ? ui323DPRCmdSize : ui323DCmdSize, // If the client has not provided a 3DPR command, the regular 3D command should be used instead - pui83DPRDMCmd ? pui83DPRDMCmd : pui83DDMCmd, - NULL, - NULL, - NULL, - RGXFWIF_CCB_CMD_TYPE_3D_PR, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, - NULL, - "3D-PR", - bCCBStateOpen, - &pas3DCmdHelperData[ui323DCmdCount++]); - } - } - - if (bKick3D || bAbort) - { - RGX_SERVER_RC_3D_DATA *ps3DData = &psRenderContext->s3DData; - const RGXFWIF_CCB_CMD_TYPE e3DCmdType = bAbort ? RGXFWIF_CCB_CMD_TYPE_ABORT : RGXFWIF_CCB_CMD_TYPE_3D; - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Prepare workload estimation */ - WorkEstPrepare(psRenderContext->psDeviceNode->pvDevice, - &psRenderContext->sWorkEstData, - &psRenderContext->sWorkEstData.uWorkloadMatchingData.sTA3D.sData3D, - e3DCmdType, - &sWorkloadCharacteristics, - ui64DeadlineInus, - &sWorkloadKickData3D); -#endif - - /* Init the 3D command helper */ - RGXCmdHelperInitCmdCCB_OtherData(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext), - bKickTA ? 0 : ui32Client3DFenceCount, /* For a kick with a TA, the 3D fences are added before the PR command instead */ - bKickTA ? NULL : pauiClient3DFenceUFOAddress, - NULL, - ui32Client3DUpdateCount, - pauiClient3DUpdateUFOAddress, - paui32Client3DUpdateValue, - ui323DCmdSize, - pui83DDMCmd, - (bKickTA ? NULL : &pPreAddr), - &pPostAddr, - &pRMWUFOAddr, - e3DCmdType, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - &sWorkloadKickData3D, -#else - NULL, -#endif - "3D", - bCCBStateOpen, - &pas3DCmdHelperData[ui323DCmdCount++]); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* The following are used to determine the offset of the command header containing the workload estimation - data so that can be accessed when the KCCB is read */ - ui323DCmdHeaderOffset = RGXCmdHelperGetDMCommandHeaderOffset(&pas3DCmdHelperData[ui323DCmdCount - 1]); - ui323DFullRenderCommandOffset = RGXCmdHelperGetCommandOffset(pas3DCmdHelperData, ui323DCmdCount - 1); -#endif - } - - /* Protect against array overflow in RGXCmdHelperAcquireCmdCCB() */ - if (unlikely(ui323DCmdCount > CCB_CMD_HELPER_NUM_3D_COMMANDS)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", __func__, eError)); - goto fail_3dcmdinit; - } - - if (ui323DCmdCount) - { - PVR_ASSERT(bKickPR || bKick3D); - - /* Acquire space for all the 3D command(s) */ - eError = RGXCmdHelperAcquireCmdCCB(ui323DCmdCount, pas3DCmdHelperData); - if (unlikely(eError != PVRSRV_OK)) - { - /* If RGXCmdHelperAcquireCmdCCB fails we skip the scheduling - * of a new TA command with the same Write offset in Kernel CCB. - */ - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", __func__, eError)); - goto fail_3dacquirecmd; - } - } - - /* - We should acquire the space in the kernel CCB here as after this point - we release the commands which will take operations on server syncs - which can't be undone - */ - - /* - Everything is ready to go now, release the commands - */ - if (ui32TACmdCount) - { - ui32TACmdOffset = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->sTAData.psServerCommonContext)); - RGXCmdHelperReleaseCmdCCB(ui32TACmdCount, - pasTACmdHelperData, - "TA", - FWCommonContextGetFWAddress(psRenderContext->sTAData.psServerCommonContext).ui32Addr); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - ui32TACmdOffsetWrapCheck = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->sTAData.psServerCommonContext)); - - /* This checks if the command would wrap around at the end of the CCB and therefore would start at an - offset of 0 rather than the current command offset */ - if (ui32TACmdOffset < ui32TACmdOffsetWrapCheck) - { - ui32TACommandOffset = ui32TACmdOffset; - } - else - { - ui32TACommandOffset = 0; - } -#endif - } - - if (ui323DCmdCount) - { - ui323DCmdOffset = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->s3DData.psServerCommonContext)); - RGXCmdHelperReleaseCmdCCB(ui323DCmdCount, - pas3DCmdHelperData, - "3D", - FWCommonContextGetFWAddress(psRenderContext->s3DData.psServerCommonContext).ui32Addr); - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - ui323DCmdOffsetWrapCheck = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->s3DData.psServerCommonContext)); - - if (ui323DCmdOffset < ui323DCmdOffsetWrapCheck) - { - ui323DCommandOffset = ui323DCmdOffset; - } - else - { - ui323DCommandOffset = 0; - } -#endif - } - - if (ui32TACmdCount) - { - IMG_UINT32 ui32FWCtx = FWCommonContextGetFWAddress(psRenderContext->sTAData.psServerCommonContext).ui32Addr; - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psRenderContext->sTAData.psServerCommonContext); - CMDTA3D_SHARED *psGeomCmdShared = IMG_OFFSET_ADDR(pui8TADMCmd, 0); - - sTACmdKickData.psContext = FWCommonContextGetFWAddress(psRenderContext->sTAData.psServerCommonContext); - sTACmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - sTACmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - - /* Add the Workload data into the KCCB kick */ -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Store the offset to the CCCB command header so that it can be referenced when the KCCB command reaches the FW */ - sTACmdKickData.ui32WorkEstCmdHeaderOffset = ui32TACommandOffset + ui32TACmdHeaderOffset; -#else - sTACmdKickData.ui32WorkEstCmdHeaderOffset = 0; -#endif - - eError = AttachKickResourcesCleanupCtls((PRGXFWIF_CLEANUP_CTL *) &sTACmdKickData.apsCleanupCtl, - &sTACmdKickData.ui32NumCleanupCtl, - RGXFWIF_DM_GEOM, - bKickTA, - psKMHWRTDataSet, - psZSBuffer, - psMSAAScratchBuffer); - if (unlikely(eError != PVRSRV_OK)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", - __func__, eError)); - goto fail_taattachcleanupctls; - } - - if (psGeomCmdShared) - { - HTBLOGK(HTB_SF_MAIN_KICK_TA, - sTACmdKickData.psContext, - ui32TACmdOffset, - psGeomCmdShared->sCmn.ui32FrameNum, - ui32ExtJobRef, - ui32IntJobRef - ); - } - - RGXSRV_HWPERF_ENQ(psRenderContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_TA, - iCheckTAFence, - iUpdateTAFence, - iUpdateTATimeline, - uiCheckTAFenceUID, - uiUpdateTAFenceUID, - ui64DeadlineInus, - WORKEST_CYCLES_PREDICTION_GET(sWorkloadKickDataTA)); - - if (!bUseSingleFWCommand) - { - /* Construct the kernel TA CCB command. */ - RGXFWIF_KCCB_CMD sTAKCCBCmd; - sTAKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - sTAKCCBCmd.uCmdData.sCmdKickData = sTACmdKickData; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psRenderContext->psDeviceNode->pvDevice, - RGXFWIF_DM_GEOM, - &sTAKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - } - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXKicKTA3DKM failed to schedule kernel CCB command. (0x%x)", eError2)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - goto fail_taacquirecmd; - } - - PVRGpuTraceEnqueueEvent(psRenderContext->psDeviceNode->pvDevice, - ui32FWCtx, ui32ExtJobRef, ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_TA3D); - } - - if (ui323DCmdCount) - { - RGXFWIF_KCCB_CMD s3DKCCBCmd = { 0 }; - IMG_UINT32 ui32FWCtx = FWCommonContextGetFWAddress(psRenderContext->s3DData.psServerCommonContext).ui32Addr; - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psRenderContext->s3DData.psServerCommonContext); - CMDTA3D_SHARED *ps3DCmdShared = IMG_OFFSET_ADDR(pui83DDMCmd, 0); - - s3DCmdKickData.psContext = FWCommonContextGetFWAddress(psRenderContext->s3DData.psServerCommonContext); - s3DCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - s3DCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - - /* Add the Workload data into the KCCB kick */ -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Store the offset to the CCCB command header so that it can be referenced when the KCCB command reaches the FW */ - s3DCmdKickData.ui32WorkEstCmdHeaderOffset = ui323DCommandOffset + ui323DCmdHeaderOffset + ui323DFullRenderCommandOffset; -#else - s3DCmdKickData.ui32WorkEstCmdHeaderOffset = 0; -#endif - - eError = AttachKickResourcesCleanupCtls((PRGXFWIF_CLEANUP_CTL *) &s3DCmdKickData.apsCleanupCtl, - &s3DCmdKickData.ui32NumCleanupCtl, - RGXFWIF_DM_3D, - bKick3D, - psKMHWRTDataSet, - psZSBuffer, - psMSAAScratchBuffer); - if (unlikely(eError != PVRSRV_OK)) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", - __func__, eError)); - goto fail_3dattachcleanupctls; - } - - if (ps3DCmdShared) - { - HTBLOGK(HTB_SF_MAIN_KICK_3D, - s3DCmdKickData.psContext, - ui323DCmdOffset, - ps3DCmdShared->sCmn.ui32FrameNum, - ui32ExtJobRef, - ui32IntJobRef - ); - } - - RGXSRV_HWPERF_ENQ(psRenderContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_3D, - iCheck3DFence, - iUpdate3DFence, - iUpdate3DTimeline, - uiCheck3DFenceUID, - uiUpdate3DFenceUID, - ui64DeadlineInus, - WORKEST_CYCLES_PREDICTION_GET(sWorkloadKickData3D)); - - if (bUseSingleFWCommand) - { - /* Construct the kernel TA/3D CCB command. */ - s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK; - s3DKCCBCmd.uCmdData.sCombinedTA3DCmdKickData.sTACmdKickData = sTACmdKickData; - s3DKCCBCmd.uCmdData.sCombinedTA3DCmdKickData.s3DCmdKickData = s3DCmdKickData; - } - else - { - /* Construct the kernel 3D CCB command. */ - s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - s3DKCCBCmd.uCmdData.sCmdKickData = s3DCmdKickData; - } - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psRenderContext->psDeviceNode->pvDevice, - RGXFWIF_DM_3D, - &s3DKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - } - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXKicKTA3DKM failed to schedule kernel CCB command. (0x%x)", eError2)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - } - - /* - * Now check eError (which may have returned an error from our earlier calls - * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first - * so we check it now... - */ - if (unlikely(eError != PVRSRV_OK )) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Failed, eError=%d, Line", - __func__, eError)); - goto fail_3dacquirecmd; - } - -#if defined(NO_HARDWARE) - /* If NO_HARDWARE, signal the output fence's sync checkpoint and sync prim */ - if (psUpdateTASyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Signalling NOHW sync checkpoint [TA] <%p>, ID:%d, FwAddr=0x%x", - __func__, (void*)psUpdateTASyncCheckpoint, - SyncCheckpointGetId(psUpdateTASyncCheckpoint), - SyncCheckpointGetFirmwareAddr(psUpdateTASyncCheckpoint))); - SyncCheckpointSignalNoHW(psUpdateTASyncCheckpoint); - } - if (psTAFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Updating NOHW sync prim [TA] <%p> to %d", - __func__, (void*)psTAFenceTimelineUpdateSync, - ui32TAFenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(psTAFenceTimelineUpdateSync, ui32TAFenceTimelineUpdateValue); - } - - if (psUpdate3DSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Signalling NOHW sync checkpoint [3D] <%p>, ID:%d, FwAddr=0x%x", - __func__, (void*)psUpdate3DSyncCheckpoint, - SyncCheckpointGetId(psUpdate3DSyncCheckpoint), - SyncCheckpointGetFirmwareAddr(psUpdate3DSyncCheckpoint))); - SyncCheckpointSignalNoHW(psUpdate3DSyncCheckpoint); - } - if (ps3DFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: Updating NOHW sync prim [3D] <%p> to %d", - __func__, (void*)ps3DFenceTimelineUpdateSync, - ui323DFenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(ps3DFenceTimelineUpdateSync, ui323DFenceTimelineUpdateValue); - } - SyncCheckpointNoHWUpdateTimelines(NULL); - -#endif /* defined(NO_HARDWARE) */ - -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - CHKPT_DBG((PVR_DBG_ERROR, - "%s: calling pvr_buffer_sync_kick_succeeded(psBufferSyncData=<%p>)...", - __func__, (void*)psBufferSyncData)); - pvr_buffer_sync_kick_succeeded(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - if (piUpdateTAFence) - { - *piUpdateTAFence = iUpdateTAFence; - } - if (piUpdate3DFence) - { - *piUpdate3DFence = iUpdate3DFence; - } - - /* Drop the references taken on the sync checkpoints in the - * resolved input fence. - * NOTE: 3D fence is always submitted, either via 3D or TA(PR). - */ - if (bKickTA) - { - SyncAddrListDeRefCheckpoints(ui32FenceTASyncCheckpointCount, apsFenceTASyncCheckpoints); - } - SyncAddrListDeRefCheckpoints(ui32Fence3DSyncCheckpointCount, apsFence3DSyncCheckpoints); - - if (pvTAUpdateFenceFinaliseData && (iUpdateTAFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psRenderContext->psDeviceNode, iUpdateTAFence, - pvTAUpdateFenceFinaliseData, - psUpdateTASyncCheckpoint, szFenceNameTA); - } - if (pv3DUpdateFenceFinaliseData && (iUpdate3DFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psRenderContext->psDeviceNode, iUpdate3DFence, - pv3DUpdateFenceFinaliseData, - psUpdate3DSyncCheckpoint, szFenceName3D); - } - - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceTASyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceTASyncCheckpoints); - } - if (apsFence3DSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFence3DSyncCheckpoints); - } - - if (sTASyncData.paui32ClientUpdateValue) - { - OSFreeMem(sTASyncData.paui32ClientUpdateValue); - } - if (s3DSyncData.paui32ClientUpdateValue) - { - OSFreeMem(s3DSyncData.paui32ClientUpdateValue); - } - -#if defined(SUPPORT_VALIDATION) - if (bTestSLRAdd3DCheck) - { - SyncCheckpointFree(psDummySyncCheckpoint); - } -#endif - OSLockRelease(psRenderContext->hLock); - - return PVRSRV_OK; - -fail_3dattachcleanupctls: -fail_taattachcleanupctls: -fail_3dacquirecmd: -fail_3dcmdinit: -fail_taacquirecmd: - SyncAddrListRollbackCheckpoints(psRenderContext->psDeviceNode, &psRenderContext->sSyncAddrListTAFence); - SyncAddrListRollbackCheckpoints(psRenderContext->psDeviceNode, &psRenderContext->sSyncAddrListTAUpdate); - SyncAddrListRollbackCheckpoints(psRenderContext->psDeviceNode, &psRenderContext->sSyncAddrList3DFence); - SyncAddrListRollbackCheckpoints(psRenderContext->psDeviceNode, &psRenderContext->sSyncAddrList3DUpdate); - /* Where a TA-only kick (ie no 3D) is submitted, the PR update will make use of the unused 3DUpdate list. - * If this has happened, performing a rollback on pauiClientPRUpdateUFOAddress will simply repeat what - * has already been done for the sSyncAddrList3DUpdate above and result in a double decrement of the - * sync checkpoint's hEnqueuedCCBCount, so we need to check before rolling back the PRUpdate. - */ - if (pauiClientPRUpdateUFOAddress && (pauiClientPRUpdateUFOAddress != psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs)) - { - SyncCheckpointRollbackFromUFO(psRenderContext->psDeviceNode, pauiClientPRUpdateUFOAddress->ui32Addr); - } - -fail_alloc_update_values_mem_3D: - if (iUpdate3DFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(iUpdate3DFence, pv3DUpdateFenceFinaliseData); - } -fail_create_3d_fence: -fail_alloc_update_values_mem_TA: - if (iUpdateTAFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(iUpdateTAFence, pvTAUpdateFenceFinaliseData); - } -fail_create_ta_fence: -#if !defined(SUPPORT_BUFFER_SYNC) -err_no_buffer_sync_invalid_params: -#endif /* !defined(SUPPORT_BUFFER_SYNC) */ -err_pr_fence_address: -err_populate_sync_addr_list_3d_update: -err_populate_sync_addr_list_3d_fence: -err_populate_sync_addr_list_ta_update: -err_populate_sync_addr_list_ta_fence: -err_not_enough_space: - /* Drop the references taken on the sync checkpoints in the - * resolved input fence. - * NOTE: 3D fence is always submitted, either via 3D or TA(PR). - */ -#if defined(SUPPORT_BUFFER_SYNC) - SyncAddrListDeRefCheckpoints(ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); -#endif - SyncAddrListDeRefCheckpoints(ui32Fence3DSyncCheckpointCount, apsFence3DSyncCheckpoints); -fail_resolve_input_3d_fence: - if (bKickTA) - { - SyncAddrListDeRefCheckpoints(ui32FenceTASyncCheckpointCount, apsFenceTASyncCheckpoints); - } -fail_resolve_input_ta_fence: - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceTASyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceTASyncCheckpoints); - } - if (apsFence3DSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFence3DSyncCheckpoints); - } - if (sTASyncData.paui32ClientUpdateValue) - { - OSFreeMem(sTASyncData.paui32ClientUpdateValue); - } - if (s3DSyncData.paui32ClientUpdateValue) - { - OSFreeMem(s3DSyncData.paui32ClientUpdateValue); - } -#if defined(SUPPORT_VALIDATION) - if (bTestSLRAdd3DCheck) - { - SyncCheckpointFree(psDummySyncCheckpoint); - } -#endif -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_failed(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - PVR_ASSERT(eError != PVRSRV_OK); - OSLockRelease(psRenderContext->hLock); - return eError; -} - -PVRSRV_ERROR PVRSRVRGXSetRenderContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - RGX_SERVER_RENDER_CONTEXT *psRenderContext, - IMG_UINT32 ui32Priority) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - - OSLockAcquire(psRenderContext->hLock); - - if (psRenderContext->sTAData.ui32Priority != ui32Priority) - { - eError = ContextSetPriority(psRenderContext->sTAData.psServerCommonContext, - psConnection, - psRenderContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_GEOM); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to set the priority of the TA part of the rendercontext (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto fail_tacontext; - } - psRenderContext->sTAData.ui32Priority = ui32Priority; - } - - if (psRenderContext->s3DData.ui32Priority != ui32Priority) - { - eError = ContextSetPriority(psRenderContext->s3DData.psServerCommonContext, - psConnection, - psRenderContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_3D); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to set the priority of the 3D part of the rendercontext (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto fail_3dcontext; - } - psRenderContext->s3DData.ui32Priority = ui32Priority; - } - - OSLockRelease(psRenderContext->hLock); - return PVRSRV_OK; - -fail_3dcontext: -fail_tacontext: - OSLockRelease(psRenderContext->hLock); - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -PVRSRV_ERROR PVRSRVRGXSetRenderContextPropertyKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (eContextProperty) - { - case RGX_CONTEXT_PROPERTY_FLAGS: - { - IMG_UINT32 ui32ContextFlags = (IMG_UINT32)ui64Input; - - OSLockAcquire(psRenderContext->hLock); - eError = FWCommonContextSetFlags(psRenderContext->sTAData.psServerCommonContext, - ui32ContextFlags); - if (eError == PVRSRV_OK) - { - eError = FWCommonContextSetFlags(psRenderContext->s3DData.psServerCommonContext, - ui32ContextFlags); - } - OSLockRelease(psRenderContext->hLock); - break; - } - - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_ERROR_NOT_SUPPORTED - asked to set unknown property (%d)", __func__, eContextProperty)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - } - - return eError; -} - - -void DumpRenderCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - DLLIST_NODE *psNode, *psNext; - OSWRLockAcquireRead(psDevInfo->hRenderCtxListLock); - dllist_foreach_node(&psDevInfo->sRenderCtxtListHead, psNode, psNext) - { - RGX_SERVER_RENDER_CONTEXT *psCurrentServerRenderCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_RENDER_CONTEXT, sListNode); - - DumpFWCommonContextInfo(psCurrentServerRenderCtx->sTAData.psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - DumpFWCommonContextInfo(psCurrentServerRenderCtx->s3DData.psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - OSWRLockReleaseRead(psDevInfo->hRenderCtxListLock); -} - -IMG_UINT32 CheckForStalledClientRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - DLLIST_NODE *psNode, *psNext; - IMG_UINT32 ui32ContextBitMask = 0; - - OSWRLockAcquireRead(psDevInfo->hRenderCtxListLock); - - dllist_foreach_node(&psDevInfo->sRenderCtxtListHead, psNode, psNext) - { - RGX_SERVER_RENDER_CONTEXT *psCurrentServerRenderCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_RENDER_CONTEXT, sListNode); - if (NULL != psCurrentServerRenderCtx->sTAData.psServerCommonContext) - { - if (CheckStalledClientCommonContext(psCurrentServerRenderCtx->sTAData.psServerCommonContext, RGX_KICK_TYPE_DM_TA) == PVRSRV_ERROR_CCCB_STALLED) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_TA; - } - } - - if (NULL != psCurrentServerRenderCtx->s3DData.psServerCommonContext) - { - if (CheckStalledClientCommonContext(psCurrentServerRenderCtx->s3DData.psServerCommonContext, RGX_KICK_TYPE_DM_3D) == PVRSRV_ERROR_CCCB_STALLED) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_3D; - } - } - } - - OSWRLockReleaseRead(psDevInfo->hRenderCtxListLock); - return ui32ContextBitMask; -} - -/* - * RGXRenderContextStalledKM - */ -PVRSRV_ERROR RGXRenderContextStalledKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext) -{ - RGXCheckForStalledClientContexts((PVRSRV_RGXDEV_INFO *) psRenderContext->psDeviceNode->pvDevice, IMG_TRUE); - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (rgxta3d.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxta3d.h b/drivers/gpu/drm/img-rogue/1.17/rgxta3d.h deleted file mode 100644 index 305bbd15b8f31..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxta3d.h +++ /dev/null @@ -1,522 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX TA and 3D Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX TA and 3D Functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RGXTA3D_H -#define RGXTA3D_H - -#include "devicemem.h" -#include "devicemem_server.h" -#include "device.h" -#include "rgxdevice.h" -#include "rgx_fwif_shared.h" -#include "rgx_fwif_resetframework.h" -#include "sync_server.h" -#include "connection_server.h" -#include "rgxdebug.h" -#include "pvr_notifier.h" - -typedef struct _RGX_SERVER_RENDER_CONTEXT_ RGX_SERVER_RENDER_CONTEXT; -typedef struct _RGX_FREELIST_ RGX_FREELIST; -typedef struct _RGX_PMR_NODE_ RGX_PMR_NODE; - -/***************************************************************************** - * The Design of Data Storage System for Render Targets * - * ==================================================== * - * Relevant for * - * understanding RGXCreateHWRTDataSet & RGXDestroyHWRTDataSet * - * * - * * - * +=========================================+ * - * | RenderTargetDataSet | * - * +---------------|---------|---------------+ * - * | | * - * V V * - * +- - - - - - - - - - - - + +- - - - - - - - - - - - + * - * | KM_HW_RT_DATA_HANDLE_0 | | KM_HW_RT_DATA_HANDLE_1 | * - * +- - -|- - - - - - - - - + +- - - - - - - - - | - - + * - * | | * - * | | [UM]Client * - * ------|-----------------------------------------|----------------------- * - * | | Bridge * - * ------|-----------------------------------------|----------------------- * - * | | [KM]Server * - * | | * - * | KM-ptr | KM-ptr * - * V V * - * +====================+ +====================+ * - * | KM_HW_RT_DATA_0 | | KM_HW_RT_DATA_1 | * - * +-----|------------|-+ +-|------------|-----+ * - * | | | | * - * | | | | * - * | | | | * - * | | | | * - * | | KM-ptr | KM-ptr | * - * | V V | * - * | +==========================+ | * - * | | HW_RT_DATA_COMMON_COOKIE | | * - * | +--------------------------+ | * - * | | | * - * | | | * - * ------|-------------------|---------------------|----------------------- * - * | | | [FW]Firmware * - * | | | * - * | FW-addr | | FW-addr * - * V | V * - * +===============+ | +===============+ * - * | HW_RT_DATA_0 | | | HW_RT_DATA_1 | * - * +------------|--+ | +--|------------+ * - * | | | * - * | FW-addr | FW-addr | FW-addr * - * V V V * - * +=========================================+ * - * | HW_RT_DATA_COMMON | * - * +-----------------------------------------+ * - * * - *****************************************************************************/ - -typedef struct _RGX_HWRTDATA_COMMON_COOKIE_ -{ - DEVMEM_MEMDESC *psHWRTDataCommonFwMemDesc; - RGXFWIF_DEV_VIRTADDR sHWRTDataCommonFwAddr; - IMG_UINT32 ui32RefCount; - -} RGX_HWRTDATA_COMMON_COOKIE; - -typedef struct _RGX_KM_HW_RT_DATASET_ -{ - RGX_HWRTDATA_COMMON_COOKIE *psHWRTDataCommonCookie; - - PVRSRV_DEVICE_NODE *psDeviceNode; - RGXFWIF_DEV_VIRTADDR sHWRTDataFwAddr; - - DEVMEM_MEMDESC *psHWRTDataFwMemDesc; - DEVMEM_MEMDESC *psRTArrayFwMemDesc; - DEVMEM_MEMDESC *psRendersAccArrayFwMemDesc; - - RGX_FREELIST *apsFreeLists[RGXFW_MAX_FREELISTS]; -#if !defined(SUPPORT_SHADOW_FREELISTS) - DLLIST_NODE sNodeHWRTData; -#endif - -} RGX_KM_HW_RT_DATASET; - -struct _RGX_FREELIST_ { - PVRSRV_RGXDEV_INFO *psDevInfo; - CONNECTION_DATA *psConnection; - - /* Free list PMR */ - PMR *psFreeListPMR; - IMG_DEVMEM_OFFSET_T uiFreeListPMROffset; - - DEVMEMINT_RESERVATION2* psFreeListReservation; - - /* Freelist config */ - IMG_UINT32 ui32MaxFLPages; - IMG_UINT32 ui32InitFLPages; - IMG_UINT32 ui32CurrentFLPages; - IMG_UINT32 ui32GrowFLPages; - IMG_UINT32 ui32ReadyFLPages; - IMG_UINT32 ui32GrowThreshold; /* Percentage of FL memory used that should trigger a new grow request */ - IMG_UINT32 ui32FreelistID; - IMG_UINT32 ui32FreelistGlobalID; /* related global freelist for this freelist */ - IMG_UINT64 ui64FreelistChecksum; /* checksum over freelist content */ - IMG_BOOL bCheckFreelist; /* freelist check enabled */ - IMG_UINT32 ui32RefCount; /* freelist reference counting */ - - IMG_UINT32 ui32NumGrowReqByApp; /* Total number of grow requests by Application */ - IMG_UINT32 ui32NumGrowReqByFW; /* Total Number of grow requests by Firmware */ - IMG_UINT32 ui32NumHighPages; /* High Mark of pages in the freelist */ - - IMG_PID ownerPid; /* Pid of the owner of the list */ - - /* Memory Blocks */ - DLLIST_NODE sMemoryBlockHead; - DLLIST_NODE sMemoryBlockInitHead; - DLLIST_NODE sNode; -#if !defined(SUPPORT_SHADOW_FREELISTS) - /* HWRTData nodes linked to local freelist */ - DLLIST_NODE sNodeHWRTDataHead; -#endif - - /* FW data structures */ - DEVMEM_MEMDESC *psFWFreelistMemDesc; - RGXFWIF_DEV_VIRTADDR sFreeListFWDevVAddr; -}; - -struct _RGX_PMR_NODE_ { - RGX_FREELIST *psFreeList; - PMR *psPMR; - PMR_PAGELIST *psPageList; - DLLIST_NODE sMemoryBlock; - IMG_UINT32 ui32NumPages; - IMG_BOOL bFirstPageMissing; -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - RI_HANDLE hRIHandle; -#endif -}; - -typedef struct { - PVRSRV_RGXDEV_INFO *psDevInfo; - DEVMEM_MEMDESC *psFWZSBufferMemDesc; - RGXFWIF_DEV_VIRTADDR sZSBufferFWDevVAddr; - - DEVMEMINT_RESERVATION2 *psReservation; - PMR *psPMR; - IMG_UINT32 ui32ZSBufferID; - IMG_UINT32 ui32RefCount; - IMG_BOOL bOnDemand; - - IMG_BOOL ui32NumReqByApp; /* Number of Backing Requests from Application */ - IMG_BOOL ui32NumReqByFW; /* Number of Backing Requests from Firmware */ - - IMG_PID owner; - - DLLIST_NODE sNode; -}RGX_ZSBUFFER_DATA; - -typedef struct { - RGX_ZSBUFFER_DATA *psZSBuffer; -} RGX_POPULATION; - -/* Dump the physical pages of a freelist */ -IMG_BOOL RGXDumpFreeListPageList(RGX_FREELIST *psFreeList); - - -/* Create set of HWRTData(s) */ -PVRSRV_ERROR RGXCreateHWRTDataSet(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR asVHeapTableDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_DEV_VIRTADDR psPMMListDevVAddr[RGXMKIF_NUM_RTDATAS], - RGX_FREELIST *apsFreeLists[RGXMKIF_NUM_RTDATA_FREELISTS], - IMG_UINT32 ui32ScreenPixelMax, - IMG_UINT64 ui64MultiSampleCtl, - IMG_UINT64 ui64FlippedMultiSampleCtl, - IMG_UINT32 ui32TPCStride, - IMG_DEV_VIRTADDR asTailPtrsDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_UINT32 ui32TPCSize, - IMG_UINT32 ui32TEScreen, - IMG_UINT32 ui32TEAA, - IMG_UINT32 ui32TEMTILE1, - IMG_UINT32 ui32TEMTILE2, - IMG_UINT32 ui32MTileStride, - IMG_UINT32 ui32ISPMergeLowerX, - IMG_UINT32 ui32ISPMergeLowerY, - IMG_UINT32 ui32ISPMergeUpperX, - IMG_UINT32 ui32ISPMergeUpperY, - IMG_UINT32 ui32ISPMergeScaleX, - IMG_UINT32 ui32ISPMergeScaleY, - IMG_DEV_VIRTADDR sMacrotileArrayDevVAddr[RGXMKIF_NUM_RTDATAS], - IMG_DEV_VIRTADDR sRgnHeaderDevVAddr[RGXMKIF_NUM_RTDATAS], - IMG_DEV_VIRTADDR asRTCDevVAddr[RGXMKIF_NUM_GEOMDATAS], - IMG_UINT32 uiRgnHeaderSize, - IMG_UINT32 ui32ISPMtileSize, - IMG_UINT16 ui16MaxRTs, - RGX_KM_HW_RT_DATASET *pasKMHWRTDataSet[RGXMKIF_NUM_RTDATAS]); - -/* Destroy HWRTDataSet */ -PVRSRV_ERROR RGXDestroyHWRTDataSet(RGX_KM_HW_RT_DATASET *psKMHWRTDataSet); - -/* - RGXCreateZSBufferKM -*/ -PVRSRV_ERROR RGXCreateZSBufferKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_RESERVATION *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - RGX_ZSBUFFER_DATA **ppsZSBuffer); - -PVRSRV_ERROR RGXCreateZSBufferKM2(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEMINT_RESERVATION2 *psReservation, - PMR *psPMR, - PVRSRV_MEMALLOCFLAGS_T uiMapFlags, - RGX_ZSBUFFER_DATA **ppsZSBuffer); - -/* - RGXDestroyZSBufferKM -*/ -PVRSRV_ERROR RGXDestroyZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer); - - -/* - * RGXBackingZSBuffer() - * - * Backs ZS-Buffer with physical pages - */ -PVRSRV_ERROR -RGXBackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer); - -/* - * RGXPopulateZSBufferKM() - * - * Backs ZS-Buffer with physical pages (called by Bridge calls) - */ -PVRSRV_ERROR RGXPopulateZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_POPULATION **ppsPopulation); - -/* - * RGXUnbackingZSBuffer() - * - * Frees ZS-Buffer's physical pages - */ -PVRSRV_ERROR RGXUnbackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer); - -/* - * RGXUnpopulateZSBufferKM() - * - * Frees ZS-Buffer's physical pages (called by Bridge calls) - */ -PVRSRV_ERROR RGXUnpopulateZSBufferKM(RGX_POPULATION *psPopulation); - -/* - RGXProcessRequestZSBufferBacking -*/ -void RGXProcessRequestZSBufferBacking(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32ZSBufferID); - -/* - RGXProcessRequestZSBufferUnbacking -*/ -void RGXProcessRequestZSBufferUnbacking(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32ZSBufferID); - -/* - RGXGrowFreeList -*/ -PVRSRV_ERROR RGXGrowFreeList(RGX_FREELIST *psFreeList, - IMG_UINT32 ui32NumPages, - PDLLIST_NODE pListHeader); - -/* Create free list */ -PVRSRV_ERROR RGXCreateFreeList(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32MaxFLPages, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32GrowFLPages, - IMG_UINT32 ui32GrowParamThreshold, - RGX_FREELIST *psGlobalFreeList, - IMG_BOOL bCheckFreelist, - IMG_DEV_VIRTADDR sFreeListDevVAddr, - PMR *psFreeListPMR, - IMG_DEVMEM_OFFSET_T uiFreeListPMROffset, - RGX_FREELIST **ppsFreeList); - -/* Create free list */ -PVRSRV_ERROR RGXCreateFreeList2(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32MaxFLPages, - IMG_UINT32 ui32InitFLPages, - IMG_UINT32 ui32GrowFLPages, - IMG_UINT32 ui32GrowParamThreshold, - RGX_FREELIST *psGlobalFreeList, - IMG_BOOL bCheckFreelist, - DEVMEMINT_RESERVATION2* psFreeListReservation, - RGX_FREELIST **ppsFreeList); - -/* Destroy free list */ -PVRSRV_ERROR RGXDestroyFreeList(RGX_FREELIST *psFreeList); - -/* - RGXProcessRequestGrow -*/ -void RGXProcessRequestGrow(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FreelistID); - - -/* Reconstruct free list after Hardware Recovery */ -void RGXProcessRequestFreelistsReconstruction(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32FreelistsCount, - const IMG_UINT32 *paui32Freelists); - -/*! -******************************************************************************* - - @Function PVRSRVRGXCreateRenderContextKM - - @Description - Server-side implementation of RGXCreateRenderContext - - @Input psConnection - - @Input psDeviceNode - device node - @Input ui32Priority - context priority - @Input sVDMCallStackAddr - VDM call stack device virtual address - @Input ui32CallStackDepth - VDM call stack depth - @Input ui32FrameworkCommandSize - framework command size - @Input pabyFrameworkCommand - ptr to framework command - @Input hMemCtxPrivData - memory context private data - @Input ui32StaticRenderContextStateSize - size of fixed render state - @Input pStaticRenderContextState - ptr to fixed render state buffer - @Input ui32PackedCCBSizeU8888 : - ui8TACCBAllocSizeLog2 - TA CCB size - ui8TACCBMaxAllocSizeLog2 - maximum size to which TA CCB can grow - ui83DCCBAllocSizeLog2 - 3D CCB size - ui83DCCBMaxAllocSizeLog2 - maximum size to which 3D CCB can grow - @Input ui32ContextFlags - flags which specify properties of the context - @Output ppsRenderContext - - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXCreateRenderContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_DEV_VIRTADDR sVDMCallStackAddr, - IMG_UINT32 ui32CallStackDepth, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pabyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32StaticRenderContextStateSize, - IMG_PBYTE pStaticRenderContextState, - IMG_UINT32 ui32PackedCCBSizeU8888, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - IMG_UINT32 ui32MaxTADeadlineMS, - IMG_UINT32 ui32Max3DDeadlineMS, - RGX_SERVER_RENDER_CONTEXT **ppsRenderContext); - - -/*! -******************************************************************************* - - @Function PVRSRVRGXDestroyRenderContextKM - - @Description - Server-side implementation of RGXDestroyRenderContext - - @Input psRenderContext - - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext); - - -/*! -******************************************************************************* - - @Function PVRSRVRGXKickTA3DKM - - @Description - Server-side implementation of RGXKickTA3D - - @Input psRTDataCleanup - RT data associated with the kick (or NULL) - @Input psZBuffer - Z-buffer associated with the kick (or NULL) - @Input psSBuffer - S-buffer associated with the kick (or NULL) - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, - IMG_UINT32 ui32ClientTAFenceCount, - SYNC_PRIMITIVE_BLOCK **apsClientTAFenceSyncPrimBlock, - IMG_UINT32 *paui32ClientTAFenceSyncOffset, - IMG_UINT32 *paui32ClientTAFenceValue, - IMG_UINT32 ui32ClientTAUpdateCount, - SYNC_PRIMITIVE_BLOCK **apsClientUpdateSyncPrimBlock, - IMG_UINT32 *paui32ClientUpdateSyncOffset, - IMG_UINT32 *paui32ClientTAUpdateValue, - IMG_UINT32 ui32Client3DUpdateCount, - SYNC_PRIMITIVE_BLOCK **apsClient3DUpdateSyncPrimBlock, - IMG_UINT32 *paui32Client3DUpdateSyncOffset, - IMG_UINT32 *paui32Client3DUpdateValue, - SYNC_PRIMITIVE_BLOCK *psPRSyncPrimBlock, - IMG_UINT32 ui32PRSyncOffset, - IMG_UINT32 ui32PRFenceValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE *piUpdateFence, - IMG_CHAR szFenceName[PVRSRV_SYNC_NAME_LENGTH], - PVRSRV_FENCE iCheckFence3D, - PVRSRV_TIMELINE iUpdateTimeline3D, - PVRSRV_FENCE *piUpdateFence3D, - IMG_CHAR szFenceName3D[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32TACmdSize, - IMG_PBYTE pui8TADMCmd, - IMG_UINT32 ui323DPRCmdSize, - IMG_PBYTE pui83DPRDMCmd, - IMG_UINT32 ui323DCmdSize, - IMG_PBYTE pui83DDMCmd, - IMG_UINT32 ui32ExtJobRef, - IMG_BOOL bKickTA, - IMG_BOOL bKickPR, - IMG_BOOL bKick3D, - IMG_BOOL bAbort, - IMG_UINT32 ui32PDumpFlags, - RGX_KM_HW_RT_DATASET *psKMHWRTDataSet, - RGX_ZSBUFFER_DATA *psZSBuffer, - RGX_ZSBUFFER_DATA *psMSAAScratchBuffer, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs, - IMG_UINT32 ui32RenderTargetSize, - IMG_UINT32 ui32NumberOfDrawCalls, - IMG_UINT32 ui32NumberOfIndices, - IMG_UINT32 ui32NumberOfMRTs, - IMG_UINT64 ui64DeadlineInus); - - -PVRSRV_ERROR PVRSRVRGXSetRenderContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - RGX_SERVER_RENDER_CONTEXT *psRenderContext, - IMG_UINT32 ui32Priority); - -PVRSRV_ERROR PVRSRVRGXSetRenderContextPropertyKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output); - -/* Debug - Dump debug info of render contexts on this device */ -void DumpRenderCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/* Debug/Watchdog - check if client contexts are stalled */ -IMG_UINT32 CheckForStalledClientRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); - -PVRSRV_ERROR RGXRenderContextStalledKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext); - -#endif /* RGXTA3D_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.c b/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.c deleted file mode 100644 index a6671476362b5..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.c +++ /dev/null @@ -1,1329 +0,0 @@ -/*************************************************************************/ /*! -@File rgxtdmtransfer.c -@Title Device specific TDM transfer queue routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pdump_km.h" -#include "rgxdevice.h" -#include "rgxccb.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgxtdmtransfer.h" -#include "rgx_tq_shared.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "osfunc.h" -#include "pvr_debug.h" -#include "pvrsrv.h" -#include "rgx_fwif_resetframework.h" -#include "rgx_memallocflags.h" -#include "rgxhwperf.h" -#include "ospvr_gputrace.h" -#include "htbuffer.h" -#include "rgxshader.h" - -#include "pdump_km.h" - -#include "sync_server.h" -#include "sync_internal.h" -#include "sync.h" - -#if defined(SUPPORT_BUFFER_SYNC) -#include "pvr_buffer_sync.h" -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) -#include "rgxworkest.h" -#endif - -#include "rgxtimerquery.h" - -/* Enable this to dump the compiled list of UFOs prior to kick call */ -#define ENABLE_TDM_UFO_DUMP 0 - -//#define TDM_CHECKPOINT_DEBUG 1 - -#if defined(TDM_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -#else -#define CHKPT_DBG(X) -#endif - -typedef struct { - RGX_SERVER_COMMON_CONTEXT * psServerCommonContext; - IMG_UINT32 ui32Priority; -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif -} RGX_SERVER_TQ_TDM_DATA; - - -struct _RGX_SERVER_TQ_TDM_CONTEXT_ { - PVRSRV_DEVICE_NODE *psDeviceNode; - DEVMEM_MEMDESC *psFWFrameworkMemDesc; - DEVMEM_MEMDESC *psFWTransferContextMemDesc; - IMG_UINT32 ui32Flags; - RGX_SERVER_TQ_TDM_DATA sTDMData; - DLLIST_NODE sListNode; - SYNC_ADDR_LIST sSyncAddrListFence; - SYNC_ADDR_LIST sSyncAddrListUpdate; - POS_LOCK hLock; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - WORKEST_HOST_DATA sWorkEstData; -#endif -}; - -static PVRSRV_ERROR _CreateTDMTransferContext( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - DEVMEM_MEMDESC * psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC * psFWMemContextMemDesc, - IMG_UINT32 ui32Priority, - RGX_COMMON_CONTEXT_INFO * psInfo, - RGX_SERVER_TQ_TDM_DATA * psTDMData, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress) -{ - PVRSRV_ERROR eError; - -#if defined(SUPPORT_BUFFER_SYNC) - psTDMData->psBufferSyncContext = - pvr_buffer_sync_context_create(psDeviceNode->psDevConfig->pvOSDevice, - "rogue-tdm"); - if (IS_ERR(psTDMData->psBufferSyncContext)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create buffer_sync context (err=%ld)", - __func__, PTR_ERR(psTDMData->psBufferSyncContext))); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_buffer_sync_context_create; - } -#endif - - eError = FWCommonContextAllocate( - psConnection, - psDeviceNode, - REQ_TYPE_TQ_TDM, - RGXFWIF_DM_TDM, - NULL, - psAllocatedMemDesc, - ui32AllocatedOffset, - psFWMemContextMemDesc, - NULL, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_TDM_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_TDM_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - UINT_MAX, /* max deadline MS */ - ui64RobustnessAddress, - psInfo, - &psTDMData->psServerCommonContext); - if (eError != PVRSRV_OK) - { - goto fail_contextalloc; - } - - psTDMData->ui32Priority = ui32Priority; - return PVRSRV_OK; - -fail_contextalloc: -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(psTDMData->psBufferSyncContext); - psTDMData->psBufferSyncContext = NULL; -fail_buffer_sync_context_create: -#endif - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -static PVRSRV_ERROR _DestroyTDMTransferContext( - RGX_SERVER_TQ_TDM_DATA * psTDMData, - PVRSRV_DEVICE_NODE * psDeviceNode) -{ - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp( - psDeviceNode, - psTDMData->psServerCommonContext, - RGXFWIF_DM_TDM, - PDUMP_FLAGS_CONTINUOUS); - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free it's resources */ - FWCommonContextFree(psTDMData->psServerCommonContext); - -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(psTDMData->psBufferSyncContext); - psTDMData->psBufferSyncContext = NULL; -#endif - - return PVRSRV_OK; -} - -/* - * PVRSRVCreateTransferContextKM - */ -PVRSRV_ERROR PVRSRVRGXTDMCreateTransferContextKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pabyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - RGX_SERVER_TQ_TDM_CONTEXT ** ppsTransferContext) -{ - RGX_SERVER_TQ_TDM_CONTEXT * psTransferContext; - - DEVMEM_MEMDESC * psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - PVRSRV_RGXDEV_INFO * psDevInfo = psDeviceNode->pvDevice; - RGX_COMMON_CONTEXT_INFO sInfo = {NULL}; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Allocate the server side structure */ - *ppsTransferContext = NULL; - psTransferContext = OSAllocZMem(sizeof(*psTransferContext)); - if (psTransferContext == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* - Create the FW transfer context, this has the TDM common - context embedded within it - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_FWTDMCONTEXT), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwTransferContext", - &psTransferContext->psFWTransferContextMemDesc); - if (eError != PVRSRV_OK) - { - goto fail_fwtransfercontext; - } - - eError = OSLockCreate(&psTransferContext->hLock); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_lockcreate; - } - - psTransferContext->psDeviceNode = psDeviceNode; - - if (ui32FrameworkCommandSize) - { - /* - * Create the FW framework buffer - */ - eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, - &psTransferContext->psFWFrameworkMemDesc, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU framework state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcreate; - } - - /* Copy the Framework client data into the framework buffer */ - eError = PVRSRVRGXFrameworkCopyCommand(psDeviceNode, - psTransferContext->psFWFrameworkMemDesc, - pabyFrameworkCommand, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to populate the framework buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcopy; - } - - sInfo.psFWFrameworkMemDesc = psTransferContext->psFWFrameworkMemDesc; - } - - eError = _CreateTDMTransferContext(psConnection, - psDeviceNode, - psTransferContext->psFWTransferContextMemDesc, - offsetof(RGXFWIF_FWTDMCONTEXT, sTDMContext), - psFWMemContextMemDesc, - ui32Priority, - &sInfo, - &psTransferContext->sTDMData, - U32toU8_Unpack1(ui32PackedCCBSizeU88), - U32toU8_Unpack2(ui32PackedCCBSizeU88), - ui32ContextFlags, - ui64RobustnessAddress); - if (eError != PVRSRV_OK) - { - goto fail_tdmtransfercontext; - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - WorkEstInitTDM(psDevInfo, &psTransferContext->sWorkEstData); - } -#endif - - SyncAddrListInit(&psTransferContext->sSyncAddrListFence); - SyncAddrListInit(&psTransferContext->sSyncAddrListUpdate); - - OSWRLockAcquireWrite(psDevInfo->hTDMCtxListLock); - dllist_add_to_tail(&(psDevInfo->sTDMCtxtListHead), &(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTDMCtxListLock); - *ppsTransferContext = psTransferContext; - - return PVRSRV_OK; - -fail_tdmtransfercontext: -fail_frameworkcopy: - if (psTransferContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWFrameworkMemDesc); - } -fail_frameworkcreate: - OSLockDestroy(psTransferContext->hLock); -fail_lockcreate: - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWTransferContextMemDesc); -fail_fwtransfercontext: - OSFreeMem(psTransferContext); - PVR_ASSERT(eError != PVRSRV_OK); - *ppsTransferContext = NULL; - return eError; -} - -PVRSRV_ERROR PVRSRVRGXTDMGetSharedMemoryKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - PMR ** ppsCLIPMRMem, - PMR ** ppsUSCPMRMem) -{ - PVRSRVTQAcquireShaders(psDeviceNode, ppsCLIPMRMem, ppsUSCPMRMem); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVRGXTDMReleaseSharedMemoryKM(PMR * psPMRMem) -{ - PVR_UNREFERENCED_PARAMETER(psPMRMem); - - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVRGXTDMDestroyTransferContextKM(RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psTransferContext->psDeviceNode->pvDevice; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_FWTDMCONTEXT *psFWTransferContext; - IMG_UINT32 ui32WorkEstCCBSubmitted; - - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - eError = DevmemAcquireCpuVirtAddr(psTransferContext->psFWTransferContextMemDesc, - (void **)&psFWTransferContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to map firmware transfer context (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - ui32WorkEstCCBSubmitted = psFWTransferContext->ui32WorkEstCCBSubmitted; - - DevmemReleaseCpuVirtAddr(psTransferContext->psFWTransferContextMemDesc); - - /* Check if all of the workload estimation CCB commands for this workload are read */ - if (ui32WorkEstCCBSubmitted != psTransferContext->sWorkEstData.ui32WorkEstCCBReceived) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: WorkEst # cmds submitted (%u) and received (%u) mismatch", - __func__, ui32WorkEstCCBSubmitted, - psTransferContext->sWorkEstData.ui32WorkEstCCBReceived)); - - return PVRSRV_ERROR_RETRY; - } - } -#endif - - - /* remove node from list before calling destroy - as destroy, if successful - * will invalidate the node - * must be re-added if destroy fails - */ - OSWRLockAcquireWrite(psDevInfo->hTDMCtxListLock); - dllist_remove_node(&(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTDMCtxListLock); - - - eError = _DestroyTDMTransferContext(&psTransferContext->sTDMData, - psTransferContext->psDeviceNode); - if (eError != PVRSRV_OK) - { - goto fail_destroyTDM; - } - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - WorkEstDeInitTDM(psDevInfo, &psTransferContext->sWorkEstData); - } -#endif - - if (psTransferContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWFrameworkMemDesc); - } - - SyncAddrListDeinit(&psTransferContext->sSyncAddrListFence); - SyncAddrListDeinit(&psTransferContext->sSyncAddrListUpdate); - - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWTransferContextMemDesc); - - OSLockDestroy(psTransferContext->hLock); - - OSFreeMem(psTransferContext); - - return PVRSRV_OK; - -fail_destroyTDM: - - OSWRLockAcquireWrite(psDevInfo->hTDMCtxListLock); - dllist_add_to_tail(&(psDevInfo->sTDMCtxtListHead), &(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTDMCtxListLock); - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -/* - * PVRSRVSubmitTQ3DKickKM - */ -PVRSRV_ERROR PVRSRVRGXTDMSubmitTransferKM( - RGX_SERVER_TQ_TDM_CONTEXT * psTransferContext, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ** pauiClientUpdateUFODevVarBlock, - IMG_UINT32 * paui32ClientUpdateSyncOffset, - IMG_UINT32 * paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE * piUpdateFence, - IMG_CHAR szUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32FWCommandSize, - IMG_UINT8 * pui8FWCommand, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 * paui32SyncPMRFlags, - PMR ** ppsSyncPMRs, - IMG_UINT32 ui32TDMCharacteristic1, - IMG_UINT32 ui32TDMCharacteristic2, - IMG_UINT64 ui64DeadlineInus) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psTransferContext->psDeviceNode; - RGX_CCB_CMD_HELPER_DATA *psCmdHelper; - PRGXFWIF_UFO_ADDR * pauiIntFenceUFOAddress = NULL; - PRGXFWIF_UFO_ADDR * pauiIntUpdateUFOAddress = NULL; - IMG_UINT32 ui32IntClientFenceCount = 0; - IMG_UINT32 * paui32IntUpdateValue = paui32ClientUpdateValue; - IMG_UINT32 ui32IntClientUpdateCount = ui32ClientUpdateCount; - PVRSRV_ERROR eError; - PVRSRV_ERROR eError2; - PVRSRV_FENCE iUpdateFence = PVRSRV_NO_FENCE; - PVRSRV_RGXDEV_INFO *psDevInfo = FWCommonContextGetRGXDevInfo(psTransferContext->sTDMData.psServerCommonContext); - RGX_CLIENT_CCB *psClientCCB = FWCommonContextGetClientCCB(psTransferContext->sTDMData.psServerCommonContext); - IMG_UINT32 ui32IntJobRef = OSAtomicIncrement(&psDevInfo->iCCBSubmissionOrdinal); - - IMG_UINT32 __maybe_unused ui32CmdOffset = 0; - IMG_BOOL bCCBStateOpen; - - PRGXFWIF_TIMESTAMP_ADDR pPreAddr; - PRGXFWIF_TIMESTAMP_ADDR pPostAddr; - PRGXFWIF_UFO_ADDR pRMWUFOAddr; - - IMG_UINT64 uiCheckFenceUID = 0; - IMG_UINT64 uiUpdateFenceUID = 0; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - RGXFWIF_WORKEST_KICK_DATA sWorkloadKickDataTransfer = {0}; - IMG_UINT32 ui32TDMWorkloadDataRO = 0; - IMG_UINT32 ui32TDMCmdHeaderOffset = 0; - IMG_UINT32 ui32TDMCmdOffsetWrapCheck = 0; - RGX_WORKLOAD sWorkloadCharacteristics = {0}; -#endif - -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_append_data *psBufferSyncData = NULL; - PSYNC_CHECKPOINT *apsBufferFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32BufferFenceSyncCheckpointCount = 0; - PSYNC_CHECKPOINT psBufferUpdateSyncCheckpoint = NULL; -#endif - - PSYNC_CHECKPOINT psUpdateSyncCheckpoint = NULL; - PSYNC_CHECKPOINT *apsFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32FenceSyncCheckpointCount = 0; - IMG_UINT32 *pui32IntAllocatedUpdateValues = NULL; - PVRSRV_CLIENT_SYNC_PRIM *psFenceTimelineUpdateSync = NULL; - IMG_UINT32 ui32FenceTimelineUpdateValue = 0; - void *pvUpdateFenceFinaliseData = NULL; - - if (iUpdateTimeline >= 0 && !piUpdateFence) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if !defined(SUPPORT_WORKLOAD_ESTIMATION) - PVR_UNREFERENCED_PARAMETER(ui32TDMCharacteristic1); - PVR_UNREFERENCED_PARAMETER(ui32TDMCharacteristic2); - PVR_UNREFERENCED_PARAMETER(ui64DeadlineInus); -#endif - - /* Ensure we haven't been given a null ptr to - * update values if we have been told we - * have updates - */ - if (ui32ClientUpdateCount > 0) - { - PVR_LOG_RETURN_IF_FALSE(paui32ClientUpdateValue != NULL, - "paui32ClientUpdateValue NULL but " - "ui32ClientUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Ensure the string is null-terminated (Required for safety) */ - szUpdateFenceName[31] = '\0'; - - if (ui32SyncPMRCount != 0) - { - if (!ppsSyncPMRs) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - OSLockAcquire(psTransferContext->hLock); - - /* We can't allocate the required amount of stack space on all consumer architectures */ - psCmdHelper = OSAllocMem(sizeof(RGX_CCB_CMD_HELPER_DATA)); - if (psCmdHelper == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_allochelper; - } - - - /* - Init the command helper commands for all the prepares - */ - { - IMG_CHAR *pszCommandName; - RGXFWIF_CCB_CMD_TYPE eType; -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif - - pszCommandName = "TQ-TDM"; - - if (ui32FWCommandSize == 0) - { - /* A NULL CMD for TDM is used to append updates to a non finished - * FW command. bCCBStateOpen is used in case capture range is - * entered on this command, to not drain CCB up to the Roff for this - * command, but the finished command prior to this. - */ - bCCBStateOpen = IMG_TRUE; - eType = RGXFWIF_CCB_CMD_TYPE_NULL; - } - else - { - bCCBStateOpen = IMG_FALSE; - eType = RGXFWIF_CCB_CMD_TYPE_TQ_TDM; - } -#if defined(SUPPORT_BUFFER_SYNC) - psBufferSyncContext = psTransferContext->sTDMData.psBufferSyncContext; -#endif - - eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListFence, - 0, - NULL, - NULL); - if (eError != PVRSRV_OK) - { - goto fail_populate_sync_addr_list; - } - - eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListUpdate, - ui32ClientUpdateCount, - pauiClientUpdateUFODevVarBlock, - paui32ClientUpdateSyncOffset); - if (eError != PVRSRV_OK) - { - goto fail_populate_sync_addr_list; - } - paui32IntUpdateValue = paui32ClientUpdateValue; - pauiIntUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs; - - - if (ui32SyncPMRCount) - { -#if defined(SUPPORT_BUFFER_SYNC) - int err; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: Calling pvr_buffer_sync_resolve_and_create_fences", __func__)); - err = pvr_buffer_sync_resolve_and_create_fences(psBufferSyncContext, - psTransferContext->psDeviceNode->hSyncCheckpointContext, - ui32SyncPMRCount, - ppsSyncPMRs, - paui32SyncPMRFlags, - &ui32BufferFenceSyncCheckpointCount, - &apsBufferFenceSyncCheckpoints, - &psBufferUpdateSyncCheckpoint, - &psBufferSyncData); - if (err) - { - switch (err) - { - case -EINTR: - eError = PVRSRV_ERROR_RETRY; - break; - case -ENOMEM: - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - break; - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: pvr_buffer_sync_resolve_and_create_fences failed (%s)", __func__, PVRSRVGetErrorString(eError))); - } - goto fail_resolve_input_fence; - } - - /* Append buffer sync fences */ - if (ui32BufferFenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d buffer sync checkpoints to TQ Fence (&psTransferContext->sSyncAddrListFence=<%p>, pauiIntFenceUFOAddress=<%p>)...", __func__, ui32BufferFenceSyncCheckpointCount, (void*)&psTransferContext->sSyncAddrListFence , (void*)pauiIntFenceUFOAddress)); - SyncAddrListAppendAndDeRefCheckpoints(&psTransferContext->sSyncAddrListFence, - ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); - if (!pauiIntFenceUFOAddress) - { - pauiIntFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs; - } - ui32IntClientFenceCount += ui32BufferFenceSyncCheckpointCount; - } - - if (psBufferUpdateSyncCheckpoint) - { - /* Append the update (from output fence) */ - SyncAddrListAppendCheckpoints(&psTransferContext->sSyncAddrListUpdate, - 1, - &psBufferUpdateSyncCheckpoint); - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs; - } - ui32IntClientUpdateCount++; - } -#else /* defined(SUPPORT_BUFFER_SYNC) */ - PVR_DPF((PVR_DBG_ERROR, "%s: Buffer sync not supported but got %u buffers", __func__, ui32SyncPMRCount)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_populate_sync_addr_list; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - } - - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence(psTransferContext->psDeviceNode->hSyncCheckpointContext, - iCheckFence, - &ui32FenceSyncCheckpointCount, - &apsFenceSyncCheckpoints, - &uiCheckFenceUID, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - goto fail_resolve_input_fence; - } -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 ii; - for (ii=0; ii<32; ii++) - { - PSYNC_CHECKPOINT psNextCheckpoint = *(apsFenceSyncCheckpoints + ii); - CHKPT_DBG((PVR_DBG_ERROR, "%s: apsFenceSyncCheckpoints[%d]=<%p>", __func__, ii, (void*)psNextCheckpoint)); //psFenceSyncCheckpoints[ii])); - } - } -#endif - /* Create the output fence (if required) */ - if (iUpdateTimeline != PVRSRV_NO_TIMELINE) - { - eError = SyncCheckpointCreateFence(psTransferContext->psDeviceNode, - szUpdateFenceName, - iUpdateTimeline, - psTransferContext->psDeviceNode->hSyncCheckpointContext, - &iUpdateFence, - &uiUpdateFenceUID, - &pvUpdateFenceFinaliseData, - &psUpdateSyncCheckpoint, - (void*)&psFenceTimelineUpdateSync, - &ui32FenceTimelineUpdateValue, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - goto fail_create_output_fence; - } - - /* Append the sync prim update for the timeline (if required) */ - if (psFenceTimelineUpdateSync) - { - IMG_UINT32 *pui32TimelineUpdateWp = NULL; - - /* Allocate memory to hold the list of update values (including our timeline update) */ - pui32IntAllocatedUpdateValues = OSAllocMem(sizeof(*pui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); - if (!pui32IntAllocatedUpdateValues) - { - /* Failed to allocate memory */ - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc_update_values_mem; - } - OSCachedMemSet(pui32IntAllocatedUpdateValues, 0xbb, sizeof(*pui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); - /* Copy the update values into the new memory, then append our timeline update value */ - if (paui32IntUpdateValue) - { - OSCachedMemCopy(pui32IntAllocatedUpdateValues, paui32IntUpdateValue, sizeof(*pui32IntAllocatedUpdateValues) * ui32IntClientUpdateCount); - } - /* Now set the additional update value */ - pui32TimelineUpdateWp = pui32IntAllocatedUpdateValues + ui32IntClientUpdateCount; - *pui32TimelineUpdateWp = ui32FenceTimelineUpdateValue; - ui32IntClientUpdateCount++; -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Now append the timeline sync prim addr to the transfer context update list */ - SyncAddrListAppendSyncPrim(&psTransferContext->sSyncAddrListUpdate, - psFenceTimelineUpdateSync); -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Ensure paui32IntUpdateValue is now pointing to our new array of update values */ - paui32IntUpdateValue = pui32IntAllocatedUpdateValues; - } - } - - if (ui32FenceSyncCheckpointCount) - { - /* Append the checks (from input fence) */ - if (ui32FenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d sync checkpoints to TQ Fence (&psTransferContext->sSyncAddrListFence=<%p>)...", __func__, ui32FenceSyncCheckpointCount, (void*)&psTransferContext->sSyncAddrListFence)); -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiIntFenceUFOAddress; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - SyncAddrListAppendCheckpoints(&psTransferContext->sSyncAddrListFence, - ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - if (!pauiIntFenceUFOAddress) - { - pauiIntFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs; - } - ui32IntClientFenceCount += ui32FenceSyncCheckpointCount; - } -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - if (psUpdateSyncCheckpoint) - { - /* Append the update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append 1 sync checkpoint to TQ Update (&psTransferContext->sSyncAddrListUpdate=<%p>, pauiIntUpdateUFOAddress=<%p>)...", __func__, (void*)&psTransferContext->sSyncAddrListUpdate , (void*)pauiIntUpdateUFOAddress)); - SyncAddrListAppendCheckpoints(&psTransferContext->sSyncAddrListUpdate, - 1, - &psUpdateSyncCheckpoint); - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs; - } - ui32IntClientUpdateCount++; -#if defined(TDM_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - -#if (ENABLE_TDM_UFO_DUMP == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: dumping TDM fence/updates syncs...", __func__)); - { - IMG_UINT32 ii; - PRGXFWIF_UFO_ADDR *psTmpIntFenceUFOAddress = pauiIntFenceUFOAddress; - PRGXFWIF_UFO_ADDR *psTmpIntUpdateUFOAddress = pauiIntUpdateUFOAddress; - IMG_UINT32 *pui32TmpIntUpdateValue = paui32IntUpdateValue; - - /* Dump Fence syncs and Update syncs */ - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TDM fence syncs (&psTransferContext->sSyncAddrListFence=<%p>, pauiIntFenceUFOAddress=<%p>):", __func__, ui32IntClientFenceCount, (void*)&psTransferContext->sSyncAddrListFence, (void*)pauiIntFenceUFOAddress)); - for (ii=0; ii. FWAddr=0x%x, CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientFenceCount, (void*)psTmpIntFenceUFOAddress, psTmpIntFenceUFOAddress->ui32Addr)); - psTmpIntFenceUFOAddress++; - } - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TDM update syncs (&psTransferContext->sSyncAddrListUpdate=<%p>, pauiIntUpdateUFOAddress=<%p>):", __func__, ui32IntClientUpdateCount, (void*)&psTransferContext->sSyncAddrListUpdate, (void*)pauiIntUpdateUFOAddress)); - for (ii=0; iiui32Addr & 0x1) - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr, *pui32TmpIntUpdateValue)); - pui32TmpIntUpdateValue++; - } - psTmpIntUpdateUFOAddress++; - } - } -#endif - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - sWorkloadCharacteristics.sTransfer.ui32Characteristic1 = ui32TDMCharacteristic1; - sWorkloadCharacteristics.sTransfer.ui32Characteristic2 = ui32TDMCharacteristic2; - - /* Prepare workload estimation */ - WorkEstPrepare(psDeviceNode->pvDevice, - &psTransferContext->sWorkEstData, - &psTransferContext->sWorkEstData.uWorkloadMatchingData.sTransfer.sDataTDM, - eType, - &sWorkloadCharacteristics, - ui64DeadlineInus, - &sWorkloadKickDataTransfer); - } -#endif - RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psTransferContext->psDeviceNode->pvDevice, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr); - /* - Create the command helper data for this command - */ - RGXCmdHelperInitCmdCCB(psDevInfo, - psClientCCB, - 0, - ui32IntClientFenceCount, - pauiIntFenceUFOAddress, - NULL, - ui32IntClientUpdateCount, - pauiIntUpdateUFOAddress, - paui32IntUpdateValue, - ui32FWCommandSize, - pui8FWCommand, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr, - eType, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - &sWorkloadKickDataTransfer, -#else /* SUPPORT_WORKLOAD_ESTIMATION */ - NULL, -#endif /* SUPPORT_WORKLOAD_ESTIMATION */ - pszCommandName, - bCCBStateOpen, - psCmdHelper); - } - - /* - Acquire space for all the commands in one go - */ - - eError = RGXCmdHelperAcquireCmdCCB(1, psCmdHelper); - if (eError != PVRSRV_OK) - { - goto fail_3dcmdacquire; - } - - - /* - We should acquire the kernel CCB(s) space here as the schedule could fail - and we would have to roll back all the syncs - */ - - /* - Only do the command helper release (which takes the server sync - operations if the acquire succeeded - */ - ui32CmdOffset = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->sTDMData.psServerCommonContext)); - RGXCmdHelperReleaseCmdCCB(1, - psCmdHelper, - "TQ_TDM", - FWCommonContextGetFWAddress(psTransferContext->sTDMData.psServerCommonContext).ui32Addr); - - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - /* The following is used to determine the offset of the command header containing - the workload estimation data so that can be accessed when the KCCB is read */ - ui32TDMCmdHeaderOffset = RGXCmdHelperGetDMCommandHeaderOffset(psCmdHelper); - - ui32TDMCmdOffsetWrapCheck = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->sTDMData.psServerCommonContext)); - - /* This checks if the command would wrap around at the end of the CCB and - * therefore would start at an offset of 0 rather than the current command - * offset */ - if (ui32CmdOffset < ui32TDMCmdOffsetWrapCheck) - { - ui32TDMWorkloadDataRO = ui32CmdOffset; - } - else - { - ui32TDMWorkloadDataRO = 0; - } - } -#endif - - /* - Even if we failed to acquire the client CCB space we might still need - to kick the HW to process a padding packet to release space for us next - time round - */ - { - RGXFWIF_KCCB_CMD sTDMKCCBCmd; - IMG_UINT32 ui32FWAddr = FWCommonContextGetFWAddress( - psTransferContext->sTDMData.psServerCommonContext).ui32Addr; - - /* Construct the kernel 3D CCB command. */ - sTDMKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - sTDMKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->sTDMData.psServerCommonContext); - sTDMKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(psClientCCB); - sTDMKCCBCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(psClientCCB); - sTDMKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - - /* Add the Workload data into the KCCB kick */ - sTDMKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0; -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, FASTRENDER_DM)) - { - /* Store the offset to the CCCB command header so that it can be referenced - * when the KCCB command reaches the FW */ - sTDMKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = ui32TDMWorkloadDataRO + ui32TDMCmdHeaderOffset; - } -#endif - - /* HTBLOGK(HTB_SF_MAIN_KICK_TDM, */ - /* s3DKCCBCmd.uCmdData.sCmdKickData.psContext, */ - /* ui323DCmdOffset); */ - RGXSRV_HWPERF_ENQ(psTransferContext, - OSGetCurrentClientProcessIDKM(), - FWCommonContextGetFWAddress(psTransferContext->sTDMData.psServerCommonContext).ui32Addr, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_TQTDM, - iCheckFence, - iUpdateFence, - iUpdateTimeline, - uiCheckFenceUID, - uiUpdateFenceUID, - NO_DEADLINE, - NO_CYCEST); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psDeviceNode->pvDevice, - RGXFWIF_DM_TDM, - & sTDMKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXTDMSubmitTransferKM failed to schedule kernel CCB command. (0x%x)", eError2)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - goto fail_2dcmdacquire; - } - - PVRGpuTraceEnqueueEvent(psDeviceNode->pvDevice, ui32FWAddr, ui32ExtJobRef, - ui32IntJobRef, RGX_HWPERF_KICK_TYPE_TQTDM); - } - - /* - * Now check eError (which may have returned an error from our earlier calls - * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first - * so we check it now... - */ - if (eError != PVRSRV_OK ) - { - goto fail_2dcmdacquire; - } - -#if defined(NO_HARDWARE) - /* If NO_HARDWARE, signal the output fence's sync checkpoint and sync prim */ - if (psUpdateSyncCheckpoint) - { - SyncCheckpointSignalNoHW(psUpdateSyncCheckpoint); - } - if (psFenceTimelineUpdateSync) - { - SyncPrimNoHwUpdate(psFenceTimelineUpdateSync, ui32FenceTimelineUpdateValue); - } - SyncCheckpointNoHWUpdateTimelines(NULL); -#endif /* defined(NO_HARDWARE) */ - -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_succeeded(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - * piUpdateFence = iUpdateFence; - if (pvUpdateFenceFinaliseData && (iUpdateFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psDeviceNode, iUpdateFence, pvUpdateFenceFinaliseData, - psUpdateSyncCheckpoint, szUpdateFenceName); - } - - OSFreeMem(psCmdHelper); - - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - /* Free memory allocated to hold the internal list of update values */ - if (pui32IntAllocatedUpdateValues) - { - OSFreeMem(pui32IntAllocatedUpdateValues); - pui32IntAllocatedUpdateValues = NULL; - } - - OSLockRelease(psTransferContext->hLock); - return PVRSRV_OK; - -/* - No resources are created in this function so there is nothing to free - unless we had to merge syncs. - If we fail after the client CCB acquire there is still nothing to do - as only the client CCB release will modify the client CCB -*/ -fail_2dcmdacquire: -fail_3dcmdacquire: - - SyncAddrListRollbackCheckpoints(psTransferContext->psDeviceNode, &psTransferContext->sSyncAddrListFence); - SyncAddrListRollbackCheckpoints(psTransferContext->psDeviceNode, &psTransferContext->sSyncAddrListUpdate); -fail_alloc_update_values_mem: - -/* fail_pdumpcheck: */ -/* fail_cmdtype: */ - - if (iUpdateFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(iUpdateFence, pvUpdateFenceFinaliseData); - } -fail_create_output_fence: - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - -fail_resolve_input_fence: - -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_failed(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - -fail_populate_sync_addr_list: - PVR_ASSERT(eError != PVRSRV_OK); - OSFreeMem(psCmdHelper); -fail_allochelper: - - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - OSLockRelease(psTransferContext->hLock); - return eError; -} - - -PVRSRV_ERROR PVRSRVRGXTDMNotifyWriteOffsetUpdateKM( - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - IMG_UINT32 ui32PDumpFlags) -{ - RGXFWIF_KCCB_CMD sKCCBCmd; - PVRSRV_ERROR eError; - - OSLockAcquire(psTransferContext->hLock); - - /* Schedule the firmware command */ - sKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE; - sKCCBCmd.uCmdData.sWriteOffsetUpdateData.psContext = FWCommonContextGetFWAddress(psTransferContext->sTDMData.psServerCommonContext); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError = RGXScheduleCommand(psTransferContext->psDeviceNode->pvDevice, - RGXFWIF_DM_TDM, - &sKCCBCmd, - ui32PDumpFlags); - if (eError != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to schedule the FW command %d (%s)", - __func__, eError, PVRSRVGETERRORSTRING(eError))); - } - - OSLockRelease(psTransferContext->hLock); - return eError; -} - -PVRSRV_ERROR PVRSRVRGXTDMSetTransferContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - IMG_UINT32 ui32Priority) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - - OSLockAcquire(psTransferContext->hLock); - - if (psTransferContext->sTDMData.ui32Priority != ui32Priority) - { - eError = ContextSetPriority(psTransferContext->sTDMData.psServerCommonContext, - psConnection, - psTransferContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_TDM); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority (%s)", __func__, PVRSRVGetErrorString(eError))); - - OSLockRelease(psTransferContext->hLock); - return eError; - } - } - - OSLockRelease(psTransferContext->hLock); - return PVRSRV_OK; -} - -PVRSRV_ERROR PVRSRVRGXTDMSetTransferContextPropertyKM(RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (eContextProperty) - { - case RGX_CONTEXT_PROPERTY_FLAGS: - { - IMG_UINT32 ui32ContextFlags = (IMG_UINT32)ui64Input; - - OSLockAcquire(psTransferContext->hLock); - eError = FWCommonContextSetFlags(psTransferContext->sTDMData.psServerCommonContext, - ui32ContextFlags); - OSLockRelease(psTransferContext->hLock); - break; - } - - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_ERROR_NOT_SUPPORTED - asked to set unknown property (%d)", __func__, eContextProperty)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - } - - return eError; -} - -void DumpTDMTransferCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - DLLIST_NODE *psNode, *psNext; - - OSWRLockAcquireRead(psDevInfo->hTDMCtxListLock); - - dllist_foreach_node(&psDevInfo->sTDMCtxtListHead, psNode, psNext) - { - RGX_SERVER_TQ_TDM_CONTEXT *psCurrentServerTransferCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_TDM_CONTEXT, sListNode); - - DumpFWCommonContextInfo(psCurrentServerTransferCtx->sTDMData.psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - - OSWRLockReleaseRead(psDevInfo->hTDMCtxListLock); -} - - -IMG_UINT32 CheckForStalledClientTDMTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - DLLIST_NODE *psNode, *psNext; - IMG_UINT32 ui32ContextBitMask = 0; - - OSWRLockAcquireRead(psDevInfo->hTDMCtxListLock); - - dllist_foreach_node(&psDevInfo->sTDMCtxtListHead, psNode, psNext) - { - RGX_SERVER_TQ_TDM_CONTEXT *psCurrentServerTransferCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_TDM_CONTEXT, sListNode); - - if (CheckStalledClientCommonContext( - psCurrentServerTransferCtx->sTDMData.psServerCommonContext, RGX_KICK_TYPE_DM_TDM_2D) - == PVRSRV_ERROR_CCCB_STALLED) { - ui32ContextBitMask = RGX_KICK_TYPE_DM_TDM_2D; - } - } - - OSWRLockReleaseRead(psDevInfo->hTDMCtxListLock); - return ui32ContextBitMask; -} - -/**************************************************************************//** - End of file (rgxtdmtransfer.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.h b/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.h deleted file mode 100644 index 87ca2cf2c2f80..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtdmtransfer.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************/ /*! -@File rgxtdmtransfer.h -@Title RGX Transfer queue 2 Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX Transfer queue Functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXTDMTRANSFER_H) -#define RGXTDMTRANSFER_H - -#include "devicemem.h" -#include "device.h" -#include "rgxdevice.h" -#include "rgxfwutils.h" -#include "rgx_fwif_resetframework.h" -#include "rgxdebug.h" -#include "pvr_notifier.h" - -#include "sync_server.h" -#include "connection_server.h" - -typedef struct _RGX_SERVER_TQ_TDM_CONTEXT_ RGX_SERVER_TQ_TDM_CONTEXT; - - -PVRSRV_ERROR PVRSRVRGXTDMCreateTransferContextKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pabyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU88, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - RGX_SERVER_TQ_TDM_CONTEXT **ppsTransferContext); - - -PVRSRV_ERROR PVRSRVRGXTDMGetSharedMemoryKM( - CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - PMR ** ppsCLIPMRMem, - PMR ** ppsUSCPMRMem); - - -PVRSRV_ERROR PVRSRVRGXTDMReleaseSharedMemoryKM(PMR * psUSCPMRMem); - - -PVRSRV_ERROR PVRSRVRGXTDMDestroyTransferContextKM(RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext); - - -PVRSRV_ERROR PVRSRVRGXTDMSubmitTransferKM( - RGX_SERVER_TQ_TDM_CONTEXT * psTransferContext, - IMG_UINT32 ui32PDumpFlags, - IMG_UINT32 ui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ** pauiClientUpdateUFODevVarBlock, - IMG_UINT32 * paui32ClientUpdateSyncOffset, - IMG_UINT32 * paui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE iUpdateTimeline, - PVRSRV_FENCE * piUpdateFence, - IMG_CHAR szUpdateFenceName[PVRSRV_SYNC_NAME_LENGTH], - IMG_UINT32 ui32FWCommandSize, - IMG_UINT8 * pui8FWCommand, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 * pui32SyncPMRFlags, - PMR ** ppsSyncPMRs, - IMG_UINT32 ui32TDMCharacteristic1, - IMG_UINT32 ui32TDMCharacteristic2, - IMG_UINT64 ui64DeadlineInus); - -PVRSRV_ERROR PVRSRVRGXTDMNotifyWriteOffsetUpdateKM( - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - IMG_UINT32 ui32PDumpFlags); - -PVRSRV_ERROR PVRSRVRGXTDMSetTransferContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - IMG_UINT32 ui32Priority); - -PVRSRV_ERROR PVRSRVRGXTDMSetTransferContextPropertyKM(RGX_SERVER_TQ_TDM_CONTEXT *psTransferContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output); - -/* Debug - Dump debug info of TDM transfer contexts on this device */ -void DumpTDMTransferCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/* Debug/Watchdog - check if client transfer contexts are stalled */ -IMG_UINT32 CheckForStalledClientTDMTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); - - -#endif /* RGXTDMTRANSFER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.c b/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.c deleted file mode 100644 index 584dbf1e3f642..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.c +++ /dev/null @@ -1,648 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific time correlation and calibration routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific time correlation and calibration routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "rgxtimecorr.h" -#include "rgxfwutils.h" -#include "htbserver.h" -#include "pvrsrv_apphint.h" - -/****************************************************************************** - * - * - A calibration period is started on power-on and after a DVFS transition, - * and it's closed before a power-off and before a DVFS transition - * (so power-on -> dfvs -> dvfs -> power-off , power on -> dvfs -> dvfs..., - * where each arrow is a calibration period). - * - * - The timers on the Host and on the FW are correlated at the beginning of - * each period together with the current GPU frequency. - * - * - Correlation and calibration are also done at regular intervals using - * a best effort approach. - * - *****************************************************************************/ - -/* - AppHint interfaces -*/ - -static PVRSRV_ERROR _SetClock(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 ui32Value) -{ - static __maybe_unused const char* const apszClocks[] = { - "mono", "mono_raw", "sched" - }; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - PVR_ASSERT(psDeviceNode->pvDevice != NULL); - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - if (ui32Value >= RGXTIMECORR_CLOCK_LAST) - { - PVR_DPF((PVR_DBG_ERROR, "Invalid clock source type (%u)", ui32Value)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - RGXTimeCorrEnd((PVRSRV_DEVICE_NODE *) psDeviceNode, - RGXTIMECORR_EVENT_CLOCK_CHANGE); - - PVR_DPF((PVR_DBG_WARNING, "Setting time correlation clock from \"%s\" to \"%s\"", - apszClocks[psDevInfo->ui32ClockSource], - apszClocks[ui32Value])); - - psDevInfo->ui32ClockSource = ui32Value; - - RGXTimeCorrBegin((PVRSRV_DEVICE_NODE *) psDeviceNode, - RGXTIMECORR_EVENT_CLOCK_CHANGE); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _GetClock(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *psPrivate, - IMG_UINT32 *pui32Value) -{ - PVR_ASSERT(psDeviceNode->pvDevice != NULL); - - *pui32Value = - ((PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice)->ui32ClockSource; - - PVR_UNREFERENCED_PARAMETER(psPrivate); - - return PVRSRV_OK; -} - -void RGXTimeCorrInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_TimeCorrClock, _GetClock, - _SetClock, psDeviceNode, NULL); -} - -/* - End of AppHint interface -*/ - -IMG_UINT64 RGXTimeCorrGetClockns64(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_UINT64 ui64Clock; - - switch (((PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice)->ui32ClockSource) { - case RGXTIMECORR_CLOCK_MONO: - return ((void) OSClockMonotonicns64(&ui64Clock), ui64Clock); - case RGXTIMECORR_CLOCK_MONO_RAW: - return OSClockMonotonicRawns64(); - case RGXTIMECORR_CLOCK_SCHED: - return OSClockns64(); - default: - PVR_ASSERT(IMG_FALSE); - return 0; - } -} - -IMG_UINT64 RGXTimeCorrGetClockus64(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - IMG_UINT32 rem; - return OSDivide64r64(RGXTimeCorrGetClockns64(psDeviceNode), 1000, &rem); -} - -void RGXGetTimeCorrData(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXFWIF_TIME_CORR *psTimeCorrs, - IMG_UINT32 ui32NumOut) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb; - IMG_UINT32 ui32CurrentIndex = psGpuUtilFWCB->ui32TimeCorrSeqCount; - - while (ui32NumOut--) - { - *(psTimeCorrs++) = psGpuUtilFWCB->sTimeCorr[RGXFWIF_TIME_CORR_CURR_INDEX(ui32CurrentIndex)]; - ui32CurrentIndex--; - } -} - -static __maybe_unused const IMG_CHAR* _EventToString(RGXTIMECORR_EVENT eEvent) -{ - switch (eEvent) - { - case RGXTIMECORR_EVENT_POWER: - return "power"; - case RGXTIMECORR_EVENT_DVFS: - return "dvfs"; - case RGXTIMECORR_EVENT_PERIODIC: - return "periodic"; - case RGXTIMECORR_EVENT_CLOCK_CHANGE: - return "clock source"; - default: - return "n/a"; - } -} - -static inline IMG_UINT32 _RGXGetSystemLayerGPUClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - RGX_DATA *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData; - - return psRGXData->psRGXTimingInfo->ui32CoreClockSpeed; -} - -static inline IMG_UINT32 _RGXGetEstimatedGPUClockSpeed(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGX_GPU_DVFS_TABLE *psGpuDVFSTable = psDevInfo->psGpuDVFSTable; - GPU_FREQ_TRACKING_DATA *psTrackingData; - - psTrackingData = &psGpuDVFSTable->asTrackingData[psGpuDVFSTable->ui32FreqIndex]; - - return psTrackingData->ui32EstCoreClockSpeed; -} - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) -static inline void _DumpTimerCorrelationHistory(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - RGX_GPU_DVFS_TABLE *psGpuDVFSTable = psDevInfo->psGpuDVFSTable; - IMG_UINT32 i = psGpuDVFSTable->ui32HistoryIndex; - - PVR_DPF((PVR_DBG_ERROR, "Dumping history of timer correlation data (latest first):")); - - do - { - PVR_DPF((PVR_DBG_ERROR, - " Begin times: OS %" IMG_UINT64_FMTSPEC ", CR %" IMG_UINT64_FMTSPEC ", " - "End times: OS %" IMG_UINT64_FMTSPEC ", CR %" IMG_UINT64_FMTSPEC ", " - "Core clk %u, Estimated clk %u", - psGpuDVFSTable->asTrackingHistory[i].ui64BeginOSTimestamp, - psGpuDVFSTable->asTrackingHistory[i].ui64BeginCRTimestamp, - psGpuDVFSTable->asTrackingHistory[i].ui64EndOSTimestamp, - psGpuDVFSTable->asTrackingHistory[i].ui64EndCRTimestamp, - psGpuDVFSTable->asTrackingHistory[i].ui32CoreClockSpeed, - psGpuDVFSTable->asTrackingHistory[i].ui32EstCoreClockSpeed)); - - i = (i - 1) % RGX_GPU_FREQ_TRACKING_SIZE; - - } while (i != psGpuDVFSTable->ui32HistoryIndex); -} -#endif - -static void _RGXMakeTimeCorrData(PVRSRV_DEVICE_NODE *psDeviceNode, RGXTIMECORR_EVENT eEvent) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb; - IMG_UINT32 ui32NewSeqCount = psGpuUtilFWCB->ui32TimeCorrSeqCount + 1; - RGXFWIF_TIME_CORR *psTimeCorr = &psGpuUtilFWCB->sTimeCorr[RGXFWIF_TIME_CORR_CURR_INDEX(ui32NewSeqCount)]; - - /* - * The following reads must be done as close together as possible, because - * they represent the same current time sampled from different clock sources. - */ -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - if (OSClockMonotonicns64(&psTimeCorr->ui64OSMonoTimeStamp) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "_RGXMakeTimeCorrData: System Monotonic Clock not available.")); - PVR_ASSERT(0); - } -#endif - psTimeCorr->ui64CRTimeStamp = RGXReadHWTimerReg(psDevInfo); - psTimeCorr->ui64OSTimeStamp = RGXTimeCorrGetClockns64(psDeviceNode); - psTimeCorr->ui32CoreClockSpeed = _RGXGetEstimatedGPUClockSpeed(psDevInfo); - psTimeCorr->ui64CRDeltaToOSDeltaKNs = RGXTimeCorrGetConversionFactor(psTimeCorr->ui32CoreClockSpeed); - - if (psTimeCorr->ui64CRDeltaToOSDeltaKNs == 0) - { -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) - _DumpTimerCorrelationHistory(psDevInfo); -#endif - - /* Revert to original clock speed (error already printed) */ - psTimeCorr->ui32CoreClockSpeed = _RGXGetSystemLayerGPUClockSpeed(psDeviceNode); - psTimeCorr->ui64CRDeltaToOSDeltaKNs = RGXTimeCorrGetConversionFactor(psTimeCorr->ui32CoreClockSpeed); - } - - /* Make sure the values are written to memory before updating the index of the current entry */ - OSWriteMemoryBarrier(psTimeCorr); - - /* Update the index of the current entry in the timer correlation array */ - psGpuUtilFWCB->ui32TimeCorrSeqCount = ui32NewSeqCount; - - PVR_DPF((PVR_DBG_MESSAGE, - "Timer correlation data (post %s event): OS %" IMG_UINT64_FMTSPEC " ns, " - "CR %" IMG_UINT64_FMTSPEC ", GPU freq. %u Hz (given as %u Hz)", - _EventToString(eEvent), - psTimeCorr->ui64OSTimeStamp, - psTimeCorr->ui64CRTimeStamp, - RGXFWIF_ROUND_TO_KHZ(psTimeCorr->ui32CoreClockSpeed), - _RGXGetSystemLayerGPUClockSpeed(psDeviceNode))); - - /* - * Don't log timing data to the HTB log after a power(-on) event. - * Otherwise this will be logged before the HTB partition marker, breaking - * the log sync grammar. This data will be automatically repeated when the - * partition marker is written. - */ - HTBSyncScale(eEvent != RGXTIMECORR_EVENT_POWER, - psTimeCorr->ui64OSTimeStamp, - psTimeCorr->ui64CRTimeStamp, - psTimeCorr->ui32CoreClockSpeed); -} - -static void _RGXCheckTimeCorrData(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_GPU_DVFS_TABLE *psGpuDVFSTable) -{ -#if !defined(NO_HARDWARE) && !defined(VIRTUAL_PLATFORM) && defined(DEBUG) -#define SCALING_FACTOR (10) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb; - IMG_UINT32 ui32Index = RGXFWIF_TIME_CORR_CURR_INDEX(psGpuUtilFWCB->ui32TimeCorrSeqCount); - RGXFWIF_TIME_CORR *psTimeCorr = &psGpuUtilFWCB->sTimeCorr[ui32Index]; - IMG_UINT64 ui64EstimatedTime, ui64CRTimeStamp, ui64OSTimeStamp; - IMG_UINT64 ui64CRTimeDiff, ui64OSTimeDiff; - IMG_INT64 i64Diff; - IMG_UINT32 ui32Ratio, ui32Remainder; - - /* - * The following reads must be done as close together as possible, because - * they represent the same current time sampled from different clock sources. - */ - ui64CRTimeStamp = RGXReadHWTimerReg(psDevInfo); - ui64OSTimeStamp = RGXTimeCorrGetClockns64(psDeviceNode); - - if ((ui64OSTimeStamp - psTimeCorr->ui64OSTimeStamp) < (1 << SCALING_FACTOR)) - { - /* - * Less than ~1us has passed since the timer correlation data was generated. - * A time frame this short is probably not enough to get an estimate - * of how good the timer correlation data was. - * Skip calculations for the above reason and to avoid a division by 0 below. - */ - return; - } - - - /* Calculate an estimated timestamp based on the latest timer correlation data */ - ui64CRTimeDiff = ui64CRTimeStamp - psTimeCorr->ui64CRTimeStamp; - ui64OSTimeDiff = RGXFWIF_GET_DELTA_OSTIME_NS(ui64CRTimeDiff, - psTimeCorr->ui64CRDeltaToOSDeltaKNs); - ui64EstimatedTime = psTimeCorr->ui64OSTimeStamp + ui64OSTimeDiff; - - /* Get difference between estimated timestamp and current timestamp, in ns */ - i64Diff = ui64EstimatedTime - ui64OSTimeStamp; - - /* - * Calculate ratio between estimated time diff and real time diff: - * ratio% : 100% = (OSestimate - OStimecorr) : (OSreal - OStimecorr) - * - * The operands are scaled down (approximately from ns to us) so at least - * the divisor fits on 32 bit. - */ - ui32Ratio = OSDivide64(((ui64EstimatedTime - psTimeCorr->ui64OSTimeStamp) * 100ULL) >> SCALING_FACTOR, - (ui64OSTimeStamp - psTimeCorr->ui64OSTimeStamp) >> SCALING_FACTOR, - &ui32Remainder); - - PVR_DPF((PVR_DBG_MESSAGE, - "Estimated timestamp check: diff %" IMG_INT64_FMTSPECd " ns over " - "period %" IMG_UINT64_FMTSPEC " ns, estimated timer speed %u%%", - i64Diff, - ui64OSTimeStamp - psTimeCorr->ui64OSTimeStamp, - ui32Ratio)); - - /* Warn if the estimated timestamp is not within +/- 1% of the current time */ - if (ui32Ratio < 99 || ui32Ratio > 101) - { - PVR_DPF((PVR_DBG_WARNING, - "Estimated timestamps generated in the last %" IMG_UINT64_FMTSPEC " ns " - "were %s the real time (increasing at %u%% speed)", - ui64OSTimeStamp - psTimeCorr->ui64OSTimeStamp, - i64Diff > 0 ? "ahead of" : "behind", - ui32Ratio)); - - /* Higher ratio == higher delta OS == higher delta CR == frequency higher than expected (and viceversa) */ - PVR_DPF((PVR_DBG_WARNING, - "Current GPU frequency %u Hz (given as %u Hz) is probably %s than expected", - RGXFWIF_ROUND_TO_KHZ(psTimeCorr->ui32CoreClockSpeed), - _RGXGetSystemLayerGPUClockSpeed(psDeviceNode), - i64Diff > 0 ? "lower" : "higher")); - } -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psGpuDVFSTable); -#endif -} - -static inline IMG_UINT32 _RGXGPUFreqGetIndex(RGX_GPU_DVFS_TABLE *psGpuDVFSTable, IMG_UINT32 ui32CoreClockSpeed) -{ - IMG_UINT32 *paui32GPUFrequencies = psGpuDVFSTable->aui32GPUFrequency; - IMG_UINT32 i; - - for (i = 0; i < RGX_GPU_DVFS_TABLE_SIZE; i++) - { - if (paui32GPUFrequencies[i] == ui32CoreClockSpeed) - { - return i; - } - - if (paui32GPUFrequencies[i] == 0) - { - paui32GPUFrequencies[i] = ui32CoreClockSpeed; - return i; - } - } - - i--; - - PVR_DPF((PVR_DBG_ERROR, "GPU frequency table in the driver is full! " - "Table size should be increased! Overriding last entry (%u) with %u", - paui32GPUFrequencies[i], ui32CoreClockSpeed)); - - paui32GPUFrequencies[i] = ui32CoreClockSpeed; - - return i; -} - -static void _RGXGPUFreqCalibrationPeriodStart(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_GPU_DVFS_TABLE *psGpuDVFSTable) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - GPU_FREQ_TRACKING_DATA *psTrackingData; - IMG_UINT32 ui32CoreClockSpeed, ui32Index; - - IMG_UINT64 ui64CRTimestamp = RGXReadHWTimerReg(psDevInfo); - IMG_UINT64 ui64OSTimestamp = RGXTimeCorrGetClockus64(psDeviceNode); - - psGpuDVFSTable->ui64CalibrationCRTimestamp = ui64CRTimestamp; - psGpuDVFSTable->ui64CalibrationOSTimestamp = ui64OSTimestamp; - - ui32CoreClockSpeed = _RGXGetSystemLayerGPUClockSpeed(psDeviceNode); - ui32Index = _RGXGPUFreqGetIndex(psGpuDVFSTable, ui32CoreClockSpeed); - psTrackingData = &psGpuDVFSTable->asTrackingData[ui32Index]; - - /* Set the time needed to (re)calibrate the GPU frequency */ - if (psTrackingData->ui32CalibrationCount == 0) /* We never met this frequency */ - { - psTrackingData->ui32EstCoreClockSpeed = ui32CoreClockSpeed; - psGpuDVFSTable->ui32CalibrationPeriod = RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US; - } - else if (psTrackingData->ui32CalibrationCount == 1) /* We calibrated this frequency only once */ - { - psGpuDVFSTable->ui32CalibrationPeriod = RGX_GPU_DVFS_TRANSITION_CALIBRATION_TIME_US; - } - else - { - psGpuDVFSTable->ui32CalibrationPeriod = RGX_GPU_DVFS_PERIODIC_CALIBRATION_TIME_US; - } - - /* Update the index to the DVFS table */ - psGpuDVFSTable->ui32FreqIndex = ui32Index; - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) - /* Update tracking history */ - { - GPU_FREQ_TRACKING_HISTORY *psTrackingHistory; - - psTrackingHistory = &psGpuDVFSTable->asTrackingHistory[psGpuDVFSTable->ui32HistoryIndex]; - psTrackingHistory->ui32CoreClockSpeed = ui32CoreClockSpeed; - psTrackingHistory->ui32EstCoreClockSpeed = psTrackingData->ui32EstCoreClockSpeed; - psTrackingHistory->ui64BeginCRTimestamp = ui64CRTimestamp; - psTrackingHistory->ui64BeginOSTimestamp = ui64OSTimestamp; - psTrackingHistory->ui64EndCRTimestamp = 0ULL; - psTrackingHistory->ui64EndOSTimestamp = 0ULL; - } -#endif -} - -static void _RGXGPUFreqCalibrationPeriodStop(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_GPU_DVFS_TABLE *psGpuDVFSTable) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - IMG_UINT64 ui64CRTimestamp = RGXReadHWTimerReg(psDevInfo); - IMG_UINT64 ui64OSTimestamp = RGXTimeCorrGetClockus64(psDeviceNode); - - psGpuDVFSTable->ui64CalibrationCRTimediff = - ui64CRTimestamp - psGpuDVFSTable->ui64CalibrationCRTimestamp; - psGpuDVFSTable->ui64CalibrationOSTimediff = - ui64OSTimestamp - psGpuDVFSTable->ui64CalibrationOSTimestamp; - - /* Check if the current timer correlation data is good enough */ - _RGXCheckTimeCorrData(psDeviceNode, psGpuDVFSTable); - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) - /* Update tracking history */ - { - GPU_FREQ_TRACKING_HISTORY *psTrackingHistory; - - psTrackingHistory = &psGpuDVFSTable->asTrackingHistory[psGpuDVFSTable->ui32HistoryIndex]; - psTrackingHistory->ui64EndCRTimestamp = ui64CRTimestamp; - psTrackingHistory->ui64EndOSTimestamp = ui64OSTimestamp; - } -#endif -} - -static void _RGXGPUFreqCalibrationCalculate(PVRSRV_DEVICE_NODE *psDeviceNode, - RGX_GPU_DVFS_TABLE *psGpuDVFSTable, - RGXTIMECORR_EVENT eEvent) -{ -#if !defined(DISABLE_GPU_FREQUENCY_CALIBRATION) - GPU_FREQ_TRACKING_DATA *psTrackingData; - IMG_UINT32 ui32EstCoreClockSpeed, ui32PrevCoreClockSpeed; - IMG_INT32 i32Diff; - IMG_UINT32 ui32Remainder; - - /* - * Find out what the GPU frequency was in the last period. - * This should return a value very close to the frequency passed by the system layer. - */ - ui32EstCoreClockSpeed = - RGXFWIF_GET_GPU_CLOCK_FREQUENCY_HZ(psGpuDVFSTable->ui64CalibrationCRTimediff, - psGpuDVFSTable->ui64CalibrationOSTimediff, - ui32Remainder); - - /* Update GPU frequency used by the driver for a given system layer frequency */ - psTrackingData = &psGpuDVFSTable->asTrackingData[psGpuDVFSTable->ui32FreqIndex]; - - ui32PrevCoreClockSpeed = psTrackingData->ui32EstCoreClockSpeed; - psTrackingData->ui32EstCoreClockSpeed = ui32EstCoreClockSpeed; - psTrackingData->ui32CalibrationCount++; - - i32Diff = (IMG_INT32) (ui32EstCoreClockSpeed - ui32PrevCoreClockSpeed); - - if ((i32Diff < -1000000) || (i32Diff > 1000000)) - { - /* Warn if the frequency changed by more than 1 MHz between recalculations */ - PVR_DPF((PVR_DBG_WARNING, - "GPU frequency calibration of system layer frequency %u Hz (pre %s event): " - "more than 1 MHz difference between old and new value " - "(%u Hz -> %u Hz over %" IMG_UINT64_FMTSPEC " us)", - _RGXGetSystemLayerGPUClockSpeed(psDeviceNode), - _EventToString(eEvent), - RGXFWIF_ROUND_TO_KHZ(ui32PrevCoreClockSpeed), - RGXFWIF_ROUND_TO_KHZ(ui32EstCoreClockSpeed), - psGpuDVFSTable->ui64CalibrationOSTimediff)); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, - "GPU frequency calibration of system layer frequency %u Hz (pre %s event): " - "%u Hz -> %u Hz done over %" IMG_UINT64_FMTSPEC " us", - _RGXGetSystemLayerGPUClockSpeed(psDeviceNode), - _EventToString(eEvent), - RGXFWIF_ROUND_TO_KHZ(ui32PrevCoreClockSpeed), - RGXFWIF_ROUND_TO_KHZ(ui32EstCoreClockSpeed), - psGpuDVFSTable->ui64CalibrationOSTimediff)); - } - - /* Reset time deltas to avoid recalibrating the same frequency over and over again */ - psGpuDVFSTable->ui64CalibrationCRTimediff = 0; - psGpuDVFSTable->ui64CalibrationOSTimediff = 0; - -#if defined(PVRSRV_TIMER_CORRELATION_HISTORY) - /* Update tracking history */ - { - GPU_FREQ_TRACKING_HISTORY *psTrackingHistory; - - psTrackingHistory = &psGpuDVFSTable->asTrackingHistory[psGpuDVFSTable->ui32HistoryIndex]; - psTrackingHistory->ui32EstCoreClockSpeed = ui32EstCoreClockSpeed; - psGpuDVFSTable->ui32HistoryIndex = - (psGpuDVFSTable->ui32HistoryIndex + 1) % RGX_GPU_FREQ_TRACKING_SIZE; - } -#endif - -#else - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(psGpuDVFSTable); - PVR_UNREFERENCED_PARAMETER(eEvent); -#endif -} - -void RGXTimeCorrBegin(IMG_HANDLE hDevHandle, RGXTIMECORR_EVENT eEvent) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_GPU_DVFS_TABLE *psGpuDVFSTable = psDevInfo->psGpuDVFSTable; - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - _RGXGPUFreqCalibrationPeriodStart(psDeviceNode, psGpuDVFSTable); - _RGXMakeTimeCorrData(psDeviceNode, eEvent); -} - -void RGXTimeCorrEnd(IMG_HANDLE hDevHandle, RGXTIMECORR_EVENT eEvent) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_GPU_DVFS_TABLE *psGpuDVFSTable = psDevInfo->psGpuDVFSTable; - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - _RGXGPUFreqCalibrationPeriodStop(psDeviceNode, psGpuDVFSTable); - - if (psGpuDVFSTable->ui64CalibrationOSTimediff >= psGpuDVFSTable->ui32CalibrationPeriod) - { - _RGXGPUFreqCalibrationCalculate(psDeviceNode, psGpuDVFSTable, eEvent); - } -} - -void RGXTimeCorrRestartPeriodic(IMG_HANDLE hDevHandle) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_GPU_DVFS_TABLE *psGpuDVFSTable = psDevInfo->psGpuDVFSTable; - IMG_UINT64 ui64TimeNow = RGXTimeCorrGetClockus64(psDeviceNode); - PVRSRV_DEV_POWER_STATE ePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; - PVRSRV_VZ_RETN_IF_MODE(GUEST); - - if (psGpuDVFSTable == NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: Required data not initialised yet", __func__)); - return; - } - - /* Check if it's the right time to recalibrate the GPU clock frequency */ - if ((ui64TimeNow - psGpuDVFSTable->ui64CalibrationOSTimestamp) < psGpuDVFSTable->ui32CalibrationPeriod) return; - - /* Try to acquire the powerlock, if not possible then don't wait */ - if (PVRSRVPowerTryLock(psDeviceNode) != PVRSRV_OK) return; - - /* If the GPU is off then we can't do anything */ - PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState); - if (ePowerState != PVRSRV_DEV_POWER_STATE_ON) - { - PVRSRVPowerUnlock(psDeviceNode); - return; - } - - /* All checks passed, we can calibrate and correlate */ - RGXTimeCorrEnd(psDeviceNode, RGXTIMECORR_EVENT_PERIODIC); - RGXTimeCorrBegin(psDeviceNode, RGXTIMECORR_EVENT_PERIODIC); - - PVRSRVPowerUnlock(psDeviceNode); -} - -/* - RGXTimeCorrGetClockSource -*/ -RGXTIMECORR_CLOCK_TYPE RGXTimeCorrGetClockSource(const PVRSRV_DEVICE_NODE *psDeviceNode) -{ - return ((PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice)->ui32ClockSource; -} - -/* - RGXTimeCorrSetClockSource -*/ -PVRSRV_ERROR RGXTimeCorrSetClockSource(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXTIMECORR_CLOCK_TYPE eClockType) -{ - return _SetClock(psDeviceNode, NULL, eClockType); -} - -PVRSRV_ERROR -PVRSRVRGXCurrentTime(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT64 * pui64Time) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - - *pui64Time = RGXTimeCorrGetClockns64(psDeviceNode); - - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (rgxtimecorr.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.h b/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.h deleted file mode 100644 index e1cfff9b7abce..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtimecorr.h +++ /dev/null @@ -1,272 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX time correlation and calibration header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX time correlation and calibration routines -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXTIMECORR_H) -#define RGXTIMECORR_H - -#include "img_types.h" -#include "device.h" -#include "osfunc.h" -#include "connection_server.h" - -typedef enum -{ - RGXTIMECORR_CLOCK_MONO, - RGXTIMECORR_CLOCK_MONO_RAW, - RGXTIMECORR_CLOCK_SCHED, - - RGXTIMECORR_CLOCK_LAST -} RGXTIMECORR_CLOCK_TYPE; - -typedef enum -{ - RGXTIMECORR_EVENT_POWER, - RGXTIMECORR_EVENT_DVFS, - RGXTIMECORR_EVENT_PERIODIC, - RGXTIMECORR_EVENT_CLOCK_CHANGE -} RGXTIMECORR_EVENT; - -/* - * Calibrated GPU frequencies are rounded to the nearest multiple of 1 KHz - * before use, to reduce the noise introduced by calculations done with - * imperfect operands (correlated timers not sampled at exactly the same - * time, GPU CR timer incrementing only once every 256 GPU cycles). - * This also helps reducing the variation between consecutive calculations. - */ -#define RGXFWIF_CONVERT_TO_KHZ(freq) (((freq) + 500) / 1000) -#define RGXFWIF_ROUND_TO_KHZ(freq) ((((freq) + 500) / 1000) * 1000) - -/* Constants used in different calculations */ -#define SECONDS_TO_MICROSECONDS (1000000ULL) -#define CRTIME_TO_CYCLES_WITH_US_SCALE (RGX_CRTIME_TICK_IN_CYCLES * SECONDS_TO_MICROSECONDS) - -/* - * Use this macro to get a more realistic GPU core clock speed than the one - * given by the upper layers (used when doing GPU frequency calibration) - */ -#define RGXFWIF_GET_GPU_CLOCK_FREQUENCY_HZ(deltacr_us, deltaos_us, remainder) \ - OSDivide64((deltacr_us) * CRTIME_TO_CYCLES_WITH_US_SCALE, (deltaos_us), &(remainder)) - - -/*! -****************************************************************************** - - @Function RGXTimeCorrGetConversionFactor - - @Description Generate constant used to convert a GPU time difference into - an OS time difference (for more info see rgx_fwif_km.h). - - @Input ui32ClockSpeed : GPU clock speed - - @Return 0 on failure, conversion factor otherwise - -******************************************************************************/ -static inline IMG_UINT64 RGXTimeCorrGetConversionFactor(IMG_UINT32 ui32ClockSpeed) -{ - IMG_UINT32 ui32Remainder; - - if (RGXFWIF_CONVERT_TO_KHZ(ui32ClockSpeed) == 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s: GPU clock frequency %u is too low", - __func__, ui32ClockSpeed)); - - return 0; - } - - return OSDivide64r64(CRTIME_TO_CYCLES_WITH_US_SCALE << RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT, - RGXFWIF_CONVERT_TO_KHZ(ui32ClockSpeed), &ui32Remainder); -} - -/*! -****************************************************************************** - - @Function RGXTimeCorrBegin - - @Description Generate new timer correlation data, and start tracking - the current GPU frequency. - - @Input hDevHandle : RGX Device Node - @Input eEvent : Event associated with the beginning of a timer - correlation period - - @Return void - -******************************************************************************/ -void RGXTimeCorrBegin(IMG_HANDLE hDevHandle, RGXTIMECORR_EVENT eEvent); - -/*! -****************************************************************************** - - @Function RGXTimeCorrEnd - - @Description Stop tracking the CPU and GPU timers, and if possible - recalculate the GPU frequency to a value which makes the timer - correlation data more accurate. - - @Input hDevHandle : RGX Device Node - @Input eEvent : Event associated with the end of a timer - correlation period - - @Return void - -******************************************************************************/ -void RGXTimeCorrEnd(IMG_HANDLE hDevHandle, RGXTIMECORR_EVENT eEvent); - -/*! -****************************************************************************** - - @Function RGXTimeCorrRestartPeriodic - - @Description Perform actions from RGXTimeCorrEnd and RGXTimeCorrBegin, - but only if enough time has passed since the last timer - correlation data was generated. - - @Input hDevHandle : RGX Device Node - - @Return void - -******************************************************************************/ -void RGXTimeCorrRestartPeriodic(IMG_HANDLE hDevHandle); - -/*! -****************************************************************************** - - @Function RGXTimeCorrGetClockns64 - - @Description Returns value of currently selected clock (in ns). - - @Input psDeviceNode : RGX Device Node - @Return clock value from currently selected clock source - -******************************************************************************/ -IMG_UINT64 RGXTimeCorrGetClockns64(const PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -****************************************************************************** - - @Function RGXTimeCorrGetClockus64 - - @Description Returns value of currently selected clock (in us). - - @Input psDeviceNode : RGX Device Node - @Return clock value from currently selected clock source - -******************************************************************************/ -IMG_UINT64 RGXTimeCorrGetClockus64(const PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -****************************************************************************** - - @Function RGXTimeCorrGetClockSource - - @Description Returns currently selected clock source - - @Input psDeviceNode : RGX Device Node - @Return clock source type - -******************************************************************************/ -RGXTIMECORR_CLOCK_TYPE RGXTimeCorrGetClockSource(const PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -****************************************************************************** - - @Function RGXTimeCorrSetClockSource - - @Description Sets clock source for correlation data. - - @Input psDeviceNode : RGX Device Node - @Input eClockType : clock source type - - @Return error code - -******************************************************************************/ -PVRSRV_ERROR RGXTimeCorrSetClockSource(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXTIMECORR_CLOCK_TYPE eClockType); - -/*! -****************************************************************************** - - @Function RGXTimeCorrInitAppHintCallbacks - - @Description Initialise apphint callbacks for timer correlation - related apphints. - - @Input psDeviceNode : RGX Device Node - - @Return void - -******************************************************************************/ -void RGXTimeCorrInitAppHintCallbacks(const PVRSRV_DEVICE_NODE *psDeviceNode); - -/*! -****************************************************************************** - - @Function RGXGetTimeCorrData - - @Description Get a number of the most recent time correlation data points - - @Input psDeviceNode : RGX Device Node - @Output psTimeCorrs : Output array of RGXFWIF_TIME_CORR elements - for data to be written to - @Input ui32NumOut : Number of elements to be written out - - @Return void - -******************************************************************************/ -void RGXGetTimeCorrData(PVRSRV_DEVICE_NODE *psDeviceNode, - RGXFWIF_TIME_CORR *psTimeCorrs, - IMG_UINT32 ui32NumOut); - -/**************************************************************************/ /*! -@Function PVRSRVRGXCurrentTime -@Description Returns the current state of the device timer -@Input psDevData Device data. -@Out pui64Time -@Return PVRSRV_OK on success. -*/ /***************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXCurrentTime(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT64 * pui64Time); - -#endif /* RGXTIMECORR_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.c b/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.c deleted file mode 100644 index d5d11bff91296..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.c +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Timer queries -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description RGX Timer queries -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgxtimerquery.h" -#include "rgxdevice.h" -#include "rgxtimecorr.h" - -#include "rgxfwutils.h" -#include "pdump_km.h" - -PVRSRV_ERROR -PVRSRVRGXBeginTimerQueryKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32QueryId) -{ - PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui32QueryId >= RGX_MAX_TIMER_QUERIES) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockAcquire(psDevInfo->hTimerQueryLock); -#endif - - psDevInfo->bSaveStart = IMG_TRUE; - psDevInfo->bSaveEnd = IMG_TRUE; - - /* clear the stamps, in case there is no Kick */ - psDevInfo->pui64StartTimeById[ui32QueryId] = 0UL; - psDevInfo->pui64EndTimeById[ui32QueryId] = 0UL; - OSWriteMemoryBarrier(&psDevInfo->pui64EndTimeById[ui32QueryId]); - - /* save of the active query index */ - psDevInfo->ui32ActiveQueryId = ui32QueryId; - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockRelease(psDevInfo->hTimerQueryLock); -#endif - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PVRSRVRGXEndTimerQueryKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode) -{ - PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - - PVR_UNREFERENCED_PARAMETER(psConnection); - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockAcquire(psDevInfo->hTimerQueryLock); -#endif - - /* clear off the flags set by Begin(). Note that _START_TIME is - * probably already cleared by Kick() - */ - psDevInfo->bSaveStart = IMG_FALSE; - psDevInfo->bSaveEnd = IMG_FALSE; - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockRelease(psDevInfo->hTimerQueryLock); -#endif - - return PVRSRV_OK; -} - - -PVRSRV_ERROR -PVRSRVRGXQueryTimerKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32QueryId, - IMG_UINT64 * pui64StartTime, - IMG_UINT64 * pui64EndTime) -{ - PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice; - IMG_UINT32 ui32Scheduled; - IMG_UINT32 ui32Completed; - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui32QueryId >= RGX_MAX_TIMER_QUERIES) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockAcquire(psDevInfo->hTimerQueryLock); -#endif - - ui32Scheduled = psDevInfo->aui32ScheduledOnId[ui32QueryId]; - ui32Completed = psDevInfo->pui32CompletedById[ui32QueryId]; - - /* if there was no kick since the Begin() on this id we return 0-s as Begin cleared - * the stamps. If there was no begin the returned data is undefined - but still - * safe from services pov - */ - if (ui32Completed >= ui32Scheduled) - { - * pui64StartTime = psDevInfo->pui64StartTimeById[ui32QueryId]; - * pui64EndTime = psDevInfo->pui64EndTimeById[ui32QueryId]; - - eError = PVRSRV_OK; - } - else - { - eError = PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - -#if !defined(PVRSRV_USE_BRIDGE_LOCK) - OSLockRelease(psDevInfo->hTimerQueryLock); -#endif - return eError; -} - - - -/****************************************************************************** - NOT BRIDGED/EXPORTED FUNCS -******************************************************************************/ -/* writes a time stamp command in the client CCB */ -void -RGXWriteTimestampCommand(void ** ppvPtr, - RGXFWIF_CCB_CMD_TYPE eCmdType, - PRGXFWIF_TIMESTAMP_ADDR pAddr) -{ - RGXFWIF_CCB_CMD_HEADER * psHeader; - PRGXFWIF_TIMESTAMP_ADDR * psTimestampAddr; - - psHeader = (RGXFWIF_CCB_CMD_HEADER *) (*ppvPtr); - - PVR_ASSERT(eCmdType == RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP - || eCmdType == RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP); - - psHeader->eCmdType = eCmdType; - psHeader->ui32CmdSize = (sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN - 1); - - (*ppvPtr) = IMG_OFFSET_ADDR(*ppvPtr, sizeof(RGXFWIF_CCB_CMD_HEADER)); - - psTimestampAddr = (PRGXFWIF_TIMESTAMP_ADDR *) *ppvPtr; - psTimestampAddr->ui32Addr = pAddr.ui32Addr; - - (*ppvPtr) = IMG_OFFSET_ADDR(*ppvPtr, psHeader->ui32CmdSize); -} - - -void -RGX_GetTimestampCmdHelper(PVRSRV_RGXDEV_INFO * psDevInfo, - PRGXFWIF_TIMESTAMP_ADDR * ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR * ppPostAddr, - PRGXFWIF_UFO_ADDR * ppUpdate) -{ - if (ppPreAddr != NULL) - { - if (psDevInfo->bSaveStart) - { - /* drop the SaveStart on the first Kick */ - psDevInfo->bSaveStart = IMG_FALSE; - - RGXSetFirmwareAddress(ppPreAddr, - psDevInfo->psStartTimeMemDesc, - sizeof(IMG_UINT64) * psDevInfo->ui32ActiveQueryId, - RFW_FWADDR_NOREF_FLAG); - } - else - { - ppPreAddr->ui32Addr = 0; - } - } - - if (ppPostAddr != NULL && ppUpdate != NULL) - { - if (psDevInfo->bSaveEnd) - { - RGXSetFirmwareAddress(ppPostAddr, - psDevInfo->psEndTimeMemDesc, - sizeof(IMG_UINT64) * psDevInfo->ui32ActiveQueryId, - RFW_FWADDR_NOREF_FLAG); - - psDevInfo->aui32ScheduledOnId[psDevInfo->ui32ActiveQueryId]++; - - RGXSetFirmwareAddress(ppUpdate, - psDevInfo->psCompletedMemDesc, - sizeof(IMG_UINT32) * psDevInfo->ui32ActiveQueryId, - RFW_FWADDR_NOREF_FLAG); - } - else - { - ppUpdate->ui32Addr = 0; - ppPostAddr->ui32Addr = 0; - } - } -} - - -/****************************************************************************** - End of file (rgxtimerquery.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.h b/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.h deleted file mode 100644 index 81898860dc234..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtimerquery.h +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Timer queries -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX Timer queries functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGX_TIMERQUERIES_H) -#define RGX_TIMERQUERIES_H - -#include "pvrsrv_error.h" -#include "img_types.h" -#include "device.h" -#include "rgxdevice.h" - -#include "connection_server.h" - -/*************************************************************************/ /*! -@Function PVRSRVRGXBeginTimerQueryKM -@Description Opens a new timer query. - -@Input ui32QueryId an identifier between [ 0 and RGX_MAX_TIMER_QUERIES - 1 ] -@Return PVRSRV_OK on success. -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXBeginTimerQueryKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32QueryId); - - -/*************************************************************************/ /*! -@Function PVRSRVRGXEndTimerQueryKM -@Description Closes a timer query - - The lack of ui32QueryId argument expresses the fact that there - can't be overlapping queries open. -@Return PVRSRV_OK on success. -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXEndTimerQueryKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode); - - - -/*************************************************************************/ /*! -@Function PVRSRVRGXQueryTimerKM -@Description Queries the state of the specified timer - -@Input ui32QueryId an identifier between [ 0 and RGX_MAX_TIMER_QUERIES - 1 ] -@Out pui64StartTime -@Out pui64EndTime -@Return PVRSRV_OK on success. - PVRSRV_ERROR_RESOURCE_UNAVAILABLE if the device is still busy with - operations from the queried period - other error code otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVRGXQueryTimerKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32QueryId, - IMG_UINT64 * pui64StartTime, - IMG_UINT64 * pui64EndTime); - - - -/****************************************************************************** - NON BRIDGED/EXPORTED interface -******************************************************************************/ - -/* write the timestamp cmd from the helper*/ -void -RGXWriteTimestampCommand(void ** ppvCmd, - RGXFWIF_CCB_CMD_TYPE eCmdType, - PRGXFWIF_TIMESTAMP_ADDR pAddr); - -/* get the relevant data from the Kick to the helper*/ -void -RGX_GetTimestampCmdHelper(PVRSRV_RGXDEV_INFO * psDevInfo, - PRGXFWIF_TIMESTAMP_ADDR * ppPreAddr, - PRGXFWIF_TIMESTAMP_ADDR * ppPostAddr, - PRGXFWIF_UFO_ADDR * ppUpdate); - -#endif /* RGX_TIMERQUERIES_H */ - -/****************************************************************************** - End of file (rgxtimerquery.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.c b/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.c deleted file mode 100644 index 91b3b8d2830ee..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.c +++ /dev/null @@ -1,1805 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific transfer queue routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pdump_km.h" -#include "rgxdevice.h" -#include "rgxccb.h" -#include "rgxutils.h" -#include "rgxfwutils.h" -#include "rgxtransfer.h" -#include "rgx_tq_shared.h" -#include "rgxmem.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "osfunc.h" -#include "pvr_debug.h" -#include "pvrsrv.h" -#include "rgx_fwif_resetframework.h" -#include "rgx_memallocflags.h" -#include "rgxhwperf.h" -#include "ospvr_gputrace.h" -#include "htbuffer.h" -#include "rgxshader.h" - -#include "pdump_km.h" - -#include "sync_server.h" -#include "sync_internal.h" -#include "sync.h" -#include "rgx_bvnc_defs_km.h" - -#if defined(SUPPORT_BUFFER_SYNC) -#include "pvr_buffer_sync.h" -#endif - -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" - -#include "rgxtimerquery.h" - -/* Enable this to dump the compiled list of UFOs prior to kick call */ -#define ENABLE_TQ_UFO_DUMP 0 - -//#define TRANSFER_CHECKPOINT_DEBUG 1 - -#if defined(TRANSFER_CHECKPOINT_DEBUG) -#define CHKPT_DBG(X) PVR_DPF(X) -#else -#define CHKPT_DBG(X) -#endif - -typedef struct { - DEVMEM_MEMDESC *psFWContextStateMemDesc; - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - IMG_UINT32 ui32Priority; -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif -} RGX_SERVER_TQ_3D_DATA; - -typedef struct { - RGX_SERVER_COMMON_CONTEXT *psServerCommonContext; - IMG_UINT32 ui32Priority; -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif -} RGX_SERVER_TQ_2D_DATA; - -struct _RGX_SERVER_TQ_CONTEXT_ { - PVRSRV_DEVICE_NODE *psDeviceNode; - DEVMEM_MEMDESC *psFWFrameworkMemDesc; - DEVMEM_MEMDESC *psFWTransferContextMemDesc; - IMG_UINT32 ui32Flags; -#define RGX_SERVER_TQ_CONTEXT_FLAGS_2D (1<<0) -#define RGX_SERVER_TQ_CONTEXT_FLAGS_3D (1<<1) - RGX_SERVER_TQ_3D_DATA s3DData; - RGX_SERVER_TQ_2D_DATA s2DData; - DLLIST_NODE sListNode; - ATOMIC_T hIntJobRef; - IMG_UINT32 ui32PDumpFlags; - /* per-prepare sync address lists */ - SYNC_ADDR_LIST asSyncAddrListFence[TQ_MAX_PREPARES_PER_SUBMIT]; - SYNC_ADDR_LIST asSyncAddrListUpdate[TQ_MAX_PREPARES_PER_SUBMIT]; - POS_LOCK hLock; -}; - -/* - Static functions used by transfer context code -*/ -static PVRSRV_ERROR _Create3DTransferContext(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psAllocatedMemDesc, - IMG_UINT32 ui32AllocatedOffset, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - IMG_UINT32 ui32Priority, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_TQ_3D_DATA *ps3DData, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress) -{ - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - IMG_UINT ui3DRegISPStateStoreSize = 0; - IMG_UINT uiNumISPStoreRegs = 1; /* default value 1 expected */ - /* - Allocate device memory for the firmware GPU context suspend state. - Note: the FW reads/writes the state to memory by accessing the GPU register interface. - */ - PDUMPCOMMENT(psDeviceNode, "Allocate RGX firmware TQ/3D context suspend state"); - - if (!RGX_IS_FEATURE_SUPPORTED(psDevInfo, XE_MEMORY_HIERARCHY)) - { - uiNumISPStoreRegs = psDeviceNode->pfnGetDeviceFeatureValue(psDeviceNode, - RGX_FEATURE_NUM_ISP_IPP_PIPES_IDX); - } - - /* Calculate the size of the 3DCTX ISP state */ - ui3DRegISPStateStoreSize = sizeof(RGXFWIF_3DCTX_STATE) + - uiNumISPStoreRegs * sizeof(((RGXFWIF_3DCTX_STATE *)0)->au3DReg_ISP_STORE[0]); - -#if defined(SUPPORT_BUFFER_SYNC) - ps3DData->psBufferSyncContext = - pvr_buffer_sync_context_create(psDeviceNode->psDevConfig->pvOSDevice, - "rogue-tq3d"); - if (IS_ERR(ps3DData->psBufferSyncContext)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create buffer_sync context (err=%ld)", - __func__, PTR_ERR(ps3DData->psBufferSyncContext))); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_buffer_sync_context_create; - } -#endif - - eError = DevmemFwAllocate(psDevInfo, - ui3DRegISPStateStoreSize, - RGX_FWCOMCTX_ALLOCFLAGS, - "FwTQ3DContext", - &ps3DData->psFWContextStateMemDesc); - if (eError != PVRSRV_OK) - { - goto fail_contextswitchstate; - } - - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_TQ_3D, - RGXFWIF_DM_3D, - NULL, - psAllocatedMemDesc, - ui32AllocatedOffset, - psFWMemContextMemDesc, - ps3DData->psFWContextStateMemDesc, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_TQ3D_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_TQ3D_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - UINT_MAX, /* max deadline MS */ - ui64RobustnessAddress, - psInfo, - &ps3DData->psServerCommonContext); - if (eError != PVRSRV_OK) - { - goto fail_contextalloc; - } - - - PDUMPCOMMENT(psDeviceNode, "Dump 3D context suspend state buffer"); - DevmemPDumpLoadMem(ps3DData->psFWContextStateMemDesc, 0, sizeof(RGXFWIF_3DCTX_STATE), PDUMP_FLAGS_CONTINUOUS); - - ps3DData->ui32Priority = ui32Priority; - return PVRSRV_OK; - -fail_contextalloc: - DevmemFwUnmapAndFree(psDevInfo, ps3DData->psFWContextStateMemDesc); -fail_contextswitchstate: -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(ps3DData->psBufferSyncContext); - ps3DData->psBufferSyncContext = NULL; -fail_buffer_sync_context_create: -#endif - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -#if defined(RGX_FEATURE_TLA_BIT_MASK) -static PVRSRV_ERROR _Create2DTransferContext(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DEVMEM_MEMDESC *psFWMemContextMemDesc, - IMG_UINT32 ui32Priority, - RGX_COMMON_CONTEXT_INFO *psInfo, - RGX_SERVER_TQ_2D_DATA *ps2DData, - IMG_UINT32 ui32CCBAllocSizeLog2, - IMG_UINT32 ui32CCBMaxAllocSizeLog2, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress) -{ - PVRSRV_ERROR eError; - -#if defined(SUPPORT_BUFFER_SYNC) - ps2DData->psBufferSyncContext = - pvr_buffer_sync_context_create(psDeviceNode->psDevConfig->pvOSDevice, - "rogue-tqtla"); - if (IS_ERR(ps2DData->psBufferSyncContext)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to create buffer_sync context (err=%ld)", - __func__, PTR_ERR(ps2DData->psBufferSyncContext))); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_buffer_sync_context_create; - } -#endif - - eError = FWCommonContextAllocate(psConnection, - psDeviceNode, - REQ_TYPE_TQ_2D, - RGXFWIF_DM_2D, - NULL, - NULL, - 0, - psFWMemContextMemDesc, - NULL, - ui32CCBAllocSizeLog2 ? ui32CCBAllocSizeLog2 : RGX_TQ2D_CCB_SIZE_LOG2, - ui32CCBMaxAllocSizeLog2 ? ui32CCBMaxAllocSizeLog2 : RGX_TQ2D_CCB_MAX_SIZE_LOG2, - ui32ContextFlags, - ui32Priority, - UINT_MAX, /* max deadline MS */ - ui64RobustnessAddress, - psInfo, - &ps2DData->psServerCommonContext); - if (eError != PVRSRV_OK) - { - goto fail_contextalloc; - } - - ps2DData->ui32Priority = ui32Priority; - return PVRSRV_OK; - -fail_contextalloc: -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(ps2DData->psBufferSyncContext); - ps2DData->psBufferSyncContext = NULL; -fail_buffer_sync_context_create: -#endif - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - - -static PVRSRV_ERROR _Destroy2DTransferContext(RGX_SERVER_TQ_2D_DATA *ps2DData, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psDeviceNode, - ps2DData->psServerCommonContext, - RGXFWIF_DM_2D, - ui32PDumpFlags); - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free its resources */ - FWCommonContextFree(ps2DData->psServerCommonContext); - ps2DData->psServerCommonContext = NULL; - -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(ps2DData->psBufferSyncContext); - ps2DData->psBufferSyncContext = NULL; -#endif - - return PVRSRV_OK; -} -#endif /* #if defined(RGX_FEATURE_TLA_BIT_MASK) */ - -static PVRSRV_ERROR _Destroy3DTransferContext(RGX_SERVER_TQ_3D_DATA *ps3DData, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eError; - - /* Check if the FW has finished with this resource ... */ - eError = RGXFWRequestCommonContextCleanUp(psDeviceNode, - ps3DData->psServerCommonContext, - RGXFWIF_DM_3D, - ui32PDumpFlags); - if (eError == PVRSRV_ERROR_RETRY) - { - return eError; - } - else if (eError != PVRSRV_OK) - { - PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)", - __func__, - PVRSRVGetErrorString(eError))); - return eError; - } - - /* ... it has so we can free its resources */ - DevmemFwUnmapAndFree(psDeviceNode->pvDevice, ps3DData->psFWContextStateMemDesc); - FWCommonContextFree(ps3DData->psServerCommonContext); - ps3DData->psServerCommonContext = NULL; - -#if defined(SUPPORT_BUFFER_SYNC) - pvr_buffer_sync_context_destroy(ps3DData->psBufferSyncContext); - ps3DData->psBufferSyncContext = NULL; -#endif - - return PVRSRV_OK; -} - - -/* - * PVRSRVCreateTransferContextKM - */ -PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pabyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU8888, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - RGX_SERVER_TQ_CONTEXT **ppsTransferContext, - PMR **ppsCLIPMRMem, - PMR **ppsUSCPMRMem) -{ - RGX_SERVER_TQ_CONTEXT *psTransferContext; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); - RGX_COMMON_CONTEXT_INFO sInfo = {NULL}; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Allocate the server side structure */ - *ppsTransferContext = NULL; - psTransferContext = OSAllocZMem(sizeof(*psTransferContext)); - if (psTransferContext == NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* - Create the FW transfer context, this has the TQ common - context embedded within it - */ - eError = DevmemFwAllocate(psDevInfo, - sizeof(RGXFWIF_FWTRANSFERCONTEXT), - RGX_FWCOMCTX_ALLOCFLAGS, - "FwTransferContext", - &psTransferContext->psFWTransferContextMemDesc); - if (eError != PVRSRV_OK) - { - goto fail_fwtransfercontext; - } - - eError = OSLockCreate(&psTransferContext->hLock); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create lock (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_createlock; - } - - psTransferContext->psDeviceNode = psDeviceNode; - - if (ui32FrameworkCommandSize) - { - /* - * Create the FW framework buffer - */ - eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, - &psTransferContext->psFWFrameworkMemDesc, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to allocate firmware GPU framework state (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcreate; - } - - /* Copy the Framework client data into the framework buffer */ - eError = PVRSRVRGXFrameworkCopyCommand(psDeviceNode, - psTransferContext->psFWFrameworkMemDesc, - pabyFrameworkCommand, - ui32FrameworkCommandSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Failed to populate the framework buffer (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_frameworkcopy; - } - - sInfo.psFWFrameworkMemDesc = psTransferContext->psFWFrameworkMemDesc; - } - - eError = _Create3DTransferContext(psConnection, - psDeviceNode, - psTransferContext->psFWTransferContextMemDesc, - offsetof(RGXFWIF_FWTRANSFERCONTEXT, sTQContext), - psFWMemContextMemDesc, - ui32Priority, - &sInfo, - &psTransferContext->s3DData, - U32toU8_Unpack3(ui32PackedCCBSizeU8888), - U32toU8_Unpack4(ui32PackedCCBSizeU8888), - ui32ContextFlags, - ui64RobustnessAddress); - if (eError != PVRSRV_OK) - { - goto fail_3dtransfercontext; - } - psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_3D; - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA)) - { - eError = _Create2DTransferContext(psConnection, - psDeviceNode, - psFWMemContextMemDesc, - ui32Priority, - &sInfo, - &psTransferContext->s2DData, - U32toU8_Unpack1(ui32PackedCCBSizeU8888), - U32toU8_Unpack2(ui32PackedCCBSizeU8888), - ui32ContextFlags, - ui64RobustnessAddress); - if (eError != PVRSRV_OK) - { - goto fail_2dtransfercontext; - } - psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_2D; - } -#endif - - PVRSRVTQAcquireShaders(psDeviceNode, ppsCLIPMRMem, ppsUSCPMRMem); - - { - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock); - dllist_add_to_tail(&(psDevInfo->sTransferCtxtListHead), &(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock); - *ppsTransferContext = psTransferContext; - } - - return PVRSRV_OK; - -#if defined(RGX_FEATURE_TLA_BIT_MASK) -fail_2dtransfercontext: - _Destroy3DTransferContext(&psTransferContext->s3DData, - psTransferContext->psDeviceNode, - psTransferContext->ui32PDumpFlags); -#endif -fail_3dtransfercontext: -fail_frameworkcopy: - if (psTransferContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWFrameworkMemDesc); - } -fail_frameworkcreate: - OSLockDestroy(psTransferContext->hLock); -fail_createlock: - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWTransferContextMemDesc); -fail_fwtransfercontext: - OSFreeMem(psTransferContext); - PVR_ASSERT(eError != PVRSRV_OK); - *ppsTransferContext = NULL; - return eError; -} - -PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransferContext) -{ - PVRSRV_ERROR eError; - PVRSRV_RGXDEV_INFO *psDevInfo = psTransferContext->psDeviceNode->pvDevice; - IMG_UINT32 i; - - /* remove node from list before calling destroy - as destroy, if successful - * will invalidate the node - * must be re-added if destroy fails - */ - OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock); - dllist_remove_node(&(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock); - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_2D) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - eError = _Destroy2DTransferContext(&psTransferContext->s2DData, - psTransferContext->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - goto fail_destroy2d; - } - /* We've freed the 2D context, don't try to free it again */ - psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_2D; - } -#endif - - if (psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_3D) - { - eError = _Destroy3DTransferContext(&psTransferContext->s3DData, - psTransferContext->psDeviceNode, - PDUMP_FLAGS_CONTINUOUS); - if (eError != PVRSRV_OK) - { - goto fail_destroy3d; - } - /* We've freed the 3D context, don't try to free it again */ - psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_3D; - } - - /* free any resources within the per-prepare UFO address stores */ - for (i = 0; i < TQ_MAX_PREPARES_PER_SUBMIT; i++) - { - SyncAddrListDeinit(&psTransferContext->asSyncAddrListFence[i]); - SyncAddrListDeinit(&psTransferContext->asSyncAddrListUpdate[i]); - } - - if (psTransferContext->psFWFrameworkMemDesc) - { - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWFrameworkMemDesc); - } - - DevmemFwUnmapAndFree(psDevInfo, psTransferContext->psFWTransferContextMemDesc); - - OSLockDestroy(psTransferContext->hLock); - - OSFreeMem(psTransferContext); - - return PVRSRV_OK; - -fail_destroy3d: -#if defined(RGX_FEATURE_TLA_BIT_MASK) - -fail_destroy2d: -#endif - OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock); - dllist_add_to_tail(&(psDevInfo->sTransferCtxtListHead), &(psTransferContext->sListNode)); - OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock); - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/* - * PVRSRVSubmitTQ3DKickKM - */ -PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, - IMG_UINT32 ui32PrepareCount, - IMG_UINT32 *paui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ***papauiClientUpdateUFODevVarBlock, - IMG_UINT32 **papaui32ClientUpdateSyncOffset, - IMG_UINT32 **papaui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE i2DUpdateTimeline, - PVRSRV_FENCE *pi2DUpdateFence, - PVRSRV_TIMELINE i3DUpdateTimeline, - PVRSRV_FENCE *pi3DUpdateFence, - IMG_CHAR szFenceName[32], - IMG_UINT32 *paui32FWCommandSize, - IMG_UINT8 **papaui8FWCommand, - IMG_UINT32 *pui32TQPrepareFlags, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = psTransferContext->psDeviceNode; - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - RGX_CCB_CMD_HELPER_DATA *pas3DCmdHelper; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - RGX_CCB_CMD_HELPER_DATA *pas2DCmdHelper; -#endif - IMG_UINT32 ui323DCmdCount = 0; - IMG_UINT32 ui323DCmdLast = 0; - IMG_UINT32 ui323DCmdOffset = 0; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - IMG_UINT32 ui322DCmdCount = 0; - IMG_UINT32 ui322DCmdLast = 0; - IMG_UINT32 ui322DCmdOffset = 0; -#endif - IMG_UINT32 ui32PDumpFlags = PDUMP_FLAGS_NONE; - IMG_UINT32 i; - IMG_UINT64 uiCheckFenceUID = 0; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - IMG_UINT64 ui2DUpdateFenceUID = 0; -#endif - IMG_UINT64 ui3DUpdateFenceUID = 0; - - PSYNC_CHECKPOINT ps3DUpdateSyncCheckpoint = NULL; - PSYNC_CHECKPOINT *apsFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32FenceSyncCheckpointCount = 0; - IMG_UINT32 *pui323DIntAllocatedUpdateValues = NULL; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - PSYNC_CHECKPOINT ps2DUpdateSyncCheckpoint = NULL; - IMG_UINT32 *pui322DIntAllocatedUpdateValues = NULL; - PVRSRV_CLIENT_SYNC_PRIM *ps2DFenceTimelineUpdateSync = NULL; - IMG_UINT32 ui322DFenceTimelineUpdateValue = 0; - void *pv2DUpdateFenceFinaliseData = NULL; -#endif - PVRSRV_CLIENT_SYNC_PRIM *ps3DFenceTimelineUpdateSync = NULL; - IMG_UINT32 ui323DFenceTimelineUpdateValue = 0; - void *pv3DUpdateFenceFinaliseData = NULL; -#if defined(SUPPORT_BUFFER_SYNC) - PSYNC_CHECKPOINT psBufferUpdateSyncCheckpoint = NULL; - struct pvr_buffer_sync_append_data *psBufferSyncData = NULL; - PSYNC_CHECKPOINT *apsBufferFenceSyncCheckpoints = NULL; - IMG_UINT32 ui32BufferFenceSyncCheckpointCount = 0; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_ERROR eError2; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - PVRSRV_FENCE i2DUpdateFence = PVRSRV_NO_FENCE; -#endif - PVRSRV_FENCE i3DUpdateFence = PVRSRV_NO_FENCE; - IMG_UINT32 ui32IntJobRef = OSAtomicIncrement(&psDevInfo->iCCBSubmissionOrdinal); - IMG_UINT32 ui32PreparesDone = 0; - - - PRGXFWIF_TIMESTAMP_ADDR pPreAddr; - PRGXFWIF_TIMESTAMP_ADDR pPostAddr; - PRGXFWIF_UFO_ADDR pRMWUFOAddr; - -#if !defined(RGX_FEATURE_TLA_BIT_MASK) - PVR_UNREFERENCED_PARAMETER(i2DUpdateTimeline); - PVR_UNREFERENCED_PARAMETER(pi2DUpdateFence); -#endif - - RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psDeviceNode->pvDevice, - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr); -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (i2DUpdateTimeline != PVRSRV_NO_TIMELINE && !pi2DUpdateFence) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } -#endif - if (i3DUpdateTimeline != PVRSRV_NO_TIMELINE && !pi3DUpdateFence) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Validate sync prim fence/update value ptrs - * for each prepare. - */ - { - IMG_UINT32 ui32Prepare; - IMG_UINT32 *pui32UpdateCount = paui32ClientUpdateCount; - IMG_UINT32 **papui32UpdateValue = papaui32ClientUpdateValue; - - /* Check that we have not been given a null ptr for - * update count parameters. - */ - PVR_LOG_RETURN_IF_FALSE((paui32ClientUpdateCount != NULL), - "paui32ClientUpdateCount NULL", - PVRSRV_ERROR_INVALID_PARAMS); - - for (ui32Prepare=0; ui32Prepare 0) - { - PVR_LOG_RETURN_IF_FALSE(*papui32UpdateValue != NULL, - "paui32ClientUpdateValue NULL but " - "ui32ClientUpdateCount > 0", - PVRSRV_ERROR_INVALID_PARAMS); - } - /* Advance local ptr to update values ptr for next prepare. */ - papui32UpdateValue++; - /* Advance local ptr to update count for next prepare. */ - pui32UpdateCount++; - } - } - - /* Ensure the string is null-terminated (Required for safety) */ - szFenceName[31] = '\0'; - - if ((ui32PrepareCount == 0) || (ui32PrepareCount > TQ_MAX_PREPARES_PER_SUBMIT)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32SyncPMRCount != 0) - { - if (!ppsSyncPMRs) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if defined(SUPPORT_BUFFER_SYNC) - /* PMR sync is valid only when there is no batching */ - if ((ui32PrepareCount != 1)) -#endif - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - OSLockAcquire(psTransferContext->hLock); - - /* We can't allocate the required amount of stack space on all consumer architectures */ - pas3DCmdHelper = OSAllocMem(sizeof(*pas3DCmdHelper) * ui32PrepareCount); - if (pas3DCmdHelper == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc3dhelper; - } - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - pas2DCmdHelper = OSAllocMem(sizeof(*pas2DCmdHelper) * ui32PrepareCount); - if (pas2DCmdHelper == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc2dhelper; - } -#endif - - if (iCheckFence != PVRSRV_NO_FENCE) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointResolveFence (iCheckFence=%d), psDeviceNode->hSyncCheckpointContext=<%p>...", __func__, iCheckFence, (void*)psDeviceNode->hSyncCheckpointContext)); - /* Resolve the sync checkpoints that make up the input fence */ - eError = SyncCheckpointResolveFence(psDeviceNode->hSyncCheckpointContext, - iCheckFence, - &ui32FenceSyncCheckpointCount, - &apsFenceSyncCheckpoints, - &uiCheckFenceUID, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, returned ERROR (eError=%d)", __func__, eError)); - goto fail_resolve_fencesync_input_fence; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: ...done, fence %d contained %d checkpoints (apsFenceSyncCheckpoints=<%p>)", __func__, iCheckFence, ui32FenceSyncCheckpointCount, (void*)apsFenceSyncCheckpoints)); -#if defined(TRANSFER_CHECKPOINT_DEBUG) - if (ui32FenceSyncCheckpointCount > 0) - { - IMG_UINT32 ii; - for (ii=0; ii", __func__, ii, (void*)psNextCheckpoint)); - } - } -#endif - } - /* - Ensure we do the right thing for server syncs which cross call boundaries - */ - for (i=0;iasSyncAddrListFence[i]; - SYNC_ADDR_LIST *psSyncAddrListUpdate = &psTransferContext->asSyncAddrListUpdate[i]; - IMG_UINT32 ui32IntClientFenceCount = 0U; - IMG_UINT32 ui32IntClientUpdateCount = paui32ClientUpdateCount[i]; - IMG_UINT32 *paui32IntUpdateValue = papaui32ClientUpdateValue[i]; -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif - - PVRSRV_FENCE *piUpdateFence = NULL; - PVRSRV_TIMELINE iUpdateTimeline = PVRSRV_NO_TIMELINE; - void **ppvUpdateFenceFinaliseData = NULL; - PSYNC_CHECKPOINT * ppsUpdateSyncCheckpoint = NULL; - PVRSRV_CLIENT_SYNC_PRIM **ppsFenceTimelineUpdateSync = NULL; - IMG_UINT32 *pui32FenceTimelineUpdateValue = NULL; - IMG_UINT32 **ppui32IntAllocatedUpdateValues = NULL; - IMG_BOOL bCheckFence = IMG_FALSE; - IMG_BOOL bUpdateFence = IMG_FALSE; - IMG_UINT64 *puiUpdateFenceUID = NULL; - - IMG_BOOL bCCBStateOpen = IMG_FALSE; - - if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 3D)) - { - psServerCommonCtx = psTransferContext->s3DData.psServerCommonContext; - psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx); - pszCommandName = "TQ-3D"; - psCmdHelper = &pas3DCmdHelper[ui323DCmdCount++]; - eType = RGXFWIF_CCB_CMD_TYPE_TQ_3D; -#if defined(SUPPORT_BUFFER_SYNC) - psBufferSyncContext = psTransferContext->s3DData.psBufferSyncContext; -#endif - bCheckFence = ui323DCmdCount == 1; - bUpdateFence = ui323DCmdCount == ui323DCmdLast - && i3DUpdateTimeline != PVRSRV_NO_TIMELINE; - - if (bUpdateFence) - { - piUpdateFence = &i3DUpdateFence; - iUpdateTimeline = i3DUpdateTimeline; - ppvUpdateFenceFinaliseData = &pv3DUpdateFenceFinaliseData; - ppsUpdateSyncCheckpoint = &ps3DUpdateSyncCheckpoint; - ppsFenceTimelineUpdateSync = &ps3DFenceTimelineUpdateSync; - pui32FenceTimelineUpdateValue = &ui323DFenceTimelineUpdateValue; - ppui32IntAllocatedUpdateValues = &pui323DIntAllocatedUpdateValues; - puiUpdateFenceUID = &ui3DUpdateFenceUID; - } - } - else -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 2D) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - psServerCommonCtx = psTransferContext->s2DData.psServerCommonContext; - psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx); - pszCommandName = "TQ-2D"; - psCmdHelper = &pas2DCmdHelper[ui322DCmdCount++]; - eType = RGXFWIF_CCB_CMD_TYPE_TQ_2D; -#if defined(SUPPORT_BUFFER_SYNC) - psBufferSyncContext = psTransferContext->s2DData.psBufferSyncContext; -#endif - bCheckFence = ui322DCmdCount == 1; - bUpdateFence = ui322DCmdCount == ui322DCmdLast - && i2DUpdateTimeline != PVRSRV_NO_TIMELINE; - - if (bUpdateFence) - { - piUpdateFence = &i2DUpdateFence; - iUpdateTimeline = i2DUpdateTimeline; - ppvUpdateFenceFinaliseData = &pv2DUpdateFenceFinaliseData; - ppsUpdateSyncCheckpoint = &ps2DUpdateSyncCheckpoint; - ppsFenceTimelineUpdateSync = &ps2DFenceTimelineUpdateSync; - pui32FenceTimelineUpdateValue = &ui322DFenceTimelineUpdateValue; - ppui32IntAllocatedUpdateValues = &pui322DIntAllocatedUpdateValues; - puiUpdateFenceUID = &ui2DUpdateFenceUID; - } - } - else -#endif - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto fail_prepare_loop; - } - - if (i == 0) - { - ui32PDumpFlags = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) != 0) ? PDUMP_FLAGS_CONTINUOUS : PDUMP_FLAGS_NONE; - PDUMPCOMMENTWITHFLAGS(psDeviceNode, ui32PDumpFlags, - "%s Command Server Submit on FWCtx %08x", pszCommandName, FWCommonContextGetFWAddress(psServerCommonCtx).ui32Addr); - psTransferContext->ui32PDumpFlags |= ui32PDumpFlags; - } - else - { - IMG_UINT32 ui32NewPDumpFlags = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) != 0) ? PDUMP_FLAGS_CONTINUOUS : PDUMP_FLAGS_NONE; - if (ui32NewPDumpFlags != ui32PDumpFlags) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - PVR_DPF((PVR_DBG_ERROR, "%s: Mixing of continuous and non-continuous command in a batch is not permitted", __func__)); - goto fail_prepare_loop; - } - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: SyncAddrListPopulate(psTransferContext->sSyncAddrListFence, %d fences)", __func__, ui32IntClientFenceCount)); - eError = SyncAddrListPopulate(psSyncAddrListFence, - 0, - NULL, - NULL); - if (eError != PVRSRV_OK) - { - goto fail_prepare_loop; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: SyncAddrListPopulate(psTransferContext->asSyncAddrListUpdate[], %d updates)", __func__, ui32IntClientUpdateCount)); - eError = SyncAddrListPopulate(psSyncAddrListUpdate, - ui32IntClientUpdateCount, - papauiClientUpdateUFODevVarBlock[i], - papaui32ClientUpdateSyncOffset[i]); - if (eError != PVRSRV_OK) - { - goto fail_prepare_loop; - } - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psSyncAddrListUpdate->pasFWAddrs; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: (after sync prims) ui32IntClientUpdateCount=%d", __func__, ui32IntClientUpdateCount)); - if (ui32SyncPMRCount) - { -#if defined(SUPPORT_BUFFER_SYNC) - int err; - - CHKPT_DBG((PVR_DBG_ERROR, "%s: Calling pvr_buffer_sync_resolve_and_create_fences", __func__)); - err = pvr_buffer_sync_resolve_and_create_fences(psBufferSyncContext, - psTransferContext->psDeviceNode->hSyncCheckpointContext, - ui32SyncPMRCount, - ppsSyncPMRs, - paui32SyncPMRFlags, - &ui32BufferFenceSyncCheckpointCount, - &apsBufferFenceSyncCheckpoints, - &psBufferUpdateSyncCheckpoint, - &psBufferSyncData); - if (err) - { - switch (err) - { - case -EINTR: - eError = PVRSRV_ERROR_RETRY; - break; - case -ENOMEM: - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - break; - default: - eError = PVRSRV_ERROR_INVALID_PARAMS; - break; - } - - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: pvr_buffer_sync_resolve_and_create_fences failed (%s)", __func__, PVRSRVGetErrorString(eError))); - } - goto fail_resolve_buffersync_input_fence; - } - - /* Append buffer sync fences */ - if (ui32BufferFenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d buffer sync checkpoints to TQ Fence (psSyncAddrListFence=<%p>, pauiIntFenceUFOAddress=<%p>)...", __func__, ui32BufferFenceSyncCheckpointCount, (void*)psSyncAddrListFence , (void*)pauiIntFenceUFOAddress)); - SyncAddrListAppendAndDeRefCheckpoints(psSyncAddrListFence, - ui32BufferFenceSyncCheckpointCount, - apsBufferFenceSyncCheckpoints); - if (!pauiIntFenceUFOAddress) - { - pauiIntFenceUFOAddress = psSyncAddrListFence->pasFWAddrs; - } - ui32IntClientFenceCount += ui32BufferFenceSyncCheckpointCount; - } - - if (psBufferUpdateSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append 1 buffer sync checkpoint<%p> to TQ Update (&psTransferContext->asSyncAddrListUpdate[i]=<%p>, pauiIntUpdateUFOAddress=<%p>)...", __func__, (void*)psBufferUpdateSyncCheckpoint, (void*)psSyncAddrListUpdate , (void*)pauiIntUpdateUFOAddress)); - /* Append the update (from output fence) */ - SyncAddrListAppendCheckpoints(psSyncAddrListUpdate, - 1, - &psBufferUpdateSyncCheckpoint); - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psSyncAddrListUpdate->pasFWAddrs; - } - ui32IntClientUpdateCount++; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: (after buffer_sync) ui32IntClientFenceCount=%d, ui32IntClientUpdateCount=%d", __func__, ui32IntClientFenceCount, ui32IntClientUpdateCount)); -#else /* defined(SUPPORT_BUFFER_SYNC) */ - PVR_DPF((PVR_DBG_ERROR, "%s: Buffer sync not supported but got %u buffers", __func__, ui32SyncPMRCount)); - PVR_DPF((PVR_DBG_ERROR, "%s: <--EXIT(%d)", __func__, PVRSRV_ERROR_INVALID_PARAMS)); - OSLockRelease(psTransferContext->hLock); - return PVRSRV_ERROR_INVALID_PARAMS; -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - } - - /* Create the output fence (if required) */ - if (bUpdateFence) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: calling SyncCheckpointCreateFence (piUpdateFence=%p, iUpdateTimeline=%d, psTranserContext->psDeviceNode->hSyncCheckpointContext=<%p>)", __func__, piUpdateFence, iUpdateTimeline, (void*)psDeviceNode->hSyncCheckpointContext)); - eError = SyncCheckpointCreateFence(psDeviceNode, - szFenceName, - iUpdateTimeline, - psDeviceNode->hSyncCheckpointContext, - piUpdateFence, - puiUpdateFenceUID, - ppvUpdateFenceFinaliseData, - ppsUpdateSyncCheckpoint, - (void*)ppsFenceTimelineUpdateSync, - pui32FenceTimelineUpdateValue, - ui32PDumpFlags); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: SyncCheckpointCreateFence failed (%s)", - __func__, - PVRSRVGetErrorString(eError))); - goto fail_prepare_loop; - } - - CHKPT_DBG((PVR_DBG_ERROR, "%s: returned from SyncCheckpointCreateFence (piUpdateFence=%p)", __func__, piUpdateFence)); - - /* Append the sync prim update for the timeline (if required) */ - if (*ppsFenceTimelineUpdateSync) - { - IMG_UINT32 *pui32TimelineUpdateWp = NULL; - - /* Allocate memory to hold the list of update values (including our timeline update) */ - *ppui32IntAllocatedUpdateValues = OSAllocMem(sizeof(**ppui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); - if (!*ppui32IntAllocatedUpdateValues) - { - /* Failed to allocate memory */ - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_prepare_loop; - } - OSCachedMemSet(*ppui32IntAllocatedUpdateValues, 0xbb, sizeof(**ppui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount+1)); -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferUpdateSyncCheckpoint) - { - /* Copy the update values into the new memory, then append our timeline update value */ - OSCachedMemCopy(*ppui32IntAllocatedUpdateValues, paui32IntUpdateValue, sizeof(**ppui32IntAllocatedUpdateValues) * (ui32IntClientUpdateCount-1)); - pui32TimelineUpdateWp = *ppui32IntAllocatedUpdateValues + (ui32IntClientUpdateCount-1); - } - else -#endif - { - /* Copy the update values into the new memory, then append our timeline update value */ - OSCachedMemCopy(*ppui32IntAllocatedUpdateValues, paui32IntUpdateValue, sizeof(**ppui32IntAllocatedUpdateValues) * ui32IntClientUpdateCount); - pui32TimelineUpdateWp = *ppui32IntAllocatedUpdateValues + ui32IntClientUpdateCount; - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: Appending the additional update value 0x%x)", __func__, *pui32FenceTimelineUpdateValue)); - /* Now set the additional update value */ - *pui32TimelineUpdateWp = *pui32FenceTimelineUpdateValue; -#if defined(TRANSFER_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)*ppui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Now append the timeline sync prim addr to the transfer context update list */ - SyncAddrListAppendSyncPrim(psSyncAddrListUpdate, - *ppsFenceTimelineUpdateSync); - ui32IntClientUpdateCount++; -#if defined(TRANSFER_CHECKPOINT_DEBUG) - if (ui32IntClientUpdateCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)*ppui32IntAllocatedUpdateValues; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - /* Ensure paui32IntUpdateValue is now pointing to our new array of update values */ - CHKPT_DBG((PVR_DBG_ERROR, "%s: set paui32IntUpdateValue<%p> to point to *ppui32IntAllocatedUpdateValues<%p>", __func__, (void*)paui32IntUpdateValue, (void*)*ppui32IntAllocatedUpdateValues)); - paui32IntUpdateValue = *ppui32IntAllocatedUpdateValues; - } - } - - if (bCheckFence && ui32FenceSyncCheckpointCount) - { - /* Append the checks (from input fence) */ - if (ui32FenceSyncCheckpointCount > 0) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append %d sync checkpoints to TQ Fence (psSyncAddrListFence=<%p>)...", __func__, ui32FenceSyncCheckpointCount, (void*)psSyncAddrListFence)); - SyncAddrListAppendCheckpoints(psSyncAddrListFence, - ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - if (!pauiIntFenceUFOAddress) - { - pauiIntFenceUFOAddress = psSyncAddrListFence->pasFWAddrs; - } - ui32IntClientFenceCount += ui32FenceSyncCheckpointCount; - } -#if defined(TRANSFER_CHECKPOINT_DEBUG) - if (ui32IntClientFenceCount > 0) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiIntFenceUFOAddress; - - for (iii=0; iiipasFWAddrs[%d](<%p>) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - if (bUpdateFence && *ppsUpdateSyncCheckpoint) - { - /* Append the update (from output fence) */ - CHKPT_DBG((PVR_DBG_ERROR, "%s: Append 1 sync checkpoint to TQ Update (psSyncAddrListUpdate=<%p>, pauiIntUpdateUFOAddress=<%p>)...", __func__, (void*)&psTransferContext->asSyncAddrListUpdate , (void*)pauiIntUpdateUFOAddress)); - SyncAddrListAppendCheckpoints(psSyncAddrListUpdate, - 1, - ppsUpdateSyncCheckpoint); - if (!pauiIntUpdateUFOAddress) - { - pauiIntUpdateUFOAddress = psSyncAddrListUpdate->pasFWAddrs; - } - ui32IntClientUpdateCount++; -#if defined(TRANSFER_CHECKPOINT_DEBUG) - { - IMG_UINT32 iii; - IMG_UINT32 *pui32Tmp = (IMG_UINT32*)pauiIntUpdateUFOAddress; - - for (iii=0; iii) = 0x%x", __func__, iii, (void*)pui32Tmp, *pui32Tmp)); - pui32Tmp++; - } - } -#endif - } - CHKPT_DBG((PVR_DBG_ERROR, "%s: (after pvr_sync) ui32IntClientFenceCount=%d, ui32IntClientUpdateCount=%d", __func__, ui32IntClientFenceCount, ui32IntClientUpdateCount)); - -#if (ENABLE_TQ_UFO_DUMP == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: dumping TQ fence/updates syncs...", __func__)); - { - IMG_UINT32 ii; - PRGXFWIF_UFO_ADDR *psTmpIntFenceUFOAddress = pauiIntFenceUFOAddress; - PRGXFWIF_UFO_ADDR *psTmpIntUpdateUFOAddress = pauiIntUpdateUFOAddress; - IMG_UINT32 *pui32TmpIntUpdateValue = paui32IntUpdateValue; - - /* Dump Fence syncs and Update syncs */ - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TQ fence syncs (&psTransferContext->asSyncAddrListFence=<%p>, pauiIntFenceUFOAddress=<%p>):", __func__, ui32IntClientFenceCount, (void*)&psTransferContext->asSyncAddrListFence, (void*)pauiIntFenceUFOAddress)); - for (ii=0; iiui32Addr & 0x1); - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, CheckValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientFenceCount, (void*)psTmpIntFenceUFOAddress, psTmpIntFenceUFOAddress->ui32Addr)); - - psTmpIntFenceUFOAddress++; - } - PVR_DPF((PVR_DBG_ERROR, "%s: Prepared %d TQ update syncs (&psTransferContext->asSyncAddrListUpdate=<%p>, pauiIntUpdateUFOAddress=<%p>):", __func__, ui32IntClientUpdateCount, (void*)&psTransferContext->asSyncAddrListUpdate, (void*)pauiIntUpdateUFOAddress)); - for (ii=0; iiui32Addr & 0x1) - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=PVRSRV_SYNC_CHECKPOINT_SIGNALLED", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr)); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: %d/%d<%p>. FWAddr=0x%x, UpdateValue=%d", __func__, ii+1, ui32IntClientUpdateCount, (void*)psTmpIntUpdateUFOAddress, psTmpIntUpdateUFOAddress->ui32Addr, *pui32TmpIntUpdateValue)); - pui32TmpIntUpdateValue++; - } - psTmpIntUpdateUFOAddress++; - } - } -#endif - - ui32PreparesDone++; - - /* - Create the command helper data for this command - */ - RGXCmdHelperInitCmdCCB(psDevInfo, - psClientCCB, - 0, - ui32IntClientFenceCount, - pauiIntFenceUFOAddress, - NULL, /* fence value */ - ui32IntClientUpdateCount, - pauiIntUpdateUFOAddress, - paui32IntUpdateValue, - paui32FWCommandSize[i], - papaui8FWCommand[i], - &pPreAddr, - &pPostAddr, - &pRMWUFOAddr, - eType, - ui32ExtJobRef, - ui32IntJobRef, - ui32PDumpFlags, - NULL, - pszCommandName, - bCCBStateOpen, - psCmdHelper); - } - - /* - Acquire space for all the commands in one go - */ - if (ui323DCmdCount) - { - eError = RGXCmdHelperAcquireCmdCCB(ui323DCmdCount, - &pas3DCmdHelper[0]); - if (eError != PVRSRV_OK) - { - goto fail_cmdacquire; - } - } - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((ui322DCmdCount) && (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - eError = RGXCmdHelperAcquireCmdCCB(ui322DCmdCount, - &pas2DCmdHelper[0]); - if (eError != PVRSRV_OK) - { - goto fail_cmdacquire; - } - } -#endif - - /* - We should acquire the kernel CCB(s) space here as the schedule could fail - and we would have to roll back all the syncs - */ - - if (ui323DCmdCount) - { - ui323DCmdOffset = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s3DData.psServerCommonContext)); - RGXCmdHelperReleaseCmdCCB(ui323DCmdCount, - &pas3DCmdHelper[0], - "TQ_3D", - FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext).ui32Addr); - } - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((ui322DCmdCount) && (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - ui322DCmdOffset = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s2DData.psServerCommonContext)); - RGXCmdHelperReleaseCmdCCB(ui322DCmdCount, - &pas2DCmdHelper[0], - "TQ_2D", - FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext).ui32Addr); - } -#endif - - if (ui323DCmdCount) - { - RGXFWIF_KCCB_CMD s3DKCCBCmd; - IMG_UINT32 ui32FWCtx = FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext).ui32Addr; - RGX_CLIENT_CCB *ps3DTQCCB = FWCommonContextGetClientCCB(psTransferContext->s3DData.psServerCommonContext); - - /* Take one of the helper data structs and extract the common cmd struct, - * this is used to obtain the frame num. Each command should share the same - * frame number so we can just get the first. - */ - RGX_CCB_CMD_HELPER_DATA *psCmdHelper = &pas3DCmdHelper[0]; - CMD_COMMON *psTransferCmdCmn = IMG_OFFSET_ADDR(psCmdHelper->pui8DMCmd, 0); - - /* Construct the kernel 3D CCB command. */ - s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - s3DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext); - s3DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(ps3DTQCCB); - s3DKCCBCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(ps3DTQCCB); - s3DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - s3DKCCBCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0; - - HTBLOGK(HTB_SF_MAIN_KICK_3D, - s3DKCCBCmd.uCmdData.sCmdKickData.psContext, - ui323DCmdOffset, - psTransferCmdCmn->ui32FrameNum, - ui32ExtJobRef, - ui32IntJobRef - ); - - RGXSRV_HWPERF_ENQ(psTransferContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_TQ3D, - iCheckFence, - i3DUpdateFence, - i3DUpdateTimeline, - uiCheckFenceUID, - ui3DUpdateFenceUID, - NO_DEADLINE, - NO_CYCEST); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_3D, - &s3DKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSubmitTransferKM failed to schedule kernel CCB command. (0x%x)", eError2)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - goto fail_cmdacquire; - } - - PVRGpuTraceEnqueueEvent(psDeviceNode, ui32FWCtx, ui32ExtJobRef, - ui32IntJobRef, RGX_HWPERF_KICK_TYPE_TQ3D); - } - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((ui322DCmdCount) && (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - RGXFWIF_KCCB_CMD s2DKCCBCmd; - IMG_UINT32 ui32FWCtx = FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext).ui32Addr; - RGX_CLIENT_CCB *ps2DTQCCB = FWCommonContextGetClientCCB(psTransferContext->s2DData.psServerCommonContext); - - /* Take one of the helper data structs and extract the common cmd struct, - * this is used to obtain the frame num. Each command should share the same - * frame number so we can just get the first. - */ - RGX_CCB_CMD_HELPER_DATA *psCmdHelper = &pas2DCmdHelper[0]; - CMD_COMMON *psTransferCmdCmn = IMG_OFFSET_ADDR(psCmdHelper->pui8DMCmd, 0); - - /* Construct the kernel 2D CCB command. */ - s2DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; - s2DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext); - s2DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(ps2DTQCCB); - s2DKCCBCmd.uCmdData.sCmdKickData.ui32CWrapMaskUpdate = RGXGetWrapMaskCCB(ps2DTQCCB); - s2DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; - - HTBLOGK(HTB_SF_MAIN_KICK_2D, - s2DKCCBCmd.uCmdData.sCmdKickData.psContext, - ui322DCmdOffset, - psTransferCmdCmn->ui32FrameNum, - ui32ExtJobRef, - ui32IntJobRef); - - RGXSRV_HWPERF_ENQ(psTransferContext, - OSGetCurrentClientProcessIDKM(), - ui32FWCtx, - ui32ExtJobRef, - ui32IntJobRef, - RGX_HWPERF_KICK_TYPE_TQ2D, - iCheckFence, - i2DUpdateFence, - i2DUpdateTimeline, - uiCheckFenceUID, - ui2DUpdateFenceUID, - NO_DEADLINE, - NO_CYCEST); - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - eError2 = RGXScheduleCommand(psDevInfo, - RGXFWIF_DM_2D, - &s2DKCCBCmd, - ui32PDumpFlags); - if (eError2 != PVRSRV_ERROR_RETRY) - { - break; - } - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - } END_LOOP_UNTIL_TIMEOUT(); - - if (eError2 != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSubmitTransferKM failed to schedule kernel CCB command. (0x%x)", eError2)); - if (eError == PVRSRV_OK) - { - eError = eError2; - } - goto fail_cmdacquire; - } - - PVRGpuTraceEnqueueEvent(psDeviceNode, ui32FWCtx, ui32ExtJobRef, - ui32IntJobRef, RGX_HWPERF_KICK_TYPE_TQ2D); - } -#endif - - /* - * Now check eError (which may have returned an error from our earlier calls - * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first - * so we check it now... - */ - if (eError != PVRSRV_OK ) - { - goto fail_cmdacquire; - } - -#if defined(NO_HARDWARE) - /* If NO_HARDWARE, signal the output fence's sync checkpoint and sync prim */ -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (ps2DUpdateSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Signalling TLA NOHW sync checkpoint<%p>, ID:%d, FwAddr=0x%x", __func__, (void*)ps2DUpdateSyncCheckpoint, SyncCheckpointGetId(ps2DUpdateSyncCheckpoint), SyncCheckpointGetFirmwareAddr(ps2DUpdateSyncCheckpoint))); - SyncCheckpointSignalNoHW(ps2DUpdateSyncCheckpoint); - } - if (ps2DFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Updating TLA NOHW sync prim<%p> to %d", __func__, (void*)ps2DFenceTimelineUpdateSync, ui322DFenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(ps2DFenceTimelineUpdateSync, ui322DFenceTimelineUpdateValue); - } -#endif - if (ps3DUpdateSyncCheckpoint) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Signalling TQ3D NOHW sync checkpoint<%p>, ID:%d, FwAddr=0x%x", __func__, (void*)ps3DUpdateSyncCheckpoint, SyncCheckpointGetId(ps3DUpdateSyncCheckpoint), SyncCheckpointGetFirmwareAddr(ps3DUpdateSyncCheckpoint))); - SyncCheckpointSignalNoHW(ps3DUpdateSyncCheckpoint); - } - if (ps3DFenceTimelineUpdateSync) - { - CHKPT_DBG((PVR_DBG_ERROR, "%s: Updating TQ3D NOHW sync prim<%p> to %d", __func__, (void*)ps3DFenceTimelineUpdateSync, ui323DFenceTimelineUpdateValue)); - SyncPrimNoHwUpdate(ps3DFenceTimelineUpdateSync, ui323DFenceTimelineUpdateValue); - } - SyncCheckpointNoHWUpdateTimelines(NULL); -#endif /* defined(NO_HARDWARE) */ - -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferSyncData) - { - pvr_buffer_sync_kick_succeeded(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (pi2DUpdateFence) - { - *pi2DUpdateFence = i2DUpdateFence; - } -#endif - if (pi3DUpdateFence) - { - *pi3DUpdateFence = i3DUpdateFence; - } -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (pv2DUpdateFenceFinaliseData && (i2DUpdateFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psDeviceNode, i2DUpdateFence, pv2DUpdateFenceFinaliseData, - ps2DUpdateSyncCheckpoint, szFenceName); - } -#endif - if (pv3DUpdateFenceFinaliseData && (i3DUpdateFence != PVRSRV_NO_FENCE)) - { - SyncCheckpointFinaliseFence(psDeviceNode, i3DUpdateFence, pv3DUpdateFenceFinaliseData, - ps3DUpdateSyncCheckpoint, szFenceName); - } - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - OSFreeMem(pas2DCmdHelper); -#endif - OSFreeMem(pas3DCmdHelper); - - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } - /* Free memory allocated to hold the internal list of update values */ -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (pui322DIntAllocatedUpdateValues) - { - OSFreeMem(pui322DIntAllocatedUpdateValues); - pui322DIntAllocatedUpdateValues = NULL; - } -#endif - if (pui323DIntAllocatedUpdateValues) - { - OSFreeMem(pui323DIntAllocatedUpdateValues); - pui323DIntAllocatedUpdateValues = NULL; - } - - OSLockRelease(psTransferContext->hLock); - return PVRSRV_OK; - -/* - No resources are created in this function so there is nothing to free - unless we had to merge syncs. - If we fail after the client CCB acquire there is still nothing to do - as only the client CCB release will modify the client CCB -*/ -fail_cmdacquire: -fail_prepare_loop: - - PVR_ASSERT(eError != PVRSRV_OK); - - for (i=0;iasSyncAddrListFence[i]); - SyncAddrListRollbackCheckpoints(psDeviceNode, &psTransferContext->asSyncAddrListUpdate[i]); - } -#if defined(SUPPORT_BUFFER_SYNC) - if (ui32PreparesDone > 0) - { - /* Prevent duplicate rollback in case of buffer sync. */ - psBufferUpdateSyncCheckpoint = NULL; - } -#endif - - /* Free memory allocated to hold the internal list of update values */ -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (pui322DIntAllocatedUpdateValues) - { - OSFreeMem(pui322DIntAllocatedUpdateValues); - pui322DIntAllocatedUpdateValues = NULL; - } -#endif - if (pui323DIntAllocatedUpdateValues) - { - OSFreeMem(pui323DIntAllocatedUpdateValues); - pui323DIntAllocatedUpdateValues = NULL; - } -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if (i2DUpdateFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(i2DUpdateFence, pv2DUpdateFenceFinaliseData); - } -#endif - if (i3DUpdateFence != PVRSRV_NO_FENCE) - { - SyncCheckpointRollbackFenceData(i3DUpdateFence, pv3DUpdateFenceFinaliseData); - } -#if defined(SUPPORT_BUFFER_SYNC) - if (psBufferUpdateSyncCheckpoint) - { - SyncAddrListRollbackCheckpoints(psDeviceNode, &psTransferContext->asSyncAddrListUpdate[0]); - } - if (psBufferSyncData) - { - pvr_buffer_sync_kick_failed(psBufferSyncData); - } - if (apsBufferFenceSyncCheckpoints) - { - kfree(apsBufferFenceSyncCheckpoints); - } -fail_resolve_buffersync_input_fence: -#endif /* defined(SUPPORT_BUFFER_SYNC) */ - - /* Drop the references taken on the sync checkpoints in the - * resolved input fence */ - SyncAddrListDeRefCheckpoints(ui32FenceSyncCheckpointCount, - apsFenceSyncCheckpoints); - /* Free the memory that was allocated for the sync checkpoint list returned by ResolveFence() */ - if (apsFenceSyncCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsFenceSyncCheckpoints); - } -fail_resolve_fencesync_input_fence: -#if defined(RGX_FEATURE_TLA_BIT_MASK) - OSFreeMem(pas2DCmdHelper); -fail_alloc2dhelper: -#endif - OSFreeMem(pas3DCmdHelper); -fail_alloc3dhelper: - - OSLockRelease(psTransferContext->hLock); - return eError; -} - - -PVRSRV_ERROR PVRSRVRGXSetTransferContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - RGX_SERVER_TQ_CONTEXT *psTransferContext, - IMG_UINT32 ui32Priority) -{ - PVRSRV_ERROR eError; -#if defined(RGX_FEATURE_TLA_BIT_MASK) - PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice; -#endif - PVR_UNREFERENCED_PARAMETER(psDevNode); - - OSLockAcquire(psTransferContext->hLock); - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((psTransferContext->s2DData.ui32Priority != ui32Priority) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - eError = ContextSetPriority(psTransferContext->s2DData.psServerCommonContext, - psConnection, - psTransferContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_2D); - if (eError != PVRSRV_OK) - { - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the 2D part of the transfercontext (%s)", __func__, PVRSRVGetErrorString(eError))); - } - goto fail_2dcontext; - } - psTransferContext->s2DData.ui32Priority = ui32Priority; - } -#endif - - if (psTransferContext->s3DData.ui32Priority != ui32Priority) - { - eError = ContextSetPriority(psTransferContext->s3DData.psServerCommonContext, - psConnection, - psTransferContext->psDeviceNode->pvDevice, - ui32Priority, - RGXFWIF_DM_3D); - if (eError != PVRSRV_OK) - { - if (eError != PVRSRV_ERROR_RETRY) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the 3D part of the transfercontext (%s)", __func__, PVRSRVGetErrorString(eError))); - } - goto fail_3dcontext; - } - psTransferContext->s3DData.ui32Priority = ui32Priority; - } - - OSLockRelease(psTransferContext->hLock); - return PVRSRV_OK; - -fail_3dcontext: -#if defined(RGX_FEATURE_TLA_BIT_MASK) - -fail_2dcontext: -#endif - OSLockRelease(psTransferContext->hLock); - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -PVRSRV_ERROR PVRSRVRGXSetTransferContextPropertyKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - switch (eContextProperty) - { - case RGX_CONTEXT_PROPERTY_FLAGS: - { - IMG_UINT32 ui32ContextFlags = (IMG_UINT32)ui64Input; - - OSLockAcquire(psTransferContext->hLock); - eError = FWCommonContextSetFlags(psTransferContext->s2DData.psServerCommonContext, - ui32ContextFlags); - if (eError == PVRSRV_OK) - { - eError = FWCommonContextSetFlags(psTransferContext->s3DData.psServerCommonContext, - ui32ContextFlags); - } - OSLockRelease(psTransferContext->hLock); - break; - } - - default: - { - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_ERROR_NOT_SUPPORTED - asked to set unknown property (%d)", __func__, eContextProperty)); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - } - } - - return eError; -} - -void DumpTransferCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel) -{ - DLLIST_NODE *psNode, *psNext; - - OSWRLockAcquireRead(psDevInfo->hTransferCtxListLock); - - dllist_foreach_node(&psDevInfo->sTransferCtxtListHead, psNode, psNext) - { - RGX_SERVER_TQ_CONTEXT *psCurrentServerTransferCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_CONTEXT, sListNode); - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((psCurrentServerTransferCtx->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_2D) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - DumpFWCommonContextInfo(psCurrentServerTransferCtx->s2DData.psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } -#endif - - if (psCurrentServerTransferCtx->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_3D) - { - DumpFWCommonContextInfo(psCurrentServerTransferCtx->s3DData.psServerCommonContext, - pfnDumpDebugPrintf, pvDumpDebugFile, ui32VerbLevel); - } - } - - OSWRLockReleaseRead(psDevInfo->hTransferCtxListLock); -} - -IMG_UINT32 CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) -{ - DLLIST_NODE *psNode, *psNext; - IMG_UINT32 ui32ContextBitMask = 0; - - OSWRLockAcquireRead(psDevInfo->hTransferCtxListLock); - - dllist_foreach_node(&psDevInfo->sTransferCtxtListHead, psNode, psNext) - { - RGX_SERVER_TQ_CONTEXT *psCurrentServerTransferCtx = - IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_CONTEXT, sListNode); - -#if defined(RGX_FEATURE_TLA_BIT_MASK) - if ((psCurrentServerTransferCtx->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_2D) && - (NULL != psCurrentServerTransferCtx->s2DData.psServerCommonContext) && - (RGX_IS_FEATURE_SUPPORTED(psDevInfo, TLA))) - { - if (CheckStalledClientCommonContext(psCurrentServerTransferCtx->s2DData.psServerCommonContext, RGX_KICK_TYPE_DM_TQ2D) == PVRSRV_ERROR_CCCB_STALLED) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_TQ2D; - } - } -#endif - - if ((psCurrentServerTransferCtx->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_3D) && (NULL != psCurrentServerTransferCtx->s3DData.psServerCommonContext)) - { - if ((CheckStalledClientCommonContext(psCurrentServerTransferCtx->s3DData.psServerCommonContext, RGX_KICK_TYPE_DM_TQ3D) == PVRSRV_ERROR_CCCB_STALLED)) - { - ui32ContextBitMask |= RGX_KICK_TYPE_DM_TQ3D; - } - } - } - - OSWRLockReleaseRead(psDevInfo->hTransferCtxListLock); - return ui32ContextBitMask; -} - -/**************************************************************************//** - End of file (rgxtransfer.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.h b/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.h deleted file mode 100644 index cbc5b73f6bbef..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer.h +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title RGX Transfer queue Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the RGX Transfer queue Functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXTRANSFER_H) -#define RGXTRANSFER_H - -#include "devicemem.h" -#include "device.h" -#include "rgxdevice.h" -#include "rgxfwutils.h" -#include "rgx_fwif_resetframework.h" -#include "rgxdebug.h" -#include "pvr_notifier.h" - -#include "sync_server.h" -#include "connection_server.h" - -typedef struct _RGX_SERVER_TQ_CONTEXT_ RGX_SERVER_TQ_CONTEXT; - -/*! -******************************************************************************* - - @Function PVRSRVRGXCreateTransferContextKM - - @Description - Server-side implementation of RGXCreateTransferContext - - @Input pvDeviceNode - device node - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Priority, - IMG_UINT32 ui32FrameworkCommandSize, - IMG_PBYTE pabyFrameworkCommand, - IMG_HANDLE hMemCtxPrivData, - IMG_UINT32 ui32PackedCCBSizeU8888, - IMG_UINT32 ui32ContextFlags, - IMG_UINT64 ui64RobustnessAddress, - RGX_SERVER_TQ_CONTEXT **ppsTransferContext, - PMR **ppsCLIPMRMem, - PMR **ppsUSCPMRMem); - - -/*! -******************************************************************************* - - @Function PVRSRVRGXDestroyTransferContextKM - - @Description - Server-side implementation of RGXDestroyTransferContext - - @Input psTransferContext - Transfer context - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransferContext); - -/*! -******************************************************************************* - - @Function PVRSRVSubmitTransferKM - - @Description - Schedules one or more 2D or 3D HW commands on the firmware - - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, - IMG_UINT32 ui32PrepareCount, - IMG_UINT32 *paui32ClientUpdateCount, - SYNC_PRIMITIVE_BLOCK ***papauiClientUpdateUFODevVarBlock, - IMG_UINT32 **papaui32ClientUpdateSyncOffset, - IMG_UINT32 **papaui32ClientUpdateValue, - PVRSRV_FENCE iCheckFence, - PVRSRV_TIMELINE i2DUpdateTimeline, - PVRSRV_FENCE *pi2DUpdateFence, - PVRSRV_TIMELINE i3DUpdateTimeline, - PVRSRV_FENCE *pi3DUpdateFence, - IMG_CHAR szFenceName[32], - IMG_UINT32 *paui32FWCommandSize, - IMG_UINT8 **papaui8FWCommand, - IMG_UINT32 *pui32TQPrepareFlags, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32SyncPMRCount, - IMG_UINT32 *paui32SyncPMRFlags, - PMR **ppsSyncPMRs); - -PVRSRV_ERROR PVRSRVRGXSetTransferContextPriorityKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - RGX_SERVER_TQ_CONTEXT *psTransferContext, - IMG_UINT32 ui32Priority); - -PVRSRV_ERROR PVRSRVRGXSetTransferContextPropertyKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, - RGX_CONTEXT_PROPERTY eContextProperty, - IMG_UINT64 ui64Input, - IMG_UINT64 *pui64Output); - -/* Debug - Dump debug info of transfer contexts on this device */ -void DumpTransferCtxtsInfo(PVRSRV_RGXDEV_INFO *psDevInfo, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile, - IMG_UINT32 ui32VerbLevel); - -/* Debug/Watchdog - check if client transfer contexts are stalled */ -IMG_UINT32 CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); - -#endif /* RGXTRANSFER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer_shader.h b/drivers/gpu/drm/img-rogue/1.17/rgxtransfer_shader.h deleted file mode 100644 index 979f85bd4414d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxtransfer_shader.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File rgxtransfer_shader.h -@Title TQ binary shader file info -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header holds info about TQ binary shader file generated - by the TQ shader factory. This header is need by shader factory - when generating the file; by services KM when reading and - loading the file into memory; and by services UM when - constructing blits using the shaders. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(RGXSHADERHEADER_H) -#define RGXSHADERHEADER_H - -typedef struct _RGX_SHADER_HEADER_ -{ - IMG_UINT32 ui32Version; - IMG_UINT32 ui32NumFragment; - IMG_UINT32 ui32SizeFragment; - IMG_UINT32 ui32NumTDMFragment; - IMG_UINT32 ui32SizeTDMFragment; - IMG_UINT32 ui32SizeClientMem; -} RGX_SHADER_HEADER; - -#endif /* RGXSHADERHEADER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxutils.c b/drivers/gpu/drm/img-rogue/1.17/rgxutils.c deleted file mode 100644 index 866fd014a44df..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxutils.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific utility routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device specific functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "rgx_fwif_km.h" -#include "pdump_km.h" -#include "osfunc.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "rgxutils.h" -#include "power.h" -#include "pvrsrv.h" -#include "sync_internal.h" -#include "rgxfwutils.h" - - -PVRSRV_ERROR RGXQueryAPMState(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_UINT32 *pui32State) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_UNREFERENCED_PARAMETER(pvPrivateData); - - if (!psDeviceNode) - return PVRSRV_ERROR_INVALID_PARAMS; - - psDevInfo = psDeviceNode->pvDevice; - *pui32State = psDevInfo->eActivePMConf; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXSetAPMState(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_UINT32 ui32State) -{ - PVRSRV_ERROR eError = PVRSRV_OK; -#if !defined(NO_HARDWARE) - PVRSRV_RGXDEV_INFO *psDevInfo; -#endif - - PVR_UNREFERENCED_PARAMETER(pvPrivateData); - - if (!psDeviceNode || !psDeviceNode->pvDevice) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (RGX_ACTIVEPM_FORCE_OFF != ui32State) - { - return PVRSRV_ERROR_NOT_SUPPORTED; - } - -#if !defined(NO_HARDWARE) - psDevInfo = psDeviceNode->pvDevice; - - if (psDevInfo->pvAPMISRData) - { - psDevInfo->eActivePMConf = RGX_ACTIVEPM_FORCE_OFF; - psDevInfo->pvAPMISRData = NULL; - eError = PVRSRVSetDeviceDefaultPowerState((PPVRSRV_DEVICE_NODE)psDeviceNode, - PVRSRV_DEV_POWER_STATE_ON); - } -#endif - - return eError; -} - -PVRSRV_ERROR RGXQueryPdumpPanicDisable(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_BOOL *pbDisabled) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_UNREFERENCED_PARAMETER(pvPrivateData); - - if (!psDeviceNode || !psDeviceNode->pvDevice) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevInfo = psDeviceNode->pvDevice; - - *pbDisabled = !psDevInfo->bPDPEnabled; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXSetPdumpPanicDisable(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_BOOL bDisable) -{ - PVRSRV_RGXDEV_INFO *psDevInfo; - - PVR_UNREFERENCED_PARAMETER(pvPrivateData); - - if (!psDeviceNode || !psDeviceNode->pvDevice) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDevInfo = psDeviceNode->pvDevice; - - psDevInfo->bPDPEnabled = !bDisable; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXGetDeviceFlags(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 *pui32DeviceFlags) -{ - if (!pui32DeviceFlags || !psDevInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - *pui32DeviceFlags = psDevInfo->ui32DeviceFlags; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RGXSetDeviceFlags(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Config, - IMG_BOOL bSetNotClear) -{ - if (!psDevInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if ((ui32Config & ~RGXKM_DEVICE_STATE_MASK) != 0) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Bits outside of device state mask set (input: 0x%x, mask: 0x%x)", - __func__, ui32Config, RGXKM_DEVICE_STATE_MASK)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (bSetNotClear) - { - psDevInfo->ui32DeviceFlags |= ui32Config; - } - else - { - psDevInfo->ui32DeviceFlags &= ~ui32Config; - } - - return PVRSRV_OK; -} - -inline const char * RGXStringifyKickTypeDM(RGX_KICK_TYPE_DM eKickTypeDM) -{ - PVR_ASSERT(eKickTypeDM < RGX_KICK_TYPE_DM_LAST); - - switch (eKickTypeDM) { - case RGX_KICK_TYPE_DM_GP: - return "GP "; - case RGX_KICK_TYPE_DM_TDM_2D: - return "TDM/2D "; - case RGX_KICK_TYPE_DM_TA: - return "TA "; - case RGX_KICK_TYPE_DM_3D: - return "3D "; - case RGX_KICK_TYPE_DM_CDM: - return "CDM "; - case RGX_KICK_TYPE_DM_RTU: - return "RTU "; - case RGX_KICK_TYPE_DM_SHG: - return "SHG "; - case RGX_KICK_TYPE_DM_TQ2D: - return "TQ2D "; - case RGX_KICK_TYPE_DM_TQ3D: - return "TQ3D "; - default: - return "Invalid DM "; - } -} - -/****************************************************************************** - End of file (rgxutils.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/rgxutils.h b/drivers/gpu/drm/img-rogue/1.17/rgxutils.h deleted file mode 100644 index 670986323d2be..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rgxutils.h +++ /dev/null @@ -1,185 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device specific utility routines declarations -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Inline functions/structures specific to RGX -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "device.h" -#include "rgxdevice.h" -#include "rgxdebug.h" -#include "pvr_notifier.h" -#include "pvrsrv.h" - -/*! -****************************************************************************** - - @Function RGXQueryAPMState - - @Description Query the state of the APM configuration - - @Input psDeviceNode : The device node - - @Input pvPrivateData: Unused (required for AppHint callback) - - @Output pui32State : The APM configuration state - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXQueryAPMState(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_UINT32 *pui32State); - -/*! -****************************************************************************** - - @Function RGXSetAPMState - - @Description Set the APM configuration state. Currently only 'OFF' is - supported - - @Input psDeviceNode : The device node - - @Input pvPrivateData: Unused (required for AppHint callback) - - @Input ui32State : The requested APM configuration state - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXSetAPMState(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_UINT32 ui32State); - -/*! -****************************************************************************** - - @Function RGXQueryPdumpPanicDisable - - @Description Get the PDump Panic Enable configuration state. - - @Input psDeviceNode : The device node - - @Input pvPrivateData: Unused (required for AppHint callback) - - @Input pbDisabled : IMG_TRUE if PDump Panic is disabled - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXQueryPdumpPanicDisable(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_BOOL *pbDisabled); - -/*! -****************************************************************************** - - @Function RGXSetPdumpPanicDisable - - @Description Set the PDump Panic Enable flag - - @Input psDeviceNode : The device node - - @Input pvPrivateData: Unused (required for AppHint callback) - - @Input bDisable : The requested configuration state - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXSetPdumpPanicDisable(const PVRSRV_DEVICE_NODE *psDeviceNode, - const void *pvPrivateData, - IMG_BOOL bDisable); - -/*! -****************************************************************************** - - @Function RGXGetDeviceFlags - - @Description Get the device flags for a given device - - @Input psDevInfo : The device descriptor query - - @Output pui32DeviceFlags : The current state of the device flags - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXGetDeviceFlags(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 *pui32DeviceFlags); - -/*! -****************************************************************************** - - @Function RGXSetDeviceFlags - - @Description Set the device flags for a given device - - @Input psDevInfo : The device descriptor to modify - - @Input ui32Config : The device flags to modify - - @Input bSetNotClear : Set or clear the specified flags - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RGXSetDeviceFlags(PVRSRV_RGXDEV_INFO *psDevInfo, - IMG_UINT32 ui32Config, - IMG_BOOL bSetNotClear); - -/*! -****************************************************************************** - - @Function RGXStringifyKickTypeDM - - @Description Gives the kick type DM name stringified - - @Input Kick type DM - - @Return Array containing the kick type DM name - -******************************************************************************/ -const char* RGXStringifyKickTypeDM(RGX_KICK_TYPE_DM eKickTypeDM); - -#define RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(bitmask, eKickTypeDM) bitmask & eKickTypeDM ? RGXStringifyKickTypeDM(eKickTypeDM) : "" -/****************************************************************************** - End of file (rgxutils.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/ri_server.c b/drivers/gpu/drm/img-rogue/1.17/ri_server.c deleted file mode 100644 index 7412cf15e80db..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ri_server.c +++ /dev/null @@ -1,2123 +0,0 @@ -/*************************************************************************/ /*! -@File ri_server.c -@Title Resource Information (RI) server implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Resource Information (RI) server functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if defined(__linux__) - #include - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) - #include - #else - #include - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) */ -#else - #include -#endif /* __linux__ */ -#include "img_defs.h" -#include "allocmem.h" -#include "pvr_debug.h" -#include "pvrsrv_error.h" -#include "osfunc.h" - -#include "srvkm.h" -#include "lock.h" - -/* services/include */ -#include "pvr_ricommon.h" - -/* services/server/include/ */ -#include "ri_server.h" - -/* services/include/shared/ */ -#include "hash.h" -/* services/shared/include/ */ -#include "dllist.h" - -#include "pmr.h" - -/* include/device.h */ -#include "device.h" - -#if !defined(RI_UNIT_TEST) -#include "pvrsrv.h" -#endif - - -#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) - -#define USE_RI_LOCK 1 - -/* - * Initial size use for Hash table. (Used to index the RI list entries). - */ -#define _RI_INITIAL_HASH_TABLE_SIZE 64 - -/* - * Values written to the 'valid' field of RI structures when created and - * cleared prior to being destroyed. The code can then check this value - * before accessing the provided pointer contents as a valid RI structure. - */ -#define _VALID_RI_LIST_ENTRY 0x66bccb66 -#define _VALID_RI_SUBLIST_ENTRY 0x77cddc77 -#define _INVALID 0x00000000 - -/* - * If this define is set to 1, details of the linked lists (addresses, - * prev/next ptrs, etc) are also output when function RIDumpList() is called. - */ -#define _DUMP_LINKEDLIST_INFO 0 - - -typedef IMG_UINT64 _RI_BASE_T; - - -/* No +1 in SIZE macros since sizeof includes \0 byte in size */ - -#define RI_PROC_BUF_SIZE 16 - -#define RI_MEMDESC_SUM_FRMT "PID %d %s MEMDESCs Alloc'd:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K) + "\ - "Imported:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K) = "\ - "Total:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K)\n" -#define RI_MEMDESC_SUM_BUF_SIZE (sizeof(RI_MEMDESC_SUM_FRMT)+5+RI_PROC_BUF_SIZE+30+60) - - -#define RI_PMR_SUM_FRMT "PID %d %s PMRs Alloc'd:0x%010" IMG_UINT64_FMTSPECx ", %" IMG_UINT64_FMTSPEC "K "\ - "[Physical: 0x%010" IMG_UINT64_FMTSPECx ", %" IMG_UINT64_FMTSPEC "K]\n" -#define RI_PMR_SUM_BUF_SIZE (sizeof(RI_PMR_SUM_FRMT)+(20+40)) - -#define RI_PMR_ENTRY_FRMT "%%sPID:%%-5d <%%p>\t%%-%ds\t0x%%010" IMG_UINT64_FMTSPECx "\t[0x%%010" IMG_UINT64_FMTSPECx "]\t%%c" -#define RI_PMR_ENTRY_BUF_SIZE (sizeof(RI_PMR_ENTRY_FRMT)+(3+5+16+PVR_ANNOTATION_MAX_LEN+10+10)) -#define RI_PMR_ENTRY_FRMT_SIZE (sizeof(RI_PMR_ENTRY_FRMT)) - -/* Use %5d rather than %d so the output aligns in server/kernel.log, debugFS sees extra spaces */ -#define RI_MEMDESC_ENTRY_PROC_FRMT "[%5d:%s]" -#define RI_MEMDESC_ENTRY_PROC_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_PROC_FRMT)+5+16) - -#define RI_SYS_ALLOC_IMPORT_FRMT "{Import from PID %d}" -#define RI_SYS_ALLOC_IMPORT_FRMT_SIZE (sizeof(RI_SYS_ALLOC_IMPORT_FRMT)+5) -static IMG_CHAR g_szSysAllocImport[RI_SYS_ALLOC_IMPORT_FRMT_SIZE]; - -#define RI_MEMDESC_ENTRY_IMPORT_FRMT "{Import from PID %d}" -#define RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_IMPORT_FRMT)+5) - -#define RI_MEMDESC_ENTRY_UNPINNED_FRMT "{Unpinned}" -#define RI_MEMDESC_ENTRY_UNPINNED_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_UNPINNED_FRMT)) - -#define RI_MEMDESC_ENTRY_FRMT "%%sPID:%%-5d 0x%%010" IMG_UINT64_FMTSPECx "\t%%-%ds %%s\t0x%%010" IMG_UINT64_FMTSPECx "\t<%%p> %%s%%s%%s%%c" -#define RI_MEMDESC_ENTRY_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_FRMT)+(3+5+10+PVR_ANNOTATION_MAX_LEN+RI_MEMDESC_ENTRY_PROC_BUF_SIZE+16+\ - RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE+RI_SYS_ALLOC_IMPORT_FRMT_SIZE+RI_MEMDESC_ENTRY_UNPINNED_BUF_SIZE)) -#define RI_MEMDESC_ENTRY_FRMT_SIZE (sizeof(RI_MEMDESC_ENTRY_FRMT)) - - -#define RI_FRMT_SIZE_MAX (MAX(RI_MEMDESC_ENTRY_BUF_SIZE,\ - MAX(RI_PMR_ENTRY_BUF_SIZE,\ - MAX(RI_MEMDESC_SUM_BUF_SIZE,\ - RI_PMR_SUM_BUF_SIZE)))) - - - - -/* Structure used to make linked sublist of memory allocations (MEMDESC) */ -struct _RI_SUBLIST_ENTRY_ -{ - DLLIST_NODE sListNode; - struct _RI_LIST_ENTRY_ *psRI; - IMG_UINT32 valid; - IMG_BOOL bIsImport; - IMG_BOOL bIsSuballoc; - IMG_PID pid; - IMG_CHAR ai8ProcName[RI_PROC_BUF_SIZE]; - IMG_DEV_VIRTADDR sVAddr; - IMG_UINT64 ui64Offset; - IMG_UINT64 ui64Size; - IMG_CHAR ai8TextB[DEVMEM_ANNOTATION_MAX_LEN+1]; - DLLIST_NODE sProcListNode; -}; - -/* - * Structure used to make linked list of PMRs. Sublists of allocations - * (MEMDESCs) made from these PMRs are chained off these entries. - */ -struct _RI_LIST_ENTRY_ -{ - DLLIST_NODE sListNode; - DLLIST_NODE sSysAllocListNode; - DLLIST_NODE sSubListFirst; - IMG_UINT32 valid; - PMR *psPMR; - IMG_PID pid; - IMG_CHAR ai8ProcName[RI_PROC_BUF_SIZE]; - IMG_UINT16 ui16SubListCount; - IMG_UINT16 ui16MaxSubListCount; - IMG_UINT32 ui32RIPMRFlags; /* Flags used to indicate the type of allocation */ - IMG_UINT32 ui32Flags; /* Flags used to indicate if PMR appears in ri debugfs output */ -}; - -typedef struct _RI_LIST_ENTRY_ RI_LIST_ENTRY; -typedef struct _RI_SUBLIST_ENTRY_ RI_SUBLIST_ENTRY; - -static IMG_UINT16 g_ui16RICount; -static HASH_TABLE *g_pRIHashTable; -static IMG_UINT16 g_ui16ProcCount; -static HASH_TABLE *g_pProcHashTable; - -static POS_LOCK g_hRILock; - -/* Linked list of PMR allocations made against the PVR_SYS_ALLOC_PID and lock - * to prevent concurrent access to it. - */ -static POS_LOCK g_hSysAllocPidListLock; -static DLLIST_NODE g_sSysAllocPidListHead; - -/* - * Flag used to indicate if RILock should be destroyed when final PMR entry is - * deleted, i.e. if RIDeInitKM() has already been called before that point but - * the handle manager has deferred deletion of RI entries. - */ -static IMG_BOOL bRIDeInitDeferred = IMG_FALSE; - -/* - * Used as head of linked-list of PMR RI entries - this is useful when we wish - * to iterate all PMR list entries (when we don't have a PMR ref) - */ -static DLLIST_NODE sListFirst; - -/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */ -static void _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry, IMG_BOOL bDebugFs, IMG_UINT16 ui16MaxStrLen, IMG_CHAR *pszEntryString); -/* Function used to produce string containing info for PMR RI entries (used for both debugfs and kernel log output) */ -static void _GeneratePMREntryString(RI_LIST_ENTRY *psRIEntry, IMG_BOOL bDebugFs, IMG_UINT16 ui16MaxStrLen, IMG_CHAR *pszEntryString); - -static PVRSRV_ERROR _DumpAllEntries (uintptr_t k, uintptr_t v, void* pvPriv); -static PVRSRV_ERROR _DeleteAllEntries (uintptr_t k, uintptr_t v, void* pvPriv); -static PVRSRV_ERROR _DeleteAllProcEntries (uintptr_t k, uintptr_t v, void* pvPriv); -static PVRSRV_ERROR _DumpList(PMR *psPMR, IMG_PID pid); -#define _RIOutput(x) PVR_LOG(x) - -#define RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS 0x1 -#define RI_FLAG_SYSALLOC_PMR 0x2 - -static IMG_UINT32 -_ProcHashFunc(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen); - -static IMG_UINT32 -_ProcHashFunc(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen) -{ - IMG_UINT32 *p = (IMG_UINT32 *)pKey; - IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32); - IMG_UINT32 ui; - IMG_UINT32 uHashKey = 0; - - PVR_UNREFERENCED_PARAMETER(uHashTabLen); - - for (ui = 0; ui < uKeyLen; ui++) - { - IMG_UINT32 uHashPart = *p++; - - uHashPart += (uHashPart << 12); - uHashPart ^= (uHashPart >> 22); - uHashPart += (uHashPart << 4); - uHashPart ^= (uHashPart >> 9); - uHashPart += (uHashPart << 10); - uHashPart ^= (uHashPart >> 2); - uHashPart += (uHashPart << 7); - uHashPart ^= (uHashPart >> 12); - - uHashKey += uHashPart; - } - - return uHashKey; -} - -static IMG_BOOL -_ProcHashComp(size_t uKeySize, void *pKey1, void *pKey2); - -static IMG_BOOL -_ProcHashComp(size_t uKeySize, void *pKey1, void *pKey2) -{ - IMG_UINT32 *p1 = (IMG_UINT32 *)pKey1; - IMG_UINT32 *p2 = (IMG_UINT32 *)pKey2; - IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32); - IMG_UINT32 ui; - - for (ui = 0; ui < uKeyLen; ui++) - { - if (*p1++ != *p2++) - return IMG_FALSE; - } - - return IMG_TRUE; -} - -static void _RILock(void) -{ -#if (USE_RI_LOCK == 1) - OSLockAcquire(g_hRILock); -#endif -} - -static void _RIUnlock(void) -{ -#if (USE_RI_LOCK == 1) - OSLockRelease(g_hRILock); -#endif -} - -/* This value maintains a count of the number of PMRs attributed to the - * PVR_SYS_ALLOC_PID. Access to this value is protected by g_hRILock, so it - * does not need to be an ATOMIC_T. - */ -static IMG_UINT32 g_ui32SysAllocPMRCount; - - -PVRSRV_ERROR RIInitKM(void) -{ - IMG_INT iCharsWritten; - PVRSRV_ERROR eError; - - bRIDeInitDeferred = IMG_FALSE; - - iCharsWritten = OSSNPrintf(g_szSysAllocImport, - RI_SYS_ALLOC_IMPORT_FRMT_SIZE, - RI_SYS_ALLOC_IMPORT_FRMT, - PVR_SYS_ALLOC_PID); - PVR_LOG_IF_FALSE((iCharsWritten>0 && iCharsWritten<(IMG_INT32)RI_SYS_ALLOC_IMPORT_FRMT_SIZE), \ - "OSSNPrintf failed to initialise g_szSysAllocImport"); - - eError = OSLockCreate(&g_hSysAllocPidListLock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OSLockCreate (g_hSysAllocPidListLock) failed (returned %d)", - __func__, - eError)); - } - dllist_init(&(g_sSysAllocPidListHead)); -#if (USE_RI_LOCK == 1) - eError = OSLockCreate(&g_hRILock); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OSLockCreate (g_hRILock) failed (returned %d)", - __func__, - eError)); - } -#endif - return eError; -} -void RIDeInitKM(void) -{ -#if (USE_RI_LOCK == 1) - if (g_ui16RICount > 0) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: called with %d entries remaining - deferring OSLockDestroy()", - __func__, - g_ui16RICount)); - bRIDeInitDeferred = IMG_TRUE; - } - else - { - OSLockDestroy(g_hRILock); - OSLockDestroy(g_hSysAllocPidListLock); - } -#endif -} - -/*! -******************************************************************************* - - @Function RILockAcquireKM - - @Description - Acquires the RI Lock (which protects the integrity of the RI - linked lists). Caller will be suspended until lock is acquired. - - @Return None - -******************************************************************************/ -void RILockAcquireKM(void) -{ - _RILock(); -} - -/*! -******************************************************************************* - - @Function RILockReleaseKM - - @Description - Releases the RI Lock (which protects the integrity of the RI - linked lists). - - @Return None - -******************************************************************************/ -void RILockReleaseKM(void) -{ - _RIUnlock(); -} - -/*! -******************************************************************************* - - @Function RIWritePMREntryWithOwnerKM - - @Description - Writes a new Resource Information list entry. - The new entry will be inserted at the head of the list of - PMR RI entries and assigned the values provided. - - @input psPMR - Reference (handle) to the PMR to which this reference relates - - @input ui32Owner - PID of the process which owns the allocation. This - may not be the current process (e.g. a request to - grow a buffer may happen in the context of a kernel - thread, or we may import further resource for a - suballocation made from the FW heap which can then - also be utilized by other processes) - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIWritePMREntryWithOwnerKM(PMR *psPMR, - IMG_PID ui32Owner) -{ - PMR *pPMRHashKey = psPMR; - RI_LIST_ENTRY *psRIEntry; - uintptr_t hashData; - - /* if Hash table has not been created, create it now */ - if (!g_pRIHashTable) - { - g_pRIHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(PMR*), HASH_Func_Default, HASH_Key_Comp_Default); - g_pProcHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(IMG_PID), _ProcHashFunc, _ProcHashComp); - } - PVR_RETURN_IF_NOMEM(g_pRIHashTable); - PVR_RETURN_IF_NOMEM(g_pProcHashTable); - - PVR_RETURN_IF_INVALID_PARAM(psPMR); - - /* Acquire RI Lock */ - _RILock(); - - /* Look-up psPMR in Hash Table */ - hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey); - psRIEntry = (RI_LIST_ENTRY *)hashData; - if (!psRIEntry) - { - /* - * If failed to find a matching existing entry, create a new one - */ - psRIEntry = (RI_LIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_LIST_ENTRY)); - if (!psRIEntry) - { - /* Release RI Lock */ - _RIUnlock(); - /* Error - no memory to allocate for new RI entry */ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - else - { - PMR_FLAGS_T uiPMRFlags = PMR_Flags(psPMR); - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)PMR_DeviceNode(psPMR); - - /* - * Add new RI Entry - */ - if (g_ui16RICount == 0) - { - /* Initialise PMR entry linked-list head */ - dllist_init(&sListFirst); - } - g_ui16RICount++; - - dllist_init (&(psRIEntry->sSysAllocListNode)); - dllist_init (&(psRIEntry->sSubListFirst)); - psRIEntry->ui16SubListCount = 0; - psRIEntry->ui16MaxSubListCount = 0; - psRIEntry->valid = _VALID_RI_LIST_ENTRY; - - /* Check if this PMR should be accounted for under the - * PVR_SYS_ALLOC_PID debugFS entry. This should happen if - * we are in the driver init phase, the flags indicate - * this is a FW Main allocation (made from FW heap) - * or the owner PID is PVR_SYS_ALLOC_PID. - * Also record host dev node allocs on the system PID. - */ - if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT || - PVRSRV_CHECK_FW_MAIN(uiPMRFlags) || - ui32Owner == PVR_SYS_ALLOC_PID || - psDeviceNode == PVRSRVGetPVRSRVData()->psHostMemDeviceNode) - { - psRIEntry->ui32RIPMRFlags = RI_FLAG_SYSALLOC_PMR; - OSSNPrintf(psRIEntry->ai8ProcName, - RI_PROC_BUF_SIZE, - "SysProc"); - psRIEntry->pid = PVR_SYS_ALLOC_PID; - OSLockAcquire(g_hSysAllocPidListLock); - /* Add this psRIEntry to the list of entries for PVR_SYS_ALLOC_PID */ - dllist_add_to_tail(&g_sSysAllocPidListHead, (PDLLIST_NODE)&(psRIEntry->sSysAllocListNode)); - OSLockRelease(g_hSysAllocPidListLock); - g_ui32SysAllocPMRCount++; - } - else - { - psRIEntry->ui32RIPMRFlags = 0; - psRIEntry->pid = ui32Owner; - } - - OSSNPrintf(psRIEntry->ai8ProcName, - RI_PROC_BUF_SIZE, - "%s", - OSGetCurrentClientProcessNameKM()); - /* Add PMR entry to linked-list of all PMR entries */ - dllist_init (&(psRIEntry->sListNode)); - dllist_add_to_tail(&sListFirst, (PDLLIST_NODE)&(psRIEntry->sListNode)); - } - - psRIEntry->psPMR = psPMR; - psRIEntry->ui32Flags = 0; - - /* Create index entry in Hash Table */ - HASH_Insert_Extended (g_pRIHashTable, (void *)&pPMRHashKey, (uintptr_t)psRIEntry); - - /* Store phRIHandle in PMR structure, so it can delete the associated RI entry when it destroys the PMR */ - PMRStoreRIHandle(psPMR, psRIEntry); - } - /* Release RI Lock */ - _RIUnlock(); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIWritePMREntryKM - - @Description - Writes a new Resource Information list entry. - The new entry will be inserted at the head of the list of - PMR RI entries and assigned the values provided. - - @input psPMR - Reference (handle) to the PMR to which this reference relates - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIWritePMREntryKM(PMR *psPMR) -{ - return RIWritePMREntryWithOwnerKM(psPMR, - OSGetCurrentClientProcessIDKM()); -} - -/*! -******************************************************************************* - - @Function RIWriteMEMDESCEntryKM - - @Description - Writes a new Resource Information sublist entry. - The new entry will be inserted at the head of the sublist of - the indicated PMR list entry, and assigned the values provided. - - @input psPMR - Reference (handle) to the PMR to which this MEMDESC RI entry relates - @input ui32TextBSize - Length of string provided in psz8TextB parameter - @input psz8TextB - String describing this secondary reference (may be null) - @input ui64Offset - Offset from the start of the PMR at which this allocation begins - @input ui64Size - Size of this allocation - @input bIsImport - Flag indicating if this is an allocation or an import - @input bIsSuballoc - Flag indicating if this is a sub-allocation - @output phRIHandle - Handle to the created RI entry - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIWriteMEMDESCEntryKM(PMR *psPMR, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR *psz8TextB, - IMG_UINT64 ui64Offset, - IMG_UINT64 ui64Size, - IMG_BOOL bIsImport, - IMG_BOOL bIsSuballoc, - RI_HANDLE *phRIHandle) -{ - RI_SUBLIST_ENTRY *psRISubEntry; - RI_LIST_ENTRY *psRIEntry; - PMR *pPMRHashKey = psPMR; - uintptr_t hashData; - IMG_PID pid; - - /* Check Hash tables have been created (meaning at least one PMR has been defined) */ - PVR_RETURN_IF_INVALID_PARAM(g_pRIHashTable); - PVR_RETURN_IF_INVALID_PARAM(g_pProcHashTable); - - PVR_RETURN_IF_INVALID_PARAM(psPMR); - PVR_RETURN_IF_INVALID_PARAM(phRIHandle); - - /* Acquire RI Lock */ - _RILock(); - - *phRIHandle = NULL; - - /* Look-up psPMR in Hash Table */ - hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey); - psRIEntry = (RI_LIST_ENTRY *)hashData; - if (!psRIEntry) - { - /* Release RI Lock */ - _RIUnlock(); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psRISubEntry = (RI_SUBLIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_SUBLIST_ENTRY)); - if (!psRISubEntry) - { - /* Release RI Lock */ - _RIUnlock(); - /* Error - no memory to allocate for new RI sublist entry */ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - else - { - /* - * Insert new entry in sublist - */ - PDLLIST_NODE currentNode = dllist_get_next_node(&(psRIEntry->sSubListFirst)); - - /* - * Insert new entry before currentNode - */ - if (!currentNode) - { - currentNode = &(psRIEntry->sSubListFirst); - } - dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sListNode)); - - psRISubEntry->psRI = psRIEntry; - - /* Increment number of entries in sublist */ - psRIEntry->ui16SubListCount++; - if (psRIEntry->ui16SubListCount > psRIEntry->ui16MaxSubListCount) - { - psRIEntry->ui16MaxSubListCount = psRIEntry->ui16SubListCount; - } - psRISubEntry->valid = _VALID_RI_SUBLIST_ENTRY; - } - - /* If allocation is made during device or driver initialisation, - * track the MEMDESC entry under PVR_SYS_ALLOC_PID, otherwise use - * the current PID. - * Record host dev node allocations on the system PID. - */ - { - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)PMR_DeviceNode(psRISubEntry->psRI->psPMR); - - if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT || - psDeviceNode == PVRSRVGetPVRSRVData()->psHostMemDeviceNode) - { - psRISubEntry->pid = psRISubEntry->psRI->pid; - } - else - { - psRISubEntry->pid = OSGetCurrentClientProcessIDKM(); - } - } - - if (ui32TextBSize > sizeof(psRISubEntry->ai8TextB)-1) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: TextBSize too long (%u). Text will be truncated " - "to %zu characters", __func__, - ui32TextBSize, sizeof(psRISubEntry->ai8TextB)-1)); - } - - /* copy ai8TextB field data */ - OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8TextB, sizeof(psRISubEntry->ai8TextB), "%s", psz8TextB); - - psRISubEntry->ui64Offset = ui64Offset; - psRISubEntry->ui64Size = ui64Size; - psRISubEntry->bIsImport = bIsImport; - psRISubEntry->bIsSuballoc = bIsSuballoc; - OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8ProcName, RI_PROC_BUF_SIZE, "%s", OSGetCurrentClientProcessNameKM()); - dllist_init (&(psRISubEntry->sProcListNode)); - - /* - * Now insert this MEMDESC into the proc list - */ - /* look-up pid in Hash Table */ - pid = psRISubEntry->pid; - hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid); - if (!hashData) - { - /* - * No allocations for this pid yet - */ - HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)&(psRISubEntry->sProcListNode)); - /* Increment number of entries in proc hash table */ - g_ui16ProcCount++; - } - else - { - /* - * Insert allocation into pid allocations linked list - */ - PDLLIST_NODE currentNode = (PDLLIST_NODE)hashData; - - /* - * Insert new entry - */ - dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sProcListNode)); - } - *phRIHandle = (RI_HANDLE)psRISubEntry; - /* Release RI Lock */ - _RIUnlock(); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIWriteProcListEntryKM - - @Description - Write a new entry in the process list directly. We have to do this - because there might be no, multiple or changing PMR handles. - - In the common case we have a PMR that will be added to the PMR list - and one or several MemDescs that are associated to it in a sub-list. - Additionally these MemDescs will be inserted in the per-process list. - - There might be special descriptors from e.g. new user APIs that - are associated with no or multiple PMRs and not just one. - These can be now added to the per-process list (as RI_SUBLIST_ENTRY) - directly with this function and won't be listed in the PMR list (RIEntry) - because there might be no PMR. - - To remove entries from the per-process list, just use - RIDeleteMEMDESCEntryKM(). - - @input psz8TextB - String describing this secondary reference (may be null) - @input ui64Size - Size of this allocation - @input ui64DevVAddr - Virtual address of this entry - @output phRIHandle - Handle to the created RI entry - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIWriteProcListEntryKM(IMG_UINT32 ui32TextBSize, - const IMG_CHAR *psz8TextB, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64DevVAddr, - RI_HANDLE *phRIHandle) -{ - uintptr_t hashData = 0; - IMG_PID pid; - RI_SUBLIST_ENTRY *psRISubEntry = NULL; - - if (!g_pRIHashTable) - { - g_pRIHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(PMR*), HASH_Func_Default, HASH_Key_Comp_Default); - g_pProcHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(IMG_PID), _ProcHashFunc, _ProcHashComp); - - if (!g_pRIHashTable || !g_pProcHashTable) - { - /* Error - no memory to allocate for Hash table(s) */ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - - /* Acquire RI Lock */ - _RILock(); - - *phRIHandle = NULL; - - psRISubEntry = (RI_SUBLIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_SUBLIST_ENTRY)); - if (!psRISubEntry) - { - /* Release RI Lock */ - _RIUnlock(); - /* Error - no memory to allocate for new RI sublist entry */ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psRISubEntry->valid = _VALID_RI_SUBLIST_ENTRY; - - psRISubEntry->pid = OSGetCurrentClientProcessIDKM(); - - if (ui32TextBSize > sizeof(psRISubEntry->ai8TextB)-1) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: TextBSize too long (%u). Text will be truncated " - "to %zu characters", __func__, - ui32TextBSize, sizeof(psRISubEntry->ai8TextB)-1)); - } - - /* copy ai8TextB field data */ - OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8TextB, sizeof(psRISubEntry->ai8TextB), "%s", psz8TextB); - - psRISubEntry->ui64Offset = 0; - psRISubEntry->ui64Size = ui64Size; - psRISubEntry->sVAddr.uiAddr = ui64DevVAddr; - psRISubEntry->bIsImport = IMG_FALSE; - psRISubEntry->bIsSuballoc = IMG_FALSE; - OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8ProcName, RI_PROC_BUF_SIZE, "%s", OSGetCurrentClientProcessNameKM()); - dllist_init (&(psRISubEntry->sProcListNode)); - - /* - * Now insert this MEMDESC into the proc list - */ - /* look-up pid in Hash Table */ - pid = psRISubEntry->pid; - hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid); - if (!hashData) - { - /* - * No allocations for this pid yet - */ - HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)&(psRISubEntry->sProcListNode)); - /* Increment number of entries in proc hash table */ - g_ui16ProcCount++; - } - else - { - /* - * Insert allocation into pid allocations linked list - */ - PDLLIST_NODE currentNode = (PDLLIST_NODE)hashData; - - /* - * Insert new entry - */ - dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sProcListNode)); - } - *phRIHandle = (RI_HANDLE)psRISubEntry; - /* Release RI Lock */ - _RIUnlock(); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIUpdateMEMDESCAddrKM - - @Description - Update a Resource Information entry. - - @input hRIHandle - Handle of object whose reference info is to be updated - @input sVAddr - New address for the RI entry - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIUpdateMEMDESCAddrKM(RI_HANDLE hRIHandle, - IMG_DEV_VIRTADDR sVAddr) -{ - RI_SUBLIST_ENTRY *psRISubEntry; - - PVR_RETURN_IF_INVALID_PARAM(hRIHandle); - - psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle; - if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY) - { - /* Pointer does not point to valid structure */ - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Acquire RI lock*/ - _RILock(); - - psRISubEntry->sVAddr.uiAddr = sVAddr.uiAddr; - - /* Release RI lock */ - _RIUnlock(); - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIDeletePMREntryKM - - @Description - Delete a Resource Information entry. - - @input hRIHandle - Handle of object whose reference info is to be deleted - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDeletePMREntryKM(RI_HANDLE hRIHandle) -{ - RI_LIST_ENTRY *psRIEntry; - PMR *pPMRHashKey; - PVRSRV_ERROR eResult = PVRSRV_OK; - - PVR_RETURN_IF_INVALID_PARAM(hRIHandle); - - psRIEntry = (RI_LIST_ENTRY *)hRIHandle; - - if (psRIEntry->valid != _VALID_RI_LIST_ENTRY) - { - /* Pointer does not point to valid structure */ - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (psRIEntry->ui16SubListCount == 0) - { - /* Acquire RI lock*/ - _RILock(); - - /* Remove the HASH table index entry */ - pPMRHashKey = psRIEntry->psPMR; - HASH_Remove_Extended(g_pRIHashTable, (void *)&pPMRHashKey); - - psRIEntry->valid = _INVALID; - - /* Remove PMR entry from linked-list of PMR entries */ - dllist_remove_node((PDLLIST_NODE)&(psRIEntry->sListNode)); - - if (psRIEntry->ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR) - { - dllist_remove_node((PDLLIST_NODE)&(psRIEntry->sSysAllocListNode)); - g_ui32SysAllocPMRCount--; - } - - /* Now, free the memory used to store the RI entry */ - OSFreeMemNoStats(psRIEntry); - psRIEntry = NULL; - - /* - * Decrement number of RI entries - if this is now zero, - * we can delete the RI hash table - */ - if (--g_ui16RICount == 0) - { - HASH_Delete(g_pRIHashTable); - g_pRIHashTable = NULL; - - _RIUnlock(); - - /* If deInit has been deferred, we can now destroy the RI Lock */ - if (bRIDeInitDeferred) - { - OSLockDestroy(g_hRILock); - } - } - else - { - /* Release RI lock*/ - _RIUnlock(); - } - /* - * Make the handle NULL once PMR RI entry is deleted - */ - hRIHandle = NULL; - } - else - { - eResult = PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP; - } - - return eResult; -} - -/*! -******************************************************************************* - - @Function RIDeleteMEMDESCEntryKM - - @Description - Delete a Resource Information entry. - Entry can be from RIEntry list or ProcList. - - @input hRIHandle - Handle of object whose reference info is to be deleted - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDeleteMEMDESCEntryKM(RI_HANDLE hRIHandle) -{ - RI_LIST_ENTRY *psRIEntry = NULL; - RI_SUBLIST_ENTRY *psRISubEntry; - uintptr_t hashData; - IMG_PID pid; - - PVR_RETURN_IF_INVALID_PARAM(hRIHandle); - - psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle; - if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY) - { - /* Pointer does not point to valid structure */ - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Acquire RI lock*/ - _RILock(); - - /* For entries which do have a parent PMR remove the node from the sublist */ - if (psRISubEntry->psRI) - { - psRIEntry = (RI_LIST_ENTRY *)psRISubEntry->psRI; - - /* Now, remove entry from the sublist */ - dllist_remove_node(&(psRISubEntry->sListNode)); - } - - psRISubEntry->valid = _INVALID; - - /* Remove the entry from the proc allocations linked list */ - pid = psRISubEntry->pid; - /* If this is the only allocation for this pid, just remove it from the hash table */ - if (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) - { - HASH_Remove_Extended(g_pProcHashTable, (void *)&pid); - /* Decrement number of entries in proc hash table, and delete the hash table if there are now none */ - if (--g_ui16ProcCount == 0) - { - HASH_Delete(g_pProcHashTable); - g_pProcHashTable = NULL; - } - } - else - { - hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid); - if ((PDLLIST_NODE)hashData == &(psRISubEntry->sProcListNode)) - { - HASH_Remove_Extended(g_pProcHashTable, (void *)&pid); - HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)dllist_get_next_node(&(psRISubEntry->sProcListNode))); - } - } - dllist_remove_node(&(psRISubEntry->sProcListNode)); - - /* Now, free the memory used to store the sublist entry */ - OSFreeMemNoStats(psRISubEntry); - psRISubEntry = NULL; - - /* - * Decrement number of entries in sublist if this MemDesc had a parent entry. - */ - if (psRIEntry) - { - psRIEntry->ui16SubListCount--; - } - - /* Release RI lock*/ - _RIUnlock(); - - /* - * Make the handle NULL once MEMDESC RI entry is deleted - */ - hRIHandle = NULL; - - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIDeleteListKM - - @Description - Delete all Resource Information entries and free associated - memory. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDeleteListKM(void) -{ - PVRSRV_ERROR eResult = PVRSRV_OK; - - _RILock(); - - if (g_pRIHashTable) - { - eResult = HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DeleteAllEntries, NULL); - if (eResult == PVRSRV_ERROR_RESOURCE_UNAVAILABLE) - { - /* - * PVRSRV_ERROR_RESOURCE_UNAVAILABLE is used to stop the Hash iterator when - * the hash table gets deleted as a result of deleting the final PMR entry, - * so this is not a real error condition... - */ - eResult = PVRSRV_OK; - } - } - - /* After the run through the RIHashTable that holds the PMR entries there might be - * still entries left in the per-process hash table because they were added with - * RIWriteProcListEntryKM() and have no PMR parent associated. - */ - if (g_pProcHashTable) - { - eResult = HASH_Iterate(g_pProcHashTable, (HASH_pfnCallback) _DeleteAllProcEntries, NULL); - if (eResult == PVRSRV_ERROR_RESOURCE_UNAVAILABLE) - { - /* - * PVRSRV_ERROR_RESOURCE_UNAVAILABLE is used to stop the Hash iterator when - * the hash table gets deleted as a result of deleting the final PMR entry, - * so this is not a real error condition... - */ - eResult = PVRSRV_OK; - } - } - - _RIUnlock(); - - return eResult; -} - -/*! -******************************************************************************* - - @Function RIDumpListKM - - @Description - Dumps out the contents of the RI List entry for the - specified PMR, and all MEMDESC allocation entries - in the associated sub linked list. - At present, output is directed to Kernel log - via PVR_DPF. - - @input psPMR - PMR for which RI entry details are to be output - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDumpListKM(PMR *psPMR) -{ - PVRSRV_ERROR eError; - - /* Acquire RI lock*/ - _RILock(); - - eError = _DumpList(psPMR, 0); - - /* Release RI lock*/ - _RIUnlock(); - - return eError; -} - -/*! -******************************************************************************* - - @Function RIGetListEntryKM - - @Description - Returns pointer to a formatted string with details of the specified - list entry. If no entry exists (e.g. it may have been deleted - since the previous call), NULL is returned. - - @input pid - pid for which RI entry details are to be output - @input ppHandle - handle to the entry, if NULL, the first entry will be - returned. - @output pszEntryString - string to be output for the entry - @output hEntry - hEntry will be returned pointing to the next entry - (or NULL if there is no next entry) - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_BOOL RIGetListEntryKM(IMG_PID pid, - IMG_HANDLE **ppHandle, - IMG_CHAR **ppszEntryString) -{ - RI_SUBLIST_ENTRY *psRISubEntry = NULL; - RI_LIST_ENTRY *psRIEntry = NULL; - uintptr_t hashData = 0; - IMG_PID hashKey = pid; - - static IMG_CHAR acStringBuffer[RI_FRMT_SIZE_MAX]; - - static IMG_UINT64 ui64TotalMemdescAlloc; - static IMG_UINT64 ui64TotalImport; - static IMG_UINT64 ui64TotalPMRAlloc; - static IMG_UINT64 ui64TotalPMRBacked; - static enum { - RI_GET_STATE_MEMDESCS_LIST_START, - RI_GET_STATE_MEMDESCS_SUMMARY, - RI_GET_STATE_PMR_LIST, - RI_GET_STATE_PMR_SUMMARY, - RI_GET_STATE_END, - RI_GET_STATE_LAST - } g_bNextGetState = RI_GET_STATE_MEMDESCS_LIST_START; - - static DLLIST_NODE *psNode; - static DLLIST_NODE *psSysAllocNode; - static IMG_CHAR szProcName[RI_PROC_BUF_SIZE]; - static IMG_UINT32 ui32ProcessedSysAllocPMRCount; - - acStringBuffer[0] = '\0'; - - switch (g_bNextGetState) - { - case RI_GET_STATE_MEMDESCS_LIST_START: - /* look-up pid in Hash Table, to obtain first entry for pid */ - hashData = HASH_Retrieve_Extended(g_pProcHashTable, (void *)&hashKey); - if (hashData) - { - if (*ppHandle) - { - psRISubEntry = (RI_SUBLIST_ENTRY *)*ppHandle; - if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY) - { - psRISubEntry = NULL; - } - } - else - { - psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode); - if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY) - { - psRISubEntry = NULL; - } - } - } - - if (psRISubEntry) - { - PDLLIST_NODE psNextProcListNode = dllist_get_next_node(&psRISubEntry->sProcListNode); - - if (psRISubEntry->bIsImport) - { - ui64TotalImport += psRISubEntry->ui64Size; - } - else - { - ui64TotalMemdescAlloc += psRISubEntry->ui64Size; - } - - _GenerateMEMDESCEntryString(psRISubEntry, - IMG_TRUE, - RI_MEMDESC_ENTRY_BUF_SIZE, - acStringBuffer); - - if (szProcName[0] == '\0') - { - OSStringLCopy(szProcName, (pid == PVR_SYS_ALLOC_PID) ? - PVRSRV_MODNAME : psRISubEntry->ai8ProcName, RI_PROC_BUF_SIZE); - } - - - *ppszEntryString = acStringBuffer; - *ppHandle = (IMG_HANDLE)IMG_CONTAINER_OF(psNextProcListNode, RI_SUBLIST_ENTRY, sProcListNode); - - if (psNextProcListNode == NULL || - psNextProcListNode == (PDLLIST_NODE)hashData) - { - g_bNextGetState = RI_GET_STATE_MEMDESCS_SUMMARY; - } - /* else continue to list MEMDESCs */ - } - else - { - if (ui64TotalMemdescAlloc == 0) - { - acStringBuffer[0] = '\0'; - *ppszEntryString = acStringBuffer; - g_bNextGetState = RI_GET_STATE_MEMDESCS_SUMMARY; - } - /* else continue to list MEMDESCs */ - } - break; - - case RI_GET_STATE_MEMDESCS_SUMMARY: - OSSNPrintf(acStringBuffer, - RI_MEMDESC_SUM_BUF_SIZE, - RI_MEMDESC_SUM_FRMT, - pid, - szProcName, - ui64TotalMemdescAlloc, - ui64TotalMemdescAlloc >> 10, - ui64TotalImport, - ui64TotalImport >> 10, - (ui64TotalMemdescAlloc + ui64TotalImport), - (ui64TotalMemdescAlloc + ui64TotalImport) >> 10); - - *ppszEntryString = acStringBuffer; - ui64TotalMemdescAlloc = 0; - ui64TotalImport = 0; - szProcName[0] = '\0'; - - g_bNextGetState = RI_GET_STATE_PMR_LIST; - break; - - case RI_GET_STATE_PMR_LIST: - if (pid == PVR_SYS_ALLOC_PID) - { - OSLockAcquire(g_hSysAllocPidListLock); - acStringBuffer[0] = '\0'; - if (!psSysAllocNode) - { - psSysAllocNode = &g_sSysAllocPidListHead; - ui32ProcessedSysAllocPMRCount = 0; - } - psSysAllocNode = dllist_get_next_node(psSysAllocNode); - - if (szProcName[0] == '\0') - { - OSStringLCopy(szProcName, PVRSRV_MODNAME, RI_PROC_BUF_SIZE); - } - if (psSysAllocNode != NULL && psSysAllocNode != &g_sSysAllocPidListHead) - { - IMG_DEVMEM_SIZE_T uiPMRPhysicalBacking, uiPMRLogicalSize = 0; - - psRIEntry = IMG_CONTAINER_OF((PDLLIST_NODE)psSysAllocNode, RI_LIST_ENTRY, sSysAllocListNode); - _GeneratePMREntryString(psRIEntry, - IMG_TRUE, - RI_PMR_ENTRY_BUF_SIZE, - acStringBuffer); - PMR_LogicalSize(psRIEntry->psPMR, - &uiPMRLogicalSize); - ui64TotalPMRAlloc += uiPMRLogicalSize; - PMR_PhysicalSize(psRIEntry->psPMR, &uiPMRPhysicalBacking); - ui64TotalPMRBacked += uiPMRPhysicalBacking; - - ui32ProcessedSysAllocPMRCount++; - if (ui32ProcessedSysAllocPMRCount > g_ui32SysAllocPMRCount+1) - { - g_bNextGetState = RI_GET_STATE_PMR_SUMMARY; - } - /* else continue to list PMRs */ - } - else - { - g_bNextGetState = RI_GET_STATE_PMR_SUMMARY; - } - *ppszEntryString = (IMG_CHAR *)acStringBuffer; - OSLockRelease(g_hSysAllocPidListLock); - } - else - { - IMG_BOOL bPMRToDisplay = IMG_FALSE; - - /* Iterate through the 'touched' PMRs and display details */ - if (!psNode) - { - psNode = dllist_get_next_node(&sListFirst); - } - else - { - psNode = dllist_get_next_node(psNode); - } - - while ((psNode != NULL && psNode != &sListFirst) && - !bPMRToDisplay) - { - psRIEntry = IMG_CONTAINER_OF(psNode, RI_LIST_ENTRY, sListNode); - if (psRIEntry->pid == pid) - { - IMG_DEVMEM_SIZE_T uiPMRPhysicalBacking, uiPMRLogicalSize = 0; - - /* This PMR was 'touched', so display details and unflag it*/ - _GeneratePMREntryString(psRIEntry, - IMG_TRUE, - RI_PMR_ENTRY_BUF_SIZE, - acStringBuffer); - PMR_LogicalSize(psRIEntry->psPMR, &uiPMRLogicalSize); - ui64TotalPMRAlloc += uiPMRLogicalSize; - PMR_PhysicalSize(psRIEntry->psPMR, &uiPMRPhysicalBacking); - ui64TotalPMRBacked += uiPMRPhysicalBacking; - - /* Remember the name of the process for 1 PMR for the summary */ - if (szProcName[0] == '\0') - { - OSStringLCopy(szProcName, psRIEntry->ai8ProcName, RI_PROC_BUF_SIZE); - } - bPMRToDisplay = IMG_TRUE; - } - else - { - psNode = dllist_get_next_node(psNode); - } - } - - if (psNode == NULL || (psNode == &sListFirst)) - { - g_bNextGetState = RI_GET_STATE_PMR_SUMMARY; - } - /* else continue listing PMRs */ - } - break; - - case RI_GET_STATE_PMR_SUMMARY: - OSSNPrintf(acStringBuffer, - RI_PMR_SUM_BUF_SIZE, - RI_PMR_SUM_FRMT, - pid, - szProcName, - ui64TotalPMRAlloc, - ui64TotalPMRAlloc >> 10, - ui64TotalPMRBacked, - ui64TotalPMRBacked >> 10); - - *ppszEntryString = acStringBuffer; - ui64TotalPMRAlloc = 0; - ui64TotalPMRBacked = 0; - szProcName[0] = '\0'; - psSysAllocNode = NULL; - - g_bNextGetState = RI_GET_STATE_END; - break; - - default: - PVR_DPF((PVR_DBG_ERROR, "%s: Bad %d)",__func__, g_bNextGetState)); - - fallthrough; - case RI_GET_STATE_END: - /* Reset state ready for the next gpu_mem_area file to display */ - *ppszEntryString = NULL; - *ppHandle = NULL; - psNode = NULL; - szProcName[0] = '\0'; - - g_bNextGetState = RI_GET_STATE_MEMDESCS_LIST_START; - return IMG_FALSE; - break; - } - - return IMG_TRUE; -} - -/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */ -static void _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry, - IMG_BOOL bDebugFs, - IMG_UINT16 ui16MaxStrLen, - IMG_CHAR *pszEntryString) -{ - IMG_CHAR szProc[RI_MEMDESC_ENTRY_PROC_BUF_SIZE]; - IMG_CHAR szImport[RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE]; - IMG_CHAR szEntryFormat[RI_MEMDESC_ENTRY_FRMT_SIZE]; - const IMG_CHAR *pszAnnotationText; - IMG_PID uiRIPid = 0; - PMR* psRIPMR = NULL; - IMG_UINT32 ui32RIPMRFlags = 0; - - if (psRISubEntry->psRI != NULL) - { - uiRIPid = psRISubEntry->psRI->pid; - psRIPMR = psRISubEntry->psRI->psPMR; - ui32RIPMRFlags = psRISubEntry->psRI->ui32RIPMRFlags; - } - - OSSNPrintf(szEntryFormat, - RI_MEMDESC_ENTRY_FRMT_SIZE, - RI_MEMDESC_ENTRY_FRMT, - DEVMEM_ANNOTATION_MAX_LEN); - - if (!bDebugFs) - { - /* we don't include process ID info for debugfs output */ - OSSNPrintf(szProc, - RI_MEMDESC_ENTRY_PROC_BUF_SIZE, - RI_MEMDESC_ENTRY_PROC_FRMT, - psRISubEntry->pid, - psRISubEntry->ai8ProcName); - } - - if (psRISubEntry->bIsImport && psRIPMR) - { - OSSNPrintf((IMG_CHAR *)&szImport, - RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE, - RI_MEMDESC_ENTRY_IMPORT_FRMT, - uiRIPid); - /* Set pszAnnotationText to that of the 'parent' PMR RI entry */ - pszAnnotationText = PMR_GetAnnotation(psRIPMR); - } - else if (!psRISubEntry->bIsSuballoc && psRIPMR) - { - /* Set pszAnnotationText to that of the 'parent' PMR RI entry */ - pszAnnotationText = PMR_GetAnnotation(psRIPMR); - } - else - { - /* Set pszAnnotationText to that of the MEMDESC RI entry */ - pszAnnotationText = psRISubEntry->ai8TextB; - } - - /* Don't print memdescs if they are local imports - * (i.e. imported PMRs allocated by this process) - */ - if (bDebugFs && - ((psRISubEntry->sVAddr.uiAddr + psRISubEntry->ui64Offset) == 0) && - (psRISubEntry->bIsImport && ((psRISubEntry->pid == uiRIPid) - || (psRISubEntry->pid == PVR_SYS_ALLOC_PID)))) - { - /* Don't print this entry */ - pszEntryString[0] = '\0'; - } - else - { - OSSNPrintf(pszEntryString, - ui16MaxStrLen, - szEntryFormat, - (bDebugFs ? "" : " "), - psRISubEntry->pid, - (psRISubEntry->sVAddr.uiAddr + psRISubEntry->ui64Offset), - pszAnnotationText, - (bDebugFs ? "" : (char *)szProc), - psRISubEntry->ui64Size, - psRIPMR, - (psRISubEntry->bIsImport ? (char *)&szImport : ""), - (!psRISubEntry->bIsImport && (ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR) && (psRISubEntry->pid != PVR_SYS_ALLOC_PID)) ? g_szSysAllocImport : "", - (psRIPMR && PMR_IsUnpinned(psRIPMR)) ? RI_MEMDESC_ENTRY_UNPINNED_FRMT : "", - (bDebugFs ? '\n' : ' ')); - } -} - -/* Function used to produce string containing info for PMR RI entries (used for debugfs and kernel log output) */ -static void _GeneratePMREntryString(RI_LIST_ENTRY *psRIEntry, - IMG_BOOL bDebugFs, - IMG_UINT16 ui16MaxStrLen, - IMG_CHAR *pszEntryString) -{ - const IMG_CHAR* pszAnnotationText; - IMG_DEVMEM_SIZE_T uiLogicalSize = 0; - IMG_DEVMEM_SIZE_T uiPhysicalSize = 0; - IMG_CHAR szEntryFormat[RI_PMR_ENTRY_FRMT_SIZE]; - - PMR_LogicalSize(psRIEntry->psPMR, &uiLogicalSize); - - PMR_PhysicalSize(psRIEntry->psPMR, &uiPhysicalSize); - - OSSNPrintf(szEntryFormat, - RI_PMR_ENTRY_FRMT_SIZE, - RI_PMR_ENTRY_FRMT, - DEVMEM_ANNOTATION_MAX_LEN); - - /* Set pszAnnotationText to that PMR RI entry */ - pszAnnotationText = (IMG_PCHAR) PMR_GetAnnotation(psRIEntry->psPMR); - - OSSNPrintf(pszEntryString, - ui16MaxStrLen, - szEntryFormat, - (bDebugFs ? "" : " "), - psRIEntry->pid, - (void*)psRIEntry->psPMR, - pszAnnotationText, - uiLogicalSize, - uiPhysicalSize, - (bDebugFs ? '\n' : ' ')); -} - -/*! -******************************************************************************* - - @Function _DumpList - - @Description - Dumps out RI List entries according to parameters passed. - - @input psPMR - If not NULL, function will output the RI entries for - the specified PMR only - @input pid - If non-zero, the function will only output MEMDESC RI - entries made by the process with ID pid. - If zero, all MEMDESC RI entries will be output. - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR _DumpList(PMR *psPMR, IMG_PID pid) -{ - RI_LIST_ENTRY *psRIEntry = NULL; - RI_SUBLIST_ENTRY *psRISubEntry = NULL; - IMG_UINT16 ui16SubEntriesParsed = 0; - uintptr_t hashData = 0; - IMG_PID hashKey; - PMR *pPMRHashKey = psPMR; - IMG_BOOL bDisplayedThisPMR = IMG_FALSE; - IMG_UINT64 ui64LogicalSize = 0; - - PVR_RETURN_IF_INVALID_PARAM(psPMR); - - if (g_pRIHashTable && g_pProcHashTable) - { - if (pid != 0) - { - /* look-up pid in Hash Table */ - hashKey = pid; - hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&hashKey); - if (hashData) - { - psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode); - if (psRISubEntry) - { - psRIEntry = psRISubEntry->psRI; - } - } - } - else - { - /* Look-up psPMR in Hash Table */ - hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey); - psRIEntry = (RI_LIST_ENTRY *)hashData; - } - if (!psRIEntry) - { - /* No entry found in hash table */ - return PVRSRV_ERROR_NOT_FOUND; - } - while (psRIEntry) - { - bDisplayedThisPMR = IMG_FALSE; - /* Output details for RI entry */ - if (!pid) - { - PMR_LogicalSize(psPMR, (IMG_DEVMEM_SIZE_T*)&ui64LogicalSize); - - _RIOutput (("%s <%p> suballocs:%d size:0x%010" IMG_UINT64_FMTSPECx, - PMR_GetAnnotation(psRIEntry->psPMR), - psRIEntry->psPMR, - (IMG_UINT)psRIEntry->ui16SubListCount, - ui64LogicalSize)); - bDisplayedThisPMR = IMG_TRUE; - } - ui16SubEntriesParsed = 0; - if (psRIEntry->ui16SubListCount) - { -#if _DUMP_LINKEDLIST_INFO - _RIOutput (("RI LIST: {sSubListFirst.psNextNode:0x%p}\n", - psRIEntry->sSubListFirst.psNextNode)); -#endif /* _DUMP_LINKEDLIST_INFO */ - if (!pid) - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)), - RI_SUBLIST_ENTRY, sListNode); - } - /* Traverse RI sublist and output details for each entry */ - while (psRISubEntry) - { - if (psRIEntry) - { - if ((ui16SubEntriesParsed >= psRIEntry->ui16SubListCount)) - { - break; - } - if (!bDisplayedThisPMR) - { - PMR_LogicalSize(psPMR, (IMG_DEVMEM_SIZE_T*)&ui64LogicalSize); - - _RIOutput (("%s <%p> suballocs:%d size:0x%010" IMG_UINT64_FMTSPECx, - PMR_GetAnnotation(psRIEntry->psPMR), - psRIEntry->psPMR, - (IMG_UINT)psRIEntry->ui16SubListCount, - ui64LogicalSize)); - bDisplayedThisPMR = IMG_TRUE; - } - } -#if _DUMP_LINKEDLIST_INFO - _RIOutput (("RI LIST: [this subentry:0x%p]\n",psRISubEntry)); - _RIOutput (("RI LIST: psRI:0x%p\n",psRISubEntry->psRI)); -#endif /* _DUMP_LINKEDLIST_INFO */ - - { - IMG_CHAR szEntryString[RI_MEMDESC_ENTRY_BUF_SIZE]; - - _GenerateMEMDESCEntryString(psRISubEntry, - IMG_FALSE, - RI_MEMDESC_ENTRY_BUF_SIZE, - szEntryString); - _RIOutput (("%s",szEntryString)); - } - - if (pid) - { - if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) || - (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData)) - { - psRISubEntry = NULL; - } - else - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)), - RI_SUBLIST_ENTRY, sProcListNode); - if (psRISubEntry) - { - if (psRIEntry != psRISubEntry->psRI) - { - /* - * The next MEMDESC in the process linked list is in a different PMR - */ - psRIEntry = psRISubEntry->psRI; - bDisplayedThisPMR = IMG_FALSE; - } - } - } - } - else - { - ui16SubEntriesParsed++; - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sListNode)), - RI_SUBLIST_ENTRY, sListNode); - } - } - } - if (!pid && psRIEntry) - { - if (ui16SubEntriesParsed != psRIEntry->ui16SubListCount) - { - /* - * Output error message as sublist does not contain the - * number of entries indicated by sublist count - */ - _RIOutput (("RI ERROR: RI sublist contains %d entries, not %d entries\n", - ui16SubEntriesParsed, psRIEntry->ui16SubListCount)); - } - else if (psRIEntry->ui16SubListCount && !dllist_get_next_node(&(psRIEntry->sSubListFirst))) - { - /* - * Output error message as sublist is empty but sublist count - * is not zero - */ - _RIOutput (("RI ERROR: ui16SubListCount=%d for empty RI sublist\n", - psRIEntry->ui16SubListCount)); - } - } - psRIEntry = NULL; - } - } - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIDumpAllKM - - @Description - Dumps out the contents of all RI List entries (i.e. for all - MEMDESC allocations for each PMR). - At present, output is directed to Kernel log - via PVR_DPF. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDumpAllKM(void) -{ - if (g_pRIHashTable) - { - return HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DumpAllEntries, NULL); - } - return PVRSRV_OK; -} - -/*! -******************************************************************************* - - @Function RIDumpProcessKM - - @Description - Dumps out the contents of all MEMDESC RI List entries (for every - PMR) which have been allocate by the specified process only. - At present, output is directed to Kernel log - via PVR_DPF. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDumpProcessKM(IMG_PID pid) -{ - PVRSRV_ERROR eError; - IMG_UINT32 dummyPMR; - - if (!g_pProcHashTable) - { - return PVRSRV_OK; - } - - /* Acquire RI lock*/ - _RILock(); - - eError = _DumpList((PMR *)&dummyPMR, pid); - - /* Release RI lock*/ - _RIUnlock(); - - return eError; -} - -/*! -******************************************************************************* - - @Function _TotalAllocsForProcess - - @Description - Totals all PMR physical backing for given process. - - @input pid - ID of process. - - @input ePhysHeapType - type of Physical Heap for which to total allocs - - @Return Size of all physical backing for PID's PMRs allocated from the - specified heap type (in bytes). - -******************************************************************************/ -static IMG_INT32 _TotalAllocsForProcess(IMG_PID pid, PHYS_HEAP_TYPE ePhysHeapType) -{ - RI_LIST_ENTRY *psRIEntry = NULL; - RI_SUBLIST_ENTRY *psInitialRISubEntry = NULL; - RI_SUBLIST_ENTRY *psRISubEntry = NULL; - uintptr_t hashData = 0; - IMG_PID hashKey; - IMG_INT32 i32TotalPhysical = 0; - - if (g_pRIHashTable && g_pProcHashTable) - { - if (pid == PVR_SYS_ALLOC_PID) - { - IMG_UINT32 ui32ProcessedSysAllocPMRCount = 0; - DLLIST_NODE *psSysAllocNode = NULL; - - OSLockAcquire(g_hSysAllocPidListLock); - psSysAllocNode = dllist_get_next_node(&g_sSysAllocPidListHead); - while (psSysAllocNode && psSysAllocNode != &g_sSysAllocPidListHead) - { - psRIEntry = IMG_CONTAINER_OF((PDLLIST_NODE)psSysAllocNode, RI_LIST_ENTRY, sSysAllocListNode); - ui32ProcessedSysAllocPMRCount++; - if (PhysHeapGetType(PMR_PhysHeap(psRIEntry->psPMR)) == ePhysHeapType) - { - IMG_UINT64 ui64PhysicalSize; - - PMR_PhysicalSize(psRIEntry->psPMR, (IMG_DEVMEM_SIZE_T*)&ui64PhysicalSize); - if (((IMG_UINT64)i32TotalPhysical + ui64PhysicalSize > 0x7fffffff)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: i32TotalPhysical exceeding size for i32",__func__)); - } - i32TotalPhysical += (IMG_INT32)(ui64PhysicalSize & 0x00000000ffffffff); - } - psSysAllocNode = dllist_get_next_node(psSysAllocNode); - } - OSLockRelease(g_hSysAllocPidListLock); - } - else - { - if (pid != 0) - { - /* look-up pid in Hash Table */ - hashKey = pid; - hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&hashKey); - if (hashData) - { - psInitialRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode); - psRISubEntry = psInitialRISubEntry; - if (psRISubEntry) - { - psRIEntry = psRISubEntry->psRI; - } - } - } - - while (psRISubEntry && psRIEntry) - { - if (!psRISubEntry->bIsImport && !(psRIEntry->ui32RIPMRFlags & RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS) && - (pid == PVR_SYS_ALLOC_PID || !(psRIEntry->ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR)) && - (PhysHeapGetType(PMR_PhysHeap(psRIEntry->psPMR)) == ePhysHeapType)) - { - IMG_UINT64 ui64PhysicalSize; - - - PMR_PhysicalSize(psRIEntry->psPMR, (IMG_DEVMEM_SIZE_T*)&ui64PhysicalSize); - if (((IMG_UINT64)i32TotalPhysical + ui64PhysicalSize > 0x7fffffff)) - { - PVR_DPF((PVR_DBG_WARNING, "%s: i32TotalPhysical exceeding size for i32",__func__)); - } - i32TotalPhysical += (IMG_INT32)(ui64PhysicalSize & 0x00000000ffffffff); - psRIEntry->ui32RIPMRFlags |= RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS; - } - if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) || - (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData)) - { - psRISubEntry = NULL; - psRIEntry = NULL; - } - else - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)), - RI_SUBLIST_ENTRY, sProcListNode); - if (psRISubEntry) - { - psRIEntry = psRISubEntry->psRI; - } - } - } - psRISubEntry = psInitialRISubEntry; - if (psRISubEntry) - { - psRIEntry = psRISubEntry->psRI; - } - while (psRISubEntry && psRIEntry) - { - psRIEntry->ui32RIPMRFlags &= ~RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS; - if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) || - (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData)) - { - psRISubEntry = NULL; - psRIEntry = NULL; - } - else - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)), - RI_SUBLIST_ENTRY, sProcListNode); - if (psRISubEntry) - { - psRIEntry = psRISubEntry->psRI; - } - } - } - } - } - return i32TotalPhysical; -} - -/*! -******************************************************************************* - - @Function RITotalAllocProcessKM - - @Description - Returns the total of allocated GPU memory (backing for PMRs) - which has been allocated from the specific heap by the specified - process only. - - @Return Amount of physical backing allocated (in bytes) - -******************************************************************************/ -IMG_INT32 RITotalAllocProcessKM(IMG_PID pid, PHYS_HEAP_TYPE ePhysHeapType) -{ - IMG_INT32 i32BackingTotal = 0; - - if (g_pProcHashTable) - { - /* Acquire RI lock*/ - _RILock(); - - i32BackingTotal = _TotalAllocsForProcess(pid, ePhysHeapType); - - /* Release RI lock*/ - _RIUnlock(); - } - return i32BackingTotal; -} - -#if defined(DEBUG) -/*! -******************************************************************************* - - @Function _DumpProcessList - - @Description - Dumps out RI List entries according to parameters passed. - - @input psPMR - If not NULL, function will output the RI entries for - the specified PMR only - @input pid - If non-zero, the function will only output MEMDESC RI - entries made by the process with ID pid. - If zero, all MEMDESC RI entries will be output. - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR _DumpProcessList(PMR *psPMR, - IMG_PID pid, - IMG_UINT64 ui64Offset, - IMG_DEV_VIRTADDR *psDevVAddr) -{ - RI_LIST_ENTRY *psRIEntry = NULL; - RI_SUBLIST_ENTRY *psRISubEntry = NULL; - IMG_UINT16 ui16SubEntriesParsed = 0; - uintptr_t hashData = 0; - PMR *pPMRHashKey = psPMR; - - psDevVAddr->uiAddr = 0; - - PVR_RETURN_IF_INVALID_PARAM(psPMR); - - if (g_pRIHashTable && g_pProcHashTable) - { - PVR_ASSERT(psPMR && pid); - - /* Look-up psPMR in Hash Table */ - hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey); - psRIEntry = (RI_LIST_ENTRY *)hashData; - - if (!psRIEntry) - { - /* No entry found in hash table */ - return PVRSRV_ERROR_NOT_FOUND; - } - - if (psRIEntry->ui16SubListCount) - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)), - RI_SUBLIST_ENTRY, sListNode); - - /* Traverse RI sublist and output details for each entry */ - while (psRISubEntry && (ui16SubEntriesParsed < psRIEntry->ui16SubListCount)) - { - if (pid == psRISubEntry->pid) - { - IMG_UINT64 ui64StartOffset = psRISubEntry->ui64Offset; - IMG_UINT64 ui64EndOffset = psRISubEntry->ui64Offset + psRISubEntry->ui64Size; - - if (ui64Offset >= ui64StartOffset && ui64Offset < ui64EndOffset) - { - psDevVAddr->uiAddr = psRISubEntry->sVAddr.uiAddr; - return PVRSRV_OK; - } - } - - ui16SubEntriesParsed++; - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sListNode)), - RI_SUBLIST_ENTRY, sListNode); - } - } - } - - return PVRSRV_ERROR_INVALID_PARAMS; -} - -/*! -******************************************************************************* - - @Function RIDumpProcessListKM - - @Description - Dumps out selected contents of all MEMDESC RI List entries (for a - PMR) which have been allocate by the specified process only. - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR RIDumpProcessListKM(PMR *psPMR, - IMG_PID pid, - IMG_UINT64 ui64Offset, - IMG_DEV_VIRTADDR *psDevVAddr) -{ - PVRSRV_ERROR eError; - - if (!g_pProcHashTable) - { - return PVRSRV_OK; - } - - /* Acquire RI lock*/ - _RILock(); - - eError = _DumpProcessList(psPMR, - pid, - ui64Offset, - psDevVAddr); - - /* Release RI lock*/ - _RIUnlock(); - - return eError; -} -#endif - -static PVRSRV_ERROR _DumpAllEntries (uintptr_t k, uintptr_t v, void* pvPriv) -{ - RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v; - - PVR_UNREFERENCED_PARAMETER (k); - PVR_UNREFERENCED_PARAMETER (pvPriv); - - return RIDumpListKM(psRIEntry->psPMR); -} - -static PVRSRV_ERROR _DeleteAllEntries (uintptr_t k, uintptr_t v, void* pvPriv) -{ - RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v; - RI_SUBLIST_ENTRY *psRISubEntry; - PVRSRV_ERROR eResult = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER (k); - PVR_UNREFERENCED_PARAMETER (pvPriv); - - while ((eResult == PVRSRV_OK) && (psRIEntry->ui16SubListCount > 0)) - { - psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)), RI_SUBLIST_ENTRY, sListNode); - eResult = RIDeleteMEMDESCEntryKM((RI_HANDLE)psRISubEntry); - } - if (eResult == PVRSRV_OK) - { - eResult = RIDeletePMREntryKM((RI_HANDLE)psRIEntry); - /* - * If we've deleted the Hash table, return - * an error to stop the iterator... - */ - if (!g_pRIHashTable) - { - eResult = PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - } - return eResult; -} - -static PVRSRV_ERROR _DeleteAllProcEntries (uintptr_t k, uintptr_t v, void* pvPriv) -{ - RI_SUBLIST_ENTRY *psRISubEntry = (RI_SUBLIST_ENTRY *)v; - PVRSRV_ERROR eResult; - - PVR_UNREFERENCED_PARAMETER (k); - PVR_UNREFERENCED_PARAMETER (pvPriv); - - eResult = RIDeleteMEMDESCEntryKM((RI_HANDLE) psRISubEntry); - if (eResult == PVRSRV_OK && !g_pProcHashTable) - { - /* - * If we've deleted the Hash table, return - * an error to stop the iterator... - */ - eResult = PVRSRV_ERROR_RESOURCE_UNAVAILABLE; - } - - return eResult; -} - -#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/ri_server.h b/drivers/gpu/drm/img-rogue/1.17/ri_server.h deleted file mode 100644 index cb57bdbd5cb9a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ri_server.h +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************/ /*! -@File ri_server.h -@Title Resource Information abstraction -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Resource Information (RI) functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RI_SERVER_H -#define RI_SERVER_H - -#include "img_defs.h" -#include "ri_typedefs.h" -#include "pmr.h" -#include "pvrsrv_error.h" -#include "physheap.h" - -PVRSRV_ERROR RIInitKM(void); -void RIDeInitKM(void); - -void RILockAcquireKM(void); -void RILockReleaseKM(void); - -PVRSRV_ERROR RIWritePMREntryKM(PMR *psPMR); - -PVRSRV_ERROR RIWritePMREntryWithOwnerKM(PMR *psPMR, - IMG_PID ui32Owner); - -PVRSRV_ERROR RIWriteMEMDESCEntryKM(PMR *psPMR, - IMG_UINT32 ui32TextBSize, - const IMG_CHAR *ai8TextB, - IMG_UINT64 uiOffset, - IMG_UINT64 uiSize, - IMG_BOOL bIsImport, - IMG_BOOL bIsSuballoc, - RI_HANDLE *phRIHandle); - -PVRSRV_ERROR RIWriteProcListEntryKM(IMG_UINT32 ui32TextBSize, - const IMG_CHAR *psz8TextB, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64DevVAddr, - RI_HANDLE *phRIHandle); - -PVRSRV_ERROR RIUpdateMEMDESCAddrKM(RI_HANDLE hRIHandle, - IMG_DEV_VIRTADDR sVAddr); - -PVRSRV_ERROR RIDeletePMREntryKM(RI_HANDLE hRIHandle); -PVRSRV_ERROR RIDeleteMEMDESCEntryKM(RI_HANDLE hRIHandle); - -PVRSRV_ERROR RIDeleteListKM(void); - -PVRSRV_ERROR RIDumpListKM(PMR *psPMR); - -PVRSRV_ERROR RIDumpAllKM(void); - -PVRSRV_ERROR RIDumpProcessKM(IMG_PID pid); - -#if defined(DEBUG) -PVRSRV_ERROR RIDumpProcessListKM(PMR *psPMR, - IMG_PID pid, - IMG_UINT64 ui64Offset, - IMG_DEV_VIRTADDR *psDevVAddr); -#endif - -IMG_BOOL RIGetListEntryKM(IMG_PID pid, - IMG_HANDLE **ppHandle, - IMG_CHAR **ppszEntryString); - -IMG_INT32 RITotalAllocProcessKM(IMG_PID pid, PHYS_HEAP_TYPE ePhysHeapType); - -#endif /* RI_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/ri_typedefs.h b/drivers/gpu/drm/img-rogue/1.17/ri_typedefs.h deleted file mode 100644 index 77be10e2ab03c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/ri_typedefs.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Resource Information (RI) Management -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Client side part of RI management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 RI_TYPEDEFS_H -#define RI_TYPEDEFS_H - -#include "img_types.h" - -typedef struct RI_SUBLIST_ENTRY RI_ENTRY; -typedef RI_ENTRY* RI_HANDLE; - -#endif /* #ifndef RI_TYPEDEFS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/rogue_trace_events.h b/drivers/gpu/drm/img-rogue/1.17/rogue_trace_events.h deleted file mode 100644 index cc877c486971d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/rogue_trace_events.h +++ /dev/null @@ -1,542 +0,0 @@ -/*************************************************************************/ /*! -@File -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM rogue_1_17 - -#if !defined(ROGUE_TRACE_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) -#define ROGUE_TRACE_EVENTS_H - -#include -#include -#include -#include - -#define show_secs_from_ns(ns) \ - ({ \ - u64 t = ns + (NSEC_PER_USEC / 2); \ - do_div(t, NSEC_PER_SEC); \ - t; \ - }) - -#define show_usecs_from_ns(ns) \ - ({ \ - u64 t = ns + (NSEC_PER_USEC / 2); \ - do_div(t, NSEC_PER_USEC); \ - do_div(t, USEC_PER_SEC); \ - }) - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int trace_fence_update_enabled_callback(void); -#else -void trace_fence_update_enabled_callback(void); -#endif -void trace_fence_update_disabled_callback(void); - -TRACE_EVENT_FN(rogue_fence_update, - - TP_PROTO(const char *comm, const char *cmd, const char *dm, u32 ctx_id, u32 offset, - u32 sync_fwaddr, u32 sync_value), - - TP_ARGS(comm, cmd, dm, ctx_id, offset, sync_fwaddr, sync_value), - - TP_STRUCT__entry( - __string( comm, comm ) - __string( cmd, cmd ) - __string( dm, dm ) - __field( u32, ctx_id ) - __field( u32, offset ) - __field( u32, sync_fwaddr ) - __field( u32, sync_value ) - ), - - TP_fast_assign( - __assign_str(comm, comm); - __assign_str(cmd, cmd); - __assign_str(dm, dm); - __entry->ctx_id = ctx_id; - __entry->offset = offset; - __entry->sync_fwaddr = sync_fwaddr; - __entry->sync_value = sync_value; - ), - - TP_printk("comm=%s cmd=%s dm=%s ctx_id=%lu offset=%lu sync_fwaddr=%#lx sync_value=%#lx", - __get_str(comm), - __get_str(cmd), - __get_str(dm), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->offset, - (unsigned long)__entry->sync_fwaddr, - (unsigned long)__entry->sync_value), - - trace_fence_update_enabled_callback, - trace_fence_update_disabled_callback -); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int trace_fence_check_enabled_callback(void); -#else -void trace_fence_check_enabled_callback(void); -#endif -void trace_fence_check_disabled_callback(void); - -TRACE_EVENT_FN(rogue_fence_check, - - TP_PROTO(const char *comm, const char *cmd, const char *dm, u32 ctx_id, u32 offset, - u32 sync_fwaddr, u32 sync_value), - - TP_ARGS(comm, cmd, dm, ctx_id, offset, sync_fwaddr, sync_value), - - TP_STRUCT__entry( - __string( comm, comm ) - __string( cmd, cmd ) - __string( dm, dm ) - __field( u32, ctx_id ) - __field( u32, offset ) - __field( u32, sync_fwaddr ) - __field( u32, sync_value ) - ), - - TP_fast_assign( - __assign_str(comm, comm); - __assign_str(cmd, cmd); - __assign_str(dm, dm); - __entry->ctx_id = ctx_id; - __entry->offset = offset; - __entry->sync_fwaddr = sync_fwaddr; - __entry->sync_value = sync_value; - ), - - TP_printk("comm=%s cmd=%s dm=%s ctx_id=%lu offset=%lu sync_fwaddr=%#lx sync_value=%#lx", - __get_str(comm), - __get_str(cmd), - __get_str(dm), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->offset, - (unsigned long)__entry->sync_fwaddr, - (unsigned long)__entry->sync_value), - - trace_fence_check_enabled_callback, - trace_fence_check_disabled_callback -); - -TRACE_EVENT(rogue_job_enqueue, - - TP_PROTO(u32 ctx_id, u32 int_id, u32 ext_id, - const char *kick_type), - - TP_ARGS(ctx_id, int_id, ext_id, kick_type), - - TP_STRUCT__entry( - __field(u32, ctx_id) - __field(u32, int_id) - __field(u32, ext_id) - __string(kick_type, kick_type) - ), - - TP_fast_assign( - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __assign_str(kick_type, kick_type); - ), - - TP_printk("ctx_id=%lu int_id=%lu ext_id=%lu kick_type=%s", - (unsigned long) __entry->ctx_id, - (unsigned long) __entry->int_id, - (unsigned long) __entry->ext_id, - __get_str(kick_type) - ) -); - -TRACE_EVENT(rogue_sched_switch, - - TP_PROTO(const char *work_type, u32 switch_type, u64 timestamp, u32 next_ctx_id, - u32 next_prio, u32 next_int_id, u32 next_ext_id), - - TP_ARGS(work_type, switch_type, timestamp, next_ctx_id, next_prio, next_int_id, next_ext_id), - - TP_STRUCT__entry( - __string(work_type, work_type) - __field(u32, switch_type) - __field(u64, timestamp) - __field(u32, next_ctx_id) - __field(u32, next_prio) - __field(u32, next_int_id) - __field(u32, next_ext_id) - ), - - TP_fast_assign( - __assign_str(work_type, work_type); - __entry->switch_type = switch_type; - __entry->timestamp = timestamp; - __entry->next_ctx_id = next_ctx_id; - __entry->next_prio = next_prio; - __entry->next_int_id = next_int_id; - __entry->next_ext_id = next_ext_id; - ), - - TP_printk("ts=%llu.%06lu next_ctx_id=%lu next_int_id=%lu next_ext_id=%lu" - " next_prio=%lu work_type=%s switch_type=%s", - (unsigned long long) show_secs_from_ns(__entry->timestamp), - (unsigned long) show_usecs_from_ns(__entry->timestamp), - (unsigned long) __entry->next_ctx_id, - (unsigned long) __entry->next_int_id, - (unsigned long) __entry->next_ext_id, - (unsigned long) __entry->next_prio, - __get_str(work_type), - __print_symbolic(__entry->switch_type, - /* These values are from ospvr_gputrace.h. */ - { 1, "begin" }, - { 2, "end" }) - ) -); - -TRACE_EVENT(rogue_create_fw_context, - - TP_PROTO(const char *comm, const char *dm, u32 ctx_id), - - TP_ARGS(comm, dm, ctx_id), - - TP_STRUCT__entry( - __string( comm, comm ) - __string( dm, dm ) - __field( u32, ctx_id ) - ), - - TP_fast_assign( - __assign_str(comm, comm); - __assign_str(dm, dm); - __entry->ctx_id = ctx_id; - ), - - TP_printk("comm=%s dm=%s ctx_id=%lu", - __get_str(comm), - __get_str(dm), - (unsigned long)__entry->ctx_id) -); - -void PVRGpuTraceEnableUfoCallback(void); -void PVRGpuTraceDisableUfoCallback(void); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int PVRGpuTraceEnableUfoCallbackWrapper(void); -#else -#define PVRGpuTraceEnableUfoCallbackWrapper \ - PVRGpuTraceEnableUfoCallback -#endif - -TRACE_EVENT_FN(rogue_ufo_update, - - TP_PROTO(u64 timestamp, u32 ctx_id, u32 int_id, u32 ext_id, - u32 fwaddr, u32 old_value, u32 new_value), - - TP_ARGS(timestamp, ctx_id, int_id, ext_id, fwaddr, old_value, - new_value), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __field( u32, ctx_id ) - __field( u32, int_id ) - __field( u32, ext_id ) - __field( u32, fwaddr ) - __field( u32, old_value ) - __field( u32, new_value ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __entry->fwaddr = fwaddr; - __entry->old_value = old_value; - __entry->new_value = new_value; - ), - - TP_printk("ts=%llu.%06lu ctx_id=%lu int_id=%lu ext_id=%lu" - " fwaddr=%#lx old_value=%#lx new_value=%#lx", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->int_id, - (unsigned long)__entry->ext_id, - (unsigned long)__entry->fwaddr, - (unsigned long)__entry->old_value, - (unsigned long)__entry->new_value), - PVRGpuTraceEnableUfoCallbackWrapper, - PVRGpuTraceDisableUfoCallback -); - -TRACE_EVENT_FN(rogue_ufo_check_fail, - - TP_PROTO(u64 timestamp, u32 ctx_id, u32 int_id, u32 ext_id, - u32 fwaddr, u32 value, u32 required), - - TP_ARGS(timestamp, ctx_id, int_id, ext_id, fwaddr, value, required), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __field( u32, ctx_id ) - __field( u32, int_id ) - __field( u32, ext_id ) - __field( u32, fwaddr ) - __field( u32, value ) - __field( u32, required ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __entry->fwaddr = fwaddr; - __entry->value = value; - __entry->required = required; - ), - - TP_printk("ts=%llu.%06lu ctx_id=%lu int_id=%lu ext_id=%lu" - " fwaddr=%#lx value=%#lx required=%#lx", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->int_id, - (unsigned long)__entry->ext_id, - (unsigned long)__entry->fwaddr, - (unsigned long)__entry->value, - (unsigned long)__entry->required), - PVRGpuTraceEnableUfoCallbackWrapper, - PVRGpuTraceDisableUfoCallback -); - -TRACE_EVENT_FN(rogue_ufo_pr_check_fail, - - TP_PROTO(u64 timestamp, u32 ctx_id, u32 int_id, u32 ext_id, - u32 fwaddr, u32 value, u32 required), - - TP_ARGS(timestamp, ctx_id, int_id, ext_id, fwaddr, value, required), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __field( u32, ctx_id ) - __field( u32, int_id ) - __field( u32, ext_id ) - __field( u32, fwaddr ) - __field( u32, value ) - __field( u32, required ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __entry->fwaddr = fwaddr; - __entry->value = value; - __entry->required = required; - ), - - TP_printk("ts=%llu.%06lu ctx_id=%lu int_id=%lu ext_id=%lu" - " fwaddr=%#lx value=%#lx required=%#lx", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->int_id, - (unsigned long)__entry->ext_id, - (unsigned long)__entry->fwaddr, - (unsigned long)__entry->value, - (unsigned long)__entry->required), - PVRGpuTraceEnableUfoCallbackWrapper, - PVRGpuTraceDisableUfoCallback -); - -TRACE_EVENT_FN(rogue_ufo_check_success, - - TP_PROTO(u64 timestamp, u32 ctx_id, u32 int_id, u32 ext_id, - u32 fwaddr, u32 value), - - TP_ARGS(timestamp, ctx_id, int_id, ext_id, fwaddr, value), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __field( u32, ctx_id ) - __field( u32, int_id ) - __field( u32, ext_id ) - __field( u32, fwaddr ) - __field( u32, value ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __entry->fwaddr = fwaddr; - __entry->value = value; - ), - - TP_printk("ts=%llu.%06lu ctx_id=%lu int_id=%lu ext_id=%lu" - " fwaddr=%#lx value=%#lx", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->int_id, - (unsigned long)__entry->ext_id, - (unsigned long)__entry->fwaddr, - (unsigned long)__entry->value), - PVRGpuTraceEnableUfoCallbackWrapper, - PVRGpuTraceDisableUfoCallback -); - -TRACE_EVENT_FN(rogue_ufo_pr_check_success, - - TP_PROTO(u64 timestamp, u32 ctx_id, u32 int_id, u32 ext_id, - u32 fwaddr, u32 value), - - TP_ARGS(timestamp, ctx_id, int_id, ext_id, fwaddr, value), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __field( u32, ctx_id ) - __field( u32, int_id ) - __field( u32, ext_id ) - __field( u32, fwaddr ) - __field( u32, value ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __entry->ctx_id = ctx_id; - __entry->int_id = int_id; - __entry->ext_id = ext_id; - __entry->fwaddr = fwaddr; - __entry->value = value; - ), - - TP_printk("ts=%llu.%06lu ctx_id=%lu int_id=%lu ext_id=%lu" - " fwaddr=%#lx value=%#lx", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - (unsigned long)__entry->ctx_id, - (unsigned long)__entry->int_id, - (unsigned long)__entry->ext_id, - (unsigned long)__entry->fwaddr, - (unsigned long)__entry->value), - PVRGpuTraceEnableUfoCallbackWrapper, - PVRGpuTraceDisableUfoCallback -); - -TRACE_EVENT(rogue_events_lost, - - TP_PROTO(u32 event_source, u32 last_ordinal, u32 curr_ordinal), - - TP_ARGS(event_source, last_ordinal, curr_ordinal), - - TP_STRUCT__entry( - __field( u32, event_source ) - __field( u32, last_ordinal ) - __field( u32, curr_ordinal ) - ), - - TP_fast_assign( - __entry->event_source = event_source; - __entry->last_ordinal = last_ordinal; - __entry->curr_ordinal = curr_ordinal; - ), - - TP_printk("event_source=%s last_ordinal=%u curr_ordinal=%u", - __print_symbolic(__entry->event_source, {0, "GPU"}, {1, "Host"}), - __entry->last_ordinal, - __entry->curr_ordinal) -); - -void PVRGpuTraceEnableFirmwareActivityCallback(void); -void PVRGpuTraceDisableFirmwareActivityCallback(void); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int PVRGpuTraceEnableFirmwareActivityCallbackWrapper(void); -#else -#define PVRGpuTraceEnableFirmwareActivityCallbackWrapper \ - PVRGpuTraceEnableFirmwareActivityCallback -#endif - -TRACE_EVENT_FN(rogue_firmware_activity, - - TP_PROTO(u64 timestamp, const char *task, u32 fw_event), - - TP_ARGS(timestamp, task, fw_event), - - TP_STRUCT__entry( - __field( u64, timestamp ) - __string( task, task ) - __field( u32, fw_event ) - ), - - TP_fast_assign( - __entry->timestamp = timestamp; - __assign_str(task, task); - __entry->fw_event = fw_event; - ), - - TP_printk("ts=%llu.%06lu task=%s event=%s", - (unsigned long long)show_secs_from_ns(__entry->timestamp), - (unsigned long)show_usecs_from_ns(__entry->timestamp), - __get_str(task), - __print_symbolic(__entry->fw_event, - /* These values are from ospvr_gputrace.h. */ - { 1, "begin" }, - { 2, "end" })), - - PVRGpuTraceEnableFirmwareActivityCallbackWrapper, - PVRGpuTraceDisableFirmwareActivityCallback -); - -#undef show_secs_from_ns -#undef show_usecs_from_ns - -#endif /* ROGUE_TRACE_EVENTS_H */ - -#undef TRACE_INCLUDE_PATH -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_PATH . - -/* This is needed because the name of this file doesn't match TRACE_SYSTEM. */ -#define TRACE_INCLUDE_FILE rogue_trace_events - -/* This part must be outside protection */ -#include diff --git a/drivers/gpu/drm/img-rogue/1.17/server_cache_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_cache_bridge.c deleted file mode 100644 index 762116a2b2158..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_cache_bridge.c +++ /dev/null @@ -1,460 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for cache -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for cache -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "cache_km.h" - -#include "common_cache_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static_assert(CACHE_BATCH_MAX <= IMG_UINT32_MAX, - "CACHE_BATCH_MAX must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeCacheOpQueue(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psCacheOpQueueIN_UI8, - IMG_UINT8 * psCacheOpQueueOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CACHEOPQUEUE *psCacheOpQueueIN = - (PVRSRV_BRIDGE_IN_CACHEOPQUEUE *) IMG_OFFSET_ADDR(psCacheOpQueueIN_UI8, 0); - PVRSRV_BRIDGE_OUT_CACHEOPQUEUE *psCacheOpQueueOUT = - (PVRSRV_BRIDGE_OUT_CACHEOPQUEUE *) IMG_OFFSET_ADDR(psCacheOpQueueOUT_UI8, 0); - - PMR **psPMRInt = NULL; - IMG_HANDLE *hPMRInt2 = NULL; - IMG_UINT64 *ui64AddressInt = NULL; - IMG_DEVMEM_OFFSET_T *uiOffsetInt = NULL; - IMG_DEVMEM_SIZE_T *uiSizeInt = NULL; - PVRSRV_CACHE_OP *iuCacheOpInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(PMR *)) + - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_UINT64)) + - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T)) + - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T)) + - ((IMG_UINT64) psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP)) + 0; - - if (unlikely(psCacheOpQueueIN->ui32NumCacheOps > CACHE_BATCH_MAX)) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto CacheOpQueue_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto CacheOpQueue_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psCacheOpQueueIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psCacheOpQueueIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto CacheOpQueue_exit; - } - } - } - - if (psCacheOpQueueIN->ui32NumCacheOps != 0) - { - psPMRInt = (PMR **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psPMRInt, 0, psCacheOpQueueIN->ui32NumCacheOps * sizeof(PMR *)); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(PMR *); - hPMRInt2 = (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hPMRInt2, (const void __user *)psCacheOpQueueIN->phPMR, - psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto CacheOpQueue_exit; - } - } - if (psCacheOpQueueIN->ui32NumCacheOps != 0) - { - ui64AddressInt = (IMG_UINT64 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_UINT64); - } - - /* Copy the data over */ - if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_UINT64) > 0) - { - if (OSCopyFromUser - (NULL, ui64AddressInt, (const void __user *)psCacheOpQueueIN->pui64Address, - psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_UINT64)) != PVRSRV_OK) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto CacheOpQueue_exit; - } - } - if (psCacheOpQueueIN->ui32NumCacheOps != 0) - { - uiOffsetInt = - (IMG_DEVMEM_OFFSET_T *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T); - } - - /* Copy the data over */ - if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T) > 0) - { - if (OSCopyFromUser - (NULL, uiOffsetInt, (const void __user *)psCacheOpQueueIN->puiOffset, - psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T)) != PVRSRV_OK) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto CacheOpQueue_exit; - } - } - if (psCacheOpQueueIN->ui32NumCacheOps != 0) - { - uiSizeInt = (IMG_DEVMEM_SIZE_T *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T); - } - - /* Copy the data over */ - if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T) > 0) - { - if (OSCopyFromUser - (NULL, uiSizeInt, (const void __user *)psCacheOpQueueIN->puiSize, - psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T)) != PVRSRV_OK) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto CacheOpQueue_exit; - } - } - if (psCacheOpQueueIN->ui32NumCacheOps != 0) - { - iuCacheOpInt = - (PVRSRV_CACHE_OP *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP); - } - - /* Copy the data over */ - if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP) > 0) - { - if (OSCopyFromUser - (NULL, iuCacheOpInt, (const void __user *)psCacheOpQueueIN->piuCacheOp, - psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP)) != PVRSRV_OK) - { - psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto CacheOpQueue_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - { - IMG_UINT32 i; - - for (i = 0; i < psCacheOpQueueIN->ui32NumCacheOps; i++) - { - /* Look up the address from the handle */ - psCacheOpQueueOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt[i], - hPMRInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psCacheOpQueueOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto CacheOpQueue_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psCacheOpQueueOUT->eError = - CacheOpQueue(psConnection, OSGetDevNode(psConnection), - psCacheOpQueueIN->ui32NumCacheOps, - psPMRInt, - ui64AddressInt, - uiOffsetInt, uiSizeInt, iuCacheOpInt, psCacheOpQueueIN->ui32OpTimeline); - -CacheOpQueue_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - if (hPMRInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psCacheOpQueueIN->ui32NumCacheOps; i++) - { - - /* Unreference the previously looked up handle */ - if (psPMRInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMRInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psCacheOpQueueOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeCacheOpExec(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psCacheOpExecIN_UI8, - IMG_UINT8 * psCacheOpExecOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CACHEOPEXEC *psCacheOpExecIN = - (PVRSRV_BRIDGE_IN_CACHEOPEXEC *) IMG_OFFSET_ADDR(psCacheOpExecIN_UI8, 0); - PVRSRV_BRIDGE_OUT_CACHEOPEXEC *psCacheOpExecOUT = - (PVRSRV_BRIDGE_OUT_CACHEOPEXEC *) IMG_OFFSET_ADDR(psCacheOpExecOUT_UI8, 0); - - IMG_HANDLE hPMR = psCacheOpExecIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psCacheOpExecOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psCacheOpExecOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto CacheOpExec_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psCacheOpExecOUT->eError = - CacheOpValExec(psPMRInt, - psCacheOpExecIN->ui64Address, - psCacheOpExecIN->uiOffset, - psCacheOpExecIN->uiSize, psCacheOpExecIN->iuCacheOp); - -CacheOpExec_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeCacheOpLog(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psCacheOpLogIN_UI8, - IMG_UINT8 * psCacheOpLogOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CACHEOPLOG *psCacheOpLogIN = - (PVRSRV_BRIDGE_IN_CACHEOPLOG *) IMG_OFFSET_ADDR(psCacheOpLogIN_UI8, 0); - PVRSRV_BRIDGE_OUT_CACHEOPLOG *psCacheOpLogOUT = - (PVRSRV_BRIDGE_OUT_CACHEOPLOG *) IMG_OFFSET_ADDR(psCacheOpLogOUT_UI8, 0); - - IMG_HANDLE hPMR = psCacheOpLogIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psCacheOpLogOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psCacheOpLogOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto CacheOpLog_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psCacheOpLogOUT->eError = - CacheOpLog(psPMRInt, - psCacheOpLogIN->ui64Address, - psCacheOpLogIN->uiOffset, - psCacheOpLogIN->uiSize, - psCacheOpLogIN->i64StartTime, - psCacheOpLogIN->i64EndTime, psCacheOpLogIN->iuCacheOp); - -CacheOpLog_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitCACHEBridge(void); -void DeinitCACHEBridge(void); - -/* - * Register all CACHE functions with services - */ -PVRSRV_ERROR InitCACHEBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE, - PVRSRVBridgeCacheOpQueue, NULL, sizeof(PVRSRV_BRIDGE_IN_CACHEOPQUEUE), - sizeof(PVRSRV_BRIDGE_OUT_CACHEOPQUEUE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPEXEC, - PVRSRVBridgeCacheOpExec, NULL, sizeof(PVRSRV_BRIDGE_IN_CACHEOPEXEC), - sizeof(PVRSRV_BRIDGE_OUT_CACHEOPEXEC)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPLOG, - PVRSRVBridgeCacheOpLog, NULL, sizeof(PVRSRV_BRIDGE_IN_CACHEOPLOG), - sizeof(PVRSRV_BRIDGE_OUT_CACHEOPLOG)); - - return PVRSRV_OK; -} - -/* - * Unregister all cache functions with services - */ -void DeinitCACHEBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPEXEC); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPLOG); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_cmm_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_cmm_bridge.c deleted file mode 100644 index cc658c793d3b8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_cmm_bridge.c +++ /dev/null @@ -1,414 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for cmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for cmm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "pmr.h" -#include "devicemem_server.h" - -#include "common_cmm_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#if !defined(EXCLUDE_CMM_BRIDGE) - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _DevmemIntExportCtxpsContextExportIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntUnexportCtx((DEVMEMINT_CTX_EXPORT *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntExportCtx(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntExportCtxIN_UI8, - IMG_UINT8 * psDevmemIntExportCtxOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX *psDevmemIntExportCtxIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX *) IMG_OFFSET_ADDR(psDevmemIntExportCtxIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX *psDevmemIntExportCtxOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX *) IMG_OFFSET_ADDR(psDevmemIntExportCtxOUT_UI8, - 0); - - IMG_HANDLE hContext = psDevmemIntExportCtxIN->hContext; - DEVMEMINT_CTX *psContextInt = NULL; - IMG_HANDLE hPMR = psDevmemIntExportCtxIN->hPMR; - PMR *psPMRInt = NULL; - DEVMEMINT_CTX_EXPORT *psContextExportInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntExportCtxOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psContextInt, - hContext, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntExportCtx_exit; - } - - /* Look up the address from the handle */ - psDevmemIntExportCtxOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntExportCtx_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntExportCtxOUT->eError = - DevmemIntExportCtx(psContextInt, psPMRInt, &psContextExportInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)) - { - goto DevmemIntExportCtx_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntExportCtxOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntExportCtxOUT-> - hContextExport, - (void *)psContextExportInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - (PFN_HANDLE_RELEASE) & - _DevmemIntExportCtxpsContextExportIntRelease); - if (unlikely(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntExportCtx_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntExportCtx_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hContext, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntExportCtxOUT->eError != PVRSRV_OK) - { - if (psContextExportInt) - { - LockHandle(KERNEL_HANDLE_BASE); - DevmemIntUnexportCtx(psContextExportInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnexportCtx(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnexportCtxIN_UI8, - IMG_UINT8 * psDevmemIntUnexportCtxOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX *psDevmemIntUnexportCtxIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX *) IMG_OFFSET_ADDR(psDevmemIntUnexportCtxIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX *psDevmemIntUnexportCtxOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX *) - IMG_OFFSET_ADDR(psDevmemIntUnexportCtxOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntUnexportCtxOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntUnexportCtxIN->hContextExport, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT); - if (unlikely((psDevmemIntUnexportCtxOUT->eError != PVRSRV_OK) && - (psDevmemIntUnexportCtxOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psDevmemIntUnexportCtxOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemIntUnexportCtxOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnexportCtx_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntUnexportCtx_exit: - - return 0; -} - -static PVRSRV_ERROR _DevmemIntAcquireRemoteCtxpsContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntCtxDestroy((DEVMEMINT_CTX *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntAcquireRemoteCtx(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntAcquireRemoteCtxIN_UI8, - IMG_UINT8 * psDevmemIntAcquireRemoteCtxOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX *psDevmemIntAcquireRemoteCtxIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX *) - IMG_OFFSET_ADDR(psDevmemIntAcquireRemoteCtxIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX *psDevmemIntAcquireRemoteCtxOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX *) - IMG_OFFSET_ADDR(psDevmemIntAcquireRemoteCtxOUT_UI8, 0); - - IMG_HANDLE hPMR = psDevmemIntAcquireRemoteCtxIN->hPMR; - PMR *psPMRInt = NULL; - DEVMEMINT_CTX *psContextInt = NULL; - IMG_HANDLE hPrivDataInt = NULL; - - psDevmemIntAcquireRemoteCtxOUT->hContext = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntAcquireRemoteCtxOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntAcquireRemoteCtx_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntAcquireRemoteCtxOUT->eError = - DevmemIntAcquireRemoteCtx(psPMRInt, &psContextInt, &hPrivDataInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)) - { - goto DevmemIntAcquireRemoteCtx_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntAcquireRemoteCtxOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntAcquireRemoteCtxOUT->hContext, - (void *)psContextInt, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - (PFN_HANDLE_RELEASE) & - _DevmemIntAcquireRemoteCtxpsContextIntRelease); - if (unlikely(psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntAcquireRemoteCtx_exit; - } - - psDevmemIntAcquireRemoteCtxOUT->eError = - PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntAcquireRemoteCtxOUT->hPrivData, - (void *)hPrivDataInt, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - psDevmemIntAcquireRemoteCtxOUT->hContext); - if (unlikely(psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntAcquireRemoteCtx_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntAcquireRemoteCtx_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK) - { - if (psDevmemIntAcquireRemoteCtxOUT->hContext) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) - psDevmemIntAcquireRemoteCtxOUT-> - hContext, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psContextInt) - { - DevmemIntCtxDestroy(psContextInt); - } - - } - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -#endif /* EXCLUDE_CMM_BRIDGE */ - -#if !defined(EXCLUDE_CMM_BRIDGE) -PVRSRV_ERROR InitCMMBridge(void); -void DeinitCMMBridge(void); - -/* - * Register all CMM functions with services - */ -PVRSRV_ERROR InitCMMBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTEXPORTCTX, - PVRSRVBridgeDevmemIntExportCtx, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTUNEXPORTCTX, - PVRSRVBridgeDevmemIntUnexportCtx, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTACQUIREREMOTECTX, - PVRSRVBridgeDevmemIntAcquireRemoteCtx, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX)); - - return PVRSRV_OK; -} - -/* - * Unregister all cmm functions with services - */ -void DeinitCMMBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTEXPORTCTX); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTUNEXPORTCTX); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTACQUIREREMOTECTX); - -} -#else /* EXCLUDE_CMM_BRIDGE */ -/* This bridge is conditional on EXCLUDE_CMM_BRIDGE - when defined, - * do not populate the dispatch table with its functions - */ -#define InitCMMBridge() \ - PVRSRV_OK - -#define DeinitCMMBridge() - -#endif /* EXCLUDE_CMM_BRIDGE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/server_devicememhistory_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_devicememhistory_bridge.c deleted file mode 100644 index 6f33ca49bb7fd..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_devicememhistory_bridge.c +++ /dev/null @@ -1,874 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for devicememhistory -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for devicememhistory -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "pmr.h" -#include "devicemem_history_server.h" - -#include "common_devicememhistory_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#include "lock.h" - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevicememHistoryMap(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevicememHistoryMapIN_UI8, - IMG_UINT8 * psDevicememHistoryMapOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *psDevicememHistoryMapIN = - (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *) IMG_OFFSET_ADDR(psDevicememHistoryMapIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *psDevicememHistoryMapOUT = - (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *) IMG_OFFSET_ADDR(psDevicememHistoryMapOUT_UI8, - 0); - - IMG_HANDLE hPMR = psDevicememHistoryMapIN->hPMR; - PMR *psPMRInt = NULL; - IMG_CHAR *uiTextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevicememHistoryMap_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevicememHistoryMapIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryMapIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevicememHistoryMap_exit; - } - } - } - - { - uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextInt, (const void __user *)psDevicememHistoryMapIN->puiText, - DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistoryMap_exit; - } - ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevicememHistoryMapOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevicememHistoryMapOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevicememHistoryMap_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevicememHistoryMapOUT->eError = - DevicememHistoryMapKM(psPMRInt, - psDevicememHistoryMapIN->uiOffset, - psDevicememHistoryMapIN->sDevVAddr, - psDevicememHistoryMapIN->uiSize, - uiTextInt, - psDevicememHistoryMapIN->ui32Log2PageSize, - psDevicememHistoryMapIN->ui32AllocationIndex, - &psDevicememHistoryMapOUT->ui32AllocationIndexOut); - -DevicememHistoryMap_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevicememHistoryMapOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevicememHistoryUnmap(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevicememHistoryUnmapIN_UI8, - IMG_UINT8 * psDevicememHistoryUnmapOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapIN = - (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *) - IMG_OFFSET_ADDR(psDevicememHistoryUnmapIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapOUT = - (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *) - IMG_OFFSET_ADDR(psDevicememHistoryUnmapOUT_UI8, 0); - - IMG_HANDLE hPMR = psDevicememHistoryUnmapIN->hPMR; - PMR *psPMRInt = NULL; - IMG_CHAR *uiTextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevicememHistoryUnmap_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevicememHistoryUnmapIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryUnmapIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevicememHistoryUnmap_exit; - } - } - } - - { - uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextInt, (const void __user *)psDevicememHistoryUnmapIN->puiText, - DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistoryUnmap_exit; - } - ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevicememHistoryUnmapOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevicememHistoryUnmapOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevicememHistoryUnmap_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevicememHistoryUnmapOUT->eError = - DevicememHistoryUnmapKM(psPMRInt, - psDevicememHistoryUnmapIN->uiOffset, - psDevicememHistoryUnmapIN->sDevVAddr, - psDevicememHistoryUnmapIN->uiSize, - uiTextInt, - psDevicememHistoryUnmapIN->ui32Log2PageSize, - psDevicememHistoryUnmapIN->ui32AllocationIndex, - &psDevicememHistoryUnmapOUT->ui32AllocationIndexOut); - -DevicememHistoryUnmap_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevicememHistoryUnmapOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevicememHistoryMapVRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevicememHistoryMapVRangeIN_UI8, - IMG_UINT8 * psDevicememHistoryMapVRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeIN = - (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE *) - IMG_OFFSET_ADDR(psDevicememHistoryMapVRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE *) - IMG_OFFSET_ADDR(psDevicememHistoryMapVRangeOUT_UI8, 0); - - IMG_CHAR *uiTextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevicememHistoryMapVRange_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevicememHistoryMapVRangeIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryMapVRangeIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevicememHistoryMapVRange_exit; - } - } - } - - { - uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextInt, (const void __user *)psDevicememHistoryMapVRangeIN->puiText, - DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistoryMapVRange_exit; - } - ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - - psDevicememHistoryMapVRangeOUT->eError = - DevicememHistoryMapVRangeKM(psConnection, OSGetDevNode(psConnection), - psDevicememHistoryMapVRangeIN->sBaseDevVAddr, - psDevicememHistoryMapVRangeIN->ui32ui32StartPage, - psDevicememHistoryMapVRangeIN->ui32NumPages, - psDevicememHistoryMapVRangeIN->uiAllocSize, - uiTextInt, - psDevicememHistoryMapVRangeIN->ui32Log2PageSize, - psDevicememHistoryMapVRangeIN->ui32AllocationIndex, - &psDevicememHistoryMapVRangeOUT->ui32AllocationIndexOut); - -DevicememHistoryMapVRange_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevicememHistoryMapVRangeOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevicememHistoryUnmapVRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevicememHistoryUnmapVRangeIN_UI8, - IMG_UINT8 * psDevicememHistoryUnmapVRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeIN = - (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE *) - IMG_OFFSET_ADDR(psDevicememHistoryUnmapVRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE *) - IMG_OFFSET_ADDR(psDevicememHistoryUnmapVRangeOUT_UI8, 0); - - IMG_CHAR *uiTextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevicememHistoryUnmapVRange_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevicememHistoryUnmapVRangeIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psDevicememHistoryUnmapVRangeIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevicememHistoryUnmapVRangeOUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevicememHistoryUnmapVRange_exit; - } - } - } - - { - uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextInt, (const void __user *)psDevicememHistoryUnmapVRangeIN->puiText, - DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistoryUnmapVRange_exit; - } - ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - - psDevicememHistoryUnmapVRangeOUT->eError = - DevicememHistoryUnmapVRangeKM(psConnection, OSGetDevNode(psConnection), - psDevicememHistoryUnmapVRangeIN->sBaseDevVAddr, - psDevicememHistoryUnmapVRangeIN->ui32ui32StartPage, - psDevicememHistoryUnmapVRangeIN->ui32NumPages, - psDevicememHistoryUnmapVRangeIN->uiAllocSize, - uiTextInt, - psDevicememHistoryUnmapVRangeIN->ui32Log2PageSize, - psDevicememHistoryUnmapVRangeIN->ui32AllocationIndex, - &psDevicememHistoryUnmapVRangeOUT-> - ui32AllocationIndexOut); - -DevicememHistoryUnmapVRange_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevicememHistoryUnmapVRangeOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevicememHistorySparseChange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevicememHistorySparseChangeIN_UI8, - IMG_UINT8 * psDevicememHistorySparseChangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeIN = - (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE *) - IMG_OFFSET_ADDR(psDevicememHistorySparseChangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeOUT = - (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE *) - IMG_OFFSET_ADDR(psDevicememHistorySparseChangeOUT_UI8, 0); - - IMG_HANDLE hPMR = psDevicememHistorySparseChangeIN->hPMR; - PMR *psPMRInt = NULL; - IMG_CHAR *uiTextInt = NULL; - IMG_UINT32 *ui32AllocPageIndicesInt = NULL; - IMG_UINT32 *ui32FreePageIndicesInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psDevicememHistorySparseChangeIN->ui32AllocPageCount * - sizeof(IMG_UINT32)) + - ((IMG_UINT64) psDevicememHistorySparseChangeIN->ui32FreePageCount * - sizeof(IMG_UINT32)) + 0; - - if (unlikely - (psDevicememHistorySparseChangeIN->ui32AllocPageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto DevicememHistorySparseChange_exit; - } - - if (unlikely - (psDevicememHistorySparseChangeIN->ui32FreePageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto DevicememHistorySparseChange_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevicememHistorySparseChange_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevicememHistorySparseChangeIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psDevicememHistorySparseChangeIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevicememHistorySparseChangeOUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevicememHistorySparseChange_exit; - } - } - } - - { - uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextInt, - (const void __user *)psDevicememHistorySparseChangeIN->puiText, - DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistorySparseChange_exit; - } - ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - if (psDevicememHistorySparseChangeIN->ui32AllocPageCount != 0) - { - ui32AllocPageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32AllocPageIndicesInt, - (const void __user *)psDevicememHistorySparseChangeIN->pui32AllocPageIndices, - psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistorySparseChange_exit; - } - } - if (psDevicememHistorySparseChangeIN->ui32FreePageCount != 0) - { - ui32FreePageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32FreePageIndicesInt, - (const void __user *)psDevicememHistorySparseChangeIN->pui32FreePageIndices, - psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevicememHistorySparseChange_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevicememHistorySparseChangeOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevicememHistorySparseChangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevicememHistorySparseChange_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevicememHistorySparseChangeOUT->eError = - DevicememHistorySparseChangeKM(psPMRInt, - psDevicememHistorySparseChangeIN->uiOffset, - psDevicememHistorySparseChangeIN->sDevVAddr, - psDevicememHistorySparseChangeIN->uiSize, - uiTextInt, - psDevicememHistorySparseChangeIN->ui32Log2PageSize, - psDevicememHistorySparseChangeIN->ui32AllocPageCount, - ui32AllocPageIndicesInt, - psDevicememHistorySparseChangeIN->ui32FreePageCount, - ui32FreePageIndicesInt, - psDevicememHistorySparseChangeIN->ui32AllocationIndex, - &psDevicememHistorySparseChangeOUT-> - ui32AllocationIndexOut); - -DevicememHistorySparseChange_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevicememHistorySparseChangeOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -static POS_LOCK pDEVICEMEMHISTORYBridgeLock; - -PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void); -void DeinitDEVICEMEMHISTORYBridge(void); - -/* - * Register all DEVICEMEMHISTORY functions with services - */ -PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void) -{ - PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&pDEVICEMEMHISTORYBridgeLock), "OSLockCreate"); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP, - PVRSRVBridgeDevicememHistoryMap, pDEVICEMEMHISTORYBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP), - sizeof(PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP, - PVRSRVBridgeDevicememHistoryUnmap, pDEVICEMEMHISTORYBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP), - sizeof(PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE, - PVRSRVBridgeDevicememHistoryMapVRange, pDEVICEMEMHISTORYBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE, - PVRSRVBridgeDevicememHistoryUnmapVRange, pDEVICEMEMHISTORYBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE, - PVRSRVBridgeDevicememHistorySparseChange, pDEVICEMEMHISTORYBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE)); - - return PVRSRV_OK; -} - -/* - * Unregister all devicememhistory functions with services - */ -void DeinitDEVICEMEMHISTORYBridge(void) -{ - OSLockDestroy(pDEVICEMEMHISTORYBridgeLock); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, - PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_di_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_di_bridge.c deleted file mode 100644 index 360dc5809a59a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_di_bridge.c +++ /dev/null @@ -1,676 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for di -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for di -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "di_impl_brg.h" - -#include "common_di_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _DICreateContextpsContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DIDestroyContextKM((DI_CONTEXT *) pvData); - return eError; -} - -static_assert(PRVSRVTL_MAX_STREAM_NAME_SIZE <= IMG_UINT32_MAX, - "PRVSRVTL_MAX_STREAM_NAME_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDICreateContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDICreateContextIN_UI8, - IMG_UINT8 * psDICreateContextOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DICREATECONTEXT *psDICreateContextIN = - (PVRSRV_BRIDGE_IN_DICREATECONTEXT *) IMG_OFFSET_ADDR(psDICreateContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DICREATECONTEXT *psDICreateContextOUT = - (PVRSRV_BRIDGE_OUT_DICREATECONTEXT *) IMG_OFFSET_ADDR(psDICreateContextOUT_UI8, 0); - - IMG_CHAR *puiStreamNameInt = NULL; - DI_CONTEXT *psContextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) + 0; - - PVR_UNREFERENCED_PARAMETER(psDICreateContextIN); - - psDICreateContextOUT->puiStreamName = psDICreateContextIN->puiStreamName; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDICreateContextOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DICreateContext_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDICreateContextIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDICreateContextIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDICreateContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DICreateContext_exit; - } - } - } - - if (IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset) != NULL) - { - puiStreamNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR); - } - - psDICreateContextOUT->eError = DICreateContextKM(puiStreamNameInt, &psContextInt); - /* Exit early if bridged call fails */ - if (unlikely(psDICreateContextOUT->eError != PVRSRV_OK)) - { - goto DICreateContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDICreateContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDICreateContextOUT->hContext, - (void *)psContextInt, - PVRSRV_HANDLE_TYPE_DI_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - (PFN_HANDLE_RELEASE) & - _DICreateContextpsContextIntRelease); - if (unlikely(psDICreateContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DICreateContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* If dest ptr is non-null and we have data to copy */ - if ((puiStreamNameInt) && ((PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psDICreateContextOUT->puiStreamName, puiStreamNameInt, - (PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR))) != PVRSRV_OK)) - { - psDICreateContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DICreateContext_exit; - } - } - -DICreateContext_exit: - - if (psDICreateContextOUT->eError != PVRSRV_OK) - { - if (psDICreateContextOUT->hContext) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDICreateContextOUT-> - hContext, - PVRSRV_HANDLE_TYPE_DI_CONTEXT); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psContextInt) - { - DIDestroyContextKM(psContextInt); - } - - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDICreateContextOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDIDestroyContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDIDestroyContextIN_UI8, - IMG_UINT8 * psDIDestroyContextOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT *psDIDestroyContextIN = - (PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT *) IMG_OFFSET_ADDR(psDIDestroyContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT *psDIDestroyContextOUT = - (PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT *) IMG_OFFSET_ADDR(psDIDestroyContextOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDIDestroyContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDIDestroyContextIN->hContext, - PVRSRV_HANDLE_TYPE_DI_CONTEXT); - if (unlikely((psDIDestroyContextOUT->eError != PVRSRV_OK) && - (psDIDestroyContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psDIDestroyContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psDIDestroyContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DIDestroyContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DIDestroyContext_exit: - - return 0; -} - -static_assert(DI_IMPL_BRG_PATH_LEN <= IMG_UINT32_MAX, - "DI_IMPL_BRG_PATH_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDIReadEntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDIReadEntryIN_UI8, - IMG_UINT8 * psDIReadEntryOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DIREADENTRY *psDIReadEntryIN = - (PVRSRV_BRIDGE_IN_DIREADENTRY *) IMG_OFFSET_ADDR(psDIReadEntryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DIREADENTRY *psDIReadEntryOUT = - (PVRSRV_BRIDGE_OUT_DIREADENTRY *) IMG_OFFSET_ADDR(psDIReadEntryOUT_UI8, 0); - - IMG_HANDLE hContext = psDIReadEntryIN->hContext; - DI_CONTEXT *psContextInt = NULL; - IMG_CHAR *uiEntryPathInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) + 0; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDIReadEntryOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DIReadEntry_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDIReadEntryIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDIReadEntryIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDIReadEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DIReadEntry_exit; - } - } - } - - { - uiEntryPathInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiEntryPathInt, (const void __user *)psDIReadEntryIN->puiEntryPath, - DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDIReadEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DIReadEntry_exit; - } - ((IMG_CHAR *) uiEntryPathInt)[(DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDIReadEntryOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psContextInt, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT, IMG_TRUE); - if (unlikely(psDIReadEntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DIReadEntry_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDIReadEntryOUT->eError = - DIReadEntryKM(psContextInt, - uiEntryPathInt, psDIReadEntryIN->ui64Offset, psDIReadEntryIN->ui64Size); - -DIReadEntry_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDIReadEntryOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DI_IMPL_BRG_PATH_LEN <= IMG_UINT32_MAX, - "DI_IMPL_BRG_PATH_LEN must not be larger than IMG_UINT32_MAX"); -static_assert(DI_IMPL_BRG_PATH_LEN <= IMG_UINT32_MAX, - "DI_IMPL_BRG_PATH_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDIWriteEntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDIWriteEntryIN_UI8, - IMG_UINT8 * psDIWriteEntryOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DIWRITEENTRY *psDIWriteEntryIN = - (PVRSRV_BRIDGE_IN_DIWRITEENTRY *) IMG_OFFSET_ADDR(psDIWriteEntryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DIWRITEENTRY *psDIWriteEntryOUT = - (PVRSRV_BRIDGE_OUT_DIWRITEENTRY *) IMG_OFFSET_ADDR(psDIWriteEntryOUT_UI8, 0); - - IMG_HANDLE hContext = psDIWriteEntryIN->hContext; - DI_CONTEXT *psContextInt = NULL; - IMG_CHAR *uiEntryPathInt = NULL; - IMG_CHAR *uiValueInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psDIWriteEntryIN->ui32ValueSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psDIWriteEntryIN->ui32ValueSize > DI_IMPL_BRG_PATH_LEN)) - { - psDIWriteEntryOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto DIWriteEntry_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDIWriteEntryOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DIWriteEntry_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDIWriteEntryIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDIWriteEntryIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDIWriteEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto DIWriteEntry_exit; - } - } - } - - { - uiEntryPathInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiEntryPathInt, (const void __user *)psDIWriteEntryIN->puiEntryPath, - DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDIWriteEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DIWriteEntry_exit; - } - ((IMG_CHAR *) uiEntryPathInt)[(DI_IMPL_BRG_PATH_LEN * sizeof(IMG_CHAR)) - 1] = '\0'; - } - if (psDIWriteEntryIN->ui32ValueSize != 0) - { - uiValueInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psDIWriteEntryIN->ui32ValueSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psDIWriteEntryIN->ui32ValueSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiValueInt, (const void __user *)psDIWriteEntryIN->puiValue, - psDIWriteEntryIN->ui32ValueSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psDIWriteEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DIWriteEntry_exit; - } - ((IMG_CHAR *) uiValueInt)[(psDIWriteEntryIN->ui32ValueSize * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDIWriteEntryOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psContextInt, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT, IMG_TRUE); - if (unlikely(psDIWriteEntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DIWriteEntry_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDIWriteEntryOUT->eError = - DIWriteEntryKM(psContextInt, - uiEntryPathInt, psDIWriteEntryIN->ui32ValueSize, uiValueInt); - -DIWriteEntry_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDIWriteEntryOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDIListAllEntries(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDIListAllEntriesIN_UI8, - IMG_UINT8 * psDIListAllEntriesOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DILISTALLENTRIES *psDIListAllEntriesIN = - (PVRSRV_BRIDGE_IN_DILISTALLENTRIES *) IMG_OFFSET_ADDR(psDIListAllEntriesIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DILISTALLENTRIES *psDIListAllEntriesOUT = - (PVRSRV_BRIDGE_OUT_DILISTALLENTRIES *) IMG_OFFSET_ADDR(psDIListAllEntriesOUT_UI8, 0); - - IMG_HANDLE hContext = psDIListAllEntriesIN->hContext; - DI_CONTEXT *psContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDIListAllEntriesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psContextInt, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT, IMG_TRUE); - if (unlikely(psDIListAllEntriesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DIListAllEntries_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDIListAllEntriesOUT->eError = DIListAllEntriesKM(psContextInt); - -DIListAllEntries_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hContext, PVRSRV_HANDLE_TYPE_DI_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitDIBridge(void); -void DeinitDIBridge(void); - -/* - * Register all DI functions with services - */ -PVRSRV_ERROR InitDIBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DICREATECONTEXT, - PVRSRVBridgeDICreateContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_DICREATECONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_DICREATECONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIDESTROYCONTEXT, - PVRSRVBridgeDIDestroyContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIREADENTRY, - PVRSRVBridgeDIReadEntry, NULL, sizeof(PVRSRV_BRIDGE_IN_DIREADENTRY), - sizeof(PVRSRV_BRIDGE_OUT_DIREADENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIWRITEENTRY, - PVRSRVBridgeDIWriteEntry, NULL, sizeof(PVRSRV_BRIDGE_IN_DIWRITEENTRY), - sizeof(PVRSRV_BRIDGE_OUT_DIWRITEENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DILISTALLENTRIES, - PVRSRVBridgeDIListAllEntries, NULL, - sizeof(PVRSRV_BRIDGE_IN_DILISTALLENTRIES), - sizeof(PVRSRV_BRIDGE_OUT_DILISTALLENTRIES)); - - return PVRSRV_OK; -} - -/* - * Unregister all di functions with services - */ -void DeinitDIBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DICREATECONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIDESTROYCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIREADENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DIWRITEENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DI, PVRSRV_BRIDGE_DI_DILISTALLENTRIES); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_dmabuf_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_dmabuf_bridge.c deleted file mode 100644 index 2c69355188208..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_dmabuf_bridge.c +++ /dev/null @@ -1,702 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for dmabuf -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for dmabuf -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "physmem_dmabuf.h" -#include "pmr.h" - -#include "common_dmabuf_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _PhysmemImportDmaBufpsPMRPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefPMR((PMR *) pvData); - return eError; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysmemImportDmaBuf(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemImportDmaBufIN_UI8, - IMG_UINT8 * psPhysmemImportDmaBufOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF *psPhysmemImportDmaBufIN = - (PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF *) IMG_OFFSET_ADDR(psPhysmemImportDmaBufIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF *psPhysmemImportDmaBufOUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF *) IMG_OFFSET_ADDR(psPhysmemImportDmaBufOUT_UI8, - 0); - - IMG_CHAR *uiNameInt = NULL; - PMR *psPMRPtrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysmemImportDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPhysmemImportDmaBufIN->ui32NameSize > DEVMEM_ANNOTATION_MAX_LEN)) - { - psPhysmemImportDmaBufOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemImportDmaBuf_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysmemImportDmaBufOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysmemImportDmaBuf_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysmemImportDmaBufIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysmemImportDmaBufIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysmemImportDmaBufOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysmemImportDmaBuf_exit; - } - } - } - - if (psPhysmemImportDmaBufIN->ui32NameSize != 0) - { - uiNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPhysmemImportDmaBufIN->ui32NameSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPhysmemImportDmaBufIN->ui32NameSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiNameInt, (const void __user *)psPhysmemImportDmaBufIN->puiName, - psPhysmemImportDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPhysmemImportDmaBufOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemImportDmaBuf_exit; - } - ((IMG_CHAR *) uiNameInt)[(psPhysmemImportDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - - psPhysmemImportDmaBufOUT->eError = - PhysmemImportDmaBuf(psConnection, OSGetDevNode(psConnection), - psPhysmemImportDmaBufIN->ifd, - psPhysmemImportDmaBufIN->uiFlags, - psPhysmemImportDmaBufIN->ui32NameSize, - uiNameInt, - &psPMRPtrInt, - &psPhysmemImportDmaBufOUT->uiSize, - &psPhysmemImportDmaBufOUT->uiAlign); - /* Exit early if bridged call fails */ - if (unlikely(psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)) - { - goto PhysmemImportDmaBuf_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPhysmemImportDmaBufOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPhysmemImportDmaBufOUT-> - hPMRPtr, (void *)psPMRPtrInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PhysmemImportDmaBufpsPMRPtrIntRelease); - if (unlikely(psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemImportDmaBuf_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PhysmemImportDmaBuf_exit: - - if (psPhysmemImportDmaBufOUT->eError != PVRSRV_OK) - { - if (psPMRPtrInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefPMR(psPMRPtrInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysmemImportDmaBufOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _PhysmemImportDmaBufLockedpsPMRPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefUnlockPMR((PMR *) pvData); - return eError; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysmemImportDmaBufLocked(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemImportDmaBufLockedIN_UI8, - IMG_UINT8 * psPhysmemImportDmaBufLockedOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED *psPhysmemImportDmaBufLockedIN = - (PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED *) - IMG_OFFSET_ADDR(psPhysmemImportDmaBufLockedIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED *psPhysmemImportDmaBufLockedOUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED *) - IMG_OFFSET_ADDR(psPhysmemImportDmaBufLockedOUT_UI8, 0); - - IMG_CHAR *uiNameInt = NULL; - PMR *psPMRPtrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysmemImportDmaBufLockedIN->ui32NameSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPhysmemImportDmaBufLockedIN->ui32NameSize > DEVMEM_ANNOTATION_MAX_LEN)) - { - psPhysmemImportDmaBufLockedOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemImportDmaBufLocked_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysmemImportDmaBufLockedOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysmemImportDmaBufLocked_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysmemImportDmaBufLockedIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysmemImportDmaBufLockedIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysmemImportDmaBufLockedOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysmemImportDmaBufLocked_exit; - } - } - } - - if (psPhysmemImportDmaBufLockedIN->ui32NameSize != 0) - { - uiNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPhysmemImportDmaBufLockedIN->ui32NameSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPhysmemImportDmaBufLockedIN->ui32NameSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiNameInt, (const void __user *)psPhysmemImportDmaBufLockedIN->puiName, - psPhysmemImportDmaBufLockedIN->ui32NameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPhysmemImportDmaBufLockedOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemImportDmaBufLocked_exit; - } - ((IMG_CHAR *) - uiNameInt)[(psPhysmemImportDmaBufLockedIN->ui32NameSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psPhysmemImportDmaBufLockedOUT->eError = - PhysmemImportDmaBufLocked(psConnection, OSGetDevNode(psConnection), - psPhysmemImportDmaBufLockedIN->ifd, - psPhysmemImportDmaBufLockedIN->uiFlags, - psPhysmemImportDmaBufLockedIN->ui32NameSize, - uiNameInt, - &psPMRPtrInt, - &psPhysmemImportDmaBufLockedOUT->uiSize, - &psPhysmemImportDmaBufLockedOUT->uiAlign); - /* Exit early if bridged call fails */ - if (unlikely(psPhysmemImportDmaBufLockedOUT->eError != PVRSRV_OK)) - { - goto PhysmemImportDmaBufLocked_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPhysmemImportDmaBufLockedOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPhysmemImportDmaBufLockedOUT->hPMRPtr, (void *)psPMRPtrInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PhysmemImportDmaBufLockedpsPMRPtrIntRelease); - if (unlikely(psPhysmemImportDmaBufLockedOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemImportDmaBufLocked_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PhysmemImportDmaBufLocked_exit: - - if (psPhysmemImportDmaBufLockedOUT->eError != PVRSRV_OK) - { - if (psPMRPtrInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefUnlockPMR(psPMRPtrInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysmemImportDmaBufLockedOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgePhysmemExportDmaBuf(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemExportDmaBufIN_UI8, - IMG_UINT8 * psPhysmemExportDmaBufOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF *psPhysmemExportDmaBufIN = - (PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF *) IMG_OFFSET_ADDR(psPhysmemExportDmaBufIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF *psPhysmemExportDmaBufOUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF *) IMG_OFFSET_ADDR(psPhysmemExportDmaBufOUT_UI8, - 0); - - IMG_HANDLE hPMR = psPhysmemExportDmaBufIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPhysmemExportDmaBufOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPhysmemExportDmaBufOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemExportDmaBuf_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPhysmemExportDmaBufOUT->eError = - PhysmemExportDmaBuf(psConnection, OSGetDevNode(psConnection), - psPMRInt, &psPhysmemExportDmaBufOUT->iFd); - -PhysmemExportDmaBuf_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static PVRSRV_ERROR _PhysmemImportSparseDmaBufpsPMRPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefPMR((PMR *) pvData); - return eError; -} - -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysmemImportSparseDmaBuf(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemImportSparseDmaBufIN_UI8, - IMG_UINT8 * psPhysmemImportSparseDmaBufOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF *psPhysmemImportSparseDmaBufIN = - (PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF *) - IMG_OFFSET_ADDR(psPhysmemImportSparseDmaBufIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF *psPhysmemImportSparseDmaBufOUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF *) - IMG_OFFSET_ADDR(psPhysmemImportSparseDmaBufOUT_UI8, 0); - - IMG_UINT32 *ui32MappingTableInt = NULL; - IMG_CHAR *uiNameInt = NULL; - PMR *psPMRPtrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psPhysmemImportSparseDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely - (psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemImportSparseDmaBuf_exit; - } - - if (unlikely(psPhysmemImportSparseDmaBufIN->ui32NameSize > DEVMEM_ANNOTATION_MAX_LEN)) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemImportSparseDmaBuf_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysmemImportSparseDmaBuf_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysmemImportSparseDmaBufIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysmemImportSparseDmaBufIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysmemImportSparseDmaBuf_exit; - } - } - } - - if (psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks != 0) - { - ui32MappingTableInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32MappingTableInt, - (const void __user *)psPhysmemImportSparseDmaBufIN->pui32MappingTable, - psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemImportSparseDmaBuf_exit; - } - } - if (psPhysmemImportSparseDmaBufIN->ui32NameSize != 0) - { - uiNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPhysmemImportSparseDmaBufIN->ui32NameSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPhysmemImportSparseDmaBufIN->ui32NameSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiNameInt, (const void __user *)psPhysmemImportSparseDmaBufIN->puiName, - psPhysmemImportSparseDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemImportSparseDmaBuf_exit; - } - ((IMG_CHAR *) - uiNameInt)[(psPhysmemImportSparseDmaBufIN->ui32NameSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psPhysmemImportSparseDmaBufOUT->eError = - PhysmemImportSparseDmaBuf(psConnection, OSGetDevNode(psConnection), - psPhysmemImportSparseDmaBufIN->ifd, - psPhysmemImportSparseDmaBufIN->uiFlags, - psPhysmemImportSparseDmaBufIN->uiChunkSize, - psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks, - psPhysmemImportSparseDmaBufIN->ui32NumVirtChunks, - ui32MappingTableInt, - psPhysmemImportSparseDmaBufIN->ui32NameSize, - uiNameInt, - &psPMRPtrInt, - &psPhysmemImportSparseDmaBufOUT->uiSize, - &psPhysmemImportSparseDmaBufOUT->uiAlign); - /* Exit early if bridged call fails */ - if (unlikely(psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK)) - { - goto PhysmemImportSparseDmaBuf_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPhysmemImportSparseDmaBufOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPhysmemImportSparseDmaBufOUT->hPMRPtr, (void *)psPMRPtrInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PhysmemImportSparseDmaBufpsPMRPtrIntRelease); - if (unlikely(psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemImportSparseDmaBuf_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PhysmemImportSparseDmaBuf_exit: - - if (psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK) - { - if (psPMRPtrInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefPMR(psPMRPtrInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysmemImportSparseDmaBufOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitDMABUFBridge(void); -void DeinitDMABUFBridge(void); - -/* - * Register all DMABUF functions with services - */ -PVRSRV_ERROR InitDMABUFBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF, - PVRSRVBridgePhysmemImportDmaBuf, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUFLOCKED, - PVRSRVBridgePhysmemImportDmaBufLocked, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF, - PVRSRVBridgePhysmemExportDmaBuf, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF, - PVRSRVBridgePhysmemImportSparseDmaBuf, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF)); - - return PVRSRV_OK; -} - -/* - * Unregister all dmabuf functions with services - */ -void DeinitDMABUFBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, - PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUFLOCKED); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, - PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_htbuffer_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_htbuffer_bridge.c deleted file mode 100644 index 8365c15a5074f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_htbuffer_bridge.c +++ /dev/null @@ -1,354 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for htbuffer -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for htbuffer -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "htbserver.h" - -#include "common_htbuffer_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#include "lock.h" - -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static_assert(HTB_FLAG_NUM_EL <= IMG_UINT32_MAX, - "HTB_FLAG_NUM_EL must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeHTBControl(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHTBControlIN_UI8, - IMG_UINT8 * psHTBControlOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HTBCONTROL *psHTBControlIN = - (PVRSRV_BRIDGE_IN_HTBCONTROL *) IMG_OFFSET_ADDR(psHTBControlIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HTBCONTROL *psHTBControlOUT = - (PVRSRV_BRIDGE_OUT_HTBCONTROL *) IMG_OFFSET_ADDR(psHTBControlOUT_UI8, 0); - - IMG_UINT32 *ui32GroupEnableInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psHTBControlIN->ui32NumGroups > HTB_FLAG_NUM_EL)) - { - psHTBControlOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto HTBControl_exit; - } - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psHTBControlOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto HTBControl_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psHTBControlIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psHTBControlIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psHTBControlOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto HTBControl_exit; - } - } - } - - if (psHTBControlIN->ui32NumGroups != 0) - { - ui32GroupEnableInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32GroupEnableInt, - (const void __user *)psHTBControlIN->pui32GroupEnable, - psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psHTBControlOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto HTBControl_exit; - } - } - - psHTBControlOUT->eError = - HTBControlKM(psHTBControlIN->ui32NumGroups, - ui32GroupEnableInt, - psHTBControlIN->ui32LogLevel, - psHTBControlIN->ui32EnablePID, - psHTBControlIN->ui32LogMode, psHTBControlIN->ui32OpMode); - -HTBControl_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psHTBControlOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(HTB_LOG_MAX_PARAMS <= IMG_UINT32_MAX, - "HTB_LOG_MAX_PARAMS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeHTBLog(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHTBLogIN_UI8, - IMG_UINT8 * psHTBLogOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HTBLOG *psHTBLogIN = - (PVRSRV_BRIDGE_IN_HTBLOG *) IMG_OFFSET_ADDR(psHTBLogIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HTBLOG *psHTBLogOUT = - (PVRSRV_BRIDGE_OUT_HTBLOG *) IMG_OFFSET_ADDR(psHTBLogOUT_UI8, 0); - - IMG_UINT32 *ui32ArgsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psHTBLogIN->ui32NumArgs > HTB_LOG_MAX_PARAMS)) - { - psHTBLogOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto HTBLog_exit; - } - - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psHTBLogOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto HTBLog_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psHTBLogIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psHTBLogIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psHTBLogOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto HTBLog_exit; - } - } - } - - if (psHTBLogIN->ui32NumArgs != 0) - { - ui32ArgsInt = (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ArgsInt, (const void __user *)psHTBLogIN->pui32Args, - psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psHTBLogOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto HTBLog_exit; - } - } - - psHTBLogOUT->eError = - HTBLogKM(psHTBLogIN->ui32PID, - psHTBLogIN->ui32TID, - psHTBLogIN->ui64TimeStamp, - psHTBLogIN->ui32SF, psHTBLogIN->ui32NumArgs, ui32ArgsInt); - -HTBLog_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psHTBLogOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -static POS_LOCK pHTBUFFERBridgeLock; - -#endif /* EXCLUDE_HTBUFFER_BRIDGE */ - -#if !defined(EXCLUDE_HTBUFFER_BRIDGE) -PVRSRV_ERROR InitHTBUFFERBridge(void); -void DeinitHTBUFFERBridge(void); - -/* - * Register all HTBUFFER functions with services - */ -PVRSRV_ERROR InitHTBUFFERBridge(void) -{ - PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&pHTBUFFERBridgeLock), "OSLockCreate"); - - SetDispatchTableEntry(PVRSRV_BRIDGE_HTBUFFER, PVRSRV_BRIDGE_HTBUFFER_HTBCONTROL, - PVRSRVBridgeHTBControl, pHTBUFFERBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_HTBCONTROL), - sizeof(PVRSRV_BRIDGE_OUT_HTBCONTROL)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_HTBUFFER, PVRSRV_BRIDGE_HTBUFFER_HTBLOG, - PVRSRVBridgeHTBLog, pHTBUFFERBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_HTBLOG), sizeof(PVRSRV_BRIDGE_OUT_HTBLOG)); - - return PVRSRV_OK; -} - -/* - * Unregister all htbuffer functions with services - */ -void DeinitHTBUFFERBridge(void) -{ - OSLockDestroy(pHTBUFFERBridgeLock); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_HTBUFFER, PVRSRV_BRIDGE_HTBUFFER_HTBCONTROL); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_HTBUFFER, PVRSRV_BRIDGE_HTBUFFER_HTBLOG); - -} -#else /* EXCLUDE_HTBUFFER_BRIDGE */ -/* This bridge is conditional on EXCLUDE_HTBUFFER_BRIDGE - when defined, - * do not populate the dispatch table with its functions - */ -#define InitHTBUFFERBridge() \ - PVRSRV_OK - -#define DeinitHTBUFFERBridge() - -#endif /* EXCLUDE_HTBUFFER_BRIDGE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/server_mm_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_mm_bridge.c deleted file mode 100644 index 3c28da5e2cca8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_mm_bridge.c +++ /dev/null @@ -1,4725 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for mm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for mm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "pvrsrv_memalloc_physheap.h" -#include "devicemem.h" -#include "devicemem_server.h" -#include "pmr.h" -#include "devicemem_heapcfg.h" -#include "physmem.h" -#include "devicemem_utils.h" -#include "process_stats.h" - -#include "common_mm_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -static PVRSRV_ERROR ReleasePMRExport(void *pvData) -{ - PVR_UNREFERENCED_PARAMETER(pvData); - - return PVRSRV_OK; -} - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _PMRExportPMRpsPMRExportIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnexportPMR((PMR_EXPORT *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgePMRExportPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRExportPMRIN_UI8, - IMG_UINT8 * psPMRExportPMROUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMREXPORTPMR *psPMRExportPMRIN = - (PVRSRV_BRIDGE_IN_PMREXPORTPMR *) IMG_OFFSET_ADDR(psPMRExportPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMREXPORTPMR *psPMRExportPMROUT = - (PVRSRV_BRIDGE_OUT_PMREXPORTPMR *) IMG_OFFSET_ADDR(psPMRExportPMROUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRExportPMRIN->hPMR; - PMR *psPMRInt = NULL; - PMR_EXPORT *psPMRExportInt = NULL; - IMG_HANDLE hPMRExportInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRExportPMROUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRExportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRExportPMR_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRExportPMROUT->eError = - PMRExportPMR(psPMRInt, - &psPMRExportInt, - &psPMRExportPMROUT->ui64Size, - &psPMRExportPMROUT->ui32Log2Contig, &psPMRExportPMROUT->ui64Password); - /* Exit early if bridged call fails */ - if (unlikely(psPMRExportPMROUT->eError != PVRSRV_OK)) - { - goto PMRExportPMR_exit; - } - - /* - * For cases where we need a cross process handle we actually allocate two. - * - * The first one is a connection specific handle and it gets given the real - * release function. This handle does *NOT* get returned to the caller. It's - * purpose is to release any leaked resources when we either have a bad or - * abnormally terminated client. If we didn't do this then the resource - * wouldn't be freed until driver unload. If the resource is freed normally, - * this handle can be looked up via the cross process handle and then - * released accordingly. - * - * The second one is a cross process handle and it gets given a noop release - * function. This handle does get returned to the caller. - */ - - /* Lock over handle creation. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psPMRExportPMROUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - &hPMRExportInt, (void *)psPMRExportInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & _PMRExportPMRpsPMRExportIntRelease); - if (unlikely(psPMRExportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto PMRExportPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - - /* Lock over handle creation. */ - LockHandle(KERNEL_HANDLE_BASE); - psPMRExportPMROUT->eError = PVRSRVAllocHandleUnlocked(KERNEL_HANDLE_BASE, - &psPMRExportPMROUT->hPMRExport, - (void *)psPMRExportInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - ReleasePMRExport); - if (unlikely(psPMRExportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(KERNEL_HANDLE_BASE); - goto PMRExportPMR_exit; - } - /* Release now we have created handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - -PMRExportPMR_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psPMRExportPMROUT->eError != PVRSRV_OK) - { - if (psPMRExportPMROUT->hPMRExport) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(KERNEL_HANDLE_BASE); - - eError = PVRSRVDestroyHandleUnlocked(KERNEL_HANDLE_BASE, - (IMG_HANDLE) psPMRExportPMROUT-> - hPMRExport, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - - } - - if (hPMRExportInt) - { - PVRSRV_ERROR eError; - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - eError = - PVRSRVDestroyHandleUnlocked(psConnection->psProcessHandleBase-> - psHandleBase, hPMRExportInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - } - - else if (psPMRExportInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnexportPMR(psPMRExportInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - - } - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRUnexportPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRUnexportPMRIN_UI8, - IMG_UINT8 * psPMRUnexportPMROUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR *psPMRUnexportPMRIN = - (PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR *) IMG_OFFSET_ADDR(psPMRUnexportPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR *psPMRUnexportPMROUT = - (PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR *) IMG_OFFSET_ADDR(psPMRUnexportPMROUT_UI8, 0); - - PMR_EXPORT *psPMRExportInt = NULL; - IMG_HANDLE hPMRExportInt = NULL; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* Lock over handle destruction. */ - LockHandle(KERNEL_HANDLE_BASE); - psPMRUnexportPMROUT->eError = - PVRSRVLookupHandleUnlocked(KERNEL_HANDLE_BASE, - (void **)&psPMRExportInt, - (IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT, IMG_FALSE); - if (unlikely(psPMRUnexportPMROUT->eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnexportPMROUT->eError))); - } - PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK); - - /* Release now we have destroyed handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - /* - * Find the connection specific handle that represents the same data - * as the cross process handle as releasing it will actually call the - * data's real release function (see the function where the cross - * process handle is allocated for more details). - */ - psPMRUnexportPMROUT->eError = - PVRSRVFindHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - &hPMRExportInt, - psPMRExportInt, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - if (unlikely(psPMRUnexportPMROUT->eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnexportPMROUT->eError))); - } - PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK); - - psPMRUnexportPMROUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psProcessHandleBase->psHandleBase, - hPMRExportInt, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - if (unlikely((psPMRUnexportPMROUT->eError != PVRSRV_OK) && - (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnexportPMROUT->eError))); - } - PVR_ASSERT((psPMRUnexportPMROUT->eError == PVRSRV_OK) || - (psPMRUnexportPMROUT->eError == PVRSRV_ERROR_RETRY)); - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - - /* Lock over handle destruction. */ - LockHandle(KERNEL_HANDLE_BASE); - - psPMRUnexportPMROUT->eError = - PVRSRVDestroyHandleStagedUnlocked(KERNEL_HANDLE_BASE, - (IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - if (unlikely((psPMRUnexportPMROUT->eError != PVRSRV_OK) && - (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnexportPMROUT->eError))); - UnlockHandle(KERNEL_HANDLE_BASE); - goto PMRUnexportPMR_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - -PMRUnexportPMR_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRGetUID(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRGetUIDIN_UI8, - IMG_UINT8 * psPMRGetUIDOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRGETUID *psPMRGetUIDIN = - (PVRSRV_BRIDGE_IN_PMRGETUID *) IMG_OFFSET_ADDR(psPMRGetUIDIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRGETUID *psPMRGetUIDOUT = - (PVRSRV_BRIDGE_OUT_PMRGETUID *) IMG_OFFSET_ADDR(psPMRGetUIDOUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRGetUIDIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRGetUIDOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRGetUIDOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRGetUID_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRGetUIDOUT->eError = PMRGetUID(psPMRInt, &psPMRGetUIDOUT->ui64UID); - -PMRGetUID_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static PVRSRV_ERROR _PMRMakeLocalImportHandlepsExtMemIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnmakeLocalImportHandle((PMR *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgePMRMakeLocalImportHandle(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRMakeLocalImportHandleIN_UI8, - IMG_UINT8 * psPMRMakeLocalImportHandleOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE *psPMRMakeLocalImportHandleIN = - (PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE *) - IMG_OFFSET_ADDR(psPMRMakeLocalImportHandleIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE *psPMRMakeLocalImportHandleOUT = - (PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE *) - IMG_OFFSET_ADDR(psPMRMakeLocalImportHandleOUT_UI8, 0); - - IMG_HANDLE hBuffer = psPMRMakeLocalImportHandleIN->hBuffer; - PMR *psBufferInt = NULL; - PMR *psExtMemInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRMakeLocalImportHandleOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psBufferInt, - hBuffer, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, IMG_TRUE); - if (unlikely(psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRMakeLocalImportHandle_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRMakeLocalImportHandleOUT->eError = PMRMakeLocalImportHandle(psBufferInt, &psExtMemInt); - /* Exit early if bridged call fails */ - if (unlikely(psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)) - { - goto PMRMakeLocalImportHandle_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psPMRMakeLocalImportHandleOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - &psPMRMakeLocalImportHandleOUT->hExtMem, (void *)psExtMemInt, - PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PMRMakeLocalImportHandlepsExtMemIntRelease); - if (unlikely(psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto PMRMakeLocalImportHandle_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - -PMRMakeLocalImportHandle_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psBufferInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hBuffer, PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK) - { - if (psExtMemInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnmakeLocalImportHandle(psExtMemInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRUnmakeLocalImportHandle(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRUnmakeLocalImportHandleIN_UI8, - IMG_UINT8 * psPMRUnmakeLocalImportHandleOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE *psPMRUnmakeLocalImportHandleIN = - (PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE *) - IMG_OFFSET_ADDR(psPMRUnmakeLocalImportHandleIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE *psPMRUnmakeLocalImportHandleOUT = - (PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE *) - IMG_OFFSET_ADDR(psPMRUnmakeLocalImportHandleOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psPMRUnmakeLocalImportHandleOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psProcessHandleBase->psHandleBase, - (IMG_HANDLE) psPMRUnmakeLocalImportHandleIN->hExtMem, - PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT); - if (unlikely((psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_OK) && - (psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psPMRUnmakeLocalImportHandleOUT->eError))); - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto PMRUnmakeLocalImportHandle_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - -PMRUnmakeLocalImportHandle_exit: - - return 0; -} - -static PVRSRV_ERROR _PMRImportPMRpsPMRIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefPMR((PMR *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgePMRImportPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRImportPMRIN_UI8, - IMG_UINT8 * psPMRImportPMROUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRIMPORTPMR *psPMRImportPMRIN = - (PVRSRV_BRIDGE_IN_PMRIMPORTPMR *) IMG_OFFSET_ADDR(psPMRImportPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRIMPORTPMR *psPMRImportPMROUT = - (PVRSRV_BRIDGE_OUT_PMRIMPORTPMR *) IMG_OFFSET_ADDR(psPMRImportPMROUT_UI8, 0); - - IMG_HANDLE hPMRExport = psPMRImportPMRIN->hPMRExport; - PMR_EXPORT *psPMRExportInt = NULL; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(KERNEL_HANDLE_BASE); - - /* Look up the address from the handle */ - psPMRImportPMROUT->eError = - PVRSRVLookupHandleUnlocked(KERNEL_HANDLE_BASE, - (void **)&psPMRExportInt, - hPMRExport, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT, IMG_TRUE); - if (unlikely(psPMRImportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(KERNEL_HANDLE_BASE); - goto PMRImportPMR_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - - psPMRImportPMROUT->eError = - PhysmemImportPMR(psConnection, OSGetDevNode(psConnection), - psPMRExportInt, - psPMRImportPMRIN->ui64uiPassword, - psPMRImportPMRIN->ui64uiSize, - psPMRImportPMRIN->ui32uiLog2Contig, &psPMRInt); - /* Exit early if bridged call fails */ - if (unlikely(psPMRImportPMROUT->eError != PVRSRV_OK)) - { - goto PMRImportPMR_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPMRImportPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPMRImportPMROUT->hPMR, - (void *)psPMRInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PMRImportPMRpsPMRIntRelease); - if (unlikely(psPMRImportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRImportPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PMRImportPMR_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(KERNEL_HANDLE_BASE); - - /* Unreference the previously looked up handle */ - if (psPMRExportInt) - { - PVRSRVReleaseHandleUnlocked(KERNEL_HANDLE_BASE, - hPMRExport, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(KERNEL_HANDLE_BASE); - - if (psPMRImportPMROUT->eError != PVRSRV_OK) - { - if (psPMRInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefPMR(psPMRInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - return 0; -} - -static PVRSRV_ERROR _PMRLocalImportPMRpsPMRIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefPMR((PMR *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgePMRLocalImportPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRLocalImportPMRIN_UI8, - IMG_UINT8 * psPMRLocalImportPMROUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR *psPMRLocalImportPMRIN = - (PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR *) IMG_OFFSET_ADDR(psPMRLocalImportPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR *psPMRLocalImportPMROUT = - (PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR *) IMG_OFFSET_ADDR(psPMRLocalImportPMROUT_UI8, 0); - - IMG_HANDLE hExtHandle = psPMRLocalImportPMRIN->hExtHandle; - PMR *psExtHandleInt = NULL; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - /* Look up the address from the handle */ - psPMRLocalImportPMROUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - (void **)&psExtHandleInt, - hExtHandle, PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT, IMG_TRUE); - if (unlikely(psPMRLocalImportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto PMRLocalImportPMR_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psPMRLocalImportPMROUT->eError = - PMRLocalImportPMR(psExtHandleInt, - &psPMRInt, - &psPMRLocalImportPMROUT->uiSize, &psPMRLocalImportPMROUT->uiAlign); - /* Exit early if bridged call fails */ - if (unlikely(psPMRLocalImportPMROUT->eError != PVRSRV_OK)) - { - goto PMRLocalImportPMR_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPMRLocalImportPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPMRLocalImportPMROUT->hPMR, - (void *)psPMRInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PMRLocalImportPMRpsPMRIntRelease); - if (unlikely(psPMRLocalImportPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRLocalImportPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PMRLocalImportPMR_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psExtHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - hExtHandle, PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - - if (psPMRLocalImportPMROUT->eError != PVRSRV_OK) - { - if (psPMRInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefPMR(psPMRInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRUnrefPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRUnrefPMRIN_UI8, - IMG_UINT8 * psPMRUnrefPMROUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRUNREFPMR *psPMRUnrefPMRIN = - (PVRSRV_BRIDGE_IN_PMRUNREFPMR *) IMG_OFFSET_ADDR(psPMRUnrefPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRUNREFPMR *psPMRUnrefPMROUT = - (PVRSRV_BRIDGE_OUT_PMRUNREFPMR *) IMG_OFFSET_ADDR(psPMRUnrefPMROUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psPMRUnrefPMROUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psPMRUnrefPMRIN->hPMR, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - if (unlikely((psPMRUnrefPMROUT->eError != PVRSRV_OK) && - (psPMRUnrefPMROUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psPMRUnrefPMROUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnrefPMROUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto PMRUnrefPMR_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -PMRUnrefPMR_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRUnrefUnlockPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRUnrefUnlockPMRIN_UI8, - IMG_UINT8 * psPMRUnrefUnlockPMROUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR *psPMRUnrefUnlockPMRIN = - (PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR *) IMG_OFFSET_ADDR(psPMRUnrefUnlockPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR *psPMRUnrefUnlockPMROUT = - (PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR *) IMG_OFFSET_ADDR(psPMRUnrefUnlockPMROUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psPMRUnrefUnlockPMROUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psPMRUnrefUnlockPMRIN->hPMR, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - if (unlikely((psPMRUnrefUnlockPMROUT->eError != PVRSRV_OK) && - (psPMRUnrefUnlockPMROUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psPMRUnrefUnlockPMROUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psPMRUnrefUnlockPMROUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto PMRUnrefUnlockPMR_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -PMRUnrefUnlockPMR_exit: - - return 0; -} - -static PVRSRV_ERROR _PhysmemNewRamBackedPMRpsPMRPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefPMR((PMR *) pvData); - return eError; -} - -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysmemNewRamBackedPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemNewRamBackedPMRIN_UI8, - IMG_UINT8 * psPhysmemNewRamBackedPMROUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR *psPhysmemNewRamBackedPMRIN = - (PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR *) - IMG_OFFSET_ADDR(psPhysmemNewRamBackedPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR *psPhysmemNewRamBackedPMROUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR *) - IMG_OFFSET_ADDR(psPhysmemNewRamBackedPMROUT_UI8, 0); - - IMG_UINT32 *ui32MappingTableInt = NULL; - IMG_CHAR *uiAnnotationInt = NULL; - PMR *psPMRPtrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemNewRamBackedPMR_exit; - } - - if (unlikely(psPhysmemNewRamBackedPMRIN->ui32AnnotationLength > DEVMEM_ANNOTATION_MAX_LEN)) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemNewRamBackedPMR_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysmemNewRamBackedPMR_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysmemNewRamBackedPMRIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysmemNewRamBackedPMRIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysmemNewRamBackedPMR_exit; - } - } - } - - if (psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks != 0) - { - ui32MappingTableInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32MappingTableInt, - (const void __user *)psPhysmemNewRamBackedPMRIN->pui32MappingTable, - psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemNewRamBackedPMR_exit; - } - } - if (psPhysmemNewRamBackedPMRIN->ui32AnnotationLength != 0) - { - uiAnnotationInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiAnnotationInt, - (const void __user *)psPhysmemNewRamBackedPMRIN->puiAnnotation, - psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) != - PVRSRV_OK) - { - psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemNewRamBackedPMR_exit; - } - ((IMG_CHAR *) - uiAnnotationInt)[(psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * - sizeof(IMG_CHAR)) - 1] = '\0'; - } - - psPhysmemNewRamBackedPMROUT->eError = - PhysmemNewRamBackedPMR(psConnection, OSGetDevNode(psConnection), - psPhysmemNewRamBackedPMRIN->uiSize, - psPhysmemNewRamBackedPMRIN->uiChunkSize, - psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks, - psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks, - ui32MappingTableInt, - psPhysmemNewRamBackedPMRIN->ui32Log2PageSize, - psPhysmemNewRamBackedPMRIN->uiFlags, - psPhysmemNewRamBackedPMRIN->ui32AnnotationLength, - uiAnnotationInt, - psPhysmemNewRamBackedPMRIN->ui32PID, - &psPMRPtrInt, - psPhysmemNewRamBackedPMRIN->ui32PDumpFlags, - &psPhysmemNewRamBackedPMROUT->uiOutFlags); - /* Exit early if bridged call fails */ - if (unlikely(psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)) - { - goto PhysmemNewRamBackedPMR_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPhysmemNewRamBackedPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPhysmemNewRamBackedPMROUT-> - hPMRPtr, - (void *)psPMRPtrInt, - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PhysmemNewRamBackedPMRpsPMRPtrIntRelease); - if (unlikely(psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemNewRamBackedPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PhysmemNewRamBackedPMR_exit: - - if (psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK) - { - if (psPMRPtrInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefPMR(psPMRPtrInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysmemNewRamBackedPMROUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _PhysmemNewRamBackedLockedPMRpsPMRPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PMRUnrefUnlockPMR((PMR *) pvData); - return eError; -} - -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysmemNewRamBackedLockedPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysmemNewRamBackedLockedPMRIN_UI8, - IMG_UINT8 * psPhysmemNewRamBackedLockedPMROUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR *psPhysmemNewRamBackedLockedPMRIN = - (PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR *) - IMG_OFFSET_ADDR(psPhysmemNewRamBackedLockedPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR *psPhysmemNewRamBackedLockedPMROUT = - (PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR *) - IMG_OFFSET_ADDR(psPhysmemNewRamBackedLockedPMROUT_UI8, 0); - - IMG_UINT32 *ui32MappingTableInt = NULL; - IMG_CHAR *uiAnnotationInt = NULL; - PMR *psPMRPtrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * - sizeof(IMG_UINT32)) + - ((IMG_UINT64) psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * - sizeof(IMG_CHAR)) + 0; - - if (unlikely - (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemNewRamBackedLockedPMR_exit; - } - - if (unlikely - (psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength > DEVMEM_ANNOTATION_MAX_LEN)) - { - psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysmemNewRamBackedLockedPMR_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysmemNewRamBackedLockedPMR_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysmemNewRamBackedLockedPMRIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psPhysmemNewRamBackedLockedPMRIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysmemNewRamBackedLockedPMROUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysmemNewRamBackedLockedPMR_exit; - } - } - } - - if (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks != 0) - { - ui32MappingTableInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32MappingTableInt, - (const void __user *)psPhysmemNewRamBackedLockedPMRIN->pui32MappingTable, - psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemNewRamBackedLockedPMR_exit; - } - } - if (psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength != 0) - { - uiAnnotationInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiAnnotationInt, - (const void __user *)psPhysmemNewRamBackedLockedPMRIN->puiAnnotation, - psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) != - PVRSRV_OK) - { - psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysmemNewRamBackedLockedPMR_exit; - } - ((IMG_CHAR *) - uiAnnotationInt)[(psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * - sizeof(IMG_CHAR)) - 1] = '\0'; - } - - psPhysmemNewRamBackedLockedPMROUT->eError = - PhysmemNewRamBackedLockedPMR(psConnection, OSGetDevNode(psConnection), - psPhysmemNewRamBackedLockedPMRIN->uiSize, - psPhysmemNewRamBackedLockedPMRIN->uiChunkSize, - psPhysmemNewRamBackedLockedPMRIN->ui32NumPhysChunks, - psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks, - ui32MappingTableInt, - psPhysmemNewRamBackedLockedPMRIN->ui32Log2PageSize, - psPhysmemNewRamBackedLockedPMRIN->uiFlags, - psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength, - uiAnnotationInt, - psPhysmemNewRamBackedLockedPMRIN->ui32PID, - &psPMRPtrInt, - psPhysmemNewRamBackedLockedPMRIN->ui32PDumpFlags, - &psPhysmemNewRamBackedLockedPMROUT->uiOutFlags); - /* Exit early if bridged call fails */ - if (unlikely(psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK)) - { - goto PhysmemNewRamBackedLockedPMR_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psPhysmemNewRamBackedLockedPMROUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psPhysmemNewRamBackedLockedPMROUT->hPMRPtr, - (void *)psPMRPtrInt, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _PhysmemNewRamBackedLockedPMRpsPMRPtrIntRelease); - if (unlikely(psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PhysmemNewRamBackedLockedPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -PhysmemNewRamBackedLockedPMR_exit: - - if (psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK) - { - if (psPMRPtrInt) - { - LockHandle(KERNEL_HANDLE_BASE); - PMRUnrefUnlockPMR(psPMRPtrInt); - UnlockHandle(KERNEL_HANDLE_BASE); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysmemNewRamBackedLockedPMROUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntPin(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntPinIN_UI8, - IMG_UINT8 * psDevmemIntPinOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTPIN *psDevmemIntPinIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTPIN *) IMG_OFFSET_ADDR(psDevmemIntPinIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTPIN *psDevmemIntPinOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTPIN *) IMG_OFFSET_ADDR(psDevmemIntPinOUT_UI8, 0); - - IMG_HANDLE hPMR = psDevmemIntPinIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntPinOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntPinOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntPin_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntPinOUT->eError = DevmemIntPin(psPMRInt); - -DevmemIntPin_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnpin(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnpinIN_UI8, - IMG_UINT8 * psDevmemIntUnpinOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN *psDevmemIntUnpinIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN *) IMG_OFFSET_ADDR(psDevmemIntUnpinIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN *psDevmemIntUnpinOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN *) IMG_OFFSET_ADDR(psDevmemIntUnpinOUT_UI8, 0); - - IMG_HANDLE hPMR = psDevmemIntUnpinIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntUnpinOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntUnpinOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnpin_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntUnpinOUT->eError = DevmemIntUnpin(psPMRInt); - -DevmemIntUnpin_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntPinValidate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntPinValidateIN_UI8, - IMG_UINT8 * psDevmemIntPinValidateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE *psDevmemIntPinValidateIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE *) IMG_OFFSET_ADDR(psDevmemIntPinValidateIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE *psDevmemIntPinValidateOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE *) - IMG_OFFSET_ADDR(psDevmemIntPinValidateOUT_UI8, 0); - - IMG_HANDLE hMapping = psDevmemIntPinValidateIN->hMapping; - DEVMEMINT_MAPPING *psMappingInt = NULL; - IMG_HANDLE hPMR = psDevmemIntPinValidateIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntPinValidateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psMappingInt, - hMapping, PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING, IMG_TRUE); - if (unlikely(psDevmemIntPinValidateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntPinValidate_exit; - } - - /* Look up the address from the handle */ - psDevmemIntPinValidateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntPinValidateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntPinValidate_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntPinValidateOUT->eError = DevmemIntPinValidate(psMappingInt, psPMRInt); - -DevmemIntPinValidate_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psMappingInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hMapping, PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnpinInvalidate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnpinInvalidateIN_UI8, - IMG_UINT8 * psDevmemIntUnpinInvalidateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE *psDevmemIntUnpinInvalidateIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE *) - IMG_OFFSET_ADDR(psDevmemIntUnpinInvalidateIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE *psDevmemIntUnpinInvalidateOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE *) - IMG_OFFSET_ADDR(psDevmemIntUnpinInvalidateOUT_UI8, 0); - - IMG_HANDLE hMapping = psDevmemIntUnpinInvalidateIN->hMapping; - DEVMEMINT_MAPPING *psMappingInt = NULL; - IMG_HANDLE hPMR = psDevmemIntUnpinInvalidateIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntUnpinInvalidateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psMappingInt, - hMapping, PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING, IMG_TRUE); - if (unlikely(psDevmemIntUnpinInvalidateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnpinInvalidate_exit; - } - - /* Look up the address from the handle */ - psDevmemIntUnpinInvalidateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntUnpinInvalidateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnpinInvalidate_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntUnpinInvalidateOUT->eError = DevmemIntUnpinInvalidate(psMappingInt, psPMRInt); - -DevmemIntUnpinInvalidate_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psMappingInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hMapping, PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static PVRSRV_ERROR _DevmemIntCtxCreatepsDevMemServerContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntCtxDestroy((DEVMEMINT_CTX *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntCtxCreate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntCtxCreateIN_UI8, - IMG_UINT8 * psDevmemIntCtxCreateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE *psDevmemIntCtxCreateIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE *) IMG_OFFSET_ADDR(psDevmemIntCtxCreateIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE *psDevmemIntCtxCreateOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE *) IMG_OFFSET_ADDR(psDevmemIntCtxCreateOUT_UI8, - 0); - - DEVMEMINT_CTX *psDevMemServerContextInt = NULL; - IMG_HANDLE hPrivDataInt = NULL; - - psDevmemIntCtxCreateOUT->hDevMemServerContext = NULL; - - psDevmemIntCtxCreateOUT->eError = - DevmemIntCtxCreate(psConnection, OSGetDevNode(psConnection), - psDevmemIntCtxCreateIN->bbKernelMemoryCtx, - &psDevMemServerContextInt, - &hPrivDataInt, &psDevmemIntCtxCreateOUT->ui32CPUCacheLineSize); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)) - { - goto DevmemIntCtxCreate_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntCtxCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntCtxCreateOUT-> - hDevMemServerContext, - (void *) - psDevMemServerContextInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemIntCtxCreatepsDevMemServerContextIntRelease); - if (unlikely(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntCtxCreate_exit; - } - - psDevmemIntCtxCreateOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntCtxCreateOUT-> - hPrivData, - (void *)hPrivDataInt, - PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psDevmemIntCtxCreateOUT-> - hDevMemServerContext); - if (unlikely(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntCtxCreate_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntCtxCreate_exit: - - if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK) - { - if (psDevmemIntCtxCreateOUT->hDevMemServerContext) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntCtxCreateOUT-> - hDevMemServerContext, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psDevMemServerContextInt) - { - DevmemIntCtxDestroy(psDevMemServerContextInt); - } - - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntCtxDestroy(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntCtxDestroyIN_UI8, - IMG_UINT8 * psDevmemIntCtxDestroyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY *psDevmemIntCtxDestroyIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY *) IMG_OFFSET_ADDR(psDevmemIntCtxDestroyIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY *psDevmemIntCtxDestroyOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY *) IMG_OFFSET_ADDR(psDevmemIntCtxDestroyOUT_UI8, - 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntCtxDestroyOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntCtxDestroyIN-> - hDevmemServerContext, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - if (unlikely - ((psDevmemIntCtxDestroyOUT->eError != PVRSRV_OK) - && (psDevmemIntCtxDestroyOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psDevmemIntCtxDestroyOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemIntCtxDestroyOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntCtxDestroy_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntCtxDestroy_exit: - - return 0; -} - -static PVRSRV_ERROR _DevmemIntHeapCreatepsDevmemHeapPtrIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntHeapDestroy((DEVMEMINT_HEAP *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntHeapCreate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntHeapCreateIN_UI8, - IMG_UINT8 * psDevmemIntHeapCreateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE *) IMG_OFFSET_ADDR(psDevmemIntHeapCreateIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE *) IMG_OFFSET_ADDR(psDevmemIntHeapCreateOUT_UI8, - 0); - - IMG_HANDLE hDevmemCtx = psDevmemIntHeapCreateIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - DEVMEMINT_HEAP *psDevmemHeapPtrInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntHeapCreateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntHeapCreate_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntHeapCreateOUT->eError = - DevmemIntHeapCreate(psDevmemCtxInt, - psDevmemIntHeapCreateIN->sHeapBaseAddr, - psDevmemIntHeapCreateIN->uiHeapLength, - psDevmemIntHeapCreateIN->ui32Log2DataPageSize, &psDevmemHeapPtrInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)) - { - goto DevmemIntHeapCreate_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntHeapCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntHeapCreateOUT-> - hDevmemHeapPtr, - (void *)psDevmemHeapPtrInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemIntHeapCreatepsDevmemHeapPtrIntRelease); - if (unlikely(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntHeapCreate_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntHeapCreate_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntHeapCreateOUT->eError != PVRSRV_OK) - { - if (psDevmemHeapPtrInt) - { - DevmemIntHeapDestroy(psDevmemHeapPtrInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntHeapDestroy(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntHeapDestroyIN_UI8, - IMG_UINT8 * psDevmemIntHeapDestroyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY *psDevmemIntHeapDestroyIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY *) IMG_OFFSET_ADDR(psDevmemIntHeapDestroyIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY *psDevmemIntHeapDestroyOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY *) - IMG_OFFSET_ADDR(psDevmemIntHeapDestroyOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntHeapDestroyOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntHeapDestroyIN->hDevmemHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - if (unlikely((psDevmemIntHeapDestroyOUT->eError != PVRSRV_OK) && - (psDevmemIntHeapDestroyOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psDevmemIntHeapDestroyOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemIntHeapDestroyOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntHeapDestroy_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntHeapDestroy_exit: - - return 0; -} - -static PVRSRV_ERROR _DevmemIntMapPMRpsMappingIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntUnmapPMR((DEVMEMINT_MAPPING *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntMapPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntMapPMRIN_UI8, - IMG_UINT8 * psDevmemIntMapPMROUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR *psDevmemIntMapPMRIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR *) IMG_OFFSET_ADDR(psDevmemIntMapPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR *psDevmemIntMapPMROUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR *) IMG_OFFSET_ADDR(psDevmemIntMapPMROUT_UI8, 0); - - IMG_HANDLE hDevmemServerHeap = psDevmemIntMapPMRIN->hDevmemServerHeap; - DEVMEMINT_HEAP *psDevmemServerHeapInt = NULL; - IMG_HANDLE hReservation = psDevmemIntMapPMRIN->hReservation; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - IMG_HANDLE hPMR = psDevmemIntMapPMRIN->hPMR; - PMR *psPMRInt = NULL; - DEVMEMINT_MAPPING *psMappingInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntMapPMROUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerHeapInt, - hDevmemServerHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psDevmemIntMapPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR_exit; - } - - /* Look up the address from the handle */ - psDevmemIntMapPMROUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, IMG_TRUE); - if (unlikely(psDevmemIntMapPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR_exit; - } - - /* Look up the address from the handle */ - psDevmemIntMapPMROUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntMapPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntMapPMROUT->eError = - DevmemIntMapPMR(psDevmemServerHeapInt, - psReservationInt, - psPMRInt, psDevmemIntMapPMRIN->uiMapFlags, &psMappingInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntMapPMROUT->eError != PVRSRV_OK)) - { - goto DevmemIntMapPMR_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntMapPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntMapPMROUT->hMapping, - (void *)psMappingInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemIntMapPMRpsMappingIntRelease); - if (unlikely(psDevmemIntMapPMROUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntMapPMR_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntMapPMROUT->eError != PVRSRV_OK) - { - if (psMappingInt) - { - DevmemIntUnmapPMR(psMappingInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnmapPMR(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnmapPMRIN_UI8, - IMG_UINT8 * psDevmemIntUnmapPMROUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR *psDevmemIntUnmapPMRIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR *) IMG_OFFSET_ADDR(psDevmemIntUnmapPMRIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR *psDevmemIntUnmapPMROUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR *) IMG_OFFSET_ADDR(psDevmemIntUnmapPMROUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntUnmapPMROUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntUnmapPMRIN->hMapping, - PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING); - if (unlikely((psDevmemIntUnmapPMROUT->eError != PVRSRV_OK) && - (psDevmemIntUnmapPMROUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psDevmemIntUnmapPMROUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psDevmemIntUnmapPMROUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnmapPMR_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntUnmapPMR_exit: - - return 0; -} - -static PVRSRV_ERROR _DevmemIntReserveRangepsReservationIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntUnreserveRange((DEVMEMINT_RESERVATION *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntReserveRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntReserveRangeIN_UI8, - IMG_UINT8 * psDevmemIntReserveRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemIntReserveRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemIntReserveRangeOUT_UI8, 0); - - IMG_HANDLE hDevmemServerHeap = psDevmemIntReserveRangeIN->hDevmemServerHeap; - DEVMEMINT_HEAP *psDevmemServerHeapInt = NULL; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntReserveRangeOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerHeapInt, - hDevmemServerHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntReserveRange_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntReserveRangeOUT->eError = - DevmemIntReserveRange(psDevmemServerHeapInt, - psDevmemIntReserveRangeIN->sAddress, - psDevmemIntReserveRangeIN->uiLength, &psReservationInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)) - { - goto DevmemIntReserveRange_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntReserveRangeOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntReserveRangeOUT-> - hReservation, - (void *)psReservationInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemIntReserveRangepsReservationIntRelease); - if (unlikely(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntReserveRange_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntReserveRange_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntReserveRangeOUT->eError != PVRSRV_OK) - { - if (psReservationInt) - { - DevmemIntUnreserveRange(psReservationInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnreserveRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnreserveRangeIN_UI8, - IMG_UINT8 * psDevmemIntUnreserveRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE *psDevmemIntUnreserveRangeIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemIntUnreserveRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE *psDevmemIntUnreserveRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemIntUnreserveRangeOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntUnreserveRangeOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntUnreserveRangeIN-> - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION); - if (unlikely - ((psDevmemIntUnreserveRangeOUT->eError != PVRSRV_OK) - && (psDevmemIntUnreserveRangeOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psDevmemIntUnreserveRangeOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemIntUnreserveRangeOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnreserveRange_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntUnreserveRange_exit: - - return 0; -} - -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeChangeSparseMem(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psChangeSparseMemIN_UI8, - IMG_UINT8 * psChangeSparseMemOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CHANGESPARSEMEM *psChangeSparseMemIN = - (PVRSRV_BRIDGE_IN_CHANGESPARSEMEM *) IMG_OFFSET_ADDR(psChangeSparseMemIN_UI8, 0); - PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM *psChangeSparseMemOUT = - (PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM *) IMG_OFFSET_ADDR(psChangeSparseMemOUT_UI8, 0); - - IMG_HANDLE hSrvDevMemHeap = psChangeSparseMemIN->hSrvDevMemHeap; - DEVMEMINT_HEAP *psSrvDevMemHeapInt = NULL; - IMG_HANDLE hPMR = psChangeSparseMemIN->hPMR; - PMR *psPMRInt = NULL; - IMG_UINT32 *ui32AllocPageIndicesInt = NULL; - IMG_UINT32 *ui32FreePageIndicesInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psChangeSparseMemIN->ui32AllocPageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto ChangeSparseMem_exit; - } - - if (unlikely(psChangeSparseMemIN->ui32FreePageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto ChangeSparseMem_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto ChangeSparseMem_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psChangeSparseMemIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psChangeSparseMemIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ChangeSparseMem_exit; - } - } - } - - if (psChangeSparseMemIN->ui32AllocPageCount != 0) - { - ui32AllocPageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32AllocPageIndicesInt, - (const void __user *)psChangeSparseMemIN->pui32AllocPageIndices, - psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto ChangeSparseMem_exit; - } - } - if (psChangeSparseMemIN->ui32FreePageCount != 0) - { - ui32FreePageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32FreePageIndicesInt, - (const void __user *)psChangeSparseMemIN->pui32FreePageIndices, - psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto ChangeSparseMem_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psChangeSparseMemOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSrvDevMemHeapInt, - hSrvDevMemHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psChangeSparseMemOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto ChangeSparseMem_exit; - } - - /* Look up the address from the handle */ - psChangeSparseMemOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psChangeSparseMemOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto ChangeSparseMem_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psChangeSparseMemOUT->eError = - DevmemIntChangeSparse(psSrvDevMemHeapInt, - psPMRInt, - psChangeSparseMemIN->ui32AllocPageCount, - ui32AllocPageIndicesInt, - psChangeSparseMemIN->ui32FreePageCount, - ui32FreePageIndicesInt, - psChangeSparseMemIN->ui32SparseFlags, - psChangeSparseMemIN->uiFlags, - psChangeSparseMemIN->sDevVAddr, - psChangeSparseMemIN->ui64CPUVAddr); - -ChangeSparseMem_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSrvDevMemHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSrvDevMemHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psChangeSparseMemOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntMapPages(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntMapPagesIN_UI8, - IMG_UINT8 * psDevmemIntMapPagesOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES *psDevmemIntMapPagesIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES *) IMG_OFFSET_ADDR(psDevmemIntMapPagesIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES *psDevmemIntMapPagesOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES *) IMG_OFFSET_ADDR(psDevmemIntMapPagesOUT_UI8, 0); - - IMG_HANDLE hReservation = psDevmemIntMapPagesIN->hReservation; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - IMG_HANDLE hPMR = psDevmemIntMapPagesIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntMapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, IMG_TRUE); - if (unlikely(psDevmemIntMapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPages_exit; - } - - /* Look up the address from the handle */ - psDevmemIntMapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntMapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPages_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntMapPagesOUT->eError = - DevmemIntMapPages(psReservationInt, - psPMRInt, - psDevmemIntMapPagesIN->ui32PageCount, - psDevmemIntMapPagesIN->ui32PhysicalPgOffset, - psDevmemIntMapPagesIN->uiFlags, psDevmemIntMapPagesIN->sDevVAddr); - -DevmemIntMapPages_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnmapPages(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnmapPagesIN_UI8, - IMG_UINT8 * psDevmemIntUnmapPagesOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES *psDevmemIntUnmapPagesIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES *) IMG_OFFSET_ADDR(psDevmemIntUnmapPagesIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES *psDevmemIntUnmapPagesOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES *) IMG_OFFSET_ADDR(psDevmemIntUnmapPagesOUT_UI8, - 0); - - IMG_HANDLE hReservation = psDevmemIntUnmapPagesIN->hReservation; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntUnmapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, IMG_TRUE); - if (unlikely(psDevmemIntUnmapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnmapPages_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntUnmapPagesOUT->eError = - DevmemIntUnmapPages(psReservationInt, - psDevmemIntUnmapPagesIN->sDevVAddr, - psDevmemIntUnmapPagesIN->ui32PageCount); - -DevmemIntUnmapPages_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIsVDevAddrValid(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIsVDevAddrValidIN_UI8, - IMG_UINT8 * psDevmemIsVDevAddrValidOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidIN = - (PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID *) - IMG_OFFSET_ADDR(psDevmemIsVDevAddrValidIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID *) - IMG_OFFSET_ADDR(psDevmemIsVDevAddrValidOUT_UI8, 0); - - IMG_HANDLE hDevmemCtx = psDevmemIsVDevAddrValidIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIsVDevAddrValidOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemIsVDevAddrValidOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIsVDevAddrValid_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIsVDevAddrValidOUT->eError = - DevmemIntIsVDevAddrValid(psConnection, OSGetDevNode(psConnection), - psDevmemCtxInt, psDevmemIsVDevAddrValidIN->sAddress); - -DevmemIsVDevAddrValid_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#if defined(RGX_SRV_SLC_RANGEBASED_CFI_SUPPORTED) - -static IMG_INT -PVRSRVBridgeDevmemFlushDevSLCRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemFlushDevSLCRangeIN_UI8, - IMG_UINT8 * psDevmemFlushDevSLCRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE *psDevmemFlushDevSLCRangeIN = - (PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE *) - IMG_OFFSET_ADDR(psDevmemFlushDevSLCRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE *psDevmemFlushDevSLCRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE *) - IMG_OFFSET_ADDR(psDevmemFlushDevSLCRangeOUT_UI8, 0); - - IMG_HANDLE hDevmemCtx = psDevmemFlushDevSLCRangeIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemFlushDevSLCRangeOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemFlushDevSLCRangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemFlushDevSLCRange_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemFlushDevSLCRangeOUT->eError = - DevmemIntFlushDevSLCRange(psDevmemCtxInt, - psDevmemFlushDevSLCRangeIN->sAddress, - psDevmemFlushDevSLCRangeIN->uiSize, - psDevmemFlushDevSLCRangeIN->bInvalidate); - -DevmemFlushDevSLCRange_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeDevmemFlushDevSLCRange NULL -#endif - -#if defined(RGX_FEATURE_FBCDC) - -static IMG_INT -PVRSRVBridgeDevmemInvalidateFBSCTable(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemInvalidateFBSCTableIN_UI8, - IMG_UINT8 * psDevmemInvalidateFBSCTableOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE *psDevmemInvalidateFBSCTableIN = - (PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE *) - IMG_OFFSET_ADDR(psDevmemInvalidateFBSCTableIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE *psDevmemInvalidateFBSCTableOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE *) - IMG_OFFSET_ADDR(psDevmemInvalidateFBSCTableOUT_UI8, 0); - - IMG_HANDLE hDevmemCtx = psDevmemInvalidateFBSCTableIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemInvalidateFBSCTableOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemInvalidateFBSCTableOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemInvalidateFBSCTable_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemInvalidateFBSCTableOUT->eError = - DevmemIntInvalidateFBSCTable(psDevmemCtxInt, - psDevmemInvalidateFBSCTableIN->ui64FBSCEntries); - -DevmemInvalidateFBSCTable_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeDevmemInvalidateFBSCTable NULL -#endif - -static IMG_INT -PVRSRVBridgeHeapCfgHeapConfigCount(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHeapCfgHeapConfigCountIN_UI8, - IMG_UINT8 * psHeapCfgHeapConfigCountOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT *psHeapCfgHeapConfigCountIN = - (PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT *) - IMG_OFFSET_ADDR(psHeapCfgHeapConfigCountIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT *psHeapCfgHeapConfigCountOUT = - (PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT *) - IMG_OFFSET_ADDR(psHeapCfgHeapConfigCountOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psHeapCfgHeapConfigCountIN); - - psHeapCfgHeapConfigCountOUT->eError = - HeapCfgHeapConfigCount(psConnection, OSGetDevNode(psConnection), - &psHeapCfgHeapConfigCountOUT->ui32NumHeapConfigs); - - return 0; -} - -static IMG_INT -PVRSRVBridgeHeapCfgHeapCount(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHeapCfgHeapCountIN_UI8, - IMG_UINT8 * psHeapCfgHeapCountOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT *psHeapCfgHeapCountIN = - (PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT *) IMG_OFFSET_ADDR(psHeapCfgHeapCountIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT *psHeapCfgHeapCountOUT = - (PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT *) IMG_OFFSET_ADDR(psHeapCfgHeapCountOUT_UI8, 0); - - psHeapCfgHeapCountOUT->eError = - HeapCfgHeapCount(psConnection, OSGetDevNode(psConnection), - psHeapCfgHeapCountIN->ui32HeapConfigIndex, - &psHeapCfgHeapCountOUT->ui32NumHeaps); - - return 0; -} - -static_assert(DEVMEM_HEAPNAME_MAXLENGTH <= IMG_UINT32_MAX, - "DEVMEM_HEAPNAME_MAXLENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeHeapCfgHeapConfigName(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHeapCfgHeapConfigNameIN_UI8, - IMG_UINT8 * psHeapCfgHeapConfigNameOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME *psHeapCfgHeapConfigNameIN = - (PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME *) - IMG_OFFSET_ADDR(psHeapCfgHeapConfigNameIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME *psHeapCfgHeapConfigNameOUT = - (PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME *) - IMG_OFFSET_ADDR(psHeapCfgHeapConfigNameOUT_UI8, 0); - - IMG_CHAR *puiHeapConfigNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR)) + - 0; - - if (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz > DEVMEM_HEAPNAME_MAXLENGTH) - { - psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto HeapCfgHeapConfigName_exit; - } - - psHeapCfgHeapConfigNameOUT->puiHeapConfigName = - psHeapCfgHeapConfigNameIN->puiHeapConfigName; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto HeapCfgHeapConfigName_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psHeapCfgHeapConfigNameIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psHeapCfgHeapConfigNameIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto HeapCfgHeapConfigName_exit; - } - } - } - - if (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz != 0) - { - puiHeapConfigNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR); - } - - psHeapCfgHeapConfigNameOUT->eError = - HeapCfgHeapConfigName(psConnection, OSGetDevNode(psConnection), - psHeapCfgHeapConfigNameIN->ui32HeapConfigIndex, - psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz, - puiHeapConfigNameInt); - /* Exit early if bridged call fails */ - if (unlikely(psHeapCfgHeapConfigNameOUT->eError != PVRSRV_OK)) - { - goto HeapCfgHeapConfigName_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((puiHeapConfigNameInt) && - ((psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psHeapCfgHeapConfigNameOUT->puiHeapConfigName, - puiHeapConfigNameInt, - (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR))) != - PVRSRV_OK)) - { - psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto HeapCfgHeapConfigName_exit; - } - } - -HeapCfgHeapConfigName_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psHeapCfgHeapConfigNameOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(DEVMEM_HEAPNAME_MAXLENGTH <= IMG_UINT32_MAX, - "DEVMEM_HEAPNAME_MAXLENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeHeapCfgHeapDetails(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHeapCfgHeapDetailsIN_UI8, - IMG_UINT8 * psHeapCfgHeapDetailsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS *psHeapCfgHeapDetailsIN = - (PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS *) IMG_OFFSET_ADDR(psHeapCfgHeapDetailsIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS *psHeapCfgHeapDetailsOUT = - (PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS *) IMG_OFFSET_ADDR(psHeapCfgHeapDetailsOUT_UI8, - 0); - - IMG_CHAR *puiHeapNameOutInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR)) + 0; - - if (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz > DEVMEM_HEAPNAME_MAXLENGTH) - { - psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto HeapCfgHeapDetails_exit; - } - - psHeapCfgHeapDetailsOUT->puiHeapNameOut = psHeapCfgHeapDetailsIN->puiHeapNameOut; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto HeapCfgHeapDetails_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psHeapCfgHeapDetailsIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psHeapCfgHeapDetailsIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto HeapCfgHeapDetails_exit; - } - } - } - - if (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz != 0) - { - puiHeapNameOutInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR); - } - - psHeapCfgHeapDetailsOUT->eError = - HeapCfgHeapDetails(psConnection, OSGetDevNode(psConnection), - psHeapCfgHeapDetailsIN->ui32HeapConfigIndex, - psHeapCfgHeapDetailsIN->ui32HeapIndex, - psHeapCfgHeapDetailsIN->ui32HeapNameBufSz, - puiHeapNameOutInt, - &psHeapCfgHeapDetailsOUT->sDevVAddrBase, - &psHeapCfgHeapDetailsOUT->uiHeapLength, - &psHeapCfgHeapDetailsOUT->uiReservedRegionLength, - &psHeapCfgHeapDetailsOUT->ui32Log2DataPageSizeOut, - &psHeapCfgHeapDetailsOUT->ui32Log2ImportAlignmentOut); - /* Exit early if bridged call fails */ - if (unlikely(psHeapCfgHeapDetailsOUT->eError != PVRSRV_OK)) - { - goto HeapCfgHeapDetails_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((puiHeapNameOutInt) && - ((psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psHeapCfgHeapDetailsOUT->puiHeapNameOut, - puiHeapNameOutInt, - (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK)) - { - psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto HeapCfgHeapDetails_exit; - } - } - -HeapCfgHeapDetails_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psHeapCfgHeapDetailsOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntRegisterPFNotifyKM(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntRegisterPFNotifyKMIN_UI8, - IMG_UINT8 * psDevmemIntRegisterPFNotifyKMOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM *psDevmemIntRegisterPFNotifyKMIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM *) - IMG_OFFSET_ADDR(psDevmemIntRegisterPFNotifyKMIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM *psDevmemIntRegisterPFNotifyKMOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM *) - IMG_OFFSET_ADDR(psDevmemIntRegisterPFNotifyKMOUT_UI8, 0); - - IMG_HANDLE hDevm = psDevmemIntRegisterPFNotifyKMIN->hDevm; - DEVMEMINT_CTX *psDevmInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntRegisterPFNotifyKMOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmInt, - hDevm, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemIntRegisterPFNotifyKMOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntRegisterPFNotifyKM_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntRegisterPFNotifyKMOUT->eError = - DevmemIntRegisterPFNotifyKM(psDevmInt, - psDevmemIntRegisterPFNotifyKMIN->ui32PID, - psDevmemIntRegisterPFNotifyKMIN->bRegister); - -DevmemIntRegisterPFNotifyKM_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevm, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeGetMaxPhysHeapCount(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetMaxPhysHeapCountIN_UI8, - IMG_UINT8 * psGetMaxPhysHeapCountOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT *psGetMaxPhysHeapCountIN = - (PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT *) IMG_OFFSET_ADDR(psGetMaxPhysHeapCountIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT *psGetMaxPhysHeapCountOUT = - (PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT *) IMG_OFFSET_ADDR(psGetMaxPhysHeapCountOUT_UI8, - 0); - - PVR_UNREFERENCED_PARAMETER(psGetMaxPhysHeapCountIN); - - psGetMaxPhysHeapCountOUT->eError = - PVRSRVGetMaxPhysHeapCountKM(psConnection, OSGetDevNode(psConnection), - &psGetMaxPhysHeapCountOUT->ui32PhysHeapCount); - - return 0; -} - -static_assert(PVRSRV_PHYS_HEAP_LAST <= IMG_UINT32_MAX, - "PVRSRV_PHYS_HEAP_LAST must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysHeapGetMemInfo(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysHeapGetMemInfoIN_UI8, - IMG_UINT8 * psPhysHeapGetMemInfoOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO *psPhysHeapGetMemInfoIN = - (PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO *) IMG_OFFSET_ADDR(psPhysHeapGetMemInfoIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO *psPhysHeapGetMemInfoOUT = - (PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO *) IMG_OFFSET_ADDR(psPhysHeapGetMemInfoOUT_UI8, - 0); - - PVRSRV_PHYS_HEAP *eaPhysHeapIDInt = NULL; - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStatsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP)) + - ((IMG_UINT64) psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS)) + - 0; - - if (unlikely(psPhysHeapGetMemInfoIN->ui32PhysHeapCount > PVRSRV_PHYS_HEAP_LAST)) - { - psPhysHeapGetMemInfoOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysHeapGetMemInfo_exit; - } - - psPhysHeapGetMemInfoOUT->pasapPhysHeapMemStats = - psPhysHeapGetMemInfoIN->pasapPhysHeapMemStats; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysHeapGetMemInfoOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysHeapGetMemInfo_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysHeapGetMemInfoIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysHeapGetMemInfoIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysHeapGetMemInfoOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysHeapGetMemInfo_exit; - } - } - } - - if (psPhysHeapGetMemInfoIN->ui32PhysHeapCount != 0) - { - eaPhysHeapIDInt = - (PVRSRV_PHYS_HEAP *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP); - } - - /* Copy the data over */ - if (psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP) > 0) - { - if (OSCopyFromUser - (NULL, eaPhysHeapIDInt, - (const void __user *)psPhysHeapGetMemInfoIN->peaPhysHeapID, - psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP)) != - PVRSRV_OK) - { - psPhysHeapGetMemInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysHeapGetMemInfo_exit; - } - } - if (psPhysHeapGetMemInfoIN->ui32PhysHeapCount != 0) - { - pasapPhysHeapMemStatsInt = - (PHYS_HEAP_MEM_STATS *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS); - } - - psPhysHeapGetMemInfoOUT->eError = - PVRSRVPhysHeapGetMemInfoKM(psConnection, OSGetDevNode(psConnection), - psPhysHeapGetMemInfoIN->ui32PhysHeapCount, - eaPhysHeapIDInt, pasapPhysHeapMemStatsInt); - /* Exit early if bridged call fails */ - if (unlikely(psPhysHeapGetMemInfoOUT->eError != PVRSRV_OK)) - { - goto PhysHeapGetMemInfo_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((pasapPhysHeapMemStatsInt) && - ((psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psPhysHeapGetMemInfoOUT->pasapPhysHeapMemStats, - pasapPhysHeapMemStatsInt, - (psPhysHeapGetMemInfoIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS))) != - PVRSRV_OK)) - { - psPhysHeapGetMemInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysHeapGetMemInfo_exit; - } - } - -PhysHeapGetMemInfo_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysHeapGetMemInfoOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeGetDefaultPhysicalHeap(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetDefaultPhysicalHeapIN_UI8, - IMG_UINT8 * psGetDefaultPhysicalHeapOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP *psGetDefaultPhysicalHeapIN = - (PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP *) - IMG_OFFSET_ADDR(psGetDefaultPhysicalHeapIN_UI8, 0); - PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP *psGetDefaultPhysicalHeapOUT = - (PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP *) - IMG_OFFSET_ADDR(psGetDefaultPhysicalHeapOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psGetDefaultPhysicalHeapIN); - - psGetDefaultPhysicalHeapOUT->eError = - PVRSRVGetDefaultPhysicalHeapKM(psConnection, OSGetDevNode(psConnection), - &psGetDefaultPhysicalHeapOUT->eHeap); - - return 0; -} - -static_assert(PVRSRV_PHYS_HEAP_LAST <= IMG_UINT32_MAX, - "PVRSRV_PHYS_HEAP_LAST must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeGetHeapPhysMemUsage(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetHeapPhysMemUsageIN_UI8, - IMG_UINT8 * psGetHeapPhysMemUsageOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE *psGetHeapPhysMemUsageIN = - (PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE *) IMG_OFFSET_ADDR(psGetHeapPhysMemUsageIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE *psGetHeapPhysMemUsageOUT = - (PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE *) IMG_OFFSET_ADDR(psGetHeapPhysMemUsageOUT_UI8, - 0); - - PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStatsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psGetHeapPhysMemUsageIN->ui32PhysHeapCount * - sizeof(PHYS_HEAP_MEM_STATS)) + 0; - - if (psGetHeapPhysMemUsageIN->ui32PhysHeapCount > PVRSRV_PHYS_HEAP_LAST) - { - psGetHeapPhysMemUsageOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto GetHeapPhysMemUsage_exit; - } - - psGetHeapPhysMemUsageOUT->pasapPhysHeapMemStats = - psGetHeapPhysMemUsageIN->pasapPhysHeapMemStats; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psGetHeapPhysMemUsageOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto GetHeapPhysMemUsage_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psGetHeapPhysMemUsageIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psGetHeapPhysMemUsageIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psGetHeapPhysMemUsageOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto GetHeapPhysMemUsage_exit; - } - } - } - - if (psGetHeapPhysMemUsageIN->ui32PhysHeapCount != 0) - { - pasapPhysHeapMemStatsInt = - (PHYS_HEAP_MEM_STATS *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psGetHeapPhysMemUsageIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS); - } - - psGetHeapPhysMemUsageOUT->eError = - PVRSRVGetHeapPhysMemUsageKM(psConnection, OSGetDevNode(psConnection), - psGetHeapPhysMemUsageIN->ui32PhysHeapCount, - pasapPhysHeapMemStatsInt); - /* Exit early if bridged call fails */ - if (unlikely(psGetHeapPhysMemUsageOUT->eError != PVRSRV_OK)) - { - goto GetHeapPhysMemUsage_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((pasapPhysHeapMemStatsInt) && - ((psGetHeapPhysMemUsageIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psGetHeapPhysMemUsageOUT->pasapPhysHeapMemStats, - pasapPhysHeapMemStatsInt, - (psGetHeapPhysMemUsageIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS))) != - PVRSRV_OK)) - { - psGetHeapPhysMemUsageOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto GetHeapPhysMemUsage_exit; - } - } - -GetHeapPhysMemUsage_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psGetHeapPhysMemUsageOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemGetFaultAddress(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemGetFaultAddressIN_UI8, - IMG_UINT8 * psDevmemGetFaultAddressOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS *psDevmemGetFaultAddressIN = - (PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS *) - IMG_OFFSET_ADDR(psDevmemGetFaultAddressIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS *psDevmemGetFaultAddressOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS *) - IMG_OFFSET_ADDR(psDevmemGetFaultAddressOUT_UI8, 0); - - IMG_HANDLE hDevmemCtx = psDevmemGetFaultAddressIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemGetFaultAddressOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemGetFaultAddressOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemGetFaultAddress_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemGetFaultAddressOUT->eError = - DevmemIntGetFaultAddress(psConnection, OSGetDevNode(psConnection), - psDevmemCtxInt, &psDevmemGetFaultAddressOUT->sFaultAddress); - -DevmemGetFaultAddress_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#if defined(PVRSRV_ENABLE_PROCESS_STATS) - -static IMG_INT -PVRSRVBridgePVRSRVUpdateOOMStats(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVUpdateOOMStatsIN_UI8, - IMG_UINT8 * psPVRSRVUpdateOOMStatsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS *psPVRSRVUpdateOOMStatsIN = - (PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS *) IMG_OFFSET_ADDR(psPVRSRVUpdateOOMStatsIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS *psPVRSRVUpdateOOMStatsOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS *) - IMG_OFFSET_ADDR(psPVRSRVUpdateOOMStatsOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - psPVRSRVUpdateOOMStatsOUT->eError = - PVRSRVServerUpdateOOMStats(psPVRSRVUpdateOOMStatsIN->ui32ui32StatType, - psPVRSRVUpdateOOMStatsIN->ui32pid); - - return 0; -} - -#else -#define PVRSRVBridgePVRSRVUpdateOOMStats NULL -#endif - -static_assert(PVRSRV_PHYS_HEAP_LAST <= IMG_UINT32_MAX, - "PVRSRV_PHYS_HEAP_LAST must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePhysHeapGetMemInfoPkd(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPhysHeapGetMemInfoPkdIN_UI8, - IMG_UINT8 * psPhysHeapGetMemInfoPkdOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFOPKD *psPhysHeapGetMemInfoPkdIN = - (PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFOPKD *) - IMG_OFFSET_ADDR(psPhysHeapGetMemInfoPkdIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFOPKD *psPhysHeapGetMemInfoPkdOUT = - (PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFOPKD *) - IMG_OFFSET_ADDR(psPhysHeapGetMemInfoPkdOUT_UI8, 0); - - PVRSRV_PHYS_HEAP *eaPhysHeapIDInt = NULL; - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStatsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP)) + - ((IMG_UINT64) psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * - sizeof(PHYS_HEAP_MEM_STATS_PKD)) + 0; - - if (unlikely(psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount > PVRSRV_PHYS_HEAP_LAST)) - { - psPhysHeapGetMemInfoPkdOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PhysHeapGetMemInfoPkd_exit; - } - - psPhysHeapGetMemInfoPkdOUT->psapPhysHeapMemStats = - psPhysHeapGetMemInfoPkdIN->psapPhysHeapMemStats; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPhysHeapGetMemInfoPkdOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PhysHeapGetMemInfoPkd_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPhysHeapGetMemInfoPkdIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPhysHeapGetMemInfoPkdIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPhysHeapGetMemInfoPkdOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PhysHeapGetMemInfoPkd_exit; - } - } - } - - if (psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount != 0) - { - eaPhysHeapIDInt = - (PVRSRV_PHYS_HEAP *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP); - } - - /* Copy the data over */ - if (psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP) > 0) - { - if (OSCopyFromUser - (NULL, eaPhysHeapIDInt, - (const void __user *)psPhysHeapGetMemInfoPkdIN->peaPhysHeapID, - psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PVRSRV_PHYS_HEAP)) != - PVRSRV_OK) - { - psPhysHeapGetMemInfoPkdOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysHeapGetMemInfoPkd_exit; - } - } - if (psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount != 0) - { - psapPhysHeapMemStatsInt = - (PHYS_HEAP_MEM_STATS_PKD *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS_PKD); - } - - psPhysHeapGetMemInfoPkdOUT->eError = - PVRSRVPhysHeapGetMemInfoPkdKM(psConnection, OSGetDevNode(psConnection), - psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount, - eaPhysHeapIDInt, psapPhysHeapMemStatsInt); - /* Exit early if bridged call fails */ - if (unlikely(psPhysHeapGetMemInfoPkdOUT->eError != PVRSRV_OK)) - { - goto PhysHeapGetMemInfoPkd_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((psapPhysHeapMemStatsInt) && - ((psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS_PKD)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psPhysHeapGetMemInfoPkdOUT->psapPhysHeapMemStats, - psapPhysHeapMemStatsInt, - (psPhysHeapGetMemInfoPkdIN->ui32PhysHeapCount * - sizeof(PHYS_HEAP_MEM_STATS_PKD))) != PVRSRV_OK)) - { - psPhysHeapGetMemInfoPkdOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PhysHeapGetMemInfoPkd_exit; - } - } - -PhysHeapGetMemInfoPkd_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPhysHeapGetMemInfoPkdOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(PVRSRV_PHYS_HEAP_LAST <= IMG_UINT32_MAX, - "PVRSRV_PHYS_HEAP_LAST must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeGetHeapPhysMemUsagePkd(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetHeapPhysMemUsagePkdIN_UI8, - IMG_UINT8 * psGetHeapPhysMemUsagePkdOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGEPKD *psGetHeapPhysMemUsagePkdIN = - (PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGEPKD *) - IMG_OFFSET_ADDR(psGetHeapPhysMemUsagePkdIN_UI8, 0); - PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGEPKD *psGetHeapPhysMemUsagePkdOUT = - (PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGEPKD *) - IMG_OFFSET_ADDR(psGetHeapPhysMemUsagePkdOUT_UI8, 0); - - PHYS_HEAP_MEM_STATS_PKD *psapPhysHeapMemStatsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount * - sizeof(PHYS_HEAP_MEM_STATS_PKD)) + 0; - - if (psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount > PVRSRV_PHYS_HEAP_LAST) - { - psGetHeapPhysMemUsagePkdOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto GetHeapPhysMemUsagePkd_exit; - } - - psGetHeapPhysMemUsagePkdOUT->psapPhysHeapMemStats = - psGetHeapPhysMemUsagePkdIN->psapPhysHeapMemStats; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psGetHeapPhysMemUsagePkdOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto GetHeapPhysMemUsagePkd_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psGetHeapPhysMemUsagePkdIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psGetHeapPhysMemUsagePkdIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psGetHeapPhysMemUsagePkdOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto GetHeapPhysMemUsagePkd_exit; - } - } - } - - if (psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount != 0) - { - psapPhysHeapMemStatsInt = - (PHYS_HEAP_MEM_STATS_PKD *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS_PKD); - } - - psGetHeapPhysMemUsagePkdOUT->eError = - PVRSRVGetHeapPhysMemUsagePkdKM(psConnection, OSGetDevNode(psConnection), - psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount, - psapPhysHeapMemStatsInt); - /* Exit early if bridged call fails */ - if (unlikely(psGetHeapPhysMemUsagePkdOUT->eError != PVRSRV_OK)) - { - goto GetHeapPhysMemUsagePkd_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((psapPhysHeapMemStatsInt) && - ((psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount * sizeof(PHYS_HEAP_MEM_STATS_PKD)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psGetHeapPhysMemUsagePkdOUT->psapPhysHeapMemStats, - psapPhysHeapMemStatsInt, - (psGetHeapPhysMemUsagePkdIN->ui32PhysHeapCount * - sizeof(PHYS_HEAP_MEM_STATS_PKD))) != PVRSRV_OK)) - { - psGetHeapPhysMemUsagePkdOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto GetHeapPhysMemUsagePkd_exit; - } - } - -GetHeapPhysMemUsagePkd_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psGetHeapPhysMemUsagePkdOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _DevmemXIntReserveRangepsReservationIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemXIntUnreserveRange((DEVMEMXINT_RESERVATION *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemXIntReserveRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemXIntReserveRangeIN_UI8, - IMG_UINT8 * psDevmemXIntReserveRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMXINTRESERVERANGE *psDevmemXIntReserveRangeIN = - (PVRSRV_BRIDGE_IN_DEVMEMXINTRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemXIntReserveRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMXINTRESERVERANGE *psDevmemXIntReserveRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMXINTRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemXIntReserveRangeOUT_UI8, 0); - - IMG_HANDLE hDevmemServerHeap = psDevmemXIntReserveRangeIN->hDevmemServerHeap; - DEVMEMINT_HEAP *psDevmemServerHeapInt = NULL; - DEVMEMXINT_RESERVATION *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemXIntReserveRangeOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerHeapInt, - hDevmemServerHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psDevmemXIntReserveRangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntReserveRange_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemXIntReserveRangeOUT->eError = - DevmemXIntReserveRange(psDevmemServerHeapInt, - psDevmemXIntReserveRangeIN->sAddress, - psDevmemXIntReserveRangeIN->uiLength, &psReservationInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemXIntReserveRangeOUT->eError != PVRSRV_OK)) - { - goto DevmemXIntReserveRange_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemXIntReserveRangeOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemXIntReserveRangeOUT-> - hReservation, - (void *)psReservationInt, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemXIntReserveRangepsReservationIntRelease); - if (unlikely(psDevmemXIntReserveRangeOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntReserveRange_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemXIntReserveRange_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemXIntReserveRangeOUT->eError != PVRSRV_OK) - { - if (psReservationInt) - { - DevmemXIntUnreserveRange(psReservationInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemXIntUnreserveRange(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemXIntUnreserveRangeIN_UI8, - IMG_UINT8 * psDevmemXIntUnreserveRangeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMXINTUNRESERVERANGE *psDevmemXIntUnreserveRangeIN = - (PVRSRV_BRIDGE_IN_DEVMEMXINTUNRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemXIntUnreserveRangeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMXINTUNRESERVERANGE *psDevmemXIntUnreserveRangeOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMXINTUNRESERVERANGE *) - IMG_OFFSET_ADDR(psDevmemXIntUnreserveRangeOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemXIntUnreserveRangeOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemXIntUnreserveRangeIN-> - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION); - if (unlikely - ((psDevmemXIntUnreserveRangeOUT->eError != PVRSRV_OK) - && (psDevmemXIntUnreserveRangeOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psDevmemXIntUnreserveRangeOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemXIntUnreserveRangeOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntUnreserveRange_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemXIntUnreserveRange_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemXIntMapPages(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemXIntMapPagesIN_UI8, - IMG_UINT8 * psDevmemXIntMapPagesOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMXINTMAPPAGES *psDevmemXIntMapPagesIN = - (PVRSRV_BRIDGE_IN_DEVMEMXINTMAPPAGES *) IMG_OFFSET_ADDR(psDevmemXIntMapPagesIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMXINTMAPPAGES *psDevmemXIntMapPagesOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMXINTMAPPAGES *) IMG_OFFSET_ADDR(psDevmemXIntMapPagesOUT_UI8, - 0); - - IMG_HANDLE hReservation = psDevmemXIntMapPagesIN->hReservation; - DEVMEMXINT_RESERVATION *psReservationInt = NULL; - IMG_HANDLE hPMR = psDevmemXIntMapPagesIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemXIntMapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION, IMG_TRUE); - if (unlikely(psDevmemXIntMapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntMapPages_exit; - } - - /* Look up the address from the handle */ - psDevmemXIntMapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemXIntMapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntMapPages_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemXIntMapPagesOUT->eError = - DevmemXIntMapPages(psReservationInt, - psPMRInt, - psDevmemXIntMapPagesIN->ui32PageCount, - psDevmemXIntMapPagesIN->ui32PhysPageOffset, - psDevmemXIntMapPagesIN->uiFlags, - psDevmemXIntMapPagesIN->ui32VirtPageOffset); - -DevmemXIntMapPages_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemXIntUnmapPages(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemXIntUnmapPagesIN_UI8, - IMG_UINT8 * psDevmemXIntUnmapPagesOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMXINTUNMAPPAGES *psDevmemXIntUnmapPagesIN = - (PVRSRV_BRIDGE_IN_DEVMEMXINTUNMAPPAGES *) IMG_OFFSET_ADDR(psDevmemXIntUnmapPagesIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_DEVMEMXINTUNMAPPAGES *psDevmemXIntUnmapPagesOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMXINTUNMAPPAGES *) - IMG_OFFSET_ADDR(psDevmemXIntUnmapPagesOUT_UI8, 0); - - IMG_HANDLE hReservation = psDevmemXIntUnmapPagesIN->hReservation; - DEVMEMXINT_RESERVATION *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemXIntUnmapPagesOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION, IMG_TRUE); - if (unlikely(psDevmemXIntUnmapPagesOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemXIntUnmapPages_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemXIntUnmapPagesOUT->eError = - DevmemXIntUnmapPages(psReservationInt, - psDevmemXIntUnmapPagesIN->ui32VirtPageOffset, - psDevmemXIntUnmapPagesIN->ui32PageCount); - -DevmemXIntUnmapPages_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMXINT_RESERVATION); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); -static_assert(PMR_MAX_SUPPORTED_PAGE_COUNT <= IMG_UINT32_MAX, - "PMR_MAX_SUPPORTED_PAGE_COUNT must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeChangeSparseMem2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psChangeSparseMem2IN_UI8, - IMG_UINT8 * psChangeSparseMem2OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CHANGESPARSEMEM2 *psChangeSparseMem2IN = - (PVRSRV_BRIDGE_IN_CHANGESPARSEMEM2 *) IMG_OFFSET_ADDR(psChangeSparseMem2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM2 *psChangeSparseMem2OUT = - (PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM2 *) IMG_OFFSET_ADDR(psChangeSparseMem2OUT_UI8, 0); - - IMG_HANDLE hSrvDevMemHeap = psChangeSparseMem2IN->hSrvDevMemHeap; - DEVMEMINT_HEAP *psSrvDevMemHeapInt = NULL; - IMG_HANDLE hPMR = psChangeSparseMem2IN->hPMR; - PMR *psPMRInt = NULL; - IMG_UINT32 *ui32AllocPageIndicesInt = NULL; - IMG_UINT32 *ui32FreePageIndicesInt = NULL; - IMG_HANDLE hReservation = psChangeSparseMem2IN->hReservation; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psChangeSparseMem2IN->ui32AllocPageCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psChangeSparseMem2IN->ui32FreePageCount * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psChangeSparseMem2IN->ui32AllocPageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto ChangeSparseMem2_exit; - } - - if (unlikely(psChangeSparseMem2IN->ui32FreePageCount > PMR_MAX_SUPPORTED_PAGE_COUNT)) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto ChangeSparseMem2_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto ChangeSparseMem2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psChangeSparseMem2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psChangeSparseMem2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ChangeSparseMem2_exit; - } - } - } - - if (psChangeSparseMem2IN->ui32AllocPageCount != 0) - { - ui32AllocPageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psChangeSparseMem2IN->ui32AllocPageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psChangeSparseMem2IN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32AllocPageIndicesInt, - (const void __user *)psChangeSparseMem2IN->pui32AllocPageIndices, - psChangeSparseMem2IN->ui32AllocPageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto ChangeSparseMem2_exit; - } - } - if (psChangeSparseMem2IN->ui32FreePageCount != 0) - { - ui32FreePageIndicesInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psChangeSparseMem2IN->ui32FreePageCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psChangeSparseMem2IN->ui32FreePageCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32FreePageIndicesInt, - (const void __user *)psChangeSparseMem2IN->pui32FreePageIndices, - psChangeSparseMem2IN->ui32FreePageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psChangeSparseMem2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto ChangeSparseMem2_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psChangeSparseMem2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSrvDevMemHeapInt, - hSrvDevMemHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psChangeSparseMem2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto ChangeSparseMem2_exit; - } - - /* Look up the address from the handle */ - psChangeSparseMem2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psChangeSparseMem2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto ChangeSparseMem2_exit; - } - - /* Look up the address from the handle */ - psChangeSparseMem2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, IMG_TRUE); - if (unlikely(psChangeSparseMem2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto ChangeSparseMem2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psChangeSparseMem2OUT->eError = - DevmemIntChangeSparse2(psSrvDevMemHeapInt, - psPMRInt, - psChangeSparseMem2IN->ui32AllocPageCount, - ui32AllocPageIndicesInt, - psChangeSparseMem2IN->ui32FreePageCount, - ui32FreePageIndicesInt, - psChangeSparseMem2IN->ui32SparseFlags, - psReservationInt, psChangeSparseMem2IN->ui64CPUVAddr); - -ChangeSparseMem2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSrvDevMemHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSrvDevMemHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psChangeSparseMem2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _DevmemIntReserveRange2psReservationIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = DevmemIntUnreserveRangeAndUnmapPMR2((DEVMEMINT_RESERVATION2 *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeDevmemIntReserveRange2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntReserveRange2IN_UI8, - IMG_UINT8 * psDevmemIntReserveRange2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE2 *psDevmemIntReserveRange2IN = - (PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE2 *) - IMG_OFFSET_ADDR(psDevmemIntReserveRange2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE2 *psDevmemIntReserveRange2OUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE2 *) - IMG_OFFSET_ADDR(psDevmemIntReserveRange2OUT_UI8, 0); - - IMG_HANDLE hDevmemServerHeap = psDevmemIntReserveRange2IN->hDevmemServerHeap; - DEVMEMINT_HEAP *psDevmemServerHeapInt = NULL; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntReserveRange2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerHeapInt, - hDevmemServerHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psDevmemIntReserveRange2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntReserveRange2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntReserveRange2OUT->eError = - DevmemIntReserveRange2(psDevmemServerHeapInt, - psDevmemIntReserveRange2IN->sAddress, - psDevmemIntReserveRange2IN->uiLength, - psDevmemIntReserveRange2IN->uiFlags, &psReservationInt); - /* Exit early if bridged call fails */ - if (unlikely(psDevmemIntReserveRange2OUT->eError != PVRSRV_OK)) - { - goto DevmemIntReserveRange2_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntReserveRange2OUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psDevmemIntReserveRange2OUT-> - hReservation, - (void *)psReservationInt, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _DevmemIntReserveRange2psReservationIntRelease); - if (unlikely(psDevmemIntReserveRange2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntReserveRange2_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntReserveRange2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psDevmemIntReserveRange2OUT->eError != PVRSRV_OK) - { - if (psReservationInt) - { - DevmemIntUnreserveRangeAndUnmapPMR2(psReservationInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnreserveRange2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnreserveRange2IN_UI8, - IMG_UINT8 * psDevmemIntUnreserveRange2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE2 *psDevmemIntUnreserveRange2IN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE2 *) - IMG_OFFSET_ADDR(psDevmemIntUnreserveRange2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE2 *psDevmemIntUnreserveRange2OUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE2 *) - IMG_OFFSET_ADDR(psDevmemIntUnreserveRange2OUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psDevmemIntUnreserveRange2OUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psDevmemIntUnreserveRange2IN-> - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - if (unlikely - ((psDevmemIntUnreserveRange2OUT->eError != PVRSRV_OK) - && (psDevmemIntUnreserveRange2OUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psDevmemIntUnreserveRange2OUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psDevmemIntUnreserveRange2OUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnreserveRange2_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -DevmemIntUnreserveRange2_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntMapPMR2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntMapPMR2IN_UI8, - IMG_UINT8 * psDevmemIntMapPMR2OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR2 *psDevmemIntMapPMR2IN = - (PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR2 *) IMG_OFFSET_ADDR(psDevmemIntMapPMR2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR2 *psDevmemIntMapPMR2OUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR2 *) IMG_OFFSET_ADDR(psDevmemIntMapPMR2OUT_UI8, 0); - - IMG_HANDLE hDevmemServerHeap = psDevmemIntMapPMR2IN->hDevmemServerHeap; - DEVMEMINT_HEAP *psDevmemServerHeapInt = NULL; - IMG_HANDLE hReservation = psDevmemIntMapPMR2IN->hReservation; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - IMG_HANDLE hPMR = psDevmemIntMapPMR2IN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntMapPMR2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerHeapInt, - hDevmemServerHeap, - PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP, IMG_TRUE); - if (unlikely(psDevmemIntMapPMR2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR2_exit; - } - - /* Look up the address from the handle */ - psDevmemIntMapPMR2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, IMG_TRUE); - if (unlikely(psDevmemIntMapPMR2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR2_exit; - } - - /* Look up the address from the handle */ - psDevmemIntMapPMR2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psDevmemIntMapPMR2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntMapPMR2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntMapPMR2OUT->eError = - DevmemIntMapPMR2(psDevmemServerHeapInt, psReservationInt, psPMRInt); - -DevmemIntMapPMR2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerHeapInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerHeap, PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP); - } - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDevmemIntUnmapPMR2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntUnmapPMR2IN_UI8, - IMG_UINT8 * psDevmemIntUnmapPMR2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR2 *psDevmemIntUnmapPMR2IN = - (PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR2 *) IMG_OFFSET_ADDR(psDevmemIntUnmapPMR2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR2 *psDevmemIntUnmapPMR2OUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR2 *) IMG_OFFSET_ADDR(psDevmemIntUnmapPMR2OUT_UI8, - 0); - - IMG_HANDLE hReservation = psDevmemIntUnmapPMR2IN->hReservation; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntUnmapPMR2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, IMG_TRUE); - if (unlikely(psDevmemIntUnmapPMR2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntUnmapPMR2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntUnmapPMR2OUT->eError = DevmemIntUnmapPMR2(psReservationInt); - -DevmemIntUnmapPMR2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitMMBridge(void); -void DeinitMMBridge(void); - -/* - * Register all MM functions with services - */ -PVRSRV_ERROR InitMMBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMREXPORTPMR, - PVRSRVBridgePMRExportPMR, NULL, sizeof(PVRSRV_BRIDGE_IN_PMREXPORTPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMREXPORTPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR, - PVRSRVBridgePMRUnexportPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRGETUID, PVRSRVBridgePMRGetUID, - NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRGETUID), - sizeof(PVRSRV_BRIDGE_OUT_PMRGETUID)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRMAKELOCALIMPORTHANDLE, - PVRSRVBridgePMRMakeLocalImportHandle, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE), - sizeof(PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNMAKELOCALIMPORTHANDLE, - PVRSRVBridgePMRUnmakeLocalImportHandle, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE), - sizeof(PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRIMPORTPMR, - PVRSRVBridgePMRImportPMR, NULL, sizeof(PVRSRV_BRIDGE_IN_PMRIMPORTPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMRIMPORTPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR, - PVRSRVBridgePMRLocalImportPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNREFPMR, - PVRSRVBridgePMRUnrefPMR, NULL, sizeof(PVRSRV_BRIDGE_IN_PMRUNREFPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMRUNREFPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNREFUNLOCKPMR, - PVRSRVBridgePMRUnrefUnlockPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR), - sizeof(PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR, - PVRSRVBridgePhysmemNewRamBackedPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDLOCKEDPMR, - PVRSRVBridgePhysmemNewRamBackedLockedPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR), - sizeof(PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTPIN, - PVRSRVBridgeDevmemIntPin, NULL, sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTPIN), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTPIN)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNPIN, - PVRSRVBridgeDevmemIntUnpin, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTPINVALIDATE, - PVRSRVBridgeDevmemIntPinValidate, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNPININVALIDATE, - PVRSRVBridgeDevmemIntUnpinInvalidate, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE, - PVRSRVBridgeDevmemIntCtxCreate, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY, - PVRSRVBridgeDevmemIntCtxDestroy, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE, - PVRSRVBridgeDevmemIntHeapCreate, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY, - PVRSRVBridgeDevmemIntHeapDestroy, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR, - PVRSRVBridgeDevmemIntMapPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR, - PVRSRVBridgeDevmemIntUnmapPMR, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE, - PVRSRVBridgeDevmemIntReserveRange, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE, - PVRSRVBridgeDevmemIntUnreserveRange, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_CHANGESPARSEMEM, - PVRSRVBridgeChangeSparseMem, NULL, - sizeof(PVRSRV_BRIDGE_IN_CHANGESPARSEMEM), - sizeof(PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPAGES, - PVRSRVBridgeDevmemIntMapPages, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES, - PVRSRVBridgeDevmemIntUnmapPages, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID, - PVRSRVBridgeDevmemIsVDevAddrValid, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMFLUSHDEVSLCRANGE, - PVRSRVBridgeDevmemFlushDevSLCRange, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINVALIDATEFBSCTABLE, - PVRSRVBridgeDevmemInvalidateFBSCTable, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT, - PVRSRVBridgeHeapCfgHeapConfigCount, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT, - PVRSRVBridgeHeapCfgHeapCount, NULL, - sizeof(PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT), - sizeof(PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME, - PVRSRVBridgeHeapCfgHeapConfigName, NULL, - sizeof(PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME), - sizeof(PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS, - PVRSRVBridgeHeapCfgHeapDetails, NULL, - sizeof(PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS), - sizeof(PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM, - PVRSRVBridgeDevmemIntRegisterPFNotifyKM, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETMAXPHYSHEAPCOUNT, - PVRSRVBridgeGetMaxPhysHeapCount, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFO, - PVRSRVBridgePhysHeapGetMemInfo, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO), - sizeof(PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETDEFAULTPHYSICALHEAP, - PVRSRVBridgeGetDefaultPhysicalHeap, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGE, - PVRSRVBridgeGetHeapPhysMemUsage, NULL, - sizeof(PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE), - sizeof(PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMGETFAULTADDRESS, - PVRSRVBridgeDevmemGetFaultAddress, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PVRSRVUPDATEOOMSTATS, - PVRSRVBridgePVRSRVUpdateOOMStats, NULL, - sizeof(PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS), - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFOPKD, - PVRSRVBridgePhysHeapGetMemInfoPkd, NULL, - sizeof(PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFOPKD), - sizeof(PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFOPKD)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGEPKD, - PVRSRVBridgeGetHeapPhysMemUsagePkd, NULL, - sizeof(PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGEPKD), - sizeof(PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGEPKD)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTRESERVERANGE, - PVRSRVBridgeDevmemXIntReserveRange, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMXINTRESERVERANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMXINTRESERVERANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTUNRESERVERANGE, - PVRSRVBridgeDevmemXIntUnreserveRange, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMXINTUNRESERVERANGE), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMXINTUNRESERVERANGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTMAPPAGES, - PVRSRVBridgeDevmemXIntMapPages, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMXINTMAPPAGES), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMXINTMAPPAGES)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTUNMAPPAGES, - PVRSRVBridgeDevmemXIntUnmapPages, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMXINTUNMAPPAGES), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMXINTUNMAPPAGES)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_CHANGESPARSEMEM2, - PVRSRVBridgeChangeSparseMem2, NULL, - sizeof(PVRSRV_BRIDGE_IN_CHANGESPARSEMEM2), - sizeof(PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE2, - PVRSRVBridgeDevmemIntReserveRange2, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE2), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE2, - PVRSRVBridgeDevmemIntUnreserveRange2, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE2), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR2, - PVRSRVBridgeDevmemIntMapPMR2, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR2), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR2, - PVRSRVBridgeDevmemIntUnmapPMR2, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR2), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR2)); - - return PVRSRV_OK; -} - -/* - * Unregister all mm functions with services - */ -void DeinitMMBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMREXPORTPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRGETUID); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRMAKELOCALIMPORTHANDLE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNMAKELOCALIMPORTHANDLE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRIMPORTPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNREFPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNREFUNLOCKPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDLOCKEDPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTPIN); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNPIN); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTPINVALIDATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNPININVALIDATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_CHANGESPARSEMEM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPAGES); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMFLUSHDEVSLCRANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINVALIDATEFBSCTABLE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETMAXPHYSHEAPCOUNT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFO); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETDEFAULTPHYSICALHEAP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMGETFAULTADDRESS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PVRSRVUPDATEOOMSTATS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFOPKD); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGEPKD); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTRESERVERANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTUNRESERVERANGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTMAPPAGES); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMXINTUNMAPPAGES); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_CHANGESPARSEMEM2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR2); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_pdump_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_pdump_bridge.c deleted file mode 100644 index 1c3cab4831524..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_pdump_bridge.c +++ /dev/null @@ -1,595 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for pdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for pdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "devicemem_server.h" -#include "pdump_km.h" - -#include "common_pdump_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static_assert(PVRSRV_PDUMP_MAX_FILENAME_SIZE <= IMG_UINT32_MAX, - "PVRSRV_PDUMP_MAX_FILENAME_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(4 <= IMG_UINT32_MAX, "4 must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePDumpImageDescriptor(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpImageDescriptorIN_UI8, - IMG_UINT8 * psPDumpImageDescriptorOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPIMAGEDESCRIPTOR *psPDumpImageDescriptorIN = - (PVRSRV_BRIDGE_IN_PDUMPIMAGEDESCRIPTOR *) IMG_OFFSET_ADDR(psPDumpImageDescriptorIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PDUMPIMAGEDESCRIPTOR *psPDumpImageDescriptorOUT = - (PVRSRV_BRIDGE_OUT_PDUMPIMAGEDESCRIPTOR *) - IMG_OFFSET_ADDR(psPDumpImageDescriptorOUT_UI8, 0); - - IMG_HANDLE hDevmemCtx = psPDumpImageDescriptorIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - IMG_CHAR *uiFileNameInt = NULL; - IMG_UINT32 *ui32FBCClearColourInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPDumpImageDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) + - ((IMG_UINT64) 4 * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psPDumpImageDescriptorIN->ui32StringSize > PVRSRV_PDUMP_MAX_FILENAME_SIZE)) - { - psPDumpImageDescriptorOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PDumpImageDescriptor_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPDumpImageDescriptorOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PDumpImageDescriptor_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPDumpImageDescriptorIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPDumpImageDescriptorIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPDumpImageDescriptorOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PDumpImageDescriptor_exit; - } - } - } - - if (psPDumpImageDescriptorIN->ui32StringSize != 0) - { - uiFileNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPDumpImageDescriptorIN->ui32StringSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPDumpImageDescriptorIN->ui32StringSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiFileNameInt, - (const void __user *)psPDumpImageDescriptorIN->puiFileName, - psPDumpImageDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPDumpImageDescriptorOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PDumpImageDescriptor_exit; - } - ((IMG_CHAR *) - uiFileNameInt)[(psPDumpImageDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - { - ui32FBCClearColourInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += 4 * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (4 * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32FBCClearColourInt, - (const void __user *)psPDumpImageDescriptorIN->pui32FBCClearColour, - 4 * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psPDumpImageDescriptorOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PDumpImageDescriptor_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPDumpImageDescriptorOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psPDumpImageDescriptorOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PDumpImageDescriptor_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPDumpImageDescriptorOUT->eError = - DevmemIntPDumpImageDescriptor(psConnection, OSGetDevNode(psConnection), - psDevmemCtxInt, - psPDumpImageDescriptorIN->ui32StringSize, - uiFileNameInt, - psPDumpImageDescriptorIN->sDataDevAddr, - psPDumpImageDescriptorIN->ui32DataSize, - psPDumpImageDescriptorIN->ui32LogicalWidth, - psPDumpImageDescriptorIN->ui32LogicalHeight, - psPDumpImageDescriptorIN->ui32PhysicalWidth, - psPDumpImageDescriptorIN->ui32PhysicalHeight, - psPDumpImageDescriptorIN->ePixelFormat, - psPDumpImageDescriptorIN->eMemLayout, - psPDumpImageDescriptorIN->eFBCompression, - ui32FBCClearColourInt, - psPDumpImageDescriptorIN->eeFBCSwizzle, - psPDumpImageDescriptorIN->sHeaderDevAddr, - psPDumpImageDescriptorIN->ui32HeaderSize, - psPDumpImageDescriptorIN->ui32PDumpFlags); - -PDumpImageDescriptor_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPDumpImageDescriptorOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(PVRSRV_PDUMP_MAX_COMMENT_SIZE <= IMG_UINT32_MAX, - "PVRSRV_PDUMP_MAX_COMMENT_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePVRSRVPDumpComment(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpCommentIN_UI8, - IMG_UINT8 * psPVRSRVPDumpCommentOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT *psPVRSRVPDumpCommentIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT *) IMG_OFFSET_ADDR(psPVRSRVPDumpCommentIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT *psPVRSRVPDumpCommentOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT *) IMG_OFFSET_ADDR(psPVRSRVPDumpCommentOUT_UI8, - 0); - - IMG_CHAR *uiCommentInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPVRSRVPDumpCommentIN->ui32CommentSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPVRSRVPDumpCommentIN->ui32CommentSize > PVRSRV_PDUMP_MAX_COMMENT_SIZE)) - { - psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PVRSRVPDumpComment_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PVRSRVPDumpComment_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPVRSRVPDumpCommentIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPVRSRVPDumpCommentIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PVRSRVPDumpComment_exit; - } - } - } - - if (psPVRSRVPDumpCommentIN->ui32CommentSize != 0) - { - uiCommentInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPVRSRVPDumpCommentIN->ui32CommentSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPVRSRVPDumpCommentIN->ui32CommentSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiCommentInt, (const void __user *)psPVRSRVPDumpCommentIN->puiComment, - psPVRSRVPDumpCommentIN->ui32CommentSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PVRSRVPDumpComment_exit; - } - ((IMG_CHAR *) - uiCommentInt)[(psPVRSRVPDumpCommentIN->ui32CommentSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psPVRSRVPDumpCommentOUT->eError = - PDumpCommentKM(psConnection, OSGetDevNode(psConnection), - psPVRSRVPDumpCommentIN->ui32CommentSize, - uiCommentInt, psPVRSRVPDumpCommentIN->ui32Flags); - -PVRSRVPDumpComment_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPVRSRVPDumpCommentOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgePVRSRVPDumpSetFrame(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpSetFrameIN_UI8, - IMG_UINT8 * psPVRSRVPDumpSetFrameOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME *psPVRSRVPDumpSetFrameIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME *) IMG_OFFSET_ADDR(psPVRSRVPDumpSetFrameIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME *psPVRSRVPDumpSetFrameOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME *) IMG_OFFSET_ADDR(psPVRSRVPDumpSetFrameOUT_UI8, - 0); - - psPVRSRVPDumpSetFrameOUT->eError = - PDumpSetFrameKM(psConnection, OSGetDevNode(psConnection), - psPVRSRVPDumpSetFrameIN->ui32Frame); - - return 0; -} - -static_assert(PVRSRV_PDUMP_MAX_FILENAME_SIZE <= IMG_UINT32_MAX, - "PVRSRV_PDUMP_MAX_FILENAME_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePDumpDataDescriptor(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpDataDescriptorIN_UI8, - IMG_UINT8 * psPDumpDataDescriptorOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPDATADESCRIPTOR *psPDumpDataDescriptorIN = - (PVRSRV_BRIDGE_IN_PDUMPDATADESCRIPTOR *) IMG_OFFSET_ADDR(psPDumpDataDescriptorIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PDUMPDATADESCRIPTOR *psPDumpDataDescriptorOUT = - (PVRSRV_BRIDGE_OUT_PDUMPDATADESCRIPTOR *) IMG_OFFSET_ADDR(psPDumpDataDescriptorOUT_UI8, - 0); - - IMG_HANDLE hDevmemCtx = psPDumpDataDescriptorIN->hDevmemCtx; - DEVMEMINT_CTX *psDevmemCtxInt = NULL; - IMG_CHAR *uiFileNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPDumpDataDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPDumpDataDescriptorIN->ui32StringSize > PVRSRV_PDUMP_MAX_FILENAME_SIZE)) - { - psPDumpDataDescriptorOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PDumpDataDescriptor_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPDumpDataDescriptorOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PDumpDataDescriptor_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPDumpDataDescriptorIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPDumpDataDescriptorIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPDumpDataDescriptorOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PDumpDataDescriptor_exit; - } - } - } - - if (psPDumpDataDescriptorIN->ui32StringSize != 0) - { - uiFileNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPDumpDataDescriptorIN->ui32StringSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPDumpDataDescriptorIN->ui32StringSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiFileNameInt, (const void __user *)psPDumpDataDescriptorIN->puiFileName, - psPDumpDataDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPDumpDataDescriptorOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PDumpDataDescriptor_exit; - } - ((IMG_CHAR *) - uiFileNameInt)[(psPDumpDataDescriptorIN->ui32StringSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPDumpDataDescriptorOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemCtxInt, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psPDumpDataDescriptorOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PDumpDataDescriptor_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPDumpDataDescriptorOUT->eError = - DevmemIntPDumpDataDescriptor(psConnection, OSGetDevNode(psConnection), - psDevmemCtxInt, - psPDumpDataDescriptorIN->ui32StringSize, - uiFileNameInt, - psPDumpDataDescriptorIN->sDataDevAddr, - psPDumpDataDescriptorIN->ui32DataSize, - psPDumpDataDescriptorIN->ui32HeaderType, - psPDumpDataDescriptorIN->ui32ElementType, - psPDumpDataDescriptorIN->ui32ElementCount, - psPDumpDataDescriptorIN->ui32PDumpFlags); - -PDumpDataDescriptor_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemCtxInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemCtx, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPDumpDataDescriptorOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitPDUMPBridge(void); -void DeinitPDUMPBridge(void); - -/* - * Register all PDUMP functions with services - */ -PVRSRV_ERROR InitPDUMPBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PDUMPIMAGEDESCRIPTOR, - PVRSRVBridgePDumpImageDescriptor, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPIMAGEDESCRIPTOR), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPIMAGEDESCRIPTOR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPCOMMENT, - PVRSRVBridgePVRSRVPDumpComment, NULL, - sizeof(PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT), - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPSETFRAME, - PVRSRVBridgePVRSRVPDumpSetFrame, NULL, - sizeof(PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME), - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PDUMPDATADESCRIPTOR, - PVRSRVBridgePDumpDataDescriptor, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPDATADESCRIPTOR), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPDATADESCRIPTOR)); - - return PVRSRV_OK; -} - -/* - * Unregister all pdump functions with services - */ -void DeinitPDUMPBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PDUMPIMAGEDESCRIPTOR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPCOMMENT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPSETFRAME); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PDUMPDATADESCRIPTOR); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_pdumpctrl_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_pdumpctrl_bridge.c deleted file mode 100644 index f4e7d43b9bc00..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_pdumpctrl_bridge.c +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for pdumpctrl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for pdumpctrl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "pdump_km.h" - -#include "common_pdumpctrl_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#include "lock.h" - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgePVRSRVPDumpGetState(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpGetStateIN_UI8, - IMG_UINT8 * psPVRSRVPDumpGetStateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETSTATE *psPVRSRVPDumpGetStateIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETSTATE *) IMG_OFFSET_ADDR(psPVRSRVPDumpGetStateIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETSTATE *psPVRSRVPDumpGetStateOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETSTATE *) IMG_OFFSET_ADDR(psPVRSRVPDumpGetStateOUT_UI8, - 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpGetStateIN); - - psPVRSRVPDumpGetStateOUT->eError = PDumpGetStateKM(&psPVRSRVPDumpGetStateOUT->ui64State); - - return 0; -} - -static IMG_INT -PVRSRVBridgePVRSRVPDumpGetFrame(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpGetFrameIN_UI8, - IMG_UINT8 * psPVRSRVPDumpGetFrameOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME *psPVRSRVPDumpGetFrameIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME *) IMG_OFFSET_ADDR(psPVRSRVPDumpGetFrameIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME *psPVRSRVPDumpGetFrameOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME *) IMG_OFFSET_ADDR(psPVRSRVPDumpGetFrameOUT_UI8, - 0); - - PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpGetFrameIN); - - psPVRSRVPDumpGetFrameOUT->eError = - PDumpGetFrameKM(psConnection, OSGetDevNode(psConnection), - &psPVRSRVPDumpGetFrameOUT->ui32Frame); - - return 0; -} - -static IMG_INT -PVRSRVBridgePVRSRVPDumpSetDefaultCaptureParams(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * - psPVRSRVPDumpSetDefaultCaptureParamsIN_UI8, - IMG_UINT8 * - psPVRSRVPDumpSetDefaultCaptureParamsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *psPVRSRVPDumpSetDefaultCaptureParamsIN - = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *) - IMG_OFFSET_ADDR(psPVRSRVPDumpSetDefaultCaptureParamsIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS - *psPVRSRVPDumpSetDefaultCaptureParamsOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *) - IMG_OFFSET_ADDR(psPVRSRVPDumpSetDefaultCaptureParamsOUT_UI8, 0); - - psPVRSRVPDumpSetDefaultCaptureParamsOUT->eError = - PDumpSetDefaultCaptureParamsKM(psConnection, OSGetDevNode(psConnection), - psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Mode, - psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Start, - psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32End, - psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Interval, - psPVRSRVPDumpSetDefaultCaptureParamsIN-> - ui32MaxParamFileSize); - - return 0; -} - -static IMG_INT -PVRSRVBridgePVRSRVPDumpIsLastCaptureFrame(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpIsLastCaptureFrameIN_UI8, - IMG_UINT8 * psPVRSRVPDumpIsLastCaptureFrameOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME *psPVRSRVPDumpIsLastCaptureFrameIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME *) - IMG_OFFSET_ADDR(psPVRSRVPDumpIsLastCaptureFrameIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME *psPVRSRVPDumpIsLastCaptureFrameOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME *) - IMG_OFFSET_ADDR(psPVRSRVPDumpIsLastCaptureFrameOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpIsLastCaptureFrameIN); - - psPVRSRVPDumpIsLastCaptureFrameOUT->eError = - PDumpIsLastCaptureFrameKM(&psPVRSRVPDumpIsLastCaptureFrameOUT->bpbIsLastCaptureFrame); - - return 0; -} - -static IMG_INT -PVRSRVBridgePVRSRVPDumpForceCaptureStop(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPVRSRVPDumpForceCaptureStopIN_UI8, - IMG_UINT8 * psPVRSRVPDumpForceCaptureStopOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PVRSRVPDUMPFORCECAPTURESTOP *psPVRSRVPDumpForceCaptureStopIN = - (PVRSRV_BRIDGE_IN_PVRSRVPDUMPFORCECAPTURESTOP *) - IMG_OFFSET_ADDR(psPVRSRVPDumpForceCaptureStopIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PVRSRVPDUMPFORCECAPTURESTOP *psPVRSRVPDumpForceCaptureStopOUT = - (PVRSRV_BRIDGE_OUT_PVRSRVPDUMPFORCECAPTURESTOP *) - IMG_OFFSET_ADDR(psPVRSRVPDumpForceCaptureStopOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpForceCaptureStopIN); - - psPVRSRVPDumpForceCaptureStopOUT->eError = - PDumpForceCaptureStopKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -static POS_LOCK pPDUMPCTRLBridgeLock; - -PVRSRV_ERROR InitPDUMPCTRLBridge(void); -void DeinitPDUMPCTRLBridge(void); - -/* - * Register all PDUMPCTRL functions with services - */ -PVRSRV_ERROR InitPDUMPCTRLBridge(void) -{ - PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&pPDUMPCTRLBridgeLock), "OSLockCreate"); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETSTATE, - PVRSRVBridgePVRSRVPDumpGetState, pPDUMPCTRLBridgeLock, 0, - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETSTATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETFRAME, - PVRSRVBridgePVRSRVPDumpGetFrame, pPDUMPCTRLBridgeLock, 0, - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS, - PVRSRVBridgePVRSRVPDumpSetDefaultCaptureParams, pPDUMPCTRLBridgeLock, - sizeof(PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS), - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISLASTCAPTUREFRAME, - PVRSRVBridgePVRSRVPDumpIsLastCaptureFrame, pPDUMPCTRLBridgeLock, 0, - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPFORCECAPTURESTOP, - PVRSRVBridgePVRSRVPDumpForceCaptureStop, pPDUMPCTRLBridgeLock, 0, - sizeof(PVRSRV_BRIDGE_OUT_PVRSRVPDUMPFORCECAPTURESTOP)); - - return PVRSRV_OK; -} - -/* - * Unregister all pdumpctrl functions with services - */ -void DeinitPDUMPCTRLBridge(void) -{ - OSLockDestroy(pPDUMPCTRLBridgeLock); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETSTATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETFRAME); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISLASTCAPTUREFRAME); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, - PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPFORCECAPTURESTOP); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_pdumpmm_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_pdumpmm_bridge.c deleted file mode 100644 index adb6c3e6db70f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_pdumpmm_bridge.c +++ /dev/null @@ -1,981 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for pdumpmm -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for pdumpmm -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "devicemem_server.h" -#include "pmr.h" -#include "physmem.h" -#include "pdump_physmem.h" - -#include "common_pdumpmm_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgePMRPDumpLoadMem(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpLoadMemIN_UI8, - IMG_UINT8 * psPMRPDumpLoadMemOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM *psPMRPDumpLoadMemIN = - (PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM *) IMG_OFFSET_ADDR(psPMRPDumpLoadMemIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM *psPMRPDumpLoadMemOUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM *) IMG_OFFSET_ADDR(psPMRPDumpLoadMemOUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpLoadMemIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpLoadMemOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpLoadMemOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpLoadMem_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpLoadMemOUT->eError = - PMRPDumpLoadMem(psPMRInt, - psPMRPDumpLoadMemIN->uiOffset, - psPMRPDumpLoadMemIN->uiSize, - psPMRPDumpLoadMemIN->ui32PDumpFlags, psPMRPDumpLoadMemIN->bbZero); - -PMRPDumpLoadMem_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRPDumpLoadMemValue32(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpLoadMemValue32IN_UI8, - IMG_UINT8 * psPMRPDumpLoadMemValue32OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32IN = - (PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32 *) - IMG_OFFSET_ADDR(psPMRPDumpLoadMemValue32IN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32OUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32 *) - IMG_OFFSET_ADDR(psPMRPDumpLoadMemValue32OUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpLoadMemValue32IN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpLoadMemValue32OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpLoadMemValue32OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpLoadMemValue32_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpLoadMemValue32OUT->eError = - PMRPDumpLoadMemValue32(psPMRInt, - psPMRPDumpLoadMemValue32IN->uiOffset, - psPMRPDumpLoadMemValue32IN->ui32Value, - psPMRPDumpLoadMemValue32IN->ui32PDumpFlags); - -PMRPDumpLoadMemValue32_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRPDumpLoadMemValue64(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpLoadMemValue64IN_UI8, - IMG_UINT8 * psPMRPDumpLoadMemValue64OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64IN = - (PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64 *) - IMG_OFFSET_ADDR(psPMRPDumpLoadMemValue64IN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64OUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64 *) - IMG_OFFSET_ADDR(psPMRPDumpLoadMemValue64OUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpLoadMemValue64IN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpLoadMemValue64OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpLoadMemValue64OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpLoadMemValue64_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpLoadMemValue64OUT->eError = - PMRPDumpLoadMemValue64(psPMRInt, - psPMRPDumpLoadMemValue64IN->uiOffset, - psPMRPDumpLoadMemValue64IN->ui64Value, - psPMRPDumpLoadMemValue64IN->ui32PDumpFlags); - -PMRPDumpLoadMemValue64_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_PDUMP_MAX_FILENAME_SIZE <= IMG_UINT32_MAX, - "PVRSRV_PDUMP_MAX_FILENAME_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePMRPDumpSaveToFile(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpSaveToFileIN_UI8, - IMG_UINT8 * psPMRPDumpSaveToFileOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileIN = - (PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE *) IMG_OFFSET_ADDR(psPMRPDumpSaveToFileIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileOUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE *) IMG_OFFSET_ADDR(psPMRPDumpSaveToFileOUT_UI8, - 0); - - IMG_HANDLE hPMR = psPMRPDumpSaveToFileIN->hPMR; - PMR *psPMRInt = NULL; - IMG_CHAR *uiFileNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psPMRPDumpSaveToFileIN->ui32ArraySize > PVRSRV_PDUMP_MAX_FILENAME_SIZE)) - { - psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PMRPDumpSaveToFile_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PMRPDumpSaveToFile_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPMRPDumpSaveToFileIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPMRPDumpSaveToFileIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PMRPDumpSaveToFile_exit; - } - } - } - - if (psPMRPDumpSaveToFileIN->ui32ArraySize != 0) - { - uiFileNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiFileNameInt, (const void __user *)psPMRPDumpSaveToFileIN->puiFileName, - psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PMRPDumpSaveToFile_exit; - } - ((IMG_CHAR *) - uiFileNameInt)[(psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpSaveToFileOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpSaveToFileOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpSaveToFile_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpSaveToFileOUT->eError = - PMRPDumpSaveToFile(psPMRInt, - psPMRPDumpSaveToFileIN->uiOffset, - psPMRPDumpSaveToFileIN->uiSize, - psPMRPDumpSaveToFileIN->ui32ArraySize, - uiFileNameInt, psPMRPDumpSaveToFileIN->ui32uiFileOffset); - -PMRPDumpSaveToFile_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPMRPDumpSaveToFileOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH <= IMG_UINT32_MAX, - "PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH <= IMG_UINT32_MAX, - "PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgePMRPDumpSymbolicAddr(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpSymbolicAddrIN_UI8, - IMG_UINT8 * psPMRPDumpSymbolicAddrOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrIN = - (PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR *) IMG_OFFSET_ADDR(psPMRPDumpSymbolicAddrIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrOUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR *) - IMG_OFFSET_ADDR(psPMRPDumpSymbolicAddrOUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpSymbolicAddrIN->hPMR; - PMR *psPMRInt = NULL; - IMG_CHAR *puiMemspaceNameInt = NULL; - IMG_CHAR *puiSymbolicAddrInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR)) + 0; - - if (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen > PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PMRPDumpSymbolicAddr_exit; - } - - if (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen > PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto PMRPDumpSymbolicAddr_exit; - } - - psPMRPDumpSymbolicAddrOUT->puiMemspaceName = psPMRPDumpSymbolicAddrIN->puiMemspaceName; - psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr = psPMRPDumpSymbolicAddrIN->puiSymbolicAddr; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto PMRPDumpSymbolicAddr_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psPMRPDumpSymbolicAddrIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psPMRPDumpSymbolicAddrIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto PMRPDumpSymbolicAddr_exit; - } - } - } - - if (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen != 0) - { - puiMemspaceNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR); - } - - if (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen != 0) - { - puiSymbolicAddrInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR); - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpSymbolicAddrOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpSymbolicAddrOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpSymbolicAddr_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpSymbolicAddrOUT->eError = - PMR_PDumpSymbolicAddr(psPMRInt, - psPMRPDumpSymbolicAddrIN->uiOffset, - psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen, - puiMemspaceNameInt, - psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen, - puiSymbolicAddrInt, - &psPMRPDumpSymbolicAddrOUT->uiNewOffset, - &psPMRPDumpSymbolicAddrOUT->uiNextSymName); - /* Exit early if bridged call fails */ - if (unlikely(psPMRPDumpSymbolicAddrOUT->eError != PVRSRV_OK)) - { - goto PMRPDumpSymbolicAddr_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((puiMemspaceNameInt) && - ((psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psPMRPDumpSymbolicAddrOUT->puiMemspaceName, - puiMemspaceNameInt, - (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR))) != - PVRSRV_OK)) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PMRPDumpSymbolicAddr_exit; - } - } - - /* If dest ptr is non-null and we have data to copy */ - if ((puiSymbolicAddrInt) && - ((psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, - puiSymbolicAddrInt, - (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR))) != - PVRSRV_OK)) - { - psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto PMRPDumpSymbolicAddr_exit; - } - } - -PMRPDumpSymbolicAddr_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psPMRPDumpSymbolicAddrOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRPDumpPol32(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpPol32IN_UI8, - IMG_UINT8 * psPMRPDumpPol32OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPPOL32 *psPMRPDumpPol32IN = - (PVRSRV_BRIDGE_IN_PMRPDUMPPOL32 *) IMG_OFFSET_ADDR(psPMRPDumpPol32IN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32 *psPMRPDumpPol32OUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32 *) IMG_OFFSET_ADDR(psPMRPDumpPol32OUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpPol32IN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpPol32OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpPol32OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpPol32_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpPol32OUT->eError = - PMRPDumpPol32(psPMRInt, - psPMRPDumpPol32IN->uiOffset, - psPMRPDumpPol32IN->ui32Value, - psPMRPDumpPol32IN->ui32Mask, - psPMRPDumpPol32IN->eOperator, psPMRPDumpPol32IN->ui32PDumpFlags); - -PMRPDumpPol32_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRPDumpCheck32(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpCheck32IN_UI8, - IMG_UINT8 * psPMRPDumpCheck32OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPCHECK32 *psPMRPDumpCheck32IN = - (PVRSRV_BRIDGE_IN_PMRPDUMPCHECK32 *) IMG_OFFSET_ADDR(psPMRPDumpCheck32IN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPCHECK32 *psPMRPDumpCheck32OUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPCHECK32 *) IMG_OFFSET_ADDR(psPMRPDumpCheck32OUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpCheck32IN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpCheck32OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpCheck32OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpCheck32_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpCheck32OUT->eError = - PMRPDumpCheck32(psPMRInt, - psPMRPDumpCheck32IN->uiOffset, - psPMRPDumpCheck32IN->ui32Value, - psPMRPDumpCheck32IN->ui32Mask, - psPMRPDumpCheck32IN->eOperator, psPMRPDumpCheck32IN->ui32PDumpFlags); - -PMRPDumpCheck32_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgePMRPDumpCBP(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPMRPDumpCBPIN_UI8, - IMG_UINT8 * psPMRPDumpCBPOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PMRPDUMPCBP *psPMRPDumpCBPIN = - (PVRSRV_BRIDGE_IN_PMRPDUMPCBP *) IMG_OFFSET_ADDR(psPMRPDumpCBPIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PMRPDUMPCBP *psPMRPDumpCBPOUT = - (PVRSRV_BRIDGE_OUT_PMRPDUMPCBP *) IMG_OFFSET_ADDR(psPMRPDumpCBPOUT_UI8, 0); - - IMG_HANDLE hPMR = psPMRPDumpCBPIN->hPMR; - PMR *psPMRInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psPMRPDumpCBPOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psPMRPDumpCBPOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto PMRPDumpCBP_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psPMRPDumpCBPOUT->eError = - PMRPDumpCBP(psPMRInt, - psPMRPDumpCBPIN->uiReadOffset, - psPMRPDumpCBPIN->uiWriteOffset, - psPMRPDumpCBPIN->uiPacketSize, psPMRPDumpCBPIN->uiBufferSize); - -PMRPDumpCBP_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_PDUMP_MAX_FILENAME_SIZE <= IMG_UINT32_MAX, - "PVRSRV_PDUMP_MAX_FILENAME_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeDevmemIntPDumpSaveToFileVirtual(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDevmemIntPDumpSaveToFileVirtualIN_UI8, - IMG_UINT8 * psDevmemIntPDumpSaveToFileVirtualOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualIN = - (PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *) - IMG_OFFSET_ADDR(psDevmemIntPDumpSaveToFileVirtualIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualOUT = - (PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *) - IMG_OFFSET_ADDR(psDevmemIntPDumpSaveToFileVirtualOUT_UI8, 0); - - IMG_HANDLE hDevmemServerContext = psDevmemIntPDumpSaveToFileVirtualIN->hDevmemServerContext; - DEVMEMINT_CTX *psDevmemServerContextInt = NULL; - IMG_CHAR *uiFileNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) + - 0; - - if (unlikely - (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize > PVRSRV_PDUMP_MAX_FILENAME_SIZE)) - { - psDevmemIntPDumpSaveToFileVirtualOUT->eError = - PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto DevmemIntPDumpSaveToFileVirtual_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto DevmemIntPDumpSaveToFileVirtual_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psDevmemIntPDumpSaveToFileVirtualIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psDevmemIntPDumpSaveToFileVirtualIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psDevmemIntPDumpSaveToFileVirtualOUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto DevmemIntPDumpSaveToFileVirtual_exit; - } - } - } - - if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize != 0) - { - uiFileNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiFileNameInt, - (const void __user *)psDevmemIntPDumpSaveToFileVirtualIN->puiFileName, - psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) != - PVRSRV_OK) - { - psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto DevmemIntPDumpSaveToFileVirtual_exit; - } - ((IMG_CHAR *) - uiFileNameInt)[(psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * - sizeof(IMG_CHAR)) - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psDevmemIntPDumpSaveToFileVirtualOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psDevmemServerContextInt, - hDevmemServerContext, - PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX, IMG_TRUE); - if (unlikely(psDevmemIntPDumpSaveToFileVirtualOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto DevmemIntPDumpSaveToFileVirtual_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psDevmemIntPDumpSaveToFileVirtualOUT->eError = - DevmemIntPDumpSaveToFileVirtual(psDevmemServerContextInt, - psDevmemIntPDumpSaveToFileVirtualIN->sAddress, - psDevmemIntPDumpSaveToFileVirtualIN->uiSize, - psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize, - uiFileNameInt, - psDevmemIntPDumpSaveToFileVirtualIN->ui32FileOffset, - psDevmemIntPDumpSaveToFileVirtualIN->ui32PDumpFlags); - -DevmemIntPDumpSaveToFileVirtual_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psDevmemServerContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hDevmemServerContext, PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psDevmemIntPDumpSaveToFileVirtualOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitPDUMPMMBridge(void); -void DeinitPDUMPMMBridge(void); - -/* - * Register all PDUMPMM functions with services - */ -PVRSRV_ERROR InitPDUMPMMBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEM, - PVRSRVBridgePMRPDumpLoadMem, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE32, - PVRSRVBridgePMRPDumpLoadMemValue32, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE64, - PVRSRVBridgePMRPDumpLoadMemValue64, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSAVETOFILE, - PVRSRVBridgePMRPDumpSaveToFile, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSYMBOLICADDR, - PVRSRVBridgePMRPDumpSymbolicAddr, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPPOL32, - PVRSRVBridgePMRPDumpPol32, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPPOL32), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCHECK32, - PVRSRVBridgePMRPDumpCheck32, NULL, - sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPCHECK32), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPCHECK32)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCBP, - PVRSRVBridgePMRPDumpCBP, NULL, sizeof(PVRSRV_BRIDGE_IN_PMRPDUMPCBP), - sizeof(PVRSRV_BRIDGE_OUT_PMRPDUMPCBP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, - PVRSRV_BRIDGE_PDUMPMM_DEVMEMINTPDUMPSAVETOFILEVIRTUAL, - PVRSRVBridgeDevmemIntPDumpSaveToFileVirtual, NULL, - sizeof(PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL), - sizeof(PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL)); - - return PVRSRV_OK; -} - -/* - * Unregister all pdumpmm functions with services - */ -void DeinitPDUMPMMBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, - PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE32); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, - PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE64); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSAVETOFILE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSYMBOLICADDR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPPOL32); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCHECK32); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCBP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, - PVRSRV_BRIDGE_PDUMPMM_DEVMEMINTPDUMPSAVETOFILEVIRTUAL); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_pvrtl_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_pvrtl_bridge.c deleted file mode 100644 index b57fec4452544..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_pvrtl_bridge.c +++ /dev/null @@ -1,851 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for pvrtl -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for pvrtl -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "tlserver.h" - -#include "common_pvrtl_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _TLOpenStreampsSDIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = TLServerCloseStreamKM((TL_STREAM_DESC *) pvData); - return eError; -} - -static_assert(PRVSRVTL_MAX_STREAM_NAME_SIZE <= IMG_UINT32_MAX, - "PRVSRVTL_MAX_STREAM_NAME_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeTLOpenStream(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLOpenStreamIN_UI8, - IMG_UINT8 * psTLOpenStreamOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLOPENSTREAM *psTLOpenStreamIN = - (PVRSRV_BRIDGE_IN_TLOPENSTREAM *) IMG_OFFSET_ADDR(psTLOpenStreamIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLOPENSTREAM *psTLOpenStreamOUT = - (PVRSRV_BRIDGE_OUT_TLOPENSTREAM *) IMG_OFFSET_ADDR(psTLOpenStreamOUT_UI8, 0); - - IMG_CHAR *uiNameInt = NULL; - TL_STREAM_DESC *psSDInt = NULL; - PMR *psTLPMRInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) + 0; - - psTLOpenStreamOUT->hSD = NULL; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psTLOpenStreamOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto TLOpenStream_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psTLOpenStreamIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psTLOpenStreamIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psTLOpenStreamOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto TLOpenStream_exit; - } - } - } - - { - uiNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiNameInt, (const void __user *)psTLOpenStreamIN->puiName, - PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psTLOpenStreamOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto TLOpenStream_exit; - } - ((IMG_CHAR *) uiNameInt)[(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psTLOpenStreamOUT->eError = - TLServerOpenStreamKM(uiNameInt, psTLOpenStreamIN->ui32Mode, &psSDInt, &psTLPMRInt); - /* Exit early if bridged call fails */ - if (unlikely(psTLOpenStreamOUT->eError != PVRSRV_OK)) - { - goto TLOpenStream_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psTLOpenStreamOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psTLOpenStreamOUT->hSD, - (void *)psSDInt, - PVRSRV_HANDLE_TYPE_PVR_TL_SD, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _TLOpenStreampsSDIntRelease); - if (unlikely(psTLOpenStreamOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLOpenStream_exit; - } - - psTLOpenStreamOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psTLOpenStreamOUT->hTLPMR, - (void *)psTLPMRInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psTLOpenStreamOUT->hSD); - if (unlikely(psTLOpenStreamOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLOpenStream_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -TLOpenStream_exit: - - if (psTLOpenStreamOUT->eError != PVRSRV_OK) - { - if (psTLOpenStreamOUT->hSD) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psTLOpenStreamOUT->hSD, - PVRSRV_HANDLE_TYPE_PVR_TL_SD); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psSDInt) - { - TLServerCloseStreamKM(psSDInt); - } - - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psTLOpenStreamOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeTLCloseStream(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLCloseStreamIN_UI8, - IMG_UINT8 * psTLCloseStreamOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLCLOSESTREAM *psTLCloseStreamIN = - (PVRSRV_BRIDGE_IN_TLCLOSESTREAM *) IMG_OFFSET_ADDR(psTLCloseStreamIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLCLOSESTREAM *psTLCloseStreamOUT = - (PVRSRV_BRIDGE_OUT_TLCLOSESTREAM *) IMG_OFFSET_ADDR(psTLCloseStreamOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psTLCloseStreamOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psTLCloseStreamIN->hSD, - PVRSRV_HANDLE_TYPE_PVR_TL_SD); - if (unlikely((psTLCloseStreamOUT->eError != PVRSRV_OK) && - (psTLCloseStreamOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psTLCloseStreamOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psTLCloseStreamOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto TLCloseStream_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -TLCloseStream_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeTLAcquireData(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLAcquireDataIN_UI8, - IMG_UINT8 * psTLAcquireDataOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLACQUIREDATA *psTLAcquireDataIN = - (PVRSRV_BRIDGE_IN_TLACQUIREDATA *) IMG_OFFSET_ADDR(psTLAcquireDataIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLACQUIREDATA *psTLAcquireDataOUT = - (PVRSRV_BRIDGE_OUT_TLACQUIREDATA *) IMG_OFFSET_ADDR(psTLAcquireDataOUT_UI8, 0); - - IMG_HANDLE hSD = psTLAcquireDataIN->hSD; - TL_STREAM_DESC *psSDInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psTLAcquireDataOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSDInt, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD, IMG_TRUE); - if (unlikely(psTLAcquireDataOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLAcquireData_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psTLAcquireDataOUT->eError = - TLServerAcquireDataKM(psSDInt, - &psTLAcquireDataOUT->ui32ReadOffset, - &psTLAcquireDataOUT->ui32ReadLen); - -TLAcquireData_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSDInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeTLReleaseData(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLReleaseDataIN_UI8, - IMG_UINT8 * psTLReleaseDataOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLRELEASEDATA *psTLReleaseDataIN = - (PVRSRV_BRIDGE_IN_TLRELEASEDATA *) IMG_OFFSET_ADDR(psTLReleaseDataIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLRELEASEDATA *psTLReleaseDataOUT = - (PVRSRV_BRIDGE_OUT_TLRELEASEDATA *) IMG_OFFSET_ADDR(psTLReleaseDataOUT_UI8, 0); - - IMG_HANDLE hSD = psTLReleaseDataIN->hSD; - TL_STREAM_DESC *psSDInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psTLReleaseDataOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSDInt, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD, IMG_TRUE); - if (unlikely(psTLReleaseDataOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLReleaseData_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psTLReleaseDataOUT->eError = - TLServerReleaseDataKM(psSDInt, - psTLReleaseDataIN->ui32ReadOffset, - psTLReleaseDataIN->ui32ReadLen); - -TLReleaseData_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSDInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PRVSRVTL_MAX_STREAM_NAME_SIZE <= IMG_UINT32_MAX, - "PRVSRVTL_MAX_STREAM_NAME_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRVTL_MAX_DISCOVERABLE_STREAMS_BUFFER <= IMG_UINT32_MAX, - "PVRSRVTL_MAX_DISCOVERABLE_STREAMS_BUFFER must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeTLDiscoverStreams(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLDiscoverStreamsIN_UI8, - IMG_UINT8 * psTLDiscoverStreamsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS *psTLDiscoverStreamsIN = - (PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS *) IMG_OFFSET_ADDR(psTLDiscoverStreamsIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS *psTLDiscoverStreamsOUT = - (PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS *) IMG_OFFSET_ADDR(psTLDiscoverStreamsOUT_UI8, 0); - - IMG_CHAR *uiNamePatternInt = NULL; - IMG_CHAR *puiStreamsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psTLDiscoverStreamsIN->ui32Size * sizeof(IMG_CHAR)) + 0; - - if (psTLDiscoverStreamsIN->ui32Size > PVRSRVTL_MAX_DISCOVERABLE_STREAMS_BUFFER) - { - psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto TLDiscoverStreams_exit; - } - - PVR_UNREFERENCED_PARAMETER(psConnection); - - psTLDiscoverStreamsOUT->puiStreams = psTLDiscoverStreamsIN->puiStreams; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto TLDiscoverStreams_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psTLDiscoverStreamsIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psTLDiscoverStreamsIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto TLDiscoverStreams_exit; - } - } - } - - { - uiNamePatternInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiNamePatternInt, - (const void __user *)psTLDiscoverStreamsIN->puiNamePattern, - PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto TLDiscoverStreams_exit; - } - ((IMG_CHAR *) uiNamePatternInt)[(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - if (psTLDiscoverStreamsIN->ui32Size != 0) - { - puiStreamsInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psTLDiscoverStreamsIN->ui32Size * sizeof(IMG_CHAR); - } - - psTLDiscoverStreamsOUT->eError = - TLServerDiscoverStreamsKM(uiNamePatternInt, - psTLDiscoverStreamsIN->ui32Size, - puiStreamsInt, &psTLDiscoverStreamsOUT->ui32NumFound); - /* Exit early if bridged call fails */ - if (unlikely(psTLDiscoverStreamsOUT->eError != PVRSRV_OK)) - { - goto TLDiscoverStreams_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((puiStreamsInt) && ((psTLDiscoverStreamsIN->ui32Size * sizeof(IMG_CHAR)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psTLDiscoverStreamsOUT->puiStreams, puiStreamsInt, - (psTLDiscoverStreamsIN->ui32Size * sizeof(IMG_CHAR))) != PVRSRV_OK)) - { - psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto TLDiscoverStreams_exit; - } - } - -TLDiscoverStreams_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psTLDiscoverStreamsOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeTLReserveStream(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLReserveStreamIN_UI8, - IMG_UINT8 * psTLReserveStreamOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLRESERVESTREAM *psTLReserveStreamIN = - (PVRSRV_BRIDGE_IN_TLRESERVESTREAM *) IMG_OFFSET_ADDR(psTLReserveStreamIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLRESERVESTREAM *psTLReserveStreamOUT = - (PVRSRV_BRIDGE_OUT_TLRESERVESTREAM *) IMG_OFFSET_ADDR(psTLReserveStreamOUT_UI8, 0); - - IMG_HANDLE hSD = psTLReserveStreamIN->hSD; - TL_STREAM_DESC *psSDInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psTLReserveStreamOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSDInt, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD, IMG_TRUE); - if (unlikely(psTLReserveStreamOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLReserveStream_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psTLReserveStreamOUT->eError = - TLServerReserveStreamKM(psSDInt, - &psTLReserveStreamOUT->ui32BufferOffset, - psTLReserveStreamIN->ui32Size, - psTLReserveStreamIN->ui32SizeMin, - &psTLReserveStreamOUT->ui32Available); - -TLReserveStream_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSDInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeTLCommitStream(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLCommitStreamIN_UI8, - IMG_UINT8 * psTLCommitStreamOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLCOMMITSTREAM *psTLCommitStreamIN = - (PVRSRV_BRIDGE_IN_TLCOMMITSTREAM *) IMG_OFFSET_ADDR(psTLCommitStreamIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM *psTLCommitStreamOUT = - (PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM *) IMG_OFFSET_ADDR(psTLCommitStreamOUT_UI8, 0); - - IMG_HANDLE hSD = psTLCommitStreamIN->hSD; - TL_STREAM_DESC *psSDInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psTLCommitStreamOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSDInt, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD, IMG_TRUE); - if (unlikely(psTLCommitStreamOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLCommitStream_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psTLCommitStreamOUT->eError = - TLServerCommitStreamKM(psSDInt, psTLCommitStreamIN->ui32ReqSize); - -TLCommitStream_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSDInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRVTL_MAX_PACKET_SIZE <= IMG_UINT32_MAX, - "PVRSRVTL_MAX_PACKET_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeTLWriteData(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psTLWriteDataIN_UI8, - IMG_UINT8 * psTLWriteDataOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_TLWRITEDATA *psTLWriteDataIN = - (PVRSRV_BRIDGE_IN_TLWRITEDATA *) IMG_OFFSET_ADDR(psTLWriteDataIN_UI8, 0); - PVRSRV_BRIDGE_OUT_TLWRITEDATA *psTLWriteDataOUT = - (PVRSRV_BRIDGE_OUT_TLWRITEDATA *) IMG_OFFSET_ADDR(psTLWriteDataOUT_UI8, 0); - - IMG_HANDLE hSD = psTLWriteDataIN->hSD; - TL_STREAM_DESC *psSDInt = NULL; - IMG_BYTE *ui8DataInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = ((IMG_UINT64) psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE)) + 0; - - if (unlikely(psTLWriteDataIN->ui32Size > PVRSRVTL_MAX_PACKET_SIZE)) - { - psTLWriteDataOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto TLWriteData_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psTLWriteDataOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto TLWriteData_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psTLWriteDataIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psTLWriteDataIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psTLWriteDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto TLWriteData_exit; - } - } - } - - if (psTLWriteDataIN->ui32Size != 0) - { - ui8DataInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8DataInt, (const void __user *)psTLWriteDataIN->pui8Data, - psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psTLWriteDataOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto TLWriteData_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psTLWriteDataOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSDInt, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD, IMG_TRUE); - if (unlikely(psTLWriteDataOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto TLWriteData_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psTLWriteDataOUT->eError = - TLServerWriteDataKM(psSDInt, psTLWriteDataIN->ui32Size, ui8DataInt); - -TLWriteData_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSDInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSD, PVRSRV_HANDLE_TYPE_PVR_TL_SD); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psTLWriteDataOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitPVRTLBridge(void); -void DeinitPVRTLBridge(void); - -/* - * Register all PVRTL functions with services - */ -PVRSRV_ERROR InitPVRTLBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM, - PVRSRVBridgeTLOpenStream, NULL, sizeof(PVRSRV_BRIDGE_IN_TLOPENSTREAM), - sizeof(PVRSRV_BRIDGE_OUT_TLOPENSTREAM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM, - PVRSRVBridgeTLCloseStream, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLCLOSESTREAM), - sizeof(PVRSRV_BRIDGE_OUT_TLCLOSESTREAM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA, - PVRSRVBridgeTLAcquireData, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLACQUIREDATA), - sizeof(PVRSRV_BRIDGE_OUT_TLACQUIREDATA)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA, - PVRSRVBridgeTLReleaseData, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLRELEASEDATA), - sizeof(PVRSRV_BRIDGE_OUT_TLRELEASEDATA)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS, - PVRSRVBridgeTLDiscoverStreams, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS), - sizeof(PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM, - PVRSRVBridgeTLReserveStream, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLRESERVESTREAM), - sizeof(PVRSRV_BRIDGE_OUT_TLRESERVESTREAM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM, - PVRSRVBridgeTLCommitStream, NULL, - sizeof(PVRSRV_BRIDGE_IN_TLCOMMITSTREAM), - sizeof(PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLWRITEDATA, - PVRSRVBridgeTLWriteData, NULL, sizeof(PVRSRV_BRIDGE_IN_TLWRITEDATA), - sizeof(PVRSRV_BRIDGE_OUT_TLWRITEDATA)); - - return PVRSRV_OK; -} - -/* - * Unregister all pvrtl functions with services - */ -void DeinitPVRTLBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLWRITEDATA); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxbreakpoint_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxbreakpoint_bridge.c deleted file mode 100644 index 95f73bd1ead5d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxbreakpoint_bridge.c +++ /dev/null @@ -1,380 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxbreakpoint -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxbreakpoint -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxbreakpoint.h" - -#include "common_rgxbreakpoint_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#if !defined(EXCLUDE_RGXBREAKPOINT_BRIDGE) - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRGXSetBreakpoint(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetBreakpointIN_UI8, - IMG_UINT8 * psRGXSetBreakpointOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT *psRGXSetBreakpointIN = - (PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT *) IMG_OFFSET_ADDR(psRGXSetBreakpointIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT *psRGXSetBreakpointOUT = - (PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT *) IMG_OFFSET_ADDR(psRGXSetBreakpointOUT_UI8, 0); - - IMG_HANDLE hPrivData = psRGXSetBreakpointIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetBreakpointOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXSetBreakpointOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetBreakpoint_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetBreakpointOUT->eError = - PVRSRVRGXSetBreakpointKM(psConnection, OSGetDevNode(psConnection), - hPrivDataInt, - psRGXSetBreakpointIN->eFWDataMaster, - psRGXSetBreakpointIN->ui32BreakpointAddr, - psRGXSetBreakpointIN->ui32HandlerAddr, - psRGXSetBreakpointIN->ui32DM); - -RGXSetBreakpoint_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXClearBreakpoint(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXClearBreakpointIN_UI8, - IMG_UINT8 * psRGXClearBreakpointOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT *psRGXClearBreakpointIN = - (PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT *) IMG_OFFSET_ADDR(psRGXClearBreakpointIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT *psRGXClearBreakpointOUT = - (PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT *) IMG_OFFSET_ADDR(psRGXClearBreakpointOUT_UI8, - 0); - - IMG_HANDLE hPrivData = psRGXClearBreakpointIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXClearBreakpointOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXClearBreakpointOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXClearBreakpoint_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXClearBreakpointOUT->eError = - PVRSRVRGXClearBreakpointKM(psConnection, OSGetDevNode(psConnection), hPrivDataInt); - -RGXClearBreakpoint_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXEnableBreakpoint(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXEnableBreakpointIN_UI8, - IMG_UINT8 * psRGXEnableBreakpointOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT *psRGXEnableBreakpointIN = - (PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT *) IMG_OFFSET_ADDR(psRGXEnableBreakpointIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT *psRGXEnableBreakpointOUT = - (PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT *) IMG_OFFSET_ADDR(psRGXEnableBreakpointOUT_UI8, - 0); - - IMG_HANDLE hPrivData = psRGXEnableBreakpointIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXEnableBreakpointOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXEnableBreakpointOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXEnableBreakpoint_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXEnableBreakpointOUT->eError = - PVRSRVRGXEnableBreakpointKM(psConnection, OSGetDevNode(psConnection), hPrivDataInt); - -RGXEnableBreakpoint_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDisableBreakpoint(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDisableBreakpointIN_UI8, - IMG_UINT8 * psRGXDisableBreakpointOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointIN = - (PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT *) IMG_OFFSET_ADDR(psRGXDisableBreakpointIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointOUT = - (PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT *) - IMG_OFFSET_ADDR(psRGXDisableBreakpointOUT_UI8, 0); - - IMG_HANDLE hPrivData = psRGXDisableBreakpointIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXDisableBreakpointOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXDisableBreakpointOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXDisableBreakpoint_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXDisableBreakpointOUT->eError = - PVRSRVRGXDisableBreakpointKM(psConnection, OSGetDevNode(psConnection), hPrivDataInt); - -RGXDisableBreakpoint_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXOverallocateBPRegisters(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXOverallocateBPRegistersIN_UI8, - IMG_UINT8 * psRGXOverallocateBPRegistersOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS *psRGXOverallocateBPRegistersIN = - (PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS *) - IMG_OFFSET_ADDR(psRGXOverallocateBPRegistersIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS *psRGXOverallocateBPRegistersOUT = - (PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS *) - IMG_OFFSET_ADDR(psRGXOverallocateBPRegistersOUT_UI8, 0); - - psRGXOverallocateBPRegistersOUT->eError = - PVRSRVRGXOverallocateBPRegistersKM(psConnection, OSGetDevNode(psConnection), - psRGXOverallocateBPRegistersIN->ui32TempRegs, - psRGXOverallocateBPRegistersIN->ui32SharedRegs); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -#endif /* EXCLUDE_RGXBREAKPOINT_BRIDGE */ - -#if !defined(EXCLUDE_RGXBREAKPOINT_BRIDGE) -PVRSRV_ERROR InitRGXBREAKPOINTBridge(void); -void DeinitRGXBREAKPOINTBridge(void); - -/* - * Register all RGXBREAKPOINT functions with services - */ -PVRSRV_ERROR InitRGXBREAKPOINTBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXSETBREAKPOINT, - PVRSRVBridgeRGXSetBreakpoint, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXCLEARBREAKPOINT, - PVRSRVBridgeRGXClearBreakpoint, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT), - sizeof(PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXENABLEBREAKPOINT, - PVRSRVBridgeRGXEnableBreakpoint, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT), - sizeof(PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXDISABLEBREAKPOINT, - PVRSRVBridgeRGXDisableBreakpoint, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT), - sizeof(PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXOVERALLOCATEBPREGISTERS, - PVRSRVBridgeRGXOverallocateBPRegisters, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS), - sizeof(PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxbreakpoint functions with services - */ -void DeinitRGXBREAKPOINTBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXSETBREAKPOINT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXCLEARBREAKPOINT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXENABLEBREAKPOINT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXDISABLEBREAKPOINT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXBREAKPOINT, - PVRSRV_BRIDGE_RGXBREAKPOINT_RGXOVERALLOCATEBPREGISTERS); - -} -#else /* EXCLUDE_RGXBREAKPOINT_BRIDGE */ -/* This bridge is conditional on EXCLUDE_RGXBREAKPOINT_BRIDGE - when defined, - * do not populate the dispatch table with its functions - */ -#define InitRGXBREAKPOINTBridge() \ - PVRSRV_OK - -#define DeinitRGXBREAKPOINTBridge() - -#endif /* EXCLUDE_RGXBREAKPOINT_BRIDGE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxcmp_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxcmp_bridge.c deleted file mode 100644 index 9c5f504ae9a39..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxcmp_bridge.c +++ /dev/null @@ -1,1185 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxcmp -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxcmp -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxcompute.h" - -#include "common_rgxcmp_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#include "rgx_bvnc_defs_km.h" - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _RGXCreateComputeContextpsComputeContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXDestroyComputeContextKM((RGX_SERVER_COMPUTE_CONTEXT *) pvData); - return eError; -} - -static_assert(RGXFWIF_RF_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_RF_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_STATIC_COMPUTECONTEXT_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_STATIC_COMPUTECONTEXT_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXCreateComputeContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateComputeContextIN_UI8, - IMG_UINT8 * psRGXCreateComputeContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextIN = - (PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateComputeContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateComputeContextOUT_UI8, 0); - - IMG_BYTE *ui8FrameworkCmdInt = NULL; - IMG_HANDLE hPrivData = psRGXCreateComputeContextIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - IMG_BYTE *ui8StaticComputeContextStateInt = NULL; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize * - sizeof(IMG_BYTE)) + 0; - - if (unlikely(psRGXCreateComputeContextIN->ui32FrameworkCmdize > RGXFWIF_RF_CMD_SIZE)) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXCreateComputeContext_exit; - } - - if (unlikely - (psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize > - RGXFWIF_STATIC_COMPUTECONTEXT_SIZE)) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXCreateComputeContext_exit; - } - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXCreateComputeContext_exit; - } - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXCreateComputeContext_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXCreateComputeContextIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXCreateComputeContextIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXCreateComputeContext_exit; - } - } - } - - if (psRGXCreateComputeContextIN->ui32FrameworkCmdize != 0) - { - ui8FrameworkCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8FrameworkCmdInt, - (const void __user *)psRGXCreateComputeContextIN->pui8FrameworkCmd, - psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != - PVRSRV_OK) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateComputeContext_exit; - } - } - if (psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize != 0) - { - ui8StaticComputeContextStateInt = - (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize * - sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8StaticComputeContextStateInt, - (const void __user *)psRGXCreateComputeContextIN-> - pui8StaticComputeContextState, - psRGXCreateComputeContextIN->ui32StaticComputeContextStateSize * - sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateComputeContext_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateComputeContextOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateComputeContext_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateComputeContextOUT->eError = - PVRSRVRGXCreateComputeContextKM(psConnection, OSGetDevNode(psConnection), - psRGXCreateComputeContextIN->ui32Priority, - psRGXCreateComputeContextIN->ui32FrameworkCmdize, - ui8FrameworkCmdInt, - hPrivDataInt, - psRGXCreateComputeContextIN-> - ui32StaticComputeContextStateSize, - ui8StaticComputeContextStateInt, - psRGXCreateComputeContextIN->ui32PackedCCBSizeU88, - psRGXCreateComputeContextIN->ui32ContextFlags, - psRGXCreateComputeContextIN->ui64RobustnessAddress, - psRGXCreateComputeContextIN->ui32MaxDeadlineMS, - &psComputeContextInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)) - { - goto RGXCreateComputeContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateComputeContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateComputeContextOUT-> - hComputeContext, - (void *) - psComputeContextInt, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateComputeContextpsComputeContextIntRelease); - if (unlikely(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateComputeContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateComputeContext_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK) - { - if (psComputeContextInt) - { - PVRSRVRGXDestroyComputeContextKM(psComputeContextInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXCreateComputeContextOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyComputeContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyComputeContextIN_UI8, - IMG_UINT8 * psRGXDestroyComputeContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT *psRGXDestroyComputeContextIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyComputeContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT *psRGXDestroyComputeContextOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyComputeContextOUT_UI8, 0); - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXDestroyComputeContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXDestroyComputeContext_exit; - } - } - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyComputeContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyComputeContextIN-> - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - if (unlikely - ((psRGXDestroyComputeContextOUT->eError != PVRSRV_OK) - && (psRGXDestroyComputeContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyComputeContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyComputeContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyComputeContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyComputeContext_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFlushComputeData(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFlushComputeDataIN_UI8, - IMG_UINT8 * psRGXFlushComputeDataOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataIN = - (PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA *) IMG_OFFSET_ADDR(psRGXFlushComputeDataIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataOUT = - (PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA *) IMG_OFFSET_ADDR(psRGXFlushComputeDataOUT_UI8, - 0); - - IMG_HANDLE hComputeContext = psRGXFlushComputeDataIN->hComputeContext; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXFlushComputeDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXFlushComputeData_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXFlushComputeDataOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psComputeContextInt, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, IMG_TRUE); - if (unlikely(psRGXFlushComputeDataOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXFlushComputeData_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXFlushComputeDataOUT->eError = PVRSRVRGXFlushComputeDataKM(psComputeContextInt); - -RGXFlushComputeData_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psComputeContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetComputeContextPriority(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetComputeContextPriorityIN_UI8, - IMG_UINT8 * psRGXSetComputeContextPriorityOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityIN = - (PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetComputeContextPriorityIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityOUT = - (PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetComputeContextPriorityOUT_UI8, 0); - - IMG_HANDLE hComputeContext = psRGXSetComputeContextPriorityIN->hComputeContext; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXSetComputeContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXSetComputeContextPriority_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetComputeContextPriorityOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psComputeContextInt, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetComputeContextPriorityOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetComputeContextPriority_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetComputeContextPriorityOUT->eError = - PVRSRVRGXSetComputeContextPriorityKM(psConnection, OSGetDevNode(psConnection), - psComputeContextInt, - psRGXSetComputeContextPriorityIN->ui32Priority); - -RGXSetComputeContextPriority_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psComputeContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXNotifyComputeWriteOffsetUpdate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXNotifyComputeWriteOffsetUpdateIN_UI8, - IMG_UINT8 * - psRGXNotifyComputeWriteOffsetUpdateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *psRGXNotifyComputeWriteOffsetUpdateIN = - (PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *) - IMG_OFFSET_ADDR(psRGXNotifyComputeWriteOffsetUpdateIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *psRGXNotifyComputeWriteOffsetUpdateOUT - = - (PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *) - IMG_OFFSET_ADDR(psRGXNotifyComputeWriteOffsetUpdateOUT_UI8, 0); - - IMG_HANDLE hComputeContext = psRGXNotifyComputeWriteOffsetUpdateIN->hComputeContext; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXNotifyComputeWriteOffsetUpdateOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXNotifyComputeWriteOffsetUpdate_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXNotifyComputeWriteOffsetUpdateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psComputeContextInt, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, IMG_TRUE); - if (unlikely(psRGXNotifyComputeWriteOffsetUpdateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXNotifyComputeWriteOffsetUpdate_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXNotifyComputeWriteOffsetUpdateOUT->eError = - PVRSRVRGXNotifyComputeWriteOffsetUpdateKM(psComputeContextInt); - -RGXNotifyComputeWriteOffsetUpdate_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psComputeContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXKickCDM2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXKickCDM2IN_UI8, - IMG_UINT8 * psRGXKickCDM2OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXKICKCDM2 *psRGXKickCDM2IN = - (PVRSRV_BRIDGE_IN_RGXKICKCDM2 *) IMG_OFFSET_ADDR(psRGXKickCDM2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXKICKCDM2 *psRGXKickCDM2OUT = - (PVRSRV_BRIDGE_OUT_RGXKICKCDM2 *) IMG_OFFSET_ADDR(psRGXKickCDM2OUT_UI8, 0); - - IMG_HANDLE hComputeContext = psRGXKickCDM2IN->hComputeContext; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - SYNC_PRIMITIVE_BLOCK **psClientUpdateUFOSyncPrimBlockInt = NULL; - IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL; - IMG_UINT32 *ui32ClientUpdateOffsetInt = NULL; - IMG_UINT32 *ui32ClientUpdateValueInt = NULL; - IMG_CHAR *uiUpdateFenceNameInt = NULL; - IMG_BYTE *ui8DMCmdInt = NULL; - IMG_UINT32 *ui32SyncPMRFlagsInt = NULL; - PMR **psSyncPMRsInt = NULL; - IMG_HANDLE *hSyncPMRsInt2 = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32CmdSize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(PMR *)) + - ((IMG_UINT64) psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) + 0; - - if (unlikely(psRGXKickCDM2IN->ui32ClientUpdateCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickCDM2_exit; - } - - if (unlikely(psRGXKickCDM2IN->ui32CmdSize > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE)) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickCDM2_exit; - } - - if (unlikely(psRGXKickCDM2IN->ui32SyncPMRCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickCDM2_exit; - } - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXKickCDM2_exit; - } - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXKickCDM2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXKickCDM2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXKickCDM2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXKickCDM2_exit; - } - } - } - - if (psRGXKickCDM2IN->ui32ClientUpdateCount != 0) - { - psClientUpdateUFOSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psClientUpdateUFOSyncPrimBlockInt, 0, - psRGXKickCDM2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *); - hClientUpdateUFOSyncPrimBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hClientUpdateUFOSyncPrimBlockInt2, - (const void __user *)psRGXKickCDM2IN->phClientUpdateUFOSyncPrimBlock, - psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - if (psRGXKickCDM2IN->ui32ClientUpdateCount != 0) - { - ui32ClientUpdateOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientUpdateOffsetInt, - (const void __user *)psRGXKickCDM2IN->pui32ClientUpdateOffset, - psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - if (psRGXKickCDM2IN->ui32ClientUpdateCount != 0) - { - ui32ClientUpdateValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientUpdateValueInt, - (const void __user *)psRGXKickCDM2IN->pui32ClientUpdateValue, - psRGXKickCDM2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - - { - uiUpdateFenceNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceNameInt, - (const void __user *)psRGXKickCDM2IN->puiUpdateFenceName, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - ((IMG_CHAR *) uiUpdateFenceNameInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - if (psRGXKickCDM2IN->ui32CmdSize != 0) - { - ui8DMCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32CmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32CmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8DMCmdInt, (const void __user *)psRGXKickCDM2IN->pui8DMCmd, - psRGXKickCDM2IN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - if (psRGXKickCDM2IN->ui32SyncPMRCount != 0) - { - ui32SyncPMRFlagsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32SyncPMRFlagsInt, - (const void __user *)psRGXKickCDM2IN->pui32SyncPMRFlags, - psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - if (psRGXKickCDM2IN->ui32SyncPMRCount != 0) - { - psSyncPMRsInt = (PMR **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psSyncPMRsInt, 0, psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(PMR *)); - ui32NextOffset += psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(PMR *); - hSyncPMRsInt2 = (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hSyncPMRsInt2, (const void __user *)psRGXKickCDM2IN->phSyncPMRs, - psRGXKickCDM2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickCDM2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickCDM2_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXKickCDM2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psComputeContextInt, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, IMG_TRUE); - if (unlikely(psRGXKickCDM2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickCDM2_exit; - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickCDM2IN->ui32ClientUpdateCount; i++) - { - /* Look up the address from the handle */ - psRGXKickCDM2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **) - &psClientUpdateUFOSyncPrimBlockInt[i], - hClientUpdateUFOSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXKickCDM2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickCDM2_exit; - } - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickCDM2IN->ui32SyncPMRCount; i++) - { - /* Look up the address from the handle */ - psRGXKickCDM2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncPMRsInt[i], - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXKickCDM2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickCDM2_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXKickCDM2OUT->eError = - PVRSRVRGXKickCDMKM(psComputeContextInt, - psRGXKickCDM2IN->ui32ClientUpdateCount, - psClientUpdateUFOSyncPrimBlockInt, - ui32ClientUpdateOffsetInt, - ui32ClientUpdateValueInt, - psRGXKickCDM2IN->hCheckFenceFd, - psRGXKickCDM2IN->hUpdateTimeline, - &psRGXKickCDM2OUT->hUpdateFence, - uiUpdateFenceNameInt, - psRGXKickCDM2IN->ui32CmdSize, - ui8DMCmdInt, - psRGXKickCDM2IN->ui32PDumpFlags, - psRGXKickCDM2IN->ui32ExtJobRef, - psRGXKickCDM2IN->ui32SyncPMRCount, - ui32SyncPMRFlagsInt, - psSyncPMRsInt, - psRGXKickCDM2IN->ui32NumOfWorkgroups, - psRGXKickCDM2IN->ui32NumOfWorkitems, - psRGXKickCDM2IN->ui64DeadlineInus); - -RGXKickCDM2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psComputeContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - } - - if (hClientUpdateUFOSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickCDM2IN->ui32ClientUpdateCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psClientUpdateUFOSyncPrimBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hClientUpdateUFOSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - - if (hSyncPMRsInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickCDM2IN->ui32SyncPMRCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psSyncPMRsInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXKickCDM2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetComputeContextProperty(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetComputeContextPropertyIN_UI8, - IMG_UINT8 * psRGXSetComputeContextPropertyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY *psRGXSetComputeContextPropertyIN = - (PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetComputeContextPropertyIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY *psRGXSetComputeContextPropertyOUT = - (PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetComputeContextPropertyOUT_UI8, 0); - - IMG_HANDLE hComputeContext = psRGXSetComputeContextPropertyIN->hComputeContext; - RGX_SERVER_COMPUTE_CONTEXT *psComputeContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXSetComputeContextPropertyOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXSetComputeContextProperty_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetComputeContextPropertyOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psComputeContextInt, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetComputeContextPropertyOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetComputeContextProperty_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetComputeContextPropertyOUT->eError = - PVRSRVRGXSetComputeContextPropertyKM(psComputeContextInt, - psRGXSetComputeContextPropertyIN->ui32Property, - psRGXSetComputeContextPropertyIN->ui64Input, - &psRGXSetComputeContextPropertyOUT->ui64Output); - -RGXSetComputeContextProperty_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psComputeContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hComputeContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXGetLastDeviceError(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXGetLastDeviceErrorIN_UI8, - IMG_UINT8 * psRGXGetLastDeviceErrorOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR *psRGXGetLastDeviceErrorIN = - (PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR *) - IMG_OFFSET_ADDR(psRGXGetLastDeviceErrorIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR *psRGXGetLastDeviceErrorOUT = - (PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR *) - IMG_OFFSET_ADDR(psRGXGetLastDeviceErrorOUT_UI8, 0); - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_COMPUTE_BIT_MASK)) - { - psRGXGetLastDeviceErrorOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXGetLastDeviceError_exit; - } - } - - PVR_UNREFERENCED_PARAMETER(psRGXGetLastDeviceErrorIN); - - psRGXGetLastDeviceErrorOUT->eError = - PVRSRVRGXGetLastDeviceErrorKM(psConnection, OSGetDevNode(psConnection), - &psRGXGetLastDeviceErrorOUT->ui32Error); - -RGXGetLastDeviceError_exit: - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXCMPBridge(void); -void DeinitRGXCMPBridge(void); - -/* - * Register all RGXCMP functions with services - */ -PVRSRV_ERROR InitRGXCMPBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT, - PVRSRVBridgeRGXCreateComputeContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT, - PVRSRVBridgeRGXDestroyComputeContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA, - PVRSRVBridgeRGXFlushComputeData, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA), - sizeof(PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY, - PVRSRVBridgeRGXSetComputeContextPriority, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE, - PVRSRVBridgeRGXNotifyComputeWriteOffsetUpdate, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE), - sizeof(PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM2, - PVRSRVBridgeRGXKickCDM2, NULL, sizeof(PVRSRV_BRIDGE_IN_RGXKICKCDM2), - sizeof(PVRSRV_BRIDGE_OUT_RGXKICKCDM2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPROPERTY, - PVRSRVBridgeRGXSetComputeContextProperty, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXGETLASTDEVICEERROR, - PVRSRVBridgeRGXGetLastDeviceError, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxcmp functions with services - */ -void DeinitRGXCMPBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, - PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPROPERTY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXGETLASTDEVICEERROR); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxfwdbg_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxfwdbg_bridge.c deleted file mode 100644 index a088e3eb6a03e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxfwdbg_bridge.c +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxfwdbg -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxfwdbg -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "devicemem_server.h" -#include "rgxfwdbg.h" -#include "pmr.h" -#include "rgxtimecorr.h" - -#include "common_rgxfwdbg_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRGXFWDebugSetFWLog(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugSetFWLogIN_UI8, - IMG_UINT8 * psRGXFWDebugSetFWLogOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG *psRGXFWDebugSetFWLogIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG *) IMG_OFFSET_ADDR(psRGXFWDebugSetFWLogIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG *psRGXFWDebugSetFWLogOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG *) IMG_OFFSET_ADDR(psRGXFWDebugSetFWLogOUT_UI8, - 0); - - psRGXFWDebugSetFWLogOUT->eError = - PVRSRVRGXFWDebugSetFWLogKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugSetFWLogIN->ui32RGXFWLogType); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugDumpFreelistPageList(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugDumpFreelistPageListIN_UI8, - IMG_UINT8 * psRGXFWDebugDumpFreelistPageListOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST *psRGXFWDebugDumpFreelistPageListIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST *) - IMG_OFFSET_ADDR(psRGXFWDebugDumpFreelistPageListIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST *psRGXFWDebugDumpFreelistPageListOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST *) - IMG_OFFSET_ADDR(psRGXFWDebugDumpFreelistPageListOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psRGXFWDebugDumpFreelistPageListIN); - - psRGXFWDebugDumpFreelistPageListOUT->eError = - PVRSRVRGXFWDebugDumpFreelistPageListKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugSetHCSDeadline(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugSetHCSDeadlineIN_UI8, - IMG_UINT8 * psRGXFWDebugSetHCSDeadlineOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE *psRGXFWDebugSetHCSDeadlineIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE *) - IMG_OFFSET_ADDR(psRGXFWDebugSetHCSDeadlineIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE *psRGXFWDebugSetHCSDeadlineOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE *) - IMG_OFFSET_ADDR(psRGXFWDebugSetHCSDeadlineOUT_UI8, 0); - - psRGXFWDebugSetHCSDeadlineOUT->eError = - PVRSRVRGXFWDebugSetHCSDeadlineKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugSetHCSDeadlineIN->ui32RGXHCSDeadline); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugSetOSidPriority(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugSetOSidPriorityIN_UI8, - IMG_UINT8 * psRGXFWDebugSetOSidPriorityOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY *psRGXFWDebugSetOSidPriorityIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY *) - IMG_OFFSET_ADDR(psRGXFWDebugSetOSidPriorityIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY *psRGXFWDebugSetOSidPriorityOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY *) - IMG_OFFSET_ADDR(psRGXFWDebugSetOSidPriorityOUT_UI8, 0); - - psRGXFWDebugSetOSidPriorityOUT->eError = - PVRSRVRGXFWDebugSetOSidPriorityKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugSetOSidPriorityIN->ui32OSid, - psRGXFWDebugSetOSidPriorityIN->ui32Priority); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugSetOSNewOnlineState(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugSetOSNewOnlineStateIN_UI8, - IMG_UINT8 * psRGXFWDebugSetOSNewOnlineStateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE *psRGXFWDebugSetOSNewOnlineStateIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE *) - IMG_OFFSET_ADDR(psRGXFWDebugSetOSNewOnlineStateIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE *psRGXFWDebugSetOSNewOnlineStateOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE *) - IMG_OFFSET_ADDR(psRGXFWDebugSetOSNewOnlineStateOUT_UI8, 0); - - psRGXFWDebugSetOSNewOnlineStateOUT->eError = - PVRSRVRGXFWDebugSetOSNewOnlineStateKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugSetOSNewOnlineStateIN->ui32OSid, - psRGXFWDebugSetOSNewOnlineStateIN-> - ui32OSNewState); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugPHRConfigure(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugPHRConfigureIN_UI8, - IMG_UINT8 * psRGXFWDebugPHRConfigureOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE *psRGXFWDebugPHRConfigureIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE *) - IMG_OFFSET_ADDR(psRGXFWDebugPHRConfigureIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE *psRGXFWDebugPHRConfigureOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE *) - IMG_OFFSET_ADDR(psRGXFWDebugPHRConfigureOUT_UI8, 0); - - psRGXFWDebugPHRConfigureOUT->eError = - PVRSRVRGXFWDebugPHRConfigureKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugPHRConfigureIN->ui32ui32PHRMode); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXFWDebugWdgConfigure(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXFWDebugWdgConfigureIN_UI8, - IMG_UINT8 * psRGXFWDebugWdgConfigureOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE *psRGXFWDebugWdgConfigureIN = - (PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE *) - IMG_OFFSET_ADDR(psRGXFWDebugWdgConfigureIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE *psRGXFWDebugWdgConfigureOUT = - (PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE *) - IMG_OFFSET_ADDR(psRGXFWDebugWdgConfigureOUT_UI8, 0); - - psRGXFWDebugWdgConfigureOUT->eError = - PVRSRVRGXFWDebugWdgConfigureKM(psConnection, OSGetDevNode(psConnection), - psRGXFWDebugWdgConfigureIN->ui32ui32WdgPeriodUs); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXCurrentTime(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCurrentTimeIN_UI8, - IMG_UINT8 * psRGXCurrentTimeOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCURRENTTIME *psRGXCurrentTimeIN = - (PVRSRV_BRIDGE_IN_RGXCURRENTTIME *) IMG_OFFSET_ADDR(psRGXCurrentTimeIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCURRENTTIME *psRGXCurrentTimeOUT = - (PVRSRV_BRIDGE_OUT_RGXCURRENTTIME *) IMG_OFFSET_ADDR(psRGXCurrentTimeOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psRGXCurrentTimeIN); - - psRGXCurrentTimeOUT->eError = - PVRSRVRGXCurrentTime(psConnection, OSGetDevNode(psConnection), - &psRGXCurrentTimeOUT->ui64Time); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXFWDBGBridge(void); -void DeinitRGXFWDBGBridge(void); - -/* - * Register all RGXFWDBG functions with services - */ -PVRSRV_ERROR InitRGXFWDBGBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETFWLOG, - PVRSRVBridgeRGXFWDebugSetFWLog, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGDUMPFREELISTPAGELIST, - PVRSRVBridgeRGXFWDebugDumpFreelistPageList, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETHCSDEADLINE, - PVRSRVBridgeRGXFWDebugSetHCSDeadline, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSIDPRIORITY, - PVRSRVBridgeRGXFWDebugSetOSidPriority, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSNEWONLINESTATE, - PVRSRVBridgeRGXFWDebugSetOSNewOnlineState, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGPHRCONFIGURE, - PVRSRVBridgeRGXFWDebugPHRConfigure, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGWDGCONFIGURE, - PVRSRVBridgeRGXFWDebugWdgConfigure, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE), - sizeof(PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXCURRENTTIME, - PVRSRVBridgeRGXCurrentTime, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXCURRENTTIME)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxfwdbg functions with services - */ -void DeinitRGXFWDBGBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETFWLOG); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGDUMPFREELISTPAGELIST); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETHCSDEADLINE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSIDPRIORITY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSNEWONLINESTATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGPHRCONFIGURE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, - PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGWDGCONFIGURE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXFWDBG, PVRSRV_BRIDGE_RGXFWDBG_RGXCURRENTTIME); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxhwperf_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxhwperf_bridge.c deleted file mode 100644 index 5eaf44e08f34a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxhwperf_bridge.c +++ /dev/null @@ -1,662 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxhwperf -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxhwperf -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxhwperf.h" -#include "rgx_fwif_km.h" - -#include "common_rgxhwperf_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRGXCtrlHWPerf(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCtrlHWPerfIN_UI8, - IMG_UINT8 * psRGXCtrlHWPerfOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCTRLHWPERF *psRGXCtrlHWPerfIN = - (PVRSRV_BRIDGE_IN_RGXCTRLHWPERF *) IMG_OFFSET_ADDR(psRGXCtrlHWPerfIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF *psRGXCtrlHWPerfOUT = - (PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF *) IMG_OFFSET_ADDR(psRGXCtrlHWPerfOUT_UI8, 0); - - psRGXCtrlHWPerfOUT->eError = - PVRSRVRGXCtrlHWPerfKM(psConnection, OSGetDevNode(psConnection), - psRGXCtrlHWPerfIN->ui32StreamId, - psRGXCtrlHWPerfIN->bToggle, psRGXCtrlHWPerfIN->ui64Mask); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXGetHWPerfBvncFeatureFlags(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXGetHWPerfBvncFeatureFlagsIN_UI8, - IMG_UINT8 * psRGXGetHWPerfBvncFeatureFlagsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS *psRGXGetHWPerfBvncFeatureFlagsIN = - (PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS *) - IMG_OFFSET_ADDR(psRGXGetHWPerfBvncFeatureFlagsIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS *psRGXGetHWPerfBvncFeatureFlagsOUT = - (PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS *) - IMG_OFFSET_ADDR(psRGXGetHWPerfBvncFeatureFlagsOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psRGXGetHWPerfBvncFeatureFlagsIN); - - psRGXGetHWPerfBvncFeatureFlagsOUT->eError = - PVRSRVRGXGetHWPerfBvncFeatureFlagsKM(psConnection, OSGetDevNode(psConnection), - &psRGXGetHWPerfBvncFeatureFlagsOUT->sBVNC); - - return 0; -} - -static_assert(RGXFWIF_HWPERF_CTRL_BLKS_MAX <= IMG_UINT32_MAX, - "RGXFWIF_HWPERF_CTRL_BLKS_MAX must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXConfigMuxHWPerfCounters(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXConfigMuxHWPerfCountersIN_UI8, - IMG_UINT8 * psRGXConfigMuxHWPerfCountersOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS *psRGXConfigMuxHWPerfCountersIN = - (PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS *) - IMG_OFFSET_ADDR(psRGXConfigMuxHWPerfCountersIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS *psRGXConfigMuxHWPerfCountersOUT = - (PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS *) - IMG_OFFSET_ADDR(psRGXConfigMuxHWPerfCountersOUT_UI8, 0); - - RGX_HWPERF_CONFIG_MUX_CNTBLK *psBlockConfigsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen * - sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK)) + 0; - - if (unlikely(psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen > RGXFWIF_HWPERF_CTRL_BLKS_MAX)) - { - psRGXConfigMuxHWPerfCountersOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXConfigMuxHWPerfCounters_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXConfigMuxHWPerfCountersOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXConfigMuxHWPerfCounters_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXConfigMuxHWPerfCountersIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psRGXConfigMuxHWPerfCountersIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXConfigMuxHWPerfCountersOUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXConfigMuxHWPerfCounters_exit; - } - } - } - - if (psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen != 0) - { - psBlockConfigsInt = - (RGX_HWPERF_CONFIG_MUX_CNTBLK *) IMG_OFFSET_ADDR(pArrayArgsBuffer, - ui32NextOffset); - ui32NextOffset += - psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen * - sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK); - } - - /* Copy the data over */ - if (psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK) > 0) - { - if (OSCopyFromUser - (NULL, psBlockConfigsInt, - (const void __user *)psRGXConfigMuxHWPerfCountersIN->psBlockConfigs, - psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen * - sizeof(RGX_HWPERF_CONFIG_MUX_CNTBLK)) != PVRSRV_OK) - { - psRGXConfigMuxHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXConfigMuxHWPerfCounters_exit; - } - } - - psRGXConfigMuxHWPerfCountersOUT->eError = - PVRSRVRGXConfigMuxHWPerfCountersKM(psConnection, OSGetDevNode(psConnection), - psRGXConfigMuxHWPerfCountersIN->ui32ArrayLen, - psBlockConfigsInt); - -RGXConfigMuxHWPerfCounters_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXConfigMuxHWPerfCountersOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(RGXFWIF_HWPERF_CTRL_BLKS_MAX <= IMG_UINT32_MAX, - "RGXFWIF_HWPERF_CTRL_BLKS_MAX must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXControlHWPerfBlocks(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXControlHWPerfBlocksIN_UI8, - IMG_UINT8 * psRGXControlHWPerfBlocksOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS *psRGXControlHWPerfBlocksIN = - (PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS *) - IMG_OFFSET_ADDR(psRGXControlHWPerfBlocksIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS *psRGXControlHWPerfBlocksOUT = - (PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS *) - IMG_OFFSET_ADDR(psRGXControlHWPerfBlocksOUT_UI8, 0); - - IMG_UINT16 *ui16BlockIDsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXControlHWPerfBlocksIN->ui32ArrayLen * sizeof(IMG_UINT16)) + 0; - - if (unlikely(psRGXControlHWPerfBlocksIN->ui32ArrayLen > RGXFWIF_HWPERF_CTRL_BLKS_MAX)) - { - psRGXControlHWPerfBlocksOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXControlHWPerfBlocks_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXControlHWPerfBlocksOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXControlHWPerfBlocks_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXControlHWPerfBlocksIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXControlHWPerfBlocksIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXControlHWPerfBlocksOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXControlHWPerfBlocks_exit; - } - } - } - - if (psRGXControlHWPerfBlocksIN->ui32ArrayLen != 0) - { - ui16BlockIDsInt = (IMG_UINT16 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXControlHWPerfBlocksIN->ui32ArrayLen * sizeof(IMG_UINT16); - } - - /* Copy the data over */ - if (psRGXControlHWPerfBlocksIN->ui32ArrayLen * sizeof(IMG_UINT16) > 0) - { - if (OSCopyFromUser - (NULL, ui16BlockIDsInt, - (const void __user *)psRGXControlHWPerfBlocksIN->pui16BlockIDs, - psRGXControlHWPerfBlocksIN->ui32ArrayLen * sizeof(IMG_UINT16)) != PVRSRV_OK) - { - psRGXControlHWPerfBlocksOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXControlHWPerfBlocks_exit; - } - } - - psRGXControlHWPerfBlocksOUT->eError = - PVRSRVRGXControlHWPerfBlocksKM(psConnection, OSGetDevNode(psConnection), - psRGXControlHWPerfBlocksIN->bEnable, - psRGXControlHWPerfBlocksIN->ui32ArrayLen, - ui16BlockIDsInt); - -RGXControlHWPerfBlocks_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXControlHWPerfBlocksOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(RGX_HWPERF_MAX_CUSTOM_CNTRS <= IMG_UINT32_MAX, - "RGX_HWPERF_MAX_CUSTOM_CNTRS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXConfigCustomCounters(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXConfigCustomCountersIN_UI8, - IMG_UINT8 * psRGXConfigCustomCountersOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS *psRGXConfigCustomCountersIN = - (PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS *) - IMG_OFFSET_ADDR(psRGXConfigCustomCountersIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS *psRGXConfigCustomCountersOUT = - (PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS *) - IMG_OFFSET_ADDR(psRGXConfigCustomCountersOUT_UI8, 0); - - IMG_UINT32 *ui32CustomCounterIDsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) + - 0; - - if (unlikely - (psRGXConfigCustomCountersIN->ui16NumCustomCounters > RGX_HWPERF_MAX_CUSTOM_CNTRS)) - { - psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXConfigCustomCounters_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXConfigCustomCounters_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXConfigCustomCountersIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXConfigCustomCountersIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXConfigCustomCounters_exit; - } - } - } - - if (psRGXConfigCustomCountersIN->ui16NumCustomCounters != 0) - { - ui32CustomCounterIDsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32CustomCounterIDsInt, - (const void __user *)psRGXConfigCustomCountersIN->pui32CustomCounterIDs, - psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXConfigCustomCounters_exit; - } - } - - psRGXConfigCustomCountersOUT->eError = - PVRSRVRGXConfigCustomCountersKM(psConnection, OSGetDevNode(psConnection), - psRGXConfigCustomCountersIN->ui16CustomBlockID, - psRGXConfigCustomCountersIN->ui16NumCustomCounters, - ui32CustomCounterIDsInt); - -RGXConfigCustomCounters_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXConfigCustomCountersOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static_assert(RGXFWIF_HWPERF_CTRL_BLKS_MAX <= IMG_UINT32_MAX, - "RGXFWIF_HWPERF_CTRL_BLKS_MAX must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXConfigureHWPerfBlocks(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXConfigureHWPerfBlocksIN_UI8, - IMG_UINT8 * psRGXConfigureHWPerfBlocksOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS *psRGXConfigureHWPerfBlocksIN = - (PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS *) - IMG_OFFSET_ADDR(psRGXConfigureHWPerfBlocksIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS *psRGXConfigureHWPerfBlocksOUT = - (PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS *) - IMG_OFFSET_ADDR(psRGXConfigureHWPerfBlocksOUT_UI8, 0); - - RGX_HWPERF_CONFIG_CNTBLK *psBlockConfigsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXConfigureHWPerfBlocksIN->ui32ArrayLen * - sizeof(RGX_HWPERF_CONFIG_CNTBLK)) + 0; - - if (unlikely(psRGXConfigureHWPerfBlocksIN->ui32ArrayLen > RGXFWIF_HWPERF_CTRL_BLKS_MAX)) - { - psRGXConfigureHWPerfBlocksOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXConfigureHWPerfBlocks_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXConfigureHWPerfBlocksOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXConfigureHWPerfBlocks_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXConfigureHWPerfBlocksIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXConfigureHWPerfBlocksIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXConfigureHWPerfBlocksOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXConfigureHWPerfBlocks_exit; - } - } - } - - if (psRGXConfigureHWPerfBlocksIN->ui32ArrayLen != 0) - { - psBlockConfigsInt = - (RGX_HWPERF_CONFIG_CNTBLK *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXConfigureHWPerfBlocksIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK); - } - - /* Copy the data over */ - if (psRGXConfigureHWPerfBlocksIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK) > 0) - { - if (OSCopyFromUser - (NULL, psBlockConfigsInt, - (const void __user *)psRGXConfigureHWPerfBlocksIN->psBlockConfigs, - psRGXConfigureHWPerfBlocksIN->ui32ArrayLen * - sizeof(RGX_HWPERF_CONFIG_CNTBLK)) != PVRSRV_OK) - { - psRGXConfigureHWPerfBlocksOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXConfigureHWPerfBlocks_exit; - } - } - - psRGXConfigureHWPerfBlocksOUT->eError = - PVRSRVRGXConfigureHWPerfBlocksKM(psConnection, OSGetDevNode(psConnection), - psRGXConfigureHWPerfBlocksIN->ui32CtrlWord, - psRGXConfigureHWPerfBlocksIN->ui32ArrayLen, - psBlockConfigsInt); - -RGXConfigureHWPerfBlocks_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXConfigureHWPerfBlocksOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXHWPERFBridge(void); -void DeinitRGXHWPERFBridge(void); - -/* - * Register all RGXHWPERF functions with services - */ -PVRSRV_ERROR InitRGXHWPERFBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF, - PVRSRVBridgeRGXCtrlHWPerf, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCTRLHWPERF), - sizeof(PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXGETHWPERFBVNCFEATUREFLAGS, - PVRSRVBridgeRGXGetHWPerfBvncFeatureFlags, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGMUXHWPERFCOUNTERS, - PVRSRVBridgeRGXConfigMuxHWPerfCounters, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS), - sizeof(PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONTROLHWPERFBLOCKS, - PVRSRVBridgeRGXControlHWPerfBlocks, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS), - sizeof(PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS, - PVRSRVBridgeRGXConfigCustomCounters, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS), - sizeof(PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGUREHWPERFBLOCKS, - PVRSRVBridgeRGXConfigureHWPerfBlocks, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS), - sizeof(PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxhwperf functions with services - */ -void DeinitRGXHWPERFBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXGETHWPERFBVNCFEATUREFLAGS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGMUXHWPERFCOUNTERS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONTROLHWPERFBLOCKS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, - PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGUREHWPERFBLOCKS); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxkicksync_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxkicksync_bridge.c deleted file mode 100644 index ad98cdada08fa..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxkicksync_bridge.c +++ /dev/null @@ -1,586 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxkicksync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxkicksync -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxkicksync.h" - -#include "common_rgxkicksync_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _RGXCreateKickSyncContextpsKickSyncContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXDestroyKickSyncContextKM((RGX_SERVER_KICKSYNC_CONTEXT *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXCreateKickSyncContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateKickSyncContextIN_UI8, - IMG_UINT8 * psRGXCreateKickSyncContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT *psRGXCreateKickSyncContextIN = - (PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateKickSyncContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT *psRGXCreateKickSyncContextOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateKickSyncContextOUT_UI8, 0); - - IMG_HANDLE hPrivData = psRGXCreateKickSyncContextIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - RGX_SERVER_KICKSYNC_CONTEXT *psKickSyncContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateKickSyncContextOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateKickSyncContext_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateKickSyncContextOUT->eError = - PVRSRVRGXCreateKickSyncContextKM(psConnection, OSGetDevNode(psConnection), - hPrivDataInt, - psRGXCreateKickSyncContextIN->ui32PackedCCBSizeU88, - psRGXCreateKickSyncContextIN->ui32ContextFlags, - &psKickSyncContextInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)) - { - goto RGXCreateKickSyncContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateKickSyncContextOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateKickSyncContextOUT->hKickSyncContext, - (void *)psKickSyncContextInt, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateKickSyncContextpsKickSyncContextIntRelease); - if (unlikely(psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateKickSyncContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateKickSyncContext_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK) - { - if (psKickSyncContextInt) - { - PVRSRVRGXDestroyKickSyncContextKM(psKickSyncContextInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyKickSyncContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyKickSyncContextIN_UI8, - IMG_UINT8 * psRGXDestroyKickSyncContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT *psRGXDestroyKickSyncContextIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyKickSyncContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT *psRGXDestroyKickSyncContextOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyKickSyncContextOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyKickSyncContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyKickSyncContextIN-> - hKickSyncContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT); - if (unlikely - ((psRGXDestroyKickSyncContextOUT->eError != PVRSRV_OK) - && (psRGXDestroyKickSyncContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyKickSyncContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyKickSyncContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyKickSyncContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyKickSyncContext_exit: - - return 0; -} - -static_assert(PVRSRV_MAX_DEV_VARS <= IMG_UINT32_MAX, - "PVRSRV_MAX_DEV_VARS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXKickSync2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXKickSync2IN_UI8, - IMG_UINT8 * psRGXKickSync2OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXKICKSYNC2 *psRGXKickSync2IN = - (PVRSRV_BRIDGE_IN_RGXKICKSYNC2 *) IMG_OFFSET_ADDR(psRGXKickSync2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXKICKSYNC2 *psRGXKickSync2OUT = - (PVRSRV_BRIDGE_OUT_RGXKICKSYNC2 *) IMG_OFFSET_ADDR(psRGXKickSync2OUT_UI8, 0); - - IMG_HANDLE hKickSyncContext = psRGXKickSync2IN->hKickSyncContext; - RGX_SERVER_KICKSYNC_CONTEXT *psKickSyncContextInt = NULL; - SYNC_PRIMITIVE_BLOCK **psUpdateUFODevVarBlockInt = NULL; - IMG_HANDLE *hUpdateUFODevVarBlockInt2 = NULL; - IMG_UINT32 *ui32UpdateDevVarOffsetInt = NULL; - IMG_UINT32 *ui32UpdateValueInt = NULL; - IMG_CHAR *uiUpdateFenceNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXKickSync2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psRGXKickSync2IN->ui32ClientUpdateCount > PVRSRV_MAX_DEV_VARS)) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickSync2_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXKickSync2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXKickSync2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXKickSync2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXKickSync2_exit; - } - } - } - - if (psRGXKickSync2IN->ui32ClientUpdateCount != 0) - { - psUpdateUFODevVarBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psUpdateUFODevVarBlockInt, 0, - psRGXKickSync2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *); - hUpdateUFODevVarBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hUpdateUFODevVarBlockInt2, - (const void __user *)psRGXKickSync2IN->phUpdateUFODevVarBlock, - psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickSync2_exit; - } - } - if (psRGXKickSync2IN->ui32ClientUpdateCount != 0) - { - ui32UpdateDevVarOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32UpdateDevVarOffsetInt, - (const void __user *)psRGXKickSync2IN->pui32UpdateDevVarOffset, - psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickSync2_exit; - } - } - if (psRGXKickSync2IN->ui32ClientUpdateCount != 0) - { - ui32UpdateValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32UpdateValueInt, - (const void __user *)psRGXKickSync2IN->pui32UpdateValue, - psRGXKickSync2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickSync2_exit; - } - } - - { - uiUpdateFenceNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceNameInt, - (const void __user *)psRGXKickSync2IN->puiUpdateFenceName, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXKickSync2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickSync2_exit; - } - ((IMG_CHAR *) uiUpdateFenceNameInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXKickSync2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psKickSyncContextInt, - hKickSyncContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT, IMG_TRUE); - if (unlikely(psRGXKickSync2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickSync2_exit; - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickSync2IN->ui32ClientUpdateCount; i++) - { - /* Look up the address from the handle */ - psRGXKickSync2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psUpdateUFODevVarBlockInt[i], - hUpdateUFODevVarBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXKickSync2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickSync2_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXKickSync2OUT->eError = - PVRSRVRGXKickSyncKM(psKickSyncContextInt, - psRGXKickSync2IN->ui32ClientUpdateCount, - psUpdateUFODevVarBlockInt, - ui32UpdateDevVarOffsetInt, - ui32UpdateValueInt, - psRGXKickSync2IN->hCheckFenceFD, - psRGXKickSync2IN->hTimelineFenceFD, - &psRGXKickSync2OUT->hUpdateFenceFD, - uiUpdateFenceNameInt, psRGXKickSync2IN->ui32ExtJobRef); - -RGXKickSync2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psKickSyncContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hKickSyncContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT); - } - - if (hUpdateUFODevVarBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickSync2IN->ui32ClientUpdateCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psUpdateUFODevVarBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hUpdateUFODevVarBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXKickSync2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetKickSyncContextProperty(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetKickSyncContextPropertyIN_UI8, - IMG_UINT8 * psRGXSetKickSyncContextPropertyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY *psRGXSetKickSyncContextPropertyIN = - (PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetKickSyncContextPropertyIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY *psRGXSetKickSyncContextPropertyOUT = - (PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetKickSyncContextPropertyOUT_UI8, 0); - - IMG_HANDLE hKickSyncContext = psRGXSetKickSyncContextPropertyIN->hKickSyncContext; - RGX_SERVER_KICKSYNC_CONTEXT *psKickSyncContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetKickSyncContextPropertyOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psKickSyncContextInt, - hKickSyncContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetKickSyncContextPropertyOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetKickSyncContextProperty_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetKickSyncContextPropertyOUT->eError = - PVRSRVRGXSetKickSyncContextPropertyKM(psKickSyncContextInt, - psRGXSetKickSyncContextPropertyIN->ui32Property, - psRGXSetKickSyncContextPropertyIN->ui64Input, - &psRGXSetKickSyncContextPropertyOUT->ui64Output); - -RGXSetKickSyncContextProperty_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psKickSyncContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hKickSyncContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXKICKSYNCBridge(void); -void DeinitRGXKICKSYNCBridge(void); - -/* - * Register all RGXKICKSYNC functions with services - */ -PVRSRV_ERROR InitRGXKICKSYNCBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXCREATEKICKSYNCCONTEXT, - PVRSRVBridgeRGXCreateKickSyncContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXDESTROYKICKSYNCCONTEXT, - PVRSRVBridgeRGXDestroyKickSyncContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, PVRSRV_BRIDGE_RGXKICKSYNC_RGXKICKSYNC2, - PVRSRVBridgeRGXKickSync2, NULL, sizeof(PVRSRV_BRIDGE_IN_RGXKICKSYNC2), - sizeof(PVRSRV_BRIDGE_OUT_RGXKICKSYNC2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXSETKICKSYNCCONTEXTPROPERTY, - PVRSRVBridgeRGXSetKickSyncContextProperty, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxkicksync functions with services - */ -void DeinitRGXKICKSYNCBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXCREATEKICKSYNCCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXDESTROYKICKSYNCCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, PVRSRV_BRIDGE_RGXKICKSYNC_RGXKICKSYNC2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXKICKSYNC, - PVRSRV_BRIDGE_RGXKICKSYNC_RGXSETKICKSYNCCONTEXTPROPERTY); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxpdump_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxpdump_bridge.c deleted file mode 100644 index 6a52346b80e9a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxpdump_bridge.c +++ /dev/null @@ -1,264 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxpdump -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxpdump -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxpdump.h" - -#include "common_rgxpdump_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgePDumpTraceBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpTraceBufferIN_UI8, - IMG_UINT8 * psPDumpTraceBufferOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER *psPDumpTraceBufferIN = - (PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER *) IMG_OFFSET_ADDR(psPDumpTraceBufferIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER *psPDumpTraceBufferOUT = - (PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER *) IMG_OFFSET_ADDR(psPDumpTraceBufferOUT_UI8, 0); - - psPDumpTraceBufferOUT->eError = - PVRSRVPDumpTraceBufferKM(psConnection, OSGetDevNode(psConnection), - psPDumpTraceBufferIN->ui32PDumpFlags); - - return 0; -} - -static IMG_INT -PVRSRVBridgePDumpSignatureBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpSignatureBufferIN_UI8, - IMG_UINT8 * psPDumpSignatureBufferOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER *psPDumpSignatureBufferIN = - (PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER *) IMG_OFFSET_ADDR(psPDumpSignatureBufferIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER *psPDumpSignatureBufferOUT = - (PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER *) - IMG_OFFSET_ADDR(psPDumpSignatureBufferOUT_UI8, 0); - - psPDumpSignatureBufferOUT->eError = - PVRSRVPDumpSignatureBufferKM(psConnection, OSGetDevNode(psConnection), - psPDumpSignatureBufferIN->ui32PDumpFlags); - - return 0; -} - -#if defined(SUPPORT_VALIDATION) - -static IMG_INT -PVRSRVBridgePDumpComputeCRCSignatureCheck(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpComputeCRCSignatureCheckIN_UI8, - IMG_UINT8 * psPDumpComputeCRCSignatureCheckOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPCOMPUTECRCSIGNATURECHECK *psPDumpComputeCRCSignatureCheckIN = - (PVRSRV_BRIDGE_IN_PDUMPCOMPUTECRCSIGNATURECHECK *) - IMG_OFFSET_ADDR(psPDumpComputeCRCSignatureCheckIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PDUMPCOMPUTECRCSIGNATURECHECK *psPDumpComputeCRCSignatureCheckOUT = - (PVRSRV_BRIDGE_OUT_PDUMPCOMPUTECRCSIGNATURECHECK *) - IMG_OFFSET_ADDR(psPDumpComputeCRCSignatureCheckOUT_UI8, 0); - - psPDumpComputeCRCSignatureCheckOUT->eError = - PVRSRVPDumpComputeCRCSignatureCheckKM(psConnection, OSGetDevNode(psConnection), - psPDumpComputeCRCSignatureCheckIN-> - ui32PDumpFlags); - - return 0; -} - -#else -#define PVRSRVBridgePDumpComputeCRCSignatureCheck NULL -#endif - -static IMG_INT -PVRSRVBridgePDumpCRCSignatureCheck(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpCRCSignatureCheckIN_UI8, - IMG_UINT8 * psPDumpCRCSignatureCheckOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPCRCSIGNATURECHECK *psPDumpCRCSignatureCheckIN = - (PVRSRV_BRIDGE_IN_PDUMPCRCSIGNATURECHECK *) - IMG_OFFSET_ADDR(psPDumpCRCSignatureCheckIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PDUMPCRCSIGNATURECHECK *psPDumpCRCSignatureCheckOUT = - (PVRSRV_BRIDGE_OUT_PDUMPCRCSIGNATURECHECK *) - IMG_OFFSET_ADDR(psPDumpCRCSignatureCheckOUT_UI8, 0); - - psPDumpCRCSignatureCheckOUT->eError = - PVRSRVPDumpCRCSignatureCheckKM(psConnection, OSGetDevNode(psConnection), - psPDumpCRCSignatureCheckIN->ui32PDumpFlags); - - return 0; -} - -static IMG_INT -PVRSRVBridgePDumpValCheckPreCommand(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpValCheckPreCommandIN_UI8, - IMG_UINT8 * psPDumpValCheckPreCommandOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPVALCHECKPRECOMMAND *psPDumpValCheckPreCommandIN = - (PVRSRV_BRIDGE_IN_PDUMPVALCHECKPRECOMMAND *) - IMG_OFFSET_ADDR(psPDumpValCheckPreCommandIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPRECOMMAND *psPDumpValCheckPreCommandOUT = - (PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPRECOMMAND *) - IMG_OFFSET_ADDR(psPDumpValCheckPreCommandOUT_UI8, 0); - - psPDumpValCheckPreCommandOUT->eError = - PVRSRVPDumpValCheckPreCommandKM(psConnection, OSGetDevNode(psConnection), - psPDumpValCheckPreCommandIN->ui32PDumpFlags); - - return 0; -} - -static IMG_INT -PVRSRVBridgePDumpValCheckPostCommand(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psPDumpValCheckPostCommandIN_UI8, - IMG_UINT8 * psPDumpValCheckPostCommandOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_PDUMPVALCHECKPOSTCOMMAND *psPDumpValCheckPostCommandIN = - (PVRSRV_BRIDGE_IN_PDUMPVALCHECKPOSTCOMMAND *) - IMG_OFFSET_ADDR(psPDumpValCheckPostCommandIN_UI8, 0); - PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPOSTCOMMAND *psPDumpValCheckPostCommandOUT = - (PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPOSTCOMMAND *) - IMG_OFFSET_ADDR(psPDumpValCheckPostCommandOUT_UI8, 0); - - psPDumpValCheckPostCommandOUT->eError = - PVRSRVPDumpValCheckPostCommandKM(psConnection, OSGetDevNode(psConnection), - psPDumpValCheckPostCommandIN->ui32PDumpFlags); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXPDUMPBridge(void); -void DeinitRGXPDUMPBridge(void); - -/* - * Register all RGXPDUMP functions with services - */ -PVRSRV_ERROR InitRGXPDUMPBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPTRACEBUFFER, - PVRSRVBridgePDumpTraceBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPSIGNATUREBUFFER, - PVRSRVBridgePDumpSignatureBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPCOMPUTECRCSIGNATURECHECK, - PVRSRVBridgePDumpComputeCRCSignatureCheck, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPCOMPUTECRCSIGNATURECHECK), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPCOMPUTECRCSIGNATURECHECK)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPCRCSIGNATURECHECK, - PVRSRVBridgePDumpCRCSignatureCheck, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPCRCSIGNATURECHECK), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPCRCSIGNATURECHECK)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPRECOMMAND, - PVRSRVBridgePDumpValCheckPreCommand, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPVALCHECKPRECOMMAND), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPRECOMMAND)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPOSTCOMMAND, - PVRSRVBridgePDumpValCheckPostCommand, NULL, - sizeof(PVRSRV_BRIDGE_IN_PDUMPVALCHECKPOSTCOMMAND), - sizeof(PVRSRV_BRIDGE_OUT_PDUMPVALCHECKPOSTCOMMAND)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxpdump functions with services - */ -void DeinitRGXPDUMPBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPTRACEBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPSIGNATUREBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPCOMPUTECRCSIGNATURECHECK); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPCRCSIGNATURECHECK); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPRECOMMAND); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, - PVRSRV_BRIDGE_RGXPDUMP_PDUMPVALCHECKPOSTCOMMAND); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxregconfig_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxregconfig_bridge.c deleted file mode 100644 index 548401470d098..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxregconfig_bridge.c +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxregconfig -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxregconfig -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxregconfig.h" - -#include "common_rgxregconfig_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRGXSetRegConfigType(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetRegConfigTypeIN_UI8, - IMG_UINT8 * psRGXSetRegConfigTypeOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE *psRGXSetRegConfigTypeIN = - (PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE *) IMG_OFFSET_ADDR(psRGXSetRegConfigTypeIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE *psRGXSetRegConfigTypeOUT = - (PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE *) IMG_OFFSET_ADDR(psRGXSetRegConfigTypeOUT_UI8, - 0); - - psRGXSetRegConfigTypeOUT->eError = - PVRSRVRGXSetRegConfigTypeKM(psConnection, OSGetDevNode(psConnection), - psRGXSetRegConfigTypeIN->ui8RegPowerIsland); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXAddRegconfig(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXAddRegconfigIN_UI8, - IMG_UINT8 * psRGXAddRegconfigOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXADDREGCONFIG *psRGXAddRegconfigIN = - (PVRSRV_BRIDGE_IN_RGXADDREGCONFIG *) IMG_OFFSET_ADDR(psRGXAddRegconfigIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG *psRGXAddRegconfigOUT = - (PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG *) IMG_OFFSET_ADDR(psRGXAddRegconfigOUT_UI8, 0); - - psRGXAddRegconfigOUT->eError = - PVRSRVRGXAddRegConfigKM(psConnection, OSGetDevNode(psConnection), - psRGXAddRegconfigIN->ui32RegAddr, - psRGXAddRegconfigIN->ui64RegValue, - psRGXAddRegconfigIN->ui64RegMask); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXClearRegConfig(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXClearRegConfigIN_UI8, - IMG_UINT8 * psRGXClearRegConfigOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG *psRGXClearRegConfigIN = - (PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG *) IMG_OFFSET_ADDR(psRGXClearRegConfigIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG *psRGXClearRegConfigOUT = - (PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG *) IMG_OFFSET_ADDR(psRGXClearRegConfigOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psRGXClearRegConfigIN); - - psRGXClearRegConfigOUT->eError = - PVRSRVRGXClearRegConfigKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXEnableRegConfig(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXEnableRegConfigIN_UI8, - IMG_UINT8 * psRGXEnableRegConfigOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG *psRGXEnableRegConfigIN = - (PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG *) IMG_OFFSET_ADDR(psRGXEnableRegConfigIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG *psRGXEnableRegConfigOUT = - (PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG *) IMG_OFFSET_ADDR(psRGXEnableRegConfigOUT_UI8, - 0); - - PVR_UNREFERENCED_PARAMETER(psRGXEnableRegConfigIN); - - psRGXEnableRegConfigOUT->eError = - PVRSRVRGXEnableRegConfigKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDisableRegConfig(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDisableRegConfigIN_UI8, - IMG_UINT8 * psRGXDisableRegConfigOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG *psRGXDisableRegConfigIN = - (PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG *) IMG_OFFSET_ADDR(psRGXDisableRegConfigIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG *psRGXDisableRegConfigOUT = - (PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG *) IMG_OFFSET_ADDR(psRGXDisableRegConfigOUT_UI8, - 0); - - PVR_UNREFERENCED_PARAMETER(psRGXDisableRegConfigIN); - - psRGXDisableRegConfigOUT->eError = - PVRSRVRGXDisableRegConfigKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -#endif /* EXCLUDE_RGXREGCONFIG_BRIDGE */ - -#if !defined(EXCLUDE_RGXREGCONFIG_BRIDGE) -PVRSRV_ERROR InitRGXREGCONFIGBridge(void); -void DeinitRGXREGCONFIGBridge(void); - -/* - * Register all RGXREGCONFIG functions with services - */ -PVRSRV_ERROR InitRGXREGCONFIGBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXSETREGCONFIGTYPE, - PVRSRVBridgeRGXSetRegConfigType, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXADDREGCONFIG, - PVRSRVBridgeRGXAddRegconfig, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXADDREGCONFIG), - sizeof(PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXCLEARREGCONFIG, - PVRSRVBridgeRGXClearRegConfig, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXENABLEREGCONFIG, - PVRSRVBridgeRGXEnableRegConfig, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXDISABLEREGCONFIG, - PVRSRVBridgeRGXDisableRegConfig, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxregconfig functions with services - */ -void DeinitRGXREGCONFIGBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXSETREGCONFIGTYPE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXADDREGCONFIG); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXCLEARREGCONFIG); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXENABLEREGCONFIG); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXREGCONFIG, - PVRSRV_BRIDGE_RGXREGCONFIG_RGXDISABLEREGCONFIG); - -} -#else /* EXCLUDE_RGXREGCONFIG_BRIDGE */ -/* This bridge is conditional on EXCLUDE_RGXREGCONFIG_BRIDGE - when defined, - * do not populate the dispatch table with its functions - */ -#define InitRGXREGCONFIGBridge() \ - PVRSRV_OK - -#define DeinitRGXREGCONFIGBridge() - -#endif /* EXCLUDE_RGXREGCONFIG_BRIDGE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxta3d_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxta3d_bridge.c deleted file mode 100644 index 2d7715335462f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxta3d_bridge.c +++ /dev/null @@ -1,2771 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxta3d -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxta3d -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxta3d.h" - -#include "common_rgxta3d_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _RGXCreateHWRTDataSetpsKmHwRTDataSetIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXDestroyHWRTDataSet((RGX_KM_HW_RT_DATASET *) pvData); - return eError; -} - -static_assert(RGXMKIF_NUM_GEOMDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_GEOMDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_RTDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_RTDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_RTDATA_FREELISTS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_RTDATA_FREELISTS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_GEOMDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_GEOMDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_RTDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_RTDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_RTDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_RTDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_GEOMDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_GEOMDATAS must not be larger than IMG_UINT32_MAX"); -static_assert(RGXMKIF_NUM_RTDATAS <= IMG_UINT32_MAX, - "RGXMKIF_NUM_RTDATAS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXCreateHWRTDataSet(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateHWRTDataSetIN_UI8, - IMG_UINT8 * psRGXCreateHWRTDataSetOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET *psRGXCreateHWRTDataSetIN = - (PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET *) IMG_OFFSET_ADDR(psRGXCreateHWRTDataSetIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET *psRGXCreateHWRTDataSetOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET *) - IMG_OFFSET_ADDR(psRGXCreateHWRTDataSetOUT_UI8, 0); - - IMG_DEV_VIRTADDR *sVHeapTableDevVAddrInt = NULL; - IMG_DEV_VIRTADDR *sPMMlistDevVAddrInt = NULL; - RGX_FREELIST **psapsFreeListsInt = NULL; - IMG_HANDLE *hapsFreeListsInt2 = NULL; - IMG_DEV_VIRTADDR *sTailPtrsDevVAddrInt = NULL; - IMG_DEV_VIRTADDR *sMacrotileArrayDevVAddrInt = NULL; - IMG_DEV_VIRTADDR *sRgnHeaderDevVAddrInt = NULL; - IMG_DEV_VIRTADDR *sRTCDevVAddrInt = NULL; - RGX_KM_HW_RT_DATASET **psKmHwRTDataSetInt = NULL; - IMG_HANDLE *hKmHwRTDataSetInt2 = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(RGX_FREELIST *)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATAS * sizeof(RGX_KM_HW_RT_DATASET *)) + - ((IMG_UINT64) RGXMKIF_NUM_RTDATAS * sizeof(IMG_HANDLE)) + 0; - - psRGXCreateHWRTDataSetOUT->phKmHwRTDataSet = psRGXCreateHWRTDataSetIN->phKmHwRTDataSet; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXCreateHWRTDataSet_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXCreateHWRTDataSetIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXCreateHWRTDataSetIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXCreateHWRTDataSet_exit; - } - } - } - - { - sVHeapTableDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sVHeapTableDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psVHeapTableDevVAddr, - RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - sPMMlistDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sPMMlistDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psPMMlistDevVAddr, - RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - psapsFreeListsInt = - (RGX_FREELIST **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psapsFreeListsInt, 0, - RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(RGX_FREELIST *)); - ui32NextOffset += RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(RGX_FREELIST *); - hapsFreeListsInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hapsFreeListsInt2, - (const void __user *)psRGXCreateHWRTDataSetIN->phapsFreeLists, - RGXMKIF_NUM_RTDATA_FREELISTS * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - sTailPtrsDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sTailPtrsDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psTailPtrsDevVAddr, - RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - sMacrotileArrayDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sMacrotileArrayDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psMacrotileArrayDevVAddr, - RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - sRgnHeaderDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sRgnHeaderDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psRgnHeaderDevVAddr, - RGXMKIF_NUM_RTDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - - { - sRTCDevVAddrInt = - (IMG_DEV_VIRTADDR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR); - } - - /* Copy the data over */ - if (RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR) > 0) - { - if (OSCopyFromUser - (NULL, sRTCDevVAddrInt, - (const void __user *)psRGXCreateHWRTDataSetIN->psRTCDevVAddr, - RGXMKIF_NUM_GEOMDATAS * sizeof(IMG_DEV_VIRTADDR)) != PVRSRV_OK) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - if (IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset) != NULL) - { - psKmHwRTDataSetInt = - (RGX_KM_HW_RT_DATASET **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psKmHwRTDataSetInt, 0, - RGXMKIF_NUM_RTDATAS * sizeof(RGX_KM_HW_RT_DATASET *)); - ui32NextOffset += RGXMKIF_NUM_RTDATAS * sizeof(RGX_KM_HW_RT_DATASET *); - hKmHwRTDataSetInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += RGXMKIF_NUM_RTDATAS * sizeof(IMG_HANDLE); - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - { - IMG_UINT32 i; - - for (i = 0; i < RGXMKIF_NUM_RTDATA_FREELISTS; i++) - { - /* Look up the address from the handle */ - psRGXCreateHWRTDataSetOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psapsFreeListsInt[i], - hapsFreeListsInt2[i], - PVRSRV_HANDLE_TYPE_RGX_FREELIST, IMG_TRUE); - if (unlikely(psRGXCreateHWRTDataSetOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateHWRTDataSet_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateHWRTDataSetOUT->eError = - RGXCreateHWRTDataSet(psConnection, OSGetDevNode(psConnection), - sVHeapTableDevVAddrInt, - sPMMlistDevVAddrInt, - psapsFreeListsInt, - psRGXCreateHWRTDataSetIN->ui32PPPScreen, - psRGXCreateHWRTDataSetIN->ui64MultiSampleCtl, - psRGXCreateHWRTDataSetIN->ui64FlippedMultiSampleCtl, - psRGXCreateHWRTDataSetIN->ui32TPCStride, - sTailPtrsDevVAddrInt, - psRGXCreateHWRTDataSetIN->ui32TPCSize, - psRGXCreateHWRTDataSetIN->ui32TEScreen, - psRGXCreateHWRTDataSetIN->ui32TEAA, - psRGXCreateHWRTDataSetIN->ui32TEMTILE1, - psRGXCreateHWRTDataSetIN->ui32TEMTILE2, - psRGXCreateHWRTDataSetIN->ui32MTileStride, - psRGXCreateHWRTDataSetIN->ui32ISPMergeLowerX, - psRGXCreateHWRTDataSetIN->ui32ISPMergeLowerY, - psRGXCreateHWRTDataSetIN->ui32ISPMergeUpperX, - psRGXCreateHWRTDataSetIN->ui32ISPMergeUpperY, - psRGXCreateHWRTDataSetIN->ui32ISPMergeScaleX, - psRGXCreateHWRTDataSetIN->ui32ISPMergeScaleY, - sMacrotileArrayDevVAddrInt, - sRgnHeaderDevVAddrInt, - sRTCDevVAddrInt, - psRGXCreateHWRTDataSetIN->ui32RgnHeaderSize, - psRGXCreateHWRTDataSetIN->ui32ISPMtileSize, - psRGXCreateHWRTDataSetIN->ui16MaxRTs, psKmHwRTDataSetInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateHWRTDataSetOUT->eError != PVRSRV_OK)) - { - goto RGXCreateHWRTDataSet_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - if (hKmHwRTDataSetInt2) - { - IMG_UINT32 i; - - for (i = 0; i < RGXMKIF_NUM_RTDATAS; i++) - { - - psRGXCreateHWRTDataSetOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &hKmHwRTDataSetInt2[i], - (void *)psKmHwRTDataSetInt[i], - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateHWRTDataSetpsKmHwRTDataSetIntRelease); - if (unlikely(psRGXCreateHWRTDataSetOUT->eError != PVRSRV_OK)) - { - IMG_UINT32 j; - /* Ensure the remaining handles are set to NULL. hKmHwRTDataSetInt2[i] was - * zeroed when calling PVRSRVAllocHandleUnlocked, so we start at the next - * element. If it was the last iteration, the loop doesn't run. - */ - for (j = i + 1; j < RGXMKIF_NUM_RTDATAS; j++) - { - hKmHwRTDataSetInt2[j] = NULL; - } - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateHWRTDataSet_exit; - } - - } - } - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* If dest ptr is non-null and we have data to copy */ - if ((hKmHwRTDataSetInt2) && ((RGXMKIF_NUM_RTDATAS * sizeof(RGX_KM_HW_RT_DATASET *)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psRGXCreateHWRTDataSetOUT->phKmHwRTDataSet, - hKmHwRTDataSetInt2, - (RGXMKIF_NUM_RTDATAS * sizeof(RGX_KM_HW_RT_DATASET *))) != PVRSRV_OK)) - { - psRGXCreateHWRTDataSetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateHWRTDataSet_exit; - } - } - -RGXCreateHWRTDataSet_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - if (hapsFreeListsInt2) - { - IMG_UINT32 i; - - for (i = 0; i < RGXMKIF_NUM_RTDATA_FREELISTS; i++) - { - - /* Unreference the previously looked up handle */ - if (psapsFreeListsInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hapsFreeListsInt2[i], - PVRSRV_HANDLE_TYPE_RGX_FREELIST); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateHWRTDataSetOUT->eError != PVRSRV_OK) - { - if (hKmHwRTDataSetInt2) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - { - IMG_UINT32 idx; - for (idx = 0; idx < RGXMKIF_NUM_RTDATAS; idx++) - { - if (hKmHwRTDataSetInt2[idx]) - { - - eError = - PVRSRVDestroyHandleUnlocked(psConnection-> - psHandleBase, - hKmHwRTDataSetInt2 - [idx], - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET); - if (unlikely - ((eError != PVRSRV_OK) - && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, - PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) - || (eError == PVRSRV_ERROR_RETRY)); - - } - else - { - /* Free/Destroy/Release the resource */ - RGXDestroyHWRTDataSet(psKmHwRTDataSetInt[idx]); - } - } - } - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psKmHwRTDataSetInt) - { - IMG_UINT32 i; - for (i = 0; i < RGXMKIF_NUM_RTDATAS; i++) - { - if (psKmHwRTDataSetInt[i]) - { - RGXDestroyHWRTDataSet(psKmHwRTDataSetInt[i]); - } - } - } - - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXCreateHWRTDataSetOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyHWRTDataSet(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyHWRTDataSetIN_UI8, - IMG_UINT8 * psRGXDestroyHWRTDataSetOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET *psRGXDestroyHWRTDataSetIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET *) - IMG_OFFSET_ADDR(psRGXDestroyHWRTDataSetIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET *psRGXDestroyHWRTDataSetOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET *) - IMG_OFFSET_ADDR(psRGXDestroyHWRTDataSetOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyHWRTDataSetOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyHWRTDataSetIN-> - hKmHwRTDataSet, - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET); - if (unlikely - ((psRGXDestroyHWRTDataSetOUT->eError != PVRSRV_OK) - && (psRGXDestroyHWRTDataSetOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyHWRTDataSetOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyHWRTDataSetOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyHWRTDataSet_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyHWRTDataSet_exit: - - return 0; -} - -static PVRSRV_ERROR _RGXCreateZSBufferpssZSBufferKMIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXDestroyZSBufferKM((RGX_ZSBUFFER_DATA *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXCreateZSBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateZSBufferIN_UI8, - IMG_UINT8 * psRGXCreateZSBufferOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER *psRGXCreateZSBufferIN = - (PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER *) IMG_OFFSET_ADDR(psRGXCreateZSBufferIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER *psRGXCreateZSBufferOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER *) IMG_OFFSET_ADDR(psRGXCreateZSBufferOUT_UI8, 0); - - IMG_HANDLE hReservation = psRGXCreateZSBufferIN->hReservation; - DEVMEMINT_RESERVATION *psReservationInt = NULL; - IMG_HANDLE hPMR = psRGXCreateZSBufferIN->hPMR; - PMR *psPMRInt = NULL; - RGX_ZSBUFFER_DATA *pssZSBufferKMInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateZSBufferOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION, IMG_TRUE); - if (unlikely(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer_exit; - } - - /* Look up the address from the handle */ - psRGXCreateZSBufferOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateZSBufferOUT->eError = - RGXCreateZSBufferKM(psConnection, OSGetDevNode(psConnection), - psReservationInt, - psPMRInt, psRGXCreateZSBufferIN->uiMapFlags, &pssZSBufferKMInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)) - { - goto RGXCreateZSBuffer_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateZSBufferOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateZSBufferOUT-> - hsZSBufferKM, - (void *)pssZSBufferKMInt, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateZSBufferpssZSBufferKMIntRelease); - if (unlikely(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateZSBuffer_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateZSBufferOUT->eError != PVRSRV_OK) - { - if (pssZSBufferKMInt) - { - RGXDestroyZSBufferKM(pssZSBufferKMInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyZSBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyZSBufferIN_UI8, - IMG_UINT8 * psRGXDestroyZSBufferOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER *psRGXDestroyZSBufferIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER *) IMG_OFFSET_ADDR(psRGXDestroyZSBufferIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER *psRGXDestroyZSBufferOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER *) IMG_OFFSET_ADDR(psRGXDestroyZSBufferOUT_UI8, - 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyZSBufferOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyZSBufferIN-> - hsZSBufferMemDesc, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER); - if (unlikely - ((psRGXDestroyZSBufferOUT->eError != PVRSRV_OK) - && (psRGXDestroyZSBufferOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyZSBufferOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyZSBufferOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyZSBuffer_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyZSBuffer_exit: - - return 0; -} - -static PVRSRV_ERROR _RGXPopulateZSBufferpssPopulationIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXUnpopulateZSBufferKM((RGX_POPULATION *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXPopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXPopulateZSBufferIN_UI8, - IMG_UINT8 * psRGXPopulateZSBufferOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferIN = - (PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER *) IMG_OFFSET_ADDR(psRGXPopulateZSBufferIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferOUT = - (PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER *) IMG_OFFSET_ADDR(psRGXPopulateZSBufferOUT_UI8, - 0); - - IMG_HANDLE hsZSBufferKM = psRGXPopulateZSBufferIN->hsZSBufferKM; - RGX_ZSBUFFER_DATA *pssZSBufferKMInt = NULL; - RGX_POPULATION *pssPopulationInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXPopulateZSBufferOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&pssZSBufferKMInt, - hsZSBufferKM, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, IMG_TRUE); - if (unlikely(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXPopulateZSBuffer_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXPopulateZSBufferOUT->eError = - RGXPopulateZSBufferKM(pssZSBufferKMInt, &pssPopulationInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)) - { - goto RGXPopulateZSBuffer_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXPopulateZSBufferOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXPopulateZSBufferOUT-> - hsPopulation, - (void *)pssPopulationInt, - PVRSRV_HANDLE_TYPE_RGX_POPULATION, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXPopulateZSBufferpssPopulationIntRelease); - if (unlikely(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXPopulateZSBuffer_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXPopulateZSBuffer_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (pssZSBufferKMInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hsZSBufferKM, PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXPopulateZSBufferOUT->eError != PVRSRV_OK) - { - if (pssPopulationInt) - { - RGXUnpopulateZSBufferKM(pssPopulationInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXUnpopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXUnpopulateZSBufferIN_UI8, - IMG_UINT8 * psRGXUnpopulateZSBufferOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER *psRGXUnpopulateZSBufferIN = - (PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER *) - IMG_OFFSET_ADDR(psRGXUnpopulateZSBufferIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER *psRGXUnpopulateZSBufferOUT = - (PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER *) - IMG_OFFSET_ADDR(psRGXUnpopulateZSBufferOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXUnpopulateZSBufferOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXUnpopulateZSBufferIN->hsPopulation, - PVRSRV_HANDLE_TYPE_RGX_POPULATION); - if (unlikely((psRGXUnpopulateZSBufferOUT->eError != PVRSRV_OK) && - (psRGXUnpopulateZSBufferOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psRGXUnpopulateZSBufferOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXUnpopulateZSBufferOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXUnpopulateZSBuffer_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXUnpopulateZSBuffer_exit: - - return 0; -} - -static PVRSRV_ERROR _RGXCreateFreeListpsCleanupCookieIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXDestroyFreeList((RGX_FREELIST *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXCreateFreeList(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateFreeListIN_UI8, - IMG_UINT8 * psRGXCreateFreeListOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEFREELIST *psRGXCreateFreeListIN = - (PVRSRV_BRIDGE_IN_RGXCREATEFREELIST *) IMG_OFFSET_ADDR(psRGXCreateFreeListIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST *psRGXCreateFreeListOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST *) IMG_OFFSET_ADDR(psRGXCreateFreeListOUT_UI8, 0); - - IMG_HANDLE hMemCtxPrivData = psRGXCreateFreeListIN->hMemCtxPrivData; - IMG_HANDLE hMemCtxPrivDataInt = NULL; - IMG_HANDLE hsGlobalFreeList = psRGXCreateFreeListIN->hsGlobalFreeList; - RGX_FREELIST *pssGlobalFreeListInt = NULL; - IMG_HANDLE hsFreeListPMR = psRGXCreateFreeListIN->hsFreeListPMR; - PMR *pssFreeListPMRInt = NULL; - RGX_FREELIST *psCleanupCookieInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateFreeListOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hMemCtxPrivDataInt, - hMemCtxPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateFreeListOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList_exit; - } - - if (psRGXCreateFreeListIN->hsGlobalFreeList) - { - /* Look up the address from the handle */ - psRGXCreateFreeListOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&pssGlobalFreeListInt, - hsGlobalFreeList, - PVRSRV_HANDLE_TYPE_RGX_FREELIST, IMG_TRUE); - if (unlikely(psRGXCreateFreeListOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList_exit; - } - } - - /* Look up the address from the handle */ - psRGXCreateFreeListOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&pssFreeListPMRInt, - hsFreeListPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXCreateFreeListOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateFreeListOUT->eError = - RGXCreateFreeList(psConnection, OSGetDevNode(psConnection), - hMemCtxPrivDataInt, - psRGXCreateFreeListIN->ui32MaxFLPages, - psRGXCreateFreeListIN->ui32InitFLPages, - psRGXCreateFreeListIN->ui32GrowFLPages, - psRGXCreateFreeListIN->ui32GrowParamThreshold, - pssGlobalFreeListInt, - psRGXCreateFreeListIN->bbFreeListCheck, - psRGXCreateFreeListIN->spsFreeListDevVAddr, - pssFreeListPMRInt, - psRGXCreateFreeListIN->uiPMROffset, &psCleanupCookieInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateFreeListOUT->eError != PVRSRV_OK)) - { - goto RGXCreateFreeList_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateFreeListOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateFreeListOUT-> - hCleanupCookie, - (void *)psCleanupCookieInt, - PVRSRV_HANDLE_TYPE_RGX_FREELIST, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateFreeListpsCleanupCookieIntRelease); - if (unlikely(psRGXCreateFreeListOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateFreeList_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hMemCtxPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hMemCtxPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - - if (psRGXCreateFreeListIN->hsGlobalFreeList) - { - - /* Unreference the previously looked up handle */ - if (pssGlobalFreeListInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hsGlobalFreeList, - PVRSRV_HANDLE_TYPE_RGX_FREELIST); - } - } - - /* Unreference the previously looked up handle */ - if (pssFreeListPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hsFreeListPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateFreeListOUT->eError != PVRSRV_OK) - { - if (psCleanupCookieInt) - { - RGXDestroyFreeList(psCleanupCookieInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyFreeList(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyFreeListIN_UI8, - IMG_UINT8 * psRGXDestroyFreeListOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST *psRGXDestroyFreeListIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST *) IMG_OFFSET_ADDR(psRGXDestroyFreeListIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST *psRGXDestroyFreeListOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST *) IMG_OFFSET_ADDR(psRGXDestroyFreeListOUT_UI8, - 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyFreeListOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyFreeListIN->hCleanupCookie, - PVRSRV_HANDLE_TYPE_RGX_FREELIST); - if (unlikely((psRGXDestroyFreeListOUT->eError != PVRSRV_OK) && - (psRGXDestroyFreeListOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psRGXDestroyFreeListOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyFreeListOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyFreeList_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyFreeList_exit: - - return 0; -} - -static PVRSRV_ERROR _RGXCreateRenderContextpsRenderContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXDestroyRenderContextKM((RGX_SERVER_RENDER_CONTEXT *) pvData); - return eError; -} - -static_assert(RGXFWIF_RF_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_RF_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_STATIC_RENDERCONTEXT_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_STATIC_RENDERCONTEXT_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXCreateRenderContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateRenderContextIN_UI8, - IMG_UINT8 * psRGXCreateRenderContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT *psRGXCreateRenderContextIN = - (PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateRenderContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT *psRGXCreateRenderContextOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateRenderContextOUT_UI8, 0); - - IMG_BYTE *ui8FrameworkCmdInt = NULL; - IMG_HANDLE hPrivData = psRGXCreateRenderContextIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - IMG_BYTE *ui8StaticRenderContextStateInt = NULL; - RGX_SERVER_RENDER_CONTEXT *psRenderContextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXCreateRenderContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize * - sizeof(IMG_BYTE)) + 0; - - if (unlikely(psRGXCreateRenderContextIN->ui32FrameworkCmdSize > RGXFWIF_RF_CMD_SIZE)) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXCreateRenderContext_exit; - } - - if (unlikely - (psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize > - RGXFWIF_STATIC_RENDERCONTEXT_SIZE)) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXCreateRenderContext_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXCreateRenderContext_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXCreateRenderContextIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXCreateRenderContextIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXCreateRenderContext_exit; - } - } - } - - if (psRGXCreateRenderContextIN->ui32FrameworkCmdSize != 0) - { - ui8FrameworkCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXCreateRenderContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXCreateRenderContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8FrameworkCmdInt, - (const void __user *)psRGXCreateRenderContextIN->pui8FrameworkCmd, - psRGXCreateRenderContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) != - PVRSRV_OK) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateRenderContext_exit; - } - } - if (psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize != 0) - { - ui8StaticRenderContextStateInt = - (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8StaticRenderContextStateInt, - (const void __user *)psRGXCreateRenderContextIN->pui8StaticRenderContextState, - psRGXCreateRenderContextIN->ui32StaticRenderContextStateSize * - sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateRenderContext_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateRenderContextOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateRenderContext_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateRenderContextOUT->eError = - PVRSRVRGXCreateRenderContextKM(psConnection, OSGetDevNode(psConnection), - psRGXCreateRenderContextIN->ui32Priority, - psRGXCreateRenderContextIN->sVDMCallStackAddr, - psRGXCreateRenderContextIN->ui32ui32CallStackDepth, - psRGXCreateRenderContextIN->ui32FrameworkCmdSize, - ui8FrameworkCmdInt, - hPrivDataInt, - psRGXCreateRenderContextIN-> - ui32StaticRenderContextStateSize, - ui8StaticRenderContextStateInt, - psRGXCreateRenderContextIN->ui32PackedCCBSizeU8888, - psRGXCreateRenderContextIN->ui32ContextFlags, - psRGXCreateRenderContextIN->ui64RobustnessAddress, - psRGXCreateRenderContextIN->ui32MaxTADeadlineMS, - psRGXCreateRenderContextIN->ui32Max3DDeadlineMS, - &psRenderContextInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)) - { - goto RGXCreateRenderContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateRenderContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateRenderContextOUT-> - hRenderContext, - (void *)psRenderContextInt, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateRenderContextpsRenderContextIntRelease); - if (unlikely(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateRenderContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateRenderContext_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateRenderContextOUT->eError != PVRSRV_OK) - { - if (psRenderContextInt) - { - PVRSRVRGXDestroyRenderContextKM(psRenderContextInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXCreateRenderContextOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyRenderContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyRenderContextIN_UI8, - IMG_UINT8 * psRGXDestroyRenderContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT *psRGXDestroyRenderContextIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyRenderContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT *psRGXDestroyRenderContextOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyRenderContextOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyRenderContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyRenderContextIN-> - hCleanupCookie, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT); - if (unlikely - ((psRGXDestroyRenderContextOUT->eError != PVRSRV_OK) - && (psRGXDestroyRenderContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyRenderContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyRenderContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyRenderContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyRenderContext_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetRenderContextPriority(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetRenderContextPriorityIN_UI8, - IMG_UINT8 * psRGXSetRenderContextPriorityOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityIN = - (PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetRenderContextPriorityIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityOUT = - (PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetRenderContextPriorityOUT_UI8, 0); - - IMG_HANDLE hRenderContext = psRGXSetRenderContextPriorityIN->hRenderContext; - RGX_SERVER_RENDER_CONTEXT *psRenderContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetRenderContextPriorityOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psRenderContextInt, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetRenderContextPriorityOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetRenderContextPriority_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetRenderContextPriorityOUT->eError = - PVRSRVRGXSetRenderContextPriorityKM(psConnection, OSGetDevNode(psConnection), - psRenderContextInt, - psRGXSetRenderContextPriorityIN->ui32Priority); - -RGXSetRenderContextPriority_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psRenderContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXRenderContextStalled(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXRenderContextStalledIN_UI8, - IMG_UINT8 * psRGXRenderContextStalledOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED *psRGXRenderContextStalledIN = - (PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED *) - IMG_OFFSET_ADDR(psRGXRenderContextStalledIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED *psRGXRenderContextStalledOUT = - (PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED *) - IMG_OFFSET_ADDR(psRGXRenderContextStalledOUT_UI8, 0); - - IMG_HANDLE hRenderContext = psRGXRenderContextStalledIN->hRenderContext; - RGX_SERVER_RENDER_CONTEXT *psRenderContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXRenderContextStalledOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psRenderContextInt, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, IMG_TRUE); - if (unlikely(psRGXRenderContextStalledOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXRenderContextStalled_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXRenderContextStalledOUT->eError = RGXRenderContextStalledKM(psRenderContextInt); - -RGXRenderContextStalled_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psRenderContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXKickTA3D2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXKickTA3D2IN_UI8, - IMG_UINT8 * psRGXKickTA3D2OUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXKICKTA3D2 *psRGXKickTA3D2IN = - (PVRSRV_BRIDGE_IN_RGXKICKTA3D2 *) IMG_OFFSET_ADDR(psRGXKickTA3D2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXKICKTA3D2 *psRGXKickTA3D2OUT = - (PVRSRV_BRIDGE_OUT_RGXKICKTA3D2 *) IMG_OFFSET_ADDR(psRGXKickTA3D2OUT_UI8, 0); - - IMG_HANDLE hRenderContext = psRGXKickTA3D2IN->hRenderContext; - RGX_SERVER_RENDER_CONTEXT *psRenderContextInt = NULL; - SYNC_PRIMITIVE_BLOCK **psClientTAFenceSyncPrimBlockInt = NULL; - IMG_HANDLE *hClientTAFenceSyncPrimBlockInt2 = NULL; - IMG_UINT32 *ui32ClientTAFenceSyncOffsetInt = NULL; - IMG_UINT32 *ui32ClientTAFenceValueInt = NULL; - SYNC_PRIMITIVE_BLOCK **psClientTAUpdateSyncPrimBlockInt = NULL; - IMG_HANDLE *hClientTAUpdateSyncPrimBlockInt2 = NULL; - IMG_UINT32 *ui32ClientTAUpdateSyncOffsetInt = NULL; - IMG_UINT32 *ui32ClientTAUpdateValueInt = NULL; - SYNC_PRIMITIVE_BLOCK **psClient3DUpdateSyncPrimBlockInt = NULL; - IMG_HANDLE *hClient3DUpdateSyncPrimBlockInt2 = NULL; - IMG_UINT32 *ui32Client3DUpdateSyncOffsetInt = NULL; - IMG_UINT32 *ui32Client3DUpdateValueInt = NULL; - IMG_HANDLE hPRFenceUFOSyncPrimBlock = psRGXKickTA3D2IN->hPRFenceUFOSyncPrimBlock; - SYNC_PRIMITIVE_BLOCK *psPRFenceUFOSyncPrimBlockInt = NULL; - IMG_CHAR *uiUpdateFenceNameInt = NULL; - IMG_CHAR *uiUpdateFenceName3DInt = NULL; - IMG_BYTE *ui8TACmdInt = NULL; - IMG_BYTE *ui83DPRCmdInt = NULL; - IMG_BYTE *ui83DCmdInt = NULL; - IMG_HANDLE hKMHWRTDataSet = psRGXKickTA3D2IN->hKMHWRTDataSet; - RGX_KM_HW_RT_DATASET *psKMHWRTDataSetInt = NULL; - IMG_HANDLE hZSBuffer = psRGXKickTA3D2IN->hZSBuffer; - RGX_ZSBUFFER_DATA *psZSBufferInt = NULL; - IMG_HANDLE hMSAAScratchBuffer = psRGXKickTA3D2IN->hMSAAScratchBuffer; - RGX_ZSBUFFER_DATA *psMSAAScratchBufferInt = NULL; - IMG_UINT32 *ui32SyncPMRFlagsInt = NULL; - PMR **psSyncPMRsInt = NULL; - IMG_HANDLE *hSyncPMRsInt2 = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAFenceCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32Client3DUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32TACmdSize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui323DPRCmdSize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui323DCmdSize * sizeof(IMG_BYTE)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(PMR *)) + - ((IMG_UINT64) psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) + 0; - - if (unlikely(psRGXKickTA3D2IN->ui32ClientTAFenceCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui32ClientTAUpdateCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui32Client3DUpdateCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui32TACmdSize > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui323DPRCmdSize > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui323DCmdSize > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (unlikely(psRGXKickTA3D2IN->ui32SyncPMRCount > PVRSRV_MAX_SYNCS)) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXKickTA3D2_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXKickTA3D2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXKickTA3D2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXKickTA3D2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXKickTA3D2_exit; - } - } - } - - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount != 0) - { - psClientTAFenceSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psClientTAFenceSyncPrimBlockInt, 0, - psRGXKickTA3D2IN->ui32ClientTAFenceCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *); - hClientTAFenceSyncPrimBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hClientTAFenceSyncPrimBlockInt2, - (const void __user *)psRGXKickTA3D2IN->phClientTAFenceSyncPrimBlock, - psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount != 0) - { - ui32ClientTAFenceSyncOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientTAFenceSyncOffsetInt, - (const void __user *)psRGXKickTA3D2IN->pui32ClientTAFenceSyncOffset, - psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount != 0) - { - ui32ClientTAFenceValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientTAFenceValueInt, - (const void __user *)psRGXKickTA3D2IN->pui32ClientTAFenceValue, - psRGXKickTA3D2IN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount != 0) - { - psClientTAUpdateSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psClientTAUpdateSyncPrimBlockInt, 0, - psRGXKickTA3D2IN->ui32ClientTAUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *); - hClientTAUpdateSyncPrimBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hClientTAUpdateSyncPrimBlockInt2, - (const void __user *)psRGXKickTA3D2IN->phClientTAUpdateSyncPrimBlock, - psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount != 0) - { - ui32ClientTAUpdateSyncOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientTAUpdateSyncOffsetInt, - (const void __user *)psRGXKickTA3D2IN->pui32ClientTAUpdateSyncOffset, - psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount != 0) - { - ui32ClientTAUpdateValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientTAUpdateValueInt, - (const void __user *)psRGXKickTA3D2IN->pui32ClientTAUpdateValue, - psRGXKickTA3D2IN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount != 0) - { - psClient3DUpdateSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psClient3DUpdateSyncPrimBlockInt, 0, - psRGXKickTA3D2IN->ui32Client3DUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *); - hClient3DUpdateSyncPrimBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hClient3DUpdateSyncPrimBlockInt2, - (const void __user *)psRGXKickTA3D2IN->phClient3DUpdateSyncPrimBlock, - psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount != 0) - { - ui32Client3DUpdateSyncOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32Client3DUpdateSyncOffsetInt, - (const void __user *)psRGXKickTA3D2IN->pui32Client3DUpdateSyncOffset, - psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount != 0) - { - ui32Client3DUpdateValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32Client3DUpdateValueInt, - (const void __user *)psRGXKickTA3D2IN->pui32Client3DUpdateValue, - psRGXKickTA3D2IN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - - { - uiUpdateFenceNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceNameInt, - (const void __user *)psRGXKickTA3D2IN->puiUpdateFenceName, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - ((IMG_CHAR *) uiUpdateFenceNameInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - - { - uiUpdateFenceName3DInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceName3DInt, - (const void __user *)psRGXKickTA3D2IN->puiUpdateFenceName3D, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - ((IMG_CHAR *) uiUpdateFenceName3DInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - if (psRGXKickTA3D2IN->ui32TACmdSize != 0) - { - ui8TACmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32TACmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32TACmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8TACmdInt, (const void __user *)psRGXKickTA3D2IN->pui8TACmd, - psRGXKickTA3D2IN->ui32TACmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui323DPRCmdSize != 0) - { - ui83DPRCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui323DPRCmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui323DPRCmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui83DPRCmdInt, (const void __user *)psRGXKickTA3D2IN->pui83DPRCmd, - psRGXKickTA3D2IN->ui323DPRCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui323DCmdSize != 0) - { - ui83DCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui323DCmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui323DCmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui83DCmdInt, (const void __user *)psRGXKickTA3D2IN->pui83DCmd, - psRGXKickTA3D2IN->ui323DCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32SyncPMRCount != 0) - { - ui32SyncPMRFlagsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32SyncPMRFlagsInt, - (const void __user *)psRGXKickTA3D2IN->pui32SyncPMRFlags, - psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - if (psRGXKickTA3D2IN->ui32SyncPMRCount != 0) - { - psSyncPMRsInt = (PMR **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psSyncPMRsInt, 0, - psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(PMR *)); - ui32NextOffset += psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(PMR *); - hSyncPMRsInt2 = (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hSyncPMRsInt2, (const void __user *)psRGXKickTA3D2IN->phSyncPMRs, - psRGXKickTA3D2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXKickTA3D2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXKickTA3D2_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psRenderContextInt, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32ClientTAFenceCount; i++) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psClientTAFenceSyncPrimBlockInt[i], - hClientTAFenceSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32ClientTAUpdateCount; i++) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **) - &psClientTAUpdateSyncPrimBlockInt[i], - hClientTAUpdateSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32Client3DUpdateCount; i++) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **) - &psClient3DUpdateSyncPrimBlockInt[i], - hClient3DUpdateSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - } - - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPRFenceUFOSyncPrimBlockInt, - hPRFenceUFOSyncPrimBlock, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - - if (psRGXKickTA3D2IN->hKMHWRTDataSet) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psKMHWRTDataSetInt, - hKMHWRTDataSet, - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - - if (psRGXKickTA3D2IN->hZSBuffer) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psZSBufferInt, - hZSBuffer, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - - if (psRGXKickTA3D2IN->hMSAAScratchBuffer) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psMSAAScratchBufferInt, - hMSAAScratchBuffer, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32SyncPMRCount; i++) - { - /* Look up the address from the handle */ - psRGXKickTA3D2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncPMRsInt[i], - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXKickTA3D2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXKickTA3D2_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXKickTA3D2OUT->eError = - PVRSRVRGXKickTA3DKM(psRenderContextInt, - psRGXKickTA3D2IN->ui32ClientTAFenceCount, - psClientTAFenceSyncPrimBlockInt, - ui32ClientTAFenceSyncOffsetInt, - ui32ClientTAFenceValueInt, - psRGXKickTA3D2IN->ui32ClientTAUpdateCount, - psClientTAUpdateSyncPrimBlockInt, - ui32ClientTAUpdateSyncOffsetInt, - ui32ClientTAUpdateValueInt, - psRGXKickTA3D2IN->ui32Client3DUpdateCount, - psClient3DUpdateSyncPrimBlockInt, - ui32Client3DUpdateSyncOffsetInt, - ui32Client3DUpdateValueInt, - psPRFenceUFOSyncPrimBlockInt, - psRGXKickTA3D2IN->ui32PRFenceUFOSyncOffset, - psRGXKickTA3D2IN->ui32PRFenceValue, - psRGXKickTA3D2IN->hCheckFence, - psRGXKickTA3D2IN->hUpdateTimeline, - &psRGXKickTA3D2OUT->hUpdateFence, - uiUpdateFenceNameInt, - psRGXKickTA3D2IN->hCheckFence3D, - psRGXKickTA3D2IN->hUpdateTimeline3D, - &psRGXKickTA3D2OUT->hUpdateFence3D, - uiUpdateFenceName3DInt, - psRGXKickTA3D2IN->ui32TACmdSize, - ui8TACmdInt, - psRGXKickTA3D2IN->ui323DPRCmdSize, - ui83DPRCmdInt, - psRGXKickTA3D2IN->ui323DCmdSize, - ui83DCmdInt, - psRGXKickTA3D2IN->ui32ExtJobRef, - psRGXKickTA3D2IN->bbKickTA, - psRGXKickTA3D2IN->bbKickPR, - psRGXKickTA3D2IN->bbKick3D, - psRGXKickTA3D2IN->bbAbort, - psRGXKickTA3D2IN->ui32PDumpFlags, - psKMHWRTDataSetInt, - psZSBufferInt, - psMSAAScratchBufferInt, - psRGXKickTA3D2IN->ui32SyncPMRCount, - ui32SyncPMRFlagsInt, - psSyncPMRsInt, - psRGXKickTA3D2IN->ui32RenderTargetSize, - psRGXKickTA3D2IN->ui32NumberOfDrawCalls, - psRGXKickTA3D2IN->ui32NumberOfIndices, - psRGXKickTA3D2IN->ui32NumberOfMRTs, psRGXKickTA3D2IN->ui64Deadline); - -RGXKickTA3D2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psRenderContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT); - } - - if (hClientTAFenceSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32ClientTAFenceCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psClientTAFenceSyncPrimBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hClientTAFenceSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - - if (hClientTAUpdateSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32ClientTAUpdateCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psClientTAUpdateSyncPrimBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hClientTAUpdateSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - - if (hClient3DUpdateSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32Client3DUpdateCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psClient3DUpdateSyncPrimBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hClient3DUpdateSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - - /* Unreference the previously looked up handle */ - if (psPRFenceUFOSyncPrimBlockInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPRFenceUFOSyncPrimBlock, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - - if (psRGXKickTA3D2IN->hKMHWRTDataSet) - { - - /* Unreference the previously looked up handle */ - if (psKMHWRTDataSetInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hKMHWRTDataSet, - PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET); - } - } - - if (psRGXKickTA3D2IN->hZSBuffer) - { - - /* Unreference the previously looked up handle */ - if (psZSBufferInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hZSBuffer, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER); - } - } - - if (psRGXKickTA3D2IN->hMSAAScratchBuffer) - { - - /* Unreference the previously looked up handle */ - if (psMSAAScratchBufferInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hMSAAScratchBuffer, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER); - } - } - - if (hSyncPMRsInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXKickTA3D2IN->ui32SyncPMRCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psSyncPMRsInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXKickTA3D2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetRenderContextProperty(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetRenderContextPropertyIN_UI8, - IMG_UINT8 * psRGXSetRenderContextPropertyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY *psRGXSetRenderContextPropertyIN = - (PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetRenderContextPropertyIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY *psRGXSetRenderContextPropertyOUT = - (PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetRenderContextPropertyOUT_UI8, 0); - - IMG_HANDLE hRenderContext = psRGXSetRenderContextPropertyIN->hRenderContext; - RGX_SERVER_RENDER_CONTEXT *psRenderContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetRenderContextPropertyOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psRenderContextInt, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetRenderContextPropertyOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetRenderContextProperty_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetRenderContextPropertyOUT->eError = - PVRSRVRGXSetRenderContextPropertyKM(psRenderContextInt, - psRGXSetRenderContextPropertyIN->ui32Property, - psRGXSetRenderContextPropertyIN->ui64Input, - &psRGXSetRenderContextPropertyOUT->ui64Output); - -RGXSetRenderContextProperty_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psRenderContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hRenderContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static PVRSRV_ERROR _RGXCreateZSBuffer2pssZSBufferKMIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXDestroyZSBufferKM((RGX_ZSBUFFER_DATA *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXCreateZSBuffer2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateZSBuffer2IN_UI8, - IMG_UINT8 * psRGXCreateZSBuffer2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER2 *psRGXCreateZSBuffer2IN = - (PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER2 *) IMG_OFFSET_ADDR(psRGXCreateZSBuffer2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER2 *psRGXCreateZSBuffer2OUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER2 *) IMG_OFFSET_ADDR(psRGXCreateZSBuffer2OUT_UI8, - 0); - - IMG_HANDLE hReservation = psRGXCreateZSBuffer2IN->hReservation; - DEVMEMINT_RESERVATION2 *psReservationInt = NULL; - IMG_HANDLE hPMR = psRGXCreateZSBuffer2IN->hPMR; - PMR *psPMRInt = NULL; - RGX_ZSBUFFER_DATA *pssZSBufferKMInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateZSBuffer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psReservationInt, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, IMG_TRUE); - if (unlikely(psRGXCreateZSBuffer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer2_exit; - } - - /* Look up the address from the handle */ - psRGXCreateZSBuffer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRInt, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXCreateZSBuffer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateZSBuffer2OUT->eError = - RGXCreateZSBufferKM2(psConnection, OSGetDevNode(psConnection), - psReservationInt, - psPMRInt, psRGXCreateZSBuffer2IN->uiMapFlags, &pssZSBufferKMInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateZSBuffer2OUT->eError != PVRSRV_OK)) - { - goto RGXCreateZSBuffer2_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateZSBuffer2OUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateZSBuffer2OUT-> - hsZSBufferKM, - (void *)pssZSBufferKMInt, - PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateZSBuffer2pssZSBufferKMIntRelease); - if (unlikely(psRGXCreateZSBuffer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateZSBuffer2_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateZSBuffer2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - } - - /* Unreference the previously looked up handle */ - if (psPMRInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateZSBuffer2OUT->eError != PVRSRV_OK) - { - if (pssZSBufferKMInt) - { - RGXDestroyZSBufferKM(pssZSBufferKMInt); - } - } - - return 0; -} - -static PVRSRV_ERROR _RGXCreateFreeList2psCleanupCookieIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RGXDestroyFreeList((RGX_FREELIST *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXCreateFreeList2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateFreeList2IN_UI8, - IMG_UINT8 * psRGXCreateFreeList2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATEFREELIST2 *psRGXCreateFreeList2IN = - (PVRSRV_BRIDGE_IN_RGXCREATEFREELIST2 *) IMG_OFFSET_ADDR(psRGXCreateFreeList2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST2 *psRGXCreateFreeList2OUT = - (PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST2 *) IMG_OFFSET_ADDR(psRGXCreateFreeList2OUT_UI8, - 0); - - IMG_HANDLE hMemCtxPrivData = psRGXCreateFreeList2IN->hMemCtxPrivData; - IMG_HANDLE hMemCtxPrivDataInt = NULL; - IMG_HANDLE hsGlobalFreeList = psRGXCreateFreeList2IN->hsGlobalFreeList; - RGX_FREELIST *pssGlobalFreeListInt = NULL; - IMG_HANDLE hFreeListReservation = psRGXCreateFreeList2IN->hFreeListReservation; - DEVMEMINT_RESERVATION2 *psFreeListReservationInt = NULL; - RGX_FREELIST *psCleanupCookieInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateFreeList2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hMemCtxPrivDataInt, - hMemCtxPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateFreeList2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList2_exit; - } - - if (psRGXCreateFreeList2IN->hsGlobalFreeList) - { - /* Look up the address from the handle */ - psRGXCreateFreeList2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&pssGlobalFreeListInt, - hsGlobalFreeList, - PVRSRV_HANDLE_TYPE_RGX_FREELIST, IMG_TRUE); - if (unlikely(psRGXCreateFreeList2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList2_exit; - } - } - - /* Look up the address from the handle */ - psRGXCreateFreeList2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psFreeListReservationInt, - hFreeListReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2, IMG_TRUE); - if (unlikely(psRGXCreateFreeList2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList2_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateFreeList2OUT->eError = - RGXCreateFreeList2(psConnection, OSGetDevNode(psConnection), - hMemCtxPrivDataInt, - psRGXCreateFreeList2IN->ui32MaxFLPages, - psRGXCreateFreeList2IN->ui32InitFLPages, - psRGXCreateFreeList2IN->ui32GrowFLPages, - psRGXCreateFreeList2IN->ui32GrowParamThreshold, - pssGlobalFreeListInt, - psRGXCreateFreeList2IN->bbFreeListCheck, - psFreeListReservationInt, &psCleanupCookieInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateFreeList2OUT->eError != PVRSRV_OK)) - { - goto RGXCreateFreeList2_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateFreeList2OUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateFreeList2OUT-> - hCleanupCookie, - (void *)psCleanupCookieInt, - PVRSRV_HANDLE_TYPE_RGX_FREELIST, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateFreeList2psCleanupCookieIntRelease); - if (unlikely(psRGXCreateFreeList2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateFreeList2_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateFreeList2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hMemCtxPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hMemCtxPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - - if (psRGXCreateFreeList2IN->hsGlobalFreeList) - { - - /* Unreference the previously looked up handle */ - if (pssGlobalFreeListInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hsGlobalFreeList, - PVRSRV_HANDLE_TYPE_RGX_FREELIST); - } - } - - /* Unreference the previously looked up handle */ - if (psFreeListReservationInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hFreeListReservation, - PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION2); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateFreeList2OUT->eError != PVRSRV_OK) - { - if (psCleanupCookieInt) - { - RGXDestroyFreeList(psCleanupCookieInt); - } - } - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXTA3DBridge(void); -void DeinitRGXTA3DBridge(void); - -/* - * Register all RGXTA3D functions with services - */ -PVRSRV_ERROR InitRGXTA3DBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATASET, - PVRSRVBridgeRGXCreateHWRTDataSet, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATASET, - PVRSRVBridgeRGXDestroyHWRTDataSet, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER, - PVRSRVBridgeRGXCreateZSBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER, - PVRSRVBridgeRGXDestroyZSBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER, - PVRSRVBridgeRGXPopulateZSBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER, - PVRSRVBridgeRGXUnpopulateZSBuffer, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER), - sizeof(PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST, - PVRSRVBridgeRGXCreateFreeList, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEFREELIST), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST, - PVRSRVBridgeRGXDestroyFreeList, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT, - PVRSRVBridgeRGXCreateRenderContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT, - PVRSRVBridgeRGXDestroyRenderContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY, - PVRSRVBridgeRGXSetRenderContextPriority, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXRENDERCONTEXTSTALLED, - PVRSRVBridgeRGXRenderContextStalled, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED), - sizeof(PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D2, - PVRSRVBridgeRGXKickTA3D2, NULL, sizeof(PVRSRV_BRIDGE_IN_RGXKICKTA3D2), - sizeof(PVRSRV_BRIDGE_OUT_RGXKICKTA3D2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPROPERTY, - PVRSRVBridgeRGXSetRenderContextProperty, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER2, - PVRSRVBridgeRGXCreateZSBuffer2, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER2), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST2, - PVRSRVBridgeRGXCreateFreeList2, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATEFREELIST2), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST2)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxta3d functions with services - */ -void DeinitRGXTA3DBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATASET); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATASET); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXRENDERCONTEXTSTALLED); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, - PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPROPERTY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST2); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxtimerquery_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxtimerquery_bridge.c deleted file mode 100644 index 4af3cfc35cbaf..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxtimerquery_bridge.c +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxtimerquery -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxtimerquery -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxtimerquery.h" - -#include "common_rgxtimerquery_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRGXBeginTimerQuery(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXBeginTimerQueryIN_UI8, - IMG_UINT8 * psRGXBeginTimerQueryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY *psRGXBeginTimerQueryIN = - (PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY *) IMG_OFFSET_ADDR(psRGXBeginTimerQueryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY *psRGXBeginTimerQueryOUT = - (PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY *) IMG_OFFSET_ADDR(psRGXBeginTimerQueryOUT_UI8, - 0); - - psRGXBeginTimerQueryOUT->eError = - PVRSRVRGXBeginTimerQueryKM(psConnection, OSGetDevNode(psConnection), - psRGXBeginTimerQueryIN->ui32QueryId); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXEndTimerQuery(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXEndTimerQueryIN_UI8, - IMG_UINT8 * psRGXEndTimerQueryOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY *psRGXEndTimerQueryIN = - (PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY *) IMG_OFFSET_ADDR(psRGXEndTimerQueryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY *psRGXEndTimerQueryOUT = - (PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY *) IMG_OFFSET_ADDR(psRGXEndTimerQueryOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psRGXEndTimerQueryIN); - - psRGXEndTimerQueryOUT->eError = - PVRSRVRGXEndTimerQueryKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXQueryTimer(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXQueryTimerIN_UI8, - IMG_UINT8 * psRGXQueryTimerOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXQUERYTIMER *psRGXQueryTimerIN = - (PVRSRV_BRIDGE_IN_RGXQUERYTIMER *) IMG_OFFSET_ADDR(psRGXQueryTimerIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXQUERYTIMER *psRGXQueryTimerOUT = - (PVRSRV_BRIDGE_OUT_RGXQUERYTIMER *) IMG_OFFSET_ADDR(psRGXQueryTimerOUT_UI8, 0); - - psRGXQueryTimerOUT->eError = - PVRSRVRGXQueryTimerKM(psConnection, OSGetDevNode(psConnection), - psRGXQueryTimerIN->ui32QueryId, - &psRGXQueryTimerOUT->ui64StartTime, - &psRGXQueryTimerOUT->ui64EndTime); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXTIMERQUERYBridge(void); -void DeinitRGXTIMERQUERYBridge(void); - -/* - * Register all RGXTIMERQUERY functions with services - */ -PVRSRV_ERROR InitRGXTIMERQUERYBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXBEGINTIMERQUERY, - PVRSRVBridgeRGXBeginTimerQuery, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY), - sizeof(PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXENDTIMERQUERY, - PVRSRVBridgeRGXEndTimerQuery, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXQUERYTIMER, PVRSRVBridgeRGXQueryTimer, - NULL, sizeof(PVRSRV_BRIDGE_IN_RGXQUERYTIMER), - sizeof(PVRSRV_BRIDGE_OUT_RGXQUERYTIMER)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxtimerquery functions with services - */ -void DeinitRGXTIMERQUERYBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXBEGINTIMERQUERY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXENDTIMERQUERY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTIMERQUERY, - PVRSRV_BRIDGE_RGXTIMERQUERY_RGXQUERYTIMER); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxtq2_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxtq2_bridge.c deleted file mode 100644 index 35559eb2994fe..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxtq2_bridge.c +++ /dev/null @@ -1,1225 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxtq2 -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxtq2 -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxtdmtransfer.h" - -#include "common_rgxtq2_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#include "rgx_bvnc_defs_km.h" - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _RGXTDMCreateTransferContextpsTransferContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXTDMDestroyTransferContextKM((RGX_SERVER_TQ_TDM_CONTEXT *) pvData); - return eError; -} - -static_assert(RGXFWIF_RF_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_RF_CMD_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXTDMCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMCreateTransferContextIN_UI8, - IMG_UINT8 * psRGXTDMCreateTransferContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT *psRGXTDMCreateTransferContextIN = - (PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXTDMCreateTransferContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT *psRGXTDMCreateTransferContextOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXTDMCreateTransferContextOUT_UI8, 0); - - IMG_BYTE *ui8FrameworkCmdInt = NULL; - IMG_HANDLE hPrivData = psRGXTDMCreateTransferContextIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContextInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize * - sizeof(IMG_BYTE)) + 0; - - if (unlikely(psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize > RGXFWIF_RF_CMD_SIZE)) - { - psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXTDMCreateTransferContext_exit; - } - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMCreateTransferContext_exit; - } - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXTDMCreateTransferContext_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXTDMCreateTransferContextIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = - (IMG_BYTE *) (void *)psRGXTDMCreateTransferContextIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXTDMCreateTransferContextOUT->eError = - PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXTDMCreateTransferContext_exit; - } - } - } - - if (psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize != 0) - { - ui8FrameworkCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8FrameworkCmdInt, - (const void __user *)psRGXTDMCreateTransferContextIN->pui8FrameworkCmd, - psRGXTDMCreateTransferContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) != - PVRSRV_OK) - { - psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMCreateTransferContext_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXTDMCreateTransferContextOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMCreateTransferContext_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXTDMCreateTransferContextOUT->eError = - PVRSRVRGXTDMCreateTransferContextKM(psConnection, OSGetDevNode(psConnection), - psRGXTDMCreateTransferContextIN->ui32Priority, - psRGXTDMCreateTransferContextIN-> - ui32FrameworkCmdSize, ui8FrameworkCmdInt, - hPrivDataInt, - psRGXTDMCreateTransferContextIN-> - ui32PackedCCBSizeU88, - psRGXTDMCreateTransferContextIN->ui32ContextFlags, - psRGXTDMCreateTransferContextIN-> - ui64RobustnessAddress, &psTransferContextInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)) - { - goto RGXTDMCreateTransferContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXTDMCreateTransferContextOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXTDMCreateTransferContextOUT->hTransferContext, - (void *)psTransferContextInt, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXTDMCreateTransferContextpsTransferContextIntRelease); - if (unlikely(psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMCreateTransferContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXTDMCreateTransferContext_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK) - { - if (psTransferContextInt) - { - PVRSRVRGXTDMDestroyTransferContextKM(psTransferContextInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXTDMCreateTransferContextOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXTDMDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMDestroyTransferContextIN_UI8, - IMG_UINT8 * psRGXTDMDestroyTransferContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT *psRGXTDMDestroyTransferContextIN = - (PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXTDMDestroyTransferContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT *psRGXTDMDestroyTransferContextOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXTDMDestroyTransferContextOUT_UI8, 0); - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMDestroyTransferContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMDestroyTransferContext_exit; - } - } - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXTDMDestroyTransferContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXTDMDestroyTransferContextIN-> - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT); - if (unlikely - ((psRGXTDMDestroyTransferContextOUT->eError != PVRSRV_OK) - && (psRGXTDMDestroyTransferContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXTDMDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, - PVRSRVGetErrorString(psRGXTDMDestroyTransferContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMDestroyTransferContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXTDMDestroyTransferContext_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXTDMSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMSetTransferContextPriorityIN_UI8, - IMG_UINT8 * psRGXTDMSetTransferContextPriorityOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY *psRGXTDMSetTransferContextPriorityIN = - (PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXTDMSetTransferContextPriorityIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY *psRGXTDMSetTransferContextPriorityOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXTDMSetTransferContextPriorityOUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXTDMSetTransferContextPriorityIN->hTransferContext; - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMSetTransferContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMSetTransferContextPriority_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXTDMSetTransferContextPriorityOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, IMG_TRUE); - if (unlikely(psRGXTDMSetTransferContextPriorityOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMSetTransferContextPriority_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXTDMSetTransferContextPriorityOUT->eError = - PVRSRVRGXTDMSetTransferContextPriorityKM(psConnection, OSGetDevNode(psConnection), - psTransferContextInt, - psRGXTDMSetTransferContextPriorityIN-> - ui32Priority); - -RGXTDMSetTransferContextPriority_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXTDMNotifyWriteOffsetUpdate(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMNotifyWriteOffsetUpdateIN_UI8, - IMG_UINT8 * psRGXTDMNotifyWriteOffsetUpdateOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE *psRGXTDMNotifyWriteOffsetUpdateIN = - (PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE *) - IMG_OFFSET_ADDR(psRGXTDMNotifyWriteOffsetUpdateIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE *psRGXTDMNotifyWriteOffsetUpdateOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE *) - IMG_OFFSET_ADDR(psRGXTDMNotifyWriteOffsetUpdateOUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXTDMNotifyWriteOffsetUpdateIN->hTransferContext; - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMNotifyWriteOffsetUpdateOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMNotifyWriteOffsetUpdate_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXTDMNotifyWriteOffsetUpdateOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, IMG_TRUE); - if (unlikely(psRGXTDMNotifyWriteOffsetUpdateOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMNotifyWriteOffsetUpdate_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXTDMNotifyWriteOffsetUpdateOUT->eError = - PVRSRVRGXTDMNotifyWriteOffsetUpdateKM(psTransferContextInt, - psRGXTDMNotifyWriteOffsetUpdateIN-> - ui32PDumpFlags); - -RGXTDMNotifyWriteOffsetUpdate_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXTDMSubmitTransfer2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMSubmitTransfer2IN_UI8, - IMG_UINT8 * psRGXTDMSubmitTransfer2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2 *psRGXTDMSubmitTransfer2IN = - (PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2 *) - IMG_OFFSET_ADDR(psRGXTDMSubmitTransfer2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2 *psRGXTDMSubmitTransfer2OUT = - (PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2 *) - IMG_OFFSET_ADDR(psRGXTDMSubmitTransfer2OUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXTDMSubmitTransfer2IN->hTransferContext; - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContextInt = NULL; - SYNC_PRIMITIVE_BLOCK **psUpdateUFOSyncPrimBlockInt = NULL; - IMG_HANDLE *hUpdateUFOSyncPrimBlockInt2 = NULL; - IMG_UINT32 *ui32UpdateSyncOffsetInt = NULL; - IMG_UINT32 *ui32UpdateValueInt = NULL; - IMG_CHAR *uiUpdateFenceNameInt = NULL; - IMG_UINT8 *ui8FWCommandInt = NULL; - IMG_UINT32 *ui32SyncPMRFlagsInt = NULL; - PMR **psSyncPMRsInt = NULL; - IMG_HANDLE *hSyncPMRsInt2 = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32CommandSize * sizeof(IMG_UINT8)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *)) + - ((IMG_UINT64) psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) + 0; - - if (unlikely(psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount > PVRSRV_MAX_SYNCS)) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXTDMSubmitTransfer2_exit; - } - - if (unlikely - (psRGXTDMSubmitTransfer2IN->ui32CommandSize > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE)) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXTDMSubmitTransfer2_exit; - } - - if (unlikely(psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount > PVRSRV_MAX_SYNCS)) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXTDMSubmitTransfer2_exit; - } - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMSubmitTransfer2_exit; - } - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXTDMSubmitTransfer2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXTDMSubmitTransfer2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXTDMSubmitTransfer2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXTDMSubmitTransfer2_exit; - } - } - } - - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount != 0) - { - psUpdateUFOSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psUpdateUFOSyncPrimBlockInt, 0, - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset += - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * - sizeof(SYNC_PRIMITIVE_BLOCK *); - hUpdateUFOSyncPrimBlockInt2 = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hUpdateUFOSyncPrimBlockInt2, - (const void __user *)psRGXTDMSubmitTransfer2IN->phUpdateUFOSyncPrimBlock, - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != - PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount != 0) - { - ui32UpdateSyncOffsetInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32UpdateSyncOffsetInt, - (const void __user *)psRGXTDMSubmitTransfer2IN->pui32UpdateSyncOffset, - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount != 0) - { - ui32UpdateValueInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32UpdateValueInt, - (const void __user *)psRGXTDMSubmitTransfer2IN->pui32UpdateValue, - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != - PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - - { - uiUpdateFenceNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceNameInt, - (const void __user *)psRGXTDMSubmitTransfer2IN->puiUpdateFenceName, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - ((IMG_CHAR *) uiUpdateFenceNameInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - if (psRGXTDMSubmitTransfer2IN->ui32CommandSize != 0) - { - ui8FWCommandInt = (IMG_UINT8 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXTDMSubmitTransfer2IN->ui32CommandSize * sizeof(IMG_UINT8); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32CommandSize * sizeof(IMG_UINT8) > 0) - { - if (OSCopyFromUser - (NULL, ui8FWCommandInt, - (const void __user *)psRGXTDMSubmitTransfer2IN->pui8FWCommand, - psRGXTDMSubmitTransfer2IN->ui32CommandSize * sizeof(IMG_UINT8)) != PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - if (psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount != 0) - { - ui32SyncPMRFlagsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32SyncPMRFlagsInt, - (const void __user *)psRGXTDMSubmitTransfer2IN->pui32SyncPMRFlags, - psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - if (psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount != 0) - { - psSyncPMRsInt = (PMR **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psSyncPMRsInt, 0, - psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *)); - ui32NextOffset += psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *); - hSyncPMRsInt2 = (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hSyncPMRsInt2, - (const void __user *)psRGXTDMSubmitTransfer2IN->phSyncPMRs, - psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXTDMSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXTDMSubmitTransfer2_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXTDMSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, IMG_TRUE); - if (unlikely(psRGXTDMSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMSubmitTransfer2_exit; - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount; i++) - { - /* Look up the address from the handle */ - psRGXTDMSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psUpdateUFOSyncPrimBlockInt[i], - hUpdateUFOSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXTDMSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMSubmitTransfer2_exit; - } - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount; i++) - { - /* Look up the address from the handle */ - psRGXTDMSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncPMRsInt[i], - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXTDMSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMSubmitTransfer2_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXTDMSubmitTransfer2OUT->eError = - PVRSRVRGXTDMSubmitTransferKM(psTransferContextInt, - psRGXTDMSubmitTransfer2IN->ui32PDumpFlags, - psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount, - psUpdateUFOSyncPrimBlockInt, - ui32UpdateSyncOffsetInt, - ui32UpdateValueInt, - psRGXTDMSubmitTransfer2IN->hCheckFenceFD, - psRGXTDMSubmitTransfer2IN->hUpdateTimeline, - &psRGXTDMSubmitTransfer2OUT->hUpdateFence, - uiUpdateFenceNameInt, - psRGXTDMSubmitTransfer2IN->ui32CommandSize, - ui8FWCommandInt, - psRGXTDMSubmitTransfer2IN->ui32ExternalJobReference, - psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount, - ui32SyncPMRFlagsInt, - psSyncPMRsInt, - psRGXTDMSubmitTransfer2IN->ui32Characteristic1, - psRGXTDMSubmitTransfer2IN->ui32Characteristic2, - psRGXTDMSubmitTransfer2IN->ui64DeadlineInus); - -RGXTDMSubmitTransfer2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT); - } - - if (hUpdateUFOSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXTDMSubmitTransfer2IN->ui32ClientUpdateCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psUpdateUFOSyncPrimBlockInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hUpdateUFOSyncPrimBlockInt2[i], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - - if (hSyncPMRsInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXTDMSubmitTransfer2IN->ui32SyncPMRCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psSyncPMRsInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXTDMSubmitTransfer2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _RGXTDMGetSharedMemorypsCLIPMRMemIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXTDMReleaseSharedMemoryKM((PMR *) pvData); - return eError; -} - -static PVRSRV_ERROR _RGXTDMGetSharedMemorypsUSCPMRMemIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXTDMReleaseSharedMemoryKM((PMR *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeRGXTDMGetSharedMemory(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMGetSharedMemoryIN_UI8, - IMG_UINT8 * psRGXTDMGetSharedMemoryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY *psRGXTDMGetSharedMemoryIN = - (PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY *) - IMG_OFFSET_ADDR(psRGXTDMGetSharedMemoryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY *psRGXTDMGetSharedMemoryOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY *) - IMG_OFFSET_ADDR(psRGXTDMGetSharedMemoryOUT_UI8, 0); - - PMR *psCLIPMRMemInt = NULL; - PMR *psUSCPMRMemInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMGetSharedMemoryOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMGetSharedMemory_exit; - } - } - - PVR_UNREFERENCED_PARAMETER(psRGXTDMGetSharedMemoryIN); - - psRGXTDMGetSharedMemoryOUT->eError = - PVRSRVRGXTDMGetSharedMemoryKM(psConnection, OSGetDevNode(psConnection), - &psCLIPMRMemInt, &psUSCPMRMemInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXTDMGetSharedMemoryOUT->eError != PVRSRV_OK)) - { - goto RGXTDMGetSharedMemory_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXTDMGetSharedMemoryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXTDMGetSharedMemoryOUT-> - hCLIPMRMem, - (void *)psCLIPMRMemInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXTDMGetSharedMemorypsCLIPMRMemIntRelease); - if (unlikely(psRGXTDMGetSharedMemoryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMGetSharedMemory_exit; - } - - psRGXTDMGetSharedMemoryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXTDMGetSharedMemoryOUT-> - hUSCPMRMem, - (void *)psUSCPMRMemInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXTDMGetSharedMemorypsUSCPMRMemIntRelease); - if (unlikely(psRGXTDMGetSharedMemoryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMGetSharedMemory_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXTDMGetSharedMemory_exit: - - if (psRGXTDMGetSharedMemoryOUT->eError != PVRSRV_OK) - { - if (psCLIPMRMemInt) - { - PVRSRVRGXTDMReleaseSharedMemoryKM(psCLIPMRMemInt); - } - if (psUSCPMRMemInt) - { - PVRSRVRGXTDMReleaseSharedMemoryKM(psUSCPMRMemInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXTDMReleaseSharedMemory(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMReleaseSharedMemoryIN_UI8, - IMG_UINT8 * psRGXTDMReleaseSharedMemoryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY *psRGXTDMReleaseSharedMemoryIN = - (PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY *) - IMG_OFFSET_ADDR(psRGXTDMReleaseSharedMemoryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY *psRGXTDMReleaseSharedMemoryOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY *) - IMG_OFFSET_ADDR(psRGXTDMReleaseSharedMemoryOUT_UI8, 0); - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMReleaseSharedMemoryOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMReleaseSharedMemory_exit; - } - } - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXTDMReleaseSharedMemoryOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXTDMReleaseSharedMemoryIN->hPMRMem, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE); - if (unlikely((psRGXTDMReleaseSharedMemoryOUT->eError != PVRSRV_OK) && - (psRGXTDMReleaseSharedMemoryOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psRGXTDMReleaseSharedMemoryOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXTDMReleaseSharedMemoryOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMReleaseSharedMemory_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXTDMReleaseSharedMemory_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXTDMSetTransferContextProperty(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXTDMSetTransferContextPropertyIN_UI8, - IMG_UINT8 * psRGXTDMSetTransferContextPropertyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY *psRGXTDMSetTransferContextPropertyIN = - (PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXTDMSetTransferContextPropertyIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY *psRGXTDMSetTransferContextPropertyOUT = - (PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXTDMSetTransferContextPropertyOUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXTDMSetTransferContextPropertyIN->hTransferContext; - RGX_SERVER_TQ_TDM_CONTEXT *psTransferContextInt = NULL; - - { - PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevNode(psConnection); - - /* Check that device supports the required feature */ - if ((psDeviceNode->pfnCheckDeviceFeature) && - !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, - RGX_FEATURE_FASTRENDER_DM_BIT_MASK)) - { - psRGXTDMSetTransferContextPropertyOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; - - goto RGXTDMSetTransferContextProperty_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXTDMSetTransferContextPropertyOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT, IMG_TRUE); - if (unlikely(psRGXTDMSetTransferContextPropertyOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXTDMSetTransferContextProperty_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXTDMSetTransferContextPropertyOUT->eError = - PVRSRVRGXTDMSetTransferContextPropertyKM(psTransferContextInt, - psRGXTDMSetTransferContextPropertyIN-> - ui32Property, - psRGXTDMSetTransferContextPropertyIN-> - ui64Input, - &psRGXTDMSetTransferContextPropertyOUT-> - ui64Output); - -RGXTDMSetTransferContextProperty_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRGXTQ2Bridge(void); -void DeinitRGXTQ2Bridge(void); - -/* - * Register all RGXTQ2 functions with services - */ -PVRSRV_ERROR InitRGXTQ2Bridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT, - PVRSRVBridgeRGXTDMCreateTransferContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT, - PVRSRVBridgeRGXTDMDestroyTransferContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY, - PVRSRVBridgeRGXTDMSetTransferContextPriority, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE, - PVRSRVBridgeRGXTDMNotifyWriteOffsetUpdate, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER2, - PVRSRVBridgeRGXTDMSubmitTransfer2, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMGETSHAREDMEMORY, - PVRSRVBridgeRGXTDMGetSharedMemory, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMRELEASESHAREDMEMORY, - PVRSRVBridgeRGXTDMReleaseSharedMemory, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPROPERTY, - PVRSRVBridgeRGXTDMSetTransferContextProperty, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY), - sizeof(PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxtq2 functions with services - */ -void DeinitRGXTQ2Bridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMGETSHAREDMEMORY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMRELEASESHAREDMEMORY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, - PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPROPERTY); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_rgxtq_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_rgxtq_bridge.c deleted file mode 100644 index 6d36873855f11..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_rgxtq_bridge.c +++ /dev/null @@ -1,1230 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for rgxtq -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for rgxtq -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "rgxtransfer.h" -#include "rgx_tq_shared.h" - -#include "common_rgxtq_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -#if defined(SUPPORT_RGXTQ_BRIDGE) - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _RGXCreateTransferContextpsTransferContextIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVRGXDestroyTransferContextKM((RGX_SERVER_TQ_CONTEXT *) pvData); - return eError; -} - -static_assert(RGXFWIF_RF_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_RF_CMD_SIZE must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXCreateTransferContextIN_UI8, - IMG_UINT8 * psRGXCreateTransferContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextIN = - (PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateTransferContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextOUT = - (PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXCreateTransferContextOUT_UI8, 0); - - IMG_BYTE *ui8FrameworkCmdInt = NULL; - IMG_HANDLE hPrivData = psRGXCreateTransferContextIN->hPrivData; - IMG_HANDLE hPrivDataInt = NULL; - RGX_SERVER_TQ_CONTEXT *psTransferContextInt = NULL; - PMR *psCLIPMRMemInt = NULL; - PMR *psUSCPMRMemInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) + 0; - - if (unlikely(psRGXCreateTransferContextIN->ui32FrameworkCmdize > RGXFWIF_RF_CMD_SIZE)) - { - psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXCreateTransferContext_exit; - } - - psRGXCreateTransferContextOUT->hTransferContext = NULL; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXCreateTransferContext_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXCreateTransferContextIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXCreateTransferContextIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXCreateTransferContext_exit; - } - } - } - - if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0) - { - ui8FrameworkCmdInt = (IMG_BYTE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE); - } - - /* Copy the data over */ - if (psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0) - { - if (OSCopyFromUser - (NULL, ui8FrameworkCmdInt, - (const void __user *)psRGXCreateTransferContextIN->pui8FrameworkCmd, - psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != - PVRSRV_OK) - { - psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXCreateTransferContext_exit; - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXCreateTransferContextOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hPrivDataInt, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA, IMG_TRUE); - if (unlikely(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateTransferContext_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXCreateTransferContextOUT->eError = - PVRSRVRGXCreateTransferContextKM(psConnection, OSGetDevNode(psConnection), - psRGXCreateTransferContextIN->ui32Priority, - psRGXCreateTransferContextIN->ui32FrameworkCmdize, - ui8FrameworkCmdInt, - hPrivDataInt, - psRGXCreateTransferContextIN->ui32PackedCCBSizeU8888, - psRGXCreateTransferContextIN->ui32ContextFlags, - psRGXCreateTransferContextIN->ui64RobustnessAddress, - &psTransferContextInt, - &psCLIPMRMemInt, &psUSCPMRMemInt); - /* Exit early if bridged call fails */ - if (unlikely(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)) - { - goto RGXCreateTransferContext_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRGXCreateTransferContextOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateTransferContextOUT->hTransferContext, - (void *)psTransferContextInt, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RGXCreateTransferContextpsTransferContextIntRelease); - if (unlikely(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateTransferContext_exit; - } - - psRGXCreateTransferContextOUT->eError = - PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateTransferContextOUT->hCLIPMRMem, - (void *)psCLIPMRMemInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psRGXCreateTransferContextOUT->hTransferContext); - if (unlikely(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateTransferContext_exit; - } - - psRGXCreateTransferContextOUT->eError = - PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psRGXCreateTransferContextOUT->hUSCPMRMem, - (void *)psUSCPMRMemInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psRGXCreateTransferContextOUT->hTransferContext); - if (unlikely(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXCreateTransferContext_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXCreateTransferContext_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hPrivDataInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPrivData, PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK) - { - if (psRGXCreateTransferContextOUT->hTransferContext) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) - psRGXCreateTransferContextOUT-> - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psTransferContextInt) - { - PVRSRVRGXDestroyTransferContextKM(psTransferContextInt); - } - - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXCreateTransferContextOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXDestroyTransferContextIN_UI8, - IMG_UINT8 * psRGXDestroyTransferContextOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextIN = - (PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyTransferContextIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextOUT = - (PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT *) - IMG_OFFSET_ADDR(psRGXDestroyTransferContextOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRGXDestroyTransferContextOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRGXDestroyTransferContextIN-> - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT); - if (unlikely - ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) - && (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRGXDestroyTransferContextOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RGXDestroyTransferContext_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RGXDestroyTransferContext_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetTransferContextPriorityIN_UI8, - IMG_UINT8 * psRGXSetTransferContextPriorityOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityIN = - (PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetTransferContextPriorityIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityOUT = - (PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *) - IMG_OFFSET_ADDR(psRGXSetTransferContextPriorityOUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXSetTransferContextPriorityIN->hTransferContext; - RGX_SERVER_TQ_CONTEXT *psTransferContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetTransferContextPriorityOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetTransferContextPriorityOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetTransferContextPriority_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetTransferContextPriorityOUT->eError = - PVRSRVRGXSetTransferContextPriorityKM(psConnection, OSGetDevNode(psConnection), - psTransferContextInt, - psRGXSetTransferContextPriorityIN->ui32Priority); - -RGXSetTransferContextPriority_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); -static_assert(RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE <= IMG_UINT32_MAX, - "RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE must not be larger than IMG_UINT32_MAX"); -static_assert(PVRSRV_MAX_SYNCS <= IMG_UINT32_MAX, - "PVRSRV_MAX_SYNCS must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRGXSubmitTransfer2(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSubmitTransfer2IN_UI8, - IMG_UINT8 * psRGXSubmitTransfer2OUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2 *psRGXSubmitTransfer2IN = - (PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2 *) IMG_OFFSET_ADDR(psRGXSubmitTransfer2IN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2 *psRGXSubmitTransfer2OUT = - (PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2 *) IMG_OFFSET_ADDR(psRGXSubmitTransfer2OUT_UI8, - 0); - - IMG_HANDLE hTransferContext = psRGXSubmitTransfer2IN->hTransferContext; - RGX_SERVER_TQ_CONTEXT *psTransferContextInt = NULL; - IMG_UINT32 *ui32ClientUpdateCountInt = NULL; - SYNC_PRIMITIVE_BLOCK ***psUpdateUFOSyncPrimBlockInt = NULL; - IMG_HANDLE **hUpdateUFOSyncPrimBlockInt2 = NULL; - IMG_UINT32 **ui32UpdateSyncOffsetInt = NULL; - IMG_UINT32 **ui32UpdateValueInt = NULL; - IMG_CHAR *uiUpdateFenceNameInt = NULL; - IMG_UINT32 *ui32CommandSizeInt = NULL; - IMG_UINT8 **ui8FWCommandInt = NULL; - IMG_UINT32 *ui32TQPrepareFlagsInt = NULL; - IMG_UINT32 *ui32SyncPMRFlagsInt = NULL; - PMR **psSyncPMRsInt = NULL; - IMG_HANDLE *hSyncPMRsInt2 = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; - IMG_BYTE *pArrayArgsBuffer2 = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) + - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) + - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *)) + - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) + 0; - IMG_UINT32 ui32BufferSize2 = 0; - IMG_UINT32 ui32NextOffset2 = 0; - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - - ui64BufferSize += - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * - sizeof(SYNC_PRIMITIVE_BLOCK **)); - ui64BufferSize += - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_HANDLE **)); - ui64BufferSize += - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32 *)); - ui64BufferSize += - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32 *)); - ui64BufferSize += - ((IMG_UINT64) psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT8 *)); - } - - if (unlikely(psRGXSubmitTransfer2IN->ui32SyncPMRCount > PVRSRV_MAX_SYNCS)) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXSubmitTransfer2_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXSubmitTransfer2_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRGXSubmitTransfer2IN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRGXSubmitTransfer2IN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXSubmitTransfer2_exit; - } - } - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - ui32ClientUpdateCountInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32ClientUpdateCountInt, - (const void __user *)psRGXSubmitTransfer2IN->pui32ClientUpdateCount, - psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - /* Assigning psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer for first dimension */ - psUpdateUFOSyncPrimBlockInt = - (SYNC_PRIMITIVE_BLOCK ***) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += - psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **); - /* Assigning hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer for first dimension */ - hUpdateUFOSyncPrimBlockInt2 = - (IMG_HANDLE **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_HANDLE); - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - /* Assigning ui32UpdateSyncOffsetInt to the right offset in the pool buffer for first dimension */ - ui32UpdateSyncOffsetInt = - (IMG_UINT32 **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32 *); - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - /* Assigning ui32UpdateValueInt to the right offset in the pool buffer for first dimension */ - ui32UpdateValueInt = - (IMG_UINT32 **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32 *); - } - - { - uiUpdateFenceNameInt = - (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiUpdateFenceNameInt, - (const void __user *)psRGXSubmitTransfer2IN->puiUpdateFenceName, - PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - ((IMG_CHAR *) uiUpdateFenceNameInt)[(PVRSRV_SYNC_NAME_LENGTH * sizeof(IMG_CHAR)) - - 1] = '\0'; - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - ui32CommandSizeInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32CommandSizeInt, - (const void __user *)psRGXSubmitTransfer2IN->pui32CommandSize, - psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - /* Assigning ui8FWCommandInt to the right offset in the pool buffer for first dimension */ - ui8FWCommandInt = (IMG_UINT8 **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT8 *); - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - ui32TQPrepareFlagsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32TQPrepareFlagsInt, - (const void __user *)psRGXSubmitTransfer2IN->pui32TQPrepareFlags, - psRGXSubmitTransfer2IN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - if (psRGXSubmitTransfer2IN->ui32SyncPMRCount != 0) - { - ui32SyncPMRFlagsInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32SyncPMRFlagsInt, - (const void __user *)psRGXSubmitTransfer2IN->pui32SyncPMRFlags, - psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - if (psRGXSubmitTransfer2IN->ui32SyncPMRCount != 0) - { - psSyncPMRsInt = (PMR **) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - OSCachedMemSet(psSyncPMRsInt, 0, - psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *)); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(PMR *); - hSyncPMRsInt2 = (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE); - } - - /* Copy the data over */ - if (psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0) - { - if (OSCopyFromUser - (NULL, hSyncPMRsInt2, (const void __user *)psRGXSubmitTransfer2IN->phSyncPMRs, - psRGXSubmitTransfer2IN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - IMG_UINT32 i; - ui64BufferSize = 0; - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - ui64BufferSize += - ((IMG_UINT64) ui32ClientUpdateCountInt[i] * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui64BufferSize += - ((IMG_UINT64) ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE *)); - ui64BufferSize += - ((IMG_UINT64) ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)); - ui64BufferSize += - ((IMG_UINT64) ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)); - ui64BufferSize += ((IMG_UINT64) ui32CommandSizeInt[i] * sizeof(IMG_UINT8)); - } - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RGXSubmitTransfer2_exit; - } - ui32BufferSize2 = (IMG_UINT32) ui64BufferSize; - } - - if (ui32BufferSize2 != 0) - { - pArrayArgsBuffer2 = OSAllocMemNoStats(ui32BufferSize2); - - if (!pArrayArgsBuffer2) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RGXSubmitTransfer2_exit; - } - } - - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - IMG_UINT32 i; - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - if (ui32ClientUpdateCountInt[i] > PVRSRV_MAX_SYNCS) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXSubmitTransfer2_exit; - } - - /* Assigning each psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer (this is the second dimension) */ - psUpdateUFOSyncPrimBlockInt[i] = - (SYNC_PRIMITIVE_BLOCK **) IMG_OFFSET_ADDR(pArrayArgsBuffer2, - ui32NextOffset2); - OSCachedMemSet(psUpdateUFOSyncPrimBlockInt[i], 0, - ui32ClientUpdateCountInt[i] * - sizeof(SYNC_PRIMITIVE_BLOCK *)); - ui32NextOffset2 += - ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *); - /* Assigning each hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer (this is the second dimension) */ - hUpdateUFOSyncPrimBlockInt2[i] = - (IMG_HANDLE *) IMG_OFFSET_ADDR(pArrayArgsBuffer2, ui32NextOffset2); - ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE); - } - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - IMG_UINT32 i; - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Assigning each ui32UpdateSyncOffsetInt to the right offset in the pool buffer (this is the second dimension) */ - ui32UpdateSyncOffsetInt[i] = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer2, ui32NextOffset2); - ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32); - } - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - IMG_UINT32 i; - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Assigning each ui32UpdateValueInt to the right offset in the pool buffer (this is the second dimension) */ - ui32UpdateValueInt[i] = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer2, ui32NextOffset2); - ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32); - } - } - if (psRGXSubmitTransfer2IN->ui32PrepareCount != 0) - { - IMG_UINT32 i; - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - if (ui32CommandSizeInt[i] > RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RGXSubmitTransfer2_exit; - } - - /* Assigning each ui8FWCommandInt to the right offset in the pool buffer (this is the second dimension) */ - ui8FWCommandInt[i] = - (IMG_UINT8 *) IMG_OFFSET_ADDR(pArrayArgsBuffer2, ui32NextOffset2); - ui32NextOffset2 += ui32CommandSizeInt[i] * sizeof(IMG_UINT8); - } - } - - { - IMG_UINT32 i; - IMG_HANDLE **psPtr; - - /* Loop over all the pointers in the array copying the data into the kernel */ - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Copy the pointer over from the client side */ - if (OSCopyFromUser - (NULL, &psPtr, - (const void __user *)&psRGXSubmitTransfer2IN-> - phUpdateUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - - /* Copy the data over */ - if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)) > 0) - { - if (OSCopyFromUser - (NULL, (hUpdateUFOSyncPrimBlockInt2[i]), - (const void __user *)psPtr, - (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != - PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - } - } - - { - IMG_UINT32 i; - IMG_UINT32 **psPtr; - - /* Loop over all the pointers in the array copying the data into the kernel */ - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Copy the pointer over from the client side */ - if (OSCopyFromUser - (NULL, &psPtr, - (const void __user *)&psRGXSubmitTransfer2IN->pui32UpdateSyncOffset[i], - sizeof(IMG_UINT32 **)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - - /* Copy the data over */ - if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0) - { - if (OSCopyFromUser - (NULL, (ui32UpdateSyncOffsetInt[i]), (const void __user *)psPtr, - (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != - PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - } - } - - { - IMG_UINT32 i; - IMG_UINT32 **psPtr; - - /* Loop over all the pointers in the array copying the data into the kernel */ - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Copy the pointer over from the client side */ - if (OSCopyFromUser - (NULL, &psPtr, - (const void __user *)&psRGXSubmitTransfer2IN->pui32UpdateValue[i], - sizeof(IMG_UINT32 **)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - - /* Copy the data over */ - if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0) - { - if (OSCopyFromUser - (NULL, (ui32UpdateValueInt[i]), (const void __user *)psPtr, - (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != - PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - } - } - - { - IMG_UINT32 i; - IMG_UINT8 **psPtr; - - /* Loop over all the pointers in the array copying the data into the kernel */ - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - /* Copy the pointer over from the client side */ - if (OSCopyFromUser - (NULL, &psPtr, - (const void __user *)&psRGXSubmitTransfer2IN->pui8FWCommand[i], - sizeof(IMG_UINT8 **)) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - - /* Copy the data over */ - if ((ui32CommandSizeInt[i] * sizeof(IMG_UINT8)) > 0) - { - if (OSCopyFromUser - (NULL, (ui8FWCommandInt[i]), (const void __user *)psPtr, - (ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK) - { - psRGXSubmitTransfer2OUT->eError = - PVRSRV_ERROR_INVALID_PARAMS; - - goto RGXSubmitTransfer2_exit; - } - } - } - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSubmitTransfer2_exit; - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - IMG_UINT32 j; - for (j = 0; j < ui32ClientUpdateCountInt[i]; j++) - { - /* Look up the address from the handle */ - psRGXSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **) - &psUpdateUFOSyncPrimBlockInt[i][j], - hUpdateUFOSyncPrimBlockInt2[i][j], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - IMG_TRUE); - if (unlikely(psRGXSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSubmitTransfer2_exit; - } - } - } - } - - { - IMG_UINT32 i; - - for (i = 0; i < psRGXSubmitTransfer2IN->ui32SyncPMRCount; i++) - { - /* Look up the address from the handle */ - psRGXSubmitTransfer2OUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncPMRsInt[i], - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRGXSubmitTransfer2OUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSubmitTransfer2_exit; - } - } - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSubmitTransfer2OUT->eError = - PVRSRVRGXSubmitTransferKM(psTransferContextInt, - psRGXSubmitTransfer2IN->ui32PrepareCount, - ui32ClientUpdateCountInt, - psUpdateUFOSyncPrimBlockInt, - ui32UpdateSyncOffsetInt, - ui32UpdateValueInt, - psRGXSubmitTransfer2IN->hCheckFenceFD, - psRGXSubmitTransfer2IN->h2DUpdateTimeline, - &psRGXSubmitTransfer2OUT->h2DUpdateFence, - psRGXSubmitTransfer2IN->h3DUpdateTimeline, - &psRGXSubmitTransfer2OUT->h3DUpdateFence, - uiUpdateFenceNameInt, - ui32CommandSizeInt, - ui8FWCommandInt, - ui32TQPrepareFlagsInt, - psRGXSubmitTransfer2IN->ui32ExtJobRef, - psRGXSubmitTransfer2IN->ui32SyncPMRCount, - ui32SyncPMRFlagsInt, psSyncPMRsInt); - -RGXSubmitTransfer2_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT); - } - - if (hUpdateUFOSyncPrimBlockInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXSubmitTransfer2IN->ui32PrepareCount; i++) - { - IMG_UINT32 j; - for (j = 0; j < ui32ClientUpdateCountInt[i]; j++) - { - - /* Unreference the previously looked up handle */ - if (psUpdateUFOSyncPrimBlockInt[i][j]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hUpdateUFOSyncPrimBlockInt2[i] - [j], - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - } - } - } - - if (hSyncPMRsInt2) - { - IMG_UINT32 i; - - for (i = 0; i < psRGXSubmitTransfer2IN->ui32SyncPMRCount; i++) - { - - /* Unreference the previously looked up handle */ - if (psSyncPMRsInt[i]) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncPMRsInt2[i], - PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - } - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXSubmitTransfer2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRGXSubmitTransfer2OUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize2 == ui32NextOffset2); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - - if (pArrayArgsBuffer2) - OSFreeMemNoStats(pArrayArgsBuffer2); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRGXSetTransferContextProperty(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRGXSetTransferContextPropertyIN_UI8, - IMG_UINT8 * psRGXSetTransferContextPropertyOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY *psRGXSetTransferContextPropertyIN = - (PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetTransferContextPropertyIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY *psRGXSetTransferContextPropertyOUT = - (PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY *) - IMG_OFFSET_ADDR(psRGXSetTransferContextPropertyOUT_UI8, 0); - - IMG_HANDLE hTransferContext = psRGXSetTransferContextPropertyIN->hTransferContext; - RGX_SERVER_TQ_CONTEXT *psTransferContextInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRGXSetTransferContextPropertyOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psTransferContextInt, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT, IMG_TRUE); - if (unlikely(psRGXSetTransferContextPropertyOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RGXSetTransferContextProperty_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRGXSetTransferContextPropertyOUT->eError = - PVRSRVRGXSetTransferContextPropertyKM(psTransferContextInt, - psRGXSetTransferContextPropertyIN->ui32Property, - psRGXSetTransferContextPropertyIN->ui64Input, - &psRGXSetTransferContextPropertyOUT->ui64Output); - -RGXSetTransferContextProperty_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psTransferContextInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hTransferContext, - PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -#endif /* SUPPORT_RGXTQ_BRIDGE */ - -#if defined(SUPPORT_RGXTQ_BRIDGE) -PVRSRV_ERROR InitRGXTQBridge(void); -void DeinitRGXTQBridge(void); - -/* - * Register all RGXTQ functions with services - */ -PVRSRV_ERROR InitRGXTQBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT, - PVRSRVBridgeRGXCreateTransferContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT, - PVRSRVBridgeRGXDestroyTransferContext, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT), - sizeof(PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, - PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY, - PVRSRVBridgeRGXSetTransferContextPriority, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2, - PVRSRVBridgeRGXSubmitTransfer2, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2), - sizeof(PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, - PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPROPERTY, - PVRSRVBridgeRGXSetTransferContextProperty, NULL, - sizeof(PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY), - sizeof(PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY)); - - return PVRSRV_OK; -} - -/* - * Unregister all rgxtq functions with services - */ -void DeinitRGXTQBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, - PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, - PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPROPERTY); - -} -#else /* SUPPORT_RGXTQ_BRIDGE */ -/* This bridge is conditional on SUPPORT_RGXTQ_BRIDGE - when not defined, - * do not populate the dispatch table with its functions - */ -#define InitRGXTQBridge() \ - PVRSRV_OK - -#define DeinitRGXTQBridge() - -#endif /* SUPPORT_RGXTQ_BRIDGE */ diff --git a/drivers/gpu/drm/img-rogue/1.17/server_ri_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_ri_bridge.c deleted file mode 100644 index 52112c32a46c4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_ri_bridge.c +++ /dev/null @@ -1,776 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for ri -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for ri -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "ri_server.h" - -#include "common_ri_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeRIWritePMREntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIWritePMREntryIN_UI8, - IMG_UINT8 * psRIWritePMREntryOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY *psRIWritePMREntryIN = - (PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY *) IMG_OFFSET_ADDR(psRIWritePMREntryIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY *psRIWritePMREntryOUT = - (PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY *) IMG_OFFSET_ADDR(psRIWritePMREntryOUT_UI8, 0); - - IMG_HANDLE hPMRHandle = psRIWritePMREntryIN->hPMRHandle; - PMR *psPMRHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRIWritePMREntryOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRHandleInt, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRIWritePMREntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIWritePMREntry_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRIWritePMREntryOUT->eError = RIWritePMREntryKM(psPMRHandleInt); - -RIWritePMREntry_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static PVRSRV_ERROR _RIWriteMEMDESCEntrypsRIHandleIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RIDeleteMEMDESCEntryKM((RI_HANDLE) pvData); - return eError; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRIWriteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIWriteMEMDESCEntryIN_UI8, - IMG_UINT8 * psRIWriteMEMDESCEntryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryIN = - (PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY *) IMG_OFFSET_ADDR(psRIWriteMEMDESCEntryIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryOUT = - (PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY *) IMG_OFFSET_ADDR(psRIWriteMEMDESCEntryOUT_UI8, - 0); - - IMG_HANDLE hPMRHandle = psRIWriteMEMDESCEntryIN->hPMRHandle; - PMR *psPMRHandleInt = NULL; - IMG_CHAR *uiTextBInt = NULL; - RI_HANDLE psRIHandleInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psRIWriteMEMDESCEntryIN->ui32TextBSize > DEVMEM_ANNOTATION_MAX_LEN)) - { - psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RIWriteMEMDESCEntry_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RIWriteMEMDESCEntry_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRIWriteMEMDESCEntryIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRIWriteMEMDESCEntryIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RIWriteMEMDESCEntry_exit; - } - } - } - - if (psRIWriteMEMDESCEntryIN->ui32TextBSize != 0) - { - uiTextBInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextBInt, (const void __user *)psRIWriteMEMDESCEntryIN->puiTextB, - psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RIWriteMEMDESCEntry_exit; - } - ((IMG_CHAR *) - uiTextBInt)[(psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRIWriteMEMDESCEntryOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRHandleInt, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIWriteMEMDESCEntry_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRIWriteMEMDESCEntryOUT->eError = - RIWriteMEMDESCEntryKM(psPMRHandleInt, - psRIWriteMEMDESCEntryIN->ui32TextBSize, - uiTextBInt, - psRIWriteMEMDESCEntryIN->ui64Offset, - psRIWriteMEMDESCEntryIN->ui64Size, - psRIWriteMEMDESCEntryIN->bIsImport, - psRIWriteMEMDESCEntryIN->bIsSuballoc, &psRIHandleInt); - /* Exit early if bridged call fails */ - if (unlikely(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)) - { - goto RIWriteMEMDESCEntry_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRIWriteMEMDESCEntryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRIWriteMEMDESCEntryOUT-> - hRIHandle, - (void *)psRIHandleInt, - PVRSRV_HANDLE_TYPE_RI_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RIWriteMEMDESCEntrypsRIHandleIntRelease); - if (unlikely(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIWriteMEMDESCEntry_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RIWriteMEMDESCEntry_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) - { - if (psRIHandleInt) - { - RIDeleteMEMDESCEntryKM(psRIHandleInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRIWriteMEMDESCEntryOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _RIWriteProcListEntrypsRIHandleIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = RIDeleteMEMDESCEntryKM((RI_HANDLE) pvData); - return eError; -} - -static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX, - "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeRIWriteProcListEntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIWriteProcListEntryIN_UI8, - IMG_UINT8 * psRIWriteProcListEntryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY *psRIWriteProcListEntryIN = - (PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY *) IMG_OFFSET_ADDR(psRIWriteProcListEntryIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY *psRIWriteProcListEntryOUT = - (PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY *) - IMG_OFFSET_ADDR(psRIWriteProcListEntryOUT_UI8, 0); - - IMG_CHAR *uiTextBInt = NULL; - RI_HANDLE psRIHandleInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psRIWriteProcListEntryIN->ui32TextBSize > DEVMEM_ANNOTATION_MAX_LEN)) - { - psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto RIWriteProcListEntry_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto RIWriteProcListEntry_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psRIWriteProcListEntryIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psRIWriteProcListEntryIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto RIWriteProcListEntry_exit; - } - } - } - - if (psRIWriteProcListEntryIN->ui32TextBSize != 0) - { - uiTextBInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiTextBInt, (const void __user *)psRIWriteProcListEntryIN->puiTextB, - psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto RIWriteProcListEntry_exit; - } - ((IMG_CHAR *) - uiTextBInt)[(psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psRIWriteProcListEntryOUT->eError = - RIWriteProcListEntryKM(psRIWriteProcListEntryIN->ui32TextBSize, - uiTextBInt, - psRIWriteProcListEntryIN->ui64Size, - psRIWriteProcListEntryIN->ui64DevVAddr, &psRIHandleInt); - /* Exit early if bridged call fails */ - if (unlikely(psRIWriteProcListEntryOUT->eError != PVRSRV_OK)) - { - goto RIWriteProcListEntry_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psRIWriteProcListEntryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psRIWriteProcListEntryOUT-> - hRIHandle, - (void *)psRIHandleInt, - PVRSRV_HANDLE_TYPE_RI_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _RIWriteProcListEntrypsRIHandleIntRelease); - if (unlikely(psRIWriteProcListEntryOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIWriteProcListEntry_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -RIWriteProcListEntry_exit: - - if (psRIWriteProcListEntryOUT->eError != PVRSRV_OK) - { - if (psRIHandleInt) - { - RIDeleteMEMDESCEntryKM(psRIHandleInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psRIWriteProcListEntryOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIUpdateMEMDESCAddr(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIUpdateMEMDESCAddrIN_UI8, - IMG_UINT8 * psRIUpdateMEMDESCAddrOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrIN = - (PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR *) IMG_OFFSET_ADDR(psRIUpdateMEMDESCAddrIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrOUT = - (PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR *) IMG_OFFSET_ADDR(psRIUpdateMEMDESCAddrOUT_UI8, - 0); - - IMG_HANDLE hRIHandle = psRIUpdateMEMDESCAddrIN->hRIHandle; - RI_HANDLE psRIHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRIUpdateMEMDESCAddrOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psRIHandleInt, - hRIHandle, PVRSRV_HANDLE_TYPE_RI_HANDLE, IMG_TRUE); - if (unlikely(psRIUpdateMEMDESCAddrOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIUpdateMEMDESCAddr_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRIUpdateMEMDESCAddrOUT->eError = - RIUpdateMEMDESCAddrKM(psRIHandleInt, psRIUpdateMEMDESCAddrIN->sAddr); - -RIUpdateMEMDESCAddr_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psRIHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hRIHandle, PVRSRV_HANDLE_TYPE_RI_HANDLE); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIDeleteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIDeleteMEMDESCEntryIN_UI8, - IMG_UINT8 * psRIDeleteMEMDESCEntryOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY *psRIDeleteMEMDESCEntryIN = - (PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY *) IMG_OFFSET_ADDR(psRIDeleteMEMDESCEntryIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY *psRIDeleteMEMDESCEntryOUT = - (PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY *) - IMG_OFFSET_ADDR(psRIDeleteMEMDESCEntryOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psRIDeleteMEMDESCEntryOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psRIDeleteMEMDESCEntryIN->hRIHandle, - PVRSRV_HANDLE_TYPE_RI_HANDLE); - if (unlikely((psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_OK) && - (psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psRIDeleteMEMDESCEntryOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto RIDeleteMEMDESCEntry_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -RIDeleteMEMDESCEntry_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIDumpList(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIDumpListIN_UI8, - IMG_UINT8 * psRIDumpListOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIDUMPLIST *psRIDumpListIN = - (PVRSRV_BRIDGE_IN_RIDUMPLIST *) IMG_OFFSET_ADDR(psRIDumpListIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RIDUMPLIST *psRIDumpListOUT = - (PVRSRV_BRIDGE_OUT_RIDUMPLIST *) IMG_OFFSET_ADDR(psRIDumpListOUT_UI8, 0); - - IMG_HANDLE hPMRHandle = psRIDumpListIN->hPMRHandle; - PMR *psPMRHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRIDumpListOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRHandleInt, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRIDumpListOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIDumpList_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRIDumpListOUT->eError = RIDumpListKM(psPMRHandleInt); - -RIDumpList_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIDumpAll(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIDumpAllIN_UI8, - IMG_UINT8 * psRIDumpAllOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIDUMPALL *psRIDumpAllIN = - (PVRSRV_BRIDGE_IN_RIDUMPALL *) IMG_OFFSET_ADDR(psRIDumpAllIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RIDUMPALL *psRIDumpAllOUT = - (PVRSRV_BRIDGE_OUT_RIDUMPALL *) IMG_OFFSET_ADDR(psRIDumpAllOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psRIDumpAllIN); - - psRIDumpAllOUT->eError = RIDumpAllKM(); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIDumpProcess(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIDumpProcessIN_UI8, - IMG_UINT8 * psRIDumpProcessOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIDUMPPROCESS *psRIDumpProcessIN = - (PVRSRV_BRIDGE_IN_RIDUMPPROCESS *) IMG_OFFSET_ADDR(psRIDumpProcessIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RIDUMPPROCESS *psRIDumpProcessOUT = - (PVRSRV_BRIDGE_OUT_RIDUMPPROCESS *) IMG_OFFSET_ADDR(psRIDumpProcessOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - psRIDumpProcessOUT->eError = RIDumpProcessKM(psRIDumpProcessIN->ui32Pid); - - return 0; -} - -static IMG_INT -PVRSRVBridgeRIWritePMREntryWithOwner(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psRIWritePMREntryWithOwnerIN_UI8, - IMG_UINT8 * psRIWritePMREntryWithOwnerOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER *psRIWritePMREntryWithOwnerIN = - (PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER *) - IMG_OFFSET_ADDR(psRIWritePMREntryWithOwnerIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER *psRIWritePMREntryWithOwnerOUT = - (PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER *) - IMG_OFFSET_ADDR(psRIWritePMREntryWithOwnerOUT_UI8, 0); - - IMG_HANDLE hPMRHandle = psRIWritePMREntryWithOwnerIN->hPMRHandle; - PMR *psPMRHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psRIWritePMREntryWithOwnerOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psPMRHandleInt, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE); - if (unlikely(psRIWritePMREntryWithOwnerOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto RIWritePMREntryWithOwner_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psRIWritePMREntryWithOwnerOUT->eError = - RIWritePMREntryWithOwnerKM(psPMRHandleInt, psRIWritePMREntryWithOwnerIN->ui32Owner); - -RIWritePMREntryWithOwner_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psPMRHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitRIBridge(void); -void DeinitRIBridge(void); - -/* - * Register all RI functions with services - */ -PVRSRV_ERROR InitRIBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY, - PVRSRVBridgeRIWritePMREntry, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY), - sizeof(PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY, - PVRSRVBridgeRIWriteMEMDESCEntry, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY), - sizeof(PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPROCLISTENTRY, - PVRSRVBridgeRIWriteProcListEntry, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY), - sizeof(PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR, - PVRSRVBridgeRIUpdateMEMDESCAddr, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR), - sizeof(PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY, - PVRSRVBridgeRIDeleteMEMDESCEntry, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY), - sizeof(PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPLIST, PVRSRVBridgeRIDumpList, - NULL, - sizeof(PVRSRV_BRIDGE_IN_RIDUMPLIST), - sizeof(PVRSRV_BRIDGE_OUT_RIDUMPLIST)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPALL, PVRSRVBridgeRIDumpAll, - NULL, 0, sizeof(PVRSRV_BRIDGE_OUT_RIDUMPALL)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPPROCESS, - PVRSRVBridgeRIDumpProcess, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIDUMPPROCESS), - sizeof(PVRSRV_BRIDGE_OUT_RIDUMPPROCESS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRYWITHOWNER, - PVRSRVBridgeRIWritePMREntryWithOwner, NULL, - sizeof(PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER), - sizeof(PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER)); - - return PVRSRV_OK; -} - -/* - * Unregister all ri functions with services - */ -void DeinitRIBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPROCLISTENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPLIST); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPALL); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPPROCESS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRYWITHOWNER); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_srvcore_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_srvcore_bridge.c deleted file mode 100644 index a930f2aec9410..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_srvcore_bridge.c +++ /dev/null @@ -1,1104 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for srvcore -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for srvcore -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "srvcore.h" -#include "info_page.h" -#include "proc_stats.h" -#include "rgx_fwif_alignchecks.h" - -#include "common_srvcore_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeConnect(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psConnectIN_UI8, - IMG_UINT8 * psConnectOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_CONNECT *psConnectIN = - (PVRSRV_BRIDGE_IN_CONNECT *) IMG_OFFSET_ADDR(psConnectIN_UI8, 0); - PVRSRV_BRIDGE_OUT_CONNECT *psConnectOUT = - (PVRSRV_BRIDGE_OUT_CONNECT *) IMG_OFFSET_ADDR(psConnectOUT_UI8, 0); - - psConnectOUT->eError = - PVRSRVConnectKM(psConnection, OSGetDevNode(psConnection), - psConnectIN->ui32Flags, - psConnectIN->ui32ClientBuildOptions, - psConnectIN->ui32ClientDDKVersion, - psConnectIN->ui32ClientDDKBuild, - &psConnectOUT->ui8KernelArch, - &psConnectOUT->ui32CapabilityFlags, &psConnectOUT->ui64PackedBvnc); - - return 0; -} - -static IMG_INT -PVRSRVBridgeDisconnect(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDisconnectIN_UI8, - IMG_UINT8 * psDisconnectOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DISCONNECT *psDisconnectIN = - (PVRSRV_BRIDGE_IN_DISCONNECT *) IMG_OFFSET_ADDR(psDisconnectIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DISCONNECT *psDisconnectOUT = - (PVRSRV_BRIDGE_OUT_DISCONNECT *) IMG_OFFSET_ADDR(psDisconnectOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - PVR_UNREFERENCED_PARAMETER(psDisconnectIN); - - psDisconnectOUT->eError = PVRSRVDisconnectKM(); - - return 0; -} - -static PVRSRV_ERROR _AcquireGlobalEventObjecthGlobalEventObjectIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVReleaseGlobalEventObjectKM((IMG_HANDLE) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeAcquireGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psAcquireGlobalEventObjectIN_UI8, - IMG_UINT8 * psAcquireGlobalEventObjectOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectIN = - (PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT *) - IMG_OFFSET_ADDR(psAcquireGlobalEventObjectIN_UI8, 0); - PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectOUT = - (PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT *) - IMG_OFFSET_ADDR(psAcquireGlobalEventObjectOUT_UI8, 0); - - IMG_HANDLE hGlobalEventObjectInt = NULL; - - PVR_UNREFERENCED_PARAMETER(psAcquireGlobalEventObjectIN); - - psAcquireGlobalEventObjectOUT->eError = - PVRSRVAcquireGlobalEventObjectKM(&hGlobalEventObjectInt); - /* Exit early if bridged call fails */ - if (unlikely(psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)) - { - goto AcquireGlobalEventObject_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psAcquireGlobalEventObjectOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psAcquireGlobalEventObjectOUT->hGlobalEventObject, - (void *)hGlobalEventObjectInt, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _AcquireGlobalEventObjecthGlobalEventObjectIntRelease); - if (unlikely(psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto AcquireGlobalEventObject_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -AcquireGlobalEventObject_exit: - - if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK) - { - if (hGlobalEventObjectInt) - { - PVRSRVReleaseGlobalEventObjectKM(hGlobalEventObjectInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeReleaseGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psReleaseGlobalEventObjectIN_UI8, - IMG_UINT8 * psReleaseGlobalEventObjectOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT *psReleaseGlobalEventObjectIN = - (PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT *) - IMG_OFFSET_ADDR(psReleaseGlobalEventObjectIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT *psReleaseGlobalEventObjectOUT = - (PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT *) - IMG_OFFSET_ADDR(psReleaseGlobalEventObjectOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psReleaseGlobalEventObjectOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psReleaseGlobalEventObjectIN-> - hGlobalEventObject, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); - if (unlikely - ((psReleaseGlobalEventObjectOUT->eError != PVRSRV_OK) - && (psReleaseGlobalEventObjectOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) - && (psReleaseGlobalEventObjectOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psReleaseGlobalEventObjectOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto ReleaseGlobalEventObject_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -ReleaseGlobalEventObject_exit: - - return 0; -} - -static PVRSRV_ERROR _EventObjectOpenhOSEventIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = OSEventObjectClose((IMG_HANDLE) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeEventObjectOpen(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psEventObjectOpenIN_UI8, - IMG_UINT8 * psEventObjectOpenOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN *psEventObjectOpenIN = - (PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN *) IMG_OFFSET_ADDR(psEventObjectOpenIN_UI8, 0); - PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN *psEventObjectOpenOUT = - (PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN *) IMG_OFFSET_ADDR(psEventObjectOpenOUT_UI8, 0); - - IMG_HANDLE hEventObject = psEventObjectOpenIN->hEventObject; - IMG_HANDLE hEventObjectInt = NULL; - IMG_HANDLE hOSEventInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psEventObjectOpenOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hEventObjectInt, - hEventObject, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, IMG_TRUE); - if (unlikely(psEventObjectOpenOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto EventObjectOpen_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psEventObjectOpenOUT->eError = OSEventObjectOpen(hEventObjectInt, &hOSEventInt); - /* Exit early if bridged call fails */ - if (unlikely(psEventObjectOpenOUT->eError != PVRSRV_OK)) - { - goto EventObjectOpen_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psEventObjectOpenOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psEventObjectOpenOUT->hOSEvent, - (void *)hOSEventInt, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _EventObjectOpenhOSEventIntRelease); - if (unlikely(psEventObjectOpenOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto EventObjectOpen_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -EventObjectOpen_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hEventObjectInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hEventObject, PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psEventObjectOpenOUT->eError != PVRSRV_OK) - { - if (hOSEventInt) - { - OSEventObjectClose(hOSEventInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeEventObjectWait(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psEventObjectWaitIN_UI8, - IMG_UINT8 * psEventObjectWaitOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT *psEventObjectWaitIN = - (PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT *) IMG_OFFSET_ADDR(psEventObjectWaitIN_UI8, 0); - PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT *psEventObjectWaitOUT = - (PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT *) IMG_OFFSET_ADDR(psEventObjectWaitOUT_UI8, 0); - - IMG_HANDLE hOSEventKM = psEventObjectWaitIN->hOSEventKM; - IMG_HANDLE hOSEventKMInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psEventObjectWaitOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hOSEventKMInt, - hOSEventKM, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, IMG_TRUE); - if (unlikely(psEventObjectWaitOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto EventObjectWait_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psEventObjectWaitOUT->eError = OSEventObjectWait(hOSEventKMInt); - -EventObjectWait_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hOSEventKMInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hOSEventKM, PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static IMG_INT -PVRSRVBridgeEventObjectClose(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psEventObjectCloseIN_UI8, - IMG_UINT8 * psEventObjectCloseOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE *psEventObjectCloseIN = - (PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE *) IMG_OFFSET_ADDR(psEventObjectCloseIN_UI8, 0); - PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE *psEventObjectCloseOUT = - (PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE *) IMG_OFFSET_ADDR(psEventObjectCloseOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psEventObjectCloseOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psEventObjectCloseIN->hOSEventKM, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - if (unlikely((psEventObjectCloseOUT->eError != PVRSRV_OK) && - (psEventObjectCloseOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psEventObjectCloseOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psEventObjectCloseOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto EventObjectClose_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -EventObjectClose_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeDumpDebugInfo(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psDumpDebugInfoIN_UI8, - IMG_UINT8 * psDumpDebugInfoOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_DUMPDEBUGINFO *psDumpDebugInfoIN = - (PVRSRV_BRIDGE_IN_DUMPDEBUGINFO *) IMG_OFFSET_ADDR(psDumpDebugInfoIN_UI8, 0); - PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO *psDumpDebugInfoOUT = - (PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO *) IMG_OFFSET_ADDR(psDumpDebugInfoOUT_UI8, 0); - - psDumpDebugInfoOUT->eError = - PVRSRVDumpDebugInfoKM(psConnection, OSGetDevNode(psConnection), - psDumpDebugInfoIN->ui32VerbLevel); - - return 0; -} - -static IMG_INT -PVRSRVBridgeGetDevClockSpeed(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetDevClockSpeedIN_UI8, - IMG_UINT8 * psGetDevClockSpeedOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED *psGetDevClockSpeedIN = - (PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED *) IMG_OFFSET_ADDR(psGetDevClockSpeedIN_UI8, 0); - PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED *psGetDevClockSpeedOUT = - (PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED *) IMG_OFFSET_ADDR(psGetDevClockSpeedOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psGetDevClockSpeedIN); - - psGetDevClockSpeedOUT->eError = - PVRSRVGetDevClockSpeedKM(psConnection, OSGetDevNode(psConnection), - &psGetDevClockSpeedOUT->ui32ClockSpeed); - - return 0; -} - -static IMG_INT -PVRSRVBridgeHWOpTimeout(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psHWOpTimeoutIN_UI8, - IMG_UINT8 * psHWOpTimeoutOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_HWOPTIMEOUT *psHWOpTimeoutIN = - (PVRSRV_BRIDGE_IN_HWOPTIMEOUT *) IMG_OFFSET_ADDR(psHWOpTimeoutIN_UI8, 0); - PVRSRV_BRIDGE_OUT_HWOPTIMEOUT *psHWOpTimeoutOUT = - (PVRSRV_BRIDGE_OUT_HWOPTIMEOUT *) IMG_OFFSET_ADDR(psHWOpTimeoutOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psHWOpTimeoutIN); - - psHWOpTimeoutOUT->eError = PVRSRVHWOpTimeoutKM(psConnection, OSGetDevNode(psConnection)); - - return 0; -} - -static_assert(RGXFW_ALIGN_CHECKS_UM_MAX <= IMG_UINT32_MAX, - "RGXFW_ALIGN_CHECKS_UM_MAX must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeAlignmentCheck(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psAlignmentCheckIN_UI8, - IMG_UINT8 * psAlignmentCheckOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_ALIGNMENTCHECK *psAlignmentCheckIN = - (PVRSRV_BRIDGE_IN_ALIGNMENTCHECK *) IMG_OFFSET_ADDR(psAlignmentCheckIN_UI8, 0); - PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK *psAlignmentCheckOUT = - (PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK *) IMG_OFFSET_ADDR(psAlignmentCheckOUT_UI8, 0); - - IMG_UINT32 *ui32AlignChecksInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32)) + 0; - - if (unlikely(psAlignmentCheckIN->ui32AlignChecksSize > RGXFW_ALIGN_CHECKS_UM_MAX)) - { - psAlignmentCheckOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto AlignmentCheck_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psAlignmentCheckOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto AlignmentCheck_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psAlignmentCheckIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psAlignmentCheckIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psAlignmentCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto AlignmentCheck_exit; - } - } - } - - if (psAlignmentCheckIN->ui32AlignChecksSize != 0) - { - ui32AlignChecksInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32); - } - - /* Copy the data over */ - if (psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32) > 0) - { - if (OSCopyFromUser - (NULL, ui32AlignChecksInt, - (const void __user *)psAlignmentCheckIN->pui32AlignChecks, - psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32)) != PVRSRV_OK) - { - psAlignmentCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto AlignmentCheck_exit; - } - } - - psAlignmentCheckOUT->eError = - PVRSRVAlignmentCheckKM(psConnection, OSGetDevNode(psConnection), - psAlignmentCheckIN->ui32AlignChecksSize, ui32AlignChecksInt); - -AlignmentCheck_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psAlignmentCheckOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeGetDeviceStatus(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetDeviceStatusIN_UI8, - IMG_UINT8 * psGetDeviceStatusOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETDEVICESTATUS *psGetDeviceStatusIN = - (PVRSRV_BRIDGE_IN_GETDEVICESTATUS *) IMG_OFFSET_ADDR(psGetDeviceStatusIN_UI8, 0); - PVRSRV_BRIDGE_OUT_GETDEVICESTATUS *psGetDeviceStatusOUT = - (PVRSRV_BRIDGE_OUT_GETDEVICESTATUS *) IMG_OFFSET_ADDR(psGetDeviceStatusOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psGetDeviceStatusIN); - - psGetDeviceStatusOUT->eError = - PVRSRVGetDeviceStatusKM(psConnection, OSGetDevNode(psConnection), - &psGetDeviceStatusOUT->ui32DeviceSatus); - - return 0; -} - -static_assert(8 <= IMG_UINT32_MAX, "8 must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeGetMultiCoreInfo(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psGetMultiCoreInfoIN_UI8, - IMG_UINT8 * psGetMultiCoreInfoOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_GETMULTICOREINFO *psGetMultiCoreInfoIN = - (PVRSRV_BRIDGE_IN_GETMULTICOREINFO *) IMG_OFFSET_ADDR(psGetMultiCoreInfoIN_UI8, 0); - PVRSRV_BRIDGE_OUT_GETMULTICOREINFO *psGetMultiCoreInfoOUT = - (PVRSRV_BRIDGE_OUT_GETMULTICOREINFO *) IMG_OFFSET_ADDR(psGetMultiCoreInfoOUT_UI8, 0); - - IMG_UINT64 *pui64CapsInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psGetMultiCoreInfoIN->ui32CapsSize * sizeof(IMG_UINT64)) + 0; - - if (psGetMultiCoreInfoIN->ui32CapsSize > 8) - { - psGetMultiCoreInfoOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto GetMultiCoreInfo_exit; - } - - psGetMultiCoreInfoOUT->pui64Caps = psGetMultiCoreInfoIN->pui64Caps; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psGetMultiCoreInfoOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto GetMultiCoreInfo_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psGetMultiCoreInfoIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psGetMultiCoreInfoIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psGetMultiCoreInfoOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto GetMultiCoreInfo_exit; - } - } - } - - if (psGetMultiCoreInfoIN->ui32CapsSize != 0) - { - pui64CapsInt = (IMG_UINT64 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psGetMultiCoreInfoIN->ui32CapsSize * sizeof(IMG_UINT64); - } - - psGetMultiCoreInfoOUT->eError = - PVRSRVGetMultiCoreInfoKM(psConnection, OSGetDevNode(psConnection), - psGetMultiCoreInfoIN->ui32CapsSize, - &psGetMultiCoreInfoOUT->ui32NumCores, pui64CapsInt); - /* Exit early if bridged call fails */ - if (unlikely(psGetMultiCoreInfoOUT->eError != PVRSRV_OK)) - { - goto GetMultiCoreInfo_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((pui64CapsInt) && ((psGetMultiCoreInfoIN->ui32CapsSize * sizeof(IMG_UINT64)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psGetMultiCoreInfoOUT->pui64Caps, pui64CapsInt, - (psGetMultiCoreInfoIN->ui32CapsSize * sizeof(IMG_UINT64))) != PVRSRV_OK)) - { - psGetMultiCoreInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto GetMultiCoreInfo_exit; - } - } - -GetMultiCoreInfo_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psGetMultiCoreInfoOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeEventObjectWaitTimeout(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psEventObjectWaitTimeoutIN_UI8, - IMG_UINT8 * psEventObjectWaitTimeoutOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT *psEventObjectWaitTimeoutIN = - (PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT *) - IMG_OFFSET_ADDR(psEventObjectWaitTimeoutIN_UI8, 0); - PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT *psEventObjectWaitTimeoutOUT = - (PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT *) - IMG_OFFSET_ADDR(psEventObjectWaitTimeoutOUT_UI8, 0); - - IMG_HANDLE hOSEventKM = psEventObjectWaitTimeoutIN->hOSEventKM; - IMG_HANDLE hOSEventKMInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psEventObjectWaitTimeoutOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&hOSEventKMInt, - hOSEventKM, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, IMG_TRUE); - if (unlikely(psEventObjectWaitTimeoutOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto EventObjectWaitTimeout_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psEventObjectWaitTimeoutOUT->eError = - OSEventObjectWaitTimeout(hOSEventKMInt, psEventObjectWaitTimeoutIN->ui64uiTimeoutus); - -EventObjectWaitTimeout_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (hOSEventKMInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hOSEventKM, PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -static_assert(PVRSRV_PROCESS_STAT_TYPE_COUNT <= IMG_UINT32_MAX, - "PVRSRV_PROCESS_STAT_TYPE_COUNT must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeFindProcessMemStats(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psFindProcessMemStatsIN_UI8, - IMG_UINT8 * psFindProcessMemStatsOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS *psFindProcessMemStatsIN = - (PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS *) IMG_OFFSET_ADDR(psFindProcessMemStatsIN_UI8, - 0); - PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS *psFindProcessMemStatsOUT = - (PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS *) IMG_OFFSET_ADDR(psFindProcessMemStatsOUT_UI8, - 0); - - IMG_UINT32 *pui32MemStatsArrayInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psFindProcessMemStatsIN->ui32ArrSize * sizeof(IMG_UINT32)) + 0; - - if (psFindProcessMemStatsIN->ui32ArrSize > PVRSRV_PROCESS_STAT_TYPE_COUNT) - { - psFindProcessMemStatsOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto FindProcessMemStats_exit; - } - - PVR_UNREFERENCED_PARAMETER(psConnection); - - psFindProcessMemStatsOUT->pui32MemStatsArray = psFindProcessMemStatsIN->pui32MemStatsArray; - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psFindProcessMemStatsOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto FindProcessMemStats_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psFindProcessMemStatsIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psFindProcessMemStatsIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psFindProcessMemStatsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto FindProcessMemStats_exit; - } - } - } - - if (psFindProcessMemStatsIN->ui32ArrSize != 0) - { - pui32MemStatsArrayInt = - (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psFindProcessMemStatsIN->ui32ArrSize * sizeof(IMG_UINT32); - } - - psFindProcessMemStatsOUT->eError = - PVRSRVFindProcessMemStatsKM(psFindProcessMemStatsIN->ui32PID, - psFindProcessMemStatsIN->ui32ArrSize, - psFindProcessMemStatsIN->bbAllProcessStats, - pui32MemStatsArrayInt); - /* Exit early if bridged call fails */ - if (unlikely(psFindProcessMemStatsOUT->eError != PVRSRV_OK)) - { - goto FindProcessMemStats_exit; - } - - /* If dest ptr is non-null and we have data to copy */ - if ((pui32MemStatsArrayInt) && - ((psFindProcessMemStatsIN->ui32ArrSize * sizeof(IMG_UINT32)) > 0)) - { - if (unlikely - (OSCopyToUser - (NULL, (void __user *)psFindProcessMemStatsOUT->pui32MemStatsArray, - pui32MemStatsArrayInt, - (psFindProcessMemStatsIN->ui32ArrSize * sizeof(IMG_UINT32))) != PVRSRV_OK)) - { - psFindProcessMemStatsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto FindProcessMemStats_exit; - } - } - -FindProcessMemStats_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psFindProcessMemStatsOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static PVRSRV_ERROR _AcquireInfoPagepsPMRIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVReleaseInfoPageKM((PMR *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeAcquireInfoPage(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psAcquireInfoPageIN_UI8, - IMG_UINT8 * psAcquireInfoPageOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE *psAcquireInfoPageIN = - (PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE *) IMG_OFFSET_ADDR(psAcquireInfoPageIN_UI8, 0); - PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE *psAcquireInfoPageOUT = - (PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE *) IMG_OFFSET_ADDR(psAcquireInfoPageOUT_UI8, 0); - - PMR *psPMRInt = NULL; - - PVR_UNREFERENCED_PARAMETER(psAcquireInfoPageIN); - - psAcquireInfoPageOUT->eError = PVRSRVAcquireInfoPageKM(&psPMRInt); - /* Exit early if bridged call fails */ - if (unlikely(psAcquireInfoPageOUT->eError != PVRSRV_OK)) - { - goto AcquireInfoPage_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psAcquireInfoPageOUT->eError = - PVRSRVAllocHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase, - &psAcquireInfoPageOUT->hPMR, (void *)psPMRInt, - PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & _AcquireInfoPagepsPMRIntRelease); - if (unlikely(psAcquireInfoPageOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto AcquireInfoPage_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - -AcquireInfoPage_exit: - - if (psAcquireInfoPageOUT->eError != PVRSRV_OK) - { - if (psPMRInt) - { - PVRSRVReleaseInfoPageKM(psPMRInt); - } - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeReleaseInfoPage(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psReleaseInfoPageIN_UI8, - IMG_UINT8 * psReleaseInfoPageOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_RELEASEINFOPAGE *psReleaseInfoPageIN = - (PVRSRV_BRIDGE_IN_RELEASEINFOPAGE *) IMG_OFFSET_ADDR(psReleaseInfoPageIN_UI8, 0); - PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE *psReleaseInfoPageOUT = - (PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE *) IMG_OFFSET_ADDR(psReleaseInfoPageOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psProcessHandleBase->psHandleBase); - - psReleaseInfoPageOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psProcessHandleBase->psHandleBase, - (IMG_HANDLE) psReleaseInfoPageIN->hPMR, - PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT); - if (unlikely((psReleaseInfoPageOUT->eError != PVRSRV_OK) && - (psReleaseInfoPageOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psReleaseInfoPageOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(psReleaseInfoPageOUT->eError))); - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - goto ReleaseInfoPage_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psProcessHandleBase->psHandleBase); - -ReleaseInfoPage_exit: - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitSRVCOREBridge(void); -void DeinitSRVCOREBridge(void); - -/* - * Register all SRVCORE functions with services - */ -PVRSRV_ERROR InitSRVCOREBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_CONNECT, - PVRSRVBridgeConnect, NULL, sizeof(PVRSRV_BRIDGE_IN_CONNECT), - sizeof(PVRSRV_BRIDGE_OUT_CONNECT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DISCONNECT, - PVRSRVBridgeDisconnect, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_DISCONNECT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT, - PVRSRVBridgeAcquireGlobalEventObject, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT, - PVRSRVBridgeReleaseGlobalEventObject, NULL, - sizeof(PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT), - sizeof(PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN, - PVRSRVBridgeEventObjectOpen, NULL, - sizeof(PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN), - sizeof(PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT, - PVRSRVBridgeEventObjectWait, NULL, - sizeof(PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT), - sizeof(PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE, - PVRSRVBridgeEventObjectClose, NULL, - sizeof(PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE), - sizeof(PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO, - PVRSRVBridgeDumpDebugInfo, NULL, - sizeof(PVRSRV_BRIDGE_IN_DUMPDEBUGINFO), - sizeof(PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED, - PVRSRVBridgeGetDevClockSpeed, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT, - PVRSRVBridgeHWOpTimeout, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_HWOPTIMEOUT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK, - PVRSRVBridgeAlignmentCheck, NULL, - sizeof(PVRSRV_BRIDGE_IN_ALIGNMENTCHECK), - sizeof(PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS, - PVRSRVBridgeGetDeviceStatus, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_GETDEVICESTATUS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETMULTICOREINFO, - PVRSRVBridgeGetMultiCoreInfo, NULL, - sizeof(PVRSRV_BRIDGE_IN_GETMULTICOREINFO), - sizeof(PVRSRV_BRIDGE_OUT_GETMULTICOREINFO)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT, - PVRSRVBridgeEventObjectWaitTimeout, NULL, - sizeof(PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT), - sizeof(PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_FINDPROCESSMEMSTATS, - PVRSRVBridgeFindProcessMemStats, NULL, - sizeof(PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS), - sizeof(PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ACQUIREINFOPAGE, - PVRSRVBridgeAcquireInfoPage, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RELEASEINFOPAGE, - PVRSRVBridgeReleaseInfoPage, NULL, - sizeof(PVRSRV_BRIDGE_IN_RELEASEINFOPAGE), - sizeof(PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE)); - - return PVRSRV_OK; -} - -/* - * Unregister all srvcore functions with services - */ -void DeinitSRVCOREBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_CONNECT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DISCONNECT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, - PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, - PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETMULTICOREINFO); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, - PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_FINDPROCESSMEMSTATS); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ACQUIREINFOPAGE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RELEASEINFOPAGE); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_sync_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_sync_bridge.c deleted file mode 100644 index a6ffcc21c9b46..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_sync_bridge.c +++ /dev/null @@ -1,763 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for sync -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for sync -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "sync.h" -#include "sync_server.h" -#include "pdump.h" -#include "pvrsrv_sync_km.h" -#include "sync_fallback_server.h" -#include "sync_checkpoint.h" - -#include "common_sync_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static PVRSRV_ERROR _AllocSyncPrimitiveBlockpsSyncHandleIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVFreeSyncPrimitiveBlockKM((SYNC_PRIMITIVE_BLOCK *) pvData); - return eError; -} - -static IMG_INT -PVRSRVBridgeAllocSyncPrimitiveBlock(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psAllocSyncPrimitiveBlockIN_UI8, - IMG_UINT8 * psAllocSyncPrimitiveBlockOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockIN = - (PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK *) - IMG_OFFSET_ADDR(psAllocSyncPrimitiveBlockIN_UI8, 0); - PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockOUT = - (PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK *) - IMG_OFFSET_ADDR(psAllocSyncPrimitiveBlockOUT_UI8, 0); - - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - PMR *pshSyncPMRInt = NULL; - - PVR_UNREFERENCED_PARAMETER(psAllocSyncPrimitiveBlockIN); - - psAllocSyncPrimitiveBlockOUT->hSyncHandle = NULL; - - psAllocSyncPrimitiveBlockOUT->eError = - PVRSRVAllocSyncPrimitiveBlockKM(psConnection, OSGetDevNode(psConnection), - &psSyncHandleInt, - &psAllocSyncPrimitiveBlockOUT->ui32SyncPrimVAddr, - &psAllocSyncPrimitiveBlockOUT->ui32SyncPrimBlockSize, - &pshSyncPMRInt); - /* Exit early if bridged call fails */ - if (unlikely(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)) - { - goto AllocSyncPrimitiveBlock_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psAllocSyncPrimitiveBlockOUT-> - hSyncHandle, - (void *)psSyncHandleInt, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - (PFN_HANDLE_RELEASE) & - _AllocSyncPrimitiveBlockpsSyncHandleIntRelease); - if (unlikely(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto AllocSyncPrimitiveBlock_exit; - } - - psAllocSyncPrimitiveBlockOUT->eError = - PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase, - &psAllocSyncPrimitiveBlockOUT->hhSyncPMR, - (void *)pshSyncPMRInt, - PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - psAllocSyncPrimitiveBlockOUT->hSyncHandle); - if (unlikely(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto AllocSyncPrimitiveBlock_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -AllocSyncPrimitiveBlock_exit: - - if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK) - { - if (psAllocSyncPrimitiveBlockOUT->hSyncHandle) - { - PVRSRV_ERROR eError; - - /* Lock over handle creation cleanup. */ - LockHandle(psConnection->psHandleBase); - - eError = PVRSRVDestroyHandleUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) - psAllocSyncPrimitiveBlockOUT-> - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - if (unlikely((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", __func__, PVRSRVGetErrorString(eError))); - } - /* Releasing the handle should free/destroy/release the resource. - * This should never fail... */ - PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); - - /* Release now we have cleaned up creation handles. */ - UnlockHandle(psConnection->psHandleBase); - - } - - else if (psSyncHandleInt) - { - PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt); - } - - } - - return 0; -} - -static IMG_INT -PVRSRVBridgeFreeSyncPrimitiveBlock(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psFreeSyncPrimitiveBlockIN_UI8, - IMG_UINT8 * psFreeSyncPrimitiveBlockOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK *psFreeSyncPrimitiveBlockIN = - (PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK *) - IMG_OFFSET_ADDR(psFreeSyncPrimitiveBlockIN_UI8, 0); - PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK *psFreeSyncPrimitiveBlockOUT = - (PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK *) - IMG_OFFSET_ADDR(psFreeSyncPrimitiveBlockOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psFreeSyncPrimitiveBlockOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psFreeSyncPrimitiveBlockIN->hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - if (unlikely((psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_OK) && - (psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psFreeSyncPrimitiveBlockOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto FreeSyncPrimitiveBlock_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -FreeSyncPrimitiveBlock_exit: - - return 0; -} - -static IMG_INT -PVRSRVBridgeSyncPrimSet(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncPrimSetIN_UI8, - IMG_UINT8 * psSyncPrimSetOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCPRIMSET *psSyncPrimSetIN = - (PVRSRV_BRIDGE_IN_SYNCPRIMSET *) IMG_OFFSET_ADDR(psSyncPrimSetIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCPRIMSET *psSyncPrimSetOUT = - (PVRSRV_BRIDGE_OUT_SYNCPRIMSET *) IMG_OFFSET_ADDR(psSyncPrimSetOUT_UI8, 0); - - IMG_HANDLE hSyncHandle = psSyncPrimSetIN->hSyncHandle; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncPrimSetOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncHandleInt, - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncPrimSetOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncPrimSet_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncPrimSetOUT->eError = - PVRSRVSyncPrimSetKM(psSyncHandleInt, - psSyncPrimSetIN->ui32Index, psSyncPrimSetIN->ui32Value); - -SyncPrimSet_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSyncHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#if defined(PDUMP) - -static IMG_INT -PVRSRVBridgeSyncPrimPDump(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncPrimPDumpIN_UI8, - IMG_UINT8 * psSyncPrimPDumpOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP *psSyncPrimPDumpIN = - (PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP *) IMG_OFFSET_ADDR(psSyncPrimPDumpIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP *psSyncPrimPDumpOUT = - (PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP *) IMG_OFFSET_ADDR(psSyncPrimPDumpOUT_UI8, 0); - - IMG_HANDLE hSyncHandle = psSyncPrimPDumpIN->hSyncHandle; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncPrimPDumpOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncHandleInt, - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncPrimPDumpOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncPrimPDump_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncPrimPDumpOUT->eError = - PVRSRVSyncPrimPDumpKM(psSyncHandleInt, psSyncPrimPDumpIN->ui32Offset); - -SyncPrimPDump_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSyncHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeSyncPrimPDump NULL -#endif - -#if defined(PDUMP) - -static IMG_INT -PVRSRVBridgeSyncPrimPDumpValue(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncPrimPDumpValueIN_UI8, - IMG_UINT8 * psSyncPrimPDumpValueOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueIN = - (PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE *) IMG_OFFSET_ADDR(psSyncPrimPDumpValueIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueOUT = - (PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE *) IMG_OFFSET_ADDR(psSyncPrimPDumpValueOUT_UI8, - 0); - - IMG_HANDLE hSyncHandle = psSyncPrimPDumpValueIN->hSyncHandle; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncPrimPDumpValueOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncHandleInt, - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncPrimPDumpValueOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncPrimPDumpValue_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncPrimPDumpValueOUT->eError = - PVRSRVSyncPrimPDumpValueKM(psSyncHandleInt, - psSyncPrimPDumpValueIN->ui32Offset, - psSyncPrimPDumpValueIN->ui32Value); - -SyncPrimPDumpValue_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSyncHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeSyncPrimPDumpValue NULL -#endif - -#if defined(PDUMP) - -static IMG_INT -PVRSRVBridgeSyncPrimPDumpPol(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncPrimPDumpPolIN_UI8, - IMG_UINT8 * psSyncPrimPDumpPolOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolIN = - (PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL *) IMG_OFFSET_ADDR(psSyncPrimPDumpPolIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolOUT = - (PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL *) IMG_OFFSET_ADDR(psSyncPrimPDumpPolOUT_UI8, 0); - - IMG_HANDLE hSyncHandle = psSyncPrimPDumpPolIN->hSyncHandle; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncPrimPDumpPolOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncHandleInt, - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncPrimPDumpPolOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncPrimPDumpPol_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncPrimPDumpPolOUT->eError = - PVRSRVSyncPrimPDumpPolKM(psSyncHandleInt, - psSyncPrimPDumpPolIN->ui32Offset, - psSyncPrimPDumpPolIN->ui32Value, - psSyncPrimPDumpPolIN->ui32Mask, - psSyncPrimPDumpPolIN->eOperator, - psSyncPrimPDumpPolIN->uiPDumpFlags); - -SyncPrimPDumpPol_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSyncHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeSyncPrimPDumpPol NULL -#endif - -#if defined(PDUMP) - -static IMG_INT -PVRSRVBridgeSyncPrimPDumpCBP(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncPrimPDumpCBPIN_UI8, - IMG_UINT8 * psSyncPrimPDumpCBPOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPIN = - (PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP *) IMG_OFFSET_ADDR(psSyncPrimPDumpCBPIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPOUT = - (PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP *) IMG_OFFSET_ADDR(psSyncPrimPDumpCBPOUT_UI8, 0); - - IMG_HANDLE hSyncHandle = psSyncPrimPDumpCBPIN->hSyncHandle; - SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL; - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncPrimPDumpCBPOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&psSyncHandleInt, - hSyncHandle, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncPrimPDumpCBPOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncPrimPDumpCBP_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncPrimPDumpCBPOUT->eError = - PVRSRVSyncPrimPDumpCBPKM(psSyncHandleInt, - psSyncPrimPDumpCBPIN->ui32Offset, - psSyncPrimPDumpCBPIN->uiWriteOffset, - psSyncPrimPDumpCBPIN->uiPacketSize, - psSyncPrimPDumpCBPIN->uiBufferSize); - -SyncPrimPDumpCBP_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (psSyncHandleInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - return 0; -} - -#else -#define PVRSRVBridgeSyncPrimPDumpCBP NULL -#endif - -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeSyncAllocEvent(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncAllocEventIN_UI8, - IMG_UINT8 * psSyncAllocEventOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCALLOCEVENT *psSyncAllocEventIN = - (PVRSRV_BRIDGE_IN_SYNCALLOCEVENT *) IMG_OFFSET_ADDR(psSyncAllocEventIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT *psSyncAllocEventOUT = - (PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT *) IMG_OFFSET_ADDR(psSyncAllocEventOUT_UI8, 0); - - IMG_CHAR *uiClassNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psSyncAllocEventIN->ui32ClassNameSize > PVRSRV_SYNC_NAME_LENGTH)) - { - psSyncAllocEventOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto SyncAllocEvent_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psSyncAllocEventOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto SyncAllocEvent_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psSyncAllocEventIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psSyncAllocEventIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psSyncAllocEventOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto SyncAllocEvent_exit; - } - } - } - - if (psSyncAllocEventIN->ui32ClassNameSize != 0) - { - uiClassNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiClassNameInt, (const void __user *)psSyncAllocEventIN->puiClassName, - psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psSyncAllocEventOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto SyncAllocEvent_exit; - } - ((IMG_CHAR *) - uiClassNameInt)[(psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - psSyncAllocEventOUT->eError = - PVRSRVSyncAllocEventKM(psConnection, OSGetDevNode(psConnection), - psSyncAllocEventIN->bServerSync, - psSyncAllocEventIN->ui32FWAddr, - psSyncAllocEventIN->ui32ClassNameSize, uiClassNameInt); - -SyncAllocEvent_exit: - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psSyncAllocEventOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -static IMG_INT -PVRSRVBridgeSyncFreeEvent(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncFreeEventIN_UI8, - IMG_UINT8 * psSyncFreeEventOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCFREEEVENT *psSyncFreeEventIN = - (PVRSRV_BRIDGE_IN_SYNCFREEEVENT *) IMG_OFFSET_ADDR(psSyncFreeEventIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCFREEEVENT *psSyncFreeEventOUT = - (PVRSRV_BRIDGE_OUT_SYNCFREEEVENT *) IMG_OFFSET_ADDR(psSyncFreeEventOUT_UI8, 0); - - psSyncFreeEventOUT->eError = - PVRSRVSyncFreeEventKM(psConnection, OSGetDevNode(psConnection), - psSyncFreeEventIN->ui32FWAddr); - - return 0; -} - -#if defined(PDUMP) - -static IMG_INT -PVRSRVBridgeSyncCheckpointSignalledPDumpPol(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncCheckpointSignalledPDumpPolIN_UI8, - IMG_UINT8 * psSyncCheckpointSignalledPDumpPolOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL *psSyncCheckpointSignalledPDumpPolIN = - (PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL *) - IMG_OFFSET_ADDR(psSyncCheckpointSignalledPDumpPolIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL *psSyncCheckpointSignalledPDumpPolOUT = - (PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL *) - IMG_OFFSET_ADDR(psSyncCheckpointSignalledPDumpPolOUT_UI8, 0); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - psSyncCheckpointSignalledPDumpPolOUT->eError = - PVRSRVSyncCheckpointSignalledPDumpPolKM(psSyncCheckpointSignalledPDumpPolIN->hFence); - - return 0; -} - -#else -#define PVRSRVBridgeSyncCheckpointSignalledPDumpPol NULL -#endif - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitSYNCBridge(void); -void DeinitSYNCBridge(void); - -/* - * Register all SYNC functions with services - */ -PVRSRV_ERROR InitSYNCBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK, - PVRSRVBridgeAllocSyncPrimitiveBlock, NULL, 0, - sizeof(PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK, - PVRSRVBridgeFreeSyncPrimitiveBlock, NULL, - sizeof(PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK), - sizeof(PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMSET, - PVRSRVBridgeSyncPrimSet, NULL, sizeof(PVRSRV_BRIDGE_IN_SYNCPRIMSET), - sizeof(PVRSRV_BRIDGE_OUT_SYNCPRIMSET)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP, - PVRSRVBridgeSyncPrimPDump, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP), - sizeof(PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE, - PVRSRVBridgeSyncPrimPDumpValue, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE), - sizeof(PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL, - PVRSRVBridgeSyncPrimPDumpPol, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL), - sizeof(PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP, - PVRSRVBridgeSyncPrimPDumpCBP, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP), - sizeof(PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT, - PVRSRVBridgeSyncAllocEvent, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCALLOCEVENT), - sizeof(PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT, - PVRSRVBridgeSyncFreeEvent, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCFREEEVENT), - sizeof(PVRSRV_BRIDGE_OUT_SYNCFREEEVENT)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, - PVRSRV_BRIDGE_SYNC_SYNCCHECKPOINTSIGNALLEDPDUMPPOL, - PVRSRVBridgeSyncCheckpointSignalledPDumpPol, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL), - sizeof(PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL)); - - return PVRSRV_OK; -} - -/* - * Unregister all sync functions with services - */ -void DeinitSYNCBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMSET); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, - PVRSRV_BRIDGE_SYNC_SYNCCHECKPOINTSIGNALLEDPDUMPPOL); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/server_synctracking_bridge.c b/drivers/gpu/drm/img-rogue/1.17/server_synctracking_bridge.c deleted file mode 100644 index 835e98d9c409f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/server_synctracking_bridge.c +++ /dev/null @@ -1,337 +0,0 @@ -/******************************************************************************* -@File -@Title Server bridge for synctracking -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side of the bridge for synctracking -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -#include "sync.h" -#include "sync_server.h" - -#include "common_synctracking_bridge.h" - -#include "allocmem.h" -#include "pvr_debug.h" -#include "connection_server.h" -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif -#include "srvcore.h" -#include "handle.h" - -#include - -/* *************************************************************************** - * Server-side bridge entry points - */ - -static IMG_INT -PVRSRVBridgeSyncRecordRemoveByHandle(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncRecordRemoveByHandleIN_UI8, - IMG_UINT8 * psSyncRecordRemoveByHandleOUT_UI8, - CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleIN = - (PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE *) - IMG_OFFSET_ADDR(psSyncRecordRemoveByHandleIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleOUT = - (PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE *) - IMG_OFFSET_ADDR(psSyncRecordRemoveByHandleOUT_UI8, 0); - - /* Lock over handle destruction. */ - LockHandle(psConnection->psHandleBase); - - psSyncRecordRemoveByHandleOUT->eError = - PVRSRVDestroyHandleStagedUnlocked(psConnection->psHandleBase, - (IMG_HANDLE) psSyncRecordRemoveByHandleIN->hhRecord, - PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE); - if (unlikely((psSyncRecordRemoveByHandleOUT->eError != PVRSRV_OK) && - (psSyncRecordRemoveByHandleOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) && - (psSyncRecordRemoveByHandleOUT->eError != PVRSRV_ERROR_RETRY))) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s", - __func__, PVRSRVGetErrorString(psSyncRecordRemoveByHandleOUT->eError))); - UnlockHandle(psConnection->psHandleBase); - goto SyncRecordRemoveByHandle_exit; - } - - /* Release now we have destroyed handles. */ - UnlockHandle(psConnection->psHandleBase); - -SyncRecordRemoveByHandle_exit: - - return 0; -} - -static PVRSRV_ERROR _SyncRecordAddpshRecordIntRelease(void *pvData) -{ - PVRSRV_ERROR eError; - eError = PVRSRVSyncRecordRemoveByHandleKM((SYNC_RECORD_HANDLE) pvData); - return eError; -} - -static_assert(PVRSRV_SYNC_NAME_LENGTH <= IMG_UINT32_MAX, - "PVRSRV_SYNC_NAME_LENGTH must not be larger than IMG_UINT32_MAX"); - -static IMG_INT -PVRSRVBridgeSyncRecordAdd(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 * psSyncRecordAddIN_UI8, - IMG_UINT8 * psSyncRecordAddOUT_UI8, CONNECTION_DATA * psConnection) -{ - PVRSRV_BRIDGE_IN_SYNCRECORDADD *psSyncRecordAddIN = - (PVRSRV_BRIDGE_IN_SYNCRECORDADD *) IMG_OFFSET_ADDR(psSyncRecordAddIN_UI8, 0); - PVRSRV_BRIDGE_OUT_SYNCRECORDADD *psSyncRecordAddOUT = - (PVRSRV_BRIDGE_OUT_SYNCRECORDADD *) IMG_OFFSET_ADDR(psSyncRecordAddOUT_UI8, 0); - - SYNC_RECORD_HANDLE pshRecordInt = NULL; - IMG_HANDLE hhServerSyncPrimBlock = psSyncRecordAddIN->hhServerSyncPrimBlock; - SYNC_PRIMITIVE_BLOCK *pshServerSyncPrimBlockInt = NULL; - IMG_CHAR *uiClassNameInt = NULL; - - IMG_UINT32 ui32NextOffset = 0; - IMG_BYTE *pArrayArgsBuffer = NULL; -#if !defined(INTEGRITY_OS) - IMG_BOOL bHaveEnoughSpace = IMG_FALSE; -#endif - - IMG_UINT32 ui32BufferSize = 0; - IMG_UINT64 ui64BufferSize = - ((IMG_UINT64) psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) + 0; - - if (unlikely(psSyncRecordAddIN->ui32ClassNameSize > PVRSRV_SYNC_NAME_LENGTH)) - { - psSyncRecordAddOUT->eError = PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG; - goto SyncRecordAdd_exit; - } - - if (ui64BufferSize > IMG_UINT32_MAX) - { - psSyncRecordAddOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL; - goto SyncRecordAdd_exit; - } - - ui32BufferSize = (IMG_UINT32) ui64BufferSize; - - if (ui32BufferSize != 0) - { -#if !defined(INTEGRITY_OS) - /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */ - IMG_UINT32 ui32InBufferOffset = - PVR_ALIGN(sizeof(*psSyncRecordAddIN), sizeof(unsigned long)); - IMG_UINT32 ui32InBufferExcessSize = - ui32InBufferOffset >= - PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset; - - bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize; - if (bHaveEnoughSpace) - { - IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psSyncRecordAddIN; - - pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset]; - } - else -#endif - { - pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize); - - if (!pArrayArgsBuffer) - { - psSyncRecordAddOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto SyncRecordAdd_exit; - } - } - } - - if (psSyncRecordAddIN->ui32ClassNameSize != 0) - { - uiClassNameInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset); - ui32NextOffset += psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR); - } - - /* Copy the data over */ - if (psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR) > 0) - { - if (OSCopyFromUser - (NULL, uiClassNameInt, (const void __user *)psSyncRecordAddIN->puiClassName, - psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) - { - psSyncRecordAddOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - - goto SyncRecordAdd_exit; - } - ((IMG_CHAR *) - uiClassNameInt)[(psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) - 1] = - '\0'; - } - - /* Lock over handle lookup. */ - LockHandle(psConnection->psHandleBase); - - /* Look up the address from the handle */ - psSyncRecordAddOUT->eError = - PVRSRVLookupHandleUnlocked(psConnection->psHandleBase, - (void **)&pshServerSyncPrimBlockInt, - hhServerSyncPrimBlock, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK, IMG_TRUE); - if (unlikely(psSyncRecordAddOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncRecordAdd_exit; - } - /* Release now we have looked up handles. */ - UnlockHandle(psConnection->psHandleBase); - - psSyncRecordAddOUT->eError = - PVRSRVSyncRecordAddKM(psConnection, OSGetDevNode(psConnection), - &pshRecordInt, - pshServerSyncPrimBlockInt, - psSyncRecordAddIN->ui32ui32FwBlockAddr, - psSyncRecordAddIN->ui32ui32SyncOffset, - psSyncRecordAddIN->bbServerSync, - psSyncRecordAddIN->ui32ClassNameSize, uiClassNameInt); - /* Exit early if bridged call fails */ - if (unlikely(psSyncRecordAddOUT->eError != PVRSRV_OK)) - { - goto SyncRecordAdd_exit; - } - - /* Lock over handle creation. */ - LockHandle(psConnection->psHandleBase); - - psSyncRecordAddOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase, - &psSyncRecordAddOUT->hhRecord, - (void *)pshRecordInt, - PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - (PFN_HANDLE_RELEASE) & - _SyncRecordAddpshRecordIntRelease); - if (unlikely(psSyncRecordAddOUT->eError != PVRSRV_OK)) - { - UnlockHandle(psConnection->psHandleBase); - goto SyncRecordAdd_exit; - } - - /* Release now we have created handles. */ - UnlockHandle(psConnection->psHandleBase); - -SyncRecordAdd_exit: - - /* Lock over handle lookup cleanup. */ - LockHandle(psConnection->psHandleBase); - - /* Unreference the previously looked up handle */ - if (pshServerSyncPrimBlockInt) - { - PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase, - hhServerSyncPrimBlock, - PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); - } - /* Release now we have cleaned up look up handles. */ - UnlockHandle(psConnection->psHandleBase); - - if (psSyncRecordAddOUT->eError != PVRSRV_OK) - { - if (pshRecordInt) - { - PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt); - } - } - - /* Allocated space should be equal to the last updated offset */ -#ifdef PVRSRV_NEED_PVR_ASSERT - if (psSyncRecordAddOUT->eError == PVRSRV_OK) - PVR_ASSERT(ui32BufferSize == ui32NextOffset); -#endif /* PVRSRV_NEED_PVR_ASSERT */ - -#if defined(INTEGRITY_OS) - if (pArrayArgsBuffer) -#else - if (!bHaveEnoughSpace && pArrayArgsBuffer) -#endif - OSFreeMemNoStats(pArrayArgsBuffer); - - return 0; -} - -/* *************************************************************************** - * Server bridge dispatch related glue - */ - -PVRSRV_ERROR InitSYNCTRACKINGBridge(void); -void DeinitSYNCTRACKINGBridge(void); - -/* - * Register all SYNCTRACKING functions with services - */ -PVRSRV_ERROR InitSYNCTRACKINGBridge(void) -{ - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, - PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE, - PVRSRVBridgeSyncRecordRemoveByHandle, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE), - sizeof(PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE)); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD, - PVRSRVBridgeSyncRecordAdd, NULL, - sizeof(PVRSRV_BRIDGE_IN_SYNCRECORDADD), - sizeof(PVRSRV_BRIDGE_OUT_SYNCRECORDADD)); - - return PVRSRV_OK; -} - -/* - * Unregister all synctracking functions with services - */ -void DeinitSYNCTRACKINGBridge(void) -{ - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, - PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE); - - UnsetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, - PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD); - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/services_kernel_client.h b/drivers/gpu/drm/img-rogue/1.17/services_kernel_client.h deleted file mode 100644 index aaca47f1e6d69..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/services_kernel_client.h +++ /dev/null @@ -1,291 +0,0 @@ -/*************************************************************************/ /*! -@File services_kernel_client.h -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* This file contains a partial redefinition of the PowerVR Services 5 - * interface for use by components which are checkpatch clean. This - * header is included by the unrefined, non-checkpatch clean headers - * to ensure that prototype/typedef/macro changes break the build. - */ - -#ifndef __SERVICES_KERNEL_CLIENT__ -#define __SERVICES_KERNEL_CLIENT__ - -#include "pvrsrv_error.h" - -#include - -#include "pvrsrv_sync_km.h" -#include "sync_checkpoint_external.h" - -/* included for the define PVRSRV_LINUX_DEV_INIT_ON_PROBE */ -#include "pvr_drm.h" - -#ifndef __pvrsrv_defined_struct_enum__ - -/* sync_external.h */ - -struct PVRSRV_CLIENT_SYNC_PRIM_TAG { - volatile __u32 *pui32LinAddr; -}; - -struct PVRSRV_CLIENT_SYNC_PRIM_OP { - __u32 ui32Flags; - struct pvrsrv_sync_prim *psSync; - __u32 ui32FenceValue; - __u32 ui32UpdateValue; -}; - -#else /* __pvrsrv_defined_struct_enum__ */ - -struct PVRSRV_CLIENT_SYNC_PRIM_TAG; -struct PVRSRV_CLIENT_SYNC_PRIM_OP; - -enum tag_img_bool; - -#endif /* __pvrsrv_defined_struct_enum__ */ - -struct _PMR_; -struct _PVRSRV_DEVICE_NODE_; -struct dma_buf; -struct SYNC_PRIM_CONTEXT_TAG; - -/* pvr_notifier.h */ - -#ifndef CMDCOMPNOTIFY_PFN -typedef void (*PFN_CMDCOMP_NOTIFY)(void *hCmdCompHandle); -#define CMDCOMPNOTIFY_PFN -#endif -enum PVRSRV_ERROR_TAG PVRSRVRegisterCmdCompleteNotify(void **phNotify, - PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, void *hPrivData); -enum PVRSRV_ERROR_TAG PVRSRVUnregisterCmdCompleteNotify(void *hNotify); -void PVRSRVCheckStatus(void *hCmdCompCallerHandle); - -#define DEBUG_REQUEST_DC 0 -#define DEBUG_REQUEST_SYNCTRACKING 1 -#define DEBUG_REQUEST_SRV 2 -#define DEBUG_REQUEST_SYS 3 -#define DEBUG_REQUEST_RGX 4 -#define DEBUG_REQUEST_ANDROIDSYNC 5 -#define DEBUG_REQUEST_LINUXFENCE 6 -#define DEBUG_REQUEST_SYNCCHECKPOINT 7 -#define DEBUG_REQUEST_HTB 8 -#define DEBUG_REQUEST_APPHINT 9 -#define DEBUG_REQUEST_FALLBACKSYNC 10 - -#define DEBUG_REQUEST_VERBOSITY_LOW 0 -#define DEBUG_REQUEST_VERBOSITY_MEDIUM 1 -#define DEBUG_REQUEST_VERBOSITY_HIGH 2 -#define DEBUG_REQUEST_VERBOSITY_MAX DEBUG_REQUEST_VERBOSITY_HIGH - -#define DD_VERB_LVL_ENABLED(_verbLvl, _verbLvlChk) ((_verbLvl) >= (_verbLvlChk)) - -#ifndef DBGNOTIFY_PFNS -typedef void (DUMPDEBUG_PRINTF_FUNC)(void *pvDumpDebugFile, - const char *fmt, ...) __printf(2, 3); -typedef void (*PFN_DBGREQ_NOTIFY) (void *hDebugRequestHandle, - __u32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); -#define DBGNOTIFY_PFNS -#endif -enum PVRSRV_ERROR_TAG PVRSRVRegisterDeviceDbgRequestNotify(void **phNotify, - struct _PVRSRV_DEVICE_NODE_ *psDevNode, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - __u32 ui32RequesterID, - void *hDbgRequestHandle); -enum PVRSRV_ERROR_TAG PVRSRVUnregisterDeviceDbgRequestNotify(void *hNotify); -enum PVRSRV_ERROR_TAG PVRSRVRegisterDriverDbgRequestNotify(void **phNotify, - PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, - __u32 ui32RequesterID, - void *hDbgRequestHandle); -enum PVRSRV_ERROR_TAG PVRSRVUnregisterDriverDbgRequestNotify(void *hNotify); - -/* physmem_dmabuf.h */ - -struct dma_buf *PhysmemGetDmaBuf(struct _PMR_ *psPMR); - -/* pvrsrv.h */ - -enum PVRSRV_ERROR_TAG PVRSRVAcquireGlobalEventObjectKM(void **phGlobalEventObject); -enum PVRSRV_ERROR_TAG PVRSRVReleaseGlobalEventObjectKM(void *hGlobalEventObject); - -/* sync.h */ - -enum PVRSRV_ERROR_TAG SyncPrimContextCreate( - struct _PVRSRV_DEVICE_NODE_ *psDevConnection, - struct SYNC_PRIM_CONTEXT_TAG **phSyncPrimContext); -void SyncPrimContextDestroy(struct SYNC_PRIM_CONTEXT_TAG *hSyncPrimContext); - -enum PVRSRV_ERROR_TAG SyncPrimAlloc(struct SYNC_PRIM_CONTEXT_TAG *hSyncPrimContext, - struct PVRSRV_CLIENT_SYNC_PRIM_TAG **ppsSync, const char *pszClassName); -enum PVRSRV_ERROR_TAG SyncPrimFree(struct PVRSRV_CLIENT_SYNC_PRIM_TAG *psSync); -enum PVRSRV_ERROR_TAG SyncPrimGetFirmwareAddr( - struct PVRSRV_CLIENT_SYNC_PRIM_TAG *psSync, - __u32 *sync_addr); - -/* osfunc.h */ -enum PVRSRV_ERROR_TAG OSEventObjectWait(void *hOSEventKM); -enum PVRSRV_ERROR_TAG OSEventObjectOpen(void *hEventObject, void **phOSEventKM); -enum PVRSRV_ERROR_TAG OSEventObjectClose(void *hOSEventKM); -__u32 OSGetCurrentClientProcessIDKM(void); -__u32 OSStringUINT32ToStr(char *pszBuf, size_t uSize, __u32 ui32Num); - -/* srvkm.h */ - -enum PVRSRV_ERROR_TAG PVRSRVCommonDeviceCreate(void *pvOSDevice, - int i32OsDeviceID, - struct _PVRSRV_DEVICE_NODE_ **ppsDeviceNode); -enum PVRSRV_ERROR_TAG PVRSRVCommonDeviceDestroy( - struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -const char *PVRSRVGetErrorString(enum PVRSRV_ERROR_TAG eError); -#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_PROBE) -enum PVRSRV_ERROR_TAG PVRSRVCommonDeviceInitialise( - struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -#endif - -#ifndef CHECKPOINT_PFNS -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_RESOLVE_FN)(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, PVRSRV_FENCE fence, u32 *nr_checkpoints, PSYNC_CHECKPOINT **checkpoint_handles, u64 *fence_uid); - -#ifndef CHECKPOINT_PFNS -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_CREATE_FN)( - struct _PVRSRV_DEVICE_NODE_ *device, - const char *fence_name, - PVRSRV_TIMELINE timeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *new_fence, - u64 *fence_uid, - void **fence_finalise_data, - PSYNC_CHECKPOINT *new_checkpoint_handle, - void **timeline_update_sync, - __u32 *timeline_update_value); -#endif - -#ifndef CHECKPOINT_PFNS -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_ROLLBACK_DATA_FN)(PVRSRV_FENCE fence_to_rollback, void *finalise_data); -#endif - -#ifndef CHECKPOINT_PFNS -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_FINALISE_FN)(PVRSRV_FENCE fence_to_finalise, void *finalise_data); -#endif - -#ifndef CHECKPOINT_PFNS -typedef __u32 (*PFN_SYNC_CHECKPOINT_DUMP_INFO_ON_STALLED_UFOS_FN)(__u32 num_ufos, __u32 *vaddrs); -#endif - -#ifndef CHECKPOINT_PFNS -typedef enum tag_img_bool (*PFN_SYNC_CHECKPOINT_UFO_HAS_SIGNALLED_FN)( - __u32 ui32FwAddr, __u32 ui32Value); -typedef enum PVRSRV_ERROR_TAG (*PFN_SYNC_CHECKPOINT_SIGNAL_WAITERS_FN)(void); -typedef void(*PFN_SYNC_CHECKPOINT_CHECK_STATE_FN)(void); -#if defined(PDUMP) -typedef PVRSRV_ERROR(*PFN_SYNC_CHECKPOINT_FENCE_GETCHECKPOINTS_FN)(PVRSRV_FENCE iFence, - IMG_UINT32 *puiNumCheckpoints, - PSYNC_CHECKPOINT **papsCheckpoints); -#endif -#endif - -/* This is the function that kick code will call in a NO_HARDWARE build only after - * sync checkpoints have been manually signalled, to allow the OS native sync - * implementation to update its timelines (as the usual callback notification - * of signalled checkpoints is not supported for NO_HARDWARE). - */ -#ifndef CHECKPOINT_PFNS -typedef void (*PFN_SYNC_CHECKPOINT_NOHW_UPDATE_TIMELINES_FN)(void *private_data); -typedef void (*PFN_SYNC_CHECKPOINT_FREE_CHECKPOINT_LIST_MEM_FN)(void *mem_ptr); - -#define SYNC_CHECKPOINT_IMPL_MAX_STRLEN 20 - -typedef struct { - PFN_SYNC_CHECKPOINT_FENCE_RESOLVE_FN pfnFenceResolve; - PFN_SYNC_CHECKPOINT_FENCE_CREATE_FN pfnFenceCreate; - PFN_SYNC_CHECKPOINT_FENCE_ROLLBACK_DATA_FN pfnFenceDataRollback; - PFN_SYNC_CHECKPOINT_FENCE_FINALISE_FN pfnFenceFinalise; - PFN_SYNC_CHECKPOINT_NOHW_UPDATE_TIMELINES_FN pfnNoHWUpdateTimelines; - PFN_SYNC_CHECKPOINT_FREE_CHECKPOINT_LIST_MEM_FN pfnFreeCheckpointListMem; - PFN_SYNC_CHECKPOINT_DUMP_INFO_ON_STALLED_UFOS_FN pfnDumpInfoOnStalledUFOs; - char pszImplName[SYNC_CHECKPOINT_IMPL_MAX_STRLEN]; -#if defined(PDUMP) - PFN_SYNC_CHECKPOINT_FENCE_GETCHECKPOINTS_FN pfnSyncFenceGetCheckpoints; -#endif -} PFN_SYNC_CHECKPOINT_STRUCT; - -enum PVRSRV_ERROR_TAG SyncCheckpointRegisterFunctions(PFN_SYNC_CHECKPOINT_STRUCT *psSyncCheckpointPfns); - -#define CHECKPOINT_PFNS -#endif - -/* sync_checkpoint.h */ -enum PVRSRV_ERROR_TAG SyncCheckpointContextCreate(struct _PVRSRV_DEVICE_NODE_ *psDevConnection, PSYNC_CHECKPOINT_CONTEXT *phSyncCheckpointContext); -enum PVRSRV_ERROR_TAG SyncCheckpointContextDestroy(PSYNC_CHECKPOINT_CONTEXT hSyncCheckpointContext); -void SyncCheckpointContextRef(PSYNC_CHECKPOINT_CONTEXT psContext); -void SyncCheckpointContextUnref(PSYNC_CHECKPOINT_CONTEXT psContext); -enum PVRSRV_ERROR_TAG SyncCheckpointAlloc(PSYNC_CHECKPOINT_CONTEXT psSyncContext, PVRSRV_TIMELINE timeline, PVRSRV_FENCE fence, const char *pszCheckpointName, PSYNC_CHECKPOINT *ppsSyncCheckpoint); -void SyncCheckpointSignal(PSYNC_CHECKPOINT psSyncCheckpoint, u32 fence_sync_flags); -void SyncCheckpointError(PSYNC_CHECKPOINT psSyncCheckpoint, u32 fence_sync_flags); -enum tag_img_bool SyncCheckpointIsSignalled(PSYNC_CHECKPOINT psSyncCheckpoint, u32 fence_sync_flags); -enum tag_img_bool SyncCheckpointIsErrored(PSYNC_CHECKPOINT psSyncCheckpoint, u32 fence_sync_flags); -enum PVRSRV_ERROR_TAG SyncCheckpointTakeRef(PSYNC_CHECKPOINT psSyncCheckpoint); -enum PVRSRV_ERROR_TAG SyncCheckpointDropRef(PSYNC_CHECKPOINT psSyncCheckpoint); -void SyncCheckpointFree(PSYNC_CHECKPOINT psSyncCheckpoint); -__u32 SyncCheckpointGetFirmwareAddr(PSYNC_CHECKPOINT psSyncCheckpoint); -void SyncCheckpointCCBEnqueued(PSYNC_CHECKPOINT psSyncCheckpoint); -__u32 SyncCheckpointGetId(PSYNC_CHECKPOINT psSyncCheckpoint); -__u32 SyncCheckpointGetEnqueuedCount(PSYNC_CHECKPOINT psSyncCheckpoint); -__u32 SyncCheckpointGetReferenceCount(PSYNC_CHECKPOINT psSyncCheckpoint); -PVRSRV_TIMELINE SyncCheckpointGetTimeline(PSYNC_CHECKPOINT psSyncCheckpoint); -const char *SyncCheckpointGetStateString(PSYNC_CHECKPOINT psSyncCheckpoint); -#if defined(SUPPORT_NATIVE_FENCE_SYNC) -struct _PVRSRV_DEVICE_NODE_ *SyncCheckpointGetAssociatedDevice(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext); -#endif - -#endif - -#if defined(SUPPORT_NATIVE_FENCE_SYNC) || defined(SUPPORT_BUFFER_SYNC) -/*************************************************************************/ /*! -@Function NativeSyncGetFenceStatusWq -@Description Called to get the Foreign Fence status workqueue used in - Fence sync and Buffer sync. -@Return struct workqueue_struct ptr on success, NULL otherwise. -*/ /**************************************************************************/ -struct workqueue_struct *NativeSyncGetFenceStatusWq(void); -#endif - -#endif /* __SERVICES_KERNEL_CLIENT__ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/services_km.h b/drivers/gpu/drm/img-rogue/1.17/services_km.h deleted file mode 100644 index 91ee3b2f0976e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/services_km.h +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services API Kernel mode Header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Exported services API details -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SERVICES_KM_H -#define SERVICES_KM_H - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "virt_validation_defs.h" -#endif - -/*! 4k page size definition */ -#define PVRSRV_4K_PAGE_SIZE 4096UL /*!< Size of a 4K Page */ -#define PVRSRV_4K_PAGE_SIZE_ALIGNSHIFT 12 /*!< Amount to shift an address by so that - it is always page-aligned */ -/*! 16k page size definition */ -#define PVRSRV_16K_PAGE_SIZE 16384UL /*!< Size of a 16K Page */ -#define PVRSRV_16K_PAGE_SIZE_ALIGNSHIFT 14 /*!< Amount to shift an address by so that - it is always page-aligned */ -/*! 64k page size definition */ -#define PVRSRV_64K_PAGE_SIZE 65536UL /*!< Size of a 64K Page */ -#define PVRSRV_64K_PAGE_SIZE_ALIGNSHIFT 16 /*!< Amount to shift an address by so that - it is always page-aligned */ -/*! 256k page size definition */ -#define PVRSRV_256K_PAGE_SIZE 262144UL /*!< Size of a 256K Page */ -#define PVRSRV_256K_PAGE_SIZE_ALIGNSHIFT 18 /*!< Amount to shift an address by so that - it is always page-aligned */ -/*! 1MB page size definition */ -#define PVRSRV_1M_PAGE_SIZE 1048576UL /*!< Size of a 1M Page */ -#define PVRSRV_1M_PAGE_SIZE_ALIGNSHIFT 20 /*!< Amount to shift an address by so that - it is always page-aligned */ -/*! 2MB page size definition */ -#define PVRSRV_2M_PAGE_SIZE 2097152UL /*!< Size of a 2M Page */ -#define PVRSRV_2M_PAGE_SIZE_ALIGNSHIFT 21 /*!< Amount to shift an address by so that - it is always page-aligned */ - -/*! - * @AddToGroup SRVConnectInterfaces - * @{ - */ - -#ifndef PVRSRV_DEV_CONNECTION_TYPEDEF -#define PVRSRV_DEV_CONNECTION_TYPEDEF -/*! - * Forward declaration (look on connection.h) - */ -typedef struct PVRSRV_DEV_CONNECTION_TAG PVRSRV_DEV_CONNECTION; -#endif - -/*! - * @Anchor SRV_FLAGS - * @Name SRV_FLAGS: Services connection flags - * Allows to define per-client policy for Services. - * @{ - */ - -/* - * Use of the 32-bit connection flags mask - * ( X = taken/in use, - = available/unused ) - * - * 31 27 20 6 4 0 - * | | | | | | - * X---XXXXXXXX-------------XXX---- - */ - -#define SRV_NO_HWPERF_CLIENT_STREAM (1UL << 4) /*!< Don't create HWPerf for this connection */ -#define SRV_FLAGS_CLIENT_64BIT_COMPAT (1UL << 5) /*!< This flags gets set if the client is 64 Bit compatible. */ -#define SRV_FLAGS_CLIENT_SLR_DISABLED (1UL << 6) /*!< This flag is set if the client does not want Sync Lockup Recovery (SLR) enabled. */ -#define SRV_FLAGS_PDUMPCTRL (1UL << 31) /*!< PDump Ctrl client flag */ - -/*! @} SRV_FLAGS */ - -/*! @} End of SRVConnectInterfaces */ - -/* - * Bits 20 - 27 are used to pass information needed for validation - * of the GPU Virtualisation Validation mechanism. In particular: - * - * Bits: - * [20 - 22]: OSid of the memory region that will be used for allocations - * [23 - 25]: OSid that will be emitted by the Firmware for all memory accesses - * regarding that memory context. - * [26]: If the AXI Protection register will be set to secure for that OSid - * [27]: If the Emulator Wrapper Register checking for protection violation - * will be set to secure for that OSid - */ - -#define VIRTVAL_FLAG_OSID_SHIFT (20) -#define SRV_VIRTVAL_FLAG_OSID_MASK (7U << VIRTVAL_FLAG_OSID_SHIFT) - -#define VIRTVAL_FLAG_OSIDREG_SHIFT (23) -#define SRV_VIRTVAL_FLAG_OSIDREG_MASK (7U << VIRTVAL_FLAG_OSIDREG_SHIFT) - -#define VIRTVAL_FLAG_AXIPREG_SHIFT (26) -#define SRV_VIRTVAL_FLAG_AXIPREG_MASK (1U << VIRTVAL_FLAG_AXIPREG_SHIFT) - -#define VIRTVAL_FLAG_AXIPTD_SHIFT (27) -#define SRV_VIRTVAL_FLAG_AXIPTD_MASK (1U << VIRTVAL_FLAG_AXIPTD_SHIFT) - - -/* Size of pointer on a 64 bit machine */ -#define POINTER_SIZE_64BIT (8U) - - -/* - Pdump flags which are accessible to Services clients -*/ -#define PDUMP_NONE 0x00000000U /*pszIOCName, - (psEntry->pfFunction != NULL) ? psEntry->pszFunctionName : "(null)", - psEntry->ui32CallCount, - psEntry->ui32CopyFromUserTotalBytes, - psEntry->ui32CopyToUserTotalBytes, - (unsigned long long) OSDivide64r64(psEntry->ui64TotalTimeNS, 1000, &ui32Remainder), - (unsigned long long) OSDivide64r64(psEntry->ui64MaxTimeNS, 1000, &ui32Remainder)); - - - } -} -#endif - -PVRSRV_ERROR -CopyFromUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void *pvDest, - void __user *pvSrc, - IMG_UINT32 ui32Size) -{ - g_BridgeDispatchTable[ui32DispatchTableEntry].ui32CopyFromUserTotalBytes+=ui32Size; - g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size; - return OSBridgeCopyFromUser(psConnection, pvDest, pvSrc, ui32Size); -} -PVRSRV_ERROR -CopyToUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void __user *pvDest, - void *pvSrc, - IMG_UINT32 ui32Size) -{ - g_BridgeDispatchTable[ui32DispatchTableEntry].ui32CopyToUserTotalBytes+=ui32Size; - g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size; - return OSBridgeCopyToUser(psConnection, pvDest, pvSrc, ui32Size); -} -#else -INLINE PVRSRV_ERROR -CopyFromUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void *pvDest, - void __user *pvSrc, - IMG_UINT32 ui32Size) -{ - PVR_UNREFERENCED_PARAMETER (ui32DispatchTableEntry); - return OSBridgeCopyFromUser(psConnection, pvDest, pvSrc, ui32Size); -} -INLINE PVRSRV_ERROR -CopyToUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void __user *pvDest, - void *pvSrc, - IMG_UINT32 ui32Size) -{ - PVR_UNREFERENCED_PARAMETER (ui32DispatchTableEntry); - return OSBridgeCopyToUser(psConnection, pvDest, pvSrc, ui32Size); -} -#endif - -PVRSRV_ERROR -PVRSRVConnectKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32Flags, - IMG_UINT32 ui32ClientBuildOptions, - IMG_UINT32 ui32ClientDDKVersion, - IMG_UINT32 ui32ClientDDKBuild, - IMG_UINT8 *pui8KernelArch, - IMG_UINT32 *pui32CapabilityFlags, - IMG_UINT64 *ui64PackedBvnc) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; - IMG_UINT32 ui32DDKVersion, ui32DDKBuild; - PVRSRV_DATA *psSRVData = NULL; - IMG_UINT64 ui64ProcessVASpaceSize = OSGetCurrentProcessVASpaceSize(); - static IMG_BOOL bIsFirstConnection=IMG_FALSE; - -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - /* Gather BVNC information to output to UM */ - - *ui64PackedBvnc = rgx_bvnc_pack(psDevInfo->sDevFeatureCfg.ui32B, - psDevInfo->sDevFeatureCfg.ui32V, - psDevInfo->sDevFeatureCfg.ui32N, - psDevInfo->sDevFeatureCfg.ui32C); -#else - *ui64PackedBvnc = 0; -#endif /* defined(SUPPORT_RGX)*/ - - /* Clear the flags */ - *pui32CapabilityFlags = 0; - - psSRVData = PVRSRVGetPVRSRVData(); - - psConnection->ui32ClientFlags = ui32Flags; - - /*Set flags to pass back to the client showing which cache coherency is available.*/ - /* Is the system snooping of caches emulated in software? */ - if (PVRSRVSystemSnoopingIsEmulated(psDeviceNode->psDevConfig)) - { - *pui32CapabilityFlags |= PVRSRV_CACHE_COHERENT_EMULATE_FLAG; - } - else - { - /*Set flags to pass back to the client showing which cache coherency is available.*/ - /*Is the system CPU cache coherent?*/ - if (PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig)) - { - *pui32CapabilityFlags |= PVRSRV_CACHE_COHERENT_DEVICE_FLAG; - } - /*Is the system device cache coherent?*/ - if (PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) - { - *pui32CapabilityFlags |= PVRSRV_CACHE_COHERENT_CPU_FLAG; - } - } - - /* Has the system device non-mappable local memory?*/ - if (PVRSRVSystemHasNonMappableLocalMemory(psDeviceNode->psDevConfig)) - { - *pui32CapabilityFlags |= PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG; - } - - /* Is system using FBCDC v31? */ - if (psDeviceNode->pfnHasFBCDCVersion31(psDeviceNode)) - { - *pui32CapabilityFlags |= PVRSRV_FBCDC_V3_1_USED; - } - - /* Set flags to indicate shared-virtual-memory (SVM) allocation availability */ - if (! psDeviceNode->ui64GeneralSVMHeapTopVA || ! ui64ProcessVASpaceSize) - { - *pui32CapabilityFlags |= PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED; - } - else - { - if (ui64ProcessVASpaceSize <= psDeviceNode->ui64GeneralSVMHeapTopVA) - { - *pui32CapabilityFlags |= PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED; - } - else - { - /* This can happen when processor has more virtual address bits - than device (i.e. alloc is not always guaranteed to succeed) */ - *pui32CapabilityFlags |= PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL; - } - } - - /* Is the system DMA capable? */ - if (psDeviceNode->bHasSystemDMA) - { - *pui32CapabilityFlags |= PVRSRV_SYSTEM_DMA_USED; - } - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -{ - IMG_UINT32 ui32OSid = 0, ui32OSidReg = 0; - IMG_BOOL bOSidAxiProtReg = IMG_FALSE; - - ui32OSid = (ui32Flags & SRV_VIRTVAL_FLAG_OSID_MASK) >> (VIRTVAL_FLAG_OSID_SHIFT); - ui32OSidReg = (ui32Flags & SRV_VIRTVAL_FLAG_OSIDREG_MASK) >> (VIRTVAL_FLAG_OSIDREG_SHIFT); - -#if defined(EMULATOR) -{ - /* AXI_ACELITE is only supported on rogue cores - volcanic cores all support full ACE - * and don't want to compile the code below (RGX_FEATURE_AXI_ACELITE_BIT_MASK is not - * defined for volcanic cores). - */ - - PVRSRV_RGXDEV_INFO *psDevInfo; - psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice; - -#if defined(RGX_FEATURE_AXI_ACELITE_BIT_MASK) - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, AXI_ACELITE)) -#else - if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, AXI_ACE)) -#endif - { - IMG_UINT32 ui32OSidAxiProtReg = 0, ui32OSidAxiProtTD = 0; - - ui32OSidAxiProtReg = (ui32Flags & SRV_VIRTVAL_FLAG_AXIPREG_MASK) >> (VIRTVAL_FLAG_AXIPREG_SHIFT); - ui32OSidAxiProtTD = (ui32Flags & SRV_VIRTVAL_FLAG_AXIPTD_MASK) >> (VIRTVAL_FLAG_AXIPTD_SHIFT); - - PVR_DPF((PVR_DBG_MESSAGE, - "[AxiProt & Virt]: Setting bOSidAxiProt of Emulator's Trusted Device for Catbase %d to %s", - ui32OSidReg, - (ui32OSidAxiProtTD == 1)?"TRUE":"FALSE")); - - bOSidAxiProtReg = ui32OSidAxiProtReg == 1; - PVR_DPF((PVR_DBG_MESSAGE, - "[AxiProt & Virt]: Setting bOSidAxiProt of FW's Register for Catbase %d to %s", - ui32OSidReg, - bOSidAxiProtReg?"TRUE":"FALSE")); - - SetAxiProtOSid(ui32OSidReg, ui32OSidAxiProtTD); - } -} -#endif /* defined(EMULATOR) */ - - /* We now know the OSid, OSidReg and bOSidAxiProtReg setting for this - * connection. We can access these from wherever we have a connection - * reference and do not need to traverse an arbitrary linked-list to - * obtain them. The settings are process-specific. - */ - psConnection->ui32OSid = ui32OSid; - psConnection->ui32OSidReg = ui32OSidReg; - psConnection->bOSidAxiProtReg = bOSidAxiProtReg; - - PVR_DPF((PVR_DBG_MESSAGE, - "[GPU Virtualization Validation]: OSIDs: %d, %d", - ui32OSid, - ui32OSidReg)); -} -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - -#if defined(SUPPORT_WORKLOAD_ESTIMATION) - /* Only enabled if enabled in the UM */ - if (!(ui32ClientBuildOptions & RGX_BUILD_OPTIONS_KM & OPTIONS_WORKLOAD_ESTIMATION_MASK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Workload Estimation disabled. Not enabled in UM", - __func__)); - } -#endif - -#if defined(SUPPORT_PDVFS) - /* Only enabled if enabled in the UM */ - if (!(ui32ClientBuildOptions & RGX_BUILD_OPTIONS_KM & OPTIONS_PDVFS_MASK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Proactive DVFS disabled. Not enabled in UM", - __func__)); - } -#endif - - ui32DDKVersion = PVRVERSION_PACK(PVRVERSION_MAJ, PVRVERSION_MIN); - ui32DDKBuild = PVRVERSION_BUILD; - - if (ui32Flags & SRV_FLAGS_CLIENT_64BIT_COMPAT) - { - psSRVData->sDriverInfo.ui8UMSupportedArch |= BUILD_ARCH_64BIT; - } - else - { - psSRVData->sDriverInfo.ui8UMSupportedArch |= BUILD_ARCH_32BIT; - } - - if (IMG_FALSE == bIsFirstConnection) - { - psSRVData->sDriverInfo.sKMBuildInfo.ui32BuildOptions = (RGX_BUILD_OPTIONS_KM); - psSRVData->sDriverInfo.sUMBuildInfo.ui32BuildOptions = ui32ClientBuildOptions; - - psSRVData->sDriverInfo.sKMBuildInfo.ui32BuildVersion = ui32DDKVersion; - psSRVData->sDriverInfo.sUMBuildInfo.ui32BuildVersion = ui32ClientDDKVersion; - - psSRVData->sDriverInfo.sKMBuildInfo.ui32BuildRevision = ui32DDKBuild; - psSRVData->sDriverInfo.sUMBuildInfo.ui32BuildRevision = ui32ClientDDKBuild; - - psSRVData->sDriverInfo.sKMBuildInfo.ui32BuildType = - ((RGX_BUILD_OPTIONS_KM) & OPTIONS_DEBUG_MASK) ? BUILD_TYPE_DEBUG : BUILD_TYPE_RELEASE; - - psSRVData->sDriverInfo.sUMBuildInfo.ui32BuildType = - (ui32ClientBuildOptions & OPTIONS_DEBUG_MASK) ? BUILD_TYPE_DEBUG : BUILD_TYPE_RELEASE; - - if (sizeof(void *) == POINTER_SIZE_64BIT) - { - psSRVData->sDriverInfo.ui8KMBitArch |= BUILD_ARCH_64BIT; - } - else - { - psSRVData->sDriverInfo.ui8KMBitArch |= BUILD_ARCH_32BIT; - } - } - - /* Masking out every option that is not kernel specific*/ - ui32ClientBuildOptions &= RGX_BUILD_OPTIONS_MASK_KM; - - /* - * Validate the build options - */ - ui32BuildOptions = (RGX_BUILD_OPTIONS_KM); - if (ui32BuildOptions != ui32ClientBuildOptions) - { - ui32BuildOptionsMismatch = ui32BuildOptions ^ ui32ClientBuildOptions; -#if !defined(PVRSRV_STRICT_COMPAT_CHECK) - /*Mask the debug flag option out as we do support combinations of debug vs release in um & km*/ - ui32BuildOptionsMismatch &= OPTIONS_STRICT; -#endif - if ( (ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) %s: Mismatch in client-side and KM driver build options; " - "extra options present in client-side driver: (0x%x). Please check rgx_options.h", - __func__, - ui32ClientBuildOptions & ui32BuildOptionsMismatch )); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH, chk_exit); - } - - if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) - { - PVR_LOG(("(FAIL) %s: Mismatch in client-side and KM driver build options; " - "extra options present in KM driver: (0x%x). Please check rgx_options.h", - __func__, - ui32BuildOptions & ui32BuildOptionsMismatch )); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH, chk_exit); - } - if (IMG_FALSE == bIsFirstConnection) - { - PVR_LOG(("%s: COMPAT_TEST: Client-side (0x%04x) (%s) and KM driver (0x%04x) (%s) build options differ.", - __func__, - ui32ClientBuildOptions, - (psSRVData->sDriverInfo.sUMBuildInfo.ui32BuildType)?"release":"debug", - ui32BuildOptions, - (psSRVData->sDriverInfo.sKMBuildInfo.ui32BuildType)?"release":"debug")); - }else{ - PVR_DPF((PVR_DBG_WARNING, "%s: COMPAT_TEST: Client-side (0x%04x) and KM driver (0x%04x) build options differ.", - __func__, - ui32ClientBuildOptions, - ui32BuildOptions)); - - } - if (!psSRVData->sDriverInfo.bIsNoMatch) - psSRVData->sDriverInfo.bIsNoMatch = IMG_TRUE; - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: Client-side and KM driver build options match. [ OK ]", __func__)); - } - - /* - * Validate DDK version - */ - if (ui32ClientDDKVersion != ui32DDKVersion) - { - if (!psSRVData->sDriverInfo.bIsNoMatch) - psSRVData->sDriverInfo.bIsNoMatch = IMG_TRUE; - PVR_LOG(("(FAIL) %s: Incompatible driver DDK version (%u.%u) / client DDK version (%u.%u).", - __func__, - PVRVERSION_MAJ, PVRVERSION_MIN, - PVRVERSION_UNPACK_MAJ(ui32ClientDDKVersion), - PVRVERSION_UNPACK_MIN(ui32ClientDDKVersion))); - PVR_DBG_BREAK; - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DDK_VERSION_MISMATCH, chk_exit); - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: driver DDK version (%u.%u) and client DDK version (%u.%u) match. [ OK ]", - __func__, - PVRVERSION_MAJ, PVRVERSION_MIN, PVRVERSION_MAJ, PVRVERSION_MIN)); - } - - /* Create stream for every connection except for the special clients - * that don't need it e.g.: recipients of HWPerf data. */ - if (!(psConnection->ui32ClientFlags & SRV_NO_HWPERF_CLIENT_STREAM)) - { - IMG_CHAR acStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; - OSSNPrintf(acStreamName, PRVSRVTL_MAX_STREAM_NAME_SIZE, - PVRSRV_TL_HWPERF_HOST_CLIENT_STREAM_FMTSPEC, - psDeviceNode->sDevId.i32OsDeviceID, - psConnection->pid); - - eError = TLStreamCreate(&psConnection->hClientTLStream, - acStreamName, - PVRSRV_CLIENT_TL_STREAM_SIZE_DEFAULT, - TL_OPMODE_DROP_NEWER | - TL_FLAG_ALLOCATE_ON_FIRST_OPEN, - NULL, NULL, NULL, NULL); - if (eError != PVRSRV_OK && eError != PVRSRV_ERROR_ALREADY_EXISTS) - { - PVR_LOG_ERROR(eError, "TLStreamCreate"); - psConnection->hClientTLStream = NULL; - } - else if (eError == PVRSRV_OK) - { - /* Set "tlctrl" stream as a notification channel. This channel is - * is used to notify recipients about stream open/close (by writer) - * actions (and possibly other actions in the future). */ - eError = TLStreamSetNotifStream(psConnection->hClientTLStream, - psSRVData->hTLCtrlStream); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "TLStreamSetNotifStream"); - TLStreamClose(psConnection->hClientTLStream); - psConnection->hClientTLStream = NULL; - } - } - - /* Reset error status. We don't want to propagate any errors from here. */ - eError = PVRSRV_OK; - PVR_DPF((PVR_DBG_MESSAGE, "Created stream \"%s\".", acStreamName)); - } - - /* - * Validate DDK build - */ - if (ui32ClientDDKBuild != ui32DDKBuild) - { - if (!psSRVData->sDriverInfo.bIsNoMatch) - psSRVData->sDriverInfo.bIsNoMatch = IMG_TRUE; - PVR_DPF((PVR_DBG_WARNING, "%s: Mismatch in driver DDK revision (%d) / client DDK revision (%d).", - __func__, ui32DDKBuild, ui32ClientDDKBuild)); -#if defined(PVRSRV_STRICT_COMPAT_CHECK) - PVR_DBG_BREAK; - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DDK_BUILD_MISMATCH, chk_exit); -#endif - } - else - { - PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: driver DDK revision (%d) and client DDK revision (%d) match. [ OK ]", - __func__, ui32DDKBuild, ui32ClientDDKBuild)); - } - -#if defined(PDUMP) - /* Success so far so is it the PDump client that is connecting? */ - if (ui32Flags & SRV_FLAGS_PDUMPCTRL) - { - if (psDeviceNode->sDevId.ui32InternalID == psSRVData->ui32PDumpBoundDevice) - { - PDumpConnectionNotify(psDeviceNode); - } - else - { - eError = PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE; - PVR_DPF((PVR_DBG_ERROR, "%s: PDump requested for device %u but only permitted for device %u", - __func__, psDeviceNode->sDevId.ui32InternalID, psSRVData->ui32PDumpBoundDevice)); - goto chk_exit; - } - } - else - { - /* Warn if the app is connecting to a device PDump won't be able to capture */ - if (psDeviceNode->sDevId.ui32InternalID != psSRVData->ui32PDumpBoundDevice) - { - PVR_DPF((PVR_DBG_WARNING, "%s: NB. App running on device %d won't be captured by PDump (must be on device %u)", - __func__, psDeviceNode->sDevId.ui32InternalID, psSRVData->ui32PDumpBoundDevice)); - } - } -#endif - - PVR_ASSERT(pui8KernelArch != NULL); - - if (psSRVData->sDriverInfo.ui8KMBitArch & BUILD_ARCH_64BIT) - { - *pui8KernelArch = 64; - } - else - { - *pui8KernelArch = 32; - } - - bIsFirstConnection = IMG_TRUE; - -#if defined(DEBUG_BRIDGE_KM) - { - int ii; - - /* dump dispatch table offset lookup table */ - PVR_DPF((PVR_DBG_MESSAGE, "%s: g_BridgeDispatchTableStartOffsets[0-%lu] entries:", __func__, BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT - 1)); - for (ii=0; ii < BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT; ii++) - { - PVR_DPF((PVR_DBG_MESSAGE, "g_BridgeDispatchTableStartOffsets[%d]: %u", ii, g_BridgeDispatchTableStartOffsets[ii][PVR_DISPATCH_OFFSET_FIRST_FUNC])); - } - } -#endif - -#if defined(PDUMP) - if (!(ui32Flags & SRV_FLAGS_PDUMPCTRL)) - { - IMG_UINT64 ui64PDumpState = 0; - - PDumpGetStateKM(&ui64PDumpState); - if (ui64PDumpState & PDUMP_STATE_CONNECTED) - { - *pui32CapabilityFlags |= PVRSRV_PDUMP_IS_RECORDING; - } - } -#endif - -chk_exit: - return eError; -} - -PVRSRV_ERROR -PVRSRVDisconnectKM(void) -{ -#if defined(INTEGRITY_OS) && defined(DEBUG_BRIDGE_KM) - PVRSRVPrintBridgeStats(); -#endif - /* just return OK, per-process data is cleaned up by resmgr */ - - return PVRSRV_OK; -} - -/**************************************************************************/ /*! -@Function PVRSRVAcquireGlobalEventObjectKM -@Description Acquire the global event object. -@Output phGlobalEventObject On success, points to the global event - object handle -@Return PVRSRV_ERROR PVRSRV_OK on success or an error - otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR -PVRSRVAcquireGlobalEventObjectKM(IMG_HANDLE *phGlobalEventObject) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - *phGlobalEventObject = psPVRSRVData->hGlobalEventObject; - - return PVRSRV_OK; -} - -/**************************************************************************/ /*! -@Function PVRSRVReleaseGlobalEventObjectKM -@Description Release the global event object. -@Output hGlobalEventObject Global event object handle -@Return PVRSRV_ERROR PVRSRV_OK on success or an error otherwise -*/ /***************************************************************************/ -PVRSRV_ERROR -PVRSRVReleaseGlobalEventObjectKM(IMG_HANDLE hGlobalEventObject) -{ - PVR_ASSERT(PVRSRVGetPVRSRVData()->hGlobalEventObject == hGlobalEventObject); - - return PVRSRV_OK; -} - -/* - PVRSRVDumpDebugInfoKM -*/ -PVRSRV_ERROR -PVRSRVDumpDebugInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32VerbLevel) -{ - if (ui32VerbLevel > DEBUG_REQUEST_VERBOSITY_MAX) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - PVR_LOG(("User requested PVR debug info")); - - PVRSRVDebugRequest(psDeviceNode, ui32VerbLevel, NULL, NULL); - - return PVRSRV_OK; -} - -/* - PVRSRVGetDevClockSpeedKM -*/ -PVRSRV_ERROR -PVRSRVGetDevClockSpeedKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_PUINT32 pui32RGXClockSpeed) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVR_ASSERT(psDeviceNode->pfnDeviceClockSpeed != NULL); - - PVR_UNREFERENCED_PARAMETER(psConnection); - - eError = psDeviceNode->pfnDeviceClockSpeed(psDeviceNode, pui32RGXClockSpeed); - PVR_WARN_IF_ERROR(eError, "pfnDeviceClockSpeed"); - - return eError; -} - - -/* - PVRSRVHWOpTimeoutKM -*/ -PVRSRV_ERROR -PVRSRVHWOpTimeoutKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(PVRSRV_RESET_ON_HWTIMEOUT) - PVR_LOG(("User requested OS reset")); - OSPanic(); -#endif - PVR_LOG(("HW operation timeout, dump server info")); - PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL); - return PVRSRV_OK; -} - - -IMG_INT -DummyBW(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 *psBridgeIn, - IMG_UINT8 *psBridgeOut, - CONNECTION_DATA *psConnection) -{ - PVR_UNREFERENCED_PARAMETER(psBridgeIn); - PVR_UNREFERENCED_PARAMETER(psBridgeOut); - PVR_UNREFERENCED_PARAMETER(psConnection); - -#if defined(DEBUG_BRIDGE_KM) - PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: ui32DispatchTableEntry %u (%s) mapped to " - "Dummy Wrapper (probably not what you want!)", - __func__, ui32DispatchTableEntry, g_BridgeDispatchTable[ui32DispatchTableEntry].pszIOCName)); -#else - PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: ui32DispatchTableEntry %u mapped to " - "Dummy Wrapper (probably not what you want!)", - __func__, ui32DispatchTableEntry)); -#endif - return PVRSRV_ERROR_BRIDGE_ENOTTY; -} - -PVRSRV_ERROR PVRSRVAlignmentCheckKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32AlignChecksSize, - IMG_UINT32 aui32AlignChecks[]) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - -#if !defined(NO_HARDWARE) - - PVR_ASSERT(psDeviceNode->pfnAlignmentCheck != NULL); - return psDeviceNode->pfnAlignmentCheck(psDeviceNode, ui32AlignChecksSize, - aui32AlignChecks); - -#else - - PVR_UNREFERENCED_PARAMETER(psDeviceNode); - PVR_UNREFERENCED_PARAMETER(ui32AlignChecksSize); - PVR_UNREFERENCED_PARAMETER(aui32AlignChecks); - - return PVRSRV_OK; - -#endif /* !defined(NO_HARDWARE) */ - -} - -PVRSRV_ERROR PVRSRVGetDeviceStatusKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *pui32DeviceStatus) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - - /* First try to update the status. */ - if (psDeviceNode->pfnUpdateHealthStatus != NULL) - { - PVRSRV_ERROR eError = psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, - IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetDeviceStatusKM: Failed to " - "check for device status (%d)", eError)); - - /* Return unknown status and error because we don't know what - * happened and if the status is valid. */ - *pui32DeviceStatus = PVRSRV_DEVICE_STATUS_UNKNOWN; - return eError; - } - } - - switch (OSAtomicRead(&psDeviceNode->eHealthStatus)) - { - case PVRSRV_DEVICE_HEALTH_STATUS_OK: - *pui32DeviceStatus = PVRSRV_DEVICE_STATUS_OK; - return PVRSRV_OK; - case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING: - *pui32DeviceStatus = PVRSRV_DEVICE_STATUS_NOT_RESPONDING; - return PVRSRV_OK; - case PVRSRV_DEVICE_HEALTH_STATUS_DEAD: - case PVRSRV_DEVICE_HEALTH_STATUS_FAULT: - case PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED: - *pui32DeviceStatus = PVRSRV_DEVICE_STATUS_DEVICE_ERROR; - return PVRSRV_OK; - default: - *pui32DeviceStatus = PVRSRV_DEVICE_STATUS_UNKNOWN; - return PVRSRV_ERROR_INTERNAL_ERROR; - } -} - -PVRSRV_ERROR PVRSRVGetMultiCoreInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CapsSize, - IMG_UINT32 *pui32NumCores, - IMG_UINT64 *pui64Caps) -{ - PVRSRV_ERROR eError = PVRSRV_ERROR_NOT_SUPPORTED; - PVR_UNREFERENCED_PARAMETER(psConnection); - - if (ui32CapsSize > 0) - { - /* Clear the buffer to ensure no uninitialised data is returned to UM - * if the pfn call below does not write to the whole array, or is null. - */ - memset(pui64Caps, 0x00, (ui32CapsSize * sizeof(IMG_UINT64))); - } - - if (psDeviceNode->pfnGetMultiCoreInfo != NULL) - { - eError = psDeviceNode->pfnGetMultiCoreInfo(psDeviceNode, ui32CapsSize, pui32NumCores, pui64Caps); - } - return eError; -} - - -/*! - * ***************************************************************************** - * @brief A wrapper for removing entries in the g_BridgeDispatchTable array. - * All this does is zero the entry to allow for a full table re-population - * later. - * - * @param ui32BridgeGroup - * @param ui32Index - * - * @return - ********************************************************************************/ -void -UnsetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup, IMG_UINT32 ui32Index) -{ - ui32Index += g_BridgeDispatchTableStartOffsets[ui32BridgeGroup][PVR_DISPATCH_OFFSET_FIRST_FUNC]; - - g_BridgeDispatchTable[ui32Index].pfFunction = NULL; - g_BridgeDispatchTable[ui32Index].hBridgeLock = NULL; -#if defined(DEBUG_BRIDGE_KM) - g_BridgeDispatchTable[ui32Index].pszIOCName = NULL; - g_BridgeDispatchTable[ui32Index].pszFunctionName = NULL; - g_BridgeDispatchTable[ui32Index].pszBridgeLockName = NULL; - g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; - g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; - g_BridgeDispatchTable[ui32Index].ui64TotalTimeNS = 0; - g_BridgeDispatchTable[ui32Index].ui64MaxTimeNS = 0; -#endif -} - -/*! - * ***************************************************************************** - * @brief A wrapper for filling in the g_BridgeDispatchTable array that does - * error checking. - * - * @param ui32Index - * @param pszIOCName - * @param pfFunction - * @param pszFunctionName - * @param hBridgeLock - * @param pszBridgeLockName - * @param ui32InBufferSize - * @param ui32OutBufferSize - * - * @return - ********************************************************************************/ -void -_SetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup, - IMG_UINT32 ui32Index, - const IMG_CHAR *pszIOCName, - BridgeWrapperFunction pfFunction, - const IMG_CHAR *pszFunctionName, - POS_LOCK hBridgeLock, - const IMG_CHAR *pszBridgeLockName, - IMG_UINT32 ui32InBufferSize, - IMG_UINT32 ui32OutBufferSize) -{ - static IMG_UINT32 ui32PrevIndex = IMG_UINT32_MAX; /* -1 */ - -#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) - PVR_UNREFERENCED_PARAMETER(pszFunctionName); - PVR_UNREFERENCED_PARAMETER(pszBridgeLockName); -#endif - - ui32Index += g_BridgeDispatchTableStartOffsets[ui32BridgeGroup][PVR_DISPATCH_OFFSET_FIRST_FUNC]; - -#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) - /* Enable this to dump out the dispatch table entries */ - PVR_DPF((PVR_DBG_WARNING, "%s: g_BridgeDispatchTableStartOffsets[%d]=%d", __func__, ui32BridgeGroup, g_BridgeDispatchTableStartOffsets[ui32BridgeGroup][PVR_DISPATCH_OFFSET_FIRST_FUNC])); - PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s %s", __func__, ui32Index, pszIOCName, pszFunctionName, pszBridgeLockName)); -#endif - - /* Any gaps are sub-optimal in-terms of memory usage, but we are mainly - * interested in spotting any large gap of wasted memory that could be - * accidentally introduced. - * - * This will currently flag up any gaps > 5 entries. - * - * NOTE: This shouldn't be debug only since switching from debug->release - * etc is likely to modify the available ioctls and thus be a point where - * mistakes are exposed. This isn't run at a performance critical time. - */ - if ((ui32PrevIndex != IMG_UINT32_MAX) && - ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) || - (ui32Index <= ui32PrevIndex))) - { -#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) - PVR_DPF((PVR_DBG_WARNING, - "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)", - __func__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName, - ui32Index, pszIOCName)); -#else - PVR_DPF((PVR_DBG_MESSAGE, - "%s: There is a gap in the dispatch table between indices %u and %u (%s)", - __func__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName)); -#endif - } - - if (ui32Index >= BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Index %u (%s) out of range", - __func__, (IMG_UINT)ui32Index, pszIOCName)); - -#if defined(DEBUG_BRIDGE_KM) - PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE_DISPATCH_TABLE_ENTRY_COUNT = %lu", - __func__, BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)); -#if defined(SUPPORT_RGX) - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXREGCONFIG_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXFWDBG_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXBREAKPOINT_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGXTIMERQUERY_DISPATCH_LAST)); - - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGX_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGX_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGX_LAST = %lu", - __func__, PVRSRV_BRIDGE_RGX_LAST)); -#endif - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_LAST = %lu", - __func__, PVRSRV_BRIDGE_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST)); - PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST = %lu", - __func__, PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST)); -#endif - - OSPanic(); - } - - /* Panic if the previous entry has been overwritten as this is not allowed! - * NOTE: This shouldn't be debug only since switching from debug->release - * etc is likely to modify the available ioctls and thus be a point where - * mistakes are exposed. This isn't run at a performance critical time. - */ - if (g_BridgeDispatchTable[ui32Index].pfFunction) - { - if (g_BridgeDispatchTable[ui32Index].pfFunction != pfFunction) - { -#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) - PVR_DPF((PVR_DBG_ERROR, - "%s: Adding dispatch table entry for %s clobbers an existing entry for %s (current pfn=<%p>, new pfn=<%p>)", - __func__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName), - (void*)g_BridgeDispatchTable[ui32Index].pfFunction, (void*)pfFunction)); -#else - PVR_DPF((PVR_DBG_ERROR, - "%s: Adding dispatch table entry for %s clobbers an existing entry (index=%u). (current pfn=<%p>, new pfn=<%p>)", - __func__, pszIOCName, ui32Index, - (void*)g_BridgeDispatchTable[ui32Index].pfFunction, (void*)pfFunction)); - PVR_DPF((PVR_DBG_WARNING, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.")); -#endif - OSPanic(); - } - } - else - { - g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction; - g_BridgeDispatchTable[ui32Index].hBridgeLock = hBridgeLock; - g_BridgeDispatchTable[ui32Index].ui32InBufferSize = ui32InBufferSize; - g_BridgeDispatchTable[ui32Index].ui32OutBufferSize = ui32OutBufferSize; -#if defined(DEBUG_BRIDGE_KM) - g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName; - g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName; - g_BridgeDispatchTable[ui32Index].pszBridgeLockName = pszBridgeLockName; - g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; - g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; - g_BridgeDispatchTable[ui32Index].ui64TotalTimeNS = 0; - g_BridgeDispatchTable[ui32Index].ui64MaxTimeNS = 0; -#endif - } - - ui32PrevIndex = ui32Index; -} - -static PVRSRV_ERROR _BridgeBufferAlloc(void *pvPrivData, void **pvOut) -{ - PVR_UNREFERENCED_PARAMETER(pvPrivData); - - *pvOut = OSAllocZMem(PVRSRV_MAX_BRIDGE_IN_SIZE + - PVRSRV_MAX_BRIDGE_OUT_SIZE); - PVR_RETURN_IF_NOMEM(*pvOut); - - return PVRSRV_OK; -} - -static void _BridgeBufferFree(void *pvPrivData, void *pvFreeData) -{ - PVR_UNREFERENCED_PARAMETER(pvPrivData); - - OSFreeMem(pvFreeData); -} - -PVRSRV_ERROR BridgeDispatcherInit(void) -{ - PVRSRV_ERROR eError; - -#if defined(DEBUG_BRIDGE_KM) - eError = OSLockCreate(&g_hStatsLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", errorLockCreateFailed); -#endif - - eError = PVRSRVPoolCreate(_BridgeBufferAlloc, - _BridgeBufferFree, - PVRSRV_MAX_POOLED_BRIDGE_BUFFERS, - "Bridge buffer pool", - NULL, - &g_psBridgeBufferPool); - PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVPoolCreate", erroPoolCreateFailed); - - return PVRSRV_OK; - -erroPoolCreateFailed: -#if defined(DEBUG_BRIDGE_KM) - OSLockDestroy(g_hStatsLock); - g_hStatsLock = NULL; -errorLockCreateFailed: -#endif - return eError; -} - -void BridgeDispatcherDeinit(void) -{ - if (g_psBridgeBufferPool) - { - PVRSRVPoolDestroy(g_psBridgeBufferPool); - g_psBridgeBufferPool = NULL; - } - -#if defined(DEBUG_BRIDGE_KM) - if (g_hStatsLock) - { - OSLockDestroy(g_hStatsLock); - g_hStatsLock = NULL; - } -#endif -} - -PVRSRV_ERROR BridgedDispatchKM(CONNECTION_DATA * psConnection, - PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM) -{ - - void * psBridgeIn=NULL; - void * psBridgeOut=NULL; - BridgeWrapperFunction pfBridgeHandler; - IMG_UINT32 ui32DispatchTableEntry, ui32GroupBoundary; - PVRSRV_ERROR err = PVRSRV_OK; -#if !defined(INTEGRITY_OS) - PVRSRV_POOL_TOKEN hBridgeBufferPoolToken = NULL; -#endif - IMG_UINT32 ui32Timestamp = OSClockus(); -#if defined(DEBUG_BRIDGE_KM) - IMG_UINT64 ui64TimeStart; - IMG_UINT64 ui64TimeEnd; - IMG_UINT64 ui64TimeDiff; -#endif - IMG_UINT32 ui32DispatchTableIndex, ui32DispatchTableEntryIndex; - -#if defined(DEBUG_BRIDGE_KM_STOP_AT_DISPATCH) - PVR_DBG_BREAK; -#endif - - if (psBridgePackageKM->ui32BridgeID >= BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Out of range dispatch table group ID: %d", - __func__, psBridgePackageKM->ui32BridgeID)); - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EINVAL, return_error); - } - - ui32DispatchTableIndex = OSConfineArrayIndexNoSpeculation(psBridgePackageKM->ui32BridgeID, BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT); - - ui32DispatchTableEntry = g_BridgeDispatchTableStartOffsets[ui32DispatchTableIndex][PVR_DISPATCH_OFFSET_FIRST_FUNC]; - ui32GroupBoundary = g_BridgeDispatchTableStartOffsets[ui32DispatchTableIndex][PVR_DISPATCH_OFFSET_LAST_FUNC]; - - /* bridge function is not implemented in this build */ - if (0 == ui32DispatchTableEntry) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Dispatch table entry=%d, boundary = %d, (bridge module %d, function %d)", - __func__, - ui32DispatchTableEntry, - ui32GroupBoundary, - psBridgePackageKM->ui32BridgeID, - psBridgePackageKM->ui32FunctionID)); - /* this points to DummyBW() which returns PVRSRV_ERROR_ENOTTY */ - err = g_BridgeDispatchTable[ui32DispatchTableEntry].pfFunction(ui32DispatchTableEntry, - psBridgeIn, - psBridgeOut, - psConnection); - goto return_error; - } - if ((ui32DispatchTableEntry + psBridgePackageKM->ui32FunctionID) > ui32GroupBoundary) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Dispatch table entry=%d, boundary = %d, (bridge module %d, function %d)", - __func__, - ui32DispatchTableEntry, - ui32GroupBoundary, - psBridgePackageKM->ui32BridgeID, - psBridgePackageKM->ui32FunctionID)); - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EINVAL, return_error); - } - ui32DispatchTableEntry += psBridgePackageKM->ui32FunctionID; - ui32DispatchTableEntryIndex = OSConfineArrayIndexNoSpeculation(ui32DispatchTableEntry, ui32GroupBoundary+1); - if (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT <= ui32DispatchTableEntry) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Dispatch table entry=%d, entry count = %lu," - " (bridge module %d, function %d)", __func__, - ui32DispatchTableEntry, BRIDGE_DISPATCH_TABLE_ENTRY_COUNT, - psBridgePackageKM->ui32BridgeID, - psBridgePackageKM->ui32FunctionID)); - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EINVAL, return_error); - } -#if defined(DEBUG_BRIDGE_KM) - PVR_DPF((PVR_DBG_MESSAGE, "%s: Dispatch table entry index=%d, (bridge module %d, function %d)", - __func__, - ui32DispatchTableEntryIndex, psBridgePackageKM->ui32BridgeID, psBridgePackageKM->ui32FunctionID)); - PVR_DPF((PVR_DBG_MESSAGE, "%s: %s", - __func__, - g_BridgeDispatchTable[ui32DispatchTableEntryIndex].pszIOCName)); - g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui32CallCount++; - g_BridgeGlobalStats.ui32IOCTLCount++; -#endif - - if (psBridgePackageKM->ui32InBufferSize != g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui32InBufferSize || - psBridgePackageKM->ui32OutBufferSize != g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui32OutBufferSize) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Bridge buffer sizes mismatch! " - "In: User(%u), Kernel(%u) - Out: User(%u), Kernel(%u)", - __func__, - psBridgePackageKM->ui32InBufferSize, g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui32InBufferSize, - psBridgePackageKM->ui32OutBufferSize, g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui32OutBufferSize)); - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EINVAL, return_error); - } - - if (g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock != NULL) - { - OSLockAcquire(g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock); - } -#if !defined(INTEGRITY_OS) - /* try to acquire a bridge buffer from the pool */ - - err = PVRSRVPoolGet(g_psBridgeBufferPool, - &hBridgeBufferPoolToken, - &psBridgeIn); - PVR_LOG_GOTO_IF_ERROR(err, "PVRSRVPoolGet", unlock_and_return_error); - - psBridgeOut = ((IMG_BYTE *) psBridgeIn) + PVRSRV_MAX_BRIDGE_IN_SIZE; -#endif - -#if defined(DEBUG_BRIDGE_KM) - ui64TimeStart = OSClockns64(); -#endif - -#if !defined(INTEGRITY_OS) - if ((CopyFromUserWrapper (psConnection, - ui32DispatchTableEntryIndex, - psBridgeIn, - psBridgePackageKM->pvParamIn, - psBridgePackageKM->ui32InBufferSize) != PVRSRV_OK) -#if defined(__QNXNTO__) -/* For Neutrino, the output bridge buffer acts as an input as well */ - || (CopyFromUserWrapper(psConnection, - ui32DispatchTableEntryIndex, - psBridgeOut, - (void *)((uintptr_t)psBridgePackageKM->pvParamIn + psBridgePackageKM->ui32InBufferSize), - psBridgePackageKM->ui32OutBufferSize) != PVRSRV_OK) -#endif - ) /* end of if-condition */ - { - PVR_LOG_GOTO_WITH_ERROR("CopyFromUserWrapper", err, PVRSRV_ERROR_BRIDGE_EFAULT, unlock_and_return_error); - } -#else - psBridgeIn = psBridgePackageKM->pvParamIn; - psBridgeOut = psBridgePackageKM->pvParamOut; -#endif - - pfBridgeHandler = - (BridgeWrapperFunction)g_BridgeDispatchTable[ui32DispatchTableEntryIndex].pfFunction; - - if (pfBridgeHandler == NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: ui32DispatchTableEntry = %d is not a registered function!", - __func__, ui32DispatchTableEntry)); - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EFAULT, unlock_and_return_error); - } - - /* pfBridgeHandler functions do not fail and return an IMG_INT. - * The value returned is either 0 or PVRSRV_OK (0). - * In the event this changes an error may be +ve or -ve, - * so try to return something consistent here. - */ - if (0 != pfBridgeHandler(ui32DispatchTableEntryIndex, - psBridgeIn, - psBridgeOut, - psConnection) - ) - { - PVR_LOG_GOTO_WITH_ERROR("pfBridgeHandler", err, PVRSRV_ERROR_BRIDGE_EPERM, unlock_and_return_error); - } - - /* - This should always be true as a.t.m. all bridge calls have to - return an error message, but this could change so we do this - check to be safe. - */ -#if !defined(INTEGRITY_OS) - if (psBridgePackageKM->ui32OutBufferSize > 0) - { - if (CopyToUserWrapper (psConnection, - ui32DispatchTableEntryIndex, - psBridgePackageKM->pvParamOut, - psBridgeOut, - psBridgePackageKM->ui32OutBufferSize) != PVRSRV_OK) - { - PVR_GOTO_WITH_ERROR(err, PVRSRV_ERROR_BRIDGE_EFAULT, unlock_and_return_error); - } - } -#endif - -#if defined(DEBUG_BRIDGE_KM) - ui64TimeEnd = OSClockns64(); - - ui64TimeDiff = ui64TimeEnd - ui64TimeStart; - - /* if there is no lock held then acquire the stats lock to - * ensure the calculations are done safely - */ - if (g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock == NULL) - { - BridgeGlobalStatsLock(); - } - - g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui64TotalTimeNS += ui64TimeDiff; - - if (ui64TimeDiff > g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui64MaxTimeNS) - { - g_BridgeDispatchTable[ui32DispatchTableEntryIndex].ui64MaxTimeNS = ui64TimeDiff; - } - - if (g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock == NULL) - { - BridgeGlobalStatsUnlock(); - } -#endif - -unlock_and_return_error: - - if (g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock != NULL) - { - OSLockRelease(g_BridgeDispatchTable[ui32DispatchTableEntryIndex].hBridgeLock); - } - -#if !defined(INTEGRITY_OS) - if (hBridgeBufferPoolToken != NULL) - { - err = PVRSRVPoolPut(g_psBridgeBufferPool, - hBridgeBufferPoolToken); - PVR_LOG_IF_ERROR(err, "PVRSRVPoolPut"); - } -#endif - -return_error: - if (err) - { - PVR_DPF((PVR_DBG_ERROR, "%s: returning (err = %d)", __func__, err)); - } - /* ignore transport layer bridge to avoid HTB flooding */ - if (psBridgePackageKM->ui32BridgeID != PVRSRV_BRIDGE_PVRTL) - { - if (err) - { - HTBLOGK(HTB_SF_BRG_BRIDGE_CALL_ERR, ui32Timestamp, - psBridgePackageKM->ui32BridgeID, - psBridgePackageKM->ui32FunctionID, err); - } - else - { - HTBLOGK(HTB_SF_BRG_BRIDGE_CALL, ui32Timestamp, - psBridgePackageKM->ui32BridgeID, - psBridgePackageKM->ui32FunctionID); - } - } - - return err; -} - -PVRSRV_ERROR PVRSRVFindProcessMemStatsKM(IMG_PID pid, IMG_UINT32 ui32ArrSize, IMG_BOOL bAllProcessStats, IMG_UINT32 *pui32MemStatArray) -{ -#if !defined(__QNXNTO__) - return PVRSRVFindProcessMemStats(pid, - ui32ArrSize, - bAllProcessStats, - pui32MemStatArray); -#else - PVR_DPF((PVR_DBG_ERROR, "This functionality is not yet implemented for this platform")); - - return PVRSRV_ERROR_NOT_SUPPORTED; -#endif - -} diff --git a/drivers/gpu/drm/img-rogue/1.17/srvcore.h b/drivers/gpu/drm/img-rogue/1.17/srvcore.h deleted file mode 100644 index 5bd8528f70c82..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/srvcore.h +++ /dev/null @@ -1,240 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title PVR Bridge Functionality -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header for the PVR Bridge code -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVCORE_H -#define SRVCORE_H - -#include "lock_types.h" -#include "connection_server.h" -#include "pvr_debug.h" - -#include "pvr_bridge.h" -#if defined(SUPPORT_RGX) -#include "rgx_bridge.h" -#endif - -PVRSRV_ERROR -CopyFromUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void *pvDest, - void __user *pvSrc, - IMG_UINT32 ui32Size); -PVRSRV_ERROR -CopyToUserWrapper(CONNECTION_DATA *psConnection, - IMG_UINT32 ui32DispatchTableEntry, - void __user *pvDest, - void *pvSrc, - IMG_UINT32 ui32Size); - -IMG_INT -DummyBW(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 *psBridgeIn, - IMG_UINT8 *psBridgeOut, - CONNECTION_DATA *psConnection); - -typedef PVRSRV_ERROR (*ServerResourceDestroyFunction)(IMG_HANDLE, IMG_HANDLE); - -typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32DispatchTableEntry, - IMG_UINT8 *psBridgeIn, - IMG_UINT8 *psBridgeOut, - CONNECTION_DATA *psConnection); - -typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY -{ - BridgeWrapperFunction pfFunction; /*!< The wrapper function that validates the ioctl - arguments before calling into srvkm proper */ - POS_LOCK hBridgeLock; /*!< The bridge lock which needs to be acquired - before calling the above wrapper */ - - IMG_UINT32 ui32InBufferSize; /*!< The expected size of the in buffer given by the client */ - IMG_UINT32 ui32OutBufferSize; /*!< The expected size of the out buffer given by the client */ - -#if defined(DEBUG_BRIDGE_KM) - const IMG_CHAR *pszIOCName; /*!< Name of the ioctl: e.g. "PVRSRV_BRIDGE_CONNECT_SERVICES" */ - const IMG_CHAR *pszFunctionName; /*!< Name of the wrapper function: e.g. "PVRSRVConnectBW" */ - const IMG_CHAR *pszBridgeLockName; /*!< Name of bridge lock which will be acquired */ - IMG_UINT32 ui32CallCount; /*!< The total number of times the ioctl has been called */ - IMG_UINT32 ui32CopyFromUserTotalBytes; /*!< The total number of bytes copied from - userspace within this ioctl */ - IMG_UINT32 ui32CopyToUserTotalBytes; /*!< The total number of bytes copied from - userspace within this ioctl */ - IMG_UINT64 ui64TotalTimeNS; /*!< The total amount of time spent in this bridge function */ - IMG_UINT64 ui64MaxTimeNS; /*!< The maximum amount of time for a single call to this bridge function */ -#endif -}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY; - -#if defined(SUPPORT_RGX) - #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_RGX_DISPATCH_LAST+1) - #define BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT (PVRSRV_BRIDGE_RGX_LAST+1) -#else - #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_DISPATCH_LAST+1) - #define BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT (PVRSRV_BRIDGE_LAST+1) -#endif - -extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; - -void BridgeDispatchTableStartOffsetsInit(void); - -void -_SetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup, - IMG_UINT32 ui32Index, - const IMG_CHAR *pszIOCName, - BridgeWrapperFunction pfFunction, - const IMG_CHAR *pszFunctionName, - POS_LOCK hBridgeLock, - const IMG_CHAR* pszBridgeLockName, - IMG_UINT32 ui32InBufferSize, - IMG_UINT32 ui32OutBufferSize); -void -UnsetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup, - IMG_UINT32 ui32Index); - - -/* PRQA S 0884,3410 2*/ /* macro relies on the lack of brackets */ -#define SetDispatchTableEntry(ui32BridgeGroup, ui32Index, pfFunction,\ - hBridgeLock, ui32InBufferSize, ui32OutBufferSize) \ - do \ - { \ - static_assert((ui32InBufferSize) <= PVRSRV_MAX_BRIDGE_IN_SIZE, "Bridge input buffer is too small for bridge function: " #pfFunction); \ - static_assert((ui32OutBufferSize) <= PVRSRV_MAX_BRIDGE_OUT_SIZE, "Bridge output buffer is too small for bridge function: " #pfFunction); \ - _SetDispatchTableEntry(ui32BridgeGroup, ui32Index, #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction,\ - (POS_LOCK)hBridgeLock, #hBridgeLock, ui32InBufferSize, ui32OutBufferSize); \ - } while(0) - -#define DISPATCH_TABLE_GAP_THRESHOLD 5 - - -#if defined(DEBUG_BRIDGE_KM) -typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS -{ - IMG_UINT32 ui32IOCTLCount; - IMG_UINT32 ui32TotalCopyFromUserBytes; - IMG_UINT32 ui32TotalCopyToUserBytes; -} PVRSRV_BRIDGE_GLOBAL_STATS; - -void BridgeGlobalStatsLock(void); -void BridgeGlobalStatsUnlock(void); - -/* OS specific code may want to report the stats held here and within the - * BRIDGE_DISPATCH_TABLE_ENTRYs (E.g. on Linux we report these via a - * debugfs entry /(sys/kernel/debug|proc)/pvr/bridge_stats) */ -extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; -#endif - -PVRSRV_ERROR BridgeDispatcherInit(void); -void BridgeDispatcherDeinit(void); - -PVRSRV_ERROR -BridgedDispatchKM(CONNECTION_DATA * psConnection, - PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM); - -PVRSRV_ERROR -PVRSRVConnectKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32Flags, - IMG_UINT32 ui32ClientBuildOptions, - IMG_UINT32 ui32ClientDDKVersion, - IMG_UINT32 ui32ClientDDKBuild, - IMG_UINT8 *pui8KernelArch, - IMG_UINT32 *ui32CapabilityFlags, - IMG_UINT64 *ui64PackedBvnc); - -PVRSRV_ERROR -PVRSRVDisconnectKM(void); - -PVRSRV_ERROR -PVRSRVAcquireGlobalEventObjectKM(IMG_HANDLE *phGlobalEventObject); - -PVRSRV_ERROR -PVRSRVReleaseGlobalEventObjectKM(IMG_HANDLE hGlobalEventObject); - -PVRSRV_ERROR -PVRSRVDumpDebugInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32VerbLevel); - -PVRSRV_ERROR -PVRSRVGetDevClockSpeedKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_PUINT32 pui32RGXClockSpeed); - -PVRSRV_ERROR -PVRSRVHWOpTimeoutKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode); - -PVRSRV_ERROR PVRSRVAlignmentCheckKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDeviceNode, - IMG_UINT32 ui32FWAlignChecksSize, - IMG_UINT32 aui32FWAlignChecks[]); - -PVRSRV_ERROR PVRSRVGetDeviceStatusKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 *pui32DeviceStatus); - -PVRSRV_ERROR PVRSRVGetMultiCoreInfoKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32CapsSize, - IMG_UINT32 *pui32NumCores, - IMG_UINT64 *pui64Caps); - -PVRSRV_ERROR PVRSRVFindProcessMemStatsKM(IMG_PID pid, - IMG_UINT32 ui32ArrSize, - IMG_BOOL bAllProcessStats, - IMG_UINT32 *ui32MemoryStats); - -static INLINE -PVRSRV_ERROR DestroyServerResource(const SHARED_DEV_CONNECTION hConnection, - IMG_HANDLE hEvent, - ServerResourceDestroyFunction pfnDestroyCall, - IMG_HANDLE hResource) -{ - PVR_UNREFERENCED_PARAMETER(hEvent); - - return pfnDestroyCall(GetBridgeHandle(hConnection), hResource); -} - -#endif /* SRVCORE_H */ - -/****************************************************************************** - End of file (srvcore.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/srvinit.h b/drivers/gpu/drm/img-rogue/1.17/srvinit.h deleted file mode 100644 index 48e6863eae1ff..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/srvinit.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Initialisation server internal header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the connections between the various parts of the - initialisation server. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVINIT_H -#define SRVINIT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "device_connection.h" -#include "device.h" - -#if defined(SUPPORT_RGX) -PVRSRV_ERROR RGXInit(PVRSRV_DEVICE_NODE *psDeviceNode); -#endif - -#if defined(__cplusplus) -} -#endif -#endif /* SRVINIT_H */ - -/****************************************************************************** - End of file (srvinit.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/srvkm.h b/drivers/gpu/drm/img-rogue/1.17/srvkm.h deleted file mode 100644 index 1ca4ee807a0a8..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/srvkm.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Services kernel module internal header file -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SRVKM_H -#define SRVKM_H - -#include "servicesext.h" - -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - -struct _PVRSRV_DEVICE_NODE_; - -/*************************************************************************/ /*! -@Function PVRSRVCommonDriverInit -@Description Performs one time driver initialisation of Services Common and - Device layers. -@Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVCommonDriverInit(void); - -/*************************************************************************/ /*! -@Function PVRSRVCommonDriverInit -@Description Performs one time driver de-initialisation of Services. -@Return void -*/ /**************************************************************************/ -void PVRSRVCommonDriverDeInit(void); - -/*************************************************************************/ /*! -@Function PVRSRVCommonDeviceCreate -@Description Creates and initialises a common layer Services device node - for an OS native device. First stage device discovery. -@Input pvOSDevice OS native device -@Input i32OsDeviceID A unique identifier which helps recognise this - Device in the UM space provided by the OS. -@Output ppsDeviceNode Points to the new device node on success -@Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVCommonDeviceCreate(void *pvOSDevice, IMG_INT32 i32OsDeviceID, - struct _PVRSRV_DEVICE_NODE_ **ppsDeviceNode); - -/*************************************************************************/ /*! -@Function PVRSRVCommonDeviceInitialise -@Description Initialises the device layer specifics (e.g. boot FW etc) - for the supplied device node, created previously by - PVRSRVCommonDeviceCreate. The device is ready for use when this - second stage device initialisation returns successfully. -@Input psDeviceNode Device node of the device to be initialised -@Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR PVRSRVCommonDeviceInitialise(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); - -/*************************************************************************/ /*! -@Function PVRSRVCommonDeviceDestroy -@Description Destroys a PVR Services device node. -@Input psDeviceNode Device node to destroy -@Return PVRSRV_ERROR PVRSRV_OK on success and an error otherwise -*/ /**************************************************************************/ -PVRSRV_ERROR -PVRSRVCommonDeviceDestroy(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); - -/****************** -HIGHER LEVEL MACROS -*******************/ - -/*---------------------------------------------------------------------------- -Repeats the body of the loop for a certain minimum time, or until the body -exits by its own means (break, return, goto, etc.) - -Example of usage: - -LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -{ - if (psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset) - { - bTimeout = IMG_FALSE; - break; - } - - OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); -} END_LOOP_UNTIL_TIMEOUT(); - ------------------------------------------------------------------------------*/ - -/* uiNotLastLoop will remain at 1 until the timeout has expired, at which time - * it will be decremented and the loop executed one final time. This is - * necessary when preemption is enabled. - */ -/* PRQA S 3411,3431 12 */ /* critical format, leave alone */ -#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \ -{\ - IMG_UINT32 uiOffset, uiStart, uiCurrent; \ - IMG_INT32 iNotLastLoop; \ - for (uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\ - ((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--; \ - uiCurrent = OSClockus(), \ - uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \ - uiStart = uiCurrent < uiStart ? 0 : uiStart) - -#define END_LOOP_UNTIL_TIMEOUT() \ -} - -#endif /* SRVKM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync.c b/drivers/gpu/drm/img-rogue/1.17/sync.c deleted file mode 100644 index 36234ae5ee57c..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync.c +++ /dev/null @@ -1,907 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services synchronisation interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements client side code for services synchronisation - interface -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "client_sync_bridge.h" -#include "client_synctracking_bridge.h" -#include "info_page_client.h" -#include "pvr_bridge.h" -#include "allocmem.h" -#include "osfunc.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "pvr_debug.h" -#include "dllist.h" -#include "sync.h" -#include "sync_internal.h" -#include "lock.h" -#include "log2.h" -#if defined(__KERNEL__) -#include "pvrsrv.h" -#include "srvcore.h" -#else -#include "srvcore_intern.h" -#endif - - -#define SYNC_BLOCK_LIST_CHUNCK_SIZE 10 - -/* - This defines the maximum amount of synchronisation memory - that can be allocated per SyncPrim context. - In reality this number is meaningless as we would run out - of synchronisation memory before we reach this limit, but - we need to provide a size to the span RA. - */ -#define MAX_SYNC_MEM (4 * 1024 * 1024) - -/* forward declaration */ -static PVRSRV_ERROR -_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value); - -/* - Internal interfaces for management of SYNC_PRIM_CONTEXT - */ -static void -_SyncPrimContextUnref(SYNC_PRIM_CONTEXT *psContext) -{ - if (!OSAtomicRead(&psContext->hRefCount)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: context already freed", __func__)); - } - else if (0 == OSAtomicDecrement(&psContext->hRefCount)) - { - /* SyncPrimContextDestroy only when no longer referenced */ - RA_Delete(psContext->psSpanRA); - RA_Delete(psContext->psSubAllocRA); - OSFreeMem(psContext); - } -} - -static void -_SyncPrimContextRef(SYNC_PRIM_CONTEXT *psContext) -{ - if (!OSAtomicRead(&psContext->hRefCount)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: context use after free", __func__)); - } - else - { - OSAtomicIncrement(&psContext->hRefCount); - } -} - -/* - Internal interfaces for management of synchronisation block memory - */ -static PVRSRV_ERROR -AllocSyncPrimitiveBlock(SYNC_PRIM_CONTEXT *psContext, - SYNC_PRIM_BLOCK **ppsSyncBlock) -{ - SYNC_PRIM_BLOCK *psSyncBlk; - IMG_HANDLE hSyncPMR; - IMG_HANDLE hSyncImportHandle; - IMG_DEVMEM_SIZE_T uiImportSize; - PVRSRV_ERROR eError; - - psSyncBlk = OSAllocMem(sizeof(SYNC_PRIM_BLOCK)); - PVR_GOTO_IF_NOMEM(psSyncBlk, eError, fail_alloc); - - psSyncBlk->psContext = psContext; - - /* Allocate sync prim block */ - eError = BridgeAllocSyncPrimitiveBlock(GetBridgeHandle(psContext->hDevConnection), - &psSyncBlk->hServerSyncPrimBlock, - &psSyncBlk->ui32FirmwareAddr, - &psSyncBlk->ui32SyncBlockSize, - &hSyncPMR); - PVR_GOTO_IF_ERROR(eError, fail_blockalloc); - - /* Make it mappable by the client */ - eError = DevmemMakeLocalImportHandle(psContext->hDevConnection, - hSyncPMR, - &hSyncImportHandle); - PVR_GOTO_IF_ERROR(eError, fail_export); - - /* Get CPU mapping of the memory block */ - eError = DevmemLocalImport(psContext->hDevConnection, - hSyncImportHandle, - PVRSRV_MEMALLOCFLAG_CPU_READABLE, - &psSyncBlk->hMemDesc, - &uiImportSize, - "SyncPrimitiveBlock"); - - /* - Regardless of success or failure we "undo" the export - */ - DevmemUnmakeLocalImportHandle(psContext->hDevConnection, - hSyncImportHandle); - - PVR_GOTO_IF_ERROR(eError, fail_import); - - eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc, - (void **) &psSyncBlk->pui32LinAddr); - PVR_GOTO_IF_ERROR(eError, fail_cpuvaddr); - - *ppsSyncBlock = psSyncBlk; - return PVRSRV_OK; - -fail_cpuvaddr: - DevmemFree(psSyncBlk->hMemDesc); -fail_import: -fail_export: - BridgeFreeSyncPrimitiveBlock(GetBridgeHandle(psContext->hDevConnection), - psSyncBlk->hServerSyncPrimBlock); -fail_blockalloc: - OSFreeMem(psSyncBlk); -fail_alloc: - return eError; -} - -static void -FreeSyncPrimitiveBlock(SYNC_PRIM_BLOCK *psSyncBlk) -{ - SYNC_PRIM_CONTEXT *psContext = psSyncBlk->psContext; - - DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc); - DevmemFree(psSyncBlk->hMemDesc); - (void) DestroyServerResource(psContext->hDevConnection, - NULL, - BridgeFreeSyncPrimitiveBlock, - psSyncBlk->hServerSyncPrimBlock); - OSFreeMem(psSyncBlk); -} - -static PVRSRV_ERROR -SyncPrimBlockImport(RA_PERARENA_HANDLE hArena, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *puiBase, - RA_LENGTH_T *puiActualSize, - RA_PERISPAN_HANDLE *phImport) -{ - SYNC_PRIM_CONTEXT *psContext = hArena; - SYNC_PRIM_BLOCK *psSyncBlock = NULL; - RA_LENGTH_T uiSpanSize; - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(uFlags); - - /* Check we've not been called with an unexpected size */ - PVR_LOG_GOTO_IF_INVALID_PARAM(hArena, eError, e0); - PVR_LOG_GOTO_IF_INVALID_PARAM(uSize == sizeof(IMG_UINT32), eError, e0); - - /* - Ensure the synprim context doesn't go away while we have sync blocks - attached to it - */ - _SyncPrimContextRef(psContext); - - /* Allocate the block of memory */ - eError = AllocSyncPrimitiveBlock(psContext, &psSyncBlock); - PVR_LOG_GOTO_IF_ERROR(eError, "AllocSyncPrimitiveBlock", fail_syncblockalloc); - - /* Allocate a span for it */ - eError = RA_Alloc(psContext->psSpanRA, - psSyncBlock->ui32SyncBlockSize, - RA_NO_IMPORT_MULTIPLIER, - 0, - psSyncBlock->ui32SyncBlockSize, - pszAnnotation, - &psSyncBlock->uiSpanBase, - &uiSpanSize, - NULL); - PVR_GOTO_IF_ERROR(eError, fail_spanalloc); - - /* - There is no reason the span RA should return an allocation larger - then we request - */ - PVR_ASSERT(uiSpanSize == psSyncBlock->ui32SyncBlockSize); - - *puiBase = psSyncBlock->uiSpanBase; - *puiActualSize = psSyncBlock->ui32SyncBlockSize; - *phImport = psSyncBlock; - return PVRSRV_OK; - -fail_spanalloc: - FreeSyncPrimitiveBlock(psSyncBlock); -fail_syncblockalloc: - _SyncPrimContextUnref(psContext); -e0: - return eError; -} - -static void -SyncPrimBlockUnimport(RA_PERARENA_HANDLE hArena, - RA_BASE_T uiBase, - RA_PERISPAN_HANDLE hImport) -{ - SYNC_PRIM_CONTEXT *psContext = hArena; - SYNC_PRIM_BLOCK *psSyncBlock = hImport; - - if (!psContext || !psSyncBlock || uiBase != psSyncBlock->uiSpanBase) - { - /* Invalid input params */ - return; - } - - /* Free the span this import is using */ - RA_Free(psContext->psSpanRA, uiBase); - - /* Free the syncpim block */ - FreeSyncPrimitiveBlock(psSyncBlock); - - /* Drop our reference to the syncprim context */ - _SyncPrimContextUnref(psContext); -} - -static INLINE IMG_UINT32 SyncPrimGetOffset(SYNC_PRIM *psSyncInt) -{ - IMG_UINT64 ui64Temp; - - PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL); - - ui64Temp = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase; - PVR_ASSERT(ui64Tempu.sLocal.psSyncBlock; - - psSyncInt->sCommon.pui32LinAddr = psSyncBlock->pui32LinAddr + - (SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32)); -} - -static void SyncPrimLocalFree(SYNC_PRIM *psSyncInt, IMG_BOOL bFreeFirstSyncPrim) -{ - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - -#if !defined(LOCAL_SYNC_BLOCK_RETAIN_FIRST) - PVR_UNREFERENCED_PARAMETER(bFreeFirstSyncPrim); -#else - /* Defer freeing the first allocated sync prim in the sync context */ - if (psSyncInt != psContext->hFirstSyncPrim || (psSyncInt == psContext->hFirstSyncPrim && bFreeFirstSyncPrim)) -#endif - { - PVRSRV_ERROR eError; - SHARED_DEV_CONNECTION hDevConnection = - psSyncInt->u.sLocal.psSyncBlock->psContext->hDevConnection; - - if (GetInfoPageDebugFlags(hDevConnection) & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - if (psSyncInt->u.sLocal.hRecord) - { - /* remove this sync record */ - eError = DestroyServerResource(hDevConnection, - NULL, - BridgeSyncRecordRemoveByHandle, - psSyncInt->u.sLocal.hRecord); - PVR_LOG_IF_ERROR(eError, "BridgeSyncRecordRemoveByHandle"); - } - } - else - { - IMG_UINT32 ui32FWAddr = psSyncBlock->ui32FirmwareAddr + - SyncPrimGetOffset(psSyncInt); - - eError = BridgeSyncFreeEvent(GetBridgeHandle(hDevConnection), ui32FWAddr); - PVR_LOG_IF_ERROR(eError, "BridgeSyncFreeEvent"); - } -#if defined(PVRSRV_ENABLE_SYNC_POISONING) - (void) _SyncPrimSetValue(psSyncInt, LOCAL_SYNC_PRIM_POISON_VALUE); -#else - /* reset the sync prim value as it is freed. - * this guarantees the client sync allocated to the client will - * have a value of zero and the client does not need to - * explicitly initialise the sync value to zero. - * the allocation of the backing memory for the sync prim block - * is done with ZERO_ON_ALLOC so the memory is initially all zero. - */ - (void) _SyncPrimSetValue(psSyncInt, LOCAL_SYNC_PRIM_RESET_VALUE); -#endif - - RA_Free(psContext->psSubAllocRA, psSyncInt->u.sLocal.uiSpanAddr); - OSFreeMem(psSyncInt); - _SyncPrimContextUnref(psContext); - } -} - -static void SyncPrimLocalUnref(SYNC_PRIM *psSyncInt) -{ - if (!OSAtomicRead(&psSyncInt->u.sLocal.hRefCount)) - { - PVR_DPF((PVR_DBG_ERROR, "SyncPrimLocalUnref sync already freed")); - } - else if (0 == OSAtomicDecrement(&psSyncInt->u.sLocal.hRefCount)) - { - SyncPrimLocalFree(psSyncInt, IMG_FALSE); - } -} - -static IMG_UINT32 SyncPrimGetFirmwareAddrLocal(SYNC_PRIM *psSyncInt) -{ - SYNC_PRIM_BLOCK *psSyncBlock; - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - return psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psSyncInt); -} - -static INLINE IMG_UINT32 _Log2(IMG_UINT32 ui32Align) -{ - PVR_ASSERT(IsPower2(ui32Align)); - return ExactLog2(ui32Align); -} - -/* - External interfaces - */ - -IMG_INTERNAL PVRSRV_ERROR -SyncPrimContextCreate(SHARED_DEV_CONNECTION hDevConnection, - PSYNC_PRIM_CONTEXT *phSyncPrimContext) -{ - SYNC_PRIM_CONTEXT *psContext; - PVRSRV_ERROR eError; - - psContext = OSAllocMem(sizeof(SYNC_PRIM_CONTEXT)); - PVR_GOTO_IF_NOMEM(psContext, eError, fail_alloc); - - psContext->hDevConnection = hDevConnection; - - OSSNPrintf(psContext->azName, SYNC_PRIM_NAME_SIZE, "Sync Prim RA-%p", psContext); - OSSNPrintf(psContext->azSpanName, SYNC_PRIM_NAME_SIZE, "Sync Prim span RA-%p", psContext); - - /* - Create the RA for sub-allocations of the SynPrim's - - Note: - The import size doesn't matter here as the server will pass - back the blocksize when does the import which overrides - what we specify here. - */ - - psContext->psSubAllocRA = RA_Create(psContext->azName, - /* Params for imports */ - _Log2(sizeof(IMG_UINT32)), - RA_LOCKCLASS_2, - SyncPrimBlockImport, - SyncPrimBlockUnimport, - psContext, - RA_POLICY_DEFAULT); - PVR_GOTO_IF_NOMEM(psContext->psSubAllocRA, eError, fail_suballoc); - - /* - Create the span-management RA - - The RA requires that we work with linear spans. For our use - here we don't require this behaviour as we're always working - within offsets of blocks (imports). However, we need to keep - the RA happy so we create the "span" management RA which - ensures that all are imports are added to the RA in a linear - fashion - */ - psContext->psSpanRA = RA_Create(psContext->azSpanName, - /* Params for imports */ - 0, - RA_LOCKCLASS_1, - NULL, - NULL, - NULL, - RA_POLICY_DEFAULT); - PVR_GOTO_IF_NOMEM(psContext->psSpanRA, eError, fail_span); - - if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_MEM, 0, NULL)) - { - RA_Delete(psContext->psSpanRA); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, fail_span); - } - -#if defined(LOCAL_SYNC_BLOCK_RETAIN_FIRST) - psContext->hFirstSyncPrim = NULL; -#endif - - OSAtomicWrite(&psContext->hRefCount, 1); - - *phSyncPrimContext = psContext; - return PVRSRV_OK; -fail_span: - RA_Delete(psContext->psSubAllocRA); -fail_suballoc: - OSFreeMem(psContext); -fail_alloc: - return eError; -} - -IMG_INTERNAL void SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext) -{ - SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext; - -#if defined(LOCAL_SYNC_BLOCK_RETAIN_FIRST) - /* Free the first sync prim that was allocated as part of this context */ - if (psContext->hFirstSyncPrim) - { - SyncPrimLocalFree((SYNC_PRIM *)psContext->hFirstSyncPrim, IMG_TRUE); - psContext->hFirstSyncPrim = NULL; - } -#endif - - if (1 != OSAtomicRead(&psContext->hRefCount)) - { - PVR_DPF((PVR_DBG_ERROR, "%s attempted with active references, may be the result of a race", __func__)); - } -#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE) -#if defined(__KERNEL__) - if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Forcing context destruction due to bad driver state", __func__)); - OSAtomicWrite(&psContext->hRefCount, 1); - } -#endif -#endif - _SyncPrimContextUnref(psContext); -} - -static PVRSRV_ERROR _SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext, - PVRSRV_CLIENT_SYNC_PRIM **ppsSync, - const IMG_CHAR *pszClassName, - IMG_BOOL bServerSync) -{ - SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext; - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM *psNewSync; - PVRSRV_ERROR eError; - RA_BASE_T uiSpanAddr; - - PVR_LOG_RETURN_IF_INVALID_PARAM(hSyncPrimContext, "hSyncPrimeContext"); - - psNewSync = OSAllocMem(sizeof(SYNC_PRIM)); - PVR_GOTO_IF_NOMEM(psNewSync, eError, fail_alloc); - - eError = RA_Alloc(psContext->psSubAllocRA, - sizeof(IMG_UINT32), - RA_NO_IMPORT_MULTIPLIER, - 0, - sizeof(IMG_UINT32), - "Sync_Prim", - &uiSpanAddr, - NULL, - (RA_PERISPAN_HANDLE *) &psSyncBlock); - PVR_GOTO_IF_ERROR(eError, fail_raalloc); - - psNewSync->eType = SYNC_PRIM_TYPE_LOCAL; - OSAtomicWrite(&psNewSync->u.sLocal.hRefCount, 1); - psNewSync->u.sLocal.uiSpanAddr = uiSpanAddr; - psNewSync->u.sLocal.psSyncBlock = psSyncBlock; - SyncPrimGetCPULinAddr(psNewSync); - *ppsSync = &psNewSync->sCommon; - _SyncPrimContextRef(psContext); -#if defined(PVRSRV_ENABLE_SYNC_POISONING) - (void) _SyncPrimSetValue(psNewSync, LOCAL_SYNC_PRIM_RESET_VALUE); -#endif - -#if defined(LOCAL_SYNC_BLOCK_RETAIN_FIRST) - /* If this is the first sync prim allocated in the context, keep a handle to it */ - if (psSyncBlock->uiSpanBase == 0 && psNewSync->u.sLocal.uiSpanAddr == 0) - { - psContext->hFirstSyncPrim = psNewSync; - } -#endif - - if (GetInfoPageDebugFlags(psSyncBlock->psContext->hDevConnection) & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - IMG_CHAR szClassName[PVRSRV_SYNC_NAME_LENGTH]; - size_t uiSize; - - if (pszClassName) - { - uiSize = OSStringNLength(pszClassName, PVRSRV_SYNC_NAME_LENGTH); - /* Copy the class name annotation into a fixed-size array */ - OSCachedMemCopy(szClassName, pszClassName, uiSize); - if (uiSize == PVRSRV_SYNC_NAME_LENGTH) - szClassName[PVRSRV_SYNC_NAME_LENGTH-1] = '\0'; - else - szClassName[uiSize++] = '\0'; - } - else - { - /* No class name annotation */ - uiSize = 0; - szClassName[0] = '\0'; - } - - /* record this sync */ - eError = BridgeSyncRecordAdd( - GetBridgeHandle(psSyncBlock->psContext->hDevConnection), - &psNewSync->u.sLocal.hRecord, - psSyncBlock->hServerSyncPrimBlock, - psSyncBlock->ui32FirmwareAddr, - SyncPrimGetOffset(psNewSync), - bServerSync, - uiSize, - szClassName); - if (PVRSRV_OK != eError) - { - PVR_DPF((PVR_DBG_ERROR, "%s: failed to add SyncRecord \"%s\" (%s)", - __func__, - szClassName, - PVRSRVGETERRORSTRING(eError))); - psNewSync->u.sLocal.hRecord = NULL; - } - } - else - { - size_t uiSize; - - uiSize = OSStringNLength(pszClassName, PVRSRV_SYNC_NAME_LENGTH); - - if (uiSize < PVRSRV_SYNC_NAME_LENGTH) - uiSize++; - /* uiSize now reflects size used for pszClassName + NUL byte */ - - eError = BridgeSyncAllocEvent(GetBridgeHandle(hSyncPrimContext->hDevConnection), - bServerSync, - psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psNewSync), - uiSize, - pszClassName); - PVR_LOG_IF_ERROR(eError, "BridgeSyncAllocEvent"); - } - - return PVRSRV_OK; - -fail_raalloc: - OSFreeMem(psNewSync); -fail_alloc: - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext, - PVRSRV_CLIENT_SYNC_PRIM **ppsSync, - const IMG_CHAR *pszClassName) -{ - return _SyncPrimAlloc(hSyncPrimContext, - ppsSync, - pszClassName, - IMG_FALSE); -} - -static PVRSRV_ERROR -_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eError; - - if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL) - { - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - - eError = BridgeSyncPrimSet(GetBridgeHandle(psContext->hDevConnection), - psSyncBlock->hServerSyncPrimBlock, - SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32), - ui32Value); - } - else - { - /* Server sync not supported, attempted use of server sync */ - return PVRSRV_ERROR_NOT_SUPPORTED; - } - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYNC_PRIM *psSyncInt; - - PVR_LOG_GOTO_IF_INVALID_PARAM(psSync, eError, err_out); - - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL) - { - SyncPrimLocalUnref(psSyncInt); - } - else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER) - { - /* Server sync not supported, attempted use of server sync */ - return PVRSRV_ERROR_NOT_SUPPORTED; - } - else - { - /* - Either the client has given us a bad pointer or there is an - error in this module - */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_SYNC_PRIM, err_out); - } - -err_out: - return eError; -} - -#if defined(NO_HARDWARE) -IMG_INTERNAL PVRSRV_ERROR -SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYNC_PRIM *psSyncInt; - - PVR_LOG_GOTO_IF_INVALID_PARAM(psSync, eError, err_out); - - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - /* There is no check for the psSyncInt to be LOCAL as this call - substitutes the Firmware updating a sync and that sync could - be a server one */ - - eError = _SyncPrimSetValue(psSyncInt, ui32Value); - -err_out: - return eError; -} -#endif - -IMG_INTERNAL PVRSRV_ERROR -SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYNC_PRIM *psSyncInt; - - PVR_LOG_GOTO_IF_INVALID_PARAM(psSync, eError, err_out); - - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL) - { - /* Invalid sync type */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_SYNC_PRIM, err_out); - } - - eError = _SyncPrimSetValue(psSyncInt, ui32Value); - -#if defined(PDUMP) - SyncPrimPDump(psSync); -#endif -err_out: - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_HANDLE *phBlock, - IMG_UINT32 *pui32Offset) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYNC_PRIM *psSyncInt; - - PVR_LOG_GOTO_IF_INVALID_PARAM(psSync, eError, err_out); - PVR_LOG_GOTO_IF_INVALID_PARAM(phBlock, eError, err_out); - PVR_LOG_GOTO_IF_INVALID_PARAM(pui32Offset, eError, err_out); - - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - if (likely(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)) - { - *phBlock = psSyncInt->u.sLocal.psSyncBlock->hServerSyncPrimBlock; - *pui32Offset = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: psSync not a Local sync prim (%d)", - __func__, psSyncInt->eType)); - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, err_out); - } - -err_out: - return eError; -} - -IMG_INTERNAL PVRSRV_ERROR -SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 *pui32FwAddr) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYNC_PRIM *psSyncInt; - - *pui32FwAddr = 0; - PVR_LOG_GOTO_IF_INVALID_PARAM(psSync, eError, err_out); - - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL) - { - *pui32FwAddr = SyncPrimGetFirmwareAddrLocal(psSyncInt); - } - else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER) - { - /* Server sync not supported, attempted use of server sync */ - return PVRSRV_ERROR_NOT_SUPPORTED; - } - else - { - /* Either the client has given us a bad pointer or there is an - * error in this module - */ - PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_SYNC_PRIM, err_out); - } - -err_out: - return eError; -} - -#if defined(PDUMP) -IMG_INTERNAL void SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync) -{ - SYNC_PRIM *psSyncInt; - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - PVRSRV_ERROR eError; - - PVR_ASSERT(psSync != NULL); - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL) - { - /* Invalid sync type */ - PVR_ASSERT(IMG_FALSE); - return; - } - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - - eError = BridgeSyncPrimPDump(GetBridgeHandle(psContext->hDevConnection), - psSyncBlock->hServerSyncPrimBlock, - SyncPrimGetOffset(psSyncInt)); - PVR_LOG_IF_ERROR(eError, "BridgeSyncPrimPDump"); - PVR_ASSERT(eError == PVRSRV_OK); -} - -IMG_INTERNAL void SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value) -{ - SYNC_PRIM *psSyncInt; - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - PVRSRV_ERROR eError; - - PVR_ASSERT(psSync != NULL); - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL) - { - /* Invalid sync type */ - PVR_ASSERT(IMG_FALSE); - return; - } - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - - eError = BridgeSyncPrimPDumpValue(GetBridgeHandle(psContext->hDevConnection), - psSyncBlock->hServerSyncPrimBlock, - SyncPrimGetOffset(psSyncInt), - ui32Value); - PVR_LOG_IF_ERROR(eError, "BridgeSyncPrimPDumpValue"); - PVR_ASSERT(eError == PVRSRV_OK); -} - -IMG_INTERNAL void SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags) -{ - SYNC_PRIM *psSyncInt; - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - PVRSRV_ERROR eError; - - PVR_ASSERT(psSync != NULL); - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL) - { - /* Invalid sync type */ - PVR_ASSERT(IMG_FALSE); - return; - } - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - - eError = BridgeSyncPrimPDumpPol(GetBridgeHandle(psContext->hDevConnection), - psSyncBlock->hServerSyncPrimBlock, - SyncPrimGetOffset(psSyncInt), - ui32Value, - ui32Mask, - eOperator, - ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "BridgeSyncPrimPDumpPol"); - PVR_ASSERT(eError == PVRSRV_OK); -} - -IMG_INTERNAL void SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT64 uiWriteOffset, - IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize) -{ - SYNC_PRIM *psSyncInt; - SYNC_PRIM_BLOCK *psSyncBlock; - SYNC_PRIM_CONTEXT *psContext; - PVRSRV_ERROR eError; - - PVR_ASSERT(psSync != NULL); - psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); - - if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL) - { - /* Invalid sync type */ - PVR_ASSERT(IMG_FALSE); - return; - } - - psSyncBlock = psSyncInt->u.sLocal.psSyncBlock; - psContext = psSyncBlock->psContext; - -#if defined(__linux__) && defined(__i386__) - PVR_ASSERT(uiWriteOffsethDevConnection), - psSyncBlock->hServerSyncPrimBlock, - SyncPrimGetOffset(psSyncInt), - TRUNCATE_64BITS_TO_32BITS(uiWriteOffset), - TRUNCATE_64BITS_TO_32BITS(uiPacketSize), - TRUNCATE_64BITS_TO_32BITS(uiBufferSize)); - PVR_LOG_IF_ERROR(eError, "BridgeSyncPrimPDumpCBP"); - PVR_ASSERT(eError == PVRSRV_OK); -} - -#endif diff --git a/drivers/gpu/drm/img-rogue/1.17/sync.h b/drivers/gpu/drm/img-rogue/1.17/sync.h deleted file mode 100644 index f126915060f4f..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync.h +++ /dev/null @@ -1,292 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Synchronisation interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the client side interface for synchronisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_H -#define SYNC_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "sync_prim_internal.h" -#include "pdumpdefs.h" -#include "dllist.h" -#include "pvr_debug.h" - -#include "device_connection.h" - -#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__) -#define __pvrsrv_defined_struct_enum__ -#include -#endif - -/*************************************************************************/ /*! -@Function SyncPrimContextCreate - -@Description Create a new synchronisation context - -@Input hBridge Bridge handle - -@Input hDeviceNode Device node handle - -@Output hSyncPrimContext Handle to the created synchronisation - primitive context - -@Return PVRSRV_OK if the synchronisation primitive context was - successfully created -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncPrimContextCreate(SHARED_DEV_CONNECTION hDevConnection, - PSYNC_PRIM_CONTEXT *hSyncPrimContext); - -/*************************************************************************/ /*! -@Function SyncPrimContextDestroy - -@Description Destroy a synchronisation context - -@Input hSyncPrimContext Handle to the synchronisation - primitive context to destroy - -@Return None -*/ -/*****************************************************************************/ -void -SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext); - -/*************************************************************************/ /*! -@Function SyncPrimAlloc - -@Description Allocate a new synchronisation primitive on the specified - synchronisation context - -@Input hSyncPrimContext Handle to the synchronisation - primitive context - -@Output ppsSync Created synchronisation primitive - -@Input pszClassName Sync source annotation - -@Return PVRSRV_OK if the synchronisation primitive was - successfully created -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext, - PVRSRV_CLIENT_SYNC_PRIM **ppsSync, - const IMG_CHAR *pszClassName); - -/*************************************************************************/ /*! -@Function SyncPrimFree - -@Description Free a synchronisation primitive - -@Input psSync The synchronisation primitive to free - -@Return PVRSRV_OK if the synchronisation primitive was - successfully freed -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync); - -/*************************************************************************/ /*! -@Function SyncPrimSet - -@Description Set the synchronisation primitive to a value - -@Input psSync The synchronisation primitive to set - -@Input ui32Value Value to set it to - -@Return PVRSRV_OK on success -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value); - -#if defined(NO_HARDWARE) - -/*************************************************************************/ /*! -@Function SyncPrimNoHwUpdate - -@Description Updates the synchronisation primitive value (in NoHardware drivers) - -@Input psSync The synchronisation primitive to update - -@Input ui32Value Value to update it to - -@Return PVRSRV_OK on success -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value); -#endif - -#if defined(PDUMP) -/*************************************************************************/ /*! -@Function SyncPrimPDump - -@Description PDump the current value of the synchronisation primitive - -@Input psSync The synchronisation primitive to PDump - -@Return None -*/ -/*****************************************************************************/ -void -SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync); - -/*************************************************************************/ /*! -@Function SyncPrimPDumpValue - -@Description PDump the ui32Value as the value of the synchronisation - primitive (regardless of the current value). - -@Input psSync The synchronisation primitive to PDump -@Input ui32Value Value to give to the sync prim on the pdump - -@Return None -*/ -/*****************************************************************************/ -void -SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value); - -/*************************************************************************/ /*! -@Function SyncPrimPDumpPol - -@Description Do a PDump poll of the synchronisation primitive - -@Input psSync The synchronisation primitive to PDump - -@Input ui32Value Value to poll for - -@Input ui32Mask PDump mask operator - -@Input ui32PDumpFlags PDump flags - -@Return None -*/ -/*****************************************************************************/ -void -SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function SyncPrimPDumpCBP - -@Description Do a PDump CB poll using the synchronisation primitive - -@Input psSync The synchronisation primitive to PDump - -@Input uiWriteOffset Current write offset of buffer - -@Input uiPacketSize Size of the packet to write into CB - -@Input uiBufferSize Size of the CB - -@Return None -*/ -/*****************************************************************************/ -void -SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT64 uiWriteOffset, - IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize); - -#else - -#ifdef INLINE_IS_PRAGMA -#pragma inline(SyncPrimPDumpValue) -#endif -static INLINE void -SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psSync); - PVR_UNREFERENCED_PARAMETER(ui32Value); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(SyncPrimPDump) -#endif -static INLINE void -SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync) -{ - PVR_UNREFERENCED_PARAMETER(psSync); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(SyncPrimPDumpPol) -#endif -static INLINE void -SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32PDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psSync); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(SyncPrimPDumpCBP) -#endif -static INLINE void -SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_UINT64 uiWriteOffset, - IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize) -{ - PVR_UNREFERENCED_PARAMETER(psSync); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); -} -#endif /* PDUMP */ -#endif /* SYNC_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.c b/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.c deleted file mode 100644 index f08734ec6ec28..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.c +++ /dev/null @@ -1,2979 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services synchronisation checkpoint interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Server side code for services synchronisation interface -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" -#include "img_types.h" -#include "allocmem.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "pvr_debug.h" -#include "pvr_notifier.h" -#include "osfunc.h" -#include "dllist.h" -#include "sync.h" -#include "sync_checkpoint_external.h" -#include "sync_checkpoint.h" -#include "sync_checkpoint_internal.h" -#include "sync_checkpoint_init.h" -#include "lock.h" -#include "log2.h" -#include "pvrsrv.h" -#include "pdump_km.h" -#include "info_page.h" - -#include "pvrsrv_sync_km.h" -#include "rgxhwperf.h" - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) -#include "rgxsoctimer.h" -#endif - -#if defined(PVRSRV_NEED_PVR_DPF) - -/* Enable this to turn on debug relating to the creation and - resolution of contexts */ -#define ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG 0 - -/* Enable this to turn on debug relating to the creation and - resolution of fences */ -#define ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG 0 - -/* Enable this to turn on debug relating to the sync checkpoint - allocation and freeing */ -#define ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG 0 - -/* Enable this to turn on debug relating to the sync checkpoint - enqueuing and signalling */ -#define ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG 0 - -/* Enable this to turn on debug relating to the sync checkpoint pool */ -#define ENABLE_SYNC_CHECKPOINT_POOL_DEBUG 0 - -/* Enable this to turn on debug relating to sync checkpoint UFO - lookup */ -#define ENABLE_SYNC_CHECKPOINT_UFO_DEBUG 0 - -/* Enable this to turn on sync checkpoint deferred cleanup debug - * (for syncs we have been told to free but which have some - * outstanding FW operations remaining (enqueued in CCBs) - */ -#define ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG 0 - -#else - -#define ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_POOL_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_UFO_DEBUG 0 -#define ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG 0 - -#endif - -/* Maximum number of deferred sync checkpoint signal/error received for atomic context */ -#define SYNC_CHECKPOINT_MAX_DEFERRED_SIGNAL 500 - -/* Set the size of the sync checkpoint pool (not used if 0). - * A pool will be maintained for each sync checkpoint context. - */ -#if defined(PDUMP) -#define SYNC_CHECKPOINT_POOL_SIZE 0 -#else -#define SYNC_CHECKPOINT_POOL_SIZE 128 -#define SYNC_CHECKPOINT_POOL_MASK (SYNC_CHECKPOINT_POOL_SIZE - 1) -#endif - -/* The 'sediment' value represents the minimum number of - * sync checkpoints which must be in the pool before one - * will be allocated from the pool rather than from memory. - * This effectively helps avoid re-use of a sync checkpoint - * just after it has been returned to the pool, making - * debugging somewhat easier to understand. - */ -#define SYNC_CHECKPOINT_POOL_SEDIMENT 20 - -#if (SYNC_CHECKPOINT_POOL_SIZE & (SYNC_CHECKPOINT_POOL_SIZE - 1)) != 0 -#error "SYNC_CHECKPOINT_POOL_SIZE must be power of 2." -#endif - -#define SYNC_CHECKPOINT_BLOCK_LIST_CHUNK_SIZE 10 - -/* - This defines the maximum amount of synchronisation memory - that can be allocated per sync checkpoint context. - In reality this number is meaningless as we would run out - of synchronisation memory before we reach this limit, but - we need to provide a size to the span RA. - */ -#define MAX_SYNC_CHECKPOINT_MEM (4 * 1024 * 1024) - - -typedef struct _SYNC_CHECKPOINT_BLOCK_LIST_ -{ - IMG_UINT32 ui32BlockCount; /*!< Number of contexts in the list */ - IMG_UINT32 ui32BlockListSize; /*!< Size of the array contexts */ - SYNC_CHECKPOINT_BLOCK **papsSyncCheckpointBlock; /*!< Array of sync checkpoint blocks */ -} SYNC_CHECKPOINT_BLOCK_LIST; - -struct _SYNC_CHECKPOINT_CONTEXT_CTL_ -{ - SHARED_DEV_CONNECTION psDeviceNode; - PFN_SYNC_CHECKPOINT_FENCE_RESOLVE_FN pfnFenceResolve; - PFN_SYNC_CHECKPOINT_FENCE_CREATE_FN pfnFenceCreate; - /* - * Used as head of linked-list of sync checkpoints for which - * SyncCheckpointFree() has been called, but have outstanding - * FW operations (enqueued in CCBs) - * This list will be check whenever a SyncCheckpointFree() is - * called, and when SyncCheckpointContextDestroy() is called. - */ - DLLIST_NODE sDeferredCleanupListHead; - /* Lock to protect the deferred cleanup list */ - POS_SPINLOCK hDeferredCleanupListLock; - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - SYNC_CHECKPOINT *psSyncCheckpointPool[SYNC_CHECKPOINT_POOL_SIZE]; - IMG_BOOL bSyncCheckpointPoolFull; - IMG_BOOL bSyncCheckpointPoolValid; - IMG_UINT32 ui32SyncCheckpointPoolCount; - IMG_UINT32 ui32SyncCheckpointPoolWp; - IMG_UINT32 ui32SyncCheckpointPoolRp; - POS_SPINLOCK hSyncCheckpointPoolLock; /*! Protects access to the checkpoint pool control data. */ -#endif -}; /*_SYNC_CHECKPOINT_CONTEXT_CTL is already typedef-ed in sync_checkpoint_internal.h */ - -/* this is the max number of sync checkpoint records we will search or dump - * at any time. - */ -#define SYNC_CHECKPOINT_RECORD_LIMIT 20000 - -#define DECREMENT_WITH_WRAP(value, sz) ((value) ? ((value) - 1) : ((sz) - 1)) - -struct SYNC_CHECKPOINT_RECORD -{ - PVRSRV_DEVICE_NODE *psDevNode; - SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock; /*!< handle to SYNC_CHECKPOINT_BLOCK */ - IMG_UINT32 ui32SyncOffset; /*!< offset to sync in block */ - IMG_UINT32 ui32FwBlockAddr; - IMG_PID uiPID; - IMG_UINT32 ui32UID; - IMG_UINT64 ui64OSTime; - DLLIST_NODE sNode; - IMG_CHAR szClassName[PVRSRV_SYNC_NAME_LENGTH]; - PSYNC_CHECKPOINT pSyncCheckpt; -}; - -static PFN_SYNC_CHECKPOINT_STRUCT *g_psSyncCheckpointPfnStruct = NULL; - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -static SYNC_CHECKPOINT *_GetCheckpointFromPool(_SYNC_CHECKPOINT_CONTEXT *psContext); -static IMG_BOOL _PutCheckpointInPool(SYNC_CHECKPOINT *psSyncCheckpoint); -static IMG_UINT32 _CleanCheckpointPool(_SYNC_CHECKPOINT_CONTEXT *psContext); -#endif - -#if (ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG == 1) -static IMG_UINT32 gui32NumSyncCheckpointContexts = 0; -#endif - -/* Defined values to indicate status of sync checkpoint, which is - * stored in the memory of the structure */ -#define SYNC_CHECKPOINT_PATTERN_IN_USE 0x1a1aa -#define SYNC_CHECKPOINT_PATTERN_IN_POOL 0x2b2bb -#define SYNC_CHECKPOINT_PATTERN_FREED 0x3c3cc - -#if defined(SUPPORT_RGX) -static inline void RGXSRVHWPerfSyncCheckpointUFOIsSignalled(PVRSRV_RGXDEV_INFO *psDevInfo, - SYNC_CHECKPOINT *psSyncCheckpointInt, IMG_UINT32 ui32FenceSyncFlags) -{ - if (RGXHWPerfHostIsEventEnabled(psDevInfo, RGX_HWPERF_HOST_UFO) - && !(ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - { - RGX_HWPERF_UFO_EV eEv; - RGX_HWPERF_UFO_DATA_ELEMENT sSyncData; - - if (psSyncCheckpointInt) - { - if ((psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_SIGNALLED) || - (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ERRORED)) - { - sSyncData.sCheckSuccess.ui32FWAddr = SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt); - sSyncData.sCheckSuccess.ui32Value = psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State; - eEv = RGX_HWPERF_UFO_EV_CHECK_SUCCESS; - } - else - { - sSyncData.sCheckFail.ui32FWAddr = SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt); - sSyncData.sCheckFail.ui32Value = psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State; - sSyncData.sCheckFail.ui32Required = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - eEv = RGX_HWPERF_UFO_EV_CHECK_FAIL; - } - RGXHWPerfHostPostUfoEvent(psDevInfo, eEv, &sSyncData, - (ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_CTX_ATOMIC) ? IMG_FALSE : IMG_TRUE); - } - } -} - -static inline void RGXSRVHWPerfSyncCheckpointUFOUpdate(PVRSRV_RGXDEV_INFO *psDevInfo, - SYNC_CHECKPOINT *psSyncCheckpointInt, IMG_UINT32 ui32FenceSyncFlags) -{ - if (RGXHWPerfHostIsEventEnabled(psDevInfo, RGX_HWPERF_HOST_UFO) - && !(ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - { - RGX_HWPERF_UFO_DATA_ELEMENT sSyncData; - - if (psSyncCheckpointInt) - { - sSyncData.sUpdate.ui32FWAddr = SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt); - sSyncData.sUpdate.ui32OldValue = psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State; - sSyncData.sUpdate.ui32NewValue = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - RGXHWPerfHostPostUfoEvent(psDevInfo, RGX_HWPERF_UFO_EV_UPDATE, &sSyncData, - (ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_CTX_ATOMIC) ? IMG_FALSE : IMG_TRUE); - } - } -} -#endif - -static PVRSRV_ERROR -_SyncCheckpointRecordAdd(PSYNC_CHECKPOINT_RECORD_HANDLE *phRecord, - SYNC_CHECKPOINT_BLOCK *hSyncCheckpointBlock, - IMG_UINT32 ui32FwBlockAddr, - IMG_UINT32 ui32SyncOffset, - IMG_UINT32 ui32UID, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName, PSYNC_CHECKPOINT pSyncCheckpt); -static PVRSRV_ERROR -_SyncCheckpointRecordRemove(PSYNC_CHECKPOINT_RECORD_HANDLE hRecord); -static void _SyncCheckpointState(PDLLIST_NODE psNode, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); -static void _SyncCheckpointDebugRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); -static PVRSRV_ERROR _SyncCheckpointRecordListInit(PVRSRV_DEVICE_NODE *psDevNode); -static void _SyncCheckpointRecordListDeinit(PVRSRV_DEVICE_NODE *psDevNode); - -#if defined(PDUMP) -static void -MISRHandler_PdumpDeferredSyncSignalPoster(void *pvData); -static PVRSRV_ERROR _SyncCheckpointAllocPDump(PVRSRV_DEVICE_NODE *psDevNode, SYNC_CHECKPOINT *psSyncCheckpoint); -static PVRSRV_ERROR _SyncCheckpointUpdatePDump(PPVRSRV_DEVICE_NODE psDevNode, SYNC_CHECKPOINT *psSyncCheckpoint, IMG_UINT32 ui32Status, IMG_UINT32 ui32FenceSyncFlags); -static PVRSRV_ERROR _SyncCheckpointPDumpTransition(void *pvData, PDUMP_TRANSITION_EVENT eEvent); -#endif - -/* Unique incremental ID assigned to sync checkpoints when allocated */ -static IMG_UINT32 g_SyncCheckpointUID; - -static void _CheckDeferredCleanupList(_SYNC_CHECKPOINT_CONTEXT *psContext); - -void SyncCheckpointContextUnref(PSYNC_CHECKPOINT_CONTEXT psContext) -{ - _SYNC_CHECKPOINT_CONTEXT *psContextInt = (_SYNC_CHECKPOINT_CONTEXT *) psContext; - _SYNC_CHECKPOINT_CONTEXT_CTL *const psCtxCtl = psContextInt->psContextCtl; - IMG_UINT32 ui32RefCt = OSAtomicRead(&psContextInt->hRefCount); - - if (ui32RefCt == 0) - { - PVR_LOG_ERROR(PVRSRV_ERROR_INVALID_CONTEXT, - "SyncCheckpointContextUnref context already freed"); - } - else if (OSAtomicDecrement(&psContextInt->hRefCount) == 0) - { - /* SyncCheckpointContextDestroy only when no longer referenced */ - OSSpinLockDestroy(psCtxCtl->hDeferredCleanupListLock); - psCtxCtl->hDeferredCleanupListLock = NULL; -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - if (psCtxCtl->ui32SyncCheckpointPoolCount) - { - PVR_DPF((PVR_DBG_WARNING, - "%s called for context<%p> with %d sync checkpoints still" - " in the pool", - __func__, - (void *) psContext, - psCtxCtl->ui32SyncCheckpointPoolCount)); - } - psCtxCtl->bSyncCheckpointPoolValid = IMG_FALSE; - OSSpinLockDestroy(psCtxCtl->hSyncCheckpointPoolLock); - psCtxCtl->hSyncCheckpointPoolLock = NULL; -#endif - OSFreeMem(psContextInt->psContextCtl); - RA_Delete(psContextInt->psSpanRA); - RA_Delete(psContextInt->psSubAllocRA); - OSLockDestroy(psContextInt->hLock); - psContextInt->hLock = NULL; - OSFreeMem(psContext); - } -} - -void SyncCheckpointContextRef(PSYNC_CHECKPOINT_CONTEXT psContext) -{ - _SYNC_CHECKPOINT_CONTEXT *psContextInt = (_SYNC_CHECKPOINT_CONTEXT *)psContext; - IMG_UINT32 ui32RefCt = OSAtomicRead(&psContextInt->hRefCount); - - if (ui32RefCt == 0) - { - PVR_LOG_ERROR(PVRSRV_ERROR_INVALID_CONTEXT, - "SyncCheckpointContextRef context use after free"); - } - else - { - OSAtomicIncrement(&psContextInt->hRefCount); - } -} - -/* - Internal interfaces for management of synchronisation block memory - */ -static PVRSRV_ERROR -_AllocSyncCheckpointBlock(_SYNC_CHECKPOINT_CONTEXT *psContext, - SYNC_CHECKPOINT_BLOCK **ppsSyncBlock) -{ - PVRSRV_DEVICE_NODE *psDevNode; - SYNC_CHECKPOINT_BLOCK *psSyncBlk; - PVRSRV_ERROR eError; - - psSyncBlk = OSAllocMem(sizeof(*psSyncBlk)); - PVR_LOG_GOTO_IF_NOMEM(psSyncBlk, eError, fail_alloc); - - psSyncBlk->psContext = psContext; - - /* Allocate sync checkpoint block */ - psDevNode = psContext->psDevNode; - PVR_LOG_GOTO_IF_INVALID_PARAM(psDevNode, eError, fail_alloc_ufo_block); - - psSyncBlk->psDevNode = psDevNode; - - eError = psDevNode->pfnAllocUFOBlock(psDevNode, - &psSyncBlk->hMemDesc, - &psSyncBlk->ui32FirmwareAddr, - &psSyncBlk->ui32SyncBlockSize); - PVR_LOG_GOTO_IF_ERROR(eError, "pfnAllocUFOBlock", fail_alloc_ufo_block); - - eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc, - (void **) &psSyncBlk->pui32LinAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", fail_devmem_acquire); - - OSAtomicWrite(&psSyncBlk->hRefCount, 1); - - OSLockCreate(&psSyncBlk->hLock); - - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, - "Allocated Sync Checkpoint UFO block (FirmwareVAddr = 0x%08x)", - psSyncBlk->ui32FirmwareAddr); -#if defined(PDUMP) - OSLockAcquire(psContext->hSyncCheckpointBlockListLock); - dllist_add_to_tail(&psContext->sSyncCheckpointBlockListHead, &psSyncBlk->sListNode); - OSLockRelease(psContext->hSyncCheckpointBlockListLock); -#endif - - *ppsSyncBlock = psSyncBlk; - return PVRSRV_OK; - -fail_devmem_acquire: - psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->hMemDesc); -fail_alloc_ufo_block: - OSFreeMem(psSyncBlk); -fail_alloc: - return eError; -} - -static void -_FreeSyncCheckpointBlock(SYNC_CHECKPOINT_BLOCK *psSyncBlk) -{ - OSLockAcquire(psSyncBlk->hLock); - if (0 == OSAtomicDecrement(&psSyncBlk->hRefCount)) - { - PVRSRV_DEVICE_NODE *psDevNode = psSyncBlk->psDevNode; - -#if defined(PDUMP) - OSLockAcquire(psSyncBlk->psContext->hSyncCheckpointBlockListLock); - dllist_remove_node(&psSyncBlk->sListNode); - OSLockRelease(psSyncBlk->psContext->hSyncCheckpointBlockListLock); -#endif - DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc); - psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->hMemDesc); - OSLockRelease(psSyncBlk->hLock); - OSLockDestroy(psSyncBlk->hLock); - psSyncBlk->hLock = NULL; - OSFreeMem(psSyncBlk); - } - else - { - OSLockRelease(psSyncBlk->hLock); - } -} - -static PVRSRV_ERROR -_SyncCheckpointBlockImport(RA_PERARENA_HANDLE hArena, - RA_LENGTH_T uSize, - RA_FLAGS_T uFlags, - const IMG_CHAR *pszAnnotation, - RA_BASE_T *puiBase, - RA_LENGTH_T *puiActualSize, - RA_PERISPAN_HANDLE *phImport) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext = hArena; - SYNC_CHECKPOINT_BLOCK *psSyncBlock = NULL; - RA_LENGTH_T uiSpanSize; - PVRSRV_ERROR eError; - PVR_UNREFERENCED_PARAMETER(uFlags); - - PVR_LOG_RETURN_IF_INVALID_PARAM((hArena != NULL), "hArena"); - - /* Check we've not be called with an unexpected size */ - PVR_LOG_RETURN_IF_INVALID_PARAM((uSize == sizeof(SYNC_CHECKPOINT_FW_OBJ)), "uSize"); - - /* - Ensure the sync checkpoint context doesn't go away while we have - sync blocks attached to it. - */ - SyncCheckpointContextRef((PSYNC_CHECKPOINT_CONTEXT)psContext); - - /* Allocate the block of memory */ - eError = _AllocSyncCheckpointBlock(psContext, &psSyncBlock); - PVR_GOTO_IF_ERROR(eError, fail_syncblockalloc); - - /* Allocate a span for it */ - eError = RA_Alloc(psContext->psSpanRA, - psSyncBlock->ui32SyncBlockSize, - RA_NO_IMPORT_MULTIPLIER, - 0, - psSyncBlock->ui32SyncBlockSize, - pszAnnotation, - &psSyncBlock->uiSpanBase, - &uiSpanSize, - NULL); - PVR_GOTO_IF_ERROR(eError, fail_spanalloc); - - /* - There is no reason the span RA should return an allocation larger - then we request - */ - PVR_LOG_IF_FALSE((uiSpanSize == psSyncBlock->ui32SyncBlockSize), - "uiSpanSize invalid"); - - *puiBase = psSyncBlock->uiSpanBase; - *puiActualSize = psSyncBlock->ui32SyncBlockSize; - *phImport = psSyncBlock; - return PVRSRV_OK; - -fail_spanalloc: - _FreeSyncCheckpointBlock(psSyncBlock); -fail_syncblockalloc: - SyncCheckpointContextUnref((PSYNC_CHECKPOINT_CONTEXT)psContext); - - return eError; -} - -static void -_SyncCheckpointBlockUnimport(RA_PERARENA_HANDLE hArena, - RA_BASE_T uiBase, - RA_PERISPAN_HANDLE hImport) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext = hArena; - SYNC_CHECKPOINT_BLOCK *psSyncBlock = hImport; - - PVR_LOG_RETURN_VOID_IF_FALSE((psContext != NULL), "hArena invalid"); - PVR_LOG_RETURN_VOID_IF_FALSE((psSyncBlock != NULL), "hImport invalid"); - PVR_LOG_RETURN_VOID_IF_FALSE((uiBase == psSyncBlock->uiSpanBase), "uiBase invalid"); - - /* Free the span this import is using */ - RA_Free(psContext->psSpanRA, uiBase); - - /* Free the sync checkpoint block */ - _FreeSyncCheckpointBlock(psSyncBlock); - - /* Drop our reference to the sync checkpoint context */ - SyncCheckpointContextUnref((PSYNC_CHECKPOINT_CONTEXT)psContext); -} - -static INLINE IMG_UINT32 _SyncCheckpointGetOffset(SYNC_CHECKPOINT *psSyncInt) -{ - IMG_UINT64 ui64Temp; - - ui64Temp = psSyncInt->uiSpanAddr - psSyncInt->psSyncCheckpointBlock->uiSpanBase; - PVR_ASSERT(ui64TemppfnFenceResolve)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - PVR_LOG_ERROR(eError, "g_pfnFenceResolve is NULL"); - return eError; - } - - if (papsSyncCheckpoints) - { - eError = g_psSyncCheckpointPfnStruct->pfnFenceResolve( - psSyncCheckpointContext, - hFence, - pui32NumSyncCheckpoints, - papsSyncCheckpoints, - pui64FenceUID); - } - else - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_LOG_RETURN_IF_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnFenceResolve"); - -#if defined(PDUMP) - if (*papsSyncCheckpoints) - { - for (i = 0; i < *pui32NumSyncCheckpoints; i++) - { - psSyncCheckpoint = (SYNC_CHECKPOINT *)(*papsSyncCheckpoints)[i]; - psSyncCheckpoint->ui32PDumpFlags = ui32PDumpFlags; - } - } -#endif - - if (*pui32NumSyncCheckpoints > MAX_SYNC_CHECKPOINTS_PER_FENCE) - { - PVR_DPF((PVR_DBG_ERROR, "%s: g_psSyncCheckpointPfnStruct->pfnFenceResolve() returned too many checkpoints (%u > MAX_SYNC_CHECKPOINTS_PER_FENCE=%u)", - __func__, *pui32NumSyncCheckpoints, MAX_SYNC_CHECKPOINTS_PER_FENCE)); - - /* Free resources after error */ - if (*papsSyncCheckpoints) - { - for (i = 0; i < *pui32NumSyncCheckpoints; i++) - { - SyncCheckpointDropRef((*papsSyncCheckpoints)[i]); - } - - SyncCheckpointFreeCheckpointListMem(*papsSyncCheckpoints); - } - - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if (ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG == 1) - { - IMG_UINT32 ii; - - PVR_DPF((PVR_DBG_WARNING, - "%s: g_psSyncCheckpointPfnStruct->pfnFenceResolve() for fence %d returned the following %d checkpoints:", - __func__, - hFence, - *pui32NumSyncCheckpoints)); - - for (ii=0; ii<*pui32NumSyncCheckpoints; ii++) - { - PSYNC_CHECKPOINT psNextCheckpoint = *(*papsSyncCheckpoints + ii); - PVR_DPF((PVR_DBG_WARNING, - "%s: *papsSyncCheckpoints[%d]:<%p>", - __func__, - ii, - (void*)psNextCheckpoint)); - } - } -#endif - - return eError; -} - -PVRSRV_ERROR -SyncCheckpointCreateFence(PVRSRV_DEVICE_NODE *psDevNode, - const IMG_CHAR *pszFenceName, - PVRSRV_TIMELINE hTimeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *phNewFence, - IMG_UINT64 *puiUpdateFenceUID, - void **ppvFenceFinaliseData, - PSYNC_CHECKPOINT *psNewSyncCheckpoint, - void **ppvTimelineUpdateSyncPrim, - IMG_UINT32 *pui32TimelineUpdateValue, - PDUMP_FLAGS_T ui32PDumpFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(psDevNode); - - if (unlikely(!g_psSyncCheckpointPfnStruct || !g_psSyncCheckpointPfnStruct->pfnFenceCreate)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - PVR_LOG_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnFenceCreate is NULL"); - } - else - { - eError = g_psSyncCheckpointPfnStruct->pfnFenceCreate( - psDevNode, - pszFenceName, - hTimeline, - psSyncCheckpointContext, - phNewFence, - puiUpdateFenceUID, - ppvFenceFinaliseData, - psNewSyncCheckpoint, - ppvTimelineUpdateSyncPrim, - pui32TimelineUpdateValue); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, - "%s failed to create new fence<%p> for timeline<%d> using " - "sync checkpoint context<%p>, psNewSyncCheckpoint=<%p>, eError=%s", - __func__, - (void*)phNewFence, - hTimeline, - (void*)psSyncCheckpointContext, - (void*)psNewSyncCheckpoint, - PVRSRVGetErrorString(eError))); - } -#if (ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG == 1) - else - { - PVR_DPF((PVR_DBG_WARNING, - "%s created new fence<%d> for timeline<%d> using " - "sync checkpoint context<%p>, new sync_checkpoint=<%p>", - __func__, - *phNewFence, - hTimeline, - (void*)psSyncCheckpointContext, - (void*)*psNewSyncCheckpoint)); - } -#endif - -#if defined(PDUMP) - if (eError == PVRSRV_OK) - { - SYNC_CHECKPOINT *psSyncCheckpoint = (SYNC_CHECKPOINT*)(*psNewSyncCheckpoint); - if (psSyncCheckpoint) - { - psSyncCheckpoint->ui32PDumpFlags = ui32PDumpFlags; - } - } -#endif - } - return eError; -} - -PVRSRV_ERROR -SyncCheckpointRollbackFenceData(PVRSRV_FENCE hFence, void *pvFinaliseData) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (!g_psSyncCheckpointPfnStruct || !g_psSyncCheckpointPfnStruct->pfnFenceDataRollback) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - PVR_LOG_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnFenceDataRollback is NULL"); - } - else - { -#if (ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s: called to rollback fence data <%p>", - __func__, - pvFinaliseData)); -#endif - eError = g_psSyncCheckpointPfnStruct->pfnFenceDataRollback( - hFence, pvFinaliseData); - PVR_LOG_IF_ERROR(eError, - "g_psSyncCheckpointPfnStruct->pfnFenceDataRollback returned error"); - } - return eError; -} - -PVRSRV_ERROR -SyncCheckpointFinaliseFence(PPVRSRV_DEVICE_NODE psDevNode, - PVRSRV_FENCE hFence, - void *pvFinaliseData, - PSYNC_CHECKPOINT psSyncCheckpoint, - const IMG_CHAR *pszName) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (!g_psSyncCheckpointPfnStruct || !g_psSyncCheckpointPfnStruct->pfnFenceFinalise) - { - PVR_DPF((PVR_DBG_WARNING, - "%s: Warning (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED) (this is permitted)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - } - else - { -#if (ENABLE_SYNC_CHECKPOINT_FENCE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s: called to finalise fence <%d>", - __func__, - hFence)); -#endif - eError = g_psSyncCheckpointPfnStruct->pfnFenceFinalise(hFence, pvFinaliseData); - PVR_LOG_IF_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnFenceFinalise returned error"); - - RGXSRV_HWPERF_ALLOC_FENCE(psDevNode, OSGetCurrentClientProcessIDKM(), hFence, - SyncCheckpointGetFirmwareAddr(psSyncCheckpoint), - pszName, OSStringLength(pszName)); - } - return eError; -} - -void -SyncCheckpointFreeCheckpointListMem(void *pvCheckpointListMem) -{ - if (g_psSyncCheckpointPfnStruct->pfnFreeCheckpointListMem) - { - g_psSyncCheckpointPfnStruct->pfnFreeCheckpointListMem(pvCheckpointListMem); - } -} - -PVRSRV_ERROR -SyncCheckpointNoHWUpdateTimelines(void *pvPrivateData) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (!g_psSyncCheckpointPfnStruct || !g_psSyncCheckpointPfnStruct->pfnNoHWUpdateTimelines) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - PVR_LOG_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnNoHWUpdateTimelines is NULL"); - } - else - { - g_psSyncCheckpointPfnStruct->pfnNoHWUpdateTimelines(pvPrivateData); - } - return eError; - -} - -PVRSRV_ERROR -SyncCheckpointDumpInfoOnStalledUFOs(IMG_UINT32 ui32NumUFOs, IMG_UINT32 *pui32Vaddrs, IMG_UINT32 *pui32NumSyncOwnedUFOs) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_FALSE((pui32NumSyncOwnedUFOs != NULL), "pui32NumSyncOwnedUFOs invalid", PVRSRV_ERROR_INVALID_PARAMS); - - if (!g_psSyncCheckpointPfnStruct || !g_psSyncCheckpointPfnStruct->pfnDumpInfoOnStalledUFOs) - { - *pui32NumSyncOwnedUFOs = 0; - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR (eError=PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)", - __func__)); - eError = PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED; - PVR_LOG_ERROR(eError, "g_psSyncCheckpointPfnStruct->pfnDumpInfoOnStalledUFOs is NULL"); - } - else - { - *pui32NumSyncOwnedUFOs = g_psSyncCheckpointPfnStruct->pfnDumpInfoOnStalledUFOs(ui32NumUFOs, pui32Vaddrs); - PVR_LOG(("%d sync checkpoint%s owned by %s in stalled context", - *pui32NumSyncOwnedUFOs, *pui32NumSyncOwnedUFOs==1 ? "" : "s", - g_psSyncCheckpointPfnStruct->pszImplName)); - } - return eError; -} - -PVRSRV_ERROR -SyncCheckpointContextCreate(PPVRSRV_DEVICE_NODE psDevNode, - PSYNC_CHECKPOINT_CONTEXT *ppsSyncCheckpointContext) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext = NULL; - _SYNC_CHECKPOINT_CONTEXT_CTL *psContextCtl = NULL; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_FALSE((ppsSyncCheckpointContext != NULL), - "ppsSyncCheckpointContext invalid", - PVRSRV_ERROR_INVALID_PARAMS); - - psContext = OSAllocMem(sizeof(*psContext)); - PVR_LOG_GOTO_IF_NOMEM(psContext, eError, fail_alloc); /* Sets OOM error code */ - - psContextCtl = OSAllocMem(sizeof(*psContextCtl)); - PVR_LOG_GOTO_IF_NOMEM(psContextCtl, eError, fail_alloc2); /* Sets OOM error code */ - - eError = OSLockCreate(&psContext->hLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate:1", fail_create_context_lock); - - eError = OSSpinLockCreate(&psContextCtl->hDeferredCleanupListLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSSpinLockCreate:1", fail_create_deferred_cleanup_lock); - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - eError = OSSpinLockCreate(&psContextCtl->hSyncCheckpointPoolLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSSpinLockCreate:2", fail_create_pool_lock); -#endif - - dllist_init(&psContextCtl->sDeferredCleanupListHead); -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - psContextCtl->ui32SyncCheckpointPoolCount = 0; - psContextCtl->ui32SyncCheckpointPoolWp = 0; - psContextCtl->ui32SyncCheckpointPoolRp = 0; - psContextCtl->bSyncCheckpointPoolFull = IMG_FALSE; - psContextCtl->bSyncCheckpointPoolValid = IMG_TRUE; -#endif - psContext->psDevNode = psDevNode; - - OSSNPrintf(psContext->azName, PVRSRV_SYNC_NAME_LENGTH, "Sync Prim RA-%p", psContext); - OSSNPrintf(psContext->azSpanName, PVRSRV_SYNC_NAME_LENGTH, "Sync Prim span RA-%p", psContext); - - /* - Create the RA for sub-allocations of the sync checkpoints - - Note: - The import size doesn't matter here as the server will pass - back the blocksize when it does the import which overrides - what we specify here. - */ - psContext->psSubAllocRA = RA_Create(psContext->azName, - /* Params for imports */ - _Log2(sizeof(IMG_UINT32)), - RA_LOCKCLASS_2, - _SyncCheckpointBlockImport, - _SyncCheckpointBlockUnimport, - psContext, - RA_POLICY_DEFAULT); - PVR_LOG_GOTO_IF_NOMEM(psContext->psSubAllocRA, eError, fail_suballoc); - - /* - Create the span-management RA - - The RA requires that we work with linear spans. For our use - here we don't require this behaviour as we're always working - within offsets of blocks (imports). However, we need to keep - the RA happy so we create the "span" management RA which - ensures that all are imports are added to the RA in a linear - fashion - */ - psContext->psSpanRA = RA_Create(psContext->azSpanName, - /* Params for imports */ - 0, - RA_LOCKCLASS_1, - NULL, - NULL, - NULL, - RA_POLICY_DEFAULT); - PVR_LOG_GOTO_IF_NOMEM(psContext->psSpanRA, eError, fail_span); - - if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_CHECKPOINT_MEM, 0, NULL)) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - PVR_LOG_ERROR(eError, "SyncCheckpointContextCreate call to RA_Add(span) failed"); - goto fail_span_add; - } - - OSAtomicWrite(&psContext->hRefCount, 1); - OSAtomicWrite(&psContext->hCheckpointCount, 0); - - psContext->psContextCtl = psContextCtl; - - *ppsSyncCheckpointContext = (PSYNC_CHECKPOINT_CONTEXT)psContext; -#if (ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s: created psSyncCheckpointContext=<%p> (%d contexts exist)", - __func__, - (void*)*ppsSyncCheckpointContext, - ++gui32NumSyncCheckpointContexts)); -#endif - -#if defined(PDUMP) - dllist_init(&psContext->sSyncCheckpointBlockListHead); - - eError = OSLockCreate(&psContext->hSyncCheckpointBlockListLock); - PVR_GOTO_IF_ERROR(eError, fail_span_add); - - OSLockAcquire(psDevNode->hSyncCheckpointContextListLock); - dllist_add_to_tail(&psDevNode->sSyncCheckpointContextListHead, &psContext->sListNode); - OSLockRelease(psDevNode->hSyncCheckpointContextListLock); - -#endif - - return PVRSRV_OK; - -fail_span_add: - RA_Delete(psContext->psSpanRA); -fail_span: - RA_Delete(psContext->psSubAllocRA); -fail_suballoc: -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - OSSpinLockDestroy(psContextCtl->hSyncCheckpointPoolLock); - psContextCtl->hSyncCheckpointPoolLock = NULL; -fail_create_pool_lock: -#endif - OSSpinLockDestroy(psContextCtl->hDeferredCleanupListLock); - psContextCtl->hDeferredCleanupListLock = NULL; -fail_create_deferred_cleanup_lock: - OSLockDestroy(psContext->hLock); - psContext->hLock = NULL; -fail_create_context_lock: - OSFreeMem(psContextCtl); -fail_alloc2: - OSFreeMem(psContext); -fail_alloc: - return eError; -} - -/* Poisons and frees the checkpoint - * Decrements context refcount. */ -static void _FreeSyncCheckpoint(SYNC_CHECKPOINT *psSyncCheckpoint) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext = psSyncCheckpoint->psSyncCheckpointBlock->psContext; - - psSyncCheckpoint->sCheckpointUFOAddr.ui32Addr = 0; - psSyncCheckpoint->psSyncCheckpointFwObj = NULL; - psSyncCheckpoint->ui32ValidationCheck = SYNC_CHECKPOINT_PATTERN_FREED; - - RA_Free(psSyncCheckpoint->psSyncCheckpointBlock->psContext->psSubAllocRA, - psSyncCheckpoint->uiSpanAddr); - psSyncCheckpoint->psSyncCheckpointBlock = NULL; - - OSFreeMem(psSyncCheckpoint); - - OSAtomicDecrement(&psContext->hCheckpointCount); -} - -PVRSRV_ERROR SyncCheckpointContextDestroy(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - _SYNC_CHECKPOINT_CONTEXT *psContext = (_SYNC_CHECKPOINT_CONTEXT*)psSyncCheckpointContext; - PVRSRV_DEVICE_NODE *psDevNode; - IMG_INT iRf = 0; - - PVR_LOG_RETURN_IF_FALSE((psSyncCheckpointContext != NULL), - "psSyncCheckpointContext invalid", - PVRSRV_ERROR_INVALID_PARAMS); - - psDevNode = (PVRSRV_DEVICE_NODE *)psContext->psDevNode; - -#if (ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s: destroying psSyncCheckpointContext=<%p> (now have %d contexts)", - __func__, - (void*)psSyncCheckpointContext, - --gui32NumSyncCheckpointContexts)); -#endif - - _CheckDeferredCleanupList(psContext); - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) - if (psContext->psContextCtl->ui32SyncCheckpointPoolCount > 0) - { - IMG_UINT32 ui32NumFreedFromPool = _CleanCheckpointPool(psContext); - -#if (ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s freed %d sync checkpoints that were still in the pool for context<%p>", - __func__, - ui32NumFreedFromPool, - (void*)psContext)); -#else - PVR_UNREFERENCED_PARAMETER(ui32NumFreedFromPool); -#endif - } -#endif - - iRf = OSAtomicRead(&psContext->hCheckpointCount); - - if (iRf != 0) - { - OS_SPINLOCK_FLAGS uiFlags; - - /* Note, this is not a permanent error as the caller may retry later */ - PVR_DPF((PVR_DBG_WARNING, - "%s <%p> attempted with active references (iRf=%d), " - "may be the result of a race", - __func__, - (void*)psContext, - iRf)); - - eError = PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT; - - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - { - DLLIST_NODE *psNode, *psNext; - - dllist_foreach_node(&psDevNode->sSyncCheckpointSyncsList, psNode, psNext) - { - SYNC_CHECKPOINT *psSyncCheckpoint = IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sListNode); - bool bDeferredFree = dllist_node_is_in_list(&psSyncCheckpoint->sDeferredFreeListNode); - - /* Line below avoids build error in release builds (where PVR_DPF is not defined) */ - PVR_UNREFERENCED_PARAMETER(bDeferredFree); - PVR_DPF((PVR_DBG_WARNING, - "%s syncCheckpoint<%p> ID=%d, %s, refs=%d, state=%s, fwaddr=%#08x, enqCount:%d, FWCount:%d %s", - __func__, - (void*)psSyncCheckpoint, - psSyncCheckpoint->ui32UID, - psSyncCheckpoint->azName, - OSAtomicRead(&psSyncCheckpoint->hRefCount), - psSyncCheckpoint->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_SIGNALLED ? - "PVRSRV_SYNC_CHECKPOINT_SIGNALLED" : - psSyncCheckpoint->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE ? - "PVRSRV_SYNC_CHECKPOINT_ACTIVE" : "PVRSRV_SYNC_CHECKPOINT_ERRORED", - psSyncCheckpoint->ui32FWAddr, - OSAtomicRead(&psSyncCheckpoint->hEnqueuedCCBCount), - psSyncCheckpoint->psSyncCheckpointFwObj->ui32FwRefCount, - bDeferredFree ? "(deferred free)" : "")); - -#if (ENABLE_SYNC_CHECKPOINT_CONTEXT_DEBUG == 1) - gui32NumSyncCheckpointContexts++; -#endif - } - } - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - } - else - { - OSAtomicRead(&psContext->hRefCount); - SyncCheckpointContextUnref(psSyncCheckpointContext); - } - -#if defined(PDUMP) - if (dllist_is_empty(&psContext->sSyncCheckpointBlockListHead)) - { - OSLockDestroy(psContext->hSyncCheckpointBlockListLock); - psContext->hSyncCheckpointBlockListLock = NULL; - - OSLockAcquire(psDevNode->hSyncCheckpointContextListLock); - dllist_remove_node(&psContext->sListNode); - OSLockRelease(psDevNode->hSyncCheckpointContextListLock); - } -#endif - - return eError; -} - -PVRSRV_ERROR -SyncCheckpointAlloc(PSYNC_CHECKPOINT_CONTEXT psSyncContext, - PVRSRV_TIMELINE hTimeline, - PVRSRV_FENCE hFence, - const IMG_CHAR *pszCheckpointName, - PSYNC_CHECKPOINT *ppsSyncCheckpoint) -{ - SYNC_CHECKPOINT *psNewSyncCheckpoint = NULL; - _SYNC_CHECKPOINT_CONTEXT *psSyncContextInt = (_SYNC_CHECKPOINT_CONTEXT*)psSyncContext; - PVRSRV_DEVICE_NODE *psDevNode; - PVRSRV_ERROR eError; - - PVR_LOG_RETURN_IF_FALSE((psSyncContext != NULL), "psSyncContext invalid", PVRSRV_ERROR_INVALID_PARAMS); - PVR_LOG_RETURN_IF_FALSE((ppsSyncCheckpoint != NULL), "ppsSyncCheckpoint invalid", PVRSRV_ERROR_INVALID_PARAMS); - - psDevNode = (PVRSRV_DEVICE_NODE *)psSyncContextInt->psDevNode; - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -#if ((ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) || (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1)) - PVR_DPF((PVR_DBG_WARNING, "%s Entry, Getting checkpoint from pool", - __func__)); -#endif - psNewSyncCheckpoint = _GetCheckpointFromPool(psSyncContextInt); - if (!psNewSyncCheckpoint) - { -#if ((ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) || (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1)) - PVR_DPF((PVR_DBG_WARNING, - "%s checkpoint pool empty - will have to allocate", - __func__)); -#endif - } -#endif - /* If pool is empty (or not defined) alloc the new sync checkpoint */ - if (!psNewSyncCheckpoint) - { - psNewSyncCheckpoint = OSAllocMem(sizeof(*psNewSyncCheckpoint)); - PVR_LOG_GOTO_IF_NOMEM(psNewSyncCheckpoint, eError, fail_alloc); /* Sets OOM error code */ - - eError = RA_Alloc(psSyncContextInt->psSubAllocRA, - sizeof(*psNewSyncCheckpoint->psSyncCheckpointFwObj), - RA_NO_IMPORT_MULTIPLIER, - 0, - sizeof(IMG_UINT32), - (IMG_CHAR*)pszCheckpointName, - &psNewSyncCheckpoint->uiSpanAddr, - NULL, - (RA_PERISPAN_HANDLE *) &psNewSyncCheckpoint->psSyncCheckpointBlock); - PVR_LOG_GOTO_IF_ERROR(eError, "RA_Alloc", fail_raalloc); - -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s CALLED RA_Alloc(), psSubAllocRA=<%p>, ui32SpanAddr=0x%llx", - __func__, - (void*)psSyncContextInt->psSubAllocRA, - psNewSyncCheckpoint->uiSpanAddr)); -#endif - psNewSyncCheckpoint->psSyncCheckpointFwObj = - (volatile SYNC_CHECKPOINT_FW_OBJ*)(void *)(psNewSyncCheckpoint->psSyncCheckpointBlock->pui32LinAddr + - (_SyncCheckpointGetOffset(psNewSyncCheckpoint)/sizeof(IMG_UINT32))); - psNewSyncCheckpoint->ui32FWAddr = psNewSyncCheckpoint->psSyncCheckpointBlock->ui32FirmwareAddr + - _SyncCheckpointGetOffset(psNewSyncCheckpoint) + 1; - OSAtomicIncrement(&psNewSyncCheckpoint->psSyncCheckpointBlock->psContext->hCheckpointCount); - psNewSyncCheckpoint->ui32ValidationCheck = SYNC_CHECKPOINT_PATTERN_IN_USE; -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called to allocate new sync checkpoint<%p> for context<%p>", - __func__, (void*)psNewSyncCheckpoint, (void*)psSyncContext)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpointFwObj<%p>", - __func__, (void*)psNewSyncCheckpoint->psSyncCheckpointFwObj)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint FwAddr=0x%x", - __func__, SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psNewSyncCheckpoint))); - PVR_DPF((PVR_DBG_WARNING, - "%s pszCheckpointName = %s", - __func__, pszCheckpointName)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint Timeline=%d", - __func__, hTimeline)); -#endif - } - - psNewSyncCheckpoint->hTimeline = hTimeline; - OSAtomicWrite(&psNewSyncCheckpoint->hRefCount, 1); - OSAtomicWrite(&psNewSyncCheckpoint->hEnqueuedCCBCount, 0); - psNewSyncCheckpoint->psSyncCheckpointFwObj->ui32FwRefCount = 0; - psNewSyncCheckpoint->psSyncCheckpointFwObj->ui32State = PVRSRV_SYNC_CHECKPOINT_ACTIVE; - psNewSyncCheckpoint->uiProcess = OSGetCurrentClientProcessIDKM(); - OSCachedMemSet(&psNewSyncCheckpoint->sDeferredFreeListNode, 0, sizeof(psNewSyncCheckpoint->sDeferredFreeListNode)); - - if (pszCheckpointName) - { - /* Copy over the checkpoint name annotation */ - OSStringLCopy(psNewSyncCheckpoint->azName, pszCheckpointName, PVRSRV_SYNC_NAME_LENGTH); - } - else - { - /* No sync checkpoint name annotation */ - psNewSyncCheckpoint->azName[0] = '\0'; - } - - /* Store sync checkpoint FW address in PRGXFWIF_UFO_ADDR struct */ - psNewSyncCheckpoint->sCheckpointUFOAddr.ui32Addr = SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psNewSyncCheckpoint); - - /* Assign unique ID to this sync checkpoint */ - psNewSyncCheckpoint->ui32UID = g_SyncCheckpointUID++; - -#if defined(PDUMP) - /* Flushing deferred fence signals to pdump */ - MISRHandler_PdumpDeferredSyncSignalPoster(psDevNode); - - _SyncCheckpointAllocPDump(psDevNode, psNewSyncCheckpoint); -#endif - - RGXSRV_HWPERF_ALLOC_SYNC_CP(psDevNode, psNewSyncCheckpoint->hTimeline, - OSGetCurrentClientProcessIDKM(), - hFence, - psNewSyncCheckpoint->ui32FWAddr, - psNewSyncCheckpoint->azName, - sizeof(psNewSyncCheckpoint->azName)); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - IMG_CHAR szChkptName[PVRSRV_SYNC_NAME_LENGTH]; - - if (pszCheckpointName) - { - /* Copy the checkpoint name annotation into a fixed-size array */ - OSStringLCopy(szChkptName, pszCheckpointName, PVRSRV_SYNC_NAME_LENGTH); - } - else - { - /* No checkpoint name annotation */ - szChkptName[0] = 0; - } - /* record this sync */ - eError = _SyncCheckpointRecordAdd(&psNewSyncCheckpoint->hRecord, - psNewSyncCheckpoint->psSyncCheckpointBlock, - psNewSyncCheckpoint->psSyncCheckpointBlock->ui32FirmwareAddr, - _SyncCheckpointGetOffset(psNewSyncCheckpoint), - psNewSyncCheckpoint->ui32UID, - OSStringNLength(szChkptName, PVRSRV_SYNC_NAME_LENGTH), - szChkptName, (PSYNC_CHECKPOINT)psNewSyncCheckpoint); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to add sync checkpoint record \"%s\" (%s)", - __func__, - szChkptName, - PVRSRVGetErrorString(eError))); - psNewSyncCheckpoint->hRecord = NULL; - /* note the error but continue without affecting driver operation */ - } - } - - { - OS_SPINLOCK_FLAGS uiFlags; - /* Add the sync checkpoint to the device list */ - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_add_to_head(&psDevNode->sSyncCheckpointSyncsList, - &psNewSyncCheckpoint->sListNode); - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - } - - *ppsSyncCheckpoint = (PSYNC_CHECKPOINT)psNewSyncCheckpoint; - -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s Exit(Ok), psNewSyncCheckpoint->ui32UID=%d <%p>", - __func__, - psNewSyncCheckpoint->ui32UID, - (void*)psNewSyncCheckpoint)); -#endif - return PVRSRV_OK; - -fail_raalloc: - OSFreeMem(psNewSyncCheckpoint); -fail_alloc: - return eError; -} - -static void SyncCheckpointUnref(SYNC_CHECKPOINT *psSyncCheckpointInt) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext; - PVRSRV_DEVICE_NODE *psDevNode; - - psContext = psSyncCheckpointInt->psSyncCheckpointBlock->psContext; - psDevNode = (PVRSRV_DEVICE_NODE *)psContext->psDevNode; - - /* - * Without this reference, the context may be destroyed as soon - * as _FreeSyncCheckpoint is called, but the context is still - * needed when _CheckDeferredCleanupList is called at the end - * of this function. - */ - SyncCheckpointContextRef((PSYNC_CHECKPOINT_CONTEXT)psContext); - - PVR_ASSERT(psSyncCheckpointInt->ui32ValidationCheck == SYNC_CHECKPOINT_PATTERN_IN_USE); - if (!OSAtomicRead(&psSyncCheckpointInt->hRefCount)) - { - PVR_DPF((PVR_DBG_ERROR, "SyncCheckpointUnref sync checkpoint already freed")); - } - else if (0 == OSAtomicDecrement(&psSyncCheckpointInt->hRefCount)) - { - /* If the firmware has serviced all enqueued references to the sync checkpoint, free it */ - if (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount == - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount))) - { -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s No outstanding FW ops and hRef is zero, deleting SyncCheckpoint..", - __func__)); -#endif - if ((GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - && psSyncCheckpointInt->hRecord) - { - PVRSRV_ERROR eError; - /* remove this sync record */ - eError = _SyncCheckpointRecordRemove(psSyncCheckpointInt->hRecord); - PVR_LOG_IF_ERROR(eError, "_SyncCheckpointRecordRemove"); - } - - { - OS_SPINLOCK_FLAGS uiFlags; - /* Remove the sync checkpoint from the global list */ - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_remove_node(&psSyncCheckpointInt->sListNode); - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - } - - RGXSRV_HWPERF_FREE(psDevNode, SYNC_CP, psSyncCheckpointInt->ui32FWAddr); - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -#if ((ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) || (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1)) - PVR_DPF((PVR_DBG_WARNING, - "%s attempting to return sync checkpoint to the pool", - __func__)); -#endif - if (!_PutCheckpointInPool(psSyncCheckpointInt)) -#endif - { -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -#if ((ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) || (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1)) - PVR_DPF((PVR_DBG_WARNING, - "%s pool is full, so just free it", - __func__)); -#endif -#endif -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s CALLING RA_Free(psSyncCheckpoint(ID:%d)<%p>), psSubAllocRA=<%p>, ui32SpanAddr=0x%llx", - __func__, - psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpointInt, - (void*)psSyncCheckpointInt->psSyncCheckpointBlock->psContext->psSubAllocRA, - psSyncCheckpointInt->uiSpanAddr)); -#endif - _FreeSyncCheckpoint(psSyncCheckpointInt); - } - } - else - { - OS_SPINLOCK_FLAGS uiFlags; -#if ((ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) || (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1)) - PVR_DPF((PVR_DBG_WARNING, - "%s Outstanding FW ops hEnqueuedCCBCount=%d != FwObj->ui32FwRefCount=%d " - "- DEFERRING CLEANUP psSyncCheckpoint(ID:%d)<%p>", - __func__, - OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount), - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount, - psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpointInt)); -#endif - /* Add the sync checkpoint to the deferred free list */ - OSSpinLockAcquire(psContext->psContextCtl->hDeferredCleanupListLock, uiFlags); - dllist_add_to_tail(&psContext->psContextCtl->sDeferredCleanupListHead, - &psSyncCheckpointInt->sDeferredFreeListNode); - OSSpinLockRelease(psContext->psContextCtl->hDeferredCleanupListLock, uiFlags); - } - } - else - { -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint(ID:%d)<%p>, hRefCount decremented to %d", - __func__, - psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpointInt, - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hRefCount)))); -#endif - } - - /* See if any sync checkpoints in the deferred cleanup list can be freed */ - _CheckDeferredCleanupList(psContext); - - SyncCheckpointContextUnref((PSYNC_CHECKPOINT_CONTEXT)psContext); -} - -void SyncCheckpointFree(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_RETURN_VOID_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s Entry, psSyncCheckpoint(ID:%d)<%p>, hRefCount=%d, psSyncCheckpoint->ui32ValidationCheck=0x%x", - __func__, - psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpoint, - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hRefCount)), - psSyncCheckpointInt->ui32ValidationCheck)); -#endif - SyncCheckpointUnref(psSyncCheckpointInt); -} - -void -SyncCheckpointSignal(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - - if (psSyncCheckpointInt) - { - PVR_LOG_IF_FALSE((psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE), - "psSyncCheckpoint already signalled"); - - if (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode->pvDevice; - - RGXSRVHWPerfSyncCheckpointUFOUpdate(psDevInfo, psSyncCheckpointInt, ui32FenceSyncFlags); -#endif - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - -#if defined(PDUMP) - _SyncCheckpointUpdatePDump(psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode, psSyncCheckpointInt, PVRSRV_SYNC_CHECKPOINT_SIGNALLED, ui32FenceSyncFlags); -#endif - } - else - { - PVR_DPF((PVR_DBG_WARNING, - "%s asked to set PVRSRV_SYNC_CHECKPOINT_SIGNALLED(%d) for (psSyncCheckpointInt->ui32UID=%d), " - "when value is already %d", - __func__, - PVRSRV_SYNC_CHECKPOINT_SIGNALLED, - psSyncCheckpointInt->ui32UID, - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State)); - } - } -} - -void -SyncCheckpointSignalNoHW(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - - if (psSyncCheckpointInt) - { - PVR_LOG_IF_FALSE((psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE), - "psSyncCheckpoint already signalled"); - - if (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode->pvDevice; - - RGXSRVHWPerfSyncCheckpointUFOUpdate(psDevInfo, psSyncCheckpointInt, PVRSRV_FENCE_FLAG_NONE); -#endif - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State = PVRSRV_SYNC_CHECKPOINT_SIGNALLED; - } - else - { -#if (ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s asked to set PVRSRV_SYNC_CHECKPOINT_SIGNALLED(%d) for (psSyncCheckpointInt->ui32UID=%d), " - "when value is already %d", - __func__, - PVRSRV_SYNC_CHECKPOINT_SIGNALLED, - psSyncCheckpointInt->ui32UID, - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State)); -#endif - } - } -} - -void -SyncCheckpointError(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - - if (psSyncCheckpointInt) - { - PVR_LOG_IF_FALSE((psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE), - "psSyncCheckpoint already signalled"); - - if (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode->pvDevice; - if (!(ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT)) - { - RGX_HWPERF_UFO_DATA_ELEMENT sSyncData; - - sSyncData.sUpdate.ui32FWAddr = SyncCheckpointGetFirmwareAddr(psSyncCheckpoint); - sSyncData.sUpdate.ui32OldValue = psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State; - sSyncData.sUpdate.ui32NewValue = PVRSRV_SYNC_CHECKPOINT_ERRORED; - - RGXSRV_HWPERF_UFO(psDevInfo, RGX_HWPERF_UFO_EV_UPDATE, &sSyncData, - (ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_CTX_ATOMIC) ? IMG_FALSE : IMG_TRUE); - } -#endif - - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State = PVRSRV_SYNC_CHECKPOINT_ERRORED; - -#if defined(PDUMP) - _SyncCheckpointUpdatePDump(psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode, psSyncCheckpointInt, PVRSRV_SYNC_CHECKPOINT_ERRORED, ui32FenceSyncFlags); -#endif - } - } -} - -IMG_BOOL SyncCheckpointIsSignalled(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags) -{ - IMG_BOOL bRet = IMG_FALSE; - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - - if (psSyncCheckpointInt) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode->pvDevice; - - RGXSRVHWPerfSyncCheckpointUFOIsSignalled(psDevInfo, psSyncCheckpointInt, ui32FenceSyncFlags); -#endif - bRet = ((psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_SIGNALLED) || - (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ERRORED)); - -#if (ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called for psSyncCheckpoint<%p>, returning %d", - __func__, - (void*)psSyncCheckpoint, - bRet)); -#endif - } - return bRet; -} - -IMG_BOOL -SyncCheckpointIsErrored(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags) -{ - IMG_BOOL bRet = IMG_FALSE; - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid"); - - if (psSyncCheckpointInt) - { -#if defined(SUPPORT_RGX) - PVRSRV_RGXDEV_INFO *psDevInfo = psSyncCheckpointInt->psSyncCheckpointBlock->psDevNode->pvDevice; - - RGXSRVHWPerfSyncCheckpointUFOIsSignalled(psDevInfo, psSyncCheckpointInt, ui32FenceSyncFlags); -#endif - bRet = (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ERRORED); - -#if (ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called for psSyncCheckpoint<%p>, returning %d", - __func__, - (void*)psSyncCheckpoint, - bRet)); -#endif - } - return bRet; -} - -const IMG_CHAR * -SyncCheckpointGetStateString(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_RETURN_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid", "Null"); - - switch (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State) - { - case PVRSRV_SYNC_CHECKPOINT_SIGNALLED: - return "Signalled"; - case PVRSRV_SYNC_CHECKPOINT_ACTIVE: - return "Active"; - case PVRSRV_SYNC_CHECKPOINT_ERRORED: - return "Errored"; - case PVRSRV_SYNC_CHECKPOINT_UNDEF: - return "Undefined"; - default: - return "Unknown"; - } -} - -PVRSRV_ERROR -SyncCheckpointTakeRef(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - PVRSRV_ERROR eRet = PVRSRV_OK; - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psSyncCheckpoint, "psSyncCheckpoint"); - -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s called for psSyncCheckpoint<%p> %d->%d (FWRef %u)", - __func__, - psSyncCheckpointInt, - OSAtomicRead(&psSyncCheckpointInt->hRefCount), - OSAtomicRead(&psSyncCheckpointInt->hRefCount)+1, - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount)); -#endif - OSAtomicIncrement(&psSyncCheckpointInt->hRefCount); - - return eRet; -} - -PVRSRV_ERROR -SyncCheckpointDropRef(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - PVRSRV_ERROR eRet = PVRSRV_OK; - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_RETURN_IF_INVALID_PARAM(psSyncCheckpoint, "psSyncCheckpoint"); - -#if (ENABLE_SYNC_CHECKPOINT_ALLOC_AND_FREE_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s called for psSyncCheckpoint<%p> %d->%d (FWRef %u)", - __func__, - psSyncCheckpointInt, - OSAtomicRead(&psSyncCheckpointInt->hRefCount), - OSAtomicRead(&psSyncCheckpointInt->hRefCount)-1, - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount)); -#endif - SyncCheckpointUnref(psSyncCheckpointInt); - - return eRet; -} - -void -SyncCheckpointCCBEnqueued(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_RETURN_VOID_IF_FALSE(psSyncCheckpoint != NULL, "psSyncCheckpoint"); - - if (psSyncCheckpointInt) - { -#if !defined(NO_HARDWARE) -#if (ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s called for psSyncCheckpoint<%p> %d->%d (FWRef %u)", - __func__, - (void*)psSyncCheckpoint, - OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount), - OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount)+1, - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount)); -#endif - OSAtomicIncrement(&psSyncCheckpointInt->hEnqueuedCCBCount); -#endif - } -} - -PRGXFWIF_UFO_ADDR* -SyncCheckpointGetRGXFWIFUFOAddr(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - - PVR_LOG_GOTO_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid", invalid_chkpt); - - if (psSyncCheckpointInt) - { - if (psSyncCheckpointInt->ui32ValidationCheck == SYNC_CHECKPOINT_PATTERN_IN_USE) - { - return &psSyncCheckpointInt->sCheckpointUFOAddr; - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s called for psSyncCheckpoint<%p>, but ui32ValidationCheck=0x%x", - __func__, - (void*)psSyncCheckpoint, - psSyncCheckpointInt->ui32ValidationCheck)); - } - } - -invalid_chkpt: - return NULL; -} - -IMG_UINT32 -SyncCheckpointGetFirmwareAddr(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - IMG_UINT32 ui32Ret = 0; - - PVR_LOG_GOTO_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid", invalid_chkpt); - - if (psSyncCheckpointInt) - { - if (psSyncCheckpointInt->ui32ValidationCheck == SYNC_CHECKPOINT_PATTERN_IN_USE) - { - ui32Ret = psSyncCheckpointInt->ui32FWAddr; - } - else - { - PVR_DPF((PVR_DBG_ERROR, - "%s called for psSyncCheckpoint<%p>, but ui32ValidationCheck=0x%x", - __func__, - (void*)psSyncCheckpoint, - psSyncCheckpointInt->ui32ValidationCheck)); - } - } - -invalid_chkpt: - return ui32Ret; -} - -IMG_UINT32 -SyncCheckpointGetId(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - IMG_UINT32 ui32Ret = 0; - - PVR_LOG_GOTO_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid", invalid_chkpt); - - if (psSyncCheckpointInt) - { -#if (ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s returning ID for sync checkpoint<%p>", - __func__, - (void*)psSyncCheckpointInt)); - PVR_DPF((PVR_DBG_WARNING, - "%s (validationCheck=0x%x)", - __func__, - psSyncCheckpointInt->ui32ValidationCheck)); -#endif - ui32Ret = psSyncCheckpointInt->ui32UID; -#if (ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s (ui32UID=0x%x)", - __func__, - psSyncCheckpointInt->ui32UID)); -#endif - } - return ui32Ret; - -invalid_chkpt: - return 0; -} - -PVRSRV_TIMELINE -SyncCheckpointGetTimeline(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - PVRSRV_TIMELINE i32Ret = PVRSRV_NO_TIMELINE; - - PVR_LOG_GOTO_IF_FALSE((psSyncCheckpoint != NULL), "psSyncCheckpoint invalid", invalid_chkpt); - - if (psSyncCheckpointInt) - { - i32Ret = psSyncCheckpointInt->hTimeline; - } - return i32Ret; - -invalid_chkpt: - return 0; -} - - -IMG_UINT32 -SyncCheckpointGetEnqueuedCount(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - PVR_LOG_RETURN_IF_FALSE(psSyncCheckpoint != NULL, "psSyncCheckpoint invalid", 0); - - return OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount); -} - -IMG_UINT32 -SyncCheckpointGetReferenceCount(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - PVR_LOG_RETURN_IF_FALSE(psSyncCheckpoint != NULL, "psSyncCheckpoint invalid", 0); - - return OSAtomicRead(&psSyncCheckpointInt->hRefCount); -} - -IMG_PID -SyncCheckpointGetCreator(PSYNC_CHECKPOINT psSyncCheckpoint) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt = (SYNC_CHECKPOINT*)psSyncCheckpoint; - PVR_LOG_RETURN_IF_FALSE(psSyncCheckpoint != NULL, "psSyncCheckpoint invalid", 0); - - return psSyncCheckpointInt->uiProcess; -} - -IMG_UINT32 SyncCheckpointStateFromUFO(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32FwAddr) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt; - PDLLIST_NODE psNode, psNext; - IMG_UINT32 ui32State = 0; - OS_SPINLOCK_FLAGS uiFlags; - - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_foreach_node(&psDevNode->sSyncCheckpointSyncsList, psNode, psNext) - { - psSyncCheckpointInt = IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sListNode); - if (ui32FwAddr == SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt)) - { - ui32State = psSyncCheckpointInt->psSyncCheckpointFwObj->ui32State; - break; - } - } - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - return ui32State; -} - -void SyncCheckpointErrorFromUFO(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32FwAddr) -{ - SYNC_CHECKPOINT *psSyncCheckpointInt; - PDLLIST_NODE psNode, psNext; - OS_SPINLOCK_FLAGS uiFlags; - -#if (ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called to error UFO with ui32FWAddr=%d", - __func__, - ui32FwAddr)); -#endif - - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_foreach_node(&psDevNode->sSyncCheckpointSyncsList, psNode, psNext) - { - psSyncCheckpointInt = IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sListNode); - if (ui32FwAddr == SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt)) - { -#if (ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s calling SyncCheckpointError for sync checkpoint <%p>", - __func__, - (void*)psSyncCheckpointInt)); -#endif - /* Mark as errored */ - SyncCheckpointError((PSYNC_CHECKPOINT)psSyncCheckpointInt, IMG_TRUE); - break; - } - } - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); -} - -void SyncCheckpointRollbackFromUFO(PPVRSRV_DEVICE_NODE psDevNode, IMG_UINT32 ui32FwAddr) -{ -#if (ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called to rollback UFO with ui32FWAddr=0x%x", - __func__, - ui32FwAddr)); -#endif -#if !defined(NO_HARDWARE) - { - SYNC_CHECKPOINT *psSyncCheckpointInt = NULL; - PDLLIST_NODE psNode = NULL, psNext = NULL; - OS_SPINLOCK_FLAGS uiFlags; - - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_foreach_node(&psDevNode->sSyncCheckpointSyncsList, psNode, psNext) - { - psSyncCheckpointInt = IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sListNode); - if (ui32FwAddr == SyncCheckpointGetFirmwareAddr((PSYNC_CHECKPOINT)psSyncCheckpointInt)) - { -#if ((ENABLE_SYNC_CHECKPOINT_UFO_DEBUG == 1)) || (ENABLE_SYNC_CHECKPOINT_ENQ_AND_SIGNAL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s called for psSyncCheckpointInt<%p> %d->%d", - __func__, - (void *) psSyncCheckpointInt, - OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount), - OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount) - 1)); -#endif - OSAtomicDecrement(&psSyncCheckpointInt->hEnqueuedCCBCount); - break; - } - } - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - } -#endif -} - -static void _SyncCheckpointState(PDLLIST_NODE psNode, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - SYNC_CHECKPOINT *psSyncCheckpoint = IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sListNode); - - if (psSyncCheckpoint->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_ACTIVE) - { - PVR_DUMPDEBUG_LOG("\t- ID = %d, FWAddr = 0x%08x, r%d:e%d:f%d: %s", - psSyncCheckpoint->ui32UID, - psSyncCheckpoint->psSyncCheckpointBlock->ui32FirmwareAddr + - _SyncCheckpointGetOffset(psSyncCheckpoint), - OSAtomicRead(&psSyncCheckpoint->hRefCount), - OSAtomicRead(&psSyncCheckpoint->hEnqueuedCCBCount), - psSyncCheckpoint->psSyncCheckpointFwObj->ui32FwRefCount, - psSyncCheckpoint->azName); - } -} - -static void _SyncCheckpointDebugRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)hDebugRequestHandle; - DLLIST_NODE *psNode, *psNext; - OS_SPINLOCK_FLAGS uiFlags; - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - { - PVR_DUMPDEBUG_LOG("------[ Active Sync Checkpoints ]------"); - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_foreach_node(&psDevNode->sSyncCheckpointSyncsList, psNode, psNext) - { - _SyncCheckpointState(psNode, pfnDumpDebugPrintf, pvDumpDebugFile); - } - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - } -} - -PVRSRV_ERROR -SyncCheckpointInit(PPVRSRV_DEVICE_NODE psDevNode) -{ - PVRSRV_ERROR eError; -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDevInfo = psDevNode->pvDevice; -#endif - - eError = OSSpinLockCreate(&psDevNode->hSyncCheckpointListLock); - PVR_RETURN_IF_ERROR(eError); - - dllist_init(&psDevNode->sSyncCheckpointSyncsList); - - eError = PVRSRVRegisterDeviceDbgRequestNotify(&psDevNode->hSyncCheckpointNotify, - psDevNode, - _SyncCheckpointDebugRequest, - DEBUG_REQUEST_SYNCCHECKPOINT, - (PVRSRV_DBGREQ_HANDLE)psDevNode); - PVR_GOTO_IF_ERROR(eError, e0); - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - _SyncCheckpointRecordListInit(psDevNode); - } - -#if defined(PDUMP) - eError = OSSpinLockCreate(&psDevInfo->hSyncCheckpointSignalSpinLock); - if (eError != PVRSRV_OK) - { - psDevInfo->hSyncCheckpointSignalSpinLock = NULL; - goto e1; - } - - eError = OSLockCreate(&psDevNode->hSyncCheckpointSignalLock); - if (eError != PVRSRV_OK) - { - psDevNode->hSyncCheckpointSignalLock = NULL; - goto e2; - } - - psDevNode->pui8DeferredSyncCPSignal = OSAllocMem(SYNC_CHECKPOINT_MAX_DEFERRED_SIGNAL - * sizeof(_SYNC_CHECKPOINT_DEFERRED_SIGNAL)); - PVR_GOTO_IF_NOMEM(psDevNode->pui8DeferredSyncCPSignal, eError, e3); - - psDevNode->ui16SyncCPWriteIdx = 0; - psDevNode->ui16SyncCPReadIdx = 0; - - eError = OSInstallMISR(&psDevNode->pvSyncCPMISR, - MISRHandler_PdumpDeferredSyncSignalPoster, - psDevNode, - "RGX_PdumpDeferredSyncSignalPoster"); - PVR_GOTO_IF_ERROR(eError, e4); - - eError = OSLockCreate(&psDevNode->hSyncCheckpointContextListLock); - if (eError != PVRSRV_OK) - { - psDevNode->hSyncCheckpointContextListLock = NULL; - goto e5; - } - - - dllist_init(&psDevNode->sSyncCheckpointContextListHead); - - eError = PDumpRegisterTransitionCallbackFenceSync(psDevNode, - _SyncCheckpointPDumpTransition, - &psDevNode->hTransition); - if (eError != PVRSRV_OK) - { - psDevNode->hTransition = NULL; - goto e6; - } -#endif - - return PVRSRV_OK; - -#if defined(PDUMP) -e6: - OSLockDestroy(psDevNode->hSyncCheckpointContextListLock); - psDevNode->hSyncCheckpointContextListLock = NULL; -e5: - (void) OSUninstallMISR(psDevNode->pvSyncCPMISR); - psDevNode->pvSyncCPMISR = NULL; -e4: - if (psDevNode->pui8DeferredSyncCPSignal) - { - OSFreeMem(psDevNode->pui8DeferredSyncCPSignal); - psDevNode->pui8DeferredSyncCPSignal = NULL; - } -e3: - OSLockDestroy(psDevNode->hSyncCheckpointSignalLock); - psDevNode->hSyncCheckpointSignalLock = NULL; -e2: - OSSpinLockDestroy(psDevInfo->hSyncCheckpointSignalSpinLock); - psDevInfo->hSyncCheckpointSignalSpinLock = NULL; -e1: - _SyncCheckpointRecordListDeinit(psDevNode); -#endif -e0: - OSSpinLockDestroy(psDevNode->hSyncCheckpointListLock); - psDevNode->hSyncCheckpointListLock = NULL; - - return eError; -} - -void SyncCheckpointDeinit(PPVRSRV_DEVICE_NODE psDevNode) -{ -#if defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDevInfo = psDevNode->pvDevice; - PDumpUnregisterTransitionCallbackFenceSync(psDevNode->hTransition); - psDevNode->hTransition = NULL; - - if (psDevNode->hSyncCheckpointContextListLock) - { - OSLockDestroy(psDevNode->hSyncCheckpointContextListLock); - psDevNode->hSyncCheckpointContextListLock = NULL; - } - - if (psDevNode->pvSyncCPMISR) - { - (void) OSUninstallMISR(psDevNode->pvSyncCPMISR); - psDevNode->pvSyncCPMISR = NULL; - } - - if (psDevNode->pui8DeferredSyncCPSignal) - { - OSFreeMem(psDevNode->pui8DeferredSyncCPSignal); - psDevNode->pui8DeferredSyncCPSignal = NULL; - } - if (psDevNode->hSyncCheckpointSignalLock) - { - OSLockDestroy(psDevNode->hSyncCheckpointSignalLock); - psDevNode->hSyncCheckpointSignalLock = NULL; - } - if (psDevInfo->hSyncCheckpointSignalSpinLock) - { - OSSpinLockDestroy(psDevInfo->hSyncCheckpointSignalSpinLock); - psDevInfo->hSyncCheckpointSignalSpinLock = NULL; - } -#endif - - PVRSRVUnregisterDeviceDbgRequestNotify(psDevNode->hSyncCheckpointNotify); - psDevNode->hSyncCheckpointNotify = NULL; - OSSpinLockDestroy(psDevNode->hSyncCheckpointListLock); - psDevNode->hSyncCheckpointListLock = NULL; - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - _SyncCheckpointRecordListDeinit(psDevNode); - } -} - -void SyncCheckpointRecordLookup(PPVRSRV_DEVICE_NODE psDevNode, IMG_UINT32 ui32FwAddr, - IMG_CHAR * pszSyncInfo, size_t len) -{ - DLLIST_NODE *psNode, *psNext; - IMG_BOOL bFound = IMG_FALSE; - - if (!pszSyncInfo) - { - return; - } - - pszSyncInfo[0] = '\0'; - - OSLockAcquire(psDevNode->hSyncCheckpointRecordLock); - dllist_foreach_node(&psDevNode->sSyncCheckpointRecordList, psNode, psNext) - { - struct SYNC_CHECKPOINT_RECORD *psSyncCheckpointRec = - IMG_CONTAINER_OF(psNode, struct SYNC_CHECKPOINT_RECORD, sNode); - if ((psSyncCheckpointRec->ui32FwBlockAddr + psSyncCheckpointRec->ui32SyncOffset + 1) == ui32FwAddr) - { - SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock = psSyncCheckpointRec->psSyncCheckpointBlock; - if (psSyncCheckpointBlock && psSyncCheckpointBlock->pui32LinAddr) - { - void *pSyncCheckpointAddr = IMG_OFFSET_ADDR(psSyncCheckpointBlock->pui32LinAddr, - psSyncCheckpointRec->ui32SyncOffset); - OSSNPrintf(pszSyncInfo, len, "%s Checkpoint:%05u (%s)", - (*(IMG_UINT32*)pSyncCheckpointAddr == PVRSRV_SYNC_CHECKPOINT_SIGNALLED) ? - "SIGNALLED" : - ((*(IMG_UINT32*)pSyncCheckpointAddr == PVRSRV_SYNC_CHECKPOINT_ERRORED) ? - "ERRORED" : "ACTIVE"), - psSyncCheckpointRec->uiPID, - psSyncCheckpointRec->szClassName); - } - else - { - OSSNPrintf(pszSyncInfo, len, "Checkpoint:%05u (%s)", - psSyncCheckpointRec->uiPID, - psSyncCheckpointRec->szClassName); - } - - bFound = IMG_TRUE; - break; - } - } - OSLockRelease(psDevNode->hSyncCheckpointRecordLock); - - if (!bFound && (psDevNode->ui32SyncCheckpointRecordCountHighWatermark == SYNC_CHECKPOINT_RECORD_LIMIT)) - { - OSSNPrintf(pszSyncInfo, len, "(Record may be lost)"); - } -} - -static PVRSRV_ERROR -_SyncCheckpointRecordAdd( - PSYNC_CHECKPOINT_RECORD_HANDLE * phRecord, - SYNC_CHECKPOINT_BLOCK *hSyncCheckpointBlock, - IMG_UINT32 ui32FwBlockAddr, - IMG_UINT32 ui32SyncOffset, - IMG_UINT32 ui32UID, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName, PSYNC_CHECKPOINT pSyncCheckpt) -{ - struct SYNC_CHECKPOINT_RECORD * psSyncRec; - _SYNC_CHECKPOINT_CONTEXT *psContext = hSyncCheckpointBlock->psContext; - PVRSRV_DEVICE_NODE *psDevNode = psContext->psDevNode; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_RETURN_IF_INVALID_PARAM(phRecord); - - *phRecord = NULL; - - psSyncRec = OSAllocMem(sizeof(*psSyncRec)); - PVR_LOG_GOTO_IF_NOMEM(psSyncRec, eError, fail_alloc); /* Sets OOM error code */ - - psSyncRec->psDevNode = psDevNode; - psSyncRec->psSyncCheckpointBlock = hSyncCheckpointBlock; - psSyncRec->ui32SyncOffset = ui32SyncOffset; - psSyncRec->ui32FwBlockAddr = ui32FwBlockAddr; - psSyncRec->ui64OSTime = OSClockns64(); - psSyncRec->uiPID = OSGetCurrentProcessID(); - psSyncRec->ui32UID = ui32UID; - psSyncRec->pSyncCheckpt = pSyncCheckpt; - if (pszClassName) - { - if (ui32ClassNameSize >= PVRSRV_SYNC_NAME_LENGTH) - ui32ClassNameSize = PVRSRV_SYNC_NAME_LENGTH; - /* Copy over the class name annotation */ - OSStringLCopy(psSyncRec->szClassName, pszClassName, ui32ClassNameSize); - } - else - { - /* No class name annotation */ - psSyncRec->szClassName[0] = 0; - } - - OSLockAcquire(psDevNode->hSyncCheckpointRecordLock); - if (psDevNode->ui32SyncCheckpointRecordCount < SYNC_CHECKPOINT_RECORD_LIMIT) - { - dllist_add_to_head(&psDevNode->sSyncCheckpointRecordList, &psSyncRec->sNode); - psDevNode->ui32SyncCheckpointRecordCount++; - - if (psDevNode->ui32SyncCheckpointRecordCount > psDevNode->ui32SyncCheckpointRecordCountHighWatermark) - { - psDevNode->ui32SyncCheckpointRecordCountHighWatermark = psDevNode->ui32SyncCheckpointRecordCount; - } - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to add sync checkpoint record \"%s\". %u records already exist.", - __func__, - pszClassName, - psDevNode->ui32SyncCheckpointRecordCount)); - OSFreeMem(psSyncRec); - psSyncRec = NULL; - eError = PVRSRV_ERROR_TOOMANYBUFFERS; - } - OSLockRelease(psDevNode->hSyncCheckpointRecordLock); - - *phRecord = (PSYNC_CHECKPOINT_RECORD_HANDLE)psSyncRec; - -fail_alloc: - return eError; -} - -static PVRSRV_ERROR -_SyncCheckpointRecordRemove(PSYNC_CHECKPOINT_RECORD_HANDLE hRecord) -{ - struct SYNC_CHECKPOINT_RECORD **ppFreedSync; - struct SYNC_CHECKPOINT_RECORD *pSync = (struct SYNC_CHECKPOINT_RECORD*)hRecord; - PVRSRV_DEVICE_NODE *psDevNode; - - PVR_RETURN_IF_INVALID_PARAM(hRecord); - - psDevNode = pSync->psDevNode; - - OSLockAcquire(psDevNode->hSyncCheckpointRecordLock); - - dllist_remove_node(&pSync->sNode); - - if (psDevNode->uiSyncCheckpointRecordFreeIdx >= PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: psDevNode->uiSyncCheckpointRecordFreeIdx out of range", - __func__)); - psDevNode->uiSyncCheckpointRecordFreeIdx = 0; - } - ppFreedSync = &psDevNode->apsSyncCheckpointRecordsFreed[psDevNode->uiSyncCheckpointRecordFreeIdx]; - psDevNode->uiSyncCheckpointRecordFreeIdx = - (psDevNode->uiSyncCheckpointRecordFreeIdx + 1) % PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN; - - if (*ppFreedSync) - { - OSFreeMem(*ppFreedSync); - } - pSync->psSyncCheckpointBlock = NULL; - pSync->ui64OSTime = OSClockns64(); - *ppFreedSync = pSync; - - psDevNode->ui32SyncCheckpointRecordCount--; - - OSLockRelease(psDevNode->hSyncCheckpointRecordLock); - - return PVRSRV_OK; -} - -#define NS_IN_S (1000000000UL) -static void _SyncCheckpointRecordPrint(struct SYNC_CHECKPOINT_RECORD *psSyncCheckpointRec, - IMG_UINT64 ui64TimeNow, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - SYNC_CHECKPOINT *psSyncCheckpoint = (SYNC_CHECKPOINT *)psSyncCheckpointRec->pSyncCheckpt; - SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock = psSyncCheckpointRec->psSyncCheckpointBlock; - IMG_UINT64 ui64DeltaS; - IMG_UINT32 ui32DeltaF; - IMG_UINT64 ui64Delta = ui64TimeNow - psSyncCheckpointRec->ui64OSTime; - ui64DeltaS = OSDivide64(ui64Delta, NS_IN_S, &ui32DeltaF); - - if (psSyncCheckpointBlock && psSyncCheckpointBlock->pui32LinAddr) - { - void *pSyncCheckpointAddr; - pSyncCheckpointAddr = IMG_OFFSET_ADDR(psSyncCheckpointBlock->pui32LinAddr, - psSyncCheckpointRec->ui32SyncOffset); - - PVR_DUMPDEBUG_LOG("\t%05u %05" IMG_UINT64_FMTSPEC ".%09u %010u FWAddr=0x%08x (r%d:e%d:f%d) State=%s (%s)", - psSyncCheckpointRec->uiPID, - ui64DeltaS, ui32DeltaF, psSyncCheckpointRec->ui32UID, - (psSyncCheckpointRec->ui32FwBlockAddr+psSyncCheckpointRec->ui32SyncOffset), - OSAtomicRead(&psSyncCheckpoint->hRefCount), - OSAtomicRead(&psSyncCheckpoint->hEnqueuedCCBCount), - psSyncCheckpoint->psSyncCheckpointFwObj->ui32FwRefCount, - (*(IMG_UINT32*)pSyncCheckpointAddr == PVRSRV_SYNC_CHECKPOINT_SIGNALLED) ? - "SIGNALLED" : - ((*(IMG_UINT32*)pSyncCheckpointAddr == PVRSRV_SYNC_CHECKPOINT_ERRORED) ? - "ERRORED" : "ACTIVE"), - psSyncCheckpointRec->szClassName); - } - else - { - PVR_DUMPDEBUG_LOG("\t%05u %05" IMG_UINT64_FMTSPEC ".%09u %010u FWAddr=0x%08x State= (%s)", - psSyncCheckpointRec->uiPID, - ui64DeltaS, ui32DeltaF, psSyncCheckpointRec->ui32UID, - (psSyncCheckpointRec->ui32FwBlockAddr+psSyncCheckpointRec->ui32SyncOffset), - psSyncCheckpointRec->szClassName - ); - } -} - -static void _SyncCheckpointRecordRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)hDebugRequestHandle; - IMG_UINT64 ui64TimeNowS; - IMG_UINT32 ui32TimeNowF; - IMG_UINT64 ui64TimeNow = OSClockns64(); - DLLIST_NODE *psNode, *psNext; - - ui64TimeNowS = OSDivide64(ui64TimeNow, NS_IN_S, &ui32TimeNowF); - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - { - IMG_UINT32 i; - - OSLockAcquire(psDevNode->hSyncCheckpointRecordLock); - - PVR_DUMPDEBUG_LOG("Dumping allocated sync checkpoints. Allocated: %u High watermark: %u (time ref %05" IMG_UINT64_FMTSPEC ".%09u)", - psDevNode->ui32SyncCheckpointRecordCount, - psDevNode->ui32SyncCheckpointRecordCountHighWatermark, - ui64TimeNowS, - ui32TimeNowF); - if (psDevNode->ui32SyncCheckpointRecordCountHighWatermark == SYNC_CHECKPOINT_RECORD_LIMIT) - { - PVR_DUMPDEBUG_LOG("Warning: Record limit (%u) was reached. Some sync checkpoints may not have been recorded in the debug information.", - SYNC_CHECKPOINT_RECORD_LIMIT); - } - PVR_DUMPDEBUG_LOG("\t%-5s %-15s %-10s %-17s %-14s (%s)", - "PID", "Time Delta (s)", "UID", "Address", "State", "Annotation"); - - dllist_foreach_node(&psDevNode->sSyncCheckpointRecordList, psNode, psNext) - { - struct SYNC_CHECKPOINT_RECORD *psSyncCheckpointRec = - IMG_CONTAINER_OF(psNode, struct SYNC_CHECKPOINT_RECORD, sNode); - _SyncCheckpointRecordPrint(psSyncCheckpointRec, ui64TimeNow, - pfnDumpDebugPrintf, pvDumpDebugFile); - } - - PVR_DUMPDEBUG_LOG("Dumping all recently freed sync checkpoints @ %05" IMG_UINT64_FMTSPEC ".%09u", - ui64TimeNowS, - ui32TimeNowF); - PVR_DUMPDEBUG_LOG("\t%-5s %-15s %-10s %-17s %-14s (%s)", - "PID", "Time Delta (s)", "UID", "Address", "State", "Annotation"); - for (i = DECREMENT_WITH_WRAP(psDevNode->uiSyncCheckpointRecordFreeIdx, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN); - i != psDevNode->uiSyncCheckpointRecordFreeIdx; - i = DECREMENT_WITH_WRAP(i, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN)) - { - if (psDevNode->apsSyncCheckpointRecordsFreed[i]) - { - _SyncCheckpointRecordPrint(psDevNode->apsSyncCheckpointRecordsFreed[i], - ui64TimeNow, pfnDumpDebugPrintf, pvDumpDebugFile); - } - else - { - break; - } - } - OSLockRelease(psDevNode->hSyncCheckpointRecordLock); - } -} -#undef NS_IN_S -static PVRSRV_ERROR _SyncCheckpointRecordListInit(PVRSRV_DEVICE_NODE *psDevNode) -{ - PVRSRV_ERROR eError; - - eError = OSLockCreate(&psDevNode->hSyncCheckpointRecordLock); - PVR_GOTO_IF_ERROR(eError, fail_lock_create); - dllist_init(&psDevNode->sSyncCheckpointRecordList); - - psDevNode->ui32SyncCheckpointRecordCount = 0; - psDevNode->ui32SyncCheckpointRecordCountHighWatermark = 0; - - eError = PVRSRVRegisterDeviceDbgRequestNotify(&psDevNode->hSyncCheckpointRecordNotify, - psDevNode, - _SyncCheckpointRecordRequest, - DEBUG_REQUEST_SYNCCHECKPOINT, - (PVRSRV_DBGREQ_HANDLE)psDevNode); - PVR_GOTO_IF_ERROR(eError, fail_dbg_register); - - return PVRSRV_OK; - -fail_dbg_register: - OSLockDestroy(psDevNode->hSyncCheckpointRecordLock); -fail_lock_create: - return eError; -} - -static void _SyncCheckpointRecordListDeinit(PVRSRV_DEVICE_NODE *psDevNode) -{ - DLLIST_NODE *psNode, *psNext; - int i; - - OSLockAcquire(psDevNode->hSyncCheckpointRecordLock); - dllist_foreach_node(&psDevNode->sSyncCheckpointRecordList, psNode, psNext) - { - struct SYNC_CHECKPOINT_RECORD *pSyncCheckpointRec = - IMG_CONTAINER_OF(psNode, struct SYNC_CHECKPOINT_RECORD, sNode); - - dllist_remove_node(psNode); - OSFreeMem(pSyncCheckpointRec); - } - - for (i = 0; i < PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN; i++) - { - if (psDevNode->apsSyncCheckpointRecordsFreed[i]) - { - OSFreeMem(psDevNode->apsSyncCheckpointRecordsFreed[i]); - psDevNode->apsSyncCheckpointRecordsFreed[i] = NULL; - } - } - OSLockRelease(psDevNode->hSyncCheckpointRecordLock); - - if (psDevNode->hSyncCheckpointRecordNotify) - { - PVRSRVUnregisterDeviceDbgRequestNotify(psDevNode->hSyncCheckpointRecordNotify); - } - OSLockDestroy(psDevNode->hSyncCheckpointRecordLock); -} - -#if defined(PDUMP) - -static PVRSRV_ERROR -_SyncCheckpointAllocPDump(PVRSRV_DEVICE_NODE *psDevNode, SYNC_CHECKPOINT *psSyncCheckpoint) -{ - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, - "Allocated Sync Checkpoint %s (ID:%d, TL:%d, FirmwareVAddr = 0x%08x)", - psSyncCheckpoint->azName, - psSyncCheckpoint->ui32UID, psSyncCheckpoint->hTimeline, - psSyncCheckpoint->sCheckpointUFOAddr.ui32Addr); - - DevmemPDumpLoadMemValue32(psSyncCheckpoint->psSyncCheckpointBlock->hMemDesc, - _SyncCheckpointGetOffset(psSyncCheckpoint), - PVRSRV_SYNC_CHECKPOINT_ACTIVE, - PDUMP_FLAGS_CONTINUOUS); - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_SyncCheckpointUpdatePDump(PPVRSRV_DEVICE_NODE psDevNode, SYNC_CHECKPOINT *psSyncCheckpoint, IMG_UINT32 ui32Status, IMG_UINT32 ui32FenceSyncFlags) -{ - IMG_BOOL bSleepAllowed = (ui32FenceSyncFlags & PVRSRV_FENCE_FLAG_CTX_ATOMIC) ? IMG_FALSE : IMG_TRUE; - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDevInfo = psDevNode->pvDevice; - /* - We might be ask to PDump sync state outside of capture range - (e.g. texture uploads) so make this continuous. - */ - if (bSleepAllowed) - { - if (ui32Status == PVRSRV_SYNC_CHECKPOINT_ERRORED) - { - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, - "Errored Sync Checkpoint %s (ID:%d, TL:%d, FirmwareVAddr = 0x%08x)", - psSyncCheckpoint->azName, - psSyncCheckpoint->ui32UID, psSyncCheckpoint->hTimeline, - (psSyncCheckpoint->psSyncCheckpointBlock->ui32FirmwareAddr + - _SyncCheckpointGetOffset(psSyncCheckpoint))); - } - else - { - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, - "Signalled Sync Checkpoint %s (ID:%d, TL:%d, FirmwareVAddr = 0x%08x)", - psSyncCheckpoint->azName, - psSyncCheckpoint->ui32UID, psSyncCheckpoint->hTimeline, - (psSyncCheckpoint->psSyncCheckpointBlock->ui32FirmwareAddr + - _SyncCheckpointGetOffset(psSyncCheckpoint))); - } - - DevmemPDumpLoadMemValue32(psSyncCheckpoint->psSyncCheckpointBlock->hMemDesc, - _SyncCheckpointGetOffset(psSyncCheckpoint), - ui32Status, - PDUMP_FLAGS_CONTINUOUS); - } - else - { - _SYNC_CHECKPOINT_DEFERRED_SIGNAL *psSyncData; - OS_SPINLOCK_FLAGS uiFlags; - IMG_UINT16 ui16NewWriteIdx; - - OSSpinLockAcquire(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - - ui16NewWriteIdx = GET_CP_CB_NEXT_IDX(psDevNode->ui16SyncCPWriteIdx); - if (ui16NewWriteIdx == psDevNode->ui16SyncCPReadIdx) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: ERROR Deferred SyncCheckpointSignal CB is full)", - __func__)); - } - else - { - psSyncData = GET_CP_CB_BASE(psDevNode->ui16SyncCPWriteIdx); - psSyncData->asSyncCheckpoint = *psSyncCheckpoint; - psSyncData->ui32Status = ui32Status; - psDevNode->ui16SyncCPWriteIdx = ui16NewWriteIdx; - } - - OSSpinLockRelease(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - - OSScheduleMISR(psDevNode->pvSyncCPMISR); - } - - return PVRSRV_OK; -} - -static void -MISRHandler_PdumpDeferredSyncSignalPoster(void *pvData) -{ - PPVRSRV_DEVICE_NODE psDevNode = (PPVRSRV_DEVICE_NODE) pvData; - OS_SPINLOCK_FLAGS uiFlags; - IMG_UINT16 ui16ReadIdx, ui16WriteIdx; - _SYNC_CHECKPOINT_DEFERRED_SIGNAL *psSyncData; - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDevInfo = psDevNode->pvDevice; - - OSLockAcquire(psDevNode->hSyncCheckpointSignalLock); - - OSSpinLockAcquire(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - /* Snapshot current write and read offset of CB */ - ui16WriteIdx = psDevNode->ui16SyncCPWriteIdx; - ui16ReadIdx = psDevNode->ui16SyncCPReadIdx; - - OSSpinLockRelease(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - /* CB is empty */ - if (ui16WriteIdx == ui16ReadIdx) - { - OSLockRelease(psDevNode->hSyncCheckpointSignalLock); - return; - } - do - { - /* Read item in the CB and flush it to pdump */ - psSyncData = GET_CP_CB_BASE(ui16ReadIdx); - _SyncCheckpointUpdatePDump(psDevNode, &psSyncData->asSyncCheckpoint, psSyncData->ui32Status, PVRSRV_FENCE_FLAG_NONE); - ui16ReadIdx = GET_CP_CB_NEXT_IDX(psDevNode->ui16SyncCPReadIdx); - /* Increment read offset in CB as one item is flushed to pdump */ - OSSpinLockAcquire(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - psDevNode->ui16SyncCPReadIdx = ui16ReadIdx; - OSSpinLockRelease(psDevInfo->hSyncCheckpointSignalSpinLock, uiFlags); - /* Call to this function will flush all the items present in CB - * when this function is called i.e. use snapshot of WriteOffset - * taken at the beginning in this function and iterate till Write != Read */ - } while (ui16WriteIdx != ui16ReadIdx); - - OSLockRelease(psDevNode->hSyncCheckpointSignalLock); -} - -PVRSRV_ERROR PVRSRVSyncCheckpointSignalledPDumpPolKM(PVRSRV_FENCE hFence) -{ - PVRSRV_ERROR eError; - PSYNC_CHECKPOINT *apsCheckpoints = NULL; - SYNC_CHECKPOINT *psSyncCheckpoint = NULL; - IMG_UINT32 i, uiNumCheckpoints = 0; -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) && defined(NO_HARDWARE) && defined(PDUMP) - PVRSRV_RGXDEV_INFO *psDevInfo; -#endif - - if (hFence != PVRSRV_NO_FENCE) - { - eError = g_psSyncCheckpointPfnStruct->pfnSyncFenceGetCheckpoints(hFence, &uiNumCheckpoints, &apsCheckpoints); - } - else - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_LOG_RETURN_IF_ERROR(eError, "g_pfnFenceGetCheckpoints"); - - if (uiNumCheckpoints) - { - /* Flushing deferred fence signals to pdump */ - psSyncCheckpoint = (SYNC_CHECKPOINT *)apsCheckpoints[0]; - MISRHandler_PdumpDeferredSyncSignalPoster(psSyncCheckpoint->psSyncCheckpointBlock->psDevNode); - } - - for (i=0; i < uiNumCheckpoints; i++) - { - psSyncCheckpoint = (SYNC_CHECKPOINT *)apsCheckpoints[i]; - if (psSyncCheckpoint->psSyncCheckpointFwObj->ui32State == PVRSRV_SYNC_CHECKPOINT_SIGNALLED) - { - PDUMPCOMMENTWITHFLAGS(psSyncCheckpoint->psSyncCheckpointBlock->psDevNode, - psSyncCheckpoint->ui32PDumpFlags, - "Wait for Fence %s (ID:%d)", - psSyncCheckpoint->azName, - psSyncCheckpoint->ui32UID); - - eError = DevmemPDumpDevmemPol32(psSyncCheckpoint->psSyncCheckpointBlock->hMemDesc, - _SyncCheckpointGetOffset(psSyncCheckpoint), - PVRSRV_SYNC_CHECKPOINT_SIGNALLED, - 0xFFFFFFFF, - PDUMP_POLL_OPERATOR_EQUAL, - psSyncCheckpoint->ui32PDumpFlags); - PVR_LOG_IF_ERROR(eError, "DevmemPDumpDevmemPol32"); - } - } - -#if defined(SUPPORT_VALIDATION) && defined(SUPPORT_SOC_TIMER) && defined(NO_HARDWARE) && defined(PDUMP) - /* Sampling of USC timers can only be done after synchronisation for a 3D kick is over */ - if (uiNumCheckpoints) - { - psSyncCheckpoint = (SYNC_CHECKPOINT *)apsCheckpoints[0]; - psDevInfo = psSyncCheckpoint->psSyncCheckpointBlock->psDevNode->pvDevice; - if (psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags & RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER) - { - RGXValidateSOCUSCTimer(psDevInfo, PDUMP_CONT, 0, 0, NULL); - } - } -#endif - - /* Free the memory that was allocated for the sync checkpoint list returned */ - if (apsCheckpoints) - { - SyncCheckpointFreeCheckpointListMem(apsCheckpoints); - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR -_SyncCheckpointPDumpTransition(void *pvData, PDUMP_TRANSITION_EVENT eEvent) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext; - DLLIST_NODE *psNode, *psNext; - DLLIST_NODE *psNode1, *psNext1; - PPVRSRV_DEVICE_NODE psDevNode = (PPVRSRV_DEVICE_NODE) pvData; - - if ((eEvent == PDUMP_TRANSITION_EVENT_RANGE_ENTERED) || (eEvent == PDUMP_TRANSITION_EVENT_BLOCK_STARTED)) - { - OSLockAcquire(psDevNode->hSyncCheckpointContextListLock); - dllist_foreach_node(&psDevNode->sSyncCheckpointContextListHead, psNode, psNext) - { - psContext = IMG_CONTAINER_OF(psNode, _SYNC_CHECKPOINT_CONTEXT, sListNode); - - OSLockAcquire(psContext->hSyncCheckpointBlockListLock); - dllist_foreach_node(&psContext->sSyncCheckpointBlockListHead, psNode1, psNext1) - { - SYNC_CHECKPOINT_BLOCK *psSyncBlk = - IMG_CONTAINER_OF(psNode1, SYNC_CHECKPOINT_BLOCK, sListNode); - DevmemPDumpLoadMem(psSyncBlk->hMemDesc, - 0, - psSyncBlk->ui32SyncBlockSize, - PDUMP_FLAGS_CONTINUOUS); - } - OSLockRelease(psContext->hSyncCheckpointBlockListLock); - } - OSLockRelease(psDevNode->hSyncCheckpointContextListLock); - } - - return PVRSRV_OK; -} -#endif - -static void _CheckDeferredCleanupList(_SYNC_CHECKPOINT_CONTEXT *psContext) -{ - _SYNC_CHECKPOINT_CONTEXT_CTL *const psCtxCtl = psContext->psContextCtl; - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE*)psContext->psDevNode; - DECLARE_DLLIST(sCleanupList); - DLLIST_NODE *psNode, *psNext; - OS_SPINLOCK_FLAGS uiFlags; - -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s called", __func__)); -#endif - - /* Check the deferred cleanup list and free any sync checkpoints we can */ - OSSpinLockAcquire(psCtxCtl->hDeferredCleanupListLock, uiFlags); - - if (dllist_is_empty(&psCtxCtl->sDeferredCleanupListHead)) - { - OSSpinLockRelease(psCtxCtl->hDeferredCleanupListLock, uiFlags); -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s: Defer free list is empty", __func__)); -#endif - /* if list is empty then we have nothing to do here */ - return; - } - - dllist_foreach_node(&psCtxCtl->sDeferredCleanupListHead, psNode, psNext) - { - SYNC_CHECKPOINT *psSyncCheckpointInt = - IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sDeferredFreeListNode); - - if (psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount == - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount))) - { - if ((GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - && psSyncCheckpointInt->hRecord) - { - PVRSRV_ERROR eError; - /* remove this sync record */ - eError = _SyncCheckpointRecordRemove(psSyncCheckpointInt->hRecord); - PVR_LOG_IF_ERROR(eError, "_SyncCheckpointRecordRemove"); - } - - /* Move the sync checkpoint from the deferred free list to local list */ - dllist_remove_node(&psSyncCheckpointInt->sDeferredFreeListNode); - /* It's not an ideal solution to traverse list of checkpoints-to-free - * twice but it allows us to avoid holding the lock for too long */ - dllist_add_to_tail(&sCleanupList, &psSyncCheckpointInt->sDeferredFreeListNode); - } -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - else - { - PVR_DPF((PVR_DBG_WARNING, "%s psSyncCheckpoint '%s'' (ID:%d)<%p>), " - "still pending (enq=%d,FWRef=%d)", __func__, - psSyncCheckpointInt->azName, psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpointInt, - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount)), - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount)); - } -#endif - } - - OSSpinLockRelease(psCtxCtl->hDeferredCleanupListLock, uiFlags); - - dllist_foreach_node(&sCleanupList, psNode, psNext) { - SYNC_CHECKPOINT *psSyncCheckpointInt = - IMG_CONTAINER_OF(psNode, SYNC_CHECKPOINT, sDeferredFreeListNode); - - /* Remove the sync checkpoint from the global list */ - OSSpinLockAcquire(psDevNode->hSyncCheckpointListLock, uiFlags); - dllist_remove_node(&psSyncCheckpointInt->sListNode); - OSSpinLockRelease(psDevNode->hSyncCheckpointListLock, uiFlags); - - RGXSRV_HWPERF_FREE(psDevNode, SYNC_CP, psSyncCheckpointInt->ui32FWAddr); - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s attempting to return sync(ID:%d),%p> to pool", - __func__, - psSyncCheckpointInt->ui32UID, - (void *) psSyncCheckpointInt)); -#endif - if (!_PutCheckpointInPool(psSyncCheckpointInt)) -#endif - { -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s pool is full, so just free it", - __func__)); -#endif -#endif -#if (ENABLE_SYNC_CHECKPOINT_DEFERRED_CLEANUP_DEBUG == 1) - else - { - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint '%s'' (ID:%d)<%p>), still pending (enq=%d,FWRef=%d)", - __func__, - psSyncCheckpointInt->azName, - psSyncCheckpointInt->ui32UID, - (void*)psSyncCheckpointInt, - (IMG_UINT32)(OSAtomicRead(&psSyncCheckpointInt->hEnqueuedCCBCount)), - psSyncCheckpointInt->psSyncCheckpointFwObj->ui32FwRefCount)); -#endif - _FreeSyncCheckpoint(psSyncCheckpointInt); - } - } -} - -#if (SYNC_CHECKPOINT_POOL_SIZE > 0) -static SYNC_CHECKPOINT *_GetCheckpointFromPool(_SYNC_CHECKPOINT_CONTEXT *psContext) -{ - _SYNC_CHECKPOINT_CONTEXT_CTL *const psCtxCtl = psContext->psContextCtl; - SYNC_CHECKPOINT *psSyncCheckpoint = NULL; - OS_SPINLOCK_FLAGS uiFlags; - - /* Acquire sync checkpoint pool lock */ - OSSpinLockAcquire(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - /* Check if we can allocate from the pool */ - if (psCtxCtl->bSyncCheckpointPoolValid && - (psCtxCtl->ui32SyncCheckpointPoolCount > SYNC_CHECKPOINT_POOL_SEDIMENT) && - (psCtxCtl->ui32SyncCheckpointPoolWp != psCtxCtl->ui32SyncCheckpointPoolRp)) - { - /* Get the next sync checkpoint from the pool */ - psSyncCheckpoint = psCtxCtl->psSyncCheckpointPool[psCtxCtl->ui32SyncCheckpointPoolRp]; - psCtxCtl->ui32SyncCheckpointPoolRp = - (psCtxCtl->ui32SyncCheckpointPoolRp + 1) & SYNC_CHECKPOINT_POOL_MASK; - psCtxCtl->ui32SyncCheckpointPoolCount--; - psCtxCtl->bSyncCheckpointPoolFull = IMG_FALSE; - psSyncCheckpoint->ui32ValidationCheck = SYNC_CHECKPOINT_PATTERN_IN_USE; -#if (ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s checkpoint(old ID:%d)<-POOL(%d/%d), psContext=<%p>, " - "poolRp=%d, poolWp=%d", - __func__, - psSyncCheckpoint->ui32UID, - psCtxCtl->ui32SyncCheckpointPoolCount, - SYNC_CHECKPOINT_POOL_SIZE, - (void *) psContext, - psCtxCtl->ui32SyncCheckpointPoolRp, - psCtxCtl->ui32SyncCheckpointPoolWp)); -#endif - } - /* Release sync checkpoint pool lock */ - OSSpinLockRelease(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - return psSyncCheckpoint; -} - -static IMG_BOOL _PutCheckpointInPool(SYNC_CHECKPOINT *psSyncCheckpoint) -{ - _SYNC_CHECKPOINT_CONTEXT *psContext = psSyncCheckpoint->psSyncCheckpointBlock->psContext; - _SYNC_CHECKPOINT_CONTEXT_CTL *const psCtxCtl = psContext->psContextCtl; - IMG_BOOL bReturnedToPool = IMG_FALSE; - OS_SPINLOCK_FLAGS uiFlags; - - /* Acquire sync checkpoint pool lock */ - OSSpinLockAcquire(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - /* Check if pool has space */ - if (psCtxCtl->bSyncCheckpointPoolValid && !psCtxCtl->bSyncCheckpointPoolFull) - { - /* Put the sync checkpoint into the next write slot in the pool */ - psCtxCtl->psSyncCheckpointPool[psCtxCtl->ui32SyncCheckpointPoolWp] = psSyncCheckpoint; - psCtxCtl->ui32SyncCheckpointPoolWp = - (psCtxCtl->ui32SyncCheckpointPoolWp + 1) & SYNC_CHECKPOINT_POOL_MASK; - psCtxCtl->ui32SyncCheckpointPoolCount++; - psCtxCtl->bSyncCheckpointPoolFull = - ((psCtxCtl->ui32SyncCheckpointPoolCount > 0) && - (psCtxCtl->ui32SyncCheckpointPoolWp == psCtxCtl->ui32SyncCheckpointPoolRp)); - bReturnedToPool = IMG_TRUE; - psSyncCheckpoint->psSyncCheckpointFwObj->ui32State = PVRSRV_SYNC_CHECKPOINT_UNDEF; - psSyncCheckpoint->ui32ValidationCheck = SYNC_CHECKPOINT_PATTERN_IN_POOL; -#if (ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, - "%s checkpoint(ID:%d)->POOL(%d/%d), poolRp=%d, poolWp=%d", - __func__, - psSyncCheckpoint->ui32UID, - psCtxCtl->ui32SyncCheckpointPoolCount, - SYNC_CHECKPOINT_POOL_SIZE, - psCtxCtl->ui32SyncCheckpointPoolRp, - psCtxCtl->ui32SyncCheckpointPoolWp)); -#endif - } - /* Release sync checkpoint pool lock */ - OSSpinLockRelease(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - return bReturnedToPool; -} - -static IMG_UINT32 _CleanCheckpointPool(_SYNC_CHECKPOINT_CONTEXT *psContext) -{ - _SYNC_CHECKPOINT_CONTEXT_CTL *const psCtxCtl = psContext->psContextCtl; - SYNC_CHECKPOINT *psCheckpoint = NULL; - DECLARE_DLLIST(sCleanupList); - DLLIST_NODE *psThis, *psNext; - OS_SPINLOCK_FLAGS uiFlags; - IMG_UINT32 ui32ItemsFreed = 0, ui32NullScpCount = 0, __maybe_unused ui32PoolCount; - IMG_BOOL bPoolValid; - - /* Acquire sync checkpoint pool lock */ - OSSpinLockAcquire(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - bPoolValid = psCtxCtl->bSyncCheckpointPoolValid; - ui32PoolCount = psCtxCtl->ui32SyncCheckpointPoolCount; - - /* While the pool still contains sync checkpoints, free them */ - while (bPoolValid && psCtxCtl->ui32SyncCheckpointPoolCount > 0) - { - /* Get the sync checkpoint from the next read slot in the pool */ - psCheckpoint = psCtxCtl->psSyncCheckpointPool[psCtxCtl->ui32SyncCheckpointPoolRp]; - psCtxCtl->ui32SyncCheckpointPoolRp = - (psCtxCtl->ui32SyncCheckpointPoolRp + 1) & SYNC_CHECKPOINT_POOL_MASK; - psCtxCtl->ui32SyncCheckpointPoolCount--; - psCtxCtl->bSyncCheckpointPoolFull = - ((psCtxCtl->ui32SyncCheckpointPoolCount > 0) && - (psCtxCtl->ui32SyncCheckpointPoolWp == psCtxCtl->ui32SyncCheckpointPoolRp)); - - if (psCheckpoint) - { - PVR_ASSERT(!dllist_node_is_in_list(&psCheckpoint->sListNode)); - /* before checkpoints are added to the pool they are removed - * from the list so it's safe to use sListNode here */ - dllist_add_to_head(&sCleanupList, &psCheckpoint->sListNode); - } - else - { - ui32NullScpCount++; - } - } - - /* Release sync checkpoint pool lock */ - OSSpinLockRelease(psCtxCtl->hSyncCheckpointPoolLock, uiFlags); - - /* go through the local list and free all of the sync checkpoints */ - -#if (ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) - PVR_DPF((PVR_DBG_WARNING, "%s psContext=<%p>, bSyncCheckpointPoolValid=%d, " - "uiSyncCheckpointPoolCount=%d", __func__, (void *) psContext, - bPoolValid, ui32PoolCount)); - - if (ui32NullScpCount > 0) - { - PVR_DPF((PVR_DBG_WARNING, "%s pool contained %u NULL entries", __func__, - ui32NullScpCount)); - } -#endif - - dllist_foreach_node(&sCleanupList, psThis, psNext) - { - psCheckpoint = IMG_CONTAINER_OF(psThis, SYNC_CHECKPOINT, sListNode); - -#if (ENABLE_SYNC_CHECKPOINT_POOL_DEBUG == 1) - if (psCheckpoint->ui32ValidationCheck != SYNC_CHECKPOINT_PATTERN_IN_POOL) - { - PVR_DPF((PVR_DBG_WARNING, "%s pool contains invalid entry " - "(ui32ValidationCheck=0x%x)", __func__, - psCheckpoint->ui32ValidationCheck)); - } - - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint(ID:%d)", - __func__, psCheckpoint->ui32UID)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint->ui32ValidationCheck=0x%x", - __func__, psCheckpoint->ui32ValidationCheck)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint->uiSpanAddr=0x%llx", - __func__, psCheckpoint->uiSpanAddr)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint->psSyncCheckpointBlock=<%p>", - __func__, (void *) psCheckpoint->psSyncCheckpointBlock)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint->psSyncCheckpointBlock->psContext=<%p>", - __func__, (void *) psCheckpoint->psSyncCheckpointBlock->psContext)); - PVR_DPF((PVR_DBG_WARNING, - "%s psSyncCheckpoint->psSyncCheckpointBlock->psContext->psSubAllocRA=<%p>", - __func__, (void *) psCheckpoint->psSyncCheckpointBlock->psContext->psSubAllocRA)); - - PVR_DPF((PVR_DBG_WARNING, - "%s CALLING RA_Free(psSyncCheckpoint(ID:%d)<%p>), " - "psSubAllocRA=<%p>, ui32SpanAddr=0x%llx", - __func__, - psCheckpoint->ui32UID, - (void *) psCheckpoint, - (void *) psCheckpoint->psSyncCheckpointBlock->psContext->psSubAllocRA, - psCheckpoint->uiSpanAddr)); -#endif - - dllist_remove_node(psThis); - - _FreeSyncCheckpoint(psCheckpoint); - ui32ItemsFreed++; - } - - return ui32ItemsFreed; -} -#endif /* (SYNC_CHECKPOINT_POOL_SIZE > 0) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.h b/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.h deleted file mode 100644 index 33c26f4208625..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint.h +++ /dev/null @@ -1,666 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Synchronisation checkpoint interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the client side interface for synchronisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_CHECKPOINT_H -#define SYNC_CHECKPOINT_H - -#include "img_types.h" -#include "pvrsrv_error.h" -#include "pvrsrv_sync_km.h" -#include "pdumpdefs.h" -#include "pdump.h" -#include "dllist.h" -#include "pvr_debug.h" -#include "device_connection.h" -#include "opaque_types.h" - -#ifndef CHECKPOINT_TYPES -#define CHECKPOINT_TYPES -typedef struct SYNC_CHECKPOINT_CONTEXT_TAG *PSYNC_CHECKPOINT_CONTEXT; - -typedef struct SYNC_CHECKPOINT_TAG *PSYNC_CHECKPOINT; -#endif - -/* definitions for functions to be implemented by OS-specific sync - the OS-specific sync code - will call SyncCheckpointRegisterFunctions() when initialised, in order to register functions - we can then call */ -#ifndef CHECKPOINT_PFNS -#define CHECKPOINT_PFNS -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_RESOLVE_FN)(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE fence, - IMG_UINT32 *nr_checkpoints, - PSYNC_CHECKPOINT **checkpoint_handles, - IMG_UINT64 *pui64FenceUID); -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_CREATE_FN)(PPVRSRV_DEVICE_NODE device, - const IMG_CHAR *fence_name, - PVRSRV_TIMELINE timeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *new_fence, - IMG_UINT64 *pui64FenceUID, - void **ppvFenceFinaliseData, - PSYNC_CHECKPOINT *new_checkpoint_handle, - IMG_HANDLE *timeline_update_sync, - IMG_UINT32 *timeline_update_value); -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_ROLLBACK_DATA_FN)(PVRSRV_FENCE fence_to_rollback, void *finalise_data); -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_FINALISE_FN)(PVRSRV_FENCE fence_to_finalise, void *finalise_data); -typedef void (*PFN_SYNC_CHECKPOINT_NOHW_UPDATE_TIMELINES_FN)(void *private_data); -typedef void (*PFN_SYNC_CHECKPOINT_FREE_CHECKPOINT_LIST_MEM_FN)(void *mem_ptr); -typedef IMG_UINT32 (*PFN_SYNC_CHECKPOINT_DUMP_INFO_ON_STALLED_UFOS_FN)(IMG_UINT32 num_ufos, IMG_UINT32 *vaddrs); -#if defined(PDUMP) -typedef PVRSRV_ERROR (*PFN_SYNC_CHECKPOINT_FENCE_GETCHECKPOINTS_FN)(PVRSRV_FENCE iFence, - IMG_UINT32 *puiNumCheckpoints, - PSYNC_CHECKPOINT **papsCheckpoints); -#endif - -#define SYNC_CHECKPOINT_IMPL_MAX_STRLEN 20 - -typedef struct -{ - PFN_SYNC_CHECKPOINT_FENCE_RESOLVE_FN pfnFenceResolve; - PFN_SYNC_CHECKPOINT_FENCE_CREATE_FN pfnFenceCreate; - PFN_SYNC_CHECKPOINT_FENCE_ROLLBACK_DATA_FN pfnFenceDataRollback; - PFN_SYNC_CHECKPOINT_FENCE_FINALISE_FN pfnFenceFinalise; - PFN_SYNC_CHECKPOINT_NOHW_UPDATE_TIMELINES_FN pfnNoHWUpdateTimelines; - PFN_SYNC_CHECKPOINT_FREE_CHECKPOINT_LIST_MEM_FN pfnFreeCheckpointListMem; - PFN_SYNC_CHECKPOINT_DUMP_INFO_ON_STALLED_UFOS_FN pfnDumpInfoOnStalledUFOs; - IMG_CHAR pszImplName[SYNC_CHECKPOINT_IMPL_MAX_STRLEN]; -#if defined(PDUMP) - PFN_SYNC_CHECKPOINT_FENCE_GETCHECKPOINTS_FN pfnSyncFenceGetCheckpoints; -#endif -} PFN_SYNC_CHECKPOINT_STRUCT; - -PVRSRV_ERROR SyncCheckpointRegisterFunctions(PFN_SYNC_CHECKPOINT_STRUCT *psSyncCheckpointPfns); - -#endif /* ifndef CHECKPOINT_PFNS */ - -/*************************************************************************/ /*! -@Function SyncCheckpointContextCreate - -@Description Create a new synchronisation checkpoint context - -@Input psDevNode Device node - -@Output ppsSyncCheckpointContext Handle to the created synchronisation - checkpoint context - -@Return PVRSRV_OK if the synchronisation checkpoint context was - successfully created -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointContextCreate(PPVRSRV_DEVICE_NODE psDevNode, - PSYNC_CHECKPOINT_CONTEXT *ppsSyncCheckpointContext); - -/*************************************************************************/ /*! -@Function SyncCheckpointContextDestroy - -@Description Destroy a synchronisation checkpoint context - -@Input psSyncCheckpointContext Handle to the synchronisation - checkpoint context to destroy - -@Return PVRSRV_OK if the synchronisation checkpoint context was - successfully destroyed. - PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT if the context still - has sync checkpoints defined -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointContextDestroy(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext); - -/*************************************************************************/ /*! -@Function SyncCheckpointContextRef - -@Description Takes a reference on a synchronisation checkpoint context - -@Input psContext Handle to the synchronisation checkpoint context - on which a ref is to be taken - -@Return None -*/ -/*****************************************************************************/ -void SyncCheckpointContextRef(PSYNC_CHECKPOINT_CONTEXT psContext); - -/*************************************************************************/ /*! -@Function SyncCheckpointContextUnref - -@Description Drops a reference taken on a synchronisation checkpoint - context - -@Input psContext Handle to the synchronisation checkpoint context - on which the ref is to be dropped - -@Return None -*/ -/*****************************************************************************/ -void SyncCheckpointContextUnref(PSYNC_CHECKPOINT_CONTEXT psContext); - -/*************************************************************************/ /*! -@Function SyncCheckpointAlloc - -@Description Allocate a new synchronisation checkpoint on the specified - synchronisation checkpoint context - -@Input hSyncCheckpointContext Handle to the synchronisation - checkpoint context - -@Input hTimeline Timeline on which this sync - checkpoint is being created - -@Input hFence Fence as passed into pfnFenceResolve - API, when the API encounters a non-PVR - fence as part of its input fence. From - all other places this argument must be - PVRSRV_NO_FENCE. - -@Input pszClassName Sync checkpoint source annotation - (will be truncated to at most - PVRSRV_SYNC_NAME_LENGTH chars) - -@Output ppsSyncCheckpoint Created synchronisation checkpoint - -@Return PVRSRV_OK if the synchronisation checkpoint was - successfully created -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointAlloc(PSYNC_CHECKPOINT_CONTEXT psSyncContext, - PVRSRV_TIMELINE hTimeline, - PVRSRV_FENCE hFence, - const IMG_CHAR *pszCheckpointName, - PSYNC_CHECKPOINT *ppsSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointFree - -@Description Free a synchronisation checkpoint - The reference count held for the synchronisation checkpoint - is decremented - if it has becomes zero, it is also freed. - -@Input psSyncCheckpoint The synchronisation checkpoint to free - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointFree(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointSignal - -@Description Signal the synchronisation checkpoint - -@Input psSyncCheckpoint The synchronisation checkpoint to signal - -@Input ui32FenceSyncFlags Flags used for controlling HWPerf behavior - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointSignal(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointSignalNoHW - -@Description Signal the synchronisation checkpoint in NO_HARWARE build - -@Input psSyncCheckpoint The synchronisation checkpoint to signal - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointSignalNoHW(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointError - -@Description Error the synchronisation checkpoint - -@Input psSyncCheckpoint The synchronisation checkpoint to error - -@Input ui32FenceSyncFlags Flags used for controlling HWPerf behavior - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointError(PSYNC_CHECKPOINT psSyncCheckpoint, IMG_UINT32 ui32FenceSyncFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointStateFromUFO - -@Description Returns the current state of the synchronisation checkpoint - which has the given UFO firmware address - -@Input psDevNode The device owning the sync - checkpoint - -@Input ui32FwAddr The firmware address of the sync - checkpoint - -@Return The current state (32-bit value) of the sync checkpoint -*/ -/*****************************************************************************/ -IMG_UINT32 SyncCheckpointStateFromUFO(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32FwAddr); - -/*************************************************************************/ /*! -@Function SyncCheckpointErrorFromUFO - -@Description Error the synchronisation checkpoint which has the - given UFO firmware address - -@Input psDevNode The device owning the sync - checkpoint to be errored - -@Input ui32FwAddr The firmware address of the sync - checkpoint to be errored - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointErrorFromUFO(PPVRSRV_DEVICE_NODE psDevNode, IMG_UINT32 ui32FwAddr); - -/*************************************************************************/ /*! -@Function SyncCheckpointRollbackFromUFO - -@Description Drop the enqueued count reference taken on the synchronisation - checkpoint on behalf of the firmware. - Called in the event of a DM Kick failing. - -@Input psDevNode The device owning the sync - checkpoint to be rolled back - -@Input ui32FwAddr The firmware address of the sync - checkpoint to be rolled back - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointRollbackFromUFO(PPVRSRV_DEVICE_NODE psDevNode, IMG_UINT32 ui32FwAddr); - -/*************************************************************************/ /*! -@Function SyncCheckpointIsSignalled - -@Description Returns IMG_TRUE if the synchronisation checkpoint is - signalled or errored - -@Input psSyncCheckpoint The synchronisation checkpoint to test - -@Input ui32FenceSyncFlags Flags used for controlling HWPerf behavior - -@Return None -*/ -/*****************************************************************************/ -IMG_BOOL -SyncCheckpointIsSignalled(PSYNC_CHECKPOINT psSyncCheckpoint, - IMG_UINT32 ui32FenceSyncFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointIsErrored - -@Description Returns IMG_TRUE if the synchronisation checkpoint is - errored - -@Input psSyncCheckpoint The synchronisation checkpoint to test - -@Input ui32FenceSyncFlags Flags used for controlling HWPerf behavior - -@Return None -*/ -/*****************************************************************************/ -IMG_BOOL -SyncCheckpointIsErrored(PSYNC_CHECKPOINT psSyncCheckpoint, - IMG_UINT32 ui32FenceSyncFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointTakeRef - -@Description Take a reference on a synchronisation checkpoint - -@Input psSyncCheckpoint Synchronisation checkpoint to take a - reference on - -@Return PVRSRV_OK if a reference was taken on the synchronisation - primitive -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointTakeRef(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointDropRef - -@Description Drop a reference on a synchronisation checkpoint - -@Input psSyncCheckpoint Synchronisation checkpoint to drop a - reference on - -@Return PVRSRV_OK if a reference was dropped on the synchronisation - primitive -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointDropRef(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointResolveFence - -@Description Resolve a fence, returning a list of the sync checkpoints - that fence contains. - This function in turn calls a function provided by the - OS native sync implementation. - -@Input psSyncCheckpointContext The sync checkpoint context - on which checkpoints should be - created (in the event of the fence - having a native sync pt with no - associated sync checkpoint) - -@Input hFence The fence to be resolved - -@Output pui32NumSyncCheckpoints The number of sync checkpoints the - fence contains. Can return 0 if - passed a null (-1) fence. - -@Output papsSyncCheckpoints List of sync checkpoints the fence - contains - -@Output puiFenceUID Unique ID of the resolved fence - -@Return PVRSRV_OK if a valid fence was provided. - PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function. -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointResolveFence(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE hFence, - IMG_UINT32 *pui32NumSyncCheckpoints, - PSYNC_CHECKPOINT **papsSyncCheckpoints, - IMG_UINT64 *puiFenceUID, - PDUMP_FLAGS_T ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointCreateFence - -@Description Create a fence containing a single sync checkpoint. - Return the fence and a ptr to sync checkpoint it contains. - This function in turn calls a function provided by the - OS native sync implementation. - -@Input pszFenceName String to assign to the new fence - (for debugging purposes) - -@Input hTimeline Timeline on which the new fence is - to be created - -@Input psSyncCheckpointContext Sync checkpoint context to be used - when creating the new fence - -@Output phNewFence The newly created fence - -@Output pui64FenceUID Unique ID of the created fence - -@Output ppvFenceFinaliseData Any data needed to finalise the fence - in a later call to the function - SyncCheckpointFinaliseFence() - -@Output psNewSyncCheckpoint The sync checkpoint contained in - the new fence - -@Return PVRSRV_OK if a valid fence was provided. - PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function. -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointCreateFence(PPVRSRV_DEVICE_NODE psDeviceNode, - const IMG_CHAR *pszFenceName, - PVRSRV_TIMELINE hTimeline, - PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext, - PVRSRV_FENCE *phNewFence, - IMG_UINT64 *pui64FenceUID, - void **ppvFenceFinaliseData, - PSYNC_CHECKPOINT *psNewSyncCheckpoint, - void **ppvTimelineUpdateSyncPrim, - IMG_UINT32 *pui32TimelineUpdateValue, - PDUMP_FLAGS_T ui32PDumpFlags); - -/*************************************************************************/ /*! -@Function SyncCheckpointRollbackFenceData - -@Description 'Rolls back' the fence specified (destroys the fence and - takes any other required actions to undo the fence - creation (eg if the implementation wishes to revert the - incrementing of the fence's timeline, etc). - This function in turn calls a function provided by the - OS native sync implementation. - -@Input hFence Fence to be 'rolled back' - -@Input pvFinaliseData Data needed to finalise the - fence - -@Return PVRSRV_OK if a valid fence was provided. - PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function. -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointRollbackFenceData(PVRSRV_FENCE hFence, void *pvFinaliseData); - -/*************************************************************************/ /*! -@Function SyncCheckpointFinaliseFence - -@Description 'Finalise' the fence specified (performs any actions the - underlying implementation may need to perform just prior - to the fence being returned to the client. - This function in turn calls a function provided by the - OS native sync implementation - if the native sync - implementation does not need to perform any actions at - this time, this function does not need to be registered. - -@Input psDevNode Device node - -@Input hFence Fence to be 'finalised' - -@Input pvFinaliseData Data needed to finalise the fence - -@Input psSyncCheckpoint Base sync checkpoint that this fence - is formed of - -@Input pszName Fence annotation - -@Return PVRSRV_OK if a valid fence and finalise data were provided. - PVRSRV_ERROR_INVALID_PARAMS if an invalid fence or finalise - data were provided. - PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function (permitted). -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointFinaliseFence(PPVRSRV_DEVICE_NODE psDevNode, - PVRSRV_FENCE hFence, - void *pvFinaliseData, - PSYNC_CHECKPOINT psSyncCheckpoint, - const IMG_CHAR *pszName); - -/*************************************************************************/ /*! -@Function SyncCheckpointFreeCheckpointListMem - -@Description Free memory the memory which was allocated by the sync - implementation and used to return the list of sync - checkpoints when resolving a fence. - to the fence being returned to the client. - This function in turn calls a free function registered by - the sync implementation (if a function has been registered). - -@Input pvCheckpointListMem Pointer to the memory to be freed - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointFreeCheckpointListMem(void *pvCheckpointListMem); - -/*************************************************************************/ /*! -@Function SyncCheckpointNoHWUpdateTimelines - -@Description Called by the DDK in a NO_HARDWARE build only. - After syncs have been manually signalled by the DDK, this - function is called to allow the OS native sync implementation - to update its timelines (as the usual callback notification - of signalled checkpoints is not supported for NO_HARDWARE). - This function in turn calls a function provided by the - OS native sync implementation. - -@Input pvPrivateData Any data the OS native sync - implementation might require. - -@Return PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function, otherwise - PVRSRV_OK. -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointNoHWUpdateTimelines(void *pvPrivateData); - -/*************************************************************************/ /*! -@Function SyncCheckpointDumpInfoOnStalledUFOs - -@Description Called by the DDK in the event of the health check watchdog - examining the CCBs and determining that one has failed to - progress after 10 second when the GPU is idle due to waiting - on one or more UFO fences. - The DDK will pass a list of UFOs on which the CCB is waiting - and the sync implementation will check them to see if any - relate to sync points it has created. If so, the - implementation should dump debug information on those sync - points to the kernel log or other suitable output (which will - allow the unsignalled syncs to be identified). - The function shall return the number of syncs in the provided - array that were syncs which it had created. - -@Input ui32NumUFOs The number of UFOs in the array passed - in the pui32VAddrs parameter. - pui32Vaddr The array of UFOs the CCB is waiting on. - -@Output pui32NumSyncOwnedUFOs The number of UFOs in pui32Vaddr which - relate to syncs created by the sync - implementation. - -@Return PVRSRV_OK if a valid pointer is provided in pui32NumSyncOwnedUFOs. - PVRSRV_ERROR_INVALID_PARAMS if a NULL value is provided in - pui32NumSyncOwnedUFOs. - PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED if the OS native - sync has not registered a callback function. - -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointDumpInfoOnStalledUFOs(IMG_UINT32 ui32NumUFOs, - IMG_UINT32 *pui32Vaddrs, - IMG_UINT32 *pui32NumSyncOwnedUFOs); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetStateString - -@Description Called to get a string representing the current state of a - sync checkpoint. - -@Input psSyncCheckpoint Synchronisation checkpoint to get the - state for. - -@Return The string representing the current state of this checkpoint -*/ -/*****************************************************************************/ -const IMG_CHAR * -SyncCheckpointGetStateString(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointRecordLookup - -@Description Returns a debug string with information about the - sync checkpoint. - -@Input psDevNode The device owning the sync - checkpoint to lookup - -@Input ui32FwAddr The firmware address of the sync - checkpoint to lookup - -@Input pszSyncInfo Character array to write to - -@Input len Len of the character array - -@Return None -*/ -/*****************************************************************************/ -void -SyncCheckpointRecordLookup(PPVRSRV_DEVICE_NODE psDevNode, - IMG_UINT32 ui32FwAddr, - IMG_CHAR * pszSyncInfo, size_t len); - -#if defined(PDUMP) -/*************************************************************************/ /*! -@Function PVRSRVSyncCheckpointFencePDumpPolKM - -@Description Called to insert a poll into the PDump script on a given - Fence being signalled or errored. - -@Input hFence Fence for PDump to poll on - -@Return PVRSRV_OK if a valid sync checkpoint was provided. -*/ -/*****************************************************************************/ - -PVRSRV_ERROR PVRSRVSyncCheckpointSignalledPDumpPolKM(PVRSRV_FENCE hFence); - -#endif - -#endif /* SYNC_CHECKPOINT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_external.h b/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_external.h deleted file mode 100644 index 19b5011aa8b75..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_external.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services external synchronisation checkpoint interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines synchronisation checkpoint structures that are visible - internally and externally -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_CHECKPOINT_EXTERNAL_H -#define SYNC_CHECKPOINT_EXTERNAL_H - -#include "img_types.h" - -#ifndef CHECKPOINT_TYPES -#define CHECKPOINT_TYPES -typedef struct SYNC_CHECKPOINT_CONTEXT_TAG *PSYNC_CHECKPOINT_CONTEXT; - -typedef struct SYNC_CHECKPOINT_TAG *PSYNC_CHECKPOINT; -#endif - -/* PVRSRV_SYNC_CHECKPOINT states. - * The OS native sync implementation should call pfnIsSignalled() to determine if a - * PVRSRV_SYNC_CHECKPOINT has signalled (which will return an IMG_BOOL), but can set the - * state for a PVRSRV_SYNC_CHECKPOINT (which is currently in the NOT_SIGNALLED state) - * where that PVRSRV_SYNC_CHECKPOINT is representing a foreign sync. - */ -typedef IMG_UINT32 PVRSRV_SYNC_CHECKPOINT_STATE; - -#define PVRSRV_SYNC_CHECKPOINT_UNDEF 0x000U -#define PVRSRV_SYNC_CHECKPOINT_ACTIVE 0xac1U /*!< checkpoint has not signalled */ -#define PVRSRV_SYNC_CHECKPOINT_SIGNALLED 0x519U /*!< checkpoint has signalled */ -#define PVRSRV_SYNC_CHECKPOINT_ERRORED 0xeffU /*!< checkpoint has been errored */ - - -#define PVRSRV_UFO_IS_SYNC_CHECKPOINT_FWADDR(fwaddr) (((fwaddr) & 0x1U) != 0U) -#define PVRSRV_UFO_IS_SYNC_CHECKPOINT(ufoptr) (PVRSRV_UFO_IS_SYNC_CHECKPOINT_FWADDR((ufoptr)->puiAddrUFO.ui32Addr)) - -/* Maximum number of sync checkpoints the firmware supports in one fence */ -#define MAX_SYNC_CHECKPOINTS_PER_FENCE 32U - -/*! - * Define to be used with SyncCheckpointAlloc() to indicate a checkpoint which - * represents a foreign sync point or collection of foreign sync points. - */ -#define SYNC_CHECKPOINT_FOREIGN_CHECKPOINT ((PVRSRV_TIMELINE) - 2U) - -#endif /* SYNC_CHECKPOINT_EXTERNAL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_init.h b/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_init.h deleted file mode 100644 index 94f2e000ded92..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_init.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services synchronisation checkpoint initialisation interface - header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines synchronisation checkpoint structures that are visible - internally and externally -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_CHECKPOINT_INIT_H -#define SYNC_CHECKPOINT_INIT_H - -#include "device.h" - -/*************************************************************************/ /*! -@Function SyncCheckpointInit - -@Description Initialise the sync checkpoint driver by giving it the - device node (needed to determine the pfnUFOAlloc function - to call in order to allocate sync block memory). - -@Input psDevNode Device for which sync checkpoints - are being initialised - -@Return PVRSRV_OK initialised successfully, - PVRSRV_ERROR_ otherwise -*/ -/*****************************************************************************/ -PVRSRV_ERROR -SyncCheckpointInit(PVRSRV_DEVICE_NODE *psDevNode); - -/*************************************************************************/ /*! -@Function SyncCheckpointDeinit - -@Description Deinitialise the sync checkpoint driver. - Frees resources allocated during initialisation. - -@Input psDevNode Device for which sync checkpoints - are being de-initialised - -@Return None -*/ -/*****************************************************************************/ -void SyncCheckpointDeinit(PVRSRV_DEVICE_NODE *psDevNode); - -#endif /* SYNC_CHECKPOINT_INIT_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_internal.h b/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_internal.h deleted file mode 100644 index ce178474112c0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_checkpoint_internal.h +++ /dev/null @@ -1,288 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services internal synchronisation checkpoint interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the internal server interface for services - synchronisation checkpoints. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_CHECKPOINT_INTERNAL_H -#define SYNC_CHECKPOINT_INTERNAL_H - -#include "img_types.h" -#include "opaque_types.h" -#include "sync_checkpoint_external.h" -#include "sync_checkpoint.h" -#include "ra.h" -#include "dllist.h" -#include "lock.h" -#include "devicemem.h" -#include "rgx_fwif_shared.h" -#include "rgx_fwif_km.h" - -struct SYNC_CHECKPOINT_RECORD; - -/* - Private structures -*/ - -typedef struct _SYNC_CHECKPOINT_CONTEXT_CTL_ _SYNC_CHECKPOINT_CONTEXT_CTL, *_PSYNC_CHECKPOINT_CONTEXT_CTL; - -typedef struct SYNC_CHECKPOINT_CONTEXT_TAG -{ - PPVRSRV_DEVICE_NODE psDevNode; - IMG_CHAR azName[PVRSRV_SYNC_NAME_LENGTH]; /*!< Name of the RA */ - RA_ARENA *psSubAllocRA; /*!< RA context */ - IMG_CHAR azSpanName[PVRSRV_SYNC_NAME_LENGTH]; /*!< Name of the span RA */ - RA_ARENA *psSpanRA; /*!< RA used for span management of SubAllocRA */ - ATOMIC_T hRefCount; /*!< Ref count for this context */ - ATOMIC_T hCheckpointCount; /*!< Checkpoint count for this context */ - POS_LOCK hLock; - _PSYNC_CHECKPOINT_CONTEXT_CTL psContextCtl; -#if defined(PDUMP) - DLLIST_NODE sSyncCheckpointBlockListHead; /*!< List head for the sync chkpt blocks in this context*/ - POS_LOCK hSyncCheckpointBlockListLock; /*!< sync chkpt blocks list lock*/ - DLLIST_NODE sListNode; /*!< List node for the sync chkpt context list*/ -#endif -} _SYNC_CHECKPOINT_CONTEXT; - -typedef struct _SYNC_CHECKPOINT_BLOCK_ -{ - ATOMIC_T hRefCount; /*!< Ref count for this sync block */ - POS_LOCK hLock; - _SYNC_CHECKPOINT_CONTEXT *psContext; /*!< Our copy of the services connection */ - PPVRSRV_DEVICE_NODE psDevNode; - IMG_UINT32 ui32SyncBlockSize; /*!< Size of the sync checkpoint block */ - IMG_UINT32 ui32FirmwareAddr; /*!< Firmware address */ - DEVMEM_MEMDESC *hMemDesc; /*!< DevMem allocation for block */ - volatile IMG_UINT32 *pui32LinAddr; /*!< Server-code CPU mapping */ - IMG_UINT64 uiSpanBase; /*!< Base of this import (FW DevMem) in the span RA */ -#if defined(PDUMP) - DLLIST_NODE sListNode; /*!< List node for the sync chkpt blocks */ -#endif -} SYNC_CHECKPOINT_BLOCK; - -typedef struct SYNC_CHECKPOINT_RECORD* PSYNC_CHECKPOINT_RECORD_HANDLE; - -typedef struct SYNC_CHECKPOINT_TAG -{ - //_SYNC_CHECKPOINT_CONTEXT *psContext; /*!< pointer to the parent context of this checkpoint */ - /* A sync checkpoint is assigned a unique ID, to avoid any confusion should - * the same memory be re-used later for a different checkpoint - */ - IMG_UINT32 ui32UID; /*!< Unique ID assigned to sync checkpoint (to distinguish checkpoints if memory is re-used)*/ - ATOMIC_T hRefCount; /*!< Ref count for this sync */ - ATOMIC_T hEnqueuedCCBCount; /*!< Num times sync has been put in CCBs */ - SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock; /*!< Synchronisation block this checkpoint is allocated on */ - IMG_UINT64 uiSpanAddr; /*!< Span address of the sync */ - volatile SYNC_CHECKPOINT_FW_OBJ *psSyncCheckpointFwObj; /*!< CPU view of the data held in the sync block */ - PRGXFWIF_UFO_ADDR sCheckpointUFOAddr; /*!< PRGXFWIF_UFO_ADDR struct used to pass update address to FW */ - IMG_CHAR azName[PVRSRV_SYNC_NAME_LENGTH]; /*!< Name of the checkpoint */ - PVRSRV_TIMELINE hTimeline; /*!< Timeline on which this sync checkpoint was created */ - IMG_UINT32 ui32ValidationCheck; - IMG_PID uiProcess; /*!< The Process ID of the process which created this sync checkpoint */ - PSYNC_CHECKPOINT_RECORD_HANDLE hRecord; /*!< Sync record handle */ - DLLIST_NODE sListNode; /*!< List node for the global sync chkpt list */ - DLLIST_NODE sDeferredFreeListNode; /*!< List node for the deferred free sync chkpt list */ - IMG_UINT32 ui32FWAddr; /*!< FWAddr stored at sync checkpoint alloc time */ - PDUMP_FLAGS_T ui32PDumpFlags; /*!< Pdump Capture mode to be used for POL*/ -} SYNC_CHECKPOINT; - - -typedef struct _SYNC_CHECKPOINT_SIGNAL_ -{ - SYNC_CHECKPOINT asSyncCheckpoint; /*!< Store sync checkpt for deferred signal */ - IMG_UINT32 ui32Status; /*!< sync checkpt status signal/errored */ -} _SYNC_CHECKPOINT_DEFERRED_SIGNAL; - -#define GET_CP_CB_NEXT_IDX(_curridx) (((_curridx) + 1) % SYNC_CHECKPOINT_MAX_DEFERRED_SIGNAL) -#define GET_CP_CB_BASE(_idx) (IMG_OFFSET_ADDR(psDevNode->pui8DeferredSyncCPSignal, \ - ((_idx) * sizeof(_SYNC_CHECKPOINT_DEFERRED_SIGNAL)))) - - -/*************************************************************************/ /*! -@Function SyncCheckpointGetFirmwareAddr - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the firmware address of - -@Return The firmware address of the sync checkpoint - -*/ -/*****************************************************************************/ -IMG_UINT32 -SyncCheckpointGetFirmwareAddr(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointCCBEnqueued - -@Description Increment the CCB enqueued reference count for a - synchronisation checkpoint. This indicates how many FW - operations (checks/update) have been placed into CCBs for the - sync checkpoint. - When the FW services these operation, it increments its own - reference count. When these two values are equal, we know - there are not outstanding FW operating for the checkpoint - in any CCB. - -@Input psSyncCheckpoint Synchronisation checkpoint for which - to increment the enqueued reference - count - -@Return None - -*/ -/*****************************************************************************/ -void -SyncCheckpointCCBEnqueued(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetEnqueuedCount - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the enqueued count of - -@Return The enqueued count of the sync checkpoint - (i.e. the number of FW operations (checks or updates) - currently enqueued in CCBs for the sync checkpoint) - -*/ -/*****************************************************************************/ -IMG_UINT32 -SyncCheckpointGetEnqueuedCount(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetReferenceCount - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the reference count of - -@Return The host reference count of the sync checkpoint - -*/ -/*****************************************************************************/ -IMG_UINT32 -SyncCheckpointGetReferenceCount(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetCreator - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the creating process of - -@Return The process id of the process which created this sync checkpoint. - -*/ -/*****************************************************************************/ -IMG_PID -SyncCheckpointGetCreator(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetId - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the unique Id of - -@Return The unique Id of the sync checkpoint - -*/ -/*****************************************************************************/ -IMG_UINT32 -SyncCheckpointGetId(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetTimeline - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the parent timeline of - -@Return The parent timeline of the sync checkpoint - -*/ -/*****************************************************************************/ -PVRSRV_TIMELINE -SyncCheckpointGetTimeline(PSYNC_CHECKPOINT psSyncCheckpoint); - -/*************************************************************************/ /*! -@Function SyncCheckpointGetRGXFWIFUFOAddr - -@Description . - -@Input psSyncCheckpoint Synchronisation checkpoint to get - the PRGXFWIF_UFO_ADDR of - -@Return The PRGXFWIF_UFO_ADDR of the sync checkpoint, used when - providing the update in server kick code. - -*/ -/*****************************************************************************/ -PRGXFWIF_UFO_ADDR* -SyncCheckpointGetRGXFWIFUFOAddr(PSYNC_CHECKPOINT psSyncCheckpoint); - -#if !defined(SUPPORT_NATIVE_FENCE_SYNC) -/*************************************************************************/ /*! -@Function SyncCheckpointGetAssociatedDevice - -@Description . - -@Input psSyncCheckpointContext Synchronisation Checkpoint context - to get the device node of - -@Return The PVRSRV_DEVICE_NODE of the device on which the sync - checkpoint context was created. - -*/ -/*****************************************************************************/ -PPVRSRV_DEVICE_NODE -SyncCheckpointGetAssociatedDevice(PSYNC_CHECKPOINT_CONTEXT psSyncCheckpointContext); -#endif /* !defined(SUPPORT_NATIVE_FENCE_SYNC) */ - -#endif /* SYNC_CHECKPOINT_INTERNAL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_fallback_server.h b/drivers/gpu/drm/img-rogue/1.17/sync_fallback_server.h deleted file mode 100644 index ac6bd4755b0ee..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_fallback_server.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Fallback sync interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_FALLBACK_SERVER_H -#define SYNC_FALLBACK_SERVER_H - -#include "img_types.h" -#include "sync_checkpoint.h" -#include "device.h" -#include "connection_server.h" - - -typedef struct _PVRSRV_TIMELINE_SERVER_ PVRSRV_TIMELINE_SERVER; -typedef struct _PVRSRV_FENCE_SERVER_ PVRSRV_FENCE_SERVER; -typedef struct _PVRSRV_FENCE_EXPORT_ PVRSRV_FENCE_EXPORT; - -typedef struct _PVRSRV_SYNC_PT_ PVRSRV_SYNC_PT; - -#define SYNC_FB_TIMELINE_MAX_LENGTH PVRSRV_SYNC_NAME_LENGTH -#define SYNC_FB_FENCE_MAX_LENGTH PVRSRV_SYNC_NAME_LENGTH - -/*****************************************************************************/ -/* */ -/* SW SPECIFIC FUNCTIONS */ -/* */ -/*****************************************************************************/ - -PVRSRV_ERROR SyncFbTimelineCreateSW(IMG_UINT32 uiTimelineNameSize, - const IMG_CHAR *pszTimelineName, - PVRSRV_TIMELINE_SERVER **ppsTimeline); - -PVRSRV_ERROR SyncFbFenceCreateSW(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_TIMELINE_SERVER *psTimeline, - IMG_UINT32 uiFenceNameSize, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE_SERVER **ppsOutputFence, - IMG_UINT64 *pui64SyncPtIdx); -PVRSRV_ERROR SyncFbSWTimelineFenceCreateKM(PVRSRV_DEVICE_NODE *psDeviceNode, - PVRSRV_TIMELINE iSWTimeline, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE *piOutputFence, - IMG_UINT64* pui64SyncPtIdx); - -PVRSRV_ERROR SyncFbTimelineAdvanceSW(PVRSRV_TIMELINE_SERVER *psTimeline, - IMG_UINT64 *pui64SyncPtIdx); -PVRSRV_ERROR SyncFbSWTimelineAdvanceKM(void *pvSWTimelineObj, - IMG_UINT64* pui64SyncPtIdx); - -/*****************************************************************************/ -/* */ -/* PVR SPECIFIC FUNCTIONS */ -/* */ -/*****************************************************************************/ - -PVRSRV_ERROR SyncFbTimelineCreatePVR(IMG_UINT32 uiTimelineNameSize, - const IMG_CHAR *pszTimelineName, - PVRSRV_TIMELINE_SERVER **ppsTimeline); - -PVRSRV_ERROR SyncFbFenceCreatePVR(PPVRSRV_DEVICE_NODE psDeviceNode, - const IMG_CHAR *pszName, - PVRSRV_TIMELINE iTl, - PSYNC_CHECKPOINT_CONTEXT hSyncCheckpointContext, - PVRSRV_FENCE *piOutFence, - IMG_UINT64 *puiFenceUID, - void **ppvFenceFinaliseData, - PSYNC_CHECKPOINT *ppsOutCheckpoint, - void **ppvTimelineUpdateSync, - IMG_UINT32 *puiTimelineUpdateValue); - -PVRSRV_ERROR SyncFbFenceResolvePVR(PSYNC_CHECKPOINT_CONTEXT psContext, - PVRSRV_FENCE iFence, - IMG_UINT32 *puiNumCheckpoints, - PSYNC_CHECKPOINT **papsCheckpoints, - IMG_UINT64 *puiFenceUID); - -/*****************************************************************************/ -/* */ -/* GENERIC FUNCTIONS */ -/* */ -/*****************************************************************************/ - -PVRSRV_ERROR SyncFbGetFenceObj(PVRSRV_FENCE iFence, - void **ppvFenceObj); - -PVRSRV_ERROR SyncFbSWGetTimelineObj(PVRSRV_TIMELINE iSWTimeline, - void **ppvSWTimelineObj); - -PVRSRV_ERROR SyncFbTimelineRelease(PVRSRV_TIMELINE_SERVER *psTl); - -PVRSRV_ERROR SyncFbFenceRelease(PVRSRV_FENCE_SERVER *psFence); -PVRSRV_ERROR SyncFbFenceReleaseKM(void *pvFenceObj); - -PVRSRV_ERROR SyncFbFenceDup(PVRSRV_FENCE_SERVER *psInFence, - PVRSRV_FENCE_SERVER **ppsOutFence); - -PVRSRV_ERROR SyncFbFenceMerge(PVRSRV_FENCE_SERVER *psInFence1, - PVRSRV_FENCE_SERVER *psInFence2, - IMG_UINT32 uiFenceNameSize, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE_SERVER **ppsOutFence); - -PVRSRV_ERROR SyncFbFenceWait(PVRSRV_FENCE_SERVER *psFence, - IMG_UINT32 uiTimeout); - -PVRSRV_ERROR SyncFbFenceDump(PVRSRV_FENCE_SERVER *psFence, - IMG_UINT32 uiLine, - IMG_UINT32 uiFileNameLength, - const IMG_CHAR *pszFile, - IMG_UINT32 uiModuleLength, - const IMG_CHAR *pszModule, - IMG_UINT32 uiDescLength, - const IMG_CHAR *pszDesc); - -PVRSRV_ERROR SyncFbDumpFenceKM(void *pvSWFenceObj, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -PVRSRV_ERROR SyncFbSWDumpTimelineKM(void *pvSWTimelineObj, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -PVRSRV_ERROR SyncFbRegisterSyncFunctions(void); - -PVRSRV_ERROR SyncFbRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -PVRSRV_ERROR SyncFbDeregisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode); - -IMG_UINT32 SyncFbDumpInfoOnStalledUFOs(IMG_UINT32 nr_ufos, IMG_UINT32 *vaddrs); - -IMG_BOOL SyncFbCheckpointHasSignalled(IMG_UINT32 ui32FwAddr, IMG_UINT32 ui32Value); - -/*****************************************************************************/ -/* */ -/* IMPORT/EXPORT FUNCTIONS */ -/* */ -/*****************************************************************************/ - -#if defined(SUPPORT_INSECURE_EXPORT) -PVRSRV_ERROR SyncFbFenceExportInsecure(PVRSRV_FENCE_SERVER *psFence, - PVRSRV_FENCE_EXPORT **ppExport); - -PVRSRV_ERROR SyncFbFenceExportDestroyInsecure(PVRSRV_FENCE_EXPORT *psExport); - -PVRSRV_ERROR SyncFbFenceImportInsecure(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevice, - PVRSRV_FENCE_EXPORT *psImport, - PVRSRV_FENCE_SERVER **psFence); -#endif /* defined(SUPPORT_INSECURE_EXPORT) */ - -PVRSRV_ERROR SyncFbFenceExportSecure(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - PVRSRV_FENCE_SERVER *psFence, - IMG_SECURE_TYPE *phSecure, - PVRSRV_FENCE_EXPORT **ppsExport, - CONNECTION_DATA **ppsSecureConnection); - -PVRSRV_ERROR SyncFbFenceExportDestroySecure(PVRSRV_FENCE_EXPORT *psExport); - -PVRSRV_ERROR SyncFbFenceImportSecure(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevice, - IMG_SECURE_TYPE hSecure, - PVRSRV_FENCE_SERVER **psFence); - -#endif /* SYNC_FALLBACK_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_internal.h b/drivers/gpu/drm/img-rogue/1.17/sync_internal.h deleted file mode 100644 index 29c836054cae7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_internal.h +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services internal synchronisation interface header -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Defines the internal client side interface for services - synchronisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_INTERNAL -#define SYNC_INTERNAL - -#include "img_types.h" -#include "img_defs.h" -#include "ra.h" -#include "dllist.h" -#include "lock.h" -#include "devicemem.h" -#include "sync_prim_internal.h" - -#define LOCAL_SYNC_PRIM_RESET_VALUE 0 -#define LOCAL_SYNC_PRIM_POISON_VALUE 0xa5a5a5a5u - -/* - Debug feature to protect against GP DM page faults when - sync prims are freed by client before work is completed. -*/ -#define LOCAL_SYNC_BLOCK_RETAIN_FIRST - -/* - Private structure's -*/ -#define SYNC_PRIM_NAME_SIZE 50 -typedef struct SYNC_PRIM_CONTEXT_TAG -{ - SHARED_DEV_CONNECTION hDevConnection; - IMG_CHAR azName[SYNC_PRIM_NAME_SIZE]; /*!< Name of the RA */ - RA_ARENA *psSubAllocRA; /*!< RA context */ - IMG_CHAR azSpanName[SYNC_PRIM_NAME_SIZE];/*!< Name of the span RA */ - RA_ARENA *psSpanRA; /*!< RA used for span management of SubAllocRA */ - ATOMIC_T hRefCount; /*!< Ref count for this context */ -#if defined(LOCAL_SYNC_BLOCK_RETAIN_FIRST) - IMG_HANDLE hFirstSyncPrim; /*!< Handle to the first allocated sync prim */ -#endif -} SYNC_PRIM_CONTEXT; - -typedef struct SYNC_PRIM_BLOCK_TAG -{ - SYNC_PRIM_CONTEXT *psContext; /*!< Our copy of the services connection */ - IMG_HANDLE hServerSyncPrimBlock; /*!< Server handle for this block */ - IMG_UINT32 ui32SyncBlockSize; /*!< Size of the sync prim block */ - IMG_UINT32 ui32FirmwareAddr; /*!< Firmware address */ - DEVMEM_MEMDESC *hMemDesc; /*!< Host mapping handle */ - IMG_UINT32 __iomem *pui32LinAddr; /*!< User CPU mapping */ - IMG_UINT64 uiSpanBase; /*!< Base of this import in the span RA */ - DLLIST_NODE sListNode; /*!< List node for the sync block list */ -} SYNC_PRIM_BLOCK; - -typedef enum SYNC_PRIM_TYPE_TAG -{ - SYNC_PRIM_TYPE_UNKNOWN = 0, - SYNC_PRIM_TYPE_LOCAL, - SYNC_PRIM_TYPE_SERVER, -} SYNC_PRIM_TYPE; - -typedef struct SYNC_PRIM_LOCAL_TAG -{ - ATOMIC_T hRefCount; /*!< Ref count for this sync */ - SYNC_PRIM_BLOCK *psSyncBlock; /*!< Synchronisation block this primitive is allocated on */ - IMG_UINT64 uiSpanAddr; /*!< Span address of the sync */ - IMG_HANDLE hRecord; /*!< Sync record handle */ -} SYNC_PRIM_LOCAL; - -typedef struct SYNC_PRIM_TAG -{ - PVRSRV_CLIENT_SYNC_PRIM sCommon; /*!< Client visible part of the sync prim */ - SYNC_PRIM_TYPE eType; /*!< Sync primitive type */ - union { - SYNC_PRIM_LOCAL sLocal; /*!< Local sync primitive data */ - } u; -} SYNC_PRIM; - - -IMG_INTERNAL PVRSRV_ERROR -SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 *pui32FwAddr); - -IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync, - IMG_HANDLE *phBlock, - IMG_UINT32 *pui32Offset); - - -#endif /* SYNC_INTERNAL */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_prim_internal.h b/drivers/gpu/drm/img-rogue/1.17/sync_prim_internal.h deleted file mode 100644 index 77164c2356cd7..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_prim_internal.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Services internal synchronisation typedef header -@Description Defines synchronisation types that are used internally - only -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 SYNC_INTERNAL_H -#define SYNC_INTERNAL_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include - -/* These are included here as the typedefs are required - * internally. - */ - -typedef struct SYNC_PRIM_CONTEXT_TAG *PSYNC_PRIM_CONTEXT; -typedef struct PVRSRV_CLIENT_SYNC_PRIM_TAG -{ - volatile uint32_t __iomem *pui32LinAddr; /*!< User pointer to the primitive */ -} PVRSRV_CLIENT_SYNC_PRIM; - -/*! - * Bundled information for a sync prim operation - * - * Structure: #PVRSRV_CLIENT_SYNC_PRIM_OP - * Typedef: ::PVRSRV_CLIENT_SYNC_PRIM_OP - */ -typedef struct PVRSRV_CLIENT_SYNC_PRIM_OP_TAG -{ - #define PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK (1U << 0) - #define PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE (1U << 1) - #define PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE (PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE | (1U<<2)) - uint32_t ui32Flags; /*!< Operation flags: PVRSRV_CLIENT_SYNC_PRIM_OP_XXX */ - PVRSRV_CLIENT_SYNC_PRIM *psSync; /*!< Pointer to the client sync primitive */ - uint32_t ui32FenceValue; /*!< The Fence value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK is set) */ - uint32_t ui32UpdateValue; /*!< The Update value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE is set) */ -} PVRSRV_CLIENT_SYNC_PRIM_OP; - -#if defined(__cplusplus) -} -#endif -#endif /* SYNC_INTERNAL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_server.c b/drivers/gpu/drm/img-rogue/1.17/sync_server.c deleted file mode 100644 index 7398f4417d5eb..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_server.c +++ /dev/null @@ -1,1223 +0,0 @@ -/*************************************************************************/ /*! -@File sync_server.c -@Title Server side synchronisation functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implements the server side functions that for synchronisation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "sync_server.h" -#include "allocmem.h" -#include "device.h" -#include "devicemem.h" -#include "devicemem_pdump.h" -#include "osfunc.h" -#include "pdump.h" -#include "pvr_debug.h" -#include "pvr_notifier.h" -#include "pdump_km.h" -#include "sync.h" -#include "sync_internal.h" -#include "connection_server.h" -#include "htbuffer.h" -#include "rgxhwperf.h" -#include "info_page.h" - -#include "sync_checkpoint_internal.h" -#include "sync_checkpoint.h" - -/* Include this to obtain MAX_SYNC_CHECKPOINTS_PER_FENCE */ -#include "sync_checkpoint_external.h" - -/* Include this to obtain PVRSRV_MAX_DEV_VARS */ -#include "pvrsrv_devvar.h" - -#if defined(SUPPORT_SECURE_EXPORT) -#include "ossecure_export.h" -#endif - -/* Set this to enable debug relating to the construction and maintenance of the sync address list */ -#define SYNC_ADDR_LIST_DEBUG 0 - -/* Set maximum number of FWAddrs that can be accommodated in a SYNC_ADDR_LIST. - * This should allow for PVRSRV_MAX_DEV_VARS dev vars plus - * MAX_SYNC_CHECKPOINTS_PER_FENCE sync checkpoints for check fences. - * The same SYNC_ADDR_LIST is also used to hold UFOs for updates. While this - * may need to accommodate the additional sync prim update returned by Native - * sync implementation (used for timeline debug), the size calculated from - * PVRSRV_MAX_DEV_VARS+MAX_SYNC_CHECKPOINTS_PER_FENCE should be ample. - */ -#define PVRSRV_MAX_SYNC_ADDR_LIST_SIZE (PVRSRV_MAX_DEV_VARS+MAX_SYNC_CHECKPOINTS_PER_FENCE) -/* Check that helper functions will not be preparing longer lists of - * UFOs than the FW can handle. - */ -static_assert(PVRSRV_MAX_SYNC_ADDR_LIST_SIZE <= RGXFWIF_CCB_CMD_MAX_UFOS, - "PVRSRV_MAX_SYNC_ADDR_LIST_SIZE > RGXFWIF_CCB_CMD_MAX_UFOS."); - -/* Max number of syncs allowed in a sync prim op */ -#define SYNC_PRIM_OP_MAX_SYNCS 1024 - -struct _SYNC_PRIMITIVE_BLOCK_ -{ - PVRSRV_DEVICE_NODE *psDevNode; - DEVMEM_MEMDESC *psMemDesc; - IMG_UINT32 *pui32LinAddr; - IMG_UINT32 ui32BlockSize; /*!< Size of the Sync Primitive Block */ - ATOMIC_T sRefCount; - DLLIST_NODE sConnectionNode; - SYNC_CONNECTION_DATA *psSyncConnectionData; /*!< Link back to the sync connection data if there is one */ - PRGXFWIF_UFO_ADDR uiFWAddr; /*!< The firmware address of the sync prim block */ -}; - -struct _SYNC_CONNECTION_DATA_ -{ - DLLIST_NODE sListHead; /*!< list of sync block associated with / created against this connection */ - ATOMIC_T sRefCount; /*!< number of references to this object */ - POS_LOCK hLock; /*!< lock protecting the list of sync blocks */ -}; - -#define DECREMENT_WITH_WRAP(value, sz) ((value) ? ((value) - 1) : ((sz) - 1)) - -/* this is the max number of syncs we will search or dump - * at any time. - */ -#define SYNC_RECORD_LIMIT 20000 - -enum SYNC_RECORD_TYPE -{ - SYNC_RECORD_TYPE_UNKNOWN = 0, - SYNC_RECORD_TYPE_CLIENT, - SYNC_RECORD_TYPE_SERVER, -}; - -struct SYNC_RECORD -{ - PVRSRV_DEVICE_NODE *psDevNode; - SYNC_PRIMITIVE_BLOCK *psServerSyncPrimBlock; /*!< handle to _SYNC_PRIMITIVE_BLOCK_ */ - IMG_UINT32 ui32SyncOffset; /*!< offset to sync in block */ - IMG_UINT32 ui32FwBlockAddr; - IMG_PID uiPID; - IMG_UINT64 ui64OSTime; - enum SYNC_RECORD_TYPE eRecordType; - DLLIST_NODE sNode; - IMG_CHAR szClassName[PVRSRV_SYNC_NAME_LENGTH]; -}; - -#if defined(SYNC_DEBUG) || defined(REFCOUNT_DEBUG) -#define SYNC_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__) -#else -#define SYNC_REFCOUNT_PRINT(fmt, ...) -#endif - -#if defined(SYNC_DEBUG) -#define SYNC_UPDATES_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__) -#else -#define SYNC_UPDATES_PRINT(fmt, ...) -#endif - -/*! -***************************************************************************** - @Function : SyncPrimitiveBlockToFWAddr - - @Description : Given a pointer to a sync primitive block and an offset, - returns the firmware address of the sync. - - @Input psSyncPrimBlock : Sync primitive block which contains the sync - @Input ui32Offset : Offset of sync within the sync primitive block - @Output psAddrOut : Absolute FW address of the sync is written out through - this pointer - @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input - parameters are invalid. -*****************************************************************************/ - -PVRSRV_ERROR -SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock, - IMG_UINT32 ui32Offset, - PRGXFWIF_UFO_ADDR *psAddrOut) -{ - /* check offset is legal */ - if (unlikely((ui32Offset >= psSyncPrimBlock->ui32BlockSize) || - (ui32Offset % sizeof(IMG_UINT32)))) - { - PVR_DPF((PVR_DBG_ERROR, "SyncPrimitiveBlockToFWAddr: parameters check failed")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psAddrOut->ui32Addr = psSyncPrimBlock->uiFWAddr.ui32Addr + ui32Offset; - return PVRSRV_OK; -} - -/*! -***************************************************************************** - @Function : SyncAddrListGrow - - @Description : Grow the SYNC_ADDR_LIST so it can accommodate the given - number of syncs, up to a maximum of PVRSRV_MAX_SYNC_PRIMS. - - @Input psList : The SYNC_ADDR_LIST to grow - @Input ui32NumSyncs : The number of sync addresses to be able to hold - @Return : PVRSRV_OK on success -*****************************************************************************/ - -static PVRSRV_ERROR SyncAddrListGrow(SYNC_ADDR_LIST *psList, IMG_UINT32 ui32NumSyncs) -{ - if (unlikely(ui32NumSyncs > PVRSRV_MAX_SYNC_ADDR_LIST_SIZE)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: ui32NumSyncs=%u > PVRSRV_MAX_SYNC_ADDR_LIST_SIZE=%u", __func__, ui32NumSyncs, PVRSRV_MAX_SYNC_ADDR_LIST_SIZE)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Entry psList=<%p>, psList->ui32NumSyncs=%d, ui32NumSyncs=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumSyncs)); -#endif - if (ui32NumSyncs > psList->ui32NumSyncs) - { - if (psList->pasFWAddrs == NULL) - { - psList->pasFWAddrs = OSAllocMem(sizeof(PRGXFWIF_UFO_ADDR) * PVRSRV_MAX_SYNC_ADDR_LIST_SIZE); - PVR_RETURN_IF_NOMEM(psList->pasFWAddrs); - } - - psList->ui32NumSyncs = ui32NumSyncs; - } - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Exit psList=<%p>, psList->ui32NumSyncs=%d, ui32NumSyncs=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumSyncs)); -#endif - return PVRSRV_OK; -} - -/*! -***************************************************************************** - @Function : SyncAddrListInit - - @Description : Initialise a SYNC_ADDR_LIST structure ready for use - - @Input psList : The SYNC_ADDR_LIST structure to initialise - @Return : None -*****************************************************************************/ - -void -SyncAddrListInit(SYNC_ADDR_LIST *psList) -{ - psList->ui32NumSyncs = 0; - psList->pasFWAddrs = NULL; -} - -/*! -***************************************************************************** - @Function : SyncAddrListDeinit - - @Description : Frees any resources associated with the given SYNC_ADDR_LIST - - @Input psList : The SYNC_ADDR_LIST structure to deinitialise - @Return : None -*****************************************************************************/ - -void -SyncAddrListDeinit(SYNC_ADDR_LIST *psList) -{ - if (psList->pasFWAddrs != NULL) - { - OSFreeMem(psList->pasFWAddrs); - } -} - -/*! -***************************************************************************** - @Function : SyncAddrListPopulate - - @Description : Populate the given SYNC_ADDR_LIST with the FW addresses - of the syncs given by the SYNC_PRIMITIVE_BLOCKs and sync offsets - - @Input ui32NumSyncs : The number of syncs being passed in - @Input apsSyncPrimBlock: Array of pointers to SYNC_PRIMITIVE_BLOCK structures - in which the syncs are based - @Input paui32SyncOffset: Array of offsets within each of the sync primitive blocks - where the syncs are located - @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input - parameters are invalid. -*****************************************************************************/ - -PVRSRV_ERROR -SyncAddrListPopulate(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumSyncs, - SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock, - IMG_UINT32 *paui32SyncOffset) -{ - IMG_UINT32 i; - PVRSRV_ERROR eError; - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Entry psList=<%p>, psList->ui32NumSyncs=%d, ui32NumSyncs=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumSyncs)); -#endif - if (ui32NumSyncs > psList->ui32NumSyncs) - { - eError = SyncAddrListGrow(psList, ui32NumSyncs); - - PVR_RETURN_IF_ERROR(eError); - } - - psList->ui32NumSyncs = ui32NumSyncs; - - for (i = 0; i < ui32NumSyncs; i++) - { - eError = SyncPrimitiveBlockToFWAddr(apsSyncPrimBlock[i], - paui32SyncOffset[i], - &psList->pasFWAddrs[i]); - - PVR_RETURN_IF_ERROR(eError); - } - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Exit psList=<%p>, psList->ui32NumSyncs=%d, ui32NumSyncs=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumSyncs)); -#endif - return PVRSRV_OK; -} - -PVRSRV_ERROR -SyncAddrListAppendSyncPrim(SYNC_ADDR_LIST *psList, - PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32FwAddr = 0; - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Entry psList=<%p>, psList->ui32NumSyncs=%d)", __func__, (void*)psList, psList->ui32NumSyncs)); -#endif - /* Ensure there's room in psList for the additional sync prim update */ - eError = SyncAddrListGrow(psList, psList->ui32NumSyncs + 1); - PVR_GOTO_IF_ERROR(eError, e0); - - SyncPrimGetFirmwareAddr(psSyncPrim, &ui32FwAddr); -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Appending sync prim <%p> UFO addr (0x%x) to psList[->pasFWAddrss[%d]", __func__, (void*)psSyncPrim, ui32FwAddr, psList->ui32NumSyncs-1)); -#endif - psList->pasFWAddrs[psList->ui32NumSyncs-1].ui32Addr = ui32FwAddr; - -#if (SYNC_ADDR_LIST_DEBUG == 1) - { - IMG_UINT32 iii; - - PVR_DPF((PVR_DBG_ERROR, "%s: psList->ui32NumSyncs=%d", __func__, psList->ui32NumSyncs)); - for (iii=0; iiiui32NumSyncs; iii++) - { - PVR_DPF((PVR_DBG_ERROR, "%s: psList->pasFWAddrs[%d].ui32Addr=0x%x", __func__, iii, psList->pasFWAddrs[iii].ui32Addr)); - } - } -#endif -e0: -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Exit psList=<%p>, psList->ui32NumSyncs=%d", __func__, (void*)psList, psList->ui32NumSyncs)); -#endif - return eError; -} - - -static PVRSRV_ERROR -_AppendCheckpoints(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint, - IMG_BOOL bDeRefCheckpoints) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32SyncCheckpointIndex; - IMG_UINT32 ui32RollbackSize = psList->ui32NumSyncs; - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: Entry psList=<%p>, psList->ui32NumSyncs=%d, ui32NumCheckpoints=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumCheckpoints)); -#endif - /* Ensure there's room in psList for the sync checkpoints */ - eError = SyncAddrListGrow(psList, psList->ui32NumSyncs + ui32NumCheckpoints); - if (unlikely(eError != PVRSRV_OK)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: * * * * ERROR * * * * Trying to SyncAddrListGrow(psList=<%p>, psList->ui32NumSyncs=%d, ui32NumCheckpoints=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumCheckpoints)); - goto e0; - } - -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: (ui32NumCheckpoints=%d) (psList->ui32NumSyncs is now %d) array already contains %d FWAddrs:", __func__, ui32NumCheckpoints, psList->ui32NumSyncs, ui32RollbackSize)); - if (ui32RollbackSize > 0) - { - { - IMG_UINT32 kk; - for (kk=0; kkpsList->pasFWAddrs[%d].ui32Addr = %u(0x%x)", __func__, - (void*)&psList->pasFWAddrs[kk], kk, - psList->pasFWAddrs[kk].ui32Addr, psList->pasFWAddrs[kk].ui32Addr)); - } - } - } - PVR_DPF((PVR_DBG_ERROR, "%s: apsSyncCheckpoint=<%p>, apsSyncCheckpoint[0] = <%p>", __func__, (void*)apsSyncCheckpoint, (void*)apsSyncCheckpoint[0])); -#endif - for (ui32SyncCheckpointIndex=0; ui32SyncCheckpointIndexpasFWAddrs[ui32RollbackSize + ui32SyncCheckpointIndex].ui32Addr = SyncCheckpointGetFirmwareAddr(apsSyncCheckpoint[ui32SyncCheckpointIndex]); -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: SyncCheckpointCCBEnqueued(<%p>)", __func__, (void*)apsSyncCheckpoint[ui32SyncCheckpointIndex])); - PVR_DPF((PVR_DBG_ERROR, "%s: ID:%d", __func__, SyncCheckpointGetId((PSYNC_CHECKPOINT)apsSyncCheckpoint[ui32SyncCheckpointIndex]))); -#endif - SyncCheckpointCCBEnqueued((PSYNC_CHECKPOINT)apsSyncCheckpoint[ui32SyncCheckpointIndex]); - if (bDeRefCheckpoints) - { - /* Drop the reference that was taken internally by the OS implementation of resolve_fence() */ - SyncCheckpointDropRef((PSYNC_CHECKPOINT)apsSyncCheckpoint[ui32SyncCheckpointIndex]); - } - } -#if (SYNC_ADDR_LIST_DEBUG == 1) - if (psList->ui32NumSyncs > 0) - { - IMG_UINT32 kk; - for (kk=0; kkui32NumSyncs; kk++) - { - PVR_DPF((PVR_DBG_ERROR, "%s: <%p>psList->pasFWAddrs[%d].ui32Addr = %u(0x%x)", __func__, - (void*)&psList->pasFWAddrs[kk], kk, - psList->pasFWAddrs[kk].ui32Addr, psList->pasFWAddrs[kk].ui32Addr)); - } - } -#endif - return eError; - -e0: - for (ui32SyncCheckpointIndex=0; ui32SyncCheckpointIndex, psList->ui32NumSyncs=%d, ui32NumCheckpoints=%d)", __func__, (void*)psList, psList->ui32NumSyncs, ui32NumCheckpoints)); -#endif - return eError; -} - -/*! -***************************************************************************** - @Function : SyncAddrListAppendCheckpoints - - @Description : Append the FW addresses of the sync checkpoints given in - the PSYNC_CHECKPOINTs array to the given SYNC_ADDR_LIST - - @Input ui32NumSyncCheckpoints : The number of sync checkpoints - being passed in - @Input apsSyncCheckpoint : Array of PSYNC_CHECKPOINTs whose details - are to be appended to the SYNC_ADDR_LIST - @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input - parameters are invalid. -*****************************************************************************/ -PVRSRV_ERROR -SyncAddrListAppendCheckpoints(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint) -{ - return _AppendCheckpoints(psList, ui32NumCheckpoints, apsSyncCheckpoint, IMG_FALSE); -} - -/*! -***************************************************************************** - @Function : SyncAddrListAppendAndDeRefCheckpoints - - @Description : Append the FW addresses of the sync checkpoints given in - the PSYNC_CHECKPOINTs array to the given SYNC_ADDR_LIST. - A reference is dropped for each of the checkpoints. - - @Input ui32NumSyncCheckpoints : The number of sync checkpoints - being passed in - @Input apsSyncCheckpoint : Array of PSYNC_CHECKPOINTs whose details - are to be appended to the SYNC_ADDR_LIST - @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input - parameters are invalid. -*****************************************************************************/ -PVRSRV_ERROR -SyncAddrListAppendAndDeRefCheckpoints(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint) -{ - return _AppendCheckpoints(psList, ui32NumCheckpoints, apsSyncCheckpoint, IMG_TRUE); -} - -void -SyncAddrListDeRefCheckpoints(IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint) -{ - IMG_UINT32 ui32SyncCheckpointIndex; - - for (ui32SyncCheckpointIndex=0; ui32SyncCheckpointIndex)", __func__, (void*)psList)); -#endif - if (psList) - { -#if (SYNC_ADDR_LIST_DEBUG == 1) - PVR_DPF((PVR_DBG_ERROR, "%s: psList->ui32NumSyncs=%d", __func__, psList->ui32NumSyncs)); -#endif - for (ui32SyncIndex=0; ui32SyncIndexui32NumSyncs; ui32SyncIndex++) - { - if (psList->pasFWAddrs[ui32SyncIndex].ui32Addr & 0x1) - { - SyncCheckpointRollbackFromUFO(psDevNode, psList->pasFWAddrs[ui32SyncIndex].ui32Addr); - } - } - } - return eError; -} - -PVRSRV_ERROR -PVRSRVSyncRecordAddKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - SYNC_RECORD_HANDLE *phRecord, - SYNC_PRIMITIVE_BLOCK *hServerSyncPrimBlock, - IMG_UINT32 ui32FwBlockAddr, - IMG_UINT32 ui32SyncOffset, - IMG_BOOL bServerSync, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName) -{ - struct SYNC_RECORD * psSyncRec; - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(psConnection); - - RGXSRV_HWPERF_ALLOC(psDevNode, SYNC, - ui32FwBlockAddr + ui32SyncOffset, - pszClassName, - ui32ClassNameSize); - - PVR_RETURN_IF_INVALID_PARAM(phRecord); - - *phRecord = NULL; - - psSyncRec = OSAllocMem(sizeof(*psSyncRec)); - PVR_GOTO_IF_NOMEM(psSyncRec, eError, fail_alloc); - - psSyncRec->psDevNode = psDevNode; - psSyncRec->psServerSyncPrimBlock = hServerSyncPrimBlock; - psSyncRec->ui32SyncOffset = ui32SyncOffset; - psSyncRec->ui32FwBlockAddr = ui32FwBlockAddr; - psSyncRec->ui64OSTime = OSClockns64(); - psSyncRec->uiPID = OSGetCurrentProcessID(); - psSyncRec->eRecordType = bServerSync? SYNC_RECORD_TYPE_SERVER: SYNC_RECORD_TYPE_CLIENT; - - if (pszClassName) - { - if (ui32ClassNameSize >= PVRSRV_SYNC_NAME_LENGTH) - ui32ClassNameSize = PVRSRV_SYNC_NAME_LENGTH; - /* Copy over the class name annotation */ - OSStringLCopy(psSyncRec->szClassName, pszClassName, ui32ClassNameSize); - } - else - { - /* No class name annotation */ - psSyncRec->szClassName[0] = 0; - } - - OSLockAcquire(psDevNode->hSyncServerRecordLock); - if (psDevNode->ui32SyncServerRecordCount < SYNC_RECORD_LIMIT) - { - dllist_add_to_head(&psDevNode->sSyncServerRecordList, &psSyncRec->sNode); - psDevNode->ui32SyncServerRecordCount++; - - if (psDevNode->ui32SyncServerRecordCount > psDevNode->ui32SyncServerRecordCountHighWatermark) - { - psDevNode->ui32SyncServerRecordCountHighWatermark = psDevNode->ui32SyncServerRecordCount; - } - } - else - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to add sync record \"%s\". %u records already exist.", - __func__, - pszClassName, - psDevNode->ui32SyncServerRecordCount)); - OSFreeMem(psSyncRec); - psSyncRec = NULL; - eError = PVRSRV_ERROR_TOOMANYBUFFERS; - } - OSLockRelease(psDevNode->hSyncServerRecordLock); - - *phRecord = (SYNC_RECORD_HANDLE)psSyncRec; - -fail_alloc: - return eError; -} - -PVRSRV_ERROR -PVRSRVSyncRecordRemoveByHandleKM( - SYNC_RECORD_HANDLE hRecord) -{ - struct SYNC_RECORD **ppFreedSync; - struct SYNC_RECORD *pSync = (struct SYNC_RECORD*)hRecord; - PVRSRV_DEVICE_NODE *psDevNode; - - PVR_RETURN_IF_INVALID_PARAM(hRecord); - - psDevNode = pSync->psDevNode; - - OSLockAcquire(psDevNode->hSyncServerRecordLock); - - RGXSRV_HWPERF_FREE(psDevNode, SYNC, pSync->ui32FwBlockAddr + pSync->ui32SyncOffset); - - dllist_remove_node(&pSync->sNode); - - if (psDevNode->uiSyncServerRecordFreeIdx >= PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN) - { - PVR_DPF((PVR_DBG_ERROR, "%s: freed sync record index out of range", - __func__)); - psDevNode->uiSyncServerRecordFreeIdx = 0; - } - ppFreedSync = &psDevNode->apsSyncServerRecordsFreed[psDevNode->uiSyncServerRecordFreeIdx]; - psDevNode->uiSyncServerRecordFreeIdx = - (psDevNode->uiSyncServerRecordFreeIdx + 1) % PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN; - - if (*ppFreedSync) - { - OSFreeMem(*ppFreedSync); - } - pSync->psServerSyncPrimBlock = NULL; - pSync->ui64OSTime = OSClockns64(); - *ppFreedSync = pSync; - - psDevNode->ui32SyncServerRecordCount--; - - OSLockRelease(psDevNode->hSyncServerRecordLock); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVSyncAllocEventKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_BOOL bServerSync, - IMG_UINT32 ui32FWAddr, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - RGXSRV_HWPERF_ALLOC(psDevNode, SYNC, ui32FWAddr, pszClassName, ui32ClassNameSize); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVSyncFreeEventKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32FWAddr) -{ - PVR_UNREFERENCED_PARAMETER(psConnection); - RGXSRV_HWPERF_FREE(psDevNode, SYNC, ui32FWAddr); - - return PVRSRV_OK; -} - -static -void _SyncConnectionRef(SYNC_CONNECTION_DATA *psSyncConnectionData) -{ - IMG_INT iRefCount = OSAtomicIncrement(&psSyncConnectionData->sRefCount); - - SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d", - __func__, psSyncConnectionData, iRefCount); - PVR_UNREFERENCED_PARAMETER(iRefCount); -} - -static -void _SyncConnectionUnref(SYNC_CONNECTION_DATA *psSyncConnectionData) -{ - IMG_INT iRefCount = OSAtomicDecrement(&psSyncConnectionData->sRefCount); - if (iRefCount == 0) - { - SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d", - __func__, psSyncConnectionData, iRefCount); - - PVR_ASSERT(dllist_is_empty(&psSyncConnectionData->sListHead)); - OSLockDestroy(psSyncConnectionData->hLock); - OSFreeMem(psSyncConnectionData); - } - else - { - SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d", - __func__, psSyncConnectionData, iRefCount); - PVR_ASSERT(iRefCount > 0); - } -} - -static -void _SyncConnectionAddBlock(CONNECTION_DATA *psConnection, SYNC_PRIMITIVE_BLOCK *psBlock) -{ - if (psConnection) - { - SYNC_CONNECTION_DATA *psSyncConnectionData = psConnection->psSyncConnectionData; - - /* - Make sure the connection doesn't go away. It doesn't matter that we will release - the lock between as the refcount and list don't have to be atomic w.r.t. to each other - */ - _SyncConnectionRef(psSyncConnectionData); - - OSLockAcquire(psSyncConnectionData->hLock); - if (psConnection != NULL) - { - dllist_add_to_head(&psSyncConnectionData->sListHead, &psBlock->sConnectionNode); - } - OSLockRelease(psSyncConnectionData->hLock); - psBlock->psSyncConnectionData = psSyncConnectionData; - } - else - { - psBlock->psSyncConnectionData = NULL; - } -} - -static -void _SyncConnectionRemoveBlock(SYNC_PRIMITIVE_BLOCK *psBlock) -{ - SYNC_CONNECTION_DATA *psSyncConnectionData = psBlock->psSyncConnectionData; - - if (psBlock->psSyncConnectionData) - { - OSLockAcquire(psSyncConnectionData->hLock); - dllist_remove_node(&psBlock->sConnectionNode); - OSLockRelease(psSyncConnectionData->hLock); - - _SyncConnectionUnref(psBlock->psSyncConnectionData); - } -} - -static inline -void _DoPrimBlockFree(SYNC_PRIMITIVE_BLOCK *psSyncBlk) -{ - PVRSRV_DEVICE_NODE *psDevNode = psSyncBlk->psDevNode; - - SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d (remove)", - __func__, psSyncBlk, OSAtomicRead(&psSyncBlk->sRefCount)); - - PVR_ASSERT(OSAtomicRead(&psSyncBlk->sRefCount) == 1); - - _SyncConnectionRemoveBlock(psSyncBlk); - DevmemReleaseCpuVirtAddr(psSyncBlk->psMemDesc); - psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->psMemDesc); - OSFreeMem(psSyncBlk); -} - -PVRSRV_ERROR -PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - SYNC_PRIMITIVE_BLOCK **ppsSyncBlk, - IMG_UINT32 *puiSyncPrimVAddr, - IMG_UINT32 *puiSyncPrimBlockSize, - PMR **ppsSyncPMR) -{ - SYNC_PRIMITIVE_BLOCK *psNewSyncBlk; - PVRSRV_ERROR eError; - - psNewSyncBlk = OSAllocMem(sizeof(SYNC_PRIMITIVE_BLOCK)); - PVR_GOTO_IF_NOMEM(psNewSyncBlk, eError, e0); - - psNewSyncBlk->psDevNode = psDevNode; - - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, "Allocate UFO block"); - - eError = psDevNode->pfnAllocUFOBlock(psDevNode, - &psNewSyncBlk->psMemDesc, - &psNewSyncBlk->uiFWAddr.ui32Addr, - &psNewSyncBlk->ui32BlockSize); - PVR_GOTO_IF_ERROR(eError, e1); - - *puiSyncPrimVAddr = psNewSyncBlk->uiFWAddr.ui32Addr; - - eError = DevmemAcquireCpuVirtAddr(psNewSyncBlk->psMemDesc, - (void **) &psNewSyncBlk->pui32LinAddr); - PVR_GOTO_IF_ERROR(eError, e2); - - eError = DevmemLocalGetImportHandle(psNewSyncBlk->psMemDesc, (void **) ppsSyncPMR); - - PVR_GOTO_IF_ERROR(eError, e3); - - OSAtomicWrite(&psNewSyncBlk->sRefCount, 1); - - /* If there is a connection pointer then add the new block onto it's list */ - _SyncConnectionAddBlock(psConnection, psNewSyncBlk); - - *ppsSyncBlk = psNewSyncBlk; - *puiSyncPrimBlockSize = psNewSyncBlk->ui32BlockSize; - - PDUMPCOMMENTWITHFLAGS(psDevNode, PDUMP_FLAGS_CONTINUOUS, - "Allocated UFO block (FirmwareVAddr = 0x%08x)", - *puiSyncPrimVAddr); - - return PVRSRV_OK; - -e3: - DevmemReleaseCpuVirtAddr(psNewSyncBlk->psMemDesc); -e2: - psDevNode->pfnFreeUFOBlock(psDevNode, psNewSyncBlk->psMemDesc); -e1: - OSFreeMem(psNewSyncBlk); -e0: - return eError; -} - -PVRSRV_ERROR -PVRSRVFreeSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk) -{ - - /* This function is an alternative to the above without reference counting. - * With the removal of sync prim ops for server syncs we no longer have to - * reference count prim blocks as the reference will never be incremented / - * decremented by a prim op */ - _DoPrimBlockFree(psSyncBlk); - return PVRSRV_OK; -} - -static INLINE IMG_BOOL _CheckSyncIndex(SYNC_PRIMITIVE_BLOCK *psSyncBlk, - IMG_UINT32 ui32Index) -{ - return ((ui32Index * sizeof(IMG_UINT32)) < psSyncBlk->ui32BlockSize); -} - -PVRSRV_ERROR -PVRSRVSyncPrimSetKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Index, - IMG_UINT32 ui32Value) -{ - if (_CheckSyncIndex(psSyncBlk, ui32Index)) - { - psSyncBlk->pui32LinAddr[ui32Index] = ui32Value; - return PVRSRV_OK; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncPrimSetKM: Index %u out of range for " - "0x%08X byte sync block (value 0x%08X)", - ui32Index, - psSyncBlk->ui32BlockSize, - ui32Value)); - return PVRSRV_ERROR_INVALID_PARAMS; - } -} - -#if defined(PDUMP) -PVRSRV_ERROR -PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -{ - /* - We might be ask to PDump sync state outside of capture range - (e.g. texture uploads) so make this continuous. - */ - DevmemPDumpLoadMemValue32(psSyncBlk->psMemDesc, - ui32Offset, - ui32Value, - PDUMP_FLAGS_CONTINUOUS); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset) -{ - /* - We might be ask to PDump sync state outside of capture range - (e.g. texture uploads) so make this continuous. - */ - DevmemPDumpLoadMem(psSyncBlk->psMemDesc, - ui32Offset, - sizeof(IMG_UINT32), - PDUMP_FLAGS_CONTINUOUS); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T ui32PDumpFlags) -{ - DevmemPDumpDevmemPol32(psSyncBlk->psMemDesc, - ui32Offset, - ui32Value, - ui32Mask, - eOperator, - ui32PDumpFlags); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset, - IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize) -{ - DevmemPDumpCBP(psSyncBlk->psMemDesc, - ui32Offset, - uiWriteOffset, - uiPacketSize, - uiBufferSize); - return PVRSRV_OK; -} -#endif - -/* SyncRegisterConnection */ -PVRSRV_ERROR SyncRegisterConnection(SYNC_CONNECTION_DATA **ppsSyncConnectionData) -{ - SYNC_CONNECTION_DATA *psSyncConnectionData; - PVRSRV_ERROR eError; - - psSyncConnectionData = OSAllocMem(sizeof(SYNC_CONNECTION_DATA)); - if (psSyncConnectionData == NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto fail_alloc; - } - - eError = OSLockCreate(&psSyncConnectionData->hLock); - PVR_GOTO_IF_ERROR(eError, fail_lockcreate); - dllist_init(&psSyncConnectionData->sListHead); - OSAtomicWrite(&psSyncConnectionData->sRefCount, 1); - - *ppsSyncConnectionData = psSyncConnectionData; - return PVRSRV_OK; - -fail_lockcreate: - OSFreeMem(psSyncConnectionData); -fail_alloc: - PVR_ASSERT(eError != PVRSRV_OK); - return eError; -} - -/* SyncUnregisterConnection */ -void SyncUnregisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData) -{ - _SyncConnectionUnref(psSyncConnectionData); -} - -void SyncConnectionPDumpSyncBlocks(PVRSRV_DEVICE_NODE *psDevNode, void *hSyncPrivData, PDUMP_TRANSITION_EVENT eEvent) -{ - if ((eEvent == PDUMP_TRANSITION_EVENT_RANGE_ENTERED) || (eEvent == PDUMP_TRANSITION_EVENT_BLOCK_STARTED)) - { - SYNC_CONNECTION_DATA *psSyncConnectionData = hSyncPrivData; - DLLIST_NODE *psNode, *psNext; - - OSLockAcquire(psSyncConnectionData->hLock); - - PDUMPCOMMENT(psDevNode, "Dump client Sync Prim state"); - dllist_foreach_node(&psSyncConnectionData->sListHead, psNode, psNext) - { - SYNC_PRIMITIVE_BLOCK *psSyncBlock = - IMG_CONTAINER_OF(psNode, SYNC_PRIMITIVE_BLOCK, sConnectionNode); - - DevmemPDumpLoadMem(psSyncBlock->psMemDesc, - 0, - psSyncBlock->ui32BlockSize, - PDUMP_FLAGS_CONTINUOUS); - } - - OSLockRelease(psSyncConnectionData->hLock); - } -} - -void SyncRecordLookup(PVRSRV_DEVICE_NODE *psDevNode, IMG_UINT32 ui32FwAddr, - IMG_CHAR * pszSyncInfo, size_t len) -{ - DLLIST_NODE *psNode, *psNext; - IMG_INT iEnd; - IMG_BOOL bFound = IMG_FALSE; - - if (!pszSyncInfo) - { - return; - } - - OSLockAcquire(psDevNode->hSyncServerRecordLock); - pszSyncInfo[0] = '\0'; - - dllist_foreach_node(&psDevNode->sSyncServerRecordList, psNode, psNext) - { - struct SYNC_RECORD *psSyncRec = - IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode); - if ((psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset) == ui32FwAddr - && SYNC_RECORD_TYPE_UNKNOWN != psSyncRec->eRecordType - && psSyncRec->psServerSyncPrimBlock - && psSyncRec->psServerSyncPrimBlock->pui32LinAddr - ) - { - IMG_UINT32 *pui32SyncAddr; - pui32SyncAddr = psSyncRec->psServerSyncPrimBlock->pui32LinAddr - + (psSyncRec->ui32SyncOffset/sizeof(IMG_UINT32)); - iEnd = OSSNPrintf(pszSyncInfo, len, "Cur=0x%08x %s:%05u (%s)", - *pui32SyncAddr, - ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"), - psSyncRec->uiPID, - psSyncRec->szClassName - ); - if (iEnd >= 0 && iEnd < len) - { - pszSyncInfo[iEnd] = '\0'; - } - bFound = IMG_TRUE; - break; - } - } - - OSLockRelease(psDevNode->hSyncServerRecordLock); - - if (!bFound && (psDevNode->ui32SyncServerRecordCountHighWatermark == SYNC_RECORD_LIMIT)) - { - OSSNPrintf(pszSyncInfo, len, "(Record may be lost)"); - } -} - -#define NS_IN_S (1000000000UL) -static void _SyncRecordPrint(struct SYNC_RECORD *psSyncRec, - IMG_UINT64 ui64TimeNow, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - SYNC_PRIMITIVE_BLOCK *psSyncBlock = psSyncRec->psServerSyncPrimBlock; - - if (SYNC_RECORD_TYPE_UNKNOWN != psSyncRec->eRecordType) - { - IMG_UINT64 ui64DeltaS; - IMG_UINT32 ui32DeltaF; - IMG_UINT64 ui64Delta = ui64TimeNow - psSyncRec->ui64OSTime; - ui64DeltaS = OSDivide64(ui64Delta, NS_IN_S, &ui32DeltaF); - - if (psSyncBlock && psSyncBlock->pui32LinAddr) - { - IMG_UINT32 *pui32SyncAddr; - pui32SyncAddr = psSyncBlock->pui32LinAddr - + (psSyncRec->ui32SyncOffset/sizeof(IMG_UINT32)); - - PVR_DUMPDEBUG_LOG("\t%s %05u %05" IMG_UINT64_FMTSPEC ".%09u FWAddr=0x%08x Val=0x%08x (%s)", - ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"), - psSyncRec->uiPID, - ui64DeltaS, ui32DeltaF, - (psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset), - *pui32SyncAddr, - psSyncRec->szClassName - ); - } - else - { - PVR_DUMPDEBUG_LOG("\t%s %05u %05" IMG_UINT64_FMTSPEC ".%09u FWAddr=0x%08x Val= (%s)", - ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"), - psSyncRec->uiPID, - ui64DeltaS, ui32DeltaF, - (psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset), - psSyncRec->szClassName - ); - } - } -} - -static void _SyncRecordRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, - IMG_UINT32 ui32VerbLevel, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile) -{ - PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)hDebugRequestHandle; - IMG_UINT64 ui64TimeNowS; - IMG_UINT32 ui32TimeNowF; - IMG_UINT64 ui64TimeNow = OSClockns64(); - DLLIST_NODE *psNode, *psNext; - - ui64TimeNowS = OSDivide64(ui64TimeNow, NS_IN_S, &ui32TimeNowF); - - if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_MEDIUM)) - { - IMG_UINT32 i; - OSLockAcquire(psDevNode->hSyncServerRecordLock); - - PVR_DUMPDEBUG_LOG("Dumping all allocated syncs. Allocated: %u High watermark: %u @ %05" IMG_UINT64_FMTSPEC ".%09u", - psDevNode->ui32SyncServerRecordCount, - psDevNode->ui32SyncServerRecordCountHighWatermark, - ui64TimeNowS, - ui32TimeNowF); - if (psDevNode->ui32SyncServerRecordCountHighWatermark == SYNC_RECORD_LIMIT) - { - PVR_DUMPDEBUG_LOG("Warning: Record limit (%u) was reached. Some sync checkpoints may not have been recorded in the debug information.", - SYNC_RECORD_LIMIT); - } - - PVR_DUMPDEBUG_LOG("\t%-6s %-5s %-15s %-17s %-14s (%s)", - "Type", "PID", "Time Delta (s)", "Address", "Value", "Annotation"); - - dllist_foreach_node(&psDevNode->sSyncServerRecordList, psNode, psNext) - { - struct SYNC_RECORD *psSyncRec = - IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode); - _SyncRecordPrint(psSyncRec, ui64TimeNow, pfnDumpDebugPrintf, pvDumpDebugFile); - } - - PVR_DUMPDEBUG_LOG("Dumping all recently freed syncs @ %05" IMG_UINT64_FMTSPEC ".%09u", - ui64TimeNowS, ui32TimeNowF); - PVR_DUMPDEBUG_LOG("\t%-6s %-5s %-15s %-17s %-14s (%s)", - "Type", "PID", "Time Delta (s)", "Address", "Value", "Annotation"); - for (i = DECREMENT_WITH_WRAP(psDevNode->uiSyncServerRecordFreeIdx, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN); - i != psDevNode->uiSyncServerRecordFreeIdx; - i = DECREMENT_WITH_WRAP(i, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN)) - { - if (psDevNode->apsSyncServerRecordsFreed[i]) - { - _SyncRecordPrint(psDevNode->apsSyncServerRecordsFreed[i], - ui64TimeNow, pfnDumpDebugPrintf, pvDumpDebugFile); - } - else - { - break; - } - } - - OSLockRelease(psDevNode->hSyncServerRecordLock); - } -} -#undef NS_IN_S - -static PVRSRV_ERROR SyncRecordListInit(PVRSRV_DEVICE_NODE *psDevNode) -{ - PVRSRV_ERROR eError; - - psDevNode->ui32SyncServerRecordCount = 0; - psDevNode->ui32SyncServerRecordCountHighWatermark = 0; - - eError = OSLockCreate(&psDevNode->hSyncServerRecordLock); - PVR_GOTO_IF_ERROR(eError, fail_lock_create); - dllist_init(&psDevNode->sSyncServerRecordList); - - eError = PVRSRVRegisterDeviceDbgRequestNotify(&psDevNode->hSyncServerRecordNotify, - psDevNode, - _SyncRecordRequest, - DEBUG_REQUEST_SYNCTRACKING, - psDevNode); - - PVR_GOTO_IF_ERROR(eError, fail_dbg_register); - - return PVRSRV_OK; - -fail_dbg_register: - OSLockDestroy(psDevNode->hSyncServerRecordLock); -fail_lock_create: - return eError; -} - -static void SyncRecordListDeinit(PVRSRV_DEVICE_NODE *psDevNode) -{ - DLLIST_NODE *psNode, *psNext; - int i; - - OSLockAcquire(psDevNode->hSyncServerRecordLock); - dllist_foreach_node(&psDevNode->sSyncServerRecordList, psNode, psNext) - { - struct SYNC_RECORD *pSyncRec = - IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode); - - dllist_remove_node(psNode); - OSFreeMem(pSyncRec); - } - - for (i = 0; i < PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN; i++) - { - if (psDevNode->apsSyncServerRecordsFreed[i]) - { - OSFreeMem(psDevNode->apsSyncServerRecordsFreed[i]); - psDevNode->apsSyncServerRecordsFreed[i] = NULL; - } - } - OSLockRelease(psDevNode->hSyncServerRecordLock); - - if (psDevNode->hSyncServerRecordNotify) - { - PVRSRVUnregisterDeviceDbgRequestNotify(psDevNode->hSyncServerRecordNotify); - } - OSLockDestroy(psDevNode->hSyncServerRecordLock); -} - -PVRSRV_ERROR SyncServerInit(PVRSRV_DEVICE_NODE *psDevNode) -{ - PVRSRV_ERROR eError; - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - eError = SyncRecordListInit(psDevNode); - PVR_GOTO_IF_ERROR(eError, fail_record_list); - } - - return PVRSRV_OK; - -fail_record_list: - return eError; -} - -void SyncServerDeinit(PVRSRV_DEVICE_NODE *psDevNode) -{ - - if (GetInfoPageDebugFlagsKM() & DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED) - { - SyncRecordListDeinit(psDevNode); - } -} diff --git a/drivers/gpu/drm/img-rogue/1.17/sync_server.h b/drivers/gpu/drm/img-rogue/1.17/sync_server.h deleted file mode 100644 index e35682970af61..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sync_server.h +++ /dev/null @@ -1,249 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Server side synchronisation interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Describes the server side synchronisation functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_types.h" -#include "img_defs.h" -#include "pvrsrv.h" -#include "device.h" -#include "devicemem.h" -#include "pdump.h" -#include "pvrsrv_error.h" -#include "connection_server.h" -#include "pdump_km.h" - -#ifndef SYNC_SERVER_H -#define SYNC_SERVER_H - -typedef struct _SYNC_PRIMITIVE_BLOCK_ SYNC_PRIMITIVE_BLOCK; -typedef struct _SYNC_CONNECTION_DATA_ SYNC_CONNECTION_DATA; -typedef struct SYNC_RECORD* SYNC_RECORD_HANDLE; - -typedef struct _SYNC_ADDR_LIST_ -{ - IMG_UINT32 ui32NumSyncs; - PRGXFWIF_UFO_ADDR *pasFWAddrs; -} SYNC_ADDR_LIST; - -PVRSRV_ERROR -SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock, - IMG_UINT32 ui32Offset, - PRGXFWIF_UFO_ADDR *psAddrOut); - -void -SyncAddrListInit(SYNC_ADDR_LIST *psList); - -void -SyncAddrListDeinit(SYNC_ADDR_LIST *psList); - -PVRSRV_ERROR -SyncAddrListPopulate(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumSyncs, - SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock, - IMG_UINT32 *paui32SyncOffset); - -PVRSRV_ERROR -SyncAddrListAppendSyncPrim(SYNC_ADDR_LIST *psList, - PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim); -PVRSRV_ERROR -SyncAddrListAppendCheckpoints(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint); - -PVRSRV_ERROR -SyncAddrListAppendAndDeRefCheckpoints(SYNC_ADDR_LIST *psList, - IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint); - -void -SyncAddrListDeRefCheckpoints(IMG_UINT32 ui32NumCheckpoints, - PSYNC_CHECKPOINT *apsSyncCheckpoint); - -PVRSRV_ERROR -SyncAddrListRollbackCheckpoints(PVRSRV_DEVICE_NODE *psDevNode, SYNC_ADDR_LIST *psList); - -PVRSRV_ERROR -PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE * psDevNode, - SYNC_PRIMITIVE_BLOCK **ppsSyncBlk, - IMG_UINT32 *puiSyncPrimVAddr, - IMG_UINT32 *puiSyncPrimBlockSize, - PMR **ppsSyncPMR); - -PVRSRV_ERROR -PVRSRVExportSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, - DEVMEM_EXPORTCOOKIE **psExportCookie); - -PVRSRV_ERROR -PVRSRVUnexportSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk); - -PVRSRV_ERROR -PVRSRVFreeSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *ppsSyncBlk); - -PVRSRV_ERROR -PVRSRVSyncPrimSetKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Index, - IMG_UINT32 ui32Value); - -PVRSRV_ERROR -PVRSRVSyncAllocEventKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_BOOL bServerSync, - IMG_UINT32 ui32FWAddr, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName); - -PVRSRV_ERROR -PVRSRVSyncFreeEventKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 ui32FWAddr); - -PVRSRV_ERROR -PVRSRVSyncRecordAddKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - SYNC_RECORD_HANDLE *phRecord, - SYNC_PRIMITIVE_BLOCK *hServerSyncPrimBlock, - IMG_UINT32 ui32FwBlockAddr, - IMG_UINT32 ui32SyncOffset, - IMG_BOOL bServerSync, - IMG_UINT32 ui32ClassNameSize, - const IMG_CHAR *pszClassName); - -PVRSRV_ERROR -PVRSRVSyncRecordRemoveByHandleKM( - SYNC_RECORD_HANDLE hRecord); -void SyncRecordLookup(PVRSRV_DEVICE_NODE *psDevNode, IMG_UINT32 ui32FwAddr, - IMG_CHAR * pszSyncInfo, size_t len); - -PVRSRV_ERROR SyncRegisterConnection(SYNC_CONNECTION_DATA **ppsSyncConnectionData); -void SyncUnregisterConnection(SYNC_CONNECTION_DATA *ppsSyncConnectionData); -void SyncConnectionPDumpSyncBlocks(PVRSRV_DEVICE_NODE *psDevNode, void *hSyncPrivData, PDUMP_TRANSITION_EVENT eEvent); - -/*! -****************************************************************************** -@Function SyncServerInit - -@Description Per-device initialisation for the ServerSync module -******************************************************************************/ -PVRSRV_ERROR SyncServerInit(PVRSRV_DEVICE_NODE *psDevNode); -void SyncServerDeinit(PVRSRV_DEVICE_NODE *psDevNode); - - -#if defined(PDUMP) -PVRSRV_ERROR -PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset); - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value); - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiDumpFlags); - -PVRSRV_ERROR -PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset, - IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize); - -#else /* PDUMP */ - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVSyncPrimPDumpKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset) -{ - PVR_UNREFERENCED_PARAMETER(psSyncBlk); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVSyncPrimPDumpValueKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value) -{ - PVR_UNREFERENCED_PARAMETER(psSyncBlk); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVSyncPrimPDumpPolKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - PDUMP_FLAGS_T uiDumpFlags) -{ - PVR_UNREFERENCED_PARAMETER(psSyncBlk); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(ui32Value); - PVR_UNREFERENCED_PARAMETER(ui32Mask); - PVR_UNREFERENCED_PARAMETER(eOperator); - PVR_UNREFERENCED_PARAMETER(uiDumpFlags); - return PVRSRV_OK; -} - -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVSyncPrimPDumpCBPKM) -#endif -static INLINE PVRSRV_ERROR -PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset, - IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize, - IMG_UINT64 uiBufferSize) -{ - PVR_UNREFERENCED_PARAMETER(psSyncBlk); - PVR_UNREFERENCED_PARAMETER(ui32Offset); - PVR_UNREFERENCED_PARAMETER(uiWriteOffset); - PVR_UNREFERENCED_PARAMETER(uiPacketSize); - PVR_UNREFERENCED_PARAMETER(uiBufferSize); - return PVRSRV_OK; -} -#endif /* PDUMP */ -#endif /*SYNC_SERVER_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/syscommon.h b/drivers/gpu/drm/img-rogue/1.17/syscommon.h deleted file mode 100644 index 934974834e50d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/syscommon.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************/ /*! -@File -@Title Common System APIs and structures -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides common system-specific declarations and - macros that are supported by all systems -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /***************************************************************************/ - -#if !defined(SYSCOMMON_H) -#define SYSCOMMON_H - -#include "img_types.h" -#include "pvr_notifier.h" -#include "pvrsrv_device.h" -#include "pvrsrv_error.h" - -/*************************************************************************/ /*! -@Description Pointer to a Low-level Interrupt Service Routine (LISR). -@Input pvData Private data provided to the LISR. -@Return True if interrupt handled, false otherwise. -*/ /**************************************************************************/ -typedef IMG_BOOL (*PFN_LISR)(void *pvData); - -/**************************************************************************/ /*! -@Function SysDevInit -@Description System specific device initialisation function. -@Input pvOSDevice pointer to the OS device reference -@Input ppsDevConfig returned device configuration info -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /***************************************************************************/ -PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig); - -/**************************************************************************/ /*! -@Function SysDevDeInit -@Description System specific device deinitialisation function. -@Input psDevConfig device configuration info of the device to be - deinitialised -@Return None. -*/ /***************************************************************************/ -void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/**************************************************************************/ /*! -@Function SysDebugInfo -@Description Dump system specific device debug information. -@Input psDevConfig pointer to device configuration info -@Input pfnDumpDebugPrintf the 'printf' function to be called to - display the debug info -@Input pvDumpDebugFile optional file identifier to be passed to - the 'printf' function if required -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /***************************************************************************/ -PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig, - DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, - void *pvDumpDebugFile); - -/**************************************************************************/ /*! -@Function SysInstallDeviceLISR -@Description Installs the system Low-level Interrupt Service Routine (LISR) - which handles low-level processing of interrupts from the device - (GPU). - The LISR will be invoked when the device raises an interrupt. An - LISR may not be descheduled, so code which needs to do so should - be placed in an MISR. - The installed LISR will schedule any MISRs once it has completed - its interrupt processing, by calling OSScheduleMISR(). -@Input hSysData pointer to the system data of the device -@Input ui32IRQ the IRQ on which the LISR is to be installed -@Input pszName name of the module installing the LISR -@Input pfnLISR pointer to the function to be installed as the - LISR -@Input pvData private data provided to the LISR -@Output phLISRData handle to the installed LISR (to be used for a - subsequent uninstall) -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /***************************************************************************/ -PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData, - IMG_UINT32 ui32IRQ, - const IMG_CHAR *pszName, - PFN_LISR pfnLISR, - void *pvData, - IMG_HANDLE *phLISRData); - -/**************************************************************************/ /*! -@Function SysUninstallDeviceLISR -@Description Uninstalls the system Low-level Interrupt Service Routine (LISR) - which handles low-level processing of interrupts from the device - (GPU). -@Input hLISRData handle of the LISR to be uninstalled -@Return PVRSRV_OK on success, a failure code otherwise. -*/ /***************************************************************************/ -PVRSRV_ERROR SysUninstallDeviceLISR(IMG_HANDLE hLISRData); - -/**************************************************************************/ /*! -@Function SysRGXErrorNotify -@Description Error reporting callback function, registered as the - pfnSysDevErrorNotify member of the PVRSRV_DEVICE_CONFIG - struct. System layer will be notified of device errors and - resets via this callback. - NB. implementers should ensure that the minimal amount of - work is done in this callback function, as it will be - executed in the main RGX MISR. (e.g. any blocking or lengthy - work should be performed by a worker queue/thread instead). -@Input hSysData pointer to the system data of the device -@Output psErrorData structure containing details of the reported error -@Return None. -*/ /***************************************************************************/ -void SysRGXErrorNotify(IMG_HANDLE hSysData, - PVRSRV_ROBUSTNESS_NOTIFY_DATA *psErrorData); - -#endif /* !defined(SYSCOMMON_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/sysvalidation.h b/drivers/gpu/drm/img-rogue/1.17/sysvalidation.h deleted file mode 100644 index 5f6d5f9c67dce..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/sysvalidation.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Validation System APIs and structures -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides system-specific declarations and macros - needed for hardware validation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(SYSVALIDATION_H) -#define SYSVALIDATION_H - -#if defined(SUPPORT_GPUVIRT_VALIDATION) -#include "img_types.h" -#include "rgxdefs_km.h" -#include "virt_validation_defs.h" - -void SysInitVirtInitialization(IMG_UINT64 aui64OSidMin[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS], - IMG_UINT64 aui64OSidMax[GPUVIRT_VALIDATION_NUM_REGIONS][GPUVIRT_VALIDATION_NUM_OS]); - -#if defined(SUPPORT_GPUVIRT_VALIDATION) && defined(EMULATOR) -void SysSetAxiProtOSid(IMG_UINT32 ui32OSid, IMG_BOOL bState); -void SysSetTrustedDeviceAceEnabled(void); -#endif -#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */ - -#endif /* !defined(SYSVALIDATION_H) */ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlclient.c b/drivers/gpu/drm/img-rogue/1.17/tlclient.c deleted file mode 100644 index dc3f17a46812e..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlclient.c +++ /dev/null @@ -1,500 +0,0 @@ -/*************************************************************************/ /*! -@File tlclient.c -@Title Services Transport Layer shared API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport layer common API used in both clients and server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -/* DESIGN NOTE - * This transport layer consumer-role API was created as a shared API when a - * client wanted to read the data of a TL stream from within the KM server - * driver. This was in addition to the existing clients supported externally - * by the UM client library component via PVR API layer. - * This shared API is thus used by the PVR TL API in the client library and - * by clients internal to the server driver module. It depends on - * client entry points of the TL and DEVMEM bridge modules. These entry points - * encapsulate from the TL shared API whether a direct bridge or an indirect - * (ioctl) bridge is used. - * One reason for needing this layer centres around the fact that some of the - * API functions make multiple bridge calls and the logic that glues these - * together is common regardless of client location. Further this layer has - * allowed the defensive coding that checks parameters to move into the PVR - * API layer where untrusted clients enter giving a more efficient KM code path. - */ - -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "pvr_debug.h" -#include "osfunc.h" - -#include "allocmem.h" -#include "devicemem.h" - -#include "tlclient.h" -#include "pvrsrv_tlcommon.h" -#include "client_pvrtl_bridge.h" - -#if defined(__KERNEL__) -#include "srvcore.h" -#else -#include "srvcore_intern.h" -#endif - -/* Defines/Constants - */ - -#define NO_ACQUIRE 0xffffffffU - -/* User-side stream descriptor structure. - */ -typedef struct _TL_STREAM_DESC_ -{ - /* Handle on kernel-side stream descriptor*/ - IMG_HANDLE hServerSD; - - /* Stream data buffer variables */ - DEVMEM_MEMDESC* psUMmemDesc; - IMG_PBYTE pBaseAddr; - - /* Offset in bytes into the circular buffer and valid only after - * an Acquire call and undefined after a release. */ - IMG_UINT32 uiReadOffset; - - /* Always a positive integer when the Acquire call returns and a release - * is outstanding. Undefined at all other times. */ - IMG_UINT32 uiReadLen; - - /* Counter indicating how many writes to a stream failed. - * It's used to reduce number of errors in output log. */ - IMG_UINT32 ui32WritesFailed; - - /* Name of the stream. */ - IMG_CHAR szName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; -} TL_STREAM_DESC, *PTL_STREAM_DESC; - - -IMG_INTERNAL -PVRSRV_ERROR TLClientOpenStream(SHARED_DEV_CONNECTION hDevConnection, - const IMG_CHAR* pszName, - IMG_UINT32 ui32Mode, - IMG_HANDLE* phSD) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - TL_STREAM_DESC *psSD = NULL; - IMG_HANDLE hTLPMR; - IMG_HANDLE hTLImportHandle; - IMG_DEVMEM_SIZE_T uiImportSize; - PVRSRV_MEMALLOCFLAGS_T uiMemFlags = PVRSRV_MEMALLOCFLAG_CPU_READABLE; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(pszName); - PVR_ASSERT(phSD); - *phSD = NULL; - - /* Allocate memory for the stream descriptor object, initialise with - * "no data read" yet. */ - psSD = OSAllocZMem(sizeof(TL_STREAM_DESC)); - PVR_LOG_GOTO_IF_NOMEM(psSD, eError, e0); - psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE; - - /* Send open stream request to kernel server to get stream handle and - * buffer cookie so we can get access to the buffer in this process. */ - eError = BridgeTLOpenStream(GetBridgeHandle(hDevConnection), pszName, - ui32Mode, &psSD->hServerSD, &hTLPMR); - if (eError != PVRSRV_OK) - { - if ((ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WAIT) && - (eError == PVRSRV_ERROR_TIMEOUT)) - { - goto e1; - } - PVR_LOG_GOTO_IF_ERROR(eError, "BridgeTLOpenStream", e1); - } - - /* Convert server export cookie into a cookie for use by this client */ - eError = DevmemMakeLocalImportHandle(hDevConnection, - hTLPMR, &hTLImportHandle); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemMakeLocalImportHandle", e2); - - uiMemFlags |= ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WO ? - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE : 0ULL; - /* Now convert client cookie into a client handle on the buffer's - * physical memory region */ - eError = DevmemLocalImport(hDevConnection, - hTLImportHandle, - uiMemFlags, - &psSD->psUMmemDesc, - &uiImportSize, - "TLBuffer"); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemImport", e3); - - /* Now map the memory into the virtual address space of this process. */ - eError = DevmemAcquireCpuVirtAddr(psSD->psUMmemDesc, (void **) - &psSD->pBaseAddr); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", e4); - - /* Ignore error, not much that can be done */ - (void) DevmemUnmakeLocalImportHandle(hDevConnection, - hTLImportHandle); - - /* Copy stream name */ - OSStringLCopy(psSD->szName, pszName, PRVSRVTL_MAX_STREAM_NAME_SIZE); - - /* Return client descriptor handle to caller */ - *phSD = psSD; - return PVRSRV_OK; - -/* Clean up post buffer setup */ -e4: - DevmemFree(psSD->psUMmemDesc); -e3: - (void) DevmemUnmakeLocalImportHandle(hDevConnection, - &hTLImportHandle); -/* Clean up post stream open */ -e2: - BridgeTLCloseStream(GetBridgeHandle(hDevConnection), psSD->hServerSD); - -/* Clean up post allocation of the descriptor object */ -e1: - OSFreeMem(psSD); - -e0: - return eError; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientCloseStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - - /* Check the caller provided connection is valid */ - if (!psSD->hServerSD) - { - PVR_DPF((PVR_DBG_ERROR, "%s: descriptor already " - "closed/not open", __func__)); - return PVRSRV_ERROR_HANDLE_NOT_FOUND; - } - - /* Check if acquire is outstanding, perform release if it is, ignore result - * as there is not much we can do if it is an error other than close */ - if (psSD->uiReadLen != NO_ACQUIRE) - { - (void) BridgeTLReleaseData(GetBridgeHandle(hDevConnection), - psSD->hServerSD, psSD->uiReadOffset, psSD->uiReadLen); - psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE; - } - - /* Clean up DevMem resources used for this stream in this client */ - DevmemReleaseCpuVirtAddr(psSD->psUMmemDesc); - - DevmemFree(psSD->psUMmemDesc); - - /* Send close to server to clean up kernel mode resources for this - * handle and release the memory. */ - eError = DestroyServerResource(hDevConnection, - NULL, - BridgeTLCloseStream, - psSD->hServerSD); - PVR_LOG_IF_ERROR(eError, "BridgeTLCloseStream"); - - if (psSD->ui32WritesFailed != 0) - { - PVR_DPF((PVR_DBG_ERROR, "%s() %u writes failed to stream %s (%c)", - __func__, psSD->ui32WritesFailed, psSD->szName, - psSD->ui32WritesFailed == IMG_UINT32_MAX ? 'T' : 'F')); - } - - OSCachedMemSet(psSD, 0x00, sizeof(TL_STREAM_DESC)); - OSFreeMem(psSD); - - return eError; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientDiscoverStreams(SHARED_DEV_CONNECTION hDevConnection, - const IMG_CHAR *pszNamePattern, - IMG_CHAR aszStreams[][PRVSRVTL_MAX_STREAM_NAME_SIZE], - IMG_UINT32 *pui32NumFound) -{ - PVR_ASSERT(hDevConnection); - PVR_ASSERT(pszNamePattern); - PVR_ASSERT(pui32NumFound); - - return BridgeTLDiscoverStreams(GetBridgeHandle(hDevConnection), - pszNamePattern, - /* we need to treat this as one dimensional array */ - *pui32NumFound * PRVSRVTL_MAX_STREAM_NAME_SIZE, - (IMG_CHAR *) aszStreams, - pui32NumFound); -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientReserveStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - IMG_UINT32 ui32BufferOffset, ui32Unused; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - PVR_ASSERT(ppui8Data); - PVR_ASSERT(ui32Size); - - eError = BridgeTLReserveStream(GetBridgeHandle(hDevConnection), - psSD->hServerSD, &ui32BufferOffset, ui32Size, ui32Size, &ui32Unused); - PVR_RETURN_IF_ERROR(eError); - - *ppui8Data = psSD->pBaseAddr + ui32BufferOffset; - - return PVRSRV_OK; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientReserveStream2(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32 *pui32Available) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - IMG_UINT32 ui32BufferOffset; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - PVR_ASSERT(ppui8Data); - PVR_ASSERT(ui32Size); - - eError = BridgeTLReserveStream(GetBridgeHandle(hDevConnection), - psSD->hServerSD, &ui32BufferOffset, ui32Size, ui32SizeMin, - pui32Available); - PVR_RETURN_IF_ERROR(eError); - - *ppui8Data = psSD->pBaseAddr + ui32BufferOffset; - - return PVRSRV_OK; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientCommitStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - PVR_ASSERT(ui32Size); - - eError = BridgeTLCommitStream(GetBridgeHandle(hDevConnection), - psSD->hServerSD, ui32Size); - PVR_RETURN_IF_ERROR(eError); - - return PVRSRV_OK; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientAcquireData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_PBYTE* ppPacketBuf, - IMG_UINT32* pui32BufLen) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - PVR_ASSERT(ppPacketBuf); - PVR_ASSERT(pui32BufLen); - - /* In case of non-blocking acquires, which can return no data, and - * error paths ensure we clear the output parameters first. */ - *ppPacketBuf = NULL; - *pui32BufLen = 0; - - /* Check Acquire has not been called twice in a row without a release */ - if (psSD->uiReadOffset != NO_ACQUIRE) - { - PVR_DPF((PVR_DBG_ERROR, "%s: acquire already " - "outstanding, ReadOffset(%d), ReadLength(%d)", - __func__, psSD->uiReadOffset, psSD->uiReadLen)); - return PVRSRV_ERROR_RETRY; - } - - /* Ask the kernel server for the next chunk of data to read */ - eError = BridgeTLAcquireData(GetBridgeHandle(hDevConnection), - psSD->hServerSD, &psSD->uiReadOffset, &psSD->uiReadLen); - if (eError != PVRSRV_OK) - { - /* Mask reporting of the errors seen under normal operation */ - if ((eError != PVRSRV_ERROR_RESOURCE_UNAVAILABLE) && - (eError != PVRSRV_ERROR_TIMEOUT) && - (eError != PVRSRV_ERROR_STREAM_READLIMIT_REACHED)) - { - PVR_LOG_ERROR(eError, "BridgeTLAcquireData"); - } - psSD->uiReadOffset = psSD->uiReadLen = NO_ACQUIRE; - return eError; - } - /* else PVRSRV_OK */ - - /* Return the data offset and length to the caller if bytes are available - * to be read. Could be zero for non-blocking mode so pass back cleared - * values above */ - if (psSD->uiReadLen) - { - *ppPacketBuf = psSD->pBaseAddr + psSD->uiReadOffset; - *pui32BufLen = psSD->uiReadLen; - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR _TLClientReleaseDataLen( - SHARED_DEV_CONNECTION hDevConnection, - TL_STREAM_DESC* psSD, - IMG_UINT32 uiReadLen) -{ - PVRSRV_ERROR eError; - - /* the previous acquire did not return any data, this is a no-operation */ - if (psSD->uiReadLen == 0) - { - return PVRSRV_OK; - } - - /* Check release has not been called twice in a row without an acquire */ - if (psSD->uiReadOffset == NO_ACQUIRE) - { - PVR_DPF((PVR_DBG_ERROR, "%s: no acquire to release", __func__)); - return PVRSRV_ERROR_RETRY; - } - - /* Inform the kernel to release the data from the buffer */ - eError = BridgeTLReleaseData(GetBridgeHandle(hDevConnection), - psSD->hServerSD, - psSD->uiReadOffset, uiReadLen); - PVR_LOG_IF_ERROR(eError, "BridgeTLReleaseData"); - - /* Reset state to indicate no outstanding acquire */ - psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE; - - return eError; -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientReleaseData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD) -{ - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - - return _TLClientReleaseDataLen(hDevConnection, psSD, psSD->uiReadLen); -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientReleaseDataLess(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, IMG_UINT32 uiActualReadLen) -{ - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - - /* Check the specified size is within the size returned by Acquire */ - if (uiActualReadLen > psSD->uiReadLen) - { - PVR_DPF((PVR_DBG_ERROR, "%s: no acquire to release", __func__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return _TLClientReleaseDataLen(hDevConnection, psSD, uiActualReadLen); -} - -IMG_INTERNAL -PVRSRV_ERROR TLClientWriteData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size, - IMG_BYTE *pui8Data) -{ - PVRSRV_ERROR eError; - TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD; - - PVR_ASSERT(hDevConnection); - PVR_ASSERT(hSD); - PVR_ASSERT(ui32Size); - PVR_ASSERT(pui8Data); - - eError = BridgeTLWriteData(GetBridgeHandle(hDevConnection), - psSD->hServerSD, ui32Size, pui8Data); - - if (eError == PVRSRV_ERROR_STREAM_FULL) - { - if (psSD->ui32WritesFailed == 0) - { - PVR_LOG_ERROR(eError, "BridgeTLWriteData"); - } - if (psSD->ui32WritesFailed != IMG_UINT32_MAX) - { - psSD->ui32WritesFailed++; - } - } - else if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "BridgeTLWriteData"); - } - - return eError; -} - -/****************************************************************************** - End of file (tlclient.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlclient.h b/drivers/gpu/drm/img-rogue/1.17/tlclient.h deleted file mode 100644 index 00f7aa8fc0433..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlclient.h +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************/ /*! -@File tlclient.h -@Title Services Transport Layer shared API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport layer common API used in both clients and server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TLCLIENT_H -#define TLCLIENT_H - - -#include "img_defs.h" -#include "pvrsrv_tlcommon.h" -#include "pvrsrv_error.h" - - -/* This value is used for the hSrvHandle argument in the client API when - * called directly from the kernel which will lead to a direct bridge access. - */ -#define DIRECT_BRIDGE_HANDLE ((IMG_HANDLE)0xDEADBEEFU) - - -/*************************************************************************/ /*! - @Function TLClientOpenStream - @Description Open a descriptor onto an existing kernel transport stream. - @Input hDevConnection Address of a pointer to a connection object - @Input pszName Address of the stream name string, no longer - than PRVSRVTL_MAX_STREAM_NAME_SIZE. - @Input ui32Mode Unused - @Output phSD Address of a pointer to an stream object - @Return PVRSRV_ERROR_NOT_FOUND when named stream not found - @Return PVRSRV_ERROR_ALREADY_OPEN stream already open by another - @Return PVRSRV_ERROR_STREAM_ERROR internal driver state error - @Return PVRSRV_ERROR_TIMEOUT timed out, stream not found - @Return PVRSRV_ERROR for other system codes -*/ /**************************************************************************/ - -IMG_INTERNAL -PVRSRV_ERROR TLClientOpenStream(SHARED_DEV_CONNECTION hDevConnection, - const IMG_CHAR* pszName, - IMG_UINT32 ui32Mode, - IMG_HANDLE* phSD); - - -/*************************************************************************/ /*! - @Function TLClientCloseStream - @Description Close and release the stream connection to Services kernel - server transport layer. Any outstanding Acquire will be - released. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to close - @Return PVRSRV_ERROR_HANDLE_NOT_FOUND when SD handle is not known - @Return PVRSRV_ERROR_STREAM_ERROR internal driver state error - @Return PVRSRV_ERROR for system codes -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientCloseStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD); - -/*************************************************************************/ /*! - @Function TLClientDiscoverStreams - @Description Finds all streams that's name starts with pszNamePattern and - ends with a number. - @Input hDevConnection Address of a pointer to a connection object - @Input pszNamePattern Name pattern. Must be beginning of a string. - @Output aszStreams Array of numbers from end of the discovered - names. - @inOut pui32NumFound When input, max number that can fit into - pui32Streams. When output, number of - discovered streams. - @Return PVRSRV_ERROR for system codes -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientDiscoverStreams(SHARED_DEV_CONNECTION hDevConnection, - const IMG_CHAR *pszNamePattern, - IMG_CHAR aszStreams[][PRVSRVTL_MAX_STREAM_NAME_SIZE], - IMG_UINT32 *pui32NumFound); - -/*************************************************************************/ /*! - @Function TLClientReserveStream - @Description Reserves a region with given size in the stream. If the stream - is already reserved the function will return an error. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to close - @Output ppui8Data pointer to the buffer - @Input ui32Size size of the data - @Return -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientReserveStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size); - -/*************************************************************************/ /*! - @Function TLClientStreamReserve2 - @Description Reserves a region with given size in the stream. If the stream - is already reserved the function will return an error. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to close - @Output ppui8Data pointer to the buffer - @Input ui32Size size of the data - @Input ui32SizeMin minimum size of the data - @Input ui32Available available space in buffer - @Return -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientReserveStream2(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32 *pui32Available); - -/*************************************************************************/ /*! - @Function TLClientStreamCommit - @Description Commits previously reserved region in the stream and therefore - allows next reserves. - This function call has to be preceded by the call to - TLClientReserveStream or TLClientReserveStream2. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to close - @Input ui32Size Size of the data - @Return -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientCommitStream(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size); - -/*************************************************************************/ /*! - @Function TLClientAcquireData - @Description When there is data available in the stream buffer this call - returns with the address and length of the data buffer the - client can safely read. This buffer may contain one or more - packets of data. - If no data is available then this call blocks until it becomes - available. However if the stream has been destroyed while - waiting then a resource unavailable error will be returned to - the caller. Clients must pair this call with a ReleaseData - call. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to read - @Output ppPacketBuf Address of a pointer to an byte buffer. On exit - pointer contains address of buffer to read from - @Output puiBufLen Pointer to an integer. On exit it is the size - of the data to read from the packet buffer - @Return PVRSRV_ERROR_RESOURCE_UNAVAILABLE when stream no longer exists - @Return PVRSRV_ERROR_HANDLE_NOT_FOUND when SD handle not known - @Return PVRSRV_ERROR_STREAM_ERROR internal driver state error - @Return PVRSRV_ERROR_RETRY release not called beforehand - @Return PVRSRV_ERROR_TIMEOUT block timed out, no data - @Return PVRSRV_ERROR for other system codes -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientAcquireData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_PBYTE* ppPacketBuf, - IMG_UINT32* puiBufLen); - - -/*************************************************************************/ /*! - @Function TLClientReleaseData - @Description Called after client has read the stream data out of the buffer - The data is subsequently flushed from the stream buffer to make - room for more data packets from the stream source. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to read - @Return PVRSRV_ERROR_RESOURCE_UNAVAILABLE when stream no longer exists - @Return PVRSRV_ERROR_HANDLE_NOT_FOUND when SD handle not known to TL - @Return PVRSRV_ERROR_STREAM_ERROR internal driver state error - @Return PVRSRV_ERROR_RETRY acquire not called beforehand - @Return PVRSRV_ERROR for system codes -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientReleaseData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD); - -/*************************************************************************/ /*! - @Function TLClientReleaseDataLess - @Description Called after client has read only some data out of the buffer - and wishes to complete the read early i.e. does not want to - read the full data that the acquire call returned e.g read just - one packet from the stream. - The data is subsequently flushed from the stream buffer to make - room for more data packets from the stream source. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to read - @Input uiActualReadLen Size of data read, in bytes. Must be on a TL - packet boundary. - @Return PVRSRV_ERROR_INVALID_PARAMS when read length too big - @Return PVRSRV_ERROR_RESOURCE_UNAVAILABLE when stream no longer exists - @Return PVRSRV_ERROR_HANDLE_NOT_FOUND when SD handle not known to TL - @Return PVRSRV_ERROR_STREAM_ERROR internal driver state error - @Return PVRSRV_ERROR_RETRY acquire not called beforehand - @Return PVRSRV_ERROR for system codes -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientReleaseDataLess(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, IMG_UINT32 uiActualReadLen); - -/*************************************************************************/ /*! - @Function TLClientWriteData - @Description Writes data to the stream. - @Input hDevConnection Address of a pointer to a connection object - @Input hSD Handle of the stream object to read - @Input ui32Size Size of the data - @Input pui8Data Pointer to data -*/ /**************************************************************************/ -IMG_INTERNAL -PVRSRV_ERROR TLClientWriteData(SHARED_DEV_CONNECTION hDevConnection, - IMG_HANDLE hSD, - IMG_UINT32 ui32Size, - IMG_BYTE *pui8Data); - - -#endif /* TLCLIENT_H */ - -/****************************************************************************** - End of file (tlclient.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlintern.c b/drivers/gpu/drm/img-rogue/1.17/tlintern.c deleted file mode 100644 index 2c84ebf7b1940..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlintern.c +++ /dev/null @@ -1,442 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Transport Layer kernel side API implementation. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport Layer functions available to driver components in - the driver. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ -//#define PVR_DPF_FUNCTION_TRACE_ON 1 -#undef PVR_DPF_FUNCTION_TRACE_ON -#include "pvr_debug.h" - -#include "allocmem.h" -#include "pvrsrv_error.h" -#include "osfunc.h" -#include "devicemem.h" - -#include "pvrsrv_tlcommon.h" -#include "tlintern.h" - -/* - * Make functions - */ -PTL_STREAM_DESC -TLMakeStreamDesc(PTL_SNODE f1, IMG_UINT32 f2, IMG_HANDLE f3) -{ - PTL_STREAM_DESC ps = OSAllocZMem(sizeof(TL_STREAM_DESC)); - if (ps == NULL) - { - return NULL; - } - ps->psNode = f1; - ps->ui32Flags = f2; - ps->hReadEvent = f3; - ps->uiRefCount = 1; - - if (f2 & PVRSRV_STREAM_FLAG_READ_LIMIT) - { - ps->ui32ReadLimit = f1->psStream->ui32Write; - } - return ps; -} - -PTL_SNODE -TLMakeSNode(IMG_HANDLE f2, TL_STREAM *f3, TL_STREAM_DESC *f4) -{ - PTL_SNODE ps = OSAllocZMem(sizeof(TL_SNODE)); - if (ps == NULL) - { - return NULL; - } - ps->hReadEventObj = f2; - ps->psStream = f3; - ps->psRDesc = f4; - f3->psNode = ps; - return ps; -} - -/* - * Transport Layer Global top variables and functions - */ -static TL_GLOBAL_DATA sTLGlobalData; - -TL_GLOBAL_DATA *TLGGD(void) /* TLGetGlobalData() */ -{ - return &sTLGlobalData; -} - -/* TLInit must only be called once at driver initialisation. - * An assert is provided to check this condition on debug builds. - */ -PVRSRV_ERROR -TLInit(void) -{ - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - PVR_ASSERT(sTLGlobalData.hTLGDLock == NULL && sTLGlobalData.hTLEventObj == NULL); - - /* Allocate a lock for TL global data, to be used while updating the TL data. - * This is for making TL global data multi-thread safe */ - eError = OSLockCreate(&sTLGlobalData.hTLGDLock); - PVR_GOTO_IF_ERROR(eError, e0); - - /* Allocate the event object used to signal global TL events such as - * a new stream created */ - eError = OSEventObjectCreate("TLGlobalEventObj", &sTLGlobalData.hTLEventObj); - PVR_GOTO_IF_ERROR(eError, e1); - - PVR_DPF_RETURN_OK; - -/* Don't allow the driver to start up on error */ -e1: - OSLockDestroy (sTLGlobalData.hTLGDLock); - sTLGlobalData.hTLGDLock = NULL; -e0: - PVR_DPF_RETURN_RC (eError); -} - -static void RemoveAndFreeStreamNode(PTL_SNODE psRemove) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE* last; - PTL_SNODE psn; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - /* Unlink the stream node from the master list */ - PVR_ASSERT(psGD->psHead); - last = &psGD->psHead; - for (psn = psGD->psHead; psn; psn=psn->psNext) - { - if (psn == psRemove) - { - /* Other calling code may have freed and zeroed the pointers */ - if (psn->psRDesc) - { - OSFreeMem(psn->psRDesc); - psn->psRDesc = NULL; - } - if (psn->psStream) - { - OSFreeMem(psn->psStream); - psn->psStream = NULL; - } - *last = psn->psNext; - break; - } - last = &psn->psNext; - } - - /* Release the event list object owned by the stream node */ - if (psRemove->hReadEventObj) - { - eError = OSEventObjectDestroy(psRemove->hReadEventObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - - psRemove->hReadEventObj = NULL; - } - - /* Release the memory of the stream node */ - OSFreeMem(psRemove); - - PVR_DPF_RETURN; -} - -static void FreeGlobalData(void) -{ - PTL_SNODE psCurrent = sTLGlobalData.psHead; - PTL_SNODE psNext; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - /* Clean up the SNODE list */ - if (psCurrent) - { - while (psCurrent) - { - psNext = psCurrent->psNext; - - /* Other calling code may have freed and zeroed the pointers */ - if (psCurrent->psRDesc) - { - OSFreeMem(psCurrent->psRDesc); - psCurrent->psRDesc = NULL; - } - if (psCurrent->psStream) - { - OSFreeMem(psCurrent->psStream); - psCurrent->psStream = NULL; - } - - /* Release the event list object owned by the stream node */ - if (psCurrent->hReadEventObj) - { - eError = OSEventObjectDestroy(psCurrent->hReadEventObj); - PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy"); - - psCurrent->hReadEventObj = NULL; - } - - OSFreeMem(psCurrent); - psCurrent = psNext; - } - - sTLGlobalData.psHead = NULL; - } - - PVR_DPF_RETURN; -} - -void -TLDeInit(void) -{ - PVR_DPF_ENTERED; - - if (sTLGlobalData.uiClientCnt) - { - PVR_DPF((PVR_DBG_ERROR, "TLDeInit transport layer but %d client streams are still connected", sTLGlobalData.uiClientCnt)); - sTLGlobalData.uiClientCnt = 0; - } - - FreeGlobalData(); - - /* Clean up the TL global event object */ - if (sTLGlobalData.hTLEventObj) - { - OSEventObjectDestroy(sTLGlobalData.hTLEventObj); - sTLGlobalData.hTLEventObj = NULL; - } - - /* Destroy the TL global data lock */ - if (sTLGlobalData.hTLGDLock) - { - OSLockDestroy (sTLGlobalData.hTLGDLock); - sTLGlobalData.hTLGDLock = NULL; - } - - PVR_DPF_RETURN; -} - -void TLAddStreamNode(PTL_SNODE psAdd) -{ - PVR_DPF_ENTERED; - - PVR_ASSERT(psAdd); - psAdd->psNext = TLGGD()->psHead; - TLGGD()->psHead = psAdd; - - PVR_DPF_RETURN; -} - -PTL_SNODE TLFindStreamNodeByName(const IMG_CHAR *pszName) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psn; - - PVR_DPF_ENTERED; - - PVR_ASSERT(pszName); - - for (psn = psGD->psHead; psn; psn=psn->psNext) - { - if (psn->psStream && OSStringNCompare(psn->psStream->szName, pszName, PRVSRVTL_MAX_STREAM_NAME_SIZE)==0) - { - PVR_DPF_RETURN_VAL(psn); - } - } - - PVR_DPF_RETURN_VAL(NULL); -} - -PTL_SNODE TLFindStreamNodeByDesc(PTL_STREAM_DESC psDesc) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psn; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psDesc); - - for (psn = psGD->psHead; psn; psn=psn->psNext) - { - if (psn->psRDesc == psDesc || psn->psWDesc == psDesc) - { - PVR_DPF_RETURN_VAL(psn); - } - } - PVR_DPF_RETURN_VAL(NULL); -} - -IMG_UINT32 TLDiscoverStreamNodes(const IMG_CHAR *pszNamePattern, - IMG_CHAR aaszStreams[][PRVSRVTL_MAX_STREAM_NAME_SIZE], - IMG_UINT32 ui32Max) -{ - TL_GLOBAL_DATA *psGD = TLGGD(); - PTL_SNODE psn; - IMG_UINT32 ui32Count = 0; - size_t uiLen; - - PVR_ASSERT(pszNamePattern); - - if ((uiLen = OSStringLength(pszNamePattern)) == 0) - return 0; - - for (psn = psGD->psHead; psn; psn = psn->psNext) - { - if (OSStringNCompare(pszNamePattern, psn->psStream->szName, uiLen) != 0) - continue; - - /* If aaszStreams is NULL we only count how many string match - * the given pattern. If it's a valid pointer we also return - * the names. */ - if (aaszStreams != NULL) - { - if (ui32Count >= ui32Max) - break; - - /* all of names are shorter than MAX and null terminated */ - OSStringLCopy(aaszStreams[ui32Count], psn->psStream->szName, - PRVSRVTL_MAX_STREAM_NAME_SIZE); - } - - ui32Count++; - } - - return ui32Count; -} - -PTL_SNODE TLFindAndGetStreamNodeByDesc(PTL_STREAM_DESC psDesc) -{ - PTL_SNODE psn; - - PVR_DPF_ENTERED; - - psn = TLFindStreamNodeByDesc(psDesc); - if (psn == NULL) - PVR_DPF_RETURN_VAL(NULL); - - PVR_ASSERT(psDesc == psn->psWDesc); - - psn->uiWRefCount++; - psDesc->uiRefCount++; - - PVR_DPF_RETURN_VAL(psn); -} - -void TLReturnStreamNode(PTL_SNODE psNode) -{ - psNode->uiWRefCount--; - psNode->psWDesc->uiRefCount--; - - PVR_ASSERT(psNode->uiWRefCount > 0); - PVR_ASSERT(psNode->psWDesc->uiRefCount > 0); -} - -IMG_BOOL TLTryRemoveStreamAndFreeStreamNode(PTL_SNODE psRemove) -{ - PVR_DPF_ENTERED; - - PVR_ASSERT(psRemove); - - /* If there is a client connected to this stream, defer stream's deletion */ - if (psRemove->psRDesc != NULL || psRemove->psWDesc != NULL) - { - PVR_DPF_RETURN_VAL(IMG_FALSE); - } - - /* Remove stream from TL_GLOBAL_DATA's list and free stream node */ - psRemove->psStream = NULL; - RemoveAndFreeStreamNode(psRemove); - - PVR_DPF_RETURN_VAL(IMG_TRUE); -} - -IMG_BOOL TLUnrefDescAndTryFreeStreamNode(PTL_SNODE psNodeToRemove, - PTL_STREAM_DESC psSD) -{ - PVR_DPF_ENTERED; - - PVR_ASSERT(psNodeToRemove); - PVR_ASSERT(psSD); - - /* Decrement reference count. For descriptor obtained by reader it must - * reach 0 (only single reader allowed) and for descriptors obtained by - * writers it must reach value greater or equal to 0 (multiple writers - * model). */ - psSD->uiRefCount--; - - if (psSD == psNodeToRemove->psRDesc) - { - PVR_ASSERT(0 == psSD->uiRefCount); - /* Remove stream descriptor (i.e. stream reader context) */ - psNodeToRemove->psRDesc = NULL; - } - else if (psSD == psNodeToRemove->psWDesc) - { - PVR_ASSERT(0 <= psSD->uiRefCount); - - psNodeToRemove->uiWRefCount--; - - /* Remove stream descriptor if reference == 0 */ - if (0 == psSD->uiRefCount) - { - psNodeToRemove->psWDesc = NULL; - } - } - - /* Do not Free Stream Node if there is a write reference (a producer - * context) to the stream */ - if (NULL != psNodeToRemove->psRDesc || NULL != psNodeToRemove->psWDesc || - 0 != psNodeToRemove->uiWRefCount) - { - PVR_DPF_RETURN_VAL(IMG_FALSE); - } - - /* Make stream pointer NULL to prevent it from being destroyed in - * RemoveAndFreeStreamNode. Cleanup of stream should be done by the - * calling context */ - psNodeToRemove->psStream = NULL; - RemoveAndFreeStreamNode(psNodeToRemove); - - PVR_DPF_RETURN_VAL(IMG_TRUE); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/tlintern.h b/drivers/gpu/drm/img-rogue/1.17/tlintern.h deleted file mode 100644 index c3edce6b8cd17..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlintern.h +++ /dev/null @@ -1,345 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Transport Layer internals -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport Layer header used by TL internally -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TLINTERN_H -#define TLINTERN_H - - -#include "devicemem_typedefs.h" -#include "pvrsrv_tlcommon.h" -#include "lock.h" -#include "tlstream.h" - -/* Forward declarations */ -typedef struct _TL_SNODE_* PTL_SNODE; - -/* To debug buffer utilisation enable this macro here and define - * PVRSRV_NEED_PVR_TRACE in the server pvr_debug.c and in tutils.c - * before the inclusion of pvr_debug.h. - * Issue pvrtutils 6 on target to see stream buffer utilisation. */ -//#define TL_BUFFER_STATS 1 - -/*! TL stream structure container. - * pbyBuffer holds the circular buffer. - * ui32Read points to the beginning of the buffer, ie to where data to - * Read begin. - * ui32Write points to the end of data that have been committed, ie this is - * where new data will be written. - * ui32Pending number of bytes reserved in last reserve call which have not - * yet been submitted. Therefore these data are not ready to - * be transported. - * hStreamWLock - provides atomic protection for the ui32Pending & ui32Write - * members of the structure for when they are checked and/or - * updated in the context of a stream writer (producer) - * calling DoTLStreamReserve() & TLStreamCommit(). - * - Reader context is not multi-threaded, only one client per - * stream is allowed. Also note the read context may be in an - * ISR which prevents a design where locks can be held in the - * AcquireData/ReleaseData() calls. Thus this lock only - * protects the stream members from simultaneous writers. - * - * ui32Read < ui32Write <= ui32Pending - * where < and <= operators are overloaded to make sense in a circular way. - */ -typedef struct _TL_STREAM_ -{ - IMG_CHAR szName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; /*!< String name identifier */ - TL_OPMODE eOpMode; /*!< Mode of Operation of TL Buffer */ - - IMG_BOOL bWaitForEmptyOnDestroy; /*!< Flag: On destroying a non-empty stream block until - * stream is drained. */ - IMG_BOOL bNoSignalOnCommit; /*!< Flag: Used to avoid the TL signalling waiting consumers - * that new data is available on every commit. Producers - * using this flag will need to manually signal when - * appropriate using the TLStreamSync() API */ - - void (*pfOnReaderOpenCallback)(void *pvArg); /*!< Optional on reader connect callback */ - void *pvOnReaderOpenUserData; /*!< On reader connect user data */ - void (*pfProducerCallback)(void); /*!< Optional producer callback of type TL_STREAM_SOURCECB */ - void *pvProducerUserData; /*!< Producer callback user data */ - - struct _TL_STREAM_ *psNotifStream; /*!< Pointer to the stream to which notification will be sent */ - - volatile IMG_UINT32 ui32Read; /*!< Pointer to the beginning of available data */ - volatile IMG_UINT32 ui32Write; /*!< Pointer to already committed data which are ready to be - * copied to user space */ - IMG_UINT32 ui32Pending; /*!< Count pending bytes reserved in buffer */ - IMG_UINT32 ui32Size; /*!< Buffer size */ - IMG_UINT32 ui32ThresholdUsageForSignal; /*!< Buffer usage threshold at which a TL writer signals a blocked/ - * waiting reader when transitioning from empty->non-empty */ - IMG_UINT32 ui32MaxPacketSize; /*! Max TL packet size */ - IMG_BYTE *pbyBuffer; /*!< Actual data buffer */ - - PTL_SNODE psNode; /*!< Ptr to parent stream node */ - DEVMEM_MEMDESC *psStreamMemDesc; /*!< MemDescriptor used to allocate buffer space through PMR */ - - IMG_HANDLE hProducerEvent; /*!< Handle to wait on if there is not enough space */ - IMG_HANDLE hProducerEventObj; /*!< Handle to signal blocked reserve calls */ - IMG_BOOL bSignalPending; /*!< Tracks if a "signal" is pending to be sent to a blocked/ - * waiting reader */ - - POS_LOCK hStreamWLock; /*!< Writers Lock for ui32Pending & ui32Write*/ - POS_LOCK hReadLock; /*!< Readers Lock for bReadPending & ui32Read*/ - IMG_BOOL bReadPending; /*!< Tracks if a read operation is pending or not*/ - IMG_BOOL bNoWrapPermanent; /*!< Flag: Prevents buffer wrap and subsequent data loss - * as well as resetting the read position on close. */ - -#if defined(TL_BUFFER_STATS) - IMG_UINT32 ui32CntReadFails; /*!< Tracks how many times reader failed to acquire read lock */ - IMG_UINT32 ui32CntReadSuccesses; /*!< Tracks how many times reader acquires read lock successfully */ - IMG_UINT32 ui32CntWriteSuccesses; /*!< Tracks how many times writer acquires read lock successfully */ - IMG_UINT32 ui32CntWriteWaits; /*!< Tracks how many times writer had to wait to acquire read lock */ - IMG_UINT32 ui32CntNumWriteSuccess; /*!< Tracks how many write operations were successful*/ - IMG_UINT32 ui32BufferUt; /*!< Buffer utilisation high watermark, see TL_BUFFER_STATS above */ - IMG_UINT32 ui32MaxReserveWatermark; /*!< Max stream reserve size that was ever requested by a writer */ - IMG_UINT32 ui32SignalsSent; /*!< Number of signals that were actually sent by the write API */ - ATOMIC_T bNoReaderSinceFirstReserve; /*!< Tracks if a read has been done since the buffer was last found empty */ - IMG_UINT32 ui32TimeStart; /*!< Time at which a write (Reserve call) was done into an empty buffer. - * Guarded by hStreamWLock. */ - IMG_UINT32 ui32MinTimeToFullInUs; /*!< Minimum time taken to (nearly) fully fill an empty buffer. Guarded - * by hStreamWLock. */ - /* Behaviour counters, protected by hStreamLock in case of - * multi-threaded access */ - IMG_UINT32 ui32NumCommits; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32SignalNotSent; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32ManSyncs; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32ProducerByteCount; /*!< Counters used to analysing stream performance, see ++ loc */ - - /* Not protected by the lock, inc in the reader thread which is currently singular */ - IMG_UINT32 ui32AcquireRead1; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32AcquireRead2; /*!< Counters used to analysing stream performance, see ++ loc */ -#endif - -} TL_STREAM, *PTL_STREAM; - -/* there need to be enough space reserved in the buffer for 2 minimal packets - * and it needs to be aligned the same way the buffer is or there will be a - * compile error.*/ -#define BUFFER_RESERVED_SPACE (2 * PVRSRVTL_PACKET_ALIGNMENT) - -/* ensure the space reserved follows the buffer's alignment */ -static_assert(!(BUFFER_RESERVED_SPACE&(PVRSRVTL_PACKET_ALIGNMENT-1)), - "BUFFER_RESERVED_SPACE must be a multiple of PVRSRVTL_PACKET_ALIGNMENT"); - -/* Define the largest value that a uint that matches the - * PVRSRVTL_PACKET_ALIGNMENT size can hold */ -#define MAX_UINT 0xffffFFFF - -/*! Defines the value used for TL_STREAM.ui32Pending when no reserve is - * outstanding on the stream. */ -#define NOTHING_PENDING IMG_UINT32_MAX - - -/* - * Transport Layer Stream Descriptor types/defs - */ -typedef struct _TL_STREAM_DESC_ -{ - PTL_SNODE psNode; /*!< Ptr to parent stream node */ - IMG_UINT32 ui32Flags; /*!< Flags supplied by client on stream open */ - IMG_HANDLE hReadEvent; /*!< For wait call (only used/set in reader descriptors) */ - IMG_INT uiRefCount; /*!< Reference count to the SD */ - -#if defined(TL_BUFFER_STATS) - /* Behaviour counters, no multi-threading protection need as they are - * incremented in a single thread due to only supporting one reader - * at present */ - IMG_UINT32 ui32AcquireCount; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32NoData; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32NoDataSleep; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32Signalled; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32TimeoutEmpty; /*!< Counters used to analysing stream performance, see ++ loc */ - IMG_UINT32 ui32TimeoutData; /*!< Counters used to analysing stream performance, see ++ loc */ -#endif - IMG_UINT32 ui32ReadLimit; /*!< Limit buffer reads to data present in the - buffer at the time of stream open. */ - IMG_UINT32 ui32ReadLen; /*!< Size of data returned by initial Acquire */ -} TL_STREAM_DESC, *PTL_STREAM_DESC; - -PTL_STREAM_DESC TLMakeStreamDesc(PTL_SNODE f1, IMG_UINT32 f2, IMG_HANDLE f3); - -#define TL_STREAM_KM_FLAG_MASK 0xFFFF0000 -#define TL_STREAM_FLAG_TEST 0x10000000 -#define TL_STREAM_FLAG_WRAPREAD 0x00010000 - -#define TL_STREAM_UM_FLAG_MASK 0x0000FFFF - -#if defined(TL_BUFFER_STATS) -# define TL_COUNTER_INC(a) ((a)++) -# define TL_COUNTER_ADD(a,b) ((a) += (b)) -#else -# define TL_COUNTER_INC(a) (void)(0) -# define TL_COUNTER_ADD(a,b) (void)(0) -#endif -/* - * Transport Layer stream list node - */ -typedef struct _TL_SNODE_ -{ - struct _TL_SNODE_* psNext; /*!< Linked list next element */ - IMG_HANDLE hReadEventObj; /*!< Readers 'wait for data' event */ - PTL_STREAM psStream; /*!< TL Stream object */ - IMG_INT uiWRefCount; /*!< Stream writer reference count */ - PTL_STREAM_DESC psRDesc; /*!< Stream reader 0 or ptr only */ - PTL_STREAM_DESC psWDesc; /*!< Stream writer 0 or ptr only */ -} TL_SNODE; - -PTL_SNODE TLMakeSNode(IMG_HANDLE f2, TL_STREAM *f3, TL_STREAM_DESC *f4); - -/* - * Transport Layer global top types and variables - * Use access function to obtain pointer. - * - * hTLGDLock - provides atomicity over read/check/write operations and - * sequence of operations on uiClientCnt, psHead list of SNODEs and - * the immediate members in a list element SNODE structure. - * - This larger scope of responsibility for this lock helps avoid - * the need for a lock in the SNODE structure. - * - Lock held in the client (reader) context when streams are - * opened/closed and in the server (writer) context when streams - * are created/open/closed. - */ -typedef struct _TL_GDATA_ -{ - IMG_HANDLE hTLEventObj; /* Global TL signal object, new streams, etc */ - - IMG_UINT uiClientCnt; /* Counter to track the number of client stream connections. */ - PTL_SNODE psHead; /* List of TL streams and associated client handle */ - - POS_LOCK hTLGDLock; /* Lock for structure AND psHead SNODE list */ -} TL_GLOBAL_DATA, *PTL_GLOBAL_DATA; - -/* - * Transport Layer Internal Kernel-Mode Server API - */ -TL_GLOBAL_DATA* TLGGD(void); /* TLGetGlobalData() */ - -PVRSRV_ERROR TLInit(void); -void TLDeInit(void); - -void TLAddStreamNode(PTL_SNODE psAdd); -PTL_SNODE TLFindStreamNodeByName(const IMG_CHAR *pszName); -PTL_SNODE TLFindStreamNodeByDesc(PTL_STREAM_DESC psDesc); -IMG_UINT32 TLDiscoverStreamNodes(const IMG_CHAR *pszNamePattern, - IMG_CHAR aaszStreams[][PRVSRVTL_MAX_STREAM_NAME_SIZE], - IMG_UINT32 ui32Max); -PTL_SNODE TLFindAndGetStreamNodeByDesc(PTL_STREAM_DESC psDesc); -void TLReturnStreamNode(PTL_SNODE psNode); - -/****************************************************************************** - Function Name : TLTryRemoveStreamAndFreeStreamNode - - Inputs : PTL_SNODE Pointer to the TL_SNODE whose stream is requested - to be removed from TL_GLOBAL_DATA's list - - Return Value : IMG_TRUE - If the stream was made NULL and this - TL_SNODE was removed from the - TL_GLOBAL_DATA's list - - IMG_FALSE - If the stream wasn't made NULL as there - is a client connected to this stream - - Description : If there is no client currently connected to this stream then, - This function removes this TL_SNODE from the - TL_GLOBAL_DATA's list. The caller is responsible for the - cleanup of the TL_STREAM whose TL_SNODE may be removed - - Otherwise, this function does nothing -******************************************************************************/ -IMG_BOOL TLTryRemoveStreamAndFreeStreamNode(PTL_SNODE psRemove); - -/****************************************************************************** - Function Name : TLUnrefDescAndTryFreeStreamNode - - Inputs : PTL_SNODE Pointer to the TL_SNODE whose descriptor is - requested to be removed - : PTL_STREAM_DESC Pointer to the STREAM_DESC - - Return Value : IMG_TRUE - If this TL_SNODE was removed from the - TL_GLOBAL_DATA's list - - IMG_FALSE - Otherwise - - Description : This function removes the stream descriptor from this TL_SNODE - and, if there is no writer (producer context) currently bound to this - stream, this function removes this TL_SNODE from the TL_GLOBAL_DATA's - list. The caller is responsible for the cleanup of the TL_STREAM - whose TL_SNODE may be removed -******************************************************************************/ -IMG_BOOL TLUnrefDescAndTryFreeStreamNode(PTL_SNODE psRemove, PTL_STREAM_DESC psSD); - -/* - * Transport Layer stream interface to server part declared here to avoid - * circular dependency. - */ -IMG_UINT32 TLStreamAcquireReadPos(PTL_STREAM psStream, - IMG_BOOL bDisableCallback, - IMG_UINT32* puiReadOffset); -PVRSRV_ERROR TLStreamAdvanceReadPos(PTL_STREAM psStream, - IMG_UINT32 uiReadLen, - IMG_UINT32 uiOrigReadLen); -void TLStreamResetReadPos(PTL_STREAM psStream); - -DEVMEM_MEMDESC* TLStreamGetBufferPointer(PTL_STREAM psStream); -IMG_BOOL TLStreamOutOfData(IMG_HANDLE psStream); - -/****************************************************************************** - Function Name : TLStreamDestroy - - Inputs : PTL_STREAM Pointer to the TL_STREAM to be destroyed - - Description : This function performs all the clean-up operations required for - destruction of this stream -******************************************************************************/ -void TLStreamDestroy(PTL_STREAM psStream); - -/* - * Test related functions - */ -PVRSRV_ERROR TUtilsInit(PVRSRV_DEVICE_NODE *psDeviceNode); -PVRSRV_ERROR TUtilsDeinit(PVRSRV_DEVICE_NODE *psDeviceNode); - - -#endif /* TLINTERN_H */ -/****************************************************************************** - End of file (tlintern.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlserver.c b/drivers/gpu/drm/img-rogue/1.17/tlserver.c deleted file mode 100644 index c250dd3dc6189..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlserver.c +++ /dev/null @@ -1,747 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title KM server Transport Layer implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main bridge APIs for Transport Layer client functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "img_defs.h" - -/*#define PVR_DPF_FUNCTION_TRACE_ON 1*/ -#undef PVR_DPF_FUNCTION_TRACE_ON -#include "pvr_debug.h" - -#include "connection_server.h" -#include "allocmem.h" -#include "devicemem.h" - -#include "tlintern.h" -#include "tlstream.h" -#include "tlserver.h" - -#include "pvrsrv_tlstreams.h" -#define NO_STREAM_WAIT_PERIOD_US 2000000ULL -#define NO_DATA_WAIT_PERIOD_US 500000ULL -#define NO_ACQUIRE 0xffffffffU - - -/* - * Transport Layer Client API Kernel-Mode bridge implementation - */ -PVRSRV_ERROR -TLServerOpenStreamKM(const IMG_CHAR* pszName, - IMG_UINT32 ui32Mode, - PTL_STREAM_DESC* ppsSD, - PMR** ppsTLPMR) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_ERROR eErrorEO = PVRSRV_OK; - PTL_SNODE psNode; - PTL_STREAM psStream; - TL_STREAM_DESC *psNewSD = NULL; - IMG_HANDLE hEvent; - IMG_BOOL bIsWriteOnly = ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WO ? - IMG_TRUE : IMG_FALSE; - IMG_BOOL bResetOnOpen = ui32Mode & PVRSRV_STREAM_FLAG_RESET_ON_OPEN ? - IMG_TRUE : IMG_FALSE; - IMG_BOOL bNoOpenCB = ui32Mode & PVRSRV_STREAM_FLAG_IGNORE_OPEN_CALLBACK ? - IMG_TRUE : IMG_FALSE; - PTL_GLOBAL_DATA psGD = TLGGD(); - -#if defined(PVR_DPF_FUNCTION_TRACE_ON) - PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered (%s, %x)", __func__, __LINE__, pszName, ui32Mode)); -#endif - - PVR_ASSERT(pszName); - - /* Acquire TL_GLOBAL_DATA lock here, as if the following TLFindStreamNodeByName - * returns NON NULL PTL_SNODE, we try updating the global data client count and - * PTL_SNODE's psRDesc and we want to make sure the TL_SNODE is valid (eg. has - * not been deleted) while we are updating it - */ - OSLockAcquire (psGD->hTLGDLock); - - psNode = TLFindStreamNodeByName(pszName); - if ((psNode == NULL) && (ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WAIT)) - { /* Blocking code to wait for stream to be created if it does not exist */ - eError = OSEventObjectOpen(psGD->hTLEventObj, &hEvent); - PVR_LOG_GOTO_IF_ERROR (eError, "OSEventObjectOpen", e0); - - do - { - if ((psNode = TLFindStreamNodeByName(pszName)) == NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "Stream %s does not exist, waiting...", pszName)); - - /* Release TL_GLOBAL_DATA lock before sleeping */ - OSLockRelease (psGD->hTLGDLock); - - /* Will exit OK or with timeout, both cases safe to ignore */ - eErrorEO = OSEventObjectWaitTimeout(hEvent, NO_STREAM_WAIT_PERIOD_US); - - /* Acquire lock after waking up */ - OSLockAcquire (psGD->hTLGDLock); - } - } - while ((psNode == NULL) && (eErrorEO == PVRSRV_OK)); - - eError = OSEventObjectClose(hEvent); - PVR_LOG_GOTO_IF_ERROR (eError, "OSEventObjectClose", e0); - } - - /* Make sure we have found a stream node after wait/search */ - if (psNode == NULL) - { - /* Did we exit the wait with timeout, inform caller */ - if (eErrorEO == PVRSRV_ERROR_TIMEOUT) - { - eError = eErrorEO; - } - else - { - eError = PVRSRV_ERROR_NOT_FOUND; - PVR_DPF((PVR_DBG_ERROR, "Stream \"%s\" does not exist", pszName)); - } - goto e0; - } - - psStream = psNode->psStream; - - /* Allocate memory for the stream. The memory will be allocated with the - * first call. */ - eError = TLAllocSharedMemIfNull(psStream); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "Failed to allocate memory for stream" - " \"%s\"", pszName)); - goto e0; - } - - if (bIsWriteOnly) - { - - /* If psWDesc == NULL it means that this is the first attempt - * to open stream for write. If yes create the descriptor or increment - * reference count otherwise. */ - if (psNode->psWDesc == NULL) - { - psNewSD = TLMakeStreamDesc(psNode, ui32Mode, NULL); - psNode->psWDesc = psNewSD; - } - else - { - psNewSD = psNode->psWDesc; - psNode->psWDesc->uiRefCount++; - } - - PVR_LOG_GOTO_IF_NOMEM(psNewSD, eError, e0); - - psNode->uiWRefCount++; - } - else - { - /* Only one reader per stream supported */ - if (psNode->psRDesc != NULL) - { - PVR_DPF((PVR_DBG_ERROR, "Cannot open \"%s\" stream, stream already" - " opened", pszName)); - eError = PVRSRV_ERROR_ALREADY_OPEN; - goto e0; - } - - /* Create an event handle for this client to wait on when no data in - * stream buffer. */ - eError = OSEventObjectOpen(psNode->hReadEventObj, &hEvent); - if (eError != PVRSRV_OK) - { - PVR_LOG_ERROR(eError, "OSEventObjectOpen"); - eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT; - goto e0; - } - - psNewSD = TLMakeStreamDesc(psNode, ui32Mode, hEvent); - psNode->psRDesc = psNewSD; - - if (!psNewSD) - { - PVR_DPF((PVR_DBG_ERROR, "Not possible to make a new stream descriptor")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e1; - } - - PVR_DPF((PVR_DBG_VERBOSE, - "TLServerOpenStreamKM evList=%p, evObj=%p", - psNode->hReadEventObj, - psNode->psRDesc->hReadEvent)); - } - - /* Copy the import handle back to the user mode API to enable access to - * the stream buffer from user-mode process. */ - eError = DevmemLocalGetImportHandle(TLStreamGetBufferPointer(psStream), - (void**) ppsTLPMR); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemLocalGetImportHandle", e2); - - psGD->uiClientCnt++; - - /* Global data updated. Now release global lock */ - OSLockRelease (psGD->hTLGDLock); - - *ppsSD = psNewSD; - - if (bResetOnOpen) - { - TLStreamReset(psStream); - } - - /* This callback is executed only on reader open. There are some actions - * executed on reader open that don't make much sense for writers e.g. - * injection on time synchronisation packet into the stream. */ - if (!bIsWriteOnly && psStream->pfOnReaderOpenCallback != NULL && !bNoOpenCB) - { - psStream->pfOnReaderOpenCallback(psStream->pvOnReaderOpenUserData); - } - - /* psNode->uiWRefCount is set to '1' on stream create so the first open - * is '2'. */ - if (bIsWriteOnly && psStream->psNotifStream != NULL && - psNode->uiWRefCount == 2) - { - TLStreamMarkStreamOpen(psStream); - } - - PVR_DPF((PVR_DBG_MESSAGE, "%s: Stream %s opened for %s", __func__, pszName, - ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WO ? "write" : "read")); - - PVR_DPF_RETURN_OK; - -e2: - OSFreeMem(psNewSD); -e1: - if (!bIsWriteOnly) - OSEventObjectClose(hEvent); -e0: - OSLockRelease (psGD->hTLGDLock); - PVR_DPF_RETURN_RC (eError); -} - -PVRSRV_ERROR -TLServerCloseStreamKM(PTL_STREAM_DESC psSD) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PTL_GLOBAL_DATA psGD = TLGGD(); - PTL_SNODE psNode; - PTL_STREAM psStream; - IMG_BOOL bDestroyStream; - IMG_BOOL bIsWriteOnly = psSD->ui32Flags & PVRSRV_STREAM_FLAG_OPEN_WO ? - IMG_TRUE : IMG_FALSE; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psSD); - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* Check stream still valid */ - psNode = TLFindStreamNodeByDesc(psSD); - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* Since the descriptor is valid, the stream should not have been made NULL */ - PVR_ASSERT (psNode->psStream); - - /* Save the stream's reference in-case its destruction is required after this - * client is removed */ - psStream = psNode->psStream; - - /* Acquire TL_GLOBAL_DATA lock as the following TLRemoveDescAndTryFreeStreamNode - * call will update the TL_SNODE's descriptor value */ - OSLockAcquire (psGD->hTLGDLock); - - /* Close event handle because event object list might be destroyed in - * TLUnrefDescAndTryFreeStreamNode(). */ - if (!bIsWriteOnly) - { - /* Reset the read position on close if the stream requires it. */ - TLStreamResetReadPos(psStream); - - /* Close and free the event handle resource used by this descriptor */ - eError = OSEventObjectClose(psSD->hReadEvent); - if (eError != PVRSRV_OK) - { - /* Log error but continue as it seems best */ - PVR_LOG_ERROR(eError, "OSEventObjectClose"); - eError = PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; - } - } - else if (psNode->uiWRefCount == 2 && psStream->psNotifStream != NULL) - { - /* psNode->uiWRefCount is set to '1' on stream create so the last close - * before destruction is '2'. */ - TLStreamMarkStreamClose(psStream); - } - - /* Remove descriptor from stream object/list */ - bDestroyStream = TLUnrefDescAndTryFreeStreamNode (psNode, psSD); - - /* Check the counter is sensible after input data validated. */ - PVR_ASSERT(psGD->uiClientCnt > 0); - psGD->uiClientCnt--; - - OSLockRelease (psGD->hTLGDLock); - - /* Destroy the stream if its TL_SNODE was removed from TL_GLOBAL_DATA */ - if (bDestroyStream) - { - TLStreamDestroy (psStream); - psStream = NULL; - } - - PVR_DPF((PVR_DBG_VERBOSE, "%s: Stream closed", __func__)); - - /* Free the descriptor if ref count reaches 0. */ - if (psSD->uiRefCount == 0) - { - /* Free the stream descriptor object */ - OSFreeMem(psSD); - } - - PVR_DPF_RETURN_RC(eError); -} - -PVRSRV_ERROR -TLServerReserveStreamKM(PTL_STREAM_DESC psSD, - IMG_UINT32* ui32BufferOffset, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32* pui32Available) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psNode; - IMG_UINT8* pui8Buffer = NULL; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psSD); - - if (!(psSD->ui32Flags & PVRSRV_STREAM_FLAG_OPEN_WO)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - /* Acquire the global lock. We have to be sure that no one modifies - * the list while we are looking for our stream. */ - OSLockAcquire(psGD->hTLGDLock); - /* Check stream still valid */ - psNode = TLFindAndGetStreamNodeByDesc(psSD); - OSLockRelease(psGD->hTLGDLock); - - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - - /* Since we have a valid stream descriptor, the stream should not have been - * made NULL by any producer context. */ - PVR_ASSERT (psNode->psStream); - - /* The TL writers that currently land here are at a very low to none risk - * to breach max TL packet size constraint (even if there is no reader - * connected to the TL stream and hence eventually will cause the TL stream - * to be full). Hence no need to know the status of TL stream reader - * connection. - */ - eError = TLStreamReserve2(psNode->psStream, &pui8Buffer, ui32Size, - ui32SizeMin, pui32Available, NULL); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, "Failed to reserve %u (%u, %u) bytes in the stream, error %s.", - ui32Size, ui32SizeMin, *pui32Available, PVRSRVGETERRORSTRING(eError))); - } - else if (pui8Buffer == NULL) - { - PVR_DPF((PVR_DBG_WARNING, "Not enough space in the stream.")); - eError = PVRSRV_ERROR_STREAM_FULL; - } - else - { - *ui32BufferOffset = pui8Buffer - psNode->psStream->pbyBuffer; - PVR_ASSERT(*ui32BufferOffset < psNode->psStream->ui32Size); - } - - OSLockAcquire(psGD->hTLGDLock); - TLReturnStreamNode(psNode); - OSLockRelease(psGD->hTLGDLock); - - PVR_DPF_RETURN_RC(eError); -} - -PVRSRV_ERROR -TLServerCommitStreamKM(PTL_STREAM_DESC psSD, - IMG_UINT32 ui32Size) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psNode; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psSD); - - if (!(psSD->ui32Flags & PVRSRV_STREAM_FLAG_OPEN_WO)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - /* Acquire the global lock. We have to be sure that no one modifies - * the list while we are looking for our stream. */ - OSLockAcquire(psGD->hTLGDLock); - /* Check stream still valid */ - psNode = TLFindAndGetStreamNodeByDesc(psSD); - OSLockRelease(psGD->hTLGDLock); - - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* Since we have a valid stream descriptor, the stream should not have been - * made NULL by any producer context. */ - PVR_ASSERT (psNode->psStream); - - eError = TLStreamCommit(psNode->psStream, ui32Size); - PVR_LOG_IF_ERROR(eError, "TLStreamCommit"); - - OSLockAcquire(psGD->hTLGDLock); - TLReturnStreamNode(psNode); - OSLockRelease(psGD->hTLGDLock); - - PVR_DPF_RETURN_RC(eError); -} - -PVRSRV_ERROR -TLServerDiscoverStreamsKM(const IMG_CHAR *pszNamePattern, - IMG_UINT32 ui32Size, - IMG_CHAR *pszStreams, - IMG_UINT32 *pui32NumFound) -{ - PTL_SNODE psNode = NULL; - IMG_CHAR (*paszStreams)[PRVSRVTL_MAX_STREAM_NAME_SIZE] = - (IMG_CHAR (*)[PRVSRVTL_MAX_STREAM_NAME_SIZE]) (void *)pszStreams; - - if (*pszNamePattern == '\0') - return PVRSRV_ERROR_INVALID_PARAMS; - - if (ui32Size % PRVSRVTL_MAX_STREAM_NAME_SIZE != 0) - return PVRSRV_ERROR_INVALID_PARAMS; - - /* Quick exit if there are no streams */ - if (TLGGD()->psHead == NULL) - { - *pui32NumFound = 0; - return PVRSRV_OK; - } - - OSLockAcquire(TLGGD()->hTLGDLock); - - *pui32NumFound = TLDiscoverStreamNodes(pszNamePattern, paszStreams, - ui32Size / PRVSRVTL_MAX_STREAM_NAME_SIZE); - - /* Find "tlctrl" stream and reset it */ - psNode = TLFindStreamNodeByName(PVRSRV_TL_CTLR_STREAM); - if (psNode != NULL) - TLStreamReset(psNode->psStream); - - OSLockRelease(TLGGD()->hTLGDLock); - - return PVRSRV_OK; -} - -PVRSRV_ERROR -TLServerAcquireDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32* puiReadOffset, - IMG_UINT32* puiReadLen) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - TL_GLOBAL_DATA* psGD = TLGGD(); - IMG_UINT32 uiTmpOffset; - IMG_UINT32 uiTmpLen = 0; - PTL_SNODE psNode; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psSD); - - TL_COUNTER_INC(psSD->ui32AcquireCount); - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - /* Check stream still valid */ - psNode = TLFindStreamNodeByDesc(psSD); - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* If we are here, the stream will never be made NULL until this context itself - * calls TLRemoveDescAndTryFreeStreamNode(). This is because the producer will - * fail to make the stream NULL (by calling TLTryRemoveStreamAndFreeStreamNode) - * when a valid stream descriptor is present (i.e. a client is connected). - * Hence, no checks for stream being NON NULL are required after this. */ - PVR_ASSERT (psNode->psStream); - - psSD->ui32ReadLen = 0; /* Handle NULL read returns */ - - do - { - uiTmpLen = TLStreamAcquireReadPos(psNode->psStream, psSD->ui32Flags & PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK, &uiTmpOffset); - - /* Check we have not already exceeded read limit with just offset - * regardless of data length to ensure the client sees the RC */ - if (psSD->ui32Flags & PVRSRV_STREAM_FLAG_READ_LIMIT) - { - /* Check to see if we are reading beyond the read limit */ - if (uiTmpOffset >= psSD->ui32ReadLimit) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_READLIMIT_REACHED); - } - } - - if (uiTmpLen > 0) - { /* Data found */ - - /* Check we have not already exceeded read limit offset+len */ - if (psSD->ui32Flags & PVRSRV_STREAM_FLAG_READ_LIMIT) - { - /* Adjust the read length if it goes beyond the read limit - * limit always guaranteed to be on packet */ - if ((uiTmpOffset + uiTmpLen) >= psSD->ui32ReadLimit) - { - uiTmpLen = psSD->ui32ReadLimit - uiTmpOffset; - } - } - - *puiReadOffset = uiTmpOffset; - *puiReadLen = uiTmpLen; - psSD->ui32ReadLen = uiTmpLen; /* Save the original data length in the stream desc */ - PVR_DPF_RETURN_OK; - } - else if (!(psSD->ui32Flags & PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING)) - { /* No data found blocking */ - - /* Instead of doing a complete sleep for `NO_DATA_WAIT_PERIOD_US` us, we sleep in chunks - * of 168 ms. In a "deferred" signal scenario from writer, this gives us a chance to - * wake-up (timeout) early and continue reading in-case some data is available */ - IMG_UINT64 ui64WaitInChunksUs = MIN(NO_DATA_WAIT_PERIOD_US, 168000ULL); - IMG_BOOL bDataFound = IMG_FALSE; - - TL_COUNTER_INC(psSD->ui32NoDataSleep); - - LOOP_UNTIL_TIMEOUT(NO_DATA_WAIT_PERIOD_US) - { - eError = OSEventObjectWaitTimeout(psSD->hReadEvent, ui64WaitInChunksUs); - if (eError == PVRSRV_OK) - { - bDataFound = IMG_TRUE; - TL_COUNTER_INC(psSD->ui32Signalled); - break; - } - else if (eError == PVRSRV_ERROR_TIMEOUT) - { - if (TLStreamOutOfData(psNode->psStream)) - { - /* Return on timeout if stream empty, else let while exit and return data */ - continue; - } - else - { - bDataFound = IMG_TRUE; - TL_COUNTER_INC(psSD->ui32TimeoutData); - PVR_DPF((PVR_DBG_MESSAGE, "%s: Data found at timeout. Current BuffUt = %u", - __func__, TLStreamGetUT(psNode->psStream))); - break; - } - } - else - { /* Some other system error with event objects */ - PVR_DPF_RETURN_RC(eError); - } - } END_LOOP_UNTIL_TIMEOUT(); - - if (bDataFound) - { - continue; - } - else - { - TL_COUNTER_INC(psSD->ui32TimeoutEmpty); - return PVRSRV_ERROR_TIMEOUT; - } - } - else - { /* No data non-blocking */ - TL_COUNTER_INC(psSD->ui32NoData); - - /* When no-data in non-blocking mode, uiReadOffset should be set to NO_ACQUIRE - * signifying there's no need of Release call */ - *puiReadOffset = NO_ACQUIRE; - *puiReadLen = 0; - PVR_DPF_RETURN_OK; - } - } - while (1); -} - -PVRSRV_ERROR -TLServerReleaseDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32 uiReadOffset, - IMG_UINT32 uiReadLen) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psNode; - - PVR_DPF_ENTERED; - - /* Unreferenced in release builds */ - PVR_UNREFERENCED_PARAMETER(uiReadOffset); - - PVR_ASSERT(psSD); - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - if ((uiReadLen % PVRSRVTL_PACKET_ALIGNMENT != 0)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Check stream still valid */ - psNode = TLFindStreamNodeByDesc(psSD); - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* Since we have a valid stream descriptor, the stream should not have been - * made NULL by any producer context. */ - PVR_ASSERT (psNode->psStream); - - PVR_DPF((PVR_DBG_VERBOSE, "TLReleaseDataKM uiReadOffset=%d, uiReadLen=%d", uiReadOffset, uiReadLen)); - - /* Move read position on to free up space in stream buffer */ - PVR_DPF_RETURN_RC(TLStreamAdvanceReadPos(psNode->psStream, uiReadLen, psSD->ui32ReadLen)); -} - -PVRSRV_ERROR -TLServerWriteDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32 ui32Size, - IMG_BYTE* pui8Data) -{ - TL_GLOBAL_DATA* psGD = TLGGD(); - PTL_SNODE psNode; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psSD); - - if (!(psSD->ui32Flags & PVRSRV_STREAM_FLAG_OPEN_WO)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Quick exit if there are no streams */ - if (psGD->psHead == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - OSLockAcquire(psGD->hTLGDLock); - /* Check stream still valid */ - psNode = TLFindAndGetStreamNodeByDesc(psSD); - OSLockRelease(psGD->hTLGDLock); - - if ((psNode == NULL) || (psNode != psSD->psNode)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND); - } - - /* Since we have a valid stream descriptor, the stream should not have been - * made NULL by any producer context. */ - PVR_ASSERT (psNode->psStream); - - eError = TLStreamWrite(psNode->psStream, pui8Data, ui32Size); - /* propagate error up but don't print anything here */ - - OSLockAcquire(psGD->hTLGDLock); - TLReturnStreamNode(psNode); - OSLockRelease(psGD->hTLGDLock); - - PVR_DPF_RETURN_RC(eError); -} - -/****************************************************************************** - End of file (tlserver.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlserver.h b/drivers/gpu/drm/img-rogue/1.17/tlserver.h deleted file mode 100644 index 7ac2958eac1ee..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlserver.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title KM server Transport Layer implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main bridge APIs for Transport Layer client functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TLSERVER_H -#define TLSERVER_H - -#include "img_defs.h" -#include "pvr_debug.h" -#include "connection_server.h" - -#include "tlintern.h" - -/* - * Transport Layer Client API Kernel-Mode bridge implementation - */ - -PVRSRV_ERROR TLServerConnectKM(CONNECTION_DATA *psConnection); -PVRSRV_ERROR TLServerDisconnectKM(CONNECTION_DATA *psConnection); - -PVRSRV_ERROR TLServerOpenStreamKM(const IMG_CHAR* pszName, - IMG_UINT32 ui32Mode, - PTL_STREAM_DESC* ppsSD, - PMR** ppsTLPMR); - -PVRSRV_ERROR TLServerCloseStreamKM(PTL_STREAM_DESC psSD); - -PVRSRV_ERROR TLServerDiscoverStreamsKM(const IMG_CHAR *pszNamePattern, - IMG_UINT32 ui32Max, - IMG_CHAR *pszStreams, - IMG_UINT32 *pui32NumFound); - -PVRSRV_ERROR TLServerReserveStreamKM(PTL_STREAM_DESC psSD, - IMG_UINT32* ui32BufferOffset, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32* pui32Available); - -PVRSRV_ERROR TLServerCommitStreamKM(PTL_STREAM_DESC psSD, - IMG_UINT32 ui32Size); - -PVRSRV_ERROR TLServerAcquireDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32* puiReadOffset, - IMG_UINT32* puiReadLen); - -PVRSRV_ERROR TLServerReleaseDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32 uiReadOffset, - IMG_UINT32 uiReadLen); - -PVRSRV_ERROR TLServerWriteDataKM(PTL_STREAM_DESC psSD, - IMG_UINT32 ui32Size, - IMG_BYTE *pui8Data); - -#endif /* TLSERVER_H */ - -/****************************************************************************** - End of file (tlserver.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/tlstream.c b/drivers/gpu/drm/img-rogue/1.17/tlstream.c deleted file mode 100644 index a80792e7bffe0..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlstream.c +++ /dev/null @@ -1,1625 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Transport Layer kernel side API implementation. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Transport Layer API implementation. - These functions are provided to driver components. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -//#define PVR_DPF_FUNCTION_TRACE_ON 1 -#undef PVR_DPF_FUNCTION_TRACE_ON -#include "pvr_debug.h" - -#include "allocmem.h" -#include "devicemem.h" -#include "pvrsrv_error.h" -#include "osfunc.h" -#include "log2.h" - -#include "tlintern.h" -#include "tlstream.h" - -#include "pvrsrv.h" - -#define EVENT_OBJECT_TIMEOUT_US 1000000ULL -#define READ_PENDING_TIMEOUT_US 100000ULL - -/*! Compute maximum TL packet size for this stream. Max packet size will be - * minimum of PVRSRVTL_MAX_PACKET_SIZE and (BufferSize / 2.5). This computation - * is required to avoid a corner case that was observed when TL buffer size is - * smaller than twice of TL max packet size and read, write index are positioned - * in such a way that the TL packet (write packet + padding packet) size is may - * be bigger than the buffer size itself. - */ -#define GET_TL_MAX_PACKET_SIZE( bufSize ) PVRSRVTL_ALIGN( MIN( PVRSRVTL_MAX_PACKET_SIZE, ( 2 * bufSize ) / 5 ) ) - -/* Given the state of the buffer it returns a number of bytes that the client - * can use for a successful allocation. */ -static INLINE IMG_UINT32 suggestAllocSize(IMG_UINT32 ui32LRead, - IMG_UINT32 ui32LWrite, - IMG_UINT32 ui32CBSize, - IMG_UINT32 ui32ReqSizeMin, - IMG_UINT32 ui32MaxPacketSize) -{ - IMG_UINT32 ui32AvSpace = 0; - - /* This could be written in fewer lines using the ? operator but it - would not be kind to potential readers of this source at all. */ - if (ui32LRead > ui32LWrite) /* Buffer WRAPPED */ - { - if ((ui32LRead - ui32LWrite) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE)) - { - ui32AvSpace = ui32LRead - ui32LWrite - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE; - } - } - else /* Normal, no wrap */ - { - if ((ui32CBSize - ui32LWrite) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE)) - { - ui32AvSpace = ui32CBSize - ui32LWrite - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE; - } - else if ((ui32LRead - 0) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE)) - { - ui32AvSpace = ui32LRead - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE; - } - } - /* The max size of a TL packet currently is UINT16. adjust accordingly */ - return MIN(ui32AvSpace, ui32MaxPacketSize); -} - -/* Returns bytes left in the buffer. Negative if there is not any. - * two 8b aligned values are reserved, one for the write failed buffer flag - * and one to be able to distinguish the buffer full state to the buffer - * empty state. - * Always returns free space -8 even when the "write failed" packet may be - * already in the stream before this write. */ -static INLINE IMG_INT -circbufSpaceLeft(IMG_UINT32 ui32Read, IMG_UINT32 ui32Write, IMG_UINT32 ui32size) -{ - /* We need to reserve 8b (one packet) in the buffer to be able to tell empty - * buffers from full buffers and one more for packet write fail packet */ - if (ui32Read > ui32Write) - { - return (IMG_INT)ui32Read - (IMG_INT)ui32Write - (IMG_INT)BUFFER_RESERVED_SPACE; - } - else - { - return (IMG_INT)ui32size - ((IMG_INT)ui32Write - (IMG_INT)ui32Read) - (IMG_INT)BUFFER_RESERVED_SPACE; - } -} - -IMG_UINT32 TLStreamGetUT(IMG_HANDLE hStream) -{ - PTL_STREAM psStream = (PTL_STREAM) hStream; - IMG_UINT32 ui32LRead = psStream->ui32Read, ui32LWrite = psStream->ui32Write; - - if (ui32LWrite >= ui32LRead) - { - return (ui32LWrite-ui32LRead); - } - else - { - return (psStream->ui32Size-ui32LRead+ui32LWrite); - } -} - -PVRSRV_ERROR TLAllocSharedMemIfNull(IMG_HANDLE hStream) -{ - PTL_STREAM psStream = (PTL_STREAM) hStream; - PVRSRV_ERROR eError; - - /* CPU Local memory used as these buffers are not accessed by the device. - * CPU Uncached write combine memory used to improve write performance, - * memory barrier added in TLStreamCommit to ensure data written to memory - * before CB write point is updated before consumption by the reader. - */ - IMG_CHAR pszBufferLabel[PRVSRVTL_MAX_STREAM_NAME_SIZE + 20]; - PVRSRV_MEMALLOCFLAGS_T uiMemFlags = PVRSRV_MEMALLOCFLAG_CPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | - PVRSRV_MEMALLOCFLAG_GPU_READABLE | - PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC | - PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | - PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(CPU_LOCAL); /* TL for now is only used by host driver, so cpulocal mem suffices */ - - /* Exit if memory has already been allocated. */ - if (psStream->pbyBuffer != NULL) - return PVRSRV_OK; - - OSSNPrintf(pszBufferLabel, sizeof(pszBufferLabel), "TLStreamBuf-%s", - psStream->szName); - - - /* Use HostMemDeviceNode instead of psStream->psDevNode to benefit from faster - * accesses to CPU local memory. When the framework to access CPU_LOCAL device - * memory from GPU is fixed, we'll switch back to use psStream->psDevNode for - * TL buffers */ - eError = DevmemAllocateExportable((IMG_HANDLE)PVRSRVGetPVRSRVData()->psHostMemDeviceNode, - (IMG_DEVMEM_SIZE_T) psStream->ui32Size, - (IMG_DEVMEM_ALIGN_T) OSGetPageSize(), - ExactLog2(OSGetPageSize()), - uiMemFlags, - pszBufferLabel, - &psStream->psStreamMemDesc); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAllocateExportable", e0); - - eError = DevmemAcquireCpuVirtAddr(psStream->psStreamMemDesc, - (void**) &psStream->pbyBuffer); - PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", e1); - - return PVRSRV_OK; - -e1: - DevmemFree(psStream->psStreamMemDesc); -e0: - return eError; -} - -void TLFreeSharedMem(IMG_HANDLE hStream) -{ - PTL_STREAM psStream = (PTL_STREAM) hStream; - - if (psStream->pbyBuffer != NULL) - { - DevmemReleaseCpuVirtAddr(psStream->psStreamMemDesc); - psStream->pbyBuffer = NULL; - } - if (psStream->psStreamMemDesc != NULL) - { - DevmemFree(psStream->psStreamMemDesc); - psStream->psStreamMemDesc = NULL; - } -} - -/* Special space left routine for TL_FLAG_PERMANENT_NO_WRAP streams */ -static INLINE IMG_UINT -bufSpaceLeft(IMG_UINT32 ui32Read, IMG_UINT32 ui32Write, IMG_UINT32 ui32size) -{ - /* buffers from full buffers and one more for packet write fail packet */ - PVR_ASSERT(ui32Read<=ui32Write); - return ui32size - ui32Write; -} - -/******************************************************************************* - * TL Server public API implementation. - ******************************************************************************/ -PVRSRV_ERROR -TLStreamCreate(IMG_HANDLE *phStream, - const IMG_CHAR *szStreamName, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32StreamFlags, - TL_STREAM_ONREADEROPENCB pfOnReaderOpenCB, - void *pvOnReaderOpenUD, - TL_STREAM_SOURCECB pfProducerCB, - void *pvProducerUD) -{ - PTL_STREAM psTmp; - PVRSRV_ERROR eError; - IMG_HANDLE hEventList; - PTL_SNODE psn; - TL_OPMODE eOpMode; - - PVR_DPF_ENTERED; - /* Parameter checks: non NULL handler required */ - if (NULL == phStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - if (szStreamName == NULL || *szStreamName == '\0' || - OSStringLength(szStreamName) >= PRVSRVTL_MAX_STREAM_NAME_SIZE) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - eOpMode = ui32StreamFlags & TL_OPMODE_MASK; - if (( eOpMode <= TL_OPMODE_UNDEF ) || ( eOpMode >= TL_OPMODE_LAST )) - { - PVR_DPF((PVR_DBG_ERROR, "OpMode for TL stream is invalid")); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Acquire TL_GLOBAL_DATA lock here because, if the following TLFindStreamNodeByName() - * returns NULL, a new TL_SNODE will be added to TL_GLOBAL_DATA's TL_SNODE list */ - OSLockAcquire (TLGGD()->hTLGDLock); - - /* Check if there already exists a stream with this name. */ - psn = TLFindStreamNodeByName( szStreamName ); - if (NULL != psn) - { - eError = PVRSRV_ERROR_ALREADY_EXISTS; - goto e0; - } - - /* Allocate stream structure container (stream struct) for the new stream */ - psTmp = OSAllocZMem(sizeof(TL_STREAM)); - if (NULL == psTmp) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto e0; - } - - OSStringLCopy(psTmp->szName, szStreamName, PRVSRVTL_MAX_STREAM_NAME_SIZE); - - if (ui32StreamFlags & TL_FLAG_FORCE_FLUSH) - { - psTmp->bWaitForEmptyOnDestroy = IMG_TRUE; - } - - psTmp->bNoSignalOnCommit = (ui32StreamFlags&TL_FLAG_NO_SIGNAL_ON_COMMIT) ? IMG_TRUE : IMG_FALSE; - psTmp->bNoWrapPermanent = (ui32StreamFlags&TL_FLAG_PERMANENT_NO_WRAP) ? IMG_TRUE : IMG_FALSE; - - psTmp->eOpMode = eOpMode; - if (psTmp->eOpMode == TL_OPMODE_BLOCK) - { - /* Only allow drop properties to be mixed with no-wrap type streams - * since space does not become available when reads take place hence - * no point blocking. - */ - if (psTmp->bNoWrapPermanent) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e1; - } - } - - /* Additional synchronisation object required for some streams e.g. blocking */ - eError = OSEventObjectCreate(NULL, &psTmp->hProducerEventObj); - PVR_GOTO_IF_ERROR(eError, e1); - /* Create an event handle for this kind of stream */ - eError = OSEventObjectOpen(psTmp->hProducerEventObj, &psTmp->hProducerEvent); - PVR_GOTO_IF_ERROR(eError, e2); - - psTmp->pfOnReaderOpenCallback = pfOnReaderOpenCB; - psTmp->pvOnReaderOpenUserData = pvOnReaderOpenUD; - /* Remember producer supplied CB and data for later */ - psTmp->pfProducerCallback = (void(*)(void))pfProducerCB; - psTmp->pvProducerUserData = pvProducerUD; - - psTmp->psNotifStream = NULL; - - /* Round the requested bytes to a multiple of array elements' size, eg round 3 to 4 */ - psTmp->ui32Size = PVRSRVTL_ALIGN(ui32Size); - - /* Signalling from TLStreamCommit is deferred until buffer is slightly (~12%) filled */ - psTmp->ui32ThresholdUsageForSignal = psTmp->ui32Size >> 3; - psTmp->ui32MaxPacketSize = GET_TL_MAX_PACKET_SIZE(psTmp->ui32Size); - psTmp->ui32Read = 0; - psTmp->ui32Write = 0; - psTmp->ui32Pending = NOTHING_PENDING; - psTmp->bReadPending = IMG_FALSE; - psTmp->bSignalPending = IMG_FALSE; - -#if defined(TL_BUFFER_STATS) - OSAtomicWrite(&psTmp->bNoReaderSinceFirstReserve, 0); - /* Setting MAX possible value for "minimum" time to full, - * helps in the logic which calculates this time */ - psTmp->ui32MinTimeToFullInUs = IMG_UINT32_MAX; -#endif - - /* Memory will be allocated on first connect to the stream */ - if (!(ui32StreamFlags & TL_FLAG_ALLOCATE_ON_FIRST_OPEN)) - { - /* Allocate memory for the circular buffer and export it to user space. */ - eError = TLAllocSharedMemIfNull(psTmp); - PVR_LOG_GOTO_IF_ERROR(eError, "TLAllocSharedMem", e3); - } - - /* Synchronisation object to synchronise with user side data transfers. */ - eError = OSEventObjectCreate(psTmp->szName, &hEventList); - PVR_GOTO_IF_ERROR(eError, e4); - - eError = OSLockCreate (&psTmp->hStreamWLock); - PVR_GOTO_IF_ERROR(eError, e5); - - eError = OSLockCreate (&psTmp->hReadLock); - PVR_GOTO_IF_ERROR(eError, e6); - - /* Now remember the stream in the global TL structures */ - psn = TLMakeSNode(hEventList, (TL_STREAM *)psTmp, NULL); - PVR_GOTO_IF_NOMEM(psn, eError, e7); - - /* Stream node created, now reset the write reference count to 1 - * (i.e. this context's reference) */ - psn->uiWRefCount = 1; - - TLAddStreamNode(psn); - - /* Release TL_GLOBAL_DATA lock as the new TL_SNODE is now added to the list */ - OSLockRelease (TLGGD()->hTLGDLock); - - /* Best effort signal, client wait timeout will ultimately let it find the - * new stream if this fails, acceptable to avoid clean-up as it is tricky - * at this point */ - (void) OSEventObjectSignal(TLGGD()->hTLEventObj); - - /* Pass the newly created stream handle back to caller */ - *phStream = (IMG_HANDLE)psTmp; - PVR_DPF_RETURN_OK; - -e7: - OSLockDestroy(psTmp->hReadLock); -e6: - OSLockDestroy(psTmp->hStreamWLock); -e5: - OSEventObjectDestroy(hEventList); -e4: - TLFreeSharedMem(psTmp); -e3: - OSEventObjectClose(psTmp->hProducerEvent); -e2: - OSEventObjectDestroy(psTmp->hProducerEventObj); -e1: - OSFreeMem(psTmp); -e0: - OSLockRelease (TLGGD()->hTLGDLock); - - PVR_DPF_RETURN_RC(eError); -} - -void TLStreamReset(IMG_HANDLE hStream) -{ - PTL_STREAM psStream = (PTL_STREAM) hStream; - - PVR_ASSERT(psStream != NULL); - - OSLockAcquire(psStream->hStreamWLock); - - while (psStream->ui32Pending != NOTHING_PENDING) - { - PVRSRV_ERROR eError; - - /* We're in the middle of a write so we cannot reset the stream. - * We are going to wait until the data is committed. Release lock while - * we're here. */ - OSLockRelease(psStream->hStreamWLock); - - /* Event when psStream->bNoSignalOnCommit is set we can still use - * the timeout capability of event object API (time in us). */ - eError = OSEventObjectWaitTimeout(psStream->psNode->hReadEventObj, 100); - if (eError != PVRSRV_ERROR_TIMEOUT && eError != PVRSRV_OK) - { - PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectWaitTimeout"); - } - - OSLockAcquire(psStream->hStreamWLock); - - /* Either timeout occurred or the stream has been signalled. - * If former we have to check if the data was committed and if latter - * if the stream hasn't been re-reserved. Either way we have to go - * back to the condition. - * If the stream has been released we'll exit with the lock held so - * we can finally go and reset the stream. */ - } - - psStream->ui32Read = 0; - psStream->ui32Write = 0; - /* we know that ui32Pending already has correct value (no need to set) */ - - OSLockRelease(psStream->hStreamWLock); -} - -PVRSRV_ERROR -TLStreamSetNotifStream(IMG_HANDLE hStream, IMG_HANDLE hNotifStream) -{ - PTL_STREAM psStream = (PTL_STREAM) hStream; - - if (hStream == NULL || hNotifStream == NULL) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - psStream->psNotifStream = (PTL_STREAM) hNotifStream; - - return PVRSRV_OK; -} - -PVRSRV_ERROR -TLStreamReconfigure( - IMG_HANDLE hStream, - IMG_UINT32 ui32StreamFlags) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PTL_STREAM psTmp; - TL_OPMODE eOpMode; - - PVR_DPF_ENTERED; - - if (NULL == hStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - eOpMode = ui32StreamFlags & TL_OPMODE_MASK; - if (( eOpMode <= TL_OPMODE_UNDEF ) || ( eOpMode >= TL_OPMODE_LAST )) - { - PVR_DPF((PVR_DBG_ERROR, "OpMode for TL stream is invalid")); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - psTmp = (PTL_STREAM)hStream; - - /* Prevent the TL Stream buffer from being written to - * while its mode is being reconfigured - */ - OSLockAcquire (psTmp->hStreamWLock); - if (NOTHING_PENDING != psTmp->ui32Pending) - { - OSLockRelease (psTmp->hStreamWLock); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_READY); - } - psTmp->ui32Pending = 0; - OSLockRelease (psTmp->hStreamWLock); - - psTmp->eOpMode = eOpMode; - if (psTmp->eOpMode == TL_OPMODE_BLOCK) - { - /* Only allow drop properties to be mixed with no-wrap type streams - * since space does not become available when reads take place hence - * no point blocking. - */ - if (psTmp->bNoWrapPermanent) - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e1; - } - } - - OSLockAcquire (psTmp->hStreamWLock); - psTmp->ui32Pending = NOTHING_PENDING; - OSLockRelease (psTmp->hStreamWLock); -e1: - PVR_DPF_RETURN_RC(eError); -} - -PVRSRV_ERROR -TLStreamOpen(IMG_HANDLE *phStream, - const IMG_CHAR *szStreamName) -{ - PTL_SNODE psTmpSNode; - - PVR_DPF_ENTERED; - - if (NULL == phStream || NULL == szStreamName) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - /* Acquire the TL_GLOBAL_DATA lock first to ensure, - * the TL_STREAM while returned and being modified, - * is not deleted by some other context */ - OSLockAcquire (TLGGD()->hTLGDLock); - - /* Search for a stream node with a matching stream name */ - psTmpSNode = TLFindStreamNodeByName(szStreamName); - - if (NULL == psTmpSNode) - { - OSLockRelease (TLGGD()->hTLGDLock); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_FOUND); - } - - if (psTmpSNode->psStream->psNotifStream != NULL && - psTmpSNode->uiWRefCount == 1) - { - TLStreamMarkStreamOpen(psTmpSNode->psStream); - } - - /* The TL_SNODE->uiWRefCount governs the presence of this node in the - * TL_GLOBAL_DATA list i.e. when uiWRefCount falls to zero we try removing - * this node from the TL_GLOBAL_DATA list. Hence, is protected using the - * TL_GLOBAL_DATA lock and not TL_STREAM lock */ - psTmpSNode->uiWRefCount++; - - OSLockRelease (TLGGD()->hTLGDLock); - - /* Return the stream handle to the caller */ - *phStream = (IMG_HANDLE)psTmpSNode->psStream; - - PVR_DPF_RETURN_VAL(PVRSRV_OK); -} - -void -TLStreamClose(IMG_HANDLE hStream) -{ - PTL_STREAM psTmp; - IMG_BOOL bDestroyStream; - - PVR_DPF_ENTERED; - - if (NULL == hStream) - { - PVR_DPF((PVR_DBG_WARNING, - "TLStreamClose failed as NULL stream handler passed, nothing done.")); - PVR_DPF_RETURN; - } - - psTmp = (PTL_STREAM)hStream; - - /* Acquire TL_GLOBAL_DATA lock for updating the reference count as this will be required - * in-case this TL_STREAM node is to be deleted */ - OSLockAcquire (TLGGD()->hTLGDLock); - - /* Decrement write reference counter of the stream */ - psTmp->psNode->uiWRefCount--; - - if (0 != psTmp->psNode->uiWRefCount) - { - /* The stream is still being used in other context(s) do not destroy - * anything */ - - /* uiWRefCount == 1 means that stream was closed for write. Next - * close is pairing TLStreamCreate(). Send notification to indicate - * that no writer are connected to the stream any more. */ - if (psTmp->psNotifStream != NULL && psTmp->psNode->uiWRefCount == 1) - { - TLStreamMarkStreamClose(psTmp); - } - - OSLockRelease (TLGGD()->hTLGDLock); - PVR_DPF_RETURN; - } - else - { - /* Now we try removing this TL_STREAM from TL_GLOBAL_DATA */ - - if (psTmp->bWaitForEmptyOnDestroy) - { - /* We won't require the TL_STREAM lock to be acquired here for accessing its read - * and write offsets. REASON: We are here because there is no producer context - * referencing this TL_STREAM, hence its ui32Write offset won't be changed now. - * Also, the update of ui32Read offset is not protected by locks */ - while (psTmp->ui32Read != psTmp->ui32Write) - { - /* Release lock before sleeping */ - OSLockRelease (TLGGD()->hTLGDLock); - - OSEventObjectWaitTimeout(psTmp->hProducerEvent, EVENT_OBJECT_TIMEOUT_US); - - OSLockAcquire (TLGGD()->hTLGDLock); - - /* Ensure destruction of stream is still required */ - if (0 != psTmp->psNode->uiWRefCount) - { - OSLockRelease (TLGGD()->hTLGDLock); - PVR_DPF_RETURN; - } - } - } - - /* Try removing the stream from TL_GLOBAL_DATA */ - bDestroyStream = TLTryRemoveStreamAndFreeStreamNode (psTmp->psNode); - - OSLockRelease (TLGGD()->hTLGDLock); - - if (bDestroyStream) - { - /* Destroy the stream if it was removed from TL_GLOBAL_DATA */ - TLStreamDestroy (psTmp); - psTmp = NULL; - } - PVR_DPF_RETURN; - } -} - -/* - * DoTLSetPacketHeader - * - * Ensure that whenever we update a Header we always add the RESERVED field - */ -static inline void DoTLSetPacketHeader(PVRSRVTL_PPACKETHDR, IMG_UINT32); -static inline void -DoTLSetPacketHeader(PVRSRVTL_PPACKETHDR pHdr, - IMG_UINT32 ui32Val) -{ - PVR_ASSERT(((size_t)pHdr & (size_t)(PVRSRVTL_PACKET_ALIGNMENT - 1)) == 0); - - /* Check that this is a correctly aligned packet header. */ - if (((size_t)pHdr & (size_t)(PVRSRVTL_PACKET_ALIGNMENT - 1)) != 0) - { - /* Should return an error because the header is misaligned */ - PVR_DPF((PVR_DBG_ERROR, "%s: Misaligned header @ %p", __func__, pHdr)); - pHdr->uiTypeSize = ui32Val; - } - else - { - pHdr->uiTypeSize = ui32Val; - pHdr->uiReserved = PVRSRVTL_PACKETHDR_RESERVED; - } -} - -static PVRSRV_ERROR -DoTLStreamReserve(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32ReqSize, - IMG_UINT32 ui32ReqSizeMin, - PVRSRVTL_PACKETTYPE ePacketType, - IMG_UINT32* pui32AvSpace, - IMG_UINT32* pui32Flags) -{ - PTL_STREAM psTmp; - IMG_UINT32 *pui32Buf, ui32LRead, ui32LWrite, ui32LPending, lReqSizeAligned, lReqSizeActual, ui32CreateFreeSpace; - IMG_UINT32 ui32InputFlags = 0; - IMG_INT pad, iFreeSpace; - IMG_UINT8 *pui8IncrRead = NULL; - PVRSRVTL_PPACKETHDR pHdr; - - PVR_DPF_ENTERED; - if (pui32AvSpace) *pui32AvSpace = 0; - if (pui32Flags) - { - ui32InputFlags = *pui32Flags; - *pui32Flags = 0; - } - - if (NULL == hStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - psTmp = (PTL_STREAM)hStream; - - /* Assert used as the packet type parameter is currently only provided - * by the TL APIs, not the calling client */ - PVR_ASSERT((PVRSRVTL_PACKETTYPE_UNDEF < ePacketType) && (PVRSRVTL_PACKETTYPE_LAST >= ePacketType)); - - /* The buffer is only used in "rounded" (aligned) chunks */ - lReqSizeAligned = PVRSRVTL_ALIGN(ui32ReqSize); - - /* Lock the stream before reading it's pending value, because if pending is set - * to NOTHING_PENDING, we update the pending value such that subsequent calls to - * this function from other context(s) fail with PVRSRV_ERROR_NOT_READY */ - OSLockAcquire (psTmp->hStreamWLock); - -#if defined(TL_BUFFER_STATS) - /* If writing into an empty buffer, start recording time-to-full */ - if (psTmp->ui32Read == psTmp->ui32Write) - { - OSAtomicWrite(&psTmp->bNoReaderSinceFirstReserve, 1); - psTmp->ui32TimeStart = OSClockus(); - } - - if (ui32ReqSize > psTmp->ui32MaxReserveWatermark) - { - psTmp->ui32MaxReserveWatermark = ui32ReqSize; - } -#endif - - /* Get a local copy of the stream buffer parameters */ - ui32LRead = psTmp->ui32Read; - ui32LWrite = psTmp->ui32Write; - ui32LPending = psTmp->ui32Pending; - - /* Multiple pending reserves are not supported. */ - if (NOTHING_PENDING != ui32LPending) - { - OSLockRelease (psTmp->hStreamWLock); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_READY); - } - - if (psTmp->ui32MaxPacketSize < lReqSizeAligned) - { - PVR_DPF((PVR_DBG_ERROR, "Requested Size: %u > TL Max Packet size: %u", lReqSizeAligned, psTmp->ui32MaxPacketSize)); - psTmp->ui32Pending = NOTHING_PENDING; - if (pui32AvSpace) - { - *pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin, psTmp->ui32MaxPacketSize); - if (*pui32AvSpace == 0 && psTmp->eOpMode == TL_OPMODE_DROP_OLDEST) - { - *pui32AvSpace = psTmp->ui32MaxPacketSize; - PVR_DPF((PVR_DBG_MESSAGE, "Opmode is Drop_Oldest, so Available Space changed to: %u", *pui32AvSpace)); - } - } - OSLockRelease (psTmp->hStreamWLock); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED); - } - - /* Prevent other threads from entering this region before we are done - * updating the pending value and write offset (in case of padding). This - * is not exactly a lock but a signal for other contexts that there is a - * TLStreamCommit operation pending on this stream */ - psTmp->ui32Pending = 0; - - OSLockRelease (psTmp->hStreamWLock); - - /* If there is enough contiguous space following the current Write - * position then no padding is required */ - if ( psTmp->ui32Size - < ui32LWrite + lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) ) - { - pad = psTmp->ui32Size - ui32LWrite; - } - else - { - pad = 0; - } - - lReqSizeActual = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) + pad; - if (psTmp->bNoWrapPermanent) - { - iFreeSpace = bufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size); - } - else - { - iFreeSpace = circbufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size); - } - - if (iFreeSpace < (IMG_INT) lReqSizeActual) - { - /* If this is a blocking reserve and there is not enough space then wait. */ - if (psTmp->eOpMode == TL_OPMODE_BLOCK) - { - /* Stream create should stop us entering here when - * psTmp->bNoWrapPermanent is true as it does not make sense to - * block on permanent data streams. */ - PVR_ASSERT(psTmp->bNoWrapPermanent == IMG_FALSE); - while ( ( circbufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size) - <(IMG_INT) lReqSizeActual ) ) - { - /* The TL bridge is lockless now, so changing to OSEventObjectWait() */ - OSEventObjectWait(psTmp->hProducerEvent); - // update local copies. - ui32LRead = psTmp->ui32Read; - ui32LWrite = psTmp->ui32Write; - } - } - /* Data overwriting, also insert PACKETS_DROPPED flag into existing packet */ - else if (psTmp->eOpMode == TL_OPMODE_DROP_OLDEST) - { - OSLockAcquire(psTmp->hReadLock); - - while (psTmp->bReadPending) - { - PVR_DPF((PVR_DBG_MESSAGE, "Waiting for the pending read operation to complete.")); - OSLockRelease(psTmp->hReadLock); -#if defined(TL_BUFFER_STATS) - TL_COUNTER_INC(psTmp->ui32CntWriteWaits); -#endif - (void) OSEventObjectWaitTimeout(psTmp->hProducerEvent, READ_PENDING_TIMEOUT_US); - OSLockAcquire(psTmp->hReadLock); - } - -#if defined(TL_BUFFER_STATS) - TL_COUNTER_INC(psTmp->ui32CntWriteSuccesses); -#endif - ui32LRead = psTmp->ui32Read; - - if ( circbufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size) - < (IMG_INT) lReqSizeActual ) - { - ui32CreateFreeSpace = 5 * (psTmp->ui32Size / 100); - if (ui32CreateFreeSpace < lReqSizeActual) - { - ui32CreateFreeSpace = lReqSizeActual; - } - - while (ui32CreateFreeSpace > (IMG_UINT32)circbufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size)) - { - pui8IncrRead = &psTmp->pbyBuffer[ui32LRead]; - ui32LRead += (sizeof(PVRSRVTL_PACKETHDR) + PVRSRVTL_ALIGN( GET_PACKET_DATA_LEN(pui8IncrRead) )); - - /* Check if buffer needs to wrap */ - if (ui32LRead >= psTmp->ui32Size) - { - ui32LRead = 0; - } - } - psTmp->ui32Read = ui32LRead; - pui8IncrRead = &psTmp->pbyBuffer[psTmp->ui32Read]; - - pHdr = GET_PACKET_HDR(pui8IncrRead); - DoTLSetPacketHeader(pHdr, SET_PACKETS_DROPPED(pHdr)); - } - /* else fall through as there is enough space now to write the data */ - - OSLockRelease(psTmp->hReadLock); - /* If we accepted a flag var set the OVERWRITE bit*/ - if (pui32Flags) *pui32Flags |= TL_FLAG_OVERWRITE_DETECTED; - } - /* No data overwriting, insert write_failed flag and return */ - else if (psTmp->eOpMode == TL_OPMODE_DROP_NEWER) - { - /* Caller should not try to use ppui8Data, - * NULLify to give user a chance of avoiding memory corruption */ - *ppui8Data = NULL; - - /* This flag should not be inserted two consecutive times, so - * check the last ui32 in case it was a packet drop packet. */ - pui32Buf = ui32LWrite - ? - (void *)&psTmp->pbyBuffer[ui32LWrite - sizeof(PVRSRVTL_PACKETHDR)] - : // Previous four bytes are not guaranteed to be a packet header... - (void *)&psTmp->pbyBuffer[psTmp->ui32Size - PVRSRVTL_PACKET_ALIGNMENT]; - - pHdr = GET_PACKET_HDR(pui32Buf); - if ( PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED - != - GET_PACKET_TYPE( pHdr ) && (ui32InputFlags & TL_FLAG_NO_WRITE_FAILED) == 0) - { - /* Insert size-stamped packet header */ - pui32Buf = (void *)&psTmp->pbyBuffer[ui32LWrite]; - pHdr = GET_PACKET_HDR(pui32Buf); - DoTLSetPacketHeader(pHdr, PVRSRVTL_SET_PACKET_WRITE_FAILED); - ui32LWrite += sizeof(PVRSRVTL_PACKETHDR); - ui32LWrite %= psTmp->ui32Size; - iFreeSpace -= sizeof(PVRSRVTL_PACKETHDR); - } - - OSLockAcquire (psTmp->hStreamWLock); - psTmp->ui32Write = ui32LWrite; - psTmp->ui32Pending = NOTHING_PENDING; - OSLockRelease (psTmp->hStreamWLock); - - if (pui32AvSpace) - { - *pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin, psTmp->ui32MaxPacketSize); - } - - /* Inform call of permanent stream misuse, no space left, - * the size of the stream will need to be increased. */ - if (psTmp->bNoWrapPermanent) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_NOT_ENOUGH_SPACE); - } - - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_FULL); - } - } - - /* The easy case: buffer has enough space to hold the requested packet (data + header) */ - - /* Should we treat the buffer as non-circular buffer? */ - if (psTmp->bNoWrapPermanent) - { - iFreeSpace = bufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size); - } - else - { - iFreeSpace = circbufSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size); - } - - if (iFreeSpace >= (IMG_INT) lReqSizeActual) - { - if (pad) - { - /* Inserting padding packet. */ - pui32Buf = (void *)&psTmp->pbyBuffer[ui32LWrite]; - pHdr = GET_PACKET_HDR(pui32Buf); - DoTLSetPacketHeader(pHdr, - PVRSRVTL_SET_PACKET_PADDING(pad-sizeof(PVRSRVTL_PACKETHDR))); - - /* CAUTION: the used pad value should always result in a properly - * aligned ui32LWrite pointer, which in this case is 0 */ - ui32LWrite = (ui32LWrite + pad) % psTmp->ui32Size; - /* Detect unaligned pad value */ - PVR_ASSERT(ui32LWrite == 0); - } - /* Insert size-stamped packet header */ - pui32Buf = (void *) &psTmp->pbyBuffer[ui32LWrite]; - - pHdr = GET_PACKET_HDR(pui32Buf); - DoTLSetPacketHeader(pHdr, - PVRSRVTL_SET_PACKET_HDR(ui32ReqSize, ePacketType)); - - /* return the next position in the buffer to the user */ - *ppui8Data = &psTmp->pbyBuffer[ ui32LWrite+sizeof(PVRSRVTL_PACKETHDR) ]; - - /* update pending offset: size stamp + data */ - ui32LPending = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR); - } - else - { - OSLockAcquire (psTmp->hStreamWLock); - psTmp->ui32Pending = NOTHING_PENDING; - OSLockRelease (psTmp->hStreamWLock); - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR); - } - - /* Acquire stream lock for updating stream parameters */ - OSLockAcquire (psTmp->hStreamWLock); - psTmp->ui32Write = ui32LWrite; - psTmp->ui32Pending = ui32LPending; - OSLockRelease (psTmp->hStreamWLock); - -#if defined(TL_BUFFER_STATS) - TL_COUNTER_INC(psTmp->ui32CntNumWriteSuccess); -#endif - - PVR_DPF_RETURN_OK; -} - -PVRSRV_ERROR -TLStreamReserve(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size) -{ - return DoTLStreamReserve(hStream, ppui8Data, ui32Size, ui32Size, PVRSRVTL_PACKETTYPE_DATA, NULL, NULL); -} - -PVRSRV_ERROR -TLStreamReserve2(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32* pui32Available, - IMG_BOOL* pbIsReaderConnected) -{ - PVRSRV_ERROR eError; - - eError = DoTLStreamReserve(hStream, ppui8Data, ui32Size, ui32SizeMin, PVRSRVTL_PACKETTYPE_DATA, pui32Available, NULL); - if (eError != PVRSRV_OK && pbIsReaderConnected != NULL) - { - *pbIsReaderConnected = TLStreamIsOpenForReading(hStream); - } - - return eError; -} - -PVRSRV_ERROR -TLStreamReserveReturnFlags(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32* pui32Flags) -{ - return DoTLStreamReserve(hStream, ppui8Data, ui32Size, ui32Size, PVRSRVTL_PACKETTYPE_DATA, NULL, pui32Flags); -} - -PVRSRV_ERROR -TLStreamCommit(IMG_HANDLE hStream, IMG_UINT32 ui32ReqSize) -{ - PTL_STREAM psTmp; - IMG_UINT32 ui32LRead, ui32OldWrite, ui32LWrite, ui32LPending; - PVRSRV_ERROR eError; - -#if defined(TL_BUFFER_STATS) - IMG_UINT32 ui32UnreadBytes; -#endif - - PVR_DPF_ENTERED; - - if (NULL == hStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - psTmp = (PTL_STREAM)hStream; - - /* Get a local copy of the stream buffer parameters */ - ui32LRead = psTmp->ui32Read; - ui32LWrite = psTmp->ui32Write; - ui32LPending = psTmp->ui32Pending; - - ui32OldWrite = ui32LWrite; - - // Space in buffer is aligned - ui32ReqSize = PVRSRVTL_ALIGN(ui32ReqSize) + sizeof(PVRSRVTL_PACKETHDR); - - /* Check pending reserver and ReqSize + packet header size. */ - if ((ui32LPending == NOTHING_PENDING) || (ui32ReqSize > ui32LPending)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE); - } - - /* Update pointer to written data. */ - ui32LWrite = (ui32LWrite + ui32ReqSize) % psTmp->ui32Size; - - /* and reset LPending to 0 since data are now submitted */ - ui32LPending = NOTHING_PENDING; - -#if defined(TL_BUFFER_STATS) - /* Calculate new number of bytes unread */ - if (ui32LWrite > ui32LRead) - { - ui32UnreadBytes = (ui32LWrite-ui32LRead); - } - else if (ui32LWrite < ui32LRead) - { - ui32UnreadBytes = (psTmp->ui32Size-ui32LRead+ui32LWrite); - } - else - { /* else equal, ignore */ - ui32UnreadBytes = 0; - } - - /* Calculate high water mark for debug purposes */ - if (ui32UnreadBytes > psTmp->ui32BufferUt) - { - psTmp->ui32BufferUt = ui32UnreadBytes; - } -#endif - - /* Memory barrier required to ensure prior data written by writer is - * flushed from WC buffer to main memory. */ - OSWriteMemoryBarrier(NULL); - - /* Acquire stream lock to ensure other context(s) (if any) - * wait on the lock (in DoTLStreamReserve) for consistent values - * of write offset and pending value */ - OSLockAcquire (psTmp->hStreamWLock); - - /* Update stream buffer parameters to match local copies */ - psTmp->ui32Write = ui32LWrite; - psTmp->ui32Pending = ui32LPending; - - /* Ensure write pointer is flushed */ - OSWriteMemoryBarrier(&psTmp->ui32Write); - - TL_COUNTER_ADD(psTmp->ui32ProducerByteCount, ui32ReqSize); - TL_COUNTER_INC(psTmp->ui32NumCommits); - -#if defined(TL_BUFFER_STATS) - /* IF there has been no-reader since first reserve on an empty-buffer, - * AND current utilisation is considerably high (90%), calculate the - * time taken to fill up the buffer */ - if ((OSAtomicRead(&psTmp->bNoReaderSinceFirstReserve) == 1) && - (TLStreamGetUT(psTmp) >= 90 * psTmp->ui32Size/100)) - { - IMG_UINT32 ui32TimeToFullInUs = OSClockus() - psTmp->ui32TimeStart; - if (psTmp->ui32MinTimeToFullInUs > ui32TimeToFullInUs) - { - psTmp->ui32MinTimeToFullInUs = ui32TimeToFullInUs; - } - /* Following write ensures ui32MinTimeToFullInUs doesn't lose its - * real (expected) value in case there is no reader until next Commit call */ - OSAtomicWrite(&psTmp->bNoReaderSinceFirstReserve, 0); - } -#endif - - if (!psTmp->bNoSignalOnCommit) - { - /* If we have transitioned from an empty buffer to a non-empty buffer, we - * must signal possibly waiting consumer. BUT, let the signal be "deferred" - * until buffer is at least 'ui32ThresholdUsageForSignal' bytes full. This - * avoids a race between OSEventObjectSignal and OSEventObjectWaitTimeout - * (in TLServerAcquireDataKM), where a "signal" might happen before "wait", - * resulting into signal being lost and stream-reader waiting even though - * buffer is no-more empty */ - if (ui32OldWrite == ui32LRead) - { - psTmp->bSignalPending = IMG_TRUE; - } - - if (psTmp->bSignalPending && (TLStreamGetUT(psTmp) >= psTmp->ui32ThresholdUsageForSignal)) - { - TL_COUNTER_INC(psTmp->ui32SignalsSent); - psTmp->bSignalPending = IMG_FALSE; - - /* Signal consumers that may be waiting */ - eError = OSEventObjectSignal(psTmp->psNode->hReadEventObj); - if (eError != PVRSRV_OK) - { - OSLockRelease (psTmp->hStreamWLock); - PVR_DPF_RETURN_RC(eError); - } - } - else - { - TL_COUNTER_INC(psTmp->ui32SignalNotSent); - } - } - OSLockRelease (psTmp->hStreamWLock); - - PVR_DPF_RETURN_OK; -} - -PVRSRV_ERROR -TLStreamWrite(IMG_HANDLE hStream, IMG_UINT8 *pui8Src, IMG_UINT32 ui32Size) -{ - IMG_BYTE *pbyDest = NULL; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - if (NULL == hStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - eError = TLStreamReserve(hStream, &pbyDest, ui32Size); - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - else - { - OSDeviceMemCopy((void*)pbyDest, (void*)pui8Src, ui32Size); - eError = TLStreamCommit(hStream, ui32Size); - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - } - - PVR_DPF_RETURN_OK; -} - -PVRSRV_ERROR -TLStreamWriteRetFlags(IMG_HANDLE hStream, IMG_UINT8 *pui8Src, IMG_UINT32 ui32Size, IMG_UINT32 *pui32Flags){ - IMG_BYTE *pbyDest = NULL; - PVRSRV_ERROR eError; - - PVR_DPF_ENTERED; - - if (NULL == hStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - eError = TLStreamReserveReturnFlags(hStream, &pbyDest, ui32Size, pui32Flags); - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - else - { - OSDeviceMemCopy((void*)pbyDest, (void*)pui8Src, ui32Size); - eError = TLStreamCommit(hStream, ui32Size); - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - } - - PVR_DPF_RETURN_OK; -} - -void TLStreamInfo(IMG_HANDLE hStream, PTL_STREAM_INFO psInfo) -{ - IMG_DEVMEM_SIZE_T actual_req_size; - IMG_DEVMEM_ALIGN_T align = 4; /* Low fake value so the real value can be obtained */ - - actual_req_size = 2; - /* ignore error as OSGetPageShift() should always return correct value */ - (void) DevmemExportalignAdjustSizeAndAlign(OSGetPageShift(), &actual_req_size, &align); - - psInfo->headerSize = sizeof(PVRSRVTL_PACKETHDR); - psInfo->minReservationSize = sizeof(IMG_UINT32); - psInfo->pageSize = (IMG_UINT32)(actual_req_size); - psInfo->pageAlign = (IMG_UINT32)(align); - psInfo->maxTLpacketSize = ((PTL_STREAM)hStream)->ui32MaxPacketSize; -} - -PVRSRV_ERROR -TLStreamMarkEOS(IMG_HANDLE psStream, IMG_BOOL bRemoveOld) -{ - PTL_STREAM psTmp; - PVRSRV_ERROR eError; - IMG_UINT8* pData; - - PVR_DPF_ENTERED; - - if (NULL == psStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - psTmp = (PTL_STREAM)psStream; - - /* Do not support EOS packets on permanent stream buffers at present, - * EOS is best used with streams where data is consumed. */ - if (psTmp->bNoWrapPermanent) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE); - } - - if (bRemoveOld) - { - eError = DoTLStreamReserve(psStream, &pData, 0, 0, PVRSRVTL_PACKETTYPE_MARKER_EOS_REMOVEOLD, NULL, NULL); - } - else - { - eError = DoTLStreamReserve(psStream, &pData, 0, 0, PVRSRVTL_PACKETTYPE_MARKER_EOS, NULL, NULL); - } - - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - - PVR_DPF_RETURN_RC(TLStreamCommit(psStream, 0)); -} - - -static PVRSRV_ERROR -_TLStreamMarkOC(IMG_HANDLE hStream, PVRSRVTL_PACKETTYPE ePacketType) -{ - PVRSRV_ERROR eError; - PTL_STREAM psStream = hStream; - IMG_UINT32 ui32Size; - IMG_UINT8 *pData; - - PVR_DPF_ENTERED; - - if (NULL == psStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - - if (NULL == psStream->psNotifStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_NOTIF_STREAM); - } - - ui32Size = OSStringLength(psStream->szName) + 1; - - eError = DoTLStreamReserve(psStream->psNotifStream, &pData, ui32Size, - ui32Size, ePacketType, NULL, NULL); - if (PVRSRV_OK != eError) - { - PVR_DPF_RETURN_RC(eError); - } - - OSDeviceMemCopy(pData, psStream->szName, ui32Size); - - PVR_DPF_RETURN_RC(TLStreamCommit(psStream->psNotifStream, ui32Size)); -} - -PVRSRV_ERROR -TLStreamMarkStreamOpen(IMG_HANDLE psStream) -{ - return _TLStreamMarkOC(psStream, PVRSRVTL_PACKETTYPE_STREAM_OPEN_FOR_WRITE); -} - -PVRSRV_ERROR -TLStreamMarkStreamClose(IMG_HANDLE psStream) -{ - return _TLStreamMarkOC(psStream, PVRSRVTL_PACKETTYPE_STREAM_CLOSE_FOR_WRITE); -} - -PVRSRV_ERROR -TLStreamSync(IMG_HANDLE psStream) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PTL_STREAM psTmp; - - PVR_DPF_ENTERED; - - if (NULL == psStream) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); - } - psTmp = (PTL_STREAM)psStream; - - /* If read client exists and has opened stream in blocking mode, - * signal when data is available to read. */ - if (psTmp->psNode->psRDesc && - (!(psTmp->psNode->psRDesc->ui32Flags & PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING)) && - psTmp->ui32Read != psTmp->ui32Write) - { - TL_COUNTER_INC(psTmp->ui32ManSyncs); - eError = OSEventObjectSignal(psTmp->psNode->hReadEventObj); - } - - PVR_DPF_RETURN_RC(eError); -} - -IMG_BOOL -TLStreamIsOpenForReading(IMG_HANDLE hStream) -{ - PTL_STREAM psTmp; - - PVR_DPF_ENTERED; - - PVR_ASSERT(hStream); - psTmp = (PTL_STREAM)hStream; - - PVR_DPF_RETURN_VAL(psTmp->psNode->psRDesc != NULL); -} - -IMG_BOOL -TLStreamOutOfData(IMG_HANDLE hStream) -{ - PTL_STREAM psTmp; - - PVR_DPF_ENTERED; - - PVR_ASSERT(hStream); - psTmp = (PTL_STREAM)hStream; - - /* If both pointers are equal then the buffer is empty */ - PVR_DPF_RETURN_VAL(psTmp->ui32Read == psTmp->ui32Write); -} - - -PVRSRV_ERROR -TLStreamResetProducerByteCount(IMG_HANDLE hStream, IMG_UINT32 ui32Value) -{ - PTL_STREAM psTmp; - IMG_UINT32 ui32LRead, ui32LWrite; - PVRSRV_ERROR eErr = PVRSRV_OK; - - PVR_DPF_ENTERED; - - PVR_ASSERT(hStream); - psTmp = (PTL_STREAM)hStream; - ui32LRead = psTmp->ui32Read; - ui32LWrite = psTmp->ui32Write; - - if (ui32LRead != ui32LWrite) - { - eErr = PVRSRV_ERROR_STREAM_MISUSE; - } -#if defined(TL_BUFFER_STATS) - psTmp->ui32ProducerByteCount = ui32Value; -#else - PVR_UNREFERENCED_PARAMETER(ui32Value); -#endif - PVR_DPF_RETURN_RC(eErr); -} -/* - * Internal stream APIs to server part of Transport Layer, declared in - * header tlintern.h. Direct pointers to stream objects are used here as - * these functions are internal. - */ -IMG_UINT32 -TLStreamAcquireReadPos(PTL_STREAM psStream, - IMG_BOOL bDisableCallback, - IMG_UINT32* puiReadOffset) -{ - IMG_UINT32 uiReadLen = 0; - IMG_UINT32 ui32LRead, ui32LWrite; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psStream); - PVR_ASSERT(puiReadOffset); - - if (psStream->eOpMode == TL_OPMODE_DROP_OLDEST) - { - if (!OSTryLockAcquire(psStream->hReadLock)) - { - /* - * This is a normal event when the system is under load. - * An example of how to produce this is to run testrunner / - * regression/ddk_test_seq2_host_fw_mem.conf with HTB / pvrhtbd - * configured as - * - * # pvrdebug -log trace -loggroups main,pow,debug \ - * -hostloggroups main,ctrl,sync,brg -hostlogtype dropoldest - * - * # pvrhtbd -hostloggroups main,ctrl,sync,brg - * - * We will see a small number of these collisions but as this is - * an expected calling path, and an expected return code, we drop - * the severity to just be a debug MESSAGE instead of WARNING - */ - PVR_DPF((PVR_DBG_MESSAGE, - "%s: Read lock on stream '%s' is acquired by some writer, " - "hence reader failed to acquire read lock.", __func__, - psStream->szName)); -#if defined(TL_BUFFER_STATS) - TL_COUNTER_INC(psStream->ui32CntReadFails); -#endif - PVR_DPF_RETURN_VAL(0); - } - } - -#if defined(TL_BUFFER_STATS) - TL_COUNTER_INC(psStream->ui32CntReadSuccesses); -#endif - - /* Grab a local copy */ - ui32LRead = psStream->ui32Read; - ui32LWrite = psStream->ui32Write; - - if (psStream->eOpMode == TL_OPMODE_DROP_OLDEST) - { - psStream->bReadPending = IMG_TRUE; - OSLockRelease(psStream->hReadLock); - } - - /* No data available and CB defined - try and get data */ - if ((ui32LRead == ui32LWrite) && psStream->pfProducerCallback && !bDisableCallback) - { - PVRSRV_ERROR eRc; - IMG_UINT32 ui32Resp = 0; - - eRc = ((TL_STREAM_SOURCECB)psStream->pfProducerCallback)(psStream, TL_SOURCECB_OP_CLIENT_EOS, - &ui32Resp, psStream->pvProducerUserData); - PVR_LOG_IF_ERROR(eRc, "TLStream->pfProducerCallback"); - - ui32LWrite = psStream->ui32Write; - } - - /* No data available... */ - if (ui32LRead == ui32LWrite) - { - if (psStream->eOpMode == TL_OPMODE_DROP_OLDEST) - { - psStream->bReadPending = IMG_FALSE; - } - PVR_DPF_RETURN_VAL(0); - } - -#if defined(TL_BUFFER_STATS) - /* The moment reader knows it will see a non-zero data, it marks its presence in writer's eyes */ - OSAtomicWrite (&psStream->bNoReaderSinceFirstReserve, 0); -#endif - - /* Data is available to read... */ - *puiReadOffset = ui32LRead; - - /*PVR_DPF((PVR_DBG_VERBOSE, - * "TLStreamAcquireReadPos Start before: Write:%d, Read:%d, size:%d", - * ui32LWrite, ui32LRead, psStream->ui32Size)); - */ - - if (ui32LRead > ui32LWrite) - { /* CB has wrapped around. */ - PVR_ASSERT(!psStream->bNoWrapPermanent); - /* Return the first contiguous piece of memory, ie [ReadLen,EndOfBuffer] - * and let a subsequent AcquireReadPos read the rest of the Buffer */ - /*PVR_DPF((PVR_DBG_VERBOSE, "TLStreamAcquireReadPos buffer has wrapped"));*/ - uiReadLen = psStream->ui32Size - ui32LRead; - TL_COUNTER_INC(psStream->ui32AcquireRead2); - } - else - { /* CB has not wrapped */ - uiReadLen = ui32LWrite - ui32LRead; - TL_COUNTER_INC(psStream->ui32AcquireRead1); - } - - PVR_DPF_RETURN_VAL(uiReadLen); -} - -PVRSRV_ERROR -TLStreamAdvanceReadPos(PTL_STREAM psStream, - IMG_UINT32 uiReadLen, - IMG_UINT32 uiOrigReadLen) -{ - IMG_UINT32 uiNewReadPos; - - PVR_DPF_ENTERED; - - PVR_ASSERT(psStream); - - /* - * This API does not use Read lock as 'bReadPending' is sufficient - * to keep Read index safe by preventing a write from updating the - * index and 'bReadPending' itself is safe as it can only be modified - * by readers and there can be only one reader in action at a time. - */ - - /* Update the read offset by the length provided in a circular manner. - * Assuming the update to be atomic hence, avoiding use of locks - */ - uiNewReadPos = (psStream->ui32Read + uiReadLen) % psStream->ui32Size; - - /* Must validate length is on a packet boundary, for - * TLReleaseDataLess calls. - */ - if (uiReadLen != uiOrigReadLen) /* buffer not empty */ - { - PVRSRVTL_PPACKETHDR psHdr = GET_PACKET_HDR(psStream->pbyBuffer+uiNewReadPos); - PVRSRVTL_PACKETTYPE eType = GET_PACKET_TYPE(psHdr); - - if ((psHdr->uiReserved != PVRSRVTL_PACKETHDR_RESERVED) || - (eType == PVRSRVTL_PACKETTYPE_UNDEF) || - (eType >= PVRSRVTL_PACKETTYPE_LAST)) - { - PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_ALIGNMENT); - } - /* else OK, on a packet boundary */ - } - /* else no check needed */ - - psStream->ui32Read = uiNewReadPos; - - if (psStream->eOpMode == TL_OPMODE_DROP_OLDEST) - { - psStream->bReadPending = IMG_FALSE; - } - - /* notify reserves that may be pending */ - /* The producer event object is used to signal the StreamReserve if the TL - * Buffer is in blocking mode and is full. - * Previously this event was only signalled if the buffer was created in - * blocking mode. Since the buffer mode can now change dynamically the event - * is signalled every time to avoid any potential race where the signal is - * required, but not produced. - */ - { - PVRSRV_ERROR eError; - eError = OSEventObjectSignal(psStream->hProducerEventObj); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_WARNING, - "Error in TLStreamAdvanceReadPos: OSEventObjectSignal returned:%u", - eError)); - /* We've failed to notify the producer event. This means there may - * be a delay in generating more data to be consumed until the next - * Write() generating action occurs. - */ - } - } - - PVR_DPF((PVR_DBG_VERBOSE, - "TLStreamAdvanceReadPos Read now at: %d", - psStream->ui32Read)); - PVR_DPF_RETURN_OK; -} - -void -TLStreamResetReadPos(PTL_STREAM psStream) -{ - PVR_DPF_ENTERED; - - PVR_ASSERT(psStream); - - if (psStream->bNoWrapPermanent) - { - - /* Update the read offset by the length provided in a circular manner. - * Assuming the update to be atomic hence, avoiding use of locks */ - psStream->ui32Read = 0; - - PVR_DPF((PVR_DBG_VERBOSE, - "TLStreamResetReadPos Read now at: %d", - psStream->ui32Read)); - } - else - { - /* else for other stream types this is a no-op */ - PVR_DPF((PVR_DBG_VERBOSE, - "No need to reset read position of circular tlstream")); - } - - PVR_DPF_RETURN; -} - -void -TLStreamDestroy (PTL_STREAM psStream) -{ - PVR_ASSERT (psStream); - - OSLockDestroy (psStream->hStreamWLock); - OSLockDestroy (psStream->hReadLock); - - OSEventObjectClose(psStream->hProducerEvent); - OSEventObjectDestroy(psStream->hProducerEventObj); - - TLFreeSharedMem(psStream); - OSFreeMem(psStream); -} - -DEVMEM_MEMDESC* -TLStreamGetBufferPointer(PTL_STREAM psStream) -{ - PVR_DPF_ENTERED; - - PVR_ASSERT(psStream); - - PVR_DPF_RETURN_VAL(psStream->psStreamMemDesc); -} diff --git a/drivers/gpu/drm/img-rogue/1.17/tlstream.h b/drivers/gpu/drm/img-rogue/1.17/tlstream.h deleted file mode 100644 index 911e720e7cdde..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tlstream.h +++ /dev/null @@ -1,600 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Transport Layer kernel side API. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description TL provides driver components with a way to copy data from kernel - space to user space (e.g. screen/file). - - Data can be passed to the Transport Layer through the - TL Stream (kernel space) API interface. - - The buffer provided to every stream is a modified version of a - circular buffer. Which CB version is created is specified by - relevant flags when creating a stream. Currently two types - of buffer are available: - - TL_OPMODE_DROP_NEWER: - When the buffer is full, incoming data are dropped - (instead of overwriting older data) and a marker is set - to let the user know that data have been lost. - - TL_OPMODE_BLOCK: - When the circular buffer is full, reserve/write calls block - until enough space is freed. - - TL_OPMODE_DROP_OLDEST: - When the circular buffer is full, the oldest packets in the - buffer are dropped and a flag is set in header of next packet - to let the user know that data have been lost. - - All size/space requests are in bytes. However, the actual - implementation uses native word sizes (i.e. 4 byte aligned). - - The user does not need to provide space for the stream buffer - as the TL handles memory allocations and usage. - - Inserting data to a stream's buffer can be done either: - - by using TLReserve/TLCommit: User is provided with a buffer - to write data to. - - or by using TLWrite: User provides a buffer with - data to be committed. The TL - copies the data from the - buffer into the stream buffer - and returns. - Users should be aware that there are implementation overheads - associated with every stream buffer. If you find that less - data are captured than expected then try increasing the - stream buffer size or use TLInfo to obtain buffer parameters - and calculate optimum required values at run time. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TLSTREAM_H -#define TLSTREAM_H - -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "pvrsrv_tlcommon.h" -#include "device.h" - -/*! Extract TL stream opmode from the given stream create flags. - * Last 3 bits of streamFlag is used for storing opmode, hence - * opmode mask is set as following. */ -#define TL_OPMODE_MASK 0x7 - -/* - * NOTE: This enum is used to directly access the HTB_OPMODE_xxx values - * within htbserver.c. - * As such we *MUST* keep the values matching in order of declaration. - */ -/*! Opmode specifying circular buffer behaviour */ -typedef enum -{ - /*! Undefined operation mode */ - TL_OPMODE_UNDEF = 0, - - /*! Reject new data if the buffer is full, producer may then decide to - * drop the data or retry after some time. */ - TL_OPMODE_DROP_NEWER, - - /*! When buffer is full, advance the tail/read position to accept the new - * reserve call (size permitting), effectively overwriting the oldest - * data in the circular buffer. Not supported yet. */ - TL_OPMODE_DROP_OLDEST, - - /*! Block Reserve (subsequently Write) calls if there is not enough space - * until some space is freed via a client read operation. */ - TL_OPMODE_BLOCK, - - /*!< For error checking */ - TL_OPMODE_LAST - -} TL_OPMODE; - -typedef enum { - /* Enum to be used in conjunction with new Flags feature */ - - /* Flag set when Drop Oldest is set and packets have been dropped */ - TL_FLAG_OVERWRITE_DETECTED = (1 << 0), - /* Prevents DoTLStreamReserve() from adding from injecting - * PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED */ - TL_FLAG_NO_WRITE_FAILED = (1 << 1), -} TL_Flags; - -static_assert(TL_OPMODE_LAST <= TL_OPMODE_MASK, - "TL_OPMODE_LAST must not exceed TL_OPMODE_MASK"); - -/*! Flags specifying stream behaviour */ -/*! Do not destroy stream if there still are data that have not been - * copied in user space. Block until the stream is emptied. */ -#define TL_FLAG_FORCE_FLUSH (1U<<8) -/*! Do not signal consumers on commit automatically when the stream buffer - * transitions from empty to non-empty. Producer responsible for signal when - * it chooses. */ -#define TL_FLAG_NO_SIGNAL_ON_COMMIT (1U<<9) - -/*! When a stream has this property it never wraps around and - * overwrites existing data, hence it is a fixed size persistent - * buffer, data written is permanent. Producers need to ensure - * the buffer is big enough for their needs. - * When a stream is opened for reading the client will always - * find the read position at the start of the buffer/data. */ -#define TL_FLAG_PERMANENT_NO_WRAP (1U<<10) - -/*! Defer allocation of stream's shared memory until first open. */ -#define TL_FLAG_ALLOCATE_ON_FIRST_OPEN (1U<<11) - -/*! Structure used to pass internal TL stream sizes information to users.*/ -typedef struct _TL_STREAM_INFO_ -{ - IMG_UINT32 headerSize; /*!< Packet header size in bytes */ - IMG_UINT32 minReservationSize; /*!< Minimum data size reserved in bytes */ - IMG_UINT32 pageSize; /*!< Page size in bytes */ - IMG_UINT32 pageAlign; /*!< Page alignment in bytes */ - IMG_UINT32 maxTLpacketSize; /*! Max allowed TL packet size*/ -} TL_STREAM_INFO, *PTL_STREAM_INFO; - -/*! Callback operations or notifications that a stream producer may handle - * when requested by the Transport Layer. - */ -#define TL_SOURCECB_OP_CLIENT_EOS 0x01 /*!< Client has reached end of stream, - * can anymore data be supplied? - * ui32Resp ignored in this operation */ - -/*! Function pointer type for the callback handler into the "producer" code - * that writes data to the TL stream. Producer should handle the notification - * or operation supplied in ui32ReqOp on stream hStream. The - * Operations and notifications are defined above in TL_SOURCECB_OP */ -typedef PVRSRV_ERROR (*TL_STREAM_SOURCECB)(IMG_HANDLE hStream, - IMG_UINT32 ui32ReqOp, IMG_UINT32* ui32Resp, void* pvUser); - -typedef void (*TL_STREAM_ONREADEROPENCB)(void *pvArg); - -/*************************************************************************/ /*! - @Function TLAllocSharedMemIfNull - @Description Allocates shared memory for the stream. - @Input hStream Stream handle. - @Return eError Internal services call returned eError error - number. - @Return PVRSRV_OK -*/ /**************************************************************************/ -PVRSRV_ERROR -TLAllocSharedMemIfNull(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLFreeSharedMem - @Description Frees stream's shared memory. - @Input phStream Stream handle. -*/ /**************************************************************************/ -void -TLFreeSharedMem(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamCreate - @Description Request the creation of a new stream and open a handle. - If creating a stream which should continue to exist after the - current context is finished, then TLStreamCreate must be - followed by a TLStreamOpen call. On any case, the number of - create/open calls must balance with the number of close calls - used. This ensures the resources of a stream are released when - it is no longer required. - @Output phStream Pointer to handle to store the new stream. - @Input szStreamName Name of stream, maximum length: - PRVSRVTL_MAX_STREAM_NAME_SIZE. - If a longer string is provided,creation fails. - @Input ui32Size Desired buffer size in bytes. - @Input ui32StreamFlags Used to configure buffer behaviour. See above. - @Input pfOnReaderOpenCB Optional callback called when a client - opens this stream, may be null. - @Input pvOnReaderOpenUD Optional user data for pfOnReaderOpenCB, - may be null. - @Input pfProducerCB Optional callback, may be null. - @Input pvProducerUD Optional user data for callback, may be null. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handle or string name - exceeded MAX_STREAM_NAME_SIZE - @Return PVRSRV_ERROR_OUT_OF_MEMORY Failed to allocate space for - stream handle. - @Return PVRSRV_ERROR_DUPLICATE_VALUE There already exists a stream with - the same stream name string. - @Return eError Internal services call returned - eError error number. - @Return PVRSRV_OK -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamCreate(IMG_HANDLE *phStream, - const IMG_CHAR *szStreamName, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32StreamFlags, - TL_STREAM_ONREADEROPENCB pfOnReaderOpenCB, - void *pvOnReaderOpenUD, - TL_STREAM_SOURCECB pfProducerCB, - void *pvProducerUD); - -/*************************************************************************/ /*! - @Function TLStreamOpen - @Description Attach to existing stream that has already been created by a - TLStreamCreate call. A handle is returned to the stream. - @Output phStream Pointer to handle to store the stream. - @Input szStreamName Name of stream, should match an already - existing stream name - @Return PVRSRV_ERROR_NOT_FOUND None of the streams matched the - requested stream name. - PVRSRV_ERROR_INVALID_PARAMS Non-NULL pointer to stream - handler is required. - @Return PVRSRV_OK Success. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamOpen(IMG_HANDLE *phStream, - const IMG_CHAR *szStreamName); - - -/*************************************************************************/ /*! - @Function TLStreamReset - @Description Resets read and write pointers and pending flag. - @Output phStream Pointer to stream's handle -*/ /**************************************************************************/ -void TLStreamReset(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamSetNotifStream - @Description Registers a "notification stream" which will be used to - publish information about state change of the "hStream" - stream. Notification can inform about events such as stream - open/close, etc. - @Input hStream Handle to stream to update. - @Input hNotifStream Handle to the stream which will be used for - publishing notifications. - @Return PVRSRV_ERROR_INVALID_PARAMS If either of the parameters is - NULL - @Return PVRSRV_OK Success. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamSetNotifStream(IMG_HANDLE hStream, IMG_HANDLE hNotifStream); - -/*************************************************************************/ /*! - @Function TLStreamReconfigure - @Description Request the stream flags controlling buffer behaviour to - be updated. - In the case where TL_OPMODE_BLOCK is to be used, - TLStreamCreate should be called without that flag and this - function used to change the stream mode once a consumer process - has been started. This avoids a deadlock scenario where the - TLStreaWrite/TLStreamReserve call will hold the Bridge Lock - while blocking if the TL buffer is full. - The TL_OPMODE_BLOCK should never drop the Bridge Lock - as this leads to another deadlock scenario where the caller to - TLStreamWrite/TLStreamReserve has already acquired another lock - (e.g. gHandleLock) which is not dropped. This then leads to that - thread acquiring locks out of order. - @Input hStream Handle to stream to update. - @Input ui32StreamFlags Flags that configure buffer behaviour. See above. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handle or inconsistent - stream flags. - @Return PVRSRV_ERROR_NOT_READY Stream is currently being written to - try again later. - @Return eError Internal services call returned - eError error number. - @Return PVRSRV_OK -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamReconfigure(IMG_HANDLE hStream, - IMG_UINT32 ui32StreamFlags); - -/*************************************************************************/ /*! - @Function TLStreamClose - @Description Detach from the stream associated with the given handle. If - the current handle is the last one accessing the stream - (i.e. the number of TLStreamCreate+TLStreamOpen calls matches - the number of TLStreamClose calls) then the stream is also - deleted. - On return the handle is no longer valid. - @Input hStream Handle to stream that will be closed. - @Return None. -*/ /**************************************************************************/ -void -TLStreamClose(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamReserve - @Description Reserve space in stream buffer. When successful every - TLStreamReserve call must be followed by a matching - TLStreamCommit call. While a TLStreamCommit call is pending - for a stream, subsequent TLStreamReserve calls for this - stream will fail. - @Input hStream Stream handle. - @Output ppui8Data Pointer to a pointer to a location in the - buffer. The caller can then use this address - in writing data into the stream. - @Input ui32Size Number of bytes to reserve in buffer. - @Return PVRSRV_INVALID_PARAMS NULL stream handler. - @Return PVRSRV_ERROR_NOT_READY There are data previously reserved - that are pending to be committed. - @Return PVRSRV_ERROR_STREAM_MISUSE Misusing the stream by trying to - reserve more space than the - buffer size. - @Return PVRSRV_ERROR_STREAM_FULL The reserve size requested - is larger than the free - space. - @Return PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED The reserve size - requested is larger - than max TL packet size - @Return PVRSRV_ERROR_STREAM_NOT_ENOUGH_SPACE Permanent stream buffer - does not have enough space - for the reserve. - @Return PVRSRV_OK Success, output arguments valid. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamReserve(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size); - -/*************************************************************************/ /*! - @Function TLStreamReserve2 - @Description Reserve space in stream buffer. When successful every - TLStreamReserve call must be followed by a matching - TLStreamCommit call. While a TLStreamCommit call is pending - for a stream, subsequent TLStreamReserve calls for this - stream will fail. - @Input hStream Stream handle. - @Output ppui8Data Pointer to a pointer to a location in the - buffer. The caller can then use this address - in writing data into the stream. - @Input ui32Size Ideal number of bytes to reserve in buffer. - @Input ui32SizeMin Minimum number of bytes to reserve in buffer. - @Input pui32Available Optional, but when present and the - RESERVE_TOO_BIG error is returned, a size - suggestion is returned in this argument which - the caller can attempt to reserve again for a - successful allocation. - @Output pbIsReaderConnected Let writing clients know if reader is - connected or not, in case of error. - @Return PVRSRV_INVALID_PARAMS NULL stream handler. - @Return PVRSRV_ERROR_NOT_READY There are data previously reserved - that are pending to be committed. - @Return PVRSRV_ERROR_STREAM_MISUSE Misusing the stream by trying to - reserve more space than the - buffer size. - @Return PVRSRV_ERROR_STREAM_FULL The reserve size requested - is larger than the free - space. - Check the pui32Available - value for the correct - reserve size to use. - @Return PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED The reserve size - requested is larger - than max TL packet size - @Return PVRSRV_ERROR_STREAM_NOT_ENOUGH_SPACE Permanent stream buffer - does not have enough space - for the reserve. - @Return PVRSRV_OK Success, output arguments valid. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamReserve2(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32SizeMin, - IMG_UINT32* pui32Available, - IMG_BOOL* pbIsReaderConnected); - -/*************************************************************************/ /*! - @Function TLStreamReserveReturnFlags - @Description Reserve space in stream buffer. When successful every - TLStreamReserve call must be followed by a matching - TLStreamCommit call. While a TLStreamCommit call is pending - for a stream, subsequent TLStreamReserve calls for this - stream will fail. - @Input hStream Stream handle. - @Output ppui8Data Pointer to a pointer to a location in the - buffer. The caller can then use this address - in writing data into the stream. - @Input ui32Size Ideal number of bytes to reserve in buffer. - @Output pui32Flags Output parameter to return flags generated within - the reserve function. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamReserveReturnFlags(IMG_HANDLE hStream, - IMG_UINT8 **ppui8Data, - IMG_UINT32 ui32Size, - IMG_UINT32* pui32Flags); - -/*************************************************************************/ /*! - @Function TLStreamGetUT - @Description Returns the current stream utilisation in bytes - @Input hStream Stream handle. - @Return IMG_UINT32 Stream utilisation -*/ /**************************************************************************/ -IMG_UINT32 TLStreamGetUT(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamCommit - @Description Notify TL that data have been written in the stream buffer. - Should always follow and match TLStreamReserve call. - @Input hStream Stream handle. - @Input ui32Size Number of bytes that have been added to the - stream. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handle. - @Return PVRSRV_ERROR_STREAM_MISUSE Commit results in more data - committed than the buffer size, - the stream is misused. - @Return eError Commit was successful but - internal services call returned - eError error number. - @Return PVRSRV_OK -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamCommit(IMG_HANDLE hStream, - IMG_UINT32 ui32Size); - -/*************************************************************************/ /*! - @Function TLStreamWrite - @Description Combined Reserve/Commit call. This function Reserves space in - the specified stream buffer, copies ui32Size bytes of data - from the array pui8Src points to and Commits in an "atomic" - style operation. - @Input hStream Stream handle. - @Input pui8Src Source to read data from. - @Input ui32Size Number of bytes to copy and commit. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handler. - @Return eError Error codes returned by either - Reserve or Commit. - @Return PVRSRV_OK - */ /**************************************************************************/ -PVRSRV_ERROR -TLStreamWrite(IMG_HANDLE hStream, - IMG_UINT8 *pui8Src, - IMG_UINT32 ui32Size); - -/*************************************************************************/ /*! - @Function TLStreamWriteRetFlags - @Description Combined Reserve/Commit call. This function Reserves space in - the specified stream buffer, copies ui32Size bytes of data - from the array pui8Src points to and Commits in an "atomic" - style operation. Also accepts a pointer to a bit flag value - for returning write status flags. - @Input hStream Stream handle. - @Input pui8Src Source to read data from. - @Input ui32Size Number of bytes to copy and commit. - @Output pui32Flags Output parameter for write status info - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handler. - @Return eError Error codes returned by either - Reserve or Commit. - @Return PVRSRV_OK - */ /**************************************************************************/ -PVRSRV_ERROR -TLStreamWriteRetFlags(IMG_HANDLE hStream, - IMG_UINT8 *pui8Src, - IMG_UINT32 ui32Size, - IMG_UINT32 *pui32Flags); - -/*************************************************************************/ /*! - @Function TLStreamSync - @Description Signal the consumer to start acquiring data from the stream - buffer. Called by producers that use the flag - TL_FLAG_NO_SIGNAL_ON_COMMIT to manually control when - consumers starting reading the stream. - Used when multiple small writes need to be batched. - @Input hStream Stream handle. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handle. - @Return eError Error codes returned by either - Reserve or Commit. - @Return PVRSRV_OK - */ /**************************************************************************/ -PVRSRV_ERROR -TLStreamSync(IMG_HANDLE hStream); - - -/*************************************************************************/ /*! - @Function TLStreamMarkEOS - @Description Insert a EOS marker packet in the given stream. - @Input hStream Stream handle. - @Input bRemoveOld if TRUE, remove old stream record file before - splitting to new file. - @Return PVRSRV_ERROR_INVALID_PARAMS NULL stream handler. - @Return eError Error codes returned by either - Reserve or Commit. - @Return PVRSRV_OK Success. -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamMarkEOS(IMG_HANDLE hStream, IMG_BOOL bRemoveOld); - -/*************************************************************************/ /*! -@Function TLStreamMarkStreamOpen -@Description Puts *open* stream packet into hStream's notification stream, - if set, error otherwise." -@Input hStream Stream handle. -@Return PVRSRV_OK on success and error code on failure -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamMarkStreamOpen(IMG_HANDLE hStream); - -/*************************************************************************/ /*! -@Function TLStreamMarkStreamClose -@Description Puts *close* stream packet into hStream's notification stream, - if set, error otherwise." -@Input hStream Stream handle. -@Return PVRSRV_OK on success and error code on failure -*/ /**************************************************************************/ -PVRSRV_ERROR -TLStreamMarkStreamClose(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamInfo - @Description Run time information about buffer elemental sizes. - It sets psInfo members accordingly. Users can use those values - to calculate the parameters they use in TLStreamCreate and - TLStreamReserve. - @Output psInfo pointer to stream info structure. - @Return None. -*/ /**************************************************************************/ -void -TLStreamInfo(IMG_HANDLE hStream, PTL_STREAM_INFO psInfo); - -/*************************************************************************/ /*! - @Function TLStreamIsOpenForReading - @Description Query if a stream has any readers connected. - @Input hStream Stream handle. - @Return IMG_BOOL True if at least one reader is connected, - false otherwise -*/ /**************************************************************************/ -IMG_BOOL -TLStreamIsOpenForReading(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamOutOfData - @Description Query if the stream is empty (no data waiting to be read). - @Input hStream Stream handle. - @Return IMG_BOOL True if read==write, no data waiting, - false otherwise -*/ /**************************************************************************/ -IMG_BOOL TLStreamOutOfData(IMG_HANDLE hStream); - -/*************************************************************************/ /*! - @Function TLStreamResetProducerByteCount - @Description Reset the producer byte counter on the specified stream. - @Input hStream Stream handle. - @Input IMG_UINT32 Value to reset counter to, often 0. - @Return PVRSRV_OK Success. - @Return PVRSRV_ERROR_STREAM_MISUSE Success but the read and write - positions did not match, - stream not empty. -*/ /**************************************************************************/ - -PVRSRV_ERROR -TLStreamResetProducerByteCount(IMG_HANDLE hStream, IMG_UINT32 ui32Value); - -#endif /* TLSTREAM_H */ -/***************************************************************************** - End of file (tlstream.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/trace_events.c b/drivers/gpu/drm/img-rogue/1.17/trace_events.c deleted file mode 100644 index 39242ed2b95ca..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/trace_events.c +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************/ /*! -@Title Linux trace event helper functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 - -#if defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) -#if !defined(CONFIG_TRACE_GPU_MEM) -#define CREATE_TRACE_POINTS -#include -#undef CREATE_TRACE_POINTS -#else /* !defined(CONFIG_TRACE_GPU_MEM) */ -#include -#endif /* !defined(CONFIG_TRACE_GPU_MEM) */ -#endif /* defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) */ - -#include "img_types.h" -#include "trace_events.h" -#include "rogue_trace_events.h" -#include "sync_checkpoint_external.h" - -static bool fence_update_event_enabled, fence_check_event_enabled; - -bool trace_rogue_are_fence_updates_traced(void) -{ - return fence_update_event_enabled; -} - -bool trace_rogue_are_fence_checks_traced(void) -{ - return fence_check_event_enabled; -} - -/* - * Call backs referenced from rogue_trace_events.h. Note that these are not - * thread-safe, however, since running trace code when tracing is not enabled is - * simply a no-op, there is no harm in it. - */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int trace_fence_update_enabled_callback(void) -#else -void trace_fence_update_enabled_callback(void) -#endif -{ - fence_update_event_enabled = true; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - return 0; -#endif -} - -void trace_fence_update_disabled_callback(void) -{ - fence_update_event_enabled = false; -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -int trace_fence_check_enabled_callback(void) -#else -void trace_fence_check_enabled_callback(void) -#endif -{ - fence_check_event_enabled = true; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - return 0; -#endif -} - -void trace_fence_check_disabled_callback(void) -{ - fence_check_event_enabled = false; -} - -#if defined(SUPPORT_RGX) -/* This is a helper that calls trace_rogue_fence_update for each fence in an - * array. - */ -void trace_rogue_fence_updates(const char *cmd, const char *dm, IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values) -{ - IMG_UINT i; - for (i = 0; i < uCount; i++) - { - trace_rogue_fence_update(current->comm, cmd, dm, ui32FWContext, ui32Offset, - pauiAddresses[i].ui32Addr, PVRSRV_SYNC_CHECKPOINT_SIGNALLED); - } -} - -void trace_rogue_fence_checks(const char *cmd, const char *dm, IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values) -{ - IMG_UINT i; - for (i = 0; i < uCount; i++) - { - trace_rogue_fence_check(current->comm, cmd, dm, ui32FWContext, ui32Offset, - pauiAddresses[i].ui32Addr, PVRSRV_SYNC_CHECKPOINT_SIGNALLED); - } -} - -void trace_rogue_ufo_updates(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ - IMG_UINT i; - for (i = 0; i < ui32UFOCount; i++) - { - trace_rogue_ufo_update(ui64OSTimestamp, ui32FWCtx, - ui32IntJobRef, - ui32ExtJobRef, - puData->sUpdate.ui32FWAddr, - puData->sUpdate.ui32OldValue, - puData->sUpdate.ui32NewValue); - puData = IMG_OFFSET_ADDR(puData, sizeof(puData->sUpdate)); - } -} - -void trace_rogue_ufo_checks_success(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ - IMG_UINT i; - for (i = 0; i < ui32UFOCount; i++) - { - if (bPrEvent) - { - trace_rogue_ufo_pr_check_success(ui64OSTimestamp, ui32FWCtx, - ui32IntJobRef, ui32ExtJobRef, - puData->sCheckSuccess.ui32FWAddr, - puData->sCheckSuccess.ui32Value); - } - else - { - trace_rogue_ufo_check_success(ui64OSTimestamp, ui32FWCtx, - ui32IntJobRef, ui32ExtJobRef, - puData->sCheckSuccess.ui32FWAddr, - puData->sCheckSuccess.ui32Value); - } - puData = IMG_OFFSET_ADDR(puData, sizeof(puData->sCheckSuccess)); - } -} - -void trace_rogue_ufo_checks_fail(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ - IMG_UINT i; - for (i = 0; i < ui32UFOCount; i++) - { - if (bPrEvent) - { - trace_rogue_ufo_pr_check_fail(ui64OSTimestamp, ui32FWCtx, - ui32IntJobRef, ui32ExtJobRef, - puData->sCheckFail.ui32FWAddr, - puData->sCheckFail.ui32Value, - puData->sCheckFail.ui32Required); - } - else - { - trace_rogue_ufo_check_fail(ui64OSTimestamp, ui32FWCtx, - ui32IntJobRef, ui32ExtJobRef, - puData->sCheckFail.ui32FWAddr, - puData->sCheckFail.ui32Value, - puData->sCheckFail.ui32Required); - } - puData = IMG_OFFSET_ADDR(puData, sizeof(puData->sCheckFail)); - } -} -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - -int PVRGpuTraceEnableUfoCallbackWrapper(void) -{ - -#if defined(SUPPORT_RGX) - PVRGpuTraceEnableUfoCallback(); -#endif - - return 0; -} - -int PVRGpuTraceEnableFirmwareActivityCallbackWrapper(void) -{ - -#if defined(SUPPORT_RGX) - PVRGpuTraceEnableFirmwareActivityCallback(); -#endif - - return 0; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) */ - -void TracepointUpdateGPUMemGlobal(IMG_UINT8 ui8GPUId, - IMG_UINT64 ui64Size) -{ -#if defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) - trace_gpu_mem_total(ui8GPUId, 0, ui64Size); -#endif /* defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) */ -} - -void TracepointUpdateGPUMemPerProcess(IMG_UINT8 ui8GPUId, - IMG_UINT32 ui32Pid, - IMG_UINT64 ui64Size) -{ -#if defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) - trace_gpu_mem_total(ui8GPUId, ui32Pid, ui64Size); -#endif /* defined(CONFIG_TRACE_GPU_MEM) || defined(PVRSRV_ENABLE_GPU_MEM_TRACEPOINT) */ -} diff --git a/drivers/gpu/drm/img-rogue/1.17/trace_events.h b/drivers/gpu/drm/img-rogue/1.17/trace_events.h deleted file mode 100644 index 0a8fffd5bc376..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/trace_events.h +++ /dev/null @@ -1,198 +0,0 @@ -/*************************************************************************/ /*! -@Title Linux trace events and event helper functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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. -*/ /**************************************************************************/ - -#if !defined(TRACE_EVENTS_H) -#define TRACE_EVENTS_H - -#include "rgx_fwif_km.h" -#include "rgx_hwperf.h" - -/* We need to make these functions do nothing if CONFIG_EVENT_TRACING isn't - * enabled, just like the actual trace event functions that the kernel - * defines for us. - */ -#ifdef CONFIG_EVENT_TRACING -bool trace_rogue_are_fence_checks_traced(void); - -bool trace_rogue_are_fence_updates_traced(void); - -void trace_job_enqueue(IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - const char *pszKickType); - -#if defined(SUPPORT_RGX) -void trace_rogue_fence_updates(const char *cmd, const char *dm, - IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values); - -void trace_rogue_fence_checks(const char *cmd, const char *dm, - IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values); - -void trace_rogue_ufo_updates(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData); - -void trace_rogue_ufo_checks_success(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData); - -void trace_rogue_ufo_checks_fail(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData); -#endif /* if defined(SUPPORT_RGX) */ - -void TracepointUpdateGPUMemGlobal(IMG_UINT8 ui8GPUId, - IMG_UINT64 ui64Size); - -void TracepointUpdateGPUMemPerProcess(IMG_UINT8 ui8GPUId, - IMG_UINT32 ui32Pid, - IMG_UINT64 ui64Size); - -#else /* CONFIG_TRACE_EVENTS */ -static inline -bool trace_rogue_are_fence_checks_traced(void) -{ - return false; -} - -static inline -bool trace_rogue_are_fence_updates_traced(void) -{ - return false; -} - -static inline -void trace_job_enqueue(IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - const char *pszKickType) -{ -} - -#if defined(SUPPORT_RGX) -static inline -void trace_rogue_fence_updates(const char *cmd, const char *dm, - IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values) -{ -} - -static inline -void trace_rogue_fence_checks(const char *cmd, const char *dm, - IMG_UINT32 ui32FWContext, - IMG_UINT32 ui32Offset, - IMG_UINT uCount, - PRGXFWIF_UFO_ADDR *pauiAddresses, - IMG_UINT32 *paui32Values) -{ -} - -static inline -void trace_rogue_ufo_updates(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ -} - -static inline -void trace_rogue_ufo_checks_success(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ -} - -static inline -void trace_rogue_ufo_checks_fail(IMG_UINT64 ui64OSTimestamp, - IMG_UINT32 ui32FWCtx, - IMG_UINT32 ui32ExtJobRef, - IMG_UINT32 ui32IntJobRef, - IMG_BOOL bPrEvent, - IMG_UINT32 ui32UFOCount, - const RGX_HWPERF_UFO_DATA_ELEMENT *puData) -{ -} -#endif /* if defined(SUPPORT_RGX)*/ - -static inline -void TracepointUpdateGPUMemGlobal(IMG_UINT8 ui8GPUId, - IMG_UINT64 ui64Size) -{ -} - -static inline -void TracepointUpdateGPUMemPerProcess(IMG_UINT8 ui8GPUId, - IMG_UINT32 ui32Pid, - IMG_UINT64 ui64Size) -{ -} - -#endif /* CONFIG_TRACE_EVENTS */ - -#endif /* TRACE_EVENTS_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/tutils_km.h b/drivers/gpu/drm/img-rogue/1.17/tutils_km.h deleted file mode 100644 index d39c07085f0a2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tutils_km.h +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************/ /*! -@File tutils_km.h -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Kernel services functions for calls to tutils (testing utils) - layer in the server -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TUTILS_KM_H -#define TUTILS_KM_H - -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "connection_server.h" -#include "device.h" -#include "pvrsrv_sync_km.h" - - -PVRSRV_ERROR ServerTestIoctlKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 uiCmd, - IMG_PBYTE uiIn1, - IMG_UINT32 uiIn2, - IMG_UINT32* puiOut1, - IMG_UINT32* puiOut2); - -PVRSRV_ERROR PowMonTestIoctlKM(IMG_UINT32 uiCmd, - IMG_UINT32 uiIn1, - IMG_UINT32 uiIn2, - IMG_UINT32 *puiOut1, - IMG_UINT32 *puiOut2); - -PVRSRV_ERROR SyncCheckpointTestIoctlKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 uiCmd, - IMG_UINT32 uiIn1, - IMG_UINT32 uiIn2, - const IMG_CHAR *pszInName, - IMG_UINT32 *puiOut1, - IMG_UINT32 *puiOut2, - IMG_UINT8 *puiOut3); - -IMG_EXPORT -PVRSRV_ERROR DevmemIntAllocHostMemKM(IMG_DEVMEM_SIZE_T ui32Size, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - IMG_UINT32 ui32LableLength, - const IMG_CHAR *pszAllocLabel, - PMR **ppsPMR); - -PVRSRV_ERROR DevmemIntFreeHostMemKM(PMR *psPMR); - -IMG_EXPORT -PVRSRV_ERROR PowerTestIoctlKM(IMG_UINT32 uiCmd, - IMG_UINT32 uiIn1, - IMG_UINT32 uiIn2, - IMG_UINT32 *puiOut1, - IMG_UINT32 *puiOut2); - -PVRSRV_ERROR TestIOCTLSyncFbFenceSignalPVR(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - void *psFence); - -PVRSRV_ERROR TestIOCTLSyncFbFenceCreatePVR(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_UINT32 uiNameLength, - const IMG_CHAR *pszName, - PVRSRV_TIMELINE iTL, - PVRSRV_FENCE *piOutFence); - -PVRSRV_ERROR TestIOCTLSyncFbFenceResolvePVR(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_FENCE iFence); -PVRSRV_ERROR TestIOCTLSyncFbSWTimelineAdvance(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE iSWTl); - -PVRSRV_ERROR TestIOCTLSyncFbSWFenceCreate(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE iTl, - IMG_UINT32 uiFenceNameLength, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE *piFence); - - - -PVRSRV_ERROR TestIOCTLSyncSWTimelineFenceCreateKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE sTimeline, - IMG_UINT32 uiNameLength, - const IMG_CHAR *pszFenceName, - PVRSRV_FENCE *psOutFence); - -PVRSRV_ERROR TestIOCTLSyncSWTimelineAdvanceKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_TIMELINE sTimeline); - -PVRSRV_ERROR TestIOCTLIsTimelineValidKM(PVRSRV_TIMELINE sTimeline, - IMG_BOOL *bResult); - -PVRSRV_ERROR TestIOCTLIsFenceValidKM(PVRSRV_FENCE sFence, - IMG_BOOL *bResult); - -PVRSRV_ERROR TestIOCTLSyncCheckpointResolveFenceKM(CONNECTION_DATA * psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - PVRSRV_FENCE hFence, - IMG_UINT32 *pui32NumSyncCheckpoints); - -PVRSRV_ERROR TestIOCTLSyncCheckpointCreateFenceKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDevNode, - IMG_CHAR *pszFenceName, - PVRSRV_TIMELINE hTimeline, - PVRSRV_FENCE *phOutFence, - IMG_UINT64 *puiUpdateFenceUID); - -PVRSRV_ERROR TestIOCTLWriteByteKM(IMG_BYTE ui8WriteData); - -PVRSRV_ERROR TestIOCTLReadByteKM(IMG_BYTE *pui8ReadData); - -typedef IMG_UINT32 DI_CONTEXT; -PVRSRV_ERROR TestIOCTLHandleArray2CreateKM(DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleArray10CreateKM(DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleCleanupDestroy(DI_CONTEXT *psTestResource); -PVRSRV_ERROR TestIOCTLHandleArray2CreateCPKM(DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleCleanupDestroyCP(DI_CONTEXT *psTestResource); -PVRSRV_ERROR TestIOCTLHandleArray2CreatePPKM(CONNECTION_DATA *psConnection, - PVRSRV_DEVICE_NODE *psDeviceNode, - DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleArray2CreateLUKM(DI_CONTEXT *psLookedup, - DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleArrayNCreate(IMG_UINT32 ui32NumResourcesRequested, - IMG_UINT32 *pui32NumResourcesCreated, - DI_CONTEXT **ppsTestResources); -PVRSRV_ERROR TestIOCTLHandleArrayNCreateCP(IMG_UINT32 ui32NumResourcesRequested, - IMG_UINT32 *pui32NumResourcesCreated, - DI_CONTEXT **ppsTestResources); - -#endif /* TUTILS_KM_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/tutilsdefs.h b/drivers/gpu/drm/img-rogue/1.17/tutilsdefs.h deleted file mode 100644 index b89e4a4bbb1f2..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/tutilsdefs.h +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************/ /*! -@File tutilsdefs.h -@Title Testing utils bridge defines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Shared structures and constants between client and server sides - of tutils bridge -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 TUTILSDEFS_H -#define TUTILSDEFS_H - - -#include "pvrsrv_tlcommon.h" -#include "pvrsrv_sync_km.h" - -/****************************************************************************** - * - * TEST Related definitions and constants - */ -#define PVR_TL_TEST_STREAM_BRIDGE_NAME "TLBRIDGE_TEST" -#define PVR_TL_TEST_UMBASE 0x00202000 -#define PVR_TL_TEST_OFFSET 0x0008 -#define PVR_TL_TEST_LEN 0x0010 - -#define PVR_TL_TEST_STREAM2_NAME "TLSTREAM2_TEST" -#define PVR_TL_TEST_STREAM2_SIZE 2 - -#define PVR_TL_TEST_STREAM3_NAME "TLSTREAM3_TEST" -#define PVR_TL_TEST_STREAM3_SIZE 256 - -// This constant, when used as a parameter in StreamCreate, lessens the size of -// the buffer that is created for a stream, to avoid going over a page boundary. -#define PVR_TL_TEST_STREAM_BUFFER_REDUCTION 32 - -#define PVR_TL_TEST_CMD_SOURCE_START 10 -typedef struct _PVR_TL_TEST_CMD_SOURCE_START_IN_ -{ - /* Stream name must always be first in struct */ - IMG_CHAR pszStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; - IMG_UINT16 uiStreamSizeInPages; /* # of 4Kb pages */ - IMG_UINT16 uiInterval; /* in milliseconds */ - IMG_UINT16 uiCallbackKicks; /* 0 for no limit of timer call backs */ - IMG_UINT16 uiEOSMarkerKicks; /* Insert EOS Marker every N Kicks, 0 for none */ - IMG_UINT16 uiPacketSizeInBytes; /* 0 for random size between 1..255 size in bytes */ - IMG_UINT32 uiStreamCreateFlags; /* See TLStreamCreate() */ - IMG_UINT16 uiStartDelay; /* 0 for normal uiInterval delay, one off delay in ms */ - IMG_BOOL bDoNotDeleteStream; /* When true the stream is not deleted on self - * cleanup sources only the timers and other resources are */ - IMG_BOOL bDelayStreamCreate; /* When true the stream used in the source is created - * in the first kick. False for normal behaviour where - * the stream is created in the bridge source start context */ -} PVR_TL_TEST_CMD_SOURCE_START_IN; - - -#define PVR_TL_TEST_CMD_SOURCE_STOP 11 -typedef struct _PVR_TL_TEST_CMD_SOURCE_STOP_IN_ -{ - /* Stream name must always be first in struct */ - IMG_CHAR pszStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; - IMG_BOOL bDoNotDeleteStream; -} PVR_TL_TEST_CMD_SOURCE_STOP_IN; - -#define PVR_TL_TEST_CMD_SOURCE_START2 12 /* Uses two stage data submit */ -typedef PVR_TL_TEST_CMD_SOURCE_START_IN PVR_TL_TEST_CMD_SOURCE_START2_IN; - -#define PVR_TL_TEST_CMD_DEBUG_LEVEL 13 -/* No typedef, uses integer uiIn1 in union */ - -#define PVR_TL_TEST_CMD_DUMP_TL_STATE 14 -/* No typedef, uses integer uiIn1 in union */ - -#define PVR_TL_TEST_CMD_STREAM_CREATE 15 -typedef struct _PVR_TL_TEST_CMD_STREAM_CREATE_IN_ -{ - /* Stream name must always be first in struct */ - IMG_CHAR pszStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; - IMG_UINT16 uiStreamSizeInPages; - IMG_UINT32 uiStreamCreateFlags; - IMG_BOOL bWithOpenCallback; -} PVR_TL_TEST_CMD_STREAM_CREATE_IN; - -#define PVR_TL_TEST_CMD_STREAM_CLOSE 16 -typedef struct _PVR_TL_TEST_CMD_STREAM_NAME_IN_ -{ - IMG_CHAR pszStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; -} PVR_TL_TEST_CMD_STREAM_NAME_IN; - -#define PVR_TL_TEST_CMD_STREAM_OPEN 17 - -#define PVR_TL_TEST_CMD_DUMP_HWPERF_STATE 18 - -#define PVR_TL_TEST_CMD_FLUSH_HWPERF_FWBUF 19 - -#define PVR_TL_TEST_CMD_DUMP_PDUMP_STATE 21 - -typedef union _PVR_TL_TEST_CMD_IN_ -{ - PVR_TL_TEST_CMD_SOURCE_START_IN sStart; - PVR_TL_TEST_CMD_SOURCE_STOP_IN sStop; -/* PVR_TL_TEST_CMD_SOURCE_START_IN sStart2; Used by #12, use sStart instead */ - IMG_UINT32 uiIn1; /* Used by #13, #14 */ - PVR_TL_TEST_CMD_STREAM_CREATE_IN sCreate; - PVR_TL_TEST_CMD_STREAM_NAME_IN sName; - IMG_UINT32 uiParams[6]; -} PVR_TL_TEST_CMD_IN; - -/* Has to be the largest test IN structure */ -#define PVR_TL_TEST_PARAM_MAX_SIZE (sizeof(PVR_TL_TEST_CMD_IN)+4) - -#define PVR_TL_TEST_CMD_SET_PWR_STATE 22 -#define PVR_TL_TEST_CMD_GET_PWR_STATE 23 -#define PVR_TL_TEST_CMD_SET_DWT_PWR_CHANGE_COUNTER 24 -#define PVR_TL_TEST_CMD_GET_DWT_PWR_CHANGE_COUNTER 25 - -#define PVR_TL_TEST_PWR_STATE_ON 1 -#define PVR_TL_TEST_PWR_STATE_OFF 0 - -/**************************************************************************** - * PowMonTestThread IOCTL calls and constants - */ - -#define PVR_POWMON_CMD_GET_ESTIMATES 1 -#define PVR_POWMON_CMD_SET_THREAD_LATENCY 2 -#define PVR_POWMON_CMD_TEST_THREAD_UPDATE_STATE 3 - -#define PVR_POWMON_TEST_THREAD_RESUME 1 -#define PVR_POWMON_TEST_THREAD_PAUSE 0 - -/**************************************************************************** - * PowerTestThread IOCTL calls and constants - */ - -#define PVR_POWER_TEST_CMD_DVFS 1 -#define PVR_POWER_TEST_CMD_FORCED_IDLE 2 -#define PVR_POWER_TEST_CMD_CANCEL_FORCED_IDLE 3 -#define PVR_POWER_TEST_CMD_POWER_ON 4 -#define PVR_POWER_TEST_CMD_POWER_OFF 5 -#define PVR_POWER_TEST_CMD_APM_LATENCY 6 -#define PVR_POWER_TEST_CMD_INVALID 7 - -#define PVR_POWER_TEST_NON_FORCED 0 -#define PVR_POWER_TEST_FORCED 1 - -/**************************************************************************** - * SyncCheckpointTest IOCTL types - */ - -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_CONTEXT_CREATE 26 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_CONTEXT_DESTROY 27 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_REGISTER_FUNCS 28 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_CREATE 29 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_CREATE_NULL_CTXT 30 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_CREATE_NULL_RTRN 31 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_DESTROY 32 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_SIGNAL 33 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_ERROR 34 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_IS_SIGNALLED 35 -#define PVR_TL_TEST_CMD_SYNC_CHECKPOINT_IS_ERRORED 36 - -typedef struct _PVR_TL_TEST_CMD_CHECKPOINT_CREATE_IN_ -{ - /* Checkpoint name must always be first in struct */ - IMG_CHAR pszCheckpointName[PVRSRV_SYNC_NAME_LENGTH]; - IMG_UINT16 uiStreamSizeInPages; - IMG_UINT32 uiStreamCreateFlags; -} PVR_TL_TEST_CMD_CHECKPOINT_CREATE_IN; - -#define PVR_TL_TEST_CMD_SET_STREAM_OPEN_COUNTER 37 -#define PVR_TL_TEST_CMD_GET_STREAM_OPEN_COUNTER 38 - -typedef struct _PVR_TL_TEST_CMD_STREAM_OPEN_COUNTER_IN_ -{ - IMG_CHAR pszStreamName[PRVSRVTL_MAX_STREAM_NAME_SIZE]; - IMG_UINT32 ui32Counter; -} PVR_TL_TEST_CMD_STREAM_OPEN_COUNTER_IN; - -/**************************************************************************** - * KmallocThreshold IOCTL types - */ - -#define PVR_TL_TEST_CMD_KMALLOC 39 - -typedef struct _PVR_TL_TEST_CMD_KMALLOC_IN_ -{ - IMG_UINT32 uiAllocCount; - IMG_UINT32 uiAllocSize; - IMG_UINT32 uiFailedAllocThreshold; - IMG_UINT32 uiFailedAllocFrequency; -} PVR_TL_TEST_CMD_KMALLOC_IN; - -#endif /* TUTILSDEFS_H */ - -/****************************************************************************** - End of file (tutilsdefs.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.c b/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.c deleted file mode 100644 index 9d40b9d5c0052..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.c +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Provides splay-trees. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implementation of splay-trees. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "allocmem.h" /* for OSMemAlloc / OSMemFree */ -#include "osfunc.h" /* for OSMemFree */ -#include "pvr_debug.h" -#include "uniq_key_splay_tree.h" - -/* - * This function performs a simple top down splay - * - * @param uiFlags the flags that must splayed to the root (if possible). - * @param psTree The tree to splay. - * @return the resulting tree after the splay operation. - */ -IMG_INTERNAL -IMG_PSPLAY_TREE PVRSRVSplay (IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree) -{ - IMG_SPLAY_TREE sTmp1; - IMG_PSPLAY_TREE psLeft; - IMG_PSPLAY_TREE psRight; - IMG_PSPLAY_TREE psTmp2; - - if (psTree == NULL) - { - return NULL; - } - - sTmp1.psLeft = NULL; - sTmp1.psRight = NULL; - - psLeft = &sTmp1; - psRight = &sTmp1; - - for (;;) - { - if (uiFlags < psTree->uiFlags) - { - if (psTree->psLeft == NULL) - { - break; - } - - if (uiFlags < psTree->psLeft->uiFlags) - { - /* if we get to this point, we need to rotate right the tree */ - psTmp2 = psTree->psLeft; - psTree->psLeft = psTmp2->psRight; - psTmp2->psRight = psTree; - psTree = psTmp2; - if (psTree->psLeft == NULL) - { - break; - } - } - - /* if we get to this point, we need to link right */ - psRight->psLeft = psTree; - psRight = psTree; - psTree = psTree->psLeft; - } - else - { - if (uiFlags > psTree->uiFlags) - { - if (psTree->psRight == NULL) - { - break; - } - - if (uiFlags > psTree->psRight->uiFlags) - { - /* if we get to this point, we need to rotate left the tree */ - psTmp2 = psTree->psRight; - psTree->psRight = psTmp2->psLeft; - psTmp2->psLeft = psTree; - psTree = psTmp2; - if (psTree->psRight == NULL) - { - break; - } - } - - /* if we get to this point, we need to link left */ - psLeft->psRight = psTree; - psLeft = psTree; - psTree = psTree->psRight; - } - else - { - break; - } - } - } - - /* at this point re-assemble the tree */ - psLeft->psRight = psTree->psLeft; - psRight->psLeft = psTree->psRight; - psTree->psLeft = sTmp1.psRight; - psTree->psRight = sTmp1.psLeft; - return psTree; -} - - -/* - * This function inserts a node into the Tree (unless it is already present, in - * which case it is equivalent to performing only a splay operation - * - * @param uiFlags the key of the new node - * @param psTree The tree into which one wants to add a new node - * @return The resulting with the node in it - */ -IMG_INTERNAL -IMG_PSPLAY_TREE PVRSRVInsert(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree) -{ - IMG_PSPLAY_TREE psNew; - - if (psTree != NULL) - { - psTree = PVRSRVSplay(uiFlags, psTree); - if (psTree->uiFlags == uiFlags) - { - return psTree; - } - } - - psNew = (IMG_PSPLAY_TREE) OSAllocMem(sizeof(IMG_SPLAY_TREE)); - if (psNew == NULL) - { - PVR_DPF ((PVR_DBG_ERROR, "Error: failed to allocate memory to add a node to the splay tree.")); - return NULL; - } - - psNew->uiFlags = uiFlags; - OSCachedMemSet(&(psNew->buckets[0]), 0, sizeof(psNew->buckets)); - -#if defined(PVR_CTZLL) - psNew->bHasEltsMapping = ~(((IMG_ELTS_MAPPINGS) 1 << (sizeof(psNew->buckets) / (sizeof(psNew->buckets[0])))) - 1); -#endif - - if (psTree == NULL) - { - psNew->psLeft = NULL; - psNew->psRight = NULL; - return psNew; - } - - if (uiFlags < psTree->uiFlags) - { - psNew->psLeft = psTree->psLeft; - psNew->psRight = psTree; - psTree->psLeft = NULL; - } - else - { - psNew->psRight = psTree->psRight; - psNew->psLeft = psTree; - psTree->psRight = NULL; - } - - return psNew; -} - - -/* - * Deletes a node from the tree (unless it is not there, in which case it is - * equivalent to a splay operation) - * - * @param uiFlags the value of the node to remove - * @param psTree the tree into which the node must be removed - * @return the resulting tree - */ -IMG_INTERNAL -IMG_PSPLAY_TREE PVRSRVDelete(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree) -{ - IMG_PSPLAY_TREE psTmp; - if (psTree == NULL) - { - return NULL; - } - - psTree = PVRSRVSplay(uiFlags, psTree); - if (uiFlags == psTree->uiFlags) - { - /* The value was present in the tree */ - if (psTree->psLeft == NULL) - { - psTmp = psTree->psRight; - } - else - { - psTmp = PVRSRVSplay(uiFlags, psTree->psLeft); - psTmp->psRight = psTree->psRight; - } - OSFreeMem(psTree); - return psTmp; - } - - /* The value was not present in the tree, so just return it as is - * (after the splay) */ - return psTree; -} - -/* - * This function picks up the appropriate node for the given flags - * - * @param uiFlags the flags that must associated with the node. - * @param psTree current splay tree node. - * @return the resulting tree node after the search operation. - */ -IMG_INTERNAL -IMG_PSPLAY_TREE PVRSRVFindNode(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree) -{ - if (psTree == NULL) - { - return NULL; - } - - while (psTree) - { - if (uiFlags == psTree->uiFlags) - { - return psTree; - } - - if (uiFlags < psTree->uiFlags) - { - psTree = psTree->psLeft; - continue; - } - - if (uiFlags > psTree->uiFlags) - { - psTree = psTree->psRight; - continue; - } - } - - return NULL; -} diff --git a/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.h b/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.h deleted file mode 100644 index 75ec9297e9c2d..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/uniq_key_splay_tree.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Splay trees interface -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provides debug functionality -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 UNIQ_KEY_SPLAY_TREE_H_ -#define UNIQ_KEY_SPLAY_TREE_H_ - -#include "img_types.h" -#include "pvr_intrinsics.h" - -#if defined(PVR_CTZLL) - /* map the is_bucket_n_free to an int. - * This way, the driver can find the first non empty without loop - */ - typedef IMG_UINT64 IMG_ELTS_MAPPINGS; -#endif - -typedef IMG_UINT64 IMG_PSPLAY_FLAGS_T; - -/* head of list of free boundary tags for indexed by pvr_log2 of the - boundary tag size */ - -#define FREE_TABLE_LIMIT 40 - -struct _BT_; - -typedef struct img_splay_tree -{ - /* left child/subtree */ - struct img_splay_tree * psLeft; - - /* right child/subtree */ - struct img_splay_tree * psRight; - - /* Flags to match on this span, used as the key. */ - IMG_PSPLAY_FLAGS_T uiFlags; -#if defined(PVR_CTZLL) - /* each bit of this int is a boolean telling if the corresponding - bucket is empty or not */ - IMG_ELTS_MAPPINGS bHasEltsMapping; -#endif - struct _BT_ * buckets[FREE_TABLE_LIMIT]; -} IMG_SPLAY_TREE, *IMG_PSPLAY_TREE; - -IMG_PSPLAY_TREE PVRSRVSplay (IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree); -IMG_PSPLAY_TREE PVRSRVInsert(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree); -IMG_PSPLAY_TREE PVRSRVDelete(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree); -IMG_PSPLAY_TREE PVRSRVFindNode(IMG_PSPLAY_FLAGS_T uiFlags, IMG_PSPLAY_TREE psTree); - - -#endif /* !UNIQ_KEY_SPLAY_TREE_H_ */ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_impl.h b/drivers/gpu/drm/img-rogue/1.17/vmm_impl.h deleted file mode 100644 index 9ad5adedaef00..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_impl.h +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_impl.h -@Title Common VM manager API -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides common VM manager definitions that need to - be shared by system virtualization layer itself and modules that - implement the actual VM manager types. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VMM_IMPL_H -#define VMM_IMPL_H - -#include "img_types.h" -#include "pvrsrv_error.h" - -typedef enum _VMM_CONF_PARAM_ -{ - VMM_CONF_PRIO_OSID0 = 0, - VMM_CONF_PRIO_OSID1 = 1, - VMM_CONF_PRIO_OSID2 = 2, - VMM_CONF_PRIO_OSID3 = 3, - VMM_CONF_PRIO_OSID4 = 4, - VMM_CONF_PRIO_OSID5 = 5, - VMM_CONF_PRIO_OSID6 = 6, - VMM_CONF_PRIO_OSID7 = 7, - VMM_CONF_HCS_DEADLINE = 8 -} VMM_CONF_PARAM; - -/* - Virtual machine manager (hypervisor) para-virtualization (PVZ) connection: - - Type is implemented by host and guest drivers - - Assumes synchronous function call semantics - - Unidirectional semantics - - For Host (vmm -> host) - - For Guest (guest -> vmm) - - Parameters can be IN/OUT/INOUT - - - Host pvz entries are pre-implemented by IMG - - For host implementation, see vmm_pvz_server.c - - Called by host side hypercall handler or VMM - - - Guest pvz entries are supplied by 3rd-party - - These are specific to hypervisor (VMM) type - - These implement the actual hypercalls mechanism - - Para-virtualization (PVZ) call runtime sequence: - 1 - Guest driver in guest VM calls PVZ function - 1.1 - Guest PVZ connection calls - 1.2 - Guest VM Manager type which - 1.2.1 - Performs any pre-processing like parameter packing, etc. - 1.2.2 - Issues hypercall (blocking synchronous call) - - 2 - VM Manager (hypervisor) receives hypercall - 2.1 - Hypercall handler: - 2.1.1 - Performs any pre-processing - 2.1.2 - If call terminates in VM Manager: perform action and return from hypercall - 2.1.3 - Otherwise forward to host driver (implementation specific call) - - 3 - Host driver receives call from VM Manager - 3.1 - Host VM manager type: - 3.1.1 - Performs any pre-processing like parameter unpacking, etc. - 3.1.2 - Acquires host driver PVZ handler and calls the appropriate entry - 3.2 - Host PVZ connection calls corresponding host system virtualisation layer - 3.3 - Host driver system virtualisation layer: - 3.3.1 - Perform action requested by guest driver - 3.3.2 - Return to host VM Manager type - 3.4 - Host VM Manager type: - 3.4.1 - Prepare to return from hypercall - 3.4.2 - Perform any post-processing like result packing, etc. - 3.4.3 - Issue return from hypercall - - 4 - VM Manager (hypervisor) - 4.1 - Perform any post-processing - 4.2 - Return control to guest driver - - 5 - Guest driver in guest VM - 5.1 - Perform any post-processing like parameter unpacking, etc. - 5.2 - Continue execution in guest VM - */ -typedef struct _VMM_PVZ_CONNECTION_ -{ - struct { - /* - This pair must be implemented if the guest is responsible - for allocating the physical heap that backs its firmware - allocations, this is the default configuration. The physical - heap is allocated within the guest VM IPA space and this - IPA Addr/Size must be translated into the host's IPA space - by the VM manager before forwarding request to host. - If not implemented, return PVRSRV_ERROR_NOT_IMPLEMENTED. - */ - PVRSRV_ERROR (*pfnMapDevPhysHeap)(IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64PAddr); - - PVRSRV_ERROR (*pfnUnmapDevPhysHeap)(IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID); - } sClientFuncTab; - - struct { - /* - Corresponding server side entries to handle guest PVZ calls - NOTE: - - Additional PVZ function ui32OSID parameter - - OSID determination is responsibility of VM manager - - Actual OSID value must be supplied by VM manager - - This can be done either in client/VMM/host side - - Must be done before host pvz function(s) are called - - Host pvz function validates incoming OSID values - */ - PVRSRV_ERROR (*pfnMapDevPhysHeap)(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64PAddr); - - PVRSRV_ERROR (*pfnUnmapDevPhysHeap)(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID); - } sServerFuncTab; - - struct { - /* - This is used by the VM manager to report pertinent runtime guest VM - information to the host; these events may in turn be forwarded to - the firmware - */ - PVRSRV_ERROR (*pfnOnVmOnline)(IMG_UINT32 ui32OSID); - - PVRSRV_ERROR (*pfnOnVmOffline)(IMG_UINT32 ui32OSID); - - PVRSRV_ERROR (*pfnVMMConfigure)(VMM_CONF_PARAM eVMMParamType, IMG_UINT32 ui32ParamValue); - - } sVmmFuncTab; -} VMM_PVZ_CONNECTION; - -/*! -******************************************************************************* - @Function VMMCreatePvzConnection() and VMMDestroyPvzConnection() - @Description Both the guest and VM manager call this in order to obtain a - PVZ connection to the VM and host respectively; that is, guest - calls it to obtain connection to VM, VM calls it to obtain a - connection to the host. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR VMMCreatePvzConnection(VMM_PVZ_CONNECTION **psPvzConnection); -void VMMDestroyPvzConnection(VMM_PVZ_CONNECTION *psPvzConnection); - -#endif /* VMM_IMPL_H */ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.c b/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.c deleted file mode 100644 index 427811a7b3a5a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_pvz_client.c -@Title VM manager client para-virtualization -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header provides VMM client para-virtualization APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" - -#include "vmm_impl.h" -#include "vz_vmm_pvz.h" -#include "vmm_pvz_client.h" - - -static inline void -PvzClientLockAcquire(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - OSLockAcquire(psPVRSRVData->hPvzConnectionLock); -} - -static inline void -PvzClientLockRelease(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - OSLockRelease(psPVRSRVData->hPvzConnectionLock); -} - -/* - * =========================================================== - * The following client para-virtualization (pvz) functions - * are exclusively called by guests to initiate a pvz call - * to the host via hypervisor (guest -> vm manager -> host) - * =========================================================== - */ - -PVRSRV_ERROR -PvzClientMapDevPhysHeap(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_ERROR eError; - IMG_DEV_PHYADDR sDevPAddr; - VMM_PVZ_CONNECTION *psVmmPvz; - IMG_UINT32 uiFuncID = PVZ_BRIDGE_MAPDEVICEPHYSHEAP; - PHYS_HEAP *psFwPhysHeap = psDevConfig->psDevNode->apsPhysHeap[PVRSRV_PHYS_HEAP_FW_MAIN]; - - eError = PhysHeapGetDevPAddr(psFwPhysHeap, &sDevPAddr); - -#if defined(PVR_PMR_TRANSLATE_UMA_ADDRESSES) -{ - /* Host expects PA rather than IPA address, so on the platforms where - * IPA-PA translation is not done in hw, performs a software translation */ - - IMG_DEV_PHYADDR sDevPAddrTranslated; - - PhysHeapCpuPAddrToDevPAddr(psFwPhysHeap, 1, &sDevPAddrTranslated, (IMG_CPU_PHYADDR *)&sDevPAddr); - sDevPAddr.uiAddr = sDevPAddrTranslated.uiAddr; -} -#endif - - PVR_LOG_RETURN_IF_ERROR(eError, "PhysHeapGetDevPAddr"); - PVR_LOG_RETURN_IF_FALSE((sDevPAddr.uiAddr != 0), "PhysHeapGetDevPAddr", PVRSRV_ERROR_INVALID_PARAMS); - - psVmmPvz = PvzConnectionAcquire(); - PvzClientLockAcquire(); - - eError = psVmmPvz->sClientFuncTab.pfnMapDevPhysHeap(uiFuncID, - 0, - RGX_FIRMWARE_RAW_HEAP_SIZE, - sDevPAddr.uiAddr); - - PvzClientLockRelease(); - PvzConnectionRelease(psVmmPvz); - - return eError; -} - -PVRSRV_ERROR -PvzClientUnmapDevPhysHeap(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_ERROR eError; - IMG_UINT32 uiFuncID = PVZ_BRIDGE_UNMAPDEVICEPHYSHEAP; - VMM_PVZ_CONNECTION *psVmmPvz = PvzConnectionAcquire(); - PVR_ASSERT(psVmmPvz); - - PvzClientLockAcquire(); - - PVR_ASSERT(psVmmPvz->sClientFuncTab.pfnUnmapDevPhysHeap); - - eError = psVmmPvz->sClientFuncTab.pfnUnmapDevPhysHeap(uiFuncID, 0); - - PvzClientLockRelease(); - PvzConnectionRelease(psVmmPvz); - - return eError; -} - -/****************************************************************************** - End of file (vmm_pvz_client.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.h b/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.h deleted file mode 100644 index 688e9f36c98cf..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_client.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_pvz_client.h -@Title Guest VM manager client para-virtualization routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header provides guest VMM client para-virtualization APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VMM_PVZ_CLIENT_H -#define VMM_PVZ_CLIENT_H - -#include "pvrsrv.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "vmm_pvz_common.h" -#include "vmm_impl.h" - -/*! -******************************************************************************* - @Function PvzClientMapDevPhysHeap - @Description The guest front-end to initiate a pfnMapDevPhysHeap PVZ call - to the host. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzClientMapDevPhysHeap(PVRSRV_DEVICE_CONFIG *psDevConfig); - -/*! -******************************************************************************* - @Function PvzClientUnmapDevPhysHeap - @Description The guest front-end to initiate a pfnUnmapDevPhysHeap PVZ call - to the host. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzClientUnmapDevPhysHeap(PVRSRV_DEVICE_CONFIG *psDevConfig); - -#endif /* VMM_PVZ_CLIENT_H */ - -/****************************************************************************** - End of file (vmm_pvz_client.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_common.h b/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_common.h deleted file mode 100644 index 82ab50d6fa30a..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_common.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_pvz_common.h -@Title Common VM manager function IDs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header provides VM manager para-virtualization function IDs and - definitions of their payload structures, if appropriate. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VMM_PVZ_COMMON_H -#define VMM_PVZ_COMMON_H - -#include "img_types.h" - -#define PVZ_BRIDGE_DEFAULT 0UL -#define PVZ_BRIDGE_MAPDEVICEPHYSHEAP (PVZ_BRIDGE_DEFAULT + 1) -#define PVZ_BRIDGE_UNMAPDEVICEPHYSHEAP (PVZ_BRIDGE_MAPDEVICEPHYSHEAP + 1) -#define PVZ_BRIDGE_LAST (PVZ_BRIDGE_UNMAPDEVICEPHYSHEAP + 1) - -typedef struct _PVZ_BRIDGEPARA_MAPDEVICEPHYSHEAP -{ - IMG_UINT64 ui64MemBase; - IMG_UINT32 ui32OSID; -}PVZ_BRIDGEPARA_MAPDEVICEPHYSHEAP; - -#endif /* VMM_PVZ_COMMON_H */ - -/***************************************************************************** - End of file (vmm_pvz_common.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.c b/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.c deleted file mode 100644 index f2c77e86cc3a4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.c +++ /dev/null @@ -1,245 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_pvz_server.c -@Title VM manager server para-virtualization handlers -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header provides VMM server para-virtz handler APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "rgxfwutils.h" - -#include "vz_vm.h" -#include "vmm_impl.h" -#include "vz_vmm_pvz.h" -#include "vmm_pvz_server.h" - -static inline void -PvzServerLockAcquire(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - OSLockAcquire(psPVRSRVData->hPvzConnectionLock); -} - -static inline void -PvzServerLockRelease(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - OSLockRelease(psPVRSRVData->hPvzConnectionLock); -} - - -/* - * =========================================================== - * The following server para-virtualization (pvz) functions - * are exclusively called by the VM manager (hypervisor) on - * behalf of guests to complete guest pvz calls - * (guest -> vm manager -> host) - * =========================================================== - */ - -PVRSRV_ERROR -PvzServerMapDevPhysHeap(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64PAddr) -{ -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - /* - * Reject hypercall if called on a system configured at build time to - * preallocate the Guest's firmware heaps from static carveout memory. - */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Host PVZ config: Does not match with Guest PVZ config\n" - " Host preallocates the Guest's FW physheap from static memory carveouts at startup.\n", __func__)); - return PVRSRV_ERROR_INVALID_PVZ_CONFIG; -#else - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_FALSE((ui32DevID == 0), "Invalid Device ID", PVRSRV_ERROR_INVALID_PARAMS); - - if (ui32FuncID != PVZ_BRIDGE_MAPDEVICEPHYSHEAP) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Host PVZ call: OSID: %d: Invalid function ID: expected %d, got %d", - __func__, - ui32OSID, - (IMG_UINT32)PVZ_BRIDGE_MAPDEVICEPHYSHEAP, - ui32FuncID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PvzServerLockAcquire(); - -#if defined(SUPPORT_RGX) - if (IsVmOnline(ui32OSID)) - { - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->psDeviceNodeList; - IMG_DEV_PHYADDR sDevPAddr = {ui64PAddr}; - IMG_UINT32 sync; - - eError = RGXFwRawHeapAllocMap(psDeviceNode, ui32OSID, sDevPAddr, ui64Size); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXFwRawHeapAllocMap", e0); - - /* Invalidate MMU cache in preparation for a kick from this Guest */ - eError = psDeviceNode->pfnMMUCacheInvalidateKick(psDeviceNode, &sync); - PVR_LOG_GOTO_IF_ERROR(eError, "MMUCacheInvalidateKick", e0); - - /* Everything is ready for the firmware to start interacting with this OS */ - eError = RGXFWSetFwOsState(psDeviceNode->pvDevice, ui32OSID, RGXFWIF_OS_ONLINE); - } -e0: -#endif /* defined(SUPPORT_RGX) */ - PvzServerLockRelease(); - - return eError; -#endif -} - -PVRSRV_ERROR -PvzServerUnmapDevPhysHeap(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID) -{ -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - /* - * Reject hypercall if called on a system configured at built time to - * preallocate the Guest's firmware heaps from static carveout memory. - */ - PVR_DPF((PVR_DBG_ERROR, - "%s: Host PVZ config: Does not match with Guest PVZ config\n" - " Host preallocates the Guest's FW physheap from static memory carveouts at startup.\n", __func__)); - return PVRSRV_ERROR_INVALID_PVZ_CONFIG; -#else - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_LOG_RETURN_IF_FALSE((ui32DevID == 0), "Invalid Device ID", PVRSRV_ERROR_INVALID_PARAMS); - - if (ui32FuncID != PVZ_BRIDGE_UNMAPDEVICEPHYSHEAP) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: Host PVZ call: OSID: %d: Invalid function ID: expected %d, got %d", - __func__, - ui32OSID, - (IMG_UINT32)PVZ_BRIDGE_UNMAPDEVICEPHYSHEAP, - ui32FuncID)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PvzServerLockAcquire(); - -#if defined(SUPPORT_RGX) - if (IsVmOnline(ui32OSID)) - { - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->psDeviceNodeList; - - /* Order firmware to offload this OS' data and stop accepting commands from it */ - eError = RGXFWSetFwOsState(psDeviceNode->pvDevice, ui32OSID, RGXFWIF_OS_OFFLINE); - PVR_LOG_GOTO_IF_ERROR(eError, "RGXFWSetFwOsState", e0); - - /* it is now safe to remove the Guest's memory mappings */ - RGXFwRawHeapUnmapFree(psDeviceNode, ui32OSID); - } -e0: -#endif - - PvzServerLockRelease(); - - return eError; -#endif -} - -/* - * ============================================================ - * The following server para-virtualization (pvz) functions - * are exclusively called by the VM manager (hypervisor) to - * pass side band information to the host (vm manager -> host) - * ============================================================ - */ - -PVRSRV_ERROR -PvzServerOnVmOnline(IMG_UINT32 ui32OSID) -{ - PVRSRV_ERROR eError; - - PvzServerLockAcquire(); - - eError = PvzOnVmOnline(ui32OSID); - - PvzServerLockRelease(); - - return eError; -} - -PVRSRV_ERROR -PvzServerOnVmOffline(IMG_UINT32 ui32OSID) -{ - PVRSRV_ERROR eError; - - PvzServerLockAcquire(); - - eError = PvzOnVmOffline(ui32OSID); - - PvzServerLockRelease(); - - return eError; -} - -PVRSRV_ERROR -PvzServerVMMConfigure(VMM_CONF_PARAM eVMMParamType, IMG_UINT32 ui32ParamValue) -{ - PVRSRV_ERROR eError; - - PvzServerLockAcquire(); - - eError = PvzVMMConfigure(eVMMParamType, ui32ParamValue); - - PvzServerLockRelease(); - - return eError; -} - -/****************************************************************************** - End of file (vmm_pvz_server.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.h b/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.h deleted file mode 100644 index 58223a0032e90..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_pvz_server.h +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_pvz_server.h -@Title VM manager para-virtualization interface helper routines -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Header provides API(s) available to VM manager, this must be - called to close the loop during guest para-virtualization calls. -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VMM_PVZ_SERVER_H -#define VMM_PVZ_SERVER_H - -#include "vmm_impl.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "vmm_pvz_common.h" - -/*! -******************************************************************************* - @Function PvzServerMapDevPhysHeap - @Description The VM manager calls this in response to guest PVZ interface - call pfnMapDevPhysHeap. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzServerMapDevPhysHeap(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64PAddr); - -/*! -******************************************************************************* - @Function PvzServerUnmapDevPhysHeap - @Description The VM manager calls this in response to guest PVZ interface - call pfnUnmapDevPhysHeap. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzServerUnmapDevPhysHeap(IMG_UINT32 ui32OSID, - IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID); - -/*! -******************************************************************************* - @Function PvzServerOnVmOnline - @Description The VM manager calls this when guest VM machine comes online. - The host driver will initialize the FW if it has not done so - already. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzServerOnVmOnline(IMG_UINT32 ui32OSID); - -/*! -******************************************************************************* - @Function PvzServerOnVmOffline - @Description The VM manager calls this when a guest VM machine is about to - go offline. The VM manager might have unmapped the GPU kick - register for such VM but not the GPU memory until the call - returns. Once the function returns, the FW does not hold any - reference for such VM and no workloads from it are running in - the GPU and it is safe to remove the memory for such VM. - @Return PVRSRV_OK on success. PVRSRV_ERROR_TIMEOUT if for some reason - the FW is taking too long to clean-up the resources of the - OSID. Otherwise, a PVRSRV_ERROR code. -******************************************************************************/ -PVRSRV_ERROR -PvzServerOnVmOffline(IMG_UINT32 ui32OSID); - -/*! -******************************************************************************* - @Function PvzServerVMMConfigure - @Description The VM manager calls this to configure several parameters like - HCS or isolation. - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR -PvzServerVMMConfigure(VMM_CONF_PARAM eVMMParamType, - IMG_UINT32 ui32ParamValue); - -#endif /* VMM_PVZ_SERVER_H */ - -/****************************************************************************** - End of file (vmm_pvz_server.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vmm_type_stub.c b/drivers/gpu/drm/img-rogue/1.17/vmm_type_stub.c deleted file mode 100644 index c8704d6ca38b4..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vmm_type_stub.c +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************/ /*! -@File vmm_type_stub.c -@Title Stub VM manager type -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Sample stub (no-operation) VM manager implementation -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv.h" -#include "img_types.h" -#include "img_defs.h" -#include "pvrsrv_error.h" -#include "rgxheapconfig.h" - -#include "vmm_impl.h" -#include "vmm_pvz_server.h" - -static PVRSRV_ERROR -StubVMMMapDevPhysHeap(IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID, - IMG_UINT64 ui64Size, - IMG_UINT64 ui64Addr) -{ - PVR_UNREFERENCED_PARAMETER(ui32FuncID); - PVR_UNREFERENCED_PARAMETER(ui32DevID); - PVR_UNREFERENCED_PARAMETER(ui64Size); - PVR_UNREFERENCED_PARAMETER(ui64Addr); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -static PVRSRV_ERROR -StubVMMUnmapDevPhysHeap(IMG_UINT32 ui32FuncID, - IMG_UINT32 ui32DevID) -{ - PVR_UNREFERENCED_PARAMETER(ui32FuncID); - PVR_UNREFERENCED_PARAMETER(ui32DevID); - return PVRSRV_ERROR_NOT_IMPLEMENTED; -} - -static VMM_PVZ_CONNECTION gsStubVmmPvz = -{ - .sClientFuncTab = { - .pfnMapDevPhysHeap = &StubVMMMapDevPhysHeap, - .pfnUnmapDevPhysHeap = &StubVMMUnmapDevPhysHeap - }, - - .sServerFuncTab = { - .pfnMapDevPhysHeap = &PvzServerMapDevPhysHeap, - .pfnUnmapDevPhysHeap = &PvzServerUnmapDevPhysHeap - }, - - .sVmmFuncTab = { - .pfnOnVmOnline = &PvzServerOnVmOnline, - .pfnOnVmOffline = &PvzServerOnVmOffline, - .pfnVMMConfigure = &PvzServerVMMConfigure - } -}; - -PVRSRV_ERROR VMMCreatePvzConnection(VMM_PVZ_CONNECTION **psPvzConnection) -{ - PVR_LOG_RETURN_IF_FALSE((NULL != psPvzConnection), "VMMCreatePvzConnection", PVRSRV_ERROR_INVALID_PARAMS); - *psPvzConnection = &gsStubVmmPvz; - PVR_DPF((PVR_DBG_ERROR, "Using a stub VM manager type, no runtime VZ support")); - return PVRSRV_OK; -} - -void VMMDestroyPvzConnection(VMM_PVZ_CONNECTION *psPvzConnection) -{ - PVR_LOG_IF_FALSE((NULL != psPvzConnection), "VMMDestroyPvzConnection"); -} - -/****************************************************************************** - End of file (vmm_type_stub.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vz_vm.h b/drivers/gpu/drm/img-rogue/1.17/vz_vm.h deleted file mode 100644 index 3a8042c7668bd..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vz_vm.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ /*! -@File vz_vm.h -@Title System virtualization VM support APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides VM management support APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VZ_VM_H -#define VZ_VM_H - -#include "vmm_impl.h" - -bool IsVmOnline(IMG_UINT32 ui32OSID); - -PVRSRV_ERROR PvzOnVmOnline(IMG_UINT32 ui32OSid); - -PVRSRV_ERROR PvzOnVmOffline(IMG_UINT32 ui32OSid); - -PVRSRV_ERROR PvzVMMConfigure(VMM_CONF_PARAM eVMMParamType, IMG_UINT32 ui32ParamValue); - -#endif /* VZ_VM_H */ - -/***************************************************************************** - End of file (vz_vm.h) -*****************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.c b/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.c deleted file mode 100644 index 39a52b5fadc02..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.c +++ /dev/null @@ -1,183 +0,0 @@ -/*************************************************************************/ /*! -@File vz_vmm_pvz.c -@Title VM manager para-virtualization APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description VM manager para-virtualization management -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "pvrsrv.h" -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv_error.h" -#include "allocmem.h" -#include "pvrsrv.h" -#include "vz_vmm_pvz.h" - -#if (RGX_NUM_OS_SUPPORTED > 1) -static PVRSRV_ERROR -PvzConnectionValidate(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - VMM_PVZ_CONNECTION *psVmmPvz; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* - * Acquire the underlying VM manager PVZ connection & validate it. - */ - psVmmPvz = PvzConnectionAcquire(); - if (psVmmPvz == NULL) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: %s PVZ config: Unable to acquire PVZ connection", - __func__, PVRSRV_VZ_MODE_IS(GUEST) ? "Guest" : "Host")); - eError = PVRSRV_ERROR_INVALID_PVZ_CONFIG; - goto e0; - } - - /* Log which PVZ setup type is being used by driver */ -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - /* - * Static PVZ bootstrap setup - * - * This setup uses carve-out memory, has no hypercall mechanism & does not support - * out-of-order initialisation of host/guest VMs/drivers. The host driver has all - * the information needed to initialize all OSIDs firmware state when it's loaded - * and its PVZ layer must mark all guest OSIDs as being online as part of its PVZ - * initialisation. Having no out-of-order initialisation support, the guest driver - * can only submit a workload to the device after the host driver has completely - * initialized the firmware, the VZ hypervisor/VM setup must guarantee this. - */ - PVR_LOG(("Using static PVZ bootstrap setup")); -#else - /* - * Dynamic PVZ bootstrap setup - * - * This setup uses guest memory, has PVZ hypercall mechanism & supports out-of-order - * initialisation of host/guest VMs/drivers. The host driver initializes only its - * own OSID-0 firmware state when its loaded and each guest driver will use its PVZ - * interface to hypercall to the host driver to both synchronise its initialisation - * so it does not submit any workload to the firmware before the host driver has - * had a chance to initialize the firmware and to also initialize its own OSID-x - * firmware state. - */ - PVR_LOG(("Using dynamic PVZ bootstrap setup")); - - if (!PVRSRV_VZ_MODE_IS(GUEST) && - (psVmmPvz->sServerFuncTab.pfnMapDevPhysHeap == NULL || - psVmmPvz->sServerFuncTab.pfnUnmapDevPhysHeap == NULL)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Host PVZ config: Functions for mapping a Guest's heaps not implemented\n", __func__)); - eError = PVRSRV_ERROR_INVALID_PVZ_CONFIG; - } -#endif - - PvzConnectionRelease(psVmmPvz); -e0: - return eError; -} -#endif /* (RGX_NUM_OS_SUPPORTED > 1) */ - -PVRSRV_ERROR PvzConnectionInit(PVRSRV_DEVICE_CONFIG *psDevConfig) -{ - PVRSRV_ERROR eError; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - -#if (RGX_NUM_OS_SUPPORTED == 1) -# if !defined(PVRSRV_NEED_PVR_DPF) - PVR_UNREFERENCED_PARAMETER(psPVRSRVData); -# endif - PVR_DPF((PVR_DBG_ERROR, "This kernel driver does not support virtualization. Please rebuild with RGX_NUM_OS_SUPPORTED > 1")); - PVR_DPF((PVR_DBG_ERROR, "Halting initialisation, cannot transition to %s mode", - psPVRSRVData->eDriverMode == DRIVER_MODE_HOST ? "host" : "guest")); - eError = PVRSRV_ERROR_NOT_SUPPORTED; - goto e0; -#else - - /* Create para-virtualization connection lock */ - eError = OSLockCreate(&psPVRSRVData->hPvzConnectionLock); - PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0); - - /* Create VM manager para-virtualization connection */ - eError = VMMCreatePvzConnection((VMM_PVZ_CONNECTION **)&psPVRSRVData->hPvzConnection); - if (eError != PVRSRV_OK) - { - OSLockDestroy(psPVRSRVData->hPvzConnectionLock); - psPVRSRVData->hPvzConnectionLock = NULL; - - PVR_LOG_ERROR(eError, "VMMCreatePvzConnection"); - goto e0; - } - - /* Ensure pvz connection is configured correctly */ - eError = PvzConnectionValidate(psDevConfig); - PVR_LOG_RETURN_IF_ERROR(eError, "PvzConnectionValidate"); - - psPVRSRVData->abVmOnline[RGXFW_HOST_OS] = IMG_TRUE; -#endif -e0: - return eError; -} - -void PvzConnectionDeInit(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - VMMDestroyPvzConnection(psPVRSRVData->hPvzConnection); - psPVRSRVData->hPvzConnection = NULL; - - OSLockDestroy(psPVRSRVData->hPvzConnectionLock); - psPVRSRVData->hPvzConnectionLock = NULL; -} - -VMM_PVZ_CONNECTION* PvzConnectionAcquire(void) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVR_ASSERT(psPVRSRVData->hPvzConnection != NULL); - return psPVRSRVData->hPvzConnection; -} - -void PvzConnectionRelease(VMM_PVZ_CONNECTION *psParaVz) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - /* Nothing to do, just validate the pointer we're passed back */ - PVR_ASSERT(psParaVz == psPVRSRVData->hPvzConnection); -} - -/****************************************************************************** - End of file (vz_vmm_pvz.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.h b/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.h deleted file mode 100644 index abc6470ebd9cd..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_pvz.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************/ /*! -@File vz_vmm_pvz.h -@Title System virtualization VM manager management APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description This header provides VM manager para-virtz management APIs -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 VZ_VMM_PVZ_H -#define VZ_VMM_PVZ_H - -#include "img_types.h" -#include "vmm_impl.h" - -/*! -******************************************************************************* - @Function PvzConnectionInit() and PvzConnectionDeInit() - @Description PvzConnectionInit initializes the VM manager para-virt - which is used subsequently for communication between guest and - host; depending on the underlying VM setup, this could either - be a hyper-call or cross-VM call - @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code -******************************************************************************/ -PVRSRV_ERROR PvzConnectionInit(PVRSRV_DEVICE_CONFIG *psDevConfig); -void PvzConnectionDeInit(void); - -/*! -******************************************************************************* - @Function PvzConnectionAcquire() and PvzConnectionRelease() - @Description These are to acquire/release a handle to the VM manager - para-virtz connection to make a pvz call; on the client, use it - it to make the actual pvz call and on the server handler / - VM manager, use it to complete the processing for the pvz call - or make a VM manager to host pvzbridge call -@Return VMM_PVZ_CONNECTION* on success. Otherwise NULL -******************************************************************************/ -VMM_PVZ_CONNECTION* PvzConnectionAcquire(void); -void PvzConnectionRelease(VMM_PVZ_CONNECTION *psPvzConnection); - -#endif /* VZ_VMM_PVZ_H */ - -/****************************************************************************** - End of file (vz_vmm_pvz.h) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_vm.c b/drivers/gpu/drm/img-rogue/1.17/vz_vmm_vm.c deleted file mode 100644 index 488c8b48a35c9..0000000000000 --- a/drivers/gpu/drm/img-rogue/1.17/vz_vmm_vm.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************/ /*! -@File vz_vmm_vm.c -@Title System virtualization VM support APIs -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description System virtualization VM support functions -@License Dual MIT/GPLv2 - -The contents of this file are subject to the MIT license as set out below. - -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. - -Alternatively, the contents of this file may be used under the terms of -the GNU General Public License Version 2 ("GPL") in which case the provisions -of GPL are applicable instead of those above. - -If you wish to allow use of your version of this file only under the terms of -GPL, and not to allow others to use your version of this file under the terms -of the MIT license, indicate your decision by deleting the provisions above -and replace them with the notice and other provisions required by GPL as set -out in the file called "GPL-COPYING" included in this distribution. If you do -not delete the provisions above, a recipient may use your version of this file -under the terms of either the MIT license or GPL. - -This License is also included in this distribution in the file called -"MIT-COPYING". - -EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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 "osfunc.h" -#include "pvrsrv.h" -#include "img_defs.h" -#include "img_types.h" -#include "pvrsrv.h" -#include "pvrsrv_error.h" -#include "vz_vm.h" -#include "rgxfwutils.h" - -bool IsVmOnline(IMG_UINT32 ui32OSID) -{ - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - - return (ui32OSID >= RGX_NUM_OS_SUPPORTED) ? (false) : (psPVRSRVData->abVmOnline[ui32OSID]); -} - -PVRSRV_ERROR PvzOnVmOnline(IMG_UINT32 ui32OSid) -{ -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED == 1) - PVRSRV_ERROR eError = PVRSRV_ERROR_INVALID_PARAMS; -#else - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDevNode; - - if (ui32OSid == 0 || ui32OSid >= RGX_NUM_OS_SUPPORTED) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: invalid OSID (%d)", - __func__, ui32OSid)); - - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - if (psPVRSRVData->abVmOnline[ui32OSid]) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OSID %d is already enabled.", - __func__, ui32OSid)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - /* For now, limit support to single device setups */ - psDevNode = psPVRSRVData->psDeviceNodeList; - - if (psDevNode->eDevState == PVRSRV_DEVICE_STATE_INIT) - { - - /* Firmware not initialized yet, do it here */ - eError = PVRSRVCommonDeviceInitialise(psDevNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: failed to initialize firmware (%s)", - __func__, PVRSRVGetErrorString(eError))); - goto e0; - } - } - - eError = RGXFWHealthCheckCmd(psDevNode->pvDevice); - if (eError != PVRSRV_OK) - { - goto e0; - } - - psPVRSRVData->abVmOnline[ui32OSid] = IMG_TRUE; - -#if defined(RGX_VZ_STATIC_CARVEOUT_FW_HEAPS) - /* Everything is ready for the firmware to start interacting with this OS */ - eError = RGXFWSetFwOsState(psDevNode->pvDevice, ui32OSid, RGXFWIF_OS_ONLINE); -#endif - -e0: -#endif - return eError; -} - -PVRSRV_ERROR PvzOnVmOffline(IMG_UINT32 ui32OSid) -{ -#if defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED == 1) - PVRSRV_ERROR eError = PVRSRV_ERROR_INVALID_PARAMS; -#else - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDevNode; - PVRSRV_RGXDEV_INFO *psDevInfo; - - if (ui32OSid == 0 || ui32OSid >= RGX_NUM_OS_SUPPORTED) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: invalid OSID (%d)", - __func__, ui32OSid)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - if (!psPVRSRVData->abVmOnline[ui32OSid]) - { - PVR_DPF((PVR_DBG_ERROR, - "%s: OSID %d is already disabled.", - __func__, ui32OSid)); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto e0; - } - - /* For now, limit support to single device setups */ - psDevNode = psPVRSRVData->psDeviceNodeList; - psDevInfo = psDevNode->pvDevice; - - eError = RGXFWSetFwOsState(psDevInfo, ui32OSid, RGXFWIF_OS_OFFLINE); - if (eError == PVRSRV_OK) - { - psPVRSRVData->abVmOnline[ui32OSid] = IMG_FALSE; - } - -e0: -#endif - return eError; -} - -PVRSRV_ERROR PvzVMMConfigure(VMM_CONF_PARAM eVMMParamType, IMG_UINT32 ui32ParamValue) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_RGXDEV_INFO *psDevInfo; - - psDeviceNode = psPVRSRVData->psDeviceNodeList; - psDevInfo = psDeviceNode->pvDevice; - - switch (eVMMParamType) - { -#if defined(SUPPORT_RGX) - case VMM_CONF_PRIO_OSID0: - case VMM_CONF_PRIO_OSID1: - case VMM_CONF_PRIO_OSID2: - case VMM_CONF_PRIO_OSID3: - case VMM_CONF_PRIO_OSID4: - case VMM_CONF_PRIO_OSID5: - case VMM_CONF_PRIO_OSID6: - case VMM_CONF_PRIO_OSID7: - { - IMG_UINT32 ui32OSid = eVMMParamType; - IMG_UINT32 ui32Prio = ui32ParamValue; - - if (ui32OSid < RGX_NUM_OS_SUPPORTED) - { - eError = RGXFWChangeOSidPriority(psDevInfo, ui32OSid, ui32Prio); - } - else - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - break; - } - case VMM_CONF_HCS_DEADLINE: - { - IMG_UINT32 ui32HCSDeadline = ui32ParamValue; - eError = RGXFWSetHCSDeadline(psDevInfo, ui32HCSDeadline); - break; - } -#else - PVR_UNREFERENCED_PARAMETER(ui32ParamValue); -#endif - default: - { - eError = PVRSRV_ERROR_INVALID_PARAMS; - } - } - - return eError; -} - -/****************************************************************************** - End of file (vz_vmm_vm.c) -******************************************************************************/ diff --git a/drivers/gpu/drm/img-rogue/Kconfig b/drivers/gpu/drm/img-rogue/Kconfig deleted file mode 100644 index 9a307f63595d3..0000000000000 --- a/drivers/gpu/drm/img-rogue/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -config DRM_POWERVR_ROGUE_1_17 - tristate "PowerVR Rogue" - depends on ARM64 - depends on HAS_IOMEM - depends on DRM - depends on SYNC_FILE - depends on DRM_KMS_HELPER - depends on PM_DEVFREQ - depends on DEVFREQ_GOV_SIMPLE_ONDEMAND - depends on PM_OPP - depends on DEVFREQ_THERMAL - help - Driver for PowerVR Rogue graphics hardware 1.17. - - Say Y here if your SoC contains a PowerVR Rogue GPU. For more - information, see . - -config DRM_POWERVR_ROGUE_DEBUG - bool "Enable PowerVR Rogue debug features" - depends on DRM_POWERVR_ROGUE_1_17 - default n - help - Add additional debug features to the PowerVR Rogue driver. - -config DRM_POWERVR_ROGUE_PDUMP - bool "Enable PowerVR Rogue PDUMP tracing." - depends on DRM_POWERVR_ROGUE_1_17 - default n - help - Enable PDUMP. -- GitLab From fe65b6ae6b93bdaccac972ddd878c3187b219c98 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 25 Sep 2024 09:38:58 +0800 Subject: [PATCH 331/456] BACKPORT: wifi: rtw89: pci: consolidate PCI basic configurations for probe and resume The PCI settings aren't always persistent after chip suspends, so reconfigure the settings after chip resumes. Since most of these settings are the same, consolidate them into a function to avoid missing somewhere. Fix the missing case of 8922AE resume flow. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925013901.9835-2-pkshih@realtek.com (cherry picked from commit 1a82680839ee86f50ace41b6375ecee0c9320b12) Conflicts: drivers/net/wireless/realtek/rtw89/pci.h (contextual conflicts) drivers/net/wireless/realtek/rtw89/pci_be.c (Unmerged path) drivers/net/wireless/realtek/rtw89/pci.c To simplify CL, not pick CL to implement two functions rtw89_pci_cfg_dac() and rtw89_pci_disable_eq(), which the former one can affect DMA behavior and the latter one is only used by RTL8852CE. Then, not add callings of these two functions to rtw89_pci_basic_cfg(). BUG=b:383048153, b:384385085 TEST=verify suite:wifi_matfunc and suite:wifi_perf Change-Id: Ib461a1b3ce3792edd33ba95c31feb5a97416722b Signed-off-by: Zong-Zhe Yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6156202 Tested-by: Tim Lee Reviewed-by: David Ruth Reviewed-by: Ruth Mekonnen Commit-Queue: Edward Dai Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/pci.c | 16 ++++++++++------ drivers/net/wireless/realtek/rtw89/pci.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 98af64444d3eb..0fe20c07c9c35 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3762,6 +3762,13 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) RTW89_PCIE_BIT_CFG_RST_MSTATE); } +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume) +{ + rtw89_pci_filter_out(rtwdev); + rtw89_pci_link_cfg(rtwdev); + rtw89_pci_l1ss_cfg(rtwdev); +} + static int __maybe_unused rtw89_pci_resume(struct device *dev) { struct ieee80211_hw *hw = dev_get_drvdata(dev); @@ -3783,9 +3790,8 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev) B_AX_SEL_REQ_ENTR_L1); } rtw89_pci_l2_hci_ldo(rtwdev); - rtw89_pci_filter_out(rtwdev); - rtw89_pci_link_cfg(rtwdev); - rtw89_pci_l1ss_cfg(rtwdev); + + rtw89_pci_basic_cfg(rtwdev, true); return 0; } @@ -3885,9 +3891,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_clear_resource; } - rtw89_pci_filter_out(rtwdev); - rtw89_pci_link_cfg(rtwdev); - rtw89_pci_l1ss_cfg(rtwdev); + rtw89_pci_basic_cfg(rtwdev, false); rtw89_core_napi_init(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 4259b79b138fb..1d306193aa442 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -1066,6 +1066,7 @@ struct pci_device_id; int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtw89_pci_remove(struct pci_dev *pdev); +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume); int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en); int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en); u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev, -- GitLab From fc18e11a7a18d6a4043fdb83c596c77842d343f5 Mon Sep 17 00:00:00 2001 From: Linux Patches Robot Date: Sun, 29 Sep 2024 01:45:09 +0000 Subject: [PATCH 332/456] UPSTREAM: drm/i915/dp: Fix AUX IO power enabling for eDP PSR Panel Self Refresh on eDP requires the AUX IO power to be enabled whenever the output (main link) is enabled. This is required by the AUX_PHY_WAKE/ML_PHY_LOCK signaling initiated by the HW automatically to re-enable the main link after it got disabled in power saving states (see eDP v1.4b, sections 5.1, 6.1.3.3.1.1). The Panel Replay mode on non-eDP outputs on the other hand is only supported by keeping the main link active, thus not requiring the above AUX_PHY_WAKE/ML_PHY_LOCK signaling (eDP v1.4b, section 6.1.3.3.1.2). Thus enabling the AUX IO power for this case is not required either. Based on the above enable the AUX IO power only for eDP/PSR outputs. Bspec: 49274, 53370 v2: - Add a TODO comment to adjust the requirement for AUX IO based on whether the ALPM/main-link off mode gets enabled. (Rodrigo) Cc: Animesh Manna Fixes: b8cf5b5d266e ("drm/i915/panelreplay: Initializaton and compute config for panel replay") Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240910111847.2995725-1-imre.deak@intel.com (cherry picked from commit f7c2ed9d4ce80a2570c492825de239dc8b500f2e) Signed-off-by: Joonas Lahtinen (cherry picked from commit ec2231b8dd2dc515912ff7816c420153b4a95e92) BUG=b:308455498 TEST=Verify Asus PG32UQXR 4K160 mode on Rex using Big Joiner Signed-off-by: Linux Patches Robot Change-Id: I1f33a14fb12d27983066702a5e810dc9ec9d1115 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5896761 Reviewed-by: Tzung-Bi Shih Reviewed-by: Drew Davenport Commit-Queue: Tzung-Bi Shih Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_psr.h | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 5aca8a7fd93c7..9ae7a9d9806f0 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -909,7 +909,7 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, * instead of a specific AUX_IO_ reference without powering up any * extra wells. */ - if (intel_encoder_can_psr(&dig_port->base)) + if (intel_psr_needs_aux_io_power(&dig_port->base, crtc_state)) return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); else if (DISPLAY_VER(i915) < 14 && (intel_crtc_has_dp_encoder(crtc_state) || diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ca7949b210901..b73ef782b36df 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -181,6 +181,25 @@ bool intel_encoder_can_psr(struct intel_encoder *encoder) return false; } +bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + /* + * For PSR/PR modes only eDP requires the AUX IO power to be enabled whenever + * the output is enabled. For non-eDP outputs the main link is always + * on, hence it doesn't require the HW initiated AUX wake-up signaling used + * for eDP. + * + * TODO: + * - Consider leaving AUX IO disabled for eDP / PR as well, in case + * the ALPM with main-link off mode is not enabled. + * - Leave AUX IO enabled for DP / PR, once support for ALPM with + * main-link off mode is added for it and this mode gets enabled. + */ + return intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && + intel_encoder_can_psr(encoder); +} + static bool psr_global_enabled(struct intel_dp *intel_dp) { struct intel_connector *connector = intel_dp->attached_connector; diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index d7e69bad36cee..a8ba41873a484 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -28,6 +28,8 @@ struct intel_plane_state; (intel_dp)->psr.source_panel_replay_support) bool intel_encoder_can_psr(struct intel_encoder *encoder); +bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc); -- GitLab From 4629df2b485fbe0da6c65cfde0049c80a81e717f Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 9 Jan 2025 14:28:53 -0800 Subject: [PATCH 333/456] FROMGIT: drm/panel-edp: Add Starry 116KHD024006 We have a few reports of sc7180-trogdor-pompom devices that have a panel in them that IDs as STA 0x0004 and has the following raw EDID: 00 ff ff ff ff ff ff 00 4e 81 04 00 00 00 00 00 10 20 01 04 a5 1a 0e 78 0a dc dd 96 5b 5b 91 28 1f 52 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 8e 1c 56 a0 50 00 1e 30 28 20 55 00 00 90 10 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe 00 31 31 36 4b 48 44 30 32 34 30 30 36 0a 00 e6 We've been unable to locate a datasheet for this panel and our partner has not been responsive, but all Starry eDP datasheets that we can find agree on the same timing (delay_100_500_e200) so it should be safe to use that here instead of the super conservative timings. We'll still go a little extra conservative and allow `hpd_absent` of 200 instead of 100 because that won't add any real-world delay in most cases. We'll associate the string from the EDID ("116KHD024006") with this panel. Given that the ID is the suspicious value of 0x0004 it seems likely that Starry doesn't always update their IDs but the string will still work to differentiate if we ever need to in the future. Reviewed-by: Neil Armstrong Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20250109142853.1.Ibcc3009933fd19507cc9c713ad0c99c7a9e4fe17@changeid (cherry picked from commit 749b5b279e5636cdcef51e15d67b77162cca6caa https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-next) BUG=b:308212153 TEST=Build and boot Change-Id: Ibcc3009933fd19507cc9c713ad0c99c7a9e4fe17 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6172929 Commit-Queue: Douglas Anderson Tested-by: Douglas Anderson Reviewed-by: Sean Paul Commit-Queue: Stephen Boyd Auto-Submit: Douglas Anderson Reviewed-by: Stephen Boyd Signed-off-by: Hubert Mazur --- drivers/gpu/drm/panel/panel-edp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index eb314ae6ff029..c7f243871b621 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -2133,6 +2133,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('S', 'H', 'P', 0x153a, &delay_200_500_e50, "LQ140T1JH01"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"), + EDP_PANEL_ENTRY('S', 'T', 'A', 0x0004, &delay_200_500_e200, "116KHD024006"), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"), { /* sentinal */ } -- GitLab From ae32e0c18c4a9282f9a2fef1a8e8394c8d39709e Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Wed, 25 Dec 2024 20:28:04 +0800 Subject: [PATCH 334/456] BACKPORT: FROMGIT: wifi: rtw89: pci: disable PCI completion timeout control Realtek's chips follow suggestion of PCIe spec to design the max timeout of PCI completion, but some PCIe host reply too slow to meet it and lead PCI AER. Disable PCI completion timeout function via PCI configuration to avoid the AER. Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241225122804.10214-1-pkshih@realtek.com (cherry picked from commit f69ccbc50a12417c74ddf891d3958ddf609f171c https://github.com/pkshih/rtw.git rtw-next) Conflicts: drivers/net/wireless/realtek/rtw89/pci.c (contextual conflicts) BUG=b:383048153, b:384385085 TEST=verify suite:wifi_matfunc and suite:wifi_perf Change-Id: I5c5419546dd09c576ed18895ad3b21fa81ecfc82 Signed-off-by: Zong-Zhe Yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6155337 Reviewed-by: Edward Dai Reviewed-by: David Ruth Commit-Queue: David Ruth Tested-by: Tim Lee Reviewed-by: Ruth Mekonnen Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 0fe20c07c9c35..d979497a1dbef 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3584,6 +3584,15 @@ static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) rtw89_pci_l1ss_set(rtwdev, true); } +static void rtw89_pci_cpl_timeout_cfg(struct rtw89_dev *rtwdev) +{ + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + + pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_COMP_TMOUT_DIS); +} + static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev) { int ret = 0; @@ -3765,6 +3774,7 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume) { rtw89_pci_filter_out(rtwdev); + rtw89_pci_cpl_timeout_cfg(rtwdev); rtw89_pci_link_cfg(rtwdev); rtw89_pci_l1ss_cfg(rtwdev); } -- GitLab From 2f9078a293e35316d92bd2d3550a29eaf117ac68 Mon Sep 17 00:00:00 2001 From: Guangjie Song Date: Thu, 15 Aug 2024 20:16:06 +0800 Subject: [PATCH 335/456] CHROMIUM: dt-bindings: power: update MT8196 power domain ids Update MT8196 power domain ids BUG=b:383207709 BUG=b:377628718 TEST=build pass and bootup to shell UPSTREAM-TASK=b:379034565 Signed-off-by: Guangjie Song Change-Id: I2f862f96ff25badf76fd5ed662499d27222c5b15 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073995 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- include/dt-bindings/power/mt8196-power.h | 100 +++++++++-------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/include/dt-bindings/power/mt8196-power.h b/include/dt-bindings/power/mt8196-power.h index ee7d76d2a76ff..3739c0914b749 100644 --- a/include/dt-bindings/power/mt8196-power.h +++ b/include/dt-bindings/power/mt8196-power.h @@ -8,71 +8,51 @@ #define _DT_BINDINGS_POWER_MT8196_POWER_H /* SPM */ -#define MT8196_POWER_DOMAIN_MD 0 -#define MT8196_POWER_DOMAIN_CONN 1 -#define MT8196_POWER_DOMAIN_SSUSB_P0 2 -#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0 3 -#define MT8196_POWER_DOMAIN_SSUSB_P1 4 -#define MT8196_POWER_DOMAIN_SSUSB_P23 5 -#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2 6 -#define MT8196_POWER_DOMAIN_PEXTP_MAC0 7 -#define MT8196_POWER_DOMAIN_PEXTP_MAC1 8 -#define MT8196_POWER_DOMAIN_PEXTP_MAC2 9 -#define MT8196_POWER_DOMAIN_PEXTP_PHY0 10 -#define MT8196_POWER_DOMAIN_PEXTP_PHY1 11 -#define MT8196_POWER_DOMAIN_PEXTP_PHY2 12 -#define MT8196_POWER_DOMAIN_ADSP_AO 13 -#define MT8196_POWER_DOMAIN_ADSP_INFRA 14 -#define MT8196_POWER_DOMAIN_AUDIO 15 -#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT 16 -#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 17 -#define MT8196_POWER_DOMAIN_SSR 18 -#define MT8196_POWER_DOMAIN_SPU_ISE 19 -#define MT8196_POWER_DOMAIN_SPU_HWROT 20 -#define MT8196_SPM_POWER_DOMAIN_NR 21 +#define MT8196_POWER_DOMAIN_CONN 0 +#define MT8196_POWER_DOMAIN_SSUSB_P0 1 +#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0 2 +#define MT8196_POWER_DOMAIN_SSUSB_P1 3 +#define MT8196_POWER_DOMAIN_SSUSB_P23 4 +#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2 5 +#define MT8196_POWER_DOMAIN_PEXTP_MAC0 6 +#define MT8196_POWER_DOMAIN_PEXTP_MAC1 7 +#define MT8196_POWER_DOMAIN_PEXTP_MAC2 8 +#define MT8196_POWER_DOMAIN_PEXTP_PHY0 9 +#define MT8196_POWER_DOMAIN_PEXTP_PHY1 10 +#define MT8196_POWER_DOMAIN_PEXTP_PHY2 11 +#define MT8196_POWER_DOMAIN_ADSP_AO 12 +#define MT8196_POWER_DOMAIN_ADSP_INFRA 13 +#define MT8196_POWER_DOMAIN_AUDIO 14 +#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT 15 +#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 16 +#define MT8196_POWER_DOMAIN_SSR 17 +#define MT8196_SPM_POWER_DOMAIN_NR 18 /* MMPC */ #define MT8196_POWER_DOMAIN_MM_INFRA_AO 0 #define MT8196_POWER_DOMAIN_MM_INFRA0 1 #define MT8196_POWER_DOMAIN_MM_INFRA1 2 -#define MT8196_POWER_DOMAIN_ISP_VCORE 3 -#define MT8196_POWER_DOMAIN_ISP_MAIN 4 -#define MT8196_POWER_DOMAIN_ISP_TRAW 5 -#define MT8196_POWER_DOMAIN_ISP_DIP 6 -#define MT8196_POWER_DOMAIN_ISP_WPE_EIS 7 -#define MT8196_POWER_DOMAIN_ISP_WPE_TNR 8 -#define MT8196_POWER_DOMAIN_ISP_WPE_LITE 9 -#define MT8196_POWER_DOMAIN_VDE_VCORE0 10 -#define MT8196_POWER_DOMAIN_VDE0 11 -#define MT8196_POWER_DOMAIN_VDE1 12 -#define MT8196_POWER_DOMAIN_VEN0 13 -#define MT8196_POWER_DOMAIN_VEN1 14 -#define MT8196_POWER_DOMAIN_VEN2 15 -#define MT8196_POWER_DOMAIN_CAM_VCORE 16 -#define MT8196_POWER_DOMAIN_CAM_MAIN 17 -#define MT8196_POWER_DOMAIN_CAM_MRAW 18 -#define MT8196_POWER_DOMAIN_CAM_RAWA 19 -#define MT8196_POWER_DOMAIN_CAM_RAWB 20 -#define MT8196_POWER_DOMAIN_CAM_RAWC 21 -#define MT8196_POWER_DOMAIN_CAM_RMSA 22 -#define MT8196_POWER_DOMAIN_CAM_RMSB 23 -#define MT8196_POWER_DOMAIN_CAM_RMSC 24 -#define MT8196_POWER_DOMAIN_CAM_CCU 25 -#define MT8196_POWER_DOMAIN_DISP_VCORE 26 -#define MT8196_POWER_DOMAIN_DIS0_DORMANT 27 -#define MT8196_POWER_DOMAIN_DIS1_DORMANT 28 -#define MT8196_POWER_DOMAIN_OVL0_DORMANT 29 -#define MT8196_POWER_DOMAIN_OVL1_DORMANT 30 -#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT 31 -#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT 32 -#define MT8196_POWER_DOMAIN_MML0_DORMANT 33 -#define MT8196_POWER_DOMAIN_MML1_DORMANT 34 -#define MT8196_POWER_DOMAIN_CSI_BS_RX 35 -#define MT8196_POWER_DOMAIN_CSI_LS_RX 36 -#define MT8196_POWER_DOMAIN_DSI_PHY0 37 -#define MT8196_POWER_DOMAIN_DSI_PHY1 38 -#define MT8196_POWER_DOMAIN_DSI_PHY2 39 -#define MT8196_MMPC_POWER_DOMAIN_NR 40 +#define MT8196_POWER_DOMAIN_VDE_VCORE0 3 +#define MT8196_POWER_DOMAIN_VDE0 4 +#define MT8196_POWER_DOMAIN_VDE1 5 +#define MT8196_POWER_DOMAIN_VEN0 6 +#define MT8196_POWER_DOMAIN_VEN1 7 +#define MT8196_POWER_DOMAIN_VEN2 8 +#define MT8196_POWER_DOMAIN_DISP_VCORE 9 +#define MT8196_POWER_DOMAIN_DIS0_DORMANT 10 +#define MT8196_POWER_DOMAIN_DIS1_DORMANT 11 +#define MT8196_POWER_DOMAIN_OVL0_DORMANT 12 +#define MT8196_POWER_DOMAIN_OVL1_DORMANT 13 +#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT 14 +#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT 15 +#define MT8196_POWER_DOMAIN_MML0_SHUTDOWN 16 +#define MT8196_POWER_DOMAIN_MML1_SHUTDOWN 17 +#define MT8196_POWER_DOMAIN_CSI_BS_RX 18 +#define MT8196_POWER_DOMAIN_CSI_LS_RX 19 +#define MT8196_POWER_DOMAIN_DSI_PHY0 20 +#define MT8196_POWER_DOMAIN_DSI_PHY1 21 +#define MT8196_POWER_DOMAIN_DSI_PHY2 22 +#define MT8196_MMPC_POWER_DOMAIN_NR 23 #endif /* _DT_BINDINGS_POWER_MT8196_POWER_H */ -- GitLab From a767d4cc12a1aeda256d2f8c0a71bf8e803dbe6c Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Thu, 19 Sep 2024 16:17:13 +0800 Subject: [PATCH 336/456] FROMGIT: wifi: mt76: mt792x: add P2P_DEVICE support Regist the NL80211_IFTYPE_P2P_DEVICE to support p2p device for mt792x chips Signed-off-by: Hao Zhang Signed-off-by: allan.wang Signed-off-by: Ming Yen Hsieh Link: https://patch.msgid.link/20240919081713.23787-1-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau (cherry picked from commit 4efded4dbcd417edd3ea9a3e1da8dc51a3ec1fae https://github.com/nbd168/wireless mt76) BUG=b:283689711, b:178754244 TEST=Verified on Nissa Cq-Depend: chromium:6156637 Change-Id: If1d6d093cf10e7c11f5cb3ce5484b737740caff9 Signed-off-by: Leon Yen Signed-off-by: Arowa Suliman Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6156636 Reviewed-by: Jintao Lin Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt792x_core.c | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 769ddee49386b..7dc951cbc84e0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -1196,6 +1196,9 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, case NL80211_IFTYPE_STATION: basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA); break; + case NL80211_IFTYPE_P2P_DEVICE: + basic_req.basic.conn_type = cpu_to_le32(CONNECTION_P2P_GO); + break; case NL80211_IFTYPE_ADHOC: basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); break; diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c index 160431a425813..59943c4631211 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -38,6 +38,10 @@ static const struct ieee80211_iface_limit if_limits_chanctx[] = { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO) + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE) } }; @@ -45,7 +49,7 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = { { .limits = if_limits_chanctx, .n_limits = ARRAY_SIZE(if_limits_chanctx), - .max_interfaces = 2, + .max_interfaces = 3, .num_different_channels = 2, .beacon_int_infra_match = false, } @@ -614,7 +618,8 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); wiphy->max_remain_on_channel_duration = 5000; wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; wiphy->max_scan_ssids = 4; -- GitLab From f6469a476966a9bbb2ee78f15df03167cdaabe40 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 16 Oct 2024 18:10:17 +0800 Subject: [PATCH 337/456] FROMGIT: wifi: mt76: introduce mt792x_config_mac_addr_list routine Add mt792x_config_mac_addr_list routine in order to set the mac address list supported by the driver. Initialize wiphy->addresses/n_addresses for mt792x driver Signed-off-by: Hao Zhang Signed-off-by: Leon Yen Signed-off-by: Allan Wang Link: https://patch.msgid.link/20241016101017.19598-1-allan.wang@mediatek.com Signed-off-by: Felix Fietkau (cherry picked from commit a85551b9e0263a2c0bd0b10ad6896e361fb716b9 https://github.com/nbd168/wireless mt76) BUG=b:283689711, b:178754244 TEST=Verified on Nissa Change-Id: Iceb1a30b6c14b7b8dcfbe4c2df6a8a2d12e91a15 Signed-off-by: Leon Yen Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6156637 Reviewed-by: Sean Paul Reviewed-by: Jintao Lin Tested-by: Arowa Suliman Reviewed-by: Arowa Suliman Commit-Queue: Arowa Suliman Signed-off-by: Hubert Mazur --- .../net/wireless/mediatek/mt76/mt7921/init.c | 1 + .../net/wireless/mediatek/mt76/mt7925/init.c | 1 + drivers/net/wireless/mediatek/mt76/mt792x.h | 3 +++ .../net/wireless/mediatek/mt76/mt792x_core.c | 22 +++++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index d48b83282d63f..14e17dc902566 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -234,6 +234,7 @@ static void mt7921_init_work(struct work_struct *work) mt76_set_stream_caps(&dev->mphy, true); mt7921_set_stream_he_caps(&dev->phy); + mt792x_config_mac_addr_list(dev); ret = mt76_register_device(&dev->mt76, true, mt76_rates, ARRAY_SIZE(mt76_rates)); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index 77d07dc85ea66..f41ca42484978 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -200,6 +200,7 @@ static void mt7925_init_work(struct work_struct *work) mt76_set_stream_caps(&dev->mphy, true); mt7925_set_stream_he_eht_caps(&dev->phy); + mt792x_config_mac_addr_list(dev); ret = mt7925_init_mlo_caps(&dev->phy); if (ret) { diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index d91d67c597112..737aad8001282 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -204,6 +204,8 @@ struct mt792x_dev { struct mt76_phy mphy; }; + struct mac_address macaddr_list[8]; + const struct mt76_bus_ops *bus_ops; struct mt792x_phy phy; @@ -416,6 +418,7 @@ int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev); void mt792x_mac_link_bss_remove(struct mt792x_dev *dev, struct mt792x_bss_conf *mconf, struct mt792x_link_sta *mlink); +void mt792x_config_mac_addr_list(struct mt792x_dev *dev); static inline char *mt792x_ram_name(struct mt792x_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c index 59943c4631211..c15469f837bdd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -916,6 +916,28 @@ int mt792x_load_firmware(struct mt792x_dev *dev) } EXPORT_SYMBOL_GPL(mt792x_load_firmware); +void mt792x_config_mac_addr_list(struct mt792x_dev *dev) +{ + struct ieee80211_hw *hw = mt76_hw(dev); + struct wiphy *wiphy = hw->wiphy; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) { + u8 *addr = dev->macaddr_list[i].addr; + + memcpy(addr, dev->mphy.macaddr, ETH_ALEN); + + if (!i) + continue; + + addr[0] |= BIT(1); + addr[0] ^= ((i - 1) << 2); + } + wiphy->addresses = dev->macaddr_list; + wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list); +} +EXPORT_SYMBOL_GPL(mt792x_config_mac_addr_list); + MODULE_DESCRIPTION("MediaTek MT792x core driver"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Lorenzo Bianconi "); -- GitLab From 70e268ae676d78c7223a246719a87a74b36f87b1 Mon Sep 17 00:00:00 2001 From: Liya Li Date: Wed, 28 Feb 2024 10:02:03 +0800 Subject: [PATCH 338/456] CHROMIUM: spi: Add MT8196 platform data Add MT8196 spi platform data. BUG=b:383440221 TEST=build pass and boot to shell. UPSTREAM-TASK=b:354022471 Signed-off-by: Liya Li Change-Id: I0e4a54fe8eb6b69e911d72f411e1b64634419833 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073688 Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/spi/spi-mt65xx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index ea8e38bfa1746..9342bdc0f35b5 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -216,6 +216,14 @@ static const struct mtk_spi_compatible mt6893_compat = { .no_need_unprepare = true, }; +static const struct mtk_spi_compatible mt8196_compat = { + .need_pad_sel = true, + .must_tx = true, + .enhance_timing = true, + .dma_ext = true, + .ipm_design = true, +}; + /* * A piece of default chip info unless the platform * supplies it. @@ -262,6 +270,9 @@ static const struct of_device_id mtk_spi_of_match[] = { { .compatible = "mediatek,mt6893-spi", .data = (void *)&mt6893_compat, }, + { .compatible = "mediatek,mt8196-spi", + .data = (void *)&mt8196_compat, + }, {} }; MODULE_DEVICE_TABLE(of, mtk_spi_of_match); -- GitLab From b6025dde9e875005ed85cc42128f0778101f4fb2 Mon Sep 17 00:00:00 2001 From: Jia Xue Date: Fri, 6 Dec 2024 16:11:26 +0800 Subject: [PATCH 339/456] CHROMIUM: spi: mediatek: fix spi transfer timeout A gic interrupt will be generated after SPI transmission, but at this time the CPU is in an idle state and the processing handler will be very slow. It takes time to exit the idle state and then become active; this will cause the SPI handler to execute slowly and cause SPI transfer timeouts BUG=b:377778854 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:354022471 Signed-off-by: Jia Xue Change-Id: I24204a071aae09a8236b46f5798f1b23f769ac84 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6080134 Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/spi/spi-mt65xx.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 9342bdc0f35b5..48029724eb2b4 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -19,6 +19,7 @@ #include #include #include +#include #define SPI_CFG0_REG 0x0000 #define SPI_CFG1_REG 0x0004 @@ -165,6 +166,7 @@ struct mtk_spi { struct scatterlist *tx_sgl, *rx_sgl; u32 tx_sgl_len, rx_sgl_len; const struct mtk_spi_compatible *dev_comp; + struct pm_qos_request spi_qos_request; u32 spi_clk_hz; struct completion spimem_done; bool use_spimem; @@ -366,6 +368,7 @@ static int mtk_spi_hw_init(struct spi_master *master, struct mtk_chip_config *chip_config = spi->controller_data; struct mtk_spi *mdata = spi_master_get_devdata(master); + cpu_latency_qos_update_request(&mdata->spi_qos_request, 500); cpha = spi->mode & SPI_CPHA ? 1 : 0; cpol = spi->mode & SPI_CPOL ? 1 : 0; @@ -469,6 +472,15 @@ static int mtk_spi_prepare_message(struct spi_master *master, return mtk_spi_hw_init(master, msg->spi); } +static int mtk_spi_unprepare_message(struct spi_controller *ctlr, + struct spi_message *message) +{ + struct mtk_spi *mdata = spi_master_get_devdata(ctlr); + + cpu_latency_qos_update_request(&mdata->spi_qos_request, PM_QOS_DEFAULT_VALUE); + return 0; +} + static void mtk_spi_set_cs(struct spi_device *spi, bool enable) { u32 reg_val; @@ -1142,6 +1154,7 @@ static int mtk_spi_probe(struct platform_device *pdev) master->set_cs = mtk_spi_set_cs; master->prepare_message = mtk_spi_prepare_message; + master->unprepare_message = mtk_spi_unprepare_message; master->transfer_one = mtk_spi_transfer_one; master->can_dma = mtk_spi_can_dma; master->setup = mtk_spi_setup; @@ -1247,6 +1260,8 @@ static int mtk_spi_probe(struct platform_device *pdev) clk_disable_unprepare(mdata->spi_hclk); } + cpu_latency_qos_add_request(&mdata->spi_qos_request, PM_QOS_DEFAULT_VALUE); + if (mdata->dev_comp->need_pad_sel) { if (mdata->pad_num != master->num_chipselect) return dev_err_probe(dev, -EINVAL, @@ -1289,6 +1304,7 @@ static void mtk_spi_remove(struct platform_device *pdev) struct mtk_spi *mdata = spi_master_get_devdata(master); int ret; + cpu_latency_qos_remove_request(&mdata->spi_qos_request); if (mdata->use_spimem && !completion_done(&mdata->spimem_done)) complete(&mdata->spimem_done); -- GitLab From 7b7b8970eff74cbf25bc36080d0f7ff5e4fd6ca3 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Tue, 30 Jan 2024 20:16:02 +0800 Subject: [PATCH 340/456] CHROMIUM: memory: mtk-smi: Add mt8196 support Add mt8196 support BUG=b:383247849 TEST=boot to homescreen UPSTREAM-TASK=b:354020406 Signed-off-by: Yong Wu Signed-off-by: Jason-jh Lin Change-Id: Ic006a90ed5bba119b4bc4fd6eb3617a6bc6d1733 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071734 Reviewed-by: Hsin-Te Yuan Reviewed-by: Fei Shao Commit-Queue: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/memory/mtk-smi.c | 184 +++++++++++++++++++++++++++++++++++---- 1 file changed, 167 insertions(+), 17 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 6523cb5105182..5889458fa7c1c 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -92,6 +92,7 @@ #define MTK_SMI_FLAG_SW_FLAG BIT(1) #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) #define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) +#define MTK_SMI_FLAG_CONNECT_SMMUV3 BIT(4) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) struct mtk_smi_reg_pair { @@ -147,6 +148,7 @@ struct mtk_smi { }; struct device *smi_common_dev; /* for sub common */ const struct mtk_smi_common_plat *plat; + bool skip_rpm; }; struct mtk_smi_larb { /* larb: local arbiter */ @@ -274,11 +276,13 @@ static int mtk_smi_larb_config_port_gen2_general(struct device *dev) } } - for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { - reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); - reg |= F_MMU_EN; - reg |= BANK_SEL(larb->bank[i]); - writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); + if (!MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_CONNECT_SMMUV3)) { + for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { + reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); + reg |= F_MMU_EN; + reg |= BANK_SEL(larb->bank[i]); + writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); + } } return 0; } @@ -377,6 +381,101 @@ static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = { [28] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,}, }; +static const u8 mtk_smi_larb_mt8196_ostd[][SMI_LARB_PORT_NR_MAX] = { + [0] = {0x4, 0x4, 0x40, 0x40, 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, + 0x1, 0x1, 0x1,}, /* LARB0 */ + [1] = {0x4, 0x4, 0x40, 0x40, 0x32, 0x1, 0x2, 0x2, 0x2, 0x4, + 0x4, 0x2, 0x1, 0x1, 0x1, 0x1,}, /* LARB1 */ + [2] = {0x1, 0x1, 0x1, 0x1, 0x9, 0xb, 0x2a, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x3, 0x1c, 0x1, 0x1,}, /* LARB2 */ + [3] = {0x2, 0x2, 0x2, 0x2, 0x1a, 0x20, 0x2a, 0x2, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x2, 0x8, 0x1c, 0x1, 0x1,}, /* LARB3 */ + [4] = {0x40, 0x10, 0x10, 0x1, 0x4, 0x10, 0x8, 0x8,}, /* LARB4 */ + [5] = {0x10, 0x8, 0x40, 0x1e, 0x8, 0x8, 0x4, 0x1,}, /* LARB5 */ + [6] ={0x40, 0x12, 0x1,}, /* LARB6 */ + [7] ={0x20, 0x6, 0x6, 0x1, 0x1, 0x24, 0x2b, 0x7, 0x4, 0x1, + 0x1, 0xf, 0x3, 0x5, 0x8, 0x8, 0x3, 0x8, 0x5, 0x23, + 0x24, 0x4, 0x2, 0xb, 0x10, 0x17, 0x4, 0x8, 0x5, 0x1, + 0x1, 0x6,}, /* LARB7 */ + [8] ={0x20, 0x6, 0x6, 0x1, 0x1, 0x24, 0x2b, 0x7, 0x4, 0x1, + 0x1, 0xf, 0x3, 0x5, 0x8, 0x8, 0x3, 0x8, 0x5, 0x23, + 0x24, 0x4, 0x2, 0xb, 0x10, 0x17, 0x4, 0x8, 0x5, 0x1, + 0x1, 0x6,}, /* LARB8 */ + [9] = {0x2b, 0x8, 0x9, 0x31, 0x10, 0x26, 0x15, 0x13, 0x7, 0x4, + 0x1, 0x1, 0x7, 0xa, 0xb, 0x6, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0xf, 0x9, 0x6, 0x3,}, /*LARB9*/ + [10] = {0x2b, 0x8, 0x20, 0x1d, 0x19, 0xf, 0x1, 0x3,}, /* LARB10 */ + [11] = {0x8, 0x16, 0x16, 0x24, 0x1, 0x1, 0x1, 0x3, 0x32, 0x1, + 0x8, 0x10, 0x16, 0x2, 0x38,}, /* LARB11 */ + [12] = {0xa, 0xa, 0x1,}, /* LARB12 */ + [13] = {0x2, 0x20, 0x14, 0x1, 0x1, 0x2, 0x2,}, /* LARB13 */ + [14] = {0x2, 0x20, 0x14, 0x1, 0x2, 0x2,}, /* LARB14 */ + [15] = {0x2b, 0x7, 0x31, 0xa, 0x10, 0x10, 0x2b, 0x29, 0x7, 0x1,}, /* LARB15 */ + [16] = {0x4, 0x4, 0x12, 0x8, 0x8, 0x16, 0x8, 0x6, 0xe, 0x6, + 0x1e, 0x18, 0x16, 0xe, 0x8, 0xe, 0x8, 0x2, 0x2,}, /* LARB16 */ + [17] = {0x18, 0x18, 0x8, 0x8, 0xc, 0x4, 0x2,}, /* LARB17 */ + [18] = {0xb, 0x1, 0x10, 0x1, 0x2,}, /* LARB18 */ + [19] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x2, 0x1, 0x1, + 0x4, 0x2, 0x1,}, /* LARB19 */ + [20] = {0x2, 0x2, 0x2, 0x40, 0x40, 0x40, 0x1, 0x2, 0x2, 0x2, + 0x4, 0x4, 0x4, 0x1, 0x1,}, /* LARB20 */ + [21] = {0x2, 0x2, 0x2, 0x40, 0x40, 0x40, 0x1, 0x32, 0x32, 0x32, + 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x2, 0x1,}, /* LARB21 */ + [22] = {0x8, 0x16, 0x16, 0x24, 0x1, 0x1, 0x1, 0x3, 0x32, 0x1, + 0x8, 0x10, 0x16, 0x2, 0x38,}, /* LARB22 */ + [23] = {0x8, 0x16, 0x16, 0x24, 0x1, 0x1, 0x1, 0x3, 0x32, 0x1, + 0x8, 0x10, 0x16, 0x2, 0x38,}, /* LARB23 */ + [24] = {0x20, 0x6, 0x6, 0x1, 0x1, 0x24, 0x2b, 0x7, 0x4, 0x1, + 0x1, 0xf, 0x3, 0x5, 0x8, 0x8, 0x3, 0x8, 0x5, 0x23, + 0x24, 0x4, 0x2, 0xb, 0x10, 0x17, 0x4, 0x8, 0x5, 0x1, + 0x1, 0x6,}, /* LARB24 */ + [25] = {0x2, 0xc, 0x2, 0xc, 0x6, 0x6, 0x3, 0x3, 0x3, 0x1, + 0x1, 0x2, 0x2,}, /* LARB25 */ + [26] = {0x2, 0xc, 0x2, 0xc, 0x6, 0x6, 0x3, 0x3, 0x3, 0x1, + 0x1, 0x2, 0x2,}, /* LARB26 */ + [27] = {0x6, 0x2, 0xe, 0x6, 0x2, 0x14, 0x14, 0x4, 0x6,}, /* LARB27 */ + [28] = {0x2b, 0x8, 0x31, 0x10, 0x26, 0x15, 0x1, 0x10,}, /* LARB28 */ + [29] = {0x2, 0x2, 0x2, 0x2, 0x10, 0xe, 0x6, 0x6, 0x1, 0x1, + 0x2, 0x2, 0x2, 0x2,}, /* LARB29 */ + [30] = {0x2, 0x2, 0x2, 0x2,}, /* LARB30 */ + {}, /* LARB31 */ + {0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x32, 0x32, 0x1, 0x2,}, /* LARB32 */ + {0xa, 0x1, 0x1, 0x1, 0xa, 0xa, 0xa, 0x1, 0x26, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x2, 0x1,}, /* LARB33 */ + {0x4, 0x4, 0x40, 0x40, 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, + 0x1, 0x1, 0x1,}, /* LARB34 */ + {0x4, 0x4, 0x40, 0x40, 0x32, 0x1, 0x2, 0x2, 0x2, 0x4, + 0x4, 0x2, 0x1, 0x1, 0x1, 0x1,}, /* LARB35 */ + {0x2, 0x2, 0x2, 0x40, 0x40, 0x40, 0x1, 0x2, 0x2, 0x2, + 0x4, 0x4, 0x4, 0x1, 0x1,}, /* LARB36 */ + {0x2, 0x2, 0x2, 0x40, 0x40, 0x40, 0x1, 0x32, 0x32, 0x32, + 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x2, 0x1,}, /* LARB37 */ + {0x29, 0x40, 0x40, 0x7, 0x4, 0x40, 0x4, 0x18, 0x1, 0x1, + 0x1, 0x7, 0x4,}, /* LARB38 */ + {0x16, 0x4, 0x4, 0x8, 0x4, 0x6, 0x6, 0x13, 0x11, 0x20, + 0x11, 0x1, 0x1, 0x1, 0x9, 0x8, 0x4, 0x6, 0x6,}, /* LARB39 */ + {0x9, 0x7, 0x7, 0xb, 0xf, 0x1d, 0x13, 0x6, 0x1, 0x1, + 0x1, 0x6, 0x9, 0x7, 0xe, 0x3,}, /* LARB40 */ + {0x40, 0x8, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x8, 0x8, 0x8, 0x8, 0x8, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1,}, /* LARB41 */ + {0x1, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x8, 0x8, 0x8, 0x8, 0x8, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1,}, /* LARB42 */ + {0x4, 0x4, 0x12, 0x8, 0x8, 0x16, 0x8, 0x6, 0xe, 0x6, + 0x1e, 0x18, 0x16, 0xe, 0x8, 0xe, 0x8, 0x1, 0x1,}, /* LARB43 */ + {0x4, 0x4, 0x12, 0x8, 0x8, 0x16, 0x8, 0x6, 0xe, 0x6, + 0x1e, 0x18, 0x16, 0xe, 0x8, 0xe, 0x8, 0x1, 0x1,}, /* LARB44 */ + {0x18, 0x18, 0x8, 0x8, 0xc, 0x4, 0x1,}, /* LARB45 */ + {0x18, 0x18, 0x8, 0x8, 0xc, 0x4, 0x1,}, /* LARB46 */ + {0x1, 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x8, 0x8, 0x8, 0x8, 0x8, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1,}, /* LARB47 */ +}; + static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { .port_in_larb = { LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, @@ -436,6 +535,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = { .ostd = mtk_smi_larb_mt8195_ostd, }; +static const struct mtk_smi_larb_gen mtk_smi_larb_mt8196 = { + .config_port = mtk_smi_larb_config_port_gen2_general, + .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG | + MTK_SMI_FLAG_SLEEP_CTL | MTK_SMI_FLAG_CONNECT_SMMUV3, + .ostd = mtk_smi_larb_mt8196_ostd, +}; + static const struct of_device_id mtk_smi_larb_of_ids[] = { {.compatible = "mediatek,mt2701-smi-larb", .data = &mtk_smi_larb_mt2701}, {.compatible = "mediatek,mt2712-smi-larb", .data = &mtk_smi_larb_mt2712}, @@ -448,6 +554,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { {.compatible = "mediatek,mt8188-smi-larb", .data = &mtk_smi_larb_mt8188}, {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192}, {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195}, + {.compatible = "mediatek,mt8196-smi-larb", .data = &mtk_smi_larb_mt8196}, {} }; @@ -513,6 +620,9 @@ static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi, { int i, ret; + if (smi->skip_rpm) + return 0; + for (i = 0; i < clk_nr_required; i++) smi->clks[i].id = clks[i]; ret = devm_clk_bulk_get(dev, clk_nr_required, smi->clks); @@ -531,6 +641,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) { struct mtk_smi_larb *larb; struct device *dev = &pdev->dev; + bool connect_with_smmuv3; int ret; larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL); @@ -542,6 +653,20 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) if (IS_ERR(larb->base)) return PTR_ERR(larb->base); + if (of_property_read_bool(dev->of_node, "mediatek,skip-rpm-cb")) { + larb->smi.skip_rpm = true; + dev_info(dev, "skip rpm callback\n"); + } + + connect_with_smmuv3 = MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_CONNECT_SMMUV3); + if (connect_with_smmuv3 && !IS_ENABLED(CONFIG_ARM_SMMU_V3)) { + dev_err(dev, " SMMU property conflict.\n"); + return -EINVAL; + } + ret = of_property_read_u32(dev->of_node, "mediatek,larb-id", &larb->larbid); + if (connect_with_smmuv3 && ret) + return ret; + ret = mtk_smi_dts_clk_init(dev, &larb->smi, mtk_smi_larb_clks, MTK_SMI_LARB_REQ_CLK_NR, MTK_SMI_LARB_OPT_CLK_NR); if (ret) @@ -549,19 +674,28 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) larb->smi.dev = dev; - ret = mtk_smi_device_link_common(dev, &larb->smi_common_dev); - if (ret < 0) - return ret; + if (!larb->smi.skip_rpm) { + ret = mtk_smi_device_link_common(dev, &larb->smi_common_dev); + if (ret < 0) { + dev_err(dev, "lnk fail %d\n", ret); + return ret; + } + + pm_runtime_enable(dev); + } - pm_runtime_enable(dev); platform_set_drvdata(pdev, larb); - ret = component_add(dev, &mtk_smi_larb_component_ops); - if (ret) - goto err_pm_disable; + if (!connect_with_smmuv3) { + ret = component_add(dev, &mtk_smi_larb_component_ops); + if (ret) + goto err_pm_disable; + } + dev_dbg(dev, "probe done"); return 0; err_pm_disable: - pm_runtime_disable(dev); + if (!larb->smi.skip_rpm) + pm_runtime_disable(dev); device_link_remove(dev, larb->smi_common_dev); return ret; } @@ -572,7 +706,8 @@ static int mtk_smi_larb_remove(struct platform_device *pdev) device_link_remove(&pdev->dev, larb->smi_common_dev); pm_runtime_disable(&pdev->dev); - component_del(&pdev->dev, &mtk_smi_larb_component_ops); + if (!MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_CONNECT_SMMUV3)) + component_del(&pdev->dev, &mtk_smi_larb_component_ops); return 0; } @@ -718,6 +853,14 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8365 = { .bus_sel = F_MMU1_LARB(2) | F_MMU1_LARB(4), }; +static const struct mtk_smi_common_plat mtk_smi_common_mt8196 = { + .type = MTK_SMI_GEN2, +}; + +static const struct mtk_smi_common_plat mtk_smi_sub_common_mt8196 = { + .type = MTK_SMI_GEN2_SUB_COMM, +}; + static const struct of_device_id mtk_smi_common_of_ids[] = { {.compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1}, {.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2}, @@ -734,6 +877,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp}, {.compatible = "mediatek,mt8195-smi-sub-common", .data = &mtk_smi_sub_common_mt8195}, {.compatible = "mediatek,mt8365-smi-common", .data = &mtk_smi_common_mt8365}, + {.compatible = "mediatek,mt8196-smi-common", .data = &mtk_smi_common_gen2}, + {.compatible = "mediatek,mt8196-smi-sub-common", .data = &mtk_smi_sub_common_mt8196}, {} }; @@ -749,7 +894,10 @@ static int mtk_smi_common_probe(struct platform_device *pdev) common->dev = dev; common->plat = of_device_get_match_data(dev); - if (common->plat->has_gals) { + if (of_property_read_bool(dev->of_node, "mediatek,skip-rpm-cb")) + common->skip_rpm = true; + + if (!common->skip_rpm && common->plat->has_gals) { if (common->plat->type == MTK_SMI_GEN2) clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR; else if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) @@ -784,14 +932,16 @@ static int mtk_smi_common_probe(struct platform_device *pdev) } /* link its smi-common if this is smi-sub-common */ - if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) { + if (common->plat->type == MTK_SMI_GEN2_SUB_COMM && !common->skip_rpm) { ret = mtk_smi_device_link_common(dev, &common->smi_common_dev); if (ret < 0) return ret; } - pm_runtime_enable(dev); + if (!common->skip_rpm) + pm_runtime_enable(dev); platform_set_drvdata(pdev, common); + dev_dbg(dev, "probe done"); return 0; } -- GitLab From 7dbc36f5998ccc0c73b3abe628a252eac0009e92 Mon Sep 17 00:00:00 2001 From: "Vineeth Pillai (Google)" Date: Thu, 12 Dec 2024 22:22:36 -0500 Subject: [PATCH 341/456] BACKPORT: sched/dlserver: Fix dlserver double enqueue dlserver can get dequeued during a dlserver pick_task due to the delayed deueue feature and this can lead to issues with dlserver logic as it still thinks that dlserver is on the runqueue. The dlserver throttling and replenish logic gets confused and can lead to double enqueue of dlserver. Double enqueue of dlserver could happend due to couple of reasons: Case 1 ------ Delayed dequeue feature[1] can cause dlserver being stopped during a pick initiated by dlserver: __pick_next_task pick_task_dl -> server_pick_task pick_task_fair pick_next_entity (if (sched_delayed)) dequeue_entities dl_server_stop server_pick_task goes ahead with update_curr_dl_se without knowing that dlserver is dequeued and this confuses the logic and may lead to unintended enqueue while the server is stopped. Case 2 ------ A race condition between a task dequeue on one cpu and same task's enqueue on this cpu by a remote cpu while the lock is released causing dlserver double enqueue. One cpu would be in the schedule() and releasing RQ-lock: current->state = TASK_INTERRUPTIBLE(); schedule(); deactivate_task() dl_stop_server(); pick_next_task() pick_next_task_fair() sched_balance_newidle() rq_unlock(this_rq) at which point another CPU can take our RQ-lock and do: try_to_wake_up() ttwu_queue() rq_lock() ... activate_task() dl_server_start() --> first enqueue wakeup_preempt() := check_preempt_wakeup_fair() update_curr() update_curr_task() if (current->dl_server) dl_server_update() enqueue_dl_entity() --> second enqueue This bug was not apparent as the enqueue in dl_server_start doesn't usually happen because of the defer logic. But as a side effect of the first case(dequeue during dlserver pick), dl_throttled and dl_yield will be set and this causes the time accounting of dlserver to messup and then leading to a enqueue in dl_server_start. Have an explicit flag representing the status of dlserver to avoid the confusion. This is set in dl_server_start and reset in dlserver_stop. BUG=b:389552368 TEST=boot and login Fixes: 63ba8422f876 ("sched/deadline: Introduce deadline servers") Suggested-by: Peter Zijlstra Signed-off-by: "Vineeth Pillai (Google)" Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: "Vineeth Pillai" Tested-by: Marcel Ziswiler # ROCK 5B Link: https://lkml.kernel.org/r/20241213032244.877029-1-vineeth@bitbyteword.org (cherry picked from commit b53127db1dbf7f1047cf35c10922d801dcd40324) Change-Id: I3fd633237ceea9e11d54a69bf5a20f62fc334b50 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6175217 Tested-by: Joel Fernandes Reviewed-by: Joel Fernandes Commit-Queue: Joel Fernandes Signed-off-by: Hubert Mazur --- include/linux/sched.h | 7 +++++++ kernel/sched/deadline.c | 8 ++++++-- kernel/sched/sched.h | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index ccc628058ad2b..8d1df323caa1e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -661,6 +661,12 @@ struct sched_dl_entity { * @dl_defer_armed tells if the deferrable server is waiting * for the replenishment timer to activate it. * + * @dl_server_active tells if the dlserver is active(started). + * dlserver is started on first cfs enqueue on an idle runqueue + * and is stopped when a dequeue results in 0 cfs tasks on the + * runqueue. In other words, dlserver is active only when cpu's + * runqueue has atleast one cfs task. + * * @dl_defer_running tells if the deferrable server is actually * running, skipping the defer phase. */ @@ -669,6 +675,7 @@ struct sched_dl_entity { unsigned int dl_non_contending : 1; unsigned int dl_overrun : 1; unsigned int dl_server : 1; + unsigned int dl_server_active : 1; unsigned int dl_defer : 1; unsigned int dl_defer_armed : 1; unsigned int dl_defer_running : 1; diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index fff9f068f5e33..0fdddb80940d9 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1648,6 +1648,7 @@ void dl_server_start(struct sched_dl_entity *dl_se) if (!dl_se->dl_runtime) return; + dl_se->dl_server_active = 1; enqueue_dl_entity(dl_se, ENQUEUE_WAKEUP); if (!dl_task(dl_se->rq->curr) || dl_entity_preempt(dl_se, &rq->curr->dl)) resched_curr(dl_se->rq); @@ -1662,6 +1663,7 @@ void dl_server_stop(struct sched_dl_entity *dl_se) hrtimer_try_to_cancel(&dl_se->dl_timer); dl_se->dl_defer_armed = 0; dl_se->dl_throttled = 0; + dl_se->dl_server_active = 0; } void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq, @@ -2424,8 +2426,10 @@ again: p = dl_se->server_pick_next(dl_se); if (!p) { WARN_ON_ONCE(1); - dl_se->dl_yielded = 1; - update_curr_dl_se(rq, dl_se, 0); + if (dl_server_active(dl_se)) { + dl_se->dl_yielded = 1; + update_curr_dl_se(rq, dl_se, 0); + } goto again; } p->dl_server = dl_se; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 05c39878209cf..fe05f85036121 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -364,6 +364,11 @@ extern void __dl_server_attach_root(struct sched_dl_entity *dl_se, struct rq *rq extern int dl_server_apply_params(struct sched_dl_entity *dl_se, u64 runtime, u64 period, bool init); +static inline bool dl_server_active(struct sched_dl_entity *dl_se) +{ + return dl_se->dl_server_active; +} + #ifdef CONFIG_CGROUP_SCHED struct cfs_rq; -- GitLab From 75846e4c7ad4fba44d4b644272b025254d75ed9a Mon Sep 17 00:00:00 2001 From: "Vineeth Pillai (Google)" Date: Thu, 12 Dec 2024 22:22:37 -0500 Subject: [PATCH 342/456] BACKPORT: sched/dlserver: Fix dlserver time accounting dlserver time is accounted when: - dlserver is active and the dlserver proxies the cfs task. - dlserver is active but deferred and cfs task runs after being picked through the normal fair class pick. dl_server_update is called in two places to make sure that both the above times are accounted for. But it doesn't check if dlserver is active or not. Now that we have this dl_server_active flag, we can consolidate dl_server_update into one place and all we need to check is whether dlserver is active or not. When dlserver is active there is only two possible conditions: - dlserver is deferred. - cfs task is running on behalf of dlserver. BUG=b:389552368 TEST=boot and login Fixes: a110a81c52a9 ("sched/deadline: Deferrable dl server") Signed-off-by: "Vineeth Pillai (Google)" Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: "Vineeth Pillai" Tested-by: Marcel Ziswiler # ROCK 5B Link: https://lore.kernel.org/r/20241213032244.877029-2-vineeth@bitbyteword.org (cherry picked from commit c7f7e9c73178e0e342486fd31e7f363ef60e3f83) Change-Id: I88a5c18f7acfeabb64f28f929ba25bda5e4ffcac Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6175218 Reviewed-by: Joel Fernandes Commit-Queue: Joel Fernandes Tested-by: Joel Fernandes Signed-off-by: Hubert Mazur --- kernel/sched/fair.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c7708a804ee7a..4bb8cee3284e5 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1220,8 +1220,6 @@ static inline void update_curr_task(struct task_struct *p, s64 delta_exec) trace_sched_stat_runtime(p, delta_exec); account_group_exec_runtime(p, delta_exec); cgroup_account_cputime(p, delta_exec); - if (p->dl_server) - dl_server_update(p->dl_server, delta_exec); } /* @@ -1265,11 +1263,16 @@ static void update_curr(struct cfs_rq *cfs_rq) update_curr_task(p, delta_exec); /* - * Any fair task that runs outside of fair_server should - * account against fair_server such that it can account for - * this time and possibly avoid running this period. + * If the fair_server is active, we need to account for the + * fair_server time whether or not the task is running on + * behalf of fair_server or not: + * - If the task is running on behalf of fair_server, we need + * to limit its time based on the assigned runtime. + * - Fair task that runs outside of fair_server should account + * against fair_server such that it can account for this time + * and possibly avoid running this period. */ - if (p->dl_server != &rq->fair_server) + if (dl_server_active(&rq->fair_server)) dl_server_update(&rq->fair_server, delta_exec); } -- GitLab From 25b27209434b7d6caa4c4728345d5ef977e383a2 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Sun, 4 Feb 2024 11:13:56 +0800 Subject: [PATCH 343/456] CHROMIUM: arm64: dts: mt8196: Add SMI node and disable dependent-VCP/OPP Add SMI device node Disable dependent-VCP/OPP temporarily They will be added by owners. BUG=b:383247849 TEST=build pass and boot to shell UPSTREAM-TASK=b:354020406 Signed-off-by: Yong Wu Change-Id: I4a6980bd5aa7bb126ca7a8c29c29d158d37fbcdd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071741 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 384 +++++++++++++++++++++++ 1 file changed, 384 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 9f55c3e4b3496..2281f6c67ae80 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -1210,6 +1210,57 @@ clocks = <&clk13m>; }; + smi_disp_common: smi-comm@30020000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30020000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,smi = <&disp_ssc0_smi_2x1_sub_comm>; + mediatek,common-id = <0>; + mediatek,skip-rpm-cb; + }; + + smi_mdp_common: smi-comm@30021000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30021000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,smi = <&mdp_ssc4_smi_2x1_sub_comm>; + mediatek,common-id = <1>; + mediatek,skip-rpm-cb; + }; + + disp_ssc0_smi_2x1_sub_comm: smi-comm@30a30000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30a30000 0 0x1000>; + mediatek,common-id = <3>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,skip-rpm-cb; + }; + + disp_ssc1_smi_2x1_sub_comm: smi-comm@30a31000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30a31000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,common-id = <4>; + mediatek,skip-rpm-cb; + }; + + mdp_ssc4_smi_2x1_sub_comm: smi-comm@30a32000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30a32000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,common-id = <5>; + mediatek,skip-rpm-cb; + }; + + mdp_ssc5_smi_2x1_sub_comm: smi-comm@30a33000 { + compatible = "mediatek,mt8196-smi-common"; + reg = <0 0x30a33000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MM_INFRA1>; + mediatek,common-id = <6>; + mediatek,skip-rpm-cb; + }; + + mminfra_hwv: syscon@31a80000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-mminfra-hwv", "mediatek,mt8196-mminfra_hwv", "syscon"; @@ -1238,6 +1289,18 @@ #clock-cells = <1>; }; + smi_larb32: larb@32240000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32240000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DIS0_DORMANT>; + clocks = <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>, + <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm1>; + mediatek,larb-id = <32>; + larb-port-real-time-type = <1 1 1 1 0 0 0 0 1 0>; + }; + dispsys1_config_clk: syscon@32400000 { compatible = "mediatek,mt8196-mmsys1", "syscon"; reg = <0 0x32400000 0 0x1000>; @@ -1245,6 +1308,18 @@ #clock-cells = <1>; }; + smi_larb33: larb@32600000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32600000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DIS1_DORMANT>; + clocks = <&dispsys1_config_clk CLK_MM1_SMI_LARB0_SMI>, + <&dispsys1_config_clk CLK_MM1_SMI_LARB0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm2>; + mediatek,larb-id = <33>; + larb-port-real-time-type = <0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1>; + }; + ovlsys_config_clk: syscon@32800000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-ovlsys-config", "mediatek,mt8196-ovlsys_config", "syscon"; @@ -1253,12 +1328,137 @@ #clock-cells = <1>; }; + smi_larb0: larb@32a60000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32a60000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL0_DORMANT>; + clocks = <&ovlsys_config_clk CLK_OVL_SMI_SMI>, + <&ovlsys_config_clk CLK_OVL_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm0>; + mediatek,larb-id = <0>; + larb-port-real-time-type = <0 0 0 0 1 1 0 0 0 0 1 1 1>; + }; + + smi_larb1: larb@32a70000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32a70000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL0_DORMANT>; + clocks = <&ovlsys_config_clk CLK_OVL_SMI_SMI>, + <&ovlsys_config_clk CLK_OVL_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm1>; + mediatek,larb-id = <1>; + larb-port-real-time-type = <0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1>; + }; + + smi_larb20: larb@32a80000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32a80000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL0_DORMANT>; + clocks = <&ovlsys_config_clk CLK_OVL_SMI_SMI>, + <&ovlsys_config_clk CLK_OVL_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm2>; + mediatek,larb-id = <20>; + larb-port-real-time-type = <0 0 0 0 0 0 1 0 0 0 0 0 0 1 1>; + }; + + smi_larb21: larb@32a90000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32a90000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL0_DORMANT>; + clocks = <&ovlsys_config_clk CLK_OVL_SMI_SMI>, + <&ovlsys_config_clk CLK_OVL_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm3>; + mediatek,larb-id = <21>; + larb-port-real-time-type = <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1>; + }; + ovlsys1_config_clk: syscon@32c00000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-ovlsys1-config", "mediatek,mt8196-ovlsys1_config", "syscon"; reg = <0 0x32c00000 0 0x1000>; mm-hw-ccf-regmap = <&mm_hwv>; #clock-cells = <1>; + + async { + clocks = <&ovlsys1_config_clk CLK_OVL_DLO5_DISP>, + <&ovlsys1_config_clk CLK_OVL_DLO6_DISP>; + }; + }; + + smi_larb34: larb@32e60000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32e60000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL1_DORMANT>; + clocks = <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>, + <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm3>; + mediatek,larb-id = <34>; + larb-port-real-time-type = <0 0 0 0 1 1 0 0 0 0 1 1 1>; + }; + + smi_larb35: larb@32e70000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32e70000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL1_DORMANT>; + clocks = <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>, + <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm2>; + mediatek,larb-id = <35>; + larb-port-real-time-type = <0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1>; + }; + + smi_larb36: larb@32e80000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32e80000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL1_DORMANT>; + clocks = <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>, + <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm1>; + mediatek,larb-id = <36>; + larb-port-real-time-type = <0 0 0 0 0 0 1 0 0 0 0 0 0 1 1>; + }; + + smi_larb37: larb@32e90000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x32e90000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL1_DORMANT>; + clocks = <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>, + <&ovlsys1_config_clk CLK_OVL1_SMI_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm0>; + mediatek,larb-id = <37>; + larb-port-real-time-type = <0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1>; + }; + + smi_larb5: larb@3600d000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x3600d000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VDE0>; + clocks = <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>, + <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_common>; + mediatek,larb-id = <5>; + larb-port-real-time-type = <1 1 1 1 1 1 1 1>; + }; + + smi_larb6: larb@3600e000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x3600e000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VDE0>; + clocks = <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>, + <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_common>; + mediatek,larb-id = <6>; + larb-port-real-time-type = <1 1 1>; }; vdec_soc_gcon_base_clk: syscon@3600f000 { @@ -1268,6 +1468,18 @@ #clock-cells = <1>; }; + smi_larb4: larb@3602e000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x3602e000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VDE1>; + clocks = <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>, + <&vdec_soc_gcon_base_clk CLK_VDE1_VDEC_CKEN>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_common>; + mediatek,larb-id = <4>; + larb-port-real-time-type = <1 1 1 1 1 1 1 1>; + }; + vdec_gcon_base_clk: syscon@3602f000 { compatible = "mediatek,mt8196-vdecsys", "syscon"; reg = <0 0x3602f000 0 0x1000>; @@ -1281,6 +1493,41 @@ #clock-cells = <1>; }; + smi_larb7: larb@38010000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38010000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN0>; + clocks = <&venc_gcon_clk CLK_VEN1_CKE0_LARB_SMI>, + <&venc_gcon_clk CLK_VEN1_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_venc_sub_comm0>; + mediatek,larb-id = <7>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + + smi_disp_venc_sub_comm0: smi-sub-comm@38070000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x38070000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN0>; + clocks = <&venc_gcon_clk CLK_VEN1_CKE0_LARB_SMI>, + <&venc_gcon_clk CLK_VEN1_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_common>; + mediatek,common-id = <15>; + }; + + smi_larb41: larb@38090000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38090000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN0>; + clocks = <&venc_gcon_clk CLK_VEN1_CKE0_LARB_SMI>, + <&venc_gcon_clk CLK_VEN1_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_venc_sub_comm0>; + mediatek,larb-id = <41>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + venc_gcon_core1_clk: syscon@38800000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-vencsys-c1", "mediatek,mt8196-vencsys_c1", "syscon"; @@ -1289,6 +1536,42 @@ #clock-cells = <1>; }; + smi_larb8: larb@38810000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38810000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN1>; + clocks = <&venc_gcon_core1_clk CLK_VEN2_CKE0_LARB_SMI>, + <&venc_gcon_core1_clk CLK_VEN2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_venc_sub_comm1>; + mediatek,larb-id = <8>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + + + smi_mdp_venc_sub_comm1: smi-sub-comm@38870000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x38870000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN1>; + clocks = <&venc_gcon_core1_clk CLK_VEN2_CKE0_LARB_SMI>, + <&venc_gcon_core1_clk CLK_VEN2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_common>; + mediatek,common-id = <16>; + }; + + smi_larb42: larb@38890000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38890000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN1>; + clocks = <&venc_gcon_core1_clk CLK_VEN2_CKE0_LARB_SMI>, + <&venc_gcon_core1_clk CLK_VEN2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_venc_sub_comm1>; + mediatek,larb-id = <42>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + venc_gcon_core2_clk: syscon@38c00000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-vencsys-c2", "mediatek,mt8196-vencsys_c2", "syscon"; @@ -1297,6 +1580,41 @@ #clock-cells = <1>; }; + smi_larb24: larb@38c10000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38c10000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN2>; + clocks = <&venc_gcon_core2_clk CLK_VEN_C2_CKE0_LARB_SMI>, + <&venc_gcon_core2_clk CLK_VEN_C2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_venc_sub_comm2>; + mediatek,larb-id = <24>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + + smi_mdp_venc_sub_comm2: smi-sub-comm@38c70000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x38c70000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN2>; + clocks = <&venc_gcon_core2_clk CLK_VEN_C2_CKE0_LARB_SMI>, + <&venc_gcon_core2_clk CLK_VEN_C2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_venc_sub_comm1>; + mediatek,common-id = <18>; + }; + + smi_larb47: larb@38c90000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x38c90000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_VEN2>; + clocks = <&venc_gcon_core2_clk CLK_VEN_C2_CKE0_LARB_SMI>, + <&venc_gcon_core2_clk CLK_VEN_C2_CKE1_VENC_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_venc_sub_comm2>; + mediatek,larb-id = <47>; + larb-port-real-time-type = <3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 3>; + }; + cam_main_r1a_clk: syscon@3a000000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-cam_main-r1a", "mediatek,mt8196-cam_main_r1a", "syscon"; @@ -1311,12 +1629,34 @@ #clock-cells = <1>; }; + smi_larb2: larb@3e030000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x3e030000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MML0_SHUTDOWN>; + clocks = <&mdpsys_config_clk CLK_MDP_SMI0_SMI>, <&mdpsys_config_clk CLK_MDP_SMI0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_dram_sub_comm0>; + mediatek,larb-id = <2>; + larb-port-real-time-type = <1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1>; + }; + mdpsys1_config_clk: syscon@3e400000 { compatible = "mediatek,mt8196-mdpsys1", "syscon"; reg = <0 0x3e400000 0 0x1000>; #clock-cells = <1>; }; + smi_larb3: larb@3e430000 { + compatible = "mediatek,mt8196-smi-larb"; + reg = <0 0x3e430000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_MML1_SHUTDOWN>; + clocks = <&mdpsys1_config_clk CLK_MDP1_SMI0_SMI>, <&mdpsys1_config_clk CLK_MDP1_SMI0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_dram_sub_comm3>; + mediatek,larb-id = <3>; + larb-port-real-time-type = <2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2>; + }; + disp_vdisp_ao_config_clk: syscon@3e800000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-disp-vdisp-ao-config", "mediatek,mt8196-disp_vdisp_ao_config", "syscon"; @@ -1325,6 +1665,50 @@ #clock-cells = <1>; }; + smi_disp_dram_sub_comm0: smi-sub-comm@3e810000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x3e810000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DISP_VCORE>; + clocks = <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>, + <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_common>; + mediatek,common-id = <9>; + }; + + smi_disp_dram_sub_comm1: smi-sub-comm@3e820000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x3e820000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DISP_VCORE>; + clocks = <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>, + <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_disp_common>; + mediatek,common-id = <10>; + }; + + smi_mdp_dram_sub_comm2: smi-sub-comm@3e830000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x3e830000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DISP_VCORE>; + clocks = <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>, + <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_common>; + mediatek,common-id = <11>; + }; + + smi_mdp_dram_sub_comm3: smi-sub-comm@3e840000 { + compatible = "mediatek,mt8196-smi-sub-common"; + reg = <0 0x3e840000 0 0x1000>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_DISP_VCORE>; + clocks = <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>, + <&disp_vdisp_ao_config_clk CLK_MM_V_SMI_SUB_SOMM0_SMI>; + clock-names = "apb", "smi"; + mediatek,smi = <&smi_mdp_common>; + mediatek,common-id = <12>; + }; + mfgpll_pll_ctrl_clk: syscon@4b810000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-mfgpll-pll-ctrl", "mediatek,mt8196-mfgpll_pll_ctrl", "syscon"; -- GitLab From f520beb8ddaa3ba3df498367dc458966285a8726 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Thu, 29 Feb 2024 11:23:55 +0800 Subject: [PATCH 344/456] CHROMIUM: arm64: dts: mt8196: Add SMMU node Add SMMU node BUG=b:329380044 BUG=b:383247849 TEST=Build pass and boot to shell UPSTREAM-TASK=b:354020406 Signed-off-by: Yong Wu Change-Id: I985b821930c0a8caa989895a6a583cf9fbacb40e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073682 Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 2281f6c67ae80..275c5827a69d6 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -1228,6 +1228,14 @@ mediatek,skip-rpm-cb; }; + mm_smmu: iommu@30800000 { + compatible = "mediatek,mt8196-mm-smmu", "arm,smmu-v3"; + reg = <0 0x30800000 0 0x1e0000>; + interrupts = ; + interrupt-names = "combined"; + #iommu-cells = <1>; + }; + disp_ssc0_smi_2x1_sub_comm: smi-comm@30a30000 { compatible = "mediatek,mt8196-smi-common"; reg = <0 0x30a30000 0 0x1000>; @@ -1709,6 +1717,15 @@ mediatek,common-id = <12>; }; + gpu_smmu: iommu@48600000 { + #iommu-cells = <1>; + compatible = "mediatek,mt8196-gpu-smmu", "arm,smmu-v3"; + reg = <0 0x48600000 0 0x1e0000>; + interrupts = ; + interrupt-names = "combined"; + status = "disabled"; + }; + mfgpll_pll_ctrl_clk: syscon@4b810000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-mfgpll-pll-ctrl", "mediatek,mt8196-mfgpll_pll_ctrl", "syscon"; @@ -1729,5 +1746,13 @@ reg = <0 0x4b810800 0 0x1000>; #clock-cells = <1>; }; + + apu_smmu: iommu@4c000000 { + compatible = "mediatek,mt8196-apu-smmu", "arm,smmu-v3"; + reg = <0 0x4c000000 0 0x1e0000>; + interrupts = ; + interrupt-names = "combined"; + #iommu-cells = <1>; + }; }; }; -- GitLab From c0bcbbd602ab2461a3c8f0ceb9c998361dbfd1b9 Mon Sep 17 00:00:00 2001 From: Xavier Chang Date: Tue, 2 Jul 2024 16:09:25 +0800 Subject: [PATCH 345/456] CHROMIUM: arm64: dts: mt8196: Add gce device node Add gce device node for mt8196. BUG=b:334735558 TEST=Build Pass Signed-off-by: Xavier Chang Signed-off-by: Jason-jh Lin Change-Id: I261c50669c2329d63ef9f133b659328b278144b7 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073704 Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 275c5827a69d6..498da32eb1ab2 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1228,6 +1229,22 @@ mediatek,skip-rpm-cb; }; + gce0: gce@300c0000 { + compatible = "mediatek,mt8196-gce"; + reg = <0 0x300c0000 0 0x80000>; + interrupts = ; + #mbox-cells = <2>; + iommus = <&mm_smmu 199>; + }; + + gce1: gce@30140000 { + compatible = "mediatek,mt8196-gce"; + reg = <0 0x30140000 0 0x80000>; + interrupts = ; + #mbox-cells = <2>; + iommus = <&mm_smmu 183>; + }; + mm_smmu: iommu@30800000 { compatible = "mediatek,mt8196-mm-smmu", "arm,smmu-v3"; reg = <0 0x30800000 0 0x1e0000>; -- GitLab From 9bd7a9ae7059fd250148630b5547f364c79030de Mon Sep 17 00:00:00 2001 From: Jason-jh Lin Date: Fri, 12 Jul 2024 17:34:50 +0800 Subject: [PATCH 346/456] CHROMIUM: arm64: dts: mt8196: Add secure mboxes to gce node Add secure mboxes property to gce node for SVP. BUG=b:340915552 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:353768019 Signed-off-by: Jason-JH.Lin Change-Id: I15710c316a28b258ddff30ea41734209fc17cd33 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4749988 Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Fei Shao Change-Id: I575b6e4498d50e95c9653fbeb1dbb1b49b517d56 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073705 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 498da32eb1ab2..09dbecc048311 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -1235,6 +1235,8 @@ interrupts = ; #mbox-cells = <2>; iommus = <&mm_smmu 199>; + mboxes = <&gce0 15 CMDQ_THR_PRIO_1>; + mediatek,gce-events = ; }; gce1: gce@30140000 { -- GitLab From 079ed129554bf4efa636dcbe65e93eb74a9765d9 Mon Sep 17 00:00:00 2001 From: William-tw Lin Date: Fri, 1 Mar 2024 17:37:20 +0800 Subject: [PATCH 347/456] CHROMIUM: arm64: dts: mt8196: Add node for efuse Added eFuse node to dts. BUG=b:387863132 TEST=build pass and boot to shell UPSTREAM-TASK=b:379034959 Signed-off-by: William-tw Lin Change-Id: Idbb0e65e5544ad66a0c80c8b41a43d963302728d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073720 Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 09dbecc048311..aa27b74af1ae2 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -722,6 +722,13 @@ #clock-cells = <1>; }; + efuse: efuse@13260000 { + compatible = "mediatek,mt8196-efuse", "mediatek,efuse"; + reg = <0 0x13260000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + }; + i2c1: i2c@13930000 { compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; reg = <0 0x13930000 0 0x80000>, -- GitLab From 9d33caedaa4bff4ba80693af13b8d5a410e00c7e Mon Sep 17 00:00:00 2001 From: Guangjie Song Date: Thu, 15 Aug 2024 19:59:24 +0800 Subject: [PATCH 348/456] CHROMIUM: clk: mediatek: modify common driver to support hwccf hwccf refers to using a voting mechanism to control the clock, where different CPUs can vote to determine the clock state without the need for software synchronization. BUG=b:383207708 UPSTREAM-TASK=b:354021544 TEST=build pass and bootup to shell Signed-off-by: Guangjie Song Change-Id: I2ec1497d443cc0c04829a1061c5d23e6f799750d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071725 Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/clk/mediatek/clk-gate.c | 224 +++++++++++++++++++++++++++++++- drivers/clk/mediatek/clk-gate.h | 6 + drivers/clk/mediatek/clk-mtk.h | 11 ++ drivers/clk/mediatek/clk-mux.c | 202 +++++++++++++++++++++++++++- drivers/clk/mediatek/clk-mux.h | 80 ++++++++++++ drivers/clk/mediatek/clk-pll.c | 52 +++++++- drivers/clk/mediatek/clk-pll.h | 5 + 7 files changed, 576 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 67d9e741c5e73..62640aba3669d 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -12,14 +12,19 @@ #include #include +#include "clk-mtk.h" #include "clk-gate.h" struct mtk_clk_gate { struct clk_hw hw; struct regmap *regmap; + struct regmap *hwv_regmap; int set_ofs; int clr_ofs; int sta_ofs; + int hwv_set_ofs; + int hwv_clr_ofs; + int hwv_sta_ofs; u8 bit; }; @@ -100,6 +105,144 @@ static void mtk_cg_disable_inv(struct clk_hw *hw) mtk_cg_clr_bit(hw); } +static int mtk_cg_is_set_hwv(struct clk_hw *hw) +{ + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val = 0; + + regmap_read(cg->hwv_regmap, cg->hwv_set_ofs, &val); + + val &= BIT(cg->bit); + + return val != 0; +} + +static int mtk_cg_is_done_hwv(struct clk_hw *hw) +{ + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val = 0; + + regmap_read(cg->hwv_regmap, cg->hwv_sta_ofs, &val); + + val &= BIT(cg->bit); + + return val != 0; +} + +static int __cg_enable_hwv(struct clk_hw *hw, bool inv) +{ + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val = 0, val2 = 0; + bool is_done = false; + int i = 0; + + regmap_write(cg->hwv_regmap, cg->hwv_set_ofs, + BIT(cg->bit)); + + while (!mtk_cg_is_set_hwv(hw)) { + if (i < MTK_WAIT_HWV_PREPARE_CNT) + udelay(MTK_WAIT_HWV_PREPARE_US); + else { + pr_err("%s cg prepare timeout\n", clk_hw_get_name(hw)); + return -EBUSY; + } + + i++; + } + + i = 0; + + while (1) { + if (!is_done) + regmap_read(cg->hwv_regmap, cg->hwv_sta_ofs, &val); + + if ((val & BIT(cg->bit)) != 0) + is_done = true; + + if (is_done) { + regmap_read(cg->regmap, cg->sta_ofs, &val2); + if ((inv && (val2 & BIT(cg->bit)) != 0) || + (!inv && (val2 & BIT(cg->bit)) == 0)) + break; + } + + if (i < MTK_WAIT_HWV_DONE_CNT) + udelay(MTK_WAIT_HWV_DONE_US); + else { + pr_err("%s cg enable timeout(%x %x)\n", clk_hw_get_name(hw), val, val2); + + if (inv) + regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); + else + regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); + + return -EBUSY; + } + + i++; + } + + return 0; +} + +static int mtk_cg_enable_hwv(struct clk_hw *hw) +{ + return __cg_enable_hwv(hw, false); +} + +static int mtk_cg_enable_hwv_inv(struct clk_hw *hw) +{ + return __cg_enable_hwv(hw, true); +} + +static void mtk_cg_disable_hwv(struct clk_hw *hw) +{ + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val; + int i = 0; + + /* dummy read to clr idle signal of hw voter bus */ + regmap_read(cg->hwv_regmap, cg->hwv_clr_ofs, &val); + + regmap_write(cg->hwv_regmap, cg->hwv_clr_ofs, BIT(cg->bit)); + + while (mtk_cg_is_set_hwv(hw)) { + if (i < MTK_WAIT_HWV_PREPARE_CNT) + udelay(MTK_WAIT_HWV_PREPARE_US); + else { + pr_err("%s cg unprepare timeout\n", clk_hw_get_name(hw)); + return; + } + + i++; + } + + i = 0; + + while (!mtk_cg_is_done_hwv(hw)) { + if (i < MTK_WAIT_HWV_DONE_CNT) + udelay(MTK_WAIT_HWV_DONE_US); + else { + pr_err("%s cg disable timeout\n", clk_hw_get_name(hw)); + return; + } + + i++; + } +} + +static void mtk_cg_disable_unused_hwv(struct clk_hw *hw) +{ + mtk_cg_enable_hwv(hw); + mtk_cg_disable_hwv(hw); +} + +static void mtk_cg_disable_unused_hwv_inv(struct clk_hw *hw) +{ + mtk_cg_enable_hwv_inv(hw); + mtk_cg_disable_hwv(hw); +} + static int mtk_cg_enable_no_setclr(struct clk_hw *hw) { mtk_cg_clr_bit_no_setclr(hw); @@ -131,6 +274,12 @@ const struct clk_ops mtk_clk_gate_ops_setclr = { }; EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr); +const struct clk_ops mtk_clk_gate_ops_setclr_enable = { + .is_enabled = mtk_cg_bit_is_cleared, + .enable = mtk_cg_enable, +}; +EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_enable); + const struct clk_ops mtk_clk_gate_ops_setclr_inv = { .is_enabled = mtk_cg_bit_is_set, .enable = mtk_cg_enable_inv, @@ -138,6 +287,21 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = { }; EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv); +const struct clk_ops mtk_clk_gate_ops_hwv = { + .is_enabled = mtk_cg_bit_is_cleared, + .enable = mtk_cg_enable_hwv, + .disable = mtk_cg_disable_hwv, + .disable_unused = mtk_cg_disable_unused_hwv, +}; +EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_hwv); + +const struct clk_ops mtk_clk_gate_ops_hwv_inv = { + .is_enabled = mtk_cg_bit_is_set, + .enable = mtk_cg_enable_hwv_inv, + .disable = mtk_cg_disable_hwv, + .disable_unused = mtk_cg_disable_unused_hwv_inv, +}; +EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_hwv_inv); const struct clk_ops mtk_clk_gate_ops_no_setclr = { .is_enabled = mtk_cg_bit_is_cleared, .enable = mtk_cg_enable_no_setclr, @@ -190,6 +354,54 @@ static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name return &cg->hw; } +static struct clk_hw *mtk_clk_register_gate_hwv( + struct device *dev, + const struct mtk_gate *gate, + struct regmap *regmap, + struct regmap *hwv_regmap) +{ + struct mtk_clk_gate *cg; + int ret; + struct clk_init_data init = {}; + + cg = kzalloc(sizeof(*cg), GFP_KERNEL); + if (!cg) + return ERR_PTR(-ENOMEM); + + init.name = gate->name; + init.flags = gate->flags | CLK_SET_RATE_PARENT; + init.parent_names = gate->parent_name ? &gate->parent_name : NULL; + init.num_parents = gate->parent_name ? 1 : 0; + if (hwv_regmap) + init.ops = gate->ops; + else + init.ops = gate->dma_ops; + + cg->regmap = regmap; + cg->hwv_regmap = hwv_regmap; + if (gate->regs) { + cg->set_ofs = gate->regs->set_ofs; + cg->clr_ofs = gate->regs->clr_ofs; + cg->sta_ofs = gate->regs->sta_ofs; + } + if (gate->hwv_regs) { + cg->hwv_set_ofs = gate->hwv_regs->set_ofs; + cg->hwv_clr_ofs = gate->hwv_regs->clr_ofs; + cg->hwv_sta_ofs = gate->hwv_regs->sta_ofs; + } + cg->bit = gate->shift; + + cg->hw.init = &init; + + ret = clk_hw_register(dev, &cg->hw); + if (ret) { + kfree(cg); + return ERR_PTR(ret); + } + + return &cg->hw; +} + static void mtk_clk_unregister_gate(struct clk_hw *hw) { struct mtk_clk_gate *cg; @@ -209,6 +421,7 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node, int i; struct clk_hw *hw; struct regmap *regmap; + struct regmap *hwv_regmap = NULL; if (!clk_data) return -ENOMEM; @@ -228,7 +441,16 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node, continue; } - hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name, + if (gate->flags & CLK_USE_HW_VOTER) { + if (gate->hwv_comp) { + hwv_regmap = syscon_regmap_lookup_by_phandle(node, gate->hwv_comp); + if (IS_ERR(hwv_regmap)) + hwv_regmap = NULL; + } + + hw = mtk_clk_register_gate_hwv(dev, gate, regmap, hwv_regmap); + } else + hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name, regmap, gate->regs->set_ofs, gate->regs->clr_ofs, diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index 1a46b4c56fc5d..1fbb1019b051e 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -16,9 +16,12 @@ struct device; struct device_node; extern const struct clk_ops mtk_clk_gate_ops_setclr; +extern const struct clk_ops mtk_clk_gate_ops_setclr_enable; extern const struct clk_ops mtk_clk_gate_ops_setclr_inv; extern const struct clk_ops mtk_clk_gate_ops_no_setclr; extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv; +extern const struct clk_ops mtk_clk_gate_ops_hwv; +extern const struct clk_ops mtk_clk_gate_ops_hwv_inv; struct mtk_gate_regs { u32 sta_ofs; @@ -30,9 +33,12 @@ struct mtk_gate { int id; const char *name; const char *parent_name; + const char *hwv_comp; const struct mtk_gate_regs *regs; + const struct mtk_gate_regs *hwv_regs; int shift; const struct clk_ops *ops; + const struct clk_ops *dma_ops; unsigned long flags; }; diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 0f76d9010bef8..b3cdc0fcbb485 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -20,6 +20,17 @@ #define MHZ (1000 * 1000) +/* hw voter timeout configures */ +#define MTK_WAIT_HWV_PREPARE_CNT 200000 +#define MTK_WAIT_HWV_PREPARE_US 1 +#define MTK_WAIT_HWV_DONE_CNT 5000000 +#define MTK_WAIT_HWV_DONE_US 1 +#define MTK_WAIT_FENC_DONE_CNT 5000000 +#define MTK_WAIT_FENC_DONE_US 1 + +#define CLK_USE_HW_VOTER BIT(30) +#define CLK_FENC_ENABLE BIT(31) + struct platform_device; /* diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index 60990296450bb..9bfa380a539b5 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -15,11 +15,13 @@ #include #include +#include "clk-mtk.h" #include "clk-mux.h" struct mtk_clk_mux { struct clk_hw hw; struct regmap *regmap; + struct regmap *hwv_regmap; const struct mtk_mux *data; spinlock_t *lock; bool reparent; @@ -30,6 +32,47 @@ static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw) return container_of(hw, struct mtk_clk_mux, hw); } +static int mtk_clk_mux_fenc_enable_setclr(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + unsigned long flags = 0; + u32 val = 0; + int i = 0; + int ret = 0; + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + else + __acquire(mux->lock); + + regmap_write(mux->regmap, mux->data->clr_ofs, + BIT(mux->data->gate_shift)); + + while (1) { + regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val); + + if ((val & BIT(mux->data->fenc_shift)) != 0) + break; + + if (i < MTK_WAIT_FENC_DONE_CNT) + udelay(MTK_WAIT_FENC_DONE_US); + else { + pr_err("%s wait fenc done timeout\n", clk_hw_get_name(hw)); + ret = -EBUSY; + break; + } + + i++; + } + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + else + __release(mux->lock); + + return ret; +} + static int mtk_clk_mux_enable_setclr(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -70,6 +113,16 @@ static void mtk_clk_mux_disable_setclr(struct clk_hw *hw) BIT(mux->data->gate_shift)); } +static int mtk_clk_mux_fenc_is_enabled(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val = 0; + + regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val); + + return (val & BIT(mux->data->fenc_shift)) != 0; +} + static int mtk_clk_mux_is_enabled(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -80,6 +133,110 @@ static int mtk_clk_mux_is_enabled(struct clk_hw *hw) return (val & BIT(mux->data->gate_shift)) == 0; } +static int mtk_clk_hwv_mux_is_enabled(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val = 0; + + regmap_read(mux->hwv_regmap, mux->data->hwv_set_ofs, &val); + + return (val & BIT(mux->data->gate_shift)) != 0; +} + +static int mtk_clk_hwv_mux_is_done(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val = 0; + + regmap_read(mux->hwv_regmap, mux->data->hwv_sta_ofs, &val); + + return (val & BIT(mux->data->gate_shift)) != 0; +} + +static int mtk_clk_hwv_mux_fenc_enable(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val = 0, val2 = 0; + bool is_done = false; + int i = 0; + + regmap_write(mux->hwv_regmap, mux->data->hwv_set_ofs, + BIT(mux->data->gate_shift)); + + while (!mtk_clk_hwv_mux_is_enabled(hw)) { + if (i < MTK_WAIT_HWV_PREPARE_CNT) + udelay(MTK_WAIT_HWV_PREPARE_US); + else { + pr_err("%s mux prepare timeout(%x)\n", clk_hw_get_name(hw), val); + return -EBUSY; + } + + i++; + } + + i = 0; + + while (1) { + if (!is_done) + regmap_read(mux->hwv_regmap, mux->data->hwv_sta_ofs, &val); + + if (((val & BIT(mux->data->gate_shift)) != 0)) + is_done = true; + + if (is_done) { + regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val2); + if ((val2 & BIT(mux->data->fenc_shift)) != 0) + break; + } + + if (i < MTK_WAIT_HWV_DONE_CNT) + udelay(MTK_WAIT_HWV_DONE_US); + else { + pr_err("%s mux enable timeout(%x %x)\n", clk_hw_get_name(hw), val, val2); + return -EBUSY; + } + + i++; + } + + return 0; +} + + +static void mtk_clk_hwv_mux_disable(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + int i = 0; + + regmap_write(mux->hwv_regmap, mux->data->hwv_clr_ofs, + BIT(mux->data->gate_shift)); + + while (mtk_clk_hwv_mux_is_enabled(hw)) { + if (i < MTK_WAIT_HWV_PREPARE_CNT) + udelay(MTK_WAIT_HWV_PREPARE_US); + else { + pr_err("%s mux unprepare timeout\n", clk_hw_get_name(hw)); + return; + } + + i++; + } + + i = 0; + + while (!mtk_clk_hwv_mux_is_done(hw)) { + if (i < MTK_WAIT_HWV_DONE_CNT) + udelay(MTK_WAIT_HWV_DONE_US); + else { + pr_err("%s mux disable timeout\n", clk_hw_get_name(hw)); + return; + } + + i++; + } + +} + static u8 mtk_clk_mux_get_parent(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -151,6 +308,12 @@ static int mtk_clk_mux_determine_rate(struct clk_hw *hw, return clk_mux_determine_rate_flags(hw, req, mux->data->flags); } +static void mtk_clk_hwv_mux_fenc_disable_unused(struct clk_hw *hw) +{ + mtk_clk_hwv_mux_fenc_enable(hw); + mtk_clk_hwv_mux_disable(hw); +} + const struct clk_ops mtk_mux_clr_set_upd_ops = { .get_parent = mtk_clk_mux_get_parent, .set_parent = mtk_clk_mux_set_parent_setclr_lock, @@ -168,9 +331,31 @@ const struct clk_ops mtk_mux_gate_clr_set_upd_ops = { }; EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops); +const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops = { + .enable = mtk_clk_mux_fenc_enable_setclr, + .disable = mtk_clk_mux_disable_setclr, + .is_enabled = mtk_clk_mux_fenc_is_enabled, + .get_parent = mtk_clk_mux_get_parent, + .set_parent = mtk_clk_mux_set_parent_setclr_lock, + .determine_rate = mtk_clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(mtk_mux_gate_fenc_clr_set_upd_ops); + +const struct clk_ops mtk_hwv_mux_fenc_ops = { + .enable = mtk_clk_hwv_mux_fenc_enable, + .disable = mtk_clk_hwv_mux_disable, + .is_enabled = mtk_clk_mux_fenc_is_enabled, + .get_parent = mtk_clk_mux_get_parent, + .set_parent = mtk_clk_mux_set_parent_setclr_lock, + .determine_rate = mtk_clk_mux_determine_rate, + .disable_unused = mtk_clk_hwv_mux_fenc_disable_unused, +}; +EXPORT_SYMBOL_GPL(mtk_hwv_mux_fenc_ops); + static struct clk_hw *mtk_clk_register_mux(struct device *dev, const struct mtk_mux *mux, struct regmap *regmap, + struct regmap *hwv_regmap, spinlock_t *lock) { struct mtk_clk_mux *clk_mux; @@ -185,9 +370,16 @@ static struct clk_hw *mtk_clk_register_mux(struct device *dev, init.flags = mux->flags; init.parent_names = mux->parent_names; init.num_parents = mux->num_parents; - init.ops = mux->ops; + if (mux->flags & CLK_USE_HW_VOTER) { + if (hwv_regmap) + init.ops = mux->ops; + else + init.ops = mux->dma_ops; + } else + init.ops = mux->ops; clk_mux->regmap = regmap; + clk_mux->hwv_regmap = hwv_regmap; clk_mux->data = mux; clk_mux->lock = lock; clk_mux->hw.init = &init; @@ -220,6 +412,7 @@ int mtk_clk_register_muxes(struct device *dev, struct clk_hw_onecell_data *clk_data) { struct regmap *regmap; + struct regmap *hwv_regmap = NULL; struct clk_hw *hw; int i; @@ -238,8 +431,13 @@ int mtk_clk_register_muxes(struct device *dev, continue; } - hw = mtk_clk_register_mux(dev, mux, regmap, lock); + if (mux->hwv_comp) { + hwv_regmap = syscon_regmap_lookup_by_phandle(node, mux->hwv_comp); + if (IS_ERR(hwv_regmap)) + hwv_regmap = NULL; + } + hw = mtk_clk_register_mux(dev, mux, regmap, hwv_regmap, lock); if (IS_ERR(hw)) { pr_err("Failed to register clk %s: %pe\n", mux->name, hw); diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h index 943ad1d7ce4be..b4f6212cb2454 100644 --- a/drivers/clk/mediatek/clk-mux.h +++ b/drivers/clk/mediatek/clk-mux.h @@ -21,6 +21,7 @@ struct mtk_mux { int id; const char *name; const char * const *parent_names; + const char *hwv_comp; const u8 *parent_index; unsigned int flags; @@ -28,13 +29,20 @@ struct mtk_mux { u32 set_ofs; u32 clr_ofs; u32 upd_ofs; + u32 hwv_set_ofs; + u32 hwv_clr_ofs; + u32 hwv_sta_ofs; + u32 fenc_sta_mon_ofs; u8 mux_shift; u8 mux_width; u8 gate_shift; s8 upd_shift; + u8 fenc_shift; const struct clk_ops *ops; + const struct clk_ops *dma_ops; + signed char num_parents; }; @@ -77,6 +85,8 @@ struct mtk_mux { extern const struct clk_ops mtk_mux_clr_set_upd_ops; extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; +extern const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops; +extern const struct clk_ops mtk_hwv_mux_fenc_ops; #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ @@ -118,6 +128,76 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ mtk_mux_clr_set_upd_ops) +#define MUX_MULT_HWV_FENC_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _hwv_comp,\ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, _flags) { \ + .id = _id, \ + .name = _name, \ + .mux_ofs = _mux_ofs, \ + .set_ofs = _mux_set_ofs, \ + .clr_ofs = _mux_clr_ofs, \ + .hwv_comp = _hwv_comp, \ + .hwv_sta_ofs = _hwv_sta_ofs, \ + .hwv_set_ofs = _hwv_set_ofs, \ + .hwv_clr_ofs = _hwv_clr_ofs, \ + .upd_ofs = _upd_ofs, \ + .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \ + .mux_shift = _shift, \ + .mux_width = _width, \ + .gate_shift = _gate, \ + .upd_shift = _upd, \ + .fenc_shift = _fenc, \ + .parent_names = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_USE_HW_VOTER | _flags, \ + .ops = &mtk_hwv_mux_fenc_ops, \ + .dma_ops = &mtk_mux_gate_fenc_clr_set_upd_ops, \ + } + +#define MUX_MULT_HWV_FENC(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _hwv_comp,\ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc) \ + MUX_MULT_HWV_FENC_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _hwv_comp,\ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, 0) + +#define MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, _flags) { \ + .id = _id, \ + .name = _name, \ + .mux_ofs = _mux_ofs, \ + .set_ofs = _mux_set_ofs, \ + .clr_ofs = _mux_clr_ofs, \ + .upd_ofs = _upd_ofs, \ + .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \ + .mux_shift = _shift, \ + .mux_width = _width, \ + .gate_shift = _gate, \ + .upd_shift = _upd, \ + .fenc_shift = _fenc, \ + .parent_names = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = _flags, \ + .ops = &mtk_mux_gate_fenc_clr_set_upd_ops, \ + } + +#define MUX_GATE_FENC_CLR_SET_UPD(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc) \ + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, 0) + int mtk_clk_register_muxes(struct device *dev, const struct mtk_mux *muxes, int num, struct device_node *node, diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 513ab6b1b3229..593d58e05107f 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -13,6 +13,7 @@ #include #include +#include "clk-mtk.h" #include "clk-pll.h" #define MHZ (1000 * 1000) @@ -37,6 +38,13 @@ int mtk_pll_is_prepared(struct clk_hw *hw) return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0; } +static int mtk_pll_fenc_is_prepared(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + return (((readl(pll->fenc_addr) & pll->fenc_mask) != 0) || (pll->onoff_cnt != 0)); +} + static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin, u32 pcw, int postdiv) { @@ -273,6 +281,31 @@ void mtk_pll_unprepare(struct clk_hw *hw) writel(r, pll->pwr_addr); } +static int mtk_pll_fenc_prepare(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + if (pll->onoff_cnt == 1) { + pr_err("%s: %s is already prepared\n", __func__, clk_hw_get_name(hw)); + return -EPERM; + } + + pll->onoff_cnt = 1; + + return 0; +} + +static void mtk_pll_fenc_unprepare(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + if (pll->onoff_cnt == 0) + pr_err("%s: %s is not prepared\n", __func__, clk_hw_get_name(hw)); + else + pll->onoff_cnt = 0; + +} + const struct clk_ops mtk_pll_ops = { .is_prepared = mtk_pll_is_prepared, .prepare = mtk_pll_prepare, @@ -282,6 +315,15 @@ const struct clk_ops mtk_pll_ops = { .set_rate = mtk_pll_set_rate, }; +static const struct clk_ops mtk_pll_fenc_ops = { + .is_prepared = mtk_pll_fenc_is_prepared, + .prepare = mtk_pll_fenc_prepare, + .unprepare = mtk_pll_fenc_unprepare, + .recalc_rate = mtk_pll_recalc_rate, + .round_rate = mtk_pll_round_rate, + .set_rate = mtk_pll_set_rate, +}; + struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, const struct mtk_pll_data *data, void __iomem *base, @@ -312,6 +354,11 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, init.name = data->name; init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0; + if (data->flags & CLK_FENC_ENABLE) { + pll->fenc_addr = base + data->fenc_sta_ofs; + pll->fenc_mask = BIT(data->fenc_sta_bit); + } + init.ops = pll_ops; if (data->parent_name) init.parent_names = &data->parent_name; @@ -337,7 +384,10 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, if (!pll) return ERR_PTR(-ENOMEM); - hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops); + if (data->flags & CLK_FENC_ENABLE) + hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_fenc_ops); + else + hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops); if (IS_ERR(hw)) kfree(pll); diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index f17278ff15d78..1d1e1708cbcd4 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -29,6 +29,7 @@ struct mtk_pll_data { u32 reg; u32 pwr_reg; u32 en_mask; + uint32_t fenc_sta_ofs; u32 pd_reg; u32 tuner_reg; u32 tuner_en_reg; @@ -48,6 +49,7 @@ struct mtk_pll_data { const char *parent_name; u32 en_reg; u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */ + u8 fenc_sta_bit; }; /* @@ -68,6 +70,9 @@ struct mtk_clk_pll { void __iomem *pcw_chg_addr; void __iomem *en_addr; const struct mtk_pll_data *data; + void __iomem *fenc_addr; + u32 fenc_mask; + u32 onoff_cnt; }; int mtk_clk_register_plls(struct device_node *node, -- GitLab From 15794c3dac76d3db326bce0dcedb98ceaffadf83 Mon Sep 17 00:00:00 2001 From: Guangjie Song Date: Thu, 15 Aug 2024 20:05:05 +0800 Subject: [PATCH 349/456] CHROMIUM: clk: mediatek: add mt8196 clock driver add mt8196 clock driver BUG=b:383207708 BUG=b:369287566 BUG=b:377628718 BUG=b:376509056 TEST=build pass and bootup to shell TEST=Change Display Resolution UPSTREAM-TASK=b:354021544 Signed-off-by: Guangjie Song Change-Id: Icdac4f9b69ded79f588732230cea6f46b15043ba Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6071726 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/clk/mediatek/Kconfig | 86 + drivers/clk/mediatek/Makefile | 15 + drivers/clk/mediatek/clk-mt8196-adsp.c | 414 +++++ drivers/clk/mediatek/clk-mt8196-apifrbus_ao.c | 71 + drivers/clk/mediatek/clk-mt8196-apmixedsys.c | 149 ++ .../clk/mediatek/clk-mt8196-apmixedsys_gp2.c | 157 ++ drivers/clk/mediatek/clk-mt8196-disp0.c | 366 ++++ drivers/clk/mediatek/clk-mt8196-disp1.c | 370 +++++ .../clk/mediatek/clk-mt8196-imp_iic_wrap.c | 242 +++ drivers/clk/mediatek/clk-mt8196-mcu.c | 171 ++ drivers/clk/mediatek/clk-mt8196-mdpsys.c | 514 ++++++ drivers/clk/mediatek/clk-mt8196-mfg.c | 148 ++ drivers/clk/mediatek/clk-mt8196-ovl0.c | 382 +++++ drivers/clk/mediatek/clk-mt8196-ovl1.c | 382 +++++ drivers/clk/mediatek/clk-mt8196-peri_ao.c | 272 +++ drivers/clk/mediatek/clk-mt8196-pextp.c | 192 +++ drivers/clk/mediatek/clk-mt8196-topckgen.c | 1469 +++++++++++++++++ drivers/clk/mediatek/clk-mt8196-topckgen2.c | 835 ++++++++++ drivers/clk/mediatek/clk-mt8196-ufs_ao.c | 121 ++ drivers/clk/mediatek/clk-mt8196-vdec.c | 484 ++++++ drivers/clk/mediatek/clk-mt8196-vdisp_ao.c | 106 ++ drivers/clk/mediatek/clk-mt8196-venc.c | 474 ++++++ drivers/clk/mediatek/clk-mt8196-vlpckgen.c | 786 +++++++++ 23 files changed, 8206 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8196-adsp.c create mode 100644 drivers/clk/mediatek/clk-mt8196-apifrbus_ao.c create mode 100644 drivers/clk/mediatek/clk-mt8196-apmixedsys.c create mode 100644 drivers/clk/mediatek/clk-mt8196-apmixedsys_gp2.c create mode 100644 drivers/clk/mediatek/clk-mt8196-disp0.c create mode 100644 drivers/clk/mediatek/clk-mt8196-disp1.c create mode 100644 drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c create mode 100644 drivers/clk/mediatek/clk-mt8196-mcu.c create mode 100644 drivers/clk/mediatek/clk-mt8196-mdpsys.c create mode 100644 drivers/clk/mediatek/clk-mt8196-mfg.c create mode 100644 drivers/clk/mediatek/clk-mt8196-ovl0.c create mode 100644 drivers/clk/mediatek/clk-mt8196-ovl1.c create mode 100644 drivers/clk/mediatek/clk-mt8196-peri_ao.c create mode 100644 drivers/clk/mediatek/clk-mt8196-pextp.c create mode 100644 drivers/clk/mediatek/clk-mt8196-topckgen.c create mode 100644 drivers/clk/mediatek/clk-mt8196-topckgen2.c create mode 100644 drivers/clk/mediatek/clk-mt8196-ufs_ao.c create mode 100644 drivers/clk/mediatek/clk-mt8196-vdec.c create mode 100644 drivers/clk/mediatek/clk-mt8196-vdisp_ao.c create mode 100644 drivers/clk/mediatek/clk-mt8196-venc.c create mode 100644 drivers/clk/mediatek/clk-mt8196-vlpckgen.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 8ad02c1f035b3..d541f70dcd7c4 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -956,6 +956,92 @@ config COMMON_CLK_MT8195_VENCSYS help This driver supports MediaTek MT8195 vencsys clocks. +config COMMON_CLK_MT8196 + tristate "Clock driver for MediaTek MT8196" + depends on ARM64 || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default MACH_MT8196 + help + This driver supports MediaTek MT8196 basic clocks. + +config COMMON_CLK_MT8196_ADSP + tristate "Clock driver for MediaTek MT8196 adsp" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 adsp clocks + +config COMMON_CLK_MT8196_APIFRBUS + tristate "Clock driver for MediaTek MT8196 apifrbus" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 apifrbus clocks + +config COMMON_CLK_MT8196_CAMSYS + tristate "Clock driver for MediaTek MT8196 camsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 camsys clocks. + +config COMMON_CLK_MT8196_IMGSYS + tristate "Clock driver for MediaTek MT8196 imgsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 imgsys clocks. + +config COMMON_CLK_MT8196_IMP_IIC_WRAP + tristate "Clock driver for MediaTek MT8196 imp_iic_wrap" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 i2c clocks. + +config COMMON_CLK_MT8196_MCUSYS + tristate "Clock driver for MediaTek MT8196 mcusys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mcusys clocks. + +config COMMON_CLK_MT8196_MDPSYS + tristate "Clock driver for MediaTek MT8196 mdpsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mdpsys clocks. + +config COMMON_CLK_MT8196_MFGCFG + tristate "Clock driver for MediaTek MT8196 mfgcfg" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mfgcfg clocks. + +config COMMON_CLK_MT8196_MMSYS + tristate "Clock driver for MediaTek MT8196 mmsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mmsys clocks. + +config COMMON_CLK_MT8196_PEXTPSYS + tristate "Clock driver for MediaTek MT8196 pextpsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 pextpsys clocks. + +config COMMON_CLK_MT8196_VDECSYS + tristate "Clock driver for MediaTek MT8196 vdecsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 vdecsys clocks. + +config COMMON_CLK_MT8196_VENCSYS + tristate "Clock driver for MediaTek MT8196 vencsys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 vencsys clocks. + +config COMMON_CLK_MT8196_UFSSYS + tristate "Clock driver for MediaTek MT8196 ufssys" + depends on COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 ufssys clocks. + config COMMON_CLK_MT8365 tristate "Clock driver for MediaTek MT8365" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index dbeaa5b41177d..f17badea1a463 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -140,6 +140,21 @@ obj-$(CONFIG_COMMON_CLK_MT8195_VDOSYS) += clk-mt8195-vdo0.o clk-mt8195-vdo1.o obj-$(CONFIG_COMMON_CLK_MT8195_VENCSYS) += clk-mt8195-venc.o obj-$(CONFIG_COMMON_CLK_MT8195_VPPSYS) += clk-mt8195-vpp0.o clk-mt8195-vpp1.o obj-$(CONFIG_COMMON_CLK_MT8195_WPESYS) += clk-mt8195-wpe.o +obj-$(CONFIG_COMMON_CLK_MT8196) += clk-mt8196-apmixedsys.o clk-mt8196-apmixedsys_gp2.o \ + clk-mt8196-topckgen.o clk-mt8196-topckgen2.o clk-mt8196-vlpckgen.o \ + clk-mt8196-peri_ao.o +obj-$(CONFIG_COMMON_CLK_MT8196_ADSP) += clk-mt8196-adsp.o +obj-$(CONFIG_COMMON_CLK_MT8196_APIFRBUS) += clk-mt8196-apifrbus_ao.o +obj-$(CONFIG_COMMON_CLK_MT8196_IMP_IIC_WRAP) += clk-mt8196-imp_iic_wrap.o +obj-$(CONFIG_COMMON_CLK_MT8196_MCUSYS) += clk-mt8196-mcu.o +obj-$(CONFIG_COMMON_CLK_MT8196_MDPSYS) += clk-mt8196-mdpsys.o +obj-$(CONFIG_COMMON_CLK_MT8196_MFGCFG) += clk-mt8196-mfg.o +obj-$(CONFIG_COMMON_CLK_MT8196_MMSYS) += clk-mt8196-disp0.o clk-mt8196-disp1.o \ + clk-mt8196-vdisp_ao.o clk-mt8196-ovl0.o clk-mt8196-ovl1.o +obj-$(CONFIG_COMMON_CLK_MT8196_PEXTPSYS) += clk-mt8196-pextp.o +obj-$(CONFIG_COMMON_CLK_MT8196_UFSSYS) += clk-mt8196-ufs_ao.o +obj-$(CONFIG_COMMON_CLK_MT8196_VDECSYS) += clk-mt8196-vdec.o +obj-$(CONFIG_COMMON_CLK_MT8196_VENCSYS) += clk-mt8196-venc.o obj-$(CONFIG_COMMON_CLK_MT8365) += clk-mt8365-apmixedsys.o clk-mt8365.o obj-$(CONFIG_COMMON_CLK_MT8365_APU) += clk-mt8365-apu.o obj-$(CONFIG_COMMON_CLK_MT8365_CAM) += clk-mt8365-cam.o diff --git a/drivers/clk/mediatek/clk-mt8196-adsp.c b/drivers/clk/mediatek/clk-mt8196-adsp.c new file mode 100644 index 0000000000000..92ed781729cd2 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-adsp.c @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Chong-ming Wei + */ + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs afe0_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x0, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs afe1_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x10, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs afe2_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x4, + .sta_ofs = 0x4, +}; + +static const struct mtk_gate_regs afe3_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0x8, + .sta_ofs = 0x8, +}; + +static const struct mtk_gate_regs afe4_cg_regs = { + .set_ofs = 0xc, + .clr_ofs = 0xc, + .sta_ofs = 0xc, +}; + +#define GATE_AFE0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &afe0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AFE0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_AFE1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &afe1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AFE1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_AFE2(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &afe2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AFE2_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_AFE3(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &afe3_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AFE3_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_AFE4(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &afe4_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AFE4_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate afe_clks[] = { + /* AFE0 */ + GATE_AFE0(CLK_AFE_PCM1, "afe_pcm1", + "vlp_aud_clksq_ck", 13), + GATE_AFE0_V(CLK_AFE_PCM1_AFE, "afe_pcm1_afe", + "afe_pcm1"), + GATE_AFE0(CLK_AFE_PCM0, "afe_pcm0", + "vlp_aud_clksq_ck", 14), + GATE_AFE0_V(CLK_AFE_PCM0_AFE, "afe_pcm0_afe", + "afe_pcm0"), + GATE_AFE0(CLK_AFE_CM2, "afe_cm2", + "vlp_aud_clksq_ck", 16), + GATE_AFE0_V(CLK_AFE_CM2_AFE, "afe_cm2_afe", + "afe_cm2"), + GATE_AFE0(CLK_AFE_CM1, "afe_cm1", + "vlp_aud_clksq_ck", 17), + GATE_AFE0_V(CLK_AFE_CM1_AFE, "afe_cm1_afe", + "afe_cm1"), + GATE_AFE0(CLK_AFE_CM0, "afe_cm0", + "vlp_aud_clksq_ck", 18), + GATE_AFE0_V(CLK_AFE_CM0_AFE, "afe_cm0_afe", + "afe_cm0"), + GATE_AFE0(CLK_AFE_STF, "afe_stf", + "vlp_aud_clksq_ck", 19), + GATE_AFE0_V(CLK_AFE_STF_AFE, "afe_stf_afe", + "afe_stf"), + GATE_AFE0(CLK_AFE_HW_GAIN23, "afe_hw_gain23", + "vlp_aud_clksq_ck", 20), + GATE_AFE0_V(CLK_AFE_HW_GAIN23_AFE, "afe_hw_gain23_afe", + "afe_hw_gain23"), + GATE_AFE0(CLK_AFE_HW_GAIN01, "afe_hw_gain01", + "vlp_aud_clksq_ck", 21), + GATE_AFE0_V(CLK_AFE_HW_GAIN01_AFE, "afe_hw_gain01_afe", + "afe_hw_gain01"), + GATE_AFE0(CLK_AFE_FM_I2S, "afe_fm_i2s", + "vlp_aud_clksq_ck", 24), + GATE_AFE0_V(CLK_AFE_FM_I2S_AFE, "afe_fm_i2s_afe", + "afe_fm_i2s"), + GATE_AFE0(CLK_AFE_MTKAIFV4, "afe_mtkaifv4", + "vlp_aud_clksq_ck", 25), + GATE_AFE0_V(CLK_AFE_MTKAIFV4_AFE, "afe_mtkaifv4_afe", + "afe_mtkaifv4"), + /* AFE1 */ + GATE_AFE1(CLK_AFE_AUDIO_HOPPING, "afe_audio_hopping_ck", + "vlp_aud_clksq_ck", 0), + GATE_AFE1_V(CLK_AFE_AUDIO_HOPPING_AFE, "afe_audio_hopping_ck_afe", + "afe_audio_hopping_ck"), + GATE_AFE1(CLK_AFE_AUDIO_F26M, "afe_audio_f26m_ck", + "vlp_aud_clksq_ck", 1), + GATE_AFE1_V(CLK_AFE_AUDIO_F26M_AFE, "afe_audio_f26m_ck_afe", + "afe_audio_f26m_ck"), + GATE_AFE1(CLK_AFE_APLL1, "afe_apll1_ck", + "ck_aud_1_ck", 2), + GATE_AFE1_V(CLK_AFE_APLL1_AFE, "afe_apll1_ck_afe", + "afe_apll1_ck"), + GATE_AFE1(CLK_AFE_APLL2, "afe_apll2_ck", + "ck_aud_2_ck", 3), + GATE_AFE1_V(CLK_AFE_APLL2_AFE, "afe_apll2_ck_afe", + "afe_apll2_ck"), + GATE_AFE1(CLK_AFE_H208M, "afe_h208m_ck", + "vlp_audio_h_ck", 4), + GATE_AFE1_V(CLK_AFE_H208M_AFE, "afe_h208m_ck_afe", + "afe_h208m_ck"), + GATE_AFE1(CLK_AFE_APLL_TUNER2, "afe_apll_tuner2", + "vlp_aud_engen2_ck", 12), + GATE_AFE1_V(CLK_AFE_APLL_TUNER2_AFE, "afe_apll_tuner2_afe", + "afe_apll_tuner2"), + GATE_AFE1(CLK_AFE_APLL_TUNER1, "afe_apll_tuner1", + "vlp_aud_engen1_ck", 13), + GATE_AFE1_V(CLK_AFE_APLL_TUNER1_AFE, "afe_apll_tuner1_afe", + "afe_apll_tuner1"), + /* AFE2 */ + GATE_AFE2(CLK_AFE_UL2_ADC_HIRES_TML, "afe_ul2_aht", + "vlp_audio_h_ck", 12), + GATE_AFE2_V(CLK_AFE_UL2_ADC_HIRES_TML_AFE, "afe_ul2_aht_afe", + "afe_ul2_aht"), + GATE_AFE2(CLK_AFE_UL2_ADC_HIRES, "afe_ul2_adc_hires", + "vlp_audio_h_ck", 13), + GATE_AFE2_V(CLK_AFE_UL2_ADC_HIRES_AFE, "afe_ul2_adc_hires_afe", + "afe_ul2_adc_hires"), + GATE_AFE2(CLK_AFE_UL2_TML, "afe_ul2_tml", + "vlp_aud_clksq_ck", 14), + GATE_AFE2_V(CLK_AFE_UL2_TML_AFE, "afe_ul2_tml_afe", + "afe_ul2_tml"), + GATE_AFE2(CLK_AFE_UL2_ADC, "afe_ul2_adc", + "vlp_aud_clksq_ck", 15), + GATE_AFE2_V(CLK_AFE_UL2_ADC_AFE, "afe_ul2_adc_afe", + "afe_ul2_adc"), + GATE_AFE2(CLK_AFE_UL1_ADC_HIRES_TML, "afe_ul1_aht", + "vlp_audio_h_ck", 16), + GATE_AFE2_V(CLK_AFE_UL1_ADC_HIRES_TML_AFE, "afe_ul1_aht_afe", + "afe_ul1_aht"), + GATE_AFE2(CLK_AFE_UL1_ADC_HIRES, "afe_ul1_adc_hires", + "vlp_audio_h_ck", 17), + GATE_AFE2_V(CLK_AFE_UL1_ADC_HIRES_AFE, "afe_ul1_adc_hires_afe", + "afe_ul1_adc_hires"), + GATE_AFE2(CLK_AFE_UL1_TML, "afe_ul1_tml", + "vlp_aud_clksq_ck", 18), + GATE_AFE2_V(CLK_AFE_UL1_TML_AFE, "afe_ul1_tml_afe", + "afe_ul1_tml"), + GATE_AFE2(CLK_AFE_UL1_ADC, "afe_ul1_adc", + "vlp_aud_clksq_ck", 19), + GATE_AFE2_V(CLK_AFE_UL1_ADC_AFE, "afe_ul1_adc_afe", + "afe_ul1_adc"), + GATE_AFE2(CLK_AFE_UL0_ADC_HIRES_TML, "afe_ul0_aht", + "vlp_audio_h_ck", 20), + GATE_AFE2_V(CLK_AFE_UL0_ADC_HIRES_TML_AFE, "afe_ul0_aht_afe", + "afe_ul0_aht"), + GATE_AFE2(CLK_AFE_UL0_ADC_HIRES, "afe_ul0_adc_hires", + "vlp_audio_h_ck", 21), + GATE_AFE2_V(CLK_AFE_UL0_ADC_HIRES_AFE, "afe_ul0_adc_hires_afe", + "afe_ul0_adc_hires"), + GATE_AFE2(CLK_AFE_UL0_TML, "afe_ul0_tml", + "vlp_aud_clksq_ck", 22), + GATE_AFE2_V(CLK_AFE_UL0_TML_AFE, "afe_ul0_tml_afe", + "afe_ul0_tml"), + GATE_AFE2(CLK_AFE_UL0_ADC, "afe_ul0_adc", + "vlp_aud_clksq_ck", 23), + GATE_AFE2_V(CLK_AFE_UL0_ADC_AFE, "afe_ul0_adc_afe", + "afe_ul0_adc"), + /* AFE3 */ + GATE_AFE3(CLK_AFE_ETDM_IN6, "afe_etdm_in6", + "vlp_aud_clksq_ck", 7), + GATE_AFE3_V(CLK_AFE_ETDM_IN6_AFE, "afe_etdm_in6_afe", + "afe_etdm_in6"), + GATE_AFE3(CLK_AFE_ETDM_IN5, "afe_etdm_in5", + "vlp_aud_clksq_ck", 8), + GATE_AFE3_V(CLK_AFE_ETDM_IN5_AFE, "afe_etdm_in5_afe", + "afe_etdm_in5"), + GATE_AFE3(CLK_AFE_ETDM_IN4, "afe_etdm_in4", + "vlp_aud_clksq_ck", 9), + GATE_AFE3_V(CLK_AFE_ETDM_IN4_AFE, "afe_etdm_in4_afe", + "afe_etdm_in4"), + GATE_AFE3(CLK_AFE_ETDM_IN3, "afe_etdm_in3", + "vlp_aud_clksq_ck", 10), + GATE_AFE3_V(CLK_AFE_ETDM_IN3_AFE, "afe_etdm_in3_afe", + "afe_etdm_in3"), + GATE_AFE3(CLK_AFE_ETDM_IN2, "afe_etdm_in2", + "vlp_aud_clksq_ck", 11), + GATE_AFE3_V(CLK_AFE_ETDM_IN2_AFE, "afe_etdm_in2_afe", + "afe_etdm_in2"), + GATE_AFE3(CLK_AFE_ETDM_IN1, "afe_etdm_in1", + "vlp_aud_clksq_ck", 12), + GATE_AFE3_V(CLK_AFE_ETDM_IN1_AFE, "afe_etdm_in1_afe", + "afe_etdm_in1"), + GATE_AFE3(CLK_AFE_ETDM_IN0, "afe_etdm_in0", + "vlp_aud_clksq_ck", 13), + GATE_AFE3_V(CLK_AFE_ETDM_IN0_AFE, "afe_etdm_in0_afe", + "afe_etdm_in0"), + GATE_AFE3(CLK_AFE_ETDM_OUT6, "afe_etdm_out6", + "vlp_aud_clksq_ck", 15), + GATE_AFE3_V(CLK_AFE_ETDM_OUT6_AFE, "afe_etdm_out6_afe", + "afe_etdm_out6"), + GATE_AFE3(CLK_AFE_ETDM_OUT5, "afe_etdm_out5", + "vlp_aud_clksq_ck", 16), + GATE_AFE3_V(CLK_AFE_ETDM_OUT5_AFE, "afe_etdm_out5_afe", + "afe_etdm_out5"), + GATE_AFE3(CLK_AFE_ETDM_OUT4, "afe_etdm_out4", + "vlp_aud_clksq_ck", 17), + GATE_AFE3_V(CLK_AFE_ETDM_OUT4_AFE, "afe_etdm_out4_afe", + "afe_etdm_out4"), + GATE_AFE3(CLK_AFE_ETDM_OUT3, "afe_etdm_out3", + "vlp_aud_clksq_ck", 18), + GATE_AFE3_V(CLK_AFE_ETDM_OUT3_AFE, "afe_etdm_out3_afe", + "afe_etdm_out3"), + GATE_AFE3(CLK_AFE_ETDM_OUT2, "afe_etdm_out2", + "vlp_aud_clksq_ck", 19), + GATE_AFE3_V(CLK_AFE_ETDM_OUT2_AFE, "afe_etdm_out2_afe", + "afe_etdm_out2"), + GATE_AFE3(CLK_AFE_ETDM_OUT1, "afe_etdm_out1", + "vlp_aud_clksq_ck", 20), + GATE_AFE3_V(CLK_AFE_ETDM_OUT1_AFE, "afe_etdm_out1_afe", + "afe_etdm_out1"), + GATE_AFE3(CLK_AFE_ETDM_OUT0, "afe_etdm_out0", + "vlp_aud_clksq_ck", 21), + GATE_AFE3_V(CLK_AFE_ETDM_OUT0_AFE, "afe_etdm_out0_afe", + "afe_etdm_out0"), + GATE_AFE3(CLK_AFE_TDM_OUT, "afe_tdm_out", + "ck_aud_1_ck", 24), + GATE_AFE3_V(CLK_AFE_TDM_OUT_AFE, "afe_tdm_out_afe", + "afe_tdm_out"), + /* AFE4 */ + GATE_AFE4(CLK_AFE_GENERAL15_ASRC, "afe_general15_asrc", + "vlp_aud_clksq_ck", 9), + GATE_AFE4_V(CLK_AFE_GENERAL15_ASRC_AFE, "afe_general15_asrc_afe", + "afe_general15_asrc"), + GATE_AFE4(CLK_AFE_GENERAL14_ASRC, "afe_general14_asrc", + "vlp_aud_clksq_ck", 10), + GATE_AFE4_V(CLK_AFE_GENERAL14_ASRC_AFE, "afe_general14_asrc_afe", + "afe_general14_asrc"), + GATE_AFE4(CLK_AFE_GENERAL13_ASRC, "afe_general13_asrc", + "vlp_aud_clksq_ck", 11), + GATE_AFE4_V(CLK_AFE_GENERAL13_ASRC_AFE, "afe_general13_asrc_afe", + "afe_general13_asrc"), + GATE_AFE4(CLK_AFE_GENERAL12_ASRC, "afe_general12_asrc", + "vlp_aud_clksq_ck", 12), + GATE_AFE4_V(CLK_AFE_GENERAL12_ASRC_AFE, "afe_general12_asrc_afe", + "afe_general12_asrc"), + GATE_AFE4(CLK_AFE_GENERAL11_ASRC, "afe_general11_asrc", + "vlp_aud_clksq_ck", 13), + GATE_AFE4_V(CLK_AFE_GENERAL11_ASRC_AFE, "afe_general11_asrc_afe", + "afe_general11_asrc"), + GATE_AFE4(CLK_AFE_GENERAL10_ASRC, "afe_general10_asrc", + "vlp_aud_clksq_ck", 14), + GATE_AFE4_V(CLK_AFE_GENERAL10_ASRC_AFE, "afe_general10_asrc_afe", + "afe_general10_asrc"), + GATE_AFE4(CLK_AFE_GENERAL9_ASRC, "afe_general9_asrc", + "vlp_aud_clksq_ck", 15), + GATE_AFE4_V(CLK_AFE_GENERAL9_ASRC_AFE, "afe_general9_asrc_afe", + "afe_general9_asrc"), + GATE_AFE4(CLK_AFE_GENERAL8_ASRC, "afe_general8_asrc", + "vlp_aud_clksq_ck", 16), + GATE_AFE4_V(CLK_AFE_GENERAL8_ASRC_AFE, "afe_general8_asrc_afe", + "afe_general8_asrc"), + GATE_AFE4(CLK_AFE_GENERAL7_ASRC, "afe_general7_asrc", + "vlp_aud_clksq_ck", 17), + GATE_AFE4_V(CLK_AFE_GENERAL7_ASRC_AFE, "afe_general7_asrc_afe", + "afe_general7_asrc"), + GATE_AFE4(CLK_AFE_GENERAL6_ASRC, "afe_general6_asrc", + "vlp_aud_clksq_ck", 18), + GATE_AFE4_V(CLK_AFE_GENERAL6_ASRC_AFE, "afe_general6_asrc_afe", + "afe_general6_asrc"), + GATE_AFE4(CLK_AFE_GENERAL5_ASRC, "afe_general5_asrc", + "vlp_aud_clksq_ck", 19), + GATE_AFE4_V(CLK_AFE_GENERAL5_ASRC_AFE, "afe_general5_asrc_afe", + "afe_general5_asrc"), + GATE_AFE4(CLK_AFE_GENERAL4_ASRC, "afe_general4_asrc", + "vlp_aud_clksq_ck", 20), + GATE_AFE4_V(CLK_AFE_GENERAL4_ASRC_AFE, "afe_general4_asrc_afe", + "afe_general4_asrc"), + GATE_AFE4(CLK_AFE_GENERAL3_ASRC, "afe_general3_asrc", + "vlp_aud_clksq_ck", 21), + GATE_AFE4_V(CLK_AFE_GENERAL3_ASRC_AFE, "afe_general3_asrc_afe", + "afe_general3_asrc"), + GATE_AFE4(CLK_AFE_GENERAL2_ASRC, "afe_general2_asrc", + "vlp_aud_clksq_ck", 22), + GATE_AFE4_V(CLK_AFE_GENERAL2_ASRC_AFE, "afe_general2_asrc_afe", + "afe_general2_asrc"), + GATE_AFE4(CLK_AFE_GENERAL1_ASRC, "afe_general1_asrc", + "vlp_aud_clksq_ck", 23), + GATE_AFE4_V(CLK_AFE_GENERAL1_ASRC_AFE, "afe_general1_asrc_afe", + "afe_general1_asrc"), + GATE_AFE4(CLK_AFE_GENERAL0_ASRC, "afe_general0_asrc", + "vlp_aud_clksq_ck", 24), + GATE_AFE4_V(CLK_AFE_GENERAL0_ASRC_AFE, "afe_general0_asrc_afe", + "afe_general0_asrc"), + GATE_AFE4(CLK_AFE_CONNSYS_I2S_ASRC, "afe_connsys_i2s_asrc", + "vlp_aud_clksq_ck", 25), + GATE_AFE4_V(CLK_AFE_CONNSYS_I2S_ASRC_AFE, "afe_connsys_i2s_asrc_afe", + "afe_connsys_i2s_asrc"), +}; + +static const struct mtk_clk_desc afe_mcd = { + .clks = afe_clks, + .num_clks = ARRAY_SIZE(afe_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_adsp[] = { + { .compatible = "mediatek,mt8196-audiosys", .data = &afe_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_adsp_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-adsp", + .of_match_table = of_match_clk_mt8196_adsp, + }, +}; + +module_platform_driver(clk_mt8196_adsp_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-apifrbus_ao.c b/drivers/clk/mediatek/clk-mt8196-apifrbus_ao.c new file mode 100644 index 0000000000000..374033ebae18c --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-apifrbus_ao.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs ifr_mem_cg_regs = { + .set_ofs = 0xd04, + .clr_ofs = 0xd08, + .sta_ofs = 0xd00, +}; + +#define GATE_IFR_MEM(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ifr_mem_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_IFR_MEM_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate ifr_mem_clks[] = { + GATE_IFR_MEM(CLK_IFR_MEM_DPMAIF_MAIN, "ifr_mem_dpmaif_main", + "ck_dpmaif_main_ck", 2), + GATE_IFR_MEM_V(CLK_IFR_MEM_DPMAIF_MAIN_CCCI, "ifr_mem_dpmaif_main_ccci", + "ifr_mem_dpmaif_main"), + GATE_IFR_MEM(CLK_IFR_MEM_DPMAIF_26M, "ifr_mem_dpmaif_26m", + "vlp_infra_26m_ck", 3), + GATE_IFR_MEM_V(CLK_IFR_MEM_DPMAIF_26M_CCCI, "ifr_mem_dpmaif_26m_ccci", + "ifr_mem_dpmaif_26m"), +}; + +static const struct mtk_clk_desc ifr_mem_mcd = { + .clks = ifr_mem_clks, + .num_clks = ARRAY_SIZE(ifr_mem_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_apifrbus_ao[] = { + { .compatible = "mediatek,mt8196-apifrbus_ao_mem_reg", .data = &ifr_mem_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_apifrbus_ao_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-apifrbus_ao", + .of_match_table = of_match_clk_mt8196_apifrbus_ao, + }, +}; + +module_platform_driver(clk_mt8196_apifrbus_ao_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c new file mode 100644 index 0000000000000..2ff80321e46f2 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PLL REG */ +#define MAINPLL_CON0 0x250 +#define MAINPLL_CON1 0x254 +#define MAINPLL_CON2 0x258 +#define MAINPLL_CON3 0x25c +#define UNIVPLL_CON0 0x264 +#define UNIVPLL_CON1 0x268 +#define UNIVPLL_CON2 0x26c +#define UNIVPLL_CON3 0x270 +#define MSDCPLL_CON0 0x278 +#define MSDCPLL_CON1 0x27c +#define MSDCPLL_CON2 0x280 +#define MSDCPLL_CON3 0x284 +#define ADSPPLL_CON0 0x28c +#define ADSPPLL_CON1 0x290 +#define ADSPPLL_CON2 0x294 +#define ADSPPLL_CON3 0x298 +#define EMIPLL_CON0 0x2a0 +#define EMIPLL_CON1 0x2a4 +#define EMIPLL_CON2 0x2a8 +#define EMIPLL_CON3 0x2ac +#define EMIPLL2_CON0 0x2b4 +#define EMIPLL2_CON1 0x2b8 +#define EMIPLL2_CON2 0x2bc +#define EMIPLL2_CON3 0x2c0 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL_FENC(_id, _name, _reg, _fenc_sta_ofs, _fenc_sta_bit, \ + _flags, _pd_reg, _pd_shift, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .fenc_sta_ofs = _fenc_sta_ofs, \ + .fenc_sta_bit = _fenc_sta_bit, \ + .flags = (_flags | CLK_FENC_ENABLE), \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data apmixed_plls[] = { + PLL_FENC(CLK_APMIXED_MAINPLL, "mainpll", MAINPLL_CON0, + 0x003c, 7, PLL_AO, + MAINPLL_CON1, 24, + MAINPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED_UNIVPLL, "univpll", UNIVPLL_CON0, + 0x003c, 6, 0, + UNIVPLL_CON1, 24, + UNIVPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED_MSDCPLL, "msdcpll", MSDCPLL_CON0, + 0x003c, 5, 0, + MSDCPLL_CON1, 24, + MSDCPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED_ADSPPLL, "adsppll", ADSPPLL_CON0, + 0x003c, 4, 0, + ADSPPLL_CON1, 24, + ADSPPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED_EMIPLL, "emipll", EMIPLL_CON0, + 0x003c, 3, PLL_AO, + EMIPLL_CON1, 24, + EMIPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED_EMIPLL2, "emipll2", EMIPLL2_CON0, + 0x003c, 2, PLL_AO, + EMIPLL2_CON1, 24, + EMIPLL2_CON1, 0, 22), +}; + +static int clk_mt8196_apmixed_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int num_plls = ARRAY_SIZE(apmixed_plls); + int r; + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, apmixed_plls, num_plls, clk_data); + if (r) { + mtk_free_clk_data(clk_data); + return r; + } + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) { + mtk_clk_unregister_plls(apmixed_plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); + return r; + } + + return 0; +} + +static void clk_mt8196_apmixed_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(apmixed_plls, ARRAY_SIZE(apmixed_plls), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_apmixed[] = { + { .compatible = "mediatek,mt8196-apmixedsys", }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_apmixed_drv = { + .probe = clk_mt8196_apmixed_probe, + .remove_new = clk_mt8196_apmixed_remove, + .driver = { + .name = "clk-mt8196-apmixed", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_apmixed, + }, +}; + +module_platform_driver(clk_mt8196_apmixed_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-apmixedsys_gp2.c b/drivers/clk/mediatek/clk-mt8196-apmixedsys_gp2.c new file mode 100644 index 0000000000000..03c0eb8c7638b --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-apmixedsys_gp2.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PLL REG */ +#define MAINPLL2_CON0 0x250 +#define MAINPLL2_CON1 0x254 +#define MAINPLL2_CON2 0x258 +#define MAINPLL2_CON3 0x25c +#define UNIVPLL2_CON0 0x264 +#define UNIVPLL2_CON1 0x268 +#define UNIVPLL2_CON2 0x26c +#define UNIVPLL2_CON3 0x270 +#define MMPLL2_CON0 0x278 +#define MMPLL2_CON1 0x27c +#define MMPLL2_CON2 0x280 +#define MMPLL2_CON3 0x284 +#define IMGPLL_CON0 0x28c +#define IMGPLL_CON1 0x290 +#define IMGPLL_CON2 0x294 +#define IMGPLL_CON3 0x298 +#define TVDPLL1_CON0 0x2a0 +#define TVDPLL1_CON1 0x2a4 +#define TVDPLL1_CON2 0x2a8 +#define TVDPLL1_CON3 0x2ac +#define TVDPLL2_CON0 0x2b4 +#define TVDPLL2_CON1 0x2b8 +#define TVDPLL2_CON2 0x2bc +#define TVDPLL2_CON3 0x2c0 +#define TVDPLL3_CON0 0x2c8 +#define TVDPLL3_CON1 0x2cc +#define TVDPLL3_CON2 0x2d0 +#define TVDPLL3_CON3 0x2d4 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL_FENC(_id, _name, _reg, _fenc_sta_ofs, _fenc_sta_bit,\ + _flags, _pd_reg, _pd_shift, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .fenc_sta_ofs = _fenc_sta_ofs, \ + .fenc_sta_bit = _fenc_sta_bit, \ + .flags = (_flags | CLK_FENC_ENABLE), \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data apmixed2_plls[] = { + PLL_FENC(CLK_APMIXED2_MAINPLL2, "mainpll2", MAINPLL2_CON0, + 0x03c, 6, 0, + MAINPLL2_CON1, 24, + MAINPLL2_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_UNIVPLL2, "univpll2", UNIVPLL2_CON0, + 0x03c, 5, 0, + UNIVPLL2_CON1, 24, + UNIVPLL2_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_MMPLL2, "mmpll2", MMPLL2_CON0, + 0x03c, 4, 0, + MMPLL2_CON1, 24, + MMPLL2_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_IMGPLL, "imgpll", IMGPLL_CON0, + 0x03c, 3, 0, + IMGPLL_CON1, 24, + IMGPLL_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_TVDPLL1, "tvdpll1", TVDPLL1_CON0, + 0x03c, 2, 0, + TVDPLL1_CON1, 24, + TVDPLL1_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_TVDPLL2, "tvdpll2", TVDPLL2_CON0, + 0x03c, 1, 0, + TVDPLL2_CON1, 24, + TVDPLL2_CON1, 0, 22), + PLL_FENC(CLK_APMIXED2_TVDPLL3, "tvdpll3", TVDPLL3_CON0, + 0x03c, 0, 0, + TVDPLL3_CON1, 24, + TVDPLL3_CON1, 0, 22), +}; + +static int clk_mt8196_apmixed2_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int num_plls = ARRAY_SIZE(apmixed2_plls); + int r; + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, apmixed2_plls, num_plls, clk_data); + if (r) { + mtk_free_clk_data(clk_data); + return r; + } + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) { + mtk_clk_unregister_plls(apmixed2_plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); + return r; + } + + return 0; +} + +static void clk_mt8196_apmixed2_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(apmixed2_plls, ARRAY_SIZE(apmixed2_plls), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_apmixed2[] = { + { .compatible = "mediatek,mt8196-apmixedsys_gp2", }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_apmixed2_drv = { + .probe = clk_mt8196_apmixed2_probe, + .remove_new = clk_mt8196_apmixed2_remove, + .driver = { + .name = "clk-mt8196-apmixed2", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_apmixed2, + }, +}; + +module_platform_driver(clk_mt8196_apmixed2_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-disp0.c b/drivers/clk/mediatek/clk-mt8196-disp0.c new file mode 100644 index 0000000000000..b958f362d707d --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-disp0.c @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs mm0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm0_hwv_regs = { + .set_ofs = 0x0020, + .clr_ofs = 0x0024, + .sta_ofs = 0x2c10, +}; + +static const struct mtk_gate_regs mm1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mm1_hwv_regs = { + .set_ofs = 0x0028, + .clr_ofs = 0x002c, + .sta_ofs = 0x2c14, +}; + +#define GATE_MM0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MM0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_MM0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &mm0_cg_regs, \ + .hwv_regs = &mm0_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE \ + } + +#define GATE_MM1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MM1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_MM1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &mm1_cg_regs, \ + .hwv_regs = &mm1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate mm_clks[] = { + /* MM0 */ + GATE_HWV_MM0(CLK_MM_CONFIG, "mm_config", + "ck2_disp_ck", 0), + GATE_MM0_V(CLK_MM_CONFIG_DISP, "mm_config_disp", + "mm_config"), + GATE_HWV_MM0(CLK_MM_DISP_MUTEX0, "mm_disp_mutex0", + "ck2_disp_ck", 1), + GATE_MM0_V(CLK_MM_DISP_MUTEX0_DISP, "mm_disp_mutex0_disp", + "mm_disp_mutex0"), + GATE_HWV_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", + "ck2_disp_ck", 2), + GATE_MM0_V(CLK_MM_DISP_AAL0_PQ, "mm_disp_aal0_pq", + "mm_disp_aal0"), + GATE_HWV_MM0(CLK_MM_DISP_AAL1, "mm_disp_aal1", + "ck2_disp_ck", 3), + GATE_MM0_V(CLK_MM_DISP_AAL1_PQ, "mm_disp_aal1_pq", + "mm_disp_aal1"), + GATE_MM0(CLK_MM_DISP_C3D0, "mm_disp_c3d0", + "ck2_disp_ck", 4), + GATE_MM0_V(CLK_MM_DISP_C3D0_PQ, "mm_disp_c3d0_pq", + "mm_disp_c3d0"), + GATE_MM0(CLK_MM_DISP_C3D1, "mm_disp_c3d1", + "ck2_disp_ck", 5), + GATE_MM0_V(CLK_MM_DISP_C3D1_PQ, "mm_disp_c3d1_pq", + "mm_disp_c3d1"), + GATE_MM0(CLK_MM_DISP_C3D2, "mm_disp_c3d2", + "ck2_disp_ck", 6), + GATE_MM0_V(CLK_MM_DISP_C3D2_PQ, "mm_disp_c3d2_pq", + "mm_disp_c3d2"), + GATE_MM0(CLK_MM_DISP_C3D3, "mm_disp_c3d3", + "ck2_disp_ck", 7), + GATE_MM0_V(CLK_MM_DISP_C3D3_PQ, "mm_disp_c3d3_pq", + "mm_disp_c3d3"), + GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", + "ck2_disp_ck", 8), + GATE_MM0_V(CLK_MM_DISP_CCORR0_PQ, "mm_disp_ccorr0_pq", + "mm_disp_ccorr0"), + GATE_MM0(CLK_MM_DISP_CCORR1, "mm_disp_ccorr1", + "ck2_disp_ck", 9), + GATE_MM0_V(CLK_MM_DISP_CCORR1_PQ, "mm_disp_ccorr1_pq", + "mm_disp_ccorr1"), + GATE_MM0(CLK_MM_DISP_CCORR2, "mm_disp_ccorr2", + "ck2_disp_ck", 10), + GATE_MM0_V(CLK_MM_DISP_CCORR2_PQ, "mm_disp_ccorr2_pq", + "mm_disp_ccorr2"), + GATE_MM0(CLK_MM_DISP_CCORR3, "mm_disp_ccorr3", + "ck2_disp_ck", 11), + GATE_MM0_V(CLK_MM_DISP_CCORR3_PQ, "mm_disp_ccorr3_pq", + "mm_disp_ccorr3"), + GATE_MM0(CLK_MM_DISP_CHIST0, "mm_disp_chist0", + "ck2_disp_ck", 12), + GATE_MM0_V(CLK_MM_DISP_CHIST0_PQ, "mm_disp_chist0_pq", + "mm_disp_chist0"), + GATE_MM0(CLK_MM_DISP_CHIST1, "mm_disp_chist1", + "ck2_disp_ck", 13), + GATE_MM0_V(CLK_MM_DISP_CHIST1_PQ, "mm_disp_chist1_pq", + "mm_disp_chist1"), + GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", + "ck2_disp_ck", 14), + GATE_MM0_V(CLK_MM_DISP_COLOR0_PQ, "mm_disp_color0_pq", + "mm_disp_color0"), + GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", + "ck2_disp_ck", 15), + GATE_MM0_V(CLK_MM_DISP_COLOR1_PQ, "mm_disp_color1_pq", + "mm_disp_color1"), + GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", + "ck2_disp_ck", 16), + GATE_MM0_V(CLK_MM_DISP_DITHER0_PQ, "mm_disp_dither0_pq", + "mm_disp_dither0"), + GATE_MM0(CLK_MM_DISP_DITHER1, "mm_disp_dither1", + "ck2_disp_ck", 17), + GATE_MM0_V(CLK_MM_DISP_DITHER1_PQ, "mm_disp_dither1_pq", + "mm_disp_dither1"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC0, "mm_disp_dli_async0", + "ck2_disp_ck", 18), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC0_DISP, "mm_disp_dli_async0_disp", + "mm_disp_dli_async0"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC1, "mm_disp_dli_async1", + "ck2_disp_ck", 19), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC1_DISP, "mm_disp_dli_async1_disp", + "mm_disp_dli_async1"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC2, "mm_disp_dli_async2", + "ck2_disp_ck", 20), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC2_DISP, "mm_disp_dli_async2_disp", + "mm_disp_dli_async2"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC3, "mm_disp_dli_async3", + "ck2_disp_ck", 21), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC3_DISP, "mm_disp_dli_async3_disp", + "mm_disp_dli_async3"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC4, "mm_disp_dli_async4", + "ck2_disp_ck", 22), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC4_DISP, "mm_disp_dli_async4_disp", + "mm_disp_dli_async4"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC5, "mm_disp_dli_async5", + "ck2_disp_ck", 23), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC5_DISP, "mm_disp_dli_async5_disp", + "mm_disp_dli_async5"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC6, "mm_disp_dli_async6", + "ck2_disp_ck", 24), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC6_DISP, "mm_disp_dli_async6_disp", + "mm_disp_dli_async6"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC7, "mm_disp_dli_async7", + "ck2_disp_ck", 25), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC7_DISP, "mm_disp_dli_async7_disp", + "mm_disp_dli_async7"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC8, "mm_disp_dli_async8", + "ck2_disp_ck", 26), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC8_DISP, "mm_disp_dli_async8_disp", + "mm_disp_dli_async8"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC9, "mm_disp_dli_async9", + "ck2_disp_ck", 27), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC9_DISP, "mm_disp_dli_async9_disp", + "mm_disp_dli_async9"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC10, "mm_disp_dli_async10", + "ck2_disp_ck", 28), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC10_DISP, "mm_disp_dli_async10_disp", + "mm_disp_dli_async10"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC11, "mm_disp_dli_async11", + "ck2_disp_ck", 29), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC11_DISP, "mm_disp_dli_async11_disp", + "mm_disp_dli_async11"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC12, "mm_disp_dli_async12", + "ck2_disp_ck", 30), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC12_DISP, "mm_disp_dli_async12_disp", + "mm_disp_dli_async12"), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC13, "mm_disp_dli_async13", + "ck2_disp_ck", 31), + GATE_MM0_V(CLK_MM_DISP_DLI_ASYNC13_DISP, "mm_disp_dli_async13_disp", + "mm_disp_dli_async13"), + /* MM1 */ + GATE_HWV_MM1(CLK_MM_DISP_DLI_ASYNC14, "mm_disp_dli_async14", + "ck2_disp_ck", 0), + GATE_MM1_V(CLK_MM_DISP_DLI_ASYNC14_DISP, "mm_disp_dli_async14_disp", + "mm_disp_dli_async14"), + GATE_HWV_MM1(CLK_MM_DISP_DLI_ASYNC15, "mm_disp_dli_async15", + "ck2_disp_ck", 1), + GATE_MM1_V(CLK_MM_DISP_DLI_ASYNC15_DISP, "mm_disp_dli_async15_disp", + "mm_disp_dli_async15"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC0, "mm_disp_dlo_async0", + "ck2_disp_ck", 2), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC0_DISP, "mm_disp_dlo_async0_disp", + "mm_disp_dlo_async0"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC1, "mm_disp_dlo_async1", + "ck2_disp_ck", 3), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC1_DISP, "mm_disp_dlo_async1_disp", + "mm_disp_dlo_async1"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC2, "mm_disp_dlo_async2", + "ck2_disp_ck", 4), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC2_DISP, "mm_disp_dlo_async2_disp", + "mm_disp_dlo_async2"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC3, "mm_disp_dlo_async3", + "ck2_disp_ck", 5), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC3_DISP, "mm_disp_dlo_async3_disp", + "mm_disp_dlo_async3"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC4, "mm_disp_dlo_async4", + "ck2_disp_ck", 6), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC4_DISP, "mm_disp_dlo_async4_disp", + "mm_disp_dlo_async4"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC5, "mm_disp_dlo_async5", + "ck2_disp_ck", 7), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC5_DISP, "mm_disp_dlo_async5_disp", + "mm_disp_dlo_async5"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC6, "mm_disp_dlo_async6", + "ck2_disp_ck", 8), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC6_DISP, "mm_disp_dlo_async6_disp", + "mm_disp_dlo_async6"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC7, "mm_disp_dlo_async7", + "ck2_disp_ck", 9), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC7_DISP, "mm_disp_dlo_async7_disp", + "mm_disp_dlo_async7"), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC8, "mm_disp_dlo_async8", + "ck2_disp_ck", 10), + GATE_MM1_V(CLK_MM_DISP_DLO_ASYNC8_DISP, "mm_disp_dlo_async8_disp", + "mm_disp_dlo_async8"), + GATE_MM1(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", + "ck2_disp_ck", 11), + GATE_MM1_V(CLK_MM_DISP_GAMMA0_PQ, "mm_disp_gamma0_pq", + "mm_disp_gamma0"), + GATE_MM1(CLK_MM_DISP_GAMMA1, "mm_disp_gamma1", + "ck2_disp_ck", 12), + GATE_MM1_V(CLK_MM_DISP_GAMMA1_PQ, "mm_disp_gamma1_pq", + "mm_disp_gamma1"), + GATE_MM1(CLK_MM_MDP_AAL0, "mm_mdp_aal0", + "ck2_disp_ck", 13), + GATE_MM1_V(CLK_MM_MDP_AAL0_PQ, "mm_mdp_aal0_pq", + "mm_mdp_aal0"), + GATE_MM1(CLK_MM_MDP_AAL1, "mm_mdp_aal1", + "ck2_disp_ck", 14), + GATE_MM1_V(CLK_MM_MDP_AAL1_PQ, "mm_mdp_aal1_pq", + "mm_mdp_aal1"), + GATE_HWV_MM1(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", + "ck2_disp_ck", 15), + GATE_MM1_V(CLK_MM_MDP_RDMA0_DISP, "mm_mdp_rdma0_disp", + "mm_mdp_rdma0"), + GATE_HWV_MM1(CLK_MM_DISP_POSTMASK0, "mm_disp_postmask0", + "ck2_disp_ck", 16), + GATE_MM1_V(CLK_MM_DISP_POSTMASK0_DISP, "mm_disp_postmask0_disp", + "mm_disp_postmask0"), + GATE_HWV_MM1(CLK_MM_DISP_POSTMASK1, "mm_disp_postmask1", + "ck2_disp_ck", 17), + GATE_MM1_V(CLK_MM_DISP_POSTMASK1_DISP, "mm_disp_postmask1_disp", + "mm_disp_postmask1"), + GATE_HWV_MM1(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", + "ck2_disp_ck", 18), + GATE_MM1_V(CLK_MM_MDP_RSZ0_DISP, "mm_mdp_rsz0_disp", + "mm_mdp_rsz0"), + GATE_HWV_MM1(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", + "ck2_disp_ck", 19), + GATE_MM1_V(CLK_MM_MDP_RSZ1_DISP, "mm_mdp_rsz1_disp", + "mm_mdp_rsz1"), + GATE_HWV_MM1(CLK_MM_DISP_SPR0, "mm_disp_spr0", + "ck2_disp_ck", 20), + GATE_MM1_V(CLK_MM_DISP_SPR0_DISP, "mm_disp_spr0_disp", + "mm_disp_spr0"), + GATE_MM1(CLK_MM_DISP_TDSHP0, "mm_disp_tdshp0", + "ck2_disp_ck", 21), + GATE_MM1_V(CLK_MM_DISP_TDSHP0_PQ, "mm_disp_tdshp0_pq", + "mm_disp_tdshp0"), + GATE_MM1(CLK_MM_DISP_TDSHP1, "mm_disp_tdshp1", + "ck2_disp_ck", 22), + GATE_MM1_V(CLK_MM_DISP_TDSHP1_PQ, "mm_disp_tdshp1_pq", + "mm_disp_tdshp1"), + GATE_HWV_MM1(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", + "ck2_disp_ck", 23), + GATE_MM1_V(CLK_MM_DISP_WDMA0_DISP, "mm_disp_wdma0_disp", + "mm_disp_wdma0"), + GATE_HWV_MM1(CLK_MM_DISP_Y2R0, "mm_disp_y2r0", + "ck2_disp_ck", 24), + GATE_MM1_V(CLK_MM_DISP_Y2R0_DISP, "mm_disp_y2r0_disp", + "mm_disp_y2r0"), + GATE_HWV_MM1(CLK_MM_SMI_SUB_COMM0, "mm_ssc", + "ck2_disp_ck", 25), + GATE_MM1_V(CLK_MM_SMI_SUB_COMM0_SMI, "mm_ssc_smi", + "mm_ssc"), + GATE_HWV_MM1(CLK_MM_DISP_FAKE_ENG0, "mm_disp_fake_eng0", + "ck2_disp_ck", 26), + GATE_MM1_V(CLK_MM_DISP_FAKE_ENG0_DISP, "mm_disp_fake_eng0_disp", + "mm_disp_fake_eng0"), +}; + +static const struct mtk_clk_desc mm_mcd = { + .clks = mm_clks, + .num_clks = ARRAY_SIZE(mm_clks), +}; + +static const struct platform_device_id clk_mt8196_disp0_id_table[] = { + { .name = "clk-mt8196-disp0", .driver_data = (kernel_ulong_t)&mm_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_disp0_id_table); + +static struct platform_driver clk_mt8196_disp0_drv = { + .probe = mtk_clk_pdev_probe, + .remove_new = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-disp0", + }, + .id_table = clk_mt8196_disp0_id_table, +}; + +module_platform_driver(clk_mt8196_disp0_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-disp1.c b/drivers/clk/mediatek/clk-mt8196-disp1.c new file mode 100644 index 0000000000000..1a1f317f2954c --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-disp1.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs mm10_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm10_hwv_regs = { + .set_ofs = 0x0010, + .clr_ofs = 0x0014, + .sta_ofs = 0x2c08, +}; + +static const struct mtk_gate_regs mm11_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mm11_hwv_regs = { + .set_ofs = 0x0018, + .clr_ofs = 0x001c, + .sta_ofs = 0x2c0c, +}; + +#define GATE_MM10(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MM10_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_MM10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &mm10_cg_regs, \ + .hwv_regs = &mm10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_MM11(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MM11_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_MM11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &mm11_cg_regs, \ + .hwv_regs = &mm11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate mm1_clks[] = { + /* MM10 */ + GATE_HWV_MM10(CLK_MM1_DISPSYS1_CONFIG, "mm1_dispsys1_config", + "ck2_disp_ck", 0), + GATE_MM10_V(CLK_MM1_DISPSYS1_CONFIG_DISP, "mm1_dispsys1_config_disp", + "mm1_dispsys1_config"), + GATE_HWV_MM10(CLK_MM1_DISPSYS1_S_CONFIG, "mm1_dispsys1_s_config", + "ck2_disp_ck", 1), + GATE_MM10_V(CLK_MM1_DISPSYS1_S_CONFIG_DISP, "mm1_dispsys1_s_config_disp", + "mm1_dispsys1_s_config"), + GATE_HWV_MM10(CLK_MM1_DISP_MUTEX0, "mm1_disp_mutex0", + "ck2_disp_ck", 2), + GATE_MM10_V(CLK_MM1_DISP_MUTEX0_DISP, "mm1_disp_mutex0_disp", + "mm1_disp_mutex0"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC20, "mm1_disp_dli_async20", + "ck2_disp_ck", 3), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC20_DISP, "mm1_disp_dli_async20_disp", + "mm1_disp_dli_async20"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC21, "mm1_disp_dli_async21", + "ck2_disp_ck", 4), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC21_DISP, "mm1_disp_dli_async21_disp", + "mm1_disp_dli_async21"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC22, "mm1_disp_dli_async22", + "ck2_disp_ck", 5), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC22_DISP, "mm1_disp_dli_async22_disp", + "mm1_disp_dli_async22"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC23, "mm1_disp_dli_async23", + "ck2_disp_ck", 6), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC23_DISP, "mm1_disp_dli_async23_disp", + "mm1_disp_dli_async23"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC24, "mm1_disp_dli_async24", + "ck2_disp_ck", 7), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC24_DISP, "mm1_disp_dli_async24_disp", + "mm1_disp_dli_async24"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC25, "mm1_disp_dli_async25", + "ck2_disp_ck", 8), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC25_DISP, "mm1_disp_dli_async25_disp", + "mm1_disp_dli_async25"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC26, "mm1_disp_dli_async26", + "ck2_disp_ck", 9), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC26_DISP, "mm1_disp_dli_async26_disp", + "mm1_disp_dli_async26"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC27, "mm1_disp_dli_async27", + "ck2_disp_ck", 10), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC27_DISP, "mm1_disp_dli_async27_disp", + "mm1_disp_dli_async27"), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC28, "mm1_disp_dli_async28", + "ck2_disp_ck", 11), + GATE_MM10_V(CLK_MM1_DISP_DLI_ASYNC28_DISP, "mm1_disp_dli_async28_disp", + "mm1_disp_dli_async28"), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY0, "mm1_disp_relay0", + "ck2_disp_ck", 12), + GATE_MM10_V(CLK_MM1_DISP_RELAY0_DISP, "mm1_disp_relay0_disp", + "mm1_disp_relay0"), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY1, "mm1_disp_relay1", + "ck2_disp_ck", 13), + GATE_MM10_V(CLK_MM1_DISP_RELAY1_DISP, "mm1_disp_relay1_disp", + "mm1_disp_relay1"), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY2, "mm1_disp_relay2", + "ck2_disp_ck", 14), + GATE_MM10_V(CLK_MM1_DISP_RELAY2_DISP, "mm1_disp_relay2_disp", + "mm1_disp_relay2"), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY3, "mm1_disp_relay3", + "ck2_disp_ck", 15), + GATE_MM10_V(CLK_MM1_DISP_RELAY3_DISP, "mm1_disp_relay3_disp", + "mm1_disp_relay3"), + GATE_HWV_MM10(CLK_MM1_DISP_DP_INTF0, "mm1_DP_CLK", + "ck2_disp_ck", 16), + GATE_MM10_V(CLK_MM1_DISP_DP_INTF0_DISP, "mm1_dp_clk_disp", + "mm1_DP_CLK"), + GATE_HWV_MM10(CLK_MM1_DISP_DP_INTF1, "mm1_disp_dp_intf1", + "ck2_disp_ck", 17), + GATE_MM10_V(CLK_MM1_DISP_DP_INTF1_DISP, "mm1_disp_dp_intf1_disp", + "mm1_disp_dp_intf1"), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP0, "mm1_disp_dsc_wrap0", + "ck2_disp_ck", 18), + GATE_MM10_V(CLK_MM1_DISP_DSC_WRAP0_DISP, "mm1_disp_dsc_wrap0_disp", + "mm1_disp_dsc_wrap0"), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP1, "mm1_disp_dsc_wrap1", + "ck2_disp_ck", 19), + GATE_MM10_V(CLK_MM1_DISP_DSC_WRAP1_DISP, "mm1_disp_dsc_wrap1_disp", + "mm1_disp_dsc_wrap1"), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP2, "mm1_disp_dsc_wrap2", + "ck2_disp_ck", 20), + GATE_MM10_V(CLK_MM1_DISP_DSC_WRAP2_DISP, "mm1_disp_dsc_wrap2_disp", + "mm1_disp_dsc_wrap2"), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP3, "mm1_disp_dsc_wrap3", + "ck2_disp_ck", 21), + GATE_MM10_V(CLK_MM1_DISP_DSC_WRAP3_DISP, "mm1_disp_dsc_wrap3_disp", + "mm1_disp_dsc_wrap3"), + GATE_HWV_MM10(CLK_MM1_DISP_DSI0, "mm1_CLK0", + "ck2_disp_ck", 22), + GATE_MM10_V(CLK_MM1_DISP_DSI0_DISP, "mm1_clk0_disp", + "mm1_CLK0"), + GATE_HWV_MM10(CLK_MM1_DISP_DSI1, "mm1_CLK1", + "ck2_disp_ck", 23), + GATE_MM10_V(CLK_MM1_DISP_DSI1_DISP, "mm1_clk1_disp", + "mm1_CLK1"), + GATE_HWV_MM10(CLK_MM1_DISP_DSI2, "mm1_CLK2", + "ck2_disp_ck", 24), + GATE_MM10_V(CLK_MM1_DISP_DSI2_DISP, "mm1_clk2_disp", + "mm1_CLK2"), + GATE_HWV_MM10(CLK_MM1_DISP_DVO0, "mm1_disp_dvo0", + "ck2_disp_ck", 25), + GATE_MM10_V(CLK_MM1_DISP_DVO0_DISP, "mm1_disp_dvo0_disp", + "mm1_disp_dvo0"), + GATE_HWV_MM10(CLK_MM1_DISP_GDMA0, "mm1_disp_gdma0", + "ck2_disp_ck", 26), + GATE_MM10_V(CLK_MM1_DISP_GDMA0_DISP, "mm1_disp_gdma0_disp", + "mm1_disp_gdma0"), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE0, "mm1_disp_merge0", + "ck2_disp_ck", 27), + GATE_MM10_V(CLK_MM1_DISP_MERGE0_DISP, "mm1_disp_merge0_disp", + "mm1_disp_merge0"), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE1, "mm1_disp_merge1", + "ck2_disp_ck", 28), + GATE_MM10_V(CLK_MM1_DISP_MERGE1_DISP, "mm1_disp_merge1_disp", + "mm1_disp_merge1"), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE2, "mm1_disp_merge2", + "ck2_disp_ck", 29), + GATE_MM10_V(CLK_MM1_DISP_MERGE2_DISP, "mm1_disp_merge2_disp", + "mm1_disp_merge2"), + GATE_HWV_MM10(CLK_MM1_DISP_ODDMR0, "mm1_disp_oddmr0", + "ck2_disp_ck", 30), + GATE_MM10_V(CLK_MM1_DISP_ODDMR0_PQ, "mm1_disp_oddmr0_pq", + "mm1_disp_oddmr0"), + GATE_HWV_MM10(CLK_MM1_DISP_POSTALIGN0, "mm1_disp_postalign0", + "ck2_disp_ck", 31), + GATE_MM10_V(CLK_MM1_DISP_POSTALIGN0_PQ, "mm1_disp_postalign0_pq", + "mm1_disp_postalign0"), + /* MM11 */ + GATE_HWV_MM11(CLK_MM1_DISP_DITHER2, "mm1_disp_dither2", + "ck2_disp_ck", 0), + GATE_MM11_V(CLK_MM1_DISP_DITHER2_PQ, "mm1_disp_dither2_pq", + "mm1_disp_dither2"), + GATE_HWV_MM11(CLK_MM1_DISP_R2Y0, "mm1_disp_r2y0", + "ck2_disp_ck", 1), + GATE_MM11_V(CLK_MM1_DISP_R2Y0_DISP, "mm1_disp_r2y0_disp", + "mm1_disp_r2y0"), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER0, "mm1_disp_splitter0", + "ck2_disp_ck", 2), + GATE_MM11_V(CLK_MM1_DISP_SPLITTER0_DISP, "mm1_disp_splitter0_disp", + "mm1_disp_splitter0"), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER1, "mm1_disp_splitter1", + "ck2_disp_ck", 3), + GATE_MM11_V(CLK_MM1_DISP_SPLITTER1_DISP, "mm1_disp_splitter1_disp", + "mm1_disp_splitter1"), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER2, "mm1_disp_splitter2", + "ck2_disp_ck", 4), + GATE_MM11_V(CLK_MM1_DISP_SPLITTER2_DISP, "mm1_disp_splitter2_disp", + "mm1_disp_splitter2"), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER3, "mm1_disp_splitter3", + "ck2_disp_ck", 5), + GATE_MM11_V(CLK_MM1_DISP_SPLITTER3_DISP, "mm1_disp_splitter3_disp", + "mm1_disp_splitter3"), + GATE_HWV_MM11(CLK_MM1_DISP_VDCM0, "mm1_disp_vdcm0", + "ck2_disp_ck", 6), + GATE_MM11_V(CLK_MM1_DISP_VDCM0_DISP, "mm1_disp_vdcm0_disp", + "mm1_disp_vdcm0"), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA1, "mm1_disp_wdma1", + "ck2_disp_ck", 7), + GATE_MM11_V(CLK_MM1_DISP_WDMA1_DISP, "mm1_disp_wdma1_disp", + "mm1_disp_wdma1"), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA2, "mm1_disp_wdma2", + "ck2_disp_ck", 8), + GATE_MM11_V(CLK_MM1_DISP_WDMA2_DISP, "mm1_disp_wdma2_disp", + "mm1_disp_wdma2"), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA3, "mm1_disp_wdma3", + "ck2_disp_ck", 9), + GATE_MM11_V(CLK_MM1_DISP_WDMA3_DISP, "mm1_disp_wdma3_disp", + "mm1_disp_wdma3"), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA4, "mm1_disp_wdma4", + "ck2_disp_ck", 10), + GATE_MM11_V(CLK_MM1_DISP_WDMA4_DISP, "mm1_disp_wdma4_disp", + "mm1_disp_wdma4"), + GATE_HWV_MM11(CLK_MM1_MDP_RDMA1, "mm1_mdp_rdma1", + "ck2_disp_ck", 11), + GATE_MM11_V(CLK_MM1_MDP_RDMA1_DISP, "mm1_mdp_rdma1_disp", + "mm1_mdp_rdma1"), + GATE_HWV_MM11(CLK_MM1_SMI_LARB0, "mm1_smi_larb0", + "ck2_disp_ck", 12), + GATE_MM11_V(CLK_MM1_SMI_LARB0_SMI, "mm1_smi_larb0_smi", + "mm1_smi_larb0"), + GATE_HWV_MM11(CLK_MM1_MOD1, "mm1_mod1", + "ck_f26m_ck", 13), + GATE_MM11_V(CLK_MM1_MOD1_DISP, "mm1_mod1_disp", + "mm1_mod1"), + GATE_HWV_MM11(CLK_MM1_MOD2, "mm1_mod2", + "ck_f26m_ck", 14), + GATE_MM11_V(CLK_MM1_MOD2_DISP, "mm1_mod2_disp", + "mm1_mod2"), + GATE_HWV_MM11(CLK_MM1_MOD3, "mm1_mod3", + "ck_f26m_ck", 15), + GATE_MM11_V(CLK_MM1_MOD3_DISP, "mm1_mod3_disp", + "mm1_mod3"), + GATE_HWV_MM11(CLK_MM1_MOD4, "mm1_mod4", + "ck2_dp0_ck", 16), + GATE_MM11_V(CLK_MM1_MOD4_DISP, "mm1_mod4_disp", + "mm1_mod4"), + GATE_HWV_MM11(CLK_MM1_MOD5, "mm1_mod5", + "ck2_dp1_ck", 17), + GATE_MM11_V(CLK_MM1_MOD5_DISP, "mm1_mod5_disp", + "mm1_mod5"), + GATE_HWV_MM11(CLK_MM1_MOD6, "mm1_mod6", + "ck2_dp1_ck", 18), + GATE_MM11_V(CLK_MM1_MOD6_DISP, "mm1_mod6_disp", + "mm1_mod6"), + GATE_HWV_MM11(CLK_MM1_CK_CG0, "mm1_cg0", + "ck2_disp_ck", 20), + GATE_MM11_V(CLK_MM1_CK_CG0_DISP, "mm1_cg0_disp", + "mm1_cg0"), + GATE_HWV_MM11(CLK_MM1_CK_CG1, "mm1_cg1", + "ck2_disp_ck", 21), + GATE_MM11_V(CLK_MM1_CK_CG1_DISP, "mm1_cg1_disp", + "mm1_cg1"), + GATE_HWV_MM11(CLK_MM1_CK_CG2, "mm1_cg2", + "ck2_disp_ck", 22), + GATE_MM11_V(CLK_MM1_CK_CG2_DISP, "mm1_cg2_disp", + "mm1_cg2"), + GATE_HWV_MM11(CLK_MM1_CK_CG3, "mm1_cg3", + "ck2_disp_ck", 23), + GATE_MM11_V(CLK_MM1_CK_CG3_DISP, "mm1_cg3_disp", + "mm1_cg3"), + GATE_HWV_MM11(CLK_MM1_CK_CG4, "mm1_cg4", + "ck2_disp_ck", 24), + GATE_MM11_V(CLK_MM1_CK_CG4_DISP, "mm1_cg4_disp", + "mm1_cg4"), + GATE_HWV_MM11(CLK_MM1_CK_CG5, "mm1_cg5", + "ck2_disp_ck", 25), + GATE_MM11_V(CLK_MM1_CK_CG5_DISP, "mm1_cg5_disp", + "mm1_cg5"), + GATE_HWV_MM11(CLK_MM1_CK_CG6, "mm1_cg6", + "ck2_disp_ck", 26), + GATE_MM11_V(CLK_MM1_CK_CG6_DISP, "mm1_cg6_disp", + "mm1_cg6"), + GATE_HWV_MM11(CLK_MM1_CK_CG7, "mm1_cg7", + "ck2_disp_ck", 27), + GATE_MM11_V(CLK_MM1_CK_CG7_DISP, "mm1_cg7_disp", + "mm1_cg7"), + GATE_HWV_MM11(CLK_MM1_F26M, "mm1_f26m_ck", + "ck_f26m_ck", 28), + GATE_MM11_V(CLK_MM1_F26M_DISP, "mm1_f26m_ck_disp", + "mm1_f26m_ck"), +}; + +static const struct mtk_clk_desc mm1_mcd = { + .clks = mm1_clks, + .num_clks = ARRAY_SIZE(mm1_clks), +}; + +static const struct platform_device_id clk_mt8196_disp1_id_table[] = { + { .name = "clk-mt8196-disp1", .driver_data = (kernel_ulong_t)&mm1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_disp1_id_table); + +static struct platform_driver clk_mt8196_disp1_drv = { + .probe = mtk_clk_pdev_probe, + .remove_new = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-disp1", + }, + .id_table = clk_mt8196_disp1_id_table, +}; + +module_platform_driver(clk_mt8196_disp1_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c new file mode 100644 index 0000000000000..3800b4176ee36 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs impc_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +#define GATE_IMPC(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &impc_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_IMPC_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate impc_clks[] = { + GATE_IMPC(CLK_IMPC_I2C11, "impc_i2c11", + "ck_i2c_p_ck", 0), + GATE_IMPC_V(CLK_IMPC_I2C11_I2C, "impc_i2c11_i2c", + "impc_i2c11"), + GATE_IMPC(CLK_IMPC_I2C12, "impc_i2c12", + "ck_i2c_p_ck", 1), + GATE_IMPC_V(CLK_IMPC_I2C12_I2C, "impc_i2c12_i2c", + "impc_i2c12"), + GATE_IMPC(CLK_IMPC_I2C13, "impc_i2c13", + "ck_i2c_p_ck", 2), + GATE_IMPC_V(CLK_IMPC_I2C13_I2C, "impc_i2c13_i2c", + "impc_i2c13"), + GATE_IMPC(CLK_IMPC_I2C14, "impc_i2c14", + "ck_i2c_p_ck", 3), + GATE_IMPC_V(CLK_IMPC_I2C14_I2C, "impc_i2c14_i2c", + "impc_i2c14"), +}; + +static const struct mtk_clk_desc impc_mcd = { + .clks = impc_clks, + .num_clks = ARRAY_SIZE(impc_clks), +}; + +static const struct mtk_gate_regs impe_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +#define GATE_IMPE(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &impe_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_IMPE_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate impe_clks[] = { + GATE_IMPE(CLK_IMPE_I2C5, "impe_i2c5", + "ck_i2c_east_ck", 0), + GATE_IMPE_V(CLK_IMPE_I2C5_I2C, "impe_i2c5_i2c", + "impe_i2c5"), +}; + +static const struct mtk_clk_desc impe_mcd = { + .clks = impe_clks, + .num_clks = ARRAY_SIZE(impe_clks), +}; + +static const struct mtk_gate_regs impn_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +static const struct mtk_gate_regs impn_hwv_regs = { + .set_ofs = 0x0000, + .clr_ofs = 0x0004, + .sta_ofs = 0x2c00, +}; + +#define GATE_IMPN(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &impn_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_IMPN_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_IMPN(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "hw-voter-regmap", \ + .regs = &impn_cg_regs, \ + .hwv_regs = &impn_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate impn_clks[] = { + GATE_IMPN(CLK_IMPN_I2C1, "impn_i2c1", + "ck_i2c_north_ck", 0), + GATE_IMPN_V(CLK_IMPN_I2C1_I2C, "impn_i2c1_i2c", + "impn_i2c1"), + GATE_IMPN(CLK_IMPN_I2C2, "impn_i2c2", + "ck_i2c_north_ck", 1), + GATE_IMPN_V(CLK_IMPN_I2C2_I2C, "impn_i2c2_i2c", + "impn_i2c2"), + GATE_IMPN(CLK_IMPN_I2C4, "impn_i2c4", + "ck_i2c_north_ck", 2), + GATE_IMPN_V(CLK_IMPN_I2C4_I2C, "impn_i2c4_i2c", + "impn_i2c4"), + GATE_HWV_IMPN(CLK_IMPN_I2C7, "impn_i2c7", + "ck_i2c_north_ck", 3), + GATE_IMPN_V(CLK_IMPN_I2C7_I2C, "impn_i2c7_i2c", + "impn_i2c7"), + GATE_IMPN(CLK_IMPN_I2C8, "impn_i2c8", + "ck_i2c_north_ck", 4), + GATE_IMPN_V(CLK_IMPN_I2C8_I2C, "impn_i2c8_i2c", + "impn_i2c8"), + GATE_IMPN(CLK_IMPN_I2C9, "impn_i2c9", + "ck_i2c_north_ck", 5), + GATE_IMPN_V(CLK_IMPN_I2C9_I2C, "impn_i2c9_i2c", + "impn_i2c9"), +}; + +static const struct mtk_clk_desc impn_mcd = { + .clks = impn_clks, + .num_clks = ARRAY_SIZE(impn_clks), +}; + +static const struct mtk_gate_regs impw_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +#define GATE_IMPW(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &impw_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_IMPW_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate impw_clks[] = { + GATE_IMPW(CLK_IMPW_I2C0, "impw_i2c0", + "ck_i2c_west_ck", 0), + GATE_IMPW_V(CLK_IMPW_I2C0_I2C, "impw_i2c0_i2c", + "impw_i2c0"), + GATE_IMPW(CLK_IMPW_I2C3, "impw_i2c3", + "ck_i2c_west_ck", 1), + GATE_IMPW_V(CLK_IMPW_I2C3_I2C, "impw_i2c3_i2c", + "impw_i2c3"), + GATE_IMPW(CLK_IMPW_I2C6, "impw_i2c6", + "ck_i2c_west_ck", 2), + GATE_IMPW_V(CLK_IMPW_I2C6_I2C, "impw_i2c6_i2c", + "impw_i2c6"), + GATE_IMPW(CLK_IMPW_I2C10, "impw_i2c10", + "ck_i2c_west_ck", 3), + GATE_IMPW_V(CLK_IMPW_I2C10_I2C, "impw_i2c10_i2c", + "impw_i2c10"), +}; + +static const struct mtk_clk_desc impw_mcd = { + .clks = impw_clks, + .num_clks = ARRAY_SIZE(impw_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_imp_iic_wrap[] = { + { .compatible = "mediatek,mt8196-imp_iic_wrap_c", .data = &impc_mcd, }, + { .compatible = "mediatek,mt8196-imp_iic_wrap_e", .data = &impe_mcd, }, + { .compatible = "mediatek,mt8196-imp_iic_wrap_n", .data = &impn_mcd, }, + { .compatible = "mediatek,mt8196-imp_iic_wrap_w", .data = &impw_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_imp_iic_wrap_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-imp_iic_wrap", + .of_match_table = of_match_clk_mt8196_imp_iic_wrap, + }, +}; + +module_platform_driver(clk_mt8196_imp_iic_wrap_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mcu.c b/drivers/clk/mediatek/clk-mt8196-mcu.c new file mode 100644 index 0000000000000..21e6c0c1c3a0a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mcu.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARMPLL_LL_CON0 0x008 +#define ARMPLL_LL_CON1 0x00c +#define ARMPLL_LL_CON2 0x010 +#define ARMPLL_LL_CON3 0x014 +#define ARMPLL_BL_CON0 0x008 +#define ARMPLL_BL_CON1 0x00c +#define ARMPLL_BL_CON2 0x010 +#define ARMPLL_BL_CON3 0x014 +#define ARMPLL_B_CON0 0x008 +#define ARMPLL_B_CON1 0x00c +#define ARMPLL_B_CON2 0x010 +#define ARMPLL_B_CON3 0x014 +#define CCIPLL_CON0 0x008 +#define CCIPLL_CON1 0x00c +#define CCIPLL_CON2 0x010 +#define CCIPLL_CON3 0x014 +#define PTPPLL_CON0 0x008 +#define PTPPLL_CON1 0x00c +#define PTPPLL_CON2 0x010 +#define PTPPLL_CON3 0x014 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL(_id, _name, _reg, _en_reg, _en_mask, _pll_en_bit, \ + _flags, _rst_bar_mask, \ + _pd_reg, _pd_shift, _tuner_reg, \ + _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .en_reg = _en_reg, \ + .en_mask = _en_mask, \ + .pll_en_bit = _pll_en_bit, \ + .flags = (_flags | CLK_FENC_ENABLE), \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data cpu_bl_plls[] = { + PLL(CLK_CPBL_ARMPLL_BL, "armpll-bl", ARMPLL_BL_CON0, + ARMPLL_BL_CON0, 0, 0, PLL_AO, BIT(0), + ARMPLL_BL_CON1, 24, 0, 0, 0, + ARMPLL_BL_CON1, 0, 22), +}; + +static const struct mtk_pll_data cpu_b_plls[] = { + PLL(CLK_CPB_ARMPLL_B, "armpll-b", ARMPLL_B_CON0, + ARMPLL_B_CON0, 0, 0, PLL_AO, BIT(0), + ARMPLL_B_CON1, 24, 0, 0, 0, + ARMPLL_B_CON1, 0, 22), +}; + +static const struct mtk_pll_data cpu_ll_plls[] = { + PLL(CLK_CPLL_ARMPLL_LL, "armpll-ll", ARMPLL_LL_CON0, + ARMPLL_LL_CON0, 0, 0, PLL_AO, BIT(0), + ARMPLL_LL_CON1, 24, 0, 0, 0, + ARMPLL_LL_CON1, 0, 22), +}; + +static const struct mtk_pll_data cci_plls[] = { + PLL(CLK_CCIPLL, "ccipll", CCIPLL_CON0, + CCIPLL_CON0, 0, 0, PLL_AO, BIT(0), + CCIPLL_CON1, 24, 0, 0, 0, + CCIPLL_CON1, 0, 22), +}; + +static const struct mtk_pll_data ptp_plls[] = { + PLL(CLK_PTPPLL, "ptppll", PTPPLL_CON0, + PTPPLL_CON0, 0, 0, PLL_AO, BIT(0), + PTPPLL_CON1, 24, 0, 0, 0, + PTPPLL_CON1, 0, 22), +}; + +static const struct of_device_id of_match_clk_mt8196_mcu[] = { + { .compatible = "mediatek,mt8196-armpll_bl_pll_ctrl", .data = &cpu_bl_plls, }, + { .compatible = "mediatek,mt8196-armpll_b_pll_ctrl", .data = &cpu_b_plls, }, + { .compatible = "mediatek,mt8196-armpll_ll_pll_ctrl", .data = &cpu_ll_plls, }, + { .compatible = "mediatek,mt8196-ccipll_pll_ctrl", .data = &cci_plls, }, + { .compatible = "mediatek,mt8196-ptppll_pll_ctrl", .data = &ptp_plls, }, + { /* sentinel */ } +}; + +static int clk_mt8196_mcu_probe(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls; + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int num_plls = 1; + int r; + + plls = of_device_get_match_data(&pdev->dev); + if (!plls) + return -EINVAL; + + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + if (r) { + mtk_free_clk_data(clk_data); + return r; + } + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) { + mtk_clk_unregister_plls(plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); + return r; + } + + return 0; +} + +static void clk_mt8196_mcu_remove(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls = of_device_get_match_data(&pdev->dev); + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + int num_plls = 1; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); +} + +static struct platform_driver clk_mt8196_mcu_drv = { + .probe = clk_mt8196_mcu_probe, + .remove_new = clk_mt8196_mcu_remove, + .driver = { + .name = "clk-mt8196-mcu", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_mcu, + }, +}; + +module_platform_driver(clk_mt8196_mcu_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mdpsys.c b/drivers/clk/mediatek/clk-mt8196-mdpsys.c new file mode 100644 index 0000000000000..f657839db91a5 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mdpsys.c @@ -0,0 +1,514 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs mdp10_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mdp11_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mdp12_cg_regs = { + .set_ofs = 0x124, + .clr_ofs = 0x128, + .sta_ofs = 0x120, +}; + +#define GATE_MDP10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_MDP10_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_MDP11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_MDP11_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_MDP12(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp12_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_MDP12_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate mdp1_clks[] = { + /* MDP10 */ + GATE_MDP10(CLK_MDP1_MDP_MUTEX0, "mdp1_mdp_mutex0", + "ck2_mdp_ck", 0), + GATE_MDP10_V(CLK_MDP1_MDP_MUTEX0_MML, "mdp1_mdp_mutex0_mml", + "mdp1_mdp_mutex0"), + GATE_MDP10(CLK_MDP1_SMI0, "mdp1_smi0", + "ck2_mdp_ck", 1), + GATE_MDP10_V(CLK_MDP1_SMI0_SMI, "mdp1_smi0_smi", + "mdp1_smi0"), + GATE_MDP10(CLK_MDP1_APB_BUS, "mdp1_apb_bus", + "ck2_mdp_ck", 2), + GATE_MDP10_V(CLK_MDP1_APB_BUS_MML, "mdp1_apb_bus_mml", + "mdp1_apb_bus"), + GATE_MDP10(CLK_MDP1_MDP_RDMA0, "mdp1_mdp_rdma0", + "ck2_mdp_ck", 3), + GATE_MDP10_V(CLK_MDP1_MDP_RDMA0_MML, "mdp1_mdp_rdma0_mml", + "mdp1_mdp_rdma0"), + GATE_MDP10(CLK_MDP1_MDP_RDMA1, "mdp1_mdp_rdma1", + "ck2_mdp_ck", 4), + GATE_MDP10_V(CLK_MDP1_MDP_RDMA1_MML, "mdp1_mdp_rdma1_mml", + "mdp1_mdp_rdma1"), + GATE_MDP10(CLK_MDP1_MDP_RDMA2, "mdp1_mdp_rdma2", + "ck2_mdp_ck", 5), + GATE_MDP10_V(CLK_MDP1_MDP_RDMA2_MML, "mdp1_mdp_rdma2_mml", + "mdp1_mdp_rdma2"), + GATE_MDP10(CLK_MDP1_MDP_BIRSZ0, "mdp1_mdp_birsz0", + "ck2_mdp_ck", 6), + GATE_MDP10_V(CLK_MDP1_MDP_BIRSZ0_MML, "mdp1_mdp_birsz0_mml", + "mdp1_mdp_birsz0"), + GATE_MDP10(CLK_MDP1_MDP_HDR0, "mdp1_mdp_hdr0", + "ck2_mdp_ck", 7), + GATE_MDP10_V(CLK_MDP1_MDP_HDR0_MML, "mdp1_mdp_hdr0_mml", + "mdp1_mdp_hdr0"), + GATE_MDP10(CLK_MDP1_MDP_AAL0, "mdp1_mdp_aal0", + "ck2_mdp_ck", 8), + GATE_MDP10_V(CLK_MDP1_MDP_AAL0_MML, "mdp1_mdp_aal0_mml", + "mdp1_mdp_aal0"), + GATE_MDP10(CLK_MDP1_MDP_RSZ0, "mdp1_mdp_rsz0", + "ck2_mdp_ck", 9), + GATE_MDP10_V(CLK_MDP1_MDP_RSZ0_MML, "mdp1_mdp_rsz0_mml", + "mdp1_mdp_rsz0"), + GATE_MDP10(CLK_MDP1_MDP_RSZ2, "mdp1_mdp_rsz2", + "ck2_mdp_ck", 10), + GATE_MDP10_V(CLK_MDP1_MDP_RSZ2_MML, "mdp1_mdp_rsz2_mml", + "mdp1_mdp_rsz2"), + GATE_MDP10(CLK_MDP1_MDP_TDSHP0, "mdp1_mdp_tdshp0", + "ck2_mdp_ck", 11), + GATE_MDP10_V(CLK_MDP1_MDP_TDSHP0_MML, "mdp1_mdp_tdshp0_mml", + "mdp1_mdp_tdshp0"), + GATE_MDP10(CLK_MDP1_MDP_COLOR0, "mdp1_mdp_color0", + "ck2_mdp_ck", 12), + GATE_MDP10_V(CLK_MDP1_MDP_COLOR0_MML, "mdp1_mdp_color0_mml", + "mdp1_mdp_color0"), + GATE_MDP10(CLK_MDP1_MDP_WROT0, "mdp1_mdp_wrot0", + "ck2_mdp_ck", 13), + GATE_MDP10_V(CLK_MDP1_MDP_WROT0_MML, "mdp1_mdp_wrot0_mml", + "mdp1_mdp_wrot0"), + GATE_MDP10(CLK_MDP1_MDP_WROT1, "mdp1_mdp_wrot1", + "ck2_mdp_ck", 14), + GATE_MDP10_V(CLK_MDP1_MDP_WROT1_MML, "mdp1_mdp_wrot1_mml", + "mdp1_mdp_wrot1"), + GATE_MDP10(CLK_MDP1_MDP_WROT2, "mdp1_mdp_wrot2", + "ck2_mdp_ck", 15), + GATE_MDP10_V(CLK_MDP1_MDP_WROT2_MML, "mdp1_mdp_wrot2_mml", + "mdp1_mdp_wrot2"), + GATE_MDP10(CLK_MDP1_MDP_FAKE_ENG0, "mdp1_mdp_fake_eng0", + "ck2_mdp_ck", 16), + GATE_MDP10_V(CLK_MDP1_MDP_FAKE_ENG0_MML, "mdp1_mdp_fake_eng0_mml", + "mdp1_mdp_fake_eng0"), + GATE_MDP10(CLK_MDP1_APB_DB, "mdp1_apb_db", + "ck2_mdp_ck", 17), + GATE_MDP10_V(CLK_MDP1_APB_DB_MML, "mdp1_apb_db_mml", + "mdp1_apb_db"), + GATE_MDP10(CLK_MDP1_MDP_DLI_ASYNC0, "mdp1_mdp_dli_async0", + "ck2_mdp_ck", 18), + GATE_MDP10_V(CLK_MDP1_MDP_DLI_ASYNC0_MML, "mdp1_mdp_dli_async0_mml", + "mdp1_mdp_dli_async0"), + GATE_MDP10(CLK_MDP1_MDP_DLI_ASYNC1, "mdp1_mdp_dli_async1", + "ck2_mdp_ck", 19), + GATE_MDP10_V(CLK_MDP1_MDP_DLI_ASYNC1_MML, "mdp1_mdp_dli_async1_mml", + "mdp1_mdp_dli_async1"), + GATE_MDP10(CLK_MDP1_MDP_DLO_ASYNC0, "mdp1_mdp_dlo_async0", + "ck2_mdp_ck", 20), + GATE_MDP10_V(CLK_MDP1_MDP_DLO_ASYNC0_MML, "mdp1_mdp_dlo_async0_mml", + "mdp1_mdp_dlo_async0"), + GATE_MDP10(CLK_MDP1_MDP_DLO_ASYNC1, "mdp1_mdp_dlo_async1", + "ck2_mdp_ck", 21), + GATE_MDP10_V(CLK_MDP1_MDP_DLO_ASYNC1_MML, "mdp1_mdp_dlo_async1_mml", + "mdp1_mdp_dlo_async1"), + GATE_MDP10(CLK_MDP1_MDP_DLI_ASYNC2, "mdp1_mdp_dli_async2", + "ck2_mdp_ck", 22), + GATE_MDP10_V(CLK_MDP1_MDP_DLI_ASYNC2_MML, "mdp1_mdp_dli_async2_mml", + "mdp1_mdp_dli_async2"), + GATE_MDP10(CLK_MDP1_MDP_DLO_ASYNC2, "mdp1_mdp_dlo_async2", + "ck2_mdp_ck", 23), + GATE_MDP10_V(CLK_MDP1_MDP_DLO_ASYNC2_MML, "mdp1_mdp_dlo_async2_mml", + "mdp1_mdp_dlo_async2"), + GATE_MDP10(CLK_MDP1_MDP_DLO_ASYNC3, "mdp1_mdp_dlo_async3", + "ck2_mdp_ck", 24), + GATE_MDP10_V(CLK_MDP1_MDP_DLO_ASYNC3_MML, "mdp1_mdp_dlo_async3_mml", + "mdp1_mdp_dlo_async3"), + GATE_MDP10(CLK_MDP1_IMG_DL_ASYNC0, "mdp1_img_dl_async0", + "ck2_mdp_ck", 25), + GATE_MDP10_V(CLK_MDP1_IMG_DL_ASYNC0_MML, "mdp1_img_dl_async0_mml", + "mdp1_img_dl_async0"), + GATE_MDP10(CLK_MDP1_MDP_RROT0, "mdp1_mdp_rrot0", + "ck2_mdp_ck", 26), + GATE_MDP10_V(CLK_MDP1_MDP_RROT0_MML, "mdp1_mdp_rrot0_mml", + "mdp1_mdp_rrot0"), + GATE_MDP10(CLK_MDP1_MDP_MERGE0, "mdp1_mdp_merge0", + "ck2_mdp_ck", 27), + GATE_MDP10_V(CLK_MDP1_MDP_MERGE0_MML, "mdp1_mdp_merge0_mml", + "mdp1_mdp_merge0"), + GATE_MDP10(CLK_MDP1_MDP_C3D0, "mdp1_mdp_c3d0", + "ck2_mdp_ck", 28), + GATE_MDP10_V(CLK_MDP1_MDP_C3D0_MML, "mdp1_mdp_c3d0_mml", + "mdp1_mdp_c3d0"), + GATE_MDP10(CLK_MDP1_MDP_FG0, "mdp1_mdp_fg0", + "ck2_mdp_ck", 29), + GATE_MDP10_V(CLK_MDP1_MDP_FG0_MML, "mdp1_mdp_fg0_mml", + "mdp1_mdp_fg0"), + GATE_MDP10(CLK_MDP1_MDP_CLA2, "mdp1_mdp_cla2", + "ck2_mdp_ck", 30), + GATE_MDP10_V(CLK_MDP1_MDP_CLA2_MML, "mdp1_mdp_cla2_mml", + "mdp1_mdp_cla2"), + GATE_MDP10(CLK_MDP1_MDP_DLO_ASYNC4, "mdp1_mdp_dlo_async4", + "ck2_mdp_ck", 31), + GATE_MDP10_V(CLK_MDP1_MDP_DLO_ASYNC4_MML, "mdp1_mdp_dlo_async4_mml", + "mdp1_mdp_dlo_async4"), + /* MDP11 */ + GATE_MDP11(CLK_MDP1_VPP_RSZ0, "mdp1_vpp_rsz0", + "ck2_mdp_ck", 0), + GATE_MDP11_V(CLK_MDP1_VPP_RSZ0_MML, "mdp1_vpp_rsz0_mml", + "mdp1_vpp_rsz0"), + GATE_MDP11(CLK_MDP1_VPP_RSZ1, "mdp1_vpp_rsz1", + "ck2_mdp_ck", 1), + GATE_MDP11_V(CLK_MDP1_VPP_RSZ1_MML, "mdp1_vpp_rsz1_mml", + "mdp1_vpp_rsz1"), + GATE_MDP11(CLK_MDP1_MDP_DLO_ASYNC5, "mdp1_mdp_dlo_async5", + "ck2_mdp_ck", 2), + GATE_MDP11_V(CLK_MDP1_MDP_DLO_ASYNC5_MML, "mdp1_mdp_dlo_async5_mml", + "mdp1_mdp_dlo_async5"), + GATE_MDP11(CLK_MDP1_IMG0, "mdp1_img0", + "ck2_mdp_ck", 3), + GATE_MDP11_V(CLK_MDP1_IMG0_MML, "mdp1_img0_mml", + "mdp1_img0"), + GATE_MDP11(CLK_MDP1_F26M, "mdp1_f26m", + "ck_f26m_ck", 27), + GATE_MDP11_V(CLK_MDP1_F26M_MML, "mdp1_f26m_mml", + "mdp1_f26m"), + /* MDP12 */ + GATE_MDP12(CLK_MDP1_IMG_DL_RELAY0, "mdp1_img_dl_relay0", + "ck2_mdp_ck", 0), + GATE_MDP12_V(CLK_MDP1_IMG_DL_RELAY0_MML, "mdp1_img_dl_relay0_mml", + "mdp1_img_dl_relay0"), + GATE_MDP12(CLK_MDP1_IMG_DL_RELAY1, "mdp1_img_dl_relay1", + "ck2_mdp_ck", 8), + GATE_MDP12_V(CLK_MDP1_IMG_DL_RELAY1_MML, "mdp1_img_dl_relay1_mml", + "mdp1_img_dl_relay1"), +}; + +static const struct mtk_clk_desc mdp1_mcd = { + .clks = mdp1_clks, + .num_clks = ARRAY_SIZE(mdp1_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs mdp0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mdp1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mdp2_cg_regs = { + .set_ofs = 0x124, + .clr_ofs = 0x128, + .sta_ofs = 0x120, +}; + +#define GATE_MDP0(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MDP0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_MDP1(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MDP1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_MDP2(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MDP2_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate mdp_clks[] = { + /* MDP0 */ + GATE_MDP0(CLK_MDP_MDP_MUTEX0, "mdp_mdp_mutex0", + "ck2_mdp_ck", 0), + GATE_MDP0_V(CLK_MDP_MDP_MUTEX0_MML, "mdp_mdp_mutex0_mml", + "mdp_mdp_mutex0"), + GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0", + "ck2_mdp_ck", 1), + GATE_MDP0_V(CLK_MDP_SMI0_MML, "mdp_smi0_mml", + "mdp_smi0"), + GATE_MDP0_V(CLK_MDP_SMI0_SMI, "mdp_smi0_smi", + "mdp_smi0"), + GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus", + "ck2_mdp_ck", 2), + GATE_MDP0_V(CLK_MDP_APB_BUS_MML, "mdp_apb_bus_mml", + "mdp_apb_bus"), + GATE_MDP0(CLK_MDP_MDP_RDMA0, "mdp_mdp_rdma0", + "ck2_mdp_ck", 3), + GATE_MDP0_V(CLK_MDP_MDP_RDMA0_MML, "mdp_mdp_rdma0_mml", + "mdp_mdp_rdma0"), + GATE_MDP0(CLK_MDP_MDP_RDMA1, "mdp_mdp_rdma1", + "ck2_mdp_ck", 4), + GATE_MDP0_V(CLK_MDP_MDP_RDMA1_MML, "mdp_mdp_rdma1_mml", + "mdp_mdp_rdma1"), + GATE_MDP0(CLK_MDP_MDP_RDMA2, "mdp_mdp_rdma2", + "ck2_mdp_ck", 5), + GATE_MDP0_V(CLK_MDP_MDP_RDMA2_MML, "mdp_mdp_rdma2_mml", + "mdp_mdp_rdma2"), + GATE_MDP0(CLK_MDP_MDP_BIRSZ0, "mdp_mdp_birsz0", + "ck2_mdp_ck", 6), + GATE_MDP0_V(CLK_MDP_MDP_BIRSZ0_MML, "mdp_mdp_birsz0_mml", + "mdp_mdp_birsz0"), + GATE_MDP0(CLK_MDP_MDP_HDR0, "mdp_mdp_hdr0", + "ck2_mdp_ck", 7), + GATE_MDP0_V(CLK_MDP_MDP_HDR0_MML, "mdp_mdp_hdr0_mml", + "mdp_mdp_hdr0"), + GATE_MDP0(CLK_MDP_MDP_AAL0, "mdp_mdp_aal0", + "ck2_mdp_ck", 8), + GATE_MDP0_V(CLK_MDP_MDP_AAL0_MML, "mdp_mdp_aal0_mml", + "mdp_mdp_aal0"), + GATE_MDP0(CLK_MDP_MDP_RSZ0, "mdp_mdp_rsz0", + "ck2_mdp_ck", 9), + GATE_MDP0_V(CLK_MDP_MDP_RSZ0_MML, "mdp_mdp_rsz0_mml", + "mdp_mdp_rsz0"), + GATE_MDP0(CLK_MDP_MDP_RSZ2, "mdp_mdp_rsz2", + "ck2_mdp_ck", 10), + GATE_MDP0_V(CLK_MDP_MDP_RSZ2_MML, "mdp_mdp_rsz2_mml", + "mdp_mdp_rsz2"), + GATE_MDP0(CLK_MDP_MDP_TDSHP0, "mdp_mdp_tdshp0", + "ck2_mdp_ck", 11), + GATE_MDP0_V(CLK_MDP_MDP_TDSHP0_MML, "mdp_mdp_tdshp0_mml", + "mdp_mdp_tdshp0"), + GATE_MDP0(CLK_MDP_MDP_COLOR0, "mdp_mdp_color0", + "ck2_mdp_ck", 12), + GATE_MDP0_V(CLK_MDP_MDP_COLOR0_MML, "mdp_mdp_color0_mml", + "mdp_mdp_color0"), + GATE_MDP0(CLK_MDP_MDP_WROT0, "mdp_mdp_wrot0", + "ck2_mdp_ck", 13), + GATE_MDP0_V(CLK_MDP_MDP_WROT0_MML, "mdp_mdp_wrot0_mml", + "mdp_mdp_wrot0"), + GATE_MDP0(CLK_MDP_MDP_WROT1, "mdp_mdp_wrot1", + "ck2_mdp_ck", 14), + GATE_MDP0_V(CLK_MDP_MDP_WROT1_MML, "mdp_mdp_wrot1_mml", + "mdp_mdp_wrot1"), + GATE_MDP0(CLK_MDP_MDP_WROT2, "mdp_mdp_wrot2", + "ck2_mdp_ck", 15), + GATE_MDP0_V(CLK_MDP_MDP_WROT2_MML, "mdp_mdp_wrot2_mml", + "mdp_mdp_wrot2"), + GATE_MDP0(CLK_MDP_MDP_FAKE_ENG0, "mdp_mdp_fake_eng0", + "ck2_mdp_ck", 16), + GATE_MDP0_V(CLK_MDP_MDP_FAKE_ENG0_MML, "mdp_mdp_fake_eng0_mml", + "mdp_mdp_fake_eng0"), + GATE_MDP0(CLK_MDP_APB_DB, "mdp_apb_db", + "ck2_mdp_ck", 17), + GATE_MDP0_V(CLK_MDP_APB_DB_MML, "mdp_apb_db_mml", + "mdp_apb_db"), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC0, "mdp_mdp_dli_async0", + "ck2_mdp_ck", 18), + GATE_MDP0_V(CLK_MDP_MDP_DLI_ASYNC0_MML, "mdp_mdp_dli_async0_mml", + "mdp_mdp_dli_async0"), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC1, "mdp_mdp_dli_async1", + "ck2_mdp_ck", 19), + GATE_MDP0_V(CLK_MDP_MDP_DLI_ASYNC1_MML, "mdp_mdp_dli_async1_mml", + "mdp_mdp_dli_async1"), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC0, "mdp_mdp_dlo_async0", + "ck2_mdp_ck", 20), + GATE_MDP0_V(CLK_MDP_MDP_DLO_ASYNC0_MML, "mdp_mdp_dlo_async0_mml", + "mdp_mdp_dlo_async0"), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC1, "mdp_mdp_dlo_async1", + "ck2_mdp_ck", 21), + GATE_MDP0_V(CLK_MDP_MDP_DLO_ASYNC1_MML, "mdp_mdp_dlo_async1_mml", + "mdp_mdp_dlo_async1"), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC2, "mdp_mdp_dli_async2", + "ck2_mdp_ck", 22), + GATE_MDP0_V(CLK_MDP_MDP_DLI_ASYNC2_MML, "mdp_mdp_dli_async2_mml", + "mdp_mdp_dli_async2"), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC2, "mdp_mdp_dlo_async2", + "ck2_mdp_ck", 23), + GATE_MDP0_V(CLK_MDP_MDP_DLO_ASYNC2_MML, "mdp_mdp_dlo_async2_mml", + "mdp_mdp_dlo_async2"), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC3, "mdp_mdp_dlo_async3", + "ck2_mdp_ck", 24), + GATE_MDP0_V(CLK_MDP_MDP_DLO_ASYNC3_MML, "mdp_mdp_dlo_async3_mml", + "mdp_mdp_dlo_async3"), + GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0", + "ck2_mdp_ck", 25), + GATE_MDP0_V(CLK_MDP_IMG_DL_ASYNC0_MML, "mdp_img_dl_async0_mml", + "mdp_img_dl_async0"), + GATE_MDP0(CLK_MDP_MDP_RROT0, "mdp_mdp_rrot0", + "ck2_mdp_ck", 26), + GATE_MDP0_V(CLK_MDP_MDP_RROT0_MML, "mdp_mdp_rrot0_mml", + "mdp_mdp_rrot0"), + GATE_MDP0(CLK_MDP_MDP_MERGE0, "mdp_mdp_merge0", + "ck2_mdp_ck", 27), + GATE_MDP0_V(CLK_MDP_MDP_MERGE0_MML, "mdp_mdp_merge0_mml", + "mdp_mdp_merge0"), + GATE_MDP0(CLK_MDP_MDP_C3D0, "mdp_mdp_c3d0", + "ck2_mdp_ck", 28), + GATE_MDP0_V(CLK_MDP_MDP_C3D0_MML, "mdp_mdp_c3d0_mml", + "mdp_mdp_c3d0"), + GATE_MDP0(CLK_MDP_MDP_FG0, "mdp_mdp_fg0", + "ck2_mdp_ck", 29), + GATE_MDP0_V(CLK_MDP_MDP_FG0_MML, "mdp_mdp_fg0_mml", + "mdp_mdp_fg0"), + GATE_MDP0(CLK_MDP_MDP_CLA2, "mdp_mdp_cla2", + "ck2_mdp_ck", 30), + GATE_MDP0_V(CLK_MDP_MDP_CLA2_MML, "mdp_mdp_cla2_mml", + "mdp_mdp_cla2"), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC4, "mdp_mdp_dlo_async4", + "ck2_mdp_ck", 31), + GATE_MDP0_V(CLK_MDP_MDP_DLO_ASYNC4_MML, "mdp_mdp_dlo_async4_mml", + "mdp_mdp_dlo_async4"), + /* MDP1 */ + GATE_MDP1(CLK_MDP_VPP_RSZ0, "mdp_vpp_rsz0", + "ck2_mdp_ck", 0), + GATE_MDP1_V(CLK_MDP_VPP_RSZ0_MML, "mdp_vpp_rsz0_mml", + "mdp_vpp_rsz0"), + GATE_MDP1(CLK_MDP_VPP_RSZ1, "mdp_vpp_rsz1", + "ck2_mdp_ck", 1), + GATE_MDP1_V(CLK_MDP_VPP_RSZ1_MML, "mdp_vpp_rsz1_mml", + "mdp_vpp_rsz1"), + GATE_MDP1(CLK_MDP_MDP_DLO_ASYNC5, "mdp_mdp_dlo_async5", + "ck2_mdp_ck", 2), + GATE_MDP1_V(CLK_MDP_MDP_DLO_ASYNC5_MML, "mdp_mdp_dlo_async5_mml", + "mdp_mdp_dlo_async5"), + GATE_MDP1(CLK_MDP_IMG0, "mdp_img0", + "ck2_mdp_ck", 3), + GATE_MDP1_V(CLK_MDP_IMG0_MML, "mdp_img0_mml", + "mdp_img0"), + GATE_MDP1(CLK_MDP_F26M, "mdp_f26m", + "ck_f26m_ck", 27), + GATE_MDP1_V(CLK_MDP_F26M_MML, "mdp_f26m_mml", + "mdp_f26m"), + /* MDP2 */ + GATE_MDP2(CLK_MDP_IMG_DL_RELAY0, "mdp_img_dl_relay0", + "ck2_mdp_ck", 0), + GATE_MDP2_V(CLK_MDP_IMG_DL_RELAY0_MML, "mdp_img_dl_relay0_mml", + "mdp_img_dl_relay0"), + GATE_MDP2(CLK_MDP_IMG_DL_RELAY1, "mdp_img_dl_relay1", + "ck2_mdp_ck", 8), + GATE_MDP2_V(CLK_MDP_IMG_DL_RELAY1_MML, "mdp_img_dl_relay1_mml", + "mdp_img_dl_relay1"), +}; + +static const struct mtk_clk_desc mdp_mcd = { + .clks = mdp_clks, + .num_clks = ARRAY_SIZE(mdp_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_mdpsys[] = { + { .compatible = "mediatek,mt8196-mdpsys1", .data = &mdp1_mcd, }, + { .compatible = "mediatek,mt8196-mdpsys", .data = &mdp_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_mdpsys_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-mdpsys", + .of_match_table = of_match_clk_mt8196_mdpsys, + }, +}; + +module_platform_driver(clk_mt8196_mdpsys_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mfg.c b/drivers/clk/mediatek/clk-mt8196-mfg.c new file mode 100644 index 0000000000000..9610c377edd0a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mfg.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MFGPLL_CON0 0x008 +#define MFGPLL_CON1 0x00c +#define MFGPLL_CON2 0x010 +#define MFGPLL_CON3 0x014 +#define MFGPLL_SC0_CON0 0x008 +#define MFGPLL_SC0_CON1 0x00c +#define MFGPLL_SC0_CON2 0x010 +#define MFGPLL_SC0_CON3 0x014 +#define MFGPLL_SC1_CON0 0x008 +#define MFGPLL_SC1_CON1 0x00c +#define MFGPLL_SC1_CON2 0x010 +#define MFGPLL_SC1_CON3 0x014 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL(_id, _name, _reg, _en_reg, _en_mask, _pll_en_bit, \ + _flags, _rst_bar_mask, \ + _pd_reg, _pd_shift, _tuner_reg, \ + _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .en_reg = _en_reg, \ + .en_mask = _en_mask, \ + .pll_en_bit = _pll_en_bit, \ + .flags = (_flags | CLK_FENC_ENABLE), \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data mfg_ao_plls[] = { + PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, + MFGPLL_CON0, 0, 0, 0, BIT(0), + MFGPLL_CON1, 24, 0, 0, 0, + MFGPLL_CON1, 0, 22), +}; + +static const struct mtk_pll_data mfgsc0_ao_plls[] = { + PLL(CLK_MFGSC0_AO_MFGPLL_SC0, "mfgpll-sc0", MFGPLL_SC0_CON0, + MFGPLL_SC0_CON0, 0, 0, 0, BIT(0), + MFGPLL_SC0_CON1, 24, 0, 0, 0, + MFGPLL_SC0_CON1, 0, 22), +}; + +static const struct mtk_pll_data mfgsc1_ao_plls[] = { + PLL(CLK_MFGSC1_AO_MFGPLL_SC1, "mfgpll-sc1", MFGPLL_SC1_CON0, + MFGPLL_SC1_CON0, 0, 0, 0, BIT(0), + MFGPLL_SC1_CON1, 24, 0, 0, 0, + MFGPLL_SC1_CON1, 0, 22), +}; + +static const struct of_device_id of_match_clk_mt8196_mfg[] = { + { .compatible = "mediatek,mt8196-mfgpll_pll_ctrl", .data = &mfg_ao_plls, }, + { .compatible = "mediatek,mt8196-mfgpll_sc0_pll_ctrl", .data = &mfgsc0_ao_plls, }, + { .compatible = "mediatek,mt8196-mfgpll_sc1_pll_ctrl", .data = &mfgsc1_ao_plls, }, + { /* sentinel */ } +}; + +static int clk_mt8196_mfg_probe(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls; + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int num_plls = 1; + int r; + + plls = of_device_get_match_data(&pdev->dev); + if (!plls) + return -EINVAL; + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + if (r) { + mtk_free_clk_data(clk_data); + return r; + } + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) { + mtk_clk_unregister_plls(plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); + return r; + } + + return 0; +} + +static void clk_mt8196_mfg_remove(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls = of_device_get_match_data(&pdev->dev); + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + int num_plls = 1; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(plls, num_plls, clk_data); + mtk_free_clk_data(clk_data); +} + +static struct platform_driver clk_mt8196_mfg_drv = { + .probe = clk_mt8196_mfg_probe, + .remove_new = clk_mt8196_mfg_remove, + .driver = { + .name = "clk-mt8196-mfg", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_mfg, + }, +}; + +module_platform_driver(clk_mt8196_mfg_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ovl0.c b/drivers/clk/mediatek/clk-mt8196-ovl0.c new file mode 100644 index 0000000000000..5405511778e5e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ovl0.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs ovl0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs ovl0_hwv_regs = { + .set_ofs = 0x0060, + .clr_ofs = 0x0064, + .sta_ofs = 0x2c30, +}; + +static const struct mtk_gate_regs ovl1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs ovl1_hwv_regs = { + .set_ofs = 0x0068, + .clr_ofs = 0x006c, + .sta_ofs = 0x2c34, +}; + +#define GATE_OVL0(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_OVL0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_OVL0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ovl0_cg_regs, \ + .hwv_regs = &ovl0_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_OVL1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_OVL1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_OVL1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ovl1_cg_regs, \ + .hwv_regs = &ovl1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ovl_clks[] = { + /* OVL0 */ + GATE_HWV_OVL0(CLK_OVLSYS_CONFIG, "ovlsys_config", + "ck2_disp_ck", 0), + GATE_OVL0_V(CLK_OVLSYS_CONFIG_DISP, "ovlsys_config_disp", + "ovlsys_config"), + GATE_HWV_OVL0(CLK_OVL_FAKE_ENG0, "ovl_fake_eng0", + "ck2_disp_ck", 1), + GATE_OVL0_V(CLK_OVL_FAKE_ENG0_DISP, "ovl_fake_eng0_disp", + "ovl_fake_eng0"), + GATE_HWV_OVL0(CLK_OVL_FAKE_ENG1, "ovl_fake_eng1", + "ck2_disp_ck", 2), + GATE_OVL0_V(CLK_OVL_FAKE_ENG1_DISP, "ovl_fake_eng1_disp", + "ovl_fake_eng1"), + GATE_HWV_OVL0(CLK_OVL_MUTEX0, "ovl_mutex0", + "ck2_disp_ck", 3), + GATE_OVL0_V(CLK_OVL_MUTEX0_DISP, "ovl_mutex0_disp", + "ovl_mutex0"), + GATE_HWV_OVL0(CLK_OVL_EXDMA0, "ovl_exdma0", + "ck2_disp_ck", 4), + GATE_OVL0_V(CLK_OVL_EXDMA0_DISP, "ovl_exdma0_disp", + "ovl_exdma0"), + GATE_HWV_OVL0(CLK_OVL_EXDMA1, "ovl_exdma1", + "ck2_disp_ck", 5), + GATE_OVL0_V(CLK_OVL_EXDMA1_DISP, "ovl_exdma1_disp", + "ovl_exdma1"), + GATE_HWV_OVL0(CLK_OVL_EXDMA2, "ovl_exdma2", + "ck2_disp_ck", 6), + GATE_OVL0_V(CLK_OVL_EXDMA2_DISP, "ovl_exdma2_disp", + "ovl_exdma2"), + GATE_HWV_OVL0(CLK_OVL_EXDMA3, "ovl_exdma3", + "ck2_disp_ck", 7), + GATE_OVL0_V(CLK_OVL_EXDMA3_DISP, "ovl_exdma3_disp", + "ovl_exdma3"), + GATE_HWV_OVL0(CLK_OVL_EXDMA4, "ovl_exdma4", + "ck2_disp_ck", 8), + GATE_OVL0_V(CLK_OVL_EXDMA4_DISP, "ovl_exdma4_disp", + "ovl_exdma4"), + GATE_HWV_OVL0(CLK_OVL_EXDMA5, "ovl_exdma5", + "ck2_disp_ck", 9), + GATE_OVL0_V(CLK_OVL_EXDMA5_DISP, "ovl_exdma5_disp", + "ovl_exdma5"), + GATE_HWV_OVL0(CLK_OVL_EXDMA6, "ovl_exdma6", + "ck2_disp_ck", 10), + GATE_OVL0_V(CLK_OVL_EXDMA6_DISP, "ovl_exdma6_disp", + "ovl_exdma6"), + GATE_HWV_OVL0(CLK_OVL_EXDMA7, "ovl_exdma7", + "ck2_disp_ck", 11), + GATE_OVL0_V(CLK_OVL_EXDMA7_DISP, "ovl_exdma7_disp", + "ovl_exdma7"), + GATE_HWV_OVL0(CLK_OVL_EXDMA8, "ovl_exdma8", + "ck2_disp_ck", 12), + GATE_OVL0_V(CLK_OVL_EXDMA8_DISP, "ovl_exdma8_disp", + "ovl_exdma8"), + GATE_HWV_OVL0(CLK_OVL_EXDMA9, "ovl_exdma9", + "ck2_disp_ck", 13), + GATE_OVL0_V(CLK_OVL_EXDMA9_DISP, "ovl_exdma9_disp", + "ovl_exdma9"), + GATE_HWV_OVL0(CLK_OVL_BLENDER0, "ovl_blender0", + "ck2_disp_ck", 14), + GATE_OVL0_V(CLK_OVL_BLENDER0_DISP, "ovl_blender0_disp", + "ovl_blender0"), + GATE_HWV_OVL0(CLK_OVL_BLENDER1, "ovl_blender1", + "ck2_disp_ck", 15), + GATE_OVL0_V(CLK_OVL_BLENDER1_DISP, "ovl_blender1_disp", + "ovl_blender1"), + GATE_HWV_OVL0(CLK_OVL_BLENDER2, "ovl_blender2", + "ck2_disp_ck", 16), + GATE_OVL0_V(CLK_OVL_BLENDER2_DISP, "ovl_blender2_disp", + "ovl_blender2"), + GATE_HWV_OVL0(CLK_OVL_BLENDER3, "ovl_blender3", + "ck2_disp_ck", 17), + GATE_OVL0_V(CLK_OVL_BLENDER3_DISP, "ovl_blender3_disp", + "ovl_blender3"), + GATE_HWV_OVL0(CLK_OVL_BLENDER4, "ovl_blender4", + "ck2_disp_ck", 18), + GATE_OVL0_V(CLK_OVL_BLENDER4_DISP, "ovl_blender4_disp", + "ovl_blender4"), + GATE_HWV_OVL0(CLK_OVL_BLENDER5, "ovl_blender5", + "ck2_disp_ck", 19), + GATE_OVL0_V(CLK_OVL_BLENDER5_DISP, "ovl_blender5_disp", + "ovl_blender5"), + GATE_HWV_OVL0(CLK_OVL_BLENDER6, "ovl_blender6", + "ck2_disp_ck", 20), + GATE_OVL0_V(CLK_OVL_BLENDER6_DISP, "ovl_blender6_disp", + "ovl_blender6"), + GATE_HWV_OVL0(CLK_OVL_BLENDER7, "ovl_blender7", + "ck2_disp_ck", 21), + GATE_OVL0_V(CLK_OVL_BLENDER7_DISP, "ovl_blender7_disp", + "ovl_blender7"), + GATE_HWV_OVL0(CLK_OVL_BLENDER8, "ovl_blender8", + "ck2_disp_ck", 22), + GATE_OVL0_V(CLK_OVL_BLENDER8_DISP, "ovl_blender8_disp", + "ovl_blender8"), + GATE_HWV_OVL0(CLK_OVL_BLENDER9, "ovl_blender9", + "ck2_disp_ck", 23), + GATE_OVL0_V(CLK_OVL_BLENDER9_DISP, "ovl_blender9_disp", + "ovl_blender9"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC0, "ovl_outproc0", + "ck2_disp_ck", 24), + GATE_OVL0_V(CLK_OVL_OUTPROC0_DISP, "ovl_outproc0_disp", + "ovl_outproc0"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC1, "ovl_outproc1", + "ck2_disp_ck", 25), + GATE_OVL0_V(CLK_OVL_OUTPROC1_DISP, "ovl_outproc1_disp", + "ovl_outproc1"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC2, "ovl_outproc2", + "ck2_disp_ck", 26), + GATE_OVL0_V(CLK_OVL_OUTPROC2_DISP, "ovl_outproc2_disp", + "ovl_outproc2"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC3, "ovl_outproc3", + "ck2_disp_ck", 27), + GATE_OVL0_V(CLK_OVL_OUTPROC3_DISP, "ovl_outproc3_disp", + "ovl_outproc3"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC4, "ovl_outproc4", + "ck2_disp_ck", 28), + GATE_OVL0_V(CLK_OVL_OUTPROC4_DISP, "ovl_outproc4_disp", + "ovl_outproc4"), + GATE_HWV_OVL0(CLK_OVL_OUTPROC5, "ovl_outproc5", + "ck2_disp_ck", 29), + GATE_OVL0_V(CLK_OVL_OUTPROC5_DISP, "ovl_outproc5_disp", + "ovl_outproc5"), + GATE_HWV_OVL0(CLK_OVL_MDP_RSZ0, "ovl_mdp_rsz0", + "ck2_disp_ck", 30), + GATE_OVL0_V(CLK_OVL_MDP_RSZ0_DISP, "ovl_mdp_rsz0_disp", + "ovl_mdp_rsz0"), + GATE_HWV_OVL0(CLK_OVL_MDP_RSZ1, "ovl_mdp_rsz1", + "ck2_disp_ck", 31), + GATE_OVL0_V(CLK_OVL_MDP_RSZ1_DISP, "ovl_mdp_rsz1_disp", + "ovl_mdp_rsz1"), + /* OVL1 */ + GATE_HWV_OVL1(CLK_OVL_DISP_WDMA0, "ovl_disp_wdma0", + "ck2_disp_ck", 0), + GATE_OVL1_V(CLK_OVL_DISP_WDMA0_DISP, "ovl_disp_wdma0_disp", + "ovl_disp_wdma0"), + GATE_HWV_OVL1(CLK_OVL_DISP_WDMA1, "ovl_disp_wdma1", + "ck2_disp_ck", 1), + GATE_OVL1_V(CLK_OVL_DISP_WDMA1_DISP, "ovl_disp_wdma1_disp", + "ovl_disp_wdma1"), + GATE_HWV_OVL1(CLK_OVL_UFBC_WDMA0, "ovl_ufbc_wdma0", + "ck2_disp_ck", 2), + GATE_OVL1_V(CLK_OVL_UFBC_WDMA0_DISP, "ovl_ufbc_wdma0_disp", + "ovl_ufbc_wdma0"), + GATE_HWV_OVL1(CLK_OVL_MDP_RDMA0, "ovl_mdp_rdma0", + "ck2_disp_ck", 3), + GATE_OVL1_V(CLK_OVL_MDP_RDMA0_DISP, "ovl_mdp_rdma0_disp", + "ovl_mdp_rdma0"), + GATE_HWV_OVL1(CLK_OVL_MDP_RDMA1, "ovl_mdp_rdma1", + "ck2_disp_ck", 4), + GATE_OVL1_V(CLK_OVL_MDP_RDMA1_DISP, "ovl_mdp_rdma1_disp", + "ovl_mdp_rdma1"), + GATE_HWV_OVL1(CLK_OVL_BWM0, "ovl_bwm0", + "ck2_disp_ck", 5), + GATE_OVL1_V(CLK_OVL_BWM0_DISP, "ovl_bwm0_disp", + "ovl_bwm0"), + GATE_HWV_OVL1(CLK_OVL_DLI0, "ovl_dli0", + "ck2_disp_ck", 6), + GATE_OVL1_V(CLK_OVL_DLI0_DISP, "ovl_dli0_disp", + "ovl_dli0"), + GATE_HWV_OVL1(CLK_OVL_DLI1, "ovl_dli1", + "ck2_disp_ck", 7), + GATE_OVL1_V(CLK_OVL_DLI1_DISP, "ovl_dli1_disp", + "ovl_dli1"), + GATE_HWV_OVL1(CLK_OVL_DLI2, "ovl_dli2", + "ck2_disp_ck", 8), + GATE_OVL1_V(CLK_OVL_DLI2_DISP, "ovl_dli2_disp", + "ovl_dli2"), + GATE_HWV_OVL1(CLK_OVL_DLI3, "ovl_dli3", + "ck2_disp_ck", 9), + GATE_OVL1_V(CLK_OVL_DLI3_DISP, "ovl_dli3_disp", + "ovl_dli3"), + GATE_HWV_OVL1(CLK_OVL_DLI4, "ovl_dli4", + "ck2_disp_ck", 10), + GATE_OVL1_V(CLK_OVL_DLI4_DISP, "ovl_dli4_disp", + "ovl_dli4"), + GATE_HWV_OVL1(CLK_OVL_DLI5, "ovl_dli5", + "ck2_disp_ck", 11), + GATE_OVL1_V(CLK_OVL_DLI5_DISP, "ovl_dli5_disp", + "ovl_dli5"), + GATE_HWV_OVL1(CLK_OVL_DLI6, "ovl_dli6", + "ck2_disp_ck", 12), + GATE_OVL1_V(CLK_OVL_DLI6_DISP, "ovl_dli6_disp", + "ovl_dli6"), + GATE_HWV_OVL1(CLK_OVL_DLI7, "ovl_dli7", + "ck2_disp_ck", 13), + GATE_OVL1_V(CLK_OVL_DLI7_DISP, "ovl_dli7_disp", + "ovl_dli7"), + GATE_HWV_OVL1(CLK_OVL_DLI8, "ovl_dli8", + "ck2_disp_ck", 14), + GATE_OVL1_V(CLK_OVL_DLI8_DISP, "ovl_dli8_disp", + "ovl_dli8"), + GATE_HWV_OVL1(CLK_OVL_DLO0, "ovl_dlo0", + "ck2_disp_ck", 15), + GATE_OVL1_V(CLK_OVL_DLO0_DISP, "ovl_dlo0_disp", + "ovl_dlo0"), + GATE_HWV_OVL1(CLK_OVL_DLO1, "ovl_dlo1", + "ck2_disp_ck", 16), + GATE_OVL1_V(CLK_OVL_DLO1_DISP, "ovl_dlo1_disp", + "ovl_dlo1"), + GATE_HWV_OVL1(CLK_OVL_DLO2, "ovl_dlo2", + "ck2_disp_ck", 17), + GATE_OVL1_V(CLK_OVL_DLO2_DISP, "ovl_dlo2_disp", + "ovl_dlo2"), + GATE_HWV_OVL1(CLK_OVL_DLO3, "ovl_dlo3", + "ck2_disp_ck", 18), + GATE_OVL1_V(CLK_OVL_DLO3_DISP, "ovl_dlo3_disp", + "ovl_dlo3"), + GATE_HWV_OVL1(CLK_OVL_DLO4, "ovl_dlo4", + "ck2_disp_ck", 19), + GATE_OVL1_V(CLK_OVL_DLO4_DISP, "ovl_dlo4_disp", + "ovl_dlo4"), + GATE_HWV_OVL1(CLK_OVL_DLO5, "ovl_dlo5", + "ck2_disp_ck", 20), + GATE_OVL1_V(CLK_OVL_DLO5_DISP, "ovl_dlo5_disp", + "ovl_dlo5"), + GATE_HWV_OVL1(CLK_OVL_DLO6, "ovl_dlo6", + "ck2_disp_ck", 21), + GATE_OVL1_V(CLK_OVL_DLO6_DISP, "ovl_dlo6_disp", + "ovl_dlo6"), + GATE_HWV_OVL1(CLK_OVL_DLO7, "ovl_dlo7", + "ck2_disp_ck", 22), + GATE_OVL1_V(CLK_OVL_DLO7_DISP, "ovl_dlo7_disp", + "ovl_dlo7"), + GATE_HWV_OVL1(CLK_OVL_DLO8, "ovl_dlo8", + "ck2_disp_ck", 23), + GATE_OVL1_V(CLK_OVL_DLO8_DISP, "ovl_dlo8_disp", + "ovl_dlo8"), + GATE_HWV_OVL1(CLK_OVL_DLO9, "ovl_dlo9", + "ck2_disp_ck", 24), + GATE_OVL1_V(CLK_OVL_DLO9_DISP, "ovl_dlo9_disp", + "ovl_dlo9"), + GATE_HWV_OVL1(CLK_OVL_DLO10, "ovl_dlo10", + "ck2_disp_ck", 25), + GATE_OVL1_V(CLK_OVL_DLO10_DISP, "ovl_dlo10_disp", + "ovl_dlo10"), + GATE_HWV_OVL1(CLK_OVL_DLO11, "ovl_dlo11", + "ck2_disp_ck", 26), + GATE_OVL1_V(CLK_OVL_DLO11_DISP, "ovl_dlo11_disp", + "ovl_dlo11"), + GATE_HWV_OVL1(CLK_OVL_DLO12, "ovl_dlo12", + "ck2_disp_ck", 27), + GATE_OVL1_V(CLK_OVL_DLO12_DISP, "ovl_dlo12_disp", + "ovl_dlo12"), + GATE_HWV_OVL1(CLK_OVLSYS_RELAY0, "ovlsys_relay0", + "ck2_disp_ck", 28), + GATE_OVL1_V(CLK_OVLSYS_RELAY0_DISP, "ovlsys_relay0_disp", + "ovlsys_relay0"), + GATE_HWV_OVL1(CLK_OVL_INLINEROT0, "ovl_inlinerot0", + "ck2_disp_ck", 29), + GATE_OVL1_V(CLK_OVL_INLINEROT0_DISP, "ovl_inlinerot0_disp", + "ovl_inlinerot0"), + GATE_HWV_OVL1(CLK_OVL_SMI, "ovl_smi", + "ck2_disp_ck", 30), + GATE_OVL1_V(CLK_OVL_SMI_SMI, "ovl_smi_smi", + "ovl_smi"), +}; + +static const struct mtk_clk_desc ovl_mcd = { + .clks = ovl_clks, + .num_clks = ARRAY_SIZE(ovl_clks), +}; + +static const struct platform_device_id clk_mt8196_ovl0_id_table[] = { + { .name = "clk-mt8196-ovl0", .driver_data = (kernel_ulong_t)&ovl_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_ovl0_id_table); + +static struct platform_driver clk_mt8196_ovl0_drv = { + .probe = mtk_clk_pdev_probe, + .remove_new = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-ovl0", + }, + .id_table = clk_mt8196_ovl0_id_table, +}; + +module_platform_driver(clk_mt8196_ovl0_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ovl1.c b/drivers/clk/mediatek/clk-mt8196-ovl1.c new file mode 100644 index 0000000000000..e6624f62296bd --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ovl1.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs ovl10_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs ovl10_hwv_regs = { + .set_ofs = 0x0050, + .clr_ofs = 0x0054, + .sta_ofs = 0x2c28, +}; + +static const struct mtk_gate_regs ovl11_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs ovl11_hwv_regs = { + .set_ofs = 0x0058, + .clr_ofs = 0x005c, + .sta_ofs = 0x2c2c, +}; + +#define GATE_OVL10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_OVL10_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_OVL10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ovl10_cg_regs, \ + .hwv_regs = &ovl10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_OVL11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_OVL11_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_OVL11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ovl11_cg_regs, \ + .hwv_regs = &ovl11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ovl1_clks[] = { + /* OVL10 */ + GATE_HWV_OVL10(CLK_OVL1_OVLSYS_CONFIG, "ovl1_ovlsys_config", + "ck2_disp_ck", 0), + GATE_OVL10_V(CLK_OVL1_OVLSYS_CONFIG_DISP, "ovl1_ovlsys_config_disp", + "ovl1_ovlsys_config"), + GATE_HWV_OVL10(CLK_OVL1_OVL_FAKE_ENG0, "ovl1_ovl_fake_eng0", + "ck2_disp_ck", 1), + GATE_OVL10_V(CLK_OVL1_OVL_FAKE_ENG0_DISP, "ovl1_ovl_fake_eng0_disp", + "ovl1_ovl_fake_eng0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_FAKE_ENG1, "ovl1_ovl_fake_eng1", + "ck2_disp_ck", 2), + GATE_OVL10_V(CLK_OVL1_OVL_FAKE_ENG1_DISP, "ovl1_ovl_fake_eng1_disp", + "ovl1_ovl_fake_eng1"), + GATE_HWV_OVL10(CLK_OVL1_OVL_MUTEX0, "ovl1_ovl_mutex0", + "ck2_disp_ck", 3), + GATE_OVL10_V(CLK_OVL1_OVL_MUTEX0_DISP, "ovl1_ovl_mutex0_disp", + "ovl1_ovl_mutex0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA0, "ovl1_ovl_exdma0", + "ck2_disp_ck", 4), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA0_DISP, "ovl1_ovl_exdma0_disp", + "ovl1_ovl_exdma0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA1, "ovl1_ovl_exdma1", + "ck2_disp_ck", 5), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA1_DISP, "ovl1_ovl_exdma1_disp", + "ovl1_ovl_exdma1"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA2, "ovl1_ovl_exdma2", + "ck2_disp_ck", 6), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA2_DISP, "ovl1_ovl_exdma2_disp", + "ovl1_ovl_exdma2"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA3, "ovl1_ovl_exdma3", + "ck2_disp_ck", 7), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA3_DISP, "ovl1_ovl_exdma3_disp", + "ovl1_ovl_exdma3"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA4, "ovl1_ovl_exdma4", + "ck2_disp_ck", 8), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA4_DISP, "ovl1_ovl_exdma4_disp", + "ovl1_ovl_exdma4"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA5, "ovl1_ovl_exdma5", + "ck2_disp_ck", 9), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA5_DISP, "ovl1_ovl_exdma5_disp", + "ovl1_ovl_exdma5"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA6, "ovl1_ovl_exdma6", + "ck2_disp_ck", 10), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA6_DISP, "ovl1_ovl_exdma6_disp", + "ovl1_ovl_exdma6"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA7, "ovl1_ovl_exdma7", + "ck2_disp_ck", 11), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA7_DISP, "ovl1_ovl_exdma7_disp", + "ovl1_ovl_exdma7"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA8, "ovl1_ovl_exdma8", + "ck2_disp_ck", 12), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA8_DISP, "ovl1_ovl_exdma8_disp", + "ovl1_ovl_exdma8"), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA9, "ovl1_ovl_exdma9", + "ck2_disp_ck", 13), + GATE_OVL10_V(CLK_OVL1_OVL_EXDMA9_DISP, "ovl1_ovl_exdma9_disp", + "ovl1_ovl_exdma9"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER0, "ovl1_ovl_blender0", + "ck2_disp_ck", 14), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER0_DISP, "ovl1_ovl_blender0_disp", + "ovl1_ovl_blender0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER1, "ovl1_ovl_blender1", + "ck2_disp_ck", 15), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER1_DISP, "ovl1_ovl_blender1_disp", + "ovl1_ovl_blender1"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER2, "ovl1_ovl_blender2", + "ck2_disp_ck", 16), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER2_DISP, "ovl1_ovl_blender2_disp", + "ovl1_ovl_blender2"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER3, "ovl1_ovl_blender3", + "ck2_disp_ck", 17), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER3_DISP, "ovl1_ovl_blender3_disp", + "ovl1_ovl_blender3"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER4, "ovl1_ovl_blender4", + "ck2_disp_ck", 18), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER4_DISP, "ovl1_ovl_blender4_disp", + "ovl1_ovl_blender4"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER5, "ovl1_ovl_blender5", + "ck2_disp_ck", 19), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER5_DISP, "ovl1_ovl_blender5_disp", + "ovl1_ovl_blender5"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER6, "ovl1_ovl_blender6", + "ck2_disp_ck", 20), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER6_DISP, "ovl1_ovl_blender6_disp", + "ovl1_ovl_blender6"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER7, "ovl1_ovl_blender7", + "ck2_disp_ck", 21), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER7_DISP, "ovl1_ovl_blender7_disp", + "ovl1_ovl_blender7"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER8, "ovl1_ovl_blender8", + "ck2_disp_ck", 22), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER8_DISP, "ovl1_ovl_blender8_disp", + "ovl1_ovl_blender8"), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER9, "ovl1_ovl_blender9", + "ck2_disp_ck", 23), + GATE_OVL10_V(CLK_OVL1_OVL_BLENDER9_DISP, "ovl1_ovl_blender9_disp", + "ovl1_ovl_blender9"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC0, "ovl1_ovl_outproc0", + "ck2_disp_ck", 24), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC0_DISP, "ovl1_ovl_outproc0_disp", + "ovl1_ovl_outproc0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC1, "ovl1_ovl_outproc1", + "ck2_disp_ck", 25), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC1_DISP, "ovl1_ovl_outproc1_disp", + "ovl1_ovl_outproc1"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC2, "ovl1_ovl_outproc2", + "ck2_disp_ck", 26), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC2_DISP, "ovl1_ovl_outproc2_disp", + "ovl1_ovl_outproc2"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC3, "ovl1_ovl_outproc3", + "ck2_disp_ck", 27), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC3_DISP, "ovl1_ovl_outproc3_disp", + "ovl1_ovl_outproc3"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC4, "ovl1_ovl_outproc4", + "ck2_disp_ck", 28), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC4_DISP, "ovl1_ovl_outproc4_disp", + "ovl1_ovl_outproc4"), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC5, "ovl1_ovl_outproc5", + "ck2_disp_ck", 29), + GATE_OVL10_V(CLK_OVL1_OVL_OUTPROC5_DISP, "ovl1_ovl_outproc5_disp", + "ovl1_ovl_outproc5"), + GATE_HWV_OVL10(CLK_OVL1_OVL_MDP_RSZ0, "ovl1_ovl_mdp_rsz0", + "ck2_disp_ck", 30), + GATE_OVL10_V(CLK_OVL1_OVL_MDP_RSZ0_DISP, "ovl1_ovl_mdp_rsz0_disp", + "ovl1_ovl_mdp_rsz0"), + GATE_HWV_OVL10(CLK_OVL1_OVL_MDP_RSZ1, "ovl1_ovl_mdp_rsz1", + "ck2_disp_ck", 31), + GATE_OVL10_V(CLK_OVL1_OVL_MDP_RSZ1_DISP, "ovl1_ovl_mdp_rsz1_disp", + "ovl1_ovl_mdp_rsz1"), + /* OVL11 */ + GATE_HWV_OVL11(CLK_OVL1_OVL_DISP_WDMA0, "ovl1_ovl_disp_wdma0", + "ck2_disp_ck", 0), + GATE_OVL11_V(CLK_OVL1_OVL_DISP_WDMA0_DISP, "ovl1_ovl_disp_wdma0_disp", + "ovl1_ovl_disp_wdma0"), + GATE_HWV_OVL11(CLK_OVL1_OVL_DISP_WDMA1, "ovl1_ovl_disp_wdma1", + "ck2_disp_ck", 1), + GATE_OVL11_V(CLK_OVL1_OVL_DISP_WDMA1_DISP, "ovl1_ovl_disp_wdma1_disp", + "ovl1_ovl_disp_wdma1"), + GATE_HWV_OVL11(CLK_OVL1_OVL_UFBC_WDMA0, "ovl1_ovl_ufbc_wdma0", + "ck2_disp_ck", 2), + GATE_OVL11_V(CLK_OVL1_OVL_UFBC_WDMA0_DISP, "ovl1_ovl_ufbc_wdma0_disp", + "ovl1_ovl_ufbc_wdma0"), + GATE_HWV_OVL11(CLK_OVL1_OVL_MDP_RDMA0, "ovl1_ovl_mdp_rdma0", + "ck2_disp_ck", 3), + GATE_OVL11_V(CLK_OVL1_OVL_MDP_RDMA0_DISP, "ovl1_ovl_mdp_rdma0_disp", + "ovl1_ovl_mdp_rdma0"), + GATE_HWV_OVL11(CLK_OVL1_OVL_MDP_RDMA1, "ovl1_ovl_mdp_rdma1", + "ck2_disp_ck", 4), + GATE_OVL11_V(CLK_OVL1_OVL_MDP_RDMA1_DISP, "ovl1_ovl_mdp_rdma1_disp", + "ovl1_ovl_mdp_rdma1"), + GATE_HWV_OVL11(CLK_OVL1_OVL_BWM0, "ovl1_ovl_bwm0", + "ck2_disp_ck", 5), + GATE_OVL11_V(CLK_OVL1_OVL_BWM0_DISP, "ovl1_ovl_bwm0_disp", + "ovl1_ovl_bwm0"), + GATE_HWV_OVL11(CLK_OVL1_DLI0, "ovl1_dli0", + "ck2_disp_ck", 6), + GATE_OVL11_V(CLK_OVL1_DLI0_DISP, "ovl1_dli0_disp", + "ovl1_dli0"), + GATE_HWV_OVL11(CLK_OVL1_DLI1, "ovl1_dli1", + "ck2_disp_ck", 7), + GATE_OVL11_V(CLK_OVL1_DLI1_DISP, "ovl1_dli1_disp", + "ovl1_dli1"), + GATE_HWV_OVL11(CLK_OVL1_DLI2, "ovl1_dli2", + "ck2_disp_ck", 8), + GATE_OVL11_V(CLK_OVL1_DLI2_DISP, "ovl1_dli2_disp", + "ovl1_dli2"), + GATE_HWV_OVL11(CLK_OVL1_DLI3, "ovl1_dli3", + "ck2_disp_ck", 9), + GATE_OVL11_V(CLK_OVL1_DLI3_DISP, "ovl1_dli3_disp", + "ovl1_dli3"), + GATE_HWV_OVL11(CLK_OVL1_DLI4, "ovl1_dli4", + "ck2_disp_ck", 10), + GATE_OVL11_V(CLK_OVL1_DLI4_DISP, "ovl1_dli4_disp", + "ovl1_dli4"), + GATE_HWV_OVL11(CLK_OVL1_DLI5, "ovl1_dli5", + "ck2_disp_ck", 11), + GATE_OVL11_V(CLK_OVL1_DLI5_DISP, "ovl1_dli5_disp", + "ovl1_dli5"), + GATE_HWV_OVL11(CLK_OVL1_DLI6, "ovl1_dli6", + "ck2_disp_ck", 12), + GATE_OVL11_V(CLK_OVL1_DLI6_DISP, "ovl1_dli6_disp", + "ovl1_dli6"), + GATE_HWV_OVL11(CLK_OVL1_DLI7, "ovl1_dli7", + "ck2_disp_ck", 13), + GATE_OVL11_V(CLK_OVL1_DLI7_DISP, "ovl1_dli7_disp", + "ovl1_dli7"), + GATE_HWV_OVL11(CLK_OVL1_DLI8, "ovl1_dli8", + "ck2_disp_ck", 14), + GATE_OVL11_V(CLK_OVL1_DLI8_DISP, "ovl1_dli8_disp", + "ovl1_dli8"), + GATE_HWV_OVL11(CLK_OVL1_DLO0, "ovl1_dlo0", + "ck2_disp_ck", 15), + GATE_OVL11_V(CLK_OVL1_DLO0_DISP, "ovl1_dlo0_disp", + "ovl1_dlo0"), + GATE_HWV_OVL11(CLK_OVL1_DLO1, "ovl1_dlo1", + "ck2_disp_ck", 16), + GATE_OVL11_V(CLK_OVL1_DLO1_DISP, "ovl1_dlo1_disp", + "ovl1_dlo1"), + GATE_HWV_OVL11(CLK_OVL1_DLO2, "ovl1_dlo2", + "ck2_disp_ck", 17), + GATE_OVL11_V(CLK_OVL1_DLO2_DISP, "ovl1_dlo2_disp", + "ovl1_dlo2"), + GATE_HWV_OVL11(CLK_OVL1_DLO3, "ovl1_dlo3", + "ck2_disp_ck", 18), + GATE_OVL11_V(CLK_OVL1_DLO3_DISP, "ovl1_dlo3_disp", + "ovl1_dlo3"), + GATE_HWV_OVL11(CLK_OVL1_DLO4, "ovl1_dlo4", + "ck2_disp_ck", 19), + GATE_OVL11_V(CLK_OVL1_DLO4_DISP, "ovl1_dlo4_disp", + "ovl1_dlo4"), + GATE_HWV_OVL11(CLK_OVL1_DLO5, "ovl1_dlo5", + "ck2_disp_ck", 20), + GATE_OVL11_V(CLK_OVL1_DLO5_DISP, "ovl1_dlo5_disp", + "ovl1_dlo5"), + GATE_HWV_OVL11(CLK_OVL1_DLO6, "ovl1_dlo6", + "ck2_disp_ck", 21), + GATE_OVL11_V(CLK_OVL1_DLO6_DISP, "ovl1_dlo6_disp", + "ovl1_dlo6"), + GATE_HWV_OVL11(CLK_OVL1_DLO7, "ovl1_dlo7", + "ck2_disp_ck", 22), + GATE_OVL11_V(CLK_OVL1_DLO7_DISP, "ovl1_dlo7_disp", + "ovl1_dlo7"), + GATE_HWV_OVL11(CLK_OVL1_DLO8, "ovl1_dlo8", + "ck2_disp_ck", 23), + GATE_OVL11_V(CLK_OVL1_DLO8_DISP, "ovl1_dlo8_disp", + "ovl1_dlo8"), + GATE_HWV_OVL11(CLK_OVL1_DLO9, "ovl1_dlo9", + "ck2_disp_ck", 24), + GATE_OVL11_V(CLK_OVL1_DLO9_DISP, "ovl1_dlo9_disp", + "ovl1_dlo9"), + GATE_HWV_OVL11(CLK_OVL1_DLO10, "ovl1_dlo10", + "ck2_disp_ck", 25), + GATE_OVL11_V(CLK_OVL1_DLO10_DISP, "ovl1_dlo10_disp", + "ovl1_dlo10"), + GATE_HWV_OVL11(CLK_OVL1_DLO11, "ovl1_dlo11", + "ck2_disp_ck", 26), + GATE_OVL11_V(CLK_OVL1_DLO11_DISP, "ovl1_dlo11_disp", + "ovl1_dlo11"), + GATE_HWV_OVL11(CLK_OVL1_DLO12, "ovl1_dlo12", + "ck2_disp_ck", 27), + GATE_OVL11_V(CLK_OVL1_DLO12_DISP, "ovl1_dlo12_disp", + "ovl1_dlo12"), + GATE_HWV_OVL11(CLK_OVL1_OVLSYS_RELAY0, "ovl1_ovlsys_relay0", + "ck2_disp_ck", 28), + GATE_OVL11_V(CLK_OVL1_OVLSYS_RELAY0_DISP, "ovl1_ovlsys_relay0_disp", + "ovl1_ovlsys_relay0"), + GATE_HWV_OVL11(CLK_OVL1_OVL_INLINEROT0, "ovl1_ovl_inlinerot0", + "ck2_disp_ck", 29), + GATE_OVL11_V(CLK_OVL1_OVL_INLINEROT0_DISP, "ovl1_ovl_inlinerot0_disp", + "ovl1_ovl_inlinerot0"), + GATE_HWV_OVL11(CLK_OVL1_SMI, "ovl1_smi", + "ck2_disp_ck", 30), + GATE_OVL11_V(CLK_OVL1_SMI_SMI, "ovl1_smi_smi", + "ovl1_smi"), +}; + +static const struct mtk_clk_desc ovl1_mcd = { + .clks = ovl1_clks, + .num_clks = ARRAY_SIZE(ovl1_clks), +}; + +static const struct platform_device_id clk_mt8196_ovl1_id_table[] = { + { .name = "clk-mt8196-ovl1", .driver_data = (kernel_ulong_t)&ovl1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_ovl1_id_table); + +static struct platform_driver clk_mt8196_ovl1_drv = { + .probe = mtk_clk_pdev_probe, + .remove_new = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-ovl1", + }, + .id_table = clk_mt8196_ovl1_id_table, +}; + +module_platform_driver(clk_mt8196_ovl1_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-peri_ao.c b/drivers/clk/mediatek/clk-mt8196-peri_ao.c new file mode 100644 index 0000000000000..b8c7738fc619a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-peri_ao.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs perao0_cg_regs = { + .set_ofs = 0x24, + .clr_ofs = 0x28, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs perao1_cg_regs = { + .set_ofs = 0x2c, + .clr_ofs = 0x30, + .sta_ofs = 0x14, +}; + +static const struct mtk_gate_regs perao1_hwv_regs = { + .set_ofs = 0x0008, + .clr_ofs = 0x000c, + .sta_ofs = 0x2c04, +}; + +static const struct mtk_gate_regs perao2_cg_regs = { + .set_ofs = 0x34, + .clr_ofs = 0x38, + .sta_ofs = 0x18, +}; + +#define GATE_PERAO0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &perao0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERAO0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_PERAO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &perao1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERAO1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_PERAO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "hw-voter-regmap", \ + .regs = &perao1_cg_regs, \ + .hwv_regs = &perao1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_PERAO2(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &perao2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERAO2_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate perao_clks[] = { + /* PERAO0 */ + GATE_PERAO0(CLK_PERAO_UART0_BCLK, "perao_uart0_bclk", + "ck_uart_ck", 0), + GATE_PERAO0_V(CLK_PERAO_UART0_BCLK_UART, "perao_uart0_bclk_uart", + "perao_uart0_bclk"), + GATE_PERAO0(CLK_PERAO_UART1_BCLK, "perao_uart1_bclk", + "ck_uart_ck", 1), + GATE_PERAO0_V(CLK_PERAO_UART1_BCLK_UART, "perao_uart1_bclk_uart", + "perao_uart1_bclk"), + GATE_PERAO0(CLK_PERAO_UART2_BCLK, "perao_uart2_bclk", + "ck_uart_ck", 2), + GATE_PERAO0_V(CLK_PERAO_UART2_BCLK_UART, "perao_uart2_bclk_uart", + "perao_uart2_bclk"), + GATE_PERAO0(CLK_PERAO_UART3_BCLK, "perao_uart3_bclk", + "ck_uart_ck", 3), + GATE_PERAO0_V(CLK_PERAO_UART3_BCLK_UART, "perao_uart3_bclk_uart", + "perao_uart3_bclk"), + GATE_PERAO0(CLK_PERAO_UART4_BCLK, "perao_uart4_bclk", + "ck_uart_ck", 4), + GATE_PERAO0_V(CLK_PERAO_UART4_BCLK_UART, "perao_uart4_bclk_uart", + "perao_uart4_bclk"), + GATE_PERAO0(CLK_PERAO_UART5_BCLK, "perao_uart5_bclk", + "ck_uart_ck", 5), + GATE_PERAO0_V(CLK_PERAO_UART5_BCLK_UART, "perao_uart5_bclk_uart", + "perao_uart5_bclk"), + GATE_PERAO0(CLK_PERAO_PWM_X16W_HCLK, "perao_pwm_x16w", + "ck_p_axi_ck", 12), + GATE_PERAO0_V(CLK_PERAO_PWM_X16W_HCLK_PWM, "perao_pwm_x16w_pwm", + "perao_pwm_x16w"), + GATE_PERAO0(CLK_PERAO_PWM_X16W_BCLK, "perao_pwm_x16w_bclk", + "ck_pwm_ck", 13), + GATE_PERAO0_V(CLK_PERAO_PWM_X16W_BCLK_PWM, "perao_pwm_x16w_bclk_pwm", + "perao_pwm_x16w_bclk"), + GATE_PERAO0(CLK_PERAO_PWM_PWM_BCLK0, "perao_pwm_pwm_bclk0", + "ck_pwm_ck", 14), + GATE_PERAO0_V(CLK_PERAO_PWM_PWM_BCLK0_PWM, "perao_pwm_pwm_bclk0_pwm", + "perao_pwm_pwm_bclk0"), + GATE_PERAO0(CLK_PERAO_PWM_PWM_BCLK1, "perao_pwm_pwm_bclk1", + "ck_pwm_ck", 15), + GATE_PERAO0_V(CLK_PERAO_PWM_PWM_BCLK1_PWM, "perao_pwm_pwm_bclk1_pwm", + "perao_pwm_pwm_bclk1"), + GATE_PERAO0(CLK_PERAO_PWM_PWM_BCLK2, "perao_pwm_pwm_bclk2", + "ck_pwm_ck", 16), + GATE_PERAO0_V(CLK_PERAO_PWM_PWM_BCLK2_PWM, "perao_pwm_pwm_bclk2_pwm", + "perao_pwm_pwm_bclk2"), + GATE_PERAO0(CLK_PERAO_PWM_PWM_BCLK3, "perao_pwm_pwm_bclk3", + "ck_pwm_ck", 17), + GATE_PERAO0_V(CLK_PERAO_PWM_PWM_BCLK3_PWM, "perao_pwm_pwm_bclk3_pwm", + "perao_pwm_pwm_bclk3"), + /* PERAO1 */ + GATE_HWV_PERAO1(CLK_PERAO_SPI0_BCLK, "perao_spi0_bclk", + "ck_spi0_b_ck", 0), + GATE_PERAO1_V(CLK_PERAO_SPI0_BCLK_SPI, "perao_spi0_bclk_spi", + "perao_spi0_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI1_BCLK, "perao_spi1_bclk", + "ck_spi1_b_ck", 2), + GATE_PERAO1_V(CLK_PERAO_SPI1_BCLK_SPI, "perao_spi1_bclk_spi", + "perao_spi1_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI2_BCLK, "perao_spi2_bclk", + "ck_spi2_b_ck", 3), + GATE_PERAO1_V(CLK_PERAO_SPI2_BCLK_SPI, "perao_spi2_bclk_spi", + "perao_spi2_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI3_BCLK, "perao_spi3_bclk", + "ck_spi3_b_ck", 4), + GATE_PERAO1_V(CLK_PERAO_SPI3_BCLK_SPI, "perao_spi3_bclk_spi", + "perao_spi3_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI4_BCLK, "perao_spi4_bclk", + "ck_spi4_b_ck", 5), + GATE_PERAO1_V(CLK_PERAO_SPI4_BCLK_SPI, "perao_spi4_bclk_spi", + "perao_spi4_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI5_BCLK, "perao_spi5_bclk", + "ck_spi5_b_ck", 6), + GATE_PERAO1_V(CLK_PERAO_SPI5_BCLK_SPI, "perao_spi5_bclk_spi", + "perao_spi5_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI6_BCLK, "perao_spi6_bclk", + "ck_spi6_b_ck", 7), + GATE_PERAO1_V(CLK_PERAO_SPI6_BCLK_SPI, "perao_spi6_bclk_spi", + "perao_spi6_bclk"), + GATE_HWV_PERAO1(CLK_PERAO_SPI7_BCLK, "perao_spi7_bclk", + "ck_spi7_b_ck", 8), + GATE_PERAO1_V(CLK_PERAO_SPI7_BCLK_SPI, "perao_spi7_bclk_spi", + "perao_spi7_bclk"), + GATE_PERAO1(CLK_PERAO_FLASHIF_FLASH, "perao_flashif_flash", + "ck_sflash_ck", 18), + GATE_PERAO1_V(CLK_PERAO_FLASHIF_FLASH_FLASHIF, "perao_flashif_flash_flashif", + "perao_flashif_flash"), + GATE_PERAO1(CLK_PERAO_FLASHIF_27M, "perao_flashif_27m", + "ck_sflash_ck", 19), + GATE_PERAO1_V(CLK_PERAO_FLASHIF_27M_FLASHIF, "perao_flashif_27m_flashif", + "perao_flashif_27m"), + GATE_PERAO1(CLK_PERAO_FLASHIF_DRAM, "perao_flashif_dram", + "ck_p_axi_ck", 20), + GATE_PERAO1_V(CLK_PERAO_FLASHIF_DRAM_FLASHIF, "perao_flashif_dram_flashif", + "perao_flashif_dram"), + GATE_PERAO1(CLK_PERAO_FLASHIF_AXI, "perao_flashif_axi", + "ck_p_axi_ck", 21), + GATE_PERAO1_V(CLK_PERAO_FLASHIF_AXI_FLASHIF, "perao_flashif_axi_flashif", + "perao_flashif_axi"), + GATE_PERAO1(CLK_PERAO_FLASHIF_BCLK, "perao_flashif_bclk", + "ck_p_axi_ck", 22), + GATE_PERAO1_V(CLK_PERAO_FLASHIF_BCLK_FLASHIF, "perao_flashif_bclk_flashif", + "perao_flashif_bclk"), + GATE_PERAO1(CLK_PERAO_AP_DMA_X32W_BCLK, "perao_ap_dma_x32w_bclk", + "ck_p_axi_ck", 26), + GATE_PERAO1_V(CLK_PERAO_AP_DMA_X32W_BCLK_UART, "perao_ap_dma_x32w_bclk_uart", + "perao_ap_dma_x32w_bclk"), + GATE_PERAO1_V(CLK_PERAO_AP_DMA_X32W_BCLK_I2C, "perao_ap_dma_x32w_bclk_i2c", + "perao_ap_dma_x32w_bclk"), + /* PERAO2 */ + GATE_PERAO2(CLK_PERAO_MSDC1_MSDC_SRC, "perao_msdc1_msdc_src", + "ck_msdc30_1_ck", 1), + GATE_PERAO2_V(CLK_PERAO_MSDC1_MSDC_SRC_MSDC1, "perao_msdc1_msdc_src_msdc1", + "perao_msdc1_msdc_src"), + GATE_PERAO2(CLK_PERAO_MSDC1_HCLK, "perao_msdc1", + "ck_msdc30_1_ck", 2), + GATE_PERAO2_V(CLK_PERAO_MSDC1_HCLK_MSDC1, "perao_msdc1_msdc1", + "perao_msdc1"), + GATE_PERAO2(CLK_PERAO_MSDC1_AXI, "perao_msdc1_axi", + "ck_p_axi_ck", 3), + GATE_PERAO2_V(CLK_PERAO_MSDC1_AXI_MSDC1, "perao_msdc1_axi_msdc1", + "perao_msdc1_axi"), + GATE_PERAO2(CLK_PERAO_MSDC1_HCLK_WRAP, "perao_msdc1_h_wrap", + "ck_p_axi_ck", 4), + GATE_PERAO2_V(CLK_PERAO_MSDC1_HCLK_WRAP_MSDC1, "perao_msdc1_h_wrap_msdc1", + "perao_msdc1_h_wrap"), + GATE_PERAO2(CLK_PERAO_MSDC2_MSDC_SRC, "perao_msdc2_msdc_src", + "ck_msdc30_2_ck", 10), + GATE_PERAO2_V(CLK_PERAO_MSDC2_MSDC_SRC_MSDC2, "perao_msdc2_msdc_src_msdc2", + "perao_msdc2_msdc_src"), + GATE_PERAO2(CLK_PERAO_MSDC2_HCLK, "perao_msdc2", + "ck_msdc30_2_ck", 11), + GATE_PERAO2_V(CLK_PERAO_MSDC2_HCLK_MSDC2, "perao_msdc2_msdc2", + "perao_msdc2"), + GATE_PERAO2(CLK_PERAO_MSDC2_AXI, "perao_msdc2_axi", + "ck_p_axi_ck", 12), + GATE_PERAO2_V(CLK_PERAO_MSDC2_AXI_MSDC2, "perao_msdc2_axi_msdc2", + "perao_msdc2_axi"), + GATE_PERAO2(CLK_PERAO_MSDC2_HCLK_WRAP, "perao_msdc2_h_wrap", + "ck_p_axi_ck", 13), + GATE_PERAO2_V(CLK_PERAO_MSDC2_HCLK_WRAP_MSDC2, "perao_msdc2_h_wrap_msdc2", + "perao_msdc2_h_wrap"), +}; + +static const struct mtk_clk_desc perao_mcd = { + .clks = perao_clks, + .num_clks = ARRAY_SIZE(perao_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_peri_ao[] = { + { .compatible = "mediatek,mt8196-pericfg_ao", .data = &perao_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_peri_ao_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-peri_ao", + .of_match_table = of_match_clk_mt8196_peri_ao, + }, +}; + +module_platform_driver(clk_mt8196_peri_ao_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-pextp.c b/drivers/clk/mediatek/clk-mt8196-pextp.c new file mode 100644 index 0000000000000..af0c533e51eaa --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-pextp.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs pext_cg_regs = { + .set_ofs = 0x18, + .clr_ofs = 0x1c, + .sta_ofs = 0x14, +}; + +#define GATE_PEXT(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &pext_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_PEXT_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate pext_clks[] = { + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_TL, "pext_pm0_tl", + "ck_tl_ck", 0), + GATE_PEXT_V(CLK_PEXT_PEXTP_MAC_P0_TL_PCIE, "pext_pm0_tl_pcie", + "pext_pm0_tl"), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_REF, "pext_pm0_ref", + "ck_f26m_ck", 1), + GATE_PEXT_V(CLK_PEXT_PEXTP_MAC_P0_REF_PCIE, "pext_pm0_ref_pcie", + "pext_pm0_ref"), + GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_MCU_BUS, "pext_pp0_mcu_bus", + "ck_f26m_ck", 6), + GATE_PEXT_V(CLK_PEXT_PEXTP_PHY_P0_MCU_BUS_PCIE, "pext_pp0_mcu_bus_pcie", + "pext_pp0_mcu_bus"), + GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF, "pext_pp0_pextp_ref", + "ck_f26m_ck", 7), + GATE_PEXT_V(CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF_PCIE, "pext_pp0_pextp_ref_pcie", + "pext_pp0_pextp_ref"), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AXI_250, "pext_pm0_axi_250", + "ck_pexpt0_mem_sub_ck", 12), + GATE_PEXT_V(CLK_PEXT_PEXTP_MAC_P0_AXI_250_PCIE, "pext_pm0_axi_250_pcie", + "pext_pm0_axi_250"), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AHB_APB, "pext_pm0_ahb_apb", + "ck_pextp0_axi_ck", 13), + GATE_PEXT_V(CLK_PEXT_PEXTP_MAC_P0_AHB_APB_PCIE, "pext_pm0_ahb_apb_pcie", + "pext_pm0_ahb_apb"), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_PL_P, "pext_pm0_pl_p", + "ck_f26m_ck", 14), + GATE_PEXT_V(CLK_PEXT_PEXTP_MAC_P0_PL_P_PCIE, "pext_pm0_pl_p_pcie", + "pext_pm0_pl_p"), + GATE_PEXT(CLK_PEXT_PEXTP_VLP_AO_P0_LP, "pext_pextp_vlp_ao_p0_lp", + "ck_f26m_ck", 19), + GATE_PEXT_V(CLK_PEXT_PEXTP_VLP_AO_P0_LP_PCIE, "pext_pextp_vlp_ao_p0_lp_pcie", + "pext_pextp_vlp_ao_p0_lp"), +}; + +static const struct mtk_clk_desc pext_mcd = { + .clks = pext_clks, + .num_clks = ARRAY_SIZE(pext_clks), +}; + +static const struct mtk_gate_regs pext1_cg_regs = { + .set_ofs = 0x18, + .clr_ofs = 0x1c, + .sta_ofs = 0x14, +}; + +#define GATE_PEXT1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &pext1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PEXT1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate pext1_clks[] = { + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P1_TL, "pext1_pm1_tl", + "ck_tl_p1_ck", 0), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P1_TL_PCIE, "pext1_pm1_tl_pcie", + "pext1_pm1_tl"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P1_REF, "pext1_pm1_ref", + "ck_f26m_ck", 1), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P1_REF_PCIE, "pext1_pm1_ref_pcie", + "pext1_pm1_ref"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P2_TL, "pext1_pm2_tl", + "ck_tl_p2_ck", 2), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P2_TL_PCIE, "pext1_pm2_tl_pcie", + "pext1_pm2_tl"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P2_REF, "pext1_pm2_ref", + "ck_f26m_ck", 3), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P2_REF_PCIE, "pext1_pm2_ref_pcie", + "pext1_pm2_ref"), + GATE_PEXT1(CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS, "pext1_pp1_mcu_bus", + "ck_f26m_ck", 8), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS_PCIE, "pext1_pp1_mcu_bus_pcie", + "pext1_pp1_mcu_bus"), + GATE_PEXT1(CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF, "pext1_pp1_pextp_ref", + "ck_f26m_ck", 9), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF_PCIE, "pext1_pp1_pextp_ref_pcie", + "pext1_pp1_pextp_ref"), + GATE_PEXT1(CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS, "pext1_pp2_mcu_bus", + "ck_f26m_ck", 10), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS_PCIE, "pext1_pp2_mcu_bus_pcie", + "pext1_pp2_mcu_bus"), + GATE_PEXT1(CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF, "pext1_pp2_pextp_ref", + "ck_f26m_ck", 11), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF_PCIE, "pext1_pp2_pextp_ref_pcie", + "pext1_pp2_pextp_ref"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P1_AXI_250, "pext1_pm1_axi_250", + "ck_pextp1_usb_axi_ck", 16), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P1_AXI_250_PCIE, "pext1_pm1_axi_250_pcie", + "pext1_pm1_axi_250"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P1_AHB_APB, "pext1_pm1_ahb_apb", + "ck_pextp1_usb_mem_sub_ck", 17), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P1_AHB_APB_PCIE, "pext1_pm1_ahb_apb_pcie", + "pext1_pm1_ahb_apb"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P1_PL_P, "pext1_pm1_pl_p", + "ck_f26m_ck", 18), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P1_PL_P_PCIE, "pext1_pm1_pl_p_pcie", + "pext1_pm1_pl_p"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P2_AXI_250, "pext1_pm2_axi_250", + "ck_pextp1_usb_axi_ck", 19), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P2_AXI_250_PCIE, "pext1_pm2_axi_250_pcie", + "pext1_pm2_axi_250"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P2_AHB_APB, "pext1_pm2_ahb_apb", + "ck_pextp1_usb_mem_sub_ck", 20), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P2_AHB_APB_PCIE, "pext1_pm2_ahb_apb_pcie", + "pext1_pm2_ahb_apb"), + GATE_PEXT1(CLK_PEXT1_PEXTP_MAC_P2_PL_P, "pext1_pm2_pl_p", + "ck_f26m_ck", 21), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_MAC_P2_PL_P_PCIE, "pext1_pm2_pl_p_pcie", + "pext1_pm2_pl_p"), + GATE_PEXT1(CLK_PEXT1_PEXTP_VLP_AO_P1_LP, "pext1_pextp_vlp_ao_p1_lp", + "ck_f26m_ck", 26), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_VLP_AO_P1_LP_PCIE, "pext1_pextp_vlp_ao_p1_lp_pcie", + "pext1_pextp_vlp_ao_p1_lp"), + GATE_PEXT1(CLK_PEXT1_PEXTP_VLP_AO_P2_LP, "pext1_pextp_vlp_ao_p2_lp", + "ck_f26m_ck", 27), + GATE_PEXT1_V(CLK_PEXT1_PEXTP_VLP_AO_P2_LP_PCIE, "pext1_pextp_vlp_ao_p2_lp_pcie", + "pext1_pextp_vlp_ao_p2_lp"), +}; + +static const struct mtk_clk_desc pext1_mcd = { + .clks = pext1_clks, + .num_clks = ARRAY_SIZE(pext1_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_pextp[] = { + { .compatible = "mediatek,mt8196-pextp0cfg_ao", .data = &pext_mcd, }, + { .compatible = "mediatek,mt8196-pextp1cfg_ao", .data = &pext1_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_pextp_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-pextp", + .of_match_table = of_match_clk_mt8196_pextp, + }, +}; + +module_platform_driver(clk_mt8196_pextp_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-topckgen.c b/drivers/clk/mediatek/clk-mt8196-topckgen.c new file mode 100644 index 0000000000000..635122271cf38 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-topckgen.c @@ -0,0 +1,1469 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-mux.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* MUX SEL REG */ +#define CLK_CFG_UPDATE 0x0004 +#define CLK_CFG_UPDATE1 0x0008 +#define CLK_CFG_UPDATE2 0x000c +#define CLK_CFG_0 0x0010 +#define CLK_CFG_0_SET 0x0014 +#define CLK_CFG_0_CLR 0x0018 +#define CLK_CFG_1 0x0020 +#define CLK_CFG_1_SET 0x0024 +#define CLK_CFG_1_CLR 0x0028 +#define CLK_CFG_2 0x0030 +#define CLK_CFG_2_SET 0x0034 +#define CLK_CFG_2_CLR 0x0038 +#define CLK_CFG_3 0x0040 +#define CLK_CFG_3_SET 0x0044 +#define CLK_CFG_3_CLR 0x0048 +#define CLK_CFG_4 0x0050 +#define CLK_CFG_4_SET 0x0054 +#define CLK_CFG_4_CLR 0x0058 +#define CLK_CFG_5 0x0060 +#define CLK_CFG_5_SET 0x0064 +#define CLK_CFG_5_CLR 0x0068 +#define CLK_CFG_6 0x0070 +#define CLK_CFG_6_SET 0x0074 +#define CLK_CFG_6_CLR 0x0078 +#define CLK_CFG_7 0x0080 +#define CLK_CFG_7_SET 0x0084 +#define CLK_CFG_7_CLR 0x0088 +#define CLK_CFG_8 0x0090 +#define CLK_CFG_8_SET 0x0094 +#define CLK_CFG_8_CLR 0x0098 +#define CLK_CFG_9 0x00a0 +#define CLK_CFG_9_SET 0x00a4 +#define CLK_CFG_9_CLR 0x00a8 +#define CLK_CFG_10 0x00b0 +#define CLK_CFG_10_SET 0x00b4 +#define CLK_CFG_10_CLR 0x00b8 +#define CLK_CFG_11 0x00c0 +#define CLK_CFG_11_SET 0x00c4 +#define CLK_CFG_11_CLR 0x00c8 +#define CLK_CFG_12 0x00d0 +#define CLK_CFG_12_SET 0x00d4 +#define CLK_CFG_12_CLR 0x00d8 +#define CLK_CFG_13 0x00e0 +#define CLK_CFG_13_SET 0x00e4 +#define CLK_CFG_13_CLR 0x00e8 +#define CLK_CFG_14 0x00f0 +#define CLK_CFG_14_SET 0x00f4 +#define CLK_CFG_14_CLR 0x00f8 +#define CLK_CFG_15 0x0100 +#define CLK_CFG_15_SET 0x0104 +#define CLK_CFG_15_CLR 0x0108 +#define CLK_CFG_16 0x0110 +#define CLK_CFG_16_SET 0x0114 +#define CLK_CFG_16_CLR 0x0118 +#define CLK_CFG_17 0x0120 +#define CLK_CFG_17_SET 0x0124 +#define CLK_CFG_17_CLR 0x0128 +#define CLK_CFG_18 0x0130 +#define CLK_CFG_18_SET 0x0134 +#define CLK_CFG_18_CLR 0x0138 +#define CLK_CFG_19 0x0140 +#define CLK_CFG_19_SET 0x0144 +#define CLK_CFG_19_CLR 0x0148 +#define CLK_AUDDIV_0 0x020c +#define CLK_FENC_STATUS_MON_0 0x0270 +#define CLK_FENC_STATUS_MON_1 0x0274 +#define CLK_FENC_STATUS_MON_2 0x0278 + +/* MUX SHIFT */ +#define TOP_MUX_AXI_SHIFT 0 +#define TOP_MUX_MEM_SUB_SHIFT 1 +#define TOP_MUX_IO_NOC_SHIFT 2 +#define TOP_MUX_PERI_AXI_SHIFT 3 +#define TOP_MUX_UFS_PEXTP0_AXI_SHIFT 4 +#define TOP_MUX_PEXTP1_USB_AXI_SHIFT 5 +#define TOP_MUX_PERI_FMEM_SUB_SHIFT 6 +#define TOP_MUX_UFS_PEXPT0_MEM_SUB_SHIFT 7 +#define TOP_MUX_PEXTP1_USB_MEM_SUB_SHIFT 8 +#define TOP_MUX_PERI_NOC_SHIFT 9 +#define TOP_MUX_EMI_N_SHIFT 10 +#define TOP_MUX_EMI_S_SHIFT 11 +#define TOP_MUX_AP2CONN_HOST_SHIFT 14 +#define TOP_MUX_ATB_SHIFT 15 +#define TOP_MUX_CIRQ_SHIFT 16 +#define TOP_MUX_PBUS_156M_SHIFT 17 +#define TOP_MUX_EFUSE_SHIFT 20 +#define TOP_MUX_MCU_L3GIC_SHIFT 21 +#define TOP_MUX_MCU_INFRA_SHIFT 22 +#define TOP_MUX_DSP_SHIFT 23 +#define TOP_MUX_MFG_REF_SHIFT 24 +#define TOP_MUX_MFG_EB_SHIFT 26 +#define TOP_MUX_UART_SHIFT 27 +#define TOP_MUX_SPI0_BCLK_SHIFT 28 +#define TOP_MUX_SPI1_BCLK_SHIFT 29 +#define TOP_MUX_SPI2_BCLK_SHIFT 30 +#define TOP_MUX_SPI3_BCLK_SHIFT 0 +#define TOP_MUX_SPI4_BCLK_SHIFT 1 +#define TOP_MUX_SPI5_BCLK_SHIFT 2 +#define TOP_MUX_SPI6_BCLK_SHIFT 3 +#define TOP_MUX_SPI7_BCLK_SHIFT 4 +#define TOP_MUX_MSDC30_1_SHIFT 7 +#define TOP_MUX_MSDC30_2_SHIFT 8 +#define TOP_MUX_DISP_PWM_SHIFT 9 +#define TOP_MUX_USB_TOP_1P_SHIFT 10 +#define TOP_MUX_SSUSB_XHCI_1P_SHIFT 11 +#define TOP_MUX_SSUSB_FMCNT_P1_SHIFT 12 +#define TOP_MUX_I2C_PERI_SHIFT 13 +#define TOP_MUX_I2C_EAST_SHIFT 14 +#define TOP_MUX_I2C_WEST_SHIFT 15 +#define TOP_MUX_I2C_NORTH_SHIFT 16 +#define TOP_MUX_AES_UFSFDE_SHIFT 17 +#define TOP_MUX_UFS_SHIFT 18 +#define TOP_MUX_AUD_1_SHIFT 21 +#define TOP_MUX_AUD_2_SHIFT 22 +#define TOP_MUX_ADSP_SHIFT 23 +#define TOP_MUX_ADSP_UARTHUB_BCLK_SHIFT 24 +#define TOP_MUX_DPMAIF_MAIN_SHIFT 25 +#define TOP_MUX_PWM_SHIFT 26 +#define TOP_MUX_MCUPM_SHIFT 27 +#define TOP_MUX_SFLASH_SHIFT 28 +#define TOP_MUX_IPSEAST_SHIFT 29 +#define TOP_MUX_TL_SHIFT 0 +#define TOP_MUX_TL_P1_SHIFT 1 +#define TOP_MUX_TL_P2_SHIFT 2 +#define TOP_MUX_EMI_INTERFACE_546_SHIFT 3 +#define TOP_MUX_SDF_SHIFT 4 +#define TOP_MUX_UARTHUB_BCLK_SHIFT 5 +#define TOP_MUX_DPSW_CMP_26M_SHIFT 6 +#define TOP_MUX_SMAPCK_SHIFT 7 +#define TOP_MUX_SSR_PKA_SHIFT 8 +#define TOP_MUX_SSR_DMA_SHIFT 9 +#define TOP_MUX_SSR_KDF_SHIFT 10 +#define TOP_MUX_SSR_RNG_SHIFT 11 +#define TOP_MUX_SPU0_SHIFT 12 +#define TOP_MUX_SPU1_SHIFT 13 +#define TOP_MUX_DXCC_SHIFT 14 + +/* CKSTA REG */ +#define CKSTA_REG 0x01c8 +#define CKSTA_REG1 0x01cc +#define CKSTA_REG2 0x01d0 + +/* DIVIDER REG */ +#define CLK_AUDDIV_2 0x0214 +#define CLK_AUDDIV_3 0x0220 +#define CLK_AUDDIV_4 0x0224 +#define CLK_AUDDIV_5 0x0228 + +/* HW Voter REG */ +#define HWV_CG_0_SET 0x0000 +#define HWV_CG_0_CLR 0x0004 +#define HWV_CG_0_DONE 0x2c00 +#define HWV_CG_1_SET 0x0008 +#define HWV_CG_1_CLR 0x000c +#define HWV_CG_1_DONE 0x2c04 +#define HWV_CG_2_SET 0x0010 +#define HWV_CG_2_CLR 0x0014 +#define HWV_CG_2_DONE 0x2c08 +#define HWV_CG_3_SET 0x0018 +#define HWV_CG_3_CLR 0x001c +#define HWV_CG_3_DONE 0x2c0c +#define HWV_CG_4_SET 0x0020 +#define HWV_CG_4_CLR 0x0024 +#define HWV_CG_4_DONE 0x2c10 +#define HWV_CG_5_SET 0x0028 +#define HWV_CG_5_CLR 0x002c +#define HWV_CG_5_DONE 0x2c14 +#define HWV_CG_6_SET 0x0030 +#define HWV_CG_6_CLR 0x0034 +#define HWV_CG_6_DONE 0x2c18 +#define HWV_CG_7_SET 0x0038 +#define HWV_CG_7_CLR 0x003c +#define HWV_CG_7_DONE 0x2c1c +#define HWV_CG_8_SET 0x0040 +#define HWV_CG_8_CLR 0x0044 +#define HWV_CG_8_DONE 0x2c20 + +static DEFINE_SPINLOCK(mt8196_clk_ck_lock); + +static const struct mtk_fixed_factor ck_divs[] = { + FACTOR(CLK_CK_MAINPLL_D3, "ck_mainpll_d3", + "mainpll", 1, 3), + FACTOR(CLK_CK_MAINPLL_D4, "ck_mainpll_d4", + "mainpll", 1, 4), + FACTOR(CLK_CK_MAINPLL_D4_D2, "ck_mainpll_d4_d2", + "mainpll", 1, 8), + FACTOR(CLK_CK_MAINPLL_D4_D4, "ck_mainpll_d4_d4", + "mainpll", 1, 16), + FACTOR(CLK_CK_MAINPLL_D4_D8, "ck_mainpll_d4_d8", + "mainpll", 1, 32), + FACTOR(CLK_CK_MAINPLL_D5, "ck_mainpll_d5", + "mainpll", 1, 5), + FACTOR(CLK_CK_MAINPLL_D5_D2, "ck_mainpll_d5_d2", + "mainpll", 1, 10), + FACTOR(CLK_CK_MAINPLL_D5_D4, "ck_mainpll_d5_d4", + "mainpll", 1, 20), + FACTOR(CLK_CK_MAINPLL_D5_D8, "ck_mainpll_d5_d8", + "mainpll", 1, 40), + FACTOR(CLK_CK_MAINPLL_D6, "ck_mainpll_d6", + "mainpll", 1, 6), + FACTOR(CLK_CK_MAINPLL_D6_D2, "ck_mainpll_d6_d2", + "mainpll", 1, 12), + FACTOR(CLK_CK_MAINPLL_D7, "ck_mainpll_d7", + "mainpll", 1, 7), + FACTOR(CLK_CK_MAINPLL_D7_D2, "ck_mainpll_d7_d2", + "mainpll", 1, 14), + FACTOR(CLK_CK_MAINPLL_D7_D4, "ck_mainpll_d7_d4", + "mainpll", 1, 28), + FACTOR(CLK_CK_MAINPLL_D7_D8, "ck_mainpll_d7_d8", + "mainpll", 1, 56), + FACTOR(CLK_CK_MAINPLL_D9, "ck_mainpll_d9", + "mainpll", 1, 9), + FACTOR(CLK_CK_UNIVPLL_D4, "ck_univpll_d4", + "univpll", 1, 4), + FACTOR(CLK_CK_UNIVPLL_D4_D2, "ck_univpll_d4_d2", + "univpll", 1, 8), + FACTOR(CLK_CK_UNIVPLL_D4_D4, "ck_univpll_d4_d4", + "univpll", 1, 16), + FACTOR(CLK_CK_UNIVPLL_D4_D8, "ck_univpll_d4_d8", + "univpll", 1, 32), + FACTOR(CLK_CK_UNIVPLL_D5, "ck_univpll_d5", + "univpll", 1, 5), + FACTOR(CLK_CK_UNIVPLL_D5_D2, "ck_univpll_d5_d2", + "univpll", 1, 10), + FACTOR(CLK_CK_UNIVPLL_D5_D4, "ck_univpll_d5_d4", + "univpll", 1, 20), + FACTOR(CLK_CK_UNIVPLL_D6, "ck_univpll_d6", + "univpll", 1, 6), + FACTOR(CLK_CK_UNIVPLL_D6_D2, "ck_univpll_d6_d2", + "univpll", 1, 12), + FACTOR(CLK_CK_UNIVPLL_D6_D4, "ck_univpll_d6_d4", + "univpll", 1, 24), + FACTOR(CLK_CK_UNIVPLL_D6_D8, "ck_univpll_d6_d8", + "univpll", 1, 48), + FACTOR(CLK_CK_UNIVPLL_D6_D16, "ck_univpll_d6_d16", + "univpll", 1, 96), + FACTOR(CLK_CK_UNIVPLL_192M, "ck_univpll_192m", + "univpll", 1, 13), + FACTOR(CLK_CK_UNIVPLL_192M_D4, "ck_univpll_192m_d4", + "univpll", 1, 52), + FACTOR(CLK_CK_UNIVPLL_192M_D8, "ck_univpll_192m_d8", + "univpll", 1, 104), + FACTOR(CLK_CK_UNIVPLL_192M_D16, "ck_univpll_192m_d16", + "univpll", 1, 208), + FACTOR(CLK_CK_UNIVPLL_192M_D32, "ck_univpll_192m_d32", + "univpll", 1, 416), + FACTOR(CLK_CK_UNIVPLL_192M_D10, "ck_univpll_192m_d10", + "univpll", 1, 130), + FACTOR(CLK_CK_APLL1, "ck_apll1_ck", + "vlp_apll1", 1, 1), + FACTOR(CLK_CK_APLL1_D4, "ck_apll1_d4", + "vlp_apll1", 1, 4), + FACTOR(CLK_CK_APLL1_D8, "ck_apll1_d8", + "vlp_apll1", 1, 8), + FACTOR(CLK_CK_APLL2, "ck_apll2_ck", + "vlp_apll2", 1, 1), + FACTOR(CLK_CK_APLL2_D4, "ck_apll2_d4", + "vlp_apll2", 1, 4), + FACTOR(CLK_CK_APLL2_D8, "ck_apll2_d8", + "vlp_apll2", 1, 8), + FACTOR(CLK_CK_ADSPPLL, "ck_adsppll_ck", + "adsppll", 1, 1), + FACTOR(CLK_CK_EMIPLL1, "ck_emipll1_ck", + "emipll", 1, 1), + FACTOR(CLK_CK_TVDPLL1_D2, "ck_tvdpll1_d2", + "tvdpll1", 1, 2), + FACTOR(CLK_CK_MSDCPLL_D2, "ck_msdcpll_d2", + "msdcpll", 1, 2), + FACTOR(CLK_CK_CLKRTC, "ck_clkrtc", + "clk32k", 1, 1), + FACTOR(CLK_CK_TCK_26M_MX9, "ck_tck_26m_mx9_ck", + "clk26m", 1, 1), + FACTOR(CLK_CK_F26M, "ck_f26m_ck", + "clk26m", 1, 1), + FACTOR(CLK_CK_F26M_CK_D2, "ck_f26m_d2", + "clk13m", 1, 1), + FACTOR(CLK_CK_OSC, "ck_osc", + "ulposc", 1, 1), + FACTOR(CLK_CK_OSC_D2, "ck_osc_d2", + "ulposc", 1, 2), + FACTOR(CLK_CK_OSC_D3, "ck_osc_d3", + "ulposc", 1, 3), + FACTOR(CLK_CK_OSC_D4, "ck_osc_d4", + "ulposc", 1, 4), + FACTOR(CLK_CK_OSC_D5, "ck_osc_d5", + "ulposc", 1, 5), + FACTOR(CLK_CK_OSC_D7, "ck_osc_d7", + "ulposc", 1, 7), + FACTOR(CLK_CK_OSC_D8, "ck_osc_d8", + "ulposc", 1, 8), + FACTOR(CLK_CK_OSC_D10, "ck_osc_d10", + "ulposc", 1, 10), + FACTOR(CLK_CK_OSC_D14, "ck_osc_d14", + "ulposc", 1, 14), + FACTOR(CLK_CK_OSC_D20, "ck_osc_d20", + "ulposc", 1, 20), + FACTOR(CLK_CK_OSC_D32, "ck_osc_d32", + "ulposc", 1, 32), + FACTOR(CLK_CK_OSC_D40, "ck_osc_d40", + "ulposc", 1, 40), + FACTOR(CLK_CK_OSC3, "ck_osc3", + "ulposc3", 1, 1), + FACTOR(CLK_CK_P_AXI, "ck_p_axi_ck", + "ck_p_axi_sel", 1, 1), + FACTOR(CLK_CK_PEXTP0_AXI, "ck_pextp0_axi_ck", + "ck_pextp0_axi_sel", 1, 1), + FACTOR(CLK_CK_PEXTP1_USB_AXI, "ck_pextp1_usb_axi_ck", + "ck_pextp1_usb_axi_sel", 1, 1), + FACTOR(CLK_CK_PEXPT0_MEM_SUB, "ck_pexpt0_mem_sub_ck", + "ck_pexpt0_mem_sub_sel", 1, 1), + FACTOR(CLK_CK_PEXTP1_USB_MEM_SUB, "ck_pextp1_usb_mem_sub_ck", + "ck_pextp1_usb_mem_sub_sel", 1, 1), + FACTOR(CLK_CK_UART, "ck_uart_ck", + "ck_uart_sel", 1, 1), + FACTOR(CLK_CK_SPI0_BCLK, "ck_spi0_b_ck", + "ck_spi0_b_sel", 1, 1), + FACTOR(CLK_CK_SPI1_BCLK, "ck_spi1_b_ck", + "ck_spi1_b_sel", 1, 1), + FACTOR(CLK_CK_SPI2_BCLK, "ck_spi2_b_ck", + "ck_spi2_b_sel", 1, 1), + FACTOR(CLK_CK_SPI3_BCLK, "ck_spi3_b_ck", + "ck_spi3_b_sel", 1, 1), + FACTOR(CLK_CK_SPI4_BCLK, "ck_spi4_b_ck", + "ck_spi4_b_sel", 1, 1), + FACTOR(CLK_CK_SPI5_BCLK, "ck_spi5_b_ck", + "ck_spi5_b_sel", 1, 1), + FACTOR(CLK_CK_SPI6_BCLK, "ck_spi6_b_ck", + "ck_spi6_b_sel", 1, 1), + FACTOR(CLK_CK_SPI7_BCLK, "ck_spi7_b_ck", + "ck_spi7_b_sel", 1, 1), + FACTOR(CLK_CK_MSDC30_1, "ck_msdc30_1_ck", + "ck_msdc30_1_sel", 1, 1), + FACTOR(CLK_CK_MSDC30_2, "ck_msdc30_2_ck", + "ck_msdc30_2_sel", 1, 1), + FACTOR(CLK_CK_I2C_PERI, "ck_i2c_p_ck", + "ck_i2c_p_sel", 1, 1), + FACTOR(CLK_CK_I2C_EAST, "ck_i2c_east_ck", + "ck_i2c_east_sel", 1, 1), + FACTOR(CLK_CK_I2C_WEST, "ck_i2c_west_ck", + "ck_i2c_west_sel", 1, 1), + FACTOR(CLK_CK_I2C_NORTH, "ck_i2c_north_ck", + "ck_i2c_north_sel", 1, 1), + FACTOR(CLK_CK_AES_UFSFDE, "ck_aes_ufsfde_ck", + "ck_aes_ufsfde_sel", 1, 1), + FACTOR(CLK_CK_UFS, "ck_ck", + "ck_sel", 1, 1), + FACTOR(CLK_CK_AUD_1, "ck_aud_1_ck", + "ck_aud_1_sel", 1, 1), + FACTOR(CLK_CK_AUD_2, "ck_aud_2_ck", + "ck_aud_2_sel", 1, 1), + FACTOR(CLK_CK_DPMAIF_MAIN, "ck_dpmaif_main_ck", + "ck_dpmaif_main_sel", 1, 1), + FACTOR(CLK_CK_PWM, "ck_pwm_ck", + "ck_pwm_sel", 1, 1), + FACTOR(CLK_CK_TL, "ck_tl_ck", + "ck_tl_sel", 1, 1), + FACTOR(CLK_CK_TL_P1, "ck_tl_p1_ck", + "ck_tl_p1_sel", 1, 1), + FACTOR(CLK_CK_TL_P2, "ck_tl_p2_ck", + "ck_tl_p2_sel", 1, 1), + FACTOR(CLK_CK_SSR_RNG, "ck_ssr_rng_ck", + "ck_ssr_rng_sel", 1, 1), + FACTOR(CLK_CK_SFLASH, "ck_sflash_ck", + "ck_sflash_sel", 1, 1), +}; + +static const char * const ck_axi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_osc_d8", + "ck_osc_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_mem_sub_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_osc_d4", + "ck_univpll_d4_d4", + "ck_osc_d3", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5", + "ck_mainpll_d4", + "ck_mainpll_d3" +}; + +static const char * const ck_io_noc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_osc_d8", + "ck_osc_d4", + "ck_mainpll_d6_d2", + "ck_mainpll_d9" +}; + +static const char * const ck_p_axi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d8", + "ck_mainpll_d5_d8", + "ck_osc_d8", + "ck_mainpll_d7_d4", + "ck_mainpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_pextp0_axi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d8", + "ck_mainpll_d5_d8", + "ck_osc_d8", + "ck_mainpll_d7_d4", + "ck_mainpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_pextp1_usb_axi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d8", + "ck_mainpll_d5_d8", + "ck_osc_d8", + "ck_mainpll_d7_d4", + "ck_mainpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_p_fmem_sub_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_osc_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5", + "ck_mainpll_d4" +}; + +static const char * const ck_pexpt0_mem_sub_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_osc_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5", + "ck_mainpll_d4" +}; + +static const char * const ck_pextp1_usb_mem_sub_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_osc_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5", + "ck_mainpll_d4" +}; + +static const char * const ck_p_noc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_osc_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5", + "ck_mainpll_d4", + "ck_mainpll_d3" +}; + +static const char * const ck_emi_n_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_emipll1_ck" +}; + +static const char * const ck_emi_s_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d5_d8", + "ck_mainpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_emipll1_ck" +}; + +static const char * const ck_ap2conn_host_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4" +}; + +static const char * const ck_atb_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6" +}; + +static const char * const ck_cirq_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d7_d4" +}; + +static const char * const ck_pbus_156m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d2", + "ck_osc_d2", + "ck_mainpll_d7" +}; + +static const char * const ck_efuse_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const ck_mcl3gic_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d8", + "ck_mainpll_d4_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_mcinfra_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d7_d2", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d9", + "ck_mainpll_d6" +}; + +static const char * const ck_dsp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d5", + "ck_osc_d4", + "ck_osc_d3", + "ck_univpll_d6_d2", + "ck_osc_d2", + "ck_univpll_d5", + "ck_osc" +}; + +static const char * const ck_mfg_ref_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d2" +}; + +static const char * const ck_mfg_eb_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d2", + "ck_mainpll_d6_d2", + "ck_mainpll_d5_d2" +}; + +static const char * const ck_uart_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d8", + "ck_univpll_d6_d4", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi0_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi1_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi2_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi3_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi4_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi5_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi6_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_spi7_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d4_d4", + "ck_mainpll_d6_d2", + "ck_univpll_192m", + "ck_univpll_d6_d2" +}; + +static const char * const ck_msdc30_1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_mainpll_d6_d2", + "ck_univpll_d6_d2", + "ck_msdcpll_d2" +}; + +static const char * const ck_msdc30_2_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_mainpll_d6_d2", + "ck_univpll_d6_d2", + "ck_msdcpll_d2" +}; + +static const char * const ck_disp_pwm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d32", + "ck_osc_d8", + "ck_univpll_d6_d4", + "ck_univpll_d5_d4", + "ck_osc_d4", + "ck_mainpll_d4_d4" +}; + +static const char * const ck_usb_1p_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d5_d4" +}; + +static const char * const ck_usb_xhci_1p_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d5_d4" +}; + +static const char * const ck_usb_fmcnt_p1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d4" +}; + +static const char * const ck_i2c_p_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d5_d2" +}; + +static const char * const ck_i2c_east_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d5_d2" +}; + +static const char * const ck_i2c_west_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d5_d2" +}; + +static const char * const ck_i2c_north_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8", + "ck_univpll_d5_d4", + "ck_mainpll_d4_d4", + "ck_univpll_d5_d2" +}; + +static const char * const ck_aes_ufsfde_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_univpll_d6_d2", + "ck_mainpll_d4_d2", + "ck_univpll_d6", + "ck_mainpll_d4" +}; + +static const char * const ck_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_univpll_d6_d2", + "ck_mainpll_d4_d2", + "ck_univpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5" +}; + +static const char * const ck_aud_1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_apll1_ck" +}; + +static const char * const ck_aud_2_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_apll2_ck" +}; + +static const char * const ck_adsp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_adsppll_ck" +}; + +static const char * const ck_adsp_uarthub_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d6_d2" +}; + +static const char * const ck_dpmaif_main_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d4_d4", + "ck_univpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_univpll_d4_d2", + "ck_mainpll_d6", + "ck_univpll_d6", + "ck_mainpll_d5", + "ck_univpll_d5" +}; + +static const char * const ck_pwm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4", + "ck_univpll_d4_d8" +}; + +static const char * const ck_mcupm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d2", + "ck_mainpll_d6_d2", + "ck_univpll_d6_d2", + "ck_mainpll_d5_d2" +}; + +static const char * const ck_ipseast_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d6", + "ck_mainpll_d5", + "ck_mainpll_d4", + "ck_mainpll_d3" +}; + +static const char * const ck_tl_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d5_d2" +}; + +static const char * const ck_tl_p1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d5_d2" +}; + +static const char * const ck_tl_p2_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4", + "ck_mainpll_d4_d4", + "ck_mainpll_d5_d2" +}; + +static const char * const ck_md_emi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4" +}; + +static const char * const ck_sdf_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck_mainpll_d4", + "ck_univpll_d4" +}; + +static const char * const ck_uarthub_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_d6_d4", + "ck_univpll_d6_d2" +}; + +static const char * const ck_dpsw_cmp_26m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const ck_smapck_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8" +}; + +static const char * const ck_ssr_pka_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const char * const ck_ssr_dma_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const char * const ck_ssr_kdf_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7" +}; + +static const char * const ck_ssr_rng_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2" +}; + +static const char * const ck_spu0_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const char * const ck_spu1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const char * const ck_dxcc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d4_d8", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2" +}; + +static const char * const ck_apll_i2sin0_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sin1_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sin2_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sin3_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sin4_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sin6_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout0_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout1_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout2_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout3_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout4_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_i2sout6_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_fmi2s_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_apll_tdmout_m_parents[] = { + "ck_aud_1_sel", + "ck_aud_2_sel" +}; + +static const char * const ck_sflash_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d8", + "ck_univpll_d6_d8" +}; + +static const struct mtk_mux ck_muxes[] = { + /* CLK_CFG_0 */ + MUX_CLR_SET_UPD(CLK_CK_AXI_SEL, "ck_axi_sel", + ck_axi_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 0, 3, + CLK_CFG_UPDATE, TOP_MUX_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_MEM_SUB_SEL, "ck_mem_sub_sel", + ck_mem_sub_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 8, 4, + CLK_CFG_UPDATE, TOP_MUX_MEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_IO_NOC_SEL, "ck_io_noc_sel", + ck_io_noc_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_IO_NOC_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_P_AXI_SEL, "ck_p_axi_sel", + ck_p_axi_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_PERI_AXI_SHIFT), + /* CLK_CFG_1 */ + MUX_CLR_SET_UPD(CLK_CK_PEXTP0_AXI_SEL, "ck_pextp0_axi_sel", + ck_pextp0_axi_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 0, 3, + CLK_CFG_UPDATE, TOP_MUX_UFS_PEXTP0_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_PEXTP1_USB_AXI_SEL, "ck_pextp1_usb_axi_sel", + ck_pextp1_usb_axi_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 8, 3, + CLK_CFG_UPDATE, TOP_MUX_PEXTP1_USB_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_P_FMEM_SUB_SEL, "ck_p_fmem_sub_sel", + ck_p_fmem_sub_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 16, 4, + CLK_CFG_UPDATE, TOP_MUX_PERI_FMEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_PEXPT0_MEM_SUB_SEL, "ck_pexpt0_mem_sub_sel", + ck_pexpt0_mem_sub_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 24, 4, + CLK_CFG_UPDATE, TOP_MUX_UFS_PEXPT0_MEM_SUB_SHIFT), + /* CLK_CFG_2 */ + MUX_CLR_SET_UPD(CLK_CK_PEXTP1_USB_MEM_SUB_SEL, "ck_pextp1_usb_mem_sub_sel", + ck_pextp1_usb_mem_sub_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 0, 4, + CLK_CFG_UPDATE, TOP_MUX_PEXTP1_USB_MEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_P_NOC_SEL, "ck_p_noc_sel", + ck_p_noc_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 8, 4, + CLK_CFG_UPDATE, TOP_MUX_PERI_NOC_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_EMI_N_SEL, "ck_emi_n_sel", + ck_emi_n_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_EMI_N_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_EMI_S_SEL, "ck_emi_s_sel", + ck_emi_s_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_EMI_S_SHIFT), + /* CLK_CFG_3 */ + MUX_CLR_SET_UPD(CLK_CK_AP2CONN_HOST_SEL, "ck_ap2conn_host_sel", + ck_ap2conn_host_parents, CLK_CFG_3, CLK_CFG_3_SET, + CLK_CFG_3_CLR, 16, 1, + CLK_CFG_UPDATE, TOP_MUX_AP2CONN_HOST_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_ATB_SEL, "ck_atb_sel", + ck_atb_parents, CLK_CFG_3, CLK_CFG_3_SET, + CLK_CFG_3_CLR, 24, 2, + CLK_CFG_UPDATE, TOP_MUX_ATB_SHIFT), + /* CLK_CFG_4 */ + MUX_CLR_SET_UPD(CLK_CK_CIRQ_SEL, "ck_cirq_sel", + ck_cirq_parents, CLK_CFG_4, CLK_CFG_4_SET, + CLK_CFG_4_CLR, 0, 2, + CLK_CFG_UPDATE, TOP_MUX_CIRQ_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_PBUS_156M_SEL, "ck_pbus_156m_sel", + ck_pbus_156m_parents, CLK_CFG_4, CLK_CFG_4_SET, + CLK_CFG_4_CLR, 8, 2, + CLK_CFG_UPDATE, TOP_MUX_PBUS_156M_SHIFT), + /* CLK_CFG_5 */ + MUX_CLR_SET_UPD(CLK_CK_EFUSE_SEL, "ck_efuse_sel", + ck_efuse_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 0, 1, + CLK_CFG_UPDATE, TOP_MUX_EFUSE_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_MCL3GIC_SEL, "ck_mcl3gic_sel", + ck_mcl3gic_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 8, 2, + CLK_CFG_UPDATE, TOP_MUX_MCU_L3GIC_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_MCINFRA_SEL, "ck_mcinfra_sel", + ck_mcinfra_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_MCU_INFRA_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_DSP_SEL, "ck_dsp_sel", + ck_dsp_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_DSP_SHIFT), + /* CLK_CFG_6 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_MFG_REF_SEL, "ck_mfg_ref_sel", ck_mfg_ref_parents, + CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, + 0, 1, 7, CLK_CFG_UPDATE, TOP_MUX_MFG_REF_SHIFT, + CLK_FENC_STATUS_MON_0, 7), + MUX_CLR_SET_UPD(CLK_CK_MFG_EB_SEL, "ck_mfg_eb_sel", + ck_mfg_eb_parents, CLK_CFG_6, CLK_CFG_6_SET, + CLK_CFG_6_CLR, 16, 2, + CLK_CFG_UPDATE, TOP_MUX_MFG_EB_SHIFT), + MUX_MULT_HWV_FENC(CLK_CK_UART_SEL, "ck_uart_sel", ck_uart_parents, + CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, "hw-voter-regmap", + HWV_CG_3_DONE, HWV_CG_3_SET, HWV_CG_3_CLR, + 24, 2, 31, CLK_CFG_UPDATE, TOP_MUX_UART_SHIFT, + CLK_FENC_STATUS_MON_0, 4), + /* CLK_CFG_7 */ + MUX_MULT_HWV_FENC(CLK_CK_SPI0_BCLK_SEL, "ck_spi0_b_sel", ck_spi0_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, "hw-voter-regmap", + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 0, 3, 7, CLK_CFG_UPDATE, TOP_MUX_SPI0_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 3), + MUX_MULT_HWV_FENC(CLK_CK_SPI1_BCLK_SEL, "ck_spi1_b_sel", ck_spi1_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, "hw-voter-regmap", + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 8, 3, 15, CLK_CFG_UPDATE, TOP_MUX_SPI1_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 2), + MUX_MULT_HWV_FENC(CLK_CK_SPI2_BCLK_SEL, "ck_spi2_b_sel", ck_spi2_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, "hw-voter-regmap", + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 16, 3, 23, CLK_CFG_UPDATE, TOP_MUX_SPI2_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 1), + MUX_MULT_HWV_FENC(CLK_CK_SPI3_BCLK_SEL, "ck_spi3_b_sel", ck_spi3_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, "hw-voter-regmap", + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_SPI3_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 0), + /* CLK_CFG_8 */ + MUX_MULT_HWV_FENC(CLK_CK_SPI4_BCLK_SEL, "ck_spi4_b_sel", ck_spi4_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, "hw-voter-regmap", + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_SPI4_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 31), + MUX_MULT_HWV_FENC(CLK_CK_SPI5_BCLK_SEL, "ck_spi5_b_sel", ck_spi5_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, "hw-voter-regmap", + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_SPI5_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 30), + MUX_MULT_HWV_FENC(CLK_CK_SPI6_BCLK_SEL, "ck_spi6_b_sel", ck_spi6_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, "hw-voter-regmap", + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_SPI6_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 29), + MUX_MULT_HWV_FENC(CLK_CK_SPI7_BCLK_SEL, "ck_spi7_b_sel", ck_spi7_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, "hw-voter-regmap", + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_SPI7_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 28), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_MSDC30_1_SEL, "ck_msdc30_1_sel", ck_msdc30_1_parents, + CLK_CFG_9, CLK_CFG_9_SET, CLK_CFG_9_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_MSDC30_1_SHIFT, + CLK_FENC_STATUS_MON_1, 25), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_MSDC30_2_SEL, "ck_msdc30_2_sel", ck_msdc30_2_parents, + CLK_CFG_9, CLK_CFG_9_SET, CLK_CFG_9_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_MSDC30_2_SHIFT, + CLK_FENC_STATUS_MON_1, 24), + /* CLK_CFG_10 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_DISP_PWM_SEL, "ck_disp_pwm_sel", ck_disp_pwm_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_DISP_PWM_SHIFT, + CLK_FENC_STATUS_MON_1, 23), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_USB_TOP_1P_SEL, "ck_usb_1p_sel", ck_usb_1p_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 8, 1, 15, CLK_CFG_UPDATE1, TOP_MUX_USB_TOP_1P_SHIFT, + CLK_FENC_STATUS_MON_1, 22), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_USB_XHCI_1P_SEL, "ck_usb_xhci_1p_sel", ck_usb_xhci_1p_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 16, 1, 23, CLK_CFG_UPDATE1, TOP_MUX_SSUSB_XHCI_1P_SHIFT, + CLK_FENC_STATUS_MON_1, 21), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_USB_FMCNT_P1_SEL, "ck_usb_fmcnt_p1_sel", ck_usb_fmcnt_p1_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 24, 1, 31, CLK_CFG_UPDATE1, TOP_MUX_SSUSB_FMCNT_P1_SHIFT, + CLK_FENC_STATUS_MON_1, 20), + /* CLK_CFG_11 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_I2C_P_SEL, "ck_i2c_p_sel", ck_i2c_p_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_I2C_PERI_SHIFT, + CLK_FENC_STATUS_MON_1, 19), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_I2C_EAST_SEL, "ck_i2c_east_sel", ck_i2c_east_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_I2C_EAST_SHIFT, + CLK_FENC_STATUS_MON_1, 18), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_I2C_WEST_SEL, "ck_i2c_west_sel", ck_i2c_west_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_I2C_WEST_SHIFT, + CLK_FENC_STATUS_MON_1, 17), + MUX_MULT_HWV_FENC(CLK_CK_I2C_NORTH_SEL, "ck_i2c_north_sel", ck_i2c_north_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, "hw-voter-regmap", + HWV_CG_6_DONE, HWV_CG_6_SET, HWV_CG_6_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_I2C_NORTH_SHIFT, + CLK_FENC_STATUS_MON_1, 16), + /* CLK_CFG_12 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_AES_UFSFDE_SEL, "ck_aes_ufsfde_sel", ck_aes_ufsfde_parents, + CLK_CFG_12, CLK_CFG_12_SET, CLK_CFG_12_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_AES_UFSFDE_SHIFT, + CLK_FENC_STATUS_MON_1, 15), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_SEL, "ck_sel", ck_parents, + CLK_CFG_12, CLK_CFG_12_SET, CLK_CFG_12_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_UFS_SHIFT, + CLK_FENC_STATUS_MON_1, 14), + /* CLK_CFG_13 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_AUD_1_SEL, "ck_aud_1_sel", ck_aud_1_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 0, 1, 7, CLK_CFG_UPDATE1, TOP_MUX_AUD_1_SHIFT, + CLK_FENC_STATUS_MON_1, 11), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_AUD_2_SEL, "ck_aud_2_sel", ck_aud_2_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 8, 1, 15, CLK_CFG_UPDATE1, TOP_MUX_AUD_2_SHIFT, + CLK_FENC_STATUS_MON_1, 10), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_ADSP_SEL, "ck_adsp_sel", ck_adsp_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 16, 1, 23, CLK_CFG_UPDATE1, TOP_MUX_ADSP_SHIFT, + CLK_FENC_STATUS_MON_1, 9), + MUX_GATE_CLR_SET_UPD(CLK_CK_ADSP_UARTHUB_BCLK_SEL, "ck_adsp_uarthub_b_sel", + ck_adsp_uarthub_b_parents, CLK_CFG_13, CLK_CFG_13_SET, + CLK_CFG_13_CLR, 24, 2, 31, + CLK_CFG_UPDATE1, TOP_MUX_ADSP_UARTHUB_BCLK_SHIFT), + /* CLK_CFG_14 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_DPMAIF_MAIN_SEL, "ck_dpmaif_main_sel", ck_dpmaif_main_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 0, 4, 7, CLK_CFG_UPDATE1, TOP_MUX_DPMAIF_MAIN_SHIFT, + CLK_FENC_STATUS_MON_1, 7), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_PWM_SEL, "ck_pwm_sel", ck_pwm_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 8, 2, 15, CLK_CFG_UPDATE1, TOP_MUX_PWM_SHIFT, + CLK_FENC_STATUS_MON_1, 6), + MUX_CLR_SET_UPD(CLK_CK_MCUPM_SEL, "ck_mcupm_sel", + ck_mcupm_parents, CLK_CFG_14, CLK_CFG_14_SET, + CLK_CFG_14_CLR, 16, 3, + CLK_CFG_UPDATE1, TOP_MUX_MCUPM_SHIFT), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_SFLASH_SEL, "ck_sflash_sel", ck_sflash_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 24, 2, 31, CLK_CFG_UPDATE1, TOP_MUX_SFLASH_SHIFT, + CLK_FENC_STATUS_MON_1, 4), + /* CLK_CFG_15 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_IPSEAST_SEL, "ck_ipseast_sel", ck_ipseast_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_IPSEAST_SHIFT, + CLK_FENC_STATUS_MON_1, 3), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_TL_SEL, "ck_tl_sel", ck_tl_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 16, 2, 23, CLK_CFG_UPDATE2, TOP_MUX_TL_SHIFT, + CLK_FENC_STATUS_MON_1, 1), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_TL_P1_SEL, "ck_tl_p1_sel", ck_tl_p1_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 24, 2, 31, CLK_CFG_UPDATE2, TOP_MUX_TL_P1_SHIFT, + CLK_FENC_STATUS_MON_1, 0), + /* CLK_CFG_16 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK_TL_P2_SEL, "ck_tl_p2_sel", ck_tl_p2_parents, + CLK_CFG_16, CLK_CFG_16_SET, CLK_CFG_16_CLR, + 0, 2, 7, CLK_CFG_UPDATE2, TOP_MUX_TL_P2_SHIFT, + CLK_FENC_STATUS_MON_2, 31), + MUX_CLR_SET_UPD(CLK_CK_EMI_INTERFACE_546_SEL, "ck_md_emi_sel", + ck_md_emi_parents, CLK_CFG_16, CLK_CFG_16_SET, + CLK_CFG_16_CLR, 8, 1, + CLK_CFG_UPDATE2, TOP_MUX_EMI_INTERFACE_546_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SDF_SEL, "ck_sdf_sel", + ck_sdf_parents, CLK_CFG_16, CLK_CFG_16_SET, + CLK_CFG_16_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SDF_SHIFT), + MUX_MULT_HWV_FENC(CLK_CK_UARTHUB_BCLK_SEL, "ck_uarthub_b_sel", ck_uarthub_b_parents, + CLK_CFG_16, CLK_CFG_16_SET, CLK_CFG_16_CLR, "hw-voter-regmap", + HWV_CG_7_DONE, HWV_CG_7_SET, HWV_CG_7_CLR, + 24, 2, 31, CLK_CFG_UPDATE2, TOP_MUX_UARTHUB_BCLK_SHIFT, + CLK_FENC_STATUS_MON_2, 28), + /* CLK_CFG_17 */ + MUX_CLR_SET_UPD(CLK_CK_DPSW_CMP_26M_SEL, "ck_dpsw_cmp_26m_sel", + ck_dpsw_cmp_26m_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 0, 1, + CLK_CFG_UPDATE2, TOP_MUX_DPSW_CMP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SMAPCK_SEL, "ck_smapck_sel", + ck_smapck_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 8, 1, + CLK_CFG_UPDATE2, TOP_MUX_SMAPCK_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SSR_PKA_SEL, "ck_ssr_pka_sel", + ck_ssr_pka_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SSR_PKA_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SSR_DMA_SEL, "ck_ssr_dma_sel", + ck_ssr_dma_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 24, 3, + CLK_CFG_UPDATE2, TOP_MUX_SSR_DMA_SHIFT), + /* CLK_CFG_18 */ + MUX_CLR_SET_UPD(CLK_CK_SSR_KDF_SEL, "ck_ssr_kdf_sel", + ck_ssr_kdf_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 0, 2, + CLK_CFG_UPDATE2, TOP_MUX_SSR_KDF_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SSR_RNG_SEL, "ck_ssr_rng_sel", + ck_ssr_rng_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 8, 2, + CLK_CFG_UPDATE2, TOP_MUX_SSR_RNG_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SPU0_SEL, "ck_spu0_sel", + ck_spu0_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SPU0_SHIFT), + MUX_CLR_SET_UPD(CLK_CK_SPU1_SEL, "ck_spu1_sel", + ck_spu1_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 24, 3, + CLK_CFG_UPDATE2, TOP_MUX_SPU1_SHIFT), + /* CLK_CFG_19 */ + MUX_CLR_SET_UPD(CLK_CK_DXCC_SEL, "ck_dxcc_sel", + ck_dxcc_parents, CLK_CFG_19, CLK_CFG_19_SET, + CLK_CFG_19_CLR, 0, 2, + CLK_CFG_UPDATE2, TOP_MUX_DXCC_SHIFT), +}; + +static const struct mtk_composite ck_composites[] = { + /* CLK_AUDDIV_0 */ + MUX(CLK_CK_APLL_I2SIN0_MCK_SEL, "ck_apll_i2sin0_m_sel", + ck_apll_i2sin0_m_parents, 0x020c, 16, 1), + MUX(CLK_CK_APLL_I2SIN1_MCK_SEL, "ck_apll_i2sin1_m_sel", + ck_apll_i2sin1_m_parents, 0x020c, 17, 1), + MUX(CLK_CK_APLL_I2SIN2_MCK_SEL, "ck_apll_i2sin2_m_sel", + ck_apll_i2sin2_m_parents, 0x020c, 18, 1), + MUX(CLK_CK_APLL_I2SIN3_MCK_SEL, "ck_apll_i2sin3_m_sel", + ck_apll_i2sin3_m_parents, 0x020c, 19, 1), + MUX(CLK_CK_APLL_I2SIN4_MCK_SEL, "ck_apll_i2sin4_m_sel", + ck_apll_i2sin4_m_parents, 0x020c, 20, 1), + MUX(CLK_CK_APLL_I2SIN6_MCK_SEL, "ck_apll_i2sin6_m_sel", + ck_apll_i2sin6_m_parents, 0x020c, 21, 1), + MUX(CLK_CK_APLL_I2SOUT0_MCK_SEL, "ck_apll_i2sout0_m_sel", + ck_apll_i2sout0_m_parents, 0x020c, 22, 1), + MUX(CLK_CK_APLL_I2SOUT1_MCK_SEL, "ck_apll_i2sout1_m_sel", + ck_apll_i2sout1_m_parents, 0x020c, 23, 1), + MUX(CLK_CK_APLL_I2SOUT2_MCK_SEL, "ck_apll_i2sout2_m_sel", + ck_apll_i2sout2_m_parents, 0x020c, 24, 1), + MUX(CLK_CK_APLL_I2SOUT3_MCK_SEL, "ck_apll_i2sout3_m_sel", + ck_apll_i2sout3_m_parents, 0x020c, 25, 1), + MUX(CLK_CK_APLL_I2SOUT4_MCK_SEL, "ck_apll_i2sout4_m_sel", + ck_apll_i2sout4_m_parents, 0x020c, 26, 1), + MUX(CLK_CK_APLL_I2SOUT6_MCK_SEL, "ck_apll_i2sout6_m_sel", + ck_apll_i2sout6_m_parents, 0x020c, 27, 1), + MUX(CLK_CK_APLL_FMI2S_MCK_SEL, "ck_apll_fmi2s_m_sel", + ck_apll_fmi2s_m_parents, 0x020c, 28, 1), + MUX(CLK_CK_APLL_TDMOUT_MCK_SEL, "ck_apll_tdmout_m_sel", + ck_apll_tdmout_m_parents, 0x020c, 29, 1), + /* CLK_AUDDIV_2 */ + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN0, "ck_apll12_div_i2sin0", + "ck_apll_i2sin0_m_sel", 0x020c, + 0, CLK_AUDDIV_2, 8, 0), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN1, "ck_apll12_div_i2sin1", + "ck_apll_i2sin1_m_sel", 0x020c, + 1, CLK_AUDDIV_2, 8, 8), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN2, "ck_apll12_div_i2sin2", + "ck_apll_i2sin2_m_sel", 0x020c, + 2, CLK_AUDDIV_2, 8, 16), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN3, "ck_apll12_div_i2sin3", + "ck_apll_i2sin3_m_sel", 0x020c, + 3, CLK_AUDDIV_2, 8, 24), + /* CLK_AUDDIV_3 */ + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN4, "ck_apll12_div_i2sin4", + "ck_apll_i2sin4_m_sel", 0x020c, + 4, CLK_AUDDIV_3, 8, 0), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SIN6, "ck_apll12_div_i2sin6", + "ck_apll_i2sin6_m_sel", 0x020c, + 5, CLK_AUDDIV_3, 8, 8), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT0, "ck_apll12_div_i2sout0", + "ck_apll_i2sout0_m_sel", 0x020c, + 6, CLK_AUDDIV_3, 8, 16), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT1, "ck_apll12_div_i2sout1", + "ck_apll_i2sout1_m_sel", 0x020c, + 7, CLK_AUDDIV_3, 8, 24), + /* CLK_AUDDIV_4 */ + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT2, "ck_apll12_div_i2sout2", + "ck_apll_i2sout2_m_sel", 0x020c, + 8, CLK_AUDDIV_4, 8, 0), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT3, "ck_apll12_div_i2sout3", + "ck_apll_i2sout3_m_sel", 0x020c, + 9, CLK_AUDDIV_4, 8, 8), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT4, "ck_apll12_div_i2sout4", + "ck_apll_i2sout4_m_sel", 0x020c, + 10, CLK_AUDDIV_4, 8, 16), + DIV_GATE(CLK_CK_APLL12_CK_DIV_I2SOUT6, "ck_apll12_div_i2sout6", + "ck_apll_i2sout6_m_sel", 0x020c, + 11, CLK_AUDDIV_4, 8, 24), + /* CLK_AUDDIV_5 */ + DIV_GATE(CLK_CK_APLL12_CK_DIV_FMI2S, "ck_apll12_div_fmi2s", + "ck_apll_fmi2s_m_sel", 0x020c, + 12, CLK_AUDDIV_5, 8, 0), + DIV_GATE(CLK_CK_APLL12_CK_DIV_TDMOUT_M, "ck_apll12_div_tdmout_m", + "ck_apll_tdmout_m_sel", 0x020c, + 13, CLK_AUDDIV_5, 8, 8), + DIV_GATE(CLK_CK_APLL12_CK_DIV_TDMOUT_B, "ck_apll12_div_tdmout_b", + "ck_apll_tdmout_m_sel", 0x020c, + 14, CLK_AUDDIV_5, 8, 16), +}; + +static int clk_mt8196_ck_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + int r; + struct device_node *node = pdev->dev.of_node; + + void __iomem *base; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) { + pr_err("%s(): ioremap failed\n", __func__); + return PTR_ERR(base); + } + + clk_data = mtk_alloc_clk_data(CLK_CK_NR_CLK); + + mtk_clk_register_factors(ck_divs, ARRAY_SIZE(ck_divs), + clk_data); + + mtk_clk_register_muxes(&pdev->dev, ck_muxes, ARRAY_SIZE(ck_muxes), node, + &mt8196_clk_ck_lock, clk_data); + + mtk_clk_register_composites(&pdev->dev, ck_composites, ARRAY_SIZE(ck_composites), + base, &mt8196_clk_ck_lock, clk_data); + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + pr_err("%s(): could not register clock provider: %d\n", + __func__, r); + + + return r; +} + +static void clk_mt8196_ck_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_composites(ck_composites, ARRAY_SIZE(ck_composites), clk_data); + mtk_clk_unregister_muxes(ck_muxes, ARRAY_SIZE(ck_muxes), clk_data); + mtk_clk_unregister_factors(ck_divs, ARRAY_SIZE(ck_divs), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_ck[] = { + { .compatible = "mediatek,mt8196-cksys", }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_ck_drv = { + .probe = clk_mt8196_ck_probe, + .remove_new = clk_mt8196_ck_remove, + .driver = { + .name = "clk-mt8196-ck", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_ck, + }, +}; + +module_platform_driver(clk_mt8196_ck_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-topckgen2.c b/drivers/clk/mediatek/clk-mt8196-topckgen2.c new file mode 100644 index 0000000000000..a3cb2c64dfaba --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-topckgen2.c @@ -0,0 +1,835 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-mtk.h" +#include "clk-mux.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* MUX SEL REG */ +#define CKSYS2_CLK_CFG_UPDATE 0x0004 +#define CKSYS2_CLK_CFG_0 0x0010 +#define CKSYS2_CLK_CFG_0_SET 0x0014 +#define CKSYS2_CLK_CFG_0_CLR 0x0018 +#define CKSYS2_CLK_CFG_1 0x0020 +#define CKSYS2_CLK_CFG_1_SET 0x0024 +#define CKSYS2_CLK_CFG_1_CLR 0x0028 +#define CKSYS2_CLK_CFG_2 0x0030 +#define CKSYS2_CLK_CFG_2_SET 0x0034 +#define CKSYS2_CLK_CFG_2_CLR 0x0038 +#define CKSYS2_CLK_CFG_3 0x0040 +#define CKSYS2_CLK_CFG_3_SET 0x0044 +#define CKSYS2_CLK_CFG_3_CLR 0x0048 +#define CKSYS2_CLK_CFG_4 0x0050 +#define CKSYS2_CLK_CFG_4_SET 0x0054 +#define CKSYS2_CLK_CFG_4_CLR 0x0058 +#define CKSYS2_CLK_CFG_5 0x0060 +#define CKSYS2_CLK_CFG_5_SET 0x0064 +#define CKSYS2_CLK_CFG_5_CLR 0x0068 +#define CKSYS2_CLK_CFG_6 0x0070 +#define CKSYS2_CLK_CFG_6_SET 0x0074 +#define CKSYS2_CLK_CFG_6_CLR 0x0078 +#define CKSYS2_CLK_FENC_STATUS_MON_0 0x0174 + +/* MUX SHIFT */ +#define TOP_MUX_SENINF0_SHIFT 0 +#define TOP_MUX_SENINF1_SHIFT 1 +#define TOP_MUX_SENINF2_SHIFT 2 +#define TOP_MUX_SENINF3_SHIFT 3 +#define TOP_MUX_SENINF4_SHIFT 4 +#define TOP_MUX_SENINF5_SHIFT 5 +#define TOP_MUX_IMG1_SHIFT 6 +#define TOP_MUX_IPE_SHIFT 7 +#define TOP_MUX_CAM_SHIFT 8 +#define TOP_MUX_CAMTM_SHIFT 9 +#define TOP_MUX_DPE_SHIFT 10 +#define TOP_MUX_VDEC_SHIFT 11 +#define TOP_MUX_CCUSYS_SHIFT 12 +#define TOP_MUX_CCUTM_SHIFT 13 +#define TOP_MUX_VENC_SHIFT 14 +#define TOP_MUX_DVO_SHIFT 15 +#define TOP_MUX_DVO_FAVT_SHIFT 16 +#define TOP_MUX_DP1_SHIFT 17 +#define TOP_MUX_DP0_SHIFT 18 +#define TOP_MUX_DISP_SHIFT 19 +#define TOP_MUX_MDP_SHIFT 20 +#define TOP_MUX_MMINFRA_SHIFT 21 +#define TOP_MUX_MMINFRA_SNOC_SHIFT 22 +#define TOP_MUX_MMUP_SHIFT 23 +#define TOP_MUX_MMINFRA_AO_SHIFT 26 + + +/* CKSTA REG */ +#define CKSYS2_CKSTA_REG1 0x00fc +#define CKSYS2_CKSTA_REG2 0x0100 +#define CKSYS2_CKSTA_REG 0x00f8 + +/* HW Voter REG */ +#define HWV_CG_30_SET 0x0058 +#define HWV_CG_30_CLR 0x005c +#define HWV_CG_30_DONE 0x2c2c + +#define MM_HW_CCF_HW_CCF_2_SET 0x0000 +#define MM_HW_CCF_HW_CCF_2_CLR 0x0004 +#define MM_HW_CCF_HW_CCF_2_DONE 0x2c00 +#define MM_HW_CCF_HW_CCF_3_SET 0x0008 +#define MM_HW_CCF_HW_CCF_3_CLR 0x000c +#define MM_HW_CCF_HW_CCF_3_DONE 0x2c04 +#define MM_HW_CCF_HW_CCF_6_SET 0x0010 +#define MM_HW_CCF_HW_CCF_6_CLR 0x0014 +#define MM_HW_CCF_HW_CCF_6_DONE 0x2c08 +#define MM_HW_CCF_HW_CCF_7_SET 0x0018 +#define MM_HW_CCF_HW_CCF_7_CLR 0x001c +#define MM_HW_CCF_HW_CCF_7_DONE 0x2c0c +#define MM_HW_CCF_HW_CCF_8_SET 0x0020 +#define MM_HW_CCF_HW_CCF_8_CLR 0x0024 +#define MM_HW_CCF_HW_CCF_8_DONE 0x2c10 +#define MM_HW_CCF_HW_CCF_9_SET 0x0028 +#define MM_HW_CCF_HW_CCF_9_CLR 0x002c +#define MM_HW_CCF_HW_CCF_9_DONE 0x2c14 +#define MM_HW_CCF_HW_CCF_10_SET 0x0030 +#define MM_HW_CCF_HW_CCF_10_CLR 0x0034 +#define MM_HW_CCF_HW_CCF_10_DONE 0x2c18 +#define MM_HW_CCF_HW_CCF_11_SET 0x0038 +#define MM_HW_CCF_HW_CCF_11_CLR 0x003c +#define MM_HW_CCF_HW_CCF_11_DONE 0x2c1c +#define MM_HW_CCF_HW_CCF_12_SET 0x0040 +#define MM_HW_CCF_HW_CCF_12_CLR 0x0044 +#define MM_HW_CCF_HW_CCF_12_DONE 0x2c20 +#define MM_HW_CCF_HW_CCF_13_SET 0x0048 +#define MM_HW_CCF_HW_CCF_13_CLR 0x004c +#define MM_HW_CCF_HW_CCF_13_DONE 0x2c24 +#define MM_HW_CCF_HW_CCF_15_SET 0x0050 +#define MM_HW_CCF_HW_CCF_15_CLR 0x0054 +#define MM_HW_CCF_HW_CCF_15_DONE 0x2c28 +#define MM_HW_CCF_HW_CCF_16_SET 0x0058 +#define MM_HW_CCF_HW_CCF_16_CLR 0x005c +#define MM_HW_CCF_HW_CCF_16_DONE 0x2c2c +#define MM_HW_CCF_HW_CCF_17_SET 0x0060 +#define MM_HW_CCF_HW_CCF_17_CLR 0x0064 +#define MM_HW_CCF_HW_CCF_17_DONE 0x2c30 +#define MM_HW_CCF_HW_CCF_18_SET 0x0068 +#define MM_HW_CCF_HW_CCF_18_CLR 0x006c +#define MM_HW_CCF_HW_CCF_18_DONE 0x2c34 +#define MM_HW_CCF_HW_CCF_5_SET 0x0070 +#define MM_HW_CCF_HW_CCF_5_CLR 0x0074 +#define MM_HW_CCF_HW_CCF_5_DONE 0x2c38 +#define MM_HW_CCF_HW_CCF_21_SET 0x0078 +#define MM_HW_CCF_HW_CCF_21_CLR 0x007c +#define MM_HW_CCF_HW_CCF_21_DONE 0x2c3c +#define MM_HW_CCF_HW_CCF_22_SET 0x0080 +#define MM_HW_CCF_HW_CCF_22_CLR 0x0084 +#define MM_HW_CCF_HW_CCF_22_DONE 0x2c40 +#define MM_HW_CCF_HW_CCF_23_SET 0x0088 +#define MM_HW_CCF_HW_CCF_23_CLR 0x008c +#define MM_HW_CCF_HW_CCF_23_DONE 0x2c44 +#define MM_HW_CCF_HW_CCF_24_SET 0x0090 +#define MM_HW_CCF_HW_CCF_24_CLR 0x0094 +#define MM_HW_CCF_HW_CCF_24_DONE 0x2c48 +#define MM_HW_CCF_HW_CCF_25_SET 0x0098 +#define MM_HW_CCF_HW_CCF_25_CLR 0x009c +#define MM_HW_CCF_HW_CCF_25_DONE 0x2c4c +#define MM_HW_CCF_HW_CCF_26_SET 0x00a0 +#define MM_HW_CCF_HW_CCF_26_CLR 0x00a4 +#define MM_HW_CCF_HW_CCF_26_DONE 0x2c50 +#define MM_HW_CCF_HW_CCF_30_SET 0x00f0 +#define MM_HW_CCF_HW_CCF_30_CLR 0x00f4 +#define MM_HW_CCF_HW_CCF_30_DONE 0x2c78 +#define MM_HW_CCF_HW_CCF_31_SET 0x00f8 +#define MM_HW_CCF_HW_CCF_31_CLR 0x00fc +#define MM_HW_CCF_HW_CCF_31_DONE 0x2c7c +#define MM_HW_CCF_HW_CCF_32_SET 0x0100 +#define MM_HW_CCF_HW_CCF_32_CLR 0x0104 +#define MM_HW_CCF_HW_CCF_32_DONE 0x2c80 +#define MM_HW_CCF_HW_CCF_33_SET 0x0108 +#define MM_HW_CCF_HW_CCF_33_CLR 0x010c +#define MM_HW_CCF_HW_CCF_33_DONE 0x2c84 +#define MM_HW_CCF_HW_CCF_34_SET 0x0110 +#define MM_HW_CCF_HW_CCF_34_CLR 0x0114 +#define MM_HW_CCF_HW_CCF_34_DONE 0x2c88 +#define MM_HW_CCF_HW_CCF_35_SET 0x0118 +#define MM_HW_CCF_HW_CCF_35_CLR 0x011c +#define MM_HW_CCF_HW_CCF_35_DONE 0x2c8c +#define MM_HW_CCF_HW_CCF_36_SET 0x0120 +#define MM_HW_CCF_HW_CCF_36_CLR 0x0124 +#define MM_HW_CCF_HW_CCF_36_DONE 0x2c90 +#define MM_HW_CCF_HW_CCF_MUX_UPDATE_31_0 0x0240 + +static DEFINE_SPINLOCK(mt8196_clk_ck2_lock); + +static const struct mtk_fixed_factor ck2_divs[] = { + FACTOR(CLK_CK2_MAINPLL2_D2, "ck2_mainpll2_d2", + "mainpll2", 1, 2), + FACTOR(CLK_CK2_MAINPLL2_D3, "ck2_mainpll2_d3", + "mainpll2", 1, 3), + FACTOR(CLK_CK2_MAINPLL2_D4, "ck2_mainpll2_d4", + "mainpll2", 1, 4), + FACTOR(CLK_CK2_MAINPLL2_D4_D2, "ck2_mainpll2_d4_d2", + "mainpll2", 1, 8), + FACTOR(CLK_CK2_MAINPLL2_D4_D4, "ck2_mainpll2_d4_d4", + "mainpll2", 1, 16), + FACTOR(CLK_CK2_MAINPLL2_D5, "ck2_mainpll2_d5", + "mainpll2", 1, 5), + FACTOR(CLK_CK2_MAINPLL2_D5_D2, "ck2_mainpll2_d5_d2", + "mainpll2", 1, 10), + FACTOR(CLK_CK2_MAINPLL2_D6, "ck2_mainpll2_d6", + "mainpll2", 1, 6), + FACTOR(CLK_CK2_MAINPLL2_D6_D2, "ck2_mainpll2_d6_d2", + "mainpll2", 1, 12), + FACTOR(CLK_CK2_MAINPLL2_D7, "ck2_mainpll2_d7", + "mainpll2", 1, 7), + FACTOR(CLK_CK2_MAINPLL2_D7_D2, "ck2_mainpll2_d7_d2", + "mainpll2", 1, 14), + FACTOR(CLK_CK2_MAINPLL2_D9, "ck2_mainpll2_d9", + "mainpll2", 1, 9), + FACTOR(CLK_CK2_UNIVPLL2_D3, "ck2_univpll2_d3", + "univpll2", 1, 3), + FACTOR(CLK_CK2_UNIVPLL2_D4, "ck2_univpll2_d4", + "univpll2", 1, 4), + FACTOR(CLK_CK2_UNIVPLL2_D4_D2, "ck2_univpll2_d4_d2", + "univpll2", 1, 8), + FACTOR(CLK_CK2_UNIVPLL2_D5, "ck2_univpll2_d5", + "univpll2", 1, 5), + FACTOR(CLK_CK2_UNIVPLL2_D5_D2, "ck2_univpll2_d5_d2", + "univpll2", 1, 10), + FACTOR(CLK_CK2_UNIVPLL2_D6, "ck2_univpll2_d6", + "univpll2", 1, 6), + FACTOR(CLK_CK2_UNIVPLL2_D6_D2, "ck2_univpll2_d6_d2", + "univpll2", 1, 12), + FACTOR(CLK_CK2_UNIVPLL2_D6_D4, "ck2_univpll2_d6_d4", + "univpll2", 1, 24), + FACTOR(CLK_CK2_UNIVPLL2_D7, "ck2_univpll2_d7", + "univpll2", 1, 7), + FACTOR(CLK_CK2_IMGPLL_D2, "ck2_imgpll_d2", + "imgpll", 1, 2), + FACTOR(CLK_CK2_IMGPLL_D4, "ck2_imgpll_d4", + "imgpll", 1, 4), + FACTOR(CLK_CK2_IMGPLL_D5, "ck2_imgpll_d5", + "imgpll", 1, 5), + FACTOR(CLK_CK2_IMGPLL_D5_D2, "ck2_imgpll_d5_d2", + "imgpll", 1, 10), + FACTOR(CLK_CK2_MMPLL2_D3, "ck2_mmpll2_d3", + "mmpll2", 1, 3), + FACTOR(CLK_CK2_MMPLL2_D4, "ck2_mmpll2_d4", + "mmpll2", 1, 4), + FACTOR(CLK_CK2_MMPLL2_D4_D2, "ck2_mmpll2_d4_d2", + "mmpll2", 1, 8), + FACTOR(CLK_CK2_MMPLL2_D5, "ck2_mmpll2_d5", + "mmpll2", 1, 5), + FACTOR(CLK_CK2_MMPLL2_D5_D2, "ck2_mmpll2_d5_d2", + "mmpll2", 1, 10), + FACTOR(CLK_CK2_MMPLL2_D6, "ck2_mmpll2_d6", + "mmpll2", 1, 6), + FACTOR(CLK_CK2_MMPLL2_D6_D2, "ck2_mmpll2_d6_d2", + "mmpll2", 1, 12), + FACTOR(CLK_CK2_MMPLL2_D7, "ck2_mmpll2_d7", + "mmpll2", 1, 7), + FACTOR(CLK_CK2_MMPLL2_D9, "ck2_mmpll2_d9", + "mmpll2", 1, 9), + FACTOR(CLK_CK2_TVDPLL1_D4, "ck2_tvdpll1_d4", + "tvdpll1", 1, 4), + FACTOR(CLK_CK2_TVDPLL1_D8, "ck2_tvdpll1_d8", + "tvdpll1", 1, 8), + FACTOR(CLK_CK2_TVDPLL1_D16, "ck2_tvdpll1_d16", + "tvdpll1", 1, 16), + FACTOR(CLK_CK2_TVDPLL2_D2, "ck2_tvdpll2_d2", + "tvdpll2", 1, 2), + FACTOR(CLK_CK2_TVDPLL2_D4, "ck2_tvdpll2_d4", + "tvdpll2", 1, 4), + FACTOR(CLK_CK2_TVDPLL2_D8, "ck2_tvdpll2_d8", + "tvdpll2", 1, 8), + FACTOR(CLK_CK2_TVDPLL2_D16, "ck2_tvdpll2_d16", + "tvdpll2", 92, 1473), + FACTOR(CLK_CK2_CCUSYS, "ck2_ccusys_ck", + "ck2_ccusys_sel", 1, 1), + FACTOR(CLK_CK2_VENC, "ck2_venc_ck", + "ck2_venc_sel", 1, 1), + FACTOR(CLK_CK2_MMINFRA, "ck2_mminfra_ck", + "ck2_mminfra_sel", 1, 1), + FACTOR(CLK_CK2_IMG1, "ck2_img1_ck", + "ck2_img1_sel", 1, 1), + FACTOR(CLK_CK2_IPE, "ck2_ipe_ck", + "ck2_ipe_sel", 1, 1), + FACTOR(CLK_CK2_CAM, "ck2_cam_ck", + "ck2_cam_sel", 1, 1), + FACTOR(CLK_CK2_CAMTM, "ck2_camtm_ck", + "ck2_camtm_sel", 1, 1), + FACTOR(CLK_CK2_DPE, "ck2_dpe_ck", + "ck2_dpe_sel", 1, 1), + FACTOR(CLK_CK2_VDEC, "ck2_vdec_ck", + "ck2_vdec_sel", 1, 1), + FACTOR(CLK_CK2_DP1, "ck2_dp1_ck", + "ck2_dp1_sel", 1, 1), + FACTOR(CLK_CK2_DP0, "ck2_dp0_ck", + "ck2_dp0_sel", 1, 1), + FACTOR(CLK_CK2_DISP, "ck2_disp_ck", + "ck2_disp_sel", 1, 1), + FACTOR(CLK_CK2_MDP, "ck2_mdp_ck", + "ck2_mdp_sel", 1, 1), + FACTOR(CLK_CK2_AVS_IMG, "ck2_avs_img_ck", + "ck_tck_26m_mx9_ck", 1, 1), + FACTOR(CLK_CK2_AVS_VDEC, "ck2_avs_vdec_ck", + "ck_tck_26m_mx9_ck", 1, 1), + FACTOR(CLK_CK2_TVDPLL3_D2, "ck2_tvdpll3_d2", + "tvdpll3", 1, 2), + FACTOR(CLK_CK2_TVDPLL3_D4, "ck2_tvdpll3_d4", + "tvdpll3", 1, 4), + FACTOR(CLK_CK2_TVDPLL3_D8, "ck2_tvdpll3_d8", + "tvdpll3", 1, 8), + FACTOR(CLK_CK2_TVDPLL3_D16, "ck2_tvdpll3_d16", + "tvdpll3", 92, 1473), +}; + +static const char * const ck2_seninf0_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_seninf1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_seninf2_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_seninf3_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_seninf4_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_seninf5_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "ck2_univpll2_d6_d2", + "ck2_mainpll2_d9", + "ck_osc_d2", + "ck2_mainpll2_d4_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mainpll2_d6", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_univpll2_d5" +}; + +static const char * const ck2_img1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_osc_d3", + "ck2_mmpll2_d6_d2", + "ck_osc_d2", + "ck2_imgpll_d5_d2", + "ck2_mmpll2_d5_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mmpll2_d5", + "ck2_univpll2_d4", + "ck2_imgpll_d4" +}; + +static const char * const ck2_ipe_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "ck2_univpll2_d6", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_imgpll_d5", + "ck_mainpll_d4", + "ck2_mmpll2_d5", + "ck2_imgpll_d4" +}; + +static const char * const ck2_cam_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "ck2_mmpll2_d5_d2", + "ck2_univpll2_d4_d2", + "ck2_univpll2_d7", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mmpll2_d5", + "ck2_univpll2_d4", + "ck2_imgpll_d4", + "ck2_mmpll2_d4" +}; + +static const char * const ck2_camtm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_univpll2_d6_d4", + "ck_osc_d4", + "ck_osc_d3", + "ck2_univpll2_d6_d2" +}; + +static const char * const ck2_dpe_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_mmpll2_d5_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mmpll2_d5", + "ck2_imgpll_d4", + "ck2_mmpll2_d4" +}; + +static const char * const ck2_vdec_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d2", + "ck2_mainpll2_d4_d4", + "ck2_mainpll2_d7_d2", + "ck2_mainpll2_d6_d2", + "ck2_mainpll2_d5_d2", + "ck2_mainpll2_d9", + "ck2_mainpll2_d4_d2", + "ck2_mainpll2_d7", + "ck2_mainpll2_d6", + "ck2_univpll2_d6", + "ck2_mainpll2_d5", + "ck2_mainpll2_d4", + "ck2_imgpll_d2" +}; + +static const char * const ck2_ccusys_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "ck2_mmpll2_d5_d2", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d7", + "ck2_univpll2_d6", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mainpll2_d4", + "ck2_mainpll2_d3", + "ck2_univpll2_d3" +}; + +static const char * const ck2_ccutm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_univpll2_d6_d4", + "ck_osc_d4", + "ck_osc_d3", + "ck2_univpll2_d6_d2" +}; + +static const char * const ck2_venc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_mainpll2_d5_d2", + "ck2_univpll2_d5_d2", + "ck2_mainpll2_d4_d2", + "ck2_mmpll2_d9", + "ck2_univpll2_d4_d2", + "ck2_mmpll2_d4_d2", + "ck2_mainpll2_d6", + "ck2_univpll2_d6", + "ck2_mainpll2_d5", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mainpll2_d4", + "ck2_univpll2_d4", + "ck2_univpll2_d3" +}; + +static const char * const ck2_dp1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_tvdpll2_d16", + "ck2_tvdpll2_d8", + "ck2_tvdpll2_d4", + "ck2_tvdpll2_d2" +}; + +static const char * const ck2_dp0_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_tvdpll1_d16", + "ck2_tvdpll1_d8", + "ck2_tvdpll1_d4", + "ck_tvdpll1_d2" +}; + +static const char * const ck2_disp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "ck2_mainpll2_d5", + "ck2_mmpll2_d6", + "ck2_mainpll2_d4", + "ck2_univpll2_d4", + "ck2_mainpll2_d3" +}; + +static const char * const ck2_mdp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d5_d2", + "ck2_mainpll2_d5_d2", + "ck2_mmpll2_d6_d2", + "ck2_mainpll2_d9", + "ck2_mainpll2_d4_d2", + "ck2_mainpll2_d7", + "ck2_mainpll2_d6", + "ck2_mainpll2_d5", + "ck2_mmpll2_d6", + "ck2_mainpll2_d4", + "ck2_univpll2_d4", + "ck2_mainpll2_d3" +}; + +static const char * const ck2_mminfra_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d7_d2", + "ck_mainpll_d5_d2", + "ck_mainpll_d9", + "ck2_mmpll2_d6_d2", + "ck2_mainpll2_d4_d2", + "ck_mainpll_d6", + "ck2_univpll2_d6", + "ck2_mainpll2_d5", + "ck2_mmpll2_d6", + "ck2_univpll2_d5", + "ck2_mainpll2_d4", + "ck2_univpll2_d4", + "ck2_mainpll2_d3", + "ck2_univpll2_d3" +}; + +static const char * const ck2_mminfra_snoc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d7_d2", + "ck_mainpll_d9", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck2_mmpll2_d4_d2", + "ck_mainpll_d5", + "ck_mainpll_d4", + "ck2_univpll2_d4", + "ck2_mmpll2_d4", + "ck2_mainpll2_d3", + "ck2_univpll2_d3", + "ck2_mmpll2_d3", + "ck2_mainpll2_d2" +}; + +static const char * const ck2_mmup_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_mainpll2_d6", + "ck2_mainpll2_d5", + "ck_osc_d2", + "ck_osc", + "ck_mainpll_d4", + "ck2_univpll2_d4", + "ck2_mainpll2_d3" +}; + +static const char * const ck2_mminfra_ao_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d3" +}; + +static const char * const ck2_dvo_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_tvdpll3_d16", + "ck2_tvdpll3_d8", + "ck2_tvdpll3_d4", + "ck2_tvdpll3_d2" +}; + +static const char * const ck2_dvo_favt_parents[] = { + "ck_tck_26m_mx9_ck", + "ck2_tvdpll3_d16", + "ck2_tvdpll3_d8", + "ck2_tvdpll3_d4", + "ck_apll1_ck", + "ck_apll2_ck", + "ck2_tvdpll3_d2" +}; + +static const struct mtk_mux ck2_muxes[] = { + /* CKSYS2_CLK_CFG_0 */ + MUX_MULT_HWV_FENC(CLK_CK2_SENINF0_SEL, "ck2_seninf0_sel", ck2_seninf0_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_30_DONE, MM_HW_CCF_HW_CCF_30_SET, MM_HW_CCF_HW_CCF_30_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF0_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 31), + MUX_MULT_HWV_FENC(CLK_CK2_SENINF1_SEL, "ck2_seninf1_sel", ck2_seninf1_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_30_DONE, MM_HW_CCF_HW_CCF_30_SET, MM_HW_CCF_HW_CCF_30_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 30), + MUX_MULT_HWV_FENC(CLK_CK2_SENINF2_SEL, "ck2_seninf2_sel", ck2_seninf2_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_30_DONE, MM_HW_CCF_HW_CCF_30_SET, MM_HW_CCF_HW_CCF_30_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF2_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 29), + MUX_MULT_HWV_FENC(CLK_CK2_SENINF3_SEL, "ck2_seninf3_sel", ck2_seninf3_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_30_DONE, MM_HW_CCF_HW_CCF_30_SET, MM_HW_CCF_HW_CCF_30_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF3_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 28), + /* CKSYS2_CLK_CFG_1 */ + MUX_MULT_HWV_FENC(CLK_CK2_SENINF4_SEL, "ck2_seninf4_sel", ck2_seninf4_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_31_DONE, MM_HW_CCF_HW_CCF_31_SET, MM_HW_CCF_HW_CCF_31_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF4_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 27), + MUX_MULT_HWV_FENC(CLK_CK2_SENINF5_SEL, "ck2_seninf5_sel", ck2_seninf5_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_31_DONE, MM_HW_CCF_HW_CCF_31_SET, MM_HW_CCF_HW_CCF_31_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF5_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 26), + MUX_MULT_HWV_FENC(CLK_CK2_IMG1_SEL, "ck2_img1_sel", ck2_img1_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_31_DONE, MM_HW_CCF_HW_CCF_31_SET, MM_HW_CCF_HW_CCF_31_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_IMG1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 25), + MUX_MULT_HWV_FENC(CLK_CK2_IPE_SEL, "ck2_ipe_sel", ck2_ipe_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_31_DONE, MM_HW_CCF_HW_CCF_31_SET, MM_HW_CCF_HW_CCF_31_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_IPE_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 24), + /* CKSYS2_CLK_CFG_2 */ + MUX_MULT_HWV_FENC(CLK_CK2_CAM_SEL, "ck2_cam_sel", ck2_cam_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_32_DONE, MM_HW_CCF_HW_CCF_32_SET, MM_HW_CCF_HW_CCF_32_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CAM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 23), + MUX_MULT_HWV_FENC(CLK_CK2_CAMTM_SEL, "ck2_camtm_sel", ck2_camtm_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_32_DONE, MM_HW_CCF_HW_CCF_32_SET, MM_HW_CCF_HW_CCF_32_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CAMTM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 22), + MUX_MULT_HWV_FENC(CLK_CK2_DPE_SEL, "ck2_dpe_sel", ck2_dpe_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_32_DONE, MM_HW_CCF_HW_CCF_32_SET, MM_HW_CCF_HW_CCF_32_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DPE_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 21), + MUX_MULT_HWV_FENC(CLK_CK2_VDEC_SEL, "ck2_vdec_sel", ck2_vdec_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_32_DONE, MM_HW_CCF_HW_CCF_32_SET, MM_HW_CCF_HW_CCF_32_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_VDEC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 20), + /* CKSYS2_CLK_CFG_3 */ + MUX_MULT_HWV_FENC(CLK_CK2_CCUSYS_SEL, "ck2_ccusys_sel", ck2_ccusys_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_33_DONE, MM_HW_CCF_HW_CCF_33_SET, MM_HW_CCF_HW_CCF_33_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CCUSYS_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 19), + MUX_MULT_HWV_FENC(CLK_CK2_CCUTM_SEL, "ck2_ccutm_sel", ck2_ccutm_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_33_DONE, MM_HW_CCF_HW_CCF_33_SET, MM_HW_CCF_HW_CCF_33_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CCUTM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 18), + MUX_MULT_HWV_FENC(CLK_CK2_VENC_SEL, "ck2_venc_sel", ck2_venc_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_33_DONE, MM_HW_CCF_HW_CCF_33_SET, MM_HW_CCF_HW_CCF_33_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_VENC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 17), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK2_DVO_SEL, "ck2_dvo_sel", ck2_dvo_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, + 24, 3, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DVO_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 16), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK2_DVO_FAVT_SEL, "ck2_dvo_favt_sel", ck2_dvo_favt_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 0, 3, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DVO_FAVT_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 15), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK2_DP1_SEL, "ck2_dp1_sel", ck2_dp1_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DP1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 14), + MUX_GATE_FENC_CLR_SET_UPD(CLK_CK2_DP0_SEL, "ck2_dp0_sel", ck2_dp0_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 16, 3, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DP0_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 13), + MUX_MULT_HWV_FENC(CLK_CK2_DISP_SEL, "ck2_disp_sel", ck2_disp_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_34_DONE, MM_HW_CCF_HW_CCF_34_SET, MM_HW_CCF_HW_CCF_34_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DISP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 12), + /* CKSYS2_CLK_CFG_5 */ + MUX_MULT_HWV_FENC(CLK_CK2_MDP_SEL, "ck2_mdp_sel", ck2_mdp_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_35_DONE, MM_HW_CCF_HW_CCF_35_SET, MM_HW_CCF_HW_CCF_35_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MDP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 11), + MUX_MULT_HWV_FENC(CLK_CK2_MMINFRA_SEL, "ck2_mminfra_sel", ck2_mminfra_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_35_DONE, MM_HW_CCF_HW_CCF_35_SET, MM_HW_CCF_HW_CCF_35_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 10), + MUX_MULT_HWV_FENC(CLK_CK2_MMINFRA_SNOC_SEL, "ck2_mminfra_snoc_sel", ck2_mminfra_snoc_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_35_DONE, MM_HW_CCF_HW_CCF_35_SET, MM_HW_CCF_HW_CCF_35_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_SNOC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 9), + MUX_MULT_HWV_FENC(CLK_CK2_MMUP_SEL, "ck2_mmup_sel", ck2_mmup_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, "hw-voter-regmap", + HWV_CG_30_DONE, HWV_CG_30_SET, HWV_CG_30_CLR, + 24, 3, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMUP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 8), + MUX_MULT_HWV_FENC(CLK_CK2_MMINFRA_AO_SEL, "ck2_mminfra_ao_sel", ck2_mminfra_ao_parents, + CKSYS2_CLK_CFG_6, CKSYS2_CLK_CFG_6_SET, CKSYS2_CLK_CFG_6_CLR, "mm-hw-ccf-regmap", + MM_HW_CCF_HW_CCF_36_DONE, MM_HW_CCF_HW_CCF_36_SET, MM_HW_CCF_HW_CCF_36_CLR, + 16, 2, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_AO_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 5), +}; + +static int clk_mt8196_ck2_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + int r; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_CK2_NR_CLK); + + mtk_clk_register_factors(ck2_divs, ARRAY_SIZE(ck2_divs), + clk_data); + + mtk_clk_register_muxes(&pdev->dev, ck2_muxes, ARRAY_SIZE(ck2_muxes), node, + &mt8196_clk_ck2_lock, clk_data); + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + pr_err("%s(): could not register clock provider: %d\n", + __func__, r); + + return r; +} + +static void clk_mt8196_ck2_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_muxes(ck2_muxes, ARRAY_SIZE(ck2_muxes), clk_data); + mtk_clk_unregister_factors(ck2_divs, ARRAY_SIZE(ck2_divs), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_ck2[] = { + { .compatible = "mediatek,mt8196-cksys-gp2", }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_ck2_drv = { + .probe = clk_mt8196_ck2_probe, + .remove_new = clk_mt8196_ck2_remove, + .driver = { + .name = "clk-mt8196-ck2", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_ck2, + }, +}; + +module_platform_driver(clk_mt8196_ck2_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ufs_ao.c b/drivers/clk/mediatek/clk-mt8196-ufs_ao.c new file mode 100644 index 0000000000000..38dcb82289224 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ufs_ao.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs ufsao0_cg_regs = { + .set_ofs = 0x108, + .clr_ofs = 0x10c, + .sta_ofs = 0x104, +}; + +static const struct mtk_gate_regs ufsao1_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x4, +}; + +#define GATE_UFSAO0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ufsao0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_UFSAO0_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_UFSAO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ufsao1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_UFSAO1_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +static const struct mtk_gate ufsao_clks[] = { + /* UFSAO0 */ + GATE_UFSAO0(CLK_UFSAO_UFSHCI_UFS, "ufsao_ufshci_ufs", + "ck_ck", 0), + GATE_UFSAO0_V(CLK_UFSAO_UFSHCI_UFS_UFS, "ufsao_ufshci_ufs_ufs", + "ufsao_ufshci_ufs"), + GATE_UFSAO0(CLK_UFSAO_UFSHCI_AES, "ufsao_ufshci_aes", + "ck_aes_ufsfde_ck", 1), + GATE_UFSAO0_V(CLK_UFSAO_UFSHCI_AES_UFS, "ufsao_ufshci_aes_ufs", + "ufsao_ufshci_aes"), + /* UFSAO1 */ + GATE_UFSAO1(CLK_UFSAO_UNIPRO_TX_SYM, "ufsao_unipro_tx_sym", + "ck_f26m_ck", 0), + GATE_UFSAO1_V(CLK_UFSAO_UNIPRO_TX_SYM_UFS, "ufsao_unipro_tx_sym_ufs", + "ufsao_unipro_tx_sym"), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM0, "ufsao_unipro_rx_sym0", + "ck_f26m_ck", 1), + GATE_UFSAO1_V(CLK_UFSAO_UNIPRO_RX_SYM0_UFS, "ufsao_unipro_rx_sym0_ufs", + "ufsao_unipro_rx_sym0"), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM1, "ufsao_unipro_rx_sym1", + "ck_f26m_ck", 2), + GATE_UFSAO1_V(CLK_UFSAO_UNIPRO_RX_SYM1_UFS, "ufsao_unipro_rx_sym1_ufs", + "ufsao_unipro_rx_sym1"), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_SYS, "ufsao_unipro_sys", + "ck_ck", 3), + GATE_UFSAO1_V(CLK_UFSAO_UNIPRO_SYS_UFS, "ufsao_unipro_sys_ufs", + "ufsao_unipro_sys"), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_SAP, "ufsao_unipro_sap", + "ck_f26m_ck", 4), + GATE_UFSAO1_V(CLK_UFSAO_UNIPRO_SAP_UFS, "ufsao_unipro_sap_ufs", + "ufsao_unipro_sap"), + GATE_UFSAO1(CLK_UFSAO_PHY_SAP, "ufsao_phy_sap", + "ck_f26m_ck", 8), + GATE_UFSAO1_V(CLK_UFSAO_PHY_SAP_UFS, "ufsao_phy_sap_ufs", + "ufsao_phy_sap"), +}; + +static const struct mtk_clk_desc ufsao_mcd = { + .clks = ufsao_clks, + .num_clks = ARRAY_SIZE(ufsao_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_ufs_ao[] = { + { .compatible = "mediatek,mt8196-ufscfg_ao", .data = &ufsao_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_ufs_ao_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-ufs_ao", + .of_match_table = of_match_clk_mt8196_ufs_ao, + }, +}; + +module_platform_driver(clk_mt8196_ufs_ao_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vdec.c b/drivers/clk/mediatek/clk-mt8196-vdec.c new file mode 100644 index 0000000000000..98c797749d93e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vdec.c @@ -0,0 +1,484 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs vde20_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x4, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs vde20_hwv_regs = { + .set_ofs = 0x0088, + .clr_ofs = 0x008c, + .sta_ofs = 0x2c44, +}; + +static const struct mtk_gate_regs vde21_cg_regs = { + .set_ofs = 0x200, + .clr_ofs = 0x204, + .sta_ofs = 0x200, +}; + +static const struct mtk_gate_regs vde21_hwv_regs = { + .set_ofs = 0x0080, + .clr_ofs = 0x0084, + .sta_ofs = 0x2c40, +}; + +static const struct mtk_gate_regs vde22_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x8, +}; + +static const struct mtk_gate_regs vde22_hwv_regs = { + .set_ofs = 0x0078, + .clr_ofs = 0x007c, + .sta_ofs = 0x2c3c, +}; + +#define GATE_VDE20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde20_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE20_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde20_cg_regs, \ + .hwv_regs = &vde20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VDE21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde21_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE21_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde21_cg_regs, \ + .hwv_regs = &vde21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VDE22(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde22_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE22_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE22(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde22_cg_regs, \ + .hwv_regs = &vde22_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + } + +static const struct mtk_gate vde2_clks[] = { + /* VDE20 */ + GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN, "vde2_vdec_cken", + "ck2_vdec_ck", 0), + GATE_VDE20_V(CLK_VDE2_VDEC_CKEN_VDEC, "vde2_vdec_cken_vdec", + "vde2_vdec_cken"), + GATE_HWV_VDE20(CLK_VDE2_VDEC_ACTIVE, "vde2_vdec_active", + "ck2_vdec_ck", 4), + GATE_VDE20_V(CLK_VDE2_VDEC_ACTIVE_VDEC, "vde2_vdec_active_vdec", + "vde2_vdec_active"), + GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN_ENG, "vde2_vdec_cken_eng", + "ck2_vdec_ck", 8), + GATE_VDE20_V(CLK_VDE2_VDEC_CKEN_ENG_VDEC, "vde2_vdec_cken_eng_vdec", + "vde2_vdec_cken_eng"), + /* VDE21 */ + GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN, "vde2_lat_cken", + "ck2_vdec_ck", 0), + GATE_VDE21_V(CLK_VDE2_LAT_CKEN_VDEC, "vde2_lat_cken_vdec", + "vde2_lat_cken"), + GATE_HWV_VDE21(CLK_VDE2_LAT_ACTIVE, "vde2_lat_active", + "ck2_vdec_ck", 4), + GATE_VDE21_V(CLK_VDE2_LAT_ACTIVE_VDEC, "vde2_lat_active_vdec", + "vde2_lat_active"), + GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN_ENG, "vde2_lat_cken_eng", + "ck2_vdec_ck", 8), + GATE_VDE21_V(CLK_VDE2_LAT_CKEN_ENG_VDEC, "vde2_lat_cken_eng_vdec", + "vde2_lat_cken_eng"), + /* VDE22 */ + GATE_HWV_VDE22(CLK_VDE2_LARB1_CKEN, "vde2_larb1_cken", + "ck2_vdec_ck", 0), + GATE_VDE22_V(CLK_VDE2_LARB1_CKEN_VDEC, "vde2_larb1_cken_vdec", + "vde2_larb1_cken"), + GATE_VDE22_V(CLK_VDE2_LARB1_CKEN_SMI, "vde2_larb1_cken_smi", + "vde2_larb1_cken"), +}; + +static const struct mtk_clk_desc vde2_mcd = { + .clks = vde2_clks, + .num_clks = ARRAY_SIZE(vde2_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs vde10_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x4, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs vde10_hwv_regs = { + .set_ofs = 0x00a0, + .clr_ofs = 0x00a4, + .sta_ofs = 0x2c50, +}; + +static const struct mtk_gate_regs vde11_cg_regs = { + .set_ofs = 0x1e0, + .clr_ofs = 0x1e0, + .sta_ofs = 0x1e0, +}; + +static const struct mtk_gate_regs vde11_hwv_regs = { + .set_ofs = 0x00b0, + .clr_ofs = 0x00b4, + .sta_ofs = 0x2c58, +}; + +static const struct mtk_gate_regs vde12_cg_regs = { + .set_ofs = 0x1ec, + .clr_ofs = 0x1ec, + .sta_ofs = 0x1ec, +}; + +static const struct mtk_gate_regs vde12_hwv_regs = { + .set_ofs = 0x00a8, + .clr_ofs = 0x00ac, + .sta_ofs = 0x2c54, +}; + +static const struct mtk_gate_regs vde13_cg_regs = { + .set_ofs = 0x200, + .clr_ofs = 0x204, + .sta_ofs = 0x200, +}; + +static const struct mtk_gate_regs vde13_hwv_regs = { + .set_ofs = 0x0098, + .clr_ofs = 0x009c, + .sta_ofs = 0x2c4c, +}; + +static const struct mtk_gate_regs vde14_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x8, +}; + +static const struct mtk_gate_regs vde14_hwv_regs = { + .set_ofs = 0x0090, + .clr_ofs = 0x0094, + .sta_ofs = 0x2c48, +}; + +#define GATE_VDE10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE10_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde10_cg_regs, \ + .hwv_regs = &vde10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VDE11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +#define GATE_VDE11_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde11_cg_regs, \ + .hwv_regs = &vde11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_no_setclr_inv, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VDE12(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde12_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_no_setclr_inv, \ + } + +#define GATE_VDE12_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE12(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde12_cg_regs, \ + .hwv_regs = &vde12_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_no_setclr_inv, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE \ + } + +#define GATE_VDE13(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde13_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE13_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE13(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde13_cg_regs, \ + .hwv_regs = &vde13_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VDE14(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde14_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VDE14_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VDE14(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &vde14_cg_regs, \ + .hwv_regs = &vde14_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + } + +static const struct mtk_gate vde1_clks[] = { + /* VDE10 */ + GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN, "vde1_vdec_cken", + "ck2_vdec_ck", 0), + GATE_VDE10_V(CLK_VDE1_VDEC_CKEN_VDEC, "vde1_vdec_cken_vdec", + "vde1_vdec_cken"), + GATE_HWV_VDE10(CLK_VDE1_VDEC_ACTIVE, "vde1_vdec_active", + "ck2_vdec_ck", 4), + GATE_VDE10_V(CLK_VDE1_VDEC_ACTIVE_VDEC, "vde1_vdec_active_vdec", + "vde1_vdec_active"), + GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN_ENG, "vde1_vdec_cken_eng", + "ck2_vdec_ck", 8), + GATE_VDE10_V(CLK_VDE1_VDEC_CKEN_ENG_VDEC, "vde1_vdec_cken_eng_vdec", + "vde1_vdec_cken_eng"), + /* VDE11 */ + GATE_HWV_VDE11(CLK_VDE1_VDEC_SOC_IPS_EN, "vde1_vdec_soc_ips_en", + "ck2_vdec_ck", 0), + GATE_VDE11_V(CLK_VDE1_VDEC_SOC_IPS_EN_VDEC, "vde1_vdec_soc_ips_en_vdec", + "vde1_vdec_soc_ips_en"), + /* VDE12 */ + GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_EN, "vde1_aptv_en", + "ck2_avs_vdec_ck", 0), + GATE_VDE12_V(CLK_VDE1_VDEC_SOC_APTV_EN_VDEC, "vde1_aptv_en_vdec", + "vde1_aptv_en"), + GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_TOP_EN, "vde1_aptv_topen", + "ck2_avs_vdec_ck", 1), + GATE_VDE12_V(CLK_VDE1_VDEC_SOC_APTV_TOP_EN_VDEC, "vde1_aptv_topen_vdec", + "vde1_aptv_topen"), + /* VDE13 */ + GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN, "vde1_lat_cken", + "ck2_vdec_ck", 0), + GATE_VDE13_V(CLK_VDE1_LAT_CKEN_VDEC, "vde1_lat_cken_vdec", + "vde1_lat_cken"), + GATE_HWV_VDE13(CLK_VDE1_LAT_ACTIVE, "vde1_lat_active", + "ck2_vdec_ck", 4), + GATE_VDE13_V(CLK_VDE1_LAT_ACTIVE_VDEC, "vde1_lat_active_vdec", + "vde1_lat_active"), + GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN_ENG, "vde1_lat_cken_eng", + "ck2_vdec_ck", 8), + GATE_VDE13_V(CLK_VDE1_LAT_CKEN_ENG_VDEC, "vde1_lat_cken_eng_vdec", + "vde1_lat_cken_eng"), + /* VDE14 */ + GATE_HWV_VDE14(CLK_VDE1_LARB1_CKEN, "vde1_larb1_cken", + "ck2_vdec_ck", 0), + GATE_VDE14_V(CLK_VDE1_LARB1_CKEN_VDEC, "vde1_larb1_cken_vdec", + "vde1_larb1_cken"), + GATE_VDE14_V(CLK_VDE1_LARB1_CKEN_SMI, "vde1_larb1_cken_smi", + "vde1_larb1_cken"), +}; + +static const struct mtk_clk_desc vde1_mcd = { + .clks = vde1_clks, + .num_clks = ARRAY_SIZE(vde1_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_vdec[] = { + { .compatible = "mediatek,mt8196-vdecsys", .data = &vde2_mcd, }, + { .compatible = "mediatek,mt8196-vdecsys_soc", .data = &vde1_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_vdec_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-vdec", + .of_match_table = of_match_clk_mt8196_vdec, + }, +}; + +module_platform_driver(clk_mt8196_vdec_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c b/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c new file mode 100644 index 0000000000000..b8d84e7d68186 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs mm_v_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm_v_hwv_regs = { + .set_ofs = 0x0030, + .clr_ofs = 0x0034, + .sta_ofs = 0x2c18, +}; + +#define GATE_MM_V(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm_v_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_MM_V_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_MM_AO_V(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm_v_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr_enable, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_MM_V(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &mm_v_cg_regs, \ + .hwv_regs = &mm_v_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate mm_v_clks[] = { + GATE_HWV_MM_V(CLK_MM_V_DISP_VDISP_AO_CONFIG, "mm_v_disp_vdisp_ao_config", + "ck2_disp_ck", 0), + GATE_MM_V_V(CLK_MM_V_DISP_VDISP_AO_CONFIG_DISP, "mm_v_disp_vdisp_ao_config_disp", + "mm_v_disp_vdisp_ao_config"), + GATE_HWV_MM_V(CLK_MM_V_DISP_DPC, "mm_v_disp_dpc", + "ck2_disp_ck", 16), + GATE_MM_V_V(CLK_MM_V_DISP_DPC_DISP, "mm_v_disp_dpc_disp", + "mm_v_disp_dpc"), + GATE_MM_AO_V(CLK_MM_V_SMI_SUB_SOMM0, "mm_v_smi_sub_somm0", + "ck2_disp_ck", 2), + GATE_MM_V_V(CLK_MM_V_SMI_SUB_SOMM0_SMI, "mm_v_smi_sub_somm0_smi", + "mm_v_smi_sub_somm0"), +}; + +static const struct mtk_clk_desc mm_v_mcd = { + .clks = mm_v_clks, + .num_clks = ARRAY_SIZE(mm_v_clks), +}; + +static const struct platform_device_id clk_mt8196_vdisp_ao_id_table[] = { + { .name = "clk-mt8196-vdisp_ao", .driver_data = (kernel_ulong_t)&mm_v_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_vdisp_ao_id_table); + +static struct platform_driver clk_mt8196_vdisp_ao_drv = { + .probe = mtk_clk_pdev_probe, + .remove_new = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-vdisp_ao", + }, + .id_table = clk_mt8196_vdisp_ao_id_table, +}; + +module_platform_driver(clk_mt8196_vdisp_ao_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-venc.c b/drivers/clk/mediatek/clk-mt8196-venc.c new file mode 100644 index 0000000000000..46fc3bd4b8752 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-venc.c @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include +#include +#include +#include +#include + +static const struct mtk_gate_regs ven10_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs ven10_hwv_regs = { + .set_ofs = 0x00b8, + .clr_ofs = 0x00bc, + .sta_ofs = 0x2c5c, +}; + +static const struct mtk_gate_regs ven11_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x14, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs ven11_hwv_regs = { + .set_ofs = 0x00c0, + .clr_ofs = 0x00c4, + .sta_ofs = 0x2c60, +}; + +#define GATE_VEN10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VEN10_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, _flags) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven10_cg_regs, \ + .hwv_regs = &ven10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = _flags | \ + CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VEN10(_id, _name, _parent, _shift) \ + GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, 0) + +#define GATE_VEN11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_VEN11_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven11_cg_regs, \ + .hwv_regs = &ven11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE \ + } + +static const struct mtk_gate ven1_clks[] = { + /* VEN10 */ + GATE_HWV_VEN10(CLK_VEN1_CKE0_LARB, "ven1_larb", + "ck2_venc_ck", 0), + GATE_VEN10_V(CLK_VEN1_CKE0_LARB_VENC, "ven1_larb_venc", + "ven1_larb"), + GATE_VEN10_V(CLK_VEN1_CKE0_LARB_JPGENC, "ven1_larb_jpgenc", + "ven1_larb"), + GATE_VEN10_V(CLK_VEN1_CKE0_LARB_JPGDEC, "ven1_larb_jpgdec", + "ven1_larb"), + GATE_VEN10_V(CLK_VEN1_CKE0_LARB_SMI, "ven1_larb_smi", + "ven1_larb"), + GATE_HWV_VEN10(CLK_VEN1_CKE1_VENC, "ven1_venc", + "ck2_venc_ck", 4), + GATE_VEN10_V(CLK_VEN1_CKE1_VENC_VENC, "ven1_venc_venc", + "ven1_venc"), + GATE_VEN10_V(CLK_VEN1_CKE1_VENC_SMI, "ven1_venc_smi", + "ven1_venc"), + GATE_VEN10(CLK_VEN1_CKE2_JPGENC, "ven1_jpgenc", + "ck2_venc_ck", 8), + GATE_VEN10_V(CLK_VEN1_CKE2_JPGENC_JPGENC, "ven1_jpgenc_jpgenc", + "ven1_jpgenc"), + GATE_VEN10(CLK_VEN1_CKE3_JPGDEC, "ven1_jpgdec", + "ck2_venc_ck", 12), + GATE_VEN10_V(CLK_VEN1_CKE3_JPGDEC_JPGDEC, "ven1_jpgdec_jpgdec", + "ven1_jpgdec"), + GATE_VEN10(CLK_VEN1_CKE4_JPGDEC_C1, "ven1_jpgdec_c1", + "ck2_venc_ck", 16), + GATE_VEN10_V(CLK_VEN1_CKE4_JPGDEC_C1_JPGDEC, "ven1_jpgdec_c1_jpgdec", + "ven1_jpgdec_c1"), + GATE_HWV_VEN10(CLK_VEN1_CKE5_GALS, "ven1_gals", + "ck2_venc_ck", 28), + GATE_VEN10_V(CLK_VEN1_CKE5_GALS_VENC, "ven1_gals_venc", + "ven1_gals"), + GATE_VEN10_V(CLK_VEN1_CKE5_GALS_JPGENC, "ven1_gals_jpgenc", + "ven1_gals"), + GATE_VEN10_V(CLK_VEN1_CKE5_GALS_JPGDEC, "ven1_gals_jpgdec", + "ven1_gals"), + GATE_HWV_VEN10(CLK_VEN1_CKE29_VENC_ADAB_CTRL, "ven1_venc_adab_ctrl", + "ck2_venc_ck", 29), + GATE_VEN10_V(CLK_VEN1_CKE29_VENC_ADAB_CTRL_VENC, "ven1_venc_adab_ctrl_venc", + "ven1_venc_adab_ctrl"), + GATE_HWV_VEN10_FLAGS(CLK_VEN1_CKE29_VENC_XPC_CTRL, "ven1_venc_xpc_ctrl", + "ck2_venc_ck", 30, CLK_IGNORE_UNUSED), + GATE_VEN10_V(CLK_VEN1_CKE29_VENC_XPC_CTRL_VENC, "ven1_venc_xpc_ctrl_venc", + "ven1_venc_xpc_ctrl"), + GATE_VEN10_V(CLK_VEN1_CKE29_VENC_XPC_CTRL_JPGENC, "ven1_venc_xpc_ctrl_jpgenc", + "ven1_venc_xpc_ctrl"), + GATE_VEN10_V(CLK_VEN1_CKE29_VENC_XPC_CTRL_JPGDEC, "ven1_venc_xpc_ctrl_jpgdec", + "ven1_venc_xpc_ctrl"), + GATE_HWV_VEN10(CLK_VEN1_CKE6_GALS_SRAM, "ven1_gals_sram", + "ck2_venc_ck", 31), + GATE_VEN10_V(CLK_VEN1_CKE6_GALS_SRAM_VENC, "ven1_gals_sram_venc", + "ven1_gals_sram"), + /* VEN11 */ + GATE_HWV_VEN11(CLK_VEN1_RES_FLAT, "ven1_res_flat", + "ck2_venc_ck", 0), + GATE_VEN11_V(CLK_VEN1_RES_FLAT_VENC, "ven1_res_flat_venc", + "ven1_res_flat"), + GATE_VEN11_V(CLK_VEN1_RES_FLAT_JPGENC, "ven1_res_flat_jpgenc", + "ven1_res_flat"), + GATE_VEN11_V(CLK_VEN1_RES_FLAT_JPGDEC, "ven1_res_flat_jpgdec", + "ven1_res_flat"), +}; + +static const struct mtk_clk_desc ven1_mcd = { + .clks = ven1_clks, + .num_clks = ARRAY_SIZE(ven1_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs ven20_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs ven20_hwv_regs = { + .set_ofs = 0x00c8, + .clr_ofs = 0x00cc, + .sta_ofs = 0x2c64, +}; + +static const struct mtk_gate_regs ven21_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x14, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs ven21_hwv_regs = { + .set_ofs = 0x00d0, + .clr_ofs = 0x00d4, + .sta_ofs = 0x2c68, +}; + +#define GATE_VEN20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven20_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VEN20_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven20_cg_regs, \ + .hwv_regs = &ven20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VEN21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven21_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_VEN21_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven21_cg_regs, \ + .hwv_regs = &ven21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE \ + } + +static const struct mtk_gate ven2_clks[] = { + /* VEN20 */ + GATE_HWV_VEN20(CLK_VEN2_CKE0_LARB, "ven2_larb", + "ck2_venc_ck", 0), + GATE_VEN20_V(CLK_VEN2_CKE0_LARB_VENC, "ven2_larb_venc", + "ven2_larb"), + GATE_VEN20_V(CLK_VEN2_CKE0_LARB_JPGENC, "ven2_larb_jpgenc", + "ven2_larb"), + GATE_VEN20_V(CLK_VEN2_CKE0_LARB_JPGDEC, "ven2_larb_jpgdec", + "ven2_larb"), + GATE_VEN20_V(CLK_VEN2_CKE0_LARB_SMI, "ven2_larb_smi", + "ven2_larb"), + GATE_HWV_VEN20(CLK_VEN2_CKE1_VENC, "ven2_venc", + "ck2_venc_ck", 4), + GATE_VEN20_V(CLK_VEN2_CKE1_VENC_VENC, "ven2_venc_venc", + "ven2_venc"), + GATE_VEN20_V(CLK_VEN2_CKE1_VENC_SMI, "ven2_venc_smi", + "ven2_venc"), + GATE_VEN20(CLK_VEN2_CKE2_JPGENC, "ven2_jpgenc", + "ck2_venc_ck", 8), + GATE_VEN20_V(CLK_VEN2_CKE2_JPGENC_JPGENC, "ven2_jpgenc_jpgenc", + "ven2_jpgenc"), + GATE_VEN20(CLK_VEN2_CKE3_JPGDEC, "ven2_jpgdec", + "ck2_venc_ck", 12), + GATE_VEN20_V(CLK_VEN2_CKE3_JPGDEC_JPGDEC, "ven2_jpgdec_jpgdec", + "ven2_jpgdec"), + GATE_HWV_VEN20(CLK_VEN2_CKE5_GALS, "ven2_gals", + "ck2_venc_ck", 28), + GATE_VEN20_V(CLK_VEN2_CKE5_GALS_VENC, "ven2_gals_venc", + "ven2_gals"), + GATE_VEN20_V(CLK_VEN2_CKE5_GALS_JPGENC, "ven2_gals_jpgenc", + "ven2_gals"), + GATE_VEN20_V(CLK_VEN2_CKE5_GALS_JPGDEC, "ven2_gals_jpgdec", + "ven2_gals"), + GATE_HWV_VEN20(CLK_VEN2_CKE29_VENC_XPC_CTRL, "ven2_venc_xpc_ctrl", + "ck2_venc_ck", 30), + GATE_VEN20_V(CLK_VEN2_CKE29_VENC_XPC_CTRL_VENC, "ven2_venc_xpc_ctrl_venc", + "ven2_venc_xpc_ctrl"), + GATE_VEN20_V(CLK_VEN2_CKE29_VENC_XPC_CTRL_JPGENC, "ven2_venc_xpc_ctrl_jpgenc", + "ven2_venc_xpc_ctrl"), + GATE_VEN20_V(CLK_VEN2_CKE29_VENC_XPC_CTRL_JPGDEC, "ven2_venc_xpc_ctrl_jpgdec", + "ven2_venc_xpc_ctrl"), + GATE_HWV_VEN20(CLK_VEN2_CKE6_GALS_SRAM, "ven2_gals_sram", + "ck2_venc_ck", 31), + GATE_VEN20_V(CLK_VEN2_CKE6_GALS_SRAM_VENC, "ven2_gals_sram_venc", + "ven2_gals_sram"), + /* VEN21 */ + GATE_HWV_VEN21(CLK_VEN2_RES_FLAT, "ven2_res_flat", + "ck2_venc_ck", 0), + GATE_VEN21_V(CLK_VEN2_RES_FLAT_VENC, "ven2_res_flat_venc", + "ven2_res_flat"), + GATE_VEN21_V(CLK_VEN2_RES_FLAT_JPGENC, "ven2_res_flat_jpgenc", + "ven2_res_flat"), + GATE_VEN21_V(CLK_VEN2_RES_FLAT_JPGDEC, "ven2_res_flat_jpgdec", + "ven2_res_flat"), +}; + +static const struct mtk_clk_desc ven2_mcd = { + .clks = ven2_clks, + .num_clks = ARRAY_SIZE(ven2_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs ven_c20_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs ven_c20_hwv_regs = { + .set_ofs = 0x00d8, + .clr_ofs = 0x00dc, + .sta_ofs = 0x2c6c, +}; + +static const struct mtk_gate_regs ven_c21_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x14, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs ven_c21_hwv_regs = { + .set_ofs = 0x00e0, + .clr_ofs = 0x00e4, + .sta_ofs = 0x2c70, +}; + +#define GATE_VEN_C20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven_c20_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_VEN_C20_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN_C20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven_c20_cg_regs, \ + .hwv_regs = &ven_c20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv_inv, \ + .dma_ops = &mtk_clk_gate_ops_setclr_inv,\ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_VEN_C21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven_c21_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_VEN_C21_V(_id, _name, _parent) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &cg_regs_dummy, \ + .ops = &mtk_clk_dummy_ops, \ + } + +#define GATE_HWV_VEN_C21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .hwv_comp = "mm-hw-ccf-regmap", \ + .regs = &ven_c21_cg_regs, \ + .hwv_regs = &ven_c21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_hwv, \ + .dma_ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_USE_HW_VOTER | \ + CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ven_c2_clks[] = { + /* VEN_C20 */ + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE0_LARB, "ven_c2_larb", + "ck2_venc_ck", 0), + GATE_VEN_C20_V(CLK_VEN_C2_CKE0_LARB_VENC, "ven_c2_larb_venc", + "ven_c2_larb"), + GATE_VEN_C20_V(CLK_VEN_C2_CKE0_LARB_SMI, "ven_c2_larb_smi", + "ven_c2_larb"), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE1_VENC, "ven_c2_venc", + "ck2_venc_ck", 4), + GATE_VEN_C20_V(CLK_VEN_C2_CKE1_VENC_VENC, "ven_c2_venc_venc", + "ven_c2_venc"), + GATE_VEN_C20_V(CLK_VEN_C2_CKE1_VENC_SMI, "ven_c2_venc_smi", + "ven_c2_venc"), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE5_GALS, "ven_c2_gals", + "ck2_venc_ck", 28), + GATE_VEN_C20_V(CLK_VEN_C2_CKE5_GALS_VENC, "ven_c2_gals_venc", + "ven_c2_gals"), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE29_VENC_XPC_CTRL, "ven_c2_venc_xpc_ctrl", + "ck2_venc_ck", 30), + GATE_VEN_C20_V(CLK_VEN_C2_CKE29_VENC_XPC_CTRL_VENC, "ven_c2_venc_xpc_ctrl_venc", + "ven_c2_venc_xpc_ctrl"), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE6_GALS_SRAM, "ven_c2_gals_sram", + "ck2_venc_ck", 31), + GATE_VEN_C20_V(CLK_VEN_C2_CKE6_GALS_SRAM_VENC, "ven_c2_gals_sram_venc", + "ven_c2_gals_sram"), + /* VEN_C21 */ + GATE_HWV_VEN_C21(CLK_VEN_C2_RES_FLAT, "ven_c2_res_flat", + "ck2_venc_ck", 0), + GATE_VEN_C21_V(CLK_VEN_C2_RES_FLAT_VENC, "ven_c2_res_flat_venc", + "ven_c2_res_flat"), +}; + +static const struct mtk_clk_desc ven_c2_mcd = { + .clks = ven_c2_clks, + .num_clks = ARRAY_SIZE(ven_c2_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_venc[] = { + { .compatible = "mediatek,mt8196-vencsys", .data = &ven1_mcd, }, + { .compatible = "mediatek,mt8196-vencsys_c1", .data = &ven2_mcd, }, + { .compatible = "mediatek,mt8196-vencsys_c2", .data = &ven_c2_mcd, }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_venc_drv = { + .probe = mtk_clk_simple_probe, + .remove_new = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-venc", + .of_match_table = of_match_clk_mt8196_venc, + }, +}; + +module_platform_driver(clk_mt8196_venc_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c new file mode 100644 index 0000000000000..b044ef29f0eb0 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c @@ -0,0 +1,786 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ +#include "clk-mtk.h" +#include "clk-mux.h" +#include "clk-pll.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* MUX SEL REG */ +#define VLP_CLK_CFG_UPDATE 0x0004 +#define VLP_CLK_CFG_UPDATE1 0x0008 +#define VLP_CLK_CFG_0 0x0010 +#define VLP_CLK_CFG_0_SET 0x0014 +#define VLP_CLK_CFG_0_CLR 0x0018 +#define VLP_CLK_CFG_1 0x0020 +#define VLP_CLK_CFG_1_SET 0x0024 +#define VLP_CLK_CFG_1_CLR 0x0028 +#define VLP_CLK_CFG_2 0x0030 +#define VLP_CLK_CFG_2_SET 0x0034 +#define VLP_CLK_CFG_2_CLR 0x0038 +#define VLP_CLK_CFG_3 0x0040 +#define VLP_CLK_CFG_3_SET 0x0044 +#define VLP_CLK_CFG_3_CLR 0x0048 +#define VLP_CLK_CFG_4 0x0050 +#define VLP_CLK_CFG_4_SET 0x0054 +#define VLP_CLK_CFG_4_CLR 0x0058 +#define VLP_CLK_CFG_5 0x0060 +#define VLP_CLK_CFG_5_SET 0x0064 +#define VLP_CLK_CFG_5_CLR 0x0068 +#define VLP_CLK_CFG_6 0x0070 +#define VLP_CLK_CFG_6_SET 0x0074 +#define VLP_CLK_CFG_6_CLR 0x0078 +#define VLP_CLK_CFG_7 0x0080 +#define VLP_CLK_CFG_7_SET 0x0084 +#define VLP_CLK_CFG_7_CLR 0x0088 +#define VLP_CLK_CFG_8 0x0090 +#define VLP_CLK_CFG_8_SET 0x0094 +#define VLP_CLK_CFG_8_CLR 0x0098 +#define VLP_CLK_CFG_9 0x00a0 +#define VLP_CLK_CFG_9_SET 0x00a4 +#define VLP_CLK_CFG_9_CLR 0x00a8 +#define VLP_CLK_CFG_10 0x00b0 +#define VLP_CLK_CFG_10_SET 0x00b4 +#define VLP_CLK_CFG_10_CLR 0x00b8 +#define VLP_OCIC_FENC_STATUS_MON_0 0x039c +#define VLP_OCIC_FENC_STATUS_MON_1 0x03a0 + +/* MUX SHIFT */ +#define TOP_MUX_SCP_SHIFT 0 +#define TOP_MUX_SCP_SPI_SHIFT 1 +#define TOP_MUX_SCP_IIC_SHIFT 2 +#define TOP_MUX_SCP_IIC_HIGH_SPD_SHIFT 3 +#define TOP_MUX_PWRAP_ULPOSC_SHIFT 4 +#define TOP_MUX_SPMI_M_TIA_32K_SHIFT 5 +#define TOP_MUX_APXGPT_26M_BCLK_SHIFT 6 +#define TOP_MUX_DPSW_SHIFT 7 +#define TOP_MUX_DPSW_CENTRAL_SHIFT 8 +#define TOP_MUX_SPMI_M_MST_SHIFT 9 +#define TOP_MUX_DVFSRC_SHIFT 10 +#define TOP_MUX_PWM_VLP_SHIFT 11 +#define TOP_MUX_AXI_VLP_SHIFT 12 +#define TOP_MUX_SYSTIMER_26M_SHIFT 13 +#define TOP_MUX_SSPM_SHIFT 14 +#define TOP_MUX_SRCK_SHIFT 15 +#define TOP_MUX_CAMTG0_SHIFT 16 +#define TOP_MUX_CAMTG1_SHIFT 17 +#define TOP_MUX_CAMTG2_SHIFT 18 +#define TOP_MUX_CAMTG3_SHIFT 19 +#define TOP_MUX_CAMTG4_SHIFT 20 +#define TOP_MUX_CAMTG5_SHIFT 21 +#define TOP_MUX_CAMTG6_SHIFT 22 +#define TOP_MUX_CAMTG7_SHIFT 23 +#define TOP_MUX_SSPM_26M_SHIFT 25 +#define TOP_MUX_ULPOSC_SSPM_SHIFT 26 +#define TOP_MUX_VLP_PBUS_26M_SHIFT 27 +#define TOP_MUX_DEBUG_ERR_FLAG_VLP_26M_SHIFT 28 +#define TOP_MUX_DPMSRDMA_SHIFT 29 +#define TOP_MUX_VLP_PBUS_156M_SHIFT 30 +#define TOP_MUX_SPM_SHIFT 0 +#define TOP_MUX_MMINFRA_VLP_SHIFT 1 +#define TOP_MUX_USB_TOP_SHIFT 2 +#define TOP_MUX_SSUSB_XHCI_SHIFT 3 +#define TOP_MUX_NOC_VLP_SHIFT 4 +#define TOP_MUX_AUDIO_H_SHIFT 5 +#define TOP_MUX_AUD_ENGEN1_SHIFT 6 +#define TOP_MUX_AUD_ENGEN2_SHIFT 7 +#define TOP_MUX_AUD_INTBUS_SHIFT 8 +#define TOP_MUX_SPU_VLP_26M_SHIFT 9 +#define TOP_MUX_SPU0_VLP_SHIFT 10 +#define TOP_MUX_SPU1_VLP_SHIFT 11 + +/* CKSTA REG */ +#define VLP_CKSTA_REG0 0x0250 +#define VLP_CKSTA_REG1 0x0254 + +/* HW Voter REG */ +#define HWV_CG_9_SET 0x0048 +#define HWV_CG_9_CLR 0x004c +#define HWV_CG_9_DONE 0x2c24 +#define HWV_CG_10_SET 0x0050 +#define HWV_CG_10_CLR 0x0054 +#define HWV_CG_10_DONE 0x2c28 + +/* PLL REG */ +#define VLP_AP_PLL_CON3 0x264 +#define VLP_APLL1_TUNER_CON0 0x2a4 +#define VLP_APLL2_TUNER_CON0 0x2a8 +#define VLP_APLL1_CON0 0x274 +#define VLP_APLL1_CON1 0x278 +#define VLP_APLL1_CON2 0x27c +#define VLP_APLL1_CON3 0x280 +#define VLP_APLL2_CON0 0x28c +#define VLP_APLL2_CON1 0x290 +#define VLP_APLL2_CON2 0x294 +#define VLP_APLL2_CON3 0x298 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL_FENC(_id, _name, _reg, _fenc_sta_ofs, _fenc_sta_bit,\ + _flags, _pd_reg, _pd_shift, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .fenc_sta_ofs = _fenc_sta_ofs, \ + .fenc_sta_bit = _fenc_sta_bit, \ + .flags = (_flags | CLK_FENC_ENABLE), \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static DEFINE_SPINLOCK(mt8196_clk_vlp_ck_lock); + +static const struct mtk_fixed_factor vlp_ck_divs[] = { + FACTOR(CLK_VLP_CK_OSC3, "vlp_osc3", + "ulposc3", 1, 1), + FACTOR(CLK_VLP_CK_CLKSQ, "vlp_clksq_ck", + "clk26m", 1, 1), + FACTOR(CLK_VLP_CK_AUDIO_H, "vlp_audio_h_ck", + "vlp_audio_h_sel", 1, 1), + FACTOR(CLK_VLP_CK_AUD_ENGEN1, "vlp_aud_engen1_ck", + "vlp_aud_engen1_sel", 1, 1), + FACTOR(CLK_VLP_CK_AUD_ENGEN2, "vlp_aud_engen2_ck", + "vlp_aud_engen2_sel", 1, 1), + FACTOR(CLK_VLP_CK_INFRA_26M, "vlp_infra_26m_ck", + "ck_tck_26m_mx9_ck", 1, 1), + FACTOR(CLK_VLP_CK_AUD_CLKSQ, "vlp_aud_clksq_ck", + "vlp_clksq_ck", 1, 1), +}; + +static const char * const vlp_scp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d6", + "ck_mainpll_d4", + "ck_mainpll_d3", + "ck_apll1_ck" +}; + +static const char * const vlp_scp_spi_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d7_d2", + "ck_mainpll_d5_d2" +}; + +static const char * const vlp_scp_iic_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d5_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const vlp_scp_iic_hs_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d5_d4", + "ck_mainpll_d7_d2", + "ck_mainpll_d7" +}; + +static const char * const vlp_pwrap_ulposc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_osc_d14", + "ck_osc_d10" +}; + +static const char * const vlp_spmi_32ksel_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_clkrtc", + "ck_osc_d20", + "ck_osc_d14", + "ck_osc_d10" +}; + +static const char * const vlp_apxgpt_26m_b_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_dpsw_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d7", + "ck_mainpll_d7_d4" +}; + +static const char * const vlp_dpsw_central_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d10", + "ck_osc_d7", + "ck_mainpll_d7_d4" +}; + +static const char * const vlp_spmi_m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_osc_d14", + "ck_osc_d10" +}; + +static const char * const vlp_dvfsrc_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_pwm_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_clkrtc", + "ck_osc_d20", + "ck_osc_d8", + "ck_mainpll_d4_d8" +}; + +static const char * const vlp_axi_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d7_d4", + "ck_osc_d4", + "ck_mainpll_d7_d2" +}; + +static const char * const vlp_systimer_26m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_sspm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d5_d2", + "ck_osc_d2", + "ck_mainpll_d6" +}; + +static const char * const vlp_srck_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_camtg0_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc3", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg1_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc3", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg2_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg3_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg4_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg5_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg6_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_camtg7_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_univpll_192m_d32", + "ck_univpll_192m_d16", + "ck_f26m_d2", + "ck_osc_d40", + "ck_osc_d32", + "ck_univpll_192m_d10", + "ck_univpll_192m_d8", + "ck_univpll_d6_d16", + "ck_osc_d20", + "ck2_tvdpll1_d16", + "ck_univpll_d6_d8" +}; + +static const char * const vlp_sspm_26m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_ulposc_sspm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d2", + "ck_mainpll_d4_d2" +}; + +static const char * const vlp_vlp_pbus_26m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_debug_err_flag_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_dpmsrdma_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d2" +}; + +static const char * const vlp_vlp_pbus_156m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d2", + "ck_mainpll_d7_d2", + "ck_mainpll_d7" +}; + +static const char * const vlp_spm_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d7_d4" +}; + +static const char * const vlp_mminfra_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d4", + "ck_mainpll_d3" +}; + +static const char * const vlp_usb_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d9" +}; + +static const char * const vlp_usb_xhci_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_mainpll_d9" +}; + +static const char * const vlp_noc_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d9" +}; + +static const char * const vlp_audio_h_parents[] = { + "ck_tck_26m_mx9_ck", + "vlp_clksq_ck", + "ck_apll1_ck", + "ck_apll2_ck" +}; + +static const char * const vlp_aud_engen1_parents[] = { + "ck_tck_26m_mx9_ck", + "vlp_clksq_ck", + "ck_apll1_d8", + "ck_apll1_d4" +}; + +static const char * const vlp_aud_engen2_parents[] = { + "ck_tck_26m_mx9_ck", + "vlp_clksq_ck", + "ck_apll2_d8", + "ck_apll2_d4" +}; + +static const char * const vlp_aud_intbus_parents[] = { + "ck_tck_26m_mx9_ck", + "vlp_clksq_ck", + "ck_mainpll_d7_d4", + "ck_mainpll_d4_d4" +}; + +static const char * const vlp_spvlp_26m_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20" +}; + +static const char * const vlp_spu0_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const char * const vlp_spu1_vlp_parents[] = { + "ck_tck_26m_mx9_ck", + "ck_osc_d20", + "ck_mainpll_d4_d4", + "ck_mainpll_d4_d2", + "ck_mainpll_d7", + "ck_mainpll_d6", + "ck_mainpll_d5" +}; + +static const struct mtk_mux vlp_ck_muxes[] = { + /* VLP_CLK_CFG_0 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_SCP_SEL, "vlp_scp_sel", vlp_scp_parents, + VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, VLP_CLK_CFG_0_CLR, + 0, 3, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 31), + MUX_CLR_SET_UPD(CLK_VLP_CK_SCP_SPI_SEL, "vlp_scp_spi_sel", + vlp_scp_spi_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 8, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_SPI_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SCP_IIC_SEL, "vlp_scp_iic_sel", + vlp_scp_iic_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_IIC_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL, "vlp_scp_iic_hs_sel", + vlp_scp_iic_hs_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 24, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_IIC_HIGH_SPD_SHIFT), + /* VLP_CLK_CFG_1 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_PWRAP_ULPOSC_SEL, "vlp_pwrap_ulposc_sel", + vlp_pwrap_ulposc_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 0, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_PWRAP_ULPOSC_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SPMI_M_TIA_32K_SEL, "vlp_spmi_32ksel", + vlp_spmi_32ksel_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 8, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SPMI_M_TIA_32K_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_APXGPT_26M_BCLK_SEL, "vlp_apxgpt_26m_b_sel", + vlp_apxgpt_26m_b_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 16, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_APXGPT_26M_BCLK_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_DPSW_SEL, "vlp_dpsw_sel", + vlp_dpsw_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 24, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPSW_SHIFT), + /* VLP_CLK_CFG_2 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_DPSW_CENTRAL_SEL, "vlp_dpsw_central_sel", + vlp_dpsw_central_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 0, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPSW_CENTRAL_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SPMI_M_MST_SEL, "vlp_spmi_m_sel", + vlp_spmi_m_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 8, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SPMI_M_MST_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_DVFSRC_SEL, "vlp_dvfsrc_sel", + vlp_dvfsrc_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 16, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DVFSRC_SHIFT), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_PWM_VLP_SEL, "vlp_pwm_vlp_sel", vlp_pwm_vlp_parents, + VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, VLP_CLK_CFG_2_CLR, + 24, 3, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_PWM_VLP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 20), + /* VLP_CLK_CFG_3 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_AXI_VLP_SEL, "vlp_axi_vlp_sel", + vlp_axi_vlp_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 0, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_AXI_VLP_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SYSTIMER_26M_SEL, "vlp_systimer_26m_sel", + vlp_systimer_26m_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SYSTIMER_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SSPM_SEL, "vlp_sspm_sel", + vlp_sspm_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 16, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SSPM_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SRCK_SEL, "vlp_srck_sel", + vlp_srck_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 24, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SRCK_SHIFT), + /* VLP_CLK_CFG_4 */ + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG0_SEL, "vlp_camtg0_sel", vlp_camtg0_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, "hw-voter-regmap", + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 0, 4, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG0_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 15), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG1_SEL, "vlp_camtg1_sel", vlp_camtg1_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, "hw-voter-regmap", + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 8, 4, 15, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG1_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 14), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG2_SEL, "vlp_camtg2_sel", vlp_camtg2_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, "hw-voter-regmap", + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 16, 4, 23, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG2_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 13), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG3_SEL, "vlp_camtg3_sel", vlp_camtg3_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, "hw-voter-regmap", + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 24, 4, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG3_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 12), + /* VLP_CLK_CFG_5 */ + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG4_SEL, "vlp_camtg4_sel", vlp_camtg4_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, "hw-voter-regmap", + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 0, 4, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG4_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 11), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG5_SEL, "vlp_camtg5_sel", vlp_camtg5_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, "hw-voter-regmap", + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 8, 4, 15, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG5_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 10), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG6_SEL, "vlp_camtg6_sel", vlp_camtg6_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, "hw-voter-regmap", + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 16, 4, 23, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG6_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 9), + MUX_MULT_HWV_FENC(CLK_VLP_CK_CAMTG7_SEL, "vlp_camtg7_sel", vlp_camtg7_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, "hw-voter-regmap", + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 24, 4, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG7_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 8), + /* VLP_CLK_CFG_6 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_SSPM_26M_SEL, "vlp_sspm_26m_sel", + vlp_sspm_26m_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SSPM_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_ULPOSC_SSPM_SEL, "vlp_ulposc_sspm_sel", + vlp_ulposc_sspm_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_ULPOSC_SSPM_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_VLP_PBUS_26M_SEL, "vlp_vlp_pbus_26m_sel", + vlp_vlp_pbus_26m_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 24, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_VLP_PBUS_26M_SHIFT), + /* VLP_CLK_CFG_7 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_DEBUG_ERR_FLAG_SEL, "vlp_debug_err_flag_sel", + vlp_debug_err_flag_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 0, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DEBUG_ERR_FLAG_VLP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_DPMSRDMA_SEL, "vlp_dpmsrdma_sel", + vlp_dpmsrdma_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPMSRDMA_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_VLP_PBUS_156M_SEL, "vlp_vlp_pbus_156m_sel", + vlp_vlp_pbus_156m_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_VLP_PBUS_156M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SPM_SEL, "vlp_spm_sel", + vlp_spm_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 24, 1, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPM_SHIFT), + /* VLP_CLK_CFG_8 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_MMINFRA_VLP_SEL, "vlp_mminfra_vlp_sel", vlp_mminfra_vlp_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 0, 2, 7, VLP_CLK_CFG_UPDATE1, TOP_MUX_MMINFRA_VLP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 31), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_USB_TOP_SEL, "vlp_usb_sel", vlp_usb_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 8, 1, 15, VLP_CLK_CFG_UPDATE1, TOP_MUX_USB_TOP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 30), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_USB_XHCI_SEL, "vlp_usb_xhci_sel", vlp_usb_xhci_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 16, 1, 23, VLP_CLK_CFG_UPDATE1, TOP_MUX_SSUSB_XHCI_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 29), + MUX_CLR_SET_UPD(CLK_VLP_CK_NOC_VLP_SEL, "vlp_noc_vlp_sel", + vlp_noc_vlp_parents, VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, + VLP_CLK_CFG_8_CLR, 24, 2, + VLP_CLK_CFG_UPDATE1, TOP_MUX_NOC_VLP_SHIFT), + /* VLP_CLK_CFG_9 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_AUDIO_H_SEL, "vlp_audio_h_sel", vlp_audio_h_parents, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 0, 2, 7, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUDIO_H_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 27), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_AUD_ENGEN1_SEL, "vlp_aud_engen1_sel", vlp_aud_engen1_parents, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 8, 2, 15, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_ENGEN1_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 26), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_AUD_ENGEN2_SEL, "vlp_aud_engen2_sel", vlp_aud_engen2_parents, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 16, 2, 23, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_ENGEN2_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 25), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_CK_AUD_INTBUS_SEL, "vlp_aud_intbus_sel", vlp_aud_intbus_parents, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 24, 2, 31, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_INTBUS_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 24), + /* VLP_CLK_CFG_10 */ + MUX_CLR_SET_UPD(CLK_VLP_CK_SPVLP_26M_SEL, "vlp_spvlp_26m_sel", + vlp_spvlp_26m_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 0, 1, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU_VLP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SPU0_VLP_SEL, "vlp_spu0_vlp_sel", + vlp_spu0_vlp_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 8, 3, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU0_VLP_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_CK_SPU1_VLP_SEL, "vlp_spu1_vlp_sel", + vlp_spu1_vlp_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 16, 3, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU1_VLP_SHIFT), +}; + +static const struct mtk_pll_data vlp_ck_plls[] = { + PLL_FENC(CLK_VLP_CK_VLP_APLL1, "vlp_apll1", VLP_APLL1_CON0, + 0x0358, 1, 0, + VLP_APLL1_CON1, 24, + VLP_APLL1_CON2, 0, 32), + PLL_FENC(CLK_VLP_CK_VLP_APLL2, "vlp_apll2", VLP_APLL2_CON0, + 0x0358, 0, 0, + VLP_APLL2_CON1, 24, + VLP_APLL2_CON2, 0, 32), +}; + +static int clk_mt8196_vlp_ck_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_VLP_CK_NR_CLK); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_factors(vlp_ck_divs, ARRAY_SIZE(vlp_ck_divs), clk_data); + if (r) + goto free_clk_data; + + r = mtk_clk_register_muxes(&pdev->dev, vlp_ck_muxes, ARRAY_SIZE(vlp_ck_muxes), node, + &mt8196_clk_vlp_ck_lock, clk_data); + if (r) + goto unregister_factors; + + r = mtk_clk_register_plls(node, vlp_ck_plls, ARRAY_SIZE(vlp_ck_plls), clk_data); + if (r) + goto unregister_muxes; + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + goto unregister_plls; + + return 0; + +unregister_plls: + mtk_clk_unregister_plls(vlp_ck_plls, ARRAY_SIZE(vlp_ck_plls), clk_data); +unregister_muxes: + mtk_clk_unregister_muxes(vlp_ck_muxes, ARRAY_SIZE(vlp_ck_muxes), clk_data); +unregister_factors: + mtk_clk_unregister_factors(vlp_ck_divs, ARRAY_SIZE(vlp_ck_divs), clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); + + return r; +} + +static void clk_mt8196_vlp_ck_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(vlp_ck_plls, ARRAY_SIZE(vlp_ck_plls), clk_data); + mtk_clk_unregister_muxes(vlp_ck_muxes, ARRAY_SIZE(vlp_ck_muxes), clk_data); + mtk_clk_unregister_factors(vlp_ck_divs, ARRAY_SIZE(vlp_ck_divs), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_vlp_ck[] = { + { .compatible = "mediatek,mt8196-vlp_cksys", }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt8196_vlp_ck_drv = { + .probe = clk_mt8196_vlp_ck_probe, + .remove_new = clk_mt8196_vlp_ck_remove, + .driver = { + .name = "clk-mt8196-vlp_ck", + .owner = THIS_MODULE, + .of_match_table = of_match_clk_mt8196_vlp_ck, + }, +}; + +module_platform_driver(clk_mt8196_vlp_ck_drv); +MODULE_LICENSE("GPL"); -- GitLab From 8fbb5225739855cb83c9a9661af26cf825b332dd Mon Sep 17 00:00:00 2001 From: Guangjie Song Date: Thu, 15 Aug 2024 20:14:18 +0800 Subject: [PATCH 350/456] CHROMIUM: pmdomain: mediatek: add mt8196 power domain driver add mt8196 power domain driver BUG=b:383207709 BUG=b:377628718 BUG=b:383207709 BUG=b:376503067 TEST=Build pass and boot to shell UPSTREAM-TASK=b:379034565 Signed-off-by: Guangjie Song Change-Id: Ic61bcd9d4dff4c29055b05be944b57fcc9d93b39 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073992 Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pmdomain/mediatek/mt8196-scpsys.h | 112 ++ drivers/pmdomain/mediatek/mtk-scpsys.c | 1229 ++++++++++++++++++++- 2 files changed, 1301 insertions(+), 40 deletions(-) create mode 100644 drivers/pmdomain/mediatek/mt8196-scpsys.h diff --git a/drivers/pmdomain/mediatek/mt8196-scpsys.h b/drivers/pmdomain/mediatek/mt8196-scpsys.h new file mode 100644 index 0000000000000..0004e9352ed82 --- /dev/null +++ b/drivers/pmdomain/mediatek/mt8196-scpsys.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Guangjie Song + */ +#ifndef __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H +#define __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H + +#define MT8196_SPM_CONN_PWR_CON 0xe04 +#define MT8196_SPM_SSUSB_DP_PHY_P0_PWR_CON 0xe18 +#define MT8196_SPM_SSUSB_P0_PWR_CON 0xe1c +#define MT8196_SPM_SSUSB_P1_PWR_CON 0xe20 +#define MT8196_SPM_SSUSB_P23_PWR_CON 0xe24 +#define MT8196_SPM_SSUSB_PHY_P2_PWR_CON 0xe28 +#define MT8196_SPM_PEXTP_MAC0_PWR_CON 0xe34 +#define MT8196_SPM_PEXTP_MAC1_PWR_CON 0xe38 +#define MT8196_SPM_PEXTP_MAC2_PWR_CON 0xe3c +#define MT8196_SPM_PEXTP_PHY0_PWR_CON 0xe40 +#define MT8196_SPM_PEXTP_PHY1_PWR_CON 0xe44 +#define MT8196_SPM_PEXTP_PHY2_PWR_CON 0xe48 +#define MT8196_SPM_AUDIO_PWR_CON 0xe4c +#define MT8196_SPM_ADSP_TOP_PWR_CON 0xe54 +#define MT8196_SPM_ADSP_INFRA_PWR_CON 0xe58 +#define MT8196_SPM_ADSP_AO_PWR_CON 0xe5c +#define MT8196_SPM_PWR_STATUS 0xf14 +#define MT8196_SPM_PWR_STATUS_2ND 0xf18 + +#define MT8196_SPM_BUS_PROTECT_EN 0xd8 +#define MT8196_SPM_BUS_PROTECT_EN_SET 0xdc +#define MT8196_SPM_BUS_PROTECT_EN_CLR 0xe0 +#define MT8196_SPM_BUS_PROTECT_RDY 0x208 + +#define MT8196_MM_PWR_STATUS 0x100 +#define MT8196_MM_PWR_STATUS_2ND 0x104 + +#define MT8196_VOTE_MTCMOS_SET0 0x218 +#define MT8196_VOTE_MTCMOS_CLR0 0x21c +#define MT8196_VOTE_MTCMOS_ENABLE0 0x1410 +#define MT8196_VOTE_MTCMOS_DONE0 0x141c +#define MT8196_VOTE_MTCMOS_SET_STATUS0 0x146c +#define MT8196_VOTE_MTCMOS_CLR_STATUS0 0x1470 + +#define MT8196_MM_VOTE_MTCMOS_SET0 0x218 +#define MT8196_MM_VOTE_MTCMOS_CLR0 0x21c +#define MT8196_MM_VOTE_MTCMOS_SET1 0x220 +#define MT8196_MM_VOTE_MTCMOS_CLR1 0x224 +#define MT8196_MM_VOTE_MTCMOS_ENABLE0 0x1410 +#define MT8196_MM_VOTE_MTCMOS_DONE0 0x141c +#define MT8196_MM_VOTE_MTCMOS_ENABLE1 0x1420 +#define MT8196_MM_VOTE_MTCMOS_DONE1 0x142c +#define MT8196_MM_VOTE_MTCMOS_SET_STATUS0 0x146c +#define MT8196_MM_VOTE_MTCMOS_CLR_STATUS0 0x1470 +#define MT8196_MM_VOTE_MTCMOS_SET_STATUS1 0x1474 +#define MT8196_MM_VOTE_MTCMOS_CLR_STATUS1 0x1478 + +#define MT8196_SPM_PROT_EN_BUS_CONN BIT(1) +#define MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0 BIT(6) +#define MT8196_SPM_PROT_EN_BUS_SSUSB_P0 BIT(7) +#define MT8196_SPM_PROT_EN_BUS_SSUSB_P1 BIT(8) +#define MT8196_SPM_PROT_EN_BUS_SSUSB_P23 BIT(9) +#define MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2 BIT(10) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0 BIT(13) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1 BIT(14) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2 BIT(15) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0 BIT(16) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1 BIT(17) +#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2 BIT(18) +#define MT8196_SPM_PROT_EN_BUS_AUDIO BIT(19) +#define MT8196_SPM_PROT_EN_BUS_ADSP_TOP BIT(21) +#define MT8196_SPM_PROT_EN_BUS_ADSP_INFRA BIT(22) +#define MT8196_SPM_PROT_EN_BUS_ADSP_AO BIT(23) + +#define MT8196_VOTE_MM_PROC_SHIFT 0 +#define MT8196_VOTE_SSR_SHIFT 1 + +#define MT8196_MM_VOTE_VDE0_SHIFT 7 +#define MT8196_MM_VOTE_VDE1_SHIFT 8 +#define MT8196_MM_VOTE_VDE_VCORE0_SHIFT 9 +#define MT8196_MM_VOTE_VEN0_SHIFT 10 +#define MT8196_MM_VOTE_VEN1_SHIFT 11 +#define MT8196_MM_VOTE_VEN2_SHIFT 12 +#define MT8196_MM_VOTE_DISP_VCORE_SHIFT 24 +#define MT8196_MM_VOTE_DIS0_SHIFT 25 +#define MT8196_MM_VOTE_DIS1_SHIFT 26 +#define MT8196_MM_VOTE_OVL0_SHIFT 27 +#define MT8196_MM_VOTE_OVL1_SHIFT 28 +#define MT8196_MM_VOTE_DISP_EDPTX_SHIFT 29 +#define MT8196_MM_VOTE_DISP_DPTX_SHIFT 30 +#define MT8196_MM_VOTE_MML0_SHIFT 31 +#define MT8196_MM_VOTE_MML1_SHIFT 0 +#define MT8196_MM_VOTE_MM_INFRA0_SHIFT 1 +#define MT8196_MM_VOTE_MM_INFRA1_SHIFT 2 +#define MT8196_MM_VOTE_MM_INFRA_AO_SHIFT 3 +#define MT8196_MM_VOTE_CSI_BS_RX_SHIFT 5 +#define MT8196_MM_VOTE_CSI_LS_RX_SHIFT 6 +#define MT8196_MM_VOTE_DSI_PHY0_SHIFT 7 +#define MT8196_MM_VOTE_DSI_PHY1_SHIFT 8 +#define MT8196_MM_VOTE_DSI_PHY2_SHIFT 9 + +enum { + MT8196_SPM_BP_INVALID = 0, + MT8196_SPM_BP_SPM, + MT8196_SPM_BP_NR +}; + +enum { + MT8196_MMPC_BP_INVALID = 0, + MT8196_MMPC_BP_MMPC, + MT8196_MMPC_BP_NR, +}; + +#endif /* __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H */ diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c index b374d01fdac71..ebfb98f80b4d6 100644 --- a/drivers/pmdomain/mediatek/mtk-scpsys.c +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -19,12 +20,35 @@ #include #include #include +#include -#define MTK_POLL_DELAY_US 10 -#define MTK_POLL_TIMEOUT USEC_PER_SEC +#include "mt8196-scpsys.h" + +#define MTK_POLL_DELAY_US 10 +#define MTK_POLL_TIMEOUT USEC_PER_SEC +#define MTK_POLL_TIMEOUT_300MS (300 * USEC_PER_MSEC) +#define MTK_POLL_IRQ_TIMEOUT USEC_PER_SEC +#define MTK_POLL_HWV_PREPARE_CNT 2500 +#define MTK_POLL_HWV_PREPARE_US 2 +#define MTK_ACK_DELAY_US 50 +#define MTK_RTFF_DELAY_US 10 +#define MTK_STABLE_DELAY_US 100 + +#define MTK_BUS_PROTECTION_RETY_TIMES 10 #define MTK_SCPD_ACTIVE_WAKEUP BIT(0) #define MTK_SCPD_FWAIT_SRAM BIT(1) +#define MTK_SCPD_SRAM_ISO BIT(2) +#define MTK_SCPD_SRAM_SLP BIT(3) +#define MTK_SCPD_BYPASS_INIT_ON BIT(4) +#define MTK_SCPD_IS_PWR_CON_ON BIT(5) +#define MTK_SCPD_HWV_OPS BIT(6) +#define MTK_SCPD_NON_CPU_RTFF BIT(7) +#define MTK_SCPD_PEXTP_PHY_RTFF BIT(8) +#define MTK_SCPD_UFS_RTFF BIT(9) +#define MTK_SCPD_RTFF_DELAY BIT(10) +#define MTK_SCPD_IRQ_SAVE BIT(11) +#define MTK_SCPD_ALWAYS_ON BIT(12) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) #define SPM_VDE_PWR_CON 0x0210 @@ -56,6 +80,15 @@ #define PWR_ON_BIT BIT(2) #define PWR_ON_2ND_BIT BIT(3) #define PWR_CLK_DIS_BIT BIT(4) +#define PWR_SRAM_CLKISO_BIT BIT(5) +#define PWR_SRAM_ISOINT_B_BIT BIT(6) +#define PWR_RTFF_SAVE BIT(24) +#define PWR_RTFF_NRESTORE BIT(25) +#define PWR_RTFF_CLK_DIS BIT(26) +#define PWR_RTFF_SAVE_FLAG BIT(27) +#define PWR_RTFF_UFS_CLK_DIS BIT(28) +#define PWR_ACK BIT(30) +#define PWR_ACK_2ND BIT(31) #define PWR_STATUS_CONN BIT(1) #define PWR_STATUS_DISP BIT(3) @@ -78,6 +111,24 @@ #define PWR_STATUS_HIF1 BIT(26) /* MT7622 */ #define PWR_STATUS_WB BIT(27) /* MT7622 */ +#define _BUS_PROT(_type, _set_ofs, _clr_ofs, \ + _en_ofs, _sta_ofs, _mask, _ack_mask, \ + _ignore_clr_ack) { \ + .type = _type, \ + .set_ofs = _set_ofs, \ + .clr_ofs = _clr_ofs, \ + .en_ofs = _en_ofs, \ + .sta_ofs = _sta_ofs, \ + .mask = _mask, \ + .ack_mask = _ack_mask, \ + .ignore_clr_ack = _ignore_clr_ack, \ + } + +#define BUS_PROT_IGN(_type, _set_ofs, _clr_ofs, \ + _en_ofs, _sta_ofs, _mask) \ + _BUS_PROT(_type, _set_ofs, _clr_ofs, \ + _en_ofs, _sta_ofs, _mask, _mask, true) + enum clk_id { CLK_NONE, CLK_MM, @@ -107,6 +158,18 @@ static const char * const clk_names[] = { }; #define MAX_CLKS 3 +#define MAX_STEPS 3 + +struct bus_prot { + u32 type; + u32 set_ofs; + u32 clr_ofs; + u32 en_ofs; + u32 sta_ofs; + u32 mask; + u32 ack_mask; + bool ignore_clr_ack; +}; /** * struct scp_domain_data - scp domain data for power on/off flow @@ -121,13 +184,25 @@ static const char * const clk_names[] = { */ struct scp_domain_data { const char *name; + const char *hwv_comp; u32 sta_mask; int ctl_offs; + u32 hwv_done_ofs; + u32 hwv_ofs; + u32 hwv_set_ofs; + u32 hwv_clr_ofs; + u32 hwv_en_ofs; + u32 hwv_set_sta_ofs; + u32 hwv_clr_sta_ofs; + u8 hwv_shift; u32 sram_pdn_bits; u32 sram_pdn_ack_bits; + u32 sram_slp_bits; + u32 sram_slp_ack_bits; u32 bus_prot_mask; enum clk_id clk_id[MAX_CLKS]; - u8 caps; + struct bus_prot bp_table[MAX_STEPS]; + u32 caps; }; struct scp; @@ -138,6 +213,8 @@ struct scp_domain { struct clk *clk[MAX_CLKS]; const struct scp_domain_data *data; struct regulator *supply; + struct regmap *hwv_regmap; + bool rtff_flag; }; struct scp_ctrl_reg { @@ -153,6 +230,8 @@ struct scp { struct regmap *infracfg; struct scp_ctrl_reg ctrl_reg; bool bus_prot_reg_update; + struct regmap **bp_regmap; + int num_bp; }; struct scp_subdomain { @@ -160,6 +239,9 @@ struct scp_subdomain { int subdomain; }; +typedef int (*scp_soc_post_probe_fn)(struct platform_device *pdev, + struct scp *scp); + struct scp_soc_data { const struct scp_domain_data *domains; int num_domains; @@ -167,6 +249,9 @@ struct scp_soc_data { int num_subdomains; const struct scp_ctrl_reg regs; bool bus_prot_reg_update; + const char **bp_list; + int num_bp; + scp_soc_post_probe_fn post_probe; }; static int scpsys_domain_is_on(struct scp_domain *scpd) @@ -191,6 +276,20 @@ static int scpsys_domain_is_on(struct scp_domain *scpd) return -EINVAL; } +static int scpsys_pwr_ack_is_on(struct scp_domain *scpd) +{ + u32 status = readl(scpd->scp->base + scpd->data->ctl_offs) & PWR_ACK; + + return status ? true : false; +} + +static int scpsys_pwr_ack_2nd_is_on(struct scp_domain *scpd) +{ + u32 status = readl(scpd->scp->base + scpd->data->ctl_offs) & PWR_ACK_2ND; + + return status ? true : false; +} + static int scpsys_regulator_enable(struct scp_domain *scpd) { if (!scpd->supply) @@ -233,11 +332,19 @@ static int scpsys_clk_enable(struct clk *clk[], int max_num) static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr) { u32 val; - u32 pdn_ack = scpd->data->sram_pdn_ack_bits; + u32 ack_mask, ack_sta; int tmp; - val = readl(ctl_addr); - val &= ~scpd->data->sram_pdn_bits; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_SLP)) { + ack_mask = scpd->data->sram_slp_ack_bits; + ack_sta = ack_mask; + val = readl(ctl_addr) | scpd->data->sram_slp_bits; + } else { + ack_mask = scpd->data->sram_pdn_ack_bits; + ack_sta = 0; + val = readl(ctl_addr) & ~scpd->data->sram_pdn_bits; + } + writel(val, ctl_addr); /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */ @@ -251,35 +358,169 @@ static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr) } else { /* Either wait until SRAM_PDN_ACK all 1 or 0 */ int ret = readl_poll_timeout(ctl_addr, tmp, - (tmp & pdn_ack) == 0, + (tmp & ack_mask) == ack_sta, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) return ret; } + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) { + val = readl(ctl_addr) | PWR_SRAM_ISOINT_B_BIT; + writel(val, ctl_addr); + udelay(1); + val &= ~PWR_SRAM_CLKISO_BIT; + writel(val, ctl_addr); + } + return 0; } static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr) { u32 val; - u32 pdn_ack = scpd->data->sram_pdn_ack_bits; + u32 ack_mask, ack_sta; int tmp; - val = readl(ctl_addr); - val |= scpd->data->sram_pdn_bits; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) { + val = readl(ctl_addr) | PWR_SRAM_CLKISO_BIT; + writel(val, ctl_addr); + val &= ~PWR_SRAM_ISOINT_B_BIT; + writel(val, ctl_addr); + udelay(1); + } + + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_SLP)) { + ack_mask = scpd->data->sram_slp_ack_bits; + ack_sta = 0; + val = readl(ctl_addr) & ~scpd->data->sram_slp_bits; + } else { + ack_mask = scpd->data->sram_pdn_ack_bits; + ack_sta = ack_mask; + val = readl(ctl_addr) | scpd->data->sram_pdn_bits; + } writel(val, ctl_addr); /* Either wait until SRAM_PDN_ACK all 1 or 0 */ return readl_poll_timeout(ctl_addr, tmp, - (tmp & pdn_ack) == pdn_ack, + (tmp & ack_mask) == ack_sta, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); } +static int set_bus_protection(struct regmap *map, struct bus_prot *bp) +{ + u32 val = 0; + int retry = 0; + int ret = 0; + + while (retry <= MTK_BUS_PROTECTION_RETY_TIMES) { + if (bp->set_ofs) + regmap_write(map, bp->set_ofs, bp->mask); + else + regmap_update_bits(map, bp->en_ofs, bp->mask, bp->mask); + + /* check bus protect enable setting */ + regmap_read(map, bp->en_ofs, &val); + if ((val & bp->mask) == bp->mask) + break; + + retry++; + } + + ret = regmap_read_poll_timeout_atomic(map, bp->sta_ofs, + val, (val & bp->ack_mask) == bp->ack_mask, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) { + pr_err("%s val=0x%x, mask=0x%x, (val & mask)=0x%x\n", + __func__, val, bp->ack_mask, (val & bp->ack_mask)); + } + + return ret; +} + +static int clear_bus_protection(struct regmap *map, struct bus_prot *bp) +{ + u32 val = 0; + int ret = 0; + + if (bp->clr_ofs) + regmap_write(map, bp->clr_ofs, bp->mask); + else + regmap_update_bits(map, bp->en_ofs, bp->mask, 0); + + if (bp->ignore_clr_ack) + return 0; + + ret = regmap_read_poll_timeout_atomic(map, bp->sta_ofs, val, + !(val & bp->ack_mask), MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) { + pr_err("%s val=0x%x, mask=0x%x, (val & mask)=0x%x\n", + __func__, val, bp->ack_mask, (val & bp->ack_mask)); + } + return ret; +} + +static int scpsys_bus_protect_table_disable(struct scp_domain *scpd, + unsigned int index) +{ + struct scp *scp = scpd->scp; + const struct bus_prot *bp_table = scpd->data->bp_table; + int ret = 0; + int i; + + for (i = index; i >= 0; i--) { + struct regmap *map; + struct bus_prot bp = bp_table[i]; + + if (bp.type == 0 || bp.type >= scp->num_bp) + continue; + + map = scp->bp_regmap[bp.type]; + if (!map) + continue; + + ret = clear_bus_protection(map, &bp); + if (ret) + break; + } + + return ret; +} + +static int scpsys_bus_protect_table_enable(struct scp_domain *scpd) +{ + struct scp *scp = scpd->scp; + const struct bus_prot *bp_table = scpd->data->bp_table; + int ret = 0; + int i; + + for (i = 0; i < MAX_STEPS; i++) { + struct regmap *map; + struct bus_prot bp = bp_table[i]; + + if (bp.type == 0 || bp.type >= scp->num_bp) + continue; + + map = scp->bp_regmap[bp.type]; + if (!map) + continue; + + ret = set_bus_protection(map, &bp); + if (ret) { + scpsys_bus_protect_table_disable(scpd, i); + return ret; + } + } + + return ret; +} + static int scpsys_bus_protect_enable(struct scp_domain *scpd) { struct scp *scp = scpd->scp; + if (scp->bp_regmap && scp->num_bp > 0) + return scpsys_bus_protect_table_enable(scpd); + if (!scpd->data->bus_prot_mask) return 0; @@ -292,6 +533,9 @@ static int scpsys_bus_protect_disable(struct scp_domain *scpd) { struct scp *scp = scpd->scp; + if (scp->bp_regmap && scp->num_bp > 0) + return scpsys_bus_protect_table_disable(scpd, MAX_STEPS - 1); + if (!scpd->data->bus_prot_mask) return 0; @@ -320,24 +564,94 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) val = readl(ctl_addr); val |= PWR_ON_BIT; writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) { + ret = readx_poll_timeout_atomic(scpsys_pwr_ack_is_on, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto err_pwr_ack; + + udelay(MTK_ACK_DELAY_US); + } + val |= PWR_ON_2ND_BIT; writel(val, ctl_addr); /* wait until PWR_ACK = 1 */ - ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0, - MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) + ret = readx_poll_timeout_atomic(scpsys_pwr_ack_2nd_is_on, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + else + ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) goto err_pwr_ack; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF) && scpd->rtff_flag) { + val |= PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + } + val &= ~PWR_CLK_DIS_BIT; writel(val, ctl_addr); val &= ~PWR_ISO_BIT; writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_RTFF_DELAY) && scpd->rtff_flag) + udelay(MTK_RTFF_DELAY_US); + val |= PWR_RST_B_BIT; writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_NON_CPU_RTFF)) { + val = readl(ctl_addr); + if (val & PWR_RTFF_SAVE_FLAG) { + val &= ~PWR_RTFF_SAVE_FLAG; + writel(val, ctl_addr); + + val |= PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val |= PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + } + } else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF)) { + val = readl(ctl_addr); + if (val & PWR_RTFF_SAVE_FLAG) { + val &= ~PWR_RTFF_SAVE_FLAG; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val |= PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + } + } else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF) && scpd->rtff_flag) { + val |= PWR_RTFF_UFS_CLK_DIS; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val |= PWR_RTFF_NRESTORE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_UFS_CLK_DIS; + writel(val, ctl_addr); + + scpd->rtff_flag = false; + } + ret = scpsys_sram_enable(scpd, ctl_addr); if (ret < 0) goto err_pwr_ack; @@ -376,9 +690,45 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) /* subsys power off */ val = readl(ctl_addr); + + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_NON_CPU_RTFF) || + MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF)) { + val |= PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + + val |= PWR_RTFF_SAVE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_SAVE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_CLK_DIS; + writel(val, ctl_addr); + + val |= PWR_RTFF_SAVE_FLAG; + writel(val, ctl_addr); + } else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF)) { + val |= PWR_RTFF_UFS_CLK_DIS; + writel(val, ctl_addr); + + val |= PWR_RTFF_SAVE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_SAVE; + writel(val, ctl_addr); + + val &= ~PWR_RTFF_UFS_CLK_DIS; + writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF)) + scpd->rtff_flag = true; + } + val |= PWR_ISO_BIT; writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_RTFF_DELAY) && scpd->rtff_flag) + udelay(1); + val &= ~PWR_RST_B_BIT; writel(val, ctl_addr); @@ -388,12 +738,23 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) val &= ~PWR_ON_BIT; writel(val, ctl_addr); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) { + ret = readx_poll_timeout_atomic(scpsys_pwr_ack_is_on, scpd, tmp, tmp == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto out; + } + val &= ~PWR_ON_2ND_BIT; writel(val, ctl_addr); /* wait until PWR_ACK = 0 */ - ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0, - MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) + ret = readx_poll_timeout_atomic(scpsys_pwr_ack_2nd_is_on, scpd, tmp, tmp == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + else + ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) goto out; @@ -411,6 +772,147 @@ out: return ret; } +static int mtk_hwv_is_done(struct scp_domain *scpd) +{ + u32 val = 0, mask = 0; + + regmap_read(scpd->hwv_regmap, scpd->data->hwv_done_ofs, &val); + mask = BIT(scpd->data->hwv_shift); + if ((val & mask) == mask) + return 1; + + return 0; +} + +static int mtk_hwv_is_enable_done(struct scp_domain *scpd) +{ + u32 val = 0, val2 = 0, val3 = 0; + + regmap_read(scpd->hwv_regmap, scpd->data->hwv_done_ofs, &val); + regmap_read(scpd->hwv_regmap, scpd->data->hwv_en_ofs, &val2); + regmap_read(scpd->hwv_regmap, scpd->data->hwv_set_sta_ofs, &val3); + + if ((val & BIT(scpd->data->hwv_shift)) && (val2 & BIT(scpd->data->hwv_shift)) + && ((val3 & BIT(scpd->data->hwv_shift)) == 0x0)) + return 1; + + return 0; +} + +static int mtk_hwv_is_disable_done(struct scp_domain *scpd) +{ + u32 val = 0, val2 = 0; + + regmap_read(scpd->hwv_regmap, scpd->data->hwv_done_ofs, &val); + regmap_read(scpd->hwv_regmap, scpd->data->hwv_clr_sta_ofs, &val2); + + if ((val & BIT(scpd->data->hwv_shift)) && + ((val2 & BIT(scpd->data->hwv_shift)) == 0x0)) + return 1; + + return 0; +} + +static int scpsys_hwv_power_on(struct generic_pm_domain *genpd) +{ + struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); + struct scp *scp = scpd->scp; + u32 val = 0; + int ret = 0; + int tmp; + int i = 0; + + ret = scpsys_regulator_enable(scpd); + if (ret < 0) + goto out; + + ret = scpsys_clk_enable(scpd->clk, MAX_CLKS); + if (ret) + goto out; + + ret = readx_poll_timeout_atomic(mtk_hwv_is_done, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_IRQ_TIMEOUT); + if (ret < 0) + goto out; + + val = BIT(scpd->data->hwv_shift); + regmap_write(scpd->hwv_regmap, scpd->data->hwv_set_ofs, val); + do { + regmap_read(scpd->hwv_regmap, scpd->data->hwv_set_ofs, &val); + if ((val & BIT(scpd->data->hwv_shift)) != 0) + break; + + if (i > MTK_POLL_HWV_PREPARE_CNT) + goto out; + + udelay(MTK_POLL_HWV_PREPARE_US); + i++; + } while (1); + + /* add debounce time */ + udelay(1); + + /* wait until VOTER_ACK = 1 */ + ret = readx_poll_timeout_atomic(mtk_hwv_is_enable_done, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT_300MS); + if (ret < 0) + goto out; + + return 0; +out: + dev_err(scp->dev, "Failed to power on domain %s(%d)\n", genpd->name, ret); + return ret; +} + +static int scpsys_hwv_power_off(struct generic_pm_domain *genpd) +{ + struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); + struct scp *scp = scpd->scp; + u32 val = 0; + int ret = 0; + int tmp; + int i = 0; + + ret = readx_poll_timeout_atomic(mtk_hwv_is_done, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_IRQ_TIMEOUT); + if (ret < 0) + goto out; + + val = BIT(scpd->data->hwv_shift); + regmap_write(scpd->hwv_regmap, scpd->data->hwv_clr_ofs, val); + do { + regmap_read(scpd->hwv_regmap, scpd->data->hwv_clr_ofs, &val); + if ((val & BIT(scpd->data->hwv_shift)) == 0) + break; + + if (i > MTK_POLL_HWV_PREPARE_CNT) + goto out; + + i++; + udelay(MTK_POLL_HWV_PREPARE_US); + } while (1); + + /* delay 100us for stable status */ + udelay(MTK_STABLE_DELAY_US); + + /* wait until VOTER_ACK = 0 */ + ret = readx_poll_timeout_atomic(mtk_hwv_is_disable_done, + scpd, tmp, tmp > 0, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT_300MS); + if (ret < 0) + goto out; + + scpsys_clk_disable(scpd->clk, MAX_CLKS); + + ret = scpsys_regulator_disable(scpd); + if (ret < 0) + goto out; + + return 0; +out: + dev_err(scp->dev, "Failed to power off domain %s(%d)\n", genpd->name, ret); + return ret; +} + static void init_clks(struct platform_device *pdev, struct clk **clk) { int i; @@ -419,25 +921,42 @@ static void init_clks(struct platform_device *pdev, struct clk **clk) clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); } -static struct scp *init_scp(struct platform_device *pdev, - const struct scp_domain_data *scp_domain_data, int num, - const struct scp_ctrl_reg *scp_ctrl_reg, - bool bus_prot_reg_update) +static int mtk_pd_get_regmap(struct platform_device *pdev, struct regmap **regmap, + const char *name) +{ + *regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, name); + if (PTR_ERR(*regmap) == -ENODEV) { + dev_notice(&pdev->dev, "%s regmap is null(%ld)\n", + name, PTR_ERR(*regmap)); + + *regmap = NULL; + } else if (IS_ERR(*regmap)) { + dev_notice(&pdev->dev, "Cannot find %s controller: %ld\n", + name, PTR_ERR(*regmap)); + + return PTR_ERR(*regmap); + } + + return 0; +} + +struct scp *init_scp(struct platform_device *pdev, const struct scp_soc_data *soc) { struct genpd_onecell_data *pd_data; struct resource *res; int i, j; struct scp *scp; struct clk *clk[CLK_MAX]; + int ret; scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); if (!scp) return ERR_PTR(-ENOMEM); - scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs; - scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs; + scp->ctrl_reg.pwr_sta_offs = soc->regs.pwr_sta_offs; + scp->ctrl_reg.pwr_sta2nd_offs = soc->regs.pwr_sta2nd_offs; - scp->bus_prot_reg_update = bus_prot_reg_update; + scp->bus_prot_reg_update = soc->bus_prot_reg_update; scp->dev = &pdev->dev; @@ -447,28 +966,43 @@ static struct scp *init_scp(struct platform_device *pdev, return ERR_CAST(scp->base); scp->domains = devm_kcalloc(&pdev->dev, - num, sizeof(*scp->domains), GFP_KERNEL); + soc->num_domains, sizeof(*scp->domains), GFP_KERNEL); if (!scp->domains) return ERR_PTR(-ENOMEM); pd_data = &scp->pd_data; pd_data->domains = devm_kcalloc(&pdev->dev, - num, sizeof(*pd_data->domains), GFP_KERNEL); + soc->num_domains, sizeof(*pd_data->domains), GFP_KERNEL); if (!pd_data->domains) return ERR_PTR(-ENOMEM); - scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "infracfg"); - if (IS_ERR(scp->infracfg)) { - dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", - PTR_ERR(scp->infracfg)); - return ERR_CAST(scp->infracfg); + if (soc->bp_list && soc->num_bp > 0) { + scp->num_bp = soc->num_bp; + scp->bp_regmap = devm_kcalloc(&pdev->dev, + scp->num_bp, sizeof(*scp->bp_regmap), GFP_KERNEL); + if (!scp->bp_regmap) + return ERR_PTR(-ENOMEM); + + /* get bus prot regmap from dts node, 0 means invalid bus type */ + for (i = 1; i < scp->num_bp; i++) { + ret = mtk_pd_get_regmap(pdev, &scp->bp_regmap[i], soc->bp_list[i]); + if (ret) + return ERR_PTR(ret); + } + } else { + scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "infracfg"); + if (IS_ERR(scp->infracfg)) { + dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", + PTR_ERR(scp->infracfg)); + return ERR_CAST(scp->infracfg); + } } - for (i = 0; i < num; i++) { + for (i = 0; i < soc->num_domains; i++) { struct scp_domain *scpd = &scp->domains[i]; - const struct scp_domain_data *data = &scp_domain_data[i]; + const struct scp_domain_data *data = &soc->domains[i]; scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name); if (IS_ERR(scpd->supply)) { @@ -479,14 +1013,14 @@ static struct scp *init_scp(struct platform_device *pdev, } } - pd_data->num_domains = num; + pd_data->num_domains = soc->num_domains; init_clks(pdev, clk); - for (i = 0; i < num; i++) { + for (i = 0; i < soc->num_domains; i++) { struct scp_domain *scpd = &scp->domains[i]; struct generic_pm_domain *genpd = &scpd->genpd; - const struct scp_domain_data *data = &scp_domain_data[i]; + const struct scp_domain_data *data = &soc->domains[i]; pd_data->domains[i] = genpd; scpd->scp = scp; @@ -505,11 +1039,26 @@ static struct scp *init_scp(struct platform_device *pdev, scpd->clk[j] = c; } + if (data->hwv_comp) { + ret = mtk_pd_get_regmap(pdev, &scpd->hwv_regmap, data->hwv_comp); + if (ret) + return ERR_PTR(ret); + } + genpd->name = data->name; - genpd->power_off = scpsys_power_off; - genpd->power_on = scpsys_power_on; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_HWV_OPS)) { + genpd->power_on = scpsys_hwv_power_on; + genpd->power_off = scpsys_hwv_power_off; + } else { + genpd->power_off = scpsys_power_off; + genpd->power_on = scpsys_power_on; + } if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP)) genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IRQ_SAVE)) + genpd->flags |= GENPD_FLAG_IRQ_SAFE; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ALWAYS_ON)) + genpd->flags |= GENPD_FLAG_ALWAYS_ON; } return scp; @@ -532,7 +1081,10 @@ static void mtk_register_power_domains(struct platform_device *pdev, * software. The unused domains will be switched off during * late_init time. */ - on = !WARN_ON(genpd->power_on(genpd) < 0); + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_BYPASS_INIT_ON)) + on = false; + else + on = !WARN_ON(genpd->power_on(genpd) < 0); pm_genpd_init(genpd, NULL, !on); } @@ -1011,6 +1563,564 @@ static const struct scp_subdomain scp_subdomain_mt8173[] = { {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, }; +/* + * MT8196 power domain support + */ +static const char *mt8196_spm_bp_list[MT8196_SPM_BP_NR] = { + [MT8196_SPM_BP_SPM] = "spm", +}; + +static const struct scp_domain_data scp_domain_mt8196_spm_hwv_data[] = { + [MT8196_POWER_DOMAIN_CONN] = { + .name = "conn", + .ctl_offs = MT8196_SPM_CONN_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_CONN), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON, + }, + [MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0] = { + .name = "ssusb-dp-phy-p0", + .ctl_offs = MT8196_SPM_SSUSB_DP_PHY_P0_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_SSUSB_P0] = { + .name = "ssusb-p0", + .ctl_offs = MT8196_SPM_SSUSB_P0_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P0), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_SSUSB_P1] = { + .name = "ssusb-p1", + .ctl_offs = MT8196_SPM_SSUSB_P1_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P1), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_SSUSB_P23] = { + .name = "ssusb-p23", + .ctl_offs = MT8196_SPM_SSUSB_P23_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P23), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON, + }, + [MT8196_POWER_DOMAIN_SSUSB_PHY_P2] = { + .name = "ssusb-phy-p2", + .ctl_offs = MT8196_SPM_SSUSB_PHY_P2_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC0] = { + .name = "pextp-mac0", + .ctl_offs = MT8196_SPM_PEXTP_MAC0_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC1] = { + .name = "pextp-mac1", + .ctl_offs = MT8196_SPM_PEXTP_MAC1_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC2] = { + .name = "pextp-mac2", + .ctl_offs = MT8196_SPM_PEXTP_MAC2_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY0] = { + .name = "pextp-phy0", + .ctl_offs = MT8196_SPM_PEXTP_PHY0_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY1] = { + .name = "pextp-phy1", + .ctl_offs = MT8196_SPM_PEXTP_PHY1_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY2] = { + .name = "pextp-phy2", + .ctl_offs = MT8196_SPM_PEXTP_PHY2_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY, + }, + [MT8196_POWER_DOMAIN_AUDIO] = { + .name = "audio", + .ctl_offs = MT8196_SPM_AUDIO_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_AUDIO), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF, + }, + [MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT] = { + .name = "adsp-top-dormant", + .ctl_offs = MT8196_SPM_ADSP_TOP_PWR_CON, + .sram_slp_bits = GENMASK(9, 9), + .sram_slp_ack_bits = GENMASK(13, 13), + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM,MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_TOP), + }, + .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_SRAM_SLP | MTK_SCPD_IS_PWR_CON_ON, + }, + [MT8196_POWER_DOMAIN_ADSP_INFRA] = { + .name = "adsp-infra", + .ctl_offs = MT8196_SPM_ADSP_INFRA_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_INFRA), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_ADSP_AO] = { + .name = "adsp-ao", + .ctl_offs = MT8196_SPM_ADSP_AO_PWR_CON, + .bp_table = { + BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET, + MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN, + MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_AO), + }, + .caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_MM_PROC_DORMANT] = { + .name = "mm-proc-dormant", + .hwv_comp = "hw-voter-regmap", + .hwv_set_ofs = MT8196_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_VOTE_MTCMOS_ENABLE0, + .hwv_set_sta_ofs = MT8196_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_VOTE_MM_PROC_SHIFT, + .caps = MTK_SCPD_HWV_OPS | MTK_SCPD_IRQ_SAVE, + }, + [MT8196_POWER_DOMAIN_SSR] = { + .name = "ssrsys", + .hwv_comp = "hw-voter-regmap", + .hwv_set_ofs = MT8196_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_VOTE_MTCMOS_ENABLE0, + .hwv_set_sta_ofs = MT8196_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_VOTE_SSR_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, +}; + +static const struct scp_subdomain scp_subdomain_mt8196_spm[] = { + {MT8196_POWER_DOMAIN_SSUSB_P0, MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0}, + {MT8196_POWER_DOMAIN_SSUSB_P23, MT8196_POWER_DOMAIN_SSUSB_PHY_P2}, + {MT8196_POWER_DOMAIN_PEXTP_MAC0, MT8196_POWER_DOMAIN_PEXTP_PHY0}, + {MT8196_POWER_DOMAIN_PEXTP_MAC1, MT8196_POWER_DOMAIN_PEXTP_PHY1}, + {MT8196_POWER_DOMAIN_PEXTP_MAC2, MT8196_POWER_DOMAIN_PEXTP_PHY2}, + {MT8196_POWER_DOMAIN_ADSP_INFRA, MT8196_POWER_DOMAIN_AUDIO}, + {MT8196_POWER_DOMAIN_ADSP_INFRA, MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT}, + {MT8196_POWER_DOMAIN_ADSP_AO, MT8196_POWER_DOMAIN_ADSP_INFRA}, +}; + +static struct generic_pm_domain *mt8196_mm_proc_domain; + +static int mt8196_spm_post_probe(struct platform_device *pdev, + struct scp *scp) +{ + mt8196_mm_proc_domain + = scp->pd_data.domains[MT8196_POWER_DOMAIN_MM_PROC_DORMANT]; + return 0; +} + +static const char *mt8196_mmpc_bp_list[MT8196_MMPC_BP_NR] = { + [MT8196_MMPC_BP_MMPC] = "mmpc", +}; + +static const struct scp_domain_data scp_domain_mt8196_mmpc_hwv_data[] = { + [MT8196_POWER_DOMAIN_VDE0] = { + .name = "vde0", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VDE0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_VDE1] = { + .name = "vde1", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VDE1_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_VDE_VCORE0] = { + .name = "vde-vcore0", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VDE_VCORE0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_VEN0] = { + .name = "ven0", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VEN0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_VEN1] = { + .name = "ven1", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VEN1_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_VEN2] = { + .name = "ven2", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_VEN2_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DISP_VCORE] = { + .name = "disp-vcore", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_DISP_VCORE_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DIS0_DORMANT] = { + .name = "dis0-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_DIS0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DIS1_DORMANT] = { + .name = "dis1-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_DIS1_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_OVL0_DORMANT] = { + .name = "ovl0-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_OVL0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_OVL1_DORMANT] = { + .name = "ovl1-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_OVL1_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT] = { + .name = "disp-edptx-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_DISP_EDPTX_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT] = { + .name = "disp-dptx-dormant", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_DISP_DPTX_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_MML0_SHUTDOWN] = { + .name = "mml0-shutdown", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0, + .hwv_shift = MT8196_MM_VOTE_MML0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_MML1_SHUTDOWN] = { + .name = "mml1-shutdown", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_MML0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_MM_INFRA0] = { + .name = "mm-infra0", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_MM_INFRA0_SHIFT, + .caps = MTK_SCPD_HWV_OPS | MTK_SCPD_IRQ_SAVE, + }, + [MT8196_POWER_DOMAIN_MM_INFRA1] = { + .name = "mm-infra1", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_MM_INFRA1_SHIFT, + .caps = MTK_SCPD_HWV_OPS | MTK_SCPD_IRQ_SAVE, + }, + [MT8196_POWER_DOMAIN_MM_INFRA_AO] = { + .name = "mm-infra-ao", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_MM_INFRA_AO_SHIFT, + .caps = MTK_SCPD_HWV_OPS | MTK_SCPD_IRQ_SAVE, + }, + [MT8196_POWER_DOMAIN_CSI_BS_RX] = { + .name = "csi-bs-rx", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_CSI_BS_RX_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_CSI_LS_RX] = { + .name = "csi-ls-rx", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_CSI_LS_RX_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DSI_PHY0] = { + .name = "dsi-phy0", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_DSI_PHY0_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DSI_PHY1] = { + .name = "dsi-phy1", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_DSI_PHY1_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, + [MT8196_POWER_DOMAIN_DSI_PHY2] = { + .name = "dsi-phy2", + .hwv_comp = "mm-hw-ccf-regmap", + .hwv_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1, + .hwv_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1, + .hwv_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1, + .hwv_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1, + .hwv_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1, + .hwv_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1, + .hwv_shift = MT8196_MM_VOTE_DSI_PHY2_SHIFT, + .caps = MTK_SCPD_HWV_OPS, + }, +}; + +static const struct scp_subdomain scp_subdomain_mt8196_mmpc[] = { + {MT8196_POWER_DOMAIN_VDE_VCORE0, MT8196_POWER_DOMAIN_VDE0}, + {MT8196_POWER_DOMAIN_VDE_VCORE0, MT8196_POWER_DOMAIN_VDE1}, + {MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_VDE_VCORE0}, + {MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_VEN0}, + {MT8196_POWER_DOMAIN_VEN0, MT8196_POWER_DOMAIN_VEN1}, + {MT8196_POWER_DOMAIN_VEN1, MT8196_POWER_DOMAIN_VEN2}, + {MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_DISP_VCORE}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DIS0_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DIS1_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_OVL0_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_OVL1_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_MML0_SHUTDOWN}, + {MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_MML1_SHUTDOWN}, +}; + +static int mt8196_mmpc_post_probe(struct platform_device *pdev, + struct scp *scp) +{ + int ret, i; + int subdomain[] = { + MT8196_POWER_DOMAIN_MM_INFRA_AO, + MT8196_POWER_DOMAIN_MM_INFRA0, + MT8196_POWER_DOMAIN_MM_INFRA1, + MT8196_POWER_DOMAIN_CSI_BS_RX, + MT8196_POWER_DOMAIN_CSI_LS_RX, + MT8196_POWER_DOMAIN_DSI_PHY0, + MT8196_POWER_DOMAIN_DSI_PHY1, + MT8196_POWER_DOMAIN_DSI_PHY2 + }; + + for (i = 0; i < ARRAY_SIZE(subdomain); i++) { + ret = pm_genpd_add_subdomain(mt8196_mm_proc_domain, scp->pd_data.domains[subdomain[i]]); + if (ret && IS_ENABLED(CONFIG_PM)) { + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); + return ret; + } + } + + return 0; +} + static const struct scp_soc_data mt2701_data = { .domains = scp_domain_data_mt2701, .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), @@ -1077,6 +2187,34 @@ static const struct scp_soc_data mt8173_data = { .bus_prot_reg_update = true, }; +static const struct scp_soc_data mt8196_spm_hwv_data = { + .domains = scp_domain_mt8196_spm_hwv_data, + .num_domains = MT8196_SPM_POWER_DOMAIN_NR, + .subdomains = scp_subdomain_mt8196_spm, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8196_spm), + .regs = { + .pwr_sta_offs = MT8196_SPM_PWR_STATUS, + .pwr_sta2nd_offs = MT8196_SPM_PWR_STATUS_2ND, + }, + .bp_list = mt8196_spm_bp_list, + .num_bp = MT8196_SPM_BP_NR, + .post_probe = mt8196_spm_post_probe, +}; + +static const struct scp_soc_data mt8196_mmpc_hwv_data = { + .domains = scp_domain_mt8196_mmpc_hwv_data, + .num_domains = MT8196_MMPC_POWER_DOMAIN_NR, + .subdomains = scp_subdomain_mt8196_mmpc, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8196_mmpc), + .regs = { + .pwr_sta_offs = MT8196_MM_PWR_STATUS, + .pwr_sta2nd_offs = MT8196_MM_PWR_STATUS_2ND, + }, + .bp_list = mt8196_mmpc_bp_list, + .num_bp = MT8196_MMPC_BP_NR, + .post_probe = mt8196_mmpc_post_probe, +}; + /* * scpsys driver init */ @@ -1100,6 +2238,12 @@ static const struct of_device_id of_scpsys_match_tbl[] = { }, { .compatible = "mediatek,mt8173-scpsys", .data = &mt8173_data, + }, { + .compatible = "mediatek,mt8196-scpsys-hwv", + .data = &mt8196_spm_hwv_data, + }, { + .compatible = "mediatek,mt8196-hfrpsys-hwv", + .data = &mt8196_mmpc_hwv_data, }, { /* sentinel */ } @@ -1115,8 +2259,7 @@ static int scpsys_probe(struct platform_device *pdev) soc = of_device_get_match_data(&pdev->dev); - scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, - soc->bus_prot_reg_update); + scp = init_scp(pdev, soc); if (IS_ERR(scp)) return PTR_ERR(scp); @@ -1132,6 +2275,12 @@ static int scpsys_probe(struct platform_device *pdev) ret); } + if (soc->post_probe) { + ret = soc->post_probe(pdev, scp); + if (ret) + return ret; + } + return 0; } -- GitLab From d344fb028848320fad9c3bc888400453c6e5d63f Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Mon, 29 Apr 2024 15:56:26 +0800 Subject: [PATCH 351/456] CHROMIUM: media: jpeg: add jpeg compatible for jpegdec & jpegenc Add jpeg compatible for mt8196 BUG=b:338341749 TEST=build and boot to shell UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: I3e73c88c4391a28ef5d3acf42325ff489e97691a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073869 Reviewed-by: Pin-yen Lin Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 8 ++++++++ drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 3 +++ drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 3 +++ 3 files changed, 14 insertions(+) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 4c7b46f5a7ddd..6689099f58ce0 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1954,6 +1954,14 @@ static const struct of_device_id mtk_jpeg_match[] = { .compatible = "mediatek,mt8195-jpgdec", .data = &mtk8195_jpegdec_drvdata, }, + { + .compatible = "mediatek,mt8196-jpgenc", + .data = &mtk8195_jpegenc_drvdata, + }, + { + .compatible = "mediatek,mt8196-jpgdec", + .data = &mtk8195_jpegdec_drvdata, + }, {}, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 2c5d74939d0a9..273d7ba17fda5 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -43,6 +43,9 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = { { .compatible = "mediatek,mt8195-jpgdec-hw", }, + { + .compatible = "mediatek,mt8196-jpgdec-hw", + }, {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index f8fa3b841ccfb..1f011fa314c6f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -50,6 +50,9 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = { { .compatible = "mediatek,mt8195-jpgenc-hw", }, + { + .compatible = "mediatek,mt8196-jpgenc-hw", + }, {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids); -- GitLab From 26a3897f5190a242d0b92d7654815e100e820b14 Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Wed, 8 May 2024 15:57:37 +0800 Subject: [PATCH 352/456] CHROMIUM: media: jpeg: fix jpeg smmu sid setting Add a function to set jpeg dec & enc smmu sid for mt8196 BUG=b:338341749 TEST=build and boot to shell UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: I6c0d60c0e2ef21052f7d5686040fa384cbd10860 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073870 Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 6 ++++ .../platform/mediatek/jpeg/mtk_jpeg_core.h | 12 ++++++++ .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 28 +++++++++++++++++-- .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.h | 1 + .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 26 ++++++++++++++++- .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.h | 1 + 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 6689099f58ce0..0639fc3bcd84f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1658,6 +1658,9 @@ retry_select: jpeg_dst_buf->frame_num = ctx->total_frame_num; ctx->total_frame_num++; mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base); +#if IS_ENABLED(CONFIG_ARM_SMMU_V3) + mtk_jpeg_enc_set_smmu_sid(comp_jpeg[hw_id]->dev, hw_id); +#endif mtk_jpeg_set_enc_dst(ctx, comp_jpeg[hw_id]->reg_base, &dst_buf->vb2_buf); @@ -1774,6 +1777,9 @@ retry_select: spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); ctx->total_frame_num++; mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base); +#if IS_ENABLED(CONFIG_ARM_SMMU_V3) + mtk_jpeg_dec_set_smmu_sid(comp_jpeg[hw_id]->dev, hw_id); +#endif mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base, &jpeg_src_buf->dec_param, jpeg_src_buf->bs_size, diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index 8ba6e757e11aa..80c94cdf28b5f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -34,6 +34,18 @@ #define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024) +#define JPG_REG_CORE0_GUSER_ID 0x380d0000 +#define JPG_REG_CORE1_GUSER_ID 0x388d0000 +#define JPG_REG_GUSER_ID_MASK 0x7 +#define JPG_REG_GUSER_ID_DEC_SID 0x4 +#define JPG_REG_GUSER_ID_ENC_SID 0x5 +#define JPG_REG_DEC_GUSER_ID_SHIFT 8 +#define JPG_REG_ENC_GUSER_ID_SHIFT 4 +#define GUSER_ID_MAPRANGE 4 + + + + /** * enum mtk_jpeg_ctx_state - states of the context state machine * @MTK_JPEG_INIT: current state is initialized diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 273d7ba17fda5..7e4ba610528d3 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -272,6 +272,30 @@ void mtk_jpeg_dec_reset(void __iomem *base) } EXPORT_SYMBOL_GPL(mtk_jpeg_dec_reset); +void mtk_jpeg_dec_set_smmu_sid(struct device *dev, int hwid) +{ + void __iomem *dec_reg_base; + u32 val, mask; + + if (hwid) + dec_reg_base = ioremap(JPG_REG_CORE1_GUSER_ID, GUSER_ID_MAPRANGE); + else + dec_reg_base = ioremap(JPG_REG_CORE0_GUSER_ID, GUSER_ID_MAPRANGE); + if (!dec_reg_base) { + dev_err(dev, "Failed to map hardware address JPG_REG_GUSER_ID\n"); + return; + } + + val = ioread32(dec_reg_base); + mask = ~(JPG_REG_GUSER_ID_MASK << JPG_REG_DEC_GUSER_ID_SHIFT); + val &= mask; + val |= (JPG_REG_GUSER_ID_DEC_SID << JPG_REG_DEC_GUSER_ID_SHIFT); + + iowrite32(val, dec_reg_base); + iounmap(dec_reg_base); +} +EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_smmu_sid); + static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w, u8 yscale_h, u8 uvscale_w, u8 uvscale_h) { @@ -515,7 +539,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_jpeg_src_buf *jpeg_src_buf; enum vb2_buffer_state buf_state; - struct mtk_jpeg_ctx *ctx; u32 dec_irq_ret; u32 irq_status; int i; @@ -525,7 +548,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) cancel_delayed_work(&jpeg->job_timeout_work); - ctx = jpeg->hw_param.curr_ctx; src_buf = jpeg->hw_param.src_buffer; dst_buf = jpeg->hw_param.dst_buffer; v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); @@ -548,7 +570,7 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) buf_state = VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(jpeg); - pm_runtime_put(ctx->jpeg->dev); + pm_runtime_put(jpeg->dev); clk_disable_unprepare(jpeg->jdec_clk.clks->clk); jpeg->hw_state = MTK_JPEG_HW_IDLE; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h index 8c31c6b124178..8facd8b22323e 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h @@ -77,5 +77,6 @@ void mtk_jpeg_dec_set_config(void __iomem *base, struct mtk_jpeg_fb *fb); void mtk_jpeg_dec_reset(void __iomem *dec_reg_base); void mtk_jpeg_dec_start(void __iomem *dec_reg_base); +void mtk_jpeg_dec_set_smmu_sid(struct device *dev, int hwid); #endif /* _MTK_JPEG_HW_H */ diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 1f011fa314c6f..b6da3d06a6711 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -65,6 +65,30 @@ void mtk_jpeg_enc_reset(void __iomem *base) } EXPORT_SYMBOL_GPL(mtk_jpeg_enc_reset); +void mtk_jpeg_enc_set_smmu_sid(struct device *dev, int hwid) +{ + void __iomem *enc_reg_base; + u32 val, mask; + + if (hwid) + enc_reg_base = ioremap(JPG_REG_CORE1_GUSER_ID, GUSER_ID_MAPRANGE); + else + enc_reg_base = ioremap(JPG_REG_CORE0_GUSER_ID, GUSER_ID_MAPRANGE); + if (!enc_reg_base) { + dev_err(dev, "Failed to map hardware address JPG_REG_GUSER_ID\n"); + return; + } + + val = ioread32(enc_reg_base); + mask = ~(JPG_REG_GUSER_ID_MASK << JPG_REG_ENC_GUSER_ID_SHIFT); + val &= mask; + val |= (JPG_REG_GUSER_ID_ENC_SID << JPG_REG_ENC_GUSER_ID_SHIFT); + + iowrite32(val, enc_reg_base); + iounmap(enc_reg_base); +} +EXPORT_SYMBOL_GPL(mtk_jpeg_enc_set_smmu_sid); + u32 mtk_jpeg_enc_get_file_size(void __iomem *base) { return readl(base + JPEG_ENC_DMA_ADDR0) - @@ -286,7 +310,7 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) buf_state = VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(jpeg); - pm_runtime_put(ctx->jpeg->dev); + pm_runtime_put(jpeg->dev); clk_disable_unprepare(jpeg->venc_clk.clks->clk); jpeg->hw_state = MTK_JPEG_HW_IDLE; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h index 61c60e4e58ea9..a999ddfba2260 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h @@ -87,5 +87,6 @@ void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, struct vb2_buffer *dst_buf); void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base); +void mtk_jpeg_enc_set_smmu_sid(struct device *dev, int hwid); #endif /* _MTK_JPEG_ENC_HW_H */ -- GitLab From 8b4ad6132feb7010ec6357ac87a1e1b5e97733e5 Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Wed, 19 Jun 2024 15:43:01 +0800 Subject: [PATCH 353/456] CHROMIUM: media: jpeg: support 34bits the iommu HW supported 34bits iova space(16GB), but mediatek jpeg enc/dec driver still is 32bit, then need to set the bit32/bit33 iova to jpeg HW. BUG=b:338341749 TEST=build and boot to shell UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: If098e6363c1f613674bfde9aa1ed1d1e3e3d8e99 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073871 Commit-Queue: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 38 +++++++++++- .../platform/mediatek/jpeg/mtk_jpeg_core.h | 2 + .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 59 +++++++++++++++---- .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.h | 1 + .../platform/mediatek/jpeg/mtk_jpeg_dec_reg.h | 8 +++ .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 47 +++++++++++++-- .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.h | 11 +++- 7 files changed, 144 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 0639fc3bcd84f..6b98fe07e9624 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1031,6 +1031,7 @@ static void mtk_jpeg_dec_device_run(void *priv) spin_lock_irqsave(&jpeg->hw_lock, flags); mtk_jpeg_dec_reset(jpeg->reg_base); mtk_jpeg_dec_set_config(jpeg->reg_base, + jpeg->variant->support_34bit, &jpeg_src_buf->dec_param, jpeg_src_buf->bs_size, &bs, @@ -1575,7 +1576,8 @@ static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base, + ctx->jpeg->variant->support_34bit); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); buf_state = VB2_BUF_STATE_DONE; @@ -1781,6 +1783,7 @@ retry_select: mtk_jpeg_dec_set_smmu_sid(comp_jpeg[hw_id]->dev, hw_id); #endif mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base, + jpeg->variant->support_34bit, &jpeg_src_buf->dec_param, jpeg_src_buf->bs_size, &bs, @@ -1939,6 +1942,35 @@ static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = { .jpeg_worker = mtk_jpegdec_worker, }; +static struct mtk_jpeg_variant mtk8196_jpegenc_drvdata = { + .formats = mtk_jpeg_enc_formats, + .num_formats = MTK_JPEG_ENC_NUM_FORMATS, + .qops = &mtk_jpeg_enc_qops, + .m2m_ops = &mtk_jpeg_multicore_enc_m2m_ops, + .dev_name = "mtk-jpeg-enc", + .ioctl_ops = &mtk_jpeg_enc_ioctl_ops, + .out_q_default_fourcc = V4L2_PIX_FMT_YUYV, + .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, + .multi_core = true, + .jpeg_worker = mtk_jpegenc_worker, + .support_34bit = true, +}; + +static const struct mtk_jpeg_variant mtk8196_jpegdec_drvdata = { + .formats = mtk_jpeg_dec_formats, + .num_formats = MTK_JPEG_DEC_NUM_FORMATS, + .qops = &mtk_jpeg_dec_qops, + .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops, + .dev_name = "mtk-jpeg-dec", + .ioctl_ops = &mtk_jpeg_dec_ioctl_ops, + .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, + .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, + .multi_core = true, + .jpeg_worker = mtk_jpegdec_worker, + .support_34bit = true, +}; + + static const struct of_device_id mtk_jpeg_match[] = { { .compatible = "mediatek,mt8173-jpgdec", @@ -1962,11 +1994,11 @@ static const struct of_device_id mtk_jpeg_match[] = { }, { .compatible = "mediatek,mt8196-jpgenc", - .data = &mtk8195_jpegenc_drvdata, + .data = &mtk8196_jpegenc_drvdata, }, { .compatible = "mediatek,mt8196-jpgdec", - .data = &mtk8195_jpegdec_drvdata, + .data = &mtk8196_jpegdec_drvdata, }, {}, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index 80c94cdf28b5f..e372a60706a39 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -74,6 +74,7 @@ enum mtk_jpeg_ctx_state { * @cap_q_default_fourcc: capture queue default fourcc * @multi_core: mark jpeg hw is multi_core or not * @jpeg_worker: jpeg dec or enc worker + * @support_34bit: flag to check if support dma_address 34bit */ struct mtk_jpeg_variant { struct clk_bulk_data *clks; @@ -90,6 +91,7 @@ struct mtk_jpeg_variant { u32 cap_q_default_fourcc; bool multi_core; void (*jpeg_worker)(struct work_struct *work); + bool support_34bit; }; struct mtk_jpeg_src_buf { diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 7e4ba610528d3..d5103d51e7cc8 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -297,7 +297,7 @@ void mtk_jpeg_dec_set_smmu_sid(struct device *dev, int hwid) EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_smmu_sid); static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w, - u8 yscale_h, u8 uvscale_w, u8 uvscale_h) + u8 yscale_h, u8 uvscale_w, u8 uvscale_h) { u32 val; @@ -306,23 +306,43 @@ static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w, writel(val, base + JPGDEC_REG_BRZ_FACTOR); } -static void mtk_jpeg_dec_set_dst_bank0(void __iomem *base, u32 addr_y, - u32 addr_u, u32 addr_v) +static void mtk_jpeg_dec_set_dst_bank0(void __iomem *base, bool support_34bit, + dma_addr_t addr_y, dma_addr_t addr_u, dma_addr_t addr_v) { + u32 val; + mtk_jpeg_verify_align(addr_y, 16, JPGDEC_REG_DEST_ADDR0_Y); writel(addr_y, base + JPGDEC_REG_DEST_ADDR0_Y); mtk_jpeg_verify_align(addr_u, 16, JPGDEC_REG_DEST_ADDR0_U); writel(addr_u, base + JPGDEC_REG_DEST_ADDR0_U); mtk_jpeg_verify_align(addr_v, 16, JPGDEC_REG_DEST_ADDR0_V); writel(addr_v, base + JPGDEC_REG_DEST_ADDR0_V); + if (support_34bit) { + val = upper_32_bits(addr_y) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR0_Y_EXT); + val = upper_32_bits(addr_u) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR0_U_EXT); + val = upper_32_bits(addr_v) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR0_V_EXT); + } } -static void mtk_jpeg_dec_set_dst_bank1(void __iomem *base, u32 addr_y, - u32 addr_u, u32 addr_v) +static void mtk_jpeg_dec_set_dst_bank1(void __iomem *base, bool support_34bit, + dma_addr_t addr_y, dma_addr_t addr_u, dma_addr_t addr_v) { + u32 val; + writel(addr_y, base + JPGDEC_REG_DEST_ADDR1_Y); writel(addr_u, base + JPGDEC_REG_DEST_ADDR1_U); writel(addr_v, base + JPGDEC_REG_DEST_ADDR1_V); + if (support_34bit) { + val = upper_32_bits(addr_y) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR1_Y_EXT); + val = upper_32_bits(addr_u) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR1_U_EXT); + val = upper_32_bits(addr_v) & 0x3; + writel(val, base + JPGDEC_REG_DEST_ADDR1_V_EXT); + } } static void mtk_jpeg_dec_set_mem_stride(void __iomem *base, u32 stride_y, @@ -349,18 +369,31 @@ static void mtk_jpeg_dec_set_dec_mode(void __iomem *base, u32 mode) writel(mode & 0x03, base + JPGDEC_REG_OPERATION_MODE); } -static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem *base, u32 ptr) +static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem *base, + bool support_34bit, dma_addr_t ptr) { + u32 val; + mtk_jpeg_verify_align(ptr, 16, JPGDEC_REG_FILE_BRP); writel(ptr, base + JPGDEC_REG_FILE_BRP); + if (support_34bit) { + val = upper_32_bits(ptr) & 0x3; + writel(val, base + JPGDEC_REG_FILE_BRP_EXT); + } } -static void mtk_jpeg_dec_set_bs_info(void __iomem *base, u32 addr, u32 size, - u32 bitstream_size) +static void mtk_jpeg_dec_set_bs_info(void __iomem *base, bool support_34bit, + dma_addr_t addr, u32 size, u32 bitstream_size) { + u32 val; + mtk_jpeg_verify_align(addr, 16, JPGDEC_REG_FILE_ADDR); mtk_jpeg_verify_align(size, 128, JPGDEC_REG_FILE_TOTAL_SIZE); writel(addr, base + JPGDEC_REG_FILE_ADDR); + if (support_34bit) { + val = upper_32_bits(addr) & 0x3; + writel(val, base + JPGDEC_REG_FILE_ADDR_EXT); + } writel(size, base + JPGDEC_REG_FILE_TOTAL_SIZE); writel(bitstream_size, base + JPGDEC_REG_BIT_STREAM_SIZE); } @@ -431,6 +464,7 @@ static void mtk_jpeg_dec_set_sampling_factor(void __iomem *base, u32 comp_num, } void mtk_jpeg_dec_set_config(void __iomem *base, + bool support_34bits, struct mtk_jpeg_dec_param *cfg, u32 bitstream_size, struct mtk_jpeg_bs *bs, @@ -440,8 +474,9 @@ void mtk_jpeg_dec_set_config(void __iomem *base, mtk_jpeg_dec_set_dec_mode(base, 0); mtk_jpeg_dec_set_comp0_du(base, cfg->unit_num); mtk_jpeg_dec_set_total_mcu(base, cfg->total_mcu); - mtk_jpeg_dec_set_bs_info(base, bs->str_addr, bs->size, bitstream_size); - mtk_jpeg_dec_set_bs_write_ptr(base, bs->end_addr); + mtk_jpeg_dec_set_bs_info(base, support_34bits, bs->str_addr, + bs->size, bitstream_size); + mtk_jpeg_dec_set_bs_write_ptr(base, support_34bits, bs->end_addr); mtk_jpeg_dec_set_du_membership(base, cfg->membership, 1, (cfg->comp_num == 1) ? 1 : 0); mtk_jpeg_dec_set_comp_id(base, cfg->comp_id[0], cfg->comp_id[1], @@ -459,9 +494,9 @@ void mtk_jpeg_dec_set_config(void __iomem *base, cfg->mem_stride[1]); mtk_jpeg_dec_set_img_stride(base, cfg->img_stride[0], cfg->img_stride[1]); - mtk_jpeg_dec_set_dst_bank0(base, fb->plane_addr[0], + mtk_jpeg_dec_set_dst_bank0(base, support_34bits, fb->plane_addr[0], fb->plane_addr[1], fb->plane_addr[2]); - mtk_jpeg_dec_set_dst_bank1(base, 0, 0, 0); + mtk_jpeg_dec_set_dst_bank1(base, support_34bits, 0, 0, 0); mtk_jpeg_dec_set_dma_group(base, cfg->dma_mcu, cfg->dma_group, cfg->dma_last_mcu); mtk_jpeg_dec_set_pause_mcu_idx(base, cfg->total_mcu); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h index 8facd8b22323e..24d6cb14906bd 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h @@ -71,6 +71,7 @@ int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param); u32 mtk_jpeg_dec_get_int_status(void __iomem *dec_reg_base); u32 mtk_jpeg_dec_enum_result(u32 irq_result); void mtk_jpeg_dec_set_config(void __iomem *base, + bool support_34bits, struct mtk_jpeg_dec_param *cfg, u32 bitstream_size, struct mtk_jpeg_bs *bs, diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_reg.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_reg.h index 27b7711ca3419..e94f52de7c690 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_reg.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_reg.h @@ -46,5 +46,13 @@ #define JPGDEC_REG_INTERRUPT_STATUS 0x0274 #define JPGDEC_REG_STATUS 0x0278 #define JPGDEC_REG_BIT_STREAM_SIZE 0x0344 +#define JPGDEC_REG_DEST_ADDR0_Y_EXT 0x0360 +#define JPGDEC_REG_DEST_ADDR0_U_EXT 0x0364 +#define JPGDEC_REG_DEST_ADDR0_V_EXT 0x0368 +#define JPGDEC_REG_DEST_ADDR1_Y_EXT 0x036c +#define JPGDEC_REG_DEST_ADDR1_U_EXT 0x0370 +#define JPGDEC_REG_DEST_ADDR1_V_EXT 0x0374 +#define JPGDEC_REG_FILE_ADDR_EXT 0x0378 +#define JPGDEC_REG_FILE_BRP_EXT 0x037c #endif /* _MTK_JPEG_REG_H */ diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index b6da3d06a6711..4f775760033b0 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -89,10 +89,16 @@ void mtk_jpeg_enc_set_smmu_sid(struct device *dev, int hwid) } EXPORT_SYMBOL_GPL(mtk_jpeg_enc_set_smmu_sid); -u32 mtk_jpeg_enc_get_file_size(void __iomem *base) +u32 mtk_jpeg_enc_get_file_size(void __iomem *base, bool support_34bit) { - return readl(base + JPEG_ENC_DMA_ADDR0) - - readl(base + JPEG_ENC_DST_ADDR0); + /* + * The dma addr0 to be shifted left by 2 bits + * for support greater than 4G address. + */ + u32 value = (support_34bit) ? 2 : 0; + + return (readl(base + JPEG_ENC_DMA_ADDR0) << value) - + readl(base + JPEG_ENC_DST_ADDR0); } EXPORT_SYMBOL_GPL(mtk_jpeg_enc_get_file_size); @@ -102,6 +108,13 @@ void mtk_jpeg_enc_start(void __iomem *base) value = readl(base + JPEG_ENC_CTRL); value |= JPEG_ENC_CTRL_INT_EN_BIT | JPEG_ENC_CTRL_ENABLE_BIT; + /* + * Enable hw auto padding for height is not 16 alignment, + * to ensure decoder downscales is correct. + */ + value |= JPEG_ENC_CTRL_RDMA_PADDING_EN; + value |= JPEG_ENC_CTRL_RDMA_RIGHT_PADDING_EN; + value &= ~JPEG_ENC_CTRL_RDMA_PADDING_0_EN; writel(value, base + JPEG_ENC_CTRL); } EXPORT_SYMBOL_GPL(mtk_jpeg_enc_start); @@ -111,14 +124,25 @@ void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, { int i; dma_addr_t dma_addr; + u32 val; + bool support_34bit = ctx->jpeg->variant->support_34bit; for (i = 0; i < src_buf->num_planes; i++) { dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + src_buf->planes[i].data_offset; - if (!i) + if (!i) { writel(dma_addr, base + JPEG_ENC_SRC_LUMA_ADDR); - else + if (support_34bit) { + val = upper_32_bits(dma_addr) & 0x3; + writel(val, base + JPEG_ENC_SRC_LUMA_ADDR_EXT); + } + } else { writel(dma_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); + if (support_34bit) { + val = upper_32_bits(dma_addr) & 0x3; + writel(val, base + JPEG_ENC_SRC_CHROMA_ADDR_EXT); + } + } } } EXPORT_SYMBOL_GPL(mtk_jpeg_set_enc_src); @@ -130,6 +154,8 @@ void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, size_t size; u32 dma_addr_offset; u32 dma_addr_offsetmask; + u32 val; + bool support_34bit = ctx->jpeg->variant->support_34bit; dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); dma_addr_offset = ctx->enable_exif ? MTK_JPEG_MAX_EXIF_SIZE : 0; @@ -139,7 +165,15 @@ void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, writel(dma_addr_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); writel(dma_addr_offsetmask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); writel(dma_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); + if (support_34bit) { + val = upper_32_bits(dma_addr) & 0x3; + writel(val, base + JPEG_ENC_DEST_ADDR0_EXT); + } writel((dma_addr + size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); + if (support_34bit) { + val = upper_32_bits(dma_addr + size) & 0x3; + writel(val, base + JPEG_ENC_STALL_ADDR0_EXT); + } } EXPORT_SYMBOL_GPL(mtk_jpeg_set_enc_dst); @@ -305,7 +339,8 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) if (!(irq_status & JPEG_ENC_INT_STATUS_DONE)) dev_warn(jpeg->dev, "Jpg Enc occurs unknown Err."); - result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base, + ctx->jpeg->variant->support_34bit); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); buf_state = VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h index a999ddfba2260..02de5ada407e3 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h @@ -68,6 +68,15 @@ #define JPEG_ENC_DCM_CTRL 0x300 #define JPEG_ENC_CODEC_SEL 0x314 #define JPEG_ENC_ULTRA_THRES 0x318 +#define JPEG_ENC_SRC_LUMA_ADDR_EXT 0x584 +#define JPEG_ENC_SRC_CHROMA_ADDR_EXT 0x588 +#define JPEG_ENC_Q_TBL_ADDR_EXT 0x58C +#define JPEG_ENC_DEST_ADDR0_EXT 0x590 +#define JPEG_ENC_STALL_ADDR0_EXT 0x594 + +#define JPEG_ENC_CTRL_RDMA_PADDING_EN (1 << 20) +#define JPEG_ENC_CTRL_RDMA_RIGHT_PADDING_EN (1 << 29) +#define JPEG_ENC_CTRL_RDMA_PADDING_0_EN (1 << 30) /** * struct mtk_jpeg_enc_qlt - JPEG encoder quality data @@ -80,7 +89,7 @@ struct mtk_jpeg_enc_qlt { }; void mtk_jpeg_enc_reset(void __iomem *base); -u32 mtk_jpeg_enc_get_file_size(void __iomem *base); +u32 mtk_jpeg_enc_get_file_size(void __iomem *base, bool support_34bit); void mtk_jpeg_enc_start(void __iomem *enc_reg_base); void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, struct vb2_buffer *src_buf); -- GitLab From 288794fbff6fe57e1f31b4067abaabab88aa3245 Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Fri, 13 Sep 2024 18:17:50 +0800 Subject: [PATCH 354/456] CHROMIUM: media: jpeg: fix jpeg hw count setting fix jpeg hw count setting BUG=b:377474081 TEST=meetcuj test UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: I541376dd45cbbd10139ee87b15f30e7673c4af12 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073875 Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 12 ++++++++---- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 6b98fe07e9624..4636f90ac3f10 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1473,7 +1473,7 @@ static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) int i; spin_lock_irqsave(&jpeg->hw_lock, flags); - for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) { + for (i = 0; i < jpeg->variant->max_hw_count; i++) { comp_jpeg = jpeg->enc_hw_dev[i]; if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { hw_id = i; @@ -1520,7 +1520,7 @@ static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx) int i; spin_lock_irqsave(&jpeg->hw_lock, flags); - for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) { + for (i = 0; i < jpeg->variant->max_hw_count; i++) { comp_jpeg = jpeg->dec_hw_dev[i]; if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { hw_id = i; @@ -1603,7 +1603,7 @@ static void mtk_jpegenc_worker(struct work_struct *work) jpeg_work); struct mtk_jpeg_dev *jpeg = ctx->jpeg; - for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) + for (i = 0; i < jpeg->variant->max_hw_count; i++) comp_jpeg[i] = jpeg->enc_hw_dev[i]; i = 0; @@ -1701,7 +1701,7 @@ static void mtk_jpegdec_worker(struct work_struct *work) struct mtk_jpeg_fb fb; unsigned long flags; - for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) + for (i = 0; i < jpeg->variant->max_hw_count; i++) comp_jpeg[i] = jpeg->dec_hw_dev[i]; i = 0; @@ -1926,6 +1926,7 @@ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = { .out_q_default_fourcc = V4L2_PIX_FMT_YUYV, .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, .multi_core = true, + .max_hw_count = 2, .jpeg_worker = mtk_jpegenc_worker, }; @@ -1939,6 +1940,7 @@ static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = { .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, .multi_core = true, + .max_hw_count = 3, .jpeg_worker = mtk_jpegdec_worker, }; @@ -1952,6 +1954,7 @@ static struct mtk_jpeg_variant mtk8196_jpegenc_drvdata = { .out_q_default_fourcc = V4L2_PIX_FMT_YUYV, .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, .multi_core = true, + .max_hw_count = 2, .jpeg_worker = mtk_jpegenc_worker, .support_34bit = true, }; @@ -1966,6 +1969,7 @@ static const struct mtk_jpeg_variant mtk8196_jpegdec_drvdata = { .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, .multi_core = true, + .max_hw_count = 2, .jpeg_worker = mtk_jpegdec_worker, .support_34bit = true, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index e372a60706a39..7b2454cdbe9e5 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -90,6 +90,7 @@ struct mtk_jpeg_variant { u32 out_q_default_fourcc; u32 cap_q_default_fourcc; bool multi_core; + u32 max_hw_count; void (*jpeg_worker)(struct work_struct *work); bool support_34bit; }; -- GitLab From 748d2650c057ecda791e6b2d3efecc353679fa09 Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Mon, 30 Sep 2024 16:29:36 +0800 Subject: [PATCH 355/456] CHROMIUM: media: jpeg: fix jpegdec resolution handle flow 1. jpegdec driver would send an event when jpeg resolution changing 2. The app may not process this event in time. At this time, the jpeg driver can no longer decode and needs to wait for the resolution change event to be processed. BUG=b:377474081 TEST=meetcuj test UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: Id5d7a83e0250cc51b6bce818ad09c510432a7d55 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073873 Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 38 +++++++++++-------- .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 1 + .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 1 + 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 4636f90ac3f10..c6dbc3e3a1d4c 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -720,10 +720,9 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb) plane_fmt = q_data->pix_mp.plane_fmt[i]; if (ctx->enable_exif && q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG) - vb2_set_plane_payload(vb, i, plane_fmt.sizeimage + - MTK_JPEG_MAX_EXIF_SIZE); + vb2_set_plane_payload(vb, i, vb2_plane_size(vb, i)); else - vb2_set_plane_payload(vb, i, plane_fmt.sizeimage); + vb2_set_plane_payload(vb, i, vb2_plane_size(vb, i)); } return 0; @@ -871,14 +870,21 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); src_buf = mtk_jpeg_vb2_to_srcbuf(&vb->vb2_buf); - mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param); + if (IS_ERR_OR_NULL(src_buf)) { + v4l2_err(&ctx->jpeg->v4l2_dev, + "Error!! src_buf is IS_ERR_OR_NULL: 0x%p\n", src_buf); + } else { + mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param); + } ctx->state = MTK_JPEG_RUNNING; } else if (V4L2_TYPE_IS_OUTPUT(q->type)) { ctx->state = MTK_JPEG_INIT; } - while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) - v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + while (atomic_read(&q->owned_by_drv_count)) { + if ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + } } static const struct vb2_ops mtk_jpeg_dec_qops = { @@ -925,8 +931,8 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, for (i = 0; i < dst_buf->num_planes; i++) { if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) { dev_err(ctx->jpeg->dev, - "buffer size is underflow (%lu < %u)\n", - vb2_plane_size(dst_buf, 0), + "i: %d, buffer size is underflow (%lu < %u)\n", + i, vb2_plane_size(dst_buf, i), param->comp_size[i]); return -EINVAL; } @@ -1736,11 +1742,15 @@ retry_select: if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) { - mtk_jpeg_queue_src_chg_event(ctx); + mtk_jpeg_set_queue_data(ctx, &jpeg_src_buf->dec_param); ctx->state = MTK_JPEG_SOURCE_CHANGE; + mtk_jpeg_queue_src_chg_event(ctx); goto getbuf_fail; } + if (ctx->state == MTK_JPEG_SOURCE_CHANGE) + goto getbuf_fail; + jpeg_src_buf->curr_ctx = ctx; jpeg_src_buf->frame_num = ctx->total_frame_num; jpeg_dst_buf->curr_ctx = ctx; @@ -1761,17 +1771,11 @@ retry_select: goto clk_end; } - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, - &dst_buf->vb2_buf, &fb)) { - dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n", - __func__, __LINE__); + &dst_buf->vb2_buf, &fb)) goto setdst_end; - } schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); @@ -1789,6 +1793,8 @@ retry_select: &bs, &fb); mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base); + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index d5103d51e7cc8..767fd119624b7 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -540,6 +540,7 @@ static void mtk_jpegdec_put_buf(struct mtk_jpegdec_comp_dev *jpeg) v4l2_m2m_buf_done(&tmp_dst_done_buf->b, VB2_BUF_STATE_DONE); ctx->last_done_frame_num++; + break; } } } diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 4f775760033b0..5413f0bd071e1 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -283,6 +283,7 @@ static void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg) v4l2_m2m_buf_done(&tmp_dst_done_buf->b, VB2_BUF_STATE_DONE); ctx->last_done_frame_num++; + break; } } } -- GitLab From d6f648a635189d95595f12a2b4905a892d0c890f Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Tue, 14 Jan 2025 18:31:58 +0800 Subject: [PATCH 356/456] CHROMIUM: media: jpeg: fix jpegdec buffer and job finishing flow 1. fix jpegdec dst buffer setting 2. fix jpegdec job finish setting BUG=b:376642442 TEST=meetcuj test UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: Idc43fec842e058890d7045f4a6f21c538a71ecf9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6172674 Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 38 ++++++++++++------- .../platform/mediatek/jpeg/mtk_jpeg_core.h | 3 +- .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 11 ++++++ .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 9 +++++ 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index c6dbc3e3a1d4c..a8e0e2c8b7d18 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -848,8 +848,12 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; struct vb2_v4l2_buffer *vb; + if (jpeg->variant->multi_core) + wait_event(jpeg->hw_wq, (atomic_read(&ctx->buf_list_cnt) == 0)); + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); } @@ -857,6 +861,7 @@ static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; struct vb2_v4l2_buffer *vb; /* @@ -864,6 +869,9 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) * Before STREAMOFF, we still have to return the old resolution and * subsampling. Update capture queue when the stream is off. */ + if (jpeg->variant->multi_core) + wait_event(jpeg->hw_wq, (atomic_read(&ctx->buf_list_cnt) == 0)); + if (ctx->state == MTK_JPEG_SOURCE_CHANGE && V4L2_TYPE_IS_CAPTURE(q->type)) { struct mtk_jpeg_src_buf *src_buf; @@ -881,10 +889,8 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) ctx->state = MTK_JPEG_INIT; } - while (atomic_read(&q->owned_by_drv_count)) { - if ((vb = mtk_jpeg_buf_remove(ctx, q->type))) - v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); - } + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); } static const struct vb2_ops mtk_jpeg_dec_qops = { @@ -1101,7 +1107,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; dst_vq->drv_priv = ctx; - dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); dst_vq->ops = jpeg->variant->qops; dst_vq->mem_ops = &vb2_dma_contig_memops; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; @@ -1184,6 +1190,7 @@ static int mtk_jpeg_open(struct file *file) v4l2_fh_init(&ctx->fh, vfd); file->private_data = &ctx->fh; v4l2_fh_add(&ctx->fh); + atomic_set(&ctx->buf_list_cnt, 0); ctx->jpeg = jpeg; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, @@ -1566,6 +1573,11 @@ static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx, return 0; } +static void jpeg_buf_queue_inc(struct mtk_jpeg_ctx *ctx) +{ + atomic_inc(&ctx->buf_list_cnt); +} + static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) { struct mtk_jpeg_ctx *ctx; @@ -1654,9 +1666,6 @@ retry_select: goto enc_end; } - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); @@ -1677,6 +1686,9 @@ retry_select: &src_buf->vb2_buf); mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base); mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base); + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + jpeg_buf_queue_inc(ctx); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); @@ -1738,7 +1750,6 @@ retry_select: v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); - jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) { @@ -1751,11 +1762,6 @@ retry_select: if (ctx->state == MTK_JPEG_SOURCE_CHANGE) goto getbuf_fail; - jpeg_src_buf->curr_ctx = ctx; - jpeg_src_buf->frame_num = ctx->total_frame_num; - jpeg_dst_buf->curr_ctx = ctx; - jpeg_dst_buf->frame_num = ctx->total_frame_num; - mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf); ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); if (ret < 0) { @@ -1781,6 +1787,9 @@ retry_select: msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); + jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); + jpeg_dst_buf->curr_ctx = ctx; + jpeg_dst_buf->frame_num = ctx->total_frame_num; ctx->total_frame_num++; mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base); #if IS_ENABLED(CONFIG_ARM_SMMU_V3) @@ -1795,6 +1804,7 @@ retry_select: mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + jpeg_buf_queue_inc(ctx); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index 7b2454cdbe9e5..8287ab010c320 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -96,10 +96,10 @@ struct mtk_jpeg_variant { }; struct mtk_jpeg_src_buf { - u32 frame_num; struct vb2_v4l2_buffer b; struct list_head list; u32 bs_size; + u32 frame_num; struct mtk_jpeg_dec_param dec_param; struct mtk_jpeg_ctx *curr_ctx; @@ -316,6 +316,7 @@ struct mtk_jpeg_ctx { /* spinlock protecting the encode done buffer */ spinlock_t done_queue_lock; u32 last_done_frame_num; + atomic_t buf_list_cnt; }; #endif /* _MTK_JPEG_CORE_H */ diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 767fd119624b7..c8e7d87deffa5 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -547,6 +547,11 @@ static void mtk_jpegdec_put_buf(struct mtk_jpegdec_comp_dev *jpeg) spin_unlock_irqrestore(&ctx->done_queue_lock, flags); } +static void jpeg_buf_queue_dec(struct mtk_jpeg_ctx *ctx) +{ + atomic_dec(&ctx->buf_list_cnt); +} + static void mtk_jpegdec_timeout_work(struct work_struct *work) { enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; @@ -555,9 +560,11 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work) job_timeout_work.work); struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_ctx *ctx; src_buf = cjpeg->hw_param.src_buffer; dst_buf = cjpeg->hw_param.dst_buffer; + ctx = cjpeg->hw_param.curr_ctx; v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); mtk_jpeg_dec_reset(cjpeg->reg_base); @@ -568,6 +575,7 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work) wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(cjpeg); + jpeg_buf_queue_dec(ctx); } static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) @@ -575,12 +583,14 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_jpeg_src_buf *jpeg_src_buf; enum vb2_buffer_state buf_state; + struct mtk_jpeg_ctx *ctx; u32 dec_irq_ret; u32 irq_status; int i; struct mtk_jpegdec_comp_dev *jpeg = priv; struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev; + ctx = jpeg->hw_param.curr_ctx; cancel_delayed_work(&jpeg->job_timeout_work); @@ -606,6 +616,7 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) buf_state = VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(jpeg); + jpeg_buf_queue_dec(ctx); pm_runtime_put(jpeg->dev); clk_disable_unprepare(jpeg->jdec_clk.clks->clk); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 5413f0bd071e1..cc5010de6a44c 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -290,6 +290,11 @@ static void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg) spin_unlock_irqrestore(&ctx->done_queue_lock, flags); } +static void jpeg_buf_queue_dec(struct mtk_jpeg_ctx *ctx) +{ + atomic_dec(&ctx->buf_list_cnt); +} + static void mtk_jpegenc_timeout_work(struct work_struct *work) { struct delayed_work *dly_work = to_delayed_work(work); @@ -300,9 +305,11 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work) struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev; enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_ctx *ctx; src_buf = cjpeg->hw_param.src_buffer; dst_buf = cjpeg->hw_param.dst_buffer; + ctx = cjpeg->hw_param.curr_ctx; v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); mtk_jpeg_enc_reset(cjpeg->reg_base); @@ -313,6 +320,7 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work) wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(cjpeg); + jpeg_buf_queue_dec(ctx); } static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) @@ -346,6 +354,7 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) buf_state = VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(jpeg); + jpeg_buf_queue_dec(ctx); pm_runtime_put(jpeg->dev); clk_disable_unprepare(jpeg->venc_clk.clks->clk); -- GitLab From ed677373a4177dd12ac2b3030a01fe6abcf2146b Mon Sep 17 00:00:00 2001 From: Kyrie Wu Date: Tue, 19 Nov 2024 13:33:04 +0800 Subject: [PATCH 357/456] CHROMIUM: media: jpeg: fix jpeg clk suspend/resume setting fix jpeg clk suspend and resume setting BUG=b:376642442 TEST=meetcuj test UPSTREAM-TASK=b:379040143 Signed-off-by: Kyrie Wu Change-Id: Ic2f56f72f879ac3a1b9639c35b60a8c6b46c0670 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073877 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 38 +++------ .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 82 +++++++++++++++++-- .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 81 +++++++++++++++++- 3 files changed, 167 insertions(+), 34 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index a8e0e2c8b7d18..4a397a0251ad5 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1122,16 +1122,20 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) { int ret; - ret = clk_bulk_prepare_enable(jpeg->variant->num_clks, - jpeg->variant->clks); - if (ret) - dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret); + if (!jpeg->variant->multi_core) { + ret = clk_bulk_prepare_enable(jpeg->variant->num_clks, + jpeg->variant->clks); + if (ret) + dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret); + } } static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) { - clk_bulk_disable_unprepare(jpeg->variant->num_clks, - jpeg->variant->clks); + if (!jpeg->variant->multi_core) { + clk_bulk_disable_unprepare(jpeg->variant->num_clks, + jpeg->variant->clks); + } } static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) @@ -1659,13 +1663,6 @@ retry_select: goto enc_end; } - ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk); - if (ret) { - dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n", - __func__, __LINE__); - goto enc_end; - } - schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); @@ -1763,25 +1760,18 @@ retry_select: goto getbuf_fail; mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf); - ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); + ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev); if (ret < 0) { dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n", __func__, __LINE__); goto dec_end; } - ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk); - if (ret) { - dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n", - __func__, __LINE__); - goto clk_end; - } - mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) - goto setdst_end; + goto set_dst_fail; schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); @@ -1810,9 +1800,7 @@ retry_select: return; -setdst_end: - clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk); -clk_end: +set_dst_fail: pm_runtime_put(comp_jpeg[hw_id]->dev); dec_end: v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index c8e7d87deffa5..239b26d487ce4 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -568,14 +568,13 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work) v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); mtk_jpeg_dec_reset(cjpeg->reg_base); - clk_disable_unprepare(cjpeg->jdec_clk.clks->clk); - pm_runtime_put(cjpeg->dev); cjpeg->hw_state = MTK_JPEG_HW_IDLE; atomic_inc(&master_jpeg->hw_rdy); wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(cjpeg); jpeg_buf_queue_dec(ctx); + pm_runtime_put(cjpeg->dev); } static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) @@ -617,12 +616,10 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(jpeg); jpeg_buf_queue_dec(ctx); - pm_runtime_put(jpeg->dev); - clk_disable_unprepare(jpeg->jdec_clk.clks->clk); - jpeg->hw_state = MTK_JPEG_HW_IDLE; wake_up(&master_jpeg->hw_wq); atomic_inc(&master_jpeg->hw_rdy); + pm_runtime_put(jpeg->dev); return IRQ_HANDLED; } @@ -704,15 +701,90 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); pm_runtime_enable(&pdev->dev); + ret = devm_clk_bulk_get(dev->dev, + jpegdec_clk->clk_num, + jpegdec_clk->clks); + if (ret) { + dev_err(&pdev->dev, "Failed to init clk\n"); + return ret; + } + + return 0; +} + +static int mtk_jpeg_clk_on(struct mtk_jpegdec_comp_dev *jpeg) +{ + int ret; + + ret = clk_bulk_prepare_enable(jpeg->jdec_clk.clk_num, jpeg->jdec_clk.clks); + if (ret) + dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n", + __func__, __LINE__); + + return ret; +} + +static void mtk_jpeg_clk_off(struct mtk_jpegdec_comp_dev *jpeg) +{ + clk_bulk_disable_unprepare(jpeg->jdec_clk.clk_num, jpeg->jdec_clk.clks); +} + +static __maybe_unused int mtk_jpegdec_pm_suspend(struct device *dev) +{ + struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev); + + mtk_jpeg_clk_off(jpeg); return 0; } +static __maybe_unused int mtk_jpegdec_pm_resume(struct device *dev) +{ + int ret; + + struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev); + + ret = mtk_jpeg_clk_on(jpeg); + if (ret) + dev_err(jpeg->dev, "%s : %d, mtk_jpeg_clk_on fail\n", + __func__, __LINE__); + + return ret; +} + +static __maybe_unused int mtk_jpegdec_suspend(struct device *dev) +{ + struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev); + + v4l2_m2m_suspend(jpeg->master_dev->m2m_dev); + return pm_runtime_force_suspend(dev); +} + +static __maybe_unused int mtk_jpegdec_resume(struct device *dev) +{ + struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + + v4l2_m2m_resume(jpeg->master_dev->m2m_dev); + return ret; +} + + +static const struct dev_pm_ops mtk_jpegdec_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mtk_jpegdec_suspend, mtk_jpegdec_resume) + SET_RUNTIME_PM_OPS(mtk_jpegdec_pm_suspend, mtk_jpegdec_pm_resume, NULL) +}; + static struct platform_driver mtk_jpegdec_hw_driver = { .probe = mtk_jpegdec_hw_probe, .driver = { .name = "mtk-jpegdec-hw", .of_match_table = mtk_jpegdec_hw_ids, + .pm = &mtk_jpegdec_pm_ops, }, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index cc5010de6a44c..86e597d100122 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -313,14 +313,13 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work) v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); mtk_jpeg_enc_reset(cjpeg->reg_base); - clk_disable_unprepare(cjpeg->venc_clk.clks->clk); - pm_runtime_put(cjpeg->dev); cjpeg->hw_state = MTK_JPEG_HW_IDLE; atomic_inc(&master_jpeg->hw_rdy); wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(cjpeg); jpeg_buf_queue_dec(ctx); + pm_runtime_put(cjpeg->dev); } static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) @@ -355,12 +354,11 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(jpeg); jpeg_buf_queue_dec(ctx); - pm_runtime_put(jpeg->dev); - clk_disable_unprepare(jpeg->venc_clk.clks->clk); jpeg->hw_state = MTK_JPEG_HW_IDLE; wake_up(&master_jpeg->hw_wq); atomic_inc(&master_jpeg->hw_rdy); + pm_runtime_put(jpeg->dev); return IRQ_HANDLED; } @@ -440,15 +438,90 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); pm_runtime_enable(&pdev->dev); + ret = devm_clk_bulk_get(dev->dev, + jpegenc_clk->clk_num, + jpegenc_clk->clks); + if (ret) { + dev_err(&pdev->dev, "Failed to init clk\n"); + return ret; + } + + return 0; +} + +static int mtk_jpeg_clk_on(struct mtk_jpegenc_comp_dev *jpeg) +{ + int ret; + + ret = clk_bulk_prepare_enable(jpeg->venc_clk.clk_num, jpeg->venc_clk.clks); + if (ret) + dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n", + __func__, __LINE__); + + return ret; +} + +static void mtk_jpeg_clk_off(struct mtk_jpegenc_comp_dev *jpeg) +{ + clk_bulk_disable_unprepare(jpeg->venc_clk.clk_num, jpeg->venc_clk.clks); +} + +static __maybe_unused int mtk_jpegenc_pm_suspend(struct device *dev) +{ + struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev); + + mtk_jpeg_clk_off(jpeg); return 0; } +static __maybe_unused int mtk_jpegenc_pm_resume(struct device *dev) +{ + int ret; + + struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev); + + ret = mtk_jpeg_clk_on(jpeg); + if (ret) + dev_err(jpeg->dev, "%s : %d, mtk_jpeg_clk_on fail\n", + __func__, __LINE__); + + return ret; +} + +static __maybe_unused int mtk_jpegenc_suspend(struct device *dev) +{ + struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev); + + v4l2_m2m_suspend(jpeg->master_dev->m2m_dev); + return pm_runtime_force_suspend(dev); +} + +static __maybe_unused int mtk_jpegenc_resume(struct device *dev) +{ + struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + + v4l2_m2m_resume(jpeg->master_dev->m2m_dev); + return ret; +} + + +static const struct dev_pm_ops mtk_jpegenc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mtk_jpegenc_suspend, mtk_jpegenc_resume) + SET_RUNTIME_PM_OPS(mtk_jpegenc_pm_suspend, mtk_jpegenc_pm_resume, NULL) +}; + static struct platform_driver mtk_jpegenc_hw_driver = { .probe = mtk_jpegenc_hw_probe, .driver = { .name = "mtk-jpegenc-hw", .of_match_table = mtk_jpegenc_drv_ids, + .pm = &mtk_jpegenc_pm_ops, }, }; -- GitLab From 68a006aa3d9793ffa15c39b761916f4421ca1af0 Mon Sep 17 00:00:00 2001 From: Langyan Ye Date: Wed, 25 Dec 2024 10:01:09 +0800 Subject: [PATCH 358/456] FROMGIT: drm/panel-edp: Add B140UAN04.4 and MNE007QS3-7 The raw edid for B140UAN04.4 panel is: 00 ff ff ff ff ff ff 00 06 af b3 a7 00 00 00 00 0c 22 01 04 a5 1e 13 78 03 cb 55 91 57 5a 91 29 1c 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 f4 3c 80 b8 70 b0 24 40 10 10 3e 00 2d bc 10 00 00 18 00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 fe 00 41 55 4f 0a 20 20 20 20 20 20 20 20 20 00 00 00 fe 00 42 31 34 30 55 41 4e 30 34 2e 34 20 0a 01 46 70 20 79 02 00 22 00 14 87 61 02 85 7f 07 b7 00 0f 80 0f 00 af 04 23 00 02 00 0d 00 25 01 09 87 61 02 87 61 02 28 3c 80 81 00 15 74 1a 00 00 03 01 28 3c 00 00 53 50 53 50 3c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0b 90 The raw edid for MNE007QS3-7 panel is: 00 ff ff ff ff ff ff 00 0e 77 48 14 00 00 00 00 34 20 01 04 a5 1e 13 78 03 2c c5 94 5c 59 95 29 1e 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ea 3d 80 c8 70 b0 2e 40 30 20 36 00 2e bd 10 00 00 1a 00 00 00 fd 00 28 3c 4b 4b 10 01 0a 20 20 20 20 20 20 00 00 00 fe 00 43 53 4f 54 20 54 39 0a 20 20 20 20 20 00 00 00 fe 00 4d 4e 45 30 30 37 51 53 33 2d 37 0a 20 00 df Signed-off-by: Langyan Ye [dianders: adjusted sort ordering] Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20241225020109.1051449-1-yelangyan@huaqin.corp-partner.google.com (cherry picked from commit 0ca6d6058852857c628b479f1e7aad3386036bdb https://anongit.freedesktop.org/git/drm/drm-misc.git/ drm-misc-next) BUG=b:383955078 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Ib97e7527268dba3dada00f30a3dcb2909d5d8dc9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6176620 Reviewed-by: Sean Paul Tested-by: Langyan Ye Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/gpu/drm/panel/panel-edp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index c7f243871b621..8ad1bcb28fd4a 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -2007,6 +2007,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0x73aa, &delay_200_500_e50, "B116XTN02.3"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xa199, &delay_200_500_e50, "B116XAN06.1"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0xa7b3, &delay_200_500_e50, "B140UAN04.4"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xc4b4, &delay_200_500_e50, "B116XAT04.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xd497, &delay_200_500_e50, "B120XAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xf390, &delay_200_500_e50, "B140XTN07.7"), @@ -2096,6 +2097,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'S', 'W', 0x1100, &delay_200_500_e80_d50, "MNB601LS1-1"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1104, &delay_200_500_e50, "MNB601LS1-4"), + EDP_PANEL_ENTRY('C', 'S', 'W', 0x1448, &delay_200_500_e50, "MNE007QS3-7"), EDP_PANEL_ENTRY('H', 'K', 'C', 0x2d51, &delay_200_500_e200, "Unknown"), EDP_PANEL_ENTRY('H', 'K', 'C', 0x2d5b, &delay_200_500_e200, "MB116AN01"), -- GitLab From ec8dea63c9a41739b51416b3fff0fedb81944f0d Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Thu, 7 Mar 2024 14:54:25 +0800 Subject: [PATCH 359/456] CHROMIUM: phy: mediatek: pcie: Add PCIe phy support for MT8196 Add PCIe phy support for MT8196. BUG=b:383258443 UPSTREAM-TASK=b:379039276 TEST=build pass and boot to shell Signed-off-by: Jianjun Wang Change-Id: Ib4ebad8a8b188299142ebcc2730e2aa28204ccf0 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073732 Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/phy/mediatek/phy-mtk-pcie.c | 481 +++++++++++++++++++++++++++- 1 file changed, 477 insertions(+), 4 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-pcie.c b/drivers/phy/mediatek/phy-mtk-pcie.c index a2f69d6c72f08..50567e4f07b75 100644 --- a/drivers/phy/mediatek/phy-mtk-pcie.c +++ b/drivers/phy/mediatek/phy-mtk-pcie.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,156 @@ #include "phy-mtk-io.h" +/* PHY sif registers */ +#define PEXTP_DIG_GLB_00 0x0 +#define PRB_SEL_TO_101 0x101 +#define PEXTP_DIG_GLB_04 0x4 +#define PEXTP_DIG_GLB_08 0x8 +#define CKGEN_PRB_SEL_TO_A000A 0xa000a +#define PEXTP_DIG_GLB_10 0x10 +#define PEXTP_DIG_GLB_20 0x20 +#define RG_XTP_BYPASS_PIPE_RST BIT(4) +#define RG_XTP_BYPASS_PIPE_RST_RC BIT(17) +#define PEXTP_DIG_GLB_28 0x28 +#define RG_XTP_PCIE_MODE BIT(3) +#define RG_XTP_PHY_CLKREQ_N_IN GENMASK(13, 12) +#define PEXTP_DIG_GLB_30 0x30 +#define RG_XTP_CKBG_STAL_STB_T_SEL GENMASK(25, 16) +#define CKBG_STAL_STB_T_SEL_TO_0 0x0 +#define PEXTP_DIG_GLB_38 0x38 +#define RG_XTP_TPLL_SET_STB_T_SEL GENMASK(7, 2) +#define TPLL_SET_STB_T_SEL_TO_3F 0x3f +#define RG_XTP_TPLL_PWE_ON_STB_T_SEL GENMASK(9, 8) +#define TPLL_PWE_ON_STB_T_SEL_TO_3 0x3 +#define PEXTP_DIG_GLB_50 0x50 +#define RG_XTP_CKM_EN_L1S0 BIT(13) +#define RG_XTP_CKM_EN_L1S1 BIT(14) +#define PEXTP_DIG_PROBE_OUT 0xd0 +#define PEXTP_DIG_GLB_70 0x70 +#define RG_XTP_PIPE_UPDT BIT(4) +#define RG_XTP_PIPE_TX_SWING BIT(22) +#define PEXTP_DIG_GLB_A4 0xa4 +#define RG_XTP_FRC_TX_SWING BIT(1) +#define PEXTP_DIG_GLB_D0 0xd0 +#define PEXTP_DIG_GLB_F4 0xf4 +#define RG_XTP_TPLL_ISO_EN_STB_T_SEL GENMASK(13, 12) +#define TPLL_ISO_EN_STB_T_SEL_TO_3 0x3 + +#define PEXTP_DIG_TPLL0_78 0x1078 +#define RG_XTP_VCO_CFIX_EN_GEN1 GENMASK(21, 20) +#define RG_XTP_VCO_CFIX_EN_GEN2 GENMASK(23, 22) +#define HIGH_VCO_FREQ 0x0 + +/* PHY ANA GLB registers */ +#define PEXTP_DIG_LN_TRX_70 0x3070 +#define RG_XTP_LN_FRC_RX_AEQ_DFETP5 BIT(21) +#define RG_XTP_LN_FRC_RX_AEQ_DFETP4 BIT(29) + +#define PEXTP_DIG_LN_TRX_74 0x3074 +#define RG_XTP_LN_FRC_RX_AEQ_DFETP3 BIT(6) +#define RG_XTP_LN_FRC_RX_AEQ_DFETP2 BIT(14) +#define RG_XTP_LN_FRC_RX_AEQ_DFETP1 BIT(23) + +#define PEXTP_DIG_LN_TRX_E8 0x30e8 +#define RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4 GENMASK(14, 12) +#define CTLE_CSEL_GEN4_TO_1 0x1 + +#define PEXTP_DIG_LN_RX_F0 0x50f0 +#define RG_XTP_LN_RX_GEN1_CTLE1_CSEL GENMASK(3, 0) +#define GEN1_CTLE1_CSEL_TO_D 0xd +#define RG_XTP_LN_RX_GEN2_CTLE1_CSEL GENMASK(7, 4) +#define GEN2_CTLE1_CSEL_TO_D 0xd +#define RG_XTP_LN_RX_GEN3_CTLE1_CSEL GENMASK(11, 8) +#define GEN3_CTLE1_CSEL_TO_D 0xd + +#define PEXTP_DIG_LN_RX2_04 0x6004 +#define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3 GENMASK(21, 16) +#define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4 GENMASK(29, 24) +#define AEQ_EGEQ_RATIO_GEN3_TO_22 0x16 +#define AEQ_EGEQ_RATIO_GEN4_TO_22 0x16 + +#define PEXTP_DIG_LN_RX2_94 0x6094 +#define RG_XTP_LN_RX_CDR_DLY_OFF_GEN3 BIT(6) +#define RG_XTP_LN_RX_CDR_DLY_OFF_GEN4 BIT(7) + +#define PEXTP_DIG_LN_RX2_A4 0x60a4 +#define RG_XTP_LN_RX_AEQ_OFORCE_GEN3 GENMASK(7, 1) +#define AEQ_OFORCE_GEN3_TO_7F 0x7f +#define RG_XTP_LN_RX_AEQ_OFORCE_GEN4 GENMASK(19, 13) +#define AEQ_OFORCE_GEN4_TO_7F 0x7f + #define PEXTP_ANA_GLB_00_REG 0x9000 /* Internal Resistor Selection of TX Bias Current */ #define EFUSE_GLB_INTR_SEL GENMASK(28, 24) +#define PEXTP_ANA_GLB_10_REG 0x9010 +#define GLB_TPLL0_RST_DLY GENMASK(5, 4) +#define RESET_COUNTER_SELECT_2 0x2 + +#define PEXTP_ANA_GLB_14_REG 0x9014 +#define GLB_TPLL0_DEBUG_SEL GENMASK(13, 11) + +#define PEXTP_ANA_GLB_6 (PEXTP_ANA_GLB_00_REG + 0x18) +#define PEXTP_ANA_GLB_9 (PEXTP_ANA_GLB_00_REG + 0x24) + +#define PEXTP_ANA_GLB_2C 0x902c +#define RG_XTP_GLB_TPLL1_RESERVE_0 GENMASK(7, 0) +#define TPLL1_P_PATH_GAIN_TO_05 0xf1 + +#define PEXTP_ANA_GLB_50_REG 0x9050 +#define PEXTP_ANA_GLB_54_REG 0x9054 + +#define PEXTP_ANA_GLB_60 0x9060 +#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(5, 0) + +#define PEXTP_ANA_GLB_C0 0x90c0 +#define RG_XTP_GLB_BIAS_V2V_VTRIM GENMASK(9, 6) + + #define PEXTP_ANA_LN0_TRX_REG 0xa000 +#define RG_XTP_LN_TX_RESERVE GENMASK(31, 16) +#define LN_TX_RESERVE_TO_8 0x8 + +#define PEXTP_ANA_LN_TRX_C 0xa00c +#define RG_XTP_LN_TX_RSWN_IMPSEL GENMASK(20, 16) + +#define PEXTP_ANA_LN_TRX_34 0xA034 +#define RG_XTP_LN_RX_FE BIT(15) + +#define PEXTP_ANA_LN_TRX_6C 0xA06C +#define RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE GENMASK(14, 13) +#define AEQ_CTLE_ERR_TYPE_H15 0x0 +#define AEQ_CTLE_ERR_TYPE_H15_H25 0x1 + +#define PEXTP_ANA_LN_TRX_A0 0xa0a0 +#define RG_XTP_LN_TX_IMPSEL_PMOS GENMASK(4, 0) +#define TX_IMPSEL_PMOS_TO_A 0xa +#define RG_XTP_LN_TX_IMPSEL_NMOS GENMASK(11, 7) +#define TX_IMPSEL_NMOS_TO_9 0x9 +#define RG_XTP_LN_RX_IMPSEL GENMASK(15, 12) + +#define PEXTP_ANA_LN_TRX_A8 0xa0a8 +#define RG_XTP_LN_RX_LEQ_RL_CTLE_CAL GENMASK(6, 2) +#define RG_XTP_LN_RX_LEQ_RL_VGA_CAL GENMASK(11, 7) +#define RG_XTP_LN_RX_LEQ_RL_DFE_CAL GENMASK(23, 19) + +#define PEXTP_DIG_LN_TX_RSWN_4 0xb004 +#define PEXTP_DIG_LN_TX_RSWN_8 0xb008 +#define PEXTP_DIG_LN_TX_RSWN_C 0xb00c +#define PEXTP_DIG_LN_TX_RSWN_10 0xb010 +#define PEXTP_DIG_LN_TX_RSWN_14 0xb014 +#define PEXTP_DIG_LN_TX_RSWN_18 0xb018 +#define RG_XTP_LN_TX_MGX_PX_CM1 GENMASK(5, 0) +#define MGX_PX_CM1_TO_1 0x1 +#define MGX_PX_CM1_TO_2 0x2 +#define RG_XTP_LN_TX_MGX_PX_C0 GENMASK(13, 8) +#define MGX_PX_C0_TO_A 0xa +#define MGX_PX_C0_TO_B 0xb +#define MGX_PX_C0_TO_C 0xc +#define RG_XTP_LN_TX_MGX_PX_CP1 GENMASK(21, 16) +#define MGX_PX_CP1_TO_1 0x1 +#define MGX_PX_CP1_TO_2 0x2 + #define PEXTP_ANA_TX_REG 0x04 /* TX PMOS impedance selection */ @@ -32,6 +178,37 @@ #define PEXTP_ANA_LANE_OFFSET 0x100 +/* PHY ckm regsiters */ +#define XTP_CKM_DA_REG_38 0x38 +#define RG_CKM_BIAS_WAIT_PRD GENMASK(21, 16) +#define CKM_BIAS_WAIT_PRD_TO_4US 0x4 +#define XTP_CKM_DA_REG_3C 0x3C +#define RG_CKM_PADCK_REQ GENMASK(13, 12) +#define RG_CKM_PROBE_SEL GENMASK(19, 17) +#define XTP_CKM_DA_REG_44 0x44 +#define XTP_CKM_DA_REG_D4 0xD4 +#define RG_CKM_CKTX_IMPSEL_PMOS GENMASK(19, 16) +#define RG_CKM_CKTX_IMPSEL_NMOS GENMASK(23, 20) +#define RG_CKM_CKTX_IMPSEL_SW GENMASK(27, 24) + +/* EFUSE */ +#define SPHY3_EFUSE_MAX_LANE 2 + +#define EFUSE_GLB_BIAS_INTR_CTRL GENMASK(5, 0) +#define EFUSE_GLB_BIAS_V2V_VTRIM GENMASK(9, 6) +#define EFUSE_CKM_CKTX_IMPSEL_PMOS GENMASK(13, 10) +#define EFUSE_CKM_CKTX_IMPSEL_NMOS GENMASK(17, 14) +#define EFUSE_CKM_CKTX_IMPSEL_RMID GENMASK(21, 18) +#define EFUSE_LN0_TX_RSWN_IMPSEL GENMASK(26, 22) +#define EFUSE_LN1_TX_RSWN_IMPSEL GENMASK(31, 27) + +#define EFUSE_LN_RX_LEQ_RL_CTLE_CAL GENMASK(4, 0) +#define EFUSE_LN_RX_LEQ_RL_VGA_CAL GENMASK(9, 5) +#define EFUSE_LN_RX_LEQ_RL_DEF_CAL GENMASK(14, 10) +#define EFUSE_LN_RX_IMPSEl GENMASK(18, 15) +#define EFUSE_LN_TX_IMPSEL_PMOS GENMASK(24, 20) +#define EFUSE_LN_TX_IMPSEL_NMOS GENMASK(29, 25) + /** * struct mtk_pcie_lane_efuse - eFuse data for each lane * @tx_pmos: TX PMOS impedance selection data @@ -54,6 +231,7 @@ struct mtk_pcie_lane_efuse { struct mtk_pcie_phy_data { int num_lanes; bool sw_efuse_supported; + int (*phy_init)(struct phy *phy); }; /** @@ -62,6 +240,9 @@ struct mtk_pcie_phy_data { * @phy: pointer to generic phy * @sif_base: IO mapped register base address of system interface * @data: pointer to SoC dependent data + * @num_lanes: supported lane numbers + * @num_clks: PCIe PHY clocks count + * @clks: PCIe PHY clocks * @sw_efuse_en: software eFuse enable status * @efuse_glb_intr: internal resistor selection of TX bias current data * @efuse: pointer to eFuse data for each lane @@ -70,10 +251,16 @@ struct mtk_pcie_phy { struct device *dev; struct phy *phy; void __iomem *sif_base; + void __iomem *ckm_base; const struct mtk_pcie_phy_data *data; + int num_lanes; + int num_clks; + struct clk_bulk_data *clks; bool sw_efuse_en; u32 efuse_glb_intr; + u32 *efuse_info; + size_t efuse_info_len; struct mtk_pcie_lane_efuse *efuse; }; @@ -110,7 +297,21 @@ static void mtk_pcie_efuse_set_lane(struct mtk_pcie_phy *pcie_phy, static int mtk_pcie_phy_init(struct phy *phy) { struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy); - int i; + int i, ret; + + if (pcie_phy->data->phy_init) { + ret = pcie_phy->data->phy_init(phy); + if (ret) + return ret; + } + + if (pcie_phy->num_clks > 0) { + ret = clk_bulk_prepare_enable(pcie_phy->num_clks, pcie_phy->clks); + if (ret) { + dev_info(pcie_phy->dev, "failed to enable clocks\n"); + return ret; + } + } if (!pcie_phy->sw_efuse_en) return 0; @@ -119,14 +320,25 @@ static int mtk_pcie_phy_init(struct phy *phy) mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_GLB_00_REG, EFUSE_GLB_INTR_SEL, pcie_phy->efuse_glb_intr); - for (i = 0; i < pcie_phy->data->num_lanes; i++) + for (i = 0; i < pcie_phy->num_lanes; i++) mtk_pcie_efuse_set_lane(pcie_phy, i); return 0; } +static int mtk_pcie_phy_exit(struct phy *phy) +{ + struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy); + + if (pcie_phy->num_clks > 0) + clk_bulk_disable_unprepare(pcie_phy->num_clks, pcie_phy->clks); + + return 0; +} + static const struct phy_ops mtk_pcie_phy_ops = { .init = mtk_pcie_phy_init, + .exit = mtk_pcie_phy_exit, .owner = THIS_MODULE, }; @@ -181,12 +393,12 @@ static int mtk_pcie_read_efuse(struct mtk_pcie_phy *pcie_phy) pcie_phy->sw_efuse_en = true; - pcie_phy->efuse = devm_kzalloc(dev, pcie_phy->data->num_lanes * + pcie_phy->efuse = devm_kzalloc(dev, pcie_phy->num_lanes * sizeof(*pcie_phy->efuse), GFP_KERNEL); if (!pcie_phy->efuse) return -ENOMEM; - for (i = 0; i < pcie_phy->data->num_lanes; i++) { + for (i = 0; i < pcie_phy->num_lanes; i++) { ret = mtk_pcie_efuse_read_for_lane(pcie_phy, i); if (ret) return ret; @@ -211,16 +423,38 @@ static int mtk_pcie_phy_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(pcie_phy->sif_base), "Failed to map phy-sif base\n"); + pcie_phy->ckm_base = devm_platform_ioremap_resource_byname(pdev, "ckm"); + if (IS_ERR(pcie_phy->ckm_base)) { + dev_info(dev, "Failed to get ckm resource\n"); + pcie_phy->ckm_base = NULL; + } + pcie_phy->phy = devm_phy_create(dev, dev->of_node, &mtk_pcie_phy_ops); if (IS_ERR(pcie_phy->phy)) return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), "Failed to create PCIe phy\n"); pcie_phy->dev = dev; + + /* Some PHY may not have clks, only print warning in that case */ + pcie_phy->num_clks = devm_clk_bulk_get_all(dev, &pcie_phy->clks); + if (pcie_phy->num_clks < 0) + dev_info(dev, "Failed to get clocks, pcie-phy may not works as expects\n"); + pcie_phy->data = of_device_get_match_data(dev); if (!pcie_phy->data) return dev_err_probe(dev, -EINVAL, "Failed to get phy data\n"); + ret = of_property_read_u32(dev->of_node, "num-lanes", &pcie_phy->num_lanes); + if (ret) { + if (pcie_phy->data->num_lanes) { + pcie_phy->num_lanes = pcie_phy->data->num_lanes; + } else { + dev_info(dev, "Failed to get num-lanes, set as 1\n"); + pcie_phy->num_lanes = 1; + } + } + if (pcie_phy->data->sw_efuse_supported) { /* * Failed to read the efuse data is not a fatal problem, @@ -241,13 +475,252 @@ static int mtk_pcie_phy_probe(struct platform_device *pdev) return 0; } +static int mtk_pcie_sphy3_calibrate(struct phy *phy) +{ + struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy); + struct device *dev = pcie_phy->dev; + u32 i; + + /* Efuse info is null or chip without calibrated data */ + if (!pcie_phy->efuse_info || !pcie_phy->efuse_info_len || !pcie_phy->efuse_info[0]) + goto no_efuse_info; + + /* Current SPHY3 efuse architecture only support 1 or 2 lane */ + if (pcie_phy->num_lanes > SPHY3_EFUSE_MAX_LANE) { + dev_info(dev, "The number of lanes %d out of range\n", pcie_phy->num_lanes); + goto no_efuse_info; + } + + if ((pcie_phy->num_lanes + 1) * sizeof(u32) > pcie_phy->efuse_info_len) { + dev_info(dev, "efuse info length = %zu error\n", pcie_phy->efuse_info_len); + goto no_efuse_info; + } + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_GLB_60, + RG_XTP_GLB_BIAS_INTR_CTRL, + FIELD_GET(EFUSE_GLB_BIAS_INTR_CTRL, pcie_phy->efuse_info[0])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_GLB_C0, + RG_XTP_GLB_BIAS_V2V_VTRIM, + FIELD_GET(EFUSE_GLB_BIAS_V2V_VTRIM, pcie_phy->efuse_info[0])); + + mtk_phy_update_field(pcie_phy->ckm_base + XTP_CKM_DA_REG_D4, + RG_CKM_CKTX_IMPSEL_PMOS, + FIELD_GET(EFUSE_CKM_CKTX_IMPSEL_PMOS, pcie_phy->efuse_info[0])); + + mtk_phy_update_field(pcie_phy->ckm_base + XTP_CKM_DA_REG_D4, + RG_CKM_CKTX_IMPSEL_NMOS, + FIELD_GET(EFUSE_CKM_CKTX_IMPSEL_NMOS, pcie_phy->efuse_info[0])); + + mtk_phy_update_field(pcie_phy->ckm_base + XTP_CKM_DA_REG_D4, + RG_CKM_CKTX_IMPSEL_SW, + FIELD_GET(EFUSE_CKM_CKTX_IMPSEL_RMID, pcie_phy->efuse_info[0])); + + for (i = 0; i < pcie_phy->num_lanes; i++) { + if (i) + mtk_phy_update_field(pcie_phy->sif_base + + PEXTP_ANA_LN_TRX_C + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_RSWN_IMPSEL, + FIELD_GET(EFUSE_LN1_TX_RSWN_IMPSEL, pcie_phy->efuse_info[0])); + else + mtk_phy_update_field(pcie_phy->sif_base + + PEXTP_ANA_LN_TRX_C + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_RSWN_IMPSEL, + FIELD_GET(EFUSE_LN0_TX_RSWN_IMPSEL, pcie_phy->efuse_info[0])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A8 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_RX_LEQ_RL_CTLE_CAL, + FIELD_GET(EFUSE_LN_RX_LEQ_RL_CTLE_CAL, pcie_phy->efuse_info[i+1])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A8 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_RX_LEQ_RL_VGA_CAL, + FIELD_GET(EFUSE_LN_RX_LEQ_RL_VGA_CAL, pcie_phy->efuse_info[i+1])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A8 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_RX_LEQ_RL_DFE_CAL, + FIELD_GET(EFUSE_LN_RX_LEQ_RL_DEF_CAL, pcie_phy->efuse_info[i+1])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A0 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_RX_IMPSEL, + FIELD_GET(EFUSE_LN_RX_IMPSEl, pcie_phy->efuse_info[i+1])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A0 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_IMPSEL_PMOS, + FIELD_GET(EFUSE_LN_TX_IMPSEL_PMOS, pcie_phy->efuse_info[i+1])); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A0 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_IMPSEL_NMOS, + FIELD_GET(EFUSE_LN_TX_IMPSEL_NMOS, pcie_phy->efuse_info[i+1])); + } + + dev_info(dev, "Calibration successful\n"); + + return 0; + +no_efuse_info: + dev_info(dev, "No calibration info\n"); + + /* To prevent potential EM problem, apply this setting + * if no Efuse calibration + */ + for (i = 0; i < pcie_phy->num_lanes; i++) { + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A0 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_IMPSEL_PMOS, + TX_IMPSEL_PMOS_TO_A); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_A0 + + i * PEXTP_ANA_LANE_OFFSET, + RG_XTP_LN_TX_IMPSEL_NMOS, + TX_IMPSEL_NMOS_TO_9); + } + + return 0; +} + +static int mtk_pcie_phy_init_8196(struct phy *phy) +{ + struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy); + struct device *dev = pcie_phy->dev; + u32 i; + + if (!pcie_phy->ckm_base) { + dev_info(dev, "phy-ckm base not found, please check\n"); + return -EINVAL; + } + + /* RC mode need adjust PHY sequence to fix L1.2 issue */ + mtk_phy_update_field(pcie_phy->ckm_base + XTP_CKM_DA_REG_38, RG_CKM_BIAS_WAIT_PRD, + CKM_BIAS_WAIT_PRD_TO_4US); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_GLB_38, RG_XTP_TPLL_SET_STB_T_SEL, + TPLL_SET_STB_T_SEL_TO_3F); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_GLB_38, RG_XTP_TPLL_PWE_ON_STB_T_SEL, + TPLL_PWE_ON_STB_T_SEL_TO_3); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_GLB_F4, RG_XTP_TPLL_ISO_EN_STB_T_SEL, + TPLL_ISO_EN_STB_T_SEL_TO_3); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_GLB_30, RG_XTP_CKBG_STAL_STB_T_SEL, + CKBG_STAL_STB_T_SEL_TO_0); + + mtk_phy_clear_bits(pcie_phy->sif_base + PEXTP_DIG_GLB_50, RG_XTP_CKM_EN_L1S1); + + /* not bypass pipe reset, pipe reset will reset TPLL */ + mtk_phy_clear_bits(pcie_phy->sif_base + PEXTP_DIG_GLB_20, RG_XTP_BYPASS_PIPE_RST_RC); + + dev_info(dev, "CKM_38=%#x, GLB_20=%#x, GLB_30=%#x, GLB_38=%#x, GLB_F4=%#x\n", + readl_relaxed(pcie_phy->ckm_base + XTP_CKM_DA_REG_38), + readl_relaxed(pcie_phy->sif_base + PEXTP_DIG_GLB_20), + readl_relaxed(pcie_phy->sif_base + PEXTP_DIG_GLB_30), + readl_relaxed(pcie_phy->sif_base + PEXTP_DIG_GLB_38), + readl_relaxed(pcie_phy->sif_base + PEXTP_DIG_GLB_F4)); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_GLB_2C, RG_XTP_GLB_TPLL1_RESERVE_0, + TPLL1_P_PATH_GAIN_TO_05); + + for (i = 0; i < pcie_phy->num_lanes; i++) { + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_6C + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE, + AEQ_CTLE_ERR_TYPE_H15_H25); + + mtk_phy_set_bits(pcie_phy->sif_base + PEXTP_ANA_LN_TRX_34 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_FE); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TRX_E8 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4, + CTLE_CSEL_GEN4_TO_1); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_RX_F0 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_GEN1_CTLE1_CSEL, + GEN1_CTLE1_CSEL_TO_D); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_RX_F0 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_GEN2_CTLE1_CSEL, + GEN2_CTLE1_CSEL_TO_D); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_RX_F0 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_GEN3_CTLE1_CSEL, + GEN3_CTLE1_CSEL_TO_D); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_RX2_04 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3, + AEQ_EGEQ_RATIO_GEN3_TO_22); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_RX2_04 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4, + AEQ_EGEQ_RATIO_GEN4_TO_22); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_4 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_A); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_4 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_CP1, + MGX_PX_CP1_TO_2); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_8 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_B); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_8 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_CP1, + MGX_PX_CP1_TO_1); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_C + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_C); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_10 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_B); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_10 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_CM1, + MGX_PX_CM1_TO_1); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_14 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_B); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_14 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_CM1, + MGX_PX_CM1_TO_1); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_18 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_C0, + MGX_PX_C0_TO_A); + + mtk_phy_update_field(pcie_phy->sif_base + PEXTP_DIG_LN_TX_RSWN_18 + + i * PEXTP_ANA_LANE_OFFSET, RG_XTP_LN_TX_MGX_PX_CM1, + MGX_PX_CM1_TO_2); + } + + return mtk_pcie_sphy3_calibrate(phy); +} + static const struct mtk_pcie_phy_data mt8195_data = { .num_lanes = 2, .sw_efuse_supported = true, }; +static const struct mtk_pcie_phy_data mt8196_data = { + .sw_efuse_supported = false, + .phy_init = mtk_pcie_phy_init_8196, +}; + static const struct of_device_id mtk_pcie_phy_of_match[] = { { .compatible = "mediatek,mt8195-pcie-phy", .data = &mt8195_data }, + { .compatible = "mediatek,mt8196-pcie-phy", .data = &mt8196_data }, { }, }; MODULE_DEVICE_TABLE(of, mtk_pcie_phy_of_match); -- GitLab From beb767e463bbe1e8539533f6169843c75533ec4d Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Fri, 10 Jan 2025 15:23:32 -0800 Subject: [PATCH 360/456] Revert "firmware_loader: Block path traversal" This reverts commit f0e5311aa8022107d63c54e2f03684ec097d1394. Reason for revert: The logic that allows the kernel to load firmware requires the path to originate in /lib/firmware, but ChromeOS ships some peripheral firmware in DLCs at /run/imageloader. Upstream linux does not have any need to load firmware files from anywhere other than /lib/firmware, and so they have landed a change that prevents firmware loading from any other location, breaking ChromeOS firmware loading from DLC, for instance on the FM350 modem. This CL reverts the upstream patch, to fix the regression in ChromeOS. This revert is only necessary on FM350 up to R134, as the FM350 modem will not load its firmware through the kernel on newer milestones. BUG=b:389154359,b:383128339 TEST=Verified FM350 firmware can be loaded from DLC on R134 Change-Id: I5c117f35da23a802e0b03187c5dfd8fcc2a793f2 Signed-off-by: Daniel Winkler Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6169026 Reviewed-by: Aleksander Morgado Signed-off-by: Hubert Mazur --- drivers/base/firmware_loader/main.c | 30 ----------------------------- 1 file changed, 30 deletions(-) diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 8fb223f325ff2..c0d50783b833f 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -915,26 +915,6 @@ static void fw_log_firmware_info(const struct firmware *fw, const char *name, {} #endif -/* - * Reject firmware file names with ".." path components. - * There are drivers that construct firmware file names from device-supplied - * strings, and we don't want some device to be able to tell us "I would like to - * be sent my firmware from ../../../etc/shadow, please". - * - * Search for ".." surrounded by either '/' or start/end of string. - * - * This intentionally only looks at the firmware name, not at the firmware base - * directory or at symlink contents. - */ -static bool name_contains_dotdot(const char *name) -{ - size_t name_len = strlen(name); - - return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 || - strstr(name, "/../") != NULL || - (name_len >= 3 && strcmp(name+name_len-3, "/..") == 0); -} - /* called from request_firmware() and request_firmware_work_func() */ static int _request_firmware(const struct firmware **firmware_p, const char *name, @@ -955,14 +935,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name, goto out; } - if (name_contains_dotdot(name)) { - dev_warn(device, - "Firmware load for '%s' refused, path contains '..' component\n", - name); - ret = -EINVAL; - goto out; - } - ret = _request_firmware_prepare(&fw, name, device, buf, size, offset, opt_flags); if (ret <= 0) /* error or already assigned */ @@ -1040,8 +1012,6 @@ out: * @name will be used as $FIRMWARE in the uevent environment and * should be distinctive enough not to be confused with any other * firmware image for this or any other device. - * It must not contain any ".." path components - "foo/bar..bin" is - * allowed, but "foo/../bar.bin" is not. * * Caller must hold the reference count of @device. * -- GitLab From d6487707a9697bbf641c509b5aa248547551efd4 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 3 Jul 2024 18:12:42 +0200 Subject: [PATCH 361/456] BACKPORT: PCI: mediatek-gen3: Add mtk_gen3_pcie_pdata data structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce mtk_gen3_pcie_pdata data structure in order to define multiple callbacks for each supported SoC. This is a preliminary patch to introduce EN7581 PCIe support. Link: https://lore.kernel.org/linux-pci/c193d1a87505d045e2e0ef33317bce17012ee095.1720022580.git.lorenzo@kernel.org Signed-off-by: Lorenzo Bianconi Signed-off-by: Krzysztof Wilczyński Tested-by: Zhengping Zhang Reviewed-by: AngeloGioacchino Del Regno Acked-by: Jianjun Wang (cherry picked from commit dc869a40d73ee6e9f47d683690ae507e30e56044) Conflicts: drivers/pci/controller/pcie-mediatek-gen3.c BUG=b:383258443 TEST=build pass and boot to shell Change-Id: Idf5a9be0a0ed9ef180fa42440fa1e731b338086b Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6171047 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 24 ++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 65d32ac5a091e..a34a10e24d347 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -111,6 +111,16 @@ static const char *const dsc_power_supplies[] = { "pcie12v", }; +struct mtk_gen3_pcie; + +/** + * struct mtk_gen3_pcie_pdata - differentiate between host generations + * @power_up: pcie power_up callback + */ +struct mtk_gen3_pcie_pdata { + int (*power_up)(struct mtk_gen3_pcie *pcie); +}; + /** * struct mtk_msi_set - MSI information for each set * @base: IO mapped register base @@ -146,6 +156,7 @@ struct mtk_msi_set { * @msi_sets: MSI sets information * @lock: lock protecting IRQ bit map * @msi_irq_in_use: bit map for assigned MSI IRQ + * @soc: pointer to SoC-dependent operations */ struct mtk_gen3_pcie { struct device *dev; @@ -170,6 +181,8 @@ struct mtk_gen3_pcie { struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; struct mutex lock; DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); + + const struct mtk_gen3_pcie_pdata *soc; }; /* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */ @@ -1002,7 +1015,7 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) usleep_range(10, 20); /* Don't touch the hardware registers before power up */ - err = mtk_pcie_power_up(pcie); + err = pcie->soc->power_up(pcie); if (err) return err; @@ -1037,6 +1050,7 @@ static int mtk_pcie_probe(struct platform_device *pdev) pcie = pci_host_bridge_priv(host); pcie->dev = dev; + pcie->soc = device_get_match_data(dev); platform_set_drvdata(pdev, pcie); err = mtk_pcie_setup(pcie); @@ -1152,7 +1166,7 @@ static int mtk_pcie_resume_noirq(struct device *dev) struct mtk_gen3_pcie *pcie = dev_get_drvdata(dev); int err; - err = mtk_pcie_power_up(pcie); + err = pcie->soc->power_up(pcie); if (err) return err; @@ -1172,8 +1186,12 @@ static const struct dev_pm_ops mtk_pcie_pm_ops = { mtk_pcie_resume_noirq) }; +static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = { + .power_up = mtk_pcie_power_up, +}; + static const struct of_device_id mtk_pcie_of_match[] = { - { .compatible = "mediatek,mt8192-pcie" }, + { .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 }, {}, }; MODULE_DEVICE_TABLE(of, mtk_pcie_of_match); -- GitLab From 816bc5862c552a64951e4794e8a78925e2162c55 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 3 Jul 2024 18:12:43 +0200 Subject: [PATCH 362/456] BACKPORT: PCI: mediatek-gen3: Rely on reset_bulk APIs for PHY reset lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use reset_bulk APIs to manage PHY reset lines. This is a preliminary patch in order to add Airoha EN7581 PCIe support. Link: https://lore.kernel.org/linux-pci/3ceb83bc0defbcf868521f8df4b9100e55ec2614.1720022580.git.lorenzo@kernel.org Signed-off-by: Lorenzo Bianconi Signed-off-by: Krzysztof Wilczyński Tested-by: Zhengping Zhang Reviewed-by: AngeloGioacchino Del Regno Acked-by: Jianjun Wang (cherry picked from commit ee9eabbe3f0f0c7458d89840add97e54d4e0bccf) Conflicts: drivers/pci/controller/pcie-mediatek-gen3.c BUG=b:383258443 TEST=build pass and boot to shell Change-Id: Ifd1b8df96f3790d6713a73fa3ecea1315a2aaa7d Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6171048 Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 45 +++++++++++++++------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index a34a10e24d347..8e3755bbd87a6 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -104,6 +104,8 @@ #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) +#define MAX_NUM_PHY_RESETS 1 + /* Downstream Component power supplies used by MediaTek PCIe */ static const char *const dsc_power_supplies[] = { "pcie1v8", @@ -116,9 +118,14 @@ struct mtk_gen3_pcie; /** * struct mtk_gen3_pcie_pdata - differentiate between host generations * @power_up: pcie power_up callback + * @phy_resets: phy reset lines SoC data. */ struct mtk_gen3_pcie_pdata { int (*power_up)(struct mtk_gen3_pcie *pcie); + struct { + const char *id[MAX_NUM_PHY_RESETS]; + int num_resets; + } phy_resets; }; /** @@ -139,7 +146,7 @@ struct mtk_msi_set { * @base: IO mapped register base * @reg_base: physical register base * @mac_reset: MAC reset control - * @phy_reset: PHY reset control + * @phy_resets: PHY reset controllers * @phy: PHY controller block * @clks: PCIe clocks * @num_clks: PCIe clocks count for this port @@ -163,7 +170,7 @@ struct mtk_gen3_pcie { void __iomem *base; phys_addr_t reg_base; struct reset_control *mac_reset; - struct reset_control *phy_reset; + struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS]; struct phy *phy; struct clk_bulk_data *clks; int num_clks; @@ -807,10 +814,10 @@ static int mtk_pcie_setup_irq(struct mtk_gen3_pcie *pcie) static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) { + int i, ret, num_resets = pcie->soc->phy_resets.num_resets; struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); struct resource *regs; - int ret, i; regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcie-mac"); if (!regs) @@ -823,12 +830,12 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) pcie->reg_base = regs->start; - pcie->phy_reset = devm_reset_control_get_optional_exclusive(dev, "phy"); - if (IS_ERR(pcie->phy_reset)) { - ret = PTR_ERR(pcie->phy_reset); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get PHY reset\n"); + for (i = 0; i < num_resets; i++) + pcie->phy_resets[i].id = pcie->soc->phy_resets.id[i]; + ret = devm_reset_control_bulk_get_optional_shared(dev, num_resets, pcie->phy_resets); + if (ret) { + dev_err(dev, "failed to get PHY bulk reset\n"); return ret; } @@ -940,7 +947,11 @@ static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie) } /* PHY power on and enable pipe clock */ - reset_control_deassert(pcie->phy_reset); + err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); + if (err) { + dev_err(dev, "failed to deassert PHYs\n"); + return err; + } err = phy_init(pcie->phy); if (err) { @@ -976,7 +987,7 @@ err_clk_init: err_phy_on: phy_exit(pcie->phy); err_phy_init: - reset_control_assert(pcie->phy_reset); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); mtk_pcie_dsc_power_down(pcie); return err; @@ -992,7 +1003,7 @@ static void mtk_pcie_power_down(struct mtk_gen3_pcie *pcie) phy_power_off(pcie->phy); phy_exit(pcie->phy); - reset_control_assert(pcie->phy_reset); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); if (!pcie->dev->power.is_suspended || !device_wakeup_path(pcie->dev)) mtk_pcie_dsc_power_down(pcie); @@ -1006,11 +1017,17 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) if (err) return err; + /* + * Deassert the line in order to avoid unbalance in deassert_count + * counter since the bulk is shared. + */ + reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); /* * The controller may have been left out of reset by the bootloader * so make sure that we get a clean start by asserting resets here. */ - reset_control_assert(pcie->phy_reset); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); + reset_control_assert(pcie->mac_reset); usleep_range(10, 20); @@ -1188,6 +1205,10 @@ static const struct dev_pm_ops mtk_pcie_pm_ops = { static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = { .power_up = mtk_pcie_power_up, + .phy_resets = { + .id[0] = "phy", + .num_resets = 1, + }, }; static const struct of_device_id mtk_pcie_of_match[] = { -- GitLab From a8d4f0e168138f22476518a289124ac30d360426 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 3 Jul 2024 18:12:44 +0200 Subject: [PATCH 363/456] BACKPORT: PCI: mediatek-gen3: Add Airoha EN7581 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce support for Airoha EN7581 PCIe controller to mediatek-gen3 PCIe controller driver. Link: https://lore.kernel.org/linux-pci/aca00bd672ee576ad96d279414fc0835ff31f637.1720022580.git.lorenzo@kernel.org Signed-off-by: Lorenzo Bianconi Signed-off-by: Krzysztof Wilczyński Tested-by: Zhengping Zhang Reviewed-by: AngeloGioacchino Del Regno Acked-by: Jianjun Wang (cherry picked from commit f6ab898356dd70f267c49045a79d28ea5cf5e43e) Conflicts: drivers/pci/controller/pcie-mediatek-gen3.c BUG=b:383258443 TEST=build pass and boot to shell Change-Id: I108af76735b4a69fdc3c0f9b197932e9cab76452 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6171049 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/Kconfig | 2 +- drivers/pci/controller/pcie-mediatek-gen3.c | 113 +++++++++++++++++++- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index c0c3f28249907..f4451a9b99335 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -196,7 +196,7 @@ config PCIE_MEDIATEK config PCIE_MEDIATEK_GEN3 tristate "MediaTek Gen3 PCIe controller" - depends on ARCH_MEDIATEK || COMPILE_TEST + depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST depends on PCI_MSI help Adds support for PCIe Gen3 MAC controller for MediaTek SoCs. diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 8e3755bbd87a6..9761bb08c443f 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -6,7 +6,9 @@ * Author: Jianjun Wang */ +#include #include +#include #include #include #include @@ -17,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -33,6 +37,12 @@ #define PCI_CLASS(class) (class << 8) #define PCIE_RC_MODE BIT(0) +#define PCIE_EQ_PRESET_01_REG 0x100 +#define PCIE_VAL_LN0_DOWNSTREAM GENMASK(6, 0) +#define PCIE_VAL_LN0_UPSTREAM GENMASK(14, 8) +#define PCIE_VAL_LN1_DOWNSTREAM GENMASK(22, 16) +#define PCIE_VAL_LN1_UPSTREAM GENMASK(30, 24) + #define PCIE_CFGNUM_REG 0x140 #define PCIE_CFG_DEVFN(devfn) ((devfn) & GENMASK(7, 0)) #define PCIE_CFG_BUS(bus) (((bus) << 8) & GENMASK(15, 8)) @@ -72,6 +82,14 @@ #define PCIE_MSI_SET_ENABLE_REG 0x190 #define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0) +#define PCIE_PIPE4_PIE8_REG 0x338 +#define PCIE_K_FINETUNE_MAX GENMASK(5, 0) +#define PCIE_K_FINETUNE_ERR GENMASK(7, 6) +#define PCIE_K_PRESET_TO_USE GENMASK(18, 8) +#define PCIE_K_PHYPARAM_QUERY BIT(19) +#define PCIE_K_QUERY_TIMEOUT BIT(20) +#define PCIE_K_PRESET_TO_USE_16G GENMASK(31, 21) + #define PCIE_MSI_SET_BASE_REG 0xc00 #define PCIE_MSI_SET_OFFSET 0x10 #define PCIE_MSI_SET_STATUS_OFFSET 0x04 @@ -104,7 +122,10 @@ #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) -#define MAX_NUM_PHY_RESETS 1 +#define MAX_NUM_PHY_RESETS 3 + +/* Time in ms needed to complete PCIe reset on EN7581 SoC */ +#define PCIE_EN7581_RESET_TIME_MS 100 /* Downstream Component power supplies used by MediaTek PCIe */ static const char *const dsc_power_supplies[] = { @@ -934,6 +955,85 @@ static void mtk_pcie_dsc_power_down(struct mtk_gen3_pcie *pcie) regulator_bulk_disable(pcie->num_supplies, pcie->supplies); } +static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie) +{ + struct device *dev = pcie->dev; + int err; + u32 val; + + /* + * Wait for the time needed to complete the bulk assert in + * mtk_pcie_setup for EN7581 SoC. + */ + mdelay(PCIE_EN7581_RESET_TIME_MS); + + err = phy_init(pcie->phy); + if (err) { + dev_err(dev, "failed to initialize PHY\n"); + return err; + } + + err = phy_power_on(pcie->phy); + if (err) { + dev_err(dev, "failed to power on PHY\n"); + goto err_phy_on; + } + + err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); + if (err) { + dev_err(dev, "failed to deassert PHYs\n"); + goto err_phy_deassert; + } + + /* + * Wait for the time needed to complete the bulk de-assert above. + * This time is specific for EN7581 SoC. + */ + mdelay(PCIE_EN7581_RESET_TIME_MS); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + err = clk_bulk_prepare(pcie->num_clks, pcie->clks); + if (err) { + dev_err(dev, "failed to prepare clock\n"); + goto err_clk_prepare; + } + + val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | + FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | + FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | + FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); + writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); + + val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | + FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | + FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | + FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); + writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); + + err = clk_bulk_enable(pcie->num_clks, pcie->clks); + if (err) { + dev_err(dev, "failed to prepare clock\n"); + goto err_clk_enable; + } + + return 0; + +err_clk_enable: + clk_bulk_unprepare(pcie->num_clks, pcie->clks); +err_clk_prepare: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); +err_phy_deassert: + phy_power_off(pcie->phy); +err_phy_on: + phy_exit(pcie->phy); + + return err; +} + static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie) { struct device *dev = pcie->dev; @@ -1211,7 +1311,18 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = { }, }; +static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { + .power_up = mtk_pcie_en7581_power_up, + .phy_resets = { + .id[0] = "phy-lane0", + .id[1] = "phy-lane1", + .id[2] = "phy-lane2", + .num_resets = 3, + }, +}; + static const struct of_device_id mtk_pcie_of_match[] = { + { .compatible = "airoha,en7581-pcie", .data = &mtk_pcie_soc_en7581 }, { .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 }, {}, }; -- GitLab From 54739cebe59581f3b4774e6c5793a14aa798328e Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Fri, 3 Jan 2025 14:00:11 +0800 Subject: [PATCH 364/456] FROMLIST: dt-bindings: PCI: mediatek-gen3: Add MT8196 support Add compatible string and clock definition for MT8196. It has 6 clocks like the MT8195, but 2 of them are different. Signed-off-by: Jianjun Wang (am from https://patchwork.kernel.org/patch/13925168/) (also found at https://lore.kernel.org/r/20250103060035.30688-2-jianjun.wang@mediatek.com) BUG=b:383258443 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Change-Id: Ic34f0df57a7fd1ebaef1810d6cc58712b20e03b1 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6174697 Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- .../bindings/pci/mediatek-pcie-gen3.yaml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml index 7e8c7a2a5f9b6..1e2ebd43060e6 100644 --- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml @@ -51,6 +51,7 @@ properties: - mediatek,mt7986-pcie - mediatek,mt8188-pcie - mediatek,mt8195-pcie + - mediatek,mt8196-pcie - const: mediatek,mt8192-pcie - const: mediatek,mt8192-pcie @@ -172,6 +173,34 @@ allOf: - const: tl_32k - const: peri_26m - const: peri_mem + - if: + properties: + compatible: + contains: + enum: + - mediatek,mt8196-pcie + then: + properties: + clocks: + minItems: 6 + + clock-names: + items: + - const: pl_250m + - const: tl_26m + - const: peri_26m + - const: peri_mem + - const: ahb_apb + - const: low_power + + resets: + minItems: 1 + maxItems: 2 + + reset-names: + minItems: 1 + maxItems: 2 + - if: properties: compatible: -- GitLab From df9cb601482c0e9fe42ae382f98b9f1b0b6139f4 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Fri, 3 Jan 2025 14:00:12 +0800 Subject: [PATCH 365/456] BACKPORT: FROMLIST: PCI: mediatek-gen3: Add MT8196 support The MT8196 is an ARM platform SoC that has the same PCIe IP as the MT8195. However, it requires additional settings in the pextpcfg registers. Introduce pextpcfg in PCIe driver for these settings. Signed-off-by: Jianjun Wang (am from https://patchwork.kernel.org/patch/13925177/) (also found at https://lore.kernel.org/r/20250103060035.30688-3-jianjun.wang@mediatek.com) Conflicts: drivers/pci/controller/pcie-mediatek-gen3.c BUG=b:383258443 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Change-Id: I41c6b447d454c41b594fc1495ad4b1138fc3cbea Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6174698 Reviewed-by: Fei Shao Commit-Queue: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 9761bb08c443f..a5fa27b9df450 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,17 @@ #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) +#define PCIE_RESOURCE_CTRL_REG 0xd2c +#define PCIE_SYS_CLK_RDY_TIME_MASK GENMASK(7, 0) +#define PCIE_SYS_CLK_RDY_TIME_TO_10US 0xa + +/* PEXTPCFG Registers */ +#define PEXTP_CLOCK_CON_REG 0x20 +#define PEXTP_P0P1_LOWPOWER_CK_SEL BIT(0) +#define PEXTP_REQ_CTRL_0_REG 0x7c +#define PEXTP_26M_REQ_FORCE_ON BIT(0) +#define PEXTP_PCIE26M_BYPASS BIT(4) + #define MAX_NUM_PHY_RESETS 3 /* Time in ms needed to complete PCIe reset on EN7581 SoC */ @@ -139,10 +151,14 @@ struct mtk_gen3_pcie; /** * struct mtk_gen3_pcie_pdata - differentiate between host generations * @power_up: pcie power_up callback + * @pre_init: initialize settings before link up + * @cleanup: cleanup when PCIe power down * @phy_resets: phy reset lines SoC data. */ struct mtk_gen3_pcie_pdata { int (*power_up)(struct mtk_gen3_pcie *pcie); + int (*pre_init)(struct mtk_gen3_pcie *pcie); + void (*cleanup)(struct mtk_gen3_pcie *pcie); struct { const char *id[MAX_NUM_PHY_RESETS]; int num_resets; @@ -165,6 +181,7 @@ struct mtk_msi_set { * struct mtk_gen3_pcie - PCIe port information * @dev: pointer to PCIe device * @base: IO mapped register base + * @pextpcfg: pextpcfg_ao IO mapped register base * @reg_base: physical register base * @mac_reset: MAC reset control * @phy_resets: PHY reset controllers @@ -189,6 +206,7 @@ struct mtk_msi_set { struct mtk_gen3_pcie { struct device *dev; void __iomem *base; + void __iomem *pextpcfg; phys_addr_t reg_base; struct reset_control *mac_reset; struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS]; @@ -405,6 +423,13 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) val |= PCIE_RC_MODE; writel_relaxed(val, pcie->base + PCIE_SETTING_REG); + /* + * The values of some registers are different in RC and EP mode. Therefore, + * call soc->pre_init after the mode change in case it depends on these registers. + */ + if (pcie->soc && pcie->soc->pre_init) + pcie->soc->pre_init(pcie); + /* Set class code */ val = readl_relaxed(pcie->base + PCIE_PCI_IDS_1); val &= ~GENMASK(31, 8); @@ -838,6 +863,7 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) int i, ret, num_resets = pcie->soc->phy_resets.num_resets; struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); + struct device_node *node; struct resource *regs; regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcie-mac"); @@ -915,6 +941,18 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie) pcie->dsc_reset_delay_ms = 5; } + node = of_parse_phandle(dev->of_node, "pextpcfg", 0); + if (node) { + pcie->pextpcfg = of_iomap(node, 0); + of_node_put(node); + if (IS_ERR(pcie->pextpcfg)) { + dev_err(dev, "failed to get pextpcfg\n"); + ret = PTR_ERR(pcie->pextpcfg); + pcie->pextpcfg = NULL; + return ret; + } + } + return 0; } @@ -1107,6 +1145,12 @@ static void mtk_pcie_power_down(struct mtk_gen3_pcie *pcie) if (!pcie->dev->power.is_suspended || !device_wakeup_path(pcie->dev)) mtk_pcie_dsc_power_down(pcie); + + if (pcie->soc && pcie->soc->cleanup) + pcie->soc->cleanup(pcie); + + if (pcie->pextpcfg) + iounmap(pcie->pextpcfg); } static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) @@ -1311,6 +1355,49 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = { }, }; +static int mtk_pcie_mt8196_pre_init(struct mtk_gen3_pcie *pcie) +{ + u32 val; + + /* Adjust SYS_CLK_RDY_TIME ot 10us to avoid glitch */ + val = readl_relaxed(pcie->base + PCIE_RESOURCE_CTRL_REG); + val &= ~PCIE_SYS_CLK_RDY_TIME_MASK; + val |= PCIE_SYS_CLK_RDY_TIME_TO_10US; + writel_relaxed(val, pcie->base + PCIE_RESOURCE_CTRL_REG); + + /* Switch to normal clock */ + val = readl_relaxed(pcie->pextpcfg + PEXTP_CLOCK_CON_REG); + val &= ~PEXTP_P0P1_LOWPOWER_CK_SEL; + writel_relaxed(val, pcie->pextpcfg + PEXTP_CLOCK_CON_REG); + + /* Force pcie_26m_req and bypass pcie_26m_ack signal */ + val = readl_relaxed(pcie->pextpcfg + PEXTP_REQ_CTRL_0_REG); + val |= (PEXTP_26M_REQ_FORCE_ON | PEXTP_PCIE26M_BYPASS); + writel_relaxed(val, pcie->pextpcfg + PEXTP_REQ_CTRL_0_REG); + + return 0; +} + +static void mtk_pcie_mt8196_cleanup(struct mtk_gen3_pcie *pcie) +{ + u32 val; + + /* Release pcie_26m_req and pcie_26m_ack signal */ + val = readl_relaxed(pcie->pextpcfg + PEXTP_REQ_CTRL_0_REG); + val &= ~(PEXTP_26M_REQ_FORCE_ON | PEXTP_PCIE26M_BYPASS); + writel_relaxed(val, pcie->pextpcfg + PEXTP_REQ_CTRL_0_REG); +} + +static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8196 = { + .power_up = mtk_pcie_power_up, + .pre_init = mtk_pcie_mt8196_pre_init, + .cleanup = mtk_pcie_mt8196_cleanup, + .phy_resets = { + .id[0] = "phy", + .num_resets = 1, + }, +}; + static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { .power_up = mtk_pcie_en7581_power_up, .phy_resets = { @@ -1324,6 +1411,7 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { static const struct of_device_id mtk_pcie_of_match[] = { { .compatible = "airoha,en7581-pcie", .data = &mtk_pcie_soc_en7581 }, { .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 }, + { .compatible = "mediatek,mt8196-pcie", .data = &mtk_pcie_soc_mt8196 }, {}, }; MODULE_DEVICE_TABLE(of, mtk_pcie_of_match); -- GitLab From eac43b0722c6090fe0ed6a2e96f98eeca0b3f617 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Fri, 3 Jan 2025 14:00:13 +0800 Subject: [PATCH 366/456] FROMLIST: PCI: mediatek-gen3: Disable ASPM L0s Disable ASPM L0s support because it does not significantly save power but impacts performance. Signed-off-by: Jianjun Wang (am from https://patchwork.kernel.org/patch/13925178/) (also found at https://lore.kernel.org/r/20250103060035.30688-4-jianjun.wang@mediatek.com) BUG=b:383258443 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Change-Id: I82cf455d08548341bbbe76fc964bc4c10ec6d87e Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6174699 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index a5fa27b9df450..985e9297c7e2d 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -83,6 +83,9 @@ #define PCIE_MSI_SET_ENABLE_REG 0x190 #define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0) +#define PCIE_LOW_POWER_CTRL_REG 0x194 +#define PCIE_FORCE_DIS_L0S BIT(8) + #define PCIE_PIPE4_PIE8_REG 0x338 #define PCIE_K_FINETUNE_MAX GENMASK(5, 0) #define PCIE_K_FINETUNE_ERR GENMASK(7, 6) @@ -441,6 +444,14 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) val &= ~PCIE_INTX_ENABLE; writel_relaxed(val, pcie->base + PCIE_INT_ENABLE_REG); + /* + * Disable L0s support because it does not significantly save power + * but impacts performance. + */ + val = readl_relaxed(pcie->base + PCIE_LOW_POWER_CTRL_REG); + val |= PCIE_FORCE_DIS_L0S; + writel_relaxed(val, pcie->base + PCIE_LOW_POWER_CTRL_REG); + /* Disable DVFSRC voltage request */ val = readl_relaxed(pcie->base + PCIE_MISC_CTRL_REG); val |= PCIE_DISABLE_DVFSRC_VLT_REQ; -- GitLab From 5f91186483e16b70b19b2820ea977bde07f7f187 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Fri, 3 Jan 2025 14:00:14 +0800 Subject: [PATCH 367/456] FROMLIST: PCI: mediatek-gen3: Don't reply AXI slave error There are some circumstances where the EP device will not respond to non-posted access from the root port (e.g., MMIO read). In such cases, the root port will reply with an AXI slave error, which will be treated as a System Error (SError), causing a kernel panic and preventing us from obtaining any useful information for further debugging. We have added a new bit in the PCIE_AXI_IF_CTRL_REG register to prevent PCIe AXI0 from replying with a slave error. Setting this bit on an older platform that does not support this feature will have no effect. By preventing AXI0 from replying with a slave error, we can keep the kernel alive and debug using the information from AER. Signed-off-by: Jianjun Wang (am from https://patchwork.kernel.org/patch/13925176/) (also found at https://lore.kernel.org/r/20250103060035.30688-5-jianjun.wang@mediatek.com) BUG=b:383258443 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Change-Id: Ibb18a9d780d3b009511632caeb9e7c4eb6b0173c Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6174700 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 985e9297c7e2d..e4ae5c1b3f55d 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -86,6 +86,9 @@ #define PCIE_LOW_POWER_CTRL_REG 0x194 #define PCIE_FORCE_DIS_L0S BIT(8) +#define PCIE_AXI_IF_CTRL_REG 0x1a8 +#define PCIE_AXI0_SLV_RESP_MASK BIT(12) + #define PCIE_PIPE4_PIE8_REG 0x338 #define PCIE_K_FINETUNE_MAX GENMASK(5, 0) #define PCIE_K_FINETUNE_ERR GENMASK(7, 6) @@ -452,6 +455,15 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) val |= PCIE_FORCE_DIS_L0S; writel_relaxed(val, pcie->base + PCIE_LOW_POWER_CTRL_REG); + /* + * Prevent PCIe AXI0 from replying a slave error, as it will cause kernel panic + * and prevent us from getting useful information. + * Keep the kernel alive and debug using the information from AER. + */ + val = readl_relaxed(pcie->base + PCIE_AXI_IF_CTRL_REG); + val |= PCIE_AXI0_SLV_RESP_MASK; + writel_relaxed(val, pcie->base + PCIE_AXI_IF_CTRL_REG); + /* Disable DVFSRC voltage request */ val = readl_relaxed(pcie->base + PCIE_MISC_CTRL_REG); val |= PCIE_DISABLE_DVFSRC_VLT_REQ; -- GitLab From b76e316c44492576abd69d9dc521f1140def7953 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Fri, 3 Jan 2025 14:00:15 +0800 Subject: [PATCH 368/456] FROMLIST: PCI: mediatek-gen3: Keep PCIe power and clocks if suspend-to-idle If the target system sleep state is suspend-to-idle, the bridge is supposed to stay in D0, and the framework will not help to restore its configuration space, so keep its power and clocks during suspend. It's recommended to enable L1ss support, so the link can be changed to L1.2 state during suspend. Signed-off-by: Jianjun Wang (am from https://patchwork.kernel.org/patch/13925179/) (also found at https://lore.kernel.org/r/20250103060035.30688-6-jianjun.wang@mediatek.com) BUG=b:383258443 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Change-Id: Iedb16bdb94509f3ff9add564f959695d78ba3303 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6174701 Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Sean Paul Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index e4ae5c1b3f55d..c6af7af7f30c0 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1325,6 +1325,19 @@ static int mtk_pcie_suspend_noirq(struct device *dev) int err; u32 val; + /* + * If the target system sleep state is suspend-to-idle, the bridge is supposed to stay in + * D0, and the framework will not help to restore its configuration space, so keep it's + * power and clocks during suspend. + * + * It's recommended to enable L1ss support, so the link can be changed to L1.2 state during + * suspend. + */ + if (pm_suspend_default_s2idle()) { + dev_info(dev, "System enter s2idle state, keep PCIe power and clocks\n"); + return 0; + } + /* Trigger link to L2 state */ err = mtk_pcie_turn_off_link(pcie); if (err) { @@ -1350,6 +1363,11 @@ static int mtk_pcie_resume_noirq(struct device *dev) struct mtk_gen3_pcie *pcie = dev_get_drvdata(dev); int err; + if (pm_suspend_default_s2idle()) { + dev_info(dev, "System enter s2idle state, no need to reinitialization\n"); + return 0; + } + err = pcie->soc->power_up(pcie); if (err) return err; -- GitLab From bf81e240303968074a4608f1eff2e3b47cd31591 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 20 Dec 2024 14:52:05 -0800 Subject: [PATCH 369/456] FROMGIT: PCI: mediatek-gen3: Enable async probe by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mediatek-gen3 driver can run its probe routine fairly slow on some hardware, which adds to the total time it takes for the system start up. Thus, turn on async mode for the probe to avoid blocking the rest of the system. Link: https://lore.kernel.org/r/20241220145205.1.Ibf2563896c3b1fc133bb46d3fc96ad0041763922@changeid Signed-off-by: Douglas Anderson [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Manivannan Sadhasivam (cherry picked from commit 17bd5e4dc96c953257eadce111d7b6ef458c6187 git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git controller/mediatek) BUG=b:385391238 TEST=WiFi still works Change-Id: Ibf2563896c3b1fc133bb46d3fc96ad0041763922 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6168655 Reviewed-by: Sean Paul Tested-by: Douglas Anderson Reviewed-by: Stephen Boyd Commit-Queue: Douglas Anderson Signed-off-by: Hubert Mazur --- drivers/pci/controller/pcie-mediatek-gen3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index c6af7af7f30c0..49878abbd20db 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1464,6 +1464,7 @@ static struct platform_driver mtk_pcie_driver = { .name = "mtk-pcie-gen3", .of_match_table = mtk_pcie_of_match, .pm = &mtk_pcie_pm_ops, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, }; -- GitLab From 1d48d915061d47a7beca8d37638231656334110f Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Tue, 14 Jan 2025 12:21:22 -0800 Subject: [PATCH 370/456] FROMGIT: platform/chrome: cros_ec_lpc: Handle EC without CRS section Fix logic to support GOOG0004 device without CRS section. Instead of failing, assume there are not memory mapped EC registers. Fixes: be4fccb5e1fb ("platform/chrome: cros_ec_lpc: Support direct EC register memory access") Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20250114202122.2352277-1-gwendal@chromium.org Signed-off-by: Tzung-Bi Shih (cherry picked from commit fccebbdde2067e359f01382a72c31ed2af7acbac https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git for-next) BUG=b:389567007, b:354066052 TEST=Check on nautilus IMU sensors are present Change-Id: Ia9ecc48430e74c94cbfe539e35da66f4923f2880 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6168955 Reviewed-by: Sean Paul Reviewed-by: Tzung-Bi Shih Tested-by: Gwendal Grignou Commit-Queue: Gwendal Grignou Auto-Submit: Gwendal Grignou Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_lpc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 288ef9198bb0a..a878758b9211c 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -562,11 +562,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) */ status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, cros_ec_lpc_resources, ec_lpc); - if (ACPI_FAILURE(status)) { - dev_err(dev, "failed to get resources\n"); - return -ENODEV; - } - if (ec_lpc->mem32.address_length) { + if (ACPI_SUCCESS(status) && ec_lpc->mem32.address_length) { ec_lpc->base = devm_ioremap(dev, ec_lpc->mem32.address, ec_lpc->mem32.address_length); -- GitLab From 0af2ff19096698de277f90cea6c5f1eb76e0f271 Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Tue, 14 Jan 2025 13:06:22 +0800 Subject: [PATCH 371/456] FROMLIST: wifi: mt76: mt7925: fix fails to enter low power mode in suspend state The mt7925 sometimes fails to enter low power mode during suspend. This is caused by the chip firmware sending an additional ACK event to the host after processing the suspend command. Due to timing issues, this event may not reach the host, causing the chip to get stuck. To resolve this, the ACK flag in the suspend command is removed, as it is not needed in the MT7925 architecture. This prevents the firmware from sending the additional ACK event, ensuring the device can reliably enter low power mode during suspend. Signed-off-by: Quan Zhou (am from https://patchwork.kernel.org/patch/13938400/) (also found at https://lore.kernel.org/r/d056938144a3a0336c3a4e3cec6f271899f32bf7.1736775666.git.quan.zhou@mediatek.com) BUG=b:387468281 UPSTREAM-TASK=b:389885387 TEST=fix fails to enter low power mode in suspend state Change-Id: I9ffde9bd382ff6607912f2aa0959200fe34de5bf Signed-off-by: Quan Zhou Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6169772 Reviewed-by: Sean Paul Commit-Queue: ChromeOS Auto Retry Reviewed-by: Jintao Lin Tested-by: Jintao Lin Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 670cf9fc0f1aa..44eab38f3198f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -3214,6 +3214,9 @@ int mt7925_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb, else uni_txd->option = MCU_CMD_UNI_EXT_ACK; + if (cmd == MCU_UNI_CMD(HIF_CTRL)) + uni_txd->option &= ~MCU_CMD_ACK; + goto exit; } -- GitLab From 013604fb44d0146969edb3acb33f055cff77c078 Mon Sep 17 00:00:00 2001 From: Jjian Zhou Date: Fri, 2 Feb 2024 13:55:57 +0800 Subject: [PATCH 372/456] CHROMIUM: mailbox: add tinysys mailbox 1. add common mailbox driver 2. add tinysys mailbox driver BUG=None TEST=build pass & bootup to shell. UPSTREAM-TASK=b:379034573 Signed-off-by: Jjian Zhou Change-Id: If57cb6e3aa9dc627dadf080132b3828ae98027c7 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073689 Commit-Queue: Fei Shao Reviewed-by: Pin-yen Lin Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- drivers/mailbox/Kconfig | 9 + drivers/mailbox/Makefile | 2 + drivers/mailbox/mtk-mbox-mailbox.c | 304 ++++++ drivers/rpmsg/Kconfig | 10 + drivers/rpmsg/Makefile | 1 + drivers/rpmsg/mtk_rpmsg_mbox.c | 247 +++++ drivers/soc/mediatek/Kconfig | 18 + drivers/soc/mediatek/Makefile | 2 + drivers/soc/mediatek/mtk-mbox.c | 1030 ++++++++++++++++++ drivers/soc/mediatek/mtk_tinysys_ipi.c | 668 ++++++++++++ include/linux/rpmsg/mtk_rpmsg.h | 36 + include/linux/soc/mediatek/mtk-mbox.h | 318 ++++++ include/linux/soc/mediatek/mtk_sip_svc.h | 2 + include/linux/soc/mediatek/mtk_tinysys_ipi.h | 144 +++ include/trace/events/mbox.h | 77 ++ 15 files changed, 2868 insertions(+) create mode 100644 drivers/mailbox/mtk-mbox-mailbox.c create mode 100644 drivers/rpmsg/mtk_rpmsg_mbox.c create mode 100644 drivers/soc/mediatek/mtk-mbox.c create mode 100644 drivers/soc/mediatek/mtk_tinysys_ipi.c create mode 100644 include/linux/soc/mediatek/mtk-mbox.h create mode 100644 include/linux/soc/mediatek/mtk_tinysys_ipi.h create mode 100644 include/trace/events/mbox.h diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index bc2e265cb02d2..d871fe0fee1dc 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -258,6 +258,15 @@ config MTK_CMDQ_MBOX critical time limitation, such as updating display configuration during the vblank. +config MTK_TINYSYS_MBOX + tristate "MediaTek TINYSYS MBOX Mailbox Support" + depends on ARM || ARM64 + help + Say yes here to add support for the MediaTek TINYSYS mailbox driver. + This uses MTK MBOX driver to communicate with remote processors + base on ipic framework. It provide channels, controller creation + and send operations. + config ZYNQMP_IPI_MBOX tristate "Xilinx ZynqMP IPI Mailbox" depends on ARCH_ZYNQMP && OF diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 82da2f4ee81a1..78c8ca5058574 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -53,6 +53,8 @@ obj-$(CONFIG_MTK_ADSP_MBOX) += mtk-adsp-mailbox.o obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o mtk-cmdq-sec-mailbox.o mtk-cmdq-sec-tee.o +obj-$(CONFIG_MTK_TINYSYS_MBOX) += mtk-mbox-mailbox.o + obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o diff --git a/drivers/mailbox/mtk-mbox-mailbox.c b/drivers/mailbox/mtk-mbox-mailbox.c new file mode 100644 index 0000000000000..4ce885a917a59 --- /dev/null +++ b/drivers/mailbox/mtk-mbox-mailbox.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_OF_RESERVED_MEM +#include +#endif + +#include +#define FIXED_MBOX_SIZE 128 +#define T_SEND_OFFSET_H (FIXED_MBOX_SIZE - 16) +#define T_SEND_OFFSET_L (FIXED_MBOX_SIZE - 12) +#define T_IRQ_OFFSET_H (FIXED_MBOX_SIZE - 8) +#define T_IRQ_OFFSET_L (FIXED_MBOX_SIZE - 4) + +/* for secure mode */ +#include +#include + +enum mtk_tinysys_sspm_kernel_op { + MTK_TINYSYS_SSPM_KERNEL_OP_MBOX_CLEAR = 0, + MTK_TINYSYS_SSPM_KERNEL_OP_MD2SPM_IPC_CLEAR = 1, + MTK_TINYSYS_SSPM_KERNEL_OP_NUM, +}; + +static unsigned int secure_mbox_clr_support; +static unsigned int secure_sspm_md2spm_clr_support; + +#define INTR_SET_OFS 0x0 +#define INTR_CLR_OFS 0x4 +#define MBOX_CHANS 2 + +struct mhu_link { + unsigned int irq; /* GIC irq */ + void __iomem *tx_reg; + void __iomem *rx_reg; + void __iomem *shmem; + resource_size_t shmem_size; + unsigned int mbox_irq; /* for secure mode */ +}; + +struct mtk_mbu { + void __iomem *base; + struct mhu_link mlink[MBOX_CHANS]; + struct mbox_chan chan[MBOX_CHANS]; + struct mbox_controller mbox; +}; + +/* for secure mode */ +static inline uint64_t sspm_do_mbox_clear(unsigned int mbox_irq) +{ + struct arm_smccc_res res; + + arm_smccc_smc(MTK_SIP_TINYSYS_SSPM_CONTROL, + MTK_TINYSYS_SSPM_KERNEL_OP_MBOX_CLEAR, + mbox_irq, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +/* Clear SSPM2SPM_IPC */ +static inline uint64_t sspm_do_md2spm_clear(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(MTK_SIP_TINYSYS_SSPM_CONTROL, + MTK_TINYSYS_SSPM_KERNEL_OP_MD2SPM_IPC_CLEAR, + 0, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +static irqreturn_t tinysys_mbox_rx_interrupt(int irq, void *p) +{ + struct mbox_chan *chan = p; + struct mhu_link *mlink = chan->con_priv; + u32 val; + u64 tv; + + tv = __arch_counter_get_cntvct(); + writel_relaxed((u32)((tv & 0xFFFFFFFF00000000LL) >> 32), mlink->shmem + T_IRQ_OFFSET_H); + writel_relaxed((u32)(tv & 0xFFFFFFFFLL), mlink->shmem + T_IRQ_OFFSET_L); + + val = readl_relaxed(mlink->rx_reg + INTR_CLR_OFS); + dev_dbg(chan->mbox->dev, + "[scmi] %s chan:%p txdone_method:%x\n", + __func__, chan, chan->txdone_method); + if (!val) + return IRQ_NONE; + + /* for secure mode */ + if (secure_mbox_clr_support) + sspm_do_mbox_clear(mlink->mbox_irq); + else + writel_relaxed(1, mlink->rx_reg + INTR_CLR_OFS); + + /* clear irq before free channel*/ + mbox_chan_received_data(chan, (void *)&val); + + /* Clear SSPM2SPM_IPC */ + if (secure_sspm_md2spm_clr_support) + sspm_do_md2spm_clear(); + + return IRQ_HANDLED; +} + +static bool tinysys_mbox_last_tx_done(struct mbox_chan *chan) +{ + struct mhu_link *mlink = chan->con_priv; + u32 val = readl_relaxed(mlink->tx_reg + INTR_SET_OFS); + + if (val == 0) + dev_dbg(chan->mbox->dev, "[scmi] last_tx_done\n"); + return (val == 0); +} + +static int tinysys_mbox_send_data(struct mbox_chan *chan, void *data) +{ + struct mhu_link *mlink = chan->con_priv; + u64 tv; + u32 *arg = data; + + dev_dbg(chan->mbox->dev, "[scmi] send_data %x\n", *arg); + /* Make sure other CPUs can write in order */ + smp_mb(); + tv = __arch_counter_get_cntvct(); + writel_relaxed((u32)((tv & 0xFFFFFFFF00000000LL) >> 32), + mlink->shmem + T_SEND_OFFSET_H); + writel_relaxed((u32)(tv & 0xFFFFFFFFLL), mlink->shmem + T_SEND_OFFSET_L); + writel_relaxed(1, mlink->tx_reg + INTR_SET_OFS); + + return 0; +} + +static int tinysys_mbox_startup(struct mbox_chan *chan) +{ + struct mhu_link *mlink = chan->con_priv; + int ret; + + ret = request_threaded_irq(mlink->irq, NULL, + tinysys_mbox_rx_interrupt, + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE | IRQF_ONESHOT, + "mtk_tinysys_mbox", chan); + if (ret) { + dev_err(chan->mbox->dev, + "Unable to acquire IRQ %d\n", mlink->irq); + return ret; + } + return 0; +} + +static void tinysys_mbox_shutdown(struct mbox_chan *chan) +{ + struct mhu_link *mlink = chan->con_priv; + + if (mlink->irq) + free_irq(mlink->irq, chan); +} + +static const struct mbox_chan_ops tinysys_mbox_chan_ops = { + .send_data = tinysys_mbox_send_data, + .startup = tinysys_mbox_startup, + .shutdown = tinysys_mbox_shutdown, + .last_tx_done = tinysys_mbox_last_tx_done, +}; + +static int tinysys_mbox_probe(struct platform_device *pdev) +{ + int err, i; + int secure_ret; /* for secure mode */ + struct mtk_mbu *mbu; + struct device *dev = &pdev->dev; + struct resource *res; + struct tinysys_mbox_plat *plat_data; + struct device_node *shmem; + struct resource shmem_res; + resource_size_t size; + + /* Allocate memory for device */ + mbu = devm_kzalloc(dev, sizeof(*mbu), GFP_KERNEL); + if (!mbu) + return -ENOMEM; + + for (i = 0; i < MBOX_CHANS; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + mbu->base = devm_ioremap_resource(dev, res); + + if (IS_ERR(mbu->base)) { + dev_err(dev, "failed to ioremap mbu"); + return PTR_ERR(mbu->base); + } + shmem = of_parse_phandle(dev->of_node, "shmem", i); + err = of_address_to_resource(shmem, 0, &shmem_res); + of_node_put(shmem); + if (err) { + dev_err(dev, "failed to get scmi profile memory\n"); + return err; + } + size = resource_size(&shmem_res); + mbu->mlink[i].shmem = devm_ioremap(dev, shmem_res.start, size); + mbu->mlink[i].shmem_size = size; + mbu->chan[i].con_priv = &mbu->mlink[i]; + + mbu->mlink[i].irq = platform_get_irq(pdev, i); + if (!mbu->mlink[i].irq) + dev_err(dev, "failed to get irq"); + + mbu->mlink[i].mbox_irq = i; /* for secure mode*/ + mbu->mlink[i].rx_reg = mbu->base; + mbu->mlink[i].tx_reg = mbu->base; + } + + /* for secure mode*/ + secure_ret = of_property_read_u32(pdev->dev.of_node, + "secure-sspm-mbox-clr", &secure_mbox_clr_support); + + if ((!secure_ret) && secure_mbox_clr_support) { + pr_notice("[scmi] secure-sspm-mbox-clr support, secure_mbox_clr_support: %d\n", + secure_mbox_clr_support); + } else { + pr_notice("[scmi] secure-sspm-mbox-clr not support\n"); + } + + /* notify spm */ + secure_ret = of_property_read_u32(pdev->dev.of_node, + "secure-sspm-md2spm-clr", &secure_sspm_md2spm_clr_support); + + if ((!secure_ret) && secure_sspm_md2spm_clr_support) { + pr_notice("[scmi] secure-sspm-md2spm-clr support, secure_sspm_md2spm_clr_support: %d\n", + secure_sspm_md2spm_clr_support); + } else { + pr_notice("[scmi] secure-sspm_md2spm-clr not support\n"); + } + + plat_data = (struct tinysys_mbox_plat *)of_device_get_match_data(dev); + if (!plat_data) { + dev_err(dev, "failed to get match data\n"); + return -EINVAL; + } + + mbu->mbox.dev = dev; + mbu->mbox.chans = &mbu->chan[0]; + mbu->mbox.num_chans = MBOX_CHANS; + mbu->mbox.ops = &tinysys_mbox_chan_ops; + mbu->mbox.txdone_irq = false; + mbu->mbox.txdone_poll = true; + mbu->mbox.txpoll_period = 1; + + platform_set_drvdata(pdev, mbu); + + err = devm_mbox_controller_register(dev, &mbu->mbox); + if (err) { + dev_err(dev, "Failed to register mailboxes %d\n", err); + return err; + } + + dev_dbg(dev, "MTK MBOX Mailbox registered\n"); + + return 0; +} + +struct tinysys_mbox_plat { + u32 thread_nr; + u32 bfs; +}; + +static const struct tinysys_mbox_plat tinysys_mbox_plat_v1 = {.thread_nr = 1, .bfs = 64}; + +static const struct of_device_id tinysys_mbox_of_ids[] = { + {.compatible = "mediatek,tinysys_mbox", .data = (void *)&tinysys_mbox_plat_v1}, + {} +}; + +static int tinysys_mbox_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver mtk_tinysys_mbox_driver = { + .probe = tinysys_mbox_probe, + .remove = tinysys_mbox_remove, + .driver = { + .name = "mtk_tinysys_mbox", + .of_match_table = tinysys_mbox_of_ids, + } +}; + +module_platform_driver(mtk_tinysys_mbox_driver); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek Mailbox driver"); + diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index d3795860f5c08..ff90b6c4e6e7c 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig @@ -31,6 +31,16 @@ config RPMSG_NS channel that probes the associated RPMsg device on remote endpoint service announcement. +config RPMSG_MTK + tristate "MediaTek TinySys RPM driver" + depends on MTK_MBOX + select RPMSG + help + Say y here to enable support communication channels to remote + processors in MediaTek platforms. This uses MTK MBOX driver to + communicate with remote processors base on rpmsg framework. It + provide channels, endpoints creation and send operations. + config RPMSG_MTK_SCP tristate "MediaTek SCP" depends on MTK_SCP diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile index 58e3b382e316c..e4558c5ec2285 100644 --- a/drivers/rpmsg/Makefile +++ b/drivers/rpmsg/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o obj-$(CONFIG_RPMSG_CTRL) += rpmsg_ctrl.o obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o +obj-$(CONFIG_RPMSG_MTK) += mtk_rpmsg_mbox.o qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o diff --git a/drivers/rpmsg/mtk_rpmsg_mbox.c b/drivers/rpmsg/mtk_rpmsg_mbox.c new file mode 100644 index 0000000000000..65ba31555c8f8 --- /dev/null +++ b/drivers/rpmsg/mtk_rpmsg_mbox.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/* + * The MediaTek Mbox communication solution provides point-to-point + * channels for clients to send and receive packet based data. + */ +#include +#include +#include + +#include "rpmsg_internal.h" +#include +#include + +#define to_mtk_rpmsg_device(r) container_of(r, struct mtk_rpmsg_device_mbox, rpdev) +#define to_mtk_rpmsg_endpoint(r) container_of(r, struct mtk_rpmsg_endpoint, ept) + +struct mtk_rpmsg_endpoint { + struct rpmsg_endpoint ept; + struct mtk_rpmsg_device_mbox *mdev; + struct mtk_rpmsg_channel_info_mbox *mchan; +}; + +struct mtk_rpmsg_operations { + int (*mbox_send)(struct mtk_rpmsg_endpoint *mept, + struct mtk_rpmsg_channel_info_mbox *mchan, + void *buf, unsigned int len, unsigned int wait); +}; + +int mtk_mbox_send(struct mtk_rpmsg_endpoint *mept, + struct mtk_rpmsg_channel_info_mbox *mchan, void *buf, + unsigned int len, unsigned int wait) +{ + struct mtk_mbox_device *mbdev; + unsigned int status; + unsigned long flags; + int ret; + + if (WARN_ON(len > mchan->send_slot_size) || WARN_ON(!buf)) + return -EINVAL; + + mbdev = mept->mdev->mbdev; + + spin_lock_irqsave(&mchan->channel_lock, flags); + status = mtk_mbox_check_send_irq(mbdev, mchan->mbox, + mchan->send_pin_index); + if (status != 0) { + spin_unlock_irqrestore(&mchan->channel_lock, flags); + return MBOX_PIN_BUSY; + } + spin_unlock_irqrestore(&mchan->channel_lock, flags); + + ret = mtk_mbox_write(mbdev, mchan->mbox, mchan->send_slot, buf, + len * MBOX_SLOT_SIZE); + if (ret != MBOX_DONE) + return ret; + + /* + * Ensure that all writes to SRAM are committed before sending the + * interrupt to mbox. + */ + mb(); + + ret = mtk_mbox_trigger_irq(mbdev, mchan->mbox, + BIT(mchan->send_pin_index)); + if (ret != MBOX_DONE) + return ret; + + return ret; +} +EXPORT_SYMBOL_GPL(mtk_mbox_send); + +static struct mtk_rpmsg_operations mtk_rpmsg_ops = { + .mbox_send = mtk_mbox_send, +}; + +static void __ept_release(struct kref *kref) +{ + struct rpmsg_endpoint *ept; + + ept = container_of(kref, struct rpmsg_endpoint, refcount); + kfree(to_mtk_rpmsg_endpoint(ept)); +} + +static void mtk_rpmsg_destroy_ept(struct rpmsg_endpoint *ept) +{ + kref_put(&ept->refcount, __ept_release); +} + +static int mtk_rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len) +{ + struct mtk_rpmsg_device_mbox *mdev; + struct mtk_rpmsg_channel_info_mbox *mchan; + + mdev = to_mtk_rpmsg_endpoint(ept)->mdev; + mchan = to_mtk_rpmsg_endpoint(ept)->mchan; + + return mdev->ops->mbox_send(to_mtk_rpmsg_endpoint(ept), + mchan, data, len, 1); +} + +static int mtk_rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len) +{ + struct mtk_rpmsg_device_mbox *mdev; + struct mtk_rpmsg_channel_info_mbox *mchan; + + mdev = to_mtk_rpmsg_endpoint(ept)->mdev; + mchan = to_mtk_rpmsg_endpoint(ept)->mchan; + + return mdev->ops->mbox_send(to_mtk_rpmsg_endpoint(ept), + mchan, data, len, 0); +} + +static const struct rpmsg_endpoint_ops mtk_rpmsg_endpoint_ops = { + .destroy_ept = mtk_rpmsg_destroy_ept, + .send = mtk_rpmsg_send, + .trysend = mtk_rpmsg_trysend, +}; + +struct mtk_rpmsg_channel_info_mbox * +mtk_rpmsg_create_channel(struct mtk_rpmsg_device_mbox *mdev, u32 chan_id, char *name) +{ + struct mtk_rpmsg_channel_info_mbox *mchan; + struct mtk_mbox_device *mbdev; + struct mtk_mbox_pin_send *msend; + struct mtk_mbox_pin_recv *mrecv; + unsigned int i, count; + + mchan = kzalloc(sizeof(*mchan), GFP_KERNEL); + if (!mchan) + return NULL; + + mbdev = mdev->mbdev; + spin_lock_init(&mchan->channel_lock); + mchan->info.src = chan_id; + strscpy(mchan->info.name, name, RPMSG_NAME_SIZE); + + count = mbdev->recv_count; + for (i = 0; i < count; ++i) { + mrecv = &(mbdev->pin_recv_table[i]); + if (chan_id == mrecv->chan_id) { + mchan->mbox = mrecv->mbox; + mchan->recv_slot = mrecv->offset; + mchan->recv_slot_size = mrecv->msg_size; + mchan->recv_pin_index = mrecv->pin_index; + mchan->recv_pin_offset = i; + } + } + + count = mbdev->send_count; + for (i = 0; i < count; ++i) { + msend = &(mbdev->pin_send_table[i]); + if (chan_id == msend->chan_id) { + mchan->mbox = msend->mbox; + mchan->send_slot = msend->offset; + mchan->send_slot_size = msend->msg_size; + mchan->send_pin_index = msend->pin_index; + mchan->send_pin_offset = i; + } + } + return mchan; +} +EXPORT_SYMBOL_GPL(mtk_rpmsg_create_channel); + +static struct rpmsg_endpoint * +__rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, + struct rpmsg_channel_info chinfo) +{ + struct mtk_rpmsg_endpoint *mept; + struct rpmsg_endpoint *ept; + + mept = kzalloc(sizeof(*mept), GFP_KERNEL); + if (!mept) + return NULL; + + mept->mdev = to_mtk_rpmsg_device(rpdev); + mept->mchan = (struct mtk_rpmsg_channel_info_mbox *)priv; + + ept = &mept->ept; + kref_init(&ept->refcount); + + ept->rpdev = rpdev; + ept->cb = cb; + ept->ops = &mtk_rpmsg_endpoint_ops; + ept->addr = chinfo.src; + + return ept; +} + +static struct rpmsg_endpoint * +mtk_rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv, + struct rpmsg_channel_info chinfo) +{ + return __rpmsg_create_ept(rpdev, cb, priv, chinfo); +} + +static const struct rpmsg_device_ops mtk_rpmsg_device_ops = { + .create_ept = mtk_rpmsg_create_ept, +}; + +static void mtk_rpmsg_release_device(struct device *dev) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + struct mtk_rpmsg_device_mbox *mdev = to_mtk_rpmsg_device(rpdev); + + kfree(mdev); +} + +/* create mtk rpmsg device */ +struct mtk_rpmsg_device_mbox * +mtk_rpmsg_create_mbox_device(struct platform_device *pdev, + struct mtk_mbox_device *mbdev, unsigned int ipc_chan_id) +{ + + struct rpmsg_device *rpdev; + struct mtk_rpmsg_device_mbox *mdev; + int ret; + + mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + if (!mdev) + return NULL; + + mdev->pdev = pdev; + mdev->mbdev = mbdev; + mdev->ops = &mtk_rpmsg_ops; + rpdev = &mdev->rpdev; + rpdev->ops = &mtk_rpmsg_device_ops; + rpdev->src = ipc_chan_id; + rpdev->dev.parent = &pdev->dev; + rpdev->dev.release = mtk_rpmsg_release_device; + + ret = rpmsg_register_device(rpdev); + if (ret) { + kfree(mdev); + return NULL; + } + + return mdev; +} +EXPORT_SYMBOL_GPL(mtk_rpmsg_create_mbox_device); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek rpmsg driver"); + diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 750081dc83d72..994bd9a7574c1 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -26,6 +26,14 @@ config MTK_DEVAPC The violation information is logged for further analysis or countermeasures. +config MTK_MBOX + tristate "MediaTek Mbox Support" + help + Say yes here to add support for the MediaTek Mbox driver. + MTK MBOX is a physical H/W which consists of configurable 128 + or 256 bytes SRAM and 32 bit irq. The driver does read/write + SRAM and IRQ handling. + config MTK_INFRACFG bool "MediaTek INFRACFG Support" select REGMAP @@ -34,6 +42,16 @@ config MTK_INFRACFG INFRACFG controller contains various infrastructure registers not directly associated to any device. +config MTK_IPI + tristate "MediaTek IPI Support" + depends on RPMSG_MTK + help + Say yes here to add support for the MediaTek IPI between tinysys. + MTK IPI consists of APIs to do Linux to/from uP/DSP communication + based on rpmsg. Synchronization among tasks is also handled by + this layer. If uP/DSP drivers handle by themselves, they can use + rpmsg directly. + config MTK_PMIC_WRAP tristate "MediaTek PMIC Wrapper Support" depends on RESET_CONTROLLER diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 6830512848fd0..59265b1735988 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -8,3 +8,5 @@ obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o obj-$(CONFIG_MTK_SVS) += mtk-svs.o obj-$(CONFIG_MTK_SOCINFO) += mtk-socinfo.o +obj-$(CONFIG_MTK_IPI) += mtk_tinysys_ipi.o +obj-$(CONFIG_MTK_MBOX) += mtk-mbox.o diff --git a/drivers/soc/mediatek/mtk-mbox.c b/drivers/soc/mediatek/mtk-mbox.c new file mode 100644 index 0000000000000..215c94cbdf0ce --- /dev/null +++ b/drivers/soc/mediatek/mtk-mbox.c @@ -0,0 +1,1030 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define CREATE_TRACE_POINTS +#include + +/* + * memory copy to tiny + * @param dest: dest address + * @param src: src address + * @param size: memory size + */ +void mtk_memcpy_to_tinysys(void __iomem *dest, const void *src, uint32_t size) +{ + int i; + u32 __iomem *t = dest; + const u32 *s = src; + + for (i = 0; i < ((size + 3) >> 2); i++) + writel(*(s + i), t + i); +} + +/* + * memory copy from tiny + * @param dest: dest address + * @param src: src address + * @param size: memory size + */ +void mtk_memcpy_from_tinysys(void *dest, const void __iomem *src, uint32_t size) +{ + int i; + u32 *t = dest; + const u32 __iomem *s = src; + + for (i = 0; i < ((size + 3) >> 2); i++) + writel(*(s + i), t + i); +} + + +/* + * write data to mbox with ipi msg header + * function must in critical context + */ +int mtk_mbox_write_hd(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *msg) +{ + unsigned int slot_ofs, size; + struct mtk_mbox_info *minfo; + struct mtk_ipi_msg *ipimsg; + struct device *dev = mbdev->dev; + void __iomem *base; + uint32_t len; + unsigned long flags; + + if (!mbdev) { + dev_err(dev, "[MBOX]write header fail, dev null"); + return MBOX_PLT_ERR; + } + + if (mbox >= mbdev->count || !msg) { + dev_err(dev, "[MBOX]write header config err"); + return MBOX_PARA_ERR; + } + + minfo = &(mbdev->info_table[mbox]); + base = minfo->base; + slot_ofs = slot * MBOX_SLOT_SIZE; + size = minfo->slot; + ipimsg = (struct mtk_ipi_msg *)msg; + len = ipimsg->ipihd.len; + + if ((slot_ofs + sizeof(struct mtk_ipi_msg_hd) + len) + > size * MBOX_SLOT_SIZE) + return MBOX_WRITE_SZ_ERR; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + /*ipi header and payload*/ + if (mbdev->memcpy_to_tiny) { + mbdev->memcpy_to_tiny((void __iomem *)(base + slot_ofs), + ipimsg, sizeof(struct mtk_ipi_msg_hd)); + mbdev->memcpy_to_tiny((void __iomem *) + (base + slot_ofs + sizeof(struct mtk_ipi_msg_hd)), + ipimsg->data, len); + } else { + mtk_memcpy_to_tinysys((void __iomem *)(base + slot_ofs), + ipimsg, sizeof(struct mtk_ipi_msg_hd)); + mtk_memcpy_to_tinysys((void __iomem *) + (base + slot_ofs + sizeof(struct mtk_ipi_msg_hd)), + ipimsg->data, len); + } + + minfo->record.write_count++; + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_write_hd); + +/* + * read data from mbox with ipi msg header + * function must in critical context + */ +int mtk_mbox_read_hd(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *dest) +{ + unsigned int slot_ofs, size; + struct mtk_mbox_info *minfo; + struct mtk_ipi_msg_hd *ipihd; + struct device *dev = mbdev->dev; + void __iomem *base; + unsigned long flags; + + if (!mbdev) { + dev_err(dev, "[MBOX]read header fail, dev null"); + return MBOX_PLT_ERR; + } + + if (mbox >= mbdev->count || !dest) { + dev_err(dev, "[MBOX]read header config err"); + return MBOX_PARA_ERR; + } + + minfo = &(mbdev->info_table[mbox]); + base = minfo->base; + slot_ofs = slot * MBOX_SLOT_SIZE; + size = minfo->slot; + ipihd = (struct mtk_ipi_msg_hd *)(base + slot_ofs); + + if ((slot_ofs + sizeof(struct mtk_ipi_msg_hd) + ipihd->len) + > size * MBOX_SLOT_SIZE) + return MBOX_READ_SZ_ERR; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + /*ipi header and payload*/ + if (mbdev->memcpy_from_tiny) + mbdev->memcpy_from_tiny(dest, (void __iomem *) + (base + slot_ofs + sizeof(struct mtk_ipi_msg_hd)), + ipihd->len); + else + mtk_memcpy_from_tinysys(dest, (void __iomem *) + (base + slot_ofs + sizeof(struct mtk_ipi_msg_hd)), + ipihd->len); + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_read_hd); + +/* + * write data to mbox, function must in critical context + */ +int mtk_mbox_write(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *data, unsigned int len) +{ + unsigned int slot_ofs, size; + struct mtk_mbox_info *minfo; + struct device *dev = mbdev->dev; + void __iomem *base; + unsigned long flags; + + if (!mbdev) { + dev_err(dev, "[MBOX]write fail, dev or ptr null"); + return MBOX_PLT_ERR; + } + + if (mbox >= mbdev->count || !data) + return MBOX_PARA_ERR; + + minfo = &(mbdev->info_table[mbox]); + base = minfo->base; + slot_ofs = slot * MBOX_SLOT_SIZE; + size = minfo->slot; + + if (slot > size) + return MBOX_WRITE_SZ_ERR; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + if (mbdev->memcpy_to_tiny) + mbdev->memcpy_to_tiny((void __iomem *)(base + slot_ofs), data, len); + else + mtk_memcpy_to_tinysys((void __iomem *)(base + slot_ofs), data, len); + + minfo->record.write_count++; + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_write); + +/* + * read data to user buffer, function must in critical context + */ +int mtk_mbox_read(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *data, unsigned int len) +{ + unsigned int slot_ofs, size; + struct mtk_mbox_info *minfo; + struct device *dev = mbdev->dev; + void __iomem *base; + unsigned long flags; + + if (!mbdev || !data) { + dev_err(dev, "[MBOX]read fail,dev or ptr null"); + return MBOX_PLT_ERR; + } + + if (mbox >= mbdev->count) + return MBOX_PARA_ERR; + + minfo = &(mbdev->info_table[mbox]); + base = minfo->base; + slot_ofs = slot * MBOX_SLOT_SIZE; + size = minfo->slot; + + if (slot > size) + return MBOX_READ_SZ_ERR; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + if (mbdev->memcpy_from_tiny) + mbdev->memcpy_from_tiny(data, (void __iomem *)(base + slot_ofs), len); + else + mtk_memcpy_from_tinysys(data, (void __iomem *)(base + slot_ofs), len); + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_read); + +/* + * clear mbox irq, + * with read/write function must in critical context + */ +int mtk_mbox_clr_irq(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int irq) +{ + struct mtk_mbox_info *minfo; + + if (!mbdev) + return MBOX_PLT_ERR; + + if (mbox >= mbdev->count) + return MBOX_IRQ_ERR; + + minfo = &(mbdev->info_table[mbox]); + writel(irq, minfo->clr_irq_reg); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_clr_irq); + +/* + * trigger mbox irq, + * with read/write function must in critical context + */ +int mtk_mbox_trigger_irq(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int irq) +{ + struct mtk_mbox_info *minfo; + unsigned long flags; + + if (!mbdev) + return MBOX_PLT_ERR; + + if (mbox >= mbdev->count) + return MBOX_IRQ_ERR; + + minfo = &(mbdev->info_table[mbox]); + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + writel(irq, minfo->set_irq_reg); + minfo->record.trig_irq_count++; + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_trigger_irq); + +/* + * check mbox 32bits set irq reg status + * with read/write function must in critical context + * @return irq status 0: not triggered , other: irq triggered + */ +unsigned int mtk_mbox_check_send_irq(struct mtk_mbox_device *mbdev, + unsigned int mbox, unsigned int pin_index) +{ + struct mtk_mbox_info *minfo; + unsigned int reg, irq_state; + unsigned long flags; + + if (!mbdev) + return 0; + + if (mbox >= mbdev->count) + return 0; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + irq_state = 0; + minfo = &(mbdev->info_table[mbox]); + if (minfo->send_status_reg) + reg = readl(minfo->send_status_reg); + else + reg = readl(minfo->set_irq_reg); + + irq_state = (reg & (0x1 << pin_index)); + + if (irq_state) + minfo->record.busy_count++; + + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return irq_state; +} +EXPORT_SYMBOL_GPL(mtk_mbox_check_send_irq); + +/* + * check mbox 32bits clr irq reg status + * with read/write function must in critical context + * @return irq status 0: not triggered , other: irq triggered + */ +unsigned int mtk_mbox_read_recv_irq(struct mtk_mbox_device *mbdev, + unsigned int mbox) +{ + struct mtk_mbox_info *minfo; + unsigned int reg; + + if (!mbdev) + return 0; + + if (mbox >= mbdev->count) + return 0; + + minfo = &(mbdev->info_table[mbox]); + + if (minfo->recv_status_reg) + reg = readl(minfo->recv_status_reg); + else + reg = readl(minfo->clr_irq_reg); + + return reg; +} +EXPORT_SYMBOL_GPL(mtk_mbox_read_recv_irq); + +/* + * set mbox base address to init register + * + */ +int mtk_mbox_set_base_reg(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int addr) +{ + struct mtk_mbox_info *minfo; + + if (!mbdev) + return MBOX_PLT_ERR; + + if (mbox >= mbdev->count) + return MBOX_PARA_ERR; + + minfo = &(mbdev->info_table[mbox]); + writel(addr, minfo->init_base_reg); + + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_set_base_reg); + +/* + * set mbox base address, task context + * + */ +int mtk_mbox_set_base_addr(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int addr) +{ + struct mtk_mbox_info *minfo; + unsigned long flags; + int ret; + + if (!mbdev) + return MBOX_PLT_ERR; + + if (mbox >= mbdev->count) + return MBOX_PARA_ERR; + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + ret = mtk_mbox_set_base_reg(mbdev, mbox, addr); + + if (ret != MBOX_DONE) { + spin_unlock_irqrestore( + &mbdev->info_table[mbox].mbox_lock, flags); + return ret; + } + + minfo = &(mbdev->info_table[mbox]); + writel(addr, minfo->base); + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_set_base_addr); + +/* + * mtk_mbox_cb_register, register callback function + * + */ +int mtk_mbox_cb_register(struct mtk_mbox_device *mbdev, unsigned int pin_offset, + mbox_pin_cb_t mbox_pin_cb, void *prdata) +{ + struct mtk_mbox_pin_recv *pin_recv; + + if (!mbdev) + return MBOX_PLT_ERR; + + pin_recv = &(mbdev->pin_recv_table[pin_offset]); + pin_recv->mbox_pin_cb = mbox_pin_cb; + pin_recv->prdata = prdata; + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_cb_register); + +/* + * mbox polling, context is protected by mbox_lock + */ +int mtk_mbox_polling(struct mtk_mbox_device *mbdev, unsigned int mbox, + void *data, struct mtk_mbox_pin_recv *pin_recv) +{ + struct mtk_mbox_info *minfo; + unsigned long flags; + unsigned int reg, irq_state; + unsigned int recv_pin_index; + int ret; + + if (!mbdev) + return MBOX_PLT_ERR; + + if (mbox >= mbdev->count) + return MBOX_PARA_ERR; + + recv_pin_index = pin_recv->pin_index; + minfo = &(mbdev->info_table[mbox]); + + spin_lock_irqsave(&mbdev->info_table[mbox].mbox_lock, flags); + /* check lock for */ + if (atomic_read(&pin_recv->polling_lock) == MBOX_PIN_BUSY) { + spin_unlock_irqrestore( + &mbdev->info_table[mbox].mbox_lock, flags); + minfo->record.busy_count++; + return MBOX_PIN_BUSY; + } + /* check bit */ + reg = mtk_mbox_read_recv_irq(mbdev, mbox); + irq_state = (reg & (0x1 << recv_pin_index)); + + if (irq_state > 0) { + trace_mtk_mbox_polling(mbdev->name, reg, recv_pin_index); + ret = mtk_mbox_clr_irq(mbdev, mbox, irq_state); + } else { + spin_unlock_irqrestore( + &mbdev->info_table[mbox].mbox_lock, flags); + minfo->record.busy_count++; + return MBOX_PIN_BUSY; + } + + spin_unlock_irqrestore(&mbdev->info_table[mbox].mbox_lock, flags); + ret = mtk_mbox_read(mbdev, mbox, pin_recv->offset, data, + pin_recv->msg_size * MBOX_SLOT_SIZE); + + if (ret != MBOX_DONE) + return ret; + + pin_recv->recv_record.poll_count++; + + /* dump recv info */ + if (mbdev->log_enable) + mtk_mbox_dump_recv_pin(mbdev, pin_recv); + + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_polling); + +/* + * set lock status + */ +static void mtk_mbox_set_lock(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int lock) +{ + struct mtk_mbox_pin_recv *pin_recv; + int i; + + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + if (pin_recv->mbox != mbox) + continue; + atomic_set(&pin_recv->polling_lock, lock); + } +} + +/* + * mbox driver isr, in isr context + */ +static irqreturn_t mtk_mbox_isr(int irq, void *dev_id) +{ + unsigned int mbox, irq_status, irq_temp; + struct mtk_mbox_pin_recv *pin_recv; + struct mtk_mbox_info *minfo = (struct mtk_mbox_info *)dev_id; + struct mtk_mbox_device *mbdev = minfo->mbdev; + struct device *dev = mbdev->dev; + struct mtk_ipi_msg_hd *ipihead; + unsigned long flags; + const uint64_t timeout_time = 5 * 1000 * 1000; + uint64_t start_time = 0, end_time = 0, pre_cb_time = 0, post_cb_time = 0, cbtimediff = 0; + uint32_t execute_count = 0; + int ret; + int i; + + start_time = cpu_clock(0); + mbox = minfo->id; + ret = MBOX_DONE; + + spin_lock_irqsave(&minfo->mbox_lock, flags); + /* lock pin */ + mtk_mbox_set_lock(mbdev, mbox, MBOX_PIN_BUSY); + /* get irq status */ + irq_status = mtk_mbox_read_recv_irq(mbdev, mbox); + if (!minfo->record.irq_record) + minfo->record.irq_record = (uint32_t)irq_status; + irq_temp = 0; + spin_unlock_irqrestore(&minfo->mbox_lock, flags); + + trace_mtk_mbox_isr_entry(mbdev->name, irq_status); + + if (mbdev->pre_cb && mbdev->pre_cb(mbdev->prdata)) { + ret = MBOX_PRE_CB_ERR; + goto skip; + } + + pre_cb_time = cpu_clock(0); + + /* execute all receive pin handler */ + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + if (pin_recv->mbox != mbox) + continue; + /* recv irq trigger */ + if (((BIT(pin_recv->pin_index)) & irq_status) > 0x0) { + pin_recv->recv_record.recv_irq_count++; + irq_temp = irq_temp | (0x1 << pin_recv->pin_index); + if (!pin_recv->pin_buf) { + dev_err(dev, "[MBOX Error]null ptr dev=%s ipi_id=%d", + mbdev->name, pin_recv->chan_id); + WARN_ON_ONCE(1); + } + if (minfo->opt == MBOX_OPT_QUEUE_DIR || + minfo->opt == MBOX_OPT_QUEUE_SMEM) { + ipihead = (struct mtk_ipi_msg_hd *)(minfo->base + + (pin_recv->offset * MBOX_SLOT_SIZE)); + ret = mtk_mbox_read_hd(mbdev, mbox, + pin_recv->offset, pin_recv->pin_buf); + + if (pin_recv->recv_opt == MBOX_RECV_MESSAGE + && pin_recv->cb_ctx_opt + == MBOX_CB_IN_ISR + && pin_recv->mbox_pin_cb + && ret == MBOX_DONE) { + pin_recv->recv_record.pre_timestamp + = cpu_clock(0); + pin_recv->mbox_pin_cb(ipihead->id, + pin_recv->prdata, pin_recv->pin_buf, + (unsigned int)ipihead->len); + pin_recv->recv_record.post_timestamp + = cpu_clock(0); + pin_recv->recv_record.cb_count++; + execute_count++; + cbtimediff = pin_recv->recv_record.post_timestamp + - pin_recv->recv_record.pre_timestamp; + if (cbtimediff > timeout_time) { + dev_err(dev, "[MBOX Error]dev=%s ipi_id=%d, timeout=%llu\n", + mbdev->name, pin_recv->chan_id, cbtimediff); + } + } + } else { + ret = mtk_mbox_read(mbdev, mbox, + pin_recv->offset, pin_recv->pin_buf, + pin_recv->msg_size * MBOX_SLOT_SIZE); + + if (pin_recv->recv_opt == MBOX_RECV_MESSAGE + && pin_recv->cb_ctx_opt + == MBOX_CB_IN_ISR + && pin_recv->mbox_pin_cb + && ret == MBOX_DONE) { + pin_recv->recv_record.pre_timestamp + = cpu_clock(0); + pin_recv->mbox_pin_cb(pin_recv->chan_id, + pin_recv->prdata, pin_recv->pin_buf, + pin_recv->msg_size * MBOX_SLOT_SIZE); + pin_recv->recv_record.post_timestamp + = cpu_clock(0); + pin_recv->recv_record.cb_count++; + execute_count++; + cbtimediff = pin_recv->recv_record.post_timestamp + - pin_recv->recv_record.pre_timestamp; + if (cbtimediff > timeout_time) { + dev_err(dev, "[MBOX Error]dev=%s ipi_id=%d, timeout=%llu\n", + mbdev->name, pin_recv->chan_id, cbtimediff); + } + } + } + + if (ret != MBOX_DONE) + dev_err(dev, "[MBOX ISR]cp to buf fail,dev=%s chan=%d ret=%d", + mbdev->name, pin_recv->chan_id, ret); + + /* dump recv info */ + if (mbdev->log_enable) + mtk_mbox_dump_recv(mbdev, i); + } + } + + if (mbdev->post_cb && mbdev->post_cb(mbdev->prdata)) + ret = MBOX_POST_CB_ERR; + + post_cb_time = cpu_clock(0); +skip: + trace_mtk_mbox_isr_exit(mbdev->name, irq_status); + + if (ret == MBOX_PRE_CB_ERR) + dev_err(dev, "[MBOX ISR] pre_cb error, skip cb handle, dev=%s ret=%d", + mbdev->name, ret); + if (ret == MBOX_POST_CB_ERR) + dev_err(dev, "[MBOX ISR] post_cb error, dev=%s ret=%d", + mbdev->name, ret); + + spin_lock_irqsave(&minfo->mbox_lock, flags); + mtk_mbox_clr_irq(mbdev, mbox, irq_temp); + mtk_mbox_set_lock(mbdev, mbox, MBOX_DONE); + spin_unlock_irqrestore(&minfo->mbox_lock, flags); + + if (irq_temp == 0 && irq_status != 0) { + dev_err(dev, "[MBOX ISR]dev=%s pin table err, status=%x", + mbdev->name, irq_status); + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + mtk_mbox_dump_recv_pin(mbdev, pin_recv); + } + } + + /* notify all receive pin handler */ + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + if (pin_recv->mbox != mbox) + continue; + if (((0x1 << pin_recv->pin_index) & irq_status) > 0x0) { + /* notify task */ + if (mbdev->ipi_cb) { + mbdev->ipi_cb(pin_recv, mbdev->ipi_priv); + pin_recv->recv_record.notify_count++; + } + } + } + end_time = cpu_clock(0); + if (end_time - start_time > timeout_time) { + dev_err(dev, "[MBOX Error]dev=%s ipi_id=%d, start=%llu, pre_cb_time=%llu, cb_pre_time=%llu\n", + mbdev->name, pin_recv->chan_id, start_time, pre_cb_time, + pin_recv->recv_record.pre_timestamp); + dev_err(dev, "[MBOX Error]cb_post_time=%llu, post_cb_time=%llu, end=%llu, diff=%llu, count=%u\n", + pin_recv->recv_record.post_timestamp, post_cb_time, end_time, + end_time - start_time, execute_count); + } + return IRQ_HANDLED; +} + +/* + * mtk_smem_init, initial share memory + * + */ +int mtk_smem_init(struct platform_device *pdev, struct mtk_mbox_device *mbdev, + unsigned int mbox, void __iomem *base, + void __iomem *set_irq_reg, void __iomem *clr_irq_reg, + void __iomem *send_status_reg, void __iomem *recv_status_reg) +{ + struct mtk_mbox_info *minfo; + char name[32]; + int ret; + + minfo = &(mbdev->info_table[mbox]); + mbdev->dev = &pdev->dev; + + minfo->base = base; + minfo->set_irq_reg = set_irq_reg; + minfo->clr_irq_reg = clr_irq_reg; + minfo->send_status_reg = send_status_reg; + minfo->recv_status_reg = recv_status_reg; + minfo->enable = true; + minfo->id = mbox; + minfo->mbdev = mbdev; + minfo->is64d = 0; + spin_lock_init(&minfo->mbox_lock); + + snprintf(name, sizeof(name), "mbox%d", mbox); + minfo->irq_num = platform_get_irq_byname(pdev, name); + if (minfo->irq_num < 0) { + dev_err(&pdev->dev, "MBOX %d can't find IRQ\n", mbox); + goto smem_fail; + } + + ret = request_irq(minfo->irq_num, mtk_mbox_isr, IRQF_TRIGGER_NONE, + mbdev->name, (void *) minfo); + if (ret) { + dev_err(&pdev->dev, "MBOX %d request irq Failed\n", mbox); + goto smem_fail; + } + + return MBOX_DONE; + +smem_fail: + return MBOX_CONFIG_ERR; +} +EXPORT_SYMBOL_GPL(mtk_smem_init); + +/* + * mtk_mbox_probe , porbe and initial mbox + */ +int mtk_mbox_probe(struct platform_device *pdev, struct mtk_mbox_device *mbdev, + unsigned int mbox) +{ + struct mtk_mbox_info *minfo; + char name[32]; + int ret; + struct device *dev = &pdev->dev; + struct resource *res; + + minfo = &(mbdev->info_table[mbox]); + mbdev->dev = dev; + + if (pdev) { + snprintf(name, sizeof(name), "mbox%d_base", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->base = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->base)) + dev_err(&pdev->dev, "MBOX %d can't remap base\n", mbox); + + minfo->slot = (unsigned int)resource_size(res) / MBOX_SLOT_SIZE; + + /* init reg */ + snprintf(name, sizeof(name), "mbox%d_init", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->init_base_reg = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->init_base_reg)) + dev_err(&pdev->dev, "MBOX %d can't find init reg\n", mbox); + /* set irq reg */ + snprintf(name, sizeof(name), "mbox%d_set", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->set_irq_reg = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->set_irq_reg)) { + dev_err(&pdev->dev, "MBOX %d can't find set reg\n", mbox); + goto mtk_mbox_probe_fail; + } + /* clear reg */ + snprintf(name, sizeof(name), "mbox%d_clr", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->clr_irq_reg = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->clr_irq_reg)) { + dev_err(&pdev->dev, "MBOX %d can't find clr reg\n", mbox); + goto mtk_mbox_probe_fail; + } + /* send status reg */ + snprintf(name, sizeof(name), "mbox%d_send", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->send_status_reg = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->send_status_reg)) { + dev_err(&pdev->dev, "MBOX %d can't find send status reg\n", mbox); + minfo->send_status_reg = NULL; + } + /* recv status reg */ + snprintf(name, sizeof(name), "mbox%d_recv", mbox); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + minfo->recv_status_reg = devm_ioremap_resource(dev, res); + if (IS_ERR((void const *)minfo->recv_status_reg)) { + dev_err(&pdev->dev, "MBOX %d can't find recv status reg\n", mbox); + minfo->recv_status_reg = NULL; + } + + snprintf(name, sizeof(name), "mbox%d", mbox); + minfo->irq_num = platform_get_irq_byname(pdev, name); + if (minfo->irq_num < 0) { + dev_err(&pdev->dev, "MBOX %d can't find IRQ\n", mbox); + goto mtk_mbox_probe_fail; + } + + minfo->enable = true; + minfo->id = mbox; + minfo->mbdev = mbdev; + spin_lock_init(&minfo->mbox_lock); + + ret = request_irq(minfo->irq_num, mtk_mbox_isr, + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, mbdev->name, + (void *)minfo); + if (ret) { + dev_err(&pdev->dev, "MBOX %d request irq Failed\n", mbox); + goto mtk_mbox_probe_fail; + } + } + + return MBOX_DONE; + +mtk_mbox_probe_fail: + return MBOX_CONFIG_ERR; +} +EXPORT_SYMBOL_GPL(mtk_mbox_probe); + +void mtk_mbox_clr_index_record(struct mtk_mbox_device *mbdev, unsigned int mbox) +{ + struct mtk_mbox_info *minfo; + + if (!mbdev || mbox >= mbdev->count) + return; + + minfo = &(mbdev->info_table[mbox]); + minfo->record.irq_record = 0; +} +EXPORT_SYMBOL_GPL(mtk_mbox_clr_index_record); + +unsigned int mtk_mbox_get_index_record(struct mtk_mbox_device *mbdev, unsigned int mbox) +{ + struct mtk_mbox_info *minfo; + + if (!mbdev || mbox >= mbdev->count) + return 0; + + minfo = &(mbdev->info_table[mbox]); + return minfo->record.irq_record; +} +EXPORT_SYMBOL_GPL(mtk_mbox_get_index_record); + +/* + *mbox print receive pin function + */ +void mtk_mbox_print_recv(struct mtk_mbox_device *mbdev, + struct mtk_mbox_pin_recv *pin_recv) +{ + pr_notice("[MBOX]dev=%s recv mbox=%u off=%u cv_opt=%u ctx_opt=%u mg_sz=%u p_idx=%u id=%u\n", + mbdev->name, pin_recv->mbox, pin_recv->offset, pin_recv->recv_opt, + pin_recv->cb_ctx_opt, pin_recv->msg_size, pin_recv->pin_index, pin_recv->chan_id); + + pr_notice("[MBOX]dev=%s recv id=%u poll=%u cv_irq=%u noti=%u cb=%u pre=%lld po=%lld\n", + mbdev->name, pin_recv->chan_id, pin_recv->recv_record.poll_count, + pin_recv->recv_record.recv_irq_count, pin_recv->recv_record.notify_count, + pin_recv->recv_record.cb_count, pin_recv->recv_record.pre_timestamp, + pin_recv->recv_record.post_timestamp); +} +EXPORT_SYMBOL_GPL(mtk_mbox_print_recv); + +/* + *mbox print send pin function + */ +void mtk_mbox_print_send(struct mtk_mbox_device *mbdev, + struct mtk_mbox_pin_send *pin_send) +{ + pr_notice("[MBOX]dev=%s send mbox=%u off=%u s_opt=%u mg_sz=%u p_idx=%u id=%u\n", + mbdev->name, pin_send->mbox, pin_send->offset, pin_send->send_opt, + pin_send->msg_size, pin_send->pin_index, pin_send->chan_id); +} +EXPORT_SYMBOL_GPL(mtk_mbox_print_send); + +/* + *mbox print mbox function + */ +void mtk_mbox_print_minfo(struct mtk_mbox_device *mbdev, + struct mtk_mbox_info *minfo) +{ + pr_notice("[MBOX]dev=%s mbox id=%u slot=%u opt=%u base=%p set_reg=%p clr_reg=%p init_reg=%p s_sta=%p cv_sta=%p\n", + mbdev->name, minfo->id, minfo->slot, minfo->opt, minfo->base, + minfo->set_irq_reg, minfo->clr_irq_reg, minfo->init_base_reg, + minfo->send_status_reg, minfo->recv_status_reg); + + pr_notice("[MBOX]dev=%s write=%u busy=%u tri_irq=%u\n", + mbdev->name, minfo->record.write_count, minfo->record.busy_count, minfo->record.trig_irq_count); +} +EXPORT_SYMBOL_GPL(mtk_mbox_print_minfo); + +/* + *mbox information dump + */ +void mtk_mbox_dump_all(struct mtk_mbox_device *mbdev) +{ + struct mtk_mbox_pin_recv *pin_recv; + struct mtk_mbox_pin_send *pin_send; + struct mtk_mbox_info *minfo; + int i; + + if (!mbdev) + return; + + pr_notice("[MBOX]dev=%s recv count=%u send count=%u\n", + mbdev->name, mbdev->recv_count, mbdev->send_count); + + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + mtk_mbox_print_recv(mbdev, pin_recv); + } + + for (i = 0; i < mbdev->send_count; i++) { + pin_send = &(mbdev->pin_send_table[i]); + mtk_mbox_print_send(mbdev, pin_send); + } + + for (i = 0; i < mbdev->count; i++) { + minfo = &(mbdev->info_table[i]); + mtk_mbox_print_minfo(mbdev, minfo); + } +} +EXPORT_SYMBOL_GPL(mtk_mbox_dump_all); + +/* + *mbox single receive pin information dump + */ +void mtk_mbox_dump_recv(struct mtk_mbox_device *mbdev, unsigned int pin) +{ + struct mtk_mbox_pin_recv *pin_recv; + + if (mbdev) { + if (pin < mbdev->recv_count) { + pin_recv = &(mbdev->pin_recv_table[pin]); + mtk_mbox_print_recv(mbdev, pin_recv); + } + } +} +EXPORT_SYMBOL_GPL(mtk_mbox_dump_recv); + +/* + *mbox single receive pin information dump + */ +void mtk_mbox_dump_recv_pin(struct mtk_mbox_device *mbdev, + struct mtk_mbox_pin_recv *pin_recv) +{ + unsigned int irq_reg; + + if (mbdev && pin_recv) { + irq_reg = mtk_mbox_read_recv_irq(mbdev, pin_recv->mbox); + pr_err("[MBOX]dev=%s mbox=%u recv irq status=%x\n", + mbdev->name, pin_recv->mbox, irq_reg); + mtk_mbox_print_recv(mbdev, pin_recv); + } +} +EXPORT_SYMBOL_GPL(mtk_mbox_dump_recv_pin); + +/* + *mbox single send pin information dump + */ +void mtk_mbox_dump_send(struct mtk_mbox_device *mbdev, unsigned int pin) +{ + struct mtk_mbox_pin_send *pin_send; + + if (mbdev && pin < mbdev->send_count) { + pin_send = &(mbdev->pin_send_table[pin]); + mtk_mbox_print_send(mbdev, pin_send); + } +} +EXPORT_SYMBOL_GPL(mtk_mbox_dump_send); + +/* + *mbox single mbox information dump + */ +void mtk_mbox_dump(struct mtk_mbox_device *mbdev, unsigned int mbox) +{ + struct mtk_mbox_info *minfo; + + if (mbdev && mbox < mbdev->count) { + minfo = &(mbdev->info_table[mbox]); + mtk_mbox_print_minfo(mbdev, minfo); + } +} +EXPORT_SYMBOL_GPL(mtk_mbox_dump); + +/* + *mbox log enable function + */ +int mtk_mbox_log_enable(struct mtk_mbox_device *mbdev, bool enable) +{ + if (!mbdev) + return MBOX_PLT_ERR; + + mbdev->log_enable = enable; + return MBOX_DONE; +} +EXPORT_SYMBOL_GPL(mtk_mbox_log_enable); + +/* + *mbox reset record + */ +void mtk_mbox_reset_record(struct mtk_mbox_device *mbdev) +{ + struct mtk_mbox_pin_recv *pin_recv; + struct mtk_mbox_info *minfo; + int i; + + if (!mbdev) + return; + + for (i = 0; i < mbdev->recv_count; i++) { + pin_recv = &(mbdev->pin_recv_table[i]); + pin_recv->recv_record.poll_count = 0; + pin_recv->recv_record.recv_irq_count = 0; + pin_recv->recv_record.notify_count = 0; + pin_recv->recv_record.cb_count = 0; + pin_recv->recv_record.pre_timestamp = 0; + pin_recv->recv_record.post_timestamp = 0; + } + + for (i = 0; i < mbdev->count; i++) { + minfo = &(mbdev->info_table[i]); + minfo->record.write_count = 0; + minfo->record.busy_count = 0; + minfo->record.trig_irq_count = 0; + } + +} +EXPORT_SYMBOL_GPL(mtk_mbox_reset_record); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek Tinysys Mbox driver"); + diff --git a/drivers/soc/mediatek/mtk_tinysys_ipi.c b/drivers/soc/mediatek/mtk_tinysys_ipi.c new file mode 100644 index 0000000000000..064a17c008f98 --- /dev/null +++ b/drivers/soc/mediatek/mtk_tinysys_ipi.c @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MS_TO_NS(x) ((x)*1000000) +#define ts_before(ts) (cpu_clock(0) < (ts)) +#define ipi_delay() udelay(10) + +#define ipi_echo(en, fmt, args...) \ + ({ if (en) pr_info(fmt, ##args); }) + +static void ipi_isr_cb(struct mtk_mbox_pin_recv *pin, void *priv); + +static void ipi_monitor(struct mtk_ipi_device *ipidev, int id, int stage) +{ + unsigned long flags = 0; + struct mtk_ipi_chan_table *chan; + + chan = &ipidev->table[id]; + + spin_lock_irqsave(&ipidev->lock_monitor, flags); + switch (stage) { + case SEND_MSG: + chan->ipi_seqno++; + chan->ipi_record[0].idx = 0; + chan->ipi_record[0].ts = cpu_clock(0); + chan->ipi_record[1].idx = 4; + chan->ipi_record[1].ts = 0; + chan->ipi_record[2].idx = 5; + chan->ipi_record[2].ts = 0; + ipi_echo(ipidev->mbdev->log_enable, + "%s: IPI_%d send msg (#%d)\n", + ipidev->name, id, chan->ipi_seqno); + break; + case ISR_RECV_MSGV: + chan->ipi_seqno++; + chan->ipi_record[0].idx = 1; + chan->ipi_record[0].ts = cpu_clock(0); + chan->ipi_record[1].idx = 2; + chan->ipi_record[1].ts = 0; + chan->ipi_record[2].idx = 3; + chan->ipi_record[2].ts = 0; + break; + case RECV_MSG: + chan->ipi_record[1].ts = cpu_clock(0); + ipi_echo(ipidev->mbdev->log_enable, + "%s: IPI_%d recv msg (#%d)\n", + ipidev->name, id, chan->ipi_seqno); + break; + case RECV_ACK: + chan->ipi_record[2].ts = cpu_clock(0); + ipi_echo(ipidev->mbdev->log_enable, + "%s: IPI_%d recv ack (#%d)\n", + ipidev->name, id, chan->ipi_seqno); + break; + case ISR_RECV_ACK: + chan->ipi_record[1].ts = cpu_clock(0); + break; + case SEND_ACK: + chan->ipi_record[2].ts = cpu_clock(0); + ipi_echo(ipidev->mbdev->log_enable, + "%s: IPI_%d send ack (#%d)\n", + ipidev->name, id, chan->ipi_seqno); + break; + default: + break; + } + + chan->ipi_stage = stage; + + spin_unlock_irqrestore(&ipidev->lock_monitor, flags); +} + +static void ipi_timeout_dump(struct mtk_ipi_device *ipidev, int ipi_id) +{ + unsigned long flags = 0; + struct mtk_ipi_chan_table *chan; + + chan = &ipidev->table[ipi_id]; + + spin_lock_irqsave(&ipidev->lock_monitor, flags); + + dev_err(ipidev->dev, "Error: %s IPI %d timeout at %lld (last done is IPI %d)\n", + ipidev->name, ipi_id, cpu_clock(0), ipidev->ipi_last_done); + + dev_err(ipidev->dev, "IPI %d: seqno=%d, state=%d, t%d=%lld, t%d=%lld, t%d=%lld (trysend %d, polling %d\n", + ipi_id, chan->ipi_seqno, chan->ipi_stage, + chan->ipi_record[0].idx, chan->ipi_record[0].ts, + chan->ipi_record[1].idx, chan->ipi_record[1].ts, + chan->ipi_record[2].idx, chan->ipi_record[2].ts, + chan->trysend_count, chan->polling_count); + + spin_unlock_irqrestore(&ipidev->lock_monitor, flags); +} + +void ipi_monitor_dump(struct mtk_ipi_device *ipidev) +{ + int i; + unsigned int ipi_chan_count; + unsigned long flags = 0; + struct mtk_ipi_chan_table *chan; + + ipi_chan_count = ipidev->mrpdev->rpdev.src; + + dev_info(ipidev->dev, "%s dump IPIMonitor:\n", ipidev->name); + + spin_lock_irqsave(&ipidev->lock_monitor, flags); + + for (i = 0; i < ipi_chan_count; i++) { + chan = &ipidev->table[i]; + if (chan->ipi_stage == UNUSED) + continue; + dev_info(ipidev->dev, "IPI %d: seqno=%d, state=%d, t%d=%lld, t%d=%lld, t%d=%lld\n", + i, chan->ipi_seqno, chan->ipi_stage, + chan->ipi_record[0].idx, chan->ipi_record[0].ts, + chan->ipi_record[1].idx, chan->ipi_record[1].ts, + chan->ipi_record[2].idx, chan->ipi_record[2].ts); + } + + spin_unlock_irqrestore(&ipidev->lock_monitor, flags); +} +EXPORT_SYMBOL(ipi_monitor_dump); + +int mtk_ipi_device_register(struct mtk_ipi_device *ipidev, + struct platform_device *pdev, struct mtk_mbox_device *mbox, + unsigned int ipi_chan_count) +{ + int index; + char chan_name[RPMSG_NAME_SIZE]; + struct mtk_ipi_chan_table *ipi_chan_table; + struct mtk_rpmsg_device_mbox *mtk_rpdev; + struct mtk_rpmsg_channel_info_mbox *mtk_rpchan; + + if (!mbox || !ipi_chan_count) + return -EINVAL; + + if (!ipidev->name) + return -ENXIO; + + ipi_chan_table = kcalloc(ipi_chan_count, + sizeof(struct mtk_ipi_chan_table), GFP_KERNEL); + if (!ipi_chan_table) + return -ENOMEM; + + ipidev->dev = &pdev->dev; + + mtk_rpdev = mtk_rpmsg_create_mbox_device(pdev, mbox, ipi_chan_count); + if (!mtk_rpdev) { + dev_err(&pdev->dev, "%s create mtk rpmsg device fail.\n", ipidev->name); + kfree(ipi_chan_table); + return IPI_RPMSG_ERR; + } + + for (index = 0; index < ipi_chan_count; index++) { + snprintf(chan_name, RPMSG_NAME_SIZE, "%s_ipi#%d", + ipidev->name, index); + mtk_rpchan = mtk_rpmsg_create_channel(mtk_rpdev, index, chan_name); + if (!mtk_rpchan) { + dev_err(&pdev->dev, "%s create rpmsg channel %d fail.\n", + ipidev->name, index); + kfree(mtk_rpdev); + return IPI_RPMSG_ERR; + } + ipi_chan_table[index].rpchan = mtk_rpchan; + ipi_chan_table[index].ept = + rpmsg_create_ept(&(mtk_rpdev->rpdev), NULL, mtk_rpchan, + mtk_rpchan->info); + if (!ipi_chan_table[index].ept) + return -EINVAL; + ipi_chan_table[index].ipi_stage = UNUSED; + ipi_chan_table[index].ipi_seqno = 0; + atomic_set(&ipi_chan_table[index].holder, 0); + } + + mutex_init(&ipidev->mutex_ipi_reg); + spin_lock_init(&ipidev->lock_monitor); + ipidev->ipi_last_done = -1; + + for (index = 0; index < mbox->send_count; index++) { + mutex_init(&mbox->pin_send_table[index].mutex_send); + init_completion(&mbox->pin_send_table[index].comp_ack); + spin_lock_init(&mbox->pin_send_table[index].pin_lock); + ipi_chan_table[mbox->pin_send_table[index].chan_id].pin_send = + &mbox->pin_send_table[index]; + } + + for (index = 0; index < mbox->recv_count; index++) { + init_completion(&mbox->pin_recv_table[index].notify); + spin_lock_init(&mbox->pin_recv_table[index].pin_lock); + ipi_chan_table[mbox->pin_recv_table[index].chan_id].pin_recv = + &mbox->pin_recv_table[index]; + } + + mbox->ipi_cb = ipi_isr_cb; + mbox->ipi_priv = (void *)ipidev; + ipidev->mrpdev = mtk_rpdev; + ipidev->table = ipi_chan_table; + ipidev->mbdev = mbox; + ipidev->ipi_inited = 1; + + dev_dbg(&pdev->dev, "%s (with %d IPI) has registered.\n", + ipidev->name, ipi_chan_count); + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_device_register); + +int mtk_ipi_device_reset(struct mtk_ipi_device *ipidev) +{ + int index, chan_count; + unsigned long flags = 0; + struct mtk_ipi_chan_table *chan_table; + + if (!ipidev->table) + return -ENXIO; + + ipidev->ipi_inited = 0; + chan_count = ipidev->mrpdev->rpdev.src; + chan_table = ipidev->table; + + spin_lock_irqsave(&ipidev->lock_monitor, flags); + + for (index = 0; index < chan_count; index++) { + chan_table[index].ipi_stage = UNUSED; + chan_table[index].ipi_seqno = 0; + } + + ipidev->ipi_last_done = -1; + + spin_unlock_irqrestore(&ipidev->lock_monitor, flags); + + mtk_mbox_reset_record(ipidev->mbdev); + + ipidev->ipi_inited = 1; + + dev_info(ipidev->dev, "%s (with %d IPI) has reset.\n", + ipidev->name, chan_count); + + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_device_reset); + +int mtk_ipi_register(struct mtk_ipi_device *ipidev, int ipi_id, + mbox_pin_cb_t cb, void *prdata, void *msg) +{ + struct mtk_mbox_pin_recv *pin_recv; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + if (!msg) + return IPI_NO_MSGBUF; + + pin_recv = ipidev->table[ipi_id].pin_recv; + if (!pin_recv) + return IPI_UNAVAILABLE; + + mutex_lock(&ipidev->mutex_ipi_reg); + + if (pin_recv->pin_buf != NULL) { + mutex_unlock(&ipidev->mutex_ipi_reg); + return IPI_DUPLEX; + } + pin_recv->mbox_pin_cb = cb; + pin_recv->pin_buf = msg; + pin_recv->prdata = prdata; + + mutex_unlock(&ipidev->mutex_ipi_reg); + + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_register); + +int mtk_ipi_unregister(struct mtk_ipi_device *ipidev, int ipi_id) +{ + unsigned long flags = 0; + struct mtk_mbox_pin_recv *pin_recv; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + pin_recv = ipidev->table[ipi_id].pin_recv; + if (!pin_recv) + return IPI_UNAVAILABLE; + + mutex_lock(&ipidev->mutex_ipi_reg); + + /* Drop the ipi and reset the record */ + complete(&pin_recv->notify); + + spin_lock_irqsave(&ipidev->lock_monitor, flags); + ipidev->table[ipi_id].ipi_stage = UNUSED; + ipidev->table[ipi_id].ipi_seqno = 0; + spin_unlock_irqrestore(&ipidev->lock_monitor, flags); + + pin_recv->mbox_pin_cb = NULL; + pin_recv->pin_buf = NULL; + pin_recv->prdata = NULL; + + mutex_unlock(&ipidev->mutex_ipi_reg); + + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_unregister); + +int mtk_ipi_send(struct mtk_ipi_device *ipidev, int ipi_id, + int opt, void *data, int len, int timeout) +{ + struct mtk_mbox_pin_send *pin; + unsigned long flags = 0; + u64 timeover; + int ret; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + pin = ipidev->table[ipi_id].pin_send; + if (!pin) + return IPI_UNAVAILABLE; + + if (len > pin->msg_size) + return IPI_NO_MEMORY; + else if (!len) + len = pin->msg_size; + + if (ipidev->pre_cb && ipidev->pre_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] pre_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_PRE_CB_FAIL; + } + + if (opt == IPI_SEND_POLLING) { + if (mutex_is_locked(&pin->mutex_send)) { + dev_err(ipidev->dev, "Error: IPI '%s' has been used in WAIT mode\n", + ipidev->table[ipi_id].rpchan->info.name); + WARN_ON_ONCE(1); + } + spin_lock_irqsave(&pin->pin_lock, flags); + } else { + /* WAIT Mode: NOT be allowed in atomic/interrupt/IRQ disabled */ + if (preempt_count() || in_interrupt() || irqs_disabled()) { + dev_err(ipidev->dev, "IPI Panic: %s pin# %d, atomic=%d, interrupt=%ld, irq disabled=%d\n", + ipidev->name, ipi_id, preempt_count(), + in_interrupt(), irqs_disabled()); + WARN_ON_ONCE(1); + } + mutex_lock(&pin->mutex_send); + } + + timeover = cpu_clock(0) + MS_TO_NS(timeout); + + ret = rpmsg_trysend(ipidev->table[ipi_id].ept, data, len); + ipidev->table[ipi_id].trysend_count = 1; + + while (ret && ts_before(timeover)) { + ipi_delay(); + ret = rpmsg_trysend(ipidev->table[ipi_id].ept, data, len); + ipidev->table[ipi_id].trysend_count++; + } + + if (!ret) { + ipi_monitor(ipidev, ipi_id, SEND_MSG); + ipidev->ipi_last_done = ipi_id; + } + + if (opt == IPI_SEND_POLLING) + spin_unlock_irqrestore(&pin->pin_lock, flags); + else + mutex_unlock(&pin->mutex_send); + + if (ipidev->post_cb && ipidev->post_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] post_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_POST_CB_FAIL; + } + + if (ret == MBOX_PIN_BUSY) { + ipi_timeout_dump(ipidev, ipi_id); + return IPI_PIN_BUSY; + } else if (ret != IPI_ACTION_DONE) { + dev_err(ipidev->dev, "%s IPI %d send fail (%d)\n", + ipidev->name, ipi_id, ret); + return IPI_RPMSG_ERR; + } + + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_send); + +int mtk_ipi_recv(struct mtk_ipi_device *ipidev, int ipi_id) +{ + struct mtk_mbox_pin_recv *pin; + int ret = 0; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + pin = ipidev->table[ipi_id].pin_recv; + if (!pin) + return IPI_UNAVAILABLE; + + /* receive the ipi from ISR */ + ret = wait_for_completion_interruptible(&pin->notify); + /* return type 0 if completed, -ERESTARTSYS if interrupted + * system suspending will freeze task with a fake signal, + * so do nothing and just return any unfinished type to caller + */ + if (ret) + return IPI_FAKE_SIGNAL; + + ipi_monitor(ipidev, ipi_id, RECV_MSG); + ipidev->ipi_last_done = ipi_id; + + if (pin->mbox_pin_cb && pin->cb_ctx_opt == MBOX_CB_IN_PROCESS) + pin->mbox_pin_cb(ipi_id, pin->prdata, pin->pin_buf, + pin->msg_size); + + return IPI_ACTION_DONE; +} +EXPORT_SYMBOL(mtk_ipi_recv); + +int mtk_ipi_send_compl(struct mtk_ipi_device *ipidev, int ipi_id, + int opt, void *data, int len, unsigned long timeout) +{ + struct mtk_mbox_pin_send *pin_s; + struct mtk_mbox_pin_recv *pin_r; + unsigned long flags = 0; + u64 timeover; + int ret; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + pin_s = ipidev->table[ipi_id].pin_send; + pin_r = ipidev->table[ipi_id].pin_recv; + if (!pin_s || !pin_r) + return IPI_UNAVAILABLE; + + if (len > pin_s->msg_size) + return IPI_NO_MEMORY; + else if (!len) + len = pin_s->msg_size; + + + if (ipidev->pre_cb && ipidev->pre_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] pre_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_PRE_CB_FAIL; + } + + if (opt == IPI_SEND_POLLING) { + if (mutex_is_locked(&pin_s->mutex_send)) { + dev_err(ipidev->dev, "Error: IPI '%s' has been used in WAIT mode\n", + ipidev->table[ipi_id].rpchan->info.name); + WARN_ON_ONCE(1); + } + spin_lock_irqsave(&pin_s->pin_lock, flags); + } else { + /* WAIT Mode: NOT be allowed in atomic/interrupt/IRQ disabled */ + if (preempt_count() || in_interrupt() || irqs_disabled()) { + dev_err(ipidev->dev, "IPI Panic: %s pin# %d, atomic=%d, interrupt=%ld, irq disabled=%d\n", + ipidev->name, ipi_id, preempt_count(), + in_interrupt(), irqs_disabled()); + WARN_ON_ONCE(1); + } + mutex_lock(&pin_s->mutex_send); + } + + atomic_inc(&ipidev->table[ipi_id].holder); + + timeover = cpu_clock(0) + MS_TO_NS(timeout); + + ret = rpmsg_trysend(ipidev->table[ipi_id].ept, data, len); + ipidev->table[ipi_id].trysend_count = 1; + ipidev->table[ipi_id].polling_count = 0; + + while (ret && ts_before(timeover)) { + ipi_delay(); + ret = rpmsg_trysend(ipidev->table[ipi_id].ept, data, len); + ipidev->table[ipi_id].trysend_count++; + } + + if (ret) { + if (opt == IPI_SEND_POLLING) + spin_unlock_irqrestore(&pin_s->pin_lock, flags); + else + mutex_unlock(&pin_s->mutex_send); + + atomic_set(&ipidev->table[ipi_id].holder, 0); + + if (ipidev->post_cb && ipidev->post_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] post_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_POST_CB_FAIL; + } + + dev_err(ipidev->dev, "%s IPI %d send fail (%d)\n", + ipidev->name, ipi_id, ret); + return (ret == MBOX_PIN_BUSY) ? IPI_PIN_BUSY : IPI_RPMSG_ERR; + } + + ipi_monitor(ipidev, ipi_id, SEND_MSG); + + if (opt == IPI_SEND_POLLING) { + do { + ipidev->table[ipi_id].polling_count++; + if (mtk_mbox_polling(ipidev->mbdev, pin_r->mbox, + pin_r->pin_buf, pin_r) == MBOX_DONE) { + ret = 1; + break; + } + + if (try_wait_for_completion(&pin_r->notify)) { + ret = 1; + break; + } + + ipi_delay(); + } while (ts_before(timeover)); + } else { + /* WAIT Mode */ + timeover = ts_before(timeover) ? timeover - cpu_clock(0) : 0; + ret = wait_for_completion_timeout(&pin_r->notify, + nsecs_to_jiffies(timeover)); + } + + atomic_set(&ipidev->table[ipi_id].holder, 0); + + if (ret > 0) { + ipi_monitor(ipidev, ipi_id, RECV_ACK); + ipidev->ipi_last_done = ipi_id; + ret = IPI_ACTION_DONE; + } else { + mtk_mbox_dump_recv_pin(ipidev->mbdev, pin_r); + ipi_timeout_dump(ipidev, ipi_id); + if (ipidev->timeout_handler) + ipidev->timeout_handler(ipi_id); + ret = IPI_COMPL_TIMEOUT; + } + + if (opt == IPI_SEND_POLLING) + spin_unlock_irqrestore(&pin_s->pin_lock, flags); + else + mutex_unlock(&pin_s->mutex_send); + + if (ipidev->post_cb && ipidev->post_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] post_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_POST_CB_FAIL; + } + + return ret; +} +EXPORT_SYMBOL(mtk_ipi_send_compl); + +int mtk_ipi_recv_reply(struct mtk_ipi_device *ipidev, int ipi_id, + void *reply_data, int len) +{ + struct mtk_mbox_pin_send *pin_s; + struct mtk_mbox_pin_recv *pin_r; + unsigned long flags = 0; + int ret; + + if (!ipidev->ipi_inited) + return IPI_DEV_ILLEGAL; + + pin_r = ipidev->table[ipi_id].pin_recv; + pin_s = ipidev->table[ipi_id].pin_send; + if (!pin_r || !pin_s) + return IPI_UNAVAILABLE; + + if (len > pin_s->msg_size) + return IPI_NO_MEMORY; + else if (len == 0) + len = pin_s->msg_size; + + /* recvice the IPI message*/ + ret = wait_for_completion_interruptible(&pin_r->notify); + /* return type 0 if completed, -ERESTARTSYS if interrupted + * system suspending will freeze task with a fake signal, + * so do nothing and just return any unfinished type to caller + */ + if (ret) + return IPI_FAKE_SIGNAL; + + ipi_monitor(ipidev, ipi_id, RECV_MSG); + + if (pin_r->mbox_pin_cb && pin_r->cb_ctx_opt == MBOX_CB_IN_PROCESS) + pin_r->mbox_pin_cb(ipi_id, pin_r->prdata, pin_r->pin_buf, + pin_r->msg_size); + + /* send the response*/ + if (ipidev->pre_cb && ipidev->pre_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] pre_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_PRE_CB_FAIL; + } + + /* lock this pin until send ack*/ + spin_lock_irqsave(&pin_s->pin_lock, flags); + + ret = rpmsg_trysend(ipidev->table[ipi_id].ept, reply_data, len); + + if (ret == IPI_ACTION_DONE) { + ipi_monitor(ipidev, ipi_id, SEND_ACK); + ipidev->ipi_last_done = ipi_id; + } + + spin_unlock_irqrestore(&pin_s->pin_lock, flags); + + if (ipidev->post_cb && ipidev->post_cb(ipidev->prdata)) { + dev_err(ipidev->dev, "Error: IPI [%s] post_cb fail\n", + ipidev->table[ipi_id].rpchan->info.name); + return IPI_POST_CB_FAIL; + } + + if (ret == MBOX_PIN_BUSY) + return IPI_PIN_BUSY; + else if (ret != IPI_ACTION_DONE) { + dev_err(ipidev->dev, "%s IPI %d reply fail (%d)\n", + ipidev->name, ipi_id, ret); + return IPI_RPMSG_ERR; + } + + return ret; +} +EXPORT_SYMBOL(mtk_ipi_recv_reply); + +void mtk_ipi_tracking(struct mtk_ipi_device *ipidev, bool en) +{ + ipidev->mbdev->log_enable = en; + dev_info(ipidev->dev, "%s IPI tracking %s\n", ipidev->name, en ? "on" : "off"); +} +EXPORT_SYMBOL(mtk_ipi_tracking); + +static void ipi_isr_cb(struct mtk_mbox_pin_recv *pin, void *priv) +{ + struct mtk_ipi_device *ipidev = priv; + int ipi_id = pin->chan_id; + atomic_t holder = ipidev->table[ipi_id].holder; + + if (pin->recv_opt == MBOX_RECV_MESSAGE) { + ipi_monitor(ipidev, ipi_id, ISR_RECV_MSGV); + complete(&pin->notify); + } else if (atomic_read(&holder)) { + ipi_monitor(ipidev, ipi_id, ISR_RECV_ACK); + complete(&pin->notify); + } + +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek Tinysys IPI driver"); + diff --git a/include/linux/rpmsg/mtk_rpmsg.h b/include/linux/rpmsg/mtk_rpmsg.h index 363b60178040b..64908238604d4 100644 --- a/include/linux/rpmsg/mtk_rpmsg.h +++ b/include/linux/rpmsg/mtk_rpmsg.h @@ -8,6 +8,8 @@ #include #include +#include +#include typedef void (*ipi_handler_t)(void *data, unsigned int len, void *priv); @@ -29,10 +31,44 @@ struct mtk_rpmsg_info { int ns_ipi_id; }; +struct mtk_rpmsg_channel_info_mbox { + struct rpmsg_channel_info info; + unsigned int send_slot; + unsigned int recv_slot; + unsigned int send_slot_size; + unsigned int recv_slot_size; + unsigned int send_pin_index; + unsigned int recv_pin_index; + unsigned int send_pin_offset; + unsigned int recv_pin_offset; + unsigned int mbox; + spinlock_t channel_lock; +}; + +struct mtk_rpmsg_device_mbox { + struct rpmsg_device rpdev; + struct platform_device *pdev; + struct mtk_rpmsg_operations *ops; + struct mtk_mbox_device *mbdev; +}; + struct rproc_subdev * mtk_rpmsg_create_rproc_subdev(struct platform_device *pdev, struct mtk_rpmsg_info *info); void mtk_rpmsg_destroy_rproc_subdev(struct rproc_subdev *subdev); +/* + * create mtk rpmsg device + */ +struct mtk_rpmsg_device_mbox +*mtk_rpmsg_create_mbox_device(struct platform_device *pdev, + struct mtk_mbox_device *mbdev, unsigned int ipc_chan_id); +/* + * create mtk rpmsg channel + */ +struct mtk_rpmsg_channel_info_mbox * +mtk_rpmsg_create_channel(struct mtk_rpmsg_device_mbox *mdev, u32 chan_id, + char *name); + #endif diff --git a/include/linux/soc/mediatek/mtk-mbox.h b/include/linux/soc/mediatek/mtk-mbox.h new file mode 100644 index 0000000000000..09b869cf3e42c --- /dev/null +++ b/include/linux/soc/mediatek/mtk-mbox.h @@ -0,0 +1,318 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MTK_MBOX_H__ +#define __MTK_MBOX_H__ + +#include +#include +#include +#include + +/* + * mbox slot size definition + * 1 slot for 4 bytes + */ +#define MBOX_SLOT_SIZE 4 + +struct mtk_mbox_pin_send; +struct mtk_mbox_pin_recv; + +typedef int (*mbox_rx_cb_t)(void *); +typedef int (*mbox_pin_cb_t)(unsigned int ipi_id, void *prdata, void *data, + unsigned int len); +typedef void (*mbox_ipi_cb_t)(struct mtk_mbox_pin_recv *, void *); + +/* + * mbox receive information + * + * @poll_count: mbox polling success count + * @recv_irq_count: mbox receive irq count + * @notify_count: mbox irq notify count + * @cb_count: mbox execute callback function count + * @pre_timestamp: time stamp before callback function + * @post_timestamp: time stamp after callback function + */ +struct mtk_mbox_recv_record { + uint32_t poll_count; + uint32_t recv_irq_count; + uint32_t notify_count; + uint32_t cb_count; + uint64_t pre_timestamp; + uint64_t post_timestamp; +}; + +/* + * mbox record information + * + * write_count :mbox write success count + * busy_count :mbox read success count + * trig_irq_count :mbox trigger irq success count + * irq_record :mbox isr receive record + */ +struct mtk_mbox_record { + uint32_t write_count; + uint32_t busy_count; + uint32_t trig_irq_count; + uint32_t irq_record; +}; + +/* + * mbox pin structure, this is for send definition, + * ipi=endpoint=pin + * mbox : (mbox number)mbox number of the pin, up to 16(plt) + * offset : (slot)msg offset in share memory, up to 1024*4 KB(plt) + * send_opt : (opt)send opt, 0:send ,1: send for response(plt) + * lock : (lock)polling lock 0:unuse,1:used + * msg_size : (slot)message size in words, 4 bytes alignment(plt) + * pin_index : (bit offset)pin index in the mbox(plt) + * chan_id : (u32) ipc channel id(plt) + * mutex : (mutex)mutex for remote response + * completion : (completion)completion for remote response + * pin_lock : (spinlock_t)lock of the pin + * send_record: send pin record information + */ +struct mtk_mbox_pin_send { + unsigned int mbox : 4, + offset : 20, + send_opt : 2, + lock : 2; + unsigned int msg_size; + unsigned int pin_index; + unsigned int chan_id; + struct mutex mutex_send; + struct completion comp_ack; // to remove + spinlock_t pin_lock; +}; + +/* + * mbox pin structure, this is for receive definition, + * ipi=endpoint=pin + * mbox : (mbox number)mbox number of the pin, up to 16(plt) + * offset : (slot)msg offset in share memory, up to 1024*4 KB(plt) + * recv_opt : (opt)recv option, 0:receive ,1: response(plt) + * lock : (lock)polling lock 0:unuse,1:used + * buf_full_opt : (opt)buffer option 0:drop, 1:assert, 2:overwrite(plt) + * cb_ctx_opt : (opt)callback option 0:isr context, 1:process context(plt) + * msg_size : (slot)msg used slots in the mbox, 4 bytes alignment(plt) + * pin_index : (bit offset)pin index in the mbox(plt) + * chan_id : (u32) ipc channel id(plt) + * notify : (completion)notify process + * mbox_pin_cb: (cb)cb function + * pin_buf : (void*)buffer point + * prdata : (void*)private data + * pin_lock: (spinlock_t)lock of the pin + * recv_record: receive pin record information + */ +struct mtk_mbox_pin_recv { + unsigned int mbox; + unsigned int offset; + unsigned int recv_opt; + unsigned int lock; + unsigned int buf_full_opt; + unsigned int cb_ctx_opt; + unsigned int msg_size; + unsigned int pin_index; + unsigned int chan_id; + struct completion notify; + mbox_pin_cb_t mbox_pin_cb; + void *pin_buf; + void *prdata; + spinlock_t pin_lock; + struct mtk_mbox_recv_record recv_record; + atomic_t polling_lock; +}; + + +/* + * mtk mbox device,Mbox is a dedicate hardware of a tinysys consists of: + * 1) a share memory tightly coupled to the tinysys + * 2) several IRQs + * + * @ipi_cb: the callback handler for synchronization layer + * @ipi_priv: private data for synchronization layer + * @pre_cb: the callback handler in the begin of mbox receiving ipi + * @post_cb: the callback handler in the end of mbox receiving ipi + * @prdata: private data for the callback use + */ +struct mtk_mbox_device { + struct device *dev; + /* Identity of the device */ + const char *name; + unsigned int id; + /* Following are platform specific interface*/ + struct mtk_mbox_pin_recv *pin_recv_table; + struct mtk_mbox_pin_send *pin_send_table; + struct mtk_mbox_info *info_table; + unsigned int count; + unsigned int recv_count; + unsigned int send_count; + void (*memcpy_to_tiny)(void __iomem *dest, const void *src, int size); + void (*memcpy_from_tiny)(void *dest, const void __iomem *src, int size); + mbox_ipi_cb_t ipi_cb; + void *ipi_priv; + mbox_rx_cb_t pre_cb; + mbox_rx_cb_t post_cb; + void *prdata; + bool log_enable; +}; + +/* + * mbox callback function context definition + * 0: isr context, 1:process context + */ +enum MBOX_PIN_CTX { + MBOX_CB_IN_ISR = 0, + MBOX_CB_IN_PROCESS = 1, +}; + +/* + * mbox buffer full action definition + * 0:drop, 1:assert, 2:overwrite + */ +enum MBOX_BUF_OPT { + MBOX_BUF_FULL_DROP = 0, + MBOX_BUF_FULL_ASSERT = 1, + MBOX_BUF_FULL_OVERWRITE = 2, + MBOX_BUF_COPY_DONE = 3, + MBOX_BUF_FULL_RET = 4, +}; + +/* + * mbox recv action definition + * 0:receive message, 1:receive ack + */ +enum MBOX_RECV_OPT { + MBOX_RECV_MESSAGE = 0, + MBOX_RECV_ACK = 1, +}; + +/* + * mbox information + * + * mbdev :mbox device + * irq_num:identity of mbox irq + * id :mbox id + * slot :how many slots that mbox used + * opt :option for tx mode, 0:mbox, 1:share memory 2:queue + * enable :mbox status, 0:disable, 1: enable + * is64d :mbox is64d status, 0:32d, 1: 64d + * base :mbox base address + * set_irq_reg :mbox set irq register + * clr_irq_reg :mbox clear irq register + * init_base_reg:mbox initialize register + * mbox lock :lock of mbox + * record :mbox record information + */ +struct mtk_mbox_info { + struct mtk_mbox_device *mbdev; + int irq_num; + unsigned int id; + unsigned int slot; + unsigned int opt; + bool enable; + bool is64d; + void __iomem *base; + void __iomem *set_irq_reg; + void __iomem *clr_irq_reg; + void __iomem *init_base_reg; + void __iomem *send_status_reg; + void __iomem *recv_status_reg; + spinlock_t mbox_lock; + struct mtk_mbox_record record; +}; + +/* + * mbox return value definition + */ +enum MBOX_RETURN { + MBOX_POST_CB_ERR = -8, + MBOX_PRE_CB_ERR = -7, + MBOX_READ_SZ_ERR = -6, + MBOX_WRITE_SZ_ERR = -5, + MBOX_PARA_ERR = -4, + MBOX_CONFIG_ERR = -3, + MBOX_IRQ_ERR = -2, + MBOX_PLT_ERR = -1, + MBOX_DONE = 0, + MBOX_PIN_BUSY = 1, +}; + +/* + * mbox message options + * 0: mbox + * 1: share memory + * 2: mbox with queue + * 3: share memory with queue + */ +enum { + MBOX_OPT_DIRECT = 0, + MBOX_OPT_SMEM = 1, + MBOX_OPT_QUEUE_DIR = 2, + MBOX_OPT_QUEUE_SMEM = 3, +}; + +/* + * mtk ipi message header + * + * id :message id + * len :data length in byte + * options :options + * reserved :reserved + */ +struct mtk_ipi_msg_hd { + uint32_t id; + uint32_t len; + uint32_t options; + uint32_t reserved; +}; + +struct mtk_ipi_msg { + struct mtk_ipi_msg_hd ipihd; + void *data; +}; + +int mtk_mbox_write_hd(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *msg); +int mtk_mbox_read_hd(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *dest); +int mtk_mbox_write(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *data, unsigned int len); +int mtk_mbox_read(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int slot, void *data, unsigned int len); +int mtk_mbox_clr_irq(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int irq); +int mtk_mbox_trigger_irq(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int irq); +unsigned int mtk_mbox_read_recv_irq(struct mtk_mbox_device *mbdev, + unsigned int mbox); +int mtk_mbox_set_base_addr(struct mtk_mbox_device *mbdev, unsigned int mbox, + unsigned int addr); +unsigned int mtk_mbox_check_send_irq(struct mtk_mbox_device *mbdev, + unsigned int mbox, unsigned int pin_index); +int mtk_mbox_probe(struct platform_device *pdev, struct mtk_mbox_device *mbdev, + unsigned int mbox); +void mtk_mbox_clr_index_record(struct mtk_mbox_device *mbdev, + unsigned int mbox); +unsigned int mtk_mbox_get_index_record(struct mtk_mbox_device *mbdev, + unsigned int mbox); +int mtk_mbox_cb_register(struct mtk_mbox_device *mbdev, unsigned int pin_offset, + mbox_pin_cb_t mbox_pin_cb, void *prdata); +int mtk_mbox_polling(struct mtk_mbox_device *mbdev, unsigned int mbox, + void *data, struct mtk_mbox_pin_recv *pin_recv); +int mtk_smem_init(struct platform_device *pdev, struct mtk_mbox_device *mbdev, + unsigned int mbox, void __iomem *base, + void __iomem *set_irq_reg, void __iomem *clr_irq_reg, + void __iomem *send_status_reg, void __iomem *recv_status_reg); +void mtk_mbox_dump_all(struct mtk_mbox_device *mbdev); +void mtk_mbox_dump_recv(struct mtk_mbox_device *mbdev, unsigned int pin); +void mtk_mbox_dump_recv_pin(struct mtk_mbox_device *mbdev, + struct mtk_mbox_pin_recv *pin_recv); +void mtk_mbox_dump_send(struct mtk_mbox_device *mbdev, unsigned int pin); +void mtk_mbox_dump(struct mtk_mbox_device *mbdev, unsigned int mbox); +int mtk_mbox_log_enable(struct mtk_mbox_device *mbdev, bool enable); +void mtk_mbox_reset_record(struct mtk_mbox_device *mbdev); +#endif + diff --git a/include/linux/soc/mediatek/mtk_sip_svc.h b/include/linux/soc/mediatek/mtk_sip_svc.h index 0761128b43547..0cd46fae6b513 100644 --- a/include/linux/soc/mediatek/mtk_sip_svc.h +++ b/include/linux/soc/mediatek/mtk_sip_svc.h @@ -25,4 +25,6 @@ /* IOMMU related SMC call */ #define MTK_SIP_KERNEL_IOMMU_CONTROL MTK_SIP_SMC_CMD(0x514) +#define MTK_SIP_TINYSYS_SSPM_CONTROL MTK_SIP_SMC_CMD(0x53C) + #endif diff --git a/include/linux/soc/mediatek/mtk_tinysys_ipi.h b/include/linux/soc/mediatek/mtk_tinysys_ipi.h new file mode 100644 index 0000000000000..36ab18c2fd09e --- /dev/null +++ b/include/linux/soc/mediatek/mtk_tinysys_ipi.h @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MTK_TINYSYS_IPI_H__ +#define __MTK_TINYSYS_IPI_H__ + +#include +#include + +#define IPI_SEND_WAIT 0 +#define IPI_SEND_POLLING 1 + +enum mtk_ipi_dev { + IPI_DEV_SCP, + IPI_DEV_SAP, + IPI_DEV_SSPM, + IPI_DEV_ADSP, + IPI_DEV_MCUPM, + IPI_DEV_CPUEB, + IPI_DEV_APUSYS, + IPI_DEV_GPUEB, + IPI_DEV_VCP, + IPI_DEV_MMUP, + IPI_DEV_TOTAL, +}; + +enum ipi_stage { + SEND_MSG, + ISR_RECV_MSGV, + RECV_MSG, + SEND_ACK, + ISR_RECV_ACK, + RECV_ACK, + UNUSED = 0xF, +}; + +typedef int (*ipi_tx_cb_t)(void *); + +struct ipimon_s { + unsigned short idx; + unsigned long long ts; +}; + +/** + * struct mtk_ipi_chan_table - channel table that belong to mtk_ipi_device + * @ept: the rpmsg endpoint of this channel + * @rpchan: info used to create the endpoint + * @pin_send: the mbox send pin table address of this channel + * @pin_recv: the mbox receive pin table address of this channel + * @holder: keep 1 if there are ipi waiters (to wait the reply) + * @ipi_stage: transmission stage for t0~t5 (default is 0xF) + * @ipi_seqno: sequence count of the IPI pin processed + * @ipi_record: timestamp of each ipi transmission stage + * + * All of these data should be initialized by mtk_ipi_device_register() + */ +struct mtk_ipi_chan_table { + struct rpmsg_endpoint *ept; + struct mtk_rpmsg_channel_info_mbox *rpchan; + struct mtk_mbox_pin_send *pin_send; + struct mtk_mbox_pin_recv *pin_recv; + atomic_t holder; + unsigned int ipi_stage: 4, + ipi_seqno : 28; + struct ipimon_s ipi_record[3]; + int trysend_count; + int polling_count; +}; + +/** + * struct mtk_ipi_device - device for represent the tinysys using mtk ipi + * @name: name of tinysys device + * @id: device id (used to match between rpmsg drivers and devices) + * @mrpdev: mtk rpmsg channel device + * @mbdev: mtk mbox device + * @table: channel table with endpoint & channel_info & mbox_pin info + * @mutex_ipi_reg: the lock must be taken when user register ipi + * @pre_cb: the callback handler before ipi send data + * @post_cb: the callback handler after ipi send data + * @prdata: private data for the callback use + * @timeout_handler: the callback for waiting reply timeout + * @lock_monitor: the lock for dump ipi timestamp + * @ipi_last_done: the last processed ipi transmission + * @ipi_inited: set when mtk_ipi_device_register() done + * + * Tinysys platform has necessary to define the vcalue of 'name', 'id', 'mbdev'; + * and optional to define the 'pre_cb', 'post_cb', 'prdata', 'timeout_handler'. + * Othes would be initialized by mtk_ipi_device_register(). + */ +struct mtk_ipi_device { + struct device *dev; + const char *name; + int id; + struct mtk_rpmsg_device_mbox *mrpdev; + struct mtk_mbox_device *mbdev; + struct mtk_ipi_chan_table *table; + struct mutex mutex_ipi_reg; + ipi_tx_cb_t pre_cb; + ipi_tx_cb_t post_cb; + void *prdata; + void (*timeout_handler)(int id); + spinlock_t lock_monitor; + int ipi_last_done; + int ipi_inited; +}; + + +#define IPI_ACTION_DONE 0 +#define IPI_DEV_ILLEGAL -1 /* ipi device is not initial */ +#define IPI_DUPLEX -2 /* the ipi has be registered */ +#define IPI_UNAVAILABLE -3 /* can't find this ipi pin define */ +#define IPI_NO_MSGBUF -4 /* receiver doesn't has message buffer */ +#define IPI_NO_MEMORY -5 /* message length is large than defined */ +#define IPI_PIN_BUSY -6 /* send message timeout */ +#define IPI_COMPL_TIMEOUT -7 /* polling or wait for ack ipi timeout */ +#define IPI_PRE_CB_FAIL -8 /* pre-callback fail */ +#define IPI_POST_CB_FAIL -9 /* post-callback fail */ +#define IPI_FAKE_SIGNAL -10 +#define IPI_RPMSG_ERR -99 /* some error from rpmsg layer */ + + +int mtk_ipi_device_register(struct mtk_ipi_device *ipidev, + struct platform_device *pdev, struct mtk_mbox_device *mbox, + unsigned int ipi_chan_count); +int mtk_ipi_device_reset(struct mtk_ipi_device *ipidev); + +int mtk_ipi_register(struct mtk_ipi_device *ipidev, int ipi_id, + mbox_pin_cb_t cb, void *prdata, void *msg); +int mtk_ipi_unregister(struct mtk_ipi_device *ipidev, int ipi_id); + +int mtk_ipi_send(struct mtk_ipi_device *ipidev, int ipi_id, + int opt, void *data, int len, int timeout); +int mtk_ipi_send_compl(struct mtk_ipi_device *ipidev, int ipi_id, + int opt, void *data, int len, unsigned long timeout); +int mtk_ipi_recv(struct mtk_ipi_device *ipidev, int ipi_id); +int mtk_ipi_recv_reply(struct mtk_ipi_device *ipidev, int ipi_id, + void *reply_data, int len); + +void ipi_monitor_dump(struct mtk_ipi_device *ipidev); +void mtk_ipi_tracking(struct mtk_ipi_device *ipidev, bool en); + +#endif diff --git a/include/trace/events/mbox.h b/include/trace/events/mbox.h new file mode 100644 index 0000000000000..682829997bab7 --- /dev/null +++ b/include/trace/events/mbox.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 MediaTek Inc. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mbox + +#if !defined(_TRACE_MBOX_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MBOX_H + +#include + +TRACE_EVENT(mtk_mbox_isr_entry, + + TP_PROTO(const char *name, unsigned int irq_status), + + TP_ARGS(name, irq_status), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned int, irq_status) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->irq_status = irq_status; + ), + + TP_printk("[MBOX]dev=%s, irq_status=0x%x", __get_str(name), __entry->irq_status) +); + +TRACE_EVENT(mtk_mbox_isr_exit, + + TP_PROTO(const char *name, unsigned int irq_status), + + TP_ARGS(name, irq_status), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned int, irq_status) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->irq_status = irq_status; + ), + + TP_printk("[MBOX]dev=%s, irq_status=0x%x", __get_str(name), __entry->irq_status) +); + +TRACE_EVENT(mtk_mbox_polling, + + TP_PROTO(const char *name, unsigned int irq_status, unsigned int recv_pin_index), + + TP_ARGS(name, irq_status, recv_pin_index), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned int, irq_status) + __field(unsigned int, recv_pin_index) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->irq_status = irq_status; + __entry->recv_pin_index = recv_pin_index; + ), + + TP_printk("[MBOX]dev=%s polling irq_status=0x%x, recv_pin_index=%u before clear irq", + __get_str(name), __entry->irq_status, __entry->recv_pin_index) +); + +#endif /* _TRACE_MBOX_H */ + +/* This part must be outside protection */ +#include -- GitLab From 9ac7c36a19b1f00bfcb34bb440cad3e194093670 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Mon, 2 Oct 2023 17:04:33 +0800 Subject: [PATCH 373/456] UPSTREAM: ASoC: tas2781: fixed compiling issue in m68k fixed m68k compiling issue: mapping table can save code field; storing the dev_idx as a member of block can reduce unnecessary time and system resource comsumption of dev_idx mapping every time the block data writing to the dsp. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Iaffd91b24bc5775a955e7a8b33468577f60fa5e7 Signed-off-by: Shenghao Ding Link: https://lore.kernel.org/r/20231002090434.1896-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 4c556d1ea5a771a91f946964d931b4974a6b917e) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173860 Reviewed-by: Fei Shao Reviewed-by: Sean Paul Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- include/sound/tas2781-dsp.h | 5 + sound/soc/codecs/tas2781-fmwlib.c | 234 +++++++++++++----------------- 2 files changed, 107 insertions(+), 132 deletions(-) diff --git a/include/sound/tas2781-dsp.h b/include/sound/tas2781-dsp.h index af3319dab230a..3cda9da14f6d1 100644 --- a/include/sound/tas2781-dsp.h +++ b/include/sound/tas2781-dsp.h @@ -77,6 +77,11 @@ struct tasdev_blk { unsigned int nr_cmds; unsigned int blk_size; unsigned int nr_subblocks; + /* fixed m68k compiling issue, storing the dev_idx as a member of block + * can reduce unnecessary timeand system resource comsumption of + * dev_idx mapping every time the block data writing to the dsp. + */ + unsigned char dev_idx; unsigned char *data; }; diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 1cc64ed8de6da..557988027e908 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -79,10 +79,72 @@ struct tas_crc { unsigned char len; }; +struct blktyp_devidx_map { + unsigned char blktyp; + unsigned char dev_idx; +}; + static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = { 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4 }; +/* fixed m68k compiling issue: mapping table can save code field */ +static const struct blktyp_devidx_map ppc3_tas2781_mapping_table[] = { + { MAIN_ALL_DEVICES_1X, 0x80 }, + { MAIN_DEVICE_A_1X, 0x81 }, + { COEFF_DEVICE_A_1X, 0xC1 }, + { PRE_DEVICE_A_1X, 0xC1 }, + { PRE_SOFTWARE_RESET_DEVICE_A, 0xC1 }, + { POST_SOFTWARE_RESET_DEVICE_A, 0xC1 }, + { MAIN_DEVICE_B_1X, 0x82 }, + { COEFF_DEVICE_B_1X, 0xC2 }, + { PRE_DEVICE_B_1X, 0xC2 }, + { PRE_SOFTWARE_RESET_DEVICE_B, 0xC2 }, + { POST_SOFTWARE_RESET_DEVICE_B, 0xC2 }, + { MAIN_DEVICE_C_1X, 0x83 }, + { COEFF_DEVICE_C_1X, 0xC3 }, + { PRE_DEVICE_C_1X, 0xC3 }, + { PRE_SOFTWARE_RESET_DEVICE_C, 0xC3 }, + { POST_SOFTWARE_RESET_DEVICE_C, 0xC3 }, + { MAIN_DEVICE_D_1X, 0x84 }, + { COEFF_DEVICE_D_1X, 0xC4 }, + { PRE_DEVICE_D_1X, 0xC4 }, + { PRE_SOFTWARE_RESET_DEVICE_D, 0xC4 }, + { POST_SOFTWARE_RESET_DEVICE_D, 0xC4 }, +}; + +static const struct blktyp_devidx_map ppc3_mapping_table[] = { + { MAIN_ALL_DEVICES_1X, 0x80 }, + { MAIN_DEVICE_A_1X, 0x81 }, + { COEFF_DEVICE_A_1X, 0xC1 }, + { PRE_DEVICE_A_1X, 0xC1 }, + { MAIN_DEVICE_B_1X, 0x82 }, + { COEFF_DEVICE_B_1X, 0xC2 }, + { PRE_DEVICE_B_1X, 0xC2 }, + { MAIN_DEVICE_C_1X, 0x83 }, + { COEFF_DEVICE_C_1X, 0xC3 }, + { PRE_DEVICE_C_1X, 0xC3 }, + { MAIN_DEVICE_D_1X, 0x84 }, + { COEFF_DEVICE_D_1X, 0xC4 }, + { PRE_DEVICE_D_1X, 0xC4 }, +}; + +static const struct blktyp_devidx_map non_ppc3_mapping_table[] = { + { MAIN_ALL_DEVICES, 0x80 }, + { MAIN_DEVICE_A, 0x81 }, + { COEFF_DEVICE_A, 0xC1 }, + { PRE_DEVICE_A, 0xC1 }, + { MAIN_DEVICE_B, 0x82 }, + { COEFF_DEVICE_B, 0xC2 }, + { PRE_DEVICE_B, 0xC2 }, + { MAIN_DEVICE_C, 0x83 }, + { COEFF_DEVICE_C, 0xC3 }, + { PRE_DEVICE_C, 0xC3 }, + { MAIN_DEVICE_D, 0x84 }, + { COEFF_DEVICE_D, 0xC4 }, + { PRE_DEVICE_D, 0xC4 }, +}; + static struct tasdevice_config_info *tasdevice_add_config( struct tasdevice_priv *tas_priv, unsigned char *config_data, unsigned int config_size, int *status) @@ -314,6 +376,37 @@ out: } EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, SND_SOC_TAS2781_FMWLIB); +/* fixed m68k compiling issue: mapping table can save code field */ +static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw, + struct tasdev_blk *block) +{ + + struct blktyp_devidx_map *p = + (struct blktyp_devidx_map *)non_ppc3_mapping_table; + struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); + struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); + + int i, n = ARRAY_SIZE(non_ppc3_mapping_table); + unsigned char dev_idx = 0; + + if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) { + p = (struct blktyp_devidx_map *)ppc3_tas2781_mapping_table; + n = ARRAY_SIZE(ppc3_tas2781_mapping_table); + } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION) { + p = (struct blktyp_devidx_map *)ppc3_mapping_table; + n = ARRAY_SIZE(ppc3_mapping_table); + } + + for (i = 0; i < n; i++) { + if (block->type == p[i].blktyp) { + dev_idx = p[i].dev_idx; + break; + } + } + + return dev_idx; +} + static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw, struct tasdev_blk *block, const struct firmware *fmw, int offset) { @@ -349,6 +442,14 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw, block->nr_subblocks = get_unaligned_be32(&data[offset]); offset += 4; + /* fixed m68k compiling issue: + * 1. mapping table can save code field. + * 2. storing the dev_idx as a member of block can reduce unnecessary + * time and system resource comsumption of dev_idx mapping every + * time the block data writing to the dsp. + */ + block->dev_idx = map_dev_idx(tas_fmw, block); + if (offset + block->blk_size > fmw->size) { dev_err(tas_fmw->dev, "%s: nSublocks error\n", __func__); offset = -EINVAL; @@ -766,144 +867,13 @@ EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, SND_SOC_TAS2781_FMWLIB); static int tasdevice_load_block_kernel( struct tasdevice_priv *tasdevice, struct tasdev_blk *block) { - struct tasdevice_dspfw_hdr *fw_hdr = &(tasdevice->fmw->fw_hdr); - struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); const unsigned int blk_size = block->blk_size; unsigned int i, length; unsigned char *data = block->data; - unsigned char dev_idx = 0; - - if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) { - switch (block->type) { - case MAIN_ALL_DEVICES_1X: - dev_idx = 0x80; - break; - case MAIN_DEVICE_A_1X: - dev_idx = 0x81; - break; - case COEFF_DEVICE_A_1X: - case PRE_DEVICE_A_1X: - case PRE_SOFTWARE_RESET_DEVICE_A: - case POST_SOFTWARE_RESET_DEVICE_A: - dev_idx = 0xC1; - break; - case MAIN_DEVICE_B_1X: - dev_idx = 0x82; - break; - case COEFF_DEVICE_B_1X: - case PRE_DEVICE_B_1X: - case PRE_SOFTWARE_RESET_DEVICE_B: - case POST_SOFTWARE_RESET_DEVICE_B: - dev_idx = 0xC2; - break; - case MAIN_DEVICE_C_1X: - dev_idx = 0x83; - break; - case COEFF_DEVICE_C_1X: - case PRE_DEVICE_C_1X: - case PRE_SOFTWARE_RESET_DEVICE_C: - case POST_SOFTWARE_RESET_DEVICE_C: - dev_idx = 0xC3; - break; - case MAIN_DEVICE_D_1X: - dev_idx = 0x84; - break; - case COEFF_DEVICE_D_1X: - case PRE_DEVICE_D_1X: - case PRE_SOFTWARE_RESET_DEVICE_D: - case POST_SOFTWARE_RESET_DEVICE_D: - dev_idx = 0xC4; - break; - default: - dev_info(tasdevice->dev, - "%s: load block: Other Type = 0x%02x\n", - __func__, block->type); - break; - } - } else if (fw_fixed_hdr->ppcver >= - PPC3_VERSION) { - switch (block->type) { - case MAIN_ALL_DEVICES_1X: - dev_idx = 0x80; - break; - case MAIN_DEVICE_A_1X: - dev_idx = 0x81; - break; - case COEFF_DEVICE_A_1X: - case PRE_DEVICE_A_1X: - dev_idx = 0xC1; - break; - case MAIN_DEVICE_B_1X: - dev_idx = 0x82; - break; - case COEFF_DEVICE_B_1X: - case PRE_DEVICE_B_1X: - dev_idx = 0xC2; - break; - case MAIN_DEVICE_C_1X: - dev_idx = 0x83; - break; - case COEFF_DEVICE_C_1X: - case PRE_DEVICE_C_1X: - dev_idx = 0xC3; - break; - case MAIN_DEVICE_D_1X: - dev_idx = 0x84; - break; - case COEFF_DEVICE_D_1X: - case PRE_DEVICE_D_1X: - dev_idx = 0xC4; - break; - default: - dev_info(tasdevice->dev, - "%s: load block: Other Type = 0x%02x\n", - __func__, block->type); - break; - } - } else { - switch (block->type) { - case MAIN_ALL_DEVICES: - dev_idx = 0|0x80; - break; - case MAIN_DEVICE_A: - dev_idx = 0x81; - break; - case COEFF_DEVICE_A: - case PRE_DEVICE_A: - dev_idx = 0xC1; - break; - case MAIN_DEVICE_B: - dev_idx = 0x82; - break; - case COEFF_DEVICE_B: - case PRE_DEVICE_B: - dev_idx = 0xC2; - break; - case MAIN_DEVICE_C: - dev_idx = 0x83; - break; - case COEFF_DEVICE_C: - case PRE_DEVICE_C: - dev_idx = 0xC3; - break; - case MAIN_DEVICE_D: - dev_idx = 0x84; - break; - case COEFF_DEVICE_D: - case PRE_DEVICE_D: - dev_idx = 0xC4; - break; - default: - dev_info(tasdevice->dev, - "%s: load block: Other Type = 0x%02x\n", - __func__, block->type); - break; - } - } for (i = 0, length = 0; i < block->nr_subblocks; i++) { int rc = tasdevice_process_block(tasdevice, data + length, - dev_idx, blk_size - length); + block->dev_idx, blk_size - length); if (rc < 0) { dev_err(tasdevice->dev, "%s: %u %u sublock write error\n", -- GitLab From 25f92b46996f0838b632ee1105f6083165bb10bf Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 17 Oct 2023 18:04:36 +0100 Subject: [PATCH 374/456] UPSTREAM: ASoC: tas2781: make const read-only array magic_number static Don't populate the const read-only array magic_number on the stack, instead make it static const. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I2c1081c6f72511c2a4f3c0884b94114d441628f1 Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20231017170436.176615-1-colin.i.king@gmail.com Signed-off-by: Mark Brown (cherry picked from commit 9a4bf1f0be01582806e85322d18bf5c9f21d0b40) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173861 Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-fmwlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 557988027e908..86f7b165fd88e 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -1755,7 +1755,7 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv, { struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); - const unsigned char magic_number[] = { 0x35, 0x35, 0x35, 0x32 }; + static const unsigned char magic_number[] = { 0x35, 0x35, 0x35, 0x32 }; const unsigned char *buf = (unsigned char *)fmw->data; if (offset + 92 > fmw->size) { -- GitLab From 35dc70d7bf2b366ee53b4e1e4a1ebeda190630d1 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:17 +0800 Subject: [PATCH 375/456] UPSTREAM: ASoC: tas2562: move tas2563 from tas2562 driver to tas2781 driver Move tas2563 from tas2562 driver to tas2781 driver to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I1371c1430aa2410be9b8c7511c0321813e0fba3e Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-2-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 645994d21287a1ad2f637818d737f7a3d84e97d7) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173862 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2562.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index 962c2cdfa0174..54561ae598b87 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -59,7 +59,6 @@ struct tas2562_data { enum tas256x_model { TAS2562, - TAS2563, TAS2564, TAS2110, }; @@ -721,7 +720,6 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562) static const struct i2c_device_id tas2562_id[] = { { "tas2562", TAS2562 }, - { "tas2563", TAS2563 }, { "tas2564", TAS2564 }, { "tas2110", TAS2110 }, { } @@ -770,7 +768,6 @@ static int tas2562_probe(struct i2c_client *client) #ifdef CONFIG_OF static const struct of_device_id tas2562_of_match[] = { { .compatible = "ti,tas2562", }, - { .compatible = "ti,tas2563", }, { .compatible = "ti,tas2564", }, { .compatible = "ti,tas2110", }, { }, -- GitLab From ee66b280af5ef731e62f2b74d757605f1e1b16b2 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:19 +0800 Subject: [PATCH 376/456] UPSTREAM: ASoC: tas2781: Add tas2563 into driver Move tas2563 from tas2562 driver to tas2781 driver to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I74252fb63b25b9fd516b3cec7120d7ee0f55e8d7 Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-4-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 9f1bcd16e2bd41d758438f1d74e5f2d35f1e8c8e) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173863 Tested-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 43775c1944452..edd1ad3062c88 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 // -// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // // Copyright (C) 2022 - 2024 Texas Instruments Incorporated // https://www.ti.com // -// The TAS2781 driver implements a flexible and configurable +// The TAS2563/TAS2781 driver implements a flexible and configurable // algo coefficient setting for one, two, or even multiple -// TAS2781 chips. +// TAS2563/TAS2781 chips. // // Author: Shenghao Ding // Author: Kevin Lu @@ -32,6 +32,7 @@ #include static const struct i2c_device_id tasdevice_id[] = { + { "tas2563", TAS2563 }, { "tas2781", TAS2781 }, {} }; @@ -39,6 +40,7 @@ MODULE_DEVICE_TABLE(i2c, tasdevice_id); #ifdef CONFIG_OF static const struct of_device_id tasdevice_of_match[] = { + { .compatible = "ti,tas2563" }, { .compatible = "ti,tas2781" }, {}, }; -- GitLab From bf13e7d708025606284bf7cc575af8e8a41667fa Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:18 +0800 Subject: [PATCH 377/456] UPSTREAM: ASoC: tas2781: Add tas2563 into header file for DSP mode Move tas2563 from tas2562 header file to tas2781 header file to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I5aafeaf9a788db6d1a010d4a1bf557e569038170 Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-3-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit e9aa44736cb75e901d76ee59d80db1ae79d516f1) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173864 Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2781.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 21434191dd772..6f6e3e2f652c9 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -1,13 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ // -// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // // Copyright (C) 2022 - 2023 Texas Instruments Incorporated // https://www.ti.com // -// The TAS2781 driver implements a flexible and configurable +// The TAS2563/TAS2781 driver implements a flexible and configurable // algo coefficient setting for one, two, or even multiple -// TAS2781 chips. +// TAS2563/TAS2781 chips. // // Author: Shenghao Ding // Author: Kevin Lu @@ -60,7 +60,8 @@ #define TASDEVICE_CMD_FIELD_W 0x4 enum audio_device { - TAS2781 = 0, + TAS2563, + TAS2781, }; enum device_catlog_id { -- GitLab From 55d777fd2a05ef2dbb8db861dc8ec7505b8df06a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 16 Feb 2024 14:22:19 +0000 Subject: [PATCH 378/456] UPSTREAM: ASoC: tas2781: Remove redundant initialization of pointer 'data' The pointer 'data' being initialized with a value that is never read, it is being re-assigned inside a while-loop. The initialization is redundant and can be removed. Cleans up clang scan build warning sound/soc/codecs/tas2781-fmwlib.c:1534:17: warning: Value stored to 'data' during its initialization is never read [deadcode.DeadStores] BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I1f7adaad129423ad9da3a9135941798e85b8c29d Signed-off-by: Colin Ian King Link: https://msgid.link/r/20240216142219.2109050-1-colin.i.king@gmail.com Signed-off-by: Mark Brown (cherry picked from commit e480c0991db00b24b39010bfd56eda5ec2417186) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173865 Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-fmwlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 86f7b165fd88e..6474cc551d551 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -1529,7 +1529,7 @@ static int tasdev_load_blk(struct tasdevice_priv *tas_priv, unsigned int sleep_time; unsigned int len; unsigned int nr_cmds; - unsigned char *data = block->data; + unsigned char *data; unsigned char crc_chksum = 0; unsigned char offset; unsigned char book; -- GitLab From e94bd2921a6c2a0ef122641bf56688e2072eaff2 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Fri, 21 Jun 2024 21:23:07 +0800 Subject: [PATCH 379/456] UPSTREAM: ASoc: tas2781: Add name_prefix as the prefix name of firmwares and kcontrol to support corresponding TAS2563/TAS2781s Add name_prefix as the prefix name of firmwares and kcontrol to support corresponding TAS2563/TAS2781s. name_prefix is not mandatory. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Ida2916a9f49b5ae256d1fd576af3c12c008588ce Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240621132309.564-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 00dd4d86ed908e70d912a96ad91d1248ff055b62) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173866 Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2781.h | 1 + sound/soc/codecs/tas2781-comlib.c | 13 +++++++++---- sound/soc/codecs/tas2781-i2c.c | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 6f6e3e2f652c9..4240e9141092e 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -102,6 +102,7 @@ struct tasdevice_priv { unsigned char coef_binaryname[64]; unsigned char rca_binaryname[64]; unsigned char dev_name[32]; + const char *name_prefix; unsigned char ndev; unsigned int magic_num; unsigned int chip_id; diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c index 0444cf90c5119..01059a06fa181 100644 --- a/sound/soc/codecs/tas2781-comlib.c +++ b/sound/soc/codecs/tas2781-comlib.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 // -// tas2781-lib.c -- TAS2781 Common functions for HDA and ASoC Audio drivers +// TAS2781 Common functions for HDA and ASoC Audio drivers // -// Copyright 2023 Texas Instruments, Inc. +// Copyright 2023 - 2024 Texas Instruments, Inc. // // Author: Shenghao Ding @@ -276,8 +276,13 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, */ mutex_lock(&tas_priv->codec_lock); - scnprintf(tas_priv->rca_binaryname, 64, "%sRCA%d.bin", - tas_priv->dev_name, tas_priv->ndev); + if (tas_priv->name_prefix) + scnprintf(tas_priv->rca_binaryname, 64, "%s-%sRCA%d.bin", + tas_priv->name_prefix, tas_priv->dev_name, + tas_priv->ndev); + else + scnprintf(tas_priv->rca_binaryname, 64, "%sRCA%d.bin", + tas_priv->dev_name, tas_priv->ndev); crc8_populate_msb(tas_priv->crc8_lkp_tbl, TASDEVICE_CRC8_POLYNOMIAL); tas_priv->codec = codec; ret = request_firmware_nowait(module, FW_ACTION_UEVENT, diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index edd1ad3062c88..fc0f532532f4d 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -579,6 +579,7 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec) { struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + tas_priv->name_prefix = codec->name_prefix; return tascodec_init(tas_priv, codec, THIS_MODULE, tasdevice_fw_ready); } -- GitLab From 7cd562d965906540eca30274eabf97203fe7eec7 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Sat, 29 Jun 2024 18:11:10 +0800 Subject: [PATCH 380/456] UPSTREAM: ASoc: tas2781: Add name_prefix as the prefix name of DSP firmwares and calibrated data files Add name_prefix as the prefix name of DSP firmwares and calibrated data files which stored speaker calibrated impedance. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I4207bdf4659a4ba1f83b87637869fcbcd6a55cef Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240629101112.628-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 55f0a1fa6ea4e339c797e9a3292ca0caa4ab3885) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173867 Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index fc0f532532f4d..9ceba4084813b 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -394,8 +394,12 @@ static void tasdevice_fw_ready(const struct firmware *fmw, * failing to load DSP firmware is NOT an error. */ tas_priv->fw_state = TASDEVICE_RCA_FW_OK; - scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin", - tas_priv->dev_name); + if (tas_priv->name_prefix) + scnprintf(tas_priv->rca_binaryname, 64, "%s-%s_coef.bin", + tas_priv->name_prefix, tas_priv->dev_name); + else + scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin", + tas_priv->dev_name); ret = tasdevice_dsp_parser(tas_priv); if (ret) { dev_err(tas_priv->dev, "dspfw load %s error\n", @@ -418,8 +422,15 @@ static void tasdevice_fw_ready(const struct firmware *fmw, * calibrated data inside algo. */ for (i = 0; i < tas_priv->ndev; i++) { - scnprintf(tas_priv->cal_binaryname[i], 64, "%s_cal_0x%02x.bin", - tas_priv->dev_name, tas_priv->tasdevice[i].dev_addr); + if (tas_priv->name_prefix) + scnprintf(tas_priv->cal_binaryname[i], 64, + "%s-%s_cal_0x%02x.bin", tas_priv->name_prefix, + tas_priv->dev_name, + tas_priv->tasdevice[i].dev_addr); + else + scnprintf(tas_priv->cal_binaryname[i], 64, + "%s_cal_0x%02x.bin", tas_priv->dev_name, + tas_priv->tasdevice[i].dev_addr); ret = tas2781_load_calibration(tas_priv, tas_priv->cal_binaryname[i], i); if (ret != 0) -- GitLab From f72e598b35611fa88bb8db332dbf0e2a1956a242 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jul 2024 17:49:37 +0800 Subject: [PATCH 381/456] UPSTREAM: ASoc: tas2781: Set "Speaker Force Firmware Load" as the common kcontrol for both tas27871 and tas2563 Set "Speaker Force Firmware Load" as the common kcontrol for both tas27871 and tas2563 and move it into newly-created tasdevice_snd_controls, and keep the digital gain and analog gain in tas2781_snd_controls. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I4beccae00041f6812b3b26290afa52ba7011b180 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240704094939.1824-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit cabf0b0cff07bc8d6e80ab6a8f8a127a2708147b) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173868 Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Sean Paul Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 9ceba4084813b..8c5e254155d10 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -103,7 +103,7 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol, return tasdevice_amp_putvol(tas_priv, ucontrol, mc); } -static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, +static int tasdev_force_fwload_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = @@ -118,7 +118,7 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, return 0; } -static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, +static int tasdev_force_fwload_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = @@ -139,6 +139,11 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, return change; } +static const struct snd_kcontrol_new tasdevice_snd_controls[] = { + SOC_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, + tasdev_force_fwload_get, tasdev_force_fwload_put), +}; + static const struct snd_kcontrol_new tas2781_snd_controls[] = { SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL, 1, 0, 20, 0, tas2781_amp_getvol, @@ -146,8 +151,6 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = { SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Gain", TAS2781_DVC_LVL, 0, 0, 200, 1, tas2781_digital_getvol, tas2781_digital_putvol, dvc_tlv), - SOC_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, - tas2781_force_fwload_get, tas2781_force_fwload_put), }; static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol, @@ -589,6 +592,18 @@ static struct snd_soc_dai_driver tasdevice_dai_driver[] = { static int tasdevice_codec_probe(struct snd_soc_component *codec) { struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + int rc; + + if (tas_priv->chip_id == TAS2781) { + rc = snd_soc_add_component_controls(codec, + tas2781_snd_controls, + ARRAY_SIZE(tas2781_snd_controls)); + if (rc < 0) { + dev_err(tas_priv->dev, "%s: Add control err rc = %d", + __func__, rc); + return rc; + } + } tas_priv->name_prefix = codec->name_prefix; return tascodec_init(tas_priv, codec, THIS_MODULE, tasdevice_fw_ready); @@ -616,8 +631,8 @@ static const struct snd_soc_component_driver soc_codec_driver_tasdevice = { .probe = tasdevice_codec_probe, .remove = tasdevice_codec_remove, - .controls = tas2781_snd_controls, - .num_controls = ARRAY_SIZE(tas2781_snd_controls), + .controls = tasdevice_snd_controls, + .num_controls = ARRAY_SIZE(tasdevice_snd_controls), .dapm_widgets = tasdevice_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(tasdevice_dapm_widgets), .dapm_routes = tasdevice_audio_map, @@ -741,7 +756,7 @@ MODULE_DEVICE_TABLE(acpi, tasdevice_acpi_match); static struct i2c_driver tasdevice_i2c_driver = { .driver = { - .name = "tas2781-codec", + .name = "tasdev-codec", .of_match_table = of_match_ptr(tasdevice_of_match), #ifdef CONFIG_ACPI .acpi_match_table = ACPI_PTR(tasdevice_acpi_match), -- GitLab From feaf207954eee718d7ccc05e2c0ba129ad59ba92 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Tue, 9 Jul 2024 12:33:40 +0800 Subject: [PATCH 382/456] BACKPORT: UPSTREAM: ASoc: TAS2781: rename the tas2781_reset as tasdevice_reset Rename the tas2781_reset as tasdevice_reset in case of misunderstanding. RESET register for both tas2563 and tas2781 is same and the use of reset pin is also same. Conflicts: sound/pci/hda/tas2781_hda_i2c.c BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I0fd03d9880066e68d23ca6e94726ea2a2b6eeb1f Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240709043342.946-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit be5db7581f59621ed9cb9cbf6bebccda38263eb5) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173869 Reviewed-by: Yu-Che Cheng Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2781.h | 8 ++++---- sound/pci/hda/tas2781_hda_i2c.c | 4 ++-- sound/soc/codecs/tas2781-comlib.c | 8 ++++---- sound/soc/codecs/tas2781-i2c.c | 2 ++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 4240e9141092e..7826365b10e8c 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -2,7 +2,7 @@ // // ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // -// Copyright (C) 2022 - 2023 Texas Instruments Incorporated +// Copyright (C) 2022 - 2024 Texas Instruments Incorporated // https://www.ti.com // // The TAS2563/TAS2781 driver implements a flexible and configurable @@ -43,8 +43,8 @@ (page * 128)) + reg) /*Software Reset */ -#define TAS2781_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01) -#define TAS2781_REG_SWRESET_RESET BIT(0) +#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01) +#define TASDEVICE_REG_SWRESET_RESET BIT(0) /*I2C Checksum */ #define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) @@ -135,7 +135,7 @@ struct tasdevice_priv { void (*apply_calibration)(struct tasdevice_priv *tas_priv); }; -void tas2781_reset(struct tasdevice_priv *tas_dev); +void tasdevice_reset(struct tasdevice_priv *tas_dev); int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, struct module *module, void (*cont)(const struct firmware *fw, void *context)); diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 2459c705a6b34..2dfc32be4635a 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -818,7 +818,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) pm_runtime_put_autosuspend(tas_hda->dev); - tas2781_reset(tas_hda->priv); + tasdevice_reset(tas_hda->priv); ret = component_add(tas_hda->dev, &tas2781_hda_comp_ops); if (ret) { @@ -913,7 +913,7 @@ static int tas2781_system_resume(struct device *dev) tas_hda->priv->tasdevice[i].cur_prog = -1; tas_hda->priv->tasdevice[i].cur_conf = -1; } - tas2781_reset(tas_hda->priv); + tasdevice_reset(tas_hda->priv); tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog); /* If calibrated data occurs error, dsp will still work with default diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c index 01059a06fa181..28d8b4d7b9855 100644 --- a/sound/soc/codecs/tas2781-comlib.c +++ b/sound/soc/codecs/tas2781-comlib.c @@ -242,7 +242,7 @@ struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c) } EXPORT_SYMBOL_GPL(tasdevice_kzalloc); -void tas2781_reset(struct tasdevice_priv *tas_dev) +void tasdevice_reset(struct tasdevice_priv *tas_dev) { int ret, i; @@ -253,8 +253,8 @@ void tas2781_reset(struct tasdevice_priv *tas_dev) } else { for (i = 0; i < tas_dev->ndev; i++) { ret = tasdevice_dev_write(tas_dev, i, - TAS2781_REG_SWRESET, - TAS2781_REG_SWRESET_RESET); + TASDEVICE_REG_SWRESET, + TASDEVICE_REG_SWRESET_RESET); if (ret < 0) dev_err(tas_dev->dev, "dev %d swreset fail, %d\n", @@ -263,7 +263,7 @@ void tas2781_reset(struct tasdevice_priv *tas_dev) } usleep_range(1000, 1050); } -EXPORT_SYMBOL_GPL(tas2781_reset); +EXPORT_SYMBOL_GPL(tasdevice_reset); int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, struct module *module, diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 8c5e254155d10..bdfe9fec54138 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -724,6 +724,8 @@ static int tasdevice_i2c_probe(struct i2c_client *i2c) if (ret) goto err; + tasdevice_reset(tas_priv); + ret = devm_snd_soc_register_component(tas_priv->dev, &soc_codec_driver_tasdevice, tasdevice_dai_driver, ARRAY_SIZE(tasdevice_dai_driver)); -- GitLab From caeca0390d232264a44c4d62b4b6f378b107b9e3 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Wed, 10 Jul 2024 14:42:37 +0800 Subject: [PATCH 383/456] UPSTREAM: ASoC: tas2781: Add new Kontrol to set tas2563 digital Volume Requriment from customer to add new kcontrol to set tas2563 digital Volume BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I93aa27adb86ab91390ebc154141a36414dbb1061 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240710064238.1480-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 75ed63a5ab5d1d2872c735bc7edf8fef0e2fa2ea) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173870 Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2781-tlv.h | 262 ++++++++++++++++++++++++++++++++- include/sound/tas2781.h | 1 + sound/soc/codecs/tas2781-i2c.c | 129 ++++++++++++++-- 3 files changed, 382 insertions(+), 10 deletions(-) diff --git a/include/sound/tas2781-tlv.h b/include/sound/tas2781-tlv.h index 1dc59005d241f..99c41bfc7827e 100644 --- a/include/sound/tas2781-tlv.h +++ b/include/sound/tas2781-tlv.h @@ -2,7 +2,7 @@ // // ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier // -// Copyright (C) 2022 - 2023 Texas Instruments Incorporated +// Copyright (C) 2022 - 2024 Texas Instruments Incorporated // https://www.ti.com // // The TAS2781 driver implements a flexible and configurable @@ -17,5 +17,265 @@ static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0); static const DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); +static const DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); +/* pow(10, db/20) * pow(2,30) */ +static const unsigned char tas2563_dvc_table[][4] = { + { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */ + { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */ + { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */ + { 0X00, 0X00, 0X04, 0X31 }, /* -120.0db */ + { 0X00, 0X00, 0X04, 0X71 }, /* -119.5db */ + { 0X00, 0X00, 0X04, 0XB4 }, /* -119.0db */ + { 0X00, 0X00, 0X04, 0XFC }, /* -118.5db */ + { 0X00, 0X00, 0X05, 0X47 }, /* -118.0db */ + { 0X00, 0X00, 0X05, 0X97 }, /* -117.5db */ + { 0X00, 0X00, 0X05, 0XEC }, /* -117.0db */ + { 0X00, 0X00, 0X06, 0X46 }, /* -116.5db */ + { 0X00, 0X00, 0X06, 0XA5 }, /* -116.0db */ + { 0X00, 0X00, 0X07, 0X0A }, /* -115.5db */ + { 0X00, 0X00, 0X07, 0X75 }, /* -115.0db */ + { 0X00, 0X00, 0X07, 0XE6 }, /* -114.5db */ + { 0X00, 0X00, 0X08, 0X5E }, /* -114.0db */ + { 0X00, 0X00, 0X08, 0XDD }, /* -113.5db */ + { 0X00, 0X00, 0X09, 0X63 }, /* -113.0db */ + { 0X00, 0X00, 0X09, 0XF2 }, /* -112.5db */ + { 0X00, 0X00, 0X0A, 0X89 }, /* -112.0db */ + { 0X00, 0X00, 0X0B, 0X28 }, /* -111.5db */ + { 0X00, 0X00, 0X0B, 0XD2 }, /* -111.0db */ + { 0X00, 0X00, 0X0C, 0X85 }, /* -110.5db */ + { 0X00, 0X00, 0X0D, 0X43 }, /* -110.0db */ + { 0X00, 0X00, 0X0E, 0X0C }, /* -109.5db */ + { 0X00, 0X00, 0X0E, 0XE1 }, /* -109.0db */ + { 0X00, 0X00, 0X0F, 0XC3 }, /* -108.5db */ + { 0X00, 0X00, 0X10, 0XB2 }, /* -108.0db */ + { 0X00, 0X00, 0X11, 0XAF }, /* -107.5db */ + { 0X00, 0X00, 0X12, 0XBC }, /* -107.0db */ + { 0X00, 0X00, 0X13, 0XD8 }, /* -106.5db */ + { 0X00, 0X00, 0X15, 0X05 }, /* -106.0db */ + { 0X00, 0X00, 0X16, 0X44 }, /* -105.5db */ + { 0X00, 0X00, 0X17, 0X96 }, /* -105.0db */ + { 0X00, 0X00, 0X18, 0XFB }, /* -104.5db */ + { 0X00, 0X00, 0X1A, 0X76 }, /* -104.0db */ + { 0X00, 0X00, 0X1C, 0X08 }, /* -103.5db */ + { 0X00, 0X00, 0X1D, 0XB1 }, /* -103.0db */ + { 0X00, 0X00, 0X1F, 0X73 }, /* -102.5db */ + { 0X00, 0X00, 0X21, 0X51 }, /* -102.0db */ + { 0X00, 0X00, 0X23, 0X4A }, /* -101.5db */ + { 0X00, 0X00, 0X25, 0X61 }, /* -101.0db */ + { 0X00, 0X00, 0X27, 0X98 }, /* -100.5db */ + { 0X00, 0X00, 0X29, 0XF1 }, /* -100.0db */ + { 0X00, 0X00, 0X2C, 0X6D }, /* -99.5db */ + { 0X00, 0X00, 0X2F, 0X0F }, /* -99.0db */ + { 0X00, 0X00, 0X31, 0XD9 }, /* -98.5db */ + { 0X00, 0X00, 0X34, 0XCD }, /* -98.0db */ + { 0X00, 0X00, 0X37, 0XEE }, /* -97.5db */ + { 0X00, 0X00, 0X3B, 0X3F }, /* -97.0db */ + { 0X00, 0X00, 0X3E, 0XC1 }, /* -96.5db */ + { 0X00, 0X00, 0X42, 0X79 }, /* -96.0db */ + { 0X00, 0X00, 0X46, 0X6A }, /* -95.5db */ + { 0X00, 0X00, 0X4A, 0X96 }, /* -95.0db */ + { 0X00, 0X00, 0X4F, 0X01 }, /* -94.5db */ + { 0X00, 0X00, 0X53, 0XAF }, /* -94.0db */ + { 0X00, 0X00, 0X58, 0XA5 }, /* -93.5db */ + { 0X00, 0X00, 0X5D, 0XE6 }, /* -93.0db */ + { 0X00, 0X00, 0X63, 0X76 }, /* -92.5db */ + { 0X00, 0X00, 0X69, 0X5B }, /* -92.0db */ + { 0X00, 0X00, 0X6F, 0X99 }, /* -91.5db */ + { 0X00, 0X00, 0X76, 0X36 }, /* -91.0db */ + { 0X00, 0X00, 0X7D, 0X37 }, /* -90.5db */ + { 0X00, 0X00, 0X84, 0XA2 }, /* -90.0db */ + { 0X00, 0X00, 0X8C, 0X7E }, /* -89.5db */ + { 0X00, 0X00, 0X94, 0XD1 }, /* -89.0db */ + { 0X00, 0X00, 0X9D, 0XA3 }, /* -88.5db */ + { 0X00, 0X00, 0XA6, 0XFA }, /* -88.0db */ + { 0X00, 0X00, 0XB0, 0XDF }, /* -87.5db */ + { 0X00, 0X00, 0XBB, 0X5A }, /* -87.0db */ + { 0X00, 0X00, 0XC6, 0X74 }, /* -86.5db */ + { 0X00, 0X00, 0XD2, 0X36 }, /* -86.0db */ + { 0X00, 0X00, 0XDE, 0XAB }, /* -85.5db */ + { 0X00, 0X00, 0XEB, 0XDC }, /* -85.0db */ + { 0X00, 0X00, 0XF9, 0XD6 }, /* -84.5db */ + { 0X00, 0X01, 0X08, 0XA4 }, /* -84.0db */ + { 0X00, 0X01, 0X18, 0X52 }, /* -83.5db */ + { 0X00, 0X01, 0X28, 0XEF }, /* -83.0db */ + { 0X00, 0X01, 0X3A, 0X87 }, /* -82.5db */ + { 0X00, 0X01, 0X4D, 0X2A }, /* -82.0db */ + { 0X00, 0X01, 0X60, 0XE8 }, /* -81.5db */ + { 0X00, 0X01, 0X75, 0XD1 }, /* -81.0db */ + { 0X00, 0X01, 0X8B, 0XF7 }, /* -80.5db */ + { 0X00, 0X01, 0XA3, 0X6E }, /* -80.0db */ + { 0X00, 0X01, 0XBC, 0X48 }, /* -79.5db */ + { 0X00, 0X01, 0XD6, 0X9B }, /* -79.0db */ + { 0X00, 0X01, 0XF2, 0X7E }, /* -78.5db */ + { 0X00, 0X02, 0X10, 0X08 }, /* -78.0db */ + { 0X00, 0X02, 0X2F, 0X51 }, /* -77.5db */ + { 0X00, 0X02, 0X50, 0X76 }, /* -77.0db */ + { 0X00, 0X02, 0X73, 0X91 }, /* -76.5db */ + { 0X00, 0X02, 0X98, 0XC0 }, /* -76.0db */ + { 0X00, 0X02, 0XC0, 0X24 }, /* -75.5db */ + { 0X00, 0X02, 0XE9, 0XDD }, /* -75.0db */ + { 0X00, 0X03, 0X16, 0X0F }, /* -74.5db */ + { 0X00, 0X03, 0X44, 0XDF }, /* -74.0db */ + { 0X00, 0X03, 0X76, 0X76 }, /* -73.5db */ + { 0X00, 0X03, 0XAA, 0XFC }, /* -73.0db */ + { 0X00, 0X03, 0XE2, 0XA0 }, /* -72.5db */ + { 0X00, 0X04, 0X1D, 0X8F }, /* -72.0db */ + { 0X00, 0X04, 0X5B, 0XFD }, /* -71.5db */ + { 0X00, 0X04, 0X9E, 0X1D }, /* -71.0db */ + { 0X00, 0X04, 0XE4, 0X29 }, /* -70.5db */ + { 0X00, 0X05, 0X2E, 0X5A }, /* -70.0db */ + { 0X00, 0X05, 0X7C, 0XF2 }, /* -69.5db */ + { 0X00, 0X05, 0XD0, 0X31 }, /* -69.0db */ + { 0X00, 0X06, 0X28, 0X60 }, /* -68.5db */ + { 0X00, 0X06, 0X85, 0XC8 }, /* -68.0db */ + { 0X00, 0X06, 0XE8, 0XB9 }, /* -67.5db */ + { 0X00, 0X07, 0X51, 0X86 }, /* -67.0db */ + { 0X00, 0X07, 0XC0, 0X8A }, /* -66.5db */ + { 0X00, 0X08, 0X36, 0X21 }, /* -66.0db */ + { 0X00, 0X08, 0XB2, 0XB0 }, /* -65.5db */ + { 0X00, 0X09, 0X36, 0XA1 }, /* -65.0db */ + { 0X00, 0X09, 0XC2, 0X63 }, /* -64.5db */ + { 0X00, 0X0A, 0X56, 0X6D }, /* -64.0db */ + { 0X00, 0X0A, 0XF3, 0X3C }, /* -63.5db */ + { 0X00, 0X0B, 0X99, 0X56 }, /* -63.0db */ + { 0X00, 0X0C, 0X49, 0X48 }, /* -62.5db */ + { 0X00, 0X0D, 0X03, 0XA7 }, /* -62.0db */ + { 0X00, 0X0D, 0XC9, 0X11 }, /* -61.5db */ + { 0X00, 0X0E, 0X9A, 0X2D }, /* -61.0db */ + { 0X00, 0X0F, 0X77, 0XAD }, /* -60.5db */ + { 0X00, 0X10, 0X62, 0X4D }, /* -60.0db */ + { 0X00, 0X11, 0X5A, 0XD5 }, /* -59.5db */ + { 0X00, 0X12, 0X62, 0X16 }, /* -59.0db */ + { 0X00, 0X13, 0X78, 0XF0 }, /* -58.5db */ + { 0X00, 0X14, 0XA0, 0X50 }, /* -58.0db */ + { 0X00, 0X15, 0XD9, 0X31 }, /* -57.5db */ + { 0X00, 0X17, 0X24, 0X9C }, /* -57.0db */ + { 0X00, 0X18, 0X83, 0XAA }, /* -56.5db */ + { 0X00, 0X19, 0XF7, 0X86 }, /* -56.0db */ + { 0X00, 0X1B, 0X81, 0X6A }, /* -55.5db */ + { 0X00, 0X1D, 0X22, 0XA4 }, /* -55.0db */ + { 0X00, 0X1E, 0XDC, 0X98 }, /* -54.5db */ + { 0X00, 0X20, 0XB0, 0XBC }, /* -54.0db */ + { 0X00, 0X22, 0XA0, 0X9D }, /* -53.5db */ + { 0X00, 0X24, 0XAD, 0XE0 }, /* -53.0db */ + { 0X00, 0X26, 0XDA, 0X43 }, /* -52.5db */ + { 0X00, 0X29, 0X27, 0X9D }, /* -52.0db */ + { 0X00, 0X2B, 0X97, 0XE3 }, /* -51.5db */ + { 0X00, 0X2E, 0X2D, 0X27 }, /* -51.0db */ + { 0X00, 0X30, 0XE9, 0X9A }, /* -50.5db */ + { 0X00, 0X33, 0XCF, 0X8D }, /* -50.0db */ + { 0X00, 0X36, 0XE1, 0X78 }, /* -49.5db */ + { 0X00, 0X3A, 0X21, 0XF3 }, /* -49.0db */ + { 0X00, 0X3D, 0X93, 0XC3 }, /* -48.5db */ + { 0X00, 0X41, 0X39, 0XD3 }, /* -48.0db */ + { 0X00, 0X45, 0X17, 0X3B }, /* -47.5db */ + { 0X00, 0X49, 0X2F, 0X44 }, /* -47.0db */ + { 0X00, 0X4D, 0X85, 0X66 }, /* -46.5db */ + { 0X00, 0X52, 0X1D, 0X50 }, /* -46.0db */ + { 0X00, 0X56, 0XFA, 0XE8 }, /* -45.5db */ + { 0X00, 0X5C, 0X22, 0X4E }, /* -45.0db */ + { 0X00, 0X61, 0X97, 0XE1 }, /* -44.5db */ + { 0X00, 0X67, 0X60, 0X44 }, /* -44.0db */ + { 0X00, 0X6D, 0X80, 0X60 }, /* -43.5db */ + { 0X00, 0X73, 0XFD, 0X65 }, /* -43.0db */ + { 0X00, 0X7A, 0XDC, 0XD7 }, /* -42.5db */ + { 0X00, 0X82, 0X24, 0X8A }, /* -42.0db */ + { 0X00, 0X89, 0XDA, 0XAB }, /* -41.5db */ + { 0X00, 0X92, 0X05, 0XC6 }, /* -41.0db */ + { 0X00, 0X9A, 0XAC, 0XC8 }, /* -40.5db */ + { 0X00, 0XA3, 0XD7, 0X0A }, /* -40.0db */ + { 0X00, 0XAD, 0X8C, 0X52 }, /* -39.5db */ + { 0X00, 0XB7, 0XD4, 0XDD }, /* -39.0db */ + { 0X00, 0XC2, 0XB9, 0X65 }, /* -38.5db */ + { 0X00, 0XCE, 0X43, 0X28 }, /* -38.0db */ + { 0X00, 0XDA, 0X7B, 0XF1 }, /* -37.5db */ + { 0X00, 0XE7, 0X6E, 0X1E }, /* -37.0db */ + { 0X00, 0XF5, 0X24, 0XAC }, /* -36.5db */ + { 0X01, 0X03, 0XAB, 0X3D }, /* -36.0db */ + { 0X01, 0X13, 0X0E, 0X24 }, /* -35.5db */ + { 0X01, 0X23, 0X5A, 0X71 }, /* -35.0db */ + { 0X01, 0X34, 0X9D, 0XF8 }, /* -34.5db */ + { 0X01, 0X46, 0XE7, 0X5D }, /* -34.0db */ + { 0X01, 0X5A, 0X46, 0X27 }, /* -33.5db */ + { 0X01, 0X6E, 0XCA, 0XC5 }, /* -33.0db */ + { 0X01, 0X84, 0X86, 0X9F }, /* -32.5db */ + { 0X01, 0X9B, 0X8C, 0X27 }, /* -32.0db */ + { 0X01, 0XB3, 0XEE, 0XE5 }, /* -31.5db */ + { 0X01, 0XCD, 0XC3, 0X8C }, /* -31.0db */ + { 0X01, 0XE9, 0X20, 0X05 }, /* -30.5db */ + { 0X02, 0X06, 0X1B, 0X89 }, /* -30.0db */ + { 0X02, 0X24, 0XCE, 0XB0 }, /* -29.5db */ + { 0X02, 0X45, 0X53, 0X85 }, /* -29.0db */ + { 0X02, 0X67, 0XC5, 0XA2 }, /* -28.5db */ + { 0X02, 0X8C, 0X42, 0X3F }, /* -28.0db */ + { 0X02, 0XB2, 0XE8, 0X55 }, /* -27.5db */ + { 0X02, 0XDB, 0XD8, 0XAD }, /* -27.0db */ + { 0X03, 0X07, 0X36, 0X05 }, /* -26.5db */ + { 0X03, 0X35, 0X25, 0X29 }, /* -26.0db */ + { 0X03, 0X65, 0XCD, 0X13 }, /* -25.5db */ + { 0X03, 0X99, 0X57, 0X0C }, /* -25.0db */ + { 0X03, 0XCF, 0XEE, 0XCF }, /* -24.5db */ + { 0X04, 0X09, 0XC2, 0XB0 }, /* -24.0db */ + { 0X04, 0X47, 0X03, 0XC1 }, /* -23.5db */ + { 0X04, 0X87, 0XE5, 0XFB }, /* -23.0db */ + { 0X04, 0XCC, 0XA0, 0X6D }, /* -22.5db */ + { 0X05, 0X15, 0X6D, 0X68 }, /* -22.0db */ + { 0X05, 0X62, 0X8A, 0XB3 }, /* -21.5db */ + { 0X05, 0XB4, 0X39, 0XBC }, /* -21.0db */ + { 0X06, 0X0A, 0XBF, 0XD4 }, /* -20.5db */ + { 0X06, 0X66, 0X66, 0X66 }, /* -20.0db */ + { 0X06, 0XC7, 0X7B, 0X36 }, /* -19.5db */ + { 0X07, 0X2E, 0X50, 0XA6 }, /* -19.0db */ + { 0X07, 0X9B, 0X3D, 0XF6 }, /* -18.5db */ + { 0X08, 0X0E, 0X9F, 0X96 }, /* -18.0db */ + { 0X08, 0X88, 0XD7, 0X6D }, /* -17.5db */ + { 0X09, 0X0A, 0X4D, 0X2F }, /* -17.0db */ + { 0X09, 0X93, 0X6E, 0XB8 }, /* -16.5db */ + { 0X0A, 0X24, 0XB0, 0X62 }, /* -16.0db */ + { 0X0A, 0XBE, 0X8D, 0X70 }, /* -15.5db */ + { 0X0B, 0X61, 0X88, 0X71 }, /* -15.0db */ + { 0X0C, 0X0E, 0X2B, 0XB0 }, /* -14.5db */ + { 0X0C, 0XC5, 0X09, 0XAB }, /* -14.0db */ + { 0X0D, 0X86, 0XBD, 0X8D }, /* -13.5db */ + { 0X0E, 0X53, 0XEB, 0XB3 }, /* -13.0db */ + { 0X0F, 0X2D, 0X42, 0X38 }, /* -12.5db */ + { 0X10, 0X13, 0X79, 0X87 }, /* -12.0db */ + { 0X11, 0X07, 0X54, 0XF9 }, /* -11.5db */ + { 0X12, 0X09, 0XA3, 0X7A }, /* -11.0db */ + { 0X13, 0X1B, 0X40, 0X39 }, /* -10.5db */ + { 0X14, 0X3D, 0X13, 0X62 }, /* -10.0db */ + { 0X15, 0X70, 0X12, 0XE1 }, /* -9.5db */ + { 0X16, 0XB5, 0X43, 0X37 }, /* -9.0db */ + { 0X18, 0X0D, 0XB8, 0X54 }, /* -8.5db */ + { 0X19, 0X7A, 0X96, 0X7F }, /* -8.0db */ + { 0X1A, 0XFD, 0X13, 0X54 }, /* -7.5db */ + { 0X1C, 0X96, 0X76, 0XC6 }, /* -7.0db */ + { 0X1E, 0X48, 0X1C, 0X37 }, /* -6.5db */ + { 0X20, 0X13, 0X73, 0X9E }, /* -6.0db */ + { 0X21, 0XFA, 0X02, 0XBF }, /* -5.5db */ + { 0X23, 0XFD, 0X66, 0X78 }, /* -5.0db */ + { 0X26, 0X1F, 0X54, 0X1C }, /* -4.5db */ + { 0X28, 0X61, 0X9A, 0XE9 }, /* -4.0db */ + { 0X2A, 0XC6, 0X25, 0X91 }, /* -3.5db */ + { 0X2D, 0X4E, 0XFB, 0XD5 }, /* -3.0db */ + { 0X2F, 0XFE, 0X44, 0X48 }, /* -2.5db */ + { 0X32, 0XD6, 0X46, 0X17 }, /* -2.0db */ + { 0X35, 0XD9, 0X6B, 0X02 }, /* -1.5db */ + { 0X39, 0X0A, 0X41, 0X5F }, /* -1.0db */ + { 0X3C, 0X6B, 0X7E, 0X4F }, /* -0.5db */ + { 0X40, 0X00, 0X00, 0X00 }, /* 0.0db */ + { 0X43, 0XCA, 0XD0, 0X22 }, /* 0.5db */ + { 0X47, 0XCF, 0X26, 0X7D }, /* 1.0db */ + { 0X4C, 0X10, 0X6B, 0XA5 }, /* 1.5db */ + { 0X50, 0X92, 0X3B, 0XE3 }, /* 2.0db */ + { 0X55, 0X58, 0X6A, 0X46 }, /* 2.5db */ + { 0X5A, 0X67, 0X03, 0XDF }, /* 3.0db */ + { 0X5F, 0XC2, 0X53, 0X32 }, /* 3.5db */ + { 0X65, 0X6E, 0XE3, 0XDB }, /* 4.0db */ + { 0X6B, 0X71, 0X86, 0X68 }, /* 4.5db */ + { 0X71, 0XCF, 0X54, 0X71 }, /* 5.0db */ + { 0X78, 0X8D, 0XB4, 0XE9 }, /* 5.5db */ + { 0XFF, 0XFF, 0XFF, 0XFF }, /* 6.0db */ +}; #endif diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 7826365b10e8c..dbda552398b5b 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -50,6 +50,7 @@ #define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) /* Volume control */ +#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C) #define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A) #define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) #define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index bdfe9fec54138..bac5ea6d99b9b 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -30,6 +30,7 @@ #include #include #include +#include static const struct i2c_device_id tasdevice_id[] = { { "tas2563", TAS2563 }, @@ -139,6 +140,101 @@ static int tasdev_force_fwload_put(struct snd_kcontrol *kcontrol, return change; } +static int tas2563_digital_gain_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_dev = snd_soc_component_get_drvdata(codec); + unsigned int l = 0, r = mc->max; + unsigned int target, ar_mid, mid, ar_l, ar_r; + unsigned int reg = mc->reg; + unsigned char data[4]; + int ret; + + mutex_lock(&tas_dev->codec_lock); + /* Read the primary device */ + ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); + if (ret) { + dev_err(tas_dev->dev, "%s, get AMP vol error\n", __func__); + goto out; + } + + target = get_unaligned_be32(&data[0]); + + while (r > 1 + l) { + mid = (l + r) / 2; + ar_mid = get_unaligned_be32(tas2563_dvc_table[mid]); + if (target < ar_mid) + r = mid; + else + l = mid; + } + + ar_l = get_unaligned_be32(tas2563_dvc_table[l]); + ar_r = get_unaligned_be32(tas2563_dvc_table[r]); + + /* find out the member same as or closer to the current volume */ + ucontrol->value.integer.value[0] = + abs(target - ar_l) <= abs(target - ar_r) ? l : r; +out: + mutex_unlock(&tas_dev->codec_lock); + return 0; +} + +static int tas2563_digital_gain_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_dev = snd_soc_component_get_drvdata(codec); + int vol = ucontrol->value.integer.value[0]; + int status = 0, max = mc->max, rc = 1; + int i, ret; + unsigned int reg = mc->reg; + unsigned int volrd, volwr; + unsigned char data[4]; + + vol = clamp(vol, 0, max); + mutex_lock(&tas_dev->codec_lock); + /* Read the primary device */ + ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); + if (ret) { + dev_err(tas_dev->dev, "%s, get AMP vol error\n", __func__); + rc = -1; + goto out; + } + + volrd = get_unaligned_be32(&data[0]); + volwr = get_unaligned_be32(tas2563_dvc_table[vol]); + + if (volrd == volwr) { + rc = 0; + goto out; + } + + for (i = 0; i < tas_dev->ndev; i++) { + ret = tasdevice_dev_bulk_write(tas_dev, i, reg, + (unsigned char *)tas2563_dvc_table[vol], 4); + if (ret) { + dev_err(tas_dev->dev, + "%s, set digital vol error in dev %d\n", + __func__, i); + status |= BIT(i); + } + } + + if (status) + rc = -1; +out: + mutex_unlock(&tas_dev->codec_lock); + return rc; +} + static const struct snd_kcontrol_new tasdevice_snd_controls[] = { SOC_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, tasdev_force_fwload_get, tasdev_force_fwload_put), @@ -153,6 +249,13 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = { tas2781_digital_putvol, dvc_tlv), }; +static const struct snd_kcontrol_new tas2563_snd_controls[] = { + SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2563_DVC_LVL, 0, + 0, ARRAY_SIZE(tas2563_dvc_table) - 1, 0, + tas2563_digital_gain_get, tas2563_digital_gain_put, + tas2563_dvc_tlv), +}; + static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -592,17 +695,25 @@ static struct snd_soc_dai_driver tasdevice_dai_driver[] = { static int tasdevice_codec_probe(struct snd_soc_component *codec) { struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + struct snd_kcontrol_new *p; + unsigned int size; int rc; - if (tas_priv->chip_id == TAS2781) { - rc = snd_soc_add_component_controls(codec, - tas2781_snd_controls, - ARRAY_SIZE(tas2781_snd_controls)); - if (rc < 0) { - dev_err(tas_priv->dev, "%s: Add control err rc = %d", - __func__, rc); - return rc; - } + switch (tas_priv->chip_id) { + case TAS2781: + p = (struct snd_kcontrol_new *)tas2781_snd_controls; + size = ARRAY_SIZE(tas2781_snd_controls); + break; + default: + p = (struct snd_kcontrol_new *)tas2563_snd_controls; + size = ARRAY_SIZE(tas2563_snd_controls); + } + + rc = snd_soc_add_component_controls(codec, p, size); + if (rc < 0) { + dev_err(tas_priv->dev, "%s: Add control err rc = %d", + __func__, rc); + return rc; } tas_priv->name_prefix = codec->name_prefix; -- GitLab From e7c28914fad148c0c974e5c4ad2a712e792265d4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 19 Jul 2024 11:56:34 +0200 Subject: [PATCH 384/456] UPSTREAM: ALSA: hda: tas2781: mark const variables as __maybe_unused An earlier patch changed the DECLARE_TLV_DB_SCALE declaration, but now there are additional static const variables that cause the same build warnings: In file included from sound/pci/hda/tas2781_hda_i2c.c:23: include/sound/tas2781-tlv.h:23:28: error: 'tas2563_dvc_table' defined but not used [-Werror=unused-const-variable=] 23 | static const unsigned char tas2563_dvc_table[][4] = { | ^~~~~~~~~~~~~~~~~ In file included from include/sound/tlv.h:10, from sound/pci/hda/tas2781_hda_i2c.c:22: include/sound/tas2781-tlv.h:20:35: error: 'tas2563_dvc_tlv' defined but not used [-Werror=unused-const-variable=] 20 | static const DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); | ^~~~~~~~~~~~~~~ Mark them all as unused as well. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I4134349caf102701dd7f86db18aa703dd27f2aaa Signed-off-by: Arnd Bergmann Link: https://patch.msgid.link/20240719095640.3741247-1-arnd@kernel.org Signed-off-by: Takashi Iwai (cherry picked from commit a2d6d8aee4a4f694920bfaf6f6be3690e0f8d302) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173871 Tested-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2781-tlv.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/sound/tas2781-tlv.h b/include/sound/tas2781-tlv.h index 99c41bfc7827e..00fd4d449ff35 100644 --- a/include/sound/tas2781-tlv.h +++ b/include/sound/tas2781-tlv.h @@ -16,11 +16,11 @@ #define __TAS2781_TLV_H__ static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0); -static const DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); -static const DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); +static const __maybe_unused DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); +static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); /* pow(10, db/20) * pow(2,30) */ -static const unsigned char tas2563_dvc_table[][4] = { +static const __maybe_unused unsigned char tas2563_dvc_table[][4] = { { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */ { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */ { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */ -- GitLab From dcd764839f2ceb8752efc5bdf291b0dd007717bd Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Tue, 16 Jul 2024 14:41:17 +0800 Subject: [PATCH 385/456] UPSTREAM: ASoC: tas2781: Add TAS2563 into the Header Add TAS2563 into the Header in case of misunderstanding and add channel No information for error debug in tasdevice_dev_read. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Iabd92c1452afb73a76dbe875842e3c176f47f93f Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240716064120.158-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit e620b496c78706bb71691502e0381eb344afeaea) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173872 Tested-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-comlib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c index 28d8b4d7b9855..664c371796d63 100644 --- a/sound/soc/codecs/tas2781-comlib.c +++ b/sound/soc/codecs/tas2781-comlib.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// TAS2781 Common functions for HDA and ASoC Audio drivers +// TAS2563/TAS2781 Common functions for HDA and ASoC Audio drivers // // Copyright 2023 - 2024 Texas Instruments, Inc. // @@ -63,8 +63,8 @@ static int tasdevice_change_chn_book(struct tasdevice_priv *tas_priv, */ ret = regmap_write(map, TASDEVICE_PAGE_SELECT, 0); if (ret < 0) { - dev_err(tas_priv->dev, "%s, E=%d\n", - __func__, ret); + dev_err(tas_priv->dev, "%s, E=%d channel:%d\n", + __func__, ret, chn); goto out; } } -- GitLab From 9973ff84e315265dad7f1a0a5c01eecf685b1922 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Fri, 2 Aug 2024 15:20:52 +0800 Subject: [PATCH 386/456] UPSTREAM: ASoC: tas2781: Fix a compiling warning reported by robot kernel test due to adding tas2563_dvc_table Move tas2563_dvc_table into a separate Header file, as only tas2781 codec driver use this table, and hda side codec driver won't use it. Fixes: 75ed63a5ab5d ("ASoC: tas2781: Add new Kontrol to set tas2563 digital Volume") BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Idd8c39b52b08e6f639806e44269c423239dc239d Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240802072055.1462-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 92b796845a4a8789c2d9434c6a77baa88a99121e) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6173873 Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- include/sound/tas2563-tlv.h | 279 +++++++++++++++++++++++++++++++++ include/sound/tas2781-tlv.h | 260 ------------------------------ sound/soc/codecs/tas2781-i2c.c | 1 + 3 files changed, 280 insertions(+), 260 deletions(-) create mode 100644 include/sound/tas2563-tlv.h diff --git a/include/sound/tas2563-tlv.h b/include/sound/tas2563-tlv.h new file mode 100644 index 0000000000000..faa3e194f73b1 --- /dev/null +++ b/include/sound/tas2563-tlv.h @@ -0,0 +1,279 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// ALSA SoC Texas Instruments TAS2563 Audio Smart Amplifier +// +// Copyright (C) 2022 - 2024 Texas Instruments Incorporated +// https://www.ti.com +// +// The TAS2563 driver implements a flexible and configurable +// algo coefficient setting for one, two, or even multiple +// TAS2563 chips. +// +// Author: Shenghao Ding +// + +#ifndef __TAS2563_TLV_H__ +#define __TAS2563_TLV_H__ + +static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); + +/* pow(10, db/20) * pow(2,30) */ +static const unsigned char tas2563_dvc_table[][4] = { + { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */ + { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */ + { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */ + { 0X00, 0X00, 0X04, 0X31 }, /* -120.0db */ + { 0X00, 0X00, 0X04, 0X71 }, /* -119.5db */ + { 0X00, 0X00, 0X04, 0XB4 }, /* -119.0db */ + { 0X00, 0X00, 0X04, 0XFC }, /* -118.5db */ + { 0X00, 0X00, 0X05, 0X47 }, /* -118.0db */ + { 0X00, 0X00, 0X05, 0X97 }, /* -117.5db */ + { 0X00, 0X00, 0X05, 0XEC }, /* -117.0db */ + { 0X00, 0X00, 0X06, 0X46 }, /* -116.5db */ + { 0X00, 0X00, 0X06, 0XA5 }, /* -116.0db */ + { 0X00, 0X00, 0X07, 0X0A }, /* -115.5db */ + { 0X00, 0X00, 0X07, 0X75 }, /* -115.0db */ + { 0X00, 0X00, 0X07, 0XE6 }, /* -114.5db */ + { 0X00, 0X00, 0X08, 0X5E }, /* -114.0db */ + { 0X00, 0X00, 0X08, 0XDD }, /* -113.5db */ + { 0X00, 0X00, 0X09, 0X63 }, /* -113.0db */ + { 0X00, 0X00, 0X09, 0XF2 }, /* -112.5db */ + { 0X00, 0X00, 0X0A, 0X89 }, /* -112.0db */ + { 0X00, 0X00, 0X0B, 0X28 }, /* -111.5db */ + { 0X00, 0X00, 0X0B, 0XD2 }, /* -111.0db */ + { 0X00, 0X00, 0X0C, 0X85 }, /* -110.5db */ + { 0X00, 0X00, 0X0D, 0X43 }, /* -110.0db */ + { 0X00, 0X00, 0X0E, 0X0C }, /* -109.5db */ + { 0X00, 0X00, 0X0E, 0XE1 }, /* -109.0db */ + { 0X00, 0X00, 0X0F, 0XC3 }, /* -108.5db */ + { 0X00, 0X00, 0X10, 0XB2 }, /* -108.0db */ + { 0X00, 0X00, 0X11, 0XAF }, /* -107.5db */ + { 0X00, 0X00, 0X12, 0XBC }, /* -107.0db */ + { 0X00, 0X00, 0X13, 0XD8 }, /* -106.5db */ + { 0X00, 0X00, 0X15, 0X05 }, /* -106.0db */ + { 0X00, 0X00, 0X16, 0X44 }, /* -105.5db */ + { 0X00, 0X00, 0X17, 0X96 }, /* -105.0db */ + { 0X00, 0X00, 0X18, 0XFB }, /* -104.5db */ + { 0X00, 0X00, 0X1A, 0X76 }, /* -104.0db */ + { 0X00, 0X00, 0X1C, 0X08 }, /* -103.5db */ + { 0X00, 0X00, 0X1D, 0XB1 }, /* -103.0db */ + { 0X00, 0X00, 0X1F, 0X73 }, /* -102.5db */ + { 0X00, 0X00, 0X21, 0X51 }, /* -102.0db */ + { 0X00, 0X00, 0X23, 0X4A }, /* -101.5db */ + { 0X00, 0X00, 0X25, 0X61 }, /* -101.0db */ + { 0X00, 0X00, 0X27, 0X98 }, /* -100.5db */ + { 0X00, 0X00, 0X29, 0XF1 }, /* -100.0db */ + { 0X00, 0X00, 0X2C, 0X6D }, /* -99.5db */ + { 0X00, 0X00, 0X2F, 0X0F }, /* -99.0db */ + { 0X00, 0X00, 0X31, 0XD9 }, /* -98.5db */ + { 0X00, 0X00, 0X34, 0XCD }, /* -98.0db */ + { 0X00, 0X00, 0X37, 0XEE }, /* -97.5db */ + { 0X00, 0X00, 0X3B, 0X3F }, /* -97.0db */ + { 0X00, 0X00, 0X3E, 0XC1 }, /* -96.5db */ + { 0X00, 0X00, 0X42, 0X79 }, /* -96.0db */ + { 0X00, 0X00, 0X46, 0X6A }, /* -95.5db */ + { 0X00, 0X00, 0X4A, 0X96 }, /* -95.0db */ + { 0X00, 0X00, 0X4F, 0X01 }, /* -94.5db */ + { 0X00, 0X00, 0X53, 0XAF }, /* -94.0db */ + { 0X00, 0X00, 0X58, 0XA5 }, /* -93.5db */ + { 0X00, 0X00, 0X5D, 0XE6 }, /* -93.0db */ + { 0X00, 0X00, 0X63, 0X76 }, /* -92.5db */ + { 0X00, 0X00, 0X69, 0X5B }, /* -92.0db */ + { 0X00, 0X00, 0X6F, 0X99 }, /* -91.5db */ + { 0X00, 0X00, 0X76, 0X36 }, /* -91.0db */ + { 0X00, 0X00, 0X7D, 0X37 }, /* -90.5db */ + { 0X00, 0X00, 0X84, 0XA2 }, /* -90.0db */ + { 0X00, 0X00, 0X8C, 0X7E }, /* -89.5db */ + { 0X00, 0X00, 0X94, 0XD1 }, /* -89.0db */ + { 0X00, 0X00, 0X9D, 0XA3 }, /* -88.5db */ + { 0X00, 0X00, 0XA6, 0XFA }, /* -88.0db */ + { 0X00, 0X00, 0XB0, 0XDF }, /* -87.5db */ + { 0X00, 0X00, 0XBB, 0X5A }, /* -87.0db */ + { 0X00, 0X00, 0XC6, 0X74 }, /* -86.5db */ + { 0X00, 0X00, 0XD2, 0X36 }, /* -86.0db */ + { 0X00, 0X00, 0XDE, 0XAB }, /* -85.5db */ + { 0X00, 0X00, 0XEB, 0XDC }, /* -85.0db */ + { 0X00, 0X00, 0XF9, 0XD6 }, /* -84.5db */ + { 0X00, 0X01, 0X08, 0XA4 }, /* -84.0db */ + { 0X00, 0X01, 0X18, 0X52 }, /* -83.5db */ + { 0X00, 0X01, 0X28, 0XEF }, /* -83.0db */ + { 0X00, 0X01, 0X3A, 0X87 }, /* -82.5db */ + { 0X00, 0X01, 0X4D, 0X2A }, /* -82.0db */ + { 0X00, 0X01, 0X60, 0XE8 }, /* -81.5db */ + { 0X00, 0X01, 0X75, 0XD1 }, /* -81.0db */ + { 0X00, 0X01, 0X8B, 0XF7 }, /* -80.5db */ + { 0X00, 0X01, 0XA3, 0X6E }, /* -80.0db */ + { 0X00, 0X01, 0XBC, 0X48 }, /* -79.5db */ + { 0X00, 0X01, 0XD6, 0X9B }, /* -79.0db */ + { 0X00, 0X01, 0XF2, 0X7E }, /* -78.5db */ + { 0X00, 0X02, 0X10, 0X08 }, /* -78.0db */ + { 0X00, 0X02, 0X2F, 0X51 }, /* -77.5db */ + { 0X00, 0X02, 0X50, 0X76 }, /* -77.0db */ + { 0X00, 0X02, 0X73, 0X91 }, /* -76.5db */ + { 0X00, 0X02, 0X98, 0XC0 }, /* -76.0db */ + { 0X00, 0X02, 0XC0, 0X24 }, /* -75.5db */ + { 0X00, 0X02, 0XE9, 0XDD }, /* -75.0db */ + { 0X00, 0X03, 0X16, 0X0F }, /* -74.5db */ + { 0X00, 0X03, 0X44, 0XDF }, /* -74.0db */ + { 0X00, 0X03, 0X76, 0X76 }, /* -73.5db */ + { 0X00, 0X03, 0XAA, 0XFC }, /* -73.0db */ + { 0X00, 0X03, 0XE2, 0XA0 }, /* -72.5db */ + { 0X00, 0X04, 0X1D, 0X8F }, /* -72.0db */ + { 0X00, 0X04, 0X5B, 0XFD }, /* -71.5db */ + { 0X00, 0X04, 0X9E, 0X1D }, /* -71.0db */ + { 0X00, 0X04, 0XE4, 0X29 }, /* -70.5db */ + { 0X00, 0X05, 0X2E, 0X5A }, /* -70.0db */ + { 0X00, 0X05, 0X7C, 0XF2 }, /* -69.5db */ + { 0X00, 0X05, 0XD0, 0X31 }, /* -69.0db */ + { 0X00, 0X06, 0X28, 0X60 }, /* -68.5db */ + { 0X00, 0X06, 0X85, 0XC8 }, /* -68.0db */ + { 0X00, 0X06, 0XE8, 0XB9 }, /* -67.5db */ + { 0X00, 0X07, 0X51, 0X86 }, /* -67.0db */ + { 0X00, 0X07, 0XC0, 0X8A }, /* -66.5db */ + { 0X00, 0X08, 0X36, 0X21 }, /* -66.0db */ + { 0X00, 0X08, 0XB2, 0XB0 }, /* -65.5db */ + { 0X00, 0X09, 0X36, 0XA1 }, /* -65.0db */ + { 0X00, 0X09, 0XC2, 0X63 }, /* -64.5db */ + { 0X00, 0X0A, 0X56, 0X6D }, /* -64.0db */ + { 0X00, 0X0A, 0XF3, 0X3C }, /* -63.5db */ + { 0X00, 0X0B, 0X99, 0X56 }, /* -63.0db */ + { 0X00, 0X0C, 0X49, 0X48 }, /* -62.5db */ + { 0X00, 0X0D, 0X03, 0XA7 }, /* -62.0db */ + { 0X00, 0X0D, 0XC9, 0X11 }, /* -61.5db */ + { 0X00, 0X0E, 0X9A, 0X2D }, /* -61.0db */ + { 0X00, 0X0F, 0X77, 0XAD }, /* -60.5db */ + { 0X00, 0X10, 0X62, 0X4D }, /* -60.0db */ + { 0X00, 0X11, 0X5A, 0XD5 }, /* -59.5db */ + { 0X00, 0X12, 0X62, 0X16 }, /* -59.0db */ + { 0X00, 0X13, 0X78, 0XF0 }, /* -58.5db */ + { 0X00, 0X14, 0XA0, 0X50 }, /* -58.0db */ + { 0X00, 0X15, 0XD9, 0X31 }, /* -57.5db */ + { 0X00, 0X17, 0X24, 0X9C }, /* -57.0db */ + { 0X00, 0X18, 0X83, 0XAA }, /* -56.5db */ + { 0X00, 0X19, 0XF7, 0X86 }, /* -56.0db */ + { 0X00, 0X1B, 0X81, 0X6A }, /* -55.5db */ + { 0X00, 0X1D, 0X22, 0XA4 }, /* -55.0db */ + { 0X00, 0X1E, 0XDC, 0X98 }, /* -54.5db */ + { 0X00, 0X20, 0XB0, 0XBC }, /* -54.0db */ + { 0X00, 0X22, 0XA0, 0X9D }, /* -53.5db */ + { 0X00, 0X24, 0XAD, 0XE0 }, /* -53.0db */ + { 0X00, 0X26, 0XDA, 0X43 }, /* -52.5db */ + { 0X00, 0X29, 0X27, 0X9D }, /* -52.0db */ + { 0X00, 0X2B, 0X97, 0XE3 }, /* -51.5db */ + { 0X00, 0X2E, 0X2D, 0X27 }, /* -51.0db */ + { 0X00, 0X30, 0XE9, 0X9A }, /* -50.5db */ + { 0X00, 0X33, 0XCF, 0X8D }, /* -50.0db */ + { 0X00, 0X36, 0XE1, 0X78 }, /* -49.5db */ + { 0X00, 0X3A, 0X21, 0XF3 }, /* -49.0db */ + { 0X00, 0X3D, 0X93, 0XC3 }, /* -48.5db */ + { 0X00, 0X41, 0X39, 0XD3 }, /* -48.0db */ + { 0X00, 0X45, 0X17, 0X3B }, /* -47.5db */ + { 0X00, 0X49, 0X2F, 0X44 }, /* -47.0db */ + { 0X00, 0X4D, 0X85, 0X66 }, /* -46.5db */ + { 0X00, 0X52, 0X1D, 0X50 }, /* -46.0db */ + { 0X00, 0X56, 0XFA, 0XE8 }, /* -45.5db */ + { 0X00, 0X5C, 0X22, 0X4E }, /* -45.0db */ + { 0X00, 0X61, 0X97, 0XE1 }, /* -44.5db */ + { 0X00, 0X67, 0X60, 0X44 }, /* -44.0db */ + { 0X00, 0X6D, 0X80, 0X60 }, /* -43.5db */ + { 0X00, 0X73, 0XFD, 0X65 }, /* -43.0db */ + { 0X00, 0X7A, 0XDC, 0XD7 }, /* -42.5db */ + { 0X00, 0X82, 0X24, 0X8A }, /* -42.0db */ + { 0X00, 0X89, 0XDA, 0XAB }, /* -41.5db */ + { 0X00, 0X92, 0X05, 0XC6 }, /* -41.0db */ + { 0X00, 0X9A, 0XAC, 0XC8 }, /* -40.5db */ + { 0X00, 0XA3, 0XD7, 0X0A }, /* -40.0db */ + { 0X00, 0XAD, 0X8C, 0X52 }, /* -39.5db */ + { 0X00, 0XB7, 0XD4, 0XDD }, /* -39.0db */ + { 0X00, 0XC2, 0XB9, 0X65 }, /* -38.5db */ + { 0X00, 0XCE, 0X43, 0X28 }, /* -38.0db */ + { 0X00, 0XDA, 0X7B, 0XF1 }, /* -37.5db */ + { 0X00, 0XE7, 0X6E, 0X1E }, /* -37.0db */ + { 0X00, 0XF5, 0X24, 0XAC }, /* -36.5db */ + { 0X01, 0X03, 0XAB, 0X3D }, /* -36.0db */ + { 0X01, 0X13, 0X0E, 0X24 }, /* -35.5db */ + { 0X01, 0X23, 0X5A, 0X71 }, /* -35.0db */ + { 0X01, 0X34, 0X9D, 0XF8 }, /* -34.5db */ + { 0X01, 0X46, 0XE7, 0X5D }, /* -34.0db */ + { 0X01, 0X5A, 0X46, 0X27 }, /* -33.5db */ + { 0X01, 0X6E, 0XCA, 0XC5 }, /* -33.0db */ + { 0X01, 0X84, 0X86, 0X9F }, /* -32.5db */ + { 0X01, 0X9B, 0X8C, 0X27 }, /* -32.0db */ + { 0X01, 0XB3, 0XEE, 0XE5 }, /* -31.5db */ + { 0X01, 0XCD, 0XC3, 0X8C }, /* -31.0db */ + { 0X01, 0XE9, 0X20, 0X05 }, /* -30.5db */ + { 0X02, 0X06, 0X1B, 0X89 }, /* -30.0db */ + { 0X02, 0X24, 0XCE, 0XB0 }, /* -29.5db */ + { 0X02, 0X45, 0X53, 0X85 }, /* -29.0db */ + { 0X02, 0X67, 0XC5, 0XA2 }, /* -28.5db */ + { 0X02, 0X8C, 0X42, 0X3F }, /* -28.0db */ + { 0X02, 0XB2, 0XE8, 0X55 }, /* -27.5db */ + { 0X02, 0XDB, 0XD8, 0XAD }, /* -27.0db */ + { 0X03, 0X07, 0X36, 0X05 }, /* -26.5db */ + { 0X03, 0X35, 0X25, 0X29 }, /* -26.0db */ + { 0X03, 0X65, 0XCD, 0X13 }, /* -25.5db */ + { 0X03, 0X99, 0X57, 0X0C }, /* -25.0db */ + { 0X03, 0XCF, 0XEE, 0XCF }, /* -24.5db */ + { 0X04, 0X09, 0XC2, 0XB0 }, /* -24.0db */ + { 0X04, 0X47, 0X03, 0XC1 }, /* -23.5db */ + { 0X04, 0X87, 0XE5, 0XFB }, /* -23.0db */ + { 0X04, 0XCC, 0XA0, 0X6D }, /* -22.5db */ + { 0X05, 0X15, 0X6D, 0X68 }, /* -22.0db */ + { 0X05, 0X62, 0X8A, 0XB3 }, /* -21.5db */ + { 0X05, 0XB4, 0X39, 0XBC }, /* -21.0db */ + { 0X06, 0X0A, 0XBF, 0XD4 }, /* -20.5db */ + { 0X06, 0X66, 0X66, 0X66 }, /* -20.0db */ + { 0X06, 0XC7, 0X7B, 0X36 }, /* -19.5db */ + { 0X07, 0X2E, 0X50, 0XA6 }, /* -19.0db */ + { 0X07, 0X9B, 0X3D, 0XF6 }, /* -18.5db */ + { 0X08, 0X0E, 0X9F, 0X96 }, /* -18.0db */ + { 0X08, 0X88, 0XD7, 0X6D }, /* -17.5db */ + { 0X09, 0X0A, 0X4D, 0X2F }, /* -17.0db */ + { 0X09, 0X93, 0X6E, 0XB8 }, /* -16.5db */ + { 0X0A, 0X24, 0XB0, 0X62 }, /* -16.0db */ + { 0X0A, 0XBE, 0X8D, 0X70 }, /* -15.5db */ + { 0X0B, 0X61, 0X88, 0X71 }, /* -15.0db */ + { 0X0C, 0X0E, 0X2B, 0XB0 }, /* -14.5db */ + { 0X0C, 0XC5, 0X09, 0XAB }, /* -14.0db */ + { 0X0D, 0X86, 0XBD, 0X8D }, /* -13.5db */ + { 0X0E, 0X53, 0XEB, 0XB3 }, /* -13.0db */ + { 0X0F, 0X2D, 0X42, 0X38 }, /* -12.5db */ + { 0X10, 0X13, 0X79, 0X87 }, /* -12.0db */ + { 0X11, 0X07, 0X54, 0XF9 }, /* -11.5db */ + { 0X12, 0X09, 0XA3, 0X7A }, /* -11.0db */ + { 0X13, 0X1B, 0X40, 0X39 }, /* -10.5db */ + { 0X14, 0X3D, 0X13, 0X62 }, /* -10.0db */ + { 0X15, 0X70, 0X12, 0XE1 }, /* -9.5db */ + { 0X16, 0XB5, 0X43, 0X37 }, /* -9.0db */ + { 0X18, 0X0D, 0XB8, 0X54 }, /* -8.5db */ + { 0X19, 0X7A, 0X96, 0X7F }, /* -8.0db */ + { 0X1A, 0XFD, 0X13, 0X54 }, /* -7.5db */ + { 0X1C, 0X96, 0X76, 0XC6 }, /* -7.0db */ + { 0X1E, 0X48, 0X1C, 0X37 }, /* -6.5db */ + { 0X20, 0X13, 0X73, 0X9E }, /* -6.0db */ + { 0X21, 0XFA, 0X02, 0XBF }, /* -5.5db */ + { 0X23, 0XFD, 0X66, 0X78 }, /* -5.0db */ + { 0X26, 0X1F, 0X54, 0X1C }, /* -4.5db */ + { 0X28, 0X61, 0X9A, 0XE9 }, /* -4.0db */ + { 0X2A, 0XC6, 0X25, 0X91 }, /* -3.5db */ + { 0X2D, 0X4E, 0XFB, 0XD5 }, /* -3.0db */ + { 0X2F, 0XFE, 0X44, 0X48 }, /* -2.5db */ + { 0X32, 0XD6, 0X46, 0X17 }, /* -2.0db */ + { 0X35, 0XD9, 0X6B, 0X02 }, /* -1.5db */ + { 0X39, 0X0A, 0X41, 0X5F }, /* -1.0db */ + { 0X3C, 0X6B, 0X7E, 0X4F }, /* -0.5db */ + { 0X40, 0X00, 0X00, 0X00 }, /* 0.0db */ + { 0X43, 0XCA, 0XD0, 0X22 }, /* 0.5db */ + { 0X47, 0XCF, 0X26, 0X7D }, /* 1.0db */ + { 0X4C, 0X10, 0X6B, 0XA5 }, /* 1.5db */ + { 0X50, 0X92, 0X3B, 0XE3 }, /* 2.0db */ + { 0X55, 0X58, 0X6A, 0X46 }, /* 2.5db */ + { 0X5A, 0X67, 0X03, 0XDF }, /* 3.0db */ + { 0X5F, 0XC2, 0X53, 0X32 }, /* 3.5db */ + { 0X65, 0X6E, 0XE3, 0XDB }, /* 4.0db */ + { 0X6B, 0X71, 0X86, 0X68 }, /* 4.5db */ + { 0X71, 0XCF, 0X54, 0X71 }, /* 5.0db */ + { 0X78, 0X8D, 0XB4, 0XE9 }, /* 5.5db */ + { 0X7F, 0XFF, 0XFF, 0XFF }, /* 6.0db */ +}; +#endif diff --git a/include/sound/tas2781-tlv.h b/include/sound/tas2781-tlv.h index 00fd4d449ff35..d87263e43fdb6 100644 --- a/include/sound/tas2781-tlv.h +++ b/include/sound/tas2781-tlv.h @@ -17,265 +17,5 @@ static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0); static const __maybe_unused DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); -static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); -/* pow(10, db/20) * pow(2,30) */ -static const __maybe_unused unsigned char tas2563_dvc_table[][4] = { - { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */ - { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */ - { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */ - { 0X00, 0X00, 0X04, 0X31 }, /* -120.0db */ - { 0X00, 0X00, 0X04, 0X71 }, /* -119.5db */ - { 0X00, 0X00, 0X04, 0XB4 }, /* -119.0db */ - { 0X00, 0X00, 0X04, 0XFC }, /* -118.5db */ - { 0X00, 0X00, 0X05, 0X47 }, /* -118.0db */ - { 0X00, 0X00, 0X05, 0X97 }, /* -117.5db */ - { 0X00, 0X00, 0X05, 0XEC }, /* -117.0db */ - { 0X00, 0X00, 0X06, 0X46 }, /* -116.5db */ - { 0X00, 0X00, 0X06, 0XA5 }, /* -116.0db */ - { 0X00, 0X00, 0X07, 0X0A }, /* -115.5db */ - { 0X00, 0X00, 0X07, 0X75 }, /* -115.0db */ - { 0X00, 0X00, 0X07, 0XE6 }, /* -114.5db */ - { 0X00, 0X00, 0X08, 0X5E }, /* -114.0db */ - { 0X00, 0X00, 0X08, 0XDD }, /* -113.5db */ - { 0X00, 0X00, 0X09, 0X63 }, /* -113.0db */ - { 0X00, 0X00, 0X09, 0XF2 }, /* -112.5db */ - { 0X00, 0X00, 0X0A, 0X89 }, /* -112.0db */ - { 0X00, 0X00, 0X0B, 0X28 }, /* -111.5db */ - { 0X00, 0X00, 0X0B, 0XD2 }, /* -111.0db */ - { 0X00, 0X00, 0X0C, 0X85 }, /* -110.5db */ - { 0X00, 0X00, 0X0D, 0X43 }, /* -110.0db */ - { 0X00, 0X00, 0X0E, 0X0C }, /* -109.5db */ - { 0X00, 0X00, 0X0E, 0XE1 }, /* -109.0db */ - { 0X00, 0X00, 0X0F, 0XC3 }, /* -108.5db */ - { 0X00, 0X00, 0X10, 0XB2 }, /* -108.0db */ - { 0X00, 0X00, 0X11, 0XAF }, /* -107.5db */ - { 0X00, 0X00, 0X12, 0XBC }, /* -107.0db */ - { 0X00, 0X00, 0X13, 0XD8 }, /* -106.5db */ - { 0X00, 0X00, 0X15, 0X05 }, /* -106.0db */ - { 0X00, 0X00, 0X16, 0X44 }, /* -105.5db */ - { 0X00, 0X00, 0X17, 0X96 }, /* -105.0db */ - { 0X00, 0X00, 0X18, 0XFB }, /* -104.5db */ - { 0X00, 0X00, 0X1A, 0X76 }, /* -104.0db */ - { 0X00, 0X00, 0X1C, 0X08 }, /* -103.5db */ - { 0X00, 0X00, 0X1D, 0XB1 }, /* -103.0db */ - { 0X00, 0X00, 0X1F, 0X73 }, /* -102.5db */ - { 0X00, 0X00, 0X21, 0X51 }, /* -102.0db */ - { 0X00, 0X00, 0X23, 0X4A }, /* -101.5db */ - { 0X00, 0X00, 0X25, 0X61 }, /* -101.0db */ - { 0X00, 0X00, 0X27, 0X98 }, /* -100.5db */ - { 0X00, 0X00, 0X29, 0XF1 }, /* -100.0db */ - { 0X00, 0X00, 0X2C, 0X6D }, /* -99.5db */ - { 0X00, 0X00, 0X2F, 0X0F }, /* -99.0db */ - { 0X00, 0X00, 0X31, 0XD9 }, /* -98.5db */ - { 0X00, 0X00, 0X34, 0XCD }, /* -98.0db */ - { 0X00, 0X00, 0X37, 0XEE }, /* -97.5db */ - { 0X00, 0X00, 0X3B, 0X3F }, /* -97.0db */ - { 0X00, 0X00, 0X3E, 0XC1 }, /* -96.5db */ - { 0X00, 0X00, 0X42, 0X79 }, /* -96.0db */ - { 0X00, 0X00, 0X46, 0X6A }, /* -95.5db */ - { 0X00, 0X00, 0X4A, 0X96 }, /* -95.0db */ - { 0X00, 0X00, 0X4F, 0X01 }, /* -94.5db */ - { 0X00, 0X00, 0X53, 0XAF }, /* -94.0db */ - { 0X00, 0X00, 0X58, 0XA5 }, /* -93.5db */ - { 0X00, 0X00, 0X5D, 0XE6 }, /* -93.0db */ - { 0X00, 0X00, 0X63, 0X76 }, /* -92.5db */ - { 0X00, 0X00, 0X69, 0X5B }, /* -92.0db */ - { 0X00, 0X00, 0X6F, 0X99 }, /* -91.5db */ - { 0X00, 0X00, 0X76, 0X36 }, /* -91.0db */ - { 0X00, 0X00, 0X7D, 0X37 }, /* -90.5db */ - { 0X00, 0X00, 0X84, 0XA2 }, /* -90.0db */ - { 0X00, 0X00, 0X8C, 0X7E }, /* -89.5db */ - { 0X00, 0X00, 0X94, 0XD1 }, /* -89.0db */ - { 0X00, 0X00, 0X9D, 0XA3 }, /* -88.5db */ - { 0X00, 0X00, 0XA6, 0XFA }, /* -88.0db */ - { 0X00, 0X00, 0XB0, 0XDF }, /* -87.5db */ - { 0X00, 0X00, 0XBB, 0X5A }, /* -87.0db */ - { 0X00, 0X00, 0XC6, 0X74 }, /* -86.5db */ - { 0X00, 0X00, 0XD2, 0X36 }, /* -86.0db */ - { 0X00, 0X00, 0XDE, 0XAB }, /* -85.5db */ - { 0X00, 0X00, 0XEB, 0XDC }, /* -85.0db */ - { 0X00, 0X00, 0XF9, 0XD6 }, /* -84.5db */ - { 0X00, 0X01, 0X08, 0XA4 }, /* -84.0db */ - { 0X00, 0X01, 0X18, 0X52 }, /* -83.5db */ - { 0X00, 0X01, 0X28, 0XEF }, /* -83.0db */ - { 0X00, 0X01, 0X3A, 0X87 }, /* -82.5db */ - { 0X00, 0X01, 0X4D, 0X2A }, /* -82.0db */ - { 0X00, 0X01, 0X60, 0XE8 }, /* -81.5db */ - { 0X00, 0X01, 0X75, 0XD1 }, /* -81.0db */ - { 0X00, 0X01, 0X8B, 0XF7 }, /* -80.5db */ - { 0X00, 0X01, 0XA3, 0X6E }, /* -80.0db */ - { 0X00, 0X01, 0XBC, 0X48 }, /* -79.5db */ - { 0X00, 0X01, 0XD6, 0X9B }, /* -79.0db */ - { 0X00, 0X01, 0XF2, 0X7E }, /* -78.5db */ - { 0X00, 0X02, 0X10, 0X08 }, /* -78.0db */ - { 0X00, 0X02, 0X2F, 0X51 }, /* -77.5db */ - { 0X00, 0X02, 0X50, 0X76 }, /* -77.0db */ - { 0X00, 0X02, 0X73, 0X91 }, /* -76.5db */ - { 0X00, 0X02, 0X98, 0XC0 }, /* -76.0db */ - { 0X00, 0X02, 0XC0, 0X24 }, /* -75.5db */ - { 0X00, 0X02, 0XE9, 0XDD }, /* -75.0db */ - { 0X00, 0X03, 0X16, 0X0F }, /* -74.5db */ - { 0X00, 0X03, 0X44, 0XDF }, /* -74.0db */ - { 0X00, 0X03, 0X76, 0X76 }, /* -73.5db */ - { 0X00, 0X03, 0XAA, 0XFC }, /* -73.0db */ - { 0X00, 0X03, 0XE2, 0XA0 }, /* -72.5db */ - { 0X00, 0X04, 0X1D, 0X8F }, /* -72.0db */ - { 0X00, 0X04, 0X5B, 0XFD }, /* -71.5db */ - { 0X00, 0X04, 0X9E, 0X1D }, /* -71.0db */ - { 0X00, 0X04, 0XE4, 0X29 }, /* -70.5db */ - { 0X00, 0X05, 0X2E, 0X5A }, /* -70.0db */ - { 0X00, 0X05, 0X7C, 0XF2 }, /* -69.5db */ - { 0X00, 0X05, 0XD0, 0X31 }, /* -69.0db */ - { 0X00, 0X06, 0X28, 0X60 }, /* -68.5db */ - { 0X00, 0X06, 0X85, 0XC8 }, /* -68.0db */ - { 0X00, 0X06, 0XE8, 0XB9 }, /* -67.5db */ - { 0X00, 0X07, 0X51, 0X86 }, /* -67.0db */ - { 0X00, 0X07, 0XC0, 0X8A }, /* -66.5db */ - { 0X00, 0X08, 0X36, 0X21 }, /* -66.0db */ - { 0X00, 0X08, 0XB2, 0XB0 }, /* -65.5db */ - { 0X00, 0X09, 0X36, 0XA1 }, /* -65.0db */ - { 0X00, 0X09, 0XC2, 0X63 }, /* -64.5db */ - { 0X00, 0X0A, 0X56, 0X6D }, /* -64.0db */ - { 0X00, 0X0A, 0XF3, 0X3C }, /* -63.5db */ - { 0X00, 0X0B, 0X99, 0X56 }, /* -63.0db */ - { 0X00, 0X0C, 0X49, 0X48 }, /* -62.5db */ - { 0X00, 0X0D, 0X03, 0XA7 }, /* -62.0db */ - { 0X00, 0X0D, 0XC9, 0X11 }, /* -61.5db */ - { 0X00, 0X0E, 0X9A, 0X2D }, /* -61.0db */ - { 0X00, 0X0F, 0X77, 0XAD }, /* -60.5db */ - { 0X00, 0X10, 0X62, 0X4D }, /* -60.0db */ - { 0X00, 0X11, 0X5A, 0XD5 }, /* -59.5db */ - { 0X00, 0X12, 0X62, 0X16 }, /* -59.0db */ - { 0X00, 0X13, 0X78, 0XF0 }, /* -58.5db */ - { 0X00, 0X14, 0XA0, 0X50 }, /* -58.0db */ - { 0X00, 0X15, 0XD9, 0X31 }, /* -57.5db */ - { 0X00, 0X17, 0X24, 0X9C }, /* -57.0db */ - { 0X00, 0X18, 0X83, 0XAA }, /* -56.5db */ - { 0X00, 0X19, 0XF7, 0X86 }, /* -56.0db */ - { 0X00, 0X1B, 0X81, 0X6A }, /* -55.5db */ - { 0X00, 0X1D, 0X22, 0XA4 }, /* -55.0db */ - { 0X00, 0X1E, 0XDC, 0X98 }, /* -54.5db */ - { 0X00, 0X20, 0XB0, 0XBC }, /* -54.0db */ - { 0X00, 0X22, 0XA0, 0X9D }, /* -53.5db */ - { 0X00, 0X24, 0XAD, 0XE0 }, /* -53.0db */ - { 0X00, 0X26, 0XDA, 0X43 }, /* -52.5db */ - { 0X00, 0X29, 0X27, 0X9D }, /* -52.0db */ - { 0X00, 0X2B, 0X97, 0XE3 }, /* -51.5db */ - { 0X00, 0X2E, 0X2D, 0X27 }, /* -51.0db */ - { 0X00, 0X30, 0XE9, 0X9A }, /* -50.5db */ - { 0X00, 0X33, 0XCF, 0X8D }, /* -50.0db */ - { 0X00, 0X36, 0XE1, 0X78 }, /* -49.5db */ - { 0X00, 0X3A, 0X21, 0XF3 }, /* -49.0db */ - { 0X00, 0X3D, 0X93, 0XC3 }, /* -48.5db */ - { 0X00, 0X41, 0X39, 0XD3 }, /* -48.0db */ - { 0X00, 0X45, 0X17, 0X3B }, /* -47.5db */ - { 0X00, 0X49, 0X2F, 0X44 }, /* -47.0db */ - { 0X00, 0X4D, 0X85, 0X66 }, /* -46.5db */ - { 0X00, 0X52, 0X1D, 0X50 }, /* -46.0db */ - { 0X00, 0X56, 0XFA, 0XE8 }, /* -45.5db */ - { 0X00, 0X5C, 0X22, 0X4E }, /* -45.0db */ - { 0X00, 0X61, 0X97, 0XE1 }, /* -44.5db */ - { 0X00, 0X67, 0X60, 0X44 }, /* -44.0db */ - { 0X00, 0X6D, 0X80, 0X60 }, /* -43.5db */ - { 0X00, 0X73, 0XFD, 0X65 }, /* -43.0db */ - { 0X00, 0X7A, 0XDC, 0XD7 }, /* -42.5db */ - { 0X00, 0X82, 0X24, 0X8A }, /* -42.0db */ - { 0X00, 0X89, 0XDA, 0XAB }, /* -41.5db */ - { 0X00, 0X92, 0X05, 0XC6 }, /* -41.0db */ - { 0X00, 0X9A, 0XAC, 0XC8 }, /* -40.5db */ - { 0X00, 0XA3, 0XD7, 0X0A }, /* -40.0db */ - { 0X00, 0XAD, 0X8C, 0X52 }, /* -39.5db */ - { 0X00, 0XB7, 0XD4, 0XDD }, /* -39.0db */ - { 0X00, 0XC2, 0XB9, 0X65 }, /* -38.5db */ - { 0X00, 0XCE, 0X43, 0X28 }, /* -38.0db */ - { 0X00, 0XDA, 0X7B, 0XF1 }, /* -37.5db */ - { 0X00, 0XE7, 0X6E, 0X1E }, /* -37.0db */ - { 0X00, 0XF5, 0X24, 0XAC }, /* -36.5db */ - { 0X01, 0X03, 0XAB, 0X3D }, /* -36.0db */ - { 0X01, 0X13, 0X0E, 0X24 }, /* -35.5db */ - { 0X01, 0X23, 0X5A, 0X71 }, /* -35.0db */ - { 0X01, 0X34, 0X9D, 0XF8 }, /* -34.5db */ - { 0X01, 0X46, 0XE7, 0X5D }, /* -34.0db */ - { 0X01, 0X5A, 0X46, 0X27 }, /* -33.5db */ - { 0X01, 0X6E, 0XCA, 0XC5 }, /* -33.0db */ - { 0X01, 0X84, 0X86, 0X9F }, /* -32.5db */ - { 0X01, 0X9B, 0X8C, 0X27 }, /* -32.0db */ - { 0X01, 0XB3, 0XEE, 0XE5 }, /* -31.5db */ - { 0X01, 0XCD, 0XC3, 0X8C }, /* -31.0db */ - { 0X01, 0XE9, 0X20, 0X05 }, /* -30.5db */ - { 0X02, 0X06, 0X1B, 0X89 }, /* -30.0db */ - { 0X02, 0X24, 0XCE, 0XB0 }, /* -29.5db */ - { 0X02, 0X45, 0X53, 0X85 }, /* -29.0db */ - { 0X02, 0X67, 0XC5, 0XA2 }, /* -28.5db */ - { 0X02, 0X8C, 0X42, 0X3F }, /* -28.0db */ - { 0X02, 0XB2, 0XE8, 0X55 }, /* -27.5db */ - { 0X02, 0XDB, 0XD8, 0XAD }, /* -27.0db */ - { 0X03, 0X07, 0X36, 0X05 }, /* -26.5db */ - { 0X03, 0X35, 0X25, 0X29 }, /* -26.0db */ - { 0X03, 0X65, 0XCD, 0X13 }, /* -25.5db */ - { 0X03, 0X99, 0X57, 0X0C }, /* -25.0db */ - { 0X03, 0XCF, 0XEE, 0XCF }, /* -24.5db */ - { 0X04, 0X09, 0XC2, 0XB0 }, /* -24.0db */ - { 0X04, 0X47, 0X03, 0XC1 }, /* -23.5db */ - { 0X04, 0X87, 0XE5, 0XFB }, /* -23.0db */ - { 0X04, 0XCC, 0XA0, 0X6D }, /* -22.5db */ - { 0X05, 0X15, 0X6D, 0X68 }, /* -22.0db */ - { 0X05, 0X62, 0X8A, 0XB3 }, /* -21.5db */ - { 0X05, 0XB4, 0X39, 0XBC }, /* -21.0db */ - { 0X06, 0X0A, 0XBF, 0XD4 }, /* -20.5db */ - { 0X06, 0X66, 0X66, 0X66 }, /* -20.0db */ - { 0X06, 0XC7, 0X7B, 0X36 }, /* -19.5db */ - { 0X07, 0X2E, 0X50, 0XA6 }, /* -19.0db */ - { 0X07, 0X9B, 0X3D, 0XF6 }, /* -18.5db */ - { 0X08, 0X0E, 0X9F, 0X96 }, /* -18.0db */ - { 0X08, 0X88, 0XD7, 0X6D }, /* -17.5db */ - { 0X09, 0X0A, 0X4D, 0X2F }, /* -17.0db */ - { 0X09, 0X93, 0X6E, 0XB8 }, /* -16.5db */ - { 0X0A, 0X24, 0XB0, 0X62 }, /* -16.0db */ - { 0X0A, 0XBE, 0X8D, 0X70 }, /* -15.5db */ - { 0X0B, 0X61, 0X88, 0X71 }, /* -15.0db */ - { 0X0C, 0X0E, 0X2B, 0XB0 }, /* -14.5db */ - { 0X0C, 0XC5, 0X09, 0XAB }, /* -14.0db */ - { 0X0D, 0X86, 0XBD, 0X8D }, /* -13.5db */ - { 0X0E, 0X53, 0XEB, 0XB3 }, /* -13.0db */ - { 0X0F, 0X2D, 0X42, 0X38 }, /* -12.5db */ - { 0X10, 0X13, 0X79, 0X87 }, /* -12.0db */ - { 0X11, 0X07, 0X54, 0XF9 }, /* -11.5db */ - { 0X12, 0X09, 0XA3, 0X7A }, /* -11.0db */ - { 0X13, 0X1B, 0X40, 0X39 }, /* -10.5db */ - { 0X14, 0X3D, 0X13, 0X62 }, /* -10.0db */ - { 0X15, 0X70, 0X12, 0XE1 }, /* -9.5db */ - { 0X16, 0XB5, 0X43, 0X37 }, /* -9.0db */ - { 0X18, 0X0D, 0XB8, 0X54 }, /* -8.5db */ - { 0X19, 0X7A, 0X96, 0X7F }, /* -8.0db */ - { 0X1A, 0XFD, 0X13, 0X54 }, /* -7.5db */ - { 0X1C, 0X96, 0X76, 0XC6 }, /* -7.0db */ - { 0X1E, 0X48, 0X1C, 0X37 }, /* -6.5db */ - { 0X20, 0X13, 0X73, 0X9E }, /* -6.0db */ - { 0X21, 0XFA, 0X02, 0XBF }, /* -5.5db */ - { 0X23, 0XFD, 0X66, 0X78 }, /* -5.0db */ - { 0X26, 0X1F, 0X54, 0X1C }, /* -4.5db */ - { 0X28, 0X61, 0X9A, 0XE9 }, /* -4.0db */ - { 0X2A, 0XC6, 0X25, 0X91 }, /* -3.5db */ - { 0X2D, 0X4E, 0XFB, 0XD5 }, /* -3.0db */ - { 0X2F, 0XFE, 0X44, 0X48 }, /* -2.5db */ - { 0X32, 0XD6, 0X46, 0X17 }, /* -2.0db */ - { 0X35, 0XD9, 0X6B, 0X02 }, /* -1.5db */ - { 0X39, 0X0A, 0X41, 0X5F }, /* -1.0db */ - { 0X3C, 0X6B, 0X7E, 0X4F }, /* -0.5db */ - { 0X40, 0X00, 0X00, 0X00 }, /* 0.0db */ - { 0X43, 0XCA, 0XD0, 0X22 }, /* 0.5db */ - { 0X47, 0XCF, 0X26, 0X7D }, /* 1.0db */ - { 0X4C, 0X10, 0X6B, 0XA5 }, /* 1.5db */ - { 0X50, 0X92, 0X3B, 0XE3 }, /* 2.0db */ - { 0X55, 0X58, 0X6A, 0X46 }, /* 2.5db */ - { 0X5A, 0X67, 0X03, 0XDF }, /* 3.0db */ - { 0X5F, 0XC2, 0X53, 0X32 }, /* 3.5db */ - { 0X65, 0X6E, 0XE3, 0XDB }, /* 4.0db */ - { 0X6B, 0X71, 0X86, 0X68 }, /* 4.5db */ - { 0X71, 0XCF, 0X54, 0X71 }, /* 5.0db */ - { 0X78, 0X8D, 0XB4, 0XE9 }, /* 5.5db */ - { 0XFF, 0XFF, 0XFF, 0XFF }, /* 6.0db */ -}; #endif diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index bac5ea6d99b9b..313c17f76ca4e 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include -- GitLab From b066a8190f134027bdf8e645e1cf610d364aa7e8 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Sun, 11 Aug 2024 21:51:41 +0800 Subject: [PATCH 387/456] UPSTREAM: ASoc: tas2781: Rename dai_driver name to unify the name between TAS2563 and TAS2781 Rename dai_driver name to unify the name between TAS2563 and TAS2781. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I6c631366191abfd6066f7dfdb07e0897a1f9c9b2 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240811135144.178-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 8f712c12f34daaaa2e47ba07cf3b348d3a442986) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181525 Commit-Queue: Fei Shao Reviewed-by: Sean Paul Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 313c17f76ca4e..8c9efd9183ff5 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -672,7 +672,7 @@ static const struct snd_soc_dai_ops tasdevice_dai_ops = { static struct snd_soc_dai_driver tasdevice_dai_driver[] = { { - .name = "tas2781_codec", + .name = "tasdev_codec", .id = 0, .playback = { .stream_name = "Playback", -- GitLab From 6dc4c9b86033027ef832c016152e9058ed68c27d Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 15 Aug 2024 12:21:35 +0800 Subject: [PATCH 388/456] UPSTREAM: ASoc: tas2781: Remove unnecessary line feed and space Remove unnecessary line feed for tasdevice_dsp_create_ctrls, and remove two unnecessary spaces in tas2563_digital_gain_get and tas2563_digital_gain_put. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I97a336ed0f6a7cf28c0564bb63f00684b355490a Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240815042138.1997-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 0a9173541b3f8cde8ad923eebd2e157650e13f35) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181526 Reviewed-by: Sean Paul Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 8c9efd9183ff5..9a32e0504857b 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -157,7 +157,7 @@ static int tas2563_digital_gain_get( mutex_lock(&tas_dev->codec_lock); /* Read the primary device */ - ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); + ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); if (ret) { dev_err(tas_dev->dev, "%s, get AMP vol error\n", __func__); goto out; @@ -203,7 +203,7 @@ static int tas2563_digital_gain_put( vol = clamp(vol, 0, max); mutex_lock(&tas_dev->codec_lock); /* Read the primary device */ - ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); + ret = tasdevice_dev_bulk_read(tas_dev, 0, reg, data, 4); if (ret) { dev_err(tas_dev->dev, "%s, get AMP vol error\n", __func__); rc = -1; @@ -423,8 +423,7 @@ static int tasdevice_configuration_put( return ret; } -static int tasdevice_dsp_create_ctrls( - struct tasdevice_priv *tas_priv) +static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) { struct snd_kcontrol_new *dsp_ctrls; char *prog_name, *conf_name; -- GitLab From 89806e36de799e1ad7f42874b5016937f44b665b Mon Sep 17 00:00:00 2001 From: Baojun Xu Date: Wed, 21 Aug 2024 15:25:27 +0800 Subject: [PATCH 389/456] UPSTREAM: ASoC: tas2781: Remove unnecessary line feed for tasdevice_codec_remove Remove unnecessary line feed for tasdevice_codec_remove. Add comma at the end the last member of the array. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I593e9b5046bd6a4b06a01d4d5dfa82396f77da39 Signed-off-by: Baojun Xu Link: https://patch.msgid.link/20240821072527.1294-1-baojun.xu@ti.com Signed-off-by: Mark Brown (cherry picked from commit 8a8dcf702673787543173b8ac5dafae2f7f13e87) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181527 Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 9a32e0504857b..eb8732b1bb99f 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -582,13 +582,13 @@ static const struct snd_soc_dapm_widget tasdevice_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_SPK("SPK", tasdevice_dapm_event), SND_SOC_DAPM_OUTPUT("OUT"), - SND_SOC_DAPM_INPUT("DMIC") + SND_SOC_DAPM_INPUT("DMIC"), }; static const struct snd_soc_dapm_route tasdevice_audio_map[] = { {"SPK", NULL, "ASI"}, {"OUT", NULL, "SPK"}, - {"ASI OUT", NULL, "DMIC"} + {"ASI OUT", NULL, "DMIC"}, }; static int tasdevice_startup(struct snd_pcm_substream *substream, @@ -730,8 +730,7 @@ static void tasdevice_deinit(void *context) tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; } -static void tasdevice_codec_remove( - struct snd_soc_component *codec) +static void tasdevice_codec_remove(struct snd_soc_component *codec) { struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); -- GitLab From 0522cdede41ca669bf4e7b2f31a787122b04db4a Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 22 Aug 2024 14:32:02 +0800 Subject: [PATCH 390/456] UPSTREAM: ASoC: tas2781: mark const variables tas2563_dvc_table as __maybe_unused In case of tas2781, tas2563_dvc_table will be unused, so mark it as __maybe_unused. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I34c8f52beca51e074b322b1b16f17e114c171315 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240822063205.662-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 1a9e3b0af301413210319e6946fb4b0b1ad71ccc) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181528 Reviewed-by: Sean Paul Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- include/sound/tas2563-tlv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/tas2563-tlv.h b/include/sound/tas2563-tlv.h index faa3e194f73b1..bb269b21f4602 100644 --- a/include/sound/tas2563-tlv.h +++ b/include/sound/tas2563-tlv.h @@ -18,7 +18,7 @@ static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1); /* pow(10, db/20) * pow(2,30) */ -static const unsigned char tas2563_dvc_table[][4] = { +static const __maybe_unused unsigned char tas2563_dvc_table[][4] = { { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */ { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */ { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */ -- GitLab From c3d8116c353c692a59ed719dbd289fd70ec5f1f7 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Sat, 24 Aug 2024 14:05:00 +0800 Subject: [PATCH 391/456] UPSTREAM: ASoC: tas2781: replace devm_kzalloc and scnprintf with devm_kstrdup Replace devm_kzalloc and scnprintf with devm_kstrdup. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: Iecb3afbae193cb7a8c8866bd5cce52c0f74402c6 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240824060503.1259-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit c8dc1016ba0e249e45863c1da3b951efe7c4214a) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181529 Commit-Queue: Fei Shao Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Sean Paul Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index eb8732b1bb99f..59fcce7fef7b3 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -346,13 +346,11 @@ static int tasdevice_create_control(struct tasdevice_priv *tas_priv) } /* Create a mixer item for selecting the active profile */ - name = devm_kzalloc(tas_priv->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, - GFP_KERNEL); + name = devm_kstrdup(tas_priv->dev, "Speaker Profile Id", GFP_KERNEL); if (!name) { ret = -ENOMEM; goto out; } - scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "Speaker Profile Id"); prof_ctrls[mix_index].name = name; prof_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; prof_ctrls[mix_index].info = tasdevice_info_profile; @@ -441,18 +439,13 @@ static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) goto out; } - /* Create a mixer item for selecting the active profile */ - prog_name = devm_kzalloc(tas_priv->dev, - SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL); - conf_name = devm_kzalloc(tas_priv->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + /* Create mixer items for selecting the active Program and Config */ + prog_name = devm_kstrdup(tas_priv->dev, "Speaker Program Id", GFP_KERNEL); - if (!prog_name || !conf_name) { + if (!prog_name) { ret = -ENOMEM; goto out; } - - scnprintf(prog_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, - "Speaker Program Id"); dsp_ctrls[mix_index].name = prog_name; dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; dsp_ctrls[mix_index].info = tasdevice_info_programs; @@ -460,8 +453,12 @@ static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) dsp_ctrls[mix_index].put = tasdevice_program_put; mix_index++; - scnprintf(conf_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, - "Speaker Config Id"); + conf_name = devm_kstrdup(tas_priv->dev, "Speaker Config Id", + GFP_KERNEL); + if (!conf_name) { + ret = -ENOMEM; + goto out; + } dsp_ctrls[mix_index].name = conf_name; dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; dsp_ctrls[mix_index].info = tasdevice_info_configurations; -- GitLab From ddb1605db15e503c35b645a523d6916ac7cbb6a5 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Sat, 7 Sep 2024 08:15:36 +0800 Subject: [PATCH 392/456] UPSTREAM: ASoC: tas2781: fix to save the dsp bin file name into the correct array in case name_prefix is not NULL fix to save the dsp bin file name into the correct array, coef_binaryname, instead of rca_binaryname, in case name_prefix is not NULL. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I1337dac808804b945c0eade7130ed5c841483764 Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240907001540.944-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit af5e317175858603f950e51fe6377027fdd6eb79) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181530 Reviewed-by: Yu-Che Cheng Reviewed-by: Sean Paul Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 59fcce7fef7b3..3bc10d615fd39 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -498,7 +498,7 @@ static void tasdevice_fw_ready(const struct firmware *fmw, */ tas_priv->fw_state = TASDEVICE_RCA_FW_OK; if (tas_priv->name_prefix) - scnprintf(tas_priv->rca_binaryname, 64, "%s-%s_coef.bin", + scnprintf(tas_priv->coef_binaryname, 64, "%s-%s_coef.bin", tas_priv->name_prefix, tas_priv->dev_name); else scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin", -- GitLab From 0c9b7ccd5c49c23a49ee5eb776a2acd56a2d1e94 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 12 Sep 2024 07:27:37 +0800 Subject: [PATCH 393/456] UPSTREAM: ASoC: tas2781: Add Calibration Kcontrols for Chromebook Add calibration related kcontrol for speaker impedance calibration and speaker leakage check for Chromebook. BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I657ea2d17e18e0838e7e5db063e032cd98632c7a Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20240911232739.1509-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 49e2e353fb0dbef8dced3e8e65365580349c4b14) Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181531 Reviewed-by: Fei Shao Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- include/sound/tas2781.h | 68 +++ sound/soc/codecs/tas2781-comlib.c | 26 + sound/soc/codecs/tas2781-fmwlib.c | 60 +- sound/soc/codecs/tas2781-i2c.c | 887 +++++++++++++++++++++++++++++- 4 files changed, 1030 insertions(+), 11 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index dbda552398b5b..8cd6da0480b79 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -49,12 +49,59 @@ /*I2C Checksum */ #define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) +/* XM_340 */ +#define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x63, 0x3c) +/* XM_341 */ +#define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x63, 0x38) + /* Volume control */ #define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C) #define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A) #define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) #define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) +#define TAS2563_IDLE TASDEVICE_REG(0x00, 0x00, 0x3e) +#define TAS2563_PRM_R0_REG TASDEVICE_REG(0x00, 0x0f, 0x34) + +#define TAS2563_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x02, 0x70) +#define TAS2563_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x02, 0x48) + +#define TAS2563_PRM_ENFF_REG TASDEVICE_REG(0x00, 0x0d, 0x54) +#define TAS2563_PRM_DISTCK_REG TASDEVICE_REG(0x00, 0x0d, 0x58) +#define TAS2563_PRM_TE_SCTHR_REG TASDEVICE_REG(0x00, 0x0f, 0x60) +#define TAS2563_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x0d, 0x74) +#define TAS2563_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x0d, 0x7c) +/* prm_Int_B0 */ +#define TAS2563_TE_TA1_REG TASDEVICE_REG(0x00, 0x10, 0x0c) +/* prm_Int_A1 */ +#define TAS2563_TE_TA1_AT_REG TASDEVICE_REG(0x00, 0x10, 0x10) +/* prm_TE_Beta */ +#define TAS2563_TE_TA2_REG TASDEVICE_REG(0x00, 0x0f, 0x64) +/* prm_TE_Beta1 */ +#define TAS2563_TE_AT_REG TASDEVICE_REG(0x00, 0x0f, 0x68) +/* prm_TE_1_Beta1 */ +#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70) + +#define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b) +#define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c) +#define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19) +#define TAS2781_PRM_TEST_57_REG TASDEVICE_REG(0x00, 0xfd, 0x39) +#define TAS2781_PRM_TEST_62_REG TASDEVICE_REG(0x00, 0xfd, 0x3e) +#define TAS2781_PRM_PVDD_UVLO_REG TASDEVICE_REG(0x00, 0x00, 0x71) +#define TAS2781_PRM_CHNL_0_REG TASDEVICE_REG(0x00, 0x00, 0x03) +#define TAS2781_PRM_NG_CFG0_REG TASDEVICE_REG(0x00, 0x00, 0x35) +#define TAS2781_PRM_IDLE_CH_DET_REG TASDEVICE_REG(0x00, 0x00, 0x66) +#define TAS2781_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x14, 0x38) +#define TAS2781_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x14, 0x40) +#define TAS2781_PRM_SINEGAIN2_REG TASDEVICE_REG(0x00, 0x14, 0x44) + +#define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xFD, 0x0D) +#define TAS2781_TEST_PAGE_UNLOCK 0x0D + +#define TAS2781_RUNTIME_LATCH_RE_REG TASDEVICE_REG(0x00, 0x00, 0x49) +#define TAS2781_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x62, 0x48) +#define TAS2781_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x63, 0x44) + #define TASDEVICE_CMD_SING_W 0x1 #define TASDEVICE_CMD_BURST 0x2 #define TASDEVICE_CMD_DELAY 0x3 @@ -70,7 +117,15 @@ enum device_catlog_id { OTHERS }; +struct bulk_reg_val { + int reg; + unsigned char val[4]; + unsigned char val_len; + bool is_locked; +}; + struct tasdevice { + struct bulk_reg_val *cali_data_backup; struct tasdevice_fw *cali_data_fmw; unsigned int dev_addr; unsigned int err_code; @@ -81,9 +136,19 @@ struct tasdevice { bool is_loaderr; }; +struct cali_reg { + unsigned int r0_reg; + unsigned int r0_low_reg; + unsigned int invr0_reg; + unsigned int pow_reg; + unsigned int tlimit_reg; +}; + struct calidata { unsigned char *data; unsigned long total_sz; + struct cali_reg cali_reg_array; + unsigned int cali_dat_sz_per_dev; }; struct tasdevice_priv { @@ -119,6 +184,7 @@ struct tasdevice_priv { bool force_fwload_status; bool playback_started; bool isacpi; + bool is_user_space_calidata; unsigned int global_addr; int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv, @@ -145,6 +211,8 @@ int tasdevice_init(struct tasdevice_priv *tas_priv); void tasdevice_remove(struct tasdevice_priv *tas_priv); int tasdevice_save_calibration(struct tasdevice_priv *tas_priv); void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv); +int tasdev_chn_switch(struct tasdevice_priv *tas_priv, + unsigned short chn); int tasdevice_dev_read(struct tasdevice_priv *tas_priv, unsigned short chn, unsigned int reg, unsigned int *value); int tasdevice_dev_write(struct tasdevice_priv *tas_priv, diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c index 664c371796d63..1e0b3aa95749d 100644 --- a/sound/soc/codecs/tas2781-comlib.c +++ b/sound/soc/codecs/tas2781-comlib.c @@ -88,6 +88,32 @@ out: return ret; } +int tasdev_chn_switch(struct tasdevice_priv *tas_priv, + unsigned short chn) +{ + struct i2c_client *client = (struct i2c_client *)tas_priv->client; + struct tasdevice *tasdev = &tas_priv->tasdevice[chn]; + struct regmap *map = tas_priv->regmap; + int ret; + + if (client->addr != tasdev->dev_addr) { + client->addr = tasdev->dev_addr; + /* All devices share the same regmap, clear the page + * inside regmap once switching to another device. + * Register 0 at any pages and any books inside tas2781 + * is the same one for page-switching. + */ + ret = regmap_write(map, TASDEVICE_PAGE_SELECT, 0); + if (ret < 0) { + dev_err(tas_priv->dev, "%s, E=%d\n", __func__, ret); + return ret; + } + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(tasdev_chn_switch); + int tasdevice_dev_read(struct tasdevice_priv *tas_priv, unsigned short chn, unsigned int reg, unsigned int *val) { diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 6474cc551d551..71a7ad132e0eb 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -2152,20 +2152,61 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv, static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) { + struct tasdevice_fw *cal_fmw = priv->tasdevice[i].cali_data_fmw; + struct calidata *cali_data = &priv->cali_data; + struct cali_reg *p = &cali_data->cali_reg_array; + unsigned char *data = cali_data->data; struct tasdevice_calibration *cal; - struct tasdevice_fw *cal_fmw; + int k = i * (cali_data->cali_dat_sz_per_dev + 1); + int rc; - cal_fmw = priv->tasdevice[i].cali_data_fmw; + /* Load the calibrated data from cal bin file */ + if (!priv->is_user_space_calidata && cal_fmw) { + cal = cal_fmw->calibrations; - /* No calibrated data for current devices, playback will go ahead. */ - if (!cal_fmw) + if (cal) + load_calib_data(priv, &cal->dev_data); return; - - cal = cal_fmw->calibrations; - if (!cal) + } + if (!priv->is_user_space_calidata) + return; + /* load calibrated data from user space */ + if (data[k] != i) { + dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n", + __func__, i); return; + } + k++; - load_calib_data(priv, &cal->dev_data); + rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc); + return; + } + k += 4; + rc = tasdevice_dev_bulk_write(priv, i, p->r0_low_reg, &(data[k]), 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d r0_low_reg err = %d\n", i, rc); + return; + } + k += 4; + rc = tasdevice_dev_bulk_write(priv, i, p->invr0_reg, &(data[k]), 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d invr0_reg err = %d\n", i, rc); + return; + } + k += 4; + rc = tasdevice_dev_bulk_write(priv, i, p->pow_reg, &(data[k]), 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d pow_reg bulk_wr err = %d\n", i, rc); + return; + } + k += 4; + rc = tasdevice_dev_bulk_write(priv, i, p->tlimit_reg, &(data[k]), 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d tlimit_reg err = %d\n", i, rc); + return; + } } int tasdevice_select_tuningprm_cfg(void *context, int prm_no, @@ -2260,9 +2301,10 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no, tas_priv->tasdevice[i].cur_conf = cfg_no; } } - } else + } else { dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n", __func__, cfg_no); + } status |= cfg_info[rca_conf_no]->active_dev; diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 3bc10d615fd39..d0ba7cbe03a81 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -33,6 +33,69 @@ #include #include +#define X2563_CL_STT_VAL(xreg, xval) \ +{ .reg = xreg, \ + .val = { xval }, \ + .val_len = 1, } + +#define X2563_CL_STT_4BYTS(xreg, byte0, byte1, byte2, byte3) \ +{ .reg = xreg, \ + .val = { byte0, byte1, byte2, byte3 }, \ + .val_len = 4, } + +static const struct bulk_reg_val tas2563_cali_start_reg[] = { + X2563_CL_STT_VAL(TAS2563_IDLE, 0x00), + X2563_CL_STT_4BYTS(TAS2563_PRM_ENFF_REG, 0x40, 0x00, 0x00, 0x00), + X2563_CL_STT_4BYTS(TAS2563_PRM_DISTCK_REG, 0x40, 0x00, 0x00, 0x00), + X2563_CL_STT_4BYTS(TAS2563_PRM_TE_SCTHR_REG, 0x7f, 0xff, 0xff, 0xff), + X2563_CL_STT_4BYTS(TAS2563_PRM_PLT_FLAG_REG, 0x40, 0x00, 0x00, 0x00), + X2563_CL_STT_4BYTS(TAS2563_PRM_SINEGAIN_REG, 0x0a, 0x3d, 0x70, 0xa4), + X2563_CL_STT_4BYTS(TAS2563_TE_TA1_REG, 0x00, 0x36, 0x91, 0x5e), + X2563_CL_STT_4BYTS(TAS2563_TE_TA1_AT_REG, 0x00, 0x36, 0x91, 0x5e), + X2563_CL_STT_4BYTS(TAS2563_TE_TA2_REG, 0x00, 0x06, 0xd3, 0x72), + X2563_CL_STT_4BYTS(TAS2563_TE_AT_REG, 0x00, 0x36, 0x91, 0x5e), + X2563_CL_STT_4BYTS(TAS2563_TE_DT_REG, 0x00, 0x36, 0x91, 0x5e), +}; + +#define X2781_CL_STT_VAL(xreg, xval, xlocked) \ +{ .reg = xreg, \ + .val = { xval }, \ + .val_len = 1, \ + .is_locked = xlocked, } + +#define X2781_CL_STT_4BYTS_UNLOCKED(xreg, byte0, byte1, byte2, byte3) \ +{ .reg = xreg, \ + .val = { byte0, byte1, byte2, byte3 }, \ + .val_len = 4, \ + .is_locked = false, } + +#define X2781_CL_STT_LEN_UNLOCKED(xreg) \ +{ .reg = xreg, \ + .val_len = 4, \ + .is_locked = false, } + +static const struct bulk_reg_val tas2781_cali_start_reg[] = { + X2781_CL_STT_VAL(TAS2781_PRM_INT_MASK_REG, 0xfe, false), + X2781_CL_STT_VAL(TAS2781_PRM_CLK_CFG_REG, 0xdd, false), + X2781_CL_STT_VAL(TAS2781_PRM_RSVD_REG, 0x20, false), + X2781_CL_STT_VAL(TAS2781_PRM_TEST_57_REG, 0x14, false), + X2781_CL_STT_VAL(TAS2781_PRM_TEST_62_REG, 0x45, true), + X2781_CL_STT_VAL(TAS2781_PRM_PVDD_UVLO_REG, 0x03, false), + X2781_CL_STT_VAL(TAS2781_PRM_CHNL_0_REG, 0xa8, false), + X2781_CL_STT_VAL(TAS2781_PRM_NG_CFG0_REG, 0xb9, false), + X2781_CL_STT_VAL(TAS2781_PRM_IDLE_CH_DET_REG, 0x92, false), + /* + * This register is pilot tone threshold, different with the + * calibration tool version, it will be updated in + * tas2781_calib_start_put(), set to 1mA. + */ + X2781_CL_STT_4BYTS_UNLOCKED(0, 0x00, 0x00, 0x00, 0x56), + X2781_CL_STT_4BYTS_UNLOCKED(TAS2781_PRM_PLT_FLAG_REG, + 0x40, 0x00, 0x00, 0x00), + X2781_CL_STT_LEN_UNLOCKED(TAS2781_PRM_SINEGAIN_REG), + X2781_CL_STT_LEN_UNLOCKED(TAS2781_PRM_SINEGAIN2_REG), +}; + static const struct i2c_device_id tasdevice_id[] = { { "tas2563", TAS2563 }, { "tas2781", TAS2781 }, @@ -141,6 +204,557 @@ static int tasdev_force_fwload_put(struct snd_kcontrol *kcontrol, return change; } +static int tasdev_cali_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + struct calidata *cali_data = &priv->cali_data; + struct cali_reg *p = &cali_data->cali_reg_array; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned char *data = cali_data->data; + unsigned int i = 0; + unsigned int j, k; + int rc; + + guard(mutex)(&priv->codec_lock); + if (!priv->is_user_space_calidata) + return -1; + + if (!p->r0_reg) + return -1; + + dst[i++] = bytes_ext->max; + dst[i++] = 'r'; + + dst[i++] = TASDEVICE_BOOK_ID(p->r0_reg); + dst[i++] = TASDEVICE_PAGE_ID(p->r0_reg); + dst[i++] = TASDEVICE_PAGE_REG(p->r0_reg); + + dst[i++] = TASDEVICE_BOOK_ID(p->r0_low_reg); + dst[i++] = TASDEVICE_PAGE_ID(p->r0_low_reg); + dst[i++] = TASDEVICE_PAGE_REG(p->r0_low_reg); + + dst[i++] = TASDEVICE_BOOK_ID(p->invr0_reg); + dst[i++] = TASDEVICE_PAGE_ID(p->invr0_reg); + dst[i++] = TASDEVICE_PAGE_REG(p->invr0_reg); + + dst[i++] = TASDEVICE_BOOK_ID(p->pow_reg); + dst[i++] = TASDEVICE_PAGE_ID(p->pow_reg); + dst[i++] = TASDEVICE_PAGE_REG(p->pow_reg); + + dst[i++] = TASDEVICE_BOOK_ID(p->tlimit_reg); + dst[i++] = TASDEVICE_PAGE_ID(p->tlimit_reg); + dst[i++] = TASDEVICE_PAGE_REG(p->tlimit_reg); + + for (j = 0, k = 0; j < priv->ndev; j++) { + if (j == data[k]) { + dst[i++] = j; + k++; + } else { + dev_err(priv->dev, "chn %d device %u not match\n", + j, data[k]); + k += 21; + continue; + } + rc = tasdevice_dev_bulk_read(priv, j, p->r0_reg, &dst[i], 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d r0_reg bulk_rd err = %d\n", + j, rc); + i += 20; + k += 20; + continue; + } + rc = memcmp(&dst[i], &data[k], 4); + if (rc != 0) + dev_dbg(priv->dev, "chn %d r0_data is not same\n", j); + k += 4; + i += 4; + rc = tasdevice_dev_bulk_read(priv, j, p->r0_low_reg, + &dst[i], 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d r0_low bulk_rd err = %d\n", + j, rc); + i += 16; + k += 16; + continue; + } + rc = memcmp(&dst[i], &data[k], 4); + if (rc != 0) + dev_dbg(priv->dev, "chn %d r0_low is not same\n", j); + i += 4; + k += 4; + rc = tasdevice_dev_bulk_read(priv, j, p->invr0_reg, + &dst[i], 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d invr0 bulk_rd err = %d\n", + j, rc); + i += 12; + k += 12; + continue; + } + rc = memcmp(&dst[i], &data[k], 4); + if (rc != 0) + dev_dbg(priv->dev, "chn %d invr0 is not same\n", j); + i += 4; + k += 4; + rc = tasdevice_dev_bulk_read(priv, j, p->pow_reg, &dst[i], 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d pow_reg bulk_rd err = %d\n", + j, rc); + i += 8; + k += 8; + continue; + } + rc = memcmp(&dst[i], &data[k], 4); + if (rc != 0) + dev_dbg(priv->dev, "chn %d pow_reg is not same\n", j); + i += 4; + k += 4; + rc = tasdevice_dev_bulk_read(priv, j, p->tlimit_reg, + &dst[i], 4); + if (rc < 0) { + dev_err(priv->dev, "chn %d tlimit bulk_rd err = %d\n", + j, rc); + } + rc = memcmp(&dst[i], &data[k], 4); + if (rc != 0) + dev_dbg(priv->dev, "chn %d tlimit is not same\n", j); + i += 4; + k += 4; + } + return 0; +} + +static int calib_data_get(struct tasdevice_priv *tas_priv, int reg, + unsigned char *dst) +{ + struct i2c_client *clt = (struct i2c_client *)tas_priv->client; + struct tasdevice *tasdev = tas_priv->tasdevice; + int rc = -1; + int i; + + for (i = 0; i < tas_priv->ndev; i++) { + if (clt->addr == tasdev[i].dev_addr) { + /* First byte is the device index. */ + dst[0] = i; + rc = tasdevice_dev_bulk_read(tas_priv, i, reg, &dst[1], + 4); + break; + } + } + + return rc; +} + +static void sngl_calib_start(struct tasdevice_priv *tas_priv, int i, + int *reg, unsigned char *dat) +{ + struct tasdevice *tasdev = tas_priv->tasdevice; + struct bulk_reg_val *p = tasdev[i].cali_data_backup; + const int sum = ARRAY_SIZE(tas2781_cali_start_reg); + int j; + + if (p == NULL) + return; + + /* Store the current setting from the chip */ + for (j = 0; j < sum; j++) { + if (p[j].val_len == 1) { + if (p[j].is_locked) + tasdevice_dev_write(tas_priv, i, + TAS2781_TEST_UNLOCK_REG, + TAS2781_TEST_PAGE_UNLOCK); + tasdevice_dev_read(tas_priv, i, p[j].reg, + (int *)&p[j].val[0]); + } else { + switch (p[j].reg) { + case 0: { + if (!reg[0]) + continue; + p[j].reg = reg[0]; + } + break; + case TAS2781_PRM_PLT_FLAG_REG: + p[j].reg = reg[1]; + break; + case TAS2781_PRM_SINEGAIN_REG: + p[j].reg = reg[2]; + break; + case TAS2781_PRM_SINEGAIN2_REG: + p[j].reg = reg[3]; + break; + } + tasdevice_dev_bulk_read(tas_priv, i, p[j].reg, + p[j].val, 4); + } + } + + /* Update the setting for calibration */ + for (j = 0; j < sum - 2; j++) { + if (p[j].val_len == 1) { + if (p[j].is_locked) + tasdevice_dev_write(tas_priv, i, + TAS2781_TEST_UNLOCK_REG, + TAS2781_TEST_PAGE_UNLOCK); + tasdevice_dev_write(tas_priv, i, p[j].reg, + tas2781_cali_start_reg[j].val[0]); + } else { + if (!p[j].reg) + continue; + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, + (unsigned char *) + tas2781_cali_start_reg[j].val, 4); + } + } + + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, &dat[1], 4); + tasdevice_dev_bulk_write(tas_priv, i, p[j + 1].reg, &dat[5], 4); +} + +static int tas2781_calib_start_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dat = ucontrol->value.bytes.data; + int i, reg[4]; + int j = 0; + + guard(mutex)(&priv->codec_lock); + if (priv->chip_id != TAS2781 || bytes_ext->max != dat[0] || + dat[1] != 'r') { + dev_err(priv->dev, "%s: package fmt or chipid incorrect\n", + __func__); + return 0; + } + j += 2; + /* refresh pilot tone and SineGain register */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + reg[i] = TASDEVICE_REG(dat[j], dat[j + 1], dat[j + 2]); + j += 3; + } + + for (i = 0; i < priv->ndev; i++) { + int k = i * 9 + j; + + if (dat[k] != i) { + dev_err(priv->dev, "%s:no cal-setting for dev %d\n", + __func__, i); + continue; + } + sngl_calib_start(priv, i, reg, dat + k); + } + return 1; +} + +static void tas2781_calib_stop_put(struct tasdevice_priv *tas_priv) +{ + const int sum = ARRAY_SIZE(tas2781_cali_start_reg); + int i, j; + + for (i = 0; i < tas_priv->ndev; i++) { + struct tasdevice *tasdev = tas_priv->tasdevice; + struct bulk_reg_val *p = tasdev[i].cali_data_backup; + + if (p == NULL) + continue; + + for (j = 0; j < sum; j++) { + if (p[j].val_len == 1) { + if (p[j].is_locked) + tasdevice_dev_write(tas_priv, i, + TAS2781_TEST_UNLOCK_REG, + TAS2781_TEST_PAGE_UNLOCK); + tasdevice_dev_write(tas_priv, i, p[j].reg, + p[j].val[0]); + } else { + if (!p[j].reg) + continue; + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, + p[j].val, 4); + } + } + } +} + +static int tas2563_calib_start_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct bulk_reg_val *q = (struct bulk_reg_val *)tas2563_cali_start_reg; + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + const int sum = ARRAY_SIZE(tas2563_cali_start_reg); + int rc = 1; + int i, j; + + guard(mutex)(&tas_priv->codec_lock); + if (tas_priv->chip_id != TAS2563) { + rc = -1; + goto out; + } + + for (i = 0; i < tas_priv->ndev; i++) { + struct tasdevice *tasdev = tas_priv->tasdevice; + struct bulk_reg_val *p = tasdev[i].cali_data_backup; + + if (p == NULL) + continue; + for (j = 0; j < sum; j++) { + if (p[j].val_len == 1) + tasdevice_dev_read(tas_priv, + i, p[j].reg, + (unsigned int *)&p[j].val[0]); + else + tasdevice_dev_bulk_read(tas_priv, + i, p[j].reg, p[j].val, 4); + } + + for (j = 0; j < sum; j++) { + if (p[j].val_len == 1) + tasdevice_dev_write(tas_priv, i, p[j].reg, + q[j].val[0]); + else + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, + q[j].val, 4); + } + } +out: + return rc; +} + +static void tas2563_calib_stop_put(struct tasdevice_priv *tas_priv) +{ + const int sum = ARRAY_SIZE(tas2563_cali_start_reg); + int i, j; + + for (i = 0; i < tas_priv->ndev; i++) { + struct tasdevice *tasdev = tas_priv->tasdevice; + struct bulk_reg_val *p = tasdev[i].cali_data_backup; + + if (p == NULL) + continue; + + for (j = 0; j < sum; j++) { + if (p[j].val_len == 1) + tasdevice_dev_write(tas_priv, i, p[j].reg, + p[j].val[0]); + else + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, + p[j].val, 4); + } + } +} + +static int tasdev_calib_stop_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *priv = snd_soc_component_get_drvdata(comp); + + guard(mutex)(&priv->codec_lock); + if (priv->chip_id == TAS2563) + tas2563_calib_stop_put(priv); + else + tas2781_calib_stop_put(priv); + + return 1; +} + +static int tasdev_cali_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + struct calidata *cali_data = &priv->cali_data; + struct cali_reg *p = &cali_data->cali_reg_array; + unsigned char *src = ucontrol->value.bytes.data; + unsigned char *dst = cali_data->data; + int rc = 1, i = 0; + int j; + + guard(mutex)(&priv->codec_lock); + if (src[0] != bytes_ext->max || src[1] != 'r') { + dev_err(priv->dev, "%s: pkg fmt invalid\n", __func__); + return 0; + } + for (j = 0; j < priv->ndev; j++) { + if (src[17 + j * 21] != j) { + dev_err(priv->dev, "%s: pkg fmt invalid\n", __func__); + return 0; + } + } + i += 2; + priv->is_user_space_calidata = true; + + p->r0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->r0_low_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->invr0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->pow_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->tlimit_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + + memcpy(dst, &src[i], cali_data->total_sz); + return rc; +} + +static int tas2781_latch_reg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct i2c_client *clt = (struct i2c_client *)tas_priv->client; + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + struct tasdevice *tasdev = tas_priv->tasdevice; + unsigned char *dst = ucontrol->value.bytes.data; + int i, val, rc = -1; + + dst[0] = bytes_ext->max; + guard(mutex)(&tas_priv->codec_lock); + for (i = 0; i < tas_priv->ndev; i++) { + if (clt->addr == tasdev[i].dev_addr) { + /* First byte is the device index. */ + dst[1] = i; + rc = tasdevice_dev_read(tas_priv, i, + TAS2781_RUNTIME_LATCH_RE_REG, &val); + if (rc < 0) + dev_err(tas_priv->dev, "%s, get value error\n", + __func__); + else + dst[2] = val; + + break; + } + } + + return rc; +} + +static int tasdev_tf_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned int reg; + int rc = -1; + + if (tas_priv->chip_id == TAS2781) + reg = TAS2781_RUNTIME_RE_REG_TF; + else + reg = TAS2563_RUNTIME_RE_REG_TF; + + guard(mutex)(&tas_priv->codec_lock); + dst[0] = bytes_ext->max; + rc = calib_data_get(tas_priv, reg, &dst[1]); + + return rc; +} + +static int tasdev_re_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned int reg; + int rc = -1; + + if (tas_priv->chip_id == TAS2781) + reg = TAS2781_RUNTIME_RE_REG; + else + reg = TAS2563_RUNTIME_RE_REG; + guard(mutex)(&tas_priv->codec_lock); + dst[0] = bytes_ext->max; + rc = calib_data_get(tas_priv, reg, &dst[1]); + + return rc; +} + +static int tasdev_r0_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct calidata *cali_data = &tas_priv->cali_data; + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned int reg; + int rc = -1; + + guard(mutex)(&tas_priv->codec_lock); + + if (tas_priv->chip_id == TAS2563) + reg = TAS2563_PRM_R0_REG; + else if (cali_data->cali_reg_array.r0_reg) + reg = cali_data->cali_reg_array.r0_reg; + else + return -1; + dst[0] = bytes_ext->max; + rc = calib_data_get(tas_priv, reg, &dst[1]); + + return rc; +} + +static int tasdev_XMA1_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned int reg = TASDEVICE_XM_A1_REG; + int rc = -1; + + guard(mutex)(&tas_priv->codec_lock); + dst[0] = bytes_ext->max; + rc = calib_data_get(tas_priv, reg, &dst[1]); + + return rc; +} + +static int tasdev_XMA2_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *) kcontrol->private_value; + unsigned char *dst = ucontrol->value.bytes.data; + unsigned int reg = TASDEVICE_XM_A2_REG; + int rc = -1; + + guard(mutex)(&tas_priv->codec_lock); + dst[0] = bytes_ext->max; + rc = calib_data_get(tas_priv, reg, &dst[1]); + + return rc; +} + +static int tasdev_nop_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + static int tas2563_digital_gain_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -241,6 +855,16 @@ static const struct snd_kcontrol_new tasdevice_snd_controls[] = { tasdev_force_fwload_get, tasdev_force_fwload_put), }; +static const struct snd_kcontrol_new tasdevice_cali_controls[] = { + SOC_SINGLE_EXT("Calibration Stop", SND_SOC_NOPM, 0, 1, 0, + tasdev_nop_get, tasdev_calib_stop_put), + SND_SOC_BYTES_EXT("Amp TF Data", 6, tasdev_tf_data_get, NULL), + SND_SOC_BYTES_EXT("Amp RE Data", 6, tasdev_re_data_get, NULL), + SND_SOC_BYTES_EXT("Amp R0 Data", 6, tasdev_r0_data_get, NULL), + SND_SOC_BYTES_EXT("Amp XMA1 Data", 6, tasdev_XMA1_data_get, NULL), + SND_SOC_BYTES_EXT("Amp XMA2 Data", 6, tasdev_XMA2_data_get, NULL), +}; + static const struct snd_kcontrol_new tas2781_snd_controls[] = { SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL, 1, 0, 20, 0, tas2781_amp_getvol, @@ -250,6 +874,10 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = { tas2781_digital_putvol, dvc_tlv), }; +static const struct snd_kcontrol_new tas2781_cali_controls[] = { + SND_SOC_BYTES_EXT("Amp Latch Data", 3, tas2781_latch_reg_get, NULL), +}; + static const struct snd_kcontrol_new tas2563_snd_controls[] = { SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2563_DVC_LVL, 0, 0, ARRAY_SIZE(tas2563_dvc_table) - 1, 0, @@ -257,6 +885,11 @@ static const struct snd_kcontrol_new tas2563_snd_controls[] = { tas2563_dvc_tlv), }; +static const struct snd_kcontrol_new tas2563_cali_controls[] = { + SOC_SINGLE_EXT("Calibration Start", SND_SOC_NOPM, 0, 1, 0, + tasdev_nop_get, tas2563_calib_start_put), +}; + static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -274,6 +907,31 @@ static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol, return ret; } +static int tasdevice_info_active_num(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = tas_priv->ndev - 1; + + return 0; +} + +static int tasdevice_info_chip_id(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = TAS2563; + uinfo->value.integer.max = TAS2781; + + return 0; +} + static int tasdevice_info_programs(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -330,6 +988,17 @@ static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol, return 0; } +static int tasdevice_get_chip_id(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tas_priv->chip_id; + + return 0; +} + static int tasdevice_create_control(struct tasdevice_priv *tas_priv) { struct snd_kcontrol_new *prof_ctrls; @@ -421,11 +1090,47 @@ static int tasdevice_configuration_put( return ret; } +static int tasdevice_active_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + struct i2c_client *clt = (struct i2c_client *)tas_priv->client; + struct tasdevice *tasdev = tas_priv->tasdevice; + int i; + + for (i = 0; i < tas_priv->ndev; i++) { + if (clt->addr == tasdev[i].dev_addr) { + ucontrol->value.integer.value[0] = i; + return 0; + } + } + + return -1; +} + +static int tasdevice_active_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); + int dev_id = ucontrol->value.integer.value[0]; + int max = tas_priv->ndev - 1, rc; + + dev_id = clamp(dev_id, 0, max); + + guard(mutex)(&tas_priv->codec_lock); + rc = tasdev_chn_switch(tas_priv, dev_id); + + return rc; +} + static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) { struct snd_kcontrol_new *dsp_ctrls; - char *prog_name, *conf_name; - int nr_controls = 2; + char *active_dev_num, *chip_id; + char *conf_name, *prog_name; + int nr_controls = 4; int mix_index = 0; int ret; @@ -466,6 +1171,30 @@ static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) dsp_ctrls[mix_index].put = tasdevice_configuration_put; mix_index++; + active_dev_num = devm_kstrdup(tas_priv->dev, "Activate Tasdevice Num", + GFP_KERNEL); + if (!active_dev_num) { + ret = -ENOMEM; + goto out; + } + dsp_ctrls[mix_index].name = active_dev_num; + dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + dsp_ctrls[mix_index].info = tasdevice_info_active_num; + dsp_ctrls[mix_index].get = tasdevice_active_num_get; + dsp_ctrls[mix_index].put = tasdevice_active_num_put; + mix_index++; + + chip_id = devm_kstrdup(tas_priv->dev, "Tasdevice Chip Id", GFP_KERNEL); + if (!chip_id) { + ret = -ENOMEM; + goto out; + } + dsp_ctrls[mix_index].name = chip_id; + dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + dsp_ctrls[mix_index].info = tasdevice_info_chip_id; + dsp_ctrls[mix_index].get = tasdevice_get_chip_id; + mix_index++; + ret = snd_soc_add_component_controls(tas_priv->codec, dsp_ctrls, nr_controls < mix_index ? nr_controls : mix_index); @@ -473,6 +1202,149 @@ out: return ret; } +static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) +{ + struct calidata *cali_data = &priv->cali_data; + struct tasdevice *tasdev = priv->tasdevice; + struct soc_bytes_ext *ext_cali_data; + struct snd_kcontrol_new *cali_ctrls; + unsigned int nctrls; + char *cali_name; + int rc, i; + + rc = snd_soc_add_component_controls(priv->codec, + tasdevice_cali_controls, ARRAY_SIZE(tasdevice_cali_controls)); + if (rc < 0) { + dev_err(priv->dev, "%s: Add cali controls err rc = %d", + __func__, rc); + return rc; + } + + if (priv->chip_id == TAS2781) { + cali_ctrls = (struct snd_kcontrol_new *)tas2781_cali_controls; + nctrls = ARRAY_SIZE(tas2781_cali_controls); + for (i = 0; i < priv->ndev; i++) { + tasdev[i].cali_data_backup = + kmemdup(tas2781_cali_start_reg, + sizeof(tas2781_cali_start_reg), GFP_KERNEL); + if (!tasdev[i].cali_data_backup) + return -ENOMEM; + } + } else { + cali_ctrls = (struct snd_kcontrol_new *)tas2563_cali_controls; + nctrls = ARRAY_SIZE(tas2563_cali_controls); + for (i = 0; i < priv->ndev; i++) { + tasdev[i].cali_data_backup = + kmemdup(tas2563_cali_start_reg, + sizeof(tas2563_cali_start_reg), GFP_KERNEL); + if (!tasdev[i].cali_data_backup) + return -ENOMEM; + } + } + + rc = snd_soc_add_component_controls(priv->codec, cali_ctrls, nctrls); + if (rc < 0) { + dev_err(priv->dev, "%s: Add chip cali ctrls err rc = %d", + __func__, rc); + return rc; + } + + /* index for cali_ctrls */ + i = 0; + if (priv->chip_id == TAS2781) + nctrls = 2; + else + nctrls = 1; + + /* + * Alloc kcontrol via devm_kzalloc(), which don't manually + * free the kcontrol。 + */ + cali_ctrls = devm_kcalloc(priv->dev, nctrls, + sizeof(cali_ctrls[0]), GFP_KERNEL); + if (!cali_ctrls) + return -ENOMEM; + + ext_cali_data = devm_kzalloc(priv->dev, sizeof(*ext_cali_data), + GFP_KERNEL); + if (!ext_cali_data) + return -ENOMEM; + + cali_name = devm_kstrdup(priv->dev, "Speaker Calibrated Data", + GFP_KERNEL); + if (!cali_name) + return -ENOMEM; + /* the number of calibrated data per tas2563/tas2781 */ + cali_data->cali_dat_sz_per_dev = 20; + /* + * Data structure for tas2563/tas2781 calibrated data: + * Pkg len (1 byte) + * Reg id (1 byte, constant 'r') + * book, page, register array for calibrated data (15 bytes) + * for (i = 0; i < Device-Sum; i++) { + * Device #i index_info (1 byte) + * Calibrated data for Device #i (20 bytes) + * } + */ + ext_cali_data->max = priv->ndev * + (cali_data->cali_dat_sz_per_dev + 1) + 1 + 15 + 1; + priv->cali_data.total_sz = priv->ndev * + (cali_data->cali_dat_sz_per_dev + 1); + priv->cali_data.data = devm_kzalloc(priv->dev, + ext_cali_data->max, GFP_KERNEL); + cali_ctrls[i].name = cali_name; + cali_ctrls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + cali_ctrls[i].info = snd_soc_bytes_info_ext; + cali_ctrls[i].get = tasdev_cali_data_get; + cali_ctrls[i].put = tasdev_cali_data_put; + cali_ctrls[i].private_value = (unsigned long)ext_cali_data; + i++; + + cali_data->data = devm_kzalloc(priv->dev, cali_data->total_sz, + GFP_KERNEL); + if (!cali_data->data) + return -ENOMEM; + + if (priv->chip_id == TAS2781) { + struct soc_bytes_ext *ext_cali_start; + char *cali_start_name; + + ext_cali_start = devm_kzalloc(priv->dev, + sizeof(*ext_cali_start), GFP_KERNEL); + if (!ext_cali_start) + return -ENOMEM; + + cali_start_name = devm_kstrdup(priv->dev, + "Calibration Start", GFP_KERNEL); + if (!cali_start_name) + return -ENOMEM; + /* + * package structure for tas2781 ftc start: + * Pkg len (1 byte) + * Reg id (1 byte, constant 'r') + * book, page, register for pilot threshold, pilot tone + * and sine gain (12 bytes) + * for (i = 0; i < Device-Sum; i++) { + * Device #i index_info (1 byte) + * Sine gain for Device #i (8 bytes) + * } + */ + ext_cali_start->max = 14 + priv->ndev * 9; + cali_ctrls[i].name = cali_start_name; + cali_ctrls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + cali_ctrls[i].info = snd_soc_bytes_info_ext; + cali_ctrls[i].put = tas2781_calib_start_put; + cali_ctrls[i].get = tasdev_nop_get; + cali_ctrls[i].private_value = (unsigned long)ext_cali_start; + i++; + } + + rc = snd_soc_add_component_controls(priv->codec, cali_ctrls, + nctrls < i ? nctrls : i); + + return rc; +} + static void tasdevice_fw_ready(const struct firmware *fmw, void *context) { @@ -519,6 +1391,12 @@ static void tasdevice_fw_ready(const struct firmware *fmw, goto out; } + ret = tasdevice_create_cali_ctrls(tas_priv); + if (ret) { + dev_err(tas_priv->dev, "cali controls error\n"); + goto out; + } + tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; /* If calibrated data occurs error, dsp will still works with default @@ -720,6 +1598,11 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec) static void tasdevice_deinit(void *context) { struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; + struct tasdevice *tasdev = tas_priv->tasdevice; + int i; + + for (i = 0; i < tas_priv->ndev; i++) + kfree(tasdev[i].cali_data_backup); tasdevice_config_info_remove(tas_priv); tasdevice_dsp_remove(tas_priv); -- GitLab From df69c9be571d71c1a768d5dd798902fccd9e593f Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Wed, 11 Dec 2024 12:38:59 +0800 Subject: [PATCH 394/456] UPSTREAM: ASoC: tas2781: Fix calibration issue in stress test One specific test condition: the default registers of p[j].reg ~ p[j+3].reg are 0, TASDEVICE_REG(0x00, 0x14, 0x38)(PLT_FLAG_REG), TASDEVICE_REG(0x00, 0x14, 0x40)(SINEGAIN_REG), and TASDEVICE_REG(0x00, 0x14, 0x44)(SINEGAIN2_REG). After first calibration, they are freshed to TASDEVICE_REG(0x00, 0x1a, 0x20), TASDEVICE_REG(0x00, 0x16, 0x58)(PLT_FLAG_REG), TASDEVICE_REG(0x00, 0x14, 0x44)(SINEGAIN_REG), and TASDEVICE_REG(0x00, 0x16, 0x64)(SINEGAIN2_REG) via "Calibration Start" kcontrol. In second calibration, the p[j].reg ~ p[j+3].reg have already become tas2781_cali_start_reg. However, p[j+2].reg, TASDEVICE_REG(0x00, 0x14, 0x44)(SINEGAIN_REG), will be freshed to TASDEVICE_REG(0x00, 0x16, 0x64), which is the third register in the input params of the kcontrol. This is why only first calibration can work, the second-time, third-time or more-time calibration always failed without reboot. Of course, if no p[j].reg is in the list of tas2781_cali_start_reg, this stress test can work well. Fixes: 49e2e353fb0d ("ASoC: tas2781: Add Calibration Kcontrols for Chromebook") Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20241211043859.1328-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit 2aa13da97e2b92d20a8ad4ead10da89f880b64e7) BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I5d652232df3c9fc20ffb929a5a482fa1d0b5c711 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6170489 Reviewed-by: Sean Paul Commit-Queue: Yu-Che Cheng Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index d0ba7cbe03a81..564a97a5635f4 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -370,7 +370,7 @@ static void sngl_calib_start(struct tasdevice_priv *tas_priv, int i, tasdevice_dev_read(tas_priv, i, p[j].reg, (int *)&p[j].val[0]); } else { - switch (p[j].reg) { + switch (tas2781_cali_start_reg[j].reg) { case 0: { if (!reg[0]) continue; -- GitLab From 0502f93176f2e5d09506b3ccc3c553ac4a832a0b Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Fri, 27 Dec 2024 15:49:09 +0800 Subject: [PATCH 395/456] UPSTREAM: ASoC: tas2781: Fix occasional calibration failture The root cause is that TAS2781 internal register is not unlocked before writing data into TAS2781_PRM_TEST_57_REG. Fixes: 49e2e353fb0d ("ASoC: tas2781: Add Calibration Kcontrols for Chromebook") Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20241227074909.1974-1-shenghao-ding@ti.com Signed-off-by: Mark Brown (cherry picked from commit cf86e0ae60a225e2c7921ced755e922da9012bea) BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I1ae6d5b29dc0a63cf279533bbf41132f53fd97a3 Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6182420 Reviewed-by: Sean Paul Commit-Queue: Yu-Che Cheng Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- sound/soc/codecs/tas2781-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 564a97a5635f4..ecf5d6666c591 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -78,7 +78,7 @@ static const struct bulk_reg_val tas2781_cali_start_reg[] = { X2781_CL_STT_VAL(TAS2781_PRM_INT_MASK_REG, 0xfe, false), X2781_CL_STT_VAL(TAS2781_PRM_CLK_CFG_REG, 0xdd, false), X2781_CL_STT_VAL(TAS2781_PRM_RSVD_REG, 0x20, false), - X2781_CL_STT_VAL(TAS2781_PRM_TEST_57_REG, 0x14, false), + X2781_CL_STT_VAL(TAS2781_PRM_TEST_57_REG, 0x14, true), X2781_CL_STT_VAL(TAS2781_PRM_TEST_62_REG, 0x45, true), X2781_CL_STT_VAL(TAS2781_PRM_PVDD_UVLO_REG, 0x03, false), X2781_CL_STT_VAL(TAS2781_PRM_CHNL_0_REG, 0xa8, false), -- GitLab From b3da6fb4f0ce2ecba5a6e089f7922df35b77ea17 Mon Sep 17 00:00:00 2001 From: Darren Ye Date: Sat, 21 Dec 2024 17:41:05 +0800 Subject: [PATCH 396/456] CHROMIUM: sound: soc/mediatek: add audio driver base for kernel-v6.6 1. Porting audio driver 2. add audio path for rauru and navi BUG=b:314021233 BUG=b:372561093 BUG=b:378823932 BUG=b:375953604 BUG=b:357736343 BUG=b:314021350 BUG=b:357753807 BUG=b:369287582 BUG=b:377339114 TEST=build and boot to shell;play audio UPSTREAM-TASK=b:379039241 Change-Id: I9f8b6d3207d648327e314f778020665fd7ef47c4 Signed-off-by: Darren Ye Signed-off-by: Cyril Chao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6123538 Commit-Queue: ChromeOS Auto Retry Reviewed-by: Eric Yilun Lin Reviewed-by: Fei Shao Tested-by: Eric Yilun Lin Signed-off-by: Hubert Mazur --- sound/soc/mediatek/Kconfig | 39 + sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/common/mtk-afe-fe-dai.c | 44 +- sound/soc/mediatek/common/mtk-afe-fe-dai.h | 7 +- .../mediatek/common/mtk-afe-platform-driver.c | 125 +- .../mediatek/common/mtk-afe-platform-driver.h | 10 + sound/soc/mediatek/common/mtk-base-afe.h | 36 +- sound/soc/mediatek/mt8196/Makefile | 36 + sound/soc/mediatek/mt8196/mt8196-afe-clk.c | 698 + sound/soc/mediatek/mt8196/mt8196-afe-clk.h | 313 + sound/soc/mediatek/mt8196/mt8196-afe-cm.c | 94 + sound/soc/mediatek/mt8196/mt8196-afe-cm.h | 23 + sound/soc/mediatek/mt8196/mt8196-afe-common.h | 287 + .../soc/mediatek/mt8196/mt8196-afe-control.c | 106 + sound/soc/mediatek/mt8196/mt8196-afe-gpio.c | 256 + sound/soc/mediatek/mt8196/mt8196-afe-gpio.h | 58 + sound/soc/mediatek/mt8196/mt8196-afe-pcm.c | 5120 +++++++ sound/soc/mediatek/mt8196/mt8196-dai-adda.c | 2204 +++ sound/soc/mediatek/mt8196/mt8196-dai-i2s.c | 4371 ++++++ sound/soc/mediatek/mt8196/mt8196-dai-tdm.c | 828 ++ .../mediatek/mt8196/mt8196-interconnection.h | 121 + sound/soc/mediatek/mt8196/mt8196-mt6681.c | 884 ++ sound/soc/mediatek/mt8196/mt8196-reg.h | 12133 ++++++++++++++++ 23 files changed, 27758 insertions(+), 36 deletions(-) create mode 100644 sound/soc/mediatek/mt8196/Makefile create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-clk.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-clk.h create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-cm.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-cm.h create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-common.h create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-control.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-gpio.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-gpio.h create mode 100644 sound/soc/mediatek/mt8196/mt8196-afe-pcm.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-dai-adda.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-dai-i2s.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-dai-tdm.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-interconnection.h create mode 100644 sound/soc/mediatek/mt8196/mt8196-mt6681.c create mode 100644 sound/soc/mediatek/mt8196/mt8196-reg.h diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 5a8476e1ecca7..835508faa96c8 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -204,6 +204,45 @@ config SND_SOC_MT8186_MT6366 Select Y if you have such device. If unsure select "N". +config SND_SOC_MT8196 + tristate "ASoC support for Mediatek MT8196 chip" + depends on ARCH_MEDIATEK && ARM64 + select SND_SOC_MEDIATEK + help + This adds ASoC driver for Mediatek MT8196 boards + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + +config SND_SOC_MT8196_MT6681 + tristate "ASoc Audio driver for MT8196 with MT6681 and I2S codec" + depends on SND_SOC_MT8196 + depends on I2C + select SND_SOC_MT6681 + select SND_SOC_NAU8315 + select SND_SOC_NAU8825 + select SND_SOC_RT5645 + select SND_SOC_RT5682_I2C + select SND_SOC_RT5682S + select SND_SOC_TAS2781_COMLIB + select SND_SOC_TAS2781_FMWLIB + select SND_SOC_TAS2781_I2C + help + This adds support for ASoC machine driver for MediaTek MT8196 + boards with the MT6681 and other I2S audio codecs. + Select Y if you have such device. + If unsure select "N". + +config SND_SOC_MTK_AUDIO_DSP + tristate "ASoC support for Mediatek audiodsp chip" + depends on MTK_AUDIODSP_SUPPORT + select SND_SOC_COMPRESS + help + This adds dsp driver for Mediatek boards + that can be used with other platforms. + Select Y if you have such device. + If unsure select "N". + config SND_SOC_MTK_BTCVSD tristate "ALSA BT SCO CVSD/MSBC Driver" help diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 3938e7f75c2ec..18ffc4ec46659 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_SND_SOC_MT8186) += mt8186/ obj-$(CONFIG_SND_SOC_MT8188) += mt8188/ obj-$(CONFIG_SND_SOC_MT8192) += mt8192/ obj-$(CONFIG_SND_SOC_MT8195) += mt8195/ +obj-$(CONFIG_SND_SOC_MT8196) += mt8196/ diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index 3044d9ab3d4d9..35588e309ba11 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c @@ -18,7 +18,7 @@ #define AFE_BASE_END_OFFSET 8 -static int mtk_regmap_update_bits(struct regmap *map, int reg, +int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, unsigned int val, int shift) { @@ -26,13 +26,16 @@ static int mtk_regmap_update_bits(struct regmap *map, int reg, return 0; return regmap_update_bits(map, reg, mask << shift, val << shift); } +EXPORT_SYMBOL(mtk_regmap_update_bits); + +int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) -static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) { if (reg < 0) return 0; return regmap_write(map, reg, val); } +EXPORT_SYMBOL(mtk_regmap_write); int mtk_afe_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -132,12 +135,13 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, if (afe->request_dram_resource) afe->request_dram_resource(afe->dev); - dev_dbg(afe->dev, "%s(), %s, ch %d, rate %d, fmt %d, dma_addr %pad, dma_area %p, dma_bytes 0x%zx\n", - __func__, memif->data->name, - channels, rate, format, - &substream->runtime->dma_addr, - substream->runtime->dma_area, - substream->runtime->dma_bytes); + dev_dbg(afe->dev, + "%s(), %s, ch %d, rate %d, fmt %d, dma_addr %pad, dma_area %px, dma_bytes 0x%zx\n", + __func__, memif->data->name, + channels, rate, format, + &substream->runtime->dma_addr, + substream->runtime->dma_area, + substream->runtime->dma_bytes); memset_io((void __force __iomem *)substream->runtime->dma_area, 0, substream->runtime->dma_bytes); @@ -379,6 +383,7 @@ int mtk_memif_set_enable(struct mtk_base_afe *afe, int id) __func__, id); return 0; } + dev_dbg(afe->dev, "%s(), id %d\n", __func__, id); return mtk_regmap_update_bits(afe->regmap, memif->data->enable_reg, 1, 1, memif->data->enable_shift); } @@ -459,8 +464,12 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe, struct mtk_base_afe_memif *memif = &afe->memif[id]; unsigned int mono; - if (memif->data->mono_shift < 0) - return 0; + dev_info(afe->dev, "%s(), id: %d, channel: %d\n", __func__, id, channel); + mono = memif->data->mono_invert ^ (channel == 1); + + if (memif->data->mono_shift > 0) + mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg, + 0x1, mono, memif->data->mono_shift); if (memif->data->quad_ch_mask) { unsigned int quad_ch = (channel == 4) ? 1 : 0; @@ -470,11 +479,6 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe, quad_ch, memif->data->quad_ch_shift); } - if (memif->data->mono_invert) - mono = (channel == 1) ? 0 : 1; - else - mono = (channel == 1) ? 1 : 0; - /* for specific configuration of memif mono mode */ if (memif->data->int_odd_flag_reg) mtk_regmap_update_bits(afe->regmap, @@ -482,8 +486,14 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe, 1, mono, memif->data->int_odd_flag_shift); - return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg, - 1, mono, memif->data->mono_shift); + if (memif->data->ch_num_maskbit) { + dev_info(afe->dev, "%s(), set ch num id: %d, channel: %d\n", __func__, id, channel); + mtk_regmap_update_bits(afe->regmap, memif->data->ch_num_reg, + memif->data->ch_num_maskbit, + channel, memif->data->ch_num_shift); + } + + return 0; } EXPORT_SYMBOL_GPL(mtk_memif_set_channel); diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.h b/sound/soc/mediatek/common/mtk-afe-fe-dai.h index 8cec906718279..d7d8d8eb85252 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.h @@ -12,7 +12,13 @@ struct snd_soc_dai_ops; struct mtk_base_afe; struct mtk_base_afe_memif; +struct mtk_base_irq_data; +int mtk_regmap_update_bits(struct regmap *map, int reg, + unsigned int mask, + unsigned int val, int shift); +int mtk_regmap_write(struct regmap *map, int reg, + unsigned int val); int mtk_afe_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai); void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream, @@ -33,7 +39,6 @@ int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe); int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id); int mtk_afe_suspend(struct snd_soc_component *component); int mtk_afe_resume(struct snd_soc_component *component); - int mtk_memif_set_enable(struct mtk_base_afe *afe, int id); int mtk_memif_set_disable(struct mtk_base_afe *afe, int id); int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c index 6b63305839414..efc5722811eea 100644 --- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c +++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c @@ -77,6 +77,16 @@ int mtk_afe_add_sub_dai_control(struct snd_soc_component *component) } EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control); +int mtk_afe_pcm_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + /* set the wait_for_avail to 2 sec*/ + substream->wait_time = msecs_to_jiffies(2 * 1000); + + return 0; +} +EXPORT_SYMBOL_GPL(mtk_afe_pcm_open); + snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { @@ -86,32 +96,109 @@ snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, const struct mtk_base_memif_data *memif_data = memif->data; struct regmap *regmap = afe->regmap; struct device *dev = afe->dev; - int reg_ofs_base = memif_data->reg_ofs_base; - int reg_ofs_cur = memif_data->reg_ofs_cur; - unsigned int hw_ptr = 0, hw_base = 0; - int ret, pcm_ptr_bytes; - - ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr); - if (ret || hw_ptr == 0) { - dev_err(dev, "%s hw_ptr err\n", __func__); - pcm_ptr_bytes = 0; + unsigned int hw_ptr_lower32 = 0, hw_ptr_upper32 = 0; + unsigned int hw_base_lower32 = 0, hw_base_upper32 = 0; + unsigned long long hw_ptr = 0, hw_base = 0; + int ret; + unsigned long long pcm_ptr_bytes = 0; + + ret = regmap_read(regmap, memif_data->reg_ofs_cur, &hw_ptr_lower32); + if (ret || hw_ptr_lower32 == 0) { + dev_err(dev, "%s hw_ptr_lower32 err\n", __func__); goto POINTER_RETURN_FRAMES; } - ret = regmap_read(regmap, reg_ofs_base, &hw_base); - if (ret || hw_base == 0) { - dev_err(dev, "%s hw_ptr err\n", __func__); - pcm_ptr_bytes = 0; - goto POINTER_RETURN_FRAMES; + if (memif_data->reg_ofs_cur_msb) { + ret = regmap_read(regmap, memif_data->reg_ofs_cur_msb, &hw_ptr_upper32); + if (ret) { + dev_err(dev, "%s hw_ptr_upper32 err\n", __func__); + goto POINTER_RETURN_FRAMES; + } } - pcm_ptr_bytes = hw_ptr - hw_base; + ret = regmap_read(regmap, memif_data->reg_ofs_base, &hw_base_lower32); + if (ret || hw_base_lower32 == 0) { + dev_err(dev, "%s hw_base_lower32 err\n", __func__); + goto POINTER_RETURN_FRAMES; + } + if (memif_data->reg_ofs_base_msb) { + ret = regmap_read(regmap, memif_data->reg_ofs_base_msb, &hw_base_upper32); + if (ret) { + dev_err(dev, "%s hw_base_upper32 err\n", __func__); + goto POINTER_RETURN_FRAMES; + } + } + hw_ptr = ((unsigned long long)hw_ptr_upper32 << 32) + hw_ptr_lower32; + hw_base = ((unsigned long long)hw_base_upper32 << 32) + hw_base_lower32; POINTER_RETURN_FRAMES: - return bytes_to_frames(substream->runtime, pcm_ptr_bytes); + pcm_ptr_bytes = MTK_WORD_SIZE_ALIGN(hw_ptr - hw_base); + return bytes_to_frames(substream->runtime, (ssize_t)pcm_ptr_bytes); } EXPORT_SYMBOL_GPL(mtk_afe_pcm_pointer); +/* calculate the target DMA-buffer position to be written/read */ +static void *get_dma_ptr(struct snd_pcm_runtime *runtime, + int channel, unsigned long hwoff) +{ + return runtime->dma_area + hwoff + + channel * (runtime->dma_bytes / runtime->channels); +} + +/* default copy_user ops for write; used for both interleaved and non- modes */ +static int default_write_copy(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *iter, unsigned long bytes) +{ + if (copy_from_iter(get_dma_ptr(substream->runtime, channel, hwoff), + bytes, iter) != bytes) + return -EFAULT; + return 0; +} + +/* default copy_user ops for read; used for both interleaved and non- modes */ +static int default_read_copy(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *iter, unsigned long bytes) +{ + if (copy_to_iter(get_dma_ptr(substream->runtime, channel, hwoff), + bytes, iter) != bytes) + return -EFAULT; + return 0; +} + +int mtk_afe_pcm_copy_user(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *buf, unsigned long bytes) +{ + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + mtk_sp_copy_f sp_copy; + int ret; + + sp_copy = is_playback ? default_write_copy : default_read_copy; + + if (afe->copy) { + ret = afe->copy(substream, channel, hwoff, + buf, bytes, sp_copy); + if (ret) + return -EFAULT; + } else { + sp_copy(substream, channel, hwoff, + buf, bytes); + } + + return 0; +} +EXPORT_SYMBOL_GPL(mtk_afe_pcm_copy_user); + +int mtk_afe_pcm_ack(struct snd_pcm_substream *substream) +{ + return 0; +} +EXPORT_SYMBOL_GPL(mtk_afe_pcm_ack); + int mtk_afe_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { @@ -142,12 +229,18 @@ static int mtk_afe_component_probe(struct snd_soc_component *component) return 0; } +void mtk_afe_pcm_free(struct snd_soc_component *component, struct snd_pcm *pcm) +{ + snd_pcm_lib_preallocate_free_for_all(pcm); +} +EXPORT_SYMBOL_GPL(mtk_afe_pcm_free); const struct snd_soc_component_driver mtk_afe_pcm_platform = { .name = AFE_PCM_NAME, .pointer = mtk_afe_pcm_pointer, .pcm_construct = mtk_afe_pcm_new, .probe = mtk_afe_component_probe, + .pcm_destruct = mtk_afe_pcm_free, }; EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform); diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.h b/sound/soc/mediatek/common/mtk-afe-platform-driver.h index fcc923b88f124..91238abd99beb 100644 --- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h +++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.h @@ -12,15 +12,25 @@ #define AFE_PCM_NAME "mtk-afe-pcm" extern const struct snd_soc_component_driver mtk_afe_pcm_platform; +#define MTK_WORD_SIZE_ALIGN(x) ((x) & (0xfffffffff0)) + struct mtk_base_afe; struct snd_pcm; struct snd_soc_component; struct snd_soc_pcm_runtime; +int mtk_afe_pcm_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream); snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream); +int mtk_afe_pcm_copy_user(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *buf, unsigned long bytes); +int mtk_afe_pcm_ack(struct snd_pcm_substream *substream); int mtk_afe_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd); +void mtk_afe_pcm_free(struct snd_soc_component *component, struct snd_pcm *pcm); int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe); int mtk_afe_add_sub_dai_control(struct snd_soc_component *component); diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h index f51578b6c50a3..27fe49cd54c13 100644 --- a/sound/soc/mediatek/common/mtk-base-afe.h +++ b/sound/soc/mediatek/common/mtk-base-afe.h @@ -53,9 +53,11 @@ struct mtk_base_memif_data { int enable_reg; int enable_shift; int hd_reg; + int hd_mask; int hd_shift; int hd_align_reg; int hd_align_mshift; + int hd_msb_shift; int msb_reg; int msb_shift; int msb_end_reg; @@ -65,13 +67,19 @@ struct mtk_base_memif_data { int ch_num_reg; int ch_num_shift; int ch_num_maskbit; - /* playback memif only */ + /* VUL 24~26 only for CM2 */ + int out_on_use_reg; + int out_on_use_mask; + int out_on_use_shift; int pbuf_reg; int pbuf_mask; int pbuf_shift; int minlen_reg; int minlen_mask; int minlen_shift; + int maxlen_reg; + int maxlen_mask; + int maxlen_shift; }; struct mtk_base_irq_data { @@ -87,6 +95,10 @@ struct mtk_base_irq_data { int irq_clr_reg; int irq_clr_shift; int irq_status_shift; + int irq_ap_en_reg; + int irq_ap_en_shift; + int irq_scp_en_reg; + int irq_scp_en_shift; }; struct device; @@ -98,6 +110,9 @@ struct regmap; struct snd_pcm_substream; struct snd_soc_dai; +typedef int (*mtk_sp_copy_f)(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *iter, unsigned long bytes); struct mtk_base_afe { void __iomem *base_addr; struct device *dev; @@ -114,9 +129,17 @@ struct mtk_base_afe { struct mtk_base_afe_memif *memif; int memif_size; + int memif_32bit_supported; struct mtk_base_afe_irq *irqs; int irqs_size; - int memif_32bit_supported; + + /* using scp semaphore to protect reg access */ + int is_scp_sema_support; + + /* Bit banding of memif use AFE_AGEN_ON_SET/CLR + * to control memif enable bit. + */ + int is_memif_bit_banding; struct list_head sub_dais; struct snd_soc_dai_driver *dai_drivers; @@ -134,7 +157,16 @@ struct mtk_base_afe { int (*request_dram_resource)(struct device *dev); int (*release_dram_resource)(struct device *dev); + struct dentry *debugfs; + const struct mtk_afe_debug_cmd *debug_cmds; + void *platform_priv; + + int (*copy)(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *iter, unsigned long bytes, + mtk_sp_copy_f sp_copy); + }; struct mtk_base_afe_memif { diff --git a/sound/soc/mediatek/mt8196/Makefile b/sound/soc/mediatek/mt8196/Makefile new file mode 100644 index 0000000000000..4024db5193ac7 --- /dev/null +++ b/sound/soc/mediatek/mt8196/Makefile @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0 + +# MENU Governor Predict(low power) include path +ifeq ($(CONFIG_MTK_ACAO_SUPPORT),y) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/mcdi/include/ +endif + +# adsp include path +ccflags-y += -I$(srctree)/drivers/misc/mediatek/audio_ipi/include +ccflags-y += -I$(srctree)/sound/soc/mediatek/audio_dsp +ccflags-y += -I$(srctree)/drivers/misc/mediatek/adsp/include + +# spm include path +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include + +# pbm include path +ccflags-y += -I$(srctree)/drivers/misc/mediatek/pbm + +# common include path +subdir-ccflags-y += -I$(srctree)/sound/soc/mediatek/common + +# platform driver +obj-$(CONFIG_SND_SOC_MT8196) += snd-soc-mt8196-afe.o +snd-soc-mt8196-afe-objs += \ + mt8196-afe-pcm.o \ + mt8196-afe-clk.o \ + mt8196-afe-gpio.o \ + mt8196-dai-adda.o \ + mt8196-afe-control.o \ + mt8196-dai-i2s.o \ + mt8196-dai-tdm.o \ + mt8196-afe-cm.o + +# machine driver +obj-$(CONFIG_SND_SOC_MT8196_MT6681) += mt8196-mt6681.o diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-clk.c b/sound/soc/mediatek/mt8196/mt8196-afe-clk.c new file mode 100644 index 0000000000000..b2ad4d24fd305 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-clk.c @@ -0,0 +1,698 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8196-afe-clk.c -- Mediatek 8196 afe clock ctrl + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include "mt8196-afe-common.h" +#include "mt8196-afe-clk.h" + +static DEFINE_MUTEX(mutex_request_dram); + +static const char *aud_clks[CLK_NUM] = { + [CLK_HOPPING] = "aud_hopping_clk", + [CLK_F26M] = "aud_f26m_clk", + [CLK_UL0_ADC_CLK] = "aud_ul0_adc_clk", + [CLK_UL0_ADC_HIRES_CLK] = "aud_ul0_adc_hires_clk", + [CLK_UL1_ADC_CLK] = "aud_ul1_adc_clk", + [CLK_UL1_ADC_HIRES_CLK] = "aud_ul1_adc_hires_clk", + [CLK_APLL1] = "aud_apll1_clk", + [CLK_APLL2] = "aud_apll2_clk", + [CLK_APLL1_TUNER] = "aud_apll_tuner1_clk", + [CLK_APLL2_TUNER] = "aud_apll_tuner2_clk", + [CLK_VLP_MUX_AUDIOINTBUS] = "vlp_mux_audio_int", + [CLK_VLP_MUX_AUD_ENG1] = "vlp_mux_aud_eng1", + [CLK_VLP_MUX_AUD_ENG2] = "vlp_mux_aud_eng2", + [CLK_VLP_MUX_AUDIO_H] = "vlp_mux_audio_h", + [CLK_VLP_CLK26M] = "vlp_clk26m_clk", + [CLK_CK_MAINPLL_D4_D4] = "ck_mainpll_d4_d4", + [CLK_CK_MUX_AUD_1] = "ck_mux_aud_1", + [CLK_CK_APLL1_CK] = "ck_apll1_ck", + [CLK_CK_MUX_AUD_2] = "ck_mux_aud_2", + [CLK_CK_APLL2_CK] = "ck_apll2_ck", + [CLK_CK_APLL1_D4] = "ck_apll1_d4", + [CLK_CK_APLL2_D4] = "ck_apll2_d4", + [CLK_CK_I2SIN0_M_SEL] = "ck_i2sin0_m_sel", + [CLK_CK_I2SIN1_M_SEL] = "ck_i2sin1_m_sel", + [CLK_CK_FMI2S_M_SEL] = "ck_fmi2s_m_sel", + [CLK_CK_TDMOUT_M_SEL] = "ck_tdmout_m_sel", + [CLK_CK_APLL12_DIV_I2SIN0] = "ck_apll12_div_i2sin0", + [CLK_CK_APLL12_DIV_I2SIN1] = "ck_apll12_div_i2sin1", + [CLK_CK_APLL12_DIV_FMI2S] = "ck_apll12_div_fmi2s", + [CLK_CK_APLL12_DIV_TDMOUT_M] = "ck_apll12_div_tdmout_m", + [CLK_CK_APLL12_DIV_TDMOUT_B] = "ck_apll12_div_tdmout_b", + [CLK_CK_ADSP_SEL] = "ck_adsp_sel", + [CLK_CLK26M] = "ck_clk26m_clk", +}; + +int mt8196_set_audio_int_bus_parent(struct mtk_base_afe *afe, + int clk_id, bool int_bus) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct clk *clk; + int ret; + + clk = int_bus ? afe_priv->clk[CLK_VLP_MUX_AUDIOINTBUS] : + afe_priv->clk[CLK_VLP_MUX_AUDIO_H]; + ret = clk_set_parent(clk, afe_priv->clk[clk_id]); + if (ret) + dev_err(afe->dev, "%s() clk_set_parent %s fail %d, int_bus %d\n", + __func__, aud_clks[clk_id], ret, int_bus); + + return ret; +} + +static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + + dev_dbg(afe->dev, "%s(), enable: %d\n", __func__, enable); + + if (enable) { + ret = clk_prepare_enable(afe_priv->clk[CLK_CK_MUX_AUD_1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_1], ret); + goto EXIT; + } + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_1], + afe_priv->clk[CLK_CK_APLL1_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_1], + aud_clks[CLK_CK_APLL1_CK], ret); + goto EXIT; + } + + /* 180.6336 / 4 = 45.1584MHz */ + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUD_ENG1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG1], ret); + goto EXIT; + } + ret = clk_set_parent(afe_priv->clk[CLK_VLP_MUX_AUD_ENG1], + afe_priv->clk[CLK_CK_APLL1_D4]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG1], + aud_clks[CLK_CK_APLL1_D4], ret); + goto EXIT; + } + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUDIO_H], ret); + goto EXIT; + } + + mt8196_set_audio_int_bus_parent(afe, CLK_CK_APLL1_CK, false); + } else { + ret = clk_set_parent(afe_priv->clk[CLK_VLP_MUX_AUD_ENG1], + afe_priv->clk[CLK_VLP_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG1], + aud_clks[CLK_VLP_CLK26M], ret); + goto EXIT; + } + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUD_ENG1]); + + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_1], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_1], + aud_clks[CLK_CLK26M], ret); + goto EXIT; + } + clk_disable_unprepare(afe_priv->clk[CLK_CK_MUX_AUD_1]); + + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, false); + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + } + +EXIT: + return 0; +} + +static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + + dev_dbg(afe->dev, "%s(), enable: %d\n", __func__, enable); + + if (enable) { + ret = clk_prepare_enable(afe_priv->clk[CLK_CK_MUX_AUD_2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_2], ret); + goto EXIT; + } + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_2], + afe_priv->clk[CLK_CK_APLL2_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_2], + aud_clks[CLK_CK_APLL2_CK], ret); + goto EXIT; + } + + /* 196.608 / 4 = 49.152MHz */ + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUD_ENG2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG2], ret); + goto EXIT; + } + ret = clk_set_parent(afe_priv->clk[CLK_VLP_MUX_AUD_ENG2], + afe_priv->clk[CLK_CK_APLL2_D4]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG2], + aud_clks[CLK_CK_APLL2_D4], ret); + goto EXIT; + } + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUDIO_H], ret); + goto EXIT; + } + + mt8196_set_audio_int_bus_parent(afe, CLK_CK_APLL2_CK, false); + } else { + ret = clk_set_parent(afe_priv->clk[CLK_VLP_MUX_AUD_ENG2], + afe_priv->clk[CLK_VLP_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUD_ENG2], + aud_clks[CLK_VLP_CLK26M], ret); + goto EXIT; + } + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUD_ENG2]); + + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_2], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_2], + aud_clks[CLK_CLK26M], ret); + goto EXIT; + } + clk_disable_unprepare(afe_priv->clk[CLK_CK_MUX_AUD_2]); + + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, false); + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + } +EXIT: + return 0; +} + +int mt8196_afe_disable_apll(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + + dev_dbg(afe->dev, "%s() successfully start\n", __func__); + + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUDIO_H], ret); + goto EXIT; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_CK_MUX_AUD_1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_1], ret); + goto EXIT; + } + + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_1], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_1], + aud_clks[CLK_CLK26M], ret); + goto EXIT; + } + ret = clk_prepare_enable(afe_priv->clk[CLK_CK_MUX_AUD_2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_2], ret); + goto EXIT; + } + + ret = clk_set_parent(afe_priv->clk[CLK_CK_MUX_AUD_2], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_CK_MUX_AUD_2], + aud_clks[CLK_CLK26M], ret); + goto EXIT; + } + + clk_disable_unprepare(afe_priv->clk[CLK_CK_MUX_AUD_1]); + clk_disable_unprepare(afe_priv->clk[CLK_CK_MUX_AUD_2]); + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, false); + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + + return 0; +EXIT: + return ret; + +} + +int mt8196_afe_apll_init(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + /* VLP_APLL1_CON0 = 0x6f28bd4c + * VLP_APLL2_CON2 = 0x78FD5264 + * VLP_APLL1_TUNER_CON0 = 0x6f28bd4d + * VLP_APLL2_TUNER_CON0 = 0x78fd5265 + */ + if (afe_priv->vlp_ck) { + regmap_write(afe_priv->vlp_ck, VLP_APLL1_TUNER_CON0, 0x6f28bd4d); + regmap_write(afe_priv->vlp_ck, VLP_APLL2_TUNER_CON0, 0x78fd5265); + } else { + dev_warn(afe->dev, "%s vlp_ck regmap is null ptr\n", __func__); + } + return 0; +} + +int mt8196_afe_enable_clock(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + + ret = clk_prepare_enable(afe_priv->clk[CLK_CK_ADSP_SEL]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_CK_ADSP_SEL], ret); + goto CLK_CK_ADSP_SEL_ERR; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUDIOINTBUS]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUDIOINTBUS], ret); + goto CLK_MUX_AUDIO_INTBUS_ERR; + } + ret = mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, true); + + ret = clk_prepare_enable(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_VLP_MUX_AUDIO_H], ret); + goto CLK_AUDIO_H_ERR; + } + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, false); + + /* IPM2.0: USE HOPPING & 26M */ + ret = clk_prepare_enable(afe_priv->clk[CLK_HOPPING]); + if (ret) { + dev_err(afe->dev, "%s() clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_HOPPING], ret); + goto CLK_AFE_ERR; + } + ret = clk_prepare_enable(afe_priv->clk[CLK_F26M]); + if (ret) { + dev_err(afe->dev, "%s() clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_F26M], ret); + goto CLK_AFE_ERR; + } + + return 0; + +CLK_AFE_ERR: + /* IPM2.0: Use HOPPING & 26M */ + clk_disable_unprepare(afe_priv->clk[CLK_HOPPING]); + clk_disable_unprepare(afe_priv->clk[CLK_F26M]); +CLK_AUDIO_H_ERR: + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); +CLK_MUX_AUDIO_INTBUS_ERR: + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIOINTBUS]); +CLK_CK_ADSP_SEL_ERR: + clk_disable_unprepare(afe_priv->clk[CLK_CK_ADSP_SEL]); + return ret; +} + +void mt8196_afe_disable_clock(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s() successfully start\n", __func__); + + /* IPM2.0: Use HOPPING & 26M */ + clk_disable_unprepare(afe_priv->clk[CLK_HOPPING]); + clk_disable_unprepare(afe_priv->clk[CLK_F26M]); + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, false); + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIO_H]); + mt8196_set_audio_int_bus_parent(afe, CLK_VLP_CLK26M, true); + clk_disable_unprepare(afe_priv->clk[CLK_VLP_MUX_AUDIOINTBUS]); + clk_disable_unprepare(afe_priv->clk[CLK_CK_ADSP_SEL]); +} + +int mt8196_afe_dram_request(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(dev, "%s(), dram_resource_counter %d\n", + __func__, afe_priv->dram_resource_counter); + + mutex_lock(&mutex_request_dram); + + afe_priv->dram_resource_counter++; + mutex_unlock(&mutex_request_dram); + + return 0; +} + +int mt8196_afe_dram_release(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(dev, "%s(), dram_resource_counter %d\n", + __func__, afe_priv->dram_resource_counter); + + mutex_lock(&mutex_request_dram); + afe_priv->dram_resource_counter--; + + if (afe_priv->dram_resource_counter < 0) { + dev_warn(dev, "%s(), dram_resource_counter %d\n", + __func__, afe_priv->dram_resource_counter); + afe_priv->dram_resource_counter = 0; + } + mutex_unlock(&mutex_request_dram); + return 0; +} + +int mt8196_apll1_enable(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* setting for APLL */ + apll1_mux_setting(afe, true); + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL1], ret); + goto ERR_CLK_APLL1; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL1_TUNER], ret); + goto ERR_CLK_APLL1_TUNER; + } + + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, + 0x0000FFF7, 0x00000372); + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1); + + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, + AUDIO_APLL1_EN_ON_MASK_SFT, + 0x1 << AUDIO_APLL1_EN_ON_SFT); + return 0; + +ERR_CLK_APLL1_TUNER: + clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]); +ERR_CLK_APLL1: + clk_disable_unprepare(afe_priv->clk[CLK_APLL1]); + + return ret; +} + +void mt8196_apll1_disable(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, + AUDIO_APLL1_EN_ON_MASK_SFT, + 0x0 << AUDIO_APLL1_EN_ON_SFT); + + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0); + + clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]); + clk_disable_unprepare(afe_priv->clk[CLK_APLL1]); + + apll1_mux_setting(afe, false); +} + +int mt8196_apll2_enable(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* setting for APLL */ + apll2_mux_setting(afe, true); + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL2], ret); + goto ERR_CLK_APLL2; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL2_TUNER], ret); + goto ERR_CLK_APLL2_TUNER; + } + + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, + 0x0000FFF7, 0x00000374); + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1); + + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, + AUDIO_APLL2_EN_ON_MASK_SFT, + 0x1 << AUDIO_APLL2_EN_ON_SFT); + + return 0; + +ERR_CLK_APLL2_TUNER: + clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]); +ERR_CLK_APLL2: + clk_disable_unprepare(afe_priv->clk[CLK_APLL2]); + + return ret; + + return 0; +} + +void mt8196_apll2_disable(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, + AUDIO_APLL2_EN_ON_MASK_SFT, + 0x0 << AUDIO_APLL2_EN_ON_SFT); + + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0); + + clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]); + clk_disable_unprepare(afe_priv->clk[CLK_APLL2]); + + apll2_mux_setting(afe, false); +} + +int mt8196_get_apll_rate(struct mtk_base_afe *afe, int apll) +{ + return (apll == MT8196_APLL1) ? 180633600 : 196608000; +} + +int mt8196_get_apll_by_rate(struct mtk_base_afe *afe, int rate) +{ + return ((rate % 8000) == 0) ? MT8196_APLL2 : MT8196_APLL1; +} + +int mt8196_get_apll_by_name(struct mtk_base_afe *afe, const char *name) +{ + if (strcmp(name, APLL1_W_NAME) == 0) + return MT8196_APLL1; + else + return MT8196_APLL2; +} + +/* mck */ +struct mt8196_mck_div { + int m_sel_id; + int div_clk_id; +}; + + +static const struct mt8196_mck_div mck_div[MT8196_MCK_NUM] = { + [MT8196_I2SIN0_MCK] = { + .m_sel_id = CLK_CK_I2SIN0_M_SEL, + .div_clk_id = CLK_CK_APLL12_DIV_I2SIN0, + }, + [MT8196_I2SIN1_MCK] = { + .m_sel_id = CLK_CK_I2SIN1_M_SEL, + .div_clk_id = CLK_CK_APLL12_DIV_I2SIN1, + }, + [MT8196_FMI2S_MCK] = { + .m_sel_id = CLK_CK_FMI2S_M_SEL, + .div_clk_id = CLK_CK_APLL12_DIV_FMI2S, + }, + [MT8196_TDMOUT_MCK] = { + .m_sel_id = CLK_CK_TDMOUT_M_SEL, + .div_clk_id = CLK_CK_APLL12_DIV_TDMOUT_M, + }, + [MT8196_TDMOUT_BCK] = { + .m_sel_id = -1, + .div_clk_id = CLK_CK_APLL12_DIV_TDMOUT_B, + }, +}; + +int mt8196_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int apll = mt8196_get_apll_by_rate(afe, rate); + int apll_clk_id = apll == MT8196_APLL1 ? + CLK_CK_MUX_AUD_1 : CLK_CK_MUX_AUD_2; + int m_sel_id = 0; + int div_clk_id = 0; + int ret = 0; + + dev_dbg(afe->dev, "%s(), mck_id: %d\n", __func__, mck_id); + + m_sel_id = mck_div[mck_id].m_sel_id; + div_clk_id = mck_div[mck_id].div_clk_id; + + /* select apll */ + if (m_sel_id >= 0) { + ret = clk_prepare_enable(afe_priv->clk[m_sel_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[m_sel_id], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[m_sel_id], + afe_priv->clk[apll_clk_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[m_sel_id], + aud_clks[apll_clk_id], ret); + return ret; + } + } + + /* enable div, set rate */ + if (div_clk_id < 0) { + dev_err(afe->dev, "%s(), invalid div_clk_id %d\n", __func__, div_clk_id); + return -EINVAL; + } + if (div_clk_id == CLK_CK_APLL12_DIV_TDMOUT_B) + rate = rate * 16; + ret = clk_prepare_enable(afe_priv->clk[div_clk_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[div_clk_id], ret); + return ret; + } + ret = clk_set_rate(afe_priv->clk[div_clk_id], rate); + if (ret) { + dev_err(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n", + __func__, aud_clks[div_clk_id], + rate, ret); + return ret; + } + return 0; +} + +int mt8196_mck_disable(struct mtk_base_afe *afe, int mck_id) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int m_sel_id = 0; + int div_clk_id = 0; + + dev_dbg(afe->dev, "%s(), mck_id: %d.\n", __func__, mck_id); + + if (mck_id < 0) { + dev_err(afe->dev, "%s(), mck_id = %d < 0\n", + __func__, mck_id); + return -EINVAL; + } + + m_sel_id = mck_div[mck_id].m_sel_id; + div_clk_id = mck_div[mck_id].div_clk_id; + + if (div_clk_id < 0) { + dev_err(afe->dev, "%s(), div_clk_id = %d < 0\n", + __func__, div_clk_id); + return -EINVAL; + } + clk_disable_unprepare(afe_priv->clk[div_clk_id]); + + + if (m_sel_id >= 0) + clk_disable_unprepare(afe_priv->clk[m_sel_id]); + + return 0; +} + +int mt8196_init_clock(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int i = 0; + + afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk), + GFP_KERNEL); + if (!afe_priv->clk) + return -ENOMEM; + + for (i = 0; i < CLK_NUM; i++) { + if (aud_clks[i] == NULL) { + dev_err(afe->dev, "%s(), clk id %d not define!!!\n", + __func__, i); + } + + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clk[i])) { + dev_err(afe->dev, "%s devm_clk_get %s fail, ret %ld\n", + __func__, + aud_clks[i], PTR_ERR(afe_priv->clk[i])); + afe_priv->clk[i] = NULL; + } + } + + afe_priv->vlp_ck = syscon_regmap_lookup_by_phandle(afe->dev->of_node, + "vlpcksys"); + if (IS_ERR(afe_priv->vlp_ck)) { + dev_err(afe->dev, "%s() Cannot find vlpcksys: %ld\n", + __func__, PTR_ERR(afe_priv->vlp_ck)); + afe_priv->vlp_ck = NULL; + } + + afe_priv->cksys_ck = syscon_regmap_lookup_by_phandle(afe->dev->of_node, + "cksys"); + if (IS_ERR(afe_priv->cksys_ck)) { + dev_err(afe->dev, "%s() Cannot find cksys controller: %ld\n", + __func__, PTR_ERR(afe_priv->cksys_ck)); + afe_priv->cksys_ck = NULL; + } + + mt8196_afe_apll_init(afe); + mt8196_afe_disable_apll(afe); + + // mt8196 is not in PERI, don't need enable peri ao clk + // mt8196_afe_enable_ao_clock(afe); + + return 0; +} diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-clk.h b/sound/soc/mediatek/mt8196/mt8196-afe-clk.h new file mode 100644 index 0000000000000..7572bb8a3bfad --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-clk.h @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8196-afe-clk.h -- Mediatek 8196 afe clock ctrl definition + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8196_AFE_CLOCK_CTRL_H_ +#define _MT8196_AFE_CLOCK_CTRL_H_ + +// vlp_cksys_clk: 0x1c016000 +#define VLP_AP_PLL_CON3 0x0264 +#define VLP_APLL1_CON0 0x0274 +#define VLP_APLL1_CON1 0x0278 +#define VLP_APLL1_CON2 0x027c +#define VLP_APLL1_CON4 0x0284 +#define VLP_APLL1_TUNER_CON0 0x02a4 + +#define VLP_APLL2_CON0 0x028c +#define VLP_APLL2_CON1 0x0290 +#define VLP_APLL2_CON2 0x0294 +#define VLP_APLL2_CON4 0x029c +#define VLP_APLL2_TUNER_CON0 0x02a8 +#define VLP_CLK_CFG_UPDATE1 0x0008 + +// cksys_clk: 0x10000000 +#define CLK_CFG_13 0x00e0 +#define CLK_CFG_UPDATE1 0x0008 + +#define CLK_AUDDIV_0 0x020c +#define CLK_AUDDIV_2 0x0214 +#define CLK_AUDDIV_5 0x0228 + +#define CKSYS_AUD_TOP_CFG 0x0218 + +/* CLK_AUDDIV_0 */ +#define APLL12_DIV_I2SIN0_PDN_SFT 0 +#define APLL12_DIV_I2SIN0_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN0_PDN_MASK_SFT (0x1 << 0) +#define APLL12_DIV_I2SIN1_PDN_SFT 1 +#define APLL12_DIV_I2SIN1_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN1_PDN_MASK_SFT (0x1 << 1) +#define APLL12_DIV_I2SIN2_PDN_SFT 2 +#define APLL12_DIV_I2SIN2_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN2_PDN_MASK_SFT (0x1 << 2) +#define APLL12_DIV_I2SIN3_PDN_SFT 3 +#define APLL12_DIV_I2SIN3_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN3_PDN_MASK_SFT (0x1 << 3) +#define APLL12_DIV_I2SIN4_PDN_SFT 4 +#define APLL12_DIV_I2SIN4_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN4_PDN_MASK_SFT (0x1 << 4) +#define APLL12_DIV_I2SIN6_PDN_SFT 5 +#define APLL12_DIV_I2SIN6_PDN_MASK 0x1 +#define APLL12_DIV_I2SIN6_PDN_MASK_SFT (0x1 << 5) +#define APLL12_DIV_I2SOUT0_PDN_SFT 6 +#define APLL12_DIV_I2SOUT0_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT0_PDN_MASK_SFT (0x1 << 6) +#define APLL12_DIV_I2SOUT1_PDN_SFT 7 +#define APLL12_DIV_I2SOUT1_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT1_PDN_MASK_SFT (0x1 << 7) +#define APLL12_DIV_I2SOUT2_PDN_SFT 8 +#define APLL12_DIV_I2SOUT2_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT2_PDN_MASK_SFT (0x1 << 8) +#define APLL12_DIV_I2SOUT3_PDN_SFT 9 +#define APLL12_DIV_I2SOUT3_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT3_PDN_MASK_SFT (0x1 << 9) +#define APLL12_DIV_I2SOUT4_PDN_SFT 10 +#define APLL12_DIV_I2SOUT4_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT4_PDN_MASK_SFT (0x1 << 10) +#define APLL12_DIV_I2SOUT6_PDN_SFT 11 +#define APLL12_DIV_I2SOUT6_PDN_MASK 0x1 +#define APLL12_DIV_I2SOUT6_PDN_MASK_SFT (0x1 << 11) +#define APLL12_DIV_FMI2S_PDN_SFT 12 +#define APLL12_DIV_FMI2S_PDN_MASK 0x1 +#define APLL12_DIV_FMI2S_PDN_MASK_SFT (0x1 << 12) +#define APLL12_DIV_TDMOUT_M_PDN_SFT 13 +#define APLL12_DIV_TDMOUT_M_PDN_MASK 0x1 +#define APLL12_DIV_TDMOUT_M_PDN_MASK_SFT (0x1 << 13) +#define APLL12_DIV_TDMOUT_B_PDN_SFT 14 +#define APLL12_DIV_TDMOUT_B_PDN_MASK 0x1 +#define APLL12_DIV_TDMOUT_B_PDN_MASK_SFT (0x1 << 14) +#define APLL_I2SIN0_MCK_SEL_SFT 16 +#define APLL_I2SIN0_MCK_SEL_MASK 0x1 +#define APLL_I2SIN0_MCK_SEL_MASK_SFT (0x1 << 16) +#define APLL_I2SIN1_MCK_SEL_SFT 17 +#define APLL_I2SIN1_MCK_SEL_MASK 0x1 +#define APLL_I2SIN1_MCK_SEL_MASK_SFT (0x1 << 17) +#define APLL_I2SIN2_MCK_SEL_SFT 18 +#define APLL_I2SIN2_MCK_SEL_MASK 0x1 +#define APLL_I2SIN2_MCK_SEL_MASK_SFT (0x1 << 18) +#define APLL_I2SIN3_MCK_SEL_SFT 19 +#define APLL_I2SIN3_MCK_SEL_MASK 0x1 +#define APLL_I2SIN3_MCK_SEL_MASK_SFT (0x1 << 19) +#define APLL_I2SIN4_MCK_SEL_SFT 20 +#define APLL_I2SIN4_MCK_SEL_MASK 0x1 +#define APLL_I2SIN4_MCK_SEL_MASK_SFT (0x1 << 20) +#define APLL_I2SIN6_MCK_SEL_SFT 21 +#define APLL_I2SIN6_MCK_SEL_MASK 0x1 +#define APLL_I2SIN6_MCK_SEL_MASK_SFT (0x1 << 21) +#define APLL_I2SOUT0_MCK_SEL_SFT 22 +#define APLL_I2SOUT0_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT0_MCK_SEL_MASK_SFT (0x1 << 22) +#define APLL_I2SOUT1_MCK_SEL_SFT 23 +#define APLL_I2SOUT1_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT1_MCK_SEL_MASK_SFT (0x1 << 23) +#define APLL_I2SOUT2_MCK_SEL_SFT 24 +#define APLL_I2SOUT2_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT2_MCK_SEL_MASK_SFT (0x1 << 24) +#define APLL_I2SOUT3_MCK_SEL_SFT 25 +#define APLL_I2SOUT3_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT3_MCK_SEL_MASK_SFT (0x1 << 25) +#define APLL_I2SOUT4_MCK_SEL_SFT 26 +#define APLL_I2SOUT4_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT4_MCK_SEL_MASK_SFT (0x1 << 26) +#define APLL_I2SOUT6_MCK_SEL_SFT 27 +#define APLL_I2SOUT6_MCK_SEL_MASK 0x1 +#define APLL_I2SOUT6_MCK_SEL_MASK_SFT (0x1 << 27) +#define APLL_FMI2S_MCK_SEL_SFT 28 +#define APLL_FMI2S_MCK_SEL_MASK 0x1 +#define APLL_FMI2S_MCK_SEL_MASK_SFT (0x1 << 28) +#define APLL_TDMOUT_MCK_SEL_SFT 29 +#define APLL_TDMOUT_MCK_SEL_MASK 0x1 +#define APLL_TDMOUT_MCK_SEL_MASK_SFT (0x1 << 29) + +/* CLK_AUDDIV_1 */ +#define APLL12_DIV_I2SIN0_INV_SFT 0 +#define APLL12_DIV_I2SIN0_INV_MASK 0x1 +#define APLL12_DIV_I2SIN0_INV_MASK_SFT (0x1 << 0) +#define APLL12_DIV_I2SIN1_INV_SFT 1 +#define APLL12_DIV_I2SIN1_INV_MASK 0x1 +#define APLL12_DIV_I2SIN1_INV_MASK_SFT (0x1 << 1) +#define APLL12_DIV_I2SIN2_INV_SFT 2 +#define APLL12_DIV_I2SIN2_INV_MASK 0x1 +#define APLL12_DIV_I2SIN2_INV_MASK_SFT (0x1 << 2) +#define APLL12_DIV_I2SIN3_INV_SFT 3 +#define APLL12_DIV_I2SIN3_INV_MASK 0x1 +#define APLL12_DIV_I2SIN3_INV_MASK_SFT (0x1 << 3) +#define APLL12_DIV_I2SIN4_INV_SFT 4 +#define APLL12_DIV_I2SIN4_INV_MASK 0x1 +#define APLL12_DIV_I2SIN4_INV_MASK_SFT (0x1 << 4) +#define APLL12_DIV_I2SIN6_INV_SFT 5 +#define APLL12_DIV_I2SIN6_INV_MASK 0x1 +#define APLL12_DIV_I2SIN6_INV_MASK_SFT (0x1 << 5) +#define APLL12_DIV_I2SOUT0_INV_SFT 6 +#define APLL12_DIV_I2SOUT0_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT0_INV_MASK_SFT (0x1 << 6) +#define APLL12_DIV_I2SOUT1_INV_SFT 7 +#define APLL12_DIV_I2SOUT1_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT1_INV_MASK_SFT (0x1 << 7) +#define APLL12_DIV_I2SOUT2_INV_SFT 8 +#define APLL12_DIV_I2SOUT2_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT2_INV_MASK_SFT (0x1 << 8) +#define APLL12_DIV_I2SOUT3_INV_SFT 9 +#define APLL12_DIV_I2SOUT3_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT3_INV_MASK_SFT (0x1 << 9) +#define APLL12_DIV_I2SOUT4_INV_SFT 10 +#define APLL12_DIV_I2SOUT4_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT4_INV_MASK_SFT (0x1 << 10) +#define APLL12_DIV_I2SOUT6_INV_SFT 11 +#define APLL12_DIV_I2SOUT6_INV_MASK 0x1 +#define APLL12_DIV_I2SOUT6_INV_MASK_SFT (0x1 << 11) +#define APLL12_DIV_FMI2S_INV_SFT 12 +#define APLL12_DIV_FMI2S_INV_MASK 0x1 +#define APLL12_DIV_FMI2S_INV_MASK_SFT (0x1 << 12) +#define APLL12_DIV_TDMOUT_M_INV_SFT 13 +#define APLL12_DIV_TDMOUT_M_INV_MASK 0x1 +#define APLL12_DIV_TDMOUT_M_INV_MASK_SFT (0x1 << 13) +#define APLL12_DIV_TDMOUT_B_INV_SFT 14 +#define APLL12_DIV_TDMOUT_B_INV_MASK 0x1 +#define APLL12_DIV_TDMOUT_B_INV_MASK_SFT (0x1 << 14) + +/* CLK_AUDDIV_2 */ +#define APLL12_CK_DIV_I2SIN0_SFT 0 +#define APLL12_CK_DIV_I2SIN0_MASK 0xff +#define APLL12_CK_DIV_I2SIN0_MASK_SFT (0xff << 0) +#define APLL12_CK_DIV_I2SIN1_SFT 8 +#define APLL12_CK_DIV_I2SIN1_MASK 0xff +#define APLL12_CK_DIV_I2SIN1_MASK_SFT (0xff << 8) +#define APLL12_CK_DIV_I2SIN2_SFT 16 +#define APLL12_CK_DIV_I2SIN2_MASK 0xff +#define APLL12_CK_DIV_I2SIN2_MASK_SFT (0xff << 16) +#define APLL12_CK_DIV_I2SIN3_SFT 24 +#define APLL12_CK_DIV_I2SIN3_MASK 0xff +#define APLL12_CK_DIV_I2SIN3_MASK_SFT (0xff << 24) + +/* AUD_TOP_CFG */ +#define AUD_TOP_CFG_SFT 0 +#define AUD_TOP_CFG_MASK 0xffffffff +#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_MON */ +#define AUD_TOP_MON_SFT 0 +#define AUD_TOP_MON_MASK 0xffffffff +#define AUD_TOP_MON_MASK_SFT (0xffffffff << 0) + +/* CLK_AUDDIV_3 */ +#define APLL12_CK_DIV_I2SIN4_SFT 0 +#define APLL12_CK_DIV_I2SIN4_MASK 0xff +#define APLL12_CK_DIV_I2SIN4_MASK_SFT (0xff << 0) +#define APLL12_CK_DIV_I2SIN6_SFT 8 +#define APLL12_CK_DIV_I2SIN6_MASK 0xff +#define APLL12_CK_DIV_I2SIN6_MASK_SFT (0xff << 8) +#define APLL12_CK_DIV_I2SOUT0_SFT 16 +#define APLL12_CK_DIV_I2SOUT0_MASK 0xff +#define APLL12_CK_DIV_I2SOUT0_MASK_SFT (0xff << 16) +#define APLL12_CK_DIV_I2SOUT1_SFT 24 +#define APLL12_CK_DIV_I2SOUT1_MASK 0xff +#define APLL12_CK_DIV_I2SOUT1_MASK_SFT (0xff << 24) + +/* CLK_AUDDIV_4 */ +#define APLL12_CK_DIV_I2SOUT2_SFT 0 +#define APLL12_CK_DIV_I2SOUT2_MASK 0xff +#define APLL12_CK_DIV_I2SOUT2_MASK_SFT (0xff << 0) +#define APLL12_CK_DIV_I2SOUT3_SFT 8 +#define APLL12_CK_DIV_I2SOUT3_MASK 0xff +#define APLL12_CK_DIV_I2SOUT3_MASK_SFT (0xff << 8) +#define APLL12_CK_DIV_I2SOUT4_SFT 16 +#define APLL12_CK_DIV_I2SOUT4_MASK 0xff +#define APLL12_CK_DIV_I2SOUT4_MASK_SFT (0xff << 16) +#define APLL12_CK_DIV_I2SOUT6_SFT 24 +#define APLL12_CK_DIV_I2SOUT6_MASK 0xff +#define APLL12_CK_DIV_I2SOUT6_MASK_SFT (0xff << 24) + +/* CLK_AUDDIV_5 */ +#define APLL12_CK_DIV_FMI2S_SFT 0 +#define APLL12_CK_DIV_FMI2S_MASK 0xff +#define APLL12_CK_DIV_FMI2S_MASK_SFT (0xff << 0) +#define APLL12_CK_DIV_TDMOUT_M_SFT 8 +#define APLL12_CK_DIV_TDMOUT_M_MASK 0xff +#define APLL12_CK_DIV_TDMOUT_M_MASK_SFT (0xff << 8) +#define APLL12_CK_DIV_TDMOUT_B_SFT 16 +#define APLL12_CK_DIV_TDMOUT_B_MASK 0xff +#define APLL12_CK_DIV_TDMOUT_B_MASK_SFT (0xff << 16) + +/* APLL */ +#define APLL1_W_NAME "APLL1" +#define APLL2_W_NAME "APLL2" +enum { + MT8196_APLL1 = 0, + MT8196_APLL2, +}; + +enum { + /* afe clk */ + CLK_HOPPING = 0, + CLK_F26M, + CLK_UL0_ADC_CLK, + CLK_UL0_ADC_HIRES_CLK, + CLK_UL1_ADC_CLK, + CLK_UL1_ADC_HIRES_CLK, + CLK_APLL1, + CLK_APLL2, + CLK_APLL1_TUNER, + CLK_APLL2_TUNER, + /* vlp clk */ + CLK_VLP_MUX_AUDIOINTBUS, + CLK_VLP_MUX_AUD_ENG1, + CLK_VLP_MUX_AUD_ENG2, + CLK_VLP_MUX_AUDIO_H, + CLK_VLP_CLK26M, + /* ck clk */ + CLK_CK_MAINPLL_D4_D4, + CLK_CK_MUX_AUD_1, + CLK_CK_APLL1_CK, + CLK_CK_MUX_AUD_2, + CLK_CK_APLL2_CK, + CLK_CK_APLL1_D4, + CLK_CK_APLL2_D4, + CLK_CK_I2SIN0_M_SEL, + CLK_CK_I2SIN1_M_SEL, + CLK_CK_FMI2S_M_SEL, + CLK_CK_TDMOUT_M_SEL, + CLK_CK_APLL12_DIV_I2SIN0, + CLK_CK_APLL12_DIV_I2SIN1, + CLK_CK_APLL12_DIV_FMI2S, + CLK_CK_APLL12_DIV_TDMOUT_M, + CLK_CK_APLL12_DIV_TDMOUT_B, + CLK_CK_ADSP_SEL, + CLK_CLK26M, + CLK_NUM +}; + +struct mtk_base_afe; + +int mt8196_init_clock(struct mtk_base_afe *afe); +int mt8196_afe_enable_clock(struct mtk_base_afe *afe); +void mt8196_afe_disable_clock(struct mtk_base_afe *afe); +int mt8196_afe_disable_apll(struct mtk_base_afe *afe); + +int mt8196_afe_dram_request(struct device *dev); +int mt8196_afe_dram_release(struct device *dev); + +int mt8196_apll1_enable(struct mtk_base_afe *afe); +void mt8196_apll1_disable(struct mtk_base_afe *afe); + +int mt8196_apll2_enable(struct mtk_base_afe *afe); +void mt8196_apll2_disable(struct mtk_base_afe *afe); + +int mt8196_get_apll_rate(struct mtk_base_afe *afe, int apll); +int mt8196_get_apll_by_rate(struct mtk_base_afe *afe, int rate); +int mt8196_get_apll_by_name(struct mtk_base_afe *afe, const char *name); + +extern void aud_intbus_mux_sel(unsigned int aud_idx); + +/* these will be replaced by using CCF */ +int mt8196_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate); +int mt8196_mck_disable(struct mtk_base_afe *afe, int mck_id); + +int mt8196_set_audio_int_bus_parent(struct mtk_base_afe *afe, + int clk_id, bool int_bus); + +#endif diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-cm.c b/sound/soc/mediatek/mt8196/mt8196-afe-cm.c new file mode 100644 index 0000000000000..b71d8cf9ce28c --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-cm.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include + +#include "mtk-afe-fe-dai.h" +#include "mtk-base-afe.h" + +#include "mt8196-afe-cm.h" +#include "mt8196-afe-common.h" + +void mt8196_set_cm_rate(struct mtk_base_afe *afe, int id, unsigned int rate) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + afe_priv->cm_rate[id] = rate; +} +EXPORT_SYMBOL_GPL(mt8196_set_cm_rate); + +static int mt8196_convert_cm_ch(unsigned int ch) +{ + return ch - 1; +} + +static unsigned int calculate_cm_update(int rate, int ch) +{ + unsigned int update_val; + + update_val = 26000000 / rate / (ch / 2); + update_val = update_val * 10 / 7; + if (update_val > 100) + update_val = 100; + if (update_val < 7) + update_val = 7; + + return update_val; +} + +int mt8196_set_cm(struct mtk_base_afe *afe, int id, + bool update, bool swap, unsigned int ch) +{ + unsigned int rate = 0; + unsigned int update_val = 0; + int reg; + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_info(afe->dev, "%s()-0, CM%d, rate %d, update %d, swap %d, ch %d\n", + __func__, id, rate, update, swap, ch); + + rate = afe_priv->cm_rate[id]; + update_val = update ? calculate_cm_update(rate, (int)ch) : 0x64; + + reg = AFE_CM0_CON0 + 0x10 * id; + /* update cnt */ + mtk_regmap_update_bits(afe->regmap, reg, AFE_CM_UPDATE_CNT_MASK, + update_val, AFE_CM_UPDATE_CNT_SFT); + + /* rate */ + mtk_regmap_update_bits(afe->regmap, reg, AFE_CM_1X_EN_SEL_FS_MASK, + rate, AFE_CM_1X_EN_SEL_FS_SFT); + + /* ch num */ + ch = mt8196_convert_cm_ch(ch); + mtk_regmap_update_bits(afe->regmap, reg, AFE_CM_CH_NUM_MASK, + ch, AFE_CM_CH_NUM_SFT); + + /* swap */ + mtk_regmap_update_bits(afe->regmap, reg, AFE_CM_BYTE_SWAP_MASK, + swap, AFE_CM_BYTE_SWAP_SFT); + + return 0; +} +EXPORT_SYMBOL_GPL(mt8196_set_cm); + +int mt8196_enable_cm_bypass(struct mtk_base_afe *afe, int id, bool en) +{ + int reg = AFE_CM0_CON0 + 0x10 * id; + + mtk_regmap_update_bits(afe->regmap, reg, AFE_CM_BYPASS_MODE_MASK, + en, AFE_CM_BYPASS_MODE_SFT); + + return 0; +} +EXPORT_SYMBOL_GPL(mt8196_enable_cm_bypass); + +MODULE_DESCRIPTION("Mediatek afe cm"); +MODULE_AUTHOR("darren ye "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-cm.h b/sound/soc/mediatek/mt8196/mt8196-afe-cm.h new file mode 100644 index 0000000000000..b7b8d1f7e1a56 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-cm.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef MTK_AFE_CM_H_ +#define MTK_AFE_CM_H_ +enum { + CM0, + CM1, + CM2, + CM_NUM, +}; + +void mt8196_set_cm_rate(struct mtk_base_afe *afe, int id, unsigned int rate); + +int mt8196_set_cm(struct mtk_base_afe *afe, int id, bool update, + bool swap, unsigned int ch); +int mt8196_enable_cm_bypass(struct mtk_base_afe *afe, int id, bool en); + +#endif /* MTK_AFE_CM_H_ */ + diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-common.h b/sound/soc/mediatek/mt8196/mt8196-afe-common.h new file mode 100644 index 0000000000000..ae3fcfc8a88e8 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-common.h @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8196-afe-common.h -- Mediatek 8196 audio driver definitions + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT_6991_AFE_COMMON_H_ +#define _MT_6991_AFE_COMMON_H_ +#include +#include +#include +#include +#include +#include "mt8196-reg.h" +#include "mtk-base-afe.h" +#include "mt8196-afe-cm.h" + +#define AUDIO_AEE(...) WARN_ON(true) + +enum { + MTK_AFE_RATE_8K, + MTK_AFE_RATE_11K, + MTK_AFE_RATE_12K, + MTK_AFE_RATE_384K, + MTK_AFE_RATE_16K, + MTK_AFE_RATE_22K, + MTK_AFE_RATE_24K, + MTK_AFE_RATE_352K, + MTK_AFE_RATE_32K, + MTK_AFE_RATE_44K, + MTK_AFE_RATE_48K, + MTK_AFE_RATE_88K, + MTK_AFE_RATE_96K, + MTK_AFE_RATE_176K, + MTK_AFE_RATE_192K, + MTK_AFE_RATE_260K, +}; +/* HW IPM 2.0 */ +enum { + MTK_AFE_IPM2P0_RATE_8K = 0x0, + MTK_AFE_IPM2P0_RATE_11K = 0x1, + MTK_AFE_IPM2P0_RATE_12K = 0x2, + MTK_AFE_IPM2P0_RATE_16K = 0x4, + MTK_AFE_IPM2P0_RATE_22K = 0x5, + MTK_AFE_IPM2P0_RATE_24K = 0x6, + MTK_AFE_IPM2P0_RATE_32K = 0x8, + MTK_AFE_IPM2P0_RATE_44K = 0x9, + MTK_AFE_IPM2P0_RATE_48K = 0xa, + MTK_AFE_IPM2P0_RATE_88K = 0xd, + MTK_AFE_IPM2P0_RATE_96K = 0xe, + MTK_AFE_IPM2P0_RATE_176K = 0x11, + MTK_AFE_IPM2P0_RATE_192K = 0x12, + MTK_AFE_IPM2P0_RATE_352K = 0x15, + MTK_AFE_IPM2P0_RATE_384K = 0x16, +}; + +enum { + MTK_AFE_PCM_RATE_8K, + MTK_AFE_PCM_RATE_16K, + MTK_AFE_PCM_RATE_32K, + MTK_AFE_PCM_RATE_48K, +}; + +enum { + MTKAIF_PROTOCOL_1 = 0, + MTKAIF_PROTOCOL_2, + MTKAIF_PROTOCOL_2_CLK_P2, +}; + +enum { + MT8196_MEMIF_DL0, + MT8196_MEMIF_DL1, + MT8196_MEMIF_DL2, + MT8196_MEMIF_DL3, + MT8196_MEMIF_DL4, + MT8196_MEMIF_DL5, + MT8196_MEMIF_DL6, + MT8196_MEMIF_DL7, + MT8196_MEMIF_DL8, + MT8196_MEMIF_DL23, + MT8196_MEMIF_DL24, + MT8196_MEMIF_DL25, + MT8196_MEMIF_DL26, + MT8196_MEMIF_DL_4CH, + MT8196_MEMIF_DL_24CH, + MT8196_MEMIF_VUL0, + MT8196_MEMIF_VUL1, + MT8196_MEMIF_VUL2, + MT8196_MEMIF_VUL3, + MT8196_MEMIF_VUL4, + MT8196_MEMIF_VUL5, + MT8196_MEMIF_VUL6, + MT8196_MEMIF_VUL7, + MT8196_MEMIF_VUL8, + MT8196_MEMIF_VUL9, + MT8196_MEMIF_VUL10, + MT8196_MEMIF_VUL24, + MT8196_MEMIF_VUL25, + MT8196_MEMIF_VUL26, + MT8196_MEMIF_VUL_CM0, + MT8196_MEMIF_VUL_CM1, + MT8196_MEMIF_VUL_CM2, + MT8196_MEMIF_ETDM_IN0, + MT8196_MEMIF_ETDM_IN1, + MT8196_MEMIF_ETDM_IN2, + MT8196_MEMIF_ETDM_IN3, + MT8196_MEMIF_ETDM_IN4, + MT8196_MEMIF_ETDM_IN6, + MT8196_MEMIF_HDMI, + MT8196_MEMIF_NUM, + MT8196_DAI_ADDA = MT8196_MEMIF_NUM, + MT8196_DAI_ADDA_CH34, + MT8196_DAI_ADDA_CH56, + MT8196_DAI_AP_DMIC, + MT8196_DAI_AP_DMIC_CH34, + MT8196_DAI_AP_DMIC_MULTICH, + MT8196_DAI_VOW, + MT8196_DAI_VOW_SCP_DMIC, + MT8196_DAI_CONNSYS_I2S, + MT8196_DAI_I2S_IN0, //48 + MT8196_DAI_I2S_IN1, + MT8196_DAI_I2S_IN2, + MT8196_DAI_I2S_IN3, + MT8196_DAI_I2S_IN4, + MT8196_DAI_I2S_IN6, + MT8196_DAI_I2S_OUT0, + MT8196_DAI_I2S_OUT1, + MT8196_DAI_I2S_OUT2, + MT8196_DAI_I2S_OUT3, + MT8196_DAI_I2S_OUT4, + MT8196_DAI_I2S_OUT6, + MT8196_DAI_FM_I2S_MASTER, + MT8196_DAI_HW_GAIN_0, + MT8196_DAI_HW_GAIN_1, + MT8196_DAI_HW_GAIN_2, + MT8196_DAI_HW_GAIN_3, + MT8196_DAI_SRC_0, + MT8196_DAI_SRC_1, + MT8196_DAI_SRC_2, + MT8196_DAI_SRC_3, + MT8196_DAI_PCM_0, + MT8196_DAI_PCM_1, + MT8196_DAI_TDM, + MT8196_DAI_TDM_DPTX, + MT8196_DAI_HOSTLESS_LPBK, + MT8196_DAI_HOSTLESS_FM, + MT8196_DAI_HOSTLESS_HW_GAIN_AAUDIO, + MT8196_DAI_HOSTLESS_SRC_AAUDIO, + MT8196_DAI_HOSTLESS_SPEECH, + MT8196_DAI_HOSTLESS_BT, + MT8196_DAI_HOSTLESS_SPH_ECHO_REF, + MT8196_DAI_HOSTLESS_SPK_INIT, + MT8196_DAI_HOSTLESS_IMPEDANCE, + MT8196_DAI_HOSTLESS_SRC_0, + MT8196_DAI_HOSTLESS_SRC_1, + MT8196_DAI_HOSTLESS_SRC_2, + MT8196_DAI_HOSTLESS_HW_SRC_0_OUT, + MT8196_DAI_HOSTLESS_HW_SRC_0_IN, + MT8196_DAI_HOSTLESS_HW_SRC_1_OUT, + MT8196_DAI_HOSTLESS_HW_SRC_1_IN, + MT8196_DAI_HOSTLESS_HW_SRC_2_OUT, + MT8196_DAI_HOSTLESS_HW_SRC_2_IN, + MT8196_DAI_HOSTLESS_SRC_BARGEIN, + MT8196_DAI_HOSTLESS_UL1, + MT8196_DAI_HOSTLESS_UL2, + MT8196_DAI_HOSTLESS_UL3, + MT8196_DAI_HOSTLESS_UL4, + MT8196_DAI_HOSTLESS_DSP_DL, + MT8196_DAI_NUM, + /* use for mtkaif calibration specail setting */ + MT8196_DAI_MTKAIF = MT8196_DAI_NUM, + MT8196_DAI_MISO_ONLY, +}; + +#define MT8196_DAI_I2S_MAX_NUM 13 //depends each platform's max i2s num + +/* update irq ID (= enum) from AFE_IRQ_MCU_STATUS */ +enum { + MT8196_IRQ_0, + MT8196_IRQ_1, + MT8196_IRQ_2, + MT8196_IRQ_3, + MT8196_IRQ_4, + MT8196_IRQ_5, + MT8196_IRQ_6, + MT8196_IRQ_7, + MT8196_IRQ_8, + MT8196_IRQ_9, + MT8196_IRQ_10, + MT8196_IRQ_11, + MT8196_IRQ_12, + MT8196_IRQ_13, + MT8196_IRQ_14, + MT8196_IRQ_15, + MT8196_IRQ_16, + MT8196_IRQ_17, + MT8196_IRQ_18, + MT8196_IRQ_19, + MT8196_IRQ_20, + MT8196_IRQ_21, + MT8196_IRQ_22, + MT8196_IRQ_23, + MT8196_IRQ_24, + MT8196_IRQ_25, + MT8196_IRQ_26, + MT8196_IRQ_31, /* used only for TDM */ + MT8196_IRQ_NUM, +}; +/* update irq ID (= enum) from AFE_IRQ_MCU_STATUS */ +enum { + MT8196_CUS_IRQ_TDM = 0, /* used only for TDM */ + MT8196_CUS_IRQ_NUM, +}; + +/* MCLK */ +enum { + MT8196_I2SIN0_MCK = 0, + MT8196_I2SIN1_MCK, + MT8196_FMI2S_MCK, + MT8196_TDMOUT_MCK, + MT8196_TDMOUT_BCK, + MT8196_MCK_NUM, +}; + +struct mt8196_afe_private { + struct clk **clk; + struct regmap *cksys_ck; + struct regmap *vlp_ck; + struct regmap *pmic_regmap; + int irq_cnt[MT8196_MEMIF_NUM]; + int stf_positive_gain_db; + int dram_resource_counter; + int sgen_sel; + int sgen_mode; + int sgen_rate; + int sgen_amplitude; + /* xrun assert */ + int xrun_assert[MT8196_MEMIF_NUM]; + + /* dai */ + bool dai_on[MT8196_DAI_NUM]; + void *dai_priv[MT8196_DAI_NUM]; + + /* adda */ + int mtkaif_protocol; + int mtkaif_chosen_phase[4]; + int mtkaif_phase_cycle[4]; + int mtkaif_calibration_num_phase; + int mtkaif_dmic; + int mtkaif_dmic_ch34; + int mtkaif_adda6_only; + /* support ap_dmic */ + int ap_dmic; + unsigned int audio_r_miso1_enable; + unsigned int miso_only; + + /* add for vs1 voter */ + /* adda dl/ul is on */ + bool is_adda_dl_on; + bool is_adda_ul_on; + /* vow is on */ + bool is_vow_enable; + /* adda dl vol idx is at maximum */ + bool is_adda_dl_max_vol; + /* current vote status of vs1 */ + bool is_mt6363_vote; + + /* mck */ + int mck_rate[MT8196_MCK_NUM]; + + /* channel merge */ + unsigned int cm_rate[CM_NUM]; +}; + +int mt8196_dai_adda_register(struct mtk_base_afe *afe); +int mt8196_dai_i2s_register(struct mtk_base_afe *afe); +int mt8196_dai_tdm_register(struct mtk_base_afe *afe); + +unsigned int mt8196_general_rate_transform(struct device *dev, + unsigned int rate); +unsigned int mt8196_rate_transform(struct device *dev, + unsigned int rate, int aud_blk); +int mt8196_dai_set_priv(struct mtk_base_afe *afe, int id, + int priv_size, const void *priv_data); +#endif diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-control.c b/sound/soc/mediatek/mt8196/mt8196-afe-control.c new file mode 100644 index 0000000000000..ab35f7ee5048f --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-control.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio Control + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include "mt8196-afe-common.h" +#include + +unsigned int mt8196_general_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_IPM2P0_RATE_8K; + case 11025: + return MTK_AFE_IPM2P0_RATE_11K; + case 12000: + return MTK_AFE_IPM2P0_RATE_12K; + case 16000: + return MTK_AFE_IPM2P0_RATE_16K; + case 22050: + return MTK_AFE_IPM2P0_RATE_22K; + case 24000: + return MTK_AFE_IPM2P0_RATE_24K; + case 32000: + return MTK_AFE_IPM2P0_RATE_32K; + case 44100: + return MTK_AFE_IPM2P0_RATE_44K; + case 48000: + return MTK_AFE_IPM2P0_RATE_48K; + case 88200: + return MTK_AFE_IPM2P0_RATE_88K; + case 96000: + return MTK_AFE_IPM2P0_RATE_96K; + case 176400: + return MTK_AFE_IPM2P0_RATE_176K; + case 192000: + return MTK_AFE_IPM2P0_RATE_192K; + /* not support 260K */ + case 352800: + return MTK_AFE_IPM2P0_RATE_352K; + case 384000: + return MTK_AFE_IPM2P0_RATE_384K; + default: + dev_info(dev, "%s(), rate %u invalid, use %d!!!\n", + __func__, + rate, MTK_AFE_IPM2P0_RATE_48K); + return MTK_AFE_IPM2P0_RATE_48K; + } +} + +static unsigned int pcm_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_PCM_RATE_8K; + case 16000: + return MTK_AFE_PCM_RATE_16K; + case 32000: + return MTK_AFE_PCM_RATE_32K; + case 48000: + return MTK_AFE_PCM_RATE_48K; + default: + dev_info(dev, "%s(), rate %u invalid, use %d!!!\n", + __func__, + rate, MTK_AFE_PCM_RATE_32K); + return MTK_AFE_PCM_RATE_32K; + } +} + +unsigned int mt8196_rate_transform(struct device *dev, + unsigned int rate, int aud_blk) +{ + switch (aud_blk) { + case MT8196_DAI_PCM_0: + case MT8196_DAI_PCM_1: + return pcm_rate_transform(dev, rate); + default: + return mt8196_general_rate_transform(dev, rate); + } +} + +int mt8196_dai_set_priv(struct mtk_base_afe *afe, int id, + int priv_size, const void *priv_data) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + void *temp_data; + + temp_data = devm_kzalloc(afe->dev, + priv_size, + GFP_KERNEL); + if (!temp_data) + return -ENOMEM; + + if (priv_data) + memcpy(temp_data, priv_data, priv_size); + + afe_priv->dai_priv[id] = temp_data; + + return 0; +} + diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-gpio.c b/sound/soc/mediatek/mt8196/mt8196-afe-gpio.c new file mode 100644 index 0000000000000..05680ed393f06 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-gpio.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8196-afe-gpio.c -- Mediatek 8196 afe gpio ctrl + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include + +#include "mt8196-afe-common.h" +#include "mt8196-afe-gpio.h" + +struct pinctrl *aud_pinctrl; +struct audio_gpio_attr { + const char *name; + bool gpio_prepare; + struct pinctrl_state *gpioctrl; +}; + +static struct audio_gpio_attr aud_gpios[MT8196_AFE_GPIO_GPIO_NUM] = { + [MT8196_AFE_GPIO_DAT_MISO0_OFF] = {"aud-dat-miso0-off", false, NULL}, + [MT8196_AFE_GPIO_DAT_MISO0_ON] = {"aud-dat-miso0-on", false, NULL}, + [MT8196_AFE_GPIO_DAT_MISO1_OFF] = {"aud-dat-miso1-off", false, NULL}, + [MT8196_AFE_GPIO_DAT_MISO1_ON] = {"aud-dat-miso1-on", false, NULL}, + [MT8196_AFE_GPIO_DAT_MOSI_OFF] = {"aud-dat-mosi-off", false, NULL}, + [MT8196_AFE_GPIO_DAT_MOSI_ON] = {"aud-dat-mosi-on", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT0_OFF] = {"aud-gpio-i2sout0-off", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT0_ON] = {"aud-gpio-i2sout0-on", false, NULL}, + [MT8196_AFE_GPIO_I2SIN0_OFF] = {"aud-gpio-i2sin0-off", false, NULL}, + [MT8196_AFE_GPIO_I2SIN0_ON] = {"aud-gpio-i2sin0-on", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT1_OFF] = {"aud-gpio-i2sout1-off", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT1_ON] = {"aud-gpio-i2sout1-on", false, NULL}, + [MT8196_AFE_GPIO_I2SIN1_OFF] = {"aud-gpio-i2sin1-off", false, NULL}, + [MT8196_AFE_GPIO_I2SIN1_ON] = {"aud-gpio-i2sin1-on", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT4_OFF] = {"aud-gpio-i2sout4-off", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT4_ON] = {"aud-gpio-i2sout4-on", false, NULL}, + [MT8196_AFE_GPIO_I2SIN4_OFF] = {"aud-gpio-i2sin4-off", false, NULL}, + [MT8196_AFE_GPIO_I2SIN4_ON] = {"aud-gpio-i2sin4-on", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT6_OFF] = {"aud-gpio-i2sout6-off", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT6_ON] = {"aud-gpio-i2sout6-on", false, NULL}, + [MT8196_AFE_GPIO_I2SIN6_OFF] = {"aud-gpio-i2sin6-off", false, NULL}, + [MT8196_AFE_GPIO_I2SIN6_ON] = {"aud-gpio-i2sin6-on", false, NULL}, + [MT8196_AFE_GPIO_AP_DMIC_OFF] = {"aud-gpio-ap-dmic-off", false, NULL}, + [MT8196_AFE_GPIO_AP_DMIC_ON] = {"aud-gpio-ap-dmic-on", false, NULL}, + [MT8196_AFE_GPIO_AP_DMIC1_OFF] = {"aud-gpio-ap-dmic1-off", false, NULL}, + [MT8196_AFE_GPIO_AP_DMIC1_ON] = {"aud-gpio-ap-dmic1-on", false, NULL}, + [MT8196_AFE_GPIO_DAT_MOSI_CH34_OFF] = {"aud-dat-mosi-ch34-off", false, NULL}, + [MT8196_AFE_GPIO_DAT_MOSI_CH34_ON] = {"aud-dat-mosi-ch34-on", false, NULL}, + [MT8196_AFE_GPIO_DAT_MISO_ONLY_OFF] = {"aud-dat-miso-only-off", false, NULL}, + [MT8196_AFE_GPIO_DAT_MISO_ONLY_ON] = {"aud-dat-miso-only-on", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT3_OFF] = {"aud-gpio-i2sout3-off", false, NULL}, + [MT8196_AFE_GPIO_I2SOUT3_ON] = {"aud-gpio-i2sout3-on", false, NULL}, + [MT8196_AFE_GPIO_I2SIN3_OFF] = {"aud-gpio-i2sin3-off", false, NULL}, + [MT8196_AFE_GPIO_I2SIN3_ON] = {"aud-gpio-i2sin3-on", false, NULL}, +}; + +static DEFINE_MUTEX(gpio_request_mutex); + +int mt8196_afe_gpio_init(struct mtk_base_afe *afe) +{ + int ret; + int i = 0; + + dev_dbg(afe->dev, "%s()\n", __func__); + + aud_pinctrl = devm_pinctrl_get(afe->dev); + if (IS_ERR(aud_pinctrl)) { + ret = PTR_ERR(aud_pinctrl); + dev_info(afe->dev, "%s(), ret %d, cannot get aud_pinctrl!\n", + __func__, ret); + return -ENODEV; + } + + for (i = 0; i < MT8196_AFE_GPIO_GPIO_NUM; i++) { + if (aud_gpios[i].name == NULL) { + dev_info(afe->dev, "%s(), gpio id %d not define!!!\n", + __func__, i); + } + } + + for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) { + aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl, + aud_gpios[i].name); + if (IS_ERR(aud_gpios[i].gpioctrl)) { + ret = PTR_ERR(aud_gpios[i].gpioctrl); + dev_info(afe->dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n", + __func__, aud_gpios[i].name, ret); + } else + aud_gpios[i].gpio_prepare = true; + } + + /* gpio status init */ + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA, 0); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA, 1); + + dev_dbg(afe->dev, "%s()\n", __func__); + + return 0; +} + +static int mt8196_afe_gpio_select(struct mtk_base_afe *afe, + enum mt8196_afe_gpio type) +{ + int ret = 0; + + dev_info(afe->dev, "%s(), type: %d.\n", __func__, type); + + if (type >= MT8196_AFE_GPIO_GPIO_NUM) { + dev_info(afe->dev, "%s(), error, invalid gpio type %d\n", + __func__, type); + return -EINVAL; + } + + if (!aud_gpios[type].gpio_prepare) { + dev_info(afe->dev, "%s(), error, gpio type %d not prepared\n", + __func__, type); + return -EIO; + } + + ret = pinctrl_select_state(aud_pinctrl, + aud_gpios[type].gpioctrl); + if (ret) + dev_info(afe->dev, "%s(), error, can not set gpio type %d\n", + __func__, type); + + return ret; +} + +int mt8196_afe_gpio_request(struct mtk_base_afe *afe, bool enable, + int dai, int uplink) +{ + dev_info(afe->dev, "%s(), enable: %d, dai: %d, uplink: %d.\n", __func__, + enable, dai, uplink); + + mutex_lock(&gpio_request_mutex); + switch (dai) { + case MT8196_DAI_ADDA: + break; + case MT8196_DAI_ADDA_CH34: + break; + case MT8196_DAI_ADDA_CH56: + break; + case MT8196_DAI_I2S_IN0: + case MT8196_DAI_I2S_OUT0: + dev_info(afe->dev, "%s(), set enable: %d, DAI_I2S_IN0, DAI_I2S_OUT0.\n", + __func__, enable); + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN0_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT0_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN0_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT0_OFF); + } + break; + case MT8196_DAI_I2S_IN1: + case MT8196_DAI_I2S_OUT1: + dev_info(afe->dev, "%s(), set enable: %d, DAI_I2S_IN1,DAI_I2S_OUT1.\n", + __func__, enable); + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN1_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT1_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN1_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT1_OFF); + } + break; + case MT8196_DAI_I2S_IN3: + case MT8196_DAI_I2S_OUT3: + dev_info(afe->dev, "%s(), set enable: %d, DAI_I2S_IN3,DAI_I2S_OUT3.\n", + __func__, enable); + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN3_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT3_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN3_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT3_OFF); + } + break; + case MT8196_DAI_I2S_IN4: + case MT8196_DAI_I2S_OUT4: + dev_info(afe->dev, "%s(), set enable: %d, DAI_I2S_IN4, DAI_I2S_OUT4.\n", + __func__, enable); + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN4_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT4_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN4_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT4_OFF); + } + break; + case MT8196_DAI_I2S_IN6: + case MT8196_DAI_I2S_OUT6: + dev_info(afe->dev, "%s(), set enable: %d, DAI_I2S_IN6, DAI_I2S_OUT6.\n", + __func__, enable); + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN6_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT6_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SIN6_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_I2SOUT6_OFF); + } + break; + case MT8196_DAI_VOW: + break; + case MT8196_DAI_VOW_SCP_DMIC: + break; + case MT8196_DAI_MTKAIF: + if (enable) { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO1_ON); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO0_ON); + } else { + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO1_OFF); + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO0_OFF); + } + break; + case MT8196_DAI_MISO_ONLY: + if (enable) + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO_ONLY_ON); + else + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_DAT_MISO_ONLY_OFF); + break; + case MT8196_DAI_AP_DMIC: + dev_info(afe->dev, "%s(), DMIC0 set gpio enable: %d, MT8196_DAI_AP_DMIC.\n", + __func__, enable); + if (enable) + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_AP_DMIC_ON); + else + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_AP_DMIC_OFF); + break; + case MT8196_DAI_AP_DMIC_CH34: + dev_info(afe->dev, "%s(), DMIC1 set gpio enable: %d, MT8196_DAI_AP_DMIC_CH34.\n", + __func__, enable); + if (enable) + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_AP_DMIC1_ON); + else + mt8196_afe_gpio_select(afe, MT8196_AFE_GPIO_AP_DMIC1_OFF); + break; + default: + mutex_unlock(&gpio_request_mutex); + dev_info(afe->dev, "%s(), invalid dai %d\n", __func__, dai); + return -EINVAL; + } + mutex_unlock(&gpio_request_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(mt8196_afe_gpio_request); + +bool mt8196_afe_gpio_is_prepared(enum mt8196_afe_gpio type) +{ + return aud_gpios[type].gpio_prepare; +} +EXPORT_SYMBOL(mt8196_afe_gpio_is_prepared); + diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-gpio.h b/sound/soc/mediatek/mt8196/mt8196-afe-gpio.h new file mode 100644 index 0000000000000..b36a8201d6490 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-gpio.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8196-afe-gpio.h -- Mediatek 8196 afe gpio ctrl definition + * + * Copyright (c) 2023 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8196_AFE_GPIO_H_ +#define _MT8196_AFE_GPIO_H_ +#include "mt8196-afe-common.h" + +enum mt8196_afe_gpio { + MT8196_AFE_GPIO_DAT_MISO0_OFF, + MT8196_AFE_GPIO_DAT_MISO0_ON, + MT8196_AFE_GPIO_DAT_MISO1_OFF, + MT8196_AFE_GPIO_DAT_MISO1_ON, + MT8196_AFE_GPIO_DAT_MOSI_OFF, + MT8196_AFE_GPIO_DAT_MOSI_ON, + MT8196_AFE_GPIO_DAT_MOSI_CH34_OFF, + MT8196_AFE_GPIO_DAT_MOSI_CH34_ON, + MT8196_AFE_GPIO_DAT_MISO_ONLY_OFF, + MT8196_AFE_GPIO_DAT_MISO_ONLY_ON, + MT8196_AFE_GPIO_I2SIN0_OFF, + MT8196_AFE_GPIO_I2SIN0_ON, + MT8196_AFE_GPIO_I2SOUT0_OFF, + MT8196_AFE_GPIO_I2SOUT0_ON, + MT8196_AFE_GPIO_I2SIN1_OFF, + MT8196_AFE_GPIO_I2SIN1_ON, + MT8196_AFE_GPIO_I2SOUT1_OFF, + MT8196_AFE_GPIO_I2SOUT1_ON, + MT8196_AFE_GPIO_I2SIN4_OFF, + MT8196_AFE_GPIO_I2SIN4_ON, + MT8196_AFE_GPIO_I2SOUT4_OFF, + MT8196_AFE_GPIO_I2SOUT4_ON, + MT8196_AFE_GPIO_I2SIN6_OFF, + MT8196_AFE_GPIO_I2SIN6_ON, + MT8196_AFE_GPIO_I2SOUT6_OFF, + MT8196_AFE_GPIO_I2SOUT6_ON, + MT8196_AFE_GPIO_AP_DMIC_OFF, + MT8196_AFE_GPIO_AP_DMIC_ON, + MT8196_AFE_GPIO_AP_DMIC1_OFF, + MT8196_AFE_GPIO_AP_DMIC1_ON, + MT8196_AFE_GPIO_I2SIN3_OFF, + MT8196_AFE_GPIO_I2SIN3_ON, + MT8196_AFE_GPIO_I2SOUT3_OFF, + MT8196_AFE_GPIO_I2SOUT3_ON, + MT8196_AFE_GPIO_GPIO_NUM +}; + +struct mtk_base_afe; + +int mt8196_afe_gpio_init(struct mtk_base_afe *afe); +int mt8196_afe_gpio_request(struct mtk_base_afe *afe, bool enable, + int dai, int uplink); +bool mt8196_afe_gpio_is_prepared(enum mt8196_afe_gpio type); + +#endif diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c new file mode 100644 index 0000000000000..edd208dfac9e8 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c @@ -0,0 +1,5120 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek ALSA SoC AFE platform driver for 8196 + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for Kernel Native SMC API */ +#include +#include /* for SMC ID table */ + +#include "mt8196-afe-common.h" +#include "mtk-afe-platform-driver.h" +#include "mtk-afe-fe-dai.h" +#include "mt8196-afe-clk.h" +#include "mt8196-afe-gpio.h" +#include "mt8196-interconnection.h" +/* FORCE_FPGA_ENABLE_IRQ use irq in fpga */ +#define FORCE_FPGA_ENABLE_IRQ + +static const struct snd_pcm_hardware mt8196_afe_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE), + .period_bytes_min = 96, + .period_bytes_max = 4 * 48 * 1024, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 256 * 1024, + .fifo_size = 0, +}; + +#define USECS_TO_CYCLES(time_usecs) \ + xloops_to_cycles((time_usecs) * 0x10C7UL) + +static inline unsigned long xloops_to_cycles(unsigned long xloops) +{ + return (xloops * loops_per_jiffy * HZ) >> 32; +} + +void mt8196_aud_delay(unsigned long usecs) +{ + unsigned long cycles = 0; + cycles_t start = get_cycles(); + + cycles = USECS_TO_CYCLES(usecs); + + while ((get_cycles() - start) < cycles) + cpu_relax(); +} + +static int mt8196_fe_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int memif_num = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware; + int ret; + + dev_dbg(afe->dev, "%s(), memif_num: %d.\n", __func__, memif_num); + + memif->substream = substream; + + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); + + snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + dev_info(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + + /* dynamic allocate irq to memif */ + if (memif->irq_usage < 0) { + int irq_id = mtk_dynamic_irq_acquire(afe); + + if (irq_id != afe->irqs_size) { + /* link */ + memif->irq_usage = irq_id; + } else { + dev_info(afe->dev, "%s() error: no more asys irq\n", + __func__); + ret = -EBUSY; + } + } + return ret; +} + +void mt8196_fe_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int memif_num = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + int irq_id = memif->irq_usage; + + dev_dbg(afe->dev, "%s(), memif_num: %d.\n", __func__, memif_num); + + memif->substream = NULL; + afe_priv->irq_cnt[memif_num] = 0; + afe_priv->xrun_assert[memif_num] = 0; + + if (!memif->const_irq) { + mtk_dynamic_irq_release(afe, irq_id); + memif->irq_usage = -1; + memif->substream = NULL; + } +} + +int mt8196_fe_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_pcm_runtime *const runtime = substream->runtime; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int id = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[id]; + int irq_id = memif->irq_usage; + struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id]; + const struct mtk_base_irq_data *irq_data = irqs->irq_data; + unsigned int counter = runtime->period_size; + unsigned int rate = runtime->rate; + int fs; + int ret = 0; + unsigned int tmp_reg = 0; + + dev_info(afe->dev, "%s(), %s cmd %d, irq_id %d\n", __func__, + memif->data->name, cmd, irq_id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + dev_info(afe->dev, "%s(), %s cmd %d, id %d\n", __func__, + memif->data->name, cmd, id); + ret = mtk_memif_set_enable(afe, id); + if (ret) { + dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n", + __func__, id, ret); + return ret; + } + + /* + * for small latency record + * ul memif need read some data before irq enable + */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if ((runtime->period_size * 1000) / rate <= 10) + mt8196_aud_delay(300); + } + + /* set irq counter */ + if (afe_priv->irq_cnt[id] > 0) + counter = afe_priv->irq_cnt[id]; + + mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg, + irq_data->irq_cnt_maskbit, + counter, irq_data->irq_cnt_shift); + + /* set irq fs */ + fs = afe->irq_fs(substream, runtime->rate); + if (fs < 0) + return -EINVAL; + + if (irq_data->irq_fs_reg >= 0) + mtk_regmap_update_bits(afe->regmap, irq_data->irq_fs_reg, + irq_data->irq_fs_maskbit, + fs, irq_data->irq_fs_shift); + + /* enable interrupt */ + mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg, + 1, 1, irq_data->irq_en_shift); + + return 0; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + ret = mtk_memif_set_disable(afe, id); + if (ret) { + dev_info(afe->dev, + "%s(), error, id %d, memif enable, ret %d\n", + __func__, id, ret); + } + + /* disable interrupt */ + mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg, + 1, 0, irq_data->irq_en_shift); + + /* clear pending IRQ */ + regmap_read(afe->regmap, irq_data->irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data->irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg^(AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + + return ret; + default: + return -EINVAL; + } +} + +static int mt8196_memif_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct mtk_base_afe *afe = NULL; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int id = cpu_dai->id; + unsigned int rate_reg = 0; + int cm = 0; + + if (!component) + return -EINVAL; + + afe = snd_soc_component_get_drvdata(component); + + if (!afe) + return -EINVAL; + + rate_reg = mt8196_rate_transform(afe->dev, rate, id); + + switch (id) { + case MT8196_MEMIF_VUL8: + case MT8196_MEMIF_VUL_CM0: + cm = CM0; + break; + case MT8196_MEMIF_VUL9: + case MT8196_MEMIF_VUL_CM1: + cm = CM1; + break; + case MT8196_MEMIF_VUL10: + case MT8196_MEMIF_VUL_CM2: + cm = CM2; + break; + default: + cm = CM0; + break; + } + + mt8196_set_cm_rate(afe, cm, rate_reg); + + return rate_reg; +} + +static int mt8196_get_dai_fs(struct mtk_base_afe *afe, + int dai_id, unsigned int rate) +{ + return mt8196_rate_transform(afe->dev, rate, dai_id); +} + +static int mt8196_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct mtk_base_afe *afe = NULL; + + if (!component) + return -EINVAL; + afe = snd_soc_component_get_drvdata(component); + return mt8196_general_rate_transform(afe->dev, rate); +} + +int mt8196_get_memif_pbuf_size(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + if ((runtime->period_size * 1000) / runtime->rate > 10) + return MT8196_MEMIF_PBUF_SIZE_256_BYTES; + else + return MT8196_MEMIF_PBUF_SIZE_32_BYTES; +} + +/* FE DAIs */ +static const struct snd_soc_dai_ops mt8196_memif_dai_ops = { + .startup = mt8196_fe_startup, + .shutdown = mt8196_fe_shutdown, + .hw_params = mtk_afe_fe_hw_params, + .hw_free = mtk_afe_fe_hw_free, + .prepare = mtk_afe_fe_prepare, + .trigger = mt8196_fe_trigger, +}; + +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_PCM_DAI_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000) + +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mt8196_memif_dai_driver[] = { + /* FE DAIs: memory intefaces to CPU */ + { + .name = "DL0", + .id = MT8196_MEMIF_DL0, + .playback = { + .stream_name = "DL0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL1", + .id = MT8196_MEMIF_DL1, + .playback = { + .stream_name = "DL1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL2", + .id = MT8196_MEMIF_DL2, + .playback = { + .stream_name = "DL2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL3", + .id = MT8196_MEMIF_DL3, + .playback = { + .stream_name = "DL3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL4", + .id = MT8196_MEMIF_DL4, + .playback = { + .stream_name = "DL4", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL5", + .id = MT8196_MEMIF_DL5, + .playback = { + .stream_name = "DL5", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL6", + .id = MT8196_MEMIF_DL6, + .playback = { + .stream_name = "DL6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL7", + .id = MT8196_MEMIF_DL7, + .playback = { + .stream_name = "DL7", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL8", + .id = MT8196_MEMIF_DL8, + .playback = { + .stream_name = "DL8", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL23", + .id = MT8196_MEMIF_DL23, + .playback = { + .stream_name = "DL23", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL24", + .id = MT8196_MEMIF_DL24, + .playback = { + .stream_name = "DL24", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL25", + .id = MT8196_MEMIF_DL25, + .playback = { + .stream_name = "DL25", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL26", + .id = MT8196_MEMIF_DL26, + .playback = { + .stream_name = "DL26", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL_4CH", + .id = MT8196_MEMIF_DL_4CH, + .playback = { + .stream_name = "DL_4CH", + .channels_min = 1, + .channels_max = 4, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "DL_24CH", + .id = MT8196_MEMIF_DL_24CH, + .playback = { + .stream_name = "DL_24CH", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL0", + .id = MT8196_MEMIF_VUL0, + .capture = { + .stream_name = "UL0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL1", + .id = MT8196_MEMIF_VUL1, + .capture = { + .stream_name = "UL1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL2", + .id = MT8196_MEMIF_VUL2, + .capture = { + .stream_name = "UL2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL3", + .id = MT8196_MEMIF_VUL3, + .capture = { + .stream_name = "UL3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL4", + .id = MT8196_MEMIF_VUL4, + .capture = { + .stream_name = "UL4", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL5", + .id = MT8196_MEMIF_VUL5, + .capture = { + .stream_name = "UL5", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL6", + .id = MT8196_MEMIF_VUL6, + .capture = { + .stream_name = "UL6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL7", + .id = MT8196_MEMIF_VUL7, + .capture = { + .stream_name = "UL7", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL8", + .id = MT8196_MEMIF_VUL8, + .capture = { + .stream_name = "UL8", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL9", + .id = MT8196_MEMIF_VUL9, + .capture = { + .stream_name = "UL9", + .channels_min = 1, + .channels_max = 16, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL10", + .id = MT8196_MEMIF_VUL10, + .capture = { + .stream_name = "UL10", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL24", + .id = MT8196_MEMIF_VUL24, + .capture = { + .stream_name = "UL24", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL25", + .id = MT8196_MEMIF_VUL25, + .capture = { + .stream_name = "UL25", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL26", + .id = MT8196_MEMIF_VUL26, + .capture = { + .stream_name = "UL26", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_CM0", + .id = MT8196_MEMIF_VUL_CM0, + .capture = { + .stream_name = "UL_CM0", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_CM1", + .id = MT8196_MEMIF_VUL_CM1, + .capture = { + .stream_name = "UL_CM1", + .channels_min = 1, + .channels_max = 16, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_CM2", + .id = MT8196_MEMIF_VUL_CM2, + .capture = { + .stream_name = "UL_CM2", + .channels_min = 1, + .channels_max = 32, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN0", + .id = MT8196_MEMIF_ETDM_IN0, + .capture = { + .stream_name = "UL_ETDM_IN0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN1", + .id = MT8196_MEMIF_ETDM_IN1, + .capture = { + .stream_name = "UL_ETDM_IN1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN2", + .id = MT8196_MEMIF_ETDM_IN2, + .capture = { + .stream_name = "UL_ETDM_IN2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN3", + .id = MT8196_MEMIF_ETDM_IN3, + .capture = { + .stream_name = "UL_ETDM_IN3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN4", + .id = MT8196_MEMIF_ETDM_IN4, + .capture = { + .stream_name = "UL_ETDM_IN4", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "UL_ETDM_IN6", + .id = MT8196_MEMIF_ETDM_IN6, + .capture = { + .stream_name = "UL_ETDM_IN6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, + { + .name = "HDMI", + .id = MT8196_MEMIF_HDMI, + .playback = { + .stream_name = "HDMI", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8196_memif_dai_ops, + }, +}; + +static const struct snd_kcontrol_new mt8196_pcm_kcontrols[] = { +}; + +enum { + CM0_MUX_VUL8_2CH, + CM0_MUX_VUL8_8CH, + CM0_MUX_MASK, +}; +enum { + CM1_MUX_VUL9_2CH, + CM1_MUX_VUL9_16CH, + CM1_MUX_MASK, +}; +enum { + CM2_MUX_VUL10_2CH, + CM2_MUX_VUL10_32CH, + CM2_MUX_MASK, +}; + +static int ul_cm0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + unsigned int channels = 0; + + dev_dbg(afe->dev, "%s(), event 0x%x, name %s\n", + __func__, event, w->name); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + channels = 3; + mt8196_enable_cm_bypass(afe, CM0, 0x0); + mt8196_set_cm(afe, CM0, true, false, channels); + break; + case SND_SOC_DAPM_PRE_PMD: + mt8196_enable_cm_bypass(afe, CM0, 0x1); + break; + default: + break; + } + return 0; +} + +static int ul_cm1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + unsigned int channels = 0; + + dev_info(afe->dev, "%s(), event 0x%x, name %s\n", + __func__, event, w->name); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + channels = 4; + mt8196_enable_cm_bypass(afe, CM1, 0x0); + mt8196_set_cm(afe, CM1, true, false, channels); + break; + case SND_SOC_DAPM_PRE_PMD: + mt8196_enable_cm_bypass(afe, CM1, 0x1); + break; + default: + break; + } + return 0; +} + +static int ul_cm2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + unsigned int channels = 0; + + dev_info(afe->dev, "%s(), event 0x%x, name %s\n", + __func__, event, w->name); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + channels = 4; + mt8196_enable_cm_bypass(afe, CM2, 0x0); + mt8196_set_cm(afe, CM2, true, false, channels); + break; + case SND_SOC_DAPM_PRE_PMD: + mt8196_enable_cm_bypass(afe, CM2, 0x1); + break; + default: + break; + } + return 0; +} + +/* dma widget & routes*/ +static const struct snd_kcontrol_new memif_ul0_ch1_mix[] = { + /* Normal record */ + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN018_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN018_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN018_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN018_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN018_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN018_0, + I_ADDA_UL_CH6, 1, 0), + /* FM */ + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1", AFE_CONN018_0, + I_CONNSYS_I2S_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN018_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN018_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN018_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN018_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN018_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN018_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN018_1, + I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN018_2, + I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN018_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN018_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN018_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN018_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN018_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN018_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN018_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul0_ch2_mix[] = { + /* Normal record */ + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN019_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN019_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN019_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN019_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN019_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN019_0, + I_ADDA_UL_CH6, 1, 0), + /* FM */ + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2", AFE_CONN019_0, + I_CONNSYS_I2S_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN019_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN019_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN019_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN019_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN019_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN019_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN019_1, + I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN019_2, + I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN019_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN019_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN019_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN019_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN019_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN019_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN019_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN019_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN019_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN020_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1", AFE_CONN020_0, + I_CONNSYS_I2S_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN020_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN020_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN020_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN020_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN020_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN020_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN020_1, + I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN020_2, + I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN020_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN020_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN020_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN020_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN020_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH1", AFE_CONN020_4, + I_I2SIN3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN4_CH1", AFE_CONN020_4, + I_I2SIN4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH1", AFE_CONN020_5, + I_I2SIN6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN020_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN020_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN021_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2", AFE_CONN021_0, + I_CONNSYS_I2S_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN021_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN021_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN021_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN021_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN021_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN021_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN021_1, + I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN021_2, + I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN021_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN021_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN021_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN021_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN021_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN021_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN021_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH2", AFE_CONN021_4, + I_I2SIN3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN4_CH2", AFE_CONN021_4, + I_I2SIN4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH2", AFE_CONN021_5, + I_I2SIN6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN021_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN021_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul2_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN022_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN022_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN022_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN022_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH1", AFE_CONN022_0, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN022_6, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul2_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN023_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN023_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN023_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN023_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH2", AFE_CONN023_0, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN023_6, + I_SRC_1_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul3_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN024_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN024_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN024_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH1", AFE_CONN024_4, + I_I2SIN3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN4_CH1", AFE_CONN024_4, + I_I2SIN4_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul3_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN025_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN025_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN025_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH2", AFE_CONN025_4, + I_I2SIN3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN4_CH2", AFE_CONN025_4, + I_I2SIN4_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul4_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN026_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN026_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN026_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN026_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN026_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN026_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN026_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN026_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN026_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN026_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN026_0, + I_GAIN0_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul4_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN027_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN027_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN027_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN027_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN027_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN027_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN027_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN027_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN027_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN027_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN027_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN027_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN027_0, + I_GAIN0_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul5_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN028_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN028_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN028_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN028_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN028_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN028_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN028_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN028_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN028_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN0_OUT_CH1", AFE_CONN028_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH1", AFE_CONN028_4, + I_I2SIN3_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul5_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN029_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN029_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN029_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN029_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN029_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN029_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN029_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN029_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN029_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN029_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN029_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN0_OUT_CH2", AFE_CONN029_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN3_CH2", AFE_CONN029_4, + I_I2SIN3_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul6_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN030_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1", AFE_CONN030_0, + I_CONNSYS_I2S_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN030_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN030_1, + I_DL2_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul6_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN031_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2", AFE_CONN031_0, + I_CONNSYS_I2S_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN031_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN031_1, + I_DL2_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul7_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN032_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN032_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN032_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN032_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1", AFE_CONN032_0, + I_CONNSYS_I2S_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN032_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN032_1, + I_DL2_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul7_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN033_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN033_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN033_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN033_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2", AFE_CONN033_0, + I_CONNSYS_I2S_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN033_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN033_1, + I_DL2_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul8_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN034_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN034_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN034_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul8_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN035_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN035_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN035_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN035_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN035_4, + I_PCM_1_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul9_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN036_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN036_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN036_0, + I_ADDA_UL_CH3, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul9_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN037_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN037_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN037_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN037_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul10_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN038_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN038_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN038_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN038_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul10_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN039_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN039_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN039_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN039_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul24_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN066_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN066_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH1", AFE_CONN066_5, + I_I2SIN6_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul24_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN067_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN067_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH2", AFE_CONN067_5, + I_I2SIN6_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul25_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN068_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH1", AFE_CONN068_5, + I_I2SIN6_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul25_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN069_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH2", AFE_CONN069_5, + I_I2SIN6_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul26_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN070_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH1", AFE_CONN070_5, + I_I2SIN6_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul26_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN071_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN6_CH2", AFE_CONN071_5, + I_I2SIN6_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dsp_dl_playback_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL0", SND_SOC_NOPM, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL2", SND_SOC_NOPM, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL1", SND_SOC_NOPM, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL6", SND_SOC_NOPM, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL3", SND_SOC_NOPM, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DSP_DL_24CH", SND_SOC_NOPM, 0, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN040_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN040_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN040_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN040_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH1", AFE_CONN040_0, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN040_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN040_6, + I_SRC_1_OUT_CH1, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN041_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN041_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN041_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN041_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH2", AFE_CONN041_0, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN041_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN041_6, + I_SRC_1_OUT_CH2, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN042_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN042_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN042_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN042_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN043_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN043_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN043_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN043_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN044_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN044_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN044_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN044_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN045_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN045_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN045_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN045_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN046_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN046_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN046_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN046_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm0_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN047_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN047_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN047_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN047_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN048_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN048_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN048_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN048_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN048_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN048_0, + I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN048_6, + I_SRC_0_OUT_CH1, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN049_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN049_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN049_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN049_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN049_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN049_0, + I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN049_6, + I_SRC_0_OUT_CH2, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN050_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN050_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN050_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN050_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN050_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN050_0, + I_ADDA_UL_CH6, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN051_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN051_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN051_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN051_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN051_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN051_0, + I_ADDA_UL_CH6, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN052_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN052_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN052_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN052_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN052_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN052_0, + I_ADDA_UL_CH6, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN053_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN053_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN053_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN053_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN053_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN053_0, + I_ADDA_UL_CH6, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN054_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN054_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN054_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN054_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN055_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN055_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN055_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN055_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch9_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN056_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN056_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN056_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN056_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch10_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN057_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN057_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN057_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN057_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch11_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN058_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN058_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN058_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN058_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch12_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN059_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN059_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN059_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN059_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch13_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN060_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN060_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN060_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN060_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch14_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN061_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN061_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN061_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN061_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch15_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN062_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN062_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN062_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN062_0, + I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm1_ch16_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN063_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN063_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN063_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN063_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm2_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN064_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN064_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN064_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN064_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN064_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN064_0, I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN064_6, + I_SRC_0_OUT_CH1, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN065_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN065_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN065_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN065_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN065_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN065_0, I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN065_6, + I_SRC_0_OUT_CH2, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN066_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN066_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN066_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN066_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN066_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN066_0, I_ADDA_UL_CH6, 1, 0) +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN067_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN067_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN067_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN067_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN067_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN067_0, I_ADDA_UL_CH6, 1, 0) +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN068_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN068_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN068_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN068_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN068_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN068_0, I_ADDA_UL_CH6, 1, 0) +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN069_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN069_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN069_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN069_0, I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN069_0, I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN069_0, I_ADDA_UL_CH6, 1, 0) +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN070_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN070_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN070_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN070_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN071_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN071_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN071_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN071_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch9_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN072_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN072_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN072_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN072_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch10_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN073_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN073_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN073_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN073_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch11_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN074_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN074_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN074_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN074_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch12_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN075_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN075_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN075_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN075_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch13_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN076_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN076_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN076_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN076_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch14_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN077_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN077_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN077_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN077_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch15_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN078_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN078_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN078_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN078_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch16_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN079_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN079_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN079_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN079_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch17_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN080_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN080_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN080_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN080_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch18_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN081_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN081_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN081_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN081_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch19_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN082_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN082_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN082_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN082_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch20_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN083_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN083_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN083_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN083_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch21_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN084_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN084_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN084_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN084_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch22_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN085_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN085_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN085_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN085_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch23_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN086_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN086_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN086_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN086_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch24_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN087_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN087_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN087_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN087_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch25_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN088_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN088_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN088_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN088_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch26_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN089_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN089_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN089_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN089_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch27_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN090_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN090_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN090_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN090_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch28_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN091_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN091_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN091_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN091_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch29_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN092_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN092_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN092_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN092_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch30_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN093_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN093_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN093_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN093_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch31_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN094_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN094_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN094_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN094_0, I_ADDA_UL_CH4, 1, 0), +}; +static const struct snd_kcontrol_new memif_ul_cm2_ch32_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN095_0, I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN095_0, I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN095_0, I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN095_0, I_ADDA_UL_CH4, 1, 0), +}; + +static const char * const cm0_mux_map[] = { + "CM0_8CH_PATH", + "CM0_2CH_PATH", +}; +static const char * const cm1_mux_map[] = { + "CM1_16CH_PATH", + "CM1_2CH_PATH", +}; +static const char * const cm2_mux_map[] = { + "CM2_32CH_PATH", + "CM2_2CH_PATH", +}; + +static int cm0_mux_map_value[] = { + CM0_MUX_VUL8_8CH, + CM0_MUX_VUL8_2CH, +}; +static int cm1_mux_map_value[] = { + CM1_MUX_VUL9_16CH, + CM1_MUX_VUL9_2CH, +}; +static int cm2_mux_map_value[] = { + CM2_MUX_VUL10_32CH, + CM2_MUX_VUL10_2CH, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(ul_cm0_mux_map_enum, + AFE_CM0_CON0, + AFE_CM0_OUTPUT_MUX_SFT, + AFE_CM0_OUTPUT_MUX_MASK, + cm0_mux_map, + cm0_mux_map_value); +static SOC_VALUE_ENUM_SINGLE_DECL(ul_cm1_mux_map_enum, + AFE_CM1_CON0, + AFE_CM1_OUTPUT_MUX_SFT, + AFE_CM1_OUTPUT_MUX_MASK, + cm1_mux_map, + cm1_mux_map_value); +static SOC_VALUE_ENUM_SINGLE_DECL(ul_cm2_mux_map_enum, + AFE_CM2_CON0, + AFE_CM2_OUTPUT_MUX_SFT, + AFE_CM2_OUTPUT_MUX_MASK, + cm2_mux_map, + cm2_mux_map_value); + +static const struct snd_kcontrol_new ul_cm0_mux_control = + SOC_DAPM_ENUM("CM0_UL_MUX Select", ul_cm0_mux_map_enum); +static const struct snd_kcontrol_new ul_cm1_mux_control = + SOC_DAPM_ENUM("CM1_UL_MUX Select", ul_cm1_mux_map_enum); +static const struct snd_kcontrol_new ul_cm2_mux_control = + SOC_DAPM_ENUM("CM2_UL_MUX Select", ul_cm2_mux_map_enum); + +static const struct snd_soc_dapm_widget mt8196_memif_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("UL0_CH1", SND_SOC_NOPM, 0, 0, + memif_ul0_ch1_mix, ARRAY_SIZE(memif_ul0_ch1_mix)), + SND_SOC_DAPM_MIXER("UL0_CH2", SND_SOC_NOPM, 0, 0, + memif_ul0_ch2_mix, ARRAY_SIZE(memif_ul0_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL1_CH1", SND_SOC_NOPM, 0, 0, + memif_ul1_ch1_mix, ARRAY_SIZE(memif_ul1_ch1_mix)), + SND_SOC_DAPM_MIXER("UL1_CH2", SND_SOC_NOPM, 0, 0, + memif_ul1_ch2_mix, ARRAY_SIZE(memif_ul1_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL2_CH1", SND_SOC_NOPM, 0, 0, + memif_ul2_ch1_mix, ARRAY_SIZE(memif_ul2_ch1_mix)), + SND_SOC_DAPM_MIXER("UL2_CH2", SND_SOC_NOPM, 0, 0, + memif_ul2_ch2_mix, ARRAY_SIZE(memif_ul2_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL3_CH1", SND_SOC_NOPM, 0, 0, + memif_ul3_ch1_mix, ARRAY_SIZE(memif_ul3_ch1_mix)), + SND_SOC_DAPM_MIXER("UL3_CH2", SND_SOC_NOPM, 0, 0, + memif_ul3_ch2_mix, ARRAY_SIZE(memif_ul3_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL4_CH1", SND_SOC_NOPM, 0, 0, + memif_ul4_ch1_mix, ARRAY_SIZE(memif_ul4_ch1_mix)), + SND_SOC_DAPM_MIXER("UL4_CH2", SND_SOC_NOPM, 0, 0, + memif_ul4_ch2_mix, ARRAY_SIZE(memif_ul4_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL5_CH1", SND_SOC_NOPM, 0, 0, + memif_ul5_ch1_mix, ARRAY_SIZE(memif_ul5_ch1_mix)), + SND_SOC_DAPM_MIXER("UL5_CH2", SND_SOC_NOPM, 0, 0, + memif_ul5_ch2_mix, ARRAY_SIZE(memif_ul5_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL6_CH1", SND_SOC_NOPM, 0, 0, + memif_ul6_ch1_mix, ARRAY_SIZE(memif_ul6_ch1_mix)), + SND_SOC_DAPM_MIXER("UL6_CH2", SND_SOC_NOPM, 0, 0, + memif_ul6_ch2_mix, ARRAY_SIZE(memif_ul6_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL7_CH1", SND_SOC_NOPM, 0, 0, + memif_ul7_ch1_mix, ARRAY_SIZE(memif_ul7_ch1_mix)), + SND_SOC_DAPM_MIXER("UL7_CH2", SND_SOC_NOPM, 0, 0, + memif_ul7_ch2_mix, ARRAY_SIZE(memif_ul7_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL8_CH1", SND_SOC_NOPM, 0, 0, + memif_ul8_ch1_mix, ARRAY_SIZE(memif_ul8_ch1_mix)), + SND_SOC_DAPM_MIXER("UL8_CH2", SND_SOC_NOPM, 0, 0, + memif_ul8_ch2_mix, ARRAY_SIZE(memif_ul8_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL9_CH1", SND_SOC_NOPM, 0, 0, + memif_ul9_ch1_mix, ARRAY_SIZE(memif_ul9_ch1_mix)), + SND_SOC_DAPM_MIXER("UL9_CH2", SND_SOC_NOPM, 0, 0, + memif_ul9_ch2_mix, ARRAY_SIZE(memif_ul9_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL10_CH1", SND_SOC_NOPM, 0, 0, + memif_ul10_ch1_mix, ARRAY_SIZE(memif_ul10_ch1_mix)), + SND_SOC_DAPM_MIXER("UL10_CH2", SND_SOC_NOPM, 0, 0, + memif_ul10_ch2_mix, ARRAY_SIZE(memif_ul10_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL24_CH1", SND_SOC_NOPM, 0, 0, + memif_ul24_ch1_mix, ARRAY_SIZE(memif_ul24_ch1_mix)), + SND_SOC_DAPM_MIXER("UL24_CH2", SND_SOC_NOPM, 0, 0, + memif_ul24_ch2_mix, ARRAY_SIZE(memif_ul24_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL25_CH1", SND_SOC_NOPM, 0, 0, + memif_ul25_ch1_mix, ARRAY_SIZE(memif_ul25_ch1_mix)), + SND_SOC_DAPM_MIXER("UL25_CH2", SND_SOC_NOPM, 0, 0, + memif_ul25_ch2_mix, ARRAY_SIZE(memif_ul25_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL26_CH1", SND_SOC_NOPM, 0, 0, + memif_ul26_ch1_mix, ARRAY_SIZE(memif_ul26_ch1_mix)), + SND_SOC_DAPM_MIXER("UL26_CH2", SND_SOC_NOPM, 0, 0, + memif_ul26_ch2_mix, ARRAY_SIZE(memif_ul26_ch2_mix)), + + SND_SOC_DAPM_MIXER("DSP_DL", SND_SOC_NOPM, 0, 0, + mtk_dsp_dl_playback_mix, + ARRAY_SIZE(mtk_dsp_dl_playback_mix)), + + SND_SOC_DAPM_MIXER("UL_CM0_CH1", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch1_mix, ARRAY_SIZE(memif_ul_cm0_ch1_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH2", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch2_mix, ARRAY_SIZE(memif_ul_cm0_ch2_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH3", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch3_mix, ARRAY_SIZE(memif_ul_cm0_ch3_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH4", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch4_mix, ARRAY_SIZE(memif_ul_cm0_ch4_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH5", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch5_mix, ARRAY_SIZE(memif_ul_cm0_ch5_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH6", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch6_mix, ARRAY_SIZE(memif_ul_cm0_ch6_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH7", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch7_mix, ARRAY_SIZE(memif_ul_cm0_ch7_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH8", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch8_mix, ARRAY_SIZE(memif_ul_cm0_ch8_mix)), + SND_SOC_DAPM_MUX_E("CM0_UL_MUX", SND_SOC_NOPM, 0, 0, + &ul_cm0_mux_control, + ul_cm0_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("UL_CM1_CH1", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch1_mix, ARRAY_SIZE(memif_ul_cm1_ch1_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH2", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch2_mix, ARRAY_SIZE(memif_ul_cm1_ch2_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH3", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch3_mix, ARRAY_SIZE(memif_ul_cm1_ch3_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH4", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch4_mix, ARRAY_SIZE(memif_ul_cm1_ch4_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH5", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch5_mix, ARRAY_SIZE(memif_ul_cm1_ch5_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH6", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch6_mix, ARRAY_SIZE(memif_ul_cm1_ch6_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH7", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch7_mix, ARRAY_SIZE(memif_ul_cm1_ch7_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH8", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch8_mix, ARRAY_SIZE(memif_ul_cm1_ch8_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH9", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch9_mix, ARRAY_SIZE(memif_ul_cm1_ch9_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH10", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch10_mix, ARRAY_SIZE(memif_ul_cm1_ch10_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH11", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch11_mix, ARRAY_SIZE(memif_ul_cm1_ch11_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH12", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch12_mix, ARRAY_SIZE(memif_ul_cm1_ch12_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH13", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch13_mix, ARRAY_SIZE(memif_ul_cm1_ch13_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH14", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch14_mix, ARRAY_SIZE(memif_ul_cm1_ch14_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH15", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch15_mix, ARRAY_SIZE(memif_ul_cm1_ch15_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH16", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch16_mix, ARRAY_SIZE(memif_ul_cm1_ch16_mix)), + SND_SOC_DAPM_MUX("CM1_UL_MUX", SND_SOC_NOPM, 0, 0, + &ul_cm1_mux_control), + + SND_SOC_DAPM_MIXER("UL_CM2_CH1", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch1_mix, ARRAY_SIZE(memif_ul_cm2_ch1_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH2", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch2_mix, ARRAY_SIZE(memif_ul_cm2_ch2_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH3", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch3_mix, ARRAY_SIZE(memif_ul_cm2_ch3_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH4", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch4_mix, ARRAY_SIZE(memif_ul_cm2_ch4_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH5", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch5_mix, ARRAY_SIZE(memif_ul_cm2_ch5_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH6", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch6_mix, ARRAY_SIZE(memif_ul_cm2_ch6_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH7", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch7_mix, ARRAY_SIZE(memif_ul_cm2_ch7_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH8", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch8_mix, ARRAY_SIZE(memif_ul_cm2_ch8_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH9", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch9_mix, ARRAY_SIZE(memif_ul_cm2_ch9_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH10", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch10_mix, ARRAY_SIZE(memif_ul_cm2_ch10_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH11", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch11_mix, ARRAY_SIZE(memif_ul_cm2_ch11_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH12", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch12_mix, ARRAY_SIZE(memif_ul_cm2_ch12_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH13", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch13_mix, ARRAY_SIZE(memif_ul_cm2_ch13_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH14", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch14_mix, ARRAY_SIZE(memif_ul_cm2_ch14_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH15", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch15_mix, ARRAY_SIZE(memif_ul_cm2_ch15_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH16", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch16_mix, ARRAY_SIZE(memif_ul_cm2_ch16_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH17", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch17_mix, ARRAY_SIZE(memif_ul_cm2_ch17_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH18", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch18_mix, ARRAY_SIZE(memif_ul_cm2_ch18_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH19", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch19_mix, ARRAY_SIZE(memif_ul_cm2_ch19_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH20", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch20_mix, ARRAY_SIZE(memif_ul_cm2_ch20_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH21", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch21_mix, ARRAY_SIZE(memif_ul_cm2_ch21_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH22", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch22_mix, ARRAY_SIZE(memif_ul_cm2_ch22_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH23", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch23_mix, ARRAY_SIZE(memif_ul_cm2_ch23_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH24", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch24_mix, ARRAY_SIZE(memif_ul_cm2_ch24_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH25", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch25_mix, ARRAY_SIZE(memif_ul_cm2_ch25_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH26", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch26_mix, ARRAY_SIZE(memif_ul_cm2_ch26_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH27", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch27_mix, ARRAY_SIZE(memif_ul_cm2_ch27_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH28", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch28_mix, ARRAY_SIZE(memif_ul_cm2_ch28_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH29", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch29_mix, ARRAY_SIZE(memif_ul_cm2_ch29_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH30", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch30_mix, ARRAY_SIZE(memif_ul_cm2_ch30_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH31", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch31_mix, ARRAY_SIZE(memif_ul_cm2_ch31_mix)), + SND_SOC_DAPM_MIXER("UL_CM2_CH32", SND_SOC_NOPM, 0, 0, + memif_ul_cm2_ch32_mix, ARRAY_SIZE(memif_ul_cm2_ch32_mix)), + SND_SOC_DAPM_MUX("CM2_UL_MUX", SND_SOC_NOPM, 0, 0, + &ul_cm2_mux_control), + + SND_SOC_DAPM_SUPPLY("CM0_Enable", + AFE_CM0_CON0, AFE_CM0_ON_SFT, 0, + ul_cm0_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("CM1_Enable", + AFE_CM1_CON0, AFE_CM1_ON_SFT, 0, + ul_cm1_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("CM2_Enable", + AFE_CM2_CON0, AFE_CM2_ON_SFT, 0, + ul_cm2_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("SOF_DMA_UL0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SOF_DMA_UL1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SOF_DMA_UL2", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route mt8196_memif_routes[] = { + {"UL0", NULL, "UL0_CH1"}, + {"UL0", NULL, "UL0_CH2"}, + /* Normal record */ + {"UL0_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + /* FM */ + {"UL0_CH1", "CONNSYS_I2S_CH1", "Connsys I2S"}, + {"UL0_CH2", "CONNSYS_I2S_CH2", "Connsys I2S"}, + + {"UL0_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL0_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL0_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL0_CH2", "I2SIN1_CH2", "I2SIN1"}, + + /* SOF Uplink */ + {"SOF_DMA_UL0", NULL, "UL0_CH1"}, + {"SOF_DMA_UL0", NULL, "UL0_CH2"}, + + {"UL1", NULL, "UL1_CH1"}, + {"UL1", NULL, "UL1_CH2"}, + + {"UL1_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL1_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + + {"UL1_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL1_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL1_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL1_CH2", "I2SIN1_CH2", "I2SIN1"}, + {"UL1_CH1", "I2SIN3_CH1", "I2SIN3"}, + {"UL1_CH2", "I2SIN3_CH2", "I2SIN3"}, + {"UL1_CH1", "I2SIN4_CH1", "I2SIN4"}, + {"UL1_CH2", "I2SIN4_CH2", "I2SIN4"}, + {"UL1_CH1", "I2SIN6_CH1", "I2SIN6"}, + {"UL1_CH2", "I2SIN6_CH2", "I2SIN6"}, + {"UL1_CH1", "CONNSYS_I2S_CH1", "Connsys I2S"}, + {"UL1_CH2", "CONNSYS_I2S_CH2", "Connsys I2S"}, + + /* SOF Uplink */ + {"SOF_DMA_UL1", NULL, "UL1_CH1"}, + {"SOF_DMA_UL1", NULL, "UL1_CH2"}, + + {"UL2", NULL, "UL2_CH1"}, + {"UL2", NULL, "UL2_CH2"}, + {"UL2_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL2_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + + /* SOF Uplink */ + {"SOF_DMA_UL2", NULL, "UL2_CH1"}, + {"SOF_DMA_UL2", NULL, "UL2_CH2"}, + + {"UL3", NULL, "UL3_CH1"}, + {"UL3", NULL, "UL3_CH2"}, + + {"UL3_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL3_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL3_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL3_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL3_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL3_CH2", "I2SIN1_CH2", "I2SIN1"}, + {"UL3_CH1", "I2SIN3_CH1", "I2SIN3"}, + {"UL3_CH2", "I2SIN3_CH2", "I2SIN3"}, + {"UL3_CH1", "I2SIN4_CH1", "I2SIN4"}, + {"UL3_CH2", "I2SIN4_CH2", "I2SIN4"}, + + {"UL4", NULL, "UL4_CH1"}, + {"UL4", NULL, "UL4_CH2"}, + {"UL4_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL4_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL4_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL4_CH2", "I2SIN0_CH2", "I2SIN0"}, + + {"UL5", NULL, "UL5_CH1"}, + {"UL5", NULL, "UL5_CH2"}, + + {"UL5_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL5_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL5_CH1", "I2SIN3_CH1", "I2SIN3"}, + {"UL5_CH2", "I2SIN3_CH2", "I2SIN3"}, + + {"UL6", NULL, "UL6_CH1"}, + {"UL6", NULL, "UL6_CH2"}, + {"UL6_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL6_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL6_CH1", "CONNSYS_I2S_CH1", "Connsys I2S"}, + {"UL6_CH2", "CONNSYS_I2S_CH2", "Connsys I2S"}, + + {"UL7", NULL, "UL7_CH1"}, + {"UL7", NULL, "UL7_CH2"}, + {"UL7_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL7_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL7_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL7_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL7_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL7_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL7_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL7_CH1", "CONNSYS_I2S_CH1", "Connsys I2S"}, + {"UL7_CH2", "CONNSYS_I2S_CH2", "Connsys I2S"}, + + {"UL8", NULL, "CM0_UL_MUX"}, + {"CM0_UL_MUX", "CM0_2CH_PATH", "UL8_CH1"}, + {"CM0_UL_MUX", "CM0_2CH_PATH", "UL8_CH2"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH1"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH2"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH3"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH4"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH5"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH6"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH7"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH8"}, + {"UL_CM0_CH1", NULL, "CM0_Enable"}, + {"UL_CM0_CH2", NULL, "CM0_Enable"}, + {"UL_CM0_CH3", NULL, "CM0_Enable"}, + {"UL_CM0_CH4", NULL, "CM0_Enable"}, + {"UL_CM0_CH5", NULL, "CM0_Enable"}, + {"UL_CM0_CH6", NULL, "CM0_Enable"}, + {"UL_CM0_CH7", NULL, "CM0_Enable"}, + {"UL_CM0_CH8", NULL, "CM0_Enable"}, + + /* UL9 */ + {"UL9", NULL, "CM1_UL_MUX"}, + {"CM1_UL_MUX", "CM1_2CH_PATH", "UL9_CH1"}, + {"CM1_UL_MUX", "CM1_2CH_PATH", "UL9_CH2"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH1"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH2"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH3"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH4"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH5"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH6"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH7"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH8"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH9"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH10"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH11"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH12"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH13"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH14"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH15"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH16"}, + + {"UL_CM1_CH1", NULL, "CM1_Enable"}, + {"UL_CM1_CH2", NULL, "CM1_Enable"}, + {"UL_CM1_CH3", NULL, "CM1_Enable"}, + {"UL_CM1_CH4", NULL, "CM1_Enable"}, + {"UL_CM1_CH5", NULL, "CM1_Enable"}, + {"UL_CM1_CH6", NULL, "CM1_Enable"}, + {"UL_CM1_CH7", NULL, "CM1_Enable"}, + {"UL_CM1_CH8", NULL, "CM1_Enable"}, + {"UL_CM1_CH9", NULL, "CM1_Enable"}, + {"UL_CM1_CH10", NULL, "CM1_Enable"}, + {"UL_CM1_CH11", NULL, "CM1_Enable"}, + {"UL_CM1_CH12", NULL, "CM1_Enable"}, + {"UL_CM1_CH13", NULL, "CM1_Enable"}, + {"UL_CM1_CH14", NULL, "CM1_Enable"}, + {"UL_CM1_CH15", NULL, "CM1_Enable"}, + {"UL_CM1_CH16", NULL, "CM1_Enable"}, + + /* UL9 o36o37 <- ADDA */ + {"UL9_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL9_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL9_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL9_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL9_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL9_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL9_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + {"UL10", NULL, "CM2_UL_MUX"}, + {"CM2_UL_MUX", "CM2_2CH_PATH", "UL10_CH1"}, + {"CM2_UL_MUX", "CM2_2CH_PATH", "UL10_CH2"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH1"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH2"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH3"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH4"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH5"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH6"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH7"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH8"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH9"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH10"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH11"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH12"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH13"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH14"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH15"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH16"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH17"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH18"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH19"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH20"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH21"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH22"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH23"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH24"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH25"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH26"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH27"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH28"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH29"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH30"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH31"}, + {"CM2_UL_MUX", "CM2_32CH_PATH", "UL_CM2_CH32"}, + {"UL_CM2_CH1", NULL, "CM2_Enable"}, + {"UL_CM2_CH2", NULL, "CM2_Enable"}, + {"UL_CM2_CH3", NULL, "CM2_Enable"}, + {"UL_CM2_CH4", NULL, "CM2_Enable"}, + {"UL_CM2_CH5", NULL, "CM2_Enable"}, + {"UL_CM2_CH6", NULL, "CM2_Enable"}, + {"UL_CM2_CH7", NULL, "CM2_Enable"}, + {"UL_CM2_CH8", NULL, "CM2_Enable"}, + {"UL_CM2_CH9", NULL, "CM2_Enable"}, + {"UL_CM2_CH10", NULL, "CM2_Enable"}, + {"UL_CM2_CH11", NULL, "CM2_Enable"}, + {"UL_CM2_CH12", NULL, "CM2_Enable"}, + {"UL_CM2_CH13", NULL, "CM2_Enable"}, + {"UL_CM2_CH14", NULL, "CM2_Enable"}, + {"UL_CM2_CH15", NULL, "CM2_Enable"}, + {"UL_CM2_CH16", NULL, "CM2_Enable"}, + {"UL_CM2_CH17", NULL, "CM2_Enable"}, + {"UL_CM2_CH18", NULL, "CM2_Enable"}, + {"UL_CM2_CH19", NULL, "CM2_Enable"}, + {"UL_CM2_CH20", NULL, "CM2_Enable"}, + {"UL_CM2_CH21", NULL, "CM2_Enable"}, + {"UL_CM2_CH22", NULL, "CM2_Enable"}, + {"UL_CM2_CH23", NULL, "CM2_Enable"}, + {"UL_CM2_CH24", NULL, "CM2_Enable"}, + {"UL_CM2_CH25", NULL, "CM2_Enable"}, + {"UL_CM2_CH26", NULL, "CM2_Enable"}, + {"UL_CM2_CH27", NULL, "CM2_Enable"}, + {"UL_CM2_CH28", NULL, "CM2_Enable"}, + {"UL_CM2_CH29", NULL, "CM2_Enable"}, + {"UL_CM2_CH30", NULL, "CM2_Enable"}, + {"UL_CM2_CH31", NULL, "CM2_Enable"}, + {"UL_CM2_CH32", NULL, "CM2_Enable"}, + + /* UL10 o38o39 <- ADDA */ + {"UL10_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL10_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL10_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL10_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL10_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL10_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL10_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + {"UL24", NULL, "UL24_CH1"}, + {"UL24", NULL, "UL24_CH2"}, + {"UL24_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL24_CH1", "I2SIN6_CH1", "I2SIN6"}, + {"UL24_CH2", "I2SIN6_CH2", "I2SIN6"}, + {"UL24_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL24_CH2", "I2SIN0_CH2", "I2SIN0"}, + + {"UL25", NULL, "UL25_CH1"}, + {"UL25", NULL, "UL25_CH2"}, + {"UL25_CH1", "I2SIN6_CH1", "I2SIN6"}, + {"UL25_CH2", "I2SIN6_CH2", "I2SIN6"}, + {"UL25_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL25_CH2", "I2SIN0_CH2", "I2SIN0"}, + + {"UL26", NULL, "UL26_CH1"}, + {"UL26", NULL, "UL26_CH2"}, + {"UL26_CH1", "I2SIN6_CH1", "I2SIN6"}, + {"UL26_CH2", "I2SIN6_CH2", "I2SIN6"}, + {"UL26_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL26_CH2", "I2SIN0_CH2", "I2SIN0"}, + + {"DSP_DL", "DSP_DL0", "DL0"}, + {"DSP_DL", "DSP_DL2", "DL2"}, + {"DSP_DL", "DSP_DL1", "DL1"}, + {"DSP_DL", "DSP_DL6", "DL6"}, + {"DSP_DL", "DSP_DL3", "DL3"}, + {"DSP_DL", "DSP_DL_24CH", "DL_24CH"}, + + {"UL_CM0", NULL, "UL_CM0_CH1"}, + {"UL_CM0", NULL, "UL_CM0_CH2"}, + {"UL_CM0", NULL, "UL_CM0_CH3"}, + {"UL_CM0", NULL, "UL_CM0_CH4"}, + {"UL_CM0", NULL, "UL_CM0_CH5"}, + {"UL_CM0", NULL, "UL_CM0_CH6"}, + {"UL_CM0", NULL, "UL_CM0_CH7"}, + {"UL_CM0", NULL, "UL_CM0_CH8"}, + {"UL_CM0_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM0_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM0_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM0_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM0_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH3", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM0_CH3", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM0_CH3", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH3", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH4", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM0_CH4", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM0_CH4", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM0_CH4", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + {"UL_CM1", NULL, "UL_CM1_CH1"}, + {"UL_CM1", NULL, "UL_CM1_CH2"}, + {"UL_CM1", NULL, "UL_CM1_CH3"}, + {"UL_CM1", NULL, "UL_CM1_CH4"}, + {"UL_CM1", NULL, "UL_CM1_CH5"}, + {"UL_CM1", NULL, "UL_CM1_CH6"}, + {"UL_CM1", NULL, "UL_CM1_CH7"}, + {"UL_CM1", NULL, "UL_CM1_CH8"}, + {"UL_CM1", NULL, "UL_CM1_CH9"}, + {"UL_CM1", NULL, "UL_CM1_CH10"}, + {"UL_CM1", NULL, "UL_CM1_CH11"}, + {"UL_CM1", NULL, "UL_CM1_CH12"}, + {"UL_CM1", NULL, "UL_CM1_CH13"}, + {"UL_CM1", NULL, "UL_CM1_CH14"}, + {"UL_CM1", NULL, "UL_CM1_CH15"}, + {"UL_CM1", NULL, "UL_CM1_CH16"}, + {"UL_CM1_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH1", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH1", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH2", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH3", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH4", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH5", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM1_CH6", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + + + {"UL_CM2", NULL, "UL_CM2_CH1"}, + {"UL_CM2", NULL, "UL_CM2_CH2"}, + {"UL_CM2", NULL, "UL_CM2_CH3"}, + {"UL_CM2", NULL, "UL_CM2_CH4"}, + {"UL_CM2", NULL, "UL_CM2_CH5"}, + {"UL_CM2", NULL, "UL_CM2_CH6"}, + {"UL_CM2", NULL, "UL_CM2_CH7"}, + {"UL_CM2", NULL, "UL_CM2_CH8"}, + {"UL_CM2", NULL, "UL_CM2_CH9"}, + {"UL_CM2", NULL, "UL_CM2_CH10"}, + {"UL_CM2", NULL, "UL_CM2_CH11"}, + {"UL_CM2", NULL, "UL_CM2_CH12"}, + {"UL_CM2", NULL, "UL_CM2_CH13"}, + {"UL_CM2", NULL, "UL_CM2_CH14"}, + {"UL_CM2", NULL, "UL_CM2_CH15"}, + {"UL_CM2", NULL, "UL_CM2_CH16"}, + {"UL_CM2", NULL, "UL_CM2_CH17"}, + {"UL_CM2", NULL, "UL_CM2_CH18"}, + {"UL_CM2", NULL, "UL_CM2_CH19"}, + {"UL_CM2", NULL, "UL_CM2_CH20"}, + {"UL_CM2", NULL, "UL_CM2_CH21"}, + {"UL_CM2", NULL, "UL_CM2_CH22"}, + {"UL_CM2", NULL, "UL_CM2_CH23"}, + {"UL_CM2", NULL, "UL_CM2_CH24"}, + {"UL_CM2", NULL, "UL_CM2_CH25"}, + {"UL_CM2", NULL, "UL_CM2_CH26"}, + {"UL_CM2", NULL, "UL_CM2_CH27"}, + {"UL_CM2", NULL, "UL_CM2_CH28"}, + {"UL_CM2", NULL, "UL_CM2_CH29"}, + {"UL_CM2", NULL, "UL_CM2_CH30"}, + {"UL_CM2", NULL, "UL_CM2_CH31"}, + {"UL_CM2", NULL, "UL_CM2_CH32"}, + {"UL_CM2_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH1", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH1", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH2", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH3", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH4", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH5", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH5", "ADDA_CH56_UL_Mux"}, + {"UL_CM2_CH6", "ADDA_UL_CH6", "ADDA_CH56_UL_Mux"}, +}; + +static const struct mtk_base_memif_data memif_data[MT8196_MEMIF_NUM] = { + [MT8196_MEMIF_DL0] = { + .name = "DL0", + .id = MT8196_MEMIF_DL0, + .reg_ofs_base = AFE_DL0_BASE, + .reg_ofs_cur = AFE_DL0_CUR, + .reg_ofs_end = AFE_DL0_END, + .reg_ofs_base_msb = AFE_DL0_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL0_CUR_MSB, + .reg_ofs_end_msb = AFE_DL0_END_MSB, + .fs_reg = AFE_DL0_CON0, + .fs_shift = DL0_SEL_FS_SFT, + .fs_maskbit = DL0_SEL_FS_MASK, + .mono_reg = AFE_DL0_CON0, + .mono_shift = DL0_MONO_SFT, + .enable_reg = AFE_DL0_CON0, + .enable_shift = DL0_ON_SFT, + .hd_reg = AFE_DL0_CON0, + .hd_mask = DL0_HD_MODE_MASK, + .hd_shift = DL0_HD_MODE_SFT, + .hd_align_reg = AFE_DL0_CON0, + .hd_align_mshift = DL0_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL0_CON0, + .pbuf_mask = DL0_PBUF_SIZE_MASK, + .pbuf_shift = DL0_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL0_CON0, + .minlen_mask = DL0_MINLEN_MASK, + .minlen_shift = DL0_MINLEN_SFT, + .maxlen_reg = AFE_DL0_CON0, + .maxlen_mask = DL0_MAXLEN_MASK, + .maxlen_shift = DL0_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL1] = { + .name = "DL1", + .id = MT8196_MEMIF_DL1, + .reg_ofs_base = AFE_DL1_BASE, + .reg_ofs_cur = AFE_DL1_CUR, + .reg_ofs_end = AFE_DL1_END, + .reg_ofs_base_msb = AFE_DL1_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL1_CUR_MSB, + .reg_ofs_end_msb = AFE_DL1_END_MSB, + .fs_reg = AFE_DL1_CON0, + .fs_shift = DL1_SEL_FS_SFT, + .fs_maskbit = DL1_SEL_FS_MASK, + .mono_reg = AFE_DL1_CON0, + .mono_shift = DL1_MONO_SFT, + .enable_reg = AFE_DL1_CON0, + .enable_shift = DL1_ON_SFT, + .hd_reg = AFE_DL1_CON0, + .hd_mask = DL1_HD_MODE_MASK, + .hd_shift = DL1_HD_MODE_SFT, + .hd_align_reg = AFE_DL1_CON0, + .hd_align_mshift = DL1_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL1_CON0, + .pbuf_mask = DL1_PBUF_SIZE_MASK, + .pbuf_shift = DL1_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL1_CON0, + .minlen_mask = DL1_MINLEN_MASK, + .minlen_shift = DL1_MINLEN_SFT, + .maxlen_reg = AFE_DL1_CON0, + .maxlen_mask = DL1_MAXLEN_MASK, + .maxlen_shift = DL1_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL2] = { + .name = "DL2", + .id = MT8196_MEMIF_DL2, + .reg_ofs_base = AFE_DL2_BASE, + .reg_ofs_cur = AFE_DL2_CUR, + .reg_ofs_end = AFE_DL2_END, + .reg_ofs_base_msb = AFE_DL2_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL2_CUR_MSB, + .reg_ofs_end_msb = AFE_DL2_END_MSB, + .fs_reg = AFE_DL2_CON0, + .fs_shift = DL2_SEL_FS_SFT, + .fs_maskbit = DL2_SEL_FS_MASK, + .mono_reg = AFE_DL2_CON0, + .mono_shift = DL2_MONO_SFT, + .enable_reg = AFE_DL2_CON0, + .enable_shift = DL2_ON_SFT, + .hd_reg = AFE_DL2_CON0, + .hd_mask = DL2_HD_MODE_MASK, + .hd_shift = DL2_HD_MODE_SFT, + .hd_align_reg = AFE_DL2_CON0, + .hd_align_mshift = DL2_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL2_CON0, + .pbuf_mask = DL2_PBUF_SIZE_MASK, + .pbuf_shift = DL2_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL2_CON0, + .minlen_mask = DL2_MINLEN_MASK, + .minlen_shift = DL2_MINLEN_SFT, + .maxlen_reg = AFE_DL2_CON0, + .maxlen_mask = DL2_MAXLEN_MASK, + .maxlen_shift = DL2_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL3] = { + .name = "DL3", + .id = MT8196_MEMIF_DL3, + .reg_ofs_base = AFE_DL3_BASE, + .reg_ofs_cur = AFE_DL3_CUR, + .reg_ofs_end = AFE_DL3_END, + .reg_ofs_base_msb = AFE_DL3_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL3_CUR_MSB, + .reg_ofs_end_msb = AFE_DL3_END_MSB, + .fs_reg = AFE_DL3_CON0, + .fs_shift = DL3_SEL_FS_SFT, + .fs_maskbit = DL3_SEL_FS_MASK, + .mono_reg = AFE_DL3_CON0, + .mono_shift = DL3_MONO_SFT, + .enable_reg = AFE_DL3_CON0, + .enable_shift = DL3_ON_SFT, + .hd_reg = AFE_DL3_CON0, + .hd_mask = DL3_HD_MODE_MASK, + .hd_shift = DL3_HD_MODE_SFT, + .hd_align_reg = AFE_DL3_CON0, + .hd_align_mshift = DL3_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL3_CON0, + .pbuf_mask = DL3_PBUF_SIZE_MASK, + .pbuf_shift = DL3_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL3_CON0, + .minlen_mask = DL3_MINLEN_MASK, + .minlen_shift = DL3_MINLEN_SFT, + .maxlen_reg = AFE_DL3_CON0, + .maxlen_mask = DL3_MAXLEN_MASK, + .maxlen_shift = DL3_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL4] = { + .name = "DL4", + .id = MT8196_MEMIF_DL4, + .reg_ofs_base = AFE_DL4_BASE, + .reg_ofs_cur = AFE_DL4_CUR, + .reg_ofs_end = AFE_DL4_END, + .reg_ofs_base_msb = AFE_DL4_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL4_CUR_MSB, + .reg_ofs_end_msb = AFE_DL4_END_MSB, + .fs_reg = AFE_DL4_CON0, + .fs_shift = DL4_SEL_FS_SFT, + .fs_maskbit = DL4_SEL_FS_MASK, + .mono_reg = AFE_DL4_CON0, + .mono_shift = DL4_MONO_SFT, + .enable_reg = AFE_DL4_CON0, + .enable_shift = DL4_ON_SFT, + .hd_reg = AFE_DL4_CON0, + .hd_mask = DL4_HD_MODE_MASK, + .hd_shift = DL4_HD_MODE_SFT, + .hd_align_reg = AFE_DL4_CON0, + .hd_align_mshift = DL4_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL4_CON0, + .pbuf_mask = DL4_PBUF_SIZE_MASK, + .pbuf_shift = DL4_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL4_CON0, + .minlen_mask = DL4_MINLEN_MASK, + .minlen_shift = DL4_MINLEN_SFT, + .maxlen_reg = AFE_DL4_CON0, + .maxlen_mask = DL4_MAXLEN_MASK, + .maxlen_shift = DL4_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL5] = { + .name = "DL5", + .id = MT8196_MEMIF_DL5, + .reg_ofs_base = AFE_DL5_BASE, + .reg_ofs_cur = AFE_DL5_CUR, + .reg_ofs_end = AFE_DL5_END, + .reg_ofs_base_msb = AFE_DL5_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL5_CUR_MSB, + .reg_ofs_end_msb = AFE_DL5_END_MSB, + .fs_reg = AFE_DL5_CON0, + .fs_shift = DL5_SEL_FS_SFT, + .fs_maskbit = DL5_SEL_FS_MASK, + .mono_reg = AFE_DL5_CON0, + .mono_shift = DL5_MONO_SFT, + .enable_reg = AFE_DL5_CON0, + .enable_shift = DL5_ON_SFT, + .hd_reg = AFE_DL5_CON0, + .hd_mask = DL5_HD_MODE_MASK, + .hd_shift = DL5_HD_MODE_SFT, + .hd_align_reg = AFE_DL5_CON0, + .hd_align_mshift = DL5_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL5_CON0, + .pbuf_mask = DL5_PBUF_SIZE_MASK, + .pbuf_shift = DL5_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL5_CON0, + .minlen_mask = DL5_MINLEN_MASK, + .minlen_shift = DL5_MINLEN_SFT, + .maxlen_reg = AFE_DL5_CON0, + .maxlen_mask = DL5_MAXLEN_MASK, + .maxlen_shift = DL5_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL6] = { + .name = "DL6", + .id = MT8196_MEMIF_DL6, + .reg_ofs_base = AFE_DL6_BASE, + .reg_ofs_cur = AFE_DL6_CUR, + .reg_ofs_end = AFE_DL6_END, + .reg_ofs_base_msb = AFE_DL6_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL6_CUR_MSB, + .reg_ofs_end_msb = AFE_DL6_END_MSB, + .fs_reg = AFE_DL6_CON0, + .fs_shift = DL6_SEL_FS_SFT, + .fs_maskbit = DL6_SEL_FS_MASK, + .mono_reg = AFE_DL6_CON0, + .mono_shift = DL6_MONO_SFT, + .enable_reg = AFE_DL6_CON0, + .enable_shift = DL6_ON_SFT, + .hd_reg = AFE_DL6_CON0, + .hd_mask = DL6_HD_MODE_MASK, + .hd_shift = DL6_HD_MODE_SFT, + .hd_align_reg = AFE_DL6_CON0, + .hd_align_mshift = DL6_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL6_CON0, + .pbuf_mask = DL6_PBUF_SIZE_MASK, + .pbuf_shift = DL6_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL6_CON0, + .minlen_mask = DL6_MINLEN_MASK, + .minlen_shift = DL6_MINLEN_SFT, + .maxlen_reg = AFE_DL6_CON0, + .maxlen_mask = DL6_MAXLEN_MASK, + .maxlen_shift = DL6_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL7] = { + .name = "DL7", + .id = MT8196_MEMIF_DL7, + .reg_ofs_base = AFE_DL7_BASE, + .reg_ofs_cur = AFE_DL7_CUR, + .reg_ofs_end = AFE_DL7_END, + .reg_ofs_base_msb = AFE_DL7_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL7_CUR_MSB, + .reg_ofs_end_msb = AFE_DL7_END_MSB, + .fs_reg = AFE_DL7_CON0, + .fs_shift = DL7_SEL_FS_SFT, + .fs_maskbit = DL7_SEL_FS_MASK, + .mono_reg = AFE_DL7_CON0, + .mono_shift = DL7_MONO_SFT, + .enable_reg = AFE_DL7_CON0, + .enable_shift = DL7_ON_SFT, + .hd_reg = AFE_DL7_CON0, + .hd_mask = DL7_HD_MODE_MASK, + .hd_shift = DL7_HD_MODE_SFT, + .hd_align_reg = AFE_DL7_CON0, + .hd_align_mshift = DL7_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL7_CON0, + .pbuf_mask = DL7_PBUF_SIZE_MASK, + .pbuf_shift = DL7_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL7_CON0, + .minlen_mask = DL7_MINLEN_MASK, + .minlen_shift = DL7_MINLEN_SFT, + .maxlen_reg = AFE_DL7_CON0, + .maxlen_mask = DL7_MAXLEN_MASK, + .maxlen_shift = DL7_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL8] = { + .name = "DL8", + .id = MT8196_MEMIF_DL8, + .reg_ofs_base = AFE_DL8_BASE, + .reg_ofs_cur = AFE_DL8_CUR, + .reg_ofs_end = AFE_DL8_END, + .reg_ofs_base_msb = AFE_DL8_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL8_CUR_MSB, + .reg_ofs_end_msb = AFE_DL8_END_MSB, + .fs_reg = AFE_DL8_CON0, + .fs_shift = DL8_SEL_FS_SFT, + .fs_maskbit = DL8_SEL_FS_MASK, + .mono_reg = AFE_DL8_CON0, + .mono_shift = DL8_MONO_SFT, + .enable_reg = AFE_DL8_CON0, + .enable_shift = DL8_ON_SFT, + .hd_reg = AFE_DL8_CON0, + .hd_mask = DL8_HD_MODE_MASK, + .hd_shift = DL8_HD_MODE_SFT, + .hd_align_reg = AFE_DL8_CON0, + .hd_align_mshift = DL8_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL8_CON0, + .pbuf_mask = DL8_PBUF_SIZE_MASK, + .pbuf_shift = DL8_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL8_CON0, + .minlen_mask = DL8_MINLEN_MASK, + .minlen_shift = DL8_MINLEN_SFT, + .maxlen_reg = AFE_DL8_CON0, + .maxlen_mask = DL8_MAXLEN_MASK, + .maxlen_shift = DL8_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL23] = { + .name = "DL23", + .id = MT8196_MEMIF_DL23, + .reg_ofs_base = AFE_DL23_BASE, + .reg_ofs_cur = AFE_DL23_CUR, + .reg_ofs_end = AFE_DL23_END, + .reg_ofs_base_msb = AFE_DL23_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL23_CUR_MSB, + .reg_ofs_end_msb = AFE_DL23_END_MSB, + .fs_reg = AFE_DL23_CON0, + .fs_shift = DL23_SEL_FS_SFT, + .fs_maskbit = DL23_SEL_FS_MASK, + .mono_reg = AFE_DL23_CON0, + .mono_shift = DL23_MONO_SFT, + .enable_reg = AFE_DL23_CON0, + .enable_shift = DL23_ON_SFT, + .hd_reg = AFE_DL23_CON0, + .hd_mask = DL23_HD_MODE_MASK, + .hd_shift = DL23_HD_MODE_SFT, + .hd_align_reg = AFE_DL23_CON0, + .hd_align_mshift = DL23_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL23_CON0, + .pbuf_mask = DL23_PBUF_SIZE_MASK, + .pbuf_shift = DL23_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL23_CON0, + .minlen_mask = DL23_MINLEN_MASK, + .minlen_shift = DL23_MINLEN_SFT, + .maxlen_reg = AFE_DL23_CON0, + .maxlen_mask = DL23_MAXLEN_MASK, + .maxlen_shift = DL23_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL24] = { + .name = "DL24", + .id = MT8196_MEMIF_DL24, + .reg_ofs_base = AFE_DL24_BASE, + .reg_ofs_cur = AFE_DL24_CUR, + .reg_ofs_end = AFE_DL24_END, + .reg_ofs_base_msb = AFE_DL24_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL24_CUR_MSB, + .reg_ofs_end_msb = AFE_DL24_END_MSB, + .fs_reg = AFE_DL24_CON0, + .fs_shift = DL24_SEL_FS_SFT, + .fs_maskbit = DL24_SEL_FS_MASK, + .mono_reg = AFE_DL24_CON0, + .mono_shift = DL24_MONO_SFT, + .enable_reg = AFE_DL24_CON0, + .enable_shift = DL24_ON_SFT, + .hd_reg = AFE_DL24_CON0, + .hd_mask = DL24_HD_MODE_MASK, + .hd_shift = DL24_HD_MODE_SFT, + .hd_align_reg = AFE_DL24_CON0, + .hd_align_mshift = DL24_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL24_CON0, + .pbuf_mask = DL24_PBUF_SIZE_MASK, + .pbuf_shift = DL24_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL24_CON0, + .minlen_mask = DL24_MINLEN_MASK, + .minlen_shift = DL24_MINLEN_SFT, + .maxlen_reg = AFE_DL24_CON0, + .maxlen_mask = DL24_MAXLEN_MASK, + .maxlen_shift = DL24_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL25] = { + .name = "DL25", + .id = MT8196_MEMIF_DL25, + .reg_ofs_base = AFE_DL25_BASE, + .reg_ofs_cur = AFE_DL25_CUR, + .reg_ofs_end = AFE_DL25_END, + .reg_ofs_base_msb = AFE_DL25_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL25_CUR_MSB, + .reg_ofs_end_msb = AFE_DL25_END_MSB, + .fs_reg = AFE_DL25_CON0, + .fs_shift = DL25_SEL_FS_SFT, + .fs_maskbit = DL25_SEL_FS_MASK, + .mono_reg = AFE_DL25_CON0, + .mono_shift = DL25_MONO_SFT, + .enable_reg = AFE_DL25_CON0, + .enable_shift = DL25_ON_SFT, + .hd_reg = AFE_DL25_CON0, + .hd_mask = DL25_HD_MODE_MASK, + .hd_shift = DL25_HD_MODE_SFT, + .hd_align_reg = AFE_DL25_CON0, + .hd_align_mshift = DL25_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL25_CON0, + .pbuf_mask = DL25_PBUF_SIZE_MASK, + .pbuf_shift = DL25_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL25_CON0, + .minlen_mask = DL25_MINLEN_MASK, + .minlen_shift = DL25_MINLEN_SFT, + .maxlen_reg = AFE_DL25_CON0, + .maxlen_mask = DL25_MAXLEN_MASK, + .maxlen_shift = DL25_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL26] = { + .name = "DL26", + .id = MT8196_MEMIF_DL26, + .reg_ofs_base = AFE_DL26_BASE, + .reg_ofs_cur = AFE_DL26_CUR, + .reg_ofs_end = AFE_DL26_END, + .reg_ofs_base_msb = AFE_DL26_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL26_CUR_MSB, + .reg_ofs_end_msb = AFE_DL26_END_MSB, + .fs_reg = AFE_DL26_CON0, + .fs_shift = DL26_SEL_FS_SFT, + .fs_maskbit = DL26_SEL_FS_MASK, + .mono_reg = AFE_DL26_CON0, + .mono_shift = DL26_MONO_SFT, + .enable_reg = AFE_DL26_CON0, + .enable_shift = DL26_ON_SFT, + .hd_reg = AFE_DL26_CON0, + .hd_mask = DL26_HD_MODE_MASK, + .hd_shift = DL26_HD_MODE_SFT, + .hd_align_reg = AFE_DL26_CON0, + .hd_align_mshift = DL26_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL26_CON0, + .pbuf_mask = DL26_PBUF_SIZE_MASK, + .pbuf_shift = DL26_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL26_CON0, + .minlen_mask = DL26_MINLEN_MASK, + .minlen_shift = DL26_MINLEN_SFT, + .maxlen_reg = AFE_DL26_CON0, + .maxlen_mask = DL26_MAXLEN_MASK, + .maxlen_shift = DL26_MAXLEN_SFT, + }, + [MT8196_MEMIF_DL_4CH] = { + .name = "DL_4CH", + .id = MT8196_MEMIF_DL_4CH, + .reg_ofs_base = AFE_DL_4CH_BASE, + .reg_ofs_cur = AFE_DL_4CH_CUR, + .reg_ofs_end = AFE_DL_4CH_END, + .reg_ofs_base_msb = AFE_DL_4CH_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL_4CH_CUR_MSB, + .reg_ofs_end_msb = AFE_DL_4CH_END_MSB, + .fs_reg = AFE_DL_4CH_CON0, + .fs_shift = DL_4CH_SEL_FS_SFT, + .fs_maskbit = DL_4CH_SEL_FS_MASK, + .mono_reg = -1, + .mono_shift = -1, + .enable_reg = AFE_DL_4CH_CON0, + .enable_shift = DL_4CH_ON_SFT, + .hd_reg = AFE_DL_4CH_CON0, + .hd_mask = DL_4CH_HD_MODE_MASK, + .hd_shift = DL_4CH_HD_MODE_SFT, + .hd_align_reg = AFE_DL_4CH_CON0, + .hd_align_mshift = DL_4CH_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL_4CH_CON0, + .pbuf_mask = DL_4CH_PBUF_SIZE_MASK, + .pbuf_shift = DL_4CH_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL_4CH_CON0, + .minlen_mask = DL_4CH_MINLEN_MASK, + .minlen_shift = DL_4CH_MINLEN_SFT, + .maxlen_reg = AFE_DL_4CH_CON0, + .maxlen_mask = DL_4CH_MAXLEN_MASK, + .maxlen_shift = DL_4CH_MAXLEN_SFT, + .ch_num_reg = AFE_DL_4CH_CON0, + .ch_num_maskbit = DL_4CH_NUM_MASK, + .ch_num_shift = DL_4CH_NUM_SFT, + }, + [MT8196_MEMIF_DL_24CH] = { + .name = "DL_24CH", + .id = MT8196_MEMIF_DL_24CH, + .reg_ofs_base = AFE_DL_24CH_BASE, + .reg_ofs_cur = AFE_DL_24CH_CUR, + .reg_ofs_end = AFE_DL_24CH_END, + .reg_ofs_base_msb = AFE_DL_24CH_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL_24CH_CUR_MSB, + .reg_ofs_end_msb = AFE_DL_24CH_END_MSB, + .fs_reg = AFE_DL_24CH_CON0, + .fs_shift = DL_24CH_SEL_FS_SFT, + .fs_maskbit = DL_24CH_SEL_FS_MASK, + .mono_reg = -1, + .mono_shift = -1, + .enable_reg = AFE_DL_24CH_CON0, + .enable_shift = DL_24CH_ON_SFT, + .hd_reg = AFE_DL_24CH_CON0, + .hd_mask = DL_24CH_HD_MODE_MASK, + .hd_shift = DL_24CH_HD_MODE_SFT, + .hd_align_reg = AFE_DL_24CH_CON0, + .hd_align_mshift = DL_24CH_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_DL_24CH_CON0, + .pbuf_mask = DL_24CH_PBUF_SIZE_MASK, + .pbuf_shift = DL_24CH_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL_24CH_CON0, + .minlen_mask = DL_24CH_MINLEN_MASK, + .minlen_shift = DL_24CH_MINLEN_SFT, + .maxlen_reg = AFE_DL_24CH_CON0, + .maxlen_mask = DL_24CH_MAXLEN_MASK, + .maxlen_shift = DL_24CH_MAXLEN_SFT, + .ch_num_reg = AFE_DL_24CH_CON0, + .ch_num_maskbit = DL_24CH_NUM_MASK, + .ch_num_shift = DL_24CH_NUM_SFT, + }, + [MT8196_MEMIF_VUL0] = { + .name = "VUL0", + .id = MT8196_MEMIF_VUL0, + .reg_ofs_base = AFE_VUL0_BASE, + .reg_ofs_cur = AFE_VUL0_CUR, + .reg_ofs_end = AFE_VUL0_END, + .reg_ofs_base_msb = AFE_VUL0_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL0_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL0_END_MSB, + .fs_reg = AFE_VUL0_CON0, + .fs_shift = VUL0_SEL_FS_SFT, + .fs_maskbit = VUL0_SEL_FS_MASK, + .mono_reg = AFE_VUL0_CON0, + .mono_shift = VUL0_MONO_SFT, + .enable_reg = AFE_VUL0_CON0, + .enable_shift = VUL0_ON_SFT, + .hd_reg = AFE_VUL0_CON0, + .hd_mask = VUL0_HD_MODE_MASK, + .hd_shift = VUL0_HD_MODE_SFT, + .hd_align_reg = AFE_VUL0_CON0, + .hd_align_mshift = VUL0_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL1] = { + .name = "VUL1", + .id = MT8196_MEMIF_VUL1, + .reg_ofs_base = AFE_VUL1_BASE, + .reg_ofs_cur = AFE_VUL1_CUR, + .reg_ofs_end = AFE_VUL1_END, + .reg_ofs_base_msb = AFE_VUL1_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL1_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL1_END_MSB, + .fs_reg = AFE_VUL1_CON0, + .fs_shift = VUL1_SEL_FS_SFT, + .fs_maskbit = VUL1_SEL_FS_MASK, + .mono_reg = AFE_VUL1_CON0, + .mono_shift = VUL1_MONO_SFT, + .enable_reg = AFE_VUL1_CON0, + .enable_shift = VUL1_ON_SFT, + .hd_reg = AFE_VUL1_CON0, + .hd_mask = VUL1_HD_MODE_MASK, + .hd_shift = VUL1_HD_MODE_SFT, + .hd_align_reg = AFE_VUL1_CON0, + .hd_align_mshift = VUL1_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL2] = { + .name = "VUL2", + .id = MT8196_MEMIF_VUL2, + .reg_ofs_base = AFE_VUL2_BASE, + .reg_ofs_cur = AFE_VUL2_CUR, + .reg_ofs_end = AFE_VUL2_END, + .reg_ofs_base_msb = AFE_VUL2_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL2_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL2_END_MSB, + .fs_reg = AFE_VUL2_CON0, + .fs_shift = VUL2_SEL_FS_SFT, + .fs_maskbit = VUL2_SEL_FS_MASK, + .mono_reg = AFE_VUL2_CON0, + .mono_shift = VUL2_MONO_SFT, + .enable_reg = AFE_VUL2_CON0, + .enable_shift = VUL2_ON_SFT, + .hd_reg = AFE_VUL2_CON0, + .hd_mask = VUL2_HD_MODE_MASK, + .hd_shift = VUL2_HD_MODE_SFT, + .hd_align_reg = AFE_VUL2_CON0, + .hd_align_mshift = VUL2_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL3] = { + .name = "VUL3", + .id = MT8196_MEMIF_VUL3, + .reg_ofs_base = AFE_VUL3_BASE, + .reg_ofs_cur = AFE_VUL3_CUR, + .reg_ofs_end = AFE_VUL3_END, + .reg_ofs_base_msb = AFE_VUL3_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL3_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL3_END_MSB, + .fs_reg = AFE_VUL3_CON0, + .fs_shift = VUL3_SEL_FS_SFT, + .fs_maskbit = VUL3_SEL_FS_MASK, + .mono_reg = AFE_VUL3_CON0, + .mono_shift = VUL3_MONO_SFT, + .enable_reg = AFE_VUL3_CON0, + .enable_shift = VUL3_ON_SFT, + .hd_reg = AFE_VUL3_CON0, + .hd_mask = VUL3_HD_MODE_MASK, + .hd_shift = VUL3_HD_MODE_SFT, + .hd_align_reg = AFE_VUL3_CON0, + .hd_align_mshift = VUL3_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL4] = { + .name = "VUL4", + .id = MT8196_MEMIF_VUL4, + .reg_ofs_base = AFE_VUL4_BASE, + .reg_ofs_cur = AFE_VUL4_CUR, + .reg_ofs_end = AFE_VUL4_END, + .reg_ofs_base_msb = AFE_VUL4_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL4_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL4_END_MSB, + .fs_reg = AFE_VUL4_CON0, + .fs_shift = VUL4_SEL_FS_SFT, + .fs_maskbit = VUL4_SEL_FS_MASK, + .mono_reg = AFE_VUL4_CON0, + .mono_shift = VUL4_MONO_SFT, + .enable_reg = AFE_VUL4_CON0, + .enable_shift = VUL4_ON_SFT, + .hd_reg = AFE_VUL4_CON0, + .hd_mask = VUL4_HD_MODE_MASK, + .hd_shift = VUL4_HD_MODE_SFT, + .hd_align_reg = AFE_VUL4_CON0, + .hd_align_mshift = VUL4_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL5] = { + .name = "VUL5", + .id = MT8196_MEMIF_VUL5, + .reg_ofs_base = AFE_VUL5_BASE, + .reg_ofs_cur = AFE_VUL5_CUR, + .reg_ofs_end = AFE_VUL5_END, + .reg_ofs_base_msb = AFE_VUL5_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL5_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL5_END_MSB, + .fs_reg = AFE_VUL5_CON0, + .fs_shift = VUL5_SEL_FS_SFT, + .fs_maskbit = VUL5_SEL_FS_MASK, + .mono_reg = AFE_VUL5_CON0, + .mono_shift = VUL5_MONO_SFT, + .enable_reg = AFE_VUL5_CON0, + .enable_shift = VUL5_ON_SFT, + .hd_reg = AFE_VUL5_CON0, + .hd_mask = VUL5_HD_MODE_MASK, + .hd_shift = VUL5_HD_MODE_SFT, + .hd_align_reg = AFE_VUL5_CON0, + .hd_align_mshift = VUL5_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL6] = { + .name = "VUL6", + .id = MT8196_MEMIF_VUL6, + .reg_ofs_base = AFE_VUL6_BASE, + .reg_ofs_cur = AFE_VUL6_CUR, + .reg_ofs_end = AFE_VUL6_END, + .reg_ofs_base_msb = AFE_VUL6_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL6_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL6_END_MSB, + .fs_reg = AFE_VUL6_CON0, + .fs_shift = VUL6_SEL_FS_SFT, + .fs_maskbit = VUL6_SEL_FS_MASK, + .mono_reg = AFE_VUL6_CON0, + .mono_shift = VUL6_MONO_SFT, + .enable_reg = AFE_VUL6_CON0, + .enable_shift = VUL6_ON_SFT, + .hd_reg = AFE_VUL6_CON0, + .hd_mask = VUL6_HD_MODE_MASK, + .hd_shift = VUL6_HD_MODE_SFT, + .hd_align_reg = AFE_VUL6_CON0, + .hd_align_mshift = VUL6_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL7] = { + .name = "VUL7", + .id = MT8196_MEMIF_VUL7, + .reg_ofs_base = AFE_VUL7_BASE, + .reg_ofs_cur = AFE_VUL7_CUR, + .reg_ofs_end = AFE_VUL7_END, + .reg_ofs_base_msb = AFE_VUL7_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL7_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL7_END_MSB, + .fs_reg = AFE_VUL7_CON0, + .fs_shift = VUL7_SEL_FS_SFT, + .fs_maskbit = VUL7_SEL_FS_MASK, + .mono_reg = AFE_VUL7_CON0, + .mono_shift = VUL7_MONO_SFT, + .enable_reg = AFE_VUL7_CON0, + .enable_shift = VUL7_ON_SFT, + .hd_reg = AFE_VUL7_CON0, + .hd_mask = VUL7_HD_MODE_MASK, + .hd_shift = VUL7_HD_MODE_SFT, + .hd_align_reg = AFE_VUL7_CON0, + .hd_align_mshift = VUL7_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL8] = { + .name = "VUL8", + .id = MT8196_MEMIF_VUL8, + .reg_ofs_base = AFE_VUL8_BASE, + .reg_ofs_cur = AFE_VUL8_CUR, + .reg_ofs_end = AFE_VUL8_END, + .reg_ofs_base_msb = AFE_VUL8_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL8_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL8_END_MSB, + .fs_reg = AFE_VUL8_CON0, + .fs_shift = VUL8_SEL_FS_SFT, + .fs_maskbit = VUL8_SEL_FS_MASK, + .mono_reg = AFE_VUL8_CON0, + .mono_shift = VUL8_MONO_SFT, + .enable_reg = AFE_VUL8_CON0, + .enable_shift = VUL8_ON_SFT, + .hd_reg = AFE_VUL8_CON0, + .hd_mask = VUL8_HD_MODE_MASK, + .hd_shift = VUL8_HD_MODE_SFT, + .hd_align_reg = AFE_VUL8_CON0, + .hd_align_mshift = VUL8_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL9] = { + .name = "VUL9", + .id = MT8196_MEMIF_VUL9, + .reg_ofs_base = AFE_VUL9_BASE, + .reg_ofs_cur = AFE_VUL9_CUR, + .reg_ofs_end = AFE_VUL9_END, + .reg_ofs_base_msb = AFE_VUL9_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL9_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL9_END_MSB, + .fs_reg = AFE_VUL9_CON0, + .fs_shift = VUL9_SEL_FS_SFT, + .fs_maskbit = VUL9_SEL_FS_MASK, + .mono_reg = AFE_VUL9_CON0, + .mono_shift = VUL9_MONO_SFT, + .enable_reg = AFE_VUL9_CON0, + .enable_shift = VUL9_ON_SFT, + .hd_reg = AFE_VUL9_CON0, + .hd_mask = VUL9_HD_MODE_MASK, + .hd_shift = VUL9_HD_MODE_SFT, + .hd_align_reg = AFE_VUL9_CON0, + .hd_align_mshift = VUL9_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL10] = { + .name = "VUL10", + .id = MT8196_MEMIF_VUL10, + .reg_ofs_base = AFE_VUL10_BASE, + .reg_ofs_cur = AFE_VUL10_CUR, + .reg_ofs_end = AFE_VUL10_END, + .reg_ofs_base_msb = AFE_VUL10_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL10_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL10_END_MSB, + .fs_reg = AFE_VUL10_CON0, + .fs_shift = VUL10_SEL_FS_SFT, + .fs_maskbit = VUL10_SEL_FS_MASK, + .mono_reg = AFE_VUL10_CON0, + .mono_shift = VUL10_MONO_SFT, + .enable_reg = AFE_VUL10_CON0, + .enable_shift = VUL10_ON_SFT, + .hd_reg = AFE_VUL10_CON0, + .hd_mask = VUL10_HD_MODE_MASK, + .hd_shift = VUL10_HD_MODE_SFT, + .hd_align_reg = AFE_VUL10_CON0, + .hd_align_mshift = VUL10_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL24] = { + .name = "VUL24", + .id = MT8196_MEMIF_VUL24, + .reg_ofs_base = AFE_VUL24_BASE, + .reg_ofs_cur = AFE_VUL24_CUR, + .reg_ofs_end = AFE_VUL24_END, + .reg_ofs_base_msb = AFE_VUL24_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL24_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL24_END_MSB, + .fs_reg = AFE_VUL24_CON0, + .fs_shift = VUL24_SEL_FS_SFT, + .fs_maskbit = VUL24_SEL_FS_MASK, + .mono_reg = AFE_VUL24_CON0, + .mono_shift = VUL24_MONO_SFT, + .enable_reg = AFE_VUL24_CON0, + .enable_shift = VUL24_ON_SFT, + .hd_reg = AFE_VUL24_CON0, + .hd_mask = VUL24_HD_MODE_MASK, + .hd_shift = VUL24_HD_MODE_SFT, + .hd_align_reg = AFE_VUL24_CON0, + .hd_align_mshift = VUL24_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .out_on_use_reg = AFE_VUL24_CON0, + .out_on_use_mask = OUT_ON_USE_VUL24_MASK, + .out_on_use_shift = OUT_ON_USE_VUL24_SFT, + }, + [MT8196_MEMIF_VUL25] = { + .name = "VUL25", + .id = MT8196_MEMIF_VUL25, + .reg_ofs_base = AFE_VUL25_BASE, + .reg_ofs_cur = AFE_VUL25_CUR, + .reg_ofs_end = AFE_VUL25_END, + .reg_ofs_base_msb = AFE_VUL25_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL25_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL25_END_MSB, + .fs_reg = AFE_VUL25_CON0, + .fs_shift = VUL25_SEL_FS_SFT, + .fs_maskbit = VUL25_SEL_FS_MASK, + .mono_reg = AFE_VUL25_CON0, + .mono_shift = VUL25_MONO_SFT, + .enable_reg = AFE_VUL25_CON0, + .enable_shift = VUL25_ON_SFT, + .hd_reg = AFE_VUL25_CON0, + .hd_mask = VUL25_HD_MODE_MASK, + .hd_shift = VUL25_HD_MODE_SFT, + .hd_align_reg = AFE_VUL25_CON0, + .hd_align_mshift = VUL25_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .out_on_use_reg = AFE_VUL25_CON0, + .out_on_use_mask = OUT_ON_USE_VUL25_MASK, + .out_on_use_shift = OUT_ON_USE_VUL25_SFT, + }, + [MT8196_MEMIF_VUL26] = { + .name = "VUL26", + .id = MT8196_MEMIF_VUL26, + .reg_ofs_base = AFE_VUL26_BASE, + .reg_ofs_cur = AFE_VUL26_CUR, + .reg_ofs_end = AFE_VUL26_END, + .reg_ofs_base_msb = AFE_VUL26_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL26_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL26_END_MSB, + .fs_reg = AFE_VUL26_CON0, + .fs_shift = VUL26_SEL_FS_SFT, + .fs_maskbit = VUL26_SEL_FS_MASK, + .mono_reg = AFE_VUL26_CON0, + .mono_shift = VUL26_MONO_SFT, + .enable_reg = AFE_VUL26_CON0, + .enable_shift = VUL26_ON_SFT, + .hd_reg = AFE_VUL26_CON0, + .hd_mask = VUL26_HD_MODE_MASK, + .hd_shift = VUL26_HD_MODE_SFT, + .hd_align_reg = AFE_VUL26_CON0, + .hd_align_mshift = VUL26_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .out_on_use_reg = AFE_VUL26_CON0, + .out_on_use_mask = OUT_ON_USE_VUL26_MASK, + .out_on_use_shift = OUT_ON_USE_VUL26_SFT, + }, + [MT8196_MEMIF_VUL_CM0] = { + .name = "VUL_CM0", + .id = MT8196_MEMIF_VUL_CM0, + .reg_ofs_base = AFE_VUL_CM0_BASE, + .reg_ofs_cur = AFE_VUL_CM0_CUR, + .reg_ofs_end = AFE_VUL_CM0_END, + .reg_ofs_base_msb = AFE_VUL_CM0_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL_CM0_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL_CM0_END_MSB, + .enable_reg = AFE_VUL_CM0_CON0, + .enable_shift = VUL_CM0_ON_SFT, + .hd_reg = AFE_VUL_CM0_CON0, + .hd_mask = VUL_CM0_HD_MODE_MASK, + .hd_shift = VUL_CM0_HD_MODE_SFT, + .hd_align_reg = AFE_VUL_CM0_CON0, + .hd_align_mshift = VUL_CM0_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL_CM1] = { + .name = "VUL_CM1", + .id = MT8196_MEMIF_VUL_CM1, + .reg_ofs_base = AFE_VUL_CM1_BASE, + .reg_ofs_cur = AFE_VUL_CM1_CUR, + .reg_ofs_end = AFE_VUL_CM1_END, + .reg_ofs_base_msb = AFE_VUL_CM1_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL_CM1_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL_CM1_END_MSB, + .enable_reg = AFE_VUL_CM1_CON0, + .enable_shift = VUL_CM1_ON_SFT, + .hd_reg = AFE_VUL_CM1_CON0, + .hd_mask = VUL_CM1_HD_MODE_MASK, + .hd_shift = VUL_CM1_HD_MODE_SFT, + .hd_align_reg = AFE_VUL_CM1_CON0, + .hd_align_mshift = VUL_CM1_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_VUL_CM2] = { + .name = "VUL_CM2", + .id = MT8196_MEMIF_VUL_CM2, + .reg_ofs_base = AFE_VUL_CM2_BASE, + .reg_ofs_cur = AFE_VUL_CM2_CUR, + .reg_ofs_end = AFE_VUL_CM2_END, + .reg_ofs_base_msb = AFE_VUL_CM2_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL_CM2_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL_CM2_END_MSB, + .enable_reg = AFE_VUL_CM2_CON0, + .enable_shift = VUL_CM2_ON_SFT, + .hd_reg = AFE_VUL_CM2_CON0, + .hd_mask = VUL_CM2_HD_MODE_MASK, + .hd_shift = VUL_CM2_HD_MODE_SFT, + .hd_align_reg = AFE_VUL_CM2_CON0, + .hd_align_mshift = VUL_CM2_HALIGN_SFT, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN0] = { + .name = "ETDM_IN0", + .id = MT8196_MEMIF_ETDM_IN0, + .reg_ofs_base = AFE_ETDM_IN0_BASE, + .reg_ofs_cur = AFE_ETDM_IN0_CUR, + .reg_ofs_end = AFE_ETDM_IN0_END, + .reg_ofs_base_msb = AFE_ETDM_IN0_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN0_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN0_END_MSB, + .fs_reg = ETDM_IN0_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN0_CON0, + .enable_shift = ETDM_IN0_ON_SFT, + .hd_reg = AFE_ETDM_IN0_CON0, + .hd_mask = ETDM_IN0_HD_MODE_MASK, + .hd_shift = ETDM_IN0_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN0_CON0, + .hd_align_mshift = ETDM_IN0_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN1] = { + .name = "ETDM_IN1", + .id = MT8196_MEMIF_ETDM_IN1, + .reg_ofs_base = AFE_ETDM_IN1_BASE, + .reg_ofs_cur = AFE_ETDM_IN1_CUR, + .reg_ofs_end = AFE_ETDM_IN1_END, + .reg_ofs_base_msb = AFE_ETDM_IN1_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN1_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN1_END_MSB, + .fs_reg = ETDM_IN1_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN1_CON0, + .enable_shift = ETDM_IN1_ON_SFT, + .hd_reg = AFE_ETDM_IN1_CON0, + .hd_mask = ETDM_IN1_HD_MODE_MASK, + .hd_shift = ETDM_IN1_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN1_CON0, + .hd_align_mshift = ETDM_IN1_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN2] = { + .name = "ETDM_IN2", + .id = MT8196_MEMIF_ETDM_IN2, + .reg_ofs_base = AFE_ETDM_IN2_BASE, + .reg_ofs_cur = AFE_ETDM_IN2_CUR, + .reg_ofs_end = AFE_ETDM_IN2_END, + .reg_ofs_base_msb = AFE_ETDM_IN2_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN2_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN2_END_MSB, + .fs_reg = ETDM_IN2_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN2_CON0, + .enable_shift = ETDM_IN2_ON_SFT, + .hd_reg = AFE_ETDM_IN2_CON0, + .hd_mask = ETDM_IN2_HD_MODE_MASK, + .hd_shift = ETDM_IN2_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN2_CON0, + .hd_align_mshift = ETDM_IN2_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN3] = { + .name = "ETDM_IN3", + .id = MT8196_MEMIF_ETDM_IN3, + .reg_ofs_base = AFE_ETDM_IN3_BASE, + .reg_ofs_cur = AFE_ETDM_IN3_CUR, + .reg_ofs_end = AFE_ETDM_IN3_END, + .reg_ofs_base_msb = AFE_ETDM_IN3_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN3_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN3_END_MSB, + .fs_reg = ETDM_IN3_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN3_CON0, + .enable_shift = ETDM_IN3_ON_SFT, + .hd_reg = AFE_ETDM_IN3_CON0, + .hd_mask = ETDM_IN3_HD_MODE_MASK, + .hd_shift = ETDM_IN3_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN3_CON0, + .hd_align_mshift = ETDM_IN3_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN4] = { + .name = "ETDM_IN4", + .id = MT8196_MEMIF_ETDM_IN4, + .reg_ofs_base = AFE_ETDM_IN4_BASE, + .reg_ofs_cur = AFE_ETDM_IN4_CUR, + .reg_ofs_end = AFE_ETDM_IN4_END, + .reg_ofs_base_msb = AFE_ETDM_IN4_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN4_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN4_END_MSB, + .fs_reg = ETDM_IN4_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN4_CON0, + .enable_shift = ETDM_IN4_ON_SFT, + .hd_reg = AFE_ETDM_IN4_CON0, + .hd_mask = ETDM_IN4_HD_MODE_MASK, + .hd_shift = ETDM_IN4_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN4_CON0, + .hd_align_mshift = ETDM_IN4_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_ETDM_IN6] = { + .name = "ETDM_IN6", + .id = MT8196_MEMIF_ETDM_IN6, + .reg_ofs_base = AFE_ETDM_IN6_BASE, + .reg_ofs_cur = AFE_ETDM_IN6_CUR, + .reg_ofs_end = AFE_ETDM_IN6_END, + .reg_ofs_base_msb = AFE_ETDM_IN6_BASE_MSB, + .reg_ofs_cur_msb = AFE_ETDM_IN6_CUR_MSB, + .reg_ofs_end_msb = AFE_ETDM_IN6_END_MSB, + .fs_reg = ETDM_IN6_CON3, + .fs_shift = REG_FS_TIMING_SEL_SFT, + .fs_maskbit = REG_FS_TIMING_SEL_MASK, + .enable_reg = AFE_ETDM_IN6_CON0, + .enable_shift = ETDM_IN6_ON_SFT, + .hd_reg = AFE_ETDM_IN6_CON0, + .hd_mask = ETDM_IN6_HD_MODE_MASK, + .hd_shift = ETDM_IN6_HD_MODE_SFT, + .hd_align_reg = AFE_ETDM_IN6_CON0, + .hd_align_mshift = ETDM_IN6_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + }, + [MT8196_MEMIF_HDMI] = { + .name = "HDMI", + .id = MT8196_MEMIF_HDMI, + .reg_ofs_base = AFE_HDMI_OUT_BASE, + .reg_ofs_cur = AFE_HDMI_OUT_CUR, + .reg_ofs_end = AFE_HDMI_OUT_END, + .reg_ofs_base_msb = AFE_HDMI_OUT_BASE_MSB, + .reg_ofs_cur_msb = AFE_HDMI_OUT_CUR_MSB, + .reg_ofs_end_msb = AFE_HDMI_OUT_END_MSB, + .fs_reg = -1, + .fs_shift = -1, + .fs_maskbit = -1, + .mono_reg = -1, + .mono_shift = -1, + .enable_reg = AFE_HDMI_OUT_CON0, + .enable_shift = HDMI_OUT_ON_SFT, + .hd_reg = AFE_HDMI_OUT_CON0, + .hd_mask = HDMI_OUT_HD_MODE_MASK, + .hd_shift = HDMI_OUT_HD_MODE_SFT, + .hd_align_reg = AFE_HDMI_OUT_CON0, + .hd_align_mshift = HDMI_OUT_HALIGN_SFT, + .hd_msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + .msb_reg = -1, + .msb_shift = -1, + .pbuf_reg = AFE_HDMI_OUT_CON0, + .pbuf_mask = HDMI_OUT_PBUF_SIZE_MASK, + .pbuf_shift = HDMI_OUT_PBUF_SIZE_SFT, + .minlen_reg = AFE_HDMI_OUT_CON0, + .minlen_mask = HDMI_OUT_MINLEN_MASK, + .minlen_shift = HDMI_OUT_MINLEN_SFT, + }, +}; + +static const struct mtk_base_irq_data irq_data[MT8196_IRQ_NUM] = { + [MT8196_IRQ_0] = { + .id = MT8196_IRQ_0, + .irq_cnt_reg = AFE_IRQ0_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ0_MCU_CFG0, + .irq_fs_shift = AFE_IRQ0_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ0_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ0_MCU_CFG0, + .irq_en_shift = AFE_IRQ0_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ0_MCU_CFG1, + .irq_clr_shift = AFE_IRQ0_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ0_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_1] = { + .id = MT8196_IRQ_1, + .irq_cnt_reg = AFE_IRQ1_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ1_MCU_CFG0, + .irq_fs_shift = AFE_IRQ1_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ1_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ1_MCU_CFG0, + .irq_en_shift = AFE_IRQ1_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ1_MCU_CFG1, + .irq_clr_shift = AFE_IRQ1_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ1_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_2] = { + .id = MT8196_IRQ_2, + .irq_cnt_reg = AFE_IRQ2_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ2_MCU_CFG0, + .irq_fs_shift = AFE_IRQ2_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ2_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ2_MCU_CFG0, + .irq_en_shift = AFE_IRQ2_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ2_MCU_CFG1, + .irq_clr_shift = AFE_IRQ2_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ2_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_3] = { + .id = MT8196_IRQ_3, + .irq_cnt_reg = AFE_IRQ3_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ3_MCU_CFG0, + .irq_fs_shift = AFE_IRQ3_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ3_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ3_MCU_CFG0, + .irq_en_shift = AFE_IRQ3_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ3_MCU_CFG1, + .irq_clr_shift = AFE_IRQ3_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ3_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_4] = { + .id = MT8196_IRQ_4, + .irq_cnt_reg = AFE_IRQ4_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ4_MCU_CFG0, + .irq_fs_shift = AFE_IRQ4_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ4_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ4_MCU_CFG0, + .irq_en_shift = AFE_IRQ4_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ4_MCU_CFG1, + .irq_clr_shift = AFE_IRQ4_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ4_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_5] = { + .id = MT8196_IRQ_5, + .irq_cnt_reg = AFE_IRQ5_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ5_MCU_CFG0, + .irq_fs_shift = AFE_IRQ5_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ5_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ5_MCU_CFG0, + .irq_en_shift = AFE_IRQ5_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ5_MCU_CFG1, + .irq_clr_shift = AFE_IRQ5_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ5_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_6] = { + .id = MT8196_IRQ_6, + .irq_cnt_reg = AFE_IRQ6_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ6_MCU_CFG0, + .irq_fs_shift = AFE_IRQ6_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ6_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ6_MCU_CFG0, + .irq_en_shift = AFE_IRQ6_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ6_MCU_CFG1, + .irq_clr_shift = AFE_IRQ6_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ6_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_7] = { + .id = MT8196_IRQ_7, + .irq_cnt_reg = AFE_IRQ7_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ7_MCU_CFG0, + .irq_fs_shift = AFE_IRQ7_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ7_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ7_MCU_CFG0, + .irq_en_shift = AFE_IRQ7_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ7_MCU_CFG1, + .irq_clr_shift = AFE_IRQ7_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ7_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_8] = { + .id = MT8196_IRQ_8, + .irq_cnt_reg = AFE_IRQ8_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ8_MCU_CFG0, + .irq_fs_shift = AFE_IRQ8_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ8_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ8_MCU_CFG0, + .irq_en_shift = AFE_IRQ8_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ8_MCU_CFG1, + .irq_clr_shift = AFE_IRQ8_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ8_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_9] = { + .id = MT8196_IRQ_9, + .irq_cnt_reg = AFE_IRQ9_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ9_MCU_CFG0, + .irq_fs_shift = AFE_IRQ9_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ9_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ9_MCU_CFG0, + .irq_en_shift = AFE_IRQ9_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ9_MCU_CFG1, + .irq_clr_shift = AFE_IRQ9_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ9_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_10] = { + .id = MT8196_IRQ_10, + .irq_cnt_reg = AFE_IRQ10_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ10_MCU_CFG0, + .irq_fs_shift = AFE_IRQ10_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ10_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ10_MCU_CFG0, + .irq_en_shift = AFE_IRQ10_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ10_MCU_CFG1, + .irq_clr_shift = AFE_IRQ10_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ10_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_11] = { + .id = MT8196_IRQ_11, + .irq_cnt_reg = AFE_IRQ11_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ11_MCU_CFG0, + .irq_fs_shift = AFE_IRQ11_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ11_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ11_MCU_CFG0, + .irq_en_shift = AFE_IRQ11_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ11_MCU_CFG1, + .irq_clr_shift = AFE_IRQ11_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ11_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_12] = { + .id = MT8196_IRQ_12, + .irq_cnt_reg = AFE_IRQ12_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ12_MCU_CFG0, + .irq_fs_shift = AFE_IRQ12_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ12_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ12_MCU_CFG0, + .irq_en_shift = AFE_IRQ12_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ12_MCU_CFG1, + .irq_clr_shift = AFE_IRQ12_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ12_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_13] = { + .id = MT8196_IRQ_13, + .irq_cnt_reg = AFE_IRQ13_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ13_MCU_CFG0, + .irq_fs_shift = AFE_IRQ13_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ13_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ13_MCU_CFG0, + .irq_en_shift = AFE_IRQ13_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ13_MCU_CFG1, + .irq_clr_shift = AFE_IRQ13_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ13_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_14] = { + .id = MT8196_IRQ_14, + .irq_cnt_reg = AFE_IRQ14_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ14_MCU_CFG0, + .irq_fs_shift = AFE_IRQ14_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ14_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ14_MCU_CFG0, + .irq_en_shift = AFE_IRQ14_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ14_MCU_CFG1, + .irq_clr_shift = AFE_IRQ14_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ14_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_15] = { + .id = MT8196_IRQ_15, + .irq_cnt_reg = AFE_IRQ15_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ15_MCU_CFG0, + .irq_fs_shift = AFE_IRQ15_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ15_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ15_MCU_CFG0, + .irq_en_shift = AFE_IRQ15_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ15_MCU_CFG1, + .irq_clr_shift = AFE_IRQ15_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ15_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_16] = { + .id = MT8196_IRQ_16, + .irq_cnt_reg = AFE_IRQ16_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ16_MCU_CFG0, + .irq_fs_shift = AFE_IRQ16_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ16_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ16_MCU_CFG0, + .irq_en_shift = AFE_IRQ16_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ16_MCU_CFG1, + .irq_clr_shift = AFE_IRQ16_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ16_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_17] = { + .id = MT8196_IRQ_17, + .irq_cnt_reg = AFE_IRQ17_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ17_MCU_CFG0, + .irq_fs_shift = AFE_IRQ17_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ17_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ17_MCU_CFG0, + .irq_en_shift = AFE_IRQ17_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ17_MCU_CFG1, + .irq_clr_shift = AFE_IRQ17_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ17_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_18] = { + .id = MT8196_IRQ_18, + .irq_cnt_reg = AFE_IRQ18_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ18_MCU_CFG0, + .irq_fs_shift = AFE_IRQ18_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ18_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ18_MCU_CFG0, + .irq_en_shift = AFE_IRQ18_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ18_MCU_CFG1, + .irq_clr_shift = AFE_IRQ18_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ18_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_19] = { + .id = MT8196_IRQ_19, + .irq_cnt_reg = AFE_IRQ19_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ19_MCU_CFG0, + .irq_fs_shift = AFE_IRQ19_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ19_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ19_MCU_CFG0, + .irq_en_shift = AFE_IRQ19_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ19_MCU_CFG1, + .irq_clr_shift = AFE_IRQ19_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ19_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_20] = { + .id = MT8196_IRQ_20, + .irq_cnt_reg = AFE_IRQ20_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ20_MCU_CFG0, + .irq_fs_shift = AFE_IRQ20_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ20_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ20_MCU_CFG0, + .irq_en_shift = AFE_IRQ20_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ20_MCU_CFG1, + .irq_clr_shift = AFE_IRQ20_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ20_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_21] = { + .id = MT8196_IRQ_21, + .irq_cnt_reg = AFE_IRQ21_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ21_MCU_CFG0, + .irq_fs_shift = AFE_IRQ21_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ21_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ21_MCU_CFG0, + .irq_en_shift = AFE_IRQ21_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ21_MCU_CFG1, + .irq_clr_shift = AFE_IRQ21_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ21_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_22] = { + .id = MT8196_IRQ_22, + .irq_cnt_reg = AFE_IRQ22_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ22_MCU_CFG0, + .irq_fs_shift = AFE_IRQ22_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ22_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ22_MCU_CFG0, + .irq_en_shift = AFE_IRQ22_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ22_MCU_CFG1, + .irq_clr_shift = AFE_IRQ22_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ22_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_23] = { + .id = MT8196_IRQ_23, + .irq_cnt_reg = AFE_IRQ23_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ23_MCU_CFG0, + .irq_fs_shift = AFE_IRQ23_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ23_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ23_MCU_CFG0, + .irq_en_shift = AFE_IRQ23_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ23_MCU_CFG1, + .irq_clr_shift = AFE_IRQ23_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ23_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_24] = { + .id = MT8196_IRQ_24, + .irq_cnt_reg = AFE_IRQ24_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ24_MCU_CFG0, + .irq_fs_shift = AFE_IRQ24_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ24_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ24_MCU_CFG0, + .irq_en_shift = AFE_IRQ24_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ24_MCU_CFG1, + .irq_clr_shift = AFE_IRQ24_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ24_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_25] = { + .id = MT8196_IRQ_25, + .irq_cnt_reg = AFE_IRQ25_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ25_MCU_CFG0, + .irq_fs_shift = AFE_IRQ25_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ25_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ25_MCU_CFG0, + .irq_en_shift = AFE_IRQ25_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ25_MCU_CFG1, + .irq_clr_shift = AFE_IRQ25_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ25_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_26] = { + .id = MT8196_IRQ_26, + .irq_cnt_reg = AFE_IRQ26_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ26_MCU_CFG0, + .irq_fs_shift = AFE_IRQ26_MCU_FS_SFT, + .irq_fs_maskbit = AFE_IRQ26_MCU_FS_MASK, + .irq_en_reg = AFE_IRQ26_MCU_CFG0, + .irq_en_shift = AFE_IRQ26_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ26_MCU_CFG1, + .irq_clr_shift = AFE_IRQ26_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_IRQ_MCU_SCP_EN, + .irq_scp_en_shift = IRQ26_MCU_SCP_EN_SFT, + }, + [MT8196_IRQ_31] = { + .id = MT8196_CUS_IRQ_TDM, + .irq_cnt_reg = AFE_CUSTOM_IRQ0_MCU_CFG1, + .irq_cnt_shift = AFE_CUSTOM_IRQ0_MCU_CNT_SFT, + .irq_cnt_maskbit = AFE_CUSTOM_IRQ0_MCU_CNT_MASK, + .irq_fs_reg = -1, + .irq_fs_shift = -1, + .irq_fs_maskbit = -1, + .irq_en_reg = AFE_CUSTOM_IRQ0_MCU_CFG0, + .irq_en_shift = AFE_CUSTOM_IRQ0_MCU_ON_SFT, + .irq_clr_reg = AFE_CUSTOM_IRQ0_MCU_CFG1, + .irq_clr_shift = AFE_CUSTOM_IRQ0_CLR_CFG_SFT, + .irq_ap_en_reg = AFE_CUSTOM_IRQ_MCU_EN, + .irq_scp_en_reg = AFE_CUSTOM_IRQ_MCU_SCP_EN, + }, +}; + +static const int memif_irq_usage[MT8196_MEMIF_NUM] = { + /* TODO: verify each memif & irq */ + [MT8196_MEMIF_DL0] = MT8196_IRQ_0, + [MT8196_MEMIF_DL1] = MT8196_IRQ_1, + [MT8196_MEMIF_DL2] = MT8196_IRQ_2, + [MT8196_MEMIF_DL3] = MT8196_IRQ_3, + [MT8196_MEMIF_DL4] = MT8196_IRQ_4, + [MT8196_MEMIF_DL5] = MT8196_IRQ_5, + [MT8196_MEMIF_DL6] = MT8196_IRQ_6, + [MT8196_MEMIF_DL7] = MT8196_IRQ_7, + [MT8196_MEMIF_DL8] = MT8196_IRQ_8, + [MT8196_MEMIF_DL23] = MT8196_IRQ_9, + [MT8196_MEMIF_DL24] = MT8196_IRQ_10, + [MT8196_MEMIF_DL25] = MT8196_IRQ_11, + [MT8196_MEMIF_DL26] = MT8196_IRQ_0, + [MT8196_MEMIF_DL_4CH] = MT8196_IRQ_0, + [MT8196_MEMIF_DL_24CH] = MT8196_IRQ_12, + [MT8196_MEMIF_VUL0] = MT8196_IRQ_13, + [MT8196_MEMIF_VUL1] = MT8196_IRQ_14, + [MT8196_MEMIF_VUL2] = MT8196_IRQ_15, + [MT8196_MEMIF_VUL3] = MT8196_IRQ_16, + [MT8196_MEMIF_VUL4] = MT8196_IRQ_17, + [MT8196_MEMIF_VUL5] = MT8196_IRQ_18, + [MT8196_MEMIF_VUL6] = MT8196_IRQ_19, + [MT8196_MEMIF_VUL7] = MT8196_IRQ_20, + [MT8196_MEMIF_VUL8] = MT8196_IRQ_21, + [MT8196_MEMIF_VUL9] = MT8196_IRQ_22, + [MT8196_MEMIF_VUL10] = MT8196_IRQ_23, + [MT8196_MEMIF_VUL24] = MT8196_IRQ_24, + [MT8196_MEMIF_VUL25] = MT8196_IRQ_25, + [MT8196_MEMIF_VUL26] = MT8196_IRQ_0, + [MT8196_MEMIF_VUL_CM0] = MT8196_IRQ_26, + [MT8196_MEMIF_VUL_CM1] = MT8196_IRQ_0, + [MT8196_MEMIF_VUL_CM2] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN0] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN1] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN2] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN3] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN4] = MT8196_IRQ_0, + [MT8196_MEMIF_ETDM_IN6] = MT8196_IRQ_0, + [MT8196_MEMIF_HDMI] = MT8196_IRQ_31 +}; + +static bool mt8196_is_volatile_reg(struct device *dev, unsigned int reg) +{ + /* these auto-gen reg has read-only bit, so put it as volatile */ + /* volatile reg cannot be cached, so cannot be set when power off */ + switch (reg) { + case AUDIO_TOP_CON0: /* reg bit controlled by CCF */ + case AUDIO_TOP_CON1: /* reg bit controlled by CCF */ + case AUDIO_TOP_CON2: + case AUDIO_TOP_CON3: + case AUDIO_TOP_CON4: + case AUD_TOP_MON_RG: + case AFE_APLL1_TUNER_MON0: + case AFE_APLL2_TUNER_MON0: + case AFE_SPM_CONTROL_ACK: + case AUDIO_TOP_IP_VERSION: + case AUDIO_ENGEN_CON0_MON: + case AFE_CONNSYS_I2S_IPM_VER_MON: + case AFE_CONNSYS_I2S_MON: + case AFE_PCM_INTF_MON: + case AFE_PCM_TOP_IP_VERSION: + case AFE_IRQ_MCU_STATUS: + case AFE_CUSTOM_IRQ_MCU_STATUS: + case AFE_IRQ_MCU_MON0: + case AFE_IRQ_MCU_MON1: + case AFE_IRQ_MCU_MON2: + case AFE_IRQ0_CNT_MON: + case AFE_IRQ1_CNT_MON: + case AFE_IRQ2_CNT_MON: + case AFE_IRQ3_CNT_MON: + case AFE_IRQ4_CNT_MON: + case AFE_IRQ5_CNT_MON: + case AFE_IRQ6_CNT_MON: + case AFE_IRQ7_CNT_MON: + case AFE_IRQ8_CNT_MON: + case AFE_IRQ9_CNT_MON: + case AFE_IRQ10_CNT_MON: + case AFE_IRQ11_CNT_MON: + case AFE_IRQ12_CNT_MON: + case AFE_IRQ13_CNT_MON: + case AFE_IRQ14_CNT_MON: + case AFE_IRQ15_CNT_MON: + case AFE_IRQ16_CNT_MON: + case AFE_IRQ17_CNT_MON: + case AFE_IRQ18_CNT_MON: + case AFE_IRQ19_CNT_MON: + case AFE_IRQ20_CNT_MON: + case AFE_IRQ21_CNT_MON: + case AFE_IRQ22_CNT_MON: + case AFE_IRQ23_CNT_MON: + case AFE_IRQ24_CNT_MON: + case AFE_IRQ25_CNT_MON: + case AFE_IRQ26_CNT_MON: + case AFE_CUSTOM_IRQ0_CNT_MON: + case AFE_STF_MON: + case AFE_STF_IP_VERSION: + case AFE_CM0_MON: + case AFE_CM0_IP_VERSION: + case AFE_CM1_MON: + case AFE_CM1_IP_VERSION: + case AFE_ADDA_UL0_SRC_DEBUG_MON0: + case AFE_ADDA_UL0_SRC_MON0: + case AFE_ADDA_UL0_SRC_MON1: + case AFE_ADDA_UL0_IP_VERSION: + case AFE_ADDA_UL1_SRC_DEBUG_MON0: + case AFE_ADDA_UL1_SRC_MON0: + case AFE_ADDA_UL1_SRC_MON1: + case AFE_ADDA_UL1_IP_VERSION: + case AFE_MTKAIF_IPM_VER_MON: + case AFE_MTKAIF_MON: + case AFE_AUD_PAD_TOP_MON: + case AFE_ADDA_MTKAIFV4_MON0: + case AFE_ADDA_MTKAIFV4_MON1: + case AFE_ADDA6_MTKAIFV4_MON0: + case ETDM_IN0_MON: + case ETDM_IN1_MON: + case ETDM_IN2_MON: + case ETDM_IN4_MON: + case ETDM_IN6_MON: + case ETDM_OUT0_MON: + case ETDM_OUT1_MON: + case ETDM_OUT2_MON: + case ETDM_OUT4_MON: + case ETDM_OUT6_MON: + case AFE_DPTX_MON: + case AFE_TDM_TOP_IP_VERSION: + case AFE_CONN_MON0: + case AFE_CONN_MON1: + case AFE_CONN_MON2: + case AFE_CONN_MON3: + case AFE_CONN_MON4: + case AFE_CONN_MON5: + case AFE_CBIP_SLV_DECODER_MON0: + case AFE_CBIP_SLV_DECODER_MON1: + case AFE_CBIP_SLV_MUX_MON0: + case AFE_CBIP_SLV_MUX_MON1: + case AFE_DL0_CUR_MSB: + case AFE_DL0_CUR: + case AFE_DL0_RCH_MON: + case AFE_DL0_LCH_MON: + case AFE_DL1_CUR_MSB: + case AFE_DL1_CUR: + case AFE_DL1_RCH_MON: + case AFE_DL1_LCH_MON: + case AFE_DL2_CUR_MSB: + case AFE_DL2_CUR: + case AFE_DL2_RCH_MON: + case AFE_DL2_LCH_MON: + case AFE_DL3_CUR_MSB: + case AFE_DL3_CUR: + case AFE_DL3_RCH_MON: + case AFE_DL3_LCH_MON: + case AFE_DL4_CUR_MSB: + case AFE_DL4_CUR: + case AFE_DL4_RCH_MON: + case AFE_DL4_LCH_MON: + case AFE_DL5_CUR_MSB: + case AFE_DL5_CUR: + case AFE_DL5_RCH_MON: + case AFE_DL5_LCH_MON: + case AFE_DL6_CUR_MSB: + case AFE_DL6_CUR: + case AFE_DL6_RCH_MON: + case AFE_DL6_LCH_MON: + case AFE_DL7_CUR_MSB: + case AFE_DL7_CUR: + case AFE_DL7_RCH_MON: + case AFE_DL7_LCH_MON: + case AFE_DL8_CUR_MSB: + case AFE_DL8_CUR: + case AFE_DL8_RCH_MON: + case AFE_DL8_LCH_MON: + case AFE_DL_24CH_CUR_MSB: + case AFE_DL_24CH_CUR: + case AFE_DL_4CH_CUR_MSB: + case AFE_DL_4CH_CUR: + case AFE_DL23_CUR_MSB: + case AFE_DL23_CUR: + case AFE_DL23_RCH_MON: + case AFE_DL23_LCH_MON: + case AFE_DL24_CUR_MSB: + case AFE_DL24_CUR: + case AFE_DL24_RCH_MON: + case AFE_DL24_LCH_MON: + case AFE_DL25_CUR_MSB: + case AFE_DL25_CUR: + case AFE_DL25_RCH_MON: + case AFE_DL25_LCH_MON: + case AFE_DL26_CUR_MSB: + case AFE_DL26_CUR: + case AFE_DL26_RCH_MON: + case AFE_DL26_LCH_MON: + case AFE_VUL0_CUR_MSB: + case AFE_VUL0_CUR: + case AFE_VUL1_CUR_MSB: + case AFE_VUL1_CUR: + case AFE_VUL2_CUR_MSB: + case AFE_VUL2_CUR: + case AFE_VUL3_CUR_MSB: + case AFE_VUL3_CUR: + case AFE_VUL4_CUR_MSB: + case AFE_VUL4_CUR: + case AFE_VUL5_CUR_MSB: + case AFE_VUL5_CUR: + case AFE_VUL6_CUR_MSB: + case AFE_VUL6_CUR: + case AFE_VUL7_CUR_MSB: + case AFE_VUL7_CUR: + case AFE_VUL8_CUR_MSB: + case AFE_VUL8_CUR: + case AFE_VUL9_CUR_MSB: + case AFE_VUL9_CUR: + case AFE_VUL10_CUR_MSB: + case AFE_VUL10_CUR: + case AFE_VUL24_CUR_MSB: + case AFE_VUL24_CUR: + case AFE_VUL25_CUR_MSB: + case AFE_VUL25_CUR: + case AFE_VUL25_RCH_MON: + case AFE_VUL25_LCH_MON: + case AFE_VUL26_CUR_MSB: + case AFE_VUL26_CUR: + case AFE_VUL_CM0_CUR_MSB: + case AFE_VUL_CM0_CUR: + case AFE_VUL_CM1_CUR_MSB: + case AFE_VUL_CM1_CUR: + case AFE_VUL_CM2_CUR_MSB: + case AFE_VUL_CM2_CUR: + case AFE_ETDM_IN0_CUR_MSB: + case AFE_ETDM_IN0_CUR: + case AFE_ETDM_IN1_CUR_MSB: + case AFE_ETDM_IN1_CUR: + case AFE_ETDM_IN2_CUR_MSB: + case AFE_ETDM_IN2_CUR: + case AFE_ETDM_IN3_CUR_MSB: + case AFE_ETDM_IN3_CUR: + case AFE_ETDM_IN4_CUR_MSB: + case AFE_ETDM_IN4_CUR: + case AFE_ETDM_IN6_CUR_MSB: + case AFE_ETDM_IN6_CUR: + case AFE_HDMI_OUT_CUR_MSB: + case AFE_HDMI_OUT_CUR: + case AFE_HDMI_OUT_END: + case AFE_PROT_SIDEBAND0_MON: + case AFE_PROT_SIDEBAND1_MON: + case AFE_PROT_SIDEBAND2_MON: + case AFE_PROT_SIDEBAND3_MON: + case AFE_DOMAIN_SIDEBAND0_MON: + case AFE_DOMAIN_SIDEBAND1_MON: + case AFE_DOMAIN_SIDEBAND2_MON: + case AFE_DOMAIN_SIDEBAND3_MON: + case AFE_DOMAIN_SIDEBAND4_MON: + case AFE_DOMAIN_SIDEBAND5_MON: + case AFE_DOMAIN_SIDEBAND6_MON: + case AFE_DOMAIN_SIDEBAND7_MON: + case AFE_DOMAIN_SIDEBAND8_MON: + case AFE_DOMAIN_SIDEBAND9_MON: + case AFE_PCM0_INTF_CON1_MASK_MON: + case AFE_PCM0_INTF_CON0_MASK_MON: + case AFE_CONNSYS_I2S_CON_MASK_MON: + case AFE_TDM_CON2_MASK_MON: + case AFE_MTKAIF0_CFG0_MASK_MON: + case AFE_MTKAIF1_CFG0_MASK_MON: + case AFE_ADDA_UL0_SRC_CON0_MASK_MON: + case AFE_ADDA_UL1_SRC_CON0_MASK_MON: + case AFE_ASRC_NEW_CON0: + case AFE_ASRC_NEW_CON6: + case AFE_ASRC_NEW_CON8: + case AFE_ASRC_NEW_CON9: + case AFE_ASRC_NEW_CON12: + case AFE_ASRC_NEW_IP_VERSION: + case AFE_GASRC0_NEW_CON0: + case AFE_GASRC0_NEW_CON6: + case AFE_GASRC0_NEW_CON8: + case AFE_GASRC0_NEW_CON9: + case AFE_GASRC0_NEW_CON10: + case AFE_GASRC0_NEW_CON11: + case AFE_GASRC0_NEW_CON12: + case AFE_GASRC0_NEW_IP_VERSION: + case AFE_GASRC1_NEW_CON0: + case AFE_GASRC1_NEW_CON6: + case AFE_GASRC1_NEW_CON8: + case AFE_GASRC1_NEW_CON9: + case AFE_GASRC1_NEW_CON12: + case AFE_GASRC1_NEW_IP_VERSION: + case AFE_GASRC2_NEW_CON0: + case AFE_GASRC2_NEW_CON6: + case AFE_GASRC2_NEW_CON8: + case AFE_GASRC2_NEW_CON9: + case AFE_GASRC2_NEW_CON12: + case AFE_GASRC2_NEW_IP_VERSION: + case AFE_GASRC3_NEW_CON0: + case AFE_GASRC3_NEW_CON6: + case AFE_GASRC3_NEW_CON8: + case AFE_GASRC3_NEW_CON9: + case AFE_GASRC3_NEW_CON12: + case AFE_GASRC3_NEW_IP_VERSION: + /* these reg would change in adsp */ + case AFE_IRQ_MCU_EN: + case AFE_IRQ_MCU_DSP_EN: + case AFE_IRQ_MCU_DSP2_EN: + case AFE_DL5_CON0: + case AFE_DL6_CON0: + case AFE_DL23_CON0: + case AFE_DL_24CH_CON0: + case AFE_VUL1_CON0: + case AFE_VUL3_CON0: + case AFE_VUL4_CON0: + case AFE_VUL5_CON0: + case AFE_VUL9_CON0: + case AFE_VUL25_CON0: + case AFE_IRQ0_MCU_CFG0: + case AFE_IRQ1_MCU_CFG0: + case AFE_IRQ2_MCU_CFG0: + case AFE_IRQ3_MCU_CFG0: + case AFE_IRQ4_MCU_CFG0: + case AFE_IRQ5_MCU_CFG0: + case AFE_IRQ6_MCU_CFG0: + case AFE_IRQ7_MCU_CFG0: + case AFE_IRQ8_MCU_CFG0: + case AFE_IRQ9_MCU_CFG0: + case AFE_IRQ10_MCU_CFG0: + case AFE_IRQ11_MCU_CFG0: + case AFE_IRQ12_MCU_CFG0: + case AFE_IRQ13_MCU_CFG0: + case AFE_IRQ14_MCU_CFG0: + case AFE_IRQ15_MCU_CFG0: + case AFE_IRQ16_MCU_CFG0: + case AFE_IRQ17_MCU_CFG0: + case AFE_IRQ18_MCU_CFG0: + case AFE_IRQ19_MCU_CFG0: + case AFE_IRQ20_MCU_CFG0: + case AFE_IRQ21_MCU_CFG0: + case AFE_IRQ22_MCU_CFG0: + case AFE_IRQ23_MCU_CFG0: + case AFE_IRQ24_MCU_CFG0: + case AFE_IRQ25_MCU_CFG0: + case AFE_IRQ26_MCU_CFG0: + case AFE_IRQ0_MCU_CFG1: + case AFE_IRQ1_MCU_CFG1: + case AFE_IRQ2_MCU_CFG1: + case AFE_IRQ3_MCU_CFG1: + case AFE_IRQ4_MCU_CFG1: + case AFE_IRQ5_MCU_CFG1: + case AFE_IRQ6_MCU_CFG1: + case AFE_IRQ7_MCU_CFG1: + case AFE_IRQ8_MCU_CFG1: + case AFE_IRQ9_MCU_CFG1: + case AFE_IRQ10_MCU_CFG1: + case AFE_IRQ11_MCU_CFG1: + case AFE_IRQ12_MCU_CFG1: + case AFE_IRQ13_MCU_CFG1: + case AFE_IRQ14_MCU_CFG1: + case AFE_IRQ15_MCU_CFG1: + case AFE_IRQ16_MCU_CFG1: + case AFE_IRQ17_MCU_CFG1: + case AFE_IRQ18_MCU_CFG1: + case AFE_IRQ19_MCU_CFG1: + case AFE_IRQ20_MCU_CFG1: + case AFE_IRQ21_MCU_CFG1: + case AFE_IRQ22_MCU_CFG1: + case AFE_IRQ23_MCU_CFG1: + case AFE_IRQ24_MCU_CFG1: + case AFE_IRQ25_MCU_CFG1: + case AFE_IRQ26_MCU_CFG1: + /* for vow using */ + case AFE_IRQ_MCU_SCP_EN: + case AFE_VUL_CM0_BASE_MSB: + case AFE_VUL_CM0_BASE: + case AFE_VUL_CM0_END_MSB: + case AFE_VUL_CM0_END: + case AFE_VUL_CM0_CON0: + return true; + default: + return false; + }; +} + +static const struct regmap_config mt8196_afe_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .volatile_reg = mt8196_is_volatile_reg, + + .max_register = AFE_MAX_REGISTER, + .num_reg_defaults_raw = AFE_MAX_REGISTER, + + .cache_type = REGCACHE_FLAT, +}; + +#if defined(FORCE_FPGA_ENABLE_IRQ) +static irqreturn_t mt8196_afe_irq_handler(int irq_id, void *dev) +{ + struct mtk_base_afe *afe = dev; + struct mtk_base_afe_irq *irq; + unsigned int status = 0; + unsigned int status_mcu; + unsigned int mcu_en = 0; + unsigned int cus_status = 0; + unsigned int cus_status_mcu; + unsigned int cus_mcu_en = 0; + unsigned int tmp_reg = 0; + int ret, cus_ret; + int i; + struct timespec64 ts64; + unsigned long long t1, t2; + /* one interrupt period = 5ms */ + unsigned long long timeout_limit = 5000000; + + /* get irq that is sent to MCU */ + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en); + regmap_read(afe->regmap, AFE_CUSTOM_IRQ_MCU_EN, &cus_mcu_en); + + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status); + cus_ret = regmap_read(afe->regmap, AFE_CUSTOM_IRQ_MCU_STATUS, &cus_status); + /* only care IRQ which is sent to MCU */ + status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS; + cus_status_mcu = cus_status & cus_mcu_en & AFE_IRQ_STATUS_BITS; + if ((ret || (status_mcu == 0)) && + (cus_ret || (cus_status_mcu == 0))) { + dev_info(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n", + __func__, ret, status, mcu_en); + dev_info(afe->dev, "%s(), irq status err, ret %d, cus_status_mcu 0x%x, cus_mcu_en 0x%x\n", + __func__, ret, cus_status_mcu, cus_mcu_en); + + goto err_irq; + } + + ktime_get_ts64(&ts64); + t1 = timespec64_to_ns(&ts64); + + for (i = 0; i < MT8196_MEMIF_NUM; i++) { + struct mtk_base_afe_memif *memif = &afe->memif[i]; + + if (!memif->substream) + continue; + + if (memif->irq_usage < 0) + continue; + irq = &afe->irqs[memif->irq_usage]; + + if (i == MT8196_MEMIF_HDMI) { + if (cus_status_mcu & (0x1 << irq->irq_data->id)) + snd_pcm_period_elapsed(memif->substream); + } else { + if (status_mcu & (0x1 << irq->irq_data->id)) + snd_pcm_period_elapsed(memif->substream); + } + } + + ktime_get_ts64(&ts64); + t2 = timespec64_to_ns(&ts64); + t2 = t2 - t1; /* in ns (10^9) */ + + if (t2 > timeout_limit) { + dev_info(afe->dev, "%s(), mcu_en 0x%x, cus_mcu_en 0x%x, timeout %llu, limit %llu, ret %d\n", + __func__, mcu_en, cus_mcu_en, + t2, timeout_limit, ret); + } + +err_irq: + /* clear irq */ + for (i = 0; i < MT8196_IRQ_NUM; ++i) { + if (status_mcu & (0x1 << i)) { + regmap_read(afe->regmap, irq_data[i].irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data[i].irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg^(AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + } + } + + return IRQ_HANDLED; +} +#endif + +static int mt8196_afe_runtime_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + unsigned int value = 0; + unsigned int tmp_reg = 0; + int ret = 0, i; + + dev_dbg(afe->dev, "%s() ready to stop\n", __func__); + + if (!afe->regmap) { + dev_info(afe->dev, "%s() skip regmap\n", __func__); + goto skip_regmap; + } + + /* Add to be off for free run*/ + /* disable AFE */ + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, 0x1, 0x0); + + ret = regmap_read_poll_timeout(afe->regmap, + AUDIO_ENGEN_CON0_MON, + value, + (value & AUDIO_ENGEN_MON_SFT) == 0, + 20, + 1 * 1000 * 1000); + dev_dbg(afe->dev, "%s() read_poll ret %d\n", __func__, ret); + if (ret) + dev_info(afe->dev, "%s(), ret %d\n", __func__, ret); + + /* make sure all irq status are cleared */ + for (i = 0; i < MT8196_IRQ_NUM; ++i) { + regmap_read(afe->regmap, irq_data[i].irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data[i].irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg^(AFE_IRQ_CLR_CFG_MASK_SFT | AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + } + + /* reset sgen */ + regmap_write(afe->regmap, AFE_SINEGEN_CON0, 0x0); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1, + SINE_DOMAIN_MASK_SFT, + 0x0 << SINE_DOMAIN_SFT); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1, + SINE_MODE_MASK_SFT, + 0x0 << SINE_MODE_SFT); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1, + INNER_LOOP_BACKI_SEL_MASK_SFT, + 0x0 << INNER_LOOP_BACKI_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1, + INNER_LOOP_BACK_MODE_MASK_SFT, + 0xff << INNER_LOOP_BACK_MODE_SFT); + + regmap_write(afe->regmap, AUDIO_TOP_CON4, 0x3fff); + + /* reset audio 26M request */ + regmap_update_bits(afe->regmap, + AFE_SPM_CONTROL_REQ, 0x1, 0x0); + + /* cache only */ + regcache_cache_only(afe->regmap, true); + regcache_mark_dirty(afe->regmap); + +skip_regmap: + mt8196_afe_disable_clock(afe); + return 0; +} + +static int mt8196_afe_runtime_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + int ret = 0; + + ret = mt8196_afe_enable_clock(afe); + dev_dbg(afe->dev, "%s(), enable_clock ret %d\n", __func__, ret); + + if (ret) + return ret; + + if (!afe->regmap) { + dev_info(afe->dev, "%s() skip regmap\n", __func__); + goto skip_regmap; + } + regcache_cache_only(afe->regmap, false); + regcache_sync(afe->regmap); + + /* set audio 26M request */ + regmap_update_bits(afe->regmap, AFE_SPM_CONTROL_REQ, 0x1, 0x1); + + /* IPM2.0: Clear AUDIO_TOP_CON4 for enabling AP side module clk */ + regmap_write(afe->regmap, AUDIO_TOP_CON4, 0x0); + + /* Add to be on for free run */ + regmap_write(afe->regmap, AUDIO_TOP_CON0, 0x0); + regmap_write(afe->regmap, AUDIO_TOP_CON1, 0x0); + regmap_write(afe->regmap, AUDIO_TOP_CON2, 0x0); + + /* Can't set AUDIO_TOP_CON3 to be 0x0, it will hang in FPGA env */ + regmap_write(afe->regmap, AUDIO_TOP_CON3, 0x0); + + regmap_update_bits(afe->regmap, AFE_CBIP_CFG0, 0x1, 0x1); + + /* force cpu use 8_24 format when writing 32bit data */ + regmap_update_bits(afe->regmap, AFE_MEMIF_CON0, + CPU_HD_ALIGN_MASK_SFT, 0 << CPU_HD_ALIGN_SFT); + + /* enable AFE */ + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, 0x1, 0x1); + +skip_regmap: + return 0; +} + +static int mt8196_afe_pcm_copy(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + struct iov_iter *buf, unsigned long bytes, + mtk_sp_copy_f sp_copy) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + int ret = 0; + + if (!component) + return -EINVAL; + + ret = sp_copy(substream, channel, hwoff, buf, bytes); + + return ret; +} + +static int mt8196_afe_component_probe(struct snd_soc_component *component) +{ + struct mtk_base_afe *afe = NULL; + struct snd_soc_card *sndcard = NULL; + struct snd_card *card = NULL; + + if (component) { + afe = snd_soc_component_get_drvdata(component); + sndcard = component->card; + card = sndcard->snd_card; + + mtk_afe_add_sub_dai_control(component); + } + + return 0; +} + +static const struct snd_soc_component_driver mt8196_afe_component = { + .name = AFE_PCM_NAME, + .probe = mt8196_afe_component_probe, + .pcm_construct = mtk_afe_pcm_new, + .pcm_destruct = mtk_afe_pcm_free, + .open = mtk_afe_pcm_open, + .pointer = mtk_afe_pcm_pointer, + .copy = mtk_afe_pcm_copy_user, +}; + +static int mt8196_dai_memif_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mt8196_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(mt8196_memif_dai_driver); + + dai->controls = mt8196_pcm_kcontrols; + dai->num_controls = ARRAY_SIZE(mt8196_pcm_kcontrols); + dai->dapm_widgets = mt8196_memif_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mt8196_memif_widgets); + dai->dapm_routes = mt8196_memif_routes; + dai->num_dapm_routes = ARRAY_SIZE(mt8196_memif_routes); + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { + mt8196_dai_adda_register, + mt8196_dai_i2s_register, + mt8196_dai_tdm_register, + mt8196_dai_memif_register, +}; + +static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev) +{ + int ret, i; + unsigned int tmp_reg = 0; +#if defined(FORCE_FPGA_ENABLE_IRQ) + int irq_id; +#endif + struct mtk_base_afe *afe; + struct mt8196_afe_private *afe_priv; + struct resource *res; + struct device *dev; + + pr_info("+%s()\n", __func__); + + ret = of_reserved_mem_device_init(&pdev->dev); + if (ret) + dev_dbg(&pdev->dev, "failed to assign memory region: %d\n", ret); + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34)); + if (ret) + return ret; + + afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + + platform_set_drvdata(pdev, afe); + + afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe_priv = afe->platform_priv; + + afe->dev = &pdev->dev; + dev = afe->dev; + + /* init audio related clock */ + ret = mt8196_init_clock(afe); + if (ret) { + dev_info(dev, "init clock error: %d\n", ret); + return ret; + } + + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) + goto err_pm_disable; + + /* Audio device is part of genpd. + * Set audio as syscore device to prevent + * genpd automatically power off audio + * device when suspend + */ + dev_pm_syscore_device(&pdev->dev, true); + + /* regmap init */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + afe->base_addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); + + /* enable clock for regcache get default value from hw */ + pm_runtime_get_sync(&pdev->dev); + + afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, + &mt8196_afe_regmap_config); + if (IS_ERR(afe->regmap)) + return PTR_ERR(afe->regmap); + + /* IPM2.0 clock flow, need debug */ + + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &tmp_reg); + regmap_write(afe->regmap, AFE_IRQ_MCU_EN, 0xffffffff); + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &tmp_reg); + /* IPM2.0 clock flow, need debug */ + + pm_runtime_put_sync(&pdev->dev); + + regcache_cache_only(afe->regmap, true); + regcache_mark_dirty(afe->regmap); + + /* init gpio */ + ret = mt8196_afe_gpio_init(afe); + if (ret) + dev_info(dev, "init gpio error\n"); + + /* init memif */ + /* IPM2.0 no need banding */ + afe->is_memif_bit_banding = 0; + afe->memif_32bit_supported = 1; + afe->memif_size = MT8196_MEMIF_NUM; + afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), + GFP_KERNEL); + + if (!afe->memif) + return -ENOMEM; + + for (i = 0; i < afe->memif_size; i++) { + afe->memif[i].data = &memif_data[i]; + afe->memif[i].irq_usage = memif_irq_usage[i]; + afe->memif[i].const_irq = 1; + } + + mutex_init(&afe->irq_alloc_lock); /* needed when dynamic irq */ + + /* init irq */ + afe->irqs_size = MT8196_IRQ_NUM; + afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), + GFP_KERNEL); + + if (!afe->irqs) + return -ENOMEM; + + for (i = 0; i < afe->irqs_size; i++) + afe->irqs[i].irq_data = &irq_data[i]; + +#if defined(FORCE_FPGA_ENABLE_IRQ) + /* request irq */ + irq_id = platform_get_irq(pdev, 0); + if (irq_id <= 0) { + dev_info(dev, "%pOFn no irq found\n", dev->of_node); + return irq_id < 0 ? irq_id : -ENXIO; + } + ret = devm_request_irq(dev, irq_id, mt8196_afe_irq_handler, + IRQF_TRIGGER_NONE, + "Afe_ISR_Handle", (void *)afe); + if (ret) { + dev_info(dev, "could not request_irq for Afe_ISR_Handle\n"); + return ret; + } + ret = enable_irq_wake(irq_id); + if (ret < 0) + dev_info(dev, "enable_irq_wake %d err: %d\n", irq_id, ret); +#endif + + /* init sub_dais */ + INIT_LIST_HEAD(&afe->sub_dais); + + for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { + ret = dai_register_cbs[i](afe); + if (ret) { + dev_info(afe->dev, "dai register i %d fail, ret %d\n", + i, ret); + goto err_pm_disable; + } + } + + /* init dai_driver and component_driver */ + ret = mtk_afe_combine_sub_dai(afe); + if (ret) { + dev_info(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n", + ret); + goto err_pm_disable; + } + + /* others */ + afe->mtk_afe_hardware = &mt8196_afe_hardware; + afe->memif_fs = mt8196_memif_fs; + afe->irq_fs = mt8196_irq_fs; + afe->get_dai_fs = mt8196_get_dai_fs; + afe->get_memif_pbuf_size = mt8196_get_memif_pbuf_size; + + afe->runtime_resume = mt8196_afe_runtime_resume; + afe->runtime_suspend = mt8196_afe_runtime_suspend; + + afe->request_dram_resource = mt8196_afe_dram_request; + afe->release_dram_resource = mt8196_afe_dram_release; + + afe->copy = mt8196_afe_pcm_copy; + + /* register component */ + ret = devm_snd_soc_register_component(&pdev->dev, + &mt8196_afe_component, + afe->dai_drivers, + afe->num_dai_drivers); + if (ret) { + dev_info(dev, "afe component err: %d\n", ret); + goto err_pm_disable; + } + return 0; + +err_pm_disable: + pm_runtime_disable(&pdev->dev); + return ret; +} + +static int mt8196_afe_pcm_dev_remove(struct platform_device *pdev) +{ + struct mtk_base_afe *afe = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + mt8196_afe_runtime_suspend(&pdev->dev); + + /* disable afe clock */ + mt8196_afe_disable_clock(afe); + return 0; +} + +static const struct of_device_id mt8196_afe_pcm_dt_match[] = { + { .compatible = "mediatek,mt8196-sound", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt8196_afe_pcm_dt_match); + +static const struct dev_pm_ops mt8196_afe_pm_ops = { + SET_RUNTIME_PM_OPS(mt8196_afe_runtime_suspend, + mt8196_afe_runtime_resume, NULL) +}; + +static struct platform_driver mt8196_afe_pcm_driver = { + .driver = { + .name = "mt8196-audio", + .of_match_table = mt8196_afe_pcm_dt_match, +#if IS_ENABLED(CONFIG_PM) + .pm = &mt8196_afe_pm_ops, +#endif + }, + .probe = mt8196_afe_pcm_dev_probe, + .remove = mt8196_afe_pcm_dev_remove, +}; + +module_platform_driver(mt8196_afe_pcm_driver); + +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8196"); +MODULE_AUTHOR("Darren Ye "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/mediatek/mt8196/mt8196-dai-adda.c b/sound/soc/mediatek/mt8196/mt8196-dai-adda.c new file mode 100644 index 0000000000000..47b63248fb681 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-dai-adda.c @@ -0,0 +1,2204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI ADDA Control + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include "mt8196-afe-clk.h" +#include "mt8196-afe-common.h" +#include "mt8196-afe-gpio.h" +#include "mt8196-interconnection.h" + +#define MTKAIF4 //for mt6338 +/* mt6363 vs1 voter */ +#define RG_BUCK_VS1_VOTER_EN_LO 0x189a +#define RG_BUCK_VS1_VOTER_EN_LO_SET 0x189b +#define RG_BUCK_VS1_VOTER_EN_LO_CLR 0x189c + +#define VS1_MT6338_MSK (0x1 << 0) + +enum { + UL_IIR_SW = 0, + UL_IIR_5HZ, + UL_IIR_10HZ, + UL_IIR_25HZ, + UL_IIR_50HZ, + UL_IIR_75HZ, +}; + +enum { + AUDIO_SDM_LEVEL_MUTE = 0, + AUDIO_SDM_LEVEL_NORMAL = 0x1d, + /* if you change level normal */ + /* you need to change formula of hp impedance and dc trim too */ +}; + +enum { + AUDIO_SDM_2ND = 0, + AUDIO_SDM_3RD, +}; + +enum { + DELAY_DATA_MISO1 = 0, + DELAY_DATA_MISO2, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K = 0, + MTK_AFE_ADDA_DL_RATE_11K = 1, + MTK_AFE_ADDA_DL_RATE_12K = 2, + MTK_AFE_ADDA_DL_RATE_16K = 4, + MTK_AFE_ADDA_DL_RATE_22K = 5, + MTK_AFE_ADDA_DL_RATE_24K = 6, + MTK_AFE_ADDA_DL_RATE_32K = 8, + MTK_AFE_ADDA_DL_RATE_44K = 9, + MTK_AFE_ADDA_DL_RATE_48K = 10, + MTK_AFE_ADDA_DL_RATE_88K = 13, + MTK_AFE_ADDA_DL_RATE_96K = 14, + MTK_AFE_ADDA_DL_RATE_176K = 17, + MTK_AFE_ADDA_DL_RATE_192K = 18, + MTK_AFE_ADDA_DL_RATE_352K = 21, + MTK_AFE_ADDA_DL_RATE_384K = 22, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K = 0, + MTK_AFE_ADDA_UL_RATE_16K = 1, + MTK_AFE_ADDA_UL_RATE_32K = 2, + MTK_AFE_ADDA_UL_RATE_48K = 3, + MTK_AFE_ADDA_UL_RATE_96K = 4, + MTK_AFE_ADDA_UL_RATE_192K = 5, + MTK_AFE_ADDA_UL_RATE_48K_HD = 6, +}; + +#ifdef MTKAIF4 +enum { + MTK_AFE_MTKAIF_RATE_8K = 0x0, + MTK_AFE_MTKAIF_RATE_12K = 0x1, + MTK_AFE_MTKAIF_RATE_16K = 0x2, + MTK_AFE_MTKAIF_RATE_24K = 0x3, + MTK_AFE_MTKAIF_RATE_32K = 0x4, + MTK_AFE_MTKAIF_RATE_48K = 0x5, + MTK_AFE_MTKAIF_RATE_64K = 0x6, + MTK_AFE_MTKAIF_RATE_96K = 0x7, + MTK_AFE_MTKAIF_RATE_128K = 0x8, + MTK_AFE_MTKAIF_RATE_192K = 0x9, + MTK_AFE_MTKAIF_RATE_256K = 0xa, + MTK_AFE_MTKAIF_RATE_384K = 0xb, + MTK_AFE_MTKAIF_RATE_11K = 0x10, + MTK_AFE_MTKAIF_RATE_22K = 0x11, + MTK_AFE_MTKAIF_RATE_44K = 0x12, + MTK_AFE_MTKAIF_RATE_88K = 0x13, + MTK_AFE_MTKAIF_RATE_176K = 0x14, + MTK_AFE_MTKAIF_RATE_352K = 0x15, +}; +#endif + +#define SDM_AUTO_RESET_THRESHOLD 0x190000 + +struct mtk_afe_adda_priv { + int dl_rate; + int ul_rate; +}; + +static struct mtk_afe_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int dai_id; + + if (strncmp(name, "aud_dl0_dac_hires_clk", 21) == 0 || + strncmp(name, "aud_ul0_adc_hires_clk", 21) == 0) + dai_id = MT8196_DAI_ADDA; + else if (strncmp(name, "aud_dl1_dac_hires_clk", 21) == 0 || + strncmp(name, "aud_ul1_adc_hires_clk", 21) == 0) + dai_id = MT8196_DAI_ADDA_CH34; + else + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_UL_RATE_48K; + } +} + +#ifdef MTKAIF4 +static unsigned int mtkaif_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_MTKAIF_RATE_8K; + case 11025: + return MTK_AFE_MTKAIF_RATE_11K; + case 12000: + return MTK_AFE_MTKAIF_RATE_12K; + case 16000: + return MTK_AFE_MTKAIF_RATE_16K; + case 22050: + return MTK_AFE_MTKAIF_RATE_22K; + case 24000: + return MTK_AFE_MTKAIF_RATE_24K; + case 32000: + return MTK_AFE_MTKAIF_RATE_32K; + case 44100: + return MTK_AFE_MTKAIF_RATE_44K; + case 48000: + return MTK_AFE_MTKAIF_RATE_48K; + case 96000: + return MTK_AFE_MTKAIF_RATE_96K; + case 192000: + return MTK_AFE_MTKAIF_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_MTKAIF_RATE_48K; + } +} +#endif + +/* dai component */ +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN014_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN014_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN014_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN014_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN014_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN014_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN014_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN014_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN014_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN014_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN014_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN014_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN014_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN014_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN014_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN014_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN014_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN014_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN014_6, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN014_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN015_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN015_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN015_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN015_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN015_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN015_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN015_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN015_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN015_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN015_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN015_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN015_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN015_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN015_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN015_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN015_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN015_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN015_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN015_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN015_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN015_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN015_6, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN015_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN016_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN016_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN016_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN016_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN016_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN016_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN016_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN016_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN016_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN016_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN016_1, I_DL_24CH_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN016_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN016_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN016_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN016_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN016_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN016_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN016_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN016_6, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN016_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN017_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN017_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN017_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN017_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN017_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN017_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN017_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN017_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN017_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN017_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN017_1, I_DL_24CH_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN017_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN017_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN017_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN017_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN017_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN017_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN017_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN017_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN017_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN017_6, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN017_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_stf_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN012_0, + I_ADDA_UL_CH1, 1, 0), +}; + +// Luke: dummy BE for codec fail +static const char * const adda_mux_map[] = { + "Normal", "Dummy_Widget", +}; +static int adda_mux_map_value[] = { + 0, 1, +}; +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(adda_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + adda_mux_map, + adda_mux_map_value); +static const struct snd_kcontrol_new adda_out_mux_control = + SOC_DAPM_ENUM("ADDA Out Select", adda_mux_map_enum); +static const struct snd_kcontrol_new adda_in_mux_control = + SOC_DAPM_ENUM("ADDA In Select", adda_mux_map_enum); +// Luke: dummy BE for codec fail + + +enum { + SUPPLY_SEQ_ADDA_AFE_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_FIFO, + SUPPLY_SEQ_ADDA_AP_DMIC, + SUPPLY_SEQ_ADDA_UL_ON, +}; + +static int mtk_adda_ul_src_dmic_phase_sync(struct mtk_base_afe *afe) +{ + dev_info(afe->dev, "%s() set dmic phase sync\n", __func__); + // ul0~1 + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + UL0_PHASE_SYNC_HCLK_SET_MASK_SFT, + 0x1 << UL0_PHASE_SYNC_HCLK_SET_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + UL0_PHASE_SYNC_FCLK_SET_MASK_SFT, + 0x1 << UL0_PHASE_SYNC_FCLK_SET_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + UL1_PHASE_SYNC_HCLK_SET_MASK_SFT, + 0x1 << UL1_PHASE_SYNC_HCLK_SET_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + UL1_PHASE_SYNC_FCLK_SET_MASK_SFT, + 0x1 << UL1_PHASE_SYNC_FCLK_SET_SFT); + // dmic 0 + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + DMIC0_PHASE_SYNC_FCLK_SET_MASK_SFT, + 0x1 << DMIC0_PHASE_SYNC_FCLK_SET_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + DMIC0_PHASE_SYNC_HCLK_SET_MASK_SFT, + 0x1 << DMIC0_PHASE_SYNC_HCLK_SET_SFT); + // dmic 1 + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + DMIC1_PHASE_SYNC_FCLK_SET_MASK_SFT, + 0x1 << DMIC1_PHASE_SYNC_FCLK_SET_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + DMIC1_PHASE_SYNC_HCLK_SET_MASK_SFT, + 0x1 << DMIC1_PHASE_SYNC_HCLK_SET_SFT); + // ul0~1 phase sync clock + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + DMIC1_PHASE_HCLK_SEL_MASK_SFT, + 0x1 << DMIC1_PHASE_HCLK_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + DMIC1_PHASE_FCLK_SEL_MASK_SFT, + 0x1 << DMIC1_PHASE_FCLK_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + DMIC0_PHASE_HCLK_SEL_MASK_SFT, + 0x1 << DMIC0_PHASE_HCLK_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + DMIC0_PHASE_FCLK_SEL_MASK_SFT, + 0x1 << DMIC0_PHASE_FCLK_SEL_SFT); + // dmic 0 + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL1_PHASE_HCLK_SEL_MASK_SFT, + 0x2 << UL1_PHASE_HCLK_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL1_PHASE_FCLK_SEL_MASK_SFT, + 0x2 << UL1_PHASE_FCLK_SEL_SFT); + // dmic 1 + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL0_PHASE_HCLK_SEL_MASK_SFT, + 0x2 << UL0_PHASE_HCLK_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL0_PHASE_FCLK_SEL_MASK_SFT, + 0x2 << UL0_PHASE_FCLK_SEL_SFT); + + return 0; +} + +static int mtk_adda_ul_src_dmic_phase_sync_clock(struct mtk_base_afe *afe) +{ + dev_info(afe->dev, "%s(), dmic turn on phase sync clk\n", __func__); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL_PHASE_SYNC_HCLK_1_ON_MASK_SFT, + 0x1 << UL_PHASE_SYNC_HCLK_1_ON_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL_PHASE_SYNC_HCLK_0_ON_MASK_SFT, + 0x1 << UL_PHASE_SYNC_HCLK_0_ON_SFT); + + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL_PHASE_SYNC_FCLK_1_ON_MASK_SFT, + 0x1 << UL_PHASE_SYNC_FCLK_1_ON_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON0, + UL_PHASE_SYNC_FCLK_0_ON_MASK_SFT, + 0x1 << UL_PHASE_SYNC_FCLK_0_ON_SFT); + + return 0; +} + +static int mtk_adda_ul_src_dmic(struct mtk_base_afe *afe, int id) +{ + unsigned int reg_con0 = 0, reg_con1 = 0; + + dev_info(afe->dev, "%s(), id: %d\n", __func__, id); + + switch (id) { + case MT8196_DAI_ADDA: + case MT8196_DAI_AP_DMIC: + reg_con0 = AFE_ADDA_UL0_SRC_CON0; + reg_con1 = AFE_ADDA_UL0_SRC_CON1; + break; + case MT8196_DAI_ADDA_CH34: + case MT8196_DAI_AP_DMIC_CH34: + reg_con0 = AFE_ADDA_UL1_SRC_CON0; + reg_con1 = AFE_ADDA_UL1_SRC_CON1; + break; + default: + return -EINVAL; + } + + switch (id) { + case MT8196_DAI_AP_DMIC: + dev_info(afe->dev, "%s(), clear mtkaifv4 ul ch1ch2 mux\n", __func__); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_UL_CH1CH2_IN_EN_SEL_SFT); + break; + case MT8196_DAI_AP_DMIC_CH34: + dev_info(afe->dev, "%s(), clear mtkaifv4 ul ch3ch4 mux\n", __func__); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_UL_CH3CH4_IN_EN_SEL_SFT); + break; + default: + return -EINVAL; + } + + /* choose Phase */ + regmap_update_bits(afe->regmap, reg_con0, + UL_DMIC_PHASE_SEL_CH1_MASK_SFT, + 0x0 << UL_DMIC_PHASE_SEL_CH1_SFT); + regmap_update_bits(afe->regmap, reg_con0, + UL_DMIC_PHASE_SEL_CH2_MASK_SFT, + 0x4 << UL_DMIC_PHASE_SEL_CH2_SFT); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, reg_con0, + DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT, + 0x0); + regmap_update_bits(afe->regmap, reg_con0, + DMIC_LOW_POWER_MODE_CTL_MASK_SFT, + 0x0); + + /* turn on dmic, ch1, ch2 */ + regmap_update_bits(afe->regmap, reg_con0, + UL_SDM_3_LEVEL_CTL_MASK_SFT, + 0x1 << UL_SDM_3_LEVEL_CTL_SFT); + regmap_update_bits(afe->regmap, reg_con0, + UL_MODE_3P25M_CH1_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH1_CTL_SFT); + regmap_update_bits(afe->regmap, reg_con0, + UL_MODE_3P25M_CH2_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH2_CTL_SFT); + + /* ul gain: gain = 0x7fff/positive_gain = 0x0/gain_mode = 0x10 */ + regmap_update_bits(afe->regmap, reg_con1, + ADDA_UL_GAIN_VALUE_MASK_SFT, + 0x7fff << ADDA_UL_GAIN_VALUE_SFT); + regmap_update_bits(afe->regmap, reg_con1, + ADDA_UL_POSTIVEGAIN_MASK_SFT, + 0x0 << ADDA_UL_POSTIVEGAIN_SFT); + /* gain_mode = 0x10: Add 0.5 gain at CIC output */ + regmap_update_bits(afe->regmap, reg_con1, + GAIN_MODE_MASK_SFT, + 0x02 << GAIN_MODE_SFT); + return 0; +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA, 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_RX_CFG0, + RG_MTKAIF0_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8196_DAI_ADDA); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA, 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic = 0; + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34; + int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only; + + dev_info(afe->dev, + "%s(), name %s, event 0x%x, mtkaif_dmic %d, mtkaif_adda6_only %d\n", + __func__, w->name, event, mtkaif_dmic, mtkaif_adda6_only); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA_CH34, 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG0, + RG_MTKAIF1_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8196_DAI_ADDA_CH34); + } + + /* when using adda6 without adda enabled, + * RG_ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE_SFT need to be set or + * data cannot be received. + */ + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK_SFT, + 0x1); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA_CH34, 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic_ch34 = 0; + + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK_SFT, + 0x0); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch56_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA_CH56, 1); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA_CH56, 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic = 0; + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ul_ap_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA, 1); + //mtk_adda_ul_src_dmic(afe, MT8196_DAI_AP_DMIC); + mt8196_afe_gpio_request(afe, true, MT8196_DAI_AP_DMIC, 1); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA, 1); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_AP_DMIC, 1); + + break; + default: + break; + } + + return 0; +} + + +static int mtk_adda_ch34_ul_ap_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only; + + dev_info(afe->dev, + "%s(), name %s, event 0x%x, mtkaif_adda6_only %d\n", + __func__, w->name, event, mtkaif_adda6_only); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA_CH34, 1); + mt8196_afe_gpio_request(afe, true, MT8196_DAI_AP_DMIC_CH34, 1); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA_CH34, 1); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_AP_DMIC_CH34, 1); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB8); + else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB0); + else + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB0); + break; + default: + break; + } + + return 0; +} + + +static bool is_adda_mtkaif_need_phase_delay(struct mt8196_afe_private *afe_priv) +{ + if (mt8196_afe_gpio_is_prepared(MT8196_AFE_GPIO_DAT_MISO0_ON) && + afe_priv->mtkaif_chosen_phase[0] < 0) { + return false; + } + + if (mt8196_afe_gpio_is_prepared(MT8196_AFE_GPIO_DAT_MISO1_ON) && + afe_priv->mtkaif_chosen_phase[1] < 0) { + return false; + } + + return true; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int delay_data; + int delay_cycle; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: +#ifdef MTKAIF4 + /* mtkaif_rxif_clkinv_adc inverse for calibration */ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_CFG0, + RG_MTKAIF0_RXIF_CLKINV_MASK_SFT, + 0x1 << RG_MTKAIF0_RXIF_CLKINV_SFT); + regmap_update_bits(afe->regmap, AFE_MTKAIF1_CFG0, + RG_MTKAIF1_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << RG_MTKAIF1_RXIF_CLKINV_ADC_SFT); +#endif + + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) { + /* set protocol 2 */ + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, + 0x00010000); + + /* mtkaif_rxif_clkinv_adc inverse for calibration */ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_CFG0, + RG_MTKAIF0_RXIF_CLKINV_MASK_SFT, + 0x1 << RG_MTKAIF0_RXIF_CLKINV_SFT); + regmap_update_bits(afe->regmap, AFE_MTKAIF1_CFG0, + RG_MTKAIF1_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << RG_MTKAIF1_RXIF_CLKINV_ADC_SFT); + + /* This event align the phase of every miso pin */ + /* If only 1 miso is used, there is no need to do phase delay. */ + if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0 && + !is_adda_mtkaif_need_phase_delay(afe_priv)) { + dev_info(afe->dev, + "%s(), check adda mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } + + /* set delay for ch12 to align phase of miso0 and miso1 */ + if (afe_priv->mtkaif_phase_cycle[0] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = afe_priv->mtkaif_phase_cycle[0] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[0]; + } + + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG2, + RG_MTKAIF0_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + RG_MTKAIF0_RXIF_DELAY_DATA_SFT); + + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG2, + RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + RG_MTKAIF0_RXIF_DELAY_CYCLE_SFT); + + /* set delay between ch3 and ch2 */ + if (afe_priv->mtkaif_phase_cycle[2] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; /* ch3 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[2] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; /* ch2 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[2]; + } + + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + RG_MTKAIF1_RXIF_DELAY_DATA_SFT); + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + RG_MTKAIF1_RXIF_DELAY_CYCLE_SFT); + } else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) { + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, + 0x00010000); + } else { + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, 0x0); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, 0x0); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA, 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA, 0); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, MT8196_DAI_ADDA_CH34, 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + udelay(125); + mt8196_afe_gpio_request(afe, false, MT8196_DAI_ADDA_CH34, 0); + break; + default: + break; + } + + return 0; +} + +static void mt6363_vs1_vote(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + bool pre_enable = afe_priv->is_mt6363_vote; + bool enable = false; + + if (afe_priv->pmic_regmap == NULL) + return; + enable = (afe_priv->is_adda_dl_on && afe_priv->is_adda_dl_max_vol) || + afe_priv->is_adda_ul_on || + afe_priv->is_vow_enable; + if (enable == pre_enable) { + dev_dbg(afe->dev, "%s() enable == pre_enable = %d\n", + __func__, enable); + return; + } + afe_priv->is_mt6363_vote = enable; + dev_info(afe->dev, "%s() enable = %d\n", + __func__, enable); + if (enable) { + regmap_update_bits(afe_priv->pmic_regmap, RG_BUCK_VS1_VOTER_EN_LO_SET, + VS1_MT6338_MSK, VS1_MT6338_MSK); + } else { + regmap_update_bits(afe_priv->pmic_regmap, RG_BUCK_VS1_VOTER_EN_LO_CLR, + VS1_MT6338_MSK, VS1_MT6338_MSK); + } +} + +static int mt_vs1_voter_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s(), event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + afe_priv->is_adda_dl_on = true; + mt6363_vs1_vote(afe); + break; + case SND_SOC_DAPM_POST_PMD: + afe_priv->is_adda_dl_on = false; + mt6363_vs1_vote(afe); + break; + default: + break; + } + + return 0; +} + +static int mt_vs1_voter_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s(), event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + afe_priv->is_adda_ul_on = true; + mt6363_vs1_vote(afe); + break; + case SND_SOC_DAPM_POST_PMD: + afe_priv->is_adda_ul_on = false; + mt6363_vs1_vote(afe); + break; + default: + break; + } + + return 0; +} + +/* stf */ +static int stf_positive_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->stf_positive_gain_db; + return 0; +} + +static int stf_positive_gain_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int gain_db = ucontrol->value.integer.value[0]; + + afe_priv->stf_positive_gain_db = gain_db; + + if (gain_db >= 0 && gain_db <= 24) { + regmap_update_bits(afe->regmap, + AFE_STF_GAIN, + SIDE_TONE_POSITIVE_GAIN_MASK_SFT, + (gain_db / 6) << SIDE_TONE_POSITIVE_GAIN_SFT); + } else { + dev_info(afe->dev, "%s(), gain_db %d invalid\n", + __func__, gain_db); + } + return 0; +} + +/* mtkaif dmic */ +static const char *const mt8196_adda_off_on_str[] = { + "Off", "On" +}; + +static const struct soc_enum mt8196_adda_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8196_adda_off_on_str), + mt8196_adda_off_on_str), +}; + +static int mt8196_adda_ap_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->ap_dmic; + return 0; +} + +static int mt8196_adda_ap_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int ap_dmic_on; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + ap_dmic_on = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, ap_dmic_on %d\n", + __func__, kcontrol->id.name, ap_dmic_on); + + afe_priv->ap_dmic = ap_dmic_on; + return 0; +} + +static int mt8196_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; + return 0; +} + +static int mt8196_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int dmic_on; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + dmic_on = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + afe_priv->mtkaif_dmic = dmic_on; + afe_priv->mtkaif_dmic_ch34 = dmic_on; + return 0; +} + +static int mt8196_adda6_only_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_adda6_only; + return 0; +} + +static int mt8196_adda6_only_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int mtkaif_adda6_only; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + mtkaif_adda6_only = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n", + __func__, kcontrol->id.name, mtkaif_adda6_only); + + afe_priv->mtkaif_adda6_only = mtkaif_adda6_only; + return 0; +} + +static int mt8196_adda_dl_max_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->is_adda_dl_max_vol; + + return 0; +} + +static int mt8196_adda_dl_max_vol_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + bool is_adda_dl_max_vol = ucontrol->value.integer.value[0]; + + afe_priv->is_adda_dl_max_vol = is_adda_dl_max_vol; + mt6363_vs1_vote(afe); + + return 0; +} + +static int mt8196_vow_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->is_vow_enable; + + return 0; +} + +static int mt8196_vow_enable_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + bool is_vow_enable = ucontrol->value.integer.value[0]; + + afe_priv->is_vow_enable = is_vow_enable; + mt6363_vs1_vote(afe); + + return 0; +} +static const struct snd_kcontrol_new mtk_adda_controls[] = { + SOC_SINGLE("Sidetone_Gain", AFE_STF_GAIN, + SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0), + SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 100, 0, + stf_positive_gain_get, stf_positive_gain_set), + SOC_ENUM_EXT("MTKAIF_DMIC", mt8196_adda_enum[0], + mt8196_adda_dmic_get, mt8196_adda_dmic_set), + SOC_ENUM_EXT("MTKAIF_ADDA6_ONLY", mt8196_adda_enum[0], + mt8196_adda6_only_get, mt8196_adda6_only_set), + SOC_SINGLE_EXT("ADDA_DL_MAX_VOL", + SND_SOC_NOPM, 0, 0x1, 0, + mt8196_adda_dl_max_vol_get, + mt8196_adda_dl_max_vol_set), + SOC_SINGLE_EXT("VOW_ENABLE", + SND_SOC_NOPM, 0, 0x1, 0, + mt8196_vow_enable_get, + mt8196_vow_enable_set), + SOC_ENUM_EXT("AP DMIC Used", mt8196_adda_enum[0], + mt8196_adda_ap_dmic_get, mt8196_adda_ap_dmic_set), +}; + +static const struct snd_kcontrol_new stf_ctl = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const uint16_t stf_coeff_table_16k[] = { + 0x049C, 0x09E8, 0x09E0, 0x089C, + 0xFF54, 0xF488, 0xEAFC, 0xEBAC, + 0xfA40, 0x17AC, 0x3D1C, 0x6028, + 0x7538 +}; + +static const uint16_t stf_coeff_table_32k[] = { + 0xFE52, 0x0042, 0x00C5, 0x0194, + 0x029A, 0x03B7, 0x04BF, 0x057D, + 0x05BE, 0x0555, 0x0426, 0x0230, + 0xFF92, 0xFC89, 0xF973, 0xF6C6, + 0xF500, 0xF49D, 0xF603, 0xF970, + 0xFEF3, 0x065F, 0x0F4F, 0x1928, + 0x2329, 0x2C80, 0x345E, 0x3A0D, + 0x3D08 +}; + +static const uint16_t stf_coeff_table_48k[] = { + 0x0401, 0xFFB0, 0xFF5A, 0xFECE, + 0xFE10, 0xFD28, 0xFC21, 0xFB08, + 0xF9EF, 0xF8E8, 0xF80A, 0xF76C, + 0xF724, 0xF746, 0xF7E6, 0xF90F, + 0xFACC, 0xFD1E, 0xFFFF, 0x0364, + 0x0737, 0x0B62, 0x0FC1, 0x1431, + 0x188A, 0x1CA4, 0x2056, 0x237D, + 0x25F9, 0x27B0, 0x2890 +}; + +static int mtk_stf_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + size_t half_tap_num; + const uint16_t *stf_coeff_table; + unsigned int ul_rate; + + uint32_t reg_value; + size_t coef_addr; + + regmap_read(afe->regmap, AFE_ADDA_UL0_SRC_CON0, &ul_rate); + ul_rate = ul_rate >> UL_VOICE_MODE_CH1_CH2_CTL_SFT; + ul_rate = ul_rate & UL_VOICE_MODE_CH1_CH2_CTL_MASK; + + if (ul_rate == MTK_AFE_ADDA_UL_RATE_48K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_48k); + stf_coeff_table = stf_coeff_table_48k; + } else if (ul_rate == MTK_AFE_ADDA_UL_RATE_32K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_32k); + stf_coeff_table = stf_coeff_table_32k; + } else { + half_tap_num = ARRAY_SIZE(stf_coeff_table_16k); + stf_coeff_table = stf_coeff_table_16k; + } + + regmap_read(afe->regmap, AFE_STF_CON0, ®_value); + + dev_info(afe->dev, "%s(), name %s, event 0x%x, ul_rate 0x%x, AFE_STF_CON0 0x%x\n", + __func__, w->name, event, ul_rate, reg_value); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_STF_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_STF_GAIN, + SIDE_TONE_POSITIVE_GAIN_MASK_SFT, + 0); + /* set stf half tap num */ + regmap_update_bits(afe->regmap, + AFE_STF_CON0, + SIDE_TONE_HALF_TAP_NUM_MASK_SFT, + half_tap_num << SIDE_TONE_HALF_TAP_NUM_SFT); + + /* set side tone coefficient */ + regmap_read(afe->regmap, AFE_STF_MON, ®_value); + for (coef_addr = 0; coef_addr < half_tap_num; coef_addr++) { + bool old_w_ready = (reg_value >> SIDE_TONE_W_RDY_SFT) & 0x1; + bool new_w_ready = 0; + int try_cnt = 0; + + regmap_update_bits(afe->regmap, + AFE_STF_COEFF, + 0x11FFFFF, + (1 << SIDE_TONE_COEFFICIENT_R_W_SEL_SFT) | + (coef_addr << + SIDE_TONE_COEFFICIENT_ADDR_SFT) | + stf_coeff_table[coef_addr]); + + /* wait until flag write_ready changed */ + for (try_cnt = 0; try_cnt < 10; try_cnt++) { + regmap_read(afe->regmap, + AFE_STF_MON, ®_value); + new_w_ready = (reg_value >> SIDE_TONE_W_RDY_SFT) & 0x1; + + /* flip => ok */ + if (new_w_ready == old_w_ready) { + udelay(3); + if (try_cnt == 9) { + dev_info(afe->dev, + "%s(), write coeff not ready", + __func__); + } + } else + break; + } + + /* need write -> read -> write to write next coeff */ + regmap_update_bits(afe->regmap, + AFE_STF_COEFF, + SIDE_TONE_COEFFICIENT_R_W_SEL_SFT, + 0x0); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_STF_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_STF_GAIN, + SIDE_TONE_POSITIVE_GAIN_MASK_SFT, + 0); + break; + default: + break; + } + + return 0; +} + +/* ADDA UL MUX */ +#define ADDA_UL_MUX_MASK 0x3 +enum { + ADDA_UL_MUX_MTKAIF = 0, + ADDA_UL_MUX_AP_DMIC, + ADDA_UL_MUX_AP_DMIC_MULTICH, +}; + +static const char *const adda_ul_mux_map[] = { + "MTKAIF", "AP_DMIC", "AP_DMIC_MULTI_CH", +}; + +static int adda_ul_map_value[] = { + ADDA_UL_MUX_MTKAIF, + ADDA_UL_MUX_AP_DMIC, + ADDA_UL_MUX_AP_DMIC_MULTICH, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(adda_ul_mux_map_enum, + SND_SOC_NOPM, + 0, + ADDA_UL_MUX_MASK, + adda_ul_mux_map, + adda_ul_map_value); + +static const struct snd_kcontrol_new adda_ul_mux_control = + SOC_DAPM_ENUM("ADDA_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_kcontrol_new adda_ch34_ul_mux_control = + SOC_DAPM_ENUM("ADDA_CH34_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_kcontrol_new adda_ch56_ul_mux_control = + SOC_DAPM_ENUM("ADDA_CH56_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), + + SND_SOC_DAPM_MIXER("ADDA_DL_CH3", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch3_mix, + ARRAY_SIZE(mtk_adda_dl_ch3_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH4", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch4_mix, + ARRAY_SIZE(mtk_adda_dl_ch4_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AUDIO_ENGEN_CON0, AUDIO_F3P25M_EN_ON_SFT, 0, + NULL, 0), + + /*AFE_ADDA_MTKAIFV4_TX_CFG0 control by PAD_CLK*/ + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + SND_SOC_NOPM, + 0, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Playback Enable", + SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA6_MTKAIFV4_TX_CFG0, + ADDA6_MTKAIFV4_TXIF_AFE_ON_SFT, 0, + mtk_adda_ch34_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL0_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL1_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ch34_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH56 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL1_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ch56_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + AFE_AUD_PAD_TOP_CFG0, + RG_RX_FIFO_ON_SFT, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_CLK", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_TXIF_AFE_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIFV4_RX", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_AFE_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA6_MTKAIFV4_RX", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_AFE_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA6_MTKAIF_CFG", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA7_MTKAIF_CFG", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_UL0_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + mtk_adda_ul_ap_dmic_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_CH34_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_UL1_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + mtk_adda_ch34_ul_ap_dmic_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL0_SRC_CON1, + FIFO_SOFT_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_CH34_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL1_SRC_CON1, + FIFO_SOFT_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("VS1_VOTER_DL", SUPPLY_SEQ_ADDA_AFE_ON, + SND_SOC_NOPM, 0, 0, + mt_vs1_voter_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VS1_VOTER_UL", SUPPLY_SEQ_ADDA_AFE_ON, + SND_SOC_NOPM, 0, 0, + mt_vs1_voter_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ADDA_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ul_mux_control), + SND_SOC_DAPM_MUX("ADDA_CH34_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ch34_ul_mux_control), + SND_SOC_DAPM_MUX("ADDA_CH56_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ch56_ul_mux_control), + + SND_SOC_DAPM_INPUT("AP_DMIC_INPUT"), + SND_SOC_DAPM_INPUT("AP_DMIC_CH34_INPUT"), + + /* stf */ + SND_SOC_DAPM_SWITCH_E("Sidetone Filter", + AFE_STF_CON0, SIDE_TONE_ON_SFT, 0, + &stf_ctl, + mtk_stf_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("STF_CH1", SND_SOC_NOPM, 0, 0, + mtk_stf_ch1_mix, + ARRAY_SIZE(mtk_stf_ch1_mix)), + SND_SOC_DAPM_OUTPUT("STF_OUTPUT"), + + /* allow i2s on without codec on */ + SND_SOC_DAPM_OUTPUT("ADDA_DUMMY_OUT"), + SND_SOC_DAPM_MUX("ADDA_Out_Mux", + SND_SOC_NOPM, 0, 0, &adda_out_mux_control), + SND_SOC_DAPM_INPUT("ADDA_DUMMY_IN"), + SND_SOC_DAPM_MUX("ADDA_In_Mux", + SND_SOC_NOPM, 0, 0, &adda_in_mux_control), + + /* clock */ + SND_SOC_DAPM_CLOCK_SUPPLY("vlp_mux_audio_h"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_ul0_adc_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_ul0_adc_hires_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_ul1_adc_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_ul1_adc_hires_clk"), +}; + +#define HIRES_THRESHOLD 48000 +static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_adda_priv *adda_priv; + + adda_priv = get_adda_priv_by_name(afe, w->name); + + if (!adda_priv) { + AUDIO_AEE("adda_priv == NULL"); + return 0; + } + + return (adda_priv->ul_rate > HIRES_THRESHOLD) ? 1 : 0; +} + +static int mtk_afe_record_miso1(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + return (afe_priv->audio_r_miso1_enable) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + /* playback */ + {"ADDA_DL_CH1", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH2", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH2", "DL0_CH2", "DL0"}, + + {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH1", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH2", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH1", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH2", "DL5_CH2", "DL5"}, + + {"ADDA_DL_CH1", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH2", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH1", "DL7_CH1", "DL7"}, + {"ADDA_DL_CH2", "DL7_CH2", "DL7"}, + + {"ADDA_DL_CH1", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH2", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"ADDA_DL_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"ADDA_DL_CH1", "DL24_CH1", "DL24"}, + {"ADDA_DL_CH2", "DL24_CH2", "DL24"}, + + {"ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"ADDA Playback", NULL, "ADDA_DL_CH2"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + {"ADDA Playback", NULL, "AUD_PAD_CLK"}, + {"ADDA Playback", NULL, "AUD_PAD_TOP"}, + {"ADDA Playback", NULL, "VS1_VOTER_DL"}, + + {"ADDA_DL_CH3", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH4", "DL0_CH2", "DL0"}, + + {"ADDA_DL_CH3", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH3", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH3", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH3", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH4", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH3", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH4", "DL5_CH2", "DL5"}, + + {"ADDA_DL_CH3", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH4", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH3", "DL7_CH1", "DL7"}, + {"ADDA_DL_CH4", "DL7_CH2", "DL7"}, + + {"ADDA_DL_CH3", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH4", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH3", "DL_24CH_CH1", "DL_24CH"}, + {"ADDA_DL_CH4", "DL_24CH_CH2", "DL_24CH"}, + {"ADDA_DL_CH3", "DL_24CH_CH3", "DL_24CH"}, + {"ADDA_DL_CH4", "DL_24CH_CH4", "DL_24CH"}, + + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH3"}, + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH4"}, + + {"ADDA CH34 Playback", NULL, "ADDA Enable"}, + {"ADDA CH34 Playback", NULL, "ADDA CH34 Playback Enable"}, + {"ADDA CH34 Playback", NULL, "AUD_PAD_CLK"}, + {"ADDA CH34 Playback", NULL, "AUD_PAD_TOP"}, + {"ADDA CH34 Playback", NULL, "VS1_VOTER_DL"}, + + /* capture */ + {"ADDA_UL_Mux", "MTKAIF", "ADDA Capture"}, + {"ADDA_UL_Mux", "AP_DMIC", "AP DMIC Capture"}, + {"ADDA_UL_Mux", "AP_DMIC_MULTI_CH", "AP DMIC MULTICH Capture"}, + + {"ADDA_CH34_UL_Mux", "MTKAIF", "ADDA CH34 Capture"}, + {"ADDA_CH34_UL_Mux", "AP_DMIC", "AP DMIC CH34 Capture"}, + {"ADDA_CH34_UL_Mux", "AP_DMIC_MULTI_CH", "AP DMIC MULTICH Capture"}, + + {"ADDA_CH56_UL_Mux", "MTKAIF", "ADDA CH56 Capture"}, + + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "AUD_PAD_CLK"}, + {"ADDA Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA Capture", NULL, "ADDA_MTKAIFV4_RX"}, + {"ADDA Capture", NULL, "ADDA6_MTKAIFV4_RX", mtk_afe_record_miso1}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + {"ADDA Capture", NULL, "VS1_VOTER_UL"}, + + {"AP DMIC Capture", NULL, "ADDA Enable"}, + {"AP DMIC Capture", NULL, "ADDA Capture Enable"}, + {"AP DMIC Capture", NULL, "ADDA_FIFO"}, + {"AP DMIC Capture", NULL, "AP_DMIC_EN"}, + + {"ADDA CH34 Capture", NULL, "ADDA Enable"}, + {"ADDA CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"ADDA CH34 Capture", NULL, "AUD_PAD_CLK"}, + {"ADDA CH34 Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA CH34 Capture", NULL, "ADDA_MTKAIFV4_RX"}, + {"ADDA CH34 Capture", NULL, "ADDA6_MTKAIFV4_RX", mtk_afe_record_miso1}, + {"ADDA CH34 Capture", NULL, "ADDA6_MTKAIF_CFG"}, + {"ADDA CH34 Capture", NULL, "VS1_VOTER_UL"}, + + {"AP DMIC CH34 Capture", NULL, "ADDA Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA_CH34_FIFO"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_EN"}, + + {"AP DMIC MULTICH Capture", NULL, "ADDA Enable"}, + {"AP DMIC MULTICH Capture", NULL, "ADDA Capture Enable"}, + {"AP DMIC MULTICH Capture", NULL, "ADDA CH34 Capture Enable"}, + {"AP DMIC MULTICH Capture", NULL, "ADDA_FIFO"}, + {"AP DMIC MULTICH Capture", NULL, "ADDA_CH34_FIFO"}, + {"AP DMIC MULTICH Capture", NULL, "AP_DMIC_EN"}, + {"AP DMIC MULTICH Capture", NULL, "AP_DMIC_CH34_EN"}, + + {"ADDA CH56 Capture", NULL, "ADDA Enable"}, + {"ADDA CH56 Capture", NULL, "ADDA CH56 Capture Enable"}, + {"ADDA CH56 Capture", NULL, "AUD_PAD_CLK"}, + {"ADDA CH56 Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA CH56 Capture", NULL, "ADDA6_MTKAIFV4_RX"}, + {"ADDA CH56 Capture", NULL, "ADDA7_MTKAIF_CFG"}, + {"ADDA CH56 Capture", NULL, "VS1_VOTER_UL"}, + + + {"AP DMIC Capture", NULL, "AP_DMIC_INPUT"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_INPUT"}, + {"AP DMIC MULTICH Capture", NULL, "AP_DMIC_INPUT"}, + + /* sidetone filter */ + {"Sidetone Filter", "Switch", "STF_CH1"}, + + {"STF_OUTPUT", NULL, "Sidetone Filter"}, + {"ADDA Playback", NULL, "Sidetone Filter"}, + {"ADDA CH34 Playback", NULL, "Sidetone Filter"}, + + /* allow i2s on without codec on */ + {"ADDA Capture", NULL, "ADDA_In_Mux"}, + {"ADDA_In_Mux", "Dummy_Widget", "ADDA_DUMMY_IN"}, + {"ADDA_Out_Mux", "Dummy_Widget", "ADDA Playback"}, + {"ADDA_DUMMY_OUT", NULL, "ADDA_Out_Mux"}, + + /* clk */ + {"ADDA Capture Enable", NULL, "aud_ul0_adc_clk"}, + {"ADDA Capture Enable", NULL, "aud_ul0_adc_hires_clk", + mtk_afe_adc_hires_connect}, + {"ADDA CH34 Capture Enable", NULL, "aud_ul1_adc_clk"}, + {"ADDA CH34 Capture Enable", NULL, "aud_ul1_adc_hires_clk", + mtk_afe_adc_hires_connect}, + + {"aud_ul0_adc_hires_clk", NULL, "vlp_mux_audio_h"}, + {"aud_ul1_adc_hires_clk", NULL, "vlp_mux_audio_h"}, +}; + +/* dai ops */ +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + unsigned int rate = params_rate(params); +#ifdef MTKAIF4 + unsigned int mtkaif_rate = 0; +#endif + int id = dai->id; + struct mtk_afe_adda_priv *adda_priv = afe_priv->dai_priv[id]; + + dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, + id, + substream->stream, + rate); + + if (!adda_priv) { + AUDIO_AEE("adda_priv == NULL"); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + + adda_priv->dl_rate = rate; + +#ifdef MTKAIF4 + /* get mtkaif dl rate */ + mtkaif_rate = + mtkaif_rate_transform(afe, adda_priv->dl_rate); +#endif + if (id == MT8196_DAI_ADDA) { +#ifdef MTKAIF4 + /* MTKAIF sample rate config */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << MTKAIFV4_TXIF_INPUT_MODE_SFT); + /* AFE_ADDA_MTKAIFV4_TX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT, + 0x0 << MTKAIFV4_TXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_ADDA_OUT_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_ADDA_OUT_EN_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_ADDA6_OUT_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_ADDA6_OUT_EN_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_TXIF_V4_MASK_SFT, + 0x1 << MTKAIFV4_TXIF_V4_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_TX_CFG0, + MTKAIFV4_TXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_TXIF_EN_SEL_SFT); +#endif + /* clean predistortion */ + } else { +#ifdef MTKAIF4 + /* MTKAIF sample rate config */ + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_TX_CFG0, + ADDA6_MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << ADDA6_MTKAIFV4_TXIF_INPUT_MODE_SFT); + /* AFE_ADDA6_MTKAIFV4_TX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_TX_CFG0, + ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT, + 0x0 << ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_TX_CFG0, + ADDA6_MTKAIFV4_TXIF_EN_SEL_MASK_SFT, + 0x1 << ADDA6_MTKAIFV4_TXIF_EN_SEL_SFT); +#endif + } + } else { + unsigned int voice_mode = 0; + unsigned int ul_src_con0 = 0; /* default value */ + + adda_priv->ul_rate = rate; + +#ifdef MTKAIF4 + /* get mtkaif dl rate */ + mtkaif_rate = + mtkaif_rate_transform(afe, adda_priv->ul_rate); +#endif + + voice_mode = adda_ul_rate_transform(afe, rate); + + ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); + + /* enable iir */ + ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & + UL_IIR_ON_TMP_CTL_MASK_SFT; + ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) & + UL_IIRMODE_CTL_MASK_SFT; + + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << MTKAIFV4_RXIF_INPUT_MODE_SFT); + + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << ADDA6_MTKAIFV4_RXIF_INPUT_MODE_SFT); + + switch (id) { + case MT8196_DAI_ADDA: + case MT8196_DAI_AP_DMIC: + case MT8196_DAI_AP_DMIC_MULTICH: +#ifdef MTKAIF4 + if (afe_priv->audio_r_miso1_enable == 1) { + /* AFE_ADDA_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x0 << MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_RXIF_EN_SEL_SFT); + + /* AFE_ADDA6_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x1 << ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x1 << ADDA6_MTKAIFV4_RXIF_EN_SEL_SFT); + } else { + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << MTKAIFV4_RXIF_INPUT_MODE_SFT); + /* AFE_ADDA_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x1 << MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_RXIF_EN_SEL_SFT); + /* [28] loopback mode + * 0: loopback adda tx to adda rx + * 1: loopback adda6 tx to adda rx + */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_TXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_TXIF_EN_SEL_SFT); + } + + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_UL_CH1CH2_IN_EN_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_UL_CH3CH4_IN_EN_SEL_SFT); +#endif + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL1_SRC_CON0, ul_src_con0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL0_SRC_CON0, ul_src_con0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + break; + case MT8196_DAI_ADDA_CH34: + case MT8196_DAI_AP_DMIC_CH34: +#ifdef MTKAIF4 + if (afe_priv->audio_r_miso1_enable == 0) { + /* AFE_ADDA_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x1 << MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_RXIF_EN_SEL_SFT); + } + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_UL_CH1CH2_IN_EN_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_UL_CH3CH4_IN_EN_SEL_SFT); + +#endif + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL1_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL1_SRC_CON0, ul_src_con0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + + break; + case MT8196_DAI_ADDA_CH56: + if (afe_priv->audio_r_miso1_enable == 1) { + /* AFE_ADDA_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x1 << MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_RXIF_EN_SEL_SFT); + /* [28] loopback mode + * 0: loopback adda tx to adda rx + * 1: loopback adda6 tx to adda rx + */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_TXIF_EN_SEL_MASK_SFT, + 0x0 << MTKAIFV4_TXIF_EN_SEL_SFT); + } + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT, + mtkaif_rate << ADDA6_MTKAIFV4_RXIF_INPUT_MODE_SFT); + /* AFE_ADDA6_MTKAIFV4_RX_CFG0 */ + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT, + 0x1 << ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIFV4_RX_CFG0, + MTKAIFV4_UL_CH5CH6_IN_EN_SEL_MASK_SFT, + 0x1 << MTKAIFV4_UL_CH5CH6_IN_EN_SEL_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIFV4_RX_CFG0, + ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK_SFT, + 0x1 << ADDA6_MTKAIFV4_RXIF_EN_SEL_SFT); + break; + default: + break; + } + + /* ap dmic */ + switch (id) { + case MT8196_DAI_AP_DMIC: + case MT8196_DAI_AP_DMIC_CH34: + mtk_adda_ul_src_dmic(afe, id); + break; + case MT8196_DAI_AP_DMIC_MULTICH: + regmap_update_bits(afe->regmap, AFE_ADDA_ULSRC_PHASE_CON1, + DMIC_CLK_PHASE_SYNC_SET_MASK_SFT, + 0x1 << DMIC_CLK_PHASE_SYNC_SET_SFT); + mtk_adda_ul_src_dmic_phase_sync(afe); + mtk_adda_ul_src_dmic(afe, MT8196_DAI_AP_DMIC); + mtk_adda_ul_src_dmic(afe, MT8196_DAI_AP_DMIC_CH34); + mtk_adda_ul_src_dmic_phase_sync_clock(afe); + break; + default: + break; + } + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "ADDA", + .id = MT8196_DAI_ADDA, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "ADDA_CH34", + .id = MT8196_DAI_ADDA_CH34, + .playback = { + .stream_name = "ADDA CH34 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "ADDA_CH56", + .id = MT8196_DAI_ADDA_CH56, + .capture = { + .stream_name = "ADDA CH56 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC", + .id = MT8196_DAI_AP_DMIC, + .capture = { + .stream_name = "AP DMIC Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC_CH34", + .id = MT8196_DAI_AP_DMIC_CH34, + .capture = { + .stream_name = "AP DMIC CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC_MULTICH", + .id = MT8196_DAI_AP_DMIC_MULTICH, + .capture = { + .stream_name = "AP DMIC MULTICH Capture", + .channels_min = 1, + .channels_max = 4, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +int mt8196_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int ret; + + dev_info(afe->dev, "%s() successfully start\n", __func__); + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + + dai->controls = mtk_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_adda_controls); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + + /* set dai priv */ + ret = mt8196_dai_set_priv(afe, MT8196_DAI_ADDA, + sizeof(struct mtk_afe_adda_priv), NULL); + if (ret) + return ret; + + ret = mt8196_dai_set_priv(afe, MT8196_DAI_ADDA_CH34, + sizeof(struct mtk_afe_adda_priv), NULL); + if (ret) + return ret; + + ret = mt8196_dai_set_priv(afe, MT8196_DAI_ADDA_CH56, + sizeof(struct mtk_afe_adda_priv), NULL); + if (ret) + return ret; + + ret = mt8196_dai_set_priv(afe, MT8196_DAI_AP_DMIC_MULTICH, + sizeof(struct mtk_afe_adda_priv), NULL); + if (ret) + return ret; + + /* get ap mic type */ + ret = of_property_read_u32(afe->dev->of_node, "mediatek,ap-dmic", + &afe_priv->ap_dmic); + if (ret) + afe_priv->ap_dmic = 0; + + + /* ap dmic priv share with adda */ + afe_priv->dai_priv[MT8196_DAI_AP_DMIC] = + afe_priv->dai_priv[MT8196_DAI_ADDA]; + afe_priv->dai_priv[MT8196_DAI_AP_DMIC_CH34] = + afe_priv->dai_priv[MT8196_DAI_ADDA_CH34]; + + return 0; +} + diff --git a/sound/soc/mediatek/mt8196/mt8196-dai-i2s.c b/sound/soc/mediatek/mt8196/mt8196-dai-i2s.c new file mode 100644 index 0000000000000..04a5e9b167f83 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-dai-i2s.c @@ -0,0 +1,4371 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI I2S Control + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include "mt8196-afe-clk.h" +#include "mt8196-afe-common.h" +#include "mt8196-afe-gpio.h" +#include "mt8196-interconnection.h" +#include "mtk-afe-fe-dai.h" + +#define ETDM_22M_CLOCK_THRES 11289600 + +#define FM_SRC_CAIL +enum { + ETDM_CLK_SOURCE_H26M = 0, + ETDM_CLK_SOURCE_APLL = 1, + ETDM_CLK_SOURCE_SPDIF = 2, + ETDM_CLK_SOURCE_HDMI = 3, + ETDM_CLK_SOURCE_EARC = 4, + ETDM_CLK_SOURCE_LINEIN = 5, +}; +enum { + ETDM_RELATCH_SEL_H26M = 0, + ETDM_RELATCH_SEL_APLL = 1, +}; +enum { + ETDM_RATE_8K = 0, + ETDM_RATE_12K = 1, + ETDM_RATE_16K = 2, + ETDM_RATE_24K = 3, + ETDM_RATE_32K = 4, + ETDM_RATE_48K = 5, + ETDM_RATE_64K = 6, //not support + ETDM_RATE_96K = 7, + ETDM_RATE_128K = 8, //not support + ETDM_RATE_192K = 9, + ETDM_RATE_256K = 10, //not support + ETDM_RATE_384K = 11, + ETDM_RATE_11025 = 16, + ETDM_RATE_22050 = 17, + ETDM_RATE_44100 = 18, + ETDM_RATE_88200 = 19, + ETDM_RATE_176400 = 20, + ETDM_RATE_352800 = 21, +}; + +enum { + ETDM_CONN_8K = 0, + ETDM_CONN_11K = 1, + ETDM_CONN_12K = 2, + ETDM_CONN_16K = 4, + ETDM_CONN_22K = 5, + ETDM_CONN_24K = 6, + ETDM_CONN_32K = 8, + ETDM_CONN_44K = 9, + ETDM_CONN_48K = 10, + ETDM_CONN_88K = 13, + ETDM_CONN_96K = 14, + ETDM_CONN_176K = 17, + ETDM_CONN_192K = 18, + ETDM_CONN_352K = 21, + ETDM_CONN_384K = 22, +}; +enum { + ETDM_WLEN_8_BIT = 0x7, + ETDM_WLEN_16_BIT = 0xf, + ETDM_WLEN_32_BIT = 0x1f, +}; +enum { + ETDM_SLAVE_SEL_ETDMIN0_MASTER = 0, + ETDM_SLAVE_SEL_ETDMIN0_SLAVE = 1, + ETDM_SLAVE_SEL_ETDMIN1_MASTER = 2, + ETDM_SLAVE_SEL_ETDMIN1_SLAVE = 3, + ETDM_SLAVE_SEL_ETDMIN2_MASTER = 4, + ETDM_SLAVE_SEL_ETDMIN2_SLAVE = 5, + ETDM_SLAVE_SEL_ETDMIN3_MASTER = 6, + ETDM_SLAVE_SEL_ETDMIN3_SLAVE = 7, + ETDM_SLAVE_SEL_ETDMOUT0_MASTER = 8, + ETDM_SLAVE_SEL_ETDMOUT0_SLAVE = 9, + ETDM_SLAVE_SEL_ETDMOUT1_MASTER = 10, + ETDM_SLAVE_SEL_ETDMOUT1_SLAVE = 11, + ETDM_SLAVE_SEL_ETDMOUT2_MASTER = 12, + ETDM_SLAVE_SEL_ETDMOUT2_SLAVE = 13, + ETDM_SLAVE_SEL_ETDMOUT3_MASTER = 14, + ETDM_SLAVE_SEL_ETDMOUT3_SLAVE = 15, +}; + +enum { + ETDM_SLAVE_SEL_ETDMIN4_MASTER = 0, + ETDM_SLAVE_SEL_ETDMIN4_SLAVE = 1, + ETDM_SLAVE_SEL_ETDMIN5_MASTER = 2, + ETDM_SLAVE_SEL_ETDMIN5_SLAVE = 3, + ETDM_SLAVE_SEL_ETDMIN6_MASTER = 4, + ETDM_SLAVE_SEL_ETDMIN6_SLAVE = 5, + ETDM_SLAVE_SEL_ETDMIN7_MASTER = 6, + ETDM_SLAVE_SEL_ETDMIN7_SLAVE = 7, + ETDM_SLAVE_SEL_ETDMOUT4_MASTER = 8, + ETDM_SLAVE_SEL_ETDMOUT4_SLAVE = 9, + ETDM_SLAVE_SEL_ETDMOUT5_MASTER = 10, + ETDM_SLAVE_SEL_ETDMOUT5_SLAVE = 11, + ETDM_SLAVE_SEL_ETDMOUT6_MASTER = 12, + ETDM_SLAVE_SEL_ETDMOUT6_SLAVE = 13, + ETDM_SLAVE_SEL_ETDMOUT7_MASTER = 14, + ETDM_SLAVE_SEL_ETDMOUT7_SLAVE = 15, +}; + +enum { + MTK_DAI_ETDM_FORMAT_I2S = 0, + MTK_DAI_ETDM_FORMAT_LJ, + MTK_DAI_ETDM_FORMAT_RJ, + MTK_DAI_ETDM_FORMAT_EIAJ, + MTK_DAI_ETDM_FORMAT_DSPA, + MTK_DAI_ETDM_FORMAT_DSPB, +}; + +static unsigned int get_etdm_wlen(snd_pcm_format_t format) +{ + unsigned int wlen = 0; + + /* The reg_word_length should be >= reg_bit_length */ + wlen = snd_pcm_format_physical_width(format); + + if (wlen < 16) + return ETDM_WLEN_16_BIT; + else + return ETDM_WLEN_32_BIT; +} + +static unsigned int get_etdm_lrck_width(snd_pcm_format_t format) +{ + /* The valid data bit number should be large than 7 due to hardware limitation. */ + return snd_pcm_format_physical_width(format) - 1; + +} + +static unsigned int get_etdm_rate(unsigned int rate) +{ + switch (rate) { + case 8000: + return ETDM_RATE_8K; + case 12000: + return ETDM_RATE_12K; + case 16000: + return ETDM_RATE_16K; + case 24000: + return ETDM_RATE_24K; + case 32000: + return ETDM_RATE_32K; + case 48000: + return ETDM_RATE_48K; + case 64000: + return ETDM_RATE_64K; + case 96000: + return ETDM_RATE_96K; + case 128000: + return ETDM_RATE_128K; + case 192000: + return ETDM_RATE_192K; + case 256000: + return ETDM_RATE_256K; + case 384000: + return ETDM_RATE_384K; + case 11025: + return ETDM_RATE_11025; + case 22050: + return ETDM_RATE_22050; + case 44100: + return ETDM_RATE_44100; + case 88200: + return ETDM_RATE_88200; + case 176400: + return ETDM_RATE_176400; + case 352800: + return ETDM_RATE_352800; + default: + return 0; + } +} + +static unsigned int get_etdm_inconn_rate(unsigned int rate) +{ + switch (rate) { + case 8000: + return ETDM_CONN_8K; + case 12000: + return ETDM_CONN_12K; + case 16000: + return ETDM_CONN_16K; + case 24000: + return ETDM_CONN_24K; + case 32000: + return ETDM_CONN_32K; + case 48000: + return ETDM_CONN_48K; + case 96000: + return ETDM_CONN_96K; + case 192000: + return ETDM_CONN_192K; + case 384000: + return ETDM_CONN_384K; + case 11025: + return ETDM_CONN_11K; + case 22050: + return ETDM_CONN_22K; + case 44100: + return ETDM_CONN_44K; + case 88200: + return ETDM_CONN_88K; + case 176400: + return ETDM_CONN_176K; + case 352800: + return ETDM_CONN_352K; + default: + return 0; + } + +} + +struct mtk_afe_i2s_priv { + int id; + int rate; /* for determine which apll to use */ + int low_jitter_en; + + const char *share_property_name; + int share_i2s_id; + + int mclk_id; + int mclk_rate; + int mclk_apll; + + int ch_num; + int sync; + int ip_mode; + int lpbk_mode; + unsigned int format; +}; + +/* this enum is merely for mtk_afe_i2s_priv & mtk_base_etdm_data declare */ +enum { + DAI_I2SIN0 = 0, + DAI_I2SIN1, + DAI_I2SIN2, + DAI_I2SIN3, + DAI_I2SIN4, + DAI_I2SIN6, + DAI_I2SOUT0, + DAI_I2SOUT1, + DAI_I2SOUT2, + DAI_I2SOUT3, + DAI_I2SOUT4, + DAI_I2SOUT6, + DAI_FMI2S_MASTER, + DAI_I2S_NUM, +}; + +static bool is_etdm_in_pad_top(unsigned int dai_num) +{ + if (dai_num >= DAI_I2S_NUM) + return false; + + switch (dai_num) { + case DAI_I2SOUT4: + case DAI_I2SIN4: + return true; + default: + return false; + } +} + +struct mtk_base_etdm_data { + int enable_reg; + int enable_mask; + int enable_shift; + int sync_reg; + int sync_mask; + int sync_shift; + int ch_reg; + int ch_mask; + int ch_shift; + int ip_mode_reg; + int ip_mode_mask; + int ip_mode_shift; + int init_count_reg; + int init_count_mask; + int init_count_shift; + int init_point_reg; + int init_point_mask; + int init_point_shift; + int lrck_reset_reg; + int lrck_reset_mask; + int lrck_reset_shift; + int clk_source_reg; + int clk_source_mask; + int clk_source_shift; + int ck_en_sel_reg; + int ck_en_sel_mask; + int ck_en_sel_shift; + int fs_timing_reg; + int fs_timing_mask; + int fs_timing_shift; + int relatch_en_sel_reg; + int relatch_en_sel_mask; + int relatch_en_sel_shift; + int use_afifo_reg; + int use_afifo_mask; + int use_afifo_shift; + int afifo_mode_reg; + int afifo_mode_mask; + int afifo_mode_shift; + int almost_end_ch_reg; + int almost_end_ch_mask; + int almost_end_ch_shift; + int almost_end_bit_reg; + int almost_end_bit_mask; + int almost_end_bit_shift; + int out2latch_time_reg; + int out2latch_time_mask; + int out2latch_time_shift; + int tdm_mode_reg; + int tdm_mode_mask; + int tdm_mode_shift; + int relatch_domain_sel_reg; + int relatch_domain_sel_mask; + int relatch_domain_sel_shift; + int bit_length_reg; + int bit_length_mask; + int bit_length_shift; + int word_length_reg; + int word_length_mask; + int word_length_shift; + int cowork_reg; + int cowork_mask; + int cowork_shift; + int cowork_val; + int in2latch_time_reg; + int in2latch_time_mask; + int in2latch_time_shift; + int pad_top_ck_en_reg; + int pad_top_ck_en_mask; + int pad_top_ck_en_shift; + int master_latch_reg; + int master_latch_mask; + int master_latch_shift; +}; + +const struct mtk_base_etdm_data mtk_etdm_data[DAI_I2S_NUM] = { + [DAI_I2SIN0] = { + .enable_reg = ETDM_IN0_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN0_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN0_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN0_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN0_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN0_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN0_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN0_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN0_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN0_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN0_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN0_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN0_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN0_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN0_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN0_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN0_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN0_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN0_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN0_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON0, + .cowork_mask = ETDM_IN0_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN0_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT0_MASTER, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SIN1] = { + .enable_reg = ETDM_IN1_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN1_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN1_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN1_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN1_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN1_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN1_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN1_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN1_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN1_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN1_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN1_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN1_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN1_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN1_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN1_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN1_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN1_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN1_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN1_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON1, + .cowork_mask = ETDM_IN1_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN1_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT1_MASTER, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SIN2] = { + .enable_reg = ETDM_IN2_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN2_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN2_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN2_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN2_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN2_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN2_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN2_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN2_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN2_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN2_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN2_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN2_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN2_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN2_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN2_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN2_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN2_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN2_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN2_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON2, + .cowork_mask = ETDM_IN2_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN2_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT2_MASTER, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SIN3] = { + .enable_reg = ETDM_IN3_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN3_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN3_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN3_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN3_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN3_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN3_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN3_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN3_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN3_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN3_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN3_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN3_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN3_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN3_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN3_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN3_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN3_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN3_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN3_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON3, + .cowork_mask = ETDM_IN3_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN3_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT3_MASTER, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SIN4] = { + .enable_reg = ETDM_IN4_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN4_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN4_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN4_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN4_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN4_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN4_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN4_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN4_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN4_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN4_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN4_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN4_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN4_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN4_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN4_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN4_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN4_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN4_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN4_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_4_7_COWORK_CON0, + .cowork_mask = ETDM_IN4_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN4_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT4_MASTER, + .pad_top_ck_en_reg = AUD_TOP_CFG_VLP_RG, + .pad_top_ck_en_mask = RG_I2S4_PAD_TOP_CK_EN_MASK, + .pad_top_ck_en_shift = RG_I2S4_PAD_TOP_CK_EN_SFT, + .master_latch_reg = AUD_TOP_CFG_VLP_RG, + .master_latch_mask = RG_I2S4_IN_BCK_NEG_EG_LATCH_MASK, + .master_latch_shift = RG_I2S4_IN_BCK_NEG_EG_LATCH_SFT, + }, + [DAI_I2SIN6] = { + .enable_reg = ETDM_IN6_CON0, + .enable_mask = REG_ETDM_IN_EN_MASK, + .enable_shift = REG_ETDM_IN_EN_SFT, + .sync_reg = ETDM_IN6_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_IN6_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .ip_mode_reg = ETDM_IN6_CON2, + .ip_mode_mask = REG_MULTI_IP_MODE_MASK, + .ip_mode_shift = REG_MULTI_IP_MODE_SFT, + .init_count_reg = ETDM_IN6_CON1, + .init_count_mask = REG_INITIAL_COUNT_MASK, + .init_count_shift = REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_IN6_CON1, + .init_point_mask = REG_INITIAL_POINT_MASK, + .init_point_shift = REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_IN6_CON1, + .lrck_reset_mask = REG_LRCK_RESET_MASK, + .lrck_reset_shift = REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_IN6_CON2, + .clk_source_mask = REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = REG_CLOCK_SOURCE_SEL_SFT, + .ck_en_sel_reg = ETDM_IN6_CON2, + .ck_en_sel_mask = REG_CK_EN_SEL_AUTO_MASK, + .ck_en_sel_shift = REG_CK_EN_SEL_AUTO_SFT, + .fs_timing_reg = ETDM_IN6_CON3, + .fs_timing_mask = REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_IN6_CON4, + .relatch_en_sel_mask = REG_RELATCH_1X_EN_SEL_MASK, + .relatch_en_sel_shift = REG_RELATCH_1X_EN_SEL_SFT, + .use_afifo_reg = ETDM_IN6_CON8, + .use_afifo_mask = REG_ETDM_USE_AFIFO_MASK, + .use_afifo_shift = REG_ETDM_USE_AFIFO_SFT, + .afifo_mode_reg = ETDM_IN6_CON8, + .afifo_mode_mask = REG_AFIFO_MODE_MASK, + .afifo_mode_shift = REG_AFIFO_MODE_SFT, + .almost_end_ch_reg = ETDM_IN6_CON9, + .almost_end_ch_mask = REG_ALMOST_END_CH_COUNT_MASK, + .almost_end_ch_shift = REG_ALMOST_END_CH_COUNT_SFT, + .almost_end_bit_reg = ETDM_IN6_CON9, + .almost_end_bit_mask = REG_ALMOST_END_BIT_COUNT_MASK, + .almost_end_bit_shift = REG_ALMOST_END_BIT_COUNT_SFT, + .out2latch_time_reg = ETDM_IN6_CON9, + .out2latch_time_mask = REG_OUT2LATCH_TIME_MASK, + .out2latch_time_shift = REG_OUT2LATCH_TIME_SFT, + .tdm_mode_reg = ETDM_IN6_CON0, + .tdm_mode_mask = REG_FMT_MASK, + .tdm_mode_shift = REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_IN6_CON0, + .relatch_domain_sel_mask = REG_RELATCH_1X_EN_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = REG_RELATCH_1X_EN_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_IN6_CON0, + .bit_length_mask = REG_BIT_LENGTH_MASK, + .bit_length_shift = REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_IN6_CON0, + .word_length_mask = REG_WORD_LENGTH_MASK, + .word_length_shift = REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_4_7_COWORK_CON2, + .cowork_mask = ETDM_IN6_SLAVE_SEL_MASK, + .cowork_shift = ETDM_IN6_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMOUT6_MASTER, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SOUT0] = { + .enable_reg = ETDM_OUT0_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT0_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT0_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT0_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT0_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT0_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT0_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT0_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT0_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT0_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT0_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT0_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT0_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON0, + .cowork_mask = ETDM_OUT0_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT0_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN0_MASTER, + .in2latch_time_reg = ETDM_OUT0_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SOUT1] = { + .enable_reg = ETDM_OUT1_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT1_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT1_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT1_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT1_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT1_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT1_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT1_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT1_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT1_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT1_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT1_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT1_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON0, + .cowork_mask = ETDM_OUT1_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT1_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN1_MASTER, + .in2latch_time_reg = ETDM_OUT1_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SOUT2] = { + .enable_reg = ETDM_OUT2_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT2_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT2_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT2_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT2_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT2_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT2_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT2_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT2_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT2_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT2_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT2_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT2_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON2, + .cowork_mask = ETDM_OUT2_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT2_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN2_MASTER, + .in2latch_time_reg = ETDM_OUT2_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SOUT3] = { + .enable_reg = ETDM_OUT3_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT3_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT3_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT3_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT3_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT3_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT3_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT3_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT3_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT3_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT3_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT3_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT3_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_0_3_COWORK_CON2, + .cowork_mask = ETDM_OUT3_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT3_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN3_MASTER, + .in2latch_time_reg = ETDM_OUT3_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + [DAI_I2SOUT4] = { + .enable_reg = ETDM_OUT4_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT4_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT4_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT4_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT4_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT4_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT4_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT4_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT4_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT4_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT4_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT4_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT4_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_4_7_COWORK_CON0, + .cowork_mask = ETDM_OUT4_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT4_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN4_MASTER, + .in2latch_time_reg = ETDM_OUT4_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = AUD_TOP_CFG_VLP_RG, + .pad_top_ck_en_mask = RG_I2S4_PAD_TOP_CK_EN_MASK, + .pad_top_ck_en_shift = RG_I2S4_PAD_TOP_CK_EN_SFT, + .master_latch_reg = AUD_TOP_CFG_VLP_RG, + .master_latch_mask = RG_I2S4_OUT_BCK_NEG_EG_LATCH_MASK, + .master_latch_shift = RG_I2S4_OUT_BCK_NEG_EG_LATCH_SFT, + }, + [DAI_I2SOUT6] = { + .enable_reg = ETDM_OUT6_CON0, + .enable_mask = OUT_REG_ETDM_OUT_EN_MASK, + .enable_shift = OUT_REG_ETDM_OUT_EN_SFT, + .sync_reg = ETDM_OUT6_CON0, + .sync_mask = REG_SYNC_MODE_MASK, + .sync_shift = REG_SYNC_MODE_SFT, + .ch_reg = ETDM_OUT6_CON0, + .ch_mask = REG_CH_NUM_MASK, + .ch_shift = REG_CH_NUM_SFT, + .init_count_reg = ETDM_OUT6_CON1, + .init_count_mask = OUT_REG_INITIAL_COUNT_MASK, + .init_count_shift = OUT_REG_INITIAL_COUNT_SFT, + .init_point_reg = ETDM_OUT6_CON1, + .init_point_mask = OUT_REG_INITIAL_POINT_MASK, + .init_point_shift = OUT_REG_INITIAL_POINT_SFT, + .lrck_reset_reg = ETDM_OUT6_CON1, + .lrck_reset_mask = OUT_REG_LRCK_RESET_MASK, + .lrck_reset_shift = OUT_REG_LRCK_RESET_SFT, + .clk_source_reg = ETDM_OUT6_CON4, + .clk_source_mask = OUT_REG_CLOCK_SOURCE_SEL_MASK, + .clk_source_shift = OUT_REG_CLOCK_SOURCE_SEL_SFT, + .fs_timing_reg = ETDM_OUT6_CON4, + .fs_timing_mask = OUT_REG_FS_TIMING_SEL_MASK, + .fs_timing_shift = OUT_REG_FS_TIMING_SEL_SFT, + .relatch_en_sel_reg = ETDM_OUT6_CON4, + .relatch_en_sel_mask = OUT_REG_RELATCH_EN_SEL_MASK, + .relatch_en_sel_shift = OUT_REG_RELATCH_EN_SEL_SFT, + .tdm_mode_reg = ETDM_OUT6_CON0, + .tdm_mode_mask = OUT_REG_FMT_MASK, + .tdm_mode_shift = OUT_REG_FMT_SFT, + .relatch_domain_sel_reg = ETDM_OUT6_CON0, + .relatch_domain_sel_mask = OUT_REG_RELATCH_DOMAIN_SEL_MASK, + .relatch_domain_sel_shift = OUT_REG_RELATCH_DOMAIN_SEL_SFT, + .bit_length_reg = ETDM_OUT6_CON0, + .bit_length_mask = OUT_REG_BIT_LENGTH_MASK, + .bit_length_shift = OUT_REG_BIT_LENGTH_SFT, + .word_length_reg = ETDM_OUT6_CON0, + .word_length_mask = OUT_REG_WORD_LENGTH_MASK, + .word_length_shift = OUT_REG_WORD_LENGTH_SFT, + .cowork_reg = ETDM_4_7_COWORK_CON2, + .cowork_mask = ETDM_OUT6_SLAVE_SEL_MASK, + .cowork_shift = ETDM_OUT6_SLAVE_SEL_SFT, + .cowork_val = ETDM_SLAVE_SEL_ETDMIN6_MASTER, + .in2latch_time_reg = ETDM_OUT6_CON2, + .in2latch_time_mask = OUT_REG_IN2LATCH_TIME_MASK, + .in2latch_time_shift = OUT_REG_IN2LATCH_TIME_SFT, + .pad_top_ck_en_reg = -1, + .master_latch_reg = -1, + }, + +}; + +/* lpbk */ +static const int etdm_lpbk_idx_0[] = { + 0x0, 0x8, +}; +static const int etdm_lpbk_idx_1[] = { + 0x2, 0xa, +}; +static const int etdm_lpbk_idx_2[] = { + 0x4, 0xc, +}; +static const int etdm_lpbk_idx_3[] = { + 0x6, 0xe, +}; + +static int etdm_lpbk_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int value = 0; + unsigned int value_ipmode = 0; + unsigned int reg = 0; + unsigned int mask = 0; + unsigned int shift = 0; + + if (!strcmp(kcontrol->id.name, "I2SIN0_LPBK")) { + reg = ETDM_0_3_COWORK_CON1; + mask = ETDM_IN0_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN0_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN1_LPBK")) { + reg = ETDM_0_3_COWORK_CON1; + mask = ETDM_IN1_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN1_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN2_LPBK")) { + reg = ETDM_0_3_COWORK_CON3; + mask = ETDM_IN2_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN2_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN3_LPBK")) { + reg = ETDM_0_3_COWORK_CON3; + mask = ETDM_IN3_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN3_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN4_LPBK")) { + reg = ETDM_4_7_COWORK_CON1; + + // Get I2SIN4 multi-ip mode + regmap_read(afe->regmap, ETDM_IN4_CON2, &value_ipmode); + value_ipmode &= REG_MULTI_IP_MODE_MASK_SFT; + value_ipmode >>= REG_MULTI_IP_MODE_SFT; + + if (value_ipmode) { + mask = ETDM_IN4_SDATA1_15_SEL_MASK_SFT; + shift = ETDM_IN4_SDATA1_15_SEL_SFT; + } else { + mask = ETDM_IN4_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN4_SDATA0_SEL_SFT; + } + } else if (!strcmp(kcontrol->id.name, "I2SIN6_LPBK")) { + reg = ETDM_4_7_COWORK_CON3; + mask = ETDM_IN6_SDATA0_SEL_MASK_SFT; + shift = ETDM_IN6_SDATA0_SEL_SFT; + } + + if (reg) + regmap_read(afe->regmap, reg, &value); + + value &= mask; + value >>= shift; + ucontrol->value.enumerated.item[0] = value; + + if (value == 0x8 || value == 0xa || value == 0xc || value == 0xe) + ucontrol->value.enumerated.item[0] = 1; + else + ucontrol->value.enumerated.item[0] = 0; + + return 0; +} + +static int etdm_lpbk_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int value = ucontrol->value.integer.value[0]; + unsigned int value_ipmode = 0; + unsigned int reg = 0; + unsigned int val = 0; + unsigned int mask = 0; + + if (value >= ARRAY_SIZE(etdm_lpbk_idx_0)) + return -EINVAL; + + if (!strcmp(kcontrol->id.name, "I2SIN0_LPBK")) { + reg = ETDM_0_3_COWORK_CON1; + mask = ETDM_IN0_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_0[value] << ETDM_IN0_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN1_LPBK")) { + reg = ETDM_0_3_COWORK_CON1; + mask = ETDM_IN1_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_1[value] << ETDM_IN1_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN2_LPBK")) { + reg = ETDM_0_3_COWORK_CON3; + mask = ETDM_IN2_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_2[value] << ETDM_IN2_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN3_LPBK")) { + reg = ETDM_0_3_COWORK_CON3; + mask = ETDM_IN3_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_3[value] << ETDM_IN3_SDATA0_SEL_SFT; + } else if (!strcmp(kcontrol->id.name, "I2SIN4_LPBK")) { + reg = ETDM_4_7_COWORK_CON1; + + // Get I2SIN4 multi-ip mode + regmap_read(afe->regmap, ETDM_IN4_CON2, &value_ipmode); + value_ipmode &= REG_MULTI_IP_MODE_MASK_SFT; + value_ipmode >>= REG_MULTI_IP_MODE_SFT; + + if (!value) { + mask = ETDM_IN4_SDATA1_15_SEL_MASK_SFT | + ETDM_IN4_SDATA0_SEL_MASK_SFT; + val = (etdm_lpbk_idx_0[value] << ETDM_IN4_SDATA1_15_SEL_SFT) | + (etdm_lpbk_idx_0[value] << ETDM_IN4_SDATA0_SEL_SFT); + } else if (value_ipmode) { + mask = ETDM_IN4_SDATA1_15_SEL_MASK_SFT; + val = etdm_lpbk_idx_0[value] << ETDM_IN4_SDATA1_15_SEL_SFT; + } else { + mask = ETDM_IN4_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_0[value] << ETDM_IN4_SDATA0_SEL_SFT; + } + } else { + reg = ETDM_4_7_COWORK_CON3; + mask = ETDM_IN6_SDATA0_SEL_MASK_SFT; + val = etdm_lpbk_idx_2[value] << ETDM_IN6_SDATA0_SEL_SFT; + } + + if (reg) + regmap_update_bits(afe->regmap, reg, mask, val); + + return 0; +} +static const char *const etdm_lpbk_map[] = { + "Off", "On", +}; +static SOC_ENUM_SINGLE_EXT_DECL(etdm_lpbk_map_enum, + etdm_lpbk_map); +/* lpbk */ + +/* multi-ip mode */ +static const int etdm_ip_mode_idx[] = { + 0x0, 0x1, +}; +static int etdm_ip_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2sin4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_IN4]; + + ucontrol->value.enumerated.item[0] = i2sin4_priv->ip_mode; + + return 0; +} + +static int etdm_ip_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2sin4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_IN4]; + unsigned int value = ucontrol->value.integer.value[0]; + + if (value >= ARRAY_SIZE(etdm_ip_mode_idx)) + return -EINVAL; + + /* 0: One IP multi-channel 1: Multi-IP 2-channel */ + i2sin4_priv->ip_mode = etdm_ip_mode_idx[value]; + + return 0; +} +static const char *const etdm_ip_mode_map[] = { + "Off", "On", +}; +static SOC_ENUM_SINGLE_EXT_DECL(etdm_ip_mode_map_enum, + etdm_ip_mode_map); +/* multi-ip mode */ + +/* ch num */ +static const int etdm_ch_num_idx[] = { + 0x2, 0x4, 0x6, 0x8, +}; +static int etdm_ch_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2sin4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_IN4]; + struct mtk_afe_i2s_priv *i2sout4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_OUT4]; + unsigned int value = 0; + + if (!strcmp(kcontrol->id.name, "I2SIN4_CH_NUM")) + value = i2sin4_priv->ch_num; + else if (!strcmp(kcontrol->id.name, "I2SOUT4_CH_NUM")) + value = i2sout4_priv->ch_num; + + if (value == 0x2) + ucontrol->value.enumerated.item[0] = 0; + else if (value == 0x4) + ucontrol->value.enumerated.item[0] = 1; + else if (value == 0x6) + ucontrol->value.enumerated.item[0] = 2; + else + ucontrol->value.enumerated.item[0] = 3; + + return 0; +} + +static int etdm_ch_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2sin4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_IN4]; + struct mtk_afe_i2s_priv *i2sout4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_OUT4]; + unsigned int value = ucontrol->value.integer.value[0]; + + if (value >= ARRAY_SIZE(etdm_ch_num_idx)) + return -EINVAL; + + if (!strcmp(kcontrol->id.name, "I2SIN4_CH_NUM")) + i2sin4_priv->ch_num = etdm_ch_num_idx[value]; + else if (!strcmp(kcontrol->id.name, "I2SOUT4_CH_NUM")) + i2sout4_priv->ch_num = etdm_ch_num_idx[value]; + + return 0; +} +static const char *const etdm_ch_num_map[] = { + "2CH", "4CH", "6CH", "8CH", +}; +static SOC_ENUM_SINGLE_EXT_DECL(etdm_ch_num_map_enum, + etdm_ch_num_map); +/* ch num */ + +enum { + I2S_FMT_EIAJ = 0, + I2S_FMT_I2S = 1, +}; + +enum { + I2S_WLEN_16_BIT = 0, + I2S_WLEN_32_BIT = 1, +}; + +enum { + I2S_HD_NORMAL = 0, + I2S_HD_LOW_JITTER = 1, +}; + +enum { + I2S1_SEL_O28_O29 = 0, + I2S1_SEL_O03_O04 = 1, +}; + +enum { + I2S_IN_PAD_CONNSYS = 0, + I2S_IN_PAD_IO_MUX = 1, +}; + +static unsigned int get_i2s_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + I2S_WLEN_16_BIT : I2S_WLEN_32_BIT; +} + +#define MTK_AFE_I2SIN0_KCONTROL_NAME "I2SIN0_HD_Mux" +#define MTK_AFE_I2SIN1_KCONTROL_NAME "I2SIN1_HD_Mux" +#define MTK_AFE_I2SIN2_KCONTROL_NAME "I2SIN2_HD_Mux" +#define MTK_AFE_I2SIN4_KCONTROL_NAME "I2SIN4_HD_Mux" +#define MTK_AFE_I2SIN6_KCONTROL_NAME "I2SIN6_HD_Mux" +#define MTK_AFE_I2SOUT0_KCONTROL_NAME "I2SOUT0_HD_Mux" +#define MTK_AFE_I2SOUT1_KCONTROL_NAME "I2SOUT1_HD_Mux" +#define MTK_AFE_I2SOUT2_KCONTROL_NAME "I2SOUT2_HD_Mux" +#define MTK_AFE_I2SOUT4_KCONTROL_NAME "I2SOUT4_HD_Mux" +#define MTK_AFE_I2SOUT6_KCONTROL_NAME "I2SOUT6_HD_Mux" +#define MTK_AFE_FMI2S_MASTER_KCONTROL_NAME "FMI2S_MASTER_HD_Mux" + +#define I2SIN0_HD_EN_W_NAME "I2SIN0_HD_EN" +#define I2SIN1_HD_EN_W_NAME "I2SIN1_HD_EN" +#define I2SIN2_HD_EN_W_NAME "I2SIN2_HD_EN" +#define I2SIN3_HD_EN_W_NAME "I2SIN3_HD_EN" +#define I2SIN4_HD_EN_W_NAME "I2SIN4_HD_EN" +#define I2SIN6_HD_EN_W_NAME "I2SIN6_HD_EN" +#define I2SOUT0_HD_EN_W_NAME "I2SOUT0_HD_EN" +#define I2SOUT1_HD_EN_W_NAME "I2SOUT1_HD_EN" +#define I2SOUT2_HD_EN_W_NAME "I2SOUT2_HD_EN" +#define I2SOUT3_HD_EN_W_NAME "I2SOUT3_HD_EN" +#define I2SOUT4_HD_EN_W_NAME "I2SOUT4_HD_EN" +#define I2SOUT6_HD_EN_W_NAME "I2SOUT6_HD_EN" +#define FMI2S_MASTER_HD_EN_W_NAME "FMI2S_MASTER_HD_EN" + +#define I2SIN0_MCLK_EN_W_NAME "I2SIN0_MCLK_EN" +#define I2SIN1_MCLK_EN_W_NAME "I2SIN1_MCLK_EN" +#define I2SIN2_MCLK_EN_W_NAME "I2SIN2_MCLK_EN" +#define I2SIN3_MCLK_EN_W_NAME "I2SIN3_MCLK_EN" +#define I2SIN4_MCLK_EN_W_NAME "I2SIN4_MCLK_EN" +#define I2SIN6_MCLK_EN_W_NAME "I2SIN6_MCLK_EN" +#define I2SOUT0_MCLK_EN_W_NAME "I2SOUT0_MCLK_EN" +#define I2SOUT1_MCLK_EN_W_NAME "I2SOUT1_MCLK_EN" +#define I2SOUT2_MCLK_EN_W_NAME "I2SOUT2_MCLK_EN" +#define I2SOUT3_MCLK_EN_W_NAME "I2SOUT3_MCLK_EN" +#define I2SOUT4_MCLK_EN_W_NAME "I2SOUT4_MCLK_EN" +#define I2SOUT6_MCLK_EN_W_NAME "I2SOUT6_MCLK_EN" +#define FMI2S_MASTER_MCLK_EN_W_NAME "FMI2S_MASTER_MCLK_EN" + +static int get_i2s_id_by_name(struct mtk_base_afe *afe, + const char *name) +{ + if (strncmp(name, "I2SIN0", 6) == 0) + return MT8196_DAI_I2S_IN0; + else if (strncmp(name, "I2SIN1", 6) == 0) + return MT8196_DAI_I2S_IN1; + else if (strncmp(name, "I2SIN2", 6) == 0) + return MT8196_DAI_I2S_IN2; + else if (strncmp(name, "I2SIN3", 6) == 0) + return MT8196_DAI_I2S_IN3; + else if (strncmp(name, "I2SIN4", 6) == 0) + return MT8196_DAI_I2S_IN4; + else if (strncmp(name, "I2SIN6", 6) == 0) + return MT8196_DAI_I2S_IN6; + else if (strncmp(name, "I2SOUT0", 7) == 0) + return MT8196_DAI_I2S_OUT0; + else if (strncmp(name, "I2SOUT1", 7) == 0) + return MT8196_DAI_I2S_OUT1; + else if (strncmp(name, "I2SOUT2", 7) == 0) + return MT8196_DAI_I2S_OUT2; + else if (strncmp(name, "I2SOUT3", 7) == 0) + return MT8196_DAI_I2S_OUT3; + else if (strncmp(name, "I2SOUT4", 7) == 0) + return MT8196_DAI_I2S_OUT4; + else if (strncmp(name, "I2SOUT6", 7) == 0) + return MT8196_DAI_I2S_OUT6; + else if (strncmp(name, "FMI2S_MASTER", 12) == 0) + return MT8196_DAI_FM_I2S_MASTER; + else + return -EINVAL; +} + +static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_i2s_id_by_name(afe, name); + + if (dai_id < 0) + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +/* + * bit mask for i2s low power control + * such as bit0 for i2s0, bit1 for i2s1... + * if set 1, means i2s low power mode + * if set 0, means i2s low jitter mode + * 0 for all i2s bit in default + */ +static unsigned int i2s_low_power_mask; +static int mtk_i2s_low_power_mask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s(), mask: %x\n", __func__, i2s_low_power_mask); + ucontrol->value.integer.value[0] = i2s_low_power_mask; + return 0; +} + +static int mtk_i2s_low_power_mask_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + i2s_low_power_mask = ucontrol->value.integer.value[0]; + pr_debug("%s(), mask: %x\n", __func__, i2s_low_power_mask); + return 0; +} + +static int mtk_is_i2s_low_power(int i2s_num) +{ + int i2s_bit_shift; + + i2s_bit_shift = i2s_num - MT8196_DAI_I2S_IN0; + if (i2s_bit_shift < 0 || i2s_bit_shift > MT8196_DAI_I2S_MAX_NUM) { + pr_debug("%s(), err i2s_num: %d\n", __func__, i2s_num); + return 0; + } + return (i2s_low_power_mask>>i2s_bit_shift) & 0x1; +} + +/* low jitter control */ +static const char *const mt8196_i2s_hd_str[] = { + "Normal", "Low_Jitter" +}; + +static const struct soc_enum mt8196_i2s_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8196_i2s_hd_str), + mt8196_i2s_hd_str), +}; + +static int mt8196_i2s_hd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en; + + return 0; +} + +static int mt8196_i2s_hd_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int hd_en; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + hd_en = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", + __func__, kcontrol->id.name, hd_en); + + i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return -EINVAL; + } + + i2s_priv->low_jitter_en = hd_en; + + return 0; +} + +static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = { + SOC_ENUM_EXT(MTK_AFE_I2SIN0_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SIN1_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SIN2_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SIN4_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SIN6_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SOUT0_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SOUT1_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SOUT2_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SOUT4_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2SOUT6_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_FMI2S_MASTER_KCONTROL_NAME, mt8196_i2s_enum[0], + mt8196_i2s_hd_get, mt8196_i2s_hd_set), + SOC_SINGLE_EXT("i2s_low_power_mask", SND_SOC_NOPM, 0, 0xffff, 0, + mtk_i2s_low_power_mask_get, + mtk_i2s_low_power_mask_set), + + SOC_ENUM_EXT("I2SIN0_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN1_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN2_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN3_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN4_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN6_LPBK", etdm_lpbk_map_enum, + etdm_lpbk_get, etdm_lpbk_put), + SOC_ENUM_EXT("I2SIN4_IP_MODE", etdm_ip_mode_map_enum, + etdm_ip_mode_get, etdm_ip_mode_put), + SOC_ENUM_EXT("I2SIN4_CH_NUM", etdm_ch_num_map_enum, + etdm_ch_num_get, etdm_ch_num_put), + SOC_ENUM_EXT("I2SOUT4_CH_NUM", etdm_ch_num_map_enum, + etdm_ch_num_get, etdm_ch_num_put), +}; + +/* dai component */ +/* i2s virtual mux to output widget */ +static const char *const i2s_mux_map[] = { + "Normal", "Dummy_Widget", +}; + +static int i2s_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + i2s_mux_map, + i2s_mux_map_value); + +static const struct snd_kcontrol_new i2s_in0_mux_control = + SOC_DAPM_ENUM("I2S IN0 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in1_mux_control = + SOC_DAPM_ENUM("I2S IN1 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in2_mux_control = + SOC_DAPM_ENUM("I2S IN2 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in3_mux_control = + SOC_DAPM_ENUM("I2S IN3 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in4_mux_control = + SOC_DAPM_ENUM("I2S IN4 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in6_mux_control = + SOC_DAPM_ENUM("I2S IN6 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out0_mux_control = + SOC_DAPM_ENUM("I2S OUT0 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out1_mux_control = + SOC_DAPM_ENUM("I2S OUT1 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out2_mux_control = + SOC_DAPM_ENUM("I2S OUT2 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out3_mux_control = + SOC_DAPM_ENUM("I2S OUT3 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out4_mux_control = + SOC_DAPM_ENUM("I2S OUT4 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out6_mux_control = + SOC_DAPM_ENUM("I2S OUT6 Select", i2s_mux_map_enum); + +/* interconnection */ +static const struct snd_kcontrol_new mtk_i2sout0_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN108_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN108_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN108_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN108_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN108_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN108_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN108_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN108_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN108_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN108_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN108_2, I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN108_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN108_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN108_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN108_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN108_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN108_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN108_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN108_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout0_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN109_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN109_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN109_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN109_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN109_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN109_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN109_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN109_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN109_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN109_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN109_2, I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN109_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN109_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN109_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN109_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN109_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN109_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN109_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN109_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN109_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN109_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN110_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN110_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN110_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN110_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN110_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN110_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN110_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN110_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN110_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN110_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN110_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN110_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN110_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN110_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN111_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN111_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN111_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN111_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN111_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN111_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN111_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN111_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN111_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN111_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN111_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN111_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN111_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN111_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN111_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN111_4, + I_PCM_1_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout2_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN112_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN112_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN112_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN112_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN112_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN112_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN112_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN112_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN112_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN112_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN112_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN112_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN112_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN112_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout2_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN113_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN113_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN113_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN113_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN113_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN113_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN113_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN113_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN113_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN113_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN113_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN113_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN113_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN113_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN113_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN113_4, + I_PCM_1_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout3_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN114_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN114_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN114_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN114_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN114_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN114_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN114_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN114_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN114_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN114_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN114_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN114_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN114_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN114_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout3_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN115_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN115_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN115_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN115_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN115_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN115_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN115_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN115_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN115_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN115_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN115_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN115_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN115_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN115_4, + I_PCM_1_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN116_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN116_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN116_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN116_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN116_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN116_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN116_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN116_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN116_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN116_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN116_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN116_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN116_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN116_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN116_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN116_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN116_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN116_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN117_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN117_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN117_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN117_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN117_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN117_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN117_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN117_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN117_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN117_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN117_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN117_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN117_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN117_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN117_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN117_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN117_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN117_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN117_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN117_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN118_1, I_DL_24CH_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN118_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN119_1, I_DL_24CH_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN118_4, + I_PCM_1_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH5", AFE_CONN120_1, I_DL_24CH_CH5, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH6", AFE_CONN121_1, I_DL_24CH_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH7", AFE_CONN122_1, I_DL_24CH_CH7, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH8", AFE_CONN123_1, I_DL_24CH_CH8, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout6_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN148_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN148_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN148_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN148_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN148_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN148_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN148_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN148_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN148_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN148_2, I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN148_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN148_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN148_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN148_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN148_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN148_6, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout6_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN149_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN149_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN149_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN149_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN149_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN149_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN149_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN149_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN149_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN149_2, I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN149_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN149_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN149_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN149_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN149_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN149_4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN149_4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN148_6, + I_SRC_1_OUT_CH2, 1, 0), +}; + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_I2S_MCLK_EN, + SUPPLY_SEQ_I2S_HD_EN, + SUPPLY_SEQ_I2S_GPIO, + SUPPLY_SEQ_I2S_EN, +}; + +static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + struct mtk_base_etdm_data etdm_data; + int id; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return -EINVAL; + } + id = i2s_priv->id - MT8196_DAI_I2S_IN0; + if (id < 0 || id >= DAI_I2S_NUM) { + dev_warn(afe->dev, "%s(), i2s id is invalid", __func__); + return -EINVAL; + } + etdm_data = mtk_etdm_data[id]; + + dev_info(cmpnt->dev, "%s(), id: %d, name %s, event 0x%x\n", + __func__, id, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_afe_gpio_request(afe, true, i2s_priv->id, 0); + break; + case SND_SOC_DAPM_POST_PMD: + mt8196_afe_gpio_request(afe, false, i2s_priv->id, 0); + break; + default: + break; + } + switch (id) { + case DAI_I2SIN4: + dev_info(cmpnt->dev, "%s(), id: %d. setting I2SIN4 ch num: 4ch.\n", __func__, id); + /* set etdm ch */ + mtk_regmap_update_bits(afe->regmap, etdm_data.ch_reg, + etdm_data.ch_mask, + (i2s_priv->ch_num - 1), + etdm_data.ch_shift); + /* set etdm ip mode */ + mtk_regmap_update_bits(afe->regmap, etdm_data.ip_mode_reg, + etdm_data.ip_mode_mask, i2s_priv->ip_mode, + etdm_data.ip_mode_shift); + /* set etdm sync */ + mtk_regmap_update_bits(afe->regmap, etdm_data.sync_reg, + etdm_data.sync_mask, + i2s_priv->sync, + etdm_data.sync_shift); + + break; + case DAI_I2SIN0: + case DAI_I2SIN1: + case DAI_I2SIN2: + case DAI_I2SIN3: + case DAI_I2SIN6: + dev_info(cmpnt->dev, "%s(), id: %d. setting I2SIN0,1,2,3,6 sync mode: 0x00.\n", __func__, id); + /* set etdm sync */ + mtk_regmap_update_bits(afe->regmap, etdm_data.sync_reg, + etdm_data.sync_mask, + 0x0, + etdm_data.sync_shift); + break; + + case DAI_I2SOUT4: + dev_info(cmpnt->dev, "%s(), id: %d. setting I2SOUT4 ch_num: %d, sync: %d\n", __func__, + id, i2s_priv->ch_num, i2s_priv->sync); + /* set etdm ch */ + mtk_regmap_update_bits(afe->regmap, etdm_data.ch_reg, + etdm_data.ch_mask, + (i2s_priv->ch_num - 1), + etdm_data.ch_shift); + /* set etdm sync */ + mtk_regmap_update_bits(afe->regmap, etdm_data.sync_reg, + etdm_data.sync_mask, + i2s_priv->sync, + etdm_data.sync_shift); + break; + + default: + break; + } + + return 0; +} + +static int mtk_i2s_hd_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + + dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + return 0; +} + +static int mtk_apll_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8196_apll1_enable(afe); + else + mt8196_apll2_enable(afe); + break; + case SND_SOC_DAPM_POST_PMD: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8196_apll1_disable(afe); + else + mt8196_apll2_disable(afe); + break; + default: + break; + } + + return 0; +} + +static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + i2s_priv->mclk_rate = 0; + mt8196_mck_disable(afe, i2s_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { + SND_SOC_DAPM_INPUT("CONNSYS"), + + SND_SOC_DAPM_MIXER("I2SOUT0_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout0_ch1_mix, + ARRAY_SIZE(mtk_i2sout0_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT0_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout0_ch2_mix, + ARRAY_SIZE(mtk_i2sout0_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT1_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout1_ch1_mix, + ARRAY_SIZE(mtk_i2sout1_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT1_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout1_ch2_mix, + ARRAY_SIZE(mtk_i2sout1_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT2_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout2_ch1_mix, + ARRAY_SIZE(mtk_i2sout2_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT2_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout2_ch2_mix, + ARRAY_SIZE(mtk_i2sout2_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT3_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout3_ch1_mix, + ARRAY_SIZE(mtk_i2sout3_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT3_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout3_ch2_mix, + ARRAY_SIZE(mtk_i2sout3_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT4_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch1_mix, + ARRAY_SIZE(mtk_i2sout4_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch2_mix, + ARRAY_SIZE(mtk_i2sout4_ch2_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH3", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch3_mix, + ARRAY_SIZE(mtk_i2sout4_ch3_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH4", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch4_mix, + ARRAY_SIZE(mtk_i2sout4_ch4_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH5", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch5_mix, + ARRAY_SIZE(mtk_i2sout4_ch5_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH6", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch6_mix, + ARRAY_SIZE(mtk_i2sout4_ch6_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH7", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch7_mix, + ARRAY_SIZE(mtk_i2sout4_ch7_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH8", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch8_mix, + ARRAY_SIZE(mtk_i2sout4_ch8_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT6_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout6_ch1_mix, + ARRAY_SIZE(mtk_i2sout6_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT6_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout6_ch2_mix, + ARRAY_SIZE(mtk_i2sout6_ch2_mix)), + /* i2s gpio*/ + SND_SOC_DAPM_SUPPLY_S("I2SIN0_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SIN1_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SIN2_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SIN3_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SIN4_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SIN6_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT2_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT3_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2SOUT6_GPIO", SUPPLY_SEQ_I2S_GPIO, + SND_SOC_NOPM, 0, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + /* i2s en*/ + SND_SOC_DAPM_SUPPLY_S("I2SIN0_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN0_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN1_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN1_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN2_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN2_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN3_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN3_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN4_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN4_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN6_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN6_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT0_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT1_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT2_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT2_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT3_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT3_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT4_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT6_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT6_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("FMI2S_MASTER_EN", SUPPLY_SEQ_I2S_EN, + AFE_CONNSYS_I2S_CON, I2S_EN_SFT, 0, + NULL, 0), + + /* i2s hd en */ + SND_SOC_DAPM_SUPPLY_S(I2SIN0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN4_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN6_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT4_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT6_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + SND_SOC_NOPM, 0, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(FMI2S_MASTER_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + AFE_CONNSYS_I2S_CON, I2S_HDEN_SFT, 0, + mtk_i2s_hd_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* i2s mclk en */ + SND_SOC_DAPM_SUPPLY_S(I2SIN0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN4_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN6_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT4_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT6_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(FMI2S_MASTER_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* apll */ + SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* allow i2s on without codec on */ + SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"), + SND_SOC_DAPM_MUX("I2S_OUT0_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out0_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT1_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out1_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT2_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out2_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT3_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out3_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT4_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out4_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT6_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out6_mux_control), + + SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"), + SND_SOC_DAPM_MUX("I2S_IN0_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in0_mux_control), + SND_SOC_DAPM_MUX("I2S_IN1_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in1_mux_control), + SND_SOC_DAPM_MUX("I2S_IN2_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in2_mux_control), + SND_SOC_DAPM_MUX("I2S_IN3_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in3_mux_control), + SND_SOC_DAPM_MUX("I2S_IN4_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in4_mux_control), + SND_SOC_DAPM_MUX("I2S_IN6_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in6_mux_control), + + SND_SOC_DAPM_MIXER("SOF_DMA_DL_24CH", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SOF_DMA_DL1", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int ret = 0; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return 0; + } + + if (i2s_priv->share_i2s_id < 0) + return 0; + + ret = (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) ? 1 : 0; + + return ret; +} + +static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int i2s_num; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return 0; + } + + i2s_num = get_i2s_id_by_name(afe, source->name); + if (get_i2s_id_by_name(afe, sink->name) == i2s_num) + return !mtk_is_i2s_low_power(i2s_num) || + i2s_priv->low_jitter_en; + + /* check if share i2s need hd en */ + if (i2s_priv->share_i2s_id < 0) + return 0; + + if (i2s_priv->share_i2s_id == i2s_num) + return !mtk_is_i2s_low_power(i2s_num) || + i2s_priv->low_jitter_en; + + return 0; +} + +static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + int i2s_need_apll; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return 0; + } + + /* which apll */ + cur_apll = mt8196_get_apll_by_name(afe, source->name); + + /* choose APLL from i2s rate */ + i2s_need_apll = mt8196_get_apll_by_rate(afe, i2s_priv->rate); + + return (i2s_need_apll == cur_apll) ? 1 : 0; +} + +static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return 0; + } + + if (get_i2s_id_by_name(afe, sink->name) == + get_i2s_id_by_name(afe, source->name)) + return (i2s_priv->mclk_rate > 0) ? 1 : 0; + + /* check if share i2s need mclk */ + if (i2s_priv->share_i2s_id < 0) + return 0; + + if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) + return (i2s_priv->mclk_rate > 0) ? 1 : 0; + + return 0; +} + +static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return 0; + } + + /* which apll */ + cur_apll = mt8196_get_apll_by_name(afe, source->name); + + return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { + {"Connsys I2S", NULL, "CONNSYS"}, + + /* i2sin0 */ + {"I2SIN0", NULL, "I2SIN0_GPIO"}, + {"I2SIN0", NULL, "I2SIN0_EN"}, + {"I2SIN0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN0", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN0", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sin1 */ + {"I2SIN1", NULL, "I2SIN1_GPIO"}, + {"I2SIN1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SIN1_EN"}, + {"I2SIN1", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN1", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN1", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sin2 */ + {"I2SIN2", NULL, "I2SIN2_GPIO"}, + {"I2SIN2", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SIN2_EN"}, + {"I2SIN2", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN2", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN2", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN2", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN2", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN2", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sin3 */ + {"I2SIN3", NULL, "I2SIN3_GPIO"}, + {"I2SIN3", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SIN3_EN"}, + {"I2SIN3", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN3", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN3", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN3", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN3", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN3", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sin4 */ + {"I2SIN4", NULL, "I2SIN4_GPIO"}, + {"I2SIN4", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SIN4_EN"}, + {"I2SIN4", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN4", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN4", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN4", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN4_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN4_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN4", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN4", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN4_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN4_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sin6 */ + {"I2SIN6", NULL, "I2SIN6_GPIO"}, + {"I2SIN6", NULL, "I2SOUT6_GPIO"}, + {"I2SIN6", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SIN6_EN"}, + {"I2SIN6", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SIN6", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN6", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SIN6", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SIN6_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SIN6_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SIN6", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN6", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN6_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN6_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout0 */ + {"I2SOUT0_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT0_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT0_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT0_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT0_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT0_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT0_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT0_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT0_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT0_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT0_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT0_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT0_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT0_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT0_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT0_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT0_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT0_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT0_CH1", "DL23_CH1", "DL23"}, + {"I2SOUT0_CH2", "DL23_CH2", "DL23"}, + {"I2SOUT0_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT0_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT0_CH1", "DL24_CH1", "DL24"}, + {"I2SOUT0_CH2", "DL24_CH2", "DL24"}, + + {"I2SOUT0", NULL, "I2SOUT0_CH1"}, + {"I2SOUT0", NULL, "I2SOUT0_CH2"}, + + {"I2SOUT0", NULL, "I2SIN0_GPIO"}, + {"I2SOUT0", NULL, "I2SOUT0_GPIO"}, + {"I2SOUT0", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT0_EN"}, + {"I2SOUT0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT0", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT0", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout1 */ + {"I2SOUT1_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT1_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT1_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT1_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT1_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT1_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT1_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT1_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT1_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT1_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT1_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT1_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT1_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT1_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT1_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT1_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT1_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT1_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT1_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT1_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT1", NULL, "I2SOUT1_CH1"}, + {"I2SOUT1", NULL, "I2SOUT1_CH2"}, + + {"I2SOUT1", NULL, "I2SIN1_GPIO"}, + {"I2SOUT1", NULL, "I2SOUT1_GPIO"}, + {"I2SOUT1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT1_EN"}, + {"I2SOUT1", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT1", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT1", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout2 */ + {"I2SOUT2_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT2_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT2_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT2_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT2_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT2_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT2_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT2_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT2_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT2_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT2_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT2_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT2_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT2_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT2_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT2_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT2_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT2_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT2_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT2_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT2", NULL, "I2SOUT2_CH1"}, + {"I2SOUT2", NULL, "I2SOUT2_CH2"}, + + {"I2SOUT2", NULL, "I2SIN2_GPIO"}, + {"I2SOUT2", NULL, "I2SOUT2_GPIO"}, + {"I2SOUT2", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SOUT2_EN"}, + {"I2SOUT2", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT2", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT2", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT2", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT2", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT2", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout3 */ + {"I2SOUT3_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT3_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT3_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT3_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT3_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT3_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT3_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT3_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT3_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT3_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT3_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT3_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT3_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT3_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT3_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT3_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT3_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT3_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT3_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT3_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT3", NULL, "I2SOUT3_CH1"}, + {"I2SOUT3", NULL, "I2SOUT3_CH2"}, + + {"I2SOUT3", NULL, "I2SIN3_GPIO"}, + {"I2SOUT3", NULL, "I2SOUT3_GPIO"}, + {"I2SOUT3", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SOUT3_EN"}, + {"I2SOUT3", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT3", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT3", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT3", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT3", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout4 */ + {"I2SOUT4_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT4_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT4_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT4_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT4_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT4_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT4_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT4_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT4_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT4_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT4_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT4_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT4_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT4_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT4_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT4_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT4_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT4_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT4_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT4_CH2", "DL_24CH_CH2", "DL_24CH"}, + {"I2SOUT4_CH3", "DL_24CH_CH3", "DL_24CH"}, + {"I2SOUT4_CH4", "DL_24CH_CH4", "DL_24CH"}, + {"I2SOUT4_CH5", "DL_24CH_CH5", "DL_24CH"}, + {"I2SOUT4_CH6", "DL_24CH_CH6", "DL_24CH"}, + {"I2SOUT4_CH7", "DL_24CH_CH7", "DL_24CH"}, + {"I2SOUT4_CH8", "DL_24CH_CH8", "DL_24CH"}, + {"I2SOUT4_CH1", "DL24_CH1", "DL24"}, + {"I2SOUT4_CH2", "DL24_CH2", "DL24"}, + + /* SOF Downlink */ + {"I2SOUT4_CH1", "DL_24CH_CH1", "SOF_DMA_DL_24CH"}, + {"I2SOUT4_CH2", "DL_24CH_CH2", "SOF_DMA_DL_24CH"}, + {"I2SOUT4_CH3", "DL_24CH_CH3", "SOF_DMA_DL_24CH"}, + {"I2SOUT4_CH4", "DL_24CH_CH4", "SOF_DMA_DL_24CH"}, + + {"I2SOUT4", NULL, "I2SOUT4_CH1"}, + {"I2SOUT4", NULL, "I2SOUT4_CH2"}, + {"I2SOUT4", NULL, "I2SOUT4_CH3"}, + {"I2SOUT4", NULL, "I2SOUT4_CH4"}, + {"I2SOUT4", NULL, "I2SOUT4_CH5"}, + {"I2SOUT4", NULL, "I2SOUT4_CH6"}, + {"I2SOUT4", NULL, "I2SOUT4_CH7"}, + {"I2SOUT4", NULL, "I2SOUT4_CH8"}, + + + {"I2SOUT4", NULL, "I2SIN4_GPIO"}, + {"I2SOUT4", NULL, "I2SOUT4_GPIO"}, + {"I2SOUT4", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT4_EN"}, + {"I2SOUT4", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT4", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT4", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT4_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT4_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT4", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2sout6 */ + {"I2SOUT6_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT6_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT6_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT6_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT6_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT6_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT6_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT6_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT6_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT6_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT6_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT6_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT6_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT6_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT6_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT6_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT6_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT6_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT6_CH1", "DL23_CH1", "DL23"}, + {"I2SOUT6_CH2", "DL23_CH2", "DL23"}, + {"I2SOUT6_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT6_CH2", "DL_24CH_CH2", "DL_24CH"}, + + /* SOF Downlink */ + {"I2SOUT6_CH1", "DL1_CH1", "SOF_DMA_DL1"}, + {"I2SOUT6_CH2", "DL1_CH2", "SOF_DMA_DL1"}, + {"I2SOUT6_CH1", "DL_24CH_CH1", "SOF_DMA_DL_24CH"}, + {"I2SOUT6_CH2", "DL_24CH_CH2", "SOF_DMA_DL_24CH"}, + + {"I2SOUT6", NULL, "I2SOUT6_CH1"}, + {"I2SOUT6", NULL, "I2SOUT6_CH2"}, + + {"I2SOUT6", NULL, "I2SIN6_GPIO"}, + {"I2SOUT6", NULL, "I2SOUT6_GPIO"}, + {"I2SOUT6", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT6", NULL, "I2SOUT6_EN"}, + {"I2SOUT6", NULL, "FMI2S_MASTER_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT6", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2SOUT6", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2SOUT6_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2SOUT6_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2SOUT6", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT6", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT6_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT6_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* fmi2s */ + {"FMI2S_MASTER", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SIN2_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SIN3_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SIN4_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SIN6_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT2_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT3_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "I2SOUT6_EN", mtk_afe_i2s_share_connect}, + {"FMI2S_MASTER", NULL, "FMI2S_MASTER_EN"}, + + {"FMI2S_MASTER", NULL, I2SIN0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SIN1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SIN2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SIN3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SIN4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SIN6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT4_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, I2SOUT6_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"FMI2S_MASTER", NULL, FMI2S_MASTER_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {FMI2S_MASTER_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {FMI2S_MASTER_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"FMI2S_MASTER", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SIN2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SIN3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SIN4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SIN6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, I2SOUT6_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"FMI2S_MASTER", NULL, FMI2S_MASTER_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {FMI2S_MASTER_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {FMI2S_MASTER_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* allow i2s on without codec on */ + {"I2SIN0", NULL, "I2S_IN0_Mux"}, + {"I2S_IN0_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN1", NULL, "I2S_IN1_Mux"}, + {"I2S_IN1_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN2", NULL, "I2S_IN2_Mux"}, + {"I2S_IN2_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN3", NULL, "I2S_IN3_Mux"}, + {"I2S_IN3_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN4", NULL, "I2S_IN4_Mux"}, + {"I2S_IN4_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN6", NULL, "I2S_IN6_Mux"}, + {"I2S_IN6_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2S_OUT0_Mux", "Dummy_Widget", "I2SOUT0"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT0_Mux"}, + + {"I2S_OUT1_Mux", "Dummy_Widget", "I2SOUT1"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT1_Mux"}, + + {"I2S_OUT2_Mux", "Dummy_Widget", "I2SOUT2"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT2_Mux"}, + + {"I2S_OUT3_Mux", "Dummy_Widget", "I2SOUT3"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT3_Mux"}, + {"I2S_OUT4_Mux", "Dummy_Widget", "I2SOUT4"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT4_Mux"}, + + {"I2S_OUT6_Mux", "Dummy_Widget", "I2SOUT6"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT6_Mux"}, +}; + +/* dai ops */ +#define SRC_REG +static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8196_rate_transform(afe->dev, + rate, dai->id); + unsigned int i2s_con = 0; + + dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, + dai->id, + substream->stream, + rate); + + /* non-inverse, i2s mode, slave, 16bits, from connsys */ + i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT; + i2s_con |= 1 << I2S_SRC_SFT; + i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT; + regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con); + + /* use asrc */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_BYPSRC_MASK_SFT, + 0x0 << I2S_BYPSRC_SFT); + + /* slave mode, set i2s for asrc */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_MODE_MASK_SFT, + rate_reg << I2S_MODE_SFT); +#ifdef SRC_REG +#if !defined(FM_SRC_CAIL) + if (rate == 44100) + regmap_write(afe->regmap, AFE_ASRC_NEW_CON3, 0x001B9000); + else if (rate == 32000) + regmap_write(afe->regmap, AFE_ASRC_NEW_CON3, 0x140000); + else + regmap_write(afe->regmap, AFE_ASRC_NEW_CON3, 0x001E0000); + + /* Calibration setting */ + regmap_write(afe->regmap, AFE_ASRC_NEW_CON4, 0x00140000); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON13, 0x00036000); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON14, 0x0002FC00); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON7, 0x00007EF4); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON6, 0x00FF5986); +#else + if (rate == 44100) + regmap_write(afe->regmap, AFE_ASRC_NEW_CON2, 0x001b9000); + else if (rate == 32000) + regmap_write(afe->regmap, AFE_ASRC_NEW_CON2, 0x140000); + else + regmap_write(afe->regmap, AFE_ASRC_NEW_CON2, 0x000f0000); + + /* Calibration setting */ + regmap_write(afe->regmap, AFE_ASRC_NEW_CON3, 0x000a0000); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON13, 0x001b000); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON14, 0x0017c00); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON7, 0x00001fbd); + regmap_write(afe->regmap, AFE_ASRC_NEW_CON5, 0xa000000); + +#if !defined(FM_SRC_CAIL) + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET0_IFS_SEL_MASK_SFT, + 0x3 << CHSET0_IFS_SEL_SFT); + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET0_OFS_SEL_MASK_SFT, + 0x2 << CHSET0_OFS_SEL_SFT); +#else + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET0_IFS_SEL_MASK_SFT, + 0x2 << CHSET0_IFS_SEL_SFT); + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET0_OFS_SEL_MASK_SFT, + 0x1 << CHSET0_OFS_SEL_SFT); +#endif + regmap_write(afe->regmap, AFE_ASRC_NEW_CON6, 0x7f888e); +#endif + + /* 0:Stereo 1:Mono */ + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET0_IS_MONO_MASK_SFT, + 0x0 << CHSET0_IS_MONO_SFT); +#endif + + return 0; +} + +static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + + dev_info(afe->dev, "%s(), cmd %d, stream %d\n", + __func__, + cmd, + substream->stream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* i2s enable */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_EN_MASK_SFT, + 0x1 << I2S_EN_SFT); +#ifdef SRC_REG + + /* calibrator enable */ + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON6, + CALI_EN_MASK_SFT, + 0x1 << CALI_EN_SFT); + + /* asrc enable */ + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + CHSET_STR_CLR_MASK_SFT, + 0x1 << CHSET_STR_CLR_SFT); + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + ASM_ON_MASK_SFT, + 0x1 << ASM_ON_SFT); +#endif + afe_priv->dai_on[dai->id] = true; + return 0; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: +#ifdef SRC_REG + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON0, + ASM_ON_MASK_SFT, + 0 << ASM_ON_SFT); + regmap_update_bits(afe->regmap, + AFE_ASRC_NEW_CON6, + CALI_EN_MASK_SFT, + 0 << CALI_EN_SFT); +#endif + /* i2s disable */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_EN_MASK_SFT, + 0x0 << I2S_EN_SFT); + + /* bypass asrc */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_BYPSRC_MASK_SFT, + 0x1 << I2S_BYPSRC_SFT); + + afe_priv->dai_on[dai->id] = false; + return 0; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = { + .hw_params = mtk_dai_connsys_i2s_hw_params, + .trigger = mtk_dai_connsys_i2s_trigger, +}; + +/* i2s dai ops*/ +static int mtk_dai_i2s_config(struct mtk_base_afe *afe, + struct snd_pcm_hw_params *params, + int i2s_id) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id]; + struct mtk_afe_i2s_priv *i2sin_priv = NULL; + int id = i2s_id - MT8196_DAI_I2S_IN0; //47 + struct mtk_base_etdm_data etdm_data; + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8196_rate_transform(afe->dev, + rate, i2s_id); + snd_pcm_format_t format = params_format(params); + unsigned int channels = params_channels(params); + unsigned int i2s_con = 0; + int ret = 0; + int pad_top = 0; + + dev_info(afe->dev, "%s(), id %d, rate %d, pcm_format %d, format %d\n", + __func__, i2s_id, rate, format, i2s_priv->format); + + if (id < 0 || id >= DAI_I2S_NUM) { + dev_warn(afe->dev, "%s(), i2s id is invalid", __func__); + return -EINVAL; + } + etdm_data = mtk_etdm_data[id]; + + if (i2s_priv) + i2s_priv->rate = rate; + else + AUDIO_AEE("i2s_priv == NULL"); + + if (is_etdm_in_pad_top(id)) + pad_top = 0x3; + else + pad_top = 0x5; + + switch (id) { + case DAI_FMI2S_MASTER: + i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT; + i2s_con |= rate_reg << I2S_MODE_SFT; + i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT; + i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT; + regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, + 0xffffeffe, i2s_con); + break; + case DAI_I2SIN0: + case DAI_I2SIN1: + case DAI_I2SIN2: + case DAI_I2SIN3: + case DAI_I2SIN4: + case DAI_I2SIN6: + /* ---etdm in --- */ + mtk_regmap_update_bits(afe->regmap, etdm_data.init_count_reg, + etdm_data.init_count_mask, + 0x5, + etdm_data.init_count_shift); + /* 3: pad top 5: no pad top */ + mtk_regmap_update_bits(afe->regmap, etdm_data.init_point_reg, + etdm_data.init_point_mask, + pad_top, + etdm_data.init_point_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.lrck_reset_reg, + etdm_data.lrck_reset_mask, + 0x1, + etdm_data.lrck_reset_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.clk_source_reg, + etdm_data.clk_source_mask, + ETDM_CLK_SOURCE_APLL, + etdm_data.clk_source_shift); + /* 0: manual 1: auto */ + mtk_regmap_update_bits(afe->regmap, etdm_data.ck_en_sel_reg, + etdm_data.ck_en_sel_mask, + 0x1, + etdm_data.ck_en_sel_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.fs_timing_reg, + etdm_data.fs_timing_mask, + get_etdm_rate(rate), + etdm_data.fs_timing_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.relatch_en_sel_reg, + etdm_data.relatch_en_sel_mask, + get_etdm_inconn_rate(rate), + etdm_data.relatch_en_sel_shift); + + mtk_regmap_update_bits(afe->regmap, etdm_data.use_afifo_reg, + etdm_data.use_afifo_mask, + 0x0, + etdm_data.use_afifo_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.afifo_mode_reg, + etdm_data.afifo_mode_mask, + 0x0, + etdm_data.afifo_mode_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.almost_end_ch_reg, + etdm_data.almost_end_ch_mask, + 0x0, + etdm_data.almost_end_ch_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.almost_end_bit_reg, + etdm_data.almost_end_bit_mask, + 0x0, + etdm_data.almost_end_bit_shift); + if (is_etdm_in_pad_top(id)) { + mtk_regmap_update_bits(afe->regmap, etdm_data.out2latch_time_reg, + etdm_data.out2latch_time_mask, + 0x6, + etdm_data.out2latch_time_shift); + } else { + mtk_regmap_update_bits(afe->regmap, etdm_data.out2latch_time_reg, + etdm_data.out2latch_time_mask, + 0x4, + etdm_data.out2latch_time_shift); + } + + /* 5: TDM Mode */ + if (id == DAI_I2SIN4) + mtk_regmap_update_bits(afe->regmap, etdm_data.tdm_mode_reg, + etdm_data.tdm_mode_mask, + i2s_priv->format, // 0x00 i2s, 0x04 adsp_a + etdm_data.tdm_mode_shift);// DSP_A mode for multi-channel + else + mtk_regmap_update_bits(afe->regmap, etdm_data.tdm_mode_reg, + etdm_data.tdm_mode_mask, + 0x0, // i2s + etdm_data.tdm_mode_shift); + + /* APLL */ + mtk_regmap_update_bits(afe->regmap, + etdm_data.relatch_domain_sel_reg, + etdm_data.relatch_domain_sel_mask, + ETDM_RELATCH_SEL_APLL, + etdm_data.relatch_domain_sel_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.bit_length_reg, + etdm_data.bit_length_mask, + get_etdm_lrck_width(format), + etdm_data.bit_length_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.word_length_reg, + etdm_data.word_length_mask, + get_etdm_wlen(format), + etdm_data.word_length_shift); + + /* ---etdm cowork --- */ + mtk_regmap_update_bits(afe->regmap, etdm_data.cowork_reg, + etdm_data.cowork_mask, + etdm_data.cowork_val, + etdm_data.cowork_shift); + + /* i2s with pad top setting */ + if (is_etdm_in_pad_top(id) && etdm_data.pad_top_ck_en_reg != -1) { + mtk_regmap_update_bits(afe->regmap, etdm_data.pad_top_ck_en_reg, + etdm_data.pad_top_ck_en_mask, + 0x1, + etdm_data.pad_top_ck_en_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.master_latch_reg, + etdm_data.master_latch_mask, + 0x0, + etdm_data.master_latch_shift); + + dev_info(afe->dev, "%s(), DAI_I2SIN4 set master_latch_reg: 0.\n", __func__); + } + + break; + case DAI_I2SOUT0: + case DAI_I2SOUT1: + case DAI_I2SOUT2: + case DAI_I2SOUT3: + case DAI_I2SOUT4: + case DAI_I2SOUT6: + dev_info(afe->dev, "%s(), DAI_I2SOUTn init.\n", __func__); + + /* ---etdm out --- */ + mtk_regmap_update_bits(afe->regmap, etdm_data.init_count_reg, + etdm_data.init_count_mask, + 0x5, + etdm_data.init_count_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.init_point_reg, + etdm_data.init_point_mask, + 0x6, + etdm_data.init_point_shift); + // clock speed > 22M need to set relatch time to avoid duplicate porint + if (rate * channels * (get_etdm_wlen(format) + 1) >= ETDM_22M_CLOCK_THRES && + get_etdm_wlen(format) >= 2) { + mtk_regmap_update_bits(afe->regmap, etdm_data.in2latch_time_reg, + etdm_data.in2latch_time_mask, + get_etdm_wlen(format) - 2, + etdm_data.in2latch_time_shift); + } else { + mtk_regmap_update_bits(afe->regmap, etdm_data.in2latch_time_reg, + etdm_data.in2latch_time_mask, + 0x6, + etdm_data.in2latch_time_shift); + } + mtk_regmap_update_bits(afe->regmap, etdm_data.lrck_reset_reg, + etdm_data.lrck_reset_mask, + 0x1, + etdm_data.lrck_reset_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.fs_timing_reg, + etdm_data.fs_timing_mask, + get_etdm_rate(rate), + etdm_data.fs_timing_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.clk_source_reg, + etdm_data.clk_source_mask, + ETDM_CLK_SOURCE_APLL, + etdm_data.clk_source_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.relatch_en_sel_reg, + etdm_data.relatch_en_sel_mask, + get_etdm_inconn_rate(rate), + etdm_data.relatch_en_sel_shift); + + /* 5: TDM Mode */ + if (id == DAI_I2SOUT4) + mtk_regmap_update_bits(afe->regmap, etdm_data.tdm_mode_reg, + etdm_data.tdm_mode_mask, + i2s_priv->format, // 0x00 i2s, 0x04 adsp_a + etdm_data.tdm_mode_shift);// DSP_A mode for multi-channel + else + mtk_regmap_update_bits(afe->regmap, etdm_data.tdm_mode_reg, + etdm_data.tdm_mode_mask, + 0x0, + etdm_data.tdm_mode_shift); + + /* APLL */ + mtk_regmap_update_bits(afe->regmap, + etdm_data.relatch_domain_sel_reg, + etdm_data.relatch_domain_sel_mask, + ETDM_RELATCH_SEL_APLL, + etdm_data.relatch_domain_sel_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.bit_length_reg, + etdm_data.bit_length_mask, + get_etdm_lrck_width(format), + etdm_data.bit_length_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.word_length_reg, + etdm_data.word_length_mask, + get_etdm_wlen(format), + etdm_data.word_length_shift); + + /* ---etdm cowork --- */ + mtk_regmap_update_bits(afe->regmap, etdm_data.cowork_reg, + etdm_data.cowork_mask, + etdm_data.cowork_val, + etdm_data.cowork_shift); + + /* i2s with pad top setting */ + if (is_etdm_in_pad_top(id) && etdm_data.pad_top_ck_en_reg != -1) { + mtk_regmap_update_bits(afe->regmap, etdm_data.pad_top_ck_en_reg, + etdm_data.pad_top_ck_en_mask, + 0x1, + etdm_data.pad_top_ck_en_shift); + mtk_regmap_update_bits(afe->regmap, etdm_data.master_latch_reg, + etdm_data.master_latch_mask, + 0x0, + etdm_data.master_latch_shift); + + dev_info(afe->dev, "%s(), DAI_I2SOUT4 set master_latch_reg: 0.\n", __func__); + } + break; + default: + dev_info(afe->dev, "%s(), id %d not support\n", + __func__, id); + return -EINVAL; + } + + /* set share i2s */ + if (i2s_priv && i2s_priv->share_i2s_id >= 0) { + dev_info(afe->dev, "%s(), share_i2s_id: %d.\n", __func__, i2s_priv->share_i2s_id); + i2sin_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; + i2sin_priv->format = i2s_priv->format; + dev_info(afe->dev, "%s(),i2sin_priv->id : %d, format: %d\n", __func__, + i2sin_priv->id, i2sin_priv->format); + ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); + } + + return ret; +} + +static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + dev_info(afe->dev, "%s(), dai->id: %d\n", __func__, dai->id); + + return mtk_dai_i2s_config(afe, params, dai->id); +} + +static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id]; + int apll; + int apll_rate; + + dev_info(afe->dev, "%s(), enter\n", __func__); + + if (!i2s_priv) { + AUDIO_AEE("i2s_priv == NULL"); + return -EINVAL; + } + + if (dir != SND_SOC_CLOCK_OUT) { + AUDIO_AEE("dir != SND_SOC_CLOCK_OUT"); + return -EINVAL; + } + + apll = mt8196_get_apll_by_rate(afe, freq); + apll_rate = mt8196_get_apll_rate(afe, apll); + + if (freq > apll_rate) { + AUDIO_AEE("freq > apll rate"); + return -EINVAL; + } + + if (apll_rate % freq != 0) { + AUDIO_AEE("APLL cannot generate freq Hz"); + return -EINVAL; + } + + i2s_priv->mclk_rate = freq; + i2s_priv->mclk_apll = apll; + + if (i2s_priv->share_i2s_id > 0) { + struct mtk_afe_i2s_priv *share_i2s_priv; + + share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; + if (!share_i2s_priv) { + AUDIO_AEE("share_i2s_priv == NULL"); + return -EINVAL; + } + + share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; + share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; + } + return 0; +} + +static int mtk_dai_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id]; + + dev_info(afe->dev, "%s(), dai->id: %d, fmt: 0x%x\n", __func__, dai->id, fmt); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + i2s_priv->format = MTK_DAI_ETDM_FORMAT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + i2s_priv->format = MTK_DAI_ETDM_FORMAT_LJ; + break; + case SND_SOC_DAIFMT_RIGHT_J: + i2s_priv->format = MTK_DAI_ETDM_FORMAT_RJ; + break; + case SND_SOC_DAIFMT_DSP_A: + i2s_priv->format = MTK_DAI_ETDM_FORMAT_DSPA; + break; + case SND_SOC_DAIFMT_DSP_B: + i2s_priv->format = MTK_DAI_ETDM_FORMAT_DSPB; + break; + default: + return -EINVAL; + } + + dev_info(afe->dev, "%s(), dai->id: %d, i2s_priv->format: 0x%x\n", __func__, + dai->id, i2s_priv->format); + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_i2s_ops = { + .hw_params = mtk_dai_i2s_hw_params, + .set_sysclk = mtk_dai_i2s_set_sysclk, + .set_fmt = mtk_dai_i2s_set_fmt, +}; + +/* dai driver */ +#define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) + +#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_384000) +#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S8 |\ + SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +#define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) +#define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { + { + .name = "CONNSYS_I2S", + .id = MT8196_DAI_CONNSYS_I2S, + .capture = { + .stream_name = "Connsys I2S", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_CONNSYS_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_connsys_i2s_ops, + }, + { + .name = "I2SIN0", + .id = MT8196_DAI_I2S_IN0, + .capture = { + .stream_name = "I2SIN0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SIN1", + .id = MT8196_DAI_I2S_IN1, + .capture = { + .stream_name = "I2SIN1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SIN2", + .id = MT8196_DAI_I2S_IN2, + .capture = { + .stream_name = "I2SIN2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SIN3", + .id = MT8196_DAI_I2S_IN3, + .capture = { + .stream_name = "I2SIN3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SIN4", + .id = MT8196_DAI_I2S_IN4, + .capture = { + .stream_name = "I2SIN4", + .channels_min = 1, + .channels_max = 32, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SIN6", + .id = MT8196_DAI_I2S_IN6, + .capture = { + .stream_name = "I2SIN6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT0", + .id = MT8196_DAI_I2S_OUT0, + .playback = { + .stream_name = "I2SOUT0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT1", + .id = MT8196_DAI_I2S_OUT1, + .playback = { + .stream_name = "I2SOUT1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT2", + .id = MT8196_DAI_I2S_OUT2, + .playback = { + .stream_name = "I2SOUT2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT3", + .id = MT8196_DAI_I2S_OUT3, + .playback = { + .stream_name = "I2SOUT3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT4", + .id = MT8196_DAI_I2S_OUT4, + .playback = { + .stream_name = "I2SOUT4", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2SOUT6", + .id = MT8196_DAI_I2S_OUT6, + .playback = { + .stream_name = "I2SOUT6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "FMI2S_MASTER", + .id = MT8196_DAI_FM_I2S_MASTER, + .capture = { + .stream_name = "FMI2S_MASTER", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, +}; + +static const struct mtk_afe_i2s_priv mt8196_i2s_priv[DAI_I2S_NUM] = { + [DAI_I2SIN0] = { + .id = MT8196_DAI_I2S_IN0, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sin0-share", + .share_i2s_id = -1, + }, + [DAI_I2SIN1] = { + .id = MT8196_DAI_I2S_IN1, + .mclk_id = MT8196_I2SIN1_MCK, + .share_property_name = "i2sin1-share", + .share_i2s_id = -1, + }, + [DAI_I2SIN2] = { + .id = MT8196_DAI_I2S_IN2, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sin2-share", + .share_i2s_id = -1, + }, + [DAI_I2SIN3] = { + .id = MT8196_DAI_I2S_IN3, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sin3-share", + .share_i2s_id = -1, + }, + [DAI_I2SIN4] = { + .id = MT8196_DAI_I2S_IN4, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sin4-share", + .share_i2s_id = -1, + }, + [DAI_I2SIN6] = { + .id = MT8196_DAI_I2S_IN6, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout6-share", + .share_i2s_id = -1, + }, + [DAI_I2SOUT0] = { + .id = MT8196_DAI_I2S_OUT0, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout0-share", + .share_i2s_id = MT8196_DAI_I2S_IN0, + }, + [DAI_I2SOUT1] = { + .id = MT8196_DAI_I2S_OUT1, + .mclk_id = MT8196_I2SIN1_MCK, + .share_property_name = "i2sout1-share", + .share_i2s_id = MT8196_DAI_I2S_IN1, + }, + [DAI_I2SOUT2] = { + .id = MT8196_DAI_I2S_OUT2, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout2-share", + .share_i2s_id = MT8196_DAI_I2S_IN2, + }, + [DAI_I2SOUT3] = { + .id = MT8196_DAI_I2S_OUT3, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout3-share", + .share_i2s_id = MT8196_DAI_I2S_IN3, + }, + [DAI_I2SOUT4] = { + .id = MT8196_DAI_I2S_OUT4, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout4-share", + .share_i2s_id = MT8196_DAI_I2S_IN4, + }, + [DAI_I2SOUT6] = { + .id = MT8196_DAI_I2S_OUT6, + .mclk_id = MT8196_I2SIN0_MCK, + .share_property_name = "i2sout6-share", + .share_i2s_id = MT8196_DAI_I2S_IN6, + }, + [DAI_FMI2S_MASTER] = { + .id = MT8196_DAI_FM_I2S_MASTER, + .mclk_id = MT8196_FMI2S_MCK, + .share_property_name = "fmi2s-share", + .share_i2s_id = -1, + }, +}; +static int etdm_parse_dt(struct mtk_base_afe *afe) +{ + int ret; + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2sin4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_IN4]; + struct mtk_afe_i2s_priv *i2sout4_priv = afe_priv->dai_priv[MT8196_DAI_I2S_OUT4]; + unsigned int ch_num_in; + unsigned int ch_num_out; + unsigned int sync_in; + unsigned int sync_out; + unsigned int ip_mode; + + dev_info(afe->dev, "%s()\n", __func__); + + /* get etdm ch */ + ret = of_property_read_u32(afe->dev->of_node, "etdm-out-ch", &ch_num_out); + if (ret) { + dev_info(afe->dev, "%s() failed to read etdm-out-ch\n", __func__); + return -EINVAL; + } + i2sout4_priv->ch_num = ch_num_out; + dev_info(afe->dev, "%s() etdm-out-ch: %d\n", __func__, ch_num_out); + + ret = of_property_read_u32(afe->dev->of_node, "etdm-in-ch", &ch_num_in); + if (ret) { + dev_info(afe->dev, "%s() failed to read etdm-in-ch\n", __func__); + return -EINVAL; + } + i2sin4_priv->ch_num = ch_num_in; + dev_info(afe->dev, "%s() etdm-in-ch: %d\n", __func__, ch_num_in); + + /* get etdm sync */ + ret = of_property_read_u32(afe->dev->of_node, "etdm-out-sync", &sync_out); + if (ret) { + dev_info(afe->dev, "%s() failed to read etdm-out-sync\n", __func__); + return -EINVAL; + } + i2sout4_priv->sync = sync_out; + dev_info(afe->dev, "%s() etdm-out-sync: %d\n", __func__, sync_out); + + ret = of_property_read_u32(afe->dev->of_node, "etdm-in-sync", &sync_in); + if (ret) { + dev_info(afe->dev, "%s() failed to read etdm-in-sync\n", __func__); + return -EINVAL; + } + i2sin4_priv->sync = sync_in; + dev_info(afe->dev, "%s() etdm-in-sync: %d\n", __func__, sync_in); + + /* get etdm ip mode */ + ret = of_property_read_u32(afe->dev->of_node, "etdm-ip-mode", &ip_mode); + if (ret) { + dev_info(afe->dev, "%s() failed to read etdm-ip-mode\n", __func__); + return -EINVAL; + } + i2sin4_priv->ip_mode = ip_mode; + dev_info(afe->dev, "%s() etdm-ip-mode: %d\n", __func__, ip_mode); + + return 0; +} + +int mt8196_dai_i2s_get_share(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + const struct device_node *of_node = afe->dev->of_node; + const char *of_str; + const char *property_name; + struct mtk_afe_i2s_priv *i2s_priv; + int i; + + for (i = 0; i < DAI_I2S_NUM; i++) { + i2s_priv = afe_priv->dai_priv[mt8196_i2s_priv[i].id]; + property_name = mt8196_i2s_priv[i].share_property_name; + if (of_property_read_string(of_node, property_name, &of_str)) + continue; + i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); + } + return 0; +} + +int mt8196_dai_i2s_set_priv(struct mtk_base_afe *afe) +{ + int i; + int ret; + + for (i = 0; i < DAI_I2S_NUM; i++) { + ret = mt8196_dai_set_priv(afe, mt8196_i2s_priv[i].id, + sizeof(struct mtk_afe_i2s_priv), + &mt8196_i2s_priv[i]); + if (ret) + return ret; + } + return 0; +} + +int mt8196_dai_i2s_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + int ret; + + dev_info(afe->dev, "%s() successfully start\n", __func__); + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_i2s_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); + + dai->controls = mtk_dai_i2s_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls); + dai->dapm_widgets = mtk_dai_i2s_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); + dai->dapm_routes = mtk_dai_i2s_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); + + /* set all dai i2s private data */ + ret = mt8196_dai_i2s_set_priv(afe); + if (ret) + return ret; + + /* parse share i2s */ + ret = mt8196_dai_i2s_get_share(afe); + if (ret) + return ret; + + /* for customer to change ch_num & sync & ipmode from dts */ + ret = etdm_parse_dt(afe); + if (ret) { + dev_info(afe->dev, "%s() fail to parse dts: %d\n", __func__, ret); + return ret; + } + + return 0; +} diff --git a/sound/soc/mediatek/mt8196/mt8196-dai-tdm.c b/sound/soc/mediatek/mt8196/mt8196-dai-tdm.c new file mode 100644 index 0000000000000..0c614746e7964 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-dai-tdm.c @@ -0,0 +1,828 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI TDM Control + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include "mt8196-afe-clk.h" +#include "mt8196-afe-common.h" +#include "mt8196-interconnection.h" + +struct mtk_afe_tdm_priv { + int bck_id; + int bck_rate; + + int mclk_id; + int mclk_multiple; /* according to sample rate */ + int mclk_rate; + int mclk_apll; +}; + +enum { + TDM_WLEN_16_BIT = 1, + TDM_WLEN_32_BIT = 2, +}; + +enum { + TDM_CHANNEL_BCK_16 = 0, + TDM_CHANNEL_BCK_24 = 1, + TDM_CHANNEL_BCK_32 = 2, +}; + +enum { + TDM_CHANNEL_NUM_2 = 0, + TDM_CHANNEL_NUM_4 = 1, + TDM_CHANNEL_NUM_8 = 2, +}; + +enum { + TDM_CH_START_O30_O31 = 0, + TDM_CH_START_O32_O33, + TDM_CH_START_O34_O35, + TDM_CH_START_O36_O37, + TDM_CH_ZERO, +}; + +enum { + DPTX_CHANNEL_2, + DPTX_CHANNEL_8, +}; + +enum { + DPTX_WLEN_24_BIT, + DPTX_WLEN_16_BIT, +}; + +enum { + DPTX_CH_EN_MASK_2CH = 0x3, + DPTX_CH_EN_MASK_4CH = 0xf, + DPTX_CH_EN_MASK_6CH = 0x3f, + DPTX_CH_EN_MASK_8CH = 0xff, +}; + +static unsigned int get_tdm_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + TDM_WLEN_16_BIT : TDM_WLEN_32_BIT; +} + +static unsigned int get_tdm_channel_bck(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + TDM_CHANNEL_BCK_16 : TDM_CHANNEL_BCK_32; +} + +static unsigned int get_tdm_lrck_width(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) - 1; +} + +static unsigned int get_tdm_ch(unsigned int ch) +{ + switch (ch) { + case 1: + case 2: + return TDM_CHANNEL_NUM_2; + case 3: + case 4: + return TDM_CHANNEL_NUM_4; + case 5: + case 6: + case 7: + case 8: + default: + return TDM_CHANNEL_NUM_8; + } +} + +static unsigned int get_dptx_ch_enable_mask(unsigned int ch) +{ + switch (ch) { + case 1: + case 2: + return DPTX_CH_EN_MASK_2CH; + case 3: + case 4: + return DPTX_CH_EN_MASK_4CH; + case 5: + case 6: + return DPTX_CH_EN_MASK_6CH; + case 7: + case 8: + return DPTX_CH_EN_MASK_8CH; + default: + pr_info("%s(), invalid channel num, default use 2ch\n", + __func__); + return DPTX_CH_EN_MASK_2CH; + } +} + +static unsigned int get_dptx_ch(unsigned int ch) +{ + if (ch == 2) + return DPTX_CHANNEL_2; + else + return DPTX_CHANNEL_8; +} + +static unsigned int get_dptx_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + DPTX_WLEN_16_BIT : DPTX_WLEN_24_BIT; +} + +/* interconnection */ +enum { + HDMI_CONN_CH0 = 0, + HDMI_CONN_CH1, + HDMI_CONN_CH2, + HDMI_CONN_CH3, + HDMI_CONN_CH4, + HDMI_CONN_CH5, + HDMI_CONN_CH6, + HDMI_CONN_CH7, +}; + +static const char *const hdmi_conn_mux_map[] = { + "CH0", "CH1", "CH2", "CH3", + "CH4", "CH5", "CH6", "CH7", +}; + +static int hdmi_conn_mux_map_value[] = { + HDMI_CONN_CH0, + HDMI_CONN_CH1, + HDMI_CONN_CH2, + HDMI_CONN_CH3, + HDMI_CONN_CH4, + HDMI_CONN_CH5, + HDMI_CONN_CH6, + HDMI_CONN_CH7, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_0_SFT, + HDMI_O_0_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch0_mux_control = + SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_1_SFT, + HDMI_O_1_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch1_mux_control = + SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_2_SFT, + HDMI_O_2_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch2_mux_control = + SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_3_SFT, + HDMI_O_3_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch3_mux_control = + SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_4_SFT, + HDMI_O_4_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch4_mux_control = + SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_5_SFT, + HDMI_O_5_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch5_mux_control = + SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_6_SFT, + HDMI_O_6_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch6_mux_control = + SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_7_SFT, + HDMI_O_7_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new hdmi_ch7_mux_control = + SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum); + +static const char *const tdm_out_mux_map[] = { + "Disconnect", "Connect", +}; + +static int tdm_out_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(hdmi_out_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + tdm_out_mux_map, + tdm_out_mux_map_value); +static const struct snd_kcontrol_new hdmi_out_mux_control = + SOC_DAPM_ENUM("HDMI_OUT_MUX", hdmi_out_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_out_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + tdm_out_mux_map, + tdm_out_mux_map_value); +static const struct snd_kcontrol_new dptx_out_mux_control = + SOC_DAPM_ENUM("DPTX_OUT_MUX", dptx_out_mux_map_enum); + + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_virtual_out_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + tdm_out_mux_map, + tdm_out_mux_map_value); + +static const struct snd_kcontrol_new dptx_virtual_out_mux_control = + SOC_DAPM_ENUM("DPTX_VIRTUAL_OUT_MUX", dptx_virtual_out_mux_map_enum); + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_TDM_MCK_EN, + SUPPLY_SEQ_TDM_BCK_EN, + SUPPLY_SEQ_TDM_DPTX_MCK_EN, + SUPPLY_SEQ_TDM_DPTX_BCK_EN, +}; + +static int get_tdm_id_by_name(const char *name) +{ + if (strstr(name, "DPTX")) + return MT8196_DAI_TDM_DPTX; + else + return MT8196_DAI_TDM; +} + +static int mtk_tdm_bck_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + dev_info(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n", + __func__, w->name, event, dai_id); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_mck_enable(afe, tdm_priv->bck_id, tdm_priv->bck_rate); + break; + case SND_SOC_DAPM_POST_PMD: + mt8196_mck_disable(afe, tdm_priv->bck_id); + break; + default: + break; + } + + return 0; +} + +static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + dev_info(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n", + __func__, w->name, event, dai_id); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8196_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + tdm_priv->mclk_rate = 0; + mt8196_mck_disable(afe, tdm_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = { + SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch0_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch1_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch2_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch3_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch4_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch5_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch6_mux_control), + SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_ch7_mux_control), + SND_SOC_DAPM_MUX("HDMI_OUT_MUX", SND_SOC_NOPM, 0, 0, + &hdmi_out_mux_control), + SND_SOC_DAPM_MUX("DPTX_OUT_MUX", SND_SOC_NOPM, 0, 0, + &dptx_out_mux_control), + + SND_SOC_DAPM_SUPPLY_S("TDM_BCK", SUPPLY_SEQ_TDM_BCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_bck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_MCK", SUPPLY_SEQ_TDM_MCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_mck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_DPTX_BCK", SUPPLY_SEQ_TDM_DPTX_BCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_bck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_DPTX_MCK", SUPPLY_SEQ_TDM_DPTX_MCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_mck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("DPTX_VIRTUAL_OUT_MUX", + SND_SOC_NOPM, 0, 0, &dptx_virtual_out_mux_control), + SND_SOC_DAPM_OUTPUT("DPTX_VIRTUAL_OUT"), +}; + +static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + int cur_apll; + + /* which apll */ + cur_apll = mt8196_get_apll_by_name(afe, source->name); + + return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = { + {"HDMI_CH0_MUX", "CH0", "HDMI"}, + {"HDMI_CH0_MUX", "CH1", "HDMI"}, + {"HDMI_CH0_MUX", "CH2", "HDMI"}, + {"HDMI_CH0_MUX", "CH3", "HDMI"}, + {"HDMI_CH0_MUX", "CH4", "HDMI"}, + {"HDMI_CH0_MUX", "CH5", "HDMI"}, + {"HDMI_CH0_MUX", "CH6", "HDMI"}, + {"HDMI_CH0_MUX", "CH7", "HDMI"}, + + {"HDMI_CH1_MUX", "CH0", "HDMI"}, + {"HDMI_CH1_MUX", "CH1", "HDMI"}, + {"HDMI_CH1_MUX", "CH2", "HDMI"}, + {"HDMI_CH1_MUX", "CH3", "HDMI"}, + {"HDMI_CH1_MUX", "CH4", "HDMI"}, + {"HDMI_CH1_MUX", "CH5", "HDMI"}, + {"HDMI_CH1_MUX", "CH6", "HDMI"}, + {"HDMI_CH1_MUX", "CH7", "HDMI"}, + + {"HDMI_CH2_MUX", "CH0", "HDMI"}, + {"HDMI_CH2_MUX", "CH1", "HDMI"}, + {"HDMI_CH2_MUX", "CH2", "HDMI"}, + {"HDMI_CH2_MUX", "CH3", "HDMI"}, + {"HDMI_CH2_MUX", "CH4", "HDMI"}, + {"HDMI_CH2_MUX", "CH5", "HDMI"}, + {"HDMI_CH2_MUX", "CH6", "HDMI"}, + {"HDMI_CH2_MUX", "CH7", "HDMI"}, + + {"HDMI_CH3_MUX", "CH0", "HDMI"}, + {"HDMI_CH3_MUX", "CH1", "HDMI"}, + {"HDMI_CH3_MUX", "CH2", "HDMI"}, + {"HDMI_CH3_MUX", "CH3", "HDMI"}, + {"HDMI_CH3_MUX", "CH4", "HDMI"}, + {"HDMI_CH3_MUX", "CH5", "HDMI"}, + {"HDMI_CH3_MUX", "CH6", "HDMI"}, + {"HDMI_CH3_MUX", "CH7", "HDMI"}, + + {"HDMI_CH4_MUX", "CH0", "HDMI"}, + {"HDMI_CH4_MUX", "CH1", "HDMI"}, + {"HDMI_CH4_MUX", "CH2", "HDMI"}, + {"HDMI_CH4_MUX", "CH3", "HDMI"}, + {"HDMI_CH4_MUX", "CH4", "HDMI"}, + {"HDMI_CH4_MUX", "CH5", "HDMI"}, + {"HDMI_CH4_MUX", "CH6", "HDMI"}, + {"HDMI_CH4_MUX", "CH7", "HDMI"}, + + {"HDMI_CH5_MUX", "CH0", "HDMI"}, + {"HDMI_CH5_MUX", "CH1", "HDMI"}, + {"HDMI_CH5_MUX", "CH2", "HDMI"}, + {"HDMI_CH5_MUX", "CH3", "HDMI"}, + {"HDMI_CH5_MUX", "CH4", "HDMI"}, + {"HDMI_CH5_MUX", "CH5", "HDMI"}, + {"HDMI_CH5_MUX", "CH6", "HDMI"}, + {"HDMI_CH5_MUX", "CH7", "HDMI"}, + + {"HDMI_CH6_MUX", "CH0", "HDMI"}, + {"HDMI_CH6_MUX", "CH1", "HDMI"}, + {"HDMI_CH6_MUX", "CH2", "HDMI"}, + {"HDMI_CH6_MUX", "CH3", "HDMI"}, + {"HDMI_CH6_MUX", "CH4", "HDMI"}, + {"HDMI_CH6_MUX", "CH5", "HDMI"}, + {"HDMI_CH6_MUX", "CH6", "HDMI"}, + {"HDMI_CH6_MUX", "CH7", "HDMI"}, + + {"HDMI_CH7_MUX", "CH0", "HDMI"}, + {"HDMI_CH7_MUX", "CH1", "HDMI"}, + {"HDMI_CH7_MUX", "CH2", "HDMI"}, + {"HDMI_CH7_MUX", "CH3", "HDMI"}, + {"HDMI_CH7_MUX", "CH4", "HDMI"}, + {"HDMI_CH7_MUX", "CH5", "HDMI"}, + {"HDMI_CH7_MUX", "CH6", "HDMI"}, + {"HDMI_CH7_MUX", "CH7", "HDMI"}, + + {"HDMI_OUT_MUX", "Connect", "HDMI_CH0_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH1_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH2_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH3_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH4_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH5_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH6_MUX"}, + {"HDMI_OUT_MUX", "Connect", "HDMI_CH7_MUX"}, + + {"DPTX_OUT_MUX", "Connect", "HDMI_CH0_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH1_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH2_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH3_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH4_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH5_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH6_MUX"}, + {"DPTX_OUT_MUX", "Connect", "HDMI_CH7_MUX"}, + + {"TDM", NULL, "HDMI_OUT_MUX"}, + {"TDM", NULL, "TDM_BCK"}, + + {"TDM_DPTX", NULL, "DPTX_OUT_MUX"}, + {"TDM_DPTX", NULL, "TDM_DPTX_BCK"}, + + {"TDM_BCK", NULL, "TDM_MCK"}, + {"TDM_DPTX_BCK", NULL, "TDM_DPTX_MCK"}, + {"TDM_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_DPTX_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_DPTX_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, + + {"DPTX_VIRTUAL_OUT_MUX", "Connect", "TDM_DPTX"}, + {"DPTX_VIRTUAL_OUT", NULL, "DPTX_VIRTUAL_OUT_MUX"}, +}; + +/* dai ops */ +static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe, + struct mtk_afe_tdm_priv *tdm_priv, + int freq) +{ + int apll; + int apll_rate; + + apll = mt8196_get_apll_by_rate(afe, freq); + apll_rate = mt8196_get_apll_rate(afe, apll); + + if (freq > apll_rate) { + AUDIO_AEE("freq > apll rate"); + return -EINVAL; + } + + if (apll_rate % freq != 0) { + AUDIO_AEE("APLL cannot generate freq Hz"); + return -EINVAL; + } + + tdm_priv->mclk_rate = freq; + tdm_priv->mclk_apll = apll; + + return 0; +} + +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + int tdm_id = dai->id; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; + unsigned int rate = params_rate(params); + unsigned int channels = params_channels(params); + snd_pcm_format_t format = params_format(params); + unsigned int tdm_con = 0; + + /* calculate mclk_rate, if not set explicitly */ + if (!tdm_priv->mclk_rate) { + tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple; + mtk_dai_tdm_cal_mclk(afe, + tdm_priv, + tdm_priv->mclk_rate); + } + + /* calculate bck */ + tdm_priv->bck_rate = rate * + channels * + snd_pcm_format_physical_width(format); + + if (tdm_priv->bck_rate > tdm_priv->mclk_rate) + AUDIO_AEE("bck_rate > mclk_rate rate"); + + if (tdm_priv->mclk_rate % tdm_priv->bck_rate != 0) + AUDIO_AEE("bck cannot generate"); + + dev_info(afe->dev, "%s(), id %d, rate %d, channels %d, format %d, mclk_rate %d, bck_rate %d\n", + __func__, + tdm_id, rate, channels, format, + tdm_priv->mclk_rate, tdm_priv->bck_rate); + + /* set tdm */ + tdm_con = 0 << BCK_INVERSE_SFT; + tdm_con |= 0 << LRCK_INVERSE_SFT; + tdm_con |= 0 << DELAY_DATA_SFT; + tdm_con |= 1 << LEFT_ALIGN_SFT; + tdm_con |= get_tdm_wlen(format) << WLEN_SFT; + tdm_con |= get_tdm_ch(channels) << CHANNEL_NUM_SFT; + tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT; + tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT; + regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); + + /* set dptx */ + if (tdm_id == MT8196_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_CHANNEL_ENABLE_MASK_SFT, + get_dptx_ch_enable_mask(channels) << + DPTX_CHANNEL_ENABLE_SFT); + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_CHANNEL_NUMBER_MASK_SFT, + get_dptx_ch(channels) << + DPTX_CHANNEL_NUMBER_SFT); + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_16BIT_MASK_SFT, + get_dptx_wlen(format) << DPTX_16BIT_SFT); + } + switch (channels) { + case 1: + case 2: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 3: + case 4: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 5: + case 6: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 7: + case 8: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT; + break; + default: + tdm_con = 0; + } + regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_CH_NUM_MASK_SFT, + channels << HDMI_CH_NUM_SFT); + + return 0; +} + +static int mtk_dai_tdm_trigger(struct snd_pcm_substream *substream, + int cmd, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int tdm_id = dai->id; + + dev_info(afe->dev, "%s(), cmd %d, tdm_id %d\n", __func__, cmd, tdm_id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* enable Out control */ + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_OUT_ON_MASK_SFT, + 0x1 << HDMI_OUT_ON_SFT); + + /* enable dptx */ + if (tdm_id == MT8196_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_ON_MASK_SFT, 0x1 << + DPTX_ON_SFT); + } + + /* enable tdm */ + regmap_update_bits(afe->regmap, AFE_TDM_CON1, + TDM_EN_MASK_SFT, 0x1 << TDM_EN_SFT); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + /* disable tdm */ + regmap_update_bits(afe->regmap, AFE_TDM_CON1, + TDM_EN_MASK_SFT, 0); + + /* disable dptx */ + if (tdm_id == MT8196_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_ON_MASK_SFT, 0); + } + + /* disable Out control */ + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_OUT_ON_MASK_SFT, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; + + if (!tdm_priv) { + AUDIO_AEE("tdm_priv == NULL"); + return -EINVAL; + } + + if (dir != SND_SOC_CLOCK_OUT) { + AUDIO_AEE("dir != SND_SOC_CLOCK_OUT"); + return -EINVAL; + } + + dev_info(afe->dev, "%s(), freq %d\n", __func__, freq); + + return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); +} + +static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { + .hw_params = mtk_dai_tdm_hw_params, + .trigger = mtk_dai_tdm_trigger, + .set_sysclk = mtk_dai_tdm_set_sysclk, +}; + +/* dai driver */ +#define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = { + { + .name = "TDM", + .id = MT8196_DAI_TDM, + .playback = { + .stream_name = "TDM", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_TDM_RATES, + .formats = MTK_TDM_FORMATS, + }, + .ops = &mtk_dai_tdm_ops, + }, + { + .name = "TDM_DPTX", + .id = MT8196_DAI_TDM_DPTX, + .playback = { + .stream_name = "TDM_DPTX", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_TDM_RATES, + .formats = MTK_TDM_FORMATS, + }, + .ops = &mtk_dai_tdm_ops, + }, +}; + +static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe, + int id) +{ + struct mtk_afe_tdm_priv *tdm_priv; + + tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv), + GFP_KERNEL); + if (!tdm_priv) + return NULL; + + if (id == MT8196_DAI_TDM_DPTX) + tdm_priv->mclk_multiple = 256; + else + tdm_priv->mclk_multiple = 128; + + tdm_priv->bck_id = MT8196_TDMOUT_BCK; + tdm_priv->mclk_id = MT8196_TDMOUT_MCK; + + return tdm_priv; +} + +int mt8196_dai_tdm_register(struct mtk_base_afe *afe) +{ + struct mt8196_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv, *tdm_dptx_priv; + struct mtk_base_afe_dai *dai; + + dev_info(afe->dev, "%s() successfully start\n", __func__); + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_tdm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver); + + dai->dapm_widgets = mtk_dai_tdm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets); + dai->dapm_routes = mtk_dai_tdm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes); + + tdm_priv = init_tdm_priv_data(afe, MT8196_DAI_TDM); + if (!tdm_priv) + return -ENOMEM; + + tdm_dptx_priv = init_tdm_priv_data(afe, MT8196_DAI_TDM_DPTX); + if (!tdm_dptx_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8196_DAI_TDM] = tdm_priv; + afe_priv->dai_priv[MT8196_DAI_TDM_DPTX] = tdm_dptx_priv; + + return 0; +} + diff --git a/sound/soc/mediatek/mt8196/mt8196-interconnection.h b/sound/soc/mediatek/mt8196/mt8196-interconnection.h new file mode 100644 index 0000000000000..e884ec3ecb317 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-interconnection.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Mediatek MT8196 audio driver interconnection definition + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8196_INTERCONNECTION_H_ +#define _MT8196_INTERCONNECTION_H_ + +/* in port define */ + +#define I_CONNSYS_I2S_CH1 0 +#define I_CONNSYS_I2S_CH2 1 +#define I_GAIN0_OUT_CH1 6 +#define I_GAIN0_OUT_CH2 7 +#define I_GAIN1_OUT_CH1 8 +#define I_GAIN1_OUT_CH2 9 +#define I_GAIN2_OUT_CH1 10 +#define I_GAIN2_OUT_CH2 11 +#define I_GAIN3_OUT_CH1 12 +#define I_GAIN3_OUT_CH2 13 +#define I_STF_CH1 14 +#define I_ADDA_UL_CH1 16 +#define I_ADDA_UL_CH2 17 +#define I_ADDA_UL_CH3 18 +#define I_ADDA_UL_CH4 19 +#define I_UL_PROX_CH1 20 +#define I_UL_PROX_CH2 21 +#define I_ADDA_UL_CH5 24 +#define I_ADDA_UL_CH6 25 +#define I_DMIC0_CH1 28 +#define I_DMIC0_CH2 29 +#define I_DMIC1_CH1 30 +#define I_DMIC1_CH2 31 + +/* in port define >= 32 */ +#define I_32_OFFSET 32 +#define I_DL0_CH1 (32 - I_32_OFFSET) +#define I_DL0_CH2 (33 - I_32_OFFSET) +#define I_DL1_CH1 (34 - I_32_OFFSET) +#define I_DL1_CH2 (35 - I_32_OFFSET) +#define I_DL2_CH1 (36 - I_32_OFFSET) +#define I_DL2_CH2 (37 - I_32_OFFSET) +#define I_DL3_CH1 (38 - I_32_OFFSET) +#define I_DL3_CH2 (39 - I_32_OFFSET) +#define I_DL4_CH1 (40 - I_32_OFFSET) +#define I_DL4_CH2 (41 - I_32_OFFSET) +#define I_DL5_CH1 (42 - I_32_OFFSET) +#define I_DL5_CH2 (43 - I_32_OFFSET) +#define I_DL6_CH1 (44 - I_32_OFFSET) +#define I_DL6_CH2 (45 - I_32_OFFSET) +#define I_DL7_CH1 (46 - I_32_OFFSET) +#define I_DL7_CH2 (47 - I_32_OFFSET) +#define I_DL8_CH1 (48 - I_32_OFFSET) +#define I_DL8_CH2 (49 - I_32_OFFSET) +#define I_DL_4CH_CH1 (50 - I_32_OFFSET) +#define I_DL_4CH_CH2 (51 - I_32_OFFSET) +#define I_DL_4CH_CH3 (52 - I_32_OFFSET) +#define I_DL_4CH_CH4 (53 - I_32_OFFSET) +#define I_DL_24CH_CH1 (54 - I_32_OFFSET) +#define I_DL_24CH_CH2 (55 - I_32_OFFSET) +#define I_DL_24CH_CH3 (56 - I_32_OFFSET) +#define I_DL_24CH_CH4 (57 - I_32_OFFSET) +#define I_DL_24CH_CH5 (58 - I_32_OFFSET) +#define I_DL_24CH_CH6 (59 - I_32_OFFSET) +#define I_DL_24CH_CH7 (60 - I_32_OFFSET) +#define I_DL_24CH_CH8 (61 - I_32_OFFSET) + +/* in port define >= 64 */ +#define I_64_OFFSET 64 +#define I_DL23_CH1 (78 - I_64_OFFSET) +#define I_DL23_CH2 (79 - I_64_OFFSET) +#define I_DL24_CH1 (80 - I_64_OFFSET) +#define I_DL24_CH2 (81 - I_64_OFFSET) +#define I_DL25_CH1 (82 - I_64_OFFSET) +#define I_DL25_CH2 (83 - I_64_OFFSET) +#define I_DL26_CH1 (84 - I_64_OFFSET) +#define I_DL26_CH2 (85 - I_64_OFFSET) + +/* in port define >= 128 */ +#define I_128_OFFSET 128 +#define I_PCM_0_CAP_CH1 (130 - I_128_OFFSET) +#define I_PCM_0_CAP_CH2 (131 - I_128_OFFSET) +#define I_PCM_1_CAP_CH1 (132 - I_128_OFFSET) +#define I_PCM_1_CAP_CH2 (133 - I_128_OFFSET) +#define I_I2SIN0_CH1 (134 - I_128_OFFSET) +#define I_I2SIN0_CH2 (135 - I_128_OFFSET) +#define I_I2SIN1_CH1 (136 - I_128_OFFSET) +#define I_I2SIN1_CH2 (137 - I_128_OFFSET) +#define I_I2SIN2_CH1 (138 - I_128_OFFSET) +#define I_I2SIN2_CH2 (139 - I_128_OFFSET) +#define I_I2SIN3_CH1 (140 - I_128_OFFSET) +#define I_I2SIN3_CH2 (141 - I_128_OFFSET) +#define I_I2SIN4_CH1 (142 - I_128_OFFSET) +#define I_I2SIN4_CH2 (143 - I_128_OFFSET) +#define I_I2SIN4_CH3 (144 - I_128_OFFSET) +#define I_I2SIN4_CH4 (145 - I_128_OFFSET) +#define I_I2SIN4_CH5 (146 - I_128_OFFSET) +#define I_I2SIN4_CH6 (147 - I_128_OFFSET) +#define I_I2SIN4_CH7 (148 - I_128_OFFSET) +#define I_I2SIN4_CH8 (149 - I_128_OFFSET) + +/* in port define >= 160 */ +#define I_160_OFFSET 160 +#define I_I2SIN6_CH1 (166 - I_160_OFFSET) +#define I_I2SIN6_CH2 (167 - I_160_OFFSET) + +/* in port define >= 192 */ +#define I_192_OFFSET 192 +#define I_SRC_0_OUT_CH1 (198 - I_192_OFFSET) +#define I_SRC_0_OUT_CH2 (199 - I_192_OFFSET) +#define I_SRC_1_OUT_CH1 (200 - I_192_OFFSET) +#define I_SRC_1_OUT_CH2 (201 - I_192_OFFSET) +#define I_SRC_2_OUT_CH1 (202 - I_192_OFFSET) +#define I_SRC_2_OUT_CH2 (203 - I_192_OFFSET) +#define I_SRC_3_OUT_CH1 (204 - I_192_OFFSET) +#define I_SRC_3_OUT_CH2 (205 - I_192_OFFSET) + +#endif diff --git a/sound/soc/mediatek/mt8196/mt8196-mt6681.c b/sound/soc/mediatek/mt8196/mt8196-mt6681.c new file mode 100644 index 0000000000000..af714d347ff88 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-mt6681.c @@ -0,0 +1,884 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8196-mt6681.c -- mt8196 mt6681 ALSA SoC machine driver + * + * Copyright (c) 2023 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mtk-afe-platform-driver.h" +#include "mt8196-afe-common.h" +#include "mt8196-afe-clk.h" +#include "mt8196-afe-gpio.h" + +#include "../../codecs/nau8825.h" +#include "../../codecs/rt5682s.h" + +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-soundcard-driver.h" +#include "../common/mtk-dsp-sof-common.h" +#include "../common/mtk-soc-card.h" + +#define MT8196_SUPPORT_ADSP + +#define NAU8825_HS_PRESENT BIT(0) +#define RT5682S_HS_PRESENT BIT(1) +#define RT5650_HS_PRESENT BIT(2) + +/* + * Nau88l25 + */ +#define NAU8825_CODEC_DAI "nau8825-hifi" + +/* + * Rt5682s + */ +#define RT5682S_CODEC_DAI "rt5682s-aif1" + +/* + * Rt5650 + */ +#define RT5650_CODEC_DAI "rt5645-aif1" + +#define SOF_DMA_DL1 "SOF_DMA_DL1" +#define SOF_DMA_DL_24CH "SOF_DMA_DL_24CH" +#define SOF_DMA_UL0 "SOF_DMA_UL0" +#define SOF_DMA_UL1 "SOF_DMA_UL1" +#define SOF_DMA_UL2 "SOF_DMA_UL2" + +enum mt8196_jacks { + MT8196_JACK_HEADSET, + MT8196_JACK_DP, + MT8196_JACK_HDMI, + MT8196_JACK_MAX, +}; + +static struct snd_soc_jack_pin mt8196_dp_jack_pins[] = { + { + .pin = "DP", + .mask = SND_JACK_LINEOUT, + }, +}; + +static struct snd_soc_jack_pin mt8196_hdmi_jack_pins[] = { + { + .pin = "HDMI", + .mask = SND_JACK_LINEOUT, + }, +}; + +static struct snd_soc_jack_pin nau8825_jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_kcontrol_new mt8196_dumb_spk_controls[] = { + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static const struct snd_soc_dapm_widget mt8196_dumb_spk_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static const struct snd_soc_dapm_widget mt8196_nau8825_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SINK("DP"), +}; + +static const struct snd_kcontrol_new mt8196_nau8825_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +/* + * if need additional control for the ext spk amp that is connected + * after Lineout Buffer / HP Buffer on the codec, put the control in + * mt8196_mt6681_spk_amp_event() + */ +#define EXT_SPK_AMP_W_NAME "Ext_Speaker_Amp" + + +static struct snd_soc_card mt8196_mt6681_soc_card; + +static const struct snd_soc_dapm_widget mt8196_mt6681_widgets[] = { +}; + +static const struct snd_soc_dapm_route mt8196_mt6681_routes[] = { +}; + +static const struct snd_kcontrol_new mt8196_mt6681_controls[] = { + SOC_DAPM_PIN_SWITCH(EXT_SPK_AMP_W_NAME), +}; + +/* + * define mtk_spk_i2s_mck node in dts when need mclk, + * BE i2s need assign snd_soc_ops = mt8196_mt6681_i2s_ops + */ +static int mt8196_mt6681_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 128; + unsigned int mclk_fs = rate * mclk_fs_ratio; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + + return snd_soc_dai_set_sysclk(cpu_dai, + 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8196_mt6681_i2s_ops = { + .hw_params = mt8196_mt6681_i2s_hw_params, +}; + +static int mt8196_dptx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 256; + unsigned int mclk_fs = rate * mclk_fs_ratio; + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); + + return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8196_dptx_ops = { + .hw_params = mt8196_dptx_hw_params, +}; + +static int mt8196_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__); + + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); + + return 0; +} + +static int mt8196_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__); + + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); + return 0; +} + +#if defined(MT8196_SUPPORT_ADSP) +static int mt8196_sof_be_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *cmpnt_afe = NULL; + struct snd_soc_pcm_runtime *runtime; + + /* find afe component */ + for_each_card_rtds(rtd->card, runtime) { + cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME); + if (cmpnt_afe) { + dev_info(rtd->dev, "component->name: %s\n", cmpnt_afe->name); + break; + } + } + + if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) { + dev_err(rtd->dev, "afe pm runtime is not active!!\n"); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_ops mt8196_sof_be_ops = { + .hw_params = mt8196_sof_be_hw_params, +}; + +static const struct sof_conn_stream g_sof_conn_streams[] = { + { + .sof_link = "AFE_SOF_DL1", + .sof_dma = SOF_DMA_DL1, + .stream_dir = SNDRV_PCM_STREAM_PLAYBACK + }, + { + .sof_link = "AFE_SOF_DL_24CH", + .sof_dma = SOF_DMA_DL_24CH, + .stream_dir = SNDRV_PCM_STREAM_PLAYBACK + }, + { + .sof_link = "AFE_SOF_UL0", + .sof_dma = SOF_DMA_UL0, + .stream_dir = SNDRV_PCM_STREAM_CAPTURE + }, + { + .sof_link = "AFE_SOF_UL1", + .sof_dma = SOF_DMA_UL1, + .stream_dir = SNDRV_PCM_STREAM_CAPTURE + }, + { + .sof_link = "AFE_SOF_UL2", + .sof_dma = SOF_DMA_UL2, + .stream_dir = SNDRV_PCM_STREAM_CAPTURE + }, +}; +#endif + +/* FE */ +SND_SOC_DAILINK_DEFS(playback1, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback2, + DAILINK_COMP_ARRAY(COMP_CPU("DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback_24ch, + DAILINK_COMP_ARRAY(COMP_CPU("DL_24CH")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture0, + DAILINK_COMP_ARRAY(COMP_CPU("UL0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture1, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture2, + DAILINK_COMP_ARRAY(COMP_CPU("UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture_cm0, + DAILINK_COMP_ARRAY(COMP_CPU("UL_CM0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback_hdmi, + DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +/* BE */ +SND_SOC_DAILINK_DEFS(ap_dmic, + DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(ap_dmic_ch34, + DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_CH34")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(ap_dmic_multich, + DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_MULTICH")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sin6, + DAILINK_COMP_ARRAY(COMP_CPU("I2SIN6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sout3, + DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sout4, + DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sout6, + DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(tdm_dptx, + DAILINK_COMP_ARRAY(COMP_CPU("TDM_DPTX")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +#if defined(MT8196_SUPPORT_ADSP) +SND_SOC_DAILINK_DEFS(AFE_SOF_DL_24CH, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL_24CH")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_DL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_UL0, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_UL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_UL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +#endif + +static struct snd_soc_dai_link mt8196_mt6681_dai_links[] = { + /* Front End DAI links */ + { + .name = "DL_24CH_FE", + .stream_name = "DL_24CH Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback_24ch), + }, + { + .name = "DL1_FE", + .stream_name = "DL1 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback1), + }, + { + .name = "UL0_FE", + .stream_name = "UL0 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture0), + }, + { + .name = "UL1_FE", + .stream_name = "UL1 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture1), + }, + { + .name = "UL2_FE", + .stream_name = "UL2 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture2), + }, + { + .name = "HDMI_FE", + .stream_name = "HDMI Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback_hdmi), + }, + { + .name = "DL2_FE", + .stream_name = "DL2 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback2), + }, + { + .name = "Capture_9", + .stream_name = "Capture_9", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture_cm0), + }, + /* Back End DAI links */ + { + .name = "I2SIN6_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + | SND_SOC_DAIFMT_GATED, + .ops = &mt8196_mt6681_i2s_ops, + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_suspend = 1, + .be_hw_params_fixup = mt8196_i2s_hw_params_fixup, + SND_SOC_DAILINK_REG(i2sin6), + }, + { + .name = "I2SOUT3_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + | SND_SOC_DAIFMT_GATED, + .ops = &mt8196_mt6681_i2s_ops, + .no_pcm = 1, + .dpcm_playback = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(i2sout3), + }, + { + .name = "I2SOUT4_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + | SND_SOC_DAIFMT_GATED, + .ops = &mt8196_mt6681_i2s_ops, + .no_pcm = 1, + .dpcm_playback = 1, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .be_hw_params_fixup = mt8196_i2s_hw_params_fixup, + SND_SOC_DAILINK_REG(i2sout4), + }, + { + .name = "I2SOUT6_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + | SND_SOC_DAIFMT_GATED, + .ops = &mt8196_mt6681_i2s_ops, + .no_pcm = 1, + .dpcm_playback = 1, + .ignore_suspend = 1, + .be_hw_params_fixup = mt8196_i2s_hw_params_fixup, + SND_SOC_DAILINK_REG(i2sout6), + }, + { + .name = "AP_DMIC_BE", + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(ap_dmic), + }, + { + .name = "AP_DMIC_CH34_BE", + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(ap_dmic_ch34), + }, + { + .name = "AP_DMIC_MULTICH_BE", + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(ap_dmic_multich), + }, + { + .name = "TDM_DPTX_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + | SND_SOC_DAIFMT_GATED, + .ops = &mt8196_dptx_ops, + .be_hw_params_fixup = mt8196_dptx_hw_params_fixup, + .no_pcm = 1, + .dpcm_playback = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(tdm_dptx), + }, +#if defined(MT8196_SUPPORT_ADSP) + /* SOF BE */ + { + .name = "AFE_SOF_DL_24CH", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8196_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_DL_24CH), + }, + { + .name = "AFE_SOF_DL1", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8196_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_DL1), + }, + { + .name = "AFE_SOF_UL0", + .no_pcm = 1, + .dpcm_capture = 1, + .ops = &mt8196_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_UL0), + }, + { + .name = "AFE_SOF_UL1", + .no_pcm = 1, + .dpcm_capture = 1, + .ops = &mt8196_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_UL1), + }, + { + .name = "AFE_SOF_UL2", + .no_pcm = 1, + .dpcm_capture = 1, + .ops = &mt8196_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_UL2), + }, +#endif +}; + +static int mt8196_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret = 0; + + ret = snd_soc_dapm_new_controls(&card->dapm, mt8196_dumb_spk_widgets, + ARRAY_SIZE(mt8196_dumb_spk_widgets)); + if (ret) { + dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, mt8196_dumb_spk_controls, + ARRAY_SIZE(mt8196_dumb_spk_controls)); + if (ret) { + dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret); + return ret; + } + + return 0; +} + +static int mt8196_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_DP]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + int ret = 0; + + ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT, + jack, mt8196_dp_jack_pins, + ARRAY_SIZE(mt8196_dp_jack_pins)); + if (ret) { + dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); + return ret; + } + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", + __func__, component->name, ret); + return ret; + } + + return 0; +} + +static int mt8196_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_HDMI]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + int ret = 0; + + ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, + jack, mt8196_hdmi_jack_pins, + ARRAY_SIZE(mt8196_hdmi_jack_pins)); + if (ret) { + dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); + return ret; + } + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", + __func__, component->name, ret); + return ret; + } + + return 0; +} + +static int mt8196_headset_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_HEADSET]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + int ret; + int type; + + ret = snd_soc_dapm_new_controls(&card->dapm, mt8196_nau8825_widgets, + ARRAY_SIZE(mt8196_nau8825_widgets)); + if (ret) { + dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, mt8196_nau8825_controls, + ARRAY_SIZE(mt8196_nau8825_controls)); + if (ret) { + dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, + nau8825_jack_pins, + ARRAY_SIZE(nau8825_jack_pins)); + if (ret) { + dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3; + ret = snd_soc_component_set_jack(component, jack,(void *)&type); + + if (ret) { + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + + return 0; +}; + +static void mt8196_headset_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + + snd_soc_component_set_jack(component, NULL, NULL); +} + +static int mt8196_nau8825_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int bit_width = params_width(params); + int clk_freq, ret; + + clk_freq = rate * 2 * bit_width; + + /* Configure clock for codec */ + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret); + return ret; + } + + /* Configure pll for codec */ + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq, + params_rate(params) * 256); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8196_nau8825_ops = { + .hw_params = mt8196_nau8825_hw_params, +}; + + +static int mt8196_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(params_format(params)); + if (bitwidth < 0) { + dev_err(card->dev, "invalid bit width: %d\n", bitwidth); + return bitwidth; + } + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); + if (ret) { + dev_err(card->dev, "failed to set tdm slot\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1, + rate * 32, rate * 512); + if (ret) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + dev_info(card->dev, "%s set mclk rate: %d\n", __func__, rate * 512); + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_MCLK, + rate * 512, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + + return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 512, + SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8196_rt5682s_i2s_ops = { + .hw_params = mt8196_rt5682s_i2s_hw_params, +}; + +static int mt8196_mt6681_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy) +{ + struct snd_soc_card *card = soc_card_data->card_data->card; + struct snd_soc_dai_link *dai_link; + bool init_nau8825 = false; + bool init_rt5682s = false; + bool init_rt5650 = false; + bool init_dumb = false; + int i; + + dev_info(card->dev, "%s(), legacy: %d\n", __func__, legacy); + + for_each_card_prelinks(card, i, dai_link) { + if (strcmp(dai_link->name, "TDM_DPTX_BE") == 0) { + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + dai_link->init = mt8196_dptx_codec_init; + } else if (strcmp(dai_link->name, "I2SOUT3_BE") == 0) { + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + dai_link->init = mt8196_hdmi_codec_init; + } else if (strcmp(dai_link->name, "I2SOUT6_BE") == 0 || + strcmp(dai_link->name, "I2SIN6_BE") == 0) { + if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) { + dai_link->ops = &mt8196_nau8825_ops; + if (!init_nau8825) { + dai_link->init = mt8196_headset_codec_init; + dai_link->exit = mt8196_headset_codec_exit; + init_nau8825 = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) { + dai_link->ops = &mt8196_rt5682s_i2s_ops; + if (!init_rt5682s) { + dai_link->init = mt8196_headset_codec_init; + dai_link->exit = mt8196_headset_codec_exit; + init_rt5682s = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, RT5650_CODEC_DAI)) { + dai_link->ops = &mt8196_rt5682s_i2s_ops; + if (!init_rt5650) { + dai_link->init = mt8196_headset_codec_init; + dai_link->exit = mt8196_headset_codec_exit; + init_rt5650 = true; + } + } else { + if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { + if (!init_dumb) { + dai_link->init = mt8196_dumb_amp_init; + init_dumb = true; + } + } + } + } + } + + return 0; +} + +static const struct mtk_sof_priv mt8196_sof_priv = { + .conn_streams = g_sof_conn_streams, + .num_streams = ARRAY_SIZE(g_sof_conn_streams), +}; + +static struct snd_soc_card mt8196_mt6681_soc_card = { + .owner = THIS_MODULE, + .dai_link = mt8196_mt6681_dai_links, + .num_links = ARRAY_SIZE(mt8196_mt6681_dai_links), + .dapm_widgets = mt8196_mt6681_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8196_mt6681_widgets), + .dapm_routes = mt8196_mt6681_routes, + .num_dapm_routes = ARRAY_SIZE(mt8196_mt6681_routes), + .controls = mt8196_mt6681_controls, + .num_controls = ARRAY_SIZE(mt8196_mt6681_controls), +}; + +static const struct mtk_soundcard_pdata mt8196_evb_card = { + .card_name = "mt8196_mt6681", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8196_mt6681_soc_card, + .num_jacks = MT8196_JACK_MAX, + }, + .sof_priv = &mt8196_sof_priv, + .soc_probe = mt8196_mt6681_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8196_nau8825_card = { + .card_name = "mt8196_nau8825", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8196_mt6681_soc_card, + .num_jacks = MT8196_JACK_MAX, + .flags = NAU8825_HS_PRESENT + }, + .sof_priv = &mt8196_sof_priv, + .soc_probe = mt8196_mt6681_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8196_rt5682s_card = { + .card_name = "mt8196_rt5682s", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8196_mt6681_soc_card, + .num_jacks = MT8196_JACK_MAX, + .flags = RT5682S_HS_PRESENT + }, + .sof_priv = &mt8196_sof_priv, + .soc_probe = mt8196_mt6681_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8196_rt5650_card = { + .card_name = "mt8196_rt5650", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8196_mt6681_soc_card, + .num_jacks = MT8196_JACK_MAX, + .flags = RT5650_HS_PRESENT + }, + .sof_priv = &mt8196_sof_priv, + .soc_probe = mt8196_mt6681_soc_card_probe, +}; + +static const struct of_device_id mt8196_mt6681_dt_match[] = { + {.compatible = "mediatek,mt8196-mt6681-sound", .data = &mt8196_evb_card,}, + {.compatible = "mediatek,mt8196-nau8825-sound", .data = &mt8196_nau8825_card,}, + {.compatible = "mediatek,mt8196-rt5682s-sound", .data = &mt8196_rt5682s_card,}, + {.compatible = "mediatek,mt8196-rt5650-sound", .data = &mt8196_rt5650_card,}, + {} +}; +MODULE_DEVICE_TABLE(of, mt8196_mt6681_dt_match); + +static struct platform_driver mt8196_mt6681_driver = { + .driver = { + .name = "mt8196-mt6681", + .of_match_table = mt8196_mt6681_dt_match, + .pm = &snd_soc_pm_ops, + }, + .probe = mtk_soundcard_common_probe, +}; +module_platform_driver(mt8196_mt6681_driver); + +/* Module information */ +MODULE_DESCRIPTION("MT8196 mt6681 ALSA SoC machine driver"); +MODULE_AUTHOR("Darren Ye "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("mt8196 mt6681 soc card"); + diff --git a/sound/soc/mediatek/mt8196/mt8196-reg.h b/sound/soc/mediatek/mt8196/mt8196-reg.h new file mode 100644 index 0000000000000..361a74f241704 --- /dev/null +++ b/sound/soc/mediatek/mt8196/mt8196-reg.h @@ -0,0 +1,12133 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8196-reg.h -- Mediatek 8196 audio driver reg definition + * + * Copyright (c) 2024 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8196_REG_H_ +#define _MT8196_REG_H_ + + /* reg bit enum */ +enum { + MT8196_MEMIF_PBUF_SIZE_32_BYTES, + MT8196_MEMIF_PBUF_SIZE_64_BYTES, + MT8196_MEMIF_PBUF_SIZE_128_BYTES, + MT8196_MEMIF_PBUF_SIZE_256_BYTES, + MT8196_MEMIF_PBUF_SIZE_NUM, +}; + +enum { + MT8196_MEMIF_MAX_LEN_0_BYTES, + MT8196_MEMIF_MAX_LEN_16_BYTES, + MT8196_MEMIF_MAX_LEN_32_BYTES, + MT8196_MEMIF_MAX_LEN_64_BYTES, +}; + +enum { + MT8196_MEMIF_MIN_LEN_NOT_SUPPORT, + MT8196_MEMIF_MIN_LEN_16_BYTES, + MT8196_MEMIF_MIN_LEN_32_BYTES, + MT8196_MEMIF_MIN_LEN_64_BYTES, +}; + +/***************************************************************************** + * R E G I S T E R D E F I N I T I O N + *****************************************************************************/ +/* AUDIO_TOP_CON0 */ +#define PDN_MTKAIFV4_SFT 25 +#define PDN_MTKAIFV4_MASK 0x1 +#define PDN_MTKAIFV4_MASK_SFT (0x1 << 25) +#define PDN_FM_I2S_SFT 24 +#define PDN_FM_I2S_MASK 0x1 +#define PDN_FM_I2S_MASK_SFT (0x1 << 24) +#define PDN_HW_GAIN01_SFT 21 +#define PDN_HW_GAIN01_MASK 0x1 +#define PDN_HW_GAIN01_MASK_SFT (0x1 << 21) +#define PDN_HW_GAIN23_SFT 20 +#define PDN_HW_GAIN23_MASK 0x1 +#define PDN_HW_GAIN23_MASK_SFT (0x1 << 20) +#define PDN_STF_SFT 19 +#define PDN_STF_MASK 0x1 +#define PDN_STF_MASK_SFT (0x1 << 19) +#define PDN_CM0_SFT 18 +#define PDN_CM0_MASK 0x1 +#define PDN_CM0_MASK_SFT (0x1 << 18) +#define PDN_CM1_SFT 17 +#define PDN_CM1_MASK 0x1 +#define PDN_CM1_MASK_SFT (0x1 << 17) +#define PDN_CM2_SFT 16 +#define PDN_CM2_MASK 0x1 +#define PDN_CM2_MASK_SFT (0x1 << 16) +#define PDN_PCM0_SFT 14 +#define PDN_PCM0_MASK 0x1 +#define PDN_PCM0_MASK_SFT (0x1 << 14) +#define PDN_PCM1_SFT 13 +#define PDN_PCM1_MASK 0x1 +#define PDN_PCM1_MASK_SFT (0x1 << 13) + +/* AUDIO_TOP_CON1 */ +#define PDN_UL0_ADC_SFT 23 +#define PDN_UL0_ADC_MASK 0x1 +#define PDN_UL0_ADC_MASK_SFT (0x1 << 23) +#define PDN_UL0_TML_SFT 22 +#define PDN_UL0_TML_MASK 0x1 +#define PDN_UL0_TML_MASK_SFT (0x1 << 22) +#define PDN_UL0_ADC_HIRES_SFT 21 +#define PDN_UL0_ADC_HIRES_MASK 0x1 +#define PDN_UL0_ADC_HIRES_MASK_SFT (0x1 << 21) +#define PDN_UL0_ADC_HIRES_TML_SFT 20 +#define PDN_UL0_ADC_HIRES_TML_MASK 0x1 +#define PDN_UL0_ADC_HIRES_TML_MASK_SFT (0x1 << 20) +#define PDN_UL1_ADC_SFT 19 +#define PDN_UL1_ADC_MASK 0x1 +#define PDN_UL1_ADC_MASK_SFT (0x1 << 19) +#define PDN_UL1_TML_SFT 18 +#define PDN_UL1_TML_MASK 0x1 +#define PDN_UL1_TML_MASK_SFT (0x1 << 18) +#define PDN_UL1_ADC_HIRES_SFT 17 +#define PDN_UL1_ADC_HIRES_MASK 0x1 +#define PDN_UL1_ADC_HIRES_MASK_SFT (0x1 << 17) +#define PDN_UL1_ADC_HIRES_TML_SFT 16 +#define PDN_UL1_ADC_HIRES_TML_MASK 0x1 +#define PDN_UL1_ADC_HIRES_TML_MASK_SFT (0x1 << 16) +#define PDN_UL2_ADC_SFT 15 +#define PDN_UL2_ADC_MASK 0x1 +#define PDN_UL2_ADC_MASK_SFT (0x1 << 15) +#define PDN_UL2_TML_SFT 14 +#define PDN_UL2_TML_MASK 0x1 +#define PDN_UL2_TML_MASK_SFT (0x1 << 14) +#define PDN_UL2_ADC_HIRES_SFT 13 +#define PDN_UL2_ADC_HIRES_MASK 0x1 +#define PDN_UL2_ADC_HIRES_MASK_SFT (0x1 << 13) +#define PDN_UL2_ADC_HIRES_TML_SFT 12 +#define PDN_UL2_ADC_HIRES_TML_MASK 0x1 +#define PDN_UL2_ADC_HIRES_TML_MASK_SFT (0x1 << 12) + +/* AUDIO_TOP_CON2 */ +#define PDN_TDM_OUT_SFT 24 +#define PDN_TDM_OUT_MASK 0x1 +#define PDN_TDM_OUT_MASK_SFT (0x1 << 24) +#define PDN_ETDM_OUT0_SFT 21 +#define PDN_ETDM_OUT0_MASK 0x1 +#define PDN_ETDM_OUT0_MASK_SFT (0x1 << 21) +#define PDN_ETDM_OUT1_SFT 20 +#define PDN_ETDM_OUT1_MASK 0x1 +#define PDN_ETDM_OUT1_MASK_SFT (0x1 << 20) +#define PDN_ETDM_OUT2_SFT 19 +#define PDN_ETDM_OUT2_MASK 0x1 +#define PDN_ETDM_OUT2_MASK_SFT (0x1 << 19) +#define PDN_ETDM_OUT3_SFT 18 +#define PDN_ETDM_OUT3_MASK 0x1 +#define PDN_ETDM_OUT3_MASK_SFT (0x1 << 18) +#define PDN_ETDM_OUT4_SFT 17 +#define PDN_ETDM_OUT4_MASK 0x1 +#define PDN_ETDM_OUT4_MASK_SFT (0x1 << 17) +#define PDN_ETDM_OUT5_SFT 16 +#define PDN_ETDM_OUT5_MASK 0x1 +#define PDN_ETDM_OUT5_MASK_SFT (0x1 << 16) +#define PDN_ETDM_OUT6_SFT 15 +#define PDN_ETDM_OUT6_MASK 0x1 +#define PDN_ETDM_OUT6_MASK_SFT (0x1 << 15) +#define PDN_ETDM_IN0_SFT 13 +#define PDN_ETDM_IN0_MASK 0x1 +#define PDN_ETDM_IN0_MASK_SFT (0x1 << 13) +#define PDN_ETDM_IN1_SFT 12 +#define PDN_ETDM_IN1_MASK 0x1 +#define PDN_ETDM_IN1_MASK_SFT (0x1 << 12) +#define PDN_ETDM_IN2_SFT 11 +#define PDN_ETDM_IN2_MASK 0x1 +#define PDN_ETDM_IN2_MASK_SFT (0x1 << 11) +#define PDN_ETDM_IN3_SFT 10 +#define PDN_ETDM_IN3_MASK 0x1 +#define PDN_ETDM_IN3_MASK_SFT (0x1 << 10) +#define PDN_ETDM_IN4_SFT 9 +#define PDN_ETDM_IN4_MASK 0x1 +#define PDN_ETDM_IN4_MASK_SFT (0x1 << 9) +#define PDN_ETDM_IN5_SFT 8 +#define PDN_ETDM_IN5_MASK 0x1 +#define PDN_ETDM_IN5_MASK_SFT (0x1 << 8) +#define PDN_ETDM_IN6_SFT 7 +#define PDN_ETDM_IN6_MASK 0x1 +#define PDN_ETDM_IN6_MASK_SFT (0x1 << 7) + +/* AUDIO_TOP_CON3 */ +#define PDN_CONNSYS_I2S_ASRC_SFT 25 +#define PDN_CONNSYS_I2S_ASRC_MASK 0x1 +#define PDN_CONNSYS_I2S_ASRC_MASK_SFT (0x1 << 25) +#define PDN_GENERAL0_ASRC_SFT 24 +#define PDN_GENERAL0_ASRC_MASK 0x1 +#define PDN_GENERAL0_ASRC_MASK_SFT (0x1 << 24) +#define PDN_GENERAL1_ASRC_SFT 23 +#define PDN_GENERAL1_ASRC_MASK 0x1 +#define PDN_GENERAL1_ASRC_MASK_SFT (0x1 << 23) +#define PDN_GENERAL2_ASRC_SFT 22 +#define PDN_GENERAL2_ASRC_MASK 0x1 +#define PDN_GENERAL2_ASRC_MASK_SFT (0x1 << 22) +#define PDN_GENERAL3_ASRC_SFT 21 +#define PDN_GENERAL3_ASRC_MASK 0x1 +#define PDN_GENERAL3_ASRC_MASK_SFT (0x1 << 21) +#define PDN_GENERAL4_ASRC_SFT 20 +#define PDN_GENERAL4_ASRC_MASK 0x1 +#define PDN_GENERAL4_ASRC_MASK_SFT (0x1 << 20) +#define PDN_GENERAL5_ASRC_SFT 19 +#define PDN_GENERAL5_ASRC_MASK 0x1 +#define PDN_GENERAL5_ASRC_MASK_SFT (0x1 << 19) +#define PDN_GENERAL6_ASRC_SFT 18 +#define PDN_GENERAL6_ASRC_MASK 0x1 +#define PDN_GENERAL6_ASRC_MASK_SFT (0x1 << 18) +#define PDN_GENERAL7_ASRC_SFT 17 +#define PDN_GENERAL7_ASRC_MASK 0x1 +#define PDN_GENERAL7_ASRC_MASK_SFT (0x1 << 17) +#define PDN_GENERAL8_ASRC_SFT 16 +#define PDN_GENERAL8_ASRC_MASK 0x1 +#define PDN_GENERAL8_ASRC_MASK_SFT (0x1 << 16) +#define PDN_GENERAL9_ASRC_SFT 15 +#define PDN_GENERAL9_ASRC_MASK 0x1 +#define PDN_GENERAL9_ASRC_MASK_SFT (0x1 << 15) +#define PDN_GENERAL10_ASRC_SFT 14 +#define PDN_GENERAL10_ASRC_MASK 0x1 +#define PDN_GENERAL10_ASRC_MASK_SFT (0x1 << 14) +#define PDN_GENERAL11_ASRC_SFT 13 +#define PDN_GENERAL11_ASRC_MASK 0x1 +#define PDN_GENERAL11_ASRC_MASK_SFT (0x1 << 13) +#define PDN_GENERAL12_ASRC_SFT 12 +#define PDN_GENERAL12_ASRC_MASK 0x1 +#define PDN_GENERAL12_ASRC_MASK_SFT (0x1 << 12) +#define PDN_GENERAL13_ASRC_SFT 11 +#define PDN_GENERAL13_ASRC_MASK 0x1 +#define PDN_GENERAL13_ASRC_MASK_SFT (0x1 << 11) +#define PDN_GENERAL14_ASRC_SFT 10 +#define PDN_GENERAL14_ASRC_MASK 0x1 +#define PDN_GENERAL14_ASRC_MASK_SFT (0x1 << 10) +#define PDN_GENERAL15_ASRC_SFT 9 +#define PDN_GENERAL15_ASRC_MASK 0x1 +#define PDN_GENERAL15_ASRC_MASK_SFT (0x1 << 9) + +/* AUDIO_TOP_CON4 */ +#define PDN_APLL_TUNER1_SFT 13 +#define PDN_APLL_TUNER1_MASK 0x1 +#define PDN_APLL_TUNER1_MASK_SFT (0x1 << 13) +#define PDN_APLL_TUNER2_SFT 12 +#define PDN_APLL_TUNER2_MASK 0x1 +#define PDN_APLL_TUNER2_MASK_SFT (0x1 << 12) +#define CG_H208M_CK_SFT 4 +#define CG_H208M_CK_MASK 0x1 +#define CG_H208M_CK_MASK_SFT (0x1 << 4) +#define CG_APLL2_CK_SFT 3 +#define CG_APLL2_CK_MASK 0x1 +#define CG_APLL2_CK_MASK_SFT (0x1 << 3) +#define CG_APLL1_CK_SFT 2 +#define CG_APLL1_CK_MASK 0x1 +#define CG_APLL1_CK_MASK_SFT (0x1 << 2) +#define CG_AUDIO_F26M_CK_SFT 1 +#define CG_AUDIO_F26M_CK_MASK 0x1 +#define CG_AUDIO_F26M_CK_MASK_SFT (0x1 << 1) +#define CG_AUDIO_HOPPING_CK_SFT 0 +#define CG_AUDIO_HOPPING_CK_MASK 0x1 +#define CG_AUDIO_HOPPING_CK_MASK_SFT (0x1 << 0) + +/* AUDIO_ENGEN_CON0 */ +#define MULTI_USER_BYPASS_SFT 17 +#define MULTI_USER_BYPASS_MASK 0x1 +#define MULTI_USER_BYPASS_MASK_SFT (0x1 << 17) +#define MULTI_USER_RST_SFT 16 +#define MULTI_USER_RST_MASK 0x1 +#define MULTI_USER_RST_MASK_SFT (0x1 << 16) +#define AUDIO_F26M_EN_RST_SFT 8 +#define AUDIO_F26M_EN_RST_MASK 0x1 +#define AUDIO_F26M_EN_RST_MASK_SFT (0x1 << 8) +#define AUDIO_APLL2_EN_ON_SFT 3 +#define AUDIO_APLL2_EN_ON_MASK 0x1 +#define AUDIO_APLL2_EN_ON_MASK_SFT (0x1 << 3) +#define AUDIO_APLL1_EN_ON_SFT 2 +#define AUDIO_APLL1_EN_ON_MASK 0x1 +#define AUDIO_APLL1_EN_ON_MASK_SFT (0x1 << 2) +#define AUDIO_F3P25M_EN_ON_SFT 1 +#define AUDIO_F3P25M_EN_ON_MASK 0x1 +#define AUDIO_F3P25M_EN_ON_MASK_SFT (0x1 << 1) +#define AUDIO_26M_EN_ON_SFT 0 +#define AUDIO_26M_EN_ON_MASK 0x1 +#define AUDIO_26M_EN_ON_MASK_SFT (0x1 << 0) + +/* AUDIO_ENGEN_CON0_USER1 */ +#define AUDIO_F26M_EN_RST_SFT 8 +#define AUDIO_F26M_EN_RST_MASK 0x1 +#define AUDIO_F26M_EN_RST_MASK_SFT (0x1 << 8) +#define AUDIO_APLL2_EN_ON_SFT 3 +#define AUDIO_APLL2_EN_ON_MASK 0x1 +#define AUDIO_APLL2_EN_ON_MASK_SFT (0x1 << 3) +#define AUDIO_APLL1_EN_ON_SFT 2 +#define AUDIO_APLL1_EN_ON_MASK 0x1 +#define AUDIO_APLL1_EN_ON_MASK_SFT (0x1 << 2) +#define AUDIO_F3P25M_EN_ON_SFT 1 +#define AUDIO_F3P25M_EN_ON_MASK 0x1 +#define AUDIO_F3P25M_EN_ON_MASK_SFT (0x1 << 1) +#define AUDIO_26M_EN_ON_SFT 0 +#define AUDIO_26M_EN_ON_MASK 0x1 +#define AUDIO_26M_EN_ON_MASK_SFT (0x1 << 0) + +/* AUDIO_ENGEN_CON0_USER2 */ +#define AUDIO_F26M_EN_RST_SFT 8 +#define AUDIO_F26M_EN_RST_MASK 0x1 +#define AUDIO_F26M_EN_RST_MASK_SFT (0x1 << 8) +#define AUDIO_APLL2_EN_ON_SFT 3 +#define AUDIO_APLL2_EN_ON_MASK 0x1 +#define AUDIO_APLL2_EN_ON_MASK_SFT (0x1 << 3) +#define AUDIO_APLL1_EN_ON_SFT 2 +#define AUDIO_APLL1_EN_ON_MASK 0x1 +#define AUDIO_APLL1_EN_ON_MASK_SFT (0x1 << 2) +#define AUDIO_F3P25M_EN_ON_SFT 1 +#define AUDIO_F3P25M_EN_ON_MASK 0x1 +#define AUDIO_F3P25M_EN_ON_MASK_SFT (0x1 << 1) +#define AUDIO_26M_EN_ON_SFT 0 +#define AUDIO_26M_EN_ON_MASK 0x1 +#define AUDIO_26M_EN_ON_MASK_SFT (0x1 << 0) + +/* AFE_SINEGEN_CON0 */ +#define DAC_EN_SFT 26 +#define DAC_EN_MASK 0x1 +#define DAC_EN_MASK_SFT (0x1 << 26) +#define TIE_SW_CH2_SFT 25 +#define TIE_SW_CH2_MASK 0x1 +#define TIE_SW_CH2_MASK_SFT (0x1 << 25) +#define TIE_SW_CH1_SFT 24 +#define TIE_SW_CH1_MASK 0x1 +#define TIE_SW_CH1_MASK_SFT (0x1 << 24) +#define AMP_DIV_CH2_SFT 20 +#define AMP_DIV_CH2_MASK 0xf +#define AMP_DIV_CH2_MASK_SFT (0xf << 20) +#define FREQ_DIV_CH2_SFT 12 +#define FREQ_DIV_CH2_MASK 0x1f +#define FREQ_DIV_CH2_MASK_SFT (0x1f << 12) +#define AMP_DIV_CH1_SFT 8 +#define AMP_DIV_CH1_MASK 0xf +#define AMP_DIV_CH1_MASK_SFT (0xf << 8) +#define FREQ_DIV_CH1_SFT 0 +#define FREQ_DIV_CH1_MASK 0x1f +#define FREQ_DIV_CH1_MASK_SFT (0x1f << 0) + +/* AFE_SINEGEN_CON1 */ +#define SINE_DOMAIN_SFT 20 +#define SINE_DOMAIN_MASK 0x7 +#define SINE_DOMAIN_MASK_SFT (0x7 << 20) +#define SINE_MODE_SFT 12 +#define SINE_MODE_MASK 0x1f +#define SINE_MODE_MASK_SFT (0x1f << 12) +#define INNER_LOOP_BACKI_SEL_SFT 8 +#define INNER_LOOP_BACKI_SEL_MASK 0x1 +#define INNER_LOOP_BACKI_SEL_MASK_SFT (0x1 << 8) +#define INNER_LOOP_BACK_MODE_SFT 0 +#define INNER_LOOP_BACK_MODE_MASK 0xff +#define INNER_LOOP_BACK_MODE_MASK_SFT (0xff << 0) + +/* AFE_SINEGEN_CON2 */ +#define TIE_CH1_CONSTANT_SFT 0 +#define TIE_CH1_CONSTANT_MASK 0xffffffff +#define TIE_CH1_CONSTANT_MASK_SFT (0xffffffff << 0) + +/* AFE_SINEGEN_CON3 */ +#define TIE_CH2_CONSTANT_SFT 0 +#define TIE_CH2_CONSTANT_MASK 0xffffffff +#define TIE_CH2_CONSTANT_MASK_SFT (0xffffffff << 0) + +/* AFE_APLL1_TUNER_CFG */ +#define UPPER_BOUND_SFT 8 +#define UPPER_BOUND_MASK 0xff +#define UPPER_BOUND_MASK_SFT (0xff << 8) +#define APLL_DIV_SFT 4 +#define APLL_DIV_MASK 0xf +#define APLL_DIV_MASK_SFT (0xf << 4) +#define XTAL_EN_128FS_SEL_SFT 1 +#define XTAL_EN_128FS_SEL_MASK 0x3 +#define XTAL_EN_128FS_SEL_MASK_SFT (0x3 << 1) +#define FREQ_TUNER_EN_SFT 0 +#define FREQ_TUNER_EN_MASK 0x1 +#define FREQ_TUNER_EN_MASK_SFT (0x1 << 0) + +/* AFE_APLL1_TUNER_MON0 */ +#define TUNER_MON_SFT 0 +#define TUNER_MON_MASK 0xffffffff +#define TUNER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_APLL2_TUNER_CFG */ +#define UPPER_BOUND_SFT 8 +#define UPPER_BOUND_MASK 0xff +#define UPPER_BOUND_MASK_SFT (0xff << 8) +#define APLL_DIV_SFT 4 +#define APLL_DIV_MASK 0xf +#define APLL_DIV_MASK_SFT (0xf << 4) +#define XTAL_EN_128FS_SEL_SFT 1 +#define XTAL_EN_128FS_SEL_MASK 0x3 +#define XTAL_EN_128FS_SEL_MASK_SFT (0x3 << 1) +#define FREQ_TUNER_EN_SFT 0 +#define FREQ_TUNER_EN_MASK 0x1 +#define FREQ_TUNER_EN_MASK_SFT (0x1 << 0) + +/* AFE_APLL2_TUNER_MON0 */ +#define TUNER_MON_SFT 0 +#define TUNER_MON_MASK 0xffffffff +#define TUNER_MON_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG0 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG1 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG2 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG3 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG4 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AFE_SPM_CONTROL_REQ */ +#define AFE_DDREN_REQ_SFT 4 +#define AFE_DDREN_REQ_MASK 0x1 +#define AFE_DDREN_REQ_MASK_SFT (0x1 << 4) +#define AFE_INFRA_REQ_SFT 3 +#define AFE_INFRA_REQ_MASK 0x1 +#define AFE_INFRA_REQ_MASK_SFT (0x1 << 3) +#define AFE_VRF18_REQ_SFT 2 +#define AFE_VRF18_REQ_MASK 0x1 +#define AFE_VRF18_REQ_MASK_SFT (0x1 << 2) +#define AFE_APSRC_REQ_SFT 1 +#define AFE_APSRC_REQ_MASK 0x1 +#define AFE_APSRC_REQ_MASK_SFT (0x1 << 1) +#define AFE_SRCCLKENA_REQ_SFT 0 +#define AFE_SRCCLKENA_REQ_MASK 0x1 +#define AFE_SRCCLKENA_REQ_MASK_SFT (0x1 << 0) + +/* AFE_SPM_CONTROL_ACK */ +#define SPM_RESOURCE_CONTROL_ACK_SFT 0 +#define SPM_RESOURCE_CONTROL_ACK_MASK 0xffffffff +#define SPM_RESOURCE_CONTROL_ACK_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_CFG_VCORE_RG */ +#define AUD_TOP_CFG_SFT 0 +#define AUD_TOP_CFG_MASK 0xffffffff +#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_IP_VERSION */ +#define AUDIO_TOP_IP_VERSION_SFT 0 +#define AUDIO_TOP_IP_VERSION_MASK 0xffffffff +#define AUDIO_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AUDIO_ENGEN_CON0_MON */ +#define AUDIO_ENGEN_MON_SFT 0 +#define AUDIO_ENGEN_MON_MASK 0xffffffff +#define AUDIO_ENGEN_MON_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_CFG_VLP_RG */ +#define I2SIN1_DAT_SEL_SFT 31 +#define I2SIN1_DAT_SEL_MASK 0x1 +#define I2SIN1_DAT_SEL_MASK_SFT (0x1 << 31) +#define FMI2S_IN_SEL_SFT 30 +#define FMI2S_IN_SEL_MASK 0x1 +#define FMI2S_IN_SEL_MASK_SFT (0x1 << 30) +#define RG_I2S4_IN_BCK_NEG_EG_LATCH_SFT 21 +#define RG_I2S4_IN_BCK_NEG_EG_LATCH_MASK 0x1 +#define RG_I2S4_IN_BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 21) +#define RG_I2S4_OUT_BCK_NEG_EG_LATCH_SFT 20 +#define RG_I2S4_OUT_BCK_NEG_EG_LATCH_MASK 0x1 +#define RG_I2S4_OUT_BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 20) +#define RG_I2S4_IN_SLV_LRCK_LATCH_EDGE_SFT 19 +#define RG_I2S4_IN_SLV_LRCK_LATCH_EDGE_MASK 0x1 +#define RG_I2S4_IN_SLV_LRCK_LATCH_EDGE_MASK_SFT (0x1 << 19) +#define RG_I2S4_IN_SLV_BCK_INV_SEL_SFT 18 +#define RG_I2S4_IN_SLV_BCK_INV_SEL_MASK 0x1 +#define RG_I2S4_IN_SLV_BCK_INV_SEL_MASK_SFT (0x1 << 18) +#define RG_I2S4_OUT_SLV_LRCK_LATCH_EDGE_SFT 17 +#define RG_I2S4_OUT_SLV_LRCK_LATCH_EDGE_MASK 0x1 +#define RG_I2S4_OUT_SLV_LRCK_LATCH_EDGE_MASK_SFT (0x1 << 17) +#define RG_I2S4_OUT_SLV_BCK_INV_SEL_SFT 16 +#define RG_I2S4_OUT_SLV_BCK_INV_SEL_MASK 0x1 +#define RG_I2S4_OUT_SLV_BCK_INV_SEL_MASK_SFT (0x1 << 16) +#define RG_I2S5_IN_BCK_NEG_EG_LATCH_SFT 13 +#define RG_I2S5_IN_BCK_NEG_EG_LATCH_MASK 0x1 +#define RG_I2S5_IN_BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 13) +#define RG_I2S5_OUT_BCK_NEG_EG_LATCH_SFT 12 +#define RG_I2S5_OUT_BCK_NEG_EG_LATCH_MASK 0x1 +#define RG_I2S5_OUT_BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 12) +#define RG_I2S5_IN_SLV_LRCK_LATCH_EDGE_SFT 11 +#define RG_I2S5_IN_SLV_LRCK_LATCH_EDGE_MASK 0x1 +#define RG_I2S5_IN_SLV_LRCK_LATCH_EDGE_MASK_SFT (0x1 << 11) +#define RG_I2S5_IN_SLV_BCK_INV_SEL_SFT 10 +#define RG_I2S5_IN_SLV_BCK_INV_SEL_MASK 0x1 +#define RG_I2S5_IN_SLV_BCK_INV_SEL_MASK_SFT (0x1 << 10) +#define RG_I2S5_OUT_SLV_LRCK_LATCH_EDGE_SFT 9 +#define RG_I2S5_OUT_SLV_LRCK_LATCH_EDGE_MASK 0x1 +#define RG_I2S5_OUT_SLV_LRCK_LATCH_EDGE_MASK_SFT (0x1 << 9) +#define RG_I2S5_OUT_SLV_BCK_INV_SEL_SFT 8 +#define RG_I2S5_OUT_SLV_BCK_INV_SEL_MASK 0x1 +#define RG_I2S5_OUT_SLV_BCK_INV_SEL_MASK_SFT (0x1 << 8) +#define RG_I2S4_PAD_TOP_CK_EN_SFT 5 +#define RG_I2S4_PAD_TOP_CK_EN_MASK 0x1 +#define RG_I2S4_PAD_TOP_CK_EN_MASK_SFT (0x1 << 5) +#define RG_I2S5_PAD_TOP_CK_EN_SFT 4 +#define RG_I2S5_PAD_TOP_CK_EN_MASK 0x1 +#define RG_I2S5_PAD_TOP_CK_EN_MASK_SFT (0x1 << 4) +#define RG_TEST_TYPE_SFT 2 +#define RG_TEST_TYPE_MASK 0x1 +#define RG_TEST_TYPE_MASK_SFT (0x1 << 2) +#define RG_SW_RESET_SFT 1 +#define RG_SW_RESET_MASK 0x1 +#define RG_SW_RESET_MASK_SFT (0x1 << 1) +#define RG_TEST_ON_SFT 0 +#define RG_TEST_ON_MASK 0x1 +#define RG_TEST_ON_MASK_SFT (0x1 << 0) + +/* AUD_TOP_MON_RG */ +#define AUD_TOP_MON_SFT 0 +#define AUD_TOP_MON_MASK 0xffffffff +#define AUD_TOP_MON_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL0 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL1 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL2 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_IPM_VER_MON */ +#define RG_CONNSYS_I2S_IPM_VER_MON_SFT 0 +#define RG_CONNSYS_I2S_IPM_VER_MON_MASK 0xffffffff +#define RG_CONNSYS_I2S_IPM_VER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_MON_SEL */ +#define RG_CONNSYS_I2S_MON_SEL_SFT 0 +#define RG_CONNSYS_I2S_MON_SEL_MASK 0xff +#define RG_CONNSYS_I2S_MON_SEL_MASK_SFT (0xff << 0) + +/* AFE_CONNSYS_I2S_MON */ +#define RG_CONNSYS_I2S_MON_SFT 0 +#define RG_CONNSYS_I2S_MON_MASK 0xffffffff +#define RG_CONNSYS_I2S_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_CON */ +#define I2S_SOFT_RST_SFT 31 +#define I2S_SOFT_RST_MASK 0x1 +#define I2S_SOFT_RST_MASK_SFT (0x1 << 31) +#define BCK_NEG_EG_LATCH_SFT 30 +#define BCK_NEG_EG_LATCH_MASK 0x1 +#define BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 30) +#define BCK_INV_SFT 29 +#define BCK_INV_MASK 0x1 +#define BCK_INV_MASK_SFT (0x1 << 29) +#define I2SIN_PAD_SEL_SFT 28 +#define I2SIN_PAD_SEL_MASK 0x1 +#define I2SIN_PAD_SEL_MASK_SFT (0x1 << 28) +#define I2S_LOOPBACK_SFT 20 +#define I2S_LOOPBACK_MASK 0x1 +#define I2S_LOOPBACK_MASK_SFT (0x1 << 20) +#define I2S_HDEN_SFT 12 +#define I2S_HDEN_MASK 0x1 +#define I2S_HDEN_MASK_SFT (0x1 << 12) +#define I2S_MODE_SFT 8 +#define I2S_MODE_MASK 0xf +#define I2S_MODE_MASK_SFT (0xf << 8) +#define I2S_BYPSRC_SFT 6 +#define I2S_BYPSRC_MASK 0x1 +#define I2S_BYPSRC_MASK_SFT (0x1 << 6) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK 0x1 +#define INV_LRCK_MASK_SFT (0x1 << 5) +#define I2S_FMT_SFT 3 +#define I2S_FMT_MASK 0x1 +#define I2S_FMT_MASK_SFT (0x1 << 3) +#define I2S_SRC_SFT 2 +#define I2S_SRC_MASK 0x1 +#define I2S_SRC_MASK_SFT (0x1 << 2) +#define I2S_WLEN_SFT 1 +#define I2S_WLEN_MASK 0x1 +#define I2S_WLEN_MASK_SFT (0x1 << 1) +#define I2S_EN_SFT 0 +#define I2S_EN_MASK 0x1 +#define I2S_EN_MASK_SFT (0x1 << 0) + +/* AFE_PCM0_INTF_CON0 */ +#define PCM0_HDEN_SFT 26 +#define PCM0_HDEN_MASK 0x1 +#define PCM0_HDEN_MASK_SFT (0x1 << 26) +#define PCM0_SYNC_DELSEL_SFT 25 +#define PCM0_SYNC_DELSEL_MASK 0x1 +#define PCM0_SYNC_DELSEL_MASK_SFT (0x1 << 25) +#define PCM0_TX_LR_SWAP_SFT 24 +#define PCM0_TX_LR_SWAP_MASK 0x1 +#define PCM0_TX_LR_SWAP_MASK_SFT (0x1 << 24) +#define PCM0_SYNC_OUT_INV_SFT 23 +#define PCM0_SYNC_OUT_INV_MASK 0x1 +#define PCM0_SYNC_OUT_INV_MASK_SFT (0x1 << 23) +#define PCM0_BCLK_OUT_INV_SFT 22 +#define PCM0_BCLK_OUT_INV_MASK 0x1 +#define PCM0_BCLK_OUT_INV_MASK_SFT (0x1 << 22) +#define PCM0_SYNC_IN_INV_SFT 21 +#define PCM0_SYNC_IN_INV_MASK 0x1 +#define PCM0_SYNC_IN_INV_MASK_SFT (0x1 << 21) +#define PCM0_BCLK_IN_INV_SFT 20 +#define PCM0_BCLK_IN_INV_MASK 0x1 +#define PCM0_BCLK_IN_INV_MASK_SFT (0x1 << 20) +#define PCM0_TX_LCH_RPT_SFT 19 +#define PCM0_TX_LCH_RPT_MASK 0x1 +#define PCM0_TX_LCH_RPT_MASK_SFT (0x1 << 19) +#define PCM0_VBT_16K_MODE_SFT 18 +#define PCM0_VBT_16K_MODE_MASK 0x1 +#define PCM0_VBT_16K_MODE_MASK_SFT (0x1 << 18) +#define PCM0_BIT_LENGTH_SFT 16 +#define PCM0_BIT_LENGTH_MASK 0x3 +#define PCM0_BIT_LENGTH_MASK_SFT (0x3 << 16) +#define PCM0_WLEN_SFT 14 +#define PCM0_WLEN_MASK 0x3 +#define PCM0_WLEN_MASK_SFT (0x3 << 14) +#define PCM0_SYNC_LENGTH_SFT 9 +#define PCM0_SYNC_LENGTH_MASK 0x1f +#define PCM0_SYNC_LENGTH_MASK_SFT (0x1f << 9) +#define PCM0_SYNC_TYPE_SFT 8 +#define PCM0_SYNC_TYPE_MASK 0x1 +#define PCM0_SYNC_TYPE_MASK_SFT (0x1 << 8) +#define PCM0_BYP_ASRC_SFT 7 +#define PCM0_BYP_ASRC_MASK 0x1 +#define PCM0_BYP_ASRC_MASK_SFT (0x1 << 7) +#define PCM0_SLAVE_SFT 6 +#define PCM0_SLAVE_MASK 0x1 +#define PCM0_SLAVE_MASK_SFT (0x1 << 6) +#define PCM0_MODE_SFT 3 +#define PCM0_MODE_MASK 0x7 +#define PCM0_MODE_MASK_SFT (0x7 << 3) +#define PCM0_FMT_SFT 1 +#define PCM0_FMT_MASK 0x3 +#define PCM0_FMT_MASK_SFT (0x3 << 1) +#define PCM0_EN_SFT 0 +#define PCM0_EN_MASK 0x1 +#define PCM0_EN_MASK_SFT (0x1 << 0) + +/* AFE_PCM0_INTF_CON1 */ +#define PCM0_TX_RX_LOOPBACK_SFT 31 +#define PCM0_TX_RX_LOOPBACK_MASK 0x1 +#define PCM0_TX_RX_LOOPBACK_MASK_SFT (0x1 << 31) +#define PCM0_BUFFER_LOOPBACK_SFT 30 +#define PCM0_BUFFER_LOOPBACK_MASK 0x1 +#define PCM0_BUFFER_LOOPBACK_MASK_SFT (0x1 << 30) +#define PCM0_PARALLEL_LOOPBACK_SFT 29 +#define PCM0_PARALLEL_LOOPBACK_MASK 0x1 +#define PCM0_PARALLEL_LOOPBACK_MASK_SFT (0x1 << 29) +#define PCM0_SERIAL_LOOPBACK_SFT 28 +#define PCM0_SERIAL_LOOPBACK_MASK 0x1 +#define PCM0_SERIAL_LOOPBACK_MASK_SFT (0x1 << 28) +#define PCM0_DAI_LOOPBACK_SFT 27 +#define PCM0_DAI_LOOPBACK_MASK 0x1 +#define PCM0_DAI_LOOPBACK_MASK_SFT (0x1 << 27) +#define PCM0_I2S_LOOPBACK_SFT 26 +#define PCM0_I2S_LOOPBACK_MASK 0x1 +#define PCM0_I2S_LOOPBACK_MASK_SFT (0x1 << 26) +#define PCM0_1X_EN_DOMAIN_SFT 23 +#define PCM0_1X_EN_DOMAIN_MASK 0x7 +#define PCM0_1X_EN_DOMAIN_MASK_SFT (0x7 << 23) +#define PCM0_1X_EN_MODE_SFT 18 +#define PCM0_1X_EN_MODE_MASK 0x1f +#define PCM0_1X_EN_MODE_MASK_SFT (0x1f << 18) +#define PCM0_TX3_RCH_DBG_MODE_SFT 17 +#define PCM0_TX3_RCH_DBG_MODE_MASK 0x1 +#define PCM0_TX3_RCH_DBG_MODE_MASK_SFT (0x1 << 17) +#define PCM0_PCM1_LOOPBACK_SFT 16 +#define PCM0_PCM1_LOOPBACK_MASK 0x1 +#define PCM0_PCM1_LOOPBACK_MASK_SFT (0x1 << 16) +#define PCM0_LOOPBACK_CH_SEL_SFT 12 +#define PCM0_LOOPBACK_CH_SEL_MASK 0x3 +#define PCM0_LOOPBACK_CH_SEL_MASK_SFT (0x3 << 12) +#define PCM0_BT_MODE_SFT 11 +#define PCM0_BT_MODE_MASK 0x1 +#define PCM0_BT_MODE_MASK_SFT (0x1 << 11) +#define PCM0_EXT_MODEM_SFT 10 +#define PCM0_EXT_MODEM_MASK 0x1 +#define PCM0_EXT_MODEM_MASK_SFT (0x1 << 10) +#define PCM0_USE_MD3_SFT 9 +#define PCM0_USE_MD3_MASK 0x1 +#define PCM0_USE_MD3_MASK_SFT (0x1 << 9) +#define PCM0_FIX_VALUE_SEL_SFT 8 +#define PCM0_FIX_VALUE_SEL_MASK 0x1 +#define PCM0_FIX_VALUE_SEL_MASK_SFT (0x1 << 8) +#define PCM0_TX_FIX_VALUE_SFT 0 +#define PCM0_TX_FIX_VALUE_MASK 0xff +#define PCM0_TX_FIX_VALUE_MASK_SFT (0xff << 0) + +/* AFE_PCM_INTF_MON */ +#define PCM0_TX_FIFO_OV_SFT 5 +#define PCM0_TX_FIFO_OV_MASK 0x1 +#define PCM0_TX_FIFO_OV_MASK_SFT (0x1 << 5) +#define PCM0_RX_FIFO_OV_SFT 4 +#define PCM0_RX_FIFO_OV_MASK 0x1 +#define PCM0_RX_FIFO_OV_MASK_SFT (0x1 << 4) +#define PCM1_TX_FIFO_OV_SFT 3 +#define PCM1_TX_FIFO_OV_MASK 0x1 +#define PCM1_TX_FIFO_OV_MASK_SFT (0x1 << 3) +#define PCM1_RX_FIFO_OV_SFT 2 +#define PCM1_RX_FIFO_OV_MASK 0x1 +#define PCM1_RX_FIFO_OV_MASK_SFT (0x1 << 2) +#define PCM0_SYNC_GLITCH_SFT 1 +#define PCM0_SYNC_GLITCH_MASK 0x1 +#define PCM0_SYNC_GLITCH_MASK_SFT (0x1 << 1) +#define PCM1_SYNC_GLITCH_SFT 0 +#define PCM1_SYNC_GLITCH_MASK 0x1 +#define PCM1_SYNC_GLITCH_MASK_SFT (0x1 << 0) + +/* AFE_PCM1_INTF_CON0 */ +#define PCM1_TX_FIX_VALUE_SFT 24 +#define PCM1_TX_FIX_VALUE_MASK 0xff +#define PCM1_TX_FIX_VALUE_MASK_SFT (0xff << 24) +#define PCM1_FIX_VALUE_SEL_SFT 23 +#define PCM1_FIX_VALUE_SEL_MASK 0x1 +#define PCM1_FIX_VALUE_SEL_MASK_SFT (0x1 << 23) +#define PCM1_BUFFER_LOOPBACK_SFT 22 +#define PCM1_BUFFER_LOOPBACK_MASK 0x1 +#define PCM1_BUFFER_LOOPBACK_MASK_SFT (0x1 << 22) +#define PCM1_PARALLEL_LOOPBACK_SFT 21 +#define PCM1_PARALLEL_LOOPBACK_MASK 0x1 +#define PCM1_PARALLEL_LOOPBACK_MASK_SFT (0x1 << 21) +#define PCM1_SERIAL_LOOPBACK_SFT 20 +#define PCM1_SERIAL_LOOPBACK_MASK 0x1 +#define PCM1_SERIAL_LOOPBACK_MASK_SFT (0x1 << 20) +#define PCM1_DAI_PCM1_LOOPBACK_SFT 19 +#define PCM1_DAI_PCM1_LOOPBACK_MASK 0x1 +#define PCM1_DAI_PCM1_LOOPBACK_MASK_SFT (0x1 << 19) +#define PCM1_I2S_PCM1_LOOPBACK_SFT 18 +#define PCM1_I2S_PCM1_LOOPBACK_MASK 0x1 +#define PCM1_I2S_PCM1_LOOPBACK_MASK_SFT (0x1 << 18) +#define PCM1_SYNC_DELSEL_SFT 17 +#define PCM1_SYNC_DELSEL_MASK 0x1 +#define PCM1_SYNC_DELSEL_MASK_SFT (0x1 << 17) +#define PCM1_TX_LR_SWAP_SFT 16 +#define PCM1_TX_LR_SWAP_MASK 0x1 +#define PCM1_TX_LR_SWAP_MASK_SFT (0x1 << 16) +#define PCM1_SYNC_IN_INV_SFT 15 +#define PCM1_SYNC_IN_INV_MASK 0x1 +#define PCM1_SYNC_IN_INV_MASK_SFT (0x1 << 15) +#define PCM1_BCLK_IN_INV_SFT 14 +#define PCM1_BCLK_IN_INV_MASK 0x1 +#define PCM1_BCLK_IN_INV_MASK_SFT (0x1 << 14) +#define PCM1_TX_LCH_RPT_SFT 13 +#define PCM1_TX_LCH_RPT_MASK 0x1 +#define PCM1_TX_LCH_RPT_MASK_SFT (0x1 << 13) +#define PCM1_VBT_16K_MODE_SFT 12 +#define PCM1_VBT_16K_MODE_MASK 0x1 +#define PCM1_VBT_16K_MODE_MASK_SFT (0x1 << 12) +#define PCM1_LOOPBACK_CH_SEL_SFT 10 +#define PCM1_LOOPBACK_CH_SEL_MASK 0x3 +#define PCM1_LOOPBACK_CH_SEL_MASK_SFT (0x3 << 10) +#define PCM1_TX2_BT_MODE_SFT 8 +#define PCM1_TX2_BT_MODE_MASK 0x1 +#define PCM1_TX2_BT_MODE_MASK_SFT (0x1 << 8) +#define PCM1_BT_MODE_SFT 7 +#define PCM1_BT_MODE_MASK 0x1 +#define PCM1_BT_MODE_MASK_SFT (0x1 << 7) +#define PCM1_AFIFO_SFT 6 +#define PCM1_AFIFO_MASK 0x1 +#define PCM1_AFIFO_MASK_SFT (0x1 << 6) +#define PCM1_WLEN_SFT 5 +#define PCM1_WLEN_MASK 0x1 +#define PCM1_WLEN_MASK_SFT (0x1 << 5) +#define PCM1_MODE_SFT 3 +#define PCM1_MODE_MASK 0x3 +#define PCM1_MODE_MASK_SFT (0x3 << 3) +#define PCM1_FMT_SFT 1 +#define PCM1_FMT_MASK 0x3 +#define PCM1_FMT_MASK_SFT (0x3 << 1) +#define PCM1_EN_SFT 0 +#define PCM1_EN_MASK 0x1 +#define PCM1_EN_MASK_SFT (0x1 << 0) + +/* AFE_PCM1_INTF_CON1 */ +#define PCM1_1X_EN_DOMAIN_SFT 23 +#define PCM1_1X_EN_DOMAIN_MASK 0x7 +#define PCM1_1X_EN_DOMAIN_MASK_SFT (0x7 << 23) +#define PCM1_1X_EN_MODE_SFT 18 +#define PCM1_1X_EN_MODE_MASK 0x1f +#define PCM1_1X_EN_MODE_MASK_SFT (0x1f << 18) + +/* AFE_PCM_TOP_IP_VERSION */ +#define AFE_PCM_TOP_IP_VERSION_SFT 0 +#define AFE_PCM_TOP_IP_VERSION_MASK 0xffffffff +#define AFE_PCM_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_EN */ +#define AFE_IRQ_MCU_EN_SFT 0 +#define AFE_IRQ_MCU_EN_MASK 0xffffffff +#define AFE_IRQ_MCU_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_DSP_EN */ +#define AFE_IRQ_DSP_EN_SFT 0 +#define AFE_IRQ_DSP_EN_MASK 0xffffffff +#define AFE_IRQ_DSP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_DSP2_EN */ +#define AFE_IRQ_DSP2_EN_SFT 0 +#define AFE_IRQ_DSP2_EN_MASK 0xffffffff +#define AFE_IRQ_DSP2_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_SCP_EN */ +#define IRQ31_MCU_SCP_EN_SFT 31 +#define IRQ30_MCU_SCP_EN_SFT 30 +#define IRQ29_MCU_SCP_EN_SFT 29 +#define IRQ28_MCU_SCP_EN_SFT 28 +#define IRQ27_MCU_SCP_EN_SFT 27 +#define IRQ26_MCU_SCP_EN_SFT 26 +#define IRQ25_MCU_SCP_EN_SFT 25 +#define IRQ24_MCU_SCP_EN_SFT 24 +#define IRQ23_MCU_SCP_EN_SFT 23 +#define IRQ22_MCU_SCP_EN_SFT 22 +#define IRQ21_MCU_SCP_EN_SFT 21 +#define IRQ20_MCU_SCP_EN_SFT 20 +#define IRQ19_MCU_SCP_EN_SFT 19 +#define IRQ18_MCU_SCP_EN_SFT 18 +#define IRQ17_MCU_SCP_EN_SFT 17 +#define IRQ16_MCU_SCP_EN_SFT 16 +#define IRQ15_MCU_SCP_EN_SFT 15 +#define IRQ14_MCU_SCP_EN_SFT 14 +#define IRQ13_MCU_SCP_EN_SFT 13 +#define IRQ12_MCU_SCP_EN_SFT 12 +#define IRQ11_MCU_SCP_EN_SFT 11 +#define IRQ10_MCU_SCP_EN_SFT 10 +#define IRQ9_MCU_SCP_EN_SFT 9 +#define IRQ8_MCU_SCP_EN_SFT 8 +#define IRQ7_MCU_SCP_EN_SFT 7 +#define IRQ6_MCU_SCP_EN_SFT 6 +#define IRQ5_MCU_SCP_EN_SFT 5 +#define IRQ4_MCU_SCP_EN_SFT 4 +#define IRQ3_MCU_SCP_EN_SFT 3 +#define IRQ2_MCU_SCP_EN_SFT 2 +#define IRQ1_MCU_SCP_EN_SFT 1 +#define IRQ0_MCU_SCP_EN_SFT 0 + +/* AFE_CUSTOM_IRQ_MCU_EN */ +#define AFE_CUSTOM_IRQ_MCU_EN_SFT 0 +#define AFE_CUSTOM_IRQ_MCU_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_MCU_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_DSP_EN */ +#define AFE_CUSTOM_IRQ_DSP_EN_SFT 0 +#define AFE_CUSTOM_IRQ_DSP_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_DSP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_DSP2_EN */ +#define AFE_CUSTOM_IRQ_DSP2_EN_SFT 0 +#define AFE_CUSTOM_IRQ_DSP2_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_DSP2_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_SCP_EN */ +#define AFE_CUSTOM_IRQ_SCP_EN_SFT 0 +#define AFE_CUSTOM_IRQ_SCP_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_SCP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_STATUS */ +#define IRQ26_MCU_SFT 26 +#define IRQ26_MCU_MASK 0x1 +#define IRQ26_MCU_MASK_SFT (0x1 << 26) +#define IRQ25_MCU_SFT 25 +#define IRQ25_MCU_MASK 0x1 +#define IRQ25_MCU_MASK_SFT (0x1 << 25) +#define IRQ24_MCU_SFT 24 +#define IRQ24_MCU_MASK 0x1 +#define IRQ24_MCU_MASK_SFT (0x1 << 24) +#define IRQ23_MCU_SFT 23 +#define IRQ23_MCU_MASK 0x1 +#define IRQ23_MCU_MASK_SFT (0x1 << 23) +#define IRQ22_MCU_SFT 22 +#define IRQ22_MCU_MASK 0x1 +#define IRQ22_MCU_MASK_SFT (0x1 << 22) +#define IRQ21_MCU_SFT 21 +#define IRQ21_MCU_MASK 0x1 +#define IRQ21_MCU_MASK_SFT (0x1 << 21) +#define IRQ20_MCU_SFT 20 +#define IRQ20_MCU_MASK 0x1 +#define IRQ20_MCU_MASK_SFT (0x1 << 20) +#define IRQ19_MCU_SFT 19 +#define IRQ19_MCU_MASK 0x1 +#define IRQ19_MCU_MASK_SFT (0x1 << 19) +#define IRQ18_MCU_SFT 18 +#define IRQ18_MCU_MASK 0x1 +#define IRQ18_MCU_MASK_SFT (0x1 << 18) +#define IRQ17_MCU_SFT 17 +#define IRQ17_MCU_MASK 0x1 +#define IRQ17_MCU_MASK_SFT (0x1 << 17) +#define IRQ16_MCU_SFT 16 +#define IRQ16_MCU_MASK 0x1 +#define IRQ16_MCU_MASK_SFT (0x1 << 16) +#define IRQ15_MCU_SFT 15 +#define IRQ15_MCU_MASK 0x1 +#define IRQ15_MCU_MASK_SFT (0x1 << 15) +#define IRQ14_MCU_SFT 14 +#define IRQ14_MCU_MASK 0x1 +#define IRQ14_MCU_MASK_SFT (0x1 << 14) +#define IRQ13_MCU_SFT 13 +#define IRQ13_MCU_MASK 0x1 +#define IRQ13_MCU_MASK_SFT (0x1 << 13) +#define IRQ12_MCU_SFT 12 +#define IRQ12_MCU_MASK 0x1 +#define IRQ12_MCU_MASK_SFT (0x1 << 12) +#define IRQ11_MCU_SFT 11 +#define IRQ11_MCU_MASK 0x1 +#define IRQ11_MCU_MASK_SFT (0x1 << 11) +#define IRQ10_MCU_SFT 10 +#define IRQ10_MCU_MASK 0x1 +#define IRQ10_MCU_MASK_SFT (0x1 << 10) +#define IRQ9_MCU_SFT 9 +#define IRQ9_MCU_MASK 0x1 +#define IRQ9_MCU_MASK_SFT (0x1 << 9) +#define IRQ8_MCU_SFT 8 +#define IRQ8_MCU_MASK 0x1 +#define IRQ8_MCU_MASK_SFT (0x1 << 8) +#define IRQ7_MCU_SFT 7 +#define IRQ7_MCU_MASK 0x1 +#define IRQ7_MCU_MASK_SFT (0x1 << 7) +#define IRQ6_MCU_SFT 6 +#define IRQ6_MCU_MASK 0x1 +#define IRQ6_MCU_MASK_SFT (0x1 << 6) +#define IRQ5_MCU_SFT 5 +#define IRQ5_MCU_MASK 0x1 +#define IRQ5_MCU_MASK_SFT (0x1 << 5) +#define IRQ4_MCU_SFT 4 +#define IRQ4_MCU_MASK 0x1 +#define IRQ4_MCU_MASK_SFT (0x1 << 4) +#define IRQ3_MCU_SFT 3 +#define IRQ3_MCU_MASK 0x1 +#define IRQ3_MCU_MASK_SFT (0x1 << 3) +#define IRQ2_MCU_SFT 2 +#define IRQ2_MCU_MASK 0x1 +#define IRQ2_MCU_MASK_SFT (0x1 << 2) +#define IRQ1_MCU_SFT 1 +#define IRQ1_MCU_MASK 0x1 +#define IRQ1_MCU_MASK_SFT (0x1 << 1) +#define IRQ0_MCU_SFT 0 +#define IRQ0_MCU_MASK 0x1 +#define IRQ0_MCU_MASK_SFT (0x1 << 0) + +/* AFE_CUSTOM_IRQ_MCU_STATUS */ +#define CUSTOM_IRQ21_MCU_SFT 21 +#define CUSTOM_IRQ21_MCU_MASK 0x1 +#define CUSTOM_IRQ21_MCU_MASK_SFT (0x1 << 21) +#define CUSTOM_IRQ20_MCU_SFT 20 +#define CUSTOM_IRQ20_MCU_MASK 0x1 +#define CUSTOM_IRQ20_MCU_MASK_SFT (0x1 << 20) +#define CUSTOM_IRQ19_MCU_SFT 19 +#define CUSTOM_IRQ19_MCU_MASK 0x1 +#define CUSTOM_IRQ19_MCU_MASK_SFT (0x1 << 19) +#define CUSTOM_IRQ18_MCU_SFT 18 +#define CUSTOM_IRQ18_MCU_MASK 0x1 +#define CUSTOM_IRQ18_MCU_MASK_SFT (0x1 << 18) +#define CUSTOM_IRQ17_MCU_SFT 17 +#define CUSTOM_IRQ17_MCU_MASK 0x1 +#define CUSTOM_IRQ17_MCU_MASK_SFT (0x1 << 17) +#define CUSTOM_IRQ16_MCU_SFT 16 +#define CUSTOM_IRQ16_MCU_MASK 0x1 +#define CUSTOM_IRQ16_MCU_MASK_SFT (0x1 << 16) +#define CUSTOM_IRQ9_MCU_SFT 9 +#define CUSTOM_IRQ9_MCU_MASK 0x1 +#define CUSTOM_IRQ9_MCU_MASK_SFT (0x1 << 9) +#define CUSTOM_IRQ8_MCU_SFT 8 +#define CUSTOM_IRQ8_MCU_MASK 0x1 +#define CUSTOM_IRQ8_MCU_MASK_SFT (0x1 << 8) +#define CUSTOM_IRQ7_MCU_SFT 7 +#define CUSTOM_IRQ7_MCU_MASK 0x1 +#define CUSTOM_IRQ7_MCU_MASK_SFT (0x1 << 7) +#define CUSTOM_IRQ6_MCU_SFT 6 +#define CUSTOM_IRQ6_MCU_MASK 0x1 +#define CUSTOM_IRQ6_MCU_MASK_SFT (0x1 << 6) +#define CUSTOM_IRQ5_MCU_SFT 5 +#define CUSTOM_IRQ5_MCU_MASK 0x1 +#define CUSTOM_IRQ5_MCU_MASK_SFT (0x1 << 5) +#define CUSTOM_IRQ4_MCU_SFT 4 +#define CUSTOM_IRQ4_MCU_MASK 0x1 +#define CUSTOM_IRQ4_MCU_MASK_SFT (0x1 << 4) +#define CUSTOM_IRQ3_MCU_SFT 3 +#define CUSTOM_IRQ3_MCU_MASK 0x1 +#define CUSTOM_IRQ3_MCU_MASK_SFT (0x1 << 3) +#define CUSTOM_IRQ2_MCU_SFT 2 +#define CUSTOM_IRQ2_MCU_MASK 0x1 +#define CUSTOM_IRQ2_MCU_MASK_SFT (0x1 << 2) +#define CUSTOM_IRQ1_MCU_SFT 1 +#define CUSTOM_IRQ1_MCU_MASK 0x1 +#define CUSTOM_IRQ1_MCU_MASK_SFT (0x1 << 1) +#define CUSTOM_IRQ0_MCU_SFT 0 +#define CUSTOM_IRQ0_MCU_MASK 0x1 +#define CUSTOM_IRQ0_MCU_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_CFG */ +#define AFE_IRQ_CLR_CFG_SFT 31 +#define AFE_IRQ_CLR_CFG_MASK 0x1 +#define AFE_IRQ_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ_MCU_CNT_SFT 0 +#define AFE_IRQ_MCU_CNT_MASK 0xffffff +#define AFE_IRQ_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ0_MCU_CFG0 */ +#define AFE_IRQ0_MCU_DOMAIN_SFT 9 +#define AFE_IRQ0_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ0_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ0_MCU_FS_SFT 4 +#define AFE_IRQ0_MCU_FS_MASK 0x1f +#define AFE_IRQ0_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ0_MCU_ON_SFT 0 +#define AFE_IRQ0_MCU_ON_MASK 0x1 +#define AFE_IRQ0_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ0_MCU_CFG1 */ +#define AFE_IRQ0_CLR_CFG_SFT 31 +#define AFE_IRQ0_CLR_CFG_MASK 0x1 +#define AFE_IRQ0_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ0_MCU_CNT_SFT 0 +#define AFE_IRQ0_MCU_CNT_MASK 0xffffff +#define AFE_IRQ0_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ1_MCU_CFG0 */ +#define AFE_IRQ1_MCU_DOMAIN_SFT 9 +#define AFE_IRQ1_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ1_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ1_MCU_FS_SFT 4 +#define AFE_IRQ1_MCU_FS_MASK 0x1f +#define AFE_IRQ1_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ1_MCU_ON_SFT 0 +#define AFE_IRQ1_MCU_ON_MASK 0x1 +#define AFE_IRQ1_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ1_MCU_CFG1 */ +#define AFE_IRQ1_CLR_CFG_SFT 31 +#define AFE_IRQ1_CLR_CFG_MASK 0x1 +#define AFE_IRQ1_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ1_MCU_CNT_SFT 0 +#define AFE_IRQ1_MCU_CNT_MASK 0xffffff +#define AFE_IRQ1_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ2_MCU_CFG0 */ +#define AFE_IRQ2_MCU_DOMAIN_SFT 9 +#define AFE_IRQ2_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ2_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ2_MCU_FS_SFT 4 +#define AFE_IRQ2_MCU_FS_MASK 0x1f +#define AFE_IRQ2_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ2_MCU_ON_SFT 0 +#define AFE_IRQ2_MCU_ON_MASK 0x1 +#define AFE_IRQ2_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ2_MCU_CFG1 */ +#define AFE_IRQ2_CLR_CFG_SFT 31 +#define AFE_IRQ2_CLR_CFG_MASK 0x1 +#define AFE_IRQ2_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ2_MCU_CNT_SFT 0 +#define AFE_IRQ2_MCU_CNT_MASK 0xffffff +#define AFE_IRQ2_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ3_MCU_CFG0 */ +#define AFE_IRQ3_MCU_DOMAIN_SFT 9 +#define AFE_IRQ3_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ3_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ3_MCU_FS_SFT 4 +#define AFE_IRQ3_MCU_FS_MASK 0x1f +#define AFE_IRQ3_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ3_MCU_ON_SFT 0 +#define AFE_IRQ3_MCU_ON_MASK 0x1 +#define AFE_IRQ3_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ3_MCU_CFG1 */ +#define AFE_IRQ3_CLR_CFG_SFT 31 +#define AFE_IRQ3_CLR_CFG_MASK 0x1 +#define AFE_IRQ3_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ3_MCU_CNT_SFT 0 +#define AFE_IRQ3_MCU_CNT_MASK 0xffffff +#define AFE_IRQ3_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ4_MCU_CFG0 */ +#define AFE_IRQ4_MCU_DOMAIN_SFT 9 +#define AFE_IRQ4_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ4_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ4_MCU_FS_SFT 4 +#define AFE_IRQ4_MCU_FS_MASK 0x1f +#define AFE_IRQ4_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ4_MCU_ON_SFT 0 +#define AFE_IRQ4_MCU_ON_MASK 0x1 +#define AFE_IRQ4_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ4_MCU_CFG1 */ +#define AFE_IRQ4_CLR_CFG_SFT 31 +#define AFE_IRQ4_CLR_CFG_MASK 0x1 +#define AFE_IRQ4_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ4_MCU_CNT_SFT 0 +#define AFE_IRQ4_MCU_CNT_MASK 0xffffff +#define AFE_IRQ4_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ5_MCU_CFG0 */ +#define AFE_IRQ5_MCU_DOMAIN_SFT 9 +#define AFE_IRQ5_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ5_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ5_MCU_FS_SFT 4 +#define AFE_IRQ5_MCU_FS_MASK 0x1f +#define AFE_IRQ5_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ5_MCU_ON_SFT 0 +#define AFE_IRQ5_MCU_ON_MASK 0x1 +#define AFE_IRQ5_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ5_MCU_CFG1 */ +#define AFE_IRQ5_CLR_CFG_SFT 31 +#define AFE_IRQ5_CLR_CFG_MASK 0x1 +#define AFE_IRQ5_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ5_MCU_CNT_SFT 0 +#define AFE_IRQ5_MCU_CNT_MASK 0xffffff +#define AFE_IRQ5_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ6_MCU_CFG0 */ +#define AFE_IRQ6_MCU_DOMAIN_SFT 9 +#define AFE_IRQ6_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ6_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ6_MCU_FS_SFT 4 +#define AFE_IRQ6_MCU_FS_MASK 0x1f +#define AFE_IRQ6_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ6_MCU_ON_SFT 0 +#define AFE_IRQ6_MCU_ON_MASK 0x1 +#define AFE_IRQ6_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ6_MCU_CFG1 */ +#define AFE_IRQ6_CLR_CFG_SFT 31 +#define AFE_IRQ6_CLR_CFG_MASK 0x1 +#define AFE_IRQ6_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ6_MCU_CNT_SFT 0 +#define AFE_IRQ6_MCU_CNT_MASK 0xffffff +#define AFE_IRQ6_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ7_MCU_CFG0 */ +#define AFE_IRQ7_MCU_DOMAIN_SFT 9 +#define AFE_IRQ7_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ7_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ7_MCU_FS_SFT 4 +#define AFE_IRQ7_MCU_FS_MASK 0x1f +#define AFE_IRQ7_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ7_MCU_ON_SFT 0 +#define AFE_IRQ7_MCU_ON_MASK 0x1 +#define AFE_IRQ7_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ7_MCU_CFG1 */ +#define AFE_IRQ7_CLR_CFG_SFT 31 +#define AFE_IRQ7_CLR_CFG_MASK 0x1 +#define AFE_IRQ7_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ7_MCU_CNT_SFT 0 +#define AFE_IRQ7_MCU_CNT_MASK 0xffffff +#define AFE_IRQ7_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ8_MCU_CFG0 */ +#define AFE_IRQ8_MCU_DOMAIN_SFT 9 +#define AFE_IRQ8_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ8_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ8_MCU_FS_SFT 4 +#define AFE_IRQ8_MCU_FS_MASK 0x1f +#define AFE_IRQ8_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ8_MCU_ON_SFT 0 +#define AFE_IRQ8_MCU_ON_MASK 0x1 +#define AFE_IRQ8_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ8_MCU_CFG1 */ +#define AFE_IRQ8_CLR_CFG_SFT 31 +#define AFE_IRQ8_CLR_CFG_MASK 0x1 +#define AFE_IRQ8_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ8_MCU_CNT_SFT 0 +#define AFE_IRQ8_MCU_CNT_MASK 0xffffff +#define AFE_IRQ8_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ9_MCU_CFG0 */ +#define AFE_IRQ9_MCU_DOMAIN_SFT 9 +#define AFE_IRQ9_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ9_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ9_MCU_FS_SFT 4 +#define AFE_IRQ9_MCU_FS_MASK 0x1f +#define AFE_IRQ9_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ9_MCU_ON_SFT 0 +#define AFE_IRQ9_MCU_ON_MASK 0x1 +#define AFE_IRQ9_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ9_MCU_CFG1 */ +#define AFE_IRQ9_CLR_CFG_SFT 31 +#define AFE_IRQ9_CLR_CFG_MASK 0x1 +#define AFE_IRQ9_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ9_MCU_CNT_SFT 0 +#define AFE_IRQ9_MCU_CNT_MASK 0xffffff +#define AFE_IRQ9_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ10_MCU_CFG0 */ +#define AFE_IRQ10_MCU_DOMAIN_SFT 9 +#define AFE_IRQ10_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ10_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ10_MCU_FS_SFT 4 +#define AFE_IRQ10_MCU_FS_MASK 0x1f +#define AFE_IRQ10_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ10_MCU_ON_SFT 0 +#define AFE_IRQ10_MCU_ON_MASK 0x1 +#define AFE_IRQ10_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ10_MCU_CFG1 */ +#define AFE_IRQ10_CLR_CFG_SFT 31 +#define AFE_IRQ10_CLR_CFG_MASK 0x1 +#define AFE_IRQ10_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ10_MCU_CNT_SFT 0 +#define AFE_IRQ10_MCU_CNT_MASK 0xffffff +#define AFE_IRQ10_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ11_MCU_CFG0 */ +#define AFE_IRQ11_MCU_DOMAIN_SFT 9 +#define AFE_IRQ11_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ11_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ11_MCU_FS_SFT 4 +#define AFE_IRQ11_MCU_FS_MASK 0x1f +#define AFE_IRQ11_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ11_MCU_ON_SFT 0 +#define AFE_IRQ11_MCU_ON_MASK 0x1 +#define AFE_IRQ11_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ11_MCU_CFG1 */ +#define AFE_IRQ11_CLR_CFG_SFT 31 +#define AFE_IRQ11_CLR_CFG_MASK 0x1 +#define AFE_IRQ11_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ11_MCU_CNT_SFT 0 +#define AFE_IRQ11_MCU_CNT_MASK 0xffffff +#define AFE_IRQ11_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ12_MCU_CFG0 */ +#define AFE_IRQ12_MCU_DOMAIN_SFT 9 +#define AFE_IRQ12_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ12_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ12_MCU_FS_SFT 4 +#define AFE_IRQ12_MCU_FS_MASK 0x1f +#define AFE_IRQ12_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ12_MCU_ON_SFT 0 +#define AFE_IRQ12_MCU_ON_MASK 0x1 +#define AFE_IRQ12_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ12_MCU_CFG1 */ +#define AFE_IRQ12_CLR_CFG_SFT 31 +#define AFE_IRQ12_CLR_CFG_MASK 0x1 +#define AFE_IRQ12_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ12_MCU_CNT_SFT 0 +#define AFE_IRQ12_MCU_CNT_MASK 0xffffff +#define AFE_IRQ12_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ13_MCU_CFG0 */ +#define AFE_IRQ13_MCU_DOMAIN_SFT 9 +#define AFE_IRQ13_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ13_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ13_MCU_FS_SFT 4 +#define AFE_IRQ13_MCU_FS_MASK 0x1f +#define AFE_IRQ13_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ13_MCU_ON_SFT 0 +#define AFE_IRQ13_MCU_ON_MASK 0x1 +#define AFE_IRQ13_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ13_MCU_CFG1 */ +#define AFE_IRQ13_CLR_CFG_SFT 31 +#define AFE_IRQ13_CLR_CFG_MASK 0x1 +#define AFE_IRQ13_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ13_MCU_CNT_SFT 0 +#define AFE_IRQ13_MCU_CNT_MASK 0xffffff +#define AFE_IRQ13_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ14_MCU_CFG0 */ +#define AFE_IRQ14_MCU_DOMAIN_SFT 9 +#define AFE_IRQ14_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ14_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ14_MCU_FS_SFT 4 +#define AFE_IRQ14_MCU_FS_MASK 0x1f +#define AFE_IRQ14_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ14_MCU_ON_SFT 0 +#define AFE_IRQ14_MCU_ON_MASK 0x1 +#define AFE_IRQ14_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ14_MCU_CFG1 */ +#define AFE_IRQ14_CLR_CFG_SFT 31 +#define AFE_IRQ14_CLR_CFG_MASK 0x1 +#define AFE_IRQ14_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ14_MCU_CNT_SFT 0 +#define AFE_IRQ14_MCU_CNT_MASK 0xffffff +#define AFE_IRQ14_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ15_MCU_CFG0 */ +#define AFE_IRQ15_MCU_DOMAIN_SFT 9 +#define AFE_IRQ15_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ15_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ15_MCU_FS_SFT 4 +#define AFE_IRQ15_MCU_FS_MASK 0x1f +#define AFE_IRQ15_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ15_MCU_ON_SFT 0 +#define AFE_IRQ15_MCU_ON_MASK 0x1 +#define AFE_IRQ15_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ15_MCU_CFG1 */ +#define AFE_IRQ15_CLR_CFG_SFT 31 +#define AFE_IRQ15_CLR_CFG_MASK 0x1 +#define AFE_IRQ15_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ15_MCU_CNT_SFT 0 +#define AFE_IRQ15_MCU_CNT_MASK 0xffffff +#define AFE_IRQ15_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ16_MCU_CFG0 */ +#define AFE_IRQ16_MCU_DOMAIN_SFT 9 +#define AFE_IRQ16_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ16_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ16_MCU_FS_SFT 4 +#define AFE_IRQ16_MCU_FS_MASK 0x1f +#define AFE_IRQ16_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ16_MCU_ON_SFT 0 +#define AFE_IRQ16_MCU_ON_MASK 0x1 +#define AFE_IRQ16_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ16_MCU_CFG1 */ +#define AFE_IRQ16_CLR_CFG_SFT 31 +#define AFE_IRQ16_CLR_CFG_MASK 0x1 +#define AFE_IRQ16_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ16_MCU_CNT_SFT 0 +#define AFE_IRQ16_MCU_CNT_MASK 0xffffff +#define AFE_IRQ16_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ17_MCU_CFG0 */ +#define AFE_IRQ17_MCU_DOMAIN_SFT 9 +#define AFE_IRQ17_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ17_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ17_MCU_FS_SFT 4 +#define AFE_IRQ17_MCU_FS_MASK 0x1f +#define AFE_IRQ17_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ17_MCU_ON_SFT 0 +#define AFE_IRQ17_MCU_ON_MASK 0x1 +#define AFE_IRQ17_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ17_MCU_CFG1 */ +#define AFE_IRQ17_CLR_CFG_SFT 31 +#define AFE_IRQ17_CLR_CFG_MASK 0x1 +#define AFE_IRQ17_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ17_MCU_CNT_SFT 0 +#define AFE_IRQ17_MCU_CNT_MASK 0xffffff +#define AFE_IRQ17_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ18_MCU_CFG0 */ +#define AFE_IRQ18_MCU_DOMAIN_SFT 9 +#define AFE_IRQ18_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ18_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ18_MCU_FS_SFT 4 +#define AFE_IRQ18_MCU_FS_MASK 0x1f +#define AFE_IRQ18_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ18_MCU_ON_SFT 0 +#define AFE_IRQ18_MCU_ON_MASK 0x1 +#define AFE_IRQ18_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ18_MCU_CFG1 */ +#define AFE_IRQ18_CLR_CFG_SFT 31 +#define AFE_IRQ18_CLR_CFG_MASK 0x1 +#define AFE_IRQ18_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ18_MCU_CNT_SFT 0 +#define AFE_IRQ18_MCU_CNT_MASK 0xffffff +#define AFE_IRQ18_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ19_MCU_CFG0 */ +#define AFE_IRQ19_MCU_DOMAIN_SFT 9 +#define AFE_IRQ19_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ19_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ19_MCU_FS_SFT 4 +#define AFE_IRQ19_MCU_FS_MASK 0x1f +#define AFE_IRQ19_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ19_MCU_ON_SFT 0 +#define AFE_IRQ19_MCU_ON_MASK 0x1 +#define AFE_IRQ19_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ19_MCU_CFG1 */ +#define AFE_IRQ19_CLR_CFG_SFT 31 +#define AFE_IRQ19_CLR_CFG_MASK 0x1 +#define AFE_IRQ19_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ19_MCU_CNT_SFT 0 +#define AFE_IRQ19_MCU_CNT_MASK 0xffffff +#define AFE_IRQ19_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ20_MCU_CFG0 */ +#define AFE_IRQ20_MCU_DOMAIN_SFT 9 +#define AFE_IRQ20_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ20_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ20_MCU_FS_SFT 4 +#define AFE_IRQ20_MCU_FS_MASK 0x1f +#define AFE_IRQ20_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ20_MCU_ON_SFT 0 +#define AFE_IRQ20_MCU_ON_MASK 0x1 +#define AFE_IRQ20_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ20_MCU_CFG1 */ +#define AFE_IRQ20_CLR_CFG_SFT 31 +#define AFE_IRQ20_CLR_CFG_MASK 0x1 +#define AFE_IRQ20_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ20_MCU_CNT_SFT 0 +#define AFE_IRQ20_MCU_CNT_MASK 0xffffff +#define AFE_IRQ20_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ21_MCU_CFG0 */ +#define AFE_IRQ21_MCU_DOMAIN_SFT 9 +#define AFE_IRQ21_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ21_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ21_MCU_FS_SFT 4 +#define AFE_IRQ21_MCU_FS_MASK 0x1f +#define AFE_IRQ21_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ21_MCU_ON_SFT 0 +#define AFE_IRQ21_MCU_ON_MASK 0x1 +#define AFE_IRQ21_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ21_MCU_CFG1 */ +#define AFE_IRQ21_CLR_CFG_SFT 31 +#define AFE_IRQ21_CLR_CFG_MASK 0x1 +#define AFE_IRQ21_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ21_MCU_CNT_SFT 0 +#define AFE_IRQ21_MCU_CNT_MASK 0xffffff +#define AFE_IRQ21_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ22_MCU_CFG0 */ +#define AFE_IRQ22_MCU_DOMAIN_SFT 9 +#define AFE_IRQ22_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ22_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ22_MCU_FS_SFT 4 +#define AFE_IRQ22_MCU_FS_MASK 0x1f +#define AFE_IRQ22_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ22_MCU_ON_SFT 0 +#define AFE_IRQ22_MCU_ON_MASK 0x1 +#define AFE_IRQ22_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ22_MCU_CFG1 */ +#define AFE_IRQ22_CLR_CFG_SFT 31 +#define AFE_IRQ22_CLR_CFG_MASK 0x1 +#define AFE_IRQ22_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ22_MCU_CNT_SFT 0 +#define AFE_IRQ22_MCU_CNT_MASK 0xffffff +#define AFE_IRQ22_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ23_MCU_CFG0 */ +#define AFE_IRQ23_MCU_DOMAIN_SFT 9 +#define AFE_IRQ23_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ23_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ23_MCU_FS_SFT 4 +#define AFE_IRQ23_MCU_FS_MASK 0x1f +#define AFE_IRQ23_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ23_MCU_ON_SFT 0 +#define AFE_IRQ23_MCU_ON_MASK 0x1 +#define AFE_IRQ23_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ23_MCU_CFG1 */ +#define AFE_IRQ23_CLR_CFG_SFT 31 +#define AFE_IRQ23_CLR_CFG_MASK 0x1 +#define AFE_IRQ23_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ23_MCU_CNT_SFT 0 +#define AFE_IRQ23_MCU_CNT_MASK 0xffffff +#define AFE_IRQ23_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ24_MCU_CFG0 */ +#define AFE_IRQ24_MCU_DOMAIN_SFT 9 +#define AFE_IRQ24_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ24_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ24_MCU_FS_SFT 4 +#define AFE_IRQ24_MCU_FS_MASK 0x1f +#define AFE_IRQ24_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ24_MCU_ON_SFT 0 +#define AFE_IRQ24_MCU_ON_MASK 0x1 +#define AFE_IRQ24_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ24_MCU_CFG1 */ +#define AFE_IRQ24_CLR_CFG_SFT 31 +#define AFE_IRQ24_CLR_CFG_MASK 0x1 +#define AFE_IRQ24_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ24_MCU_CNT_SFT 0 +#define AFE_IRQ24_MCU_CNT_MASK 0xffffff +#define AFE_IRQ24_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ25_MCU_CFG0 */ +#define AFE_IRQ25_MCU_DOMAIN_SFT 9 +#define AFE_IRQ25_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ25_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ25_MCU_FS_SFT 4 +#define AFE_IRQ25_MCU_FS_MASK 0x1f +#define AFE_IRQ25_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ25_MCU_ON_SFT 0 +#define AFE_IRQ25_MCU_ON_MASK 0x1 +#define AFE_IRQ25_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ25_MCU_CFG1 */ +#define AFE_IRQ25_CLR_CFG_SFT 31 +#define AFE_IRQ25_CLR_CFG_MASK 0x1 +#define AFE_IRQ25_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ25_MCU_CNT_SFT 0 +#define AFE_IRQ25_MCU_CNT_MASK 0xffffff +#define AFE_IRQ25_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ26_MCU_CFG0 */ +#define AFE_IRQ26_MCU_DOMAIN_SFT 9 +#define AFE_IRQ26_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ26_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ26_MCU_FS_SFT 4 +#define AFE_IRQ26_MCU_FS_MASK 0x1f +#define AFE_IRQ26_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ26_MCU_ON_SFT 0 +#define AFE_IRQ26_MCU_ON_MASK 0x1 +#define AFE_IRQ26_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ26_MCU_CFG1 */ +#define AFE_IRQ26_CLR_CFG_SFT 31 +#define AFE_IRQ26_CLR_CFG_MASK 0x1 +#define AFE_IRQ26_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ26_MCU_CNT_SFT 0 +#define AFE_IRQ26_MCU_CNT_MASK 0xffffff +#define AFE_IRQ26_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_CUSTOM_IRQ0_MCU_CFG0 */ +#define AFE_CUSTOM_IRQ0_MCU_ON_SFT 0 +#define AFE_CUSTOM_IRQ0_MCU_ON_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_MON0 */ +#define AFE_IRQ26_MISS_FLAG_SFT 26 +#define AFE_IRQ26_MISS_FLAG_MASK 0x1 +#define AFE_IRQ26_MISS_FLAG_MASK_SFT (0x1 << 26) +#define AFE_IRQ25_MISS_FLAG_SFT 25 +#define AFE_IRQ25_MISS_FLAG_MASK 0x1 +#define AFE_IRQ25_MISS_FLAG_MASK_SFT (0x1 << 25) +#define AFE_IRQ24_MISS_FLAG_SFT 24 +#define AFE_IRQ24_MISS_FLAG_MASK 0x1 +#define AFE_IRQ24_MISS_FLAG_MASK_SFT (0x1 << 24) +#define AFE_IRQ23_MISS_FLAG_SFT 23 +#define AFE_IRQ23_MISS_FLAG_MASK 0x1 +#define AFE_IRQ23_MISS_FLAG_MASK_SFT (0x1 << 23) +#define AFE_IRQ22_MISS_FLAG_SFT 22 +#define AFE_IRQ22_MISS_FLAG_MASK 0x1 +#define AFE_IRQ22_MISS_FLAG_MASK_SFT (0x1 << 22) +#define AFE_IRQ21_MISS_FLAG_SFT 21 +#define AFE_IRQ21_MISS_FLAG_MASK 0x1 +#define AFE_IRQ21_MISS_FLAG_MASK_SFT (0x1 << 21) +#define AFE_IRQ20_MISS_FLAG_SFT 20 +#define AFE_IRQ20_MISS_FLAG_MASK 0x1 +#define AFE_IRQ20_MISS_FLAG_MASK_SFT (0x1 << 20) +#define AFE_IRQ19_MISS_FLAG_SFT 19 +#define AFE_IRQ19_MISS_FLAG_MASK 0x1 +#define AFE_IRQ19_MISS_FLAG_MASK_SFT (0x1 << 19) +#define AFE_IRQ18_MISS_FLAG_SFT 18 +#define AFE_IRQ18_MISS_FLAG_MASK 0x1 +#define AFE_IRQ18_MISS_FLAG_MASK_SFT (0x1 << 18) +#define AFE_IRQ17_MISS_FLAG_SFT 17 +#define AFE_IRQ17_MISS_FLAG_MASK 0x1 +#define AFE_IRQ17_MISS_FLAG_MASK_SFT (0x1 << 17) +#define AFE_IRQ16_MISS_FLAG_SFT 16 +#define AFE_IRQ16_MISS_FLAG_MASK 0x1 +#define AFE_IRQ16_MISS_FLAG_MASK_SFT (0x1 << 16) +#define AFE_IRQ15_MISS_FLAG_SFT 15 +#define AFE_IRQ15_MISS_FLAG_MASK 0x1 +#define AFE_IRQ15_MISS_FLAG_MASK_SFT (0x1 << 15) +#define AFE_IRQ14_MISS_FLAG_SFT 14 +#define AFE_IRQ14_MISS_FLAG_MASK 0x1 +#define AFE_IRQ14_MISS_FLAG_MASK_SFT (0x1 << 14) +#define AFE_IRQ13_MISS_FLAG_SFT 13 +#define AFE_IRQ13_MISS_FLAG_MASK 0x1 +#define AFE_IRQ13_MISS_FLAG_MASK_SFT (0x1 << 13) +#define AFE_IRQ12_MISS_FLAG_SFT 12 +#define AFE_IRQ12_MISS_FLAG_MASK 0x1 +#define AFE_IRQ12_MISS_FLAG_MASK_SFT (0x1 << 12) +#define AFE_IRQ11_MISS_FLAG_SFT 11 +#define AFE_IRQ11_MISS_FLAG_MASK 0x1 +#define AFE_IRQ11_MISS_FLAG_MASK_SFT (0x1 << 11) +#define AFE_IRQ10_MISS_FLAG_SFT 10 +#define AFE_IRQ10_MISS_FLAG_MASK 0x1 +#define AFE_IRQ10_MISS_FLAG_MASK_SFT (0x1 << 10) +#define AFE_IRQ9_MISS_FLAG_SFT 9 +#define AFE_IRQ9_MISS_FLAG_MASK 0x1 +#define AFE_IRQ9_MISS_FLAG_MASK_SFT (0x1 << 9) +#define AFE_IRQ8_MISS_FLAG_SFT 8 +#define AFE_IRQ8_MISS_FLAG_MASK 0x1 +#define AFE_IRQ8_MISS_FLAG_MASK_SFT (0x1 << 8) +#define AFE_IRQ7_MISS_FLAG_SFT 7 +#define AFE_IRQ7_MISS_FLAG_MASK 0x1 +#define AFE_IRQ7_MISS_FLAG_MASK_SFT (0x1 << 7) +#define AFE_IRQ6_MISS_FLAG_SFT 6 +#define AFE_IRQ6_MISS_FLAG_MASK 0x1 +#define AFE_IRQ6_MISS_FLAG_MASK_SFT (0x1 << 6) +#define AFE_IRQ5_MISS_FLAG_SFT 5 +#define AFE_IRQ5_MISS_FLAG_MASK 0x1 +#define AFE_IRQ5_MISS_FLAG_MASK_SFT (0x1 << 5) +#define AFE_IRQ4_MISS_FLAG_SFT 4 +#define AFE_IRQ4_MISS_FLAG_MASK 0x1 +#define AFE_IRQ4_MISS_FLAG_MASK_SFT (0x1 << 4) +#define AFE_IRQ3_MISS_FLAG_SFT 3 +#define AFE_IRQ3_MISS_FLAG_MASK 0x1 +#define AFE_IRQ3_MISS_FLAG_MASK_SFT (0x1 << 3) +#define AFE_IRQ2_MISS_FLAG_SFT 2 +#define AFE_IRQ2_MISS_FLAG_MASK 0x1 +#define AFE_IRQ2_MISS_FLAG_MASK_SFT (0x1 << 2) +#define AFE_IRQ1_MISS_FLAG_SFT 1 +#define AFE_IRQ1_MISS_FLAG_MASK 0x1 +#define AFE_IRQ1_MISS_FLAG_MASK_SFT (0x1 << 1) +#define AFE_IRQ0_MISS_FLAG_SFT 0 +#define AFE_IRQ0_MISS_FLAG_MASK 0x1 +#define AFE_IRQ0_MISS_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_MON1 */ +#define AFE_CUSTOM_IRQ21_MISS_FLAG_SFT 21 +#define AFE_CUSTOM_IRQ21_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ21_MISS_FLAG_MASK_SFT (0x1 << 21) +#define AFE_CUSTOM_IRQ20_MISS_FLAG_SFT 20 +#define AFE_CUSTOM_IRQ20_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ20_MISS_FLAG_MASK_SFT (0x1 << 20) +#define AFE_CUSTOM_IRQ19_MISS_FLAG_SFT 19 +#define AFE_CUSTOM_IRQ19_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ19_MISS_FLAG_MASK_SFT (0x1 << 19) +#define AFE_CUSTOM_IRQ18_MISS_FLAG_SFT 18 +#define AFE_CUSTOM_IRQ18_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ18_MISS_FLAG_MASK_SFT (0x1 << 18) +#define AFE_CUSTOM_IRQ17_MISS_FLAG_SFT 17 +#define AFE_CUSTOM_IRQ17_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ17_MISS_FLAG_MASK_SFT (0x1 << 17) +#define AFE_CUSTOM_IRQ16_MISS_FLAG_SFT 16 +#define AFE_CUSTOM_IRQ16_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ16_MISS_FLAG_MASK_SFT (0x1 << 16) +#define AFE_CUSTOM_IRQ9_MISS_FLAG_SFT 9 +#define AFE_CUSTOM_IRQ9_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ9_MISS_FLAG_MASK_SFT (0x1 << 9) +#define AFE_CUSTOM_IRQ8_MISS_FLAG_SFT 8 +#define AFE_CUSTOM_IRQ8_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ8_MISS_FLAG_MASK_SFT (0x1 << 8) +#define AFE_CUSTOM_IRQ7_MISS_FLAG_SFT 7 +#define AFE_CUSTOM_IRQ7_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ7_MISS_FLAG_MASK_SFT (0x1 << 7) +#define AFE_CUSTOM_IRQ6_MISS_FLAG_SFT 6 +#define AFE_CUSTOM_IRQ6_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ6_MISS_FLAG_MASK_SFT (0x1 << 6) +#define AFE_CUSTOM_IRQ5_MISS_FLAG_SFT 5 +#define AFE_CUSTOM_IRQ5_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ5_MISS_FLAG_MASK_SFT (0x1 << 5) +#define AFE_CUSTOM_IRQ4_MISS_FLAG_SFT 4 +#define AFE_CUSTOM_IRQ4_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ4_MISS_FLAG_MASK_SFT (0x1 << 4) +#define AFE_CUSTOM_IRQ3_MISS_FLAG_SFT 3 +#define AFE_CUSTOM_IRQ3_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ3_MISS_FLAG_MASK_SFT (0x1 << 3) +#define AFE_CUSTOM_IRQ2_MISS_FLAG_SFT 2 +#define AFE_CUSTOM_IRQ2_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ2_MISS_FLAG_MASK_SFT (0x1 << 2) +#define AFE_CUSTOM_IRQ1_MISS_FLAG_SFT 1 +#define AFE_CUSTOM_IRQ1_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ1_MISS_FLAG_MASK_SFT (0x1 << 1) +#define AFE_CUSTOM_IRQ0_MISS_FLAG_SFT 0 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_MON2 */ +#define AFE_IRQ_B_R_CNT_SFT 8 +#define AFE_IRQ_B_R_CNT_MASK 0xff +#define AFE_IRQ_B_R_CNT_MASK_SFT (0xff << 8) +#define AFE_IRQ_B_F_CNT_SFT 0 +#define AFE_IRQ_B_F_CNT_MASK 0xff +#define AFE_IRQ_B_F_CNT_MASK_SFT (0xff << 0) + +/* AFE_IRQ0_CNT_MON */ +#define AFE_IRQ0_CNT_MON_SFT 0 +#define AFE_IRQ0_CNT_MON_MASK 0xffffff +#define AFE_IRQ0_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ1_CNT_MON */ +#define AFE_IRQ1_CNT_MON_SFT 0 +#define AFE_IRQ1_CNT_MON_MASK 0xffffff +#define AFE_IRQ1_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ2_CNT_MON */ +#define AFE_IRQ2_CNT_MON_SFT 0 +#define AFE_IRQ2_CNT_MON_MASK 0xffffff +#define AFE_IRQ2_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ3_CNT_MON */ +#define AFE_IRQ3_CNT_MON_SFT 0 +#define AFE_IRQ3_CNT_MON_MASK 0xffffff +#define AFE_IRQ3_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ4_CNT_MON */ +#define AFE_IRQ4_CNT_MON_SFT 0 +#define AFE_IRQ4_CNT_MON_MASK 0xffffff +#define AFE_IRQ4_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ5_CNT_MON */ +#define AFE_IRQ5_CNT_MON_SFT 0 +#define AFE_IRQ5_CNT_MON_MASK 0xffffff +#define AFE_IRQ5_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ6_CNT_MON */ +#define AFE_IRQ6_CNT_MON_SFT 0 +#define AFE_IRQ6_CNT_MON_MASK 0xffffff +#define AFE_IRQ6_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ7_CNT_MON */ +#define AFE_IRQ7_CNT_MON_SFT 0 +#define AFE_IRQ7_CNT_MON_MASK 0xffffff +#define AFE_IRQ7_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ8_CNT_MON */ +#define AFE_IRQ8_CNT_MON_SFT 0 +#define AFE_IRQ8_CNT_MON_MASK 0xffffff +#define AFE_IRQ8_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ9_CNT_MON */ +#define AFE_IRQ9_CNT_MON_SFT 0 +#define AFE_IRQ9_CNT_MON_MASK 0xffffff +#define AFE_IRQ9_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ10_CNT_MON */ +#define AFE_IRQ10_CNT_MON_SFT 0 +#define AFE_IRQ10_CNT_MON_MASK 0xffffff +#define AFE_IRQ10_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ11_CNT_MON */ +#define AFE_IRQ11_CNT_MON_SFT 0 +#define AFE_IRQ11_CNT_MON_MASK 0xffffff +#define AFE_IRQ11_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ12_CNT_MON */ +#define AFE_IRQ12_CNT_MON_SFT 0 +#define AFE_IRQ12_CNT_MON_MASK 0xffffff +#define AFE_IRQ12_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ13_CNT_MON */ +#define AFE_IRQ13_CNT_MON_SFT 0 +#define AFE_IRQ13_CNT_MON_MASK 0xffffff +#define AFE_IRQ13_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ14_CNT_MON */ +#define AFE_IRQ14_CNT_MON_SFT 0 +#define AFE_IRQ14_CNT_MON_MASK 0xffffff +#define AFE_IRQ14_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ15_CNT_MON */ +#define AFE_IRQ15_CNT_MON_SFT 0 +#define AFE_IRQ15_CNT_MON_MASK 0xffffff +#define AFE_IRQ15_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ16_CNT_MON */ +#define AFE_IRQ16_CNT_MON_SFT 0 +#define AFE_IRQ16_CNT_MON_MASK 0xffffff +#define AFE_IRQ16_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ17_CNT_MON */ +#define AFE_IRQ17_CNT_MON_SFT 0 +#define AFE_IRQ17_CNT_MON_MASK 0xffffff +#define AFE_IRQ17_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ18_CNT_MON */ +#define AFE_IRQ18_CNT_MON_SFT 0 +#define AFE_IRQ18_CNT_MON_MASK 0xffffff +#define AFE_IRQ18_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ19_CNT_MON */ +#define AFE_IRQ19_CNT_MON_SFT 0 +#define AFE_IRQ19_CNT_MON_MASK 0xffffff +#define AFE_IRQ19_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ20_CNT_MON */ +#define AFE_IRQ20_CNT_MON_SFT 0 +#define AFE_IRQ20_CNT_MON_MASK 0xffffff +#define AFE_IRQ20_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ21_CNT_MON */ +#define AFE_IRQ21_CNT_MON_SFT 0 +#define AFE_IRQ21_CNT_MON_MASK 0xffffff +#define AFE_IRQ21_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ22_CNT_MON */ +#define AFE_IRQ22_CNT_MON_SFT 0 +#define AFE_IRQ22_CNT_MON_MASK 0xffffff +#define AFE_IRQ22_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ23_CNT_MON */ +#define AFE_IRQ23_CNT_MON_SFT 0 +#define AFE_IRQ23_CNT_MON_MASK 0xffffff +#define AFE_IRQ23_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ24_CNT_MON */ +#define AFE_IRQ24_CNT_MON_SFT 0 +#define AFE_IRQ24_CNT_MON_MASK 0xffffff +#define AFE_IRQ24_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ25_CNT_MON */ +#define AFE_IRQ25_CNT_MON_SFT 0 +#define AFE_IRQ25_CNT_MON_MASK 0xffffff +#define AFE_IRQ25_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ26_CNT_MON */ +#define AFE_IRQ26_CNT_MON_SFT 0 +#define AFE_IRQ26_CNT_MON_MASK 0xffffff +#define AFE_IRQ26_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_CUSTOM_IRQ0_CNT_MON */ +#define AFE_CUSTOM_IRQ0_CNT_MON_SFT 0 +#define AFE_CUSTOM_IRQ0_CNT_MON_MASK 0xffffff +#define AFE_CUSTOM_IRQ0_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_CUSTOM_IRQ0_MCU_CFG1 */ +#define AFE_CUSTOM_IRQ0_CLR_CFG_SFT 31 +#define AFE_CUSTOM_IRQ0_CLR_CFG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_CUSTOM_IRQ0_MCU_CNT_SFT 0 +#define AFE_CUSTOM_IRQ0_MCU_CNT_MASK 0xffffff +#define AFE_CUSTOM_IRQ0_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_GAIN0_CON1_R */ +/* AFE_GAIN1_CON1_R */ +/* AFE_GAIN2_CON1_R */ +/* AFE_GAIN3_CON1_R */ +#define GAIN_TARGET_R_SFT 0 +#define GAIN_TARGET_R_MASK 0xffffffff +#define GAIN_TARGET_R_MASK_SFT (0xffffffff << 0) + +/* AFE_GAIN0_CON1_L */ +/* AFE_GAIN1_CON1_L */ +/* AFE_GAIN2_CON1_L */ +/* AFE_GAIN3_CON1_L */ +#define GAIN_TARGET_L_SFT 0 +#define GAIN_TARGET_L_MASK 0xffffffff +#define GAIN_TARGET_L_MASK_SFT (0xffffffff << 0) + +/* AFE_GAIN0_CON2 */ +#define GAIN0_DOWN_STEP_SFT 0 +#define GAIN0_DOWN_STEP_MASK 0x3fffff +#define GAIN0_DOWN_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN0_CON3 */ +#define GAIN0_UP_STEP_SFT 0 +#define GAIN0_UP_STEP_MASK 0x3fffff +#define GAIN0_UP_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN0_CUR_R */ +/* AFE_GAIN1_CUR_R */ +/* AFE_GAIN2_CUR_R */ +/* AFE_GAIN3_CUR_R */ +#define AFE_GAIN_CUR_R_SFT 0 +#define AFE_GAIN_CUR_R_MASK 0xffffffff +#define AFE_GAIN_CUR_R_MASK_SFT (0xffffffff << 0) + +/* AFE_GAIN0_CUR_L */ +/* AFE_GAIN1_CUR_L */ +/* AFE_GAIN2_CUR_L */ +/* AFE_GAIN3_CUR_L */ +#define AFE_GAIN_CUR_L_SFT 0 +#define AFE_GAIN_CUR_L_MASK 0xffffffff +#define AFE_GAIN_CUR_L_MASK_SFT (0xffffffff << 0) + +/* AFE_GAIN0_CON0 */ +/* AFE_GAIN1_CON0 */ +/* AFE_GAIN2_CON0 */ +/* AFE_GAIN3_CON0 */ +#define GAIN_TARGET_SYNC_ON_SFT 24 +#define GAIN_TARGET_SYNC_ON_MASK 0x1 +#define GAIN_TARGET_SYNC_ON_MASK_SFT (0x1 << 24) +#define GAIN_TIMEOUT_SFT 18 +#define GAIN_TIMEOUT_MASK 0x3f +#define GAIN_TIMEOUT_MASK_SFT (0x3f << 18) +#define GAIN_TRIG_SFT 17 +#define GAIN_TRIG_MASK 0x1 +#define GAIN_TRIG_MASK_SFT (0x1 << 17) +#define GAIN_ON_SFT 16 +#define GAIN_ON_MASK 0x1 +#define GAIN_ON_MASK_SFT (0x1 << 16) +#define GAIN_SAMPLE_PER_STEP_SFT 8 +#define GAIN_SAMPLE_PER_STEP_MASK 0xff +#define GAIN_SAMPLE_PER_STEP_MASK_SFT (0xff << 8) +#define GAIN_SEL_DOMAIN_SFT 5 +#define GAIN_SEL_DOMAIN_MASK 0x7 +#define GAIN_SEL_DOMAIN_MASK_SFT (0x7 << 5) +#define GAIN_SEL_FS_SFT 0 +#define GAIN_SEL_FS_MASK 0x1f +#define GAIN_SEL_FS_MASK_SFT (0x1f << 0) + +/* AFE_GAIN1_CON2 */ +#define GAIN1_DOWN_STEP_SFT 0 +#define GAIN1_DOWN_STEP_MASK 0x3fffff +#define GAIN1_DOWN_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN1_CON3 */ +#define GAIN1_UP_STEP_SFT 0 +#define GAIN1_UP_STEP_MASK 0x3fffff +#define GAIN1_UP_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN2_CON2 */ +#define GAIN2_DOWN_STEP_SFT 0 +#define GAIN2_DOWN_STEP_MASK 0x3fffff +#define GAIN2_DOWN_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN2_CON3 */ +#define GAIN2_UP_STEP_SFT 0 +#define GAIN2_UP_STEP_MASK 0x3fffff +#define GAIN2_UP_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN3_CON2 */ +#define GAIN3_DOWN_STEP_SFT 0 +#define GAIN3_DOWN_STEP_MASK 0x3fffff +#define GAIN3_DOWN_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_GAIN3_CON3 */ +#define GAIN3_UP_STEP_SFT 0 +#define GAIN3_UP_STEP_MASK 0x3fffff +#define GAIN3_UP_STEP_MASK_SFT (0x3fffff << 0) + +/* AFE_STF_CON0 */ +#define SLT_CNT_FLAG_RESET_SFT 28 +#define SLT_CNT_FLAG_RESET_MASK 0x1 +#define SLT_CNT_FLAG_RESET_MASK_SFT (0x1 << 28) +#define SLT_CNT_THD_SFT 16 +#define SLT_CNT_THD_MASK 0xfff +#define SLT_CNT_THD_MASK_SFT (0xfff << 16) +#define SIDE_TONE_HALF_TAP_NUM_SFT 4 +#define SIDE_TONE_HALF_TAP_NUM_MASK 0x7f +#define SIDE_TONE_HALF_TAP_NUM_MASK_SFT (0x7f << 4) +#define SIDE_TONE_ODD_MODE_SFT 1 +#define SIDE_TONE_ODD_MODE_MASK 0x1 +#define SIDE_TONE_ODD_MODE_MASK_SFT (0x1 << 1) +#define SIDE_TONE_ON_SFT 0 +#define SIDE_TONE_ON_MASK 0x1 +#define SIDE_TONE_ON_MASK_SFT (0x1 << 0) + +/* AFE_STF_CON1 */ +#define SIDE_TONE_IN_EN_SEL_DOMAIN_SFT 5 +#define SIDE_TONE_IN_EN_SEL_DOMAIN_MASK 0x7 +#define SIDE_TONE_IN_EN_SEL_DOMAIN_MASK_SFT (0x7 << 5) +#define SIDE_TONE_IN_EN_SEL_FS_SFT 0 +#define SIDE_TONE_IN_EN_SEL_FS_MASK 0x1f +#define SIDE_TONE_IN_EN_SEL_FS_MASK_SFT (0x1f << 0) + +/* AFE_STF_COEFF */ +#define SIDE_TONE_COEFFICIENT_R_W_SEL_SFT 24 +#define SIDE_TONE_COEFFICIENT_R_W_SEL_MASK 0x1 +#define SIDE_TONE_COEFFICIENT_R_W_SEL_MASK_SFT (0x1 << 24) +#define SIDE_TONE_COEFFICIENT_ADDR_SFT 16 +#define SIDE_TONE_COEFFICIENT_ADDR_MASK 0x1f +#define SIDE_TONE_COEFFICIENT_ADDR_MASK_SFT (0x1f << 16) +#define SIDE_TONE_COEFFICIENT_SFT 0 +#define SIDE_TONE_COEFFICIENT_MASK 0xffff +#define SIDE_TONE_COEFFICIENT_MASK_SFT (0xffff << 0) + +/* AFE_STF_GAIN */ +#define SIDE_TONE_POSITIVE_GAIN_SFT 16 +#define SIDE_TONE_POSITIVE_GAIN_MASK 0x7 +#define SIDE_TONE_POSITIVE_GAIN_MASK_SFT (0x7 << 16) +#define SIDE_TONE_GAIN_SFT 0 +#define SIDE_TONE_GAIN_MASK 0xffff +#define SIDE_TONE_GAIN_MASK_SFT (0xffff << 0) + +/* AFE_STF_MON */ +#define SIDE_TONE_R_RDY_SFT 30 +#define SIDE_TONE_R_RDY_MASK 0x1 +#define SIDE_TONE_R_RDY_MASK_SFT (0x1 << 30) +#define SIDE_TONE_W_RDY_SFT 29 +#define SIDE_TONE_W_RDY_MASK 0x1 +#define SIDE_TONE_W_RDY_MASK_SFT (0x1 << 29) +#define SLT_CNT_FLAG_SFT 28 +#define SLT_CNT_FLAG_MASK 0x1 +#define SLT_CNT_FLAG_MASK_SFT (0x1 << 28) +#define SLT_CNT_SFT 16 +#define SLT_CNT_MASK 0xfff +#define SLT_CNT_MASK_SFT (0xfff << 16) +#define SIDE_TONE_COEFF_SFT 0 +#define SIDE_TONE_COEFF_MASK 0xffff +#define SIDE_TONE_COEFF_MASK_SFT (0xffff << 0) + +/* AFE_STF_IP_VERSION */ +#define SIDE_TONE_IP_VERSION_SFT 0 +#define SIDE_TONE_IP_VERSION_MASK 0xffffffff +#define SIDE_TONE_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CM_REG */ +#define AFE_CM_UPDATE_CNT_SFT 16 +#define AFE_CM_UPDATE_CNT_MASK 0x7fff +#define AFE_CM_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM_1X_EN_SEL_FS_SFT 8 +#define AFE_CM_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM_CH_NUM_SFT 2 +#define AFE_CM_CH_NUM_MASK 0x1f +#define AFE_CM_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM_BYTE_SWAP_SFT 1 +#define AFE_CM_BYTE_SWAP_MASK 0x1 +#define AFE_CM_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM_BYPASS_MODE_SFT 31 +#define AFE_CM_BYPASS_MODE_MASK 0x1 +#define AFE_CM_BYPASS_MODE_MASK_SFT (0x1 << 31) + +/* AFE_CM0_CON0 */ +#define AFE_CM0_BYPASS_MODE_SFT 31 +#define AFE_CM0_BYPASS_MODE_MASK 0x1 +#define AFE_CM0_BYPASS_MODE_MASK_SFT (0x1 << 31) +#define AFE_CM0_UPDATE_CNT_SFT 16 +#define AFE_CM0_UPDATE_CNT_MASK 0x7fff +#define AFE_CM0_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM0_1X_EN_SEL_DOMAIN_SFT 13 +#define AFE_CM0_1X_EN_SEL_DOMAIN_MASK 0x7 +#define AFE_CM0_1X_EN_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define AFE_CM0_1X_EN_SEL_FS_SFT 8 +#define AFE_CM0_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM0_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM0_OUTPUT_MUX_SFT 7 +#define AFE_CM0_OUTPUT_MUX_MASK 0x1 +#define AFE_CM0_OUTPUT_MUX_MASK_SFT (0x1 << 7) +#define AFE_CM0_CH_NUM_SFT 2 +#define AFE_CM0_CH_NUM_MASK 0x1f +#define AFE_CM0_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM0_BYTE_SWAP_SFT 1 +#define AFE_CM0_BYTE_SWAP_MASK 0x1 +#define AFE_CM0_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM0_ON_SFT 0 +#define AFE_CM0_ON_MASK 0x1 +#define AFE_CM0_ON_MASK_SFT (0x1 << 0) + +/* AFE_CM0_MON */ +#define AFE_CM0_BYPASS_MODE_MON_SFT 31 +#define AFE_CM0_BYPASS_MODE_MON_MASK 0x1 +#define AFE_CM0_BYPASS_MODE_MON_MASK_SFT (0x1 << 31) +#define AFE_CM0_OUTPUT_CNT_MON_SFT 16 +#define AFE_CM0_OUTPUT_CNT_MON_MASK 0x7fff +#define AFE_CM0_OUTPUT_CNT_MON_MASK_SFT (0x7fff << 16) +#define AFE_CM0_CUR_CHSET_MON_SFT 5 +#define AFE_CM0_CUR_CHSET_MON_MASK 0xf +#define AFE_CM0_CUR_CHSET_MON_MASK_SFT (0xf << 5) +#define AFE_CM0_ODD_FLAG_MON_SFT 4 +#define AFE_CM0_ODD_FLAG_MON_MASK 0x1 +#define AFE_CM0_ODD_FLAG_MON_MASK_SFT (0x1 << 4) +#define AFE_CM0_BYTE_SWAP_MON_SFT 1 +#define AFE_CM0_BYTE_SWAP_MON_MASK 0x1 +#define AFE_CM0_BYTE_SWAP_MON_MASK_SFT (0x1 << 1) +#define AFE_CM0_ON_MON_SFT 0 +#define AFE_CM0_ON_MON_MASK 0x1 +#define AFE_CM0_ON_MON_MASK_SFT (0x1 << 0) + +/* AFE_CM0_IP_VERSION */ +#define AFE_CM0_IP_VERSION_SFT 0 +#define AFE_CM0_IP_VERSION_MASK 0xffffffff +#define AFE_CM0_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CM1_CON0 */ +#define AFE_CM1_BYPASS_MODE_SFT 31 +#define AFE_CM1_BYPASS_MODE_MASK 0x1 +#define AFE_CM1_BYPASS_MODE_MASK_SFT (0x1 << 31) +#define AFE_CM1_UPDATE_CNT_SFT 16 +#define AFE_CM1_UPDATE_CNT_MASK 0x7fff +#define AFE_CM1_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM1_1X_EN_SEL_DOMAIN_SFT 13 +#define AFE_CM1_1X_EN_SEL_DOMAIN_MASK 0x7 +#define AFE_CM1_1X_EN_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define AFE_CM1_1X_EN_SEL_FS_SFT 8 +#define AFE_CM1_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM1_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM1_OUTPUT_MUX_SFT 7 +#define AFE_CM1_OUTPUT_MUX_MASK 0x1 +#define AFE_CM1_OUTPUT_MUX_MASK_SFT (0x1 << 7) +#define AFE_CM1_CH_NUM_SFT 2 +#define AFE_CM1_CH_NUM_MASK 0x1f +#define AFE_CM1_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM1_BYTE_SWAP_SFT 1 +#define AFE_CM1_BYTE_SWAP_MASK 0x1 +#define AFE_CM1_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM1_ON_SFT 0 +#define AFE_CM1_ON_MASK 0x1 +#define AFE_CM1_ON_MASK_SFT (0x1 << 0) + +/* AFE_CM1_MON */ +#define AFE_CM1_BYPASS_MODE_MON_SFT 31 +#define AFE_CM1_BYPASS_MODE_MON_MASK 0x1 +#define AFE_CM1_BYPASS_MODE_MON_MASK_SFT (0x1 << 31) +#define AFE_CM1_OUTPUT_CNT_MON_SFT 16 +#define AFE_CM1_OUTPUT_CNT_MON_MASK 0x7fff +#define AFE_CM1_OUTPUT_CNT_MON_MASK_SFT (0x7fff << 16) +#define AFE_CM1_CUR_CHSET_MON_SFT 5 +#define AFE_CM1_CUR_CHSET_MON_MASK 0xf +#define AFE_CM1_CUR_CHSET_MON_MASK_SFT (0xf << 5) +#define AFE_CM1_ODD_FLAG_MON_SFT 4 +#define AFE_CM1_ODD_FLAG_MON_MASK 0x1 +#define AFE_CM1_ODD_FLAG_MON_MASK_SFT (0x1 << 4) +#define AFE_CM1_BYTE_SWAP_MON_SFT 1 +#define AFE_CM1_BYTE_SWAP_MON_MASK 0x1 +#define AFE_CM1_BYTE_SWAP_MON_MASK_SFT (0x1 << 1) +#define AFE_CM1_ON_MON_SFT 0 +#define AFE_CM1_ON_MON_MASK 0x1 +#define AFE_CM1_ON_MON_MASK_SFT (0x1 << 0) + +/* AFE_CM1_IP_VERSION */ +#define AFE_CM1_IP_VERSION_SFT 0 +#define AFE_CM1_IP_VERSION_MASK 0xffffffff +#define AFE_CM1_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CM2_CON0 */ +#define AFE_CM2_BYPASS_MODE_SFT 31 +#define AFE_CM2_BYPASS_MODE_MASK 0x1 +#define AFE_CM2_BYPASS_MODE_MASK_SFT (0x1 << 31) +#define AFE_CM2_UPDATE_CNT_SFT 16 +#define AFE_CM2_UPDATE_CNT_MASK 0x7fff +#define AFE_CM2_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM2_1X_EN_SEL_DOMAIN_SFT 13 +#define AFE_CM2_1X_EN_SEL_DOMAIN_MASK 0x7 +#define AFE_CM2_1X_EN_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define AFE_CM2_1X_EN_SEL_FS_SFT 8 +#define AFE_CM2_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM2_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM2_OUTPUT_MUX_SFT 7 +#define AFE_CM2_OUTPUT_MUX_MASK 0x1 +#define AFE_CM2_OUTPUT_MUX_MASK_SFT (0x1 << 7) +#define AFE_CM2_CH_NUM_SFT 2 +#define AFE_CM2_CH_NUM_MASK 0x1f +#define AFE_CM2_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM2_BYTE_SWAP_SFT 1 +#define AFE_CM2_BYTE_SWAP_MASK 0x1 +#define AFE_CM2_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM2_ON_SFT 0 +#define AFE_CM2_ON_MASK 0x1 +#define AFE_CM2_ON_MASK_SFT (0x1 << 0) + +/* AFE_CM2_MON */ +#define AFE_CM2_BYPASS_MODE_MON_SFT 31 +#define AFE_CM2_BYPASS_MODE_MON_MASK 0x1 +#define AFE_CM2_BYPASS_MODE_MON_MASK_SFT (0x1 << 31) +#define AFE_CM2_OUTPUT_CNT_MON_SFT 16 +#define AFE_CM2_OUTPUT_CNT_MON_MASK 0x7fff +#define AFE_CM2_OUTPUT_CNT_MON_MASK_SFT (0x7fff << 16) +#define AFE_CM2_CUR_CHSET_MON_SFT 5 +#define AFE_CM2_CUR_CHSET_MON_MASK 0xf +#define AFE_CM2_CUR_CHSET_MON_MASK_SFT (0xf << 5) +#define AFE_CM2_ODD_FLAG_MON_SFT 4 +#define AFE_CM2_ODD_FLAG_MON_MASK 0x1 +#define AFE_CM2_ODD_FLAG_MON_MASK_SFT (0x1 << 4) +#define AFE_CM2_BYTE_SWAP_MON_SFT 1 +#define AFE_CM2_BYTE_SWAP_MON_MASK 0x1 +#define AFE_CM2_BYTE_SWAP_MON_MASK_SFT (0x1 << 1) +#define AFE_CM2_ON_MON_SFT 0 +#define AFE_CM2_ON_MON_MASK 0x1 +#define AFE_CM2_ON_MON_MASK_SFT (0x1 << 0) + +/* AFE_CM2_IP_VERSION */ +#define AFE_CM2_IP_VERSION_SFT 0 +#define AFE_CM2_IP_VERSION_MASK 0xffffffff +#define AFE_CM2_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK 0x1 +#define ULCF_CFG_EN_CTL_MASK_SFT (0x1 << 31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT (0x7 << 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT (0x7 << 24) +#define UL_DMIC_TWO_WIRE_CTL_SFT 23 +#define UL_DMIC_TWO_WIRE_CTL_MASK 0x1 +#define UL_DMIC_TWO_WIRE_CTL_MASK_SFT (0x1 << 23) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK 0x1 +#define UL_AP_DMIC_ON_MASK_SFT (0x1 << 16) +#define DMIC_LOW_POWER_MODE_CTL_SFT 14 +#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3 +#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK 0x1 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12) +#define AMIC_26M_SEL_CTL_SFT 11 +#define AMIC_26M_SEL_CTL_MASK 0x1 +#define AMIC_26M_SEL_CTL_MASK_SFT (0x1 << 11) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK 0x1 +#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK 0x7 +#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK 0x1 +#define DIGMIC_4P33M_SEL_MASK_SFT (0x1 << 6) +#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5) +#define AMIC_6P5M_SEL_CTL_SFT 4 +#define AMIC_6P5M_SEL_CTL_MASK 0x1 +#define AMIC_6P5M_SEL_CTL_MASK_SFT (0x1 << 4) +#define AMIC_1P625M_SEL_CTL_SFT 3 +#define AMIC_1P625M_SEL_CTL_MASK 0x1 +#define AMIC_1P625M_SEL_CTL_MASK_SFT (0x1 << 3) +#define UL_LOOP_BACK_MODE_CTL_SFT 2 +#define UL_LOOP_BACK_MODE_CTL_MASK 0x1 +#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2) +#define UL_SDM_3_LEVEL_CTL_SFT 1 +#define UL_SDM_3_LEVEL_CTL_MASK 0x1 +#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1) +#define UL_SRC_ON_TMP_CTL_SFT 0 +#define UL_SRC_ON_TMP_CTL_MASK 0x1 +#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_UL0_SRC_CON1 */ +#define ADDA_UL_GAIN_VALUE_SFT 16 +#define ADDA_UL_GAIN_VALUE_MASK 0xffff +#define ADDA_UL_GAIN_VALUE_MASK_SFT (0xffff << 16) +#define ADDA_UL_POSTIVEGAIN_SFT 12 +#define ADDA_UL_POSTIVEGAIN_MASK 0x7 +#define ADDA_UL_POSTIVEGAIN_MASK_SFT (0x7 << 12) +#define ADDA_UL_ODDTAP_MODE_SFT 11 +#define ADDA_UL_ODDTAP_MODE_MASK 0x1 +#define ADDA_UL_ODDTAP_MODE_MASK_SFT (0x1 << 11) +#define ADDA_UL_HALF_TAP_NUM_SFT 5 +#define ADDA_UL_HALF_TAP_NUM_MASK 0x3f +#define ADDA_UL_HALF_TAP_NUM_MASK_SFT (0x3f << 5) +#define FIFO_SOFT_RST_SFT 4 +#define FIFO_SOFT_RST_MASK 0x1 +#define FIFO_SOFT_RST_MASK_SFT (0x1 << 4) +#define FIFO_SOFT_RST_EN_SFT 3 +#define FIFO_SOFT_RST_EN_MASK 0x1 +#define FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 3) +#define LR_SWAP_SFT 2 +#define LR_SWAP_MASK 0x1 +#define LR_SWAP_MASK_SFT (0x1 << 2) +#define GAIN_MODE_SFT 0 +#define GAIN_MODE_MASK 0x3 +#define GAIN_MODE_MASK_SFT (0x3 << 0) + +/* AFE_ADDA_UL0_SRC_CON2 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK 0x1 +#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK 0x1 +#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK 0x7 +#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK 0x1f +#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK 0xf +#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK 0x7 +#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK 0x1f +#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK 0xf +#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_UL0_SRC_DEBUG */ +#define UL_SLT_CNT_FLAG_RESET_CTL_SFT 16 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 16) +#define FIFO_DIGMIC_TESTIN_SFT 12 +#define FIFO_DIGMIC_TESTIN_MASK 0x3 +#define FIFO_DIGMIC_TESTIN_MASK_SFT (0x3 << 12) +#define FIFO_DIGMIC_WDATA_TESTEN_SFT 11 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK 0x1 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT (0x1 << 11) +#define SLT_CNT_THD_CTL_SFT 0 +#define SLT_CNT_THD_CTL_MASK 0x7ff +#define SLT_CNT_THD_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL0_SRC_DEBUG_MON0 */ +#define SLT_CNT_FLAG_CTL_SFT 16 +#define SLT_CNT_FLAG_CTL_MASK 0x1 +#define SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 16) +#define SLT_COUNTER_CTL_SFT 0 +#define SLT_COUNTER_CTL_MASK 0x7ff +#define SLT_COUNTER_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_02_01 */ +#define ADDA_IIR_COEF_02_01_SFT 0 +#define ADDA_IIR_COEF_02_01_MASK 0xffffffff +#define ADDA_IIR_COEF_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_04_03 */ +#define ADDA_IIR_COEF_04_03_SFT 0 +#define ADDA_IIR_COEF_04_03_MASK 0xffffffff +#define ADDA_IIR_COEF_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_06_05 */ +#define ADDA_IIR_COEF_06_05_SFT 0 +#define ADDA_IIR_COEF_06_05_MASK 0xffffffff +#define ADDA_IIR_COEF_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_08_07 */ +#define ADDA_IIR_COEF_08_07_SFT 0 +#define ADDA_IIR_COEF_08_07_MASK 0xffffffff +#define ADDA_IIR_COEF_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_10_09 */ +#define ADDA_IIR_COEF_10_09_SFT 0 +#define ADDA_IIR_COEF_10_09_MASK 0xffffffff +#define ADDA_IIR_COEF_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_02_01 */ +#define ADDA_ULCF_CFG_02_01_SFT 0 +#define ADDA_ULCF_CFG_02_01_MASK 0xffffffff +#define ADDA_ULCF_CFG_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_04_03 */ +#define ADDA_ULCF_CFG_04_03_SFT 0 +#define ADDA_ULCF_CFG_04_03_MASK 0xffffffff +#define ADDA_ULCF_CFG_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_06_05 */ +#define ADDA_ULCF_CFG_06_05_SFT 0 +#define ADDA_ULCF_CFG_06_05_MASK 0xffffffff +#define ADDA_ULCF_CFG_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_08_07 */ +#define ADDA_ULCF_CFG_08_07_SFT 0 +#define ADDA_ULCF_CFG_08_07_MASK 0xffffffff +#define ADDA_ULCF_CFG_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_10_09 */ +#define ADDA_ULCF_CFG_10_09_SFT 0 +#define ADDA_ULCF_CFG_10_09_MASK 0xffffffff +#define ADDA_ULCF_CFG_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_12_11 */ +#define ADDA_ULCF_CFG_12_11_SFT 0 +#define ADDA_ULCF_CFG_12_11_MASK 0xffffffff +#define ADDA_ULCF_CFG_12_11_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_14_13 */ +#define ADDA_ULCF_CFG_14_13_SFT 0 +#define ADDA_ULCF_CFG_14_13_MASK 0xffffffff +#define ADDA_ULCF_CFG_14_13_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_16_15 */ +#define ADDA_ULCF_CFG_16_15_SFT 0 +#define ADDA_ULCF_CFG_16_15_MASK 0xffffffff +#define ADDA_ULCF_CFG_16_15_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_18_17 */ +#define ADDA_ULCF_CFG_18_17_SFT 0 +#define ADDA_ULCF_CFG_18_17_MASK 0xffffffff +#define ADDA_ULCF_CFG_18_17_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_20_19 */ +#define ADDA_ULCF_CFG_20_19_SFT 0 +#define ADDA_ULCF_CFG_20_19_MASK 0xffffffff +#define ADDA_ULCF_CFG_20_19_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_22_21 */ +#define ADDA_ULCF_CFG_22_21_SFT 0 +#define ADDA_ULCF_CFG_22_21_MASK 0xffffffff +#define ADDA_ULCF_CFG_22_21_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_24_23 */ +#define ADDA_ULCF_CFG_24_23_SFT 0 +#define ADDA_ULCF_CFG_24_23_MASK 0xffffffff +#define ADDA_ULCF_CFG_24_23_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_26_25 */ +#define ADDA_ULCF_CFG_26_25_SFT 0 +#define ADDA_ULCF_CFG_26_25_MASK 0xffffffff +#define ADDA_ULCF_CFG_26_25_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_28_27 */ +#define ADDA_ULCF_CFG_28_27_SFT 0 +#define ADDA_ULCF_CFG_28_27_MASK 0xffffffff +#define ADDA_ULCF_CFG_28_27_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_30_29 */ +#define ADDA_ULCF_CFG_30_29_SFT 0 +#define ADDA_ULCF_CFG_30_29_MASK 0xffffffff +#define ADDA_ULCF_CFG_30_29_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_32_31 */ +#define ADDA_ULCF_CFG_32_31_SFT 0 +#define ADDA_ULCF_CFG_32_31_MASK 0xffffffff +#define ADDA_ULCF_CFG_32_31_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IP_VERSION */ +#define ADDA_ULCF_IP_VERSION_SFT 0 +#define ADDA_ULCF_IP_VERSION_MASK 0xffffffff +#define ADDA_ULCF_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK 0x1 +#define ULCF_CFG_EN_CTL_MASK_SFT (0x1 << 31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT (0x7 << 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT (0x7 << 24) +#define UL_DMIC_TWO_WIRE_CTL_SFT 23 +#define UL_DMIC_TWO_WIRE_CTL_MASK 0x1 +#define UL_DMIC_TWO_WIRE_CTL_MASK_SFT (0x1 << 23) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK 0x1 +#define UL_AP_DMIC_ON_MASK_SFT (0x1 << 16) +#define DMIC_LOW_POWER_MODE_CTL_SFT 14 +#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3 +#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK 0x1 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12) +#define AMIC_26M_SEL_CTL_SFT 11 +#define AMIC_26M_SEL_CTL_MASK 0x1 +#define AMIC_26M_SEL_CTL_MASK_SFT (0x1 << 11) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK 0x1 +#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK 0x7 +#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK 0x1 +#define DIGMIC_4P33M_SEL_MASK_SFT (0x1 << 6) +#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5) +#define AMIC_6P5M_SEL_CTL_SFT 4 +#define AMIC_6P5M_SEL_CTL_MASK 0x1 +#define AMIC_6P5M_SEL_CTL_MASK_SFT (0x1 << 4) +#define AMIC_1P625M_SEL_CTL_SFT 3 +#define AMIC_1P625M_SEL_CTL_MASK 0x1 +#define AMIC_1P625M_SEL_CTL_MASK_SFT (0x1 << 3) +#define UL_LOOP_BACK_MODE_CTL_SFT 2 +#define UL_LOOP_BACK_MODE_CTL_MASK 0x1 +#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2) +#define UL_SDM_3_LEVEL_CTL_SFT 1 +#define UL_SDM_3_LEVEL_CTL_MASK 0x1 +#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1) +#define UL_SRC_ON_TMP_CTL_SFT 0 +#define UL_SRC_ON_TMP_CTL_MASK 0x1 +#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_UL1_SRC_CON1 */ +#define ADDA_UL_GAIN_VALUE_SFT 16 +#define ADDA_UL_GAIN_VALUE_MASK 0xffff +#define ADDA_UL_GAIN_VALUE_MASK_SFT (0xffff << 16) +#define ADDA_UL_POSTIVEGAIN_SFT 12 +#define ADDA_UL_POSTIVEGAIN_MASK 0x7 +#define ADDA_UL_POSTIVEGAIN_MASK_SFT (0x7 << 12) +#define ADDA_UL_ODDTAP_MODE_SFT 11 +#define ADDA_UL_ODDTAP_MODE_MASK 0x1 +#define ADDA_UL_ODDTAP_MODE_MASK_SFT (0x1 << 11) +#define ADDA_UL_HALF_TAP_NUM_SFT 5 +#define ADDA_UL_HALF_TAP_NUM_MASK 0x3f +#define ADDA_UL_HALF_TAP_NUM_MASK_SFT (0x3f << 5) +#define FIFO_SOFT_RST_SFT 4 +#define FIFO_SOFT_RST_MASK 0x1 +#define FIFO_SOFT_RST_MASK_SFT (0x1 << 4) +#define FIFO_SOFT_RST_EN_SFT 3 +#define FIFO_SOFT_RST_EN_MASK 0x1 +#define FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 3) +#define LR_SWAP_SFT 2 +#define LR_SWAP_MASK 0x1 +#define LR_SWAP_MASK_SFT (0x1 << 2) +#define GAIN_MODE_SFT 0 +#define GAIN_MODE_MASK 0x3 +#define GAIN_MODE_MASK_SFT (0x3 << 0) + +/* AFE_ADDA_UL1_SRC_CON2 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK 0x1 +#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK 0x1 +#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK 0x7 +#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK 0x1f +#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK 0xf +#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK 0x7 +#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK 0x1f +#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK 0xf +#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_UL1_SRC_DEBUG */ +#define UL_SLT_CNT_FLAG_RESET_CTL_SFT 16 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 16) +#define FIFO_DIGMIC_TESTIN_SFT 12 +#define FIFO_DIGMIC_TESTIN_MASK 0x3 +#define FIFO_DIGMIC_TESTIN_MASK_SFT (0x3 << 12) +#define FIFO_DIGMIC_WDATA_TESTEN_SFT 11 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK 0x1 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT (0x1 << 11) +#define SLT_CNT_THD_CTL_SFT 0 +#define SLT_CNT_THD_CTL_MASK 0x7ff +#define SLT_CNT_THD_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL1_SRC_DEBUG_MON0 */ +#define SLT_CNT_FLAG_CTL_SFT 16 +#define SLT_CNT_FLAG_CTL_MASK 0x1 +#define SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 16) +#define SLT_COUNTER_CTL_SFT 0 +#define SLT_COUNTER_CTL_MASK 0x7ff +#define SLT_COUNTER_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_02_01 */ +#define ADDA_IIR_COEF_02_01_SFT 0 +#define ADDA_IIR_COEF_02_01_MASK 0xffffffff +#define ADDA_IIR_COEF_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_04_03 */ +#define ADDA_IIR_COEF_04_03_SFT 0 +#define ADDA_IIR_COEF_04_03_MASK 0xffffffff +#define ADDA_IIR_COEF_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_06_05 */ +#define ADDA_IIR_COEF_06_05_SFT 0 +#define ADDA_IIR_COEF_06_05_MASK 0xffffffff +#define ADDA_IIR_COEF_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_08_07 */ +#define ADDA_IIR_COEF_08_07_SFT 0 +#define ADDA_IIR_COEF_08_07_MASK 0xffffffff +#define ADDA_IIR_COEF_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_10_09 */ +#define ADDA_IIR_COEF_10_09_SFT 0 +#define ADDA_IIR_COEF_10_09_MASK 0xffffffff +#define ADDA_IIR_COEF_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_02_01 */ +#define ADDA_ULCF_CFG_02_01_SFT 0 +#define ADDA_ULCF_CFG_02_01_MASK 0xffffffff +#define ADDA_ULCF_CFG_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_04_03 */ +#define ADDA_ULCF_CFG_04_03_SFT 0 +#define ADDA_ULCF_CFG_04_03_MASK 0xffffffff +#define ADDA_ULCF_CFG_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_06_05 */ +#define ADDA_ULCF_CFG_06_05_SFT 0 +#define ADDA_ULCF_CFG_06_05_MASK 0xffffffff +#define ADDA_ULCF_CFG_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_08_07 */ +#define ADDA_ULCF_CFG_08_07_SFT 0 +#define ADDA_ULCF_CFG_08_07_MASK 0xffffffff +#define ADDA_ULCF_CFG_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_10_09 */ +#define ADDA_ULCF_CFG_10_09_SFT 0 +#define ADDA_ULCF_CFG_10_09_MASK 0xffffffff +#define ADDA_ULCF_CFG_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_12_11 */ +#define ADDA_ULCF_CFG_12_11_SFT 0 +#define ADDA_ULCF_CFG_12_11_MASK 0xffffffff +#define ADDA_ULCF_CFG_12_11_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_14_13 */ +#define ADDA_ULCF_CFG_14_13_SFT 0 +#define ADDA_ULCF_CFG_14_13_MASK 0xffffffff +#define ADDA_ULCF_CFG_14_13_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_16_15 */ +#define ADDA_ULCF_CFG_16_15_SFT 0 +#define ADDA_ULCF_CFG_16_15_MASK 0xffffffff +#define ADDA_ULCF_CFG_16_15_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_18_17 */ +#define ADDA_ULCF_CFG_18_17_SFT 0 +#define ADDA_ULCF_CFG_18_17_MASK 0xffffffff +#define ADDA_ULCF_CFG_18_17_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_20_19 */ +#define ADDA_ULCF_CFG_20_19_SFT 0 +#define ADDA_ULCF_CFG_20_19_MASK 0xffffffff +#define ADDA_ULCF_CFG_20_19_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_22_21 */ +#define ADDA_ULCF_CFG_22_21_SFT 0 +#define ADDA_ULCF_CFG_22_21_MASK 0xffffffff +#define ADDA_ULCF_CFG_22_21_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_24_23 */ +#define ADDA_ULCF_CFG_24_23_SFT 0 +#define ADDA_ULCF_CFG_24_23_MASK 0xffffffff +#define ADDA_ULCF_CFG_24_23_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_26_25 */ +#define ADDA_ULCF_CFG_26_25_SFT 0 +#define ADDA_ULCF_CFG_26_25_MASK 0xffffffff +#define ADDA_ULCF_CFG_26_25_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_28_27 */ +#define ADDA_ULCF_CFG_28_27_SFT 0 +#define ADDA_ULCF_CFG_28_27_MASK 0xffffffff +#define ADDA_ULCF_CFG_28_27_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_30_29 */ +#define ADDA_ULCF_CFG_30_29_SFT 0 +#define ADDA_ULCF_CFG_30_29_MASK 0xffffffff +#define ADDA_ULCF_CFG_30_29_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_32_31 */ +#define ADDA_ULCF_CFG_32_31_SFT 0 +#define ADDA_ULCF_CFG_32_31_MASK 0xffffffff +#define ADDA_ULCF_CFG_32_31_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IP_VERSION */ +#define ADDA_ULCF_IP_VERSION_SFT 0 +#define ADDA_ULCF_IP_VERSION_MASK 0xffffffff +#define ADDA_ULCF_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK 0x1 +#define ULCF_CFG_EN_CTL_MASK_SFT (0x1 << 31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT (0x7 << 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT (0x7 << 24) +#define UL_DMIC_TWO_WIRE_CTL_SFT 23 +#define UL_DMIC_TWO_WIRE_CTL_MASK 0x1 +#define UL_DMIC_TWO_WIRE_CTL_MASK_SFT (0x1 << 23) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK 0x1 +#define UL_AP_DMIC_ON_MASK_SFT (0x1 << 16) +#define DMIC_LOW_POWER_MODE_CTL_SFT 14 +#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3 +#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK 0x1 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12) +#define AMIC_26M_SEL_CTL_SFT 11 +#define AMIC_26M_SEL_CTL_MASK 0x1 +#define AMIC_26M_SEL_CTL_MASK_SFT (0x1 << 11) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK 0x1 +#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK 0x7 +#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK 0x1 +#define DIGMIC_4P33M_SEL_MASK_SFT (0x1 << 6) +#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5) +#define AMIC_6P5M_SEL_CTL_SFT 4 +#define AMIC_6P5M_SEL_CTL_MASK 0x1 +#define AMIC_6P5M_SEL_CTL_MASK_SFT (0x1 << 4) +#define AMIC_1P625M_SEL_CTL_SFT 3 +#define AMIC_1P625M_SEL_CTL_MASK 0x1 +#define AMIC_1P625M_SEL_CTL_MASK_SFT (0x1 << 3) +#define UL_LOOP_BACK_MODE_CTL_SFT 2 +#define UL_LOOP_BACK_MODE_CTL_MASK 0x1 +#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2) +#define UL_SDM_3_LEVEL_CTL_SFT 1 +#define UL_SDM_3_LEVEL_CTL_MASK 0x1 +#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1) +#define UL_SRC_ON_TMP_CTL_SFT 0 +#define UL_SRC_ON_TMP_CTL_MASK 0x1 +#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_UL2_SRC_CON1 */ +#define ADDA_UL_GAIN_VALUE_SFT 16 +#define ADDA_UL_GAIN_VALUE_MASK 0xffff +#define ADDA_UL_GAIN_VALUE_MASK_SFT (0xffff << 16) +#define ADDA_UL_POSTIVEGAIN_SFT 12 +#define ADDA_UL_POSTIVEGAIN_MASK 0x7 +#define ADDA_UL_POSTIVEGAIN_MASK_SFT (0x7 << 12) +#define ADDA_UL_ODDTAP_MODE_SFT 11 +#define ADDA_UL_ODDTAP_MODE_MASK 0x1 +#define ADDA_UL_ODDTAP_MODE_MASK_SFT (0x1 << 11) +#define ADDA_UL_HALF_TAP_NUM_SFT 5 +#define ADDA_UL_HALF_TAP_NUM_MASK 0x3f +#define ADDA_UL_HALF_TAP_NUM_MASK_SFT (0x3f << 5) +#define FIFO_SOFT_RST_SFT 4 +#define FIFO_SOFT_RST_MASK 0x1 +#define FIFO_SOFT_RST_MASK_SFT (0x1 << 4) +#define FIFO_SOFT_RST_EN_SFT 3 +#define FIFO_SOFT_RST_EN_MASK 0x1 +#define FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 3) +#define LR_SWAP_SFT 2 +#define LR_SWAP_MASK 0x1 +#define LR_SWAP_MASK_SFT (0x1 << 2) +#define GAIN_MODE_SFT 0 +#define GAIN_MODE_MASK 0x3 +#define GAIN_MODE_MASK_SFT (0x3 << 0) + +/* AFE_ADDA_UL2_SRC_CON2 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK 0x1 +#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK 0x1 +#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK 0x7 +#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK 0x1f +#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK 0xf +#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK 0x7 +#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK 0x1f +#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK 0xf +#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_UL2_SRC_DEBUG */ +#define UL_SLT_CNT_FLAG_RESET_CTL_SFT 16 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 16) +#define FIFO_DIGMIC_TESTIN_SFT 12 +#define FIFO_DIGMIC_TESTIN_MASK 0x3 +#define FIFO_DIGMIC_TESTIN_MASK_SFT (0x3 << 12) +#define FIFO_DIGMIC_WDATA_TESTEN_SFT 11 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK 0x1 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT (0x1 << 11) +#define SLT_CNT_THD_CTL_SFT 0 +#define SLT_CNT_THD_CTL_MASK 0x7ff +#define SLT_CNT_THD_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL2_SRC_DEBUG_MON0 */ +#define SLT_CNT_FLAG_CTL_SFT 16 +#define SLT_CNT_FLAG_CTL_MASK 0x1 +#define SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 16) +#define SLT_COUNTER_CTL_SFT 0 +#define SLT_COUNTER_CTL_MASK 0x7ff +#define SLT_COUNTER_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL2_IIR_COEF_02_01 */ +#define ADDA_IIR_COEF_02_01_SFT 0 +#define ADDA_IIR_COEF_02_01_MASK 0xffffffff +#define ADDA_IIR_COEF_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_IIR_COEF_04_03 */ +#define ADDA_IIR_COEF_04_03_SFT 0 +#define ADDA_IIR_COEF_04_03_MASK 0xffffffff +#define ADDA_IIR_COEF_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_IIR_COEF_06_05 */ +#define ADDA_IIR_COEF_06_05_SFT 0 +#define ADDA_IIR_COEF_06_05_MASK 0xffffffff +#define ADDA_IIR_COEF_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_IIR_COEF_08_07 */ +#define ADDA_IIR_COEF_08_07_SFT 0 +#define ADDA_IIR_COEF_08_07_MASK 0xffffffff +#define ADDA_IIR_COEF_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_IIR_COEF_10_09 */ +#define ADDA_IIR_COEF_10_09_SFT 0 +#define ADDA_IIR_COEF_10_09_MASK 0xffffffff +#define ADDA_IIR_COEF_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_02_01 */ +#define ADDA_ULCF_CFG_02_01_SFT 0 +#define ADDA_ULCF_CFG_02_01_MASK 0xffffffff +#define ADDA_ULCF_CFG_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_04_03 */ +#define ADDA_ULCF_CFG_04_03_SFT 0 +#define ADDA_ULCF_CFG_04_03_MASK 0xffffffff +#define ADDA_ULCF_CFG_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_06_05 */ +#define ADDA_ULCF_CFG_06_05_SFT 0 +#define ADDA_ULCF_CFG_06_05_MASK 0xffffffff +#define ADDA_ULCF_CFG_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_08_07 */ +#define ADDA_ULCF_CFG_08_07_SFT 0 +#define ADDA_ULCF_CFG_08_07_MASK 0xffffffff +#define ADDA_ULCF_CFG_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_10_09 */ +#define ADDA_ULCF_CFG_10_09_SFT 0 +#define ADDA_ULCF_CFG_10_09_MASK 0xffffffff +#define ADDA_ULCF_CFG_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_12_11 */ +#define ADDA_ULCF_CFG_12_11_SFT 0 +#define ADDA_ULCF_CFG_12_11_MASK 0xffffffff +#define ADDA_ULCF_CFG_12_11_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_14_13 */ +#define ADDA_ULCF_CFG_14_13_SFT 0 +#define ADDA_ULCF_CFG_14_13_MASK 0xffffffff +#define ADDA_ULCF_CFG_14_13_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_16_15 */ +#define ADDA_ULCF_CFG_16_15_SFT 0 +#define ADDA_ULCF_CFG_16_15_MASK 0xffffffff +#define ADDA_ULCF_CFG_16_15_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_18_17 */ +#define ADDA_ULCF_CFG_18_17_SFT 0 +#define ADDA_ULCF_CFG_18_17_MASK 0xffffffff +#define ADDA_ULCF_CFG_18_17_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_20_19 */ +#define ADDA_ULCF_CFG_20_19_SFT 0 +#define ADDA_ULCF_CFG_20_19_MASK 0xffffffff +#define ADDA_ULCF_CFG_20_19_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_22_21 */ +#define ADDA_ULCF_CFG_22_21_SFT 0 +#define ADDA_ULCF_CFG_22_21_MASK 0xffffffff +#define ADDA_ULCF_CFG_22_21_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_24_23 */ +#define ADDA_ULCF_CFG_24_23_SFT 0 +#define ADDA_ULCF_CFG_24_23_MASK 0xffffffff +#define ADDA_ULCF_CFG_24_23_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_26_25 */ +#define ADDA_ULCF_CFG_26_25_SFT 0 +#define ADDA_ULCF_CFG_26_25_MASK 0xffffffff +#define ADDA_ULCF_CFG_26_25_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_28_27 */ +#define ADDA_ULCF_CFG_28_27_SFT 0 +#define ADDA_ULCF_CFG_28_27_MASK 0xffffffff +#define ADDA_ULCF_CFG_28_27_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_30_29 */ +#define ADDA_ULCF_CFG_30_29_SFT 0 +#define ADDA_ULCF_CFG_30_29_MASK 0xffffffff +#define ADDA_ULCF_CFG_30_29_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_ULCF_CFG_32_31 */ +#define ADDA_ULCF_CFG_32_31_SFT 0 +#define ADDA_ULCF_CFG_32_31_MASK 0xffffffff +#define ADDA_ULCF_CFG_32_31_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_IP_VERSION */ +#define ADDA_ULCF_IP_VERSION_SFT 0 +#define ADDA_ULCF_IP_VERSION_MASK 0xffffffff +#define ADDA_ULCF_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_PROXIMITY_CON0 */ +#define PROXIMITY_CH1_ON_SFT 12 +#define PROXIMITY_CH1_ON_MASK 0x1 +#define PROXIMITY_CH1_ON_MASK_SFT (0x1 << 12) +#define PROXIMITY_CH1_SEL_SFT 8 +#define PROXIMITY_CH1_SEL_MASK 0xf +#define PROXIMITY_CH1_SEL_MASK_SFT (0xf << 8) +#define PROXIMITY_CH2_ON_SFT 4 +#define PROXIMITY_CH2_ON_MASK 0x1 +#define PROXIMITY_CH2_ON_MASK_SFT (0x1 << 4) +#define PROXIMITY_CH2_SEL_SFT 0 +#define PROXIMITY_CH2_SEL_MASK 0xf +#define PROXIMITY_CH2_SEL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON0 */ +#define DMIC1_PHASE_FCLK_SEL_SFT 30 +#define DMIC1_PHASE_FCLK_SEL_MASK 0x3 +#define DMIC1_PHASE_FCLK_SEL_MASK_SFT (0x3 << 30) +#define DMIC0_PHASE_FCLK_SEL_SFT 28 +#define DMIC0_PHASE_FCLK_SEL_MASK 0x3 +#define DMIC0_PHASE_FCLK_SEL_MASK_SFT (0x3 << 28) +#define UL3_PHASE_FCLK_SEL_SFT 26 +#define UL3_PHASE_FCLK_SEL_MASK 0x3 +#define UL3_PHASE_FCLK_SEL_MASK_SFT (0x3 << 26) +#define UL2_PHASE_FCLK_SEL_SFT 24 +#define UL2_PHASE_FCLK_SEL_MASK 0x3 +#define UL2_PHASE_FCLK_SEL_MASK_SFT (0x3 << 24) +#define UL1_PHASE_FCLK_SEL_SFT 22 +#define UL1_PHASE_FCLK_SEL_MASK 0x3 +#define UL1_PHASE_FCLK_SEL_MASK_SFT (0x3 << 22) +#define UL0_PHASE_FCLK_SEL_SFT 20 +#define UL0_PHASE_FCLK_SEL_MASK 0x3 +#define UL0_PHASE_FCLK_SEL_MASK_SFT (0x3 << 20) +#define UL_PHASE_SYNC_FCLK_2_ON_SFT 18 +#define UL_PHASE_SYNC_FCLK_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_2_ON_MASK_SFT (0x1 << 18) +#define UL_PHASE_SYNC_FCLK_1_ON_SFT 17 +#define UL_PHASE_SYNC_FCLK_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1_ON_MASK_SFT (0x1 << 17) +#define UL_PHASE_SYNC_FCLK_0_ON_SFT 16 +#define UL_PHASE_SYNC_FCLK_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_0_ON_MASK_SFT (0x1 << 16) +#define DMIC1_PHASE_HCLK_SEL_SFT 14 +#define DMIC1_PHASE_HCLK_SEL_MASK 0x3 +#define DMIC1_PHASE_HCLK_SEL_MASK_SFT (0x3 << 14) +#define DMIC0_PHASE_HCLK_SEL_SFT 12 +#define DMIC0_PHASE_HCLK_SEL_MASK 0x3 +#define DMIC0_PHASE_HCLK_SEL_MASK_SFT (0x3 << 12) +#define UL3_PHASE_HCLK_SEL_SFT 10 +#define UL3_PHASE_HCLK_SEL_MASK 0x3 +#define UL3_PHASE_HCLK_SEL_MASK_SFT (0x3 << 10) +#define UL2_PHASE_HCLK_SEL_SFT 8 +#define UL2_PHASE_HCLK_SEL_MASK 0x3 +#define UL2_PHASE_HCLK_SEL_MASK_SFT (0x3 << 8) +#define UL1_PHASE_HCLK_SEL_SFT 6 +#define UL1_PHASE_HCLK_SEL_MASK 0x3 +#define UL1_PHASE_HCLK_SEL_MASK_SFT (0x3 << 6) +#define UL0_PHASE_HCLK_SEL_SFT 4 +#define UL0_PHASE_HCLK_SEL_MASK 0x3 +#define UL0_PHASE_HCLK_SEL_MASK_SFT (0x3 << 4) +#define UL_PHASE_SYNC_HCLK_2_ON_SFT 2 +#define UL_PHASE_SYNC_HCLK_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_HCLK_1_ON_SFT 1 +#define UL_PHASE_SYNC_HCLK_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_HCLK_0_ON_SFT 0 +#define UL_PHASE_SYNC_HCLK_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON1 */ +#define DMIC_CLK_PHASE_SYNC_SET_SFT 31 +#define DMIC_CLK_PHASE_SYNC_SET_MASK 0x1 +#define DMIC_CLK_PHASE_SYNC_SET_MASK_SFT (0x1 << 31) +#define DMIC1_PHASE_SYNC_FCLK_SET_SFT 11 +#define DMIC1_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define DMIC1_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 11) +#define DMIC1_PHASE_SYNC_HCLK_SET_SFT 10 +#define DMIC1_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define DMIC1_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 10) +#define DMIC0_PHASE_SYNC_FCLK_SET_SFT 9 +#define DMIC0_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define DMIC0_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 9) +#define DMIC0_PHASE_SYNC_HCLK_SET_SFT 8 +#define DMIC0_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define DMIC0_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 8) +#define UL3_PHASE_SYNC_FCLK_SET_SFT 7 +#define UL3_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL3_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 7) +#define UL3_PHASE_SYNC_HCLK_SET_SFT 6 +#define UL3_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL3_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 6) +#define UL2_PHASE_SYNC_FCLK_SET_SFT 5 +#define UL2_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL2_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 5) +#define UL2_PHASE_SYNC_HCLK_SET_SFT 4 +#define UL2_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL2_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 4) +#define UL1_PHASE_SYNC_FCLK_SET_SFT 3 +#define UL1_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL1_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 3) +#define UL1_PHASE_SYNC_HCLK_SET_SFT 2 +#define UL1_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL1_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 2) +#define UL0_PHASE_SYNC_FCLK_SET_SFT 1 +#define UL0_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL0_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 1) +#define UL0_PHASE_SYNC_HCLK_SET_SFT 0 +#define UL0_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL0_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON2 */ +#define DMIC1_PHASE_SYNC_1X_EN_SEL_SFT 26 +#define DMIC1_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define DMIC1_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 26) +#define DMIC0_PHASE_SYNC_1X_EN_SEL_SFT 24 +#define DMIC0_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define DMIC0_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 24) +#define UL3_PHASE_SYNC_1X_EN_SEL_SFT 22 +#define UL3_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL3_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 22) +#define UL2_PHASE_SYNC_1X_EN_SEL_SFT 20 +#define UL2_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL2_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 20) +#define UL1_PHASE_SYNC_1X_EN_SEL_SFT 18 +#define UL1_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL1_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 18) +#define UL0_PHASE_SYNC_1X_EN_SEL_SFT 16 +#define UL0_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL0_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 16) +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_SFT 5 +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_MASK_SFT (0x1 << 5) +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_SFT 4 +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_MASK_SFT (0x1 << 4) +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_SFT 3 +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_MASK_SFT (0x1 << 3) +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_SFT 2 +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_SFT 1 +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_SFT 0 +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON3 */ +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_SFT 26 +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 26) +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_SFT 24 +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 24) +#define UL3_PHASE_SYNC_SOFT_RST_SEL_SFT 22 +#define UL3_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL3_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 22) +#define UL2_PHASE_SYNC_SOFT_RST_SEL_SFT 20 +#define UL2_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL2_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 20) +#define UL1_PHASE_SYNC_SOFT_RST_SEL_SFT 18 +#define UL1_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL1_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 18) +#define UL0_PHASE_SYNC_SOFT_RST_SEL_SFT 16 +#define UL0_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL0_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 16) +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_SFT 13 +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 13) +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_SFT 12 +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 12) +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_SFT 11 +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 11) +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_SFT 10 +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 10) +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_SFT 9 +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 9) +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_SFT 8 +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 8) +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_SFT 5 +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_MASK_SFT (0x1 << 5) +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_SFT 4 +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_MASK_SFT (0x1 << 4) +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_SFT 3 +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_MASK_SFT (0x1 << 3) +#define UL_PHASE_SYNC_SOFT_RST_2_ON_SFT 2 +#define UL_PHASE_SYNC_SOFT_RST_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_SOFT_RST_1_ON_SFT 1 +#define UL_PHASE_SYNC_SOFT_RST_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_SOFT_RST_0_ON_SFT 0 +#define UL_PHASE_SYNC_SOFT_RST_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF_IPM_VER_MON */ +#define RG_MTKAIF_IPM_VER_MON_SFT 0 +#define RG_MTKAIF_IPM_VER_MON_MASK 0xffffffff +#define RG_MTKAIF_IPM_VER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF_MON_SEL */ +#define RG_MTKAIF_MON_SEL_SFT 0 +#define RG_MTKAIF_MON_SEL_MASK 0xff +#define RG_MTKAIF_MON_SEL_MASK_SFT (0xff << 0) + +/* AFE_MTKAIF_MON */ +#define RG_MTKAIF_MON_SFT 0 +#define RG_MTKAIF_MON_MASK 0xffffffff +#define RG_MTKAIF_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF0_CFG0 */ +#define RG_MTKAIF0_RXIF_CLKINV_SFT 31 +#define RG_MTKAIF0_RXIF_CLKINV_MASK 0x1 +#define RG_MTKAIF0_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define RG_MTKAIF0_RXIF_BYPASS_SRC_SFT 17 +#define RG_MTKAIF0_RXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF0_RXIF_BYPASS_SRC_MASK_SFT (0x1 << 17) +#define RG_MTKAIF0_RXIF_PROTOCOL2_SFT 16 +#define RG_MTKAIF0_RXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF0_RXIF_PROTOCOL2_MASK_SFT (0x1 << 16) +#define RG_MTKAIF0_TXIF_NLE_DEBUG_SFT 8 +#define RG_MTKAIF0_TXIF_NLE_DEBUG_MASK 0x1 +#define RG_MTKAIF0_TXIF_NLE_DEBUG_MASK_SFT (0x1 << 8) +#define RG_MTKAIF0_TXIF_BYPASS_SRC_SFT 5 +#define RG_MTKAIF0_TXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF0_TXIF_BYPASS_SRC_MASK_SFT (0x1 << 5) +#define RG_MTKAIF0_TXIF_PROTOCOL2_SFT 4 +#define RG_MTKAIF0_TXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF0_TXIF_PROTOCOL2_MASK_SFT (0x1 << 4) +#define RG_MTKAIF0_TXIF_8TO5_SFT 2 +#define RG_MTKAIF0_TXIF_8TO5_MASK 0x1 +#define RG_MTKAIF0_TXIF_8TO5_MASK_SFT (0x1 << 2) +#define RG_MTKAIF0_RXIF_8TO5_SFT 1 +#define RG_MTKAIF0_RXIF_8TO5_MASK 0x1 +#define RG_MTKAIF0_RXIF_8TO5_MASK_SFT (0x1 << 1) +#define RG_MTKAIF0_TX2RX_LOOPBACK1_SFT 0 +#define RG_MTKAIF0_TX2RX_LOOPBACK1_MASK 0x1 +#define RG_MTKAIF0_TX2RX_LOOPBACK1_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF0_TX_CFG0 */ +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_SFT 23 +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_MASK_SFT (0x1 << 23) +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_SFT 20 +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_MASK_SFT (0x7 << 20) +#define RG_MTKAIF0_TXIF_FIFO_SWAP_SFT 15 +#define RG_MTKAIF0_TXIF_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF0_TXIF_FIFO_SWAP_MASK_SFT (0x1 << 15) +#define RG_MTKAIF0_TXIF_FIFO_RSP_SFT 12 +#define RG_MTKAIF0_TXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_TXIF_FIFO_RSP_MASK_SFT (0x7 << 12) +#define RG_MTKAIF0_TXIF_SYNC_WORD1_SFT 4 +#define RG_MTKAIF0_TXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF0_TXIF_SYNC_WORD1_MASK_SFT (0x7 << 4) +#define RG_MTKAIF0_TXIF_SYNC_WORD0_SFT 0 +#define RG_MTKAIF0_TXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF0_TXIF_SYNC_WORD0_MASK_SFT (0x7 << 0) + +/* AFE_MTKAIF0_RX_CFG0 */ +#define RG_MTKAIF0_RXIF_VOICE_MODE_SFT 20 +#define RG_MTKAIF0_RXIF_VOICE_MODE_MASK 0xf +#define RG_MTKAIF0_RXIF_VOICE_MODE_MASK_SFT (0xf << 20) +#define RG_MTKAIF0_RXIF_DETECT_ON_SFT 16 +#define RG_MTKAIF0_RXIF_DETECT_ON_MASK 0x1 +#define RG_MTKAIF0_RXIF_DETECT_ON_MASK_SFT (0x1 << 16) +#define RG_MTKAIF0_RXIF_DATA_BIT_SFT 8 +#define RG_MTKAIF0_RXIF_DATA_BIT_MASK 0x7 +#define RG_MTKAIF0_RXIF_DATA_BIT_MASK_SFT (0x7 << 8) +#define RG_MTKAIF0_RXIF_FIFO_RSP_SFT 4 +#define RG_MTKAIF0_RXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_RXIF_FIFO_RSP_MASK_SFT (0x7 << 4) +#define RG_MTKAIF0_RXIF_DATA_MODE_SFT 0 +#define RG_MTKAIF0_RXIF_DATA_MODE_MASK 0x1 +#define RG_MTKAIF0_RXIF_DATA_MODE_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF0_RX_CFG1 */ +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_SFT 28 +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_MASK 0x1 +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_MASK_SFT (0x1 << 28) +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_SFT 16 +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 16) +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_MASK 0xf +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_SFT 8 +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) + +/* AFE_MTKAIF0_RX_CFG2 */ +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_SFT 27 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_MASK 0x1 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_MASK_SFT (0x1 << 27) +#define RG_MTKAIF0_RXIF_SYNC_WORD1_SFT 24 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_MASK_SFT (0x7 << 24) +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_SFT 23 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_MASK 0x1 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_MASK_SFT (0x1 << 23) +#define RG_MTKAIF0_RXIF_SYNC_WORD0_SFT 20 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_MASK_SFT (0x7 << 20) +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_SFT 12 +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK 0xf +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF0_RXIF_DELAY_DATA_SFT 8 +#define RG_MTKAIF0_RXIF_DELAY_DATA_MASK 0x1 +#define RG_MTKAIF0_RXIF_DELAY_DATA_MASK_SFT (0x1 << 8) + +/* AFE_MTKAIF1_CFG0 */ +#define RG_MTKAIF1_RXIF_CLKINV_ADC_SFT 31 +#define RG_MTKAIF1_RXIF_CLKINV_ADC_MASK 0x1 +#define RG_MTKAIF1_RXIF_CLKINV_ADC_MASK_SFT (0x1 << 31) +#define RG_MTKAIF1_RXIF_BYPASS_SRC_SFT 17 +#define RG_MTKAIF1_RXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF1_RXIF_BYPASS_SRC_MASK_SFT (0x1 << 17) +#define RG_MTKAIF1_RXIF_PROTOCOL2_SFT 16 +#define RG_MTKAIF1_RXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF1_RXIF_PROTOCOL2_MASK_SFT (0x1 << 16) +#define RG_MTKAIF1_TXIF_NLE_DEBUG_SFT 8 +#define RG_MTKAIF1_TXIF_NLE_DEBUG_MASK 0x1 +#define RG_MTKAIF1_TXIF_NLE_DEBUG_MASK_SFT (0x1 << 8) +#define RG_MTKAIF1_TXIF_BYPASS_SRC_SFT 5 +#define RG_MTKAIF1_TXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF1_TXIF_BYPASS_SRC_MASK_SFT (0x1 << 5) +#define RG_MTKAIF1_TXIF_PROTOCOL2_SFT 4 +#define RG_MTKAIF1_TXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF1_TXIF_PROTOCOL2_MASK_SFT (0x1 << 4) +#define RG_MTKAIF1_TXIF_8TO5_SFT 2 +#define RG_MTKAIF1_TXIF_8TO5_MASK 0x1 +#define RG_MTKAIF1_TXIF_8TO5_MASK_SFT (0x1 << 2) +#define RG_MTKAIF1_RXIF_8TO5_SFT 1 +#define RG_MTKAIF1_RXIF_8TO5_MASK 0x1 +#define RG_MTKAIF1_RXIF_8TO5_MASK_SFT (0x1 << 1) +#define RG_MTKAIF1_IF_LOOPBACK1_SFT 0 +#define RG_MTKAIF1_IF_LOOPBACK1_MASK 0x1 +#define RG_MTKAIF1_IF_LOOPBACK1_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF1_TX_CFG0 */ +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_SFT 23 +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_MASK_SFT (0x1 << 23) +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_SFT 20 +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_MASK_SFT (0x7 << 20) +#define RG_MTKAIF1_TXIF_FIFO_SWAP_SFT 15 +#define RG_MTKAIF1_TXIF_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF1_TXIF_FIFO_SWAP_MASK_SFT (0x1 << 15) +#define RG_MTKAIF1_TXIF_FIFO_RSP_SFT 12 +#define RG_MTKAIF1_TXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_TXIF_FIFO_RSP_MASK_SFT (0x7 << 12) +#define RG_MTKAIF1_TXIF_SYNC_WORD1_SFT 4 +#define RG_MTKAIF1_TXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF1_TXIF_SYNC_WORD1_MASK_SFT (0x7 << 4) +#define RG_MTKAIF1_TXIF_SYNC_WORD0_SFT 0 +#define RG_MTKAIF1_TXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF1_TXIF_SYNC_WORD0_MASK_SFT (0x7 << 0) + +/* AFE_MTKAIF1_RX_CFG0 */ +#define RG_MTKAIF1_RXIF_VOICE_MODE_SFT 20 +#define RG_MTKAIF1_RXIF_VOICE_MODE_MASK 0xf +#define RG_MTKAIF1_RXIF_VOICE_MODE_MASK_SFT (0xf << 20) +#define RG_MTKAIF1_RXIF_DETECT_ON_SFT 16 +#define RG_MTKAIF1_RXIF_DETECT_ON_MASK 0x1 +#define RG_MTKAIF1_RXIF_DETECT_ON_MASK_SFT (0x1 << 16) +#define RG_MTKAIF1_RXIF_DATA_BIT_SFT 8 +#define RG_MTKAIF1_RXIF_DATA_BIT_MASK 0x7 +#define RG_MTKAIF1_RXIF_DATA_BIT_MASK_SFT (0x7 << 8) +#define RG_MTKAIF1_RXIF_FIFO_RSP_SFT 4 +#define RG_MTKAIF1_RXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_RXIF_FIFO_RSP_MASK_SFT (0x7 << 4) +#define RG_MTKAIF1_RXIF_DATA_MODE_SFT 0 +#define RG_MTKAIF1_RXIF_DATA_MODE_MASK 0x1 +#define RG_MTKAIF1_RXIF_DATA_MODE_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF1_RX_CFG1 */ +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_SFT 28 +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_MASK 0x1 +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_MASK_SFT (0x1 << 28) +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_SFT 16 +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 16) +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_MASK 0xf +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_SFT 8 +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) + +/* AFE_MTKAIF1_RX_CFG2 */ +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_SFT 27 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK 0x1 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK_SFT (0x1 << 27) +#define RG_MTKAIF1_RXIF_SYNC_WORD1_SFT 24 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_MASK_SFT (0x7 << 24) +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_SFT 23 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_MASK 0x1 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_MASK_SFT (0x1 << 23) +#define RG_MTKAIF1_RXIF_SYNC_WORD0_SFT 20 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_MASK_SFT (0x7 << 20) +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_SFT 12 +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK 0xf +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF1_RXIF_DELAY_DATA_SFT 8 +#define RG_MTKAIF1_RXIF_DELAY_DATA_MASK 0x1 +#define RG_MTKAIF1_RXIF_DELAY_DATA_MASK_SFT (0x1 << 8) + +/* AFE_AUD_PAD_TOP_CFG0 */ +#define AUD_PAD_TOP_FIFO_RSP_SFT 4 +#define AUD_PAD_TOP_FIFO_RSP_MASK 0xf +#define AUD_PAD_TOP_FIFO_RSP_MASK_SFT (0xf << 4) +#define RG_RX_PROTOCOL2_SFT 3 +#define RG_RX_PROTOCOL2_MASK 0x1 +#define RG_RX_PROTOCOL2_MASK_SFT (0x1 << 3) +#define RG_RX_FIFO_ON_SFT 0 +#define RG_RX_FIFO_ON_MASK 0x1 +#define RG_RX_FIFO_ON_MASK_SFT (0x1 << 0) + +/* AFE_AUD_PAD_TOP_MON */ +#define AUD_PAD_TOP_MON_SFT 0 +#define AUD_PAD_TOP_MON_MASK 0xffff +#define AUD_PAD_TOP_MON_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_TX_CFG0 */ +#define MTKAIFV4_TXIF_EN_SEL_SFT 12 +#define MTKAIFV4_TXIF_EN_SEL_MASK 0x1 +#define MTKAIFV4_TXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define MTKAIFV4_TXIF_V4_SFT 11 +#define MTKAIFV4_TXIF_V4_MASK 0x1 +#define MTKAIFV4_TXIF_V4_MASK_SFT (0x1 << 11) +#define MTKAIFV4_ADDA6_OUT_EN_SEL_SFT 10 +#define MTKAIFV4_ADDA6_OUT_EN_SEL_MASK 0x1 +#define MTKAIFV4_ADDA6_OUT_EN_SEL_MASK_SFT (0x1 << 10) +#define MTKAIFV4_ADDA_OUT_EN_SEL_SFT 9 +#define MTKAIFV4_ADDA_OUT_EN_SEL_MASK 0x1 +#define MTKAIFV4_ADDA_OUT_EN_SEL_MASK_SFT (0x1 << 9) +#define MTKAIFV4_TXIF_INPUT_MODE_SFT 4 +#define MTKAIFV4_TXIF_INPUT_MODE_MASK 0x1f +#define MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define MTKAIFV4_TXIF_FOUR_CHANNEL_SFT 1 +#define MTKAIFV4_TXIF_FOUR_CHANNEL_MASK 0x1 +#define MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define MTKAIFV4_TXIF_AFE_ON_SFT 0 +#define MTKAIFV4_TXIF_AFE_ON_MASK 0x1 +#define MTKAIFV4_TXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_TX_CFG0 */ +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_SFT 12 +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_SFT 4 +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_MASK 0x1f +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_SFT 1 +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_SFT 0 +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_RX_CFG0 */ +#define MTKAIFV4_RXIF_CLKINV_SFT 31 +#define MTKAIFV4_RXIF_CLKINV_MASK 0x1 +#define MTKAIFV4_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define MTKAIFV4_RXIF_LOOPBACK_MODE_SFT 28 +#define MTKAIFV4_RXIF_LOOPBACK_MODE_MASK 0x1 +#define MTKAIFV4_RXIF_LOOPBACK_MODE_MASK_SFT (0x1 << 28) +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_SFT 19 +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_MASK_SFT (0x1 << 19) +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_SFT 18 +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_MASK_SFT (0x1 << 18) +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_SFT 17 +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK_SFT (0x1 << 17) +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_SFT 16 +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK_SFT (0x1 << 16) +#define MTKAIFV4_RXIF_EN_SEL_SFT 12 +#define MTKAIFV4_RXIF_EN_SEL_MASK 0x1 +#define MTKAIFV4_RXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define MTKAIFV4_RXIF_INPUT_MODE_SFT 4 +#define MTKAIFV4_RXIF_INPUT_MODE_MASK 0x1f +#define MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define MTKAIFV4_RXIF_FOUR_CHANNEL_SFT 1 +#define MTKAIFV4_RXIF_FOUR_CHANNEL_MASK 0x1 +#define MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define MTKAIFV4_RXIF_AFE_ON_SFT 0 +#define MTKAIFV4_RXIF_AFE_ON_MASK 0x1 +#define MTKAIFV4_RXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_RX_CFG1 */ +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_SFT 17 +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 17) +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK 0x1f +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0x1f << 12) +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_SFT 8 +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK 0xf +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) +#define MTKAIFV4_RXIF_FIFO_RSP_SFT 1 +#define MTKAIFV4_RXIF_FIFO_RSP_MASK 0x7 +#define MTKAIFV4_RXIF_FIFO_RSP_MASK_SFT (0x7 << 1) +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_SFT 0 +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK 0x1 +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_RX_CFG0 */ +#define ADDA6_MTKAIFV4_RXIF_CLKINV_SFT 31 +#define ADDA6_MTKAIFV4_RXIF_CLKINV_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_SFT 28 +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_MASK_SFT (0x1 << 28) +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_SFT 12 +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_SFT 4 +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK 0x1f +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_SFT 1 +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_SFT 0 +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_RX_CFG1 */ +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_SFT 17 +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 17) +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK 0x1f +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0x1f << 12) +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_SFT 8 +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK 0xf +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_SFT 1 +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_MASK 0x7 +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_MASK_SFT (0x7 << 1) +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_SFT 0 +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_TX_SYNCWORD_CFG */ +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_SFT 16 +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_MASK 0xffff +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_MASK_SFT (0xffff << 16) +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_SFT 0 +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_MASK 0xffff +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_RX_SYNCWORD_CFG */ +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_SFT 16 +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_MASK 0xffff +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_MASK_SFT (0xffff << 16) +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_SFT 0 +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_MASK 0xffff +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_MON0 */ +#define MTKAIFV4_TXIF_SDATA_OUT_SFT 23 +#define MTKAIFV4_TXIF_SDATA_OUT_MASK 0x1 +#define MTKAIFV4_TXIF_SDATA_OUT_MASK_SFT (0x1 << 23) +#define MTKAIFV4_RXIF_SDATA_IN_SFT 22 +#define MTKAIFV4_RXIF_SDATA_IN_MASK 0x1 +#define MTKAIFV4_RXIF_SDATA_IN_MASK_SFT (0x1 << 22) +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_SFT 21 +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK 0x1 +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK_SFT (0x1 << 21) +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_SFT 0 +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_MASK 0xfff +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_MTKAIFV4_MON1 */ +#define MTKAIFV4_RXIF_OUT_CH4_SFT 24 +#define MTKAIFV4_RXIF_OUT_CH4_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH4_MASK_SFT (0xff << 24) +#define MTKAIFV4_RXIF_OUT_CH3_SFT 16 +#define MTKAIFV4_RXIF_OUT_CH3_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH3_MASK_SFT (0xff << 16) +#define MTKAIFV4_RXIF_OUT_CH2_SFT 8 +#define MTKAIFV4_RXIF_OUT_CH2_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH2_MASK_SFT (0xff << 8) +#define MTKAIFV4_RXIF_OUT_CH1_SFT 0 +#define MTKAIFV4_RXIF_OUT_CH1_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH1_MASK_SFT (0xff << 0) + +/* AFE_ADDA6_MTKAIFV4_MON0 */ +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_SFT 23 +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_MASK_SFT (0x1 << 23) +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_SFT 22 +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_MASK_SFT (0x1 << 22) +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_SFT 21 +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK_SFT (0x1 << 21) +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_SFT 0 +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_MASK 0xfff +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_MASK_SFT (0xfff << 0) + +/* ETDM_IN0_CON0 */ +#define REG_ETDM_IN_EN_SFT 0 +#define REG_ETDM_IN_EN_MASK 0x1 +#define REG_ETDM_IN_EN_MASK_SFT (0x1 << 0) +#define REG_SYNC_MODE_SFT 1 +#define REG_SYNC_MODE_MASK 0x1 +#define REG_SYNC_MODE_MASK_SFT (0x1 << 1) +#define REG_LSB_FIRST_SFT 3 +#define REG_LSB_FIRST_MASK 0x1 +#define REG_LSB_FIRST_MASK_SFT (0x1 << 3) +#define REG_SOFT_RST_SFT 4 +#define REG_SOFT_RST_MASK 0x1 +#define REG_SOFT_RST_MASK_SFT (0x1 << 4) +#define REG_SLAVE_MODE_SFT 5 +#define REG_SLAVE_MODE_MASK 0x1 +#define REG_SLAVE_MODE_MASK_SFT (0x1 << 5) +#define REG_FMT_SFT 6 +#define REG_FMT_MASK 0x7 +#define REG_FMT_MASK_SFT (0x7 << 6) +#define REG_LRCK_EDGE_SEL_SFT 10 +#define REG_LRCK_EDGE_SEL_MASK 0x1 +#define REG_LRCK_EDGE_SEL_MASK_SFT (0x1 << 10) +#define REG_BIT_LENGTH_SFT 11 +#define REG_BIT_LENGTH_MASK 0x1f +#define REG_BIT_LENGTH_MASK_SFT (0x1f << 11) +#define REG_WORD_LENGTH_SFT 16 +#define REG_WORD_LENGTH_MASK 0x1f +#define REG_WORD_LENGTH_MASK_SFT (0x1f << 16) +#define REG_CH_NUM_SFT 23 +#define REG_CH_NUM_MASK 0x1f +#define REG_CH_NUM_MASK_SFT (0x1f << 23) +#define REG_RELATCH_1X_EN_DOMAIN_SEL_SFT 28 +#define REG_RELATCH_1X_EN_DOMAIN_SEL_MASK 0x7 +#define REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT (0x7 << 28) +#define REG_VALID_TOGETHER_SFT 31 +#define REG_VALID_TOGETHER_MASK 0x1 +#define REG_VALID_TOGETHER_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON1 */ +/* ETDM_IN1_CON1 */ +/* ETDM_IN2_CON1 */ +/* ETDM_IN3_CON1 */ +/* ETDM_IN4_CON1 */ +/* ETDM_IN5_CON1 */ +/* ETDM_IN6_CON1 */ +#define REG_INITIAL_COUNT_SFT 0 +#define REG_INITIAL_COUNT_MASK 0x1f +#define REG_INITIAL_COUNT_MASK_SFT (0x1f << 0) +#define REG_INITIAL_POINT_SFT 5 +#define REG_INITIAL_POINT_MASK 0x1f +#define REG_INITIAL_POINT_MASK_SFT (0x1f << 5) +#define REG_LRCK_AUTO_OFF_SFT 10 +#define REG_LRCK_AUTO_OFF_MASK 0x1 +#define REG_LRCK_AUTO_OFF_MASK_SFT (0x1 << 10) +#define REG_BCK_AUTO_OFF_SFT 11 +#define REG_BCK_AUTO_OFF_MASK 0x1 +#define REG_BCK_AUTO_OFF_MASK_SFT (0x1 << 11) +#define REG_INITIAL_LRCK_SFT 13 +#define REG_INITIAL_LRCK_MASK 0x1 +#define REG_INITIAL_LRCK_MASK_SFT (0x1 << 13) +#define REG_NO_ALIGN_1X_EN_SFT 14 +#define REG_NO_ALIGN_1X_EN_MASK 0x1 +#define REG_NO_ALIGN_1X_EN_MASK_SFT (0x1 << 14) +#define REG_LRCK_RESET_SFT 15 +#define REG_LRCK_RESET_MASK 0x1 +#define REG_LRCK_RESET_MASK_SFT (0x1 << 15) +#define PINMUX_MCLK_CTRL_OE_SFT 16 +#define PINMUX_MCLK_CTRL_OE_MASK 0x1 +#define PINMUX_MCLK_CTRL_OE_MASK_SFT (0x1 << 16) +#define REG_OUTPUT_CR_EN_SFT 18 +#define REG_OUTPUT_CR_EN_MASK 0x1 +#define REG_OUTPUT_CR_EN_MASK_SFT (0x1 << 18) +#define REG_LR_ALIGN_SFT 19 +#define REG_LR_ALIGN_MASK 0x1 +#define REG_LR_ALIGN_MASK_SFT (0x1 << 19) +#define REG_LRCK_WIDTH_SFT 20 +#define REG_LRCK_WIDTH_MASK 0x3ff +#define REG_LRCK_WIDTH_MASK_SFT (0x3ff << 20) +#define REG_DIRECT_INPUT_MASTER_BCK_SFT 30 +#define REG_DIRECT_INPUT_MASTER_BCK_MASK 0x1 +#define REG_DIRECT_INPUT_MASTER_BCK_MASK_SFT (0x1 << 30) +#define REG_LRCK_AUTO_MODE_SFT 31 +#define REG_LRCK_AUTO_MODE_MASK 0x1 +#define REG_LRCK_AUTO_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON2 */ +/* ETDM_IN1_CON2 */ +/* ETDM_IN2_CON2 */ +/* ETDM_IN3_CON2 */ +/* ETDM_IN4_CON2 */ +/* ETDM_IN5_CON2 */ +/* ETDM_IN6_CON2 */ +#define REG_UPDATE_POINT_SFT 0 +#define REG_UPDATE_POINT_MASK 0x1f +#define REG_UPDATE_POINT_MASK_SFT (0x1f << 0) +#define REG_UPDATE_GAP_SFT 5 +#define REG_UPDATE_GAP_MASK 0x1f +#define REG_UPDATE_GAP_MASK_SFT (0x1f << 5) +#define REG_CLOCK_SOURCE_SEL_SFT 10 +#define REG_CLOCK_SOURCE_SEL_MASK 0x7 +#define REG_CLOCK_SOURCE_SEL_MASK_SFT (0x7 << 10) +#define REG_CK_EN_SEL_AUTO_SFT 14 +#define REG_CK_EN_SEL_AUTO_MASK 0x1 +#define REG_CK_EN_SEL_AUTO_MASK_SFT (0x1 << 14) +#define REG_MULTI_IP_TOTAL_CHNUM_SFT 15 +#define REG_MULTI_IP_TOTAL_CHNUM_MASK 0x1f +#define REG_MULTI_IP_TOTAL_CHNUM_MASK_SFT (0x1f << 15) +#define REG_MASK_AUTO_SFT 20 +#define REG_MASK_AUTO_MASK 0x1 +#define REG_MASK_AUTO_MASK_SFT (0x1 << 20) +#define REG_MASK_NUM_SFT 21 +#define REG_MASK_NUM_MASK 0x1f +#define REG_MASK_NUM_MASK_SFT (0x1f << 21) +#define REG_UPDATE_POINT_AUTO_SFT 26 +#define REG_UPDATE_POINT_AUTO_MASK 0x1 +#define REG_UPDATE_POINT_AUTO_MASK_SFT (0x1 << 26) +#define REG_SDATA_DELAY_0P5T_EN_SFT 27 +#define REG_SDATA_DELAY_0P5T_EN_MASK 0x1 +#define REG_SDATA_DELAY_0P5T_EN_MASK_SFT (0x1 << 27) +#define REG_SDATA_DELAY_BCK_INV_SFT 28 +#define REG_SDATA_DELAY_BCK_INV_MASK 0x1 +#define REG_SDATA_DELAY_BCK_INV_MASK_SFT (0x1 << 28) +#define REG_LRCK_DELAY_0P5T_EN_SFT 29 +#define REG_LRCK_DELAY_0P5T_EN_MASK 0x1 +#define REG_LRCK_DELAY_0P5T_EN_MASK_SFT (0x1 << 29) +#define REG_LRCK_DELAY_BCK_INV_SFT 30 +#define REG_LRCK_DELAY_BCK_INV_MASK 0x1 +#define REG_LRCK_DELAY_BCK_INV_MASK_SFT (0x1 << 30) +#define REG_MULTI_IP_MODE_SFT 31 +#define REG_MULTI_IP_MODE_MASK 0x1 +#define REG_MULTI_IP_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON3 */ +/* ETDM_IN1_CON3 */ +/* ETDM_IN2_CON3 */ +/* ETDM_IN3_CON3 */ +/* ETDM_IN4_CON3 */ +/* ETDM_IN5_CON3 */ +/* ETDM_IN6_CON3 */ +#define REG_DISABLE_OUT_SFT 0 +#define REG_DISABLE_OUT_MASK 0xffff +#define REG_DISABLE_OUT_MASK_SFT (0xffff << 0) +#define REG_RJ_DATA_RIGHT_ALIGN_SFT 16 +#define REG_RJ_DATA_RIGHT_ALIGN_MASK 0x1 +#define REG_RJ_DATA_RIGHT_ALIGN_MASK_SFT (0x1 << 16) +#define REG_MONITOR_SEL_SFT 17 +#define REG_MONITOR_SEL_MASK 0x3 +#define REG_MONITOR_SEL_MASK_SFT (0x3 << 17) +#define REG_CNT_UPPER_LIMIT_SFT 19 +#define REG_CNT_UPPER_LIMIT_MASK 0x3f +#define REG_CNT_UPPER_LIMIT_MASK_SFT (0x3f << 19) +#define REG_COMPACT_SAMPLE_END_DIS_SFT 25 +#define REG_COMPACT_SAMPLE_END_DIS_MASK 0x1 +#define REG_COMPACT_SAMPLE_END_DIS_MASK_SFT (0x1 << 25) +#define REG_FS_TIMING_SEL_SFT 26 +#define REG_FS_TIMING_SEL_MASK 0x1f +#define REG_FS_TIMING_SEL_MASK_SFT (0x1f << 26) +#define REG_SAMPLE_END_MODE_SFT 31 +#define REG_SAMPLE_END_MODE_MASK 0x1 +#define REG_SAMPLE_END_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON4 */ +/* ETDM_IN1_CON4 */ +/* ETDM_IN2_CON4 */ +/* ETDM_IN3_CON4 */ +/* ETDM_IN4_CON4 */ +/* ETDM_IN5_CON4 */ +/* ETDM_IN6_CON4 */ +#define REG_ALWAYS_OPEN_1X_EN_SFT 31 +#define REG_ALWAYS_OPEN_1X_EN_MASK 0x1 +#define REG_ALWAYS_OPEN_1X_EN_MASK_SFT (0x1 << 31) +#define REG_WAIT_LAST_SAMPLE_SFT 30 +#define REG_WAIT_LAST_SAMPLE_MASK 0x1 +#define REG_WAIT_LAST_SAMPLE_MASK_SFT (0x1 << 30) +#define REG_SAMPLE_END_POINT_SFT 25 +#define REG_SAMPLE_END_POINT_MASK 0x1f +#define REG_SAMPLE_END_POINT_MASK_SFT (0x1f << 25) +#define REG_RELATCH_1X_EN_SEL_SFT 20 +#define REG_RELATCH_1X_EN_SEL_MASK 0x1f +#define REG_RELATCH_1X_EN_SEL_MASK_SFT (0x1f << 20) +#define REG_MASTER_WS_INV_SFT 19 +#define REG_MASTER_WS_INV_MASK 0x1 +#define REG_MASTER_WS_INV_MASK_SFT (0x1 << 19) +#define REG_MASTER_BCK_INV_SFT 18 +#define REG_MASTER_BCK_INV_MASK 0x1 +#define REG_MASTER_BCK_INV_MASK_SFT (0x1 << 18) +#define REG_SLAVE_LRCK_INV_SFT 17 +#define REG_SLAVE_LRCK_INV_MASK 0x1 +#define REG_SLAVE_LRCK_INV_MASK_SFT (0x1 << 17) +#define REG_SLAVE_BCK_INV_SFT 16 +#define REG_SLAVE_BCK_INV_MASK 0x1 +#define REG_SLAVE_BCK_INV_MASK_SFT (0x1 << 16) +#define REG_REPACK_CHNUM_SFT 12 +#define REG_REPACK_CHNUM_MASK 0xf +#define REG_REPACK_CHNUM_MASK_SFT (0xf << 12) +#define REG_ASYNC_RESET_SFT 11 +#define REG_ASYNC_RESET_MASK 0x1 +#define REG_ASYNC_RESET_MASK_SFT (0x1 << 11) +#define REG_REPACK_WORD_LENGTH_SFT 9 +#define REG_REPACK_WORD_LENGTH_MASK 0x3 +#define REG_REPACK_WORD_LENGTH_MASK_SFT (0x3 << 9) +#define REG_REPACK_AUTO_MODE_SFT 8 +#define REG_REPACK_AUTO_MODE_MASK 0x1 +#define REG_REPACK_AUTO_MODE_MASK_SFT (0x1 << 8) +#define REG_REPACK_MODE_SFT 0 +#define REG_REPACK_MODE_MASK 0x3f +#define REG_REPACK_MODE_MASK_SFT (0x3f << 0) + +/* ETDM_IN0_CON5 */ +/* ETDM_IN1_CON5 */ +/* ETDM_IN2_CON5 */ +/* ETDM_IN3_CON5 */ +/* ETDM_IN4_CON5 */ +/* ETDM_IN5_CON5 */ +/* ETDM_IN6_CON5 */ +#define REG_LR_SWAP_SFT 16 +#define REG_LR_SWAP_MASK 0xffff +#define REG_LR_SWAP_MASK_SFT (0xffff << 16) +#define REG_ODD_FLAG_EN_SFT 0 +#define REG_ODD_FLAG_EN_MASK 0xffff +#define REG_ODD_FLAG_EN_MASK_SFT (0xffff << 0) + +/* ETDM_IN0_CON6 */ +/* ETDM_IN1_CON6 */ +/* ETDM_IN2_CON6 */ +/* ETDM_IN3_CON6 */ +/* ETDM_IN4_CON6 */ +/* ETDM_IN5_CON6 */ +/* ETDM_IN6_CON6 */ +#define LCH_DATA_REG_SFT 0 +#define LCH_DATA_REG_MASK 0xffffffff +#define LCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_IN0_CON7 */ +/* ETDM_IN1_CON7 */ +/* ETDM_IN2_CON7 */ +/* ETDM_IN3_CON7 */ +/* ETDM_IN4_CON7 */ +/* ETDM_IN5_CON7 */ +/* ETDM_IN6_CON7 */ +#define RCH_DATA_REG_SFT 0 +#define RCH_DATA_REG_MASK 0xffffffff +#define RCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_IN0_CON8 */ +/* ETDM_IN1_CON8 */ +/* ETDM_IN2_CON8 */ +/* ETDM_IN3_CON8 */ +/* ETDM_IN4_CON8 */ +/* ETDM_IN5_CON8 */ +/* ETDM_IN6_CON8 */ +#define REG_AFIFO_THRESHOLD_SFT 29 +#define REG_AFIFO_THRESHOLD_MASK 0x3 +#define REG_AFIFO_THRESHOLD_MASK_SFT (0x3 << 29) +#define REG_CK_EN_SEL_MANUAL_SFT 16 +#define REG_CK_EN_SEL_MANUAL_MASK 0x3ff +#define REG_CK_EN_SEL_MANUAL_MASK_SFT (0x3ff << 16) +#define REG_AFIFO_SW_RESET_SFT 15 +#define REG_AFIFO_SW_RESET_MASK 0x1 +#define REG_AFIFO_SW_RESET_MASK_SFT (0x1 << 15) +#define REG_AFIFO_RESET_SEL_SFT 14 +#define REG_AFIFO_RESET_SEL_MASK 0x1 +#define REG_AFIFO_RESET_SEL_MASK_SFT (0x1 << 14) +#define REG_AFIFO_AUTO_RESET_DIS_SFT 9 +#define REG_AFIFO_AUTO_RESET_DIS_MASK 0x1 +#define REG_AFIFO_AUTO_RESET_DIS_MASK_SFT (0x1 << 9) +#define REG_ETDM_USE_AFIFO_SFT 8 +#define REG_ETDM_USE_AFIFO_MASK 0x1 +#define REG_ETDM_USE_AFIFO_MASK_SFT (0x1 << 8) +#define REG_AFIFO_CLOCK_DOMAIN_SEL_SFT 5 +#define REG_AFIFO_CLOCK_DOMAIN_SEL_MASK 0x7 +#define REG_AFIFO_CLOCK_DOMAIN_SEL_MASK_SFT (0x7 << 5) +#define REG_AFIFO_MODE_SFT 0 +#define REG_AFIFO_MODE_MASK 0x1f +#define REG_AFIFO_MODE_MASK_SFT (0x1f << 0) + +/* ETDM_IN0_CON9 */ +/* ETDM_IN1_CON9 */ +/* ETDM_IN2_CON9 */ +/* ETDM_IN3_CON9 */ +/* ETDM_IN4_CON9 */ +/* ETDM_IN5_CON9 */ +/* ETDM_IN6_CON9 */ +#define REG_OUT2LATCH_TIME_SFT 10 +#define REG_OUT2LATCH_TIME_MASK 0x1f +#define REG_OUT2LATCH_TIME_MASK_SFT (0x1f << 10) +#define REG_ALMOST_END_BIT_COUNT_SFT 5 +#define REG_ALMOST_END_BIT_COUNT_MASK 0x1f +#define REG_ALMOST_END_BIT_COUNT_MASK_SFT (0x1f << 5) +#define REG_ALMOST_END_CH_COUNT_SFT 0 +#define REG_ALMOST_END_CH_COUNT_MASK 0x1f +#define REG_ALMOST_END_CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_IN0_MON */ +/* ETDM_IN1_MON */ +/* ETDM_IN2_MON */ +/* ETDM_IN3_MON */ +/* ETDM_IN4_MON */ +/* ETDM_IN5_MON */ +/* ETDM_IN6_MON */ +#define LRCK_INV_SFT 30 +#define LRCK_INV_MASK 0x1 +#define LRCK_INV_MASK_SFT (0x1 << 30) +#define EN_SYNC_OUT_SFT 29 +#define EN_SYNC_OUT_MASK 0x1 +#define EN_SYNC_OUT_MASK_SFT (0x1 << 29) +#define HOPPING_EN_SYNC_OUT_PRE_SFT 28 +#define HOPPING_EN_SYNC_OUT_PRE_MASK 0x1 +#define HOPPING_EN_SYNC_OUT_PRE_MASK_SFT (0x1 << 28) +#define WFULL_SFT 27 +#define WFULL_MASK 0x1 +#define WFULL_MASK_SFT (0x1 << 27) +#define REMPTY_SFT 26 +#define REMPTY_MASK 0x1 +#define REMPTY_MASK_SFT (0x1 << 26) +#define ETDM_2X_CK_EN_SFT 25 +#define ETDM_2X_CK_EN_MASK 0x1 +#define ETDM_2X_CK_EN_MASK_SFT (0x1 << 25) +#define ETDM_1X_CK_EN_SFT 24 +#define ETDM_1X_CK_EN_MASK 0x1 +#define ETDM_1X_CK_EN_MASK_SFT (0x1 << 24) +#define SDATA0_SFT 23 +#define SDATA0_MASK 0x1 +#define SDATA0_MASK_SFT (0x1 << 23) +#define CURRENT_STATUS_SFT 21 +#define CURRENT_STATUS_MASK 0x3 +#define CURRENT_STATUS_MASK_SFT (0x3 << 21) +#define BIT_POINT_SFT 16 +#define BIT_POINT_MASK 0x1f +#define BIT_POINT_MASK_SFT (0x1f << 16) +#define BIT_CH_COUNT_SFT 10 +#define BIT_CH_COUNT_MASK 0x3f +#define BIT_CH_COUNT_MASK_SFT (0x3f << 10) +#define BIT_COUNT_SFT 5 +#define BIT_COUNT_MASK 0x1f +#define BIT_COUNT_MASK_SFT (0x1f << 5) +#define CH_COUNT_SFT 0 +#define CH_COUNT_MASK 0x1f +#define CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_OUT0_CON0 */ +/* ETDM_OUT1_CON0 */ +/* ETDM_OUT2_CON0 */ +/* ETDM_OUT3_CON0 */ +/* ETDM_OUT4_CON0 */ +/* ETDM_OUT5_CON0 */ +/* ETDM_OUT6_CON0 */ +#define OUT_REG_ETDM_OUT_EN_SFT 0 +#define OUT_REG_ETDM_OUT_EN_MASK 0x1 +#define OUT_REG_ETDM_OUT_EN_MASK_SFT (0x1 << 0) +#define OUT_REG_SYNC_MODE_SFT 1 +#define OUT_REG_SYNC_MODE_MASK 0x1 +#define OUT_REG_SYNC_MODE_MASK_SFT (0x1 << 1) +#define OUT_REG_LSB_FIRST_SFT 3 +#define OUT_REG_LSB_FIRST_MASK 0x1 +#define OUT_REG_LSB_FIRST_MASK_SFT (0x1 << 3) +#define OUT_REG_SOFT_RST_SFT 4 +#define OUT_REG_SOFT_RST_MASK 0x1 +#define OUT_REG_SOFT_RST_MASK_SFT (0x1 << 4) +#define OUT_REG_SLAVE_MODE_SFT 5 +#define OUT_REG_SLAVE_MODE_MASK 0x1 +#define OUT_REG_SLAVE_MODE_MASK_SFT (0x1 << 5) +#define OUT_REG_FMT_SFT 6 +#define OUT_REG_FMT_MASK 0x7 +#define OUT_REG_FMT_MASK_SFT (0x7 << 6) +#define OUT_REG_LRCK_EDGE_SEL_SFT 10 +#define OUT_REG_LRCK_EDGE_SEL_MASK 0x1 +#define OUT_REG_LRCK_EDGE_SEL_MASK_SFT (0x1 << 10) +#define OUT_REG_BIT_LENGTH_SFT 11 +#define OUT_REG_BIT_LENGTH_MASK 0x1f +#define OUT_REG_BIT_LENGTH_MASK_SFT (0x1f << 11) +#define OUT_REG_WORD_LENGTH_SFT 16 +#define OUT_REG_WORD_LENGTH_MASK 0x1f +#define OUT_REG_WORD_LENGTH_MASK_SFT (0x1f << 16) +#define OUT_REG_CH_NUM_SFT 23 +#define OUT_REG_CH_NUM_MASK 0x1f +#define OUT_REG_CH_NUM_MASK_SFT (0x1f << 23) +#define OUT_REG_RELATCH_DOMAIN_SEL_SFT 28 +#define OUT_REG_RELATCH_DOMAIN_SEL_MASK 0x7 +#define OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT (0x7 << 28) +#define OUT_REG_VALID_TOGETHER_SFT 31 +#define OUT_REG_VALID_TOGETHER_MASK 0x1 +#define OUT_REG_VALID_TOGETHER_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON1 */ +/* ETDM_OUT1_CON1 */ +/* ETDM_OUT2_CON1 */ +/* ETDM_OUT3_CON1 */ +/* ETDM_OUT4_CON1 */ +/* ETDM_OUT5_CON1 */ +/* ETDM_OUT6_CON1 */ +#define OUT_REG_INITIAL_COUNT_SFT 0 +#define OUT_REG_INITIAL_COUNT_MASK 0x1f +#define OUT_REG_INITIAL_COUNT_MASK_SFT (0x1f << 0) +#define OUT_REG_INITIAL_POINT_SFT 5 +#define OUT_REG_INITIAL_POINT_MASK 0x1f +#define OUT_REG_INITIAL_POINT_MASK_SFT (0x1f << 5) +#define OUT_REG_LRCK_AUTO_OFF_SFT 10 +#define OUT_REG_LRCK_AUTO_OFF_MASK 0x1 +#define OUT_REG_LRCK_AUTO_OFF_MASK_SFT (0x1 << 10) +#define OUT_REG_BCK_AUTO_OFF_SFT 11 +#define OUT_REG_BCK_AUTO_OFF_MASK 0x1 +#define OUT_REG_BCK_AUTO_OFF_MASK_SFT (0x1 << 11) +#define OUT_REG_INITIAL_LRCK_SFT 13 +#define OUT_REG_INITIAL_LRCK_MASK 0x1 +#define OUT_REG_INITIAL_LRCK_MASK_SFT (0x1 << 13) +#define OUT_REG_NO_ALIGN_1X_EN_SFT 14 +#define OUT_REG_NO_ALIGN_1X_EN_MASK 0x1 +#define OUT_REG_NO_ALIGN_1X_EN_MASK_SFT (0x1 << 14) +#define OUT_REG_LRCK_RESET_SFT 15 +#define OUT_REG_LRCK_RESET_MASK 0x1 +#define OUT_REG_LRCK_RESET_MASK_SFT (0x1 << 15) +#define OUT_PINMUX_MCLK_CTRL_OE_SFT 16 +#define OUT_PINMUX_MCLK_CTRL_OE_MASK 0x1 +#define OUT_PINMUX_MCLK_CTRL_OE_MASK_SFT (0x1 << 16) +#define OUT_REG_OUTPUT_CR_EN_SFT 18 +#define OUT_REG_OUTPUT_CR_EN_MASK 0x1 +#define OUT_REG_OUTPUT_CR_EN_MASK_SFT (0x1 << 18) +#define OUT_REG_LRCK_WIDTH_SFT 19 +#define OUT_REG_LRCK_WIDTH_MASK 0x3ff +#define OUT_REG_LRCK_WIDTH_MASK_SFT (0x3ff << 19) +#define OUT_REG_LRCK_AUTO_MODE_SFT 29 +#define OUT_REG_LRCK_AUTO_MODE_MASK 0x1 +#define OUT_REG_LRCK_AUTO_MODE_MASK_SFT (0x1 << 29) +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_SFT 30 +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_MASK 0x1 +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_MASK_SFT (0x1 << 30) +#define OUT_REG_16B_COMPACT_MODE_SFT 31 +#define OUT_REG_16B_COMPACT_MODE_MASK 0x1 +#define OUT_REG_16B_COMPACT_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON2 */ +/* ETDM_OUT1_CON2 */ +/* ETDM_OUT2_CON2 */ +/* ETDM_OUT3_CON2 */ +/* ETDM_OUT4_CON2 */ +/* ETDM_OUT5_CON2 */ +/* ETDM_OUT6_CON2 */ +#define OUT_REG_IN2LATCH_TIME_SFT 0 +#define OUT_REG_IN2LATCH_TIME_MASK 0x1f +#define OUT_REG_IN2LATCH_TIME_MASK_SFT (0x1f << 0) +#define OUT_REG_MASK_NUM_SFT 5 +#define OUT_REG_MASK_NUM_MASK 0x1f +#define OUT_REG_MASK_NUM_MASK_SFT (0x1f << 5) +#define OUT_REG_MASK_AUTO_SFT 10 +#define OUT_REG_MASK_AUTO_MASK 0x1 +#define OUT_REG_MASK_AUTO_MASK_SFT (0x1 << 10) +#define OUT_REG_SDATA_SHIFT_SFT 11 +#define OUT_REG_SDATA_SHIFT_MASK 0x3 +#define OUT_REG_SDATA_SHIFT_MASK_SFT (0x3 << 11) +#define OUT_REG_ALMOST_END_BIT_COUNT_SFT 13 +#define OUT_REG_ALMOST_END_BIT_COUNT_MASK 0x1f +#define OUT_REG_ALMOST_END_BIT_COUNT_MASK_SFT (0x1f << 13) +#define OUT_REG_SDATA_CON_SFT 18 +#define OUT_REG_SDATA_CON_MASK 0x3 +#define OUT_REG_SDATA_CON_MASK_SFT (0x3 << 18) +#define OUT_REG_REDUNDANT_0_SFT 20 +#define OUT_REG_REDUNDANT_0_MASK 0x1 +#define OUT_REG_REDUNDANT_0_MASK_SFT (0x1 << 20) +#define OUT_REG_SDATA_AUTO_OFF_SFT 21 +#define OUT_REG_SDATA_AUTO_OFF_MASK 0x1 +#define OUT_REG_SDATA_AUTO_OFF_MASK_SFT (0x1 << 21) +#define OUT_REG_BCK_OFF_TIME_SFT 22 +#define OUT_REG_BCK_OFF_TIME_MASK 0x3 +#define OUT_REG_BCK_OFF_TIME_MASK_SFT (0x3 << 22) +#define OUT_REG_MONITOR_SEL_SFT 24 +#define OUT_REG_MONITOR_SEL_MASK 0x3 +#define OUT_REG_MONITOR_SEL_MASK_SFT (0x3 << 24) +#define OUT_REG_SHIFT_AUTO_SFT 26 +#define OUT_REG_SHIFT_AUTO_MASK 0x1 +#define OUT_REG_SHIFT_AUTO_MASK_SFT (0x1 << 26) +#define OUT_REG_SDATA_DELAY_0P5T_EN_SFT 27 +#define OUT_REG_SDATA_DELAY_0P5T_EN_MASK 0x1 +#define OUT_REG_SDATA_DELAY_0P5T_EN_MASK_SFT (0x1 << 27) +#define OUT_REG_SDATA_DELAY_BCK_INV_SFT 28 +#define OUT_REG_SDATA_DELAY_BCK_INV_MASK 0x1 +#define OUT_REG_SDATA_DELAY_BCK_INV_MASK_SFT (0x1 << 28) +#define OUT_REG_LRCK_DELAY_0P5T_EN_SFT 29 +#define OUT_REG_LRCK_DELAY_0P5T_EN_MASK 0x1 +#define OUT_REG_LRCK_DELAY_0P5T_EN_MASK_SFT (0x1 << 29) +#define OUT_REG_LRCK_DELAY_BCK_INV_SFT 30 +#define OUT_REG_LRCK_DELAY_BCK_INV_MASK 0x1 +#define OUT_REG_LRCK_DELAY_BCK_INV_MASK_SFT (0x1 << 30) +#define OUT_REG_OFF_CR_EN_SFT 31 +#define OUT_REG_OFF_CR_EN_MASK 0x1 +#define OUT_REG_OFF_CR_EN_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON3 */ +/* ETDM_OUT1_CON3 */ +/* ETDM_OUT2_CON3 */ +/* ETDM_OUT3_CON3 */ +/* ETDM_OUT4_CON3 */ +/* ETDM_OUT5_CON3 */ +/* ETDM_OUT6_CON3 */ +#define OUT_REG_START_CH_PAIR0_SFT 0 +#define OUT_REG_START_CH_PAIR0_MASK 0xf +#define OUT_REG_START_CH_PAIR0_MASK_SFT (0xf << 0) +#define OUT_REG_START_CH_PAIR1_SFT 4 +#define OUT_REG_START_CH_PAIR1_MASK 0xf +#define OUT_REG_START_CH_PAIR1_MASK_SFT (0xf << 4) +#define OUT_REG_START_CH_PAIR2_SFT 8 +#define OUT_REG_START_CH_PAIR2_MASK 0xf +#define OUT_REG_START_CH_PAIR2_MASK_SFT (0xf << 8) +#define OUT_REG_START_CH_PAIR3_SFT 12 +#define OUT_REG_START_CH_PAIR3_MASK 0xf +#define OUT_REG_START_CH_PAIR3_MASK_SFT (0xf << 12) +#define OUT_REG_START_CH_PAIR4_SFT 16 +#define OUT_REG_START_CH_PAIR4_MASK 0xf +#define OUT_REG_START_CH_PAIR4_MASK_SFT (0xf << 16) +#define OUT_REG_START_CH_PAIR5_SFT 20 +#define OUT_REG_START_CH_PAIR5_MASK 0xf +#define OUT_REG_START_CH_PAIR5_MASK_SFT (0xf << 20) +#define OUT_REG_START_CH_PAIR6_SFT 24 +#define OUT_REG_START_CH_PAIR6_MASK 0xf +#define OUT_REG_START_CH_PAIR6_MASK_SFT (0xf << 24) +#define OUT_REG_START_CH_PAIR7_SFT 28 +#define OUT_REG_START_CH_PAIR7_MASK 0xf +#define OUT_REG_START_CH_PAIR7_MASK_SFT (0xf << 28) + +/* ETDM_OUT0_CON4 */ +/* ETDM_OUT1_CON4 */ +/* ETDM_OUT2_CON4 */ +/* ETDM_OUT3_CON4 */ +/* ETDM_OUT4_CON4 */ +/* ETDM_OUT5_CON4 */ +/* ETDM_OUT6_CON4 */ +#define OUT_REG_FS_TIMING_SEL_SFT 0 +#define OUT_REG_FS_TIMING_SEL_MASK 0x1f +#define OUT_REG_FS_TIMING_SEL_MASK_SFT (0x1f << 0) +#define OUT_REG_CLOCK_SOURCE_SEL_SFT 6 +#define OUT_REG_CLOCK_SOURCE_SEL_MASK 0x7 +#define OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT (0x7 << 6) +#define OUT_REG_CK_EN_SEL_AUTO_SFT 10 +#define OUT_REG_CK_EN_SEL_AUTO_MASK 0x1 +#define OUT_REG_CK_EN_SEL_AUTO_MASK_SFT (0x1 << 10) +#define OUT_REG_ASYNC_RESET_SFT 11 +#define OUT_REG_ASYNC_RESET_MASK 0x1 +#define OUT_REG_ASYNC_RESET_MASK_SFT (0x1 << 11) +#define OUT_REG_CK_EN_SEL_MANUAL_SFT 14 +#define OUT_REG_CK_EN_SEL_MANUAL_MASK 0x3ff +#define OUT_REG_CK_EN_SEL_MANUAL_MASK_SFT (0x3ff << 14) +#define OUT_REG_RELATCH_EN_SEL_SFT 24 +#define OUT_REG_RELATCH_EN_SEL_MASK 0x1f +#define OUT_REG_RELATCH_EN_SEL_MASK_SFT (0x1f << 24) +#define OUT_REG_WAIT_LAST_SAMPLE_SFT 30 +#define OUT_REG_WAIT_LAST_SAMPLE_MASK 0x1 +#define OUT_REG_WAIT_LAST_SAMPLE_MASK_SFT (0x1 << 30) +#define OUT_REG_ALWAYS_OPEN_1X_EN_SFT 31 +#define OUT_REG_ALWAYS_OPEN_1X_EN_MASK 0x1 +#define OUT_REG_ALWAYS_OPEN_1X_EN_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON5 */ +/* ETDM_OUT1_CON5 */ +/* ETDM_OUT2_CON5 */ +/* ETDM_OUT3_CON5 */ +/* ETDM_OUT4_CON5 */ +/* ETDM_OUT5_CON5 */ +/* ETDM_OUT6_CON5 */ +#define OUT_REG_REPACK_BITNUM_SFT 0 +#define OUT_REG_REPACK_BITNUM_MASK 0x3 +#define OUT_REG_REPACK_BITNUM_MASK_SFT (0x3 << 0) +#define OUT_REG_REPACK_CHNUM_SFT 2 +#define OUT_REG_REPACK_CHNUM_MASK 0xf +#define OUT_REG_REPACK_CHNUM_MASK_SFT (0xf << 2) +#define OUT_REG_SLAVE_BCK_INV_SFT 7 +#define OUT_REG_SLAVE_BCK_INV_MASK 0x1 +#define OUT_REG_SLAVE_BCK_INV_MASK_SFT (0x1 << 7) +#define OUT_REG_SLAVE_LRCK_INV_SFT 8 +#define OUT_REG_SLAVE_LRCK_INV_MASK 0x1 +#define OUT_REG_SLAVE_LRCK_INV_MASK_SFT (0x1 << 8) +#define OUT_REG_MASTER_BCK_INV_SFT 9 +#define OUT_REG_MASTER_BCK_INV_MASK 0x1 +#define OUT_REG_MASTER_BCK_INV_MASK_SFT (0x1 << 9) +#define OUT_REG_MASTER_WS_INV_SFT 10 +#define OUT_REG_MASTER_WS_INV_MASK 0x1 +#define OUT_REG_MASTER_WS_INV_MASK_SFT (0x1 << 10) +#define OUT_REG_REPACK_24B_MSB_ALIGN_SFT 11 +#define OUT_REG_REPACK_24B_MSB_ALIGN_MASK 0x1 +#define OUT_REG_REPACK_24B_MSB_ALIGN_MASK_SFT (0x1 << 11) +#define OUT_REG_LR_SWAP_SFT 16 +#define OUT_REG_LR_SWAP_MASK 0xffff +#define OUT_REG_LR_SWAP_MASK_SFT (0xffff << 16) + +/* ETDM_OUT0_CON6 */ +/* ETDM_OUT1_CON6 */ +/* ETDM_OUT2_CON6 */ +/* ETDM_OUT3_CON6 */ +/* ETDM_OUT4_CON6 */ +/* ETDM_OUT5_CON6 */ +/* ETDM_OUT6_CON6 */ +#define OUT_LCH_DATA_REG_SFT 0 +#define OUT_LCH_DATA_REG_MASK 0xffffffff +#define OUT_LCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_OUT0_CON7 */ +/* ETDM_OUT1_CON7 */ +/* ETDM_OUT2_CON7 */ +/* ETDM_OUT3_CON7 */ +/* ETDM_OUT4_CON7 */ +/* ETDM_OUT5_CON7 */ +/* ETDM_OUT6_CON7 */ +#define OUT_RCH_DATA_REG_SFT 0 +#define OUT_RCH_DATA_REG_MASK 0xffffffff +#define OUT_RCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_OUT0_CON8 */ +/* ETDM_OUT1_CON8 */ +/* ETDM_OUT2_CON8 */ +/* ETDM_OUT3_CON8 */ +/* ETDM_OUT4_CON8 */ +/* ETDM_OUT5_CON8 */ +/* ETDM_OUT6_CON8 */ +#define OUT_REG_START_CH_PAIR8_SFT 0 +#define OUT_REG_START_CH_PAIR8_MASK 0xf +#define OUT_REG_START_CH_PAIR8_MASK_SFT (0xf << 0) +#define OUT_REG_START_CH_PAIR9_SFT 4 +#define OUT_REG_START_CH_PAIR9_MASK 0xf +#define OUT_REG_START_CH_PAIR9_MASK_SFT (0xf << 4) +#define OUT_REG_START_CH_PAIR10_SFT 8 +#define OUT_REG_START_CH_PAIR10_MASK 0xf +#define OUT_REG_START_CH_PAIR10_MASK_SFT (0xf << 8) +#define OUT_REG_START_CH_PAIR11_SFT 12 +#define OUT_REG_START_CH_PAIR11_MASK 0xf +#define OUT_REG_START_CH_PAIR11_MASK_SFT (0xf << 12) +#define OUT_REG_START_CH_PAIR12_SFT 16 +#define OUT_REG_START_CH_PAIR12_MASK 0xf +#define OUT_REG_START_CH_PAIR12_MASK_SFT (0xf << 16) +#define OUT_REG_START_CH_PAIR13_SFT 20 +#define OUT_REG_START_CH_PAIR13_MASK 0xf +#define OUT_REG_START_CH_PAIR13_MASK_SFT (0xf << 20) +#define OUT_REG_START_CH_PAIR14_SFT 24 +#define OUT_REG_START_CH_PAIR14_MASK 0xf +#define OUT_REG_START_CH_PAIR14_MASK_SFT (0xf << 24) +#define OUT_REG_START_CH_PAIR15_SFT 28 +#define OUT_REG_START_CH_PAIR15_MASK 0xf +#define OUT_REG_START_CH_PAIR15_MASK_SFT (0xf << 28) + +/* ETDM_OUT0_CON9 */ +/* ETDM_OUT1_CON9 */ +/* ETDM_OUT2_CON9 */ +/* ETDM_OUT3_CON9 */ +/* ETDM_OUT4_CON9 */ +/* ETDM_OUT5_CON9 */ +/* ETDM_OUT6_CON9 */ +#define OUT_REG_AFIFO_THRESHOLD_SFT 29 +#define OUT_REG_AFIFO_THRESHOLD_MASK 0x3 +#define OUT_REG_AFIFO_THRESHOLD_MASK_SFT (0x3 << 29) +#define OUT_REG_AFIFO_SW_RESET_SFT 15 +#define OUT_REG_AFIFO_SW_RESET_MASK 0x1 +#define OUT_REG_AFIFO_SW_RESET_MASK_SFT (0x1 << 15) +#define OUT_REG_AFIFO_RESET_SEL_SFT 14 +#define OUT_REG_AFIFO_RESET_SEL_MASK 0x1 +#define OUT_REG_AFIFO_RESET_SEL_MASK_SFT (0x1 << 14) +#define OUT_REG_AFIFO_AUTO_RESET_DIS_SFT 9 +#define OUT_REG_AFIFO_AUTO_RESET_DIS_MASK 0x1 +#define OUT_REG_AFIFO_AUTO_RESET_DIS_MASK_SFT (0x1 << 9) +#define OUT_REG_ETDM_USE_AFIFO_SFT 8 +#define OUT_REG_ETDM_USE_AFIFO_MASK 0x1 +#define OUT_REG_ETDM_USE_AFIFO_MASK_SFT (0x1 << 8) +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT 5 +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_MASK 0x7 +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_MASK_SFT (0x7 << 5) +#define OUT_REG_AFIFO_MODE_SFT 0 +#define OUT_REG_AFIFO_MODE_MASK 0x1f +#define OUT_REG_AFIFO_MODE_MASK_SFT (0x1f << 0) + +/* ETDM_OUT0_MON */ +/* ETDM_OUT1_MON */ +/* ETDM_OUT2_MON */ +/* ETDM_OUT3_MON */ +/* ETDM_OUT4_MON */ +/* ETDM_OUT5_MON */ +/* ETDM_OUT6_MON */ +#define LRCK_INV_SFT 30 +#define LRCK_INV_MASK 0x1 +#define LRCK_INV_MASK_SFT (0x1 << 30) +#define EN_SYNC_OUT_SFT 29 +#define EN_SYNC_OUT_MASK 0x1 +#define EN_SYNC_OUT_MASK_SFT (0x1 << 29) +#define HOPPING_EN_SYNC_OUT_PRE_SFT 28 +#define HOPPING_EN_SYNC_OUT_PRE_MASK 0x1 +#define HOPPING_EN_SYNC_OUT_PRE_MASK_SFT (0x1 << 28) +#define ETDM_2X_CK_EN_SFT 25 +#define ETDM_2X_CK_EN_MASK 0x1 +#define ETDM_2X_CK_EN_MASK_SFT (0x1 << 25) +#define ETDM_1X_CK_EN_SFT 24 +#define ETDM_1X_CK_EN_MASK 0x1 +#define ETDM_1X_CK_EN_MASK_SFT (0x1 << 24) +#define SDATA0_SFT 23 +#define SDATA0_MASK 0x1 +#define SDATA0_MASK_SFT (0x1 << 23) +#define CURRENT_STATUS_SFT 21 +#define CURRENT_STATUS_MASK 0x3 +#define CURRENT_STATUS_MASK_SFT (0x3 << 21) +#define BIT_POINT_SFT 16 +#define BIT_POINT_MASK 0x1f +#define BIT_POINT_MASK_SFT (0x1f << 16) +#define BIT_CH_COUNT_SFT 10 +#define BIT_CH_COUNT_MASK 0x3f +#define BIT_CH_COUNT_MASK_SFT (0x3f << 10) +#define BIT_COUNT_SFT 5 +#define BIT_COUNT_MASK 0x1f +#define BIT_COUNT_MASK_SFT (0x1f << 5) +#define CH_COUNT_SFT 0 +#define CH_COUNT_MASK 0x1f +#define CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_0_3_COWORK_CON0 */ +#define ETDM_OUT0_DATA_SEL_SFT 0 +#define ETDM_OUT0_DATA_SEL_MASK 0xf +#define ETDM_OUT0_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT0_SYNC_SEL_SFT 4 +#define ETDM_OUT0_SYNC_SEL_MASK 0xf +#define ETDM_OUT0_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT0_SLAVE_SEL_SFT 8 +#define ETDM_OUT0_SLAVE_SEL_MASK 0xf +#define ETDM_OUT0_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_OUT1_DATA_SEL_SFT 12 +#define ETDM_OUT1_DATA_SEL_MASK 0xf +#define ETDM_OUT1_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_OUT1_SYNC_SEL_SFT 16 +#define ETDM_OUT1_SYNC_SEL_MASK 0xf +#define ETDM_OUT1_SYNC_SEL_MASK_SFT (0xf << 16) +#define ETDM_OUT1_SLAVE_SEL_SFT 20 +#define ETDM_OUT1_SLAVE_SEL_MASK 0xf +#define ETDM_OUT1_SLAVE_SEL_MASK_SFT (0xf << 20) +#define ETDM_IN0_SLAVE_SEL_SFT 24 +#define ETDM_IN0_SLAVE_SEL_MASK 0xf +#define ETDM_IN0_SLAVE_SEL_MASK_SFT (0xf << 24) +#define ETDM_IN0_SYNC_SEL_SFT 28 +#define ETDM_IN0_SYNC_SEL_MASK 0xf +#define ETDM_IN0_SYNC_SEL_MASK_SFT (0xf << 28) + +/* ETDM_0_3_COWORK_CON1 */ +#define ETDM_IN0_SDATA0_SEL_SFT 0 +#define ETDM_IN0_SDATA0_SEL_MASK 0xf +#define ETDM_IN0_SDATA0_SEL_MASK_SFT (0xf << 0) +#define ETDM_IN0_SDATA1_15_SEL_SFT 4 +#define ETDM_IN0_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN0_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_IN1_SLAVE_SEL_SFT 8 +#define ETDM_IN1_SLAVE_SEL_MASK 0xf +#define ETDM_IN1_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_IN1_SYNC_SEL_SFT 12 +#define ETDM_IN1_SYNC_SEL_MASK 0xf +#define ETDM_IN1_SYNC_SEL_MASK_SFT (0xf << 12) +#define ETDM_IN1_SDATA0_SEL_SFT 16 +#define ETDM_IN1_SDATA0_SEL_MASK 0xf +#define ETDM_IN1_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_IN1_SDATA1_15_SEL_SFT 20 +#define ETDM_IN1_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN1_SDATA1_15_SEL_MASK_SFT (0xf << 20) + +/* ETDM_0_3_COWORK_CON2 */ +#define ETDM_OUT2_DATA_SEL_SFT 0 +#define ETDM_OUT2_DATA_SEL_MASK 0xf +#define ETDM_OUT2_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT2_SYNC_SEL_SFT 4 +#define ETDM_OUT2_SYNC_SEL_MASK 0xf +#define ETDM_OUT2_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT2_SLAVE_SEL_SFT 8 +#define ETDM_OUT2_SLAVE_SEL_MASK 0xf +#define ETDM_OUT2_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_OUT3_DATA_SEL_SFT 12 +#define ETDM_OUT3_DATA_SEL_MASK 0xf +#define ETDM_OUT3_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_OUT3_SYNC_SEL_SFT 16 +#define ETDM_OUT3_SYNC_SEL_MASK 0xf +#define ETDM_OUT3_SYNC_SEL_MASK_SFT (0xf << 16) +#define ETDM_OUT3_SLAVE_SEL_SFT 20 +#define ETDM_OUT3_SLAVE_SEL_MASK 0xf +#define ETDM_OUT3_SLAVE_SEL_MASK_SFT (0xf << 20) +#define ETDM_IN2_SLAVE_SEL_SFT 24 +#define ETDM_IN2_SLAVE_SEL_MASK 0xf +#define ETDM_IN2_SLAVE_SEL_MASK_SFT (0xf << 24) +#define ETDM_IN2_SYNC_SEL_SFT 28 +#define ETDM_IN2_SYNC_SEL_MASK 0xf +#define ETDM_IN2_SYNC_SEL_MASK_SFT (0xf << 28) + +/* ETDM_0_3_COWORK_CON3 */ +#define ETDM_IN2_SDATA0_SEL_SFT 0 +#define ETDM_IN2_SDATA0_SEL_MASK 0xf +#define ETDM_IN2_SDATA0_SEL_MASK_SFT (0xf << 0) +#define ETDM_IN2_SDATA1_15_SEL_SFT 4 +#define ETDM_IN2_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN2_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_IN3_SLAVE_SEL_SFT 8 +#define ETDM_IN3_SLAVE_SEL_MASK 0xf +#define ETDM_IN3_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_IN3_SYNC_SEL_SFT 12 +#define ETDM_IN3_SYNC_SEL_MASK 0xf +#define ETDM_IN3_SYNC_SEL_MASK_SFT (0xf << 12) +#define ETDM_IN3_SDATA0_SEL_SFT 16 +#define ETDM_IN3_SDATA0_SEL_MASK 0xf +#define ETDM_IN3_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_IN3_SDATA1_15_SEL_SFT 20 +#define ETDM_IN3_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN3_SDATA1_15_SEL_MASK_SFT (0xf << 20) + +/* ETDM_4_7_COWORK_CON0 */ +#define ETDM_OUT4_DATA_SEL_SFT 0 +#define ETDM_OUT4_DATA_SEL_MASK 0xf +#define ETDM_OUT4_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT4_SYNC_SEL_SFT 4 +#define ETDM_OUT4_SYNC_SEL_MASK 0xf +#define ETDM_OUT4_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT4_SLAVE_SEL_SFT 8 +#define ETDM_OUT4_SLAVE_SEL_MASK 0xf +#define ETDM_OUT4_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_OUT5_DATA_SEL_SFT 12 +#define ETDM_OUT5_DATA_SEL_MASK 0xf +#define ETDM_OUT5_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_OUT5_SYNC_SEL_SFT 16 +#define ETDM_OUT5_SYNC_SEL_MASK 0xf +#define ETDM_OUT5_SYNC_SEL_MASK_SFT (0xf << 16) +#define ETDM_OUT5_SLAVE_SEL_SFT 20 +#define ETDM_OUT5_SLAVE_SEL_MASK 0xf +#define ETDM_OUT5_SLAVE_SEL_MASK_SFT (0xf << 20) +#define ETDM_IN4_SLAVE_SEL_SFT 24 +#define ETDM_IN4_SLAVE_SEL_MASK 0xf +#define ETDM_IN4_SLAVE_SEL_MASK_SFT (0xf << 24) +#define ETDM_IN4_SYNC_SEL_SFT 28 +#define ETDM_IN4_SYNC_SEL_MASK 0xf +#define ETDM_IN4_SYNC_SEL_MASK_SFT (0xf << 28) + +/* ETDM_4_7_COWORK_CON1 */ +#define ETDM_IN4_SDATA0_SEL_SFT 0 +#define ETDM_IN4_SDATA0_SEL_MASK 0xf +#define ETDM_IN4_SDATA0_SEL_MASK_SFT (0xf << 0) +#define ETDM_IN4_SDATA1_15_SEL_SFT 4 +#define ETDM_IN4_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN4_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_IN5_SLAVE_SEL_SFT 8 +#define ETDM_IN5_SLAVE_SEL_MASK 0xf +#define ETDM_IN5_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_IN5_SYNC_SEL_SFT 12 +#define ETDM_IN5_SYNC_SEL_MASK 0xf +#define ETDM_IN5_SYNC_SEL_MASK_SFT (0xf << 12) +#define ETDM_IN5_SDATA0_SEL_SFT 16 +#define ETDM_IN5_SDATA0_SEL_MASK 0xf +#define ETDM_IN5_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_IN5_SDATA1_15_SEL_SFT 20 +#define ETDM_IN5_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN5_SDATA1_15_SEL_MASK_SFT (0xf << 20) + +/* ETDM_4_7_COWORK_CON2 */ +#define ETDM_OUT6_DATA_SEL_SFT 0 +#define ETDM_OUT6_DATA_SEL_MASK 0xf +#define ETDM_OUT6_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT6_SYNC_SEL_SFT 4 +#define ETDM_OUT6_SYNC_SEL_MASK 0xf +#define ETDM_OUT6_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT6_SLAVE_SEL_SFT 8 +#define ETDM_OUT6_SLAVE_SEL_MASK 0xf +#define ETDM_OUT6_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_OUT7_DATA_SEL_SFT 12 +#define ETDM_OUT7_DATA_SEL_MASK 0xf +#define ETDM_OUT7_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_OUT7_SYNC_SEL_SFT 16 +#define ETDM_OUT7_SYNC_SEL_MASK 0xf +#define ETDM_OUT7_SYNC_SEL_MASK_SFT (0xf << 16) +#define ETDM_OUT7_SLAVE_SEL_SFT 20 +#define ETDM_OUT7_SLAVE_SEL_MASK 0xf +#define ETDM_OUT7_SLAVE_SEL_MASK_SFT (0xf << 20) +#define ETDM_IN6_SLAVE_SEL_SFT 24 +#define ETDM_IN6_SLAVE_SEL_MASK 0xf +#define ETDM_IN6_SLAVE_SEL_MASK_SFT (0xf << 24) +#define ETDM_IN6_SYNC_SEL_SFT 28 +#define ETDM_IN6_SYNC_SEL_MASK 0xf +#define ETDM_IN6_SYNC_SEL_MASK_SFT (0xf << 28) + +/* ETDM_4_7_COWORK_CON3 */ +#define ETDM_IN6_SDATA0_SEL_SFT 0 +#define ETDM_IN6_SDATA0_SEL_MASK 0xf +#define ETDM_IN6_SDATA0_SEL_MASK_SFT (0xf << 0) +#define ETDM_IN6_SDATA1_15_SEL_SFT 4 +#define ETDM_IN6_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN6_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_IN7_SLAVE_SEL_SFT 8 +#define ETDM_IN7_SLAVE_SEL_MASK 0xf +#define ETDM_IN7_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_IN7_SYNC_SEL_SFT 12 +#define ETDM_IN7_SYNC_SEL_MASK 0xf +#define ETDM_IN7_SYNC_SEL_MASK_SFT (0xf << 12) +#define ETDM_IN7_SDATA0_SEL_SFT 16 +#define ETDM_IN7_SDATA0_SEL_MASK 0xf +#define ETDM_IN7_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_IN7_SDATA1_15_SEL_SFT 20 +#define ETDM_IN7_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN7_SDATA1_15_SEL_MASK_SFT (0xf << 20) + +/* AFE_DPTX_CON */ +#define DPTX_CHANNEL_ENABLE_SFT 8 +#define DPTX_CHANNEL_ENABLE_MASK 0xff +#define DPTX_CHANNEL_ENABLE_MASK_SFT (0xff << 8) +#define DPTX_REGISTER_MONITOR_SELECT_SFT 3 +#define DPTX_REGISTER_MONITOR_SELECT_MASK 0xf +#define DPTX_REGISTER_MONITOR_SELECT_MASK_SFT (0xf << 3) +#define DPTX_16BIT_SFT 2 +#define DPTX_16BIT_MASK 0x1 +#define DPTX_16BIT_MASK_SFT (0x1 << 2) +#define DPTX_CHANNEL_NUMBER_SFT 1 +#define DPTX_CHANNEL_NUMBER_MASK 0x1 +#define DPTX_CHANNEL_NUMBER_MASK_SFT (0x1 << 1) +#define DPTX_ON_SFT 0 +#define DPTX_ON_MASK 0x1 +#define DPTX_ON_MASK_SFT (0x1 << 0) + +/* AFE_DPTX_MON */ +#define AFE_DPTX_MON0_SFT 0 +#define AFE_DPTX_MON0_MASK 0xffffffff +#define AFE_DPTX_MON0_MASK_SFT (0xffffffff << 0) + +/* AFE_TDM_CON1 */ +#define TDM_EN_SFT 0 +#define TDM_EN_MASK 0x1 +#define TDM_EN_MASK_SFT (0x1 << 0) +#define BCK_INVERSE_SFT 1 +#define BCK_INVERSE_MASK 0x1 +#define BCK_INVERSE_MASK_SFT (0x1 << 1) +#define LRCK_INVERSE_SFT 2 +#define LRCK_INVERSE_MASK 0x1 +#define LRCK_INVERSE_MASK_SFT (0x1 << 2) +#define DELAY_DATA_SFT 3 +#define DELAY_DATA_MASK 0x1 +#define DELAY_DATA_MASK_SFT (0x1 << 3) +#define LEFT_ALIGN_SFT 4 +#define LEFT_ALIGN_MASK 0x1 +#define LEFT_ALIGN_MASK_SFT (0x1 << 4) +#define TDM_LRCK_D0P5T_SFT 5 +#define TDM_LRCK_D0P5T_MASK 0x1 +#define TDM_LRCK_D0P5T_MASK_SFT (0x1 << 5) +#define TDM_SDATA_D0P5T_SFT 6 +#define TDM_SDATA_D0P5T_MASK 0x1 +#define TDM_SDATA_D0P5T_MASK_SFT (0x1 << 6) +#define WLEN_SFT 8 +#define WLEN_MASK 0x3 +#define WLEN_MASK_SFT (0x3 << 8) +#define CHANNEL_NUM_SFT 10 +#define CHANNEL_NUM_MASK 0x3 +#define CHANNEL_NUM_MASK_SFT (0x3 << 10) +#define CHANNEL_BCK_CYCLES_SFT 12 +#define CHANNEL_BCK_CYCLES_MASK 0x3 +#define CHANNEL_BCK_CYCLES_MASK_SFT (0x3 << 12) +#define HDMI_CLK_INV_SEL_SFT 15 +#define HDMI_CLK_INV_SEL_MASK 0x1 +#define HDMI_CLK_INV_SEL_MASK_SFT (0x1 << 15) +#define DAC_BIT_NUM_SFT 16 +#define DAC_BIT_NUM_MASK 0x1f +#define DAC_BIT_NUM_MASK_SFT (0x1f << 16) +#define LRCK_TDM_WIDTH_SFT 24 +#define LRCK_TDM_WIDTH_MASK 0xff +#define LRCK_TDM_WIDTH_MASK_SFT (0xff << 24) + +/* AFE_TDM_CON2 */ +#define ST_CH_PAIR_SOUT0_SFT 0 +#define ST_CH_PAIR_SOUT0_MASK 0x7 +#define ST_CH_PAIR_SOUT0_MASK_SFT (0x7 << 0) +#define ST_CH_PAIR_SOUT1_SFT 4 +#define ST_CH_PAIR_SOUT1_MASK 0x7 +#define ST_CH_PAIR_SOUT1_MASK_SFT (0x7 << 4) +#define ST_CH_PAIR_SOUT2_SFT 8 +#define ST_CH_PAIR_SOUT2_MASK 0x7 +#define ST_CH_PAIR_SOUT2_MASK_SFT (0x7 << 8) +#define ST_CH_PAIR_SOUT3_SFT 12 +#define ST_CH_PAIR_SOUT3_MASK 0x7 +#define ST_CH_PAIR_SOUT3_MASK_SFT (0x7 << 12) +#define TDM_FIX_VALUE_SEL_SFT 16 +#define TDM_FIX_VALUE_SEL_MASK 0x1 +#define TDM_FIX_VALUE_SEL_MASK_SFT (0x1 << 16) +#define TDM_I2S_LOOPBACK_SFT 20 +#define TDM_I2S_LOOPBACK_MASK 0x1 +#define TDM_I2S_LOOPBACK_MASK_SFT (0x1 << 20) +#define TDM_I2S_LOOPBACK_CH_SFT 21 +#define TDM_I2S_LOOPBACK_CH_MASK 0x3 +#define TDM_I2S_LOOPBACK_CH_MASK_SFT (0x3 << 21) +#define TDM_USE_SINEGEN_INPUT_SFT 23 +#define TDM_USE_SINEGEN_INPUT_MASK 0x1 +#define TDM_USE_SINEGEN_INPUT_MASK_SFT (0x1 << 23) +#define TDM_FIX_VALUE_SFT 24 +#define TDM_FIX_VALUE_MASK 0xff +#define TDM_FIX_VALUE_MASK_SFT (0xff << 24) + +/* AFE_TDM_CON3 */ +#define TDM_OUT_SEL_DOMAIN_SFT 29 +#define TDM_OUT_SEL_DOMAIN_MASK 0x7 +#define TDM_OUT_SEL_DOMAIN_MASK_SFT (0x7 << 29) +#define TDM_OUT_SEL_FS_SFT 24 +#define TDM_OUT_SEL_FS_MASK 0x1f +#define TDM_OUT_SEL_FS_MASK_SFT (0x1f << 24) +#define TDM_OUT_MON_SEL_SFT 3 +#define TDM_OUT_MON_SEL_MASK 0x1 +#define TDM_OUT_MON_SEL_MASK_SFT (0x1 << 3) +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_SFT 2 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_MASK 0x1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 2) +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_SFT 1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_MASK 0x1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_MASK_SFT (0x1 << 1) +#define TDM_UPDATE_EN_SEL_SFT 0 +#define TDM_UPDATE_EN_SEL_MASK 0x1 +#define TDM_UPDATE_EN_SEL_MASK_SFT (0x1 << 0) + +/* AFE_TDM_OUT_MON */ +#define AFE_TDM_OUT_MON_SFT 0 +#define AFE_TDM_OUT_MON_MASK 0xffffffff +#define AFE_TDM_OUT_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_HDMI_CONN0 */ +#define HDMI_O_7_SFT 21 +#define HDMI_O_7_MASK 0x7 +#define HDMI_O_7_MASK_SFT (0x7 << 21) +#define HDMI_O_6_SFT 18 +#define HDMI_O_6_MASK 0x7 +#define HDMI_O_6_MASK_SFT (0x7 << 18) +#define HDMI_O_5_SFT 15 +#define HDMI_O_5_MASK 0x7 +#define HDMI_O_5_MASK_SFT (0x7 << 15) +#define HDMI_O_4_SFT 12 +#define HDMI_O_4_MASK 0x7 +#define HDMI_O_4_MASK_SFT (0x7 << 12) +#define HDMI_O_3_SFT 9 +#define HDMI_O_3_MASK 0x7 +#define HDMI_O_3_MASK_SFT (0x7 << 9) +#define HDMI_O_2_SFT 6 +#define HDMI_O_2_MASK 0x7 +#define HDMI_O_2_MASK_SFT (0x7 << 6) +#define HDMI_O_1_SFT 3 +#define HDMI_O_1_MASK 0x7 +#define HDMI_O_1_MASK_SFT (0x7 << 3) +#define HDMI_O_0_SFT 0 +#define HDMI_O_0_MASK 0x7 +#define HDMI_O_0_MASK_SFT (0x7 << 0) + +/* AFE_TDM_TOP_IP_VERSION */ +#define AFE_TDM_TOP_IP_VERSION_SFT 0 +#define AFE_TDM_TOP_IP_VERSION_MASK 0xffffffff +#define AFE_TDM_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CBIP_CFG0 */ +#define CBIP_TOP_SLV_MUX_WAY_EN_SFT 16 +#define CBIP_TOP_SLV_MUX_WAY_EN_MASK 0xffff +#define CBIP_TOP_SLV_MUX_WAY_EN_MASK_SFT (0xffff << 16) +#define RESERVED_04_SFT 15 +#define RESERVED_04_MASK 0x1 +#define RESERVED_04_MASK_SFT (0x1 << 15) +#define CBIP_ASYNC_MST_RG_FIFO_THRE_SFT 13 +#define CBIP_ASYNC_MST_RG_FIFO_THRE_MASK 0x3 +#define CBIP_ASYNC_MST_RG_FIFO_THRE_MASK_SFT (0x3 << 13) +#define CBIP_ASYNC_MST_POSTWRITE_DIS_SFT 12 +#define CBIP_ASYNC_MST_POSTWRITE_DIS_MASK 0x1 +#define CBIP_ASYNC_MST_POSTWRITE_DIS_MASK_SFT (0x1 << 12) +#define RESERVED_03_SFT 11 +#define RESERVED_03_MASK 0x1 +#define RESERVED_03_MASK_SFT (0x1 << 11) +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_SFT 9 +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_MASK 0x3 +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_MASK_SFT (0x3 << 9) +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_SFT 8 +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_MASK 0x1 +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_MASK_SFT (0x1 << 8) +#define AUDIOSYS_BUSY_SFT 7 +#define AUDIOSYS_BUSY_MASK 0x1 +#define AUDIOSYS_BUSY_MASK_SFT (0x1 << 7) +#define CBIP_SLV_DECODER_ERR_FLAG_EN_SFT 6 +#define CBIP_SLV_DECODER_ERR_FLAG_EN_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_FLAG_EN_MASK_SFT (0x1 << 6) +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_SFT 5 +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_MASK 0x1 +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_MASK_SFT (0x1 << 5) +#define APB_R2T_SFT 3 +#define APB_R2T_MASK 0x1 +#define APB_R2T_MASK_SFT (0x1 << 3) +#define APB_W2T_SFT 2 +#define APB_W2T_MASK 0x1 +#define APB_W2T_MASK_SFT (0x1 << 2) +#define AHB_IDLE_EN_INT_SFT 1 +#define AHB_IDLE_EN_INT_MASK 0x1 +#define AHB_IDLE_EN_INT_MASK_SFT (0x1 << 1) +#define AHB_IDLE_EN_EXT_SFT 0 +#define AHB_IDLE_EN_EXT_MASK 0x1 +#define AHB_IDLE_EN_EXT_MASK_SFT (0x1 << 0) + +/* AFE_CBIP_SLV_DECODER_MON0 */ +#define CBIP_SLV_DECODER_ERR_DOMAIN_SFT 4 +#define CBIP_SLV_DECODER_ERR_DOMAIN_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_DOMAIN_MASK_SFT (0x1 << 4) +#define CBIP_SLV_DECODER_ERR_ID_SFT 3 +#define CBIP_SLV_DECODER_ERR_ID_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_ID_MASK_SFT (0x1 << 3) +#define CBIP_SLV_DECODER_ERR_RW_SFT 2 +#define CBIP_SLV_DECODER_ERR_RW_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_RW_MASK_SFT (0x1 << 2) +#define CBIP_SLV_DECODER_ERR_DECERR_SFT 1 +#define CBIP_SLV_DECODER_ERR_DECERR_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_DECERR_MASK_SFT (0x1 << 1) +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_SFT 0 +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_MASK 0x1 +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_MASK_SFT (0x1 << 0) + +/* AFE_CBIP_SLV_DECODER_MON1 */ +#define CBIP_SLV_DECODER_ERR_ADDR_SFT 0 +#define CBIP_SLV_DECODER_ERR_ADDR_MASK 0xffffffff +#define CBIP_SLV_DECODER_ERR_ADDR_MASK_SFT (0xffffffff << 0) + +/* AFE_CBIP_SLV_MUX_MON_CFG */ +#define CBIP_SLV_MUX_ERR_FLAG_EN_SFT 3 +#define CBIP_SLV_MUX_ERR_FLAG_EN_MASK 0x1 +#define CBIP_SLV_MUX_ERR_FLAG_EN_MASK_SFT (0x1 << 3) +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_SFT 2 +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_MASK 0x1 +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_MASK_SFT (0x1 << 2) +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_SFT 0 +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_MASK 0x3 +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_MASK_SFT (0x3 << 0) + +/* AFE_CBIP_SLV_MUX_MON0 */ +#define CBIP_SLV_MUX_ERR_DOMAIN_SFT 8 +#define CBIP_SLV_MUX_ERR_DOMAIN_MASK 0x1 +#define CBIP_SLV_MUX_ERR_DOMAIN_MASK_SFT (0x1 << 8) +#define CBIP_SLV_MUX_ERR_ID_SFT 7 +#define CBIP_SLV_MUX_ERR_ID_MASK 0x1 +#define CBIP_SLV_MUX_ERR_ID_MASK_SFT (0x1 << 7) +#define CBIP_SLV_MUX_ERR_RD_SFT 6 +#define CBIP_SLV_MUX_ERR_RD_MASK 0x1 +#define CBIP_SLV_MUX_ERR_RD_MASK_SFT (0x1 << 6) +#define CBIP_SLV_MUX_ERR_WR_SFT 5 +#define CBIP_SLV_MUX_ERR_WR_MASK 0x1 +#define CBIP_SLV_MUX_ERR_WR_MASK_SFT (0x1 << 5) +#define CBIP_SLV_MUX_ERR_EN_SLV_SFT 4 +#define CBIP_SLV_MUX_ERR_EN_SLV_MASK 0x1 +#define CBIP_SLV_MUX_ERR_EN_SLV_MASK_SFT (0x1 << 4) +#define CBIP_SLV_MUX_ERR_EN_MST_SFT 2 +#define CBIP_SLV_MUX_ERR_EN_MST_MASK 0x3 +#define CBIP_SLV_MUX_ERR_EN_MST_MASK_SFT (0x3 << 2) +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_SFT 0 +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_MASK 0x3 +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_MASK_SFT (0x3 << 0) + +/* AFE_CBIP_SLV_MUX_MON1 */ +#define CBIP_SLV_MUX_ERR_ADDR_SFT 0 +#define CBIP_SLV_MUX_ERR_ADDR_MASK 0xffffffff +#define CBIP_SLV_MUX_ERR_ADDR_MASK_SFT (0xffffffff << 0) + +/* AFE_MEMIF_CON0 */ +#define CPU_COMPACT_MODE_SFT 2 +#define CPU_COMPACT_MODE_MASK 0x1 +#define CPU_COMPACT_MODE_MASK_SFT (0x1 << 2) +#define CPU_HD_ALIGN_SFT 1 +#define CPU_HD_ALIGN_MASK 0x1 +#define CPU_HD_ALIGN_MASK_SFT (0x1 << 1) +#define SYSRAM_SIGN_SFT 0 +#define SYSRAM_SIGN_MASK 0x1 +#define SYSRAM_SIGN_MASK_SFT (0x1 << 0) + +/* AFE_MEMIF_ONE_HEART */ +#define DL_ONE_HEART_ON_2_SFT 2 +#define DL_ONE_HEART_ON_2_MASK 0x1 +#define DL_ONE_HEART_ON_2_MASK_SFT (0x1 << 2) +#define DL_ONE_HEART_ON_1_SFT 1 +#define DL_ONE_HEART_ON_1_MASK 0x1 +#define DL_ONE_HEART_ON_1_MASK_SFT (0x1 << 1) +#define DL_ONE_HEART_ON_0_SFT 0 +#define DL_ONE_HEART_ON_0_MASK 0x1 +#define DL_ONE_HEART_ON_0_MASK_SFT (0x1 << 0) + +/* AFE_DL0_BASE_MSB */ +#define DL0_BASE_ADDR_MSB_SFT 0 +#define DL0_BASE_ADDR_MSB_MASK 0x1ff +#define DL0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_BASE */ +#define DL0_BASE_ADDR_SFT 4 +#define DL0_BASE_ADDR_MASK 0xfffffff +#define DL0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL0_CUR_MSB */ +#define DL0_CUR_PTR_MSB_SFT 0 +#define DL0_CUR_PTR_MSB_MASK 0x1ff +#define DL0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_CUR */ +#define DL0_CUR_PTR_SFT 0 +#define DL0_CUR_PTR_MASK 0xffffffff +#define DL0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_END_MSB */ +#define DL0_END_ADDR_MSB_SFT 0 +#define DL0_END_ADDR_MSB_MASK 0x1ff +#define DL0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_END */ +#define DL0_END_ADDR_SFT 4 +#define DL0_END_ADDR_MASK 0xfffffff +#define DL0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL0_RCH_MON */ +#define DL0_RCH_DATA_SFT 0 +#define DL0_RCH_DATA_MASK 0xffffffff +#define DL0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_LCH_MON */ +#define DL0_LCH_DATA_SFT 0 +#define DL0_LCH_DATA_MASK 0xffffffff +#define DL0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_CON0 */ +#define DL0_ON_SFT 28 +#define DL0_ON_MASK 0x1 +#define DL0_ON_MASK_SFT (0x1 << 28) +#define DL0_ONE_HEART_SEL_SFT 22 +#define DL0_ONE_HEART_SEL_MASK 0x3 +#define DL0_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL0_MINLEN_SFT 20 +#define DL0_MINLEN_MASK 0x3 +#define DL0_MINLEN_MASK_SFT (0x3 << 20) +#define DL0_MAXLEN_SFT 16 +#define DL0_MAXLEN_MASK 0x3 +#define DL0_MAXLEN_MASK_SFT (0x3 << 16) +#define DL0_SEL_DOMAIN_SFT 13 +#define DL0_SEL_DOMAIN_MASK 0x7 +#define DL0_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL0_SEL_FS_SFT 8 +#define DL0_SEL_FS_MASK 0x1f +#define DL0_SEL_FS_MASK_SFT (0x1f << 8) +#define DL0_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL0_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL0_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL0_PBUF_SIZE_SFT 5 +#define DL0_PBUF_SIZE_MASK 0x3 +#define DL0_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL0_MONO_SFT 4 +#define DL0_MONO_MASK 0x1 +#define DL0_MONO_MASK_SFT (0x1 << 4) +#define DL0_NORMAL_MODE_SFT 3 +#define DL0_NORMAL_MODE_MASK 0x1 +#define DL0_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL0_HALIGN_SFT 2 +#define DL0_HALIGN_MASK 0x1 +#define DL0_HALIGN_MASK_SFT (0x1 << 2) +#define DL0_HD_MODE_SFT 0 +#define DL0_HD_MODE_MASK 0x3 +#define DL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL1_BASE_MSB */ +#define DL1_BASE_ADDR_MSB_SFT 0 +#define DL1_BASE_ADDR_MSB_MASK 0x1ff +#define DL1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_BASE */ +#define DL1_BASE_ADDR_SFT 4 +#define DL1_BASE_ADDR_MASK 0xfffffff +#define DL1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL1_CUR_MSB */ +#define DL1_CUR_PTR_MSB_SFT 0 +#define DL1_CUR_PTR_MSB_MASK 0x1ff +#define DL1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_CUR */ +#define DL1_CUR_PTR_SFT 0 +#define DL1_CUR_PTR_MASK 0xffffffff +#define DL1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_END_MSB */ +#define DL1_END_ADDR_MSB_SFT 0 +#define DL1_END_ADDR_MSB_MASK 0x1ff +#define DL1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_END */ +#define DL1_END_ADDR_SFT 4 +#define DL1_END_ADDR_MASK 0xfffffff +#define DL1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL1_RCH_MON */ +#define DL1_RCH_DATA_SFT 0 +#define DL1_RCH_DATA_MASK 0xffffffff +#define DL1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_LCH_MON */ +#define DL1_LCH_DATA_SFT 0 +#define DL1_LCH_DATA_MASK 0xffffffff +#define DL1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_CON0 */ +#define DL1_ON_SFT 28 +#define DL1_ON_MASK 0x1 +#define DL1_ON_MASK_SFT (0x1 << 28) +#define DL1_ONE_HEART_SEL_SFT 22 +#define DL1_ONE_HEART_SEL_MASK 0x3 +#define DL1_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL1_MINLEN_SFT 20 +#define DL1_MINLEN_MASK 0x3 +#define DL1_MINLEN_MASK_SFT (0x3 << 20) +#define DL1_MAXLEN_SFT 16 +#define DL1_MAXLEN_MASK 0x3 +#define DL1_MAXLEN_MASK_SFT (0x3 << 16) +#define DL1_SEL_DOMAIN_SFT 13 +#define DL1_SEL_DOMAIN_MASK 0x7 +#define DL1_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL1_SEL_FS_SFT 8 +#define DL1_SEL_FS_MASK 0x1f +#define DL1_SEL_FS_MASK_SFT (0x1f << 8) +#define DL1_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL1_PBUF_SIZE_SFT 5 +#define DL1_PBUF_SIZE_MASK 0x3 +#define DL1_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL1_MONO_SFT 4 +#define DL1_MONO_MASK 0x1 +#define DL1_MONO_MASK_SFT (0x1 << 4) +#define DL1_NORMAL_MODE_SFT 3 +#define DL1_NORMAL_MODE_MASK 0x1 +#define DL1_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL1_HALIGN_SFT 2 +#define DL1_HALIGN_MASK 0x1 +#define DL1_HALIGN_MASK_SFT (0x1 << 2) +#define DL1_HD_MODE_SFT 0 +#define DL1_HD_MODE_MASK 0x3 +#define DL1_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL2_BASE_MSB */ +#define DL2_BASE__ADDR_MSB_SFT 0 +#define DL2_BASE__ADDR_MSB_MASK 0x1ff +#define DL2_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_BASE */ +#define DL2_BASE_ADDR_SFT 4 +#define DL2_BASE_ADDR_MASK 0xfffffff +#define DL2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL2_CUR_MSB */ +#define DL2_CUR_PTR_MSB_SFT 0 +#define DL2_CUR_PTR_MSB_MASK 0x1ff +#define DL2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_CUR */ +#define DL2_CUR_PTR_SFT 0 +#define DL2_CUR_PTR_MASK 0xffffffff +#define DL2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_END_MSB */ +#define DL2_END_ADDR_MSB_SFT 0 +#define DL2_END_ADDR_MSB_MASK 0x1ff +#define DL2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_END */ +#define DL2_END_ADDR_SFT 4 +#define DL2_END_ADDR_MASK 0xfffffff +#define DL2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL2_RCH_MON */ +#define DL2_RCH_DATA_SFT 0 +#define DL2_RCH_DATA_MASK 0xffffffff +#define DL2_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_LCH_MON */ +#define DL2_LCH_DATA_SFT 0 +#define DL2_LCH_DATA_MASK 0xffffffff +#define DL2_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_CON0 */ +#define DL2_ON_SFT 28 +#define DL2_ON_MASK 0x1 +#define DL2_ON_MASK_SFT (0x1 << 28) +#define DL2_ONE_HEART_SEL_SFT 22 +#define DL2_ONE_HEART_SEL_MASK 0x3 +#define DL2_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL2_MINLEN_SFT 20 +#define DL2_MINLEN_MASK 0x3 +#define DL2_MINLEN_MASK_SFT (0x3 << 20) +#define DL2_MAXLEN_SFT 16 +#define DL2_MAXLEN_MASK 0x3 +#define DL2_MAXLEN_MASK_SFT (0x3 << 16) +#define DL2_SEL_DOMAIN_SFT 13 +#define DL2_SEL_DOMAIN_MASK 0x7 +#define DL2_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL2_SEL_FS_SFT 8 +#define DL2_SEL_FS_MASK 0x1f +#define DL2_SEL_FS_MASK_SFT (0x1f << 8) +#define DL2_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL2_PBUF_SIZE_SFT 5 +#define DL2_PBUF_SIZE_MASK 0x3 +#define DL2_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL2_MONO_SFT 4 +#define DL2_MONO_MASK 0x1 +#define DL2_MONO_MASK_SFT (0x1 << 4) +#define DL2_NORMAL_MODE_SFT 3 +#define DL2_NORMAL_MODE_MASK 0x1 +#define DL2_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL2_HALIGN_SFT 2 +#define DL2_HALIGN_MASK 0x1 +#define DL2_HALIGN_MASK_SFT (0x1 << 2) +#define DL2_HD_MODE_SFT 0 +#define DL2_HD_MODE_MASK 0x3 +#define DL2_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL3_BASE_MSB */ +#define DL3_BASE__ADDR_MSB_SFT 0 +#define DL3_BASE__ADDR_MSB_MASK 0x1ff +#define DL3_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_BASE */ +#define DL3_BASE_ADDR_SFT 4 +#define DL3_BASE_ADDR_MASK 0xfffffff +#define DL3_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL3_CUR_MSB */ +#define DL3_CUR_PTR_MSB_SFT 0 +#define DL3_CUR_PTR_MSB_MASK 0x1ff +#define DL3_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_CUR */ +#define DL3_CUR_PTR_SFT 0 +#define DL3_CUR_PTR_MASK 0xffffffff +#define DL3_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_END_MSB */ +#define DL3_END_ADDR_MSB_SFT 0 +#define DL3_END_ADDR_MSB_MASK 0x1ff +#define DL3_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_END */ +#define DL3_END_ADDR_SFT 4 +#define DL3_END_ADDR_MASK 0xfffffff +#define DL3_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL3_RCH_MON */ +#define DL3_RCH_DATA_SFT 0 +#define DL3_RCH_DATA_MASK 0xffffffff +#define DL3_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_LCH_MON */ +#define DL3_LCH_DATA_SFT 0 +#define DL3_LCH_DATA_MASK 0xffffffff +#define DL3_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_CON0 */ +#define DL3_ON_SFT 28 +#define DL3_ON_MASK 0x1 +#define DL3_ON_MASK_SFT (0x1 << 28) +#define DL3_ONE_HEART_SEL_SFT 22 +#define DL3_ONE_HEART_SEL_MASK 0x3 +#define DL3_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL3_MINLEN_SFT 20 +#define DL3_MINLEN_MASK 0x3 +#define DL3_MINLEN_MASK_SFT (0x3 << 20) +#define DL3_MAXLEN_SFT 16 +#define DL3_MAXLEN_MASK 0x3 +#define DL3_MAXLEN_MASK_SFT (0x3 << 16) +#define DL3_SEL_DOMAIN_SFT 13 +#define DL3_SEL_DOMAIN_MASK 0x7 +#define DL3_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL3_SEL_FS_SFT 8 +#define DL3_SEL_FS_MASK 0x1f +#define DL3_SEL_FS_MASK_SFT (0x1f << 8) +#define DL3_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL3_PBUF_SIZE_SFT 5 +#define DL3_PBUF_SIZE_MASK 0x3 +#define DL3_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL3_MONO_SFT 4 +#define DL3_MONO_MASK 0x1 +#define DL3_MONO_MASK_SFT (0x1 << 4) +#define DL3_NORMAL_MODE_SFT 3 +#define DL3_NORMAL_MODE_MASK 0x1 +#define DL3_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL3_HALIGN_SFT 2 +#define DL3_HALIGN_MASK 0x1 +#define DL3_HALIGN_MASK_SFT (0x1 << 2) +#define DL3_HD_MODE_SFT 0 +#define DL3_HD_MODE_MASK 0x3 +#define DL3_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL4_BASE_MSB */ +#define DL4_BASE__ADDR_MSB_SFT 0 +#define DL4_BASE__ADDR_MSB_MASK 0x1ff +#define DL4_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_BASE */ +#define DL4_BASE_ADDR_SFT 4 +#define DL4_BASE_ADDR_MASK 0xfffffff +#define DL4_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL4_CUR_MSB */ +#define DL4_CUR_PTR_MSB_SFT 0 +#define DL4_CUR_PTR_MSB_MASK 0x1ff +#define DL4_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_CUR */ +#define DL4_CUR_PTR_SFT 0 +#define DL4_CUR_PTR_MASK 0xffffffff +#define DL4_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_END_MSB */ +#define DL4_END_ADDR_MSB_SFT 0 +#define DL4_END_ADDR_MSB_MASK 0x1ff +#define DL4_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_END */ +#define DL4_END_ADDR_SFT 4 +#define DL4_END_ADDR_MASK 0xfffffff +#define DL4_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL4_RCH_MON */ +#define DL4_RCH_DATA_SFT 0 +#define DL4_RCH_DATA_MASK 0xffffffff +#define DL4_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_LCH_MON */ +#define DL4_LCH_DATA_SFT 0 +#define DL4_LCH_DATA_MASK 0xffffffff +#define DL4_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_CON0 */ +#define DL4_ON_SFT 28 +#define DL4_ON_MASK 0x1 +#define DL4_ON_MASK_SFT (0x1 << 28) +#define DL4_ONE_HEART_SEL_SFT 22 +#define DL4_ONE_HEART_SEL_MASK 0x3 +#define DL4_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL4_MINLEN_SFT 20 +#define DL4_MINLEN_MASK 0x3 +#define DL4_MINLEN_MASK_SFT (0x3 << 20) +#define DL4_MAXLEN_SFT 16 +#define DL4_MAXLEN_MASK 0x3 +#define DL4_MAXLEN_MASK_SFT (0x3 << 16) +#define DL4_SEL_DOMAIN_SFT 13 +#define DL4_SEL_DOMAIN_MASK 0x7 +#define DL4_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL4_SEL_FS_SFT 8 +#define DL4_SEL_FS_MASK 0x1f +#define DL4_SEL_FS_MASK_SFT (0x1f << 8) +#define DL4_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL4_PBUF_SIZE_SFT 5 +#define DL4_PBUF_SIZE_MASK 0x3 +#define DL4_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL4_MONO_SFT 4 +#define DL4_MONO_MASK 0x1 +#define DL4_MONO_MASK_SFT (0x1 << 4) +#define DL4_NORMAL_MODE_SFT 3 +#define DL4_NORMAL_MODE_MASK 0x1 +#define DL4_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL4_HALIGN_SFT 2 +#define DL4_HALIGN_MASK 0x1 +#define DL4_HALIGN_MASK_SFT (0x1 << 2) +#define DL4_HD_MODE_SFT 0 +#define DL4_HD_MODE_MASK 0x3 +#define DL4_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL5_BASE_MSB */ +#define DL5_BASE__ADDR_MSB_SFT 0 +#define DL5_BASE__ADDR_MSB_MASK 0x1ff +#define DL5_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_BASE */ +#define DL5_BASE_ADDR_SFT 4 +#define DL5_BASE_ADDR_MASK 0xfffffff +#define DL5_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL5_CUR_MSB */ +#define DL5_CUR_PTR_MSB_SFT 0 +#define DL5_CUR_PTR_MSB_MASK 0x1ff +#define DL5_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_CUR */ +#define DL5_CUR_PTR_SFT 0 +#define DL5_CUR_PTR_MASK 0xffffffff +#define DL5_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_END_MSB */ +#define DL5_END_ADDR_MSB_SFT 0 +#define DL5_END_ADDR_MSB_MASK 0x1ff +#define DL5_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_END */ +#define DL5_END_ADDR_SFT 4 +#define DL5_END_ADDR_MASK 0xfffffff +#define DL5_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL5_RCH_MON */ +#define DL5_RCH_DATA_SFT 0 +#define DL5_RCH_DATA_MASK 0xffffffff +#define DL5_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_LCH_MON */ +#define DL5_LCH_DATA_SFT 0 +#define DL5_LCH_DATA_MASK 0xffffffff +#define DL5_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_CON0 */ +#define DL5_ON_SFT 28 +#define DL5_ON_MASK 0x1 +#define DL5_ON_MASK_SFT (0x1 << 28) +#define DL5_ONE_HEART_SEL_SFT 22 +#define DL5_ONE_HEART_SEL_MASK 0x3 +#define DL5_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL5_MINLEN_SFT 20 +#define DL5_MINLEN_MASK 0x3 +#define DL5_MINLEN_MASK_SFT (0x3 << 20) +#define DL5_MAXLEN_SFT 16 +#define DL5_MAXLEN_MASK 0x3 +#define DL5_MAXLEN_MASK_SFT (0x3 << 16) +#define DL5_SEL_DOMAIN_SFT 13 +#define DL5_SEL_DOMAIN_MASK 0x7 +#define DL5_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL5_SEL_FS_SFT 8 +#define DL5_SEL_FS_MASK 0x1f +#define DL5_SEL_FS_MASK_SFT (0x1f << 8) +#define DL5_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL5_PBUF_SIZE_SFT 5 +#define DL5_PBUF_SIZE_MASK 0x3 +#define DL5_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL5_MONO_SFT 4 +#define DL5_MONO_MASK 0x1 +#define DL5_MONO_MASK_SFT (0x1 << 4) +#define DL5_NORMAL_MODE_SFT 3 +#define DL5_NORMAL_MODE_MASK 0x1 +#define DL5_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL5_HALIGN_SFT 2 +#define DL5_HALIGN_MASK 0x1 +#define DL5_HALIGN_MASK_SFT (0x1 << 2) +#define DL5_HD_MODE_SFT 0 +#define DL5_HD_MODE_MASK 0x3 +#define DL5_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL6_BASE_MSB */ +#define DL6_BASE__ADDR_MSB_SFT 0 +#define DL6_BASE__ADDR_MSB_MASK 0x1ff +#define DL6_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_BASE */ +#define DL6_BASE_ADDR_SFT 4 +#define DL6_BASE_ADDR_MASK 0xfffffff +#define DL6_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL6_CUR_MSB */ +#define DL6_CUR_PTR_MSB_SFT 0 +#define DL6_CUR_PTR_MSB_MASK 0x1ff +#define DL6_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_CUR */ +#define DL6_CUR_PTR_SFT 0 +#define DL6_CUR_PTR_MASK 0xffffffff +#define DL6_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_END_MSB */ +#define DL6_END_ADDR_MSB_SFT 0 +#define DL6_END_ADDR_MSB_MASK 0x1ff +#define DL6_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_END */ +#define DL6_END_ADDR_SFT 4 +#define DL6_END_ADDR_MASK 0xfffffff +#define DL6_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL6_RCH_MON */ +#define DL6_RCH_DATA_SFT 0 +#define DL6_RCH_DATA_MASK 0xffffffff +#define DL6_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_LCH_MON */ +#define DL6_LCH_DATA_SFT 0 +#define DL6_LCH_DATA_MASK 0xffffffff +#define DL6_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_CON0 */ +#define DL6_ON_SFT 28 +#define DL6_ON_MASK 0x1 +#define DL6_ON_MASK_SFT (0x1 << 28) +#define DL6_ONE_HEART_SEL_SFT 22 +#define DL6_ONE_HEART_SEL_MASK 0x3 +#define DL6_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL6_MINLEN_SFT 20 +#define DL6_MINLEN_MASK 0x3 +#define DL6_MINLEN_MASK_SFT (0x3 << 20) +#define DL6_MAXLEN_SFT 16 +#define DL6_MAXLEN_MASK 0x3 +#define DL6_MAXLEN_MASK_SFT (0x3 << 16) +#define DL6_SEL_DOMAIN_SFT 13 +#define DL6_SEL_DOMAIN_MASK 0x7 +#define DL6_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL6_SEL_FS_SFT 8 +#define DL6_SEL_FS_MASK 0x1f +#define DL6_SEL_FS_MASK_SFT (0x1f << 8) +#define DL6_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL6_PBUF_SIZE_SFT 5 +#define DL6_PBUF_SIZE_MASK 0x3 +#define DL6_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL6_MONO_SFT 4 +#define DL6_MONO_MASK 0x1 +#define DL6_MONO_MASK_SFT (0x1 << 4) +#define DL6_NORMAL_MODE_SFT 3 +#define DL6_NORMAL_MODE_MASK 0x1 +#define DL6_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL6_HALIGN_SFT 2 +#define DL6_HALIGN_MASK 0x1 +#define DL6_HALIGN_MASK_SFT (0x1 << 2) +#define DL6_HD_MODE_SFT 0 +#define DL6_HD_MODE_MASK 0x3 +#define DL6_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL7_BASE_MSB */ +#define DL7_BASE__ADDR_MSB_SFT 0 +#define DL7_BASE__ADDR_MSB_MASK 0x1ff +#define DL7_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_BASE */ +#define DL7_BASE_ADDR_SFT 4 +#define DL7_BASE_ADDR_MASK 0xfffffff +#define DL7_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL7_CUR_MSB */ +#define DL7_CUR_PTR_MSB_SFT 0 +#define DL7_CUR_PTR_MSB_MASK 0x1ff +#define DL7_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_CUR */ +#define DL7_CUR_PTR_SFT 0 +#define DL7_CUR_PTR_MASK 0xffffffff +#define DL7_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_END_MSB */ +#define DL7_END_ADDR_MSB_SFT 0 +#define DL7_END_ADDR_MSB_MASK 0x1ff +#define DL7_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_END */ +#define DL7_END_ADDR_SFT 4 +#define DL7_END_ADDR_MASK 0xfffffff +#define DL7_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL7_RCH_MON */ +#define DL7_RCH_DATA_SFT 0 +#define DL7_RCH_DATA_MASK 0xffffffff +#define DL7_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_LCH_MON */ +#define DL7_LCH_DATA_SFT 0 +#define DL7_LCH_DATA_MASK 0xffffffff +#define DL7_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_CON0 */ +#define DL7_ON_SFT 28 +#define DL7_ON_MASK 0x1 +#define DL7_ON_MASK_SFT (0x1 << 28) +#define DL7_ONE_HEART_SEL_SFT 22 +#define DL7_ONE_HEART_SEL_MASK 0x3 +#define DL7_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL7_MINLEN_SFT 20 +#define DL7_MINLEN_MASK 0x3 +#define DL7_MINLEN_MASK_SFT (0x3 << 20) +#define DL7_MAXLEN_SFT 16 +#define DL7_MAXLEN_MASK 0x3 +#define DL7_MAXLEN_MASK_SFT (0x3 << 16) +#define DL7_SEL_DOMAIN_SFT 13 +#define DL7_SEL_DOMAIN_MASK 0x7 +#define DL7_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL7_SEL_FS_SFT 8 +#define DL7_SEL_FS_MASK 0x1f +#define DL7_SEL_FS_MASK_SFT (0x1f << 8) +#define DL7_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL7_PBUF_SIZE_SFT 5 +#define DL7_PBUF_SIZE_MASK 0x3 +#define DL7_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL7_MONO_SFT 4 +#define DL7_MONO_MASK 0x1 +#define DL7_MONO_MASK_SFT (0x1 << 4) +#define DL7_NORMAL_MODE_SFT 3 +#define DL7_NORMAL_MODE_MASK 0x1 +#define DL7_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL7_HALIGN_SFT 2 +#define DL7_HALIGN_MASK 0x1 +#define DL7_HALIGN_MASK_SFT (0x1 << 2) +#define DL7_HD_MODE_SFT 0 +#define DL7_HD_MODE_MASK 0x3 +#define DL7_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL8_BASE_MSB */ +#define DL8_BASE__ADDR_MSB_SFT 0 +#define DL8_BASE__ADDR_MSB_MASK 0x1ff +#define DL8_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_BASE */ +#define DL8_BASE_ADDR_SFT 4 +#define DL8_BASE_ADDR_MASK 0xfffffff +#define DL8_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL8_CUR_MSB */ +#define DL8_CUR_PTR_MSB_SFT 0 +#define DL8_CUR_PTR_MSB_MASK 0x1ff +#define DL8_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_CUR */ +#define DL8_CUR_PTR_SFT 0 +#define DL8_CUR_PTR_MASK 0xffffffff +#define DL8_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_END_MSB */ +#define DL8_END_ADDR_MSB_SFT 0 +#define DL8_END_ADDR_MSB_MASK 0x1ff +#define DL8_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_END */ +#define DL8_END_ADDR_SFT 4 +#define DL8_END_ADDR_MASK 0xfffffff +#define DL8_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL8_RCH_MON */ +#define DL8_RCH_DATA_SFT 0 +#define DL8_RCH_DATA_MASK 0xffffffff +#define DL8_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_LCH_MON */ +#define DL8_LCH_DATA_SFT 0 +#define DL8_LCH_DATA_MASK 0xffffffff +#define DL8_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_CON0 */ +#define DL8_ON_SFT 28 +#define DL8_ON_MASK 0x1 +#define DL8_ON_MASK_SFT (0x1 << 28) +#define DL8_ONE_HEART_SEL_SFT 22 +#define DL8_ONE_HEART_SEL_MASK 0x3 +#define DL8_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL8_MINLEN_SFT 20 +#define DL8_MINLEN_MASK 0x3 +#define DL8_MINLEN_MASK_SFT (0x3 << 20) +#define DL8_MAXLEN_SFT 16 +#define DL8_MAXLEN_MASK 0x3 +#define DL8_MAXLEN_MASK_SFT (0x3 << 16) +#define DL8_SEL_DOMAIN_SFT 13 +#define DL8_SEL_DOMAIN_MASK 0x7 +#define DL8_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL8_SEL_FS_SFT 8 +#define DL8_SEL_FS_MASK 0x1f +#define DL8_SEL_FS_MASK_SFT (0x1f << 8) +#define DL8_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL8_PBUF_SIZE_SFT 5 +#define DL8_PBUF_SIZE_MASK 0x3 +#define DL8_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL8_MONO_SFT 4 +#define DL8_MONO_MASK 0x1 +#define DL8_MONO_MASK_SFT (0x1 << 4) +#define DL8_NORMAL_MODE_SFT 3 +#define DL8_NORMAL_MODE_MASK 0x1 +#define DL8_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL8_HALIGN_SFT 2 +#define DL8_HALIGN_MASK 0x1 +#define DL8_HALIGN_MASK_SFT (0x1 << 2) +#define DL8_HD_MODE_SFT 0 +#define DL8_HD_MODE_MASK 0x3 +#define DL8_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL_4CH_BASE_MSB */ +#define DL_4CH_BASE__ADDR_MSB_SFT 0 +#define DL_4CH_BASE__ADDR_MSB_MASK 0x1ff +#define DL_4CH_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_4CH_BASE */ +#define DL_4CH_BASE_ADDR_SFT 4 +#define DL_4CH_BASE_ADDR_MASK 0xfffffff +#define DL_4CH_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_4CH_CUR_MSB */ +#define DL_4CH_CUR_PTR_MSB_SFT 0 +#define DL_4CH_CUR_PTR_MSB_MASK 0x1ff +#define DL_4CH_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_4CH_CUR */ +#define DL_4CH_CUR_PTR_SFT 0 +#define DL_4CH_CUR_PTR_MASK 0xffffffff +#define DL_4CH_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_4CH_END_MSB */ +#define DL_4CH_END_ADDR_MSB_SFT 0 +#define DL_4CH_END_ADDR_MSB_MASK 0x1ff +#define DL_4CH_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_4CH_END */ +#define DL_4CH_END_ADDR_SFT 4 +#define DL_4CH_END_ADDR_MASK 0xfffffff +#define DL_4CH_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_4CH_CON0 */ +#define DL_4CH_ON_SFT 31 +#define DL_4CH_ON_MASK 0x1 +#define DL_4CH_ON_MASK_SFT (0x1 << 31) +#define DL_4CH_NUM_SFT 24 +#define DL_4CH_NUM_MASK 0x1f +#define DL_4CH_NUM_MASK_SFT (0x1f << 24) +#define DL_4CH_ONE_HEART_SEL_SFT 22 +#define DL_4CH_ONE_HEART_SEL_MASK 0x3 +#define DL_4CH_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL_4CH_MINLEN_SFT 20 +#define DL_4CH_MINLEN_MASK 0x3 +#define DL_4CH_MINLEN_MASK_SFT (0x3 << 20) +#define DL_4CH_MAXLEN_SFT 16 +#define DL_4CH_MAXLEN_MASK 0x3 +#define DL_4CH_MAXLEN_MASK_SFT (0x3 << 16) +#define DL_4CH_SEL_DOMAIN_SFT 13 +#define DL_4CH_SEL_DOMAIN_MASK 0x7 +#define DL_4CH_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL_4CH_SEL_FS_SFT 8 +#define DL_4CH_SEL_FS_MASK 0x1f +#define DL_4CH_SEL_FS_MASK_SFT (0x1f << 8) +#define DL_4CH_BUF_EMPTY_CLR_SFT 7 +#define DL_4CH_BUF_EMPTY_CLR_MASK 0x1 +#define DL_4CH_BUF_EMPTY_CLR_MASK_SFT (0x1 << 7) +#define DL_4CH_PBUF_SIZE_SFT 5 +#define DL_4CH_PBUF_SIZE_MASK 0x3 +#define DL_4CH_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL_4CH_HANG_CLR_SFT 4 +#define DL_4CH_HANG_CLR_MASK 0x1 +#define DL_4CH_HANG_CLR_MASK_SFT (0x1 << 4) +#define DL_4CH_NORMAL_MODE_SFT 3 +#define DL_4CH_NORMAL_MODE_MASK 0x1 +#define DL_4CH_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL_4CH_HALIGN_SFT 2 +#define DL_4CH_HALIGN_MASK 0x1 +#define DL_4CH_HALIGN_MASK_SFT (0x1 << 2) +#define DL_4CH_HD_MODE_SFT 0 +#define DL_4CH_HD_MODE_MASK 0x3 +#define DL_4CH_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL_24CH_BASE_MSB */ +#define DL_24CH_BASE__ADDR_MSB_SFT 0 +#define DL_24CH_BASE__ADDR_MSB_MASK 0x1ff +#define DL_24CH_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_BASE */ +#define DL_24CH_BASE_ADDR_SFT 4 +#define DL_24CH_BASE_ADDR_MASK 0xfffffff +#define DL_24CH_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_24CH_CUR_MSB */ +#define DL_24CH_CUR_PTR_MSB_SFT 0 +#define DL_24CH_CUR_PTR_MSB_MASK 0x1ff +#define DL_24CH_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_CUR */ +#define DL_24CH_CUR_PTR_SFT 0 +#define DL_24CH_CUR_PTR_MASK 0xffffffff +#define DL_24CH_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_END_MSB */ +#define DL_24CH_END_ADDR_MSB_SFT 0 +#define DL_24CH_END_ADDR_MSB_MASK 0x1ff +#define DL_24CH_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_END */ +#define DL_24CH_END_ADDR_SFT 4 +#define DL_24CH_END_ADDR_MASK 0xfffffff +#define DL_24CH_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_24CH_CON0 */ +#define DL_24CH_ON_SFT 31 +#define DL_24CH_ON_MASK 0x1 +#define DL_24CH_ON_MASK_SFT (0x1 << 31) +#define DL_24CH_NUM_SFT 24 +#define DL_24CH_NUM_MASK 0x3f +#define DL_24CH_NUM_MASK_SFT (0x3f << 24) +#define DL_24CH_ONE_HEART_SEL_SFT 22 +#define DL_24CH_ONE_HEART_SEL_MASK 0x3 +#define DL_24CH_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL_24CH_MINLEN_SFT 20 +#define DL_24CH_MINLEN_MASK 0x3 +#define DL_24CH_MINLEN_MASK_SFT (0x3 << 20) +#define DL_24CH_MAXLEN_SFT 16 +#define DL_24CH_MAXLEN_MASK 0x3 +#define DL_24CH_MAXLEN_MASK_SFT (0x3 << 16) +#define DL_24CH_SEL_DOMAIN_SFT 13 +#define DL_24CH_SEL_DOMAIN_MASK 0x7 +#define DL_24CH_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL_24CH_SEL_FS_SFT 8 +#define DL_24CH_SEL_FS_MASK 0x1f +#define DL_24CH_SEL_FS_MASK_SFT (0x1f << 8) +#define DL_24CH_BUF_EMPTY_CLR_SFT 7 +#define DL_24CH_BUF_EMPTY_CLR_MASK 0x1 +#define DL_24CH_BUF_EMPTY_CLR_MASK_SFT (0x1 << 7) +#define DL_24CH_PBUF_SIZE_SFT 5 +#define DL_24CH_PBUF_SIZE_MASK 0x3 +#define DL_24CH_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL_24CH_HANG_CLR_SFT 4 +#define DL_24CH_HANG_CLR_MASK 0x1 +#define DL_24CH_HANG_CLR_MASK_SFT (0x1 << 4) +#define DL_24CH_NORMAL_MODE_SFT 3 +#define DL_24CH_NORMAL_MODE_MASK 0x1 +#define DL_24CH_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL_24CH_HALIGN_SFT 2 +#define DL_24CH_HALIGN_MASK 0x1 +#define DL_24CH_HALIGN_MASK_SFT (0x1 << 2) +#define DL_24CH_HD_MODE_SFT 0 +#define DL_24CH_HD_MODE_MASK 0x3 +#define DL_24CH_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL23_BASE_MSB */ +#define DL23_BASE__ADDR_MSB_SFT 0 +#define DL23_BASE__ADDR_MSB_MASK 0x1ff +#define DL23_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_BASE */ +#define DL23_BASE_ADDR_SFT 4 +#define DL23_BASE_ADDR_MASK 0xfffffff +#define DL23_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL23_CUR_MSB */ +#define DL23_CUR_PTR_MSB_SFT 0 +#define DL23_CUR_PTR_MSB_MASK 0x1ff +#define DL23_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_CUR */ +#define DL23_CUR_PTR_SFT 0 +#define DL23_CUR_PTR_MASK 0xffffffff +#define DL23_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_END_MSB */ +#define DL23_END_ADDR_MSB_SFT 0 +#define DL23_END_ADDR_MSB_MASK 0x1ff +#define DL23_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_END */ +#define DL23_END_ADDR_SFT 4 +#define DL23_END_ADDR_MASK 0xfffffff +#define DL23_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL23_RCH_MON */ +#define DL23_RCH_DATA_SFT 0 +#define DL23_RCH_DATA_MASK 0xffffffff +#define DL23_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_LCH_MON */ +#define DL23_LCH_DATA_SFT 0 +#define DL23_LCH_DATA_MASK 0xffffffff +#define DL23_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_CON0 */ +#define DL23_ON_SFT 28 +#define DL23_ON_MASK 0x1 +#define DL23_ON_MASK_SFT (0x1 << 28) +#define DL23_ONE_HEART_SEL_SFT 22 +#define DL23_ONE_HEART_SEL_MASK 0x3 +#define DL23_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL23_MINLEN_SFT 20 +#define DL23_MINLEN_MASK 0x3 +#define DL23_MINLEN_MASK_SFT (0x3 << 20) +#define DL23_MAXLEN_SFT 16 +#define DL23_MAXLEN_MASK 0x3 +#define DL23_MAXLEN_MASK_SFT (0x3 << 16) +#define DL23_SEL_DOMAIN_SFT 13 +#define DL23_SEL_DOMAIN_MASK 0x7 +#define DL23_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL23_SEL_FS_SFT 8 +#define DL23_SEL_FS_MASK 0x1f +#define DL23_SEL_FS_MASK_SFT (0x1f << 8) +#define DL23_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL23_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL23_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL23_PBUF_SIZE_SFT 5 +#define DL23_PBUF_SIZE_MASK 0x3 +#define DL23_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL23_MONO_SFT 4 +#define DL23_MONO_MASK 0x1 +#define DL23_MONO_MASK_SFT (0x1 << 4) +#define DL23_NORMAL_MODE_SFT 3 +#define DL23_NORMAL_MODE_MASK 0x1 +#define DL23_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL23_HALIGN_SFT 2 +#define DL23_HALIGN_MASK 0x1 +#define DL23_HALIGN_MASK_SFT (0x1 << 2) +#define DL23_HD_MODE_SFT 0 +#define DL23_HD_MODE_MASK 0x3 +#define DL23_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL24_BASE_MSB */ +#define DL24_BASE__ADDR_MSB_SFT 0 +#define DL24_BASE__ADDR_MSB_MASK 0x1ff +#define DL24_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_BASE */ +#define DL24_BASE_ADDR_SFT 4 +#define DL24_BASE_ADDR_MASK 0xfffffff +#define DL24_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL24_CUR_MSB */ +#define DL24_CUR_PTR_MSB_SFT 0 +#define DL24_CUR_PTR_MSB_MASK 0x1ff +#define DL24_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_CUR */ +#define DL24_CUR_PTR_SFT 0 +#define DL24_CUR_PTR_MASK 0xffffffff +#define DL24_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_END_MSB */ +#define DL24_END_ADDR_MSB_SFT 0 +#define DL24_END_ADDR_MSB_MASK 0x1ff +#define DL24_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_END */ +#define DL24_END_ADDR_SFT 4 +#define DL24_END_ADDR_MASK 0xfffffff +#define DL24_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL24_RCH_MON */ +#define DL24_RCH_DATA_SFT 0 +#define DL24_RCH_DATA_MASK 0xffffffff +#define DL24_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_LCH_MON */ +#define DL24_LCH_DATA_SFT 0 +#define DL24_LCH_DATA_MASK 0xffffffff +#define DL24_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_CON0 */ +#define DL24_ON_SFT 28 +#define DL24_ON_MASK 0x1 +#define DL24_ON_MASK_SFT (0x1 << 28) +#define DL24_ONE_HEART_SEL_SFT 22 +#define DL24_ONE_HEART_SEL_MASK 0x3 +#define DL24_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL24_MINLEN_SFT 20 +#define DL24_MINLEN_MASK 0x3 +#define DL24_MINLEN_MASK_SFT (0x3 << 20) +#define DL24_MAXLEN_SFT 16 +#define DL24_MAXLEN_MASK 0x3 +#define DL24_MAXLEN_MASK_SFT (0x3 << 16) +#define DL24_SEL_DOMAIN_SFT 13 +#define DL24_SEL_DOMAIN_MASK 0x7 +#define DL24_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL24_SEL_FS_SFT 8 +#define DL24_SEL_FS_MASK 0x1f +#define DL24_SEL_FS_MASK_SFT (0x1f << 8) +#define DL24_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL24_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL24_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL24_PBUF_SIZE_SFT 5 +#define DL24_PBUF_SIZE_MASK 0x3 +#define DL24_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL24_MONO_SFT 4 +#define DL24_MONO_MASK 0x1 +#define DL24_MONO_MASK_SFT (0x1 << 4) +#define DL24_NORMAL_MODE_SFT 3 +#define DL24_NORMAL_MODE_MASK 0x1 +#define DL24_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL24_HALIGN_SFT 2 +#define DL24_HALIGN_MASK 0x1 +#define DL24_HALIGN_MASK_SFT (0x1 << 2) +#define DL24_HD_MODE_SFT 0 +#define DL24_HD_MODE_MASK 0x3 +#define DL24_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL25_BASE_MSB */ +#define DL25_BASE__ADDR_MSB_SFT 0 +#define DL25_BASE__ADDR_MSB_MASK 0x1ff +#define DL25_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_BASE */ +#define DL25_BASE_ADDR_SFT 4 +#define DL25_BASE_ADDR_MASK 0xfffffff +#define DL25_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL25_CUR_MSB */ +#define DL25_CUR_PTR_MSB_SFT 0 +#define DL25_CUR_PTR_MSB_MASK 0x1ff +#define DL25_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_CUR */ +#define DL25_CUR_PTR_SFT 0 +#define DL25_CUR_PTR_MASK 0xffffffff +#define DL25_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_END_MSB */ +#define DL25_END_ADDR_MSB_SFT 0 +#define DL25_END_ADDR_MSB_MASK 0x1ff +#define DL25_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_END */ +#define DL25_END_ADDR_SFT 4 +#define DL25_END_ADDR_MASK 0xfffffff +#define DL25_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL25_RCH_MON */ +#define DL25_RCH_DATA_SFT 0 +#define DL25_RCH_DATA_MASK 0xffffffff +#define DL25_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_LCH_MON */ +#define DL25_LCH_DATA_SFT 0 +#define DL25_LCH_DATA_MASK 0xffffffff +#define DL25_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_CON0 */ +#define DL25_ON_SFT 28 +#define DL25_ON_MASK 0x1 +#define DL25_ON_MASK_SFT (0x1 << 28) +#define DL25_ONE_HEART_SEL_SFT 22 +#define DL25_ONE_HEART_SEL_MASK 0x3 +#define DL25_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL25_MINLEN_SFT 20 +#define DL25_MINLEN_MASK 0x3 +#define DL25_MINLEN_MASK_SFT (0x3 << 20) +#define DL25_MAXLEN_SFT 16 +#define DL25_MAXLEN_MASK 0x3 +#define DL25_MAXLEN_MASK_SFT (0x3 << 16) +#define DL25_SEL_DOMAIN_SFT 13 +#define DL25_SEL_DOMAIN_MASK 0x7 +#define DL25_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL25_SEL_FS_SFT 8 +#define DL25_SEL_FS_MASK 0x1f +#define DL25_SEL_FS_MASK_SFT (0x1f << 8) +#define DL25_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL25_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL25_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL25_PBUF_SIZE_SFT 5 +#define DL25_PBUF_SIZE_MASK 0x3 +#define DL25_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL25_MONO_SFT 4 +#define DL25_MONO_MASK 0x1 +#define DL25_MONO_MASK_SFT (0x1 << 4) +#define DL25_NORMAL_MODE_SFT 3 +#define DL25_NORMAL_MODE_MASK 0x1 +#define DL25_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL25_HALIGN_SFT 2 +#define DL25_HALIGN_MASK 0x1 +#define DL25_HALIGN_MASK_SFT (0x1 << 2) +#define DL25_HD_MODE_SFT 0 +#define DL25_HD_MODE_MASK 0x3 +#define DL25_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL26_BASE_MSB */ +#define DL26_BASE__ADDR_MSB_SFT 0 +#define DL26_BASE__ADDR_MSB_MASK 0x1ff +#define DL26_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL26_BASE */ +#define DL26_BASE_ADDR_SFT 4 +#define DL26_BASE_ADDR_MASK 0xfffffff +#define DL26_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL26_CUR_MSB */ +#define DL26_CUR_PTR_MSB_SFT 0 +#define DL26_CUR_PTR_MSB_MASK 0x1ff +#define DL26_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL26_CUR */ +#define DL26_CUR_PTR_SFT 0 +#define DL26_CUR_PTR_MASK 0xffffffff +#define DL26_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL26_END_MSB */ +#define DL26_END_ADDR_MSB_SFT 0 +#define DL26_END_ADDR_MSB_MASK 0x1ff +#define DL26_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL26_END */ +#define DL26_END_ADDR_SFT 4 +#define DL26_END_ADDR_MASK 0xfffffff +#define DL26_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL26_RCH_MON */ +#define DL26_RCH_DATA_SFT 0 +#define DL26_RCH_DATA_MASK 0xffffffff +#define DL26_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL26_LCH_MON */ +#define DL26_LCH_DATA_SFT 0 +#define DL26_LCH_DATA_MASK 0xffffffff +#define DL26_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL26_CON0 */ +#define DL26_ON_SFT 28 +#define DL26_ON_MASK 0x1 +#define DL26_ON_MASK_SFT (0x1 << 28) +#define DL26_ONE_HEART_SEL_SFT 22 +#define DL26_ONE_HEART_SEL_MASK 0x3 +#define DL26_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL26_MINLEN_SFT 20 +#define DL26_MINLEN_MASK 0x3 +#define DL26_MINLEN_MASK_SFT (0x3 << 20) +#define DL26_MAXLEN_SFT 16 +#define DL26_MAXLEN_MASK 0x3 +#define DL26_MAXLEN_MASK_SFT (0x3 << 16) +#define DL26_SEL_DOMAIN_SFT 13 +#define DL26_SEL_DOMAIN_MASK 0x7 +#define DL26_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL26_SEL_FS_SFT 8 +#define DL26_SEL_FS_MASK 0x1f +#define DL26_SEL_FS_MASK_SFT (0x1f << 8) +#define DL26_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL26_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL26_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL26_PBUF_SIZE_SFT 5 +#define DL26_PBUF_SIZE_MASK 0x3 +#define DL26_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL26_MONO_SFT 4 +#define DL26_MONO_MASK 0x1 +#define DL26_MONO_MASK_SFT (0x1 << 4) +#define DL26_NORMAL_MODE_SFT 3 +#define DL26_NORMAL_MODE_MASK 0x1 +#define DL26_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL26_HALIGN_SFT 2 +#define DL26_HALIGN_MASK 0x1 +#define DL26_HALIGN_MASK_SFT (0x1 << 2) +#define DL26_HD_MODE_SFT 0 +#define DL26_HD_MODE_MASK 0x3 +#define DL26_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL0_BASE_MSB */ +#define VUL0_BASE_ADDR_MSB_SFT 0 +#define VUL0_BASE_ADDR_MSB_MASK 0x1ff +#define VUL0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_BASE */ +#define VUL0_BASE_ADDR_SFT 4 +#define VUL0_BASE_ADDR_MASK 0xfffffff +#define VUL0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL0_CUR_MSB */ +#define VUL0_CUR_PTR_MSB_SFT 0 +#define VUL0_CUR_PTR_MSB_MASK 0x1ff +#define VUL0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_CUR */ +#define VUL0_CUR_PTR_SFT 0 +#define VUL0_CUR_PTR_MASK 0xffffffff +#define VUL0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_END_MSB */ +#define VUL0_END_ADDR_MSB_SFT 0 +#define VUL0_END_ADDR_MSB_MASK 0x1ff +#define VUL0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_END */ +#define VUL0_END_ADDR_SFT 4 +#define VUL0_END_ADDR_MASK 0xfffffff +#define VUL0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL0_RCH_MON */ +#define VUL0_RCH_DATA_SFT 0 +#define VUL0_RCH_DATA_MASK 0xffffffff +#define VUL0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_LCH_MON */ +#define VUL0_LCH_DATA_SFT 0 +#define VUL0_LCH_DATA_MASK 0xffffffff +#define VUL0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_CON0 */ +#define VUL0_ON_SFT 28 +#define VUL0_ON_MASK 0x1 +#define VUL0_ON_MASK_SFT (0x1 << 28) +#define VUL0_MINLEN_SFT 20 +#define VUL0_MINLEN_MASK 0x3 +#define VUL0_MINLEN_MASK_SFT (0x3 << 20) +#define VUL0_MAXLEN_SFT 16 +#define VUL0_MAXLEN_MASK 0x3 +#define VUL0_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL0_SEL_DOMAIN_SFT 13 +#define VUL0_SEL_DOMAIN_MASK 0x7 +#define VUL0_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL0_SEL_FS_SFT 8 +#define VUL0_SEL_FS_MASK 0x1f +#define VUL0_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL0_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL0_WR_SIGN_SFT 6 +#define VUL0_WR_SIGN_MASK 0x1 +#define VUL0_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL0_R_MONO_SFT 5 +#define VUL0_R_MONO_MASK 0x1 +#define VUL0_R_MONO_MASK_SFT (0x1 << 5) +#define VUL0_MONO_SFT 4 +#define VUL0_MONO_MASK 0x1 +#define VUL0_MONO_MASK_SFT (0x1 << 4) +#define VUL0_NORMAL_MODE_SFT 3 +#define VUL0_NORMAL_MODE_MASK 0x1 +#define VUL0_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL0_HALIGN_SFT 2 +#define VUL0_HALIGN_MASK 0x1 +#define VUL0_HALIGN_MASK_SFT (0x1 << 2) +#define VUL0_HD_MODE_SFT 0 +#define VUL0_HD_MODE_MASK 0x3 +#define VUL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL1_BASE_MSB */ +#define VUL1_BASE_ADDR_MSB_SFT 0 +#define VUL1_BASE_ADDR_MSB_MASK 0x1ff +#define VUL1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_BASE */ +#define VUL1_BASE_ADDR_SFT 4 +#define VUL1_BASE_ADDR_MASK 0xfffffff +#define VUL1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL1_CUR_MSB */ +#define VUL1_CUR_PTR_MSB_SFT 0 +#define VUL1_CUR_PTR_MSB_MASK 0x1ff +#define VUL1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_CUR */ +#define VUL1_CUR_PTR_SFT 0 +#define VUL1_CUR_PTR_MASK 0xffffffff +#define VUL1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_END_MSB */ +#define VUL1_END_ADDR_MSB_SFT 0 +#define VUL1_END_ADDR_MSB_MASK 0x1ff +#define VUL1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_END */ +#define VUL1_END_ADDR_SFT 4 +#define VUL1_END_ADDR_MASK 0xfffffff +#define VUL1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL1_RCH_MON */ +#define VUL1_RCH_DATA_SFT 0 +#define VUL1_RCH_DATA_MASK 0xffffffff +#define VUL1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_LCH_MON */ +#define VUL1_LCH_DATA_SFT 0 +#define VUL1_LCH_DATA_MASK 0xffffffff +#define VUL1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_CON0 */ +#define VUL1_ON_SFT 28 +#define VUL1_ON_MASK 0x1 +#define VUL1_ON_MASK_SFT (0x1 << 28) +#define VUL1_MINLEN_SFT 20 +#define VUL1_MINLEN_MASK 0x3 +#define VUL1_MINLEN_MASK_SFT (0x3 << 20) +#define VUL1_MAXLEN_SFT 16 +#define VUL1_MAXLEN_MASK 0x3 +#define VUL1_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL1_SEL_DOMAIN_SFT 13 +#define VUL1_SEL_DOMAIN_MASK 0x7 +#define VUL1_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL1_SEL_FS_SFT 8 +#define VUL1_SEL_FS_MASK 0x1f +#define VUL1_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL1_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL1_WR_SIGN_SFT 6 +#define VUL1_WR_SIGN_MASK 0x1 +#define VUL1_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL1_R_MONO_SFT 5 +#define VUL1_R_MONO_MASK 0x1 +#define VUL1_R_MONO_MASK_SFT (0x1 << 5) +#define VUL1_MONO_SFT 4 +#define VUL1_MONO_MASK 0x1 +#define VUL1_MONO_MASK_SFT (0x1 << 4) +#define VUL1_NORMAL_MODE_SFT 3 +#define VUL1_NORMAL_MODE_MASK 0x1 +#define VUL1_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL1_HALIGN_SFT 2 +#define VUL1_HALIGN_MASK 0x1 +#define VUL1_HALIGN_MASK_SFT (0x1 << 2) +#define VUL1_HD_MODE_SFT 0 +#define VUL1_HD_MODE_MASK 0x3 +#define VUL1_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL2_BASE_MSB */ +#define VUL2_BASE_ADDR_MSB_SFT 0 +#define VUL2_BASE_ADDR_MSB_MASK 0x1ff +#define VUL2_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_BASE */ +#define VUL2_BASE_ADDR_SFT 4 +#define VUL2_BASE_ADDR_MASK 0xfffffff +#define VUL2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL2_CUR_MSB */ +#define VUL2_CUR_PTR_MSB_SFT 0 +#define VUL2_CUR_PTR_MSB_MASK 0x1ff +#define VUL2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_CUR */ +#define VUL2_CUR_PTR_SFT 0 +#define VUL2_CUR_PTR_MASK 0xffffffff +#define VUL2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_END_MSB */ +#define VUL2_END_ADDR_MSB_SFT 0 +#define VUL2_END_ADDR_MSB_MASK 0x1ff +#define VUL2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_END */ +#define VUL2_END_ADDR_SFT 4 +#define VUL2_END_ADDR_MASK 0xfffffff +#define VUL2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL2_RCH_MON */ +#define VUL2_RCH_DATA_SFT 0 +#define VUL2_RCH_DATA_MASK 0xffffffff +#define VUL2_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_LCH_MON */ +#define VUL2_LCH_DATA_SFT 0 +#define VUL2_LCH_DATA_MASK 0xffffffff +#define VUL2_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_CON0 */ +#define VUL2_ON_SFT 28 +#define VUL2_ON_MASK 0x1 +#define VUL2_ON_MASK_SFT (0x1 << 28) +#define VUL2_MINLEN_SFT 20 +#define VUL2_MINLEN_MASK 0x3 +#define VUL2_MINLEN_MASK_SFT (0x3 << 20) +#define VUL2_MAXLEN_SFT 16 +#define VUL2_MAXLEN_MASK 0x3 +#define VUL2_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL2_SEL_DOMAIN_SFT 13 +#define VUL2_SEL_DOMAIN_MASK 0x7 +#define VUL2_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL2_SEL_FS_SFT 8 +#define VUL2_SEL_FS_MASK 0x1f +#define VUL2_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL2_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL2_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL2_WR_SIGN_SFT 6 +#define VUL2_WR_SIGN_MASK 0x1 +#define VUL2_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL2_R_MONO_SFT 5 +#define VUL2_R_MONO_MASK 0x1 +#define VUL2_R_MONO_MASK_SFT (0x1 << 5) +#define VUL2_MONO_SFT 4 +#define VUL2_MONO_MASK 0x1 +#define VUL2_MONO_MASK_SFT (0x1 << 4) +#define VUL2_NORMAL_MODE_SFT 3 +#define VUL2_NORMAL_MODE_MASK 0x1 +#define VUL2_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL2_HALIGN_SFT 2 +#define VUL2_HALIGN_MASK 0x1 +#define VUL2_HALIGN_MASK_SFT (0x1 << 2) +#define VUL2_HD_MODE_SFT 0 +#define VUL2_HD_MODE_MASK 0x3 +#define VUL2_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL3_BASE_MSB */ +#define VUL3_BASE_ADDR_MSB_SFT 0 +#define VUL3_BASE_ADDR_MSB_MASK 0x1ff +#define VUL3_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_BASE */ +#define VUL3_BASE_ADDR_SFT 4 +#define VUL3_BASE_ADDR_MASK 0xfffffff +#define VUL3_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL3_CUR_MSB */ +#define VUL3_CUR_PTR_MSB_SFT 0 +#define VUL3_CUR_PTR_MSB_MASK 0x1ff +#define VUL3_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_CUR */ +#define VUL3_CUR_PTR_SFT 0 +#define VUL3_CUR_PTR_MASK 0xffffffff +#define VUL3_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_END_MSB */ +#define VUL3_END_ADDR_MSB_SFT 0 +#define VUL3_END_ADDR_MSB_MASK 0x1ff +#define VUL3_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_END */ +#define VUL3_END_ADDR_SFT 4 +#define VUL3_END_ADDR_MASK 0xfffffff +#define VUL3_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL3_RCH_MON */ +#define VUL3_RCH_DATA_SFT 0 +#define VUL3_RCH_DATA_MASK 0xffffffff +#define VUL3_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_LCH_MON */ +#define VUL3_LCH_DATA_SFT 0 +#define VUL3_LCH_DATA_MASK 0xffffffff +#define VUL3_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_CON0 */ +#define VUL3_ON_SFT 28 +#define VUL3_ON_MASK 0x1 +#define VUL3_ON_MASK_SFT (0x1 << 28) +#define VUL3_MINLEN_SFT 20 +#define VUL3_MINLEN_MASK 0x3 +#define VUL3_MINLEN_MASK_SFT (0x3 << 20) +#define VUL3_MAXLEN_SFT 16 +#define VUL3_MAXLEN_MASK 0x3 +#define VUL3_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL3_SEL_DOMAIN_SFT 13 +#define VUL3_SEL_DOMAIN_MASK 0x7 +#define VUL3_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL3_SEL_FS_SFT 8 +#define VUL3_SEL_FS_MASK 0x1f +#define VUL3_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL3_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL3_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL3_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL3_WR_SIGN_SFT 6 +#define VUL3_WR_SIGN_MASK 0x1 +#define VUL3_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL3_R_MONO_SFT 5 +#define VUL3_R_MONO_MASK 0x1 +#define VUL3_R_MONO_MASK_SFT (0x1 << 5) +#define VUL3_MONO_SFT 4 +#define VUL3_MONO_MASK 0x1 +#define VUL3_MONO_MASK_SFT (0x1 << 4) +#define VUL3_NORMAL_MODE_SFT 3 +#define VUL3_NORMAL_MODE_MASK 0x1 +#define VUL3_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL3_HALIGN_SFT 2 +#define VUL3_HALIGN_MASK 0x1 +#define VUL3_HALIGN_MASK_SFT (0x1 << 2) +#define VUL3_HD_MODE_SFT 0 +#define VUL3_HD_MODE_MASK 0x3 +#define VUL3_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL4_BASE_MSB */ +#define VUL4_BASE_ADDR_MSB_SFT 0 +#define VUL4_BASE_ADDR_MSB_MASK 0x1ff +#define VUL4_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_BASE */ +#define VUL4_BASE_ADDR_SFT 4 +#define VUL4_BASE_ADDR_MASK 0xfffffff +#define VUL4_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL4_CUR_MSB */ +#define VUL4_CUR_PTR_MSB_SFT 0 +#define VUL4_CUR_PTR_MSB_MASK 0x1ff +#define VUL4_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_CUR */ +#define VUL4_CUR_PTR_SFT 0 +#define VUL4_CUR_PTR_MASK 0xffffffff +#define VUL4_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_END_MSB */ +#define VUL4_END_ADDR_MSB_SFT 0 +#define VUL4_END_ADDR_MSB_MASK 0x1ff +#define VUL4_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_END */ +#define VUL4_END_ADDR_SFT 4 +#define VUL4_END_ADDR_MASK 0xfffffff +#define VUL4_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL4_RCH_MON */ +#define VUL4_RCH_DATA_SFT 0 +#define VUL4_RCH_DATA_MASK 0xffffffff +#define VUL4_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_LCH_MON */ +#define VUL4_LCH_DATA_SFT 0 +#define VUL4_LCH_DATA_MASK 0xffffffff +#define VUL4_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_CON0 */ +#define VUL4_ON_SFT 28 +#define VUL4_ON_MASK 0x1 +#define VUL4_ON_MASK_SFT (0x1 << 28) +#define VUL4_MINLEN_SFT 20 +#define VUL4_MINLEN_MASK 0x3 +#define VUL4_MINLEN_MASK_SFT (0x3 << 20) +#define VUL4_MAXLEN_SFT 16 +#define VUL4_MAXLEN_MASK 0x3 +#define VUL4_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL4_SEL_DOMAIN_SFT 13 +#define VUL4_SEL_DOMAIN_MASK 0x7 +#define VUL4_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL4_SEL_FS_SFT 8 +#define VUL4_SEL_FS_MASK 0x1f +#define VUL4_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL4_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL4_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL4_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL4_WR_SIGN_SFT 6 +#define VUL4_WR_SIGN_MASK 0x1 +#define VUL4_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL4_R_MONO_SFT 5 +#define VUL4_R_MONO_MASK 0x1 +#define VUL4_R_MONO_MASK_SFT (0x1 << 5) +#define VUL4_MONO_SFT 4 +#define VUL4_MONO_MASK 0x1 +#define VUL4_MONO_MASK_SFT (0x1 << 4) +#define VUL4_NORMAL_MODE_SFT 3 +#define VUL4_NORMAL_MODE_MASK 0x1 +#define VUL4_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL4_HALIGN_SFT 2 +#define VUL4_HALIGN_MASK 0x1 +#define VUL4_HALIGN_MASK_SFT (0x1 << 2) +#define VUL4_HD_MODE_SFT 0 +#define VUL4_HD_MODE_MASK 0x3 +#define VUL4_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL5_BASE_MSB */ +#define VUL5_BASE_ADDR_MSB_SFT 0 +#define VUL5_BASE_ADDR_MSB_MASK 0x1ff +#define VUL5_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_BASE */ +#define VUL5_BASE_ADDR_SFT 4 +#define VUL5_BASE_ADDR_MASK 0xfffffff +#define VUL5_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL5_CUR_MSB */ +#define VUL5_CUR_PTR_MSB_SFT 0 +#define VUL5_CUR_PTR_MSB_MASK 0x1ff +#define VUL5_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_CUR */ +#define VUL5_CUR_PTR_SFT 0 +#define VUL5_CUR_PTR_MASK 0xffffffff +#define VUL5_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_END_MSB */ +#define VUL5_END_ADDR_MSB_SFT 0 +#define VUL5_END_ADDR_MSB_MASK 0x1ff +#define VUL5_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_END */ +#define VUL5_END_ADDR_SFT 4 +#define VUL5_END_ADDR_MASK 0xfffffff +#define VUL5_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL5_RCH_MON */ +#define VUL5_RCH_DATA_SFT 0 +#define VUL5_RCH_DATA_MASK 0xffffffff +#define VUL5_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_LCH_MON */ +#define VUL5_LCH_DATA_SFT 0 +#define VUL5_LCH_DATA_MASK 0xffffffff +#define VUL5_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_CON0 */ +#define VUL5_ON_SFT 28 +#define VUL5_ON_MASK 0x1 +#define VUL5_ON_MASK_SFT (0x1 << 28) +#define VUL5_MINLEN_SFT 20 +#define VUL5_MINLEN_MASK 0x3 +#define VUL5_MINLEN_MASK_SFT (0x3 << 20) +#define VUL5_MAXLEN_SFT 16 +#define VUL5_MAXLEN_MASK 0x3 +#define VUL5_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL5_SEL_DOMAIN_SFT 13 +#define VUL5_SEL_DOMAIN_MASK 0x7 +#define VUL5_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL5_SEL_FS_SFT 8 +#define VUL5_SEL_FS_MASK 0x1f +#define VUL5_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL5_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL5_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL5_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL5_WR_SIGN_SFT 6 +#define VUL5_WR_SIGN_MASK 0x1 +#define VUL5_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL5_R_MONO_SFT 5 +#define VUL5_R_MONO_MASK 0x1 +#define VUL5_R_MONO_MASK_SFT (0x1 << 5) +#define VUL5_MONO_SFT 4 +#define VUL5_MONO_MASK 0x1 +#define VUL5_MONO_MASK_SFT (0x1 << 4) +#define VUL5_NORMAL_MODE_SFT 3 +#define VUL5_NORMAL_MODE_MASK 0x1 +#define VUL5_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL5_HALIGN_SFT 2 +#define VUL5_HALIGN_MASK 0x1 +#define VUL5_HALIGN_MASK_SFT (0x1 << 2) +#define VUL5_HD_MODE_SFT 0 +#define VUL5_HD_MODE_MASK 0x3 +#define VUL5_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL6_BASE_MSB */ +#define VUL6_BASE_ADDR_MSB_SFT 0 +#define VUL6_BASE_ADDR_MSB_MASK 0x1ff +#define VUL6_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_BASE */ +#define VUL6_BASE_ADDR_SFT 4 +#define VUL6_BASE_ADDR_MASK 0xfffffff +#define VUL6_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL6_CUR_MSB */ +#define VUL6_CUR_PTR_MSB_SFT 0 +#define VUL6_CUR_PTR_MSB_MASK 0x1ff +#define VUL6_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_CUR */ +#define VUL6_CUR_PTR_SFT 0 +#define VUL6_CUR_PTR_MASK 0xffffffff +#define VUL6_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_END_MSB */ +#define VUL6_END_ADDR_MSB_SFT 0 +#define VUL6_END_ADDR_MSB_MASK 0x1ff +#define VUL6_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_END */ +#define VUL6_END_ADDR_SFT 4 +#define VUL6_END_ADDR_MASK 0xfffffff +#define VUL6_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL6_RCH_MON */ +#define VUL6_RCH_DATA_SFT 0 +#define VUL6_RCH_DATA_MASK 0xffffffff +#define VUL6_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_LCH_MON */ +#define VUL6_LCH_DATA_SFT 0 +#define VUL6_LCH_DATA_MASK 0xffffffff +#define VUL6_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_CON0 */ +#define VUL6_ON_SFT 28 +#define VUL6_ON_MASK 0x1 +#define VUL6_ON_MASK_SFT (0x1 << 28) +#define VUL6_MINLEN_SFT 20 +#define VUL6_MINLEN_MASK 0x3 +#define VUL6_MINLEN_MASK_SFT (0x3 << 20) +#define VUL6_MAXLEN_SFT 16 +#define VUL6_MAXLEN_MASK 0x3 +#define VUL6_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL6_SEL_DOMAIN_SFT 13 +#define VUL6_SEL_DOMAIN_MASK 0x7 +#define VUL6_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL6_SEL_FS_SFT 8 +#define VUL6_SEL_FS_MASK 0x1f +#define VUL6_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL6_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL6_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL6_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL6_WR_SIGN_SFT 6 +#define VUL6_WR_SIGN_MASK 0x1 +#define VUL6_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL6_R_MONO_SFT 5 +#define VUL6_R_MONO_MASK 0x1 +#define VUL6_R_MONO_MASK_SFT (0x1 << 5) +#define VUL6_MONO_SFT 4 +#define VUL6_MONO_MASK 0x1 +#define VUL6_MONO_MASK_SFT (0x1 << 4) +#define VUL6_NORMAL_MODE_SFT 3 +#define VUL6_NORMAL_MODE_MASK 0x1 +#define VUL6_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL6_HALIGN_SFT 2 +#define VUL6_HALIGN_MASK 0x1 +#define VUL6_HALIGN_MASK_SFT (0x1 << 2) +#define VUL6_HD_MODE_SFT 0 +#define VUL6_HD_MODE_MASK 0x3 +#define VUL6_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL7_BASE_MSB */ +#define VUL7_BASE_ADDR_MSB_SFT 0 +#define VUL7_BASE_ADDR_MSB_MASK 0x1ff +#define VUL7_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_BASE */ +#define VUL7_BASE_ADDR_SFT 4 +#define VUL7_BASE_ADDR_MASK 0xfffffff +#define VUL7_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL7_CUR_MSB */ +#define VUL7_CUR_PTR_MSB_SFT 0 +#define VUL7_CUR_PTR_MSB_MASK 0x1ff +#define VUL7_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_CUR */ +#define VUL7_CUR_PTR_SFT 0 +#define VUL7_CUR_PTR_MASK 0xffffffff +#define VUL7_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_END_MSB */ +#define VUL7_END_ADDR_MSB_SFT 0 +#define VUL7_END_ADDR_MSB_MASK 0x1ff +#define VUL7_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_END */ +#define VUL7_END_ADDR_SFT 4 +#define VUL7_END_ADDR_MASK 0xfffffff +#define VUL7_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL7_RCH_MON */ +#define VUL7_RCH_DATA_SFT 0 +#define VUL7_RCH_DATA_MASK 0xffffffff +#define VUL7_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_LCH_MON */ +#define VUL7_LCH_DATA_SFT 0 +#define VUL7_LCH_DATA_MASK 0xffffffff +#define VUL7_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_CON0 */ +#define VUL7_ON_SFT 28 +#define VUL7_ON_MASK 0x1 +#define VUL7_ON_MASK_SFT (0x1 << 28) +#define VUL7_MINLEN_SFT 20 +#define VUL7_MINLEN_MASK 0x3 +#define VUL7_MINLEN_MASK_SFT (0x3 << 20) +#define VUL7_MAXLEN_SFT 16 +#define VUL7_MAXLEN_MASK 0x3 +#define VUL7_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL7_SEL_DOMAIN_SFT 13 +#define VUL7_SEL_DOMAIN_MASK 0x7 +#define VUL7_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL7_SEL_FS_SFT 8 +#define VUL7_SEL_FS_MASK 0x1f +#define VUL7_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL7_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL7_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL7_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL7_WR_SIGN_SFT 6 +#define VUL7_WR_SIGN_MASK 0x1 +#define VUL7_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL7_R_MONO_SFT 5 +#define VUL7_R_MONO_MASK 0x1 +#define VUL7_R_MONO_MASK_SFT (0x1 << 5) +#define VUL7_MONO_SFT 4 +#define VUL7_MONO_MASK 0x1 +#define VUL7_MONO_MASK_SFT (0x1 << 4) +#define VUL7_NORMAL_MODE_SFT 3 +#define VUL7_NORMAL_MODE_MASK 0x1 +#define VUL7_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL7_HALIGN_SFT 2 +#define VUL7_HALIGN_MASK 0x1 +#define VUL7_HALIGN_MASK_SFT (0x1 << 2) +#define VUL7_HD_MODE_SFT 0 +#define VUL7_HD_MODE_MASK 0x3 +#define VUL7_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL8_BASE_MSB */ +#define VUL8_BASE_ADDR_MSB_SFT 0 +#define VUL8_BASE_ADDR_MSB_MASK 0x1ff +#define VUL8_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_BASE */ +#define VUL8_BASE_ADDR_SFT 4 +#define VUL8_BASE_ADDR_MASK 0xfffffff +#define VUL8_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL8_CUR_MSB */ +#define VUL8_CUR_PTR_MSB_SFT 0 +#define VUL8_CUR_PTR_MSB_MASK 0x1ff +#define VUL8_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_CUR */ +#define VUL8_CUR_PTR_SFT 0 +#define VUL8_CUR_PTR_MASK 0xffffffff +#define VUL8_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_END_MSB */ +#define VUL8_END_ADDR_MSB_SFT 0 +#define VUL8_END_ADDR_MSB_MASK 0x1ff +#define VUL8_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_END */ +#define VUL8_END_ADDR_SFT 4 +#define VUL8_END_ADDR_MASK 0xfffffff +#define VUL8_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL8_RCH_MON */ +#define VUL8_RCH_DATA_SFT 0 +#define VUL8_RCH_DATA_MASK 0xffffffff +#define VUL8_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_LCH_MON */ +#define VUL8_LCH_DATA_SFT 0 +#define VUL8_LCH_DATA_MASK 0xffffffff +#define VUL8_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_CON0 */ +#define VUL8_ON_SFT 28 +#define VUL8_ON_MASK 0x1 +#define VUL8_ON_MASK_SFT (0x1 << 28) +#define VUL8_MINLEN_SFT 20 +#define VUL8_MINLEN_MASK 0x3 +#define VUL8_MINLEN_MASK_SFT (0x3 << 20) +#define VUL8_MAXLEN_SFT 16 +#define VUL8_MAXLEN_MASK 0x3 +#define VUL8_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL8_SEL_DOMAIN_SFT 13 +#define VUL8_SEL_DOMAIN_MASK 0x7 +#define VUL8_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL8_SEL_FS_SFT 8 +#define VUL8_SEL_FS_MASK 0x1f +#define VUL8_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL8_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL8_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL8_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL8_WR_SIGN_SFT 6 +#define VUL8_WR_SIGN_MASK 0x1 +#define VUL8_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL8_R_MONO_SFT 5 +#define VUL8_R_MONO_MASK 0x1 +#define VUL8_R_MONO_MASK_SFT (0x1 << 5) +#define VUL8_MONO_SFT 4 +#define VUL8_MONO_MASK 0x1 +#define VUL8_MONO_MASK_SFT (0x1 << 4) +#define VUL8_NORMAL_MODE_SFT 3 +#define VUL8_NORMAL_MODE_MASK 0x1 +#define VUL8_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL8_HALIGN_SFT 2 +#define VUL8_HALIGN_MASK 0x1 +#define VUL8_HALIGN_MASK_SFT (0x1 << 2) +#define VUL8_HD_MODE_SFT 0 +#define VUL8_HD_MODE_MASK 0x3 +#define VUL8_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL9_BASE_MSB */ +#define VUL9_BASE_ADDR_MSB_SFT 0 +#define VUL9_BASE_ADDR_MSB_MASK 0x1ff +#define VUL9_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_BASE */ +#define VUL9_BASE_ADDR_SFT 4 +#define VUL9_BASE_ADDR_MASK 0xfffffff +#define VUL9_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL9_CUR_MSB */ +#define VUL9_CUR_PTR_MSB_SFT 0 +#define VUL9_CUR_PTR_MSB_MASK 0x1ff +#define VUL9_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_CUR */ +#define VUL9_CUR_PTR_SFT 0 +#define VUL9_CUR_PTR_MASK 0xffffffff +#define VUL9_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_END_MSB */ +#define VUL9_END_ADDR_MSB_SFT 0 +#define VUL9_END_ADDR_MSB_MASK 0x1ff +#define VUL9_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_END */ +#define VUL9_END_ADDR_SFT 4 +#define VUL9_END_ADDR_MASK 0xfffffff +#define VUL9_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL9_RCH_MON */ +#define VUL9_RCH_DATA_SFT 0 +#define VUL9_RCH_DATA_MASK 0xffffffff +#define VUL9_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_LCH_MON */ +#define VUL9_LCH_DATA_SFT 0 +#define VUL9_LCH_DATA_MASK 0xffffffff +#define VUL9_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_CON0 */ +#define VUL9_ON_SFT 28 +#define VUL9_ON_MASK 0x1 +#define VUL9_ON_MASK_SFT (0x1 << 28) +#define VUL9_MINLEN_SFT 20 +#define VUL9_MINLEN_MASK 0x3 +#define VUL9_MINLEN_MASK_SFT (0x3 << 20) +#define VUL9_MAXLEN_SFT 16 +#define VUL9_MAXLEN_MASK 0x3 +#define VUL9_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL9_SEL_DOMAIN_SFT 13 +#define VUL9_SEL_DOMAIN_MASK 0x7 +#define VUL9_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL9_SEL_FS_SFT 8 +#define VUL9_SEL_FS_MASK 0x1f +#define VUL9_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL9_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL9_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL9_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL9_WR_SIGN_SFT 6 +#define VUL9_WR_SIGN_MASK 0x1 +#define VUL9_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL9_R_MONO_SFT 5 +#define VUL9_R_MONO_MASK 0x1 +#define VUL9_R_MONO_MASK_SFT (0x1 << 5) +#define VUL9_MONO_SFT 4 +#define VUL9_MONO_MASK 0x1 +#define VUL9_MONO_MASK_SFT (0x1 << 4) +#define VUL9_NORMAL_MODE_SFT 3 +#define VUL9_NORMAL_MODE_MASK 0x1 +#define VUL9_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL9_HALIGN_SFT 2 +#define VUL9_HALIGN_MASK 0x1 +#define VUL9_HALIGN_MASK_SFT (0x1 << 2) +#define VUL9_HD_MODE_SFT 0 +#define VUL9_HD_MODE_MASK 0x3 +#define VUL9_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL10_BASE_MSB */ +#define VUL10_BASE_ADDR_MSB_SFT 0 +#define VUL10_BASE_ADDR_MSB_MASK 0x1ff +#define VUL10_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_BASE */ +#define VUL10_BASE_ADDR_SFT 4 +#define VUL10_BASE_ADDR_MASK 0xfffffff +#define VUL10_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL10_CUR_MSB */ +#define VUL10_CUR_PTR_MSB_SFT 0 +#define VUL10_CUR_PTR_MSB_MASK 0x1ff +#define VUL10_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_CUR */ +#define VUL10_CUR_PTR_SFT 0 +#define VUL10_CUR_PTR_MASK 0xffffffff +#define VUL10_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_END_MSB */ +#define VUL10_END_ADDR_MSB_SFT 0 +#define VUL10_END_ADDR_MSB_MASK 0x1ff +#define VUL10_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_END */ +#define VUL10_END_ADDR_SFT 4 +#define VUL10_END_ADDR_MASK 0xfffffff +#define VUL10_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL10_RCH_MON */ +#define VUL10_RCH_DATA_SFT 0 +#define VUL10_RCH_DATA_MASK 0xffffffff +#define VUL10_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_LCH_MON */ +#define VUL10_LCH_DATA_SFT 0 +#define VUL10_LCH_DATA_MASK 0xffffffff +#define VUL10_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_CON0 */ +#define VUL10_ON_SFT 28 +#define VUL10_ON_MASK 0x1 +#define VUL10_ON_MASK_SFT (0x1 << 28) +#define VUL10_MINLEN_SFT 20 +#define VUL10_MINLEN_MASK 0x3 +#define VUL10_MINLEN_MASK_SFT (0x3 << 20) +#define VUL10_MAXLEN_SFT 16 +#define VUL10_MAXLEN_MASK 0x3 +#define VUL10_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL10_SEL_DOMAIN_SFT 13 +#define VUL10_SEL_DOMAIN_MASK 0x7 +#define VUL10_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL10_SEL_FS_SFT 8 +#define VUL10_SEL_FS_MASK 0x1f +#define VUL10_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL10_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL10_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL10_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL10_WR_SIGN_SFT 6 +#define VUL10_WR_SIGN_MASK 0x1 +#define VUL10_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL10_R_MONO_SFT 5 +#define VUL10_R_MONO_MASK 0x1 +#define VUL10_R_MONO_MASK_SFT (0x1 << 5) +#define VUL10_MONO_SFT 4 +#define VUL10_MONO_MASK 0x1 +#define VUL10_MONO_MASK_SFT (0x1 << 4) +#define VUL10_NORMAL_MODE_SFT 3 +#define VUL10_NORMAL_MODE_MASK 0x1 +#define VUL10_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL10_HALIGN_SFT 2 +#define VUL10_HALIGN_MASK 0x1 +#define VUL10_HALIGN_MASK_SFT (0x1 << 2) +#define VUL10_HD_MODE_SFT 0 +#define VUL10_HD_MODE_MASK 0x3 +#define VUL10_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL24_BASE_MSB */ +#define VUL24_BASE_ADDR_MSB_SFT 0 +#define VUL24_BASE_ADDR_MSB_MASK 0x1ff +#define VUL24_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_BASE */ +#define VUL24_BASE_ADDR_SFT 4 +#define VUL24_BASE_ADDR_MASK 0xfffffff +#define VUL24_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL24_CUR_MSB */ +#define VUL24_CUR_PTR_MSB_SFT 0 +#define VUL24_CUR_PTR_MSB_MASK 0x1ff +#define VUL24_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_CUR */ +#define VUL24_CUR_PTR_SFT 0 +#define VUL24_CUR_PTR_MASK 0xffffffff +#define VUL24_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL24_END_MSB */ +#define VUL24_END_ADDR_MSB_SFT 0 +#define VUL24_END_ADDR_MSB_MASK 0x1ff +#define VUL24_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_END */ +#define VUL24_END_ADDR_SFT 4 +#define VUL24_END_ADDR_MASK 0xfffffff +#define VUL24_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL24_CON0 */ +#define OUT_ON_USE_VUL24_SFT 29 +#define OUT_ON_USE_VUL24_MASK 0x1 +#define OUT_ON_USE_VUL24_MASK_SFT (0x1 << 29) +#define VUL24_ON_SFT 28 +#define VUL24_ON_MASK 0x1 +#define VUL24_ON_MASK_SFT (0x1 << 28) +#define VUL24_MINLEN_SFT 20 +#define VUL24_MINLEN_MASK 0x3 +#define VUL24_MINLEN_MASK_SFT (0x3 << 20) +#define VUL24_MAXLEN_SFT 16 +#define VUL24_MAXLEN_MASK 0x3 +#define VUL24_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL24_SEL_DOMAIN_SFT 13 +#define VUL24_SEL_DOMAIN_MASK 0x7 +#define VUL24_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL24_SEL_FS_SFT 8 +#define VUL24_SEL_FS_MASK 0x1f +#define VUL24_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL24_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL24_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL24_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL24_WR_SIGN_SFT 6 +#define VUL24_WR_SIGN_MASK 0x1 +#define VUL24_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL24_R_MONO_SFT 5 +#define VUL24_R_MONO_MASK 0x1 +#define VUL24_R_MONO_MASK_SFT (0x1 << 5) +#define VUL24_MONO_SFT 4 +#define VUL24_MONO_MASK 0x1 +#define VUL24_MONO_MASK_SFT (0x1 << 4) +#define VUL24_NORMAL_MODE_SFT 3 +#define VUL24_NORMAL_MODE_MASK 0x1 +#define VUL24_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL24_HALIGN_SFT 2 +#define VUL24_HALIGN_MASK 0x1 +#define VUL24_HALIGN_MASK_SFT (0x1 << 2) +#define VUL24_HD_MODE_SFT 0 +#define VUL24_HD_MODE_MASK 0x3 +#define VUL24_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL25_BASE_MSB */ +#define VUL25_BASE_ADDR_MSB_SFT 0 +#define VUL25_BASE_ADDR_MSB_MASK 0x1ff +#define VUL25_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_BASE */ +#define VUL25_BASE_ADDR_SFT 4 +#define VUL25_BASE_ADDR_MASK 0xfffffff +#define VUL25_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL25_CUR_MSB */ +#define VUL25_CUR_PTR_MSB_SFT 0 +#define VUL25_CUR_PTR_MSB_MASK 0x1ff +#define VUL25_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_CUR */ +#define VUL25_CUR_PTR_SFT 0 +#define VUL25_CUR_PTR_MASK 0xffffffff +#define VUL25_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_END_MSB */ +#define VUL25_END_ADDR_MSB_SFT 0 +#define VUL25_END_ADDR_MSB_MASK 0x1ff +#define VUL25_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_END */ +#define VUL25_END_ADDR_SFT 4 +#define VUL25_END_ADDR_MASK 0xfffffff +#define VUL25_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL25_CON0 */ +#define OUT_ON_USE_VUL25_SFT 29 +#define OUT_ON_USE_VUL25_MASK 0x1 +#define OUT_ON_USE_VUL25_MASK_SFT (0x1 << 29) +#define VUL25_ON_SFT 28 +#define VUL25_ON_MASK 0x1 +#define VUL25_ON_MASK_SFT (0x1 << 28) +#define VUL25_MINLEN_SFT 20 +#define VUL25_MINLEN_MASK 0x3 +#define VUL25_MINLEN_MASK_SFT (0x3 << 20) +#define VUL25_MAXLEN_SFT 16 +#define VUL25_MAXLEN_MASK 0x3 +#define VUL25_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL25_SEL_DOMAIN_SFT 13 +#define VUL25_SEL_DOMAIN_MASK 0x7 +#define VUL25_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL25_SEL_FS_SFT 8 +#define VUL25_SEL_FS_MASK 0x1f +#define VUL25_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL25_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL25_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL25_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL25_WR_SIGN_SFT 6 +#define VUL25_WR_SIGN_MASK 0x1 +#define VUL25_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL25_R_MONO_SFT 5 +#define VUL25_R_MONO_MASK 0x1 +#define VUL25_R_MONO_MASK_SFT (0x1 << 5) +#define VUL25_MONO_SFT 4 +#define VUL25_MONO_MASK 0x1 +#define VUL25_MONO_MASK_SFT (0x1 << 4) +#define VUL25_NORMAL_MODE_SFT 3 +#define VUL25_NORMAL_MODE_MASK 0x1 +#define VUL25_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL25_HALIGN_SFT 2 +#define VUL25_HALIGN_MASK 0x1 +#define VUL25_HALIGN_MASK_SFT (0x1 << 2) +#define VUL25_HD_MODE_SFT 0 +#define VUL25_HD_MODE_MASK 0x3 +#define VUL25_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL26_BASE_MSB */ +#define VUL26_BASE_ADDR_MSB_SFT 0 +#define VUL26_BASE_ADDR_MSB_MASK 0x1ff +#define VUL26_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL26_BASE */ +#define VUL26_BASE_ADDR_SFT 4 +#define VUL26_BASE_ADDR_MASK 0xfffffff +#define VUL26_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL26_CUR_MSB */ +#define VUL26_CUR_PTR_MSB_SFT 0 +#define VUL26_CUR_PTR_MSB_MASK 0x1ff +#define VUL26_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL26_CUR */ +#define VUL26_CUR_PTR_SFT 0 +#define VUL26_CUR_PTR_MASK 0xffffffff +#define VUL26_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL26_END_MSB */ +#define VUL26_END_ADDR_MSB_SFT 0 +#define VUL26_END_ADDR_MSB_MASK 0x1ff +#define VUL26_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL26_END */ +#define VUL26_END_ADDR_SFT 4 +#define VUL26_END_ADDR_MASK 0xfffffff +#define VUL26_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL26_CON0 */ +#define OUT_ON_USE_VUL26_SFT 29 +#define OUT_ON_USE_VUL26_MASK 0x1 +#define OUT_ON_USE_VUL26_MASK_SFT (0x1 << 29) +#define VUL26_ON_SFT 28 +#define VUL26_ON_MASK 0x1 +#define VUL26_ON_MASK_SFT (0x1 << 28) +#define VUL26_MINLEN_SFT 20 +#define VUL26_MINLEN_MASK 0x3 +#define VUL26_MINLEN_MASK_SFT (0x3 << 20) +#define VUL26_MAXLEN_SFT 16 +#define VUL26_MAXLEN_MASK 0x3 +#define VUL26_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL26_SEL_DOMAIN_SFT 13 +#define VUL26_SEL_DOMAIN_MASK 0x7 +#define VUL26_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL26_SEL_FS_SFT 8 +#define VUL26_SEL_FS_MASK 0x1f +#define VUL26_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL26_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL26_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL26_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL26_WR_SIGN_SFT 6 +#define VUL26_WR_SIGN_MASK 0x1 +#define VUL26_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL26_R_MONO_SFT 5 +#define VUL26_R_MONO_MASK 0x1 +#define VUL26_R_MONO_MASK_SFT (0x1 << 5) +#define VUL26_MONO_SFT 4 +#define VUL26_MONO_MASK 0x1 +#define VUL26_MONO_MASK_SFT (0x1 << 4) +#define VUL26_NORMAL_MODE_SFT 3 +#define VUL26_NORMAL_MODE_MASK 0x1 +#define VUL26_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL26_HALIGN_SFT 2 +#define VUL26_HALIGN_MASK 0x1 +#define VUL26_HALIGN_MASK_SFT (0x1 << 2) +#define VUL26_HD_MODE_SFT 0 +#define VUL26_HD_MODE_MASK 0x3 +#define VUL26_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL_CM0_BASE_MSB */ +#define VUL_CM0_BASE_ADDR_MSB_SFT 0 +#define VUL_CM0_BASE_ADDR_MSB_MASK 0x1ff +#define VUL_CM0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_BASE */ +#define VUL_CM0_BASE_ADDR_SFT 4 +#define VUL_CM0_BASE_ADDR_MASK 0xfffffff +#define VUL_CM0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM0_CUR_MSB */ +#define VUL_CM0_CUR_PTR_MSB_SFT 0 +#define VUL_CM0_CUR_PTR_MSB_MASK 0x1ff +#define VUL_CM0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_CUR */ +#define VUL_CM0_CUR_PTR_SFT 0 +#define VUL_CM0_CUR_PTR_MASK 0xffffffff +#define VUL_CM0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_END_MSB */ +#define VUL_CM0_END_ADDR_MSB_SFT 0 +#define VUL_CM0_END_ADDR_MSB_MASK 0x1ff +#define VUL_CM0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_END */ +#define VUL_CM0_END_ADDR_SFT 4 +#define VUL_CM0_END_ADDR_MASK 0xfffffff +#define VUL_CM0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM0_CON0 */ +#define VUL_CM0_ON_SFT 28 +#define VUL_CM0_ON_MASK 0x1 +#define VUL_CM0_ON_MASK_SFT (0x1 << 28) +#define VUL_CM0_REG_CH_SHIFT_MODE_SFT 26 +#define VUL_CM0_REG_CH_SHIFT_MODE_MASK 0x1 +#define VUL_CM0_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define VUL_CM0_SW_CLEAR_BUF_FULL_SFT 24 +#define VUL_CM0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_CM0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define VUL_CM0_ULTRA_TH_SFT 20 +#define VUL_CM0_ULTRA_TH_MASK 0xf +#define VUL_CM0_ULTRA_TH_MASK_SFT (0xf << 20) +#define VUL_CM0_NORMAL_MODE_SFT 17 +#define VUL_CM0_NORMAL_MODE_MASK 0x1 +#define VUL_CM0_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define VUL_CM0_ODD_USE_EVEN_SFT 16 +#define VUL_CM0_ODD_USE_EVEN_MASK 0x1 +#define VUL_CM0_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define VUL_CM0_AXI_REQ_MAXLEN_SFT 12 +#define VUL_CM0_AXI_REQ_MAXLEN_MASK 0x3 +#define VUL_CM0_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define VUL_CM0_AXI_REQ_MINLEN_SFT 8 +#define VUL_CM0_AXI_REQ_MINLEN_MASK 0x3 +#define VUL_CM0_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define VUL_CM0_HALIGN_SFT 7 +#define VUL_CM0_HALIGN_MASK 0x1 +#define VUL_CM0_HALIGN_MASK_SFT (0x1 << 7) +#define VUL_CM0_SIGN_EXT_SFT 6 +#define VUL_CM0_SIGN_EXT_MASK 0x1 +#define VUL_CM0_SIGN_EXT_MASK_SFT (0x1 << 6) +#define VUL_CM0_HD_MODE_SFT 4 +#define VUL_CM0_HD_MODE_MASK 0x3 +#define VUL_CM0_HD_MODE_MASK_SFT (0x3 << 4) +#define VUL_CM0_MAKE_EXTRA_UPDATE_SFT 3 +#define VUL_CM0_MAKE_EXTRA_UPDATE_MASK 0x1 +#define VUL_CM0_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define VUL_CM0_AGENT_FREE_RUN_SFT 2 +#define VUL_CM0_AGENT_FREE_RUN_MASK 0x1 +#define VUL_CM0_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define VUL_CM0_USE_INT_ODD_SFT 1 +#define VUL_CM0_USE_INT_ODD_MASK 0x1 +#define VUL_CM0_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define VUL_CM0_INT_ODD_FLAG_SFT 0 +#define VUL_CM0_INT_ODD_FLAG_MASK 0x1 +#define VUL_CM0_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_VUL_CM1_BASE_MSB */ +#define VUL_CM1_BASE_ADDR_MSB_SFT 0 +#define VUL_CM1_BASE_ADDR_MSB_MASK 0x1ff +#define VUL_CM1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_BASE */ +#define VUL_CM1_BASE_ADDR_SFT 4 +#define VUL_CM1_BASE_ADDR_MASK 0xfffffff +#define VUL_CM1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM1_CUR_MSB */ +#define VUL_CM1_CUR_PTR_MSB_SFT 0 +#define VUL_CM1_CUR_PTR_MSB_MASK 0x1ff +#define VUL_CM1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_CUR */ +#define VUL_CM1_CUR_PTR_SFT 0 +#define VUL_CM1_CUR_PTR_MASK 0xffffffff +#define VUL_CM1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_END_MSB */ +#define VUL_CM1_END_ADDR_MSB_SFT 0 +#define VUL_CM1_END_ADDR_MSB_MASK 0x1ff +#define VUL_CM1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_END */ +#define VUL_CM1_END_ADDR_SFT 4 +#define VUL_CM1_END_ADDR_MASK 0xfffffff +#define VUL_CM1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM1_CON0 */ +#define VUL_CM1_ON_SFT 28 +#define VUL_CM1_ON_MASK 0x1 +#define VUL_CM1_ON_MASK_SFT (0x1 << 28) +#define VUL_CM1_REG_CH_SHIFT_MODE_SFT 26 +#define VUL_CM1_REG_CH_SHIFT_MODE_MASK 0x1 +#define VUL_CM1_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define VUL_CM1_SW_CLEAR_BUF_FULL_SFT 24 +#define VUL_CM1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_CM1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define VUL_CM1_ULTRA_TH_SFT 20 +#define VUL_CM1_ULTRA_TH_MASK 0xf +#define VUL_CM1_ULTRA_TH_MASK_SFT (0xf << 20) +#define VUL_CM1_NORMAL_MODE_SFT 17 +#define VUL_CM1_NORMAL_MODE_MASK 0x1 +#define VUL_CM1_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define VUL_CM1_ODD_USE_EVEN_SFT 16 +#define VUL_CM1_ODD_USE_EVEN_MASK 0x1 +#define VUL_CM1_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define VUL_CM1_AXI_REQ_MAXLEN_SFT 12 +#define VUL_CM1_AXI_REQ_MAXLEN_MASK 0x3 +#define VUL_CM1_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define VUL_CM1_AXI_REQ_MINLEN_SFT 8 +#define VUL_CM1_AXI_REQ_MINLEN_MASK 0x3 +#define VUL_CM1_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define VUL_CM1_HALIGN_SFT 7 +#define VUL_CM1_HALIGN_MASK 0x1 +#define VUL_CM1_HALIGN_MASK_SFT (0x1 << 7) +#define VUL_CM1_SIGN_EXT_SFT 6 +#define VUL_CM1_SIGN_EXT_MASK 0x1 +#define VUL_CM1_SIGN_EXT_MASK_SFT (0x1 << 6) +#define VUL_CM1_HD_MODE_SFT 4 +#define VUL_CM1_HD_MODE_MASK 0x3 +#define VUL_CM1_HD_MODE_MASK_SFT (0x3 << 4) +#define VUL_CM1_MAKE_EXTRA_UPDATE_SFT 3 +#define VUL_CM1_MAKE_EXTRA_UPDATE_MASK 0x1 +#define VUL_CM1_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define VUL_CM1_AGENT_FREE_RUN_SFT 2 +#define VUL_CM1_AGENT_FREE_RUN_MASK 0x1 +#define VUL_CM1_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define VUL_CM1_USE_INT_ODD_SFT 1 +#define VUL_CM1_USE_INT_ODD_MASK 0x1 +#define VUL_CM1_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define VUL_CM1_INT_ODD_FLAG_SFT 0 +#define VUL_CM1_INT_ODD_FLAG_MASK 0x1 +#define VUL_CM1_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_VUL_CM2_BASE_MSB */ +#define VUL_CM2_BASE_ADDR_MSB_SFT 0 +#define VUL_CM2_BASE_ADDR_MSB_MASK 0x1ff +#define VUL_CM2_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM2_BASE */ +#define VUL_CM2_BASE_ADDR_SFT 4 +#define VUL_CM2_BASE_ADDR_MASK 0xfffffff +#define VUL_CM2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM2_CUR_MSB */ +#define VUL_CM2_CUR_PTR_MSB_SFT 0 +#define VUL_CM2_CUR_PTR_MSB_MASK 0x1ff +#define VUL_CM2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM2_CUR */ +#define VUL_CM2_CUR_PTR_SFT 0 +#define VUL_CM2_CUR_PTR_MASK 0xffffffff +#define VUL_CM2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM2_END_MSB */ +#define VUL_CM2_END_ADDR_MSB_SFT 0 +#define VUL_CM2_END_ADDR_MSB_MASK 0x1ff +#define VUL_CM2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM2_END */ +#define VUL_CM2_END_ADDR_SFT 4 +#define VUL_CM2_END_ADDR_MASK 0xfffffff +#define VUL_CM2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM2_CON0 */ +#define VUL_CM2_ON_SFT 28 +#define VUL_CM2_ON_MASK 0x1 +#define VUL_CM2_ON_MASK_SFT (0x1 << 28) +#define VUL_CM2_REG_CH_SHIFT_MODE_SFT 26 +#define VUL_CM2_REG_CH_SHIFT_MODE_MASK 0x1 +#define VUL_CM2_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define VUL_CM2_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define VUL_CM2_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define VUL_CM2_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define VUL_CM2_SW_CLEAR_BUF_FULL_SFT 24 +#define VUL_CM2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_CM2_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define VUL_CM2_ULTRA_TH_SFT 20 +#define VUL_CM2_ULTRA_TH_MASK 0xf +#define VUL_CM2_ULTRA_TH_MASK_SFT (0xf << 20) +#define VUL_CM2_NORMAL_MODE_SFT 17 +#define VUL_CM2_NORMAL_MODE_MASK 0x1 +#define VUL_CM2_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define VUL_CM2_ODD_USE_EVEN_SFT 16 +#define VUL_CM2_ODD_USE_EVEN_MASK 0x1 +#define VUL_CM2_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define VUL_CM2_AXI_REQ_MAXLEN_SFT 12 +#define VUL_CM2_AXI_REQ_MAXLEN_MASK 0x3 +#define VUL_CM2_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define VUL_CM2_AXI_REQ_MINLEN_SFT 8 +#define VUL_CM2_AXI_REQ_MINLEN_MASK 0x3 +#define VUL_CM2_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define VUL_CM2_HALIGN_SFT 7 +#define VUL_CM2_HALIGN_MASK 0x1 +#define VUL_CM2_HALIGN_MASK_SFT (0x1 << 7) +#define VUL_CM2_SIGN_EXT_SFT 6 +#define VUL_CM2_SIGN_EXT_MASK 0x1 +#define VUL_CM2_SIGN_EXT_MASK_SFT (0x1 << 6) +#define VUL_CM2_HD_MODE_SFT 4 +#define VUL_CM2_HD_MODE_MASK 0x3 +#define VUL_CM2_HD_MODE_MASK_SFT (0x3 << 4) +#define VUL_CM2_MAKE_EXTRA_UPDATE_SFT 3 +#define VUL_CM2_MAKE_EXTRA_UPDATE_MASK 0x1 +#define VUL_CM2_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define VUL_CM2_AGENT_FREE_RUN_SFT 2 +#define VUL_CM2_AGENT_FREE_RUN_MASK 0x1 +#define VUL_CM2_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define VUL_CM2_USE_INT_ODD_SFT 1 +#define VUL_CM2_USE_INT_ODD_MASK 0x1 +#define VUL_CM2_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define VUL_CM2_INT_ODD_FLAG_SFT 0 +#define VUL_CM2_INT_ODD_FLAG_MASK 0x1 +#define VUL_CM2_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN0_BASE_MSB */ +#define ETDM_IN0_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN0_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_BASE */ +#define ETDM_IN0_BASE_ADDR_SFT 4 +#define ETDM_IN0_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN0_CUR_MSB */ +#define ETDM_IN0_CUR_PTR_MSB_SFT 0 +#define ETDM_IN0_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_CUR */ +#define ETDM_IN0_CUR_PTR_SFT 0 +#define ETDM_IN0_CUR_PTR_MASK 0xffffffff +#define ETDM_IN0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN0_END_MSB */ +#define ETDM_IN0_END_ADDR_MSB_SFT 0 +#define ETDM_IN0_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_END */ +#define ETDM_IN0_END_ADDR_SFT 4 +#define ETDM_IN0_END_ADDR_MASK 0xfffffff +#define ETDM_IN0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN0_CON0 */ +#define ETDM_IN0_CH_NUM_SFT 28 +#define ETDM_IN0_CH_NUM_MASK 0xf +#define ETDM_IN0_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN0_ON_SFT 27 +#define ETDM_IN0_ON_MASK 0x1 +#define ETDM_IN0_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN0_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN0_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN0_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN0_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN0_ULTRA_TH_SFT 20 +#define ETDM_IN0_ULTRA_TH_MASK 0xf +#define ETDM_IN0_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN0_NORMAL_MODE_SFT 17 +#define ETDM_IN0_NORMAL_MODE_MASK 0x1 +#define ETDM_IN0_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN0_ODD_USE_EVEN_SFT 16 +#define ETDM_IN0_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN0_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN0_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN0_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN0_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN0_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN0_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN0_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN0_HALIGN_SFT 7 +#define ETDM_IN0_HALIGN_MASK 0x1 +#define ETDM_IN0_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN0_SIGN_EXT_SFT 6 +#define ETDM_IN0_SIGN_EXT_MASK 0x1 +#define ETDM_IN0_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN0_HD_MODE_SFT 4 +#define ETDM_IN0_HD_MODE_MASK 0x3 +#define ETDM_IN0_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN0_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN0_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN0_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN0_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN0_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN0_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN0_USE_INT_ODD_SFT 1 +#define ETDM_IN0_USE_INT_ODD_MASK 0x1 +#define ETDM_IN0_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN0_INT_ODD_FLAG_SFT 0 +#define ETDM_IN0_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN0_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN1_BASE_MSB */ +#define ETDM_IN1_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN1_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_BASE */ +#define ETDM_IN1_BASE_ADDR_SFT 4 +#define ETDM_IN1_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN1_CUR_MSB */ +#define ETDM_IN1_CUR_PTR_MSB_SFT 0 +#define ETDM_IN1_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_CUR */ +#define ETDM_IN1_CUR_PTR_SFT 0 +#define ETDM_IN1_CUR_PTR_MASK 0xffffffff +#define ETDM_IN1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN1_END_MSB */ +#define ETDM_IN1_END_ADDR_MSB_SFT 0 +#define ETDM_IN1_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_END */ +#define ETDM_IN1_END_ADDR_SFT 4 +#define ETDM_IN1_END_ADDR_MASK 0xfffffff +#define ETDM_IN1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN1_CON0 */ +#define ETDM_IN1_CH_NUM_SFT 28 +#define ETDM_IN1_CH_NUM_MASK 0xf +#define ETDM_IN1_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN1_ON_SFT 27 +#define ETDM_IN1_ON_MASK 0x1 +#define ETDM_IN1_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN1_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN1_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN1_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN1_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN1_ULTRA_TH_SFT 20 +#define ETDM_IN1_ULTRA_TH_MASK 0xf +#define ETDM_IN1_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN1_NORMAL_MODE_SFT 17 +#define ETDM_IN1_NORMAL_MODE_MASK 0x1 +#define ETDM_IN1_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN1_ODD_USE_EVEN_SFT 16 +#define ETDM_IN1_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN1_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN1_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN1_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN1_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN1_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN1_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN1_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN1_HALIGN_SFT 7 +#define ETDM_IN1_HALIGN_MASK 0x1 +#define ETDM_IN1_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN1_SIGN_EXT_SFT 6 +#define ETDM_IN1_SIGN_EXT_MASK 0x1 +#define ETDM_IN1_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN1_HD_MODE_SFT 4 +#define ETDM_IN1_HD_MODE_MASK 0x3 +#define ETDM_IN1_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN1_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN1_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN1_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN1_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN1_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN1_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN1_USE_INT_ODD_SFT 1 +#define ETDM_IN1_USE_INT_ODD_MASK 0x1 +#define ETDM_IN1_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN1_INT_ODD_FLAG_SFT 0 +#define ETDM_IN1_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN1_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN2_BASE_MSB */ +#define ETDM_IN2_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN2_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN2_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN2_BASE */ +#define ETDM_IN2_BASE_ADDR_SFT 4 +#define ETDM_IN2_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN2_CUR_MSB */ +#define ETDM_IN2_CUR_PTR_MSB_SFT 0 +#define ETDM_IN2_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN2_CUR */ +#define ETDM_IN2_CUR_PTR_SFT 0 +#define ETDM_IN2_CUR_PTR_MASK 0xffffffff +#define ETDM_IN2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN2_END_MSB */ +#define ETDM_IN2_END_ADDR_MSB_SFT 0 +#define ETDM_IN2_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN2_END */ +#define ETDM_IN2_END_ADDR_SFT 4 +#define ETDM_IN2_END_ADDR_MASK 0xfffffff +#define ETDM_IN2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN2_CON0 */ +#define ETDM_IN2_CH_NUM_SFT 28 +#define ETDM_IN2_CH_NUM_MASK 0xf +#define ETDM_IN2_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN2_ON_SFT 27 +#define ETDM_IN2_ON_MASK 0x1 +#define ETDM_IN2_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN2_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN2_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN2_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN2_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN2_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN2_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN2_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN2_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN2_ULTRA_TH_SFT 20 +#define ETDM_IN2_ULTRA_TH_MASK 0xf +#define ETDM_IN2_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN2_NORMAL_MODE_SFT 17 +#define ETDM_IN2_NORMAL_MODE_MASK 0x1 +#define ETDM_IN2_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN2_ODD_USE_EVEN_SFT 16 +#define ETDM_IN2_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN2_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN2_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN2_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN2_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN2_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN2_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN2_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN2_HALIGN_SFT 7 +#define ETDM_IN2_HALIGN_MASK 0x1 +#define ETDM_IN2_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN2_SIGN_EXT_SFT 6 +#define ETDM_IN2_SIGN_EXT_MASK 0x1 +#define ETDM_IN2_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN2_HD_MODE_SFT 4 +#define ETDM_IN2_HD_MODE_MASK 0x3 +#define ETDM_IN2_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN2_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN2_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN2_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN2_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN2_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN2_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN2_USE_INT_ODD_SFT 1 +#define ETDM_IN2_USE_INT_ODD_MASK 0x1 +#define ETDM_IN2_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN2_INT_ODD_FLAG_SFT 0 +#define ETDM_IN2_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN2_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN3_BASE_MSB */ +#define ETDM_IN3_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN3_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN3_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN3_BASE */ +#define ETDM_IN3_BASE_ADDR_SFT 4 +#define ETDM_IN3_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN3_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN3_CUR_MSB */ +#define ETDM_IN3_CUR_PTR_MSB_SFT 0 +#define ETDM_IN3_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN3_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN3_CUR */ +#define ETDM_IN3_CUR_PTR_SFT 0 +#define ETDM_IN3_CUR_PTR_MASK 0xffffffff +#define ETDM_IN3_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN3_END_MSB */ +#define ETDM_IN3_END_ADDR_MSB_SFT 0 +#define ETDM_IN3_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN3_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN3_END */ +#define ETDM_IN3_END_ADDR_SFT 4 +#define ETDM_IN3_END_ADDR_MASK 0xfffffff +#define ETDM_IN3_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN3_CON0 */ +#define ETDM_IN3_CH_NUM_SFT 28 +#define ETDM_IN3_CH_NUM_MASK 0xf +#define ETDM_IN3_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN3_ON_SFT 27 +#define ETDM_IN3_ON_MASK 0x1 +#define ETDM_IN3_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN3_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN3_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN3_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN3_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN3_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN3_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN3_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN3_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN3_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN3_ULTRA_TH_SFT 20 +#define ETDM_IN3_ULTRA_TH_MASK 0xf +#define ETDM_IN3_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN3_NORMAL_MODE_SFT 17 +#define ETDM_IN3_NORMAL_MODE_MASK 0x1 +#define ETDM_IN3_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN3_ODD_USE_EVEN_SFT 16 +#define ETDM_IN3_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN3_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN3_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN3_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN3_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN3_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN3_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN3_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN3_HALIGN_SFT 7 +#define ETDM_IN3_HALIGN_MASK 0x1 +#define ETDM_IN3_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN3_SIGN_EXT_SFT 6 +#define ETDM_IN3_SIGN_EXT_MASK 0x1 +#define ETDM_IN3_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN3_HD_MODE_SFT 4 +#define ETDM_IN3_HD_MODE_MASK 0x3 +#define ETDM_IN3_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN3_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN3_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN3_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN3_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN3_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN3_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN3_USE_INT_ODD_SFT 1 +#define ETDM_IN3_USE_INT_ODD_MASK 0x1 +#define ETDM_IN3_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN3_INT_ODD_FLAG_SFT 0 +#define ETDM_IN3_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN3_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN4_BASE_MSB */ +#define ETDM_IN4_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN4_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN4_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN4_BASE */ +#define ETDM_IN4_BASE_ADDR_SFT 4 +#define ETDM_IN4_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN4_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN4_CUR_MSB */ +#define ETDM_IN4_CUR_PTR_MSB_SFT 0 +#define ETDM_IN4_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN4_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN4_CUR */ +#define ETDM_IN4_CUR_PTR_SFT 0 +#define ETDM_IN4_CUR_PTR_MASK 0xffffffff +#define ETDM_IN4_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN4_END_MSB */ +#define ETDM_IN4_END_ADDR_MSB_SFT 0 +#define ETDM_IN4_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN4_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN4_END */ +#define ETDM_IN4_END_ADDR_SFT 4 +#define ETDM_IN4_END_ADDR_MASK 0xfffffff +#define ETDM_IN4_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN4_CON0 */ +#define ETDM_IN4_CH_NUM_SFT 28 +#define ETDM_IN4_CH_NUM_MASK 0xf +#define ETDM_IN4_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN4_ON_SFT 27 +#define ETDM_IN4_ON_MASK 0x1 +#define ETDM_IN4_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN4_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN4_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN4_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN4_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN4_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN4_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN4_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN4_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN4_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN4_ULTRA_TH_SFT 20 +#define ETDM_IN4_ULTRA_TH_MASK 0xf +#define ETDM_IN4_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN4_NORMAL_MODE_SFT 17 +#define ETDM_IN4_NORMAL_MODE_MASK 0x1 +#define ETDM_IN4_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN4_ODD_USE_EVEN_SFT 16 +#define ETDM_IN4_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN4_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN4_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN4_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN4_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN4_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN4_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN4_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN4_HALIGN_SFT 7 +#define ETDM_IN4_HALIGN_MASK 0x1 +#define ETDM_IN4_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN4_SIGN_EXT_SFT 6 +#define ETDM_IN4_SIGN_EXT_MASK 0x1 +#define ETDM_IN4_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN4_HD_MODE_SFT 4 +#define ETDM_IN4_HD_MODE_MASK 0x3 +#define ETDM_IN4_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN4_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN4_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN4_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN4_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN4_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN4_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN4_USE_INT_ODD_SFT 1 +#define ETDM_IN4_USE_INT_ODD_MASK 0x1 +#define ETDM_IN4_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN4_INT_ODD_FLAG_SFT 0 +#define ETDM_IN4_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN4_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN5_BASE_MSB */ +#define ETDM_IN5_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN5_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN5_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN5_BASE */ +#define ETDM_IN5_BASE_ADDR_SFT 4 +#define ETDM_IN5_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN5_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN5_CUR_MSB */ +#define ETDM_IN5_CUR_PTR_MSB_SFT 0 +#define ETDM_IN5_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN5_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN5_CUR */ +#define ETDM_IN5_CUR_PTR_SFT 0 +#define ETDM_IN5_CUR_PTR_MASK 0xffffffff +#define ETDM_IN5_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN5_END_MSB */ +#define ETDM_IN5_END_ADDR_MSB_SFT 0 +#define ETDM_IN5_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN5_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN5_END */ +#define ETDM_IN5_END_ADDR_SFT 4 +#define ETDM_IN5_END_ADDR_MASK 0xfffffff +#define ETDM_IN5_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN5_CON0 */ +#define ETDM_IN5_CH_NUM_SFT 28 +#define ETDM_IN5_CH_NUM_MASK 0xf +#define ETDM_IN5_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN5_ON_SFT 27 +#define ETDM_IN5_ON_MASK 0x1 +#define ETDM_IN5_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN5_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN5_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN5_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN5_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN5_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN5_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN5_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN5_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN5_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN5_ULTRA_TH_SFT 20 +#define ETDM_IN5_ULTRA_TH_MASK 0xf +#define ETDM_IN5_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN5_NORMAL_MODE_SFT 17 +#define ETDM_IN5_NORMAL_MODE_MASK 0x1 +#define ETDM_IN5_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN5_ODD_USE_EVEN_SFT 16 +#define ETDM_IN5_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN5_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN5_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN5_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN5_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN5_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN5_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN5_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN5_HALIGN_SFT 7 +#define ETDM_IN5_HALIGN_MASK 0x1 +#define ETDM_IN5_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN5_SIGN_EXT_SFT 6 +#define ETDM_IN5_SIGN_EXT_MASK 0x1 +#define ETDM_IN5_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN5_HD_MODE_SFT 4 +#define ETDM_IN5_HD_MODE_MASK 0x3 +#define ETDM_IN5_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN5_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN5_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN5_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN5_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN5_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN5_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN5_USE_INT_ODD_SFT 1 +#define ETDM_IN5_USE_INT_ODD_MASK 0x1 +#define ETDM_IN5_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN5_INT_ODD_FLAG_SFT 0 +#define ETDM_IN5_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN5_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN6_BASE_MSB */ +#define ETDM_IN6_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN6_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN6_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN6_BASE */ +#define ETDM_IN6_BASE_ADDR_SFT 4 +#define ETDM_IN6_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN6_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN6_CUR_MSB */ +#define ETDM_IN6_CUR_PTR_MSB_SFT 0 +#define ETDM_IN6_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN6_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN6_CUR */ +#define ETDM_IN6_CUR_PTR_SFT 0 +#define ETDM_IN6_CUR_PTR_MASK 0xffffffff +#define ETDM_IN6_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN6_END_MSB */ +#define ETDM_IN6_END_ADDR_MSB_SFT 0 +#define ETDM_IN6_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN6_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN6_END */ +#define ETDM_IN6_END_ADDR_SFT 4 +#define ETDM_IN6_END_ADDR_MASK 0xfffffff +#define ETDM_IN6_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN6_CON0 */ +#define ETDM_IN6_CH_NUM_SFT 28 +#define ETDM_IN6_CH_NUM_MASK 0xf +#define ETDM_IN6_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN6_ON_SFT 27 +#define ETDM_IN6_ON_MASK 0x1 +#define ETDM_IN6_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN6_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN6_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN6_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN6_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN6_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN6_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN6_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN6_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN6_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN6_ULTRA_TH_SFT 20 +#define ETDM_IN6_ULTRA_TH_MASK 0xf +#define ETDM_IN6_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN6_NORMAL_MODE_SFT 17 +#define ETDM_IN6_NORMAL_MODE_MASK 0x1 +#define ETDM_IN6_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN6_ODD_USE_EVEN_SFT 16 +#define ETDM_IN6_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN6_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN6_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN6_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN6_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN6_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN6_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN6_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN6_HALIGN_SFT 7 +#define ETDM_IN6_HALIGN_MASK 0x1 +#define ETDM_IN6_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN6_SIGN_EXT_SFT 6 +#define ETDM_IN6_SIGN_EXT_MASK 0x1 +#define ETDM_IN6_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN6_HD_MODE_SFT 4 +#define ETDM_IN6_HD_MODE_MASK 0x3 +#define ETDM_IN6_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN6_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN6_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN6_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN6_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN6_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN6_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN6_USE_INT_ODD_SFT 1 +#define ETDM_IN6_USE_INT_ODD_MASK 0x1 +#define ETDM_IN6_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN6_INT_ODD_FLAG_SFT 0 +#define ETDM_IN6_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN6_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_HDMI_OUT_BASE_MSB */ +#define AFE_HDMI_OUT_BASE_MSB_SFT 0 +#define AFE_HDMI_OUT_BASE_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_BASE_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_BASE */ +#define AFE_HDMI_OUT_BASE_SFT 4 +#define AFE_HDMI_OUT_BASE_MASK 0xfffffff +#define AFE_HDMI_OUT_BASE_MASK_SFT (0xfffffff << 4) + +/* AFE_HDMI_OUT_CUR_MSB */ +#define AFE_HDMI_OUT_CUR_MSB_SFT 0 +#define AFE_HDMI_OUT_CUR_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_CUR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_CUR */ +#define AFE_HDMI_OUT_CUR_SFT 0 +#define AFE_HDMI_OUT_CUR_MASK 0xffffffff +#define AFE_HDMI_OUT_CUR_MASK_SFT (0xffffffff << 0) + +/* AFE_HDMI_OUT_END_MSB */ +#define AFE_HDMI_OUT_END_MSB_SFT 0 +#define AFE_HDMI_OUT_END_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_END_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_END */ +#define AFE_HDMI_OUT_END_SFT 4 +#define AFE_HDMI_OUT_END_MASK 0xfffffff +#define AFE_HDMI_OUT_END_MASK_SFT (0xfffffff << 4) +#define AFE_HDMI_OUT_END_LSB_SFT 0 +#define AFE_HDMI_OUT_END_LSB_MASK 0xf +#define AFE_HDMI_OUT_END_LSB_MASK_SFT (0xf << 0) + +/* AFE_HDMI_OUT_CON0 */ +#define HDMI_OUT_ON_SFT 28 +#define HDMI_OUT_ON_MASK 0x1 +#define HDMI_OUT_ON_MASK_SFT (0x1 << 28) +#define HDMI_CH_NUM_SFT 24 +#define HDMI_CH_NUM_MASK 0xf +#define HDMI_CH_NUM_MASK_SFT (0xf << 24) +#define HDMI_OUT_ONE_HEART_SEL_SFT 22 +#define HDMI_OUT_ONE_HEART_SEL_MASK 0x3 +#define HDMI_OUT_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define HDMI_OUT_MINLEN_SFT 20 +#define HDMI_OUT_MINLEN_MASK 0x3 +#define HDMI_OUT_MINLEN_MASK_SFT (0x3 << 20) +#define HDMI_OUT_MAXLEN_SFT 16 +#define HDMI_OUT_MAXLEN_MASK 0x3 +#define HDMI_OUT_MAXLEN_MASK_SFT (0x3 << 16) +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_SFT 15 +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 15) +#define HDMI_OUT_PBUF_SIZE_SFT 12 +#define HDMI_OUT_PBUF_SIZE_MASK 0x3 +#define HDMI_OUT_PBUF_SIZE_MASK_SFT (0x3 << 12) +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_SFT 7 +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_MASK 0x1 +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define HDMI_OUT_NORMAL_MODE_SFT 5 +#define HDMI_OUT_NORMAL_MODE_MASK 0x1 +#define HDMI_OUT_NORMAL_MODE_MASK_SFT (0x1 << 5) +#define HDMI_OUT_HALIGN_SFT 4 +#define HDMI_OUT_HALIGN_MASK 0x1 +#define HDMI_OUT_HALIGN_MASK_SFT (0x1 << 4) +#define HDMI_OUT_HD_MODE_SFT 0 +#define HDMI_OUT_HD_MODE_MASK 0x3 +#define HDMI_OUT_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL24_RCH_MON */ +#define VUL24_RCH_DATA_SFT 0 +#define VUL24_RCH_DATA_MASK 0xffffffff +#define VUL24_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL24_LCH_MON */ +#define VUL24_LCH_DATA_SFT 0 +#define VUL24_LCH_DATA_MASK 0xffffffff +#define VUL24_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_RCH_MON */ +#define VUL25_RCH_DATA_SFT 0 +#define VUL25_RCH_DATA_MASK 0xffffffff +#define VUL25_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_LCH_MON */ +#define VUL25_LCH_DATA_SFT 0 +#define VUL25_LCH_DATA_MASK 0xffffffff +#define VUL25_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL26_RCH_MON */ +#define VUL26_RCH_DATA_SFT 0 +#define VUL26_RCH_DATA_MASK 0xffffffff +#define VUL26_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL26_LCH_MON */ +#define VUL26_LCH_DATA_SFT 0 +#define VUL26_LCH_DATA_MASK 0xffffffff +#define VUL26_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_RCH_MON */ +#define VUL_CM0_RCH_DATA_SFT 0 +#define VUL_CM0_RCH_DATA_MASK 0xffffffff +#define VUL_CM0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_LCH_MON */ +#define VUL_CM0_LCH_DATA_SFT 0 +#define VUL_CM0_LCH_DATA_MASK 0xffffffff +#define VUL_CM0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_RCH_MON */ +#define VUL_CM1_RCH_DATA_SFT 0 +#define VUL_CM1_RCH_DATA_MASK 0xffffffff +#define VUL_CM1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_LCH_MON */ +#define VUL_CM1_LCH_DATA_SFT 0 +#define VUL_CM1_LCH_DATA_MASK 0xffffffff +#define VUL_CM1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM2_RCH_MON */ +#define VUL_CM2_RCH_DATA_SFT 0 +#define VUL_CM2_RCH_DATA_MASK 0xffffffff +#define VUL_CM2_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM2_LCH_MON */ +#define VUL_CM2_LCH_DATA_SFT 0 +#define VUL_CM2_LCH_DATA_MASK 0xffffffff +#define VUL_CM2_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_4CH_CH0_MON */ +#define DL_4CH_CH0_DATA_SFT 0 +#define DL_4CH_CH0_DATA_MASK 0xffffffff +#define DL_4CH_CH0_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_4CH_CH1_MON */ +#define DL_4CH_CH1_DATA_SFT 0 +#define DL_4CH_CH1_DATA_MASK 0xffffffff +#define DL_4CH_CH1_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_4CH_CH2_MON */ +#define DL_4CH_CH2_DATA_SFT 0 +#define DL_4CH_CH2_DATA_MASK 0xffffffff +#define DL_4CH_CH2_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_4CH_CH3_MON */ +#define DL_4CH_CH3_DATA_SFT 0 +#define DL_4CH_CH3_DATA_MASK 0xffffffff +#define DL_4CH_CH3_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH0_MON */ +#define DL_24CH_CH0_DATA_SFT 0 +#define DL_24CH_CH0_DATA_MASK 0xffffffff +#define DL_24CH_CH0_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH1_MON */ +#define DL_24CH_CH1_DATA_SFT 0 +#define DL_24CH_CH1_DATA_MASK 0xffffffff +#define DL_24CH_CH1_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH2_MON */ +#define DL_24CH_CH2_DATA_SFT 0 +#define DL_24CH_CH2_DATA_MASK 0xffffffff +#define DL_24CH_CH2_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH3_MON */ +#define DL_24CH_CH3_DATA_SFT 0 +#define DL_24CH_CH3_DATA_MASK 0xffffffff +#define DL_24CH_CH3_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH4_MON */ +#define DL_24CH_CH4_DATA_SFT 0 +#define DL_24CH_CH4_DATA_MASK 0xffffffff +#define DL_24CH_CH4_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH5_MON */ +#define DL_24CH_CH5_DATA_SFT 0 +#define DL_24CH_CH5_DATA_MASK 0xffffffff +#define DL_24CH_CH5_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH6_MON */ +#define DL_24CH_CH6_DATA_SFT 0 +#define DL_24CH_CH6_DATA_MASK 0xffffffff +#define DL_24CH_CH6_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH7_MON */ +#define DL_24CH_CH7_DATA_SFT 0 +#define DL_24CH_CH7_DATA_MASK 0xffffffff +#define DL_24CH_CH7_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH8_MON */ +#define DL_24CH_CH8_DATA_SFT 0 +#define DL_24CH_CH8_DATA_MASK 0xffffffff +#define DL_24CH_CH8_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH9_MON */ +#define DL_24CH_CH9_DATA_SFT 0 +#define DL_24CH_CH9_DATA_MASK 0xffffffff +#define DL_24CH_CH9_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH10_MON */ +#define DL_24CH_CH10_DATA_SFT 0 +#define DL_24CH_CH10_DATA_MASK 0xffffffff +#define DL_24CH_CH10_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH11_MON */ +#define DL_24CH_CH11_DATA_SFT 0 +#define DL_24CH_CH11_DATA_MASK 0xffffffff +#define DL_24CH_CH11_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH12_MON */ +#define DL_24CH_CH12_DATA_SFT 0 +#define DL_24CH_CH12_DATA_MASK 0xffffffff +#define DL_24CH_CH12_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH13_MON */ +#define DL_24CH_CH13_DATA_SFT 0 +#define DL_24CH_CH13_DATA_MASK 0xffffffff +#define DL_24CH_CH13_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH14_MON */ +#define DL_24CH_CH14_DATA_SFT 0 +#define DL_24CH_CH14_DATA_MASK 0xffffffff +#define DL_24CH_CH14_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH15_MON */ +#define DL_24CH_CH15_DATA_SFT 0 +#define DL_24CH_CH15_DATA_MASK 0xffffffff +#define DL_24CH_CH15_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_SRAM_BOUND */ +#define SECURE_BIT_SFT 19 +#define SECURE_BIT_MASK 0x1 +#define SECURE_BIT_MASK_SFT (0x1 << 19) +#define SECURE_SRAM_BOUND_SFT 0 +#define SECURE_SRAM_BOUND_MASK 0x7ffff +#define SECURE_SRAM_BOUND_MASK_SFT (0x7ffff << 0) + +/* AFE_SECURE_CON0 */ +#define READ_EN15_NS_SFT 31 +#define READ_EN15_NS_MASK 0x1 +#define READ_EN15_NS_MASK_SFT (0x1 << 31) +#define WRITE_EN15_NS_SFT 30 +#define WRITE_EN15_NS_MASK 0x1 +#define WRITE_EN15_NS_MASK_SFT (0x1 << 30) +#define READ_EN14_NS_SFT 29 +#define READ_EN14_NS_MASK 0x1 +#define READ_EN14_NS_MASK_SFT (0x1 << 29) +#define WRITE_EN14_NS_SFT 28 +#define WRITE_EN14_NS_MASK 0x1 +#define WRITE_EN14_NS_MASK_SFT (0x1 << 28) +#define READ_EN13_NS_SFT 27 +#define READ_EN13_NS_MASK 0x1 +#define READ_EN13_NS_MASK_SFT (0x1 << 27) +#define WRITE_EN13_NS_SFT 26 +#define WRITE_EN13_NS_MASK 0x1 +#define WRITE_EN13_NS_MASK_SFT (0x1 << 26) +#define READ_EN12_NS_SFT 25 +#define READ_EN12_NS_MASK 0x1 +#define READ_EN12_NS_MASK_SFT (0x1 << 25) +#define WRITE_EN12_NS_SFT 24 +#define WRITE_EN12_NS_MASK 0x1 +#define WRITE_EN12_NS_MASK_SFT (0x1 << 24) +#define READ_EN11_NS_SFT 23 +#define READ_EN11_NS_MASK 0x1 +#define READ_EN11_NS_MASK_SFT (0x1 << 23) +#define WRITE_EN11_NS_SFT 22 +#define WRITE_EN11_NS_MASK 0x1 +#define WRITE_EN11_NS_MASK_SFT (0x1 << 22) +#define READ_EN10_NS_SFT 21 +#define READ_EN10_NS_MASK 0x1 +#define READ_EN10_NS_MASK_SFT (0x1 << 21) +#define WRITE_EN10_NS_SFT 20 +#define WRITE_EN10_NS_MASK 0x1 +#define WRITE_EN10_NS_MASK_SFT (0x1 << 20) +#define READ_EN9_NS_SFT 19 +#define READ_EN9_NS_MASK 0x1 +#define READ_EN9_NS_MASK_SFT (0x1 << 19) +#define WRITE_EN9_NS_SFT 18 +#define WRITE_EN9_NS_MASK 0x1 +#define WRITE_EN9_NS_MASK_SFT (0x1 << 18) +#define READ_EN8_NS_SFT 17 +#define READ_EN8_NS_MASK 0x1 +#define READ_EN8_NS_MASK_SFT (0x1 << 17) +#define WRITE_EN8_NS_SFT 16 +#define WRITE_EN8_NS_MASK 0x1 +#define WRITE_EN8_NS_MASK_SFT (0x1 << 16) +#define READ_EN7_NS_SFT 15 +#define READ_EN7_NS_MASK 0x1 +#define READ_EN7_NS_MASK_SFT (0x1 << 15) +#define WRITE_EN7_NS_SFT 14 +#define WRITE_EN7_NS_MASK 0x1 +#define WRITE_EN7_NS_MASK_SFT (0x1 << 14) +#define READ_EN6_NS_SFT 13 +#define READ_EN6_NS_MASK 0x1 +#define READ_EN6_NS_MASK_SFT (0x1 << 13) +#define WRITE_EN6_NS_SFT 12 +#define WRITE_EN6_NS_MASK 0x1 +#define WRITE_EN6_NS_MASK_SFT (0x1 << 12) +#define READ_EN5_NS_SFT 11 +#define READ_EN5_NS_MASK 0x1 +#define READ_EN5_NS_MASK_SFT (0x1 << 11) +#define WRITE_EN5_NS_SFT 10 +#define WRITE_EN5_NS_MASK 0x1 +#define WRITE_EN5_NS_MASK_SFT (0x1 << 10) +#define READ_EN4_NS_SFT 9 +#define READ_EN4_NS_MASK 0x1 +#define READ_EN4_NS_MASK_SFT (0x1 << 9) +#define WRITE_EN4_NS_SFT 8 +#define WRITE_EN4_NS_MASK 0x1 +#define WRITE_EN4_NS_MASK_SFT (0x1 << 8) +#define READ_EN3_NS_SFT 7 +#define READ_EN3_NS_MASK 0x1 +#define READ_EN3_NS_MASK_SFT (0x1 << 7) +#define WRITE_EN3_NS_SFT 6 +#define WRITE_EN3_NS_MASK 0x1 +#define WRITE_EN3_NS_MASK_SFT (0x1 << 6) +#define READ_EN2_NS_SFT 5 +#define READ_EN2_NS_MASK 0x1 +#define READ_EN2_NS_MASK_SFT (0x1 << 5) +#define WRITE_EN2_NS_SFT 4 +#define WRITE_EN2_NS_MASK 0x1 +#define WRITE_EN2_NS_MASK_SFT (0x1 << 4) +#define READ_EN1_NS_SFT 3 +#define READ_EN1_NS_MASK 0x1 +#define READ_EN1_NS_MASK_SFT (0x1 << 3) +#define WRITE_EN1_NS_SFT 2 +#define WRITE_EN1_NS_MASK 0x1 +#define WRITE_EN1_NS_MASK_SFT (0x1 << 2) +#define READ_EN0_NS_SFT 1 +#define READ_EN0_NS_MASK 0x1 +#define READ_EN0_NS_MASK_SFT (0x1 << 1) +#define WRITE_EN0_NS_SFT 0 +#define WRITE_EN0_NS_MASK 0x1 +#define WRITE_EN0_NS_MASK_SFT (0x1 << 0) + +/* AFE_SECURE_CON1 */ +#define READ_EN15_S_SFT 31 +#define READ_EN15_S_MASK 0x1 +#define READ_EN15_S_MASK_SFT (0x1 << 31) +#define WRITE_EN15_S_SFT 30 +#define WRITE_EN15_S_MASK 0x1 +#define WRITE_EN15_S_MASK_SFT (0x1 << 30) +#define READ_EN14_S_SFT 29 +#define READ_EN14_S_MASK 0x1 +#define READ_EN14_S_MASK_SFT (0x1 << 29) +#define WRITE_EN14_S_SFT 28 +#define WRITE_EN14_S_MASK 0x1 +#define WRITE_EN14_S_MASK_SFT (0x1 << 28) +#define READ_EN13_S_SFT 27 +#define READ_EN13_S_MASK 0x1 +#define READ_EN13_S_MASK_SFT (0x1 << 27) +#define WRITE_EN13_S_SFT 26 +#define WRITE_EN13_S_MASK 0x1 +#define WRITE_EN13_S_MASK_SFT (0x1 << 26) +#define READ_EN12_S_SFT 25 +#define READ_EN12_S_MASK 0x1 +#define READ_EN12_S_MASK_SFT (0x1 << 25) +#define WRITE_EN12_S_SFT 24 +#define WRITE_EN12_S_MASK 0x1 +#define WRITE_EN12_S_MASK_SFT (0x1 << 24) +#define READ_EN11_S_SFT 23 +#define READ_EN11_S_MASK 0x1 +#define READ_EN11_S_MASK_SFT (0x1 << 23) +#define WRITE_EN11_S_SFT 22 +#define WRITE_EN11_S_MASK 0x1 +#define WRITE_EN11_S_MASK_SFT (0x1 << 22) +#define READ_EN10_S_SFT 21 +#define READ_EN10_S_MASK 0x1 +#define READ_EN10_S_MASK_SFT (0x1 << 21) +#define WRITE_EN10_S_SFT 20 +#define WRITE_EN10_S_MASK 0x1 +#define WRITE_EN10_S_MASK_SFT (0x1 << 20) +#define READ_EN9_S_SFT 19 +#define READ_EN9_S_MASK 0x1 +#define READ_EN9_S_MASK_SFT (0x1 << 19) +#define WRITE_EN9_S_SFT 18 +#define WRITE_EN9_S_MASK 0x1 +#define WRITE_EN9_S_MASK_SFT (0x1 << 18) +#define READ_EN8_S_SFT 17 +#define READ_EN8_S_MASK 0x1 +#define READ_EN8_S_MASK_SFT (0x1 << 17) +#define WRITE_EN8_S_SFT 16 +#define WRITE_EN8_S_MASK 0x1 +#define WRITE_EN8_S_MASK_SFT (0x1 << 16) +#define READ_EN7_S_SFT 15 +#define READ_EN7_S_MASK 0x1 +#define READ_EN7_S_MASK_SFT (0x1 << 15) +#define WRITE_EN7_S_SFT 14 +#define WRITE_EN7_S_MASK 0x1 +#define WRITE_EN7_S_MASK_SFT (0x1 << 14) +#define READ_EN6_S_SFT 13 +#define READ_EN6_S_MASK 0x1 +#define READ_EN6_S_MASK_SFT (0x1 << 13) +#define WRITE_EN6_S_SFT 12 +#define WRITE_EN6_S_MASK 0x1 +#define WRITE_EN6_S_MASK_SFT (0x1 << 12) +#define READ_EN5_S_SFT 11 +#define READ_EN5_S_MASK 0x1 +#define READ_EN5_S_MASK_SFT (0x1 << 11) +#define WRITE_EN5_S_SFT 10 +#define WRITE_EN5_S_MASK 0x1 +#define WRITE_EN5_S_MASK_SFT (0x1 << 10) +#define READ_EN4_S_SFT 9 +#define READ_EN4_S_MASK 0x1 +#define READ_EN4_S_MASK_SFT (0x1 << 9) +#define WRITE_EN4_S_SFT 8 +#define WRITE_EN4_S_MASK 0x1 +#define WRITE_EN4_S_MASK_SFT (0x1 << 8) +#define READ_EN3_S_SFT 7 +#define READ_EN3_S_MASK 0x1 +#define READ_EN3_S_MASK_SFT (0x1 << 7) +#define WRITE_EN3_S_SFT 6 +#define WRITE_EN3_S_MASK 0x1 +#define WRITE_EN3_S_MASK_SFT (0x1 << 6) +#define READ_EN2_S_SFT 5 +#define READ_EN2_S_MASK 0x1 +#define READ_EN2_S_MASK_SFT (0x1 << 5) +#define WRITE_EN2_S_SFT 4 +#define WRITE_EN2_S_MASK 0x1 +#define WRITE_EN2_S_MASK_SFT (0x1 << 4) +#define READ_EN1_S_SFT 3 +#define READ_EN1_S_MASK 0x1 +#define READ_EN1_S_MASK_SFT (0x1 << 3) +#define WRITE_EN1_S_SFT 2 +#define WRITE_EN1_S_MASK 0x1 +#define WRITE_EN1_S_MASK_SFT (0x1 << 2) +#define READ_EN0_S_SFT 1 +#define READ_EN0_S_MASK 0x1 +#define READ_EN0_S_MASK_SFT (0x1 << 1) +#define WRITE_EN0_S_SFT 0 +#define WRITE_EN0_S_MASK 0x1 +#define WRITE_EN0_S_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON0 */ +#define AFE_HDMI_SE_SECURE_BIT_SFT 11 +#define AFE_HDMI_SE_SECURE_BIT_MASK 0x1 +#define AFE_HDMI_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_SFT 10 +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_SPDIF_OUT_SE_SECURE_BIT_SFT 9 +#define AFE_SPDIF_OUT_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIF_OUT_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_DL8_SE_SECURE_BIT_SFT 8 +#define AFE_DL8_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL8_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_DL7_SE_SECURE_BIT_SFT 7 +#define AFE_DL7_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL7_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_DL6_SE_SECURE_BIT_SFT 6 +#define AFE_DL6_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL6_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_DL5_SE_SECURE_BIT_SFT 5 +#define AFE_DL5_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL5_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_DL4_SE_SECURE_BIT_SFT 4 +#define AFE_DL4_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL4_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_DL3_SE_SECURE_BIT_SFT 3 +#define AFE_DL3_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL3_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_DL2_SE_SECURE_BIT_SFT 2 +#define AFE_DL2_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL2_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_DL1_SE_SECURE_BIT_SFT 1 +#define AFE_DL1_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_DL0_SE_SECURE_BIT_SFT 0 +#define AFE_DL0_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON1 */ +#define AFE_DL46_SE_SECURE_BIT_SFT 26 +#define AFE_DL46_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL46_SE_SECURE_BIT_MASK_SFT (0x1 << 26) +#define AFE_DL45_SE_SECURE_BIT_SFT 25 +#define AFE_DL45_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL45_SE_SECURE_BIT_MASK_SFT (0x1 << 25) +#define AFE_DL44_SE_SECURE_BIT_SFT 24 +#define AFE_DL44_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL44_SE_SECURE_BIT_MASK_SFT (0x1 << 24) +#define AFE_DL43_SE_SECURE_BIT_SFT 23 +#define AFE_DL43_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL43_SE_SECURE_BIT_MASK_SFT (0x1 << 23) +#define AFE_DL42_SE_SECURE_BIT_SFT 22 +#define AFE_DL42_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL42_SE_SECURE_BIT_MASK_SFT (0x1 << 22) +#define AFE_DL41_SE_SECURE_BIT_SFT 21 +#define AFE_DL41_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL41_SE_SECURE_BIT_MASK_SFT (0x1 << 21) +#define AFE_DL40_SE_SECURE_BIT_SFT 20 +#define AFE_DL40_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL40_SE_SECURE_BIT_MASK_SFT (0x1 << 20) +#define AFE_DL39_SE_SECURE_BIT_SFT 19 +#define AFE_DL39_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL39_SE_SECURE_BIT_MASK_SFT (0x1 << 19) +#define AFE_DL38_SE_SECURE_BIT_SFT 18 +#define AFE_DL38_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL38_SE_SECURE_BIT_MASK_SFT (0x1 << 18) +#define AFE_DL37_SE_SECURE_BIT_SFT 17 +#define AFE_DL37_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL37_SE_SECURE_BIT_MASK_SFT (0x1 << 17) +#define AFE_DL36_SE_SECURE_BIT_SFT 16 +#define AFE_DL36_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL36_SE_SECURE_BIT_MASK_SFT (0x1 << 16) +#define AFE_DL35_SE_SECURE_BIT_SFT 15 +#define AFE_DL35_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL35_SE_SECURE_BIT_MASK_SFT (0x1 << 15) +#define AFE_DL34_SE_SECURE_BIT_SFT 14 +#define AFE_DL34_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL34_SE_SECURE_BIT_MASK_SFT (0x1 << 14) +#define AFE_DL33_SE_SECURE_BIT_SFT 13 +#define AFE_DL33_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL33_SE_SECURE_BIT_MASK_SFT (0x1 << 13) +#define AFE_DL32_SE_SECURE_BIT_SFT 12 +#define AFE_DL32_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL32_SE_SECURE_BIT_MASK_SFT (0x1 << 12) +#define AFE_DL31_SE_SECURE_BIT_SFT 11 +#define AFE_DL31_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL31_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_DL30_SE_SECURE_BIT_SFT 10 +#define AFE_DL30_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL30_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_DL29_SE_SECURE_BIT_SFT 9 +#define AFE_DL29_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL29_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_DL28_SE_SECURE_BIT_SFT 8 +#define AFE_DL28_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL28_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_DL27_SE_SECURE_BIT_SFT 7 +#define AFE_DL27_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL27_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_DL26_SE_SECURE_BIT_SFT 6 +#define AFE_DL26_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL26_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_DL25_SE_SECURE_BIT_SFT 5 +#define AFE_DL25_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL25_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_DL24_SE_SECURE_BIT_SFT 4 +#define AFE_DL24_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL24_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_DL23_SE_SECURE_BIT_SFT 3 +#define AFE_DL23_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL23_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_DL_48CH_SE_SECURE_BIT_SFT 2 +#define AFE_DL_48CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_48CH_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_DL_24CH_SE_SECURE_BIT_SFT 1 +#define AFE_DL_24CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_24CH_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_DL_4CH_SE_SECURE_BIT_SFT 0 +#define AFE_DL_4CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_4CH_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON2 */ +#define AFE_VUL38_SE_SECURE_BIT_SFT 28 +#define AFE_VUL38_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL38_SE_SECURE_BIT_MASK_SFT (0x1 << 28) +#define AFE_VUL37_SE_SECURE_BIT_SFT 27 +#define AFE_VUL37_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL37_SE_SECURE_BIT_MASK_SFT (0x1 << 27) +#define AFE_VUL36_SE_SECURE_BIT_SFT 26 +#define AFE_VUL36_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL36_SE_SECURE_BIT_MASK_SFT (0x1 << 26) +#define AFE_VUL35_SE_SECURE_BIT_SFT 25 +#define AFE_VUL35_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL35_SE_SECURE_BIT_MASK_SFT (0x1 << 25) +#define AFE_VUL34_SE_SECURE_BIT_SFT 24 +#define AFE_VUL34_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL34_SE_SECURE_BIT_MASK_SFT (0x1 << 24) +#define AFE_VUL33_SE_SECURE_BIT_SFT 23 +#define AFE_VUL33_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL33_SE_SECURE_BIT_MASK_SFT (0x1 << 23) +#define AFE_VUL32_SE_SECURE_BIT_SFT 22 +#define AFE_VUL32_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL32_SE_SECURE_BIT_MASK_SFT (0x1 << 22) +#define AFE_VUL31_SE_SECURE_BIT_SFT 21 +#define AFE_VUL31_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL31_SE_SECURE_BIT_MASK_SFT (0x1 << 21) +#define AFE_VUL30_SE_SECURE_BIT_SFT 20 +#define AFE_VUL30_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL30_SE_SECURE_BIT_MASK_SFT (0x1 << 20) +#define AFE_VUL29_SE_SECURE_BIT_SFT 19 +#define AFE_VUL29_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL29_SE_SECURE_BIT_MASK_SFT (0x1 << 19) +#define AFE_VUL28_SE_SECURE_BIT_SFT 18 +#define AFE_VUL28_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL28_SE_SECURE_BIT_MASK_SFT (0x1 << 18) +#define AFE_VUL27_SE_SECURE_BIT_SFT 17 +#define AFE_VUL27_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL27_SE_SECURE_BIT_MASK_SFT (0x1 << 17) +#define AFE_VUL26_SE_SECURE_BIT_SFT 16 +#define AFE_VUL26_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL26_SE_SECURE_BIT_MASK_SFT (0x1 << 16) +#define AFE_VUL25_SE_SECURE_BIT_SFT 15 +#define AFE_VUL25_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL25_SE_SECURE_BIT_MASK_SFT (0x1 << 15) +#define AFE_VUL24_SE_SECURE_BIT_SFT 14 +#define AFE_VUL24_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL24_SE_SECURE_BIT_MASK_SFT (0x1 << 14) +#define AFE_VUL_CM2_SE_SECURE_BIT_SFT 13 +#define AFE_VUL_CM2_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM2_SE_SECURE_BIT_MASK_SFT (0x1 << 13) +#define AFE_VUL_CM1_SE_SECURE_BIT_SFT 12 +#define AFE_VUL_CM1_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM1_SE_SECURE_BIT_MASK_SFT (0x1 << 12) +#define AFE_VUL_CM0_SE_SECURE_BIT_SFT 11 +#define AFE_VUL_CM0_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM0_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_VUL10_SE_SECURE_BIT_SFT 10 +#define AFE_VUL10_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL10_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_VUL9_SE_SECURE_BIT_SFT 9 +#define AFE_VUL9_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL9_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_VUL8_SE_SECURE_BIT_SFT 8 +#define AFE_VUL8_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL8_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_VUL7_SE_SECURE_BIT_SFT 7 +#define AFE_VUL7_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL7_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_VUL6_SE_SECURE_BIT_SFT 6 +#define AFE_VUL6_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL6_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_VUL5_SE_SECURE_BIT_SFT 5 +#define AFE_VUL5_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL5_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_VUL4_SE_SECURE_BIT_SFT 4 +#define AFE_VUL4_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL4_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_VUL3_SE_SECURE_BIT_SFT 3 +#define AFE_VUL3_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL3_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_VUL2_SE_SECURE_BIT_SFT 2 +#define AFE_VUL2_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL2_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_VUL1_SE_SECURE_BIT_SFT 1 +#define AFE_VUL1_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_VUL0_SE_SECURE_BIT_SFT 0 +#define AFE_VUL0_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON3 */ +#define AFE_SPDIFIN_SE_SECURE_BIT_SFT 10 +#define AFE_SPDIFIN_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIFIN_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_TDM_IN_SE_SECURE_BIT_SFT 9 +#define AFE_TDM_IN_SE_SECURE_BIT_MASK 0x1 +#define AFE_TDM_IN_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_MPHONE_EARC_SE_SECURE_BIT_SFT 8 +#define AFE_MPHONE_EARC_SE_SECURE_BIT_MASK 0x1 +#define AFE_MPHONE_EARC_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_SFT 7 +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_MASK 0x1 +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_ETDM_IN6_SE_SECURE_BIT_SFT 6 +#define AFE_ETDM_IN6_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN6_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_ETDM_IN5_SE_SECURE_BIT_SFT 5 +#define AFE_ETDM_IN5_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN5_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_ETDM_IN4_SE_SECURE_BIT_SFT 4 +#define AFE_ETDM_IN4_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN4_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_ETDM_IN3_SE_SECURE_BIT_SFT 3 +#define AFE_ETDM_IN3_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN3_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_ETDM_IN2_SE_SECURE_BIT_SFT 2 +#define AFE_ETDM_IN2_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN2_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_ETDM_IN1_SE_SECURE_BIT_SFT 1 +#define AFE_ETDM_IN1_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_ETDM_IN0_SE_SECURE_BIT_SFT 0 +#define AFE_ETDM_IN0_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND0 */ +#define HDMI_HPROT_SFT 11 +#define HDMI_HPROT_MASK 0x1 +#define HDMI_HPROT_MASK_SFT (0x1 << 11) +#define SPDIF2_OUT_HPROT_SFT 10 +#define SPDIF2_OUT_HPROT_MASK 0x1 +#define SPDIF2_OUT_HPROT_MASK_SFT (0x1 << 10) +#define SPDIF_OUT_HPROT_SFT 9 +#define SPDIF_OUT_HPROT_MASK 0x1 +#define SPDIF_OUT_HPROT_MASK_SFT (0x1 << 9) +#define DL8_HPROT_SFT 8 +#define DL8_HPROT_MASK 0x1 +#define DL8_HPROT_MASK_SFT (0x1 << 8) +#define DL7_HPROT_SFT 7 +#define DL7_HPROT_MASK 0x1 +#define DL7_HPROT_MASK_SFT (0x1 << 7) +#define DL6_HPROT_SFT 6 +#define DL6_HPROT_MASK 0x1 +#define DL6_HPROT_MASK_SFT (0x1 << 6) +#define DL5_HPROT_SFT 5 +#define DL5_HPROT_MASK 0x1 +#define DL5_HPROT_MASK_SFT (0x1 << 5) +#define DL4_HPROT_SFT 4 +#define DL4_HPROT_MASK 0x1 +#define DL4_HPROT_MASK_SFT (0x1 << 4) +#define DL3_HPROT_SFT 3 +#define DL3_HPROT_MASK 0x1 +#define DL3_HPROT_MASK_SFT (0x1 << 3) +#define DL2_HPROT_SFT 2 +#define DL2_HPROT_MASK 0x1 +#define DL2_HPROT_MASK_SFT (0x1 << 2) +#define DL1_HPROT_SFT 1 +#define DL1_HPROT_MASK 0x1 +#define DL1_HPROT_MASK_SFT (0x1 << 1) +#define DL0_HPROT_SFT 0 +#define DL0_HPROT_MASK 0x1 +#define DL0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND1 */ +#define DL46_HPROT_SFT 26 +#define DL46_HPROT_MASK 0x1 +#define DL46_HPROT_MASK_SFT (0x1 << 26) +#define DL45_HPROT_SFT 25 +#define DL45_HPROT_MASK 0x1 +#define DL45_HPROT_MASK_SFT (0x1 << 25) +#define DL44_HPROT_SFT 24 +#define DL44_HPROT_MASK 0x1 +#define DL44_HPROT_MASK_SFT (0x1 << 24) +#define DL43_HPROT_SFT 23 +#define DL43_HPROT_MASK 0x1 +#define DL43_HPROT_MASK_SFT (0x1 << 23) +#define DL42_HPROT_SFT 22 +#define DL42_HPROT_MASK 0x1 +#define DL42_HPROT_MASK_SFT (0x1 << 22) +#define DL41_HPROT_SFT 21 +#define DL41_HPROT_MASK 0x1 +#define DL41_HPROT_MASK_SFT (0x1 << 21) +#define DL40_HPROT_SFT 20 +#define DL40_HPROT_MASK 0x1 +#define DL40_HPROT_MASK_SFT (0x1 << 20) +#define DL39_HPROT_SFT 19 +#define DL39_HPROT_MASK 0x1 +#define DL39_HPROT_MASK_SFT (0x1 << 19) +#define DL38_HPROT_SFT 18 +#define DL38_HPROT_MASK 0x1 +#define DL38_HPROT_MASK_SFT (0x1 << 18) +#define DL37_HPROT_SFT 17 +#define DL37_HPROT_MASK 0x1 +#define DL37_HPROT_MASK_SFT (0x1 << 17) +#define DL36_HPROT_SFT 16 +#define DL36_HPROT_MASK 0x1 +#define DL36_HPROT_MASK_SFT (0x1 << 16) +#define DL35_HPROT_SFT 15 +#define DL35_HPROT_MASK 0x1 +#define DL35_HPROT_MASK_SFT (0x1 << 15) +#define DL34_HPROT_SFT 14 +#define DL34_HPROT_MASK 0x1 +#define DL34_HPROT_MASK_SFT (0x1 << 14) +#define DL33_HPROT_SFT 13 +#define DL33_HPROT_MASK 0x1 +#define DL33_HPROT_MASK_SFT (0x1 << 13) +#define DL32_HPROT_SFT 12 +#define DL32_HPROT_MASK 0x1 +#define DL32_HPROT_MASK_SFT (0x1 << 12) +#define DL31_HPROT_SFT 11 +#define DL31_HPROT_MASK 0x1 +#define DL31_HPROT_MASK_SFT (0x1 << 11) +#define DL30_HPROT_SFT 10 +#define DL30_HPROT_MASK 0x1 +#define DL30_HPROT_MASK_SFT (0x1 << 10) +#define DL29_HPROT_SFT 9 +#define DL29_HPROT_MASK 0x1 +#define DL29_HPROT_MASK_SFT (0x1 << 9) +#define DL28_HPROT_SFT 8 +#define DL28_HPROT_MASK 0x1 +#define DL28_HPROT_MASK_SFT (0x1 << 8) +#define DL27_HPROT_SFT 7 +#define DL27_HPROT_MASK 0x1 +#define DL27_HPROT_MASK_SFT (0x1 << 7) +#define DL26_HPROT_SFT 6 +#define DL26_HPROT_MASK 0x1 +#define DL26_HPROT_MASK_SFT (0x1 << 6) +#define DL25_HPROT_SFT 5 +#define DL25_HPROT_MASK 0x1 +#define DL25_HPROT_MASK_SFT (0x1 << 5) +#define DL24_HPROT_SFT 4 +#define DL24_HPROT_MASK 0x1 +#define DL24_HPROT_MASK_SFT (0x1 << 4) +#define DL23_HPROT_SFT 3 +#define DL23_HPROT_MASK 0x1 +#define DL23_HPROT_MASK_SFT (0x1 << 3) +#define DL_48CH_PROT_SFT 2 +#define DL_48CH_PROT_MASK 0x1 +#define DL_48CH_PROT_MASK_SFT (0x1 << 2) +#define DL_24CH_PROT_SFT 1 +#define DL_24CH_PROT_MASK 0x1 +#define DL_24CH_PROT_MASK_SFT (0x1 << 1) +#define DL_4CH_PROT_SFT 0 +#define DL_4CH_PROT_MASK 0x1 +#define DL_4CH_PROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND2 */ +#define VUL38_HPROT_SFT 28 +#define VUL38_HPROT_MASK 0x1 +#define VUL38_HPROT_MASK_SFT (0x1 << 28) +#define VUL37_HPROT_SFT 27 +#define VUL37_HPROT_MASK 0x1 +#define VUL37_HPROT_MASK_SFT (0x1 << 27) +#define VUL36_HPROT_SFT 26 +#define VUL36_HPROT_MASK 0x1 +#define VUL36_HPROT_MASK_SFT (0x1 << 26) +#define VUL35_HPROT_SFT 25 +#define VUL35_HPROT_MASK 0x1 +#define VUL35_HPROT_MASK_SFT (0x1 << 25) +#define VUL34_HPROT_SFT 24 +#define VUL34_HPROT_MASK 0x1 +#define VUL34_HPROT_MASK_SFT (0x1 << 24) +#define VUL33_HPROT_SFT 23 +#define VUL33_HPROT_MASK 0x1 +#define VUL33_HPROT_MASK_SFT (0x1 << 23) +#define VUL32_HPROT_SFT 22 +#define VUL32_HPROT_MASK 0x1 +#define VUL32_HPROT_MASK_SFT (0x1 << 22) +#define VUL31_HPROT_SFT 21 +#define VUL31_HPROT_MASK 0x1 +#define VUL31_HPROT_MASK_SFT (0x1 << 21) +#define VUL30_HPROT_SFT 20 +#define VUL30_HPROT_MASK 0x1 +#define VUL30_HPROT_MASK_SFT (0x1 << 20) +#define VUL29_HPROT_SFT 19 +#define VUL29_HPROT_MASK 0x1 +#define VUL29_HPROT_MASK_SFT (0x1 << 19) +#define VUL28_HPROT_SFT 18 +#define VUL28_HPROT_MASK 0x1 +#define VUL28_HPROT_MASK_SFT (0x1 << 18) +#define VUL27_HPROT_SFT 17 +#define VUL27_HPROT_MASK 0x1 +#define VUL27_HPROT_MASK_SFT (0x1 << 17) +#define VUL26_HPROT_SFT 16 +#define VUL26_HPROT_MASK 0x1 +#define VUL26_HPROT_MASK_SFT (0x1 << 16) +#define VUL25_HPROT_SFT 15 +#define VUL25_HPROT_MASK 0x1 +#define VUL25_HPROT_MASK_SFT (0x1 << 15) +#define VUL24_HPROT_SFT 14 +#define VUL24_HPROT_MASK 0x1 +#define VUL24_HPROT_MASK_SFT (0x1 << 14) +#define VUL_CM2_HPROT_SFT 13 +#define VUL_CM2_HPROT_MASK 0x1 +#define VUL_CM2_HPROT_MASK_SFT (0x1 << 13) +#define VUL_CM1_HPROT_SFT 12 +#define VUL_CM1_HPROT_MASK 0x1 +#define VUL_CM1_HPROT_MASK_SFT (0x1 << 12) +#define VUL_CM0_HPROT_SFT 11 +#define VUL_CM0_HPROT_MASK 0x1 +#define VUL_CM0_HPROT_MASK_SFT (0x1 << 11) +#define VUL10_HPROT_SFT 10 +#define VUL10_HPROT_MASK 0x1 +#define VUL10_HPROT_MASK_SFT (0x1 << 10) +#define VUL9_HPROT_SFT 9 +#define VUL9_HPROT_MASK 0x1 +#define VUL9_HPROT_MASK_SFT (0x1 << 9) +#define VUL8_HPROT_SFT 8 +#define VUL8_HPROT_MASK 0x1 +#define VUL8_HPROT_MASK_SFT (0x1 << 8) +#define VUL7_HPROT_SFT 7 +#define VUL7_HPROT_MASK 0x1 +#define VUL7_HPROT_MASK_SFT (0x1 << 7) +#define VUL6_HPROT_SFT 6 +#define VUL6_HPROT_MASK 0x1 +#define VUL6_HPROT_MASK_SFT (0x1 << 6) +#define VUL5_HPROT_SFT 5 +#define VUL5_HPROT_MASK 0x1 +#define VUL5_HPROT_MASK_SFT (0x1 << 5) +#define VUL4_HPROT_SFT 4 +#define VUL4_HPROT_MASK 0x1 +#define VUL4_HPROT_MASK_SFT (0x1 << 4) +#define VUL3_HPROT_SFT 3 +#define VUL3_HPROT_MASK 0x1 +#define VUL3_HPROT_MASK_SFT (0x1 << 3) +#define VUL2_HPROT_SFT 2 +#define VUL2_HPROT_MASK 0x1 +#define VUL2_HPROT_MASK_SFT (0x1 << 2) +#define VUL1_HPROT_SFT 1 +#define VUL1_HPROT_MASK 0x1 +#define VUL1_HPROT_MASK_SFT (0x1 << 1) +#define VUL0_HPROT_SFT 0 +#define VUL0_HPROT_MASK 0x1 +#define VUL0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND3 */ +#define MPHONE_EARC_HPROT_SFT 10 +#define MPHONE_EARC_HPROT_MASK 0x1 +#define MPHONE_EARC_HPROT_MASK_SFT (0x1 << 10) +#define MPHONE_SPDIF_HPROT_SFT 9 +#define MPHONE_SPDIF_HPROT_MASK 0x1 +#define MPHONE_SPDIF_HPROT_MASK_SFT (0x1 << 9) +#define SPDIFIN_HPROT_SFT 8 +#define SPDIFIN_HPROT_MASK 0x1 +#define SPDIFIN_HPROT_MASK_SFT (0x1 << 8) +#define TDMIN_HPROT_SFT 7 +#define TDMIN_HPROT_MASK 0x1 +#define TDMIN_HPROT_MASK_SFT (0x1 << 7) +#define ETDM_IN6_HPROT_SFT 6 +#define ETDM_IN6_HPROT_MASK 0x1 +#define ETDM_IN6_HPROT_MASK_SFT (0x1 << 6) +#define ETDM_IN5_HPROT_SFT 5 +#define ETDM_IN5_HPROT_MASK 0x1 +#define ETDM_IN5_HPROT_MASK_SFT (0x1 << 5) +#define ETDM_IN4_HPROT_SFT 4 +#define ETDM_IN4_HPROT_MASK 0x1 +#define ETDM_IN4_HPROT_MASK_SFT (0x1 << 4) +#define ETDM_IN3_HPROT_SFT 3 +#define ETDM_IN3_HPROT_MASK 0x1 +#define ETDM_IN3_HPROT_MASK_SFT (0x1 << 3) +#define ETDM_IN2_HPROT_SFT 2 +#define ETDM_IN2_HPROT_MASK 0x1 +#define ETDM_IN2_HPROT_MASK_SFT (0x1 << 2) +#define ETDM_IN1_HPROT_SFT 1 +#define ETDM_IN1_HPROT_MASK 0x1 +#define ETDM_IN1_HPROT_MASK_SFT (0x1 << 1) +#define ETDM_IN0_HPROT_SFT 0 +#define ETDM_IN0_HPROT_MASK 0x1 +#define ETDM_IN0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_DOMAIN_SIDEBAND0 */ +#define DL7_HDOMAIN_SFT 28 +#define DL7_HDOMAIN_MASK 0xf +#define DL7_HDOMAIN_MASK_SFT (0xf << 28) +#define DL6_HDOMAIN_SFT 24 +#define DL6_HDOMAIN_MASK 0xf +#define DL6_HDOMAIN_MASK_SFT (0xf << 24) +#define DL5_HDOMAIN_SFT 20 +#define DL5_HDOMAIN_MASK 0xf +#define DL5_HDOMAIN_MASK_SFT (0xf << 20) +#define DL4_HDOMAIN_SFT 16 +#define DL4_HDOMAIN_MASK 0xf +#define DL4_HDOMAIN_MASK_SFT (0xf << 16) +#define DL3_HDOMAIN_SFT 12 +#define DL3_HDOMAIN_MASK 0xf +#define DL3_HDOMAIN_MASK_SFT (0xf << 12) +#define DL2_HDOMAIN_SFT 8 +#define DL2_HDOMAIN_MASK 0xf +#define DL2_HDOMAIN_MASK_SFT (0xf << 8) +#define DL1_HDOMAIN_SFT 4 +#define DL1_HDOMAIN_MASK 0xf +#define DL1_HDOMAIN_MASK_SFT (0xf << 4) +#define DL0_HDOMAIN_SFT 0 +#define DL0_HDOMAIN_MASK 0xf +#define DL0_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND1 */ +#define DL_48CH_HDOMAIN_SFT 24 +#define DL_48CH_HDOMAIN_MASK 0xf +#define DL_48CH_HDOMAIN_MASK_SFT (0xf << 24) +#define DL_24CH_HDOMAIN_SFT 20 +#define DL_24CH_HDOMAIN_MASK 0xf +#define DL_24CH_HDOMAIN_MASK_SFT (0xf << 20) +#define DL_4CH_HDOMAIN_SFT 16 +#define DL_4CH_HDOMAIN_MASK 0xf +#define DL_4CH_HDOMAIN_MASK_SFT (0xf << 16) +#define HDMI_HDOMAIN_SFT 12 +#define HDMI_HDOMAIN_MASK 0xf +#define HDMI_HDOMAIN_MASK_SFT (0xf << 12) +#define SPDIF2_OUT_HDOMAIN_SFT 8 +#define SPDIF2_OUT_HDOMAIN_MASK 0xf +#define SPDIF2_OUT_HDOMAIN_MASK_SFT (0xf << 8) +#define SPDIF_OUT_HDOMAIN_SFT 4 +#define SPDIF_OUT_HDOMAIN_MASK 0xf +#define SPDIF_OUT_HDOMAIN_MASK_SFT (0xf << 4) +#define DL8_HDOMAIN_SFT 0 +#define DL8_HDOMAIN_MASK 0xf +#define DL8_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND2 */ +#define DL30_HDOMAIN_SFT 28 +#define DL30_HDOMAIN_MASK 0xf +#define DL30_HDOMAIN_MASK_SFT (0xf << 28) +#define DL29_HDOMAIN_SFT 24 +#define DL29_HDOMAIN_MASK 0xf +#define DL29_HDOMAIN_MASK_SFT (0xf << 24) +#define DL28_HDOMAIN_SFT 20 +#define DL28_HDOMAIN_MASK 0xf +#define DL28_HDOMAIN_MASK_SFT (0xf << 20) +#define DL27_HDOMAIN_SFT 16 +#define DL27_HDOMAIN_MASK 0xf +#define DL27_HDOMAIN_MASK_SFT (0xf << 16) +#define DL26_HDOMAIN_SFT 12 +#define DL26_HDOMAIN_MASK 0xf +#define DL26_HDOMAIN_MASK_SFT (0xf << 12) +#define DL25_HDOMAIN_SFT 8 +#define DL25_HDOMAIN_MASK 0xf +#define DL25_HDOMAIN_MASK_SFT (0xf << 8) +#define DL24_HDOMAIN_SFT 4 +#define DL24_HDOMAIN_MASK 0xf +#define DL24_HDOMAIN_MASK_SFT (0xf << 4) +#define DL23_HDOMAIN_SFT 0 +#define DL23_HDOMAIN_MASK 0xf +#define DL23_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND3 */ +#define DL38_HDOMAIN_SFT 28 +#define DL38_HDOMAIN_MASK 0xf +#define DL38_HDOMAIN_MASK_SFT (0xf << 28) +#define DL37_HDOMAIN_SFT 24 +#define DL37_HDOMAIN_MASK 0xf +#define DL37_HDOMAIN_MASK_SFT (0xf << 24) +#define DL36_HDOMAIN_SFT 20 +#define DL36_HDOMAIN_MASK 0xf +#define DL36_HDOMAIN_MASK_SFT (0xf << 20) +#define DL35_HDOMAIN_SFT 16 +#define DL35_HDOMAIN_MASK 0xf +#define DL35_HDOMAIN_MASK_SFT (0xf << 16) +#define DL34_HDOMAIN_SFT 12 +#define DL34_HDOMAIN_MASK 0xf +#define DL34_HDOMAIN_MASK_SFT (0xf << 12) +#define DL33_HDOMAIN_SFT 8 +#define DL33_HDOMAIN_MASK 0xf +#define DL33_HDOMAIN_MASK_SFT (0xf << 8) +#define DL32_HDOMAIN_SFT 4 +#define DL32_HDOMAIN_MASK 0xf +#define DL32_HDOMAIN_MASK_SFT (0xf << 4) +#define DL31_HDOMAIN_SFT 0 +#define DL31_HDOMAIN_MASK 0xf +#define DL31_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND4 */ +#define DL46_HDOMAIN_SFT 28 +#define DL46_HDOMAIN_MASK 0xf +#define DL46_HDOMAIN_MASK_SFT (0xf << 28) +#define DL45_HDOMAIN_SFT 24 +#define DL45_HDOMAIN_MASK 0xf +#define DL45_HDOMAIN_MASK_SFT (0xf << 24) +#define DL44_HDOMAIN_SFT 20 +#define DL44_HDOMAIN_MASK 0xf +#define DL44_HDOMAIN_MASK_SFT (0xf << 20) +#define DL43_HDOMAIN_SFT 16 +#define DL43_HDOMAIN_MASK 0xf +#define DL43_HDOMAIN_MASK_SFT (0xf << 16) +#define DL42_HDOMAIN_SFT 12 +#define DL42_HDOMAIN_MASK 0xf +#define DL42_HDOMAIN_MASK_SFT (0xf << 12) +#define DL41_HDOMAIN_SFT 8 +#define DL41_HDOMAIN_MASK 0xf +#define DL41_HDOMAIN_MASK_SFT (0xf << 8) +#define DL40_HDOMAIN_SFT 4 +#define DL40_HDOMAIN_MASK 0xf +#define DL40_HDOMAIN_MASK_SFT (0xf << 4) +#define DL39_HDOMAIN_SFT 0 +#define DL39_HDOMAIN_MASK 0xf +#define DL39_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND5 */ +#define VUL7_HDOMAIN_SFT 28 +#define VUL7_HDOMAIN_MASK 0xf +#define VUL7_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL6_HDOMAIN_SFT 24 +#define VUL6_HDOMAIN_MASK 0xf +#define VUL6_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL5_HDOMAIN_SFT 20 +#define VUL5_HDOMAIN_MASK 0xf +#define VUL5_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL4_HDOMAIN_SFT 16 +#define VUL4_HDOMAIN_MASK 0xf +#define VUL4_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL3_HDOMAIN_SFT 12 +#define VUL3_HDOMAIN_MASK 0xf +#define VUL3_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL2_HDOMAIN_SFT 8 +#define VUL2_HDOMAIN_MASK 0xf +#define VUL2_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL1_HDOMAIN_SFT 4 +#define VUL1_HDOMAIN_MASK 0xf +#define VUL1_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL0_HDOMAIN_SFT 0 +#define VUL0_HDOMAIN_MASK 0xf +#define VUL0_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND6 */ +#define VU25_HDOMAIN_SFT 28 +#define VU25_HDOMAIN_MASK 0xf +#define VU25_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL24_HDOMAIN_SFT 24 +#define VUL24_HDOMAIN_MASK 0xf +#define VUL24_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL_CM2_HDOMAIN_SFT 20 +#define VUL_CM2_HDOMAIN_MASK 0xf +#define VUL_CM2_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL_CM1_HDOMAIN_SFT 16 +#define VUL_CM1_HDOMAIN_MASK 0xf +#define VUL_CM1_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL_CM0_HDOMAIN_SFT 12 +#define VUL_CM0_HDOMAIN_MASK 0xf +#define VUL_CM0_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL10_HDOMAIN_SFT 8 +#define VUL10_HDOMAIN_MASK 0xf +#define VUL10_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL9_HDOMAIN_SFT 4 +#define VUL9_HDOMAIN_MASK 0xf +#define VUL9_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL8_HDOMAIN_SFT 0 +#define VUL8_HDOMAIN_MASK 0xf +#define VUL8_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND7 */ +#define VUL33_HDOMAIN_SFT 28 +#define VUL33_HDOMAIN_MASK 0xf +#define VUL33_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL32_HDOMAIN_SFT 24 +#define VUL32_HDOMAIN_MASK 0xf +#define VUL32_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL31_HDOMAIN_SFT 20 +#define VUL31_HDOMAIN_MASK 0xf +#define VUL31_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL30_HDOMAIN_SFT 16 +#define VUL30_HDOMAIN_MASK 0xf +#define VUL30_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL29_HDOMAIN_SFT 12 +#define VUL29_HDOMAIN_MASK 0xf +#define VUL29_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL28_HDOMAIN_SFT 8 +#define VUL28_HDOMAIN_MASK 0xf +#define VUL28_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL27_HDOMAIN_SFT 4 +#define VUL27_HDOMAIN_MASK 0xf +#define VUL27_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL26_HDOMAIN_SFT 0 +#define VUL26_HDOMAIN_MASK 0xf +#define VUL26_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND8 */ +#define ETDM_IN2_HDOMAIN_SFT 28 +#define ETDM_IN2_HDOMAIN_MASK 0xf +#define ETDM_IN2_HDOMAIN_MASK_SFT (0xf << 28) +#define ETDM_IN1_HDOMAIN_SFT 24 +#define ETDM_IN1_HDOMAIN_MASK 0xf +#define ETDM_IN1_HDOMAIN_MASK_SFT (0xf << 24) +#define ETDM_IN0_HDOMAIN_SFT 20 +#define ETDM_IN0_HDOMAIN_MASK 0xf +#define ETDM_IN0_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL38_HDOMAIN_SFT 16 +#define VUL38_HDOMAIN_MASK 0xf +#define VUL38_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL37_HDOMAIN_SFT 12 +#define VUL37_HDOMAIN_MASK 0xf +#define VUL37_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL36_HDOMAIN_SFT 8 +#define VUL36_HDOMAIN_MASK 0xf +#define VUL36_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL35_HDOMAIN_SFT 4 +#define VUL35_HDOMAIN_MASK 0xf +#define VUL35_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL34_HDOMAIN_SFT 0 +#define VUL34_HDOMAIN_MASK 0xf +#define VUL34_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND9 */ +#define MPHONE_EARC_HDOMAIN_SFT 28 +#define MPHONE_EARC_HDOMAIN_MASK 0xf +#define MPHONE_EARC_HDOMAIN_MASK_SFT (0xf << 28) +#define MPHONE_SPDIF_HDOMAIN_SFT 24 +#define MPHONE_SPDIF_HDOMAIN_MASK 0xf +#define MPHONE_SPDIF_HDOMAIN_MASK_SFT (0xf << 24) +#define SPDIFIN_HDOMAIN_SFT 20 +#define SPDIFIN_HDOMAIN_MASK 0xf +#define SPDIFIN_HDOMAIN_MASK_SFT (0xf << 20) +#define TDMIN_HDOMAIN_SFT 16 +#define TDMIN_HDOMAIN_MASK 0xf +#define TDMIN_HDOMAIN_MASK_SFT (0xf << 16) +#define ETDM_IN6_HDOMAIN_SFT 12 +#define ETDM_IN6_HDOMAIN_MASK 0xf +#define ETDM_IN6_HDOMAIN_MASK_SFT (0xf << 12) +#define ETDM_IN5_HDOMAIN_SFT 8 +#define ETDM_IN5_HDOMAIN_MASK 0xf +#define ETDM_IN5_HDOMAIN_MASK_SFT (0xf << 8) +#define ETDM_IN4_HDOMAIN_SFT 4 +#define ETDM_IN4_HDOMAIN_MASK 0xf +#define ETDM_IN4_HDOMAIN_MASK_SFT (0xf << 4) +#define ETDM_IN3_HDOMAIN_SFT 0 +#define ETDM_IN3_HDOMAIN_MASK 0xf +#define ETDM_IN3_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_PROT_SIDEBAND0_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND1_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND2_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND3_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND0_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND1_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND2_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND3_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND4_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND5_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND6_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND7_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND8_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND9_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_SECURE_CONN0 */ +#define AFE_SPDIFIN_LPBK_CON_MASK_S_SFT 26 +#define AFE_SPDIFIN_LPBK_CON_MASK_S_MASK 0x3 +#define AFE_SPDIFIN_LPBK_CON_MASK_S_MASK_SFT (0x3 << 26) +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_SFT 25 +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_MASK_SFT (0x1 << 25) +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_SFT 24 +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_MASK_SFT (0x1 << 24) +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_SFT 23 +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_MASK_SFT (0x1 << 23) +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_SFT 22 +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_MASK_SFT (0x1 << 22) +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_SFT 21 +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_MASK_SFT (0x1 << 21) +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_SFT 20 +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_MASK_SFT (0x1 << 20) +#define AFE_MRKAIF1_CFG0_MASK_S_SFT 19 +#define AFE_MRKAIF1_CFG0_MASK_S_MASK 0x1 +#define AFE_MRKAIF1_CFG0_MASK_S_MASK_SFT (0x1 << 19) +#define AFE_MRKAIF0_CFG0_MASK_S_SFT 18 +#define AFE_MRKAIF0_CFG0_MASK_S_MASK 0x1 +#define AFE_MRKAIF0_CFG0_MASK_S_MASK_SFT (0x1 << 18) +#define AFE_TDMIN_CON1_MASK_S_SFT 17 +#define AFE_TDMIN_CON1_MASK_S_MASK 0x1 +#define AFE_TDMIN_CON1_MASK_S_MASK_SFT (0x1 << 17) +#define AFE_TDM_CON2_MASK_S_SFT 16 +#define AFE_TDM_CON2_MASK_S_MASK 0x1 +#define AFE_TDM_CON2_MASK_S_MASK_SFT (0x1 << 16) +#define AFE_DAIBT_CON_MASK_S_SFT 14 +#define AFE_DAIBT_CON_MASK_S_MASK 0x3 +#define AFE_DAIBT_CON_MASK_S_MASK_SFT (0x3 << 14) +#define AFE_MRGIF_CON_MASK_S_SFT 12 +#define AFE_MRGIF_CON_MASK_S_MASK 0x3 +#define AFE_MRGIF_CON_MASK_S_MASK_SFT (0x3 << 12) +#define AFE_CONNSYS_I2S_CON_MASK_S_SFT 11 +#define AFE_CONNSYS_I2S_CON_MASK_S_MASK 0x1 +#define AFE_CONNSYS_I2S_CON_MASK_S_MASK_SFT (0x1 << 11) +#define AFE_PCM1_INFT_CON0_MASK_S_SFT 6 +#define AFE_PCM1_INFT_CON0_MASK_S_MASK 0x1f +#define AFE_PCM1_INFT_CON0_MASK_S_MASK_SFT (0x1f << 6) +#define AFE_PCM0_INTF_CON1_MASK_S_SFT 0 +#define AFE_PCM0_INTF_CON1_MASK_S_MASK 0x3f +#define AFE_PCM0_INTF_CON1_MASK_S_MASK_SFT (0x3f << 0) + +/* AFE_SECURE_CONN_ETDM0 */ +#define ETDM_0_3_COWORK_CON2_OUT3_DATA_SEL_SFT 28 +#define ETDM_0_3_COWORK_CON2_OUT3_DATA_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_OUT3_DATA_SEL_MASK_SFT (0xf << 28) +#define ETDM_0_3_COWORK_CON2_OUT2_DATA_SEL_SFT 24 +#define ETDM_0_3_COWORK_CON2_OUT2_DATA_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_OUT2_DATA_SEL_MASK_SFT (0xf << 24) +#define ETDM_0_3_COWORK_CON2_IN1_SDATA1_15_SEL_SFT 20 +#define ETDM_0_3_COWORK_CON2_IN1_SDATA1_15_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_IN1_SDATA1_15_SEL_MASK_SFT (0xf << 20) +#define ETDM_0_3_COWORK_CON2_IN1_SDATA0_SEL_SFT 16 +#define ETDM_0_3_COWORK_CON2_IN1_SDATA0_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_IN1_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_0_3_COWORK_CON2_IN0_SDATA1_15_SEL_SFT 12 +#define ETDM_0_3_COWORK_CON2_IN0_SDATA1_15_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_IN0_SDATA1_15_SEL_MASK_SFT (0xf << 12) +#define ETDM_0_3_COWORK_CON2_IN0_SDATA0_SEL_SFT 8 +#define ETDM_0_3_COWORK_CON2_IN0_SDATA0_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_IN0_SDATA0_SEL_MASK_SFT (0xf << 8) +#define ETDM_0_3_COWORK_CON2_OUT1_DATA_SEL_SFT 4 +#define ETDM_0_3_COWORK_CON2_OUT1_DATA_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_OUT1_DATA_SEL_MASK_SFT (0xf << 4) +#define ETDM_0_3_COWORK_CON2_OUT0_DATA_SEL_SFT 0 +#define ETDM_0_3_COWORK_CON2_OUT0_DATA_SEL_MASK 0xf +#define ETDM_0_3_COWORK_CON2_OUT0_DATA_SEL_MASK_SFT (0xf << 0) + +/* AFE_SECURE_CONN_ETDM1 */ +#define ETDM_4_7_COWORK_CON1_IN4_SDATA1_15_SEL_SFT 28 +#define ETDM_4_7_COWORK_CON1_IN4_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN4_SDATA1_15_SEL_MASK_SFT (0xf << 28) +#define ETDM_4_7_COWORK_CON1_IN4_SDATA0_SEL_SFT 24 +#define ETDM_4_7_COWORK_CON1_IN4_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN4_SDATA0_SEL_MASK_SFT (0xf << 24) +#define ETDM_4_7_COWORK_CON1_OUT5_DATA_SEL_SFT 20 +#define ETDM_4_7_COWORK_CON1_OUT5_DATA_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_OUT5_DATA_SEL_MASK_SFT (0xf << 20) +#define ETDM_4_7_COWORK_CON1_OUT4_DATA_SEL_SFT 16 +#define ETDM_4_7_COWORK_CON1_OUT4_DATA_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_OUT4_DATA_SEL_MASK_SFT (0xf << 16) +#define ETDM_4_7_COWORK_CON1_IN3_SDATA1_15_SEL_SFT 12 +#define ETDM_4_7_COWORK_CON1_IN3_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN3_SDATA1_15_SEL_MASK_SFT (0xf << 12) +#define ETDM_4_7_COWORK_CON1_IN3_SDATA0_SEL_SFT 8 +#define ETDM_4_7_COWORK_CON1_IN3_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN3_SDATA0_SEL_MASK_SFT (0xf << 8) +#define ETDM_4_7_COWORK_CON1_IN2_SDATA1_15_SEL_SFT 4 +#define ETDM_4_7_COWORK_CON1_IN2_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN2_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_4_7_COWORK_CON1_IN2_SDATA0_SEL_SFT 0 +#define ETDM_4_7_COWORK_CON1_IN2_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON1_IN2_SDATA0_SEL_MASK_SFT (0xf << 0) + +/* AFE_SECURE_CONN_ETDM2 */ +#define ETDM_4_7_COWORK_CON3_IN7_SDATA1_15_SEL_SFT 28 +#define ETDM_4_7_COWORK_CON3_IN7_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN7_SDATA1_15_SEL_MASK_SFT (0xf << 28) +#define ETDM_4_7_COWORK_CON3_IN7_SDATA0_SEL_SFT 24 +#define ETDM_4_7_COWORK_CON3_IN7_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN7_SDATA0_SEL_MASK_SFT (0xf << 24) +#define ETDM_4_7_COWORK_CON3_IN6_SDATA1_15_SEL_SFT 20 +#define ETDM_4_7_COWORK_CON3_IN6_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN6_SDATA1_15_SEL_MASK_SFT (0xf << 20) +#define ETDM_4_7_COWORK_CON3_IN6_SDATA0_SEL_SFT 16 +#define ETDM_4_7_COWORK_CON3_IN6_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN6_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_4_7_COWORK_CON3_OUT7_DATA_SEL_SFT 12 +#define ETDM_4_7_COWORK_CON3_OUT7_DATA_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_OUT7_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_4_7_COWORK_CON3_OUT6_DATA_SEL_SFT 8 +#define ETDM_4_7_COWORK_CON3_OUT6_DATA_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_OUT6_DATA_SEL_MASK_SFT (0xf << 8) +#define ETDM_4_7_COWORK_CON3_IN5_SDATA1_15_SEL_SFT 4 +#define ETDM_4_7_COWORK_CON3_IN5_SDATA1_15_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN5_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_4_7_COWORK_CON3_IN5_SDATA0_SEL_SFT 0 +#define ETDM_4_7_COWORK_CON3_IN5_SDATA0_SEL_MASK 0xf +#define ETDM_4_7_COWORK_CON3_IN5_SDATA0_SEL_MASK_SFT (0xf << 0) + +/* AFE_SECURE_SRAM_CON0 */ +#define SRAM_READ_EN15_NS_SFT 31 +#define SRAM_READ_EN15_NS_MASK 0x1 +#define SRAM_READ_EN15_NS_MASK_SFT (0x1 << 31) +#define SRAM_WRITE_EN15_NS_SFT 30 +#define SRAM_WRITE_EN15_NS_MASK 0x1 +#define SRAM_WRITE_EN15_NS_MASK_SFT (0x1 << 30) +#define SRAM_READ_EN14_NS_SFT 29 +#define SRAM_READ_EN14_NS_MASK 0x1 +#define SRAM_READ_EN14_NS_MASK_SFT (0x1 << 29) +#define SRAM_WRITE_EN14_NS_SFT 28 +#define SRAM_WRITE_EN14_NS_MASK 0x1 +#define SRAM_WRITE_EN14_NS_MASK_SFT (0x1 << 28) +#define SRAM_READ_EN13_NS_SFT 27 +#define SRAM_READ_EN13_NS_MASK 0x1 +#define SRAM_READ_EN13_NS_MASK_SFT (0x1 << 27) +#define SRAM_WRITE_EN13_NS_SFT 26 +#define SRAM_WRITE_EN13_NS_MASK 0x1 +#define SRAM_WRITE_EN13_NS_MASK_SFT (0x1 << 26) +#define SRAM_READ_EN12_NS_SFT 25 +#define SRAM_READ_EN12_NS_MASK 0x1 +#define SRAM_READ_EN12_NS_MASK_SFT (0x1 << 25) +#define SRAM_WRITE_EN12_NS_SFT 24 +#define SRAM_WRITE_EN12_NS_MASK 0x1 +#define SRAM_WRITE_EN12_NS_MASK_SFT (0x1 << 24) +#define SRAM_READ_EN11_NS_SFT 23 +#define SRAM_READ_EN11_NS_MASK 0x1 +#define SRAM_READ_EN11_NS_MASK_SFT (0x1 << 23) +#define SRAM_WRITE_EN11_NS_SFT 22 +#define SRAM_WRITE_EN11_NS_MASK 0x1 +#define SRAM_WRITE_EN11_NS_MASK_SFT (0x1 << 22) +#define SRAM_READ_EN10_NS_SFT 21 +#define SRAM_READ_EN10_NS_MASK 0x1 +#define SRAM_READ_EN10_NS_MASK_SFT (0x1 << 21) +#define SRAM_WRITE_EN10_NS_SFT 20 +#define SRAM_WRITE_EN10_NS_MASK 0x1 +#define SRAM_WRITE_EN10_NS_MASK_SFT (0x1 << 20) +#define SRAM_READ_EN9_NS_SFT 19 +#define SRAM_READ_EN9_NS_MASK 0x1 +#define SRAM_READ_EN9_NS_MASK_SFT (0x1 << 19) +#define SRAM_WRITE_EN9_NS_SFT 18 +#define SRAM_WRITE_EN9_NS_MASK 0x1 +#define SRAM_WRITE_EN9_NS_MASK_SFT (0x1 << 18) +#define SRAM_READ_EN8_NS_SFT 17 +#define SRAM_READ_EN8_NS_MASK 0x1 +#define SRAM_READ_EN8_NS_MASK_SFT (0x1 << 17) +#define SRAM_WRITE_EN8_NS_SFT 16 +#define SRAM_WRITE_EN8_NS_MASK 0x1 +#define SRAM_WRITE_EN8_NS_MASK_SFT (0x1 << 16) +#define SRAM_READ_EN7_NS_SFT 15 +#define SRAM_READ_EN7_NS_MASK 0x1 +#define SRAM_READ_EN7_NS_MASK_SFT (0x1 << 15) +#define SRAM_WRITE_EN7_NS_SFT 14 +#define SRAM_WRITE_EN7_NS_MASK 0x1 +#define SRAM_WRITE_EN7_NS_MASK_SFT (0x1 << 14) +#define SRAM_READ_EN6_NS_SFT 13 +#define SRAM_READ_EN6_NS_MASK 0x1 +#define SRAM_READ_EN6_NS_MASK_SFT (0x1 << 13) +#define SRAM_WRITE_EN6_NS_SFT 12 +#define SRAM_WRITE_EN6_NS_MASK 0x1 +#define SRAM_WRITE_EN6_NS_MASK_SFT (0x1 << 12) +#define SRAM_READ_EN5_NS_SFT 11 +#define SRAM_READ_EN5_NS_MASK 0x1 +#define SRAM_READ_EN5_NS_MASK_SFT (0x1 << 11) +#define SRAM_WRITE_EN5_NS_SFT 10 +#define SRAM_WRITE_EN5_NS_MASK 0x1 +#define SRAM_WRITE_EN5_NS_MASK_SFT (0x1 << 10) +#define SRAM_READ_EN4_NS_SFT 9 +#define SRAM_READ_EN4_NS_MASK 0x1 +#define SRAM_READ_EN4_NS_MASK_SFT (0x1 << 9) +#define SRAM_WRITE_EN4_NS_SFT 8 +#define SRAM_WRITE_EN4_NS_MASK 0x1 +#define SRAM_WRITE_EN4_NS_MASK_SFT (0x1 << 8) +#define SRAM_READ_EN3_NS_SFT 7 +#define SRAM_READ_EN3_NS_MASK 0x1 +#define SRAM_READ_EN3_NS_MASK_SFT (0x1 << 7) +#define SRAM_WRITE_EN3_NS_SFT 6 +#define SRAM_WRITE_EN3_NS_MASK 0x1 +#define SRAM_WRITE_EN3_NS_MASK_SFT (0x1 << 6) +#define SRAM_READ_EN2_NS_SFT 5 +#define SRAM_READ_EN2_NS_MASK 0x1 +#define SRAM_READ_EN2_NS_MASK_SFT (0x1 << 5) +#define SRAM_WRITE_EN2_NS_SFT 4 +#define SRAM_WRITE_EN2_NS_MASK 0x1 +#define SRAM_WRITE_EN2_NS_MASK_SFT (0x1 << 4) +#define SRAM_READ_EN1_NS_SFT 3 +#define SRAM_READ_EN1_NS_MASK 0x1 +#define SRAM_READ_EN1_NS_MASK_SFT (0x1 << 3) +#define SRAM_WRITE_EN1_NS_SFT 2 +#define SRAM_WRITE_EN1_NS_MASK 0x1 +#define SRAM_WRITE_EN1_NS_MASK_SFT (0x1 << 2) +#define SRAM_READ_EN0_NS_SFT 1 +#define SRAM_READ_EN0_NS_MASK 0x1 +#define SRAM_READ_EN0_NS_MASK_SFT (0x1 << 1) +#define SRAM_WRITE_EN0_NS_SFT 0 +#define SRAM_WRITE_EN0_NS_MASK 0x1 +#define SRAM_WRITE_EN0_NS_MASK_SFT (0x1 << 0) + +/* AFE_SECURE_SRAM_CON1 */ +#define SRAM_READ_EN15_S_SFT 31 +#define SRAM_READ_EN15_S_MASK 0x1 +#define SRAM_READ_EN15_S_MASK_SFT (0x1 << 31) +#define SRAM_WRITE_EN15_S_SFT 30 +#define SRAM_WRITE_EN15_S_MASK 0x1 +#define SRAM_WRITE_EN15_S_MASK_SFT (0x1 << 30) +#define SRAM_READ_EN14_S_SFT 29 +#define SRAM_READ_EN14_S_MASK 0x1 +#define SRAM_READ_EN14_S_MASK_SFT (0x1 << 29) +#define SRAM_WRITE_EN14_S_SFT 28 +#define SRAM_WRITE_EN14_S_MASK 0x1 +#define SRAM_WRITE_EN14_S_MASK_SFT (0x1 << 28) +#define SRAM_READ_EN13_S_SFT 27 +#define SRAM_READ_EN13_S_MASK 0x1 +#define SRAM_READ_EN13_S_MASK_SFT (0x1 << 27) +#define SRAM_WRITE_EN13_S_SFT 26 +#define SRAM_WRITE_EN13_S_MASK 0x1 +#define SRAM_WRITE_EN13_S_MASK_SFT (0x1 << 26) +#define SRAM_READ_EN12_S_SFT 25 +#define SRAM_READ_EN12_S_MASK 0x1 +#define SRAM_READ_EN12_S_MASK_SFT (0x1 << 25) +#define SRAM_WRITE_EN12_S_SFT 24 +#define SRAM_WRITE_EN12_S_MASK 0x1 +#define SRAM_WRITE_EN12_S_MASK_SFT (0x1 << 24) +#define SRAM_READ_EN11_S_SFT 23 +#define SRAM_READ_EN11_S_MASK 0x1 +#define SRAM_READ_EN11_S_MASK_SFT (0x1 << 23) +#define SRAM_WRITE_EN11_S_SFT 22 +#define SRAM_WRITE_EN11_S_MASK 0x1 +#define SRAM_WRITE_EN11_S_MASK_SFT (0x1 << 22) +#define SRAM_READ_EN10_S_SFT 21 +#define SRAM_READ_EN10_S_MASK 0x1 +#define SRAM_READ_EN10_S_MASK_SFT (0x1 << 21) +#define SRAM_WRITE_EN10_S_SFT 20 +#define SRAM_WRITE_EN10_S_MASK 0x1 +#define SRAM_WRITE_EN10_S_MASK_SFT (0x1 << 20) +#define SRAM_READ_EN9_S_SFT 19 +#define SRAM_READ_EN9_S_MASK 0x1 +#define SRAM_READ_EN9_S_MASK_SFT (0x1 << 19) +#define SRAM_WRITE_EN9_S_SFT 18 +#define SRAM_WRITE_EN9_S_MASK 0x1 +#define SRAM_WRITE_EN9_S_MASK_SFT (0x1 << 18) +#define SRAM_READ_EN8_S_SFT 17 +#define SRAM_READ_EN8_S_MASK 0x1 +#define SRAM_READ_EN8_S_MASK_SFT (0x1 << 17) +#define SRAM_WRITE_EN8_S_SFT 16 +#define SRAM_WRITE_EN8_S_MASK 0x1 +#define SRAM_WRITE_EN8_S_MASK_SFT (0x1 << 16) +#define SRAM_READ_EN7_S_SFT 15 +#define SRAM_READ_EN7_S_MASK 0x1 +#define SRAM_READ_EN7_S_MASK_SFT (0x1 << 15) +#define SRAM_WRITE_EN7_S_SFT 14 +#define SRAM_WRITE_EN7_S_MASK 0x1 +#define SRAM_WRITE_EN7_S_MASK_SFT (0x1 << 14) +#define SRAM_READ_EN6_S_SFT 13 +#define SRAM_READ_EN6_S_MASK 0x1 +#define SRAM_READ_EN6_S_MASK_SFT (0x1 << 13) +#define SRAM_WRITE_EN6_S_SFT 12 +#define SRAM_WRITE_EN6_S_MASK 0x1 +#define SRAM_WRITE_EN6_S_MASK_SFT (0x1 << 12) +#define SRAM_READ_EN5_S_SFT 11 +#define SRAM_READ_EN5_S_MASK 0x1 +#define SRAM_READ_EN5_S_MASK_SFT (0x1 << 11) +#define SRAM_WRITE_EN5_S_SFT 10 +#define SRAM_WRITE_EN5_S_MASK 0x1 +#define SRAM_WRITE_EN5_S_MASK_SFT (0x1 << 10) +#define SRAM_READ_EN4_S_SFT 9 +#define SRAM_READ_EN4_S_MASK 0x1 +#define SRAM_READ_EN4_S_MASK_SFT (0x1 << 9) +#define SRAM_WRITE_EN4_S_SFT 8 +#define SRAM_WRITE_EN4_S_MASK 0x1 +#define SRAM_WRITE_EN4_S_MASK_SFT (0x1 << 8) +#define SRAM_READ_EN3_S_SFT 7 +#define SRAM_READ_EN3_S_MASK 0x1 +#define SRAM_READ_EN3_S_MASK_SFT (0x1 << 7) +#define SRAM_WRITE_EN3_S_SFT 6 +#define SRAM_WRITE_EN3_S_MASK 0x1 +#define SRAM_WRITE_EN3_S_MASK_SFT (0x1 << 6) +#define SRAM_READ_EN2_S_SFT 5 +#define SRAM_READ_EN2_S_MASK 0x1 +#define SRAM_READ_EN2_S_MASK_SFT (0x1 << 5) +#define SRAM_WRITE_EN2_S_SFT 4 +#define SRAM_WRITE_EN2_S_MASK 0x1 +#define SRAM_WRITE_EN2_S_MASK_SFT (0x1 << 4) +#define SRAM_READ_EN1_S_SFT 3 +#define SRAM_READ_EN1_S_MASK 0x1 +#define SRAM_READ_EN1_S_MASK_SFT (0x1 << 3) +#define SRAM_WRITE_EN1_S_SFT 2 +#define SRAM_WRITE_EN1_S_MASK 0x1 +#define SRAM_WRITE_EN1_S_MASK_SFT (0x1 << 2) +#define SRAM_READ_EN0_S_SFT 1 +#define SRAM_READ_EN0_S_MASK 0x1 +#define SRAM_READ_EN0_S_MASK_SFT (0x1 << 1) +#define SRAM_WRITE_EN0_S_SFT 0 +#define SRAM_WRITE_EN0_S_MASK 0x1 +#define SRAM_WRITE_EN0_S_MASK_SFT (0x1 << 0) + +/* AFE_SE_CONN_INPUT_MASK0 */ +#define SECURE_INTRCONN_I0_I31_S_SFT 0 +#define SECURE_INTRCONN_I0_I31_S_MASK 0xffffffff +#define SECURE_INTRCONN_I0_I31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK1 */ +#define SECURE_INTRCONN_I32_I63_S_SFT 0 +#define SECURE_INTRCONN_I32_I63_S_MASK 0xffffffff +#define SECURE_INTRCONN_I32_I63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK2 */ +#define SECURE_INTRCONN_I64_I95_S_SFT 0 +#define SECURE_INTRCONN_I64_I95_S_MASK 0xffffffff +#define SECURE_INTRCONN_I64_I95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK3 */ +#define SECURE_INTRCONN_I96_I127_S_SFT 0 +#define SECURE_INTRCONN_I96_I127_S_MASK 0xffffffff +#define SECURE_INTRCONN_I96_I127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK4 */ +#define SECURE_INTRCONN_I128_I159_S_SFT 0 +#define SECURE_INTRCONN_I128_I159_S_MASK 0xffffffff +#define SECURE_INTRCONN_I128_I159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK5 */ +#define SECURE_INTRCONN_I160_I191_S_SFT 0 +#define SECURE_INTRCONN_I160_I191_S_MASK 0xffffffff +#define SECURE_INTRCONN_I160_I191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK6 */ +#define SECURE_INTRCONN_I192_I223_S_SFT 0 +#define SECURE_INTRCONN_I192_I223_S_MASK 0xffffffff +#define SECURE_INTRCONN_I192_I223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK7 */ +#define SECURE_INTRCONN_I224_I256_S_SFT 0 +#define SECURE_INTRCONN_I224_I256_S_MASK 0xffffffff +#define SECURE_INTRCONN_I224_I256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK0 */ +#define NORMAL_INTRCONN_I0_I31_S_SFT 0 +#define NORMAL_INTRCONN_I0_I31_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I0_I31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK1 */ +#define NORMAL_INTRCONN_I32_I63_S_SFT 0 +#define NORMAL_INTRCONN_I32_I63_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I32_I63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK2 */ +#define NORMAL_INTRCONN_I64_I95_S_SFT 0 +#define NORMAL_INTRCONN_I64_I95_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I64_I95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK3 */ +#define NORMAL_INTRCONN_I96_I127_S_SFT 0 +#define NORMAL_INTRCONN_I96_I127_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I96_I127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK4 */ +#define NORMAL_INTRCONN_I128_I159_S_SFT 0 +#define NORMAL_INTRCONN_I128_I159_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I128_I159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK5 */ +#define NORMAL_INTRCONN_I160_I191_S_SFT 0 +#define NORMAL_INTRCONN_I160_I191_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I160_I191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK6 */ +#define NORMAL_INTRCONN_I192_I223_S_SFT 0 +#define NORMAL_INTRCONN_I192_I223_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I192_I223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK7 */ +#define NORMAL_INTRCONN_I224_I256_S_SFT 0 +#define NORMAL_INTRCONN_I224_I256_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I224_I256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL0 */ +#define SECURE_INTRCONN_O0_O31_S_SFT 0 +#define SECURE_INTRCONN_O0_O31_S_MASK 0xffffffff +#define SECURE_INTRCONN_O0_O31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL1 */ +#define SECURE_INTRCONN_O32_O63_S_SFT 0 +#define SECURE_INTRCONN_O32_O63_S_MASK 0xffffffff +#define SECURE_INTRCONN_O32_O63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL2 */ +#define SECURE_INTRCONN_O64_O95_S_SFT 0 +#define SECURE_INTRCONN_O64_O95_S_MASK 0xffffffff +#define SECURE_INTRCONN_O64_O95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL3 */ +#define SECURE_INTRCONN_O96_O127_S_SFT 0 +#define SECURE_INTRCONN_O96_O127_S_MASK 0xffffffff +#define SECURE_INTRCONN_O96_O127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL4 */ +#define SECURE_INTRCONN_O128_O159_S_SFT 0 +#define SECURE_INTRCONN_O128_O159_S_MASK 0xffffffff +#define SECURE_INTRCONN_O128_O159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL5 */ +#define SECURE_INTRCONN_O160_O191_S_SFT 0 +#define SECURE_INTRCONN_O160_O191_S_MASK 0xffffffff +#define SECURE_INTRCONN_O160_O191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL6 */ +#define SECURE_INTRCONN_O192_O223_S_SFT 0 +#define SECURE_INTRCONN_O192_O223_S_MASK 0xffffffff +#define SECURE_INTRCONN_O192_O223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL7 */ +#define SECURE_INTRCONN_O224_O256_S_SFT 0 +#define SECURE_INTRCONN_O224_O256_S_MASK 0xffffffff +#define SECURE_INTRCONN_O224_O256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_PCM0_INTF_CON1_MASK_MON */ +#define AFE_PCM0_INTF_CON1_MASK_MON_SFT 0 +#define AFE_PCM0_INTF_CON1_MASK_MON_MASK 0xffffffff +#define AFE_PCM0_INTF_CON1_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PCM0_INTF_CON0_MASK_MON */ +#define AFE_PCM0_INTF_CON0_MASK_MON_SFT 0 +#define AFE_PCM0_INTF_CON0_MASK_MON_MASK 0xffffffff +#define AFE_PCM0_INTF_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_CON_MASK_MON */ +#define AFE_CONNSYS_I2S_CON_MASK_MON_SFT 0 +#define AFE_CONNSYS_I2S_CON_MASK_MON_MASK 0xffffffff +#define AFE_CONNSYS_I2S_CON_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_TDM_CON2_MASK_MON */ +#define AFE_TDM_CON2_MASK_MON_SFT 0 +#define AFE_TDM_CON2_MASK_MON_MASK 0xffffffff +#define AFE_TDM_CON2_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF0_CFG0_MASK_MON */ +#define AFE_MTKAIF0_CFG0_MASK_MON_SFT 0 +#define AFE_MTKAIF0_CFG0_MASK_MON_MASK 0xffffffff +#define AFE_MTKAIF0_CFG0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF1_CFG0_MASK_MON */ +#define AFE_MTKAIF1_CFG0_MASK_MON_SFT 0 +#define AFE_MTKAIF1_CFG0_MASK_MON_MASK 0xffffffff +#define AFE_MTKAIF1_CFG0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_SRC_CON0_MASK_MON */ +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_SFT 0 +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_MASK 0xffffffff +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_SRC_CON0_MASK_MON */ +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_SFT 0 +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_MASK 0xffffffff +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL2_SRC_CON0_MASK_MON */ +#define AFE_ADDA_UL2_SRC_CON0_MASK_MON_SFT 0 +#define AFE_ADDA_UL2_SRC_CON0_MASK_MON_MASK 0xffffffff +#define AFE_ADDA_UL2_SRC_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ASRC_NEW_CON0 */ +#define ONE_HEART_SFT 31 +#define ONE_HEART_MASK 0x1 +#define ONE_HEART_MASK_SFT (0x1 << 31) +#define CHSET0_OFS_ONE_HEART_DISABLE_SFT 30 +#define CHSET0_OFS_ONE_HEART_DISABLE_MASK 0x1 +#define CHSET0_OFS_ONE_HEART_DISABLE_MASK_SFT (0x1 << 30) +#define USE_SHORT_DELAY_COEFF_SFT 29 +#define USE_SHORT_DELAY_COEFF_MASK 0x1 +#define USE_SHORT_DELAY_COEFF_MASK_SFT (0x1 << 29) +#define CHSET0_O16BIT_SFT 19 +#define CHSET0_O16BIT_MASK 0x1 +#define CHSET0_O16BIT_MASK_SFT (0x1 << 19) +#define CHSET0_CLR_IIR_HISTORY_SFT 17 +#define CHSET0_CLR_IIR_HISTORY_MASK 0x1 +#define CHSET0_CLR_IIR_HISTORY_MASK_SFT (0x1 << 17) +#define CHSET0_IS_MONO_SFT 16 +#define CHSET0_IS_MONO_MASK 0x1 +#define CHSET0_IS_MONO_MASK_SFT (0x1 << 16) +#define CHSET0_OFS_SEL_SFT 14 +#define CHSET0_OFS_SEL_MASK 0x3 +#define CHSET0_OFS_SEL_MASK_SFT (0x3 << 14) +#define CHSET0_IFS_SEL_SFT 12 +#define CHSET0_IFS_SEL_MASK 0x3 +#define CHSET0_IFS_SEL_MASK_SFT (0x3 << 12) +#define CHSET0_IIR_EN_SFT 11 +#define CHSET0_IIR_EN_MASK 0x1 +#define CHSET0_IIR_EN_MASK_SFT (0x1 << 11) +#define CHSET0_IIR_STAGE_SFT 8 +#define CHSET0_IIR_STAGE_MASK 0x7 +#define CHSET0_IIR_STAGE_MASK_SFT (0x7 << 8) +#define ASM_ON_MOD_SFT 7 +#define ASM_ON_MOD_MASK 0x1 +#define ASM_ON_MOD_MASK_SFT (0x1 << 7) +#define CHSET_STR_CLR_SFT 4 +#define CHSET_STR_CLR_MASK 0x1 +#define CHSET_STR_CLR_MASK_SFT (0x1 << 4) +#define CHSET_ON_SFT 2 +#define CHSET_ON_MASK 0x1 +#define CHSET_ON_MASK_SFT (0x1 << 2) +#define COEFF_SRAM_CTRL_SFT 1 +#define COEFF_SRAM_CTRL_MASK 0x1 +#define COEFF_SRAM_CTRL_MASK_SFT (0x1 << 1) +#define ASM_ON_SFT 0 +#define ASM_ON_MASK 0x1 +#define ASM_ON_MASK_SFT (0x1 << 0) + +/* AFE_ASRC_NEW_CON1 */ +#define ASM_FREQ_0_SFT 0 +#define ASM_FREQ_0_MASK 0xffffff +#define ASM_FREQ_0_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON2 */ +#define ASM_FREQ_1_SFT 0 +#define ASM_FREQ_1_MASK 0xffffff +#define ASM_FREQ_1_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON3 */ +#define ASM_FREQ_2_SFT 0 +#define ASM_FREQ_2_MASK 0xffffff +#define ASM_FREQ_2_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON4 */ +#define ASM_FREQ_3_SFT 0 +#define ASM_FREQ_3_MASK 0xffffff +#define ASM_FREQ_3_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON5 */ +#define OUT_EN_SEL_DOMAIN_SFT 29 +#define OUT_EN_SEL_DOMAIN_MASK 0x7 +#define OUT_EN_SEL_DOMAIN_MASK_SFT (0x7 << 29) +#define OUT_EN_SEL_FS_SFT 24 +#define OUT_EN_SEL_FS_MASK 0x1f +#define OUT_EN_SEL_FS_MASK_SFT (0x1f << 24) +#define IN_EN_SEL_DOMAIN_SFT 21 +#define IN_EN_SEL_DOMAIN_MASK 0x7 +#define IN_EN_SEL_DOMAIN_MASK_SFT (0x7 << 21) +#define IN_EN_SEL_FS_SFT 16 +#define IN_EN_SEL_FS_MASK 0x1f +#define IN_EN_SEL_FS_MASK_SFT (0x1f << 16) +#define RESULT_SEL_SFT 8 +#define RESULT_SEL_MASK 0x7 +#define RESULT_SEL_MASK_SFT (0x7 << 8) +#define CALI_CK_SEL_SFT 4 +#define CALI_CK_SEL_MASK 0x7 +#define CALI_CK_SEL_MASK_SFT (0x7 << 4) +#define CALI_LRCK_SEL_SFT 1 +#define CALI_LRCK_SEL_MASK 0x7 +#define CALI_LRCK_SEL_MASK_SFT (0x7 << 1) +#define SOFT_RESET_SFT 0 +#define SOFT_RESET_MASK 0x1 +#define SOFT_RESET_MASK_SFT (0x1 << 0) + +/* AFE_ASRC_NEW_CON6 */ +#define FREQ_CALI_CYCLE_SFT 16 +#define FREQ_CALI_CYCLE_MASK 0xffff +#define FREQ_CALI_CYCLE_MASK_SFT (0xffff << 16) +#define FREQ_CALI_AUTORST_EN_SFT 15 +#define FREQ_CALI_AUTORST_EN_MASK 0x1 +#define FREQ_CALI_AUTORST_EN_MASK_SFT (0x1 << 15) +#define CALI_AUTORST_DETECT_SFT 14 +#define CALI_AUTORST_DETECT_MASK 0x1 +#define CALI_AUTORST_DETECT_MASK_SFT (0x1 << 14) +#define FREQ_CALC_RUNNING_SFT 13 +#define FREQ_CALC_RUNNING_MASK 0x1 +#define FREQ_CALC_RUNNING_MASK_SFT (0x1 << 13) +#define AUTO_TUNE_FREQ3_SFT 12 +#define AUTO_TUNE_FREQ3_MASK 0x1 +#define AUTO_TUNE_FREQ3_MASK_SFT (0x1 << 12) +#define COMP_FREQ_RES_EN_SFT 11 +#define COMP_FREQ_RES_EN_MASK 0x1 +#define COMP_FREQ_RES_EN_MASK_SFT (0x1 << 11) +#define FREQ_CALI_SEL_SFT 8 +#define FREQ_CALI_SEL_MASK 0x3 +#define FREQ_CALI_SEL_MASK_SFT (0x3 << 8) +#define FREQ_CALI_BP_DGL_SFT 7 +#define FREQ_CALI_BP_DGL_MASK 0x1 +#define FREQ_CALI_BP_DGL_MASK_SFT (0x1 << 7) +#define FREQ_CALI_MAX_GWIDTH_SFT 4 +#define FREQ_CALI_MAX_GWIDTH_MASK 0x7 +#define FREQ_CALI_MAX_GWIDTH_MASK_SFT (0x7 << 4) +#define AUTO_TUNE_FREQ2_SFT 3 +#define AUTO_TUNE_FREQ2_MASK 0x1 +#define AUTO_TUNE_FREQ2_MASK_SFT (0x1 << 3) +#define FREQ_CALI_AUTO_RESTART_SFT 2 +#define FREQ_CALI_AUTO_RESTART_MASK 0x1 +#define FREQ_CALI_AUTO_RESTART_MASK_SFT (0x1 << 2) +#define CALI_USE_FREQ_OUT_SFT 1 +#define CALI_USE_FREQ_OUT_MASK 0x1 +#define CALI_USE_FREQ_OUT_MASK_SFT (0x1 << 1) +#define CALI_EN_SFT 0 +#define CALI_EN_MASK 0x1 +#define CALI_EN_MASK_SFT (0x1 << 0) + +/* AFE_ASRC_NEW_CON7 */ +#define FREQ_CALC_DENOMINATOR_SFT 0 +#define FREQ_CALC_DENOMINATOR_MASK 0xffffff +#define FREQ_CALC_DENOMINATOR_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON8 */ +#define PRD_CALI_RESULT_RECORD_SFT 0 +#define PRD_CALI_RESULT_RECORD_MASK 0xffffff +#define PRD_CALI_RESULT_RECORD_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON9 */ +#define FREQ_CALI_RESULT_SFT 0 +#define FREQ_CALI_RESULT_MASK 0xffffff +#define FREQ_CALI_RESULT_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON10 */ +#define COEFF_SRAM_DATA_SFT 0 +#define COEFF_SRAM_DATA_MASK 0xffffffff +#define COEFF_SRAM_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_ASRC_NEW_CON11 */ +#define COEFF_SRAM_ADR_SFT 0 +#define COEFF_SRAM_ADR_MASK 0x3f +#define COEFF_SRAM_ADR_MASK_SFT (0x3f << 0) + +/* AFE_ASRC_NEW_CON12 */ +#define RING_DBG_RD_SFT 0 +#define RING_DBG_RD_MASK 0x3ffffff +#define RING_DBG_RD_MASK_SFT (0x3ffffff << 0) + +/* AFE_ASRC_NEW_CON13 */ +#define FREQ_CALI_AUTORST_TH_HIGH_SFT 0 +#define FREQ_CALI_AUTORST_TH_HIGH_MASK 0xffffff +#define FREQ_CALI_AUTORST_TH_HIGH_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_CON14 */ +#define FREQ_CALI_AUTORST_TH_LOW_SFT 0 +#define FREQ_CALI_AUTORST_TH_LOW_MASK 0xffffff +#define FREQ_CALI_AUTORST_TH_LOW_MASK_SFT (0xffffff << 0) + +/* AFE_ASRC_NEW_IP_VERSION */ +#define IP_VERSION_SFT 0 +#define IP_VERSION_MASK 0xffffffff +#define IP_VERSION_MASK_SFT (0xffffffff << 0) + +#define AUDIO_TOP_CON0 0x0 +#define AUDIO_TOP_CON1 0x4 +#define AUDIO_TOP_CON2 0x8 +#define AUDIO_TOP_CON3 0xc +#define AUDIO_TOP_CON4 0x10 +#define AUDIO_ENGEN_CON0 0x14 +#define AUDIO_ENGEN_CON0_USER1 0x18 +#define AUDIO_ENGEN_CON0_USER2 0x1c +#define AFE_SINEGEN_CON0 0x20 +#define AFE_SINEGEN_CON1 0x24 +#define AFE_SINEGEN_CON2 0x28 +#define AFE_SINEGEN_CON3 0x2c +#define AFE_APLL1_TUNER_CFG 0x30 +#define AFE_APLL1_TUNER_MON0 0x34 +#define AFE_APLL2_TUNER_CFG 0x38 +#define AFE_APLL2_TUNER_MON0 0x3c +#define AUDIO_TOP_RG0 0x4c +#define AUDIO_TOP_RG1 0x50 +#define AUDIO_TOP_RG2 0x54 +#define AUDIO_TOP_RG3 0x58 +#define AUDIO_TOP_RG4 0x5c +#define AFE_SPM_CONTROL_REQ 0x60 +#define AFE_SPM_CONTROL_ACK 0x64 +#define AUD_TOP_CFG_VCORE_RG 0x68 +#define AUDIO_TOP_IP_VERSION 0x6c +#define AUDIO_ENGEN_CON0_MON 0x7c +#define AUD_TOP_CFG_VLP_RG 0x98 +#define AUD_TOP_MON_RG 0x9c +#define AUDIO_USE_DEFAULT_DELSEL0 0xa0 +#define AUDIO_USE_DEFAULT_DELSEL1 0xa4 +#define AUDIO_USE_DEFAULT_DELSEL2 0xa8 +#define AFE_CONNSYS_I2S_IPM_VER_MON 0xb0 +#define AFE_CONNSYS_I2S_MON_SEL 0xb4 +#define AFE_CONNSYS_I2S_MON 0xb8 +#define AFE_CONNSYS_I2S_CON 0xbc +#define AFE_PCM0_INTF_CON0 0xc0 +#define AFE_PCM0_INTF_CON1 0xc4 +#define AFE_PCM_INTF_MON 0xc8 +#define AFE_PCM1_INTF_CON0 0xd0 +#define AFE_PCM1_INTF_CON1 0xd4 +#define AFE_PCM_TOP_IP_VERSION 0xe8 +#define AFE_IRQ_MCU_EN 0x100 +#define AFE_IRQ_MCU_DSP_EN 0x104 +#define AFE_IRQ_MCU_DSP2_EN 0x108 +#define AFE_IRQ_MCU_SCP_EN 0x10c +#define AFE_CUSTOM_IRQ_MCU_EN 0x110 +#define AFE_CUSTOM_IRQ_MCU_DSP_EN 0x114 +#define AFE_CUSTOM_IRQ_MCU_DSP2_EN 0x118 +#define AFE_CUSTOM_IRQ_MCU_SCP_EN 0x11c +#define AFE_IRQ_MCU_STATUS 0x120 +#define AFE_CUSTOM_IRQ_MCU_STATUS 0x124 +#define AFE_IRQ0_MCU_CFG0 0x140 +#define AFE_IRQ0_MCU_CFG1 0x144 +#define AFE_IRQ1_MCU_CFG0 0x148 +#define AFE_IRQ1_MCU_CFG1 0x14c +#define AFE_IRQ2_MCU_CFG0 0x150 +#define AFE_IRQ2_MCU_CFG1 0x154 +#define AFE_IRQ3_MCU_CFG0 0x158 +#define AFE_IRQ3_MCU_CFG1 0x15c +#define AFE_IRQ4_MCU_CFG0 0x160 +#define AFE_IRQ4_MCU_CFG1 0x164 +#define AFE_IRQ5_MCU_CFG0 0x168 +#define AFE_IRQ5_MCU_CFG1 0x16c +#define AFE_IRQ6_MCU_CFG0 0x170 +#define AFE_IRQ6_MCU_CFG1 0x174 +#define AFE_IRQ7_MCU_CFG0 0x178 +#define AFE_IRQ7_MCU_CFG1 0x17c +#define AFE_IRQ8_MCU_CFG0 0x180 +#define AFE_IRQ8_MCU_CFG1 0x184 +#define AFE_IRQ9_MCU_CFG0 0x188 +#define AFE_IRQ9_MCU_CFG1 0x18c +#define AFE_IRQ10_MCU_CFG0 0x190 +#define AFE_IRQ10_MCU_CFG1 0x194 +#define AFE_IRQ11_MCU_CFG0 0x198 +#define AFE_IRQ11_MCU_CFG1 0x19c +#define AFE_IRQ12_MCU_CFG0 0x1a0 +#define AFE_IRQ12_MCU_CFG1 0x1a4 +#define AFE_IRQ13_MCU_CFG0 0x1a8 +#define AFE_IRQ13_MCU_CFG1 0x1ac +#define AFE_IRQ14_MCU_CFG0 0x1b0 +#define AFE_IRQ14_MCU_CFG1 0x1b4 +#define AFE_IRQ15_MCU_CFG0 0x1b8 +#define AFE_IRQ15_MCU_CFG1 0x1bc +#define AFE_IRQ16_MCU_CFG0 0x1c0 +#define AFE_IRQ16_MCU_CFG1 0x1c4 +#define AFE_IRQ17_MCU_CFG0 0x1c8 +#define AFE_IRQ17_MCU_CFG1 0x1cc +#define AFE_IRQ18_MCU_CFG0 0x1d0 +#define AFE_IRQ18_MCU_CFG1 0x1d4 +#define AFE_IRQ19_MCU_CFG0 0x1d8 +#define AFE_IRQ19_MCU_CFG1 0x1dc +#define AFE_IRQ20_MCU_CFG0 0x1e0 +#define AFE_IRQ20_MCU_CFG1 0x1e4 +#define AFE_IRQ21_MCU_CFG0 0x1e8 +#define AFE_IRQ21_MCU_CFG1 0x1ec +#define AFE_IRQ22_MCU_CFG0 0x1f0 +#define AFE_IRQ22_MCU_CFG1 0x1f4 +#define AFE_IRQ23_MCU_CFG0 0x1f8 +#define AFE_IRQ23_MCU_CFG1 0x1fc +#define AFE_IRQ24_MCU_CFG0 0x200 +#define AFE_IRQ24_MCU_CFG1 0x204 +#define AFE_IRQ25_MCU_CFG0 0x208 +#define AFE_IRQ25_MCU_CFG1 0x20c +#define AFE_IRQ26_MCU_CFG0 0x210 +#define AFE_IRQ26_MCU_CFG1 0x214 +#define AFE_CUSTOM_IRQ0_MCU_CFG0 0x268 +#define AFE_IRQ_MCU_MON0 0x300 +#define AFE_IRQ_MCU_MON1 0x304 +#define AFE_IRQ_MCU_MON2 0x308 +#define AFE_IRQ0_CNT_MON 0x310 +#define AFE_IRQ1_CNT_MON 0x314 +#define AFE_IRQ2_CNT_MON 0x318 +#define AFE_IRQ3_CNT_MON 0x31c +#define AFE_IRQ4_CNT_MON 0x320 +#define AFE_IRQ5_CNT_MON 0x324 +#define AFE_IRQ6_CNT_MON 0x328 +#define AFE_IRQ7_CNT_MON 0x32c +#define AFE_IRQ8_CNT_MON 0x330 +#define AFE_IRQ9_CNT_MON 0x334 +#define AFE_IRQ10_CNT_MON 0x338 +#define AFE_IRQ11_CNT_MON 0x33c +#define AFE_IRQ12_CNT_MON 0x340 +#define AFE_IRQ13_CNT_MON 0x344 +#define AFE_IRQ14_CNT_MON 0x348 +#define AFE_IRQ15_CNT_MON 0x34c +#define AFE_IRQ16_CNT_MON 0x350 +#define AFE_IRQ17_CNT_MON 0x354 +#define AFE_IRQ18_CNT_MON 0x358 +#define AFE_IRQ19_CNT_MON 0x35c +#define AFE_IRQ20_CNT_MON 0x360 +#define AFE_IRQ21_CNT_MON 0x364 +#define AFE_IRQ22_CNT_MON 0x368 +#define AFE_IRQ23_CNT_MON 0x36c +#define AFE_IRQ24_CNT_MON 0x370 +#define AFE_IRQ25_CNT_MON 0x374 +#define AFE_IRQ26_CNT_MON 0x378 +#define AFE_CUSTOM_IRQ0_CNT_MON 0x390 +#define AFE_CUSTOM_IRQ0_MCU_CFG1 0x3dc +#define AFE_GAIN0_CON0 0x400 +#define AFE_GAIN0_CON1_R 0x404 +#define AFE_GAIN0_CON1_L 0x408 +#define AFE_GAIN0_CON2 0x40c +#define AFE_GAIN0_CON3 0x410 +#define AFE_GAIN0_CUR_R 0x414 +#define AFE_GAIN0_CUR_L 0x418 +#define AFE_GAIN1_CON0 0x41c +#define AFE_GAIN1_CON1_R 0x420 +#define AFE_GAIN1_CON1_L 0x424 +#define AFE_GAIN1_CON2 0x428 +#define AFE_GAIN1_CON3 0x42c +#define AFE_GAIN1_CUR_R 0x430 +#define AFE_GAIN1_CUR_L 0x434 +#define AFE_GAIN2_CON0 0x438 +#define AFE_GAIN2_CON1_R 0x43c +#define AFE_GAIN2_CON1_L 0x440 +#define AFE_GAIN2_CON2 0x444 +#define AFE_GAIN2_CON3 0x448 +#define AFE_GAIN2_CUR_R 0x44c +#define AFE_GAIN2_CUR_L 0x450 +#define AFE_GAIN3_CON0 0x454 +#define AFE_GAIN3_CON1_R 0x458 +#define AFE_GAIN3_CON1_L 0x45c +#define AFE_GAIN3_CON2 0x460 +#define AFE_GAIN3_CON3 0x464 +#define AFE_GAIN3_CUR_R 0x468 +#define AFE_GAIN3_CUR_L 0x46c +#define AFE_STF_CON0 0xb80 +#define AFE_STF_CON1 0xb84 +#define AFE_STF_COEFF 0xb88 +#define AFE_STF_GAIN 0xb8c +#define AFE_STF_MON 0xb90 +#define AFE_STF_IP_VERSION 0xb94 +#define AFE_CM0_CON0 0xba0 +#define AFE_CM0_MON 0xba4 +#define AFE_CM0_IP_VERSION 0xba8 +#define AFE_CM1_CON0 0xbb0 +#define AFE_CM1_MON 0xbb4 +#define AFE_CM1_IP_VERSION 0xbb8 +#define AFE_CM2_CON0 0xbc0 +#define AFE_CM2_MON 0xbc4 +#define AFE_CM2_IP_VERSION 0xbc8 +#define AFE_ADDA_UL0_SRC_CON0 0xbd0 +#define AFE_ADDA_UL0_SRC_CON1 0xbd4 +#define AFE_ADDA_UL0_SRC_CON2 0xbd8 +#define AFE_ADDA_UL0_SRC_DEBUG 0xbdc +#define AFE_ADDA_UL0_SRC_DEBUG_MON0 0xbe0 +#define AFE_ADDA_UL0_SRC_MON0 0xbe4 +#define AFE_ADDA_UL0_SRC_MON1 0xbe8 +#define AFE_ADDA_UL0_IIR_COEF_02_01 0xbec +#define AFE_ADDA_UL0_IIR_COEF_04_03 0xbf0 +#define AFE_ADDA_UL0_IIR_COEF_06_05 0xbf4 +#define AFE_ADDA_UL0_IIR_COEF_08_07 0xbf8 +#define AFE_ADDA_UL0_IIR_COEF_10_09 0xbfc +#define AFE_ADDA_UL0_ULCF_CFG_02_01 0xc00 +#define AFE_ADDA_UL0_ULCF_CFG_04_03 0xc04 +#define AFE_ADDA_UL0_ULCF_CFG_06_05 0xc08 +#define AFE_ADDA_UL0_ULCF_CFG_08_07 0xc0c +#define AFE_ADDA_UL0_ULCF_CFG_10_09 0xc10 +#define AFE_ADDA_UL0_ULCF_CFG_12_11 0xc14 +#define AFE_ADDA_UL0_ULCF_CFG_14_13 0xc18 +#define AFE_ADDA_UL0_ULCF_CFG_16_15 0xc1c +#define AFE_ADDA_UL0_ULCF_CFG_18_17 0xc20 +#define AFE_ADDA_UL0_ULCF_CFG_20_19 0xc24 +#define AFE_ADDA_UL0_ULCF_CFG_22_21 0xc28 +#define AFE_ADDA_UL0_ULCF_CFG_24_23 0xc2c +#define AFE_ADDA_UL0_ULCF_CFG_26_25 0xc30 +#define AFE_ADDA_UL0_ULCF_CFG_28_27 0xc34 +#define AFE_ADDA_UL0_ULCF_CFG_30_29 0xc38 +#define AFE_ADDA_UL0_ULCF_CFG_32_31 0xc3c +#define AFE_ADDA_UL0_IP_VERSION 0xc4c +#define AFE_ADDA_UL1_SRC_CON0 0xc50 +#define AFE_ADDA_UL1_SRC_CON1 0xc54 +#define AFE_ADDA_UL1_SRC_CON2 0xc58 +#define AFE_ADDA_UL1_SRC_DEBUG 0xc5c +#define AFE_ADDA_UL1_SRC_DEBUG_MON0 0xc60 +#define AFE_ADDA_UL1_SRC_MON0 0xc64 +#define AFE_ADDA_UL1_SRC_MON1 0xc68 +#define AFE_ADDA_UL1_IIR_COEF_02_01 0xc6c +#define AFE_ADDA_UL1_IIR_COEF_04_03 0xc70 +#define AFE_ADDA_UL1_IIR_COEF_06_05 0xc74 +#define AFE_ADDA_UL1_IIR_COEF_08_07 0xc78 +#define AFE_ADDA_UL1_IIR_COEF_10_09 0xc7c +#define AFE_ADDA_UL1_ULCF_CFG_02_01 0xc80 +#define AFE_ADDA_UL1_ULCF_CFG_04_03 0xc84 +#define AFE_ADDA_UL1_ULCF_CFG_06_05 0xc88 +#define AFE_ADDA_UL1_ULCF_CFG_08_07 0xc8c +#define AFE_ADDA_UL1_ULCF_CFG_10_09 0xc90 +#define AFE_ADDA_UL1_ULCF_CFG_12_11 0xc94 +#define AFE_ADDA_UL1_ULCF_CFG_14_13 0xc98 +#define AFE_ADDA_UL1_ULCF_CFG_16_15 0xc9c +#define AFE_ADDA_UL1_ULCF_CFG_18_17 0xca0 +#define AFE_ADDA_UL1_ULCF_CFG_20_19 0xca4 +#define AFE_ADDA_UL1_ULCF_CFG_22_21 0xca8 +#define AFE_ADDA_UL1_ULCF_CFG_24_23 0xcac +#define AFE_ADDA_UL1_ULCF_CFG_26_25 0xcb0 +#define AFE_ADDA_UL1_ULCF_CFG_28_27 0xcb4 +#define AFE_ADDA_UL1_ULCF_CFG_30_29 0xcb8 +#define AFE_ADDA_UL1_ULCF_CFG_32_31 0xcbc +#define AFE_ADDA_UL1_IP_VERSION 0xccc +#define AFE_ADDA_UL2_SRC_CON0 0xcd0 +#define AFE_ADDA_UL2_SRC_CON1 0xcd4 +#define AFE_ADDA_UL2_SRC_CON2 0xcd8 +#define AFE_ADDA_UL2_SRC_DEBUG 0xcdc +#define AFE_ADDA_UL2_SRC_DEBUG_MON0 0xce0 +#define AFE_ADDA_UL2_SRC_MON0 0xce4 +#define AFE_ADDA_UL2_SRC_MON1 0xce8 +#define AFE_ADDA_UL2_IIR_COEF_02_01 0xcec +#define AFE_ADDA_UL2_IIR_COEF_04_03 0xcf0 +#define AFE_ADDA_UL2_IIR_COEF_06_05 0xcf4 +#define AFE_ADDA_UL2_IIR_COEF_08_07 0xcf8 +#define AFE_ADDA_UL2_IIR_COEF_10_09 0xcfc +#define AFE_ADDA_UL2_ULCF_CFG_02_01 0xd00 +#define AFE_ADDA_UL2_ULCF_CFG_04_03 0xd04 +#define AFE_ADDA_UL2_ULCF_CFG_06_05 0xd08 +#define AFE_ADDA_UL2_ULCF_CFG_08_07 0xd0c +#define AFE_ADDA_UL2_ULCF_CFG_10_09 0xd10 +#define AFE_ADDA_UL2_ULCF_CFG_12_11 0xd14 +#define AFE_ADDA_UL2_ULCF_CFG_14_13 0xd18 +#define AFE_ADDA_UL2_ULCF_CFG_16_15 0xd1c +#define AFE_ADDA_UL2_ULCF_CFG_18_17 0xd20 +#define AFE_ADDA_UL2_ULCF_CFG_20_19 0xd24 +#define AFE_ADDA_UL2_ULCF_CFG_22_21 0xd28 +#define AFE_ADDA_UL2_ULCF_CFG_24_23 0xd2c +#define AFE_ADDA_UL2_ULCF_CFG_26_25 0xd30 +#define AFE_ADDA_UL2_ULCF_CFG_28_27 0xd34 +#define AFE_ADDA_UL2_ULCF_CFG_30_29 0xd38 +#define AFE_ADDA_UL2_ULCF_CFG_32_31 0xd3c +#define AFE_ADDA_UL2_IP_VERSION 0xd4c +#define AFE_ADDA_PROXIMITY_CON0 0xed0 +#define AFE_ADDA_ULSRC_PHASE_CON0 0xf00 +#define AFE_ADDA_ULSRC_PHASE_CON1 0xf04 +#define AFE_ADDA_ULSRC_PHASE_CON2 0xf08 +#define AFE_ADDA_ULSRC_PHASE_CON3 0xf0c +#define AFE_MTKAIF_IPM_VER_MON 0x1180 +#define AFE_MTKAIF_MON_SEL 0x1184 +#define AFE_MTKAIF_MON 0x1188 +#define AFE_MTKAIF0_CFG0 0x1190 +#define AFE_MTKAIF0_TX_CFG0 0x1194 +#define AFE_MTKAIF0_RX_CFG0 0x1198 +#define AFE_MTKAIF0_RX_CFG1 0x119c +#define AFE_MTKAIF0_RX_CFG2 0x11a0 +#define AFE_MTKAIF1_CFG0 0x11f0 +#define AFE_MTKAIF1_TX_CFG0 0x11f4 +#define AFE_MTKAIF1_RX_CFG0 0x11f8 +#define AFE_MTKAIF1_RX_CFG1 0x11fc +#define AFE_MTKAIF1_RX_CFG2 0x1200 +#define AFE_AUD_PAD_TOP_CFG0 0x1204 +#define AFE_AUD_PAD_TOP_MON 0x1208 +#define AFE_ADDA_MTKAIFV4_TX_CFG0 0x1280 +#define AFE_ADDA6_MTKAIFV4_TX_CFG0 0x1284 +#define AFE_ADDA_MTKAIFV4_RX_CFG0 0x1288 +#define AFE_ADDA_MTKAIFV4_RX_CFG1 0x128c +#define AFE_ADDA6_MTKAIFV4_RX_CFG0 0x1290 +#define AFE_ADDA6_MTKAIFV4_RX_CFG1 0x1294 +#define AFE_ADDA_MTKAIFV4_TX_SYNCWORD_CFG 0x1298 +#define AFE_ADDA_MTKAIFV4_RX_SYNCWORD_CFG 0x129c +#define AFE_ADDA_MTKAIFV4_MON0 0x12a0 +#define AFE_ADDA_MTKAIFV4_MON1 0x12a4 +#define AFE_ADDA6_MTKAIFV4_MON0 0x12a8 +#define ETDM_IN0_CON0 0x1300 +#define ETDM_IN0_CON1 0x1304 +#define ETDM_IN0_CON2 0x1308 +#define ETDM_IN0_CON3 0x130c +#define ETDM_IN0_CON4 0x1310 +#define ETDM_IN0_CON5 0x1314 +#define ETDM_IN0_CON6 0x1318 +#define ETDM_IN0_CON7 0x131c +#define ETDM_IN0_CON8 0x1320 +#define ETDM_IN0_CON9 0x1324 +#define ETDM_IN0_MON 0x1328 +#define ETDM_IN1_CON0 0x1330 +#define ETDM_IN1_CON1 0x1334 +#define ETDM_IN1_CON2 0x1338 +#define ETDM_IN1_CON3 0x133c +#define ETDM_IN1_CON4 0x1340 +#define ETDM_IN1_CON5 0x1344 +#define ETDM_IN1_CON6 0x1348 +#define ETDM_IN1_CON7 0x134c +#define ETDM_IN1_CON8 0x1350 +#define ETDM_IN1_CON9 0x1354 +#define ETDM_IN1_MON 0x1358 +#define ETDM_IN2_CON0 0x1360 +#define ETDM_IN2_CON1 0x1364 +#define ETDM_IN2_CON2 0x1368 +#define ETDM_IN2_CON3 0x136c +#define ETDM_IN2_CON4 0x1370 +#define ETDM_IN2_CON5 0x1374 +#define ETDM_IN2_CON6 0x1378 +#define ETDM_IN2_CON7 0x137c +#define ETDM_IN2_CON8 0x1380 +#define ETDM_IN2_CON9 0x1384 +#define ETDM_IN2_MON 0x1388 +#define ETDM_IN3_CON0 0x1390 +#define ETDM_IN3_CON1 0x1394 +#define ETDM_IN3_CON2 0x1398 +#define ETDM_IN3_CON3 0x139c +#define ETDM_IN3_CON4 0x13a0 +#define ETDM_IN3_CON5 0x13a4 +#define ETDM_IN3_CON6 0x13a8 +#define ETDM_IN3_CON7 0x13ac +#define ETDM_IN3_CON8 0x13b0 +#define ETDM_IN3_CON9 0x13b4 +#define ETDM_IN3_MON 0x13b8 +#define ETDM_IN4_CON0 0x13c0 +#define ETDM_IN4_CON1 0x13c4 +#define ETDM_IN4_CON2 0x13c8 +#define ETDM_IN4_CON3 0x13cc +#define ETDM_IN4_CON4 0x13d0 +#define ETDM_IN4_CON5 0x13d4 +#define ETDM_IN4_CON6 0x13d8 +#define ETDM_IN4_CON7 0x13dc +#define ETDM_IN4_CON8 0x13e0 +#define ETDM_IN4_CON9 0x13e4 +#define ETDM_IN4_MON 0x13e8 +#define ETDM_IN5_CON0 0x13f0 +#define ETDM_IN5_CON1 0x13f4 +#define ETDM_IN5_CON2 0x13f8 +#define ETDM_IN5_CON3 0x13fc +#define ETDM_IN5_CON4 0x1400 +#define ETDM_IN5_CON5 0x1404 +#define ETDM_IN5_CON6 0x1408 +#define ETDM_IN5_CON7 0x140c +#define ETDM_IN5_CON8 0x1410 +#define ETDM_IN5_CON9 0x1414 +#define ETDM_IN5_MON 0x1418 +#define ETDM_IN6_CON0 0x1420 +#define ETDM_IN6_CON1 0x1424 +#define ETDM_IN6_CON2 0x1428 +#define ETDM_IN6_CON3 0x142c +#define ETDM_IN6_CON4 0x1430 +#define ETDM_IN6_CON5 0x1434 +#define ETDM_IN6_CON6 0x1438 +#define ETDM_IN6_CON7 0x143c +#define ETDM_IN6_CON8 0x1440 +#define ETDM_IN6_CON9 0x1444 +#define ETDM_IN6_MON 0x1448 +#define ETDM_OUT0_CON0 0x1480 +#define ETDM_OUT0_CON1 0x1484 +#define ETDM_OUT0_CON2 0x1488 +#define ETDM_OUT0_CON3 0x148c +#define ETDM_OUT0_CON4 0x1490 +#define ETDM_OUT0_CON5 0x1494 +#define ETDM_OUT0_CON6 0x1498 +#define ETDM_OUT0_CON7 0x149c +#define ETDM_OUT0_CON8 0x14a0 +#define ETDM_OUT0_CON9 0x14a4 +#define ETDM_OUT0_MON 0x14a8 +#define ETDM_OUT1_CON0 0x14c0 +#define ETDM_OUT1_CON1 0x14c4 +#define ETDM_OUT1_CON2 0x14c8 +#define ETDM_OUT1_CON3 0x14cc +#define ETDM_OUT1_CON4 0x14d0 +#define ETDM_OUT1_CON5 0x14d4 +#define ETDM_OUT1_CON6 0x14d8 +#define ETDM_OUT1_CON7 0x14dc +#define ETDM_OUT1_CON8 0x14e0 +#define ETDM_OUT1_CON9 0x14e4 +#define ETDM_OUT1_MON 0x14e8 +#define ETDM_OUT2_CON0 0x1500 +#define ETDM_OUT2_CON1 0x1504 +#define ETDM_OUT2_CON2 0x1508 +#define ETDM_OUT2_CON3 0x150c +#define ETDM_OUT2_CON4 0x1510 +#define ETDM_OUT2_CON5 0x1514 +#define ETDM_OUT2_CON6 0x1518 +#define ETDM_OUT2_CON7 0x151c +#define ETDM_OUT2_CON8 0x1520 +#define ETDM_OUT2_CON9 0x1524 +#define ETDM_OUT2_MON 0x1528 +#define ETDM_OUT3_CON0 0x1540 +#define ETDM_OUT3_CON1 0x1544 +#define ETDM_OUT3_CON2 0x1548 +#define ETDM_OUT3_CON3 0x154c +#define ETDM_OUT3_CON4 0x1550 +#define ETDM_OUT3_CON5 0x1554 +#define ETDM_OUT3_CON6 0x1558 +#define ETDM_OUT3_CON7 0x155c +#define ETDM_OUT3_CON8 0x1560 +#define ETDM_OUT3_CON9 0x1564 +#define ETDM_OUT3_MON 0x1568 +#define ETDM_OUT4_CON0 0x1580 +#define ETDM_OUT4_CON1 0x1584 +#define ETDM_OUT4_CON2 0x1588 +#define ETDM_OUT4_CON3 0x158c +#define ETDM_OUT4_CON4 0x1590 +#define ETDM_OUT4_CON5 0x1594 +#define ETDM_OUT4_CON6 0x1598 +#define ETDM_OUT4_CON7 0x159c +#define ETDM_OUT4_CON8 0x15a0 +#define ETDM_OUT4_CON9 0x15a4 +#define ETDM_OUT4_MON 0x15a8 +#define ETDM_OUT5_CON0 0x15c0 +#define ETDM_OUT5_CON1 0x15c4 +#define ETDM_OUT5_CON2 0x15c8 +#define ETDM_OUT5_CON3 0x15cc +#define ETDM_OUT5_CON4 0x15d0 +#define ETDM_OUT5_CON5 0x15d4 +#define ETDM_OUT5_CON6 0x15d8 +#define ETDM_OUT5_CON7 0x15dc +#define ETDM_OUT5_CON8 0x15e0 +#define ETDM_OUT5_CON9 0x15e4 +#define ETDM_OUT5_MON 0x15e8 +#define ETDM_OUT6_CON0 0x1600 +#define ETDM_OUT6_CON1 0x1604 +#define ETDM_OUT6_CON2 0x1608 +#define ETDM_OUT6_CON3 0x160c +#define ETDM_OUT6_CON4 0x1610 +#define ETDM_OUT6_CON5 0x1614 +#define ETDM_OUT6_CON6 0x1618 +#define ETDM_OUT6_CON7 0x161c +#define ETDM_OUT6_CON8 0x1620 +#define ETDM_OUT6_CON9 0x1624 +#define ETDM_OUT6_MON 0x1628 +#define ETDM_0_3_COWORK_CON0 0x1680 +#define ETDM_0_3_COWORK_CON1 0x1684 +#define ETDM_0_3_COWORK_CON2 0x1688 +#define ETDM_0_3_COWORK_CON3 0x168c +#define ETDM_4_7_COWORK_CON0 0x1690 +#define ETDM_4_7_COWORK_CON1 0x1694 +#define ETDM_4_7_COWORK_CON2 0x1698 +#define ETDM_4_7_COWORK_CON3 0x169c +#define AFE_DPTX_CON 0x2040 +#define AFE_DPTX_MON 0x2044 +#define AFE_TDM_CON1 0x2048 +#define AFE_TDM_CON2 0x204c +#define AFE_TDM_CON3 0x2050 +#define AFE_TDM_OUT_MON 0x2054 +#define AFE_HDMI_CONN0 0x2078 +#define AFE_TDM_TOP_IP_VERSION 0x207c +#define AFE_CONN004_0 0x2100 +#define AFE_CONN004_1 0x2104 +#define AFE_CONN004_2 0x2108 +#define AFE_CONN004_4 0x2110 +#define AFE_CONN004_5 0x2114 +#define AFE_CONN004_6 0x2118 +#define AFE_CONN004_7 0x211c +#define AFE_CONN005_0 0x2120 +#define AFE_CONN005_1 0x2124 +#define AFE_CONN005_2 0x2128 +#define AFE_CONN005_4 0x2130 +#define AFE_CONN005_5 0x2134 +#define AFE_CONN005_6 0x2138 +#define AFE_CONN005_7 0x213c +#define AFE_CONN006_0 0x2140 +#define AFE_CONN006_1 0x2144 +#define AFE_CONN006_2 0x2148 +#define AFE_CONN006_4 0x2150 +#define AFE_CONN006_5 0x2154 +#define AFE_CONN006_6 0x2158 +#define AFE_CONN006_7 0x215c +#define AFE_CONN007_0 0x2160 +#define AFE_CONN007_1 0x2164 +#define AFE_CONN007_2 0x2168 +#define AFE_CONN007_4 0x2170 +#define AFE_CONN007_5 0x2174 +#define AFE_CONN007_6 0x2178 +#define AFE_CONN007_7 0x217c +#define AFE_CONN008_0 0x2180 +#define AFE_CONN008_1 0x2184 +#define AFE_CONN008_2 0x2188 +#define AFE_CONN008_4 0x2190 +#define AFE_CONN008_5 0x2194 +#define AFE_CONN008_6 0x2198 +#define AFE_CONN008_7 0x219c +#define AFE_CONN009_0 0x21a0 +#define AFE_CONN009_1 0x21a4 +#define AFE_CONN009_2 0x21a8 +#define AFE_CONN009_4 0x21b0 +#define AFE_CONN009_5 0x21b4 +#define AFE_CONN009_6 0x21b8 +#define AFE_CONN009_7 0x21bc +#define AFE_CONN010_0 0x21c0 +#define AFE_CONN010_1 0x21c4 +#define AFE_CONN010_2 0x21c8 +#define AFE_CONN010_4 0x21d0 +#define AFE_CONN010_5 0x21d4 +#define AFE_CONN010_6 0x21d8 +#define AFE_CONN010_7 0x21dc +#define AFE_CONN011_0 0x21e0 +#define AFE_CONN011_1 0x21e4 +#define AFE_CONN011_2 0x21e8 +#define AFE_CONN011_4 0x21f0 +#define AFE_CONN011_5 0x21f4 +#define AFE_CONN011_6 0x21f8 +#define AFE_CONN011_7 0x21fc +#define AFE_CONN012_0 0x2200 +#define AFE_CONN012_1 0x2204 +#define AFE_CONN012_2 0x2208 +#define AFE_CONN012_4 0x2210 +#define AFE_CONN012_5 0x2214 +#define AFE_CONN012_6 0x2218 +#define AFE_CONN012_7 0x221c +#define AFE_CONN014_0 0x2240 +#define AFE_CONN014_1 0x2244 +#define AFE_CONN014_2 0x2248 +#define AFE_CONN014_4 0x2250 +#define AFE_CONN014_5 0x2254 +#define AFE_CONN014_6 0x2258 +#define AFE_CONN014_7 0x225c +#define AFE_CONN015_0 0x2260 +#define AFE_CONN015_1 0x2264 +#define AFE_CONN015_2 0x2268 +#define AFE_CONN015_4 0x2270 +#define AFE_CONN015_5 0x2274 +#define AFE_CONN015_6 0x2278 +#define AFE_CONN015_7 0x227c +#define AFE_CONN016_0 0x2280 +#define AFE_CONN016_1 0x2284 +#define AFE_CONN016_2 0x2288 +#define AFE_CONN016_4 0x2290 +#define AFE_CONN016_5 0x2294 +#define AFE_CONN016_6 0x2298 +#define AFE_CONN016_7 0x229c +#define AFE_CONN017_0 0x22a0 +#define AFE_CONN017_1 0x22a4 +#define AFE_CONN017_2 0x22a8 +#define AFE_CONN017_4 0x22b0 +#define AFE_CONN017_5 0x22b4 +#define AFE_CONN017_6 0x22b8 +#define AFE_CONN017_7 0x22bc +#define AFE_CONN018_0 0x22c0 +#define AFE_CONN018_1 0x22c4 +#define AFE_CONN018_2 0x22c8 +#define AFE_CONN018_4 0x22d0 +#define AFE_CONN018_5 0x22d4 +#define AFE_CONN018_6 0x22d8 +#define AFE_CONN018_7 0x22dc +#define AFE_CONN019_0 0x22e0 +#define AFE_CONN019_1 0x22e4 +#define AFE_CONN019_2 0x22e8 +#define AFE_CONN019_4 0x22f0 +#define AFE_CONN019_5 0x22f4 +#define AFE_CONN019_6 0x22f8 +#define AFE_CONN019_7 0x22fc +#define AFE_CONN020_0 0x2300 +#define AFE_CONN020_1 0x2304 +#define AFE_CONN020_2 0x2308 +#define AFE_CONN020_4 0x2310 +#define AFE_CONN020_5 0x2314 +#define AFE_CONN020_6 0x2318 +#define AFE_CONN020_7 0x231c +#define AFE_CONN021_0 0x2320 +#define AFE_CONN021_1 0x2324 +#define AFE_CONN021_2 0x2328 +#define AFE_CONN021_4 0x2330 +#define AFE_CONN021_5 0x2334 +#define AFE_CONN021_6 0x2338 +#define AFE_CONN021_7 0x233c +#define AFE_CONN022_0 0x2340 +#define AFE_CONN022_1 0x2344 +#define AFE_CONN022_2 0x2348 +#define AFE_CONN022_4 0x2350 +#define AFE_CONN022_5 0x2354 +#define AFE_CONN022_6 0x2358 +#define AFE_CONN022_7 0x235c +#define AFE_CONN023_0 0x2360 +#define AFE_CONN023_1 0x2364 +#define AFE_CONN023_2 0x2368 +#define AFE_CONN023_4 0x2370 +#define AFE_CONN023_5 0x2374 +#define AFE_CONN023_6 0x2378 +#define AFE_CONN023_7 0x237c +#define AFE_CONN024_0 0x2380 +#define AFE_CONN024_1 0x2384 +#define AFE_CONN024_2 0x2388 +#define AFE_CONN024_4 0x2390 +#define AFE_CONN024_5 0x2394 +#define AFE_CONN024_6 0x2398 +#define AFE_CONN024_7 0x239c +#define AFE_CONN025_0 0x23a0 +#define AFE_CONN025_1 0x23a4 +#define AFE_CONN025_2 0x23a8 +#define AFE_CONN025_4 0x23b0 +#define AFE_CONN025_5 0x23b4 +#define AFE_CONN025_6 0x23b8 +#define AFE_CONN025_7 0x23bc +#define AFE_CONN026_0 0x23c0 +#define AFE_CONN026_1 0x23c4 +#define AFE_CONN026_2 0x23c8 +#define AFE_CONN026_4 0x23d0 +#define AFE_CONN026_5 0x23d4 +#define AFE_CONN026_6 0x23d8 +#define AFE_CONN026_7 0x23dc +#define AFE_CONN027_0 0x23e0 +#define AFE_CONN027_1 0x23e4 +#define AFE_CONN027_2 0x23e8 +#define AFE_CONN027_4 0x23f0 +#define AFE_CONN027_5 0x23f4 +#define AFE_CONN027_6 0x23f8 +#define AFE_CONN027_7 0x23fc +#define AFE_CONN028_0 0x2400 +#define AFE_CONN028_1 0x2404 +#define AFE_CONN028_2 0x2408 +#define AFE_CONN028_4 0x2410 +#define AFE_CONN028_5 0x2414 +#define AFE_CONN028_6 0x2418 +#define AFE_CONN028_7 0x241c +#define AFE_CONN029_0 0x2420 +#define AFE_CONN029_1 0x2424 +#define AFE_CONN029_2 0x2428 +#define AFE_CONN029_4 0x2430 +#define AFE_CONN029_5 0x2434 +#define AFE_CONN029_6 0x2438 +#define AFE_CONN029_7 0x243c +#define AFE_CONN030_0 0x2440 +#define AFE_CONN030_1 0x2444 +#define AFE_CONN030_2 0x2448 +#define AFE_CONN030_4 0x2450 +#define AFE_CONN030_5 0x2454 +#define AFE_CONN030_6 0x2458 +#define AFE_CONN030_7 0x245c +#define AFE_CONN031_0 0x2460 +#define AFE_CONN031_1 0x2464 +#define AFE_CONN031_2 0x2468 +#define AFE_CONN031_4 0x2470 +#define AFE_CONN031_5 0x2474 +#define AFE_CONN031_6 0x2478 +#define AFE_CONN031_7 0x247c +#define AFE_CONN032_0 0x2480 +#define AFE_CONN032_1 0x2484 +#define AFE_CONN032_2 0x2488 +#define AFE_CONN032_4 0x2490 +#define AFE_CONN032_5 0x2494 +#define AFE_CONN032_6 0x2498 +#define AFE_CONN032_7 0x249c +#define AFE_CONN033_0 0x24a0 +#define AFE_CONN033_1 0x24a4 +#define AFE_CONN033_2 0x24a8 +#define AFE_CONN033_4 0x24b0 +#define AFE_CONN033_5 0x24b4 +#define AFE_CONN033_6 0x24b8 +#define AFE_CONN033_7 0x24bc +#define AFE_CONN034_0 0x24c0 +#define AFE_CONN034_1 0x24c4 +#define AFE_CONN034_2 0x24c8 +#define AFE_CONN034_4 0x24d0 +#define AFE_CONN034_5 0x24d4 +#define AFE_CONN034_6 0x24d8 +#define AFE_CONN034_7 0x24dc +#define AFE_CONN035_0 0x24e0 +#define AFE_CONN035_1 0x24e4 +#define AFE_CONN035_2 0x24e8 +#define AFE_CONN035_4 0x24f0 +#define AFE_CONN035_5 0x24f4 +#define AFE_CONN035_6 0x24f8 +#define AFE_CONN035_7 0x24fc +#define AFE_CONN036_0 0x2500 +#define AFE_CONN036_1 0x2504 +#define AFE_CONN036_2 0x2508 +#define AFE_CONN036_4 0x2510 +#define AFE_CONN036_5 0x2514 +#define AFE_CONN036_6 0x2518 +#define AFE_CONN036_7 0x251c +#define AFE_CONN037_0 0x2520 +#define AFE_CONN037_1 0x2524 +#define AFE_CONN037_2 0x2528 +#define AFE_CONN037_4 0x2530 +#define AFE_CONN037_5 0x2534 +#define AFE_CONN037_6 0x2538 +#define AFE_CONN037_7 0x253c +#define AFE_CONN038_0 0x2540 +#define AFE_CONN038_1 0x2544 +#define AFE_CONN038_2 0x2548 +#define AFE_CONN038_4 0x2550 +#define AFE_CONN038_5 0x2554 +#define AFE_CONN038_6 0x2558 +#define AFE_CONN038_7 0x255c +#define AFE_CONN039_0 0x2560 +#define AFE_CONN039_1 0x2564 +#define AFE_CONN039_2 0x2568 +#define AFE_CONN039_4 0x2570 +#define AFE_CONN039_5 0x2574 +#define AFE_CONN039_6 0x2578 +#define AFE_CONN039_7 0x257c +#define AFE_CONN040_0 0x2580 +#define AFE_CONN040_1 0x2584 +#define AFE_CONN040_2 0x2588 +#define AFE_CONN040_4 0x2590 +#define AFE_CONN040_5 0x2594 +#define AFE_CONN040_6 0x2598 +#define AFE_CONN040_7 0x259c +#define AFE_CONN041_0 0x25a0 +#define AFE_CONN041_1 0x25a4 +#define AFE_CONN041_2 0x25a8 +#define AFE_CONN041_4 0x25b0 +#define AFE_CONN041_5 0x25b4 +#define AFE_CONN041_6 0x25b8 +#define AFE_CONN041_7 0x25bc +#define AFE_CONN042_0 0x25c0 +#define AFE_CONN042_1 0x25c4 +#define AFE_CONN042_2 0x25c8 +#define AFE_CONN042_4 0x25d0 +#define AFE_CONN042_5 0x25d4 +#define AFE_CONN042_6 0x25d8 +#define AFE_CONN042_7 0x25dc +#define AFE_CONN043_0 0x25e0 +#define AFE_CONN043_1 0x25e4 +#define AFE_CONN043_2 0x25e8 +#define AFE_CONN043_4 0x25f0 +#define AFE_CONN043_5 0x25f4 +#define AFE_CONN043_6 0x25f8 +#define AFE_CONN043_7 0x25fc +#define AFE_CONN044_0 0x2600 +#define AFE_CONN044_1 0x2604 +#define AFE_CONN044_2 0x2608 +#define AFE_CONN044_4 0x2610 +#define AFE_CONN044_5 0x2614 +#define AFE_CONN044_6 0x2618 +#define AFE_CONN044_7 0x261c +#define AFE_CONN045_0 0x2620 +#define AFE_CONN045_1 0x2624 +#define AFE_CONN045_2 0x2628 +#define AFE_CONN045_4 0x2630 +#define AFE_CONN045_5 0x2634 +#define AFE_CONN045_6 0x2638 +#define AFE_CONN045_7 0x263c +#define AFE_CONN046_0 0x2640 +#define AFE_CONN046_1 0x2644 +#define AFE_CONN046_2 0x2648 +#define AFE_CONN046_4 0x2650 +#define AFE_CONN046_5 0x2654 +#define AFE_CONN046_6 0x2658 +#define AFE_CONN046_7 0x265c +#define AFE_CONN047_0 0x2660 +#define AFE_CONN047_1 0x2664 +#define AFE_CONN047_2 0x2668 +#define AFE_CONN047_4 0x2670 +#define AFE_CONN047_5 0x2674 +#define AFE_CONN047_6 0x2678 +#define AFE_CONN047_7 0x267c +#define AFE_CONN048_0 0x2680 +#define AFE_CONN048_1 0x2684 +#define AFE_CONN048_2 0x2688 +#define AFE_CONN048_4 0x2690 +#define AFE_CONN048_5 0x2694 +#define AFE_CONN048_6 0x2698 +#define AFE_CONN048_7 0x269c +#define AFE_CONN049_0 0x26a0 +#define AFE_CONN049_1 0x26a4 +#define AFE_CONN049_2 0x26a8 +#define AFE_CONN049_4 0x26b0 +#define AFE_CONN049_5 0x26b4 +#define AFE_CONN049_6 0x26b8 +#define AFE_CONN049_7 0x26bc +#define AFE_CONN050_0 0x26c0 +#define AFE_CONN050_1 0x26c4 +#define AFE_CONN050_2 0x26c8 +#define AFE_CONN050_4 0x26d0 +#define AFE_CONN050_5 0x26d4 +#define AFE_CONN050_6 0x26d8 +#define AFE_CONN050_7 0x26dc +#define AFE_CONN051_0 0x26e0 +#define AFE_CONN051_1 0x26e4 +#define AFE_CONN051_2 0x26e8 +#define AFE_CONN051_4 0x26f0 +#define AFE_CONN051_5 0x26f4 +#define AFE_CONN051_6 0x26f8 +#define AFE_CONN051_7 0x26fc +#define AFE_CONN052_0 0x2700 +#define AFE_CONN052_1 0x2704 +#define AFE_CONN052_2 0x2708 +#define AFE_CONN052_4 0x2710 +#define AFE_CONN052_5 0x2714 +#define AFE_CONN052_6 0x2718 +#define AFE_CONN052_7 0x271c +#define AFE_CONN053_0 0x2720 +#define AFE_CONN053_1 0x2724 +#define AFE_CONN053_2 0x2728 +#define AFE_CONN053_4 0x2730 +#define AFE_CONN053_5 0x2734 +#define AFE_CONN053_6 0x2738 +#define AFE_CONN053_7 0x273c +#define AFE_CONN054_0 0x2740 +#define AFE_CONN054_1 0x2744 +#define AFE_CONN054_2 0x2748 +#define AFE_CONN054_4 0x2750 +#define AFE_CONN054_5 0x2754 +#define AFE_CONN054_6 0x2758 +#define AFE_CONN054_7 0x275c +#define AFE_CONN055_0 0x2760 +#define AFE_CONN055_1 0x2764 +#define AFE_CONN055_2 0x2768 +#define AFE_CONN055_4 0x2770 +#define AFE_CONN055_5 0x2774 +#define AFE_CONN055_6 0x2778 +#define AFE_CONN055_7 0x277c +#define AFE_CONN056_0 0x2780 +#define AFE_CONN056_1 0x2784 +#define AFE_CONN056_2 0x2788 +#define AFE_CONN056_4 0x2790 +#define AFE_CONN056_5 0x2794 +#define AFE_CONN056_6 0x2798 +#define AFE_CONN056_7 0x279c +#define AFE_CONN057_0 0x27a0 +#define AFE_CONN057_1 0x27a4 +#define AFE_CONN057_2 0x27a8 +#define AFE_CONN057_4 0x27b0 +#define AFE_CONN057_5 0x27b4 +#define AFE_CONN057_6 0x27b8 +#define AFE_CONN057_7 0x27bc +#define AFE_CONN058_0 0x27c0 +#define AFE_CONN058_1 0x27c4 +#define AFE_CONN058_2 0x27c8 +#define AFE_CONN058_4 0x27d0 +#define AFE_CONN058_5 0x27d4 +#define AFE_CONN058_6 0x27d8 +#define AFE_CONN058_7 0x27dc +#define AFE_CONN059_0 0x27e0 +#define AFE_CONN059_1 0x27e4 +#define AFE_CONN059_2 0x27e8 +#define AFE_CONN059_4 0x27f0 +#define AFE_CONN059_5 0x27f4 +#define AFE_CONN059_6 0x27f8 +#define AFE_CONN059_7 0x27fc +#define AFE_CONN060_0 0x2800 +#define AFE_CONN060_1 0x2804 +#define AFE_CONN060_2 0x2808 +#define AFE_CONN060_4 0x2810 +#define AFE_CONN060_5 0x2814 +#define AFE_CONN060_6 0x2818 +#define AFE_CONN060_7 0x281c +#define AFE_CONN061_0 0x2820 +#define AFE_CONN061_1 0x2824 +#define AFE_CONN061_2 0x2828 +#define AFE_CONN061_4 0x2830 +#define AFE_CONN061_5 0x2834 +#define AFE_CONN061_6 0x2838 +#define AFE_CONN061_7 0x283c +#define AFE_CONN062_0 0x2840 +#define AFE_CONN062_1 0x2844 +#define AFE_CONN062_2 0x2848 +#define AFE_CONN062_4 0x2850 +#define AFE_CONN062_5 0x2854 +#define AFE_CONN062_6 0x2858 +#define AFE_CONN062_7 0x285c +#define AFE_CONN063_0 0x2860 +#define AFE_CONN063_1 0x2864 +#define AFE_CONN063_2 0x2868 +#define AFE_CONN063_4 0x2870 +#define AFE_CONN063_5 0x2874 +#define AFE_CONN063_6 0x2878 +#define AFE_CONN063_7 0x287c +#define AFE_CONN064_0 0x2880 +#define AFE_CONN064_1 0x2884 +#define AFE_CONN064_2 0x2888 +#define AFE_CONN064_4 0x2890 +#define AFE_CONN064_5 0x2894 +#define AFE_CONN064_6 0x2898 +#define AFE_CONN064_7 0x289c +#define AFE_CONN065_0 0x28a0 +#define AFE_CONN065_1 0x28a4 +#define AFE_CONN065_2 0x28a8 +#define AFE_CONN065_4 0x28b0 +#define AFE_CONN065_5 0x28b4 +#define AFE_CONN065_6 0x28b8 +#define AFE_CONN065_7 0x28bc +#define AFE_CONN066_0 0x28c0 +#define AFE_CONN066_1 0x28c4 +#define AFE_CONN066_2 0x28c8 +#define AFE_CONN066_4 0x28d0 +#define AFE_CONN066_5 0x28d4 +#define AFE_CONN066_6 0x28d8 +#define AFE_CONN066_7 0x28dc +#define AFE_CONN067_0 0x28e0 +#define AFE_CONN067_1 0x28e4 +#define AFE_CONN067_2 0x28e8 +#define AFE_CONN067_4 0x28f0 +#define AFE_CONN067_5 0x28f4 +#define AFE_CONN067_6 0x28f8 +#define AFE_CONN067_7 0x28fc +#define AFE_CONN068_0 0x2900 +#define AFE_CONN068_1 0x2904 +#define AFE_CONN068_2 0x2908 +#define AFE_CONN068_4 0x2910 +#define AFE_CONN068_5 0x2914 +#define AFE_CONN068_6 0x2918 +#define AFE_CONN068_7 0x291c +#define AFE_CONN069_0 0x2920 +#define AFE_CONN069_1 0x2924 +#define AFE_CONN069_2 0x2928 +#define AFE_CONN069_4 0x2930 +#define AFE_CONN069_5 0x2934 +#define AFE_CONN069_6 0x2938 +#define AFE_CONN069_7 0x293c +#define AFE_CONN070_0 0x2940 +#define AFE_CONN070_1 0x2944 +#define AFE_CONN070_2 0x2948 +#define AFE_CONN070_4 0x2950 +#define AFE_CONN070_5 0x2954 +#define AFE_CONN070_6 0x2958 +#define AFE_CONN070_7 0x295c +#define AFE_CONN071_0 0x2960 +#define AFE_CONN071_1 0x2964 +#define AFE_CONN071_2 0x2968 +#define AFE_CONN071_4 0x2970 +#define AFE_CONN071_5 0x2974 +#define AFE_CONN071_6 0x2978 +#define AFE_CONN071_7 0x297c +#define AFE_CONN072_0 0x2980 +#define AFE_CONN072_1 0x2984 +#define AFE_CONN072_2 0x2988 +#define AFE_CONN072_4 0x2990 +#define AFE_CONN072_5 0x2994 +#define AFE_CONN072_6 0x2998 +#define AFE_CONN072_7 0x299c +#define AFE_CONN073_0 0x29a0 +#define AFE_CONN073_1 0x29a4 +#define AFE_CONN073_2 0x29a8 +#define AFE_CONN073_4 0x29b0 +#define AFE_CONN073_5 0x29b4 +#define AFE_CONN073_6 0x29b8 +#define AFE_CONN073_7 0x29bc +#define AFE_CONN074_0 0x29c0 +#define AFE_CONN074_1 0x29c4 +#define AFE_CONN074_2 0x29c8 +#define AFE_CONN074_4 0x29d0 +#define AFE_CONN074_5 0x29d4 +#define AFE_CONN074_6 0x29d8 +#define AFE_CONN074_7 0x29dc +#define AFE_CONN075_0 0x29e0 +#define AFE_CONN075_1 0x29e4 +#define AFE_CONN075_2 0x29e8 +#define AFE_CONN075_4 0x29f0 +#define AFE_CONN075_5 0x29f4 +#define AFE_CONN075_6 0x29f8 +#define AFE_CONN075_7 0x29fc +#define AFE_CONN076_0 0x2a00 +#define AFE_CONN076_1 0x2a04 +#define AFE_CONN076_2 0x2a08 +#define AFE_CONN076_4 0x2a10 +#define AFE_CONN076_5 0x2a14 +#define AFE_CONN076_6 0x2a18 +#define AFE_CONN076_7 0x2a1c +#define AFE_CONN077_0 0x2a20 +#define AFE_CONN077_1 0x2a24 +#define AFE_CONN077_2 0x2a28 +#define AFE_CONN077_4 0x2a30 +#define AFE_CONN077_5 0x2a34 +#define AFE_CONN077_6 0x2a38 +#define AFE_CONN077_7 0x2a3c +#define AFE_CONN078_0 0x2a40 +#define AFE_CONN078_1 0x2a44 +#define AFE_CONN078_2 0x2a48 +#define AFE_CONN078_4 0x2a50 +#define AFE_CONN078_5 0x2a54 +#define AFE_CONN078_6 0x2a58 +#define AFE_CONN078_7 0x2a5c +#define AFE_CONN079_0 0x2a60 +#define AFE_CONN079_1 0x2a64 +#define AFE_CONN079_2 0x2a68 +#define AFE_CONN079_4 0x2a70 +#define AFE_CONN079_5 0x2a74 +#define AFE_CONN079_6 0x2a78 +#define AFE_CONN079_7 0x2a7c +#define AFE_CONN080_0 0x2a80 +#define AFE_CONN080_1 0x2a84 +#define AFE_CONN080_2 0x2a88 +#define AFE_CONN080_4 0x2a90 +#define AFE_CONN080_5 0x2a94 +#define AFE_CONN080_6 0x2a98 +#define AFE_CONN080_7 0x2a9c +#define AFE_CONN081_0 0x2aa0 +#define AFE_CONN081_1 0x2aa4 +#define AFE_CONN081_2 0x2aa8 +#define AFE_CONN081_4 0x2ab0 +#define AFE_CONN081_5 0x2ab4 +#define AFE_CONN081_6 0x2ab8 +#define AFE_CONN081_7 0x2abc +#define AFE_CONN082_0 0x2ac0 +#define AFE_CONN082_1 0x2ac4 +#define AFE_CONN082_2 0x2ac8 +#define AFE_CONN082_4 0x2ad0 +#define AFE_CONN082_5 0x2ad4 +#define AFE_CONN082_6 0x2ad8 +#define AFE_CONN082_7 0x2adc +#define AFE_CONN083_0 0x2ae0 +#define AFE_CONN083_1 0x2ae4 +#define AFE_CONN083_2 0x2ae8 +#define AFE_CONN083_4 0x2af0 +#define AFE_CONN083_5 0x2af4 +#define AFE_CONN083_6 0x2af8 +#define AFE_CONN083_7 0x2afc +#define AFE_CONN084_0 0x2b00 +#define AFE_CONN084_1 0x2b04 +#define AFE_CONN084_2 0x2b08 +#define AFE_CONN084_4 0x2b10 +#define AFE_CONN084_5 0x2b14 +#define AFE_CONN084_6 0x2b18 +#define AFE_CONN084_7 0x2b1c +#define AFE_CONN085_0 0x2b20 +#define AFE_CONN085_1 0x2b24 +#define AFE_CONN085_2 0x2b28 +#define AFE_CONN085_4 0x2b30 +#define AFE_CONN085_5 0x2b34 +#define AFE_CONN085_6 0x2b38 +#define AFE_CONN085_7 0x2b3c +#define AFE_CONN086_0 0x2b40 +#define AFE_CONN086_1 0x2b44 +#define AFE_CONN086_2 0x2b48 +#define AFE_CONN086_4 0x2b50 +#define AFE_CONN086_5 0x2b54 +#define AFE_CONN086_6 0x2b58 +#define AFE_CONN086_7 0x2b5c +#define AFE_CONN087_0 0x2b60 +#define AFE_CONN087_1 0x2b64 +#define AFE_CONN087_2 0x2b68 +#define AFE_CONN087_4 0x2b70 +#define AFE_CONN087_5 0x2b74 +#define AFE_CONN087_6 0x2b78 +#define AFE_CONN087_7 0x2b7c +#define AFE_CONN088_0 0x2b80 +#define AFE_CONN088_1 0x2b84 +#define AFE_CONN088_2 0x2b88 +#define AFE_CONN088_4 0x2b90 +#define AFE_CONN088_5 0x2b94 +#define AFE_CONN088_6 0x2b98 +#define AFE_CONN088_7 0x2b9c +#define AFE_CONN089_0 0x2ba0 +#define AFE_CONN089_1 0x2ba4 +#define AFE_CONN089_2 0x2ba8 +#define AFE_CONN089_4 0x2bb0 +#define AFE_CONN089_5 0x2bb4 +#define AFE_CONN089_6 0x2bb8 +#define AFE_CONN089_7 0x2bbc +#define AFE_CONN090_0 0x2bc0 +#define AFE_CONN090_1 0x2bc4 +#define AFE_CONN090_2 0x2bc8 +#define AFE_CONN090_4 0x2bd0 +#define AFE_CONN090_5 0x2bd4 +#define AFE_CONN090_6 0x2bd8 +#define AFE_CONN090_7 0x2bdc +#define AFE_CONN091_0 0x2be0 +#define AFE_CONN091_1 0x2be4 +#define AFE_CONN091_2 0x2be8 +#define AFE_CONN091_4 0x2bf0 +#define AFE_CONN091_5 0x2bf4 +#define AFE_CONN091_6 0x2bf8 +#define AFE_CONN091_7 0x2bfc +#define AFE_CONN092_0 0x2c00 +#define AFE_CONN092_1 0x2c04 +#define AFE_CONN092_2 0x2c08 +#define AFE_CONN092_4 0x2c10 +#define AFE_CONN092_5 0x2c14 +#define AFE_CONN092_6 0x2c18 +#define AFE_CONN092_7 0x2c1c +#define AFE_CONN093_0 0x2c20 +#define AFE_CONN093_1 0x2c24 +#define AFE_CONN093_2 0x2c28 +#define AFE_CONN093_4 0x2c30 +#define AFE_CONN093_5 0x2c34 +#define AFE_CONN093_6 0x2c38 +#define AFE_CONN093_7 0x2c3c +#define AFE_CONN094_0 0x2c40 +#define AFE_CONN094_1 0x2c44 +#define AFE_CONN094_2 0x2c48 +#define AFE_CONN094_4 0x2c50 +#define AFE_CONN094_5 0x2c54 +#define AFE_CONN094_6 0x2c58 +#define AFE_CONN094_7 0x2c5c +#define AFE_CONN095_0 0x2c60 +#define AFE_CONN095_1 0x2c64 +#define AFE_CONN095_2 0x2c68 +#define AFE_CONN095_4 0x2c70 +#define AFE_CONN095_5 0x2c74 +#define AFE_CONN095_6 0x2c78 +#define AFE_CONN095_7 0x2c7c +#define AFE_CONN096_0 0x2c80 +#define AFE_CONN096_1 0x2c84 +#define AFE_CONN096_2 0x2c88 +#define AFE_CONN096_4 0x2c90 +#define AFE_CONN096_5 0x2c94 +#define AFE_CONN096_6 0x2c98 +#define AFE_CONN096_7 0x2c9c +#define AFE_CONN097_0 0x2ca0 +#define AFE_CONN097_1 0x2ca4 +#define AFE_CONN097_2 0x2ca8 +#define AFE_CONN097_4 0x2cb0 +#define AFE_CONN097_5 0x2cb4 +#define AFE_CONN097_6 0x2cb8 +#define AFE_CONN097_7 0x2cbc +#define AFE_CONN098_0 0x2cc0 +#define AFE_CONN098_1 0x2cc4 +#define AFE_CONN098_2 0x2cc8 +#define AFE_CONN098_4 0x2cd0 +#define AFE_CONN098_5 0x2cd4 +#define AFE_CONN098_6 0x2cd8 +#define AFE_CONN098_7 0x2cdc +#define AFE_CONN099_0 0x2ce0 +#define AFE_CONN099_1 0x2ce4 +#define AFE_CONN099_2 0x2ce8 +#define AFE_CONN099_4 0x2cf0 +#define AFE_CONN099_5 0x2cf4 +#define AFE_CONN099_6 0x2cf8 +#define AFE_CONN099_7 0x2cfc +#define AFE_CONN100_0 0x2d00 +#define AFE_CONN100_1 0x2d04 +#define AFE_CONN100_2 0x2d08 +#define AFE_CONN100_4 0x2d10 +#define AFE_CONN100_5 0x2d14 +#define AFE_CONN100_6 0x2d18 +#define AFE_CONN100_7 0x2d1c +#define AFE_CONN102_0 0x2d40 +#define AFE_CONN102_1 0x2d44 +#define AFE_CONN102_2 0x2d48 +#define AFE_CONN102_4 0x2d50 +#define AFE_CONN102_5 0x2d54 +#define AFE_CONN102_6 0x2d58 +#define AFE_CONN102_7 0x2d5c +#define AFE_CONN103_0 0x2d60 +#define AFE_CONN103_1 0x2d64 +#define AFE_CONN103_2 0x2d68 +#define AFE_CONN103_4 0x2d70 +#define AFE_CONN103_5 0x2d74 +#define AFE_CONN103_6 0x2d78 +#define AFE_CONN103_7 0x2d7c +#define AFE_CONN104_0 0x2d80 +#define AFE_CONN104_1 0x2d84 +#define AFE_CONN104_2 0x2d88 +#define AFE_CONN104_4 0x2d90 +#define AFE_CONN104_5 0x2d94 +#define AFE_CONN104_6 0x2d98 +#define AFE_CONN104_7 0x2d9c +#define AFE_CONN105_0 0x2da0 +#define AFE_CONN105_1 0x2da4 +#define AFE_CONN105_2 0x2da8 +#define AFE_CONN105_4 0x2db0 +#define AFE_CONN105_5 0x2db4 +#define AFE_CONN105_6 0x2db8 +#define AFE_CONN105_7 0x2dbc +#define AFE_CONN106_0 0x2dc0 +#define AFE_CONN106_1 0x2dc4 +#define AFE_CONN106_2 0x2dc8 +#define AFE_CONN106_4 0x2dd0 +#define AFE_CONN106_5 0x2dd4 +#define AFE_CONN106_6 0x2dd8 +#define AFE_CONN106_7 0x2ddc +#define AFE_CONN108_0 0x2e00 +#define AFE_CONN108_1 0x2e04 +#define AFE_CONN108_2 0x2e08 +#define AFE_CONN108_4 0x2e10 +#define AFE_CONN108_5 0x2e14 +#define AFE_CONN108_6 0x2e18 +#define AFE_CONN108_7 0x2e1c +#define AFE_CONN109_0 0x2e20 +#define AFE_CONN109_1 0x2e24 +#define AFE_CONN109_2 0x2e28 +#define AFE_CONN109_4 0x2e30 +#define AFE_CONN109_5 0x2e34 +#define AFE_CONN109_6 0x2e38 +#define AFE_CONN109_7 0x2e3c +#define AFE_CONN110_0 0x2e40 +#define AFE_CONN110_1 0x2e44 +#define AFE_CONN110_2 0x2e48 +#define AFE_CONN110_4 0x2e50 +#define AFE_CONN110_5 0x2e54 +#define AFE_CONN110_6 0x2e58 +#define AFE_CONN110_7 0x2e5c +#define AFE_CONN111_0 0x2e60 +#define AFE_CONN111_1 0x2e64 +#define AFE_CONN111_2 0x2e68 +#define AFE_CONN111_4 0x2e70 +#define AFE_CONN111_5 0x2e74 +#define AFE_CONN111_6 0x2e78 +#define AFE_CONN111_7 0x2e7c +#define AFE_CONN112_0 0x2e80 +#define AFE_CONN112_1 0x2e84 +#define AFE_CONN112_2 0x2e88 +#define AFE_CONN112_4 0x2e90 +#define AFE_CONN112_5 0x2e94 +#define AFE_CONN112_6 0x2e98 +#define AFE_CONN112_7 0x2e9c +#define AFE_CONN113_0 0x2ea0 +#define AFE_CONN113_1 0x2ea4 +#define AFE_CONN113_2 0x2ea8 +#define AFE_CONN113_4 0x2eb0 +#define AFE_CONN113_5 0x2eb4 +#define AFE_CONN113_6 0x2eb8 +#define AFE_CONN113_7 0x2ebc +#define AFE_CONN114_0 0x2ec0 +#define AFE_CONN114_1 0x2ec4 +#define AFE_CONN114_2 0x2ec8 +#define AFE_CONN114_4 0x2ed0 +#define AFE_CONN114_5 0x2ed4 +#define AFE_CONN114_6 0x2ed8 +#define AFE_CONN114_7 0x2edc +#define AFE_CONN115_0 0x2ee0 +#define AFE_CONN115_1 0x2ee4 +#define AFE_CONN115_2 0x2ee8 +#define AFE_CONN115_4 0x2ef0 +#define AFE_CONN115_5 0x2ef4 +#define AFE_CONN115_6 0x2ef8 +#define AFE_CONN115_7 0x2efc +#define AFE_CONN116_0 0x2f00 +#define AFE_CONN116_1 0x2f04 +#define AFE_CONN116_2 0x2f08 +#define AFE_CONN116_4 0x2f10 +#define AFE_CONN116_5 0x2f14 +#define AFE_CONN116_6 0x2f18 +#define AFE_CONN116_7 0x2f1c +#define AFE_CONN117_0 0x2f20 +#define AFE_CONN117_1 0x2f24 +#define AFE_CONN117_2 0x2f28 +#define AFE_CONN117_4 0x2f30 +#define AFE_CONN117_5 0x2f34 +#define AFE_CONN117_6 0x2f38 +#define AFE_CONN117_7 0x2f3c +#define AFE_CONN118_0 0x2f40 +#define AFE_CONN118_1 0x2f44 +#define AFE_CONN118_2 0x2f48 +#define AFE_CONN118_4 0x2f50 +#define AFE_CONN118_5 0x2f54 +#define AFE_CONN118_6 0x2f58 +#define AFE_CONN118_7 0x2f5c +#define AFE_CONN119_0 0x2f60 +#define AFE_CONN119_1 0x2f64 +#define AFE_CONN119_2 0x2f68 +#define AFE_CONN119_4 0x2f70 +#define AFE_CONN119_5 0x2f74 +#define AFE_CONN119_6 0x2f78 +#define AFE_CONN119_7 0x2f7c +#define AFE_CONN120_0 0x2f80 +#define AFE_CONN120_1 0x2f84 +#define AFE_CONN120_2 0x2f88 +#define AFE_CONN120_4 0x2f90 +#define AFE_CONN120_5 0x2f94 +#define AFE_CONN120_6 0x2f98 +#define AFE_CONN120_7 0x2f9c +#define AFE_CONN121_0 0x2fa0 +#define AFE_CONN121_1 0x2fa4 +#define AFE_CONN121_2 0x2fa8 +#define AFE_CONN121_4 0x2fb0 +#define AFE_CONN121_5 0x2fb4 +#define AFE_CONN121_6 0x2fb8 +#define AFE_CONN121_7 0x2fbc +#define AFE_CONN122_0 0x2fc0 +#define AFE_CONN122_1 0x2fc4 +#define AFE_CONN122_2 0x2fc8 +#define AFE_CONN122_4 0x2fd0 +#define AFE_CONN122_5 0x2fd4 +#define AFE_CONN122_6 0x2fd8 +#define AFE_CONN122_7 0x2fdc +#define AFE_CONN123_0 0x2fe0 +#define AFE_CONN123_1 0x2fe4 +#define AFE_CONN123_2 0x2fe8 +#define AFE_CONN123_4 0x2ff0 +#define AFE_CONN123_5 0x2ff4 +#define AFE_CONN123_6 0x2ff8 +#define AFE_CONN123_7 0x2ffc +#define AFE_CONN124_0 0x3000 +#define AFE_CONN124_1 0x3004 +#define AFE_CONN124_2 0x3008 +#define AFE_CONN124_4 0x3010 +#define AFE_CONN124_5 0x3014 +#define AFE_CONN124_6 0x3018 +#define AFE_CONN124_7 0x301c +#define AFE_CONN125_0 0x3020 +#define AFE_CONN125_1 0x3024 +#define AFE_CONN125_2 0x3028 +#define AFE_CONN125_4 0x3030 +#define AFE_CONN125_5 0x3034 +#define AFE_CONN125_6 0x3038 +#define AFE_CONN125_7 0x303c +#define AFE_CONN126_0 0x3040 +#define AFE_CONN126_1 0x3044 +#define AFE_CONN126_2 0x3048 +#define AFE_CONN126_4 0x3050 +#define AFE_CONN126_5 0x3054 +#define AFE_CONN126_6 0x3058 +#define AFE_CONN126_7 0x305c +#define AFE_CONN127_0 0x3060 +#define AFE_CONN127_1 0x3064 +#define AFE_CONN127_2 0x3068 +#define AFE_CONN127_4 0x3070 +#define AFE_CONN127_5 0x3074 +#define AFE_CONN127_6 0x3078 +#define AFE_CONN127_7 0x307c +#define AFE_CONN128_0 0x3080 +#define AFE_CONN128_1 0x3084 +#define AFE_CONN128_2 0x3088 +#define AFE_CONN128_4 0x3090 +#define AFE_CONN128_5 0x3094 +#define AFE_CONN128_6 0x3098 +#define AFE_CONN128_7 0x309c +#define AFE_CONN129_0 0x30a0 +#define AFE_CONN129_1 0x30a4 +#define AFE_CONN129_2 0x30a8 +#define AFE_CONN129_4 0x30b0 +#define AFE_CONN129_5 0x30b4 +#define AFE_CONN129_6 0x30b8 +#define AFE_CONN129_7 0x30bc +#define AFE_CONN130_0 0x30c0 +#define AFE_CONN130_1 0x30c4 +#define AFE_CONN130_2 0x30c8 +#define AFE_CONN130_4 0x30d0 +#define AFE_CONN130_5 0x30d4 +#define AFE_CONN130_6 0x30d8 +#define AFE_CONN130_7 0x30dc +#define AFE_CONN131_0 0x30e0 +#define AFE_CONN131_1 0x30e4 +#define AFE_CONN131_2 0x30e8 +#define AFE_CONN131_4 0x30f0 +#define AFE_CONN131_5 0x30f4 +#define AFE_CONN131_6 0x30f8 +#define AFE_CONN131_7 0x30fc +#define AFE_CONN132_0 0x3100 +#define AFE_CONN132_1 0x3104 +#define AFE_CONN132_2 0x3108 +#define AFE_CONN132_4 0x3110 +#define AFE_CONN132_5 0x3114 +#define AFE_CONN132_6 0x3118 +#define AFE_CONN132_7 0x311c +#define AFE_CONN133_0 0x3120 +#define AFE_CONN133_1 0x3124 +#define AFE_CONN133_2 0x3128 +#define AFE_CONN133_4 0x3130 +#define AFE_CONN133_5 0x3134 +#define AFE_CONN133_6 0x3138 +#define AFE_CONN133_7 0x313c +#define AFE_CONN134_0 0x3140 +#define AFE_CONN134_1 0x3144 +#define AFE_CONN134_2 0x3148 +#define AFE_CONN134_4 0x3150 +#define AFE_CONN134_5 0x3154 +#define AFE_CONN134_6 0x3158 +#define AFE_CONN134_7 0x315c +#define AFE_CONN135_0 0x3160 +#define AFE_CONN135_1 0x3164 +#define AFE_CONN135_2 0x3168 +#define AFE_CONN135_4 0x3170 +#define AFE_CONN135_5 0x3174 +#define AFE_CONN135_6 0x3178 +#define AFE_CONN135_7 0x317c +#define AFE_CONN136_0 0x3180 +#define AFE_CONN136_1 0x3184 +#define AFE_CONN136_2 0x3188 +#define AFE_CONN136_4 0x3190 +#define AFE_CONN136_5 0x3194 +#define AFE_CONN136_6 0x3198 +#define AFE_CONN136_7 0x319c +#define AFE_CONN137_0 0x31a0 +#define AFE_CONN137_1 0x31a4 +#define AFE_CONN137_2 0x31a8 +#define AFE_CONN137_4 0x31b0 +#define AFE_CONN137_5 0x31b4 +#define AFE_CONN137_6 0x31b8 +#define AFE_CONN137_7 0x31bc +#define AFE_CONN138_0 0x31c0 +#define AFE_CONN138_1 0x31c4 +#define AFE_CONN138_2 0x31c8 +#define AFE_CONN138_4 0x31d0 +#define AFE_CONN138_5 0x31d4 +#define AFE_CONN138_6 0x31d8 +#define AFE_CONN138_7 0x31dc +#define AFE_CONN139_0 0x31e0 +#define AFE_CONN139_1 0x31e4 +#define AFE_CONN139_2 0x31e8 +#define AFE_CONN139_4 0x31f0 +#define AFE_CONN139_5 0x31f4 +#define AFE_CONN139_6 0x31f8 +#define AFE_CONN139_7 0x31fc +#define AFE_CONN148_0 0x3300 +#define AFE_CONN148_1 0x3304 +#define AFE_CONN148_2 0x3308 +#define AFE_CONN148_4 0x3310 +#define AFE_CONN148_5 0x3314 +#define AFE_CONN148_6 0x3318 +#define AFE_CONN148_7 0x331c +#define AFE_CONN149_0 0x3320 +#define AFE_CONN149_1 0x3324 +#define AFE_CONN149_2 0x3328 +#define AFE_CONN149_4 0x3330 +#define AFE_CONN149_5 0x3334 +#define AFE_CONN149_6 0x3338 +#define AFE_CONN149_7 0x333c +#define AFE_CONN180_0 0x3700 +#define AFE_CONN180_1 0x3704 +#define AFE_CONN180_2 0x3708 +#define AFE_CONN180_4 0x3710 +#define AFE_CONN180_5 0x3714 +#define AFE_CONN180_6 0x3718 +#define AFE_CONN180_7 0x371c +#define AFE_CONN181_0 0x3720 +#define AFE_CONN181_1 0x3724 +#define AFE_CONN181_2 0x3728 +#define AFE_CONN181_4 0x3730 +#define AFE_CONN181_5 0x3734 +#define AFE_CONN181_6 0x3738 +#define AFE_CONN181_7 0x373c +#define AFE_CONN182_0 0x3740 +#define AFE_CONN182_1 0x3744 +#define AFE_CONN182_2 0x3748 +#define AFE_CONN182_4 0x3750 +#define AFE_CONN182_5 0x3754 +#define AFE_CONN182_6 0x3758 +#define AFE_CONN182_7 0x375c +#define AFE_CONN183_0 0x3760 +#define AFE_CONN183_1 0x3764 +#define AFE_CONN183_2 0x3768 +#define AFE_CONN183_4 0x3770 +#define AFE_CONN183_5 0x3774 +#define AFE_CONN183_6 0x3778 +#define AFE_CONN183_7 0x377c +#define AFE_CONN184_0 0x3780 +#define AFE_CONN184_1 0x3784 +#define AFE_CONN184_2 0x3788 +#define AFE_CONN184_4 0x3790 +#define AFE_CONN184_5 0x3794 +#define AFE_CONN184_6 0x3798 +#define AFE_CONN184_7 0x379c +#define AFE_CONN185_0 0x37a0 +#define AFE_CONN185_1 0x37a4 +#define AFE_CONN185_2 0x37a8 +#define AFE_CONN185_4 0x37b0 +#define AFE_CONN185_5 0x37b4 +#define AFE_CONN185_6 0x37b8 +#define AFE_CONN185_7 0x37bc +#define AFE_CONN186_0 0x37c0 +#define AFE_CONN186_1 0x37c4 +#define AFE_CONN186_2 0x37c8 +#define AFE_CONN186_4 0x37d0 +#define AFE_CONN186_5 0x37d4 +#define AFE_CONN186_6 0x37d8 +#define AFE_CONN186_7 0x37dc +#define AFE_CONN187_0 0x37e0 +#define AFE_CONN187_1 0x37e4 +#define AFE_CONN187_2 0x37e8 +#define AFE_CONN187_4 0x37f0 +#define AFE_CONN187_5 0x37f4 +#define AFE_CONN187_6 0x37f8 +#define AFE_CONN187_7 0x37fc +#define AFE_CONN188_0 0x3800 +#define AFE_CONN188_1 0x3804 +#define AFE_CONN188_2 0x3808 +#define AFE_CONN188_4 0x3810 +#define AFE_CONN188_5 0x3814 +#define AFE_CONN188_6 0x3818 +#define AFE_CONN188_7 0x381c +#define AFE_CONN189_0 0x3820 +#define AFE_CONN189_1 0x3824 +#define AFE_CONN189_2 0x3828 +#define AFE_CONN189_4 0x3830 +#define AFE_CONN189_5 0x3834 +#define AFE_CONN189_6 0x3838 +#define AFE_CONN189_7 0x383c +#define AFE_CONN190_0 0x3840 +#define AFE_CONN190_1 0x3844 +#define AFE_CONN190_2 0x3848 +#define AFE_CONN190_4 0x3850 +#define AFE_CONN190_5 0x3854 +#define AFE_CONN190_6 0x3858 +#define AFE_CONN190_7 0x385c +#define AFE_CONN191_0 0x3860 +#define AFE_CONN191_1 0x3864 +#define AFE_CONN191_2 0x3868 +#define AFE_CONN191_4 0x3870 +#define AFE_CONN191_5 0x3874 +#define AFE_CONN191_6 0x3878 +#define AFE_CONN191_7 0x387c +#define AFE_CONN192_0 0x3880 +#define AFE_CONN192_1 0x3884 +#define AFE_CONN192_2 0x3888 +#define AFE_CONN192_4 0x3890 +#define AFE_CONN192_5 0x3894 +#define AFE_CONN192_6 0x3898 +#define AFE_CONN192_7 0x389c +#define AFE_CONN193_0 0x38a0 +#define AFE_CONN193_1 0x38a4 +#define AFE_CONN193_2 0x38a8 +#define AFE_CONN193_4 0x38b0 +#define AFE_CONN193_5 0x38b4 +#define AFE_CONN193_6 0x38b8 +#define AFE_CONN193_7 0x38bc +#define AFE_CONN194_0 0x38c0 +#define AFE_CONN194_1 0x38c4 +#define AFE_CONN194_2 0x38c8 +#define AFE_CONN194_4 0x38d0 +#define AFE_CONN194_5 0x38d4 +#define AFE_CONN194_6 0x38d8 +#define AFE_CONN194_7 0x38dc +#define AFE_CONN195_0 0x38e0 +#define AFE_CONN195_1 0x38e4 +#define AFE_CONN195_2 0x38e8 +#define AFE_CONN195_4 0x38f0 +#define AFE_CONN195_5 0x38f4 +#define AFE_CONN195_6 0x38f8 +#define AFE_CONN195_7 0x38fc +#define AFE_CONN196_0 0x3900 +#define AFE_CONN196_1 0x3904 +#define AFE_CONN196_2 0x3908 +#define AFE_CONN196_4 0x3910 +#define AFE_CONN196_5 0x3914 +#define AFE_CONN196_6 0x3918 +#define AFE_CONN196_7 0x391c +#define AFE_CONN197_0 0x3920 +#define AFE_CONN197_1 0x3924 +#define AFE_CONN197_2 0x3928 +#define AFE_CONN197_4 0x3930 +#define AFE_CONN197_5 0x3934 +#define AFE_CONN197_6 0x3938 +#define AFE_CONN197_7 0x393c +#define AFE_CONN198_0 0x3940 +#define AFE_CONN198_1 0x3944 +#define AFE_CONN198_2 0x3948 +#define AFE_CONN198_4 0x3950 +#define AFE_CONN198_5 0x3954 +#define AFE_CONN198_6 0x3958 +#define AFE_CONN198_7 0x395c +#define AFE_CONN199_0 0x3960 +#define AFE_CONN199_1 0x3964 +#define AFE_CONN199_2 0x3968 +#define AFE_CONN199_4 0x3970 +#define AFE_CONN199_5 0x3974 +#define AFE_CONN199_6 0x3978 +#define AFE_CONN199_7 0x397c +#define AFE_CONN200_0 0x3980 +#define AFE_CONN200_1 0x3984 +#define AFE_CONN200_2 0x3988 +#define AFE_CONN200_4 0x3990 +#define AFE_CONN200_5 0x3994 +#define AFE_CONN200_6 0x3998 +#define AFE_CONN200_7 0x399c +#define AFE_CONN201_0 0x39a0 +#define AFE_CONN201_1 0x39a4 +#define AFE_CONN201_2 0x39a8 +#define AFE_CONN201_4 0x39b0 +#define AFE_CONN201_5 0x39b4 +#define AFE_CONN201_6 0x39b8 +#define AFE_CONN201_7 0x39bc +#define AFE_CONN202_0 0x39c0 +#define AFE_CONN202_1 0x39c4 +#define AFE_CONN202_2 0x39c8 +#define AFE_CONN202_4 0x39d0 +#define AFE_CONN202_5 0x39d4 +#define AFE_CONN202_6 0x39d8 +#define AFE_CONN202_7 0x39dc +#define AFE_CONN203_0 0x39e0 +#define AFE_CONN203_1 0x39e4 +#define AFE_CONN203_2 0x39e8 +#define AFE_CONN203_4 0x39f0 +#define AFE_CONN203_5 0x39f4 +#define AFE_CONN203_6 0x39f8 +#define AFE_CONN203_7 0x39fc +#define AFE_CONN204_0 0x3a00 +#define AFE_CONN204_1 0x3a04 +#define AFE_CONN204_2 0x3a08 +#define AFE_CONN204_4 0x3a10 +#define AFE_CONN204_5 0x3a14 +#define AFE_CONN204_6 0x3a18 +#define AFE_CONN204_7 0x3a1c +#define AFE_CONN205_0 0x3a20 +#define AFE_CONN205_1 0x3a24 +#define AFE_CONN205_2 0x3a28 +#define AFE_CONN205_4 0x3a30 +#define AFE_CONN205_5 0x3a34 +#define AFE_CONN205_6 0x3a38 +#define AFE_CONN205_7 0x3a3c +#define AFE_CONN206_0 0x3a40 +#define AFE_CONN206_1 0x3a44 +#define AFE_CONN206_2 0x3a48 +#define AFE_CONN206_4 0x3a50 +#define AFE_CONN206_5 0x3a54 +#define AFE_CONN206_6 0x3a58 +#define AFE_CONN206_7 0x3a5c +#define AFE_CONN207_0 0x3a60 +#define AFE_CONN207_1 0x3a64 +#define AFE_CONN207_2 0x3a68 +#define AFE_CONN207_4 0x3a70 +#define AFE_CONN207_5 0x3a74 +#define AFE_CONN207_6 0x3a78 +#define AFE_CONN207_7 0x3a7c +#define AFE_CONN208_0 0x3a80 +#define AFE_CONN208_1 0x3a84 +#define AFE_CONN208_2 0x3a88 +#define AFE_CONN208_4 0x3a90 +#define AFE_CONN208_5 0x3a94 +#define AFE_CONN208_6 0x3a98 +#define AFE_CONN208_7 0x3a9c +#define AFE_CONN209_0 0x3aa0 +#define AFE_CONN209_1 0x3aa4 +#define AFE_CONN209_2 0x3aa8 +#define AFE_CONN209_4 0x3ab0 +#define AFE_CONN209_5 0x3ab4 +#define AFE_CONN209_6 0x3ab8 +#define AFE_CONN209_7 0x3abc +#define AFE_CONN210_0 0x3ac0 +#define AFE_CONN210_1 0x3ac4 +#define AFE_CONN210_2 0x3ac8 +#define AFE_CONN210_4 0x3ad0 +#define AFE_CONN210_5 0x3ad4 +#define AFE_CONN210_6 0x3ad8 +#define AFE_CONN210_7 0x3adc +#define AFE_CONN211_0 0x3ae0 +#define AFE_CONN211_1 0x3ae4 +#define AFE_CONN211_2 0x3ae8 +#define AFE_CONN211_4 0x3af0 +#define AFE_CONN211_5 0x3af4 +#define AFE_CONN211_6 0x3af8 +#define AFE_CONN211_7 0x3afc +#define AFE_CONN_MON_CFG 0x4080 +#define AFE_CONN_MON0 0x4084 +#define AFE_CONN_MON1 0x4088 +#define AFE_CONN_MON2 0x408c +#define AFE_CONN_MON3 0x4090 +#define AFE_CONN_MON4 0x4094 +#define AFE_CONN_MON5 0x4098 +#define AFE_CONN_RS_0 0x40a0 +#define AFE_CONN_RS_1 0x40a4 +#define AFE_CONN_RS_2 0x40a8 +#define AFE_CONN_RS_3 0x40ac +#define AFE_CONN_RS_4 0x40b0 +#define AFE_CONN_RS_5 0x40b4 +#define AFE_CONN_RS_6 0x40b8 +#define AFE_CONN_DI_0 0x40c0 +#define AFE_CONN_DI_1 0x40c4 +#define AFE_CONN_DI_2 0x40c8 +#define AFE_CONN_DI_3 0x40cc +#define AFE_CONN_DI_4 0x40d0 +#define AFE_CONN_DI_5 0x40d4 +#define AFE_CONN_DI_6 0x40d8 +#define AFE_CONN_16BIT_0 0x40e0 +#define AFE_CONN_16BIT_1 0x40e4 +#define AFE_CONN_16BIT_2 0x40e8 +#define AFE_CONN_16BIT_3 0x40ec +#define AFE_CONN_16BIT_4 0x40f0 +#define AFE_CONN_16BIT_5 0x40f4 +#define AFE_CONN_16BIT_6 0x40f8 +#define AFE_CONN_24BIT_0 0x4100 +#define AFE_CONN_24BIT_1 0x4104 +#define AFE_CONN_24BIT_2 0x4108 +#define AFE_CONN_24BIT_3 0x410c +#define AFE_CONN_24BIT_4 0x4110 +#define AFE_CONN_24BIT_5 0x4114 +#define AFE_CONN_24BIT_6 0x4118 +#define AFE_CBIP_CFG0 0x4380 +#define AFE_CBIP_SLV_DECODER_MON0 0x4384 +#define AFE_CBIP_SLV_DECODER_MON1 0x4388 +#define AFE_CBIP_SLV_MUX_MON_CFG 0x438c +#define AFE_CBIP_SLV_MUX_MON0 0x4390 +#define AFE_CBIP_SLV_MUX_MON1 0x4394 +#define AFE_MEMIF_CON0 0x4400 +#define AFE_MEMIF_ONE_HEART 0x4420 +#define AFE_DL0_BASE_MSB 0x4440 +#define AFE_DL0_BASE 0x4444 +#define AFE_DL0_CUR_MSB 0x4448 +#define AFE_DL0_CUR 0x444c +#define AFE_DL0_END_MSB 0x4450 +#define AFE_DL0_END 0x4454 +#define AFE_DL0_RCH_MON 0x4458 +#define AFE_DL0_LCH_MON 0x445c +#define AFE_DL0_CON0 0x4460 +#define AFE_DL0_MON0 0x4464 +#define AFE_DL1_BASE_MSB 0x4470 +#define AFE_DL1_BASE 0x4474 +#define AFE_DL1_CUR_MSB 0x4478 +#define AFE_DL1_CUR 0x447c +#define AFE_DL1_END_MSB 0x4480 +#define AFE_DL1_END 0x4484 +#define AFE_DL1_RCH_MON 0x4488 +#define AFE_DL1_LCH_MON 0x448c +#define AFE_DL1_CON0 0x4490 +#define AFE_DL1_MON0 0x4494 +#define AFE_DL2_BASE_MSB 0x44a0 +#define AFE_DL2_BASE 0x44a4 +#define AFE_DL2_CUR_MSB 0x44a8 +#define AFE_DL2_CUR 0x44ac +#define AFE_DL2_END_MSB 0x44b0 +#define AFE_DL2_END 0x44b4 +#define AFE_DL2_RCH_MON 0x44b8 +#define AFE_DL2_LCH_MON 0x44bc +#define AFE_DL2_CON0 0x44c0 +#define AFE_DL2_MON0 0x44c4 +#define AFE_DL3_BASE_MSB 0x44d0 +#define AFE_DL3_BASE 0x44d4 +#define AFE_DL3_CUR_MSB 0x44d8 +#define AFE_DL3_CUR 0x44dc +#define AFE_DL3_END_MSB 0x44e0 +#define AFE_DL3_END 0x44e4 +#define AFE_DL3_RCH_MON 0x44e8 +#define AFE_DL3_LCH_MON 0x44ec +#define AFE_DL3_CON0 0x44f0 +#define AFE_DL3_MON0 0x44f4 +#define AFE_DL4_BASE_MSB 0x4500 +#define AFE_DL4_BASE 0x4504 +#define AFE_DL4_CUR_MSB 0x4508 +#define AFE_DL4_CUR 0x450c +#define AFE_DL4_END_MSB 0x4510 +#define AFE_DL4_END 0x4514 +#define AFE_DL4_RCH_MON 0x4518 +#define AFE_DL4_LCH_MON 0x451c +#define AFE_DL4_CON0 0x4520 +#define AFE_DL4_MON0 0x4524 +#define AFE_DL5_BASE_MSB 0x4530 +#define AFE_DL5_BASE 0x4534 +#define AFE_DL5_CUR_MSB 0x4538 +#define AFE_DL5_CUR 0x453c +#define AFE_DL5_END_MSB 0x4540 +#define AFE_DL5_END 0x4544 +#define AFE_DL5_RCH_MON 0x4548 +#define AFE_DL5_LCH_MON 0x454c +#define AFE_DL5_CON0 0x4550 +#define AFE_DL5_MON0 0x4554 +#define AFE_DL6_BASE_MSB 0x4560 +#define AFE_DL6_BASE 0x4564 +#define AFE_DL6_CUR_MSB 0x4568 +#define AFE_DL6_CUR 0x456c +#define AFE_DL6_END_MSB 0x4570 +#define AFE_DL6_END 0x4574 +#define AFE_DL6_RCH_MON 0x4578 +#define AFE_DL6_LCH_MON 0x457c +#define AFE_DL6_CON0 0x4580 +#define AFE_DL6_MON0 0x4584 +#define AFE_DL7_BASE_MSB 0x4590 +#define AFE_DL7_BASE 0x4594 +#define AFE_DL7_CUR_MSB 0x4598 +#define AFE_DL7_CUR 0x459c +#define AFE_DL7_END_MSB 0x45a0 +#define AFE_DL7_END 0x45a4 +#define AFE_DL7_RCH_MON 0x45a8 +#define AFE_DL7_LCH_MON 0x45ac +#define AFE_DL7_CON0 0x45b0 +#define AFE_DL7_MON0 0x45b4 +#define AFE_DL8_BASE_MSB 0x45c0 +#define AFE_DL8_BASE 0x45c4 +#define AFE_DL8_CUR_MSB 0x45c8 +#define AFE_DL8_CUR 0x45cc +#define AFE_DL8_END_MSB 0x45d0 +#define AFE_DL8_END 0x45d4 +#define AFE_DL8_RCH_MON 0x45d8 +#define AFE_DL8_LCH_MON 0x45dc +#define AFE_DL8_CON0 0x45e0 +#define AFE_DL8_MON0 0x45e4 +#define AFE_DL_4CH_BASE_MSB 0x45f0 +#define AFE_DL_4CH_BASE 0x45f4 +#define AFE_DL_4CH_CUR_MSB 0x45f8 +#define AFE_DL_4CH_CUR 0x45fc +#define AFE_DL_4CH_END_MSB 0x4600 +#define AFE_DL_4CH_END 0x4604 +#define AFE_DL_4CH_CON0 0x4610 +#define AFE_DL_4CH_MON0 0x4618 +#define AFE_DL_24CH_BASE_MSB 0x4620 +#define AFE_DL_24CH_BASE 0x4624 +#define AFE_DL_24CH_CUR_MSB 0x4628 +#define AFE_DL_24CH_CUR 0x462c +#define AFE_DL_24CH_END_MSB 0x4630 +#define AFE_DL_24CH_END 0x4634 +#define AFE_DL_24CH_CON0 0x4640 +#define AFE_DL_24CH_MON0 0x4648 +#define AFE_DL23_BASE_MSB 0x4680 +#define AFE_DL23_BASE 0x4684 +#define AFE_DL23_CUR_MSB 0x4688 +#define AFE_DL23_CUR 0x468c +#define AFE_DL23_END_MSB 0x4690 +#define AFE_DL23_END 0x4694 +#define AFE_DL23_RCH_MON 0x4698 +#define AFE_DL23_LCH_MON 0x469c +#define AFE_DL23_CON0 0x46a0 +#define AFE_DL23_MON0 0x46a4 +#define AFE_DL24_BASE_MSB 0x46b0 +#define AFE_DL24_BASE 0x46b4 +#define AFE_DL24_CUR_MSB 0x46b8 +#define AFE_DL24_CUR 0x46bc +#define AFE_DL24_END_MSB 0x46c0 +#define AFE_DL24_END 0x46c4 +#define AFE_DL24_RCH_MON 0x46c8 +#define AFE_DL24_LCH_MON 0x46cc +#define AFE_DL24_CON0 0x46d0 +#define AFE_DL24_MON0 0x46d4 +#define AFE_DL25_BASE_MSB 0x46e0 +#define AFE_DL25_BASE 0x46e4 +#define AFE_DL25_CUR_MSB 0x46e8 +#define AFE_DL25_CUR 0x46ec +#define AFE_DL25_END_MSB 0x46f0 +#define AFE_DL25_END 0x46f4 +#define AFE_DL25_RCH_MON 0x46f8 +#define AFE_DL25_LCH_MON 0x46fc +#define AFE_DL25_CON0 0x4700 +#define AFE_DL25_MON0 0x4704 +#define AFE_DL26_BASE_MSB 0x4710 +#define AFE_DL26_BASE 0x4714 +#define AFE_DL26_CUR_MSB 0x4718 +#define AFE_DL26_CUR 0x471c +#define AFE_DL26_END_MSB 0x4720 +#define AFE_DL26_END 0x4724 +#define AFE_DL26_RCH_MON 0x4728 +#define AFE_DL26_LCH_MON 0x472c +#define AFE_DL26_CON0 0x4730 +#define AFE_DL26_MON0 0x4734 +#define AFE_VUL0_BASE_MSB 0x4d60 +#define AFE_VUL0_BASE 0x4d64 +#define AFE_VUL0_CUR_MSB 0x4d68 +#define AFE_VUL0_CUR 0x4d6c +#define AFE_VUL0_END_MSB 0x4d70 +#define AFE_VUL0_END 0x4d74 +#define AFE_VUL0_RCH_MON 0x4d78 +#define AFE_VUL0_LCH_MON 0x4d7c +#define AFE_VUL0_CON0 0x4d80 +#define AFE_VUL0_MON0 0x4d84 +#define AFE_VUL1_BASE_MSB 0x4d90 +#define AFE_VUL1_BASE 0x4d94 +#define AFE_VUL1_CUR_MSB 0x4d98 +#define AFE_VUL1_CUR 0x4d9c +#define AFE_VUL1_END_MSB 0x4da0 +#define AFE_VUL1_END 0x4da4 +#define AFE_VUL1_RCH_MON 0x4da8 +#define AFE_VUL1_LCH_MON 0x4dac +#define AFE_VUL1_CON0 0x4db0 +#define AFE_VUL1_MON0 0x4db4 +#define AFE_VUL2_BASE_MSB 0x4dc0 +#define AFE_VUL2_BASE 0x4dc4 +#define AFE_VUL2_CUR_MSB 0x4dc8 +#define AFE_VUL2_CUR 0x4dcc +#define AFE_VUL2_END_MSB 0x4dd0 +#define AFE_VUL2_END 0x4dd4 +#define AFE_VUL2_RCH_MON 0x4dd8 +#define AFE_VUL2_LCH_MON 0x4ddc +#define AFE_VUL2_CON0 0x4de0 +#define AFE_VUL2_MON0 0x4de4 +#define AFE_VUL3_BASE_MSB 0x4df0 +#define AFE_VUL3_BASE 0x4df4 +#define AFE_VUL3_CUR_MSB 0x4df8 +#define AFE_VUL3_CUR 0x4dfc +#define AFE_VUL3_END_MSB 0x4e00 +#define AFE_VUL3_END 0x4e04 +#define AFE_VUL3_RCH_MON 0x4e08 +#define AFE_VUL3_LCH_MON 0x4e0c +#define AFE_VUL3_CON0 0x4e10 +#define AFE_VUL3_MON0 0x4e14 +#define AFE_VUL4_BASE_MSB 0x4e20 +#define AFE_VUL4_BASE 0x4e24 +#define AFE_VUL4_CUR_MSB 0x4e28 +#define AFE_VUL4_CUR 0x4e2c +#define AFE_VUL4_END_MSB 0x4e30 +#define AFE_VUL4_END 0x4e34 +#define AFE_VUL4_RCH_MON 0x4e38 +#define AFE_VUL4_LCH_MON 0x4e3c +#define AFE_VUL4_CON0 0x4e40 +#define AFE_VUL4_MON0 0x4e44 +#define AFE_VUL5_BASE_MSB 0x4e50 +#define AFE_VUL5_BASE 0x4e54 +#define AFE_VUL5_CUR_MSB 0x4e58 +#define AFE_VUL5_CUR 0x4e5c +#define AFE_VUL5_END_MSB 0x4e60 +#define AFE_VUL5_END 0x4e64 +#define AFE_VUL5_RCH_MON 0x4e68 +#define AFE_VUL5_LCH_MON 0x4e6c +#define AFE_VUL5_CON0 0x4e70 +#define AFE_VUL5_MON0 0x4e74 +#define AFE_VUL6_BASE_MSB 0x4e80 +#define AFE_VUL6_BASE 0x4e84 +#define AFE_VUL6_CUR_MSB 0x4e88 +#define AFE_VUL6_CUR 0x4e8c +#define AFE_VUL6_END_MSB 0x4e90 +#define AFE_VUL6_END 0x4e94 +#define AFE_VUL6_RCH_MON 0x4e98 +#define AFE_VUL6_LCH_MON 0x4e9c +#define AFE_VUL6_CON0 0x4ea0 +#define AFE_VUL6_MON0 0x4ea4 +#define AFE_VUL7_BASE_MSB 0x4eb0 +#define AFE_VUL7_BASE 0x4eb4 +#define AFE_VUL7_CUR_MSB 0x4eb8 +#define AFE_VUL7_CUR 0x4ebc +#define AFE_VUL7_END_MSB 0x4ec0 +#define AFE_VUL7_END 0x4ec4 +#define AFE_VUL7_RCH_MON 0x4ec8 +#define AFE_VUL7_LCH_MON 0x4ecc +#define AFE_VUL7_CON0 0x4ed0 +#define AFE_VUL7_MON0 0x4ed4 +#define AFE_VUL8_BASE_MSB 0x4ee0 +#define AFE_VUL8_BASE 0x4ee4 +#define AFE_VUL8_CUR_MSB 0x4ee8 +#define AFE_VUL8_CUR 0x4eec +#define AFE_VUL8_END_MSB 0x4ef0 +#define AFE_VUL8_END 0x4ef4 +#define AFE_VUL8_RCH_MON 0x4ef8 +#define AFE_VUL8_LCH_MON 0x4efc +#define AFE_VUL8_CON0 0x4f00 +#define AFE_VUL8_MON0 0x4f04 +#define AFE_VUL9_BASE_MSB 0x4f10 +#define AFE_VUL9_BASE 0x4f14 +#define AFE_VUL9_CUR_MSB 0x4f18 +#define AFE_VUL9_CUR 0x4f1c +#define AFE_VUL9_END_MSB 0x4f20 +#define AFE_VUL9_END 0x4f24 +#define AFE_VUL9_RCH_MON 0x4f28 +#define AFE_VUL9_LCH_MON 0x4f2c +#define AFE_VUL9_CON0 0x4f30 +#define AFE_VUL9_MON0 0x4f34 +#define AFE_VUL10_BASE_MSB 0x4f40 +#define AFE_VUL10_BASE 0x4f44 +#define AFE_VUL10_CUR_MSB 0x4f48 +#define AFE_VUL10_CUR 0x4f4c +#define AFE_VUL10_END_MSB 0x4f50 +#define AFE_VUL10_END 0x4f54 +#define AFE_VUL10_RCH_MON 0x4f58 +#define AFE_VUL10_LCH_MON 0x4f5c +#define AFE_VUL10_CON0 0x4f60 +#define AFE_VUL10_MON0 0x4f64 +#define AFE_VUL24_BASE_MSB 0x4fa0 +#define AFE_VUL24_BASE 0x4fa4 +#define AFE_VUL24_CUR_MSB 0x4fa8 +#define AFE_VUL24_CUR 0x4fac +#define AFE_VUL24_END_MSB 0x4fb0 +#define AFE_VUL24_END 0x4fb4 +#define AFE_VUL24_CON0 0x4fb8 +#define AFE_VUL24_MON0 0x4fbc +#define AFE_VUL25_BASE_MSB 0x4fc0 +#define AFE_VUL25_BASE 0x4fc4 +#define AFE_VUL25_CUR_MSB 0x4fc8 +#define AFE_VUL25_CUR 0x4fcc +#define AFE_VUL25_END_MSB 0x4fd0 +#define AFE_VUL25_END 0x4fd4 +#define AFE_VUL25_CON0 0x4fd8 +#define AFE_VUL25_MON0 0x4fdc +#define AFE_VUL26_BASE_MSB 0x4fe0 +#define AFE_VUL26_BASE 0x4fe4 +#define AFE_VUL26_CUR_MSB 0x4fe8 +#define AFE_VUL26_CUR 0x4fec +#define AFE_VUL26_END_MSB 0x4ff0 +#define AFE_VUL26_END 0x4ff4 +#define AFE_VUL26_CON0 0x4ff8 +#define AFE_VUL26_MON0 0x4ffc +#define AFE_VUL_CM0_BASE_MSB 0x51c0 +#define AFE_VUL_CM0_BASE 0x51c4 +#define AFE_VUL_CM0_CUR_MSB 0x51c8 +#define AFE_VUL_CM0_CUR 0x51cc +#define AFE_VUL_CM0_END_MSB 0x51d0 +#define AFE_VUL_CM0_END 0x51d4 +#define AFE_VUL_CM0_CON0 0x51d8 +#define AFE_VUL_CM1_BASE_MSB 0x51e0 +#define AFE_VUL_CM1_BASE 0x51e4 +#define AFE_VUL_CM1_CUR_MSB 0x51e8 +#define AFE_VUL_CM1_CUR 0x51ec +#define AFE_VUL_CM1_END_MSB 0x51f0 +#define AFE_VUL_CM1_END 0x51f4 +#define AFE_VUL_CM1_CON0 0x51f8 +#define AFE_VUL_CM2_BASE_MSB 0x5200 +#define AFE_VUL_CM2_BASE 0x5204 +#define AFE_VUL_CM2_CUR_MSB 0x5208 +#define AFE_VUL_CM2_CUR 0x520c +#define AFE_VUL_CM2_END_MSB 0x5210 +#define AFE_VUL_CM2_END 0x5214 +#define AFE_VUL_CM2_CON0 0x5218 +#define AFE_ETDM_IN0_BASE_MSB 0x5220 +#define AFE_ETDM_IN0_BASE 0x5224 +#define AFE_ETDM_IN0_CUR_MSB 0x5228 +#define AFE_ETDM_IN0_CUR 0x522c +#define AFE_ETDM_IN0_END_MSB 0x5230 +#define AFE_ETDM_IN0_END 0x5234 +#define AFE_ETDM_IN0_CON0 0x5238 +#define AFE_ETDM_IN1_BASE_MSB 0x5240 +#define AFE_ETDM_IN1_BASE 0x5244 +#define AFE_ETDM_IN1_CUR_MSB 0x5248 +#define AFE_ETDM_IN1_CUR 0x524c +#define AFE_ETDM_IN1_END_MSB 0x5250 +#define AFE_ETDM_IN1_END 0x5254 +#define AFE_ETDM_IN1_CON0 0x5258 +#define AFE_ETDM_IN2_BASE_MSB 0x5260 +#define AFE_ETDM_IN2_BASE 0x5264 +#define AFE_ETDM_IN2_CUR_MSB 0x5268 +#define AFE_ETDM_IN2_CUR 0x526c +#define AFE_ETDM_IN2_END_MSB 0x5270 +#define AFE_ETDM_IN2_END 0x5274 +#define AFE_ETDM_IN2_CON0 0x5278 +#define AFE_ETDM_IN3_BASE_MSB 0x5280 +#define AFE_ETDM_IN3_BASE 0x5284 +#define AFE_ETDM_IN3_CUR_MSB 0x5288 +#define AFE_ETDM_IN3_CUR 0x528c +#define AFE_ETDM_IN3_END_MSB 0x5290 +#define AFE_ETDM_IN3_END 0x5294 +#define AFE_ETDM_IN3_CON0 0x5298 +#define AFE_ETDM_IN4_BASE_MSB 0x52a0 +#define AFE_ETDM_IN4_BASE 0x52a4 +#define AFE_ETDM_IN4_CUR_MSB 0x52a8 +#define AFE_ETDM_IN4_CUR 0x52ac +#define AFE_ETDM_IN4_END_MSB 0x52b0 +#define AFE_ETDM_IN4_END 0x52b4 +#define AFE_ETDM_IN4_CON0 0x52b8 +#define AFE_ETDM_IN5_BASE_MSB 0x52c0 +#define AFE_ETDM_IN5_BASE 0x52c4 +#define AFE_ETDM_IN5_CUR_MSB 0x52c8 +#define AFE_ETDM_IN5_CUR 0x52cc +#define AFE_ETDM_IN5_END_MSB 0x52d0 +#define AFE_ETDM_IN5_END 0x52d4 +#define AFE_ETDM_IN5_CON0 0x52d8 +#define AFE_ETDM_IN6_BASE_MSB 0x52e0 +#define AFE_ETDM_IN6_BASE 0x52e4 +#define AFE_ETDM_IN6_CUR_MSB 0x52e8 +#define AFE_ETDM_IN6_CUR 0x52ec +#define AFE_ETDM_IN6_END_MSB 0x52f0 +#define AFE_ETDM_IN6_END 0x52f4 +#define AFE_ETDM_IN6_CON0 0x52f8 +#define AFE_HDMI_OUT_BASE_MSB 0x5360 +#define AFE_HDMI_OUT_BASE 0x5364 +#define AFE_HDMI_OUT_CUR_MSB 0x5368 +#define AFE_HDMI_OUT_CUR 0x536c +#define AFE_HDMI_OUT_END_MSB 0x5370 +#define AFE_HDMI_OUT_END 0x5374 +#define AFE_HDMI_OUT_CON0 0x5378 +#define AFE_VUL24_RCH_MON 0x53e0 +#define AFE_VUL24_LCH_MON 0x53e4 +#define AFE_VUL25_RCH_MON 0x53e8 +#define AFE_VUL25_LCH_MON 0x53ec +#define AFE_VUL26_RCH_MON 0x53f0 +#define AFE_VUL26_LCH_MON 0x53f4 +#define AFE_VUL_CM0_RCH_MON 0x5458 +#define AFE_VUL_CM0_LCH_MON 0x545c +#define AFE_VUL_CM1_RCH_MON 0x5460 +#define AFE_VUL_CM1_LCH_MON 0x5464 +#define AFE_VUL_CM2_RCH_MON 0x5468 +#define AFE_VUL_CM2_LCH_MON 0x546c +#define AFE_DL_4CH_CH0_MON 0x54f4 +#define AFE_DL_4CH_CH1_MON 0x54f8 +#define AFE_DL_4CH_CH2_MON 0x54fc +#define AFE_DL_4CH_CH3_MON 0x5500 +#define AFE_DL_24CH_CH0_MON 0x5504 +#define AFE_DL_24CH_CH1_MON 0x5508 +#define AFE_DL_24CH_CH2_MON 0x550c +#define AFE_DL_24CH_CH3_MON 0x5510 +#define AFE_DL_24CH_CH4_MON 0x5514 +#define AFE_DL_24CH_CH5_MON 0x5518 +#define AFE_DL_24CH_CH6_MON 0x551c +#define AFE_DL_24CH_CH7_MON 0x5520 +#define AFE_DL_24CH_CH8_MON 0x5524 +#define AFE_DL_24CH_CH9_MON 0x5528 +#define AFE_DL_24CH_CH10_MON 0x552c +#define AFE_DL_24CH_CH11_MON 0x5530 +#define AFE_DL_24CH_CH12_MON 0x5534 +#define AFE_DL_24CH_CH13_MON 0x5538 +#define AFE_DL_24CH_CH14_MON 0x553c +#define AFE_DL_24CH_CH15_MON 0x5540 +#define AFE_SRAM_BOUND 0x5620 +#define AFE_SECURE_CON0 0x5624 +#define AFE_SECURE_CON1 0x5628 +#define AFE_SE_SECURE_CON0 0x5630 +#define AFE_SE_SECURE_CON1 0x5634 +#define AFE_SE_SECURE_CON2 0x5638 +#define AFE_SE_SECURE_CON3 0x563c +#define AFE_SE_PROT_SIDEBAND0 0x5640 +#define AFE_SE_PROT_SIDEBAND1 0x5644 +#define AFE_SE_PROT_SIDEBAND2 0x5648 +#define AFE_SE_PROT_SIDEBAND3 0x564c +#define AFE_SE_DOMAIN_SIDEBAND0 0x5650 +#define AFE_SE_DOMAIN_SIDEBAND1 0x5654 +#define AFE_SE_DOMAIN_SIDEBAND2 0x5658 +#define AFE_SE_DOMAIN_SIDEBAND3 0x565c +#define AFE_SE_DOMAIN_SIDEBAND4 0x5660 +#define AFE_SE_DOMAIN_SIDEBAND5 0x5664 +#define AFE_SE_DOMAIN_SIDEBAND6 0x5668 +#define AFE_SE_DOMAIN_SIDEBAND7 0x566c +#define AFE_SE_DOMAIN_SIDEBAND8 0x5670 +#define AFE_SE_DOMAIN_SIDEBAND9 0x5674 +#define AFE_PROT_SIDEBAND0_MON 0x5678 +#define AFE_PROT_SIDEBAND1_MON 0x567c +#define AFE_PROT_SIDEBAND2_MON 0x5680 +#define AFE_PROT_SIDEBAND3_MON 0x5684 +#define AFE_DOMAIN_SIDEBAND0_MON 0x5688 +#define AFE_DOMAIN_SIDEBAND1_MON 0x568c +#define AFE_DOMAIN_SIDEBAND2_MON 0x5690 +#define AFE_DOMAIN_SIDEBAND3_MON 0x5694 +#define AFE_DOMAIN_SIDEBAND4_MON 0x5698 +#define AFE_DOMAIN_SIDEBAND5_MON 0x569c +#define AFE_DOMAIN_SIDEBAND6_MON 0x56a0 +#define AFE_DOMAIN_SIDEBAND7_MON 0x56a4 +#define AFE_DOMAIN_SIDEBAND8_MON 0x56a8 +#define AFE_DOMAIN_SIDEBAND9_MON 0x56ac +#define AFE_SECURE_CONN0 0x56b0 +#define AFE_SECURE_CONN_ETDM0 0x56b4 +#define AFE_SECURE_CONN_ETDM1 0x56b8 +#define AFE_SECURE_CONN_ETDM2 0x56bc +#define AFE_SECURE_SRAM_CON0 0x56c0 +#define AFE_SECURE_SRAM_CON1 0x56c4 +#define AFE_SE_CONN_INPUT_MASK0 0x56d0 +#define AFE_SE_CONN_INPUT_MASK1 0x56d4 +#define AFE_SE_CONN_INPUT_MASK2 0x56d8 +#define AFE_SE_CONN_INPUT_MASK3 0x56dc +#define AFE_SE_CONN_INPUT_MASK4 0x56e0 +#define AFE_SE_CONN_INPUT_MASK5 0x56e4 +#define AFE_SE_CONN_INPUT_MASK6 0x56e8 +#define AFE_SE_CONN_INPUT_MASK7 0x56ec +#define AFE_NON_SE_CONN_INPUT_MASK0 0x56f0 +#define AFE_NON_SE_CONN_INPUT_MASK1 0x56f4 +#define AFE_NON_SE_CONN_INPUT_MASK2 0x56f8 +#define AFE_NON_SE_CONN_INPUT_MASK3 0x56fc +#define AFE_NON_SE_CONN_INPUT_MASK4 0x5700 +#define AFE_NON_SE_CONN_INPUT_MASK5 0x5704 +#define AFE_NON_SE_CONN_INPUT_MASK6 0x5708 +#define AFE_NON_SE_CONN_INPUT_MASK7 0x570c +#define AFE_SE_CONN_OUTPUT_SEL0 0x5710 +#define AFE_SE_CONN_OUTPUT_SEL1 0x5714 +#define AFE_SE_CONN_OUTPUT_SEL2 0x5718 +#define AFE_SE_CONN_OUTPUT_SEL3 0x571c +#define AFE_SE_CONN_OUTPUT_SEL4 0x5720 +#define AFE_SE_CONN_OUTPUT_SEL5 0x5724 +#define AFE_SE_CONN_OUTPUT_SEL6 0x5728 +#define AFE_SE_CONN_OUTPUT_SEL7 0x572c +#define AFE_PCM0_INTF_CON1_MASK_MON 0x5730 +#define AFE_PCM0_INTF_CON0_MASK_MON 0x5734 +#define AFE_CONNSYS_I2S_CON_MASK_MON 0x5738 +#define AFE_TDM_CON2_MASK_MON 0x5744 +#define AFE_MTKAIF0_CFG0_MASK_MON 0x574c +#define AFE_MTKAIF1_CFG0_MASK_MON 0x5750 +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON 0x5754 +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON 0x5758 +#define AFE_ADDA_UL2_SRC_CON0_MASK_MON 0x575c +#define AFE_ASRC_NEW_CON0 0x7800 +#define AFE_ASRC_NEW_CON1 0x7804 +#define AFE_ASRC_NEW_CON2 0x7808 +#define AFE_ASRC_NEW_CON3 0x780c +#define AFE_ASRC_NEW_CON4 0x7810 +#define AFE_ASRC_NEW_CON5 0x7814 +#define AFE_ASRC_NEW_CON6 0x7818 +#define AFE_ASRC_NEW_CON7 0x781c +#define AFE_ASRC_NEW_CON8 0x7820 +#define AFE_ASRC_NEW_CON9 0x7824 +#define AFE_ASRC_NEW_CON10 0x7828 +#define AFE_ASRC_NEW_CON11 0x782c +#define AFE_ASRC_NEW_CON12 0x7830 +#define AFE_ASRC_NEW_CON13 0x7834 +#define AFE_ASRC_NEW_CON14 0x7838 +#define AFE_ASRC_NEW_IP_VERSION 0x783c +#define AFE_GASRC0_NEW_CON0 0x7840 +#define AFE_GASRC0_NEW_CON1 0x7844 +#define AFE_GASRC0_NEW_CON2 0x7848 +#define AFE_GASRC0_NEW_CON3 0x784c +#define AFE_GASRC0_NEW_CON4 0x7850 +#define AFE_GASRC0_NEW_CON5 0x7854 +#define AFE_GASRC0_NEW_CON6 0x7858 +#define AFE_GASRC0_NEW_CON7 0x785c +#define AFE_GASRC0_NEW_CON8 0x7860 +#define AFE_GASRC0_NEW_CON9 0x7864 +#define AFE_GASRC0_NEW_CON10 0x7868 +#define AFE_GASRC0_NEW_CON11 0x786c +#define AFE_GASRC0_NEW_CON12 0x7870 +#define AFE_GASRC0_NEW_CON13 0x7874 +#define AFE_GASRC0_NEW_CON14 0x7878 +#define AFE_GASRC0_NEW_IP_VERSION 0x787c +#define AFE_GASRC1_NEW_CON0 0x7880 +#define AFE_GASRC1_NEW_CON1 0x7884 +#define AFE_GASRC1_NEW_CON2 0x7888 +#define AFE_GASRC1_NEW_CON3 0x788c +#define AFE_GASRC1_NEW_CON4 0x7890 +#define AFE_GASRC1_NEW_CON5 0x7894 +#define AFE_GASRC1_NEW_CON6 0x7898 +#define AFE_GASRC1_NEW_CON7 0x789c +#define AFE_GASRC1_NEW_CON8 0x78a0 +#define AFE_GASRC1_NEW_CON9 0x78a4 +#define AFE_GASRC1_NEW_CON10 0x78a8 +#define AFE_GASRC1_NEW_CON11 0x78ac +#define AFE_GASRC1_NEW_CON12 0x78b0 +#define AFE_GASRC1_NEW_CON13 0x78b4 +#define AFE_GASRC1_NEW_CON14 0x78b8 +#define AFE_GASRC1_NEW_IP_VERSION 0x78bc +#define AFE_GASRC2_NEW_CON0 0x78c0 +#define AFE_GASRC2_NEW_CON1 0x78c4 +#define AFE_GASRC2_NEW_CON2 0x78c8 +#define AFE_GASRC2_NEW_CON3 0x78cc +#define AFE_GASRC2_NEW_CON4 0x78d0 +#define AFE_GASRC2_NEW_CON5 0x78d4 +#define AFE_GASRC2_NEW_CON6 0x78d8 +#define AFE_GASRC2_NEW_CON7 0x78dc +#define AFE_GASRC2_NEW_CON8 0x78e0 +#define AFE_GASRC2_NEW_CON9 0x78e4 +#define AFE_GASRC2_NEW_CON10 0x78e8 +#define AFE_GASRC2_NEW_CON11 0x78ec +#define AFE_GASRC2_NEW_CON12 0x78f0 +#define AFE_GASRC2_NEW_CON13 0x78f4 +#define AFE_GASRC2_NEW_CON14 0x78f8 +#define AFE_GASRC2_NEW_IP_VERSION 0x78fc +#define AFE_GASRC3_NEW_CON0 0x7900 +#define AFE_GASRC3_NEW_CON1 0x7904 +#define AFE_GASRC3_NEW_CON2 0x7908 +#define AFE_GASRC3_NEW_CON3 0x790c +#define AFE_GASRC3_NEW_CON4 0x7910 +#define AFE_GASRC3_NEW_CON5 0x7914 +#define AFE_GASRC3_NEW_CON6 0x7918 +#define AFE_GASRC3_NEW_CON7 0x791c +#define AFE_GASRC3_NEW_CON8 0x7920 +#define AFE_GASRC3_NEW_CON9 0x7924 +#define AFE_GASRC3_NEW_CON10 0x7928 +#define AFE_GASRC3_NEW_CON11 0x792c +#define AFE_GASRC3_NEW_CON12 0x7930 +#define AFE_GASRC3_NEW_CON13 0x7934 +#define AFE_GASRC3_NEW_CON14 0x7938 +#define AFE_GASRC3_NEW_IP_VERSION 0x793c +#define AFE_GASRC4_NEW_CON0 0x7940 +#define AFE_GASRC4_NEW_CON1 0x7944 +#define AFE_GASRC4_NEW_CON2 0x7948 +#define AFE_GASRC4_NEW_CON3 0x794c +#define AFE_GASRC4_NEW_CON4 0x7950 +#define AFE_GASRC4_NEW_CON5 0x7954 +#define AFE_GASRC4_NEW_CON6 0x7958 +#define AFE_GASRC4_NEW_CON7 0x795c +#define AFE_GASRC4_NEW_CON8 0x7960 +#define AFE_GASRC4_NEW_CON9 0x7964 +#define AFE_GASRC4_NEW_CON10 0x7968 +#define AFE_GASRC4_NEW_CON11 0x796c +#define AFE_GASRC4_NEW_CON12 0x7970 +#define AFE_GASRC4_NEW_CON13 0x7974 +#define AFE_GASRC4_NEW_CON14 0x7978 +#define AFE_GASRC4_NEW_IP_VERSION 0x797c +#define AFE_GASRC5_NEW_CON0 0x7980 +#define AFE_GASRC5_NEW_CON1 0x7984 +#define AFE_GASRC5_NEW_CON2 0x7988 +#define AFE_GASRC5_NEW_CON3 0x798c +#define AFE_GASRC5_NEW_CON4 0x7990 +#define AFE_GASRC5_NEW_CON5 0x7994 +#define AFE_GASRC5_NEW_CON6 0x7998 +#define AFE_GASRC5_NEW_CON7 0x799c +#define AFE_GASRC5_NEW_CON8 0x79a0 +#define AFE_GASRC5_NEW_CON9 0x79a4 +#define AFE_GASRC5_NEW_CON10 0x79a8 +#define AFE_GASRC5_NEW_CON11 0x79ac +#define AFE_GASRC5_NEW_CON12 0x79b0 +#define AFE_GASRC5_NEW_CON13 0x79b4 +#define AFE_GASRC5_NEW_CON14 0x79b8 +#define AFE_GASRC5_NEW_IP_VERSION 0x79bc +#define AFE_GASRC6_NEW_CON0 0x79c0 +#define AFE_GASRC6_NEW_CON1 0x79c4 +#define AFE_GASRC6_NEW_CON2 0x79c8 +#define AFE_GASRC6_NEW_CON3 0x79cc +#define AFE_GASRC6_NEW_CON4 0x79d0 +#define AFE_GASRC6_NEW_CON5 0x79d4 +#define AFE_GASRC6_NEW_CON6 0x79d8 +#define AFE_GASRC6_NEW_CON7 0x79dc +#define AFE_GASRC6_NEW_CON8 0x79e0 +#define AFE_GASRC6_NEW_CON9 0x79e4 +#define AFE_GASRC6_NEW_CON10 0x79e8 +#define AFE_GASRC6_NEW_CON11 0x79ec +#define AFE_GASRC6_NEW_CON12 0x79f0 +#define AFE_GASRC6_NEW_CON13 0x79f4 +#define AFE_GASRC6_NEW_CON14 0x79f8 +#define AFE_GASRC6_NEW_IP_VERSION 0x79fc +#define AFE_GASRC7_NEW_CON0 0x7a00 +#define AFE_GASRC7_NEW_CON1 0x7a04 +#define AFE_GASRC7_NEW_CON2 0x7a08 +#define AFE_GASRC7_NEW_CON3 0x7a0c +#define AFE_GASRC7_NEW_CON4 0x7a10 +#define AFE_GASRC7_NEW_CON5 0x7a14 +#define AFE_GASRC7_NEW_CON6 0x7a18 +#define AFE_GASRC7_NEW_CON7 0x7a1c +#define AFE_GASRC7_NEW_CON8 0x7a20 +#define AFE_GASRC7_NEW_CON9 0x7a24 +#define AFE_GASRC7_NEW_CON10 0x7a28 +#define AFE_GASRC7_NEW_CON11 0x7a2c +#define AFE_GASRC7_NEW_CON12 0x7a30 +#define AFE_GASRC7_NEW_CON13 0x7a34 +#define AFE_GASRC7_NEW_CON14 0x7a38 +#define AFE_GASRC7_NEW_IP_VERSION 0x7a3c +#define AFE_GASRC8_NEW_CON0 0x7a40 +#define AFE_GASRC8_NEW_CON1 0x7a44 +#define AFE_GASRC8_NEW_CON2 0x7a48 +#define AFE_GASRC8_NEW_CON3 0x7a4c +#define AFE_GASRC8_NEW_CON4 0x7a50 +#define AFE_GASRC8_NEW_CON5 0x7a54 +#define AFE_GASRC8_NEW_CON6 0x7a58 +#define AFE_GASRC8_NEW_CON7 0x7a5c +#define AFE_GASRC8_NEW_CON8 0x7a60 +#define AFE_GASRC8_NEW_CON9 0x7a64 +#define AFE_GASRC8_NEW_CON10 0x7a68 +#define AFE_GASRC8_NEW_CON11 0x7a6c +#define AFE_GASRC8_NEW_CON12 0x7a70 +#define AFE_GASRC8_NEW_CON13 0x7a74 +#define AFE_GASRC8_NEW_CON14 0x7a78 +#define AFE_GASRC8_NEW_IP_VERSION 0x7a7c +#define AFE_GASRC9_NEW_CON0 0x7a80 +#define AFE_GASRC9_NEW_CON1 0x7a84 +#define AFE_GASRC9_NEW_CON2 0x7a88 +#define AFE_GASRC9_NEW_CON3 0x7a8c +#define AFE_GASRC9_NEW_CON4 0x7a90 +#define AFE_GASRC9_NEW_CON5 0x7a94 +#define AFE_GASRC9_NEW_CON6 0x7a98 +#define AFE_GASRC9_NEW_CON7 0x7a9c +#define AFE_GASRC9_NEW_CON8 0x7aa0 +#define AFE_GASRC9_NEW_CON9 0x7aa4 +#define AFE_GASRC9_NEW_CON10 0x7aa8 +#define AFE_GASRC9_NEW_CON11 0x7aac +#define AFE_GASRC9_NEW_CON12 0x7ab0 +#define AFE_GASRC9_NEW_CON13 0x7ab4 +#define AFE_GASRC9_NEW_CON14 0x7ab8 +#define AFE_GASRC9_NEW_IP_VERSION 0x7abc +#define AFE_GASRC10_NEW_CON0 0x7ac0 +#define AFE_GASRC10_NEW_CON1 0x7ac4 +#define AFE_GASRC10_NEW_CON2 0x7ac8 +#define AFE_GASRC10_NEW_CON3 0x7acc +#define AFE_GASRC10_NEW_CON4 0x7ad0 +#define AFE_GASRC10_NEW_CON5 0x7ad4 +#define AFE_GASRC10_NEW_CON6 0x7ad8 +#define AFE_GASRC10_NEW_CON7 0x7adc +#define AFE_GASRC10_NEW_CON8 0x7ae0 +#define AFE_GASRC10_NEW_CON9 0x7ae4 +#define AFE_GASRC10_NEW_CON10 0x7ae8 +#define AFE_GASRC10_NEW_CON11 0x7aec +#define AFE_GASRC10_NEW_CON12 0x7af0 +#define AFE_GASRC10_NEW_CON13 0x7af4 +#define AFE_GASRC10_NEW_CON14 0x7af8 +#define AFE_GASRC10_NEW_IP_VERSION 0x7afc +#define AFE_GASRC11_NEW_CON0 0x7b00 +#define AFE_GASRC11_NEW_CON1 0x7b04 +#define AFE_GASRC11_NEW_CON2 0x7b08 +#define AFE_GASRC11_NEW_CON3 0x7b0c +#define AFE_GASRC11_NEW_CON4 0x7b10 +#define AFE_GASRC11_NEW_CON5 0x7b14 +#define AFE_GASRC11_NEW_CON6 0x7b18 +#define AFE_GASRC11_NEW_CON7 0x7b1c +#define AFE_GASRC11_NEW_CON8 0x7b20 +#define AFE_GASRC11_NEW_CON9 0x7b24 +#define AFE_GASRC11_NEW_CON10 0x7b28 +#define AFE_GASRC11_NEW_CON11 0x7b2c +#define AFE_GASRC11_NEW_CON12 0x7b30 +#define AFE_GASRC11_NEW_CON13 0x7b34 +#define AFE_GASRC11_NEW_CON14 0x7b38 +#define AFE_GASRC11_NEW_IP_VERSION 0x7b3c +#define AFE_GASRC12_NEW_CON0 0x7b40 +#define AFE_GASRC12_NEW_CON1 0x7b44 +#define AFE_GASRC12_NEW_CON2 0x7b48 +#define AFE_GASRC12_NEW_CON3 0x7b4c +#define AFE_GASRC12_NEW_CON4 0x7b50 +#define AFE_GASRC12_NEW_CON5 0x7b54 +#define AFE_GASRC12_NEW_CON6 0x7b58 +#define AFE_GASRC12_NEW_CON7 0x7b5c +#define AFE_GASRC12_NEW_CON8 0x7b60 +#define AFE_GASRC12_NEW_CON9 0x7b64 +#define AFE_GASRC12_NEW_CON10 0x7b68 +#define AFE_GASRC12_NEW_CON11 0x7b6c +#define AFE_GASRC12_NEW_CON12 0x7b70 +#define AFE_GASRC12_NEW_CON13 0x7b74 +#define AFE_GASRC12_NEW_CON14 0x7b78 +#define AFE_GASRC12_NEW_IP_VERSION 0x7b7c +#define AFE_GASRC13_NEW_CON0 0x7b80 +#define AFE_GASRC13_NEW_CON1 0x7b84 +#define AFE_GASRC13_NEW_CON2 0x7b88 +#define AFE_GASRC13_NEW_CON3 0x7b8c +#define AFE_GASRC13_NEW_CON4 0x7b90 +#define AFE_GASRC13_NEW_CON5 0x7b94 +#define AFE_GASRC13_NEW_CON6 0x7b98 +#define AFE_GASRC13_NEW_CON7 0x7b9c +#define AFE_GASRC13_NEW_CON8 0x7ba0 +#define AFE_GASRC13_NEW_CON9 0x7ba4 +#define AFE_GASRC13_NEW_CON10 0x7ba8 +#define AFE_GASRC13_NEW_CON11 0x7bac +#define AFE_GASRC13_NEW_CON12 0x7bb0 +#define AFE_GASRC13_NEW_CON13 0x7bb4 +#define AFE_GASRC13_NEW_CON14 0x7bb8 +#define AFE_GASRC13_NEW_IP_VERSION 0x7bbc +#define AFE_GASRC14_NEW_CON0 0x7bc0 +#define AFE_GASRC14_NEW_CON1 0x7bc4 +#define AFE_GASRC14_NEW_CON2 0x7bc8 +#define AFE_GASRC14_NEW_CON3 0x7bcc +#define AFE_GASRC14_NEW_CON4 0x7bd0 +#define AFE_GASRC14_NEW_CON5 0x7bd4 +#define AFE_GASRC14_NEW_CON6 0x7bd8 +#define AFE_GASRC14_NEW_CON7 0x7bdc +#define AFE_GASRC14_NEW_CON8 0x7be0 +#define AFE_GASRC14_NEW_CON9 0x7be4 +#define AFE_GASRC14_NEW_CON10 0x7be8 +#define AFE_GASRC14_NEW_CON11 0x7bec +#define AFE_GASRC14_NEW_CON12 0x7bf0 +#define AFE_GASRC14_NEW_CON13 0x7bf4 +#define AFE_GASRC14_NEW_CON14 0x7bf8 +#define AFE_GASRC14_NEW_IP_VERSION 0x7bfc +#define AFE_GASRC15_NEW_CON0 0x7c00 +#define AFE_GASRC15_NEW_CON1 0x7c04 +#define AFE_GASRC15_NEW_CON2 0x7c08 +#define AFE_GASRC15_NEW_CON3 0x7c0c +#define AFE_GASRC15_NEW_CON4 0x7c10 +#define AFE_GASRC15_NEW_CON5 0x7c14 +#define AFE_GASRC15_NEW_CON6 0x7c18 +#define AFE_GASRC15_NEW_CON7 0x7c1c +#define AFE_GASRC15_NEW_CON8 0x7c20 +#define AFE_GASRC15_NEW_CON9 0x7c24 +#define AFE_GASRC15_NEW_CON10 0x7c28 +#define AFE_GASRC15_NEW_CON11 0x7c2c +#define AFE_GASRC15_NEW_CON12 0x7c30 +#define AFE_GASRC15_NEW_CON13 0x7c34 +#define AFE_GASRC15_NEW_CON14 0x7c38 +#define AFE_GASRC15_NEW_IP_VERSION 0x7c3c + +#define AFE_MAX_REGISTER AFE_GASRC15_NEW_IP_VERSION + +#define AFE_IRQ_STATUS_BITS 0x87FFFFFF +#define AFE_IRQ_CNT_SHIFT 0 +#define AFE_IRQ_CNT_MASK 0xffffff +#endif + -- GitLab From 9024ede69cf6fc5c83635dc0cb39af9337b135a9 Mon Sep 17 00:00:00 2001 From: Darren Ye Date: Mon, 23 Dec 2024 13:27:13 +0800 Subject: [PATCH 397/456] CHROMIUM: sound: soc/sof: add mt8196 sof audio driver add mt8196 sof audio driver BUG=b:314021325 BUG=b:360972899 TEST=build and boot to shell UPSTREAM-TASK=b:379040142 Change-Id: I341a4c6755f321a2472b6df11ff8869d58817dac Signed-off-by: Darren Ye Signed-off-by: Hailong Fan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6123539 Reviewed-by: Fei Shao Commit-Queue: ChromeOS Auto Retry Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- sound/soc/sof/mediatek/Kconfig | 9 + sound/soc/sof/mediatek/Makefile | 1 + sound/soc/sof/mediatek/mt8196/Makefile | 4 + sound/soc/sof/mediatek/mt8196/mt8196-clk.c | 101 +++ sound/soc/sof/mediatek/mt8196/mt8196-clk.h | 23 + sound/soc/sof/mediatek/mt8196/mt8196-loader.c | 61 ++ sound/soc/sof/mediatek/mt8196/mt8196.c | 642 ++++++++++++++++++ sound/soc/sof/mediatek/mt8196/mt8196.h | 109 +++ 8 files changed, 950 insertions(+) create mode 100644 sound/soc/sof/mediatek/mt8196/Makefile create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-clk.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-clk.h create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196-loader.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196.c create mode 100644 sound/soc/sof/mediatek/mt8196/mt8196.h diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig index 4a2eddf6009a5..ff89c4b1e0528 100644 --- a/sound/soc/sof/mediatek/Kconfig +++ b/sound/soc/sof/mediatek/Kconfig @@ -42,4 +42,13 @@ config SND_SOC_SOF_MT8195 Say Y if you have such a device. If unsure select "N". +config SND_SOC_SOF_MT8196 + tristate "SOF support for MT8196 audio DSP" + select SND_SOC_SOF_MTK_COMMON + depends on MTK_ADSP_IPC + help + This adds support for Sound Open Firmware for Mediatek platforms + using the mt8196 processors. + Say Y if you have such a device. + If unsure select "N". endif ## SND_SOC_SOF_MTK_TOPLEVEL diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makefile index 29c5afb2f3d6f..3e36d538679e9 100644 --- a/sound/soc/sof/mediatek/Makefile +++ b/sound/soc/sof/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_SOF_MTK_COMMON) += mtk-adsp-common.o obj-$(CONFIG_SND_SOC_SOF_MT8195) += mt8195/ obj-$(CONFIG_SND_SOC_SOF_MT8186) += mt8186/ +obj-$(CONFIG_SND_SOC_SOF_MT8196) += mt8196/ diff --git a/sound/soc/sof/mediatek/mt8196/Makefile b/sound/soc/sof/mediatek/mt8196/Makefile new file mode 100644 index 0000000000000..c9d10374b900f --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +snd-sof-mt8196-objs := mt8196.o mt8196-clk.o mt8196-loader.o +obj-$(CONFIG_SND_SOC_SOF_MT8196) += snd-sof-mt8196.o + diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-clk.c b/sound/soc/sof/mediatek/mt8196/mt8196-clk.c new file mode 100644 index 0000000000000..cac19d9db2e9e --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-clk.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Hailong Fan + */ + +// Hardware interface for mt8196 DSP clock + +#include +#include + +#include "../../sof-audio.h" +#include "../../ops.h" +#include "../adsp_helper.h" +#include "mt8196.h" +#include "mt8196-clk.h" + +static const char *adsp_clks[ADSP_CLK_MAX] = { + [CLK_TOP_ADSP_SEL] = "clk_top_adsp_sel", + [CLK_TOP_CLK26M] = "clk_top_clk26m", + [CLK_TOP_ADSPPLL] = "clk_top_adsppll", + +}; + +int mt8196_adsp_init_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct device *dev = sdev->dev; + int i; + + priv->clk = devm_kcalloc(dev, ADSP_CLK_MAX, sizeof(*priv->clk), GFP_KERNEL); + if (!priv->clk) + return -ENOMEM; + + for (i = 0; i < ADSP_CLK_MAX; i++) { + priv->clk[i] = devm_clk_get(dev, adsp_clks[i]); + + if (IS_ERR(priv->clk[i])) + return PTR_ERR(priv->clk[i]); + } + + return 0; +} + +static int adsp_enable_all_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct device *dev = sdev->dev; + int ret; + + ret = clk_prepare_enable(priv->clk[CLK_TOP_ADSP_SEL]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(audiodsp) fail %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static void adsp_disable_all_clock(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + clk_disable_unprepare(priv->clk[CLK_TOP_ADSP_SEL]); +} + +int mt8196_adsp_clock_on(struct snd_sof_dev *sdev) +{ + struct device *dev = sdev->dev; + int ret; + + ret = adsp_enable_all_clock(sdev); + if (ret) { + dev_err(dev, "failed to adsp_enable_clock: %d\n", ret); + return ret; + } + + ret = snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CK_EN, + UART_BT_EN | DMA_AXI_EN | DMA1_EN, + UART_BT_EN | DMA_AXI_EN | DMA1_EN); + if (ret < 0) + dev_err(sdev->dev, "Failed to update DSP register: %d\n", ret); + + ret = snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_UART_CTRL, + UART_BCLK_CG | UART_RSTN, + UART_BCLK_CG | UART_RSTN); + if (ret < 0) + dev_err(sdev->dev, "Failed to update DSP register: %d\n", ret); + + + return 0; +} + +void mt8196_adsp_clock_off(struct snd_sof_dev *sdev) +{ + snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_CK_EN, 0); + snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_UART_CTRL, 0); + adsp_disable_all_clock(sdev); +} + diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-clk.h b/sound/soc/sof/mediatek/mt8196/mt8196-clk.h new file mode 100644 index 0000000000000..429665be6a54f --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-clk.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Hailong Fan + */ + +#ifndef __MT8196_CLK_H +#define __MT8196_CLK_H + +struct snd_sof_dev; + +/* DSP clock */ +enum adsp_clk_id { + CLK_TOP_ADSP_SEL, + CLK_TOP_CLK26M, + CLK_TOP_ADSPPLL, + ADSP_CLK_MAX +}; + +int mt8196_adsp_init_clock(struct snd_sof_dev *sdev); +int mt8196_adsp_clock_on(struct snd_sof_dev *sdev); +void mt8196_adsp_clock_off(struct snd_sof_dev *sdev); +#endif diff --git a/sound/soc/sof/mediatek/mt8196/mt8196-loader.c b/sound/soc/sof/mediatek/mt8196/mt8196-loader.c new file mode 100644 index 0000000000000..77c1339ac54df --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196-loader.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Hailong Fan + */ + +// Hardware interface for mt8196 DSP code loader + +#include +#include "mt8196.h" +#include "../../ops.h" + +void mt8196_sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr) +{ + /* step1. clr ADSP_ALTVEC_C0 */ + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, 0); + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, 0); + + /* step2. set core boot address */ + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, boot_addr); + snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, ADSP_ALTVECSEL_C0); + + /* step3. set RUNSTALL to stop core */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, RUNSTALL); + + /* enable mbox 0 & 1 IRQ */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_MBOX_IRQ_EN, + DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN, + DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN); + + /* step4. assert core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + SW_RSTN_C0 | SW_DBG_RSTN_C0); + + /* hardware requirement */ + udelay(1); + + /* step5. release core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + 0); + + /* step6. release RUNSTALL */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, 0); +} + +void mt8196_sof_hifixdsp_shutdown(struct snd_sof_dev *sdev) +{ + /* set RUNSTALL to stop core */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_RUNSTALL, + RUNSTALL, RUNSTALL); + + /* assert core reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN, + SW_RSTN_C0 | SW_DBG_RSTN_C0, + SW_RSTN_C0 | SW_DBG_RSTN_C0); +} + diff --git a/sound/soc/sof/mediatek/mt8196/mt8196.c b/sound/soc/sof/mediatek/mt8196/mt8196.c new file mode 100644 index 0000000000000..6b5323c631f95 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Hailong Fan + */ + +/* + * Hardware interface for audio DSP on mt8196 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../ops.h" +#include "../../sof-of-dev.h" +#include "../../sof-audio.h" +#include "../adsp_helper.h" +#include "../mtk-adsp-common.h" +#include "mt8196.h" +#include "mt8196-clk.h" + +static void sof_reg_write_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, u32 value, + u8 bits, u8 len) +{ + u32 mask, val; + int ret; + + mask = GENMASK(len + bits - 1, bits); + val = (value << bits) & mask; + + ret = snd_sof_dsp_update_bits(sdev, bar, offset, mask, val); + if (ret < 0) + dev_err(sdev->dev, "Failed to update DSP register: %d\n", ret); +} + +static u32 reg_read_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, u8 bits, u8 len) +{ + u32 target_bit_field, curr_value; + + target_bit_field = GENMASK(len + bits - 1, bits); + curr_value = snd_sof_dsp_read(sdev, bar, offset); + + return (curr_value & target_bit_field) >> bits; +} + +static int mt8196_get_mailbox_offset(struct snd_sof_dev *sdev) +{ + return MBOX_OFFSET; +} + +static int mt8196_get_window_offset(struct snd_sof_dev *sdev, u32 id) +{ + return MBOX_OFFSET; +} + +static int mt8196_send_msg(struct snd_sof_dev *sdev, + struct snd_sof_ipc_msg *msg) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, + msg->msg_size); + + return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ); +} + +static void mt8196_dsp_handle_reply(struct mtk_adsp_ipc *ipc) +{ + struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); + unsigned long flags; + + spin_lock_irqsave(&priv->sdev->ipc_lock, flags); + snd_sof_ipc_process_reply(priv->sdev, 0); + spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); +} + +static void mt8196_dsp_handle_request(struct mtk_adsp_ipc *ipc) +{ + struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); + u32 p; /* panic code */ + int ret; + + /* Read the message from the debug box. */ + sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + sizeof(u32), + &p, sizeof(p)); + + /* Check to see if the message is a panic code 0x0dead*** */ + if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { + snd_sof_dsp_panic(priv->sdev, p, true); + } else { + snd_sof_ipc_msgs_rx(priv->sdev); + + /* tell DSP cmd is done */ + ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP); + if (ret) + dev_err(priv->dev, "request send ipc failed"); + } +} + +static struct mtk_adsp_ipc_ops dsp_ops = { + .handle_reply = mt8196_dsp_handle_reply, + .handle_request = mt8196_dsp_handle_request, +}; + +static int platform_parse_resource(struct platform_device *pdev, void *data) +{ + struct resource *mmio; + struct resource res; + struct device_node *mem_region; + struct device *dev = &pdev->dev; + struct mtk_adsp_chip_info *adsp = data; + int ret; + + ret = of_reserved_mem_device_init(dev); + if (ret) { + dev_err(dev, "of_reserved_mem_device_init failed\n"); + return ret; + } + + mem_region = of_parse_phandle(dev->of_node, "memory-region", 1); + if (!mem_region) { + dev_err(dev, "no memory-region sysmem phandle\n"); + return -ENODEV; + } + + ret = of_address_to_resource(mem_region, 0, &res); + of_node_put(mem_region); + if (ret) { + dev_err(dev, "of_address_to_resource sysmem failed\n"); + return ret; + } + + adsp->pa_dram = (phys_addr_t)res.start; + if (adsp->pa_dram & DRAM_REMAP_MASK) { + dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n", + (u32)adsp->pa_dram); + return -EINVAL; + } + + adsp->dramsize = resource_size(&res); + if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) { + dev_err(dev, "adsp memory(%#x) is not enough for share\n", + adsp->dramsize); + return -EINVAL; + } + + dev_dbg(dev, "dram pbase=%pa size=%#x\n", &adsp->pa_dram, adsp->dramsize); + + mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); + if (!mmio) { + dev_err(dev, "no ADSP-CFG register resource\n"); + return -ENXIO; + } + + adsp->va_cfgreg = devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_cfgreg)) + return PTR_ERR(adsp->va_cfgreg); + + adsp->pa_cfgreg = (phys_addr_t)mmio->start; + adsp->cfgregsize = resource_size(mmio); + + mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); + if (!mmio) { + dev_err(dev, "no SRAM resource\n"); + return -ENXIO; + } + + adsp->pa_sram = (phys_addr_t)mmio->start; + adsp->sramsize = resource_size(mmio); + + dev_dbg(dev, "sram pbase=%pa size=%#x\n", &adsp->pa_sram, adsp->sramsize); + + mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec"); + if (!mmio) { + dev_err(dev, "no SEC register resource\n"); + return -ENXIO; + } + + adsp->va_secreg = devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_secreg)) + return PTR_ERR(adsp->va_secreg); + + adsp->pa_secreg = (phys_addr_t)mmio->start; + adsp->secregsize = resource_size(mmio); + + dev_dbg(dev, "secreg pbase=%pa size=%#x\n", &adsp->pa_secreg, adsp->secregsize); + + mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus"); + if (!mmio) { + dev_err(dev, "no BUS register resource\n"); + return -ENXIO; + } + + adsp->va_busreg = devm_ioremap_resource(dev, mmio); + if (IS_ERR(adsp->va_busreg)) + return PTR_ERR(adsp->va_busreg); + + adsp->pa_busreg = (phys_addr_t)mmio->start; + adsp->busregsize = resource_size(mmio); + + dev_dbg(dev, "busreg pbase=%pa, vbase=%pa, size=%#x\n", &adsp->pa_busreg, + &adsp->va_busreg, adsp->busregsize); + + return 0; +} + +static void adsp_sram_power_on(struct snd_sof_dev *sdev) +{ + int i; + + for (i = 0; i < ADSP_SRAM_CHANNEL_NUM; i++) { + sof_reg_write_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON, 0, i, 1); + while (1) { + if (reg_read_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_ACK, i, 1) == 0) + break; + } + } +} + +static void adsp_sram_power_off(struct snd_sof_dev *sdev) +{ + int i; + + for (i = 0; i < ADSP_SRAM_CHANNEL_NUM; i++) { + sof_reg_write_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON, 1, i, 1); + while (1) { + if (reg_read_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_ACK, i, 1) == 1) + break; + } + } +} + +/* Init the basic DSP DRAM address */ +static int adsp_memory_remap_init(struct snd_sof_dev *sdev, struct mtk_adsp_chip_info *adsp) +{ + u32 from, to; + + from = ADSP_REMAP_REGION_FROM(DRAM_PHYS_BASE_FROM_DSP_VIEW, DSP_DRAM_SIZE); + to = (u32)ADSP_REMAP_REGION_TO(adsp->pa_dram); + + snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, AUDIO_BUS_CFG_RSV_10, from); + snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR, to); + + snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, AUDIO_BUS_CFG_BUS_REMAP_CTRL, 1, 1); + + return 0; +} + +static int mt8196_run(struct snd_sof_dev *sdev) +{ + u32 adsp_bootup_addr; + + adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW; + dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr); + mt8196_sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr); + + return 0; +} + +static int mt8196_dsp_probe(struct snd_sof_dev *sdev) +{ + struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + struct adsp_priv *priv; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sdev->pdata->hw_pdata = priv; + priv->dev = sdev->dev; + priv->sdev = sdev; + + priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info), GFP_KERNEL); + if (!priv->adsp) + return -ENOMEM; + + ret = platform_parse_resource(pdev, priv->adsp); + if (ret) + return ret; + + sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, + priv->adsp->pa_sram, + priv->adsp->sramsize); + if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", + &priv->adsp->pa_sram, priv->adsp->sramsize); + return -ENOMEM; + } + + priv->adsp->va_sram = sdev->bar[SOF_FW_BLK_TYPE_IRAM]; + dev_dbg(sdev->dev, "pa_sram %pa,va: %pa, size %#x\n", + &priv->adsp->pa_sram, &priv->adsp->va_sram, priv->adsp->sramsize); + + sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(sdev->dev, + priv->adsp->pa_dram, + priv->adsp->dramsize); + + if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", + &priv->adsp->pa_dram, priv->adsp->dramsize); + return -ENOMEM; + } + + priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM]; + + dev_dbg(sdev->dev, "pa_dram %pa, va: %pa, size %#x\n", + &priv->adsp->pa_dram, &priv->adsp->va_dram, priv->adsp->dramsize); + + + sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg; + sdev->bar[DSP_SECREG_BAR] = priv->adsp->va_secreg; + sdev->bar[DSP_BUSREG_BAR] = priv->adsp->va_busreg; + + sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM; + sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; + + /* set default mailbox offset for FW ready message */ + sdev->dsp_box.offset = mt8196_get_mailbox_offset(sdev); + + /* enable adsp clock before touching registers */ + ret = mt8196_adsp_init_clock(sdev); + if (ret) { + dev_err(sdev->dev, "mt8196_adsp_init_clock failed\n"); + return ret; + } + + ret = mt8196_adsp_clock_on(sdev); + if (ret) { + dev_err(sdev->dev, "mt8196_adsp_clock_on fail!\n"); + return ret; + } + + ret = adsp_memory_remap_init(sdev, priv->adsp); + if (ret) { + dev_err(sdev->dev, "adsp_memory_remap_init fail!\n"); + return ret; + } + + adsp_sram_power_on(sdev); + + priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc", + PLATFORM_DEVID_NONE, + pdev, sizeof(*pdev)); + if (IS_ERR(priv->ipc_dev)) { + ret = PTR_ERR(priv->ipc_dev); + dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n"); + goto err_adsp_off; + } + + priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); + if (!priv->dsp_ipc) { + ret = -EPROBE_DEFER; + dev_err(sdev->dev, "failed to get drvdata\n"); + goto exit_pdev_unregister; + } + + mtk_adsp_ipc_set_data(priv->dsp_ipc, priv); + priv->dsp_ipc->ops = &dsp_ops; + + return 0; + +exit_pdev_unregister: + platform_device_unregister(priv->ipc_dev); +err_adsp_off: + adsp_sram_power_off(sdev); + mt8196_adsp_clock_off(sdev); + + return ret; +} + +static void mt8196_dsp_remove(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + platform_device_unregister(priv->ipc_dev); + mt8196_sof_hifixdsp_shutdown(sdev); + adsp_sram_power_off(sdev); +} + +static int mt8196_dsp_shutdown(struct snd_sof_dev *sdev) +{ + return snd_sof_suspend(sdev->dev); +} + +static int mt8196_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_IO_CONFIG, ADSP_CLK_SEL, 0); + clk_set_parent(priv->clk[CLK_TOP_ADSP_SEL], priv->clk[CLK_TOP_CLK26M]); + mt8196_sof_hifixdsp_shutdown(sdev); + adsp_sram_power_off(sdev); + clk_disable_unprepare(priv->clk[CLK_TOP_ADSP_SEL]); + + return 0; +} + +static int mt8196_dsp_resume(struct snd_sof_dev *sdev) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + clk_prepare_enable(priv->clk[CLK_TOP_ADSP_SEL]); + clk_set_parent(priv->clk[CLK_TOP_ADSP_SEL], priv->clk[CLK_TOP_ADSPPLL]); + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_IO_CONFIG, ADSP_CLK_SEL, BIT(31)); + adsp_sram_power_on(sdev); + + return 0; +} + +/* on mt8196 there is 1 to 1 match between type and BAR idx */ +static int mt8196_get_bar_index(struct snd_sof_dev *sdev, u32 type) +{ + return type; +} + +static int mt8196_pcm_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params) +{ + platform_params->cont_update_posn = 1; + + return 0; +} + +static snd_pcm_uframes_t mt8196_pcm_pointer(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + int ret; + snd_pcm_uframes_t pos; + struct snd_sof_pcm *spcm; + struct sof_ipc_stream_posn posn; + struct snd_sof_pcm_stream *stream; + struct snd_soc_component *scomp = sdev->component; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n", + rtd->dai_link->id); + return 0; + } + + stream = &spcm->stream[substream->stream]; + ret = snd_sof_ipc_msg_data(sdev, stream, &posn, sizeof(posn)); + if (ret < 0) { + dev_warn(sdev->dev, "failed to read stream position: %d\n", ret); + return 0; + } + + memcpy(&stream->posn, &posn, sizeof(posn)); + pos = spcm->stream[substream->stream].posn.host_posn; + pos = bytes_to_frames(substream->runtime, pos); + + return pos; +} + +static void mt8196_adsp_dump(struct snd_sof_dev *sdev, u32 flags) +{ + u32 dbg_pc, dbg_data, dbg_inst, dbg_ls0stat, dbg_status, faultinfo; + + /* dump debug registers */ + dbg_pc = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC); + dbg_data = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGDATA); + dbg_inst = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGINST); + dbg_ls0stat = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGLS0STAT); + dbg_status = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGSTATUS); + faultinfo = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PFAULTINFO); + + dev_info(sdev->dev, "adsp dump : pc %#x, data %#x, dbg_inst %#x,", + dbg_pc, dbg_data, dbg_inst); + dev_info(sdev->dev, "ls0stat %#x, status %#x, faultinfo %#x", + dbg_ls0stat, dbg_status, faultinfo); + + mtk_adsp_dump(sdev, flags); +} + +/* + * DL_24CH, DL1, UL0, UL1, UL2 are registered as SOF FE, so creating the corresponding + * SOF BE to complete the pipeline. + */ +static struct snd_soc_dai_driver mt8196_dai[] = { +{ + .name = "SOF_DL_24CH", + .playback = { + .channels_min = CHAN_MIN, + .channels_max = CHAN_MAX, + }, +}, +{ + .name = "SOF_DL1", + .playback = { + .channels_min = CHAN_MIN, + .channels_max = CHAN_MAX, + }, +}, +{ + .name = "SOF_UL0", + .capture = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_UL1", + .capture = { + .channels_min = CHAN_MIN, + .channels_max = CHAN_MAX, + }, +}, +{ + .name = "SOF_UL2", + .capture = { + .channels_min = CHAN_MIN, + .channels_max = CHAN_MAX, + }, +}, +}; + +/* mt8196 ops */ +static struct snd_sof_dsp_ops sof_mt8196_ops = { + /* probe and remove */ + .probe = mt8196_dsp_probe, + .remove = mt8196_dsp_remove, + .shutdown = mt8196_dsp_shutdown, + + /* DSP core boot */ + .run = mt8196_run, + + /* Block IO */ + .block_read = sof_block_read, + .block_write = sof_block_write, + + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + + /* Register IO */ + .write = sof_io_write, + .read = sof_io_read, + .write64 = sof_io_write64, + .read64 = sof_io_read64, + + /* ipc */ + .send_msg = mt8196_send_msg, + .get_mailbox_offset = mt8196_get_mailbox_offset, + .get_window_offset = mt8196_get_window_offset, + .ipc_msg_data = sof_ipc_msg_data, + .set_stream_data_offset = sof_set_stream_data_offset, + + /* misc */ + .get_bar_index = mt8196_get_bar_index, + + /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_hw_params = mt8196_pcm_hw_params, + .pcm_pointer = mt8196_pcm_pointer, + .pcm_close = sof_stream_pcm_close, + + /* firmware loading */ + .load_firmware = snd_sof_load_firmware_memcpy, + + /* Firmware ops */ + .dsp_arch_ops = &sof_xtensa_arch_ops, + + /* DAI drivers */ + .drv = mt8196_dai, + .num_drv = ARRAY_SIZE(mt8196_dai), + + /* Debug information */ + .dbg_dump = mt8196_adsp_dump, + .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, + + /* PM */ + .suspend = mt8196_dsp_suspend, + .resume = mt8196_dsp_resume, + + /* ALSA HW info flags */ + .hw_info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, +}; + +static struct snd_sof_of_mach sof_mt8196_machs[] = { + { + .compatible = "mediatek,mt8196", + .sof_tplg_filename = "sof-mt8196.tplg", + }, + {} +}; + +static const struct sof_dev_desc sof_of_mt8196_desc = { + .of_machines = sof_mt8196_machs, + .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), + .ipc_default = SOF_IPC_TYPE_3, + .default_fw_path = { + [SOF_IPC_TYPE_3] = "mediatek/sof", + }, + .default_tplg_path = { + [SOF_IPC_TYPE_3] = "mediatek/sof-tplg", + }, + .default_fw_filename = { + [SOF_IPC_TYPE_3] = "sof-mt8196.ri", + }, + .nocodec_tplg_filename = "sof-mt8196-nocodec.tplg", + .ops = &sof_mt8196_ops, +}; + +static const struct of_device_id sof_of_mt8196_ids[] = { + { .compatible = "mediatek,mt8196-dsp", .data = &sof_of_mt8196_desc}, + { } +}; +MODULE_DEVICE_TABLE(of, sof_of_mt8196_ids); + +/* DT driver definition */ +static struct platform_driver snd_sof_of_mt8196_driver = { + .probe = sof_of_probe, + .remove_new = sof_of_remove, + .shutdown = sof_of_shutdown, + .driver = { + .name = "sof-audio-of-mt8196", + .pm = &sof_of_pm, + .of_match_table = sof_of_mt8196_ids, + }, +}; +module_platform_driver(snd_sof_of_mt8196_driver); + +MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); +MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/sof/mediatek/mt8196/mt8196.h b/sound/soc/sof/mediatek/mt8196/mt8196.h new file mode 100644 index 0000000000000..3080cf98515cb --- /dev/null +++ b/sound/soc/sof/mediatek/mt8196/mt8196.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + * Author: Hailong Fan + */ + +#ifndef __MT8196_H +#define __MT8196_H + +struct mtk_adsp_chip_info; +struct snd_sof_dev; + +#define DSP_REG_BAR 4 +#define DSP_SECREG_BAR 5 +#define DSP_BUSREG_BAR 6 +#define CHAN_MIN 1 +#define CHAN_MAX 2 + +/***************************************************************************** + * R E G I S T E R TABLE + *****************************************************************************/ +/* dsp cfg */ +#define ADSP_CFGREG_SW_RSTN 0x0000 +#define SW_DBG_RSTN_C0 BIT(0) +#define SW_RSTN_C0 BIT(4) +#define ADSP_IO_CONFIG 0x000C +#define ADSP_CLK_SEL BIT(31) +#define ADSP_HIFI_RUNSTALL 0x0108 +#define TRACEMEMREADY BIT(15) +#define RUNSTALL BIT(12) +#define ADSP_IRQ_MASK 0x0030 +#define ADSP_DVFSRC_REQ 0x0040 +#define ADSP_DDREN_REQ_0 0x0044 +#define ADSP_SEMAPHORE 0x0064 +#define ADSP_WDT_CON_C0 0x007C +#define ADSP_MBOX_IRQ_EN 0x009C +#define DSP_MBOX0_IRQ_EN BIT(0) +#define DSP_MBOX1_IRQ_EN BIT(1) +#define DSP_MBOX2_IRQ_EN BIT(2) +#define DSP_MBOX3_IRQ_EN BIT(3) +#define DSP_MBOX4_IRQ_EN BIT(4) +#define DSP_PDEBUGPC 0x013C +#define DSP_PDEBUGDATA 0x0140 +#define DSP_PDEBUGINST 0x0144 +#define DSP_PDEBUGLS0STAT 0x0148 +#define DSP_PDEBUGSTATUS 0x014C +#define DSP_PFAULTINFO 0x0150 +#define ADSP_CK_EN 0x1000 +#define DMA1_EN BIT(12) +#define DMA_AXI_EN BIT(13) +#define UART_BT_EN BIT(14) +#define DMA_EN BIT(4) +#define UART_EN BIT(5) +#define ADSP_UART_CTRL 0x1010 +#define UART_BCLK_CG BIT(0) +#define UART_RSTN BIT(3) + +/* dsp sec */ +#define ADSP_PRID 0x0 +#define ADSP_ALTVEC_C0 0x04 +#define ADSP_ALTVECSEL 0x0C +#define MT8196_ADSP_ALTVECSEL_C0 1 + +#define ADSP_ALTVECSEL_C0 MT8196_ADSP_ALTVECSEL_C0 + +/* dsp bus */ +#define AUDIO_BUS_CFG_RSV_10 0x30 +#define ADSP_SRAM_POOL_CON 0x190 +#define ADSP_SRAM_POOL_ACK 0x1A0 +#define ADSP_SRAM_CHANNEL_NUM 6 +#define DSP_SRAM_POOL_PD_MASK 0xF00F /* [0:3] and [12:15] */ +#define DSP_C0_EMI_MAP_ADDR 0xA00 /* ADSP Core0 To EMI Address Remap */ +#define DSP_C0_DMAEMI_MAP_ADDR 0xA08 /* DMA0 To EMI Address Remap */ +#define AUDIO_BUS_CFG_BUS_REMAP_CTRL 0x016C +#define AUDIO_BUS_DSP2EMI_REMAP0 0x0A00 +#define AUDIO_BUS_DSP2EMI_REMAP1 0x0A04 +#define AUDIO_BUS_DMA2EMI_REMAP0 0x0A08 +#define AUDIO_BUS_DMA2EMI_REMAP1 0x0A0C + +/* DSP memories */ +#define MBOX_OFFSET 0x500000 /* DRAM */ +#define MBOX_SIZE 0x1000 /* consistent with which in memory.h of sof fw */ +#define DSP_DRAM_SIZE 0x900000 /* 9M */ + +/*remap dram between AP and DSP view, 4KB aligned*/ +#define SRAM_PHYS_BASE_FROM_DSP_VIEW 0x4e100000 /* MT8196 DSP view */ +#define DRAM_PHYS_BASE_FROM_DSP_VIEW 0x90000000 /* MT8196 DSP view */ +#define DRAM_REMAP_SHIFT 12 +#define DRAM_REMAP_MASK 0xFFF + /* remap */ +#define ADSP_REMAP_REGION +#define ADSP_EMI_REMAP_SET_TOTAL (4) +#define EMI_REMAP_REGION (AUDIO_BUS_CFG_RSV_10) +#define EMI_REMAP_REPLACE (AUDIO_BUS_DSP2EMI_REMAP0) +#define EMI_REMAP_EN (1U) +#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) +#define MIX_BEGIN_AND_END_ADDR(begin, end) \ + (((begin >> 16) & 0xFFFF) | (end & 0xFFFF0000)) +#define ADSP_REMAP_REGION_FROM(start, size) MIX_BEGIN_AND_END_ADDR(start, \ + ROUNDUP((start + size), 0x10000)) +#define ADSP_REMAP_REGION_TO(start) ((start >> 25) << 9) + +#define SIZE_SHARED_DRAM_DL 0x40000 /*Shared buffer for Downlink*/ +#define SIZE_SHARED_DRAM_UL 0x40000 /*Shared buffer for Uplink*/ +#define TOTAL_SIZE_SHARED_DRAM_FROM_TAIL (SIZE_SHARED_DRAM_DL + SIZE_SHARED_DRAM_UL) + +void mt8196_sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr); +void mt8196_sof_hifixdsp_shutdown(struct snd_sof_dev *sdev); +#endif -- GitLab From ad2a013311c5a44c078a5d27116de6cb13f11438 Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Tue, 2 Apr 2024 19:34:12 +0800 Subject: [PATCH 398/456] CHROMIUM: pwm/mtk-disp: fix clock mt8196 doesn't have mm clock. Make this clock optional for mt8196. BUG=b:336581017 TEST=boot to shell and boot to sign in screen UPSTREAM-TASK=b:379039734 Signed-off-by: Jitao Shi Change-Id: I095b3454274e0a0bb137350a437893590908fd3f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073850 Commit-Queue: ChromeOS Auto Retry Tested-by: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/pwm/pwm-mtk-disp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index a83bd6e18b07f..01fb97158e37f 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -249,7 +249,7 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) if (IS_ERR(mdp->clk_main)) return PTR_ERR(mdp->clk_main); - mdp->clk_mm = devm_clk_get(&pdev->dev, "mm"); + mdp->clk_mm = devm_clk_get_optional(&pdev->dev, "mm"); if (IS_ERR(mdp->clk_mm)) return PTR_ERR(mdp->clk_mm); -- GitLab From da9e6494bbe9523baa8f6158a384d50a4f07e971 Mon Sep 17 00:00:00 2001 From: Xavier Chang Date: Thu, 8 Aug 2024 11:04:53 +0800 Subject: [PATCH 399/456] CHROMIUM: soc: mediatek: Upgrade socinfo data for mt8196 1.Update socinfo data for mt8196 2.Configure soc_id of device attribute. BUG=b:342024963 TEST=emerge-rauru chromeos-kernel-6_6;boot to homescreen Change-Id: I59050c3e58e396f02aca63121ddf11046ec513d8 Signed-off-by: Xavier Chang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073972 Commit-Queue: ChromeOS Auto Retry Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index d717a2855bff4..37310eef338cf 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -56,6 +56,7 @@ static struct socinfo_data socinfo_data_table[] = { MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED), MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED), MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED), + MTK_SOCINFO_ENTRY("MT8196", "MT8196GZ/NZB", "", 0x30000000, 0x00001E00), }; static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop) -- GitLab From b6eb26d55a0f9f52b3724d65ced88d2da1bf9532 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 10:30:30 +0800 Subject: [PATCH 400/456] CHROMIUM: remoteproc: mediatek: Add APU rproc header files Add APU rproc image loading header files to support other modules that need to load part of the APU binary in advnace. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Idb497f10bcf63b372e07056915ac171ec1adb5c8 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166782 Commit-Queue: ChromeOS Auto Retry Reviewed-by: Chen-Yu Tsai Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- include/linux/remoteproc/mtk_apu.h | 46 ++++++++++++++++++++ include/linux/remoteproc/mtk_apu_loadimage.h | 36 +++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 include/linux/remoteproc/mtk_apu.h create mode 100644 include/linux/remoteproc/mtk_apu_loadimage.h diff --git a/include/linux/remoteproc/mtk_apu.h b/include/linux/remoteproc/mtk_apu.h new file mode 100644 index 0000000000000..b9c52690bdc5d --- /dev/null +++ b/include/linux/remoteproc/mtk_apu.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_H +#define MTK_APU_H + +struct apusys_secure_info_t { + unsigned int total_sz; + unsigned int up_code_buf_ofs; + unsigned int up_code_buf_sz; + + unsigned int up_fw_ofs; + unsigned int up_fw_sz; + unsigned int up_xfile_ofs; + unsigned int up_xfile_sz; + unsigned int mdla_fw_boot_ofs; + unsigned int mdla_fw_boot_sz; + unsigned int mdla_fw_main_ofs; + unsigned int mdla_fw_main_sz; + unsigned int mdla_xfile_ofs; + unsigned int mdla_xfile_sz; + unsigned int mvpu_fw_ofs; + unsigned int mvpu_fw_sz; + unsigned int mvpu_xfile_ofs; + unsigned int mvpu_xfile_sz; + unsigned int mvpu_sec_fw_ofs; + unsigned int mvpu_sec_fw_sz; + unsigned int mvpu_sec_xfile_ofs; + unsigned int mvpu_sec_xfile_sz; + + unsigned int up_coredump_ofs; + unsigned int up_coredump_sz; + unsigned int mdla_coredump_ofs; + unsigned int mdla_coredump_sz; + unsigned int mvpu_coredump_ofs; + unsigned int mvpu_coredump_sz; + unsigned int mvpu_sec_coredump_ofs; + unsigned int mvpu_sec_coredump_sz; + + unsigned int ce_bin_ofs; + unsigned int ce_bin_sz; +}; + +#endif /* MTK_APU_H */ diff --git a/include/linux/remoteproc/mtk_apu_loadimage.h b/include/linux/remoteproc/mtk_apu_loadimage.h new file mode 100644 index 0000000000000..ec6640284c332 --- /dev/null +++ b/include/linux/remoteproc/mtk_apu_loadimage.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_LOADIMAGE_H +#define MTK_APU_LOADIMAGE_H + +#define APUSYS_FW_ALIGN (16) +#define MTK_APUSYS_SEC_MEM_ALIGN (0x200000) +#define PT_MAGIC (0x58901690) + +struct ptimg_hdr_t { + unsigned int magic; /* magic number*/ + unsigned int hdr_size; /* header size */ + unsigned int img_size; /* img size */ + unsigned int align; /* alignment */ + unsigned int id; /* image id */ + unsigned int addr; /* memory addr */ +}; + +enum PT_ID_APUSYS { + PT_ID_APUSYS_FW, + PT_ID_APUSYS_XFILE, + PT_ID_MDLA_FW_BOOT, + PT_ID_MDLA_FW_MAIN, + PT_ID_MDLA_XFILE, + PT_ID_MVPU_FW, + PT_ID_MVPU_XFILE, + PT_ID_MVPU_SEC_FW, + PT_ID_MVPU_SEC_XFILE, + PT_ID_CE_BIN, + PT_ID_CE_BIN_DUMMY +}; + +#endif /* MTK_APU_LOADIMAGE_H */ -- GitLab From 51c9c972e671b31558fddfa9461d4ace73909c8c Mon Sep 17 00:00:00 2001 From: Karl Li Date: Wed, 30 Oct 2024 09:35:28 +0800 Subject: [PATCH 401/456] FROMLIST: soc: mediatek: Add command for APU SMC call Add command for APU SMC call. The APU microprocess's start and stop sequence will process in ATF. Signed-off-by: Karl Li (am from https://patchwork.kernel.org/patch/13855824/) (also found at https://lore.kernel.org/r/20241030013533.855696-2-karl.li@mediatek.com) UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I7d3c1630818e0ff6c8344e2bcec3cd2b20905f42 Signed-off-by: Karl Li Reviewed-by: AngeloGioacchino Del Regno Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083210 Commit-Queue: ChromeOS Auto Retry Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- include/linux/firmware/mediatek/mtk-apu.h | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 include/linux/firmware/mediatek/mtk-apu.h diff --git a/include/linux/firmware/mediatek/mtk-apu.h b/include/linux/firmware/mediatek/mtk-apu.h new file mode 100644 index 0000000000000..a327e31d40fa1 --- /dev/null +++ b/include/linux/firmware/mediatek/mtk-apu.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef __MEDIATEK_APU_H__ +#define __MEDIATEK_APU_H__ + +enum mtk_apusys_kernel_op { + MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */ + MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */ + MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, /* 7 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, /* 8 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, /* 9 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */ + MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU, /* 13 */ + MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP, /* 14 */ + MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE, /* 15 */ + MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C, /* 16 */ + MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY, /* 17 */ + MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN, /* 18 */ + MTK_APUSYS_KERNEL_OP_NUM, +}; + +#endif -- GitLab From 4d8c8fc0813ca3e03534988395ea707a8a05e755 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Mon, 30 Dec 2024 11:43:35 +0800 Subject: [PATCH 402/456] FROMLIST: dt-bindings: mailbox: mediatek: Add apu-mailbox dt-bindings Add devicetree binding for apu-mailbox. MediaTek APU (AI Processing Unit) is a microcontroller unit designed for AI acceleration tasks. The MediaTek APU-Mailbox facilitates communication with the APU microcontroller. Signed-off-by: Karl Li (am from https://patchwork.kernel.org/patch/13923033/) (also found at https://lore.kernel.org/r/20241230034446.1195728-2-karl.li@mediatek.com) UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Iba01451b4c8fadf5802a0bdb3e4ad4a70aefbd38 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083297 Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Tested-by: Fei Shao Commit-Queue: ChromeOS Auto Retry Signed-off-by: Hubert Mazur --- .../mailbox/mediatek,apu-mailbox.yaml | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml new file mode 100644 index 0000000000000..fdb0dec5fb780 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/mediatek,apu-mailbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek APU mailbox + +maintainers: + - Karl Li + +description: + MediaTek APU (AI Processing Unit) is a microcontroller unit + designed for AI acceleration tasks. The MediaTek APU-Mailbox + facilitates communication with the APU microcontroller. + Within the MediaTek APU subsystem, a message passing mechanism is + built on top of the mailbox system. The mailbox only has limited + space for each message. The firmware expects the message header + from the mailbox, while the message body is passed through some + fixed shared memory. + +properties: + compatible: + const: mediatek,mt8196-apu-mailbox + + "#mbox-cells": + const: 1 + description: + The cell describe which channel the device will use. + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - "#mbox-cells" + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + mailbox@4c200000 { + compatible = "mediatek,mt8196-apu-mailbox"; + reg = <0 0x4c200000 0 0xfffff>; + interrupts = ; + #mbox-cells = <1>; + }; + }; -- GitLab From 09ba58914443e43068062c224220654d219c0d6a Mon Sep 17 00:00:00 2001 From: Karl Li Date: Mon, 30 Dec 2024 11:43:36 +0800 Subject: [PATCH 403/456] FROMLIST: mailbox: add support for bottom half received data Within the MediaTek APU subsystem, a message passing mechanism is constructed on top of the mailbox system. The mailbox only has limited space for each message. The MTK APU firmware expects the message header from the mailbox, while the message body is passed through some fixed shared memory. The mailbox interrupt also serves as a mutex for the shared memory. Thus the interrupt may only be cleared after the message is handled. To be specific, the MTK APU firmware fills the message body into a fixed shared memory, while passing the message header via a mailbox. --------------- --------------- --------- | Kernel Buffer | <- | Shared Memory | <- | MTK APU | --------------- --------------- --------- The top-half handler first copies the data from the shared memory to the kernel buffer. Subsequently, the bottom-half handler uses the data in the kernel buffer for specific processing tasks. However, it is possible for the MTK APU to send a new message while the kernel is still processing the previous one. In such cases, the top-half handler may overwrite the kernel buffer while the data is still needed, leading to a race condition. Additionally, due to performance considerations, we cannot allocate a new kernel buffer for each message. To prevent this, we need a mechanism to protect the kernel buffer from such race conditions. Since we cannot use locks to protect the kernel buffer in an atomic context, we use the mailbox interrupt as a mutex for the shared memory to further protect our kernel buffer. Therefore, we clear the interrupt only after the message is handled. Since the bottom half callback might need to go to sleep, we require a sleepable callback for mailbox clients. This patch adds a new sleepable RX callback for mailbox clients for cases where handling the incoming message requires sleeping. Signed-off-by: Karl Li (am from https://patchwork.kernel.org/patch/13923034/) (also found at https://lore.kernel.org/r/20241230034446.1195728-3-karl.li@mediatek.com) UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I9d832fad51da9ec8757285bdcba72374c967bbbb Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083298 Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Commit-Queue: ChromeOS Auto Retry Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/mailbox/mailbox.c | 16 ++++++++++++++++ include/linux/mailbox_client.h | 2 ++ include/linux/mailbox_controller.h | 1 + 3 files changed, 19 insertions(+) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 7546fcd750312..01b76797c8ba5 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -183,6 +183,22 @@ void mbox_chan_received_data(struct mbox_chan *chan, void *mssg) } EXPORT_SYMBOL_GPL(mbox_chan_received_data); +/** + * mbox_chan_received_data_bh - A way for controller driver to push data + * received from remote to the upper layer. + * @chan: Pointer to the mailbox channel on which RX happened. + * @mssg: Client specific message typecasted as void * + * + * For the operations which is not atomic can be called from + * mbox_chan_received_data_bh(). + */ +void mbox_chan_received_data_bh(struct mbox_chan *chan, void *mssg) +{ + if (chan->cl->rx_callback_bh) + chan->cl->rx_callback_bh(chan->cl, mssg); +} +EXPORT_SYMBOL_GPL(mbox_chan_received_data_bh); + /** * mbox_chan_txdone - A way for controller driver to notify the * framework that the last TX has completed. diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h index 734694912ef74..2cc6fa4e1bf96 100644 --- a/include/linux/mailbox_client.h +++ b/include/linux/mailbox_client.h @@ -22,6 +22,7 @@ struct mbox_chan; * if the client receives some ACK packet for transmission. * Unused if the controller already has TX_Done/RTR IRQ. * @rx_callback: Atomic callback to provide client the data received + * @rx_callback_bh: Non-atomic callback to provide client the data received * @tx_prepare: Atomic callback to ask client to prepare the payload * before initiating the transmission if required. * @tx_done: Atomic callback to tell client of data transmission @@ -33,6 +34,7 @@ struct mbox_client { bool knows_txdone; void (*rx_callback)(struct mbox_client *cl, void *mssg); + void (*rx_callback_bh)(struct mbox_client *cl, void *mssg); void (*tx_prepare)(struct mbox_client *cl, void *mssg); void (*tx_done)(struct mbox_client *cl, void *mssg, int r); }; diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h index e8f26e7dabfde..d980b9c4cad8a 100644 --- a/include/linux/mailbox_controller.h +++ b/include/linux/mailbox_controller.h @@ -141,6 +141,7 @@ struct mbox_chan { int mbox_controller_register(struct mbox_controller *mbox); /* can sleep */ void mbox_controller_unregister(struct mbox_controller *mbox); /* can sleep */ void mbox_chan_received_data(struct mbox_chan *chan, void *data); /* atomic */ +void mbox_chan_received_data_bh(struct mbox_chan *chan, void *data); /* can sleep */ void mbox_chan_txdone(struct mbox_chan *chan, int r); /* atomic */ int devm_mbox_controller_register(struct device *dev, -- GitLab From 63848d8573add196661e421e20d9fcf67f712fca Mon Sep 17 00:00:00 2001 From: Xiufeng Li Date: Thu, 20 Jun 2024 16:58:20 +0800 Subject: [PATCH 404/456] CHROMIUM: cpufreq: Add cpufreq-hw drivers for MT8196 add cpufreq driver code in kernel MTK has no plan upstreaming this driver because this part is strongly related to hardware operations BUG=b:383982458 TEST=build and boot to shell UPSTREAM-TASK=b:383958462 Signed-off-by: Xiufeng Li Signed-off-by: Ccong Chen Change-Id: Iddbd5f51c8fa414de96d4aeecf6e76d0a2cd16a2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073899 Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/cpufreq/Kconfig.arm | 12 + drivers/cpufreq/Makefile | 3 +- drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.c | 112 ++++ drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.h | 24 + drivers/cpufreq/mediatek-cpufreq-hw_main.c | 698 ++++++++++++++++++++ 5 files changed, 848 insertions(+), 1 deletion(-) create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.c create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.h create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw_main.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index c5cecbd89ba9c..ab6ff52a8f756 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -159,6 +159,18 @@ config ARM_OMAP2PLUS_CPUFREQ depends on ARCH_OMAP2PLUS default ARCH_OMAP2PLUS +config ARM_MEDIATEK_CPUFREQ_HW_V1 + bool "MediaTek CPUFreq HW driver" + depends on ARCH_MEDIATEK || COMPILE_TEST + default y + help + Support for the CPUFreq HW driver. + Some MediaTek chipsets have a HW engine to offload the steps + necessary for changing the frequency of the CPUs. Firmware loaded + in this engine exposes a programming interface to the OS. + The driver implements the cpufreq interface for this HW engine. + Say Y if you want to support CPUFreq HW. + config ARM_QCOM_CPUFREQ_NVMEM tristate "Qualcomm nvmem based CPUFreq" depends on ARCH_QCOM diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index c27e3672631ec..53cef052a6ebc 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW) += mediatek-cpufreq-hw.o obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o +obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW_V1) += mediatek-cpufreq-hw-v1.o obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o @@ -93,7 +94,7 @@ obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o obj-$(CONFIG_ARM_TEGRA194_CPUFREQ) += tegra194-cpufreq.o obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o - +mediatek-cpufreq-hw-v1-y := mediatek-cpufreq-hw_main.o mediatek-cpufreq-hw_fdvfs.o ################################################################################## # PowerPC platform drivers diff --git a/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.c b/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.c new file mode 100644 index 0000000000000..625f36e4791f5 --- /dev/null +++ b/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include "mediatek-cpufreq-hw_fdvfs.h" + +static int fdvfs_support = UNSUPPORTED; +static void __iomem *fdvfs_base, *fdvfs_reg, *fdvfs_cci_reg; + +static bool ioremap_fdvfs_reg(struct platform_device *pdev) +{ + fdvfs_reg = devm_platform_ioremap_resource_byname(pdev, "fdvfs-reg"); + if (!fdvfs_reg) { + dev_err(&pdev->dev,"%s failed to map resource %d\n", __func__, FDVFS_REG); + goto no_res; + } + + fdvfs_cci_reg = devm_platform_ioremap_resource_byname(pdev, "fdvfs-cci-reg"); + if (!fdvfs_cci_reg) { + dev_err(&pdev->dev,"%s failed to map resource %d\n", __func__, FDVFS_CCI_REG); + goto no_res; + } + + dev_dbg(&pdev->dev,"%s: fdvfs reg mapping success.\n", __func__); + return true; + +no_res: + return false; +} + +int check_fdvfs_support(struct device *dev) +{ + struct device_node *np; + struct platform_device *pdev; + int ret = 0; + + if (fdvfs_support != UNSUPPORTED) + return fdvfs_support == SUPPORTED ? SUPPORTED : UNKNOWN; + + np = of_find_compatible_node(NULL, NULL, "mediatek,fdvfs"); + if (!np) { + dev_err(dev, "%s: failed to find node\n", __func__); + ret = -EINVAL; + goto exit; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + dev_err(dev, "%s: failed to find fdvfs device\n", __func__); + ret = -ENODEV; + goto exit; + } + + fdvfs_base = devm_platform_ioremap_resource_byname(pdev, "fdvfs-support"); + if (!fdvfs_base) { + dev_err(dev, "%s: can't get mem resource\n", __func__); + ret = -ENOMEM; + goto exit; + } + + if (readl_relaxed(fdvfs_base) == FDVFS_MAGICNUM && ioremap_fdvfs_reg(pdev)) { + fdvfs_support = SUPPORTED; + dev_dbg(dev, "%s: fdvfs supports\n", __func__); + } else { + fdvfs_support = UNKNOWN; + dev_dbg(dev, "%s: fdvfs not supports\n", __func__); + } + + of_node_put(np); + return fdvfs_support; + +exit: + fdvfs_support = UNKNOWN; + of_node_put(np); + + return ret; +} + +int cpufreq_fdvfs_switch(unsigned int target_f, struct cpufreq_policy *policy) +{ + unsigned int cpu; + + target_f = DIV_ROUND_UP(target_f, FDVFS_FREQU); + for_each_cpu(cpu, policy->real_cpus) { + writel_relaxed(target_f, fdvfs_reg + cpu*CPU_OFS); + } + + return 0; +} + +bool cpufreq_fdvfs_cci_switch(unsigned int target_f) +{ + + if (fdvfs_support != SUPPORTED || fdvfs_cci_reg == NULL) + return false; + + target_f = DIV_ROUND_UP(target_f, FDVFS_FREQU); + writel_relaxed(target_f, fdvfs_cci_reg); + + return true; +} + +MODULE_AUTHOR("Haohao Yang "); +MODULE_DESCRIPTION("fdvfs apis"); +MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.h b/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.h new file mode 100644 index 0000000000000..04d7919a38367 --- /dev/null +++ b/drivers/cpufreq/mediatek-cpufreq-hw_fdvfs.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (c) 2023 MediaTek Inc. + */ + +#define FDVFS_MAGICNUM 0xABCD0001 +#define FDVFS_FREQU 26000 +#define CPU_OFS 0x4 + +enum FDVFS_REG_TYPE { + FDVFS_REG, + FDVFS_CCI_REG, + FDVFS_SUPPORT, +}; + +enum SupportState { + UNSUPPORTED = -1, + UNKNOWN = 0, + SUPPORTED = 1, +}; + +int check_fdvfs_support(struct device *dev); +int cpufreq_fdvfs_switch(unsigned int target_f, struct cpufreq_policy *policy); +bool cpufreq_fdvfs_cci_switch(unsigned int target_f); diff --git a/drivers/cpufreq/mediatek-cpufreq-hw_main.c b/drivers/cpufreq/mediatek-cpufreq-hw_main.c new file mode 100644 index 0000000000000..8f8713f13c1fa --- /dev/null +++ b/drivers/cpufreq/mediatek-cpufreq-hw_main.c @@ -0,0 +1,698 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mediatek-cpufreq-hw_fdvfs.h" + +#define LUT_MAX_ENTRIES 32U +#define LUT_FREQ GENMASK(11, 0) +#define LUT_ROW_SIZE 0x4 +#define CPUFREQ_HW_STATUS BIT(0) +#define SVS_HW_STATUS BIT(1) +#define POLL_USEC 1000 +#define TIMEOUT_USEC 300000 +#define REG_FREQ_SCALING 0x4cc/* from csram_base */ +#define REG_STOP_CPUDVFS_LOG 0x128 /* from csram_base */ +#define REG_QOS_OFF 0x20 +#define CHECK_VAL 0X55AA55AA +#define MAX_CONTROL_GROUPS 8 +#define MAX_PERF_DOMAINS 3 +#define PER_CORE_OFF 0x1380 +#define PER_CORE_SIZE 0x20 +#define CSRAM_BASE_ADD 0x10 + +enum { + REG_FREQ_LUT_TABLE, + REG_FREQ_ENABLE, + REG_FREQ_PERF_STATE, + REG_FREQ_HW_STATE, + REG_EM_POWER_TBL, + REG_FREQ_LATENCY, + + REG_ARRAY_SIZE, +}; + +struct cpufreq_mtk { + struct cpufreq_frequency_table *table; + void __iomem *reg_bases[REG_ARRAY_SIZE]; + int nr_opp; + unsigned int last_index; + cpumask_t related_cpus; + long sb_ch; +}; + +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { + [REG_FREQ_LUT_TABLE] = 0x0, + [REG_FREQ_ENABLE] = 0x84, + [REG_FREQ_PERF_STATE] = 0x88, + [REG_FREQ_HW_STATE] = 0x8C, + [REG_EM_POWER_TBL] = 0x90, + [REG_FREQ_LATENCY] = 0x114, +}; + +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS]; +static bool freq_scaling_disabled = true; +static bool fdvfs_enabled; +static bool per_core_enabled; +static void __iomem *qos_base; +static void __iomem *per_core_base; +static int cpu_control_group_map[MAX_CONTROL_GROUPS]; +static int control_group_master[MAX_CONTROL_GROUPS]; +static int perf_domain_master[MAX_PERF_DOMAINS]; + +static int look_up_cpu(struct device *cpu_dev) +{ + unsigned int cpu = 0; + + for_each_possible_cpu(cpu) { + if (cpu_dev == get_cpu_device(cpu)) + return cpu; + } + + return 0; /* fallback to cpu0 */ +} + + +static int __maybe_unused +mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *uW, + unsigned long *KHz) +{ + int cpu = look_up_cpu(cpu_dev); + struct cpufreq_mtk *c = mtk_freq_domain_map[cpu]; + int i; + + for (i = 0; i < c->nr_opp; i++) { + if (c->table[i].frequency < *KHz) + break; + } + i--; + + *KHz = c->table[i].frequency; + *uW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] + + i * LUT_ROW_SIZE); + + return 0; +} + +static int stop_dvfs_log(struct notifier_block *self, unsigned long cmd, void *ptr) +{ + static atomic_t first_exception = ATOMIC_INIT(0); + struct cpufreq_mtk *c = mtk_freq_domain_map[0]; + void __iomem *csram_base_add_0x10; + void __iomem *stop_dvfs_log; + + if(c) { + if(atomic_cmpxchg(&first_exception, 0, 1) != 0) + return NOTIFY_DONE; + csram_base_add_0x10 = c->reg_bases[REG_FREQ_LUT_TABLE]; + stop_dvfs_log = csram_base_add_0x10 + REG_STOP_CPUDVFS_LOG - CSRAM_BASE_ADD; + writel_relaxed(0x1, stop_dvfs_log); + } + return NOTIFY_DONE; +} + +static struct notifier_block die_blk = { + .notifier_call = stop_dvfs_log, + .priority = INT_MAX, +}; + +static struct notifier_block panic_blk = { + .notifier_call = stop_dvfs_log, + .priority = INT_MAX, +}; +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy, + unsigned int index) +{ + struct cpufreq_mtk *c = policy->driver_data; + + if (!freq_scaling_disabled) { + int target_freq = policy->freq_table[index].frequency; + + if (fdvfs_enabled) + cpufreq_fdvfs_switch(target_freq, policy); + else + writel_relaxed(target_freq, c->reg_bases[REG_FREQ_PERF_STATE]); + } else + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); + + return 0; +} + +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu) +{ + struct cpufreq_mtk *c; + unsigned int index, freq, nr_opp; + + c = mtk_freq_domain_map[cpu]; + nr_opp = c->nr_opp; + + if (per_core_enabled) + index = readl_relaxed(per_core_base + CPU_OFS * cpu); + else + freq = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]); + + if (per_core_enabled && index <= LUT_MAX_ENTRIES - 1) { + index = min(index, LUT_MAX_ENTRIES - 1); + return c->table[index].frequency; + } else if (c->table[0].frequency >= freq && freq >= c->table[nr_opp - 1].frequency) { + return freq; + } + + return 0; +} + +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + struct cpufreq_mtk *c = policy->driver_data; + unsigned int index; +#if IS_ENABLED(CONFIG_MTK_IRQ_MONITOR_DEBUG) + u64 ts[2]; + + ts[0] = sched_clock(); +#endif + + if (policy->cached_target_freq == target_freq) + index = policy->cached_resolved_idx; + else + index = cpufreq_table_find_index_dl(policy, target_freq, false); + + if (fdvfs_enabled) { + if(c->sb_ch && c->sb_ch != -1) + cpufreq_fdvfs_cci_switch(c->sb_ch); + cpufreq_fdvfs_switch(target_freq, policy); + } else { + if(qos_base && c->sb_ch) { + c->sb_ch == -1 ? + writel_relaxed(0, qos_base + REG_QOS_OFF): + writel_relaxed(c->sb_ch, qos_base + REG_QOS_OFF); + } + if (!freq_scaling_disabled) // Frequency scaling enabled + writel_relaxed(target_freq, c->reg_bases[REG_FREQ_PERF_STATE]); + else + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); + } + + if (c->last_index == index) + return 0; + c->last_index = index; + +#if IS_ENABLED(CONFIG_MTK_IRQ_MONITOR_DEBUG) + ts[1] = sched_clock(); + + if ((ts[1] - ts[0] > 100000ULL) && in_hardirq()) { + printk_deferred("%s duration %llu, ts[0]=%llu, ts[1]=%llu\n", + __func__, ts[1] - ts[0], ts[0], ts[1]); + } +#endif + + return policy->freq_table[index].frequency; +} + +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) +{ + struct cpufreq_mtk *c; + struct pm_qos_request *qos_request; + struct device *dev = get_cpu_device(policy->cpu); + int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS; + int ret = 0; + unsigned int latency; + + qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL); + if (!qos_request) + return -ENOMEM; + + c = mtk_freq_domain_map[policy->cpu]; + if (!c) { + dev_err(dev, "No scaling support for CPU%d\n", policy->cpu); + ret = -EOPNOTSUPP; + goto free_qos_request; + } + + cpumask_copy(policy->cpus, &c->related_cpus); + + policy->freq_table = c->table; + policy->driver_data = c; + + latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]); + if (!latency) + latency = CPUFREQ_ETERNAL; + + /* us convert to ns */ + policy->cpuinfo.transition_latency = latency * POLL_USEC; + + policy->fast_switch_possible = true; + + /* Let CPUs leave idle-off state for SVS CPU initializing */ + cpu_latency_qos_add_request(qos_request, PM_QOS_DEFAULT_VALUE); + + /* HW should be in enabled state to proceed now */ + writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]); + + if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig, + (sig & pwr_hw) == pwr_hw, POLL_USEC, + TIMEOUT_USEC)) { + if (!(sig & CPUFREQ_HW_STATUS)) { + dev_err(dev, "cpufreq hardware of CPU%d is not enabled\n", policy->cpu); + cpu_latency_qos_remove_request(qos_request); + ret = -EOPNOTSUPP; + goto remove_qos_request; + } + + dev_notice(dev, "SVS of CPU%d is not enabled\n", policy->cpu); + } + +remove_qos_request: + cpu_latency_qos_remove_request(qos_request); +free_qos_request: + kfree(qos_request); + + return ret; +} + +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) +{ + struct cpufreq_mtk *c; + + c = mtk_freq_domain_map[policy->cpu]; + if (!c) { + dev_err(get_cpu_device(policy->cpu), "No scaling support for CPU%d\n", policy->cpu); + return -EOPNOTSUPP; + } + + /* HW should be in paused state now */ + writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]); + + return 0; +} + +static void mtk_cpufreq_register_em(struct cpufreq_policy *policy) +{ + struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power); + struct cpufreq_mtk *c = policy->driver_data; + + if (!c->nr_opp) { + dev_err(get_cpu_device(policy->cpu), + "%s: %d: CPU%d: Get opp failed\n", __func__, __LINE__, + policy->cpu); + return; + } + + em_dev_register_perf_domain(get_cpu_device(policy->cpu), c->nr_opp, &em_cb, policy->cpus, + true); +} + +static struct cpufreq_driver cpufreq_mtk_hw_driver = { + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | + CPUFREQ_HAVE_GOVERNOR_PER_POLICY | + CPUFREQ_IS_COOLING_DEV, + .verify = cpufreq_generic_frequency_table_verify, + .target_index = mtk_cpufreq_hw_target_index, + .get = mtk_cpufreq_hw_get, + .init = mtk_cpufreq_hw_cpu_init, + .exit = mtk_cpufreq_hw_cpu_exit, + .register_em = mtk_cpufreq_register_em, + .fast_switch = mtk_cpufreq_hw_fast_switch, + .name = "mtk-cpufreq-hw", + .attr = cpufreq_generic_attr, +}; + +static int mtk_cpu_create_freq_table(struct platform_device *pdev, + struct cpufreq_mtk *c) +{ + struct device *dev = &pdev->dev; + void __iomem *base_table; + u32 data, i, freq, prev_freq = 0; + + c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1, + sizeof(*c->table), GFP_KERNEL); + if (!c->table) + return -ENOMEM; + + base_table = c->reg_bases[REG_FREQ_LUT_TABLE]; + + for (i = 0; i < LUT_MAX_ENTRIES; i++) { + data = readl_relaxed(base_table + (i * LUT_ROW_SIZE)); + freq = FIELD_GET(LUT_FREQ, data) * POLL_USEC; + + if (freq == prev_freq) + break; + + c->table[i].frequency = freq; + + dev_dbg(dev, "index=%d freq=%d\n", + i, c->table[i].frequency); + + prev_freq = freq; + } + + c->table[i].frequency = CPUFREQ_TABLE_END; + c->nr_opp = i; + + return 0; +} + +static int mtk_get_related_cpus(int master_index, struct cpufreq_mtk *c) +{ + struct device_node *cpu_np; + struct of_phandle_args args; + int control_index; + int cpu, ret; + + for_each_possible_cpu(cpu) { + if(!per_core_enabled) { + cpu_np = of_cpu_device_node_get(cpu); + if (!cpu_np) + continue; + + ret = of_parse_phandle_with_args(cpu_np, "performance-domains", + "#performance-domain-cells", 0, + &args); + of_node_put(cpu_np); + if (ret < 0) + continue; + + control_index = args.args[0]; + } else + control_index = cpu_control_group_map[cpu]; + + if (control_index == master_index) { + cpumask_set_cpu(cpu, &c->related_cpus); + mtk_freq_domain_map[cpu] = c; + } + } + + return 0; +} + +static int mtk_cpu_resources_init(struct platform_device *pdev, + unsigned int cpu, int index, + const u16 *offsets) +{ + struct cpufreq_mtk *c; + struct device *dev = &pdev->dev; + int control_index; + int ret, i; + void __iomem *base; + + if (mtk_freq_domain_map[cpu]) + return 0; + + c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + base = devm_platform_ioremap_resource(pdev, index); + if (IS_ERR(base)) + return PTR_ERR(base); + + for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++) + c->reg_bases[i] = base + offsets[i]; + + control_index = !per_core_enabled ? index : cpu_control_group_map[cpu]; + ret = mtk_get_related_cpus(control_index, c); + if (ret) { + dev_err(dev, "Domain-%d failed to get related CPUs\n", control_index); + return ret; + } + + ret = mtk_cpu_create_freq_table(pdev, c); + if (ret) { + dev_err(dev, "Domain-%d failed to create freq table\n", index); + return ret; + } + + return 0; +} + +static int mtk_per_core_cpu_resources_init(struct platform_device *pdev, + unsigned int cpu, int index, + const u16 *offsets) +{ + struct cpufreq_mtk *c; + struct cpufreq_mtk *master_c; + struct device *dev = &pdev->dev; + int ret, i, master; + int control_group = cpu_control_group_map[cpu]; + + if (mtk_freq_domain_map[cpu]) { + dev_info(dev, "already has per-core entry: index-%d cpu-%d\n", index, cpu); + return 0; + } + + if (cpu == perf_domain_master[index]) + return mtk_cpu_resources_init(pdev, cpu, index, offsets); + else if (cpu == control_group_master[control_group]) { + master = perf_domain_master[index]; + if (master == -1) { + dev_err(dev, "no master for control group %d, index %d\n", control_group, index); + return -EINVAL; + } + master_c = mtk_freq_domain_map[master]; + + c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + /* init all other member variables from master_c */ + c->table = master_c->table; + c->nr_opp = master_c->nr_opp; + + for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++) + c->reg_bases[i] = master_c->reg_bases[i]; + + ret = mtk_get_related_cpus(control_group, c); + if (ret) { + dev_err(dev, "Domain-%d failed to get related CPUs\n", control_group); + return ret; + } + } else { + /* shall not go in here */ + dev_err(dev, "wrong per-core entry, index-%d cpu-%d\n", index, cpu); + return -EINVAL; + } + + return 0; +} + +static bool check_per_core_enabled(struct device *dev) +{ + static int control_group_num; + struct device_node *cpu_np; + u32 control_group; + int cpu_cluster_id; + int i, cpu, ret; + + if (!fdvfs_enabled) { + dev_err(dev, "%s: per-core requires fdvfs support\n", __func__); + return false; + } + + control_group_num = 0; + for (i = 0; i < MAX_CONTROL_GROUPS; i++) + control_group_master[i] = -1; + + for (i = 0; i < MAX_PERF_DOMAINS; i++) + perf_domain_master[i] = -1; + + for_each_possible_cpu(cpu) { + cpu_np = of_cpu_device_node_get(cpu); + if (!cpu_np) { + dev_err(dev, "%s: failed to get cpu device\n", __func__); + return false; + } + + ret = of_property_read_u32(cpu_np, "control-group", &control_group); + of_node_put(cpu_np); + if (ret < 0) { + dev_err(dev, "%s: failed to get control-group\n", __func__); + return false; + } + + if (control_group >= MAX_CONTROL_GROUPS) { + dev_err(dev, "%s: control-group incorrect\n", __func__); + return false; + } + + cpu_control_group_map[cpu] = control_group; + + if (control_group_master[control_group] == -1) + control_group_master[control_group] = cpu; + + if (control_group + 1 > control_group_num) + control_group_num = control_group + 1; + + cpu_cluster_id = topology_cluster_id(cpu); + if (perf_domain_master[cpu_cluster_id] == -1) + perf_domain_master[cpu_cluster_id] = cpu; + } + + dev_dbg(dev, "%s: per-core enabled\n", __func__); + return true; +} + +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev) +{ + struct device_node *cpu_np; + struct device_node *hvfs_node, *csram_sys_node; + struct of_phandle_args args; + struct resource *csram_res; + struct platform_device *pdev_c; + static void __iomem *csram_base; + const u16 *offsets; + unsigned int cpu; + int ret; + + offsets = of_device_get_match_data(&pdev->dev); + if (!offsets) + return -EINVAL; + + hvfs_node = of_find_compatible_node(NULL, NULL, "mediatek,cpufreq-hybrid"); + if (!hvfs_node) { + dev_err(&pdev->dev, "failed to find node @ %s\n", __func__); + return -ENODEV; + } + + pdev_c = of_find_device_by_node(hvfs_node); + if (!pdev_c) { + dev_err(&pdev->dev, "failed to find pdev @ %s\n", __func__); + return -EINVAL; + } + + csram_res = platform_get_resource(pdev_c, IORESOURCE_MEM, 1); + if (!csram_res) { + dev_err(&pdev->dev, "failed to get mem resource @ %s\n", __func__); + return -ENODEV; + } + + if (!request_mem_region(csram_res->start, resource_size(csram_res), + csram_res->name)) { + dev_err(&pdev->dev, "failed to request resource %pR\n", csram_res); + return -EBUSY; + } + + csram_base = ioremap(csram_res->start, resource_size(csram_res)); + if (!csram_base) { + dev_err(&pdev->dev, "failed to map csram_base @ %s\n", __func__); + ret = -ENOMEM; + goto release_region; + } + + csram_sys_node = of_parse_phandle(hvfs_node, "csram-sys-base", 0); + if (csram_sys_node != NULL) { + static void __iomem *csram_sys_base; + + csram_sys_base = of_iomap(csram_sys_node, 0); + if (readl_relaxed(csram_sys_base) != CHECK_VAL || + !readl_relaxed(csram_sys_base + CSRAM_BASE_ADD + + cpufreq_mtk_offsets[REG_FREQ_HW_STATE])) { + dev_err(&pdev->dev, "%s: cpufreq hardware not enable\n", __func__); + ret = -EIO; + iounmap(csram_base); + goto release_region; + } + dev_dbg(&pdev->dev, "%s: cpufreq hardware enable\n", __func__); + } + + if (readl_relaxed(csram_base + REG_FREQ_SCALING)){ + freq_scaling_disabled = false; + iounmap(csram_base); + release_mem_region(csram_res->start, resource_size(csram_res)); + } + fdvfs_enabled = check_fdvfs_support(&pdev->dev) == 1 ? true : false; + per_core_enabled = check_per_core_enabled(&pdev->dev); + + if (per_core_enabled) { + per_core_base = ioremap(csram_res->start + PER_CORE_OFF, PER_CORE_SIZE); + if (!per_core_base) { + dev_err(&pdev->dev, "failed to map per_core_base @ %s\n", __func__); + return -ENOMEM; + } + } + + for_each_possible_cpu(cpu) { + cpu_np = of_cpu_device_node_get(cpu); + if (!cpu_np) { + dev_err(&pdev->dev, "Failed to get cpu %d device\n", + cpu); + return -ENODEV; + } + + ret = of_parse_phandle_with_args(cpu_np, "performance-domains", + "#performance-domain-cells", 0, + &args); + if (ret < 0) + return ret; + + if (per_core_enabled) { + ret = mtk_per_core_cpu_resources_init(pdev, cpu, args.args[0], offsets); + if (ret) { + dev_err(&pdev->dev, "per-core CPUFreq resource init failed\n"); + return ret; + } + } else { + /* Get the bases of cpufreq for domains */ + ret = mtk_cpu_resources_init(pdev, cpu, args.args[0], offsets); + if (ret) { + dev_err(&pdev->dev, "CPUFreq resource init failed\n"); + return ret; + } + } + } + + ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver); + if (ret) { + dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n"); + return ret; + } + register_die_notifier(&die_blk); + atomic_notifier_chain_register(&panic_notifier_list, &panic_blk); + + return 0; + +release_region: + release_mem_region(csram_res->start, resource_size(csram_res)); + return ret; +} + +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev) +{ + cpufreq_unregister_driver(&cpufreq_mtk_hw_driver); + return 0; +} + +static const struct of_device_id mtk_cpufreq_hw_match[] = { + { .compatible = "mediatek,cpufreq-hw-v1", .data = &cpufreq_mtk_offsets }, + {} +}; + +static struct platform_driver mtk_cpufreq_hw_driver = { + .probe = mtk_cpufreq_hw_driver_probe, + .remove = mtk_cpufreq_hw_driver_remove, + .driver = { + .name = "mtk-cpufreq-hw-v1", + .of_match_table = mtk_cpufreq_hw_match, + }, +}; +module_platform_driver(mtk_cpufreq_hw_driver); + +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver"); +MODULE_LICENSE("GPL"); -- GitLab From 58800f4e8ab86ea89648ee243d6d04c3e7ca9acb Mon Sep 17 00:00:00 2001 From: Kai Liang Date: Fri, 20 Dec 2024 11:37:38 +0800 Subject: [PATCH 405/456] CHROMIUM: cpufreq: mediatek: disable s2idle state Disable s2idle state in kernel. BUG=b:383264870 TEST=build pass and s2idle count is zero Signed-off-by: Kai Liang Change-Id: I60cc4988ae1a065500825aca040d0773df0b9d28 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6109720 Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/cpufreq/mediatek-cpufreq-hw_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cpufreq/mediatek-cpufreq-hw_main.c b/drivers/cpufreq/mediatek-cpufreq-hw_main.c index 8f8713f13c1fa..3dfa3bfc32295 100644 --- a/drivers/cpufreq/mediatek-cpufreq-hw_main.c +++ b/drivers/cpufreq/mediatek-cpufreq-hw_main.c @@ -28,6 +28,7 @@ #define CPUFREQ_HW_STATUS BIT(0) #define SVS_HW_STATUS BIT(1) #define POLL_USEC 1000 +#define CPU_DMA_LATENCY 10000 #define TIMEOUT_USEC 300000 #define REG_FREQ_SCALING 0x4cc/* from csram_base */ #define REG_STOP_CPUDVFS_LOG 0x128 /* from csram_base */ @@ -68,6 +69,7 @@ static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { [REG_FREQ_LATENCY] = 0x114, }; +static struct pm_qos_request cpufreq_lpm_qos_request; static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS]; static bool freq_scaling_disabled = true; static bool fdvfs_enabled; @@ -263,6 +265,7 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) /* Let CPUs leave idle-off state for SVS CPU initializing */ cpu_latency_qos_add_request(qos_request, PM_QOS_DEFAULT_VALUE); + cpu_latency_qos_add_request(&cpufreq_lpm_qos_request, CPU_DMA_LATENCY); /* HW should be in enabled state to proceed now */ writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]); -- GitLab From 2ca081fe705ea9003680cf894f6d07da29687c7f Mon Sep 17 00:00:00 2001 From: Karl Li Date: Mon, 30 Dec 2024 11:43:37 +0800 Subject: [PATCH 406/456] FROMLIST: mailbox: mediatek: Add mtk-apu-mailbox driver Add mtk-apu-mailbox driver to support the communication with APU remote microprocessor. Also, the mailbox hardware contains extra spare (scratch) registers that other hardware blocks use to communicate through. Use regmap to provide the such operations. Signed-off-by: Karl Li (am from https://patchwork.kernel.org/patch/13923035/) (also found at https://lore.kernel.org/r/20241230034446.1195728-4-karl.li@mediatek.com) UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I1e0ce8dad793412dc4457410e9943352ca017382 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083299 Reviewed-by: Yidi Lin Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- drivers/mailbox/Kconfig | 9 ++ drivers/mailbox/Makefile | 2 + drivers/mailbox/mtk-apu-mailbox.c | 202 ++++++++++++++++++++++++ include/linux/mailbox/mtk-apu-mailbox.h | 15 ++ 4 files changed, 228 insertions(+) create mode 100644 drivers/mailbox/mtk-apu-mailbox.c create mode 100644 include/linux/mailbox/mtk-apu-mailbox.h diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index d871fe0fee1dc..0c28eddfc95cf 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -248,6 +248,15 @@ config MTK_ADSP_MBOX between processors with ADSP. It will place the message to share buffer and will access the ipc control. +config MTK_APU_MBOX + tristate "MediaTek APU Mailbox Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + help + Say yes here to add support for the MediaTek APU Mailbox + driver. The mailbox implementation provides access from the + application processor to the MediaTek AI Processing Unit. + If unsure say N. + config MTK_CMDQ_MBOX tristate "MediaTek CMDQ Mailbox Support" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 78c8ca5058574..e589f00731958 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -51,6 +51,8 @@ obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o obj-$(CONFIG_MTK_ADSP_MBOX) += mtk-adsp-mailbox.o +obj-$(CONFIG_MTK_APU_MBOX) += mtk-apu-mailbox.o + obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o mtk-cmdq-sec-mailbox.o mtk-cmdq-sec-tee.o obj-$(CONFIG_MTK_TINYSYS_MBOX) += mtk-mbox-mailbox.o diff --git a/drivers/mailbox/mtk-apu-mailbox.c b/drivers/mailbox/mtk-apu-mailbox.c new file mode 100644 index 0000000000000..6cc98d0df94a3 --- /dev/null +++ b/drivers/mailbox/mtk-apu-mailbox.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MTK_APU_MBOX_INBOX (0x0) +#define MTK_APU_MBOX_OUTBOX (0x20) +#define MTK_APU_MBOX_INBOX_IRQ (0xc0) +#define MTK_APU_MBOX_OUTBOX_IRQ (0xc4) +#define MTK_APU_MBOX_INBOX_IRQ_MASK (0xd0) + +#define MTK_APU_MBOX_SPARE_OFF_START (0x40) +#define MTK_APU_MBOX_SPARE_OFF_END (0xB0) + +struct mtk_apu_mailbox_platdata { + u8 msg_mbox_slots; +}; + +struct mtk_apu_mailbox { + u8 msg_mbox_slots; + struct device *dev; + void __iomem *regs; + struct mbox_controller mbox; + struct mtk_apu_mailbox_msg msgs; +}; + +static inline struct mtk_apu_mailbox *get_mtk_apu_mailbox(struct mbox_controller *mbox) +{ + return container_of(mbox, struct mtk_apu_mailbox, mbox); +} + +static irqreturn_t mtk_apu_mailbox_irq(int irq, void *data) +{ + struct mbox_chan *chan = data; + struct mtk_apu_mailbox *apu_mbox = get_mtk_apu_mailbox(chan->mbox); + struct mbox_chan *link = &apu_mbox->mbox.chans[0]; + u8 data_cnt = fls(readl(apu_mbox->regs + MTK_APU_MBOX_OUTBOX_IRQ)); + + memcpy_fromio(apu_mbox->msgs.data, apu_mbox->regs + MTK_APU_MBOX_OUTBOX, + sizeof(*apu_mbox->msgs.data) * data_cnt); + + mbox_chan_received_data(link, apu_mbox->msgs.data); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t mtk_apu_mailbox_irq_thread(int irq, void *data) +{ + struct mbox_chan *chan = data; + struct mtk_apu_mailbox *apu_mbox = get_mtk_apu_mailbox(chan->mbox); + struct mbox_chan *link = &apu_mbox->mbox.chans[0]; + + mbox_chan_received_data_bh(link, apu_mbox->msgs.data); + writel(readl(apu_mbox->regs + MTK_APU_MBOX_OUTBOX_IRQ), + apu_mbox->regs + MTK_APU_MBOX_OUTBOX_IRQ); + + return IRQ_HANDLED; +} + +static int mtk_apu_mailbox_send_data(struct mbox_chan *chan, void *data) +{ + struct mtk_apu_mailbox *apu_mbox = get_mtk_apu_mailbox(chan->mbox); + struct mtk_apu_mailbox_msg *msg = data; + + if (msg->data_cnt <= 0 || msg->data_cnt > apu_mbox->msg_mbox_slots) { + dev_err(apu_mbox->dev, "%s: invalid data_cnt %d\n", __func__, msg->data_cnt); + return -EINVAL; + } + + /* + * Mask lowest "data_cnt-1" interrupts bits, so the interrupt on the other side + * triggers only after the last data slot is written (sent). + */ + writel(GENMASK(msg->data_cnt - 2, 0), apu_mbox->regs + MTK_APU_MBOX_INBOX_IRQ_MASK); + memcpy_toio(apu_mbox->regs + MTK_APU_MBOX_INBOX, + msg->data, sizeof(*msg->data) * msg->data_cnt); + + return 0; +} + +static bool mtk_apu_mailbox_last_tx_done(struct mbox_chan *chan) +{ + struct mtk_apu_mailbox *apu_mbox = get_mtk_apu_mailbox(chan->mbox); + + return readl(apu_mbox->regs + MTK_APU_MBOX_INBOX_IRQ) == 0; +} + +static const struct mbox_chan_ops mtk_apu_mailbox_ops = { + .send_data = mtk_apu_mailbox_send_data, + .last_tx_done = mtk_apu_mailbox_last_tx_done, +}; + +static bool mtk_apu_mailbox_regmap_accessible_reg(struct device *dev, + unsigned int reg) +{ + if (reg >= MTK_APU_MBOX_SPARE_OFF_START && reg < MTK_APU_MBOX_SPARE_OFF_END) + return true; + return false; +} + +static const struct regmap_config mtk_apu_mailbox_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x100, + .readable_reg = mtk_apu_mailbox_regmap_accessible_reg, + .writeable_reg = mtk_apu_mailbox_regmap_accessible_reg, +}; + +static int mtk_apu_mailbox_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct mtk_apu_mailbox_platdata *data; + struct mtk_apu_mailbox *apu_mbox; + struct regmap *regmap; + int irq = -1, ret = 0; + + data = of_device_get_match_data(dev); + + apu_mbox = devm_kzalloc(dev, sizeof(*apu_mbox), GFP_KERNEL); + if (!apu_mbox) + return -ENOMEM; + + apu_mbox->dev = dev; + platform_set_drvdata(pdev, apu_mbox); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + apu_mbox->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(apu_mbox->regs)) + return PTR_ERR(apu_mbox->regs); + + apu_mbox->msg_mbox_slots = data->msg_mbox_slots; + apu_mbox->msgs.data = devm_kcalloc(dev, apu_mbox->msg_mbox_slots, + sizeof(*apu_mbox->msgs.data), GFP_KERNEL); + if (!apu_mbox->msgs.data) + return -ENOMEM; + + apu_mbox->mbox.txdone_irq = false; + apu_mbox->mbox.txdone_poll = true; + apu_mbox->mbox.txpoll_period = 1; + apu_mbox->mbox.ops = &mtk_apu_mailbox_ops; + apu_mbox->mbox.dev = dev; + apu_mbox->mbox.num_chans = 1; + apu_mbox->mbox.chans = devm_kcalloc(dev, apu_mbox->mbox.num_chans, + sizeof(*apu_mbox->mbox.chans), + GFP_KERNEL); + if (!apu_mbox->mbox.chans) + return -ENOMEM; + + ret = devm_mbox_controller_register(dev, &apu_mbox->mbox); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, irq, mtk_apu_mailbox_irq, + mtk_apu_mailbox_irq_thread, IRQF_ONESHOT, + dev_name(dev), apu_mbox->mbox.chans); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ\n"); + + regmap = devm_regmap_init_mmio(dev, apu_mbox->regs, &mtk_apu_mailbox_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return 0; +} + +static const struct mtk_apu_mailbox_platdata mt8196_platdata = { + .msg_mbox_slots = 8, +}; + +static const struct of_device_id mtk_apu_mailbox_of_match[] = { + { .compatible = "mediatek,mt8196-apu-mailbox", .data = &mt8196_platdata }, + {} +}; +MODULE_DEVICE_TABLE(of, mtk_apu_mailbox_of_match); + +static struct platform_driver mtk_apu_mailbox_driver = { + .probe = mtk_apu_mailbox_probe, + .driver = { + .name = "mtk-apu-mailbox", + .of_match_table = mtk_apu_mailbox_of_match, + }, +}; +module_platform_driver(mtk_apu_mailbox_driver); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek APU Mailbox Driver"); diff --git a/include/linux/mailbox/mtk-apu-mailbox.h b/include/linux/mailbox/mtk-apu-mailbox.h new file mode 100644 index 0000000000000..0afce8848205c --- /dev/null +++ b/include/linux/mailbox/mtk-apu-mailbox.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + * + */ + +#ifndef __MTK_APU_MAILBOX_H__ +#define __MTK_APU_MAILBOX_H__ + +struct mtk_apu_mailbox_msg { + u8 data_cnt; + u32 *data; +}; + +#endif /* __MTK_APU_MAILBOX_H__ */ -- GitLab From a74753975f43347220f9abd302486af5c506c90d Mon Sep 17 00:00:00 2001 From: Guodong Liu Date: Sat, 20 Jan 2024 17:02:33 +0800 Subject: [PATCH 407/456] CHROMIUM: arm64: dts: mt8196: Add mediatek pinctrl dts Add pinctrl device tree node support BUG=None TEST=build pass and boot to shell UPSTREAM-TASK=b:379035069 Signed-off-by: Guodong Liu Change-Id: Idf103e8adb3aaab1dd25c7887b390014f6cd9f41 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073684 Reviewed-by: Yu-Che Cheng Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index aa27b74af1ae2..96763fd7b87f9 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -633,6 +633,58 @@ reg = <0 0x1002c000 0 0x1000>; }; + pio: pinctrl@1002d000 { + compatible = "mediatek,mt8196-pinctrl"; + reg = <0 0x1002d000 0 0x1000>, + <0 0x12000000 0 0x1000>, + <0 0x12020000 0 0x1000>, + <0 0x12040000 0 0x1000>, + <0 0x12060000 0 0x1000>, + <0 0x12820000 0 0x1000>, + <0 0x12840000 0 0x1000>, + <0 0x12860000 0 0x1000>, + <0 0x13000000 0 0x1000>, + <0 0x13020000 0 0x1000>, + <0 0x13040000 0 0x1000>, + <0 0x130f0000 0 0x1000>, + <0 0x13110000 0 0x1000>, + <0 0x13800000 0 0x1000>, + <0 0x13820000 0 0x1000>, + <0 0x13860000 0 0x1000>, + <0 0x12080000 0 0x1000>, + <0 0x12880000 0 0x1000>, + <0 0x13080000 0 0x1000>, + <0 0x13880000 0 0x1000>, + <0 0x1c54a000 0 0x1000>; + reg-names = "iocfg0", + "iocfg_rt", + "iocfg_rm1", + "iocfg_rm2", + "iocfg_rb", + "iocfg_bm1", + "iocfg_bm2", + "iocfg_bm3", + "iocfg_lt", + "iocfg_lm1", + "iocfg_lm2", + "iocfg_lb1", + "iocfg_lb2", + "iocfg_tm1", + "iocfg_tm2", + "iocfg_tm3", + "eint-e", + "eint-s", + "eint-w", + "eint-n", + "eint-c"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 271>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <2>; + }; + i2c5: i2c@120a0000 { compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; reg = <0 0x120a0000 0 0x20000>, -- GitLab From f7e2bff0926a53e24ac81fcaf074e7615d1ffe3e Mon Sep 17 00:00:00 2001 From: Noah Shen Date: Fri, 1 Mar 2024 14:52:18 +0800 Subject: [PATCH 408/456] CHROMIUM: arm64: dts: mt8196: add snfc Add to support spi nor flash controller BUG=b:376509056 BUG=b:383247850 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:379034916 Change-Id: Ie380a8089d9a0e3323c0b6d36a4c4f94ae353e47 Signed-off-by: Noah Shen Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073708 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196-evb.dts | 39 +++++++++++++++++++++ arch/arm64/boot/dts/mediatek/mt8196.dtsi | 27 ++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts index c9747f3e4a7f8..e834ca5db1a0c 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts @@ -16,6 +16,45 @@ }; }; +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&nor_pins_default>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; +}; + +&pio { + nor_pins_default: nor-default-pins { + pins0 { + pinmux = ; + bias-pull-down = ; + mediatek,drive-strength-adv = <0>; + drive-strength = <14>; + }; + + pins1 { + pinmux = ; + bias-pull-up = ; + mediatek,drive-strength-adv = <0>; + drive-strength = <14>; + }; + + pins2 { + pinmux = , + ; + bias-pull-down; + drive-strength = <14>; + }; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 96763fd7b87f9..426b905d1d803 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -1149,6 +1149,33 @@ status = "disabled"; }; + pwm: pwm@16330000 { + compatible = "mediatek,pwm"; + reg = <0 0x16330000 0 0x1000>; + interrupts = ; + + status = "disabled"; + }; + + nor_flash: spi@16340000 { + compatible = "mediatek,mt8196-nor", + "mediatek,mt8186-nor"; + reg = <0 0x16340000 0 0x1000>; + clocks = <&cksys_clk CLK_CK_SFLASH_SEL>, + <&pericfg_ao_clk CLK_PERAO_FLASHIF_FLASH_FLASHIF>, + <&pericfg_ao_clk CLK_PERAO_FLASHIF_DRAM_FLASHIF>, + <&pericfg_ao_clk CLK_PERAO_FLASHIF_AXI_FLASHIF>, + <&pericfg_ao_clk CLK_PERAO_FLASHIF_BCLK_FLASHIF>, + <&pericfg_ao_clk CLK_PERAO_FLASHIF_27M_FLASHIF>; + clock-names = "spi", "sf", "axi", "axi_s", "bclk", "27m"; + assigned-clocks = <&cksys_clk CLK_CK_SFLASH_SEL>; + assigned-clock-parents = <&cksys_clk CLK_CK_UNIVPLL_D6_D8>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pericfg_ao_clk: syscon@16640000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-pericfg-ao", "mediatek,mt8196-pericfg_ao", "syscon"; -- GitLab From 6240f09a9554158540d6fc516f69a577f6962737 Mon Sep 17 00:00:00 2001 From: Mingjin Ge Date: Fri, 1 Mar 2024 09:48:37 +0800 Subject: [PATCH 409/456] CHROMIUM: arm64: dts: mt8196: Add usb dts 1.add USB xhci node 2.Add two syscon nodes for USB and wakeup on MT8196. 3.open EINT for USB and wakeup on MT8196 4.add disconnect setting for usb BUG=b:384639123 BUG=b:357046538 BUG=b:364480848 TEST=USB disk detection OK UPSTREAM-TASK=b:379036090 Signed-off-by: Mingjin Ge Signed-off-by: Liu Liu Change-Id: Icb8037d14555f77122d008f568eeaaf6b98ea4f2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073712 Tested-by: Fei Shao Commit-Queue: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196-evb.dts | 32 ++++++ arch/arm64/boot/dts/mediatek/mt8196.dtsi | 102 ++++++++++++++++++-- 2 files changed, 127 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts index e834ca5db1a0c..982b66d20c96d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts @@ -5,6 +5,7 @@ */ /dts-v1/; #include "mt8196.dtsi" +#include / { model = "MediaTek MT8196 evaluation board"; @@ -14,6 +15,15 @@ chosen: chosen { stdout-path = "serial0:115200n8"; }; + + usb_p0_vbus: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 20 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; &nor_flash { @@ -53,6 +63,28 @@ drive-strength = <14>; }; }; + + xhci0_pins_default: xhci0-default-pins { + pins-cmd-dat { + pinmux = ; + output-high; + }; + }; +}; + +&xhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&xhci0_pins_default>; + vbus-supply = <&usb_p0_vbus>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u3phy0 { + status = "okay"; }; &uart0 { diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index 426b905d1d803..da6dda1bf7a58 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -620,13 +620,6 @@ #clock-cells = <1>; }; - infracfg_ao_clk: syscon@10001000 { - /* TODO: Fix compatible in driver */ - compatible = "mediatek,mt8196-infracfg-ao", "mediatek,mt8196-infracfg_ao", "syscon"; - reg = <0 0x10001000 0 0x1000>; - #clock-cells = <1>; - }; - ifr_bus: syscon@1002c000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-ifr-bus", "mediatek,mt8196-ifr_bus", "syscon"; @@ -1184,6 +1177,101 @@ #clock-cells = <1>; }; + xhci0: usb@16700000 { + compatible = "mediatek,mtk-xhci"; + reg = <0 0x16700000 0 0x1000>, + <0 0x16703e00 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts-extended = <&gic GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH 0>, + <&pio 273 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host","wakeup"; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&vlp_cksys_clk CLK_VLP_CK_USB_TOP_SEL>, + <&vlp_cksys_clk CLK_VLP_CK_USB_XHCI_SEL>, + <&cksys_clk CLK_CK_USB_FMCNT_P1_SEL>; + clock-names = "sys_ck", "xhci_ck", "frmcnt_ck"; + power-domains = <&scpsys MT8196_POWER_DOMAIN_SSUSB_P0>; + mediatek,syscon-wakeup = <&usbwkcfg_ao_clk 0x200 107>; + wakeup-source; + status = "disabled"; + }; + + xhci1: usb1@16710000 { + compatible = "mediatek,mtk-xhci"; + reg = <0 0x16710000 0 0x1000>, + <0 0x16713e00 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts-extended = <&gic GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH 0>, + <&pio 276 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host","wakeup"; + phys = <&u2port1 PHY_TYPE_USB2>; + clocks = <&cksys_clk CLK_CK_USB_TOP_1P_SEL>, + <&cksys_clk CLK_CK_USB_XHCI_1P_SEL>, + <&cksys_clk CLK_CK_USB_FMCNT_P1_SEL>; + clock-names = "sys_ck", "xhci_ck", "frmcnt_ck"; + power-domains = <&scpsys MT8196_POWER_DOMAIN_SSUSB_P1>; + mediatek,syscon-wakeup = <&usbwkcfg_ao_clk 0x200 108>; + wakeup-source; + status = "disabled"; + }; + + u2phy0: usb-phy0@16730000 { + compatible = "mediatek,xsphy"; + ranges = <0x0 0x0 0x16730000 0x700>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + u2port0: usb2-phy0@0 { + reg = <0x0 0x400>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + mediatek,discth = <10>; + }; + }; + + u2phy1: usb-phy1@16740000 { + compatible = "mediatek,xsphy"; + ranges = <0x0 0x0 0x16740000 0x700>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + u2port1: usb2-phy1@0 { + reg = <0x0 0x400>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + mediatek,discth = <10>; + }; + }; + + u3phy0: usb3-phy0@16773000 { + compatible = "mediatek,xsphy"; + ranges; + reg = <0 0x16773000 0 0x200>; + #address-cells = <2>; + #size-cells = <2>; + power-domains = <&scpsys MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0>; + status = "disabled"; + + u3port0: usb3-phy0@16773400 { + reg = <0 0x16773400 0 0x500>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + }; + }; + + usbwkcfg_ao_clk: syscon@167a0000 { + compatible = "mediatek,mt8196-usbwkcfg-ao", "syscon"; + reg = <0 0x167a0000 0 0x1000>; + }; + ufscfg_ao_sec_clk: syscon@16890000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-ufscfg-ao-sec", "mediatek,mt8196-ufscfg_ao_sec", "syscon"; -- GitLab From 87fd84533b0446739eb6b1dc3044d2ba3204e239 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Thu, 7 Mar 2024 14:52:39 +0800 Subject: [PATCH 410/456] CHROMIUM: arm64: dts: mt8196: Enable PCIe0 and PCIe1 Add PCIe0 and PCIe1 support. BUG=b:383258443 BUG=b:354107653 TEST=build pass and boot to shell UPSTREAM-TASK=b:379039276 Signed-off-by: Jianjun Wang Signed-off-by: Hsin-Yi Wang Change-Id: I1859535cf3e95ca0c116bb3a6865e5aab9bdcf92 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073738 Commit-Queue: Fei Shao Reviewed-by: Fei Shao Tested-by: Fei Shao Reviewed-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196-evb.dts | 38 ++++ arch/arm64/boot/dts/mediatek/mt8196.dtsi | 188 ++++++++++++++++++++ 2 files changed, 226 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts index 982b66d20c96d..e245d663fc37a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8196-evb.dts @@ -40,6 +40,26 @@ }; }; +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins_default>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins_default>; + status = "okay"; +}; + +&pciephy0 { + status = "okay"; +}; + +&pciephy1 { + status = "okay"; +}; + &pio { nor_pins_default: nor-default-pins { pins0 { @@ -70,6 +90,24 @@ output-high; }; }; + + pcie0_pins_default: pcie0-default { + pins-cmd-dat { + pinmux = , + , + ; + bias-pull-up; + }; + }; + + pcie1_pins_default: pcie1-default { + pins-cmd-dat { + pinmux = , + , + ; + bias-pull-up = ; + }; + }; }; &xhci0 { diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index da6dda1bf7a58..c4a90446c8a68 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -1286,6 +1286,194 @@ #clock-cells = <1>; }; + pciephy0: phy@16900000 { + compatible = "mediatek,mt8196-pcie-phy"; + reg = <0 0x16900000 0 0x10000>, + <0 0x16920000 0 0x10000>; + reg-names = "sif", "ckm"; + + clocks = <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_PHY_P0_MCU_BUS_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF_PCIE>; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_PHY0>; + + num-lanes = <1>; + #phy-cells = <0>; + status = "disabled"; + }; + + pcie0: pcie@16910000 { + compatible = "mediatek,mt8196-pcie"; + device_type = "pci"; + reg = <0 0x16910000 0 0x4000>; + reg-names = "pcie-mac"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + bus-range = <0x00 0xff>; + linux,pci-domain = <0>; + pextpcfg = <&pextp0cfg_ao_clk>; + ranges = <0x82000000 0 0x50000000 0x0 0x50000000 0 0x8000000>; + + clocks = <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_MAC_P0_PL_P_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_MAC_P0_TL_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_MAC_P0_REF_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_MAC_P0_AXI_250_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_MAC_P0_AHB_APB_PCIE>, + <&pextp0cfg_ao_clk CLK_PEXT_PEXTP_VLP_AO_P0_LP_PCIE>; + clock-names = "pl_250m", "tl_26m", "peri_26m", + "peri_mem", "bus", "low_power"; + assigned-clocks = <&cksys_clk CLK_CK_TL_SEL>; + assigned-clock-parents = <&cksys_clk CLK_CK_MAINPLL_D4_D4>; + + resets = <&pextp0ao_rst 0>, <&pextp0ao_rst 1>; + reset-names = "mac", "phy"; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_MAC0>; + + phys = <&pciephy0>; + phy-names = "pcie-phy"; + + status = "disabled"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pciephy1: phy@16930000 { + compatible = "mediatek,mt8196-pcie-phy"; + reg = <0 0x16930000 0 0x10000>, + <0 0x16950000 0 0x10000>; + reg-names = "sif", "ckm"; + + clocks = <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF_PCIE>; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_PHY1>; + + num-lanes = <2>; + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie1: pcie@16940000 { + compatible = "mediatek,mt8196-pcie"; + device_type = "pci"; + reg = <0 0x16940000 0 0x4000>; + reg-names = "pcie-mac"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + bus-range = <0x00 0xff>; + linux,pci-domain = <1>; + pextpcfg = <&pextp1cfg_ao_clk>; + ranges = <0x82000000 0 0x58000000 0x0 0x58000000 0 0x18000000>; + + clocks = <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P1_PL_P_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P1_TL_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P1_REF_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P1_AXI_250_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P1_AHB_APB_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_VLP_AO_P1_LP_PCIE>; + clock-names = "pl_250m", "tl_26m", "peri_26m", + "peri_mem", "bus", "low_power"; + assigned-clocks = <&cksys_clk CLK_CK_TL_P1_SEL>; + assigned-clock-parents = <&cksys_clk CLK_CK_MAINPLL_D4_D4>; + + resets = <&pextp1ao_rst 0>, <&pextp1ao_rst 1>; + reset-names = "mac", "phy"; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_MAC1>; + + phys = <&pciephy1>; + phy-names = "pcie-phy"; + + status = "disabled"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pciephy2: phy@16960000 { + compatible = "mediatek,mt8196-pcie-phy"; + reg = <0 0x16960000 0 0x10000>, + <0 0x16980000 0 0x10000>; + reg-names = "sif", "ckm"; + + clocks = <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF_PCIE>; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_PHY2>; + + num-lanes = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie2: pcie@16970000 { + device_type = "pci"; + compatible = "mediatek,mt8196-pcie"; + reg = <0 0x16970000 0 0x4000>; + reg-names = "pcie-mac"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + bus-range = <0x00 0xff>; + linux,pci-domain = <2>; + pextpcfg = <&pextp1cfg_ao_clk>; + ranges = <0x82000000 0 0x70000000 0x0 0x70000000 0 0x8000000>; + + clocks = <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P2_PL_P_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P2_TL_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P2_REF_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P2_AXI_250_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_MAC_P2_AHB_APB_PCIE>, + <&pextp1cfg_ao_clk CLK_PEXT1_PEXTP_VLP_AO_P2_LP_PCIE>; + clock-names = "pl_250m", "tl_26m", "peri_26m", + "peri_mem", "bus", "low_power"; + assigned-clocks = <&cksys_clk CLK_CK_TL_P2_SEL>; + assigned-clock-parents = <&cksys_clk CLK_CK_MAINPLL_D4_D4>; + + resets = <&pextp1ao_rst 2>, <&pextp1ao_rst 3>; + reset-names = "mac", "phy"; + power-domains = <&scpsys MT8196_POWER_DOMAIN_PEXTP_MAC2>; + + phys = <&pciephy2>; + phy-names = "pcie-phy"; + + status = "disabled"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc2 0>, + <0 0 0 2 &pcie_intc2 1>, + <0 0 0 3 &pcie_intc2 2>, + <0 0 0 4 &pcie_intc2 3>; + + pcie_intc2: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + pextp0cfg_ao_clk: syscon@169b0000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-pextp0cfg-ao", "mediatek,mt8196-pextp0cfg_ao", "syscon", "simple-mfd"; -- GitLab From e23e922b32301c31c020692de1fce667d1ebe3da Mon Sep 17 00:00:00 2001 From: Runyang Chen Date: Tue, 26 Mar 2024 14:17:08 +0800 Subject: [PATCH 411/456] CHROMIUM: arm64: dts: mt8196: add node for dapc Add dapc node for mt8196 BUG=b:383916441 UPSTREAM-TASK=b:383957588 TEST=build pass and boot to shell Signed-off-by: Runyang Chen Change-Id: I2456dbcc2ff249991f83706ae7f2e2fc3d857e6b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073742 Reviewed-by: Yu-Che Cheng Tested-by: Fei Shao Reviewed-by: Fei Shao Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- arch/arm64/boot/dts/mediatek/mt8196.dtsi | 146 +++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8196.dtsi b/arch/arm64/boot/dts/mediatek/mt8196.dtsi index c4a90446c8a68..3c683987b2773 100644 --- a/arch/arm64/boot/dts/mediatek/mt8196.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8196.dtsi @@ -678,6 +678,27 @@ #interrupt-cells = <2>; }; + devapc_apinfra_dramc: devapc@102f3000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x102f3000 0 0x1000>; + vio-idx-num = <61>; + interrupts = ; + }; + + devapc_apinfra_emi: devapc@10613000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x10613000 0 0x1000>; + vio-idx-num = <149>; + interrupts = ; + }; + + devapc_apinfra_big4: devapc@10693000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x10693000 0 0x1000>; + vio-idx-num = <89>; + interrupts = ; + }; + i2c5: i2c@120a0000 { compatible = "mediatek,mt8196-i2c", "mediatek,mt8188-i2c"; reg = <0 0x120a0000 0 0x20000>, @@ -872,6 +893,27 @@ #clock-cells = <1>; }; + devapc_apinfra_io_intf: devapc@140a0000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x140a0000 0 0x1000>; + vio-idx-num = <8>; + interrupts = ; + }; + + devapc_apinfra_mem_intf: devapc@140c0000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x140c0000 0 0x1000>; + vio-idx-num = <7>; + interrupts = ; + }; + + devapc_apinfra_slb: devapc@140e0000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x140e0000 0 0x1000>; + vio-idx-num = <14>; + interrupts = ; + }; + apifrbus_ao_mem_reg_clk: syscon@14126000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-apifrbus-ao-mem-reg", "mediatek,mt8196-apifrbus_ao_mem_reg", "syscon"; @@ -879,11 +921,59 @@ #clock-cells = <1>; }; + devapc_apinfra_mem: devapc@14130000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x14130000 0 0x1000>; + vio-idx-num = <13>; + interrupts = ; + }; + + + devapc_apinfra_mem_ctrl: devapc@14131000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x14131000 0 0x1000>; + vio-idx-num = <23>; + interrupts = ; + }; + + infracfg@14136000 { + compatible = "mediatek,infracfg"; + reg = <0 0x14136000 0 0x1000>; + }; + + devapc_apinfra_int: devapc@142f4000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x142f4000 0 0x1000>; + vio-idx-num = <26>; + interrupts = ; + }; + + devapc_apinfra_io_ctrl: devapc@14400000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x14400000 0 0x1000>; + vio-idx-num = <10>; + interrupts = ; + }; + + devapc_apinfra_io: devapc@14401000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x14401000 0 0x1000>; + vio-idx-num = <230>; + interrupts = ; + }; + hwv: syscon@14500000 { compatible = "mediatek,mt8196-hwv", "syscon"; reg = <0 0x14500000 0 0x3000>; }; + devapc_apinfra_mmu: devapc@14800000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x14800000 0 0x1000>; + vio-idx-num = <20>; + interrupts = ; + }; + uart0: serial@16000000 { compatible = "mediatek,mt6577-uart"; reg = <0 0x16000000 0 0x1000>; @@ -1177,6 +1267,13 @@ #clock-cells = <1>; }; + devapc_peri: devapc@16670000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x16670000 0 0x1000>; + vio-idx-num = <204>; + interrupts = ; + }; + xhci0: usb@16700000 { compatible = "mediatek,mtk-xhci"; reg = <0 0x16700000 0 0x1000>, @@ -1530,6 +1627,20 @@ #clock-cells = <1>; }; + devapc_apinfra_ssr: devapc@180f3000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x180f3000 0 0x1000>; + vio-idx-num = <39>; + interrupts = ; + }; + + devapc_adsp: devapc@1a019000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x1a019000 0 0x1000>; + vio-idx-num = <54>; + interrupts = ; + }; + afe_clk: syscon@1a110000 { compatible = "mediatek,mt8196-audiosys", "syscon"; reg = <0 0x1a110000 0 0x1000>; @@ -1565,6 +1676,13 @@ #clock-cells = <1>; }; + devapc_vlp: devapc@1c032000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x1c032000 0 0x1000>; + vio-idx-num = <101>; + interrupts = ; + }; + systimer: systimer@1c400000 { compatible = "mediatek,mt8196-timer", "mediatek,mt6765-timer"; @@ -1591,6 +1709,13 @@ mediatek,skip-rpm-cb; }; + devapc_mminfra: devapc@30040000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x30040000 0 0x1000>; + vio-idx-num = <699>; + interrupts = ; + }; + gce0: gce@300c0000 { compatible = "mediatek,mt8196-gce"; reg = <0 0x300c0000 0 0x80000>; @@ -1656,6 +1781,13 @@ reg = <0 0x31a80000 0 0x1000>; }; + devapc_mmup: devapc@31ad5000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x31ad5000 0 0x1000>; + vio-idx-num = <71>; + interrupts = ; + }; + mm_hwv: syscon@31b00000 { /* TODO: Fix compatible in driver */ compatible = "mediatek,mt8196-mm-hwv", "mediatek,mt8196-mm_hwv", "syscon"; @@ -2128,6 +2260,20 @@ #clock-cells = <1>; }; + devapc_gpu: devapc@4b890000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x4b890000 0 0x1000>; + vio-idx-num = <20>; + interrupts = ; + }; + + devapc_gpu1: devapc@4b8b0000 { + compatible = "mediatek,mt8196-devapc"; + reg = <0 0x4b8b0000 0 0x1000>; + vio-idx-num = <26>; + interrupts = ; + }; + apu_smmu: iommu@4c000000 { compatible = "mediatek,mt8196-apu-smmu", "arm,smmu-v3"; reg = <0 0x4c000000 0 0x1e0000>; -- GitLab From 8e3e5a590f30ca258193f602cb6df1dafe0908cb Mon Sep 17 00:00:00 2001 From: Shunxi Zhang Date: Thu, 31 Oct 2024 21:58:02 +0800 Subject: [PATCH 412/456] CHROMIUM: rtc: mediatek: Add mt6685 RTC driver Add mt6685 rtc driver BUG=b:385289574 TEST=emerge-rauru chromeos-kernel-6_6 UPSTREAM-TASK=b:379039123 Change-Id: If52b3c7e4c5da4c6ae7fe62b7fdea2fbe051f1c1 Signed-off-by: Shunxi Zhang Signed-off-by: Xavier Chang Signed-off-by: Fei Shao Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6073730 Reviewed-by: Yidi Lin Signed-off-by: Hubert Mazur --- drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-mt6685.c | 535 ++++++++++++++++ include/linux/mfd/mt6685-audclk.h | 11 + include/linux/mfd/mt6685/core.h | 22 + include/linux/mfd/mt6685/registers.h | 921 +++++++++++++++++++++++++++ include/linux/mfd/mt6685/rtc.h | 300 +++++++++ 7 files changed, 1800 insertions(+) create mode 100644 drivers/rtc/rtc-mt6685.c create mode 100644 include/linux/mfd/mt6685-audclk.h create mode 100644 include/linux/mfd/mt6685/core.h create mode 100644 include/linux/mfd/mt6685/registers.h create mode 100644 include/linux/mfd/mt6685/rtc.h diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 92f46a6312c24..440e6763cf0fb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1841,6 +1841,16 @@ config RTC_DRV_MT6397 If you want to use MediaTek(R) RTC interface, select Y or M here. +config RTC_DRV_MT6685 + tristate "Mediatek Real Time Clock driver" + depends on MFD_MT6685 || (COMPILE_TEST && IRQ_DOMAIN) + help + This selects the Mediatek(R) RTC driver. RTC is part of Mediatek + MT6685. You should enable MT6685 MFD before select + Mediatek(R) RTC driver. + + If you want to use Mediatek(R) RTC interface, select Y or M here. + config RTC_DRV_MT7622 tristate "MediaTek SoC based RTC" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index fd209883ee2ef..51bf51cb736e6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_MSC313) += rtc-msc313.o obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o obj-$(CONFIG_RTC_DRV_MT2712) += rtc-mt2712.o obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o +obj-$(CONFIG_RTC_DRV_MT6685) += rtc-mt6685.o obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o diff --git a/drivers/rtc/rtc-mt6685.c b/drivers/rtc/rtc-mt6685.c new file mode 100644 index 0000000000000..716f1dbb2cc75 --- /dev/null +++ b/drivers/rtc/rtc-mt6685.c @@ -0,0 +1,535 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + * Author: Amber Lin + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void power_on_mclk(struct mt6685_rtc *rtc) +{ + guard(mutex)(&rtc->clk_lock); + /* Power on RTC MCLK and 32k clk before write RTC register */ + regmap_write(rtc->regmap, RG_RTC_32K_CK_PDN_CLR, RG_RTC_32K_CK_PDN_MASK); + regmap_write(rtc->regmap, RG_RTC_MCLK_PDN_CLR, RG_RTC_MCLK_PDN_MASK); + + rtc->clk_cnt++; + + mdelay(1); +} + +static void power_down_mclk(struct mt6685_rtc *rtc) +{ + guard(mutex)(&rtc->clk_lock); + rtc->clk_cnt--; + + if (rtc->clk_cnt == 0) { + /* Power down RTC MCLK and 32k clk after write RTC register */ + regmap_write(rtc->regmap, RG_RTC_32K_CK_PDN_SET, RG_RTC_32K_CK_PDN_MASK); + regmap_write(rtc->regmap, RG_RTC_MCLK_PDN_SET, RG_RTC_MCLK_PDN_MASK); + mdelay(1); + } +} + +static inline int rtc_read(struct mt6685_rtc *rtc, unsigned int reg, + unsigned int *val) +{ + return regmap_bulk_read(rtc->regmap, reg, val, 2); +} + +static inline int rtc_write(struct mt6685_rtc *rtc, unsigned int reg, + unsigned int val) +{ + return regmap_bulk_write(rtc->regmap, reg, &val, 2); +} + +static int rtc_update_bits(struct mt6685_rtc *rtc, unsigned int reg, + unsigned int mask, unsigned int val) +{ + int ret; + unsigned int tmp, orig = 0; + + ret = rtc_read(rtc, reg, &orig); + if (ret != 0) + return ret; + + tmp = orig & ~mask; + tmp |= val & mask; + ret = rtc_write(rtc, reg, tmp); + + return ret; +} + +static int mtk_rtc_write_trigger(struct mt6685_rtc *rtc) +{ + unsigned long timeout = jiffies + HZ; + int ret; + u32 data; + + ret = rtc_write(rtc, + rtc->addr_base + rtc->data->wrtgr, 1); + if (ret < 0) + return ret; + + while (1) { + ret = rtc_read(rtc, rtc->addr_base + RTC_BBPU, + &data); + if (ret < 0) + break; + if (!(data & RTC_BBPU_CBUSY)) + break; + if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; + break; + } + cpu_relax(); + } + + return ret; +} + +static void mtk_rtc_reset_bbpu_alarm_status(struct mt6685_rtc *rtc) +{ + u32 bbpu; + int ret; + + power_on_mclk(rtc); + + bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN | RTC_BBPU_RESET_AL; + ret = rtc_write(rtc, rtc->addr_base + RTC_BBPU, bbpu); + if (ret < 0) { + dev_err(rtc->rtc_dev->dev.parent, "%s: write rtc bbpu error\n", __func__); + goto exit; + } + + mtk_rtc_write_trigger(rtc); +exit: + power_down_mclk(rtc); + return; +} + +static int mtk_rtc_is_alarm_irq(struct mt6685_rtc *rtc) +{ + u32 irqsta = 0, bbpu = 0, sck = 0, sck_check = 0, irqsta_check = 0; + int ret; + + power_on_mclk(rtc); + + /* read clear */ + ret = rtc_read(rtc, rtc->addr_base + RTC_IRQ_STA, &irqsta); + dev_dbg(rtc->rtc_dev->dev.parent, "%s: IRQ STA 0x%x\n", __func__, irqsta); + + /* clear SCK_TOP rtc interrupt */ + rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck); + rtc_write(rtc, SCK_TOP_INT_STATUS0, sck); + + rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck_check); + if (sck_check) { + udelay(70); + rtc_write(rtc, SCK_TOP_INT_STATUS0, 1); + + rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck_check); + if (sck_check) { + dev_notice(rtc->rtc_dev->dev.parent, + "%s: TOP INT STA 0x%x\n", __func__, sck_check); + + rtc_read(rtc, rtc->addr_base + RTC_IRQ_STA, &irqsta_check); + dev_notice(rtc->rtc_dev->dev.parent, + "%s: IRQ STA 0x%x\n", __func__, irqsta_check); + } + } + + if ((ret == 0) && (irqsta & RTC_IRQ_STA_AL)) { + bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN; + ret = rtc_write(rtc, + rtc->addr_base + RTC_BBPU, bbpu); + if (ret < 0) + dev_err(rtc->rtc_dev->dev.parent, + "%s: %d error\n", __func__, __LINE__); + + ret = rtc_update_bits(rtc, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_AL, 0); + if (ret < 0) + dev_err(rtc->rtc_dev->dev.parent, + "%s: %d error\n", __func__, __LINE__); + + mtk_rtc_write_trigger(rtc); + power_down_mclk(rtc); + + return RTC_ALSTA; + } + + power_down_mclk(rtc); + + return RTC_NONE; +} + +static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) +{ + struct mt6685_rtc *rtc = data; + int status = RTC_NONE; + + guard(mutex)(&rtc->lock); + + status = mtk_rtc_is_alarm_irq(rtc); + + if (rtc->rtc_dev == NULL) + return IRQ_NONE; + + if (status == RTC_NONE) + return IRQ_NONE; + + mtk_rtc_reset_bbpu_alarm_status(rtc); + + if (rtc->rtc_dev != NULL) + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +static int __mtk_rtc_read_time(struct mt6685_rtc *rtc, + struct rtc_time *tm, int *sec) +{ + int ret; + unsigned int reload = 0; + u16 data[RTC_OFFSET_COUNT] = { 0 }; + + power_on_mclk(rtc); + + rtc_read(rtc, rtc->addr_base + RTC_BBPU, &reload); + reload = reload | RTC_BBPU_KEY | RTC_BBPU_RELOAD; + rtc_write(rtc, rtc->addr_base + RTC_BBPU, reload); + mtk_rtc_write_trigger(rtc); + power_down_mclk(rtc); + + guard(mutex)(&rtc->lock); + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT * 2); + if (ret < 0) + return ret; + + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_TC_SEC_MASK; + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_TC_MIN_MASK; + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_TC_HOU_MASK; + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_TC_DOM_MASK; + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK; + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_TC_YEA_MASK; + + ret = rtc_read(rtc, rtc->addr_base + RTC_TC_SEC, sec); + *sec &= RTC_TC_SEC_MASK; + + return ret; +} + +static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + time64_t time; + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + int days, sec, ret; + + do { + ret = __mtk_rtc_read_time(rtc, tm, &sec); + if (ret < 0) + return ret; + } while (sec < tm->tm_sec); + + /* HW register use 7 bits to store year data, minus + * RTC_MIN_YEAR_OFFSET before write year data to register, and plus + * RTC_MIN_YEAR_OFFSET back after read year from register + */ + + /* HW register start mon from one, but tm_mon start from zero. */ + tm->tm_mon--; + time = rtc_tm_to_time64(tm); + + /* rtc_tm_to_time64 covert Gregorian date to seconds since + * 01-01-1970 00:00:00, and this date is Thursday. + */ + days = div_s64(time, 86400); + tm->tm_wday = (days + 4) % 7; + + return ret; +} + +static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + power_on_mclk(rtc); + + tm->tm_mon++; + + data[RTC_OFFSET_SEC] = tm->tm_sec; + data[RTC_OFFSET_MIN] = tm->tm_min; + data[RTC_OFFSET_HOUR] = tm->tm_hour; + data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_MTH] = tm->tm_mon; + data[RTC_OFFSET_YEAR] = tm->tm_year; + + guard(mutex)(&rtc->lock); + ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT * 2); + if (ret < 0) + goto exit; + + /* Time register write to hardware after call trigger function */ + ret = mtk_rtc_write_trigger(rtc); + +exit: + power_down_mclk(rtc); + + return ret; +} + +static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + u32 irqen = 0, pdn2 = 0; + int ret; + u16 data[RTC_OFFSET_COUNT] = { 0 }; + + guard(mutex)(&rtc->lock); + ret = rtc_read(rtc, rtc->addr_base + RTC_IRQ_EN, &irqen); + if (ret < 0) + return ret; + + ret = rtc_read(rtc, rtc->addr_base + RTC_PDN2, &pdn2); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT * 2); + if (ret < 0) + return ret; + + alm->enabled = !!(irqen & RTC_IRQ_EN_AL); + alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); + + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; + + tm->tm_mon--; + + return 0; +} + +static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + power_on_mclk(rtc); + + tm->tm_mon++; + guard(mutex)(&rtc->lock); + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT * 2); + if (ret < 0) + goto exit; + + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) | + (tm->tm_sec & RTC_AL_SEC_MASK)); + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) | + (tm->tm_min & RTC_AL_MIN_MASK)); + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) | + (tm->tm_hour & RTC_AL_HOU_MASK)); + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) | + (tm->tm_mday & RTC_AL_DOM_MASK)); + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) | + (tm->tm_mon & RTC_AL_MTH_MASK)); + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) | + (tm->tm_year & RTC_AL_YEA_MASK)); + + if (alm->enabled) { + ret = regmap_bulk_write(rtc->regmap, + rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT * 2); + if (ret < 0) + goto exit; + + ret = rtc_write(rtc, rtc->addr_base + RTC_AL_MASK, + RTC_AL_MASK_DOW); + if (ret < 0) + goto exit; + + ret = rtc_update_bits(rtc, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_AL, RTC_IRQ_EN_AL); + if (ret < 0) + goto exit; + } else { + ret = rtc_update_bits(rtc, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_AL, 0); + if (ret < 0) + goto exit; + } + + /* All alarm time register write to hardware after calling + * mtk_rtc_write_trigger. This can avoid race condition if alarm + * occur happen during writing alarm time register. + */ + ret = mtk_rtc_write_trigger(rtc); + +exit: + power_down_mclk(rtc); + return ret; +} + +static const struct rtc_class_ops mtk_rtc_ops = { + .read_time = mtk_rtc_read_time, + .set_time = mtk_rtc_set_time, + .read_alarm = mtk_rtc_read_alarm, + .set_alarm = mtk_rtc_set_alarm, +}; + +static int mtk_rtc_probe(struct platform_device *pdev) +{ + struct mt6685_rtc *rtc; + struct device_node *np = pdev->dev.of_node; + int ret; + + if (!of_device_is_available(np)) { + dev_err(&pdev->dev, "rtc disabled\n"); + return -ENODEV; + } + + rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6685_rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + rtc->data = of_device_get_match_data(&pdev->dev); + if (!rtc->data) { + dev_err(&pdev->dev, "of_device_get_match_data failed\n"); + return -ENODEV; + } + + if (of_property_read_u32(pdev->dev.of_node, "base", &rtc->addr_base)) + rtc->addr_base = RTC_DSN_ID; + + mutex_init(&rtc->lock); + mutex_init(&rtc->clk_lock); + + platform_set_drvdata(pdev, rtc); + + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + + rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!rtc->regmap) + return -ENODEV; + + /* Obtain interrupt ID from DTS or MFD */ + rtc->irq = platform_get_irq(pdev, 0); + if (rtc->irq < 0) + return rtc->irq; + + rtc->clk_cnt = 0; + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, + mtk_rtc_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + "mt6685-rtc", rtc); + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + rtc->irq, ret); + return ret; + } + + /*Enable SCK_TOP rtc interrupt*/ + rtc_update_bits(rtc, SCK_TOP_INT_CON0, EN_RTC_INTERRUPT, 1); + + device_init_wakeup(&pdev->dev, 1); + + rtc->rtc_dev->ops = &mtk_rtc_ops; + ret = devm_rtc_register_device(rtc->rtc_dev); + if (ret) { + dev_err(&pdev->dev, "register rtc device failed\n"); + return ret; + }; + + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; + rtc->rtc_dev->range_max = mktime64(2027, 12, 31, 23, 59, 59); + rtc->rtc_dev->start_secs = mktime64(1968, 1, 2, 0, 0, 0); + rtc->rtc_dev->set_start_time = true; + + power_on_mclk(rtc); + power_down_mclk(rtc); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int mt6685_rtc_suspend(struct device *dev) +{ + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(rtc->irq); + + return 0; +} + +static int mt6685_rtc_resume(struct device *dev) +{ + struct mt6685_rtc *rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(rtc->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mt6685_pm_ops, mt6685_rtc_suspend, + mt6685_rtc_resume); +#endif + +static const struct mtk_rtc_data mt6685_rtc_data = { + .wrtgr = RTC_WRTGR, +}; + +static const struct of_device_id mt6685_rtc_of_match[] = { + { .compatible = "mediatek,mt6685-rtc", .data = &mt6685_rtc_data }, + { } +}; +MODULE_DEVICE_TABLE(of, mt6685_rtc_of_match); + +static struct platform_driver mtk_rtc_driver = { + .driver = { + .name = "mt6685-rtc", + .of_match_table = mt6685_rtc_of_match, +#ifdef CONFIG_PM_SLEEP + .pm = &mt6685_pm_ops, +#endif + }, + .probe = mtk_rtc_probe, +}; + +module_platform_driver(mtk_rtc_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mw Lin "); +MODULE_DESCRIPTION("RTC Driver for MediaTek MT6685 Clock IC"); diff --git a/include/linux/mfd/mt6685-audclk.h b/include/linux/mfd/mt6685-audclk.h new file mode 100644 index 0000000000000..fd99effd0a6c0 --- /dev/null +++ b/include/linux/mfd/mt6685-audclk.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 MediaTek Inc. + */ +#ifndef _AUDIO_DCXO_H_ +#define _AUDIO_DCXO_H_ + +/* just be called by audio module for dcxo */ +void mt6685_set_dcxo_mode(unsigned int mode); +void mt6685_set_dcxo(bool enable); +#endif diff --git a/include/linux/mfd/mt6685/core.h b/include/linux/mfd/mt6685/core.h new file mode 100644 index 0000000000000..dcaf800e82128 --- /dev/null +++ b/include/linux/mfd/mt6685/core.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MFD_MT6685_CORE_H__ +#define __MFD_MT6685_CORE_H__ + +struct mt6685_chip { + struct device *dev; + struct regmap *regmap; + int irq; + struct irq_domain *irq_domain; + struct mutex irqlock; /* Mid-end lock for synchronous operation */ + u16 wake_mask[2]; + u16 irq_masks_cur[2]; + u16 irq_masks_cache[2]; + u16 int_con[2]; + u16 int_status[2]; +}; + +#endif /* __MFD_MT6685_CORE_H__ */ diff --git a/include/linux/mfd/mt6685/registers.h b/include/linux/mfd/mt6685/registers.h new file mode 100644 index 0000000000000..3072a59545b69 --- /dev/null +++ b/include/linux/mfd/mt6685/registers.h @@ -0,0 +1,921 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc + */ + +#ifndef _MT6685_HW_H_ +#define _MT6685_HW_H_ + +#define MT6685_REG_BASE ((unsigned int)(0x0)) +#define MT6685_HWCID_L (MT6685_REG_BASE + 0x8) +#define MT6685_TOP_CON (MT6685_REG_BASE + 0x18) +#define MT6685_TOP_CKPDN_CON0 (MT6685_REG_BASE + 0x10b) +#define MT6685_TOP_CKPDN_CON0_SET (MT6685_REG_BASE + 0x10c) +#define MT6685_TOP_CKPDN_CON0_CLR (MT6685_REG_BASE + 0x10d) +#define MT6685_TOP_CKSEL_CON0 (MT6685_REG_BASE + 0x111) +#define MT6685_TOP_CKSEL_CON0_SET (MT6685_REG_BASE + 0x112) +#define MT6685_TOP_CKSEL_CON0_CLR (MT6685_REG_BASE + 0x113) +#define MT6685_TOP2_ELR1 (MT6685_REG_BASE + 0x12f) +#define MT6685_TOP_DIG_WPK (MT6685_REG_BASE + 0x3a8) +#define MT6685_TOP_DIG_WPK_H (MT6685_REG_BASE + 0x3a9) +#define MT6685_SCK_TOP_INT_STATUS0 (MT6685_REG_BASE + 0x534) +#define MT6685_SCK_TOP_INT_RAW_STATUS0 (MT6685_REG_BASE + 0x536) +#define MT6685_SCK_TOP_CON0_L (MT6685_REG_BASE + 0x50c) +#define MT6685_SCK_TOP_CON0_H (MT6685_REG_BASE + 0x50d) +#define MT6685_SCK_TOP_CKPDN_CON0_L (MT6685_REG_BASE + 0x514) +#define MT6685_SCK_TOP_CKPDN_CON0_L_SET (MT6685_REG_BASE + 0x515) +#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR (MT6685_REG_BASE + 0x516) +#define MT6685_SCK_TOP_RST_CON0 (MT6685_REG_BASE + 0x522) +#define MT6685_SCK_TOP_INT_CON0 (MT6685_REG_BASE + 0x528) +#define MT6685_SCK_TOP_INT_CON0_SET (MT6685_REG_BASE + 0x52a) +#define MT6685_SCK_TOP_INT_CON0_CLR (MT6685_REG_BASE + 0x52c) +#define MT6685_FQMTR_CON0_L (MT6685_REG_BASE + 0x546) +#define MT6685_FQMTR_CON0_H (MT6685_REG_BASE + 0x547) +#define MT6685_FQMTR_CON1_L (MT6685_REG_BASE + 0x548) +#define MT6685_FQMTR_CON2_L (MT6685_REG_BASE + 0x54a) +#define MT6685_SCK_TOP_CKSEL_CON (MT6685_REG_BASE + 0x568) +#define MT6685_RTC_SPAR_RELOAD (MT6685_REG_BASE + 0x56a) +#define MT6685_RTC_ANA_ID (MT6685_REG_BASE + 0x580) +#define MT6685_RTC_DIG_ID (MT6685_REG_BASE + 0x581) +#define MT6685_RTC_ANA_REV (MT6685_REG_BASE + 0x582) +#define MT6685_RTC_DIG_REV (MT6685_REG_BASE + 0x583) +#define MT6685_RTC_DBI (MT6685_REG_BASE + 0x584) +#define MT6685_RTC_ESP (MT6685_REG_BASE + 0x585) +#define MT6685_RTC_FPI (MT6685_REG_BASE + 0x586) +#define MT6685_RTC_DXI (MT6685_REG_BASE + 0x587) +#define MT6685_RTC_BBPU_L (MT6685_REG_BASE + 0x588) +#define MT6685_RTC_BBPU_H (MT6685_REG_BASE + 0x589) +#define MT6685_RTC_IRQ_STA (MT6685_REG_BASE + 0x58a) +#define MT6685_RTC_IRQ_EN (MT6685_REG_BASE + 0x58c) +#define MT6685_RTC_CII_EN_L (MT6685_REG_BASE + 0x58e) +#define MT6685_RTC_CII_EN_H (MT6685_REG_BASE + 0x58f) +#define MT6685_RTC_AL_MASK (MT6685_REG_BASE + 0x590) +#define MT6685_RTC_TC_SEC (MT6685_REG_BASE + 0x592) +#define MT6685_RTC_TC_MIN (MT6685_REG_BASE + 0x594) +#define MT6685_RTC_TC_HOU (MT6685_REG_BASE + 0x596) +#define MT6685_RTC_TC_DOM (MT6685_REG_BASE + 0x598) +#define MT6685_RTC_TC_DOW (MT6685_REG_BASE + 0x59a) +#define MT6685_RTC_TC_MTH_L (MT6685_REG_BASE + 0x59c) +#define MT6685_RTC_TC_MTH_H (MT6685_REG_BASE + 0x59d) +#define MT6685_RTC_TC_YEA (MT6685_REG_BASE + 0x59e) +#define MT6685_RTC_AL_SEC_L (MT6685_REG_BASE + 0x5a0) +#define MT6685_RTC_AL_SEC_H (MT6685_REG_BASE + 0x5a1) +#define MT6685_RTC_AL_MIN (MT6685_REG_BASE + 0x5a2) +#define MT6685_RTC_AL_HOU_L (MT6685_REG_BASE + 0x5a4) +#define MT6685_RTC_AL_HOU_H (MT6685_REG_BASE + 0x5a5) +#define MT6685_RTC_AL_DOM_L (MT6685_REG_BASE + 0x5a6) +#define MT6685_RTC_AL_DOM_H (MT6685_REG_BASE + 0x5a7) +#define MT6685_RTC_AL_DOW_L (MT6685_REG_BASE + 0x5a8) +#define MT6685_RTC_AL_DOW_H (MT6685_REG_BASE + 0x5a9) +#define MT6685_RTC_AL_MTH_L (MT6685_REG_BASE + 0x5aa) +#define MT6685_RTC_AL_MTH_H (MT6685_REG_BASE + 0x5ab) +#define MT6685_RTC_AL_YEA_L (MT6685_REG_BASE + 0x5ac) +#define MT6685_RTC_AL_YEA_H (MT6685_REG_BASE + 0x5ad) +#define MT6685_RTC_OSC32CON_L (MT6685_REG_BASE + 0x5ae) +#define MT6685_RTC_OSC32CON_H (MT6685_REG_BASE + 0x5af) +#define MT6685_RTC_POWERKEY1_L (MT6685_REG_BASE + 0x5b0) +#define MT6685_RTC_POWERKEY1_H (MT6685_REG_BASE + 0x5b1) +#define MT6685_RTC_POWERKEY2_L (MT6685_REG_BASE + 0x5b2) +#define MT6685_RTC_POWERKEY2_H (MT6685_REG_BASE + 0x5b3) +#define MT6685_RTC_PDN1_L (MT6685_REG_BASE + 0x5b4) +#define MT6685_RTC_PDN1_H (MT6685_REG_BASE + 0x5b5) +#define MT6685_RTC_PDN2_L (MT6685_REG_BASE + 0x5b6) +#define MT6685_RTC_PDN2_H (MT6685_REG_BASE + 0x5b7) +#define MT6685_RTC_SPAR0_L (MT6685_REG_BASE + 0x5b8) +#define MT6685_RTC_SPAR0_H (MT6685_REG_BASE + 0x5b9) +#define MT6685_RTC_SPAR1_L (MT6685_REG_BASE + 0x5ba) +#define MT6685_RTC_SPAR1_H (MT6685_REG_BASE + 0x5bb) +#define MT6685_RTC_PROT_L (MT6685_REG_BASE + 0x5bc) +#define MT6685_RTC_PROT_H (MT6685_REG_BASE + 0x5bd) +#define MT6685_RTC_DIFF_L (MT6685_REG_BASE + 0x5be) +#define MT6685_RTC_DIFF_H (MT6685_REG_BASE + 0x5bf) +#define MT6685_RTC_CALI_L (MT6685_REG_BASE + 0x5c0) +#define MT6685_RTC_CALI_H (MT6685_REG_BASE + 0x5c1) +#define MT6685_RTC_WRTGR (MT6685_REG_BASE + 0x5c2) +#define MT6685_RTC_CON_L (MT6685_REG_BASE + 0x5c4) +#define MT6685_RTC_CON_H (MT6685_REG_BASE + 0x5c5) +#define MT6685_RTC_SEC_CTRL (MT6685_REG_BASE + 0x5c6) +#define MT6685_RTC_INT_CNT_L (MT6685_REG_BASE + 0x5c8) +#define MT6685_RTC_INT_CNT_H (MT6685_REG_BASE + 0x5c9) +#define MT6685_RTC_SEC_DAT0_L (MT6685_REG_BASE + 0x5ca) +#define MT6685_RTC_SEC_DAT0_H (MT6685_REG_BASE + 0x5cb) +#define MT6685_RTC_SEC_DAT1_L (MT6685_REG_BASE + 0x5cc) +#define MT6685_RTC_SEC_DAT1_H (MT6685_REG_BASE + 0x5cd) +#define MT6685_RTC_SEC_DAT2_L (MT6685_REG_BASE + 0x5ce) +#define MT6685_RTC_SEC_DAT2_H (MT6685_REG_BASE + 0x5cf) +#define MT6685_RTC_RG_FG0 (MT6685_REG_BASE + 0x5d0) +#define MT6685_RTC_RG_FG1 (MT6685_REG_BASE + 0x5d2) +#define MT6685_RTC_RG_FG2 (MT6685_REG_BASE + 0x5d4) +#define MT6685_RTC_RG_FG3 (MT6685_REG_BASE + 0x5d6) +#define MT6685_RTC_SPAR_MACRO (MT6685_REG_BASE + 0x5d8) +#define MT6685_RTC_SPAR_CORE (MT6685_REG_BASE + 0x5e0) +#define MT6685_RTC_EOSC_CALI (MT6685_REG_BASE + 0x5e2) +#define MT6685_RTC_SEC_ANA_ID (MT6685_REG_BASE + 0x600) +#define MT6685_RTC_SEC_DIG_ID (MT6685_REG_BASE + 0x601) +#define MT6685_RTC_SEC_ANA_REV (MT6685_REG_BASE + 0x602) +#define MT6685_RTC_SEC_DIG_REV (MT6685_REG_BASE + 0x603) +#define MT6685_RTC_SEC_DBI (MT6685_REG_BASE + 0x604) +#define MT6685_RTC_SEC_ESP (MT6685_REG_BASE + 0x605) +#define MT6685_RTC_SEC_FPI (MT6685_REG_BASE + 0x606) +#define MT6685_RTC_SEC_DXI (MT6685_REG_BASE + 0x607) +#define MT6685_RTC_TC_SEC_SEC (MT6685_REG_BASE + 0x608) +#define MT6685_RTC_TC_MIN_SEC (MT6685_REG_BASE + 0x60a) +#define MT6685_RTC_TC_HOU_SEC (MT6685_REG_BASE + 0x60c) +#define MT6685_RTC_TC_DOM_SEC (MT6685_REG_BASE + 0x60e) +#define MT6685_RTC_TC_DOW_SEC (MT6685_REG_BASE + 0x610) +#define MT6685_RTC_TC_MTH_SEC (MT6685_REG_BASE + 0x612) +#define MT6685_RTC_TC_YEA_SEC (MT6685_REG_BASE + 0x614) +#define MT6685_RTC_SEC_CK_PDN (MT6685_REG_BASE + 0x616) +#define MT6685_RTC_SEC_WRTGR (MT6685_REG_BASE + 0x618) +#define MT6685_DCXO_DIG_MODE_CW0 (MT6685_REG_BASE + 0x789) +/* mask is HEX; shift is Integer */ +#define MT6685_RG_SRCLKEN_IN0_HW_MODE_ADDR \ + MT6685_TOP_CON +#define MT6685_RG_SRCLKEN_IN0_HW_MODE_MASK 0x1 +#define MT6685_RG_SRCLKEN_IN0_HW_MODE_SHIFT 1 +#define MT6685_RG_SRCLKEN_IN1_HW_MODE_ADDR \ + MT6685_TOP_CON +#define MT6685_RG_SRCLKEN_IN1_HW_MODE_MASK 0x1 +#define MT6685_RG_FQMTR_32K_CK_PDN_ADDR \ + MT6685_TOP_CKPDN_CON0 +#define MT6685_RG_FQMTR_32K_CK_PDN_MASK 0x1 +#define MT6685_RG_FQMTR_32K_CK_PDN_SHIFT 4 + #define MT6685_RG_SRCLKEN_IN1_HW_MODE_SHIFT 2 +#define MT6685_RG_FQMTR_CK_PDN_ADDR \ + MT6685_TOP_CKPDN_CON0 +#define MT6685_RG_FQMTR_CK_PDN_MASK 0x1 +#define MT6685_RG_FQMTR_CK_PDN_SHIFT 5 +#define MT6685_RG_INTRP_CK_PDN_ADDR \ + MT6685_TOP_CKPDN_CON0 +#define MT6685_RG_INTRP_CK_PDN_MASK 0x1 +#define MT6685_RG_INTRP_CK_PDN_SHIFT 6 +#define MT6685_TOP_CKPDN_CON0_SET_ADDR \ + MT6685_TOP_CKPDN_CON0_SET +#define MT6685_TOP_CKPDN_CON0_SET_MASK 0xFF +#define MT6685_TOP_CKPDN_CON0_SET_SHIFT 0 +#define MT6685_TOP_CKPDN_CON0_CLR_ADDR \ + MT6685_TOP_CKPDN_CON0_CLR +#define MT6685_TOP_CKPDN_CON0_CLR_MASK 0xFF +#define MT6685_TOP_CKPDN_CON0_CLR_SHIFT 0 +#define MT6685_RG_FQMTR_CK_CKSEL_ADDR \ + MT6685_TOP_CKSEL_CON0 +#define MT6685_RG_FQMTR_CK_CKSEL_MASK 0x7 +#define MT6685_RG_FQMTR_CK_CKSEL_SHIFT 0 +#define MT6685_RG_PMU32K_CK_CKSEL_ADDR \ + MT6685_TOP_CKSEL_CON0 +#define MT6685_RG_PMU32K_CK_CKSEL_MASK 0x1 +#define MT6685_RG_PMU32K_CK_CKSEL_SHIFT 3 +#define MT6685_TOP_CKSEL_CON0_SET_ADDR \ + MT6685_TOP_CKSEL_CON0_SET +#define MT6685_TOP_CKSEL_CON0_SET_MASK 0xFF +#define MT6685_TOP_CKSEL_CON0_SET_SHIFT 0 +#define MT6685_TOP_CKSEL_CON0_CLR_ADDR \ + MT6685_TOP_CKSEL_CON0_CLR +#define MT6685_TOP_CKSEL_CON0_CLR_MASK 0xFF +#define MT6685_TOP_CKSEL_CON0_CLR_SHIFT 0 +#define MT6685_DIG_WPK_KEY_ADDR \ + MT6685_TOP_DIG_WPK +#define MT6685_DIG_WPK_KEY_MASK 0xFF +#define MT6685_DIG_WPK_KEY_SHIFT 0 +#define MT6685_DIG_WPK_KEY_H_ADDR \ + MT6685_TOP_DIG_WPK_H +#define MT6685_DIG_WPK_KEY_H_MASK 0xFF +#define MT6685_DIG_WPK_KEY_H_SHIFT 0 +#define MT6685_SCK_TOP_XTAL_SEL_ADDR \ + MT6685_SCK_TOP_CON0_L +#define MT6685_SCK_TOP_XTAL_SEL_MASK 0x1 +#define MT6685_SCK_TOP_XTAL_SEL_SHIFT 0 +#define MT6685_RG_RTC_SEC_MCLK_PDN_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L +#define MT6685_RG_RTC_SEC_MCLK_PDN_MASK 0x1 +#define MT6685_RG_RTC_SEC_MCLK_PDN_SHIFT 0 +#define MT6685_RG_RTC_EOSC32_CK_PDN_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L +#define MT6685_RG_RTC_EOSC32_CK_PDN_MASK 0x1 +#define MT6685_RG_RTC_EOSC32_CK_PDN_SHIFT 2 +#define MT6685_RG_RTC_SEC_32K_CK_PDN_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L +#define MT6685_RG_RTC_SEC_32K_CK_PDN_MASK 0x1 +#define MT6685_RG_RTC_SEC_32K_CK_PDN_SHIFT 3 +#define MT6685_RG_RTC_MCLK_PDN_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L +#define MT6685_RG_RTC_MCLK_PDN_MASK 0x1 +#define MT6685_RG_RTC_MCLK_PDN_SHIFT 4 +#define MT6685_RG_RTC_32K_CK_PDN_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L +#define MT6685_RG_RTC_32K_CK_PDN_MASK 0x1 +#define MT6685_RG_RTC_32K_CK_PDN_SHIFT 5 +#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L_SET +#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_MASK 0xFF +#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_SHIFT 0 +#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_ADDR \ + MT6685_SCK_TOP_CKPDN_CON0_L_CLR +#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_MASK 0xFF +#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_SHIFT 0 +#define MT6685_RG_BANK_FQMTR_RST_ADDR \ + MT6685_SCK_TOP_RST_CON0 +#define MT6685_RG_BANK_FQMTR_RST_MASK 0x1 +#define MT6685_RG_BANK_FQMTR_RST_SHIFT 6 +#define MT6685_RG_RTC_DIG_TEST_MODE_ADDR \ + MT6685_RTC_DIG_CON0_H +#define MT6685_RG_RTC_DIG_TEST_MODE_MASK 0x1 +#define MT6685_RG_RTC_DIG_TEST_MODE_SHIFT 7 +#define MT6685_FQMTR_TCKSEL_ADDR \ + MT6685_FQMTR_CON0_L +#define MT6685_FQMTR_TCKSEL_MASK 0x7 +#define MT6685_FQMTR_TCKSEL_SHIFT 0 +#define MT6685_FQMTR_BUSY_ADDR \ + MT6685_FQMTR_CON0_L +#define MT6685_FQMTR_BUSY_MASK 0x1 +#define MT6685_FQMTR_BUSY_SHIFT 3 +#define MT6685_FQMTR_DCXO26M_EN_ADDR \ + MT6685_FQMTR_CON0_L +#define MT6685_FQMTR_DCXO26M_EN_MASK 0x1 +#define MT6685_FQMTR_DCXO26M_EN_SHIFT 4 +#define MT6685_FQMTR_EN_ADDR \ + MT6685_FQMTR_CON0_H +#define MT6685_FQMTR_EN_MASK 0x1 +#define MT6685_FQMTR_EN_SHIFT 7 +#define MT6685_FQMTR_WINSET_L_ADDR \ + MT6685_FQMTR_CON1_L +#define MT6685_FQMTR_WINSET_L_MASK 0xFF +#define MT6685_FQMTR_WINSET_L_SHIFT 0 +#define MT6685_FQMTR_WINSET_H_ADDR \ + MT6685_FQMTR_CON1_H +#define MT6685_FQMTR_WINSET_H_MASK 0xFF +#define MT6685_FQMTR_WINSET_H_SHIFT 0 +#define MT6685_FQMTR_DATA_L_ADDR \ + MT6685_FQMTR_CON2_L +#define MT6685_FQMTR_DATA_L_MASK 0xFF +#define MT6685_FQMTR_DATA_L_SHIFT 0 +#define MT6685_RG_RTC_32K1V8_0_SEL_ADDR \ + MT6685_SCK_TOP_CKSEL_CON +#define MT6685_RG_RTC_32K1V8_0_SEL_MASK 0x3 +#define MT6685_RG_RTC_32K1V8_0_SEL_SHIFT 0 +#define MT6685_SPAR_SW_RELOAD_ADDR \ + MT6685_RTC_SPAR_RELOAD +#define MT6685_SPAR_SW_RELOAD_MASK 0x1 +#define MT6685_SPAR_SW_RELOAD_SHIFT 0 +#define MT6685_RTC_ANA_ID_ADDR \ + MT6685_RTC_ANA_ID +#define MT6685_RTC_ANA_ID_MASK 0xFF +#define MT6685_RTC_ANA_ID_SHIFT 0 +#define MT6685_RTC_DIG_ID_ADDR \ + MT6685_RTC_DIG_ID +#define MT6685_RTC_DIG_ID_MASK 0xFF +#define MT6685_RTC_DIG_ID_SHIFT 0 +#define MT6685_RTC_ANA_MINOR_REV_ADDR \ + MT6685_RTC_ANA_REV +#define MT6685_RTC_ANA_MINOR_REV_MASK 0xF +#define MT6685_RTC_ANA_MINOR_REV_SHIFT 0 +#define MT6685_RTC_ANA_MAJOR_REV_ADDR \ + MT6685_RTC_ANA_REV +#define MT6685_RTC_ANA_MAJOR_REV_MASK 0xF +#define MT6685_RTC_ANA_MAJOR_REV_SHIFT 4 +#define MT6685_RTC_DIG_MINOR_REV_ADDR \ + MT6685_RTC_DIG_REV +#define MT6685_RTC_DIG_MINOR_REV_MASK 0xF +#define MT6685_RTC_DIG_MINOR_REV_SHIFT 0 +#define MT6685_RTC_DIG_MAJOR_REV_ADDR \ + MT6685_RTC_DIG_REV +#define MT6685_RTC_DIG_MAJOR_REV_MASK 0xF +#define MT6685_RTC_DIG_MAJOR_REV_SHIFT 4 +#define MT6685_RTC_CBS_ADDR \ + MT6685_RTC_DBI +#define MT6685_RTC_CBS_MASK 0x3 +#define MT6685_RTC_CBS_SHIFT 0 +#define MT6685_RTC_BIX_ADDR \ + MT6685_RTC_DBI +#define MT6685_RTC_BIX_MASK 0x3 +#define MT6685_RTC_BIX_SHIFT 2 +#define MT6685_RTC_ESP_ADDR \ + MT6685_RTC_ESP +#define MT6685_RTC_ESP_MASK 0xFF +#define MT6685_RTC_ESP_SHIFT 0 +#define MT6685_RTC_FPI_ADDR \ + MT6685_RTC_FPI +#define MT6685_RTC_FPI_MASK 0xFF +#define MT6685_RTC_FPI_SHIFT 0 +#define MT6685_RTC_DXI_ADDR \ + MT6685_RTC_DXI +#define MT6685_RTC_DXI_MASK 0xFF +#define MT6685_RTC_DXI_SHIFT 0 +#define MT6685_BBPU_ADDR \ + MT6685_RTC_BBPU_L +#define MT6685_BBPU_MASK 0xF +#define MT6685_BBPU_SHIFT 0 +#define MT6685_CLRPKY_ADDR \ + MT6685_RTC_BBPU_L +#define MT6685_CLRPKY_MASK 0x1 +#define MT6685_CLRPKY_SHIFT 4 +#define MT6685_RELOAD_ADDR \ + MT6685_RTC_BBPU_L +#define MT6685_RELOAD_MASK 0x1 +#define MT6685_RELOAD_SHIFT 5 +#define MT6685_CBUSY_ADDR \ + MT6685_RTC_BBPU_L +#define MT6685_CBUSY_MASK 0x1 +#define MT6685_CBUSY_SHIFT 6 +#define MT6685_ALARM_STATUS_ADDR \ + MT6685_RTC_BBPU_L +#define MT6685_ALARM_STATUS_MASK 0x1 +#define MT6685_ALARM_STATUS_SHIFT 7 +#define MT6685_KEY_BBPU_ADDR \ + MT6685_RTC_BBPU_H +#define MT6685_KEY_BBPU_MASK 0xFF +#define MT6685_KEY_BBPU_SHIFT 0 +#define MT6685_ALSTA_ADDR \ + MT6685_RTC_IRQ_STA +#define MT6685_ALSTA_MASK 0x1 +#define MT6685_ALSTA_SHIFT 0 +#define MT6685_TCSTA_ADDR \ + MT6685_RTC_IRQ_STA +#define MT6685_TCSTA_MASK 0x1 +#define MT6685_TCSTA_SHIFT 1 +#define MT6685_LPSTA_ADDR \ + MT6685_RTC_IRQ_STA +#define MT6685_LPSTA_MASK 0x1 +#define MT6685_LPSTA_SHIFT 3 +#define MT6685_AL_EN_ADDR \ + MT6685_RTC_IRQ_EN +#define MT6685_AL_EN_MASK 0x1 +#define MT6685_AL_EN_SHIFT 0 +#define MT6685_TC_EN_ADDR \ + MT6685_RTC_IRQ_EN +#define MT6685_TC_EN_MASK 0x1 +#define MT6685_TC_EN_SHIFT 1 +#define MT6685_ONESHOT_ADDR \ + MT6685_RTC_IRQ_EN +#define MT6685_ONESHOT_MASK 0x1 +#define MT6685_ONESHOT_SHIFT 2 +#define MT6685_LP_EN_ADDR \ + MT6685_RTC_IRQ_EN +#define MT6685_LP_EN_MASK 0x1 +#define MT6685_LP_EN_SHIFT 3 +#define MT6685_SECCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_SECCII_MASK 0x1 +#define MT6685_SECCII_SHIFT 0 +#define MT6685_MINCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_MINCII_MASK 0x1 +#define MT6685_MINCII_SHIFT 1 +#define MT6685_HOUCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_HOUCII_MASK 0x1 +#define MT6685_HOUCII_SHIFT 2 +#define MT6685_DOMCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_DOMCII_MASK 0x1 +#define MT6685_DOMCII_SHIFT 3 +#define MT6685_DOWCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_DOWCII_MASK 0x1 +#define MT6685_DOWCII_SHIFT 4 +#define MT6685_MTHCII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_MTHCII_MASK 0x1 +#define MT6685_MTHCII_SHIFT 5 +#define MT6685_YEACII_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_YEACII_MASK 0x1 +#define MT6685_YEACII_SHIFT 6 +#define MT6685_SECCII_1_2_ADDR \ + MT6685_RTC_CII_EN_L +#define MT6685_SECCII_1_2_MASK 0x1 +#define MT6685_SECCII_1_2_SHIFT 7 +#define MT6685_SECCII_1_4_ADDR \ + MT6685_RTC_CII_EN_H +#define MT6685_SECCII_1_4_MASK 0x1 +#define MT6685_SECCII_1_4_SHIFT 0 +#define MT6685_SECCII_1_8_ADDR \ + MT6685_RTC_CII_EN_H +#define MT6685_SECCII_1_8_MASK 0x1 +#define MT6685_SECCII_1_8_SHIFT 1 +#define MT6685_SEC_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_SEC_MSK_MASK 0x1 +#define MT6685_SEC_MSK_SHIFT 0 +#define MT6685_MIN_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_MIN_MSK_MASK 0x1 +#define MT6685_MIN_MSK_SHIFT 1 +#define MT6685_HOU_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_HOU_MSK_MASK 0x1 +#define MT6685_HOU_MSK_SHIFT 2 +#define MT6685_DOM_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_DOM_MSK_MASK 0x1 +#define MT6685_DOM_MSK_SHIFT 3 +#define MT6685_DOW_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_DOW_MSK_MASK 0x1 +#define MT6685_DOW_MSK_SHIFT 4 +#define MT6685_MTH_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_MTH_MSK_MASK 0x1 +#define MT6685_MTH_MSK_SHIFT 5 +#define MT6685_YEA_MSK_ADDR \ + MT6685_RTC_AL_MASK +#define MT6685_YEA_MSK_MASK 0x1 +#define MT6685_YEA_MSK_SHIFT 6 +#define MT6685_TC_SECOND_ADDR \ + MT6685_RTC_TC_SEC +#define MT6685_TC_SECOND_MASK 0x3F +#define MT6685_TC_SECOND_SHIFT 0 +#define MT6685_TC_MINUTE_ADDR \ + MT6685_RTC_TC_MIN +#define MT6685_TC_MINUTE_MASK 0x3F +#define MT6685_TC_MINUTE_SHIFT 0 +#define MT6685_TC_HOUR_ADDR \ + MT6685_RTC_TC_HOU +#define MT6685_TC_HOUR_MASK 0x1F +#define MT6685_TC_HOUR_SHIFT 0 +#define MT6685_TC_DOM_ADDR \ + MT6685_RTC_TC_DOM +#define MT6685_TC_DOM_MASK 0x1F +#define MT6685_TC_DOM_SHIFT 0 +#define MT6685_TC_DOW_ADDR \ + MT6685_RTC_TC_DOW +#define MT6685_TC_DOW_MASK 0x7 +#define MT6685_TC_DOW_SHIFT 0 +#define MT6685_TC_MONTH_ADDR \ + MT6685_RTC_TC_MTH_L +#define MT6685_TC_MONTH_MASK 0xF +#define MT6685_TC_MONTH_SHIFT 0 +#define MT6685_RTC_MACRO_ID_L_ADDR \ + MT6685_RTC_TC_MTH_L +#define MT6685_RTC_MACRO_ID_L_MASK 0xF +#define MT6685_RTC_MACRO_ID_L_SHIFT 4 +#define MT6685_RTC_MACRO_ID_H_ADDR \ + MT6685_RTC_TC_MTH_H +#define MT6685_RTC_MACRO_ID_H_MASK 0xFF +#define MT6685_RTC_MACRO_ID_H_SHIFT 0 +#define MT6685_TC_YEAR_ADDR \ + MT6685_RTC_TC_YEA +#define MT6685_TC_YEAR_MASK 0x7F +#define MT6685_TC_YEAR_SHIFT 0 +#define MT6685_AL_SECOND_ADDR \ + MT6685_RTC_AL_SEC_L +#define MT6685_AL_SECOND_MASK 0x3F +#define MT6685_AL_SECOND_SHIFT 0 +#define MT6685_BBPU_AUTO_PDN_SEL_ADDR \ + MT6685_RTC_AL_SEC_L +#define MT6685_BBPU_AUTO_PDN_SEL_MASK 0x1 +#define MT6685_BBPU_AUTO_PDN_SEL_SHIFT 6 +#define MT6685_BBPU_2SEC_CK_SEL_ADDR \ + MT6685_RTC_AL_SEC_L +#define MT6685_BBPU_2SEC_CK_SEL_MASK 0x1 +#define MT6685_BBPU_2SEC_CK_SEL_SHIFT 7 +#define MT6685_BBPU_2SEC_EN_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_BBPU_2SEC_EN_MASK 0x1 +#define MT6685_BBPU_2SEC_EN_SHIFT 0 +#define MT6685_BBPU_2SEC_MODE_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_BBPU_2SEC_MODE_MASK 0x3 +#define MT6685_BBPU_2SEC_MODE_SHIFT 1 +#define MT6685_BBPU_2SEC_STAT_CLEAR_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_BBPU_2SEC_STAT_CLEAR_MASK 0x1 +#define MT6685_BBPU_2SEC_STAT_CLEAR_SHIFT 3 +#define MT6685_BBPU_2SEC_STAT_STA_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_BBPU_2SEC_STAT_STA_MASK 0x1 +#define MT6685_BBPU_2SEC_STAT_STA_SHIFT 4 +#define MT6685_RTC_LPD_OPT_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_RTC_LPD_OPT_MASK 0x3 +#define MT6685_RTC_LPD_OPT_SHIFT 5 +#define MT6685_K_EOSC32_VTCXO_ON_SEL_ADDR \ + MT6685_RTC_AL_SEC_H +#define MT6685_K_EOSC32_VTCXO_ON_SEL_MASK 0x1 +#define MT6685_K_EOSC32_VTCXO_ON_SEL_SHIFT 7 +#define MT6685_AL_MINUTE_ADDR \ + MT6685_RTC_AL_MIN +#define MT6685_AL_MINUTE_MASK 0x3F +#define MT6685_AL_MINUTE_SHIFT 0 +#define MT6685_AL_HOUR_ADDR \ + MT6685_RTC_AL_HOU_L +#define MT6685_AL_HOUR_MASK 0x1F +#define MT6685_AL_HOUR_SHIFT 0 +#define MT6685_NEW_SPARE0_ADDR \ + MT6685_RTC_AL_HOU_H +#define MT6685_NEW_SPARE0_MASK 0xFF +#define MT6685_NEW_SPARE0_SHIFT 0 +#define MT6685_AL_DOM_ADDR \ + MT6685_RTC_AL_DOM_L +#define MT6685_AL_DOM_MASK 0x1F +#define MT6685_AL_DOM_SHIFT 0 +#define MT6685_NEW_SPARE1_ADDR \ + MT6685_RTC_AL_DOM_H +#define MT6685_NEW_SPARE1_MASK 0xFF +#define MT6685_NEW_SPARE1_SHIFT 0 +#define MT6685_AL_DOW_ADDR \ + MT6685_RTC_AL_DOW_L +#define MT6685_AL_DOW_MASK 0x7 +#define MT6685_AL_DOW_SHIFT 0 +#define MT6685_RG_EOSC_CALI_TD_ADDR \ + MT6685_RTC_AL_DOW_L +#define MT6685_RG_EOSC_CALI_TD_MASK 0x7 +#define MT6685_RG_EOSC_CALI_TD_SHIFT 5 +#define MT6685_NEW_SPARE2_ADDR \ + MT6685_RTC_AL_DOW_H +#define MT6685_NEW_SPARE2_MASK 0xFF +#define MT6685_NEW_SPARE2_SHIFT 0 +#define MT6685_AL_MONTH_ADDR \ + MT6685_RTC_AL_MTH_L +#define MT6685_AL_MONTH_MASK 0xF +#define MT6685_AL_MONTH_SHIFT 0 +#define MT6685_NEW_SPARE3_ADDR \ + MT6685_RTC_AL_MTH_H +#define MT6685_NEW_SPARE3_MASK 0xFF +#define MT6685_NEW_SPARE3_SHIFT 0 +#define MT6685_AL_YEAR_ADDR \ + MT6685_RTC_AL_YEA_L +#define MT6685_AL_YEAR_MASK 0x7F +#define MT6685_AL_YEAR_SHIFT 0 +#define MT6685_RTC_K_EOSC_RSV_ADDR \ + MT6685_RTC_AL_YEA_H +#define MT6685_RTC_K_EOSC_RSV_MASK 0xFF +#define MT6685_RTC_K_EOSC_RSV_SHIFT 0 +#define MT6685_XOSCCALI_ADDR \ + MT6685_RTC_OSC32CON_L +#define MT6685_XOSCCALI_MASK 0x1F +#define MT6685_XOSCCALI_SHIFT 0 +#define MT6685_RTC_XOSC32_ENB_ADDR \ + MT6685_RTC_OSC32CON_L +#define MT6685_RTC_XOSC32_ENB_MASK 0x1 +#define MT6685_RTC_XOSC32_ENB_SHIFT 5 +#define MT6685_RTC_EMBCK_SEL_MODE_ADDR \ + MT6685_RTC_OSC32CON_L +#define MT6685_RTC_EMBCK_SEL_MODE_MASK 0x3 +#define MT6685_RTC_EMBCK_SEL_MODE_SHIFT 6 +#define MT6685_RTC_EMBCK_SRC_SEL_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_EMBCK_SRC_SEL_MASK 0x1 +#define MT6685_RTC_EMBCK_SRC_SEL_SHIFT 0 +#define MT6685_RTC_EMBCK_SEL_OPTION_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_EMBCK_SEL_OPTION_MASK 0x1 +#define MT6685_RTC_EMBCK_SEL_OPTION_SHIFT 1 +#define MT6685_RTC_GPS_CKOUT_EN_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_GPS_CKOUT_EN_MASK 0x1 +#define MT6685_RTC_GPS_CKOUT_EN_SHIFT 2 +#define MT6685_RTC_EOSC32_VCT_EN_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_EOSC32_VCT_EN_MASK 0x1 +#define MT6685_RTC_EOSC32_VCT_EN_SHIFT 3 +#define MT6685_RTC_EOSC32_CHOP_EN_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_EOSC32_CHOP_EN_MASK 0x1 +#define MT6685_RTC_EOSC32_CHOP_EN_SHIFT 4 +#define MT6685_RTC_GP_OSC32_CON_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_GP_OSC32_CON_MASK 0x3 +#define MT6685_RTC_GP_OSC32_CON_SHIFT 5 +#define MT6685_RTC_REG_XOSC32_ENB_ADDR \ + MT6685_RTC_OSC32CON_H +#define MT6685_RTC_REG_XOSC32_ENB_MASK 0x1 +#define MT6685_RTC_REG_XOSC32_ENB_SHIFT 7 +#define MT6685_RTC_POWERKEY1_L_ADDR \ + MT6685_RTC_POWERKEY1_L +#define MT6685_RTC_POWERKEY1_L_MASK 0xFF +#define MT6685_RTC_POWERKEY1_L_SHIFT 0 +#define MT6685_RTC_POWERKEY1_H_ADDR \ + MT6685_RTC_POWERKEY1_H +#define MT6685_RTC_POWERKEY1_H_MASK 0xFF +#define MT6685_RTC_POWERKEY1_H_SHIFT 0 +#define MT6685_RTC_POWERKEY2_L_ADDR \ + MT6685_RTC_POWERKEY2_L +#define MT6685_RTC_POWERKEY2_L_MASK 0xFF +#define MT6685_RTC_POWERKEY2_L_SHIFT 0 +#define MT6685_RTC_POWERKEY2_H_ADDR \ + MT6685_RTC_POWERKEY2_H +#define MT6685_RTC_POWERKEY2_H_MASK 0xFF +#define MT6685_RTC_POWERKEY2_H_SHIFT 0 +#define MT6685_RTC_PDN1_L_ADDR \ + MT6685_RTC_PDN1_L +#define MT6685_RTC_PDN1_L_MASK 0xFF +#define MT6685_RTC_PDN1_L_SHIFT 0 +#define MT6685_RTC_PDN1_H_ADDR \ + MT6685_RTC_PDN1_H +#define MT6685_RTC_PDN1_H_MASK 0xFF +#define MT6685_RTC_PDN1_H_SHIFT 0 +#define MT6685_RTC_PDN2_L_ADDR \ + MT6685_RTC_PDN2_L +#define MT6685_RTC_PDN2_L_MASK 0xFF +#define MT6685_RTC_PDN2_L_SHIFT 0 +#define MT6685_RTC_PDN2_H_ADDR \ + MT6685_RTC_PDN2_H +#define MT6685_RTC_PDN2_H_MASK 0xFF +#define MT6685_RTC_PDN2_H_SHIFT 0 +#define MT6685_RTC_SPAR0_L_ADDR \ + MT6685_RTC_SPAR0_L +#define MT6685_RTC_SPAR0_L_MASK 0xFF +#define MT6685_RTC_SPAR0_L_SHIFT 0 +#define MT6685_RTC_SPAR0_H_ADDR \ + MT6685_RTC_SPAR0_H +#define MT6685_RTC_SPAR0_H_MASK 0xFF +#define MT6685_RTC_SPAR0_H_SHIFT 0 +#define MT6685_RTC_SPAR1_L_ADDR \ + MT6685_RTC_SPAR1_L +#define MT6685_RTC_SPAR1_L_MASK 0xFF +#define MT6685_RTC_SPAR1_L_SHIFT 0 +#define MT6685_RTC_SPAR1_H_ADDR \ + MT6685_RTC_SPAR1_H +#define MT6685_RTC_SPAR1_H_MASK 0xFF +#define MT6685_RTC_SPAR1_H_SHIFT 0 +#define MT6685_RTC_PROT_L_ADDR \ + MT6685_RTC_PROT_L +#define MT6685_RTC_PROT_L_MASK 0xFF +#define MT6685_RTC_PROT_L_SHIFT 0 +#define MT6685_RTC_PROT_H_ADDR \ + MT6685_RTC_PROT_H +#define MT6685_RTC_PROT_H_MASK 0xFF +#define MT6685_RTC_PROT_H_SHIFT 0 +#define MT6685_RTC_DIFF_L_ADDR \ + MT6685_RTC_DIFF_L +#define MT6685_RTC_DIFF_L_MASK 0xFF +#define MT6685_RTC_DIFF_L_SHIFT 0 +#define MT6685_RTC_DIFF_H_ADDR \ + MT6685_RTC_DIFF_H +#define MT6685_RTC_DIFF_H_MASK 0xF +#define MT6685_RTC_DIFF_H_SHIFT 0 +#define MT6685_POWER_DETECTED_ADDR \ + MT6685_RTC_DIFF_H +#define MT6685_POWER_DETECTED_MASK 0x1 +#define MT6685_POWER_DETECTED_SHIFT 4 +#define MT6685_K_EOSC32_RSV_ADDR \ + MT6685_RTC_DIFF_H +#define MT6685_K_EOSC32_RSV_MASK 0x1 +#define MT6685_K_EOSC32_RSV_SHIFT 6 +#define MT6685_CALI_RD_SEL_ADDR \ + MT6685_RTC_DIFF_H +#define MT6685_CALI_RD_SEL_MASK 0x1 +#define MT6685_CALI_RD_SEL_SHIFT 7 +#define MT6685_RTC_CALI_L_ADDR \ + MT6685_RTC_CALI_L +#define MT6685_RTC_CALI_L_MASK 0xFF +#define MT6685_RTC_CALI_L_SHIFT 0 +#define MT6685_RTC_CALI_H_ADDR \ + MT6685_RTC_CALI_H +#define MT6685_RTC_CALI_H_MASK 0x3F +#define MT6685_RTC_CALI_H_SHIFT 0 +#define MT6685_CALI_WR_SEL_ADDR \ + MT6685_RTC_CALI_H +#define MT6685_CALI_WR_SEL_MASK 0x1 +#define MT6685_CALI_WR_SEL_SHIFT 6 +#define MT6685_K_EOSC32_OVERFLOW_ADDR \ + MT6685_RTC_CALI_H +#define MT6685_K_EOSC32_OVERFLOW_MASK 0x1 +#define MT6685_K_EOSC32_OVERFLOW_SHIFT 7 +#define MT6685_WRTGR_ADDR \ + MT6685_RTC_WRTGR +#define MT6685_WRTGR_MASK 0x1 +#define MT6685_WRTGR_SHIFT 0 +#define MT6685_VBAT_LPSTA_RAW_ADDR \ + MT6685_RTC_CON_L +#define MT6685_VBAT_LPSTA_RAW_MASK 0x1 +#define MT6685_VBAT_LPSTA_RAW_SHIFT 0 +#define MT6685_EOSC32_LPEN_ADDR \ + MT6685_RTC_CON_L +#define MT6685_EOSC32_LPEN_MASK 0x1 +#define MT6685_EOSC32_LPEN_SHIFT 1 +#define MT6685_XOSC32_LPEN_ADDR \ + MT6685_RTC_CON_L +#define MT6685_XOSC32_LPEN_MASK 0x1 +#define MT6685_XOSC32_LPEN_SHIFT 2 +#define MT6685_LPRST_ADDR \ + MT6685_RTC_CON_L +#define MT6685_LPRST_MASK 0x1 +#define MT6685_LPRST_SHIFT 3 +#define MT6685_CDBO_ADDR \ + MT6685_RTC_CON_L +#define MT6685_CDBO_MASK 0x1 +#define MT6685_CDBO_SHIFT 4 +#define MT6685_F32KOB_ADDR \ + MT6685_RTC_CON_L +#define MT6685_F32KOB_MASK 0x1 +#define MT6685_F32KOB_SHIFT 5 +#define MT6685_GPO_ADDR \ + MT6685_RTC_CON_L +#define MT6685_GPO_MASK 0x1 +#define MT6685_GPO_SHIFT 6 +#define MT6685_GOE_ADDR \ + MT6685_RTC_CON_L +#define MT6685_GOE_MASK 0x1 +#define MT6685_GOE_SHIFT 7 +#define MT6685_GSR_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GSR_MASK 0x1 +#define MT6685_GSR_SHIFT 0 +#define MT6685_GSMT_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GSMT_MASK 0x1 +#define MT6685_GSMT_SHIFT 1 +#define MT6685_GPEN_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GPEN_MASK 0x1 +#define MT6685_GPEN_SHIFT 2 +#define MT6685_GPU_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GPU_MASK 0x1 +#define MT6685_GPU_SHIFT 3 +#define MT6685_GE4_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GE4_MASK 0x1 +#define MT6685_GE4_SHIFT 4 +#define MT6685_GE8_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GE8_MASK 0x1 +#define MT6685_GE8_SHIFT 5 +#define MT6685_GPI_ADDR \ + MT6685_RTC_CON_H +#define MT6685_GPI_MASK 0x1 +#define MT6685_GPI_SHIFT 6 +#define MT6685_LPSTA_RAW_ADDR \ + MT6685_RTC_CON_H +#define MT6685_LPSTA_RAW_MASK 0x1 +#define MT6685_LPSTA_RAW_SHIFT 7 +#define MT6685_DAT0_LOCK_ADDR \ + MT6685_RTC_SEC_CTRL +#define MT6685_DAT0_LOCK_MASK 0x1 +#define MT6685_DAT0_LOCK_SHIFT 0 +#define MT6685_DAT1_LOCK_ADDR \ + MT6685_RTC_SEC_CTRL +#define MT6685_DAT1_LOCK_MASK 0x1 +#define MT6685_DAT1_LOCK_SHIFT 1 +#define MT6685_DAT2_LOCK_ADDR \ + MT6685_RTC_SEC_CTRL +#define MT6685_DAT2_LOCK_MASK 0x1 +#define MT6685_DAT2_LOCK_SHIFT 2 +#define MT6685_RTC_INT_CNT_L_ADDR \ + MT6685_RTC_INT_CNT_L +#define MT6685_RTC_INT_CNT_L_MASK 0xFF +#define MT6685_RTC_INT_CNT_L_SHIFT 0 +#define MT6685_RTC_INT_CNT_H_ADDR \ + MT6685_RTC_INT_CNT_H +#define MT6685_RTC_INT_CNT_H_MASK 0x7F +#define MT6685_RTC_INT_CNT_H_SHIFT 0 +#define MT6685_RTC_SEC_DAT0_L_ADDR \ + MT6685_RTC_SEC_DAT0_L +#define MT6685_RTC_SEC_DAT0_L_MASK 0xFF +#define MT6685_RTC_SEC_DAT0_L_SHIFT 0 +#define MT6685_RTC_SEC_DAT0_H_ADDR \ + MT6685_RTC_SEC_DAT0_H +#define MT6685_RTC_SEC_DAT0_H_MASK 0xFF +#define MT6685_RTC_SEC_DAT0_H_SHIFT 0 +#define MT6685_RTC_SEC_DAT1_L_ADDR \ + MT6685_RTC_SEC_DAT1_L +#define MT6685_RTC_SEC_DAT1_L_MASK 0xFF +#define MT6685_RTC_SEC_DAT1_L_SHIFT 0 +#define MT6685_RTC_SEC_DAT1_H_ADDR \ + MT6685_RTC_SEC_DAT1_H +#define MT6685_RTC_SEC_DAT1_H_MASK 0xFF +#define MT6685_RTC_SEC_DAT1_H_SHIFT 0 +#define MT6685_RTC_SEC_DAT2_L_ADDR \ + MT6685_RTC_SEC_DAT2_L +#define MT6685_RTC_SEC_DAT2_L_MASK 0xFF +#define MT6685_RTC_SEC_DAT2_L_SHIFT 0 +#define MT6685_RTC_SEC_DAT2_H_ADDR \ + MT6685_RTC_SEC_DAT2_H +#define MT6685_RTC_SEC_DAT2_H_MASK 0xFF +#define MT6685_RTC_SEC_DAT2_H_SHIFT 0 +#define MT6685_RTC_RG_FG0_ADDR \ + MT6685_RTC_RG_FG0 +#define MT6685_RTC_RG_FG0_MASK 0xFF +#define MT6685_RTC_RG_FG0_SHIFT 0 +#define MT6685_RTC_RG_FG1_ADDR \ + MT6685_RTC_RG_FG1 +#define MT6685_RTC_RG_FG1_MASK 0xFF +#define MT6685_RTC_RG_FG1_SHIFT 0 +#define MT6685_RTC_RG_FG2_ADDR \ + MT6685_RTC_RG_FG2 +#define MT6685_RTC_RG_FG2_MASK 0xFF +#define MT6685_RTC_RG_FG2_SHIFT 0 +#define MT6685_RTC_RG_FG3_ADDR \ + MT6685_RTC_RG_FG3 +#define MT6685_RTC_RG_FG3_MASK 0xFF +#define MT6685_RTC_RG_FG3_SHIFT 0 +#define MT6685_RTC_UVLO_WAIT_ADDR \ + MT6685_RTC_SPAR_MACRO +#define MT6685_RTC_UVLO_WAIT_MASK 0x3 +#define MT6685_RTC_UVLO_WAIT_SHIFT 0 +#define MT6685_RTC_SPAR_THRE_SEL_ADDR \ + MT6685_RTC_SPAR_MACRO +#define MT6685_RTC_SPAR_THRE_SEL_MASK 0x1 +#define MT6685_RTC_SPAR_THRE_SEL_SHIFT 2 +#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_ADDR \ + MT6685_RTC_SPAR_MACRO +#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_MASK 0x1 +#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_SHIFT 4 +#define MT6685_RTC_SPAR_PWRKEY_MATCH_ADDR \ + MT6685_RTC_SPAR_MACRO +#define MT6685_RTC_SPAR_PWRKEY_MATCH_MASK 0x1 +#define MT6685_RTC_SPAR_PWRKEY_MATCH_SHIFT 5 +#define MT6685_SPAR_PROT_STAT_ADDR \ + MT6685_RTC_SPAR_MACRO +#define MT6685_RTC_SPAR_PROT_STAT_MASK 0x3 +#define MT6685_RTC_SPAR_PROT_STAT_SHIFT 6 +#define MT6685_RTC_SPAR_CORE_ADDR \ + MT6685_RTC_SPAR_CORE +#define MT6685_RTC_SPAR_CORE_MASK 0xFF +#define MT6685_RTC_SPAR_CORE_SHIFT 0 +#define MT6685_RTC_RG_EOSC_CALI_ADDR \ + MT6685_RTC_EOSC_CALI +#define MT6685_RTC_RG_EOSC_CALI_MASK 0x1F +#define MT6685_RTC_RG_EOSC_CALI_SHIFT 0 +#define MT6685_RTC_SEC_ANA_ID_ADDR \ + MT6685_RTC_SEC_ANA_ID +#define MT6685_RTC_SEC_ANA_ID_MASK 0xFF +#define MT6685_RTC_SEC_ANA_ID_SHIFT 0 +#define MT6685_RTC_SEC_DIG_ID_ADDR \ + MT6685_RTC_SEC_DIG_ID +#define MT6685_RTC_SEC_DIG_ID_MASK 0xFF +#define MT6685_RTC_SEC_DIG_ID_SHIFT 0 +#define MT6685_RTC_SEC_ANA_MINOR_REV_ADDR \ + MT6685_RTC_SEC_ANA_REV +#define MT6685_RTC_SEC_ANA_MINOR_REV_MASK 0xF +#define MT6685_RTC_SEC_ANA_MINOR_REV_SHIFT 0 +#define MT6685_RTC_SEC_ANA_MAJOR_REV_ADDR \ + MT6685_RTC_SEC_ANA_REV +#define MT6685_RTC_SEC_ANA_MAJOR_REV_MASK 0xF +#define MT6685_RTC_SEC_ANA_MAJOR_REV_SHIFT 4 +#define MT6685_RTC_SEC_DIG_MINOR_REV_ADDR \ + MT6685_RTC_SEC_DIG_REV +#define MT6685_RTC_SEC_DIG_MINOR_REV_MASK 0xF +#define MT6685_RTC_SEC_DIG_MINOR_REV_SHIFT 0 +#define MT6685_RTC_SEC_DIG_MAJOR_REV_ADDR \ + MT6685_RTC_SEC_DIG_REV +#define MT6685_RTC_SEC_DIG_MAJOR_REV_MASK 0xF +#define MT6685_RTC_SEC_DIG_MAJOR_REV_SHIFT 4 +#define MT6685_RTC_SEC_CBS_ADDR \ + MT6685_RTC_SEC_DBI +#define MT6685_RTC_SEC_CBS_MASK 0x3 +#define MT6685_RTC_SEC_CBS_SHIFT 0 +#define MT6685_RTC_SEC_BIX_ADDR \ + MT6685_RTC_SEC_DBI +#define MT6685_RTC_SEC_BIX_MASK 0x3 +#define MT6685_RTC_SEC_BIX_SHIFT 2 +#define MT6685_RTC_SEC_ESP_ADDR \ + MT6685_RTC_SEC_ESP +#define MT6685_RTC_SEC_ESP_MASK 0xFF +#define MT6685_RTC_SEC_ESP_SHIFT 0 +#define MT6685_RTC_SEC_FPI_ADDR \ + MT6685_RTC_SEC_FPI +#define MT6685_RTC_SEC_FPI_MASK 0xFF +#define MT6685_RTC_SEC_FPI_SHIFT 0 +#define MT6685_RTC_SEC_DXI_ADDR \ + MT6685_RTC_SEC_DXI +#define MT6685_RTC_SEC_DXI_MASK 0xFF +#define MT6685_RTC_SEC_DXI_SHIFT 0 +#define MT6685_TC_SECOND_SEC_ADDR \ + MT6685_RTC_TC_SEC_SEC +#define MT6685_TC_SECOND_SEC_MASK 0x3F +#define MT6685_TC_SECOND_SEC_SHIFT 0 +#define MT6685_TC_MINUTE_SEC_ADDR \ + MT6685_RTC_TC_MIN_SEC +#define MT6685_TC_MINUTE_SEC_MASK 0x3F +#define MT6685_TC_MINUTE_SEC_SHIFT 0 +#define MT6685_TC_HOUR_SEC_ADDR \ + MT6685_RTC_TC_HOU_SEC +#define MT6685_TC_HOUR_SEC_MASK 0x1F +#define MT6685_TC_HOUR_SEC_SHIFT 0 +#define MT6685_TC_DOM_SEC_ADDR \ + MT6685_RTC_TC_DOM_SEC +#define MT6685_TC_DOM_SEC_MASK 0x1F +#define MT6685_TC_DOM_SEC_SHIFT 0 +#define MT6685_TC_DOW_SEC_ADDR \ + MT6685_RTC_TC_DOW_SEC +#define MT6685_TC_DOW_SEC_MASK 0x7 +#define MT6685_TC_DOW_SEC_SHIFT 0 +#define MT6685_TC_MONTH_SEC_ADDR \ + MT6685_RTC_TC_MTH_SEC +#define MT6685_TC_MONTH_SEC_MASK 0xF +#define MT6685_TC_MONTH_SEC_SHIFT 0 +#define MT6685_TC_YEAR_SEC_ADDR \ + MT6685_RTC_TC_YEA_SEC +#define MT6685_TC_YEAR_SEC_MASK 0x7F +#define MT6685_TC_YEAR_SEC_SHIFT 0 +#define MT6685_RTC_SEC_CK_PDN_ADDR \ + MT6685_RTC_SEC_CK_PDN +#define MT6685_RTC_SEC_CK_PDN_MASK 0x1 +#define MT6685_RTC_SEC_CK_PDN_SHIFT 0 +#define MT6685_RTC_SEC_WRTGR_ADDR \ + MT6685_RTC_SEC_WRTGR +#define MT6685_RTC_SEC_WRTGR_MASK 0x1 +#define MT6685_RTC_SEC_WRTGR_SHIFT 0 +#define MT6685_XO_EN32K_MAN_ADDR \ + MT6685_DCXO_DIG_MODE_CW0 +#define MT6685_XO_EN32K_MAN_MASK 0x1 +#define MT6685_XO_EN32K_MAN_SHIFT 1 +#define MT6685_RG_INT_EN_RTC_ADDR \ + MT6685_SCK_TOP_INT_CON0 +#define MT6685_RG_INT_EN_RTC_MASK 0x1 +#define MT6685_RG_INT_EN_RTC_SHIFT 0 + +#endif /* _MT6685_HW_H_ */ diff --git a/include/linux/mfd/mt6685/rtc.h b/include/linux/mfd/mt6685/rtc.h new file mode 100644 index 0000000000000..17b32f66bdac2 --- /dev/null +++ b/include/linux/mfd/mt6685/rtc.h @@ -0,0 +1,300 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MT6685_RTC_H__ +#define __MT6685_RTC_H__ + +#include + +/* features */ + +#define HWID MT6685_HWCID_L + +#define RTC_TC_SEC 0x12 +#define RTC_TC_MIN 0x14 +#define RTC_TC_HOU 0x16 +#define RTC_TC_DOM 0x18 +#define RTC_TC_DOW 0x1A +#define RTC_TC_MTH 0x1C +#define RTC_TC_YEA 0x1E + +/* Min, Hour, Dom... register offset to RTC_TC_SEC */ +#define RTC_OFFSET_SEC 0 +#define RTC_OFFSET_MIN 1 +#define RTC_OFFSET_HOUR 2 +#define RTC_OFFSET_DOM 3 +#define RTC_OFFSET_DOW 4 +#define RTC_OFFSET_MTH 5 +#define RTC_OFFSET_YEAR 6 +#define RTC_OFFSET_COUNT 7 + +#define RTC_DSN_ID 0x580 + +#define DCXO_ANA_ID 0x200 + +#define RTC_BBPU 0x8 +#define RTC_WRTGR_MT6685 0x42 +#define RTC_IRQ_STA 0xa +#define RTC_IRQ_EN 0xc +#define RTC_AL_MASK 0x10 + +#define RTC_AL_SEC 0x20 +#define RTC_AL_MIN 0x22 +#define RTC_AL_HOU0x24 +#define RTC_AL_HOU_H 0x25 +#define RTC_AL_DOM 0x26 +#define RTC_AL_DOW 0x28 +#define RTC_AL_DOW_H 0x29 +#define RTC_AL_MTH 0x2a +#define RTC_AL_MTH_H 0x2b +#define RTC_AL_YEA 0x2c +#define RTC_AL_YEA_H 0x2d +#define RTC_OSC32CON 0x2e +#define RTC_POWERKEY10x30 +#define RTC_POWERKEY20x32 +#define RTC_PDN1 0x34 +#define RTC_PDN1_H 0x35 +#define RTC_PDN2 0x36 +#define RTC_SPAR0 0x38 +#define RTC_SPAR1 0x3a +#define RTC_PROT 0x3c +#define RTC_WRTGR 0x42 +#define RTC_CON 0x44 +#define RTC_INT_CNT_L0x48 +#define RTC_SPAR_MACRO 0x58 + +#define RTC_TC_SEC_MASK 0x3f +#define RTC_TC_MIN_MASK 0x3f +#define RTC_TC_HOU_MASK 0x1f +#define RTC_TC_DOM_MASK 0x1f +#define RTC_TC_DOW_MASK 0x7 +#define RTC_TC_MTH_MASK 0xf +#define RTC_TC_YEA_MASK 0x7f + +#define RTC_AL_SEC_MASK 0x3f +#define RTC_AL_MIN_MASK 0x3f +#define RTC_AL_HOU_MASK 0x1f +#define RTC_AL_DOM_MASK 0x1f +#define RTC_AL_DOW_MASK 0x7 +#define RTC_AL_MTH_MASK 0xf +#define RTC_AL_YEA_MASK 0x7f + +#define RTC_PWRON_YEA RTC_PDN2 +#define RTC_PWRON_MTH RTC_PDN2 +#define RTC_PWRON_SEC RTC_SPAR0 +#define RTC_PWRON_MIN RTC_SPAR1 +#define RTC_PWRON_HOU RTC_SPAR1 +#define RTC_PWRON_DOM RTC_SPAR1 + +#define RTC_PWRON_SEC_SHIFT 0x0 +#define RTC_PWRON_MIN_SHIFT 0x0 +#define RTC_PWRON_HOU_SHIFT 0x6 +#define RTC_PWRON_DOM_SHIFT 0xb +#define RTC_PWRON_MTH_SHIFT 0x0 +#define RTC_PWRON_YEA_SHIFT 0x8 + +#define RTC_PWRON_SEC_MASK (RTC_AL_SEC_MASK << RTC_PWRON_SEC_SHIFT) +#define RTC_PWRON_MIN_MASK (RTC_AL_MIN_MASK << RTC_PWRON_MIN_SHIFT) +#define RTC_PWRON_HOU_MASK (RTC_AL_HOU_MASK << RTC_PWRON_HOU_SHIFT) +#define RTC_PWRON_DOM_MASK (RTC_AL_DOM_MASK << RTC_PWRON_DOM_SHIFT) +#define RTC_PWRON_MTH_MASK (RTC_AL_MTH_MASK << RTC_PWRON_MTH_SHIFT) +#define RTC_PWRON_YEA_MASK (RTC_AL_YEA_MASK << RTC_PWRON_YEA_SHIFT) + +#define RTC_BBPU_KEY 0x4300 +#define RTC_BBPU_CBUSY BIT(6) +#define RTC_BBPU_RELOAD BIT(5) +#define RTC_BBPU_AUTO BIT(3) +#define RTC_BBPU_CLR BIT(1) +#define RTC_BBPU_PWREN BIT(0) +#define RTC_BBPU_AL_STA BIT(7) +#define RTC_BBPU_RESET_AL BIT(3) +#define RTC_BBPU_RESET_SPAR BIT(2) + +#define RTC_AL_MASK_DOW BIT(4) + +#define RTC_IRQ_EN_LP BIT(3) +#define RTC_IRQ_EN_ONESHOT BIT(2) +#define RTC_IRQ_EN_AL BIT(0) +#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) + +#define RTC_IRQ_STA_LP BIT(3) +#define RTC_IRQ_STA_AL BIT(0) + +#define RTC_PDN1_PWRON_TIME BIT(7) +#define RTC_PDN2_PWRON_LOGO BIT(15) +#define RTC_PDN2_PWRON_ALARM BIT(4) + +#define RTC_RG_FG2 0x54 +#define RTC_RG_FG3 0x56 + +#define EOSC_CALI_TD_MT6685 0x29 +#define EOSC_CALI_TD_MASK 0x3 + +#define HWID_MT6685 0x8 + +#define TOP_RTC_EOSC32_CK_PDN MT6685_SCK_TOP_CKPDN_CON0_L +#define TOP_RTC_EOSC32_CK_PDN_MASK (MT6685_RG_RTC_EOSC32_CK_PDN_MASK \ + << MT6685_RG_RTC_EOSC32_CK_PDN_SHIFT) + +#define TOP_DIG_WPK MT6685_TOP_DIG_WPK +#define DIG_WPK_KEY_MASK (MT6685_DIG_WPK_KEY_MASK << MT6685_DIG_WPK_KEY_SHIFT) + +#define TOP_DIG_WPK_H MT6685_TOP_DIG_WPK_H +#define DIG_WPK_KEY_H_MASK (MT6685_DIG_WPK_KEY_H_MASK << MT6685_DIG_WPK_KEY_H_SHIFT) + +#define RG_RTC_MCLK_PDN MT6685_SCK_TOP_CKPDN_CON0_L +#define RG_RTC_MCLK_PDN_STA_MASK MT6685_RG_RTC_MCLK_PDN_MASK +#define RG_RTC_MCLK_PDN_STA_SHIFT MT6685_RG_RTC_MCLK_PDN_SHIFT + +#define RG_RTC_MCLK_PDN_SET MT6685_SCK_TOP_CKPDN_CON0_L_SET +#define RG_RTC_MCLK_PDN_CLR MT6685_SCK_TOP_CKPDN_CON0_L_CLR +#define RG_RTC_MCLK_PDN_MASK (MT6685_RG_RTC_MCLK_PDN_MASK \ + << MT6685_RG_RTC_MCLK_PDN_SHIFT) + +#define RG_RTC_32K_CK_PDN_SET MT6685_SCK_TOP_CKPDN_CON0_L_SET +#define RG_RTC_32K_CK_PDN_CLR MT6685_SCK_TOP_CKPDN_CON0_L_CLR +#define RG_RTC_32K_CK_PDN_MASK (MT6685_RG_RTC_32K_CK_PDN_MASK \ + << MT6685_RG_RTC_32K_CK_PDN_SHIFT) + +#define SPAR_PROT_STAT_MASK MT6685_RTC_SPAR_PROT_STAT_MASK +#define SPAR_PROT_STAT_SHIFT MT6685_RTC_SPAR_PROT_STAT_SHIFT + +/* SCK_TOP rtc interrupt */ +#define SCK_TOP_INT_CON0 MT6685_SCK_TOP_INT_CON0 +#define EN_RTC_INTERRUPT MT6685_RG_INT_EN_RTC_MASK +#define SCK_TOP_INT_STATUS0 MT6685_SCK_TOP_INT_STATUS0 + +#define TOP2_ELR1 MT6685_TOP2_ELR1 +#define TOP2_ELR1_MASK BIT(0) + +#define MTK_RTC_POLL_DELAY_US 10 +#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) + +#define RTC_POFF_ALM_SET _IOW('p', 0x15, struct rtc_time) /* Set alarm time */ + +#define SPARE_REG_WIDTH 1 + +enum mtk_rtc_spare_enum { + SPARE_FG2, + SPARE_FG3, + SPARE_SPAR0, + SPARE_KPOC, + SPARE_RG_MAX, +}; + +enum rtc_irq_sta { + RTC_NONE, + RTC_ALSTA, + RTC_TCSTA, + RTC_LPSTA, +}; + +enum rtc_reg_set { + RTC_REG, + RTC_MASK, + RTC_SHIFT +}; + +enum chip_version { + NULL_SERIES, + MT6685_SERIES, +}; + + +#define EOSC_SOL_1 0x5 +#define EOSC_SOL_2 0x7 + +enum rtc_eosc_cali_td { + EOSC_CALI_TD_01_SEC = 0x3, + EOSC_CALI_TD_02_SEC, + EOSC_CALI_TD_04_SEC, + EOSC_CALI_TD_08_SEC, + EOSC_CALI_TD_16_SEC, +}; + +enum cali_field_enum { + EOSC_CALI_TD, + CALI_FILED_MAX, +}; + +struct tag_bootmode { + u32 size; + u32 tag; + u32 bootmode; + u32 boottype; +}; + +enum boot_mode_t { + + NORMAL_BOOT = 0, + META_BOOT = 1, + RECOVERY_BOOT = 2, + SW_REBOOT = 3, + FACTORY_BOOT = 4, + ADVMETA_BOOT = 5, + ATE_FACTORY_BOOT = 6, + ALARM_BOOT = 7, + KERNEL_POWER_OFF_CHARGING_BOOT = 8, + LOW_POWER_OFF_CHARGING_BOOT = 9, + DONGLE_BOOT = 10, + UNKNOWN_BOOT +}; + +struct mtk_rtc_data { + u32 wrtgr; + u32 hwid; + u32 chip_version; + bool single_read_write_is_supported; + struct reg_field *spare_reg_fields; + struct reg_field *cali_reg_fields; +}; + +static const char *rtc_time_reg_name[RTC_OFFSET_COUNT] = { + [0] = "SEC", + [1] = "MIN", + [2] = "HOUR", + [3] = "DOM", + [4] = "DOW", + [5] = "MTH", + [6] = "YEAR", +}; + +enum rtc_time_mask { + SEC_MASK, + MIN_MASK, + HOU_MASK, + DOM_MASK, + DOW_MASK, + MTH_MASK, + YEA_MASK, + MASK_COUNT + +}; + +static char rtc_time_mask[MASK_COUNT] = { + [SEC_MASK] = 0x3f, + [MIN_MASK] = 0x3f, + [HOU_MASK] = 0x1f, + [DOM_MASK] = 0x1f, + [DOW_MASK] = 0x7, + [MTH_MASK] = 0xf, + [YEA_MASK] = 0x7f +}; + + +struct mt6685_rtc { + struct rtc_device *rtc_dev; + + /* Protect register access from multiple tasks */ + struct mutex lock; + struct regmap *regmap; + int irq; + u32 addr_base; + const struct mtk_rtc_data *data; + struct mutex clk_lock; + int clk_cnt; +}; + +#endif /* __MT6685_RTC_H__ */ -- GitLab From b82aa61cebb1f70e1ddc5d57d35ae35dd04698c0 Mon Sep 17 00:00:00 2001 From: Emilie Roberts Date: Wed, 15 Jan 2025 13:32:00 +0100 Subject: [PATCH 413/456] CHROMIUM: termina: enable USB audio/MIDI devices Allow for USB audio and MIDI devices to be used. USB MIDI and audio devices are able to be passed through to Linux in the standard ChromeOS settings, but kernel support was not enabled. This change enables the kernel flags needed for USB audio and MIDI sequencer support. BUG=b:260275869 TEST=Install qjackctl: `sudo apt install qjackctl` Start qjackctl: `qjackctl` Press Start Open Graph, notice there are no MIDI devices Plug in USB MIDI device (like AKAI MPK mini Mk II) In ChromeOS settings, share the USB device with Linux Wait 5 seconds Notice that the USB MIDI device now appears in qjackctl graph Change-Id: I4352a95e1ac7dbb60e9265c6e8e5550f57074a32 Signed-off-by: Emilie Roberts Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6169942 Reviewed-by: maciek swiech Reviewed-by: Daniel Verkamp Reviewed-by: Junichi Uekawa Signed-off-by: Hubert Mazur --- chromeos/config/termina/base.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chromeos/config/termina/base.config b/chromeos/config/termina/base.config index 4d748f16588aa..35d6a58cab811 100644 --- a/chromeos/config/termina/base.config +++ b/chromeos/config/termina/base.config @@ -306,7 +306,8 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SND=y CONFIG_SND_INTEL8X0=y CONFIG_SND_SEQUENCER=y -# CONFIG_SND_USB is not set +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_AUDIO_MIDI_V2=y CONFIG_SND_VIRTIO=y CONFIG_SOUND=y CONFIG_SQUASHFS=y -- GitLab From 8ddfbe48f728c5ab6c7118f5e102de6cc675e847 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 3 Dec 2024 14:39:04 +0800 Subject: [PATCH 414/456] FIXUP: CHROMIUM: arm64: dts: mt8186: Add unprovisioned Steelix SKUs The "regulator-compatible" property has been deprecated since 2012. Drop usage of it and fix up the regulator node names to match. Also reindent the regulator blocks correctly. BUG=b:366135265 TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 Change-Id: I1f53118abf5b1725adc940bf138aeb6b0dae336f Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6178988 Reviewed-by: Pin-yen Lin Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../mt8186-corsola-steelix-sku131076.dts | 51 +++++++++---------- .../mt8186-corsola-steelix-sku131077.dts | 51 +++++++++---------- 2 files changed, 48 insertions(+), 54 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131076.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131076.dts index ff3aab221f0aa..f18d4b830fcab 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131076.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131076.dts @@ -48,35 +48,32 @@ compatible = "mediatek,mt6315-regulator"; reg = <0x6 SPMI_USID>; - regulators { - mt6315_6_vbuck1: buck1 { - regulator-compatible = "vbuck1"; - regulator-name = "6_vbuck1"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + regulators { + mt6315_6_vbuck1: vbuck1 { + regulator-name = "6_vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck3: buck3 { - regulator-compatible = "vbuck3"; - regulator-name = "6_vbuck3"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + mt6315_6_vbuck3: vbuck3 { + regulator-name = "6_vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck4: buck4 { - regulator-compatible = "vbuck4"; - regulator-name = "6_vbuck4"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; + mt6315_6_vbuck4: vbuck4 { + regulator-name = "6_vbuck4"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; }; }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131077.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131077.dts index 030b3155b6c37..88b12fd38b96b 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131077.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131077.dts @@ -47,35 +47,32 @@ compatible = "mediatek,mt6315-regulator"; reg = <0x6 SPMI_USID>; - regulators { - mt6315_6_vbuck1: buck1 { - regulator-compatible = "vbuck1"; - regulator-name = "6_vbuck1"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + regulators { + mt6315_6_vbuck1: vbuck1 { + regulator-name = "6_vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck3: buck3 { - regulator-compatible = "vbuck3"; - regulator-name = "6_vbuck3"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + mt6315_6_vbuck3: vbuck3 { + regulator-name = "6_vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck4: buck4 { - regulator-compatible = "vbuck4"; - regulator-name = "6_vbuck4"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; + mt6315_6_vbuck4: vbuck4 { + regulator-name = "6_vbuck4"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; }; }; }; -- GitLab From 12f54da89de3400dfce84eb7b06ff17a923098b7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 3 Dec 2024 14:44:19 +0800 Subject: [PATCH 415/456] FIXUP: CHROMIUM: arm64: dts: mt8186: Add unprovisioned SKU IDs for Rusty The "regulator-compatible" property has been deprecated since 2012. Drop usage of it and fix up the regulator node names to match. Also reindent the regulator blocks correctly. BUG=b:366135451 TEST=emerge-corsola-kernelnext chromeos-kernel-6_6 Change-Id: Ic758b6f3906c213a6e57e85ccb1c704ff6787354 Signed-off-by: Chen-Yu Tsai Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6178989 Reviewed-by: Pin-yen Lin Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../mt8186-corsola-rusty-sku196612.dts | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196612.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196612.dts index 4216eedca58e6..ca7e975663a53 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196612.dts +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196612.dts @@ -51,35 +51,32 @@ compatible = "mediatek,mt6315-regulator"; reg = <0x6 SPMI_USID>; - regulators { - mt6315_6_vbuck1: buck1 { - regulator-compatible = "vbuck1"; - regulator-name = "6_vbuck1"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + regulators { + mt6315_6_vbuck1: vbuck1 { + regulator-name = "6_vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck3: buck3 { - regulator-compatible = "vbuck3"; - regulator-name = "6_vbuck3"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; + mt6315_6_vbuck3: vbuck3 { + regulator-name = "6_vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; - mt6315_6_vbuck4: buck4 { - regulator-compatible = "vbuck4"; - regulator-name = "6_vbuck4"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; + mt6315_6_vbuck4: vbuck4 { + regulator-name = "6_vbuck4"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; }; }; }; -- GitLab From 958ad3b84e9d15c7203b7ed1f782bcb66be08ec9 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Sat, 18 Jan 2025 14:31:56 +0000 Subject: [PATCH 416/456] CHROMIUM: sound: soc/mediatek: Use udelay instead of mt8196_aud_delay Mediatek implement their own udelay inside the driver, which is not compatible with 32-bit. The implementation pretty similar to the udelay implement in arm64. Change to using general kernel function. BUG=b:314021233 BUG=b:372561093 BUG=b:378823932 BUG=b:375953604 BUG=b:357736343 BUG=b:314021350 BUG=b:357753807 BUG=b:369287582 BUG=b:377339114 TEST=build and boot to shell;play audio UPSTREAM-TASK=b:379039241 Change-Id: Ide2b290ca61e1c8f25234eb04782e027b6643548 Signed-off-by: Hsin-Te Yuan Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6178930 Reviewed-by: Yu-Che Cheng Tested-by: Yu-Che Cheng Signed-off-by: Hubert Mazur --- sound/soc/mediatek/Kconfig | 2 +- sound/soc/mediatek/mt8196/mt8196-afe-pcm.c | 21 +-------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 835508faa96c8..13c115220f366 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -206,7 +206,7 @@ config SND_SOC_MT8186_MT6366 config SND_SOC_MT8196 tristate "ASoC support for Mediatek MT8196 chip" - depends on ARCH_MEDIATEK && ARM64 + depends on ARCH_MEDIATEK select SND_SOC_MEDIATEK help This adds ASoC driver for Mediatek MT8196 boards diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c index edd208dfac9e8..5c1588633b9d3 100644 --- a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c +++ b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c @@ -44,25 +44,6 @@ static const struct snd_pcm_hardware mt8196_afe_hardware = { .fifo_size = 0, }; -#define USECS_TO_CYCLES(time_usecs) \ - xloops_to_cycles((time_usecs) * 0x10C7UL) - -static inline unsigned long xloops_to_cycles(unsigned long xloops) -{ - return (xloops * loops_per_jiffy * HZ) >> 32; -} - -void mt8196_aud_delay(unsigned long usecs) -{ - unsigned long cycles = 0; - cycles_t start = get_cycles(); - - cycles = USECS_TO_CYCLES(usecs); - - while ((get_cycles() - start) < cycles) - cpu_relax(); -} - static int mt8196_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -169,7 +150,7 @@ int mt8196_fe_trigger(struct snd_pcm_substream *substream, int cmd, */ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { if ((runtime->period_size * 1000) / rate <= 10) - mt8196_aud_delay(300); + udelay(300); } /* set irq counter */ -- GitLab From 3d01580d237ab4885a2624f002b895748371be56 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 15 Jan 2025 19:36:36 -0800 Subject: [PATCH 417/456] FROMGIT: Bluetooth: btusb: mediatek: Add locks for usb_driver_claim_interface() The documentation for usb_driver_claim_interface() says that "the device lock" is needed when the function is called from places other than probe(). This appears to be the lock for the USB interface device. The Mediatek btusb code gets called via this path: Workqueue: hci0 hci_power_on [bluetooth] Call trace: usb_driver_claim_interface btusb_mtk_claim_iso_intf btusb_mtk_setup hci_dev_open_sync hci_power_on process_scheduled_works worker_thread kthread With the above call trace the device lock hasn't been claimed. Claim it. Without this fix, we'd sometimes see the error "Failed to claim iso interface". Sometimes we'd even see worse errors, like a NULL pointer dereference (where `intf->dev.driver` was NULL) with a trace like: Call trace: usb_suspend_both usb_runtime_suspend __rpm_callback rpm_suspend pm_runtime_work process_scheduled_works Both errors appear to be fixed with the proper locking. Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions") Signed-off-by: Douglas Anderson Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit ec5570088c6aff8aecce998bf3aec4b9381dfa62 git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master) BUG=b:390289984 TEST=git diff Change-Id: I3cddc490ba37624163727fdb04370c9a12b10879 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6187681 Tested-by: Douglas Anderson Reviewed-by: Stephen Boyd Commit-Queue: ChromeOS Auto Retry Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/bluetooth/btusb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index af45f4a6e3c1e..707b30bc56ee0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2701,8 +2701,15 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data) struct btmtk_data *btmtk_data = hci_get_priv(data->hdev); int err; + /* + * The function usb_driver_claim_interface() is documented to need + * locks held if it's not called from a probe routine. The code here + * is called from the hci_power_on workqueue, so grab the lock. + */ + device_lock(&btmtk_data->isopkt_intf->dev); err = usb_driver_claim_interface(&btusb_driver, btmtk_data->isopkt_intf, data); + device_unlock(&btmtk_data->isopkt_intf->dev); if (err < 0) { btmtk_data->isopkt_intf = NULL; bt_dev_err(data->hdev, "Failed to claim iso interface"); -- GitLab From 0f5a60ea808448b41a16dc843f9bde7fdb5005fe Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 15 Jan 2025 19:36:37 -0800 Subject: [PATCH 418/456] FROMGIT: Bluetooth: btusb: mediatek: Add err code to btusb claim iso printout Add the error code to the message "Failed to claim iso interface". That allows us to know which error case usb_driver_claim_interface() hit. Signed-off-by: Douglas Anderson Signed-off-by: Luiz Augusto von Dentz (cherry picked from commit 6ca1c15fcb92dabffbe2d19050bee36fe37fbd71 git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master) BUG=b:390289984 TEST=code inspection Change-Id: I6d983dd02a0b6426e6380073feae504b180e4215 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6187682 Tested-by: Douglas Anderson Reviewed-by: Stephen Boyd Commit-Queue: ChromeOS Auto Retry Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/bluetooth/btusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 707b30bc56ee0..c2a241ff92c1a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2712,7 +2712,7 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data) device_unlock(&btmtk_data->isopkt_intf->dev); if (err < 0) { btmtk_data->isopkt_intf = NULL; - bt_dev_err(data->hdev, "Failed to claim iso interface"); + bt_dev_err(data->hdev, "Failed to claim iso interface: %d", err); return; } -- GitLab From bee7b1712473cad7d098f7351ee18f498d3671b0 Mon Sep 17 00:00:00 2001 From: Alvin1 Chen Date: Thu, 12 Dec 2024 18:40:51 +0800 Subject: [PATCH 419/456] BACKPORT: FROMLIST: mtd: spi-nor: xmc: Add support for XM25LU64C The device is produced by Wuhan Xinxin Semiconductor Manufacturing Corp. (XMC) and found on some routers from Chinese manufactures. The data sheet can be found here: https://www.xmcwh.com/uploads/954/XM25LU64C%20_%20Ver1.4.pdf Signed-off-by: Kankan Sun (am from https://lore.kernel.org/all/20241103142126.3406-1-ssunkkan@gmail.com/) Conflicts: drivers/mtd/spi-nor/xmc.c flash_info format is different with upstream, so modify flash_info manually. BUG=b:376390658 UPSTREAM-TASK=b:391057683 TEST=cros workon --board rauru start chromeos-kernel-6_6 emerge-rauru chromeos-kernel-6_6 Signed-off-by: Alvin1 Chen Change-Id: I3527fda9167dd73ffd1e148200737aef650593f3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6091134 Reviewed-by: Fei Shao Reviewed-by: Knox Chiou Commit-Queue: Knox Chiou Signed-off-by: Hubert Mazur --- drivers/mtd/spi-nor/xmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/spi-nor/xmc.c b/drivers/mtd/spi-nor/xmc.c index 051411e86339c..57006f0ab6745 100644 --- a/drivers/mtd/spi-nor/xmc.c +++ b/drivers/mtd/spi-nor/xmc.c @@ -16,6 +16,9 @@ static const struct flash_info xmc_nor_parts[] = { { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "XM25LU64C", INFO(0x204117, 0, 64 * 1024, 128) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) }, }; const struct spi_nor_manufacturer spi_nor_xmc = { -- GitLab From b9eca67671ab444a2e3cdc6ed127d1bf023dff8d Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 16 Jan 2025 09:42:50 -0800 Subject: [PATCH 420/456] FROMLIST: drm/mediatek: dp: drm_err => dev_err in HPD path to avoid NULL ptr The function mtk_dp_wait_hpd_asserted() may be called before the `mtk_dp->drm_dev` pointer is assigned in mtk_dp_bridge_attach(). Specifically it can be called via this callpath: - mtk_edp_wait_hpd_asserted - [panel probe] - dp_aux_ep_probe Using "drm" level prints anywhere in this callpath causes a NULL pointer dereference. Change the error message directly in mtk_dp_wait_hpd_asserted() to dev_err() to avoid this. Also change the error messages in mtk_dp_parse_capabilities(), which is called by mtk_dp_wait_hpd_asserted(). While touching these prints, also add the error code to them to make future debugging easier. Fixes: 7eacba9a083b ("drm/mediatek: dp: Add .wait_hpd_asserted() for AUX bus") Signed-off-by: Douglas Anderson (am from https://patchwork.kernel.org/patch/13942094/) (also found at https://lore.kernel.org/r/20250116094249.1.I29b0b621abb613ddc70ab4996426a3909e1aa75f@changeid) UPSTREAM-TASK=b:391646448 BUG=b:390455848 TEST=Put printout in non-error case and see crash fixed Change-Id: I29b0b621abb613ddc70ab4996426a3909e1aa75f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6191527 Commit-Queue: Douglas Anderson Reviewed-by: Sean Paul Commit-Queue: Stephen Boyd Tested-by: Douglas Anderson Auto-Submit: Douglas Anderson Reviewed-by: Stephen Boyd Signed-off-by: Hubert Mazur --- drivers/gpu/drm/mediatek/mtk_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 2407bc9f0ddba..1af045d5824bb 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -1754,7 +1754,7 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val); if (ret < 1) { - drm_err(mtk_dp->drm_dev, "Read mstm cap failed\n"); + dev_err(mtk_dp->dev, "Read mstm cap failed: %zd\n", ret); return ret == 0 ? -EIO : ret; } @@ -1764,7 +1764,7 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val); if (ret < 1) { - drm_err(mtk_dp->drm_dev, "Read irq vector failed\n"); + dev_err(mtk_dp->dev, "Read irq vector failed: %zd\n", ret); return ret == 0 ? -EIO : ret; } @@ -2047,7 +2047,7 @@ static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wa ret = mtk_dp_parse_capabilities(mtk_dp); if (ret) { - drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n"); + dev_err(mtk_dp->dev, "Can't parse capabilities: %d\n", ret); return ret; } -- GitLab From b5e9a80a77e31f854ee4584ff3e7290800042a88 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 27 Sep 2024 13:44:17 +0800 Subject: [PATCH 421/456] CHROMIUM: soc: mediatek: apu: Add mt8196 apu power driver Add MT8196 APU power driver, which is responsible for the initial power-on sequence, ensuring the APU SMMU operates correctly. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I92ea6fbd0450c25309b57025f3e7e841e0e9ddeb Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083911 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/Kconfig | 2 + drivers/soc/mediatek/Makefile | 1 + drivers/soc/mediatek/apusys/Kconfig | 16 + drivers/soc/mediatek/apusys/Makefile | 3 + drivers/soc/mediatek/apusys/power/Makefile | 5 + .../mediatek/apusys/power/mtk_apu_pwr_ipi.h | 36 ++ .../apusys/power/mtk_apu_pwr_ipi_tx.c | 223 ++++++++++++ .../soc/mediatek/apusys/power/mtk_apu_top.h | 19 + .../mediatek/apusys/power/mtk_aputop_drv.c | 87 +++++ .../apusys/power/platform/mt8196_aputop.c | 335 ++++++++++++++++++ include/linux/soc/mediatek/mtk_apu_pwr.h | 11 + include/linux/soc/mediatek/mtk_sip_svc.h | 3 + 12 files changed, 741 insertions(+) create mode 100644 drivers/soc/mediatek/apusys/Kconfig create mode 100644 drivers/soc/mediatek/apusys/Makefile create mode 100644 drivers/soc/mediatek/apusys/power/Makefile create mode 100644 drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi.h create mode 100644 drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi_tx.c create mode 100644 drivers/soc/mediatek/apusys/power/mtk_apu_top.h create mode 100644 drivers/soc/mediatek/apusys/power/mtk_aputop_drv.c create mode 100644 drivers/soc/mediatek/apusys/power/platform/mt8196_aputop.c create mode 100644 include/linux/soc/mediatek/mtk_apu_pwr.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 994bd9a7574c1..ee2549a0ef0a3 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -5,6 +5,8 @@ menu "MediaTek SoC drivers" depends on ARCH_MEDIATEK || COMPILE_TEST +source "drivers/soc/mediatek/apusys/Kconfig" + config MTK_CMDQ tristate "MediaTek CMDQ Support" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 59265b1735988..0d3992e30e090 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-y += apusys/ obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o diff --git a/drivers/soc/mediatek/apusys/Kconfig b/drivers/soc/mediatek/apusys/Kconfig new file mode 100644 index 0000000000000..f094406310a63 --- /dev/null +++ b/drivers/soc/mediatek/apusys/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config MTK_APUSYS_SUPPORT + tristate "MediaTek APUSYS driver" + depends on ARM || ARM64 + select REGMAP + select MAILBOX + select MTK_APU_MBOX + select MTK_SCP + select PM_DEVFREQ + help + Enable Mediatek APUSYS feature for centralize control. + Middleware and APU scheduler will control memory, + QoS, and normal/deadline command queue in central layer. + Support multiple, multicore APU command scheduling and + execution in low level driver. diff --git a/drivers/soc/mediatek/apusys/Makefile b/drivers/soc/mediatek/apusys/Makefile new file mode 100644 index 0000000000000..eff2e9fa81ab3 --- /dev/null +++ b/drivers/soc/mediatek/apusys/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += power/ diff --git a/drivers/soc/mediatek/apusys/power/Makefile b/drivers/soc/mediatek/apusys/power/Makefile new file mode 100644 index 0000000000000..bc7f77be8d7d9 --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += mtk_apu_top.o +mtk_apu_top-objs += mtk_aputop_drv.o +mtk_apu_top-objs += platform/mt8196_aputop.o + +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += mtk_apu_pwr_ipi_tx.o diff --git a/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi.h b/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi.h new file mode 100644 index 0000000000000..bf352f517a34e --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_PWR_IPI_RX_H +#define MTK_APU_PWR_IPI_RX_H + +enum mtk_apu_pwr_cmd { + MTK_APU_PWR_DEV_CTL, + MTK_APU_PWR_DEV_SET_OPP, + MTK_APU_PWR_DUMP_OPP_TBL, + MTK_APU_PWR_DUMP_OPP_TBL2, + MTK_APU_PWR_CURR_STATUS, + MTK_APU_PWR_PWR_PROFILING, + MTK_APU_PWR_CLK_SET_RATE, + MTK_APU_PWR_BUK_SET_VOLT, + MTK_APU_PWR_ARE_DBG, + MTK_APU_PWR_HW_VOTER_DBG, + MTK_APU_PWR_SET_LIMIT_FREQ, + MTK_APU_PWR_THERMAL_GET_TEMP, + MTK_APU_PWR_GET_CURR_FREQ, + MTK_APU_PWR_RPMSG_CMD_MAX, +}; + +struct mtk_apu_pwr_rpmsg_data { + enum mtk_apu_pwr_cmd cmd; + int data0; + int data1; + int data2; + int data3; + int _resv; + void *data4; +}; + +#endif diff --git a/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi_tx.c b/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi_tx.c new file mode 100644 index 0000000000000..e427c1952d878 --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/mtk_apu_pwr_ipi_tx.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_apu_pwr_ipi.h" + +struct mtk_apu_pwr_rpmsg { + struct device *dev; + struct rpmsg_device *rpdev; + struct mutex send_lock; + struct completion comp; + unsigned int curr_freq; + enum mtk_apu_pwr_cmd curr_rpmsg_cmd; +}; + +static int mtk_apu_pwr_send_rpmsg(struct device *dev, struct mtk_apu_pwr_rpmsg_data *rpmsg_data, + unsigned int timeout) +{ + struct mtk_apu_pwr_rpmsg *power_rpmsg = dev_get_drvdata(dev); + + scoped_guard(mutex, &power_rpmsg->send_lock) { + long ret; + + reinit_completion(&power_rpmsg->comp); + + power_rpmsg->curr_rpmsg_cmd = rpmsg_data->cmd; + + ret = rpmsg_send(power_rpmsg->rpdev->ept, rpmsg_data, sizeof(*rpmsg_data)); + if (ret) { + dev_err(dev, "%s: failed to send msg to remote side, ret=%ld\n", + __func__, ret); + return ret; + } + + if (!timeout) + return 0; + + ret = wait_for_completion_interruptible_timeout(&power_rpmsg->comp, + msecs_to_jiffies(timeout)); + + if (ret < 0) { + dev_err(dev, "%s: failed to wait for completion, ret=%ld\n", + __func__, ret); + return ret; + } else if (ret == 0) { + dev_err(dev, "%s: failed to wait for completion, timeout\n", __func__); + return -ETIMEDOUT; + } + } + + return 0; +} + +static int mtk_apu_pwr_tx_callback(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct device *dev = &rpdev->dev; + struct mtk_apu_pwr_rpmsg *power_rpmsg = dev_get_drvdata(dev); + struct mtk_apu_pwr_rpmsg_data *rpmsg_data; + + if (len != sizeof(*rpmsg_data)) { + dev_err(dev, "%s: invalid length %d, which should be %zu\n", __func__, len, + sizeof(*rpmsg_data)); + return -EINVAL; + } + + rpmsg_data = data; + + if (rpmsg_data->cmd != power_rpmsg->curr_rpmsg_cmd) { + dev_err(dev, "%s: the current command is %d, abort unexpected command %d\n", + __func__, power_rpmsg->curr_rpmsg_cmd, rpmsg_data->cmd); + return -EINVAL; + } + + switch (power_rpmsg->curr_rpmsg_cmd) { + case MTK_APU_PWR_GET_CURR_FREQ: + power_rpmsg->curr_freq = rpmsg_data->data0; + break; + default: + break; + } + + complete(&power_rpmsg->comp); + + return 0; +} + +static int mtk_apu_set_limit_freq(struct device *dev, int max_freq) +{ + struct mtk_apu_pwr_rpmsg_data rpmsg_data = { + .cmd = MTK_APU_PWR_SET_LIMIT_FREQ, + .data0 = max_freq, + }; + + return mtk_apu_pwr_send_rpmsg(dev, &rpmsg_data, 100); +} + +static int mtk_apu_get_remote_freq(struct device *dev) +{ + struct mtk_apu_pwr_rpmsg_data rpmsg_data = { + .cmd = MTK_APU_PWR_GET_CURR_FREQ, + }; + + return mtk_apu_pwr_send_rpmsg(dev, &rpmsg_data, 100); +} + +static int mtk_apu_freq_target(struct device *dev, unsigned long *freq, u32 flags) +{ + struct dev_pm_opp *opp; + unsigned long rate; + + flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; + + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) { + dev_err(dev, "%s: failed to get recommended opp for %lu hz\n", __func__, *freq); + return PTR_ERR(opp); + } + dev_pm_opp_put(opp); + + rate = *freq / 1000; /* to KHz */ + + return mtk_apu_set_limit_freq(dev, rate); +} + +static int mtk_apu_get_cur_freq(struct device *dev, unsigned long *freq) +{ + int ret; + struct mtk_apu_pwr_rpmsg *power_rpmsg = dev_get_drvdata(dev); + + ret = mtk_apu_get_remote_freq(dev); + + if (ret) { + dev_err(dev, "Failed to get current frequency, ret = %d\n", ret); + *freq = 0; + return ret; + } + + *freq = power_rpmsg->curr_freq * 1000; + + return ret; +} + +static int mtk_apu_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) +{ + /* + * MediaTek NPU does not support dynamic adjustment of OPP level + * on the kernel side, so this function is bypassed. + */ + return 0; +} + +static struct devfreq_dev_profile devfreq_dev_profile = { + .initial_freq = 1800000000, + .polling_ms = 0, + .target = mtk_apu_freq_target, + .get_dev_status = mtk_apu_get_dev_status, + .get_cur_freq = mtk_apu_get_cur_freq, + .is_cooling_device = true, +}; + +static int mtk_apu_pwr_tx_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + struct mtk_apu_pwr_rpmsg *power_rpmsg; + struct devfreq *devfreq; + int ret = 0; + + power_rpmsg = devm_kzalloc(dev, sizeof(struct mtk_apu_pwr_rpmsg), GFP_KERNEL); + if (!power_rpmsg) + return -ENOMEM; + + power_rpmsg->rpdev = rpdev; + init_completion(&power_rpmsg->comp); + mutex_init(&power_rpmsg->send_lock); + + power_rpmsg->dev = dev; + dev_set_drvdata(dev, power_rpmsg); + + ret = dev_pm_opp_of_add_table(dev); + if (ret) + dev_err(dev, "%s: failed to add opp table (%d)\n", __func__, ret); + + devfreq = devm_devfreq_add_device(dev, &devfreq_dev_profile, DEVFREQ_GOV_PERFORMANCE, + NULL); + if (IS_ERR(devfreq)) + dev_err(dev, "%s: failed to register devfreq (%ld)\n", __func__, PTR_ERR(devfreq)); + else + dev_info(dev, "%s: registered devfreq\n", __func__); + + return 0; +} + +static const struct of_device_id mtk_apu_pwr_tx_rpmsg_of_match[] = { + { .compatible = "mediatek,aputop-rpmsg", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, mtk_apu_pwr_tx_rpmsg_of_match); + +static struct rpmsg_driver apu_pwr_tx_rpmsg_drv = { + .drv = { + .name = "mtk_apu_pwr_ipi_tx", + .owner = THIS_MODULE, + .of_match_table = mtk_apu_pwr_tx_rpmsg_of_match, + }, + .callback = mtk_apu_pwr_tx_callback, + .probe = mtk_apu_pwr_tx_probe, +}; + +module_rpmsg_driver(apu_pwr_tx_rpmsg_drv); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek apu-tx-ipi rpmsg driver"); diff --git a/drivers/soc/mediatek/apusys/power/mtk_apu_top.h b/drivers/soc/mediatek/apusys/power/mtk_apu_top.h new file mode 100644 index 0000000000000..a037f8703cbe4 --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/mtk_apu_top.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ +#ifndef __MTK_APU_TOP_H__ +#define __MTK_APU_TOP_H__ + +struct platform_device; + +struct apupwr_plat_data { + int (*probe)(struct platform_device *pdev); + void (*remove)(struct platform_device *pdev); + int (*get_rpc_status)(struct platform_device *pdev); + int (*get_rpc_pwr_status)(struct platform_device *pdev); +}; + +extern const struct apupwr_plat_data mt8196_plat_data; + +#endif diff --git a/drivers/soc/mediatek/apusys/power/mtk_aputop_drv.c b/drivers/soc/mediatek/apusys/power/mtk_aputop_drv.c new file mode 100644 index 0000000000000..5f3f29b44f958 --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/mtk_aputop_drv.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include "mtk_apu_top.h" + +static int mtk_apu_top_probe(struct platform_device *pdev) +{ + const struct apupwr_plat_data *pwr_data = of_device_get_match_data(&pdev->dev); + + return pwr_data->probe(pdev); +} + +static void mtk_apu_top_remove(struct platform_device *pdev) +{ + const struct apupwr_plat_data *pwr_data = of_device_get_match_data(&pdev->dev); + + if (pwr_data->remove) + pwr_data->remove(pdev); +} + +static const struct of_device_id of_match_mtk_apu_top[] = { + { .compatible = "mt8196,apu-top-3", .data = &mt8196_plat_data }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_match_mtk_apu_top); + +static struct platform_driver mtk_apu_top_drv = { + .probe = mtk_apu_top_probe, + // TODO: will change the name to ".remove" when sending upstream + .remove_new = mtk_apu_top_remove, + .driver = { + .name = "apu_top_3", + .of_match_table = of_match_mtk_apu_top, + }, +}; +module_platform_driver(mtk_apu_top_drv); + +int mtk_apu_get_rpc_status(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct apupwr_plat_data *pwr_data; + + if (dev->driver != &mtk_apu_top_drv.driver) { + dev_err(dev, "Device not supported by MTK APU TOP driver\n"); + return -EINVAL; + } + + pwr_data = of_device_get_match_data(dev); + if (!pwr_data->get_rpc_status) { + dev_err(dev, "No get_rpc_status function defined for this platform\n"); + return -EINVAL; + } + + return pwr_data->get_rpc_status(pdev); +} +EXPORT_SYMBOL_NS(mtk_apu_get_rpc_status, MTK_APU_PWR); + +int mtk_apu_get_rpc_pwr_status(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct apupwr_plat_data *pwr_data; + + if (dev->driver != &mtk_apu_top_drv.driver) { + dev_err(dev, "Device not supported by MTK APU TOP driver\n"); + return -EINVAL; + } + + pwr_data = of_device_get_match_data(dev); + + if (!pwr_data->get_rpc_pwr_status) { + dev_err(dev, "No get_rpc_pwr_status function defined for this platform\n"); + return -EINVAL; + } + + return pwr_data->get_rpc_pwr_status(pdev); +} +EXPORT_SYMBOL_NS(mtk_apu_get_rpc_pwr_status, MTK_APU_PWR); + +MODULE_SOFTDEP("pre: mtk-apu-mailbox"); + +MODULE_DESCRIPTION("MediaTek APU Power Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/apusys/power/platform/mt8196_aputop.c b/drivers/soc/mediatek/apusys/power/platform/mt8196_aputop.c new file mode 100644 index 0000000000000..3a446125270d8 --- /dev/null +++ b/drivers/soc/mediatek/apusys/power/platform/mt8196_aputop.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "../mtk_apu_pwr_ipi.h" +#include "../mtk_apu_top.h" + +/* RPC offset define */ +#define MTK_APU_RPC_STATUS_1 (0x0034) +#define MTK_APU_RPC_INTF_PWR_RDY (0x0044) +#define MTK_APU_RPC_PWR_ACK (0x0048) + +/* vcore offset define */ +#define MTK_APU_VCORE_CG_CLR (0x0008) + +/* rcx offset define */ +#define MTK_APU_RCX_CG_CLR (0x0008) + +enum apupw_reg { + RCX, + VCORE, + RPC, + APUPW_MAX_REGS, +}; + +struct mtk_apu_power { + void __iomem *regs[APUPW_MAX_REGS]; + struct regmap_field *apu_smmu_sema_regmap_field; +}; + +static const char *reg_name[APUPW_MAX_REGS] = { + "RCX", "VCORE", "RPC" +}; + +static struct regmap *get_mbox_regmap(struct device *dev) +{ + struct device_node *mbox_node; + struct platform_device *mbox_pdev; + struct regmap *regmap = NULL; + struct device_link *link; + + mbox_node = of_parse_phandle(dev->of_node, "mediatek,mbox-spare-reg", 0); + if (!mbox_node) + return ERR_PTR(-ENODEV); + + mbox_pdev = of_find_device_by_node(mbox_node); + if (!mbox_pdev) { + regmap = ERR_PTR(-EPROBE_DEFER); + goto out_put_node; + } + + regmap = dev_get_regmap(&mbox_pdev->dev, NULL); + if (!regmap) + regmap = ERR_PTR(-EINVAL); + + link = device_link_add(dev, &mbox_pdev->dev, DL_FLAG_PM_RUNTIME); + if (!link) + return dev_err_probe(dev, -EPROBE_DEFER, + "failed to add device link between power and mailbox\n"); + + platform_device_put(mbox_pdev); + +out_put_node: + of_node_put(mbox_node); + return regmap; +} + +static int init_reg_base(struct platform_device *pdev, struct mtk_apu_power *apupw) +{ + for (unsigned int idx = 0; idx < ARRAY_SIZE(reg_name); idx++) { + apupw->regs[idx] = devm_platform_ioremap_resource_byname(pdev, reg_name[idx]); + if (IS_ERR(apupw->regs[idx])) + return dev_err_probe(&pdev->dev, PTR_ERR(apupw->regs[idx]), + "%s remap base fail\n", reg_name[idx]); + } + + return 0; +} + +static uint32_t apusys_pwr_smc_call(struct device *dev, uint32_t smc_id, uint32_t a2) +{ + struct arm_smccc_res res; + + dev_dbg(dev, "%s: smc call %d\n", __func__, smc_id); + + arm_smccc_smc(MTK_SIP_APUSYS_CONTROL, smc_id, a2, 0, 0, 0, 0, 0, &res); + if (((long) res.a0) < 0) + dev_err(dev, "%s: smc call %d return error(%lu)\n", __func__, smc_id, res.a0); + + return res.a0; +} + + +static int get_reserved_mem(struct device *dev, void **resv_mem_va) +{ + struct device_node *data_np; + struct resource r; + int ret; + + /* + * To enable the MTK APU power feature, we need to load the binary of the + * Command Engine (CE) into the reserved memory, which is shared with the + * MTK APU remote processor (remoteproc) to store the APU image. + * Therefore, we need to parse the phandle and obtain the virtual address + * of that reserved memory. + */ + data_np = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!data_np) { + dev_err(dev, "No reserved memory region found.\n"); + return -EINVAL; + } + + ret = of_address_to_resource(data_np, 0, &r); + if (ret) { + dev_err(dev, "failed to parse reserved memory: %d\n", ret); + of_node_put(data_np); + return ret; + } + of_node_put(data_np); + + *resv_mem_va = devm_ioremap_wc(dev, r.start, resource_size(&r)); + + return 0; +} + +static int load_ce_bin(struct device *dev, const struct firmware *fw, void *resv_mem_va) +{ + struct apusys_secure_info_t *sec_info_ptr = NULL; + const struct ptimg_hdr_t *hdr; + const struct ptimg_hdr_t *hdr_end; + const void *img; + void *resv_ce_va; + + hdr = (const struct ptimg_hdr_t *)(fw->data + 0x200); + dev_dbg(dev, "%s: hdr->magic is 0x%x\n", __func__, hdr->magic); + + sec_info_ptr = resv_mem_va + 0x100000; + sec_info_ptr->ce_bin_ofs = 0x100000 + roundup(sizeof(*sec_info_ptr), 16); + resv_ce_va = resv_mem_va + sec_info_ptr->ce_bin_ofs; + + hdr_end = (const struct ptimg_hdr_t *)(fw->data + fw->size); + while (hdr < hdr_end && hdr->magic == PT_MAGIC) { + img = ((const void *) hdr) + hdr->hdr_size; + dev_dbg(dev, "Rhdr->hdr_size= 0x%x\n", hdr->hdr_size); + dev_dbg(dev, "img address is %p\n", img); + + switch (hdr->id) { + case PT_ID_CE_BIN: + dev_dbg(dev, "PT_ID_CE_BIN\n"); + sec_info_ptr->ce_bin_sz = hdr->hdr_size + hdr->img_size; + memcpy_toio(resv_ce_va, img, sec_info_ptr->ce_bin_sz); + dev_dbg(dev, "ce_bin_sz = 0x%x\n", sec_info_ptr->ce_bin_sz); + return 0; + default: + break; + } + + img += roundup(hdr->img_size, hdr->align); + hdr = (const struct ptimg_hdr_t *)img; + } + + return -EINVAL; +} + +static int setup_ce_bin(struct device *dev, const char *fw_path) +{ + const struct firmware *fw; + int ret; + void *resv_mem_va; + + ret = request_firmware(&fw, fw_path, dev); + if (ret < 0) { + dev_err(dev, "failed to load firmware '%s': %d\n", fw_path, ret); + return ret; + } + + ret = get_reserved_mem(dev, &resv_mem_va); + if (ret) + goto out_release_fw; + + ret = load_ce_bin(dev, fw, resv_mem_va); + if (ret) + goto out_unmap_mem; + + ret = apusys_pwr_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN, 0); + if (ret) + dev_err(dev, "%s: load ce bin failed, ret = %d\n", __func__, ret); + +out_unmap_mem: + devm_iounmap(dev, resv_mem_va); + +out_release_fw: + release_firmware(fw); + + return ret; +} + +static int __apu_wake_rpc_rcx(struct device *dev, struct mtk_apu_power *apupw) +{ + int ret = 0, val = 0; + + dev_dbg(dev, "%s before wakeup RCX MTK_APU_RPC_INTF_PWR_RDY = 0x%x\n", __func__, + readl(apupw->regs[RPC] + MTK_APU_RPC_INTF_PWR_RDY)); + + /* Used RV SMC call to wake up RPC */ + apusys_pwr_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, 0); + + ret = readl_relaxed_poll_timeout_atomic((apupw->regs[RPC] + MTK_APU_RPC_INTF_PWR_RDY), + val, (val & 0x1UL), 50, 10000); + + if (ret) { + dev_err(dev, "%s polling RPC RDY timeout, ret %d\n", __func__, ret); + dev_err(dev, "%s RCX MTK_APU_RPC_PWR_ACK = 0x%x\n", __func__, + readl(apupw->regs[RPC] + MTK_APU_RPC_PWR_ACK)); + goto out; + } + + dev_dbg(dev, "%s after wakeup RCX MTK_APU_RPC_INTF_PWR_RDY = 0x%x\n", __func__, + readl(apupw->regs[RPC] + MTK_APU_RPC_INTF_PWR_RDY)); + + ret |= readl_relaxed_poll_timeout_atomic((apupw->regs[RPC] + MTK_APU_RPC_STATUS_1), + val, (val & (0x1 << 13)), 50, 10000); + + if (ret) { + dev_err(dev, "%s polling ARE FSM timeout, ret %d\n", __func__, ret); + dev_err(dev, "%s RCX MTK_APU_RPC_PWR_ACK 0x%x\n", __func__, + readl(apupw->regs[RPC] + MTK_APU_RPC_PWR_ACK)); + goto out; + } + + /* clear vcore/rcx cgs */ + writel(0xFFFFFFFF, apupw->regs[VCORE] + MTK_APU_VCORE_CG_CLR); + writel(0xFFFFFFFF, apupw->regs[RCX] + MTK_APU_RCX_CG_CLR); + +out: + return ret; +} + +static int mt8196_apu_top_on(struct device *dev, struct mtk_apu_power *apupw) +{ + int ret; + + ret = __apu_wake_rpc_rcx(dev, apupw); + if (ret) { + dev_err(dev, "%s fail to wakeup RPC, ret %d\n", __func__, ret); + return ret; + } + + return ret; +} + +static int mt8196_apu_top_probe(struct platform_device *pdev) +{ + int ret = 0, val = 0; + struct device *dev = &pdev->dev; + struct regmap *mbox_regmap; + struct mtk_apu_power *apupw; + const char *fw_path = "mediatek/mt8196/apusys.img"; + + ret = setup_ce_bin(dev, fw_path); + if (ret) + return ret; + + apupw = devm_kzalloc(dev, sizeof(*apupw), GFP_KERNEL); + if (!apupw) + return -ENOMEM; + + ret = init_reg_base(pdev, apupw); + if (ret) + return ret; + + mbox_regmap = get_mbox_regmap(dev); + if (IS_ERR(mbox_regmap)) { + ret = PTR_ERR(mbox_regmap); + return dev_err_probe(dev, ret, "failed to get mailbox regmap: %d\n", ret); + } + + ret = mt8196_apu_top_on(dev, apupw); + if (ret) + return dev_err_probe(dev, ret, "fail to power on APU\n"); + + ret = readl_relaxed_poll_timeout_atomic((apupw->regs[RPC] + MTK_APU_RPC_INTF_PWR_RDY), + val, (val & 0x1UL), 50, 10000); + if (ret) + return dev_err_probe(dev, ret, "fail to wait for RPC ready\n"); + + /* release hw sema before smmu driver init */ + dev_dbg(dev, "%s release hw sema before smmu driver init\n", __func__); + ret = regmap_write(mbox_regmap, 0xA0, 0x2); + if (ret) + return dev_err_probe(dev, ret, "failed to release hw sema (%d)\n", ret); + + dev_set_drvdata(dev, apupw); + + return ret; +} + +static int mt8196_get_rpc_status(struct platform_device *pdev) +{ + struct mtk_apu_power *apupw = dev_get_drvdata(&pdev->dev); + + return readl(apupw->regs[RPC] + MTK_APU_RPC_STATUS_1); +} + +static int mt8196_get_rpc_pwr_status(struct platform_device *pdev) +{ + struct mtk_apu_power *apupw = dev_get_drvdata(&pdev->dev); + + return readl(apupw->regs[RPC] + MTK_APU_RPC_INTF_PWR_RDY); +} + +const struct apupwr_plat_data mt8196_plat_data = { + .probe = mt8196_apu_top_probe, + .get_rpc_status = mt8196_get_rpc_status, + .get_rpc_pwr_status = mt8196_get_rpc_pwr_status, +}; diff --git a/include/linux/soc/mediatek/mtk_apu_pwr.h b/include/linux/soc/mediatek/mtk_apu_pwr.h new file mode 100644 index 0000000000000..9bd7a8742b14c --- /dev/null +++ b/include/linux/soc/mediatek/mtk_apu_pwr.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ +#ifndef __MTK_APU_PWR_H__ +#define __MTK_APU_PWR_H__ + +int mtk_apu_get_rpc_status(struct platform_device *pdev); +int mtk_apu_get_rpc_pwr_status(struct platform_device *pdev); + +#endif diff --git a/include/linux/soc/mediatek/mtk_sip_svc.h b/include/linux/soc/mediatek/mtk_sip_svc.h index 0cd46fae6b513..41b82ac171ae7 100644 --- a/include/linux/soc/mediatek/mtk_sip_svc.h +++ b/include/linux/soc/mediatek/mtk_sip_svc.h @@ -27,4 +27,7 @@ #define MTK_SIP_TINYSYS_SSPM_CONTROL MTK_SIP_SMC_CMD(0x53C) +/* for APUSYS SMC call */ +#define MTK_SIP_APUSYS_CONTROL MTK_SIP_SMC_CMD(0x51E) + #endif -- GitLab From 221e5c39ae688fed414b0a231d2933761b2abe34 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 13:20:53 +0800 Subject: [PATCH 422/456] CHROMIUM: remoteproc: mediatek: Add APU remoteproc driver The APU integrates a subsystem with MD32RV33 (MD32) that runs tinysys. This patch add the base structure for APU rproc driver. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Ibbddaebc86df427828b15473441f151e865d8fa7 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166783 Commit-Queue: Chen-Yu Tsai Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Tested-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../mediatek_apusys/mtk_apu_excep.c | 76 +++ .../remoteproc/mediatek_apusys/mtk_apu_mem.c | 25 + .../mediatek_apusys/mtk_apu_rproc.c | 522 ++++++++++++++++++ .../mediatek_apusys/mtk_apu_rproc.h | 23 + .../mediatek_apusys/plat/mt8196_plat.c | 181 ++++++ include/linux/remoteproc/mtk_apu.h | 140 +++++ 6 files changed, 967 insertions(+) create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_excep.c create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_mem.c create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h create mode 100644 drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_excep.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_excep.c new file mode 100644 index 0000000000000..445c0cd1e35b1 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_excep.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include + +#include +#include +#include "mtk_apu_rproc.h" + +static irqreturn_t mtk_apu_wdt_isr(int irq, void *private_data) +{ + struct mtk_apu *apu = (struct mtk_apu *) private_data; + struct device *dev = apu->dev; + + if (apu->platdata->flags.secure_coredump) { + mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, 0); + mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, 0); + mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, 0); + } else { + dev_err(dev, "%s: Not support in non-secure coredump\n", __func__); + } + + disable_irq_nosync(apu->wdt_irq_number); + dev_dbg(dev, "%s: disable wdt_irq(%d)\n", __func__, apu->wdt_irq_number); + + /* Bypass the power off timeout checking after the exception is triggered */ + apu->bypass_pwr_off_chk = true; + + return IRQ_HANDLED; +} + +static int mtk_apu_wdt_irq_register(struct platform_device *pdev, struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + int ret = 0; + + apu->wdt_irq_number = platform_get_irq(pdev, 0); + dev_dbg(dev, "%s: wdt_irq_number = %d\n", __func__, apu->wdt_irq_number); + + ret = devm_request_irq(&pdev->dev, apu->wdt_irq_number, + mtk_apu_wdt_isr, 0, "apusys_wdt", apu); + + if (ret < 0) + dev_err(dev, "%s: devm_request_irq Failed to request irq %d: %d\n", + __func__, apu->wdt_irq_number, ret); + + return ret; +} + +int mtk_apu_exception_init(struct platform_device *pdev, struct mtk_apu *apu) +{ + int ret = 0; + + ret = mtk_apu_wdt_irq_register(pdev, apu); + if (ret < 0) + return ret; + + return ret; +} + +void mtk_apu_exception_exit(struct platform_device *pdev, struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + + if (apu->platdata->flags.secure_coredump) { + mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, 0); + mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, 0); + } else { + dev_err(dev, "%s: Not support in non-secure boot\n", __func__); + } + + devm_free_irq(&pdev->dev, apu->wdt_irq_number, "apusys_wdt"); + dev_dbg(dev, "%s: free wdt_irq(%d)\n", __func__, apu->wdt_irq_number); +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_mem.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_mem.c new file mode 100644 index 0000000000000..c352f8771c562 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_mem.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include + +#include "linux/remoteproc/mtk_apu.h" + +int mtk_apu_mem_init(struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + int ret; + + if (apu->platdata->flags.bypass_iommu) + return 0; + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(dev, "%s: dma_set_mask_and_coherent failed: %d\n", __func__, ret); + return ret; + } + + return 0; +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c new file mode 100644 index 0000000000000..0cd0eb6835162 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -0,0 +1,522 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "mtk_apu_rproc.h" + +#define MTK_APU_RUN_WAIT_CNT (3) +#define MTK_APU_RUN_TIMEOUT (10000) + +static const struct reg_field mtk_apu_config_reg_field = { + .reg = MBOX_HOST_CONFIG_ADDR, + .lsb = 0, + .msb = 31, +}; + +uint32_t mtk_apu_rv_smc_call(struct device *dev, uint32_t smc_id, uint32_t a2) +{ + struct arm_smccc_res res; + + dev_dbg(dev, "%s: smc call %d(a2 = %d)\n", __func__, smc_id, a2); + + arm_smccc_smc(MTK_SIP_APUSYS_CONTROL, smc_id, a2, 0, 0, 0, 0, 0, &res); + if (((int) res.a0) < 0) + dev_err(dev, "%s: smc call %d return error(%ld)\n", __func__, smc_id, res.a0); + + return res.a0; +} + +static void mtk_apu_dram_boot_remove(struct mtk_apu *apu) +{ + void *domain = iommu_get_domain_for_dev(apu->dev); + u32 boundary = (u32) upper_32_bits(apu->code_da); + u64 iova = CODE_BUF_DA | ((u64) boundary << 32); + + if (apu->platdata->flags.secure_boot && !apu->platdata->flags.map_iova) + return; + + if (domain != NULL) { + if (apu->platdata->flags.preload_firmware) + iommu_unmap(domain, MTK_APU_SEC_FW_IOVA, apu->apusys_sec_mem_size); + else if (!apu->platdata->flags.bypass_iommu) + iommu_unmap(domain, iova, apu->up_code_buf_sz); + } + + if (!apu->platdata->flags.preload_firmware) + dma_free_coherent(apu->dev, apu->up_code_buf_sz, apu->code_buf, apu->code_da); +} + +static int mtk_apu_dram_boot_init(struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + int ret = 0; + void *domain; + + if (apu->platdata->flags.secure_boot && !apu->platdata->flags.map_iova) + return 0; + + if (!apu->platdata->flags.preload_firmware || apu->platdata->flags.bypass_iommu) { + dev_err(dev, "%s: not support non-preload firmware\n", __func__); + return -EINVAL; + } + + if (!apu->platdata->flags.bypass_iommu) { + domain = iommu_get_domain_for_dev(apu->dev); + if (domain == NULL) { + dev_err(dev, "%s: iommu_get_domain_for_dev fail\n", __func__); + return -ENOMEM; + } + } + + apu->code_buf = (void *) apu->apu_sec_mem_base + apu->apusys_sec_info->up_code_buf_ofs; + apu->code_da = MTK_APU_SEC_FW_IOVA; + if (!apu->platdata->flags.smmu_support) + ret = iommu_map(domain, MTK_APU_SEC_FW_IOVA, apu->apusys_sec_mem_start, + apu->apusys_sec_mem_size, IOMMU_READ | IOMMU_WRITE, GFP_KERNEL); + else + ret = iommu_map(domain, MTK_APU_SEC_FW_IOVA, apu->apusys_sec_mem_start, + apu->apusys_sec_mem_size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, + GFP_KERNEL); + + if (ret) { + dev_err(dev, "%s: iommu_map fail(%d)\n", __func__, ret); + return ret; + } + + dev_dbg(dev, "%s: iommu_map done\n", __func__); + return ret; +} + +static int mtk_apu_setup_sec_mem(struct mtk_apu *apu) +{ + if (!apu->platdata->flags.secure_boot) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, 0); +} + +static void *mtk_apu_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) +{ + void *ptr = NULL; + struct mtk_apu *apu = (struct mtk_apu *)rproc->priv; + + if (da < DRAM_OFFSET + apu->up_code_buf_sz) { + ptr = apu->code_buf + (da - DRAM_OFFSET); + dev_dbg(apu->dev, "%s: (DRAM): da = 0x%llx, len = 0x%zx\n", __func__, da, len); + } else if (da >= TCM_OFFSET && da < TCM_OFFSET + apu->platdata->config.up_tcm_sz) { + if (apu->md32_tcm) + ptr = apu->md32_tcm + (da - TCM_OFFSET); + dev_dbg(apu->dev, "%s: (TCM): da = 0x%llx, len = 0x%zx\n", __func__, da, len); + } + return ptr; +} + +static int __mtk_apu_run(struct rproc *rproc) +{ + struct mtk_apu *apu = (struct mtk_apu *)rproc->priv; + const struct mtk_apu_hw_ops *hw_ops = &apu->platdata->ops; + struct device *dev = apu->dev; + struct mtk_apu_run *run = &apu->run; + struct timespec64 begin, end, delta; + int wait_cnt = MTK_APU_RUN_WAIT_CNT; + int ret; + + if (!hw_ops->start) { + WARN_ON(1); + return -EINVAL; + } + + ret = hw_ops->setup(apu); + if (ret) + goto stop; + + ret = hw_ops->start(apu); + if (ret) { + dev_err(dev, "failed to start APU\n"); + goto stop; + } + + while (wait_cnt > 0) { + /* check if boot success */ + ktime_get_ts64(&begin); + + ret = wait_event_interruptible_timeout(run->wq, run->signaled, + msecs_to_jiffies(MTK_APU_RUN_TIMEOUT)); + + ktime_get_ts64(&end); + + if (ret == 0) { + dev_err(dev, "APU initialization timeout!!\n"); + apu->bypass_pwr_off_chk = true; + goto stop; + } else if (ret == -ERESTARTSYS) { + dev_info(dev, "wait APU interrupted by a signal\n"); + wait_cnt -= 1; + } else { + break; + } + } + + if (wait_cnt == 0) { + dev_err(dev, "failed to wait APU interrupt\n"); + apu->bypass_pwr_off_chk = true; + goto stop; + } + + delta = timespec64_sub(end, begin); + dev_dbg(dev, "APU uP boot done. boot time: %llu s, %llu ns. fw_ver: %s\n", + (uint64_t)delta.tv_sec, (uint64_t)delta.tv_nsec, run->fw_ver); + + return 0; + +stop: + if (!hw_ops->stop) { + WARN_ON(1); + return -EINVAL; + } + hw_ops->stop(apu); + + return ret; +} + +static int mtk_apu_start(struct rproc *rproc) +{ + struct mtk_apu *apu = (struct mtk_apu *)rproc->priv; + int ret; + + if (!(apu->platdata->flags.secure_boot) || (apu->platdata->flags.map_iova)) + apu->apusys_sec_info = apu->apu_sec_mem_base + apu->up_code_buf_sz; + + ret = mtk_apu_config_setup(apu); + if (ret) + goto out_mtk_apu_start; + + ret = mtk_apu_dram_boot_init(apu); + if (ret) + goto remove_mtk_apu_config_setup; + + ret = mtk_apu_setup_sec_mem(apu); + if (ret) + goto remove_mtk_apu_dram_boot; + + dev_dbg(apu->dev, "%s: try to boot uP\n", __func__); + ret = __mtk_apu_run(rproc); + if (ret) + goto remove_mtk_apu_dram_boot; + + devm_iounmap(apu->dev, apu->resv_mem_va); + + return ret; + +remove_mtk_apu_dram_boot: + mtk_apu_dram_boot_remove(apu); + +remove_mtk_apu_config_setup: + mtk_apu_config_remove(apu); + +out_mtk_apu_start: + return ret; +} + +static int mtk_apu_stop(struct rproc *rproc) +{ + struct mtk_apu *apu = (struct mtk_apu *)rproc->priv; + const struct mtk_apu_hw_ops *hw_ops = &apu->platdata->ops; + int ret; + + if (!hw_ops->stop) { + WARN_ON(1); + return -EINVAL; + } + ret = hw_ops->stop(apu); + if (ret) { + dev_err(apu->dev, "Failed to stop APU\n"); + return ret; + } + + mtk_apu_dram_boot_remove(apu); + mtk_apu_config_remove(apu); + + return 0; +} + +static int mtk_apu_prepare(struct rproc *rproc) +{ + struct mtk_apu *apu = rproc->priv; + struct device_node *data_np; + struct resource r; + int ret = 0; + const struct mtk_apu_platdata *data; + const struct mtk_apu_hw_ops *hw_ops; + + data = of_device_get_match_data(apu->dev); + hw_ops = &data->ops; + + /* get reserved memory */ + data_np = of_parse_phandle(apu->pdev->dev.of_node, "memory-region", 0); + if (!data_np) { + dev_err(apu->dev, "No reserved memory region found.\n"); + return -EINVAL; + } + + ret = of_address_to_resource(data_np, 0, &r); + if (ret) { + dev_err(apu->dev, "failed to parse reserved memory: %d\n", ret); + of_node_put(data_np); + return ret; + } + of_node_put(data_np); + + apu->resv_mem_pa = r.start; + apu->resv_mem_va = devm_ioremap_wc(apu->dev, apu->resv_mem_pa, resource_size(&r)); + dev_dbg(apu->dev, "Reserved memory %pR mapped to %p\n\n", &r, apu->resv_mem_va); + memset_io(apu->resv_mem_va, 0, resource_size(&r)); + + ret = hw_ops->mtk_apu_memmap_init(apu); + if (ret) + return ret; + + ret = mtk_apu_mem_init(apu); + if (ret) + return ret; + + ret = mtk_apu_exception_init(apu->pdev, apu); + if (ret) + goto remove_apu_hw_logger_ipi; + + if (hw_ops->init) { + ret = hw_ops->init(apu); + if (ret) + goto remove_mtk_apu_exception; + } + + return ret; + +remove_mtk_apu_exception: + mtk_apu_exception_exit(apu->pdev, apu); + +remove_apu_hw_logger_ipi: + mtk_apu_hw_logger_ipi_remove(apu); + + return ret; +} + +static int mtk_apu_unprepare(struct rproc *rproc) +{ + struct mtk_apu *apu = rproc->priv; + + mtk_apu_exception_exit(apu->pdev, apu); + mtk_apu_hw_logger_ipi_remove(apu); + + return 0; +} + +static const struct rproc_ops mtk_apu_ops = { + .start = mtk_apu_start, + .stop = mtk_apu_stop, + .prepare = mtk_apu_prepare, + .unprepare = mtk_apu_unprepare, + .da_to_va = mtk_apu_da_to_va, +}; + +struct regmap *mtk_apu_get_mbox_regmap(struct device_node *node) +{ + struct device_node *mbox_node; + struct platform_device *mbox_pdev; + struct regmap *regmap = NULL; + + mbox_node = of_parse_phandle(node, "mediatek,mbox-spare-reg", 0); + if (!mbox_node) + return ERR_PTR(-ENODEV); + + mbox_pdev = of_find_device_by_node(mbox_node); + if (!mbox_pdev) { + regmap = ERR_PTR(-EPROBE_DEFER); + goto out_put_node; + } + + regmap = dev_get_regmap(&mbox_pdev->dev, NULL); + if (!regmap) + regmap = ERR_PTR(-EINVAL); + + platform_device_put(mbox_pdev); + +out_put_node: + of_node_put(mbox_node); + return regmap; +} + +static int mtk_apu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *hw_logger_np, *apu_power_np; + struct device_link *link; + struct rproc *rproc; + struct mtk_apu *apu; + const struct mtk_apu_platdata *data; + const struct mtk_apu_hw_ops *hw_ops; + struct regmap *regmap; + int ret = 0; + + data = of_device_get_match_data(dev); + hw_ops = &data->ops; + + rproc = devm_rproc_alloc(dev, np->name, &mtk_apu_ops, data->fw_name, sizeof(struct mtk_apu)); + if (!rproc) + return dev_err_probe(dev, -ENOMEM, "unable to allocate remoteproc\n"); + + rproc->auto_boot = data->flags.auto_boot; + rproc->sysfs_read_only = true; + + apu = rproc->priv; + apu->rproc = rproc; + apu->pdev = pdev; + apu->dev = dev; + apu->platdata = data; + platform_set_drvdata(pdev, apu); + + apu_power_np = of_parse_phandle(np, "mediatek,apu-power", 0); + if (!apu_power_np) + dev_err(dev, "failed to get mediatek,apu-power phandle\n"); + + apu->power_pdev = of_find_device_by_node(apu_power_np); + of_node_put(apu_power_np); + if (!apu->power_pdev) + return dev_err_probe(dev, -EPROBE_DEFER, "failed to find power device for mtk_apu\n"); + + link = device_link_add(dev, &apu->power_pdev->dev, DL_FLAG_PM_RUNTIME); + if (!link) + dev_err(dev, "Unable to create device link between mtk_apu and mtk apu power\n"); + + hw_logger_np = of_parse_phandle(np, "mediatek,hw-logger", 0); + if (!hw_logger_np) + dev_err(dev, "failed to get hw-logger phandle\n"); + + apu->hw_logger_data = get_mtk_apu_hw_logger_device(hw_logger_np); + + of_node_put(hw_logger_np); + + if (!apu->hw_logger_data || IS_ERR(apu->hw_logger_data)) { + dev_err(dev, "failed to get hw-logger data\n"); + ret = PTR_ERR(apu->hw_logger_data); + return dev_err_probe(dev, ret, "failed to get mtk_apu_hw_logger device: %d\n", + ret); + } + + regmap = mtk_apu_get_mbox_regmap(dev->of_node); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + return dev_err_probe(dev, ret, "failed to get mailbox regmap: %d\n", ret); + } + + apu->config_regmap_field = devm_regmap_field_alloc(dev, regmap, mtk_apu_config_reg_field); + if (IS_ERR(apu->config_regmap_field)) { + ret = PTR_ERR(apu->config_regmap_field); + return dev_err_probe(dev, ret, "failed to allocate config regmap field: %d\n", + ret); + } + + spin_lock_init(&apu->reg_lock); + + if (!hw_ops->mtk_apu_memmap_init) { + dev_err(dev, "%s: mtk_apu_memmap_init is not implemented\n", __func__); + return -EOPNOTSUPP; + } + + ret = rproc_add(rproc); + if (ret < 0) { + dev_err(dev, "boot fail ret:%d\n", ret); + goto err_put_device; + } + +err_put_device: + return ret; +} + +static int mtk_apu_resume(struct device *dev) +{ + struct mtk_apu *apu = dev_get_drvdata(dev); + const struct mtk_apu_hw_ops *hw_ops = &apu->platdata->ops; + + if (!hw_ops->resume) + return 0; + + return hw_ops->resume(apu); +} + +static int mtk_apu_suspend(struct device *dev) +{ + struct mtk_apu *apu = dev_get_drvdata(dev); + const struct mtk_apu_hw_ops *hw_ops = &apu->platdata->ops; + + if (!hw_ops->suspend) + return 0; + + return hw_ops->suspend(apu); +} + +extern const struct mtk_apu_platdata mt8196_platdata; +static const struct of_device_id mtk_apu_of_match[] = { + { .compatible = "mediatek,mt8196-apusys_rv", .data = &mt8196_platdata }, + {}, +}; +MODULE_DEVICE_TABLE(of, mtk_apu_of_match); + +static const struct dev_pm_ops mtk_apu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mtk_apu_suspend, mtk_apu_resume) +}; + +/* + * The kernel driver of the MediaTek APU will load the image into a specific + * reserved memory area and then protect the memory immediately after the loading is completed. + * Once the protection is set up, the kernel cannot access the memory to prevent + * non-secure operations. + * Hence, we do not support module removal in this driver because we cannot probe the APU again + * once the memory protection has been established. + */ +static struct platform_driver mtk_apu_driver = { + .probe = mtk_apu_probe, + .driver = { + .name = "mtk-apu", + .pm = &mtk_apu_pm_ops, + .suppress_bind_attrs = true, + .of_match_table = of_match_ptr(mtk_apu_of_match), + }, +}; + +int mtk_apu_rproc_init(void) +{ + int ret; + + ret = platform_driver_register(&mtk_apu_driver); + if (ret) + pr_err("failed to register mtk_apu_driver\n"); + + return ret; +} + +MODULE_IMPORT_NS(MTK_APU_PWR); + +MODULE_SOFTDEP("pre: mtk-apu-mailbox"); + +module_init(mtk_apu_rproc_init); +MODULE_DESCRIPTION("MTK APUSys Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h new file mode 100644 index 0000000000000..91f4b7d9eff52 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_RPROC_H +#define MTK_APU_RPROC_H + +#define MBOX_HOST_CONFIG_ADDR (0x48) + +#define CONFIG_SIZE (round_up(sizeof(struct mtk_apu_config_v1), PAGE_SIZE)) +#define DRAM_OFFSET (0x00000UL) +#define TCM_OFFSET (0x4d000000UL) +#define CODE_BUF_DA (DRAM_OFFSET) +#define MTK_APU_SEC_FW_IOVA (0x200000UL) +#define MDLA_RESERVE_MEM_SZ (0x10000) + +int mtk_apu_exception_init(struct platform_device *pdev, struct mtk_apu *apu); +void mtk_apu_exception_exit(struct platform_device *pdev, struct mtk_apu *apu); +uint32_t mtk_apu_rv_smc_call(struct device *dev, uint32_t smc_id, uint32_t a2); +struct regmap *mtk_apu_get_mbox_regmap(struct device_node *node); + +#endif /* MTK_APU_RPROC_H */ diff --git a/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c b/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c new file mode 100644 index 0000000000000..fcf7144d9ef80 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include "../mtk_apu_rproc.h" + + + +static int apu_setup_apummu(struct mtk_apu *apu) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU, 0); +} + +static int apu_setup_devapc(struct mtk_apu *apu) +{ + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, 0); +} + +static int apu_reset_mp(struct mtk_apu *apu) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, 0); +} + +static int apu_setup_boot(struct mtk_apu *apu) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, 0); +} + +static int mt8196_rproc_start(struct mtk_apu *apu) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, 0); +} + +static int mt8196_rproc_setup(struct mtk_apu *apu) +{ + int ret; + + ret = apu_setup_devapc(apu); + if (ret) { + dev_err(apu->dev, "Failed to setup devapc\n"); + return ret; + } + + ret = apu_setup_apummu(apu); + if (ret) { + dev_err(apu->dev, "Failed to setup apummu\n"); + return ret; + } + + ret = apu_reset_mp(apu); + if (ret) { + dev_err(apu->dev, "Failed to reset mp\n"); + return ret; + } + + ret = apu_setup_boot(apu); + if (ret) { + dev_err(apu->dev, "Failed to setup boot\n"); + return ret; + } + + return ret; +} + +static int mt8196_rproc_stop(struct mtk_apu *apu) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, 0); +} + +static int mt8196_apu_memmap_init(struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + + apu->md32_tcm = NULL; + + apu->apu_infra_hwsem = devm_ioremap(dev, 0x190b0e00, 0xff); + if (IS_ERR((void const *)apu->apu_infra_hwsem)) { + dev_err(dev, "%s: apu_infra_hwsem remap base fail\n", __func__); + return -ENOMEM; + } + + return 0; +} + +static int mt8196_rproc_init(struct mtk_apu *apu) +{ + apu->is_under_lp_scp_recovery_flow = false; + return 0; +} + +static int mt8196_apu_resume(struct mtk_apu *apu) +{ + mutex_lock(&apu->forbid_ipi_lock); + apu->forbid_ipi_send = false; + mutex_unlock(&apu->forbid_ipi_lock); + + return 0; +} + +static int mt8196_apu_suspend(struct mtk_apu *apu) +{ + int pwr_status = mtk_apu_get_rpc_pwr_status(apu->power_pdev) & 0x1; + + if (pwr_status) { + // Deny any incoming IPI + mutex_lock(&apu->forbid_ipi_lock); + apu->forbid_ipi_send = true; + mutex_unlock(&apu->forbid_ipi_lock); + + // Cancel current timer and do power off if needed + if (timer_pending(&apu->power_off_timer)) + del_timer(&apu->power_off_timer); + } + + return 0; +} + +const struct mtk_apu_platdata mt8196_platdata = { + .flags = { + .auto_boot = true, + .fast_on_off = true, + .infra_wa = true, + .kernel_load_image = true, + .map_iova = true, + .preload_firmware = true, + .secure_boot = true, + .secure_coredump = true, + .smmu_support = true, + }, + .config = { + .up_code_buf_sz = 0x100000, + .up_coredump_buf_sz = 0x160000, + .regdump_buf_sz = 0x10000, + .mdla_coredump_buf_sz = 0x0, + .mvpu_coredump_buf_sz = 0x0, + .mvpu_sec_coredump_buf_sz = 0x0, + .up_tcm_sz = 0x50000, + .ce_coredump_buf_sz = 0x10000 + }, + .ops = { + .init = mt8196_rproc_init, + .start = mt8196_rproc_start, + .setup = mt8196_rproc_setup, + .stop = mt8196_rproc_stop, + .mtk_apu_memmap_init = mt8196_apu_memmap_init, + .suspend = mt8196_apu_suspend, + .resume = mt8196_apu_resume, + }, + .fw_name = "mediatek/mt8196/apusys.img", +}; diff --git a/include/linux/remoteproc/mtk_apu.h b/include/linux/remoteproc/mtk_apu.h index b9c52690bdc5d..66e49cae022c9 100644 --- a/include/linux/remoteproc/mtk_apu.h +++ b/include/linux/remoteproc/mtk_apu.h @@ -5,6 +5,61 @@ #ifndef MTK_APU_H #define MTK_APU_H +#include +#include +#include +#include + +#include +#include + +struct mtk_apu; + +struct mtk_apu_hw_ops { + int (*init)(struct mtk_apu *apu); + int (*exit)(struct mtk_apu *apu); + int (*start)(struct mtk_apu *apu); + int (*setup)(struct mtk_apu *apu); + int (*stop)(struct mtk_apu *apu); + int (*mtk_apu_memmap_init)(struct mtk_apu *apu); + void (*mtk_apu_memmap_remove)(struct mtk_apu *apu); + int (*power_on_off)(struct mtk_apu *apu, u32 id, u32 on, u32 off); + + int (*suspend)(struct mtk_apu *apu); + int (*resume)(struct mtk_apu *apu); +}; + +struct mtk_apu_plat_config { + uint64_t up_code_buf_sz; + uint64_t up_coredump_buf_sz; + uint64_t regdump_buf_sz; + uint64_t mdla_coredump_buf_sz; + uint64_t mvpu_coredump_buf_sz; + uint64_t mvpu_sec_coredump_buf_sz; + uint64_t up_tcm_sz; + uint64_t ce_coredump_buf_sz; +}; + +struct mtk_apu_flag { + bool auto_boot; + bool bypass_iommu; + bool debug_log_on; + bool fast_on_off; + bool infra_wa; + bool kernel_load_image; + bool map_iova; + bool preload_firmware; + bool secure_boot; + bool secure_coredump; + bool smmu_support; +}; + +struct mtk_apu_platdata { + struct mtk_apu_flag flags; + struct mtk_apu_plat_config config; + struct mtk_apu_hw_ops ops; + char *fw_name; +}; struct apusys_secure_info_t { unsigned int total_sz; @@ -43,4 +98,89 @@ struct apusys_secure_info_t { unsigned int ce_bin_sz; }; +struct mtk_apu { + struct rproc *rproc; + struct platform_device *pdev; + struct device *dev; + void *md32_tcm; + void *apu_rpc; + void *apu_infra_hwsem; + void *apu_sec_mem_base; + int wdt_irq_number; + spinlock_t reg_lock; + + struct apusys_secure_info_t *apusys_sec_info; + uint64_t apusys_sec_mem_start; + uint64_t apusys_sec_mem_size; + + /* Buffer to place execution area */ + void *code_buf; + dma_addr_t code_da; + + /* hw_logger */ + struct mtk_apu_hw_logger *hw_logger_data; + + /* mailbox */ + struct mbox_client cl; + struct mbox_chan *ch; + + /* Buffer to place config area */ + struct mtk_apu_config_v1 *conf_buf; + dma_addr_t conf_da; + + /* to synchronize boot status of remote processor */ + struct mtk_apu_run run; + + /* to prevent multiple ipi_send run concurrently */ + struct mutex send_lock; + struct mutex power_lock; + struct mutex forbid_ipi_lock; + spinlock_t usage_cnt_lock; + struct mtk_apu_ipi_desc ipi_desc[MTK_APU_IPI_MAX]; + u32 ipi_id; + bool ipi_id_ack[MTK_APU_IPI_MAX]; /* per-ipi ack */ + bool ipi_inbound_locked; + bool bypass_pwr_off_chk; + wait_queue_head_t ack_wq; /* for waiting for ipi ack */ + bool forbid_ipi_send; /* Forbid ipi sending request when system want to suspend */ + + /* ipi share buffer */ + dma_addr_t recv_buf_da; + struct mtk_share_obj *recv_buf; + dma_addr_t send_buf_da; + struct mtk_share_obj *send_buf; + struct mtk_ipi_task ipi_task; + + struct rproc_subdev *rpmsg_subdev; + + const struct mtk_apu_platdata *platdata; + + /* timesync workqueue */ + struct work_struct timesync_work; + struct workqueue_struct *timesync_workq; + + uint32_t up_code_buf_sz; + uint32_t local_pwr_ref_cnt; + uint32_t ipi_pwr_ref_cnt[MTK_APU_IPI_MAX]; + + /* reserved memory */ + uint64_t resv_mem_pa; + void *resv_mem_va; + + /* delay power off */ + struct timer_list power_off_timer; + uint64_t cur_dtime_ts; + + struct regmap_field *config_regmap_field; + + const struct firmware *fw; + struct platform_device *power_pdev; + + bool is_under_lp_scp_recovery_flow; +}; + +int mtk_apu_config_setup(struct mtk_apu *apu); +void mtk_apu_config_remove(struct mtk_apu *apu); +int mtk_apu_mem_init(struct mtk_apu *apu); + #endif /* MTK_APU_H */ -- GitLab From b513ef1e0b57ef41afee7dd680d23c38c842460c Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 13:45:01 +0800 Subject: [PATCH 423/456] CHROMIUM: remoteproc: mediatek: Add APU firmware loading The APU firmware is loaded and booted from the kernel side. This patch add the function to load APU firmware. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I98475c3e7eef78bed024473b5583421f537cabd2 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166784 Commit-Queue: Chen-Yu Tsai Reviewed-by: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Tested-by: Chen-Yu Tsai Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- .../mediatek_apusys/mtk_apu_loadimage.c | 326 ++++++++++++++++++ .../mediatek_apusys/mtk_apu_rproc.c | 1 + include/linux/remoteproc/mtk_apu.h | 2 + 3 files changed, 329 insertions(+) create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_loadimage.c diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_loadimage.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_loadimage.c new file mode 100644 index 0000000000000..e349e69aa0fb0 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_loadimage.c @@ -0,0 +1,326 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include + +#include +#include +#include + +#include "mtk_apu_rproc.h" + +#define MTK_APU_FW_HEADER_OFFSET (0x200) + +static int mtk_apusys_rv_load_fw(struct apusys_secure_info_t *sec_info, + void *sec_mem_addr_va, struct mtk_apu *apu, + const struct firmware *fw) +{ + unsigned int apusys_pmsize, apusys_xsize; + const void *apusys_pmimg, *apusys_ximg; + void *tmp_addr; + const void *img; + const struct ptimg_hdr_t *hdr; + unsigned int *img_size; + + /* initialize apusys sec_info */ + tmp_addr = sec_info->up_code_buf_ofs + sec_info->up_code_buf_sz + + sec_mem_addr_va + roundup(sizeof(*sec_info), APUSYS_FW_ALIGN); + + /* separate ptimg */ + apusys_pmimg = apusys_ximg = NULL; + apusys_pmsize = apusys_xsize = 0; + + hdr = (const struct ptimg_hdr_t *)(fw->data + MTK_APU_FW_HEADER_OFFSET); + dev_dbg(apu->dev, "%s: hdr->magic is 0x%x\n", __func__, hdr->magic); + img_size = (void *)fw->data + (0x4); + dev_dbg(apu->dev, "%s: apu_partition_sz is 0x%x\n", __func__, *img_size); + memcpy_toio(tmp_addr, ((void *)fw->data + (MTK_APU_FW_HEADER_OFFSET)), (*img_size)); + + hdr = tmp_addr; + + while (hdr->magic == PT_MAGIC) { + img = ((const void *) hdr) + hdr->hdr_size; + dev_dbg(apu->dev, "Rhdr->hdr_size= 0x%x\n", hdr->hdr_size); + dev_dbg(apu->dev, "img address is %p\n", img); + + switch (hdr->id) { + case PT_ID_APUSYS_FW: + dev_dbg(apu->dev, "PT_ID_APUSYS_FW\n"); + apusys_pmimg = img; + apusys_pmsize = hdr->img_size; + sec_info->up_fw_ofs = (u64)img - (u64)sec_mem_addr_va; + sec_info->up_fw_sz = apusys_pmsize; + dev_dbg(apu->dev, "up_fw_ofs = 0x%x, up_fw_sz = 0x%x\n", + sec_info->up_fw_ofs, sec_info->up_fw_sz); + break; + case PT_ID_APUSYS_XFILE: + dev_dbg(apu->dev, "PT_ID_APUSYS_XFILE\n"); + apusys_ximg = img; + apusys_xsize = hdr->img_size; + sec_info->up_xfile_ofs = (u64)hdr - (u64)sec_mem_addr_va; + sec_info->up_xfile_sz = hdr->hdr_size + apusys_xsize; + dev_dbg(apu->dev, "up_xfile_ofs = 0x%x, up_xfile_sz = 0x%x\n", + sec_info->up_xfile_ofs, sec_info->up_xfile_sz); + break; + case PT_ID_MDLA_FW_BOOT: + dev_dbg(apu->dev, "PT_ID_MDLA_FW_BOOT\n"); + sec_info->mdla_fw_boot_ofs = (u64)img - (u64)sec_mem_addr_va; + sec_info->mdla_fw_boot_sz = hdr->img_size; + dev_dbg(apu->dev, "mdla_fw_boot_ofs = 0x%x, mdla_fw_boot_sz = 0x%x\n", + sec_info->mdla_fw_boot_ofs, + sec_info->mdla_fw_boot_sz); + break; + case PT_ID_MDLA_FW_MAIN: + dev_dbg(apu->dev, "PT_ID_MDLA_FW_MAIN\n"); + sec_info->mdla_fw_main_ofs = (u64)img - (u64)sec_mem_addr_va; + sec_info->mdla_fw_main_sz = hdr->img_size; + dev_dbg(apu->dev, "mdla_fw_main_ofs = 0x%x, mdla_fw_main_sz = 0x%x\n", + sec_info->mdla_fw_main_ofs, + sec_info->mdla_fw_main_sz); + break; + case PT_ID_MDLA_XFILE: + dev_dbg(apu->dev, "PT_ID_MDLA_XFILE\n"); + sec_info->mdla_xfile_ofs = (u64)hdr - (u64)sec_mem_addr_va; + sec_info->mdla_xfile_sz = hdr->hdr_size + hdr->img_size; + dev_dbg(apu->dev, "mdla_xfile_ofs = 0x%x, mdla_xfile_sz = 0x%x\n", + sec_info->mdla_xfile_ofs, + sec_info->mdla_xfile_sz); + break; + case PT_ID_MVPU_FW: + dev_dbg(apu->dev, "PT_ID_MVPU_FW\n"); + sec_info->mvpu_fw_ofs = (u64)img - (u64)sec_mem_addr_va; + sec_info->mvpu_fw_sz = hdr->img_size; + dev_dbg(apu->dev, "mvpu_fw_ofs = 0x%x, mvpu_fw_sz = 0x%x\n", + sec_info->mvpu_fw_ofs, sec_info->mvpu_fw_sz); + break; + case PT_ID_MVPU_XFILE: + dev_dbg(apu->dev, "PT_ID_MVPU_XFILE\n"); + sec_info->mvpu_xfile_ofs = (u64)hdr - (u64)sec_mem_addr_va; + sec_info->mvpu_xfile_sz = hdr->hdr_size + hdr->img_size; + dev_dbg(apu->dev, "mvpu_xfile_ofs = 0x%x, mvpu_xfile_sz = 0x%x\n", + sec_info->mvpu_xfile_ofs, + sec_info->mvpu_xfile_sz); + break; + case PT_ID_MVPU_SEC_FW: + dev_dbg(apu->dev, "PT_ID_MVPU_SEC_FW\n"); + sec_info->mvpu_sec_fw_ofs = (u64)img - (u64)sec_mem_addr_va; + sec_info->mvpu_sec_fw_sz = hdr->img_size; + dev_dbg(apu->dev, "mvpu_sec_fw_ofs = 0x%x, mvpu_sec_fw_sz = 0x%x\n", + sec_info->mvpu_sec_fw_ofs, + sec_info->mvpu_sec_fw_sz); + break; + case PT_ID_MVPU_SEC_XFILE: + dev_dbg(apu->dev, "PT_ID_MVPU_SEC_XFILE\n"); + sec_info->mvpu_sec_xfile_ofs = (u64)hdr - (u64)sec_mem_addr_va; + sec_info->mvpu_sec_xfile_sz = hdr->hdr_size + hdr->img_size; + dev_dbg(apu->dev, "mvpu_sec_xfile_ofs = 0x%x, mvpu_sec_xfile_sz = 0x%x\n", + sec_info->mvpu_sec_xfile_ofs, + sec_info->mvpu_sec_xfile_sz); + break; + case PT_ID_CE_BIN: + dev_dbg(apu->dev, "PT_ID_CE_BIN\n"); + sec_info->ce_bin_ofs = (uint64_t) img - (uint64_t) sec_mem_addr_va; + sec_info->ce_bin_sz = hdr->hdr_size + hdr->img_size; + dev_dbg(apu->dev, "ce_bin_ofs = 0x%x, ce_bin_sz = 0x%x\n", + sec_info->ce_bin_ofs, sec_info->ce_bin_sz); + break; + case PT_ID_CE_BIN_DUMMY: + /* dummy image do nothing */ + break; + default: + dev_warn(apu->dev, "Ignore unknown APUSYS image %d\n", hdr->id); + break; + } + + dev_dbg(apu->dev, "hdr->img_size = 0x%x, roundup(hdr->img_size, hdr->align) = 0x%x\n", + hdr->img_size, roundup(hdr->img_size, hdr->align)); + img += roundup(hdr->img_size, hdr->align); + hdr = (const struct ptimg_hdr_t *)img; + } + + if (!apusys_pmimg || !apusys_ximg) { + dev_err(apu->dev, "APUSYS partition missing - PM: %p, XM: %p (@%p)\n", + apusys_pmimg, apusys_ximg, tmp_addr); + return -ENOENT; + } + + dev_dbg(apu->dev, "APUSYS part load finished: PM: %p(up_fw_ofs = 0x%x), XM: %p(up_xfile_ofs = 0x%x)\n", + apusys_pmimg, sec_info->up_fw_ofs, apusys_ximg, sec_info->up_xfile_ofs); + + return 0; +} + +static int mtk_apusys_rv_fill_sec_info(struct apusys_secure_info_t *sec_info, + const struct mtk_apu_plat_config *config, + uint64_t apusys_part_size, struct mtk_apu *apu) +{ + uint64_t coredump_buf_sz = 0, sec_mem_sz = 0; + + sec_info->up_code_buf_ofs = 0; + apu->up_code_buf_sz = config->up_code_buf_sz; + sec_info->up_code_buf_sz = config->up_code_buf_sz; + dev_dbg(apu->dev, "%s: up_code_buf_sz is 0x%x\n", __func__, sec_info->up_code_buf_sz); + + sec_info->up_coredump_ofs = sec_info->up_code_buf_ofs + sec_info->up_code_buf_sz + + apusys_part_size - MTK_APU_FW_HEADER_OFFSET; + sec_info->up_coredump_sz = config->up_coredump_buf_sz; + dev_dbg(apu->dev, "%s: up_coredump_ofs is 0x%x, up_coredump_sz is 0x%x\n", + __func__, sec_info->up_coredump_ofs, sec_info->up_coredump_sz); + + sec_info->mdla_coredump_ofs = sec_info->up_coredump_ofs + sec_info->up_coredump_sz; + sec_info->mdla_coredump_sz = config->mdla_coredump_buf_sz; + dev_dbg(apu->dev, "%s: mdla_coredump_ofs is 0x%x, mdla_coredump_sz is 0x%x\n", + __func__, sec_info->mdla_coredump_ofs, sec_info->mdla_coredump_sz); + + sec_info->mvpu_coredump_ofs = sec_info->mdla_coredump_ofs + sec_info->mdla_coredump_sz; + sec_info->mvpu_coredump_sz = config->mvpu_coredump_buf_sz; + dev_dbg(apu->dev, "%s: mvpu_coredump_ofs is 0x%x, mvpu_coredump_sz is 0x%x\n", + __func__, sec_info->mvpu_coredump_ofs, sec_info->mvpu_coredump_sz); + + sec_info->mvpu_sec_coredump_ofs = sec_info->mvpu_coredump_ofs + sec_info->mvpu_coredump_sz; + sec_info->mvpu_sec_coredump_sz = config->mvpu_sec_coredump_buf_sz; + dev_dbg(apu->dev, "%s: mvpu_sec_coredump_ofs is 0x%x, mvpu_sec_coredump_sz is 0x%x\n", + __func__, sec_info->mvpu_sec_coredump_ofs, sec_info->mvpu_sec_coredump_sz); + + coredump_buf_sz = sec_info->up_coredump_sz + sec_info->mdla_coredump_sz + + sec_info->mvpu_coredump_sz + sec_info->mvpu_sec_coredump_sz + + config->ce_coredump_buf_sz; + + sec_mem_sz = roundup(apusys_part_size - MTK_APU_FW_HEADER_OFFSET + + sec_info->up_code_buf_sz + coredump_buf_sz, + MTK_APUSYS_SEC_MEM_ALIGN); + + sec_info->total_sz = sec_mem_sz; + + return 0; +} + +static void mtk_apusys_rv_initialize_sec_buf(struct apusys_secure_info_t *sec_info, + void *sec_mem_addr_va) +{ + struct apusys_secure_info_t *sec_info_ptr = + sec_mem_addr_va + sec_info->up_code_buf_ofs + sec_info->up_code_buf_sz; + uint32_t offset = sec_info->up_code_buf_ofs; + + sec_info_ptr->total_sz = sec_info->total_sz; + + /* copy uP firmware to code buffer */ + sec_info_ptr->up_code_buf_ofs = offset; + sec_info_ptr->up_code_buf_sz = sec_info->up_fw_sz; + memcpy(sec_mem_addr_va + offset, sec_mem_addr_va + sec_info->up_fw_ofs, sec_info->up_fw_sz); + offset += sec_info->up_code_buf_sz + + roundup(sizeof(struct apusys_secure_info_t), APUSYS_FW_ALIGN); + + /* copy MDLA_BOOT firmware */ + sec_info_ptr->mdla_fw_boot_ofs = offset; + sec_info_ptr->mdla_fw_boot_sz = sec_info->mdla_fw_boot_sz; + memcpy(sec_mem_addr_va + offset, + sec_mem_addr_va + sec_info->mdla_fw_boot_ofs, sec_info->mdla_fw_boot_sz); + offset += sec_info->mdla_fw_boot_sz; + + /* copy MDLA_MAIN firmware */ + sec_info_ptr->mdla_fw_main_ofs = offset; + sec_info_ptr->mdla_fw_main_sz = sec_info->mdla_fw_main_sz; + memcpy(sec_mem_addr_va + offset, + sec_mem_addr_va + sec_info->mdla_fw_main_ofs, sec_info->mdla_fw_main_sz); + offset += sec_info->mdla_fw_main_sz; + + /* copy MVPU firmware */ + sec_info_ptr->mvpu_fw_ofs = offset; + sec_info_ptr->mvpu_fw_sz = sec_info->mvpu_fw_sz; + memcpy(sec_mem_addr_va + offset, + sec_mem_addr_va + sec_info->mvpu_fw_ofs, sec_info->mvpu_fw_sz); + offset += sec_info->mvpu_fw_sz; + + /* copy MVPU_SEC firmware */ + sec_info_ptr->mvpu_sec_fw_ofs = offset; + sec_info_ptr->mvpu_sec_fw_sz = sec_info->mvpu_sec_fw_sz; + memcpy(sec_mem_addr_va + offset, + sec_mem_addr_va + sec_info->mvpu_sec_fw_ofs, sec_info->mvpu_sec_fw_sz); + offset += sec_info->mvpu_sec_fw_sz; + + /* copy CE firmware */ + sec_info_ptr->ce_bin_ofs = offset; + sec_info_ptr->ce_bin_sz = sec_info->ce_bin_sz; + memcpy(sec_mem_addr_va + offset, + sec_mem_addr_va + sec_info->ce_bin_ofs, sec_info->ce_bin_sz); + offset += sec_info->ce_bin_sz; + + sec_info_ptr->up_coredump_ofs = offset; + sec_info_ptr->up_coredump_sz = sec_info->up_coredump_sz; + offset += sec_info->up_coredump_sz; + + sec_info_ptr->mdla_coredump_ofs = offset; + sec_info_ptr->mdla_coredump_sz = sec_info->mdla_coredump_sz; + offset += sec_info->mdla_coredump_sz; + + sec_info_ptr->mvpu_coredump_ofs = offset; + sec_info_ptr->mvpu_coredump_sz = sec_info->mvpu_coredump_sz; + offset += sec_info->mvpu_coredump_sz; + + sec_info_ptr->mvpu_sec_coredump_ofs = offset; + sec_info_ptr->mvpu_sec_coredump_sz = sec_info->mvpu_sec_coredump_sz; + offset += sec_info->mvpu_sec_coredump_sz; +} + +int mtk_apu_load(struct rproc *rproc, const struct firmware *fw) +{ + int ret = 0; + struct apusys_secure_info_t *sec_info = NULL; + unsigned int sec_mem_size = 0; + size_t apusys_part_size = 0; + struct mtk_apu *apu = rproc->priv; + struct mtk_apu_plat_config config = apu->platdata->config; + + /* allocate sec_info memory */ + sec_info = kzalloc(sizeof(struct apusys_secure_info_t), GFP_KERNEL); + if (!sec_info) + return -ENOMEM; + + apusys_part_size = fw->size; + dev_dbg(apu->dev, "%s: apusys_part_size is 0x%zx\n", __func__, apusys_part_size); + + ret = mtk_apusys_rv_fill_sec_info(sec_info, &config, apusys_part_size, apu); + if (ret) { + dev_err(apu->dev, "%s: mtk_apusys_rv_fill_sec_info failed: %d\n", __func__, ret); + goto err_apusys_rv_get_buf_sz; + } + + ret = mtk_apusys_rv_load_fw(sec_info, apu->resv_mem_va, apu, fw); + if (ret) { + dev_err(apu->dev, "%s: mtk_apusys_rv_load_fw failed: %d\n", __func__, ret); + goto err_apusys_rv_get_buf_sz; + } + + mtk_apusys_rv_initialize_sec_buf(sec_info, apu->resv_mem_va); + + if (sec_info->ce_bin_sz) { + ret = mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN, 0); + if (ret) { + dev_err(apu->dev, "%s: load ce bin failed, ret = %d\n", __func__, ret); + goto err_apusys_rv_get_buf_sz; + } + } + + /* calc apu aee coredump mem info */ + sec_mem_size = sec_info->total_sz; + + /* set memory addr,size to mtk_apu */ + apu->apusys_sec_mem_start = apu->resv_mem_pa; + apu->apusys_sec_mem_size = sec_mem_size; + apu->apu_sec_mem_base = apu->resv_mem_va; + dev_dbg(apu->dev, "%s: apu_apusys-rv_secure: start = 0x%llx, size = 0x%llx\n", + __func__, apu->apusys_sec_mem_start, apu->apusys_sec_mem_size); + + kfree(sec_info); + + return ret; + +err_apusys_rv_get_buf_sz: + kfree(sec_info); + + return ret; +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c index 0cd0eb6835162..8246dd418ed5f 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -331,6 +331,7 @@ static int mtk_apu_unprepare(struct rproc *rproc) static const struct rproc_ops mtk_apu_ops = { .start = mtk_apu_start, .stop = mtk_apu_stop, + .load = mtk_apu_load, .prepare = mtk_apu_prepare, .unprepare = mtk_apu_unprepare, .da_to_va = mtk_apu_da_to_va, diff --git a/include/linux/remoteproc/mtk_apu.h b/include/linux/remoteproc/mtk_apu.h index 66e49cae022c9..7409af3e00505 100644 --- a/include/linux/remoteproc/mtk_apu.h +++ b/include/linux/remoteproc/mtk_apu.h @@ -183,4 +183,6 @@ int mtk_apu_config_setup(struct mtk_apu *apu); void mtk_apu_config_remove(struct mtk_apu *apu); int mtk_apu_mem_init(struct mtk_apu *apu); +int mtk_apu_load(struct rproc *rproc, const struct firmware *fw); + #endif /* MTK_APU_H */ -- GitLab From ba8c35afc65109319fb1382df7569402d377f748 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 13:54:54 +0800 Subject: [PATCH 424/456] CHROMIUM: remoteproc: mediatek: Add APU IPI The kernel and tinysys utilize IPI for message transmission and reception. This patch add the APU IPI system to enable the communication between kernel and tinysys. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I657630b4d19d96a34a49208e02c85d5b79651581 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166785 Commit-Queue: Chen-Yu Tsai Tested-by: Chen-Yu Tsai Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../remoteproc/mediatek_apusys/mtk_apu_ipi.c | 505 ++++++++++++++++++ .../mediatek_apusys/mtk_apu_ipi_config.h | 155 ++++++ .../mediatek_apusys/mtk_apu_rproc.c | 11 +- .../mediatek_apusys/mtk_apu_rproc.h | 4 + include/linux/remoteproc/mtk_apu.h | 11 + include/linux/remoteproc/mtk_apu_ipi.h | 82 +++ include/linux/rpmsg/mtk_rpmsg.h | 1 + 7 files changed, 766 insertions(+), 3 deletions(-) create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_ipi_config.h create mode 100644 include/linux/remoteproc/mtk_apu_ipi.h diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c new file mode 100644 index 0000000000000..9c09342a43f0c --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c @@ -0,0 +1,505 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include "mtk_apu_ipi_config.h" +#include "mtk_apu_rproc.h" + +#define MTK_APU_MBOX_SEND_CNT (4) +#define MTK_APU_MBOX_TIMEOUT (1000) + +struct mtk_apu_mbox_hdr { + unsigned int id; + unsigned int len; + unsigned int serial_no; + unsigned int csum; +}; +struct mtk_apu_mbox_send_hdr { + u8 send_cnt; + struct mtk_apu_mbox_hdr *hdr; +}; + +static uint32_t calculate_csum(void *data, uint32_t len) +{ + uint32_t csum = 0, res = 0, i; + uint8_t *ptr; + + for (i = 0; i < (len / sizeof(csum)); i++) + csum += *(((uint32_t *)data) + i); + + ptr = (uint8_t *)data + len / sizeof(csum) * sizeof(csum); + for (i = 0; i < (len % sizeof(csum)); i++) + res |= *(ptr + i) << i * 8; + + csum += res; + + return csum; +} + +static inline bool bypass_check(u32 id) +{ + /* whitelist IPI used in power off flow */ + return id == MTK_APU_IPI_DEEP_IDLE; +} + +static void ipi_usage_cnt_update(struct mtk_apu *apu, u32 id, int diff) +{ + struct mtk_apu_ipi_desc *ipi = &apu->ipi_desc[id]; + + if (ipi_attrs[id].ack != IPI_WITH_ACK) + return; + + spin_lock(&apu->usage_cnt_lock); + ipi->usage_cnt += diff; + spin_unlock(&apu->usage_cnt_lock); +} + +static int mtk_apu_ipi_check(struct mtk_apu *apu, u32 id, void *data, u32 len) +{ + bool forbid_ipi_send; + + if (!apu || id <= MTK_APU_IPI_INIT || id >= MTK_APU_IPI_MAX || + id == MTK_APU_IPI_NS_SERVICE || len > MTK_APU_SHARE_BUFFER_SIZE || !data) + return -EINVAL; + + mutex_lock(&apu->forbid_ipi_lock); + forbid_ipi_send = apu->forbid_ipi_send; + mutex_unlock(&apu->forbid_ipi_lock); + + if (forbid_ipi_send) + return -ESHUTDOWN; + + if (!apu->platdata->flags.fast_on_off && !pm_runtime_enabled(apu->dev)) { + dev_err(apu->dev, "%s: rpm disabled, ipi=%d\n", __func__, id); + return -EBUSY; + } + + if (ipi_attrs[id].direction == IPI_HOST_INITIATE && + apu->ipi_inbound_locked == IPI_LOCKED && !bypass_check(id)) { + return -EAGAIN; + } + + return 0; +} + +int mtk_apu_ipi_send(struct mtk_apu *apu, u32 id, void *data, u32 len, u32 wait_ms) +{ + struct timespec64 ts, te; + struct mtk_apu_mbox_send_hdr send_hdr; + unsigned long timeout; + int ret = 0; + + if (apu->platdata->flags.fast_on_off && ipi_attrs[id].direction == IPI_HOST_INITIATE) + mtk_apu_power_on_off(apu->pdev, id, 1, 0); + + ktime_get_ts64(&ts); + + mutex_lock(&apu->send_lock); + ret = mtk_apu_ipi_check(apu, id, data, len); + + if (ret) { + mutex_unlock(&apu->send_lock); + return ret; + } + + /* + * copy message payload to share buffer, need to do cache flush if + * the buffer is cacheable. currently not + */ + memcpy(apu->send_buf, data, len); + + send_hdr.hdr = kzalloc(sizeof(*send_hdr.hdr), GFP_KERNEL); + + send_hdr.send_cnt = MTK_APU_MBOX_SEND_CNT; + send_hdr.hdr->id = id; + send_hdr.hdr->len = len; + send_hdr.hdr->csum = calculate_csum(data, len); + send_hdr.hdr->serial_no = apu->tx_serial_no++; + + ipi_usage_cnt_update(apu, id, 1); + + ret = mbox_send_message(apu->ch, &send_hdr); + if (ret < 0) { + dev_err(apu->dev, "%s: failed to send msg, ret=%d\n", __func__, ret); + goto unlock_mutex; + } else { + ret = 0; + } + + apu->ipi_id = id; + apu->ipi_id_ack[id] = false; + + /* poll ack from remote processor if wait_ms specified */ + if (wait_ms) { + timeout = jiffies + msecs_to_jiffies(wait_ms); + ret = wait_event_timeout(apu->ack_wq, apu->ipi_id_ack[id], timeout); + + apu->ipi_id_ack[id] = false; + + if (WARN(!ret, "apu ipi %d ack timeout!", id)) { + ret = -EIO; + goto unlock_mutex; + } else { + ret = 0; + } + } + +unlock_mutex: + kfree(send_hdr.hdr); + mutex_unlock(&apu->send_lock); + ktime_get_ts64(&te); + ts = timespec64_sub(te, ts); + + dev_dbg(apu->dev, "%s: ipi_id=%d, len=%d, csum=%x, serial_no=%d, elapse=%lld\n", + __func__, id, len, send_hdr.hdr->csum, send_hdr.hdr->serial_no, + timespec64_to_ns(&ts)); + + return ret; +} + +int mtk_apu_ipi_register(struct mtk_apu *apu, u32 id, ipi_top_handler_t top_handler, + ipi_handler_t handler, void *priv) +{ + if (!apu || id >= MTK_APU_IPI_MAX || WARN_ON(!top_handler && !handler)) { + if (apu) + dev_err(apu->dev, "%s failed. apu=%ps, id=%d, handler=%ps, priv=%p\n", + __func__, apu, id, handler, priv); + return -EINVAL; + } + + dev_dbg(apu->dev, "%s: ipi=%d, handler=%p, priv=%p", __func__, id, handler, priv); + + mutex_lock(&apu->ipi_desc[id].lock); + apu->ipi_desc[id].top_handler = top_handler; + apu->ipi_desc[id].handler = handler; + apu->ipi_desc[id].priv = priv; + mutex_unlock(&apu->ipi_desc[id].lock); + + return 0; +} + +void mtk_apu_ipi_unregister(struct mtk_apu *apu, u32 id) +{ + if (!apu || id >= MTK_APU_IPI_MAX) { + if (apu != NULL) + dev_err(apu->dev, "%s: invalid id=%d\n", __func__, id); + return; + } + + mutex_lock(&apu->ipi_desc[id].lock); + apu->ipi_desc[id].top_handler = NULL; + apu->ipi_desc[id].handler = NULL; + apu->ipi_desc[id].priv = NULL; + mutex_unlock(&apu->ipi_desc[id].lock); +} + +static int mtk_apu_init_ipi_top_handler(void *data, unsigned int len, void *priv) +{ + struct mtk_apu *apu = priv; + + strscpy(apu->run.fw_ver, data, MTK_APU_FW_VER_LEN); + + apu->run.signaled = 1; + wake_up_interruptible(&apu->run.wq); + + return IRQ_HANDLED; +} + +static void mtk_apu_init_ipi_bottom_handler(void *data, unsigned int len, void *priv) +{ + struct mtk_apu *apu = priv; + int ret; + + strscpy(apu->run.fw_ver, data, MTK_APU_FW_VER_LEN); + + apu->run.signaled = 1; + wake_up_interruptible(&apu->run.wq); + + ret = mtk_apu_power_on_off(apu->pdev, MTK_APU_IPI_INIT, 0, 1); + if (ret) + dev_err(apu->dev, "%s: call mtk_apu_power_on_off fail(%d)\n", __func__, ret); +} + +static void mtk_apu_ipi_bottom_handle(struct mbox_client *cl, void *mssg) +{ + struct mtk_apu *apu = container_of(cl, struct mtk_apu, cl); + int id, len; + + struct device *dev = apu->dev; + ipi_handler_t handler; + + id = apu->ipi_task.id; + len = apu->ipi_task.len; + + if (id < 0 || id >= MTK_APU_IPI_MAX) { + dev_err(apu->dev, "IPI id=%d is out of range", id); + return; + } + + mutex_lock(&apu->ipi_desc[id].lock); + + handler = apu->ipi_desc[id].handler; + if (!handler) { + dev_err(dev, "IPI id=%d is not registered", id); + mutex_unlock(&apu->ipi_desc[id].lock); + } + + apu->current_ipi_handler_id = id; + + handler(apu->temp_buf, len, apu->ipi_desc[id].priv); + + ipi_usage_cnt_update(apu, id, -1); + + apu->current_ipi_handler_id = -1; + + mutex_unlock(&apu->ipi_desc[id].lock); + + apu->ipi_id_ack[id] = true; + + wake_up(&apu->ack_wq); + + if (apu->platdata->flags.fast_on_off && ipi_attrs[id].direction == IPI_HOST_INITIATE) + mtk_apu_power_on_off(apu->pdev, id, 0, 1); +} + +static void mtk_apu_ipi_handle_rx(struct mbox_client *cl, void *mssg) +{ + struct mtk_apu *apu = container_of(cl, struct mtk_apu, cl); + struct mtk_share_obj *recv_obj = apu->recv_buf; + struct mtk_apu_mbox_hdr *hdr = mssg; + u32 calc_csum; + struct device *dev = apu->dev; + ipi_top_handler_t top_handler; + int ret; + + if (hdr->id >= MTK_APU_IPI_MAX) { + dev_err(dev, "no such IPI id = %d\n", hdr->id); + apu->ipi_task.id = -1; + return; + } + + if (hdr->len > MTK_APU_SHARE_BUFFER_SIZE) { + dev_err(dev, "IPI message too long(len %d, max %d)\n", + hdr->len, MTK_APU_SHARE_BUFFER_SIZE); + apu->ipi_task.id = -1; + return; + } + + if (hdr->serial_no != apu->rx_serial_no) { + dev_warn(dev, "unmatched serial_no: curr=%u, recv=%u\n", + apu->rx_serial_no, hdr->serial_no); + /* correct the serial no. */ + apu->rx_serial_no = hdr->serial_no; + } + apu->rx_serial_no++; + + memcpy(apu->temp_buf, &recv_obj->share_buf, hdr->len); + + calc_csum = calculate_csum(apu->temp_buf, hdr->len); + if (calc_csum != hdr->csum) { + dev_err(dev, "csum error: recv=0x%08x, calc=0x%08x, skip\n", + hdr->csum, calc_csum); + apu->ipi_task.id = -1; + return; + } + + /* execute top handler if exist */ + top_handler = apu->ipi_desc[hdr->id].top_handler; + if (top_handler) { + ret = top_handler(apu->temp_buf, hdr->len, apu->ipi_desc[hdr->id].priv); + if (ret == IRQ_HANDLED) + return; + } + apu->ipi_task.id = hdr->id; + apu->ipi_task.len = hdr->len; +} + +static int mtk_apu_send_ipi(struct platform_device *pdev, u32 id, void *buf, + unsigned int len, unsigned int wait) +{ + struct mtk_apu *apu = platform_get_drvdata(pdev); + + return mtk_apu_ipi_send(apu, id, buf, len, wait); +} + +static int mtk_apu_register_ipi(struct platform_device *pdev, u32 id, + ipi_handler_t handler, void *priv) +{ + struct mtk_apu *apu = platform_get_drvdata(pdev); + + return mtk_apu_ipi_register(apu, id, NULL, handler, priv); +} + +static void mtk_apu_unregister_ipi(struct platform_device *pdev, u32 id) +{ + struct mtk_apu *apu = platform_get_drvdata(pdev); + + mtk_apu_ipi_unregister(apu, id); +} + +int mtk_apu_power_on_off(struct platform_device *pdev, u32 id, u32 on, u32 off) +{ + int ret; + struct mtk_apu *apu = platform_get_drvdata(pdev); + struct device *dev; + const struct mtk_apu_hw_ops *hw_ops; + struct mtk_apu_ipi_desc *ipi; + + if (!apu) + return -EINVAL; + + dev = apu->dev; + + if (id >= MTK_APU_IPI_MAX) { + dev_err(dev, "%s: invalid ipi id = %d", __func__, id); + return -EINVAL; + } + + hw_ops = &apu->platdata->ops; + + if (!apu->platdata->flags.fast_on_off || !hw_ops->power_on_off) + return -EOPNOTSUPP; + + ipi = &apu->ipi_desc[id]; + spin_lock(&apu->usage_cnt_lock); + if (off == 1 && ipi_attrs[id].direction == IPI_HOST_INITIATE && + (ipi->usage_cnt != 0 && apu->ipi_pwr_ref_cnt[id] <= 1) && + !(ipi->usage_cnt == 1 && apu->current_ipi_handler_id == id && + apu->ipi_pwr_ref_cnt[id] == 1)) { + dev_err(dev, "%s: power off fail, ipi(%d) usage cnt(%d) not zero!\n", + __func__, id, ipi->usage_cnt); + spin_unlock(&apu->usage_cnt_lock); + ret = -EINVAL; + return ret; + } + spin_unlock(&apu->usage_cnt_lock); + + ret = hw_ops->power_on_off(apu, id, on, off); + + return ret; +} + +static struct mtk_rpmsg_info mtk_apu_rpmsg_info = { + .send_ipi = mtk_apu_send_ipi, + .register_ipi = mtk_apu_register_ipi, + .unregister_ipi = mtk_apu_unregister_ipi, + .ns_ipi_id = MTK_APU_IPI_NS_SERVICE, +}; + +static void mtk_apu_add_rpmsg_subdev(struct mtk_apu *apu) +{ + apu->rpmsg_subdev = mtk_rpmsg_create_rproc_subdev(to_platform_device(apu->dev), + &mtk_apu_rpmsg_info); + + if (apu->rpmsg_subdev) + rproc_add_subdev(apu->rproc, apu->rpmsg_subdev); +} + +static void mtk_apu_remove_rpmsg_subdev(struct mtk_apu *apu) +{ + if (apu->rpmsg_subdev) { + rproc_remove_subdev(apu->rproc, apu->rpmsg_subdev); + mtk_rpmsg_destroy_rproc_subdev(apu->rpmsg_subdev); + apu->rpmsg_subdev = NULL; + } +} + +static void mtk_apu_ipi_tx_done(struct mbox_client *cl, void *msg, int ret) +{ + struct mtk_apu *apu = container_of(cl, struct mtk_apu, cl); + + if (ret < 0) + dev_err(apu->dev, "tx not complete: sent:0x%p, ret:%d\n", msg, ret); + else + dev_dbg(apu->dev, "tx completed. sent:0x%p, ret:%d\n", msg, ret); +} + +int mtk_apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + struct mbox_client *cl; + int i, ret; + + apu->tx_serial_no = 0; + apu->rx_serial_no = 0; + + mutex_init(&apu->send_lock); + mutex_init(&apu->power_lock); + mutex_init(&apu->forbid_ipi_lock); + spin_lock_init(&apu->usage_cnt_lock); + + for (i = 0; i < MTK_APU_IPI_MAX; i++) { + mutex_init(&apu->ipi_desc[i].lock); + lockdep_set_class_and_name(&apu->ipi_desc[i].lock, &ipi_lock_key[i], + ipi_attrs[i].name); + apu->ipi_pwr_ref_cnt[i] = 0; + } + + apu->current_ipi_handler_id = -1; + + init_waitqueue_head(&apu->run.wq); + init_waitqueue_head(&apu->ack_wq); + + /* APU initialization IPI register */ + if (!apu->platdata->flags.fast_on_off) { + ret = mtk_apu_ipi_register(apu, MTK_APU_IPI_INIT, mtk_apu_init_ipi_top_handler, + NULL, apu); + if (ret) { + dev_err(dev, "failed to register mtk_apu_init_ipi_top_handler for init, ret=%d\n", + ret); + return ret; + } + } else { + ret = mtk_apu_ipi_register(apu, MTK_APU_IPI_INIT, NULL, + mtk_apu_init_ipi_bottom_handler, apu); + if (ret) { + dev_err(dev, "failed to register mtk_apu_init_ipi_bottom_handler for init, ret=%d\n", + ret); + return ret; + } + } + + /* add rpmsg subdev */ + mtk_apu_add_rpmsg_subdev(apu); + + cl = &apu->cl; + cl->dev = dev; + cl->tx_block = true; + cl->tx_tout = MTK_APU_MBOX_TIMEOUT; + cl->knows_txdone = false; + cl->rx_callback = mtk_apu_ipi_handle_rx; + cl->rx_callback_bh = mtk_apu_ipi_bottom_handle; + cl->tx_done = mtk_apu_ipi_tx_done; + + apu->ch = mbox_request_channel(cl, 0); + + if (IS_ERR(apu->ch)) { + ret = PTR_ERR(apu->ch); + dev_err_probe(dev, ret, "Failed to request mbox chan: %d\n", ret); + goto remove_rpmsg_subdev; + } + + return 0; + +remove_rpmsg_subdev: + mtk_apu_remove_rpmsg_subdev(apu); + mtk_apu_ipi_unregister(apu, MTK_APU_IPI_INIT); + + return ret; +} + +void mtk_apu_ipi_remove(struct mtk_apu *apu) +{ + if (!IS_ERR(apu->ch)) + mbox_free_channel(apu->ch); + mtk_apu_remove_rpmsg_subdev(apu); + mtk_apu_ipi_unregister(apu, MTK_APU_IPI_INIT); +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi_config.h b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi_config.h new file mode 100644 index 0000000000000..12e59f4030f13 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi_config.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_IPI_CONFIG_H +#define MTK_APU_IPI_CONFIG_H + +#include "linux/remoteproc/mtk_apu_ipi.h" + +#define IPI_LOCKED (1) +#define IPI_UNLOCKED (0) + +#define IPI_HOST_INITIATE (0) +#define IPI_APU_INITIATE (1) + +#define IPI_WITH_ACK (1) +#define IPI_WITHOUT_ACK (0) + +static struct lock_class_key ipi_lock_key[MTK_APU_IPI_MAX]; + +static const struct { + char *name; + unsigned int direction:1; + unsigned int ack:1; +} ipi_attrs[MTK_APU_IPI_MAX] = { + [MTK_APU_IPI_INIT] = { /* 0 */ + .name = "init", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITHOUT_ACK, + }, + [MTK_APU_IPI_NS_SERVICE] = { /* 1 */ + .name = "name-service", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITHOUT_ACK, + }, + [MTK_APU_IPI_DEEP_IDLE] = { /* 2 */ + .name = "deep_idle", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_CTRL_RPMSG] = { /* 3 */ + .name = "apu-ctrl-rpmsg", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MIDDLEWARE] = { /* 4 */ + .name = "apu-mdw", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_REVISER_RPMSG] = { /* 5 */ + .name = "apu-reviser", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_PWR_TX] = { /* 6 */ + .name = "apu-pwr-tx", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_PWR_RX] = { /* 7 */ + .name = "apu-pwr-rx", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MDLA_TX] = { /* 8 */ + .name = "apu-mdla-tx", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MDLA_RX] = { /* 9 */ + .name = "apu-mdla-rx", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_TIMESYNC] = { /* 10 */ + .name = "timesync", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_EDMA_TX] = { /* 11 */ + .name = "apu-edma-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MNOC_TX] = { /* 12 */ + .name = "apu-mnoc-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MVPU_TX] = { /* 13 */ + .name = "apu-mvpu-tx", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_MVPU_RX] = { /* 14 */ + .name = "apu-mvpu-rx", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_LOG_LEVEL] = { /* 15 */ + .name = "apu-log-level", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_APS_TX] = { /* 16 */ + .name = "apu-aps-tx", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_APS_RX] = { /* 17 */ + .name = "apu-aps-rx", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_SAPU_LOCK] = { /* 18 */ + .name = "apu-lock-rv-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_SCP_MIDDLEWARE] = { /* 19 */ + .name = "apu-scp-mdw-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_SCP_NP_RECOVER] = { /* 20 */ + .name = "apu-scp-np-recover-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_UT] = { /* 21 */ + .name = "apu-ipi-ut-rpmsg", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_APUMMU_RPMSG] = { /* 22 */ + .name = "apu-apummu", + .direction = IPI_HOST_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_EDMA_RX] = { /* 23 */ + .name = "edma-rx-rpmsg", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, + [MTK_APU_IPI_APUMMU_RX] = { /* 24 */ + .name = "apu-apummu-rx", + .direction = IPI_APU_INITIATE, + .ack = IPI_WITH_ACK, + }, +}; + + +#endif /* MTK_APU_IPI_CONFIG_H */ diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c index 8246dd418ed5f..91b62df1d7adb 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -297,9 +297,13 @@ static int mtk_apu_prepare(struct rproc *rproc) if (ret) return ret; + ret = mtk_apu_ipi_init(apu->pdev, apu); + if (ret) + return ret; + ret = mtk_apu_exception_init(apu->pdev, apu); if (ret) - goto remove_apu_hw_logger_ipi; + goto remove_mtk_apu_ipi; if (hw_ops->init) { ret = hw_ops->init(apu); @@ -312,8 +316,8 @@ static int mtk_apu_prepare(struct rproc *rproc) remove_mtk_apu_exception: mtk_apu_exception_exit(apu->pdev, apu); -remove_apu_hw_logger_ipi: - mtk_apu_hw_logger_ipi_remove(apu); +remove_mtk_apu_ipi: + mtk_apu_ipi_remove(apu); return ret; } @@ -324,6 +328,7 @@ static int mtk_apu_unprepare(struct rproc *rproc) mtk_apu_exception_exit(apu->pdev, apu); mtk_apu_hw_logger_ipi_remove(apu); + mtk_apu_ipi_remove(apu); return 0; } diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h index 91f4b7d9eff52..b24c59e2f92a3 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h @@ -15,8 +15,12 @@ #define MTK_APU_SEC_FW_IOVA (0x200000UL) #define MDLA_RESERVE_MEM_SZ (0x10000) +#define MIN_DTIME (0) +#define MAX_DTIME (10000) + int mtk_apu_exception_init(struct platform_device *pdev, struct mtk_apu *apu); void mtk_apu_exception_exit(struct platform_device *pdev, struct mtk_apu *apu); +void mtk_apu_init_mdw_dtime_setting(void (*update_power_dtime)(int dtime)); uint32_t mtk_apu_rv_smc_call(struct device *dev, uint32_t smc_id, uint32_t a2); struct regmap *mtk_apu_get_mbox_regmap(struct device_node *node); diff --git a/include/linux/remoteproc/mtk_apu.h b/include/linux/remoteproc/mtk_apu.h index 7409af3e00505..72c19c109f155 100644 --- a/include/linux/remoteproc/mtk_apu.h +++ b/include/linux/remoteproc/mtk_apu.h @@ -177,10 +177,21 @@ struct mtk_apu { struct platform_device *power_pdev; bool is_under_lp_scp_recovery_flow; + + unsigned int tx_serial_no; + unsigned int rx_serial_no; + unsigned int temp_buf[MTK_APU_SHARE_BUFFER_SIZE / 4]; + int current_ipi_handler_id; }; int mtk_apu_config_setup(struct mtk_apu *apu); void mtk_apu_config_remove(struct mtk_apu *apu); +int mtk_apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu); +void mtk_apu_ipi_remove(struct mtk_apu *apu); +int mtk_apu_ipi_register(struct mtk_apu *apu, u32 id, ipi_top_handler_t top_handler, + ipi_handler_t handler, void *priv); +void mtk_apu_ipi_unregister(struct mtk_apu *apu, u32 id); +int mtk_apu_ipi_send(struct mtk_apu *apu, u32 id, void *data, u32 len, u32 wait_ms); int mtk_apu_mem_init(struct mtk_apu *apu); int mtk_apu_load(struct rproc *rproc, const struct firmware *fw); diff --git a/include/linux/remoteproc/mtk_apu_ipi.h b/include/linux/remoteproc/mtk_apu_ipi.h new file mode 100644 index 0000000000000..a2ac9d0e6eccd --- /dev/null +++ b/include/linux/remoteproc/mtk_apu_ipi.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_IPI_H +#define MTK_APU_IPI_H + +#include + +#define MTK_APU_FW_VER_LEN (250) +#define MTK_APU_SHARE_BUFFER_SIZE (256) +#define MTK_APU_SHARE_BUF_SIZE (round_up(sizeof(struct mtk_share_obj)*2, PAGE_SIZE)) + +struct mtk_apu; + +enum { + MTK_APU_IPI_INIT = 0, + MTK_APU_IPI_NS_SERVICE, + MTK_APU_IPI_DEEP_IDLE, + MTK_APU_IPI_CTRL_RPMSG, + MTK_APU_IPI_MIDDLEWARE, + MTK_APU_IPI_REVISER_RPMSG, + MTK_APU_IPI_PWR_TX, // cmd direction from ap to up + MTK_APU_IPI_PWR_RX, // cmd direction from up to ap + MTK_APU_IPI_MDLA_TX, + MTK_APU_IPI_MDLA_RX, + MTK_APU_IPI_TIMESYNC, + MTK_APU_IPI_EDMA_TX, + MTK_APU_IPI_MNOC_TX, + MTK_APU_IPI_MVPU_TX, + MTK_APU_IPI_MVPU_RX, + MTK_APU_IPI_LOG_LEVEL, + MTK_APU_IPI_APS_TX, + MTK_APU_IPI_APS_RX, + MTK_APU_IPI_SAPU_LOCK, + MTK_APU_IPI_SCP_MIDDLEWARE, + MTK_APU_IPI_SCP_NP_RECOVER, + MTK_APU_IPI_UT, + MTK_APU_IPI_APUMMU_RPMSG, + MTK_APU_IPI_EDMA_RX, + MTK_APU_IPI_APUMMU_RX, + MTK_APU_IPI_MAX, +}; + +struct mtk_apu_run { + s8 fw_ver[MTK_APU_FW_VER_LEN]; + u32 signaled; + wait_queue_head_t wq; +}; + +struct mtk_apu_ipi_desc { + struct mutex lock; + ipi_top_handler_t top_handler; + ipi_handler_t handler; + void *priv; + + /* + * positive: host-initiated ipi outstanding count + * negative: apu-initiated ipi outstanding count + */ + int usage_cnt; +}; + +struct mtk_share_obj { + u8 share_buf[MTK_APU_SHARE_BUFFER_SIZE]; +}; + +struct mtk_ipi_task { + int id; + int len; +}; + +void mtk_apu_ipi_remove(struct mtk_apu *apu); +int mtk_apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu); +int mtk_apu_ipi_register(struct mtk_apu *apu, u32 id, ipi_top_handler_t top_handler, + ipi_handler_t handler, void *priv); +void mtk_apu_ipi_unregister(struct mtk_apu *apu, u32 id); +int mtk_apu_ipi_send(struct mtk_apu *apu, u32 id, void *data, u32 len, u32 wait_ms); +int mtk_apu_power_on_off(struct platform_device *pdev, u32 id, u32 on, u32 off); + +#endif /* MTK_APU_IPI_H */ diff --git a/include/linux/rpmsg/mtk_rpmsg.h b/include/linux/rpmsg/mtk_rpmsg.h index 64908238604d4..efc85fdaf7cbd 100644 --- a/include/linux/rpmsg/mtk_rpmsg.h +++ b/include/linux/rpmsg/mtk_rpmsg.h @@ -12,6 +12,7 @@ #include typedef void (*ipi_handler_t)(void *data, unsigned int len, void *priv); +typedef int (*ipi_top_handler_t)(void *data, unsigned int len, void *priv); /* * struct mtk_rpmsg_info - IPI functions tied to the rpmsg device. -- GitLab From a8fc6bda929968899263afa92764a6838a7e6286 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 14:22:30 +0800 Subject: [PATCH 425/456] CHROMIUM: remoteproc: mediatek: Add APU config and timesync Add APU config setting and timesync IPI. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Icce96708357cfa142a6cff82ce8fa997ebaac238 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166786 Reviewed-by: Hsin-Te Yuan Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../mediatek_apusys/mtk_apu_config.c | 136 ++++++++++++ .../remoteproc/mediatek_apusys/mtk_apu_ipi.c | 34 +++ .../mediatek_apusys/mtk_apu_rproc.c | 10 +- .../mediatek_apusys/mtk_apu_timesync.c | 49 +++++ .../mediatek_apusys/plat/mt8196_plat.c | 198 +++++++++++++++++- include/linux/remoteproc/mtk_apu.h | 2 + include/linux/remoteproc/mtk_apu_config.h | 130 ++++++++++++ 7 files changed, 555 insertions(+), 4 deletions(-) create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_config.c create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_timesync.c create mode 100644 include/linux/remoteproc/mtk_apu_config.h diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c new file mode 100644 index 0000000000000..9ab2bd543ce2b --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include "mtk_apu_rproc.h" + +#define MTK_APU_CONFIG_HEADER_MAGIC (0xc0de0101) +#define MTK_APU_CONFIG_HEADER_REV (0x1) + +static void mtk_apu_config_user_ptr_init(const struct mtk_apu *apu) +{ + struct mtk_apu_config_v1 *config; + struct mtk_apu_config_v1_entry_table *entry_table; + + config = apu->conf_buf; + + config->header_magic = MTK_APU_CONFIG_HEADER_MAGIC; + config->header_rev = MTK_APU_CONFIG_HEADER_REV; + config->entry_offset = offsetof(struct mtk_apu_config_v1, entry_tbl); + config->config_size = sizeof(struct mtk_apu_config_v1); + + entry_table = (struct mtk_apu_config_v1_entry_table *)((void *)config + config->entry_offset); + + entry_table->user_entry[0] = offsetof(struct mtk_apu_config_v1, user0_data); + entry_table->user_entry[1] = offsetof(struct mtk_apu_config_v1, user1_data); + entry_table->user_entry[2] = offsetof(struct mtk_apu_config_v1, user2_data); + entry_table->user_entry[3] = offsetof(struct mtk_apu_config_v1, user3_data); + entry_table->user_entry[4] = offsetof(struct mtk_apu_config_v1, user4_data); + entry_table->user_entry[5] = offsetof(struct mtk_apu_config_v1, user5_data); + entry_table->user_entry[6] = offsetof(struct mtk_apu_config_v1, user6_data); +} + +int mtk_apu_config_setup(struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + unsigned long flags; + int ret; + u64 timertick; + struct mtk_apu_mdla_rv_mem *mdla_rv_mem; + void *mdla_buf; + dma_addr_t mdla_da; + + apu->conf_buf = dma_alloc_coherent(apu->dev, CONFIG_SIZE, &apu->conf_da, GFP_KERNEL); + + if (apu->conf_buf == NULL || apu->conf_da == 0) { + dev_err(dev, "%s: dma_alloc_coherent fail\n", __func__); + return -ENOMEM; + } + + dev_dbg(dev, "%s: apu->conf_buf = %p, apu->conf_da = %pad\n", __func__, + apu->conf_buf, &apu->conf_da); + + mtk_apu_config_user_ptr_init(apu); + + spin_lock_irqsave(&apu->reg_lock, flags); + ret = regmap_field_write(apu->config_regmap_field, (u32)apu->conf_da); + spin_unlock_irqrestore(&apu->reg_lock, flags); + + if (ret) { + dev_err(dev, "Failed to set config address, ret = %d\n", ret); + return ret; + } + + spin_lock_irqsave(&apu->reg_lock, flags); + apu->conf_buf->time_offset = sched_clock(); + timertick = arch_timer_read_counter(); + spin_unlock_irqrestore(&apu->reg_lock, flags); + + apu->conf_buf->time_diff = div_u64(timertick * 1000, 13) - apu->conf_buf->time_offset; + apu->conf_buf->time_diff_cycle = timertick - div_u64(apu->conf_buf->time_offset * 13, 1000); + + ret = mtk_apu_ipi_config_init(apu); + if (ret) { + dev_err(dev, "apu ipi config init failed: %d\n", ret); + goto free_apu_conf_buf; + } + + if (apu->hw_logger_data != NULL) { + dma_addr_t hw_log_buf_dma_addr; + struct mtk_apu_logger_init_info *st_logger_init_info; + + hw_log_buf_dma_addr = mtk_apu_hw_logger_config_init(apu->hw_logger_data); + st_logger_init_info = (struct mtk_apu_logger_init_info *) + get_mtk_apu_config_user_ptr(apu->conf_buf, eLOGGER_INIT_INFO); + + if (hw_log_buf_dma_addr) { + st_logger_init_info->iova = lower_32_bits(hw_log_buf_dma_addr); + st_logger_init_info->iova_h = upper_32_bits(hw_log_buf_dma_addr); + st_logger_init_info->lbc_sz = apu->hw_logger_data->hw_log_lbc_size; + dev_dbg(dev, "set st_logger_init_info iova = 0x%x, iova_h = 0x%x, lbc_sz = 0x%x\n", + st_logger_init_info->iova, + st_logger_init_info->iova_h, + st_logger_init_info->lbc_sz); + } else { + dev_err(dev, "hw_log_buf_dma_addr is NULL\n"); + } + } + + mdla_rv_mem = (struct mtk_apu_mdla_rv_mem *) + get_mtk_apu_config_user_ptr(apu->conf_buf, eMDLA_MEM_INFO); + + mdla_buf = dma_alloc_coherent(apu->dev, MDLA_RESERVE_MEM_SZ, + &mdla_da, GFP_KERNEL); + if (mdla_buf == NULL || mdla_da == 0) { + dev_err(dev, "%s() dma_alloc_coherent fail\n", __func__); + return -ENOMEM; + } + mdla_rv_mem->size = MDLA_RESERVE_MEM_SZ; + mdla_rv_mem->buf = mdla_buf; + mdla_rv_mem->da = mdla_da; + + return 0; + +free_apu_conf_buf: + dma_free_coherent(apu->dev, CONFIG_SIZE, apu->conf_buf, apu->conf_da); + + return ret; +} + +void mtk_apu_config_remove(struct mtk_apu *apu) +{ + mtk_apu_ipi_config_remove(apu); + + dma_free_coherent(apu->dev, CONFIG_SIZE, apu->conf_buf, apu->conf_da); +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c index 9c09342a43f0c..adac562ae0bb7 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c @@ -422,6 +422,40 @@ static void mtk_apu_ipi_tx_done(struct mbox_client *cl, void *msg, int ret) dev_dbg(apu->dev, "tx completed. sent:0x%p, ret:%d\n", msg, ret); } +void mtk_apu_ipi_config_remove(struct mtk_apu *apu) +{ + dma_free_coherent(apu->dev, MTK_APU_SHARE_BUF_SIZE, apu->recv_buf, apu->recv_buf_da); +} + +int mtk_apu_ipi_config_init(struct mtk_apu *apu) +{ + struct device *dev = apu->dev; + struct mtk_apu_ipi_config *ipi_config; + void *ipi_buf = NULL; + dma_addr_t ipi_buf_da = 0; + + ipi_config = get_mtk_apu_config_user_ptr(apu->conf_buf, eAPU_IPI_CONFIG); + + /* initialize shared buffer */ + ipi_buf = dma_alloc_coherent(dev, MTK_APU_SHARE_BUF_SIZE, &ipi_buf_da, GFP_KERNEL); + if (!ipi_buf || !ipi_buf_da) { + dev_err(dev, "failed to allocate ipi share memory\n"); + return -ENOMEM; + } + + dev_dbg(dev, "%s: ipi_buf=%p, ipi_buf_da=%pad\n", __func__, ipi_buf, &ipi_buf_da); + + apu->recv_buf = ipi_buf; + apu->recv_buf_da = ipi_buf_da; + apu->send_buf = ipi_buf + sizeof(struct mtk_share_obj); + apu->send_buf_da = ipi_buf_da + sizeof(struct mtk_share_obj); + + ipi_config->in_buf_da = apu->send_buf_da; + ipi_config->out_buf_da = apu->recv_buf_da; + + return 0; +} + int mtk_apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu) { struct device *dev = apu->dev; diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c index 91b62df1d7adb..3a5fcae12bb06 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -301,10 +301,14 @@ static int mtk_apu_prepare(struct rproc *rproc) if (ret) return ret; - ret = mtk_apu_exception_init(apu->pdev, apu); + ret = mtk_apu_timesync_init(apu); if (ret) goto remove_mtk_apu_ipi; + ret = mtk_apu_exception_init(apu->pdev, apu); + if (ret) + goto remove_mtk_apu_timesync; + if (hw_ops->init) { ret = hw_ops->init(apu); if (ret) @@ -316,6 +320,9 @@ static int mtk_apu_prepare(struct rproc *rproc) remove_mtk_apu_exception: mtk_apu_exception_exit(apu->pdev, apu); +remove_mtk_apu_timesync: + mtk_apu_timesync_remove(apu); + remove_mtk_apu_ipi: mtk_apu_ipi_remove(apu); @@ -327,6 +334,7 @@ static int mtk_apu_unprepare(struct rproc *rproc) struct mtk_apu *apu = rproc->priv; mtk_apu_exception_exit(apu->pdev, apu); + mtk_apu_timesync_remove(apu); mtk_apu_hw_logger_ipi_remove(apu); mtk_apu_ipi_remove(apu); diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_timesync.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_timesync.c new file mode 100644 index 0000000000000..cf1ac9d9e77d4 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_timesync.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include + +#include + +static void mtk_apu_send_timesync_request(struct mtk_apu *apu) +{ + int ret; + u64 timesync_stamp; + + timesync_stamp = sched_clock(); + ret = mtk_apu_ipi_send(apu, MTK_APU_IPI_TIMESYNC, ×ync_stamp, sizeof(u64), 0); + + if (ret) + dev_err(apu->dev, "%s: mtk_apu_ipi_send fail(%d)\n", __func__, ret); +} + +static void mtk_apu_timesync_handler(void *data, u32 len, void *priv) +{ + struct mtk_apu *apu = (struct mtk_apu *)priv; + + dev_dbg(apu->dev, "%s: timesync request received\n", __func__); + mtk_apu_send_timesync_request(apu); +} + +int mtk_apu_timesync_init(struct mtk_apu *apu) +{ + int ret; + + ret = mtk_apu_ipi_register(apu, MTK_APU_IPI_TIMESYNC, NULL, mtk_apu_timesync_handler, apu); + if (ret) { + dev_err(apu->dev, "%s: failed to register IPI\n", __func__); + return ret; + } + + return 0; +} + +void mtk_apu_timesync_remove(struct mtk_apu *apu) +{ + mtk_apu_ipi_unregister(apu, MTK_APU_IPI_TIMESYNC); +} diff --git a/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c b/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c index fcf7144d9ef80..c267ac651fe0e 100644 --- a/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c +++ b/drivers/remoteproc/mediatek_apusys/plat/mt8196_plat.c @@ -10,7 +10,11 @@ #include #include "../mtk_apu_rproc.h" - +enum apu_infra_bit_id { + APU_INFRA_SYS_APMCU = 1UL, + APU_INFRA_SYS_GZ = 2UL, + APU_INFRA_SYS_SCP = 3UL, +}; static int apu_setup_apummu(struct mtk_apu *apu) { @@ -98,6 +102,183 @@ static int mt8196_rproc_stop(struct mtk_apu *apu) return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, 0); } +int apu_infra_lock(struct mtk_apu *apu, uint32_t op, enum apu_infra_bit_id id) +{ + uint32_t timeout_cnt = 0; + uint32_t timeout = 1000000; + struct device *dev = apu->dev; + + if (op == 1) + iowrite32(BIT(id), apu->apu_infra_hwsem); + else if (op == 0) + iowrite32(BIT(id + 16), apu->apu_infra_hwsem); + + if (op == 0) + goto end; + + while ((ioread32(apu->apu_infra_hwsem) & BIT(id)) != BIT(id)) { + if (timeout_cnt++ >= timeout) { + dev_err(dev, "%s: apu_infra_hwsem :0x%08x\n", __func__, + ioread32(apu->apu_infra_hwsem)); + return -EBUSY; + } + + iowrite32(BIT(id), apu->apu_infra_hwsem); + udelay(1); + } +end: + return 0; +} + +static int apu_power_ctrl(struct mtk_apu *apu, uint32_t op) +{ + if (!(apu->platdata->flags.secure_boot)) { + dev_err(apu->dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + if (op == 1) + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, 0); + else if (op == 0) + return mtk_apu_rv_smc_call(apu->dev, MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, 0); + else + return -EINVAL; +} + +static int mt8196_cold_boot_power_on(struct mtk_apu *apu) +{ + int ret; + struct device *dev = apu->dev; + + if (!(apu->platdata->flags.secure_boot)) { + dev_err(dev, "Not support in non-secure boot\n"); + return -EINVAL; + } + + apu->ipi_pwr_ref_cnt[MTK_APU_IPI_INIT]++; + apu->local_pwr_ref_cnt++; + + ret = mtk_apu_rv_smc_call(dev, MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY, 0); + if (ret) { + dev_err(dev, "Failed to clear mailbox dummy register, ret=%d\n", ret); + return ret; + } + + ret = apu_power_ctrl(apu, 1); + if (ret) + dev_err(dev, "Failed to power on APU, ret=%d\n", ret); + + return ret; +} + +static int mt8196_power_on_off_locked(struct mtk_apu *apu, u32 id, u32 on, u32 off) +{ + int ret = 0; + struct device *dev = apu->dev; + uint32_t rpc_state = 0; + + lockdep_assert_held(&apu->power_lock); + + if (on == 1 && off == 0) { + if (apu->is_under_lp_scp_recovery_flow) + return -EBUSY; + + if (apu->ipi_pwr_ref_cnt[id] < U32_MAX) { + apu->ipi_pwr_ref_cnt[id]++; + apu->local_pwr_ref_cnt++; + + if (apu->local_pwr_ref_cnt == 1) { + rpc_state = mtk_apu_get_rpc_status(apu->power_pdev) & 0x1; + if (id != MTK_APU_IPI_SCP_NP_RECOVER && rpc_state == 1) { + dev_warn(dev, "%s: APU RPC is under LP mode, retry later\n", __func__); + return -EBUSY; + } + + ret = apu_power_ctrl(apu, 1); + if (!ret) { + if (id == MTK_APU_IPI_SCP_NP_RECOVER && rpc_state == 1) + apu->is_under_lp_scp_recovery_flow = true; + } else { + apu->ipi_pwr_ref_cnt[id]--; + apu->local_pwr_ref_cnt--; + dev_err(dev, "%s: APU power on fail(%d)\n", __func__, ret); + } + } + } else { + dev_err(dev, "%s: ipi_pwr_ref_cnt[%u] == U32_MAX\n", __func__, id); + ret = -EINVAL; + } + } else if (on == 0 && off == 1) { + if (apu->ipi_pwr_ref_cnt[id] != 0) { + apu->ipi_pwr_ref_cnt[id]--; + apu->local_pwr_ref_cnt--; + + if (apu->local_pwr_ref_cnt == 0) { + if (apu->platdata->flags.infra_wa) + apu_infra_lock(apu, 1, APU_INFRA_SYS_APMCU); + + ret = apu_power_ctrl(apu, 0); + + if (apu->platdata->flags.infra_wa) + apu_infra_lock(apu, 0, APU_INFRA_SYS_APMCU); + + if (!ret) { + if (id == MTK_APU_IPI_SCP_NP_RECOVER) + apu->is_under_lp_scp_recovery_flow = false; + } else { + apu->ipi_pwr_ref_cnt[id]++; + apu->local_pwr_ref_cnt++; + dev_err(dev, "%s: APU power off fail(%d)\n", __func__, ret); + } + } + } else { + dev_err(dev, "%s: ipi_pwr_ref_cnt[%u] == 0\n", __func__, id); + ret = -EINVAL; + } + } else { + dev_err(dev, "%s: invalid operation: id(%d), on(%d), off(%d)\n", + __func__, id, on, off); + ret = -EINVAL; + } + + return ret; +} + +static int mt8196_power_on_off(struct mtk_apu *apu, u32 id, u32 on, u32 off) +{ + int ret = 0; + struct device *dev = apu->dev; + uint32_t retry_cnt = 500, i = 0; + + for (i = 0; i < retry_cnt; i++) { + mutex_lock(&apu->power_lock); + + ret = mt8196_power_on_off_locked(apu, id, on, off); + + mutex_unlock(&apu->power_lock); + + if (ret == -EBUSY) { + /* + * Retry the power on/off if the returned value is -EBUSY, because + * the hw semaphore might be blocked by other host or apu under lp mode + */ + if (i!=0 && (i%10)==0) + dev_warn(dev, "%s: retry on(%u) off(%u)(%u/%u)\n", __func__, + on, off, i, retry_cnt); + if (i < 10) + usleep_range(200, 500); + else if (i < 50) + usleep_range(1000, 2000); + else + usleep_range(10000, 11000); + continue; + } + break; + } + + return ret; +} + static int mt8196_apu_memmap_init(struct mtk_apu *apu) { struct device *dev = apu->dev; @@ -115,8 +296,16 @@ static int mt8196_apu_memmap_init(struct mtk_apu *apu) static int mt8196_rproc_init(struct mtk_apu *apu) { + int ret; + apu->is_under_lp_scp_recovery_flow = false; - return 0; + + ret = mt8196_cold_boot_power_on(apu); + if (ret) + dev_err(apu->dev, "%s: call mt8196_cold_boot_power_on fail(%d)\n", + __func__, ret); + + return ret; } static int mt8196_apu_resume(struct mtk_apu *apu) @@ -139,8 +328,10 @@ static int mt8196_apu_suspend(struct mtk_apu *apu) mutex_unlock(&apu->forbid_ipi_lock); // Cancel current timer and do power off if needed - if (timer_pending(&apu->power_off_timer)) + if (timer_pending(&apu->power_off_timer)) { del_timer(&apu->power_off_timer); + mt8196_power_on_off(apu, MTK_APU_IPI_MIDDLEWARE, 0, 1); + } } return 0; @@ -174,6 +365,7 @@ const struct mtk_apu_platdata mt8196_platdata = { .setup = mt8196_rproc_setup, .stop = mt8196_rproc_stop, .mtk_apu_memmap_init = mt8196_apu_memmap_init, + .power_on_off = mt8196_power_on_off, .suspend = mt8196_apu_suspend, .resume = mt8196_apu_resume, }, diff --git a/include/linux/remoteproc/mtk_apu.h b/include/linux/remoteproc/mtk_apu.h index 72c19c109f155..5eb8156606973 100644 --- a/include/linux/remoteproc/mtk_apu.h +++ b/include/linux/remoteproc/mtk_apu.h @@ -192,6 +192,8 @@ int mtk_apu_ipi_register(struct mtk_apu *apu, u32 id, ipi_top_handler_t top_hand ipi_handler_t handler, void *priv); void mtk_apu_ipi_unregister(struct mtk_apu *apu, u32 id); int mtk_apu_ipi_send(struct mtk_apu *apu, u32 id, void *data, u32 len, u32 wait_ms); +int mtk_apu_timesync_init(struct mtk_apu *apu); +void mtk_apu_timesync_remove(struct mtk_apu *apu); int mtk_apu_mem_init(struct mtk_apu *apu); int mtk_apu_load(struct rproc *rproc, const struct firmware *fw); diff --git a/include/linux/remoteproc/mtk_apu_config.h b/include/linux/remoteproc/mtk_apu_config.h new file mode 100644 index 0000000000000..733ff43589dfe --- /dev/null +++ b/include/linux/remoteproc/mtk_apu_config.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef MTK_APU_CONFIG_H +#define MTK_APU_CONFIG_H + +struct mtk_apu; + +struct mtk_apu_ipi_config { + u64 in_buf_da; + u64 out_buf_da; +}; + +struct mtk_vpu_init_info { + uint32_t vpu_num; + uint32_t cfg_addr; + uint32_t cfg_size; + uint32_t algo_info_ptr[3 * 2]; + uint32_t rst_vec[3]; + uint32_t dmem_addr[3]; + uint32_t imem_addr[3]; + uint32_t iram_addr[3]; + uint32_t cmd_addr[3]; + uint32_t log_addr[3]; + uint32_t log_size[3]; +}; + +struct mtk_apusys_chip_data { + uint32_t s_code; + uint32_t b_code; + uint32_t r_code; + uint32_t a_code; +}; + +struct mtk_apu_logger_init_info { + uint32_t iova; + uint32_t iova_h; + uint32_t aov_iova; + uint32_t aov_iova_h; + uint32_t aov_buf_sz; + uint32_t lbc_sz; +}; + +struct mtk_apummu_init_info { + uint64_t dram[32]; + uint32_t boundary; + uint32_t _reserved; +}; + +struct mtk_apu_reviser_init_info { + uint64_t dram[32]; + uint32_t boundary; + uint32_t _reserved; +}; + +struct mtk_apu_mvpu_preempt_data { + uint32_t itcm_buffer_core_0[5]; + uint32_t l1_buffer_core_0[5]; + uint32_t itcm_buffer_core_1[5]; + uint32_t l1_buffer_core_1[5]; +}; + +struct mtk_apu_mdla_rv_mem { + uint64_t buf; + uint64_t da; + uint64_t size; +}; + +enum mtk_apu_user_config { + eAPU_IPI_CONFIG = 0x0, + eVPU_INIT_INFO, + eAPUSYS_CHIP_DATA, + eLOGGER_INIT_INFO, + eREVISER_INIT_INFO, + eMVPU_PREEMPT_DATA, + eMDLA_MEM_INFO, + eUSER_CONFIG_MAX +}; + +struct mtk_apu_config_v1_entry_table { + u32 user_entry[eUSER_CONFIG_MAX]; + u32 _reserved; +}; + +struct mtk_apu_config_v1 { + u32 header_magic; + u32 header_rev; + u32 entry_offset; + u32 config_size; + + u64 time_offset; + u64 time_diff; + u64 time_diff_cycle; + u32 ramdump_offset; + u32 ramdump_type; + u32 ramdump_module; + u32 _reserved; + + struct mtk_apu_config_v1_entry_table entry_tbl; + + struct mtk_apu_ipi_config user0_data; + struct mtk_vpu_init_info user1_data; + struct mtk_apusys_chip_data user2_data; + struct mtk_apu_logger_init_info user3_data; + struct mtk_apu_reviser_init_info user4_data; + struct mtk_apu_mvpu_preempt_data user5_data; + struct mtk_apu_mdla_rv_mem user6_data; +}; + +void mtk_apu_ipi_config_remove(struct mtk_apu *apu); +int mtk_apu_ipi_config_init(struct mtk_apu *apu); + +static inline void *get_mtk_apu_config_user_ptr(struct mtk_apu_config_v1 *conf, + enum mtk_apu_user_config user_id) +{ + struct mtk_apu_config_v1_entry_table *entry_tbl; + + if (!conf) + return NULL; + + if (user_id >= eUSER_CONFIG_MAX) + return NULL; + + entry_tbl = (struct mtk_apu_config_v1_entry_table *) ((void *)conf + conf->entry_offset); + + return (void *)conf + entry_tbl->user_entry[user_id]; +} +#endif /* MTK_APU_CONFIG_H */ -- GitLab From 5d3fdf7538827e08b7a6318cb31a077820c60827 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 14:26:32 +0800 Subject: [PATCH 426/456] CHROMIUM: remoteproc: mediatek: Add APU hw_logger Add APU hardware logger. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: I4e5278456613b8078b320e906f15ea817329d37a Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166787 Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Reviewed-by: Fei Shao Reviewed-by: Hsin-Te Yuan Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../mediatek_apusys/mtk_apu_hw_logger.c | 1174 +++++++++++++++++ .../mediatek_apusys/mtk_apu_rproc.c | 15 +- include/linux/remoteproc/mtk_apu_hw_logger.h | 120 ++ 3 files changed, 1308 insertions(+), 1 deletion(-) create mode 100644 drivers/remoteproc/mediatek_apusys/mtk_apu_hw_logger.c create mode 100644 include/linux/remoteproc/mtk_apu_hw_logger.h diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_hw_logger.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_hw_logger.c new file mode 100644 index 0000000000000..6c1afbaf1f3d6 --- /dev/null +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_hw_logger.c @@ -0,0 +1,1174 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_apu_rproc.h" + +#define APUSYS_HWLOGR_DIR "apusys_logger" +#define HWLOG_DEV_NAME "apu_hw_logger" + +static const struct reg_field mtk_apu_log_r_reg_field = { + .reg = LOG_R_OFS, + .lsb = 0, + .msb = 31, +}; + +static const struct reg_field mtk_apu_log_w_reg_field = { + .reg = LOG_W_OFS, + .lsb = 0, + .msb = 31, +}; + +static void hw_logger_buf_invalidate(struct mtk_apu_hw_logger *hw_logger_data) +{ + dma_sync_single_for_cpu(hw_logger_data->apu->dev, + hw_logger_data->hw_log_buf.hw_log_buf_dma_addr, + HWLOG_LOG_SIZE, DMA_FROM_DEVICE); +} + +static int hw_logger_buf_alloc(struct mtk_apu_hw_logger *hw_logger_data) +{ + int ret = 0; + + ret = dma_set_coherent_mask(hw_logger_data->apu->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(hw_logger_data->dev, "dma_set_coherent_mask fail (%d)\n", ret); + ret = -ENOMEM; + goto out; + } + + /* local buffer for dump */ + hw_logger_data->local_log_buf = kzalloc(LOCAL_LOG_SIZE, GFP_KERNEL); + if (!hw_logger_data->local_log_buf) { + ret = -ENOMEM; + goto out; + } + + /* memory used by hw logger */ + hw_logger_data->hw_log_buf.hw_log_buf = kzalloc(HWLOG_LOG_SIZE, GFP_KERNEL); + if (!hw_logger_data->hw_log_buf.hw_log_buf) { + ret = -ENOMEM; + goto out; + } + + hw_logger_data->hw_log_buf.hw_log_buf_dma_addr = dma_map_single(hw_logger_data->apu->dev, + hw_logger_data->hw_log_buf.hw_log_buf, HWLOG_LOG_SIZE, DMA_FROM_DEVICE); + ret = dma_mapping_error(hw_logger_data->apu->dev, + hw_logger_data->hw_log_buf.hw_log_buf_dma_addr); + if (ret) { + dev_err(hw_logger_data->dev, + "dma_map_single fail for hw_log_buf_dma_addr (%d)\n", ret); + ret = -ENOMEM; + goto out; + } + + dev_dbg(hw_logger_data->dev, "local_log_buf = %p\n", hw_logger_data->local_log_buf); + dev_dbg(hw_logger_data->dev, "hw_log_buf = %pK, hw_log_buf_dma_addr = %pad\n", + hw_logger_data->hw_log_buf.hw_log_buf, + &hw_logger_data->hw_log_buf.hw_log_buf_dma_addr); + +out: + return ret; +} + +static void hw_logger_buf_free(struct device *dev, struct mtk_apu_hw_logger *hw_logger_data) +{ + dma_unmap_single(dev, hw_logger_data->hw_log_buf.hw_log_buf_dma_addr, HWLOG_LOG_SIZE, + DMA_FROM_DEVICE); + + kfree(hw_logger_data->hw_log_buf.hw_log_buf); + hw_logger_data->hw_log_buf.hw_log_buf = NULL; + kfree(hw_logger_data->local_log_buf); + hw_logger_data->local_log_buf = NULL; +} + +static int ioread32_atf(uint8_t op_num, void **addr, uint32_t **ret_val, + struct mtk_apu_hw_logger *hw_logger_data) +{ + int i, op = 0; + uint8_t smc_op; + struct arm_smccc_res res; + unsigned long flags = 0; + struct device *dev = hw_logger_data->dev; + + if (op_num == 0 || op_num > MAX_SMC_OP_NUM) { + dev_err(dev, "op_num invalid: %d\n", op_num); + return -EINVAL; + } + + for (i = 0; i < op_num; i++) { + if (addr[i] == hw_logger_data->apu_logtop + APU_LOG_BUF_T_SIZE_OFF) + smc_op = SMC_OP_APU_LOG_BUF_T_SIZE; + else if (addr[i] == hw_logger_data->apu_logtop + APU_LOG_BUF_W_PTR_OFF) + smc_op = SMC_OP_APU_LOG_BUF_W_PTR; + else if (addr[i] == hw_logger_data->apu_logtop + APU_LOG_BUF_R_PTR_OFF) + smc_op = SMC_OP_APU_LOG_BUF_R_PTR; + else if (addr[i] == hw_logger_data->apu_logtop + APU_LOGTOP_CON_OFF) + smc_op = SMC_OP_APU_LOG_BUF_CON; + else { + dev_err(dev, "Not support addr: 0x%llx", (unsigned long long)addr[i]); + return -EINVAL; + } + op |= smc_op << (8 * i); + } + dev_dbg(dev, "arm_smccc_smc reg_dump op: 0x%08x\n", op); + + spin_lock_irqsave(&hw_logger_data->smc_spinlock, flags); + arm_smccc_smc(MTK_SIP_APUSYS_CONTROL, + MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP, + op, 0, 0, 0, 0, 0, &res); + spin_unlock_irqrestore(&hw_logger_data->smc_spinlock, flags); + + if (res.a0 != 0) { + if (res.a0 == -16) { + dev_dbg(dev, "arm_smccc_smc reg_dump acquire rcx sema timeout (rcx off)\n"); + } else { + dev_err(dev, "arm_smccc_smc reg_dump error ret: 0x%lx\n", res.a0); + dev_err(dev, "arm_smccc_smc reg_dump op: 0x%08x\n", op); + dev_err(dev, "arm_smccc_smc reg_dump a0 a1 a2 a3 / 0x%lx 0x%lx 0x%lx 0x%lx\n", + res.a0, res.a1, res.a2, res.a3); + } + return res.a0; + } + + *ret_val[0] = res.a1; + if (op_num > 1) + *ret_val[1] = res.a2; + if (op_num > 2) + *ret_val[2] = res.a3; + + return 0; +} + +static int iowrite32_atf(uint32_t write_val, void *addr, struct mtk_apu_hw_logger *hw_logger_data) +{ + int op; + struct arm_smccc_res res; + unsigned long flags = 0; + struct device *dev = hw_logger_data->dev; + + if (addr == hw_logger_data->apu_logtop + APU_LOG_BUF_R_PTR_OFF) { + op = SMC_OP_APU_LOG_BUF_R_PTR; + } else { + dev_err(dev, "Not support addr: %p", addr); + return -EINVAL; + } + + spin_lock_irqsave(&hw_logger_data->smc_spinlock, flags); + arm_smccc_smc(MTK_SIP_APUSYS_CONTROL, MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE, + op, write_val, 0, 0, 0, 0, &res); + spin_unlock_irqrestore(&hw_logger_data->smc_spinlock, flags); + + if (res.a0 != 0) { + if (res.a0 == -16) { + dev_info(dev, "arm_smccc_smc reg_write acquire rcx sema timeout (rcx off)\n"); + } else { + dev_err(dev, "arm_smccc_smc reg_write error! ret = 0x%lx, a1 = 0x%lx", + res.a0, res.a1); + dev_err(dev, "arm_smccc_smc reg_write op val / 0x%x 0x%x\n", op, write_val); + } + return res.a0; + } + + return 0; +} + +static int w1c32_atf(void *addr, uint32_t *ret_val, struct mtk_apu_hw_logger *hw_logger_data) +{ + int op; + struct arm_smccc_res res; + unsigned long flags = 0; + struct device *dev = hw_logger_data->dev; + + if (addr == hw_logger_data->apu_logtop + APU_LOGTOP_CON_OFF) { + op = SMC_OP_APU_LOG_BUF_CON; + } else { + dev_err(dev, "Not support addr: %p", addr); + return -EINVAL; + } + + spin_lock_irqsave(&hw_logger_data->smc_spinlock, flags); + arm_smccc_smc(MTK_SIP_APUSYS_CONTROL, + MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C, + op, 0, 0, 0, 0, 0, &res); + spin_unlock_irqrestore(&hw_logger_data->smc_spinlock, flags); + + if (res.a0 != 0) { + if (res.a0 == -16) { + dev_info(dev, "arm_smccc_smc reg_w1c acquire rcx sema timeout (rcx off)\n"); + } else { + dev_err(dev, "arm_smccc_smc reg_w1c error! ret = 0x%lx, a1 = 0x%lx", + res.a0, res.a1); + dev_err(dev, "arm_smccc_smc reg_w1c op / 0x%x\n", op); + } + return res.a0; + } + + *ret_val = res.a1; + return 0; +} + +static unsigned long long get_st_addr(struct mtk_apu_hw_logger *hw_logger_data) +{ + return (unsigned long long) hw_logger_data->hw_log_buf.hw_log_buf_dma_addr; +} + +static unsigned int get_t_size(void) +{ + return HWLOG_LOG_SIZE; +} + +static int get_r_w_ptr(unsigned long long *r_ptr, unsigned long long *w_ptr, + struct mtk_apu_hw_logger *hw_logger_data) +{ + int ret = 0; + uint32_t r_ptr_reg = 0, w_ptr_reg = 0; + + ret = ioread32_atf(2, + (void*[]){hw_logger_data->apu_logtop + APU_LOG_BUF_R_PTR_OFF, + hw_logger_data->apu_logtop + APU_LOG_BUF_W_PTR_OFF}, + (uint32_t*[]){&r_ptr_reg, &w_ptr_reg}, hw_logger_data + ); + if (ret) + goto out; + + /* hw log w/r_ptr is a 34bit addr but store in a 32bit feild */ + if (r_ptr != NULL) + *r_ptr = (unsigned long long)r_ptr_reg << 2; + if (w_ptr != NULL) + *w_ptr = (unsigned long long)w_ptr_reg << 2; + +out: + return ret; +} + +static void set_r_ptr(unsigned long long r_ptr, struct mtk_apu_hw_logger *hw_logger_data) +{ + int ret = 0; + + ret = iowrite32_atf(lower_32_bits(r_ptr >> 2), + hw_logger_data->apu_logtop + APU_LOG_BUF_R_PTR_OFF, + hw_logger_data); + if (ret < 0) + dev_dbg(hw_logger_data->dev, "iowrite32_atf failed\n"); +} + +static void store_r_ofs(unsigned int pwr_status, unsigned int r_ofs, + struct mtk_apu_hw_logger *hw_logger_data) +{ + int ret; + + /* set read pointer */ + if (pwr_status != 0) { + dev_dbg(hw_logger_data->dev, "set_r_ptr r_ofs = 0x%x\n", r_ofs); + set_r_ptr(get_st_addr(hw_logger_data) + r_ofs, hw_logger_data); + } + + dev_dbg(hw_logger_data->dev, "set_r_ofs_mbox r_ofs = 0x%x\n", r_ofs); + ret = regmap_field_write(hw_logger_data->log_read_regmap_field, r_ofs); + if (ret) + dev_err(hw_logger_data->dev, "failed to set r_ofs\n"); +} + +static struct platform_driver hw_logger_driver; +struct mtk_apu_hw_logger *get_mtk_apu_hw_logger_device(struct device_node *hw_logger_np) +{ + struct platform_device *pdev; + struct device *dev; + struct mtk_apu_hw_logger *hw_logger_data; + + pdev = of_find_device_by_node(hw_logger_np); + if (!pdev) + return ERR_PTR(-ENODEV); + + dev = &pdev->dev; + + if (!dev->driver) + return -EPROBE_DEFER; + + if (dev->driver != &hw_logger_driver.driver) + return -EINVAL; + + hw_logger_data = dev_get_drvdata(dev); + put_device(dev); + + return hw_logger_data; +} + +static void mtk_apu_hw_log_level_ipi_handler(void *data, unsigned int len, void *priv) +{ + int ret; + unsigned int log_level = *(unsigned int *)data; + struct mtk_apu *apu = priv; + + pr_info("log_level = 0x%x (%d)\n", log_level, len); + ret = mtk_apu_power_on_off(apu->pdev, MTK_APU_IPI_LOG_LEVEL, 0, 1); + if (ret && ret != -EOPNOTSUPP) + pr_err("mtk_apu_power_on_off fail(%d)\n", ret); +} + +dma_addr_t mtk_apu_hw_logger_config_init(struct mtk_apu_hw_logger *hw_logger_data) +{ + unsigned long flags; + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + hw_logger_data->g_log.norm_mode.w_ptr = 0; + hw_logger_data->g_log.norm_mode.r_ptr = U32_MAX; + hw_logger_data->g_log.norm_mode.ov_flg = 0; + hw_logger_data->g_log.lock_mode.w_ptr = 0; + hw_logger_data->g_log.lock_mode.r_ptr = U32_MAX; + hw_logger_data->g_log.lock_mode.ov_flg = 0; + hw_logger_data->g_log.mobile_lock_mode.w_ptr = 0; + hw_logger_data->g_log.mobile_lock_mode.r_ptr = U32_MAX; + hw_logger_data->g_log.mobile_lock_mode.ov_flg = 0; + hw_logger_data->buf_track.__loc_log_sz = 0; + atomic_set(&hw_logger_data->apu_toplog_deep_idle, 0); + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + hw_logger_buf_alloc(hw_logger_data); + + return hw_logger_data->hw_log_buf.hw_log_buf_dma_addr; +} + +int mtk_apu_hw_logger_ipi_init(struct mtk_apu_hw_logger *hw_logger_data, struct mtk_apu *apu) +{ + int ret = 0; + + hw_logger_data->apu = apu; + + if (!hw_logger_data->apu_logtop) + return 0; + + ret = mtk_apu_ipi_register(apu, MTK_APU_IPI_LOG_LEVEL, NULL, + mtk_apu_hw_log_level_ipi_handler, apu); + if (ret) + dev_err(apu->dev, "Fail in hw_log_level_ipi_init\n"); + return 0; +} + +void mtk_apu_hw_logger_ipi_remove(struct mtk_apu *apu) +{ + mtk_apu_ipi_unregister(apu, MTK_APU_IPI_LOG_LEVEL); +} + +static int __apu_logtop_copy_buf(unsigned int r_ofs, unsigned int w_ofs, unsigned int pwr_status, + struct mtk_apu_hw_logger *hw_logger_data) +{ + unsigned long flags; + unsigned int t_size, r_size; + unsigned int log_w_ofs, log_ov_flg; + int ret = 0; + static bool err_log; + + if (!hw_logger_data->apu_logtop || !hw_logger_data->hw_log_buf.hw_log_buf + || !hw_logger_data->local_log_buf) + return 0; + + dev_dbg(hw_logger_data->dev, "w_ofs = 0x%x, r_ofs = 0x%x\n", w_ofs, r_ofs); + + if (w_ofs == r_ofs) + goto out; + + t_size = get_t_size(); + + /* check copy size */ + if (w_ofs > r_ofs) + r_size = w_ofs - r_ofs; + else + r_size = t_size - r_ofs + w_ofs; + + /* sanity check */ + if (r_size >= t_size) + r_size = t_size; + + ret = r_size; + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + log_w_ofs = hw_logger_data->buf_track.__loc_log_w_ofs; + log_ov_flg = hw_logger_data->buf_track.__loc_log_ov_flg; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + if (w_ofs + HWLOG_LINE_MAX_LENS > t_size || r_ofs + HWLOG_LINE_MAX_LENS > t_size || + t_size == 0 || t_size > HWLOG_LOG_SIZE) { + if (!err_log) + dev_warn(hw_logger_data->dev, "w_ofs = 0x%x, r_ofs = 0x%x, t_size = 0x%x\n", + w_ofs, r_ofs, t_size); + err_log = true; + return 0; + } + + if (log_w_ofs + HWLOG_LINE_MAX_LENS > LOCAL_LOG_SIZE) { + if (!err_log) + dev_warn(hw_logger_data->dev, "log_w_ofs = 0x%x\n", log_w_ofs); + err_log = true; + return 0; + } + + if (err_log) { + dev_warn(hw_logger_data->dev, "[ok] w_ofs = 0x%x, r_ofs = 0x%x, t_size = 0x%x\n", + w_ofs, r_ofs, t_size); + err_log = false; + } + + hw_logger_buf_invalidate(hw_logger_data); + + while (r_size > 0) { + /* copy hw logger buffer to local buffer */ + memcpy(hw_logger_data->local_log_buf + log_w_ofs, + hw_logger_data->hw_log_buf.hw_log_buf + r_ofs, HWLOG_LINE_MAX_LENS); + + /* update local write pointer */ + log_w_ofs = (log_w_ofs + HWLOG_LINE_MAX_LENS) % LOCAL_LOG_SIZE; + + /* update hw logger read pointer */ + r_ofs = (r_ofs + HWLOG_LINE_MAX_LENS) % t_size; + r_size -= HWLOG_LINE_MAX_LENS; + + hw_logger_data->buf_track.__loc_log_sz += HWLOG_LINE_MAX_LENS; + if (hw_logger_data->buf_track.__loc_log_sz >= LOCAL_LOG_SIZE) + log_ov_flg = 1; + }; + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + hw_logger_data->buf_track.__loc_log_w_ofs = log_w_ofs; + hw_logger_data->buf_track.__loc_log_ov_flg = log_ov_flg; + hw_logger_data->g_log.lock_mode.not_rd_sz += ret; + hw_logger_data->g_log.mobile_lock_mode.not_rd_sz += ret; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + store_r_ofs(pwr_status, r_ofs, hw_logger_data); +out: + return ret; +} + +static int apu_logtop_copy_buf(struct mtk_apu_hw_logger *hw_logger_data) +{ + int ret = 0; + static bool lock_fail; + unsigned int r_ofs, w_ofs, pwr_status; + unsigned long long r_ptr = 0, w_ptr = 0; + + if (!mutex_trylock(&hw_logger_data->mutex)) { + if (!lock_fail) { + dev_dbg(hw_logger_data->dev, "lock fail\n"); + lock_fail = true; + } + return ret; + } else if (lock_fail) { + dev_dbg(hw_logger_data->dev, "lock success\n"); + lock_fail = false; + } + + pwr_status = mtk_apu_get_rpc_pwr_status(hw_logger_data->power_pdev) & 0x1; + dev_dbg(hw_logger_data->dev, "APU_RPC_PWR_STATUS = 0x%x\n", pwr_status); + + ret = get_r_w_ptr(&r_ptr, &w_ptr, hw_logger_data); + + if (ret != 0 && pwr_status != 0) { + dev_dbg(hw_logger_data->dev, "skip copy buf, apu may power off, ret = %d\n", ret); + goto out; + } + + r_ofs = r_ptr - get_st_addr(hw_logger_data); + w_ofs = w_ptr - get_st_addr(hw_logger_data); + dev_dbg(hw_logger_data->dev, "w_ofs = 0x%x, r_ofs = 0x%x, st_addr = 0x%llx, t_size = 0x%x\n", + w_ofs, r_ofs, get_st_addr(hw_logger_data), get_t_size()); + + if (pwr_status == 0 || r_ptr == 0 || w_ptr == 0) { + ret = regmap_field_read(hw_logger_data->log_read_regmap_field, &r_ofs); + if (ret) + dev_err(hw_logger_data->dev, "failed to read log r_ofs\n"); + + ret = regmap_field_read(hw_logger_data->log_write_regmap_field, &w_ofs); + if (ret) + dev_err(hw_logger_data->dev, "failed to read log w_ofs\n"); + + dev_dbg(hw_logger_data->dev, "mbox w_ofs = 0x%x, r_ofs = 0x%x\n", + w_ofs, r_ofs); + } + + ret = __apu_logtop_copy_buf(r_ofs, w_ofs, pwr_status, hw_logger_data); +out: + mutex_unlock(&hw_logger_data->mutex); + + return ret; +} + +static int hw_logger_copy_buf(struct mtk_apu_hw_logger *hw_logger_data) +{ + dev_dbg(hw_logger_data->dev, "in\n"); + + if (!hw_logger_data->apu_logtop || !hw_logger_data->apu) + return 0; + + return apu_logtop_copy_buf(hw_logger_data); +} + +static irqreturn_t apu_logtop_irq_handler(int irq, void *dev_id) +{ + static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); + + bool lbc_full_flg, ovwrite_flg; + unsigned int ctrl_flag = 0; + unsigned long long irq_start_time; + struct mtk_apu_hw_logger *hw_logger_data = dev_id; + struct device *dev = hw_logger_data->dev; + + irq_start_time = sched_clock(); + + apu_logtop_copy_buf(hw_logger_data); + + w1c32_atf(hw_logger_data->apu_logtop + APU_LOGTOP_CON_FLAG_OFF, &ctrl_flag, hw_logger_data); + + dev_dbg(dev, "w1c %s = 0x%x\n", __func__, + (ctrl_flag & APU_LOGTOP_CON_FLAG_MASK) >> APU_LOGTOP_CON_FLAG_SHIFT); + + lbc_full_flg = !!(ctrl_flag & LBC_FULL_FLAG); + ovwrite_flg = !!(ctrl_flag & OVWRITE_FLAG); + + if (!lbc_full_flg && !ovwrite_flg && !__ratelimit(&_rs)) { + if (hw_logger_data->burst_intr_cnt < HW_LOG_INTR_THRESHOLD) { + dev_dbg(dev, "apu may power off, intr status = 0x%x, intr cnt = %d\n", + ctrl_flag, hw_logger_data->burst_intr_cnt); + hw_logger_data->burst_intr_cnt++; + } else if (hw_logger_data->burst_intr_cnt == HW_LOG_INTR_THRESHOLD) { + hw_logger_data->burst_intr_cnt++; + } + } else { + hw_logger_data->burst_intr_cnt = 0; + } + + wake_up_all(&hw_logger_data->wq_data.apusys_hwlog_wait); + dev_dbg(dev, "irq_time = %lld ns\n", sched_clock() - irq_start_time); + + return IRQ_HANDLED; +} + +static int mtk_apu_get_dbglv(void *data, u64 *val) +{ + struct mtk_apu_hw_logger *hw_logger_data = data; + + *val = hw_logger_data->hw_ipi_log_level; + + return 0; +} + +static int mtk_apu_set_dbglv(void *data, u64 val) +{ + int ret; + struct mtk_apu_hw_logger *hw_logger_data = data; + struct mtk_apu *apu = hw_logger_data->apu; + + dev_dbg(hw_logger_data->dev, "set uP debug lv = 0x%llx\n", val); + + hw_logger_data->hw_ipi_log_level = val; + + ret = mtk_apu_power_on_off(apu->pdev, MTK_APU_IPI_LOG_LEVEL, 1, 0); + if (ret && ret != -EOPNOTSUPP) { + dev_err(hw_logger_data->dev, "mtk_apu_power_on_off fail(%d)\n", ret); + return -1; + } + + ret = mtk_apu_ipi_send(apu, MTK_APU_IPI_LOG_LEVEL, + &hw_logger_data->hw_ipi_log_level, + sizeof(hw_logger_data->hw_ipi_log_level), + 1000); + if (ret) + dev_err(hw_logger_data->dev, "Failed for hw_logger log level send.\n"); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(mtk_apu_hwlogger_dbglv_fops, mtk_apu_get_dbglv, mtk_apu_set_dbglv, + "%llu\n"); + +static int mtk_apu_hwlogger_attr_show(struct seq_file *s, void *data) +{ + unsigned long flags; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + seq_printf(s, "hw_log_buf = %pK\n", hw_logger_data->hw_log_buf.hw_log_buf); + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + seq_printf(s, "__loc_log_w_ofs = %d\n", hw_logger_data->buf_track.__loc_log_w_ofs); + seq_printf(s, "__loc_log_ov_flg = %d\n", hw_logger_data->buf_track.__loc_log_ov_flg); + seq_printf(s, "__loc_log_sz = %d\n", hw_logger_data->buf_track.__loc_log_sz); + seq_printf(s, "norm_log.w_ptr = %d\n", hw_logger_data->g_log.norm_mode.w_ptr); + seq_printf(s, "norm_log.r_ptr = %d\n", hw_logger_data->g_log.norm_mode.r_ptr); + seq_printf(s, "norm_log.ov_flg = %d\n", hw_logger_data->g_log.norm_mode.ov_flg); + seq_printf(s, "lock_log.w_ptr = %d\n", hw_logger_data->g_log.lock_mode.w_ptr); + seq_printf(s, "lock_log.r_ptr = %d\n", hw_logger_data->g_log.lock_mode.r_ptr); + seq_printf(s, "lock_log.ov_flg = %d\n", hw_logger_data->g_log.lock_mode.ov_flg); + seq_printf(s, "lock_log.not_rd_sz = %d\n", hw_logger_data->g_log.lock_mode.not_rd_sz); + seq_printf(s, "mobile_lock_log.w_ptr = %d\n", hw_logger_data->g_log.mobile_lock_mode.w_ptr); + seq_printf(s, "mobile_lock_log.r_ptr = %d\n", hw_logger_data->g_log.mobile_lock_mode.r_ptr); + seq_printf(s, "mobile_lock_log.ov_flg = %d\n", hw_logger_data->g_log.mobile_lock_mode.ov_flg); + seq_printf(s, "mobile_lock_log.not_rd_sz = %d\n", hw_logger_data->g_log.mobile_lock_mode.not_rd_sz); + + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(mtk_apu_hwlogger_attr); + +static void *mtk_apu_hw_logger_seq_start(struct seq_file *s, loff_t *pos) +{ + struct hw_log_seq_data *pSData; + unsigned int w_ptr, r_ptr, ov_flg = 0; + unsigned long flags; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + hw_logger_copy_buf(hw_logger_data); + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + if (hw_logger_data->g_log.norm_mode.r_ptr == U32_MAX) { + w_ptr = hw_logger_data->buf_track.__loc_log_w_ofs; + ov_flg = hw_logger_data->buf_track.__loc_log_ov_flg; + hw_logger_data->g_log.norm_mode.w_ptr = w_ptr; + hw_logger_data->g_log.norm_mode.ov_flg = ov_flg; + if (ov_flg) + r_ptr = (w_ptr + HWLOG_LINE_MAX_LENS) % HWLOG_LOG_SIZE; + else + r_ptr = 0; + hw_logger_data->g_log.norm_mode.r_ptr = r_ptr; + } else { + w_ptr = hw_logger_data->g_log.norm_mode.w_ptr; + r_ptr = hw_logger_data->g_log.norm_mode.r_ptr; + } + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + dev_dbg(hw_logger_data->dev, "w_ptr = %d, r_ptr = %d, ov_flg = %d, *pos = %d\n", + w_ptr, r_ptr, ov_flg, (unsigned int)*pos); + + if (w_ptr == r_ptr) { + if (s->size == PAGE_SIZE) { + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + hw_logger_data->g_log.norm_mode.r_ptr = U32_MAX; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + } else { + s->size = PAGE_SIZE; + } + return NULL; + } + + pSData = kzalloc(sizeof(struct hw_log_seq_data), GFP_KERNEL); + if (!pSData) + return NULL; + + pSData->w_ptr = w_ptr; + pSData->ov_flg = ov_flg; + if (ov_flg == 0) + pSData->r_ptr = r_ptr; + else + pSData->r_ptr = w_ptr; + + return pSData; +} + +static void *mtk_apu_hw_logger_seq_startl(struct seq_file *s, loff_t *pos) +{ + uint32_t w_ptr, r_ptr, ov_flg; + struct hw_log_seq_data *pSData, *gpSData; + unsigned long flags; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + pSData = kzalloc(sizeof(struct hw_log_seq_data), GFP_KERNEL); + if (!pSData) + return NULL; + + /* flush the last hw buffer */ + hw_logger_copy_buf(hw_logger_data); + + if (s->file && s->file->f_flags & O_NONBLOCK) { + pSData->nonblock = true; + gpSData = &hw_logger_data->g_log.mobile_lock_mode; + } else { + pSData->nonblock = false; + gpSData = &hw_logger_data->g_log.lock_mode; + } + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + w_ptr = hw_logger_data->buf_track.__loc_log_w_ofs; + gpSData->w_ptr = w_ptr; + if (gpSData->r_ptr == U32_MAX) { + ov_flg = hw_logger_data->buf_track.__loc_log_ov_flg; + gpSData->ov_flg = ov_flg; + if (ov_flg) + r_ptr = (w_ptr + HWLOG_LINE_MAX_LENS) % HWLOG_LOG_SIZE; + else + r_ptr = 0; + gpSData->r_ptr = r_ptr; + } else { + r_ptr = gpSData->r_ptr; + /* check if overflow occurs */ + if (gpSData->not_rd_sz >= LOCAL_LOG_SIZE - HWLOG_LINE_MAX_LENS) { + r_ptr = (w_ptr + HWLOG_LINE_MAX_LENS) % HWLOG_LOG_SIZE; + gpSData->not_rd_sz = LOCAL_LOG_SIZE - HWLOG_LINE_MAX_LENS; + } + } + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + while (!signal_pending(current) && w_ptr == r_ptr) { + if (w_ptr != r_ptr) + break; + else if (pSData->nonblock) { + kfree(pSData); + dev_dbg(hw_logger_data->dev, "END\n"); + return NULL; + } + usleep_range(10000, 15000); + + /* flush the last hw buffer */ + hw_logger_copy_buf(hw_logger_data); + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + w_ptr = hw_logger_data->buf_track.__loc_log_w_ofs; + ov_flg = hw_logger_data->buf_track.__loc_log_ov_flg; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + }; + + dev_dbg(hw_logger_data->dev, "w_ptr = %d, r_ptr = %d, ov_flg = %d, *pos = %d\n", + w_ptr, r_ptr, ov_flg, (unsigned int)*pos); + + pSData->w_ptr = w_ptr; + pSData->r_ptr = r_ptr; + pSData->ov_flg = ov_flg; + + if (signal_pending(current)) { + dev_dbg(hw_logger_data->dev, "BREAK w_ptr = %d, r_ptr = %d, ov_flg = %d\n", + w_ptr, r_ptr, ov_flg); + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + gpSData->r_ptr = U32_MAX; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + kfree(pSData); + return NULL; + } + + return pSData; +} + +static void *mtk_apu_hw_logger_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + struct hw_log_seq_data *pSData = v; + unsigned long flags; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + pSData->r_ptr = (pSData->r_ptr + HWLOG_LINE_MAX_LENS) % LOCAL_LOG_SIZE; + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + hw_logger_data->g_log.norm_mode.r_ptr = pSData->r_ptr; + *pos = pSData->r_ptr + 1; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + if (pSData->r_ptr != pSData->w_ptr) + return pSData; + + dev_dbg(hw_logger_data->dev, + "END norm_log.w_ptr = %d, norm_log.r_ptr = %d, lock_log.ov_flg = %d\n", + hw_logger_data->g_log.norm_mode.w_ptr, hw_logger_data->g_log.norm_mode.r_ptr, + hw_logger_data->g_log.lock_mode.ov_flg); + + kfree(pSData); + return NULL; +} + +static void *mtk_apu_hw_logger_seq_nextl(struct seq_file *s, void *v, loff_t *pos) +{ + struct hw_log_seq_data *pSData = v, *gpSData; + unsigned long flags; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + if (pSData->nonblock) + gpSData = &hw_logger_data->g_log.mobile_lock_mode; + else + gpSData = &hw_logger_data->g_log.lock_mode; + + dev_dbg(hw_logger_data->dev, + "w_ptr = %d, r_ptr = %d, ov_flg = %d, nonblock = %d, *pos = %d\n", + pSData->w_ptr, pSData->r_ptr, + pSData->ov_flg, pSData->nonblock, (unsigned int)*pos); + + pSData->r_ptr = (pSData->r_ptr + HWLOG_LINE_MAX_LENS) % LOCAL_LOG_SIZE; + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + gpSData->r_ptr = pSData->r_ptr; + gpSData->not_rd_sz -= HWLOG_LINE_MAX_LENS; + *pos = pSData->r_ptr + 1; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + if (pSData->r_ptr != pSData->w_ptr) + return pSData; + + dev_dbg(hw_logger_data->dev, + "END gpSData w_ptr = %d, r_ptr = %d, nonblock = %d, ov_flg = %d\n", + gpSData->w_ptr, gpSData->r_ptr, gpSData->nonblock, + gpSData->ov_flg); + + kfree(pSData); + return NULL; +} + +static void mtk_apu_hw_logger_seq_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static int mtk_apu_hw_logger_seq_show(struct seq_file *s, void *v) +{ + struct hw_log_seq_data *pSData = v; + static unsigned int prevIsBinary; + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + dev_dbg(hw_logger_data->dev, "(%04d)(%d) %s", pSData->r_ptr, + (int)strlen(hw_logger_data->local_log_buf + pSData->r_ptr), + hw_logger_data->local_log_buf + pSData->r_ptr); + + if ((hw_logger_data->local_log_buf[pSData->r_ptr] == 0xA5) && + (hw_logger_data->local_log_buf[pSData->r_ptr+1] == 0xA5)) { + prevIsBinary = 1; + seq_write(s, hw_logger_data->local_log_buf + pSData->r_ptr, HWLOG_LINE_MAX_LENS); + } else { + if (prevIsBinary) + seq_putc(s, '\n'); + prevIsBinary = 0; + *(hw_logger_data->local_log_buf + pSData->r_ptr + HWLOG_LINE_MAX_LENS - 1) = '\0'; + seq_puts(s, hw_logger_data->local_log_buf + pSData->r_ptr); + } + + return 0; +} + +static unsigned int mtk_apu_hw_logger_seq_poll(struct file *file, poll_table *wait) +{ + unsigned int ret = 0; + struct mtk_apu_hw_logger *hw_logger_data; + + if (!(file->f_mode & FMODE_READ)) + return ret; + + hw_logger_data = ((struct seq_file *)file->private_data)->private; + + /* flush the last hw buffer */ + hw_logger_copy_buf(hw_logger_data); + + poll_wait(file, &hw_logger_data->wq_data.apusys_hwlog_wait, wait); + + if (hw_logger_data->g_log.mobile_lock_mode.r_ptr != hw_logger_data->buf_track.__loc_log_w_ofs) + ret = POLLIN | POLLRDNORM; + + return ret; +} + +static const struct seq_operations mtk_apu_hw_logger_log_sops = { + .start = mtk_apu_hw_logger_seq_start, + .next = mtk_apu_hw_logger_seq_next, + .stop = mtk_apu_hw_logger_seq_stop, + .show = mtk_apu_hw_logger_seq_show +}; + +static const struct seq_operations mtk_apu_hw_logger_seq_ops_locked = { + .start = mtk_apu_hw_logger_seq_startl, + .next = mtk_apu_hw_logger_seq_nextl, + .stop = mtk_apu_hw_logger_seq_stop, + .show = mtk_apu_hw_logger_seq_show +}; + +static int debug_sqopen_lock(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &mtk_apu_hw_logger_seq_ops_locked); + + if (!res) + ((struct seq_file *)file->private_data)->private = inode->i_private; + else + pr_err("%s: seq_open failed\n", __func__); + + return res; +} + +DEFINE_SEQ_ATTRIBUTE(mtk_apu_hw_logger_log); + +static const struct file_operations hw_loggerSeqLogL_ops = { + .owner = THIS_MODULE, + .open = debug_sqopen_lock, + .poll = mtk_apu_hw_logger_seq_poll, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +static void clear_local_log_buf(struct mtk_apu_hw_logger *hw_logger_data) +{ + unsigned long flags; + + hw_logger_copy_buf(hw_logger_data); + + mutex_lock(&hw_logger_data->mutex); + + memset(hw_logger_data->local_log_buf, 0, LOCAL_LOG_SIZE); + + spin_lock_irqsave(&hw_logger_data->spinlock, flags); + hw_logger_data->buf_track.__loc_log_w_ofs = 0; + hw_logger_data->buf_track.__loc_log_ov_flg = 0; + hw_logger_data->buf_track.__loc_log_sz = 0; + + hw_logger_data->g_log.norm_mode.w_ptr = 0; + hw_logger_data->g_log.norm_mode.r_ptr = U32_MAX; + hw_logger_data->g_log.norm_mode.ov_flg = 0; + hw_logger_data->g_log.norm_mode.not_rd_sz = 0; + hw_logger_data->g_log.lock_mode.w_ptr = 0; + hw_logger_data->g_log.lock_mode.r_ptr = U32_MAX; + hw_logger_data->g_log.lock_mode.ov_flg = 0; + hw_logger_data->g_log.lock_mode.not_rd_sz = 0; + + hw_logger_data->g_log.mobile_lock_mode.not_rd_sz = 0; + spin_unlock_irqrestore(&hw_logger_data->spinlock, flags); + + mutex_unlock(&hw_logger_data->mutex); +} + +static int mtk_apu_hwlogger_clear_show(struct seq_file *s, void *data) +{ + struct mtk_apu_hw_logger *hw_logger_data = s->private; + + clear_local_log_buf(hw_logger_data); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(mtk_apu_hwlogger_clear); + +static void hw_logger_remove_debugfs(struct mtk_apu_hw_logger *hw_logger_data) +{ + debugfs_remove_recursive(hw_logger_data->log_root); +} + +static int hw_logger_create_debugfs(struct mtk_apu_hw_logger *hw_logger_data) +{ + struct dentry *log_devinfo; + struct dentry *log_devattr; + struct dentry *log_seqlog; + struct dentry *log_seqlogL; + struct dentry *log_clear; + int ret = 0; + + hw_logger_data->log_root = debugfs_create_dir(APUSYS_HWLOGR_DIR, NULL); + ret = IS_ERR_OR_NULL(hw_logger_data->log_root); + if (ret) { + dev_err(hw_logger_data->dev, "create dir fail (%d)\n", ret); + goto out; + } + + log_devinfo = debugfs_create_file("log_level", 0440, hw_logger_data->log_root, + hw_logger_data, &mtk_apu_hwlogger_dbglv_fops); + ret = IS_ERR_OR_NULL(log_devinfo); + if (ret) { + dev_err(hw_logger_data->dev, "create devinfo fail (%d)\n", ret); + goto out; + } + + log_seqlog = debugfs_create_file("seq_log", 0440, hw_logger_data->log_root, + hw_logger_data, &mtk_apu_hw_logger_log_fops); + ret = IS_ERR_OR_NULL(log_seqlog); + if (ret) { + dev_err(hw_logger_data->dev, "create seqlog fail (%d)\n", ret); + goto out; + } + + log_seqlogL = debugfs_create_file("seq_logl", 0440, hw_logger_data->log_root, + hw_logger_data, &hw_loggerSeqLogL_ops); + ret = IS_ERR_OR_NULL(log_seqlogL); + if (ret) { + dev_err(hw_logger_data->dev, "create seqlogL fail (%d)\n", ret); + goto out; + } + + log_devattr = debugfs_create_file("state", 0440, hw_logger_data->log_root, + hw_logger_data, &mtk_apu_hwlogger_attr_fops); + ret = IS_ERR_OR_NULL(log_devattr); + if (ret) { + dev_err(hw_logger_data->dev, "create attr fail (%d)\n", ret); + goto out; + } + + log_clear = debugfs_create_file("clear_log", 0200, hw_logger_data->log_root, + hw_logger_data, &mtk_apu_hwlogger_clear_fops); + ret = IS_ERR_OR_NULL(log_clear); + if (ret) { + dev_err(hw_logger_data->dev, "create clear fail (%d)\n", ret); + goto out; + } + + return 0; + +out: + hw_logger_remove_debugfs(hw_logger_data); + return ret; +} + +static int hw_logger_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_link *link; + struct mtk_apu_hw_logger *hw_logger_data; + struct device_node *apu_power_np; + struct regmap *regmap; + int ret = 0; + + hw_logger_data = devm_kzalloc(dev, sizeof(*hw_logger_data), GFP_KERNEL); + if (!hw_logger_data) + return -ENOMEM; + + hw_logger_data->dev = dev; + + mutex_init(&hw_logger_data->mutex); + spin_lock_init(&hw_logger_data->spinlock); + spin_lock_init(&hw_logger_data->smc_spinlock); + + init_waitqueue_head(&hw_logger_data->wq_data.apusys_hwlog_wait); + + hw_logger_data->apu_logtop = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR((void const *)hw_logger_data->apu_logtop)) { + dev_err(dev, "apu_logtop remap base fail\n"); + ret = -ENOMEM; + return ret; + } + + apu_power_np = of_parse_phandle(dev->of_node, "mediatek,apu-power", 0); + if (!apu_power_np) + return dev_err_probe(dev, -EINVAL, "failed to parse mediatek,apu-power phandle\n"); + + hw_logger_data->power_pdev = of_find_device_by_node(apu_power_np); + of_node_put(apu_power_np); + if (!hw_logger_data->power_pdev) + return dev_err_probe(dev, -EPROBE_DEFER, + "failed to find power device for hw logger\n"); + + link = device_link_add(dev, &hw_logger_data->power_pdev->dev, DL_FLAG_PM_RUNTIME); + if (!link) + return dev_err_probe(dev, -EPROBE_DEFER, + "failed to add device link between hw logger and mtk apu power\n"); + + regmap = mtk_apu_get_mbox_regmap(dev->of_node); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "failed to get mailbox regmap\n"); + + hw_logger_data->log_read_regmap_field = + devm_regmap_field_alloc(dev, regmap, mtk_apu_log_r_reg_field); + if (IS_ERR(hw_logger_data->log_read_regmap_field)) + return dev_err_probe(dev, PTR_ERR(hw_logger_data->log_read_regmap_field), + "failed to allocate log read regmap field\n"); + + hw_logger_data->log_write_regmap_field = + devm_regmap_field_alloc(dev, regmap, mtk_apu_log_w_reg_field); + if (IS_ERR(hw_logger_data->log_write_regmap_field)) + return dev_err_probe(dev, PTR_ERR(hw_logger_data->log_write_regmap_field), + "failed to allocate log write regmap field\n"); + + ret = hw_logger_create_debugfs(hw_logger_data); + if (ret) + return dev_err_probe(dev, ret, "failed to create debugfs for hw logger\n"); + + hw_logger_data->hw_logger_irq_number = platform_get_irq(pdev, 0); + dev_dbg(dev, "hw_logger_irq_number = %d\n", hw_logger_data->hw_logger_irq_number); + + ret = devm_request_threaded_irq(dev, hw_logger_data->hw_logger_irq_number, NULL, + apu_logtop_irq_handler, IRQF_ONESHOT, pdev->name, + hw_logger_data); + if (ret) { + dev_err(dev, "failed to request IRQ %d\n", ret); + goto remove_debugfs; + } + + dev_set_drvdata(dev, hw_logger_data); + + pm_runtime_enable(dev); + + dev_dbg(dev, "%s --\n", __func__); + + return 0; + +remove_debugfs: + hw_logger_remove_debugfs(hw_logger_data); + + return ret; +} + +static int hw_logger_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_apu_hw_logger *hw_logger_data = dev_get_drvdata(dev); + + pm_runtime_disable(dev); + + if (hw_logger_data->hw_logger_irq_number) { + dev_info(dev, "disable hw logger irq\n"); + disable_irq(hw_logger_data->hw_logger_irq_number); + } + + hw_logger_remove_debugfs(hw_logger_data); + + hw_logger_buf_free(dev, hw_logger_data); + + return 0; +} + +static void hw_logger_shutdown(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_apu_hw_logger *hw_logger_data = dev_get_drvdata(dev); + + dev_dbg(dev, "%s ++\n", __func__); + + if (hw_logger_data->hw_logger_irq_number) { + dev_info(dev, "disable hw logger irq\n"); + disable_irq(hw_logger_data->hw_logger_irq_number); + } +} + +static const struct of_device_id apusys_hw_logger_of_match[] = { + { .compatible = "mediatek,apusys-hw-logger"}, + {}, +}; + +static struct platform_driver hw_logger_driver = { + .probe = hw_logger_probe, + .remove = hw_logger_remove, + .shutdown = hw_logger_shutdown, + .driver = { + .name = HWLOG_DEV_NAME, + .of_match_table = of_match_ptr(apusys_hw_logger_of_match), + } +}; + +int mtk_apu_hw_logger_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&hw_logger_driver); + if (ret != 0) { + pr_err("Failed to register mtk_apu hw_logger driver"); + return -ENODEV; + } + + return ret; +} diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c index 3a5fcae12bb06..9c2c6af3968df 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -301,10 +301,14 @@ static int mtk_apu_prepare(struct rproc *rproc) if (ret) return ret; - ret = mtk_apu_timesync_init(apu); + ret = mtk_apu_hw_logger_ipi_init(apu->hw_logger_data, apu); if (ret) goto remove_mtk_apu_ipi; + ret = mtk_apu_timesync_init(apu); + if (ret) + goto remove_apu_hw_logger_ipi; + ret = mtk_apu_exception_init(apu->pdev, apu); if (ret) goto remove_mtk_apu_timesync; @@ -323,6 +327,9 @@ remove_mtk_apu_exception: remove_mtk_apu_timesync: mtk_apu_timesync_remove(apu); +remove_apu_hw_logger_ipi: + mtk_apu_hw_logger_ipi_remove(apu); + remove_mtk_apu_ipi: mtk_apu_ipi_remove(apu); @@ -520,6 +527,12 @@ int mtk_apu_rproc_init(void) { int ret; + ret = mtk_apu_hw_logger_init(); + if (ret) { + pr_err("failed to init hw logger\n"); + return ret; + } + ret = platform_driver_register(&mtk_apu_driver); if (ret) pr_err("failed to register mtk_apu_driver\n"); diff --git a/include/linux/remoteproc/mtk_apu_hw_logger.h b/include/linux/remoteproc/mtk_apu_hw_logger.h new file mode 100644 index 0000000000000..fff14c732a085 --- /dev/null +++ b/include/linux/remoteproc/mtk_apu_hw_logger.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef __MTK_APU_HW_LOGGER_H__ +#define __MTK_APU_HW_LOGGER_H__ + +#include +#include + +struct mtk_apu; + +#define APU_LOGTOP_CON_OFF (0x0) +#define APU_LOG_BUF_ST_ADDR_OFF (0x74) +#define APU_LOG_BUF_T_SIZE_OFF (0x78) +#define APU_LOG_BUF_W_PTR_OFF (0x80) +#define APU_LOG_BUF_R_PTR_OFF (0x84) +#define APU_LOGTOP_CON_FLAG_OFF (APU_LOGTOP_CON_OFF) +#define APU_LOGTOP_CON_FLAG_SHIFT (8) +#define APU_LOGTOP_CON_FLAG_MASK (0xF << APU_LOGTOP_CON_FLAG_SHIFT) +#define APU_LOGTOP_CON_ST_ADDR_HI_OFF (APU_LOGTOP_CON_OFF) +#define APU_LOGTOP_CON_ST_ADDR_HI_SHIFT (4) +#define APU_LOGTOP_CON_ST_ADDR_HI_MASK (0x3 << APU_LOGTOP_CON_ST_ADDR_HI_SHIFT) + +#define LBC_FULL_FLAG BIT(0) +#define OVWRITE_FLAG BIT(2) + +#define HWLOG_LINE_MAX_LENS (128) + +#define HWLOG_LOG_SIZE (1024 * 1024) +#define LOCAL_LOG_SIZE (1024 * 1024) + +#define HW_LOG_INTR_THRESHOLD (10) +#define MAX_SMC_OP_NUM (0x3) + +#define LOG_W_OFS (0x40) +#define LOG_R_OFS (0x44) + +enum { + SMC_OP_APU_LOG_BUF_NULL = 0, + SMC_OP_APU_LOG_BUF_T_SIZE, + SMC_OP_APU_LOG_BUF_W_PTR, + SMC_OP_APU_LOG_BUF_R_PTR, + SMC_OP_APU_LOG_BUF_CON, + SMC_OP_APU_LOG_BUF_NUM +}; + +struct buf_tracking { + unsigned int __loc_log_w_ofs; + unsigned int __loc_log_ov_flg; + unsigned int __loc_log_sz; + unsigned int __hw_log_r_ofs; + unsigned int __hw_log_r_reg; +}; + +struct hw_log_buffer { + char *hw_log_buf; + dma_addr_t hw_log_buf_dma_addr; +}; + +struct hw_log_wq { + struct workqueue_struct *apusys_hwlog_wq; + struct work_struct apusys_hwlog_task; + struct delayed_work apusys_mtklog_task; + wait_queue_head_t apusys_hwlog_wait; + unsigned int w_ofs; + unsigned int r_ofs; + unsigned int t_size; +}; + +struct hw_log_seq_data { + unsigned int w_ptr; + unsigned int r_ptr; + unsigned int ov_flg; + unsigned int not_rd_sz; + bool nonblock; +}; + +struct global_log_data { + struct hw_log_seq_data norm_mode; /* for debugfs normal dump */ + struct hw_log_seq_data lock_mode; /* for debugfs lock dump */ + struct hw_log_seq_data mobile_lock_mode; /* for debugfs mobile logger lock dump */ +}; + +struct mtk_apu_hw_logger { + struct device *dev; + void __iomem *apu_logtop; + atomic_t apu_toplog_deep_idle; + struct buf_tracking buf_track; + struct global_log_data g_log; + struct hw_log_wq wq_data; + struct hw_log_buffer hw_log_buf; + char *local_log_buf; + struct mtk_apu *apu; + struct dentry *log_root; + unsigned int hw_ipi_log_level; + unsigned int access_rcx_in_atf; + unsigned int enable_interrupt; + unsigned int hw_log_lbc_size; + int hw_logger_irq_number; + int burst_intr_cnt; + int (*apu_ipi_send_ptr)(struct mtk_apu*, u32, void*, u32, u32); + struct mutex mutex; /* for buffer copying */ + spinlock_t spinlock; /* for accessing hw_logger members*/ + spinlock_t smc_spinlock; /* for executing smc operation*/ + struct regmap_field *log_read_regmap_field; + struct regmap_field *log_write_regmap_field; + struct platform_device *power_pdev; +}; + +int mtk_apu_hw_logger_ipi_init(struct mtk_apu_hw_logger *hw_logger_data, struct mtk_apu *apu); +void mtk_apu_hw_logger_ipi_remove(struct mtk_apu *apu); + +dma_addr_t mtk_apu_hw_logger_config_init(struct mtk_apu_hw_logger *hw_logger_data); +struct mtk_apu_hw_logger *get_mtk_apu_hw_logger_device(struct device_node *hw_logger_np); + +int mtk_apu_hw_logger_init(void); + +#endif /* __MTK_APU_HW_LOGGER_H__ */ -- GitLab From 3bc19a54e54c668be389e2656ccf3374789ece9f Mon Sep 17 00:00:00 2001 From: Karl Li Date: Thu, 2 Jan 2025 14:34:24 +0800 Subject: [PATCH 427/456] CHROMIUM: remoteproc: mediatek: Enable APU rproc building Add Kconfig to build APU rproc driver. UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Ie26008f6b17564b21faa7de18c4e26ce5978bcc9 Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6166788 Tested-by: Chen-Yu Tsai Reviewed-by: Fei Shao Commit-Queue: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- drivers/remoteproc/Kconfig | 13 +++++++++++++ drivers/remoteproc/Makefile | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 48845dc8fa852..ff5f5f1e32600 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -54,6 +54,19 @@ config INGENIC_VPU_RPROC This can be either built-in or a loadable module. If unsure say N. +config MTK_APU_RPROC + tristate "MediaTek APU remoteproc support" + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on ARM || ARM64 + select MAILBOX + select MTK_APU_MBOX + select MTK_APUSYS_SUPPORT + help + Say y here to support MediaTek AI Processing Unit Subsystem + via the remote processor framework. + + It's safe to say N here. + config MTK_SCP tristate "Mediatek SCP support" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 91314a9b43cef..4616f00fb463d 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -14,6 +14,16 @@ obj-$(CONFIG_REMOTEPROC_CDEV) += remoteproc_cdev.o obj-$(CONFIG_IMX_REMOTEPROC) += imx_rproc.o obj-$(CONFIG_IMX_DSP_REMOTEPROC) += imx_dsp_rproc.o obj-$(CONFIG_INGENIC_VPU_RPROC) += ingenic_rproc.o +obj-$(CONFIG_MTK_APU_RPROC) += mtk_apusys.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_config.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_excep.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_ipi.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_loadimage.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_mem.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_rproc.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_timesync.o +mtk_apusys-objs += mediatek_apusys/mtk_apu_hw_logger.o +mtk_apusys-objs += mediatek_apusys/plat/mt8196_plat.o obj-$(CONFIG_MTK_SCP) += mtk_scp.o mtk_scp_ipi.o obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o -- GitLab From b6701d65018bed8e2b5c0924a10720d6ef578de7 Mon Sep 17 00:00:00 2001 From: Karl Li Date: Fri, 27 Sep 2024 14:35:50 +0800 Subject: [PATCH 428/456] CHROMIUM: soc: mediatek: Add APU mvpu, mdw, apummu driver Add APU mvpu, mdw, apummu driver UPSTREAM-TASK=b:379040514 BUG=b:365876446 TEST=emerge-rauru chromeos-kernel-6_6 Change-Id: Iac23d6c4f9afe44e743cab5f73cc3203c97d27ee Signed-off-by: Karl Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6083913 Tested-by: Chen-Yu Tsai Commit-Queue: Chen-Yu Tsai Reviewed-by: Hsin-Te Yuan Signed-off-by: Hubert Mazur --- .../mediatek_apusys/mtk_apu_config.c | 8 + .../remoteproc/mediatek_apusys/mtk_apu_ipi.c | 64 +- .../mediatek_apusys/mtk_apu_rproc.c | 4 + .../mediatek_apusys/mtk_apu_rproc.h | 1 + drivers/soc/mediatek/apusys/Makefile | 72 + .../mediatek/apusys/apu_mem/apu_mem_export.c | 198 ++ .../apu_mem/apummu/common/apummu_boot.c | 693 ++++++ .../apusys/apu_mem/apummu/common/apummu_cmn.h | 88 + .../apusys/apu_mem/apummu/common/apummu_dbg.c | 331 +++ .../apusys/apu_mem/apummu/common/apummu_dbg.h | 15 + .../apusys/apu_mem/apummu/common/apummu_drv.c | 641 +++++ .../apusys/apu_mem/apummu/common/apummu_drv.h | 93 + .../apu_mem/apummu/common/apummu_export.c | 436 ++++ .../apu_mem/apummu/common/apummu_import.c | 112 + .../apu_mem/apummu/common/apummu_import.h | 17 + .../apusys/apu_mem/apummu/common/apummu_mem.c | 815 ++++++ .../apusys/apu_mem/apummu/common/apummu_mem.h | 34 + .../apusys/apu_mem/apummu/common/apummu_mgt.c | 992 ++++++++ .../apusys/apu_mem/apummu/common/apummu_mgt.h | 89 + .../apusys/apu_mem/apummu/common/apummu_msg.h | 49 + .../apu_mem/apummu/common/apummu_remote.c | 220 ++ .../apu_mem/apummu/common/apummu_remote.h | 38 + .../apu_mem/apummu/common/apummu_remote_cmd.c | 357 +++ .../apu_mem/apummu/common/apummu_remote_cmd.h | 41 + .../apu_mem/apummu/common/apummu_trace.h | 10 + .../apu_mem/apummu/platform/apummu_device.c | 27 + .../apu_mem/apummu/platform/apummu_device.h | 12 + .../apu_mem/apummu/platform/apummu_plat.c | 45 + .../apu_mem/apummu/platform/apummu_plat.h | 19 + .../mediatek/apusys/midware/2.0/cmd/mdw_cmd.h | 83 + .../apusys/midware/2.0/cmd/mdw_cmd_cmn.c | 815 ++++++ .../apusys/midware/2.0/cmd/mdw_cmd_v2.c | 341 +++ .../apusys/midware/2.0/cmd/mdw_cmd_v3.c | 439 ++++ .../apusys/midware/2.0/cmd/mdw_cmd_v4.c | 1187 +++++++++ .../mediatek/apusys/midware/2.0/ext/mdw_ext.c | 96 + .../mediatek/apusys/midware/2.0/ext/mdw_ext.h | 31 + .../apusys/midware/2.0/ext/mdw_ext_cmd.c | 149 ++ .../apusys/midware/2.0/ext/mdw_ext_cmn.h | 51 + .../apusys/midware/2.0/ext/mdw_ext_export.h | 20 + .../apusys/midware/2.0/ext/mdw_ext_hs.c | 38 + .../apusys/midware/2.0/ext/mdw_ext_ioctl.c | 63 + .../apusys/midware/2.0/ext/mdw_ext_ioctl.h | 69 + drivers/soc/mediatek/apusys/midware/2.0/mdw.h | 534 ++++ .../soc/mediatek/apusys/midware/2.0/mdw_cmd.c | 12 + .../soc/mediatek/apusys/midware/2.0/mdw_cmn.c | 22 + .../soc/mediatek/apusys/midware/2.0/mdw_cmn.h | 78 + .../soc/mediatek/apusys/midware/2.0/mdw_ctx.c | 15 + .../soc/mediatek/apusys/midware/2.0/mdw_dbg.c | 125 + .../soc/mediatek/apusys/midware/2.0/mdw_dev.c | 151 ++ .../soc/mediatek/apusys/midware/2.0/mdw_drv.c | 331 +++ .../soc/mediatek/apusys/midware/2.0/mdw_hs.c | 87 + .../mediatek/apusys/midware/2.0/mdw_import.c | 109 + .../mediatek/apusys/midware/2.0/mdw_import.h | 27 + .../mediatek/apusys/midware/2.0/mdw_ioctl.c | 70 + .../mediatek/apusys/midware/2.0/mdw_ioctl.h | 341 +++ .../soc/mediatek/apusys/midware/2.0/mdw_mem.c | 1131 +++++++++ .../soc/mediatek/apusys/midware/2.0/mdw_mem.h | 12 + .../apusys/midware/2.0/mdw_mem_aram.c | 307 +++ .../mediatek/apusys/midware/2.0/mdw_mem_dma.c | 467 ++++ .../mediatek/apusys/midware/2.0/mdw_mem_drv.c | 118 + .../mediatek/apusys/midware/2.0/mdw_mem_drv.h | 12 + .../apusys/midware/2.0/mdw_mem_pool.c | 385 +++ .../apusys/midware/2.0/mdw_mem_pool.h | 23 + .../mediatek/apusys/midware/2.0/mdw_mem_rsc.c | 106 + .../mediatek/apusys/midware/2.0/mdw_mem_rsc.h | 33 + .../mediatek/apusys/midware/2.0/mdw_sysfs.c | 340 +++ .../mediatek/apusys/midware/2.0/mdw_sysfs.h | 12 + .../mediatek/apusys/midware/2.0/mdw_trace.h | 11 + .../mediatek/apusys/midware/2.0/mdw_util.c | 89 + .../mediatek/apusys/midware/2.0/rv/mdw_rv.c | 229 ++ .../mediatek/apusys/midware/2.0/rv/mdw_rv.h | 82 + .../apusys/midware/2.0/rv/mdw_rv_cmd_v2.c | 327 +++ .../apusys/midware/2.0/rv/mdw_rv_cmd_v3.c | 363 +++ .../apusys/midware/2.0/rv/mdw_rv_cmd_v4.c | 446 ++++ .../apusys/midware/2.0/rv/mdw_rv_dev.c | 583 +++++ .../apusys/midware/2.0/rv/mdw_rv_events.h | 236 ++ .../apusys/midware/2.0/rv/mdw_rv_msg.h | 107 + .../apusys/midware/2.0/rv/mdw_rv_tag.c | 403 +++ .../apusys/midware/2.0/rv/mdw_rv_tag.h | 78 + .../mediatek/apusys/mvpu/common/mvpu_config.c | 183 ++ .../mediatek/apusys/mvpu/common/mvpu_driver.c | 183 ++ .../mediatek/apusys/mvpu/common/mvpu_driver.h | 11 + .../mediatek/apusys/mvpu/common/mvpu_plat.c | 80 + .../mediatek/apusys/mvpu/common/mvpu_plat.h | 78 + .../mediatek/apusys/mvpu/common/mvpu_sysfs.c | 91 + .../mediatek/apusys/mvpu/common/mvpu_sysfs.h | 13 + .../mvpu/platform/v2/2.5/mvpu25_handler.c | 69 + .../mvpu/platform/v2/2.5/mvpu25_handler.h | 17 + .../apusys/mvpu/platform/v2/2.5/mvpu25_ipi.c | 294 +++ .../apusys/mvpu/platform/v2/2.5/mvpu25_ipi.h | 29 + .../mvpu/platform/v2/2.5/mvpu25_platdata.c | 37 + .../mvpu/platform/v2/2.5/mvpu25_request.h | 72 + .../apusys/mvpu/platform/v2/2.5/mvpu25_sec.c | 2211 +++++++++++++++++ .../apusys/mvpu/platform/v2/2.5/mvpu25_sec.h | 344 +++ .../mvpu/platform/v2/2.5/mvpu25_valid.c | 1027 ++++++++ .../mvpu/platform/v2/2.5/mvpu25_valid.h | 10 + .../apusys/mvpu/platform/v2/mvpu2_cmd_data.h | 83 + drivers/soc/mediatek/apusys/slbc_ops.h | 308 +++ include/linux/soc/mediatek/apu_mem_def.h | 52 + include/linux/soc/mediatek/apu_mem_export.h | 40 + include/linux/soc/mediatek/apu_mvpu_config.h | 13 + include/linux/soc/mediatek/apummu_export.h | 77 + include/linux/soc/mediatek/apummu_mem_def.h | 62 + include/linux/soc/mediatek/apummu_tbl.h | 473 ++++ include/linux/soc/mediatek/mtk_apu_device.h | 104 + 105 files changed, 22664 insertions(+), 2 deletions(-) create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apu_mem_export.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_boot.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_cmn.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_export.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_msg.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_trace.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.h create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.c create mode 100644 drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_cmn.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v2.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v3.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v4.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmd.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmn.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_export.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_hs.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_cmd.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_ctx.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_dbg.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_dev.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_drv.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_hs.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_import.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_import.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_aram.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_dma.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_trace.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/mdw_util.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v2.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v3.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v4.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_dev.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_events.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_msg.h create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.c create mode 100644 drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_config.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_platdata.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_request.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.c create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.h create mode 100644 drivers/soc/mediatek/apusys/mvpu/platform/v2/mvpu2_cmd_data.h create mode 100644 drivers/soc/mediatek/apusys/slbc_ops.h create mode 100644 include/linux/soc/mediatek/apu_mem_def.h create mode 100644 include/linux/soc/mediatek/apu_mem_export.h create mode 100644 include/linux/soc/mediatek/apu_mvpu_config.h create mode 100644 include/linux/soc/mediatek/apummu_export.h create mode 100644 include/linux/soc/mediatek/apummu_mem_def.h create mode 100644 include/linux/soc/mediatek/apummu_tbl.h create mode 100644 include/linux/soc/mediatek/mtk_apu_device.h diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c index 9ab2bd543ce2b..b98a506d80aa8 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_config.c @@ -14,6 +14,7 @@ #include #include #include "mtk_apu_rproc.h" +#include "linux/soc/mediatek/apu_mvpu_config.h" #define MTK_APU_CONFIG_HEADER_MAGIC (0xc0de0101) #define MTK_APU_CONFIG_HEADER_REV (0x1) @@ -107,6 +108,12 @@ int mtk_apu_config_setup(struct mtk_apu *apu) } } + ret = mvpu_config_init(apu); + if (ret) { + dev_info(apu->dev, "mvpu config init failed\n"); + goto free_apu_conf_buf; + } + mdla_rv_mem = (struct mtk_apu_mdla_rv_mem *) get_mtk_apu_config_user_ptr(apu->conf_buf, eMDLA_MEM_INFO); @@ -131,6 +138,7 @@ free_apu_conf_buf: void mtk_apu_config_remove(struct mtk_apu *apu) { mtk_apu_ipi_config_remove(apu); + mvpu_config_remove(apu); dma_free_coherent(apu->dev, CONFIG_SIZE, apu->conf_buf, apu->conf_da); } diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c index adac562ae0bb7..bb6232d0439a8 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_ipi.c @@ -27,6 +27,45 @@ struct mtk_apu_mbox_send_hdr { struct mtk_apu_mbox_hdr *hdr; }; +static int power_dtime; + +static void mtk_apu_update_power_dtime(int dtime) +{ + power_dtime = dtime; +} + +static void mtk_apu_timer_callback(struct timer_list *timer) +{ + struct mtk_apu *apu = container_of(timer, struct mtk_apu, power_off_timer); + + mtk_apu_power_on_off(apu->pdev, MTK_APU_IPI_MIDDLEWARE, 0, 1); +} + +static void mtk_apu_power_dtime_handler(struct mtk_apu *apu, int dtime) +{ + uint64_t ts = sched_clock(); + uint64_t dtime_ts; + unsigned long power_dtime = 0; + + dtime = (dtime > MAX_DTIME)? MAX_DTIME: dtime; + dtime = (dtime < MIN_DTIME)? MIN_DTIME: dtime; + + dtime_ts = ts + dtime; + if (apu->cur_dtime_ts < dtime_ts) + apu->cur_dtime_ts = dtime_ts; + else + return; + + if (timer_pending(&apu->power_off_timer)) { + apu->ipi_pwr_ref_cnt[MTK_APU_IPI_MIDDLEWARE]--; + apu->local_pwr_ref_cnt--; + } + + power_dtime = msecs_to_jiffies(apu->cur_dtime_ts - ts); + + mod_timer(&apu->power_off_timer, jiffies + power_dtime); +} + static uint32_t calculate_csum(void *data, uint32_t len) { uint32_t csum = 0, res = 0, i; @@ -235,6 +274,7 @@ static void mtk_apu_ipi_bottom_handle(struct mbox_client *cl, void *mssg) struct device *dev = apu->dev; ipi_handler_t handler; + bool power_off_directly; id = apu->ipi_task.id; len = apu->ipi_task.len; @@ -266,8 +306,22 @@ static void mtk_apu_ipi_bottom_handle(struct mbox_client *cl, void *mssg) wake_up(&apu->ack_wq); - if (apu->platdata->flags.fast_on_off && ipi_attrs[id].direction == IPI_HOST_INITIATE) - mtk_apu_power_on_off(apu->pdev, id, 0, 1); + if (apu->platdata->flags.fast_on_off && ipi_attrs[id].direction == IPI_HOST_INITIATE) { + if (power_dtime == 0) { + power_off_directly = true; + } else { + mutex_lock(&apu->forbid_ipi_lock); + power_off_directly = apu->forbid_ipi_send; + mutex_unlock(&apu->forbid_ipi_lock); + } + + if (power_off_directly) { + mtk_apu_power_on_off(apu->pdev, id, 0, 1); + } else { + mtk_apu_power_dtime_handler(apu, power_dtime); + power_dtime = 0; + } + } } static void mtk_apu_ipi_handle_rx(struct mbox_client *cl, void *mssg) @@ -521,6 +575,9 @@ int mtk_apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu) goto remove_rpmsg_subdev; } + timer_setup(&apu->power_off_timer, mtk_apu_timer_callback, 0); + mtk_apu_init_mdw_dtime_setting(mtk_apu_update_power_dtime); + return 0; remove_rpmsg_subdev: @@ -532,6 +589,9 @@ remove_rpmsg_subdev: void mtk_apu_ipi_remove(struct mtk_apu *apu) { + if (timer_pending(&apu->power_off_timer)) + del_timer(&apu->power_off_timer); + if (!IS_ERR(apu->ch)) mbox_free_channel(apu->ch); mtk_apu_remove_rpmsg_subdev(apu); diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c index 9c2c6af3968df..04de2126a1ef6 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.c @@ -455,6 +455,8 @@ static int mtk_apu_probe(struct platform_device *pdev) ret); } + mtk_apu_init_mdw_dev(dev); + spin_lock_init(&apu->reg_lock); if (!hw_ops->mtk_apu_memmap_init) { @@ -541,6 +543,8 @@ int mtk_apu_rproc_init(void) } MODULE_IMPORT_NS(MTK_APU_PWR); +MODULE_IMPORT_NS(MTK_APU_MDW); +MODULE_IMPORT_NS(MTK_APU_MVPU); MODULE_SOFTDEP("pre: mtk-apu-mailbox"); diff --git a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h index b24c59e2f92a3..161e587965ce2 100644 --- a/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h +++ b/drivers/remoteproc/mediatek_apusys/mtk_apu_rproc.h @@ -23,5 +23,6 @@ void mtk_apu_exception_exit(struct platform_device *pdev, struct mtk_apu *apu); void mtk_apu_init_mdw_dtime_setting(void (*update_power_dtime)(int dtime)); uint32_t mtk_apu_rv_smc_call(struct device *dev, uint32_t smc_id, uint32_t a2); struct regmap *mtk_apu_get_mbox_regmap(struct device_node *node); +void mtk_apu_init_mdw_dev(struct device *dev); #endif /* MTK_APU_RPROC_H */ diff --git a/drivers/soc/mediatek/apusys/Makefile b/drivers/soc/mediatek/apusys/Makefile index eff2e9fa81ab3..a1fbf41df4264 100644 --- a/drivers/soc/mediatek/apusys/Makefile +++ b/drivers/soc/mediatek/apusys/Makefile @@ -1,3 +1,75 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += mtk_apu_mdw.o +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += mtk_apu_mem.o +obj-$(CONFIG_MTK_APUSYS_SUPPORT) += mtk_apu_mvpu.o obj-$(CONFIG_MTK_APUSYS_SUPPORT) += power/ + +APUSYS_PATH="$(srctree)/$(DEVICE_MODULES_REL_DIR)/drivers/soc/mediatek/apusys" + +# midware +ccflags-y += -I$(APUSYS_PATH)/midware/2.0/ +ccflags-y += -I$(APUSYS_PATH)/midware/2.0/rv/ +ccflags-y += -I$(APUSYS_PATH)/midware/2.0/ext/ +ccflags-y += -I$(APUSYS_PATH)/midware/2.0/cmd/ +mtk_apu_mdw-objs += midware/2.0/mdw_mem_drv.o +mtk_apu_mdw-objs += midware/2.0/mdw_mem_rsc.o +mtk_apu_mdw-objs += midware/2.0/mdw_drv.o +mtk_apu_mdw-objs += midware/2.0/mdw_ctx.o +mtk_apu_mdw-objs += midware/2.0/mdw_dev.o +mtk_apu_mdw-objs += midware/2.0/mdw_ioctl.o +mtk_apu_mdw-objs += midware/2.0/mdw_mem.o +mtk_apu_mdw-objs += midware/2.0/mdw_mem_dma.o +mtk_apu_mdw-objs += midware/2.0/mdw_mem_aram.o +mtk_apu_mdw-objs += midware/2.0/mdw_mem_pool.o +mtk_apu_mdw-objs += midware/2.0/mdw_cmd.o +mtk_apu_mdw-objs += midware/2.0/cmd/mdw_cmd_v2.o +mtk_apu_mdw-objs += midware/2.0/cmd/mdw_cmd_v3.o +mtk_apu_mdw-objs += midware/2.0/cmd/mdw_cmd_v4.o +mtk_apu_mdw-objs += midware/2.0/cmd/mdw_cmd_cmn.o +mtk_apu_mdw-objs += midware/2.0/mdw_cmn.o +mtk_apu_mdw-objs += midware/2.0/mdw_hs.o +mtk_apu_mdw-objs += midware/2.0/mdw_sysfs.o +mtk_apu_mdw-objs += midware/2.0/mdw_dbg.o +mtk_apu_mdw-objs += midware/2.0/mdw_import.o +mtk_apu_mdw-objs += midware/2.0/mdw_util.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv_cmd_v2.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv_cmd_v3.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv_cmd_v4.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv_dev.o +mtk_apu_mdw-objs += midware/2.0/rv/mdw_rv_tag.o +mtk_apu_mdw-objs += midware/2.0/ext/mdw_ext.o +mtk_apu_mdw-objs += midware/2.0/ext/mdw_ext_ioctl.o +mtk_apu_mdw-objs += midware/2.0/ext/mdw_ext_cmd.o +mtk_apu_mdw-objs += midware/2.0/ext/mdw_ext_hs.o + +# apummu +ccflags-y += -I$(srctree)/$(src)/ +mtk_apu_mem-objs += apu_mem/apu_mem_export.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_boot.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_drv.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_dbg.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_export.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_import.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_mem.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_remote.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_remote_cmd.o +mtk_apu_mem-objs += apu_mem/apummu/common/apummu_mgt.o +mtk_apu_mem-objs += apu_mem/apummu/platform/apummu_device.o +mtk_apu_mem-objs += apu_mem/apummu/platform/apummu_plat.o + +# mvpu +ccflags-y += -I$(srctree)/$(DEVICE_MODULES_REL_DIR)/drivers/soc/mediatek/apusys/mvpu/common/ +ccflags-y += -I$(srctree)/$(DEVICE_MODULES_REL_DIR)/drivers/soc/mediatek/apusys/mvpu/platform/v2/ +ccflags-y += -I$(srctree)/$(DEVICE_MODULES_REL_DIR)/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/ +mtk_apu_mvpu-objs += mvpu/common/mvpu_driver.o +mtk_apu_mvpu-objs += mvpu/common/mvpu_plat.o +mtk_apu_mvpu-objs += mvpu/common/mvpu_sysfs.o +mtk_apu_mvpu-objs += mvpu/common/mvpu_config.o +subdir-ccflags-y += -DMVPU_V25_PLAT_DATA +mtk_apu_mvpu-objs += mvpu/platform/v2/2.5/mvpu25_ipi.o +mtk_apu_mvpu-objs += mvpu/platform/v2/2.5/mvpu25_sec.o +mtk_apu_mvpu-objs += mvpu/platform/v2/2.5/mvpu25_platdata.o +mtk_apu_mvpu-objs += mvpu/platform/v2/2.5/mvpu25_valid.o +mtk_apu_mvpu-objs += mvpu/platform/v2/2.5/mvpu25_handler.o diff --git a/drivers/soc/mediatek/apusys/apu_mem/apu_mem_export.c b/drivers/soc/mediatek/apusys/apu_mem/apu_mem_export.c new file mode 100644 index 0000000000000..98f59fc0a2e02 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apu_mem_export.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include + +#include "linux/soc/mediatek/apu_mem_export.h" +#include "linux/soc/mediatek/apummu_export.h" + +struct apu_mem_op_set { + struct apu_mem_export_ops *apu_mem_ops; + bool is_OP_init; +}; + +static struct apu_mem_op_set apu_mem_plat_op_set; + +#define APU_MEM_LOG_ERR(x, args...) \ + pr_info("[APU_MEM][error] %s " x, __func__, ##args) + +int apu_mem_op_init(struct apu_mem_export_ops *apu_mem_init_ops) +{ + if (apu_mem_plat_op_set.is_OP_init) { + APU_MEM_LOG_ERR("apu_mem op already init!!\n"); + return -EACCES; + } + + apu_mem_plat_op_set.apu_mem_ops = apu_mem_init_ops; + + apu_mem_plat_op_set.is_OP_init = true; + return 0; +} + +/* Common API */ +int apu_mem_alloc(uint32_t type, uint32_t size, uint64_t *addr, uint32_t *sid) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_alloc == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_alloc(type, size, addr, sid); +} +EXPORT_SYMBOL_NS(apu_mem_alloc, MTK_APU_MEM); + +int apu_mem_free(uint32_t sid) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_free == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_free(sid); +} +EXPORT_SYMBOL_NS(apu_mem_free, MTK_APU_MEM); + +int apu_mem_import(uint64_t session, uint32_t sid) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_import == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_import(session, sid); +} +EXPORT_SYMBOL_NS(apu_mem_import, MTK_APU_MEM); + +int apu_mem_unimport(uint64_t session, uint32_t sid) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_unimport == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_unimport(session, sid); +} +EXPORT_SYMBOL_NS(apu_mem_unimport, MTK_APU_MEM); + +int apu_mem_map(uint64_t session, uint32_t sid, uint64_t *addr) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_map == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_map(session, sid, addr); +} +EXPORT_SYMBOL_NS(apu_mem_map, MTK_APU_MEM); + +int apu_mem_unmap(uint64_t session, uint32_t sid) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_unmap == NULL) { + APU_MEM_LOG_ERR("%s is NULL!!\n", __func__); + return -EACCES; + } + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_unmap(session, sid); +} +EXPORT_SYMBOL_NS(apu_mem_unmap, MTK_APU_MEM); + +/* Reviser only API */ +int apu_mem_rvs_get_vlm(uint32_t request_size, bool force, unsigned long *ctx, uint32_t *tcm_size) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_vlm == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_vlm(request_size, force, + ctx, tcm_size); +} + +int apu_mem_rvs_free_vlm(uint32_t ctx) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_free_vlm == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_free_vlm(ctx); +} + +int apu_mem_rvs_set_context(int type, int index, uint8_t ctx) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_set_context == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_set_context(type, index, ctx); +} + +int apu_mem_rvs_get_resource_vlm(uint32_t *addr, uint32_t *size) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_resource_vlm == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_resource_vlm(addr, size); +} + +int apu_mem_rvs_get_pool_size(uint32_t type, uint32_t *size) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_pool_size == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_rvs_get_pool_size(type, size); +} + +/* APUMMU only API */ +int apu_mem_map_iova(uint32_t type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_map_iova == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_map_iova(type, session, + device_va, buf_size, eva); +} +EXPORT_SYMBOL_NS(apu_mem_map_iova, MTK_APU_MEM); + +int apu_mem_iova_decode(uint64_t eva, uint64_t *iova) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_iova_decode == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_iova_decode(eva, iova); +} +EXPORT_SYMBOL_NS(apu_mem_iova_decode, MTK_APU_MEM); + +int apu_mem_unmap_iova(uint64_t session, uint64_t device_va, uint32_t buf_size) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_unmap_iova == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_unmap_iova(session, device_va, buf_size); +} + +int apu_mem_table_get(uint64_t session, void **tbl_kva, uint32_t *size) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_table_get == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_table_get(session, tbl_kva, size); +} +EXPORT_SYMBOL_NS(apu_mem_table_get, MTK_APU_MEM); + +int apu_mem_table_free(uint64_t session) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_table_free == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_table_free(session); +} +EXPORT_SYMBOL_NS(apu_mem_table_free, MTK_APU_MEM); + +int apu_mem_DRAM_FB_alloc(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num) +{ + if (apu_mem_plat_op_set.apu_mem_ops->apu_mem_DRAM_FB_alloc == NULL) + return -EOPNOTSUPP; + + return apu_mem_plat_op_set.apu_mem_ops->apu_mem_DRAM_FB_alloc(session, + vlm_size, subcmd_num); +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_boot.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_boot.c new file mode 100644 index 0000000000000..a1a00131c60bf --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_boot.c @@ -0,0 +1,693 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include "linux/soc/mediatek/apummu_tbl.h" + +/* + * CMU + * #define APUMMU_CMU_TOP_BASE 0x19067000, apb register, 1k + * TCU + * RCX + * #define APUMMU_RCX_UPRV_TCU_BASE 0x19060000 + * #define APUMMU_RCX_EXTM_TCU_BASE 0x19061000 + * #define APUMMU_RCX_EDPA_TCU_BASE 0x19062000 + * #define APUMMU_RCX_MDLA_TCU_BASE 0x19063000 + */ + +#ifdef linux_ep +void *ammu_cmu_top_base; +void *ammu_rcx_uprv_tcu_base; +void *ammu_rcx_extm_tcu_base; +#ifdef SMMU_EN +void *ammu_vcore_config_base; +#endif + +int apummu_ioremap(void) +{ + /* ammu_cmu_top_base = ioremap(APUMMU_CMU_TOP_BASE, 0x5000); */ + ammu_cmu_top_base = ioremap(APUMMU_CMU_TOP_REG_BASE, 0x7000); + ammu_rcx_uprv_tcu_base = ioremap(APUMMU_RCX_UPRV_TCU_REG_BASE, 0x1000); + ammu_rcx_extm_tcu_base = ioremap(APUMMU_RCX_EXTM_TCU_REG_BASE, 0x1000); +#ifdef SMMU_EN + ammu_vcore_config_base = ioremap(APUMMU_VCORE_CONFIG_REGISTER, 0x4); + + printf("ammu remap: CMU(0x%llx), RV TCU(0x%llx), EXTM TCU(0x%llx), SMMU CFG(0x%llx)\n", + (uint64_t)ammu_cmu_top_base, + (uint64_t)ammu_rcx_uprv_tcu_base, + (uint64_t)ammu_rcx_extm_tcu_base, + (uint64_t)ammu_vcore_config_base); +#else + printf("ammu remap adr: CMUL(0x%llx), RV TCU(0x%llx) , EXTM TCU(0x%llx)\n", + (uint64_t)ammu_cmu_top_base, + (uint64_t)ammu_rcx_uprv_tcu_base, + (uint64_t)ammu_rcx_extm_tcu_base); +#endif + + return 0; +} +#else /* non linux ep */ + +static const mmap_region_t apusys_ammu_mmap[] MTK_MMAP_SECTION = { + MAP_REGION_FLAT(APU_CMU_TOP, APU_CMU_TOP_SZ, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(APU_RCX_UPRV_TCU, APU_RCX_UPRV_TCU_SZ, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(APU_RCX_EXTM_TCU, APU_RCX_EXTM_TCU_SZ, + MT_DEVICE | MT_RW | MT_SECURE), + {0} +}; +DECLARE_MTK_MMAP_REGIONS(apusys_ammu_mmap); +#endif /* end ep */ + + +/* Get vsid segment 0x00 */ +int apummu_get_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t *input_adr, + uint8_t *res_bits, uint8_t *page_sel, uint8_t *page_len) +{ + //check abnormal parameter + //printf parameters + *input_adr = APUMMU_SEGMENT_GET_INPUT(vsid_idx, seg_idx); + *res_bits = APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid_idx, seg_idx); + *page_sel = APUMMU_SEGMENT_GET_PAGESEL(vsid_idx, seg_idx); + *page_len = APUMMU_SEGMENT_GET_PAGELEN(vsid_idx, seg_idx); + + return 0; //indicate success or fail +} + +/* Get vsid segment 0x04 */ +void apummu_get_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, + uint32_t *output_adr, uint8_t *res_bits0, + uint8_t *SMMU_en, uint8_t *res_bits1) +{ + *output_adr = APUMMU_SEGMENT_GET_OUTPUT(vsid_idx, seg_idx); + *res_bits0 = APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid_idx, seg_idx); + *SMMU_en = APUMMU_SEGMENT_GET_MMU_EN(vsid_idx, seg_idx); + *res_bits1 = APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid_idx, seg_idx); +} + +/* Get vsid segment 0x08 */ +void apummu_get_segment_offset2(uint32_t vsid_idx, uint8_t seg_idx, + uint8_t *domain, uint8_t *acp_en, + uint8_t *aw_clr, uint8_t *aw_invalid, + uint8_t *ar_exclu, uint8_t *ar_sepcu, + uint8_t *aw_cache_alloc, uint8_t *aw_slc_en, + uint8_t *aw_slb_en, uint8_t *ar_cache_alloc, + uint8_t *ar_slc_en, uint8_t *ar_slb_en, + uint8_t *ns) +{ + *domain = APUMMU_SEGMENT_GET_DOMAIN(vsid_idx, seg_idx); + *acp_en = APUMMU_SEGMENT_GET_ACP_EN(vsid_idx, seg_idx); + *aw_clr = APUMMU_SEGMENT_GET_AW_CLR(vsid_idx, seg_idx); + *aw_invalid = APUMMU_SEGMENT_GET_AW_INVALID(vsid_idx, seg_idx); + *ar_exclu = APUMMU_SEGMENT_GET_AR_EXCLU(vsid_idx, seg_idx); + *ar_sepcu = APUMMU_SEGMENT_GET_AR_SEPCU(vsid_idx, seg_idx); + *aw_cache_alloc = APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid_idx, seg_idx); + *aw_slc_en = APUMMU_SEGMENT_GET_AW_SLC_EN(vsid_idx, seg_idx); + *aw_slb_en = APUMMU_SEGMENT_GET_AW_SLB_EN(vsid_idx, seg_idx); + *ar_cache_alloc = APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid_idx, seg_idx); + *ar_slc_en = APUMMU_SEGMENT_GET_AR_SLC_EN(vsid_idx, seg_idx); + *ar_slb_en = APUMMU_SEGMENT_GET_AR_SLB_EN(vsid_idx, seg_idx); + *ns = APUMMU_SEGMENT_GET_NS(vsid_idx, seg_idx); +} + +void apummu_get_segment_offset3(uint32_t vsid_idx, uint8_t seg_idx, + uint8_t *seg_valid) +{ + *seg_valid = APUMMU_SEGMENT_GET_SEG_VALID(vsid_idx, seg_idx); +} + + +/* Set vsid segment 0x00 */ +void apummu_set_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr, + uint8_t res_bits, uint8_t page_sel, uint8_t page_len) +{ + /* check abnormal parameter + * printf parameters + */ + DRV_WriteReg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 0), + APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, res_bits, page_sel, page_len)); +} + + +/* Set vsid segment 0x04 */ +void apummu_set_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, uint32_t output_adr, + uint8_t res0, uint8_t smmu_en, uint8_t res1) +{ + /* check abnormal parameter + * printf parameters + */ + DRV_WriteReg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 1), + APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, res0, smmu_en, res1)); +} + + +/* set vsid segment 0x08 -prefer bit fields as input parameters */ +void apummu_set_segment_offset2( + uint32_t vsid_idx, uint8_t seg_idx, uint8_t resv, uint8_t domain, uint8_t acp_en, + uint8_t aw_clr, uint8_t aw_invalid, uint8_t ar_exclu, uint8_t ar_sepcu, + uint8_t aw_cache_allocate, uint8_t aw_slc_en, uint8_t aw_slb_en, + uint8_t ar_cache_allocate, uint8_t ar_slc_en, uint8_t ar_slb_en, uint8_t ro, uint8_t ns) +{ + DRV_WriteReg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 2), + APUMMU_BUILD_SEGMENT_OFFSET2( + resv, domain, acp_en, aw_clr, aw_invalid, + ar_exclu, ar_sepcu, aw_cache_allocate, + aw_slc_en, aw_slb_en, ar_cache_allocate, + ar_slc_en, ar_slb_en, ro, ns)); +} + + +/* set vsid segment 0x0c */ +void apummu_set_segment_offset3(uint32_t vsid_idx, uint8_t seg_idx, uint8_t seg_valid, uint8_t rsv) +{ + DRV_WriteReg32(APUMMU_VSID_SEGMENT_EN_BASE(vsid_idx), + (DRV_Reg32(APUMMU_VSID_SEGMENT_EN_BASE(vsid_idx)) | (1 << seg_idx))); +} + + +/* + * apummu_enable_vsid() + + * VSID in CMU Configuration + + * 0x50 VSID_enable0_set 32 1 VSID enable0 set BX; SCU; + * RAND 31 0 the_VSID31_0_enable_set_register + + * 0x54 VSID_enable1_set 32 1 VSID enable1 set BX; SCU; + * RAND 31 0 the_VSID63_32_enable_set_register + + * *((UINT32P)(APU_RCX_AMU_CMU_TOP+(vsid/32)*0x4+0x50)) = 0x1 << (vsid%32); + * *((UINT32P)(APU_RCX_AMU_CMU_TOP+(vsid/32)*0x4+0xb0)) = 0x1 << (vsid%32); + +*/ +int apummu_enable_vsid(uint32_t vsid_idx) +{ + if (vsid_idx > (APUMMU_VSID_ACTIVE-1) && + vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV+1)) { + printf("invalid vsid index %d\n", vsid_idx); + return -1; + } + + /* this vsid is distributed */ + DRV_WriteReg32(APUMMU_VSID_ENABLE_BASE(vsid_idx), 0x1 << (vsid_idx & 0x1f)); + /* this vsid is ready for used */ + DRV_WriteReg32(APUMMU_VSID_VALID_BASE(vsid_idx), 0x1 << (vsid_idx & 0x1f)); + + return 0; +} + +/* + * apummu_enable() + * CMU init + * ((UINT32P)(0x19067000)) = 0x1; //bit0: apu_mmu_en + * 0x0 cmu_con 32 1 cmu control register + * 0 0 APU_MMU_enable + * 1 1 tcu_apb_dbg_en + * 2 2 tcu_secure_chk_en + * 3 3 DCM_en + * 4 4 sw_slp_prot_en_override + */ +void apummu_enable(void) +{ + uint32_t flag = 0; + + /* need to read first, only set bit 0 (keep the default value) */ + flag = DRV_Reg32(APUMMU_CMU_TOP_BASE); + flag |= 0x1; + DRV_WriteReg32(APUMMU_CMU_TOP_BASE, flag); +} + +int apummu_topology_init(void) +{ + /* Note: This is don't care since no invalidate is called */ + DRV_WriteReg32(APUMMU_CMU_TOP_TOPOLOGY, ((0xf << 7) | 0x03)); + + return 0; +} + +/* apummu_vsid_sram_config() @ drv_init */ +int apummu_vsid_sram_config(void) +{ + uint32_t idx; + + for (idx = 0; idx < APUMMU_VSID_RSV; idx++) { + DRV_WriteReg32(APUMMU_VSID(APUMMU_RSV_VSID_IDX_START+idx), + APUMMU_VSID_DESC(APUMMU_VSID_SRAM_TOTAL - APUMMU_VSID_RSV + idx)); + } + + +#ifdef SHOW_COMMENT + /* config active vsid's vsid desc 0-31 (ponsot) */ + for (idx = 0; idx < APUMMU_VSID_ACTIVE; idx++) + DRV_WriteReg32(APUMMU_VSID(idx), APUMMU_VSID_DESC(idx)); + + /* set valid bit = 0 of 10 segment to avoid abnormal operations */ + /* TBD */ +#endif + + return 0; +} + +/* apummu_uP_monitor */ +void apummu_rv_addr_monitor(uint32_t lower, uint32_t upper) +{ + printf("%s: lower=0x%x, upper=0x%x\n", __func__, + lower, upper); + + DRV_WriteReg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE60)), lower); + DRV_WriteReg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE64)), upper); + DRV_WriteReg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE68)), ((0<<2) | (0<<0))); + DRV_WriteReg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE6C)), ((0<<1))); + DRV_WriteReg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE40)), ((1<<3))); +} + +/* apummu_uP_monitor latch */ +uint32_t apummu_rv_monitor_latch(void) +{ + uint32_t status = 0; + + status = DRV_Reg32((APUMMU_RCX_UPRV_TCU_BASE + (0xEA0))); + printf("apummu_rv_monitor_latch_(ea0): status = 0x%x\n", status); + + return DRV_Reg32((APUMMU_RCX_UPRV_TCU_BASE + (0xE7C))); +} + +/* + * apummu_bind_vsid() + * //thread mapping to VSID table + * e.g + * //bit17 to bit11: COR_ID, bit10 to bit3: VSID, bit0: VSID valid, bit1: COR_ID valid + * *((UINT32P)(base + (thread*0x4))) = (cor_id << 11) + (vsid << 3) + 0x1 + 0x2; + * => VSDI valid:1 -> means the enigne bind this visd + * => VSID valid:0 -> interurpt will be triggered if transaction is sent + * 17 11 cor_id + * 10 3 vsid + * 2 2 vsid_prefetch_trigger + * 1 1 corid_vld + * 0 0 vsid_vld + */ +#ifdef linux_ep +void apummu_bind_vsid(void *tcu_base, uint32_t vsid_idx, uint8_t cor_id, uint8_t hw_thread, + uint8_t cor_valid, uint8_t vsid_valid) +#else +void apummu_bind_vsid(uint32_t tcu_base, uint32_t vsid_idx, uint8_t cor_id, uint8_t hw_thread, + uint8_t cor_valid, uint8_t vsid_valid) +#endif +{ +#ifdef linux_ep + printf("TCU BASE:0x%llx, vsid=%d, core_id=%d, thread=%d, cor_valid=%d, vsid_valid=%d\n", + (uint64_t)tcu_base, vsid_idx, cor_id, hw_thread, cor_valid, vsid_valid); +#else + printf("TCU BASE:0x%x, vsid=%d, core_id=%d, thread=%d, cor_valid=%d, vsid_valid=%d\n", + tcu_base, vsid_idx, cor_id, hw_thread, cor_valid, vsid_valid); +#endif + DRV_WriteReg32((tcu_base + hw_thread*0x4), (((cor_id & 0x7f) << 11) + | ((vsid_idx & 0xff) << 3) + | ((cor_valid & 0x1) << 1) | ((vsid_valid & 0x1) << 0))); +} + +int apummu_rv_bind_vsid(uint8_t hw_thread) +{ + //UINT32 thread = 2;//md32 user->thread0, logger -> thread2 ? + if (hw_thread > 7) { + printf("the hw thread id (%d) is not valid for rv/logger\n", hw_thread); + return -1; + } + + /* for rV */ + apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, 0, 0, 0, 1); + apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, 0, hw_thread, 0, 1); + + printf("Binding APUMMU_UPRV_RSV_VSID successfully (%d)\n", APUMMU_UPRV_RSV_VSID); + + return 0; +} + +int apummu_logger_bind_vsid(uint8_t hw_thread) +{ + + if (hw_thread > 7) { + printf("the hw thread id (%d) is not valid for rv/logger\n", hw_thread); + return -1; + } + /* for logger */ + apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_LOGGER_RSV_VSID, 0, hw_thread, 0, 1); + + printf("Binding APUMMU_LOGGER_RSV_VSID successfully (%d)\n", APUMMU_LOGGER_RSV_VSID); + + return 0; +} + +int apummu_apmcu_bind_vsid(uint8_t hw_thread) +{ + + if (hw_thread > 7) { + printf("the hw thread id (%d) is not valid for rv/logger\n", hw_thread); + return -1; + } + /* for APmcu */ + apummu_bind_vsid(APUMMU_RCX_EXTM_TCU_BASE, APUMMU_APMCU_RSV_VSID, 0, hw_thread, 0, 1); + + printf("Binding APUMMU_LOGGER_RSV_VSID successfully (%d)\n", APUMMU_APMCU_RSV_VSID); + + return 0; +} + + +/* + * apummu_add_map() + + * vsid_idx:0-255 + * seg_idx :0-9 + * input eva: 22bits + * output remap_adr: 22bits + + * Page length:This field indicate the segment size selection. There are several options + * page length=0-> size 128KB + * page length=1-> size 256KB + * page length=2-> size 512KB + * page length=3-> size 1MB + * page length=4-> size 128MB + * page length=5-> size 256MB + * page length=6-> size 512MB + * page length=7-> size 4GB + * when page sel=0, total remap size = input base+page length (page enable bit ?¡æ?) + * when page sel=3~7, total remap size=input base+page length*page enable + + * Segment layout for reserved VSID + * reserved VSID 254 for uP + * reserved VSID 253 for logger + * reserved VSID 252 for ARM + * reserved VSID 251 for GPU + * reserved VSID 250 for sAPU + * reserved VSID 249 for AoV (1-1 mapping, or disable APUMMMU) + + * Up + * seg_idx 0 - 1M + * seg_idx 1 - 512M + * seg_idx 2 - 4G + * e.g apummu_add_map(254, 0, 0, output_adr, 0, 3, 5, 0); + * apummu_add_map(254, 1, 0, output_adr, 0, 6, 5, 0); + * apummu_add_map(254, 2, 0, output_adr, 0, 7, 7, 1); + * Logger + * seg_idx 0 - 4G + + * xPU (CPU/GPU) + * seg_idx 0 - core dump address + */ +#ifndef linux_ep +apummu_vsid_t gApummu_vsid; +#endif +int apummu_add_map(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr, uint32_t output_adr, + uint8_t page_sel, uint8_t page_len, uint8_t domain, uint8_t ns) +{ +#ifdef SMMU_EN + uint8_t sid, smmu_en; +#endif + +#ifdef COMMENT_SHOW + if ((input_adr & 0x3fffff) != 0 || (output_adr & 0x3fffff) != 0) { // check 4k alignment + printf("input/output adr is not 4k alignment (%x / %x)\n", input_adr, output_adr); + return -1; //error code + } +#endif + /* if (vsid_idx > (APUMMU_VSID_ACTIVE-1) && \ + * vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV+1)) { //check vsid if valid + * printf("vsid_idx is not valid (0x%x:0x%x)\n", vsid_idx); + * return -2; + * } + */ + + if (seg_idx > 9) { /* check segment position if illegal */ + printf("seg_idx is not illegal (0x%x)\n", seg_idx); + return -3; + } + +#ifdef SMMU_EN +#ifdef FPGA + sid = 0; +#else + sid = 9; +#endif + smmu_en = 1; +#endif + + /* fill segment */ + apummu_set_segment_offset0(vsid_idx, seg_idx, input_adr, 0, page_sel, page_len); +#ifdef SMMU_EN + apummu_set_segment_offset1(vsid_idx, seg_idx, output_adr, sid, smmu_en, 0); +#else + apummu_set_segment_offset1(vsid_idx, seg_idx, output_adr, 0, 1, 0); +#endif + apummu_set_segment_offset2(vsid_idx, seg_idx, 0, domain, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ns); + apummu_set_segment_offset3(vsid_idx, seg_idx, 1, 0); + +#ifdef COMMENT_SHOW /* ndef linux_ep */ + /* fill page array if needs */ +#endif + + return 0; /* success or fail */ +} + +void apummu_dump_map(uint32_t vsid_idx, uint8_t seg_idx) +{ + uint32_t input_adr = 0, output_adr = 0; + uint8_t resv = 0, smmu_sid = 0, axmmusecsid = 0; + uint8_t page_sel = 0, page_len = 0; + uint8_t en = 0; + uint8_t domain = 0, acp_en = 0, aw_clr = 0; + uint8_t aw_invalid = 0, ar_exclu = 0; + uint8_t ar_sepcu = 0, aw_cache_alloc = 0; + uint8_t aw_slc_en = 0, aw_slb_en = 0; + uint8_t ar_cache_alloc = 0, ar_slc_en = 0; + uint8_t ar_slb_en = 0, ns = 0; + uint8_t seg_valid = 0; + + apummu_get_segment_offset0(vsid_idx, seg_idx, &input_adr, + &resv, &page_sel, &page_len); + apummu_get_segment_offset1(vsid_idx, seg_idx, &output_adr, + &smmu_sid, &en, &axmmusecsid); + apummu_get_segment_offset2(vsid_idx, seg_idx, &domain, &acp_en, + &aw_clr, &aw_invalid, &ar_exclu, + &ar_sepcu, &aw_cache_alloc, &aw_slc_en, + &aw_slb_en, &ar_cache_alloc, &ar_slc_en, + &ar_slb_en, &ns); + apummu_get_segment_offset3(vsid_idx, seg_idx, &seg_valid); + + printf("----vsid = 0x%x, seg_idx = 0x%x-----\n", vsid_idx, seg_idx); + + printf("input_adr = 0x%x, output_adr = 0x%x\n", input_adr, output_adr); + printf("smmu_sid = 0x%x, ssid_en = 0x%x, axmmusecsid = 0x%x\n", + smmu_sid, en, axmmusecsid); + printf("resv = 0x%x, page_sel = 0x%x, page_len = 0x%x\n", + resv, page_sel, page_len); + + printf("domain = 0x%x, ns= 0x%x\n", domain, ns); + printf("acp_en = 0x%x, aw_clr = 0x%x, aw_invalid = 0x%x\n", + acp_en, aw_clr, aw_invalid); + printf("ar_exclu = 0x%x, ar_sepcu = 0x%x, aw_cache_alloc = 0x%x\n", + ar_exclu, ar_sepcu, aw_cache_alloc); + printf("aw_slc_en = 0x%x, aw_slb_en = 0x%x\n", aw_slc_en, aw_slb_en); + printf("ar_cache_alloc = 0x%x, ar_slc_en = 0x%x, ar_slb_en = 0x%x\n", + ar_cache_alloc, ar_slc_en, ar_slb_en); + + printf("---------seg_valid = 0x%x---------\n", seg_valid); + +} + +int apummu_boot_init(void) +{ + +#ifdef linux_ep + /* apummu ioremap */ + apummu_ioremap(); +#endif + /* vsid sram descript init */ + apummu_vsid_sram_config(); + +#ifdef COMMENT_SHOW /* ndef linux_ep */ + /* topology init */ + apummu_topology_init(); +#endif + +#ifdef SMMU_EN + /* Set SID (8), SSID(0) */ + DRV_WriteReg32(ammu_vcore_config_base, ((0x8 << 4) | (0x0 << 0))); +#endif + /* enable apummu h/w */ + apummu_enable(); + + + return 0; +} + + +/* + * virtual engine thread generator + */ + +void virtual_engine_thread(void) +{ + uint32_t thread_map; + uint32_t data; + +/* + * init TEE dns 0 maps thread 1 + * (dns consists of 5 bits xxxy -> xxxx is domain, y is ns) + */ +#ifdef linux_ep + thread_map = APUMMU_THD_ID_APMCU_NORMAL; //0 + data = (thread_map << 3); +#else + thread_map = APUMMU_THD_ID_TEE; //1 + data = thread_map; +#endif + + DRV_WriteReg32((APUMMU_RCX_EXTM_TCU_BASE + APUMMU_INT_D2T_TBL0_OFS), + data); +} + +/* + * for apmcu map + */ +int apummu_add_apmcu_map(uint32_t seg_input0, uint32_t seg_output0, enum eAPUMMUPAGESIZE page_size) +{ + int ret = 0; + uint8_t domain = 7, ns = 1; + + DRV_WriteReg32(APUMMU_VSID_SEGMENT_EN_BASE(APUMMU_APMCU_RSV_DESC_IDX), 0); + + /* must be in order */ + ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, 0, seg_input0, seg_output0, + 0, page_size, domain, ns); /* page length=3 -> size 1MB */ + if (ret) + return ret; + + /* enable vsid */ + ret = apummu_enable_vsid(APUMMU_APMCU_RSV_VSID); + + return 0; +} + + +/* + * for logger map + */ +int apummu_add_logger_map(uint32_t seg_input0, uint32_t seg_output0, enum eAPUMMUPAGESIZE page_size) +{ + int ret = 0; + uint8_t domain = 7, ns = 1; + + // DRV_WriteReg32(APUMMU_VSID_SEGMENT_EN_BASE(APUMMU_LOGGER_RSV_DESC_IDX), 0); + + /* must be in order */ + ret = apummu_add_map(APUMMU_LOGGER_RSV_DESC_IDX, 0, seg_input0, seg_output0, + 0, page_size, domain, ns); /* page length=3 -> size 1MB */ + if (ret) + return ret; + + /* enable vsid */ + ret = apummu_enable_vsid(APUMMU_LOGGER_RSV_VSID); + + return ret; +} + +/* + * for rv boot map + */ +int apummu_add_rv_boot_map(uint32_t seg_output0, int32_t seg_output1, int32_t seg_output2) +{ + int ret = 0; + uint8_t domain = 7, ns = 1; + + DRV_WriteReg32(APUMMU_VSID_SEGMENT_EN_BASE(APUMMU_RSV_VSID_DESC_IDX_END), 0); + + /* must be in order */ + /* eAPUMMU_PAGE_LEN_1MB, = 3 */ + ret = apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 0, 0, seg_output0, + 0, eAPUMMU_PAGE_LEN_1MB, domain, ns); + /* eAPUMMU_PAGE_LEN_512MB, 6 */ + ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 1, 0, seg_output1, + 0, eAPUMMU_PAGE_LEN_512MB, domain, ns); + /* eAPUMMU_PAGE_LEN_4GB, 7 */ + ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 2, 0, seg_output2, + 0, eAPUMMU_PAGE_LEN_4GB, domain, ns); + + /* enable vsid */ + ret |= apummu_enable_vsid(APUMMU_UPRV_RSV_VSID); + + return ret; +} + +/* Example func. Before RCX power on */ +int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread, + uint32_t logger_seg_output, enum eAPUMMUPAGESIZE logger_page_size, + uint32_t XPU_seg_output, enum eAPUMMUPAGESIZE XPU_page_size) +{ + int ret = 0; + + /* apummu init @ beginning - call this once only */ + apummu_boot_init(); + printf("<%s> output addr, uP_seg = 0x%8x logger_seg = 0x%8x XPU_seg = 0x%8x\n", + __func__, uP_seg_output, logger_seg_output, XPU_seg_output); + printf("<%s> uP_hw_thread = %u, (logger, XPU) page size = (%u, %u)\n", + __func__, uP_hw_thread, logger_page_size, XPU_page_size); + + /* 1. add rv map - MUST be in-order for rv booting */ + ret = apummu_add_rv_boot_map(uP_seg_output, 0, 0); + if (ret) { + printf("apummu_add_rv_boot_map fail\n"); + return ret; + } + + /* bind rv vsid */ + /* thread: 0:normal, 1:secure, 2:logger?; MP flow should be 1 */ + ret = apummu_rv_bind_vsid(uP_hw_thread); + if (ret) { + printf("apummu_rv_bind_vsid fail(%u)\n", uP_hw_thread); + return ret; + } + + ret = apummu_rv_bind_vsid(uP_hw_thread + 1); + if (ret) { + printf("apummu_rv_bind_vsid fail(%u)\n", (uP_hw_thread + 1)); + return ret; + } + + /* 2. add h/w logger map */ + ret = apummu_add_logger_map(logger_seg_output/*input*/, logger_seg_output/*output*/, + logger_page_size); + if (ret) { + printf("apummu add map for logger fail\n"); + return ret; + } + + /* bind logger vsid */ + ret = apummu_logger_bind_vsid(uP_hw_thread+2); //thread: 0:normal, 1:secure, 2:logger + if (ret) { + printf("apummu_logger_bind_vsid fail(%u)\n", (uP_hw_thread + 2)); + return ret; + } + + /* 3. add apmcu map */ + virtual_engine_thread(); + ret = apummu_add_apmcu_map(XPU_seg_output/*input*/, XPU_seg_output/*output*/, + XPU_page_size); + if (ret) { + printf("apummu add map for apmcu fail\n"); + return ret; + } + + /* bind apmmu vsid */ + ret = apummu_apmcu_bind_vsid(APUMMU_THD_ID_APMCU_NORMAL); + if (ret) { + printf("apummu_apmcu_bind_vsid fail\n"); + return ret; + } + + return ret; +} +/* Example func. */ diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_cmn.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_cmn.h new file mode 100644 index 0000000000000..580f236f2ce98 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_cmn.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_COMMON_H__ +#define __APUSYS_APUMMU_COMMON_H__ + +#include +#include + +extern u32 g_ammu_klog; + +enum { + AMMU_ERR = 0x1, + AMMU_WRN = 0x2, + AMMU_INFO = 0x4, + AMMU_DBG = 0x8, + AMMU_VERBO = 0x10, +}; + +#define APUMMU_PREFIX "[apummu]" + +static inline int ammu_log_level_check(int log_level) +{ + return g_ammu_klog & log_level; +} + +#define AMMU_LOG_ERR(x, args...) \ + do { \ + if (ammu_log_level_check(AMMU_ERR)) \ + pr_info(APUMMU_PREFIX "[error] %s " x, __func__, ##args); \ + } while (0) + +#define AMMU_LOG_WRN(x, args...) \ + do { \ + if (ammu_log_level_check(AMMU_WRN)) \ + pr_info(APUMMU_PREFIX "[warn] %s " x, __func__, ##args); \ + } while (0) + +#define AMMU_LOG_INFO(x, args...) \ + do { \ + if (ammu_log_level_check(AMMU_INFO)) \ + pr_info(APUMMU_PREFIX "[info] %s " x, __func__, ##args); \ + } while (0) + +#define AMMU_LOG_DBG(x, args...) \ + do { \ + if (ammu_log_level_check(AMMU_DBG)) \ + pr_info(APUMMU_PREFIX "[dbg] %s " x, __func__, ##args); \ + } while (0) + +#define AMMU_LOG_VERBO(x, args...) \ + do { \ + if (ammu_log_level_check(AMMU_VERBO)) \ + pr_info(APUMMU_PREFIX "[verbo] %s " x, __func__, ##args); \ + } while (0) + +/* For tracking sequence */ +#define AMMU_FOOT_PRINT(x, args...) \ + pr_info(APUMMU_PREFIX "[FootPrint] %s " x, __func__, ##args) + +#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE) +#include +#define _ammu_exception(key, reason) \ + do { \ + char info[150];\ + if (snprintf(info, 150, "apummu:" reason) > 0) { \ + aee_kernel_exception(info, \ + "\nCRDISPATCH_KEY:%s\n", key); \ + } else { \ + AMMU_LOG_ERR("apu_ammu: %s snprintf fail(%d)\n", __func__, __LINE__); \ + } \ + } while (0) + +#define apusys_ammu_exception(reason) _ammu_exception("APUSYS_APUMMU", reason) +#define apusys_hse_exception(reason) _ammu_exception("APUSYS_HSE", reason) +#define apusys_cbfc_exception(reason) _ammu_exception("APUSYS_CBFC", reason) + +#else +#define apusys_ammu_exception(reason) +#define apusys_hse_exception(reason) +#define apusys_cbfc_exception(reason) +#endif /* end of IS_ENABLED(CONFIG_MTK_AEE_FEATURE) */ + + +#endif /* end of __APUSYS_APUMMU_COMMON_H__ */ diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.c new file mode 100644 index 0000000000000..0beae8bcbd365 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apummu_cmn.h" +#include "apummu_drv.h" +#include "apummu_dbg.h" +#include "apummu_remote.h" +#include "apummu_remote_cmd.h" +#include "linux/soc/mediatek/apummu_export.h" // for verify API to MDW + +#include "apummu_mgt.h" +#include "apummu_mem.h" + +/* All level default on */ +uint32_t g_ammu_klog = 0xF; /* apummu kernel log level */ +u8 apummu_apusys_trace; + +#define APUMMU_DBG_DIR "apummu" + +#define PARSER_DBG (0) /* Enable op parse dump */ +#define KERNEL_DBG (1) /* Enable kernel debug node */ + +/* debug root node */ +static struct dentry *apummu_dbg_root; + +/* remote debug node */ +static struct dentry *apummu_dbg_remote_op; + +#if KERNEL_DBG +static struct dentry *apummu_dbg_kernel; +#endif + +/* parse input and send IPI */ +static ssize_t apummu_dbg_write_op(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ +#define MAX_ARG (7) + struct apummu_dev_info *adv = file->private_data; + char *tmp, *token, *cursor; + uint32_t argv[MAX_ARG]; + int ret, i; + + tmp = kzalloc(count + 1, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = copy_from_user(tmp, user_buf, count); + if (ret) { + ret = -EINVAL; + goto out; + } + + tmp[count] = '\0'; + cursor = tmp; + + /* parse arguments */ + for (i = 0; i < MAX_ARG && (token = strsep(&cursor, " ")); i++) { + ret = kstrtouint(token, 16, &argv[i]); + if (ret) { + AMMU_LOG_ERR("fail to parse argv[%d]\n", i); + goto out; + } + } + +#if PARSER_DBG + for (i = 0; i < MAX_ARG; i++) + AMMU_LOG_INFO("args[%d][%d]\n", i, argv[i]); +#endif + + ret = apummu_remote_set_op(adv, argv, MAX_ARG); + if (ret) { + AMMU_LOG_ERR("set OP fail %d\n", ret); + goto out; + } + ret = count; +out: + kfree(tmp); + return ret; + +} +static const struct file_operations apummu_dbg_fops_remoteop = { + .open = simple_open, + .write = apummu_dbg_write_op, + .llseek = default_llseek, +}; + +#if KERNEL_DBG + +enum apummu_UT_OP { + AMMU_ADD_STABLE, + AMMU_FREE_STABLE, + AMMU_DSETROY_ALL_STABLE, + AMMU_GET_STABLE_AND_DUMP, + AMMU_ALLOC_AND_MAP, + AMMU_UNMAP_AND_FREE, + AMMU_IMPORT, + AMMU_UNIMPORT, + AMMU_GET_STABLE_AND_SEND2RV, +}; + +/* dump interest kernel info */ +static ssize_t apummu_dbg_kernel_read(struct file *filp, char *buffer, + size_t length, loff_t *offset) +{ + int ret = 0; + + dump_session_table_set(); + + return ret; +} + +static ssize_t apummu_dbg_write_kernel(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ +#define MAX_ARG_kernel (4) + struct apummu_dev_info *adv = file->private_data; + char *tmp, *token, *cursor; + uint32_t argv[MAX_ARG_kernel]; + int ret, i; + uint32_t mode, type, device_va, sid, size = 0; + uint64_t session, addr = 0, eva = 0; + void *tbl_kva = NULL; + struct apummu_session_tbl *g_ammu_session_table_ptr_DBG = NULL; + struct apummu_mem ammu_mem; + dma_addr_t iova; + + memset(&ammu_mem, 0, sizeof(struct apummu_mem)); + + tmp = kzalloc(count + 1, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = copy_from_user(tmp, user_buf, count); + if (ret) { + ret = -EINVAL; + goto out; + } + + tmp[count] = '\0'; + cursor = tmp; + + /* parse arguments */ + for (i = 0; i < MAX_ARG_kernel && (token = strsep(&cursor, " ")); i++) { + ret = kstrtouint(token, 16, &argv[i]); + if (ret) { + AMMU_LOG_ERR("fail to parse argv[%d]\n", i); + goto out; + } + } + +#if PARSER_DBG + for (i = 0; i < MAX_ARG_kernel; i++) + AMMU_LOG_INFO("args[%x][%x]\n", i, argv[i]); +#endif + + mode = argv[0]; + type = argv[1]; + session = argv[2]; + device_va = argv[3]; + + switch (mode) { + case AMMU_ADD_STABLE: // 0 + ret = apummu_iova2eva(type, session, device_va, 0, &eva); + if (ret) + AMMU_LOG_ERR("apummu_iova2eva fail\n"); + else + AMMU_LOG_DBG("apummu_iova2eva ret IOVA = 0x%llx\n", eva); + + break; + case AMMU_FREE_STABLE: // 1 + AMMU_LOG_DBG("Free stable, session = 0x%llx\n", session); + apummu_table_free(session); + break; + case AMMU_DSETROY_ALL_STABLE: // 2 + AMMU_LOG_DBG("Destroy apummu stable\n"); + apummu_mgt_destroy(); + break; + case AMMU_GET_STABLE_AND_DUMP: // 3 + AMMU_LOG_DBG("apummu get stable, session = 0x%llx\n", session); + ret = apummu_table_get(session, &tbl_kva, &size); + if (ret) { + AMMU_LOG_ERR("apummu get_session_table fail\n"); + break; + } + + if (!tbl_kva) { + AMMU_LOG_ERR("tbl_kva NULL\n"); + break; + } + + g_ammu_session_table_ptr_DBG = (struct apummu_session_tbl *) tbl_kva; + + AMMU_LOG_DBG("== APUMMU dump session table in DBG Start ==\n"); + AMMU_LOG_DBG("== size = 0x%x\n", size); + AMMU_LOG_DBG("session = 0x%llx\n", + g_ammu_session_table_ptr_DBG->session); + AMMU_LOG_DBG("mem_mask = 0x%x\n", + g_ammu_session_table_ptr_DBG->stable_info.mem_mask); + AMMU_LOG_DBG("DRAM_page_array_mask = 0x%x 0x%x\n", + g_ammu_session_table_ptr_DBG->stable_info.DRAM_page_array_mask[0], + g_ammu_session_table_ptr_DBG->stable_info.DRAM_page_array_mask[1]); + AMMU_LOG_DBG("DRAM_page_array_en_num = %u, %u\n", + g_ammu_session_table_ptr_DBG->stable_info.DRAM_page_array_en_num[0], + g_ammu_session_table_ptr_DBG->stable_info.DRAM_page_array_en_num[1]); + AMMU_LOG_DBG("EXT_SLB_addr = 0x%x, RSV_S_SLB PA start = %u, page = %u\n", + g_ammu_session_table_ptr_DBG->stable_info.EXT_SLB_addr, + g_ammu_session_table_ptr_DBG->stable_info.RSV_S_SLB_page_array_start, + g_ammu_session_table_ptr_DBG->stable_info.RSV_S_SLB_page); + break; + case AMMU_ALLOC_AND_MAP: // 4 + ret = apummu_alloc_mem(type, size, &addr, &sid); + if (ret) + break; + + // ret = apummu_map_mem(session, type, &addr); + ret = addr_encode_and_write_stable(0, session, addr, size, &eva); + if (ret) + break; + + AMMU_LOG_INFO("Input addr = 0x%llx, EVA = 0x%llx\n", + addr, eva); + break; + case AMMU_UNMAP_AND_FREE: // 5 + ret = apummu_unmap_mem(session, type); + if (ret) + break; + + ret = apummu_free_mem(type); + if (ret) + break; + break; + case AMMU_IMPORT: // 6 + ret = apummu_import_mem(session, type); + break; + case AMMU_UNIMPORT: // 7 + ret = apummu_unimport_mem(session, type); + break; + case AMMU_GET_STABLE_AND_SEND2RV: // 8 + ret = apummu_table_get(session, &tbl_kva, &size); + if (ret) { + AMMU_LOG_ERR("apummu get_session_table fail\n"); + break; + } + + ammu_mem.size = size; + ammu_mem.kva = (uint64_t)dma_alloc_coherent(adv->dev, ammu_mem.size, &iova, GFP_KERNEL); + ammu_mem.iova = (uint64_t)iova; + memcpy((void *) (ammu_mem.kva), tbl_kva, size); + + apummu_remote_send_stable(adv, session, (uint32_t) ammu_mem.iova, + (device_va), size); + dma_free_coherent(adv->dev, ammu_mem.size, (void *)ammu_mem.kva, ammu_mem.iova); + break; + } + + ret = count; +out: + kfree(tmp); + return ret; +} + +static const struct file_operations apummu_dbg_fops_kernel = { + .open = simple_open, + .read = apummu_dbg_kernel_read, + .write = apummu_dbg_write_kernel, + .llseek = default_llseek, +}; +#endif + +void apummu_dbg_init(struct apummu_dev_info *adv, struct dentry *apu_dbg_root) +{ + g_ammu_klog = 0xF; /* log all on, plz refer to apummu_cmn.h*/ + apummu_apusys_trace = 0; + + /* create apummu FS root node */ + apummu_dbg_root = debugfs_create_dir(APUMMU_DBG_DIR, apu_dbg_root); + if (IS_ERR_OR_NULL(apummu_dbg_root)) { + AMMU_LOG_WRN("failed to create debug dir.\n"); + goto fail; + } + + /* create log level */ + debugfs_create_u32("klog", 0644, + apummu_dbg_root, &g_ammu_klog); + + /* Enable sys trace */ + debugfs_create_u8("trace_en", 0644, + apummu_dbg_root, &apummu_apusys_trace); + + /* create remote op node */ + apummu_dbg_remote_op = debugfs_create_file("op", 0644, + apummu_dbg_root, adv, + &apummu_dbg_fops_remoteop); + if (IS_ERR_OR_NULL(apummu_dbg_remote_op)) { + AMMU_LOG_WRN("failed to create debug node(op).\n"); + goto fail; + } + +#if KERNEL_DBG + /* create kernel debug(dump) node */ + apummu_dbg_kernel = debugfs_create_file("kernel", 0644, + apummu_dbg_root, adv, + &apummu_dbg_fops_kernel); + if (IS_ERR_OR_NULL(apummu_dbg_kernel)) { + AMMU_LOG_WRN("failed to create debug node(kernel).\n"); + goto fail; + } +#endif + + return; +fail: + apummu_dbg_destroy(adv); +} + +void apummu_dbg_destroy(struct apummu_dev_info *adv) +{ + debugfs_remove_recursive(apummu_dbg_root); +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.h new file mode 100644 index 0000000000000..fdf8021cb606f --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_dbg.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_DEBUG_H__ +#define __APUSYS_APUMMU_DEBUG_H__ + +#include + +void apummu_dbg_init(struct apummu_dev_info *rdv, struct dentry *apu_dbg_root); +void apummu_dbg_destroy(struct apummu_dev_info *rdv); + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.c new file mode 100644 index 0000000000000..a63cfbeefb26a --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.c @@ -0,0 +1,641 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include /* Needed by all modules */ +#include /* Needed for KERN_ALERT */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../platform/apummu_plat.h" +#include "../platform/apummu_device.h" + +#if IS_ENABLED(CONFIG_OF) +#include +#include +#endif +#include "linux/remoteproc/mtk_apu.h" +#include "linux/remoteproc/mtk_apu_config.h" + +#include "slbc_ops.h" + +/* import apummu header */ +#include "apummu_drv.h" +#include "apummu_cmn.h" +#include "apummu_dbg.h" +#include "apummu_mem.h" +#include "apummu_remote.h" +#include "apummu_remote_cmd.h" +#include "apummu_mgt.h" +#include "linux/soc/mediatek/apummu_export.h" + +/* define */ +#define APUSYS_DRV_NAME "apusys_drv_apummu" +#define APUSYS_DEV_NAME "apusys_apummu" + +#define SLB_NODE (0) + +MODULE_IMPORT_NS(DMA_BUF); + +/* global variable */ +static struct class *apummu_class; +struct apummu_dev_info *g_adv; +static struct task_struct *mem_task; +static struct dentry *apummu_dbg_root; +static int apummu_suspend_release_flag; + +/* function declaration */ +static int apummu_open(struct inode *, struct file *); +static int apummu_release(struct inode *, struct file *); +#if !(DRAM_FALL_BACK_IN_RUNTIME) +static int apummu_memory_func(void *arg); +#endif +static int apummu_map_dts(struct platform_device *pdev); +static int apummu_create_node(struct platform_device *pdev); +static int apummu_delete_node(void *drvinfo); + +struct apu_ipi_apummu_rx_rpmsg_device { + struct rpmsg_endpoint *ept; + struct rpmsg_device *rpdev; +}; +static struct apu_ipi_apummu_rx_rpmsg_device apu_ipi_apummmu_rx_rpm_dev; +static const struct of_device_id apu_apummu_rx_rpmsg_of_match[] = { + { .compatible = "mediatek,apu-apummu-rx", }, + { }, +}; +static int apu_ipi_apummu_rx_rpmsg_probe(struct rpmsg_device *rpdev) +{ + AMMU_LOG_INFO("%s: name=%s, src=%d\n", + __func__, rpdev->id.name, rpdev->src); + + apu_ipi_apummmu_rx_rpm_dev.ept = rpdev->ept; + apu_ipi_apummmu_rx_rpm_dev.rpdev = rpdev; + + AMMU_LOG_INFO("%s: rpdev->ept = %p\n", __func__, rpdev->ept); + + return 0; +} +static int apu_ipi_apummu_rx_rpmsg_cb(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct apummu_rx_data *d = (struct apummu_rx_data *)data; + + switch (d->module_id) { + case APUMMU_RX_TEST: + pr_info("%s: received APUMMU_RX_TEST from uP\n", __func__); + break; + case APUMMU_RX_APUMMU_AEE: + AMMU_LOG_ERR("APUMMU error in uP, error_code = %d\n", d->error_code); + apusys_ammu_exception("APUMMU error in uP"); + break; + case APUMMU_RX_HSE_AEE: + pr_info("HSE error in uP, error_code = %d\n", d->error_code); + apusys_hse_exception("HSE error in uP"); + break; + case APUMMU_RX_CBFC_AEE: + pr_info("CBFC error in uP, error_code = %d\n", d->error_code); + apusys_cbfc_exception("CBFC error in uP"); + break; + default: + pr_info("%s: unknown cmd %d\n", __func__, d->module_id); + break; + } + + rpmsg_send(apu_ipi_apummmu_rx_rpm_dev.ept, data, sizeof(struct apummu_rx_data)); + + return 0; +} + +static void apummu_ipi_apummu_rx_rpmsg_remove(struct rpmsg_device *rpdev) +{ + AMMU_LOG_INFO("apummu_ipi_apummu_rx remove Done\n"); +} +static struct rpmsg_driver apu_ipi_apummu_rx_rpmsg_driver = { + .drv = { + .name = "apu-apummu-rx", + .owner = THIS_MODULE, + .of_match_table = apu_apummu_rx_rpmsg_of_match, + }, + .probe = apu_ipi_apummu_rx_rpmsg_probe, + .remove = apummu_ipi_apummu_rx_rpmsg_remove, + .callback = apu_ipi_apummu_rx_rpmsg_cb, +}; + +#if !(DRAM_FALL_BACK_IN_RUNTIME) +/* alloc DRAM for fallback */ +static int apummu_memory_func(void *arg) +{ + int ret = 0; + struct apummu_dev_info *adv; + + adv = (struct apummu_dev_info *) arg; + + ret = apummu_dram_remap_alloc(adv); + if (ret) { + AMMU_LOG_ERR("Could not set memory for apummu\n"); + ret = -ENOMEM; + goto out; + } + AMMU_LOG_INFO("apummu memory init\n"); + +out: + return ret; +} +#endif + +/* RV HS and set RV DRAM fallback */ +static int apummu_rprmsg_memory_func(void *arg) +{ + struct apummu_dev_info *adv; + int ret = 0; +#if !(DRAM_FALL_BACK_IN_RUNTIME) + uint32_t i; +#endif + + adv = (struct apummu_dev_info *) arg; + + ret = apummu_remote_handshake(adv, NULL); + if (ret) { + AMMU_LOG_ERR("Remote Handshake fail %d\n", ret); + goto out; + } + +#if !(DRAM_FALL_BACK_IN_RUNTIME) + ret = apummu_memory_func(arg); + if (ret) { + AMMU_LOG_ERR("apummu memory fail\n"); + goto out; + } + + for (i = 0; i < adv->remote.dram_max; i++) { + ret = apummu_remote_set_hw_default_iova(adv, i, adv->remote.dram[i]); + if (ret) { + AMMU_LOG_ERR("apummu_remote_set_hw_default_iova fail %d\n", ret); + goto out; + } + } +#endif + + AMMU_LOG_INFO("apummu rprmsg remote init done\n"); + +out: + return ret; +} + + +int apummu_set_init_info(struct mtk_apu *apu) +{ + struct apummu_dev_info *adv; + struct mtk_apummu_init_info *rv_info; + // int i = 0; + + adv = g_adv; + + if (!adv) { + AMMU_LOG_ERR("No apummu_dev_info!\n"); + return -EINVAL; + } + + rv_info = (struct mtk_apummu_init_info *) + get_mtk_apu_config_user_ptr(apu->conf_buf, eREVISER_INIT_INFO); + + memset((void *)rv_info, 0, sizeof(struct mtk_apummu_init_info)); + + /* NOTE: since alloc in runtime, this info may not be right */ + rv_info->boundary = adv->plat.boundary; + // for (i = 0; i < adv->remote.dram_max; i++) + // rv_info->dram[i] = adv->remote.dram[i]; + + AMMU_LOG_INFO("apummu info init\n"); + + return 0; +} +EXPORT_SYMBOL(apummu_set_init_info); + +static const struct file_operations apummu_fops = { + .open = apummu_open, + .release = apummu_release, +}; + + +static int apummu_open(struct inode *inode, struct file *filp) +{ + struct apummu_dev_info *adv; + + adv = container_of(inode->i_cdev, + struct apummu_dev_info, apummu_cdev); + + filp->private_data = adv; + AMMU_LOG_INFO("adv %p\n", adv); + AMMU_LOG_INFO("filp->private_data %p\n", filp->private_data); + return 0; +} + +static int apummu_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int apummu_map_dts(struct platform_device *pdev) +{ + int ret = 0; + struct apummu_dev_info *adv = platform_get_drvdata(pdev); + +#if SLB_NODE + uint32_t slb_size = 0; + struct device_node *slb_node; +#endif + + if (!adv) { + AMMU_LOG_ERR("No apummu_dev_info!\n"); + ret = -EINVAL; + goto out; + } + + /* boundary can also take from HS */ + adv->plat.boundary = 0; + +#if SLB_NODE + slb_node = of_find_compatible_node( + NULL, NULL, "mediatek,mtk-slbc"); + if (slb_node) { + of_property_read_u32(slb_node, "apu", &slb_size); + adv->rsc.pool[APUMMU_POOL_SLBS].size = slb_size; + AMMU_LOG_INFO("APU-slb size: 0x%x\n", adv->rsc.pool[APUMMU_POOL_SLBS].size); + } +#endif + +out: + return ret; +} + +static int apummu_create_node(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct apummu_dev_info *adv = platform_get_drvdata(pdev); + + if (!adv) { + AMMU_LOG_ERR("No apummu_dev_info!\n"); + return -EINVAL; + } + + /* get major */ + ret = alloc_chrdev_region(&adv->apummu_devt, + 0, 1, APUSYS_DRV_NAME); + if (ret < 0) { + AMMU_LOG_ERR("alloc_chrdev_region failed, %d\n", ret); + goto out; + } + + /* Attach file operation. */ + cdev_init(&adv->apummu_cdev, &apummu_fops); + adv->apummu_cdev.owner = THIS_MODULE; + + /* Add to system */ + ret = cdev_add(&adv->apummu_cdev, + adv->apummu_devt, 1); + if (ret < 0) { + AMMU_LOG_ERR("Attach file operation failed, %d\n", ret); + goto free_chrdev_region; + } + + /* Create class register */ + apummu_class = class_create(APUSYS_DRV_NAME); + if (IS_ERR(apummu_class)) { + ret = PTR_ERR(apummu_class); + AMMU_LOG_ERR("Unable to create class, err = %d\n", ret); + goto free_cdev_add; + } + + dev = device_create(apummu_class, NULL, adv->apummu_devt, + NULL, APUSYS_DEV_NAME); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + AMMU_LOG_ERR("Failed to create device: /dev/%s, err = %d", + APUSYS_DEV_NAME, ret); + goto free_class; + } + + return 0; + +free_class: + /* Release class */ + class_destroy(apummu_class); +free_cdev_add: + /* Release char driver */ + cdev_del(&adv->apummu_cdev); + +free_chrdev_region: + unregister_chrdev_region(adv->apummu_devt, 1); +out: + return ret; +} + +static int apummu_delete_node(void *drvinfo) +{ + int ret = 0; + struct apummu_dev_info *adv = NULL; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + adv = (struct apummu_dev_info *)drvinfo; + + device_destroy(apummu_class, adv->apummu_devt); + class_destroy(apummu_class); + cdev_del(&adv->apummu_cdev); + unregister_chrdev_region(adv->apummu_devt, 1); + + return ret; +} + +static int apummu_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct apummu_dev_info *adv; + + g_adv = NULL; + mem_task = NULL; + + adv = devm_kzalloc(dev, sizeof(*adv), GFP_KERNEL); + if (!adv) { + ret = -ENOMEM; + goto out; + } + + adv->dev = &pdev->dev; + + platform_set_drvdata(pdev, adv); + dev_set_drvdata(dev, adv); + + // add for VLM DRAM 4-16G + ret = dma_set_mask_and_coherent(adv->dev, DMA_BIT_MASK(34)); + if (ret) { + AMMU_LOG_ERR("dma_set_mask_and_coherent fail\n"); + goto out; + } + + adv->init_done = false; + + if (apummu_plat_init(pdev)) { + dev_info(dev, "platform init failed\n"); + ret = -ENODEV; + goto out; + } + + if (apummu_create_node(pdev)) { + AMMU_LOG_ERR("apummu_create_node fail\n"); + ret = -ENODEV; + goto out; + } + + if (apummu_map_dts(pdev)) { + AMMU_LOG_ERR("apummu_map_dts fail\n"); + ret = -ENODEV; + goto free_node; + } + + apummu_dbg_init(adv, apummu_dbg_root); + + apummu_mgt_init(); + apummu_mem_init(); + if (apummu_export_API_init()) { + AMMU_LOG_ERR("export API init fail\n"); + ret = -EINVAL; + goto free_node; + } + g_adv = adv; + + adv->init_done = true; + AMMU_LOG_INFO("apummu probe done\n"); + +out: + return ret; +free_node: + apummu_delete_node(adv); + return ret; +} + +static int apummu_remove(struct platform_device *pdev) +{ + struct apummu_dev_info *adv = platform_get_drvdata(pdev); + + apummu_dbg_destroy(adv); + apummu_mgt_destroy(); + if (mem_task) { + #if !(DRAM_FALL_BACK_IN_RUNTIME) + apummu_dram_remap_free(adv); + #endif + mem_task = NULL; + } + apummu_delete_node(adv); + + g_adv = NULL; + + AMMU_LOG_INFO("remove done\n"); + return 0; +} + +static int apusys_apummu_resume(struct device *dev) +{ + int ret = 0; + // SLB data init + struct slbc_data slb_data = { + .uid = UID_APU, + .type = TP_BUFFER, + }; + + mutex_lock(&g_ammu_table_set.table_lock); + if (g_adv->plat.is_general_SLB_support) + if (!g_ammu_table_set.is_SLB_alloc + && apummu_suspend_release_flag) { + ret = slbc_request(&slb_data); + if (ret) { + AMMU_LOG_ERR("general SLB alloc fail in resume...\n"); + apusys_ammu_exception("Alloc SLB fail in resume\n"); + goto out; + } + + g_ammu_table_set.is_SLB_alloc = true; + apummu_suspend_release_flag = false; + } + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + return ret; +} + +static int apusys_apummu_suspend(struct device *dev) +{ + int ret = 0; + // SLB data init + struct slbc_data slb_data = { + .uid = UID_APU, + .type = TP_BUFFER, + }; + + mutex_lock(&g_ammu_table_set.table_lock); + if (g_adv->plat.is_general_SLB_support) + if (g_ammu_table_set.is_SLB_alloc) { + ret = slbc_release(&slb_data); + if (ret) { + AMMU_LOG_ERR("general SLB free fail in suspend...\n"); + apusys_ammu_exception("Free SLB fail in suspend\n"); + goto out; + } + + apummu_suspend_release_flag = true; + g_ammu_table_set.is_SLB_alloc = false; + } + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + return ret; +} + +static const struct dev_pm_ops apusys_apummu_pm_cb = { + .resume = apusys_apummu_resume, + .suspend = apusys_apummu_suspend, +}; + +static struct platform_driver apummu_driver = { + .probe = apummu_probe, + .remove = apummu_remove, + .driver = { + .name = APUSYS_DRV_NAME, + .owner = THIS_MODULE, + .pm = &apusys_apummu_pm_cb, + }, +}; + +static int apummu_rpmsg_cb(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + int ret = 0; + void *drvinfo; + + if (!rpdev) { + AMMU_LOG_ERR("No apummu rpmsg device\n"); + return -1; + } + + drvinfo = dev_get_drvdata(&rpdev->dev); + if (!drvinfo) { + AMMU_LOG_ERR("No apummu dev info\n"); + return -1; + } + + ret = apummu_remote_rx_cb(drvinfo, data, len); + + return ret; +} + +static int apummu_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct apummu_dev_info *adv; + int ret = 0; + + AMMU_LOG_INFO("name=%s, src=%d\n", rpdev->id.name, rpdev->src); + + if (!g_adv) { + AMMU_LOG_ERR("No apummu Driver Init\n"); + return -ENODEV; + } + + adv = g_adv; + adv->rpdev = rpdev; + apummu_remote_init(); + + dev_set_drvdata(&rpdev->dev, adv); + + mem_task = kthread_run(apummu_rprmsg_memory_func, adv, "apummu"); + if (mem_task == NULL) { + AMMU_LOG_ERR("create kthread(mem) fail\n"); + ret = -ENOMEM; + goto out; + } + + AMMU_LOG_INFO("Done\n"); +out: + return ret; +} + +static void apummu_rpmsg_remove(struct rpmsg_device *rpdev) +{ + apummu_remote_exit(); + + AMMU_LOG_INFO("Done\n"); +} + +static const struct of_device_id apummu_rpmsg_of_match[] = { + { .compatible = "mediatek,apu-apummu-rpmsg", }, + { }, +}; + +static struct rpmsg_driver apummu_rpmsg_driver = { + .drv = { + .name = "apu-apummu-rpmsg", + .of_match_table = apummu_rpmsg_of_match, + }, + .probe = apummu_rpmsg_probe, + .remove = apummu_rpmsg_remove, + .callback = apummu_rpmsg_cb, +}; + +int apummu_init(void) +{ + int ret = 0; + + apummu_driver.driver.of_match_table = apummu_get_of_device_id(); + + ret = platform_driver_register(&apummu_driver); + if (ret) { + AMMU_LOG_ERR("failed to register APUSYS driver"); + goto out; + } + + ret = register_rpmsg_driver(&apummu_rpmsg_driver); + if (ret) { + AMMU_LOG_ERR("failed to register RMPSG driver"); + goto out; + } + + ret = register_rpmsg_driver(&apu_ipi_apummu_rx_rpmsg_driver); + if (ret) { + AMMU_LOG_ERR("failed to register RX_RMPSG driver"); + goto out; + } + + apummu_suspend_release_flag = false; + +out: + return ret; +} + +void apummu_exit(void) +{ + unregister_rpmsg_driver(&apu_ipi_apummu_rx_rpmsg_driver); + unregister_rpmsg_driver(&apummu_rpmsg_driver); + platform_driver_unregister(&apummu_driver); +} + +MODULE_SOFTDEP("pre: mtk_apu_top"); + +module_init(apummu_init); +module_exit(apummu_exit); +MODULE_DESCRIPTION("APU APUMMU Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.h new file mode 100644 index 0000000000000..416bf0d4d45b8 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_drv.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_DRV_H__ +#define __APUSYS_APUMMU_DRV_H__ + +#include +#include +#include +#include +#include +#include + +/* config define */ +#define DRAM_FALL_BACK_IN_RUNTIME (1) + +/* for RV data*/ +struct apummu_remote_data { +#if !(DRAM_FALL_BACK_IN_RUNTIME) + uint64_t dram[32]; +#endif + uint32_t dram_max; + + uint32_t vlm_size; + uint32_t vlm_addr; + + uint32_t SLB_base_addr; + uint32_t SLB_EXT_addr; + uint32_t SLB_size; + + uint32_t TCM_base_addr; + uint32_t general_SRAM_size; // TCM + general SLB +}; + +/* for plat data */ +struct apummu_platform { + uint32_t slb_wait_time; + uint32_t boundary; + + uint32_t internal_SLB_cnt; + uint32_t external_SLB_cnt; + struct mutex slb_mtx; + + bool is_general_SLB_support; + bool alloc_DRAM_FB_in_session_create; // add for DRAM FB alloc time check +}; + +struct apummu_resource { + uint64_t iova; + uint32_t size; + void *base; +}; + +struct apummu_resource_mgt { + struct apummu_resource vlm_dram; + struct apummu_resource internal_SLB; + struct apummu_resource external_SLB; + struct apummu_resource genernal_SLB; +}; + +/* apummu driver's private structure */ +struct apummu_dev_info { + bool init_done; + struct device *dev; + dev_t apummu_devt; + struct cdev apummu_cdev; + struct rpmsg_device *rpdev; + + struct apummu_resource_mgt rsc; + + struct apummu_platform plat; + struct apummu_remote_data remote; +}; + +/* for aputop module AEE data */ +struct apummu_rx_data { + uint8_t module_id; + int8_t error_code; +}; +enum { + APUMMU_RX_TEST = 0, + APUMMU_RX_APUMMU_AEE = 1, + APUMMU_RX_HSE_AEE = 2, + APUMMU_RX_CBFC_AEE = 3, + APUMMU_RX_LAST = 4, +}; + +extern struct apummu_tbl g_ammu_table_set; + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_export.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_export.c new file mode 100644 index 0000000000000..4d3709e3f94e8 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_export.c @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include "linux/soc/mediatek/mtk_apu_device.h" + +#include "apummu_cmn.h" +#include "linux/soc/mediatek/apummu_export.h" +#include "apummu_drv.h" +#include "apummu_remote_cmd.h" +#include "apummu_import.h" +#include "apummu_mgt.h" + +#include "linux/soc/mediatek/apu_mem_export.h" + +extern struct apummu_dev_info *g_adv; + +static struct apu_mem_export_ops apummu_export_ops = { + .apu_mem_alloc = apummu_alloc_mem, + .apu_mem_free = apummu_free_mem, + .apu_mem_import = apummu_import_mem, + .apu_mem_unimport = apummu_unimport_mem, + .apu_mem_map = apummu_map_mem, + .apu_mem_unmap = apummu_unmap_mem, + + + .apu_mem_map_iova = apummu_iova2eva, + .apu_mem_iova_decode = apummu_eva2iova, + .apu_mem_unmap_iova = apummu_buffer_remove, + .apu_mem_table_get = apummu_table_get, + .apu_mem_table_free = apummu_table_free, + .apu_mem_DRAM_FB_alloc = apummu_DRAM_FB_alloc +}; + +int apummu_alloc_mem(uint32_t type, uint32_t size, uint64_t *addr, uint32_t *sid) +{ + int ret = 0; + uint64_t ret_addr = 0, ret_size = 0; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + mutex_lock(&g_adv->plat.slb_mtx); + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + if (g_adv->plat.external_SLB_cnt) { + AMMU_LOG_WRN("External SLB is already alloced(%u->%u)\n", + g_adv->plat.external_SLB_cnt, g_adv->plat.external_SLB_cnt+1); + /* Still return to prevent unexcept user behavior */ + ret_addr = g_adv->rsc.external_SLB.iova; + ret_size = g_adv->rsc.external_SLB.size; + g_adv->plat.external_SLB_cnt++; + goto out; + } + + /* Put alloc inside to prevent alloc twice */ + ret = apummu_alloc_slb(type, size, g_adv->plat.slb_wait_time, + &ret_addr, &ret_size); + if (ret) + goto err; + + g_adv->rsc.external_SLB.iova = ret_addr; + g_adv->rsc.external_SLB.size = (uint32_t) ret_size; + AMMU_LOG_DBG("External SLB allocate(%u->%u)\n", + g_adv->plat.external_SLB_cnt, g_adv->plat.external_SLB_cnt+1); + g_adv->plat.external_SLB_cnt++; + break; + case APUMMU_MEM_TYPE_RSV_S: + if (g_adv->plat.internal_SLB_cnt) { + AMMU_LOG_WRN("Internal SLB is already alloced(%u->%u)\n", + g_adv->plat.internal_SLB_cnt, g_adv->plat.internal_SLB_cnt+1); + /* Still return to prevent unexcept user behavior */ + ret_addr = g_adv->rsc.internal_SLB.iova; + ret_size = g_adv->rsc.internal_SLB.size; + g_adv->plat.internal_SLB_cnt++; + goto out; + } + + /* Put alloc inside to prevent alloc twice */ + ret = apummu_alloc_slb(type, size, g_adv->plat.slb_wait_time, + &ret_addr, &ret_size); + if (ret) + goto err; + + g_adv->rsc.internal_SLB.iova = ret_addr; + g_adv->rsc.internal_SLB.size = (uint32_t) ret_size; + AMMU_LOG_DBG("Internal SLB allocate(%u->%u)\n", + g_adv->plat.internal_SLB_cnt, g_adv->plat.internal_SLB_cnt+1); + g_adv->plat.internal_SLB_cnt++; + break; + case APUMMU_MEM_TYPE_RSV_T: + ret_addr = g_adv->remote.TCM_base_addr; + ret_size = g_adv->remote.general_SRAM_size; + break; + case APUMMU_MEM_TYPE_VLM: + ret_addr = g_adv->remote.vlm_addr; + ret_size = g_adv->remote.vlm_size; + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + AMMU_LOG_DBG("[Alloc][Done] Mem type(%u), addr(0x%llx), size(0x%llx)\n", + type, ret_addr, ret_size); + +out: + mutex_unlock(&g_adv->plat.slb_mtx); + *addr = ret_addr; + *sid = type; + + return ret; + +err: + mutex_unlock(&g_adv->plat.slb_mtx); + AMMU_LOG_ERR("[Alloc][Fail] Mem type(%u), addr(0x%llx), size(0x%llx)\n", + type, ret_addr, ret_size); + apusys_ammu_exception("alloc SLB fail\n"); + return ret; +} + +int apummu_free_mem(uint32_t sid) +{ + int ret = 0; + uint32_t type = sid; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + mutex_lock(&g_adv->plat.slb_mtx); + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + case APUMMU_MEM_TYPE_RSV_S: + if (type == APUMMU_MEM_TYPE_EXT) { + if (!g_adv->plat.external_SLB_cnt) { + AMMU_LOG_WRN("External SLB is not alloced\n"); + goto out; + } + + g_adv->plat.external_SLB_cnt--; + if (g_adv->plat.external_SLB_cnt) { + AMMU_LOG_DBG("External SLB cnt(%u->%u), dont release\n", + g_adv->plat.external_SLB_cnt+1, g_adv->plat.external_SLB_cnt); + goto out; + } + + AMMU_LOG_DBG("release External SLB cnt(%u)\n", g_adv->plat.external_SLB_cnt); + //g_adv->plat.is_external_SLB_alloc = false; + g_adv->rsc.external_SLB.iova = 0; + g_adv->rsc.external_SLB.size = 0; + } else { + if (!g_adv->plat.internal_SLB_cnt) { + AMMU_LOG_WRN("Internal SLB is not alloced\n"); + goto out; + } + + g_adv->plat.internal_SLB_cnt--; + if (g_adv->plat.internal_SLB_cnt) { + AMMU_LOG_DBG("Internal SLB cnt(%u->%u), dont release\n", + g_adv->plat.internal_SLB_cnt+1, g_adv->plat.internal_SLB_cnt); + goto out; + } + + AMMU_LOG_DBG("release Internal SLB cnt(%u)\n", g_adv->plat.internal_SLB_cnt); + //g_adv->plat.is_internal_SLB_alloc = false; + g_adv->rsc.internal_SLB.iova = 0; + g_adv->rsc.internal_SLB.size = 0; + } + + ret = apummu_free_slb(type); + if (ret) + goto err; + + ammu_session_table_check_SLB(type); + break; + case APUMMU_MEM_TYPE_VLM: + case APUMMU_MEM_TYPE_RSV_T: + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + AMMU_LOG_DBG("[Free][Done] Mem type(%u)\n", type); + +out: + mutex_unlock(&g_adv->plat.slb_mtx); + return ret; + +err: + mutex_unlock(&g_adv->plat.slb_mtx); + AMMU_LOG_ERR("[Free][Fail] Mem type(%u)\n", type); + apusys_ammu_exception("free SLB fail\n"); + return ret; +} + +int apummu_import_mem(uint64_t session, uint32_t type) +{ + int ret = 0; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + case APUMMU_MEM_TYPE_RSV_S: + ret = ammu_session_table_add_SLB(session, type); + if (ret) + goto err; + + break; + case APUMMU_MEM_TYPE_VLM: + case APUMMU_MEM_TYPE_RSV_T: + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + AMMU_LOG_DBG("[Import][Done] Mem session(0x%llx), type(%u)\n", session, type); + return ret; + +err: + AMMU_LOG_ERR("[Import][Fail] Mem session(0x%llx), type(%u)\n", session, type); + return ret; +} + +int apummu_unimport_mem(uint64_t session, uint32_t type) +{ + int ret = 0; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + case APUMMU_MEM_TYPE_RSV_S: + ret = ammu_session_table_remove_SLB(session, type); + if (ret) + goto err; + + break; + case APUMMU_MEM_TYPE_VLM: + case APUMMU_MEM_TYPE_RSV_T: + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + AMMU_LOG_DBG("[Unimport][Done] Mem session(0x%llx), type(%u)\n", session, type); + return ret; + +err: + AMMU_LOG_ERR("[Unimport][Fail] Mem session(0x%llx), type(%u)\n", session, type); + return ret; +} + +int apummu_map_mem(uint64_t session, uint32_t sid, uint64_t *addr) +{ + int ret = 0; + uint64_t ret_addr = 0; + uint32_t type = sid; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + case APUMMU_MEM_TYPE_RSV_S: + ret = ammu_session_table_add_SLB(session, type); + if (ret) + goto err; + + ret_addr = (type == APUMMU_MEM_TYPE_EXT) + ? g_adv->rsc.external_SLB.iova + : g_adv->rsc.internal_SLB.iova; + + break; + case APUMMU_MEM_TYPE_VLM: + case APUMMU_MEM_TYPE_RSV_T: + ret_addr = g_adv->remote.vlm_addr; + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + *addr = ret_addr; + + AMMU_LOG_DBG("[Map][Done] Mem (0x%llx/0x%x/0x%llx)\n", session, type, ret_addr); + return ret; + +err: + AMMU_LOG_ERR("[Map][Fail] Mem (0x%llx/0x%x/0x%llx)\n", session, type, ret_addr); + return ret; +} + +int apummu_unmap_mem(uint64_t session, uint32_t sid) +{ + int ret = 0; + uint32_t type = sid; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + return ret; + } + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + case APUMMU_MEM_TYPE_RSV_S: + ret = ammu_session_table_remove_SLB(session, type); + if (ret) + goto err; + + break; + case APUMMU_MEM_TYPE_VLM: + case APUMMU_MEM_TYPE_RSV_T: + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto err; + } + + AMMU_LOG_DBG("[Unmap][Done] Mem (0x%llx/0x%x)\n", session, sid); + return ret; + +err: + AMMU_LOG_ERR("[Unmap][Fail] Mem (0x%llx/0x%x)\n", session, sid); + return ret; +} + +/** + * @para: + * type -> input buffer type, plz refer to enum AMMU_BUF_TYPE + * session -> input session + * device_va -> input device_va (gonna encode to eva) + * buf_size -> size of the buffer + * eva -> output eva + * @description: + * encode input addr to eva according to buffer type + * for apummu, we also record translate info into session table + */ +int apummu_iova2eva(uint32_t type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva) +{ + return addr_encode_and_write_stable(type, session, device_va, buf_size, eva); +} + +/** + * @para: + * eva -> input eva (gonna decode to iova) + * iova -> output iova + * @description: + * decode input addr to iova according to buffer type + */ +int apummu_eva2iova(uint64_t eva, uint64_t *iova) +{ + return apummu_eva_decode(eva, iova, AMMU_DATA_BUF); +} + +/** + * @para: + * session -> input session + * device_va -> input device_va + * buf_size -> size of the buffer + * @description: + * remove the mapping setting of the given buffer + */ +int apummu_buffer_remove(uint64_t session, uint64_t device_va, uint32_t buf_size) +{ + return apummu_stable_buffer_remove(session, device_va, buf_size); +} + +/** + * @para: + * session -> hint for searching target session table + * tbl_kva -> returned addr for session rable + * size -> returned session table size + * @description: + * return the session table according to session + */ +int apummu_table_get(uint64_t session, void **tbl_kva, uint32_t *size) +{ + return get_session_table(session, tbl_kva, size); +} + +/** + * @para: + * session -> hint for searching target session table + * @description: + * delete the session table according to session + */ +int apummu_table_free(uint64_t session) +{ + return session_table_free(session); +} + +int apummu_DRAM_FB_alloc(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num) +{ + return ammu_DRAM_FB_alloc(session, vlm_size, subcmd_num); +} +EXPORT_SYMBOL_NS(apummu_DRAM_FB_alloc, MTK_APU_MEM); + + +int apummu_export_API_init(void) +{ + return apu_mem_op_init(&apummu_export_ops); +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.c new file mode 100644 index 0000000000000..d8553c224670e --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include "linux/soc/mediatek/mtk_apu_device.h" +#include "apummu_cmn.h" +#include "apummu_import.h" +#include "slbc_ops.h" + +int apummu_alloc_slb(uint32_t type, uint32_t size, uint32_t slb_wait_time, + uint64_t *ret_addr, uint64_t *ret_size) +{ + int ret = 0; + struct slbc_data slb; + + slb.paddr = 0; + slb.size = 0; + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + slb.uid = UID_SH_APU; + slb.type = TP_BUFFER; + break; + case APUMMU_MEM_TYPE_RSV_S: + slb.uid = UID_AINR; + slb.type = TP_BUFFER; + slb.timeout = slb_wait_time; + break; + case APUMMU_MEM_TYPE_GENERAL_S: + slb.uid = UID_APU; + slb.type = TP_BUFFER; + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto out; + } + + ret = slbc_request(&slb); + if (ret) + goto out; + + *ret_addr = (size_t) slb.paddr; + *ret_size = slb.size; +out: + return ret; +} +int apummu_free_slb(uint32_t type) +{ + int ret = 0; + struct slbc_data slb; + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + slb.uid = UID_SH_APU; + slb.type = TP_BUFFER; + break; + case APUMMU_MEM_TYPE_RSV_S: + slb.uid = UID_AINR; + slb.type = TP_BUFFER; + break; + case APUMMU_MEM_TYPE_GENERAL_S: + slb.uid = UID_APU; + slb.type = TP_BUFFER; + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto out; + } + + ret = slbc_release(&slb); + if (ret) { + AMMU_LOG_ERR("slbc_release Fail %d\n", ret); + goto out; + } +out: + return ret; +} + +int apummu_check_slb_status(uint32_t type) +{ + int ret = 0; + struct slbc_data slb; + + switch (type) { + case APUMMU_MEM_TYPE_EXT: + slb.uid = UID_SH_APU; + slb.type = TP_BUFFER; + break; + case APUMMU_MEM_TYPE_RSV_S: + slb.uid = UID_AINR; + slb.type = TP_BUFFER; + break; + case APUMMU_MEM_TYPE_GENERAL_S: + slb.uid = UID_APU; + slb.type = TP_BUFFER; + break; + default: + AMMU_LOG_ERR("Invalid type %u\n", type); + ret = -EINVAL; + goto out; + } + + ret = slbc_status(&slb); + +out: + return ret; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.h new file mode 100644 index 0000000000000..d7dd947142266 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_import.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_IMPORT_H__ +#define __APUSYS_APUMMU_IMPORT_H__ +#include + +#include "linux/soc/mediatek/apummu_mem_def.h" + +int apummu_alloc_slb(uint32_t type, uint32_t size, uint32_t slb_wait_time, + uint64_t *ret_addr, uint64_t *ret_size); +int apummu_free_slb(uint32_t type); +int apummu_check_slb_status(uint32_t type); +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.c new file mode 100644 index 0000000000000..060ddb336a4b9 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.c @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apummu_cmn.h" +#include "apummu_mem.h" +#include "apummu_import.h" +#include "linux/soc/mediatek/apummu_mem_def.h" + +static struct apummu_mem *g_mem_sys; +static uint32_t general_SLB_attempt_cnt; +static uint32_t DMA_CNT; + +static struct list_head g_mem_list_head; + +struct ammu_mem_dma { + dma_addr_t dma_addr; + uint32_t dma_size; + uint32_t size; + uint32_t cnt; + void *vaddr; + struct list_head attachments; + struct sg_table sgt; + void *buf; + bool uncached; + struct mutex mtx; + struct device *mem_dev; +}; + +#if USING_SELF_DMA +struct ammu_mem_dma_attachment { + struct sg_table *sgt; + struct device *dev; + struct list_head node; + bool mapped; + bool uncached; +}; + +static struct sg_table *ammu_dmabuf_map_dma(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct ammu_mem_dma_attachment *a = attach->priv; + struct sg_table *table = NULL; + int attr = attach->dma_map_attrs; + int ret = 0; + + table = a->sgt; + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; + + ret = dma_map_sgtable(attach->dev, table, dir, attr); + if (ret) + table = ERR_PTR(ret); + + a->mapped = true; + + return table; +} + +static void ammu_dmabuf_unmap_dma(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ + struct ammu_mem_dma_attachment *a = attach->priv; + int attr = attach->dma_map_attrs; + int attr = 0; + + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; + + a->mapped = false; + dma_unmap_sgtable(attach->dev, sgt, dir, attr); +} + +static struct sg_table *ammu_mem_dma_dup_sg(struct sg_table *table) +{ + struct sg_table *new_table; + int ret, i; + struct scatterlist *sg, *new_sg; + + new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); + if (!new_table) + return ERR_PTR(-ENOMEM); + + ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL); + if (ret) { + kfree(new_table); + return ERR_PTR(-ENOMEM); + } + + new_sg = new_table->sgl; + for_each_sgtable_sg(table, sg, i) { + sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset); + new_sg = sg_next(new_sg); + } + + return new_table; +} + +static int ammu_dmabuf_attach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct ammu_mem_dma_attachment *a = NULL; + struct apummu_mem *m = dbuf->priv; + struct ammu_mem_dma *mdbuf = m->priv; + int ret = 0; + struct sg_table *table; + + AMMU_LOG_VERBO("dbuf(0x%llx)\n", (uint64_t)dbuf); + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + table = ammu_mem_dma_dup_sg(&mdbuf->sgt); + if (IS_ERR(table)) { + kfree(a); + return -ENOMEM; + } + + a->sgt = table; + a->dev = attach->dev; + INIT_LIST_HEAD(&a->node); + a->mapped = false; + a->uncached = mdbuf->uncached; + attach->priv = a; + + mutex_lock(&mdbuf->mtx); + list_add(&a->node, &mdbuf->attachments); + mutex_unlock(&mdbuf->mtx); + + return ret; +} + +static void ammu_dmabuf_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct ammu_mem_dma_attachment *a = attach->priv; + struct apummu_mem *m = dbuf->priv; + struct ammu_mem_dma *mdbuf = m->priv; + + AMMU_LOG_VERBO("dbuf(0x%llx)\n", (uint64_t)dbuf); + + mutex_lock(&mdbuf->mtx); + list_del(&a->node); + mutex_unlock(&mdbuf->mtx); + + sg_free_table(a->sgt); + kfree(a->sgt); + kfree(a); +} + +static void ammu_dmabuf_release(struct dma_buf *dbuf) +{ + struct apummu_mem *m = dbuf->priv; + struct ammu_mem_dma *mdbuf = m->priv; + + AMMU_LOG_VERBO("dbuf(0x%llx) release\n", (uint64_t)dbuf); + + sg_free_table(&mdbuf->sgt); + vunmap(mdbuf->vaddr); + vfree(mdbuf->buf); + kfree(mdbuf); + kfree(m); +} + +static struct dma_buf_ops ammu_dmabuf_ops = { + .attach = ammu_dmabuf_attach, + .detach = ammu_dmabuf_detach, + .map_dma_buf = ammu_dmabuf_map_dma, + .unmap_dma_buf = ammu_dmabuf_unmap_dma, + .release = ammu_dmabuf_release, +}; + +static int ammu_mem_dma_allocate_sgt(const char *buf, + size_t len, struct sg_table *sgt, bool uncached, void **vaddr) +{ + struct page **pages = NULL; + unsigned int nr_pages; + unsigned int alloc_size; + unsigned int index; + const char *p; + int ret; + pgprot_t pgprot = PAGE_KERNEL; + void *va; + + nr_pages = DIV_ROUND_UP((unsigned long)buf + len, PAGE_SIZE) + - ((unsigned long)buf / PAGE_SIZE); + alloc_size = nr_pages * sizeof(struct page *); + pages = kvmalloc(alloc_size, GFP_KERNEL); + + AMMU_LOG_VERBO("ammu buf: 0x%lx, len: 0x%lx, nr_pages: %d\n", + (unsigned long)buf, len, nr_pages); + + if (!pages) { + AMMU_LOG_ERR("No Page 0x%lx, len: 0x%lx, nr_pages: %d\n", + (unsigned long)buf, len, nr_pages); + return -ENOMEM; + } + + p = buf - offset_in_page(buf); + AMMU_LOG_VERBO("start p: 0x%llx buf: 0x%llx\n", + (uint64_t) p, (uint64_t) buf); + + for (index = 0; index < nr_pages; index++) { + if (is_vmalloc_addr(p)) + pages[index] = vmalloc_to_page(p); + else + pages[index] = kmap_to_page((void *)p); + if (!pages[index]) { + kvfree(pages); + AMMU_LOG_ERR("map failed\n"); + return -EFAULT; + } + p += PAGE_SIZE; + } + if (uncached) + pgprot = pgprot_writecombine(PAGE_KERNEL); + + // vmap to set page property + va = vmap(pages, nr_pages, VM_MAP, pgprot); + + ret = sg_alloc_table_from_pages(sgt, pages, index, + offset_in_page(buf), len, GFP_KERNEL); + kvfree(pages); + if (ret) { + AMMU_LOG_ERR("sg_alloc_table_from_pages: %d\n", ret); + return ret; + } + + *vaddr = va; + + AMMU_LOG_VERBO("buf: 0x%lx, len: 0x%lx, sgt: 0x%lx nr_pages: %d va 0x%lx\n", + (unsigned long)buf, len, (unsigned long)sgt, nr_pages, (unsigned long)va); + + return 0; +} + +static int apummu_mem_alloc_sgt(struct device *dev, struct apummu_mem *mem) +{ + struct ammu_mem_dma *mdbuf = NULL; + int ret = 0; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + void *kva; + bool uncached = true; + + /* alloc ammu dma-buf container */ + mdbuf = kzalloc(sizeof(*mdbuf), GFP_KERNEL); + if (!mdbuf) { + AMMU_LOG_ERR("alloc mdbuf fail\n"); + return -ENOMEM; + } + + mutex_init(&mdbuf->mtx); + INIT_LIST_HEAD(&mdbuf->attachments); + + /* alloc buffer by dma */ + mdbuf->dma_size = PAGE_ALIGN(mem->size); + AMMU_LOG_VERBO("alloc (mem size, dma size) (0x%x/0x%x)\n", mem->size, mdbuf->dma_size); + + kva = vzalloc(mdbuf->dma_size); + if (!kva) { + AMMU_LOG_ERR("alloc DRAM fail, (mem size, dma size)=(0x%x, 0x%x)\n", + mem->size, mdbuf->dma_size); + ret = -ENOMEM; + goto free_ammu_dbuf; + } + + mdbuf->buf = kva; + + if (ammu_mem_dma_allocate_sgt( + kva, mdbuf->dma_size, &mdbuf->sgt, + uncached, &mdbuf->vaddr)) { + AMMU_LOG_ERR("get sgt: failed\n"); + ret = -ENOMEM; + goto free_buf; + } + + /* export as dma-buf */ + exp_info.ops = &ammu_dmabuf_ops; + exp_info.size = mdbuf->dma_size; + exp_info.flags = O_RDWR | O_CLOEXEC; + exp_info.priv = mem; + + mem->dbuf = dma_buf_export(&exp_info); + if (IS_ERR(mem->dbuf)) { + AMMU_LOG_ERR("dma_buf_export Fail\n"); + ret = -ENOMEM; + goto free_sgt; + } + + mdbuf->mem_dev = dev; + mdbuf->size = mem->size; + mdbuf->uncached = uncached; + mdbuf->cnt = DMA_CNT++; + /* access data to ammu_mem */ + mem->vaddr = mdbuf->vaddr; + mem->priv = mdbuf; + + if (uncached) { + dma_sync_sgtable_for_device(dev, + &mdbuf->sgt, DMA_TO_DEVICE); + } + + goto out; + +free_sgt: + sg_free_table(&mdbuf->sgt); +free_buf: + vfree(kva); +free_ammu_dbuf: + kfree(mdbuf); +out: + return ret; +} + +static int ammu_mem_map_create(struct device *dev, struct apummu_mem *m) +{ + struct ammu_mem_map *map = NULL; + struct scatterlist *sg = NULL; + int ret = 0, i = 0; + + // get_dma_buf(m->dbuf); + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) { + ret = -ENOMEM; + goto out; + } + + /* attach device */ + map->attach = dma_buf_attach(m->dbuf, dev); + if (IS_ERR(map->attach)) { + ret = PTR_ERR(map->attach); + AMMU_LOG_ERR("dma_buf_attach failed: %d\n", ret); + goto free_map; + } + + /* map device va */ + map->sgt = dma_buf_map_attachment_unlocked(map->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(map->sgt)) { + ret = PTR_ERR(map->sgt); + AMMU_LOG_ERR("dma_buf_map_attachment_unlocked failed: %d\n", ret); + goto detach_dbuf; + } + + /* get start addr and size */ + m->iova = sg_dma_address(map->sgt->sgl); + for_each_sgtable_dma_sg(map->sgt, sg, i) { + if (!sg) + break; + m->dva_size += sg_dma_len(sg); + } + + /* check iova and size */ + if (!m->iova || !m->dva_size) { + AMMU_LOG_ERR("can't get mem(0x%llx) iova(0x%llx/%u)\n", + (uint64_t)m, m->iova, m->dva_size); + ret = -ENOMEM; + goto unmap_dbuf; + } + + map->m = m; + m->map = map; + goto out; + +unmap_dbuf: + dma_buf_unmap_attachment_unlocked(map->attach, + map->sgt, DMA_BIDIRECTIONAL); +detach_dbuf: + dma_buf_detach(m->dbuf, map->attach); +free_map: + m->iova = 0; + m->dva_size = 0; + m->map = NULL; + kfree(map); +out: + return ret; +} + +static int ammu_mem_unmap(struct apummu_mem *m) +{ + int ret = 0; + struct ammu_mem_map *map = m->map; + + /* unmap device va */ + dma_buf_unmap_attachment_unlocked(map->attach, + map->sgt, DMA_BIDIRECTIONAL); + dma_buf_detach(m->dbuf, map->attach); + m->iova = 0; + m->size = 0; + m->map = NULL; + kfree(map); + + return ret; +} +#endif + +void apummu_mem_free(struct device *dev, struct apummu_mem *mem) +{ +#if USING_SELF_DMA + int ret = 0; + + ret = ammu_mem_unmap(mem); + if (ret) + AMMU_LOG_ERR("ammu_mem_unmap fail...\n"); + + dma_buf_put(mem->dbuf); +#else + if (mem->iova != 0) { // To handle dma_heap_buffer_alloc fail by signal + dma_buf_unmap_attachment(mem->attach, mem->sgt, DMA_BIDIRECTIONAL); + dma_buf_detach(mem->priv, mem->attach); + dma_buf_put(mem->priv); + dma_heap_put(mem->heap); + } + // dma_free_coherent(dev, mem->size, (void *)mem->kva, mem->iova); +#endif +} + +int apummu_mem_alloc(struct device *dev, struct apummu_mem *mem) +{ + int ret = 0; + struct platform_device *apusys_rv_pdev; + struct device_node *apusys_rv_np; + + apusys_rv_np = of_parse_phandle(dev->of_node, "apu-rv-dev", 0); + if (!apusys_rv_np) { + pr_err("failed to find apu-rv-dev\n"); + return -ENXIO; + } + + apusys_rv_pdev = of_find_device_by_node(apusys_rv_np); + if (!apusys_rv_pdev) { + pr_err("failed to find apu-rv-dev\n"); + return -1; + } + + dev = &apusys_rv_pdev->dev; + +#if USING_SELF_DMA + ret = apummu_mem_alloc_sgt(dev, mem); + if (ret) { + AMMU_LOG_ERR("apummu_mem_alloc_sgt fail (0x%x)\n", mem->size); + goto out; + } + + ret = ammu_mem_map_create(dev, mem); + if (ret) { + AMMU_LOG_ERR("ammu_mem_map_create fail (0x%x)\n", mem->size); + goto out; + } +#else + mem->heap = dma_heap_find("system"); + if (!mem->heap) { + AMMU_LOG_ERR("Cannot get system heap\n"); + ret = -ENOMEM; + goto out; + } + + mem->priv = dma_heap_buffer_alloc(mem->heap, mem->size, O_RDWR | O_CLOEXEC, 0); + if (IS_ERR_OR_NULL(mem->priv)) { + if (!mem->priv || mem->priv != ERR_PTR(-EINTR)) { + AMMU_LOG_ERR("dma_heap_buffer_alloc fail mem size = 0x%x\n", mem->size); + ret = -ENOMEM; + } else { + AMMU_LOG_WRN("APUMMU mem alloc fail trigger by signal...\n"); + } + goto heap_alloc_err; + } + + mem->attach = dma_buf_attach(mem->priv, dev); + if (IS_ERR_OR_NULL(mem->attach)) { + AMMU_LOG_ERR("dma_buf_attach fail\n"); + ret = -ENOMEM; + goto dma_buf_attach_err; + } + + mem->sgt = dma_buf_map_attachment(mem->attach, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(mem->sgt)) { + AMMU_LOG_ERR("dma_buf_map_attachment fail\n"); + ret = -ENOMEM; + goto dbuf_map_attachment_err; + } + + mem->iova = sg_dma_address(mem->sgt->sgl); +#endif + + AMMU_LOG_INFO("DRAM alloc mem(0x%llx/0x%x)\n", + mem->iova, mem->size); + +out: + return ret; + +#if !(USING_SELF_DMA) +dbuf_map_attachment_err: + dma_buf_detach(mem->priv, mem->attach); +dma_buf_attach_err: + dma_buf_put(mem->priv); +heap_alloc_err: + dma_heap_put(mem->heap); +#endif + return ret; +} + +#if !(DRAM_FALL_BACK_IN_RUNTIME) +int apummu_dram_remap_alloc(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + unsigned int i = 0; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + g_mem_sys.size = (uint64_t) adv->remote.vlm_size * adv->remote.dram_max; + ret = apummu_mem_alloc(adv->dev, &g_mem_sys); + if (ret) { + AMMU_LOG_ERR("DRAM FB mem alloc fail\n"); + goto out; + } + + adv->rsc.vlm_dram.base = (void *) g_mem_sys.kva; + adv->rsc.vlm_dram.size = g_mem_sys.size; + for (i = 0; i < adv->remote.dram_max; i++) + adv->remote.dram[i] = g_mem_sys.iova + adv->remote.vlm_size * (uint64_t) i; + +out: + return ret; +} + +int apummu_dram_remap_free(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + adv = (struct apummu_dev_info *)drvinfo; + + apummu_mem_free(adv->dev, &g_mem_sys); + adv->rsc.vlm_dram.base = NULL; + return 0; +} +#else +int apummu_dram_remap_runtime_alloc(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + if (adv->rsc.vlm_dram.iova != 0) { + AMMU_LOG_ERR("Error DRAM FB already alloc\n"); + ret = -EINVAL; + goto out; + } + + g_mem_sys = kzalloc(sizeof(*g_mem_sys), GFP_KERNEL); + if (!g_mem_sys) { + AMMU_LOG_ERR("g_mem_sys alloc fail\n"); + ret = -ENOMEM; + goto out; + } + + g_mem_sys->size = (uint64_t) adv->remote.vlm_size * adv->remote.dram_max; + + ret = apummu_mem_alloc(adv->dev, g_mem_sys); + if (ret) { + kfree(g_mem_sys); + goto out; + } + + adv->rsc.vlm_dram.base = (void *) g_mem_sys->kva; + adv->rsc.vlm_dram.size = g_mem_sys->size; + adv->rsc.vlm_dram.iova = g_mem_sys->iova; + +out: + return ret; +} + +int apummu_dram_remap_runtime_free(void *drvinfo) +{ + int ret = 0; + + struct apummu_dev_info *adv = NULL; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + apummu_mem_free(adv->dev, g_mem_sys); + adv->rsc.vlm_dram.base = 0; + adv->rsc.vlm_dram.size = 0; + adv->rsc.vlm_dram.iova = 0; +#if USING_SELF_DMA + g_mem_sys = NULL; +#else + kfree(g_mem_sys); +#endif + +out: + return ret; +} + +int apummu_dram_remap_runtime_alloc_with_size(void *drvinfo, uint32_t ctx_num_going_alloc, uint64_t *ret_IOVA) +{ + struct apummu_mem *mem; + struct apummu_dev_info *adv = NULL; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + if (ctx_num_going_alloc == 0) { + AMMU_LOG_ERR("Cannot alloc with ctx_num_going_alloc Zero\n"); + ret = -EINVAL; + goto out; + } + + mem = kzalloc(sizeof(struct apummu_mem), GFP_KERNEL); + if (!mem) { + AMMU_LOG_ERR("apummu_mem alloc fail\n"); + ret = -ENOMEM; + goto out; + } + + mem->size = (uint64_t) adv->remote.vlm_size * ctx_num_going_alloc; + + ret = apummu_mem_alloc(adv->dev, mem); + if (ret) { + kfree(mem); + goto out; + } + + *ret_IOVA = mem->iova; + AMMU_LOG_VERBO("sbu_cmd_num = %u, mem->size = 0x%x, ret_IOVA = 0x%llx\n", + ctx_num_going_alloc, mem->size, *ret_IOVA); + list_add_tail(&mem->list, &g_mem_list_head); + +out: + return ret; +} + +int apummu_dram_remap_runtime_free_single_node(void *drvinfo, uint64_t target_iova) +{ + int ret = -EINVAL; + struct list_head *list_ptr; + struct apummu_mem *target_mem_node; + struct apummu_dev_info *adv = NULL; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + list_for_each(list_ptr, &g_mem_list_head) { + target_mem_node = list_entry(list_ptr, struct apummu_mem, list); + if (target_mem_node->iova == target_iova) { + ret = 0; + list_del(&target_mem_node->list); + apummu_mem_free(adv->dev, target_mem_node); + kfree(target_mem_node); + break; + } + } + +out: + return ret; +} + +int apummu_dram_remap_runtime_free_whole_list(void *drvinfo) +{ + int ret = 0; + struct list_head *list_ptr1, *list_ptr2; + struct apummu_mem *mem_ptr; + struct apummu_dev_info *adv = NULL; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + list_for_each_safe(list_ptr1, list_ptr2, &g_mem_list_head) { + mem_ptr = list_entry(list_ptr1, struct apummu_mem, list); + list_del(&mem_ptr->list); + apummu_mem_free(adv->dev, mem_ptr); + kfree(mem_ptr); + mem_ptr = NULL; + } + +out: + return ret; +} +#endif + +int apummu_alloc_general_SLB(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + uint64_t ret_addr, ret_size; + uint32_t size = 0; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + if (adv->rsc.genernal_SLB.iova != 0) { + /* Call check SLB status API, since SLB might timeout */ + if (apummu_check_slb_status(APUMMU_MEM_TYPE_GENERAL_S) != 0) { + AMMU_LOG_INFO("general SLB already added\n"); + goto out; + } else { + adv->rsc.genernal_SLB.iova = 0; + adv->rsc.genernal_SLB.size = 0; + AMMU_LOG_INFO("Overwrite SLB status manually, (addr, size) = (%llx, %x)\n", + adv->rsc.genernal_SLB.iova, adv->rsc.genernal_SLB.size); + } + } + + ret = apummu_alloc_slb(APUMMU_MEM_TYPE_GENERAL_S, size, adv->plat.slb_wait_time, + &ret_addr, &ret_size); + if (ret) { + AMMU_LOG_WRN("general SLB alloc fail %u times...\n", + general_SLB_attempt_cnt); + general_SLB_attempt_cnt += 1; + goto out; + } + + adv->rsc.genernal_SLB.iova = ret_addr; + adv->rsc.genernal_SLB.size = (uint32_t) ret_size; + + AMMU_LOG_VERBO("General SLB alloced after %u times. (addr, size) = (0x%llx, 0x%llx)\n", + general_SLB_attempt_cnt, ret_addr, ret_size); + general_SLB_attempt_cnt = 0; + +out: + return ret; +} + +int apummu_free_general_SLB(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + ret = -EINVAL; + goto out; + } + adv = (struct apummu_dev_info *)drvinfo; + + if (adv->rsc.genernal_SLB.iova == 0) { + AMMU_LOG_ERR("No general SLB is alloced\n"); + ret = -EINVAL; + goto out; + } + + ret = apummu_free_slb(APUMMU_MEM_TYPE_GENERAL_S); + if (ret) { + AMMU_LOG_WRN("general SLB free fail...\n"); + goto out; + } + + adv->rsc.genernal_SLB.iova = 0; + adv->rsc.genernal_SLB.size = 0; + + AMMU_LOG_VERBO("General SLB freeed\n"); + +out: + return ret; +} + +void apummu_mem_init(void) +{ + INIT_LIST_HEAD(&g_mem_list_head); + general_SLB_attempt_cnt = 0; + DMA_CNT = 0; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.h new file mode 100644 index 0000000000000..c6d762ebf7b79 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mem.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __APUSYS_APUMMU_MEM_H__ +#define __APUSYS_APUMMU_MEM_H__ +#include + +#include "linux/soc/mediatek/apummu_mem_def.h" +#include "apummu_drv.h" + +void apummu_mem_free(struct device *dev, struct apummu_mem *mem); +int apummu_mem_alloc(struct device *dev, struct apummu_mem *mem); + +/* VLM DRAM FB alloc/free API */ +#if !(DRAM_FALL_BACK_IN_RUNTIME) +int apummu_dram_remap_alloc(void *drvinfo); +int apummu_dram_remap_free(void *drvinfo); +#else +int apummu_dram_remap_runtime_alloc(void *drvinfo); +int apummu_dram_remap_runtime_free(void *drvinfo); +int apummu_dram_remap_runtime_alloc_with_size(void *drvinfo, + uint32_t ctx_num_going_alloc, uint64_t *ret_IOVA); +int apummu_dram_remap_runtime_free_single_node(void *drvinfo, uint64_t target_iova); +int apummu_dram_remap_runtime_free_whole_list(void *drvinfo); +#endif + +int apummu_alloc_general_SLB(void *drvinfo); +int apummu_free_general_SLB(void *drvinfo); + +void apummu_mem_init(void); + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.c new file mode 100644 index 0000000000000..2c3a0faa27606 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.c @@ -0,0 +1,992 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "apummu_drv.h" +#include "apummu_mgt.h" +#include "apummu_mem.h" +#include "apummu_remote_cmd.h" +#include "apummu_cmn.h" +#include "apummu_trace.h" + +extern struct apummu_dev_info *g_adv; + +struct apummu_tbl g_ammu_table_set; +struct apummu_session_tbl *g_ammu_stable_ptr; // stable stand for session table + +#define AMMU_FREE_DRAM_DELAY_MS (5 * 1000) +static struct workqueue_struct *ammu_workq; +static struct delayed_work DRAM_free_work; + +#define IOVA2EVA_ENCODE_EN (1) +#define PAGE_ARRAY_CNT_EN (1) +#define SHIFT_BITS (12) + +#if IOVA2EVA_ENCODE_EN +#define ENCODE_OFFSET (0x20000000) +#define IOVA2EVA(input_addr) (input_addr - ENCODE_OFFSET) // -512M +#define EVA2IOVA(input_addr) (input_addr + ENCODE_OFFSET) // +512M +#else +#define IOVA2EVA(input_addr) (input_addr) +#define EVA2IOVA(input_addr) (input_addr) +#endif + +/** + * @input: + * type -> buffer type + * input_addr -> addr to encode (IOVA) + * output_addr -> encoded address (EVA) + * @output: + * if encode succeeded + * @description: + * encode input addr according to type + */ +static int addr_encode(uint64_t input_addr, enum AMMU_BUF_TYPE type, uint64_t *output_addr) +{ + int ret = 0; + uint64_t ret_addr; + + switch (type) { + case AMMU_DATA_BUF: + ret_addr = IOVA2EVA(input_addr); + break; + case AMMU_CMD_BUF: + case AMMU_VLM_BUF: + ret_addr = input_addr; + break; + default: + AMMU_LOG_ERR("APUMMU encode invalid buffer type(%u)\n", type); + ret = -EINVAL; + goto out; + } + + *output_addr = ret_addr; +out: + return ret; +} + +static int addr_decode(uint64_t input_addr, enum AMMU_BUF_TYPE type, uint64_t *output_addr) +{ + int ret = 0; + uint64_t ret_addr; + + switch (type) { + case AMMU_DATA_BUF: + ret_addr = EVA2IOVA(input_addr); + break; + case AMMU_CMD_BUF: + case AMMU_VLM_BUF: + ret_addr = input_addr; + break; + default: + AMMU_LOG_ERR("APUMMU decode invalid buffer type(%u)\n", type); + ret = -EINVAL; + goto out; + } + + *output_addr = ret_addr; +out: + return ret; +} + +int apummu_eva_decode(uint64_t eva, uint64_t *iova, enum AMMU_BUF_TYPE type) +{ + return addr_decode(eva, type, iova); +} + +/** + * @input: + * session -> for session check + * @output: + * if the stable of input session is exist + * @description: + * Check if session table of input session exist + * also bind exist stable to g_ammu_stable_ptr + */ +static bool is_session_table_exist(uint64_t session) +{ + bool isExist = false; + struct list_head *list_ptr; + + list_for_each(list_ptr, &g_ammu_table_set.g_stable_head) { + g_ammu_stable_ptr = list_entry(list_ptr, struct apummu_session_tbl, list); + if (g_ammu_stable_ptr->session == session) { + isExist = true; + break; + } + } + + return isExist; +} + +static void count_page_array_en_num(void) +{ + int i; + uint32_t idx; + + for (idx = 0; idx < 2; idx++) { + #if PAGE_ARRAY_CNT_EN + if (g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[idx] != 0) { + for (i = 31; i >= 0; i--) { + if (g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[idx] + & (1 << i)) + break; + } + + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[idx] = + i + 1; + } else { + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[idx] = 0; + } + #else + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[idx] = 32; + #endif + } +} + +static void ammu_DRAM_free_work(struct work_struct *work) +{ + mutex_lock(&g_ammu_table_set.DRAM_FB_lock); + + if (g_ammu_table_set.is_work_canceled) { + ammu_trace_begin("APUMMU: free DRAM"); + apummu_dram_remap_runtime_free(g_adv); + ammu_trace_end(); + AMMU_LOG_INFO("Delay DRAM Free done\n"); + } else + g_ammu_table_set.is_work_canceled = true; + + g_ammu_table_set.is_free_job_set = false; + mutex_unlock(&g_ammu_table_set.DRAM_FB_lock); +} + +static void free_memory(struct kref *kref) +{ + ammu_trace_begin("APUMMU: free memory"); + + AMMU_LOG_VERBO("kref destroy\n"); +#if DRAM_FALL_BACK_IN_RUNTIME + if (g_adv->plat.alloc_DRAM_FB_in_session_create) { + if (g_adv->rsc.vlm_dram.iova != 0) { + queue_delayed_work(ammu_workq, &DRAM_free_work, + msecs_to_jiffies(AMMU_FREE_DRAM_DELAY_MS)); + g_ammu_table_set.is_free_job_set = true; + } + } else { + apummu_dram_remap_runtime_free_whole_list(g_adv); + g_ammu_table_set.subcmd_refcnt = 0; + g_ammu_table_set.alloc_subcmd_refcnt = 0; + AMMU_LOG_INFO("DRAM FB Free done\n"); + } +#endif + + if (g_ammu_table_set.is_SLB_alloc) { + ammu_trace_begin("APUMMU: Free SLB without IPI"); + /* MDW will close session in IPI handler in some case */ + // apummu_remote_mem_free_pool(g_adv); + if (apummu_free_general_SLB(g_adv)) + AMMU_LOG_WRN("General APU SLB free fail\n"); + + g_ammu_table_set.is_SLB_alloc = false; + ammu_trace_end(); + } + + g_ammu_table_set.is_VLM_info_IPI_sent = false; + g_ammu_table_set.is_SLB_set = false; + + ammu_trace_end(); +} + +static int apummu_whole_DRAM_FB_alloc(void) +{ + int ret = 0; + + /* + * Alloc DRAM for VLM fall back if DRAM is not allocated + * Cancel DRAM free delay workqueue if it is created + */ +#if DRAM_FALL_BACK_IN_RUNTIME + mutex_lock(&g_ammu_table_set.DRAM_FB_lock); + if (g_adv->remote.vlm_size != 0) { + if (g_adv->rsc.vlm_dram.iova == 0) { + ammu_trace_begin("APUMMU: Alloc DRAM"); + ret = apummu_dram_remap_runtime_alloc(g_adv); + if (ret) { + ammu_trace_end(); + apusys_ammu_exception("alloc DRAM FB fail\n"); + mutex_unlock(&g_ammu_table_set.DRAM_FB_lock); + goto out; + } + ammu_trace_end(); + } else { // DRAM not free, cancel delay job + if (!cancel_delayed_work(&DRAM_free_work) && g_ammu_table_set.is_free_job_set) + g_ammu_table_set.is_work_canceled = false; + else + g_ammu_table_set.is_free_job_set = false; + } + } + + mutex_unlock(&g_ammu_table_set.DRAM_FB_lock); +#endif + +out: + return ret; +} + +static void apummu_general_SLB_alloc(void) +{ + if (!g_adv->plat.is_general_SLB_support) + return; + + if (!g_ammu_table_set.is_SLB_alloc) { // SLB retry + ammu_trace_begin("APUMMU: SLB alloc"); + /* Do not assign return value, since alloc SLB may fail */ + if (apummu_alloc_general_SLB(g_adv)) + AMMU_LOG_VERBO("general SLB alloc fail...\n"); + else + g_ammu_table_set.is_SLB_alloc = true; + + ammu_trace_end(); + } +} + +static int apummu_first_session_IPI(bool vlm_dram_condition) +{ + int ret = 0; + + ammu_trace_begin("APUMMU: SLB + DRAM IPI"); + // if (g_adv->rsc.vlm_dram.iova != 0 || g_ammu_table_set.is_SLB_alloc) { + if (vlm_dram_condition || g_ammu_table_set.is_SLB_alloc) { + ret = apummu_remote_set_hw_default_iova_one_shot(g_adv); + if (ret) { + ammu_trace_end(); + AMMU_LOG_ERR("Remote set hw IOVA one shot fail!!\n"); + apusys_ammu_exception("Set DRAM FB + SLB fail\n"); + goto out; + } + } + ammu_trace_end(); + + g_ammu_table_set.is_SLB_set = (g_ammu_table_set.is_SLB_alloc); + g_ammu_table_set.is_VLM_info_IPI_sent = true; + +out: + return ret; +} + +static int apummu_set_general_SLB_IPI(void) +{ + int ret = 0; + + if (!g_ammu_table_set.is_SLB_set && g_ammu_table_set.is_SLB_alloc) { + ammu_trace_begin("APUMMU: SLB ONLY IPI"); + ret = apummu_remote_mem_add_pool( + g_adv, APUMMU_MEM_TYPE_GENERAL_S, + g_adv->rsc.genernal_SLB.iova, + g_adv->rsc.genernal_SLB.size, 0 + ); + if (ret) { + ammu_trace_end(); + apusys_ammu_exception("Set SLB fail\n"); + goto out; + } + ammu_trace_end(); + + g_ammu_table_set.is_SLB_set = true; + } + +out: + return ret; +} + +static int DRAM_and_SLB_alloc(void) +{ + int ret = 0; + + ret = apummu_whole_DRAM_FB_alloc(); + if (ret) + goto out; + + apummu_general_SLB_alloc(); + + if (!g_ammu_table_set.is_VLM_info_IPI_sent) { + #if DRAM_FALL_BACK_IN_RUNTIME + ret = apummu_first_session_IPI((g_adv->rsc.vlm_dram.iova != 0)); + if (ret) + goto free_DRAM; + #else + ret = apummu_set_general_SLB_IPI(); + if (ret) + goto free_general_SLB; + #endif + } else { + /* SLB retry IPI */ + ret = apummu_set_general_SLB_IPI(); + if (ret) + goto free_general_SLB; + } + +out: + return ret; + +#if DRAM_FALL_BACK_IN_RUNTIME +free_DRAM: + apummu_dram_remap_runtime_free(g_adv); +#endif +free_general_SLB: + apummu_free_general_SLB(g_adv); + return ret; +} + +static int DRAM_FB_alloc_with_size(uint32_t ctx_num_going_alloc, uint64_t *iova) +{ + int ret = 0; + uint64_t ret_IOVA = 0; + + if (g_adv->remote.vlm_size != 0) { + ammu_trace_begin("APUMMU: Alloc DRAM"); + ret = apummu_dram_remap_runtime_alloc_with_size(g_adv, ctx_num_going_alloc, &ret_IOVA); + if (ret) { + ammu_trace_end(); + apusys_ammu_exception("alloc DRAM FB fail\n"); + goto out; + } + ammu_trace_end(); + } else { + AMMU_LOG_WRN("Should not call VLM alloc in VLM not supported platform\n"); + } + + *iova = ret_IOVA; + +out: + return ret; +} + +static int partial_DRAM_FB_alloc_and_add_pool(uint64_t session, uint32_t subcmd_num) +{ + int subcmd_refcnt_diff, ret = 0; + uint64_t allocated_iova; + + AMMU_LOG_VERBO("subcmd_num = %u\n", subcmd_num); + + // Count ctx number gonna alloc + mutex_lock(&g_ammu_table_set.table_lock); + if (!is_session_table_exist(session)) { + AMMU_LOG_ERR("Session table NOT exist!!!(0x%llx)\n", session); + mutex_unlock(&g_ammu_table_set.table_lock); + ret = -ENOMEM; + goto out; + } + g_ammu_stable_ptr->subcmd_num_for_DRAM_FB += subcmd_num; + AMMU_LOG_VERBO("g_ammu_stable_ptr->subcmd_num_for_DRAM_FB = %u\n", g_ammu_stable_ptr->subcmd_num_for_DRAM_FB); + mutex_unlock(&g_ammu_table_set.table_lock); + g_ammu_table_set.subcmd_refcnt += subcmd_num; + if (g_ammu_table_set.alloc_subcmd_refcnt >= g_adv->remote.dram_max) + subcmd_refcnt_diff = 0; + else { + if (g_ammu_table_set.subcmd_refcnt >= g_adv->remote.dram_max) + subcmd_refcnt_diff = + g_adv->remote.dram_max - + g_ammu_table_set.alloc_subcmd_refcnt; + else + subcmd_refcnt_diff = + g_ammu_table_set.subcmd_refcnt - + g_ammu_table_set.alloc_subcmd_refcnt; + } + + // if there is ctx number gonna alloc, alloc and send IPI + if (subcmd_refcnt_diff > 0) { + ret = DRAM_FB_alloc_with_size(subcmd_refcnt_diff, &allocated_iova); + if (ret) + goto out; + + #if DRAM_FALL_BACK_IN_RUNTIME + ret = apummu_remote_mem_add_pool( + g_adv, APUMMU_MEM_TYPE_VLM, + allocated_iova, subcmd_refcnt_diff, + g_ammu_table_set.alloc_subcmd_refcnt + ); + if (ret) { + AMMU_LOG_ERR("APUMMU add DRAM into pool fail\n"); + goto free_DRAM; + } + #endif + g_ammu_table_set.alloc_subcmd_refcnt += subcmd_refcnt_diff; + } + AMMU_LOG_VERBO("subcmd_num = %u\n", subcmd_num); + AMMU_LOG_VERBO("g_ammu_table_set.subcmd_refcnt = %u\n", g_ammu_table_set.subcmd_refcnt); + AMMU_LOG_VERBO("g_ammu_table_set.alloc_subcmd_refcnt = %u\n", g_ammu_table_set.alloc_subcmd_refcnt); + AMMU_LOG_VERBO("subcmd_refcnt_diff = %d\n", subcmd_refcnt_diff); + +out: + return ret; + +free_DRAM: + apummu_dram_remap_runtime_free_single_node(g_adv, allocated_iova); + return ret; +} + +static int general_SLB_alloc_and_add_pool(void) +{ + int ret = 0; + + apummu_general_SLB_alloc(); + ret = apummu_set_general_SLB_IPI(); + if (ret) + goto free_general_SLB; + + return ret; + +free_general_SLB: + apummu_free_general_SLB(g_adv); + return ret; +} + +int ammu_DRAM_FB_alloc(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num) +{ + int ret = 0; + + if (!g_adv->plat.alloc_DRAM_FB_in_session_create && vlm_size) { + mutex_lock(&g_ammu_table_set.DRAM_FB_lock); + // ret = DRAM_and_SLB_alloc(); + ret = partial_DRAM_FB_alloc_and_add_pool(session, subcmd_num); + general_SLB_alloc_and_add_pool(); + mutex_unlock(&g_ammu_table_set.DRAM_FB_lock); + } + + return ret; +} + + +/** + * @input: + * None + * @output: + * if stable alloc succeeded + * @description: + * bind stable to g_ammu_stable_ptr if unused table exist + */ +static int session_table_alloc(void) +{ + int ret = 0; + struct apummu_session_tbl *sTable_ptr = NULL; + + ammu_trace_begin("APUMMU: session table allocate"); + + sTable_ptr = kvzalloc(sizeof(struct apummu_session_tbl), GFP_KERNEL); + if (!sTable_ptr) { + AMMU_LOG_ERR("Session table alloc failed, kvzalloc failed\n"); + ret = -ENOMEM; + goto out; + } + + if (list_empty(&g_ammu_table_set.g_stable_head)) { + AMMU_LOG_VERBO("kref init\n"); + kref_init(&g_ammu_table_set.session_tbl_cnt); + } else { + AMMU_LOG_VERBO("kref get\n"); + kref_get(&g_ammu_table_set.session_tbl_cnt); + } + + list_add_tail(&sTable_ptr->list, &g_ammu_table_set.g_stable_head); + g_ammu_stable_ptr = sTable_ptr; + + if (g_adv->plat.alloc_DRAM_FB_in_session_create) + ret = DRAM_and_SLB_alloc(); + +out: + ammu_trace_end(); + return ret; +} + +/* device_va == iova */ +int addr_encode_and_write_stable(enum AMMU_BUF_TYPE type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva) +{ + int ret = 0; + uint64_t ret_eva = 0; + uint32_t SLB_type, cross_page_array_num = 0; + uint8_t mask_idx; + + ammu_trace_begin("APUMMU: add table"); + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + goto out; + } + + AMMU_LOG_VERBO("session = 0x%llx, device_va = 0x%llx, size = 0x%llx\n", + session, device_va, buf_size); + + if (device_va < 0x40000000) { + if (((device_va >= g_adv->remote.vlm_addr) && + (device_va <= (g_adv->remote.vlm_addr + g_adv->remote.vlm_size)))) { + ret_eva = device_va; + goto out; + } else if ((device_va >= g_adv->remote.SLB_base_addr) && + ((device_va < (g_adv->remote.SLB_base_addr + g_adv->remote.SLB_size)))) { + SLB_type = (device_va == g_adv->rsc.internal_SLB.iova) + ? APUMMU_MEM_TYPE_RSV_S + : APUMMU_MEM_TYPE_EXT; + + ret = ammu_session_table_add_SLB(session, SLB_type); + if (ret) { + AMMU_LOG_ERR("IOVA 2 EVA SLB fail!!\n"); + goto out; + } + + ret_eva = (device_va == g_adv->rsc.internal_SLB.iova) + ? g_adv->remote.vlm_addr + : device_va; + + goto out; + } else { + AMMU_LOG_ERR("Invalid input VA 0x%llx\n", device_va); + ret = -EINVAL; + goto out; + } + } + + /* addr encode and CHECK input type */ + ret = addr_encode(device_va, type, &ret_eva); + if (ret) + goto out; + + /* lock for g_ammu_stable_ptr */ + mutex_lock(&g_ammu_table_set.table_lock); + + /* check if session table exist by session */ + if (!is_session_table_exist(session)) { + /* if session table not exist alloc a session table */ + ret = session_table_alloc(); + if (ret) + goto out_after_lock; + + g_ammu_stable_ptr->session = session; + } + + /* Hint for RV APUMMU fill VSID table */ + /* NOTE: cross_page_array_num is use when the given buffer cross different page array */ + if ((device_va >> SHIFT_BITS) & 0x300000) { // mask for 34-bit + cross_page_array_num = (((device_va + buf_size) / (0x20000000)) + - ((device_va) / (0x20000000))); + do { + /* >> 29 = 512M / 0x20000000 */ + mask_idx = (((device_va - 0x100000000) >> 29) + + cross_page_array_num) & (0x1f); + + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[1] |= + (1 << mask_idx); + g_ammu_stable_ptr->DRAM_4_16G_mask_cnter[mask_idx] += 1; + + } while (cross_page_array_num--); + g_ammu_stable_ptr->stable_info.mem_mask |= (1 << DRAM_4_16G); + } else { + cross_page_array_num = + (((device_va + buf_size) / (0x8000000)) - ((device_va) / (0x8000000))); + do { + #if IOVA2EVA_ENCODE_EN + /* - (0x40000000) because mapping start from 1G */ + /* >> 27 = 128M / 0x20000000 */ + mask_idx = (((device_va - (0x40000000)) >> 27) + + cross_page_array_num) & (0x1f); + #else + mask_idx = ((device_va >> 27) + cross_page_array_num) & + (0x1f); + #endif + + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[0] |= + (1 << mask_idx); + g_ammu_stable_ptr->DRAM_1_4G_mask_cnter[mask_idx] += 1; + + } while (cross_page_array_num--); + g_ammu_stable_ptr->stable_info.mem_mask |= (1 << DRAM_1_4G); + } + + count_page_array_en_num(); + +out_after_lock: + mutex_unlock(&g_ammu_table_set.table_lock); +out: + *eva = ret_eva; + + AMMU_LOG_VERBO("apummu add 0x%llx -> 0x%llx in 0x%llx stable done\n", + ret_eva, device_va, session); + + ammu_trace_end(); + return ret; +} + +/* get session table by session */ +int get_session_table(uint64_t session, void **tbl_kva, uint32_t *size) +{ + int ret = 0; + + ammu_trace_begin("APUMMU: Get session table"); + mutex_lock(&g_ammu_table_set.table_lock); + + if (!is_session_table_exist(session)) { + AMMU_LOG_ERR("Session table NOT exist!!!(0x%llx)\n", session); + ret = -ENOMEM; + goto out; + } + + AMMU_LOG_VERBO("stable session(%llx), mem_mask = 0x%08x\n", + g_ammu_stable_ptr->session, + g_ammu_stable_ptr->stable_info.mem_mask); + AMMU_LOG_VERBO("stable DRAM_page_array_mask 1~4G = 0x%08x, enable num = 0x%08x\n", + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[0], + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[0]); + AMMU_LOG_VERBO("stable DRAM_page_array_mask 4~16G = 0x%08x, enable num = 0x%08x\n", + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[1], + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[1]); + AMMU_LOG_VERBO("stable EXT_SLB_addr = 0x%08x, RSV_S (start, page) = (%u, %u)\n", + g_ammu_stable_ptr->stable_info.EXT_SLB_addr, + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page_array_start, + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page); + + *tbl_kva = (void *) (&g_ammu_stable_ptr->stable_info); + *size = sizeof(struct ammu_stable_info); + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + ammu_trace_end(); + return ret; +} + +/* free session table by session */ +int session_table_free(uint64_t session) +{ + int ret = 0; + + ammu_trace_begin("APUMMU: free session table"); + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + goto out; + } + + mutex_lock(&g_ammu_table_set.table_lock); + if (!is_session_table_exist(session)) { + ret = -EFAULT; + AMMU_LOG_ERR("free session table FAILED!!!, session table 0x%llx not found\n", + session); + goto out; + } + + if (!g_adv->plat.alloc_DRAM_FB_in_session_create) { + g_ammu_table_set.subcmd_refcnt -= g_ammu_stable_ptr->subcmd_num_for_DRAM_FB; + AMMU_LOG_VERBO("--- g_ammu_table_set.subcmd_refcnt = %u\n", g_ammu_table_set.subcmd_refcnt); + } + + list_del(&g_ammu_stable_ptr->list); + kvfree(g_ammu_stable_ptr); + AMMU_LOG_VERBO("kref put\n"); + kref_put(&g_ammu_table_set.session_tbl_cnt, free_memory); + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + ammu_trace_end(); + return ret; +} + +void dump_session_table_set(void) +{ + struct list_head *list_ptr; + uint32_t i = 0; + + mutex_lock(&g_ammu_table_set.table_lock); + + AMMU_LOG_DBG("== APUMMU dump session table Start ==\n"); + AMMU_LOG_DBG("Total stable cnt = %u\n", kref_read(&g_ammu_table_set.session_tbl_cnt)); + AMMU_LOG_DBG("----------------------------------\n"); + + list_for_each(list_ptr, &g_ammu_table_set.g_stable_head) { + g_ammu_stable_ptr = list_entry(list_ptr, struct apummu_session_tbl, list); + AMMU_LOG_DBG("== dump session table %u info ==\n", i++); + AMMU_LOG_DBG("session = 0x%llx\n", + g_ammu_stable_ptr->session); + AMMU_LOG_DBG("mem_mask = 0x%x\n", + g_ammu_stable_ptr->stable_info.mem_mask); + AMMU_LOG_DBG("DRAM_page_array_mask = 0x%x 0x%x\n", + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[0], + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[1]); + AMMU_LOG_DBG("DRAM_page_array_en_num = %u, %u\n", + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[0], + g_ammu_stable_ptr->stable_info.DRAM_page_array_en_num[1]); + AMMU_LOG_DBG("EXT_SLB_addr = 0x%x, RSV_S_SLB PA start = %u, page = %u\n", + g_ammu_stable_ptr->stable_info.EXT_SLB_addr, + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page_array_start, + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page); + } + + mutex_unlock(&g_ammu_table_set.table_lock); + AMMU_LOG_DBG("== APUMMU dump session table End ==\n"); +} + +int ammu_session_table_add_SLB(uint64_t session, uint32_t type) +{ + int ret = 0; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + goto out; + } + + mutex_lock(&g_ammu_table_set.table_lock); + if (!is_session_table_exist(session)) { + ret = -EINVAL; + AMMU_LOG_ERR("Add SLB to stable FAILED!!!, session table 0x%llx not found\n", + session); + goto out; + } + + if (type == APUMMU_MEM_TYPE_EXT) { + if (!g_adv->plat.external_SLB_cnt) { + ret = -ENOMEM; + AMMU_LOG_ERR("External SLB is not alloced\n"); + goto out; + } + + g_ammu_stable_ptr->stable_info.EXT_SLB_addr = g_adv->rsc.external_SLB.iova; + g_ammu_stable_ptr->stable_info.mem_mask |= (1 << SLB_EXT); + } else if (type == APUMMU_MEM_TYPE_RSV_S) { + if (!g_adv->plat.internal_SLB_cnt) { + ret = -ENOMEM; + AMMU_LOG_ERR("Internal SLB is not alloced\n"); + goto out; + } + + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page_array_start = + (g_adv->rsc.internal_SLB.iova - g_adv->remote.SLB_base_addr) >> 19; + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page = + g_adv->rsc.internal_SLB.size >> 19; // / 512K + g_ammu_stable_ptr->stable_info.mem_mask |= (1 << SLB_RSV_S); + } else { + AMMU_LOG_ERR("Invalid apu memory type\n"); + ret = -EINVAL; + goto out; + } + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + return ret; +} + +static int ammu_remove_stable_SLB_status(uint32_t type) +{ + int ret = 0; + + if (type == APUMMU_MEM_TYPE_EXT) { + g_ammu_stable_ptr->stable_info.EXT_SLB_addr = 0; + g_ammu_stable_ptr->stable_info.mem_mask &= ~(1 << SLB_EXT); + } else if (type == APUMMU_MEM_TYPE_RSV_S) { + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page_array_start = 0; + g_ammu_stable_ptr->stable_info.RSV_S_SLB_page = 0; + g_ammu_stable_ptr->stable_info.mem_mask &= ~(1 << SLB_RSV_S); + } else { + AMMU_LOG_ERR("Invalid apu memory type %u\n", type); + ret = -EINVAL; + goto out; + } + +out: + return ret; +} + + +int apummu_stable_buffer_remove(uint64_t session, uint64_t device_va, uint32_t buf_size) +{ + int ret = 0; + uint32_t SLB_type, cross_page_array_num = 0; + uint8_t mask_idx; + bool is_34bit; + + if (device_va < 0x40000000) { + if (((device_va >= g_adv->remote.vlm_addr) && + (device_va <= (g_adv->remote.vlm_addr + g_adv->remote.vlm_size)))) + goto out; + else if ((device_va >= g_adv->remote.SLB_base_addr) && + ((device_va < (g_adv->remote.SLB_base_addr + g_adv->remote.SLB_size)))) { + SLB_type = (device_va == g_adv->rsc.internal_SLB.iova) + ? APUMMU_MEM_TYPE_RSV_S + : APUMMU_MEM_TYPE_EXT; + + ret = ammu_session_table_remove_SLB(session, SLB_type); + if (ret) { + AMMU_LOG_ERR("Remove SLB buffer fail!!\n"); + goto out; + } + + goto out; + } else { + AMMU_LOG_ERR("Invalid input VA 0x%llx\n", device_va); + ret = -EINVAL; + goto out; + } + } + + mutex_lock(&g_ammu_table_set.table_lock); + + if (!is_session_table_exist(session)) { + AMMU_LOG_ERR("Session table NOT exist!!!(0x%llx)\n", session); + ret = -ENOMEM; + goto out; + } + + is_34bit = device_va & (0x300000000); + + if (is_34bit) { + cross_page_array_num = (((device_va + buf_size) / (0x20000000)) + - ((device_va) / (0x20000000))); + do { + /* >> 29 = 512M / 0x20000000 */ + mask_idx = ((device_va >> 29) + cross_page_array_num) & + (0x1f); + + g_ammu_stable_ptr->DRAM_4_16G_mask_cnter[mask_idx] -= 1; + if (g_ammu_stable_ptr->DRAM_4_16G_mask_cnter[mask_idx] == 0) { + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[1] &= + ~(1 << mask_idx); + } + } while (cross_page_array_num--); + + if (g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[1] == 0) + g_ammu_stable_ptr->stable_info.mem_mask &= ~(1 << DRAM_4_16G); + } else { + cross_page_array_num = + (((device_va + buf_size) / (0x8000000)) - ((device_va) / (0x8000000))); + do { + #if IOVA2EVA_ENCODE_EN + /* - (0x40000000) because mapping start from 1G */ + /* >> 27 = 128M / 0x20000000 */ + mask_idx = (((device_va - (0x40000000)) >> 27) + + cross_page_array_num) & (0x1f); + #else + mask_idx = ((device_va >> 27) + cross_page_array_num) & + (0x1f); + #endif + + g_ammu_stable_ptr->DRAM_1_4G_mask_cnter[mask_idx] -= 1; + if (g_ammu_stable_ptr->DRAM_1_4G_mask_cnter[mask_idx] == 0) { + g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[0] &= + ~(1 << mask_idx); + } + } while (cross_page_array_num--); + + if (g_ammu_stable_ptr->stable_info.DRAM_page_array_mask[0] == 0) + g_ammu_stable_ptr->stable_info.mem_mask &= ~(1 << DRAM_1_4G); + } + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + return ret; +} + +int ammu_session_table_remove_SLB(uint64_t session, uint32_t type) +{ + int ret = 0; + + if (g_adv == NULL) { + AMMU_LOG_ERR("Invalid apummu_device\n"); + ret = -EINVAL; + goto out; + } + + mutex_lock(&g_ammu_table_set.table_lock); + if (!is_session_table_exist(session)) { + ret = -EINVAL; + AMMU_LOG_ERR("Remove SLB to stable FAILED!!!, session table 0x%llx not found\n", + session); + goto out; + } + + ret = ammu_remove_stable_SLB_status(type); + +out: + mutex_unlock(&g_ammu_table_set.table_lock); + return ret; +} + +void ammu_session_table_check_SLB(uint32_t type) +{ + int ret = 0; + struct list_head *list_ptr; + + mutex_lock(&g_ammu_table_set.table_lock); + list_for_each(list_ptr, &g_ammu_table_set.g_stable_head) { + g_ammu_stable_ptr = list_entry(list_ptr, struct apummu_session_tbl, list); + + if (type == APUMMU_MEM_TYPE_EXT) { + if (g_ammu_stable_ptr->stable_info.EXT_SLB_addr != 0) { + // AMMU_LOG_WRN("0x%llx is still using EXT_SLB after free\n", + // g_ammu_stable_ptr->session); + + ret = ammu_remove_stable_SLB_status(APUMMU_MEM_TYPE_EXT); + if (ret) + AMMU_LOG_ERR("ammu_remove_stable_SLB_status fail\n"); + } + } else if (type == APUMMU_MEM_TYPE_RSV_S) { + if (g_ammu_stable_ptr->stable_info.RSV_S_SLB_page_array_start != 0) { + // AMMU_LOG_WRN("0x%llx is still using RSV_S_SLB after free\n", + // g_ammu_stable_ptr->session); + + ret = ammu_remove_stable_SLB_status(APUMMU_MEM_TYPE_RSV_S); + if (ret) + AMMU_LOG_ERR("ammu_remove_stable_SLB_status fail\n"); + } + } + } + + mutex_unlock(&g_ammu_table_set.table_lock); +} + +/* Init lust head, lock */ +void apummu_mgt_init(void) +{ + g_ammu_table_set.is_VLM_info_IPI_sent = false; + g_ammu_table_set.is_SLB_set = false; + g_ammu_table_set.is_work_canceled = true; + g_ammu_table_set.is_SLB_alloc = false; + INIT_LIST_HEAD(&g_ammu_table_set.g_stable_head); + mutex_init(&g_ammu_table_set.table_lock); + mutex_init(&g_ammu_table_set.DRAM_FB_lock); + + INIT_DELAYED_WORK(&DRAM_free_work, ammu_DRAM_free_work); + ammu_workq = alloc_ordered_workqueue("ammu_dram_free", WQ_MEM_RECLAIM); +} + +/* apummu_mgt_destroy session table set */ +void apummu_mgt_destroy(void) +{ + struct list_head *list_ptr1, *list_ptr2; + + mutex_lock(&g_ammu_table_set.table_lock); + list_for_each_safe(list_ptr1, list_ptr2, &g_ammu_table_set.g_stable_head) { + g_ammu_stable_ptr = list_entry(list_ptr1, struct apummu_session_tbl, list); + list_del(&g_ammu_stable_ptr->list); + kvfree(g_ammu_stable_ptr); + g_ammu_stable_ptr = NULL; + AMMU_LOG_VERBO("kref put\n"); + kref_put(&g_ammu_table_set.session_tbl_cnt, free_memory); + } + + mutex_unlock(&g_ammu_table_set.table_lock); + + /* Flush free DRAM job */ + flush_delayed_work(&DRAM_free_work); +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.h new file mode 100644 index 0000000000000..ce14a2880aea9 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_mgt.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __APUMMU_TABLE_H__ +#define __APUMMU_TABLE_H__ + +#define APUMMU_MAX_BUF_CNT (16) +/* midware has max 64 SCs */ +#define APUMMU_MAX_SC_CNT (64) + +#define APUMMU_MAX_TBL_ENTRY (APUMMU_MAX_SC_CNT*APUMMU_MAX_BUF_CNT) + +enum mem_mask_idx { + DRAM_1_4G, + DRAM_4_16G, + SLB_EXT, + SLB_RSV_S, +}; + +/* NOTE: DATA_BUF, CMD_BUF aligned MDW */ +enum AMMU_BUF_TYPE { + AMMU_DATA_BUF, // (non 1-1 mapping) + AMMU_CMD_BUF, // (1-1 mapping) + AMMU_VLM_BUF, // (1-1 mapping) +}; + +struct ammu_stable_info { + uint32_t EXT_SLB_addr; // SLB addr for EXT + + /* + * Issue: there's only 5 page arrays, so we cannot use 4 page arrays for 0-16G + * 1 segment for 4-16G with page array size is 512M (24 fields) + * 1~4 4~16G + */ + uint32_t DRAM_page_array_mask[2]; // 1 for 0~4G, 1 for 4~16G + uint8_t DRAM_page_array_en_num[2]; // 0-1, for page_idx_mask[x] enable + uint8_t mem_mask; // bit meaning plz refer to mem_mask_idx + + /* NOTE: No EXT_SLB_size since size is not important */ + uint8_t RSV_S_SLB_page_array_start; // SLB PA for RSV_S + uint8_t RSV_S_SLB_page; // SLB size for RSV_S, shift by 512M +}; + +/* apummu iova-eva mapping table */ +struct apummu_session_tbl { + /* stuff pass to RV */ + struct ammu_stable_info stable_info; + uint64_t session; + + uint32_t DRAM_1_4G_mask_cnter[32]; + uint32_t DRAM_4_16G_mask_cnter[32]; + uint32_t subcmd_num_for_DRAM_FB; + + struct list_head list; +}; + +struct apummu_tbl { + struct list_head g_stable_head; + struct kref session_tbl_cnt; + struct mutex table_lock; + struct mutex DRAM_FB_lock; + uint16_t subcmd_refcnt; + uint8_t alloc_subcmd_refcnt; + bool is_VLM_info_IPI_sent; // to set VLM DRAM FB or clean setting + bool is_SLB_set; + bool is_work_canceled; + bool is_free_job_set; + bool is_SLB_alloc; // Since SLB state might not sync with APU +}; + +int ammu_DRAM_FB_alloc(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num); +int addr_encode_and_write_stable(enum AMMU_BUF_TYPE type, uint64_t session, + uint64_t iova, uint64_t buf_size, uint64_t *eva); +int apummu_eva_decode(uint64_t eva, uint64_t *iova, enum AMMU_BUF_TYPE type); +int apummu_stable_buffer_remove(uint64_t session, uint64_t device_va, + uint32_t buf_size); +int get_session_table(uint64_t session, void **tbl_kva, uint32_t *size); +int session_table_free(uint64_t session); +void dump_session_table_set(void); +void apummu_mgt_init(void); +void apummu_mgt_destroy(void); + +int ammu_session_table_add_SLB(uint64_t session, uint32_t type); +int ammu_session_table_remove_SLB(uint64_t session, uint32_t type); +void ammu_session_table_check_SLB(uint32_t type); + +#endif //Endof __APUMMU_TABLE_H__ diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_msg.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_msg.h new file mode 100644 index 0000000000000..df911112a8fd0 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_msg.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_MSG_H__ +#define __APUSYS_APUMMU_MSG_H__ + +enum APUMMU_MSG_OPTION_TYPE { + APUMMU_OPTION_GET, + APUMMU_OPTION_SET, + APUMMU_OPTION_MAX, +}; + +enum APUMMU_MSG_CMD_TYPE { + APUMMU_CMD_HANDSHAKE = 0x0, + APUMMU_CMD_SYSTEM_RAM, + APUMMU_CMD_HW_DEFAULT_IOVA, + APUMMU_CMD_HW_DEFAULT_IOVA_ONE_SHOT, + APUMMU_CMD_MEM_OP, + APUMMU_CMD_DBG_OP = 0x80, + APUMMU_CMD_MAX, +}; + +enum APUMMU_MSG_MEM_TYPE { + APUMMU_MEM_NONE, + APUMMU_MEM_ALLOC, + APUMMU_MEM_FREE, + APUMMU_MEM_IMPORT, + APUMMU_MEM_UNIMPORT, + APUMMU_MEM_MAP, + APUMMU_MEM_UNMAP, + APUMMU_MEM_INFO, + APUMMU_MEM_ADD_POOL, + APUMMU_MEM_FREE_POOL, + APUMMU_MEM_MAX, +}; + +struct apummu_msg { + uint32_t cmd; + uint32_t option; + uint32_t ack; + uint32_t sn; + uint32_t data[12]; +} __packed; + + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.c new file mode 100644 index 0000000000000..bbf8a11089dfa --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "apummu_cmn.h" +#include "apummu_drv.h" +#include "apummu_remote.h" +#include "apummu_msg.h" + +struct apummu_msg_item { + struct apummu_msg msg; + struct list_head list; +}; + +struct apummu_msg *g_ammu_reply; +struct apummu_msg_mgr *g_ammu_msg; + +static struct apummu_msg g_apummu_msg_reply; +static struct apummu_msg_mgr g_msg_mgr; + +bool apummu_is_remote(void) +{ + bool is_remote = false; + + mutex_lock(&g_ammu_msg->lock.mutex_mgr); + if (g_ammu_msg->info.init) + is_remote = true; + + mutex_unlock(&g_ammu_msg->lock.mutex_mgr); + + return is_remote; +} + +void apummu_remote_init(void) +{ + mutex_init(&g_msg_mgr.lock.mutex_cmd); + mutex_init(&g_msg_mgr.lock.mutex_ipi); + mutex_init(&g_msg_mgr.lock.mutex_mgr); + + spin_lock_init(&g_msg_mgr.lock.lock_rx); + init_waitqueue_head(&g_msg_mgr.lock.wait_rx); + + INIT_LIST_HEAD(&g_msg_mgr.list_rx); + + g_ammu_reply = &g_apummu_msg_reply; + g_ammu_reply->sn = 0; + g_msg_mgr.count = 0; + g_ammu_msg = &g_msg_mgr; + g_msg_mgr.info.init = true; +} + +void apummu_remote_exit(void) +{ + g_msg_mgr.info.init = false; + g_ammu_reply->sn = 0; +} + +int apummu_remote_send_cmd_sync(void *drvinfo, void *request, void *reply, uint32_t timeout) +{ + struct apummu_dev_info *rdv = NULL; + int ret = 0; + unsigned long flags; + struct apummu_msg_item *item; + struct list_head *tmp = NULL, *pos = NULL; + struct apummu_msg *rmesg, *snd_rmesg; + struct timespec64 begin, end, delta; + int retry = 0; + bool find = false; + uint32_t *ptr; + uint32_t cnt = 100, i = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + rdv = (struct apummu_dev_info *)drvinfo; + + snd_rmesg = (struct apummu_msg *) request; + mutex_lock(&g_ammu_msg->lock.mutex_cmd); + mutex_lock(&g_ammu_msg->lock.mutex_ipi); + + snd_rmesg->sn = g_ammu_msg->send_sn; + g_ammu_msg->send_sn++; + + ptr = (uint32_t *)request; + AMMU_LOG_VERBO("Send [%x][%x][%x][%x][%x][%x][%x][%x]\n", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + + /* send & retry */ + for (i = 0; i < cnt; i++) { + ret = rpmsg_send(rdv->rpdev->ept, request, sizeof(struct apummu_msg)); + /* send busy, retry */ + if (ret == -EBUSY || ret == -EAGAIN) { + if (!(i % 10)) + AMMU_LOG_INFO("re-send ipi(%u/%u)\n", i, cnt); + if (ret == -EAGAIN && i < 10) + usleep_range(200, 500); + else if (ret == -EAGAIN && i < 50) + usleep_range(1000, 2000); + else if (ret == -EAGAIN && i < 200) + usleep_range(10000, 20000); + continue; + } + break; + } + + mutex_unlock(&g_ammu_msg->lock.mutex_ipi); + + if (ret) + AMMU_LOG_ERR("Send apummu IPI Fail %d\n", ret); + + ktime_get_ts64(&begin); + do { + ret = wait_event_interruptible_timeout( + g_ammu_msg->lock.wait_rx, + g_ammu_msg->count, + msecs_to_jiffies(APUMMU_REMOTE_TIMEOUT)); + if (!ret) { + AMMU_LOG_ERR("wait ACK timeout!!\n"); + ret = -ETIME; + goto out; + } else if (ret != -ERESTARTSYS) { + break; + } + + ktime_get_ts64(&end); + delta = timespec64_sub(end, begin); + if (delta.tv_sec > (APUMMU_REMOTE_TIMEOUT/1000)) { + AMMU_LOG_ERR("wait ACK timeout manually!!\n"); + ret = -ETIME; + goto out; + } + + retry += 1; + if (retry % 100 == 0) + AMMU_LOG_WRN("Wake up by signal!, still waiting for ACK %d\n", retry); + msleep(20); + } while (ret == -ERESTARTSYS); + + spin_lock_irqsave(&g_ammu_msg->lock.lock_rx, flags); + + list_for_each_safe(pos, tmp, &g_ammu_msg->list_rx) { + item = list_entry(pos, struct apummu_msg_item, list); + list_del(pos); + g_ammu_msg->count--; + rmesg = (struct apummu_msg *) &item->msg; + + memcpy(reply, rmesg, sizeof(struct apummu_msg)); + find = true; + break; + } + + spin_unlock_irqrestore(&g_ammu_msg->lock.lock_rx, flags); + + if (find) + vfree(item); + + ret = 0; +out: + mutex_unlock(&g_ammu_msg->lock.mutex_cmd); + return ret; +} + + +int apummu_remote_rx_cb(void *drvinfo, void *data, int len) +{ + unsigned long flags; + struct apummu_dev_info *rdv = NULL; + struct apummu_msg_item *item; + uint32_t *ptr; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + rdv = (struct apummu_dev_info *)drvinfo; + + if (len != sizeof(struct apummu_msg)) { + AMMU_LOG_ERR("invalid len %d / %zu\n", len, sizeof(struct apummu_msg)); + return -EINVAL; + } + + item = vzalloc(sizeof(*item)); + + memcpy(&item->msg, data, len); + + ptr = (uint32_t *)data; + AMMU_LOG_VERBO("Rcv [%x][%x][%x][%x][%x][%x][%x][%x]\n", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + + spin_lock_irqsave(&g_ammu_msg->lock.lock_rx, flags); + list_add_tail(&item->list, &g_ammu_msg->list_rx); + g_ammu_msg->count++; + spin_unlock_irqrestore(&g_ammu_msg->lock.lock_rx, flags); + + wake_up_interruptible(&g_ammu_msg->lock.wait_rx); + + return 0; +} + +int apummu_remote_sync_sn(void *drvinfo, uint32_t sn) +{ + mutex_lock(&g_ammu_msg->lock.mutex_mgr); + + g_ammu_msg->send_sn = sn; + + mutex_unlock(&g_ammu_msg->lock.mutex_mgr); + + return 0; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.h new file mode 100644 index 0000000000000..cabab35035011 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_REMOTE_H__ +#define __APUSYS_APUMMU_REMOTE_H__ + +#define APUMMU_REMOTE_TIMEOUT (40000) // RV ipi_send timeout after 30 sec + +struct apummu_remote_info { + bool init; +}; +struct apummu_remote_lock { + struct mutex mutex_cmd; + struct mutex mutex_ipi; + struct mutex mutex_mgr; + spinlock_t lock_rx; + wait_queue_head_t wait_rx; +}; + +struct apummu_msg_mgr { + struct apummu_remote_lock lock; + struct apummu_remote_info info; + struct list_head list_rx; + uint32_t count; + uint32_t send_sn; +}; + +bool apummu_is_remote(void); +void apummu_remote_init(void); +void apummu_remote_exit(void); +int apummu_remote_send_cmd_sync(void *drvinfo, void *request, void *reply, uint32_t timeout); +int apummu_remote_rx_cb(void *drvinfo, void *data, int len); +int apummu_remote_sync_sn(void *drvinfo, uint32_t sn); + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.c new file mode 100644 index 0000000000000..d68152c6ea28d --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.c @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include + +#include "apummu_cmn.h" +#include "apummu_drv.h" +#include "apummu_remote.h" +#include "linux/soc/mediatek/apummu_mem_def.h" +#include "apummu_msg.h" +#include "apummu_remote_cmd.h" + + +int apummu_remote_check_reply(void *reply) +{ + struct apummu_msg *msg; + + if (reply == NULL) { + AMMU_LOG_ERR("Reply Null\n"); + return -EINVAL; + } + + msg = (struct apummu_msg *)reply; + if (msg->ack != 0) { + AMMU_LOG_ERR("Reply Ack Error %x\n", msg->ack); + return -EINVAL; + } + + return 0; +} + +int apummu_remote_set_op(void *drvinfo, uint32_t *argv, uint32_t argc) +{ + struct apummu_msg req, reply; + uint32_t i = 0; + int ret = 0; + uint32_t max_data = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + max_data = ARRAY_SIZE(req.data); + if (argc > max_data) { + AMMU_LOG_ERR("invalid argc %d / %d\n", argc, max_data); + return -EINVAL; + } + + req.cmd = APUMMU_CMD_DBG_OP; + req.option = APUMMU_OPTION_SET; + + for (i = 0; i < argc; i++) + req.data[i] = argv[i]; + + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } + +out: + return ret; +} + +int apummu_remote_send_stable(void *drvinfo, uint64_t session, uint32_t ammu_stable_addr, + uint32_t SRAM_req_size, uint32_t table_size) +{ + struct apummu_msg req, reply; + uint32_t op; + int ret = 0, widx = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + req.cmd = APUMMU_CMD_DBG_OP; + req.option = APUMMU_OPTION_SET; + + op = 1; + + AMMU_RPMSG_write(&op, req.data, sizeof(op), widx); + AMMU_RPMSG_write(&session, req.data, sizeof(session), widx); + AMMU_RPMSG_write(&ammu_stable_addr, req.data, sizeof(ammu_stable_addr), widx); + AMMU_RPMSG_write(&SRAM_req_size, req.data, sizeof(SRAM_req_size), widx); + AMMU_RPMSG_write(&table_size, req.data, sizeof(table_size), widx); + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } + +out: + return ret; +} + +int apummu_remote_handshake(void *drvinfo, void *remote) +{ + struct apummu_dev_info *adv = NULL; + struct apummu_msg req, reply; + int ridx = 0; + int ret = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + if (!apummu_is_remote()) { + AMMU_LOG_ERR("Remote Not Init\n"); + return -EINVAL; + } + + adv = (struct apummu_dev_info *)drvinfo; + + memset(&req, 0, sizeof(struct apummu_msg)); + memset(&reply, 0, sizeof(struct apummu_msg)); + + + req.cmd = APUMMU_CMD_HANDSHAKE; + req.option = APUMMU_OPTION_GET; + + AMMU_LOG_INFO("Remote Handshake...\n"); + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Remote Handshake Fail %d\n", ret); + goto out; + } + + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } + + /* Init Remote Info */ + AMMU_RPMSG_RAED(&adv->remote.dram_max, reply.data, sizeof(adv->remote.dram_max), ridx); + AMMU_RPMSG_RAED(&adv->remote.vlm_addr, reply.data, sizeof(adv->remote.vlm_addr), ridx); + AMMU_RPMSG_RAED(&adv->remote.vlm_size, reply.data, sizeof(adv->remote.vlm_size), ridx); + AMMU_RPMSG_RAED(&adv->remote.SLB_base_addr, reply.data, + sizeof(adv->remote.SLB_base_addr), ridx); + AMMU_RPMSG_RAED(&adv->remote.SLB_EXT_addr, reply.data, + sizeof(adv->remote.SLB_EXT_addr), ridx); + AMMU_RPMSG_RAED(&adv->remote.SLB_size, reply.data, + sizeof(adv->remote.SLB_size), ridx); + + adv->remote.TCM_base_addr = adv->remote.vlm_addr; + adv->remote.general_SRAM_size = adv->remote.vlm_size; + + apummu_remote_sync_sn(drvinfo, reply.sn); +out: + return ret; +} + +int apummu_remote_set_hw_default_iova(void *drvinfo, uint32_t ctx, uint64_t iova) +{ + struct apummu_msg req, reply; + int ret = 0; + int widx = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + if (!apummu_is_remote()) { + AMMU_LOG_ERR("Remote Not Init\n"); + return -EINVAL; + } + + memset(&req, 0, sizeof(struct apummu_msg)); + memset(&reply, 0, sizeof(struct apummu_msg)); + + req.cmd = APUMMU_CMD_HW_DEFAULT_IOVA; + req.option = APUMMU_OPTION_SET; + + AMMU_RPMSG_write(&ctx, req.data, sizeof(ctx), widx); + AMMU_RPMSG_write(&iova, req.data, sizeof(iova), widx); + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } +out: + return ret; +} + +int apummu_remote_set_hw_default_iova_one_shot(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + struct apummu_msg req, reply; + int ret = 0; + int widx = 0; + uint32_t type, in_addr = 0, size = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + if (!apummu_is_remote()) { + AMMU_LOG_ERR("Remote Not Init\n"); + return -EINVAL; + } + + adv = (struct apummu_dev_info *)drvinfo; + + memset(&req, 0, sizeof(struct apummu_msg)); + memset(&reply, 0, sizeof(struct apummu_msg)); + + req.cmd = APUMMU_CMD_HW_DEFAULT_IOVA_ONE_SHOT; + req.option = APUMMU_OPTION_SET; + + type = APUMMU_MEM_TYPE_GENERAL_S; + if (adv->rsc.genernal_SLB.iova != 0) { // if SLB allocated + in_addr = (uint32_t) adv->rsc.genernal_SLB.iova; + size = adv->rsc.genernal_SLB.size; + } + + AMMU_RPMSG_write(&adv->rsc.vlm_dram.iova, req.data, + sizeof(adv->rsc.vlm_dram.iova), widx); + AMMU_RPMSG_write(&type, req.data, sizeof(type), widx); + AMMU_RPMSG_write(&in_addr, req.data, sizeof(in_addr), widx); + AMMU_RPMSG_write(&size, req.data, sizeof(size), widx); + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } +out: + return ret; +} + +int apummu_remote_mem_add_pool(void *drvinfo, uint32_t type, + uint64_t in_addr, uint32_t size, uint32_t start_idx) +{ + struct apummu_msg req, reply; + int ret = 0, widx = 0; + uint32_t mem_op = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + if (!apummu_is_remote()) { + AMMU_LOG_ERR("Remote Not Init\n"); + return -EINVAL; + } + + memset(&req, 0, sizeof(struct apummu_msg)); + memset(&reply, 0, sizeof(struct apummu_msg)); + + req.cmd = APUMMU_CMD_SYSTEM_RAM; + req.option = APUMMU_OPTION_SET; + + mem_op = APUMMU_MEM_ADD_POOL; + + AMMU_RPMSG_write(&mem_op, req.data, sizeof(mem_op), widx); + AMMU_RPMSG_write(&type, req.data, sizeof(type), widx); + AMMU_RPMSG_write(&in_addr, req.data, sizeof(in_addr), widx); + AMMU_RPMSG_write(&size, req.data, sizeof(size), widx); + AMMU_RPMSG_write(&start_idx, req.data, sizeof(start_idx), widx); + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } + +out: + return ret; +} + +int apummu_remote_mem_free_pool(void *drvinfo) +{ + struct apummu_dev_info *adv = NULL; + struct apummu_msg req, reply; + int ret = 0, widx = 0; + uint32_t mem_op = 0, in_addr = 0, size = 0, type = 0; + + if (drvinfo == NULL) { + AMMU_LOG_ERR("invalid argument\n"); + return -EINVAL; + } + + if (!apummu_is_remote()) { + AMMU_LOG_ERR("Remote Not Init\n"); + return -EINVAL; + } + + adv = (struct apummu_dev_info *)drvinfo; + + memset(&req, 0, sizeof(struct apummu_msg)); + memset(&reply, 0, sizeof(struct apummu_msg)); + + req.cmd = APUMMU_CMD_SYSTEM_RAM; + req.option = APUMMU_OPTION_SET; + + mem_op = APUMMU_MEM_FREE_POOL; + + type = APUMMU_MEM_TYPE_GENERAL_S; + in_addr = (uint32_t) adv->rsc.genernal_SLB.iova; + size = adv->rsc.genernal_SLB.size; + + AMMU_RPMSG_write(&mem_op, req.data, sizeof(mem_op), widx); + AMMU_RPMSG_write(&type, req.data, sizeof(type), widx); + AMMU_RPMSG_write(&in_addr, req.data, sizeof(in_addr), widx); + AMMU_RPMSG_write(&size, req.data, sizeof(size), widx); + + ret = apummu_remote_send_cmd_sync(drvinfo, (void *) &req, (void *) &reply, 0); + if (ret) { + AMMU_LOG_ERR("Send Msg Fail %d\n", ret); + goto out; + } + ret = apummu_remote_check_reply((void *) &reply); + if (ret) { + AMMU_LOG_ERR("Check Msg Fail %d\n", ret); + goto out; + } + +out: + return ret; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.h new file mode 100644 index 0000000000000..7ef9628ff7c14 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_remote_cmd.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_REMOTE_CMD_H__ +#define __APUSYS_APUMMU_REMOTE_CMD_H__ + +#define AMMU_RPMSG_RAED(var, data, size, idx) do {\ + memcpy(var, data + idx, size); \ + idx = idx + size/sizeof(uint32_t); \ + } while (0) + +#define AMMU_RPMSG_write(var, data, size, idx) do {\ + memcpy(data + idx, var, size); \ + idx = idx + size/sizeof(uint32_t); \ + } while (0) + + +extern struct apummu_msg *g_reply; +extern struct apummu_msg_mgr *g_ammu_msg; + +int apummu_remote_check_reply(void *reply); + + +int apummu_remote_set_op(void *drvinfo, uint32_t *argv, uint32_t argc); + +int apummu_remote_handshake(void *drvinfo, void *remote); +int apummu_remote_set_hw_default_iova(void *drvinfo, uint32_t ctx, uint64_t iova); +int apummu_remote_set_hw_default_iova_one_shot(void *drvinfo); + +/* General SLB add/remove pool APIs */ +int apummu_remote_mem_add_pool(void *drvinfo, uint32_t type, + uint64_t in_addr, uint32_t size, uint32_t start_idx); +int apummu_remote_mem_free_pool(void *drvinfo); + +int apummu_remote_send_stable(void *drvinfo, uint64_t session, uint32_t ammu_stable_addr, + uint32_t SRAM_req_size, uint32_t table_size); + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_trace.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_trace.h new file mode 100644 index 0000000000000..c89caa548b808 --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/common/apummu_trace.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include + +#define ammu_trace_begin(...) +#define ammu_trace_end(...) diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.c new file mode 100644 index 0000000000000..89fadee483d5c --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include + +#include "../common/apummu_cmn.h" +#include "apummu_plat.h" +#include "apummu_device.h" + +static struct apummu_plat mt8196_drv = { + .slb_wait_time = 0, + .is_general_SLB_support = true, + .alloc_DRAM_FB_in_session_create = false, +}; + +static const struct of_device_id apummu_of_match[] = { + { .compatible = "mediatek,rv-apummu-mt8196", .data = &mt8196_drv }, + { /* end of list */ }, +}; + +const struct of_device_id *apummu_get_of_device_id(void) +{ + return apummu_of_match; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.h new file mode 100644 index 0000000000000..5740e61470e7f --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_device.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_DEVICE_H__ +#define __APUSYS_APUMMU_DEVICE_H__ + +const struct of_device_id *apummu_get_of_device_id(void); + +#endif diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.c b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.c new file mode 100644 index 0000000000000..ad926b280d83a --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include + +#include "../common/apummu_cmn.h" +#include "apummu_plat.h" +#include "../common/apummu_drv.h" + +int apummu_plat_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct apummu_plat *aplat; + struct apummu_dev_info *adv = platform_get_drvdata(pdev); + int ret = 0; + + if (!adv) { + AMMU_LOG_ERR("No apummu_dev_info!\n"); + ret = -EINVAL; + goto out; + } + + aplat = (struct apummu_plat *) of_device_get_match_data(dev); + if (!aplat) { + AMMU_LOG_ERR("No apummu_plat!\n"); + ret = -EINVAL; + goto out; + } + + /* get platform data */ + AMMU_LOG_INFO("slb_wait_time: %d\n", aplat->slb_wait_time); + AMMU_LOG_INFO("is_general_SLB_support: %d\n", aplat->is_general_SLB_support); + + adv->plat.slb_wait_time = aplat->slb_wait_time; + adv->plat.is_general_SLB_support = aplat->is_general_SLB_support; + adv->plat.alloc_DRAM_FB_in_session_create = aplat->alloc_DRAM_FB_in_session_create; + mutex_init(&adv->plat.slb_mtx); + +out: + return ret; +} diff --git a/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.h b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.h new file mode 100644 index 0000000000000..dc7e8693ffedb --- /dev/null +++ b/drivers/soc/mediatek/apusys/apu_mem/apummu/platform/apummu_plat.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_PLAT_H__ +#define __APUSYS_APUMMU_PLAT_H__ + +/* apummu platform data */ +struct apummu_plat { + unsigned int slb_wait_time; + bool is_general_SLB_support; + bool alloc_DRAM_FB_in_session_create; +}; + +int apummu_plat_init(struct platform_device *pdev); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd.h b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd.h new file mode 100644 index 0000000000000..94f953daf6fd2 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MTK_APUCMD_H__ +#define __MTK_APUCMD_H__ + +#include + +#include "mdw_cmn.h" + +/* cmd idr range */ +#define MDW_CMD_IDR_MIN (1) +#define MDW_CMD_IDR_MAX (64) + +/* stale cmd timeout */ +#define MDW_STALE_CMD_TIMEOUT (5*1000) //ms + +/* poll cmd */ +#define MDW_POLL_TIMEOUT (4*1000) //us +#define MDW_POLLTIME_SLEEP_TH(x) div_u64((x) * 65, 100) //us + +/* cmd deubg */ +#define mdw_cmd_show(c, f) \ + f("cmd(0x%llx/0x%llx/0x%llx/0x%llx/%d/%u)param(%u/%u/%u/%u/"\ + "%u/%u/%u/%u/%u/%llu)subcmds(%u/%pK/%u/%u)pid(%d/%d)(%d)\n", \ + (uint64_t) c->mpriv, c->uid, c->kid, c->rvid, c->id, kref_read(&c->ref), \ + c->priority, c->hardlimit, c->softlimit, \ + c->power_save, c->power_plcy, c->power_dtime, \ + c->app_type, c->inference_ms, c->tolerance_ms, c->is_dtime_set, \ + c->num_subcmds, c->cmdbufs, c->num_cmdbufs, c->size_cmdbufs, \ + c->pid, c->tgid, task_pid_nr(current)) + +/* cmd ioctl */ +int mdw_cmd_ioctl_v2(struct mdw_fpriv *mpriv, void *data); +int mdw_cmd_ioctl_v3(struct mdw_fpriv *mpriv, void *data); +int mdw_cmd_ioctl_v4(struct mdw_fpriv *mpriv, void *data); + +/* cmd release */ +void mdw_cmd_mpriv_release(struct mdw_fpriv *mpriv); +void mdw_cmd_mpriv_release_without_stale(struct mdw_fpriv *mpriv); + +/* cmd history */ +void mdw_cmd_history_init(struct mdw_device *mdev); +void mdw_cmd_history_deinit(struct mdw_device *mdev); +struct mdw_cmd_history_tbl *mdw_cmd_ch_tbl_find(struct mdw_cmd *c); +void mdw_cmd_history_reset(struct mdw_fpriv *mpriv); + +/* cmdbuf */ +void mdw_cmd_cmdbuf_out(struct mdw_fpriv *mpriv, struct mdw_cmd *c); +void mdw_cmd_put_cmdbufs(struct mdw_fpriv *mpriv, struct mdw_cmd *c); +int mdw_cmd_get_cmdbufs(struct mdw_fpriv *mpriv, struct mdw_cmd *c); +int mdw_cmd_get_cmdbufs_with_apummu(struct mdw_fpriv *mpriv, struct mdw_cmd *c); + +/* cmd infos */ +int mdw_cmd_create_infos(struct mdw_fpriv *mpriv, struct mdw_cmd *c); +void mdw_cmd_delete_infos(struct mdw_fpriv *mpriv, struct mdw_cmd *c); + +/* cmd check */ +int mdw_cmd_sanity_check(struct mdw_cmd *c); +int mdw_cmd_sc_sanity_check(struct mdw_cmd *c); +int mdw_cmd_link_check(struct mdw_cmd *c); +int mdw_cmd_adj_check(struct mdw_cmd *c); +void mdw_cmd_check_rets(struct mdw_cmd *c, int ret); + +/* cmd delete */ +void mdw_cmd_delete(struct mdw_cmd *c); +void mdw_cmd_delete_async(struct mdw_cmd *c); +int mdw_cmd_ioctl_del(struct mdw_fpriv *mpriv, union mdw_cmd_args *args); + +/* cmd map */ +int mdw_cmd_invoke_map(struct mdw_cmd *c, struct mdw_mem_map *map); +void mdw_cmd_unvoke_map(struct mdw_cmd *c); + +/* get apummu table */ +int mdw_cmd_get_apummutable(struct mdw_fpriv *mpriv, struct mdw_cmd *c); + +/* cmd kref */ +void mdw_cmd_put(struct mdw_cmd *c); +void mdw_cmd_get(struct mdw_cmd *c); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_cmn.c b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_cmn.c new file mode 100644 index 0000000000000..065adae966a82 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_cmn.c @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "mdw_trace.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "linux/soc/mediatek/apummu_export.h" +#include "rv/mdw_rv_tag.h" +#include "mdw_ext_export.h" +#include "linux/soc/mediatek/apu_mem_export.h" +#include "linux/soc/mediatek/apu_mem_def.h" + +void mdw_cmd_cmdbuf_out(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_subcmd_kinfo *ksubcmd = NULL; + unsigned int i = 0, j = 0; + + if (!c->cmdbufs) + return; + + /* flush cmdbufs and execinfos */ + if (mdw_mem_invalidate(mpriv, c->cmdbufs)) + mdw_drv_warn("s(0x%llx)c(0x%llx) invalidate cmdbufs(%llu) fail\n", + (uint64_t)mpriv, c->kid, c->cmdbufs->size); + + for (i = 0; i < c->num_subcmds; i++) { + ksubcmd = &c->ksubcmds[i]; + for (j = 0; j < ksubcmd->info->num_cmdbufs; j++) { + if (!ksubcmd->ori_cbs[j]) { + mdw_drv_warn("no ori mems(%d-%d)\n", i, j); + continue; + } + + /* cmdbuf copy out */ + if (ksubcmd->cmdbufs[j].direction != MDW_CB_IN) { + mdw_trace_begin("apumdw:cbs_copy_out|cb:%u-%u size:%llu type:%u", + i, j, ksubcmd->ori_cbs[j]->size, ksubcmd->info->type); + memcpy(ksubcmd->ori_cbs[j]->vaddr, + (void *)ksubcmd->kvaddrs[j], + ksubcmd->ori_cbs[j]->size); + mdw_trace_end(); + } + } + } +} + +void mdw_cmd_put_cmdbufs(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_subcmd_kinfo *ksubcmd = NULL; + unsigned int i = 0, j = 0; + + if (!c->cmdbufs) + return; + + mdw_trace_begin("apumdw:cbs_put|c:0x%llx num_subcmds:%u num_cmdbufs:%u", + c->kid, c->num_subcmds, c->num_cmdbufs); + + for (i = 0; i < c->num_subcmds; i++) { + ksubcmd = &c->ksubcmds[i]; + for (j = 0; j < ksubcmd->info->num_cmdbufs; j++) { + if (!ksubcmd->ori_cbs[j]) { + mdw_drv_warn("no ori mems(%d-%d)\n", i, j); + continue; + } + + /* put mem */ + mdw_mem_put(mpriv, ksubcmd->ori_cbs[j]); + ksubcmd->ori_cbs[j] = NULL; + } + } + + mdw_mem_pool_free(c->cmdbufs); + c->cmdbufs = NULL; + + mdw_trace_end(); +} + +int mdw_cmd_get_cmdbufs(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + unsigned int i = 0, j = 0, ofs = 0; + int ret = -EINVAL; + struct mdw_subcmd_kinfo *ksubcmd = NULL; + struct mdw_mem *m = NULL; + struct apusys_cmdbuf *acbs = NULL; + + mdw_trace_begin("apumdw:cbs_get|c:0x%llx num_subcmds:%u num_cmdbufs:%u", + c->kid, c->num_subcmds, c->num_cmdbufs); + + if (!c->size_cmdbufs || c->cmdbufs) + goto out; + + c->cmdbufs = mdw_mem_pool_alloc(&mpriv->cmd_buf_pool, c->size_cmdbufs, + MDW_DEFAULT_ALIGN); + if (!c->cmdbufs) { + mdw_drv_err("s(0x%llx)c(0x%llx) alloc buffer for duplicate fail\n", + (uint64_t) mpriv, c->kid); + ret = -ENOMEM; + goto out; + } + + /* alloc mem for duplicated cmdbuf */ + for (i = 0; i < c->num_subcmds; i++) { + mdw_cmd_debug("sc(0x%llx-%u) #cmdbufs(%u)\n", + c->kid, i, c->ksubcmds[i].info->num_cmdbufs); + + acbs = kcalloc(c->ksubcmds[i].info->num_cmdbufs, sizeof(*acbs), GFP_KERNEL); + if (!acbs) + goto free_cmdbufs; + + ksubcmd = &c->ksubcmds[i]; + for (j = 0; j < ksubcmd->info->num_cmdbufs; j++) { + /* calc align */ + if (ksubcmd->cmdbufs[j].align) + ofs = MDW_ALIGN(ofs, ksubcmd->cmdbufs[j].align); + else + ofs = MDW_ALIGN(ofs, MDW_DEFAULT_ALIGN); + + mdw_cmd_debug("sc(0x%llx-%u) cb#%u offset(%u)\n", + c->kid, i, j, ofs); + + /* get mem from handle */ + m = mdw_mem_get(mpriv, ksubcmd->cmdbufs[j].handle); + if (!m) { + mdw_drv_err("sc(0x%llx-%u) cb#%u(%llu) get fail\n", + c->kid, i, j, + ksubcmd->cmdbufs[j].handle); + ret = -EINVAL; + goto free_cmdbufs; + } + /* check mem boundary */ + if (m->vaddr == NULL || + ksubcmd->cmdbufs[j].size != m->size) { + mdw_drv_err("sc(0x%llx-%u) cb#%u invalid range(%p/%u/%llu)\n", + c->kid, i, j, m->vaddr, + ksubcmd->cmdbufs[j].size, + m->size); + ret = -EINVAL; + goto free_cmdbufs; + } + + /* cmdbuf copy in */ + if (ksubcmd->cmdbufs[j].direction != MDW_CB_OUT) { + mdw_trace_begin("apumdw:cbs_copy_in|cb:%u-%u size:%u type:%u", + i, j, + ksubcmd->cmdbufs[j].size, + ksubcmd->info->type); + memcpy(c->cmdbufs->vaddr + ofs, + m->vaddr, + ksubcmd->cmdbufs[j].size); + mdw_trace_end(); + } + + /* record buffer info */ + ksubcmd->ori_cbs[j] = m; + ksubcmd->kvaddrs[j] = + (uint64_t)(c->cmdbufs->vaddr + ofs); + ksubcmd->daddrs[j] = + (uint64_t)(c->cmdbufs->device_va + ofs); + ofs += ksubcmd->cmdbufs[j].size; + + mdw_cmd_debug("sc(0x%llx-%u) cb#%u (0x%llx/0x%llx/%u)\n", + c->kid, i, j, + ksubcmd->kvaddrs[j], + ksubcmd->daddrs[j], + ksubcmd->cmdbufs[j].size); + + acbs[j].kva = (void *)ksubcmd->kvaddrs[j]; + acbs[j].size = ksubcmd->cmdbufs[j].size; + } + + mdw_trace_begin("apumdw:dev validation|c:0x%llx type:%u", + c->kid, ksubcmd->info->type); + ret = mdw_dev_validation(mpriv, ksubcmd->info->type, + c, acbs, ksubcmd->info->num_cmdbufs); + mdw_trace_end(); + kfree(acbs); + acbs = NULL; + if (ret) { + mdw_drv_err("sc(0x%llx-%u) dev(%u) validate cb(%u) fail(%d)\n", + c->kid, i, ksubcmd->info->type, ksubcmd->info->num_cmdbufs, ret); + goto free_cmdbufs; + } + } + + /* flush cmdbufs */ + if (mdw_mem_flush(mpriv, c->cmdbufs)) + mdw_drv_warn("s(0x%llx) c(0x%llx) flush cmdbufs(%llu) fail\n", + (uint64_t)mpriv, c->kid, c->cmdbufs->size); + + ret = 0; + goto out; + +free_cmdbufs: + mdw_cmd_put_cmdbufs(mpriv, c); + kfree(acbs); +out: + mdw_cmd_debug("ret(%d)\n", ret); + mdw_trace_end(); + return ret; +} + +int mdw_cmd_get_apummutable(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + unsigned int tbl_size = 0; + int ret = -ENOMEM; + + mdw_cmd_debug("mdw call apummu_table_get priv(0x%llx) tbl_kva(0x%llx)\n", + (uint64_t)c->mpriv, (uint64_t)c->tbl_kva); + + /* get apummu table */ + mdw_trace_begin("apummu:table_get|s:0x%llx", (uint64_t)c->mpriv); + ret = apu_mem_table_get((uint64_t)c->mpriv, &c->tbl_kva, &tbl_size); + mdw_trace_end(); + + if (ret == -EOPNOTSUPP) { + mdw_drv_warn("no support apummu\n"); + return ret; + } + if (ret) { + mdw_drv_err("get apummu table fail\n"); + return ret; + } + + c->size_cmdbufs += tbl_size; + c->size_apummutable = tbl_size; + mdw_cmd_debug("c->kid(0x%llx) tbl_size(%u) apummutable size(%u)\n", + c->kid, tbl_size, c->size_apummutable); + + return ret; +} + +int mdw_cmd_create_infos(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + unsigned int i = 0, j = 0, total_size = 0, tmp_size = 0; + struct mdw_subcmd_exec_info *sc_einfo = NULL; + int ret = -ENOMEM; + + c->einfos = c->exec_infos->vaddr; + if (!c->einfos) { + mdw_drv_err("invalid exec info addr\n"); + return -EINVAL; + } + /* clear run infos for return */ + memset(c->exec_infos->vaddr, 0, c->exec_infos->size); + + sc_einfo = &c->einfos->sc; + + for (i = 0; i < c->num_subcmds; i++) { + c->ksubcmds[i].info = &c->subcmds[i]; + mdw_cmd_debug("subcmd(%u)(%u/%u/%u/%u/%u/%u/%u/%u/0x%llx)\n", + i, c->subcmds[i].type, + c->subcmds[i].suggest_time, c->subcmds[i].vlm_usage, + c->subcmds[i].vlm_ctx_id, c->subcmds[i].vlm_force, + c->subcmds[i].boost, c->subcmds[i].pack_id, + c->subcmds[i].num_cmdbufs, c->subcmds[i].cmdbufs); + + /* kva for oroginal buffer */ + c->ksubcmds[i].ori_cbs = kcalloc(c->subcmds[i].num_cmdbufs, + sizeof(c->ksubcmds[i].ori_cbs), GFP_KERNEL); + if (!c->ksubcmds[i].ori_cbs) + goto free_cmdbufs; + + /* record kva for duplicate */ + c->ksubcmds[i].kvaddrs = kcalloc(c->subcmds[i].num_cmdbufs, + sizeof(*c->ksubcmds[i].kvaddrs), GFP_KERNEL); + if (!c->ksubcmds[i].kvaddrs) + goto free_cmdbufs; + + /* record dva for cmdbufs */ + c->ksubcmds[i].daddrs = kcalloc(c->subcmds[i].num_cmdbufs, + sizeof(*c->ksubcmds[i].daddrs), GFP_KERNEL); + if (!c->ksubcmds[i].daddrs) + goto free_cmdbufs; + + /* allocate for subcmd cmdbuf */ + c->ksubcmds[i].cmdbufs = kcalloc(c->subcmds[i].num_cmdbufs, + sizeof(*c->ksubcmds[i].cmdbufs), GFP_KERNEL); + if (!c->ksubcmds[i].cmdbufs) + goto free_cmdbufs; + + /* copy cmdbuf info */ + if (copy_from_user(c->ksubcmds[i].cmdbufs, + (void __user *)c->subcmds[i].cmdbufs, + c->subcmds[i].num_cmdbufs * + sizeof(*c->ksubcmds[i].cmdbufs))) { + goto free_cmdbufs; + } + + c->ksubcmds[i].sc_einfo = &sc_einfo[i]; + + /* accumulate cmdbuf size with alignment */ + for (j = 0; j < c->subcmds[i].num_cmdbufs; j++) { + c->num_cmdbufs++; + /* alignment */ + if (c->ksubcmds[i].cmdbufs[j].align) { + tmp_size = MDW_ALIGN(total_size, + c->ksubcmds[i].cmdbufs[j].align); + } else { + tmp_size = MDW_ALIGN(total_size, MDW_DEFAULT_ALIGN); + } + if (tmp_size < total_size) { + mdw_drv_err("cmdbuf(%u,%u) size align overflow(%u/%u/%u)\n", + i, j, total_size, + c->ksubcmds[i].cmdbufs[j].align, tmp_size); + goto free_cmdbufs; + } + total_size = tmp_size; + + /* accumulator */ + tmp_size = total_size + c->ksubcmds[i].cmdbufs[j].size; + if (tmp_size < total_size) { + mdw_drv_err("cmdbuf(%u,%u) size overflow(%u/%u/%u)\n", + i, j, total_size, + c->ksubcmds[i].cmdbufs[j].size, tmp_size); + goto free_cmdbufs; + } + total_size = tmp_size; + } + } + /* align cmdbuf tail offset for apummu table */ + tmp_size = MDW_ALIGN(total_size, MDW_DEFAULT_ALIGN); + if (tmp_size < total_size) { + mdw_drv_err("cmdbuf end size align overflow(%u/%u)\n", + total_size, tmp_size); + goto free_cmdbufs; + } + total_size = tmp_size; + c->size_cmdbufs = total_size; + + mdw_cmd_debug("sc(0x%llx) cb_num(%u) total size(%u)\n", + c->kid, c->num_cmdbufs, c->size_cmdbufs); + + ret = mdw_cmd_get_apummutable(mpriv, c); + if (ret && ret != -EOPNOTSUPP) { + mdw_drv_err("get apummu table fail\n"); + goto free_cmdbufs; + } + + ret = mpriv->mdev->plat_funcs->get_cmdbuf(mpriv, c); + if (ret) + goto free_cmdbufs; + + goto out; + +free_cmdbufs: + for (i = 0; i < c->num_subcmds; i++) { + /* free dvaddrs */ + kfree(c->ksubcmds[i].daddrs); + c->ksubcmds[i].daddrs = NULL; + + /* free kvaddrs */ + kfree(c->ksubcmds[i].kvaddrs); + c->ksubcmds[i].kvaddrs = NULL; + + /* free ori kvas */ + kfree(c->ksubcmds[i].ori_cbs); + c->ksubcmds[i].ori_cbs = NULL; + + /* free cmdbufs */ + kfree(c->ksubcmds[i].cmdbufs); + c->ksubcmds[i].cmdbufs = NULL; + } + +out: + return ret; +} + +void mdw_cmd_delete_infos(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + unsigned int i = 0; + + mdw_cmd_put_cmdbufs(mpriv, c); + + for (i = 0; i < c->num_subcmds; i++) { + /* free dvaddrs */ + kfree(c->ksubcmds[i].daddrs); + c->ksubcmds[i].daddrs = NULL; + + /* free kvaddrs */ + kfree(c->ksubcmds[i].kvaddrs); + c->ksubcmds[i].kvaddrs = NULL; + + /* free ori kvas */ + kfree(c->ksubcmds[i].ori_cbs); + c->ksubcmds[i].ori_cbs = NULL; + + /* free cmdbufs */ + kfree(c->ksubcmds[i].cmdbufs); + c->ksubcmds[i].cmdbufs = NULL; + } +} + +void mdw_cmd_history_reset(struct mdw_fpriv *mpriv) +{ + struct mdw_device *mdev = mpriv->mdev; + int i = 0; + + /* reset min heap */ + mutex_lock(&mdev->h_mtx); + mdev->heap.nr = 0; + for (i = 0; i < MDW_NUM_PREDICT_CMD; i++) + mdev->predict_cmd_ts[i] = 0; + mutex_unlock(&mdev->h_mtx); +} + +static void mdw_cmd_history_tbl_delete(struct mdw_fpriv *mpriv) +{ + struct mdw_cmd_history_tbl *ch_tbl = NULL, *tmp = NULL; + + mutex_lock(&mpriv->ch_mtx); + list_for_each_entry_safe(ch_tbl, tmp, &mpriv->ch_list, ch_tbl_node) { + list_del(&ch_tbl->ch_tbl_node); + mdw_cmd_debug("s(0x%llx) uid(0x%llx) delete ch_tbl\n", + (uint64_t)mpriv, ch_tbl->uid); + kfree(ch_tbl->h_sc_einfo); + kfree(ch_tbl); + } + mutex_unlock(&mpriv->ch_mtx); + + mdw_cmd_history_reset(mpriv); +} + +void mdw_cmd_mpriv_release(struct mdw_fpriv *mpriv) +{ + struct mdw_cmd *c = NULL; + uint32_t id = 0; + + if (!atomic_read(&mpriv->active) && !atomic_read(&mpriv->active_cmds)) { + mdw_flw_debug("s(0x%llx) release cmd\n", (uint64_t)mpriv); + idr_for_each_entry(&mpriv->cmds, c, id) { + idr_remove(&mpriv->cmds, id); + mdw_cmd_delete(c); + } + mdw_flw_debug("s(0x%llx) release mem\n", (uint64_t)mpriv); + mutex_lock(&mpriv->mdev->mctl_mtx); + mdw_mem_mpriv_release(mpriv); + mutex_unlock(&mpriv->mdev->mctl_mtx); + mdw_flw_debug("s(0x%llx) release apummu table\n", (uint64_t)mpriv); + mdw_trace_begin("apummu:table_free|s:0x%llx", (uint64_t)mpriv); + apu_mem_table_free((uint64_t)mpriv); + mdw_trace_end(); + mdw_flw_debug("s(0x%llx) release history tbl\n", (uint64_t)mpriv); + mdw_cmd_history_tbl_delete(mpriv); + } +} + +//-------------------------------------------- +uint64_t mdw_fence_ctx_alloc(struct mdw_device *mdev) +{ + uint64_t idx = 0, ctx = 0; + + mutex_lock(&mdev->f_mtx); + idx = find_first_zero_bit(mdev->fence_ctx_mask, mdev->num_fence_ctx); + if (idx >= mdev->num_fence_ctx) { + ctx = dma_fence_context_alloc(1); + mdw_drv_warn("no free fence ctx(%llu), alloc ctx(%llu)\n", idx, ctx); + } else { + set_bit(idx, mdev->fence_ctx_mask); + ctx = mdev->base_fence_ctx + idx; + } + mutex_unlock(&mdev->f_mtx); + mdw_cmd_debug("alloc fence ctx(%llu) idx(%llu) base(%llu)\n", + ctx, idx, mdev->base_fence_ctx); + + return ctx; +} + +void mdw_fence_ctx_free(struct mdw_device *mdev, uint64_t ctx) +{ + int idx = 0; + + idx = ctx - mdev->base_fence_ctx; + if (idx < 0 || idx >= mdev->num_fence_ctx) { + mdw_cmd_debug("out of range ctx(%llu/%llu)\n", ctx, mdev->base_fence_ctx); + return; + } + + mutex_lock(&mdev->f_mtx); + if (!test_bit(idx, mdev->fence_ctx_mask)) + mdw_drv_warn("ctx state conflict(%d)\n", idx); + else + clear_bit(idx, mdev->fence_ctx_mask); + mutex_unlock(&mdev->f_mtx); +} + +const char *mdw_fence_get_driver_name(struct dma_fence *fence) +{ + return "apu_mdw"; +} + +const char *mdw_fence_get_timeline_name(struct dma_fence *fence) +{ + struct mdw_fence *f = + container_of(fence, struct mdw_fence, base_fence); + + return f->name; +} + +bool mdw_fence_enable_signaling(struct dma_fence *fence) +{ + return true; +} + +void mdw_fence_release(struct dma_fence *fence) +{ + struct mdw_fence *mf = + container_of(fence, struct mdw_fence, base_fence); + + mdw_flw_debug("fence release, fence(%s/%llu-%llu)\n", + mf->name, mf->base_fence.context, mf->base_fence.seqno); + mdw_fence_ctx_free(mf->mdev, mf->base_fence.context); + kfree(mf); +} + +const struct dma_fence_ops mdw_fence_ops = { + .get_driver_name = mdw_fence_get_driver_name, + .get_timeline_name = mdw_fence_get_timeline_name, + .enable_signaling = mdw_fence_enable_signaling, + .wait = dma_fence_default_wait, + .release = mdw_fence_release, +}; + +//-------------------------------------------- +int mdw_fence_init(struct mdw_cmd *c, int fd) +{ + int ret = 0; + struct mdw_device *mdev = c->mpriv->mdev; + + c->fence = kzalloc(sizeof(*c->fence), GFP_KERNEL); + if (!c->fence) + return -ENOMEM; + + if (snprintf(c->fence->name, sizeof(c->fence->name), "%d:%s", fd, c->comm) <= 0) + mdw_drv_warn("set fance name fail\n"); + c->fence->mdev = c->mpriv->mdev; + spin_lock_init(&c->fence->lock); + dma_fence_init(&c->fence->base_fence, &mdw_fence_ops, + &c->fence->lock, mdw_fence_ctx_alloc(mdev), + atomic_add_return(1, &c->mpriv->exec_seqno)); + + mdw_flw_debug("fence init, c(0x%llx) fence(%s/%llu-%llu)\n", + (uint64_t)c, c->fence->name, c->fence->base_fence.context, + c->fence->base_fence.seqno); + + return ret; +} + +void mdw_cmd_unvoke_map(struct mdw_cmd *c) +{ + struct mdw_cmd_map_invoke *cm_invoke = NULL, *tmp = NULL; + + list_for_each_entry_safe(cm_invoke, tmp, &c->map_invokes, c_node) { + list_del(&cm_invoke->c_node); + mdw_cmd_debug("s(0x%llx)c(0x%llx) unvoke m(0x%llx/%llu)\n", + (uint64_t)c->mpriv, (uint64_t)c, + cm_invoke->map->m->device_va, + cm_invoke->map->m->dva_size); + cm_invoke->map->put(cm_invoke->map); + kfree(cm_invoke); + } +} + +int mdw_cmd_invoke_map(struct mdw_cmd *c, struct mdw_mem_map *map) +{ + struct mdw_cmd_map_invoke *cm_invoke = NULL; + + if (map == NULL) + return -EINVAL; + + /* query */ + list_for_each_entry(cm_invoke, &c->map_invokes, c_node) { + /* already invoked */ + if (cm_invoke->map == map) + return 0; + } + + cm_invoke = kzalloc(sizeof(*cm_invoke), GFP_KERNEL); + if (cm_invoke == NULL) + return -ENOMEM; + + map->get(map); + cm_invoke->map = map; + list_add_tail(&cm_invoke->c_node, &c->map_invokes); + mdw_cmd_debug("s(0x%llx)c(0x%llx) invoke m(0x%llx/%llu)\n", + (uint64_t)c->mpriv, (uint64_t)c, map->m->device_va, map->m->dva_size); + + return 0; +} + +static void mdw_cmd_release(struct kref *ref) +{ + struct mdw_cmd *c = + container_of(ref, struct mdw_cmd, ref); + struct mdw_fpriv *mpriv = c->mpriv; + + mdw_cmd_show(c, mdw_drv_debug); + /* remove ext id */ + mdw_ext_cmd_put_id(c); + mdw_trace_begin("apumdw:cmd_release|c:0x%llx", c->kid); + if (c->del_internal) + c->del_internal(c); + mutex_lock(&mpriv->mdev->mctl_mtx); + mdw_cmd_unvoke_map(c); + mutex_unlock(&mpriv->mdev->mctl_mtx); + mdw_cmd_delete_infos(c->mpriv, c); + mdw_mem_put(c->mpriv, c->exec_infos); + kfree(c->adj_matrix); + kfree(c->ksubcmds); + kfree(c->subcmds); + kfree(c); + + mpriv->put(mpriv); + mdw_trace_end(); +} + +void mdw_cmd_put(struct mdw_cmd *c) +{ + mdw_ext_lock(); + kref_put(&c->ref, mdw_cmd_release); + mdw_ext_unlock(); +} + +void mdw_cmd_get(struct mdw_cmd *c) +{ + kref_get(&c->ref); +} + +void mdw_cmd_delete(struct mdw_cmd *c) +{ + mdw_cmd_show(c, mdw_drv_debug); + mdw_cmd_put(c); +} + +void mdw_cmd_delete_async(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + + /* add cmd list to delete */ + mutex_lock(&mdev->c_mtx); + list_add_tail(&c->d_node, &mdev->d_cmds); + mutex_unlock(&mdev->c_mtx); + + schedule_work(&mdev->c_wk); +} + +int mdw_cmd_sanity_check(struct mdw_cmd *c) +{ + if (c->priority >= MDW_PRIORITY_MAX || + c->num_subcmds > MDW_SUBCMD_MAX || + c->num_links > c->num_subcmds) { + mdw_drv_err("s(0x%llx)cmd invalid(0x%llx/0x%llx)(%u/%u/%u)\n", + (uint64_t)c->mpriv, c->uid, c->kid, + c->priority, c->num_subcmds, c->num_links); + return -EINVAL; + } + + if (c->exec_infos->size != sizeof(struct mdw_cmd_exec_info) + + c->num_subcmds * sizeof(struct mdw_subcmd_exec_info)) { + mdw_drv_err("s(0x%llx)cmd invalid(0x%llx/0x%llx) einfo(%llu/%zu)\n", + (uint64_t)c->mpriv, c->uid, c->kid, + c->exec_infos->size, + sizeof(struct mdw_cmd_exec_info) + + c->num_subcmds * sizeof(struct mdw_subcmd_exec_info)); + return -EINVAL; + } + + return 0; +} + +int mdw_cmd_adj_check(struct mdw_cmd *c) +{ + uint32_t i = 0, j = 0; + + for (i = 0; i < c->num_subcmds; i++) { + for (j = 0; j < c->num_subcmds; j++) { + if (i == j) { + c->adj_matrix[i * c->num_subcmds + j] = 0; + continue; + } + + if (i < j) + continue; + + if (!c->adj_matrix[i * c->num_subcmds + j] || + !c->adj_matrix[i + j * c->num_subcmds]) + continue; + + mdw_drv_err("s(0x%llx)c(0x%llx/0x%llx) adj matrix(%u/%u) fail\n", + (uint64_t)c->mpriv, c->uid, c->kid, i, j); + return -EINVAL; + } + } + + return 0; +} + +int mdw_cmd_link_check(struct mdw_cmd *c) +{ + uint32_t i = 0; + + for (i = 0; i < c->num_links; i++) { + if (c->links[i].producer_idx > c->num_subcmds || + c->links[i].consumer_idx > c->num_subcmds || + !c->links[i].x || !c->links[i].y || + !c->links[i].va) { + mdw_drv_err("link(%u) invalid(%u/%u)(%llu/%llu)(0x%llx)\n", i, + c->links[i].producer_idx, + c->links[i].consumer_idx, + c->links[i].x, + c->links[i].y, + c->links[i].va); + return -EINVAL; + } + } + return 0; +} + +int mdw_cmd_sc_sanity_check(struct mdw_cmd *c) +{ + unsigned int i = 0; + + /* subcmd info */ + for (i = 0; i < c->num_subcmds; i++) { + if (c->subcmds[i].type >= MDW_DEV_MAX || + c->subcmds[i].vlm_ctx_id >= MDW_SUBCMD_MAX || + c->subcmds[i].boost > MDW_BOOST_MAX || + c->subcmds[i].pack_id >= MDW_SUBCMD_MAX) { + mdw_drv_err("subcmd(%u) invalid (%u/%u/%u)\n", + i, c->subcmds[i].type, + c->subcmds[i].boost, + c->subcmds[i].pack_id); + return -EINVAL; + } + } + + return 0; +} + +void mdw_cmd_check_rets(struct mdw_cmd *c, int ret) +{ + uint32_t idx = 0, is_dma = 0, is_aps = 0; + DECLARE_BITMAP(tmp, 64); + + memcpy(&tmp, &c->einfos->c.sc_rets, sizeof(c->einfos->c.sc_rets)); + + /* extract fail subcmd */ + do { + idx = find_next_bit((unsigned long *)&tmp, c->num_subcmds, idx); + if (idx >= c->num_subcmds) + break; + + mdw_drv_warn("sc(0x%llx-#%u) type(%u) softlimit(%u) boost(%u) fail\n", + c->kid, idx, c->subcmds[idx].type, + c->softlimit, c->subcmds[idx].boost); + switch (c->subcmds[idx].type) { + case APUSYS_DEVICE_EDMA: + is_dma++; + break; + case APUSYS_DEVICE_APS: + is_aps++; + break; + default: + break; + } + + idx++; + } while (idx < c->num_subcmds); + + /* trigger exception if dma */ + if (is_dma) { + dma_exception("dma exec fail:%s:ret(%d/0x%llx)pid(%d/%d)c(0x%llx)\n", + c->comm, ret, c->einfos->c.sc_rets, + c->pid, c->tgid, c->kid); + } + if (is_aps) { + aps_exception("aps exec fail:%s:ret(%d/0x%llx)pid(%d/%d)c(0x%llx)\n", + c->comm, ret, c->einfos->c.sc_rets, + c->pid, c->tgid, c->kid); + } +} + +int mdw_cmd_ioctl_del(struct mdw_fpriv *mpriv, union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL; + int ret = 0; + + mdw_trace_begin("apumdw:user_delete"); + + mutex_lock(&mpriv->mtx); + c = (struct mdw_cmd *)idr_find(&mpriv->cmds, in->id); + if (!c) { + ret = -EINVAL; + mdw_drv_warn("can't find id(%lld)\n", in->id); + } else { + if (c != idr_remove(&mpriv->cmds, c->id)) + mdw_drv_warn("remove cmd idr conflict(0x%llx/%d)\n", c->kid, c->id); + mdw_cmd_delete(c); + } + mutex_unlock(&mpriv->mtx); + + mdw_trace_end(); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v2.c b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v2.c new file mode 100644 index 0000000000000..e789014d12eb9 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v2.c @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "mdw_trace.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "rv/mdw_rv_tag.h" + +static int mdw_cmd_run(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_device *mdev = mpriv->mdev; + int ret = 0; + + mdw_cmd_show(c, mdw_cmd_debug); + mutex_lock(&c->mtx); + + c->start_ts = sched_clock(); + ret = mdev->plat_funcs->run_cmd(mpriv, c); + if (ret) { + mdw_drv_err("s(0x%llx) run cmd(0x%llx) fail(%d)\n", + (uint64_t) c->mpriv, c->kid, ret); + + dma_fence_set_error(&c->fence->base_fence, ret); + } else { + mdw_flw_debug("s(0x%llx) cmd(0x%llx) run\n", + (uint64_t)c->mpriv, c->kid); + } + + mutex_unlock(&c->mtx); + + return ret; +} + +static void mdw_cmd_delete_v2(struct mdw_cmd *c) +{ + struct mdw_fpriv *mpriv = c->mpriv; + struct dma_fence *f = &c->fence->base_fence; + + mdw_cmd_show(c, mdw_drv_debug); + + mutex_lock(&mpriv->mtx); + mdw_cmd_unvoke_map(c); + mdw_cmd_cmdbuf_out(mpriv, c); + mdw_cmd_delete_infos(c->mpriv, c); + list_del(&c->u_item); + mpriv->mdev->plat_funcs->release_cmd(mpriv); + mutex_unlock(&mpriv->mtx); + mdw_mem_put(c->mpriv, c->exec_infos); + dma_fence_signal(f); + kfree(c->adj_matrix); + kfree(c->ksubcmds); + kfree(c->subcmds); + dma_fence_put(f); + kfree(c); + + mpriv->put(mpriv); +} + +static int mdw_cmd_complete(struct mdw_cmd *c, int ret) +{ + mutex_lock(&c->mtx); + + c->end_ts = sched_clock(); + c->einfos->c.total_us = div_u64(c->end_ts - c->start_ts, 1000); + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d) sc_rets(0x%llx) complete, pid(%d/%d)(%d)\n", + (uint64_t)c->mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->pid, c->tgid, task_pid_nr(current)); + + /* check subcmds return value */ + if (c->einfos->c.sc_rets) { + if (!ret) + ret = -EIO; + + mdw_cmd_check_rets(c, ret); + } else if (ret == -EBUSY) { + mdw_exception("AP/uP busy:%s:ret(%d/0x%llx)pid(%d/%d)\n", + c->comm, ret, c->einfos->c.sc_rets, c->pid, c->tgid); + } + c->einfos->c.ret = ret; + + if (ret) { + mdw_drv_err("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)c->mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + dma_fence_set_error(&c->fence->base_fence, ret); + } else { + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)c->mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + } + + mutex_unlock(&c->mtx); + mdw_cmd_delete_v2(c); + + return 0; +} + +static void mdw_cmd_trigger_func(struct work_struct *wk) +{ + struct mdw_cmd *c = + container_of(wk, struct mdw_cmd, t_wk); + + if (c->wait_fence) { + dma_fence_wait(c->wait_fence, false); + dma_fence_put(c->wait_fence); + } + + mdw_flw_debug("s(0x%llx) c(0x%llx) wait fence done, start run\n", + (uint64_t)c->mpriv, c->kid); + mdw_cmd_run(c->mpriv, c); +} + +static struct mdw_cmd *mdw_cmd_create(struct mdw_fpriv *mpriv, + union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL; + + mdw_trace_begin("apumdw:cmd_create|s:0x%llx", (uint64_t)mpriv); + + mutex_lock(&mpriv->mtx); + /* check num subcmds maximum */ + if (in->exec.num_subcmds > MDW_SUBCMD_MAX) { + mdw_drv_err("too much subcmds(%u)\n", in->exec.num_subcmds); + goto out; + } + + /* alloc mdw cmd */ + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + goto out; + + mutex_init(&c->mtx); + INIT_LIST_HEAD(&c->map_invokes); + c->mpriv = mpriv; + + /* setup cmd info */ + c->pid = task_pid_nr(current); + c->tgid = current->tgid; + c->kid = (uint64_t)c; + c->uid = in->exec.uid; + //c->usr_id = in->exec.usr_id; + get_task_comm(c->comm, current); + c->priority = in->exec.priority; + c->hardlimit = in->exec.hardlimit; + c->softlimit = in->exec.softlimit; + c->power_save = in->exec.power_save; + c->power_plcy = in->exec.power_plcy; + c->power_dtime = in->exec.power_dtime; + c->app_type = in->exec.app_type; + c->num_subcmds = in->exec.num_subcmds; + c->exec_infos = mdw_mem_get(mpriv, in->exec.exec_infos); + if (!c->exec_infos) { + mdw_drv_err("get exec info fail\n"); + goto free_cmd; + } + + /* check input params */ + if (mdw_cmd_sanity_check(c)) { + mdw_drv_err("cmd sanity check fail\n"); + goto put_execinfos; + } + + /* subcmds/ksubcmds */ + c->subcmds = kzalloc(c->num_subcmds * sizeof(*c->subcmds), GFP_KERNEL); + if (!c->subcmds) + goto put_execinfos; + if (copy_from_user(c->subcmds, (void __user *)in->exec.subcmd_infos, + c->num_subcmds * sizeof(*c->subcmds))) { + mdw_drv_err("copy subcmds fail\n"); + goto free_subcmds; + } + if (mdw_cmd_sc_sanity_check(c)) { + mdw_drv_err("sc sanity check fail\n"); + goto free_subcmds; + } + + c->ksubcmds = kzalloc(c->num_subcmds * sizeof(*c->ksubcmds), + GFP_KERNEL); + if (!c->ksubcmds) + goto free_subcmds; + + /* adj matrix */ + c->adj_matrix = kzalloc(c->num_subcmds * + c->num_subcmds * sizeof(uint8_t), GFP_KERNEL); + if (!c->adj_matrix) + goto free_ksubcmds; + if (copy_from_user(c->adj_matrix, (void __user *)in->exec.adj_matrix, + (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)))) { + mdw_drv_err("copy adj matrix fail\n"); + goto free_adj; + } + if (g_mdw_klog & MDW_DBG_CMD) { + print_hex_dump(KERN_INFO, "[apusys] adj matrix: ", + DUMP_PREFIX_OFFSET, 16, 1, c->adj_matrix, + c->num_subcmds * c->num_subcmds, 0); + } + if (mdw_cmd_adj_check(c)) + goto free_adj; + + /* create infos */ + if (mdw_cmd_create_infos(mpriv, c)) { + mdw_drv_err("create cmd info fail\n"); + goto free_adj; + } + + c->mpriv->get(c->mpriv); + c->complete = mdw_cmd_complete; + INIT_WORK(&c->t_wk, &mdw_cmd_trigger_func); + list_add_tail(&c->u_item, &mpriv->cmds_list); + mdw_cmd_show(c, mdw_drv_debug); + + goto out; + +free_adj: + kfree(c->adj_matrix); +free_ksubcmds: + kfree(c->ksubcmds); +free_subcmds: + kfree(c->subcmds); +put_execinfos: + mdw_mem_put(mpriv, c->exec_infos); +free_cmd: + kfree(c); + c = NULL; +out: + mutex_unlock(&mpriv->mtx); + mdw_trace_end(); + return c; +} + +static int mdw_cmd_ioctl_run_v2(struct mdw_fpriv *mpriv, union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL; + struct sync_file *sync_file = NULL; + int ret = 0, fd = 0, wait_fd = 0; + + /* get wait fd */ + wait_fd = in->exec.fence; + + c = mdw_cmd_create(mpriv, args); + if (!c) { + mdw_drv_err("create cmd fail\n"); + ret = -EINVAL; + goto out; + } + memset(args, 0, sizeof(*args)); + + /* get sync_file fd */ + fd = get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) { + mdw_drv_err("get unused fd fail\n"); + ret = -EINVAL; + goto delete_cmd; + } + + /* init fence */ + if (mdw_fence_init(c, fd)) { + mdw_drv_err("cmd init fence fail\n"); + goto put_file; + } + + sync_file = sync_file_create(&c->fence->base_fence); + if (!sync_file) { + mdw_drv_err("create sync file fail\n"); + ret = -ENOMEM; + goto put_file; + } + + /* check wait fence from other module */ + mdw_flw_debug("s(0x%llx)c(0x%llx) wait fence(%d)\n", + (uint64_t)c->mpriv, c->kid, wait_fd); + c->wait_fence = sync_file_get_fence(wait_fd); + if (!c->wait_fence) { + mdw_flw_debug("s(0x%llx)c(0x%llx) no wait fence, trigger directly\n", + (uint64_t)c->mpriv, c->kid); + ret = mdw_cmd_run(mpriv, c); + } else { + /* wait fence from wq */ + schedule_work(&c->t_wk); + } + + if (ret) + goto put_file; + + /* assign fd */ + fd_install(fd, sync_file->file); + args->out.exec.fence = fd; + mdw_flw_debug("async fd(%d)\n", fd); + goto out; + +put_file: + put_unused_fd(fd); +delete_cmd: + mdw_cmd_delete_v2(c); +out: + return ret; +} +int mdw_cmd_ioctl_v2(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_cmd_args *args = (union mdw_cmd_args *)data; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op::%d\n", (uint64_t)mpriv, args->in.op); + + switch (args->in.op) { + case MDW_CMD_IOCTL_RUN: + ret = mdw_cmd_ioctl_run_v2(mpriv, args); + break; + + default: + ret = -EINVAL; + break; + } + mdw_flw_debug("done\n"); + + return ret; +} + +void mdw_cmd_mpriv_release_without_stale(struct mdw_fpriv *mpriv) +{ + if (!atomic_read(&mpriv->active) && + list_empty_careful(&mpriv->cmds_list)) { + mdw_flw_debug("s(0x%llx) release mem\n", (uint64_t)mpriv); + mdw_mem_mpriv_release(mpriv); + } +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v3.c b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v3.c new file mode 100644 index 0000000000000..5ead56268625c --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v3.c @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "mdw_trace.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "rv/mdw_rv_tag.h" + +static int mdw_cmd_run(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_device *mdev = mpriv->mdev; + struct dma_fence *f = &c->fence->base_fence; + int ret = 0; + + mdw_cmd_show(c, mdw_cmd_debug); + + c->start_ts = sched_clock(); + ret = mdev->plat_funcs->run_cmd(mpriv, c); + if (ret) { + mdw_drv_err("s(0x%llx) run cmd(0x%llx) fail(%d)\n", + (uint64_t) c->mpriv, c->kid, ret); + dma_fence_set_error(f, ret); + if (dma_fence_signal(f)) { + mdw_drv_warn("c(0x%llx) signal fence fail\n", (uint64_t)c); + if (f->ops->get_timeline_name && f->ops->get_driver_name) { + mdw_drv_warn(" fence name(%s-%s)\n", + f->ops->get_driver_name(f), f->ops->get_timeline_name(f)); + } + } + dma_fence_put(f); + } else { + mdw_flw_debug("s(0x%llx) cmd(0x%llx) run\n", + (uint64_t)c->mpriv, c->kid); + } + + return ret; +} + +static int mdw_cmd_complete(struct mdw_cmd *c, int ret) +{ + struct dma_fence *f = &c->fence->base_fence; + struct mdw_fpriv *mpriv = c->mpriv; + + mdw_trace_begin("apumdw:cmd_complete|cmd:0x%llx/0x%llx", c->uid, c->kid); + mutex_lock(&c->mtx); + + c->end_ts = sched_clock(); + c->einfos->c.total_us = div_u64(c->end_ts - c->start_ts, 1000); + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d) sc_rets(0x%llx) complete, pid(%d/%d)(%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->pid, c->tgid, task_pid_nr(current)); + + /* check subcmds return value */ + if (c->einfos->c.sc_rets) { + if (!ret) + ret = -EIO; + + mdw_cmd_check_rets(c, ret); + } else if (ret == -EBUSY) { + mdw_exception("uP busy:%s:ret(%d/0x%llx)pid(%d/%d)\n", + c->comm, ret, c->einfos->c.sc_rets, c->pid, c->tgid); + } + c->einfos->c.ret = ret; + + if (ret) { + mdw_drv_err("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + dma_fence_set_error(f, ret); + + if (mdw_debug_on(MDW_DBG_EXP)) + mdw_exception("exec fail:%s:ret(%d/0x%llx)pid(%d/%d)\n", + c->comm, ret, c->einfos->c.sc_rets, c->pid, c->tgid); + } else { + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + } + + mdw_cmd_cmdbuf_out(mpriv, c); + + /* signal done */ + c->fence = NULL; + atomic_dec(&c->is_running); + if (dma_fence_signal(f)) { + mdw_drv_warn("c(0x%llx) signal fence fail\n", (uint64_t)c); + if (f->ops->get_timeline_name && f->ops->get_driver_name) { + mdw_drv_warn(" fence name(%s-%s)\n", + f->ops->get_driver_name(f), f->ops->get_timeline_name(f)); + } + } + dma_fence_put(f); + atomic_dec(&mpriv->active_cmds); + mutex_unlock(&c->mtx); + + /* check mpriv to clean cmd */ + mutex_lock(&mpriv->mtx); + mpriv->mdev->plat_funcs->release_cmd(mpriv); + mutex_unlock(&mpriv->mtx); + + /* put cmd execution ref */ + mdw_cmd_put(c); + mdw_trace_end(); + + return 0; +} + +static void mdw_cmd_trigger_func(struct work_struct *wk) +{ + struct mdw_cmd *c = + container_of(wk, struct mdw_cmd, t_wk); + int ret = 0; + + if (c->wait_fence) { + dma_fence_wait(c->wait_fence, false); + dma_fence_put(c->wait_fence); + } + + mdw_flw_debug("s(0x%llx) c(0x%llx) wait fence done, start run\n", + (uint64_t)c->mpriv, c->kid); + mutex_lock(&c->mtx); + ret = mdw_cmd_run(c->mpriv, c); + mutex_unlock(&c->mtx); + + /* put cmd execution ref */ + if (ret) { + atomic_dec(&c->is_running); + mdw_cmd_put(c); + } +} + +static struct mdw_cmd *mdw_cmd_create(struct mdw_fpriv *mpriv, + union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL; + + mdw_trace_begin("apumdw:cmd_create|s:0x%llx", (uint64_t)mpriv); + + /* check num subcmds maximum */ + if (in->exec.num_subcmds > MDW_SUBCMD_MAX) { + mdw_drv_err("too much subcmds(%u)\n", in->exec.num_subcmds); + goto out; + } + + /* alloc mdw cmd */ + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + goto out; + + mutex_init(&c->mtx); + INIT_LIST_HEAD(&c->map_invokes); + c->mpriv = mpriv; + atomic_set(&c->is_running, 0); + + /* setup cmd info */ + c->pid = task_pid_nr(current); + c->tgid = task_tgid_nr(current); + c->kid = (uint64_t)c; + c->uid = in->exec.uid; + get_task_comm(c->comm, current); + c->priority = in->exec.priority; + c->hardlimit = in->exec.hardlimit; + c->softlimit = in->exec.softlimit; + c->power_save = in->exec.power_save; + c->power_plcy = in->exec.power_plcy; + c->power_dtime = in->exec.power_dtime; + c->fastmem_ms = in->exec.fastmem_ms; + c->app_type = in->exec.app_type; + c->num_subcmds = in->exec.num_subcmds; + c->num_links = in->exec.num_links; + c->exec_infos = mdw_mem_get(mpriv, in->exec.exec_infos); + if (!c->exec_infos) { + mdw_drv_err("get exec info fail\n"); + goto free_cmd; + } + + /* check input params */ + if (mdw_cmd_sanity_check(c)) { + mdw_drv_err("cmd sanity check fail\n"); + goto put_execinfos; + } + + /* subcmds/ksubcmds */ + c->subcmds = kzalloc(c->num_subcmds * sizeof(*c->subcmds), GFP_KERNEL); + if (!c->subcmds) + goto put_execinfos; + if (copy_from_user(c->subcmds, (void __user *)in->exec.subcmd_infos, + c->num_subcmds * sizeof(*c->subcmds))) { + mdw_drv_err("copy subcmds fail\n"); + goto free_subcmds; + } + if (mdw_cmd_sc_sanity_check(c)) { + mdw_drv_err("sc sanity check fail\n"); + goto free_subcmds; + } + + c->ksubcmds = kzalloc(c->num_subcmds * sizeof(*c->ksubcmds), + GFP_KERNEL); + if (!c->ksubcmds) + goto free_subcmds; + + /* adj matrix */ + c->adj_matrix = kzalloc(c->num_subcmds * + c->num_subcmds * sizeof(uint8_t), GFP_KERNEL); + if (!c->adj_matrix) + goto free_ksubcmds; + if (copy_from_user(c->adj_matrix, (void __user *)in->exec.adj_matrix, + (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)))) { + mdw_drv_err("copy adj matrix fail\n"); + goto free_adj; + } + if (g_mdw_klog & MDW_DBG_CMD) { + print_hex_dump(KERN_INFO, "[apusys] adj matrix: ", + DUMP_PREFIX_OFFSET, 16, 1, c->adj_matrix, + c->num_subcmds * c->num_subcmds, 0); + } + if (mdw_cmd_adj_check(c)) + goto free_adj; + + /* link */ + if (c->num_links) { + c->links = kcalloc(c->num_links, sizeof(*c->links), GFP_KERNEL); + if (!c->links) + goto free_adj; + if (copy_from_user(c->links, (void __user *)in->exec.links, + c->num_links * sizeof(*c->links))) { + mdw_drv_err("copy links fail\n"); + goto free_link; + } + } + if (mdw_cmd_link_check(c)) + goto free_link; + + /* create infos */ + if (mdw_cmd_create_infos(mpriv, c)) { + mdw_drv_err("create cmd info fail\n"); + goto free_link; + } + + c->mpriv->get(c->mpriv); + c->complete = mdw_cmd_complete; + INIT_WORK(&c->t_wk, &mdw_cmd_trigger_func); + kref_init(&c->ref); + mdw_cmd_show(c, mdw_drv_debug); + + goto out; + +free_link: + kfree(c->links); +free_adj: + kfree(c->adj_matrix); +free_ksubcmds: + kfree(c->ksubcmds); +free_subcmds: + kfree(c->subcmds); +put_execinfos: + mdw_mem_put(mpriv, c->exec_infos); +free_cmd: + kfree(c); + c = NULL; +out: + mdw_trace_end(); + return c; +} + +static int mdw_cmd_ioctl_run_v3(struct mdw_fpriv *mpriv, union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL, *priv_c = NULL; + struct sync_file *sync_file = NULL; + int ret = 0, fd = 0, wait_fd = 0, is_running = 0; + + mdw_trace_begin("apumdw:user_run"); + + /* get wait fd */ + wait_fd = in->exec.fence; + + mutex_lock(&mpriv->mtx); + /* get stale cmd */ + c = (struct mdw_cmd *)idr_find(&mpriv->cmds, in->id); + if (!c) { + /* no stale cmd, create cmd */ + mdw_cmd_debug("s(0x%llx) create new\n", (uint64_t)mpriv); + } else if (in->op == MDW_CMD_IOCTL_RUN_STALE) { + is_running = atomic_read(&c->is_running); + if (is_running) { + mdw_drv_err("s(0x%llx) c(0x%llx) is running(%d), can't execute again\n", + (uint64_t)mpriv, (uint64_t)c, is_running); + ret = -ETXTBSY; + goto out; + } + /* run stale cmd */ + mdw_cmd_debug("s(0x%llx) run stale(0x%llx)\n", + (uint64_t)mpriv, (uint64_t)c); + goto exec; + } else { + /* release stale cmd and create new */ + mdw_cmd_debug("s(0x%llx) delete stale(0x%llx) and create new\n", + (uint64_t)mpriv, (uint64_t)c); + priv_c = c; + c = NULL; + if (priv_c != idr_remove(&mpriv->cmds, priv_c->id)) { + mdw_drv_warn("remove cmd idr conflict(0x%llx/%d)\n", + priv_c->kid, priv_c->id); + } + } + + /* create cmd */ + c = mdw_cmd_create(mpriv, args); + if (!c) { + mdw_drv_err("create cmd fail\n"); + ret = -EINVAL; + goto out; + } + memset(args, 0, sizeof(*args)); + + /* alloc idr */ + c->id = idr_alloc(&mpriv->cmds, c, MDW_CMD_IDR_MIN, MDW_CMD_IDR_MAX, GFP_KERNEL); + if (c->id < MDW_CMD_IDR_MIN) { + mdw_drv_err("alloc idr fail(%d)\n", c->id); + goto delete_cmd; + } + +exec: + mutex_lock(&c->mtx); + mdw_cmd_trace(c, MDW_CMD_ENQUE); + /* get sync_file fd */ + fd = get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) { + mdw_drv_err("get unused fd fail\n"); + ret = -EINVAL; + goto delete_idr; + } + if (mdw_fence_init(c, fd)) { + mdw_drv_err("cmd init fence fail\n"); + goto put_fd; + } + sync_file = sync_file_create(&c->fence->base_fence); + if (!sync_file) { + mdw_drv_err("create sync file fail\n"); + dma_fence_put(&c->fence->base_fence); + ret = -ENOMEM; + goto put_fd; + } + + /* get cmd execution ref */ + atomic_inc(&c->is_running); + mdw_cmd_get(c); + + /* check wait fence from other module */ + mdw_flw_debug("s(0x%llx)c(0x%llx) wait fence(%d)...\n", + (uint64_t)c->mpriv, c->kid, wait_fd); + c->wait_fence = sync_file_get_fence(wait_fd); + if (!c->wait_fence) { + mdw_flw_debug("s(0x%llx)c(0x%llx) no wait fence, trigger directly\n", + (uint64_t)c->mpriv, c->kid); + ret = mdw_cmd_run(mpriv, c); + } else { + /* wait fence from wq */ + schedule_work(&c->t_wk); + } + + if (ret) { + /* put cmd execution ref */ + atomic_dec(&c->is_running); + mdw_cmd_put(c); + goto put_file; + } + + /* assign fd */ + fd_install(fd, sync_file->file); + + /* get ref for cmd exec */ + atomic_inc(&mpriv->active_cmds); + + /* return fd */ + args->out.exec.fence = fd; + args->out.exec.id = c->id; + mdw_flw_debug("async fd(%d) id(%d)\n", fd, c->id); + mutex_unlock(&c->mtx); + goto out; + +put_file: + fput(sync_file->file); +put_fd: + put_unused_fd(fd); +delete_idr: + if (c != idr_remove(&mpriv->cmds, c->id)) + mdw_drv_warn("remove cmd idr conflict(0x%llx/%d)\n", c->kid, c->id); + mutex_unlock(&c->mtx); +delete_cmd: + mdw_cmd_delete(c); +out: + mutex_unlock(&mpriv->mtx); + if (priv_c) + mdw_cmd_delete_async(priv_c); + + mdw_trace_end(); + + return ret; +} +int mdw_cmd_ioctl_v3(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_cmd_args *args = (union mdw_cmd_args *)data; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op::%d\n", (uint64_t)mpriv, args->in.op); + + switch (args->in.op) { + case MDW_CMD_IOCTL_RUN: + case MDW_CMD_IOCTL_RUN_STALE: + ret = mdw_cmd_ioctl_run_v3(mpriv, args); + break; + case MDW_CMD_IOCTL_DEL: + ret = mdw_cmd_ioctl_del(mpriv, args); + break; + + default: + ret = -EINVAL; + break; + } + mdw_flw_debug("done\n"); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v4.c b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v4.c new file mode 100644 index 0000000000000..138e6fe0e7f46 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/cmd/mdw_cmd_v4.c @@ -0,0 +1,1187 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mdw_trace.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "linux/soc/mediatek/apummu_export.h" +#include "rv/mdw_rv_tag.h" +#include "mdw_ext_export.h" +#include "linux/soc/mediatek/apu_mem_export.h" +#include "linux/soc/mediatek/apu_mem_def.h" + +/* 64-bit execid : [world(4bit) | session_id(28bit) | counter(32bit)] */ +#define mdw_world (1ULL) +#define MDW_CMD_GEN_INFID(session, cnt) ((mdw_world << 60) | ((session & 0xfffffff) << 32) \ + | (cnt & 0xffffffff)) + +/* 64-bit sync info : [cbfc vid(32bit) | cbfc_en(16bit) | hse_en(16bit)] */ +#define MDW_CMD_GEN_SYNC_INFO(vid, cbfc_en, hse_en) ((vid << 32) | ( cbfc_en << 16) \ + | (hse_en)) + +int mdw_cmd_get_cmdbufs_with_apummu(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + unsigned int i = 0, j = 0, ofs = 0; + int ret = -EINVAL; + struct mdw_subcmd_kinfo *ksubcmd = NULL; + struct mdw_mem *m = NULL; + struct apusys_cmdbuf *acbs = NULL; + + mdw_trace_begin("apumdw:cbs_get|c:0x%llx num_subcmds:%u num_cmdbufs:%u", + c->kid, c->num_subcmds, c->num_cmdbufs); + + if (!c->size_cmdbufs || c->cmdbufs) + goto out; + + c->cmdbufs = mdw_mem_pool_alloc(&mpriv->cmd_buf_pool, c->size_cmdbufs, + MDW_DEFAULT_ALIGN); + if (!c->cmdbufs) { + mdw_drv_err("s(0x%llx)c(0x%llx) alloc buffer for duplicate fail\n", + (uint64_t) mpriv, c->kid); + ret = -ENOMEM; + goto out; + } + + /* alloc mem for duplicated cmdbuf */ + for (i = 0; i < c->num_subcmds; i++) { + mdw_cmd_debug("sc(0x%llx-%u) #cmdbufs(%u)\n", + c->kid, i, c->ksubcmds[i].info->num_cmdbufs); + + acbs = kcalloc(c->ksubcmds[i].info->num_cmdbufs, sizeof(*acbs), GFP_KERNEL); + if (!acbs) + goto free_cmdbufs; + + ksubcmd = &c->ksubcmds[i]; + for (j = 0; j < ksubcmd->info->num_cmdbufs; j++) { + /* calc align */ + if (ksubcmd->cmdbufs[j].align) + ofs = MDW_ALIGN(ofs, ksubcmd->cmdbufs[j].align); + else + ofs = MDW_ALIGN(ofs, MDW_DEFAULT_ALIGN); + + mdw_cmd_debug("sc(0x%llx-%u) cb#%u offset(%u)\n", + c->kid, i, j, ofs); + + /* get mem from handle */ + m = mdw_mem_get(mpriv, ksubcmd->cmdbufs[j].handle); + if (!m) { + mdw_drv_err("sc(0x%llx-%u) cb#%u(%llu) get fail\n", + c->kid, i, j, + ksubcmd->cmdbufs[j].handle); + ret = -EINVAL; + goto free_cmdbufs; + } + /* check mem boundary */ + if (m->vaddr == NULL || + ksubcmd->cmdbufs[j].size != m->size) { + mdw_drv_err("sc(0x%llx-%u) cb#%u invalid range(%p/%u/%llu)\n", + c->kid, i, j, m->vaddr, + ksubcmd->cmdbufs[j].size, + m->size); + ret = -EINVAL; + goto free_cmdbufs; + } + + /* cmdbuf copy in */ + if (ksubcmd->cmdbufs[j].direction != MDW_CB_OUT) { + mdw_trace_begin("apumdw:cbs_copy_in|cb:%u-%u size:%u type:%u", + i, j, + ksubcmd->cmdbufs[j].size, + ksubcmd->info->type); + memcpy(c->cmdbufs->vaddr + ofs, + m->vaddr, + ksubcmd->cmdbufs[j].size); + mdw_trace_end(); + } + + /* record buffer info */ + ksubcmd->ori_cbs[j] = m; + ksubcmd->kvaddrs[j] = + (uint64_t)(c->cmdbufs->vaddr + ofs); + ksubcmd->daddrs[j] = + (uint64_t)(c->cmdbufs->device_va + ofs); + ofs += ksubcmd->cmdbufs[j].size; + + mdw_cmd_debug("sc(0x%llx-%u) cb#%u (0x%llx/0x%llx/%u)\n", + c->kid, i, j, + ksubcmd->kvaddrs[j], + ksubcmd->daddrs[j], + ksubcmd->cmdbufs[j].size); + + acbs[j].kva = (void *)ksubcmd->kvaddrs[j]; + acbs[j].size = ksubcmd->cmdbufs[j].size; + } + + mdw_trace_begin("apumdw:dev validation|c:0x%llx type:%u", + c->kid, ksubcmd->info->type); + ret = mdw_dev_validation(mpriv, ksubcmd->info->type, + c, acbs, ksubcmd->info->num_cmdbufs); + mdw_trace_end(); + kfree(acbs); + acbs = NULL; + if (ret) { + mdw_drv_err("sc(0x%llx-%u) dev(%u) validate cb(%u) fail(%d)\n", + c->kid, i, ksubcmd->info->type, ksubcmd->info->num_cmdbufs, ret); + goto free_cmdbufs; + } + } + + /* handle apummu table */ + ofs = MDW_ALIGN(ofs, MDW_DEFAULT_ALIGN); + if ((c->size_apummutable + ofs) == c->size_cmdbufs) { + mdw_cmd_debug("apummu table kva(0x%llx) copy to cmdbuf tail kva(0x%llx)\n", + (uint64_t)c->tbl_kva, (uint64_t)c->cmdbufs->vaddr + ofs); + mdw_trace_begin("apumdw:apummutable_copy_in|size:%u", + c->size_apummutable); + memcpy(c->cmdbufs->vaddr + ofs, + c->tbl_kva, + c->size_apummutable); + c->cmdbufs->tbl_daddr = (uint32_t)(long)(c->cmdbufs->device_va + ofs); + mdw_trace_end(); + mdw_cmd_debug("apummu table copy done tbl iova(0x%x) cmdbuf tail iova(0x%llx)\n", + c->cmdbufs->tbl_daddr, (uint64_t)c->cmdbufs->device_va + ofs); + } else { + mdw_drv_err("c->size_apummutable(%u) + ofs(%u) != c->size_cmdbufs(%u), tbl_kva(0x%llx)\n", + c->size_apummutable, ofs, c->size_cmdbufs, (uint64_t)c->tbl_kva); + } + + /* flush cmdbufs */ + if (mdw_mem_flush(mpriv, c->cmdbufs)) + mdw_drv_warn("s(0x%llx) c(0x%llx) flush cmdbufs(%llu) fail\n", + (uint64_t)mpriv, c->kid, c->cmdbufs->size); + + ret = 0; + goto out; + +free_cmdbufs: + mdw_cmd_put_cmdbufs(mpriv, c); + kfree(acbs); +out: + mdw_cmd_debug("ret(%d)\n", ret); + mdw_trace_end(); + return ret; +} + +static void mdw_cmd_update_einfos(struct mdw_cmd *c) +{ + c->end_ts = sched_clock(); + c->einfos->c.total_us = div_u64(c->end_ts - c->start_ts, 1000); + c->einfos->c.inference_id = c->inference_id; +} + +static void mdw_cmd_execinfo_out(struct mdw_cmd *c) +{ + struct mdw_fpriv *mpriv = c->mpriv; + struct mdw_device *mdev = c->mpriv->mdev; + + /* copy exec info */ + mdev->plat_funcs->cp_execinfo(c); + + /* copy cmdbuf to user */ + mdw_cmd_cmdbuf_out(mpriv, c); + + /* update einfos */ + mdw_cmd_update_einfos(c); +} + +static int mdw_cmd_history_tbl_create(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_cmd_history_tbl *ch_tbl = NULL; + int ret = 0; + + /* alloc cmd history */ + ch_tbl = kzalloc(sizeof(*ch_tbl), GFP_KERNEL); + if (!ch_tbl) { + ret = -ENOMEM; + goto out; + } + + /* alloc subcmd history */ + ch_tbl->h_sc_einfo = + kcalloc(c->num_subcmds, sizeof(*ch_tbl->h_sc_einfo), GFP_KERNEL); + + /* assign basic info */ + ch_tbl->uid = c->uid; + ch_tbl->num_subcmds = c->num_subcmds; + + /* add history tbl node to list */ + mutex_lock(&mpriv->ch_mtx); + list_add_tail(&ch_tbl->ch_tbl_node , &mpriv->ch_list); + mutex_unlock(&mpriv->ch_mtx); + + if (!ch_tbl->h_sc_einfo) { + ret = -ENOMEM; + goto out; + } + + mdw_flw_debug("create cmd history done\n"); + +out: + return ret; +} + +static bool mdw_cmd_exec_time_check(uint64_t h_exec_time, uint64_t exec_time) +{ + uint64_t exec_time_th = 0; + + exec_time_th = MDW_EXECTIME_TOLERANCE_TH(h_exec_time); + if (abs(exec_time - h_exec_time) < exec_time_th) + return true; + + return false; +} + +static void mdw_cmd_poll_cmd(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_device *mdev = mpriv->mdev; + bool poll_ret = false; + + poll_ret = mdev->plat_funcs->poll_cmd(c); + + if (poll_ret) { + c->cmd_state = MDW_PERF_CMD_DONE; + mdw_cmd_execinfo_out(c); + } +} + +static int mdw_cmd_run(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_device *mdev = mpriv->mdev; + struct dma_fence *f = &c->fence->base_fence; + struct mdw_cmd_history_tbl *ch_tbl = NULL; + int ret = 0; + uint64_t poll_timeout = MDW_POLL_TIMEOUT; + + mdw_cmd_show(c, mdw_cmd_debug); + + c->start_ts = sched_clock(); + atomic_inc(&mdev->cmd_running); + ret = mdev->plat_funcs->run_cmd(mpriv, c); + if (ret) { + mdw_drv_err("s(0x%llx) run cmd(0x%llx) fail(%d)\n", + (uint64_t) c->mpriv, c->kid, ret); + dma_fence_set_error(f, ret); + if (dma_fence_signal(f)) { + mdw_drv_warn("c(0x%llx) signal fence fail\n", (uint64_t)c); + if (f->ops->get_timeline_name && f->ops->get_driver_name) { + mdw_drv_warn(" fence name(%s-%s)\n", + f->ops->get_driver_name(f), f->ops->get_timeline_name(f)); + } + } + dma_fence_put(f); + /* power off */ + atomic_dec(&mdev->cmd_running); + c->end_ts = sched_clock(); + } else { + mdw_flw_debug("s(0x%llx) cmd(0x%llx) run\n", + (uint64_t)c->mpriv, c->kid); + if (c->power_plcy == MDW_POWERPOLICY_PERFORMANCE) { + ch_tbl = mdw_cmd_ch_tbl_find(c); + if (!ch_tbl) + goto out; + + if (g_mdw_poll_timeout) + poll_timeout = g_mdw_poll_timeout; + + if (ch_tbl->h_exec_time > poll_timeout) + goto out; + + if (ch_tbl->h_exec_time) + usleep_range(MDW_POLLTIME_SLEEP_TH(ch_tbl->h_exec_time), + MDW_POLLTIME_SLEEP_TH(ch_tbl->h_exec_time)+10); + mdw_cmd_poll_cmd(mpriv, c); + } + } +out: + return ret; +} + +struct mdw_cmd_history_tbl *mdw_cmd_ch_tbl_find(struct mdw_cmd *c) +{ + struct mdw_cmd_history_tbl *ch_tbl = NULL; + struct mdw_fpriv *mpriv = c->mpriv; + + mutex_lock(&mpriv->ch_mtx); + list_for_each_entry(ch_tbl, &mpriv->ch_list, ch_tbl_node) { + if(ch_tbl->uid == c->uid) { + mdw_flw_debug("find ch_tbl uid(0x%llx)\n", c->uid); + goto out; + } + } + ch_tbl = NULL; + +out: + mutex_unlock(&mpriv->ch_mtx); + return ch_tbl; +} + +void mdw_cmd_history_init(struct mdw_device *mdev) +{ + mdev->heap.data = mdev->predict_cmd_ts; + mdev->heap.nr = 0; + mdev->heap.size = ARRAY_SIZE(mdev->predict_cmd_ts); +} + +void mdw_cmd_history_deinit(struct mdw_device *mdev) +{ +} + +static uint64_t mdw_cmd_iptime_cal(uint64_t his_iptime, uint64_t new_iptime) +{ + uint64_t iptime = 0; + + iptime = max(his_iptime, new_iptime); + + mdw_cmd_debug("history iptime(%llu)", iptime); + + return iptime; +} + +static uint64_t mdw_cmd_period_avg(uint64_t old_period, uint64_t new_period) +{ + uint64_t period = 0; + + period = div_u64(old_period + new_period, 2); + + return period; +} + +static bool mdw_cmd_iptime_check(uint64_t h_iptime, uint64_t new_iptime) +{ + uint64_t interval_th = 0; + + if (h_iptime == 0) + goto out; + + interval_th = MDW_IPTIME_TOLERANCE_TH(h_iptime); + if (abs(new_iptime - h_iptime) < interval_th) + return true; + +out: + return false; +} + +static bool mdw_cmd_period_check(uint64_t old_period, uint64_t new_period) +{ + uint64_t interval_th = 0; + + interval_th = MDW_PERIOD_TOLERANCE_TH(old_period); + if (abs(new_period - old_period) < interval_th) + return true; + + return false; +} + +//-------------------------------------------- + +static void mdw_swap_uint64(void *lhs, void *rhs) +{ + uint64_t temp = *(uint64_t *)lhs; + + *(uint64_t *)lhs = *(uint64_t *)rhs; + *(uint64_t *)rhs = temp; +} + +static bool mdw_less_than(const void *lhs, const void *rhs) +{ + return *(uint64_t *)lhs < *(uint64_t *)rhs; +} + +static const struct min_heap_callbacks mdw_min_heap_funcs = { + .elem_size = sizeof(uint64_t), + .less = mdw_less_than, + .swp = mdw_swap_uint64, +}; + +//-------------------------------------------- + + +static void mdw_cmd_history_check_interval(struct mdw_cmd_history_tbl *ch_tbl, + struct mdw_cmd *c) +{ + uint64_t interval = 0; + + /* no history cmd */ + if (!ch_tbl->h_start_ts) + return; + + /* cmd overlap case */ + if (c->start_ts <= ch_tbl->h_end_ts) { + ch_tbl->h_period = 0; + ch_tbl->period_cnt = 0; + return; + } + + interval = (c->start_ts - ch_tbl->h_start_ts); + + /* initial h_period */ + if (!ch_tbl->h_period) { + mdw_cmd_debug("init period_ts(%llu) interval(%llu)\n", + ch_tbl->h_period, interval); + ch_tbl->h_period = interval; + ch_tbl->period_cnt++; + return; + } + + /* check interval time and cal h_period */ + if (mdw_cmd_period_check(ch_tbl->h_period, interval)) { + mdw_cmd_debug("period h_period_ts(%llu) interval(%llu)\n", + ch_tbl->h_period, interval); + ch_tbl->h_period = + mdw_cmd_period_avg(ch_tbl->h_period, interval); + if (ch_tbl->period_cnt < MDW_NUM_HISTORY) + ch_tbl->period_cnt++; + } else { + mdw_cmd_debug("no period h_period_ts(%llu) interval(%llu)\n", + ch_tbl->h_period, interval); + ch_tbl->h_period = interval; + ch_tbl->period_cnt = 1; + } +} + +static void mdw_cmd_min_heap_sanity_check(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + + if (mdev->heap.nr >= MDW_NUM_PREDICT_CMD) + mdw_cmd_history_reset(c->mpriv); +} + +static int mdw_cmd_record(struct mdw_cmd *c) +{ + struct mdw_cmd_history_tbl *ch_tbl = NULL; + struct mdw_device *mdev = c->mpriv->mdev; + struct mdw_subcmd_exec_info *sc_einfo = NULL; + int i = 0, ret = -EINVAL; + uint32_t h_iptime = 0, c_iptime = 0; + uint32_t producer_idx = 0, consumer_idx = 0, cbfc_en = 0; + uint64_t predict_start_ts = 0, sc_sync_info = 0; + int8_t vid_array[MDW_SUBCMD_MAX] = {0}; + int64_t vid = 0, vsid = 0; + + memset(vid_array, -1, sizeof(vid_array)); + + /* check history table */ + ch_tbl = mdw_cmd_ch_tbl_find(c); + if (!ch_tbl) + goto out; + + /* Setup subcmd history */ + sc_einfo = &c->einfos->sc; + if (!sc_einfo) + goto out; + + /* assign vid for check cbfc enable */ + for (i = 0; i < c->num_links; i++) { + producer_idx = c->links[i].producer_idx; + consumer_idx = c->links[i].consumer_idx; + if (consumer_idx < MDW_SUBCMD_MAX && producer_idx < MDW_SUBCMD_MAX) { + vid_array[producer_idx] = c->links[i].vid; + vid_array[consumer_idx] = c->links[i].vid; + } else { + mdw_drv_err("unexcepted producer_idx(%d) consumer_idx(%d)\n", + producer_idx, consumer_idx); + } + } + + /* calculate history ip_time */ + for (i = 0; i < c->num_subcmds; i++) { + h_iptime = ch_tbl->h_sc_einfo[i].ip_time; + c_iptime = sc_einfo[i].ip_time; + vsid = sc_einfo[i].vsid; + + if (vid_array[i] != -1 ) { + cbfc_en = 1; + vid = vid_array[i]; + } else { + cbfc_en = 0; + vid = 0; + } + + sc_sync_info = MDW_CMD_GEN_SYNC_INFO(vid, cbfc_en, c->subcmds[i].hse_en); + + if (sc_einfo[i].was_preempted || sc_einfo[i].ret) { + mdw_flw_debug("sc was preempted or failed, skip this iptime\n"); + mdw_subcmd_trace(c, i, vsid, ch_tbl->h_sc_einfo[i].ip_time, sc_sync_info, MDW_CMD_SCHED); + continue; + } + + if (mdw_cmd_iptime_check(h_iptime, c_iptime)) { + ch_tbl->h_sc_einfo[i].ip_time = + mdw_cmd_iptime_cal(h_iptime, c_iptime); + } else { + ch_tbl->h_sc_einfo[i].ip_time = c_iptime; + } + mdw_subcmd_trace(c, i, vsid, ch_tbl->h_sc_einfo[i].ip_time, sc_sync_info ,MDW_CMD_SCHED); + } + + /* calculate interval time */ + mdw_cmd_history_check_interval(ch_tbl, c); + + /* calculate predict cmd_start_ts and push to min heap */ + if (ch_tbl->period_cnt >= MDW_NUM_HISTORY) { + predict_start_ts = c->start_ts + ch_tbl->h_period; + mdw_cmd_min_heap_sanity_check(c); + min_heap_push(&mdev->heap, &predict_start_ts, &mdw_min_heap_funcs); + mdw_cmd_debug("predict_start_ts(%llu) nr(%d)", + mdev->predict_cmd_ts[0], mdev->heap.nr); + } + + /* record cmd end_ts */ + ch_tbl->h_start_ts = c->start_ts; + ch_tbl->h_end_ts = c->end_ts; + ret = 0; + +out: + return ret; +} + +static bool mdw_cmd_is_perf_mode(struct mdw_cmd *c) +{ + /* check cmd mode */ + if (c->power_plcy == MDW_POWERPOLICY_PERFORMANCE || + c->power_plcy == MDW_POWERPOLICY_SUSTAINABLE) { + mdw_flw_debug("cmd is performace policy\n"); + /* reset history */ + mdw_cmd_history_reset(c->mpriv); + return true; + } + return false; +} + +static uint64_t mdw_cmd_get_predict(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + uint64_t i = 0, predict_start_ts = 0; + int heap_nr = 0; + + heap_nr = mdev->heap.nr; + for (i = 0; i < heap_nr; i++) { + predict_start_ts = mdev->predict_cmd_ts[0]; + if (c->end_ts >= predict_start_ts) { + mdw_flw_debug("predict cmd start_ts(%llu) is invalid\n", + predict_start_ts); + min_heap_pop(&mdev->heap, &mdw_min_heap_funcs); + predict_start_ts = 0; + continue; + } else { + mdw_flw_debug("predict cmd start_ts(%llu) is valid\n", + predict_start_ts); + break; + } + } + + return predict_start_ts; +} + +static bool mdw_cmd_predict(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + uint64_t predict_idle = 0, predict_start_ts = 0; + int cmd_running = 0; + bool ret = false; // dtime management + + /* check predict cmd exist */ + if (!mdev->heap.nr) { + mdw_flw_debug("no enough history\n"); + goto out; + } + + /* check heap predict start_ts with cmd */ + predict_start_ts = mdw_cmd_get_predict(c); + + if (predict_start_ts == 0) { + mdw_flw_debug("no valid predict cmd in heap\n"); + goto out; + } + + /* check predict idle time */ + predict_idle = div_u64(predict_start_ts - c->end_ts, 1000); + if (predict_idle > mdev->power_gain_time_us) { + cmd_running = atomic_read(&mdev->cmd_running); + if (cmd_running) { + mdw_flw_debug("Disable fast power off\n"); + } else { + mdw_flw_debug("Maybe enable fast power off\n"); + ret = true; // need check dtime setting + } + } + +out: + return ret; +} + +static int mdw_cmd_complete(struct mdw_cmd *c, int ret) +{ + struct dma_fence *f = &c->fence->base_fence; + struct mdw_fpriv *mpriv = c->mpriv; + struct mdw_device *mdev = c->mpriv->mdev; + struct mdw_cmd_history_tbl *ch_tbl = NULL; + bool need_dtime_check = false; + uint64_t ts1 = 0, ts2 = 0; + int power_dtime = c->power_dtime; + + ts1 = sched_clock(); + mdw_trace_begin("apumdw:cmd_complete|cmd:0x%llx/0x%llx", c->uid, c->kid); + mutex_lock(&c->mtx); + ts2 = sched_clock(); + c->enter_complt_time = ts2 - ts1; + + ts1 = sched_clock(); + c->pb_put_time = ts1 - ts2; + + /* execinfo out */ + if (c->cmd_state == MDW_PERF_CMD_INIT) + mdw_cmd_execinfo_out(c); + else + c->cmd_state = MDW_PERF_CMD_INIT; + + ts2 = sched_clock(); + c->cmdbuf_out_time = ts2 - ts1; + + atomic_dec(&mdev->cmd_running); + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx/0x%llx) ret(%d) sc_rets(0x%llx) complete, pid(%d/%d)(%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, c->inference_id, + ret, c->einfos->c.sc_rets, + c->pid, c->tgid, task_pid_nr(current)); + + /* check subcmds return value */ + if (c->einfos->c.sc_rets) { + if (!ret) + ret = -EIO; + + mdw_cmd_check_rets(c, ret); + } else if (ret == -EBUSY) { + mdw_exception("uP busy:%s:ret(%d/0x%llx)pid(%d/%d)\n", + c->comm, ret, c->einfos->c.sc_rets, c->pid, c->tgid); + } + c->einfos->c.ret = ret; + + if (ret) { + mdw_drv_err("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, c->inference_id, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + dma_fence_set_error(f, ret); + + if (mdw_debug_on(MDW_DBG_EXP)) + mdw_exception("exec fail:%s:ret(%d/0x%llx)pid(%d/%d)\n", + c->comm, ret, c->einfos->c.sc_rets, c->pid, c->tgid); + } else { + mdw_flw_debug("s(0x%llx) c(%s/0x%llx/0x%llx/0x%llx/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + (uint64_t)mpriv, c->comm, c->uid, c->kid, c->rvid, c->inference_id, + ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + } + + /* signal done */ + c->fence = NULL; + if (dma_fence_signal(f)) { + mdw_drv_warn("c(0x%llx) signal fence fail\n", (uint64_t)c); + if (f->ops->get_timeline_name && f->ops->get_driver_name) { + mdw_drv_warn(" fence name(%s-%s)\n", + f->ops->get_driver_name(f), f->ops->get_timeline_name(f)); + } + } + dma_fence_put(f); + ts1 = sched_clock(); + c->handle_cmd_result_time = ts1 - ts2; + + /* get cmd history table */ + ch_tbl = mdw_cmd_ch_tbl_find(c); + if (!ch_tbl) + goto out; + + /* initial or update h_exec_time */ + if (!ch_tbl->h_exec_time || + mdw_cmd_exec_time_check(ch_tbl->h_exec_time, c->einfos->c.total_us)) { + ch_tbl->h_exec_time = c->einfos->c.total_us; + mdw_cmd_debug("h_exec_time(%llu)\n", ch_tbl->h_exec_time); + } + + /* check cmd mode */ + if (!mdw_cmd_is_perf_mode(c)) { + /* cmd record */ + ret = mdw_cmd_record(c); + if (ret) { + mdw_drv_err("record cmd fail(%d)\n", ret); + } else { + mutex_lock(&mdev->h_mtx); + need_dtime_check = mdw_cmd_predict(c); + mutex_unlock(&mdev->h_mtx); + } + } + /* check support power fast power on off */ + if (mdev->support_power_fast_on_off == false) { + mdw_flw_debug("no support power fast on off\n"); + goto out; + } + + /* check dtime setting */ + if (need_dtime_check) { + mdw_flw_debug("check user set dtime\n"); + /* check dtime setting */ + if (c->power_dtime > MAX_DTIME || !c->is_dtime_set) { + mdw_flw_debug("trigger fast power off directly\n"); + g_mdw_pwroff_cnt++; + mdw_trace_begin("apumdw:power_off|pwroff_cnt(%u)", g_mdw_pwroff_cnt); + power_dtime = 0; + mdw_trace_end(); + } + } + + if (mdw_dev->update_power_dtime) + mdw_dev->update_power_dtime(power_dtime); + + ts2 = sched_clock(); + c->load_aware_pwroff_time = ts2 - ts1; +out: + mdw_flw_debug("c(0x%llx) complete done\n", c->kid); + atomic_dec(&c->is_running); + complete(&c->cmplt); + mutex_unlock(&c->mtx); + + /* check mpriv to clean cmd */ + mutex_lock(&mpriv->mtx); + ts1 = sched_clock(); + c->enter_mpriv_release_time = ts1 - ts2; + atomic_dec(&mpriv->active_cmds); + mdev->plat_funcs->release_cmd(mpriv); + ts2 = sched_clock(); + c->mpriv_release_time = ts2 - ts1; + mutex_unlock(&mpriv->mtx); + mdw_cmd_deque_trace(c, MDW_CMD_DEQUE); + + /* put cmd execution ref */ + mdw_cmd_put(c); + mdw_trace_end(); + + return 0; +} + +static int mdw_cmd_wait_cmd_done(struct mdw_cmd *c) +{ + int ret = 0; + unsigned long timeout = msecs_to_jiffies(MDW_STALE_CMD_TIMEOUT); + + /* wait for cmd done */ + if (!wait_for_completion_timeout(&c->cmplt, timeout)) { + mdw_drv_err("s(0x%llx) c(0x%llx) cmd timeout\n", + (uint64_t)c->mpriv, c->kid); + ret = -ETIME; + } else { + mdw_flw_debug("c(0x%llx) cmd done", c->kid); + } + return ret; +} + +static void mdw_cmd_trigger_func(struct work_struct *wk) +{ + struct mdw_cmd *c = + container_of(wk, struct mdw_cmd, t_wk); + int ret = 0; + + if (c->wait_fence) { + dma_fence_wait(c->wait_fence, false); + dma_fence_put(c->wait_fence); + } + + mdw_flw_debug("s(0x%llx) c(0x%llx) wait fence done, start run\n", + (uint64_t)c->mpriv, c->kid); + mutex_lock(&c->mtx); + ret = mdw_cmd_run(c->mpriv, c); + mutex_unlock(&c->mtx); + + /* put cmd execution ref */ + if (ret) { + atomic_dec(&c->is_running); + mdw_cmd_put(c); + } +} + +static struct mdw_cmd *mdw_cmd_create(struct mdw_fpriv *mpriv, + union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL; + + mdw_trace_begin("apumdw:cmd_create|s:0x%llx", (uint64_t)mpriv); + + /* check num subcmds maximum */ + if (in->exec.num_subcmds > MDW_SUBCMD_MAX) { + mdw_drv_err("too much subcmds(%u)\n", in->exec.num_subcmds); + goto out; + } + + /* alloc mdw cmd */ + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + goto out; + + mutex_init(&c->mtx); + INIT_LIST_HEAD(&c->map_invokes); + c->mpriv = mpriv; + atomic_set(&c->is_running, 0); + + /* setup cmd info */ + c->pid = task_pid_nr(current); + c->tgid = task_tgid_nr(current); + c->kid = (uint64_t)c; + c->uid = in->exec.uid; + c->u_pid = in->exec.u_pid; + get_task_comm(c->comm, current); + c->priority = in->exec.priority; + c->hardlimit = in->exec.hardlimit; + c->softlimit = in->exec.softlimit; + c->power_save = in->exec.power_save; + c->power_plcy = in->exec.power_plcy; + c->power_dtime = in->exec.power_dtime; + c->power_etime = in->exec.power_etime; + c->fastmem_ms = in->exec.fastmem_ms; + c->app_type = in->exec.app_type; + c->num_subcmds = in->exec.num_subcmds; + c->num_links = in->exec.num_links; + c->inference_ms = in->exec.inference_ms; + c->tolerance_ms = in->exec.tolerance_ms; + c->is_dtime_set = in->exec.is_dtime_set; + c->exec_infos = mdw_mem_get(mpriv, in->exec.exec_infos); + if (!c->exec_infos) { + mdw_drv_err("get exec info fail\n"); + goto free_cmd; + } + + /* check input params */ + if (mdw_cmd_sanity_check(c)) { + mdw_drv_err("cmd sanity check fail\n"); + goto put_execinfos; + } + + /* subcmds/ksubcmds */ + c->subcmds = kzalloc(c->num_subcmds * sizeof(*c->subcmds), GFP_KERNEL); + if (!c->subcmds) + goto put_execinfos; + if (copy_from_user(c->subcmds, (void __user *)in->exec.subcmd_infos, + c->num_subcmds * sizeof(*c->subcmds))) { + mdw_drv_err("copy subcmds fail\n"); + goto free_subcmds; + } + if (mdw_cmd_sc_sanity_check(c)) { + mdw_drv_err("sc sanity check fail\n"); + goto free_subcmds; + } + + c->ksubcmds = kzalloc(c->num_subcmds * sizeof(*c->ksubcmds), + GFP_KERNEL); + if (!c->ksubcmds) + goto free_subcmds; + + /* adj matrix */ + c->adj_matrix = kzalloc(c->num_subcmds * + c->num_subcmds * sizeof(uint8_t), GFP_KERNEL); + if (!c->adj_matrix) + goto free_ksubcmds; + if (copy_from_user(c->adj_matrix, (void __user *)in->exec.adj_matrix, + (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)))) { + mdw_drv_err("copy adj matrix fail\n"); + goto free_adj; + } + if (g_mdw_klog & MDW_DBG_CMD) { + print_hex_dump(KERN_INFO, "[apusys] adj matrix: ", + DUMP_PREFIX_OFFSET, 16, 1, c->adj_matrix, + c->num_subcmds * c->num_subcmds, 0); + } + if (mdw_cmd_adj_check(c)) + goto free_adj; + + /* link */ + if (c->num_links) { + c->links = kcalloc(c->num_links, sizeof(*c->links), GFP_KERNEL); + if (!c->links) + goto free_adj; + if (copy_from_user(c->links, (void __user *)in->exec.links, + c->num_links * sizeof(*c->links))) { + mdw_drv_err("copy links fail\n"); + goto free_link; + } + } + if (mdw_cmd_link_check(c)) + goto free_link; + + /* create infos */ + if (mdw_cmd_create_infos(mpriv, c)) { + mdw_drv_err("create cmd info fail\n"); + goto free_link; + } + + c->mpriv->get(c->mpriv); + c->complete = mdw_cmd_complete; + + INIT_WORK(&c->t_wk, &mdw_cmd_trigger_func); + init_completion(&c->cmplt); + kref_init(&c->ref); + + /* get ext id */ + mdw_ext_cmd_get_id(c); + + mdw_cmd_show(c, mdw_drv_debug); + + goto out; + +free_link: + kfree(c->links); +free_adj: + kfree(c->adj_matrix); +free_ksubcmds: + kfree(c->ksubcmds); +free_subcmds: + kfree(c->subcmds); +put_execinfos: + mdw_mem_put(mpriv, c->exec_infos); +free_cmd: + kfree(c); + c = NULL; +out: + mdw_trace_end(); + return c; +} + +static void mdw_cmd_ch_tbl_sanity_check(struct mdw_fpriv *mpriv) +{ + if (mpriv->cmd_cnt > MDW_CMD_MAX) + mdw_flw_debug("session has %d cmd\n", mpriv->cmd_cnt); +} + +static void mdw_cmd_ch_tbl_sc_check(struct mdw_cmd_history_tbl *ch_tbl, + struct mdw_cmd *c) +{ + /* compare num_subcmds */ + if (ch_tbl->num_subcmds < c->num_subcmds) { + mdw_flw_debug("s(0x%llx) uid(0x%llx) del old ch_tbl and create new\n", + (uint64_t)c->mpriv, c->uid); + list_del(&ch_tbl->ch_tbl_node); + kfree(ch_tbl->h_sc_einfo); + kfree(ch_tbl); + mdw_cmd_history_tbl_create(c->mpriv, c); + } +} + +static int mdw_cmd_ioctl_run_v4(struct mdw_fpriv *mpriv, union mdw_cmd_args *args) +{ + struct mdw_cmd_in *in = (struct mdw_cmd_in *)args; + struct mdw_cmd *c = NULL, *priv_c = NULL; + struct sync_file *sync_file = NULL; + struct mdw_cmd_history_tbl *ch_tbl = NULL; + int ret = 0, fd = 0, wait_fd = 0, is_running = 0; + + mdw_trace_begin("apumdw:user_run"); + + /* get wait fd */ + wait_fd = in->exec.fence; + + mutex_lock(&mpriv->mtx); + /* get stale cmd */ + c = (struct mdw_cmd *)idr_find(&mpriv->cmds, in->id); + if (!c) { + /* no stale cmd, create cmd */ + mdw_cmd_debug("s(0x%llx) create new\n", (uint64_t)mpriv); + } else if (in->op == MDW_CMD_IOCTL_RUN_STALE) { + is_running = atomic_read(&c->is_running); + if (is_running) { + mdw_cmd_debug("s(0x%llx) c(0x%llx) is running(%d), wait cmd done\n", + (uint64_t)mpriv, (uint64_t)c, is_running); + mdw_cmd_get(c); + mutex_unlock(&mpriv->mtx); + ret = mdw_cmd_wait_cmd_done(c); + mutex_lock(&mpriv->mtx); + if (ret) { + mdw_cmd_put(c); + goto out; + } + } + /* run stale cmd */ + mdw_cmd_debug("s(0x%llx) run stale(0x%llx)\n", + (uint64_t)mpriv, (uint64_t)c); + goto exec; + } else { + /* release stale cmd and create new */ + mdw_cmd_debug("s(0x%llx) delete stale(0x%llx) and create new\n", + (uint64_t)mpriv, (uint64_t)c); + priv_c = c; + c = NULL; + if (priv_c != idr_remove(&mpriv->cmds, priv_c->id)) { + mdw_drv_warn("remove cmd idr conflict(0x%llx/%d)\n", + priv_c->kid, priv_c->id); + } + } + + /* create cmd */ + c = mdw_cmd_create(mpriv, args); + if (!c) { + mdw_drv_err("create cmd fail\n"); + ret = -EINVAL; + goto out; + } + + /* alloc idr */ + c->id = idr_alloc(&mpriv->cmds, c, MDW_CMD_IDR_MIN, MDW_CMD_IDR_MAX, GFP_KERNEL); + if (c->id < MDW_CMD_IDR_MIN) { + mdw_drv_err("alloc idr fail(%d)\n", c->id); + goto delete_cmd; + } + + if (in->op == MDW_CMD_IOCTL_ENQ) { + /* return input fence fd (enq no use fence) */ + memset(args, 0, sizeof(*args)); + args->out.exec.fence = wait_fd; + args->out.exec.id = c->id; + goto out; + } + + memset(args, 0, sizeof(*args)); + +exec: + mutex_lock(&c->mtx); + + /* handle cmd history */ + ch_tbl = mdw_cmd_ch_tbl_find(c); + if (ch_tbl) { + mdw_flw_debug("s(0x%llx) uid(0x%llx) check num subcmd\n", + (uint64_t)mpriv, c->uid); + mdw_cmd_ch_tbl_sc_check(ch_tbl, c); + } else { + mdw_flw_debug("s(0x%llx) uid(0x%llx) create ch_tbl\n", + (uint64_t)mpriv, c->uid); + mdw_cmd_history_tbl_create(mpriv, c); + mpriv->cmd_cnt++; + } + + /* ch_tbl sanity check */ + mdw_cmd_ch_tbl_sanity_check(mpriv); + + /* get sync_file fd */ + fd = get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) { + mdw_drv_err("get unused fd fail\n"); + ret = -EINVAL; + goto delete_idr; + } + if (mdw_fence_init(c, fd)) { + mdw_drv_err("cmd init fence fail\n"); + goto put_fd; + } + sync_file = sync_file_create(&c->fence->base_fence); + if (!sync_file) { + mdw_drv_err("create sync file fail\n"); + dma_fence_put(&c->fence->base_fence); + ret = -ENOMEM; + goto put_fd; + } + /* reinit completion */ + reinit_completion(&c->cmplt); + + /* get cmd execution ref */ + atomic_inc(&c->is_running); + mdw_cmd_get(c); + + /* put cmd execution ref when stale cmd wait */ + if (is_running) + mdw_cmd_put(c); + + /* generate cmd inference id */ + c->inference_id = MDW_CMD_GEN_INFID((uint64_t) mpriv, mpriv->counter++); + + /* mdw cmd tag : enqueue */ + mdw_cmd_trace(c, MDW_CMD_ENQUE); + + /* check wait fence from other module */ + mdw_flw_debug("s(0x%llx)c(0x%llx) wait fence(%d)...\n", + (uint64_t)c->mpriv, c->kid, wait_fd); + c->wait_fence = sync_file_get_fence(wait_fd); + if (!c->wait_fence) { + mdw_flw_debug("s(0x%llx)c(0x%llx) no wait fence, trigger directly\n", + (uint64_t)c->mpriv, c->kid); + ret = mdw_cmd_run(mpriv, c); + } else { + /* wait fence from wq */ + schedule_work(&c->t_wk); + } + + if (ret) { + /* put cmd execution ref */ + atomic_dec(&c->is_running); + mdw_cmd_put(c); + goto put_file; + } + + /* assign fd */ + fd_install(fd, sync_file->file); + + /* get ref for cmd exec */ + atomic_inc(&mpriv->active_cmds); + + /* return fd */ + args->out.exec.fence = fd; + args->out.exec.id = c->id; + args->out.exec.cmd_done_usr = c->cmd_state; + args->out.exec.ext_id = c->ext_id; + mdw_flw_debug("async fd(%d) id(%d) extid(0x%llx) inference_id(0x%llx)\n", + fd, c->id, c->ext_id, c->inference_id); + mutex_unlock(&c->mtx); + goto out; + +put_file: + fput(sync_file->file); +put_fd: + put_unused_fd(fd); +delete_idr: + if (c != idr_remove(&mpriv->cmds, c->id)) + mdw_drv_warn("remove cmd idr conflict(0x%llx/%d)\n", c->kid, c->id); + mutex_unlock(&c->mtx); +delete_cmd: + mdw_cmd_delete(c); +out: + mutex_unlock(&mpriv->mtx); + if (priv_c) + mdw_cmd_delete_async(priv_c); + + mdw_trace_end(); + + return ret; +} + +int mdw_cmd_ioctl_v4(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_cmd_args *args = (union mdw_cmd_args *)data; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op::%d\n", (uint64_t)mpriv, args->in.op); + + switch (args->in.op) { + case MDW_CMD_IOCTL_RUN: + case MDW_CMD_IOCTL_RUN_STALE: + case MDW_CMD_IOCTL_ENQ: + ret = mdw_cmd_ioctl_run_v4(mpriv, args); + break; + case MDW_CMD_IOCTL_DEL: + ret = mdw_cmd_ioctl_del(mpriv, args); + break; + + default: + ret = -EINVAL; + break; + } + mdw_flw_debug("done\n"); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.c b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.c new file mode 100644 index 0000000000000..2e7d629877526 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include "mdw.h" +#include "mdw_ext.h" +#include "mdw_ext_cmn.h" +#include "mdw_ext_export.h" +#include "mdw_ext_ioctl.h" + +#define MDWEXT_DEV_NAME "apuext" + +struct mdw_ext_device *mdw_ext_dev; + +void mdw_ext_lock(void) +{ + mutex_lock(&mdw_ext_dev->ext_mtx); +} + +void mdw_ext_unlock(void) +{ + mutex_unlock(&mdw_ext_dev->ext_mtx); +} + +static int mdw_ext_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int mdw_ext_close(struct inode *inode, struct file *filp) +{ + return 0; +} + +static const struct file_operations mdw_ext_fops = { + .owner = THIS_MODULE, + .open = mdw_ext_open, + .release = mdw_ext_close, + .unlocked_ioctl = mdw_ext_ioctl, + .compat_ioctl = mdw_ext_ioctl, +}; + +static struct miscdevice mdw_ext_misc_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = MDWEXT_DEV_NAME, + .fops = &mdw_ext_fops, +}; + +//---------------------------------------- +int mdw_ext_init(struct mdw_device *mdw_dev) +{ + int ret = -EINVAL; + + /* check support ext by version */ + if (mdw_dev) { + if (mdw_dev->mdw_ver < 4) { + ret = 0; + goto out; + } + } + + pr_info("%s register misc...\n", __func__); + if (misc_register(&mdw_ext_misc_dev)) { + pr_info("failed to register apu ext misc driver\n"); + goto out; + } + + /* alloc ext device */ + mdw_ext_dev = kzalloc(sizeof(*mdw_ext_dev), GFP_KERNEL); + if (mdw_ext_dev == NULL) + goto deregister_ext; + + mdw_ext_dev->misc_dev = &mdw_ext_misc_dev; + idr_init(&mdw_ext_dev->ext_ids); + mutex_init(&mdw_ext_dev->ext_mtx); + pr_info("%s register misc done\n", __func__); + + ret = 0; + + goto out; + +deregister_ext: + misc_deregister(&mdw_ext_misc_dev); +out: + return ret; +} + +void mdw_ext_deinit(void) +{ + /* free ext driver */ + if (mdw_ext_dev != NULL) { + misc_deregister(&mdw_ext_misc_dev); + kfree(mdw_ext_dev); + } +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.h b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.h new file mode 100644 index 0000000000000..041573a320e7b --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#ifndef __MTK_APUEXT_H__ +#define __MTK_APUEXT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#define MDW_EXT_IDR_MIN (1) +#define MDW_EXT_IDR_MAX (4096) + +struct mdw_ext_device { + struct miscdevice *misc_dev; + /* ext operation */ + struct idr ext_ids; + struct mutex ext_mtx; +}; + +long mdw_ext_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +int mdw_ext_cmd_ioctl(void *data); +int mdw_ext_hs_ioctl(void *data); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmd.c b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmd.c new file mode 100644 index 0000000000000..16fec3c555553 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmd.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include "mdw_ext.h" +#include "mdw_ext_cmn.h" +#include "mdw_ext_ioctl.h" +#include "mdw_ext_export.h" +#include "mdw_cmd.h" + +#define MDWEXT_IDKID2EXTID(id, kid) (((0xffffffff & (uint64_t)(task_tgid_nr(current))) << 32) \ + | ((0xffff & kid) << 16) | (0xffff & id)) +#define MDWEXT_EXTID2TGID(extid) (extid >> 32) +#define MDWEXT_EXTID2KID(extid) (0xffff & (extid >> 16)) +#define MDWEXT_EXTID2ID(extid) (0xffff & extid) +#define MDWEXT_KID16BIT(kid) (0xffff & kid) + +static inline int mdw_ext_cmd_sanity_check(struct mdw_cmd *c) +{ + if (MDWEXT_EXTID2KID(c->ext_id) != MDWEXT_KID16BIT(c->kid) || + MDWEXT_EXTID2ID(c->ext_id) < MDW_EXT_IDR_MIN || + MDWEXT_EXTID2ID(c->ext_id) > MDW_EXT_IDR_MAX) + return -EINVAL; + + return 0; +} + +void mdw_ext_cmd_get_id(struct mdw_cmd *c) +{ + int ret = 0; + char comm[16]; + + mdw_ext_lock(); + if (c->ext_id) { + mdwext_drv_warn("c(0x%llx) ext_id(0x%llx) already exist\n", c->kid, c->ext_id); + goto out; + } + + /* alloc idr */ + ret = idr_alloc_cyclic(&mdw_ext_dev->ext_ids, c, MDW_EXT_IDR_MIN, MDW_EXT_IDR_MAX, GFP_KERNEL); + if (ret < MDW_EXT_IDR_MIN) { + mdwext_drv_warn("driver alloc ext id fail(%d/%d~%d)\n", ret, MDW_EXT_IDR_MIN, MDW_EXT_IDR_MAX); + } else { + /* get id success, gen extid */ + c->ext_id = MDWEXT_IDKID2EXTID(ret, c->kid); + mdwext_cmd_debug("c(0x%llx) extid(0x%llx) tgid(%d:%s/%d:%s)\n", + c->kid, c->ext_id, task_tgid_nr(current), comm, c->tgid, c->comm); + } + +out: + mdw_ext_unlock(); +} + +void mdw_ext_cmd_put_id(struct mdw_cmd *c) +{ + if (c->mpriv->mdev->mdw_ver < 4) + return; + + mdwext_cmd_debug("c(0x%llx) extid(0x%llx) tgid(%d/%d)\n", + c->kid, c->ext_id, task_tgid_nr(current), c->tgid); + + /* don't need lock ext lock because mdw_cmd_put() already get mutex */ + if (mdw_ext_cmd_sanity_check(c)) { + mdwext_drv_warn("c(0x%llx) extid(0x%llx) not available, cmd tgid(%d)\n", + c->kid, c->ext_id, c->tgid); + } else { + idr_remove(&mdw_ext_dev->ext_ids, MDWEXT_EXTID2ID(c->ext_id)); + c->ext_id = 0; + } +} + +static int mdw_ext_cmd_ioctl_run(union mdw_ext_cmd_args *args) +{ + struct mdw_cmd *c = NULL; + union mdw_cmd_args c_args; + int ret = -EINVAL; + + mdw_ext_lock(); + /* find cmd */ + c = (struct mdw_cmd *)idr_find(&mdw_ext_dev->ext_ids, MDWEXT_EXTID2ID(args->in.ext_id)); + if (!c) { + mdwext_drv_err("invalid extid(0x%llx)\n", args->in.ext_id); + goto unlock_extlock; + } + + /* check support */ + if (c->mpriv->mdev->mdw_ver < 4) { + mdwext_drv_warn("no support mdw ext\n"); + goto unlock_extlock; + } + /* check cmd */ + if (c->ext_id != args->in.ext_id) { + mdwext_drv_err("c(0x%llx) extid not available(0x%llx/0x%llx)\n", + c->kid, args->in.ext_id, c->ext_id); + goto unlock_extlock; + } + if (c->u_pid != task_tgid_nr(current) || !c->u_pid) { + mdwext_drv_err("c(0x%llx) pid not match(0x%x/0x%x)\n", + c->kid, c->u_pid, task_tgid_nr(current)); + goto unlock_extlock; + } + if (mdw_ext_cmd_sanity_check(c)) { + mdwext_drv_err("c(0x%llx) extid(0x%llx) not available, cmd tgid(%d)\n", + c->kid, c->ext_id, c->tgid); + goto unlock_extlock; + } + + /* get cmd refcnt to avoid racing */ + mdw_cmd_get(c); + mdw_ext_unlock(); + + /* trigger cmd */ + memset(&c_args, 0, sizeof(c_args)); + c_args.in.op = MDW_CMD_IOCTL_RUN_STALE; + c_args.in.id = c->id; + ret = mdw_cmd_ioctl(c->mpriv, &c_args); + if (ret) { + mdwext_drv_err("c(0x%llx) extid(0x%llx) trigger fail(%d)\n", c->kid, c->ext_id, ret); + mdw_cmd_put(c); + goto out; + } + + memset(args, 0, sizeof(*args)); + args->out.fence = c_args.out.exec.fence; + args->out.u_done = c_args.out.exec.cmd_done_usr; + + mdw_cmd_put(c); + goto out; + +unlock_extlock: + mdw_ext_unlock(); +out: + return ret; +} + +int mdw_ext_cmd_ioctl(void *data) +{ + union mdw_ext_cmd_args *args = (union mdw_ext_cmd_args *)data; + int ret = 0; + uint64_t ext_id = args->in.ext_id; + + mdwext_cmd_debug("extid(0x%llx)\n", ext_id); + ret = mdw_ext_cmd_ioctl_run(args); + mdwext_drv_debug("extid(0x%llx) trigger done, fence(%llu) udone(%llu) ret(%d)\n", + ext_id, args->out.fence, args->out.u_done, ret); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmn.h b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmn.h new file mode 100644 index 0000000000000..383e1a388074e --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_cmn.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_EXT_CMN_H__ +#define __MTK_APU_MDW_EXT_CMN_H__ + +#include +#include +#include + +#include "mdw_cmn.h" +#include "mdw_ext.h" + +enum { + MDWEXT_DBG_DRV = 0x01, + MDWEXT_DBG_FLW = 0x02, + MDWEXT_DBG_CMD = 0x04, + MDWEXT_DBG_VLD = 0x40, +}; +extern struct mdw_ext_device *mdw_ext_dev; + +static inline +int mdwext_debug_on(int mask) +{ + return g_mdw_klog & mask; +} + +#define mdwext_debug(mask, x, ...) do { if (mdwext_debug_on(mask)) \ + dev_info(mdw_ext_dev->misc_dev->this_device, \ + "[debug] %s/%d " x, __func__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define mdwext_drv_err(x, args...) \ + dev_info(mdw_ext_dev->misc_dev->this_device, \ + "[error] %s " x, __func__, ##args) +#define mdwext_drv_warn(x, args...) \ + dev_info(mdw_ext_dev->misc_dev->this_device, \ + "[warn] %s " x, __func__, ##args) +#define mdwext_drv_info(x, args...) \ + dev_info(mdw_ext_dev->misc_dev->this_device, \ + "%s " x, __func__, ##args) + +#define mdwext_drv_debug(x, ...) mdwext_debug(MDWEXT_DBG_DRV, x, ##__VA_ARGS__) +#define mdwext_flw_debug(x, ...) mdwext_debug(MDWEXT_DBG_FLW, x, ##__VA_ARGS__) +#define mdwext_cmd_debug(x, ...) mdwext_debug(MDWEXT_DBG_CMD, x, ##__VA_ARGS__) +#define mdwext_vld_debug(x, ...) mdwext_debug(MDWEXT_DBG_VLD, x, ##__VA_ARGS__) + + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_export.h b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_export.h new file mode 100644 index 0000000000000..c70ab21e48a03 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_export.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#ifndef __MTK_APUEXT_EXPORT_H__ +#define __MTK_APUEXT_EXPORT_H__ + +#include "mdw.h" + +int mdw_ext_init(struct mdw_device *mdw_dev); +void mdw_ext_deinit(void); + +void mdw_ext_lock(void); +void mdw_ext_unlock(void); + +void mdw_ext_cmd_get_id(struct mdw_cmd *c); +void mdw_ext_cmd_put_id(struct mdw_cmd *c); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_hs.c b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_hs.c new file mode 100644 index 0000000000000..f4ec204be08a5 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_hs.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include "mdw_ext.h" +#include "mdw_ext_cmn.h" +#include "mdw_ext_ioctl.h" + +#define MDW_EXT_SUPPORT_VER (4) + +static int mdw_ext_hs_version(union mdw_ext_hs_args *args) +{ + memset(args, 0, sizeof(*args)); + args->out.out0 = MDW_EXT_SUPPORT_VER; + mdwext_drv_debug("ext hs version(%llu)\n", args->out.out0); + + return 0; +} + +int mdw_ext_hs_ioctl(void *data) +{ + union mdw_ext_hs_args *args = (union mdw_ext_hs_args *)data; + int ret = -EINVAL; + + mdwext_drv_debug("ext hs op(%llu)\n", args->in.op); + switch (args->in.op) { + case MDW_EXT_HS_TYPE_VERSION: + ret = mdw_ext_hs_version(args); + break; + default: + mdwext_drv_err("no support hs(%llu)\n", args->in.op); + break; + } + mdwext_drv_debug("ext hs op(%llu) done\n", args->in.op); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.c b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.c new file mode 100644 index 0000000000000..e1a7fbc6151af --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include +#include + +#include "mdw_ext_ioctl.h" +#include "mdw_ext.h" +#include "mdw_ext_cmn.h" + +long mdw_ext_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + unsigned int usize = 0, nr = _IOC_NR(cmd); + void *kdata = NULL; + + /* check nr before any actions */ + if (nr < MDW_EXT_IOCTL_START || nr > MDW_EXT_IOCTL_END) { + mdw_drv_debug("not support nr(%u)\n", nr); + return -ENOTTY; + } + + /* allocate for user data */ + usize = _IOC_SIZE(cmd); + /* check kzalloc return */ + kdata = kzalloc(usize, GFP_KERNEL); + if (unlikely(ZERO_OR_NULL_PTR(kdata))) + return -ENOMEM; + /* copy from user data */ + if (cmd & IOC_IN) { + if (copy_from_user(kdata, (void __user *)arg, usize)) { + ret = -EFAULT; + goto out; + } + } + + switch (cmd) { + case MDW_EXT_IOCTL_HS: + ret = mdw_ext_hs_ioctl(kdata); + break; + case MDW_EXT_IOCTL_CMD: + ret = mdw_ext_cmd_ioctl(kdata); + break; + default: + ret = -EFAULT; + goto out; + } + + /* copy to user data */ + if (cmd & IOC_OUT) { + if (copy_to_user((void __user *)arg, kdata, usize)) { + ret = -EFAULT; + goto out; + } + } + +out: + kfree(kdata); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.h b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.h new file mode 100644 index 0000000000000..eb0668cdcdccb --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/ext/mdw_ext_ioctl.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#ifndef __MTK_APUEXT_IOCTL_H__ +#define __MTK_APUEXT_IOCTL_H__ + +#include +#include + +#define APUEXT_MAGICNO 'E' +#define APUEXT_NODE_NAME "apuext" + +enum MDW_EXT_HS_TYPE { + MDW_EXT_HS_TYPE_VERSION, +}; + +struct mdw_ext_hs_in { + uint64_t op; + + uint64_t reserve0; + uint64_t reserve1; + uint64_t reserve2; +}; + +struct mdw_ext_hs_out { + uint64_t out0; + uint64_t out1; + uint64_t out2; + uint64_t out3; +}; + +union mdw_ext_hs_args { + struct mdw_ext_hs_in in; + struct mdw_ext_hs_out out; +}; + +#define MDW_EXT_IOCTL_HS \ + _IOWR(APUEXT_MAGICNO, 1, union mdw_ext_hs_args) + +struct mdw_ext_cmd_in { + uint64_t ext_id; + + uint64_t reserve0; + uint64_t reserve1; + uint64_t reserve2; +}; + +struct mdw_ext_cmd_out { + int64_t fence; + uint64_t u_done; + + uint64_t reserve0; + uint64_t reserve1; +}; + +union mdw_ext_cmd_args { + struct mdw_ext_cmd_in in; + struct mdw_ext_cmd_out out; +}; + +#define MDW_EXT_IOCTL_CMD \ + _IOWR(APUEXT_MAGICNO, 2, union mdw_ext_cmd_args) + +#define MDW_EXT_IOCTL_START (1) +#define MDW_EXT_IOCTL_END (2) + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw.h new file mode 100644 index 0000000000000..27e1ec41061fa --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw.h @@ -0,0 +1,534 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_H__ +#define __MTK_APU_MDW_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" +#include "mdw_ioctl.h" +#include "mdw_import.h" + +#define MDW_NAME "apusys" +#define MDW_DEV_MAX (APUSYS_DEVICE_MAX) +#define MDW_DEV_TAB_DEV_MAX (16) +#define MDW_CMD_MAX (32) +#define MDW_SUBCMD_MAX (64) +#define MDW_PRIORITY_MAX (32) +#define MDW_DEFAULT_TIMEOUT_MS (30*1000) +#define MDW_BOOST_MAX (100) +#define MDW_DEFAULT_ALIGN (16) +#define MDW_UTIL_CMD_MAX_SIZE (1*1024*1024) + +#define MDW_FENCE_MAX_RINGS (64) + +#define MDW_ALIGN(x, align) ((x+align-1) & (~(align-1))) + +/* history parameter */ +#define MDW_NUM_HISTORY 2 +#define MDW_NUM_PREDICT_CMD 16 +#define MDW_POWER_GAIN_TH 7680 //us +#define MDW_PERIOD_TOLERANCE_TH(x) div_u64((x) * 10, 100) //ms +#define MDW_IPTIME_TOLERANCE_TH(x) div_u64((x) * 10, 100) //ms +#define MDW_EXECTIME_TOLERANCE_TH(x) div_u64((x) * 50, 100) //us + +/* power budget debounce time */ +#define MDW_PB_DEBOUNCE_MS (50*1000) + +/* dtime */ +#define MAX_DTIME (2000) /* 2s */ + +struct mdw_fpriv; +struct mdw_device; +struct mdw_mem; + +extern const struct mdw_plat_func rv_plat_drv_v2; +extern const struct mdw_plat_func rv_plat_drv_v3; +extern const struct mdw_plat_func rv_plat_drv_v4; + +enum mdw_perf_cmd_state { + MDW_PERF_CMD_INIT, + MDW_PERF_CMD_DONE, +}; + +enum mdw_power_type { + MDW_APU_POWER_OFF, + MDW_APU_POWER_ON, +}; + +enum mdw_buf_type { + MDW_DATA_BUF, + MDW_CMD_BUF, +}; + +enum mdw_mem_op { + MDW_MEM_OP_NONE, + MDW_MEM_OP_INTERNAL, + MDW_MEM_OP_ALLOC, + MDW_MEM_OP_IMPORT, +}; + +struct mdw_mem_map { + struct dma_buf_attachment *attach; + struct sg_table *sgt; + struct kref map_ref; + struct mdw_mem *m; + void (*get)(struct mdw_mem_map *map); + void (*put)(struct mdw_mem_map *map); +}; + +struct mdw_mem_invoke { + struct list_head map_node; //to mdw_mem_map + struct list_head u_node; //to mpriv + struct kref ref; + struct mdw_mem *m; + struct mdw_fpriv *invoker; + void (*get)(struct mdw_mem_invoke *m_invoke); + void (*put)(struct mdw_mem_invoke *m_invoke); +}; + +enum mdw_queue_type { + MDW_QUEUE_COMMON, + MDW_QUEUE_NORMAL, + MDW_QUEUE_DEADLINE, + + MDW_QUEUE_MAX, +}; + +struct mdw_mem { + /* in */ + enum mdw_mem_type type; + uint64_t size; + uint64_t align; + uint64_t flags; + uint32_t buf_type; + + /* out */ + void *vaddr; + uint32_t tbl_daddr; + struct device *mdev; + struct dma_buf *dbuf; + void *priv; + int (*bind)(void *session, struct mdw_mem *m); + void (*unbind)(void *session, struct mdw_mem *m); + + /* map */ + uint64_t device_va; + uint64_t device_iova; + uint64_t dva_size; + struct mdw_mem_map *map; + + /* control */ + int handle; + bool belong_apu; + bool need_handle; + struct list_head maps; + struct mdw_fpriv *mpriv; + struct mdw_mem_pool *pool; + struct list_head u_item; //to mpriv + struct list_head d_node; //to mdev + struct list_head p_chunk; //to mem pool + struct mutex mtx; + void (*release)(struct mdw_mem *m); +}; + +/* default chunk size of memory pool */ +#define MDW_MEM_POOL_CHUNK_SIZE (4*1024*1024) + +struct mdw_mem_pool { + struct mdw_fpriv *mpriv; + /* pool attribute */ + enum mdw_mem_type type; + uint64_t flags; + uint32_t align; + uint32_t chunk_size; + /* container and lock */ + struct gen_pool *gp; + struct mutex m_mtx; + /* list of resource chunks */ + struct list_head m_chunks; + /* list of allocated memories from gp */ + struct list_head m_list; + /* ref count for cmd/mem */ + struct kref m_ref; + void (*get)(struct mdw_mem_pool *pool); + void (*put)(struct mdw_mem_pool *pool); +}; + +struct mdw_dinfo { + uint32_t type; + uint32_t num; + uint8_t meta[MDW_DEV_META_SIZE]; +}; + +enum mdw_driver_type { + MDW_DRIVER_TYPE_PLATFORM, + MDW_DRIVER_TYPE_RPMSG, +}; + +enum mdw_info_type { + MDW_INFO_KLOG, + MDW_INFO_ULOG, + MDW_INFO_PREEMPT_POLICY, + MDW_INFO_SCHED_POLICY, + + MDW_INFO_NORMAL_TASK_DLA, + MDW_INFO_NORMAL_TASK_DSP, + MDW_INFO_NORMAL_TASK_DMA, + + MDW_INFO_MIN_DTIME, + MDW_INFO_MIN_ETIME, + MDW_INFO_MAX_DTIME, + + MDW_INFO_RESERV_TIME_REMAIN, + + MDW_INFO_MAX, +}; + +enum mdw_info_dir { + MDW_INFO_SET, + MDW_INFO_GET +}; + +enum mdw_pwrplcy_type { + MDW_POWERPOLICY_DEFAULT = 0, //do nothing + MDW_POWERPOLICY_SUSTAINABLE = 1, + MDW_POWERPOLICY_PERFORMANCE = 2, + MDW_POWERPOLICY_POWERSAVING = 3, +}; + +enum { + MDW_APPTYPE_DEFAULT = 0, + MDW_APPTYPE_ONESHOT = 1, + MDW_APPTYPE_STREAMING = 2, +}; + +struct mdw_device { + enum mdw_driver_type driver_type; + union { + struct platform_device *pdev; + struct rpmsg_device *rpdev; + }; + struct device *dev; + struct miscdevice *misc_dev; + + /* init flag */ + bool inited; + + /* cores enable bitmask */ + uint32_t dsp_mask; + uint32_t dla_mask; + uint32_t dma_mask; + + /* mdw version */ + uint32_t mdw_ver; + + /* device */ + struct apusys_device *adevs[MDW_DEV_MAX]; + + /* device support information */ + unsigned long dev_mask[BITS_TO_LONGS(MDW_DEV_MAX)]; + struct mdw_dinfo *dinfos[MDW_DEV_MAX]; + /* memory support information */ + unsigned long mem_mask[BITS_TO_LONGS(MDW_MEM_TYPE_MAX)]; + struct mdw_mem minfos[MDW_MEM_TYPE_MAX]; + + /* memory hlist */ + struct list_head m_list; + struct mutex m_mtx; + struct mutex mctl_mtx; + + /* cmd clear wq */ + struct mutex c_mtx; + struct list_head d_cmds; + struct work_struct c_wk; + + /* platform functions */ + const struct mdw_plat_func *plat_funcs; + void *dev_specific; + + /* fence info */ + uint64_t base_fence_ctx; + uint32_t num_fence_ctx; + unsigned long fence_ctx_mask[BITS_TO_LONGS(MDW_FENCE_MAX_RINGS)]; + struct mutex f_mtx; + + /* cmd history */ + uint64_t idle_time_ts; + uint64_t predict_cmd_ts[MDW_NUM_PREDICT_CMD]; + struct min_heap heap; + atomic_t cmd_running; + struct mutex h_mtx; + + /* power fast on/off */ + bool support_power_fast_on_off; + enum mdw_power_type power_state; + uint64_t max_dtime_ts; + struct mutex dtime_mtx; + struct mutex power_mtx; + uint32_t power_gain_time_us; + + /* dtime setting function */ + void (*update_power_dtime)(int dtime); +}; + +struct mdw_fpriv { + struct mdw_device *mdev; + + struct list_head mems; + struct list_head invokes; + struct mutex mtx; + struct mdw_mem_pool cmd_buf_pool; + struct idr cmds; + struct list_head cmds_list; + atomic_t active_cmds; + atomic_t exec_seqno; + + uint64_t cb_head_device_va; + + /* ref count for cmd/mem */ + atomic_t active; + struct kref ref; + void (*get)(struct mdw_fpriv *mpriv); + void (*put)(struct mdw_fpriv *mpriv); + + /* cmd history */ + struct list_head ch_list; + uint32_t cmd_cnt; + struct mutex ch_mtx; + + /* cmd execute id counter */ + uint32_t counter; +}; + +struct mdw_exec_info { + struct mdw_cmd_exec_info c; + struct mdw_subcmd_exec_info sc; +}; + +struct mdw_subcmd_kinfo { + struct mdw_subcmd_info *info; //c->subcmds + struct mdw_subcmd_cmdbuf *cmdbufs; //from usr + struct mdw_mem **ori_cbs; //pointer to original cmdbuf + struct mdw_subcmd_exec_info *sc_einfo; + uint64_t *kvaddrs; //pointer to duplicated buf + uint64_t *daddrs; //pointer to duplicated buf + void *priv; //mdw_ap_sc +}; + +struct mdw_fence { + struct dma_fence base_fence; + struct mdw_device *mdev; + spinlock_t lock; + char name[32]; +}; + +struct mdw_cmd_map_invoke { + struct list_head c_node; + struct mdw_mem_map *map; +}; + +struct mdw_cmd_history_tbl { + /* history basic struct */ + uint64_t uid; + struct list_head ch_tbl_node; //to mpriv + uint64_t period_cnt; + uint32_t num_subcmds; + + /* history cmd time info */ + uint64_t h_end_ts; + uint64_t h_start_ts; + uint64_t h_period; + uint64_t h_exec_time; + + /* history subcmd einfo */ + struct mdw_subcmd_exec_info *h_sc_einfo; +}; + +struct mdw_cmd { + pid_t pid; + pid_t tgid; + char comm[16]; + uint64_t kid; + uint64_t uid; + uint64_t rvid; + uint32_t u_pid; + uint32_t priority; + uint32_t hardlimit; + uint32_t softlimit; + uint32_t power_save; + uint32_t power_plcy; + uint32_t power_dtime; + uint32_t power_etime; + uint32_t fastmem_ms; + uint32_t app_type; + uint32_t num_subcmds; + uint32_t num_links; + struct mdw_subcmd_info *subcmds; //from usr + struct mdw_subcmd_kinfo *ksubcmds; + uint32_t num_cmdbufs; + uint32_t size_cmdbufs; + uint32_t size_apummutable; + struct mdw_mem *cmdbufs; + struct mdw_mem *exec_infos; + struct mdw_exec_info *einfos; + uint8_t *adj_matrix; + struct mdw_subcmd_link_v1 *links; + + struct mutex mtx; + struct list_head u_item; + struct list_head map_invokes; //mdw_cmd_map_invoke + struct list_head d_node; //mdev->d_cmds + + int id; + struct kref ref; + atomic_t is_running; + + uint64_t start_ts; + uint64_t end_ts; + + struct mdw_fpriv *mpriv; + void *internal_cmd; + int (*complete)(struct mdw_cmd *c, int ret); + int (*del_internal)(struct mdw_cmd *c); + + struct mdw_fence *fence; + struct work_struct t_wk; + struct dma_fence *wait_fence; + + void *tbl_kva; + /* history params */ + uint32_t inference_ms; + uint32_t tolerance_ms; + /* set dtime */ + uint64_t is_dtime_set; + /* polling cmd result */ + + /* ext operation */ + uint64_t ext_id; // for apuext unique id + + /* cmd poll */ + uint32_t cmd_state; + struct completion cmplt; + + /* cmd exec id */ + uint64_t inference_id; + + /* cmd tag time */ + uint64_t enter_complt_time; + uint64_t pb_put_time; + uint64_t cmdbuf_out_time; + uint64_t handle_cmd_result_time; + uint64_t load_aware_pwroff_time; + uint64_t enter_mpriv_release_time; + uint64_t mpriv_release_time; + uint64_t enter_rv_cb_time; + uint64_t rv_cb_time; + +}; + +struct mdw_plat_func { + int (*late_init)(struct mdw_device *mdev); + void (*late_deinit)(struct mdw_device *mdev); + int (*sw_init)(struct mdw_device *mdev); + void (*sw_deinit)(struct mdw_device *mdev); + int (*prepare_cmd)(struct mdw_fpriv *mpriv, void *kdata); + int (*get_cmdbuf)(struct mdw_fpriv *mpriv, struct mdw_cmd *c); + int (*run_cmd)(struct mdw_fpriv *mpriv, struct mdw_cmd *c); + void (*release_cmd)(struct mdw_fpriv *mpriv); + int (*set_power)(struct mdw_device *mdev, uint32_t type, uint32_t idx, uint32_t boost); + int (*ucmd)(struct mdw_device *mdev, uint32_t type, void *vaddr, uint32_t size); + int (*set_param)(struct mdw_device *mdev, enum mdw_info_type type, uint32_t val); + uint32_t (*get_info)(struct mdw_device *mdev, enum mdw_info_type type); + int (*register_device)(struct apusys_device *adev); + int (*unregister_device)(struct apusys_device *adev); + int (*power_onoff)(struct mdw_device *mdev, enum mdw_power_type power_onoff); + bool (*poll_cmd)(struct mdw_cmd *c); + void (*cp_execinfo)(struct mdw_cmd *c); + /* power budget funcs */ + // int (*pb_get)(enum mdw_pwrplcy_type type, uint32_t deboundce_ms); + // int (*pb_put)(enum mdw_pwrplcy_type type); +}; + +#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE) +#include +#define _mdw_exception(key, reason, args...) \ + do { \ + char info[150];\ + mdw_drv_err(reason, args); \ + if (snprintf(info, 150, "apu_mdw:" reason, args) > 0) { \ + aee_kernel_exception(info, \ + "\nCRDISPATCH_KEY:%s\n", key); \ + } else { \ + mdw_drv_err("apu_mdw: %s snprintf fail(%d)\n", __func__, __LINE__); \ + } \ + } while (0) +#define mdw_exception(reason, args...) _mdw_exception("APUSYS_MIDDLEWARE", reason, ##args) +#define dma_exception(reason, args...) _mdw_exception("APUSYS_EDMA", reason, ##args) +#define aps_exception(reason, args...) _mdw_exception("APUSYS_APS", reason, ##args) +#else +#define mdw_exception(reason, args...) +#define dma_exception(reason, args...) +#define aps_exception(reason, args...) +#endif + +long mdw_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); +int mdw_hs_ioctl(struct mdw_fpriv *mpriv, void *data); +int mdw_cmd_ioctl(struct mdw_fpriv *mpriv, void *kdata); +int mdw_mem_ioctl(struct mdw_fpriv *mpriv, void *data); +int mdw_util_ioctl(struct mdw_fpriv *mpriv, void *data); + +void mdw_mem_all_print(struct mdw_fpriv *mpriv); + +void mdw_mem_put(struct mdw_fpriv *mpriv, struct mdw_mem *m); +struct mdw_mem *mdw_mem_get(struct mdw_fpriv *mpriv, int handle); +struct mdw_mem *mdw_mem_alloc(struct mdw_fpriv *mpriv, enum mdw_mem_type type, + uint64_t size, uint64_t align, uint64_t flags, bool need_handle); +void mdw_mem_free(struct mdw_fpriv *mpriv, struct mdw_mem *m); +long mdw_mem_set_name(struct mdw_mem *m, const char *buf); +int mdw_mem_map(struct mdw_fpriv *mpriv, struct mdw_mem *m); +int mdw_mem_unmap(struct mdw_fpriv *mpriv, struct mdw_mem *m); +int mdw_mem_flush(struct mdw_fpriv *mpriv, struct mdw_mem *m); +int mdw_mem_invalidate(struct mdw_fpriv *mpriv, struct mdw_mem *m); +int mdw_mem_init(struct mdw_device *mdev); +void mdw_mem_deinit(struct mdw_device *mdev); +void mdw_mem_mpriv_release(struct mdw_fpriv *mpriv); + +int mdw_sysfs_init(struct mdw_device *mdev); +void mdw_sysfs_deinit(struct mdw_device *mdev); + +int mdw_dbg_init(struct mdw_device *mdev, struct dentry *dbg_root); +void mdw_dbg_deinit(void); + +int mdw_dev_init(struct device *dev, struct mdw_device *mdev); +void mdw_dev_deinit(struct mdw_device *mdev); +void mdw_dev_session_create(struct mdw_fpriv *mpriv); +void mdw_dev_session_delete(struct mdw_fpriv *mpriv); +int mdw_dev_validation(struct mdw_fpriv *mpriv, uint32_t dtype, + struct mdw_cmd *cmd, struct apusys_cmdbuf *cbs, uint32_t num); + +uint64_t mdw_fence_ctx_alloc(struct mdw_device *mdev); +void mdw_fence_ctx_free(struct mdw_device *mdev, uint64_t ctx); +const char *mdw_fence_get_driver_name(struct dma_fence *fence); +const char *mdw_fence_get_timeline_name(struct dma_fence *fence); +bool mdw_fence_enable_signaling(struct dma_fence *fence); +void mdw_fence_release(struct dma_fence *fence); +int mdw_fence_init(struct mdw_cmd *c, int fd); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmd.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmd.c new file mode 100644 index 0000000000000..02b290a186239 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmd.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_cmn.h" + +int mdw_cmd_ioctl(struct mdw_fpriv *mpriv, void *kdata) +{ + return mpriv->mdev->plat_funcs->prepare_cmd(mpriv, kdata); +} + diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.c new file mode 100644 index 0000000000000..fb1eade7c224b --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include + +#include "mdw_cmn.h" + +uint32_t mdw_cmn_get_time_diff(struct timespec64 *prev, struct timespec64 *next) +{ + uint32_t diff = 0; + + diff = (next->tv_sec - prev->tv_sec) * 1000 * 1000; + if (next->tv_nsec - prev->tv_nsec) + diff += (next->tv_nsec - prev->tv_nsec)/1000; + + return diff; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.h new file mode 100644 index 0000000000000..0611c68d31544 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_cmn.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_CMN_H__ +#define __MTK_APU_MDW_CMN_H__ + +#include +#include +#include + +#include "mdw.h" + +extern u32 g_mdw_klog; +extern u8 cfg_apusys_trace; +extern u64 dbg_min_dtime; +extern u64 dbg_max_dtime; +extern u32 g_mdw_pwroff_cnt; +extern u32 g_mdw_poll_interval; +extern u32 g_mdw_poll_timeout; + +enum { + MDW_DBG_DRV = 0x01, + MDW_DBG_FLW = 0x02, + MDW_DBG_CMD = 0x04, + MDW_DBG_MEM = 0x08, + MDW_DBG_PEF = 0x10, + MDW_DBG_SUB = 0x20, + MDW_DBG_VLD = 0x40, + + MDW_DBG_EXP = 0x1000, +}; + +extern struct mdw_device *mdw_dev; + +static inline +int mdw_debug_on(int mask) +{ + return g_mdw_klog & mask; +} + +#define mdw_debug(mask, x, ...) do { if (mdw_debug_on(mask)) \ + dev_info(mdw_dev->misc_dev->this_device, \ + "[debug] %s/%d " x, __func__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define mdw_drv_err(x, args...) \ + dev_info(mdw_dev->misc_dev->this_device, \ + "[error] %s " x, __func__, ##args) +#define mdw_drv_warn(x, args...) \ + dev_info(mdw_dev->misc_dev->this_device, \ + "[warn] %s " x, __func__, ##args) +#define mdw_drv_info(x, args...) \ + dev_info(mdw_dev->misc_dev->this_device, \ + "%s " x, __func__, ##args) + +#define mdw_drv_debug(x, ...) mdw_debug(MDW_DBG_DRV, x, ##__VA_ARGS__) +#define mdw_flw_debug(x, ...) mdw_debug(MDW_DBG_FLW, x, ##__VA_ARGS__) +#define mdw_cmd_debug(x, ...) mdw_debug(MDW_DBG_CMD, x, ##__VA_ARGS__) +#define mdw_mem_debug(x, ...) mdw_debug(MDW_DBG_MEM, x, ##__VA_ARGS__) +#define mdw_pef_debug(x, ...) mdw_debug(MDW_DBG_PEF, x, ##__VA_ARGS__) +#define mdw_sub_debug(x, ...) mdw_debug(MDW_DBG_SUB, x, ##__VA_ARGS__) +#define mdw_vld_debug(x, ...) mdw_debug(MDW_DBG_VLD, x, ##__VA_ARGS__) + +/* print to console via seq file */ +#define mdw_con_info(s, x, args...) \ + {\ + if (s) \ + seq_printf(s, x, ##args); \ + else \ + mdw_drv_debug(x, ##args); \ + } + +uint32_t mdw_cmn_get_time_diff(struct timespec64 *prev, + struct timespec64 *next); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_ctx.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ctx.c new file mode 100644 index 0000000000000..3bf131216772a --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ctx.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_cmn.h" + +int mdw_ctx_init(struct mdw_device *mdev) +{ + return 0; +} + +void mdw_ctx_deinit(struct mdw_device *mdev) +{ +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_dbg.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_dbg.c new file mode 100644 index 0000000000000..e899b421a5b7b --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_dbg.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mdw_cmn.h" + +struct dentry *mdw_dbg_root; +struct dentry *mdw_dbg_trace; +struct dentry *mdw_dbg_device; + +u32 g_mdw_klog; +u8 cfg_apusys_trace; +u32 g_mdw_pwroff_cnt; +u32 g_mdw_poll_interval; +u32 g_mdw_poll_timeout; + +/* default value need to align with rv or add sync flow */ +u64 dbg_min_dtime; +u64 dbg_max_dtime; + +static int min_etime_set(void *data, u64 val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + mdev->plat_funcs->set_param(mdev, MDW_INFO_MIN_ETIME, val); + return 0; +} +static int min_etime_get(void *data, u64 *val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + *val = mdev->plat_funcs->get_info(mdev, MDW_INFO_MIN_ETIME); + return 0; +} + +static int min_dtime_set(void *data, u64 val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + dbg_min_dtime = val; + mdev->plat_funcs->set_param(mdev, MDW_INFO_MIN_DTIME, val); + return 0; +} +static int min_dtime_get(void *data, u64 *val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + *val = mdev->plat_funcs->get_info(mdev, MDW_INFO_MIN_DTIME); + return 0; +} + +static int max_dtime_set(void *data, u64 val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + dbg_max_dtime = val; + mdev->plat_funcs->set_param(mdev, MDW_INFO_MAX_DTIME, val); + return 0; +} + +static int max_dtime_get(void *data, u64 *val) +{ + struct mdw_device *mdev = (struct mdw_device *)data; + + *val = mdev->plat_funcs->get_info(mdev, MDW_INFO_MAX_DTIME); + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_min_dtime, min_dtime_get, min_dtime_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_max_dtime, max_dtime_get, max_dtime_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_min_etime, min_etime_get, min_etime_set, "%llu\n"); +//---------------------------------------------- +int mdw_dbg_init(struct mdw_device *mdev, struct dentry *dbg_root) +{ + g_mdw_klog = 0x0; + g_mdw_pwroff_cnt = 0x0; + g_mdw_poll_interval = 0x0; + g_mdw_poll_timeout = 0x0; + + /* create debug root */ + mdw_dbg_root = debugfs_create_dir("midware", dbg_root); + + /* create log level */ + debugfs_create_u32("klog", 0644, + mdw_dbg_root, &g_mdw_klog); + + /* create log level */ + cfg_apusys_trace = 0; + debugfs_create_u8("trace_en", 0644, + mdw_dbg_root, &cfg_apusys_trace); + + /* create pwroff_cnt */ + debugfs_create_u32("pwroff_cnt", 0644, + mdw_dbg_root, &g_mdw_pwroff_cnt); + + /* create poll_time */ + debugfs_create_u32("poll_interval", 0644, + mdw_dbg_root, &g_mdw_poll_interval); + /* create poll_timeout */ + debugfs_create_u32("poll_timeout", 0644, + mdw_dbg_root, &g_mdw_poll_timeout); + + dbg_min_dtime = 0; + dbg_max_dtime = 10000; + debugfs_create_file("min_dtime", 0644, mdw_dbg_root, mdw_dev, &fops_min_dtime); + debugfs_create_file("max_dtime", 0644, mdw_dbg_root, mdw_dev, &fops_max_dtime); + debugfs_create_file("min_etime", 0644, mdw_dbg_root, mdw_dev, &fops_min_etime); + + mdw_dbg_device = debugfs_create_dir("device", mdw_dbg_root); + + return 0; +} + +void mdw_dbg_deinit(void) +{ +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_dev.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_dev.c new file mode 100644 index 0000000000000..2105af599ee17 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_dev.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include + +#include "mdw_cmn.h" +#include "mdw_cmd.h" + + +static void mdw_dev_clear_cmd_func(struct work_struct *wk) +{ + struct mdw_device *mdev = + container_of(wk, struct mdw_device, c_wk); + struct mdw_cmd *c = NULL, *tmp = NULL; + + mutex_lock(&mdev->c_mtx); + list_for_each_entry_safe(c, tmp, &mdev->d_cmds, d_node) { + list_del(&c->d_node); + mdw_cmd_delete(c); + } + mutex_unlock(&mdev->c_mtx); +} + +int mdw_dev_init(struct device *dev, struct mdw_device *mdev) +{ + int ret = -ENODEV; + + mdw_drv_info("mdw dev init type(%d-%u)\n", + mdev->driver_type, mdev->mdw_ver); + + INIT_LIST_HEAD(&mdev->d_cmds); + mutex_init(&mdev->c_mtx); + INIT_WORK(&mdev->c_wk, &mdw_dev_clear_cmd_func); + mdev->base_fence_ctx = dma_fence_context_alloc(MDW_FENCE_MAX_RINGS); + mdev->num_fence_ctx = MDW_FENCE_MAX_RINGS; + mutex_init(&mdev->f_mtx); + mutex_init(&mdev->dtime_mtx); + mutex_init(&mdev->power_mtx); + mutex_init(&mdev->h_mtx); + + mdev->plat_funcs = (struct mdw_plat_func *)of_device_get_match_data(dev); + if (!mdev->plat_funcs) { + pr_info("of_device_get_match_data fail\n"); + return -EINVAL; + } + + if (mdev->plat_funcs) + ret = mdev->plat_funcs->late_init(mdev); + + return ret; +} + +void mdw_dev_deinit(struct mdw_device *mdev) +{ + if (mdev->plat_funcs) { + mdev->plat_funcs->late_deinit(mdev); + mdev->plat_funcs = NULL; + } +} + +void mdw_dev_session_create(struct mdw_fpriv *mpriv) +{ + struct mdw_device *mdev = mpriv->mdev; + uint32_t i = 0; + + for (i = 0; i < MDW_DEV_MAX; i++) { + if (mdev->adevs[i]) + mdev->adevs[i]->send_cmd(APUSYS_CMD_SESSION_CREATE, mpriv, mdev->adevs[i]); + } +} + +void mdw_dev_session_delete(struct mdw_fpriv *mpriv) +{ + struct mdw_device *mdev = mpriv->mdev; + uint32_t i = 0; + + for (i = 0; i < MDW_DEV_MAX; i++) { + if (mdev->adevs[i]) + mdev->adevs[i]->send_cmd(APUSYS_CMD_SESSION_DELETE, mpriv, mdev->adevs[i]); + } +} + +int mdw_dev_validation(struct mdw_fpriv *mpriv, uint32_t dtype, + struct mdw_cmd *cmd, struct apusys_cmdbuf *cbs, uint32_t num) +{ + struct apusys_device *adev = NULL; + struct apusys_cmd_valid_handle v_hnd; + int ret = 0; + + if (dtype >= MDW_DEV_MAX) + return -ENODEV; + + memset(&v_hnd, 0, sizeof(v_hnd)); + v_hnd.cmdbufs = cbs; + v_hnd.num_cmdbufs = num; + v_hnd.session = mpriv; + v_hnd.cmd = cmd; + adev = mpriv->mdev->adevs[dtype]; + if (adev) { + mutex_lock(&mpriv->mdev->mctl_mtx); + ret = adev->send_cmd(APUSYS_CMD_VALIDATE, &v_hnd, adev); + mutex_unlock(&mpriv->mdev->mctl_mtx); + } + + return ret; +} + +int apusys_register_device(struct apusys_device *adev) +{ + uint32_t type = 0; + + if (!mdw_dev) { + pr_info("[apusys] apu mdw not ready\n"); + return -ENODEV; + } + + if (!mdw_dev->plat_funcs) { + pr_info("[apusys] apu mdw not inited\n"); + return -ENODEV; + } + + type = adev->dev_type; + if (type >= MDW_DEV_MAX) { + pr_info("[apusys] invalid dev(%u)\n", type); + return -EINVAL; + } + + if (!mdw_dev->adevs[type]) + mdw_dev->adevs[type] = adev; + + return mdw_dev->plat_funcs->register_device(adev); +} +EXPORT_SYMBOL_NS(apusys_register_device, MTK_APU_MDW); + +int apusys_unregister_device(struct apusys_device *adev) +{ + if (!mdw_dev) { + pr_info("[apusys] apu mdw not ready\n"); + return -ENODEV; + } + + if (!mdw_dev->plat_funcs) { + pr_info("[apusys] apu mdw not inited\n"); + return -ENODEV; + } + + return mdw_dev->plat_funcs->unregister_device(adev); +} +EXPORT_SYMBOL_NS(apusys_unregister_device, MTK_APU_MDW); diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_drv.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_drv.c new file mode 100644 index 0000000000000..2af157beb1fec --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_drv.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "mdw_ext_export.h" +#include "mdw_trace.h" +#include "mdw_mem_drv.h" + +#define APUSYS_DEV_NAME "apusys" + +struct mdw_device *mdw_dev; +static struct dentry *g_dbg_root; +static atomic_t g_inited; +static void (*g_update_power_dtime)(int dtime); + +static void mdw_drv_priv_delete(struct kref *ref) +{ + struct mdw_fpriv *mpriv = + container_of(ref, struct mdw_fpriv, ref); + + mdw_drv_debug("mpriv(0x%llx) free\n", (uint64_t) mpriv); + mdw_dev_session_delete(mpriv); + kfree(mpriv); +} + +static void mdw_drv_priv_get(struct mdw_fpriv *mpriv) +{ + mdw_flw_debug("mpriv(0x%llx) ref(%u)\n", + (uint64_t) mpriv, kref_read(&mpriv->ref)); + kref_get(&mpriv->ref); +} + +static void mdw_drv_priv_put(struct mdw_fpriv *mpriv) +{ + mdw_flw_debug("mpriv(0x%llx) ref(%u)\n", + (uint64_t) mpriv, kref_read(&mpriv->ref)); + kref_put(&mpriv->ref, mdw_drv_priv_delete); +} + +static int mdw_drv_open(struct inode *inode, struct file *filp) +{ + struct mdw_fpriv *mpriv = NULL; + int ret = 0; + + mdw_trace_begin("apumdw:drv_open"); + if (!mdw_dev) { + pr_info("apusys/mdw: apu mdw no dev\n"); + return -ENODEV; + } + + if (mdw_dev->inited == false) { + mdw_drv_warn("apu mdw dev not init"); + return -EBUSY; + } + + mpriv = kzalloc(sizeof(*mpriv), GFP_KERNEL); + if (!mpriv) + return -ENOMEM; + + mpriv->mdev = mdw_dev; + filp->private_data = mpriv; + atomic_set(&mpriv->active, 1); + mutex_init(&mpriv->mtx); + mutex_init(&mpriv->ch_mtx); + INIT_LIST_HEAD(&mpriv->mems); + INIT_LIST_HEAD(&mpriv->invokes); + INIT_LIST_HEAD(&mpriv->ch_list); + atomic_set(&mpriv->active_cmds, 0); + idr_init(&mpriv->cmds); + INIT_LIST_HEAD(&mpriv->cmds_list); + atomic_set(&mpriv->exec_seqno, 0); + + mpriv->get = mdw_drv_priv_get; + mpriv->put = mdw_drv_priv_put; + kref_init(&mpriv->ref); + + if (!atomic_read(&g_inited)) { + ret = mdw_dev->plat_funcs->sw_init(mdw_dev); + if (ret) { + mdw_drv_err("mdw sw init fail(%d)\n", ret); + goto put_mpriv; + } + atomic_inc(&g_inited); + } + + ret = mdw_mem_pool_create(mpriv, &mpriv->cmd_buf_pool, + MDW_MEM_TYPE_MAIN, MDW_MEM_POOL_CHUNK_SIZE, + MDW_DEFAULT_ALIGN, F_MDW_MEM_32BIT); + if (ret) { + mdw_drv_err("mdw create mem pool fail ret(%d)\n", ret); + goto put_mpriv; + } + + mdw_dev_session_create(mpriv); + mdw_flw_debug("mpriv(0x%lx)\n", (unsigned long)mpriv); + mdw_trace_end(); + goto out; + +put_mpriv: + mpriv->put(mpriv); +out: + return ret; +} + +static int mdw_drv_close(struct inode *inode, struct file *filp) +{ + struct mdw_fpriv *mpriv = NULL; + + mpriv = filp->private_data; + mdw_flw_debug("mpriv(0x%llx)\n", (uint64_t)mpriv); + mutex_lock(&mpriv->mtx); + atomic_set(&mpriv->active, 0); + mpriv->mdev->plat_funcs->release_cmd(mpriv); + mdw_mem_pool_destroy(&mpriv->cmd_buf_pool); + mutex_unlock(&mpriv->mtx); + mpriv->put(mpriv); + + return 0; +} + +static const struct file_operations mdw_fops = { + .owner = THIS_MODULE, + .open = mdw_drv_open, + .release = mdw_drv_close, + .unlocked_ioctl = mdw_ioctl, + .compat_ioctl = mdw_ioctl, +}; + +static struct miscdevice mdw_misc_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = MDW_NAME, + .fops = &mdw_fops, +}; + +void mtk_apu_init_mdw_dtime_setting(void (*update_power_dtime)(int dtime)) +{ + g_update_power_dtime = update_power_dtime; +} +EXPORT_SYMBOL_NS(mtk_apu_init_mdw_dtime_setting, MTK_APU_MDW); + +static int mdw_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + struct mdw_device *mdev = NULL; + int ret = 0; + + pr_info("%s +\n", __func__); + + if (mdw_dev) { + pr_info("%s already probe\n", __func__); + return -EBUSY; + } + mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + if (!mdev) + return -ENOMEM; + + /* get parameter from dts */ + of_property_read_u32(rpdev->dev.of_node, "version", &mdev->mdw_ver); + of_property_read_u32(rpdev->dev.of_node, "dsp_mask", &mdev->dsp_mask); + of_property_read_u32(rpdev->dev.of_node, "dla_mask", &mdev->dla_mask); + of_property_read_u32(rpdev->dev.of_node, "dma_mask", &mdev->dma_mask); + + mdev->driver_type = MDW_DRIVER_TYPE_RPMSG; + mdev->rpdev = rpdev; + mdev->misc_dev = &mdw_misc_dev; + mdw_dev = mdev; + dev_set_drvdata(dev, mdev); + + ret = mdw_mem_init(mdev); + if (ret) + goto delete_mdw_dev; + + ret = mdw_sysfs_init(mdev); + if (ret) + goto deinit_mem; + + mdw_dbg_init(mdev, g_dbg_root); + + ret = mdw_dev_init(dev, mdev); + if (ret) + goto deinit_dbg; + + mdw_cmd_history_init(mdev); + + mdev->support_power_fast_on_off = true; + mdev->power_state = MDW_APU_POWER_OFF; + mdev->update_power_dtime = g_update_power_dtime; + + pr_info("%s -\n", __func__); + + goto out; + +deinit_dbg: + mdw_dbg_deinit(); + mdw_sysfs_deinit(mdev); +deinit_mem: + mdw_mem_deinit(mdev); +delete_mdw_dev: + kfree(mdev); + mdw_dev = NULL; +out: + return ret; +} + +static void mdw_rpmsg_remove(struct rpmsg_device *rpdev) +{ + struct mdw_device *mdev = dev_get_drvdata(&rpdev->dev); + + atomic_dec(&g_inited); + + mdev->plat_funcs->sw_deinit(mdev); + mdw_dev_deinit(mdev); + mdw_cmd_history_deinit(mdev); + mdw_dbg_deinit(); + mdw_sysfs_deinit(mdev); + mdw_mem_deinit(mdev); + kfree(mdev); + mdw_dev = NULL; + pr_info("%s +\n", __func__); +} + +static void create_dbg_root(void) +{ + g_dbg_root = debugfs_create_dir(APUSYS_DEV_NAME, NULL); + + /* check dbg root create status */ + if (IS_ERR_OR_NULL(g_dbg_root)) + pr_info("failed to create debug dir.\n"); +} + +static void destroy_dbg_root(void) +{ + debugfs_remove_recursive(g_dbg_root); +} + +static const struct of_device_id mdw_rpmsg_of_match[] = { + { .compatible = "mediatek,apu-mdw-rpmsg-v2", .data = &rv_plat_drv_v2 }, + { .compatible = "mediatek,apu-mdw-rpmsg-v3", .data = &rv_plat_drv_v3 }, + { .compatible = "mediatek,apu-mdw-rpmsg-v4", .data = &rv_plat_drv_v4 }, + { .compatible = "mediatek,apu-mdw-rpmsg-v5", .data = &rv_plat_drv_v4 }, + { }, +}; + +static struct rpmsg_driver mdw_rpmsg_driver = { + .drv = { + .name = "apu-mdw-rpmsg", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mdw_rpmsg_of_match), + }, + .probe = mdw_rpmsg_probe, + .remove = mdw_rpmsg_remove, +}; + +//---------------------------------------- +int mdw_init(void) +{ + int ret = 0; + + create_dbg_root(); + + // if (!mdw_pwr_check()) { + // pr_info("apusys mdw disable\n"); + // return -ENODEV; + // } + + pr_info("%s register mdw_mem...\n", __func__); + ret = apumem_init(); + if (ret) { + pr_info("failed to register apu mdw mem driver\n"); + goto out; + } + + pr_info("%s register misc...\n", __func__); + ret = misc_register(&mdw_misc_dev); + if (ret) { + pr_info("failed to register apu mdw misc driver\n"); + goto out; + } + + pr_info("%s register rpmsg...\n", __func__); + ret = register_rpmsg_driver(&mdw_rpmsg_driver); + if (ret) { + pr_info("failed to register apu mdw rpmsg driver\n"); + goto unregister_platform_driver; + } + + /* init apu ext function */ + ret = mdw_ext_init(mdw_dev); + if (ret) { + pr_info("failed to do ext init\n"); + goto unregister_rpmsg_driver; + } + + pr_info("%s init done\n", __func__); + goto out; + +unregister_rpmsg_driver: + unregister_rpmsg_driver(&mdw_rpmsg_driver); +unregister_platform_driver: + // platform_driver_unregister(&mdw_platform_driver); +// unregister_misc_dev: + misc_deregister(&mdw_misc_dev); +out: + return ret; +} + +void mdw_exit(void) +{ + mdw_ext_deinit(); + unregister_rpmsg_driver(&mdw_rpmsg_driver); + // platform_driver_unregister(&mdw_platform_driver); + misc_deregister(&mdw_misc_dev); + destroy_dbg_root(); +} + +module_init(mdw_init); +module_exit(mdw_exit); +MODULE_DESCRIPTION("APU Middleware Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_hs.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_hs.c new file mode 100644 index 0000000000000..30e6f2247341c --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_hs.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_ioctl.h" +#include "mdw_cmn.h" + +int mdw_hs_ioctl(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_hs_args *args = (union mdw_hs_args *)data; + struct mdw_device *mdev = mpriv->mdev; + unsigned int type = 0; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op:%d\n", (uint64_t)mpriv, args->in.op); + + switch (args->in.op) { + case MDW_HS_IOCTL_OP_BASIC: + /* assign basic infos */ + memset(args, 0, sizeof(*args)); + args->out.basic.version = mdev->mdw_ver; + memcpy(&args->out.basic.dev_bitmask, + mdev->dev_mask, sizeof(mdev->dev_mask)); + memcpy(&args->out.basic.mem_bitmask, + mdev->mem_mask, sizeof(mdev->mem_mask)); + args->out.basic.meta_size = MDW_DEV_META_SIZE; + mdw_flw_debug("version(%llu) dev mask(0x%llx) mem mask(0x%llx)\n", + args->out.basic.version, + args->out.basic.dev_bitmask, + args->out.basic.mem_bitmask); + break; + + case MDW_HS_IOCTL_OP_DEV: + /* check type valid */ + type = args->in.dev.type; + if (type >= MDW_DEV_MAX) { + ret = -EINVAL; + break; + } + + /* assign dev infos */ + memset(args, 0, sizeof(*args)); + args->out.dev.type = type; + if (mdev->dinfos[type] == NULL) { + ret = -EINVAL; + mdw_drv_err("dev type(%u) not support\n", type); + break; + } + + args->out.dev.num = mdev->dinfos[type]->num; + memcpy(args->out.dev.meta, mdev->dinfos[type]->meta, + sizeof(args->out.dev.meta)); + mdw_flw_debug("dev(%u) num(%u) meta(%s)\n", + args->out.dev.type, args->out.dev.num, + mdev->dinfos[type]->meta); + break; + + case MDW_HS_IOCTL_OP_MEM: + /* check type valid */ + type = args->in.mem.type; + if (type >= MDW_MEM_TYPE_MAX) { + mdw_drv_err("unknown mem type(%u)\n", type); + ret = -EINVAL; + break; + } + + /* assign mem infos */ + memset(args, 0, sizeof(*args)); + args->out.mem.type = type; + + args->out.mem.start = mdev->minfos[type].device_va; + args->out.mem.size = mdev->minfos[type].dva_size; + mdw_flw_debug("mem(%u) start(0x%llx) size(0x%x)\n", + args->out.mem.type, + args->out.mem.start, + args->out.mem.size); + break; + + default: + mdw_drv_err("invalid handshake op code(%d)\n", args->in.op); + ret = -EINVAL; + break; + } + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.c new file mode 100644 index 0000000000000..278c54068e7f5 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_cmn.h" +#include "mdw_import.h" +#include "mdw_trace.h" +#include "linux/soc/mediatek/apummu_export.h" +#include "linux/soc/mediatek/apummu_mem_def.h" +#include "linux/soc/mediatek/apu_mem_export.h" +#include "linux/soc/mediatek/apu_mem_def.h" + +bool mdw_pwr_check(void) +{ + // return apusys_power_check(); + return true; +} + +static int mdw_mem_type_convert(uint32_t type, uint32_t *out) +{ + switch (type) { + case MDW_MEM_TYPE_VLM: + *out = APUMMU_MEM_TYPE_VLM; + break; + case MDW_MEM_TYPE_LOCAL: + *out = APUMMU_MEM_TYPE_RSV_T; + break; + case MDW_MEM_TYPE_SYSTEM_ISP: + *out = APUMMU_MEM_TYPE_EXT; + break; + case MDW_MEM_TYPE_SYSTEM_APU: + *out = APUMMU_MEM_TYPE_RSV_S; + break; + + default: + return -EINVAL; + } + + return 0; +} + +int mdw_apu_mem_alloc(uint32_t type, uint32_t size, + uint64_t *addr, uint32_t *sid) +{ + uint32_t mapped_type = 0; + int ret = 0; + + if (mdw_mem_type_convert(type, &mapped_type)) + return -EINVAL; + + ret = apu_mem_alloc(mapped_type, size, addr, sid); + mdw_flw_debug("type(%u->%u)size(%u)addr(0x%llx)sid(%u)\n", + type, mapped_type, size, *addr, *sid); + + return ret; +} + +int mdw_apu_mem_free(uint32_t sid) +{ + mdw_flw_debug("sid(%u)\n", sid); + return apu_mem_free(sid); +} + +int mdw_apu_mem_import(uint64_t session, uint32_t sid) +{ + mdw_flw_debug("s(0x%llx)sid(%u)\n", (uint64_t)session, sid); + return apu_mem_import(session, sid); +} + +int mdw_apu_mem_unimport(uint64_t session, uint32_t sid) +{ + mdw_flw_debug("s(0x%llx)sid(%u)\n", (uint64_t)session, sid); + return apu_mem_unimport(session, sid); +} + +int mdw_apu_mem_map(uint64_t session, uint32_t sid, uint64_t *vaddr) +{ + int ret = 0; + + ret = apu_mem_map(session, sid, vaddr); + mdw_flw_debug("s(0x%llx)sid(%u)vaddr(0x%llx)\n", + session, sid, *vaddr); + + return ret; +} + +int mdw_apu_mem_unmap(uint64_t session, uint32_t sid) +{ + mdw_flw_debug("s(0x%llx)sid(%u)\n", (uint64_t)session, sid); + return apu_mem_unmap(session, sid); +} + +int mdw_ammu_eva2iova(uint64_t eva, uint64_t *iova) +{ + return apu_mem_iova_decode(eva, iova); +} + +// int mdw_qos_cmd_start(uint64_t cmd_id, uint64_t sc_id, +// int type, int core, uint32_t boost) +// { +// return apu_cmd_qos_start(cmd_id, sc_id, type, core, boost); +// } + +// int mdw_qos_cmd_end(uint64_t cmd_id, uint64_t sc_id, +// int type, int core) +// { +// return apu_cmd_qos_end(cmd_id, sc_id, type, core); +// } diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.h new file mode 100644 index 0000000000000..5c8a9cf9ac7f8 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_import.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_IMPORT_H__ +#define __MTK_APU_MDW_IMPORT_H__ + +/* import function */ +bool mdw_pwr_check(void); + +int mdw_apu_mem_alloc(uint32_t type, uint32_t size, + uint64_t *addr, uint32_t *sid); +int mdw_apu_mem_free(uint32_t sid); +int mdw_apu_mem_import(uint64_t session, uint32_t sid); +int mdw_apu_mem_unimport(uint64_t session, uint32_t sid); +int mdw_apu_mem_map(uint64_t session, uint32_t sid, uint64_t *vaddr); +int mdw_apu_mem_unmap(uint64_t session, uint32_t sid); + +int mdw_ammu_eva2iova(uint64_t eva, uint64_t *iova); + +int mdw_qos_cmd_start(uint64_t cmd_id, uint64_t sc_id, + int type, int core, uint32_t boost); +int mdw_qos_cmd_end(uint64_t cmd_id, uint64_t sc_id, + int type, int core); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.c new file mode 100644 index 0000000000000..c1e0290273ce0 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include + +#include "mdw_ioctl.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" + +long mdw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + unsigned int usize = 0, nr = _IOC_NR(cmd); + void *kdata = NULL; + struct mdw_fpriv *mpriv = filp->private_data; + + /* check nr before any actions */ + if (nr < APU_MDW_IOCTL_START || nr > APU_MDW_IOCTL_END) { + mdw_drv_debug("not support nr(%u)\n", nr); + return -ENOTTY; + } + + /* allocate for user data */ + usize = _IOC_SIZE(cmd); + /* check kzalloc return */ + kdata = kzalloc(usize, GFP_KERNEL); + if (unlikely(ZERO_OR_NULL_PTR(kdata))) + return -ENOMEM; + /* copy from user data */ + if (cmd & IOC_IN) { + if (copy_from_user(kdata, (void __user *)arg, usize)) { + ret = -EFAULT; + goto out; + } + } + + switch (cmd) { + case APU_MDW_IOCTL_HANDSHAKE: + ret = mdw_hs_ioctl(mpriv, kdata); + break; + case APU_MDW_IOCTL_MEM: + ret = mdw_mem_ioctl(mpriv, kdata); + break; + case APU_MDW_IOCTL_CMD: + ret = mdw_cmd_ioctl(mpriv, kdata); + break; + case APU_MDW_IOCTL_UTIL: + ret = mdw_util_ioctl(mpriv, kdata); + break; + default: + ret = -EFAULT; + goto out; + } + + /* copy to user data */ + if (cmd & IOC_OUT) { + if (copy_to_user((void __user *)arg, kdata, usize)) { + ret = -EFAULT; + goto out; + } + } + +out: + kfree(kdata); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.h new file mode 100644 index 0000000000000..35483743ffb11 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_ioctl.h @@ -0,0 +1,341 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MTK_APU_IOCTL_H__ +#define __MTK_APU_IOCTL_H__ + +#include +#include + +#define APUSYS_MAGICNO 'A' + +enum mdw_hs_ioctl_op { + MDW_HS_IOCTL_OP_BASIC, + MDW_HS_IOCTL_OP_DEV, + MDW_HS_IOCTL_OP_MEM, +}; + +struct mdw_hs_in { + uint32_t op; //enum mdw_hs_ioctl_op + uint64_t flags; + union { + struct { + uint32_t type; + } dev; + struct { + uint32_t type; + } mem; + }; +}; + +#define MDW_DEV_META_SIZE (32) + +struct mdw_hs_out { + union { + struct { + uint64_t version; + uint64_t dev_bitmask; + uint64_t mem_bitmask; + uint64_t flags; + uint32_t meta_size; + uint32_t reserved; + } basic; + + struct { + uint32_t type; + uint32_t num; + char meta[MDW_DEV_META_SIZE]; + } dev; + + struct { + uint32_t type; + uint32_t reserved; + uint64_t start; + uint32_t size; + } mem; + }; +}; + +union mdw_hs_args { + struct mdw_hs_in in; + struct mdw_hs_out out; +}; + +#define APU_MDW_IOCTL_HANDSHAKE \ + _IOWR(APUSYS_MAGICNO, 32, union mdw_hs_args) + +enum mdw_mem_ioctl_op { + MDW_MEM_IOCTL_ALLOC, + MDW_MEM_IOCTL_FREE, + MDW_MEM_IOCTL_MAP, + MDW_MEM_IOCTL_UNMAP, + MDW_MEM_IOCTL_FLUSH, + MDW_MEM_IOCTL_INVALIDATE, + MDW_MEM_IOCTL_ALLOC_FB, +}; + +enum mdw_mem_flag { + MDW_MEM_FLAG_CACHEABLE = 0, + MDW_MEM_FLAG_32BIT = 1, + MDW_MEM_FLAG_HIGHADDR = 2, +}; +#define F_MDW_MEM_CACHEABLE (1ULL << MDW_MEM_FLAG_CACHEABLE) +#define F_MDW_MEM_32BIT (1ULL << MDW_MEM_FLAG_32BIT) +#define F_MDW_MEM_HIGHADDR (1ULL << MDW_MEM_FLAG_HIGHADDR) + +enum mdw_mem_type { + MDW_MEM_TYPE_MAIN, + MDW_MEM_TYPE_VLM, + MDW_MEM_TYPE_LOCAL, + MDW_MEM_TYPE_SYSTEM, + MDW_MEM_TYPE_SYSTEM_ISP, + MDW_MEM_TYPE_SYSTEM_APU, + + MDW_MEM_TYPE_MAX, +}; + +struct mdw_mem_in { + uint32_t op; //enum mdw_mem_ioctl_op + uint64_t flags; + union { + /* alloc */ + struct { + uint32_t type; //enum mdw_mem_type + uint64_t size; + uint64_t align; + uint64_t flags; + } alloc; + struct { + uint64_t handle; + } free; + + /* map */ + struct { + uint64_t handle; + uint64_t size; + uint64_t flags; + uint64_t reserved; + } map; + struct { + uint64_t handle; + } unmap; + + /* cache operation */ + struct { + uint64_t handle; + uint32_t offset; + uint32_t size; + } flush; + struct { + uint64_t handle; + uint32_t offset; + uint32_t size; + } invalidate; + + /* alloc DRAM fallback */ + struct { + uint32_t total_vlm_size; + uint32_t num_subcmds; + uint64_t reserved; + } alloc_fb; + }; +}; + +struct mdw_mem_out { + union { + struct { + uint64_t handle; + } alloc; + struct { + uint32_t type; + uint64_t device_va; + } map; + struct { + uint64_t device_va; + uint64_t size; + } import; + }; +}; + +union mdw_mem_args { + struct mdw_mem_in in; + struct mdw_mem_out out; +}; +#define APU_MDW_IOCTL_MEM \ + _IOWR(APUSYS_MAGICNO, 33, union mdw_mem_args) + +enum mdw_cmd_ioctl_op { + MDW_CMD_IOCTL_RUN, + MDW_CMD_IOCTL_RUN_STALE, + MDW_CMD_IOCTL_DEL, + MDW_CMD_IOCTL_ENQ, +}; + +enum { + /* cmdbuf copy in before execution and copy out after execution */ + MDW_CB_BIDIRECTIONAL, + /* cmdbuf copy in before execution */ + MDW_CB_IN, + /* cmdbuf copy out after execution */ + MDW_CB_OUT, +}; + +struct mdw_subcmd_exec_info { + uint32_t driver_time; + uint32_t ip_time; + uint32_t ip_start_ts; + uint32_t ip_end_ts; + uint32_t bw; + uint32_t boost; + uint32_t tcm_usage; + int32_t ret; + uint32_t was_preempted; + uint32_t executed_core_bitmap; + uint32_t vsid; +}; + +struct mdw_cmd_exec_info { + uint64_t sc_rets; + int64_t ret; + uint64_t total_us; + uint64_t inference_id; +}; + +struct mdw_subcmd_cmdbuf { + uint64_t handle; + uint32_t size; + uint32_t align; + uint32_t direction; +}; + +struct mdw_subcmd_info { + uint32_t type; + uint32_t suggest_time; + uint32_t vlm_usage; + uint32_t vlm_ctx_id; + uint32_t vlm_force; + uint32_t boost; + uint32_t turbo_boost; + uint32_t min_boost; + uint32_t max_boost; + uint32_t hse_en; + uint32_t pack_id; + uint32_t driver_time; + uint32_t ip_time; + uint32_t bw; + uint32_t affinity; + uint32_t trigger_type; + + /* cmdbufs */ + uint32_t num_cmdbufs; + uint64_t cmdbufs; +}; + +struct mdw_subcmd_link_v1 { + uint32_t producer_idx; + uint32_t consumer_idx; + uint32_t vid; + uint64_t va; + uint64_t x; + uint64_t y; +}; + +struct mdw_cmd_in { + uint32_t op; + uint64_t reserved; + int64_t id; + union { + struct { + uint64_t uid; + uint32_t priority; + uint32_t hardlimit; + uint32_t softlimit; + uint32_t fastmem_ms; + uint32_t power_save; + uint32_t power_plcy; + uint32_t power_dtime; + uint32_t power_etime; + uint32_t app_type; + uint32_t flags; + uint32_t num_subcmds; + uint64_t subcmd_infos; + uint64_t adj_matrix; + uint64_t fence; + uint64_t exec_infos; + uint32_t num_links; + uint64_t links; + uint32_t inference_ms; + uint32_t tolerance_ms; + uint64_t is_dtime_set; + uint32_t u_pid; + } exec; + }; +}; + +struct mdw_cmd_out { + union { + struct { + uint64_t id; + uint64_t fence; + uint64_t cmd_done_usr; + uint64_t ext_id; + uint64_t reserved; + } exec; + }; +}; + +union mdw_cmd_args { + struct mdw_cmd_in in; + struct mdw_cmd_out out; +}; + +#define APU_MDW_IOCTL_CMD \ + _IOWR(APUSYS_MAGICNO, 34, union mdw_cmd_args) + +enum mdw_util_ioctl_op { + MDW_UTIL_IOCTL_SETPOWER, + MDW_UTIL_IOCTL_UCMD, + MDW_UTIL_IOCTL_INFO, +}; + +enum mdw_util_info_type { + MDW_UTIL_INFO_POWERPOLICY, + + MDW_UTIL_INFO_MAX, +}; + +struct mdw_util_in { + uint32_t op; //enum mdw_util_ioctl_op + union { + struct { + uint32_t dev_type; + uint32_t core_idx; + uint32_t boost; + uint64_t reserve; + } power; + struct { + uint32_t dev_type; + uint32_t size; + uint64_t handle; + } ucmd; + struct { + uint32_t type; + uint64_t value; + uint64_t reserve; + } info; + }; +}; + +union mdw_util_args { + struct mdw_util_in in; +}; + +#define APU_MDW_IOCTL_UTIL \ + _IOWR(APUSYS_MAGICNO, 35, union mdw_util_args) + +#define APU_MDW_IOCTL_START (32) +#define APU_MDW_IOCTL_END (35) + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.c new file mode 100644 index 0000000000000..d8a7cdd264efa --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.c @@ -0,0 +1,1131 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem.h" +#include "mdw_mem_rsc.h" +#include "mdw_trace.h" +#include "mdw_mem_pool.h" +#include "linux/soc/mediatek/apummu_export.h" +#include "linux/soc/mediatek/apu_mem_export.h" +#include "linux/soc/mediatek/apu_mem_def.h" + +#define mdw_mem_show(m) \ + mdw_mem_debug("mem(0x%llx/0x%llx/%d/0x%llx/%d/0x%llx/0x%llx/0x%llx" \ + "/0x%llx/0x%llx/%llu/0x%llx/%d/%p)(%d)(%u)\n", \ + (uint64_t)m->mpriv, (uint64_t)m, m->handle, (uint64_t)m->dbuf, \ + m->type, (uint64_t)m->vaddr, m->size, \ + m->device_va, m->device_iova, m->dva_size, m->align, m->flags, \ + m->need_handle, m->priv, task_pid_nr(current), m->buf_type) + + +void mdw_mem_put(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + dma_buf_put(m->dbuf); +} + +struct mdw_mem *mdw_mem_get(struct mdw_fpriv *mpriv, int handle) +{ + struct dma_buf *dbuf = NULL; + struct mdw_device *mdev = mpriv->mdev; + struct mdw_mem *m = NULL, *tmp = NULL; + + dbuf = dma_buf_get(handle); + if (IS_ERR_OR_NULL(dbuf)) { + mdw_drv_err("get dma_buf handle(%d) fail\n", handle); + return NULL; + } + + mutex_lock(&mdev->m_mtx); + list_for_each_entry_safe(m, tmp, &mdev->m_list, d_node) { + if (m->dbuf == dbuf) { + mutex_unlock(&mdev->m_mtx); + return m; + } + } + mutex_unlock(&mdev->m_mtx); + + dma_buf_put(dbuf); + mdw_mem_debug("handle(%d) not belong to apu\n", handle); + + return NULL; +} + +static struct mdw_mem *mdw_mem_get_by_dbuf(struct mdw_fpriv *mpriv, struct dma_buf *dbuf) +{ + struct mdw_device *mdev = mpriv->mdev; + struct mdw_mem *m = NULL, *tmp = NULL; + + mutex_lock(&mdev->m_mtx); + list_for_each_entry_safe(m, tmp, &mdev->m_list, d_node) { + if (m->dbuf == dbuf) { + get_dma_buf(dbuf); + mutex_unlock(&mdev->m_mtx); + return m; + } + } + mutex_unlock(&mdev->m_mtx); + + mdw_mem_debug("dmabuf not belong to apu\n"); + + return NULL; +} + +void mdw_mem_all_print(struct mdw_fpriv *mpriv) +{ + struct list_head *tmp = NULL, *list_ptr = NULL; + struct mdw_mem *m = NULL; + + mdw_mem_debug("---list--\n"); + mutex_lock(&mpriv->mtx); + list_for_each_safe(list_ptr, tmp, &mpriv->mems) { + m = list_entry(list_ptr, struct mdw_mem, u_item); + mdw_mem_show(m); + } + mutex_unlock(&mpriv->mtx); + mdw_mem_debug("---list--\n"); +} + +static void mdw_mem_release(struct mdw_mem *m, bool put_mpriv) +{ + struct mdw_device *mdev = m->mpriv->mdev; + struct mdw_fpriv *mpriv = m->mpriv; + + mdw_mem_show(m); + + mutex_lock(&mdev->m_mtx); + list_del(&m->d_node); + mutex_unlock(&mdev->m_mtx); + + if (m->belong_apu) + list_del(&m->u_item); + + kfree(m); + + if (put_mpriv == true) + mpriv->put(mpriv); +} + +static void mdw_mem_delete(struct mdw_mem *m) +{ + struct mdw_fpriv *mpriv = m->mpriv; + + mutex_lock(&mpriv->mtx); + mdw_mem_release(m, false); + mutex_unlock(&mpriv->mtx); + + mpriv->put(mpriv); +} + +static struct mdw_mem *mdw_mem_create(struct mdw_fpriv *mpriv) +{ + struct mdw_mem *m = NULL; + struct mdw_device *mdev = mpriv->mdev; + + m = kzalloc(sizeof(*m), GFP_KERNEL); + if (m) { + m->mpriv = mpriv; + m->release = mdw_mem_delete; + m->handle = -1; + m->pool = NULL; + INIT_LIST_HEAD(&m->p_chunk); + mutex_init(&m->mtx); + INIT_LIST_HEAD(&m->maps); + mdw_mem_show(m); + mpriv->get(mpriv); + mutex_lock(&mdev->m_mtx); + list_add_tail(&m->d_node, &mdev->m_list); + mutex_unlock(&mdev->m_mtx); + } + + return m; +} + +static int mdw_mem_gen_handle(struct mdw_mem *m) +{ + int ret = 0; + + if (IS_ERR_OR_NULL(m->dbuf) || m->handle >= 0) + return -EINVAL; + + /* create fd from dma-buf */ + m->handle = dma_buf_fd(m->dbuf, + (O_RDWR | O_CLOEXEC) & ~O_ACCMODE); + if (m->handle < 0) { + mdw_drv_err("create handle for dmabuf(%d) fail\n", m->type); + ret = -EINVAL; + } + + return ret; +} + +static int mdw_mem_alloc_internal(struct mdw_mem *m) +{ + int ret = 0; + + switch (m->type) { + case MDW_MEM_TYPE_MAIN: + ret = mdw_mem_dma_alloc(m); + break; + case MDW_MEM_TYPE_LOCAL: + case MDW_MEM_TYPE_VLM: + case MDW_MEM_TYPE_SYSTEM_ISP: + case MDW_MEM_TYPE_SYSTEM_APU: + ret = mdw_mem_aram_alloc(m); + break; + case MDW_MEM_TYPE_SYSTEM: + default: + ret = -EINVAL; + break; + } + + return ret; +} + +long mdw_mem_set_name(struct mdw_mem *m, const char *buf) +{ + char *name = NULL; + + if (IS_ERR_OR_NULL(m->dbuf)) + return -EINVAL; + + name = kstrndup(buf, DMA_BUF_NAME_LEN, GFP_KERNEL); + if (IS_ERR(name)) + return PTR_ERR(name); + + spin_lock(&m->dbuf->name_lock); + kfree(m->dbuf->name); + m->dbuf->name = name; + spin_unlock(&m->dbuf->name_lock); + + return 0; +} + +struct mdw_mem *mdw_mem_alloc(struct mdw_fpriv *mpriv, enum mdw_mem_type type, + uint64_t size, uint64_t align, uint64_t flags, bool need_handle) +{ + struct mdw_mem *m = NULL; + int ret = -EINVAL; + + mdw_trace_begin("apumdw:mem_alloc|size:%llu align:%llu", + size, align); + + /* create mem struct */ + m = mdw_mem_create(mpriv); + if (!m) + goto out; + + /* setup in args */ + m->size = size; + m->align = align; + m->flags = flags; + m->type = type; + m->belong_apu = true; + m->need_handle = need_handle; + list_add_tail(&m->u_item, &mpriv->mems); + + /* alloc mem */ + ret = mdw_mem_alloc_internal(m); + if (ret || IS_ERR_OR_NULL(m->dbuf)) { + mdw_drv_err("alloc mem(%d/%d/%p) fail(%d)\n", + m->type, m->need_handle, m->dbuf, ret); + goto delete_mem; + } + + /* generate handle */ + if (need_handle) { + ret = mdw_mem_gen_handle(m); + if (ret) { + mdw_drv_err("generate mem handle fail\n"); + dma_buf_put(m->dbuf); + m = NULL; + goto out; + } + } + + mdw_mem_show(m); + goto out; + +delete_mem: + /* delete mem struct */ + mdw_mem_release(m, true); + m = NULL; +out: + mdw_trace_end(); + return m; +} + +void mdw_mem_free(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + mdw_mem_show(m); + + mdw_trace_begin("apumdw:mem_free|size:%llu align:%llu", + m->size, m->align); + + dma_buf_put(m->dbuf); + + mdw_trace_end(); +} + +static void mdw_mem_map_release(struct kref *ref) +{ + struct mdw_mem_map *map = + container_of(ref, struct mdw_mem_map, map_ref); + struct mdw_mem *m = map->m; + struct dma_buf *dbuf = m->dbuf; + + mdw_mem_show(m); + + /* unmap device va */ + mutex_lock(&m->mtx); + mdw_trace_begin("apumdw:detach|size:%llu align:%llu", + m->size, m->align); + dma_buf_unmap_attachment_unlocked(map->attach, + map->sgt, DMA_BIDIRECTIONAL); + mdw_trace_end(); + mdw_trace_begin("apumdw:unmap|size:%llu align:%llu", + m->size, m->align); + dma_buf_detach(m->dbuf, map->attach); + mdw_trace_end(); + m->device_va = 0; + m->dva_size = 0; + m->map = NULL; + kfree(map); + mutex_unlock(&m->mtx); + + /* delete mem struct */ + if (m->belong_apu == false) + mdw_mem_release(m, true); + + /* put dma buf ref from map */ + dma_buf_put(dbuf); +} + +static void mdw_mem_map_put(struct mdw_mem_map *map) +{ + if (map) + kref_put(&map->map_ref, mdw_mem_map_release); +} + +static void mdw_mem_map_get(struct mdw_mem_map *map) +{ + if (map) + kref_get(&map->map_ref); +} + +static int mdw_mem_map_create(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + struct mdw_mem_map *map = NULL; + struct scatterlist *sg = NULL; + int ret = 0, i = 0; + uint64_t eva = 0; + bool is_apummu = false; + + mutex_lock(&m->mtx); + get_dma_buf(m->dbuf); + if (m->map) { + mdw_drv_err("mem(0x%llx) already map\n", (uint64_t)m->map); + ret = -EINVAL; + goto out; + } + + /* check size */ + if (m->size > m->dbuf->size) { + mdw_drv_err("m(0x%llx/0x%llx/%d/0x%llx) size not match(%llu/%zu)\n", + (uint64_t)m->mpriv, (uint64_t)m, m->handle, (uint64_t)m->dbuf, + m->size, m->dbuf->size); + ret = -EINVAL; + goto out; + } + + if (!m->mdev) { + if (m->flags & F_MDW_MEM_HIGHADDR) + m->mdev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_DATA); + else + m->mdev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_CODE); + + if (!m->mdev) { + mdw_drv_err("get mem dev fail\n"); + ret = -ENODEV; + goto out; + } + } + + mdw_mem_debug("mem flags(%llx) dev %s\n", m->flags, dev_name(m->mdev)); + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) { + ret = -ENOMEM; + goto out; + } + + map->get = mdw_mem_map_get; + map->put = mdw_mem_map_put; + + /* attach device */ + mdw_trace_begin("apumdw:attach|size:%llu align:%llu", + m->size, m->align); + map->attach = dma_buf_attach(m->dbuf, m->mdev); + if (IS_ERR(map->attach)) { + ret = PTR_ERR(map->attach); + mdw_drv_err("dma_buf_attach failed: %d\n", ret); + mdw_trace_end(); + goto free_map; + } + mdw_trace_end(); + + /* map device va */ + mdw_trace_begin("apumdw:map|size:%llu align:%llu", + m->size, m->align); + map->sgt = dma_buf_map_attachment_unlocked(map->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(map->sgt)) { + ret = PTR_ERR(map->sgt); + mdw_drv_err("dma_buf_map_attachment_unlocked failed: %d\n", ret); + mdw_trace_end(); + goto detach_dbuf; + } + mdw_trace_end(); + + /* get start addr and size */ + m->device_iova = sg_dma_address(map->sgt->sgl); + for_each_sgtable_dma_sg(map->sgt, sg, i) { + if (!sg) + break; + m->dva_size += sg_dma_len(sg); + } + + /* check iova and size */ + if (!m->device_iova || !m->dva_size) { + mdw_drv_err("can't get mem(0x%llx) iova(0x%llx/%llu)\n", + (uint64_t)m, m->device_va, m->dva_size); + ret = -ENOMEM; + goto unmap_dbuf; + } + + if (mpriv->mdev->mdw_ver < 4) { + m->device_va = m->device_iova; + goto skip_iova2eva; + } + /* handle iova to eva */ + mdw_trace_begin("apummu:iova2eva|iova:0x%llx,size:%llu btype(%d)", + m->device_iova, m->dva_size, m->buf_type); + ret = apu_mem_map_iova(m->buf_type, (uint64_t)m->mpriv, m->device_iova, m->dva_size, &eva); + mdw_trace_end(); + + if (ret) { + mdw_drv_err("apu_mem_map_iova fail s(0x%llx) ret(%d)\n", (uint64_t)m->mpriv, ret); + is_apummu = true; + ret = -EINVAL; + goto unmap_dbuf; + } + + m->device_va = eva; + + /* check eva */ + if (!m->device_va) { + mdw_drv_err("can't get mem(0x%llx) dva(0x%llx)\n", + (uint64_t)m, m->device_va); + ret = -ENOMEM; + goto unmap_dbuf; + } + mdw_mem_debug("iova2eva pass s(0x%llx)\n", (uint64_t)m->mpriv); + +skip_iova2eva: + map->m = m; + m->map = map; + kref_init(&map->map_ref); + mdw_mem_show(m); + goto out; + +unmap_dbuf: + dma_buf_unmap_attachment_unlocked(map->attach, + map->sgt, DMA_BIDIRECTIONAL); +detach_dbuf: + dma_buf_detach(m->dbuf, map->attach); +free_map: + mdw_mem_show(m); + m->device_iova = 0; + m->device_va = 0; + m->dva_size = 0; + m->map = NULL; + kfree(map); +out: + if (ret) { + if (is_apummu == false) + mdw_exception("%s:map dva fail, type(%u) size(%llu)\n", + current->comm, m->type, m->size); + dma_buf_put(m->dbuf); + } + mutex_unlock(&m->mtx); + + return ret; +} + +static void mdw_mem_invoke_release(struct kref *ref) +{ + struct mdw_mem_invoke *m_invoke = + container_of(ref, struct mdw_mem_invoke, ref); + struct mdw_mem_map *map = m_invoke->m->map; + struct mdw_mem *m = m_invoke->m; + struct dma_buf *dbuf = m_invoke->m->dbuf; + + mdw_mem_show(m_invoke->m); + if (m->unbind) + m->unbind(m_invoke->invoker, m_invoke->m); + list_del(&m_invoke->u_node); + kfree(m_invoke); + map->put(map); + dma_buf_put(dbuf); +} + +static struct mdw_mem_invoke *mdw_mem_invoke_find(struct mdw_fpriv *mpriv, + struct mdw_mem *m) +{ + struct mdw_mem_invoke *m_invoke = NULL; + + list_for_each_entry(m_invoke, &mpriv->invokes, u_node) { + if (m_invoke->m == m) { + mdw_flw_debug("s(0x%llx) find invoke(0x%llx) to mem(0x%llx)\n", + (uint64_t)mpriv, (uint64_t)m_invoke, + (uint64_t)m); + return m_invoke; + } + } + + return NULL; +} + +static void mdw_mem_invoke_put(struct mdw_mem_invoke *m_invoke) +{ + if (m_invoke) { + mdw_mem_show(m_invoke->m); + kref_put(&m_invoke->ref, mdw_mem_invoke_release); + } +} + +static void mdw_mem_invoke_get(struct mdw_mem_invoke *m_invoke) +{ + if (m_invoke) { + mdw_mem_show(m_invoke->m); + kref_get(&m_invoke->ref); + } +} + +static int mdw_mem_invoke_create(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + struct mdw_mem_invoke *m_invoke = NULL; + struct mdw_mem_map *map = m->map; + int ret = 0; + + m_invoke = kzalloc(sizeof(*m_invoke), GFP_KERNEL); + if (!m_invoke) + return -ENOMEM; + + get_dma_buf(m->dbuf); + map->get(map); + mdw_mem_show(m); + m_invoke->m = m; + m_invoke->invoker = mpriv; + m_invoke->get = mdw_mem_invoke_get; + m_invoke->put = mdw_mem_invoke_put; + kref_init(&m_invoke->ref); + list_add_tail(&m_invoke->u_node, &mpriv->invokes); + if (m->bind) { + ret = m->bind(mpriv, m); + if (ret) { + mdw_drv_err("m(0x%llx) bind usr(0x%llx) fail\n", + (uint64_t)m, (uint64_t)mpriv); + goto delete_invoke; + } + } + + goto out; + +delete_invoke: + list_del(&m_invoke->u_node); + map->put(map); + dma_buf_put(m->dbuf); + kfree(m_invoke); +out: + return ret; +} + +int mdw_mem_map(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + struct mdw_mem_invoke *m_invoke = NULL; + int ret = 0; + uint64_t eva = 0; + + if (IS_ERR_OR_NULL(m->dbuf)) { + mdw_drv_err("mem dbuf invalid (0x%llx)\n", (uint64_t) m); + return -EINVAL; + } + + mdw_trace_begin("apumdw:mem_map|size:%llu", m->size); + get_dma_buf(m->dbuf); + + mdw_mem_show(m); + + /* handle map */ + if (m->map == NULL) { + ret = mdw_mem_map_create(mpriv, m); + if (ret) { + mdw_drv_err("m(0x%llx) map fail(%d)\n", + (uint64_t)m, ret); + goto out; + } else { + /* map create ok, create invoke for map */ + ret = mdw_mem_invoke_create(mpriv, m); + if (ret) + mdw_drv_err("m(0x%llx) create invoke fail(%d)\n", + (uint64_t)m, ret); + } + + m->map->put(m->map); + goto out; + } else { + if (mpriv->mdev->mdw_ver < 4) + goto skip_iova2eva; + /* handle iova2eva */ + mdw_trace_begin("apummu:iova2eva|iova:0x%llx,size:%llu btype(%d)", + m->device_iova, m->dva_size, m->buf_type); + ret = apu_mem_map_iova(m->buf_type, (uint64_t)mpriv, m->device_iova, + m->dva_size, &eva); + mdw_trace_end(); + if (ret) { + mdw_drv_err("apu_mem_map_iova fail s(0x%llx) ret(%d),\n", (uint64_t)mpriv, ret); + ret = -EINVAL; + goto out; + } + + /* check eva */ + if (!m->device_va) { + mdw_drv_err("can't get mem(0x%llx) dva(0x%llx)\n", + (uint64_t)m, m->device_va); + ret = -ENOMEM; + goto out; + } + mdw_mem_debug("iova2eva pass s(0x%llx)\n", (uint64_t)mpriv); + } + +skip_iova2eva: + /* handle invoke */ + m_invoke = mdw_mem_invoke_find(mpriv, m); + mdw_flw_debug("0x%llx\n", (uint64_t)m_invoke); + if (m_invoke) { + m_invoke->get(m_invoke); + } else { + ret = mdw_mem_invoke_create(mpriv, m); + if (ret) + mdw_drv_err("m(0x%llx) invoke fail(%d)\n", + (uint64_t)m, ret); + } + + goto out; + +out: + dma_buf_put(m->dbuf); + mdw_trace_end(); + + return ret; +} + +int mdw_mem_unmap(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + struct mdw_mem_invoke *m_invoke = NULL; + int ret = 0; + + mdw_mem_show(m); + m_invoke = mdw_mem_invoke_find(mpriv, m); + if (m_invoke == NULL) { + mdw_drv_warn("s(0x%llx) no invoke m(0x%llx)\n", + (uint64_t)mpriv, (uint64_t)m); + ret = -EINVAL; + goto out; + } + + m_invoke->put(m_invoke); + +out: + return ret; +} + +int mdw_mem_flush(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + int ret = 0; + + if (m->pool) + return mdw_mem_pool_flush(m); + + mdw_trace_begin("apumdw:mem_flush|size:%llu", m->dva_size); + ret = dma_buf_end_cpu_access(m->dbuf, DMA_TO_DEVICE); + if (ret) { + mdw_drv_err("Flush Fail\n"); + ret = -EINVAL; + goto out; + } + + mdw_mem_show(m); +out: + mdw_trace_end(); + return ret; +} + +int mdw_mem_invalidate(struct mdw_fpriv *mpriv, struct mdw_mem *m) +{ + int ret = 0; + + if (m->pool) + return mdw_mem_pool_invalidate(m); + + mdw_trace_begin("apumdw:mem_invalidate|size:%llu", m->dva_size); + + ret = dma_buf_begin_cpu_access(m->dbuf, DMA_FROM_DEVICE); + if (ret) { + mdw_drv_err("Invalidate Fail\n"); + ret = -EINVAL; + goto out; + } + + mdw_mem_show(m); +out: + mdw_trace_end(); + return ret; +} + +void mdw_mem_mpriv_release(struct mdw_fpriv *mpriv) +{ + struct mdw_mem_invoke *m_invoke = NULL, *tmp = NULL; + + list_for_each_entry_safe(m_invoke, tmp, &mpriv->invokes, u_node) { + if (m_invoke->m->handle >= 0) { + mdw_mem_show(m_invoke->m); + mdw_mem_invoke_release(&m_invoke->ref); + } + } +} + +static int mdw_mem_ioctl_alloc(struct mdw_fpriv *mpriv, + union mdw_mem_args *args) +{ + struct mdw_mem_in *in = (struct mdw_mem_in *)args; + struct mdw_mem *m = NULL; + int ret = 0; + + if (!in->alloc.size) { + mdw_drv_err("invalid size(%llu)\n", in->alloc.size); + return -EINVAL; + } + + mutex_lock(&mpriv->mtx); + + m = mdw_mem_alloc(mpriv, in->alloc.type, in->alloc.size, + in->alloc.align, in->alloc.flags, true); + memset(args, 0, sizeof(*args)); + if (!m) { + mdw_drv_err("mdw_mem_alloc fail\n"); + ret = -ENOMEM; + goto out; + } + + args->out.alloc.handle = m->handle; + mdw_mem_show(m); + +out: + mutex_unlock(&mpriv->mtx); + return ret; +} + +static int mdw_mem_ioctl_alloc_fb(struct mdw_fpriv *mpriv, + union mdw_mem_args *args) +{ + struct mdw_mem_in *in = (struct mdw_mem_in *)args; + int ret = 0; + + if (!in->alloc_fb.total_vlm_size) { + mdw_drv_warn("invalid size(%u)\n", in->alloc_fb.total_vlm_size); + return -EINVAL; + } + + mdw_mem_debug("size(%u) num_subcmds(%u)\n", + in->alloc_fb.total_vlm_size, in->alloc_fb.num_subcmds); + mdw_trace_begin("apummu:alloc dram fb|size:%u", + in->alloc_fb.total_vlm_size); + ret = apummu_DRAM_FB_alloc((uint64_t)mpriv, in->alloc_fb.total_vlm_size, + in->alloc_fb.num_subcmds); + mdw_trace_end(); + + if (ret) + mdw_drv_err("apummu: alloc fb size(%u) fail(%d) num_subcmds(%u)\n", + in->alloc_fb.total_vlm_size, ret, + in->alloc_fb.num_subcmds); + + return ret; +} + +static int mdw_mem_ioctl_map(struct mdw_fpriv *mpriv, + union mdw_mem_args *args) +{ + struct mdw_mem_in *in = (struct mdw_mem_in *)args; + struct mdw_mem *m = NULL; + struct dma_buf *dbuf = NULL; + int ret = -ENOMEM, handle = (int)in->map.handle; + uint64_t size = in->map.size; + uint64_t flags = in->map.flags; + bool in_highaddr = (flags & F_MDW_MEM_HIGHADDR) ? true : false; + bool m_highaddr = false; + + memset(args, 0, sizeof(*args)); + + dbuf = dma_buf_get(handle); + if (IS_ERR_OR_NULL(dbuf)) { + mdw_drv_err("handle(%d) not dmabuf\n", handle); + return -EINVAL; + } + + mutex_lock(&mpriv->mtx); + mutex_lock(&mpriv->mdev->mctl_mtx); + + /* query mem from apu's mem list */ + m = mdw_mem_get_by_dbuf(mpriv, dbuf); + if (!m) { + m = mdw_mem_create(mpriv); + if (!m) { + mdw_drv_err("create mdw mem fail\n"); + goto out; + } else { + m->size = size; + m->dbuf = dbuf; + m->type = MDW_MEM_TYPE_MAIN; + m->handle = handle; + m->flags = flags; + } + } else { + mdw_mem_put(mpriv, m); + } + + /* Compare user input addr with memory addr */ + m_highaddr = (m->flags & F_MDW_MEM_HIGHADDR) ? true : false; + if (in_highaddr != m_highaddr) { + mdw_drv_err("input addr flags(%llx) not match with m->flags(%llx)\n", + flags, m->flags); + ret = -EINVAL; + goto out; + } + + /* map apu va */ + ret = mdw_mem_map(mpriv, m); + if (ret && m->belong_apu == false) { + mdw_drv_err("map dmabuf(%d) fail\n", handle); + mdw_mem_release(m, true); + m = NULL; + goto out; + } + + mdw_mem_show(m); + goto out; + +out: + if (m) { + args->out.map.device_va = m->device_va; + args->out.map.type = m->type; + } + dma_buf_put(dbuf); + mutex_unlock(&mpriv->mdev->mctl_mtx); + mutex_unlock(&mpriv->mtx); + if (ret || !m) + mdw_drv_err("handle(%d) m(%p) ret(%d)\n", handle, m, ret); + + return ret; +} + +static int mdw_mem_ioctl_unmap(struct mdw_fpriv *mpriv, + union mdw_mem_args *args) +{ + struct mdw_mem_in *in = (struct mdw_mem_in *)args; + struct mdw_mem *m = NULL; + int ret = -ENOMEM, handle = in->unmap.handle; + + memset(args, 0, sizeof(*args)); + + mutex_lock(&mpriv->mtx); + mutex_lock(&mpriv->mdev->mctl_mtx); + m = mdw_mem_get(mpriv, handle); + if (!m) + goto out; + else + mdw_mem_put(mpriv, m); + + mdw_mem_show(m); + ret = mdw_mem_unmap(mpriv, m); + +out: + mutex_unlock(&mpriv->mdev->mctl_mtx); + mutex_unlock(&mpriv->mtx); + if (ret) + mdw_drv_err("handle(%d) ret(%d)\n", handle, ret); + + return ret; +} + +int mdw_mem_ioctl(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_mem_args *args = (union mdw_mem_args *)data; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op::%d\n", (uint64_t)mpriv, args->in.op); + switch (args->in.op) { + case MDW_MEM_IOCTL_ALLOC: + ret = mdw_mem_ioctl_alloc(mpriv, args); + break; + + case MDW_MEM_IOCTL_MAP: + ret = mdw_mem_ioctl_map(mpriv, args); + break; + + case MDW_MEM_IOCTL_UNMAP: + ret = mdw_mem_ioctl_unmap(mpriv, args); + break; + + case MDW_MEM_IOCTL_ALLOC_FB: + ret = mdw_mem_ioctl_alloc_fb(mpriv, args); + break; + + case MDW_MEM_IOCTL_FREE: + case MDW_MEM_IOCTL_FLUSH: + case MDW_MEM_IOCTL_INVALIDATE: + default: + mdw_drv_warn("not support memory op(%d)\n", args->in.op); + ret = -EINVAL; + break; + } + + return ret; +} + +int mdw_mem_init(struct mdw_device *mdev) +{ + int ret = 0; + + mutex_init(&mdev->m_mtx); + mutex_init(&mdev->mctl_mtx); + INIT_LIST_HEAD(&mdev->m_list); + mdw_drv_info("set mem done\n"); + + return ret; +} + +void mdw_mem_deinit(struct mdw_device *mdev) +{ +} + +struct mdw_mem *mdw_mem_query_mem(uint64_t kva) +{ + struct mdw_mem *m = NULL, *tmp = NULL; + + mutex_lock(&mdw_dev->m_mtx); + list_for_each_entry_safe(m, tmp, &mdw_dev->m_list, d_node) { + if (kva >= (uint64_t)m->vaddr && + kva < (uint64_t)m->vaddr + m->size) { + + mdw_mem_debug("query iova (0x%llx->0x%llx)\n", + kva, (uint64_t)m); + mutex_unlock(&mdw_dev->m_mtx); + return m; + } + } + mutex_unlock(&mdw_dev->m_mtx); + + return NULL; +} + +int apusys_mem_validate_by_cmd(void *session, void *cmd, uint64_t eva, uint32_t size) +{ + struct mdw_fpriv *mpriv = (struct mdw_fpriv *)session; + struct mdw_cmd *c = (struct mdw_cmd *)cmd; + struct mdw_device *mdev = mpriv->mdev; + struct mdw_mem_invoke *m_invoke = NULL; + struct mdw_mem *m = NULL; + uint64_t iova; + int ret = 0; + + ret = mdw_ammu_eva2iova(eva, &iova); + if (ret) { + mdw_drv_err("Apummu ev2iova fail\n"); + return ret; + } + + mdw_vld_debug("target: s(0x%llx) c(0x%llx) iova(0x%llx/%u)\n", + (uint64_t)mpriv, (uint64_t)c, iova, size); + + if (c) { + /* check c/s match */ + if (c->mpriv != session) { + mdw_drv_err("session(0x%llx) cmd(0x%llx) not match\n", + (uint64_t)mpriv, (uint64_t)c); + return -EINVAL; + } + } + + /* query from mpriv invoke list */ + list_for_each_entry(m_invoke, &mpriv->invokes, u_node) { + m = m_invoke->m; + mdw_vld_debug("check mem invoke list: va(0x%llx/%llu) iova(0x%llx/%llu)...\n", + (uint64_t)m->vaddr, m->size, m->device_iova, m->dva_size); + if (iova < m->device_iova || iova + size > m->device_iova + m->dva_size) + continue; + mdw_vld_debug("check mem invoke list: va(0x%llx/%llu) iova(0x%llx/%llu) match\n", + (uint64_t)m->vaddr, m->size, m->device_iova, m->dva_size); + if (c) { + ret = mdw_cmd_invoke_map(c, m->map); + if (ret) { + mdw_drv_err("s(0x%llx)c(0x%llx)m(0x%llx/%u)get map fail(%d)\n", + (uint64_t)session, (uint64_t)cmd, + iova, size, ret); + } + } + return ret; + } + + /* check vlm */ + if (test_bit(MDW_MEM_TYPE_VLM, mdev->mem_mask) && + size && + iova >= mdev->minfos[MDW_MEM_TYPE_VLM].device_iova && + iova + size <= mdev->minfos[MDW_MEM_TYPE_VLM].device_iova + + mdev->minfos[MDW_MEM_TYPE_VLM].dva_size) { + mdw_vld_debug("m(0x%llx/%u) in vlm range(0x%llx/%llu)\n", + iova, size, + mdev->minfos[MDW_MEM_TYPE_VLM].device_iova, + mdev->minfos[MDW_MEM_TYPE_VLM].dva_size); + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL_NS(apusys_mem_validate_by_cmd, MTK_APU_MDW); + +int apusys_mem_get_by_iova(void *session, uint64_t iova) +{ + return 0; +} + +void *apusys_mem_query_kva_by_sess(void *session, uint64_t eva) +{ + struct mdw_fpriv *mpriv = (struct mdw_fpriv *)session; + struct mdw_mem_invoke *m_invoke = NULL; + struct mdw_mem *m = NULL; + uint64_t iova; + + if (mdw_ammu_eva2iova(eva, &iova)) { + mdw_drv_err("Apummu ev2iova fail\n"); + return NULL; + } + + + list_for_each_entry(m_invoke, &mpriv->invokes, u_node) { + m = m_invoke->m; + if (iova >= m->device_iova && + iova < m->device_iova + m->dva_size && + m->vaddr) + return m->vaddr + (iova - m->device_iova); + } + + return NULL; +} +EXPORT_SYMBOL_NS(apusys_mem_query_kva_by_sess, MTK_APU_MDW); + +int apusys_mem_flush_kva(void *kva, uint32_t size) +{ + struct mdw_mem *m = NULL; + int ret = 0; + + m = mdw_mem_query_mem((uint64_t)kva); + if (!m) { + mdw_drv_err("No Mem\n"); + ret = -ENOMEM; + goto out; + } + + ret = mdw_mem_flush(m->mpriv, m); + mdw_mem_debug("flush kva 0x%llx\n", (uint64_t)kva); + +out: + return ret; +} + +int apusys_mem_invalidate_kva(void *kva, uint32_t size) +{ + struct mdw_mem *m = NULL; + int ret = 0; + + m = mdw_mem_query_mem((uint64_t)kva); + if (!m) { + mdw_drv_err("No Mem\n"); + ret = -ENOMEM; + goto out; + } + + ret = mdw_mem_invalidate(m->mpriv, m); + + mdw_mem_debug("invalidate kva 0x%llx\n", (uint64_t)kva); +out: + return ret; +} + +uint64_t apusys_mem_query_kva(uint64_t iova) +{ + struct mdw_mem *m = NULL, *tmp = NULL; + uint64_t kva = 0; + + mutex_lock(&mdw_dev->m_mtx); + list_for_each_entry_safe(m, tmp, &mdw_dev->m_list, d_node) { + if (iova >= m->device_va && + iova < m->device_va + m->size) { + if (m->vaddr == NULL) + break; + + kva = (uint64_t)m->vaddr + (iova - m->device_va); + mdw_mem_debug("query kva (0x%llx->0x%llx)\n", + iova, kva); + } + } + mutex_unlock(&mdw_dev->m_mtx); + + return kva; +} + +uint64_t apusys_mem_query_iova(uint64_t kva) +{ + struct mdw_mem *m = NULL, *tmp = NULL; + uint64_t iova = 0; + + mutex_lock(&mdw_dev->m_mtx); + list_for_each_entry_safe(m, tmp, &mdw_dev->m_list, d_node) { + if (kva >= (uint64_t)m->vaddr && + kva < (uint64_t)m->vaddr + m->size) { + if (!m->device_va) + break; + + iova = m->device_va + (kva - (uint64_t)m->vaddr); + mdw_mem_debug("query iova (0x%llx->0x%llx)\n", + kva, iova); + } + } + mutex_unlock(&mdw_dev->m_mtx); + + return iova; +} + +MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS(MTK_APU_MEM); diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.h new file mode 100644 index 0000000000000..f163cbc15a564 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_MEM_H__ +#define __MTK_APU_MDW_MEM_H__ + +int mdw_mem_dma_alloc(struct mdw_mem *mem); +int mdw_mem_aram_alloc(struct mdw_mem *mem); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_aram.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_aram.c new file mode 100644 index 0000000000000..9b298c40fb136 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_aram.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mdw_cmn.h" +#include "mdw_mem.h" +#include "mdw_mem_rsc.h" + +struct mdw_mem_aram { + dma_addr_t dma_addr; + uint64_t dma_size; + uint64_t addr; + uint32_t sid; + struct mdw_mem *m; + + struct list_head attachments; + struct mutex mtx; +}; + +struct mdw_mem_aram_attachment { + struct mdw_mem_aram *am; + struct mdw_mem *m; + struct sg_table sgt; + struct list_head node; +}; + +static int mdw_mem_aram_attach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct mdw_mem_aram_attachment *am_attach = NULL; + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_aram *am = m->priv; + int ret = 0; + + /* check type */ + if (m->type >= MDW_MEM_TYPE_MAX || + m->type == MDW_MEM_TYPE_MAIN) { + mdw_drv_err("invalid type(%u)\n", m->type); + return -EINVAL; + } + + /* alloc attach */ + am_attach = kzalloc(sizeof(*am_attach), GFP_KERNEL); + if (!am_attach) { + ret = -ENOMEM; + goto out; + } + + /* alloc sg table */ + ret = sg_alloc_table(&am_attach->sgt, 1, GFP_KERNEL); + if (ret) + goto free_attach; + + /* map vlm */ + if (m->type == MDW_MEM_TYPE_SYSTEM_ISP) { + mdw_mem_debug("s(0x%llx) bypass vlm map\n", + (uint64_t)m->mpriv); + am->dma_addr = am->addr; + } else { + uint64_t dma_addr = am->dma_addr; + ret = mdw_apu_mem_map((uint64_t)m->mpriv, am->sid, &dma_addr); + if (ret) { + mdw_drv_err("apumem(0x%llx/%u) map fail\n", + (uint64_t)m->mpriv, am->sid); + goto free_table; + } + am->dma_addr = dma_addr; + } + + sg_dma_address(am_attach->sgt.sgl) = am->dma_addr; + sg_dma_len(am_attach->sgt.sgl) = am->dma_size; + am_attach->am = am; + am_attach->m = m; + attach->priv = am_attach; + mdw_mem_debug("s(0x%llx) sg(%p) m(%u/%pad/0x%x)\n", + (uint64_t)m->mpriv, + &am_attach->sgt, + am->sid, + &sg_dma_address(am_attach->sgt.sgl), + sg_dma_len(am_attach->sgt.sgl)); + + mutex_lock(&am->mtx); + list_add_tail(&am_attach->node, &am->attachments); + mutex_unlock(&am->mtx); + + goto out; + +free_table: + sg_free_table(&am_attach->sgt); +free_attach: + kfree(am_attach); +out: + return ret; +} + +static void mdw_mem_aram_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct mdw_mem_aram_attachment *am_attach = attach->priv; + struct mdw_mem_aram *am = am_attach->am; + struct mdw_mem *m = am->m; + int ret = 0; + + mutex_lock(&am->mtx); + list_del(&am_attach->node); + mutex_unlock(&am->mtx); + + if (m->type == MDW_MEM_TYPE_SYSTEM_ISP) { + mdw_mem_debug("s(0x%llx) bypass vlm unmap\n", + (uint64_t)m->mpriv); + } else { + ret = mdw_apu_mem_unmap((uint64_t)m->mpriv, am->sid); + if (ret) { + mdw_drv_warn("s(0x%llx) unmap sid(%u) fail\n", + (uint64_t)m->mpriv, am->sid); + } + } + + sg_free_table(&am_attach->sgt); + kfree(am_attach); + mdw_mem_debug("\n"); +} + +static struct sg_table *mdw_mem_aram_map_dma(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct mdw_mem_aram_attachment *am_attach = attach->priv; + + mdw_mem_debug("\n"); + return &am_attach->sgt; +} + +static void mdw_mem_aram_unmap_dma(struct dma_buf_attachment *attach, + struct sg_table *sgt, enum dma_data_direction dir) +{ + mdw_mem_debug("\n"); +} + +static void mdw_mem_aram_unprepare(struct mdw_mem_aram *am) +{ + mdw_mem_debug("type(%u)sid(%u)m(%pad/0x%llx)\n", + am->m->type, am->sid, &am->dma_addr, am->dma_size); + + switch (am->m->type) { + case MDW_MEM_TYPE_VLM: + case MDW_MEM_TYPE_LOCAL: + case MDW_MEM_TYPE_SYSTEM: + case MDW_MEM_TYPE_SYSTEM_ISP: + case MDW_MEM_TYPE_SYSTEM_APU: + if (mdw_apu_mem_free(am->sid)) + mdw_mem_debug("free apumem type(%u)sid(%u)m(%pad/0x%llx) fail\n", + am->m->type, am->sid, + &am->dma_addr, am->dma_size); + break; + + default: + mdw_drv_warn("not support apumem(%u)\n", + am->m->type); + break; + } +} + +static void mdw_mem_aram_release(struct dma_buf *dbuf) +{ + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_aram *am = m->priv; + + mdw_mem_debug("\n"); + mdw_mem_aram_unprepare(am); + kfree(am); + m->release(m); +} + +static struct dma_buf_ops mdw_mem_aram_ops = { + .attach = mdw_mem_aram_attach, + .detach = mdw_mem_aram_detach, + .map_dma_buf = mdw_mem_aram_map_dma, + .unmap_dma_buf = mdw_mem_aram_unmap_dma, + .release = mdw_mem_aram_release, +}; + +static int mdw_mem_aram_prepare(struct mdw_fpriv *mpriv, + struct mdw_mem_aram *am) +{ + int ret = 0; + + mdw_mem_debug("type(%u)size(0x%llx)\n", am->m->type, am->m->size); + switch (am->m->type) { + case MDW_MEM_TYPE_VLM: + case MDW_MEM_TYPE_LOCAL: + case MDW_MEM_TYPE_SYSTEM: + case MDW_MEM_TYPE_SYSTEM_ISP: + case MDW_MEM_TYPE_SYSTEM_APU: + ret = mdw_apu_mem_alloc(am->m->type, + (uint32_t)am->m->size, &am->addr, &am->sid); + if (ret) { + mdw_drv_err("alloc apuram(%u/%llu) fail(%d)\n", + am->m->type, am->m->size, ret); + } else { + am->dma_size = am->m->size; + } + break; + + default: + mdw_drv_warn("not support apumem(%u)\n", am->m->type); + ret = -EINVAL; + break; + } + + return ret; +} + +static int mdw_mem_aram_bind(void *session, struct mdw_mem *m) +{ + struct mdw_mem_aram *am = (struct mdw_mem_aram *)m->priv; + + mdw_mem_debug("s(0x%llx) m(0x%llx/%u/%u)\n", + (uint64_t)session, (uint64_t)m, m->type, am->sid); + if (m->mpriv == session) { + mdw_mem_debug("s(0x%llx) don't need bind\n", (uint64_t)session); + return 0; + } + + if (m->type == MDW_MEM_TYPE_SYSTEM_ISP) { + mdw_mem_debug("s(0x%llx) bypass vlm bind\n", + (uint64_t)m->mpriv); + return 0; + } + + return mdw_apu_mem_import((uint64_t)session, am->sid); +} + +static void mdw_mem_aram_unbind(void *session, struct mdw_mem *m) +{ + struct mdw_mem_aram *am = (struct mdw_mem_aram *)m->priv; + + mdw_mem_debug("s(0x%llx) m(0x%llx/%u/%u)\n", + (uint64_t)session, (uint64_t)m, m->type, am->sid); + if (m->mpriv == session) { + mdw_mem_debug("s(0x%llx) don't need unbind\n", (uint64_t)session); + return; + } + + if (m->type == MDW_MEM_TYPE_SYSTEM_ISP) { + mdw_mem_debug("s(0x%llx) bypass vlm unbind\n", + (uint64_t)m->mpriv); + return; + } + + mdw_apu_mem_unimport((uint64_t)session, am->sid); +} + +int mdw_mem_aram_alloc(struct mdw_mem *m) +{ + struct mdw_mem_aram *am = NULL; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + int ret = 0; + + /* alloc mdw dma-buf container */ + am = kzalloc(sizeof(*am), GFP_KERNEL); + if (!am) + return -ENOMEM; + + mutex_init(&am->mtx); + INIT_LIST_HEAD(&am->attachments); + am->m = m; + m->bind = mdw_mem_aram_bind; + m->unbind = mdw_mem_aram_unbind; + m->priv = am; + + ret = mdw_mem_aram_prepare(m->mpriv, am); + if (ret) { + mdw_drv_err("prepare apumem(%u) fail\n", m->type); + goto free_aram; + } + + /* export as dma-buf */ + exp_info.ops = &mdw_mem_aram_ops; + exp_info.size = am->dma_size; + exp_info.flags = O_RDWR | O_CLOEXEC; + exp_info.priv = m; + m->dbuf = dma_buf_export(&exp_info); + if (IS_ERR(m->dbuf)) { + mdw_drv_err("dma_buf_export Fail\n"); + ret = -ENOMEM; + goto unprepare_aram; + } + + goto out; + +unprepare_aram: + mdw_mem_aram_unprepare(am); +free_aram: + kfree(am); +out: + return ret; +} +MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS(MTK_APU_MEM); diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_dma.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_dma.c new file mode 100644 index 0000000000000..b5ced7b102b92 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_dma.c @@ -0,0 +1,467 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mdw_mem_rsc.h" +#include "mdw_cmn.h" +#include "mdw_mem.h" +#include "mdw_trace.h" + +struct mdw_mem_dma_attachment { + struct sg_table *sgt; + struct device *dev; + struct list_head node; + bool mapped; + bool uncached; +}; + +struct mdw_mem_dma { + dma_addr_t dma_addr; + uint64_t dma_size; + uint32_t size; + + void *vaddr; + struct list_head attachments; + struct sg_table sgt; + void *buf; + + bool uncached; + + struct mutex mtx; + + struct mdw_mem *mmem; + struct device *mem_dev; +}; + +#define mdw_mem_dma_show(d) \ + mdw_mem_debug("mem(0x%llx/%d/0x%llx/0x%llx/%pad/0x%llx/%d/%ld)(%d)\n", \ + (uint64_t) d->mmem, d->mmem->handle, (uint64_t)d->mmem->vaddr, d->mmem->size, \ + &d->dma_addr, d->dma_size, d->mmem->need_handle, \ + file_count(d->mmem->dbuf->file), task_pid_nr(current)) + +static struct sg_table *mdw_mem_dma_dup_sg(struct sg_table *table) +{ + struct sg_table *new_table; + int ret, i; + struct scatterlist *sg, *new_sg; + + new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); + if (!new_table) + return ERR_PTR(-ENOMEM); + + ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL); + if (ret) { + kfree(new_table); + return ERR_PTR(-ENOMEM); + } + + new_sg = new_table->sgl; + for_each_sgtable_sg(table, sg, i) { + sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset); + new_sg = sg_next(new_sg); + } + + return new_table; +} + +static int mdw_mem_dma_allocate_sgt(const char *buf, + size_t len, struct sg_table *sgt, bool uncached, void **vaddr) +{ + struct page **pages = NULL; + unsigned int nr_pages; + unsigned int index; + const char *p; + int ret; + pgprot_t pgprot = PAGE_KERNEL; + void *va; + + nr_pages = DIV_ROUND_UP((unsigned long)buf + len, PAGE_SIZE) + - ((unsigned long)buf / PAGE_SIZE); + pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); + + mdw_mem_debug("mdw buf: 0x%lx, len: 0x%zx, nr_pages: %d\n", + (unsigned long)buf, len, nr_pages); + + if (!pages) { + mdw_drv_err("No Page 0x%lx, len: 0x%zx, nr_pages: %d\n", + (unsigned long)buf, len, nr_pages); + return -ENOMEM; + } + + + p = buf - offset_in_page(buf); + mdw_mem_debug("start p: 0x%llx buf: 0x%llx\n", + (uint64_t) p, (uint64_t) buf); + + for (index = 0; index < nr_pages; index++) { + if (is_vmalloc_addr(p)) + pages[index] = vmalloc_to_page(p); + else + pages[index] = kmap_to_page((void *)p); + if (!pages[index]) { + kvfree(pages); + mdw_drv_err("map failed\n"); + return -EFAULT; + } + p += PAGE_SIZE; + } + if (uncached) + pgprot = pgprot_writecombine(PAGE_KERNEL); + + //vmap to set page property + va = vmap(pages, nr_pages, VM_MAP, pgprot); + + ret = sg_alloc_table_from_pages(sgt, pages, index, + offset_in_page(buf), len, GFP_KERNEL); + kvfree(pages); + if (ret) { + mdw_drv_err("sg_alloc_table_from_pages: %d\n", ret); + return ret; + } + + *vaddr = va; + + mdw_mem_debug("buf: 0x%lx, len: 0x%zx, sgt: 0x%lx nr_pages: %d va 0x%lx\n", + (unsigned long)buf, len, (unsigned long)sgt, nr_pages, (unsigned long)va); + + return 0; +} + +static int mdw_mem_dma_free_sgt(struct sg_table *sgt) +{ + int ret = 0; + + sg_free_table(sgt); + + return ret; +} + +static int mdw_dmabuf_attach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct mdw_mem_dma_attachment *a = NULL; + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + int ret = 0; + struct sg_table *table; + + mdw_mem_debug("dbuf(0x%llx)\n", (uint64_t)dbuf); + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + table = mdw_mem_dma_dup_sg(&mdbuf->sgt); + if (IS_ERR(table)) { + kfree(a); + return -ENOMEM; + } + + a->sgt = table; + a->dev = attach->dev; + INIT_LIST_HEAD(&a->node); + a->mapped = false; + a->uncached = mdbuf->uncached; + attach->priv = a; + + + mutex_lock(&mdbuf->mtx); + list_add(&a->node, &mdbuf->attachments); + mutex_unlock(&mdbuf->mtx); + + mdw_mem_dma_show(mdbuf); + + return ret; +} + +static void mdw_dmabuf_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct mdw_mem_dma_attachment *a = attach->priv; + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + + mdw_mem_debug("dbuf(0x%llx)\n", (uint64_t)dbuf); + + mutex_lock(&mdbuf->mtx); + list_del(&a->node); + mutex_unlock(&mdbuf->mtx); + + sg_free_table(a->sgt); + kfree(a->sgt); + kfree(a); + + mdw_mem_dma_show(mdbuf); +} + +static struct sg_table *mdw_dmabuf_map_dma(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct mdw_mem_dma_attachment *a = attach->priv; + struct sg_table *table = NULL; + // int attr = attach->dma_map_attrs; // As Linux kernel 6.6 doesn't have dma_map_attrs + int attr = 0; + int ret = 0; + + table = a->sgt; + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; + + ret = dma_map_sgtable(attach->dev, table, dir, attr); + if (ret) + table = ERR_PTR(ret); + + a->mapped = true; + mdw_mem_debug("\n"); + + return table; +} + +static void mdw_dmabuf_unmap_dma(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ + struct mdw_mem_dma_attachment *a = attach->priv; + // int attr = attach->dma_map_attrs; // As Linux kernel 6.6 doesn't have dma_map_attrs + int attr = 0; + + mdw_mem_debug("\n"); + + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; + + a->mapped = false; + dma_unmap_sgtable(attach->dev, sgt, dir, attr); +} + +static int mdw_dmabuf_vmap(struct dma_buf *dbuf, struct iosys_map *dbuf_map) +{ + struct mdw_mem_dma *mdbuf = dbuf->priv; + + mdw_mem_debug("dmabuf vmap: 0x%llx\n", (uint64_t) mdbuf->vaddr); + if (dbuf_map->is_iomem) + dbuf_map->vaddr_iomem = mdbuf->vaddr; + else + dbuf_map->vaddr = mdbuf->vaddr; + return 0; +} + +static int mdw_dmabuf_invalidate(struct dma_buf *dbuf, + enum dma_data_direction dir) +{ + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + + if (!mdbuf->vaddr) { + mdw_drv_err("mdbuf vaddr NULL\n"); + return -EINVAL; + } + + if (!mdbuf->uncached) { + dma_sync_sgtable_for_cpu(mdbuf->mem_dev, + &mdbuf->sgt, DMA_FROM_DEVICE); + mdw_mem_debug("mem invalidate(0x%llx)\n", (uint64_t)m); + } + + mdw_mem_dma_show(mdbuf); + return 0; +} + +static int mdw_dmabuf_flush(struct dma_buf *dbuf, + enum dma_data_direction dir) +{ + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + + if (!mdbuf->vaddr) { + mdw_drv_err("mdbuf vaddr NULL\n"); + return -EINVAL; + } + + if (!mdbuf->uncached) { + dma_sync_sgtable_for_device(mdbuf->mem_dev, + &mdbuf->sgt, DMA_TO_DEVICE); + mdw_mem_debug("mem flush(0x%llx)\n", (uint64_t) m); + } + + mdw_mem_dma_show(mdbuf); + + return 0; +} + +static void mdw_dmabuf_release(struct dma_buf *dbuf) +{ + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + + mdw_mem_dma_show(mdbuf); + + mdw_mem_dma_free_sgt(&mdbuf->sgt); + vunmap(mdbuf->vaddr); + vfree(mdbuf->buf); + kfree(mdbuf); + m->release(m); +} + +static int mdw_dmabuf_mmap(struct dma_buf *dbuf, + struct vm_area_struct *vma) +{ + struct mdw_mem *m = dbuf->priv; + struct mdw_mem_dma *mdbuf = m->priv; + struct sg_table *table = &mdbuf->sgt; + unsigned long addr = vma->vm_start; + struct sg_page_iter piter; + int ret = 0; + + mdw_mem_debug("%p/%p\n", m, mdbuf); + + if (mdbuf->uncached) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + for_each_sgtable_page(table, &piter, vma->vm_pgoff) { + struct page *page = sg_page_iter_page(&piter); + + ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, + vma->vm_page_prot); + if (ret) + return ret; + addr += PAGE_SIZE; + if (addr >= vma->vm_end) + return 0; + } + mdw_mem_dma_show(mdbuf); + return ret; +} + +static int mdw_mem_dma_bind(void *session, struct mdw_mem *m) +{ + return 0; +} + +static void mdw_mem_dma_unbind(void *session, struct mdw_mem *m) +{ +} + +static struct dma_buf_ops mdw_dmabuf_ops = { + .attach = mdw_dmabuf_attach, + .detach = mdw_dmabuf_detach, + .map_dma_buf = mdw_dmabuf_map_dma, + .unmap_dma_buf = mdw_dmabuf_unmap_dma, + .vmap = mdw_dmabuf_vmap, + .mmap = mdw_dmabuf_mmap, + .begin_cpu_access = mdw_dmabuf_invalidate, + .end_cpu_access = mdw_dmabuf_flush, + .release = mdw_dmabuf_release, +}; + +int mdw_mem_dma_alloc(struct mdw_mem *mem) +{ + struct mdw_mem_dma *mdbuf = NULL; + int ret = 0; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct device *dev; + void *kva; + bool uncached = true; + + /* alloc mdw dma-buf container */ + mdbuf = kzalloc(sizeof(*mdbuf), GFP_KERNEL); + if (!mdbuf) + return -ENOMEM; + + mutex_init(&mdbuf->mtx); + INIT_LIST_HEAD(&mdbuf->attachments); + + /* alloc buffer by dma */ + mdbuf->dma_size = PAGE_ALIGN(mem->size); + mdw_mem_debug("alloc mem(0x%llx)(%llu/%llu)\n", + (uint64_t) mem, mem->size, mdbuf->dma_size); + + if (mem->flags & F_MDW_MEM_HIGHADDR) { + dev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_DATA); + if (dev) + mdw_mem_debug("data %llx dev %s\n", + mem->flags, dev_name(dev)); + } else { + dev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_CODE); + if (dev) + mdw_mem_debug("code %llx dev %s\n", + mem->flags, dev_name(dev)); + } + if (mem->flags & F_MDW_MEM_CACHEABLE) + uncached = false; + else + uncached = true; + + if (!dev) { + mdw_drv_err("dev invalid\n"); + ret = -ENOMEM; + goto free_mdw_dbuf; + } + + kva = vzalloc(mdbuf->dma_size); + if (!kva) { + ret = -ENOMEM; + goto free_mdw_dbuf; + } + + mdbuf->buf = kva; + + if (mdw_mem_dma_allocate_sgt( + kva, mdbuf->dma_size, &mdbuf->sgt, + uncached, &mdbuf->vaddr)) { + mdw_drv_err("get sgt: failed\n"); + ret = -ENOMEM; + goto free_buf; + } + + /* export as dma-buf */ + exp_info.ops = &mdw_dmabuf_ops; + exp_info.size = mdbuf->dma_size; + exp_info.flags = O_RDWR | O_CLOEXEC; + exp_info.priv = mem; + + mem->dbuf = dma_buf_export(&exp_info); + if (IS_ERR(mem->dbuf)) { + mdw_drv_err("dma_buf_export Fail\n"); + ret = -ENOMEM; + goto free_sgt; + } + + mdbuf->mmem = mem; + mdbuf->mem_dev = dev; + mdbuf->size = mem->size; + mdbuf->uncached = uncached; + /* access data to mdw_mem */ + mem->vaddr = mdbuf->vaddr; + mem->mdev = dev; + mem->priv = mdbuf; + mem->bind = mdw_mem_dma_bind; + mem->unbind = mdw_mem_dma_unbind; + + if (uncached) { + dma_sync_sgtable_for_device(mdbuf->mem_dev, + &mdbuf->sgt, DMA_TO_DEVICE); + } + + mdw_mem_dma_show(mdbuf); + goto out; + +free_sgt: + mdw_mem_dma_free_sgt(&mdbuf->sgt); +free_buf: + vfree(kva); +free_mdw_dbuf: + kfree(mdbuf); +out: + return ret; +} +MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS(MTK_APU_MEM); diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.c new file mode 100644 index 0000000000000..8be9650d6f06e --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mdw_mem_rsc.h" +#include "mdw_cmn.h" +#include "mdw_mem.h" + +static int apumem_probe(struct platform_device *pdev) +{ + int ret = 0; + uint32_t type = 0; + uint64_t mask = 0; + struct device *dev = &pdev->dev; + + pr_info("%s start, dev:%s\n", __func__, dev_name(&pdev->dev)); + + of_property_read_u64(pdev->dev.of_node, "mask", &mask); + of_property_read_u32(pdev->dev.of_node, "type", &type); + + + pr_info("%s mask 0x%llx type %u\n", __func__, mask, type); + + ret = dma_set_mask_and_coherent(dev, mask); + if (ret) { + dev_info(&pdev->dev, "unable to set DMA mask coherent: %d\n", ret); + return ret; + } + + pr_info("%s dma_set_mask_and_coherent 0x%llx type %u\n", __func__, mask, type); + + ret = dma_set_mask(dev, mask); + if (ret) { + dev_info(&pdev->dev, "unable to set DMA mask: %d\n", ret); + return ret; + } + + pr_info("%s dma_set_mask 0x%llx type %u\n", __func__, mask, type); + + if (!pdev->dev.dma_parms) { + pdev->dev.dma_parms = + devm_kzalloc(dev, sizeof(*pdev->dev.dma_parms), GFP_KERNEL); + } + if (pdev->dev.dma_parms) { + ret = dma_set_max_seg_size(dev, mask); + if (ret) + dev_info(dev, "Failed to set DMA segment size\n"); + } + + mdw_mem_rsc_register(&pdev->dev, type); + + pr_info("%s +\n", __func__); + + + return ret; +} + +static int apumem_remove(struct platform_device *pdev) +{ + int type = 0; + + of_property_read_u32(pdev->dev.of_node, "type", &type); + mdw_mem_rsc_unregister(type); + + pr_info("%s +\n", __func__); + return 0; +} + +static const struct of_device_id mem_of_match[] = { + {.compatible = "mediatek, apu_mem_code" }, + {.compatible = "mediatek, apu_mem_data" }, + {}, +}; + +static struct platform_driver apumem_driver = { + .driver = { + .name = "apumem_driver", + .owner = THIS_MODULE, + .of_match_table = mem_of_match, + }, + .probe = apumem_probe, + .remove = apumem_remove, +}; + +int apumem_init(void) +{ + int ret = 0; + + mdw_mem_rsc_init(); + + ret = platform_driver_register(&apumem_driver); + if (ret) { + pr_info("failed to register apu mdw driver\n"); + goto out; + } + + pr_info("%s:%d\n", __func__, __LINE__); + + goto out; + +out: + return ret; +} + +void apumem_exit(void) +{ + pr_info("%s:%d\n", __func__, __LINE__); + platform_driver_unregister(&apumem_driver); + mdw_mem_rsc_deinit(); +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.h new file mode 100644 index 0000000000000..5491952f63265 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_drv.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_MEM_DRV_H__ +#define __MTK_APU_MDW_MEM_DRV_H__ + +int apumem_init(void); +void apumem_exit(void); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.c new file mode 100644 index 0000000000000..52be308698a21 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include "mdw.h" +#include "mdw_cmn.h" +#include "mdw_mem.h" +#include "mdw_mem_pool.h" +#include "mdw_trace.h" +#include "mdw_mem_rsc.h" +#include "linux/soc/mediatek/apummu_export.h" + +#define mdw_mem_pool_show(m) \ + mdw_mem_debug("mem_pool(0x%llx/0x%llx/%d/0x%llx/%d/0x%llx/0x%llx/0x%llx" \ + "/0x%llx/%llu/0x%llx/%d/%p)(%d)\n", \ + (uint64_t)m->mpriv, (uint64_t)m, m->handle, (uint64_t)m->dbuf, \ + m->type, (uint64_t)m->vaddr, m->size, \ + m->device_va, m->dva_size, m->align, m->flags, m->need_handle, \ + m->priv, task_pid_nr(current)) + +/* allocate a memory chunk, and add it to pool */ +static int mdw_mem_pool_chunk_add(struct mdw_mem_pool *pool, uint32_t size) +{ + int ret = 0, len = 0; + struct mdw_mem *m; + char buf_name[DMA_BUF_NAME_LEN]; + + mdw_trace_begin("apumdw:pool_chunk_add|size:%u", size); + + m = mdw_mem_alloc(pool->mpriv, pool->type, size, pool->align, + pool->flags, false); + if (!m) { + mdw_drv_err("mem_pool(0x%llx) create allocate fail, size: %d\n", + (uint64_t) pool->mpriv, size); + ret = -ENOMEM; + goto out; + } + + memset(buf_name, 0, sizeof(buf_name)); + len = snprintf(buf_name, sizeof(buf_name), "APU_CMDBUF_POOL:%u/%u", + task_pid_nr(current), task_tgid_nr(current)); + if (len >= sizeof(buf_name) || len < 0) { + mdw_drv_err("snprintf fail\n"); + ret = -EINVAL; + goto out; + } + + if (mdw_mem_set_name(m, buf_name)) { + mdw_drv_err("s(0x%llx) m(0x%llx) set name fail, size: %d\n", + (uint64_t)pool->mpriv, (uint64_t)m, size); + } + + m->buf_type = MDW_CMD_BUF; + + ret = mdw_mem_map(pool->mpriv, m); + if (ret) { + mdw_drv_err("mem_pool(0x%llx) create map fail\n", + (uint64_t)pool->mpriv); + ret = -ENOMEM; + goto err_map; + } + + mdw_mem_debug("mpriv: 0x%llx, pool: 0x%llx, new chunk mem: 0x%llx, kva: 0x%llx, iova: 0x%llx, size: %d", + (uint64_t)pool->mpriv, (uint64_t)pool, (uint64_t)m, + (uint64_t)m->vaddr, (uint64_t)m->device_va, size); + + ret = gen_pool_add_owner(pool->gp, (unsigned long)m->vaddr, + (phys_addr_t)m->device_va, m->size, -1, m); + + if (ret) { + mdw_drv_err("mem_pool(0x%llx) gen_pool add fail: %d\n", + (uint64_t) pool->mpriv, ret); + goto err_add; + } + list_add_tail(&m->p_chunk, &pool->m_chunks); + m->pool = pool; + mdw_mem_debug("add chunk: pool: 0x%llx, mem: 0x%llx, size: %d", + (uint64_t)m->pool, (uint64_t)m, size); + + /* record first dva for apummu */ + pool->mpriv->cb_head_device_va = m->device_va; + + goto out; + +err_add: + mdw_mem_unmap(pool->mpriv, m); + +err_map: + mdw_mem_free(pool->mpriv, m); + +out: + mdw_trace_end(); + + return ret; +} + +/* removes a memory chunk from pool, and free it */ +static void mdw_mem_pool_chunk_del(struct mdw_mem *m) +{ + mdw_trace_begin("apumdw:pool_chunk_del|size:%llu", m->size); + list_del(&m->p_chunk); + mdw_mem_debug("free chunk: pool: 0x%llx, mem: 0x%llx", + (uint64_t)m->pool, (uint64_t)m); + mdw_mem_unmap(m->mpriv, m); + mdw_mem_free(m->mpriv, m); + mdw_trace_end(); +} + +/* create memory pool */ +int mdw_mem_pool_create(struct mdw_fpriv *mpriv, struct mdw_mem_pool *pool, + enum mdw_mem_type type, uint32_t size, uint32_t align, uint64_t flags) +{ + int ret = 0; + + if (IS_ERR_OR_NULL(mpriv) || IS_ERR_OR_NULL(pool)) + return -EINVAL; + + /* TODO: cacheable command buffer */ + if (flags & F_MDW_MEM_CACHEABLE) { + mdw_drv_err("cacheable pool is unsupported: mpriv: 0x%llx", + (uint64_t)mpriv); + return -EINVAL; + } + + mdw_trace_begin("apumdw:pool_create|size:%u align:%u", size, align); + + pool->mpriv = mpriv; + pool->flags = flags; + pool->type = type; + pool->align = align; + pool->chunk_size = size; + mutex_init(&pool->m_mtx); + kref_init(&pool->m_ref); + INIT_LIST_HEAD(&pool->m_chunks); + INIT_LIST_HEAD(&pool->m_list); + pool->gp = gen_pool_create(PAGE_SHIFT, -1 /* nid */); + + if (IS_ERR(pool->gp)) { + ret = PTR_ERR(pool->gp); + mdw_drv_err("mem_pool(0x%llx) gen_pool init fail: %d\n", + (uint64_t) mpriv, ret); + goto out; + } + + ret = mdw_mem_pool_chunk_add(pool, size); + if (ret) + goto err_add; + + mdw_mem_debug("success, mpriv: 0x%llx, pool: 0x%llx", + (uint64_t)mpriv, (uint64_t)pool); + + goto out; + +err_add: + if (pool->gp) + gen_pool_destroy(pool->gp); + +out: + mdw_trace_end(); + + return ret; +} + +/* the release function when pool reference count reaches zero */ +static void mdw_mem_pool_release(struct kref *ref) +{ + struct mdw_mem_pool *pool; + struct mdw_mem *m = NULL, *tmp = NULL; + + pool = container_of(ref, struct mdw_mem_pool, m_ref); + if (IS_ERR_OR_NULL(pool->mpriv)) + return; + + mdw_trace_begin("apumdw:pool_release|size:%u align:%u", + pool->chunk_size, pool->align); + + /* release all allocated memories */ + list_for_each_entry_safe(m, tmp, &pool->m_list, d_node) { + /* This should not happen, when m_ref is zero */ + list_del(&m->d_node); + mdw_mem_debug("free mem: pool: 0x%llx, mem: 0x%llx", + (uint64_t)pool, (uint64_t)m); + gen_pool_free(pool->gp, (unsigned long)m->vaddr, m->size); + kfree(m); + } + + /* destroy gen pool */ + gen_pool_destroy(pool->gp); + + /* release all chunks */ + list_for_each_entry_safe(m, tmp, &pool->m_chunks, p_chunk) { + mdw_mem_pool_chunk_del(m); + } + + mdw_trace_end(); +} + +/* destroy memory pool */ +void mdw_mem_pool_destroy(struct mdw_mem_pool *pool) +{ + mdw_mem_debug("pool: 0x%llx", (uint64_t)pool); + mutex_lock(&pool->m_mtx); + kref_put(&pool->m_ref, mdw_mem_pool_release); + mutex_unlock(&pool->m_mtx); +} + +/* frees a mdw_mem struct */ +static void mdw_mem_pool_ent_release(struct mdw_mem *m) +{ + mdw_mem_pool_show(m); + kfree(m); +} + +/* allocates a mdw_mem struct */ +static struct mdw_mem *mdw_mem_pool_ent_create(struct mdw_mem_pool *pool) +{ + struct mdw_mem *m; + + m = kzalloc(sizeof(*m), GFP_KERNEL); + if (!m) + return NULL; + + m->pool = pool; + m->mpriv = pool->mpriv; + m->release = NULL; + m->handle = -1; + mutex_init(&m->mtx); + INIT_LIST_HEAD(&m->maps); + mdw_mem_pool_show(m); + + return m; +} + +/* alloc memory from pool, and alloc/add its mdw_mem struct to pool->list */ +struct mdw_mem *mdw_mem_pool_alloc(struct mdw_mem_pool *pool, uint64_t size, + uint32_t align) +{ + struct mdw_mem *m = NULL; + dma_addr_t dma; + bool retried = false; + unsigned long chunk_size; + int ret = 0; + + if (!pool || !size) + return NULL; + + mdw_trace_begin("apumdw:pool_alloc|size:%llu align:%u", + size, align); + + /* create mem struct */ + m = mdw_mem_pool_ent_create(pool); + if (!m) + goto out; + + /* setup in args */ + m->pool = pool; + m->size = size; + m->align = align; + m->flags = pool->flags; + m->type = pool->type; + m->belong_apu = true; + m->need_handle = false; + m->dbuf = NULL; + m->release = mdw_mem_pool_ent_release; + + /* alloc mem */ + mutex_lock(&pool->m_mtx); +retry: + m->vaddr = gen_pool_dma_alloc_align(pool->gp, size, &dma, align); + if (m->vaddr) { + list_add_tail(&m->d_node, &pool->m_list); + kref_get(&pool->m_ref); + } else { + /* try to add a new chunk to pool, and retry again */ + chunk_size = max(PAGE_SIZE, __roundup_pow_of_two(size)); + ret = mdw_mem_pool_chunk_add(pool, chunk_size); + if (!ret && !retried) { + retried = true; + goto retry; + } + } + mutex_unlock(&pool->m_mtx); + + if (!m->vaddr) { + mdw_drv_err("alloc (%p,%d,%llu,%d) fail\n", + pool, m->type, size, align); + goto err_alloc; + } + m->mdev = NULL; + m->device_va = dma; + m->dva_size = size; + + /* zero out the allocated buffer */ + memset(m->vaddr, 0, size); + + mdw_mem_pool_show(m); + goto out; + +err_alloc: + kfree(m); + m = NULL; + +out: + if (m) { + mdw_mem_debug("pool: 0x%llx, mem: 0x%llx, size: %llu, align: %d, kva: 0x%llx, iova: 0x%llx", + (uint64_t)pool, (uint64_t)m, size, align, + (uint64_t)m->vaddr, (uint64_t)m->device_va); + } + + mdw_trace_end(); + return m; +} + +/* free memory from pool, and free/delete its mdw_mem struct from pool->list */ +void mdw_mem_pool_free(struct mdw_mem *m) +{ + struct mdw_mem_pool *pool; + + if (!m) + return; + + pool = m->pool; + + if (!pool || !pool->gp) + return; + + mdw_trace_begin("apumdw:pool_free|size:%u align:%u", + m->size, m->align); + + mdw_mem_debug("pool: 0x%llx, mem: 0x%llx, size: %llu, kva: 0x%llx, iova: 0x%llx", + (uint64_t)pool, (uint64_t)m, m->size, + (uint64_t)m->vaddr, (uint64_t)m->device_va); + + + mutex_lock(&pool->m_mtx); + list_del(&m->d_node); + gen_pool_free(m->pool->gp, (unsigned long)m->vaddr, m->size); + kref_put(&pool->m_ref, mdw_mem_pool_release); + mutex_unlock(&pool->m_mtx); + + m->release(m); + + mdw_trace_end(); +} + +/* flush a memory, do nothing, if it's non-cacheable */ +int mdw_mem_pool_flush(struct mdw_mem *m) +{ + if (!m) + return 0; + + if (m->flags ^ F_MDW_MEM_CACHEABLE) + return 0; + + mdw_trace_begin("apumdw:pool_flush|size:%llu", m->dva_size); + /* TODO: cacheable command buffer */ + mdw_drv_err("cacheable buffer: pool: 0x%llx, mem: 0x%llx", + (uint64_t)m->pool, (uint64_t)m); + mdw_trace_end(); + + return -EINVAL; +} + +/* invalidate a memory, do nothing, if it's non-cacheable */ +int mdw_mem_pool_invalidate(struct mdw_mem *m) +{ + if (!m) + return 0; + + if (m->flags ^ F_MDW_MEM_CACHEABLE) + return 0; + + mdw_trace_begin("apumdw:pool_invalidate|size:%llu", m->dva_size); + /* TODO: cacheable command buffer */ + mdw_drv_err("cacheable buffer: pool: 0x%llx, mem: 0x%llx", + (uint64_t)m->pool, (uint64_t)m); + mdw_trace_end(); + + return -EINVAL; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.h new file mode 100644 index 0000000000000..acfe5fe7dfb0a --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_pool.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_MEM_POOL_H__ +#define __MTK_APU_MDW_MEM_POOL_H__ + +#include "mdw.h" + +int mdw_mem_pool_create(struct mdw_fpriv *mpriv, struct mdw_mem_pool *pool, + enum mdw_mem_type type, uint32_t size, uint32_t align, uint64_t flags); +void mdw_mem_pool_destroy(struct mdw_mem_pool *pool); + +struct mdw_mem *mdw_mem_pool_alloc(struct mdw_mem_pool *pool, uint64_t size, + uint32_t align); +void mdw_mem_pool_free(struct mdw_mem *m); + +int mdw_mem_pool_flush(struct mdw_mem *m); +int mdw_mem_pool_invalidate(struct mdw_mem *m); + +#endif + diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.c new file mode 100644 index 0000000000000..e13df0fdb38a9 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include + + +#include "mdw_cmn.h" +#include "mdw_mem_rsc.h" + +#define MDW_MEM_DOMAIN_MAX (2) + +static struct device *apu_dev; + +struct mdw_mem_rsc_mgr { + struct apusys_memory mdw_mem[MDW_MEM_DOMAIN_MAX]; + struct mutex mtx; +}; + +static struct mdw_mem_rsc_mgr rsc_mem_mgr; + +void mtk_apu_init_mdw_dev(struct device *dev) +{ + apu_dev = dev; +} +EXPORT_SYMBOL_NS(mtk_apu_init_mdw_dev, MTK_APU_MDW); + +int mdw_mem_rsc_init(void) +{ + memset(&rsc_mem_mgr, 0, sizeof(rsc_mem_mgr)); + mutex_init(&rsc_mem_mgr.mtx); + + pr_info("%s +\n", __func__); + + return 0; + +} +void mdw_mem_rsc_deinit(void) +{ + +} +struct device *mdw_mem_rsc_get_dev(int type) +{ + switch (type) { + case APUSYS_MEMORY_CODE: + return apu_dev; + case APUSYS_MEMORY_DATA: + return rsc_mem_mgr.mdw_mem[type - 1].dev; + default: + pr_info("Unsupported Type %d\n", type); + return NULL; + } +} + +int mdw_mem_rsc_register(struct device *dev, int type) +{ + int ret = 0; + + if (!dev) + return -EINVAL; + + mutex_lock(&rsc_mem_mgr.mtx); + switch (type) { + case APUSYS_MEMORY_CODE: + case APUSYS_MEMORY_DATA: + rsc_mem_mgr.mdw_mem[type - 1].mem_type = type; + if (rsc_mem_mgr.mdw_mem[type - 1].dev == NULL) + rsc_mem_mgr.mdw_mem[type - 1].dev = dev; + else { + ret = -EINVAL; + pr_info("Mulit-Register %d\n", type); + } + break; + default: + ret = -EINVAL; + pr_info("Unsupported Type %d\n", type); + break; + } + mutex_unlock(&rsc_mem_mgr.mtx); + + pr_info("Register type[%d] Done\n", type); + + return ret; +} + +int mdw_mem_rsc_unregister(int type) +{ + int ret = 0; + + mutex_lock(&rsc_mem_mgr.mtx); + switch (type) { + case APUSYS_MEMORY_CODE: + case APUSYS_MEMORY_DATA: + rsc_mem_mgr.mdw_mem[type - 1].mem_type = APUSYS_MEMORY_NONE; + rsc_mem_mgr.mdw_mem[type - 1].dev = NULL; + break; + default: + ret = -EINVAL; + break; + } + mutex_unlock(&rsc_mem_mgr.mtx); + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.h new file mode 100644 index 0000000000000..b471969387399 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_mem_rsc.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_MEM_RSC_H__ +#define __MTK_APU_MDW_MEM_RSC_H__ + +#include + +/* memory type */ +enum { + APUSYS_MEMORY_NONE, + + APUSYS_MEMORY_CODE, + APUSYS_MEMORY_DATA, + APUSYS_MEMORY_MAX = 64, //total support 64 different memory +}; + +struct apusys_memory { + struct device *dev; + int mem_type; +}; + + +int mdw_mem_rsc_register(struct device *dev, int type); +int mdw_mem_rsc_unregister(int type); + +int mdw_mem_rsc_init(void); +void mdw_mem_rsc_deinit(void); +struct device *mdw_mem_rsc_get_dev(int type); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.c new file mode 100644 index 0000000000000..3d060d2086a25 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "mdw_cmn.h" + +static uint32_t g_sched_plcy_show; + +static ssize_t reserv_time_remain_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t num = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + /* get dma normal task num */ + num = mdev->plat_funcs->get_info(mdev, MDW_INFO_RESERV_TIME_REMAIN); + ret = sprintf(buf, "%u\n", num); + if (ret < 0) + mdw_drv_warn("show reserv_time_remain fail(%d)\n", ret); + +out: + return ret; +} +static DEVICE_ATTR_RO(reserv_time_remain); + +static ssize_t dsp_task_num_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t num = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + /* get dma normal task num */ + num = mdev->plat_funcs->get_info(mdev, MDW_INFO_NORMAL_TASK_DSP); + ret = sprintf(buf, "%u\n", num); + if (ret < 0) + mdw_drv_warn("show dsp task num fail(%d)\n", ret); + +out: + return ret; +} +static DEVICE_ATTR_RO(dsp_task_num); + +static ssize_t dla_task_num_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t num = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + /* get dla normal task num */ + num = mdev->plat_funcs->get_info(mdev, MDW_INFO_NORMAL_TASK_DLA); + ret = sprintf(buf, "%u\n", num); + if (ret < 0) + mdw_drv_warn("show dla task num fail(%d)\n", ret); + +out: + return ret; +} +static DEVICE_ATTR_RO(dla_task_num); + +static ssize_t dma_task_num_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t num = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + /* get dma normal task num */ + num = mdev->plat_funcs->get_info(mdev, MDW_INFO_NORMAL_TASK_DMA); + ret = sprintf(buf, "%u\n", num); + if (ret < 0) + mdw_drv_warn("show dma task num fail(%d)\n", ret); + +out: + return ret; +} +static DEVICE_ATTR_RO(dma_task_num); + +static struct attribute *mdw_task_attrs[] = { + &dev_attr_dsp_task_num.attr, + &dev_attr_dla_task_num.attr, + &dev_attr_dma_task_num.attr, + NULL, +}; + +static struct attribute_group mdw_devinfo_attr_group = { + .name = "queue", + .attrs = mdw_task_attrs, +}; + +//------------------------------ +static ssize_t policy_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return -EINVAL; +} + +static ssize_t policy_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + return -EINVAL; +} +static DEVICE_ATTR_RW(policy); + +static struct attribute *mdw_sched_attrs[] = { + &dev_attr_policy.attr, + &dev_attr_reserv_time_remain.attr, + NULL, +}; + +static struct attribute_group mdw_sched_attr_group = { + .name = "sched", + .attrs = mdw_sched_attrs, +}; + +//------------------------------ +static ssize_t mem_statistics_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int n = 0; + + //ToDo + //mdw_usr_sys_aee_mem(buf, &n); + + return n; +} +static DEVICE_ATTR_RO(mem_statistics); + +static struct attribute *mdw_mem_attrs[] = { + &dev_attr_mem_statistics.attr, + NULL, +}; + +static struct attribute_group mdw_mem_attr_group = { + .name = "memory", + .attrs = mdw_mem_attrs, +}; + +//------------------------------ +static ssize_t ulog_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t log_lv = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + log_lv = mdev->plat_funcs->get_info(mdev, MDW_INFO_ULOG); + ret = sprintf(buf, "%u\n", log_lv); + if (ret < 0) + mdw_drv_warn("show ulog fail(%d)\n", log_lv); + +out: + return ret; +} + +static ssize_t ulog_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct mdw_device *mdev = mdw_dev; + uint32_t val = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + return -ENODEV; + } + + if (!kstrtouint(buf, 0, &val)) { + mdw_drv_info("set ulog(%u)\n", val); + mdev->plat_funcs->set_param(mdev, MDW_INFO_ULOG, val); + } + + return count; +} +static DEVICE_ATTR_RW(ulog); + +static ssize_t klog_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mdw_device *mdev = mdw_dev; + int ret = 0; + uint32_t log_lv = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + ret = -ENODEV; + goto out; + } + + log_lv = mdev->plat_funcs->get_info(mdev, MDW_INFO_KLOG); + ret = sprintf(buf, "%u\n", log_lv); + if (ret < 0) + mdw_drv_warn("show klog fail(%d)\n", log_lv); + +out: + return ret; +} + +static ssize_t klog_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct mdw_device *mdev = mdw_dev; + uint32_t val = 0; + + if (!mdev) { + mdw_drv_err("no mdw device\n"); + return -ENODEV; + } + + if (!kstrtouint(buf, 0, &val)) { + mdw_drv_info("set klog(%u)\n", val); + mdev->plat_funcs->set_param(mdev, MDW_INFO_KLOG, val); + } + + return count; +} +static DEVICE_ATTR_RW(klog); + +static ssize_t tlog_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + uint32_t log_lv = 0; + + log_lv = cfg_apusys_trace; + ret = sprintf(buf, "%u\n", log_lv); + if (ret < 0) + mdw_drv_warn("show tlog fail(%d)\n", log_lv); + + return ret; +} + +static ssize_t tlog_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + uint32_t val = 0; + + if (!kstrtouint(buf, 0, &val)) { + mdw_drv_info("set tlog(%u)\n", val); + cfg_apusys_trace = val; + } + + return count; +} +static DEVICE_ATTR_RW(tlog); + +static struct attribute *mdw_log_attrs[] = { + &dev_attr_ulog.attr, + &dev_attr_klog.attr, + &dev_attr_tlog.attr, + NULL, +}; + +static struct attribute_group mdw_log_attr_group = { + .name = "log", + .attrs = mdw_log_attrs, +}; + +//------------------------------ +int mdw_sysfs_init(struct mdw_device *mdev) +{ + int ret = 0; + + g_sched_plcy_show = 0; + + /* create /sys/class/misc/apusys/xxx */ + ret = sysfs_create_group(&mdev->misc_dev->this_device->kobj, + &mdw_devinfo_attr_group); + if (ret) + mdw_drv_err("create mdw devinfo attr fail, ret %d\n", ret); + + ret = sysfs_create_group(&mdev->misc_dev->this_device->kobj, + &mdw_sched_attr_group); + if (ret) + mdw_drv_err("create mdw sched attr fail, ret %d\n", ret); + + ret = sysfs_create_group(&mdev->misc_dev->this_device->kobj, + &mdw_log_attr_group); + if (ret) + mdw_drv_err("create mdw log attr fail, ret %d\n", ret); + + ret = sysfs_create_group(&mdev->misc_dev->this_device->kobj, + &mdw_mem_attr_group); + if (ret) + mdw_drv_err("create mdw mem attr fail, ret %d\n", ret); + + return ret; +} + +void mdw_sysfs_deinit(struct mdw_device *mdev) +{ + struct device *dev = mdev->misc_dev->this_device; + + sysfs_remove_group(&dev->kobj, &mdw_mem_attr_group); + sysfs_remove_group(&dev->kobj, &mdw_log_attr_group); + sysfs_remove_group(&dev->kobj, &mdw_sched_attr_group); + sysfs_remove_group(&dev->kobj, &mdw_devinfo_attr_group); +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.h new file mode 100644 index 0000000000000..098f0ce3f4c5b --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_sysfs.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_SYSFS_H__ +#define __MTK_APU_MDW_SYSFS_H__ + +int mdw_sysfs_init(struct device *kdev); +void mdw_sysfs_exit(void); + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_trace.h b/drivers/soc/mediatek/apusys/midware/2.0/mdw_trace.h new file mode 100644 index 0000000000000..d9c01ded38bbd --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_trace.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include "mdw_cmn.h" + +#define mdw_trace_begin(...) +#define mdw_trace_end(...) diff --git a/drivers/soc/mediatek/apusys/midware/2.0/mdw_util.c b/drivers/soc/mediatek/apusys/midware/2.0/mdw_util.c new file mode 100644 index 0000000000000..a4eca23cc22d2 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/mdw_util.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_ioctl.h" +#include "mdw_cmn.h" + +static int mdw_util_info(struct mdw_fpriv *mpriv, uint32_t type, uint64_t val) +{ + int ret = 0; + + return ret; +} + +int mdw_util_ioctl(struct mdw_fpriv *mpriv, void *data) +{ + union mdw_util_args *args = (union mdw_util_args *)data; + struct mdw_util_in *in = (struct mdw_util_in *)args; + struct mdw_device *mdev = mpriv->mdev; + void *mem_ucmd = NULL; + int ret = 0; + + mdw_flw_debug("s(0x%llx) op::%d\n", (uint64_t)mpriv, args->in.op); + + switch (args->in.op) { + case MDW_UTIL_IOCTL_INFO: + ret = mdw_util_info(mpriv, in->info.type, in->info.value); + if (ret) { + mdw_drv_err("setup info(%u/0x%llx) fail(%d)\n", + in->info.type, in->info.value, ret); + } + break; + + case MDW_UTIL_IOCTL_SETPOWER: + ret = mdev->plat_funcs->set_power(mdev, in->power.dev_type, + in->power.core_idx, in->power.boost); + break; + + case MDW_UTIL_IOCTL_UCMD: + if (!in->ucmd.size || !in->ucmd.handle) { + mdw_drv_err("invalid ucmd(%u/0x%llx) param\n", + in->ucmd.size, in->ucmd.handle); + ret = -EINVAL; + break; + } + + if (args->in.ucmd.size > MDW_UTIL_CMD_MAX_SIZE) { + mdw_drv_err("util cmd over size(%u/%u)\n", + args->in.ucmd.size, MDW_UTIL_CMD_MAX_SIZE); + ret = -EINVAL; + break; + } + + mem_ucmd = vzalloc(args->in.ucmd.size); + if (!mem_ucmd) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(mem_ucmd, + (void __user *)in->ucmd.handle, + in->ucmd.size)) { + ret = -EFAULT; + goto free_ucmd; + } + ret = mdev->plat_funcs->ucmd(mdev, in->ucmd.dev_type, + mem_ucmd, in->ucmd.size); + if (ret) { + mdw_drv_err("dev(%d) ucmd fail\n", in->ucmd.dev_type); + goto free_ucmd; + } + + if (copy_to_user((void __user *)in->ucmd.handle, + mem_ucmd, in->ucmd.size)) + ret = -EFAULT; + +free_ucmd: + vfree(mem_ucmd); + break; + + default: + mdw_drv_err("invalid util op code(%d)\n", args->in.op); + ret = -EINVAL; + break; + } + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.c new file mode 100644 index 0000000000000..a339eed3c2a75 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_cmd.h" +#include "mdw_cmn.h" +#include "mdw_rv.h" +#include "mdw_rv_tag.h" + +static int mdw_rv_sw_init(struct mdw_device *mdev) +{ + int ret = 0, i = 0; + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + struct mdw_dinfo *d = NULL; + + /* update device infos */ + for (i = 0; i < MDW_DEV_MAX; i++) { + if (!test_bit(i, mrdev->dev_mask) || mdev->dinfos[i]) + continue; + + /* setup mdev's info */ + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (!d) + goto free_dinfo; + + d->num = mrdev->dev_num[i]; + d->type = i; + + /* meta data */ + memcpy(d->meta, &mrdev->meta_data[i][0], sizeof(d->meta)); + mdw_drv_debug("dev(%u) support (%u)core\n", d->type, d->num); + + mdev->dinfos[i] = d; + bitmap_set(mdev->dev_mask, i, 1); + } + + /* update mem infos */ + mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + memcpy(mdev->mem_mask, mrdev->mem_mask, sizeof(mdev->mem_mask)); + memcpy(mdev->minfos, mrdev->minfos, sizeof(mdev->minfos)); + + goto out; + +free_dinfo: + for (i = 0; i < MDW_DEV_MAX; i++) { + if (mdev->dinfos[i] != NULL) { + kfree(mdev->dinfos[i]); + mdev->dinfos[i] = NULL; + } + } + ret = -ENOMEM; +out: + return ret; +} + +static void mdw_rv_sw_deinit(struct mdw_device *mdev) +{ + unsigned int i = 0; + + for (i = 0; i < MDW_DEV_MAX; i++) { + if (mdev->dinfos[i] != NULL) { + kfree(mdev->dinfos[i]); + mdev->dinfos[i] = NULL; + } + } +} + +static int mdw_rv_late_init(struct mdw_device *mdev) +{ + int ret = 0; + + mdw_rv_tag_init(); + + /* init rv device */ + ret = mdw_rv_dev_init(mdev); + if (ret || !mdev->dev_specific) { + mdw_drv_err("init mdw rvdev fail(%d)\n", ret); + goto dev_deinit; + } + + goto out; + +dev_deinit: + mdw_rv_dev_deinit(mdev); +out: + return ret; +} + +static int mdw_rv_late_init_v4(struct mdw_device *mdev) +{ + int ret = 0; + + mdw_rv_tag_init(); + + /* init rv device */ + ret = mdw_rv_dev_init(mdev); + if (ret || !mdev->dev_specific) { + mdw_drv_err("init mdw rvdev fail(%d)\n", ret); + goto dev_deinit; + } + + goto out; + +dev_deinit: + mdw_rv_dev_deinit(mdev); +out: + return ret; +} + +static void mdw_rv_late_deinit(struct mdw_device *mdev) +{ + mdw_rv_dev_deinit(mdev); + mdw_rv_tag_deinit(); +} + +static int mdw_rv_run_cmd(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + return mdw_rv_dev_run_cmd(mpriv, c); +} + +static int mdw_rv_set_power(struct mdw_device *mdev, + uint32_t type, uint32_t idx, uint32_t boost) +{ + return -EINVAL; +} + +static int mdw_rv_ucmd(struct mdw_device *mdev, + uint32_t type, void *vaddr, uint32_t size) +{ + return -EINVAL; +} + +static int mdw_rv_set_param(struct mdw_device *mdev, + enum mdw_info_type type, uint32_t val) +{ + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + + return mdw_rv_dev_set_param(mrdev, type, val); +} + +static uint32_t mdw_rv_get_info(struct mdw_device *mdev, + enum mdw_info_type type) +{ + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + int val = 0; + + mdw_rv_dev_get_param(mrdev, type, &val); + return val; +} + +static int mdw_rv_register_device(struct apusys_device *adev) +{ + return 0; +} + +static int mdw_rv_unregister_device(struct apusys_device *adev) +{ + return 0; +} + +static bool mdw_rv_poll_cmd(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + + return mdw_rv_dev_poll_cmd(mrdev, c); +} + +static void mdw_rv_cp_execinfo(struct mdw_cmd *c) +{ + struct mdw_device *mdev = c->mpriv->mdev; + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + + mdw_rv_dev_cp_execinfo(mrdev, c); +} + +const struct mdw_plat_func rv_plat_drv_v2 = { + .sw_init = mdw_rv_sw_init, + .sw_deinit = mdw_rv_sw_deinit, + .late_init = mdw_rv_late_init, + .late_deinit = mdw_rv_late_deinit, + .prepare_cmd = mdw_cmd_ioctl_v2, + .get_cmdbuf = mdw_cmd_get_cmdbufs, + .run_cmd = mdw_rv_run_cmd, + .release_cmd = mdw_cmd_mpriv_release_without_stale, + .set_power = mdw_rv_set_power, + .ucmd = mdw_rv_ucmd, + .set_param = mdw_rv_set_param, + .get_info = mdw_rv_get_info, + .register_device = mdw_rv_register_device, + .unregister_device = mdw_rv_unregister_device, +}; + +const struct mdw_plat_func rv_plat_drv_v3 = { + .sw_init = mdw_rv_sw_init, + .sw_deinit = mdw_rv_sw_deinit, + .late_init = mdw_rv_late_init, + .late_deinit = mdw_rv_late_deinit, + .prepare_cmd = mdw_cmd_ioctl_v3, + .get_cmdbuf = mdw_cmd_get_cmdbufs, + .run_cmd = mdw_rv_run_cmd, + .release_cmd = mdw_cmd_mpriv_release, + .set_power = mdw_rv_set_power, + .ucmd = mdw_rv_ucmd, + .set_param = mdw_rv_set_param, + .get_info = mdw_rv_get_info, + .register_device = mdw_rv_register_device, + .unregister_device = mdw_rv_unregister_device, +}; + +const struct mdw_plat_func rv_plat_drv_v4 = { + .sw_init = mdw_rv_sw_init, + .sw_deinit = mdw_rv_sw_deinit, + .late_init = mdw_rv_late_init_v4, + .late_deinit = mdw_rv_late_deinit, + .prepare_cmd = mdw_cmd_ioctl_v4, + .get_cmdbuf = mdw_cmd_get_cmdbufs_with_apummu, + .run_cmd = mdw_rv_run_cmd, + .release_cmd = mdw_cmd_mpriv_release, + .set_power = mdw_rv_set_power, + .ucmd = mdw_rv_ucmd, + .set_param = mdw_rv_set_param, + .get_info = mdw_rv_get_info, + .register_device = mdw_rv_register_device, + .unregister_device = mdw_rv_unregister_device, + .poll_cmd = mdw_rv_poll_cmd, + .cp_execinfo = mdw_rv_cp_execinfo, +}; diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.h b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.h new file mode 100644 index 0000000000000..7ed1e1cfc0d7c --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_RV_H__ +#define __MTK_APU_MDW_RV_H__ + +#include "mdw.h" +#include "mdw_rv_msg.h" + +struct mdw_rv_dev; + +struct mdw_rv_cmd { + struct mdw_cmd *c; + struct mdw_mem *cb; + struct list_head u_item; // to usr list + struct mdw_ipi_msg_sync s_msg; // for ipi + uint64_t start_ts_ns; // create time at ap +}; + +struct mdw_rv_cmd_func { + struct mdw_rv_cmd *(*create)(struct mdw_fpriv *mpriv, + struct mdw_cmd *c); + int (*delete)(struct mdw_cmd *c); + void (*done)(struct mdw_rv_cmd *rc, int ret); + bool (*poll)(struct mdw_rv_cmd *rc); + void (*cp_execinfo)(struct mdw_rv_cmd *rc); +}; + +struct mdw_rv_dev { + struct rpmsg_device *rpdev; + struct rpmsg_endpoint *ept; + struct mdw_device *mdev; + + struct mdw_ipi_param param; + + struct list_head s_list; // for sync msg + struct mutex msg_mtx; + struct mutex mtx; + + struct work_struct init_wk; // init wq to avoid ipi conflict + + const struct mdw_rv_cmd_func *cmd_funcs; + + /* rv information */ + uint32_t rv_version; + unsigned long dev_mask[BITS_TO_LONGS(MDW_DEV_MAX)]; + uint8_t dev_num[MDW_DEV_MAX]; + unsigned long mem_mask[BITS_TO_LONGS(MDW_MEM_TYPE_MAX)]; + struct mdw_mem minfos[MDW_MEM_TYPE_MAX]; + uint8_t meta_data[MDW_DEV_MAX][MDW_DEV_META_SIZE]; + struct mdw_stat *stat; + uint64_t stat_iova; + + /* dtime handle */ + struct work_struct power_off_wk; + struct timer_list power_off_timer; + + uint64_t enter_rv_cb_time; + uint64_t rv_cb_time; +}; + +int mdw_rv_dev_init(struct mdw_device *mdev); +void mdw_rv_dev_deinit(struct mdw_device *mdev); +int mdw_rv_dev_run_cmd(struct mdw_fpriv *mpriv, struct mdw_cmd *c); +int mdw_rv_dev_set_param(struct mdw_rv_dev *mrdev, uint32_t idx, uint32_t val); +int mdw_rv_dev_get_param(struct mdw_rv_dev *mrdev, uint32_t idx, uint32_t *val); +bool mdw_rv_dev_poll_cmd(struct mdw_rv_dev *mrdev, struct mdw_cmd *c); +void mdw_rv_dev_cp_execinfo(struct mdw_rv_dev *mrdev, struct mdw_cmd *c); + +/* power budget functions */ +int mdw_rv_pb_get(enum mdw_pwrplcy_type type, uint32_t debounce_ms); +int mdw_rv_pb_put(enum mdw_pwrplcy_type type); +void mdw_rv_pb_init(struct mdw_device *mdev); + +/* rv cmd functions */ +extern const struct mdw_rv_cmd_func mdw_rv_cmd_func_v2; +extern const struct mdw_rv_cmd_func mdw_rv_cmd_func_v3; +extern const struct mdw_rv_cmd_func mdw_rv_cmd_func_v4; + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v2.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v2.c new file mode 100644 index 0000000000000..9067c93e256a3 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v2.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_rv.h" +#include "mdw_cmn.h" +#include "mdw_mem_pool.h" +#include "mdw_trace.h" + +#include "linux/remoteproc/mtk_apu_ipi.h" + +#define MDW_IS_HIGHADDR(addr) ((addr & 0xffffffff00000000) ? true : false) + +struct mdw_rv_msg_cmd { + /* ids */ + uint64_t session_id; + uint64_t cmd_id; + uint32_t pid; + uint32_t tgid; + /* params */ + uint32_t priority; + uint32_t hardlimit; + uint32_t softlimit; + uint32_t power_save; + uint32_t power_plcy; + uint32_t power_dtime; + uint32_t app_type; + uint32_t num_subcmds; + uint32_t subcmds_offset; + uint32_t num_cmdbufs; + uint32_t cmdbuf_infos_offset; + uint32_t adj_matrix_offset; + uint32_t exec_infos_offset; + uint32_t num_links; + uint32_t link_offset; +} __packed; + +struct mdw_rv_msg_sc { + /* params */ + uint32_t type; + uint32_t suggest_time; + uint32_t vlm_usage; + uint32_t vlm_ctx_id; + uint32_t vlm_force; + uint32_t boost; + uint32_t turbo_boost; + uint32_t min_boost; + uint32_t max_boost; + uint32_t hse_en; + uint32_t driver_time; + uint32_t ip_time; + uint32_t bw; + uint32_t pack_id; + uint32_t affinity; + /* cmdbufs info */ + uint32_t cmdbuf_start_idx; + uint32_t num_cmdbufs; +} __packed; + +struct mdw_rv_msg_cb { + uint64_t device_va; + uint32_t size; +} __packed; + + +static void mdw_rv_cmd_print(struct mdw_rv_msg_cmd *rc) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rc kid(0x%llx)\n", rc->cmd_id); + mdw_cmd_debug(" sesion = 0x%llx\n", rc->session_id); + mdw_cmd_debug(" priority = %u\n", rc->priority); + mdw_cmd_debug(" hardlimit = %u\n", rc->hardlimit); + mdw_cmd_debug(" softlimit = %u\n", rc->softlimit); + mdw_cmd_debug(" power_save = %u\n", rc->power_save); + mdw_cmd_debug(" power_plcy = %u\n", rc->power_plcy); + mdw_cmd_debug(" power_dtime = %u\n", rc->power_dtime); + mdw_cmd_debug(" app_type = %u\n", rc->app_type); + mdw_cmd_debug(" num_subcmds = %u\n", rc->num_subcmds); + mdw_cmd_debug(" subcmds_offset = 0x%x\n", rc->subcmds_offset); + mdw_cmd_debug(" num_cmdbufs = %u\n", rc->num_cmdbufs); + mdw_cmd_debug(" cmdbuf_infos_offset = 0x%x\n", rc->cmdbuf_infos_offset); + mdw_cmd_debug(" adj_matrix_offset = 0x%x\n", rc->adj_matrix_offset); + mdw_cmd_debug(" exec_infos_offset = 0x%x\n", rc->exec_infos_offset); + mdw_cmd_debug("-------------------------\n"); +} + +static void mdw_rv_cmd_set_affinity(struct mdw_cmd *c, bool enable) +{ + if (c->power_plcy != MDW_POWERPOLICY_PERFORMANCE) + return; +} + +static void mdw_rv_sc_print(struct mdw_rv_msg_sc *rsc, + uint64_t cmd_id, uint32_t idx) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rv subcmd(0x%llx-#%u)\n", cmd_id, idx); + mdw_cmd_debug(" type = %u\n", rsc->type); + mdw_cmd_debug(" suggest_time = %u\n", rsc->suggest_time); + mdw_cmd_debug(" vlm_usage = %u\n", rsc->vlm_usage); + mdw_cmd_debug(" vlm_ctx_id = %u\n", rsc->vlm_ctx_id); + mdw_cmd_debug(" vlm_force = %u\n", rsc->vlm_force); + mdw_cmd_debug(" boost = %u\n", rsc->boost); + mdw_cmd_debug(" turbo_boost = %u\n", rsc->turbo_boost); + mdw_cmd_debug(" min_boost = %u\n", rsc->min_boost); + mdw_cmd_debug(" max_boost = %u\n", rsc->max_boost); + mdw_cmd_debug(" hse_en = %u\n", rsc->hse_en); + mdw_cmd_debug(" driver_time = %u\n", rsc->driver_time); + mdw_cmd_debug(" ip_time = %u\n", rsc->ip_time); + mdw_cmd_debug(" pack_id = %u\n", rsc->pack_id); + mdw_cmd_debug(" cmdbuf_start_idx = %u\n", rsc->cmdbuf_start_idx); + mdw_cmd_debug(" num_cmdbufs = %u\n", rsc->num_cmdbufs); + mdw_cmd_debug("-------------------------\n"); +} + +static int mdw_rv_cmd_delete(struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = (struct mdw_rv_cmd *)c->internal_cmd; + + if (!rc) + return -EINVAL; + + mdw_trace_begin("apumdw:rv_cmd_delete"); + mdw_rv_cmd_set_affinity(c, false); + mdw_mem_pool_free(rc->cb); + kfree(rc); + c->internal_cmd = NULL; + c->del_internal = NULL; + mdw_trace_end(); + + return 0; +} + +static struct mdw_rv_cmd *mdw_rv_cmd_create(struct mdw_fpriv *mpriv, + struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = NULL; + uint64_t cb_size = 0; + uint32_t acc_cb = 0, i = 0, j = 0; + uint32_t subcmds_ofs = 0, cmdbuf_infos_ofs = 0, adj_matrix_ofs = 0; + uint32_t exec_infos_ofs = 0; + struct mdw_rv_msg_cmd *rmc = NULL; + struct mdw_rv_msg_sc *rmsc = NULL; + struct mdw_rv_msg_cb *rmcb = NULL; + + mdw_trace_begin("apumdw:rv_cmd_create"); + + /* reuse internal cmd if exist */ + if (c->internal_cmd) { + mdw_cmd_debug("reuse internal cmd\n"); + rc = (struct mdw_rv_cmd *)c->internal_cmd; + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + goto reuse; + } + + /* check mem address for rv */ + if (MDW_IS_HIGHADDR(c->exec_infos->device_va) || + MDW_IS_HIGHADDR(c->cmdbufs->device_va)) { + mdw_drv_err("rv dva high addr(0x%llx/0x%llx)\n", + c->cmdbufs->device_va, c->exec_infos->device_va); + goto out; + } + + rc = kzalloc(sizeof(*rc), GFP_KERNEL); + if (!rc) + goto out; + + c->rvid = (uint64_t)&rc->s_msg; + init_completion(&rc->s_msg.cmplt); + + /* calc size and offset */ + rc->c = c; + cb_size += sizeof(struct mdw_rv_msg_cmd); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + adj_matrix_ofs = cb_size; + cb_size += (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + subcmds_ofs = cb_size; + cb_size += (c->num_subcmds * sizeof(struct mdw_rv_msg_sc)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + cmdbuf_infos_ofs = cb_size; + cb_size += (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb)); + if (cb_size < (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb))) { + mdw_drv_err("cb_size overflow(%llu) cmdbufs(%u*%zu)\n", + cb_size, c->num_cmdbufs, sizeof(struct mdw_rv_msg_cb)); + goto free_rc; + } + exec_infos_ofs = cb_size; + cb_size += c->exec_infos->size; + if (cb_size < c->exec_infos->size) { + mdw_drv_err("cb_size overflow(%llu) exec_infos size(%llu)\n", + cb_size, c->exec_infos->size); + goto free_rc; + } + + /* allocate communicate buffer */ + rc->cb = mdw_mem_pool_alloc(&mpriv->cmd_buf_pool, cb_size, + MDW_DEFAULT_ALIGN); + if (!rc->cb) { + mdw_drv_err("c(0x%llx) alloc cb size(%llu) fail\n", + c->kid, cb_size); + goto free_rc; + } + + /* assign cmd info */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + rmc->session_id = (uint64_t)c->mpriv; + rmc->cmd_id = c->kid; + rmc->pid = (uint32_t)c->pid; + rmc->tgid = (uint32_t)c->tgid; + rmc->priority = c->priority; + rmc->hardlimit = c->hardlimit; + rmc->softlimit = c->softlimit; + rmc->power_save = c->power_save; + rmc->power_plcy = c->power_plcy; + rmc->power_dtime = c->power_dtime; + rmc->app_type = c->app_type; + rmc->num_subcmds = c->num_subcmds; + rmc->num_cmdbufs = c->num_cmdbufs; + rmc->subcmds_offset = subcmds_ofs; + rmc->cmdbuf_infos_offset = cmdbuf_infos_ofs; + rmc->adj_matrix_offset = adj_matrix_ofs; + rmc->exec_infos_offset = exec_infos_ofs; + mdw_rv_cmd_print(rmc); + + /* assign subcmds info */ + rmsc = (void *)rmc + rmc->subcmds_offset; + rmcb = (void *)rmc + rmc->cmdbuf_infos_offset; + for (i = 0; i < c->num_subcmds; i++) { + rmsc[i].type = c->subcmds[i].type; + rmsc[i].suggest_time = c->subcmds[i].suggest_time; + rmsc[i].vlm_usage = c->subcmds[i].vlm_usage; + rmsc[i].vlm_ctx_id = c->subcmds[i].vlm_ctx_id; + rmsc[i].vlm_force = c->subcmds[i].vlm_force; + rmsc[i].boost = c->subcmds[i].boost; + rmsc[i].ip_time = c->subcmds[i].ip_time; + rmsc[i].driver_time = c->subcmds[i].driver_time; + rmsc[i].bw = c->subcmds[i].bw; + rmsc[i].turbo_boost = c->subcmds[i].turbo_boost; + rmsc[i].min_boost = c->subcmds[i].min_boost; + rmsc[i].max_boost = c->subcmds[i].max_boost; + rmsc[i].hse_en = c->subcmds[i].hse_en; + rmsc[i].pack_id = c->subcmds[i].pack_id; + rmsc[i].num_cmdbufs = c->subcmds[i].num_cmdbufs; + rmsc[i].cmdbuf_start_idx = acc_cb; + mdw_rv_sc_print(&rmsc[i], rmc->cmd_id, i); + + for (j = 0; j < rmsc[i].num_cmdbufs; j++) { + rmcb[acc_cb + j].size = + c->ksubcmds[i].cmdbufs[j].size; + rmcb[acc_cb + j].device_va = + c->ksubcmds[i].daddrs[j]; + mdw_cmd_debug("sc(%u) #%u-cmdbufs 0x%llx/%u\n", + i, j, + rmcb[acc_cb + j].device_va, + rmcb[acc_cb + j].size); + } + acc_cb += c->subcmds[i].num_cmdbufs; + } + + /* setup internal cmd */ + c->del_internal = mdw_rv_cmd_delete; + c->internal_cmd = rc; + +reuse: + /* set start timestamp */ + rc->start_ts_ns = c->start_ts; + + /* copy adj matrix */ + memcpy((void *)rmc + rmc->adj_matrix_offset, c->adj_matrix, + c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + + /* clear exec ret */ + c->einfos->c.ret = 0; + c->einfos->c.sc_rets = 0; + + if (mdw_mem_flush(mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx) flush rv cbs(%llu) fail\n", + (uint64_t)c->mpriv, c->kid, c->rvid, rc->cb->size); + + mdw_rv_cmd_set_affinity(c, true); + + goto out; + +free_rc: + kfree(rc); + rc = NULL; +out: + mdw_trace_end(); + return rc; +} + +static void mdw_rv_cmd_done(struct mdw_rv_cmd *rc, int ret) +{ + struct mdw_cmd *c = rc->c; + struct mdw_rv_msg_cmd *rmc = NULL; + + /* invalidate */ + if (mdw_mem_invalidate(c->mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx/0x%llx) invalidate rcbs(%llu) fail\n", + (uint64_t)c->mpriv, c->uid, c->kid, + c->rvid, rc->cb->size); + + /* copy exec infos */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + if (rmc->exec_infos_offset + c->exec_infos->size != rc->cb->size) { + mdw_drv_warn("c(0x%llx/0x%llx/0x%llx) execinfos size(%llu/%llu) not matched\n", + c->uid, c->kid, c->rvid, + rmc->exec_infos_offset + c->exec_infos->size, + rc->cb->size); + } else { + memcpy(c->exec_infos->vaddr, + rc->cb->vaddr + rmc->exec_infos_offset, + c->exec_infos->size); + } + + /* complete cmd */ + c->complete(c, ret); +} + +/* kernel-tinysys version <= v2 */ +const struct mdw_rv_cmd_func mdw_rv_cmd_func_v2 = { + .create = mdw_rv_cmd_create, + .delete = mdw_rv_cmd_delete, + .done = mdw_rv_cmd_done, +}; diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v3.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v3.c new file mode 100644 index 0000000000000..db05f85c5d7e1 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v3.c @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_rv.h" +#include "mdw_cmn.h" +#include "mdw_mem_pool.h" +#include "mdw_trace.h" + +#include "linux/remoteproc/mtk_apu_ipi.h" + +#define MDW_IS_HIGHADDR(addr) ((addr & 0xffffffff00000000) ? true : false) + +struct mdw_rv_msg_cmd { + /* ids */ + uint64_t session_id; + uint64_t cmd_id; + uint32_t pid; + uint32_t tgid; + /* params */ + uint32_t priority; + uint32_t hardlimit; + uint32_t softlimit; + uint32_t fastmem_ms; + uint32_t power_plcy; + uint32_t power_dtime; + uint32_t app_type; + uint32_t num_subcmds; + uint32_t subcmds_offset; + uint32_t num_cmdbufs; + uint32_t cmdbuf_infos_offset; + uint32_t adj_matrix_offset; + uint32_t exec_infos_offset; + uint32_t num_links; + uint32_t link_offset; +} __packed; + +struct mdw_rv_msg_sc { + /* params */ + uint32_t type; + uint32_t suggest_time; + uint32_t vlm_usage; + uint32_t vlm_ctx_id; + uint32_t vlm_force; + uint32_t boost; + uint32_t turbo_boost; + uint32_t min_boost; + uint32_t max_boost; + uint32_t hse_en; + uint32_t driver_time; + uint32_t ip_time; + uint32_t bw; + uint32_t pack_id; + uint32_t affinity; + /* cmdbufs info */ + uint32_t cmdbuf_start_idx; + uint32_t num_cmdbufs; +} __packed; + +struct mdw_rv_msg_cb { + uint64_t device_va; + uint32_t size; +} __packed; + +struct mdw_rv_sc_link { + uint32_t producer_idx; + uint32_t consumer_idx; + uint32_t vid; + uint64_t va; + uint64_t x; + uint64_t y; +} __packed; + +static void mdw_rv_cmd_print(struct mdw_rv_msg_cmd *rc) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rc kid(0x%llx)\n", rc->cmd_id); + mdw_cmd_debug(" session = 0x%llx\n", rc->session_id); + mdw_cmd_debug(" priority = %u\n", rc->priority); + mdw_cmd_debug(" hardlimit = %u\n", rc->hardlimit); + mdw_cmd_debug(" softlimit = %u\n", rc->softlimit); + mdw_cmd_debug(" fastmem_ms = %u\n", rc->fastmem_ms); + mdw_cmd_debug(" power_plcy = %u\n", rc->power_plcy); + mdw_cmd_debug(" power_dtime = %u\n", rc->power_dtime); + mdw_cmd_debug(" app_type = %u\n", rc->app_type); + mdw_cmd_debug(" num_subcmds = %u\n", rc->num_subcmds); + mdw_cmd_debug(" subcmds_offset = 0x%x\n", rc->subcmds_offset); + mdw_cmd_debug(" num_cmdbufs = %u\n", rc->num_cmdbufs); + mdw_cmd_debug(" cmdbuf_infos_offset = 0x%x\n", rc->cmdbuf_infos_offset); + mdw_cmd_debug(" adj_matrix_offset = 0x%x\n", rc->adj_matrix_offset); + mdw_cmd_debug(" exec_infos_offset = 0x%x\n", rc->exec_infos_offset); + mdw_cmd_debug(" num_links = %u\n", rc->num_links); + mdw_cmd_debug(" link_offset = 0x%x\n", rc->link_offset); + mdw_cmd_debug("-------------------------\n"); +} + +static void mdw_rv_cmd_set_affinity(struct mdw_cmd *c, bool enable) +{ + if (c->power_plcy != MDW_POWERPOLICY_PERFORMANCE) + return; +} + +static void mdw_rv_sc_print(struct mdw_rv_msg_sc *rsc, + uint64_t cmd_id, uint32_t idx) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rv subcmd(0x%llx-#%u)\n", cmd_id, idx); + mdw_cmd_debug(" type = %u\n", rsc->type); + mdw_cmd_debug(" suggest_time = %u\n", rsc->suggest_time); + mdw_cmd_debug(" vlm_usage = %u\n", rsc->vlm_usage); + mdw_cmd_debug(" vlm_ctx_id = %u\n", rsc->vlm_ctx_id); + mdw_cmd_debug(" vlm_force = %u\n", rsc->vlm_force); + mdw_cmd_debug(" boost = %u\n", rsc->boost); + mdw_cmd_debug(" turbo_boost = %u\n", rsc->turbo_boost); + mdw_cmd_debug(" min_boost = %u\n", rsc->min_boost); + mdw_cmd_debug(" max_boost = %u\n", rsc->max_boost); + mdw_cmd_debug(" hse_en = %u\n", rsc->hse_en); + mdw_cmd_debug(" driver_time = %u\n", rsc->driver_time); + mdw_cmd_debug(" ip_time = %u\n", rsc->ip_time); + mdw_cmd_debug(" pack_id = %u\n", rsc->pack_id); + mdw_cmd_debug(" affinity = 0x%x\n", rsc->affinity); + mdw_cmd_debug(" cmdbuf_start_idx = %u\n", rsc->cmdbuf_start_idx); + mdw_cmd_debug(" num_cmdbufs = %u\n", rsc->num_cmdbufs); + mdw_cmd_debug("-------------------------\n"); +} + +static int mdw_rv_cmd_delete(struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = (struct mdw_rv_cmd *)c->internal_cmd; + + if (!rc) + return -EINVAL; + + mdw_trace_begin("apumdw:rv_cmd_delete"); + mdw_rv_cmd_set_affinity(c, false); + mdw_mem_pool_free(rc->cb); + kfree(rc); + c->internal_cmd = NULL; + c->del_internal = NULL; + mdw_trace_end(); + + return 0; +} + +static struct mdw_rv_cmd *mdw_rv_cmd_create(struct mdw_fpriv *mpriv, + struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = NULL; + uint64_t cb_size = 0; + uint32_t acc_cb = 0, i = 0, j = 0; + uint32_t subcmds_ofs = 0, cmdbuf_infos_ofs = 0, adj_matrix_ofs = 0; + uint32_t exec_infos_ofs = 0, link_ofs = 0; + struct mdw_rv_msg_cmd *rmc = NULL; + struct mdw_rv_msg_sc *rmsc = NULL; + struct mdw_rv_msg_cb *rmcb = NULL; + struct mdw_rv_sc_link *rl = NULL; + + mdw_trace_begin("apumdw:rv_cmd_create"); + + /* reuse internal cmd if exist */ + if (c->internal_cmd) { + mdw_cmd_debug("reuse internal cmd\n"); + rc = (struct mdw_rv_cmd *)c->internal_cmd; + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + goto reuse; + } + + /* check mem address for rv */ + if (MDW_IS_HIGHADDR(c->exec_infos->device_va) || + MDW_IS_HIGHADDR(c->cmdbufs->device_va)) { + mdw_drv_err("rv dva high addr(0x%llx/0x%llx)\n", + c->cmdbufs->device_va, c->exec_infos->device_va); + goto out; + } + + rc = kzalloc(sizeof(*rc), GFP_KERNEL); + if (!rc) + goto out; + + c->rvid = (uint64_t)&rc->s_msg; + init_completion(&rc->s_msg.cmplt); + + /* calc size and offset */ + rc->c = c; + cb_size += sizeof(struct mdw_rv_msg_cmd); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + adj_matrix_ofs = cb_size; + cb_size += (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + subcmds_ofs = cb_size; + cb_size += (c->num_subcmds * sizeof(struct mdw_rv_msg_sc)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + cmdbuf_infos_ofs = cb_size; + cb_size += (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb)); + if (cb_size < (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb))) { + mdw_drv_err("cb_size overflow(%llu) cmdbufs(%u*%zu)\n", + cb_size, c->num_cmdbufs, sizeof(struct mdw_rv_msg_cb)); + goto free_rc; + } + if (cb_size < c->exec_infos->size) { + mdw_drv_err("cb_size overflow(%llu) exec_infos size(%llu)\n", + cb_size, c->exec_infos->size); + goto free_rc; + } + if (c->num_links) { + link_ofs = cb_size; + cb_size += (c->num_links * sizeof(struct mdw_rv_sc_link)); + if (cb_size < (c->num_links * sizeof(struct mdw_rv_sc_link))) { + mdw_drv_err("cb_size overflow(%llu) links(%u*%zu)\n", + cb_size, c->num_links, sizeof(struct mdw_rv_sc_link)); + goto free_rc; + } + } + + /* allocate communicate buffer */ + rc->cb = mdw_mem_pool_alloc(&mpriv->cmd_buf_pool, cb_size, + MDW_DEFAULT_ALIGN); + if (!rc->cb) { + mdw_drv_err("c(0x%llx) alloc cb size(%llu) fail\n", + c->kid, cb_size); + goto free_rc; + } + + /* assign cmd info */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + rmc->session_id = (uint64_t)c->mpriv; + rmc->cmd_id = c->kid; + rmc->pid = (uint32_t)c->pid; + rmc->tgid = (uint32_t)c->tgid; + rmc->priority = c->priority; + rmc->hardlimit = c->hardlimit; + rmc->softlimit = c->softlimit; + rmc->fastmem_ms = c->fastmem_ms; + rmc->power_plcy = c->power_plcy; + rmc->power_dtime = c->power_dtime; + rmc->app_type = c->app_type; + rmc->num_subcmds = c->num_subcmds; + rmc->num_cmdbufs = c->num_cmdbufs; + rmc->subcmds_offset = subcmds_ofs; + rmc->cmdbuf_infos_offset = cmdbuf_infos_ofs; + rmc->adj_matrix_offset = adj_matrix_ofs; + rmc->exec_infos_offset = exec_infos_ofs; + rmc->num_links = c->num_links; + rmc->link_offset = link_ofs; + mdw_rv_cmd_print(rmc); + + /* copy links */ + rl = (void *)rmc + rmc->link_offset; + for (i = 0; i < c->num_links; i++) { + rl[i].producer_idx = c->links[i].producer_idx; + rl[i].consumer_idx = c->links[i].consumer_idx; + rl[i].vid = c->links[i].vid; + rl[i].va = c->links[i].va; + rl[i].x = c->links[i].x; + rl[i].y = c->links[i].y; + } + + /* assign subcmds info */ + rmsc = (void *)rmc + rmc->subcmds_offset; + rmcb = (void *)rmc + rmc->cmdbuf_infos_offset; + for (i = 0; i < c->num_subcmds; i++) { + rmsc[i].type = c->subcmds[i].type; + rmsc[i].suggest_time = c->subcmds[i].suggest_time; + rmsc[i].vlm_usage = c->subcmds[i].vlm_usage; + rmsc[i].vlm_ctx_id = c->subcmds[i].vlm_ctx_id; + rmsc[i].vlm_force = c->subcmds[i].vlm_force; + rmsc[i].boost = c->subcmds[i].boost; + rmsc[i].ip_time = c->subcmds[i].ip_time; + rmsc[i].driver_time = c->subcmds[i].driver_time; + rmsc[i].bw = c->subcmds[i].bw; + rmsc[i].turbo_boost = c->subcmds[i].turbo_boost; + rmsc[i].min_boost = c->subcmds[i].min_boost; + rmsc[i].max_boost = c->subcmds[i].max_boost; + rmsc[i].hse_en = c->subcmds[i].hse_en; + rmsc[i].pack_id = c->subcmds[i].pack_id; + rmsc[i].affinity = c->subcmds[i].affinity; + rmsc[i].num_cmdbufs = c->subcmds[i].num_cmdbufs; + rmsc[i].cmdbuf_start_idx = acc_cb; + mdw_rv_sc_print(&rmsc[i], rmc->cmd_id, i); + + for (j = 0; j < rmsc[i].num_cmdbufs; j++) { + rmcb[acc_cb + j].size = + c->ksubcmds[i].cmdbufs[j].size; + rmcb[acc_cb + j].device_va = + c->ksubcmds[i].daddrs[j]; + mdw_cmd_debug("sc(%u) #%u-cmdbufs 0x%llx/%u\n", + i, j, + rmcb[acc_cb + j].device_va, + rmcb[acc_cb + j].size); + } + acc_cb += c->subcmds[i].num_cmdbufs; + } + + /* setup internal cmd */ + c->del_internal = mdw_rv_cmd_delete; + c->internal_cmd = rc; + +reuse: + /* set start timestamp */ + rc->start_ts_ns = c->start_ts; + + /* copy adj matrix */ + memcpy((void *)rmc + rmc->adj_matrix_offset, c->adj_matrix, + c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + + /* clear exec ret */ + c->einfos->c.ret = 0; + c->einfos->c.sc_rets = 0; + + if (mdw_mem_flush(mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx) flush rv cbs(%llu) fail\n", + (uint64_t)c->mpriv, c->kid, c->rvid, rc->cb->size); + + mdw_rv_cmd_set_affinity(c, true); + + goto out; + +free_rc: + kfree(rc); + rc = NULL; +out: + mdw_trace_end(); + return rc; +} + +static void mdw_rv_cmd_done(struct mdw_rv_cmd *rc, int ret) +{ + struct mdw_cmd *c = rc->c; + struct mdw_rv_msg_cmd *rmc = NULL; + + /* invalidate */ + if (mdw_mem_invalidate(c->mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx/0x%llx) invalidate rcbs(%llu) fail\n", + (uint64_t)c->mpriv, c->uid, c->kid, + c->rvid, rc->cb->size); + + /* copy exec infos */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + if (rmc->exec_infos_offset + c->exec_infos->size == rc->cb->size || + rmc->link_offset + c->num_links * sizeof(struct mdw_rv_sc_link) + == rc->cb->size) { + memcpy(c->exec_infos->vaddr, + rc->cb->vaddr + rmc->exec_infos_offset, + c->exec_infos->size); + } else { + mdw_drv_warn("c(0x%llx/0x%llx/0x%llx) execinfos(%llu/%u) links(%u/%llu) not matched\n", + c->uid, c->kid, c->rvid, + rmc->exec_infos_offset + c->exec_infos->size, + rmc->link_offset, c->num_links, + rc->cb->size); + } + + /* complete cmd */ + c->complete(c, ret); +} + +/* kernel-tinysys version v3 */ +const struct mdw_rv_cmd_func mdw_rv_cmd_func_v3 = { + .create = mdw_rv_cmd_create, + .delete = mdw_rv_cmd_delete, + .done = mdw_rv_cmd_done, +}; diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v4.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v4.c new file mode 100644 index 0000000000000..2b9e82abbb311 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_cmd_v4.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include "mdw_rv.h" +#include "mdw_cmn.h" +#include "mdw_cmd.h" +#include "mdw_mem_pool.h" +#include "mdw_trace.h" + +#include "linux/remoteproc/mtk_apu_ipi.h" + +#define MDW_IS_HIGHADDR(addr) ((addr & 0xffffffff00000000) ? true : false) +#define MDW_POLL_TIME (1) //us + +struct mdw_rv_msg_cmd { + /* ids */ + uint64_t session_id; + uint64_t cmd_id; + uint64_t inference_id; + uint32_t pid; + uint32_t tgid; + /* params */ + uint32_t priority; + uint32_t hardlimit; + uint32_t softlimit; + uint32_t fastmem_ms; + uint32_t power_plcy; + uint32_t power_dtime; + uint32_t power_etime; + uint32_t app_type; + uint32_t num_subcmds; + uint32_t subcmds_offset; + uint32_t num_cmdbufs; + uint32_t cmdbuf_infos_offset; + uint32_t apummu_tbl_infos_offset; + uint32_t adj_matrix_offset; + uint32_t exec_infos_offset; + uint32_t num_links; + uint32_t link_offset; + /* history params */ + uint32_t inference_ms; + uint32_t tolerance_ms; + /* cmd done */ + uint32_t cmd_done; +} __packed; + +struct mdw_rv_msg_sc { + /* params */ + uint32_t type; + uint32_t suggest_time; + uint32_t vlm_usage; + uint32_t vlm_ctx_id; + uint32_t vlm_force; + uint32_t boost; + uint32_t turbo_boost; + uint32_t min_boost; + uint32_t max_boost; + uint32_t hse_en; + uint32_t driver_time; + uint32_t ip_time; + uint32_t bw; + uint32_t pack_id; + uint32_t affinity; + uint32_t trigger_type; + /* cmdbufs info */ + uint32_t cmdbuf_start_idx; + uint32_t num_cmdbufs; + /* history info */ + uint32_t history_ip_time; +} __packed; + +struct mdw_rv_msg_cb { + uint64_t device_va; + uint32_t size; +} __packed; + +struct mdw_rv_msg_ammu { + uint32_t cb_head_device_va; + uint32_t table_head_device_va; + uint32_t table_size; +} __packed; + +struct mdw_rv_sc_link { + uint32_t producer_idx; + uint32_t consumer_idx; + uint32_t vid; + uint64_t va; + uint64_t x; + uint64_t y; +} __packed; + +static void mdw_rv_cmd_print(struct mdw_rv_msg_cmd *rc) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rc kid(0x%llx)\n", rc->cmd_id); + mdw_cmd_debug(" inference_id = 0x%llx\n", rc->inference_id); + mdw_cmd_debug(" session = 0x%llx\n", rc->session_id); + mdw_cmd_debug(" priority = %u\n", rc->priority); + mdw_cmd_debug(" hardlimit = %u\n", rc->hardlimit); + mdw_cmd_debug(" softlimit = %u\n", rc->softlimit); + mdw_cmd_debug(" fastmem_ms = %u\n", rc->fastmem_ms); + mdw_cmd_debug(" power_plcy = %u\n", rc->power_plcy); + mdw_cmd_debug(" power_dtime = %u\n", rc->power_dtime); + mdw_cmd_debug(" power_etime = %u\n", rc->power_etime); + mdw_cmd_debug(" app_type = %u\n", rc->app_type); + mdw_cmd_debug(" num_subcmds = %u\n", rc->num_subcmds); + mdw_cmd_debug(" subcmds_offset = 0x%x\n", rc->subcmds_offset); + mdw_cmd_debug(" num_cmdbufs = %u\n", rc->num_cmdbufs); + mdw_cmd_debug(" cmdbuf_infos_offset = 0x%x\n", rc->cmdbuf_infos_offset); + mdw_cmd_debug(" apummu_tbl_infos_offset = 0x%x\n", rc->apummu_tbl_infos_offset); + mdw_cmd_debug(" adj_matrix_offset = 0x%x\n", rc->adj_matrix_offset); + mdw_cmd_debug(" exec_infos_offset = 0x%x\n", rc->exec_infos_offset); + mdw_cmd_debug(" num_links = %u\n", rc->num_links); + mdw_cmd_debug(" link_offset = 0x%x\n", rc->link_offset); + mdw_cmd_debug(" inference_time = %u\n", rc->inference_ms); + mdw_cmd_debug(" tolerance_time = %u\n", rc->tolerance_ms); + mdw_cmd_debug("-------------------------\n"); +} + +static void mdw_rv_sc_print(struct mdw_rv_msg_sc *rsc, + uint64_t cmd_id, uint32_t idx) +{ + mdw_cmd_debug("-------------------------\n"); + mdw_cmd_debug("rv subcmd(0x%llx-#%u)\n", cmd_id, idx); + mdw_cmd_debug(" type = %u\n", rsc->type); + mdw_cmd_debug(" suggest_time = %u\n", rsc->suggest_time); + mdw_cmd_debug(" vlm_usage = %u\n", rsc->vlm_usage); + mdw_cmd_debug(" vlm_ctx_id = %u\n", rsc->vlm_ctx_id); + mdw_cmd_debug(" vlm_force = %u\n", rsc->vlm_force); + mdw_cmd_debug(" boost = %u\n", rsc->boost); + mdw_cmd_debug(" turbo_boost = %u\n", rsc->turbo_boost); + mdw_cmd_debug(" min_boost = %u\n", rsc->min_boost); + mdw_cmd_debug(" max_boost = %u\n", rsc->max_boost); + mdw_cmd_debug(" hse_en = %u\n", rsc->hse_en); + mdw_cmd_debug(" driver_time = %u\n", rsc->driver_time); + mdw_cmd_debug(" ip_time = %u\n", rsc->ip_time); + mdw_cmd_debug(" pack_id = %u\n", rsc->pack_id); + mdw_cmd_debug(" affinity = 0x%x\n", rsc->affinity); + mdw_cmd_debug(" trigger_type = %u\n", rsc->trigger_type); + mdw_cmd_debug(" cmdbuf_start_idx = %u\n", rsc->cmdbuf_start_idx); + mdw_cmd_debug(" num_cmdbufs = %u\n", rsc->num_cmdbufs); + mdw_cmd_debug(" history_ip_time = %u\n", rsc->history_ip_time); + mdw_cmd_debug("-------------------------\n"); +} + +static int mdw_rv_cmd_delete(struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = (struct mdw_rv_cmd *)c->internal_cmd; + + if (!rc) + return -EINVAL; + + mdw_trace_begin("apumdw:rv_cmd_delete"); + mdw_mem_pool_free(rc->cb); + kfree(rc); + c->internal_cmd = NULL; + c->del_internal = NULL; + mdw_trace_end(); + + return 0; +} + +static struct mdw_rv_cmd *mdw_rv_cmd_create(struct mdw_fpriv *mpriv, + struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = NULL; + uint64_t cb_size = 0; + uint32_t acc_cb = 0, i = 0, j = 0; + uint32_t subcmds_ofs = 0, cmdbuf_infos_ofs = 0, adj_matrix_ofs = 0; + uint32_t exec_infos_ofs = 0, link_ofs = 0; + uint32_t apummu_tbl_infos_ofs = 0; + struct mdw_rv_msg_cmd *rmc = NULL; + struct mdw_rv_msg_sc *rmsc = NULL; + struct mdw_rv_msg_cb *rmcb = NULL; + struct mdw_rv_msg_ammu *rmammu = NULL; + struct mdw_rv_sc_link *rl = NULL; + struct mdw_cmd_history_tbl *ch_tbl = NULL; + + mdw_trace_begin("apumdw:rv_cmd_create"); + /* reuse internal cmd if exist */ + if (c->internal_cmd) { + mdw_cmd_debug("reuse internal cmd\n"); + rc = (struct mdw_rv_cmd *)c->internal_cmd; + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + goto reuse; + } + + /* check mem address for rv */ + if (MDW_IS_HIGHADDR(c->exec_infos->device_va) || + MDW_IS_HIGHADDR(c->cmdbufs->device_va)) { + mdw_drv_err("rv dva high addr(0x%llx/0x%llx)\n", + c->cmdbufs->device_va, c->exec_infos->device_va); + goto out; + } + + rc = kzalloc(sizeof(*rc), GFP_KERNEL); + if (!rc) + goto out; + + c->rvid = (uint64_t)&rc->s_msg; + init_completion(&rc->s_msg.cmplt); + + /* calc size and offset */ + rc->c = c; + cb_size += sizeof(struct mdw_rv_msg_cmd); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + adj_matrix_ofs = cb_size; + cb_size += (c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + subcmds_ofs = cb_size; + cb_size += (c->num_subcmds * sizeof(struct mdw_rv_msg_sc)); + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + cmdbuf_infos_ofs = cb_size; + cb_size += (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb)); + if (cb_size < (c->num_cmdbufs * sizeof(struct mdw_rv_msg_cb))) { + mdw_drv_err("cb_size overflow(%llu) cmdbufs(%u*%zu)\n", + cb_size, c->num_cmdbufs, sizeof(struct mdw_rv_msg_cb)); + goto free_rc; + } + cb_size = MDW_ALIGN(cb_size, MDW_DEFAULT_ALIGN); + apummu_tbl_infos_ofs = cb_size; /* APUMMU add tail of cmd buf */ + cb_size += sizeof(struct mdw_rv_msg_ammu); + exec_infos_ofs = cb_size; + cb_size += c->exec_infos->size; + if (cb_size < c->exec_infos->size) { + mdw_drv_err("cb_size overflow(%llu) exec_infos size(%llu)\n", + cb_size, c->exec_infos->size); + goto free_rc; + } + if (c->num_links) { + link_ofs = cb_size; + cb_size += (c->num_links * sizeof(struct mdw_rv_sc_link)); + if (cb_size < (c->num_links * sizeof(struct mdw_rv_sc_link))) { + mdw_drv_err("cb_size overflow(%llu) links(%u*%zu)\n", + cb_size, c->num_links, sizeof(struct mdw_rv_sc_link)); + goto free_rc; + } + } + + /* allocate communicate buffer */ + rc->cb = mdw_mem_pool_alloc(&mpriv->cmd_buf_pool, cb_size, + MDW_DEFAULT_ALIGN); + if (!rc->cb) { + mdw_drv_err("c(0x%llx) alloc cb size(%llu) fail\n", + c->kid, cb_size); + goto free_rc; + } + + /* assign cmd info */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + rmc->session_id = (uint64_t)c->mpriv; + rmc->cmd_id = c->kid; + rmc->pid = (uint32_t)c->pid; + rmc->tgid = (uint32_t)c->tgid; + rmc->priority = c->priority; + rmc->hardlimit = c->hardlimit; + rmc->softlimit = c->softlimit; + rmc->fastmem_ms = c->fastmem_ms; + rmc->power_plcy = c->power_plcy; + rmc->power_dtime = c->power_dtime; + rmc->power_etime = c->power_etime; + rmc->app_type = c->app_type; + rmc->num_subcmds = c->num_subcmds; + rmc->num_cmdbufs = c->num_cmdbufs; + rmc->subcmds_offset = subcmds_ofs; + rmc->cmdbuf_infos_offset = cmdbuf_infos_ofs; + rmc->apummu_tbl_infos_offset = apummu_tbl_infos_ofs; /* APUMMU Table offset */ + rmc->adj_matrix_offset = adj_matrix_ofs; + rmc->exec_infos_offset = exec_infos_ofs; + rmc->num_links = c->num_links; + rmc->link_offset = link_ofs; + rmc->inference_ms = c->inference_ms; + rmc->tolerance_ms = c->tolerance_ms; + rmc->inference_id = c->inference_id; + mdw_rv_cmd_print(rmc); + + /* copy links */ + rl = (void *)rmc + rmc->link_offset; + for (i = 0; i < c->num_links; i++) { + rl[i].producer_idx = c->links[i].producer_idx; + rl[i].consumer_idx = c->links[i].consumer_idx; + rl[i].vid = c->links[i].vid; + rl[i].va = c->links[i].va; + rl[i].x = c->links[i].x; + rl[i].y = c->links[i].y; + } + + /* assign subcmds info */ + rmsc = (void *)rmc + rmc->subcmds_offset; + rmcb = (void *)rmc + rmc->cmdbuf_infos_offset; + for (i = 0; i < c->num_subcmds; i++) { + rmsc[i].type = c->subcmds[i].type; + rmsc[i].suggest_time = c->subcmds[i].suggest_time; + rmsc[i].vlm_usage = c->subcmds[i].vlm_usage; + rmsc[i].vlm_ctx_id = c->subcmds[i].vlm_ctx_id; + rmsc[i].vlm_force = c->subcmds[i].vlm_force; + rmsc[i].boost = c->subcmds[i].boost; + rmsc[i].ip_time = c->subcmds[i].ip_time; + rmsc[i].driver_time = c->subcmds[i].driver_time; + rmsc[i].bw = c->subcmds[i].bw; + rmsc[i].turbo_boost = c->subcmds[i].turbo_boost; + rmsc[i].min_boost = c->subcmds[i].min_boost; + rmsc[i].max_boost = c->subcmds[i].max_boost; + rmsc[i].hse_en = c->subcmds[i].hse_en; + rmsc[i].pack_id = c->subcmds[i].pack_id; + rmsc[i].affinity = c->subcmds[i].affinity; + rmsc[i].num_cmdbufs = c->subcmds[i].num_cmdbufs; + rmsc[i].cmdbuf_start_idx = acc_cb; + rmsc[i].trigger_type = c->subcmds[i].trigger_type; + + for (j = 0; j < rmsc[i].num_cmdbufs; j++) { + rmcb[acc_cb + j].size = + c->ksubcmds[i].cmdbufs[j].size; + rmcb[acc_cb + j].device_va = + c->ksubcmds[i].daddrs[j]; + mdw_cmd_debug("sc(%u) #%u-cmdbufs 0x%llx/%u\n", + i, j, + rmcb[acc_cb + j].device_va, + rmcb[acc_cb + j].size); + } + acc_cb += c->subcmds[i].num_cmdbufs; + } + + /* assign apummu info */ + rmammu = (void *)rmc + rmc->apummu_tbl_infos_offset; + rmammu->cb_head_device_va = (uint32_t)mpriv->cb_head_device_va; + rmammu->table_head_device_va = c->cmdbufs->tbl_daddr; + rmammu->table_size = (uint32_t)c->size_apummutable; + + /* setup internal cmd */ + c->del_internal = mdw_rv_cmd_delete; + c->internal_cmd = rc; + +reuse: + /* set start timestamp */ + rc->start_ts_ns = c->start_ts; + + /* copy adj matrix */ + memcpy((void *)rmc + rmc->adj_matrix_offset, c->adj_matrix, + c->num_subcmds * c->num_subcmds * sizeof(uint8_t)); + + /* clear einfos */ + memset((void *)rmc + rmc->exec_infos_offset, 0, c->exec_infos->size); + + /* clear exec ret */ + c->einfos->c.ret = 0; + c->einfos->c.sc_rets = 0; + rmc->cmd_done = 0; + + /* update history ip time */ + rmsc = (void *)rmc + rmc->subcmds_offset; + ch_tbl = mdw_cmd_ch_tbl_find(c); + for (i = 0; i < c->num_subcmds; i++) { + if (ch_tbl) + rmsc[i].history_ip_time = ch_tbl->h_sc_einfo[i].ip_time; + mdw_rv_sc_print(&rmsc[i], rmc->cmd_id, i); + } + + if (mdw_mem_flush(mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx) flush rv cbs(%llu) fail\n", + (uint64_t)c->mpriv, c->kid, c->rvid, rc->cb->size); + + + goto out; + +free_rc: + kfree(rc); + rc = NULL; +out: + mdw_trace_end(); + return rc; +} + +static void mdw_rv_cmd_cp_execinfo(struct mdw_rv_cmd *rc) +{ + struct mdw_cmd *c = rc->c; + struct mdw_rv_msg_cmd *rmc = NULL; + + /* invalidate */ + if (mdw_mem_invalidate(c->mpriv, rc->cb)) + mdw_drv_warn("s(0x%llx) c(0x%llx/0x%llx/0x%llx) invalidate rcbs(%llu) fail\n", + (uint64_t)c->mpriv, c->uid, c->kid, + c->rvid, rc->cb->size); + + /* copy exec infos */ + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + if (rmc->exec_infos_offset + c->exec_infos->size == rc->cb->size || + rmc->link_offset + c->num_links * sizeof(struct mdw_rv_sc_link) + == rc->cb->size) { + memcpy(c->exec_infos->vaddr, + rc->cb->vaddr + rmc->exec_infos_offset, + c->exec_infos->size); + } else { + mdw_drv_warn("c(0x%llx/0x%llx/0x%llx) execinfos(%llu/%u) links(%u/%llu) not matched\n", + c->uid, c->kid, c->rvid, + rmc->exec_infos_offset + c->exec_infos->size, + rmc->link_offset, c->num_links, + rc->cb->size); + } +} + +static void mdw_rv_cmd_done(struct mdw_rv_cmd *rc, int ret) +{ + struct mdw_cmd *c = rc->c; + + /* complete cmd */ + c->complete(c, ret); +} + +static bool mdw_rv_cmd_poll(struct mdw_rv_cmd *rc) +{ + struct mdw_rv_msg_cmd *rmc = NULL; + uint32_t i = 0; + uint32_t poll_interval = MDW_POLL_TIME, poll_timeout = MDW_POLL_TIMEOUT; + bool poll_ret = false; + + rmc = (struct mdw_rv_msg_cmd *)rc->cb->vaddr; + + if (g_mdw_poll_interval) + poll_interval = g_mdw_poll_interval; + if (g_mdw_poll_timeout) + poll_timeout = g_mdw_poll_timeout; + + mdw_cmd_debug("poll_interval(%u), poll_timeout(%u)\n", poll_interval, poll_timeout); + + /* poll cmd done result */ + for(i = 0; i< poll_timeout; i++) { + if(rmc->cmd_done) { + poll_ret = true; + break; + } + udelay(poll_interval); + } + return poll_ret; +} + +/* kernel-tinysys version v4 */ +const struct mdw_rv_cmd_func mdw_rv_cmd_func_v4 = { + .create = mdw_rv_cmd_create, + .delete = mdw_rv_cmd_delete, + .done = mdw_rv_cmd_done, + .poll = mdw_rv_cmd_poll, + .cp_execinfo = mdw_rv_cmd_cp_execinfo, +}; diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_dev.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_dev.c new file mode 100644 index 0000000000000..bbdfb0c8e6a1f --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_dev.c @@ -0,0 +1,583 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include "mdw_cmn.h" +#include "mdw_trace.h" +#include "mdw_rv.h" +#include "mdw_rv_msg.h" +#include "mdw_rv_tag.h" +#define CREATE_TRACE_POINTS +#include "mdw_rv_events.h" +#include "mdw_mem_rsc.h" +#include + +#define MDW_CMD_IPI_TIMEOUT (10*1000) //ms + + +static void mdw_rv_dev_msg_insert(struct mdw_rv_dev *mrdev, + struct mdw_ipi_msg_sync *s_msg) +{ + list_add_tail(&s_msg->ud_item, &mrdev->s_list); +} + +static void mdw_rv_dev_msg_remove(struct mdw_rv_dev *mrdev, + struct mdw_ipi_msg_sync *s_msg) +{ + list_del(&s_msg->ud_item); +} + +static struct mdw_ipi_msg_sync *mdw_rv_dev_msg_find(struct mdw_rv_dev *mrdev, + uint64_t sync_id) +{ + struct mdw_ipi_msg_sync *s_msg = NULL, *tmp = NULL; + + mdw_drv_debug("get msg(0x%llx)\n", sync_id); + + list_for_each_entry_safe(s_msg, tmp, &mrdev->s_list, ud_item) { + if (s_msg->msg.sync_id == sync_id) + return s_msg; + } + return NULL; +} + +static int mdw_rv_dev_send_msg(struct mdw_rv_dev *mrdev, struct mdw_ipi_msg_sync *s_msg) +{ + int ret = 0; + uint32_t cnt = 100, i = 0; + + s_msg->msg.sync_id = (uint64_t)s_msg; + mdw_drv_debug("sync id(0x%llx) (0x%llx/%u)\n", + s_msg->msg.sync_id, s_msg->msg.c.iova, s_msg->msg.c.size); + + /* insert to msg list */ + mutex_lock(&mrdev->msg_mtx); + mdw_rv_dev_msg_insert(mrdev, s_msg); + mutex_unlock(&mrdev->msg_mtx); + + /* send & retry */ + for (i = 0; i < cnt; i++) { + mdw_trace_begin("apumdw:send_ipi|msg:0x%llx", s_msg->msg.sync_id); + ret = rpmsg_send(mrdev->ept, &s_msg->msg, sizeof(s_msg->msg)); + mdw_trace_end(); + + /* send busy, retry */ + if (ret == -EBUSY || ret == -EAGAIN) { + if (!(i % 10)) + mdw_drv_info("re-send ipi(%u/%u)\n", i, cnt); + if (ret == -EAGAIN && i < 10) + usleep_range(200, 500); + else if (ret == -EAGAIN && i < 50) + usleep_range(1000, 2000); + else + usleep_range(10000, 11000); + continue; + } + break; + } + + /* send ipi fail, remove msg from list */ + if (ret) { + mdw_drv_err("send ipi msg(0x%llx) fail(%d)\n", + s_msg->msg.sync_id, ret); + + mutex_lock(&mrdev->msg_mtx); + if (mdw_rv_dev_msg_find(mrdev, s_msg->msg.sync_id) == s_msg) { + mdw_drv_warn("remove ipi msg(0x%llx)\n", + s_msg->msg.sync_id); + mdw_rv_dev_msg_remove(mrdev, s_msg); + } else { + mdw_drv_err("can't find ipi msg(0x%llx)\n", + s_msg->msg.sync_id); + } + mutex_unlock(&mrdev->msg_mtx); + } + + return ret; +} + +static void mdw_rv_ipi_cmplt_sync(struct mdw_ipi_msg_sync *s_msg) +{ + mdw_flw_debug("\n"); + complete(&s_msg->cmplt); +} + +static int mdw_rv_dev_send_sync(struct mdw_rv_dev *mrdev, struct mdw_ipi_msg *msg) +{ + int ret = 0; + struct mdw_ipi_msg_sync *s_msg = NULL; + unsigned long timeout = msecs_to_jiffies(MDW_CMD_IPI_TIMEOUT); + + s_msg = kzalloc(sizeof(*s_msg), GFP_KERNEL); + if (!s_msg) + return -ENOMEM; + + memcpy(&s_msg->msg, msg, sizeof(*msg)); + init_completion(&s_msg->cmplt); + s_msg->complete = mdw_rv_ipi_cmplt_sync; + + mutex_lock(&mrdev->mtx); + /* send */ + ret = mdw_rv_dev_send_msg(mrdev, s_msg); + if (ret) { + mdw_drv_err("send msg fail\n"); + goto fail_send_sync; + } + mutex_unlock(&mrdev->mtx); + + /* wait for response */ + if (!wait_for_completion_timeout(&s_msg->cmplt, timeout)) { + mdw_drv_err("ipi no response\n"); + mutex_lock(&mrdev->msg_mtx); + if (mdw_rv_dev_msg_find(mrdev, s_msg->msg.sync_id) == s_msg) { + mdw_drv_warn("remove ipi msg(0x%llx)\n", + s_msg->msg.sync_id); + mdw_rv_dev_msg_remove(mrdev, s_msg); + } else { + mdw_drv_err("can't find ipi msg(0x%llx)\n", + s_msg->msg.sync_id); + } + mutex_unlock(&mrdev->msg_mtx); + ret = -ETIME; + } else { + memcpy(msg, &s_msg->msg, sizeof(*msg)); + ret = msg->ret; + if (ret) + mdw_drv_warn("up return fail(%d)\n", ret); + } + + goto out; + +fail_send_sync: + mutex_unlock(&mrdev->mtx); +out: + kfree(s_msg); + + return ret; +} + +static void mdw_rv_ipi_cmplt_cmd(struct mdw_ipi_msg_sync *s_msg) +{ + int ret = 0; + struct mdw_rv_cmd *rc = + container_of(s_msg, struct mdw_rv_cmd, s_msg); + struct mdw_cmd *c = rc->c; + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)c->mpriv->mdev->dev_specific; + + switch (s_msg->msg.ret) { + case MDW_IPI_MSG_STATUS_BUSY: + ret = -EBUSY; + break; + + case MDW_IPI_MSG_STATUS_ERR: + ret = -EREMOTEIO; + mdw_exception("uP mdw error, sync_id (0x%llx)\n", + s_msg->msg.sync_id); + break; + + case MDW_IPI_MSG_STATUS_TIMEOUT: + ret = -ETIME; + break; + + default: + break; + } + + if (ret) + mdw_drv_err("cmd(%p/0x%llx) ret(%d/0x%llx) time(%llu) pid(%d/%d)\n", + c->mpriv, c->kid, ret, c->einfos->c.sc_rets, + c->einfos->c.total_us, c->pid, c->tgid); + c->enter_rv_cb_time = mrdev->enter_rv_cb_time; + c->rv_cb_time = mrdev->rv_cb_time; + mdw_cmd_trace(rc->c, MDW_CMD_DONE); + mrdev->cmd_funcs->done(rc, ret); +} + +static int mdw_rv_dev_send_cmd(struct mdw_rv_dev *mrdev, struct mdw_rv_cmd *rc) +{ + int ret = 0; + + mdw_drv_debug("pid(%d) run cmd(0x%llx/0x%llx) dva(0x%llx) size(%llu)\n", + task_pid_nr(current), rc->c->kid, rc->c->rvid, + rc->cb->device_va, rc->cb->size); + + rc->s_msg.msg.id = MDW_IPI_APU_CMD; + rc->s_msg.msg.c.iova = rc->cb->device_va; + rc->s_msg.msg.c.size = rc->cb->size; + rc->s_msg.msg.c.start_ts_ns = rc->start_ts_ns; + rc->s_msg.complete = mdw_rv_ipi_cmplt_cmd; + + /* send */ + ret = mdw_rv_dev_send_msg(mrdev, &rc->s_msg); + mdw_cmd_trace(rc->c, MDW_CMD_START); + if (ret) { + mdw_cmd_trace(rc->c, MDW_CMD_DONE); + mdw_drv_err("pid(%d) send msg fail\n", task_pid_nr(current)); + } + + return ret; +} + +int mdw_rv_dev_run_cmd(struct mdw_fpriv *mpriv, struct mdw_cmd *c) +{ + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mpriv->mdev->dev_specific; + struct mdw_rv_cmd *rc = NULL; + int ret = 0; + + mdw_trace_begin("apumdw:dev_run|cmd:0x%llx/0x%llx", c->uid, c->kid); + + rc = mrdev->cmd_funcs->create(mpriv, c); + if (!rc) { + ret = -EINVAL; + goto out; + } + + mdw_drv_debug("run rc(0%llx)\n", (uint64_t)rc); + mutex_lock(&mrdev->mtx); + ret = mdw_rv_dev_send_cmd(mrdev, rc); + mutex_unlock(&mrdev->mtx); + +out: + mdw_trace_end(); + return ret; +} + +bool mdw_rv_dev_poll_cmd(struct mdw_rv_dev *mrdev, struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = (struct mdw_rv_cmd *)c->internal_cmd; + bool poll_ret = false; + + if (mrdev->rv_version < 4) { + mdw_flw_debug("not support poll cmd\n"); + goto out; + } + + /* poll cmd done */ + mdw_trace_begin("apumdw:poll_cmd"); + poll_ret = mrdev->cmd_funcs->poll(rc); + mdw_trace_end(); + + if (poll_ret) { + mdw_flw_debug("c(0x%llx) poll cmd done\n", + c->kid); + } else { + mdw_flw_debug("poll cmd c(0x%llx) is running\n", + c->kid); + } +out: + return poll_ret; +} + +void mdw_rv_dev_cp_execinfo(struct mdw_rv_dev *mrdev, struct mdw_cmd *c) +{ + struct mdw_rv_cmd *rc = (struct mdw_rv_cmd *)c->internal_cmd; + + if (mrdev->rv_version < 4) { + mdw_flw_debug("not support cp execinfo\n"); + return; + } + /* cp execinfo */ + mrdev->cmd_funcs->cp_execinfo(rc); +} + +static int mdw_rv_callback(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct mdw_ipi_msg *msg = (struct mdw_ipi_msg *)data; + struct mdw_ipi_msg_sync *s_msg = NULL; + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)priv; + uint64_t ts1 = 0, ts2 = 0; + + mdw_drv_debug("callback msg(%d/0x%llx)\n", msg->id, msg->sync_id); + + ts1 = sched_clock(); + mutex_lock(&mrdev->msg_mtx); + ts2 = sched_clock(); + mrdev->enter_rv_cb_time = ts2 - ts1; + s_msg = mdw_rv_dev_msg_find(mrdev, msg->sync_id); + if (!s_msg) { + mdw_exception("get ipi msg fail(0x%llx)", msg->sync_id); + } else { + memcpy(&s_msg->msg, msg, sizeof(*msg)); + list_del(&s_msg->ud_item); + } + mutex_unlock(&mrdev->msg_mtx); + ts1 = sched_clock(); + mrdev->rv_cb_time = ts1 - ts2; + /* complete callback */ + if (s_msg) + s_msg->complete(s_msg); + + return 0; +} + +int mdw_rv_dev_set_param(struct mdw_rv_dev *mrdev, enum mdw_info_type type, uint32_t val) +{ + struct mdw_ipi_msg msg; + int ret = 0; + + if (type == MDW_INFO_KLOG) { + g_mdw_klog = val; + goto out; + } else if (type >= MDW_INFO_MAX) { + ret = -EINVAL; + goto out; + } + memset(&msg, 0, sizeof(msg)); + msg.id = MDW_IPI_PARAM; + msg.p.type = type; + msg.p.dir = MDW_INFO_SET; + msg.p.value = val; + + mdw_drv_debug("set param(%u/%u/%u)\n", msg.p.type, msg.p.dir, msg.p.value); + ret = mdw_rv_dev_send_sync(mrdev, &msg); + if (!ret) + memcpy(&mrdev->param, &msg.p, sizeof(msg.p)); + +out: + return ret; +} + +int mdw_rv_dev_get_param(struct mdw_rv_dev *mrdev, enum mdw_info_type type, uint32_t *val) +{ + int ret = 0; + struct mdw_ipi_msg msg; + + switch (type) { + case MDW_INFO_KLOG: + *val = g_mdw_klog; + break; + case MDW_INFO_NORMAL_TASK_DLA: + *val = mrdev->stat->task_num[APUSYS_DEVICE_MDLA][MDW_QUEUE_NORMAL]; + break; + case MDW_INFO_NORMAL_TASK_DSP: + *val = mrdev->stat->task_num[APUSYS_DEVICE_VPU][MDW_QUEUE_NORMAL] + + mrdev->stat->task_num[APUSYS_DEVICE_MVPU][MDW_QUEUE_NORMAL]; + break; + case MDW_INFO_NORMAL_TASK_DMA: + *val = mrdev->stat->task_num[APUSYS_DEVICE_EDMA][MDW_QUEUE_NORMAL]; + break; + case MDW_INFO_MIN_DTIME: + case MDW_INFO_MIN_ETIME: + case MDW_INFO_MAX_DTIME: + case MDW_INFO_RESERV_TIME_REMAIN: + memset(&msg, 0, sizeof(msg)); + msg.id = MDW_IPI_PARAM; + msg.p.type = type; + msg.p.dir = MDW_INFO_GET; + + mdw_drv_debug("get param(%u/%u/%u)\n", msg.p.type, msg.p.dir, msg.p.value); + ret = mdw_rv_dev_send_sync(mrdev, &msg); + if (!ret) + *val = msg.p.value; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int mdw_rv_dev_handshake(struct mdw_rv_dev *mrdev) +{ + struct mdw_ipi_msg msg; + int ret = 0; + uint32_t type = 0; + + /* query basic infos */ + memset(&msg, 0, sizeof(msg)); + msg.id = MDW_IPI_HANDSHAKE; + msg.h.h_id = MDW_IPI_HANDSHAKE_BASIC_INFO; + msg.h.basic.stat_iova = mrdev->stat_iova; + msg.h.basic.stat_size = sizeof(struct mdw_stat); + ret = mdw_rv_dev_send_sync(mrdev, &msg); + if (ret) + goto out; + + if (msg.id != MDW_IPI_HANDSHAKE || + msg.h.h_id != MDW_IPI_HANDSHAKE_BASIC_INFO) { + ret = -EINVAL; + goto out; + } + + memcpy(mrdev->dev_mask, &msg.h.basic.dev_bmp, sizeof(mrdev->dev_mask)); + memcpy(mrdev->mem_mask, &msg.h.basic.mem_bmp, sizeof(mrdev->mem_mask)); + mrdev->rv_version = msg.h.basic.version; + mrdev->mdev->power_gain_time_us = msg.h.basic.power_gain_time; + mdw_drv_warn("apusys: rv infos(%u)(0x%lx/0x%llx)(0x%lx/0x%llx) pwr(%u)\n", + mrdev->rv_version, mrdev->dev_mask[0], + msg.h.basic.dev_bmp, mrdev->mem_mask[0], msg.h.basic.mem_bmp, + mrdev->mdev->power_gain_time_us); + + /* query device num */ + type = 0; + do { + type = find_next_bit(mrdev->dev_mask, APUSYS_DEVICE_MAX, type); + if (type >= APUSYS_DEVICE_MAX) + break; + + memset(&msg, 0, sizeof(msg)); + msg.id = MDW_IPI_HANDSHAKE; + msg.h.h_id = MDW_IPI_HANDSHAKE_DEV_NUM; + msg.h.dev.type = type; + ret = mdw_rv_dev_send_sync(mrdev, &msg); + if (ret) + break; + + if (msg.id != MDW_IPI_HANDSHAKE || + msg.h.h_id != MDW_IPI_HANDSHAKE_DEV_NUM) { + ret = -EINVAL; + break; + } + + mrdev->dev_num[type] = msg.h.dev.num; + memcpy(&mrdev->meta_data[msg.h.dev.type][0], + msg.h.dev.meta, sizeof(msg.h.dev.meta)); + mdw_drv_debug("dev(%d) num(%u)\n", type, msg.h.dev.num); + type++; + } while (type < APUSYS_DEVICE_MAX); + + /* query mem info */ + type = 0; + do { + type = find_next_bit(mrdev->mem_mask, MDW_MEM_TYPE_MAX, type); + if (type >= MDW_MEM_TYPE_MAX) + break; + + memset(&msg, 0, sizeof(msg)); + msg.id = MDW_IPI_HANDSHAKE; + msg.h.h_id = MDW_IPI_HANDSHAKE_MEM_INFO; + msg.h.mem.type = type; + ret = mdw_rv_dev_send_sync(mrdev, &msg); + if (ret) + break; + + if (msg.id != MDW_IPI_HANDSHAKE || + msg.h.h_id != MDW_IPI_HANDSHAKE_MEM_INFO) { + ret = -EINVAL; + break; + } + + /* only vlm need addr */ + if (type == MDW_MEM_TYPE_VLM) + mrdev->minfos[type].device_va = msg.h.mem.start; + mrdev->minfos[type].dva_size = msg.h.mem.size; + + mdw_drv_debug("mem(%d)(0x%llx/0x%x)\n", + type, msg.h.mem.start, msg.h.mem.size); + type++; + } while (type < MDW_MEM_TYPE_MAX); + +out: + return ret; +} + +static void mdw_rv_dev_init_func(struct work_struct *wk) +{ + struct mdw_rv_dev *mrdev = container_of(wk, struct mdw_rv_dev, init_wk); + struct mdw_device *mdev = mrdev->mdev; + int ret = 0; + + ret = mdw_rv_dev_handshake(mrdev); + if (ret) { + mdw_drv_err("handshake fail(%d)\n", ret); + return; + } + + if (mrdev->rv_version < 2) { + mrdev->cmd_funcs = &mdw_rv_cmd_func_v2; + mdw_drv_info("use cmd_v2\n"); + } else if (mrdev->rv_version == 3) { + mrdev->cmd_funcs = &mdw_rv_cmd_func_v3; + mdw_drv_info("use cmd_v3\n"); + } else { + mrdev->cmd_funcs = &mdw_rv_cmd_func_v4; + mdw_drv_info("use cmd_v4\n"); + } + + memcpy(mdev->dev_mask, mrdev->dev_mask, sizeof(mrdev->dev_mask)); + mdev->inited = true; + mdw_drv_info("late init done\n"); +} + +int mdw_rv_dev_init(struct mdw_device *mdev) +{ + struct rpmsg_channel_info chinfo = {}; + struct mdw_rv_dev *mrdev = NULL; + struct device *dev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_CODE); + dma_addr_t dma_addr; + int ret = 0; + + if (!mdev->rpdev || mdev->driver_type != MDW_DRIVER_TYPE_RPMSG) { + mdw_drv_err("invalid driver type(%d)\n", mdev->driver_type); + ret = -EINVAL; + goto out; + } + + mrdev = kzalloc(sizeof(*mrdev), GFP_KERNEL); + if (!mrdev) + return -ENOMEM; + + mdev->dev_specific = mrdev; + mrdev->mdev = mdev; + mrdev->rpdev = mdev->rpdev; + + strscpy(chinfo.name, mrdev->rpdev->id.name, RPMSG_NAME_SIZE); + chinfo.src = mrdev->rpdev->src; + chinfo.dst = RPMSG_ADDR_ANY; + mrdev->ept = rpmsg_create_ept(mrdev->rpdev, + mdw_rv_callback, mrdev, chinfo); + if (!mrdev->ept) { + mdw_drv_err("create ept fail\n"); + ret = -ENODEV; + goto free_mrdev; + } + + /* Allocate stat buffer */ + dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + mrdev->stat = dma_alloc_coherent(dev, sizeof(struct mdw_stat), + &dma_addr, GFP_KERNEL); + mrdev->stat_iova = dma_addr; + mdw_drv_info("%pad\n", &dma_addr); + + if (!mrdev->stat) { + ret = -ENOMEM; + goto free_ept; + } + + /* init up dev */ + mutex_init(&mrdev->msg_mtx); + mutex_init(&mrdev->mtx); + INIT_LIST_HEAD(&mrdev->s_list); + INIT_WORK(&mrdev->init_wk, &mdw_rv_dev_init_func); + + schedule_work(&mrdev->init_wk); + + goto out; + +free_ept: + rpmsg_destroy_ept(mrdev->ept); +free_mrdev: + kfree(mrdev); + mdev->dev_specific = NULL; +out: + return ret; +} + +void mdw_rv_dev_deinit(struct mdw_device *mdev) +{ + struct mdw_rv_dev *mrdev = (struct mdw_rv_dev *)mdev->dev_specific; + struct device *dev = mdw_mem_rsc_get_dev(APUSYS_MEMORY_CODE); + + if (mrdev == NULL) + return; + + dma_free_coherent(dev, sizeof(struct mdw_stat), mrdev->stat, mrdev->stat_iova); + rpmsg_destroy_ept(mrdev->ept); + if (timer_pending(&mrdev->power_off_timer)) + del_timer(&mrdev->power_off_timer); + kfree(mrdev); + mdev->dev_specific = NULL; +} diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_events.h b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_events.h new file mode 100644 index 0000000000000..54ac8c12d2aff --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_events.h @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mdw_rv_events +#if !defined(__MDW_RV_EVENTS_H__) || defined(TRACE_HEADER_MULTI_READ) +#define __MDW_RV_EVENTS_H__ +#include + +#define MDW_TAG_CMD_PRINT \ + "%u,pid=%d,uid=0x%llx,rvid=0x%llx,"\ + "num_subcmds=%llu,priority=%llu,"\ + "softlimit=%u,pwr_dtime=%u,sc_rets=0x%llx,"\ + "pwr_plcy=%x,tolerance=%x,start_ts=0x%llx"\ + +#define MDW_TAG_SUBCMD_PRINT \ + "%u,rvid=0x%llx,inf_id=0x%llx,"\ + "%llu,vsid=%llu,ipstart_ts=0x%x,ipend_ts=0x%x,"\ + "was_preempted=0x%x,executed_core_bmp=0x%x,"\ + "tcm_usage=0x%x,history_iptime=%u,sync_info=0x%llx"\ + +#define MDW_TAG_CMD_DONE_PRINT \ + "%u,rvid=0x%llx,inf_id=0x%llx,enter_complt=%llu,pb_put_time=%llu"\ + "pb_put_time=%llu,handle_cmd_result_time=%llu,"\ + "load_aware_pwroff_time=%llu,enter_mpriv_release_time=%llu,"\ + "mpriv_release_time=%llu,sc_rets=0x%llx,ret=0x%llx"\ + +TRACE_EVENT(mdw_rv_cmd, + TP_PROTO(uint32_t status, + pid_t pid, + uint64_t uid, + uint64_t rvid, + uint64_t num_subcmds, + uint64_t priority, + uint32_t softlimit, + uint32_t pwr_dtime, + uint64_t sc_rets, + uint32_t pwr_plcy, + uint32_t tolerance, + uint64_t start_ts + ), + TP_ARGS(status, pid, uid, rvid, + num_subcmds, priority, + softlimit, pwr_dtime, + sc_rets, pwr_plcy, tolerance, start_ts + ), + TP_STRUCT__entry( + __field(uint32_t, status) + __field(pid_t, pid) + __field(uint64_t, uid) + __field(uint64_t, rvid) + __field(uint64_t, num_subcmds) + __field(uint64_t, priority) + __field(uint32_t, softlimit) + __field(uint32_t, pwr_dtime) + __field(uint64_t, sc_rets) + __field(uint32_t, pwr_plcy) + __field(uint32_t, tolerance) + __field(uint64_t, start_ts) + ), + TP_fast_assign( + __entry->status = status; + __entry->pid = pid; + __entry->uid = uid; + __entry->rvid = rvid; + __entry->num_subcmds = num_subcmds; + __entry->priority = priority; + __entry->softlimit = softlimit; + __entry->pwr_dtime = pwr_dtime; + __entry->sc_rets = sc_rets; + __entry->pwr_dtime = pwr_plcy; + __entry->pwr_dtime = tolerance; + __entry->pwr_dtime = start_ts; + ), + TP_printk( + MDW_TAG_CMD_PRINT, + __entry->status, + __entry->pid, + __entry->uid, + __entry->rvid, + __entry->num_subcmds, + __entry->priority, + __entry->softlimit, + __entry->pwr_dtime, + __entry->sc_rets, + __entry->pwr_plcy, + __entry->tolerance, + __entry->start_ts + ) +); + +TRACE_EVENT(mdw_rv_subcmd, + TP_PROTO(uint32_t status, + uint64_t rvid, + uint64_t inf_id, + uint64_t sc_info, + uint64_t vsid, + uint32_t ipstart_ts, + uint32_t ipend_ts, + uint32_t was_preempted, + uint32_t executed_core_bmp, + uint32_t tcm_usage, + uint32_t history_iptime, + uint64_t sync_info + ), + TP_ARGS(status, rvid, inf_id, sc_info, vsid, + ipstart_ts, ipend_ts, + was_preempted, executed_core_bmp, + tcm_usage, history_iptime, sync_info + ), + TP_STRUCT__entry( + __field(uint32_t, status) + __field(uint64_t, rvid) + __field(uint64_t, inf_id) + __field(uint64_t, sc_info) + __field(uint64_t, vsid) + __field(uint32_t, ipstart_ts) + __field(uint32_t, ipend_ts) + __field(uint32_t, was_preempted) + __field(uint32_t, executed_core_bmp) + __field(uint32_t, tcm_usage) + __field(uint32_t, history_iptime) + __field(uint64_t, sync_info) + ), + TP_fast_assign( + __entry->status = status; + __entry->rvid = rvid; + __entry->inf_id = inf_id; + __entry->sc_info= sc_info; + __entry->vsid= vsid; + __entry->ipstart_ts = ipstart_ts; + __entry->ipend_ts = ipend_ts; + __entry->was_preempted = was_preempted; + __entry->executed_core_bmp = executed_core_bmp; + __entry->tcm_usage = tcm_usage; + __entry->history_iptime = history_iptime; + __entry->sync_info = sync_info; + ), + TP_printk( + MDW_TAG_SUBCMD_PRINT, + __entry->status, + __entry->rvid, + __entry->inf_id, + __entry->sc_info, + __entry->vsid, + __entry->ipstart_ts, + __entry->ipend_ts, + __entry->was_preempted, + __entry->executed_core_bmp, + __entry->tcm_usage, + __entry->history_iptime, + __entry->sync_info + ) +); + +TRACE_EVENT(mdw_rv_cmd_deque, + TP_PROTO(uint32_t status, + uint64_t rvid, + uint64_t inf_id, + uint64_t enter_complt, + uint64_t pb_put_time, + uint64_t cmdbuf_out_time, + uint64_t handle_cmd_result_time, + uint64_t load_aware_pwroff_time, + uint64_t enter_mpriv_release_time, + uint64_t mpriv_release_time, + uint64_t sc_rets, + uint64_t c_ret + ), + TP_ARGS(status, rvid, inf_id, + enter_complt, pb_put_time, + cmdbuf_out_time, handle_cmd_result_time, + load_aware_pwroff_time, enter_mpriv_release_time, mpriv_release_time, + sc_rets, c_ret + ), + TP_STRUCT__entry( + __field(uint32_t, status) + __field(uint64_t, rvid) + __field(uint64_t, inf_id) + __field(uint64_t, enter_complt) + __field(uint64_t, pb_put_time) + __field(uint64_t, cmdbuf_out_time) + __field(uint64_t, handle_cmd_result_time) + __field(uint64_t, load_aware_pwroff_time) + __field(uint64_t, enter_mpriv_release_time) + __field(uint64_t, mpriv_release_time) + __field(uint64_t, sc_rets) + __field(uint64_t, c_ret) + ), + TP_fast_assign( + __entry->status = status; + __entry->rvid = rvid; + __entry->inf_id = inf_id; + __entry->enter_complt = enter_complt; + __entry->pb_put_time = pb_put_time; + __entry->cmdbuf_out_time = cmdbuf_out_time; + __entry->handle_cmd_result_time = handle_cmd_result_time; + __entry->load_aware_pwroff_time = load_aware_pwroff_time; + __entry->enter_mpriv_release_time = enter_mpriv_release_time; + __entry->mpriv_release_time = mpriv_release_time; + __entry->sc_rets = sc_rets; + __entry->c_ret = c_ret; + ), + TP_printk( + MDW_TAG_CMD_DONE_PRINT, + __entry->status, + __entry->rvid, + __entry->inf_id, + __entry->enter_complt, + __entry->pb_put_time, + __entry->cmdbuf_out_time, + __entry->handle_cmd_result_time, + __entry->load_aware_pwroff_time, + __entry->enter_mpriv_release_time, + __entry->mpriv_release_time, + __entry->sc_rets, + __entry->c_ret + ) +); + +#undef MDW_TAG_CMD_PRINT +#undef MDW_TAG_SUBCMD_PRINT +#undef MDW_TAG_CMD_DONE_PRINT + +#endif /* #if !defined(__MDW_RV_EVENTS_H__) || defined(TRACE_HEADER_MULTI_READ) */ + + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE mdw_rv_events +#include + diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_msg.h b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_msg.h new file mode 100644 index 0000000000000..98b2fb277c87b --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_msg.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_RV_MSG__ +#define __MTK_APU_MDW_RV_MSG__ + +#include "mdw.h" +/* mdw queue cmd type */ +enum { + MDW_IPI_NONE, + MDW_IPI_APU_CMD, + MDW_IPI_HANDSHAKE, + MDW_IPI_PARAM, + MDW_IPI_MAX = 0x20, +}; + +enum { + MDW_IPI_HANDSHAKE_BASIC_INFO, + MDW_IPI_HANDSHAKE_DEV_NUM, + MDW_IPI_HANDSHAKE_TASK_NUM, + MDW_IPI_HANDSHAKE_MEM_INFO, +}; + +enum { + MDW_IPI_MSG_STATUS_OK, + MDW_IPI_MSG_STATUS_BUSY, + MDW_IPI_MSG_STATUS_ERR, + MDW_IPI_MSG_STATUS_TIMEOUT, + MDW_IPI_MSG_STATUS_ABORT, +}; + +struct mdw_ipi_ucmd { + uint32_t dev_type; + uint32_t dev_idx; + uint64_t iova; + uint32_t size; +}; + +struct mdw_ipi_apu_cmd { + uint64_t start_ts_ns; // cmd time + uint64_t iova; + uint32_t size; +} __packed; + +struct mdw_ipi_handshake { + uint32_t h_id; + union { + struct { + uint64_t magic; + uint32_t version; + uint64_t dev_bmp; + uint64_t mem_bmp; + uint64_t stat_iova; + uint32_t stat_size; + uint32_t power_gain_time; + } basic; + struct { + uint32_t type; + uint32_t num; + uint8_t meta[MDW_DEV_META_SIZE]; + } dev; + struct { + uint32_t type; + uint64_t start; + uint32_t size; + } mem; + struct { + uint32_t type; + uint32_t norm_task_num; + uint32_t deadline_task_num; + } task; + }; +}; + +struct mdw_ipi_param { + uint32_t type; + uint32_t dir; + uint32_t value; +}; + +struct mdw_stat { + uint32_t task_num[APUSYS_DEVICE_LAST][MDW_QUEUE_MAX]; + uint32_t task_loading[APUSYS_DEVICE_LAST][MDW_QUEUE_MAX][2]; +} __packed; + +struct mdw_ipi_msg { + uint64_t sync_id; + uint32_t id; //ipi id + int32_t ret; + union { + struct mdw_ipi_apu_cmd c; + struct mdw_ipi_handshake h; + struct mdw_ipi_param p; + struct mdw_ipi_ucmd u; + }; +} __packed; + +struct mdw_ipi_msg_sync { + struct mdw_ipi_msg msg; + struct list_head ud_item; + struct completion cmplt; + void (*complete)(struct mdw_ipi_msg_sync *s_msg); +}; + +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.c b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.c new file mode 100644 index 0000000000000..abad0f67fd665 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mdw_rv.h" +#include "mdw_rv_tag.h" +#include "mdw_rv_events.h" +#include "mdw_cmn.h" + +/* 64-bit Subcmd information : [subcmd type(32bit) | subcmd index(32bit)] */ +#define MDW_SUBCMD_GEN_INFO(sc_type, sc_idx) ((sc_type << 32) | sc_idx) + +#define MDW_SUBCMD_GEN_INDEX(sc_info) (sc_info & 0xffffffff) +#define MDW_SUBCMD_GEN_TYPE(sc_info) (sc_info >> 32) + +enum mdw_tag_type { + MDW_TAG_CMD, + MDW_TAG_SUBCMD, + MDW_TAG_CMD_DEQUE, +}; + +#if IS_ENABLED(CONFIG_MTK_APUSYS_DEBUG) + +static struct apu_tags *mdw_rv_tags; + +void mdw_cmd_trace(struct mdw_cmd *c, uint32_t status) +{ + uint64_t param1 = 0, param2 = 0, param3 = 0, param4 = 0, param5 = 0; + + if (status == MDW_CMD_ENQUE) { + param1 = c->tgid; + param2 = c->power_etime; + param3 = c->inference_id; + param4 = c->num_subcmds; + param5 = c->priority; + } else if (status == MDW_CMD_START) { + param1 = c->uid; + param2 = c->inference_id; + param3 = c->start_ts; + param4 = c->num_subcmds; + param5 = c->priority; + } else if (status == MDW_CMD_DONE) { + param1 = c->rv_cb_time; + param2 = c->inference_id; + param3 = c->enter_rv_cb_time; + } + + trace_mdw_rv_cmd(status, + c->pid, + param1, + c->rvid, + param4, + param5, + c->softlimit, + c->power_dtime, + param2, + c->power_plcy, + c->tolerance_ms, + param3); +} + +/* The parameters must aligned with trace_mdw_rv_cmd() */ +static void +probe_rv_mdw_cmd(void *data, uint32_t status, pid_t pid, + uint64_t param1, uint64_t rvid, + uint64_t param4, + uint64_t param5, + uint32_t softlimit, + uint32_t pwr_dtime, + uint64_t param2, + uint32_t pwr_plcy, + uint32_t tolerance, + uint64_t param3) +{ + struct mdw_rv_tag t; + + if (!mdw_rv_tags) + return; + + t.type = MDW_TAG_CMD; + t.d.cmd.status = status; + t.d.cmd.pid = pid; + t.d.cmd.param1 = param1; + t.d.cmd.rvid = rvid; + t.d.cmd.param4 = param4; + t.d.cmd.param5 = param5; + t.d.cmd.softlimit = softlimit; + t.d.cmd.pwr_dtime = pwr_dtime; + t.d.cmd.param2 = param2; + t.d.cmd.pwr_plcy = pwr_plcy; + t.d.cmd.tolerance = tolerance; + t.d.cmd.param3 = param3; + + apu_tag_add(mdw_rv_tags, &t); +} + +void mdw_subcmd_trace(struct mdw_cmd *c, uint32_t sc_idx, uint64_t vsid, + uint32_t history_iptime, uint64_t sync_info, uint32_t status) +{ + + struct mdw_subcmd_exec_info *sc_einfo = NULL; + uint64_t sc_type = 0, sc_info = 0; + + sc_einfo = &c->einfos->sc; + sc_type = c->subcmds[sc_idx].type; + sc_info = MDW_SUBCMD_GEN_INFO(sc_type, sc_idx); + + trace_mdw_rv_subcmd(status, + c->rvid, c->inference_id, + sc_info, + vsid, + sc_einfo[sc_idx].ip_start_ts, + sc_einfo[sc_idx].ip_end_ts, + sc_einfo[sc_idx].was_preempted, + sc_einfo[sc_idx].executed_core_bitmap, + sc_einfo[sc_idx].tcm_usage, + history_iptime, + sync_info); +} + +/* The parameters must aligned with trace_mdw_rv_subcmd() */ +static void +probe_rv_mdw_subcmd(void *data, uint32_t status, + uint64_t rvid, uint64_t inf_id, + uint64_t sc_info, + uint64_t vsid, + uint32_t ipstart_ts, + uint32_t ipend_ts, + uint32_t was_preempted, + uint32_t executed_core_bmp, + uint32_t tcm_usage, + uint32_t history_iptime, + uint64_t sync_info) +{ + struct mdw_rv_tag t; + + if (!mdw_rv_tags) + return; + + t.type = MDW_TAG_SUBCMD; + t.d.subcmd.status = status; + t.d.subcmd.rvid = rvid; + t.d.subcmd.inf_id = inf_id; + t.d.subcmd.sc_idx = MDW_SUBCMD_GEN_INDEX(sc_info); + t.d.subcmd.sc_type = MDW_SUBCMD_GEN_TYPE(sc_info); + t.d.subcmd.vsid = vsid; + t.d.subcmd.ipstart_ts = ipstart_ts; + t.d.subcmd.ipend_ts = ipend_ts; + t.d.subcmd.was_preempted = was_preempted; + t.d.subcmd.executed_core_bmp = executed_core_bmp; + t.d.subcmd.tcm_usage = tcm_usage; + t.d.subcmd.history_iptime = history_iptime; + t.d.subcmd.sync_info = sync_info; + + apu_tag_add(mdw_rv_tags, &t); +} + +void mdw_cmd_deque_trace(struct mdw_cmd *c, uint32_t status) +{ + trace_mdw_rv_cmd_deque(status, + c->rvid, + c->inference_id, + c->enter_complt_time, + c->pb_put_time, + c->cmdbuf_out_time, + c->handle_cmd_result_time, + c->load_aware_pwroff_time, + c->enter_mpriv_release_time, + c->mpriv_release_time, + c->einfos->c.sc_rets, + c->einfos->c.ret); +} + +/* The parameters must aligned with trace_mdw_rv_cmd_deque() */ +static void +probe_rv_mdw_cmd_deque(void *data, uint32_t status, + uint64_t rvid, uint64_t inf_id, uint64_t enter_complt, + uint64_t pb_put_time, uint64_t cmdbuf_out_time, + uint64_t handle_cmd_result_time, + uint64_t load_aware_pwroff_time, + uint64_t enter_mpriv_release_time, + uint64_t mpriv_release_time, + uint64_t sc_rets, + uint64_t c_ret) + +{ + struct mdw_rv_tag t; + + if (!mdw_rv_tags) + return; + + t.type = MDW_TAG_CMD_DEQUE; + t.d.deqcmd.status = status; + t.d.deqcmd.rvid = rvid; + t.d.deqcmd.inf_id = inf_id; + t.d.deqcmd.enter_complt= enter_complt; + t.d.deqcmd.pb_put_time = pb_put_time; + t.d.deqcmd.cmdbuf_out_time = cmdbuf_out_time; + t.d.deqcmd.handle_cmd_result_time = handle_cmd_result_time; + t.d.deqcmd.load_aware_pwroff_time = load_aware_pwroff_time; + t.d.deqcmd.enter_mpriv_release_time = enter_mpriv_release_time; + t.d.deqcmd.mpriv_release_time = mpriv_release_time; + t.d.deqcmd.sc_rets = sc_rets; + t.d.deqcmd.c_ret = c_ret; + + apu_tag_add(mdw_rv_tags, &t); +} + +static void mdw_rv_tag_enq_printf(struct seq_file *s, struct mdw_rv_tag *t) +{ + char status[8] = ""; + + if (snprintf(status, sizeof(status)-1, "%s", "enque") < 0) + return; + + seq_printf(s, "%s,", status); + seq_printf(s, "pid=%d,inf_id=0x%llx,tgid=%llu,rvid=0x%llx,", + t->d.cmd.pid, t->d.cmd.param3, t->d.cmd.param1, t->d.cmd.rvid); + seq_printf(s, "num_subcmds=%llu,", t->d.cmd.param4); + seq_printf(s, "priority=%llu,softlimit=%u,", + t->d.cmd.param5, t->d.cmd.softlimit); + seq_printf(s, "pwr_dtime=%u,", t->d.cmd.pwr_dtime); + seq_printf(s, "pwr_etime=%llu,", t->d.cmd.param2); + seq_printf(s, "pwr_plcy=0x%x,tolerance=0x%x\n", + t->d.cmd.pwr_plcy, t->d.cmd.tolerance); + +} + +static void mdw_rv_tag_start_printf(struct seq_file *s, struct mdw_rv_tag *t) +{ + char status[8] = ""; + + if (snprintf(status, sizeof(status)-1, "%s", "start") < 0) + return; + + seq_printf(s, "%s,", status); + seq_printf(s, "pid=%d,inf_id=0x%llx,uid=0x%llx,rvid=0x%llx,", + t->d.cmd.pid, t->d.cmd.param2, t->d.cmd.param1, t->d.cmd.rvid); + seq_printf(s, "start_ts=0x%llx\n", t->d.cmd.param3); + +} + +static void mdw_rv_tag_done_printf(struct seq_file *s, struct mdw_rv_tag *t) +{ + char status[8] = ""; + + if (snprintf(status, sizeof(status)-1, "%s", "done") < 0) + return; + + seq_printf(s, "%s,", status); + seq_printf(s, "pid=%d,inf_id=0x%llx,rvid=0x%llx,", + t->d.cmd.pid, t->d.cmd.param2, t->d.cmd.rvid); + seq_printf(s, "enter_rv_cb=%llu,", t->d.cmd.param3); + seq_printf(s, "rv_cb=%llu\n", t->d.cmd.param1); +} + +static void mdw_rv_tag_seq_cmd(struct seq_file *s, struct mdw_rv_tag *t) +{ + if (t->d.cmd.status == MDW_CMD_DONE) { + mdw_rv_tag_done_printf(s, t); + return; + } else if (t->d.cmd.status == MDW_CMD_START) { + mdw_rv_tag_start_printf(s, t); + return; + } else if (t->d.cmd.status == MDW_CMD_ENQUE) { + mdw_rv_tag_enq_printf(s, t); + return; + } +} + +static void mdw_rv_tag_seq_subcmd(struct seq_file *s, struct mdw_rv_tag *t) +{ + char status[8] = ""; + char sc_idx[8] = ""; + + if (snprintf(status, sizeof(status)-1, "%s", "sched") < 0) + return; + + if (snprintf(sc_idx, sizeof(sc_idx)-1, "sc#%d:", t->d.subcmd.sc_idx) < 0) + return; + + seq_printf(s, "%s,", status); + seq_printf(s, "inf_id=0x%llx,rvid=0x%llx,%s", + t->d.subcmd.inf_id, t->d.subcmd.rvid, sc_idx); + seq_printf(s, "type=%u,vsid=0x%llx,ipstart_ts=0x%x,ipend_ts=0x%x,", + t->d.subcmd.sc_type , t->d.subcmd.vsid, t->d.subcmd.ipstart_ts, + t->d.subcmd.ipend_ts); + seq_printf(s, "was_preempted=0x%x,exc_core_bmp=0x%x,", + t->d.subcmd.was_preempted, + t->d.subcmd.executed_core_bmp); + seq_printf(s, "tcm_usage=0x%x,h_iptime=%u,sync_info=0x%llx\n", + t->d.subcmd.tcm_usage, t->d.subcmd.history_iptime, t->d.subcmd.sync_info); +} + +static void mdw_rv_tag_seq_cmd_deque(struct seq_file *s, struct mdw_rv_tag *t) +{ + char status[8] = ""; + + if (snprintf(status, sizeof(status)-1, "%s", "deque") < 0) + return; + + seq_printf(s, "%s,", status); + seq_printf(s, "inf_id=0x%llx,", t->d.deqcmd.inf_id); + seq_printf(s, "rvid=0x%llx,", t->d.deqcmd.rvid); + seq_printf(s, "enter_complt=%llu,", t->d.deqcmd.enter_complt); + seq_printf(s, "pb_put=%llu,", t->d.deqcmd.pb_put_time); + seq_printf(s, "cb_out=%llu,", t->d.deqcmd.cmdbuf_out_time); + seq_printf(s, "hnd_cmd=%llu,", t->d.deqcmd.handle_cmd_result_time); + seq_printf(s, "las_pwroff=%llu,", t->d.deqcmd.load_aware_pwroff_time); + seq_printf(s, "enter_mpriv_release=%llu,", t->d.deqcmd.enter_mpriv_release_time); + seq_printf(s, "mpriv_release=%llu,", t->d.deqcmd.mpriv_release_time); + seq_printf(s, "sc_rets=0x%llx,", t->d.deqcmd.sc_rets); + seq_printf(s, "c_ret=0x%llx\n", t->d.deqcmd.c_ret); +} + +static int mdw_rv_tag_seq(struct seq_file *s, void *tag, void *priv) +{ + struct mdw_rv_tag *t = (struct mdw_rv_tag *)tag; + + if (!t) + return -ENOENT; + + if (t->type == MDW_TAG_CMD) + mdw_rv_tag_seq_cmd(s, t); + else if (t->type == MDW_TAG_SUBCMD) + mdw_rv_tag_seq_subcmd(s, t); + else if (t->type == MDW_TAG_CMD_DEQUE) + mdw_rv_tag_seq_cmd_deque(s, t); + + return 0; +} + +static int mdw_rv_tag_seq_info(struct seq_file *s, void *tag, void *priv) +{ + return 0; +} + +static struct apu_tp_tbl mdw_rv_tp_tbl[] = { + {.name = "mdw_rv_cmd", .func = probe_rv_mdw_cmd}, + {.name = "mdw_rv_subcmd", .func = probe_rv_mdw_subcmd}, + {.name = "mdw_rv_cmd_deque", .func = probe_rv_mdw_cmd_deque}, + APU_TP_TBL_END +}; + +void mdw_rv_tag_show(struct seq_file *s) +{ + apu_tags_seq(mdw_rv_tags, s); +} + +int mdw_rv_tag_init(void) +{ + int ret; + + mdw_rv_tags = apu_tags_alloc("mdw", sizeof(struct mdw_rv_tag), + MDW_TAGS_CNT, mdw_rv_tag_seq, mdw_rv_tag_seq_info, NULL); + + if (!mdw_rv_tags) + return -ENOMEM; + + ret = apu_tp_init(mdw_rv_tp_tbl); + if (ret) + pr_info("%s: unable to register\n", __func__); + + return ret; +} + +void mdw_rv_tag_deinit(void) +{ + apu_tp_exit(mdw_rv_tp_tbl); + apu_tags_free(mdw_rv_tags); +} + +#else +int mdw_rv_tag_init(void) +{ + return 0; +} + +void mdw_rv_tag_deinit(void) +{ +} +void mdw_rv_tag_show(struct seq_file *s) +{ +} +void mdw_cmd_trace(struct mdw_cmd *c, uint32_t status) +{ +} +void mdw_subcmd_trace(struct mdw_cmd *c, uint32_t sc_idx, uint64_t vsid, + uint32_t history_iptime, uint64_t sync_info, uint32_t status) +{ +} +void mdw_cmd_deque_trace(struct mdw_cmd *c, uint32_t status) +{ +} +#endif diff --git a/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.h b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.h new file mode 100644 index 0000000000000..f07e2d06bfff1 --- /dev/null +++ b/drivers/soc/mediatek/apusys/midware/2.0/rv/mdw_rv_tag.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MTK_APU_MDW_APTAG_H__ +#define __MTK_APU_MDW_APTAG_H__ + +#include "mdw_rv.h" +#define MDW_TAGS_CNT (6000) + +enum mdw_cmd_status { + MDW_CMD_ENQUE, + MDW_CMD_START, + MDW_CMD_DONE, + MDW_CMD_SCHED, + MDW_CMD_DEQUE, +}; + +struct mdw_rv_tag { + int type; + + union mdw_tag_data { + struct mdw_tag_cmd { + uint32_t status; + pid_t pid; + uint64_t param1; + uint64_t rvid; + uint64_t param4; + uint64_t param5; + uint32_t softlimit; + uint32_t pwr_dtime; + uint64_t param2; + uint32_t pwr_plcy; + uint32_t tolerance; + uint64_t param3; + } cmd; + struct mdw_tag_subcmd { + uint32_t status; + uint64_t rvid; + uint64_t inf_id; + uint32_t sc_idx; + uint32_t sc_type; + uint64_t vsid; + uint32_t ipstart_ts; + uint32_t ipend_ts; + uint32_t was_preempted; + uint32_t executed_core_bmp; + uint32_t tcm_usage; + uint32_t history_iptime; + uint64_t sync_info; + } subcmd; + struct mdw_tag_deque_cmd { + uint32_t status; + uint64_t rvid; + uint64_t inf_id; + uint64_t enter_complt; + uint64_t pb_put_time; + uint64_t cmdbuf_out_time; + uint64_t handle_cmd_result_time; + uint64_t load_aware_pwroff_time; + uint64_t enter_mpriv_release_time; + uint64_t mpriv_release_time; + uint64_t sc_rets; + uint64_t c_ret; + } deqcmd; + } d; +}; + +int mdw_rv_tag_init(void); +void mdw_rv_tag_deinit(void); +void mdw_rv_tag_show(struct seq_file *s); +void mdw_cmd_trace(struct mdw_cmd *c, uint32_t status); +void mdw_subcmd_trace(struct mdw_cmd *c, uint32_t sc_idx, uint64_t vsid, + uint32_t history_iptime, uint64_t sync_info, uint32_t status); +void mdw_cmd_deque_trace(struct mdw_cmd *c, uint32_t status); + +#endif diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_config.c b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_config.c new file mode 100644 index 0000000000000..1acae8cb10f97 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_config.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include + +#include "linux/remoteproc/mtk_apu.h" +#include "linux/remoteproc/mtk_apu_config.h" + +#include "mvpu_plat.h" +#include "linux/soc/mediatek/apu_mvpu_config.h" + +#define PLAT_POLL_TIMEOUT (1000*100) // 1000 ms +#define PLAT_POLL_PERIOD (10) // 10 us + +int mvpu_config_init(struct mtk_apu *apu) +{ + uint32_t id, level = 0; + uint32_t *addr0, *addr1; + dma_addr_t mvpu_da_l1; + dma_addr_t mvpu_da_itcm; + struct mtk_apu_mvpu_preempt_data *info; + struct mvpu_preempt_buffer *preempt_buffer; + uint32_t nr_core_ids; + uint32_t sw_preemption_level; + + while (g_mvpu_platdata == NULL) + for (int i=0; ipreempt_buffer; + nr_core_ids = g_mvpu_platdata->core_num; + sw_preemption_level = g_mvpu_platdata->sw_preemption_level; + + pr_info("%s core number = %d, sw_preemption_level = 0x%x\n", __func__, + nr_core_ids, sw_preemption_level); + + info = (struct mtk_apu_mvpu_preempt_data *) get_mtk_apu_config_user_ptr( + apu->conf_buf, eMVPU_PREEMPT_DATA); + + for (id = 0; id < nr_core_ids; id++) { + + for (level = 0; level < sw_preemption_level; level++) { + if (id == 0) { + addr0 = dma_alloc_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + &mvpu_da_itcm, GFP_KERNEL); + preempt_buffer->itcm_kernel_addr_core_0[level] = addr0; + + info->itcm_buffer_core_0[level] = (uint32_t) mvpu_da_itcm; + + if (addr0 == NULL || mvpu_da_itcm == 0) { + pr_info("%s: dma_alloc_coherent fail\n", __func__); + return -ENOMEM; + } + + pr_info("core 0 itcm kernel va = 0x%lx, core 0 itcm iova = %pad\n", + (unsigned long)addr0, &mvpu_da_itcm); + + memset(addr0, 0, PREEMPT_ITCM_BUFFER); + + addr1 = dma_alloc_coherent(apu->dev, PREEMPT_L1_BUFFER, + &mvpu_da_l1, GFP_KERNEL); + preempt_buffer->l1_kernel_addr_core_0[level] = addr1; + info->l1_buffer_core_0[level] = mvpu_da_l1; + + if (addr1 == NULL || mvpu_da_l1 == 0) { + pr_info("dma_alloc_coherent fail\n"); + + dma_free_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + addr0, mvpu_da_itcm); + + return -ENOMEM; + } + + pr_info("core 0 L1 kernel va = 0x%lx, core 0 L1 iova = %pad\n", + (unsigned long)addr1, &mvpu_da_l1); + + memset(addr1, 0, PREEMPT_L1_BUFFER); + + } else if (id == 1) { + + addr0 = dma_alloc_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + &mvpu_da_itcm, GFP_KERNEL); + preempt_buffer->itcm_kernel_addr_core_1[level] = addr0; + + info->itcm_buffer_core_1[level] = (uint32_t) mvpu_da_itcm; + + if (addr0 == NULL || mvpu_da_itcm == 0) { + pr_info("dma_alloc_coherent fail\n"); + return -ENOMEM; + } + + pr_info("addr0 = 0x%lx, mvpu_da_itcm = %pad\n", + (unsigned long)addr0, &mvpu_da_itcm); + + memset(addr0, 0, PREEMPT_ITCM_BUFFER); + + addr1 = dma_alloc_coherent(apu->dev, PREEMPT_L1_BUFFER, + &mvpu_da_l1, GFP_KERNEL); + + preempt_buffer->l1_kernel_addr_core_1[level] = addr1; + info->l1_buffer_core_1[level] = mvpu_da_l1; + + if (addr1 == NULL || mvpu_da_l1 == 0) { + pr_info("dma_alloc_coherent fail\n"); + dma_free_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + addr0, mvpu_da_itcm); + return -ENOMEM; + } + + pr_info("addr0 = 0x%lx, mvpu_da_itcm = %pad\n", + (unsigned long)addr1, &mvpu_da_l1); + + memset(addr1, 0, PREEMPT_L1_BUFFER); + + } else { + pr_info("nr_core_ids error\n"); + } + } + } + return 0; +} +EXPORT_SYMBOL_NS(mvpu_config_init, MTK_APU_MVPU); + +int mvpu_config_remove(struct mtk_apu *apu) +{ + int id, level = 0; + struct mtk_apu_mvpu_preempt_data *info; + struct mvpu_preempt_buffer *preempt_buffer = &g_mvpu_platdata->preempt_buffer; + uint32_t nr_core_ids = g_mvpu_platdata->core_num; + uint32_t sw_preemption_level = g_mvpu_platdata->sw_preemption_level; + + info = (struct mtk_apu_mvpu_preempt_data *) get_mtk_apu_config_user_ptr( + apu->conf_buf, eMVPU_PREEMPT_DATA); + + for (id = 0; id < nr_core_ids; id++) { + for (level = 0; level < sw_preemption_level; level++) { + + if (id == 0) { + + if (!preempt_buffer->l1_kernel_addr_core_0[level] || + !info->l1_buffer_core_0[level]) { + dma_free_coherent(apu->dev, PREEMPT_L1_BUFFER, + preempt_buffer->l1_kernel_addr_core_0[level], + info->l1_buffer_core_0[level]); + } + + if (!preempt_buffer->itcm_kernel_addr_core_0[level] || + !info->itcm_buffer_core_0[level]) { + dma_free_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + preempt_buffer->itcm_kernel_addr_core_0[level], + info->itcm_buffer_core_0[level]); + } + + } else { + if (!preempt_buffer->l1_kernel_addr_core_1[level] || + !info->l1_buffer_core_1[level]) { + dma_free_coherent(apu->dev, PREEMPT_L1_BUFFER, + preempt_buffer->l1_kernel_addr_core_1[level], + info->l1_buffer_core_1[level]); + } + + if (!preempt_buffer->itcm_kernel_addr_core_1[level] || + !info->itcm_buffer_core_1[level]) { + dma_free_coherent(apu->dev, PREEMPT_ITCM_BUFFER, + preempt_buffer->itcm_kernel_addr_core_1[level], + info->itcm_buffer_core_1[level]); + } + } + + } + } + return 0; +} +EXPORT_SYMBOL_NS(mvpu_config_remove, MTK_APU_MVPU); diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.c b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.c new file mode 100644 index 0000000000000..a6726237249c0 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" +#include "linux/remoteproc/mtk_apu_config.h" + +#include "mvpu_plat.h" +#include "mvpu_sysfs.h" +#include "mvpu_driver.h" + +static struct apusys_device mvpu_apusys_dev; + +static int mvpu_dma_init(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + uint64_t mask = g_mvpu_platdata->dma_mask; + + ret = dma_set_mask_and_coherent(dev, mask); + if (ret) { + dev_info(dev, "%s: unable to set DMA mask coherent: %d\n", __func__, ret); + return ret; + } + + dev_info(dev, "%s: dma_set_mask_and_coherent 0x%llx\n", __func__, mask); + + ret = dma_set_mask(dev, mask); + if (ret) { + dev_info(dev, "%s: unable to set DMA mask: %d\n", __func__, ret); + return ret; + } + + dev_info(dev, "%s: dma_set_mask 0x%llx\n", __func__, mask); + + return ret; +} + +static int mvpu_apusys_register(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + + mvpu_apusys_dev.dev_type = APUSYS_DEVICE_MVPU; + mvpu_apusys_dev.preempt_type = APUSYS_PREEMPT_NONE; + mvpu_apusys_dev.preempt_level = 0; + mvpu_apusys_dev.send_cmd = g_mvpu_platdata->ops->mvpu_handler_lite; + mvpu_apusys_dev.idx = 0; + + ret = apusys_register_device(&mvpu_apusys_dev); + if (ret) + dev_info(dev, "%s: failed to register apusys (%d)\n", __func__, ret); + + return ret; +} + +static int mvpu_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + struct device *dev = &pdev->dev; + + dev_info(dev, "%s +\n", __func__); + return 0; +} + +static int mvpu_resume(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_info(dev, "%s +\n", __func__); + return 0; +} + +static int mvpu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_info(dev, "%s +\n", __func__); + + if (mvpu_platdata_init(pdev)) { + dev_info(dev, "%s: get plat info fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: get plat info pass\n", __func__); + + if (mvpu_apusys_register(pdev)) { + dev_info(dev, "%s: apusys dev register fail, defer probe\n", __func__); + return -EPROBE_DEFER; + } + dev_info(dev, "%s: apusys dev register pass\n", __func__); + + g_mvpu_platdata->ops->mvpu_handler_lite_init(); + + if (mvpu_dma_init(pdev)) { + dev_info(dev, "%s: dma init fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: dma init pass\n", __func__); + + if (g_mvpu_platdata->sw_ver == MVPU_SW_VER_MVPU20 || g_mvpu_platdata->sw_ver == MVPU_SW_VER_MVPU25 || + g_mvpu_platdata->sw_ver == MVPU_SW_VER_MVPU25a) { + if (g_mvpu_platdata->sec_ops->mvpu_sec_init(dev)) { + dev_info(dev, "%s: sec init fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: sec init pass\n", __func__); + + if (g_mvpu_platdata->sec_ops->mvpu_load_img(dev)) { + dev_info(dev, "%s: load img fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: load img pass\n", __func__); + } + + if (mvpu_sysfs_init()) { + dev_info(dev, "%s: sysfs init fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: sysfs init pass\n", __func__); + + if (g_mvpu_platdata->ops->mvpu_ipi_init()) { + dev_info(dev, "%s: ipi init fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: ipi init pass\n", __func__); + + dev_info(dev, "%s probe pass\n", __func__); + return 0; +} + +static int mvpu_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_info(dev, "%s +\n", __func__); + g_mvpu_platdata->ops->mvpu_ipi_deinit(); + mvpu_sysfs_exit(); + + return 0; +} + +static struct platform_driver mvpu_driver = { + .probe = mvpu_probe, + .remove = mvpu_remove, + .suspend = mvpu_suspend, + .resume = mvpu_resume, + .driver = { + .name = "mtk_mvpu", + .owner = THIS_MODULE, + } +}; + +int mvpu_init(void) +{ + pr_info("%s +\n", __func__); + mvpu_driver.driver.of_match_table = mvpu_plat_get_device(); + + if (platform_driver_register(&mvpu_driver) != 0) { + pr_info("%s: register platform driver fail\n", __func__); + return -ENODEV; + } + pr_info("%s: register platform driver pass\n", __func__); + + return 0; +} + +void mvpu_exit(void) +{ + platform_driver_unregister(&mvpu_driver); +} + +MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS(MTK_APU_MDW); + +module_init(mvpu_init); +module_exit(mvpu_exit); +MODULE_DESCRIPTION("APU MVPU Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.h b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.h new file mode 100644 index 0000000000000..e350c0ecef020 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_driver.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __MVPU_DRIVER_H__ +#define __MVPU_DRIVER_H__ + +int mvpu_init(void); +void mvpu_exit(void); + +#endif /* __MVPU_DRIVER_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.c b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.c new file mode 100644 index 0000000000000..b68ad853a78ce --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include + +#include "mvpu_plat.h" + +struct mvpu_platdata *g_mvpu_platdata; + +int mvpu_drv_loglv; + +static const struct of_device_id mvpu_of_match[] = { + { + .compatible = "mediatek, mt8196-mvpu", + .data = &mvpu_mt8196_platdata + }, + { + /* end of list */ + }, +}; + +const struct of_device_id *mvpu_plat_get_device(void) +{ + return mvpu_of_match; +} + +int mvpu_platdata_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mvpu_platdata *platdata; + unsigned int dts_ver; + + if (g_mvpu_platdata != NULL) { + dev_info(dev, "%s: already init, by pass\n", __func__); + return 0; + } + + platdata = (struct mvpu_platdata *)of_device_get_match_data(dev); + + if (!platdata) { + dev_info(dev, "%s: get of_device_get_match_data fail\n", __func__); + return -EINVAL; + } + + dev_info(dev, "%s: platdata_sw_ver = %d\n", __func__, platdata->sw_ver); + dev_info(dev, "%s: sw_preemption_level = %d\n", + __func__, platdata->sw_preemption_level); + + if (of_property_read_u32(dev->of_node, "version", &dts_ver) == 0) + dev_info(dev, "%s: dts_ver = %d\n", __func__, dts_ver); + + if (!of_property_read_u32(dev->of_node, "core_num", &platdata->core_num)) { + } else if (!of_property_read_u32(dev->of_node, "core-num", &platdata->core_num)) { + } else { + dev_info(dev, "%s: get core num fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: core-num = %d\n", __func__, platdata->core_num); + + if (platdata->core_num > MAX_CORE_NUM) { + dev_info(dev, "%s: invalid core number: %d\n", __func__, platdata->core_num); + return -EINVAL; + } + + if (of_property_read_u64(dev->of_node, "mask", &platdata->dma_mask)) { + dev_info(dev, "%s: get mask fail\n", __func__); + return -EINVAL; + } + dev_info(dev, "%s: mask = 0x%llx\n", __func__, platdata->dma_mask); + + platdata->pdev = pdev; + g_mvpu_platdata = platdata; + + return 0; +} diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.h b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.h new file mode 100644 index 0000000000000..3bfb72a99e1a7 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_plat.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MVPU_PLAT_API_H__ +#define __MVPU_PLAT_API_H__ + +#include +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" + +#define MAX_CORE_NUM 2 +#define PREEMPT_L1_BUFFER (512 * 1024) +#define PREEMPT_ITCM_BUFFER (128 * 1024) + +enum MVPU_IPI_TYPE { + /* set uP log level */ + MVPU_IPI_LOG_LEVEL, + /* uP exception msg */ + MVPU_IPI_MICROP_MSG +}; + +enum MVPU_IPI_DIR_TYPE { + MVPU_IPI_READ, + MVPU_IPI_WRITE, +}; + +enum MVPU_SW_VERSION { + MVPU_SW_VER_MVPU20 = 0, + MVPU_SW_VER_MVPU25, + MVPU_SW_VER_MVPU25a, + MVPU_SW_VER_MVPU3, +}; + +struct mvpu_sec_ops { + int (*mvpu_sec_init)(struct device *dev); + int (*mvpu_load_img)(struct device *dev); + int (*mvpu_sec_sysfs_init)(struct kobject *root_dir); +}; + + +struct mvpu_ops { + int (*mvpu_ipi_init)(void); + void (*mvpu_ipi_deinit)(void); + int (*mvpu_ipi_send)(uint32_t type, uint32_t dir, uint64_t *val); + void (*mvpu_handler_lite_init)(void); + int (*mvpu_handler_lite)(int type, void *hnd, struct apusys_device *dev); +}; + +struct mvpu_preempt_buffer { + uint32_t *itcm_kernel_addr_core_0[5]; + uint32_t *l1_kernel_addr_core_0[5]; + uint32_t *itcm_kernel_addr_core_1[5]; + uint32_t *l1_kernel_addr_core_1[5]; +}; + +struct mvpu_platdata { + struct platform_device *pdev; + const struct mvpu_ops *ops; + const struct mvpu_sec_ops *sec_ops; + enum MVPU_SW_VERSION sw_ver; + struct mvpu_preempt_buffer preempt_buffer; + uint32_t core_num; + uint32_t sw_preemption_level; + uint64_t dma_mask; +}; + +int mvpu_platdata_init(struct platform_device *pdev); +const struct of_device_id *mvpu_plat_get_device(void); + +extern struct mvpu_platdata mvpu_mt8196_platdata; + +extern struct mvpu_platdata *g_mvpu_platdata; +extern int mvpu_drv_loglv; + +#endif /* __MVPU_PLAT_API_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.c b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.c new file mode 100644 index 0000000000000..1ea38e46a26bd --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include + +#include "mvpu_plat.h" +#include "mvpu_sysfs.h" + +static struct kobject *root_dir; + +static ssize_t loglevel_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + uint64_t level = 0; + int ret = 0; + + g_mvpu_platdata->ops->mvpu_ipi_send(MVPU_IPI_LOG_LEVEL, MVPU_IPI_READ, &level); + + pr_info("[MVPU] %s, level= %llu\n", __func__, level); + ret = sprintf(buf, "mvpu log level= %llu\n", level); + + if (ret < 0) { + pr_info("[MVPU] %s, sprintf fail(%d)\n", __func__, ret); + return 0; + } + + return ret; +} + +static ssize_t loglevel_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *cmd, size_t count) +{ + uint64_t ret = 0; + uint64_t level = 0; + + ret = kstrtoull(cmd, 16, &level); + + if (!ret) { + pr_info("[MVPU] %s, level= %llu\n", __func__, level); + + g_mvpu_platdata->ops->mvpu_ipi_send(MVPU_IPI_LOG_LEVEL, MVPU_IPI_WRITE, &level); + + mvpu_drv_loglv = level; + } else { + pr_info("[MVPU] %s[%d]: get invalid cmd\n", __func__, __LINE__); + } + return count; + +} + +static struct kobj_attribute loglevel = { + .attr = { + .name = "loglevel", + .mode = 0644, + }, + .show = loglevel_show, + .store = loglevel_store, +}; + +int mvpu_sysfs_init(void) +{ + int ret = 0; + + pr_info("%s +\n", __func__); + + mvpu_drv_loglv = 0; + + /* create /sys/kernel/mvpu */ + root_dir = kobject_create_and_add("mvpu", kernel_kobj); + if (!root_dir) { + pr_info("%s kobject_create_and_add fail\n", __func__); + return -EINVAL; + } + + if (sysfs_create_file(root_dir, &loglevel.attr)) { + pr_info("%s sysfs_create_file fail\n", __func__); + return -EINVAL; + } + + ret = g_mvpu_platdata->sec_ops->mvpu_sec_sysfs_init(root_dir); + + return ret; +} + +void mvpu_sysfs_exit(void) +{ + kobject_del(root_dir); +} diff --git a/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.h b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.h new file mode 100644 index 0000000000000..956e3a4b26613 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/common/mvpu_sysfs.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MVPU_SYSFS_H__ +#define __MVPU_SYSFS_H__ + +int mvpu_sysfs_init(void); +void mvpu_sysfs_exit(void); + +#endif /* __MVPU_SYSFS_H__ */ + diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.c b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.c new file mode 100644 index 0000000000000..8eaa2e7b500ff --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#include +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" + +#include "mvpu_plat.h" +#include "mvpu25_handler.h" +#include "mvpu25_valid.h" +#include "mvpu25_sec.h" + +struct mutex mvpu25_pool_lock; + +void mvpu25_handler_lite_init(void) +{ + mutex_init(&mvpu25_pool_lock); +} + + +int mvpu25_handler_lite(int type, void *hnd, struct apusys_device *dev) +{ + int ret = 0; + + if (!dev) + return -1; + + if (!hnd) { + pr_info("%s get hnd fail\n", __func__); + return -1; + } + + if (dev->dev_type != APUSYS_DEVICE_MVPU) { + pr_info("%s get wrong dev_type: %d\n", __func__, dev->dev_type); + return -1; + } + + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] APU CMD type %d\n", type); + + switch (type) { + case APUSYS_CMD_VALIDATE: + ret = mvpu25_validation(hnd); + break; + case APUSYS_CMD_SESSION_CREATE: + mvpu25_set_sec_log_lvl(mvpu_drv_loglv); + ret = 0; + break; + case APUSYS_CMD_SESSION_DELETE: + if (hnd == NULL) { + pr_info("[MVPU][Sec] APUSYS_CMD_SESSION_DELETE error: hnd is NULL\n"); + ret = -1; + } else { + mutex_lock(&mvpu25_pool_lock); + mvpu25_clear_session(hnd); + mutex_unlock(&mvpu25_pool_lock); + ret = 0; + } + break; + default: + pr_info("%s get wrong cmd type: %d\n", __func__, type); + ret = -1; + break; + } + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.h new file mode 100644 index 0000000000000..0403ae21838b7 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_handler.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __MVPU25_HANDLER_H__ +#define __MVPU25_HANDLER_H__ + +#include +#include +#include "linux/soc/mediatek/mtk_apu_device.h" + +extern struct mutex mvpu25_pool_lock; + +void mvpu25_handler_lite_init(void); +int mvpu25_handler_lite(int type, void *hnd, struct apusys_device *dev); + +#endif /* __MVPU25_HANDLER_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.c b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.c new file mode 100644 index 0000000000000..cd8c79a0a5abd --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mvpu_driver.h" +#include "mvpu25_request.h" +#include "mvpu_plat.h" +#include "mvpu25_ipi.h" + +/* + * type0: Distinguish pwr_time, timeout, klog, or CX + * type1: prepare to C1~C16 + * dir : Distinguish read or write + * data : store data + */ + +struct mvpu_ipi_data { + u32 type0; + u16 dir; + u64 data; + + u32 error_code; + char algo_name[MVPU_REQUEST_NAME_SIZE]; + uint64_t mpu_addr; + uint32_t mpu_setting[MVPU_MPU_SEGMENT_NUMS]; +}; +static struct mvpu_ipi_data ipi_tx_recv_buf; +static struct mvpu_ipi_data ipi_rx_send_buf; +static struct mutex mvpu_ipi_mtx; + +struct mvpu_rpmsg_device { + struct rpmsg_endpoint *ept; + struct rpmsg_device *rpdev; + struct completion ack; +}; + +static struct mvpu_rpmsg_device mvpu_tx_rpm_dev; +static struct mvpu_rpmsg_device mvpu_rx_rpm_dev; + +int mvpu25_ipi_send(uint32_t type, uint32_t dir, uint64_t *val) +{ + struct mvpu_ipi_data ipi_data; + int ret = 0, rpms_ret = 0; + + if (!mvpu_tx_rpm_dev.ept) + return -1; + + ipi_data.type0 = type; + ipi_data.dir = dir; + ipi_data.data = *val; + + mutex_lock(&mvpu_ipi_mtx); + + rpms_ret = rpmsg_send(mvpu_tx_rpm_dev.ept, &ipi_data, sizeof(ipi_data)); + if (rpms_ret) { + pr_info("%s: rpmsg_send fail(%d)\n", __func__, rpms_ret); + ret = rpms_ret; + + goto out; + } + + ret = wait_for_completion_interruptible_timeout( + &mvpu_tx_rpm_dev.ack, msecs_to_jiffies(1000)); + + *val = ipi_tx_recv_buf.data; + + if (ret == 0) { + pr_info("%s: timeout\n", __func__); + ret = -1; + } else { + ret = 0; + } + +out: + mutex_unlock(&mvpu_ipi_mtx); + return ret; +} + +static int mvpu25_rpmsg_tx_cb(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct mvpu_ipi_data *d = (struct mvpu_ipi_data *)data; + + ipi_tx_recv_buf.type0= d->type0; + ipi_tx_recv_buf.dir= d->dir; + ipi_tx_recv_buf.data= d->data; + + /* wait_for_completion_interruptible_timeout */ + complete(&mvpu_tx_rpm_dev.ack); + + return 0; +} + +static int mvpu25_rpmsg_rx_cb(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct mvpu_ipi_data *d = (struct mvpu_ipi_data *)data; + + if (d->type0 == MVPU_IPI_MICROP_MSG) { + + ipi_rx_send_buf.type0 = d->type0; + ipi_rx_send_buf.dir = d->dir; + ipi_rx_send_buf.data = d->data; + + rpmsg_send(mvpu_rx_rpm_dev.ept, &ipi_rx_send_buf, sizeof(ipi_rx_send_buf)); + + mvpu_aee_exception("MVPU", "MVPU aee"); + } else { + pr_info("Receive command ack -> use the wrong channel!?\n"); + } + + return 0; +} + +static int mvpu25a_rpmsg_rx_cb(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 src) +{ + struct mvpu_ipi_data *d = (struct mvpu_ipi_data *)data; + + if (d->type0 == MVPU_IPI_MICROP_MSG) { + + ipi_rx_send_buf.type0 = d->type0; + ipi_rx_send_buf.dir = d->dir; + ipi_rx_send_buf.data = d->data; + + ipi_rx_send_buf.error_code = d->error_code; + strscpy(ipi_rx_send_buf.algo_name, d->algo_name, sizeof(d->algo_name)); + if (d->error_code == 94) { + pr_info("[MVPU] [ERROR] mpu addr 0x%llx\n", d->mpu_addr); + for (unsigned int idx = 38; idx >= 1; idx = idx-2) + pr_info("[MVPU] [ERROR] mpu_setting [%02d~%02d] 0x%08x~0x%08x\n", + idx-1, idx, d->mpu_setting[idx-1], d->mpu_setting[idx]); + } + rpmsg_send(mvpu_rx_rpm_dev.ept, &ipi_rx_send_buf, sizeof(ipi_rx_send_buf)); + + pr_info("[MVPU] [ERROR] error_code(%d), algo_name: %s\n", + ipi_rx_send_buf.error_code, ipi_rx_send_buf.algo_name); + mvpu_aee_exception("MVPU", "MVPU aee"); + } else { + pr_info("Receive command ack -> use the wrong channel!?\n"); + } + + return 0; +} + +static int mvpu_rpmsg_tx_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + + dev_info(dev, "%s: name=%s, src=%d\n", + __func__, rpdev->id.name, rpdev->src); + + mvpu_tx_rpm_dev.ept = rpdev->ept; + mvpu_tx_rpm_dev.rpdev = rpdev; + + return 0; +} + +static int mvpu_rpmsg_rx_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + + dev_info(dev, "%s: name=%s, src=%d\n", + __func__, rpdev->id.name, rpdev->src); + + mvpu_rx_rpm_dev.ept = rpdev->ept; + mvpu_rx_rpm_dev.rpdev = rpdev; + + return 0; +} + +static void mvpu_rpmsg_remove(struct rpmsg_device *rpdev) +{ +} + + +static const struct of_device_id mvpu_tx_rpmsg_of_match[] = { + { .compatible = "mediatek,mvpu-tx-rpmsg" }, + {}, +}; + +static const struct of_device_id mvpu_rx_rpmsg_of_match[] = { + { .compatible = "mediatek,mvpu-rx-rpmsg" }, + {}, +}; + +static struct rpmsg_driver mvpu25_rpmsg_tx_drv = { + .drv = { + .name = "mvpu-tx-rpmsg", + .owner = THIS_MODULE, + .of_match_table = mvpu_tx_rpmsg_of_match, + }, + .probe = mvpu_rpmsg_tx_probe, + .callback = mvpu25_rpmsg_tx_cb, + .remove = mvpu_rpmsg_remove, +}; + +static struct rpmsg_driver mvpu25_rpmsg_rx_drv = { + .drv = { + .name = "mvpu-rx-rpmsg", + .owner = THIS_MODULE, + .of_match_table = mvpu_rx_rpmsg_of_match, + }, + .probe = mvpu_rpmsg_rx_probe, + .callback = mvpu25_rpmsg_rx_cb, + .remove = mvpu_rpmsg_remove, +}; + +static struct rpmsg_driver mvpu25a_rpmsg_tx_drv = { + .drv = { + .name = "mvpu-tx-rpmsg", + .owner = THIS_MODULE, + .of_match_table = mvpu_tx_rpmsg_of_match, + }, + .probe = mvpu_rpmsg_tx_probe, + .callback = mvpu25_rpmsg_tx_cb, + .remove = mvpu_rpmsg_remove, +}; + +static struct rpmsg_driver mvpu25a_rpmsg_rx_drv = { + .drv = { + .name = "mvpu-rx-rpmsg", + .owner = THIS_MODULE, + .of_match_table = mvpu_rx_rpmsg_of_match, + }, + .probe = mvpu_rpmsg_rx_probe, + .callback = mvpu25a_rpmsg_rx_cb, + .remove = mvpu_rpmsg_remove, +}; + +int mvpu25_ipi_init(void) +{ + int ret; + + pr_info("%s +\n", __func__); + + init_completion(&mvpu_rx_rpm_dev.ack); + init_completion(&mvpu_tx_rpm_dev.ack); + mutex_init(&mvpu_ipi_mtx); + + ret = register_rpmsg_driver(&mvpu25_rpmsg_rx_drv); + if (ret) + pr_info("failed to register mvpu rx rpmsg\n"); + + ret = register_rpmsg_driver(&mvpu25_rpmsg_tx_drv); + if (ret) + pr_info("failed to register mvpu tx rpmsg\n"); + + return 0; +} + +void mvpu25_ipi_deinit(void) +{ + unregister_rpmsg_driver(&mvpu25_rpmsg_tx_drv); + unregister_rpmsg_driver(&mvpu25_rpmsg_rx_drv); + mutex_destroy(&mvpu_ipi_mtx); +} + +int mvpu25a_ipi_init(void) +{ + int ret; + + pr_info("%s +\n", __func__); + + init_completion(&mvpu_rx_rpm_dev.ack); + init_completion(&mvpu_tx_rpm_dev.ack); + mutex_init(&mvpu_ipi_mtx); + + ret = register_rpmsg_driver(&mvpu25a_rpmsg_rx_drv); + if (ret) + pr_info("failed to register mvpu rx rpmsg\n"); + + ret = register_rpmsg_driver(&mvpu25a_rpmsg_tx_drv); + if (ret) + pr_info("failed to register mvpu tx rpmsg\n"); + + return 0; +} + +void mvpu25a_ipi_deinit(void) +{ + unregister_rpmsg_driver(&mvpu25a_rpmsg_tx_drv); + unregister_rpmsg_driver(&mvpu25a_rpmsg_rx_drv); + mutex_destroy(&mvpu_ipi_mtx); +} diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.h new file mode 100644 index 0000000000000..80b565fe63eac --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_ipi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __MVPU25_IPI_H__ +#define __MVPU25_IPI_H__ + +#include + +#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE) +#include +#define mvpu_aee_exception(key, format, args...) \ + do { \ + pr_info(format, ##args); \ + aee_kernel_exception("MVPU", \ + "\nCRDISPATCH_KEY:" key "\n" format, ##args); \ + } while (0) +#else +#define mvpu_aee_exception(key, format, args...) +#endif + +int mvpu25_ipi_init(void); +void mvpu25_ipi_deinit(void); +int mvpu25_ipi_send(uint32_t type, uint32_t dir, uint64_t *val); +int mvpu25a_ipi_init(void); +void mvpu25a_ipi_deinit(void); + +#endif /* __MVPU25_IPI_H__ */ + diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_platdata.c b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_platdata.c new file mode 100644 index 0000000000000..019c1ececddc6 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_platdata.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#include "mvpu_plat.h" +#include "mvpu25_ipi.h" +#include "mvpu25_handler.h" +#include "mvpu25_sec.h" + +struct mvpu_sec_ops mvpu25_sec_ops = { + .mvpu_sec_init = mvpu25_sec_init, + .mvpu_load_img = mvpu25_load_img, + .mvpu_sec_sysfs_init = mvpu25_sec_sysfs_init +}; + +struct mvpu_ops mvpu25_ops = { + .mvpu_ipi_init = mvpu25_ipi_init, + .mvpu_ipi_deinit = mvpu25_ipi_deinit, + .mvpu_ipi_send = mvpu25_ipi_send, + .mvpu_handler_lite_init = mvpu25_handler_lite_init, + .mvpu_handler_lite = mvpu25_handler_lite, +}; + +struct mvpu_ops mvpu25a_ops = { + .mvpu_ipi_init = mvpu25a_ipi_init, + .mvpu_ipi_deinit = mvpu25a_ipi_deinit, + .mvpu_ipi_send = mvpu25_ipi_send, + .mvpu_handler_lite_init = mvpu25_handler_lite_init, + .mvpu_handler_lite = mvpu25_handler_lite, +}; + +struct mvpu_platdata mvpu_mt8196_platdata = { + .sw_preemption_level = 1, + .sw_ver = MVPU_SW_VER_MVPU25a, + .ops = &mvpu25a_ops, + .sec_ops = &mvpu25_sec_ops +}; diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_request.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_request.h new file mode 100644 index 0000000000000..dccbbceb637db --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_request.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MVPU25_REQUEST_H__ +#define __MVPU25_REQUEST_H__ + +#include "mvpu2_cmd_data.h" + +/* MVPU command structure*/ +struct mvpu_request_v25 { + struct BundleHeader header; + uint32_t algo_id; + char name[MVPU_REQUEST_NAME_SIZE]; + + /* driver info, exception etc */ + uint32_t drv_info; + uint32_t drv_ret; + + /* mpu setting */ + uint16_t mpu_num; + uint32_t mpu_seg[MVPU_MPU_SEGMENT_NUMS]; + + /* debug mode */ + /* 0x0 : debugger */ + /* 0x1 : rv break debug */ + /* 0x2 : safe mode for memory in-order */ + uint16_t debug_mode; + /* debugger id when rv debug */ + uint16_t debug_id; + + /* PMU setting */ + uint16_t pmu_mode; + uint16_t pmc_mode; + uint32_t pmu_buff; + uint32_t buff_size; + +#ifdef MVPU_SECURITY + uint32_t batch_name_hash; + + uint32_t buf_num; + uint32_t rp_num; + + uint64_t sec_chk_addr; + uint64_t sec_buf_size; + uint64_t sec_buf_attr; + + uint64_t target_buf_old_base; + uint64_t target_buf_old_offset; + uint64_t target_buf_new_base; + uint64_t target_buf_new_offset; + + uint32_t kerarg_num; + uint64_t kerarg_buf_id; + uint64_t kerarg_offset; + uint64_t kerarg_size; + + uint32_t primem_num; + uint64_t primem_src_buf_id; + uint64_t primem_dst_buf_id; + uint64_t primem_src_offset; + uint64_t primem_dst_offset; + uint64_t primem_size; +#endif + uint32_t sw_version; + uint64_t feature_control_mask; + uint32_t glsu_idx_mode_table; + uint32_t glsu_idx_mode_table_size; +} __packed; + +#endif /* __MVPU25_REQUEST_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.c b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.c new file mode 100644 index 0000000000000..a2c4b3c37f23f --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.c @@ -0,0 +1,2211 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" +#include "linux/remoteproc/mtk_apu_config.h" + +#include "mvpu_plat.h" +#include "mvpu_sysfs.h" +#include "mvpu25_ipi.h" +#include "mvpu25_request.h" +#include "mvpu_driver.h" +#include "mvpu25_sec.h" + +//#define FULL_RP_INFO + +void mvpu25_set_sec_log_lvl(int log_lvl) +{ + mvpu_loglvl_sec = log_lvl; +} + +bool mvpu25_get_mvpu_algo_available(void) +{ + return mvpu_algo_available; +} + +uint32_t mvpu25_get_ptn_total_size(void) +{ + uint32_t ptn_total_size = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return 0; + } + + ptn_total_size = mvpu_algo_img[3]; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][IMG] PTN total size: 0x%08x\n", ptn_total_size); + + return ptn_total_size; +} + +uint32_t mvpu25_get_ptn_size(uint32_t hash) +{ + uint32_t ptn_size = 0; + uint32_t ptn_total_num = 0; + int i = 0; + + uint32_t shift = 0; + uint32_t ptn_hash = 0; + uint32_t ptn_size_offset = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return 0; + } + + ptn_total_num = mvpu_algo_img[KER_NUM_OFFSET]; + + for (i = 0; i < ptn_total_num; i++) { + // get hash by ptn.bin size + shift = IMG_HEADER_SIZE + ptn_size_offset/sizeof(uint32_t) + PTN_INFO_SIZE*i; + ptn_hash = mvpu_algo_img[shift]; + + // check hash + if ((ptn_hash & MVPU_BATCH_MASK) == (hash & MVPU_BATCH_MASK)) { + ptn_size = mvpu_algo_img[shift + KER_SIZE_OFFSET]; + break; + } + + // count ptn.bin size to shift + ptn_size_offset += mvpu_algo_img[shift + PNT_SIZE_OFFSET]; + + // alignment + ptn_size_offset = ptn_size_offset + 4 - (ptn_size_offset % 4); + } + + if ((ptn_hash & MVPU_BATCH_MASK) != (hash & MVPU_BATCH_MASK)) + pr_info("[MVPU][Sec] PTN HASH: 0x%08x not found\n", hash); + + //printf("[SEC_IMG] get PTN HASH: 0x%08x, img addr 0x%08x, + // size: 0x%08x\n", ptn_hash, img_addr, ptn_size); + return ptn_size; +} + +bool mvpu25_get_ptn_hash(uint32_t hash) +{ + uint32_t ptn_total_num = 0; + int i = 0; + + uint32_t shift = 0; + uint32_t ptn_hash = 0; + uint32_t ptn_size_offset = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return false; + } + + ptn_total_num = mvpu_algo_img[KER_NUM_OFFSET]; + + for (i = 0; i < ptn_total_num; i++) { + // get hash by ptn.bin size + shift = IMG_HEADER_SIZE + ptn_size_offset/sizeof(uint32_t) + PTN_INFO_SIZE*i; + ptn_hash = mvpu_algo_img[shift]; + + // check hash + if ((ptn_hash & MVPU_BATCH_MASK) == (hash & MVPU_BATCH_MASK)) + return true; + + // count ptn.bin size to shift + ptn_size_offset += mvpu_algo_img[shift + PNT_SIZE_OFFSET]; + + // alignment + if ((ptn_size_offset % 4) != 0) + ptn_size_offset = ptn_size_offset + 4 - (ptn_size_offset % 4); + } + + + return false; +} + +uint32_t mvpu25_get_kerbin_total_size(void) +{ + uint32_t kerbin_total_size = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return 0; + } + + kerbin_total_size = mvpu_algo_img[ker_img_offset/sizeof(uint32_t) + KER_BIN_SIZE_OFFSET]; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][IMG] KER total size: 0x%08x\n", kerbin_total_size); + + return kerbin_total_size; +} + +uint32_t mvpu25_get_ker_img_offset(void) +{ + uint32_t offset = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return 0; + } + + offset = mvpu_algo_img[3] + 0x10; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] ker_img_offset : 0x%08x\n", offset); + + return offset; +} + +void mvpu25_get_ker_info(uint32_t hash, uint32_t *ker_bin_offset, uint32_t *ker_bin_num) +{ + uint32_t ker_img_total_num = 0; + uint32_t shift = 0; + uint32_t ker_hash = 0; + uint32_t ker_size_offset = 0; + int i = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return; + } + + ker_img_total_num = mvpu_algo_img[ker_img_offset/sizeof(uint32_t) + KER_NUM_OFFSET]; + + if (ker_img_total_num == 0) + pr_info("[MVPU][IMG] [ERROR] not found Kernel_*.bin in mvpu_algo.img, please check\n"); + + for (i = 0; i < ker_img_total_num; i++) { + // get hash by ker.bin size + shift = ker_img_offset/sizeof(uint32_t) + + IMG_HEADER_SIZE + + ker_size_offset/sizeof(uint32_t) + + KER_INFO_SIZE*i; + + ker_hash = mvpu_algo_img[shift]; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][IMG] shift 0x%08x, 0x%08x 0x%08x 0x%08x 0x%08x\n", + shift, + mvpu_algo_img[shift + 0], + mvpu_algo_img[shift + 1], + mvpu_algo_img[shift + 2], + mvpu_algo_img[shift + 3] + ); + } + + // check hash + if ((ker_hash & MVPU_BATCH_MASK) == (hash & MVPU_BATCH_MASK)) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][IMG] Get KNL HASH 0x%08x\n", hash); + + *ker_bin_offset = (shift + KER_INFO_SIZE)*sizeof(uint32_t); + //*ker_size = mvpu_algo_img[shift + KER_SIZE_OFFSET]; + *ker_bin_num = mvpu_algo_img[shift + KER_NUM_OFFSET]; + break; + } + + // count ker.bin size to shift + ker_size_offset += mvpu_algo_img[shift + KER_SIZE_OFFSET]; + + // alignment + //ker_size_offset = ker_size_offset + 4 - (ker_size_offset % 4); + } + +} + +void mvpu25_set_ker_iova(uint32_t ker_bin_offset, uint32_t ker_bin_num, uint32_t *ker_bin_each_iova) +{ + uint32_t shift = 0; + uint32_t ker_size_offset = 0; + int i = 0; + + if (mvpu_algo_available == false) { + pr_info("[MVPU][IMG] %s: mvpu_algo_available is false\n", __func__); + return; + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s, ker_bin_num %d\n", __func__, ker_bin_num); + + for (i = 0; i < ker_bin_num; i++) { + shift = ker_bin_offset/sizeof(uint32_t) + + ker_size_offset/sizeof(uint32_t) + + KER_BIN_INFO_SIZE*i; + + //shift = 4*(ker_size_offset/sizeof(uint32_t) + KER_BIN_INFO_SIZE*i); + ker_bin_each_iova[i] = (shift + KER_BIN_INFO_SIZE)*sizeof(uint32_t) + + mvpu_algo_iova; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][IMG] ker_bin_each_iova[%d] = 0x%08x\n", + i, ker_bin_each_iova[i]); + + ker_size_offset += mvpu_algo_img[shift + KER_SIZE_OFFSET]; + } +} + +void mvpu25_map_base_buf_id(uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_attr, + uint32_t rp_num, + uint32_t *target_old_map, + uint32_t *target_old_base, + uint32_t *target_new_map, + uint32_t *target_new_base, + uint32_t buf_cmd_kreg, + uint32_t buf_cmd_next) +{ + int i = 0, j = 0; + bool mapped_new_buf = false; + bool mapped_old_buf = false; + + for (j = 0; j < rp_num; j++) { + mapped_new_buf = false; + mapped_old_buf = false; + + if (target_new_base[j] == sec_chk_addr[buf_cmd_next]) { + target_new_map[j] = buf_cmd_next; + mapped_new_buf = true; + } else if (target_new_base[j] == 0) { + mapped_new_buf = true; + } + + if (target_old_base[j] == sec_chk_addr[buf_cmd_next]) { + target_old_map[j] = buf_cmd_next; + mapped_old_buf = true; +#ifdef MVPU_SEC_KREG_IN_POOL + } else if (target_old_base[j] == 0) { + target_old_map[j] = buf_cmd_kreg; + mapped_old_buf = true; +#endif + } + + if (mapped_new_buf && mapped_old_buf) + continue; + + for (i = 0; i < buf_num; i++) { + if (mapped_new_buf && mapped_old_buf) + break; + + if (i == buf_cmd_next) + continue; + + if (sec_chk_addr[i] == MVPU_CMD_BUFF_ADDR) + continue; + + if (mapped_new_buf == false) { + if (target_new_base[j] == sec_chk_addr[i]) { + target_new_map[j] = i; + mapped_new_buf = true; + } + } + + if (sec_buf_attr[i] == BUF_KERNEL || + sec_buf_attr[i] == BUF_IO) + continue; + + if (mapped_old_buf == false) { + if (target_old_base[j] == sec_chk_addr[i]) { + target_old_map[j] = i; + mapped_old_buf = true; + } + } + } + } +} + +uint32_t mvpu25_get_saved_session_id(void *session) +{ + uint32_t cnt = 0; + uint32_t session_id = 0xFFFFFFFF; + + for (cnt = 0; cnt < MAX_SAVE_SESSION; cnt++) { + if (saved_session[cnt] == 0xFFFFFFFFFFFFFFFF) + continue; + + //if (memcmp(session, saved_session[cnt], sizeof(uint64_t)) == 0) { + if (saved_session[cnt] == (uint64_t)session) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Get saved_session at %d: 0x%llx\n", + cnt, saved_session[cnt]); + session_id = cnt; + break; + } + } + + return session_id; +} + +uint32_t mvpu25_get_avail_session_id(void) +{ + uint32_t cnt = 0; + uint32_t session_id = 0xFFFFFFFF; + + for (cnt = 0; cnt < MAX_SAVE_SESSION; cnt++) { + if (saved_session[cnt] == 0xFFFFFFFFFFFFFFFF) { + session_id = cnt; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Get available session_id %d\n", + session_id); + break; + } + } + +#ifdef MVPU_SEC_USE_OLDEST_SESSION_ID + // all session place are used, take the oldest + if (session_id == 0xFFFFFFFF) { + session_id = sess_oldest; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Take oldest session_id %d\n", + session_id); + } +#endif + + return session_id; +} + + +void mvpu25_clear_session(void *session) +{ + uint32_t session_id = 0; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + for (session_id = 0; session_id < MAX_SAVE_SESSION; session_id++) { + if (saved_session[session_id] == 0xFFFFFFFFFFFFFFFF) + continue; + + //if (memcmp(session, saved_session[session_id], sizeof(uint64_t)) == 0) { + if (saved_session[session_id] == (uint64_t)session) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] apusys session %llx match saved_session[%d]\n", + (uint64_t)session, + session_id); + } + + mvpu25_free_all_hash(session_id); + //memset(saved_session[session_id], 0xFFFFFFFFFFFFFFFF, sizeof(uint64_t)); + saved_session[session_id] = 0xFFFFFFFFFFFFFFFF; + break; + } + } +} + +void mvpu25_update_session_id(uint32_t session_id, void *session) +{ +#ifdef MVPU_SEC_USE_OLDEST_SESSION_ID + sess_oldest++; + if (sess_oldest == MAX_SAVE_SESSION) + sess_oldest = 0; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] set oldest session_id: %d\n", sess_oldest); +#endif + + if (saved_session[session_id] == 0xFFFFFFFFFFFFFFFF && session != NULL) { + //memcpy(saved_session[session_id], session, sizeof(uint64_t)); + saved_session[session_id] = (uint64_t)session; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] set saved_session[%d]: 0x%llx to apu_session: 0x%llx\n", + session_id, + saved_session[session_id], + (uint64_t)session); + } + } +} + +uint32_t mvpu25_get_saved_hash_id(uint32_t session_id, uint32_t batch_name_hash) +{ + uint32_t cnt = 0; + uint32_t hash_id = 0xFFFFFFFF; + + for (cnt = 0; cnt < MAX_SAVE_HASH; cnt++) { + if (batch_name_hash == hash_pool[session_id]->hash_list[cnt]) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Get saved_hash_list at %d: 0x%08x\n", + cnt, batch_name_hash); + hash_id = cnt; + break; + } + } + + return hash_id; +} + +uint32_t mvpu25_get_avail_hash_id(uint32_t session_id) +{ + uint32_t cnt = 0; + uint32_t hash_id = 0xFFFFFFFF; + + for (cnt = 0; cnt < MAX_SAVE_HASH; cnt++) { + if (hash_pool[session_id]->hash_list[cnt] == 0) { + hash_id = cnt; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Get available hash id %d\n", hash_id); + break; + } + } + +#ifdef MVPU_SEC_USE_OLDEST_HASH_ID + // all hash place are used, take the oldest + if (hash_id == 0xFFFFFFFF) { + hash_id = hash_pool[session_id]->hash_oldest; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Take oldest hash id %d\n", hash_id); + } +#endif + + return hash_id; +} + +void mvpu25_clear_hash(uint32_t session_id, uint32_t hash_id) +{ + // clear old hash settings + if (hash_pool[session_id]->hash_list[hash_id] != 0) { + hash_pool[session_id]->buf_num[hash_id] = 0; + hash_pool[session_id]->rp_num[hash_id] = 0; + hash_pool[session_id]->hash_list[hash_id] = 0; + + dma_buf_unmap_attachment(hash_pool[session_id]->attach[hash_id], + hash_pool[session_id]->sgt[hash_id], + DMA_BIDIRECTIONAL); + + dma_buf_detach(hash_pool[session_id]->hash_dma_buf[hash_id], + hash_pool[session_id]->attach[hash_id]); + + dma_buf_put(hash_pool[session_id]->hash_dma_buf[hash_id]); + + hash_pool[session_id]->hash_base_iova[hash_id] = 0; + hash_pool[session_id]->hash_pool_size[hash_id] = 0; + + kfree(hash_pool[session_id]->sec_chk_addr[hash_id]); + +#ifdef FULL_RP_INFO + kfree(hash_pool[session_id]->target_buf_old_base[hash_id]); + kfree(hash_pool[session_id]->target_buf_old_offset[hash_id]); + kfree(hash_pool[session_id]->target_buf_new_base[hash_id]); + kfree(hash_pool[session_id]->target_buf_new_offset[hash_id]); + kfree(hash_pool[session_id]->target_buf_old_map[hash_id]); + kfree(hash_pool[session_id]->target_buf_new_map[hash_id]); +#endif + + kfree(hash_pool[session_id]->hash_offset[hash_id]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] Clear hash_id[%d] settings\n", + hash_id); + + } else { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] bypass Clear hash_id[%d] settings\n", + hash_id); + } +} + +void mvpu25_free_all_hash(uint32_t session_id) +{ + uint32_t hash_id = 0; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s saved_session[%d]\n", __func__, session_id); + + for (hash_id = 0; hash_id < MAX_SAVE_HASH; hash_id++) { + if (hash_pool[session_id]->hash_list[hash_id] != 0) + mvpu25_clear_hash(session_id, hash_id); + else + break; + } +} + +int mvpu25_update_hash_pool(void *session, + bool algo_in_img, + uint32_t session_id, + uint32_t hash_id, + uint32_t batch_name_hash, + uint32_t buf_num, + void *kreg_kva, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_size, + uint32_t *sec_buf_attr) +{ + uint32_t cnt = 0; + uint32_t buf_size = 0; + uint32_t buf_ofst = 0; + void *p_buf; + void *cp_buff; + void *buf_kva; + bool copy_to_pool = true; + int ret_dma_buf_vmap = 0; + struct iosys_map sys_map = {0}; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + hash_pool[session_id]->buf_num[hash_id] = buf_num; + hash_pool[session_id]->hash_list[hash_id] = batch_name_hash; + +#ifdef MVPU_SEC_USE_OLDEST_HASH_ID + hash_pool[session_id]->hash_oldest++; + if (hash_pool[session_id]->hash_oldest >= MAX_SAVE_HASH) + hash_pool[session_id]->hash_oldest = 0; +#endif + + hash_pool[session_id]->dma_heap[hash_id] = dma_heap_find("system"); + + if (!hash_pool[session_id]->dma_heap[hash_id]) { + pr_info("[MVPU][Sec] heap find fail\n"); + return -1; + } + + // count buf size + for (cnt = 0; cnt < hash_pool[session_id]->buf_num[hash_id]; cnt++) { + if (sec_buf_attr[cnt] != BUF_IO) { + buf_size = sec_buf_size[cnt]; + + // alignment + buf_size = + (((buf_size) + MVPU_ADDR_ALIGN - 1) + /MVPU_ADDR_ALIGN) + *MVPU_ADDR_ALIGN; + hash_pool[session_id]->hash_pool_size[hash_id] += buf_size; + } + } + + // set MPU region size + hash_pool[session_id]->hash_pool_size[hash_id] = + (((hash_pool[session_id]->hash_pool_size[hash_id]) + + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + + hash_pool[session_id]->hash_dma_buf[hash_id] = + dma_heap_buffer_alloc(hash_pool[session_id]->dma_heap[hash_id], + hash_pool[session_id]->hash_pool_size[hash_id], + O_RDWR | O_CLOEXEC, + DMA_HEAP_VALID_HEAP_FLAGS); + + if (IS_ERR(hash_pool[session_id]->hash_dma_buf[hash_id])) { + pr_info("[MVPU][Sec] buffer alloc fail\n"); + return PTR_ERR(hash_pool[session_id]->hash_dma_buf[hash_id]); + } + + if (g_mvpu_platdata->pdev == NULL) { + pr_info("[MVPU][Sec] mvpu_plat_dev is NULL\n"); + return -1; + } + + hash_pool[session_id]->attach[hash_id] = + dma_buf_attach(hash_pool[session_id]->hash_dma_buf[hash_id], + &g_mvpu_platdata->pdev->dev); + + if (IS_ERR(hash_pool[session_id]->attach[hash_id])) { + pr_info("[MVPU][Sec] attach fail, return\n"); + return PTR_ERR(hash_pool[session_id]->attach[hash_id]); + } + + hash_pool[session_id]->sgt[hash_id] = + dma_buf_map_attachment(hash_pool[session_id]->attach[hash_id], + DMA_BIDIRECTIONAL); + + if (IS_ERR(hash_pool[session_id]->sgt[hash_id])) { + pr_info("[MVPU][Sec] map failed, detach and return\n"); + dma_buf_detach(hash_pool[session_id]->hash_dma_buf[hash_id], + hash_pool[session_id]->attach[hash_id]); + return PTR_ERR(hash_pool[session_id]->sgt[hash_id]); + } + + // get iova + hash_pool[session_id]->hash_base_iova[hash_id] = + (uint32_t)sg_dma_address(hash_pool[session_id]->sgt[hash_id]->sgl); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] hash_base_iova 0x%08x\n", + hash_pool[session_id]->hash_base_iova[hash_id]); + pr_info("[MVPU][Sec] hash_pool_size 0x%08x\n", + hash_pool[session_id]->hash_pool_size[hash_id]); + } + + // get *kva + ret_dma_buf_vmap = dma_buf_vmap(hash_pool[session_id]->hash_dma_buf[hash_id], &sys_map); + p_buf = sys_map.vaddr; + //hash_pool[session_id]->hash_base_kva[hash_id] = (uint64_t *)p_buf; + + if ((ret_dma_buf_vmap != 0) || (!p_buf)) { + pr_info("[MVPU][Sec] kva map failed\n"); + return -ENOMEM; + } + + hash_pool[session_id]->hash_offset[hash_id] = + kcalloc(hash_pool[session_id]->buf_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + //cache sync + dma_buf_begin_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + if (hash_pool[session_id]->hash_offset[hash_id] != NULL) { + buf_size = 0; + + for (cnt = 0; cnt < hash_pool[session_id]->buf_num[hash_id]; cnt++) { + //iova + hash_pool[session_id]->hash_offset[hash_id][cnt] = buf_ofst; + cp_buff = (void *)((uintptr_t)p_buf + buf_ofst); + + buf_size = sec_buf_size[cnt]; + switch (sec_buf_attr[cnt]) { + case BUF_NORMAL: + case BUF_RINGBUFFER: + if (sec_chk_addr[cnt] != MVPU_CMD_BUFF_ADDR) { + buf_kva = apusys_mem_query_kva_by_sess(session, + sec_chk_addr[cnt]); + if (buf_kva == NULL) { + pr_info("[MVPU][Sec] apusys_mem_query_kva_by_sess fail (session: 0x%llx, sec_chk_addr[%3d]: 0x%08x)\n", + (unsigned long long)session, cnt, sec_chk_addr[cnt]); + return -ENOMEM; + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: copy to pool\n", + cnt); + copy_to_pool = true; + } else { +#ifndef MVPU_SEC_KREG_IN_POOL + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: bypass cmd_buf\n", + cnt); + copy_to_pool = false; + buf_kva = 0x0; +#else + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: copy cmd_buf\n", + cnt); + copy_to_pool = true; + buf_kva = kreg_kva; +#endif + } + break; + case BUF_KERNEL: + if (!algo_in_img) { + buf_kva = apusys_mem_query_kva_by_sess(session, + sec_chk_addr[cnt]); + if (buf_kva == NULL) { + pr_info("[MVPU][Sec] apusys_mem_query_kva_by_sess fail (session: 0x%llx, sec_chk_addr[%3d]: 0x%08x)\n", + (unsigned long long)session, cnt, sec_chk_addr[cnt]); + return -ENOMEM; + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: copy to pool\n", + cnt); + copy_to_pool = true; + } else { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: use kernel from image\n", + cnt); + copy_to_pool = false; + buf_kva = 0x0; + } + break; + case BUF_IO: + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: bypass IO buffer\n", + cnt); + copy_to_pool = false; + buf_kva = 0x0; + break; + default: + pr_info("[MVPU][Sec] [ERROR] unrecognized buf[%3d] attr: %d\n", + cnt, sec_buf_attr[cnt]); + copy_to_pool = false; + buf_kva = 0x0; + break; + } + + if (copy_to_pool) { + if (buf_size < UINT_MAX) { + memcpy(cp_buff, buf_kva, buf_size); + } else { + pr_info("[MVPU][Sec] buf_size error\n"); + return -1; + } + + //alignment + buf_size = (((buf_size) + MVPU_ADDR_ALIGN - 1) + /MVPU_ADDR_ALIGN) + *MVPU_ADDR_ALIGN; + + //next buf + buf_ofst += buf_size; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][Sec] buf[%3d]: copy 0x%lx to 0x%lx\n", + cnt, + (uintptr_t)buf_kva, + (uintptr_t)cp_buff); + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][Sec] buf[%3d]: copy size 0x%08x, offset 0x%08x\n", + cnt, + buf_size, + hash_pool[session_id]->hash_offset[hash_id][cnt]); + } + } + } + } else { + pr_info("[MVPU][Sec] hash_offset alloc fail\n"); + return -ENOMEM; + } + + //cache sync + dma_buf_end_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + if (p_buf) + dma_buf_vunmap(hash_pool[session_id]->hash_dma_buf[hash_id], p_buf); + + return 0; +} + +#ifdef FULL_RP_INFO +int mvpu25_save_hash_info(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t rp_num, + uint32_t *sec_chk_addr, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + uint32_t *target_buf_old_map, + uint32_t *target_buf_new_map) +#else +int mvpu25_save_hash_info(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t *sec_chk_addr) + +#endif +{ + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + +#ifdef FULL_RP_INFO + hash_pool[session_id]->rp_num[hash_id] = rp_num; +#endif + + hash_pool[session_id]->sec_chk_addr[hash_id] = + kcalloc(hash_pool[session_id]->buf_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->sec_chk_addr[hash_id] != NULL) { + memcpy(hash_pool[session_id]->sec_chk_addr[hash_id], + sec_chk_addr, + hash_pool[session_id]->buf_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + +#ifdef FULL_RP_INFO + hash_pool[session_id]->target_buf_old_base[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_old_base[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_old_base[hash_id], + target_buf_old_base, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + + hash_pool[session_id]->target_buf_old_offset[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_old_offset[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_old_offset[hash_id], + target_buf_old_offset, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + + hash_pool[session_id]->target_buf_new_base[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_new_base[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_new_base[hash_id], + target_buf_new_base, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + + hash_pool[session_id]->target_buf_new_offset[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_new_offset[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_new_offset[hash_id], + target_buf_new_offset, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + + hash_pool[session_id]->target_buf_old_map[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_old_map[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_old_map[hash_id], + target_buf_old_map, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } + + hash_pool[session_id]->target_buf_new_map[hash_id] = + kcalloc(hash_pool[session_id]->rp_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (hash_pool[session_id]->target_buf_new_map[hash_id] != NULL) { + memcpy(hash_pool[session_id]->target_buf_new_map[hash_id], + target_buf_new_map, + hash_pool[session_id]->rp_num[hash_id]*sizeof(uint32_t)); + } else { + return -ENOMEM; + } +#endif + + return 0; +} + +bool mvpu25_get_hash_info(void *session, + uint32_t batch_name_hash, + uint32_t *session_id, + uint32_t *hash_id, + uint32_t buf_num) +{ + if (batch_name_hash == 0x0) + return false; + + *session_id = mvpu25_get_saved_session_id(session); + + if (*session_id == 0xFFFFFFFF) + return false; + + *hash_id = mvpu25_get_saved_hash_id(*session_id, batch_name_hash); + + if (*hash_id == 0xFFFFFFFF) + return false; + else if (*hash_id == hash_pool[*session_id]->hash_oldest) + hash_pool[*session_id]->hash_oldest++; + + if (hash_pool[*session_id]->buf_num[*hash_id] != buf_num) + return false; + + return true; +} + + +int mvpu25_replace_img_knl(void *session, + uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_attr, + uint32_t rp_num, + uint32_t *target_buf_old_map, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + uint32_t ker_bin_num, + uint32_t *ker_bin_each_iova) +{ + int ret = 0; + uint32_t cnt = 0; + uint32_t ker_img_cnt = 0; + void *buf_ptr; + void *buf_ptr_base; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + for (cnt = 0; cnt < buf_num; cnt++) { + if (sec_buf_attr[cnt] != BUF_KERNEL) + continue; + + if (ker_img_cnt > ker_bin_num) { + pr_info("[MVPU][IMG] [ERROR] User's KNL buf num > mvpu_algo.img Kernel_*.bin num %d\n", + ker_bin_num); + + ret = -1; + return ret; + } + + sec_chk_addr[cnt] = ker_bin_each_iova[ker_img_cnt]; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] set target_buf[%d] = 0x%08x, from partition\n", + cnt, sec_chk_addr[cnt]); + + ker_img_cnt++; + } + + for (cnt = 0; cnt < rp_num; cnt++) { + buf_ptr_base = apusys_mem_query_kva_by_sess(session, target_buf_old_base[cnt]); + buf_ptr = (void *)((uintptr_t)buf_ptr_base + + target_buf_old_offset[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][Sec] DRV rp cnt %03d, replace *[0x%llx + 0x%08x] from 0x%08x to [0x%08x + 0x%08x]\n", + cnt, + (unsigned long long)target_buf_old_base[cnt], + target_buf_old_offset[cnt], + *((uint32_t *)buf_ptr), + sec_chk_addr[target_buf_new_map[cnt]], + target_buf_new_offset[cnt]); + } + + // replacement, set new values + *((uint32_t *)buf_ptr) = + (uint32_t)(sec_chk_addr[target_buf_new_map[cnt]] + + target_buf_new_offset[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] new value: 0x%08x\n", + *((uint32_t *)buf_ptr)); + } + + return ret; +} + + +bool mvpu25_set_rp_skip_buf(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_attr, + uint32_t *rp_skip_buf) +{ + int i = 0; + bool algo_all_same_buf = true; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + for (i = 0; i < buf_num; i++) { + if (sec_buf_attr[i] != BUF_IO) { + rp_skip_buf[i] = 1; + continue; + } + + if (hash_pool[session_id]->sec_chk_addr[hash_id][i] == sec_chk_addr[i]) + rp_skip_buf[i] = 1; + else + algo_all_same_buf = false; + } + + return algo_all_same_buf; +} + +int mvpu25_update_new_base_addr(bool algo_in_img, + bool algo_in_pool, + uint32_t session_id, + uint32_t hash_id, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_attr, + uint32_t *rp_skip_buf, + uint32_t rp_num, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t ker_bin_num, + uint32_t *ker_bin_each_iova, + void *kreg_kva) +{ + int ret = 0; + uint32_t cnt = 0; + uint32_t ker_img_cnt = 0; + uint32_t *target_pool_addr = NULL; + uint32_t target_pool_ofst = 0; + uint32_t *rp_buf_new_base; + uint32_t *rp_buf_new_map; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + target_pool_addr = + kcalloc(hash_pool[session_id]->buf_num[hash_id], sizeof(uint32_t), GFP_KERNEL); + + if (!target_pool_addr) + return -ENOMEM; + +#ifdef FULL_RP_INFO + if (algo_in_pool == true) { + rp_buf_new_base = hash_pool[session_id]->target_buf_new_base[hash_id]; + rp_buf_new_map = hash_pool[session_id]->target_buf_new_map[hash_id]; + } else { + rp_buf_new_base = target_buf_new_base; + rp_buf_new_map = target_buf_new_map; + } +#else + rp_buf_new_base = target_buf_new_base; + rp_buf_new_map = target_buf_new_map; +#endif + + // update pool addr + for (cnt = 0; cnt < hash_pool[session_id]->buf_num[hash_id]; cnt++) { + if (rp_skip_buf[cnt] == 1) + continue; + + if (algo_in_img && sec_buf_attr[cnt] == BUF_KERNEL) { + if (ker_img_cnt > ker_bin_num) { + pr_info("[MVPU][IMG] [ERROR] User's KNL buf num > mvpu_algo.img Kernel_*.bin num %d\n", + ker_bin_num); + + ret = -1; + goto END; + } + + target_pool_addr[cnt] = ker_bin_each_iova[ker_img_cnt]; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] set target_pool_addr[%d] = 0x%08x, from partition\n", + cnt, target_pool_addr[cnt]); + + ker_img_cnt++; + } else if (sec_buf_attr[cnt] == BUF_IO) { + if (algo_in_pool == false) + continue; + else + target_pool_addr[cnt] = sec_chk_addr[cnt]; + } else { + target_pool_ofst = hash_pool[session_id]->hash_offset[hash_id][cnt]; + target_pool_addr[cnt] = hash_pool[session_id]->hash_base_iova[hash_id] + + target_pool_ofst; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] set target_pool_addr[%d]: 0x%08x\n", + cnt, target_pool_addr[cnt]); + } + } + + // update new base addr to pool addr with buf_map + for (cnt = 0; cnt < rp_num; cnt++) { +#ifdef MVPU_SEC_USE_MEM_POOL + if (rp_skip_buf[rp_buf_new_map[cnt]] == 1) + continue; + + if (rp_buf_new_base[cnt] != 0) { + if (algo_in_pool == false && + (sec_buf_attr[rp_buf_new_map[cnt]] == BUF_IO)) + continue; + + rp_buf_new_base[cnt] = target_pool_addr[rp_buf_new_map[cnt]]; + } +#endif + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] update target_buf_new_base[%02d]: 0x%08x\n", + cnt, rp_buf_new_base[cnt]); + } + +END: + kfree(target_pool_addr); + + return ret; +} + +int mvpu25_replace_mem(uint32_t session_id, + uint32_t hash_id, + uint32_t *sec_buf_attr, + bool algo_in_pool, + uint32_t *rp_skip_buf, + uint32_t rp_num, + uint32_t *target_buf_old_map, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + void *kreg_kva) +{ + int ret = 0; + int cnt = 0; + + // get *kva + void *buf_ptr_base; + void *buf_ptr; + uint32_t target_pool_ofst = 0; + + uint32_t *rp_buf_old_map; + uint32_t *rp_buf_old_base; + uint32_t *rp_buf_old_offset; + uint32_t *rp_buf_new_map; + uint32_t *rp_buf_new_base; + uint32_t *rp_buf_new_offset; + int ret_dma_buf_vmap = 0; + struct iosys_map sys_map = {0}; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + ret_dma_buf_vmap = dma_buf_vmap(hash_pool[session_id]->hash_dma_buf[hash_id], &sys_map); + buf_ptr_base = sys_map.vaddr; + + if ((ret_dma_buf_vmap != 0) || (!buf_ptr_base)) { + pr_info("[MVPU][Sec] buf_ptr_base kva map failed\n"); + return -ENOMEM; + } + + buf_ptr = buf_ptr_base; + +#ifdef FULL_RP_INFO + if (algo_in_pool == true) { + rp_buf_old_map = hash_pool[session_id]->target_buf_old_map[hash_id]; + rp_buf_old_base = hash_pool[session_id]->target_buf_old_base[hash_id]; + rp_buf_old_offset = hash_pool[session_id]->target_buf_old_offset[hash_id]; + rp_buf_new_map = hash_pool[session_id]->target_buf_new_map[hash_id]; + rp_buf_new_base = hash_pool[session_id]->target_buf_new_base[hash_id]; + rp_buf_new_offset = hash_pool[session_id]->target_buf_new_offset[hash_id]; + } else { + rp_buf_old_map = target_buf_old_map; + rp_buf_old_base = target_buf_old_base; + rp_buf_old_offset = target_buf_old_offset; + rp_buf_new_map = target_buf_new_map; + rp_buf_new_base = target_buf_new_base; + rp_buf_new_offset = target_buf_new_offset; + } +#else + rp_buf_old_map = target_buf_old_map; + rp_buf_old_base = target_buf_old_base; + rp_buf_old_offset = target_buf_old_offset; + rp_buf_new_map = target_buf_new_map; + rp_buf_new_base = target_buf_new_base; + rp_buf_new_offset = target_buf_new_offset; +#endif + + //cache sync + dma_buf_begin_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + for (cnt = 0; cnt < rp_num; cnt++) { + if (rp_skip_buf[rp_buf_new_map[cnt]] == 1) + continue; + +#ifndef MVPU_SEC_KREG_IN_POOL + // get addr kva + if (rp_buf_old_base[cnt] == 0) { + buf_ptr = (void *)((uintptr_t)kreg_kva + rp_buf_old_offset[cnt]); + } else { + target_pool_ofst = + hash_pool[session_id] + ->hash_offset[hash_id][rp_buf_old_map[cnt]]; + buf_ptr = (void *)((uintptr_t)buf_ptr_base + + target_pool_ofst + + rp_buf_old_offset[cnt]); + } +#else + target_pool_ofst = + hash_pool[session_id] + ->hash_offset[hash_id][rp_buf_old_map[cnt]]; + buf_ptr = (void *)((uintptr_t)buf_ptr_base + + target_pool_ofst + + rp_buf_old_offset[cnt]); +#endif + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][Sec] DRV rp cnt %03d, replace *[0x%llx + 0x%08x] from 0x%08x to [0x%08x + 0x%08x]\n", + cnt, +#ifndef MVPU_SEC_KREG_IN_POOL + (rp_buf_old_base[cnt] == 0) ? + ((uintptr_t)kreg_kva):(rp_buf_old_base[cnt]), +#else + (unsigned long long)rp_buf_old_base[cnt], +#endif + rp_buf_old_offset[cnt], + *((uint32_t *)buf_ptr), + rp_buf_new_base[cnt], + rp_buf_new_offset[cnt]); + } + + // replacement, set new values + if (*((uint32_t *)buf_ptr) != 0x80000000) + *((uint32_t *)buf_ptr) = + (uint32_t)(rp_buf_new_base[cnt] + rp_buf_new_offset[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] new value: 0x%08x\n", + *((uint32_t *)buf_ptr)); + } + + //cache sync + dma_buf_end_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + if (buf_ptr_base) + dma_buf_vunmap(hash_pool[session_id]->hash_dma_buf[hash_id], buf_ptr_base); + + return ret; +} + +void mvpu25_CopyArgToPrimem(char *dst_ptr, char *src_ptr, int src_size) +{ + char dup_buf[MVPU_DUP_BUF_SIZE] = { 0 }; + char *src_data; + int i, j; + + for (i = 0; i < src_size; i += 2) { + src_data = src_ptr + i; + for (j = 0; j < MVPU_PE_NUM * 2; j += 2) + memcpy(dup_buf + j, src_data, 2); + + memcpy(dst_ptr, dup_buf, MVPU_DUP_BUF_SIZE); + dst_ptr = dst_ptr + MVPU_DUP_BUF_SIZE; + } +} + +void mvpu25_CheckPrimemArg(char *dst_ptr, int src_size) +{ + int i, j; + + for (i = 0; i < src_size; i += 2) { + for (j = 0; j < MVPU_PE_NUM * 2; j += 2) + pr_info("[MVPU][Sec] check primem_ptr 0x%02x%02x\n", + *((char *)dst_ptr + j + 1), *((char *)dst_ptr + j)); + + dst_ptr = dst_ptr + MVPU_DUP_BUF_SIZE; + } +} + +int mvpu25_replace_kerarg(void *session, + uint32_t session_id, + uint32_t hash_id, + uint32_t kerarg_num, + uint32_t *sec_chk_addr, + uint32_t *kerarg_buf_id, + uint32_t *kerarg_offset, + uint32_t *kerarg_size, + uint32_t primem_num, + uint32_t *primem_src_buf_id, + uint32_t *primem_dst_buf_id, + uint32_t *primem_src_offset, + uint32_t *primem_dst_offset, + uint32_t *primem_size) +{ + int ret = 0; + int cnt = 0; + + // get *kva + void *sec_chk_addr_kva; + void *pool_ptr_base; + + void *buf_ptr; + void *kerarg_ptr; + void *primem_ptr; + + uint32_t target_pool_ofst = 0; + uint32_t target_src_ofst = 0; + uint32_t target_dst_ofst = 0; + int i; + int ret_dma_buf_vmap = 0; + struct iosys_map sys_map = {0}; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] %s\n", __func__); + + ret_dma_buf_vmap = dma_buf_vmap(hash_pool[session_id]->hash_dma_buf[hash_id], &sys_map); + pool_ptr_base = sys_map.vaddr; + + if ((ret_dma_buf_vmap != 0) || (!pool_ptr_base)) { + pr_info("[MVPU][Sec] buf_ptr_base kva map failed\n"); + return -ENOMEM; + } + + //cache sync + dma_buf_begin_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + for (cnt = 0; cnt < kerarg_num; cnt++) { + sec_chk_addr_kva = + apusys_mem_query_kva_by_sess(session, sec_chk_addr[kerarg_buf_id[cnt]]); + buf_ptr = (void *)((uintptr_t)sec_chk_addr_kva + + kerarg_offset[cnt]); + + target_pool_ofst = hash_pool[session_id]->hash_offset[hash_id][kerarg_buf_id[cnt]]; + kerarg_ptr = (void *)((uintptr_t)pool_ptr_base + + target_pool_ofst + + kerarg_offset[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] kerarg cnt %03d, set kerarg[%03d][0x%lx] from buf[%03d][0x%lx] offset 0x%08x with 0x%x bytes\n", + cnt, + kerarg_buf_id[cnt], + (unsigned long)pool_ptr_base + target_pool_ofst, + kerarg_buf_id[cnt], + (unsigned long)sec_chk_addr_kva, + kerarg_offset[cnt], + kerarg_size[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + for (i = 0; i < kerarg_size[cnt]; i++) { + pr_info("[MVPU][Sec] set kerarg_ptr 0x%02x from buf_ptr 0x%02x\n", + *((char *)kerarg_ptr + i), *((char *)buf_ptr + i)); + } + } + } + + memcpy(kerarg_ptr, buf_ptr, kerarg_size[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + for (i = 0; i < kerarg_size[cnt]; i++) { + pr_info("[MVPU][Sec] kerarg_ptr 0x%02x\n", + *((char *)kerarg_ptr + i)); + } + } + + // replace primem + for (i = 0; i < primem_num; i++) { + if ((kerarg_buf_id[cnt] == primem_src_buf_id[i]) && + (kerarg_offset[cnt] >= primem_src_offset[i]) && + (kerarg_offset[cnt] < primem_src_offset[i] + primem_size[i])) { + target_pool_ofst = + hash_pool[session_id]->hash_offset + [hash_id][primem_dst_buf_id[i]]; + target_src_ofst = kerarg_offset[cnt] - primem_src_offset[i]; + target_dst_ofst = + primem_dst_offset[i] + target_src_ofst * MVPU_PE_NUM; + + primem_ptr = (void *)((uintptr_t)pool_ptr_base + + target_pool_ofst + + target_dst_ofst); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] mvpu25_CopyArgToPrimem buf[%d]->buf[%d], ker_ofst 0x%08x, dst_ofst (0x%08x + 0x%08x), size 0x%x\n", + primem_src_buf_id[i], + primem_dst_buf_id[i], + kerarg_offset[cnt], + primem_dst_offset[i], + target_dst_ofst, + kerarg_size[cnt]); + } + + mvpu25_CopyArgToPrimem(primem_ptr, kerarg_ptr, kerarg_size[cnt]); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + mvpu25_CheckPrimemArg(primem_ptr, kerarg_size[cnt]); + + break; + } + } + } + + //cache sync + dma_buf_end_cpu_access(hash_pool[session_id]->hash_dma_buf[hash_id], DMA_TO_DEVICE); + + if (pool_ptr_base) + dma_buf_vunmap(hash_pool[session_id]->hash_dma_buf[hash_id], pool_ptr_base); + + return ret; +} + +void mvpu25_get_pool_kreg_iova(uint32_t *kreg_iova_pool, + uint32_t session_id, + uint32_t hash_id, + uint32_t buf_cmd_kreg) +{ + *kreg_iova_pool = hash_pool[session_id]->hash_base_iova[hash_id] + + hash_pool[session_id]->hash_offset[hash_id][buf_cmd_kreg]; +} + +void mvpu25_region_sort(uint32_t region_num, uint32_t *region) +{ + int i = 0, j = 0; + uint32_t tmp = 0; + + for (i = 0; i < region_num; i++) { + for (j = i + 1; j < region_num; j++) { + if (region[i] > region[j]) { + tmp = region[i]; + region[i] = region[j]; + region[j] = tmp; + } + } + } +} + +int mvpu25_region_info_set(uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_size, + uint32_t *sec_buf_attr, + uint32_t *buf_io_addr, + uint32_t *buf_io_size, + bool protect_phase) +{ + int i = 0, j = 0; + uint32_t buf_io_cnt = 0; + uint32_t buf_io_total = 0; + uint32_t base_shift = 0; + uint32_t size_shift = 0; + uint32_t size = 0; + + //get all IO buf addr + for (i = 0; i < buf_num; i++) { + if ((sec_chk_addr[i] >= VIRTUAL_APUSYS_TCM_BASE) && + (sec_chk_addr[i] < VIRTUAL_APUSYS_TCM_BASE_END)) + continue; + + if (protect_phase == true) { + if (sec_buf_attr[i] == BUF_IO) { + buf_io_addr[buf_io_cnt] = sec_chk_addr[i]; + buf_io_cnt++; + } + } else { + if ((sec_buf_attr[i] == BUF_IO) || + ((sec_buf_attr[i] == BUF_NORMAL) && + (sec_chk_addr[i] != MVPU_CMD_BUFF_ADDR)) || + (sec_buf_attr[i] == BUF_KERNEL) || + (sec_buf_attr[i] == BUF_RINGBUFFER)) { + buf_io_addr[buf_io_cnt] = sec_chk_addr[i]; + buf_io_cnt++; + } + } + } + + buf_io_total = buf_io_cnt; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][SEC] [MPU] buf_io_total = %3d\n", buf_io_total); + for (i = 0; i < buf_io_total; i++) + pr_info("[MVPU][SEC] [MPU] origin buf_io_addr[%3d] = 0x%08x\n", + i, buf_io_addr[i]); + } + + //Sorting + mvpu25_region_sort(buf_io_total, buf_io_addr); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] [MPU] mapping buf_io_addr with sec_chk_addr\n"); + + //mapping size info + for (i = 0; i < buf_io_total; i++) { + base_shift = buf_io_addr[i] & 0x00000FFF; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] [MPU] start to mapping buf_io_addr[%d] 0x%08x\n", i, buf_io_addr[i]); + + for (j = 0; j < buf_num; j++) { + if (buf_io_addr[i] == sec_chk_addr[j]) { + size = (((sec_buf_size[j] + base_shift) + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) * MVPU_MPU_SIZE; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] [MPU] sec_chk_addr[%d] 0x%08x, sec_buf_size[%d] 0x%08x->0x%08x (aligned)\n", + j, sec_chk_addr[j], j, sec_buf_size[j], size); + + if (size > buf_io_size[i]) { + buf_io_size[i] = size; + size_shift = buf_io_size[i] - sec_buf_size[j]; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG && base_shift > size_shift) + pr_info("[MVPU][SEC] [MPU] ERROR base_shift 0x%08x, size_shift 0x%08x\n", + base_shift, size_shift); + } + } + } + + buf_io_addr[i] = buf_io_addr[i] & 0xFFFFF000; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] mapping result buf_io_addr[%d] 0x%08x (aligned), buf_io_size[%d] 0x%08x (aligned)\n", + i, buf_io_addr[i], i, buf_io_size[i]); + } + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][SEC] [MPU] %s buf_io_total = %3d\n", __func__, buf_io_total); + for (i = 0; i < buf_io_total; i++) { + pr_info("[MVPU][SEC] [MPU] sorted buf_io_addr[%3d] = 0x%08x (aligned)\n", + i, buf_io_addr[i]); + pr_info(" buf_io_size[%3d] = 0x%08x (aligned)\n", + i, buf_io_size[i]); + } + } + + return buf_io_total; +} + +int mvpu25_region_merge(uint32_t region_num, + uint32_t *curr_addr_list, + uint32_t *curr_size_list, + uint32_t *merged_region) +{ + int i = 0; + + uint32_t addr_curr = 0, addr_next = 0; + uint32_t addr_curr_end = 0, addr_next_end = 0; + + int merged_region_cnt = 0; + + for (i = 0; i < region_num; i++) { + addr_curr = curr_addr_list[i]; + addr_curr_end = addr_curr + curr_size_list[i]; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] [MPU] %s buf_curr[%3d] region 0x%08x - 0x%08x\n", + __func__, i, addr_curr, addr_curr_end); + + while (i < region_num) { + if (i == region_num - 1) + break; + + addr_next = curr_addr_list[i + 1]; + addr_next_end = addr_next + curr_size_list[i + 1]; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] [MPU] %s buf_next[%3d] region 0x%08x - 0x%08x\n", + __func__, i + 1, addr_next, addr_next_end); + + if (addr_curr_end >= addr_next) { + addr_curr_end = + (addr_next_end >= addr_curr_end) ? + addr_next_end : addr_curr_end; + i++; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] [MPU] %s merge region to 0x%08x - 0x%08x\n", + __func__, addr_curr, addr_curr_end); + } else { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) + pr_info("[MVPU][Sec] [MPU] %s find next region\n", + __func__); + break; + } + } + + merged_region[merged_region_cnt] = addr_curr; + merged_region[merged_region_cnt + 1] = addr_curr_end; + merged_region_cnt = merged_region_cnt + 2; + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] [MPU] IO region merged: %d to %d\n", + region_num*2, merged_region_cnt); + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + for (i = 0; i < merged_region_cnt; i++) + pr_info("[MVPU][SEC] [MPU] merged_region[%3d] 0x%08x\n", + i, merged_region[i]); + } + + return merged_region_cnt; +} + +int mvpu25_region_mpu_set(uint32_t session_id, + uint32_t hash_id, + uint32_t pmu_buff, + uint32_t buff_size, + uint32_t *mpu_seg, + uint32_t buf_io_total_merged, + uint32_t *buf_io_addr_merged, + bool protect_phase) +{ + int i = 0; + int buf_io_cnt = 0; + int total_mpu_cnt = 0; + + //IO buffers + for (i = 0; i < buf_io_total_merged; i++) { + mpu_seg[buf_io_cnt] = buf_io_addr_merged[i]; + buf_io_cnt++; + } + + //SYS buffers + mpu_seg[buf_io_cnt + ITCM_BASE_SFT] = ITCM_VIRTUAL_BASE; + mpu_seg[buf_io_cnt + ITCM_END_SFT] = ITCM_VIRTUAL_BASE_END; + mpu_seg[buf_io_cnt + TCM_BASE_SFT] = VIRTUAL_APUSYS_TCM_BASE; + mpu_seg[buf_io_cnt + TCM_END_SFT] = VIRTUAL_APUSYS_TCM_BASE_END; + + if (protect_phase == true) { + mpu_seg[buf_io_cnt + IMG_BASE_SFT] = mvpu_algo_iova; + if (mvpu_algo_available == true) { + mpu_seg[buf_io_cnt + IMG_END_SFT] = + (((mvpu_algo_iova + 32 + + ptn_img_size + + knl_img_size) + + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + } else { + mpu_seg[buf_io_cnt + IMG_END_SFT] = mvpu_algo_iova + MVPU_MPU_SIZE; + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][IMG] [MPU][WARN] set fake image region: 0x%08x\n", + mpu_seg[buf_io_cnt + IMG_END_SFT]); + } + + mpu_seg[buf_io_cnt + POOL_BASE_SFT] + = hash_pool[session_id]->hash_base_iova[hash_id]; + mpu_seg[buf_io_cnt + POOL_END_SFT] = + (((hash_pool[session_id]->hash_base_iova[hash_id] + + hash_pool[session_id]->hash_pool_size[hash_id]) + + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] set algo region: 0x%08x - 0x%08x\n", + mpu_seg[buf_io_cnt + IMG_BASE_SFT], + mpu_seg[buf_io_cnt + IMG_END_SFT]); + pr_info("[MVPU][SEC] [MPU] set pool region: 0x%08x - 0x%08x\n", + mpu_seg[buf_io_cnt + POOL_BASE_SFT], + mpu_seg[buf_io_cnt + POOL_END_SFT]); + } + } + + if (pmu_buff != 0) { + mpu_seg[buf_io_cnt + PMU_BASE_SFT] = + ((pmu_buff + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + + mpu_seg[buf_io_cnt + PMU_END_SFT] = + (((pmu_buff + buff_size) + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] set PMU region: 0x%08x - 0x%08x\n", + mpu_seg[buf_io_cnt + PMU_BASE_SFT], + mpu_seg[buf_io_cnt + PMU_END_SFT]); + } + + if (protect_phase == true) + buf_io_cnt = buf_io_cnt + PMU_END_SFT; + else + buf_io_cnt = buf_io_cnt + TCM_END_SFT + 2; + + } else { + if (protect_phase == true) + buf_io_cnt = buf_io_cnt + POOL_END_SFT; + else + buf_io_cnt = buf_io_cnt + TCM_END_SFT; + } + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_ALL) { + for (i = 0; i < MVPU_MPU_SEGMENT_NUMS; i++) + pr_info("[MVPU][SEC] [MPU] sec mpu_reg[%3d] = 0x%08x\n", + i, mpu_seg[i]); + } + + //Sorting + mvpu25_region_sort(MVPU_MPU_SEGMENT_NUMS, mpu_seg); + + total_mpu_cnt = buf_io_cnt + 1; + return total_mpu_cnt; +} + +int mvpu25_add_img_mpu(void *mvpu_cmd) +{ + struct mvpu_request_v25 *mvpu_req; + + int ret = 0; + int i = 0; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] %s\n", __func__); + + mvpu_req = (struct mvpu_request_v25 *)mvpu_cmd; + + if (mvpu_req->mpu_num > MVPU_MPU_SEGMENT_NUMS - 3) { + mvpu_req->mpu_num = 0; + memset(mvpu_req->mpu_seg, 0, sizeof(mvpu_req->mpu_seg)); + } else { + mvpu_req->mpu_seg[0] = mvpu_algo_iova; + mvpu_req->mpu_seg[1] = + (((mvpu_algo_iova + 32 + + ptn_img_size + + knl_img_size) + + MVPU_MPU_SIZE - 1) + /MVPU_MPU_SIZE) + *MVPU_MPU_SIZE; + + mvpu25_region_sort(MVPU_MPU_SEGMENT_NUMS, mvpu_req->mpu_seg); + mvpu_req->mpu_num = mvpu_req->mpu_num + 2; + } + + if (mvpu_req->mpu_num != 0 && mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] mpu_num = %3d\n", mvpu_req->mpu_num); + for (i = 0; i < MVPU_MPU_SEGMENT_NUMS; i++) + pr_info("[MVPU][SEC] [MPU] drv mpu_reg[%3d] = 0x%08x\n", + i, mvpu_req->mpu_seg[i]); + } + + return ret; +} + + +int mvpu25_update_mpu(void *mvpu_cmd, + uint32_t session_id, + uint32_t hash_id, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_size, + uint32_t *sec_buf_attr, + bool protect_phase) +{ + uint32_t mpu_seg[MVPU_MPU_SEGMENT_NUMS] = {0}; + struct mvpu_request_v25 *mvpu_req; + + int ret = 0; + int i = 0; + uint32_t buf_num = 0; + + uint32_t buf_io_total = 0; + uint32_t buf_io_total_merged = 0; + + uint32_t *buf_io_addr = NULL; + uint32_t *buf_io_size = NULL; + uint32_t *buf_io_addr_merged = NULL; + + uint32_t total_mpu_cnt = 0; + + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] %s\n", __func__); + + mvpu_req = (struct mvpu_request_v25 *)mvpu_cmd; + buf_num = mvpu_req->buf_num & BUF_NUM_MASK; + +#ifdef MVPU_SEC_CLEAR_MPU + //clear MPU + mvpu_req->mpu_num = 0; + memset(mvpu_req->mpu_seg, 0, sizeof(mvpu_req->mpu_seg)); +#endif + + //get total IO buffers + for (i = 0; i < buf_num; i++) { + if ((sec_chk_addr[i] >= VIRTUAL_APUSYS_TCM_BASE) && + (sec_chk_addr[i] < VIRTUAL_APUSYS_TCM_BASE_END)) + continue; + + if (protect_phase == true) { + if (sec_buf_attr[i] == BUF_IO) + buf_io_total++; + } else { + if ((sec_buf_attr[i] == BUF_IO) || + ((sec_buf_attr[i] == BUF_NORMAL) && + (sec_chk_addr[i] != MVPU_CMD_BUFF_ADDR)) || + (sec_buf_attr[i] == BUF_KERNEL) || + (sec_buf_attr[i] == BUF_RINGBUFFER)) + buf_io_total++; + } + } + + buf_io_addr = kcalloc(buf_io_total, sizeof(uint32_t), GFP_KERNEL); + if (!buf_io_addr) { + ret = -ENOMEM; + goto END; + } + + buf_io_size = kcalloc(buf_io_total, sizeof(uint32_t), GFP_KERNEL); + if (!buf_io_size) { + ret = -ENOMEM; + goto END; + } + + buf_io_total = mvpu25_region_info_set(buf_num, + sec_chk_addr, sec_buf_size, sec_buf_attr, + buf_io_addr, buf_io_size, protect_phase); + + //try to merge IO buf region + buf_io_addr_merged = kcalloc(buf_io_total * 2, sizeof(uint32_t), GFP_KERNEL); + if (!buf_io_addr_merged) { + ret = -ENOMEM; + goto END; + } + + buf_io_total_merged = + mvpu25_region_merge(buf_io_total, buf_io_addr, buf_io_size, buf_io_addr_merged); + + if (buf_io_total_merged > (MVPU_MPU_SEGMENT_NUMS - 1 - SYS_BUF_NUM)) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] [MPU][NOTICE] IO buff num %d is too much\n", + buf_io_total); + +#ifdef MVPU_SEC_MPU_NUM_BLOCK + ret = -1; +#else + ret = 0; +#endif + goto END; + } + + total_mpu_cnt = mvpu25_region_mpu_set(session_id, hash_id, + mvpu_req->pmu_buff, mvpu_req->buff_size, + mpu_seg, buf_io_total_merged, + buf_io_addr_merged, protect_phase); + +#ifdef MVPU_SEC_UPDT_MPU + //set MPU + mvpu_req->mpu_num = total_mpu_cnt; + memcpy(mvpu_req->mpu_seg, mpu_seg, sizeof(mvpu_req->mpu_seg)); +#else + pr_info("[MVPU][SEC] [MPU] Bypass MPU setting\n"); +#endif + +END: + if (buf_io_addr != NULL) + kfree(buf_io_addr); + if (buf_io_size != NULL) + kfree(buf_io_size); + if (buf_io_addr_merged != NULL) + kfree(buf_io_addr_merged); + + return ret; +} + +bool mvpu25_mem_use_iova(uint32_t addr) +{ + if ((addr == MVPU_CMD_BUFF_ADDR) || + ((addr >= VIRTUAL_APUSYS_TCM_BASE) && (addr < VIRTUAL_APUSYS_TCM_BASE_END)) || + ((addr >= VIRTUAL_MVPU_TCM_BASE) && (addr < VIRTUAL_MVPU_TCM_BASE_END)) || + ((addr & 0xFFFC0000) == 0)) + return false; + + return true; +} + +int mvpu25_check_iova(void *session, + void *cmd, + uint32_t desc_type, + uint32_t chk_num, + uint32_t chk_base, + uint32_t chk_size) +{ + int ret = 0; + int i = 0; + + uint32_t desc_size = 64; + + uint32_t *desc_ptr; + uint32_t desc_addr_ofst = 0; + uint32_t desc_addr = 0; + + if (mvpu25_mem_use_iova(chk_base) == false) + return 0; + + switch (desc_type) { + case DESC_TYPE_NONE: + if (apusys_mem_validate_by_cmd(session, cmd, + chk_base, chk_size) != 0) { + pr_info("[MVPU][Sec] [ERROR] ker mem 0x%08x integrity checked FAIL\n", + chk_base); + ret = -EINVAL; + goto END; + } + break; + case DESC_TYPE_GLSU: + case DESC_TYPE_EDMA: + if (chk_num == 0) + goto END; + + if (apusys_mem_validate_by_cmd(session, cmd, + chk_base, chk_num*desc_size) != 0) { + pr_info("[MVPU][Sec] [ERROR] desc base 0x%08x integrity checked FAIL\n", + chk_base); + ret = -EINVAL; + goto END; + } + + desc_ptr = (uint32_t *)apusys_mem_query_kva_by_sess(session, chk_base); + if (desc_ptr == NULL) { + pr_info("[MVPU][Sec] apusys_mem_query_kva_by_sess fail (session: 0x%lx, chk_base: 0x%08x)\n", + (unsigned long)session, chk_base); + ret = -ENOMEM; + goto END; + } + + if (desc_type == DESC_TYPE_GLSU) + desc_addr_ofst = 1; + else + desc_addr_ofst = 7; + + for (i = 0; i < 2; i++) { + desc_addr = desc_ptr[desc_addr_ofst + i]; + + if (mvpu25_mem_use_iova(desc_addr) == false) + continue; + + if (apusys_mem_validate_by_cmd(session, cmd, + desc_addr, 0) != 0) { + pr_info("[MVPU][Sec] [ERROR] desc[%d][%d] addr 0x%08x integrity checked FAIL\n", + desc_type, desc_addr_ofst + i, desc_addr); + ret = -EINVAL; + goto END; + } + } + break; + default: + break; + } + +END: + return ret; +} + +int mvpu25_check_batch_flow(void *session, + void *cmd, + uint32_t sec_level, + uint32_t *kreg_kva, + uint32_t knl_num) +{ + int ret = 0; + uint32_t i = 0, j = 0; + uint32_t cnt = 0; + + uint32_t chk_num = 0; + uint32_t chk_base = 0; + uint32_t chk_size = 0; + + uint32_t desc[8] = {7, 8, 10, 35, 36, 38, 0, 0}; + uint32_t sample = 1; + + uint32_t *buf_ptr = NULL; + + for (i = 0; i < knl_num; i = i + sample) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][CHK] knl_num %d, check %03d\n", knl_num, i); + + if (cnt >= MVPU_CHK_MAX) + break; + + if (sec_level != SEC_LVL_CHECK_ALL) { + sample = get_random_u32()%100; + + if (sample == 0) + sample = 1; + } + + buf_ptr = (uint32_t *)((uintptr_t)kreg_kva + i*72); + + if (buf_ptr == NULL) + goto END; + + if ((buf_ptr[0] & 0x2) != 0) { + chk_base = buf_ptr[KREG_OFST_26]; + chk_size = buf_ptr[KREG_OFST_28]; + + ret = mvpu25_check_iova(session, cmd, DESC_TYPE_NONE, 0, chk_base, chk_size); + if (ret != 0) { + pr_info("[MVPU][Sec] [ERROR] KREG[%03d][%d] instr 0x%08x FAIL\n", + i, KREG_OFST_26, chk_base); + goto END; + } + } + + for (j = 0; j < 6; j = j + 3) { + chk_num = buf_ptr[desc[j]] & 0x0000FFFF; + chk_base = buf_ptr[desc[j + 1]]; + chk_size = 0; + + ret = mvpu25_check_iova(session, cmd, DESC_TYPE_GLSU, chk_num, chk_base, chk_size); + if (ret != 0) { + pr_info("[MVPU][Sec] [ERROR] KREG[%03d] desc 0x%08x FAIL\n", + i, chk_base); + goto END; + } + + chk_num = (buf_ptr[desc[j]] & 0xFFFF0000) >> 16; + chk_base = buf_ptr[desc[j + 2]]; + chk_size = 0; + + ret = mvpu25_check_iova(session, cmd, DESC_TYPE_EDMA, chk_num, chk_base, chk_size); + if (ret != 0) { + pr_info("[MVPU][Sec] [ERROR] KREG[%03d] desc 0x%08x FAIL\n", + i, chk_base); + goto END; + } + } + + cnt++; + } + +END: + return ret; +} + +int mvpu25_load_img(struct device *dev) +{ + int ret = 0; +#ifndef MVPU_ALGO_IMG_DISABLE + struct device_node *mvpu_sec_mem_node; + struct reserved_mem *mvpu_algo; + phys_addr_t pa; + phys_addr_t size; +#endif + +#ifdef MVPU_ALGO_IMG_DISABLE + mvpu_algo_available = false; + pr_info("[MVPU] %s algo img disable\n", __func__); + goto END; +#else + mvpu_sec_mem_node = of_find_compatible_node(NULL, NULL, "mediatek,apu_mvpu_algo"); + if (!mvpu_sec_mem_node) { + dev_info(dev, "(f:%s/l:%d) DT,mediatek,mvpu_algo not found\n", __func__, __LINE__); + ret = -EINVAL; + goto END; + } + + mvpu_algo = of_reserved_mem_lookup(mvpu_sec_mem_node); + if (!mvpu_algo) { + pr_info("%s, mvpu_algo cannot lookup reserved memory\n", __func__); + ret = -EINVAL; + goto END; + } + + pa = mvpu_algo->base; + size = mvpu_algo->size; + + mvpu_algo_img = (uint32_t *)phys_to_virt(pa); + if (!mvpu_algo_img) { + // user may not need image partition + mvpu_algo_available = false; + goto END; + } + + mvpu_algo_iova = + (uint32_t)dma_map_single_attrs(dev, mvpu_algo_img, size, + DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); + + if (dma_mapping_error(dev, mvpu_algo_iova)) { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][WARN] get mvpu_algo_iova error: 0x%08llx, VA: 0x%lx\n", + mvpu_algo_iova, (unsigned long)mvpu_algo_img); + } else { + pr_info("[MVPU][WARN] get mvpu_algo_iova error: 0x%08llx\n", + mvpu_algo_iova); + } + } else { + if (mvpu_loglvl_sec >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] get mvpu_algo_iova: 0x%08llx\n", + mvpu_algo_iova); + } + + ker_img_offset = mvpu25_get_ker_img_offset(); + //ker_img_iova = mvpu_algo_iova + ker_img_offset; + + ptn_img_size = mvpu25_get_ptn_total_size(); + knl_img_size = mvpu25_get_kerbin_total_size(); + if ((ptn_img_size % 4 == 0) && (knl_img_size % 4 == 0)) { + mvpu_algo_available = true; + } else { + mvpu_algo_available = false; + pr_info("[MVPU][IMG] [WARN] get mvpu_algo.img size error, PTN: 0x%08x, KNL: 0x%08x\n", + ptn_img_size, knl_img_size); + } +#endif + +END: + return ret; +} + +int mvpu25_sec_init(struct device *dev) +{ + int ret = 0; + uint32_t session_id = 0; + uint32_t hash_id = 0; + + //image settings + mvpu_algo_iova = 0x0; + + ker_img_offset = 0x0; + //ker_img_iova = 0x0; + + mvpu_loglvl_sec = 0; + + //mem pool settings + sess_oldest = 0; + + for (session_id = 0; session_id < MAX_SAVE_SESSION; session_id++) { + saved_session[session_id] = 0xFFFFFFFFFFFFFFFF; + +/* + * saved_session[session_id] = kmalloc(sizeof(uint64_t), GFP_KERNEL); + * if (!saved_session[session_id]) { + * ret = -ENOMEM; + * goto END; + * } else { + * memset(saved_session[session_id], 0xFFFFFFFFFFFFFFFF, sizeof(uint64_t)); + * } + */ + + hash_pool[session_id] = kvzalloc(sizeof(struct mvpu_hash_pool), GFP_KERNEL); + if (!hash_pool[session_id]) { + ret = -ENOMEM; + goto END; + } + + for (hash_id = 0; hash_id < MAX_SAVE_HASH; hash_id++) + hash_pool[session_id]->hash_list[hash_id] = 0; + + hash_pool[session_id]->hash_oldest = 0; + } + +END: + return ret; +} + + +static uint64_t ptn_total_size; +static uint64_t kerbin_total_size; + +static ssize_t mvpu_img_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int ret = 0; + + if (ptn_total_size == 0) + ptn_total_size = mvpu25_get_ptn_total_size(); + else + pr_info("[MVPU] already get ptn_total_size: 0x%llx\n", ptn_total_size); + + if (kerbin_total_size == 0) + kerbin_total_size = mvpu25_get_kerbin_total_size(); + else + pr_info("[MVPU] already get kerbin_total_size: 0x%llx\n", kerbin_total_size); + + ret = sprintf(buf, "0x%llx", ptn_total_size + kerbin_total_size + 32); + if (ret < 0) { + pr_info("[MVPU] %s, sprintf error\n", __func__); + return ret; + } + + pr_info("[MVPU] %s, ptn_size = 0x%x, kerbin_size = 0x%x, mvpu_img_sz = 0x%x\n", + __func__, (uint32_t)ptn_total_size, (uint32_t)kerbin_total_size, + (uint32_t)(ptn_total_size + kerbin_total_size + 32)); + + return ret; +} + +static ssize_t mvpu_img_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *cmd, size_t count) +{ + return count; +} + +static struct kobj_attribute get_mvpu_img = { + .attr = { + .name = "mvpu_img_sz", + .mode = 0644, + }, + .show = mvpu_img_show, + .store = mvpu_img_store, +}; + +int mvpu25_sec_sysfs_init(struct kobject *root_dir) +{ + return sysfs_create_file(root_dir, &get_mvpu_img.attr); +} + +MODULE_IMPORT_NS(DMA_BUF); diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.h new file mode 100644 index 0000000000000..76a4a48aba6f6 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_sec.h @@ -0,0 +1,344 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __MVPU25_SEC_H__ +#define __MVPU25_SEC_H__ +#include +#include +#include +#include + +#ifndef MVPU_SECURITY +#define MVPU_SECURITY +#endif + +#ifdef MVPU_SECURITY + +//#define MVPU_SEC_BLOCK_WRONG_BUF_INFO // Forbidden (buf_num == 0 || rp_num == 0) + +#define MVPU_SEC_IMPROVE_MAP // improve info mapping + +//function switches for debug +#define MVPU_SEC_USE_MEM_POOL // Use mem pool instead of user's buf +#define MVPU_SEC_KREG_IN_POOL // Copy CMD buf KREG part to mem pool + +//#define MVPU_SEC_MPU_NUM_BLOCK // Forbidden buffer num > MVPU_MPU_SEGMENT_NUMS +#define MVPU_SEC_UPDT_MPU // Use mem pool's MPU region setting instead of engine's setting +#define MVPU_SEC_CLEAR_MPU // Clear All MPU settings + +//#define MVPU_SEC_USE_OLDEST_SESSION_ID //TBD: clear and use oldest session id +#define MVPU_SEC_USE_OLDEST_HASH_ID //TBD: clear and use oldest hash id + +//#define MVPU_SEC_BLOCK_EDMA_KERNEL // Forbidden edma in kernel code +// #define MVPU_SEC_BLOCK_EDMA_KERNEL_RETURN // FIXME: block jobs to use edma in kernel code +#define RT_BATCH_KERNEL_USING_EDMA (1 << 27) +#define RT_BATCH_HASH_EXEC_CNT ((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28)) +#define MVPU_BATCH_MASK 0x07FFFFFF +#define MVPU_ONLINE_BATCH_NAME_HASH 0xAAAAAAAA +#define MVPU_CMD_BUFF_ADDR 0x00000000 + +#define MVPU_CHK_MAX 20 + +#define MVPU_ALGO_IMG_DISABLE + +//mvpu_algo.img +//void * mvpu_algo_img; +static dma_addr_t mvpu_algo_iova; + +static uint32_t *mvpu_algo_img; +static uint32_t ker_img_offset; + +static uint32_t ptn_img_size; +static uint32_t knl_img_size; + +static bool mvpu_algo_available; + +static int mvpu_loglvl_sec; + +//image headers +#define IMG_HEADER_SIZE 4 +#define PTN_INFO_SIZE 2 +#define KER_INFO_SIZE 3 + +#define PNT_SIZE_OFFSET 1 +#define KER_SIZE_OFFSET 1 +#define KER_NUM_OFFSET 2 +#define KER_BIN_SIZE_OFFSET 3 +#define KER_BIN_INFO_SIZE 2 + +#define MVPU_ADDR_ALIGN 128 +#define MVPU_MPU_SIZE 4096 + +enum { + APUSYS_MVPU_LOG_ERR = 0, + APUSYS_MVPU_LOG_WRN = 1, + APUSYS_MVPU_LOG_INFO = 2, + APUSYS_MVPU_LOG_DBG = 3, + APUSYS_MVPU_LOG_ALL = 4, +}; + +enum buffer_attr { + BUF_NORMAL = 0, + BUF_KERNEL, + BUF_IO, + BUF_RINGBUFFER, +}; + +// mem pool use +#define MAX_SAVE_SESSION 64 +#define MAX_SAVE_HASH 128 + +static uint64_t saved_session[MAX_SAVE_SESSION]; +static uint32_t sess_oldest; + +// HASH +static struct mvpu_hash_pool *hash_pool[MAX_SAVE_SESSION]; + +struct mvpu_hash_pool { + uint32_t buf_num[MAX_SAVE_HASH]; + uint32_t rp_num[MAX_SAVE_HASH]; + uint32_t hash_list[MAX_SAVE_HASH]; + uint32_t hash_oldest; + + struct dma_heap *dma_heap[MAX_SAVE_HASH]; + struct dma_buf *hash_dma_buf[MAX_SAVE_HASH]; + struct dma_buf_attachment *attach[MAX_SAVE_HASH]; + struct sg_table *sgt[MAX_SAVE_HASH]; + + uint32_t hash_base_iova[MAX_SAVE_HASH]; + uint64_t hash_base_kva[MAX_SAVE_HASH]; + uint32_t hash_pool_size[MAX_SAVE_HASH]; + + uint32_t *sec_chk_addr[MAX_SAVE_HASH]; + +#ifdef FULL_RP_INFO + uint32_t *target_buf_old_base[MAX_SAVE_HASH]; + uint32_t *target_buf_old_offset[MAX_SAVE_HASH]; + uint32_t *target_buf_new_base[MAX_SAVE_HASH]; + uint32_t *target_buf_new_offset[MAX_SAVE_HASH]; + uint32_t *target_buf_old_map[MAX_SAVE_HASH]; + uint32_t *target_buf_new_map[MAX_SAVE_HASH]; +#endif + + uint32_t *hash_offset[MAX_SAVE_HASH]; +}; + +#define ITCM_VIRTUAL_BASE 0x19600000 +#define ITCM_VIRTUAL_BASE_END 0x19620000 +#define VIRTUAL_MVPU_TCM_BASE 0x19600000 +#define VIRTUAL_MVPU_TCM_BASE_END 0x19700000 +#define VIRTUAL_APUSYS_TCM_BASE 0x02000000 +#define VIRTUAL_APUSYS_TCM_BASE_END 0x03000000 + +enum mpu_region_shift { + ITCM_BASE_SFT = 0, + ITCM_END_SFT, + TCM_BASE_SFT, + TCM_END_SFT, + IMG_BASE_SFT, + IMG_END_SFT, + POOL_BASE_SFT, + POOL_END_SFT, + PMU_BASE_SFT, + PMU_END_SFT, + SYS_BUF_NUM, +}; + +enum KREG_OFFSET { + KREG_OFST_18 = 18, + + KREG_OFST_26 = 26, + KREG_OFST_28 = 28, + + KREG_OFST_END = 360, +}; + +enum DESC_TYPE { + DESC_TYPE_NONE = 0, + DESC_TYPE_GLSU = 1, + DESC_TYPE_EDMA = 2, + DESC_TYPE_END = 3, +}; + + +void mvpu25_set_sec_log_lvl(int log_lvl); + +// image +bool mvpu25_get_mvpu_algo_available(void); +uint32_t mvpu25_get_ptn_total_size(void); +uint32_t mvpu25_get_ptn_size(uint32_t hash); +bool mvpu25_get_ptn_hash(uint32_t hash); +uint32_t mvpu25_get_kerbin_total_size(void); +uint32_t mvpu25_get_ker_img_offset(void); + +void mvpu25_get_ker_info(uint32_t hash, uint32_t *ker_bin_offset, uint32_t *ker_bin_num); +void mvpu25_set_ker_iova(uint32_t ker_bin_offset, uint32_t ker_bin_num, uint32_t *ker_bin_each_iova); + +// buf map +void mvpu25_map_base_buf_id(uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *mem_is_kernel, + uint32_t rp_num, + uint32_t *target_old_map, + uint32_t *target_old_base, + uint32_t *target_new_map, + uint32_t *target_new_base, + uint32_t buf_cmd_kreg, + uint32_t buf_cmd_next); + +// mem pool +uint32_t mvpu25_get_saved_session_id(void *session); +uint32_t mvpu25_get_avail_session_id(void); + +void mvpu25_clear_session(void *session); + +void mvpu25_update_session_id(uint32_t session_id, void *session); + +uint32_t mvpu25_get_saved_hash_id(uint32_t session_id, uint32_t batch_name_hash); +uint32_t mvpu25_get_avail_hash_id(uint32_t session_id); + +void mvpu25_clear_hash(uint32_t session_id, uint32_t hash_id); +void mvpu25_free_all_hash(uint32_t session_id); + +int mvpu25_update_hash_pool(void *session, + bool algo_in_img, + uint32_t session_id, + uint32_t hash_id, + uint32_t batch_name_hash, + uint32_t buf_num, + void *kreg_kva, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_size, + uint32_t *sec_buf_attr); + +#ifdef FULL_RP_INFO +int mvpu25_save_hash_info(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t rp_num, + uint32_t *sec_chk_addr, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + uint32_t *target_buf_old_map, + uint32_t *target_buf_new_map); +#else +int mvpu25_save_hash_info(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t *sec_chk_addr); +#endif + +bool mvpu25_get_hash_info(void *session, + uint32_t batch_name_hash, + uint32_t *session_id, + uint32_t *hash_id, + uint32_t buf_num); + +int mvpu25_replace_img_knl(void *session, + uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_attr, + uint32_t rp_num, + uint32_t *target_buf_old_map, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + uint32_t ker_bin_num, + uint32_t *ker_bin_each_iova); + +bool mvpu25_set_rp_skip_buf(uint32_t session_id, + uint32_t hash_id, + uint32_t buf_num, + uint32_t *sec_chk_addr, + uint32_t *mem_is_kernel, + uint32_t *rp_skip_buf); + + +// replacement +int mvpu25_update_new_base_addr(bool algo_in_img, + bool algo_in_pool, + uint32_t session_id, + uint32_t hash_id, + uint32_t *sec_chk_addr, + uint32_t *mem_is_kernel, + uint32_t *rp_skip_buf, + uint32_t rp_num, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t ker_bin_num, + uint32_t *ker_bin_each_iova, + void *kreg_kva); + +int mvpu25_replace_mem(uint32_t session_id, + uint32_t hash_id, + uint32_t *mem_is_kernel, + bool algo_in_pool, + uint32_t *rp_skip_buf, + uint32_t rp_num, + uint32_t *target_buf_old_map, + uint32_t *target_buf_old_base, + uint32_t *target_buf_old_offset, + uint32_t *target_buf_new_map, + uint32_t *target_buf_new_base, + uint32_t *target_buf_new_offset, + void *kreg_kva); + +int mvpu25_replace_kerarg(void *session, + uint32_t session_id, + uint32_t hash_id, + uint32_t kerarg_num, + uint32_t *sec_chk_addr, + uint32_t *kerarg_buf_id, + uint32_t *kerarg_offset, + uint32_t *kerarg_size, + uint32_t primem_num, + uint32_t *primem_src_buf_id, + uint32_t *primem_dst_buf_id, + uint32_t *primem_src_offset, + uint32_t *primem_dst_offset, + uint32_t *primem_size); + +void mvpu25_get_pool_kreg_iova(uint32_t *kreg_iova_pool, + uint32_t session_id, + uint32_t hash_id, + uint32_t buf_cmd_kreg); + +int mvpu25_add_img_mpu(void *mvpu_cmd); + +int mvpu25_update_mpu(void *mvpu_cmd, + uint32_t session_id, + uint32_t hash_id, + uint32_t *sec_chk_addr, + uint32_t *sec_buf_size, + uint32_t *sec_buf_attr, + bool protect_phase); + +bool mvpu25_mem_use_iova(uint32_t addr); + +int mvpu25_check_iova(void *session, + void *cmd, + uint32_t desc_type, + uint32_t chk_num, + uint32_t chk_base, + uint32_t chk_size); + +int mvpu25_check_batch_flow(void *session, + void *cmd, + uint32_t sec_level, + uint32_t *kreg_kva, + uint32_t knl_num); + +int mvpu25_load_img(struct device *dev); + +int mvpu25_sec_init(struct device *dev); + +int mvpu25_sec_sysfs_init(struct kobject *root_dir); + +#endif + +#endif /* __MVPU25_SEC_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.c b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.c new file mode 100644 index 0000000000000..bc25c7f5e3a86 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.c @@ -0,0 +1,1027 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include + +#include "linux/soc/mediatek/mtk_apu_device.h" + +#include "mvpu_plat.h" +#include "mvpu_sysfs.h" +#include "mvpu25_request.h" +#include "mvpu25_sec.h" +#include "mvpu25_handler.h" +#include "mvpu25_ipi.h" + +int mvpu25_validation(void *hnd) +{ + int ret = 0; + struct mvpu_request_v25 *mvpu_req; + struct apusys_cmd_valid_handle *cmd_hnd; + void *session; + struct apusys_cmdbuf *cmdbuf; + + void *kreg_kva; +#ifdef MVPU_SEC_KREG_IN_POOL + uint32_t kreg_iova_pool = 0; +#endif + uint32_t knl_num = 0; + + uint32_t batch_name_hash; + uint32_t buf_num = 0; + uint32_t rp_num = 0; + uint32_t kerarg_num = 0; + uint32_t primem_num = 0; + uint32_t sec_level = 0; + uint32_t buf_int_check_pass = 1; + + uint32_t i = 0; + + uint32_t *sec_chk_addr = NULL; + uint32_t *sec_buf_size = NULL; + uint32_t *sec_buf_attr = NULL; + + uint32_t *target_buf_old_base = NULL; + uint32_t *target_buf_old_offset = NULL; + uint32_t *target_buf_new_base = NULL; + uint32_t *target_buf_new_offset = NULL; + + uint32_t *kerarg_buf_id = NULL; + uint32_t *kerarg_offset = NULL; + uint32_t *kerarg_size = NULL; + + uint32_t *primem_src_buf_id = NULL; + uint32_t *primem_dst_buf_id = NULL; + uint32_t *primem_src_offset = NULL; + uint32_t *primem_dst_offset = NULL; + uint32_t *primem_size = NULL; + + void *sec_chk_addr_kva = NULL; + void *sec_buf_size_kva = NULL; + void *sec_buf_attr_kva = NULL; + + void *tgtbuf_old_base_kva = NULL; + void *tgtbuf_old_ofst_kva = NULL; + void *tgtbuf_new_base_kva = NULL; + void *tgtbuf_new_ofst_kva = NULL; + + void *kerarg_buf_id_kva = NULL; + void *kerarg_offset_kva = NULL; + void *kerarg_size_kva = NULL; + + void *primem_src_buf_id_kva = NULL; + void *primem_dst_buf_id_kva = NULL; + void *primem_src_offset_kva = NULL; + void *primem_dst_offset_kva = NULL; + void *primem_size_kva = NULL; + + uint32_t *target_buf_old_map = NULL; + uint32_t *target_buf_new_map = NULL; + uint32_t *rp_skip_buf = NULL; + + bool algo_in_img = false; + uint32_t ker_bin_offset = 0; + //uint32_t ker_size = 0; + uint32_t ker_bin_num = 0; + uint32_t *ker_bin_each_iova = NULL; + + uint32_t check_buf_size = 0; + + uint32_t session_id = 0xFFFFFFFF; + uint32_t hash_id = 0xFFFFFFFF; + bool algo_in_pool = false; + bool algo_all_same_buf = true; + + uint32_t buf_cmd_cnt = 0; + uint32_t buf_cmd_kreg = 0; + uint32_t buf_cmd_next = 0; + + bool support_mod_kerarg = false; + + cmd_hnd = hnd; + + if (cmd_hnd->session == NULL) { + pr_info("[MVPU][Sec] [ERROR] APUSYS_CMD_VALIDATE: session is NULL\n"); + ret = -1; + goto END; + } else { + session = cmd_hnd->session; + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] get session: 0x%llx\n", (uint64_t)session); + } + + if (cmd_hnd->num_cmdbufs < MVPU_MIN_CMDBUF_NUM) { + pr_info("[MVPU][Sec] [ERROR] %s get wrong num_cmdbufs: %d\n", + __func__, cmd_hnd->num_cmdbufs); + ret = -1; + goto END; + } + + cmdbuf = cmd_hnd->cmdbufs; + + if (cmdbuf[MVPU_CMD_INFO_IDX].size != sizeof(struct mvpu_request_v25)) { + pr_info("[MVPU][Sec] [ERROR] get wrong cmdbuf size: 0x%x, should be 0x%zx\n", + cmdbuf[MVPU_CMD_INFO_IDX].size, + sizeof(struct mvpu_request_v25)); + ret = -1; + goto END; + } + + mvpu_req = (struct mvpu_request_v25 *)cmdbuf[MVPU_CMD_INFO_IDX].kva; + kreg_kva = cmdbuf[MVPU_CMD_KREG_BASE_IDX].kva; + + batch_name_hash = mvpu_req->batch_name_hash; + + //get buf infos + buf_num = mvpu_req->buf_num & BUF_NUM_MASK; + + //get replace infos + rp_num = mvpu_req->rp_num; + + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] DRV set batch: 0x%08x\n", batch_name_hash); + pr_info("[MVPU][Sec] buf_num %d\n", buf_num); + pr_info("[MVPU][Sec] rp_num %d\n", rp_num); + } + + if ((batch_name_hash & MVPU_BATCH_MASK) == 0x0) { + pr_info("[MVPU][IMG] [ERROR] get wrong HASH 0x%08x\n", batch_name_hash); + ret = -1; + goto END; + } + + if (mvpu_algo_available == true) + algo_in_img = mvpu25_get_ptn_hash(batch_name_hash); + + if (algo_in_img == true && mvpu25_get_mvpu_algo_available() == false) { + pr_info("[MVPU][IMG] [ERROR] get HASH 0x%08x but mvpu_algo.img is wrong, please check\n", + batch_name_hash); + ret = -1; + goto END; + } + +#ifdef MVPU_SEC_BLOCK_EDMA_KERNEL + if ((batch_name_hash & RT_BATCH_KERNEL_USING_EDMA) != 0x0) { + if (algo_in_img == false) { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] [ERROR] batch 0x%08x using EDMA function is forbiddened!!!\n", + batch_name_hash); +#ifdef MVPU_SEC_BLOCK_EDMA_KERNEL_RETURN + ret = -1; + goto END; +#endif // MVPU_SEC_BLOCK_EDMA_KERNEL_RETURN + } + } +#endif + + if (g_mvpu_platdata->sw_ver == MVPU_SW_VER_MVPU25a) { + if ((mvpu_req->feature_control_mask & MVPU_REQ_FEATURE_OSGB_LIMITED) != MVPU_REQ_FEATURE_OSGB_LIMITED) { + pr_info("[MVPU] [ERROR] binary is too old, please regenerate binary with version after SW 4.1 (include OSG patch)\n"); + strscpy(&mvpu_req->name[31], "\0", sizeof(char)); + pr_info("[MVPU] algo_name: %s\n", mvpu_req->name); + mvpu_aee_exception("MVPU", "MVPU aee"); + ret = -1; + goto END; + } + } + + mutex_lock(&mvpu25_pool_lock); + + algo_in_pool = mvpu25_get_hash_info(session, + batch_name_hash, + &session_id, + &hash_id, + buf_num); + + //get security level + sec_level = (mvpu_req->buf_num & SEC_LEVEL_MASK) >> SEC_LEVEL_SHIFT; + + if (sec_level >= SEC_LVL_END) { + pr_info("[MVPU][Sec] [WARNING] wrong sec_level %d, set to check\n", + sec_level); + sec_level = SEC_LVL_CHECK; + } + + // get kerarg setting and check support modify + kerarg_num = (mvpu_req->buf_num & KERARG_NUM_MASK) >> KERARG_NUM_SHIFT; + if (cmdbuf[MVPU_CMD_INFO_IDX].size == sizeof(struct mvpu_request_v25)) + support_mod_kerarg = true; + + if (support_mod_kerarg == false && kerarg_num != 0) { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] [WARNING] not support ker arg modify, set to check\n"); + sec_level = SEC_LVL_CHECK; + } + + // set security level to uP + mvpu_req->header.reg_bundle_setting_0.s.kreg_0x0000_rsv1 = sec_level; + + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] sec_level %d\n", sec_level); + pr_info("[MVPU][Sec] kerarg_num %d\n", kerarg_num); + } + + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_ALL) { + pr_info("[MVPU][SEC] [MPU] Engine settings\n"); + pr_info("[MVPU][SEC] [MPU] mpu_num = %3d\n", mvpu_req->mpu_num); + for (i = 0; i < MVPU_MPU_SEGMENT_NUMS; i++) + pr_info("[MVPU][SEC] [MPU] eng mpu_reg[%3d] = 0x%08x\n", + i, mvpu_req->mpu_seg[i]); + } + + if (mvpu25_mem_use_iova(mvpu_req->pmu_buff)) { + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->pmu_buff, mvpu_req->buff_size) != 0) { + pr_info("[MVPU][Sec] pmu_buff 0x%lx integrity checked FAIL\n", + (unsigned long)mvpu_req->pmu_buff); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + } + + if ((batch_name_hash & MVPU_BATCH_MASK) != + (MVPU_ONLINE_BATCH_NAME_HASH & MVPU_BATCH_MASK)) { + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->sec_chk_addr, buf_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] sec_chk_addr integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->sec_buf_size, buf_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] sec_buf_size integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->sec_buf_attr, buf_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] sec_buf_attr integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + // copy buf infos + sec_chk_addr = kcalloc(buf_num, sizeof(uint32_t), GFP_KERNEL); + if (sec_chk_addr == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + sec_chk_addr_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->sec_chk_addr); + + if (sec_chk_addr_kva != NULL) { + memcpy(sec_chk_addr, sec_chk_addr_kva, buf_num*sizeof(uint32_t)); + } else { + pr_info("[MVPU][Sec] [ERROR] sec_chk_addr_kva is NULL\n"); + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + sec_buf_size = kcalloc(buf_num, sizeof(uint32_t), GFP_KERNEL); + if (sec_buf_size == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + sec_buf_size_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->sec_buf_size); + + if (sec_buf_size_kva != NULL) { + memcpy(sec_buf_size, sec_buf_size_kva, buf_num*sizeof(uint32_t)); + } else { + pr_info("[MVPU][Sec] [ERROR] sec_buf_size_kva is NULL\n"); + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + sec_buf_attr = kcalloc(buf_num, sizeof(uint32_t), GFP_KERNEL); + if (sec_buf_attr == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + + sec_buf_attr_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->sec_buf_attr); + + if (sec_buf_attr_kva != NULL) { + memcpy(sec_buf_attr, sec_buf_attr_kva, buf_num*sizeof(uint32_t)); + } else { + pr_info("[MVPU][Sec] [ERROR] sec_buf_attr_kva is NULL\n"); + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + // buf integrity check + for (i = 0; i < buf_num; i++) { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][Sec] buf[%3d]: addr 0x%08x, attr: %d, size: 0x%08x\n", + i, sec_chk_addr[i], + sec_buf_attr[i], + sec_buf_size[i]); + } + + if (mvpu25_mem_use_iova(sec_chk_addr[i]) == false) { + if (sec_chk_addr[i] == 0) { + buf_cmd_cnt++; + if (buf_cmd_cnt == MVPU_MIN_CMDBUF_NUM) { + buf_cmd_kreg = i; + buf_cmd_next = i + 1; + } + } + continue; + } + + // check buffer integrity + if (sec_buf_attr[i] == BUF_IO) + check_buf_size = 0; + else + check_buf_size = sec_buf_size[i]; + + if (apusys_mem_validate_by_cmd(cmd_hnd->session, cmd_hnd->cmd, + (uint64_t)sec_chk_addr[i], check_buf_size) != 0) { + pr_info("[MVPU][Sec] buf[%3d]: 0x%08x integrity checked FAIL\n", + i, sec_chk_addr[i]); + buf_int_check_pass = 0; + } else { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] buf[%3d]: 0x%08x integrity checked PASS\n", + i, sec_chk_addr[i]); + } + } + + if (buf_int_check_pass == 0) { + pr_info("[MVPU][Sec] [ERROR] integrity checked FAIL\n"); + ret = -1; + goto END_WITH_MUTEX; + } + + ret = mvpu25_update_mpu(mvpu_req, session_id, hash_id, + sec_chk_addr, sec_buf_size, sec_buf_attr, false); + + if (mvpu_req->mpu_num != 0 && mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] Offline batch\n"); + pr_info("[MVPU][SEC] [MPU] mpu_num = %3d\n", mvpu_req->mpu_num); + for (i = 0; i < MVPU_MPU_SEGMENT_NUMS; i++) + pr_info("[MVPU][SEC] [MPU] drv mpu_reg[%3d] = 0x%08x\n", + i, mvpu_req->mpu_seg[i]); + } + + if (ret != 0) + goto END_WITH_MUTEX; + } + + if (algo_in_pool == false) { + if ((buf_num == 0 || rp_num == 0) || + sec_level != SEC_LVL_PROTECT) { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][Sec] check flow\n"); + + knl_num = mvpu_req->header.reg_bundle_setting_0.s.kreg_kernel_num; + ret = mvpu25_check_batch_flow(session, cmd_hnd->cmd, sec_level, kreg_kva, knl_num); + + if (ret != 0) { + pr_info("[MVPU][Sec] integrity checked FAIL\n"); + goto END_WITH_MUTEX; + } + + if (algo_in_img == false) + goto END_WITH_MUTEX; + } + } + + if (algo_in_pool == false) { + if (kerarg_num != 0) { + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->kerarg_buf_id, + kerarg_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] kerarg_buf_id integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->kerarg_offset, + kerarg_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] kerarg_offset integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->kerarg_size, + kerarg_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] kerarg_size integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + // get primem only when ker arg num != 0 & not get into check flow + primem_num = mvpu_req->primem_num; + if (primem_num != 0) { + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->primem_src_buf_id, + primem_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] primem_src_buf_id integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->primem_dst_buf_id, + primem_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] primem_dst_buf_id integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->primem_dst_offset, + primem_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] primem_dst_offset integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->primem_src_offset, + primem_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] primem_src_offset integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->primem_size, + primem_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] primem_size integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + } //(primem_num != 0) + } //(kerarg_num != 0) + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->target_buf_old_base, + rp_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] target_buf_old_base integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->target_buf_old_offset, + rp_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] target_buf_old_offset integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->target_buf_new_base, + rp_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] target_buf_new_base integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + + if (apusys_mem_validate_by_cmd(session, cmd_hnd->cmd, + (uint64_t)mvpu_req->target_buf_new_offset, + rp_num*sizeof(uint32_t)) != 0) { + pr_info("[MVPU][Sec] target_buf_new_offset integrity checked FAIL\n"); + ret = -EINVAL; + goto END_WITH_MUTEX; + } + } + + //get image infos: kernel.bin + if (algo_in_img) { + mvpu25_get_ker_info(batch_name_hash, &ker_bin_offset, &ker_bin_num); + + if (ker_bin_num == 0) { + pr_info("[MVPU][IMG] [ERROR] not found Kernel_*.bin in mvpu_algo.img, please check\n"); + ret = -1; + goto END_WITH_MUTEX; + } + + ker_bin_each_iova = kcalloc(ker_bin_num, sizeof(uint32_t), GFP_KERNEL); + if (ker_bin_each_iova == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + mvpu25_set_ker_iova(ker_bin_offset, ker_bin_num, ker_bin_each_iova); + } + + // copy ker arg infos + if (kerarg_num != 0) { + kerarg_buf_id = kcalloc(kerarg_num, sizeof(uint32_t), GFP_KERNEL); + if (kerarg_buf_id == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + kerarg_buf_id_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->kerarg_buf_id); + + if (kerarg_buf_id_kva != NULL) + memcpy(kerarg_buf_id, kerarg_buf_id_kva, kerarg_num*sizeof(uint32_t)); + + kerarg_offset = kcalloc(kerarg_num, sizeof(uint32_t), GFP_KERNEL); + if (kerarg_offset == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + kerarg_offset_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->kerarg_offset); + + if (kerarg_offset_kva != NULL) + memcpy(kerarg_offset, kerarg_offset_kva, kerarg_num*sizeof(uint32_t)); + + kerarg_size = kcalloc(kerarg_num, sizeof(uint32_t), GFP_KERNEL); + if (kerarg_size == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + kerarg_size_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->kerarg_size); + + if (kerarg_size_kva != NULL) + memcpy(kerarg_size, kerarg_size_kva, kerarg_num*sizeof(uint32_t)); + + // get primem only when ker arg num != 0 & not get into check flow + primem_num = mvpu_req->primem_num; + if (primem_num != 0) { + primem_src_buf_id = kcalloc(primem_num, sizeof(uint32_t), GFP_KERNEL); + if (primem_src_buf_id == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + primem_src_buf_id_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->primem_src_buf_id); + + if (primem_src_buf_id_kva != NULL) + memcpy(primem_src_buf_id, primem_src_buf_id_kva, + primem_num*sizeof(uint32_t)); + + primem_dst_buf_id = kcalloc(primem_num, sizeof(uint32_t), GFP_KERNEL); + if (primem_dst_buf_id == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + primem_dst_buf_id_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->primem_dst_buf_id); + + if (primem_dst_buf_id_kva != NULL) + memcpy(primem_dst_buf_id, primem_dst_buf_id_kva, + primem_num*sizeof(uint32_t)); + + primem_src_offset = kcalloc(primem_num, sizeof(uint32_t), GFP_KERNEL); + if (primem_src_offset == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + primem_src_offset_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->primem_src_offset); + + if (primem_src_offset_kva != NULL) + memcpy(primem_src_offset, primem_src_offset_kva, + primem_num*sizeof(uint32_t)); + + primem_dst_offset = kcalloc(primem_num, sizeof(uint32_t), GFP_KERNEL); + if (primem_dst_offset == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + primem_dst_offset_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->primem_dst_offset); + + if (primem_dst_offset_kva != NULL) + memcpy(primem_dst_offset, primem_dst_offset_kva, + primem_num*sizeof(uint32_t)); + + primem_size = kcalloc(primem_num, sizeof(uint32_t), GFP_KERNEL); + if (primem_size == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + primem_size_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->primem_size); + + if (primem_size_kva != NULL) + memcpy(primem_size, primem_size_kva, primem_num*sizeof(uint32_t)); + } + } + + // copy rp infos + if (rp_num != 0) { + target_buf_old_base = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_old_base == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + tgtbuf_old_base_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->target_buf_old_base); + + if (tgtbuf_old_base_kva != NULL) + memcpy(target_buf_old_base, tgtbuf_old_base_kva, rp_num*sizeof(uint32_t)); + + target_buf_old_offset = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_old_offset == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + tgtbuf_old_ofst_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->target_buf_old_offset); + + if (tgtbuf_old_ofst_kva != NULL) + memcpy(target_buf_old_offset, tgtbuf_old_ofst_kva, rp_num*sizeof(uint32_t)); + + target_buf_new_base = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_new_base == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + tgtbuf_new_base_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->target_buf_new_base); + + if (tgtbuf_new_base_kva != NULL) + memcpy(target_buf_new_base, tgtbuf_new_base_kva, rp_num*sizeof(uint32_t)); + + target_buf_new_offset = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_new_offset == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + tgtbuf_new_ofst_kva = + apusys_mem_query_kva_by_sess(session, mvpu_req->target_buf_new_offset); + + if (tgtbuf_new_ofst_kva != NULL) + memcpy(target_buf_new_offset, tgtbuf_new_ofst_kva, rp_num*sizeof(uint32_t)); + + target_buf_old_map = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_old_map == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + target_buf_new_map = kcalloc(rp_num, sizeof(uint32_t), GFP_KERNEL); + if (target_buf_new_map == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + } + + if ((sec_chk_addr != NULL) && (sec_buf_attr != NULL)) { + //map rp_info to buf_id + mvpu25_map_base_buf_id(buf_num, + sec_chk_addr, + sec_buf_attr, + rp_num, + target_buf_old_map, + target_buf_old_base, + target_buf_new_map, + target_buf_new_base, + buf_cmd_kreg, + buf_cmd_next); + } else { + pr_info("[MVPU][Sec] [ERROR] sec_chk_addr or sec_buf_attr is NULL\n"); + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + if (algo_in_pool == true) + goto REPLACE_MEM; + + // special case: check flow with image + if ((sec_level != SEC_LVL_PROTECT) && (algo_in_img == true)) { + ret = mvpu25_replace_img_knl(session, + buf_num, + sec_chk_addr, + sec_buf_attr, + rp_num, + target_buf_old_map, + target_buf_old_base, + target_buf_old_offset, + target_buf_new_map, + target_buf_new_base, + target_buf_new_offset, + ker_bin_num, + ker_bin_each_iova); + + if (mvpu_req->mpu_num != 0) + ret = mvpu25_add_img_mpu(mvpu_req); + + goto END_WITH_MUTEX; + } + + //mem pool: session/hash + if (session_id != 0xFFFFFFFF) { + if (hash_id == 0xFFFFFFFF) { + hash_id = mvpu25_get_avail_hash_id(session_id); +#ifndef MVPU_SEC_USE_OLDEST_HASH_ID + if (hash_id == 0xFFFFFFFF) { + pr_info("[MVPU][SEC] [ERROR] out of hash pool\n"); + ret = -1; + goto END_WITH_MUTEX; + } +#endif + + mvpu25_clear_hash(session_id, hash_id); + + ret = mvpu25_update_hash_pool(session, + algo_in_img, + session_id, + hash_id, + batch_name_hash, + buf_num, + kreg_kva, + sec_chk_addr, + sec_buf_size, + sec_buf_attr); + + if (ret != 0) { + pr_info("[MVPU][SEC] hash error: ret = 0x%08x\n", + ret); + mvpu25_clear_hash(session_id, hash_id); + goto END_WITH_MUTEX; + } + } + } else { + session_id = mvpu25_get_avail_session_id(); +#ifndef MVPU_SEC_USE_OLDEST_SESSION_ID + if (session_id == 0xFFFFFFFF) { + pr_info("[MVPU][SEC] [ERROR] out of session pool\n"); + ret = -1; + goto END_WITH_MUTEX; + } +#endif + + //clear_session_id(session_id); + mvpu25_update_session_id(session_id, session); + + hash_id = mvpu25_get_avail_hash_id(session_id); +#ifndef MVPU_SEC_USE_OLDEST_HASH_ID + if (hash_id == 0xFFFFFFFF) { + pr_info("[MVPU][SEC] [ERROR] out of hash pool\n"); + ret = -1; + goto END_WITH_MUTEX; + } +#endif + + mvpu25_clear_hash(session_id, hash_id); + + ret = mvpu25_update_hash_pool(session, + algo_in_img, + session_id, + hash_id, + batch_name_hash, + buf_num, + kreg_kva, + sec_chk_addr, + sec_buf_size, + sec_buf_attr); + + if (ret != 0) { + pr_info("[MVPU][SEC] hash error: ret = 0x%08x\n", + ret); + mvpu25_clear_hash(session_id, hash_id); + goto END_WITH_MUTEX; + } + } + +REPLACE_MEM: + + rp_skip_buf = kcalloc(buf_num, sizeof(uint32_t), GFP_KERNEL); + if (rp_skip_buf == NULL) { + ret = -ENOMEM; + goto END_WITH_MUTEX; + } + + if (algo_in_pool == true) { + algo_all_same_buf = mvpu25_set_rp_skip_buf(session_id, + hash_id, + buf_num, + sec_chk_addr, + sec_buf_attr, + rp_skip_buf); + + if (algo_all_same_buf == true || rp_num == 0) { + if (mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) + pr_info("[MVPU][SEC] skip replacement\n"); + goto TRIGGER_SETTING; + } + } + + ret = mvpu25_update_new_base_addr(algo_in_img, + algo_in_pool, + session_id, + hash_id, + sec_chk_addr, + sec_buf_attr, + rp_skip_buf, + rp_num, + target_buf_new_map, + target_buf_new_base, + ker_bin_num, + ker_bin_each_iova, + kreg_kva); + + if (ret != 0) + goto END_WITH_MUTEX; + +#ifdef FULL_RP_INFO + ret = mvpu25_save_hash_info(session_id, + hash_id, + buf_num, + rp_num, + sec_chk_addr, + target_buf_old_base, + target_buf_old_offset, + target_buf_new_base, + target_buf_new_offset, + target_buf_old_map, + target_buf_new_map); +#else + ret = mvpu25_save_hash_info(session_id, + hash_id, + buf_num, + sec_chk_addr); + + if (ret != 0) + goto END_WITH_MUTEX; + +#endif + + ret = mvpu25_replace_mem(session_id, hash_id, + sec_buf_attr, + algo_in_pool, + rp_skip_buf, + rp_num, + target_buf_old_map, + target_buf_old_base, + target_buf_old_offset, + target_buf_new_map, + target_buf_new_base, + target_buf_new_offset, + kreg_kva); + + if (ret != 0) + goto END_WITH_MUTEX; + + ret = mvpu25_update_mpu(mvpu_req, session_id, hash_id, + sec_chk_addr, sec_buf_size, sec_buf_attr, true); + + if (mvpu_req->mpu_num != 0 && mvpu_drv_loglv >= APUSYS_MVPU_LOG_DBG) { + pr_info("[MVPU][SEC] [MPU] mpu_num = %3d\n", mvpu_req->mpu_num); + for (i = 0; i < MVPU_MPU_SEGMENT_NUMS; i++) + pr_info("[MVPU][SEC] [MPU] drv mpu_reg[%3d] = 0x%08x\n", + i, mvpu_req->mpu_seg[i]); + } + + if (ret != 0) + goto END_WITH_MUTEX; + +TRIGGER_SETTING: +#ifdef MVPU_SEC_KREG_IN_POOL + mvpu25_get_pool_kreg_iova(&kreg_iova_pool, + session_id, + hash_id, + buf_cmd_kreg); + + // set KREG iova to uP + mvpu_req->header.reg_bundle_setting_1.dwValue = kreg_iova_pool; +#endif + + if (kerarg_num != 0 && algo_in_pool == true) { + ret = mvpu25_replace_kerarg(session, + session_id, hash_id, + kerarg_num, + sec_chk_addr, + kerarg_buf_id, + kerarg_offset, + kerarg_size, + primem_num, + primem_src_buf_id, + primem_dst_buf_id, + primem_src_offset, + primem_dst_offset, + primem_size); + } + +END_WITH_MUTEX: + mutex_unlock(&mvpu25_pool_lock); + +END: + if (sec_chk_addr != NULL) { + kfree(sec_chk_addr); + sec_chk_addr = NULL; + } + + if (sec_buf_size != NULL) { + kfree(sec_buf_size); + sec_buf_size = NULL; + } + + if (sec_buf_attr != NULL) { + kfree(sec_buf_attr); + sec_buf_attr = NULL; + } + + if (target_buf_old_base != NULL) { + kfree(target_buf_old_base); + target_buf_old_base = NULL; + } + + if (target_buf_old_offset != NULL) { + kfree(target_buf_old_offset); + target_buf_old_offset = NULL; + } + + if (target_buf_new_base != NULL) { + kfree(target_buf_new_base); + target_buf_new_base = NULL; + } + + if (target_buf_new_offset != NULL) { + kfree(target_buf_new_offset); + target_buf_new_offset = NULL; + } + + if (kerarg_buf_id != NULL) { + kfree(kerarg_buf_id); + kerarg_buf_id = NULL; + } + + if (kerarg_offset != NULL) { + kfree(kerarg_offset); + kerarg_offset = NULL; + } + + if (kerarg_size != NULL) { + kfree(kerarg_size); + kerarg_size = NULL; + } + + if (primem_src_buf_id != NULL) { + kfree(primem_src_buf_id); + primem_src_buf_id = NULL; + } + + if (primem_dst_buf_id != NULL) { + kfree(primem_dst_buf_id); + primem_dst_buf_id = NULL; + } + + if (primem_dst_offset != NULL) { + kfree(primem_dst_offset); + primem_dst_offset = NULL; + } + + if (primem_src_offset != NULL) { + kfree(primem_src_offset); + primem_src_offset = NULL; + } + + if (primem_size != NULL) { + kfree(primem_size); + primem_size = NULL; + } + + if (target_buf_old_map != NULL) { + kfree(target_buf_old_map); + target_buf_old_map = NULL; + } + + if (target_buf_new_map != NULL) { + kfree(target_buf_new_map); + target_buf_new_map = NULL; + } + + if (rp_skip_buf != NULL) { + kfree(rp_skip_buf); + rp_skip_buf = NULL; + } + + if (ker_bin_each_iova != NULL) { + kfree(ker_bin_each_iova); + ker_bin_each_iova = NULL; + } + + return ret; +} diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.h new file mode 100644 index 0000000000000..cc87fd5970119 --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/2.5/mvpu25_valid.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __MVPU25_VALID_H__ +#define __MVPU25_VALID_H__ + +int mvpu25_validation(void *hnd); + +#endif /* __MVPU25_VALID_H__ */ diff --git a/drivers/soc/mediatek/apusys/mvpu/platform/v2/mvpu2_cmd_data.h b/drivers/soc/mediatek/apusys/mvpu/platform/v2/mvpu2_cmd_data.h new file mode 100644 index 0000000000000..77e5cb6d16a1f --- /dev/null +++ b/drivers/soc/mediatek/apusys/mvpu/platform/v2/mvpu2_cmd_data.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __MVPU2_CMD_DATA_H__ +#define __MVPU2_CMD_DATA_H__ + +#define MVPU_PE_NUM 64 +#define MVPU_DUP_BUF_SIZE (2 * MVPU_PE_NUM) + +#define MVPU_REQUEST_NAME_SIZE 32 +#define MVPU_MPU_SEGMENT_NUMS 39 + +#define MVPU_MIN_CMDBUF_NUM 2 +#define MVPU_CMD_INFO_IDX 0 +#define MVPU_CMD_KREG_BASE_IDX 1 + +#define MVPU_CMD_LITE_SIZE_0 0x12E +#define MVPU_CMD_LITE_SIZE_1 0x14A + +#ifndef MVPU_SECURITY +#define MVPU_SECURITY +#endif + +#ifdef MVPU_SECURITY +#define BUF_NUM_MASK 0x0000FFFF + +#define KERARG_NUM_MASK 0x3FFF0000 +#define KERARG_NUM_SHIFT 16 + +#define SEC_LEVEL_MASK 0xC0000000 +#define SEC_LEVEL_SHIFT 30 + +enum MVPU_SEC_LEVEL { + SEC_LVL_CHECK = 0, + SEC_LVL_CHECK_ALL = 1, + SEC_LVL_PROTECT = 2, + SEC_LVL_END, +}; +#endif + +#define MVPU_REQ_FEATURE_HSE_ENABLE (1ULL << 0) +#define MVPU_REQ_FEATURE_OSGB_LIMITED (1ULL << 1) + +struct BundleHeader { + union { + unsigned int dwValue; + struct { + unsigned int kreg_bundle_thread_mode_cfg : 8; + unsigned int kreg_bundle_high_priority : 1; + unsigned int kreg_bundle_interrupt_en : 1; + unsigned int kreg_0x0000_rsv0 : 2; + unsigned int kreg_kernel_thread_mode : 2; + unsigned int kreg_0x0000_rsv1 : 2; + unsigned int kreg_kernel_num : 16; + } s; + } reg_bundle_setting_0; + + union { + unsigned int dwValue; + struct { + unsigned int kreg_bundle_cfg_base : 32; + } s; + } reg_bundle_setting_1; + + union { + unsigned int dwValue; + struct { + unsigned int kreg_bundle_event_id : 32; + } s; + } reg_bundle_setting_2; + + union { + unsigned int dwValue; + struct { + unsigned int kreg_kernel_start_cnt : 16; + unsigned int kreg_bundle_skip_dma_num : 4; + } s; + } reg_bundle_setting_3; +}; + +#endif /* __MVPU2_CMD_DATA_H__ */ diff --git a/drivers/soc/mediatek/apusys/slbc_ops.h b/drivers/soc/mediatek/apusys/slbc_ops.h new file mode 100644 index 0000000000000..027901ba35f52 --- /dev/null +++ b/drivers/soc/mediatek/apusys/slbc_ops.h @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _SLBC_OPS_H_ +#define _SLBC_OPS_H_ +#include +#include +#include +/* error code */ +#define EWAIT_RELEASE 1 /* wait for release */ +#define ENOT_AVAILABLE 2 /* not available for now */ +#define EREQ_DONE 3 /* already requested */ +#define EREQ_MASKED 4 /* req madk bit set */ +#define EDISABLED 5 /* req madk bit set */ +#define EID_WRONG 6 /* wrong id */ +#define EREF_NOT_ZERO 7 /* ref not zero */ +#define EREQ_TIMEOUT 8 /* req timeout */ +#define EREQ_WAIT_FAIL 9 /* req wait fail */ +#define EREQ_GID_RUN_OUT 10 /* req wait fail */ +/* call back return value */ +#define CB_DONE 0 /* no need to use*/ +#define CB_OK 1 /* ready to use/release */ +/* slot status */ +#define SLOT_AVAILABLE 0 /* slot available*/ +#define SLOT_NOT_FOUND 1 /* slot not found */ +#define SLOT_USED 2 /* slot used */ +/* sid status */ +#define SID_NOT_FOUND 0xffff +/* SLC all cache mode magic num */ +#define SLC_DATA_MAGIC 0x51ca11ca +/* maximum number of GID */ +#define GID_MAX 64 +/* GID settings */ +#define GS_M BIT(0) +#define GS_K BIT(1) +#define GS_RD BIT(2) +#define GS_FD BIT(3) +/* need to modify slbc_uid_str */ +enum slbc_uid { + UID_ZERO = 0, + UID_MM_VENC, + UID_MM_DISP, + UID_MM_MDP, + UID_MM_VDEC, + UID_AI_MDLA, + UID_AI_ISP, + UID_GPU, + UID_HIFI3, + UID_CPU, + UID_AOV, + UID_SH_P2, + UID_SH_APU, + UID_MML, + UID_DSC_IDLE, + UID_AINR, + UID_TEST_BUFFER, /* 0x10 */ + UID_TEST_CACHE, + UID_TEST_ACP, + UID_DISP, + UID_AOV_DC, + UID_AOV_APU, + UID_AISR_APU, + UID_AISR_MML, + UID_SH_P1, + UID_SMT, + UID_APU, + UID_AOD, + UID_BIF, + UID_MM_VENC_SL, + UID_SENSOR, + UID_MM_VENC_FHD, + UID_MM_VENC_8K, + UID_MAX, +}; +#define UID_MM_BITS_1 (BIT(UID_MM_DISP) | BIT(UID_MM_MDP)) +#define BIT_IN_MM_BITS_1(x) ((x) & UID_MM_BITS_1) +#define UID_MM_BITS_2 (BIT(UID_SH_P2) | BIT(UID_SH_APU)) +#define BIT_IN_MM_BITS_2(x) ((x) & UID_MM_BITS_2) +#define UID_MM_BITS_3 (BIT(UID_MML) | BIT(UID_DISP)) +#define BIT_IN_MM_BITS_3(x) ((x) & UID_MM_BITS_3) +#define UID_MM_BITS_4 (BIT(UID_AISR_APU) | BIT(UID_AISR_MML)) +#define BIT_IN_MM_BITS_4(x) ((x) & UID_MM_BITS_4) +enum slbc_type { + TP_BUFFER = 0, + TP_CACHE, + TP_ACP, +}; +enum slbc_force { + FR_DIS = 0, + FR_CPU, + FR_GPU, + FR_APU, + FR_MAX, +}; +#define ACP_ONLY_BIT 2 +enum slbc_flag { + FG_SECURE = BIT(0), + FG_POWER = BIT(1), + FG_ACP_ONLY = BIT(ACP_ONLY_BIT), + FG_ACP_1_4 = BIT(ACP_ONLY_BIT + 1), + FG_ACP_2_4 = BIT(ACP_ONLY_BIT + 2), + FG_ACP_3_4 = BIT(ACP_ONLY_BIT + 3), + FG_ACP_4_4 = BIT(ACP_ONLY_BIT + 4), +}; +/* SLC all cache mode user id */ +enum slc_ach_uid { + ID_PD, + ID_CPU, + ID_GPU, + ID_GPU_W, + ID_OVL_R, + ID_VDEC_FRAME, + ID_VDEC_UBE, + ID_SMMU, + ID_MD, + ID_ADSP, + ID_AOV, + ID_IMG, + ID_CAM, + ID_MAE, + ID_DMR, + ID_OD, + ID_DBI, + ID_MAX, +}; +#define FG_ACP_BITS (FG_ACP_1_4 | FG_ACP_2_4 | FG_ACP_3_4 | FG_ACP_4_4) +#define SLBC_TRY_FLAG_BIT(d, bit) (((d)->flag & (bit)) == (bit)) +struct slbc_data { + unsigned int uid; + unsigned int type; + ssize_t size; + unsigned int flag; + int ret; + unsigned int timeout; + void *user_cb_data; + /* below used by slbc driver */ + void __iomem *paddr; + void __iomem *vaddr; + void __iomem *emi_paddr; + + struct_group(sid_group, + unsigned int sid; + unsigned int slot_used; + void *config; + int ref; + int pwr_ref; + struct slbc_data *private; + ); +}; +struct slbc_gid_data { + unsigned int sign; + unsigned int buffer_fd; + unsigned int producer; + unsigned int consumer; + unsigned int height; //unit: pixel + unsigned int width; //unit: pixel + unsigned int dma_size; //unit: MB + unsigned int bw; //unit: MBps + unsigned int fps; //unit: frames per sec + unsigned int flag; +}; +#define ui_to_slbc_data(d, ui) \ + do { \ + (d)->uid = ((ui) >> 24 & 0xff); \ + (d)->type = ((ui) >> 16 & 0xff); \ + (d)->flag = ((ui) >> 8 & 0xff); \ + } while (0) +#define slbc_data_to_ui(d) \ + ((((d)->uid) & 0xff) << 24 | \ + (((d)->type) & 0xff) << 16 | \ + (((d)->flag) & 0xff) << 8) +struct slbc_ops { + struct list_head node; + struct slbc_data *data; + int (*activate)(struct slbc_data *data); + int (*deactivate)(struct slbc_data *data); +}; +extern unsigned int slbc_enable; +extern unsigned int slbc_all_cache_mode; +extern char *slbc_uid_str[UID_MAX + 1]; +extern char *slc_ach_uid_str[ID_MAX + 1]; +extern int popcount(unsigned int x); +#if IS_ENABLED(CONFIG_MTK_SLBC) +extern int slbc_status(struct slbc_data *d); +extern int slbc_request(struct slbc_data *d); +extern int slbc_release(struct slbc_data *d); +extern int slbc_power_on(struct slbc_data *d); +extern int slbc_power_off(struct slbc_data *d); +extern int slbc_secure_on(struct slbc_data *d); +extern int slbc_secure_off(struct slbc_data *d); +extern int slbc_register_activate_ops(struct slbc_ops *ops); +extern int slbc_activate_status(struct slbc_data *d); +extern void slbc_update_mm_bw(unsigned int bw); +extern void slbc_update_mic_num(unsigned int num); +extern void slbc_update_inner(unsigned int inner); +extern void slbc_update_outer(unsigned int outer); +void slbc_get_gid_for_dma(struct dma_buf *dmabuf); +int slbc_gid_val(enum slc_ach_uid uid); +int slbc_gid_request(enum slc_ach_uid uid, int *gid, struct slbc_gid_data *data); +int slbc_gid_release(enum slc_ach_uid uid, int gid); +int slbc_roi_update(enum slc_ach_uid uid, int gid, struct slbc_gid_data *data); +int slbc_validate(enum slc_ach_uid uid, int gid); +int slbc_invalidate(enum slc_ach_uid uid, int gid); +int slbc_read_invalidate(enum slc_ach_uid uid, int gid, int enable); +int slbc_force_cache(enum slc_ach_uid uid, unsigned int size); +int slbc_ceil(enum slc_ach_uid uid, unsigned int ceil); +int slbc_window(unsigned int window); +int slbc_get_cache_size(enum slc_ach_uid uid); +int slbc_get_cache_hit_rate(enum slc_ach_uid uid); +int slbc_get_cache_hit_bw(enum slc_ach_uid uid); +int slbc_get_cache_usage(int *cpu, int *gpu, int *other); +#else +__weak int slbc_status(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_request(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_release(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_power_on(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_power_off(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_secure_on(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_secure_off(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak int slbc_register_activate_ops(struct slbc_ops *ops) +{ + return -EDISABLED; +}; +__weak int slbc_activate_status(struct slbc_data *d) +{ + return -EDISABLED; +}; +__weak void slbc_update_mm_bw(unsigned int bw) {} +__weak void slbc_update_mic_num(unsigned int num) {} +__weak void slbc_update_inner(unsigned int inner) {} +__weak void slbc_update_outer(unsigned int outer) {} +__weak int slbc_gid_val(enum slc_ach_uid uid) { return -EINVAL; } +__weak int slbc_gid_request(enum slc_ach_uid uid, int *gid, struct slbc_gid_data *data) +{ + return -EDISABLED; +}; +__weak int slbc_gid_release(enum slc_ach_uid uid, int gid) +{ + return -EDISABLED; +}; +__weak int slbc_roi_update(enum slc_ach_uid uid, int gid, struct slbc_gid_data *data) +{ + return -EDISABLED; +}; +__weak int slbc_validate(enum slc_ach_uid uid, int gid) +{ + return -EDISABLED; +}; +__weak int slbc_invalidate(enum slc_ach_uid uid, int gid) +{ + return -EDISABLED; +}; +__weak int slbc_read_invalidate(enum slc_ach_uid uid, int gid, int enable) +{ + return -EDISABLED; +}; +__weak int slbc_force_cache(enum slc_ach_uid uid, unsigned int size) +{ + return -EDISABLED; +} +__weak int slbc_ceil(enum slc_ach_uid uid, unsigned int ceil) +{ + return -EDISABLED; +}; +__weak int slbc_window(unsigned int window) +{ + return -EDISABLED; +}; +__weak int slbc_get_cache_size(enum slc_ach_uid uid) +{ + return -EDISABLED; +}; +__weak int slbc_get_cache_hit_rate(enum slc_ach_uid uid) +{ + return -EDISABLED; +}; +__weak int slbc_get_cache_hit_bw(enum slc_ach_uid uid) +{ + return -EDISABLED; +} +__weak int slbc_get_cache_usage(int *cpu, int *gpu, int *other) +{ + return -EDISABLED; +} +#endif /* CONFIG_MTK_SLBC */ +#endif /* _SLBC_OPS_H_ */ diff --git a/include/linux/soc/mediatek/apu_mem_def.h b/include/linux/soc/mediatek/apu_mem_def.h new file mode 100644 index 0000000000000..ca6ec3126d7a9 --- /dev/null +++ b/include/linux/soc/mediatek/apu_mem_def.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APU_MEM_DEF_H__ +#define __APUSYS_APU_MEM_DEF_H__ + +struct apu_mem_export_ops { + /* Common API */ + int (*apu_mem_alloc) (uint32_t type, uint32_t size, uint64_t *addr, + uint32_t *sid); + int (*apu_mem_free) (uint32_t sid); + int (*apu_mem_import) (uint64_t session, uint32_t sid); + int (*apu_mem_unimport) (uint64_t session, uint32_t sid); + int (*apu_mem_map) (uint64_t session, uint32_t sid, uint64_t *addr); + int (*apu_mem_unmap) (uint64_t session, uint32_t sid); + + /* Reviser only API */ + int (*apu_mem_rvs_get_vlm) (uint32_t request_size, bool force, + unsigned long *ctx, uint32_t *tcm_size); + int (*apu_mem_rvs_free_vlm) (uint32_t ctx); + int (*apu_mem_rvs_set_context) (int type, int index, uint8_t ctx); + int (*apu_mem_rvs_get_resource_vlm)(uint32_t *addr, uint32_t *size); + int (*apu_mem_rvs_get_pool_size) (uint32_t type, uint32_t *size); + + /* APUMMU only API */ + int (*apu_mem_map_iova) (uint32_t type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva); + int (*apu_mem_iova_decode) (uint64_t eva, uint64_t *iova); + int (*apu_mem_unmap_iova) (uint64_t session, uint64_t device_va, uint32_t buf_size); + int (*apu_mem_table_get) (uint64_t session, void **tbl_kva, uint32_t *size); + int (*apu_mem_table_free) (uint64_t session); + int (*apu_mem_DRAM_FB_alloc)(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num); +}; + +enum APU_MEM_TYPE { + /* memory type */ + APU_MEM_TYPE_NONE = 0x0, + APU_MEM_TYPE_DRAM, + APU_MEM_TYPE_TCM, + APU_MEM_TYPE_SLBS, + APU_MEM_TYPE_VLM, + APU_MEM_TYPE_RSV_T, + APU_MEM_TYPE_RSV_S, + APU_MEM_TYPE_EXT, + APU_MEM_TYPE_GENERAL_S, + APU_MEM_TYPE_MAX +}; + +#endif /* end of __APUSYS_APU_MEM_DEF_H__ */ diff --git a/include/linux/soc/mediatek/apu_mem_export.h b/include/linux/soc/mediatek/apu_mem_export.h new file mode 100644 index 0000000000000..2f894021519bc --- /dev/null +++ b/include/linux/soc/mediatek/apu_mem_export.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APU_MEM_EXPORT_H__ +#define __APUSYS_APU_MEM_EXPORT_H__ + +#include +#include "linux/soc/mediatek/apu_mem_def.h" + +int apu_mem_op_init(struct apu_mem_export_ops *apu_mem_init_ops); + +/* Common API */ +int apu_mem_alloc(uint32_t type, uint32_t size, uint64_t *addr, uint32_t *sid); +int apu_mem_free(uint32_t sid); +int apu_mem_import(uint64_t session, uint32_t sid); +int apu_mem_unimport(uint64_t session, uint32_t sid); +int apu_mem_map(uint64_t session, uint32_t sid, uint64_t *addr); +int apu_mem_unmap(uint64_t session, uint32_t sid); + +/* Reviser only API */ +int apu_mem_rvs_get_vlm(uint32_t request_size, bool force, unsigned long *ctx, uint32_t *tcm_size); +int apu_mem_rvs_free_vlm(uint32_t ctx); +int apu_mem_rvs_set_context(int type, int index, uint8_t ctx); +int apu_mem_rvs_get_resource_vlm(uint32_t *addr, uint32_t *size); +int apu_mem_rvs_get_pool_size(uint32_t type, uint32_t *size); + +/* APUMMU only API */ +int apu_mem_map_iova(uint32_t type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva); +int apu_mem_iova_decode(uint64_t eva, uint64_t *iova); +int apu_mem_unmap_iova(uint64_t session, uint64_t device_va, uint32_t buf_size); +int apu_mem_table_get(uint64_t session, void **tbl_kva, uint32_t *size); +int apu_mem_table_free(uint64_t session); +int apu_mem_DRAM_FB_alloc (uint64_t session, uint32_t vlm_size, uint32_t subcmd_num); + +int apummu_export_API_init(void); +#endif /* end of __APUSYS_APU_MEM_EXPORT_H__ */ diff --git a/include/linux/soc/mediatek/apu_mvpu_config.h b/include/linux/soc/mediatek/apu_mvpu_config.h new file mode 100644 index 0000000000000..af940274726ad --- /dev/null +++ b/include/linux/soc/mediatek/apu_mvpu_config.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __MVPU_CONFIG_H__ +#define __MVPU_CONFIG_H__ + +#include "linux/remoteproc/mtk_apu.h" + +int mvpu_config_init(struct mtk_apu *apu); +int mvpu_config_remove(struct mtk_apu *apu); + +#endif diff --git a/include/linux/soc/mediatek/apummu_export.h b/include/linux/soc/mediatek/apummu_export.h new file mode 100644 index 0000000000000..5e9ab157c9b7f --- /dev/null +++ b/include/linux/soc/mediatek/apummu_export.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + + +#ifndef __APUSYS_APUMMU_EXPORT_H__ +#define __APUSYS_APUMMU_EXPORT_H__ +#include + +int apummu_alloc_mem(uint32_t type, uint32_t size, uint64_t *addr, uint32_t *sid); +int apummu_free_mem(uint32_t sid); +int apummu_import_mem(uint64_t session, uint32_t sid); +int apummu_unimport_mem(uint64_t session, uint32_t sid); +// remap? map PA -> VA +int apummu_map_mem(uint64_t session, uint32_t sid, uint64_t *addr); +int apummu_unmap_mem(uint64_t session, uint32_t sid); + + +/* add for APUMMU */ + +/** + * @para: + * type -> input buffer type, plz refer to enum AMMU_BUF_TYPE + * session -> input session + * device_va -> input device_va (gonna encode to eva) + * buf_size -> input buffer size(for EVA encode) + * eva -> output eva + * @description: + * encode input addr to eva according to buffer type + * for apummu, we also record translate info into session table + */ +int apummu_iova2eva(uint32_t type, uint64_t session, uint64_t device_va, + uint64_t buf_size, uint64_t *eva); + +int apummu_eva2iova(uint64_t eva, uint64_t *iova); + +/** + * @para: + * session -> input session + * device_va -> input device_va + * buf_size -> size of the buffer + * @description: + * remove the mapping setting of the given buffer + */ +int apummu_buffer_remove(uint64_t session, uint64_t device_va, uint32_t buf_size); + +/** + * @para: + * session -> hint for searching target session table + * tbl_kva -> returned addr for session rable + * size -> returned session table size + * @description: + * return the session table according to session + */ +int apummu_table_get(uint64_t session, void **tbl_kva, uint32_t *size); + +/** + * @para: + * session -> hint for searching target session table + * @description: + * delete the session table according to session + */ +int apummu_table_free(uint64_t session); + +/** + * @para: + * session -> session id + * vlm_size -> sum of the vlm size in the APUCMD + * subcmd_num -> sum of the subcmd number in the APUCMD + * @description: + * VLM DRAM FB allocated according to vlm_size and subcmd_num + */ +int apummu_DRAM_FB_alloc(uint64_t session, uint32_t vlm_size, uint32_t subcmd_num); + +int apummu_export_API_init(void); +#endif diff --git a/include/linux/soc/mediatek/apummu_mem_def.h b/include/linux/soc/mediatek/apummu_mem_def.h new file mode 100644 index 0000000000000..ce643d928c7ce --- /dev/null +++ b/include/linux/soc/mediatek/apummu_mem_def.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __APUSYS_APUMMU_MEM_DEF_H__ +#define __APUSYS_APUMMU_MEM_DEF_H__ + +#include +#include + +enum APUMMU_MEM_TYPE { + /* memory type */ + APUMMU_MEM_TYPE_NONE = 0x0, + APUMMU_MEM_TYPE_DRAM, + APUMMU_MEM_TYPE_TCM, + APUMMU_MEM_TYPE_SLBS, + APUMMU_MEM_TYPE_VLM, + APUMMU_MEM_TYPE_RSV_T, + APUMMU_MEM_TYPE_RSV_S, + APUMMU_MEM_TYPE_EXT, + APUMMU_MEM_TYPE_GENERAL_S, + APUMMU_MEM_TYPE_MAX +}; + +#define USING_SELF_DMA (0) +#if USING_SELF_DMA +struct ammu_mem_map { + struct dma_buf_attachment *attach; + struct sg_table *sgt; + struct kref map_ref; + struct apummu_mem *m; + void (*get)(struct ammu_mem_map *map); + void (*put)(struct ammu_mem_map *map); +}; + +struct apummu_mem { + uint64_t kva; + uint64_t iova; + uint32_t size; + uint32_t dva_size; + + void *vaddr; + void *dbuf; + void *priv; + struct mutex mtx; + struct ammu_mem_map *map; +}; +#else // using mm_heap +struct apummu_mem { + uint64_t kva; + uint64_t iova; + uint32_t size; + + struct dma_heap *heap; + void *priv; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + struct list_head list; +}; +#endif +#endif diff --git a/include/linux/soc/mediatek/apummu_tbl.h b/include/linux/soc/mediatek/apummu_tbl.h new file mode 100644 index 0000000000000..c4cde0b190af2 --- /dev/null +++ b/include/linux/soc/mediatek/apummu_tbl.h @@ -0,0 +1,473 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef __APUMMU_TABLE_H__ +#define __APUMMU_TABLE_H__ + +/* + * This file is platform dependent + * Note the fields of vsid descirpt between iommu and smmu are different ! + */ +#define linux_ep +#define SMMU_EN + +/* TCU RCX */ +#define APUMMU_CMU_TOP_REG_BASE 0x19067000 +#define APUMMU_RCX_UPRV_TCU_REG_BASE 0x19060000 +#define APUMMU_RCX_EXTM_TCU_REG_BASE 0x19061000 +#ifdef SMMU_EN +#define APUMMU_VCORE_CONFIG_REGISTER 0x190E0CC0 +#endif + +/* VSID SRAM */ +#define APUMMU_VSID_SRAM_SIZE 0x5C00 +#define APUMMU_VSID_TBL_SIZE (0xF4) // for apummu 1.0 0x118 + +#define APUMMU_PREFIX "[apummu]" + +#ifdef linux_ep +#include +#include +#include +#include +#include + +#define LOG_ERR(x, args...) \ + pr_info(APUMMU_PREFIX "[error] %s " x, __func__, ##args) +#define LOG_WARN(x, args...) \ + pr_info(APUMMU_PREFIX "[warn] %s " x, __func__, ##args) +#define LOG_INFO(x, args...) \ + pr_info(APUMMU_PREFIX "%s " x, __func__, ##args) + +#define printf LOG_INFO + +#define DRV_Reg32(addr) \ + ioread32((void __iomem *) (uintptr_t) (addr)) +#define DRV_WriteReg32(addr, val) \ + iowrite32(val, (void __iomem *) (uintptr_t) addr) + +/* CMU */ +#define APUMMU_CMU_TOP_BASE_PTR \ + ammu_cmu_top_base +#define APUMMU_CMU_TOP_TOPOLOGY_PTR \ + (APUMMU_CMU_TOP_BASE_PTR + 0x04) +#define APUMMU_VSID_ENABLE_BASE_PTR(vsid_idx) \ + (APUMMU_CMU_TOP_BASE_PTR + ((vsid_idx) >> 5)*0x4 + 0x50) +#define APUMMU_VSID_VALID_BASE_PTR(vsid_idx) \ + (APUMMU_CMU_TOP_BASE_PTR + ((vsid_idx) >> 5)*0x4 + 0xb0) + +/* TCU */ +#define APUMMU_RCX_UPRV_TCU_BASE_PTR \ + ammu_rcx_uprv_tcu_base /* apb register, 4k */ +#define APUMMU_RCX_EXTM_TCU_BASE_PTR \ + ammu_rcx_extm_tcu_base /* apb register, 4k */ + +/* VSID BASE and DESC */ +#define APUMMU_VSID_BASE_PTR \ + (APUMMU_CMU_TOP_BASE_PTR + 0x1000) +#define APUMMU_VSID_DESC_BASE_PTR \ + (APUMMU_VSID_BASE_PTR + 0x400) //apb sram +#define APUMMU_VSID_DESC_PTR(vsid_idx) \ + (APUMMU_VSID_DESC_BASE_PTR + (vsid_idx)*APUMMU_VSID_TBL_SIZE) +#define APUMMU_VSID_PTR(vsid_idx) \ + (APUMMU_VSID_BASE_PTR + (vsid_idx)*4) +#define APUMMU_VSID_DESC(vsid_idx) \ + (APUMMU_CMU_TOP_REG_BASE + 0x1400 + (vsid_idx)*APUMMU_VSID_TBL_SIZE) + +/* VSID table descript base + * 0:0x00, 1:0x04, 2:0x08, 3:0x0C; seg_idx: 0-9 + */ +#define APUMMU_VSID_SEGMENT_BASE_PTR(vsid_idx, seg_idx, seg_offset) \ + (APUMMU_VSID_DESC_PTR(vsid_idx) + (seg_idx)*0xC + (seg_offset)*0x04 + 0x4) + +#define APUMMU_VSID_SEGMENT_EN_BASE(vsid_idx) \ + (APUMMU_VSID_DESC_PTR(vsid_idx)) + +/* Replace String for DRV_W/R */ +#define APUMMU_CMU_TOP_BASE APUMMU_CMU_TOP_BASE_PTR +#define APUMMU_RCX_UPRV_TCU_BASE APUMMU_RCX_UPRV_TCU_BASE_PTR +#define APUMMU_RCX_EXTM_TCU_BASE APUMMU_RCX_EXTM_TCU_BASE_PTR +#define APUMMU_CMU_TOP_TOPOLOGY APUMMU_CMU_TOP_TOPOLOGY_PTR +#define APUMMU_VSID APUMMU_VSID_PTR +#define APUMMU_VSID_ENABLE_BASE APUMMU_VSID_ENABLE_BASE_PTR +#define APUMMU_VSID_VALID_BASE APUMMU_VSID_VALID_BASE_PTR +#define APUMMU_VSID_SEGMENT_BASE APUMMU_VSID_SEGMENT_BASE_PTR + +#define SEC_LEVEL_NORMAL 0 + +#else /* non linux_ep, tfa boot */ + +/* TF-A system header */ +#include +#include +#include + +/* Vendor header */ +#include +#include +#include "apusys_ammu.h" + +#include "apusys_security_ctrl_perm.h" + +#define LOG_ERR(x, args...) \ + ERROR(APUMMU_PREFIX "[error] %s " x, __func__, ##args) +#define LOG_WARN(x, args...) \ + INFO(APUMMU_PREFIX "[warn] %s " x, __func__, ##args) +#define LOG_INFO(x, args...) \ + INFO(APUMMU_PREFIX "%s " x, __func__, ##args) + +#define printf LOG_INFO + +#define DRV_Reg32(addr) mmio_read_32(addr) +#define DRV_WriteReg32(addr, val) mmio_write_32(addr, val) + +/* CMU */ +#define APUMMU_CMU_TOP_BASE (APU_CMU_TOP) +#define APUMMU_CMU_TOP_TOPOLOGY \ + (APUMMU_CMU_TOP_BASE + 0x04) +#define APUMMU_VSID_ENABLE_BASE(vsid_idx) \ + (APUMMU_CMU_TOP_BASE + ((vsid_idx) >> 5)*0x4 + 0x50) +#define APUMMU_VSID_VALID_BASE(vsid_idx) \ + (APUMMU_CMU_TOP_BASE + ((vsid_idx) >> 5)*0x4 + 0xb0) + +/* TCU */ +#define APUMMU_RCX_UPRV_TCU_BASE (APU_RCX_UPRV_TCU) +#define APUMMU_RCX_EXTM_TCU_BASE (APU_RCX_EXTM_TCU) + +/* VSID BASE and DESC */ +#define APUMMU_VSID_BASE \ + (APUMMU_CMU_TOP_BASE + 0x1000) /* apb sram, 0x19068000, vsid index */ +#define APUMMU_VSID(vsid_idx) \ + (APUMMU_VSID_BASE + (vsid_idx)*4) +#define APUMMU_VSID_DESC_BASE \ + (APUMMU_VSID_BASE + 0x400) /* apb sram */ +#define APUMMU_VSID_DESC(vsid_idx) \ + (APUMMU_VSID_DESC_BASE + (vsid_idx)*APUMMU_VSID_TBL_SIZE) + +/* VSID table descript base + * 0:0x00, 1:0x04, 2:0x08, 3:0x0C; seg_idx: 0-9 + */ +#define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \ + (APUMMU_VSID_DESC(vsid_idx) + (seg_idx)*0xC + (seg_offset)*0x04 + 0x4) + +#endif /* Endif of #ifdef linux_ep */ + + +//segment page len +/* + * Page length:This field indicate the segment size selection. There are several options + * page length=0-> size 128KB + * page length=1-> size 256KB + * page length=2-> size 512KB + * page length=3-> size 1MB + * page length=4-> size 128MB + * page length=5-> size 256MB + * page length=6-> size 512MB + * page length=7-> size 4GB + */ +enum eAPUMMUPAGESIZE { + eAPUMMU_PAGE_LEN_128KB = 0, + eAPUMMU_PAGE_LEN_256KB, + eAPUMMU_PAGE_LEN_512KB, + eAPUMMU_PAGE_LEN_1MB, //=3 + eAPUMMU_PAGE_LEN_128MB, + eAPUMMU_PAGE_LEN_256MB, + eAPUMMU_PAGE_LEN_512MB,//=6 + eAPUMMU_PAGE_LEN_4GB, //=7 +}; + +/* RSV VSID: uP, logger, external cpu(cpu,gpu), SAPU, AOV */ +/* (15*1024/280 = 54, 0-53) */ +/* (23*1024/280 = 84, 0-83) */ +#define APUMMU_VSID_SRAM_TOTAL \ + (APUMMU_VSID_SRAM_SIZE / APUMMU_VSID_TBL_SIZE) +#define APUMMU_RSV_VSID_DESC_IDX_END \ + (APUMMU_VSID_SRAM_TOTAL - 1) +#define APUMMU_UPRV_RSV_DESC_IDX \ + APUMMU_RSV_VSID_DESC_IDX_END /* 53:P 83:L */ +#define APUMMU_LOGGER_RSV_DESC_IDX \ + (APUMMU_RSV_VSID_DESC_IDX_END-1) /* 52:P 82:L */ +#define APUMMU_APMCU_RSV_DESC_IDX \ + (APUMMU_RSV_VSID_DESC_IDX_END-2) /* 51:P 81:L */ +#define APUMMU_GPU_RSV_DESC_IDX \ + (APUMMU_RSV_VSID_DESC_IDX_END-3) +#define APUMMU_SAPU_RSV_DESC_IDX \ + (APUMMU_RSV_VSID_DESC_IDX_END-4) +#define APUMMU_AOV_RSV_DESC_IDX \ + (APUMMU_RSV_VSID_DESC_IDX_END-5) /* 48:P 78:L */ + + +#define APUMMU_VSID_RSV (6) +#define APUMMU_VSID_ACTIVE (32) +#define APUMMU_VSID_UNUSED (12) /* unused vsid */ +#define APUMMU_VSID_USE_MAX \ + (APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV) /* 32+6 */ +#define APUMMU_VSID_SRAM_SUM \ + (APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) +/*TODO: check for preprocessor + * (APUMMU_VSID_RSV+APUMMU_VSID_ACTIVE+APUMMU_VSID_UNUSED + 1) <= APUMMU_VSID_TOTAL + */ +#if (APUMMU_VSID_SRAM_SUM > APUMMU_VSID_SRAM_TOTAL) +#error APUMMU VSID Overflow +#endif + +#define APUMMU_RSV_VSID_IDX_END 254 /* no-use 255 (number form 0-255) */ +#define APUMMU_RSV_VSID_IDX_START \ + (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1) /* 254-6+1 = 249 */ +/*TODO: check for preprocessor + *(APUMMU_RSV_VSID_END - APUMMU_RSV_VSID_START + 1) <= APUMMU_VSID_RSV + */ +#if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV) +#error APUMMU VSID RSV Overflow +#endif + +/* Reserve */ +#define APUMMU_UPRV_RSV_VSID APUMMU_RSV_VSID_IDX_END /* 254 */ +#define APUMMU_LOGGER_RSV_VSID (APUMMU_RSV_VSID_IDX_END-1) /* 253 */ +#define APUMMU_APMCU_RSV_VSID (APUMMU_RSV_VSID_IDX_END-2) /* 252 */ +#define APUMMU_GPU_RSV_VSID (APUMMU_RSV_VSID_IDX_END-3) +#define APUMMU_SAPU_RSV_VSID (APUMMU_RSV_VSID_IDX_END-4) +#define APUMMU_AOV_RSV_VSID (APUMMU_RSV_VSID_IDX_END-5) /* 249 */ +/* TODO: check the minimal rsv vsid >= APUMMU_RSV_VSID_START */ + +/* VSID bit mask */ +#define APUMMU_VSID_MAX_MASK_WORD \ + ((APUMMU_VSID_USE_MAX+32-1)/32) /* ceiling word */ + +/* VSID fields + * Get segment offset 0 data - 0x00 + */ +#define APUMMU_SEGMENT_GET_INPUT(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 0)) >> 10) & \ + 0x3fffff) +#define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 0)) >> 6) & 0xf) +#define APUMMU_SEGMENT_GET_PAGESEL(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 0)) >> 3) & 0x7) +#define APUMMU_SEGMENT_GET_PAGELEN(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 0)) >> 0) & 0x7) + +/* Get segment offset 1 data - 0x04 */ +#define APUMMU_SEGMENT_GET_OUTPUT(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 1)) >> 10) & \ + 0x3fffff) +#define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 1)) >> 2) & 0xff) +#define APUMMU_SEGMENT_GET_MMU_EN(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 1)) >> 1) & 0x1) +#define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid_idx, seg_idx) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, 1)) >> 0) & 0x1) + +/* Get segment offset 2 data - 0x08 */ +#define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 13) & \ + 0xf) +#define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 12) & 0x1) +#define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 11) & 0x1) +#define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 10) & 0x1) +#define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 9) & 0x1) +#define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 8) & 0x1) +#define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 7) & 0x1) +#define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 6) & 0x1) +#define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 5) & 0x1) +#define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 4) & 0x1) +#define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 3) & 0x1) +#define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 2) & 0x1) +#define APUMMU_SEGMENT_GET_NS(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 2)) >> 0) & 0x1) + +/* Get segment offset 3 data - 0x0c */ +#define APUMMU_SEGMENT_GET_SEG_VALID(vsid, seg) \ + ((DRV_Reg32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, 3)) >> 31) & 0x1) + +/* Build segment data + * Build segment offset 0 (0x00) data + */ +#define APUMMU_VSID_SEGMENT_00_INPUT(input_adr) \ + (((input_adr) & 0x3fffff) << 10) /* 22bits */ +#define APUMMU_VSID_SEGMENT_00_RESV(resv) \ + (((resv) & 0xf) << 6) /* 4bits */ +#define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) \ + (((page_sel) & 0x7) << 3) /* 3bits */ +#define APUMMU_VSID_SETMENT_00_PAGELEN(page_len) \ + (((page_len) & 0x7) << 0) /* 3bits */ +#define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \ + (APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \ + APUMMU_VSID_SEGMENT_00_RESV(resv) | \ + APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \ + APUMMU_VSID_SETMENT_00_PAGELEN(page_len)) + +/* Build segment offset 1 (0x04) data */ +#define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) \ + (((output_adr) & 0x3fffff) << 10) /* 22bits */ +#define APUMMU_VSID_SEGMENT_04_RESV0(resv0) \ + (((resv0) & 0xff) << 2) /* 8bits */ +#ifdef SMMU_EN +#define APUMMU_VSID_SEGMENT_04_MMU_EN(mmu_en) \ + (((!mmu_en) & 0x1) << 1) /* 1bits */ +#else +#define APUMMU_VSID_SEGMENT_04_MMU_EN(mmu_en) \ + (((mmu_en) & 0x1) << 1) /* 1bits */ +#endif +#define APUMMU_VSID_SEGMENT_04_RESV1(resv1) \ + (((resv1) & 0x1) << 0) /* 1bits */ +#define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \ + (APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \ + APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \ + APUMMU_VSID_SEGMENT_04_MMU_EN(iommu_en) | \ + APUMMU_VSID_SEGMENT_04_RESV1(resv1)) +/* Build segment offset 2 (0x08) data + * mask and shift + */ +#define APUMMU_VSID_SEGMENT_08_RESV_MASK 0x7fff +#define APUMMU_VSID_SEGMENT_08_RESV_SHIFT 17 +#define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK 0xf +#define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT 13 +// +#define APUMMU_VSID_SEGMENT_08_RESV(resv) \ + (((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << \ + APUMMU_VSID_SEGMENT_08_RESV_SHIFT) +#define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \ + (((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << \ + APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT) +#define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en) \ + (((acp_en) & 0x1) << 12) /* bool type? */ +#define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr) \ + (((aw_clr) & 0x1) << 11) +#define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid) \ + (((aw_invalid) & 0x1) << 10) +#define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu) \ + (((ar_exclu) & 0x1) << 9) +#define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu) \ + (((ar_sepcu) & 0x1) << 8) +#define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \ + (((aw_cache_allocate) & 0x1) << 7) +#define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en) \ + (((aw_slc_en) & 0x1) << 6) +#define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en) \ + (((aw_slb_en) & 0x1) << 5) +#define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \ + (((ar_cache_allocate) & 0x1) << 4) +#define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en) \ + (((ar_slc_en) & 0x1) << 3) +#define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en) \ + (((ar_slb_en) & 0x1) << 2) +#define APUMMU_VSID_SEGMENT_08_RO(ro) \ + (((ro) & 0x1) << 1) +#define APUMMU_VSID_SEGMENT_08_NS(ns) \ + (((ns) & 0x1) << 0) + +#define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \ + aw_invalid, ar_exclu, ar_sepcu, \ + aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \ + ar_slc_en, ar_slb_en, ro, ns) \ + ((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\ + (APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\ + (APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\ + (APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\ + (APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\ + (APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\ + (APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\ + (APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\ + (APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\ + (APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\ + (APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\ + (APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\ + (APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\ + (APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns))) + +/* Build segment offset 3 (0x0c) data */ +#define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) \ + (((seg_valid) & 0x1) << 31) /* 1bit */ +#define APUMMU_VSID_SEGMENT_0C_RESV(rsv) \ + (((rsv) & 0x7fffffff) << 0) /* 31bit */ +#define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \ + (APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \ + APUMMU_VSID_SEGMENT_0C_RESV(rsv)) + + + +#ifdef APUUMU_RV +struct apummu_vsid_tlb { + uint32_t cmd_id; //apucmd id by midware + uint32_t vsid_num; //vsid_num = APUMMU_VSID_MAX + uint32_t sram_mask; //tcm , slb , or tcm+sbl for this visd + uint32_t dram_mask_l; //low dram usaeg for this vsid + uint32_t dram_mask_l; //high dram usage for this vsid + apummu_apucmd_tbl *apummu_apucmd_tb; //point to apummu_apucmd_tbl_t[index] +} apummu_vsid_tbl_t; + + +//Global vsid +struct apummu_vsid { + //uint32_t tcm_mask; //granularity 512k, 16M + //uint32_t slb_mask; //granularity 512K, 16M + uint32_t tsram_mask; //sram = tcm + slb, granularity 512k, 8+8 + uint32_t tdram_mask_l; //granularity 128M, 0-4G + uint32_t tdram_mask_h; //granularity 512M, 16G, 4-16G + uint32_t vsid_mask[APUMMU_VSID_MAX_MASK_WORD]; //((32+10)+31) /32=2 + //e.g. vsid=3, use apummu_vsid_tbl_t[3] + apummu_vsid_tbl_t apummu_vsid_tbl_t[APUMMU_VSID_USE_MAX]; +} apummu_vsid_t; + + +//Global status. +struct apummu_drv { + //config + uint32_t tcm_scale; + uint32_t dram_scale; + uint64_t tcm_pa; + ///.....etc. + + //vsid + apummu_vsid_t *apummu_vsid; +} apummu_drv_t; + +//Global data structure +apummu_drv_t gApummu_drv; + +//int rv_boot(uint32_t seg_output0, uint32_t seg_output1, uint32_t seg_output2, uint8_t hw_thread); + +//@pare table +//vsid table (= dram table + sram table) + +struct apummu_vsid_tlb { + uint32_t intput_adr:22 + uint32_t reserv:4; + uint32_t page_selt: 3; + .... + + // + *ptr = &apummu_session_tbl_t //locate dram +} apummu_vsid_tbl_t[16]; + +#endif //Endof #ifdef APUUMU_RV + +int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread, + uint32_t logger_seg_output, enum eAPUMMUPAGESIZE logger_page_size, + uint32_t XPU_seg_output, enum eAPUMMUPAGESIZE XPU_page_size); + +/* got from peter */ +#define APUMMU_INT_D2T_TBL0_OFS 0x40 +enum { + APUMMU_THD_ID_APMCU_NORMAL = 0, + APUMMU_THD_ID_TEE, + APUMMU_THD_ID_MAX +}; + + + +#endif //Endof __APUMMU_TABLE_H__ diff --git a/include/linux/soc/mediatek/mtk_apu_device.h b/include/linux/soc/mediatek/mtk_apu_device.h new file mode 100644 index 0000000000000..3bce36722dfa6 --- /dev/null +++ b/include/linux/soc/mediatek/mtk_apu_device.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 MediaTek Inc. + */ + +#ifndef __MTK_APU_DEVICE_H__ +#define __MTK_APU_DEVICE_H__ + +#include + + +/* device type */ +enum { + APUSYS_DEVICE_NONE, + + APUSYS_DEVICE_SAMPLE, + APUSYS_DEVICE_MDLA, + APUSYS_DEVICE_VPU, + APUSYS_DEVICE_EDMA, + APUSYS_DEVICE_EDMA_LITE, + APUSYS_DEVICE_MVPU, + APUSYS_DEVICE_UP, + APUSYS_DEVICE_APS, + APUSYS_DEVICE_LAST, + APUSYS_DEVICE_RT = 32, + APUSYS_DEVICE_SAMPLE_RT, + APUSYS_DEVICE_MDLA_RT, + APUSYS_DEVICE_VPU_RT, + APUSYS_DEVICE_EDMA_LITE_RT, + APUSYS_DEVICE_MVPU_RT, + APUSYS_DEVICE_UP_RT, + APUSYS_DEVICE_APS_RT, + + APUSYS_DEVICE_MAX = 64, //total support 64 different devices +}; + +/* device cmd type */ +enum { + APUSYS_CMD_POWERON, + APUSYS_CMD_POWERDOWN, + APUSYS_CMD_RESUME, + APUSYS_CMD_SUSPEND, + APUSYS_CMD_EXECUTE, + APUSYS_CMD_PREEMPT, + + APUSYS_CMD_FIRMWARE, + APUSYS_CMD_USER, + APUSYS_CMD_VALIDATE, + APUSYS_CMD_SESSION_CREATE, + APUSYS_CMD_SESSION_DELETE, + + APUSYS_CMD_MAX, +}; + +/* device preempt type */ +enum { + // device don't support preemption + APUSYS_PREEMPT_NONE, + // midware should resend preempted command after preemption call + APUSYS_PREEMPT_RESEND, + // midware don't need to resend cmd, and wait preempted cmd completed + APUSYS_PREEMPT_WAITCOMPLETED, + + APUSYS_PREEMPT_MAX, +}; + +struct apusys_cmdbuf { + void *kva; + uint32_t size; +}; + +struct apusys_cmd_valid_handle { + void *session; + void *cmd; + uint32_t num_cmdbufs; + struct apusys_cmdbuf *cmdbufs; +}; + +/* device definition */ +#define APUSYS_DEVICE_META_SIZE (32) + +struct apusys_device { + uint32_t dev_type; + int idx; + int preempt_type; + uint8_t preempt_level; + char meta_data[APUSYS_DEVICE_META_SIZE]; + + void *private; // for hw driver to record private structure + + int (*send_cmd)(int type, void *hnd, struct apusys_device *dev); +}; + +int apusys_register_device(struct apusys_device *dev); +int apusys_unregister_device(struct apusys_device *dev); +int apusys_mem_validate_by_cmd(void *session, void *cmd, uint64_t eva, uint32_t size); +void *apusys_mem_query_kva_by_sess(void *session, uint64_t eva); +int apusys_mem_get_by_iova(void *session, uint64_t iova); +uint64_t apusys_mem_query_kva(uint64_t iova); +uint64_t apusys_mem_query_iova(uint64_t kva); +int apusys_mem_flush_kva(void *kva, uint32_t size); +int apusys_mem_invalidate_kva(void *kva, uint32_t size); + +#endif -- GitLab From ede209fe38d4738e8264fdb1becb9ce564164211 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 4 Nov 2024 17:44:34 +0800 Subject: [PATCH 429/456] UPSTREAM: wwan: core: Add WWAN ADB and MIPC port type Add new WWAN ports that connect to the device's ADB protocol interface and MTK MIPC diagnostic interface. Signed-off-by: Jinjian Song Reviewed-by: Sergey Ryazanov Signed-off-by: Paolo Abeni (cherry picked from commit 495e7c8e9601245738a6ab53c992cc5aa0b13cb4) Signed-off-by: qifeng.liu BUG=b:383572694 TEST=check npt tool support on nissa Change-Id: I6a18d7527b05b5b5bde567e0fc1dda82b267cb9c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6186563 Commit-Queue: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Sean Paul Reviewed-by: Daniel Winkler Reviewed-by: Ujjwal Pande Signed-off-by: Hubert Mazur --- drivers/net/wwan/wwan_core.c | 8 ++++++++ include/linux/wwan.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index 4e6709bb6a867..2c65f16bbb7e4 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -331,6 +331,14 @@ static const struct { .name = "FASTBOOT", .devsuf = "fastboot", }, + [WWAN_PORT_ADB] = { + .name = "ADB", + .devsuf = "adb", + }, + [WWAN_PORT_MIPC] = { + .name = "MIPC", + .devsuf = "mipc", + }, }; static ssize_t type_show(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/wwan.h b/include/linux/wwan.h index 2b1280308259e..9b0aa522a5f7a 100644 --- a/include/linux/wwan.h +++ b/include/linux/wwan.h @@ -18,6 +18,8 @@ * @WWAN_PORT_FIREHOSE: XML based command protocol * @WWAN_PORT_XMMRPC: Control protocol for Intel XMM modems * @WWAN_PORT_FASTBOOT: Fastboot protocol control + * @WWAN_PORT_ADB: ADB protocol control + * @WWAN_PORT_MIPC: MTK MIPC diagnostic interface * * @WWAN_PORT_MAX: Highest supported port types * @WWAN_PORT_UNKNOWN: Special value to indicate an unknown port type @@ -31,6 +33,8 @@ enum wwan_port_type { WWAN_PORT_FIREHOSE, WWAN_PORT_XMMRPC, WWAN_PORT_FASTBOOT, + WWAN_PORT_ADB, + WWAN_PORT_MIPC, /* Add new port types above this line */ -- GitLab From 0bb9b4dbe4ece87b077d9c9446470e96fe75163a Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 4 Nov 2024 17:44:35 +0800 Subject: [PATCH 430/456] UPSTREAM: net: wwan: t7xx: Add debug ports Add support for userspace to enable/disable the debug ports(ADB,MIPC). - ADB port: /dev/wwan0adb0 - MIPC port: /dev/wwan0mipc0 Application can use ADB (Android Debug Bridge) port to implement functions (shell, pull, push ...) by ADB protocol commands. E.g., ADB commands: - A_OPEN: OPEN(local-id, 0, "destination") - A_WRTE: WRITE(local-id, remote-id, "data") - A_OKEY: READY(local-id, remote-id, "") - A_CLSE: CLOSE(local-id, remote-id, "") Link: https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/README.md Application can use MIPC (Modem Information Process Center) port to debug antenna tuner or noise profiling through this MTK modem diagnostic interface. By default, debug ports are not exposed, so using the command to enable or disable debug ports. Enable debug ports: - enable: 'echo 1 > /sys/bus/pci/devices/${bdf}/t7xx_debug_ports Disable debug ports: - disable: 'echo 0 > /sys/bus/pci/devices/${bdf}/t7xx_debug_ports Signed-off-by: Jinjian Song Reviewed-by: Sergey Ryazanov Signed-off-by: Paolo Abeni (cherry picked from commit 61329a1152dd1f1c7ea75f6a8fb815f63a4440ad) Signed-off-by: qifeng.liu BUG=b:383572694 TEST=check npt tool support on nissa. Change-Id: Icd13e34acb109717c684b6069a57af512fb6fa62 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6186564 Reviewed-by: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Ujjwal Pande Commit-Queue: Daniel Winkler Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- .../networking/device_drivers/wwan/t7xx.rst | 47 +++++++++++++++ drivers/net/wwan/t7xx/t7xx_modem_ops.c | 1 + drivers/net/wwan/t7xx/t7xx_pci.c | 58 +++++++++++++++++-- drivers/net/wwan/t7xx/t7xx_pci.h | 1 + drivers/net/wwan/t7xx/t7xx_port.h | 3 + drivers/net/wwan/t7xx/t7xx_port_proxy.c | 51 ++++++++++++++-- drivers/net/wwan/t7xx/t7xx_port_proxy.h | 1 + drivers/net/wwan/t7xx/t7xx_port_wwan.c | 8 ++- 8 files changed, 157 insertions(+), 13 deletions(-) diff --git a/Documentation/networking/device_drivers/wwan/t7xx.rst b/Documentation/networking/device_drivers/wwan/t7xx.rst index f346f5f85f154..4cf777c341cd6 100644 --- a/Documentation/networking/device_drivers/wwan/t7xx.rst +++ b/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -67,6 +67,28 @@ Write from userspace to set the device mode. :: $ echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode +t7xx_debug_ports +---------------- +The sysfs interface provides userspace with access to enable/disable the debug +ports, this interface supports read and write operations. + +Debug port status: + +- ``1`` represents enable debug ports +- ``0`` represents disable debug ports + +Currently supported debug ports (ADB/MIPC). + +Read from userspace to get the current debug ports status. + +:: + $ cat /sys/bus/pci/devices/${bdf}/t7xx_debug_ports + +Write from userspace to set the debug ports status. + +:: + $ echo 1 > /sys/bus/pci/devices/${bdf}/t7xx_debug_ports + Management application development ================================== The driver and userspace interfaces are described below. The MBIM protocol is @@ -139,6 +161,25 @@ Please note that driver needs to be reloaded to export /dev/wwan0fastboot0 port, because device needs a cold reset after enter ``fastboot_switching`` mode. +ADB port userspace ABI +---------------------- + +/dev/wwan0adb0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a ADB protocol interface by implementing ADB WWAN Port. +The userspace end of the ADB channel pipe is a /dev/wwan0adb0 character device. +Application shall use this interface for ADB protocol communication. + +MIPC port userspace ABI +----------------------- + +/dev/wwan0mipc0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a diagnostic interface by implementing MIPC (Modem +Information Process Center) WWAN Port. The userspace end of the MIPC channel +pipe is a /dev/wwan0mipc0 character device. +Application shall use this interface for MTK modem diagnostic communication. + The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification. References @@ -164,3 +205,9 @@ speak the Mobile Interface Broadband Model (MBIM) protocol"* [5] *fastboot "a mechanism for communicating with bootloaders"* - https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md + +[6] *ADB (Android Debug Bridge) "a mechanism to keep track of Android devices +and emulators instances connected to or running on a given host developer +machine with ADB protocol"* + +- https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/README.md diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c index 79f17100f70b1..7968e208dd37c 100644 --- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c +++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c @@ -198,6 +198,7 @@ int t7xx_reset_device(struct t7xx_pci_dev *t7xx_dev, enum reset_type type) pci_save_state(t7xx_dev->pdev); t7xx_pci_reprobe_early(t7xx_dev); t7xx_mode_update(t7xx_dev, T7XX_RESET); + WRITE_ONCE(t7xx_dev->debug_ports_show, false); if (type == FLDR) { ret = t7xx_acpi_reset(t7xx_dev, "_RST"); diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 6da0d431d26d6..fa4627d47b318 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -41,6 +41,7 @@ #include "t7xx_pcie_mac.h" #include "t7xx_reg.h" #include "t7xx_state_monitor.h" +#include "t7xx_port_proxy.h" #define T7XX_PCI_IREG_BASE 0 #define T7XX_PCI_EREG_BASE 2 @@ -120,13 +121,58 @@ static ssize_t t7xx_mode_show(struct device *dev, static DEVICE_ATTR_RW(t7xx_mode); -static struct attribute *t7xx_mode_attr[] = { +static ssize_t t7xx_debug_ports_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + bool show; + int ret; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + ret = kstrtobool(buf, &show); + if (ret < 0) + return ret; + + t7xx_proxy_debug_ports_show(t7xx_dev, show); + WRITE_ONCE(t7xx_dev->debug_ports_show, show); + + return count; +}; + +static ssize_t t7xx_debug_ports_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct t7xx_pci_dev *t7xx_dev; + struct pci_dev *pdev; + bool show; + + pdev = to_pci_dev(dev); + t7xx_dev = pci_get_drvdata(pdev); + if (!t7xx_dev) + return -ENODEV; + + show = READ_ONCE(t7xx_dev->debug_ports_show); + + return sysfs_emit(buf, "%d\n", show); +} + +static DEVICE_ATTR_RW(t7xx_debug_ports); + +static struct attribute *t7xx_attr[] = { &dev_attr_t7xx_mode.attr, + &dev_attr_t7xx_debug_ports.attr, NULL }; -static const struct attribute_group t7xx_mode_attribute_group = { - .attrs = t7xx_mode_attr, +static const struct attribute_group t7xx_attribute_group = { + .attrs = t7xx_attr, }; void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode) @@ -839,7 +885,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) t7xx_pcie_mac_interrupts_dis(t7xx_dev); ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); if (ret) goto err_md_exit; @@ -855,7 +901,7 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_remove_group: sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); err_md_exit: t7xx_md_exit(t7xx_dev); @@ -870,7 +916,7 @@ static void t7xx_pci_remove(struct pci_dev *pdev) t7xx_dev = pci_get_drvdata(pdev); sysfs_remove_group(&t7xx_dev->pdev->dev.kobj, - &t7xx_mode_attribute_group); + &t7xx_attribute_group); t7xx_md_exit(t7xx_dev); for (i = 0; i < EXT_INT_NUM; i++) { diff --git a/drivers/net/wwan/t7xx/t7xx_pci.h b/drivers/net/wwan/t7xx/t7xx_pci.h index cd8ea17c26441..b25d867e72d29 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.h +++ b/drivers/net/wwan/t7xx/t7xx_pci.h @@ -94,6 +94,7 @@ struct t7xx_pci_dev { struct dentry *debugfs_dir; #endif u32 mode; + bool debug_ports_show; }; enum t7xx_pm_id { diff --git a/drivers/net/wwan/t7xx/t7xx_port.h b/drivers/net/wwan/t7xx/t7xx_port.h index f74d3bab810d8..9f5d6d288c97e 100644 --- a/drivers/net/wwan/t7xx/t7xx_port.h +++ b/drivers/net/wwan/t7xx/t7xx_port.h @@ -42,6 +42,8 @@ enum port_ch { /* to AP */ PORT_CH_AP_CONTROL_RX = 0x1000, PORT_CH_AP_CONTROL_TX = 0x1001, + PORT_CH_AP_ADB_RX = 0x100a, + PORT_CH_AP_ADB_TX = 0x100b, /* to MD */ PORT_CH_CONTROL_RX = 0x2000, @@ -100,6 +102,7 @@ struct t7xx_port_conf { struct port_ops *ops; char *name; enum wwan_port_type port_type; + bool debug; }; struct t7xx_port { diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.c b/drivers/net/wwan/t7xx/t7xx_port_proxy.c index 35743e7de0c30..4fc131f9632f8 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.c +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.c @@ -38,7 +38,8 @@ #include "t7xx_state_monitor.h" #define Q_IDX_CTRL 0 -#define Q_IDX_MBIM 2 +#define Q_IDX_MBIM_MIPC 2 +#define Q_IDX_ADB 3 #define Q_IDX_AT_CMD 5 #define INVALID_SEQ_NUM GENMASK(15, 0) @@ -66,8 +67,8 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { }, { .tx_ch = PORT_CH_MBIM_TX, .rx_ch = PORT_CH_MBIM_RX, - .txq_index = Q_IDX_MBIM, - .rxq_index = Q_IDX_MBIM, + .txq_index = Q_IDX_MBIM_MIPC, + .rxq_index = Q_IDX_MBIM_MIPC, .path_id = CLDMA_ID_MD, .ops = &wwan_sub_port_ops, .name = "MBIM", @@ -100,7 +101,27 @@ static const struct t7xx_port_conf t7xx_port_conf[] = { .path_id = CLDMA_ID_AP, .ops = &ctl_port_ops, .name = "t7xx_ap_ctrl", - }, + }, { + .tx_ch = PORT_CH_AP_ADB_TX, + .rx_ch = PORT_CH_AP_ADB_RX, + .txq_index = Q_IDX_ADB, + .rxq_index = Q_IDX_ADB, + .path_id = CLDMA_ID_AP, + .ops = &wwan_sub_port_ops, + .name = "adb", + .port_type = WWAN_PORT_ADB, + .debug = true, + }, { + .tx_ch = PORT_CH_MIPC_TX, + .rx_ch = PORT_CH_MIPC_RX, + .txq_index = Q_IDX_MBIM_MIPC, + .rxq_index = Q_IDX_MBIM_MIPC, + .path_id = CLDMA_ID_MD, + .ops = &wwan_sub_port_ops, + .name = "mipc", + .port_type = WWAN_PORT_MIPC, + .debug = true, + } }; static const struct t7xx_port_conf t7xx_early_port_conf[] = { @@ -505,13 +526,33 @@ static void t7xx_proxy_init_all_ports(struct t7xx_modem *md) spin_lock_init(&port->port_update_lock); port->chan_enable = false; - if (port_conf->ops && port_conf->ops->init) + if (!port_conf->debug && + port_conf->ops && + port_conf->ops->init) port_conf->ops->init(port); } t7xx_proxy_setup_ch_mapping(port_prox); } +void t7xx_proxy_debug_ports_show(struct t7xx_pci_dev *t7xx_dev, bool show) +{ + struct port_proxy *port_prox = t7xx_dev->md->port_prox; + struct t7xx_port *port; + int i; + + for_each_proxy_port(i, port, port_prox) { + const struct t7xx_port_conf *port_conf = port->port_conf; + + if (port_conf->debug && port_conf->ops) { + if (show && port_conf->ops->init) + port_conf->ops->init(port); + else if (!show && port_conf->ops->uninit) + port_conf->ops->uninit(port); + } + } +} + void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id) { struct port_proxy *port_prox = md->port_prox; diff --git a/drivers/net/wwan/t7xx/t7xx_port_proxy.h b/drivers/net/wwan/t7xx/t7xx_port_proxy.h index 7f5706811445b..f0918b36e899b 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h +++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h @@ -98,6 +98,7 @@ extern struct port_ops ctl_port_ops; extern struct port_ops t7xx_trace_port_ops; #endif +void t7xx_proxy_debug_ports_show(struct t7xx_pci_dev *t7xx_dev, bool show); void t7xx_port_proxy_reset(struct port_proxy *port_prox); void t7xx_port_proxy_uninit(struct port_proxy *port_prox); int t7xx_port_proxy_init(struct t7xx_modem *md); diff --git a/drivers/net/wwan/t7xx/t7xx_port_wwan.c b/drivers/net/wwan/t7xx/t7xx_port_wwan.c index 4b23ba693f3f1..7fc569565ff99 100644 --- a/drivers/net/wwan/t7xx/t7xx_port_wwan.c +++ b/drivers/net/wwan/t7xx/t7xx_port_wwan.c @@ -169,7 +169,9 @@ static int t7xx_port_wwan_init(struct t7xx_port *port) { const struct t7xx_port_conf *port_conf = port->port_conf; - if (port_conf->port_type == WWAN_PORT_FASTBOOT) + if (port_conf->port_type == WWAN_PORT_FASTBOOT || + port_conf->port_type == WWAN_PORT_ADB || + port_conf->port_type == WWAN_PORT_MIPC) t7xx_port_wwan_create(port); port->rx_length_th = RX_QUEUE_MAXLEN; @@ -224,7 +226,9 @@ static void t7xx_port_wwan_md_state_notify(struct t7xx_port *port, unsigned int { const struct t7xx_port_conf *port_conf = port->port_conf; - if (port_conf->port_type == WWAN_PORT_FASTBOOT) + if (port_conf->port_type == WWAN_PORT_FASTBOOT || + port_conf->port_type == WWAN_PORT_ADB || + port_conf->port_type == WWAN_PORT_MIPC) return; if (state != MD_STATE_READY) -- GitLab From 0f416111d7753d0518e54555f69958f9a469bd13 Mon Sep 17 00:00:00 2001 From: Jinjian Song Date: Mon, 4 Nov 2024 17:44:36 +0800 Subject: [PATCH 431/456] UPSTREAM: net: wwan: t7xx: Unify documentation column width Unify the column width of the document to comply with specifications. Signed-off-by: Jinjian Song Reviewed-by: Sergey Ryazanov Signed-off-by: Paolo Abeni (cherry picked from commit 238f2ca1e61fe5a2d979e25fd95b3ee26dcc1618) Signed-off-by: qifeng.liu BUG=b:383572694 TEST=check npt tool support on brya. Change-Id: Ibbc69898bab8bd211b45e1ba1998e5ca4dfcd83f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6186565 Commit-Queue: Daniel Winkler Reviewed-by: Daniel Winkler Tested-by: Daniel Winkler Reviewed-by: Ujjwal Pande Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- .../networking/device_drivers/wwan/t7xx.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Documentation/networking/device_drivers/wwan/t7xx.rst b/Documentation/networking/device_drivers/wwan/t7xx.rst index 4cf777c341cd6..e07de7700dfc9 100644 --- a/Documentation/networking/device_drivers/wwan/t7xx.rst +++ b/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -7,12 +7,13 @@ ============================================ t7xx driver for MTK PCIe based T700 5G modem ============================================ -The t7xx driver is a WWAN PCIe host driver developed for linux or Chrome OS platforms -for data exchange over PCIe interface between Host platform & MediaTek's T700 5G modem. -The driver exposes an interface conforming to the MBIM protocol [1]. Any front end -application (e.g. Modem Manager) could easily manage the MBIM interface to enable -data communication towards WWAN. The driver also provides an interface to interact -with the MediaTek's modem via AT commands. +The t7xx driver is a WWAN PCIe host driver developed for linux or Chrome OS +platforms for data exchange over PCIe interface between Host platform & +MediaTek's T700 5G modem. +The driver exposes an interface conforming to the MBIM protocol [1]. Any front +end application (e.g. Modem Manager) could easily manage the MBIM interface to +enable data communication towards WWAN. The driver also provides an interface +to interact with the MediaTek's modem via AT commands. Basic usage =========== @@ -45,8 +46,8 @@ The driver provides sysfs interfaces to userspace. t7xx_mode --------- -The sysfs interface provides userspace with access to the device mode, this interface -supports read and write operations. +The sysfs interface provides userspace with access to the device mode, this +interface supports read and write operations. Device mode: -- GitLab From 2dcf60c7c4fb78a02dbaa48e6cae493c188c7cfe Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Fri, 10 Jan 2025 09:54:14 +0800 Subject: [PATCH 432/456] BACKPORT: FROMGIT: wifi: rtw89: coex: Add protect to avoid A2DP lag while Wi-Fi connecting To get a well Wi-Fi RF quality, Wi-Fi need to do RF calibrations. While Wi-Fi is doing RF calibrations, driver will pause the Bluetooth traffic to make sure the RF calibration will not be interfered by Bluetooth. However, if the RF calibrations take too much time, Bluetooth audio will perform a lag sound. Add a function to make Bluetooth can do traffic between the individual calibrations to avoid Bluetooth sound lag. And patch related A2DP coexistence mechanism actions. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250110015416.10704-2-pkshih@realtek.com (cherry picked from commit 5251fd321684b591245a072b765d01a6c22a112c https://github.com/pkshih/rtw.git rtw-next) Conflicts: drivers/net/wireless/realtek/rtw89/rtw8851b.c (contextual conflicts) drivers/net/wireless/realtek/rtw89/rtw8852a.c (contextual conflicts) drivers/net/wireless/realtek/rtw89/rtw8852b.c (contextual conflicts) drivers/net/wireless/realtek/rtw89/rtw8852bt.c (Unmerged path) drivers/net/wireless/realtek/rtw89/rtw8852c.c (contextual conflicts) BUG=b:383905730 TEST=verify suite:wifi_matfunc and suite:bluetooth_wifi_coex on Nissa Change-Id: I18f197459f2af9e8c34298c01690703ed1b4795f Signed-off-by: Zong-Zhe Yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181454 Reviewed-by: Ruth Mekonnen Tested-by: Tim Lee Commit-Queue: Ruth Mekonnen Reviewed-by: David Ruth Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/coex.c | 90 +++++++++++-------- drivers/net/wireless/realtek/rtw89/coex.h | 2 + drivers/net/wireless/realtek/rtw89/core.h | 3 +- drivers/net/wireless/realtek/rtw89/rtw8851b.c | 6 ++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 6 ++ drivers/net/wireless/realtek/rtw89/rtw8852b.c | 6 ++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 6 ++ 7 files changed, 79 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index d636cdb60cff8..4c693ef5d558f 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4373,17 +4373,16 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev) _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + if (a2dp.vendor_id == 0x4c || dm->leak_ap || bt_linfo->slave_role) + dm->slot_dur[CXST_W1] = 20; + else + dm->slot_dur[CXST_W1] = 40; + + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + switch (btc->cx.state_map) { case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, - BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); - } else { - _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP); - } + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP); @@ -4393,15 +4392,10 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev) break; case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */ case BTC_WLINKING: /* wl-connecting + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, - BTC_ACT_BT_A2DP); - } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, - BTC_ACT_BT_A2DP); - } + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP); break; case BTC_WIDLE: /* wl-idle + bt-A2DP */ _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP); @@ -4429,7 +4423,10 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK); break; case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */ - _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DPSINK); + else + _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); break; case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */ _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK); @@ -4483,21 +4480,20 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); + if (a2dp.vendor_id == 0x4c || dm->leak_ap || bt_linfo->slave_role) + dm->slot_dur[CXST_W1] = 20; + else + dm->slot_dur[CXST_W1] = 40; + + dm->slot_dur[CXST_B1] = BTC_B1_MAX; + switch (btc->cx.state_map) { case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */ case BTC_WIDLE: /* wl-idle + bt-A2DP */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, - BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); - } else { - _set_policy(rtwdev, - BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID); - } + _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ - _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID); + _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_HID); break; case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */ @@ -4505,15 +4501,10 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) break; case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */ case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */ - if (a2dp.vendor_id == 0x4c || dm->leak_ap) { - dm->slot_dur[CXST_W1] = 40; - dm->slot_dur[CXST_B1] = 200; - _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, - BTC_ACT_BT_A2DP_HID); - } else { - _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1, - BTC_ACT_BT_A2DP_HID); - } + if (btc->cx.wl.rfk_info.con_rfk) + _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP_HID); + else + _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); break; } } @@ -6525,7 +6516,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) goto exit; } - if (wl->status.val & btc_scanning_map.val) { + if (wl->status.val & btc_scanning_map.val && !wl->rfk_info.con_rfk) { _action_wl_scan(rtwdev); bt->scan_rx_low_pri = true; goto exit; @@ -10526,3 +10517,24 @@ out: rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n", (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code); } + +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms) +{ + struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt.link_info; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + + if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) + return; + + if (!a2dp.exist) + return; + + fsleep(ms * 1000); +} +EXPORT_SYMBOL(rtw89_btc_ntfy_preserve_bt_time); + +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state) +{ + rtwdev->btc.cx.wl.rfk_info.con_rfk = state; +} +EXPORT_SYMBOL(rtw89_btc_ntfy_conn_rfk); diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h index 50a26d510bb46..dc6c7fb120929 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.h +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -285,6 +285,8 @@ void rtw89_coex_power_on(struct rtw89_dev *rtwdev); void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); +void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms); +void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state); static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 2c0ab0d361490..b6bbbf50b979b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -1621,7 +1621,8 @@ struct rtw89_btc_wl_rfk_info { u32 phy_map: 2; u32 band: 2; u32 type: 8; - u32 rsvd: 14; + u32 con_rfk: 1; + u32 rsvd: 13; u32 start_time; u32 proc_time; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 2bf91fc4dc013..9ac82f10f1122 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -1580,10 +1580,16 @@ static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev) { enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8851b_rx_dck(rtwdev, phy_idx); rtw8851b_iqk(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8851b_tssi(rtwdev, phy_idx, true); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8851b_dpk(rtwdev, phy_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index f08cdadf07dea..e7c358929493d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -1340,10 +1340,16 @@ static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev) { enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852a_rx_dck(rtwdev, phy_idx, true); rtw8852a_iqk(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852a_tssi(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852a_dpk(rtwdev, phy_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index f0c97a0627ee6..00863cb5f9d5c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -1567,10 +1567,16 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev) { enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852b_rx_dck(rtwdev, phy_idx); rtw8852b_iqk(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852b_tssi(rtwdev, phy_idx, true); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852b_dpk(rtwdev, phy_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); } static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 73294b96bf387..92b8f5b6b4fdf 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1805,10 +1805,16 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev) enum rtw89_phy_idx phy_idx = RTW89_PHY_0; rtw8852c_mcc_get_ch_info(rtwdev, phy_idx); + rtw89_btc_ntfy_conn_rfk(rtwdev, true); + rtw8852c_rx_dck(rtwdev, phy_idx, false); rtw8852c_iqk(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852c_tssi(rtwdev, phy_idx); + rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30); rtw8852c_dpk(rtwdev, phy_idx); + + rtw89_btc_ntfy_conn_rfk(rtwdev, false); rtw89_fw_h2c_rf_ntfy_mcc(rtwdev); } -- GitLab From a94f5af4282df60817a1a8e2b116163b73dbb913 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Fri, 10 Jan 2025 09:54:15 +0800 Subject: [PATCH 433/456] FROMGIT: wifi: rtw89: coex: Separated Wi-Fi connecting event from Wi-Fi scan event Wi-Fi connecting process don't need to assign to firmware slot control, if assign firmware slot control for Wi-Fi connecting event, firmware will not toggle slots because driver don't tell the slot schedule to firmware. Wi-Fi connecting event end should also cancel the 4way handshake status. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250110015416.10704-3-pkshih@realtek.com (cherry picked from commit 4a57346652154bb339c48b41166df9154cff33f5 https://github.com/pkshih/rtw.git rtw-next) BUG=b:383905730 TEST=verify suite:wifi_matfunc and suite:bluetooth_wifi_coex on Nissa Change-Id: Ib3d46e598b3e42895cf799d6cf06f4e1d4c9f883 Signed-off-by: Zong-Zhe Yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181455 Commit-Queue: Ruth Mekonnen Reviewed-by: Sean Paul Tested-by: Tim Lee Reviewed-by: Ruth Mekonnen Reviewed-by: David Ruth Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/coex.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 4c693ef5d558f..0772ffbe1ddee 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -5138,7 +5138,8 @@ static void _action_wl_scan(struct rtw89_dev *rtwdev) struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; - if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { + if (btc->cx.state_map != BTC_WLINKING && + RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { _action_wl_25g_mcc(rtwdev); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n"); } else if (rtwdev->dbcc_en) { @@ -6737,6 +6738,8 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx) _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); } + btc->dm.tdma_instant_excute = 1; + _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH); } @@ -7169,7 +7172,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif else wl->status.map.connecting = 0; - if (state == BTC_ROLE_MSTS_STA_DIS_CONN) + if (state == BTC_ROLE_MSTS_STA_DIS_CONN || + state == BTC_ROLE_MSTS_STA_CONN_END) wl->status.map._4way = false; _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO); -- GitLab From 5712690abc33d915ff70e7c5336fbcbdab745429 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Fri, 10 Jan 2025 09:54:16 +0800 Subject: [PATCH 434/456] FROMGIT: wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 7.0.2 With this version, fix Wi-Fi scan/connecting/RF calibration triggered A2DP sound lag related issues. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250110015416.10704-4-pkshih@realtek.com (cherry picked from commit dbb6a738f6cb55c542df286f028fb7d524f71077 https://github.com/pkshih/rtw.git rtw-next) BUG=b:383905730 TEST=verify suite:wifi_matfunc and suite:bluetooth_wifi_coex on Nissa Change-Id: I375326e262c40b58709399234d26b4e976aa52e9 Signed-off-by: Zong-Zhe Yang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181456 Reviewed-by: Ruth Mekonnen Tested-by: Tim Lee Reviewed-by: Sean Paul Reviewed-by: David Ruth Commit-Queue: Ruth Mekonnen Signed-off-by: Hubert Mazur --- drivers/net/wireless/realtek/rtw89/coex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 0772ffbe1ddee..48ac4af71982a 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -10,7 +10,7 @@ #include "ps.h" #include "reg.h" -#define RTW89_COEX_VERSION 0x07000113 +#define RTW89_COEX_VERSION 0x07000213 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ #define BTC_E2G_LIMIT_DEF 80 -- GitLab From c0593341a4db3549041727edbc574a089e2d60e9 Mon Sep 17 00:00:00 2001 From: Nathan Hebert Date: Wed, 15 Jan 2025 11:48:15 -0800 Subject: [PATCH 435/456] CHROMIUM: media: mediatek: vcodec: Enable HEVC main still picture MTK devices that support HEVC also support main still picture profile, but today, the main still picture profile is excluded. This removes the skip mask for HEVC, which enables the main still picture profile. BUG=b:389168730 TEST=CTS HEIC decoding tests pass UPSTREAM-TASK=b:390214569 Signed-off-by: Nathan Hebert Change-Id: I848b0d898940cd12a7a35ac889830bef68f3351d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6176726 Reviewed-by: Justin Green Reviewed-by: Hirokazu Honda Commit-Queue: ChromeOS Auto Retry Signed-off-by: Hubert Mazur --- .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c index b903e39fee892..194bc6f96c791 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c @@ -152,8 +152,6 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, .def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, - .menu_skip_mask = - BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), }, .codec_type = V4L2_PIX_FMT_HEVC_SLICE, }, -- GitLab From 6c7ed3d00a1706434ad2f4fc3a39a54cc4a0481f Mon Sep 17 00:00:00 2001 From: Alvin1 Chen Date: Wed, 22 Jan 2025 19:46:45 +0800 Subject: [PATCH 436/456] FROMLIST: drm/panel: samsung-atna33xc20: extend msleep in atana33xc20_disable to avoid glitch samsung-atna40ct03 encounters glitch when powering off, extend msleep in atana33xc20_disable to 40 can avoid this symptom. Signed-off-by: Alvin1 Chen (am from https://lore.kernel.org/all/20250122113144.1203705-1-alvin1.chen@lcfc.corp-partner.google.com/) BUG=b:387940284 UPSTREAM-TASK=b:391527789 TEST=cros workon --board rauru start chromeos-kernel-6_6 emerge-rauru chromeos-kernel-6_6 Change-Id: If3711815728a39dc14cdce8fad8b26f9f06e5537 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6189104 Reviewed-by: Yu-Che Cheng Commit-Queue: Knox Chiou Tested-by: Alvin1 Chen Reviewed-by: Knox Chiou Signed-off-by: Hubert Mazur --- drivers/gpu/drm/panel/panel-samsung-atna33xc20.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c index 6828a4f24d146..a3878ce11f44b 100644 --- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c +++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c @@ -161,10 +161,10 @@ static int atana33xc20_disable(struct drm_panel *panel) p->el3_was_on = true; /* - * Sleeping 20 ms here (after setting the GPIO) avoids a glitch when + * Sleeping 40 ms here (after setting the GPIO) avoids a glitch when * powering off. */ - msleep(20); + msleep(40); return 0; } -- GitLab From 9a425d40611a2b212ad5976f5d8c6e9e7975e63b Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 9 Jan 2025 12:59:58 -0800 Subject: [PATCH 437/456] UPSTREAM: PM: sleep: Allow configuring the DPM watchdog to warn earlier than panic Allow configuring the DPM watchdog to warn about slow suspend/resume functions without causing a system panic(). This allows you to set the DPM_WATCHDOG_WARNING_TIMEOUT to something like 5 or 10 seconds to get warnings about slow suspend/resume functions that eventually succeed. Signed-off-by: Douglas Anderson Reviewed-by: Tomasz Figa Link: https://patch.msgid.link/20250109125957.v2.1.I4554f931b8da97948f308ecc651b124338ee9603@changeid [ rjw: Subject edit ] Signed-off-by: Rafael J. Wysocki (cherry picked from commit 56cabb937f8f6091c231bdbc17c0d0a10130fb5d) BUG=b:382269699 TEST=Fake a short hang and see warning but no panic Change-Id: I4554f931b8da97948f308ecc651b124338ee9603 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6191528 Reviewed-by: Sean Paul Tested-by: Douglas Anderson Reviewed-by: Tomasz Figa Reviewed-by: Boris Mittelberg Commit-Queue: Douglas Anderson Signed-off-by: Hubert Mazur --- drivers/base/power/main.c | 24 +++++++++++++++++++----- kernel/power/Kconfig | 21 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 87d426c7192a5..5f726dda31f86 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -503,6 +503,7 @@ struct dpm_watchdog { struct device *dev; struct task_struct *tsk; struct timer_list timer; + bool fatal; }; #define DECLARE_DPM_WATCHDOG_ON_STACK(wd) \ @@ -519,11 +520,23 @@ struct dpm_watchdog { static void dpm_watchdog_handler(struct timer_list *t) { struct dpm_watchdog *wd = from_timer(wd, t, timer); + struct timer_list *timer = &wd->timer; + unsigned int time_left; + + if (wd->fatal) { + dev_emerg(wd->dev, "**** DPM device timeout ****\n"); + show_stack(wd->tsk, NULL, KERN_EMERG); + panic("%s %s: unrecoverable failure\n", + dev_driver_string(wd->dev), dev_name(wd->dev)); + } + + time_left = CONFIG_DPM_WATCHDOG_TIMEOUT - CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT; + dev_warn(wd->dev, "**** DPM device timeout after %u seconds; %u seconds until panic ****\n", + CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT, time_left); + show_stack(wd->tsk, NULL, KERN_WARNING); - dev_emerg(wd->dev, "**** DPM device timeout ****\n"); - show_stack(wd->tsk, NULL, KERN_EMERG); - panic("%s %s: unrecoverable failure\n", - dev_driver_string(wd->dev), dev_name(wd->dev)); + wd->fatal = true; + mod_timer(timer, jiffies + HZ * time_left); } /** @@ -537,10 +550,11 @@ static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev) wd->dev = dev; wd->tsk = current; + wd->fatal = CONFIG_DPM_WATCHDOG_TIMEOUT == CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT; timer_setup_on_stack(timer, dpm_watchdog_handler, 0); /* use same timeout value for both suspend and resume */ - timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_TIMEOUT; + timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT; add_timer(timer); } diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 4b31629c5be4b..f38a632ea2504 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -235,11 +235,30 @@ config DPM_WATCHDOG boot session. config DPM_WATCHDOG_TIMEOUT - int "Watchdog timeout in seconds" + int "Watchdog timeout to panic in seconds" range 1 120 default 120 depends on DPM_WATCHDOG +config DPM_WATCHDOG_WARNING_TIMEOUT + int "Watchdog timeout to warn in seconds" + range 1 DPM_WATCHDOG_TIMEOUT + default DPM_WATCHDOG_TIMEOUT + depends on DPM_WATCHDOG + help + If the DPM watchdog warning timeout and main timeout are + different then a non-fatal warning (with a stack trace of + the stuck suspend routine) will be printed when the warning + timeout expires. If the suspend routine gets un-stuck + before the main timeout expires then no other action is + taken. If the routine continues to be stuck and the main + timeout expires then an emergency-level message and stack + trace will be printed and the system will panic. + + If the warning timeout is equal to the main timeout (the + default) then the warning will never happen and the system + will jump straight to panic when the main timeout expires. + config PM_TRACE bool help -- GitLab From dd538e263e44716bd604f137ace43c8fa1a3f474 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 22 Jan 2025 13:41:17 -0800 Subject: [PATCH 438/456] CHROMIUM: config: DPM watchdog warning to 10s, panic to 30s Now that we have the ability to have the DPM watchdog warn without doing a panic, drop the warning level to 10 seconds. Bump the panic level up to 30 seconds. See for some discussion. BUG=b:382269699 TEST=Fake a delay in suspend and see warning. Change-Id: I14f2e5e548c4b10efa1e51d3d0454c94570f9bd4 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6191529 Reviewed-by: Boris Mittelberg Reviewed-by: Tomasz Figa Signed-off-by: Hubert Mazur --- chromeos/config/chromeos/arm64/common.config | 3 ++- chromeos/config/chromeos/armel/common.config | 3 ++- .../chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config | 3 ++- .../chromeos/x86_64/chromeos-intel-denverton.flavour.config | 3 ++- .../chromeos/x86_64/chromeos-intel-pineview.flavour.config | 3 ++- .../chromeos/x86_64/chromiumos-x86_64-generic.flavour.config | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/chromeos/config/chromeos/arm64/common.config b/chromeos/config/chromeos/arm64/common.config index 23d54554a62cd..bc3ccd81f8199 100644 --- a/chromeos/config/chromeos/arm64/common.config +++ b/chromeos/config/chromeos/arm64/common.config @@ -46,7 +46,8 @@ CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_PANEL_EDP=y CONFIG_ENERGY_MODEL=y diff --git a/chromeos/config/chromeos/armel/common.config b/chromeos/config/chromeos/armel/common.config index 163b786868673..1278efbef9ce9 100644 --- a/chromeos/config/chromeos/armel/common.config +++ b/chromeos/config/chromeos/armel/common.config @@ -49,7 +49,8 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y CONFIG_DEVFREQ_THERMAL=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 CONFIG_DRM_DW_HDMI_AHB_AUDIO=y CONFIG_DRM_DW_HDMI_I2S_AUDIO=y # CONFIG_DRM_FBDEV_EMULATION is not set diff --git a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config index 55b42a952469e..a710496906478 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-amd-stoneyridge.flavour.config @@ -37,7 +37,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_DEBUG_GPIO=y CONFIG_DMA_CMA=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 CONFIG_DRM_AMDGPU=y CONFIG_DRM_AMDGPU_SI=y CONFIG_DRM_AMD_ACP=y diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config index fd6ec6272ed9a..d72f2948c0617 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-denverton.flavour.config @@ -15,7 +15,8 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y # CONFIG_CPU_SUP_AMD is not set CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_I915=y CONFIG_DW_DMAC=m diff --git a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config index d9ea65c9adf8d..802e656e8a688 100644 --- a/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromeos-intel-pineview.flavour.config @@ -21,7 +21,8 @@ CONFIG_CROS_EC_ISHTP=m CONFIG_DEBUG_GPIO=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 CONFIG_DPTF_PCH_FIVR=y # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_I915=y diff --git a/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config b/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config index 27f273473f2b5..73189e0f3a99b 100644 --- a/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config +++ b/chromeos/config/chromeos/x86_64/chromiumos-x86_64-generic.flavour.config @@ -18,7 +18,8 @@ CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_DEBUG_GPIO=y CONFIG_DMADEVICES=y CONFIG_DPM_WATCHDOG=y -CONFIG_DPM_WATCHDOG_TIMEOUT=15 +CONFIG_DPM_WATCHDOG_TIMEOUT=30 +CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=10 # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_GMA500=y # CONFIG_DRM_I2C_CH7006 is not set -- GitLab From 31a6bc526c877f77ca8d05c2c3438383e04f1d22 Mon Sep 17 00:00:00 2001 From: Sarthak Kukreti Date: Thu, 23 Jan 2025 11:30:38 -0800 Subject: [PATCH 439/456] CHROMIUM: fs: Introduce passthrough attribute for blk-crypto Introduce attribute for blk-crypto passthrough. Setting this attribute will allow files to skip the blk-crypto layer. BUG=b:376100765, b:376099411 UPSTREAM-TASK=b:391902360 TEST=USE=default_key_stateful, add /mnt/stateful_partition/unencrypted 1. write to /mnt/stateful_partition/unencrypted/a.txt 2. filefrag -v a.txt to get extents 3. hexdump -C -n 100 --skip /dev/nvme0n1p1 4. Validate contents have been passed through Change-Id: I622696656924da27951c0d6fd1ce9f276e997c1a Signed-off-by: Sarthak Kukreti Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6195232 Reviewed-by: Stephen Boyd Reviewed-by: Gwendal Grignou Signed-off-by: Hubert Mazur --- fs/crypto/policy.c | 2 +- include/linux/fs.h | 3 +++ include/linux/fscrypt.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 701259991277e..f0c3722edd1fd 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -669,7 +669,7 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) return 1; /* Encrypted directories must not contain unencrypted files */ - if (!IS_ENCRYPTED(child)) + if (!IS_ENCRYPTED(child) || IS_BLKCRYPTO_PASSTHROUGH(child)) return 0; /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 82a46846955c0..79a6ba5f33f84 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2109,6 +2109,7 @@ struct super_operations { #define S_CASEFOLD (1 << 15) /* Casefolded file */ #define S_VERITY (1 << 16) /* Verity file (using fs/verity/) */ #define S_KERNEL_FILE (1 << 17) /* File is in use by the kernel (eg. fs/cachefiles) */ +#define S_BLKCRYPTO_PASSTHROUGH (1 << 18) /* File is not encrypted (using block/blk-crypto) */ /* * Note that nosuid etc flags are inode-specific: setting some file-system @@ -2155,6 +2156,8 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \ (inode)->i_rdev == WHITEOUT_DEV) +#define IS_BLKCRYPTO_PASSTHROUGH(inode) ((inode)->i_flags & S_BLKCRYPTO_PASSTHROUGH) + static inline bool HAS_UNMAPPED_ID(struct mnt_idmap *idmap, struct inode *inode) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 9945dc67ee9d9..5f44ae538b0a0 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -855,7 +855,7 @@ static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, static inline bool fscrypt_inode_should_skip_dm_default_key(const struct inode *inode) { - return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode); + return (IS_ENCRYPTED(inode) || IS_BLKCRYPTO_PASSTHROUGH(inode)) && S_ISREG(inode->i_mode); } #else static inline bool -- GitLab From 8cb75e133906b981eb92d7c1c89194a1004c7983 Mon Sep 17 00:00:00 2001 From: Sarthak Kukreti Date: Fri, 11 Oct 2024 14:49:50 -0700 Subject: [PATCH 440/456] CHROMIUM: chromiumos: Add policy for blk-crypto passthrough Annotate inodes with an attribute that allows block I/O from those inodes to be passed through blk-crypto. This is useful for inline encryption setups where the underlying layer has encryption but the files might require unencrypted usage. BUG=b:376100765, b:376099411 UPSTREAM-TASK=b:391902360 TEST=USE=default_key_stateful, add /mnt/stateful_partition/unencrypted 1. write to /mnt/stateful_partition/unencrypted/a.txt 2. filefrag -v a.txt to get extents 3. hexdump -C -n 100 --skip /dev/nvme0n1p1 4. Validate contents have been passed through Signed-off-by: Sarthak Kukreti Change-Id: I7a2aca71e2863957b2bb1753597600752f21b5da Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5926146 Reviewed-by: Gwendal Grignou Reviewed-by: Thomas Cedeno Signed-off-by: Hubert Mazur --- security/chromiumos/inode_mark.h | 1 + security/chromiumos/lsm.c | 47 ++++++++++++++++++++------------ security/chromiumos/securityfs.c | 8 ++++++ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/security/chromiumos/inode_mark.h b/security/chromiumos/inode_mark.h index ec00bb483d292..7b54068066fcd 100644 --- a/security/chromiumos/inode_mark.h +++ b/security/chromiumos/inode_mark.h @@ -32,6 +32,7 @@ enum chromiumos_inode_security_policy { enum chromiumos_inode_security_policy_type { CHROMIUMOS_SYMLINK_TRAVERSAL = 0, CHROMIUMOS_FIFO_ACCESS, + CHROMIUMOS_BLK_CRYPTO_PASSTHROUGH, CHROMIUMOS_NUMBER_OF_POLICIES, /* Do not add entries after this line. */ }; diff --git a/security/chromiumos/lsm.c b/security/chromiumos/lsm.c index 2a0777c6dd47a..e549500f4c933 100644 --- a/security/chromiumos/lsm.c +++ b/security/chromiumos/lsm.c @@ -206,25 +206,38 @@ static int chromiumos_security_file_open(struct file *file) enum chromiumos_inode_security_policy policy; struct dentry *dentry = file->f_path.dentry; - /* Returns 0 if file is not a FIFO */ - if (!S_ISFIFO(file->f_inode->i_mode)) - return 0; + if (S_ISFIFO(file->f_inode->i_mode)) { - policy = chromiumos_get_inode_security_policy( - dentry, dentry->d_inode, - CHROMIUMOS_FIFO_ACCESS); - - /* - * Emit a warning in cases of blocked fifo access attempts. These will - * show up in kernel warning reports collected by the crash reporter, - * so we have some insight on spurious failures that need addressing. - */ - WARN(policy == CHROMIUMOS_INODE_POLICY_BLOCK, - "Blocked fifo access for path %x:%x:%s\n (see https://goo.gl/8xICW6 for context and rationale)\n", - MAJOR(dentry->d_sb->s_dev), MINOR(dentry->d_sb->s_dev), - dentry_path(dentry, accessed_path, PATH_MAX)); + policy = chromiumos_get_inode_security_policy( + dentry, dentry->d_inode, + CHROMIUMOS_FIFO_ACCESS); - return policy == CHROMIUMOS_INODE_POLICY_BLOCK ? -EACCES : 0; + /* + * Emit a warning in cases of blocked fifo access attempts. These will + * show up in kernel warning reports collected by the crash reporter, + * so we have some insight on spurious failures that need addressing. + */ + WARN(policy == CHROMIUMOS_INODE_POLICY_BLOCK, + "Blocked fifo access for path %x:%x:%s\n (see https://goo.gl/8xICW6 for context and rationale)\n", + MAJOR(dentry->d_sb->s_dev), MINOR(dentry->d_sb->s_dev), + dentry_path(dentry, accessed_path, PATH_MAX)); + + return policy == CHROMIUMOS_INODE_POLICY_BLOCK ? -EACCES : 0; + } + + if (S_ISDIR(file->f_inode->i_mode) || S_ISREG(file->f_inode->i_mode)) { + + policy = chromiumos_get_inode_security_policy( + dentry, dentry->d_inode, + CHROMIUMOS_BLK_CRYPTO_PASSTHROUGH); + + if (policy == CHROMIUMOS_INODE_POLICY_ALLOW) + file->f_inode->i_flags |= S_BLKCRYPTO_PASSTHROUGH; + else + file->f_inode->i_flags &= ~S_BLKCRYPTO_PASSTHROUGH; + } + + return 0; } static int chromiumos_sb_eat_lsm_opts(char *options, void **mnt_opts) diff --git a/security/chromiumos/securityfs.c b/security/chromiumos/securityfs.c index ae2d76a08fd9f..fae89d0e2df1a 100644 --- a/security/chromiumos/securityfs.c +++ b/security/chromiumos/securityfs.c @@ -85,6 +85,14 @@ static struct chromiumos_inode_policy_file_entry .handle_write = chromiumos_inode_policy_file_write, .type = CHROMIUMOS_FIFO_ACCESS, .policy = CHROMIUMOS_INODE_POLICY_INHERIT}, + {.name = "allow_blk_crypto_passthrough", + .handle_write = chromiumos_inode_policy_file_write, + .type = CHROMIUMOS_BLK_CRYPTO_PASSTHROUGH, + .policy = CHROMIUMOS_INODE_POLICY_ALLOW}, + {.name = "reset_blk_crypto_passthrough", + .handle_write = chromiumos_inode_policy_file_write, + .type = CHROMIUMOS_BLK_CRYPTO_PASSTHROUGH, + .policy = CHROMIUMOS_INODE_POLICY_INHERIT}, {.name = "flush_policies", .handle_write = &chromiumos_inode_policy_file_flush_write}, }; -- GitLab From ce90e36606aa2a3e10d122ea429a4052b6983abb Mon Sep 17 00:00:00 2001 From: Langyan Ye Date: Thu, 23 Jan 2025 19:20:55 +0800 Subject: [PATCH 441/456] FROMGIT: drm/panel-edp: Add STA 116QHD024002 Add support for the STA 116QHD024002, pleace the EDID here for subsequent reference. 00 ff ff ff ff ff ff 00 4e 81 09 00 00 00 00 00 26 21 01 04 a5 1a 0e 78 02 1e b5 9a 5f 57 94 26 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 8e 1c 56 a0 50 00 1e 30 28 20 55 00 00 90 10 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe 00 20 20 20 20 20 20 0a 20 20 20 20 20 20 00 00 00 fe 00 31 31 36 51 48 44 30 32 34 30 30 32 0a 00 3b Signed-off-by: Langyan Ye Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20250123112055.1521471-1-yelangyan@huaqin.corp-partner.google.com (cherry picked from commit 6ce24b3450b8e8132b74d4f0b43a48f4e370e825 https://anongit.freedesktop.org/git/drm/drm-misc.git/ drm-misc-next) BUG=b:391478315 TEST=emerge-staryu sys-kernel/chromeos-kernel-5_15 Change-Id: I749d1f806b09118c1b0983a0f9326827806ac3e2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6196997 Reviewed-by: Douglas Anderson Reviewed-by: Sean Paul Tested-by: Langyan Ye Reviewed-by: Stephen Boyd Commit-Queue: Douglas Anderson Reviewed-by: Haikun Zhou (cherry picked from commit 8cef4e0c8904145e892d2bf0c57c3498bf0de0a1) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6199485 Commit-Queue: ChromeOS Auto Retry Auto-Submit: Douglas Anderson Bot-Commit: Rubber Stamper Signed-off-by: Hubert Mazur --- drivers/gpu/drm/panel/panel-edp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 8ad1bcb28fd4a..4fad5299760dd 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1953,6 +1953,12 @@ static const struct panel_delay delay_200_150_e50 = { .enable = 50, }; +static const struct panel_delay delay_200_500_e250 = { + .hpd_absent = 200, + .unprepare = 500, + .enable = 250, +}; + #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name) \ { \ .ident = { \ @@ -2136,6 +2142,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0004, &delay_200_500_e200, "116KHD024006"), + EDP_PANEL_ENTRY('S', 'T', 'A', 0x0009, &delay_200_500_e250, "116QHD024002"), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"), { /* sentinal */ } -- GitLab From 31c976277bac12334a679f950f7755e04b655894 Mon Sep 17 00:00:00 2001 From: "stefano.chu" Date: Mon, 20 Jan 2025 13:17:10 +0800 Subject: [PATCH 442/456] CHROMIUM: config: add amp TAS2781 config enable tas2781 amp driver support BUG=b:357753807 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 Change-Id: I307e4b72fcfd52b251ba38f9b37e15e9f3bd4f4f Signed-off-by: stefano.chu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181469 Reviewed-by: Fei Shao Reviewed-by: Yu-Che Cheng Reviewed-by: Hsin-Te Yuan Commit-Queue: Fei Shao Signed-off-by: Hubert Mazur --- .../config/chromeos/arm64/chromiumos-mediatek.flavour.config | 1 + 1 file changed, 1 insertion(+) diff --git a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config index 002f2656eb0fd..6628a9fe56eac 100644 --- a/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config +++ b/chromeos/config/chromeos/arm64/chromiumos-mediatek.flavour.config @@ -133,6 +133,7 @@ CONFIG_SND_SOC_SOF_MT8195=m CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y CONFIG_SND_SOC_SOF_OF=y CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_TAS2781_I2C=y CONFIG_SPI_GPIO=y CONFIG_SPI_MT65XX=y CONFIG_SPI_MTK_NOR=y -- GitLab From d7c0bcf2bdd539ea7fba4e9070d8f1d788630a75 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Mon, 27 Jan 2025 15:43:32 -0500 Subject: [PATCH 443/456] FROMLIST: drm/i915: Fix page cleanup on DMA remap failure When converting to folios the cleanup path of shmem_get_pages() was missed. When a DMA remap fails and the max segment size is greater than PAGE_SIZE it will attempt to retry the remap with a PAGE_SIZEd segment size. The cleanup code isn't properly using the folio apis and as a result isn't handling compound pages correctly. v2 -> v3: (Ville) Just use shmem_sg_free_table() as-is in the failure path of shmem_get_pages(). shmem_sg_free_table() will clear mapping unevictable but it will be reset when it retries in shmem_sg_alloc_table(). v1 -> v2: (Ville) Fixed locations where we were not clearing mapping unevictable. Cc: stable@vger.kernel.org Cc: Ville Syrjala Cc: Vidya Srinivas Link: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13487 Link: https://lore.kernel.org/lkml/20250116135636.410164-1-bgeffon@google.com/ Fixes: 0b62af28f249 ("i915: convert shmem_sg_free_table() to use a folio_batch") Signed-off-by: Brian Geffon Suggested-by: Tomasz Figa Reviewed-by: Jonathan Cavitt Tested-by: Vidya Srinivas (am from https://patchwork.kernel.org/patch/13951705/) (also found at https://lore.kernel.org/r/20250127204332.336665-1-bgeffon@google.com) BUG=b:341810357 TEST=fixes local repro Change-Id: I53426e2d57d2bf4fe790fe0bb14aab0e52d9043c Signed-off-by: Brian Geffon Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6207891 Reviewed-by: Prahlad Kilambi Reviewed-by: Sean Paul Commit-Queue: Sean Paul Reviewed-by: Drew Davenport Reviewed-by: Sean Paul Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 38b72d86560f0..c107a3a226e44 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -209,8 +209,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) struct address_space *mapping = obj->base.filp->f_mapping; unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); struct sg_table *st; - struct sgt_iter sgt_iter; - struct page *page; int ret; /* @@ -239,9 +237,7 @@ rebuild_st: * for PAGE_SIZE chunks instead may be helpful. */ if (max_segment > PAGE_SIZE) { - for_each_sgt_page(page, sgt_iter, st) - put_page(page); - sg_free_table(st); + shmem_sg_free_table(st, mapping, false, false); kfree(st); max_segment = PAGE_SIZE; -- GitLab From aaadf679235f714dc0b8d96c4e7e6784912838ee Mon Sep 17 00:00:00 2001 From: "Paul-pl.Chen" Date: Fri, 10 Jan 2025 20:33:56 +0800 Subject: [PATCH 444/456] FROMLIST: dt-bindings: arm: mediatek: mmsys: add compatible for MT8196 Add compatible for mmsys yaml of MT8196 Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935608/) (also found at https://lore.kernel.org/r/20250110123835.2719824-2-paul-pl.chen@mediatek.com) BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: I6fb1b61082747b4b2c7548c7c670dc7ea65236c7 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181666 Reviewed-by: Chen-Yu Tsai Tested-by: Eric Yilun Lin Commit-Queue: Eric Yilun Lin Reviewed-by: Pin-yen Lin Reviewed-by: Fei Shao Signed-off-by: Hubert Mazur --- .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml index b3c6888c14573..602334e993319 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml @@ -39,6 +39,11 @@ properties: - mediatek,mt8195-vdosys1 - mediatek,mt8195-vppsys0 - mediatek,mt8195-vppsys1 + - mediatek,mt8196-dispsys0 + - mediatek,mt8196-dispsys1 + - mediatek,mt8196-ovlsys0 + - mediatek,mt8196-ovlsys1 + - mediatek,mt8196-vdisp-ao - mediatek,mt8365-mmsys - const: syscon -- GitLab From af9b755926cc2348fbcafabb29b7224a0cd8acde Mon Sep 17 00:00:00 2001 From: "Paul-pl.Chen" Date: Fri, 10 Jan 2025 20:33:57 +0800 Subject: [PATCH 445/456] FROMLIST: dt-bindings: soc: mediatek: add mutex yaml for MT8196 Add compatible string to support mutex for MT8196. Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935609/) (also found at https://lore.kernel.org/r/20250110123835.2719824-3-paul-pl.chen@mediatek.com) BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: I6a4fa9990769d95b0469025c7f9b11947a1dea24 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181667 Reviewed-by: Pin-yen Lin Reviewed-by: Fei Shao Reviewed-by: Chen-Yu Tsai Tested-by: Eric Yilun Lin Commit-Queue: Eric Yilun Lin Signed-off-by: Hubert Mazur --- .../devicetree/bindings/soc/mediatek/mediatek,mutex.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml index ba2014a8725c3..6cc0be247a2b0 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml @@ -35,6 +35,7 @@ properties: - mediatek,mt8188-disp-mutex - mediatek,mt8192-disp-mutex - mediatek,mt8195-disp-mutex + - mediatek,mt8196-disp-mutex - mediatek,mt8195-vpp-mutex - mediatek,mt8365-disp-mutex @@ -86,6 +87,7 @@ allOf: - mediatek,mt8186-mdp3-mutex - mediatek,mt8192-disp-mutex - mediatek,mt8195-disp-mutex + - mediatek,mt8196-disp-mutex then: required: - clocks -- GitLab From 69e9197ac920a284925152638442a09600aaaa2a Mon Sep 17 00:00:00 2001 From: "Paul-pl.Chen" Date: Fri, 10 Jan 2025 20:33:58 +0800 Subject: [PATCH 446/456] FROMLIST: dt-bindings: display: mediatek: add EXDMA yaml for MT8196 Add mediatek,exdma.yaml to support EXDMA for MT8196. Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935618/) (also found at https://lore.kernel.org/r/20250110123835.2719824-4-paul-pl.chen@mediatek.com) BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: Id1597914954382176714a41993555a9bd76d3a04 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181668 Commit-Queue: Eric Yilun Lin Reviewed-by: Pin-yen Lin Tested-by: Eric Yilun Lin Reviewed-by: Chen-Yu Tsai Signed-off-by: Hubert Mazur --- .../display/mediatek/mediatek,exdma.yaml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,exdma.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,exdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,exdma.yaml new file mode 100644 index 0000000000000..ad15e59dcb79e --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,exdma.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,exdma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek EXDMA + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: + The MediaTek display overlap extended DMA engine, namely OVL_EXDMA or EXDMA, + primarily functions as a DMA engine for reading data from DRAM with various + DRAM footprints and data formats. For input sources in certain color formats + and color domains, OVL_EXDMA also includes a color transfer function + to process pixels into a consistent color domain. + +properties: + compatible: + const: mediatek,mt8196-exdma + + reg: + maxItems: 1 + + clocks: + items: + - description: EXDMA Clock + + power-domains: + maxItems: 1 + + mediatek,larb: + $ref: /schemas/types.yaml#/definitions/phandle + description: | + A phandle to the local arbiters node in the current SoCs. + Refer to bindings/memory-controllers/mediatek,smi-larb.yaml. + + iommus: + maxItems: 1 + + '#dma-cells': + const: 1 + +required: + - compatible + - reg + - clocks + - power-domains + - mediatek,larb + - iommus + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + disp_ovl0_exdma2: dma-controller@32850000 { + compatible = "mediatek,mt8196-exdma"; + reg = <0 0x32850000 0 0x1000>; + clocks = <&ovlsys_config_clk CLK_OVL_EXDMA2_DISP>; + power-domains = <&hfrpsys MT8196_POWER_DOMAIN_OVL0_DORMANT>; + mediatek,larb = <&smi_larb0>; + iommus = <&mm_smmu 144>; + #dma-cells = <1>; + }; + }; -- GitLab From 2fa655a164de536e5a3830aab6e4e89ac0197ad8 Mon Sep 17 00:00:00 2001 From: "Paul-pl.Chen" Date: Fri, 10 Jan 2025 20:34:00 +0800 Subject: [PATCH 447/456] FROMLIST: dt-bindings: display: mediatek: add BLENDER yaml for MT8196 Add mediatek,blender.yaml to support BLENDER for MT8196. Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935617/) (also found at https://lore.kernel.org/r/20250110123835.2719824-6-paul-pl.chen@mediatek.com) BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: I1270a80d6c2950684f397a82220d3d0779ceee9b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181669 Reviewed-by: Pin-yen Lin Reviewed-by: Chen-Yu Tsai Reviewed-by: Fei Shao Tested-by: Eric Yilun Lin Commit-Queue: Eric Yilun Lin Signed-off-by: Hubert Mazur --- .../display/mediatek/mediatek,blender.yaml | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,blender.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,blender.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,blender.yaml new file mode 100644 index 0000000000000..0bcc1a797f713 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,blender.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,blender.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Display Overlap Blender + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: + MediaTek display overlap blender, namely OVL_BLENDER or BLENDER, + executes the alpha blending function for overlapping layers + from different sources. This is the primary function of the + overlapping system. + +properties: + compatible: + const: mediatek,mt8196-blender + + reg: + maxItems: 1 + + clocks: + items: + - description: Overlap Blender Clock + +required: + - compatible + - reg + - clocks + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + disp_ovl0_blender0: blender@328d0000 { + compatible = "mediatek,mt8196-blender"; + reg = <0 0x328d0000 0 0x1000>; + clocks = <&ovlsys_config_clk CLK_OVL_BLENDER0_DISP>; + }; + }; -- GitLab From 6f8058d7f3db65f06bcb1de225e2eb3b2dd43cdd Mon Sep 17 00:00:00 2001 From: "Paul-pl.Chen" Date: Fri, 10 Jan 2025 20:34:01 +0800 Subject: [PATCH 448/456] FROMLIST: dt-bindings: display: mediatek: add binding for OUTPROC block on MT8196 Add binding to describe OUTPROC display block for MT8196. OUTPROC is used to handle the post-stage of pixel processing in the overlapping procedure. OVL_OUTPROC manages pixels for gamma correction and ensures that pixel values are within the correct range. Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935616/) (also found at https://lore.kernel.org/r/20250110123835.2719824-7-paul-pl.chen@mediatek.com) BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: If172e9934f427ec7493dd60f41e292a49a81d6b1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181670 Reviewed-by: Pin-yen Lin Reviewed-by: Chen-Yu Tsai Tested-by: Eric Yilun Lin Commit-Queue: Eric Yilun Lin Signed-off-by: Hubert Mazur --- .../display/mediatek/mediatek,outproc.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,outproc.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,outproc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,outproc.yaml new file mode 100644 index 0000000000000..b304ae41420ff --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,outproc.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,outproc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek display overlap output processor + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: | + MediaTek display overlap output processor, namely OVL_OUTPROC or OUTPROC, + handles the post-stage of pixel processing in the overlapping procedure. + OVL_OUTPROC manages pixels for gamma correction and ensures that pixel + values are within the correct range. + +properties: + compatible: + const: mediatek,mt8196-outproc + + reg: + maxItems: 1 + + clocks: + items: + - description: Overlap Output Processor Clock + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + disp_ovl0_outproc0: outproc@32970000 { + compatible = "mediatek,mt8196-outproc"; + reg = <0 0x32970000 0 0x1000>; + clocks = <&ovlsys_config_clk CLK_OVL_OUTPROC0_DISP>; + interrupts = ; + }; + }; -- GitLab From fe95a75e8172301acb77d8daa613b6eef862731a Mon Sep 17 00:00:00 2001 From: "Nancy.Lin" Date: Fri, 10 Jan 2025 20:34:02 +0800 Subject: [PATCH 449/456] BACKPORT: FROMLIST: soc: mediatek: add mmsys support for MT8196 1. Defining driver data and adding compatible string for different subsystems (DISPSYS0, DISPSYS1, OVLSYS0, OVLSYS1, VDISP_AO) 2. Adding functions to control top clocks and ddp clocks. 3. Updating the probe function to initialize clocks and enable runtime PM if its node has the power-domains property. 4. Adding functions to configure ddp components and set default configurations. 5. Adding the routing table for each mmsys in MT8196. Signed-off-by: Nancy.Lin Signed-off-by: Paul-pl.Chen (am from https://patchwork.kernel.org/patch/13935610/) (also found at https://lore.kernel.org/r/20250110123835.2719824-8-paul-pl.chen@mediatek.com) Conflicts: drivers/soc/mediatek/mtk-mmsys.c [Paul: change mtk_mmsys_remove type] drivers/soc/mediatek/mtk-mmsys.h include/linux/soc/mediatek/mtk-mmsys.h BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Signed-off-by: Paul-PL Chen Change-Id: Iaf3ab2b1b0b0750409090c7e9e47b50f22950d68 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6181671 Reviewed-by: Eric Yilun Lin Tested-by: Eric Yilun Lin Reviewed-by: Pin-yen Lin Commit-Queue: Eric Yilun Lin Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mt8196-mmsys.h | 447 +++++++++++++++++++++++++ drivers/soc/mediatek/mtk-mmsys.c | 203 ++++++++++- drivers/soc/mediatek/mtk-mmsys.h | 18 + include/linux/soc/mediatek/mtk-mmsys.h | 60 ++++ 4 files changed, 727 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/mediatek/mt8196-mmsys.h diff --git a/drivers/soc/mediatek/mt8196-mmsys.h b/drivers/soc/mediatek/mt8196-mmsys.h new file mode 100644 index 0000000000000..03d1210d2b800 --- /dev/null +++ b/drivers/soc/mediatek/mt8196-mmsys.h @@ -0,0 +1,447 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Nancy Lin + */ + +#ifndef __SOC_MEDIATEK_MT8196_MMSYS_H +#define __SOC_MEDIATEK_MT8196_MMSYS_H + +/* DISPSYS1 */ +#define MT8196_COMP_OUT_CB6_MOUT_EN 0xd30 +#define MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB0 BIT(0) +#define MT8196_COMP_OUT_CB7_MOUT_EN 0xd38 +#define MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB1 BIT(1) +#define MT8196_COMP_OUT_CB8_MOUT_EN 0xd40 +#define MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2 BIT(2) +#define MT8196_MERGE_OUT_CB0_MOUT_EN 0xdcc +#define MT8196_DISP_COMP_OUT_CB_TO_DVO0 BIT(9) +#define MT8196_MERGE_OUT_CB1_MOUT_EN 0xdd4 +#define MT8196_MERGE_OUT_CB2_MOUT_EN 0xddc +#define MT8196_DISP_COMP_OUT_CB_TO_DSI0 BIT(0) +#define MT8196_DISP_COMP_OUT_CB_TO_DP_INTF0 BIT(10) +#define MT8196_DISP_COMP_OUT_CB_TO_DP_INTF1 BIT(11) +#define MT8196_SPLITTER_IN_CB1_MOUT_EN 0xeac +#define MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB9 BIT(5) +#define MT8196_SPLITTER_IN_CB2_MOUT_EN 0xeb4 +#define MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB10 BIT(6) +#define MT8196_SPLITTER_IN_CB3_MOUT_EN 0xebc +#define MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11 BIT(7) +#define MT8196_SPLITTER_OUT_CB9_MOUT_EN 0xf64 +#define MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB6 BIT(10) +#define MT8196_SPLITTER_OUT_CB10_MOUT_EN 0xf6c +#define MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB7 BIT(11) +#define MT8196_SPLITTER_OUT_CB11_MOUT_EN 0xf74 +#define MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8 BIT(12) +#define MT8196_OVL_RSZ_IN_CB2_MOUT_EN 0xf70 +#define MT8196_DISP_OVL_EXDMA2_1_TO_OVL_EXDMA_OUT_CB3 BIT(1) + +/* OVLSYS */ +#define MT8196_OVL_BLENDER_OUT_CB4_MOUT_EN 0xe10 +#define MT8196_OVL_BLENDER_OUT_CB8_MOUT_EN 0xe20 +#define MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC0 BIT(0) +#define MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC1 BIT(1) +#define MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC2 BIT(2) +#define MT8196_OVL_EXDMA_OUT_CB2_MOUT_EN 0xe60 +#define MT8196_OVL_EXDMA_OUT_CB3_MOUT_EN 0xe68 +#define MT8196_OVL_EXDMA_OUT_CB4_MOUT_EN 0xe70 +#define MT8196_OVL_EXDMA_OUT_CB5_MOUT_EN 0xe78 +#define MT8196_OVL_EXDMA_OUT_CB6_MOUT_EN 0xe80 +#define MT8196_OVL_EXDMA_OUT_CB7_MOUT_EN 0xe88 +#define MT8196_OVL_EXDMA_OUT_CB8_MOUT_EN 0xe90 +#define MT8196_OVL_EXDMA_OUT_CB9_MOUT_EN 0xe98 +#define MT8196_OVL_EXDMA_OUT_CB10_MOUT_EN 0xea0 +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER1 BIT(2) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER2 BIT(3) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER3 BIT(4) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER4 BIT(5) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER5 BIT(6) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER6 BIT(7) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER7 BIT(8) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER8 BIT(9) +#define MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER9 BIT(10) +#define MT8196_OVL_OUTPROC_OUT_CB0_MOUT_EN 0xf10 +#define MT8196_OVL_OUTPROC_OUT_CB1_MOUT_EN 0xf14 +#define MT8196_OVL_OUTPROC_OUT_CB2_MOUT_EN 0xf18 +#define MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY5 BIT(0) +#define MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY6 BIT(1) +#define MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY7 BIT(2) + +/* DISPSYS0 */ +#define MT8196_PANEL_COMP_OUT_CB1_MOUT_EN 0xd84 +#define MT8196_DISP_TO_DLO_RELAY1 BIT(1) +#define MT8196_PANEL_COMP_OUT_CB2_MOUT_EN 0xd88 +#define MT8196_DISP_TO_DLO_RELAY2 BIT(2) +#define MT8196_PANEL_COMP_OUT_CB3_MOUT_EN 0xd8c +#define MT8196_DISP_TO_DLO_RELAY3 BIT(3) +#define MT8196_PQ_IN_CB0_MOUT_EN 0xdd0 +#define MT8196_PQ_IN_CB0_TO_PQ_OUT_CB_6 BIT(2) + +#define MT8196_PQ_IN_CB1_MOUT_EN 0xdd4 +#define MT8196_PQ_IN_CB1_TO_PQ_OUT_CB_7 BIT(3) +#define MT8196_PQ_IN_CB8_MOUT_EN 0xdf0 +#define MT8196_PQ_IN_CB8_TO_PQ_OUT_CB_8 BIT(4) +#define MT8196_PQ_OUT_CB6_MOUT_EN 0xe54 +#define MT8196_PQ_OUT_CB6_TO_PANEL0_COMP_OUT_CB1 BIT(1) +#define MT8196_PQ_OUT_CB7_MOUT_EN 0xe58 +#define MT8196_PQ_OUT_CB7_TO_PANEL0_COMP_OUT_CB2 BIT(2) +#define MT8196_PQ_OUT_CB8_MOUT_EN 0xe5c +#define MT8196_PQ_OUT_CB8_TO_PANEL0_COMP_OUT_CB3 BIT(3) + +/* OVLSYS config */ +#define MT8196_OVL_INT_MERGE 0x008 +#define MT8196_OVL_DL_OUT_RELAY5_SIZE 0x29c +#define MT8196_OVL_DL_OUT_RELAY6_SIZE 0x2a0 +#define MT8196_OVLSYS_GCE_EVENT_SEL 0x408 +#define MT8196_OVLSYS_BYPASS_MUX_SHADOW 0xca0 +#define MT8196_OVLSYS_CB_CON 0xcac +#define CB_BYPASS_MUX_SHADOW (0xff << 16) +#define MT8196_EVENT_GCE_EN (BIT(0) | BIT(1)) + +/* DISPSYS config */ +#define MT8196_DISP0_DLI_RELAY0 0x200 +#define MT8196_DISP0_DLI_RELAY1 0x204 +#define MT8196_DISP0_DLI_RELAY8 0x220 +#define MT8196_DISP0_DLO_RELAY1 0x268 +#define MT8196_DISP0_DLO_RELAY2 0x26c +#define MT8196_DISP0_DLO_RELAY3 0x270 +#define DISP_DLI_RELAY_1T2P BIT(30) +#define MT8196_DISP0_BYPASS_MUX_SHADOW 0xc30 +#define BYPASS_MUX_SHADOW BIT(0) +#define OVLSYS_CB_BYPASS_MUX_SHADOW (0xff << 16) + +/* DISPSYS1 config */ +#define MT8196_DISP1_INT_MERGE 0x008 +#define MT8196_DISP1_DLI_RELAY21 0x204 +#define MT8196_DISP1_DLI_RELAY22 0x208 +#define MT8196_DISP1_DLI_RELAY23 0x20c +#define MT8196_DISP1_GCE_FRAME_DONE_SEL0 0xa10 +#define MT8196_DISP1_GCE_FRAME_DONE_SEL1 0xa14 +#define MT8196_FRAME_DONE_DVO 25 +#define MT8196_FRAME_DONE_DP_INTF0 41 +#define MT8196_DISP1_BYPASS_MUX_SHADOW 0xcf8 + +/* VDISP_AO config */ +#define MT8196_VDISP_AO_REG_INTEN 0x000 +#define CPU_INTEN BIT(0) +#define CPU_INT_MERGE BIT(4) +#define MT8196_VDISP_AO_REG_INT_SEL_G0 0x020 +#define MT8196_VDISP_AO_REG_INT_SEL_G1 0x024 +#define MT8196_VDISP_AO_REG_INT_SEL_G2 0x028 +#define MT8196_VDISP_AO_REG_INT_SEL_G3 0x02c +#define MT8196_VDISP_AO_REG_INT_SEL_G4 0x030 +#define MT8196_VDISP_AO_REG_INT_SEL_G5 0x034 +#define MT8196_VDISP_AO_REG_INT_SEL_G6 0x038 +#define MT8196_IRQ_TABLE_OVL0_OUTPROC0 (0xa6) /* GIC 450 */ +#define MT8196_IRQ_TABLE_OVL0_OUTPROC1 (0xa7) /* GIC 451 */ +#define MT8196_IRQ_TABLE_OVL1_OUTPROC0 (0xd6) /* GIC 452 */ +#define MT8196_IRQ_TABLE_DSI0 (0x35) /* GIC 453 */ + +static const struct mtk_mmsys_async_info mmsys_mt8196_ovl0_async_comp_table[] = { + {DDP_COMPONENT_OVL0_DLO_ASYNC5, 0, MT8196_OVL_DL_OUT_RELAY5_SIZE, GENMASK(29, 0)}, + {DDP_COMPONENT_OVL0_DLO_ASYNC6, 1, MT8196_OVL_DL_OUT_RELAY6_SIZE, GENMASK(29, 0)}, +}; + +static const struct mtk_mmsys_async_info mmsys_mt8196_ovl1_async_comp_table[] = { + {DDP_COMPONENT_OVL1_DLO_ASYNC5, 0, MT8196_OVL_DL_OUT_RELAY5_SIZE, GENMASK(29, 0)}, + {DDP_COMPONENT_OVL1_DLO_ASYNC6, 1, MT8196_OVL_DL_OUT_RELAY6_SIZE, GENMASK(29, 0)}, +}; + +static const struct mtk_mmsys_async_info mmsys_mt8196_disp0_async_comp_table[] = { + {DDP_COMPONENT_DLI_ASYNC0, 0, MT8196_DISP0_DLI_RELAY0, GENMASK(29, 0)}, + {DDP_COMPONENT_DLI_ASYNC1, 1, MT8196_DISP0_DLI_RELAY1, GENMASK(29, 0)}, + {DDP_COMPONENT_DLI_ASYNC8, 2, MT8196_DISP0_DLI_RELAY8, GENMASK(29, 0)}, + {DDP_COMPONENT_DLO_ASYNC1, 3, MT8196_DISP0_DLO_RELAY1, GENMASK(29, 0)}, + {DDP_COMPONENT_DLO_ASYNC2, 4, MT8196_DISP0_DLO_RELAY2, GENMASK(29, 0)}, + {DDP_COMPONENT_DLO_ASYNC3, 5, MT8196_DISP0_DLO_RELAY3, GENMASK(29, 0)}, +}; + +static const struct mtk_mmsys_async_info mmsys_mt8196_disp1_async_comp_table[] = { + {DDP_COMPONENT_DLI_ASYNC21, 0, MT8196_DISP1_DLI_RELAY21, GENMASK(29, 0)}, + {DDP_COMPONENT_DLI_ASYNC22, 1, MT8196_DISP1_DLI_RELAY22, GENMASK(29, 0)}, + {DDP_COMPONENT_DLI_ASYNC23, 2, MT8196_DISP1_DLI_RELAY23, GENMASK(29, 0)}, +}; + +static const struct mtk_mmsys_default mmsys_mt8196_vdisp_ao_default_table[] = { + {MT8196_VDISP_AO_REG_INTEN, CPU_INTEN, CPU_INT_MERGE | CPU_INTEN}, + {MT8196_VDISP_AO_REG_INT_SEL_G0, MT8196_IRQ_TABLE_OVL0_OUTPROC0, GENMASK(7, 0)}, + {MT8196_VDISP_AO_REG_INT_SEL_G0, MT8196_IRQ_TABLE_OVL0_OUTPROC1 << 8, GENMASK(15, 8)}, + {MT8196_VDISP_AO_REG_INT_SEL_G0, MT8196_IRQ_TABLE_OVL1_OUTPROC0 << 16, GENMASK(23, 16)}, + {MT8196_VDISP_AO_REG_INT_SEL_G0, MT8196_IRQ_TABLE_DSI0 << 24, GENMASK(31, 24)} +}; + +static const struct mtk_mmsys_default mmsys_mt8196_ovl0_default_table[] = { + {MT8196_OVLSYS_GCE_EVENT_SEL, MT8196_EVENT_GCE_EN, GENMASK(1, 0)}, + {MT8196_OVL_INT_MERGE, 0, BIT(0)}, + {MT8196_OVLSYS_BYPASS_MUX_SHADOW, BYPASS_MUX_SHADOW, BYPASS_MUX_SHADOW}, + {MT8196_OVLSYS_CB_CON, OVLSYS_CB_BYPASS_MUX_SHADOW, OVLSYS_CB_BYPASS_MUX_SHADOW}, +}; + +static const struct mtk_mmsys_default mmsys_mt8196_disp0_default_table[] = { + {MT8196_OVLSYS_GCE_EVENT_SEL, MT8196_EVENT_GCE_EN, GENMASK(1, 0)}, + {MT8196_DISP0_BYPASS_MUX_SHADOW, CB_BYPASS_MUX_SHADOW | BYPASS_MUX_SHADOW, + CB_BYPASS_MUX_SHADOW | BYPASS_MUX_SHADOW}, + {MT8196_DISP0_DLI_RELAY0, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP0_DLI_RELAY1, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP0_DLI_RELAY8, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP0_DLO_RELAY1, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP0_DLO_RELAY2, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP0_DLO_RELAY3, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, +}; + +static const struct mtk_mmsys_default mmsys_mt8196_disp1_default_table[] = { + {MT8196_OVLSYS_GCE_EVENT_SEL, MT8196_EVENT_GCE_EN, GENMASK(1, 0)}, + {MT8196_DISP1_INT_MERGE, 0, BIT(0)}, + {MT8196_DISP1_BYPASS_MUX_SHADOW, CB_BYPASS_MUX_SHADOW | BYPASS_MUX_SHADOW, + CB_BYPASS_MUX_SHADOW | BYPASS_MUX_SHADOW}, + {MT8196_DISP1_DLI_RELAY21, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP1_DLI_RELAY22, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP1_DLI_RELAY23, DISP_DLI_RELAY_1T2P, GENMASK(31, 30)}, + {MT8196_DISP1_GCE_FRAME_DONE_SEL0, MT8196_FRAME_DONE_DVO, GENMASK(5, 0)}, + {MT8196_DISP1_GCE_FRAME_DONE_SEL1, MT8196_FRAME_DONE_DP_INTF0, GENMASK(5, 0)}, +}; + +static const struct mtk_mmsys_routes mmsys_mt8196_ovl0_routing_table[] = { + { + DDP_COMPONENT_OVL0_EXDMA2, DDP_COMPONENT_OVL0_BLENDER1, + MT8196_OVL_RSZ_IN_CB2_MOUT_EN, MT8196_DISP_OVL_EXDMA2_1_TO_OVL_EXDMA_OUT_CB3, + MT8196_DISP_OVL_EXDMA2_1_TO_OVL_EXDMA_OUT_CB3 + }, { + DDP_COMPONENT_OVL0_EXDMA2, DDP_COMPONENT_OVL0_BLENDER1, + MT8196_OVL_EXDMA_OUT_CB3_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER1, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER1 + }, { + DDP_COMPONENT_OVL0_EXDMA3, DDP_COMPONENT_OVL0_BLENDER2, + MT8196_OVL_EXDMA_OUT_CB4_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER2, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER2 + }, { + DDP_COMPONENT_OVL0_EXDMA4, DDP_COMPONENT_OVL0_BLENDER3, + MT8196_OVL_EXDMA_OUT_CB5_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER3, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER3 + }, { + DDP_COMPONENT_OVL0_EXDMA5, DDP_COMPONENT_OVL0_BLENDER4, + MT8196_OVL_EXDMA_OUT_CB6_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER4, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER4 + }, { + DDP_COMPONENT_OVL0_EXDMA6, DDP_COMPONENT_OVL0_BLENDER5, + MT8196_OVL_EXDMA_OUT_CB7_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER5, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER5 + }, { + DDP_COMPONENT_OVL0_EXDMA7, DDP_COMPONENT_OVL0_BLENDER6, + MT8196_OVL_EXDMA_OUT_CB8_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER6, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER6 + }, { + DDP_COMPONENT_OVL0_EXDMA8, DDP_COMPONENT_OVL0_BLENDER7, + MT8196_OVL_EXDMA_OUT_CB9_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER7, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER7 + }, { + DDP_COMPONENT_OVL0_EXDMA9, DDP_COMPONENT_OVL0_BLENDER8, + MT8196_OVL_EXDMA_OUT_CB10_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER8, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER8 + }, { + DDP_COMPONENT_OVL0_BLENDER4, DDP_COMPONENT_OVL0_OUTPROC0, + MT8196_OVL_BLENDER_OUT_CB4_MOUT_EN, MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC0, + MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC0 + }, { + DDP_COMPONENT_OVL0_BLENDER8, DDP_COMPONENT_OVL0_OUTPROC1, + MT8196_OVL_BLENDER_OUT_CB8_MOUT_EN, MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC1, + MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC1 + }, { + DDP_COMPONENT_OVL0_OUTPROC0, DDP_COMPONENT_OVL0_DLO_ASYNC5, + MT8196_OVL_OUTPROC_OUT_CB0_MOUT_EN, MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY5, + MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY5 + }, { + DDP_COMPONENT_OVL0_OUTPROC1, DDP_COMPONENT_OVL0_DLO_ASYNC6, + MT8196_OVL_OUTPROC_OUT_CB1_MOUT_EN, MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY6, + MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY6 + } +}; + +static const struct mtk_mmsys_routes mmsys_mt8196_ovl1_routing_table[] = { + { + DDP_COMPONENT_OVL1_EXDMA2, DDP_COMPONENT_OVL1_BLENDER1, + MT8196_OVL_RSZ_IN_CB2_MOUT_EN, MT8196_DISP_OVL_EXDMA2_1_TO_OVL_EXDMA_OUT_CB3, + MT8196_DISP_OVL_EXDMA2_1_TO_OVL_EXDMA_OUT_CB3 + }, { + DDP_COMPONENT_OVL1_EXDMA2, DDP_COMPONENT_OVL1_BLENDER1, + MT8196_OVL_EXDMA_OUT_CB3_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER1, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER1 + }, { + DDP_COMPONENT_OVL1_EXDMA3, DDP_COMPONENT_OVL1_BLENDER2, + MT8196_OVL_EXDMA_OUT_CB4_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER2, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER2 + }, { + DDP_COMPONENT_OVL1_EXDMA4, DDP_COMPONENT_OVL1_BLENDER3, + MT8196_OVL_EXDMA_OUT_CB5_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER3, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER3 + }, { + DDP_COMPONENT_OVL1_EXDMA5, DDP_COMPONENT_OVL1_BLENDER4, + MT8196_OVL_EXDMA_OUT_CB6_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER4, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER4 + }, { + DDP_COMPONENT_OVL1_EXDMA6, DDP_COMPONENT_OVL1_BLENDER5, + MT8196_OVL_EXDMA_OUT_CB7_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER5, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER5 + }, { + DDP_COMPONENT_OVL1_EXDMA7, DDP_COMPONENT_OVL1_BLENDER6, + MT8196_OVL_EXDMA_OUT_CB8_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER6, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER6 + }, { + DDP_COMPONENT_OVL1_EXDMA8, DDP_COMPONENT_OVL1_BLENDER7, + MT8196_OVL_EXDMA_OUT_CB9_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER7, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER7 + }, { + DDP_COMPONENT_OVL1_EXDMA9, DDP_COMPONENT_OVL1_BLENDER8, + MT8196_OVL_EXDMA_OUT_CB10_MOUT_EN, MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER8, + MT8196_DISP_OVL_EXDMA_OUT_CB_TO_OVL_BLENDER8 + }, { + DDP_COMPONENT_OVL1_BLENDER4, DDP_COMPONENT_OVL1_OUTPROC0, + MT8196_OVL_BLENDER_OUT_CB4_MOUT_EN, MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC0, + MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC0 + }, { + DDP_COMPONENT_OVL1_BLENDER8, DDP_COMPONENT_OVL1_OUTPROC1, + MT8196_OVL_BLENDER_OUT_CB8_MOUT_EN, MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC1, + MT8196_DISP_OUT_BLENDER_CB_TO_OVL_OUTPROC1 + }, { + DDP_COMPONENT_OVL1_OUTPROC0, DDP_COMPONENT_OVL1_DLO_ASYNC5, + MT8196_OVL_OUTPROC_OUT_CB0_MOUT_EN, MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY5, + MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY5 + }, { + DDP_COMPONENT_OVL1_OUTPROC1, DDP_COMPONENT_OVL1_DLO_ASYNC6, + MT8196_OVL_OUTPROC_OUT_CB1_MOUT_EN, MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY6, + MT8196_DISP_OVL_OUT_PROC_CB_TO_OVL_DLO_RELAY6 + } +}; + +/* + * main: DLI_ASYNC0-> PQ_IN_CB0 -> PQ_OUT_CB6 -> PANEL_COMP_OUT_CB1 -> DLO_ASYNC1 + * ext: DLI_ASYNC1-> PQ_IN_CB1 -> PQ_OUT_CB7 -> PANEL_COMP_OUT_CB2 -> DLO_ASYNC2 + */ +static const struct mtk_mmsys_routes mmsys_mt8196_disp0_routing_table[] = { + { + DDP_COMPONENT_DLI_ASYNC0, DDP_COMPONENT_DLO_ASYNC1, + MT8196_PQ_IN_CB0_MOUT_EN, MT8196_PQ_IN_CB0_TO_PQ_OUT_CB_6, + MT8196_PQ_IN_CB0_TO_PQ_OUT_CB_6 + }, { + DDP_COMPONENT_DLI_ASYNC0, DDP_COMPONENT_DLO_ASYNC1, + MT8196_PQ_OUT_CB6_MOUT_EN, MT8196_PQ_OUT_CB6_TO_PANEL0_COMP_OUT_CB1, + MT8196_PQ_OUT_CB6_TO_PANEL0_COMP_OUT_CB1 + }, { + DDP_COMPONENT_DLI_ASYNC0, DDP_COMPONENT_DLO_ASYNC1, + MT8196_PANEL_COMP_OUT_CB1_MOUT_EN, MT8196_DISP_TO_DLO_RELAY1, + MT8196_DISP_TO_DLO_RELAY1 + }, { + DDP_COMPONENT_DLI_ASYNC1, DDP_COMPONENT_DLO_ASYNC2, + MT8196_PQ_IN_CB1_MOUT_EN, MT8196_PQ_IN_CB1_TO_PQ_OUT_CB_7, + MT8196_PQ_IN_CB1_TO_PQ_OUT_CB_7 + }, { + DDP_COMPONENT_DLI_ASYNC1, DDP_COMPONENT_DLO_ASYNC2, + MT8196_PQ_OUT_CB7_MOUT_EN, MT8196_PQ_OUT_CB7_TO_PANEL0_COMP_OUT_CB2, + MT8196_PQ_OUT_CB7_TO_PANEL0_COMP_OUT_CB2 + }, { + DDP_COMPONENT_DLI_ASYNC1, DDP_COMPONENT_DLO_ASYNC2, + MT8196_PANEL_COMP_OUT_CB2_MOUT_EN, MT8196_DISP_TO_DLO_RELAY2, + MT8196_DISP_TO_DLO_RELAY2 + }, { + DDP_COMPONENT_DLI_ASYNC8, DDP_COMPONENT_DLO_ASYNC3, + MT8196_PQ_IN_CB8_MOUT_EN, MT8196_PQ_IN_CB8_TO_PQ_OUT_CB_8, + MT8196_PQ_IN_CB8_TO_PQ_OUT_CB_8 + }, { + DDP_COMPONENT_DLI_ASYNC8, DDP_COMPONENT_DLO_ASYNC3, + MT8196_PQ_OUT_CB8_MOUT_EN, MT8196_PQ_OUT_CB8_TO_PANEL0_COMP_OUT_CB3, + MT8196_PQ_OUT_CB8_TO_PANEL0_COMP_OUT_CB3 + }, { + DDP_COMPONENT_DLI_ASYNC8, DDP_COMPONENT_DLO_ASYNC3, + MT8196_PANEL_COMP_OUT_CB3_MOUT_EN, MT8196_DISP_TO_DLO_RELAY3, + MT8196_DISP_TO_DLO_RELAY3 + } +}; + +/* + * main: DLI_ASYNC21-> SPLITTER_IN_CB1-> SPLITTER_OUT_CB9-> COMP_OUT_CB6-> MERGE_OUT_CB0 -> DVO + * ext: DLI_ASYNC22-> SPLITTER_IN_CB2-> SPLITTER_OUT_CB10-> COMP_OUT_CB7-> MERGE_OUT_CB1 -> DP_INTF0 + */ +static const struct mtk_mmsys_routes mmsys_mt8196_disp1_routing_table[] = { + { + DDP_COMPONENT_DLI_ASYNC21, DDP_COMPONENT_DVO0, + MT8196_SPLITTER_IN_CB1_MOUT_EN, MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB9, + MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB9 + }, { + DDP_COMPONENT_DLI_ASYNC21, DDP_COMPONENT_DVO0, + MT8196_SPLITTER_OUT_CB9_MOUT_EN, MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB6, + MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB6 + }, { + DDP_COMPONENT_DLI_ASYNC21, DDP_COMPONENT_DVO0, + MT8196_COMP_OUT_CB6_MOUT_EN, MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB0, + MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB0 + }, { + DDP_COMPONENT_DLI_ASYNC21, DDP_COMPONENT_DVO0, + MT8196_MERGE_OUT_CB0_MOUT_EN, MT8196_DISP_COMP_OUT_CB_TO_DVO0, + MT8196_DISP_COMP_OUT_CB_TO_DVO0 + }, { + DDP_COMPONENT_DLI_ASYNC22, DDP_COMPONENT_DP_INTF0, + MT8196_SPLITTER_IN_CB2_MOUT_EN, MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB10, + MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB10 + }, { + DDP_COMPONENT_DLI_ASYNC22, DDP_COMPONENT_DP_INTF0, + MT8196_SPLITTER_OUT_CB10_MOUT_EN, MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB7, + MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB7 + }, { + DDP_COMPONENT_DLI_ASYNC22, DDP_COMPONENT_DP_INTF0, + MT8196_COMP_OUT_CB7_MOUT_EN, MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB1, + MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB1 + }, { + DDP_COMPONENT_DLI_ASYNC22, DDP_COMPONENT_DP_INTF0, + MT8196_MERGE_OUT_CB1_MOUT_EN, MT8196_DISP_COMP_OUT_CB_TO_DP_INTF0, + MT8196_DISP_COMP_OUT_CB_TO_DP_INTF0 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DVO0, + MT8196_SPLITTER_IN_CB3_MOUT_EN, MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11, + MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DVO0, + MT8196_SPLITTER_OUT_CB11_MOUT_EN, MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8, + MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DVO0, + MT8196_COMP_OUT_CB8_MOUT_EN, MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2, + MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DVO0, + MT8196_MERGE_OUT_CB2_MOUT_EN, MT8196_DISP_COMP_OUT_CB_TO_DVO0, + MT8196_DISP_COMP_OUT_CB_TO_DVO0 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DP_INTF1, + MT8196_SPLITTER_IN_CB3_MOUT_EN, MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11, + MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DP_INTF1, + MT8196_SPLITTER_OUT_CB11_MOUT_EN, MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8, + MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DP_INTF1, + MT8196_COMP_OUT_CB8_MOUT_EN, MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2, + MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DP_INTF1, + MT8196_MERGE_OUT_CB2_MOUT_EN, MT8196_DISP_COMP_OUT_CB_TO_DP_INTF1, + MT8196_DISP_COMP_OUT_CB_TO_DP_INTF1 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DSI0, + MT8196_SPLITTER_IN_CB3_MOUT_EN, MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11, + MT8196_DISP_DLI_RELAY_TO_SPLITTER_OUT_CB11 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DSI0, + MT8196_SPLITTER_OUT_CB11_MOUT_EN, MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8, + MT8196_DISP_SPLITTER_IN_CB_TO_COMP_OUT_CB8 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DSI0, + MT8196_COMP_OUT_CB8_MOUT_EN, MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2, + MT8196_DISP_SPLITTER_OUT_CB_TO_MERGE_OUT_CB2 + }, { + DDP_COMPONENT_DLI_ASYNC23, DDP_COMPONENT_DSI0, + MT8196_MERGE_OUT_CB2_MOUT_EN, MT8196_DISP_COMP_OUT_CB_TO_DSI0, + MT8196_DISP_COMP_OUT_CB_TO_DSI0 + } +}; +#endif /* __SOC_MEDIATEK_MT8196_MMSYS_H */ diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index aa5a4ee17078b..a8f26a6bd7781 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -4,12 +4,14 @@ * Author: James Liao */ +#include #include #include #include #include #include #include +#include #include #include @@ -21,6 +23,7 @@ #include "mt8188-mmsys.h" #include "mt8192-mmsys.h" #include "mt8195-mmsys.h" +#include "mt8196-mmsys.h" #include "mt8365-mmsys.h" #define MMSYS_SW_RESET_PER_REG 32 @@ -146,6 +149,54 @@ static const struct mtk_mmsys_driver_data mt8195_vppsys1_driver_data = { .is_vppsys = true, }; +static const struct mtk_mmsys_driver_data mt8196_dispsys0_driver_data = { + .clk_driver = "clk-mt8196-disp0", + .routes = mmsys_mt8196_disp0_routing_table, + .num_routes = ARRAY_SIZE(mmsys_mt8196_disp0_routing_table), + .async_info = mmsys_mt8196_disp0_async_comp_table, + .num_async_info = ARRAY_SIZE(mmsys_mt8196_disp0_async_comp_table), + .def_config = mmsys_mt8196_disp0_default_table, + .num_def_config = ARRAY_SIZE(mmsys_mt8196_disp0_default_table), + .num_top_clk = 1, +}; + +static const struct mtk_mmsys_driver_data mt8196_dispsys1_driver_data = { + .clk_driver = "clk-mt8196-disp1", + .routes = mmsys_mt8196_disp1_routing_table, + .num_routes = ARRAY_SIZE(mmsys_mt8196_disp1_routing_table), + .async_info = mmsys_mt8196_disp1_async_comp_table, + .num_async_info = ARRAY_SIZE(mmsys_mt8196_disp1_async_comp_table), + .def_config = mmsys_mt8196_disp1_default_table, + .num_def_config = ARRAY_SIZE(mmsys_mt8196_disp1_default_table), + .num_top_clk = 1, +}; + +static const struct mtk_mmsys_driver_data mt8196_ovlsys0_driver_data = { + .clk_driver = "clk-mt8196-ovl0", + .routes = mmsys_mt8196_ovl0_routing_table, + .num_routes = ARRAY_SIZE(mmsys_mt8196_ovl0_routing_table), + .async_info = mmsys_mt8196_ovl0_async_comp_table, + .num_async_info = ARRAY_SIZE(mmsys_mt8196_ovl0_async_comp_table), + .def_config = mmsys_mt8196_ovl0_default_table, + .num_def_config = ARRAY_SIZE(mmsys_mt8196_ovl0_default_table), +}; + +static const struct mtk_mmsys_driver_data mt8196_ovlsys1_driver_data = { + .clk_driver = "clk-mt8196-ovl1", + .routes = mmsys_mt8196_ovl1_routing_table, + .num_routes = ARRAY_SIZE(mmsys_mt8196_ovl1_routing_table), + .async_info = mmsys_mt8196_ovl1_async_comp_table, + .num_async_info = ARRAY_SIZE(mmsys_mt8196_ovl1_async_comp_table), + .def_config = mmsys_mt8196_ovl0_default_table, + .num_def_config = ARRAY_SIZE(mmsys_mt8196_ovl0_default_table), +}; + +static const struct mtk_mmsys_driver_data mt8196_vdisp_ao_driver_data = { + .clk_driver = "clk-mt8196-vdisp_ao", + .def_config = mmsys_mt8196_vdisp_ao_default_table, + .num_def_config = ARRAY_SIZE(mmsys_mt8196_vdisp_ao_default_table), +}; + static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = { .clk_driver = "clk-mt8365-mm", .routes = mt8365_mmsys_routing_table, @@ -160,6 +211,9 @@ struct mtk_mmsys { spinlock_t lock; /* protects mmsys_sw_rst_b reg */ struct reset_controller_dev rcdev; struct cmdq_client_reg cmdq_base; + struct clk **async_clk; + int num_async_clk; + struct clk **top_clk; }; static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val, @@ -190,6 +244,99 @@ static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, writel_relaxed(tmp, mmsys->regs + offset); } +int mtk_mmsys_top_clk_enable(struct device *dev) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + int ret, i; + + if (!mmsys->data->num_top_clk) + return 0; + + for (i = 0; i < mmsys->data->num_top_clk; i++) + ret = clk_prepare_enable(mmsys->top_clk[i]); + return ret; +} +EXPORT_SYMBOL_GPL(mtk_mmsys_top_clk_enable); + +void mtk_mmsys_top_clk_disable(struct device *dev) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + int i; + + for (i = 0; i < mmsys->data->num_top_clk; i++) + clk_disable_unprepare(mmsys->top_clk[i]); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_top_clk_disable); + +int mtk_mmsys_ddp_clk_enable(struct device *dev, enum mtk_ddp_comp_id comp_id) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + const struct mtk_mmsys_async_info *async = mmsys->data->async_info; + + int i; + + if (!mmsys->data->num_async_info) + return 0; + + for (i = 0; i < mmsys->data->num_async_info; i++) + if (comp_id == async[i].comp_id) + return clk_prepare_enable(mmsys->async_clk[async[i].index]); + return 0; +} +EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_clk_enable); + +void mtk_mmsys_ddp_clk_disable(struct device *dev, enum mtk_ddp_comp_id comp_id) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + const struct mtk_mmsys_async_info *async = mmsys->data->async_info; + int i; + + if (!mmsys->data->num_async_info) + return; + + for (i = 0; i < mmsys->data->num_async_info; i++) + if (comp_id == async[i].comp_id) + clk_disable_unprepare(mmsys->async_clk[async[i].index]); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_clk_disable); + +void mtk_mmsys_ddp_config(struct device *dev, enum mtk_ddp_comp_id comp_id, + int width, int height, struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + const struct mtk_mmsys_async_info *async = mmsys->data->async_info; + int i; + + if (!mmsys->data->num_async_info) + return; + + for (i = 0; i < mmsys->data->num_async_info; i++) + if (comp_id == async[i].comp_id) + break; + + if (i == mmsys->data->num_async_info) + return; + + mtk_mmsys_update_bits(mmsys, async[i].offset, async[i].mask, + height << 16 | width, cmdq_pkt); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config); + +void mtk_mmsys_default_config(struct device *dev) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + const struct mtk_mmsys_default *def_config = mmsys->data->def_config; + int i; + + if (!mmsys->data->num_def_config) + return; + + for (i = 0; i < mmsys->data->num_def_config; i++) + mtk_mmsys_update_bits(mmsys, def_config[i].offset, def_config[i].mask, + def_config[i].val, NULL); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_default_config); + void mtk_mmsys_ddp_connect(struct device *dev, enum mtk_ddp_comp_id cur, enum mtk_ddp_comp_id next) @@ -461,7 +608,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev) struct platform_device *clks; struct platform_device *drm; struct mtk_mmsys *mmsys; - int ret; + int ret, i; mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL); if (!mmsys) @@ -503,6 +650,49 @@ static int mtk_mmsys_probe(struct platform_device *pdev) return PTR_ERR(clks); mmsys->clks_pdev = clks; + if (mmsys->data->num_top_clk) { + struct device_node *node; + + node = of_get_child_by_name(dev->of_node, "top"); + if (!node) { + dev_err(&pdev->dev, "Couldn't find top node\n"); + return -EINVAL; + } + + mmsys->top_clk = devm_kmalloc_array(dev, mmsys->data->num_top_clk, + sizeof(*mmsys->top_clk), GFP_KERNEL); + if (!mmsys->top_clk) + return -ENOMEM; + + for (i = 0; i < mmsys->data->num_top_clk; i++) { + mmsys->top_clk[i] = of_clk_get(node, i); + if (IS_ERR(mmsys->top_clk[i])) + return PTR_ERR(mmsys->top_clk[i]); + } + } + + if (mmsys->data->num_async_info) { + struct device_node *node; + + node = of_get_child_by_name(dev->of_node, "async"); + if (!node) { + dev_err(&pdev->dev, "Couldn't find async node\n"); + return -EINVAL; + } + + mmsys->async_clk = devm_kmalloc_array(dev, mmsys->data->num_async_info, + sizeof(*mmsys->async_clk), GFP_KERNEL); + if (!mmsys->async_clk) + return -ENOMEM; + mmsys->num_async_clk = mmsys->data->num_async_info; + + for (i = 0; i < mmsys->num_async_clk; i++) { + mmsys->async_clk[i] = of_clk_get(node, i); + if (IS_ERR(mmsys->async_clk[i])) + return PTR_ERR(mmsys->async_clk[i]); + } + } + if (mmsys->data->is_vppsys) goto out_probe_done; @@ -514,6 +704,9 @@ static int mtk_mmsys_probe(struct platform_device *pdev) } mmsys->drm_pdev = drm; + if (of_property_present(dev->of_node, "power-domains")) + pm_runtime_enable(dev); + out_probe_done: return 0; } @@ -525,6 +718,9 @@ static int mtk_mmsys_remove(struct platform_device *pdev) platform_device_unregister(mmsys->drm_pdev); platform_device_unregister(mmsys->clks_pdev); + if (of_property_present(pdev->dev.of_node, "power-domains")) + pm_runtime_disable(&pdev->dev); + return 0; } @@ -549,6 +745,11 @@ static const struct of_device_id of_match_mtk_mmsys[] = { { .compatible = "mediatek,mt8195-vdosys1", .data = &mt8195_vdosys1_driver_data }, { .compatible = "mediatek,mt8195-vppsys0", .data = &mt8195_vppsys0_driver_data }, { .compatible = "mediatek,mt8195-vppsys1", .data = &mt8195_vppsys1_driver_data }, + { .compatible = "mediatek,mt8196-dispsys0", .data = &mt8196_dispsys0_driver_data }, + { .compatible = "mediatek,mt8196-dispsys1", .data = &mt8196_dispsys1_driver_data }, + { .compatible = "mediatek,mt8196-ovlsys0", .data = &mt8196_ovlsys0_driver_data }, + { .compatible = "mediatek,mt8196-ovlsys1", .data = &mt8196_ovlsys1_driver_data }, + { .compatible = "mediatek,mt8196-vdisp-ao", .data = &mt8196_vdisp_ao_driver_data }, { .compatible = "mediatek,mt8365-mmsys", .data = &mt8365_mmsys_driver_data }, { /* sentinel */ } }; diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h index 921c3f1e67686..9c141440164d7 100644 --- a/drivers/soc/mediatek/mtk-mmsys.h +++ b/drivers/soc/mediatek/mtk-mmsys.h @@ -88,6 +88,19 @@ struct mtk_mmsys_routes { u32 val; }; +struct mtk_mmsys_async_info { + u32 comp_id; + u32 index; + u32 offset; + u32 mask; +}; + +struct mtk_mmsys_default { + u32 offset; + u32 val; + u32 mask; +}; + /** * struct mtk_mmsys_driver_data - Settings of the mmsys * @clk_driver: Clock driver name that the mmsys is using @@ -126,6 +139,11 @@ struct mtk_mmsys_driver_data { const bool is_vppsys; const u8 vsync_len; const unsigned int *mdp_isp_ctrl[ISP_CTRL_MAX]; + const struct mtk_mmsys_async_info *async_info; + const unsigned int num_async_info; + const struct mtk_mmsys_default *def_config; + const unsigned int num_def_config; + const unsigned int num_top_clk; }; /* diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 15641e435a760..85c2e06e71b27 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -29,6 +29,15 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_COLOR1, DDP_COMPONENT_DITHER0, DDP_COMPONENT_DITHER1, + DDP_COMPONENT_DLI_ASYNC0, + DDP_COMPONENT_DLI_ASYNC1, + DDP_COMPONENT_DLI_ASYNC8, + DDP_COMPONENT_DLI_ASYNC21, + DDP_COMPONENT_DLI_ASYNC22, + DDP_COMPONENT_DLI_ASYNC23, + DDP_COMPONENT_DLO_ASYNC1, + DDP_COMPONENT_DLO_ASYNC2, + DDP_COMPONENT_DLO_ASYNC3, DDP_COMPONENT_DP_INTF0, DDP_COMPONENT_DP_INTF1, DDP_COMPONENT_DPI0, @@ -39,6 +48,7 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_DSI1, DDP_COMPONENT_DSI2, DDP_COMPONENT_DSI3, + DDP_COMPONENT_DVO0, DDP_COMPONENT_ETHDR_MIXER, DDP_COMPONENT_GAMMA, DDP_COMPONENT_MDP_RDMA0, @@ -58,10 +68,52 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_OD0, DDP_COMPONENT_OD1, DDP_COMPONENT_OVL0, + DDP_COMPONENT_OVL0_BLENDER1, + DDP_COMPONENT_OVL0_BLENDER2, + DDP_COMPONENT_OVL0_BLENDER3, + DDP_COMPONENT_OVL0_BLENDER4, + DDP_COMPONENT_OVL0_BLENDER5, + DDP_COMPONENT_OVL0_BLENDER6, + DDP_COMPONENT_OVL0_BLENDER7, + DDP_COMPONENT_OVL0_BLENDER8, + DDP_COMPONENT_OVL0_BLENDER9, + DDP_COMPONENT_OVL0_DLO_ASYNC5, + DDP_COMPONENT_OVL0_DLO_ASYNC6, + DDP_COMPONENT_OVL0_EXDMA2, + DDP_COMPONENT_OVL0_EXDMA3, + DDP_COMPONENT_OVL0_EXDMA4, + DDP_COMPONENT_OVL0_EXDMA5, + DDP_COMPONENT_OVL0_EXDMA6, + DDP_COMPONENT_OVL0_EXDMA7, + DDP_COMPONENT_OVL0_EXDMA8, + DDP_COMPONENT_OVL0_EXDMA9, + DDP_COMPONENT_OVL0_OUTPROC0, + DDP_COMPONENT_OVL0_OUTPROC1, DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_OVL_2L1, DDP_COMPONENT_OVL_2L2, DDP_COMPONENT_OVL1, + DDP_COMPONENT_OVL1_BLENDER1, + DDP_COMPONENT_OVL1_BLENDER2, + DDP_COMPONENT_OVL1_BLENDER3, + DDP_COMPONENT_OVL1_BLENDER4, + DDP_COMPONENT_OVL1_BLENDER5, + DDP_COMPONENT_OVL1_BLENDER6, + DDP_COMPONENT_OVL1_BLENDER7, + DDP_COMPONENT_OVL1_BLENDER8, + DDP_COMPONENT_OVL1_BLENDER9, + DDP_COMPONENT_OVL1_DLO_ASYNC5, + DDP_COMPONENT_OVL1_DLO_ASYNC6, + DDP_COMPONENT_OVL1_EXDMA2, + DDP_COMPONENT_OVL1_EXDMA3, + DDP_COMPONENT_OVL1_EXDMA4, + DDP_COMPONENT_OVL1_EXDMA5, + DDP_COMPONENT_OVL1_EXDMA6, + DDP_COMPONENT_OVL1_EXDMA7, + DDP_COMPONENT_OVL1_EXDMA8, + DDP_COMPONENT_OVL1_EXDMA9, + DDP_COMPONENT_OVL1_OUTPROC0, + DDP_COMPONENT_OVL1_OUTPROC1, DDP_COMPONENT_PADDING0, DDP_COMPONENT_PADDING1, DDP_COMPONENT_PADDING2, @@ -90,6 +142,14 @@ enum mtk_isp_ctrl { ISP_CTRL_MAX }; +int mtk_mmsys_top_clk_enable(struct device *dev); +void mtk_mmsys_top_clk_disable(struct device *dev); +int mtk_mmsys_ddp_clk_enable(struct device *dev, enum mtk_ddp_comp_id comp_id); +void mtk_mmsys_ddp_clk_disable(struct device *dev, enum mtk_ddp_comp_id comp_id); +void mtk_mmsys_ddp_config(struct device *dev, enum mtk_ddp_comp_id comp_id, + int width, int height, struct cmdq_pkt *cmdq_pkt); +void mtk_mmsys_default_config(struct device *dev); + void mtk_mmsys_ddp_connect(struct device *dev, enum mtk_ddp_comp_id cur, enum mtk_ddp_comp_id next); -- GitLab From fd43e178b82f8b0d16a3b5decb05f4b7e22ce011 Mon Sep 17 00:00:00 2001 From: Jason-jh Lin Date: Wed, 22 Jan 2025 17:34:13 +0800 Subject: [PATCH 450/456] CHROMIUM: soc: mediatek: mtk-mutex: Fix the confusing naming of MUTEX_MOD2 Since MUTEX_MOD1 is used to define settings over 32 currently, the previous MUTEX_MOD2 should be renamed to MUTEX_MOD1 for consistency and to avoid confusion. BUG=b:384077322 TEST=emerge-rauru sys-kernel/chromeos-kernel-6_6 UPSTREAM-TASK=b:379039599 Change-Id: I06154e921397195b777af2a6f79377c27d8f3444 Signed-off-by: Jason-jh Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6194912 Commit-Queue: Eric Yilun Lin Reviewed-by: Eric Yilun Lin Reviewed-by: Chen-Yu Tsai Tested-by: Eric Yilun Lin Signed-off-by: Hubert Mazur --- drivers/soc/mediatek/mtk-mutex.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index 5e2ce726abbba..2f4c546cf0c60 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -26,7 +26,6 @@ #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) #define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n) ((mutex_mod_reg) + 0x20 * (n) + 0x4) #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) -#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) #define INT_MUTEX BIT(1) @@ -131,7 +130,7 @@ #define MT8188_MUTEX_MOD_DISP_VPP_MERGE 20 #define MT8188_MUTEX_MOD_DISP_DP_INTF0 21 #define MT8188_MUTEX_MOD_DISP_POSTMASK0 24 -#define MT8188_MUTEX_MOD2_DISP_PWM0 33 +#define MT8188_MUTEX_MOD1_DISP_PWM0 (32 + 1) #define MT8188_MUTEX_MOD_DISP1_MDP_RDMA0 0 #define MT8188_MUTEX_MOD_DISP1_MDP_RDMA1 1 @@ -265,8 +264,8 @@ #define MT2712_MUTEX_MOD_DISP_PWM0 23 #define MT2712_MUTEX_MOD_DISP_PWM1 24 #define MT2712_MUTEX_MOD_DISP_OD0 25 -#define MT2712_MUTEX_MOD2_DISP_AAL1 33 -#define MT2712_MUTEX_MOD2_DISP_OD1 34 +#define MT2712_MUTEX_MOD1_DISP_AAL1 (32 + 1) +#define MT2712_MUTEX_MOD1_DISP_OD1 (32 + 2) #define MT2701_MUTEX_MOD_DISP_OVL 3 #define MT2701_MUTEX_MOD_DISP_WDMA 6 @@ -356,11 +355,11 @@ static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0, - [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1, + [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD1_DISP_AAL1, [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0, [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1, [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0, - [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1, + [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD1_DISP_OD1, [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0, [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1, [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0, @@ -469,7 +468,7 @@ static const unsigned int mt8188_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_MERGE0] = MT8188_MUTEX_MOD_DISP_VPP_MERGE, [DDP_COMPONENT_DSC0] = MT8188_MUTEX_MOD_DISP_DSC_WRAP0_CORE0, [DDP_COMPONENT_DSI0] = MT8188_MUTEX_MOD_DISP_DSI0, - [DDP_COMPONENT_PWM0] = MT8188_MUTEX_MOD2_DISP_PWM0, + [DDP_COMPONENT_PWM0] = MT8188_MUTEX_MOD1_DISP_PWM0, [DDP_COMPONENT_DP_INTF0] = MT8188_MUTEX_MOD_DISP_DP_INTF0, [DDP_COMPONENT_DP_INTF1] = MT8188_MUTEX_MOD_DISP1_DP_INTF1, [DDP_COMPONENT_ETHDR_MIXER] = MT8188_MUTEX_MOD_DISP1_DISP_MIXER, @@ -850,7 +849,8 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex, reg |= 1 << mtx->data->mutex_mod[id]; writel_relaxed(reg, mtx->regs + offset); } else { - offset = DISP_REG_MUTEX_MOD2(mutex->id); + offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg, + mutex->id); reg = readl_relaxed(mtx->regs + offset); reg |= 1 << (mtx->data->mutex_mod[id] - 32); writel_relaxed(reg, mtx->regs + offset); @@ -896,7 +896,8 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex, reg &= ~(1 << mtx->data->mutex_mod[id]); writel_relaxed(reg, mtx->regs + offset); } else { - offset = DISP_REG_MUTEX_MOD2(mutex->id); + offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg, + mutex->id); reg = readl_relaxed(mtx->regs + offset); reg &= ~(1 << (mtx->data->mutex_mod[id] - 32)); writel_relaxed(reg, mtx->regs + offset); -- GitLab From 7f0475dbfdbd6aad099f30c52bf65b768d96133c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 9 Oct 2024 14:01:34 +0300 Subject: [PATCH 451/456] BACKPORT: drm/i915/dp_mst: Handle error during DSC BW overhead/slice calculation The MST branch device may not support the number of DSC slices a mode requires, handle the error in this case. Fixes: 4e0837a8d00a ("drm/i915/dp_mst: Account for FEC and DSC overhead during BW allocation") Cc: stable@vger.kernel.org # v6.8+ Reviewed-by: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20241009110135.1216498-1-imre.deak@intel.com (cherry picked from commit 802a69b6b8a0502a9e2309afec7e1b77f67874f2) Signed-off-by: Joonas Lahtinen (cherry picked from commit 69b3d87212676c4c22aa4660435e2066dc7d1311) Conflicts: drivers/gpu/drm/i915/display/intel_dp_mst.c BUG=b:325713868 TEST=CQ Change-Id: Ie583e928685b58469beaa86624b41be4cc837cc2 Signed-off-by: Tim Van Patten Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5948230 Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 37 +++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8f9c65f2bba27..ed29cd1670956 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -89,25 +89,19 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, const struct intel_connector *connector, - bool ssc, bool dsc, int bpp_x16) + bool ssc, int dsc_slice_count, int bpp_x16) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; unsigned long flags = DRM_DP_BW_OVERHEAD_MST; - int dsc_slice_count = 0; int overhead; flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; - if (dsc) { + if (dsc_slice_count) flags |= DRM_DP_BW_OVERHEAD_DSC; - dsc_slice_count = intel_dp_dsc_get_slice_count(connector, - adjusted_mode->clock, - adjusted_mode->hdisplay, - crtc_state->bigjoiner_pipes); - } overhead = drm_dp_bw_overhead(crtc_state->lane_count, adjusted_mode->hdisplay, @@ -153,6 +147,19 @@ static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead) return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000); } +static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector, + const struct intel_crtc_state *crtc_state) +{ + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + int num_joined_pipes = crtc_state->bigjoiner_pipes; + + return intel_dp_dsc_get_slice_count(connector, + adjusted_mode->clock, + adjusted_mode->hdisplay, + num_joined_pipes); +} + static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, int max_bpp, @@ -172,6 +179,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int bpp, slots = -EINVAL; + int dsc_slice_count = 0; int max_dpt_bpp; int ret = 0; @@ -203,6 +211,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", min_bpp, max_bpp); + if (dsc) { + dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state); + if (!dsc_slice_count) { + drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n"); + + return -ENOSPC; + } + } + for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { int local_bw_overhead; int remote_bw_overhead; @@ -216,9 +233,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, intel_dp_output_bpp(crtc_state->output_format, bpp)); local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, - false, dsc, link_bpp_x16); + false, dsc_slice_count, link_bpp_x16); remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, - true, dsc, link_bpp_x16); + true, dsc_slice_count, link_bpp_x16); intel_dp_mst_compute_m_n(crtc_state, connector, local_bw_overhead, -- GitLab From 30feb1431ee4bb85390640f6190d0055c168df92 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 9 Oct 2024 14:01:35 +0300 Subject: [PATCH 452/456] UPSTREAM: drm/i915/dp_mst: Don't require DSC hblank quirk for a non-DSC compatible mode If an MST branch device doesn't support DSC for a given mode, but the MST link has enough BW for the mode, assume that the branch device does support the mode using an uncompressed stream. Fixes: 55eaef164174 ("drm/i915/dp_mst: Handle the Synaptics HBlank expansion quirk") Cc: stable@vger.kernel.org # v6.8+ Reviewed-by: Suraj Kandpal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20241009110135.1216498-2-imre.deak@intel.com (cherry picked from commit 4e75c3e208a06ad6fd9b3517fb77337460d7c2b0) Signed-off-by: Joonas Lahtinen (cherry picked from commit 2f54e71359eb2abc0bdf6619cd356e5e350ff27b) BUG=b:325713868 TEST=CQ Change-Id: I391ef02c0e81c6003e52040bfc78e3903a7753c8 Signed-off-by: Tim Van Patten Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5948231 Reviewed-by: Sean Paul Reviewed-by: Drew Davenport Signed-off-by: Hubert Mazur --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index ed29cd1670956..e542323117bcc 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -478,6 +478,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) return false; + if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state)) + return false; + return true; } -- GitLab From c0e55b3f3e039b30d45b0724b228b6c746bec7a9 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Fri, 6 Dec 2024 09:15:13 +0000 Subject: [PATCH 453/456] UPSTREAM: platform/chrome: cros_ec: jump to RW before probing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are EC devices, like FPMCU, that use RWSIG as a method of authenticating RW section. After the authentication succeeds, EC device waits some time before jumping to RW. EC can be probed before the jump, which means there is a time window after jump to RW in which EC won't respond, because it is not initialized. It can cause a communication errors after probing. To avoid such problems, send the RWSIG continue command first, which skips waiting for the jump to RW. Send the command more times, to make sure EC is ready in RW before the start of the actual probing process. If a EC device doesn't support the RWSIG, it will respond with invalid command error code and probing will continue as usual. Signed-off-by: Dawid Niedzwiecki Link: https://lore.kernel.org/r/20241206091514.2538350-2-dawidn@google.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit 5ffa0dbfdc9fc05acae02d5b0dc766ec778569ac) BUG=b:373543912 TEST=Make sure FPMCU is always registers for Omniknight devices. Change-Id: I6dd5178f24169cc2f045ecfa6b13a1d8a5f2ea73 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6218201 Reviewed-by: Sean Paul Reviewed-by: Kornel Dulęba Reviewed-by: Patryk Duda Tested-by: Dawid Niedźwiecki Commit-Queue: Dawid Niedźwiecki Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec.c | 5 ++ drivers/platform/chrome/cros_ec_i2c.c | 3 +- drivers/platform/chrome/cros_ec_ishtp.c | 2 +- drivers/platform/chrome/cros_ec_lpc.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 60 +++++++++++++++++++++ drivers/platform/chrome/cros_ec_rpmsg.c | 2 +- drivers/platform/chrome/cros_ec_spi.c | 2 +- drivers/platform/chrome/cros_ec_uart.c | 2 +- include/linux/platform_data/cros_ec_proto.h | 2 + 9 files changed, 74 insertions(+), 6 deletions(-) diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index 47d19f7e295a7..27275e4ddf2c0 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -204,6 +204,11 @@ int cros_ec_register(struct cros_ec_device *ec_dev) mutex_init(&ec_dev->lock); lockdep_set_class(&ec_dev->lock, &ec_dev->lockdep_key); + /* Send RWSIG continue to jump to RW for devices using RWSIG. */ + err = cros_ec_rwsig_continue(ec_dev); + if (err) + dev_info(dev, "Failed to continue RWSIG: %d\n", err); + err = cros_ec_query_all(ec_dev); if (err) { dev_err(dev, "Cannot identify the EC: error %d\n", err); diff --git a/drivers/platform/chrome/cros_ec_i2c.c b/drivers/platform/chrome/cros_ec_i2c.c index e29c51cbfd71b..79cbd5aa58cbe 100644 --- a/drivers/platform/chrome/cros_ec_i2c.c +++ b/drivers/platform/chrome/cros_ec_i2c.c @@ -305,7 +305,8 @@ static int cros_ec_i2c_probe(struct i2c_client *client) ec_dev->phys_name = client->adapter->name; ec_dev->din_size = sizeof(struct ec_host_response_i2c) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct ec_host_request_i2c); + ec_dev->dout_size = sizeof(struct ec_host_request_i2c) + + sizeof(struct ec_params_rwsig_action); err = cros_ec_register(ec_dev); if (err) { diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c index cb2031cf7106f..189cfe3b9a70d 100644 --- a/drivers/platform/chrome/cros_ec_ishtp.c +++ b/drivers/platform/chrome/cros_ec_ishtp.c @@ -582,7 +582,7 @@ static int cros_ec_dev_init(struct ishtp_cl_data *client_data) ec_dev->phys_name = dev_name(dev); ec_dev->din_size = sizeof(struct cros_ish_in_msg) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct cros_ish_out_msg); + ec_dev->dout_size = sizeof(struct cros_ish_out_msg) + sizeof(struct ec_params_rwsig_action); return cros_ec_register(ec_dev); } diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index a878758b9211c..56b0b035d1435 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -645,7 +645,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) ec_dev->cmd_readmem = cros_ec_lpc_readmem; ec_dev->din_size = sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct ec_host_request); + ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action); ec_dev->priv = ec_lpc; /* diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 36aa6a0c415a0..384bf452b223c 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -14,6 +14,8 @@ #include "cros_ec_trace.h" #define EC_COMMAND_RETRIES 50 +#define RWSIG_CONTINUE_RETRIES 8 +#define RWSIG_CONTINUE_MAX_ERRORS_IN_ROW 3 static const int cros_ec_error_map[] = { [EC_RES_INVALID_COMMAND] = -EOPNOTSUPP, @@ -288,6 +290,64 @@ exit: return ret; } +int cros_ec_rwsig_continue(struct cros_ec_device *ec_dev) +{ + struct cros_ec_command *msg; + struct ec_params_rwsig_action *rwsig_action; + int ret = 0; + int error_count = 0; + + ec_dev->proto_version = 3; + + msg = kmalloc(sizeof(*msg) + sizeof(*rwsig_action), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->version = 0; + msg->command = EC_CMD_RWSIG_ACTION; + msg->insize = 0; + msg->outsize = sizeof(*rwsig_action); + + rwsig_action = (struct ec_params_rwsig_action *)msg->data; + rwsig_action->action = RWSIG_ACTION_CONTINUE; + + for (int i = 0; i < RWSIG_CONTINUE_RETRIES; i++) { + ret = cros_ec_send_command(ec_dev, msg); + + if (ret < 0) { + if (++error_count >= RWSIG_CONTINUE_MAX_ERRORS_IN_ROW) + break; + } else if (msg->result == EC_RES_INVALID_COMMAND) { + /* + * If EC_RES_INVALID_COMMAND is retured, it means RWSIG + * is not supported or EC is already in RW, so there is + * nothing left to do. + */ + break; + } else if (msg->result != EC_RES_SUCCESS) { + /* Unexpected command error. */ + ret = cros_ec_map_error(msg->result); + break; + } else { + /* + * The EC_CMD_RWSIG_ACTION succeed. Send the command + * more times, to make sure EC is in RW. A following + * command can timeout, because EC may need some time to + * initialize after jump to RW. + */ + error_count = 0; + } + + if (ret != -ETIMEDOUT) + usleep_range(90000, 100000); + } + + kfree(msg); + + return ret; +} +EXPORT_SYMBOL(cros_ec_rwsig_continue); + static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx) { struct cros_ec_command *msg; diff --git a/drivers/platform/chrome/cros_ec_rpmsg.c b/drivers/platform/chrome/cros_ec_rpmsg.c index 39d3b50a7c09e..bc2666491db1f 100644 --- a/drivers/platform/chrome/cros_ec_rpmsg.c +++ b/drivers/platform/chrome/cros_ec_rpmsg.c @@ -231,7 +231,7 @@ static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev) ec_dev->phys_name = dev_name(&rpdev->dev); ec_dev->din_size = sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct ec_host_request); + ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action); dev_set_drvdata(dev, ec_dev); ec_rpmsg->rpdev = rpdev; diff --git a/drivers/platform/chrome/cros_ec_spi.c b/drivers/platform/chrome/cros_ec_spi.c index 3e88cc92e8192..410429ab0add7 100644 --- a/drivers/platform/chrome/cros_ec_spi.c +++ b/drivers/platform/chrome/cros_ec_spi.c @@ -766,7 +766,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) ec_dev->din_size = EC_MSG_PREAMBLE_COUNT + sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct ec_host_request); + ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action); ec_spi->last_transfer_ns = ktime_get_ns(); diff --git a/drivers/platform/chrome/cros_ec_uart.c b/drivers/platform/chrome/cros_ec_uart.c index 823371037af72..48b4eb013831b 100644 --- a/drivers/platform/chrome/cros_ec_uart.c +++ b/drivers/platform/chrome/cros_ec_uart.c @@ -284,7 +284,7 @@ static int cros_ec_uart_probe(struct serdev_device *serdev) ec_dev->pkt_xfer = cros_ec_uart_pkt_xfer; ec_dev->din_size = sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); - ec_dev->dout_size = sizeof(struct ec_host_request); + ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action); serdev_device_set_client_ops(serdev, &cros_ec_uart_client_ops); diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index 0b7e31b63ffb0..0bc2ae62f185c 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -246,6 +246,8 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg); +int cros_ec_rwsig_continue(struct cros_ec_device *ec_dev); + int cros_ec_query_all(struct cros_ec_device *ec_dev); int cros_ec_get_next_event(struct cros_ec_device *ec_dev, -- GitLab From 325de38e5e6814f3e631d07966fea1f263b74926 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Fri, 6 Dec 2024 09:15:14 +0000 Subject: [PATCH 454/456] UPSTREAM: platform/chrome: cros_ec_proto: remove unnecessary retries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the retry of the get protocol info command. It is not needed anymore, because RWSIG continue command is send before start of the probing. That assures the EC device is ready in RW and there is no need to try again because FPMCU is not fully booted. Signed-off-by: Dawid Niedzwiecki Link: https://lore.kernel.org/r/20241206091514.2538350-3-dawidn@google.com Signed-off-by: Tzung-Bi Shih (cherry picked from commit dce2f5b5da23389f838a22a7c149b717da93d9fe) BUG=b:373543912 TEST=Make sure FPMCU is always registers for Omniknight devices. Change-Id: I323b063c53202057ef8af814c0cb445cffba43f0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6218202 Reviewed-by: Kornel Dulęba Reviewed-by: Patryk Duda Reviewed-by: Sean Paul Tested-by: Dawid Niedźwiecki Commit-Queue: Dawid Niedźwiecki Signed-off-by: Hubert Mazur --- drivers/platform/chrome/cros_ec_proto.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 384bf452b223c..8e03bb400beae 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -366,15 +366,6 @@ static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx) msg->insize = sizeof(*info); ret = cros_ec_send_command(ec_dev, msg); - /* - * Send command once again when timeout occurred. - * Fingerprint MCU (FPMCU) is restarted during system boot which - * introduces small window in which FPMCU won't respond for any - * messages sent by kernel. There is no need to wait before next - * attempt because we waited at least EC_MSG_DEADLINE_MS. - */ - if (ret == -ETIMEDOUT) - ret = cros_ec_send_command(ec_dev, msg); if (ret < 0) { dev_dbg(ec_dev->dev, -- GitLab From 2875b671f12fc90a5b3eeb090528713c1c8a711b Mon Sep 17 00:00:00 2001 From: Jameson Thies Date: Wed, 29 Jan 2025 18:21:10 +0000 Subject: [PATCH 455/456] CHROMIUM: usb: typec: cros_ec_ucsi: Resume work after EC init A manual EC sysjump will restart the PPM and break communication with the UCSI driver by disabling notifications. Update cros_ec_ucsi to listen for PPM init events, and treat them as a system resume to re-establish communication with the PPM. BUG=b:387538657 UPSTREAM-TASK=b:335338337 TEST=Built kernel and manually tested after sysjump on Brox. Change-Id: Id8438f5955e5f82e4dbc9edd3c44d09e26f3beba Signed-off-by: Jameson Thies Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6215290 Reviewed-by: Benson Leung Signed-off-by: Hubert Mazur --- drivers/usb/typec/ucsi/cros_ec_ucsi.c | 17 ++++++++++++----- include/linux/platform_data/cros_ec_commands.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c index afecdcb1d3938..75c3dfb73e7fc 100644 --- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c +++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c @@ -227,12 +227,19 @@ static int cros_ucsi_event(struct notifier_block *nb, { struct cros_ucsi_data *udata = container_of(nb, struct cros_ucsi_data, nb); - if (!(host_event & PD_EVENT_PPM)) - return NOTIFY_OK; + if (host_event & PD_EVENT_INIT) { + /* Late init event received from ChromeOS EC. Treat this as a + * system resume to re-enable communication with the PPM. + */ + dev_dbg(udata->dev, "Late PD init received"); + ucsi_resume(udata->ucsi); + } - dev_dbg(udata->dev, "UCSI notification received"); - flush_work(&udata->work); - schedule_work(&udata->work); + if (host_event & PD_EVENT_PPM) { + dev_dbg(udata->dev, "UCSI notification received"); + flush_work(&udata->work); + schedule_work(&udata->work); + } return NOTIFY_OK; } diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index fff191a8d413e..2061df28e2f3a 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -5032,6 +5032,7 @@ struct ec_response_pd_status { #define PD_EVENT_IDENTITY_RECEIVED BIT(2) #define PD_EVENT_DATA_SWAP BIT(3) #define PD_EVENT_PPM BIT(5) +#define PD_EVENT_INIT BIT(6) struct ec_response_host_event_status { uint32_t status; /* PD MCU host event status */ } __ec_align4; -- GitLab From 80cff296cd45a7a18808e3611322641d58ccd2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Jakie=C5=82a?= Date: Fri, 14 Feb 2025 14:11:36 +0000 Subject: [PATCH 456/456] CHROMIUM: spi: mtk-nor: Fix clock selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mtk-nor-spi controller is based on SPI, which is initialized before nor. This initialization failed, due to the selection of the first clock, which wasn't labeled "spi" This resulted in a failed mtk-nor-spi probe on Corsola boards. BUG=b:396521623, b:396607629 TEST=emerge-{corsola-kernelnext\rauru} chromeos-kernel-6_6 \ update_kernel && check if mtd devices are present && run `futility gbb --get --flags --flash` with success. UPSTREAM-TASK=b:379034916 Change-Id: I8bba4d5b80899da95c0c2e3daeaa5aa8ddf95727 Signed-off-by: Albert Jakieła Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/6269778 Commit-Queue: Wojciech Macek Reviewed-by: Fei Shao Reviewed-by: Wojciech Macek Tested-by: Wojciech Macek Signed-off-by: Hubert Mazur --- drivers/spi/spi-mtk-nor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index 8c11ffada79c9..948c91b2a7837 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -722,8 +722,7 @@ static int mtk_nor_enable_clk(struct mtk_nor *sp) dev_err(sp->dev, "get %s fail\n",sp->clocks[i].id); return PTR_ERR(sp->clocks[i].clk); } - - if(strcmp(sp->clocks[i].id, "spi")) + if (!strcmp(sp->clocks[i].id, "spi")) sp->spi_freq = clk_get_rate(sp->clocks[i].clk); } -- GitLab